diff --git a/.dockerignore b/.dockerignore
index 6ca3ad4..633d33e 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -16,6 +16,7 @@
 # under the License.
 
 cloudstack/tools/docker/Dockerfile
+cloudstack/tools/docker/Dockerfile.smokedev
 .dockerignore
 .idea
 .git
diff --git a/.gitignore b/.gitignore
index 37eaa05..0e50a95 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-build/replace.properties
 build/build.number
 .lock-wscript
 .waf-*
diff --git a/.travis.yml b/.travis.yml
index 69b845b..c37e236 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,31 +17,38 @@
 sudo: required
 dist: xenial
 group: edge
+
 language: java
 jdk:
-- openjdk8
+  - openjdk8
 python:
   - "2.7"
+
 cache:
   directories:
-  - $HOME/.m2
+    - $HOME/.m2
   timeout: 500
+
 notifications:
   email: false
+
 env:
   global:
      - PATH=$HOME/.local/bin:$PATH
   matrix:
     # Keep the TESTS sorted by name and grouped by type
+    - TESTS="smoke/test_certauthority_root"
+
     - TESTS="smoke/test_accounts
              smoke/test_affinity_groups
              smoke/test_affinity_groups_projects
-             smoke/test_certauthority_root
+             smoke/test_async_job
              smoke/test_deploy_vgpu_enabled_vm
              smoke/test_deploy_vm_iso
              smoke/test_deploy_vm_root_resize
              smoke/test_deploy_vm_with_userdata
              smoke/test_deploy_vms_with_varied_deploymentplanners
+             smoke/test_diagnostics
              smoke/test_disk_offerings
              smoke/test_dynamicroles
              smoke/test_global_settings
@@ -70,9 +77,10 @@
              smoke/test_password_server
              smoke/test_portable_publicip
              smoke/test_portforwardingrules"
-
-    - TESTS="smoke/test_primary_storage
-             smoke/test_privategw_acl
+    
+    - TESTS="smoke/test_primary_storage"
+    
+    - TESTS="smoke/test_privategw_acl
              smoke/test_projects
              smoke/test_public_ip_range
              smoke/test_pvlan
@@ -174,3 +182,41 @@
 after_success: ./tools/travis/after_success.sh
 after_failure: ./tools/travis/after_failure.sh
 after_script: ./tools/travis/after_script.sh
+
+# Packaging job definition, will be reused
+.package_job: &package_job
+  before_install: docker pull ${IMAGE}
+  install: true
+  before_script: true
+  script: |
+    docker run \
+     --volume ${TRAVIS_BUILD_DIR}:/mnt/build/cloudstack \
+     --volume $HOME/.m2:/root/.m2 \
+     --rm \
+     ${IMAGE} ${PARAMS}
+  after_script: true
+  after_success: true
+  after_failure: true
+
+jobs:
+  include:
+    - stage: package
+      services: docker
+      env: IMAGE=khos2ow/cloudstack-rpm-builder:centos7 PARAMS="--distribution centos7 --pack oss"
+      <<: *package_job
+
+    - stage: package
+      services: docker
+      env: IMAGE=khos2ow/cloudstack-rpm-builder:centos6 PARAMS="--distribution centos63 --pack oss"
+      <<: *package_job
+
+    - stage: package
+      services: docker
+      env: IMAGE=khos2ow/cloudstack-deb-builder:ubuntu1804 PARAMS=""
+      <<: *package_job
+
+    - stage: package
+      services: docker
+      env: IMAGE=khos2ow/cloudstack-deb-builder:ubuntu1604 PARAMS=""
+      <<: *package_job
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6ac3ad5..2f9bc4b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,6 +24,15 @@
 PR will only be merged when master is open, will be held otherwise until master is open again. 
 No back porting / cherry-picking features to existing branches!
 
+PendingReleaseNotes file
+------------------------
+When developing a new feature or making a (major) change to a existing feature you are encouraged to append this to the PendingReleaseNotes file so that the Release Manager can
+use this file as a source of information when compiling the Release Notes for a new release.
+
+When adding information to the PendingReleaseNotes file make sure that you write a good and understandable description of the new feature or change which you have developed.
+
+Updating the PendingReleaseNotes file is preferably a part of the original Pull Request, but that is up to the developers' discretion.
+
 Fork the code 
 -------------
 
diff --git a/INSTALL.md b/INSTALL.md
index 626df91..281707e 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -44,12 +44,10 @@
 
 Following installation, execute the following commands to configure jenv and pyenv for use with CloudStack development:
 
-'''
-  # pyenv install 2.7.11                                          # Install Python 2.7.11
-  # pyenv virtualenv 2.7.11 cloudstack                            # Create a cloidstack virtualenv using Python 2.7.11
-  # pip install -r <root CloudStack source tree>/requirements.txt # Install cloudstack Python dependencies
-  # jenv add <path to JDK 1.7 installation>                       # Add Java7 to jenv
-'''
+    # pyenv install 2.7.11                                          ## Install Python 2.7.11
+    # pyenv virtualenv 2.7.11 cloudstack                            ## Create a cloudstack virtualenv using Python 2.7.11
+    # pip install -r <root CloudStack source tree>/requirements.txt ## Install cloudstack Python dependencies
+    # jenv add <path to JDK 1.7 installation>                       ## Add Java7 to jenv
 
 *N.B.* If you are running Linux, you may need to install additional packages to allow pyenv to build Python.
 
@@ -59,7 +57,7 @@
 
 You may get the source code from the repository hosted on Apache:
 
-    $ git clone https://git-wip-us.apache.org/repos/asf/cloudstack.git
+    $ git clone https://gitbox.apache.org/repos/asf/cloudstack.git
 
 Or, you may fork the repository from the official Apache CloudStack mirror on [Github](https://github.com/apache/cloudstack)
 
@@ -97,13 +95,13 @@
 
 ## Building with non-redistributable plugins
 
-CloudStack supports several plugins that depend on libraries with distribution restrictions. 
-Because of this they are not included in the default build. Enable these additional plugins 
+CloudStack supports several plugins that depend on libraries with distribution restrictions.
+Because of this they are not included in the default build. Enable these additional plugins
 activate their respective profiles. For convenience adding -Dnoredist will enable all plugins
-that depend on libraries with distribution restrictions. The build procedure expects that the 
-required libraries are present in the maven repository. 
+that depend on libraries with distribution restrictions. The build procedure expects that the
+required libraries are present in the maven repository.
 
-The following procedure can be used to add the libraries to the local maven repository. Details 
+The following procedure can be used to add the libraries to the local maven repository. Details
 on obtaining the required libraries can be found in this file. Note that this will vary between
 releases of CloudStack
 
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..2162732
--- /dev/null
+++ b/ISSUE_TEMPLATE.md
@@ -0,0 +1,76 @@
+<!--
+Verify first that your issue/request is not already reported on GitHub.
+Also test if the latest release and master branch are affected too.
+Always add information AFTER of these HTML comments, but no need to delete the comments.
+-->
+
+##### ISSUE TYPE
+<!-- Pick one below and delete the rest -->
+ * Bug Report
+ * Improvement Request
+ * Enhancement Request
+ * Feature Idea
+ * Documentation Report
+ * Other
+
+##### COMPONENT NAME
+<!--
+Categorize the issue, e.g. API, VR, VPN, UI, etc.
+-->
+~~~
+
+~~~
+
+##### CLOUDSTACK VERSION
+<!--
+New line separated list of affected versions, commit ID for issues on master branch.
+-->
+
+~~~
+
+~~~
+
+##### CONFIGURATION
+<!--
+Information about the configuration if relevant, e.g. basic network, advanced networking, etc.  N/A otherwise
+-->
+
+
+##### OS / ENVIRONMENT
+<!--
+Information about the environment if relevant, N/A otherwise
+-->
+
+
+##### SUMMARY
+<!-- Explain the problem/feature briefly -->
+
+
+##### STEPS TO REPRODUCE
+<!--
+For bugs, show exactly how to reproduce the problem, using a minimal test-case. Use Screenshots if accurate.
+
+For new features, show how the feature would be used.
+-->
+
+<!-- Paste example playbooks or commands between quotes below -->
+~~~
+
+~~~
+
+<!-- You can also paste gist.github.com links for larger files -->
+
+##### EXPECTED RESULTS
+<!-- What did you expect to happen when running the steps above? -->
+
+~~~
+
+~~~
+
+##### ACTUAL RESULTS
+<!-- What actually happened? -->
+
+<!-- Paste verbatim command output between quotes below -->
+~~~
+
+~~~
diff --git a/LICENSE b/LICENSE
index 0dcb45c..48d8526 100644
--- a/LICENSE
+++ b/LICENSE
@@ -612,13 +612,13 @@
             qunit.css  from http://docs.jquery.com/QUnit
             qunit.js  from http://docs.jquery.com/QUnit
 
-Within the utils/src/com/cloud/utils/db directory
+Within the utils/src/main/java/com/cloud/utils/db directory
     licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt  (as above)
     Copyright (c) 2004 Clinton Begin
         from Clinton Begin  http://code.google.com/p/mybatis/ 
             ScriptRunner.java  from http://code.google.com/p/mybatis/
 
-Within the utils/src/org/apache/commons/httpclient/contrib/ssl directory
+Within the utils/src/main/java/org/apache/commons/httpclient/contrib/ssl directory
     licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt  (as above)
     Copyright (c) 2007 The Apache Software Foundation
         from The Apache Software Foundation  http://www.apache.org/ 
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index a7c739d..c56bc98 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -19,9 +19,9 @@
 ## Screenshots (if appropriate):
 
 ## How Has This Been Tested?
-
 <!-- Please describe in detail how you tested your changes. -->
 <!-- Include details of your testing environment, and the tests you ran to -->
 <!-- see how your change affects other areas of the code, etc. -->
 
+
 <!-- Please read the [CONTRIBUTING](https://github.com/apache/cloudstack/blob/master/CONTRIBUTING.md) document -->
diff --git a/PendingReleaseNotes b/PendingReleaseNotes
new file mode 100644
index 0000000..9670b6e
--- /dev/null
+++ b/PendingReleaseNotes
@@ -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.
+#
+#
+# PENDING RELEASE NOTES
+#
+# WHEN DEVELOPING A NEW FEATURE OR MAKING A (MAJOR) CHANGE TO
+# AN EXISTING FEATURE DEVELOPERS ARE ENCOURAGED TO UPDATED THIS
+# FILE WITH THE CHANGES THEY MADE.
+#
+# THE RELEASE MANAGER CAN USE THIS FILE AS A SOURCE OF INFORMATION
+# WHEN COMPILING THE RELEASE NOTES FOR A NEW RELEASE.
+#
+# THIS FILE IS TRUNCATED AFTER THE RELEASE OF THE NEW VERSION
+#
+#
+
+
+example.ver.1 > example.ver.2:
+  * VirtualRouters are now deployed with the latest version of ExampleLinux
+    and wil also use a new MyFirstDHCPServer instead of dnsmasq to provide
+    faster and more robust deployment of new Instances
+
+  * ISOs are no longer supported and will be replaced by 2.88MB Floppy Drives
+    which can now be attached to Instances. This is to prevent the Secondary
+    Storage to grow to enormous sizes as Linux Distributions keep growing in
+    size while a stripped down Linux should fit on a 2.88MB floppy.
diff --git a/README.md b/README.md
index 17a7a8f..100080e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Apache CloudStack [![Build Status](https://travis-ci.org/apache/cloudstack.svg?branch=master)](https://travis-ci.org/apache/cloudstack) [![Coverity Scan Build Status](https://scan.coverity.com/projects/943/badge.svg)](https://scan.coverity.com/projects/943)
+# Apache CloudStack [![Build Status](https://travis-ci.org/apache/cloudstack.svg?branch=master)](https://travis-ci.org/apache/cloudstack) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=apachecloudstack&metric=alert_status)](https://sonarcloud.io/dashboard?id=apachecloudstack) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=apachecloudstack&metric=ncloc)](https://sonarcloud.io/dashboard?id=apachecloudstack)
 
 ![Apache CloudStack](tools/logo/apache_cloudstack.png)
 
@@ -67,7 +67,7 @@
 participation from anybody willing to work [The Apache Way](http://theapacheway.com) and make a
 contribution. Note that you do not have to be a developer in order to contribute
 to Apache CloudStack. We need folks to help with documentation, translation,
-promotion etc.See our contribution [page](http://cloudstack.apache.org/contribute.html).
+promotion etc. See our contribution [page](http://cloudstack.apache.org/contribute.html).
 
 If you're interested in learning more or participating in the Apache CloudStack
 project, the mailing lists are the best way to do that. While the project has
@@ -100,7 +100,7 @@
 released version of CloudStack, please report it to `security@cloudstack.apache.org` with details about the vulnerability, how it
 might be exploited, and any additional information that might be useful.
 
-For more details, please visit our security [page](http://cloudstack.apache.org/security.html)
+For more details, please visit our security [page](http://cloudstack.apache.org/security.html).
 
 ## License
 
@@ -143,7 +143,7 @@
 
 The following provides more details on the included cryptographic software:
 
-* CloudStack makes use of JaSypt cryptographic libraries
+* CloudStack makes use of JaSypt cryptographic libraries.
 * CloudStack has a system requirement of MySQL, and uses native database encryption functionality.
 * CloudStack makes use of the Bouncy Castle general-purpose encryption library.
 * CloudStack can optionally interacts with and controls OpenSwan-based VPNs.
diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index ad35b96..b45526a 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -108,6 +108,10 @@
 # openvswitch = com.cloud.hypervisor.kvm.resource.OvsVifDriver
 #libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.BridgeVifDriver
 
+# Set DPDK Support on OpenVswitch
+#openvswitch.dpdk.enabled=true
+#openvswitch.dpdk.ovs.path=/var/run/openvswitch
+
 # set the hypervisor type, values are: kvm, lxc
 hypervisor.type=kvm
 
@@ -197,6 +201,13 @@
 # reports to the Management Server
 # Default: 0
 #
+# host.reserved.mem.mb = 0
+# How much host memory to reserve for non-allocation. 
+# A useful parameter if a node uses some other software that requires memory,
+# or in case that OOM Killer kicks in sometimes.
+# If this parameter is used, host.overcommit.mem.mb must be set to 0.
+# Default value: 0
+#
 # vm.watchdog.model=i6300esb
 # The model of Watchdog timer to present to the Guest
 # For all models refer to the libvirt documentation.
diff --git a/agent/pom.xml b/agent/pom.xml
index fcad5b0..b3c5ec7 100644
--- a/agent/pom.xml
+++ b/agent/pom.xml
@@ -1,120 +1,113 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-agent</artifactId>
-  <name>Apache CloudStack Agents</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-        <groupId>commons-daemon</groupId>
-        <artifactId>commons-daemon</artifactId>
-    </dependency>    
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>generate-resource</id>
-            <phase>generate-resources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <copy
-                  todir="${basedir}/target/transformed">
-                  <fileset dir="${basedir}/conf">
-                    <include name="agent.properties" />
-                  </fileset>
-                </copy>
-                <copy overwrite="true"
-                  todir="${basedir}/target/transformed">
-                  <fileset dir="${basedir}/conf">
-                    <include name="*.in" />
-                  </fileset>
-                  <globmapper from="*.in" to="*" />
-                  <filterchain>
-                    <filterreader
-                      classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile"
-                        value="${cs.replace.properties}" />
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy overwrite="true"
-                  todir="${basedir}/target/transformed">
-                  <fileset dir="${basedir}/bindir">
-                    <include name="*.in" />
-                  </fileset>
-                  <globmapper from="*.in" to="*" />
-                  <filterchain>
-                    <filterreader
-                      classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile"
-                        value="${cs.replace.properties}" />
-                    </filterreader>
-                  </filterchain>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy-dependencies</id>
-            <phase>package</phase>
-            <goals>
-              <goal>copy-dependencies</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
-              <includeScope>runtime</includeScope>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+<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-agent</artifactId>
+    <name>Apache CloudStack Agents</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-daemon</groupId>
+            <artifactId>commons-daemon</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>generate-resource</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target>
+                                <copy todir="${basedir}/target/transformed">
+                                    <fileset dir="${basedir}/conf">
+                                        <include name="agent.properties" />
+                                    </fileset>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/transformed">
+                                    <fileset dir="${basedir}/conf">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/transformed">
+                                    <fileset dir="${basedir}/bindir">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
+                            <includeScope>runtime</includeScope>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
deleted file mode 100644
index b3b17e7..0000000
--- a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
+++ /dev/null
@@ -1,464 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.resource.consoleproxy;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.Agent.ExitStatus;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthAnswer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
-import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
-import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
-import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
-import com.cloud.exception.AgentControlChannelException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.ReflectUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.Script;
-import com.google.gson.Gson;
-
-/**
- *
- * I don't want to introduce extra cross-cutting concerns into console proxy
- * process, as it involves configurations like zone/pod, agent auto self-upgrade
- * etc. I also don't want to introduce more module dependency issues into our
- * build system, cross-communication between this resource and console proxy
- * will be done through reflection. As a result, come out with following
- * solution to solve the problem of building a communication channel between
- * consoole proxy and management server.
- *
- * We will deploy an agent shell inside console proxy VM, and this agent shell
- * will launch current console proxy from within this special server resource,
- * through it console proxy can build a communication channel with management
- * server.
- *
- */
-public class ConsoleProxyResource extends ServerResourceBase implements ServerResource {
-    static final Logger s_logger = Logger.getLogger(ConsoleProxyResource.class);
-
-    private final Properties _properties = new Properties();
-    private Thread _consoleProxyMain = null;
-
-    long _proxyVmId;
-    int _proxyPort;
-
-    String _localgw;
-    String _eth1ip;
-    String _eth1mask;
-    String _pubIp;
-
-    @Override
-    public Answer executeRequest(final Command cmd) {
-        if (cmd instanceof CheckConsoleProxyLoadCommand) {
-            return execute((CheckConsoleProxyLoadCommand)cmd);
-        } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
-            return execute((WatchConsoleProxyLoadCommand)cmd);
-        } else if (cmd instanceof ReadyCommand) {
-            s_logger.info("Receive ReadyCommand, response with ReadyAnswer");
-            return new ReadyAnswer((ReadyCommand)cmd);
-        } else if (cmd instanceof CheckHealthCommand) {
-            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
-        } else if (cmd instanceof StartConsoleProxyAgentHttpHandlerCommand) {
-            return execute((StartConsoleProxyAgentHttpHandlerCommand)cmd);
-        } else {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    private Answer execute(StartConsoleProxyAgentHttpHandlerCommand cmd) {
-        s_logger.info("Invoke launchConsoleProxy() in responding to StartConsoleProxyAgentHttpHandlerCommand");
-        launchConsoleProxy(cmd.getKeystoreBits(), cmd.getKeystorePassword(), cmd.getEncryptorPassword());
-        return new Answer(cmd);
-    }
-
-    private void disableRpFilter() {
-        try (FileWriter fstream = new FileWriter("/proc/sys/net/ipv4/conf/eth2/rp_filter");
-             BufferedWriter out = new BufferedWriter(fstream);)
-        {
-            out.write("0");
-        } catch (IOException e) {
-            s_logger.warn("Unable to disable rp_filter");
-        }
-    }
-
-    protected Answer execute(final CheckConsoleProxyLoadCommand cmd) {
-        return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort());
-    }
-
-    protected Answer execute(final WatchConsoleProxyLoadCommand cmd) {
-        return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort());
-    }
-
-    private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
-        String result = null;
-
-        final StringBuffer sb = new StringBuffer();
-        sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus");
-
-        boolean success = true;
-        try {
-            final URL url = new URL(sb.toString());
-            final URLConnection conn = url.openConnection();
-
-            final InputStream is = conn.getInputStream();
-            final BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
-            final StringBuilder sb2 = new StringBuilder();
-            String line = null;
-            try {
-                while ((line = reader.readLine()) != null)
-                    sb2.append(line + "\n");
-                result = sb2.toString();
-            } catch (final IOException e) {
-                success = false;
-            } finally {
-                try {
-                    is.close();
-                } catch (final IOException e) {
-                    s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp);
-                    success = false;
-                }
-            }
-        } catch (final IOException e) {
-            s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp);
-            success = false;
-        }
-
-        return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result);
-    }
-
-    @Override
-    protected String getDefaultScriptsDir() {
-        return null;
-    }
-
-    @Override
-    public Type getType() {
-        return Host.Type.ConsoleProxy;
-    }
-
-    @Override
-    public synchronized StartupCommand[] initialize() {
-        final StartupProxyCommand cmd = new StartupProxyCommand();
-        fillNetworkInformation(cmd);
-        cmd.setProxyPort(_proxyPort);
-        cmd.setProxyVmId(_proxyVmId);
-        if (_pubIp != null)
-            cmd.setPublicIpAddress(_pubIp);
-        return new StartupCommand[] {cmd};
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(long id) {
-        return new PingCommand(Type.ConsoleProxy, id);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _localgw = (String)params.get("localgw");
-        _eth1mask = (String)params.get("eth1mask");
-        _eth1ip = (String)params.get("eth1ip");
-        if (_eth1ip != null) {
-            params.put("private.network.device", "eth1");
-        } else {
-            s_logger.info("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
-        }
-
-        String eth2ip = (String)params.get("eth2ip");
-        if (eth2ip != null) {
-            params.put("public.network.device", "eth2");
-        } else {
-            s_logger.info("eth2ip parameter is not found, assuming that we are not inside a system vm");
-        }
-
-        super.configure(name, params);
-
-        for (Map.Entry<String, Object> entry : params.entrySet()) {
-            _properties.put(entry.getKey(), entry.getValue());
-        }
-
-        String value = (String)params.get("premium");
-        if (value != null && value.equals("premium"))
-            _proxyPort = 443;
-        else {
-            value = (String)params.get("consoleproxy.httpListenPort");
-            _proxyPort = NumbersUtil.parseInt(value, 80);
-        }
-
-        value = (String)params.get("proxy_vm");
-        _proxyVmId = NumbersUtil.parseLong(value, 0);
-
-        if (_localgw != null) {
-            String mgmtHosts = (String)params.get("host");
-            if (_eth1ip != null) {
-                for (final String mgmtHost : mgmtHosts.split(",")) {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
-                }
-                String internalDns1 = (String) params.get("internaldns1");
-                if (internalDns1 == null) {
-                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
-                } else {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
-                }
-                String internalDns2 = (String) params.get("internaldns2");
-                if (internalDns2 != null) {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
-                }
-            }
-        }
-
-        _pubIp = (String)params.get("public.ip");
-
-        value = (String)params.get("disable_rp_filter");
-        if (value != null && value.equalsIgnoreCase("true")) {
-            disableRpFilter();
-        }
-
-        if (s_logger.isInfoEnabled())
-            s_logger.info("Receive proxyVmId in ConsoleProxyResource configuration as " + _proxyVmId);
-
-        return true;
-    }
-
-    private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
-        s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
-        if (destIpOrCidr == null) {
-            s_logger.debug("addRouteToInternalIp: destIp is null");
-            return;
-        }
-        if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) {
-            s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
-            return;
-        }
-        boolean inSameSubnet = false;
-        if (NetUtils.isValidIp4(destIpOrCidr)) {
-            if (eth1ip != null && eth1mask != null) {
-                inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
-            } else {
-                s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
-            }
-        } else {
-            inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
-        }
-        if (inSameSubnet) {
-            s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
-            return;
-        }
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ip route delete " + destIpOrCidr);
-        command.execute();
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ip route add " + destIpOrCidr + " via " + localgw);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in configuring route to internal ip err=" + result);
-        } else {
-            s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
-        }
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    private void launchConsoleProxy(final byte[] ksBits, final String ksPassword, final String encryptorPassword) {
-        final Object resource = this;
-        s_logger.info("Building class loader for com.cloud.consoleproxy.ConsoleProxy");
-        final ClassLoader loader = ReflectUtil.getClassLoaderForName("console-proxy");
-        if (_consoleProxyMain == null) {
-            s_logger.info("Running com.cloud.consoleproxy.ConsoleProxy with encryptor password=" + encryptorPassword);
-            _consoleProxyMain = new Thread(new ManagedContextRunnable() {
-                @Override
-                protected void runInContext() {
-                    try {
-                        Class<?> consoleProxyClazz = loader.loadClass("com.cloud.consoleproxy.ConsoleProxy");
-                        try {
-                            s_logger.info("Invoke startWithContext()");
-                            Method method = consoleProxyClazz.getMethod("startWithContext", Properties.class, Object.class, byte[].class, String.class, String.class);
-                            method.invoke(null, _properties, resource, ksBits, ksPassword, encryptorPassword);
-                        } catch (SecurityException e) {
-                            s_logger.error("Unable to launch console proxy due to SecurityException", e);
-                            System.exit(ExitStatus.Error.value());
-                        } catch (NoSuchMethodException e) {
-                            s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
-                            System.exit(ExitStatus.Error.value());
-                        } catch (IllegalArgumentException e) {
-                            s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
-                            System.exit(ExitStatus.Error.value());
-                        } catch (IllegalAccessException e) {
-                            s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
-                            System.exit(ExitStatus.Error.value());
-                        } catch (InvocationTargetException e) {
-                            s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
-                            System.exit(ExitStatus.Error.value());
-                        }
-                    } catch (final ClassNotFoundException e) {
-                        s_logger.error("Unable to launch console proxy due to ClassNotFoundException");
-                        System.exit(ExitStatus.Error.value());
-                    }
-                }
-            }, "Console-Proxy-Main");
-            _consoleProxyMain.setDaemon(true);
-            _consoleProxyMain.start();
-        } else {
-            s_logger.info("com.cloud.consoleproxy.ConsoleProxy is already running");
-
-            try {
-                Class<?> consoleProxyClazz = loader.loadClass("com.cloud.consoleproxy.ConsoleProxy");
-                Method methodSetup = consoleProxyClazz.getMethod("setEncryptorPassword", String.class);
-                methodSetup.invoke(null, encryptorPassword);
-            } catch (SecurityException e) {
-                s_logger.error("Unable to launch console proxy due to SecurityException", e);
-                System.exit(ExitStatus.Error.value());
-            } catch (NoSuchMethodException e) {
-                s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
-                System.exit(ExitStatus.Error.value());
-            } catch (IllegalArgumentException e) {
-                s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
-                System.exit(ExitStatus.Error.value());
-            } catch (IllegalAccessException e) {
-                s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
-                System.exit(ExitStatus.Error.value());
-            } catch (InvocationTargetException e) {
-                s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
-                System.exit(ExitStatus.Error.value());
-            } catch (final ClassNotFoundException e) {
-                s_logger.error("Unable to launch console proxy due to ClassNotFoundException", e);
-                System.exit(ExitStatus.Error.value());
-            }
-        }
-    }
-
-    public String authenticateConsoleAccess(String host, String port, String vmId, String sid, String ticket, Boolean isReauthentication) {
-
-        ConsoleAccessAuthenticationCommand cmd = new ConsoleAccessAuthenticationCommand(host, port, vmId, sid, ticket);
-        cmd.setReauthenticating(isReauthentication);
-
-        ConsoleProxyAuthenticationResult result = new ConsoleProxyAuthenticationResult();
-        result.setSuccess(false);
-        result.setReauthentication(isReauthentication);
-
-        try {
-            AgentControlAnswer answer = getAgentControl().sendRequest(cmd, 10000);
-
-            if (answer != null) {
-                ConsoleAccessAuthenticationAnswer authAnswer = (ConsoleAccessAuthenticationAnswer)answer;
-                result.setSuccess(authAnswer.succeeded());
-                result.setHost(authAnswer.getHost());
-                result.setPort(authAnswer.getPort());
-                result.setTunnelUrl(authAnswer.getTunnelUrl());
-                result.setTunnelSession(authAnswer.getTunnelSession());
-            } else {
-                s_logger.error("Authentication failed for vm: " + vmId + " with sid: " + sid);
-            }
-        } catch (AgentControlChannelException e) {
-            s_logger.error("Unable to send out console access authentication request due to " + e.getMessage(), e);
-        }
-
-        return new Gson().toJson(result);
-    }
-
-    public void reportLoadInfo(String gsonLoadInfo) {
-        ConsoleProxyLoadReportCommand cmd = new ConsoleProxyLoadReportCommand(_proxyVmId, gsonLoadInfo);
-        try {
-            getAgentControl().postRequest(cmd);
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Report proxy load info, proxy : " + _proxyVmId + ", load: " + gsonLoadInfo);
-        } catch (AgentControlChannelException e) {
-            s_logger.error("Unable to send out load info due to " + e.getMessage(), e);
-        }
-    }
-
-    public void ensureRoute(String address) {
-        if (_localgw != null) {
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Ensure route for " + address + " via " + _localgw);
-
-            // this method won't be called in high frequency, serialize access
-            // to script execution
-            synchronized (this) {
-                try {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, address);
-                } catch (Throwable e) {
-                    s_logger.warn("Unexpected exception while adding internal route to " + address, e);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void setName(String name) {
-    }
-
-    @Override
-    public void setConfigParams(Map<String, Object> params) {
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        return new HashMap<String, Object>();
-    }
-
-    @Override
-    public int getRunLevel() {
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(int level) {
-    }
-}
diff --git a/agent/src/com/cloud/agent/Agent.java b/agent/src/main/java/com/cloud/agent/Agent.java
similarity index 100%
rename from agent/src/com/cloud/agent/Agent.java
rename to agent/src/main/java/com/cloud/agent/Agent.java
diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/main/java/com/cloud/agent/AgentShell.java
similarity index 100%
rename from agent/src/com/cloud/agent/AgentShell.java
rename to agent/src/main/java/com/cloud/agent/AgentShell.java
diff --git a/agent/src/com/cloud/agent/IAgentShell.java b/agent/src/main/java/com/cloud/agent/IAgentShell.java
similarity index 100%
rename from agent/src/com/cloud/agent/IAgentShell.java
rename to agent/src/main/java/com/cloud/agent/IAgentShell.java
diff --git a/agent/src/com/cloud/agent/dao/StorageComponent.java b/agent/src/main/java/com/cloud/agent/dao/StorageComponent.java
similarity index 100%
rename from agent/src/com/cloud/agent/dao/StorageComponent.java
rename to agent/src/main/java/com/cloud/agent/dao/StorageComponent.java
diff --git a/agent/src/com/cloud/agent/dao/impl/PropertiesStorage.java b/agent/src/main/java/com/cloud/agent/dao/impl/PropertiesStorage.java
similarity index 100%
rename from agent/src/com/cloud/agent/dao/impl/PropertiesStorage.java
rename to agent/src/main/java/com/cloud/agent/dao/impl/PropertiesStorage.java
diff --git a/agent/src/com/cloud/agent/dhcp/DhcpProtocolParserServer.java b/agent/src/main/java/com/cloud/agent/dhcp/DhcpProtocolParserServer.java
similarity index 100%
rename from agent/src/com/cloud/agent/dhcp/DhcpProtocolParserServer.java
rename to agent/src/main/java/com/cloud/agent/dhcp/DhcpProtocolParserServer.java
diff --git a/agent/src/com/cloud/agent/dhcp/DhcpSnooper.java b/agent/src/main/java/com/cloud/agent/dhcp/DhcpSnooper.java
similarity index 100%
rename from agent/src/com/cloud/agent/dhcp/DhcpSnooper.java
rename to agent/src/main/java/com/cloud/agent/dhcp/DhcpSnooper.java
diff --git a/agent/src/com/cloud/agent/dhcp/FakeDhcpSnooper.java b/agent/src/main/java/com/cloud/agent/dhcp/FakeDhcpSnooper.java
similarity index 100%
rename from agent/src/com/cloud/agent/dhcp/FakeDhcpSnooper.java
rename to agent/src/main/java/com/cloud/agent/dhcp/FakeDhcpSnooper.java
diff --git a/agent/src/com/cloud/agent/direct/download/DirectTemplateDownloader.java b/agent/src/main/java/com/cloud/agent/direct/download/DirectTemplateDownloader.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/DirectTemplateDownloader.java
rename to agent/src/main/java/com/cloud/agent/direct/download/DirectTemplateDownloader.java
diff --git a/agent/src/com/cloud/agent/direct/download/DirectTemplateDownloaderImpl.java b/agent/src/main/java/com/cloud/agent/direct/download/DirectTemplateDownloaderImpl.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/DirectTemplateDownloaderImpl.java
rename to agent/src/main/java/com/cloud/agent/direct/download/DirectTemplateDownloaderImpl.java
diff --git a/agent/src/com/cloud/agent/direct/download/HttpDirectTemplateDownloader.java b/agent/src/main/java/com/cloud/agent/direct/download/HttpDirectTemplateDownloader.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/HttpDirectTemplateDownloader.java
rename to agent/src/main/java/com/cloud/agent/direct/download/HttpDirectTemplateDownloader.java
diff --git a/agent/src/com/cloud/agent/direct/download/HttpsDirectTemplateDownloader.java b/agent/src/main/java/com/cloud/agent/direct/download/HttpsDirectTemplateDownloader.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/HttpsDirectTemplateDownloader.java
rename to agent/src/main/java/com/cloud/agent/direct/download/HttpsDirectTemplateDownloader.java
diff --git a/agent/src/com/cloud/agent/direct/download/MetalinkDirectTemplateDownloader.java b/agent/src/main/java/com/cloud/agent/direct/download/MetalinkDirectTemplateDownloader.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/MetalinkDirectTemplateDownloader.java
rename to agent/src/main/java/com/cloud/agent/direct/download/MetalinkDirectTemplateDownloader.java
diff --git a/agent/src/com/cloud/agent/direct/download/NfsDirectTemplateDownloader.java b/agent/src/main/java/com/cloud/agent/direct/download/NfsDirectTemplateDownloader.java
similarity index 100%
rename from agent/src/com/cloud/agent/direct/download/NfsDirectTemplateDownloader.java
rename to agent/src/main/java/com/cloud/agent/direct/download/NfsDirectTemplateDownloader.java
diff --git a/agent/src/com/cloud/agent/mockvm/MockVm.java b/agent/src/main/java/com/cloud/agent/mockvm/MockVm.java
similarity index 100%
rename from agent/src/com/cloud/agent/mockvm/MockVm.java
rename to agent/src/main/java/com/cloud/agent/mockvm/MockVm.java
diff --git a/agent/src/com/cloud/agent/mockvm/MockVmMgr.java b/agent/src/main/java/com/cloud/agent/mockvm/MockVmMgr.java
similarity index 100%
rename from agent/src/com/cloud/agent/mockvm/MockVmMgr.java
rename to agent/src/main/java/com/cloud/agent/mockvm/MockVmMgr.java
diff --git a/agent/src/com/cloud/agent/mockvm/VmMgr.java b/agent/src/main/java/com/cloud/agent/mockvm/VmMgr.java
similarity index 100%
rename from agent/src/com/cloud/agent/mockvm/VmMgr.java
rename to agent/src/main/java/com/cloud/agent/mockvm/VmMgr.java
diff --git a/agent/src/com/cloud/agent/resource/DummyResource.java b/agent/src/main/java/com/cloud/agent/resource/DummyResource.java
similarity index 100%
rename from agent/src/com/cloud/agent/resource/DummyResource.java
rename to agent/src/main/java/com/cloud/agent/resource/DummyResource.java
diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java b/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java
similarity index 100%
rename from agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java
rename to agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java
diff --git a/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
new file mode 100644
index 0000000..fb5e327
--- /dev/null
+++ b/agent/src/main/java/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
@@ -0,0 +1,464 @@
+// 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.resource.consoleproxy;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.Agent.ExitStatus;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
+import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
+import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
+import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.exception.AgentControlChannelException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.ReflectUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.Script;
+import com.google.gson.Gson;
+
+/**
+ *
+ * I don't want to introduce extra cross-cutting concerns into console proxy
+ * process, as it involves configurations like zone/pod, agent auto self-upgrade
+ * etc. I also don't want to introduce more module dependency issues into our
+ * build system, cross-communication between this resource and console proxy
+ * will be done through reflection. As a result, come out with following
+ * solution to solve the problem of building a communication channel between
+ * consoole proxy and management server.
+ *
+ * We will deploy an agent shell inside console proxy VM, and this agent shell
+ * will launch current console proxy from within this special server resource,
+ * through it console proxy can build a communication channel with management
+ * server.
+ *
+ */
+public class ConsoleProxyResource extends ServerResourceBase implements ServerResource {
+    static final Logger s_logger = Logger.getLogger(ConsoleProxyResource.class);
+
+    private final Properties _properties = new Properties();
+    private Thread _consoleProxyMain = null;
+
+    long _proxyVmId;
+    int _proxyPort;
+
+    String _localgw;
+    String _eth1ip;
+    String _eth1mask;
+    String _pubIp;
+
+    @Override
+    public Answer executeRequest(final Command cmd) {
+        if (cmd instanceof CheckConsoleProxyLoadCommand) {
+            return execute((CheckConsoleProxyLoadCommand)cmd);
+        } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
+            return execute((WatchConsoleProxyLoadCommand)cmd);
+        } else if (cmd instanceof ReadyCommand) {
+            s_logger.info("Receive ReadyCommand, response with ReadyAnswer");
+            return new ReadyAnswer((ReadyCommand)cmd);
+        } else if (cmd instanceof CheckHealthCommand) {
+            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+        } else if (cmd instanceof StartConsoleProxyAgentHttpHandlerCommand) {
+            return execute((StartConsoleProxyAgentHttpHandlerCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(StartConsoleProxyAgentHttpHandlerCommand cmd) {
+        s_logger.info("Invoke launchConsoleProxy() in responding to StartConsoleProxyAgentHttpHandlerCommand");
+        launchConsoleProxy(cmd.getKeystoreBits(), cmd.getKeystorePassword(), cmd.getEncryptorPassword());
+        return new Answer(cmd);
+    }
+
+    private void disableRpFilter() {
+        try (FileWriter fstream = new FileWriter("/proc/sys/net/ipv4/conf/eth2/rp_filter");
+             BufferedWriter out = new BufferedWriter(fstream);)
+        {
+            out.write("0");
+        } catch (IOException e) {
+            s_logger.warn("Unable to disable rp_filter");
+        }
+    }
+
+    protected Answer execute(final CheckConsoleProxyLoadCommand cmd) {
+        return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort());
+    }
+
+    protected Answer execute(final WatchConsoleProxyLoadCommand cmd) {
+        return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort());
+    }
+
+    private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
+        String result = null;
+
+        final StringBuffer sb = new StringBuffer();
+        sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus");
+
+        boolean success = true;
+        try {
+            final URL url = new URL(sb.toString());
+            final URLConnection conn = url.openConnection();
+
+            final InputStream is = conn.getInputStream();
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
+            final StringBuilder sb2 = new StringBuilder();
+            String line = null;
+            try {
+                while ((line = reader.readLine()) != null)
+                    sb2.append(line + "\n");
+                result = sb2.toString();
+            } catch (final IOException e) {
+                success = false;
+            } finally {
+                try {
+                    is.close();
+                } catch (final IOException e) {
+                    s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp);
+                    success = false;
+                }
+            }
+        } catch (final IOException e) {
+            s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp);
+            success = false;
+        }
+
+        return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result);
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return null;
+    }
+
+    @Override
+    public Type getType() {
+        return Host.Type.ConsoleProxy;
+    }
+
+    @Override
+    public synchronized StartupCommand[] initialize() {
+        final StartupProxyCommand cmd = new StartupProxyCommand();
+        fillNetworkInformation(cmd);
+        cmd.setProxyPort(_proxyPort);
+        cmd.setProxyVmId(_proxyVmId);
+        if (_pubIp != null)
+            cmd.setPublicIpAddress(_pubIp);
+        return new StartupCommand[] {cmd};
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        return new PingCommand(Type.ConsoleProxy, id);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _localgw = (String)params.get("localgw");
+        _eth1mask = (String)params.get("eth1mask");
+        _eth1ip = (String)params.get("eth1ip");
+        if (_eth1ip != null) {
+            params.put("private.network.device", "eth1");
+        } else {
+            s_logger.info("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
+        }
+
+        String eth2ip = (String)params.get("eth2ip");
+        if (eth2ip != null) {
+            params.put("public.network.device", "eth2");
+        } else {
+            s_logger.info("eth2ip parameter is not found, assuming that we are not inside a system vm");
+        }
+
+        super.configure(name, params);
+
+        for (Map.Entry<String, Object> entry : params.entrySet()) {
+            _properties.put(entry.getKey(), entry.getValue());
+        }
+
+        String value = (String)params.get("premium");
+        if (value != null && value.equals("premium"))
+            _proxyPort = 443;
+        else {
+            value = (String)params.get("consoleproxy.httpListenPort");
+            _proxyPort = NumbersUtil.parseInt(value, 80);
+        }
+
+        value = (String)params.get("proxy_vm");
+        _proxyVmId = NumbersUtil.parseLong(value, 0);
+
+        if (_localgw != null) {
+            String mgmtHosts = (String)params.get("host");
+            if (_eth1ip != null) {
+                for (final String mgmtHost : mgmtHosts.split(",")) {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+                }
+                String internalDns1 = (String) params.get("internaldns1");
+                if (internalDns1 == null) {
+                    s_logger.warn("No DNS entry found during configuration of ConsoleProxy");
+                } else {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+                }
+                String internalDns2 = (String) params.get("internaldns2");
+                if (internalDns2 != null) {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+                }
+            }
+        }
+
+        _pubIp = (String)params.get("public.ip");
+
+        value = (String)params.get("disable_rp_filter");
+        if (value != null && value.equalsIgnoreCase("true")) {
+            disableRpFilter();
+        }
+
+        if (s_logger.isInfoEnabled())
+            s_logger.info("Receive proxyVmId in ConsoleProxyResource configuration as " + _proxyVmId);
+
+        return true;
+    }
+
+    private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
+        s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
+        if (destIpOrCidr == null) {
+            s_logger.debug("addRouteToInternalIp: destIp is null");
+            return;
+        }
+        if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) {
+            s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
+            return;
+        }
+        boolean inSameSubnet = false;
+        if (NetUtils.isValidIp4(destIpOrCidr)) {
+            if (eth1ip != null && eth1mask != null) {
+                inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
+            } else {
+                s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
+            }
+        } else {
+            inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
+        }
+        if (inSameSubnet) {
+            s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
+            return;
+        }
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route delete " + destIpOrCidr);
+        command.execute();
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route add " + destIpOrCidr + " via " + localgw);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in configuring route to internal ip err=" + result);
+        } else {
+            s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    private void launchConsoleProxy(final byte[] ksBits, final String ksPassword, final String encryptorPassword) {
+        final Object resource = this;
+        s_logger.info("Building class loader for com.cloud.consoleproxy.ConsoleProxy");
+        final ClassLoader loader = ReflectUtil.getClassLoaderForName("console-proxy");
+        if (_consoleProxyMain == null) {
+            s_logger.info("Running com.cloud.consoleproxy.ConsoleProxy with encryptor password=" + encryptorPassword);
+            _consoleProxyMain = new Thread(new ManagedContextRunnable() {
+                @Override
+                protected void runInContext() {
+                    try {
+                        Class<?> consoleProxyClazz = loader.loadClass("com.cloud.consoleproxy.ConsoleProxy");
+                        try {
+                            s_logger.info("Invoke startWithContext()");
+                            Method method = consoleProxyClazz.getMethod("startWithContext", Properties.class, Object.class, byte[].class, String.class, String.class);
+                            method.invoke(null, _properties, resource, ksBits, ksPassword, encryptorPassword);
+                        } catch (SecurityException e) {
+                            s_logger.error("Unable to launch console proxy due to SecurityException", e);
+                            System.exit(ExitStatus.Error.value());
+                        } catch (NoSuchMethodException e) {
+                            s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
+                            System.exit(ExitStatus.Error.value());
+                        } catch (IllegalArgumentException e) {
+                            s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
+                            System.exit(ExitStatus.Error.value());
+                        } catch (IllegalAccessException e) {
+                            s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
+                            System.exit(ExitStatus.Error.value());
+                        } catch (InvocationTargetException e) {
+                            s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
+                            System.exit(ExitStatus.Error.value());
+                        }
+                    } catch (final ClassNotFoundException e) {
+                        s_logger.error("Unable to launch console proxy due to ClassNotFoundException");
+                        System.exit(ExitStatus.Error.value());
+                    }
+                }
+            }, "Console-Proxy-Main");
+            _consoleProxyMain.setDaemon(true);
+            _consoleProxyMain.start();
+        } else {
+            s_logger.info("com.cloud.consoleproxy.ConsoleProxy is already running");
+
+            try {
+                Class<?> consoleProxyClazz = loader.loadClass("com.cloud.consoleproxy.ConsoleProxy");
+                Method methodSetup = consoleProxyClazz.getMethod("setEncryptorPassword", String.class);
+                methodSetup.invoke(null, encryptorPassword);
+            } catch (SecurityException e) {
+                s_logger.error("Unable to launch console proxy due to SecurityException", e);
+                System.exit(ExitStatus.Error.value());
+            } catch (NoSuchMethodException e) {
+                s_logger.error("Unable to launch console proxy due to NoSuchMethodException", e);
+                System.exit(ExitStatus.Error.value());
+            } catch (IllegalArgumentException e) {
+                s_logger.error("Unable to launch console proxy due to IllegalArgumentException", e);
+                System.exit(ExitStatus.Error.value());
+            } catch (IllegalAccessException e) {
+                s_logger.error("Unable to launch console proxy due to IllegalAccessException", e);
+                System.exit(ExitStatus.Error.value());
+            } catch (InvocationTargetException e) {
+                s_logger.error("Unable to launch console proxy due to InvocationTargetException " + e.getTargetException().toString(), e);
+                System.exit(ExitStatus.Error.value());
+            } catch (final ClassNotFoundException e) {
+                s_logger.error("Unable to launch console proxy due to ClassNotFoundException", e);
+                System.exit(ExitStatus.Error.value());
+            }
+        }
+    }
+
+    public String authenticateConsoleAccess(String host, String port, String vmId, String sid, String ticket, Boolean isReauthentication) {
+
+        ConsoleAccessAuthenticationCommand cmd = new ConsoleAccessAuthenticationCommand(host, port, vmId, sid, ticket);
+        cmd.setReauthenticating(isReauthentication);
+
+        ConsoleProxyAuthenticationResult result = new ConsoleProxyAuthenticationResult();
+        result.setSuccess(false);
+        result.setReauthentication(isReauthentication);
+
+        try {
+            AgentControlAnswer answer = getAgentControl().sendRequest(cmd, 10000);
+
+            if (answer != null) {
+                ConsoleAccessAuthenticationAnswer authAnswer = (ConsoleAccessAuthenticationAnswer)answer;
+                result.setSuccess(authAnswer.succeeded());
+                result.setHost(authAnswer.getHost());
+                result.setPort(authAnswer.getPort());
+                result.setTunnelUrl(authAnswer.getTunnelUrl());
+                result.setTunnelSession(authAnswer.getTunnelSession());
+            } else {
+                s_logger.error("Authentication failed for vm: " + vmId + " with sid: " + sid);
+            }
+        } catch (AgentControlChannelException e) {
+            s_logger.error("Unable to send out console access authentication request due to " + e.getMessage(), e);
+        }
+
+        return new Gson().toJson(result);
+    }
+
+    public void reportLoadInfo(String gsonLoadInfo) {
+        ConsoleProxyLoadReportCommand cmd = new ConsoleProxyLoadReportCommand(_proxyVmId, gsonLoadInfo);
+        try {
+            getAgentControl().postRequest(cmd);
+
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Report proxy load info, proxy : " + _proxyVmId + ", load: " + gsonLoadInfo);
+        } catch (AgentControlChannelException e) {
+            s_logger.error("Unable to send out load info due to " + e.getMessage(), e);
+        }
+    }
+
+    public void ensureRoute(String address) {
+        if (_localgw != null) {
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Ensure route for " + address + " via " + _localgw);
+
+            // this method won't be called in high frequency, serialize access
+            // to script execution
+            synchronized (this) {
+                try {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, address);
+                } catch (Throwable e) {
+                    s_logger.warn("Unexpected exception while adding internal route to " + address, e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setName(String name) {
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        return new HashMap<String, Object>();
+    }
+
+    @Override
+    public int getRunLevel() {
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+    }
+}
diff --git a/agent/src/com/cloud/agent/vmdata/VmDataServer.java b/agent/src/main/java/com/cloud/agent/vmdata/VmDataServer.java
similarity index 100%
rename from agent/src/com/cloud/agent/vmdata/VmDataServer.java
rename to agent/src/main/java/com/cloud/agent/vmdata/VmDataServer.java
diff --git a/agent/test/com/cloud/agent/AgentShellTest.java b/agent/src/test/java/com/cloud/agent/AgentShellTest.java
similarity index 100%
rename from agent/test/com/cloud/agent/AgentShellTest.java
rename to agent/src/test/java/com/cloud/agent/AgentShellTest.java
diff --git a/agent/test/com/cloud/agent/dao/impl/PropertiesStorageTest.java b/agent/src/test/java/com/cloud/agent/dao/impl/PropertiesStorageTest.java
similarity index 100%
rename from agent/test/com/cloud/agent/dao/impl/PropertiesStorageTest.java
rename to agent/src/test/java/com/cloud/agent/dao/impl/PropertiesStorageTest.java
diff --git a/agent/test/com/cloud/agent/direct/download/DirectTemplateDownloaderImplTest.java b/agent/src/test/java/com/cloud/agent/direct/download/DirectTemplateDownloaderImplTest.java
similarity index 100%
rename from agent/test/com/cloud/agent/direct/download/DirectTemplateDownloaderImplTest.java
rename to agent/src/test/java/com/cloud/agent/direct/download/DirectTemplateDownloaderImplTest.java
diff --git a/api/pom.xml b/api/pom.xml
index a57c019..f8a4903 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -1,85 +1,85 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-api</artifactId>
-  <name>Apache CloudStack API</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>javax.servlet-api</artifactId>
-      <version>${cs.servlet.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-      <version>${cs.commons-lang3.version}</version>
-    </dependency>
-    <dependency>
+<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-api</artifactId>
+    <name>Apache CloudStack API</name>
+    <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-framework-direct-download</artifactId>
-        <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${cs.commons-lang3.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-direct-download</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java b/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java
deleted file mode 100644
index 901dfd7..0000000
--- a/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.cloud.agent.api.storage;
-
-// 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.
diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java
deleted file mode 100644
index 3863e1b..0000000
--- a/api/src/com/cloud/agent/api/to/NicTO.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to;
-
-import com.cloud.offering.NetworkOffering;
-
-import java.util.List;
-import java.util.Map;
-
-public class NicTO extends NetworkTO {
-    int deviceId;
-    Integer networkRateMbps;
-    Integer networkRateMulticastMbps;
-    boolean defaultNic;
-    boolean pxeDisable;
-    String nicUuid;
-    List<String> nicSecIps;
-    Map<NetworkOffering.Detail, String> details;
-
-    public NicTO() {
-        super();
-    }
-
-    public void setDeviceId(int deviceId) {
-        this.deviceId = deviceId;
-    }
-
-    public int getDeviceId() {
-        return deviceId;
-    }
-
-    public Integer getNetworkRateMbps() {
-        return networkRateMbps;
-    }
-
-    public void setNetworkRateMbps(Integer networkRateMbps) {
-        this.networkRateMbps = networkRateMbps;
-    }
-
-    public Integer getNetworkRateMulticastMbps() {
-        return networkRateMulticastMbps;
-    }
-
-    public boolean isDefaultNic() {
-        return defaultNic;
-    }
-
-    public void setDefaultNic(boolean defaultNic) {
-        this.defaultNic = defaultNic;
-    }
-
-    public void setPxeDisable(boolean pxeDisable) {
-        this.pxeDisable = pxeDisable;
-    }
-
-    public boolean getPxeDisable() {
-        return pxeDisable;
-    }
-
-    @Override
-    public String getUuid() {
-        return nicUuid;
-    }
-
-    @Override
-    public void setUuid(String uuid) {
-        this.nicUuid = uuid;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString();
-    }
-
-    public void setNicSecIps(List<String> secIps) {
-        this.nicSecIps = secIps;
-    }
-
-    public List<String> getNicSecIps() {
-        return nicSecIps;
-    }
-
-    public String getNetworkUuid() {
-        return super.getUuid();
-    }
-
-    public void setNetworkUuid(String uuid) {
-        super.setUuid(uuid);
-    }
-
-    public Map<NetworkOffering.Detail, String> getDetails() {
-        return details;
-    }
-
-    public void setDetails(final Map<NetworkOffering.Detail, String> details) {
-        this.details = details;
-    }
-}
diff --git a/api/src/com/cloud/agent/api/to/S3TO.java b/api/src/com/cloud/agent/api/to/S3TO.java
deleted file mode 100644
index ec6bc02..0000000
--- a/api/src/com/cloud/agent/api/to/S3TO.java
+++ /dev/null
@@ -1,337 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to;
-
-import java.util.Date;
-
-import com.cloud.agent.api.LogLevel;
-import com.cloud.agent.api.LogLevel.Log4jLevel;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.utils.storage.S3.ClientOptions;
-
-public final class S3TO implements ClientOptions, DataStoreTO {
-
-    private Long id;
-    private String uuid;
-    @LogLevel(Log4jLevel.Off)
-    private String accessKey;
-    @LogLevel(Log4jLevel.Off)
-    private String secretKey;
-    private String endPoint;
-    private String bucketName;
-    private String signer;
-    private Boolean httpsFlag;
-    private Boolean useTCPKeepAlive;
-    private Integer connectionTimeout;
-    private Integer maxErrorRetry;
-    private Integer socketTimeout;
-    private Integer connectionTtl;
-    private Date created;
-    private boolean enableRRS;
-    private long maxSingleUploadSizeInBytes;
-    private static final String pathSeparator = "/";
-
-    public S3TO(final Long id, final String uuid, final String accessKey, final String secretKey, final String endPoint, final String bucketName,
-            final String signer, final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, final Integer socketTimeout,
-            final Date created, final boolean enableRRS, final long maxUploadSize, final Integer connectionTtl, final Boolean useTCPKeepAlive) {
-
-        this.id = id;
-        this.uuid = uuid;
-        this.accessKey = accessKey;
-        this.secretKey = secretKey;
-        this.endPoint = endPoint;
-        this.bucketName = bucketName;
-        this.signer = signer;
-        this.httpsFlag = httpsFlag;
-        this.connectionTimeout = connectionTimeout;
-        this.maxErrorRetry = maxErrorRetry;
-        this.socketTimeout = socketTimeout;
-        this.created = created;
-        this.enableRRS = enableRRS;
-        this.maxSingleUploadSizeInBytes = maxUploadSize;
-        this.connectionTtl = connectionTtl;
-        this.useTCPKeepAlive = useTCPKeepAlive;
-
-    }
-
-    public Long getId() {
-        return this.id;
-    }
-
-    public void setId(final Long id) {
-        this.id = id;
-    }
-
-    @Override
-    public String getUuid() {
-        return this.uuid;
-    }
-
-    @Override
-    public String getUrl() {
-        return null;
-    }
-
-    public void setUuid(final String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public String getAccessKey() {
-        return this.accessKey;
-    }
-
-    public void setAccessKey(final String accessKey) {
-        this.accessKey = accessKey;
-    }
-
-    @Override
-    public String getSecretKey() {
-        return this.secretKey;
-    }
-
-    public void setSecretKey(final String secretKey) {
-        this.secretKey = secretKey;
-    }
-
-    @Override
-    public String getEndPoint() {
-        return this.endPoint;
-    }
-
-    public void setEndPoint(final String endPoint) {
-        this.endPoint = endPoint;
-    }
-
-    public String getBucketName() {
-        return this.bucketName;
-    }
-
-    public void setBucketName(final String bucketName) {
-        this.bucketName = bucketName;
-    }
-
-    @Override
-    public String getSigner() {
-        return this.signer;
-    }
-
-    public void setSigner(final String signer) {
-        this.signer = signer;
-    }
-
-    @Override
-    public Boolean isHttps() {
-        return this.httpsFlag;
-    }
-
-    public void setHttps(final Boolean httpsFlag) {
-        this.httpsFlag = httpsFlag;
-    }
-
-    @Override
-    public Integer getConnectionTimeout() {
-        return connectionTimeout;
-    }
-
-    public void setConnectionTimeout(final Integer connectionTimeout) {
-        this.connectionTimeout = connectionTimeout;
-    }
-
-    @Override
-    public Integer getMaxErrorRetry() {
-        return maxErrorRetry;
-    }
-
-    public void setMaxErrorRetry(final Integer maxErrorRetry) {
-        this.maxErrorRetry = maxErrorRetry;
-    }
-
-    @Override
-    public Integer getSocketTimeout() {
-        return socketTimeout;
-    }
-
-    public void setSocketTimeout(final Integer socketTimeout) {
-        this.socketTimeout = socketTimeout;
-    }
-
-    @Override
-    public Integer getConnectionTtl() {
-        return this.connectionTtl;
-    }
-
-    public void setConnectionTtl(final Integer connectionTtl) {
-        this.connectionTtl = connectionTtl;
-    }
-
-    @Override
-    public Boolean getUseTCPKeepAlive() {
-        return this.useTCPKeepAlive;
-    }
-
-    public void setUseTCPKeepAlive(final Boolean useTCPKeepAlive) {
-        this.useTCPKeepAlive = useTCPKeepAlive;
-    }
-
-    public Date getCreated() {
-        return this.created;
-    }
-
-    public void setCreated(final Date created) {
-        this.created = created;
-    }
-
-    @Override
-    public DataStoreRole getRole() {
-        return DataStoreRole.Image;
-    }
-
-    public boolean getEnableRRS() {
-        return enableRRS;
-    }
-
-    public void setEnableRRS(boolean enableRRS) {
-        this.enableRRS = enableRRS;
-    }
-
-    public long getMaxSingleUploadSizeInBytes() {
-        return maxSingleUploadSizeInBytes;
-    }
-
-    public void setMaxSingleUploadSizeInBytes(long maxSingleUploadSizeInBytes) {
-        this.maxSingleUploadSizeInBytes = maxSingleUploadSizeInBytes;
-    }
-
-    public boolean getSingleUpload(long objSize) {
-        if (maxSingleUploadSizeInBytes < 0) {
-            // always use single part upload
-            return true;
-        } else if (maxSingleUploadSizeInBytes == 0) {
-            // always use multi part upload
-            return false;
-        } else {
-            // check object size to set flag
-            if (objSize < maxSingleUploadSizeInBytes) {
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public String getPathSeparator() {
-        return pathSeparator;
-    }
-
-    @Override
-    public boolean equals(final Object thatObject) {
-
-        if (this == thatObject) {
-            return true;
-        }
-        if (thatObject == null || getClass() != thatObject.getClass()) {
-            return false;
-        }
-
-        final S3TO thatS3TO = (S3TO)thatObject;
-
-        if (httpsFlag != null ? !httpsFlag.equals(thatS3TO.httpsFlag) : thatS3TO.httpsFlag != null) {
-            return false;
-        }
-
-        if (accessKey != null ? !accessKey.equals(thatS3TO.accessKey) : thatS3TO.accessKey != null) {
-            return false;
-        }
-
-        if (connectionTimeout != null ? !connectionTimeout.equals(thatS3TO.connectionTimeout) : thatS3TO.connectionTimeout != null) {
-            return false;
-        }
-
-        if (endPoint != null ? !endPoint.equals(thatS3TO.endPoint) : thatS3TO.endPoint != null) {
-            return false;
-        }
-
-        if (id != null ? !id.equals(thatS3TO.id) : thatS3TO.id != null) {
-            return false;
-        }
-
-        if (uuid != null ? !uuid.equals(thatS3TO.uuid) : thatS3TO.uuid != null) {
-            return false;
-        }
-
-        if (maxErrorRetry != null ? !maxErrorRetry.equals(thatS3TO.maxErrorRetry) : thatS3TO.maxErrorRetry != null) {
-            return false;
-        }
-
-        if (secretKey != null ? !secretKey.equals(thatS3TO.secretKey) : thatS3TO.secretKey != null) {
-            return false;
-        }
-
-        if (socketTimeout != null ? !socketTimeout.equals(thatS3TO.socketTimeout) : thatS3TO.socketTimeout != null) {
-            return false;
-        }
-
-        if (connectionTtl != null ? !connectionTtl.equals(thatS3TO.connectionTtl) : thatS3TO.connectionTtl != null) {
-            return false;
-        }
-
-        if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatS3TO.useTCPKeepAlive) : thatS3TO.useTCPKeepAlive != null) {
-            return false;
-        }
-
-        if (bucketName != null ? !bucketName.equals(thatS3TO.bucketName) : thatS3TO.bucketName != null) {
-            return false;
-        }
-
-        if (signer != null ? !signer.equals(thatS3TO.signer) : thatS3TO.signer != null) {
-            return false;
-        }
-
-        if (created != null ? !created.equals(thatS3TO.created) : thatS3TO.created != null) {
-            return false;
-        }
-
-        if (enableRRS != thatS3TO.enableRRS) {
-            return false;
-        }
-
-        return true;
-
-    }
-
-    @Override
-    public int hashCode() {
-
-        int result = id != null ? id.hashCode() : 0;
-
-        result = 31 * result + (accessKey != null ? accessKey.hashCode() : 0);
-        result = 31 * result + (secretKey != null ? secretKey.hashCode() : 0);
-        result = 31 * result + (endPoint != null ? endPoint.hashCode() : 0);
-        result = 31 * result + (bucketName != null ? bucketName.hashCode() : 0);
-        result = 31 * result + (signer != null ? signer.hashCode() : 0);
-        result = 31 * result + (httpsFlag ? 1 : 0);
-        result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
-        result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
-        result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
-        result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
-        result = 31 * result + (useTCPKeepAlive ? 1 : 0);
-
-        return result;
-    }
-}
diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
deleted file mode 100644
index 84a6bf5..0000000
--- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java
+++ /dev/null
@@ -1,353 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to;
-
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-
-public class VirtualMachineTO {
-    private long id;
-    private String name;
-    private BootloaderType bootloader;
-    Type type;
-    int cpus;
-
-    /**
-        'speed' is still here since 4.0.X/4.1.X management servers do not support
-         the overcommit feature yet.
-
-         The overcommit feature sends minSpeed and maxSpeed
-
-         So this is here for backwards compatibility with 4.0.X/4.1.X management servers
-         and newer agents.
-    */
-    Integer speed;
-    Integer minSpeed;
-    Integer maxSpeed;
-
-    long minRam;
-    long maxRam;
-    String hostName;
-    String arch;
-    String os;
-    String platformEmulator;
-    String bootArgs;
-    String[] bootupScripts;
-    boolean enableHA;
-    boolean limitCpuUse;
-    boolean enableDynamicallyScaleVm;
-    String vncPassword;
-    String vncAddr;
-    Map<String, String> params;
-    String uuid;
-
-    DiskTO[] disks;
-    NicTO[] nics;
-    GPUDeviceTO gpuDevice;
-    Integer vcpuMaxLimit;
-    List<String[]> vmData = null;
-
-    String configDriveLabel = null;
-    String configDriveIsoRootFolder = null;
-    String configDriveIsoFile = null;
-
-    Double cpuQuotaPercentage = null;
-
-    Map<String, String> guestOsDetails = new HashMap<String, String>();
-
-    public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
-            String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
-        this.id = id;
-        name = instanceName;
-        this.type = type;
-        this.cpus = cpus;
-        this.speed = speed;
-        this.minRam = minRam;
-        this.maxRam = maxRam;
-        this.bootloader = bootloader;
-        this.os = os;
-        this.enableHA = enableHA;
-        this.limitCpuUse = limitCpuUse;
-        this.vncPassword = vncPassword;
-    }
-
-    public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer minSpeed, Integer maxSpeed, long minRam, long maxRam,
-            BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
-        this.id = id;
-        name = instanceName;
-        this.type = type;
-        this.cpus = cpus;
-        this.minSpeed = minSpeed;
-        this.maxSpeed = maxSpeed;
-        this.minRam = minRam;
-        this.maxRam = maxRam;
-        this.bootloader = bootloader;
-        this.os = os;
-        this.enableHA = enableHA;
-        this.limitCpuUse = limitCpuUse;
-        this.vncPassword = vncPassword;
-    }
-
-    protected VirtualMachineTO() {
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public boolean isEnableDynamicallyScaleVm() {
-        return enableDynamicallyScaleVm;
-    }
-
-    public void setEnableDynamicallyScaleVm(boolean enableDynamicallyScaleVm) {
-        this.enableDynamicallyScaleVm = enableDynamicallyScaleVm;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    public BootloaderType getBootloader() {
-        return bootloader;
-    }
-
-    public void setBootloader(BootloaderType bootloader) {
-        this.bootloader = bootloader;
-    }
-
-    public int getCpus() {
-        return cpus;
-    }
-
-    public void setCpus(int cpus) {
-        this.cpus = cpus;
-    }
-
-    public Integer getSpeed() {
-        return speed;
-    }
-
-    public Integer getMinSpeed() {
-        return minSpeed;
-    }
-
-    public Integer getMaxSpeed() {
-        return maxSpeed;
-    }
-
-    public boolean getLimitCpuUse() {
-        return limitCpuUse;
-    }
-
-    public long getMinRam() {
-        return minRam;
-    }
-
-    public void setRam(long minRam, long maxRam) {
-        this.minRam = minRam;
-        this.maxRam = maxRam;
-    }
-
-    public long getMaxRam() {
-        return maxRam;
-    }
-
-    public String getHostName() {
-        return hostName;
-    }
-
-    public void setHostName(String hostName) {
-        this.hostName = hostName;
-    }
-
-    public String getArch() {
-        return arch;
-    }
-
-    public void setArch(String arch) {
-        this.arch = arch;
-    }
-
-    public String getOs() {
-        return os;
-    }
-
-    public void setOs(String os) {
-        this.os = os;
-    }
-
-    public String getBootArgs() {
-        return bootArgs;
-    }
-
-    public void setBootArgs(String bootArgs) {
-        this.bootArgs = bootArgs;
-    }
-
-    public void setBootArgs(Map<String, String> bootParams) {
-        StringBuilder buf = new StringBuilder();
-        for (Map.Entry<String, String> entry : bootParams.entrySet()) {
-            buf.append(" ").append(entry.getKey()).append("=").append(entry.getValue());
-        }
-        bootArgs = buf.toString();
-    }
-
-    public String[] getBootupScripts() {
-        return bootupScripts;
-    }
-
-    public void setBootupScripts(String[] bootupScripts) {
-        this.bootupScripts = bootupScripts;
-    }
-
-    public DiskTO[] getDisks() {
-        return disks;
-    }
-
-    public void setDisks(DiskTO[] disks) {
-        this.disks = disks;
-    }
-
-    public NicTO[] getNics() {
-        return nics;
-    }
-
-    public void setNics(NicTO[] nics) {
-        this.nics = nics;
-    }
-
-    public String getVncPassword() {
-        return vncPassword;
-    }
-
-    public void setVncPassword(String vncPassword) {
-        this.vncPassword = vncPassword;
-    }
-
-    public String getVncAddr() {
-        return vncAddr;
-    }
-
-    public void setVncAddr(String vncAddr) {
-        this.vncAddr = vncAddr;
-    }
-
-    public Map<String, String> getDetails() {
-        return params;
-    }
-
-    public void setDetails(Map<String, String> params) {
-        this.params = params;
-    }
-
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public GPUDeviceTO getGpuDevice() {
-        return gpuDevice;
-    }
-
-    public void setGpuDevice(GPUDeviceTO gpuDevice) {
-        this.gpuDevice = gpuDevice;
-    }
-
-    public String getPlatformEmulator() {
-        return platformEmulator;
-    }
-
-    public void setPlatformEmulator(String platformEmulator) {
-        this.platformEmulator = platformEmulator;
-    }
-
-    public Integer getVcpuMaxLimit() {
-        return vcpuMaxLimit;
-    }
-
-    public void setVcpuMaxLimit(Integer vcpuMaxLimit) {
-        this.vcpuMaxLimit = vcpuMaxLimit;
-    }
-
-    public List<String[]> getVmData() {
-        return vmData;
-    }
-
-    public void setVmData(List<String[]> vmData) {
-        this.vmData = vmData;
-    }
-
-    public String getConfigDriveLabel() {
-        return configDriveLabel;
-    }
-
-    public void setConfigDriveLabel(String configDriveLabel) {
-        this.configDriveLabel = configDriveLabel;
-    }
-
-    public String getConfigDriveIsoRootFolder() {
-        return configDriveIsoRootFolder;
-    }
-
-    public void setConfigDriveIsoRootFolder(String configDriveIsoRootFolder) {
-        this.configDriveIsoRootFolder = configDriveIsoRootFolder;
-    }
-
-    public String getConfigDriveIsoFile() {
-        return configDriveIsoFile;
-    }
-
-    public void setConfigDriveIsoFile(String configDriveIsoFile) {
-        this.configDriveIsoFile = configDriveIsoFile;
-    }
-
-    public Map<String, String> getGuestOsDetails() {
-        return guestOsDetails;
-    }
-
-    public void setGuestOsDetails(Map<String, String> guestOsDetails) {
-        this.guestOsDetails = guestOsDetails;
-    }
-
-    public Double getCpuQuotaPercentage() {
-        return cpuQuotaPercentage;
-    }
-
-    public void setCpuQuotaPercentage(Double cpuQuotaPercentage) {
-        this.cpuQuotaPercentage = cpuQuotaPercentage;
-    }
-}
diff --git a/api/src/com/cloud/alert/Alert.java b/api/src/com/cloud/alert/Alert.java
deleted file mode 100644
index f774420..0000000
--- a/api/src/com/cloud/alert/Alert.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.alert;
-
-import java.util.Date;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface Alert extends Identity, InternalIdentity {
-    short getType();
-
-    String getSubject();
-
-    Long getPodId();
-
-    long getDataCenterId();
-
-    int getSentCount();
-
-    Date getCreatedDate();
-
-    Date getLastSent();
-
-    Date getResolved();
-
-    boolean getArchived();
-
-    String getName();
-}
diff --git a/api/src/com/cloud/deploy/DeployDestination.java b/api/src/com/cloud/deploy/DeployDestination.java
deleted file mode 100644
index eadc64e..0000000
--- a/api/src/com/cloud/deploy/DeployDestination.java
+++ /dev/null
@@ -1,157 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deploy;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.host.Host;
-import com.cloud.org.Cluster;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.utils.NumbersUtil;
-
-public class DeployDestination implements Serializable {
-    private static final long serialVersionUID = 7113840781939014695L;
-
-    DataCenter _dc;
-    Pod _pod;
-    Cluster _cluster;
-    Host _host;
-    Map<Volume, StoragePool> _storage;
-
-    public DataCenter getDataCenter() {
-        return _dc;
-    }
-
-    public Pod getPod() {
-        return _pod;
-    }
-
-    public Cluster getCluster() {
-        return _cluster;
-    }
-
-    public Host getHost() {
-        return _host;
-    }
-
-    public Map<Volume, StoragePool> getStorageForDisks() {
-        return _storage;
-    }
-
-    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host) {
-        _dc = dc;
-        _pod = pod;
-        _cluster = cluster;
-        _host = host;
-    }
-
-    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host, Map<Volume, StoragePool> storage) {
-        this(dc, pod, cluster, host);
-        _storage = storage;
-    }
-
-    public DeployDestination() {
-    }
-
-    @Override
-    public int hashCode() {
-        return NumbersUtil.hash(_host.getId());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        DeployDestination that = (DeployDestination)obj;
-        if (_dc == null || that._dc == null) {
-            return false;
-        }
-        if (_dc.getId() != that._dc.getId()) {
-            return false;
-        }
-        if (_pod == null || that._pod == null) {
-            return false;
-        }
-        if (_pod.getId() != that._pod.getId()) {
-            return false;
-        }
-        if (_cluster == null || that._cluster == null) {
-            return false;
-        }
-        if (_cluster.getId() != that._cluster.getId()) {
-            return false;
-        }
-        if (_host == null || that._host == null) {
-            return false;
-        }
-        return _host.getId() == that._host.getId();
-    }
-
-    @Override
-    public String toString() {
-
-        Long dcId = null;
-        Long podId = null;
-        Long clusterId = null;
-        Long hostId = null;
-
-        if (_dc != null) {
-            dcId = _dc.getId();
-        }
-
-        if (_pod != null) {
-            podId = _pod.getId();
-        }
-
-        if (_cluster != null) {
-            clusterId = _cluster.getId();
-        }
-
-        if (_host != null) {
-            hostId = _host.getId();
-        }
-
-        StringBuilder destination = new StringBuilder("Dest[Zone(Id)-Pod(Id)-Cluster(Id)-Host(Id)-Storage(Volume(Id|Type-->Pool(Id))] : Dest[");
-        destination.append("Zone(").append(dcId).append(")").append("-");
-        destination.append("Pod(").append(podId).append(")").append("-");
-        destination.append("Cluster(").append(clusterId).append(")").append("-");
-        destination.append("Host(").append(hostId).append(")").append("-");
-        destination.append("Storage(");
-        if (_storage != null) {
-            StringBuffer storageBuf = new StringBuffer();
-            //String storageStr = "";
-            for (Volume vol : _storage.keySet()) {
-                if (!storageBuf.toString().equals("")) {
-                    storageBuf.append(storageBuf.toString());
-                    storageBuf.append(", ");
-                }
-                storageBuf.append(storageBuf);
-                storageBuf.append("Volume(");
-                storageBuf.append(vol.getId());
-                storageBuf.append("|");
-                storageBuf.append(vol.getVolumeType().name());
-                storageBuf.append("-->Pool(");
-                storageBuf.append(_storage.get(vol).getId());
-                storageBuf.append(")");
-            }
-            destination.append(storageBuf.toString());
-        }
-        return destination.append(")]").toString();
-    }
-}
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
deleted file mode 100644
index 907b93e..0000000
--- a/api/src/com/cloud/event/EventTypes.java
+++ /dev/null
@@ -1,1010 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.event;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.dc.StorageNetworkIpRange;
-import com.cloud.dc.Vlan;
-import com.cloud.domain.Domain;
-import com.cloud.host.Host;
-import com.cloud.network.GuestVlan;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PhysicalNetworkTrafficType;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteCustomerGateway;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.Site2SiteVpnGateway;
-import com.cloud.network.as.AutoScaleCounter;
-import com.cloud.network.as.AutoScalePolicy;
-import com.cloud.network.as.AutoScaleVmGroup;
-import com.cloud.network.as.AutoScaleVmProfile;
-import com.cloud.network.as.Condition;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.HealthCheckPolicy;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StickinessPolicy;
-import com.cloud.network.security.SecurityGroup;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.projects.Project;
-import com.cloud.server.ResourceTag;
-import com.cloud.storage.GuestOS;
-import com.cloud.storage.GuestOSHypervisor;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.storage.snapshot.SnapshotPolicy;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.VirtualMachine;
-import org.apache.cloudstack.acl.Role;
-import org.apache.cloudstack.acl.RolePermission;
-import org.apache.cloudstack.annotation.Annotation;
-import org.apache.cloudstack.config.Configuration;
-import org.apache.cloudstack.ha.HAConfig;
-import org.apache.cloudstack.usage.Usage;
-
-public class EventTypes {
-
-    //map of Event and corresponding entity for which Event is applicable
-    private static Map<String, Object> entityEventDetails = null;
-
-    // VM Events
-    public static final String EVENT_VM_CREATE = "VM.CREATE";
-    public static final String EVENT_VM_DESTROY = "VM.DESTROY";
-    public static final String EVENT_VM_START = "VM.START";
-    public static final String EVENT_VM_STOP = "VM.STOP";
-    public static final String EVENT_VM_REBOOT = "VM.REBOOT";
-    public static final String EVENT_VM_UPDATE = "VM.UPDATE";
-    public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
-    public static final String EVENT_VM_DYNAMIC_SCALE = "VM.DYNAMIC.SCALE";
-    public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
-    public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
-    public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
-    public static final String EVENT_VM_MOVE = "VM.MOVE";
-    public static final String EVENT_VM_RESTORE = "VM.RESTORE";
-    public static final String EVENT_VM_EXPUNGE = "VM.EXPUNGE";
-
-    // Domain Router
-    public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE";
-    public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY";
-    public static final String EVENT_ROUTER_START = "ROUTER.START";
-    public static final String EVENT_ROUTER_STOP = "ROUTER.STOP";
-    public static final String EVENT_ROUTER_REBOOT = "ROUTER.REBOOT";
-    public static final String EVENT_ROUTER_HA = "ROUTER.HA";
-    public static final String EVENT_ROUTER_UPGRADE = "ROUTER.UPGRADE";
-
-    // Console proxy
-    public static final String EVENT_PROXY_CREATE = "PROXY.CREATE";
-    public static final String EVENT_PROXY_DESTROY = "PROXY.DESTROY";
-    public static final String EVENT_PROXY_START = "PROXY.START";
-    public static final String EVENT_PROXY_STOP = "PROXY.STOP";
-    public static final String EVENT_PROXY_REBOOT = "PROXY.REBOOT";
-    public static final String EVENT_PROXY_HA = "PROXY.HA";
-
-    // VNC Console Events
-    public static final String EVENT_VNC_CONNECT = "VNC.CONNECT";
-    public static final String EVENT_VNC_DISCONNECT = "VNC.DISCONNECT";
-
-    // Network Events
-    public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN";
-    public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE";
-    public static final String EVENT_NET_IP_UPDATE = "NET.IPUPDATE";
-    public static final String EVENT_PORTABLE_IP_ASSIGN = "PORTABLE.IPASSIGN";
-    public static final String EVENT_PORTABLE_IP_RELEASE = "PORTABLE.IPRELEASE";
-    public static final String EVENT_NET_RULE_ADD = "NET.RULEADD";
-    public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE";
-    public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY";
-    public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE";
-    public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE";
-    public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE";
-    public static final String EVENT_NETWORK_MIGRATE = "NETWORK.MIGRATE";
-    public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN";
-    public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
-    public static final String EVENT_FIREWALL_UPDATE = "FIREWALL.UPDATE";
-
-    public static final String EVENT_FIREWALL_EGRESS_OPEN = "FIREWALL.EGRESS.OPEN";
-    public static final String EVENT_FIREWALL_EGRESS_CLOSE = "FIREWALL.EGRESS.CLOSE";
-    public static final String EVENT_FIREWALL_EGRESS_UPDATE = "FIREWALL.EGRESS.UPDATE";
-
-    //NIC Events
-    public static final String EVENT_NIC_CREATE = "NIC.CREATE";
-    public static final String EVENT_NIC_DELETE = "NIC.DELETE";
-    public static final String EVENT_NIC_UPDATE = "NIC.UPDATE";
-    public static final String EVENT_NIC_DETAIL_ADD = "NIC.DETAIL.ADD";
-    public static final String EVENT_NIC_DETAIL_UPDATE = "NIC.DETAIL.UPDATE";
-    public static final String EVENT_NIC_DETAIL_REMOVE = "NIC.DETAIL.REMOVE";
-
-    // Load Balancers
-    public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE";
-    public static final String EVENT_REMOVE_FROM_LOAD_BALANCER_RULE = "LB.REMOVE.FROM.RULE";
-    public static final String EVENT_LOAD_BALANCER_CREATE = "LB.CREATE";
-    public static final String EVENT_LOAD_BALANCER_DELETE = "LB.DELETE";
-    public static final String EVENT_LB_STICKINESSPOLICY_CREATE = "LB.STICKINESSPOLICY.CREATE";
-    public static final String EVENT_LB_STICKINESSPOLICY_UPDATE = "LB.STICKINESSPOLICY.UPDATE";
-    public static final String EVENT_LB_STICKINESSPOLICY_DELETE = "LB.STICKINESSPOLICY.DELETE";
-    public static final String EVENT_LB_HEALTHCHECKPOLICY_CREATE = "LB.HEALTHCHECKPOLICY.CREATE";
-    public static final String EVENT_LB_HEALTHCHECKPOLICY_DELETE = "LB.HEALTHCHECKPOLICY.DELETE";
-    public static final String EVENT_LB_HEALTHCHECKPOLICY_UPDATE = "LB.HEALTHCHECKPOLICY.UPDATE";
-    public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE";
-    public static final String EVENT_LB_CERT_UPLOAD = "LB.CERT.UPLOAD";
-    public static final String EVENT_LB_CERT_DELETE = "LB.CERT.DELETE";
-    public static final String EVENT_LB_CERT_ASSIGN = "LB.CERT.ASSIGN";
-    public static final String EVENT_LB_CERT_REMOVE = "LB.CERT.REMOVE";
-
-    // Global Load Balancer rules
-    public static final String EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.ASSIGN";
-    public static final String EVENT_REMOVE_FROM_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.REMOVE";
-    public static final String EVENT_GLOBAL_LOAD_BALANCER_CREATE = "GLOBAL.LB.CREATE";
-    public static final String EVENT_GLOBAL_LOAD_BALANCER_DELETE = "GLOBAL.LB.DELETE";
-    public static final String EVENT_GLOBAL_LOAD_BALANCER_UPDATE = "GLOBAL.LB.UPDATE";
-
-    // Role events
-    public static final String EVENT_ROLE_CREATE = "ROLE.CREATE";
-    public static final String EVENT_ROLE_UPDATE = "ROLE.UPDATE";
-    public static final String EVENT_ROLE_DELETE = "ROLE.DELETE";
-    public static final String EVENT_ROLE_PERMISSION_CREATE = "ROLE.PERMISSION.CREATE";
-    public static final String EVENT_ROLE_PERMISSION_UPDATE = "ROLE.PERMISSION.UPDATE";
-    public static final String EVENT_ROLE_PERMISSION_DELETE = "ROLE.PERMISSION.DELETE";
-
-    // CA events
-    public static final String EVENT_CA_CERTIFICATE_ISSUE = "CA.CERTIFICATE.ISSUE";
-    public static final String EVENT_CA_CERTIFICATE_REVOKE = "CA.CERTIFICATE.REVOKE";
-    public static final String EVENT_CA_CERTIFICATE_PROVISION = "CA.CERTIFICATE.PROVISION";
-
-    // Account events
-    public static final String EVENT_ACCOUNT_ENABLE = "ACCOUNT.ENABLE";
-    public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE";
-    public static final String EVENT_ACCOUNT_CREATE = "ACCOUNT.CREATE";
-    public static final String EVENT_ACCOUNT_DELETE = "ACCOUNT.DELETE";
-    public static final String EVENT_ACCOUNT_UPDATE = "ACCOUNT.UPDATE";
-    public static final String EVENT_ACCOUNT_MARK_DEFAULT_ZONE = "ACCOUNT.MARK.DEFAULT.ZONE";
-
-    // UserVO Events
-    public static final String EVENT_USER_LOGIN = "USER.LOGIN";
-    public static final String EVENT_USER_LOGOUT = "USER.LOGOUT";
-    public static final String EVENT_USER_CREATE = "USER.CREATE";
-    public static final String EVENT_USER_DELETE = "USER.DELETE";
-    public static final String EVENT_USER_DISABLE = "USER.DISABLE";
-    public static final String EVENT_USER_MOVE = "USER.MOVE";
-    public static final String EVENT_USER_UPDATE = "USER.UPDATE";
-    public static final String EVENT_USER_ENABLE = "USER.ENABLE";
-    public static final String EVENT_USER_LOCK = "USER.LOCK";
-
-    //registering SSH keypair events
-    public static final String EVENT_REGISTER_SSH_KEYPAIR = "REGISTER.SSH.KEYPAIR";
-
-    //register for user API and secret keys
-    public static final String EVENT_REGISTER_FOR_SECRET_API_KEY = "REGISTER.USER.KEY";
-
-    // Template Events
-    public static final String EVENT_TEMPLATE_CREATE = "TEMPLATE.CREATE";
-    public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE";
-    public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE";
-    public static final String EVENT_TEMPLATE_DOWNLOAD_START = "TEMPLATE.DOWNLOAD.START";
-    public static final String EVENT_TEMPLATE_DOWNLOAD_SUCCESS = "TEMPLATE.DOWNLOAD.SUCCESS";
-    public static final String EVENT_TEMPLATE_DOWNLOAD_FAILED = "TEMPLATE.DOWNLOAD.FAILED";
-    public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY";
-    public static final String EVENT_TEMPLATE_EXTRACT = "TEMPLATE.EXTRACT";
-    public static final String EVENT_TEMPLATE_UPLOAD = "TEMPLATE.UPLOAD";
-    public static final String EVENT_TEMPLATE_CLEANUP = "TEMPLATE.CLEANUP";
-
-    // Volume Events
-    public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE";
-    public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE";
-    public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH";
-    public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH";
-    public static final String EVENT_VOLUME_EXTRACT = "VOLUME.EXTRACT";
-    public static final String EVENT_VOLUME_UPLOAD = "VOLUME.UPLOAD";
-    public static final String EVENT_VOLUME_MIGRATE = "VOLUME.MIGRATE";
-    public static final String EVENT_VOLUME_RESIZE = "VOLUME.RESIZE";
-    public static final String EVENT_VOLUME_DETAIL_UPDATE = "VOLUME.DETAIL.UPDATE";
-    public static final String EVENT_VOLUME_DETAIL_ADD = "VOLUME.DETAIL.ADD";
-    public static final String EVENT_VOLUME_DETAIL_REMOVE = "VOLUME.DETAIL.REMOVE";
-    public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
-
-    // Domains
-    public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
-    public static final String EVENT_DOMAIN_DELETE = "DOMAIN.DELETE";
-    public static final String EVENT_DOMAIN_UPDATE = "DOMAIN.UPDATE";
-
-    // Snapshots
-    public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE";
-    public static final String EVENT_SNAPSHOT_ON_PRIMARY = "SNAPSHOT.ON_PRIMARY";
-    public static final String EVENT_SNAPSHOT_OFF_PRIMARY = "SNAPSHOT.OFF_PRIMARY";
-    public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE";
-    public static final String EVENT_SNAPSHOT_REVERT = "SNAPSHOT.REVERT";
-    public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE";
-    public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE";
-    public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE";
-
-    // ISO
-    public static final String EVENT_ISO_CREATE = "ISO.CREATE";
-    public static final String EVENT_ISO_DELETE = "ISO.DELETE";
-    public static final String EVENT_ISO_COPY = "ISO.COPY";
-    public static final String EVENT_ISO_ATTACH = "ISO.ATTACH";
-    public static final String EVENT_ISO_DETACH = "ISO.DETACH";
-    public static final String EVENT_ISO_EXTRACT = "ISO.EXTRACT";
-    public static final String EVENT_ISO_UPLOAD = "ISO.UPLOAD";
-
-    // SSVM
-    public static final String EVENT_SSVM_CREATE = "SSVM.CREATE";
-    public static final String EVENT_SSVM_DESTROY = "SSVM.DESTROY";
-    public static final String EVENT_SSVM_START = "SSVM.START";
-    public static final String EVENT_SSVM_STOP = "SSVM.STOP";
-    public static final String EVENT_SSVM_REBOOT = "SSVM.REBOOT";
-    public static final String EVENT_SSVM_HA = "SSVM.HA";
-
-    // Service Offerings
-    public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE";
-    public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT";
-    public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE";
-
-    // Disk Offerings
-    public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE";
-    public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT";
-    public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE";
-
-    // Network offerings
-    public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE";
-    public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN";
-    public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT";
-    public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE";
-    public static final String EVENT_NETWORK_OFFERING_DELETE = "NETWORK.OFFERING.DELETE";
-
-    // Pods
-    public static final String EVENT_POD_CREATE = "POD.CREATE";
-    public static final String EVENT_POD_EDIT = "POD.EDIT";
-    public static final String EVENT_POD_DELETE = "POD.DELETE";
-
-    // Zones
-    public static final String EVENT_ZONE_CREATE = "ZONE.CREATE";
-    public static final String EVENT_ZONE_EDIT = "ZONE.EDIT";
-    public static final String EVENT_ZONE_DELETE = "ZONE.DELETE";
-
-    // VLANs/IP ranges
-    public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE";
-    public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE";
-    public static final String EVENT_VLAN_IP_RANGE_DEDICATE = "VLAN.IP.RANGE.DEDICATE";
-    public static final String EVENT_VLAN_IP_RANGE_RELEASE = "VLAN.IP.RANGE.RELEASE";
-
-    public static final String EVENT_MANAGEMENT_IP_RANGE_CREATE = "MANAGEMENT.IP.RANGE.CREATE";
-    public static final String EVENT_MANAGEMENT_IP_RANGE_DELETE = "MANAGEMENT.IP.RANGE.DELETE";
-
-    public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE";
-    public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE";
-    public static final String EVENT_STORAGE_IP_RANGE_UPDATE = "STORAGE.IP.RANGE.UPDATE";
-
-    // Configuration Table
-    public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT";
-
-    // Security Groups
-    public static final String EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS = "SG.AUTH.INGRESS";
-    public static final String EVENT_SECURITY_GROUP_REVOKE_INGRESS = "SG.REVOKE.INGRESS";
-    public static final String EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS = "SG.AUTH.EGRESS";
-    public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS";
-    public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE";
-    public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE";
-    public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN";
-    public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE";
-
-    // Host
-    public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT";
-
-    // Host Out-of-band management
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_ENABLE = "HOST.OOBM.ENABLE";
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_DISABLE = "HOST.OOBM.DISABLE";
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_CONFIGURE = "HOST.OOBM.CONFIGURE";
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_ACTION = "HOST.OOBM.ACTION";
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_CHANGE_PASSWORD = "HOST.OOBM.CHANGEPASSWORD";
-    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_POWERSTATE_TRANSITION = "HOST.OOBM.POWERSTATE.TRANSITION";
-
-    // HA
-    public static final String EVENT_HA_RESOURCE_ENABLE = "HA.RESOURCE.ENABLE";
-    public static final String EVENT_HA_RESOURCE_DISABLE = "HA.RESOURCE.DISABLE";
-    public static final String EVENT_HA_RESOURCE_CONFIGURE = "HA.RESOURCE.CONFIGURE";
-    public static final String EVENT_HA_STATE_TRANSITION = "HA.STATE.TRANSITION";
-
-    // Maintenance
-    public static final String EVENT_MAINTENANCE_CANCEL = "MAINT.CANCEL";
-    public static final String EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE = "MAINT.CANCEL.PS";
-    public static final String EVENT_MAINTENANCE_PREPARE = "MAINT.PREPARE";
-    public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS";
-
-    // Primary storage pool
-    public static final String EVENT_ENABLE_PRIMARY_STORAGE = "ENABLE.PS";
-    public static final String EVENT_DISABLE_PRIMARY_STORAGE = "DISABLE.PS";
-
-    // VPN
-    public static final String EVENT_REMOTE_ACCESS_VPN_CREATE = "VPN.REMOTE.ACCESS.CREATE";
-    public static final String EVENT_REMOTE_ACCESS_VPN_DESTROY = "VPN.REMOTE.ACCESS.DESTROY";
-    public static final String EVENT_REMOTE_ACCESS_VPN_UPDATE = "VPN.REMOTE.ACCESS.UPDATE";
-    public static final String EVENT_VPN_USER_ADD = "VPN.USER.ADD";
-    public static final String EVENT_VPN_USER_REMOVE = "VPN.USER.REMOVE";
-    public static final String EVENT_S2S_VPN_GATEWAY_CREATE = "VPN.S2S.VPN.GATEWAY.CREATE";
-    public static final String EVENT_S2S_VPN_GATEWAY_DELETE = "VPN.S2S.VPN.GATEWAY.DELETE";
-    public static final String EVENT_S2S_VPN_GATEWAY_UPDATE = "VPN.S2S.VPN.GATEWAY.UPDATE";
-    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE";
-    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE";
-    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE";
-    public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE";
-    public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE";
-    public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET";
-    public static final String EVENT_S2S_VPN_CONNECTION_UPDATE = "VPN.S2S.CONNECTION.UPDATE";
-
-    // Network
-    public static final String EVENT_NETWORK_RESTART = "NETWORK.RESTART";
-
-    // Custom certificates
-    public static final String EVENT_UPLOAD_CUSTOM_CERTIFICATE = "UPLOAD.CUSTOM.CERTIFICATE";
-
-    // OneToOnenat
-    public static final String EVENT_ENABLE_STATIC_NAT = "STATICNAT.ENABLE";
-    public static final String EVENT_DISABLE_STATIC_NAT = "STATICNAT.DISABLE";
-
-    public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN";
-    public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE";
-
-    // Projects
-    public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE";
-    public static final String EVENT_PROJECT_UPDATE = "PROJECT.UPDATE";
-    public static final String EVENT_PROJECT_DELETE = "PROJECT.DELETE";
-    public static final String EVENT_PROJECT_ACTIVATE = "PROJECT.ACTIVATE";
-    public static final String EVENT_PROJECT_SUSPEND = "PROJECT.SUSPEND";
-    public static final String EVENT_PROJECT_ACCOUNT_ADD = "PROJECT.ACCOUNT.ADD";
-    public static final String EVENT_PROJECT_INVITATION_UPDATE = "PROJECT.INVITATION.UPDATE";
-    public static final String EVENT_PROJECT_INVITATION_REMOVE = "PROJECT.INVITATION.REMOVE";
-    public static final String EVENT_PROJECT_ACCOUNT_REMOVE = "PROJECT.ACCOUNT.REMOVE";
-
-    // Network as a Service
-    public static final String EVENT_NETWORK_ELEMENT_CONFIGURE = "NETWORK.ELEMENT.CONFIGURE";
-
-    // Physical Network Events
-    public static final String EVENT_PHYSICAL_NETWORK_CREATE = "PHYSICAL.NETWORK.CREATE";
-    public static final String EVENT_PHYSICAL_NETWORK_DELETE = "PHYSICAL.NETWORK.DELETE";
-    public static final String EVENT_PHYSICAL_NETWORK_UPDATE = "PHYSICAL.NETWORK.UPDATE";
-
-    // Physical Network Service Provider Events
-    public static final String EVENT_SERVICE_PROVIDER_CREATE = "SERVICE.PROVIDER.CREATE";
-    public static final String EVENT_SERVICE_PROVIDER_DELETE = "SERVICE.PROVIDER.DELETE";
-    public static final String EVENT_SERVICE_PROVIDER_UPDATE = "SERVICE.PROVIDER.UPDATE";
-
-    // Physical Network TrafficType Events
-    public static final String EVENT_TRAFFIC_TYPE_CREATE = "TRAFFIC.TYPE.CREATE";
-    public static final String EVENT_TRAFFIC_TYPE_DELETE = "TRAFFIC.TYPE.DELETE";
-    public static final String EVENT_TRAFFIC_TYPE_UPDATE = "TRAFFIC.TYPE.UPDATE";
-
-    // external network device events
-    public static final String EVENT_EXTERNAL_LB_DEVICE_ADD = "PHYSICAL.LOADBALANCER.ADD";
-    public static final String EVENT_EXTERNAL_LB_DEVICE_DELETE = "PHYSICAL.LOADBALANCER.DELETE";
-    public static final String EVENT_EXTERNAL_LB_DEVICE_CONFIGURE = "PHYSICAL.LOADBALANCER.CONFIGURE";
-
-    // external NCC device events
-    public static final String EVENT_EXTERNAL_NCC_DEVICE_ADD = "PHYSICAL.NCC.ADD";
-    public static final String EVENT_EXTERNAL_NCC_DEVICE_DELETE = "PHYSICAL.NCC.DELETE";
-
-    // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module.
-    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD = "SWITCH.MGMT.ADD";
-    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE = "SWITCH.MGMT.DELETE";
-    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE = "SWITCH.MGMT.CONFIGURE";
-    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE = "SWITCH.MGMT.ENABLE";
-    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE = "SWITCH.MGMT.DISABLE";
-
-    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_ADD = "PHYSICAL.FIREWALL.ADD";
-    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE = "PHYSICAL.FIREWALL.DELETE";
-    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE = "PHYSICAL.FIREWALL.CONFIGURE";
-
-    // VPC
-    public static final String EVENT_VPC_CREATE = "VPC.CREATE";
-    public static final String EVENT_VPC_UPDATE = "VPC.UPDATE";
-    public static final String EVENT_VPC_DELETE = "VPC.DELETE";
-    public static final String EVENT_VPC_RESTART = "VPC.RESTART";
-
-    // Network ACL
-    public static final String EVENT_NETWORK_ACL_CREATE = "NETWORK.ACL.CREATE";
-    public static final String EVENT_NETWORK_ACL_DELETE = "NETWORK.ACL.DELETE";
-    public static final String EVENT_NETWORK_ACL_REPLACE = "NETWORK.ACL.REPLACE";
-    public static final String EVENT_NETWORK_ACL_UPDATE = "NETWORK.ACL.UPDATE";
-    public static final String EVENT_NETWORK_ACL_ITEM_CREATE = "NETWORK.ACL.ITEM.CREATE";
-    public static final String EVENT_NETWORK_ACL_ITEM_UPDATE = "NETWORK.ACL.ITEM.UPDATE";
-    public static final String EVENT_NETWORK_ACL_ITEM_DELETE = "NETWORK.ACL.ITEM.DELETE";
-
-    // VPC offerings
-    public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE";
-    public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE";
-    public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE";
-
-    // Private gateway
-    public static final String EVENT_PRIVATE_GATEWAY_CREATE = "PRIVATE.GATEWAY.CREATE";
-    public static final String EVENT_PRIVATE_GATEWAY_DELETE = "PRIVATE.GATEWAY.DELETE";
-
-    // Static routes
-    public static final String EVENT_STATIC_ROUTE_CREATE = "STATIC.ROUTE.CREATE";
-    public static final String EVENT_STATIC_ROUTE_DELETE = "STATIC.ROUTE.DELETE";
-
-    // tag related events
-    public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
-    public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
-
-    // meta data related events
-    public static final String EVENT_RESOURCE_DETAILS_CREATE = "CREATE_RESOURCE_DETAILS";
-    public static final String EVENT_RESOURCE_DETAILS_DELETE = "DELETE_RESOURCE_DETAILS";
-
-    // vm snapshot events
-    public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
-    public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
-    public static final String EVENT_VM_SNAPSHOT_ON_PRIMARY = "VMSNAPSHOT.ON_PRIMARY";
-    public static final String EVENT_VM_SNAPSHOT_OFF_PRIMARY = "VMSNAPSHOT.OFF_PRIMARY";
-    public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
-
-    // external network device events
-    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
-    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE";
-    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE = "PHYSICAL.NVPCONTROLLER.CONFIGURE";
-    public static final String EVENT_EXTERNAL_OVS_CONTROLLER_ADD = "PHYSICAL.OVSCONTROLLER.ADD";
-    public static final String EVENT_EXTERNAL_OVS_CONTROLLER_DELETE = "PHYSICAL.OVSCONTROLLER.DELETE";
-
-    // external network mapping events
-    public static final String EVENT_EXTERNAL_VSP_VSD_ADD = "PHYSICAL.NUAGE.VSD.ADD";
-    public static final String EVENT_EXTERNAL_VSP_VSD_UPDATE = "PHYSICAL.NUAGE.VSD.UPDATE";
-    public static final String EVENT_EXTERNAL_VSP_VSD_DELETE = "PHYSICAL.NUAGE.VSD.DELETE";
-    // AutoScale
-    public static final String EVENT_COUNTER_CREATE = "COUNTER.CREATE";
-    public static final String EVENT_COUNTER_DELETE = "COUNTER.DELETE";
-    public static final String EVENT_CONDITION_CREATE = "CONDITION.CREATE";
-    public static final String EVENT_CONDITION_DELETE = "CONDITION.DELETE";
-    public static final String EVENT_AUTOSCALEPOLICY_CREATE = "AUTOSCALEPOLICY.CREATE";
-    public static final String EVENT_AUTOSCALEPOLICY_UPDATE = "AUTOSCALEPOLICY.UPDATE";
-    public static final String EVENT_AUTOSCALEPOLICY_DELETE = "AUTOSCALEPOLICY.DELETE";
-    public static final String EVENT_AUTOSCALEVMPROFILE_CREATE = "AUTOSCALEVMPROFILE.CREATE";
-    public static final String EVENT_AUTOSCALEVMPROFILE_DELETE = "AUTOSCALEVMPROFILE.DELETE";
-    public static final String EVENT_AUTOSCALEVMPROFILE_UPDATE = "AUTOSCALEVMPROFILE.UPDATE";
-    public static final String EVENT_AUTOSCALEVMGROUP_CREATE = "AUTOSCALEVMGROUP.CREATE";
-    public static final String EVENT_AUTOSCALEVMGROUP_DELETE = "AUTOSCALEVMGROUP.DELETE";
-    public static final String EVENT_AUTOSCALEVMGROUP_UPDATE = "AUTOSCALEVMGROUP.UPDATE";
-    public static final String EVENT_AUTOSCALEVMGROUP_ENABLE = "AUTOSCALEVMGROUP.ENABLE";
-    public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DISABLE";
-
-    public static final String EVENT_BAREMETAL_DHCP_SERVER_ADD = "PHYSICAL.DHCP.ADD";
-    public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE";
-    public static final String EVENT_BAREMETAL_PXE_SERVER_ADD = "PHYSICAL.PXE.ADD";
-    public static final String EVENT_BAREMETAL_PXE_SERVER_DELETE = "PHYSICAL.PXE.DELETE";
-    public static final String EVENT_BAREMETAL_RCT_ADD = "BAREMETAL.RCT.ADD";
-    public static final String EVENT_BAREMETAL_RCT_DELETE = "BAREMETAL.RCT.DELETE";
-    public static final String EVENT_BAREMETAL_PROVISION_DONE = "BAREMETAL.PROVISION.DONE";
-
-    public static final String EVENT_AFFINITY_GROUP_CREATE = "AG.CREATE";
-    public static final String EVENT_AFFINITY_GROUP_DELETE = "AG.DELETE";
-    public static final String EVENT_AFFINITY_GROUP_ASSIGN = "AG.ASSIGN";
-    public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
-    public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
-
-    public static final String EVENT_INTERNAL_LB_VM_START = "INTERNALLBVM.START";
-    public static final String EVENT_INTERNAL_LB_VM_STOP = "INTERNALLBVM.STOP";
-
-    public static final String EVENT_HOST_RESERVATION_RELEASE = "HOST.RESERVATION.RELEASE";
-    // Dedicated guest vlan range
-    public static final String EVENT_GUEST_VLAN_RANGE_DEDICATE = "GUESTVLANRANGE.DEDICATE";
-    public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE";
-
-    public static final String EVENT_PORTABLE_IP_RANGE_CREATE = "PORTABLE.IP.RANGE.CREATE";
-    public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
-    public static final String EVENT_PORTABLE_IP_TRANSFER = "PORTABLE.IP.TRANSFER";
-
-    // Dedicated Resources
-    public static final String EVENT_DEDICATE_RESOURCE = "DEDICATE.RESOURCE";
-    public static final String EVENT_DEDICATE_RESOURCE_RELEASE = "DEDICATE.RESOURCE.RELEASE";
-
-    public static final String EVENT_CLEANUP_VM_RESERVATION = "VM.RESERVATION.CLEANUP";
-
-    public static final String EVENT_UCS_ASSOCIATED_PROFILE = "UCS.ASSOCIATEPROFILE";
-
-    // IAM events
-    public static final String EVENT_IAM_POLICY_CREATE = "IAMPOLICY.CREATE";
-    public static final String EVENT_IAM_POLICY_DELETE = "IAMPOLICY.DELETE";
-    public static final String EVENT_IAM_POLICY_GRANT = "IAMPOLICY.GRANT";
-    public static final String EVENT_IAM_POLICY_REVOKE = "IAMPOLICY.REVOKE";
-
-    public static final String EVENT_IAM_GROUP_UPDATE = "IAMGROUP.UPDATE";
-    public static final String EVENT_IAM_GROUP_CREATE = "IAMGROUP.CREATE";
-    public static final String EVENT_IAM_GROUP_DELETE = "IAMGROUP.DELETE";
-    public static final String EVENT_IAM_GROUP_GRANT = "IAMGROUP.GRANT";
-    public static final String EVENT_IAM_GROUP_REVOKE = "IAMGROUP.REVOKE";
-    public static final String EVENT_IAM_ACCOUNT_POLICY_UPDATE = "IAMACCOUNTPOLICY.UPDATE";
-
-    // Object store migration
-    public static final String EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE = "MIGRATE.PREPARE.SS";
-
-    //Alert generation
-    public static final String ALERT_GENERATE = "ALERT.GENERATE";
-
-    // OpenDaylight
-    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER = "PHYSICAL.ODLCONTROLLER.ADD";
-    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.DELETE";
-    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.CONFIGURE";
-
-    //Guest OS related events
-    public static final String EVENT_GUEST_OS_ADD = "GUEST.OS.ADD";
-    public static final String EVENT_GUEST_OS_REMOVE = "GUEST.OS.REMOVE";
-    public static final String EVENT_GUEST_OS_UPDATE = "GUEST.OS.UPDATE";
-    public static final String EVENT_GUEST_OS_MAPPING_ADD = "GUEST.OS.MAPPING.ADD";
-    public static final String EVENT_GUEST_OS_MAPPING_REMOVE = "GUEST.OS.MAPPING.REMOVE";
-    public static final String EVENT_GUEST_OS_MAPPING_UPDATE = "GUEST.OS.MAPPING.UPDATE";
-
-    public static final String EVENT_NIC_SECONDARY_IP_ASSIGN = "NIC.SECONDARY.IP.ASSIGN";
-    public static final String EVENT_NIC_SECONDARY_IP_UNASSIGN = "NIC.SECONDARY.IP.UNASSIGN";
-    public static final String EVENT_NIC_SECONDARY_IP_CONFIGURE = "NIC.SECONDARY.IP.CONFIGURE";
-    public static final String EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH = "EXTERNAL.DHCP.VM.IP.FETCH";
-
-    //Usage related events
-    public static final String EVENT_USAGE_REMOVE_USAGE_RECORDS = "USAGE.REMOVE.USAGE.RECORDS";
-
-    // Netscaler Service Package events
-    public static final String EVENT_NETSCALER_SERVICEPACKAGE_ADD = "NETSCALER.SERVICEPACKAGE.ADD";
-    public static final String EVENT_NETSCALER_SERVICEPACKAGE_DELETE = "NETSCALER.SERVICEPACKAGE.DELETE";
-
-    public static final String EVENT_NETSCALER_VM_START = "NETSCALERVM.START";
-    public static final String EVENT_NETSCALER_VM_STOP = "NETSCALERVM.STOP";
-
-    public static final String EVENT_ANNOTATION_CREATE = "ANNOTATION.CREATE";
-    public static final String EVENT_ANNOTATION_REMOVE = "ANNOTATION.REMOVE";
-
-    public static final String EVENT_TEMPLATE_DIRECT_DOWNLOAD_FAILURE = "TEMPLATE.DIRECT.DOWNLOAD.FAILURE";
-    public static final String EVENT_ISO_DIRECT_DOWNLOAD_FAILURE = "ISO.DIRECT.DOWNLOAD.FAILURE";
-
-    static {
-
-        // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
-
-        entityEventDetails = new HashMap<String, Object>();
-
-        entityEventDetails.put(EVENT_VM_CREATE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_DESTROY, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_START, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_STOP, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class);
-
-        entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_START, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_STOP, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_REBOOT, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class);
-        entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class);
-
-        entityEventDetails.put(EVENT_PROXY_CREATE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_PROXY_DESTROY, VirtualMachine.class);
-        entityEventDetails.put(EVENT_PROXY_START, VirtualMachine.class);
-        entityEventDetails.put(EVENT_PROXY_STOP, VirtualMachine.class);
-        entityEventDetails.put(EVENT_PROXY_REBOOT, VirtualMachine.class);
-        entityEventDetails.put(EVENT_ROUTER_HA, VirtualMachine.class);
-        entityEventDetails.put(EVENT_PROXY_HA, VirtualMachine.class);
-
-        entityEventDetails.put(EVENT_VNC_CONNECT, "VNC");
-        entityEventDetails.put(EVENT_VNC_DISCONNECT, "VNC");
-
-        // Network Events
-        entityEventDetails.put(EVENT_NETWORK_CREATE, Network.class);
-        entityEventDetails.put(EVENT_NETWORK_DELETE, Network.class);
-        entityEventDetails.put(EVENT_NETWORK_UPDATE, Network.class);
-        entityEventDetails.put(EVENT_NETWORK_RESTART, Network.class);
-        entityEventDetails.put(EVENT_NET_IP_ASSIGN, IpAddress.class);
-        entityEventDetails.put(EVENT_PORTABLE_IP_ASSIGN, IpAddress.class);
-        entityEventDetails.put(EVENT_PORTABLE_IP_RELEASE, IpAddress.class);
-        entityEventDetails.put(EVENT_NET_IP_RELEASE, IpAddress.class);
-        entityEventDetails.put(EVENT_NET_RULE_ADD, FirewallRule.class);
-        entityEventDetails.put(EVENT_NET_RULE_DELETE, FirewallRule.class);
-        entityEventDetails.put(EVENT_NET_RULE_MODIFY, FirewallRule.class);
-        entityEventDetails.put(EVENT_FIREWALL_OPEN, FirewallRule.class);
-        entityEventDetails.put(EVENT_FIREWALL_CLOSE, FirewallRule.class);
-        entityEventDetails.put(EVENT_FIREWALL_EGRESS_OPEN, FirewallRule.class);
-        entityEventDetails.put(EVENT_FIREWALL_EGRESS_CLOSE, FirewallRule.class);
-        entityEventDetails.put(EVENT_FIREWALL_EGRESS_UPDATE, FirewallRule.class);
-
-        // Nic Events
-        entityEventDetails.put(EVENT_NIC_CREATE, Nic.class);
-
-        // Load Balancers
-        entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class);
-        entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, FirewallRule.class);
-        entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class);
-        entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, FirewallRule.class);
-        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, StickinessPolicy.class);
-        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_UPDATE, StickinessPolicy.class);
-        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, StickinessPolicy.class);
-        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_CREATE, HealthCheckPolicy.class);
-        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_UPDATE, HealthCheckPolicy.class);
-        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_DELETE, HealthCheckPolicy.class);
-        entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class);
-        entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class);
-        entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class);
-        entityEventDetails.put(EVENT_LB_CERT_ASSIGN, LoadBalancer.class);
-        entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class);
-
-        // Role events
-        entityEventDetails.put(EVENT_ROLE_CREATE, Role.class);
-        entityEventDetails.put(EVENT_ROLE_UPDATE, Role.class);
-        entityEventDetails.put(EVENT_ROLE_DELETE, Role.class);
-        entityEventDetails.put(EVENT_ROLE_PERMISSION_CREATE, RolePermission.class);
-        entityEventDetails.put(EVENT_ROLE_PERMISSION_UPDATE, RolePermission.class);
-        entityEventDetails.put(EVENT_ROLE_PERMISSION_DELETE, RolePermission.class);
-
-        // Account events
-        entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class);
-        entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class);
-        entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class);
-        entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class);
-        entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class);
-        entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class);
-
-        // UserVO Events
-        entityEventDetails.put(EVENT_USER_LOGIN, User.class);
-        entityEventDetails.put(EVENT_USER_LOGOUT, User.class);
-        entityEventDetails.put(EVENT_USER_CREATE, User.class);
-        entityEventDetails.put(EVENT_USER_DELETE, User.class);
-        entityEventDetails.put(EVENT_USER_DISABLE, User.class);
-        entityEventDetails.put(EVENT_USER_UPDATE, User.class);
-        entityEventDetails.put(EVENT_USER_ENABLE, User.class);
-        entityEventDetails.put(EVENT_USER_LOCK, User.class);
-
-        // Template Events
-        entityEventDetails.put(EVENT_TEMPLATE_CREATE, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_DELETE, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_UPDATE, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_START, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_SUCCESS, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_FAILED, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_COPY, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_EXTRACT, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_UPLOAD, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_TEMPLATE_CLEANUP, VirtualMachineTemplate.class);
-
-        // Volume Events
-        entityEventDetails.put(EVENT_VOLUME_CREATE, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_DELETE, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_ATTACH, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_DETACH, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_EXTRACT, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_UPLOAD, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_MIGRATE, Volume.class);
-        entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class);
-
-        // Domains
-        entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
-        entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class);
-        entityEventDetails.put(EVENT_DOMAIN_UPDATE, Domain.class);
-
-        // Snapshots
-        entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_ON_PRIMARY, Snapshot.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_OFF_PRIMARY, Snapshot.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, SnapshotPolicy.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, SnapshotPolicy.class);
-        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, SnapshotPolicy.class);
-
-        // ISO
-        entityEventDetails.put(EVENT_ISO_CREATE, "Iso");
-        entityEventDetails.put(EVENT_ISO_DELETE, "Iso");
-        entityEventDetails.put(EVENT_ISO_COPY, "Iso");
-        entityEventDetails.put(EVENT_ISO_ATTACH, "Iso");
-        entityEventDetails.put(EVENT_ISO_DETACH, "Iso");
-        entityEventDetails.put(EVENT_ISO_EXTRACT, "Iso");
-        entityEventDetails.put(EVENT_ISO_UPLOAD, "Iso");
-
-        // SSVM
-        entityEventDetails.put(EVENT_SSVM_CREATE, VirtualMachine.class);
-        entityEventDetails.put(EVENT_SSVM_DESTROY, VirtualMachine.class);
-        entityEventDetails.put(EVENT_SSVM_START, VirtualMachine.class);
-        entityEventDetails.put(EVENT_SSVM_STOP, VirtualMachine.class);
-        entityEventDetails.put(EVENT_SSVM_REBOOT, VirtualMachine.class);
-        entityEventDetails.put(EVENT_SSVM_HA, VirtualMachine.class);
-
-        // Service Offerings
-        entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class);
-        entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class);
-        entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class);
-
-        // Disk Offerings
-        entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class);
-        entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class);
-        entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class);
-
-        // Network offerings
-        entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class);
-        entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class);
-        entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class);
-        entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class);
-        entityEventDetails.put(EVENT_NETWORK_OFFERING_DELETE, NetworkOffering.class);
-
-        // Pods
-        entityEventDetails.put(EVENT_POD_CREATE, Pod.class);
-        entityEventDetails.put(EVENT_POD_EDIT, Pod.class);
-        entityEventDetails.put(EVENT_POD_DELETE, Pod.class);
-
-        // Zones
-        entityEventDetails.put(EVENT_ZONE_CREATE, DataCenter.class);
-        entityEventDetails.put(EVENT_ZONE_EDIT, DataCenter.class);
-        entityEventDetails.put(EVENT_ZONE_DELETE, DataCenter.class);
-
-        // VLANs/IP ranges
-        entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class);
-        entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE, Vlan.class);
-        entityEventDetails.put(EVENT_VLAN_IP_RANGE_DEDICATE, Vlan.class);
-        entityEventDetails.put(EVENT_VLAN_IP_RANGE_RELEASE, Vlan.class);
-
-        entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_CREATE, Pod.class);
-        entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_DELETE, Pod.class);
-
-        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class);
-        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class);
-        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class);
-
-        // Configuration Table
-        entityEventDetails.put(EVENT_CONFIGURATION_VALUE_EDIT, Configuration.class);
-
-        // Security Groups
-        entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_INGRESS, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_EGRESS, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_CREATE, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_DELETE, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_ASSIGN, SecurityGroup.class);
-        entityEventDetails.put(EVENT_SECURITY_GROUP_REMOVE, SecurityGroup.class);
-
-        // Host
-        entityEventDetails.put(EVENT_HOST_RECONNECT, Host.class);
-
-        // Host Out-of-band management
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_ENABLE, Host.class);
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_DISABLE, Host.class);
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_CONFIGURE, Host.class);
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_ACTION, Host.class);
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_CHANGE_PASSWORD, Host.class);
-        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_POWERSTATE_TRANSITION, Host.class);
-
-        // HA
-        entityEventDetails.put(EVENT_HA_RESOURCE_ENABLE, HAConfig.class);
-        entityEventDetails.put(EVENT_HA_RESOURCE_DISABLE, HAConfig.class);
-        entityEventDetails.put(EVENT_HA_RESOURCE_CONFIGURE, HAConfig.class);
-        entityEventDetails.put(EVENT_HA_STATE_TRANSITION, HAConfig.class);
-
-        // Maintenance
-        entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class);
-        entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class);
-        entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class);
-        entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class);
-
-        // Primary storage pool
-        entityEventDetails.put(EVENT_ENABLE_PRIMARY_STORAGE, StoragePool.class);
-        entityEventDetails.put(EVENT_DISABLE_PRIMARY_STORAGE, StoragePool.class);
-
-        // VPN
-        entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class);
-        entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class);
-        entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class);
-        entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class);
-        entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, Site2SiteVpnGateway.class);
-        entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, Site2SiteVpnGateway.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class);
-        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class);
-
-        // Custom certificates
-        entityEventDetails.put(EVENT_UPLOAD_CUSTOM_CERTIFICATE, "Certificate");
-
-        // OneToOnenat
-        entityEventDetails.put(EVENT_ENABLE_STATIC_NAT, StaticNat.class);
-        entityEventDetails.put(EVENT_DISABLE_STATIC_NAT, StaticNat.class);
-
-        entityEventDetails.put(EVENT_ZONE_VLAN_ASSIGN, Vlan.class);
-        entityEventDetails.put(EVENT_ZONE_VLAN_RELEASE, Vlan.class);
-
-        // Projects
-        entityEventDetails.put(EVENT_PROJECT_CREATE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_UPDATE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_DELETE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_ACTIVATE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_SUSPEND, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_ACCOUNT_ADD, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_INVITATION_UPDATE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_INVITATION_REMOVE, Project.class);
-        entityEventDetails.put(EVENT_PROJECT_ACCOUNT_REMOVE, Project.class);
-
-        // Network as a Service
-        entityEventDetails.put(EVENT_NETWORK_ELEMENT_CONFIGURE, Network.class);
-
-        // Physical Network Events
-        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_CREATE, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_DELETE, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_UPDATE, PhysicalNetwork.class);
-
-        // Physical Network Service Provider Events
-        entityEventDetails.put(EVENT_SERVICE_PROVIDER_CREATE, PhysicalNetworkServiceProvider.class);
-        entityEventDetails.put(EVENT_SERVICE_PROVIDER_DELETE, PhysicalNetworkServiceProvider.class);
-        entityEventDetails.put(EVENT_SERVICE_PROVIDER_UPDATE, PhysicalNetworkServiceProvider.class);
-
-        // Physical Network TrafficType Events
-        entityEventDetails.put(EVENT_TRAFFIC_TYPE_CREATE, PhysicalNetworkTrafficType.class);
-        entityEventDetails.put(EVENT_TRAFFIC_TYPE_DELETE, PhysicalNetworkTrafficType.class);
-        entityEventDetails.put(EVENT_TRAFFIC_TYPE_UPDATE, PhysicalNetworkTrafficType.class);
-
-        // external network device events
-        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_ADD, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_DELETE, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_CONFIGURE, PhysicalNetwork.class);
-
-        // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module.
-        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD, "Nexus1000v");
-        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE, "Nexus1000v");
-        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE, "Nexus1000v");
-        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE, "Nexus1000v");
-        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE, "Nexus1000v");
-
-        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_ADD, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE, PhysicalNetwork.class);
-        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE, PhysicalNetwork.class);
-
-        // Network ACL
-        entityEventDetails.put(EVENT_NETWORK_ACL_CREATE, NetworkACL.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_DELETE, NetworkACL.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_REPLACE, NetworkACL.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_UPDATE, NetworkACL.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_CREATE, NetworkACLItem.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_UPDATE, NetworkACLItem.class);
-        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_DELETE, NetworkACLItem.class);
-
-        // VPC
-        entityEventDetails.put(EVENT_VPC_CREATE, Vpc.class);
-        entityEventDetails.put(EVENT_VPC_UPDATE, Vpc.class);
-        entityEventDetails.put(EVENT_VPC_DELETE, Vpc.class);
-        entityEventDetails.put(EVENT_VPC_RESTART, Vpc.class);
-
-        // VPC offerings
-        entityEventDetails.put(EVENT_VPC_OFFERING_CREATE, Vpc.class);
-        entityEventDetails.put(EVENT_VPC_OFFERING_UPDATE, Vpc.class);
-        entityEventDetails.put(EVENT_VPC_OFFERING_DELETE, Vpc.class);
-
-        // Private gateway
-        entityEventDetails.put(EVENT_PRIVATE_GATEWAY_CREATE, PrivateGateway.class);
-        entityEventDetails.put(EVENT_PRIVATE_GATEWAY_DELETE, PrivateGateway.class);
-
-        // Static routes
-        entityEventDetails.put(EVENT_STATIC_ROUTE_CREATE, StaticRoute.class);
-        entityEventDetails.put(EVENT_STATIC_ROUTE_DELETE, StaticRoute.class);
-
-        // tag related events
-        entityEventDetails.put(EVENT_TAGS_CREATE, ResourceTag.class);
-        entityEventDetails.put(EVENT_TAGS_DELETE, ResourceTag.class);
-
-        // external network device events
-        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_ADD, "NvpController");
-        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_DELETE, "NvpController");
-        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController");
-
-        // external network mapping events
-        entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_ADD,  "NuageVsp");
-        entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_DELETE,  "NuageVsp");
-
-        // AutoScale
-        entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class);
-        entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class);
-        entityEventDetails.put(EVENT_CONDITION_CREATE, Condition.class);
-        entityEventDetails.put(EVENT_CONDITION_DELETE, Condition.class);
-        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_CREATE, AutoScalePolicy.class);
-        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_UPDATE, AutoScalePolicy.class);
-        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_DELETE, AutoScalePolicy.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_CREATE, AutoScaleVmProfile.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_DELETE, AutoScaleVmProfile.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_UPDATE, AutoScaleVmProfile.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_CREATE, AutoScaleVmGroup.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DELETE, AutoScaleVmGroup.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class);
-        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class);
-        entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class);
-        entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class);
-
-        // OpenDaylight
-        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER, "OpenDaylightController");
-        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER, "OpenDaylightController");
-        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER, "OpenDaylightController");
-
-        //Guest OS
-        entityEventDetails.put(EVENT_GUEST_OS_ADD, GuestOS.class);
-        entityEventDetails.put(EVENT_GUEST_OS_REMOVE, GuestOS.class);
-        entityEventDetails.put(EVENT_GUEST_OS_UPDATE, GuestOS.class);
-        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class);
-        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class);
-        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class);
-        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_ASSIGN, NicSecondaryIp.class);
-        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_UNASSIGN, NicSecondaryIp.class);
-        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_CONFIGURE, NicSecondaryIp.class);
-
-        //Usage
-        entityEventDetails.put(EVENT_USAGE_REMOVE_USAGE_RECORDS, Usage.class);
-        // Netscaler Service Packages
-        entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_ADD, "NETSCALER.SERVICEPACKAGE.CREATE");
-        entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_DELETE, "NETSCALER.SERVICEPACKAGE.DELETE");
-
-        entityEventDetails.put(EVENT_ANNOTATION_CREATE, Annotation.class);
-        entityEventDetails.put(EVENT_ANNOTATION_REMOVE, Annotation.class);
-
-        entityEventDetails.put(EVENT_TEMPLATE_DIRECT_DOWNLOAD_FAILURE, VirtualMachineTemplate.class);
-        entityEventDetails.put(EVENT_ISO_DIRECT_DOWNLOAD_FAILURE, "Iso");
-    }
-
-    public static String getEntityForEvent(String eventName) {
-        Object entityClass = entityEventDetails.get(eventName);
-        if (entityClass == null) {
-            return null;
-        } else if (entityClass instanceof String){
-            return (String)entityClass;
-        } else if (entityClass instanceof Class){
-            String entityClassName = ((Class)entityClass).getName();
-            int index = entityClassName.lastIndexOf(".");
-            String entityName = entityClassName;
-            if (index != -1) {
-                entityName = entityClassName.substring(index + 1);
-            }
-            return entityName;
-        }
-
-        return null;
-    }
-
-    public static Class getEntityClassForEvent(String eventName) {
-        Object clz = entityEventDetails.get(eventName);
-
-        if(clz instanceof Class){
-            return (Class)entityEventDetails.get(eventName);
-        }
-
-        return null;
-    }
-}
diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java
deleted file mode 100644
index 45e19ee..0000000
--- a/api/src/com/cloud/hypervisor/HypervisorGuru.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.Adapter;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-
-public interface HypervisorGuru extends Adapter {
-    static final ConfigKey<Boolean> VmwareFullClone = new ConfigKey<Boolean>("Advanced", Boolean.class, "vmware.create.full.clone", "true",
-            "If set to true, creates guest VMs as full clones on ESX", false);
-    HypervisorType getHypervisorType();
-
-    /**
-     * Convert from a virtual machine to the
-     * virtual machine that the hypervisor expects.
-     * @param vm
-     * @return
-     */
-    VirtualMachineTO implement(VirtualMachineProfile vm);
-
-    /**
-     * Gives hypervisor guru opportunity to decide if certain commands need to be delegated to another host, for instance, we may have the opportunity to change from a system VM (is considered a host) to a real host to execute commands.
-     *
-     * @param hostId original hypervisor host
-     * @param cmd command that is going to be sent, hypervisor guru usually needs to register various context objects into the command object
-     *
-     * @return delegated host id if the command will be delegated
-     */
-    Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd);
-
-    /**
-     *  @return true if VM can be migrated independently with CloudStack, and therefore CloudStack needs to track and reflect host change
-     *  into CloudStack database, false if CloudStack enforces VM sync logic
-     *
-     */
-    boolean trackVmHostChange();
-
-    /**
-     * @param profile
-     * @return
-     */
-    NicTO toNicTO(NicProfile profile);
-
-    /**
-     * Give hypervisor guru opportunity to decide if certain command needs to be done after expunge VM from DB
-     * @param vm
-     * @return a list of Commands
-     */
-    List<Command> finalizeExpunge(VirtualMachine vm);
-
-    /**
-     * Give the hypervisor guru the opportinity to decide if additional clean is
-     * required for nics before expunging the VM
-     *
-     */
-    List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics);
-
-    List<Command> finalizeExpungeVolumes(VirtualMachine vm);
-
-    Map<String, String> getClusterSettings(long vmId);
-}
diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java
deleted file mode 100644
index a5bf5e4..0000000
--- a/api/src/com/cloud/network/NetworkModel.java
+++ /dev/null
@@ -1,320 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.cloud.dc.Vlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.user.Account;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine;
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-/**
- * The NetworkModel presents a read-only view into the Network data such as L2 networks,
- * Nics, PublicIps, NetworkOfferings, traffic labels, physical networks and the like
- * The idea is that only the orchestration core should be able to modify the data, while other
- * participants in the orchestration can use this interface to query the data.
- */
-public interface NetworkModel {
-    String METATDATA_DIR = "metadata";
-    String USERDATA_DIR = "userdata";
-    String USERDATA_FILE = "user_data";
-    String PASSWORD_DIR = "password";
-    String PASSWORD_FILE = "vm_password";
-    String PASSWORD_CHECKSUM_FILE = "vm-password-md5checksum";
-    String SERVICE_OFFERING_FILE = "service-offering";
-    String AVAILABILITY_ZONE_FILE = "availability-zone";
-    String LOCAL_HOSTNAME_FILE = "local-hostname";
-    String LOCAL_IPV4_FILE = "local-ipv4";
-    String PUBLIC_HOSTNAME_FILE = "public-hostname";
-    String PUBLIC_IPV4_FILE = "public-ipv4";
-    String INSTANCE_ID_FILE = "instance-id";
-    String VM_ID_FILE = "vm-id";
-    String PUBLIC_KEYS_FILE = "public-keys";
-    String CLOUD_IDENTIFIER_FILE = "cloud-identifier";
-    int CONFIGDATA_DIR = 0;
-    int CONFIGDATA_FILE = 1;
-    int CONFIGDATA_CONTENT = 2;
-    ImmutableMap<String, String> openStackFileMapping = ImmutableMap.of(
-            AVAILABILITY_ZONE_FILE, "availability_zone",
-            LOCAL_HOSTNAME_FILE, "hostname",
-            VM_ID_FILE, "uuid",
-            PUBLIC_HOSTNAME_FILE, "name"
-    );
-
-    static final ConfigKey<Integer> MACIdentifier = new ConfigKey<Integer>("Advanced",Integer.class, "mac.identifier", "0",
-            "This value will be used while generating the mac addresses for isolated and shared networks. The hexadecimal equivalent value will be present at the 2nd octet of the mac address. Default value is null which means this feature is disabled.Its scope is global.", true, ConfigKey.Scope.Global);
-
-    /**
-     * Lists IP addresses that belong to VirtualNetwork VLANs
-     *
-     * @param accountId
-     *            - account that the IP address should belong to
-     * @param associatedNetworkId
-     *            TODO
-     * @param sourceNat
-     *            - (optional) true if the IP address should be a source NAT address
-     * @return - list of IP addresses
-     */
-    List<? extends IpAddress> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat);
-
-    List<? extends IpAddress> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat);
-
-    List<? extends NetworkOffering> getSystemAccountNetworkOfferings(String... offeringNames);
-
-    List<? extends Nic> getNics(long vmId);
-
-    String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
-
-    PublicIpAddress getPublicIpAddress(long ipAddressId);
-
-    List<? extends Vlan> listPodVlans(long podId);
-
-    List<? extends Network> listNetworksUsedByVm(long vmId, boolean isSystem);
-
-    Nic getNicInNetwork(long vmId, long networkId);
-
-    List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type);
-
-    Network getDefaultNetworkForVm(long vmId);
-
-    Nic getDefaultNic(long vmId);
-
-    UserDataServiceProvider getUserDataUpdateProvider(Network network);
-
-    boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId);
-
-    Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service);
-
-    boolean isSharedNetworkWithoutServices(long networkId);
-
-    boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services);
-
-    Network getNetworkWithSGWithFreeIPs(Long zoneId);
-
-    Network getNetworkWithSecurityGroupEnabled(Long zoneId);
-
-    String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId);
-
-    List<? extends Network> listNetworksForAccount(long accountId, long zoneId, Network.GuestType type);
-
-    List<? extends Network> listAllNetworksInAllZonesByType(Network.GuestType type);
-
-    String getStartIpAddress(long networkId);
-
-    String getIpInNetwork(long vmId, long networkId);
-
-    String getIpInNetworkIncludingRemoved(long vmId, long networkId);
-
-    Long getPodIdForVlan(long vlanDbId);
-
-    List<Long> listNetworkOfferingsForUpgrade(long networkId);
-
-    boolean isSecurityGroupSupportedInNetwork(Network network);
-
-    boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider);
-
-    boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName);
-
-    String getNetworkTag(HypervisorType hType, Network network);
-
-    List<Service> getElementServices(Provider provider);
-
-    boolean canElementEnableIndividualServices(Provider provider);
-
-    boolean areServicesSupportedInNetwork(long networkId, Service... services);
-
-    boolean isNetworkSystem(Network network);
-
-    Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service);
-
-    Long getPhysicalNetworkId(Network network);
-
-    boolean getAllowSubdomainAccessGlobal();
-
-    boolean isProviderForNetwork(Provider provider, long networkId);
-
-    boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId);
-
-    void canProviderSupportServices(Map<Provider, Set<Service>> providersMap);
-
-    List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType);
-
-    boolean canAddDefaultSecurityGroup();
-
-    List<Service> listNetworkOfferingServices(long networkOfferingId);
-
-    boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services);
-
-    Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall);
-
-    Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices);
-
-    boolean checkIpForService(IpAddress ip, Service service, Long networkId);
-
-    boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap);
-
-    void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue);
-
-    Provider getDefaultUniqueProviderForService(String serviceName);
-
-    void checkNetworkPermissions(Account owner, Network network);
-
-    String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType);
-
-    String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType);
-
-    String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware);
-
-    String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware);
-
-    /**
-     * @param providerName
-     * @return
-     */
-    NetworkElement getElementImplementingProvider(String providerName);
-
-    /**
-     * @param accountId
-     * @param zoneId
-     * @return
-     */
-    String getAccountNetworkDomain(long accountId, long zoneId);
-
-    /**
-     * @param ntwkOffId
-     * @return
-     */
-    List<Provider> getNtwkOffDistinctProviders(long ntwkOffId);
-
-    /**
-     * @param accountId
-     * @param dcId
-     * @param sourceNat
-     * @return
-     */
-    List<? extends IpAddress> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat);
-
-    /**
-     * @param zoneId
-     * @param trafficType
-     * @return
-     */
-    List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType);
-
-    /**
-     * @param ntwkId
-     * @return
-     */
-    boolean isPrivateGateway(long ntwkId);
-
-    Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId);
-
-    Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType);
-
-    Long getDedicatedNetworkDomain(long networkId);
-
-    Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId);
-
-    List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName);
-
-    List<? extends Network> listNetworksByVpc(long vpcId);
-
-    boolean canUseForDeploy(Network network);
-
-    Network getExclusiveGuestNetwork(long zoneId);
-
-    long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType);
-
-    Integer getNetworkRate(long networkId, Long vmId);
-
-    boolean isVmPartOfNetwork(long vmId, long ntwkId);
-
-    PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType);
-
-    Network getNetwork(long networkId);
-
-    IpAddress getIp(long sourceIpAddressId);
-
-    boolean isNetworkAvailableInDomain(long networkId, long domainId);
-
-    NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri);
-
-    Set<Long> getAvailableIps(Network network, String requestedIp);
-
-    String getDomainNetworkDomain(long domainId, long zoneId);
-
-    PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork);
-
-    boolean isNetworkInlineMode(Network network);
-
-    boolean isIP6AddressAvailableInNetwork(long networkId);
-
-    boolean isIP6AddressAvailableInVlan(long vlanId);
-
-    void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException;
-
-    void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException;
-
-    String getStartIpv6Address(long id);
-
-    boolean isProviderEnabledInZone(long zoneId, String provider);
-
-    Nic getPlaceholderNicForRouter(Network network, Long podId);
-
-    IpAddress getPublicIpAddress(String ipAddress, long zoneId);
-
-    List<String> getUsedIpsInNetwork(Network network);
-
-    Map<Detail, String> getNtwkOffDetails(long offId);
-
-    Networks.IsolationType[] listNetworkIsolationMethods();
-
-    Nic getNicInNetworkIncludingRemoved(long vmId, long networkId);
-
-    boolean getExecuteInSeqNtwkElmtCmd();
-
-    boolean isNetworkReadyForGc(long networkId);
-
-    boolean getNetworkEgressDefaultPolicy(Long networkId);
-
-    List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
-                                  String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows);
-
-    String getValidNetworkCidr(Network guestNetwork);
-
-}
diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java
deleted file mode 100644
index d76d659..0000000
--- a/api/src/com/cloud/network/NetworkService.java
+++ /dev/null
@@ -1,211 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
-import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
-import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.utils.Pair;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-
-/**
- * The NetworkService interface is the "public" api to entities that make requests to the orchestration engine
- * Such entities are usually the admin and end-user API.
- *
- */
-public interface NetworkService {
-
-    List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner);
-
-    IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp) throws ResourceAllocationException, InsufficientAddressCapacityException,
-        ConcurrentOperationException;
-
-    boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
-
-    IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
-        InsufficientAddressCapacityException, ConcurrentOperationException;
-
-    boolean releasePortableIpAddress(long ipAddressId);
-
-    Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
-
-    Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd);
-
-    boolean deleteNetwork(long networkId, boolean forced);
-
-    boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
-
-    int getActiveNicsInNetwork(long networkId);
-
-    Network getNetwork(long networkId);
-
-    Network getNetwork(String networkUuid);
-
-    IpAddress getIp(long id);
-
-    Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId,
-        Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID, boolean updateInSequence, boolean forced);
-
-    /**
-     * Migrate a network from one physical network to another physical network
-     * @param networkId of the network that needs to be migrated
-     * @param networkOfferingId new network offering id for the network
-     * @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
-     * @return the migrated network
-     */
-    Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume);
-
-    /**
-     * Migrate a vpc from on physical network to another physical network
-     * @param vpcId the id of the vpc that needs to be migrated
-     * @param vpcNetworkofferingId the new vpc offering id
-     * @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
-     * @return the migrated vpc
-     */
-    Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume);
-
-    PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange, Long domainId,
-        List<String> tags, String name);
-
-    Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name);
-
-    PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state);
-
-    boolean deletePhysicalNetwork(Long id);
-
-    List<? extends Service> listNetworkServices(String providerName);
-
-    PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId,
-        List<String> enabledServices);
-
-    Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex,
-        Long pageSize);
-
-    PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List<String> enabledServices);
-
-    boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException;
-
-    PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId);
-
-    PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId);
-
-    PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId);
-
-    PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId);
-
-    long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType);
-
-    PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-        String simulatorLabel, String vlan, String hypervLabel, String ovm3label);
-
-    PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id);
-
-    PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3label);
-
-    boolean deletePhysicalNetworkTrafficType(Long id);
-
-    GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd);
-
-    Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd);
-
-    boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId);
-
-    Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId);
-
-    Network getExclusiveGuestNetwork(long zoneId);
-
-    List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd);
-
-    List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner);
-
-    /**
-     * @param networkId
-     * @param entityId
-     * @return
-     * @throws ConcurrentOperationException
-     * @throws ResourceUnavailableException
-     * @throws ResourceAllocationException
-     * @throws InsufficientAddressCapacityException
-     */
-    IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException,
-        ConcurrentOperationException;
-
-    /**
-     *
-     * @param networkName
-     * @param displayText
-     * @param physicalNetworkId
-     * @param broadcastUri TODO set the guru name based on the broadcastUri?
-     * @param startIp
-     * @param endIP TODO
-     * @param gateway
-     * @param netmask
-     * @param networkOwnerId
-     * @param vpcId TODO
-     * @param sourceNat
-     * @return
-     * @throws InsufficientCapacityException
-     * @throws ConcurrentOperationException
-     * @throws ResourceAllocationException
-     */
-    Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String broadcastUri, String startIp, String endIP, String gateway,
-        String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException,
-        InsufficientCapacityException;
-
-    /* Requests an IP address for the guest nic */
-    NicSecondaryIp allocateSecondaryGuestIP(long nicId, String ipaddress) throws InsufficientAddressCapacityException;
-
-    boolean releaseSecondaryIpFromNic(long ipAddressId);
-
-    /* lists the nic informaton */
-    List<? extends Nic> listNics(ListNicsCmd listNicsCmd);
-
-    Map<Network.Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service);
-
-    IpAddress updateIP(Long id, String customId, Boolean displayIp);
-
-    boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled);
-
-    List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd);
-
-    AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException;
-
-    boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException;
-}
diff --git a/api/src/com/cloud/network/vpc/NetworkACLItem.java b/api/src/com/cloud/network/vpc/NetworkACLItem.java
deleted file mode 100644
index 75153fd..0000000
--- a/api/src/com/cloud/network/vpc/NetworkACLItem.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.Displayable;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface NetworkACLItem extends InternalIdentity, Identity, Displayable {
-
-    String getUuid();
-
-    Action getAction();
-
-    int getNumber();
-
-    enum State {
-        Staged, // Rule been created but has never got through network rule conflict detection.  Rules in this state can not be sent to network elements.
-        Add,    // Add means the rule has been created and has gone through network rule conflict detection.
-        Active, // Rule has been sent to the network elements and reported to be active.
-        Revoke  // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database.
-    }
-
-    enum TrafficType {
-        Ingress, Egress
-    }
-
-    enum Action {
-        Allow, Deny
-    }
-
-    /**
-     * @return first port of the source port range.
-     */
-    Integer getSourcePortStart();
-
-    /**
-     * @return last port of the source prot range.  If this is null, that means only one port is mapped.
-     */
-    Integer getSourcePortEnd();
-
-    /**
-     * @return protocol to open these ports for.
-     */
-    String getProtocol();
-
-    State getState();
-
-    long getAclId();
-
-    Integer getIcmpCode();
-
-    Integer getIcmpType();
-
-    List<String> getSourceCidrList();
-
-    /**
-     * @return
-     */
-    TrafficType getTrafficType();
-
-    @Override
-    boolean isDisplay();
-
-}
diff --git a/api/src/com/cloud/network/vpc/NetworkACLService.java b/api/src/com/cloud/network/vpc/NetworkACLService.java
deleted file mode 100644
index f08fff5..0000000
--- a/api/src/com/cloud/network/vpc/NetworkACLService.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
-
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.utils.Pair;
-
-public interface NetworkACLService {
-    /**
-     * Creates Network ACL for the specified VPC
-     * @param name
-     * @param description
-     * @param vpcId
-     * @param forDisplay TODO
-     * @return
-     */
-    NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay);
-
-    /**
-     * Get Network ACL with specified Id
-     * @param id
-     * @return
-     */
-    NetworkACL getNetworkACL(long id);
-
-    /**
-     * List NetworkACLs by Id/Name/Network or Vpc it belongs to
-     * @param cmd
-     * @return
-     */
-    Pair<List<? extends NetworkACL>, Integer> listNetworkACLs(ListNetworkACLListsCmd cmd);
-
-    /**
-     * Delete specified network ACL. Deletion fails if the list is not empty
-     * @param id
-     * @return
-     */
-    boolean deleteNetworkACL(long id);
-
-    /**
-     * Associates ACL with specified Network
-     * @param aclId
-     * @param networkId
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean replaceNetworkACL(long aclId, long networkId) throws ResourceUnavailableException;
-
-    /**
-     * Applied ACL to associated networks
-     * @param aclId
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean applyNetworkACL(long aclId) throws ResourceUnavailableException;
-
-    /**
-     * Creates a Network ACL Item within an ACL and applies the ACL to associated networks
-     * @param createNetworkACLCmd
-     * @return
-     */
-    NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd);
-
-    /**
-     * Return ACL item with specified Id
-     * @param ruleId
-     * @return
-     */
-    NetworkACLItem getNetworkACLItem(long ruleId);
-
-    /**
-     * Lists Network ACL Items by Id, Network, ACLId, Traffic Type, protocol
-     * @param listNetworkACLsCmd
-     * @return
-     */
-    Pair<List<? extends NetworkACLItem>, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd);
-
-    /**
-     * Revoke ACL Item with specified Id
-     * @param ruleId
-     * @return
-     */
-    boolean revokeNetworkACLItem(long ruleId);
-
-    /**
-     * Updates existing aclItem applies to associated networks
-     * @param id
-     * @param protocol
-     * @param sourceCidrList
-     * @param trafficType
-     * @param action
-     * @param number
-     * @param sourcePortStart
-     * @param sourcePortEnd
-     * @param icmpCode
-     * @param icmpType
-     * @param newUUID TODO
-     * @param forDisplay TODO
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    NetworkACLItem updateNetworkACLItem(Long id, String protocol, List<String> sourceCidrList, NetworkACLItem.TrafficType trafficType, String action, Integer number,
-            Integer sourcePortStart, Integer sourcePortEnd, Integer icmpCode, Integer icmpType, String newUUID, Boolean forDisplay) throws ResourceUnavailableException;
-
-    /**
-     * Associates ACL with specified Network
-     * @param aclId
-     * @param privateGatewayId
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean replaceNetworkACLonPrivateGw(long aclId, long privateGatewayId) throws ResourceUnavailableException;
-
-    NetworkACL updateNetworkACL(Long id, String customId, Boolean forDisplay);
-
-}
diff --git a/api/src/com/cloud/offering/DiskOffering.java b/api/src/com/cloud/offering/DiskOffering.java
deleted file mode 100644
index c2069c2..0000000
--- a/api/src/com/cloud/offering/DiskOffering.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.offering;
-
-import java.util.Date;
-
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-import com.cloud.storage.Storage.ProvisioningType;
-
-/**
- * Represents a disk offering that specifies what the end user needs in
- * the disk offering.
- *
- */
-public interface DiskOffering extends InfrastructureEntity, Identity, InternalIdentity {
-    enum State {
-        Inactive, Active,
-    }
-
-    public enum Type {
-        Disk, Service
-    };
-
-    State getState();
-
-    public enum DiskCacheMode {
-        NONE("none"), WRITEBACK("writeback"), WRITETHROUGH("writethrough");
-
-        private final String _diskCacheMode;
-
-        DiskCacheMode(String cacheMode) {
-            _diskCacheMode = cacheMode;
-        }
-
-        @Override
-        public String toString() {
-            return _diskCacheMode;
-        }
-    };
-
-    String getUniqueName();
-
-    boolean getUseLocalStorage();
-
-    Long getDomainId();
-
-    String getName();
-
-    boolean getSystemUse();
-
-    String getDisplayText();
-
-    public ProvisioningType getProvisioningType();
-
-    public String getTags();
-
-    public String[] getTagsArray();
-
-    Date getCreated();
-
-    boolean isCustomized();
-
-    void setDiskSize(long diskSize);
-
-    long getDiskSize();
-
-    void setCustomizedIops(Boolean customizedIops);
-
-    Boolean isCustomizedIops();
-
-    void setMinIops(Long minIops);
-
-    Long getMinIops();
-
-    void setMaxIops(Long maxIops);
-
-    Long getMaxIops();
-
-    boolean isRecreatable();
-
-    void setBytesReadRate(Long bytesReadRate);
-
-    Long getBytesReadRate();
-
-    void setBytesWriteRate(Long bytesWriteRate);
-
-    Long getBytesWriteRate();
-
-    void setIopsReadRate(Long iopsReadRate);
-
-    Long getIopsReadRate();
-
-    void setIopsWriteRate(Long iopsWriteRate);
-
-    Long getIopsWriteRate();
-
-    void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve);
-
-    Integer getHypervisorSnapshotReserve();
-
-    DiskCacheMode getCacheMode();
-
-    void setCacheMode(DiskCacheMode cacheMode);
-
-    Type getType();
-}
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
deleted file mode 100644
index 33b165b..0000000
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.offering;
-
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Networks.TrafficType;
-
-/**
- * Describes network offering
- *
- */
-public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, Identity {
-
-    public enum Availability {
-        Required, Optional
-    }
-
-    public enum State {
-        Disabled, Enabled
-    }
-
-    public enum Detail {
-        InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, RelatedNetworkOffering
-    }
-
-    public final static String SystemPublicNetwork = "System-Public-Network";
-    public final static String SystemControlNetwork = "System-Control-Network";
-    public final static String SystemManagementNetwork = "System-Management-Network";
-    public final static String SystemStorageNetwork = "System-Storage-Network";
-    public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
-
-    public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
-    public final static String QuickCloudNoServices = "QuickCloudNoServices";
-    public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
-    public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
-    public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";
-    public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering";
-    public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering";
-    public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks";
-    public final static String DefaultIsolatedNetworkOfferingForVpcNetworksNoLB = "DefaultIsolatedNetworkOfferingForVpcNetworksNoLB";
-    public final static String DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB = "DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB";
-    public final static String DefaultL2NetworkOffering = "DefaultL2NetworkOffering";
-    public final static String DefaultL2NetworkOfferingVlan = "DefaultL2NetworkOfferingVlan";
-    public final static String DefaultL2NetworkOfferingConfigDrive = "DefaultL2NetworkOfferingConfigDrive";
-    public final static String DefaultL2NetworkOfferingConfigDriveVlan = "DefaultL2NetworkOfferingConfigDriveVlan";
-
-    /**
-     * @return name for the network offering.
-     */
-    String getName();
-
-    /**
-     * @return text to display to the end user.
-     */
-    String getDisplayText();
-
-    /**
-     * @return the rate in megabits per sec to which a VM's network interface is throttled to
-     */
-    Integer getRateMbps();
-
-    /**
-     * @return the rate megabits per sec to which a VM's multicast&broadcast traffic is throttled to
-     */
-    Integer getMulticastRateMbps();
-
-    boolean getForVpc();
-
-    TrafficType getTrafficType();
-
-    boolean getSpecifyVlan();
-
-    String getTags();
-
-    boolean isDefault();
-
-    boolean isSystemOnly();
-
-    Availability getAvailability();
-
-    String getUniqueName();
-
-    void setState(State state);
-
-    State getState();
-
-    GuestType getGuestType();
-
-    Long getServiceOfferingId();
-
-    boolean getDedicatedLB();
-
-    boolean getSharedSourceNat();
-
-    boolean getRedundantRouter();
-
-    boolean isConserveMode();
-
-    boolean getElasticIp();
-
-    boolean getAssociatePublicIP();
-
-    boolean getElasticLb();
-
-    boolean getSpecifyIpRanges();
-
-    boolean isInline();
-
-    boolean getIsPersistent();
-
-    boolean getInternalLb();
-
-    boolean getPublicLb();
-
-    boolean getEgressDefaultPolicy();
-
-    Integer getConcurrentConnections();
-
-    boolean isKeepAliveEnabled();
-
-    boolean getSupportsStrechedL2();
-
-    boolean getSupportsPublicAccess();
-
-    String getServicePackage();
-}
diff --git a/api/src/com/cloud/offering/ServiceOffering.java b/api/src/com/cloud/offering/ServiceOffering.java
deleted file mode 100644
index 196d2b4..0000000
--- a/api/src/com/cloud/offering/ServiceOffering.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.offering;
-
-import java.util.Date;
-
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-/**
- * offered.
- */
-public interface ServiceOffering extends DiskOffering, InfrastructureEntity, InternalIdentity, Identity {
-    public static final String consoleProxyDefaultOffUniqueName = "Cloud.com-ConsoleProxy";
-    public static final String ssvmDefaultOffUniqueName = "Cloud.com-SecondaryStorage";
-    public static final String routerDefaultOffUniqueName = "Cloud.Com-SoftwareRouter";
-    public static final String elbVmDefaultOffUniqueName = "Cloud.Com-ElasticLBVm";
-    public static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
-    // leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
-
-    public enum StorageType {
-        local, shared
-    }
-
-    @Override
-    String getDisplayText();
-
-    @Override
-    Date getCreated();
-
-    @Override
-    String getTags();
-
-    /**
-     * @return user readable description
-     */
-    @Override
-    String getName();
-
-    /**
-     * @return is this a system service offering
-     */
-    @Override
-    boolean getSystemUse();
-
-    /**
-     * @return # of cpu.
-     */
-    Integer getCpu();
-
-    /**
-     * @return speed in mhz
-     */
-    Integer getSpeed();
-
-    /**
-     * @return ram size in megabytes
-     */
-    Integer getRamSize();
-
-    /**
-     * @return Does this service plan offer HA?
-     */
-    boolean getOfferHA();
-
-    /**
-     * @return Does this service plan offer VM to use CPU resources beyond the service offering limits?
-     */
-    boolean getLimitCpuUse();
-
-    /**
-     * @return Does this service plan support Volatile VM that is, discard VM's root disk and create a new one on reboot?
-     */
-    boolean getVolatileVm();
-
-    /**
-     * @return the rate in megabits per sec to which a VM's network interface is throttled to
-     */
-    Integer getRateMbps();
-
-    /**
-     * @return the rate megabits per sec to which a VM's multicast&broadcast traffic is throttled to
-     */
-    Integer getMulticastRateMbps();
-
-    /**
-     * @return whether or not the service offering requires local storage
-     */
-    @Override
-    boolean getUseLocalStorage();
-
-    @Override
-    Long getDomainId();
-
-    /**
-     * @return tag that should be present on the host needed, optional parameter
-     */
-    String getHostTag();
-
-    boolean getDefaultUse();
-
-    String getSystemVmType();
-
-    String getDeploymentPlanner();
-
-    boolean isDynamic();
-}
diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java
deleted file mode 100644
index 854b535..0000000
--- a/api/src/com/cloud/resource/ResourceService.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.resource;
-
-import java.util.List;
-
-import com.cloud.dc.DataCenter;
-import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
-import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
-import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
-import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
-import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
-
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Cluster;
-import com.cloud.utils.fsm.NoTransitionException;
-
-public interface ResourceService {
-    /**
-     * Updates a host
-     *
-     * @param cmd
-     *            - the command specifying hostId
-     * @return hostObject
-     * @throws NoTransitionException
-     */
-    Host updateHost(UpdateHostCmd cmd) throws NoTransitionException;
-
-    Host cancelMaintenance(CancelMaintenanceCmd cmd);
-
-    Host reconnectHost(ReconnectHostCmd cmd);
-
-    /**
-     * We will automatically create an Apache CloudStack cluster to attach to the external cluster and return a hyper host to perform
-     * host related operation within the cluster
-     *
-     * @param cmd
-     * @return
-     * @throws IllegalArgumentException
-     * @throws DiscoveryException
-     */
-    List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException;
-
-    boolean deleteCluster(DeleteClusterCmd cmd);
-
-    Cluster updateCluster(Cluster cluster, String clusterType, String hypervisor, String allocationState, String managedstate);
-
-    List<? extends Host> discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
-
-    List<? extends Host> discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
-
-    Host maintain(PrepareForMaintenanceCmd cmd);
-
-    /**
-     * Deletes a host
-     *
-     * @param hostId
-     *            TODO
-     * @param isForced
-     *            TODO
-     *
-     * @param true if deleted, false otherwise
-     */
-    boolean deleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage);
-
-    boolean updateClusterPassword(UpdateHostPasswordCmd upasscmd);
-
-    boolean updateHostPassword(UpdateHostPasswordCmd upasscmd);
-
-    Host getHost(long hostId);
-
-    Cluster getCluster(Long clusterId);
-
-    DataCenter getZone(Long zoneId);
-
-    List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
-
-    boolean releaseHostReservation(Long hostId);
-
-}
diff --git a/api/src/com/cloud/storage/GuestOS.java b/api/src/com/cloud/storage/GuestOS.java
deleted file mode 100644
index 371260b..0000000
--- a/api/src/com/cloud/storage/GuestOS.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.util.Date;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface GuestOS extends InternalIdentity, Identity {
-
-    String getName();
-
-    String getDisplayName();
-
-    long getCategoryId();
-
-    Date getCreated();
-
-    Date getRemoved();
-
-    boolean getIsUserDefined();
-}
diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java
deleted file mode 100644
index e40b1e6..0000000
--- a/api/src/com/cloud/storage/StorageService.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.storage;
-
-import java.net.UnknownHostException;
-import java.util.Map;
-
-import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
-
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.exception.ResourceUnavailableException;
-
-public interface StorageService {
-    /**
-     * Create StoragePool based on uri
-     *
-     * @param cmd
-     *            The command object that specifies the zone, cluster/pod, URI, details, etc. to use to create the
-     *            storage pool.
-     * @return
-     *            The StoragePool created.
-     * @throws ResourceInUseException
-     * @throws IllegalArgumentException
-     * @throws UnknownHostException
-     * @throws ResourceUnavailableException
-     */
-    StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException;
-
-    ImageStore createSecondaryStagingStore(CreateSecondaryStagingStoreCmd cmd);
-
-    /**
-     * Delete the storage pool
-     *
-     * @param cmd
-     *            - the command specifying poolId
-     * @return success or failure
-     */
-    boolean deletePool(DeletePoolCmd cmd);
-
-    /**
-     * Enable maintenance for primary storage
-     *
-     * @param primaryStorageId
-     *            - the primaryStorageId
-     * @return the primary storage pool
-     * @throws ResourceUnavailableException
-     * @throws InsufficientCapacityException
-     */
-    StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException;
-
-    /**
-     * Complete maintenance for primary storage
-     *
-     * @param cmd
-     *            - the command specifying primaryStorageId
-     * @return the primary storage pool
-     * @throws ResourceUnavailableException
-     */
-    StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException;
-
-    StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException;
-
-    StoragePool getStoragePool(long id);
-
-    boolean deleteImageStore(DeleteImageStoreCmd cmd);
-
-    boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd);
-
-    ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException,
-            InvalidParameterValueException;
-
-
-        /**
-     * Migrate existing NFS to use object store.
-     * @param name object store name.
-     * @param url object store url.
-     * @param providerName object store provider Name.
-     * @param details object store other details
-     * @return Object store created.
-     * @throws IllegalArgumentException
-     * @throws DiscoveryException
-     * @throws InvalidParameterValueException
-     */
-    ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException,
-            InvalidParameterValueException;
-
-
-}
diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java
deleted file mode 100644
index cf13cd6..0000000
--- a/api/src/com/cloud/storage/VolumeApiService.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.storage;
-
-import java.net.MalformedURLException;
-
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
-import org.apache.cloudstack.api.response.GetUploadParamsResponse;
-
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.user.Account;
-
-public interface VolumeApiService {
-    /**
-     * Creates the database object for a volume based on the given criteria
-     *
-     * @param cmd
-     *            the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
-     *            name)
-     * @return the volume object
-     */
-    Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
-
-    /**
-     * Creates the volume based on the given criteria
-     *
-     * @param cmd
-     *            the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
-     *            name)
-     * @return the volume object
-     */
-    Volume createVolume(CreateVolumeCmd cmd);
-
-    /**
-     * Resizes the volume based on the given criteria
-     *
-     * @param cmd
-     *            the API command wrapping the criteria
-     * @return the volume object
-     * @throws ResourceAllocationException
-     */
-    Volume resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException;
-
-    Volume migrateVolume(MigrateVolumeCmd cmd);
-
-    /**
-     * Uploads the volume to secondary storage
-     *
-     * @return Volume object
-     */
-    Volume uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException;
-
-    GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException;
-
-    boolean deleteVolume(long volumeId, Account caller);
-
-    Volume attachVolumeToVM(AttachVolumeCmd command);
-
-    Volume detachVolumeFromVM(DetachVolumeCmd cmd);
-
-    Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
-            throws ResourceAllocationException;
-
-    Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
-
-    Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo);
-
-    /**
-     * Extracts the volume to a particular location.
-     *
-     * @param cmd
-     *            the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume exists),
-     *            id (the id of the volume)
-     */
-    String extractVolume(ExtractVolumeCmd cmd);
-
-    boolean isDisplayResourceEnabled(Long id);
-
-    void updateDisplay(Volume volume, Boolean displayVolume);
-
-    Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException;
-}
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
deleted file mode 100644
index eb13935..0000000
--- a/api/src/com/cloud/storage/snapshot/SnapshotApiService.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.snapshot;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
-import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
-
-import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-import com.cloud.utils.Pair;
-import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
-
-public interface SnapshotApiService {
-
-    /**
-     * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval
-     *
-     * @param cmd
-     *            the command containing the search criteria (order by, limit, etc.)
-     * @return list of snapshots
-     */
-    Pair<List<? extends Snapshot>, Integer> listSnapshots(ListSnapshotsCmd cmd);
-
-    /**
-     * Delete specified snapshot from the specified. If no other policies are assigned it calls destroy snapshot. This
-     * will be
-     * used for manual snapshots too.
-     *
-     * @param snapshotId
-     *            TODO
-     */
-    boolean deleteSnapshot(long snapshotId);
-
-    /**
-     * Creates a policy with specified schedule. maxSnaps specifies the number of most recent snapshots that are to be
-     * retained.
-     * If the number of snapshots go beyond maxSnaps the oldest snapshot is deleted
-     *
-     * @param cmd
-     *            the command that
-     * @param policyOwner
-     *            TODO
-     * @return the newly created snapshot policy if success, null otherwise
-     */
-    SnapshotPolicy createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner);
-
-    /**
-     * Get the recurring snapshots scheduled for this volume currently along with the time at which they are scheduled
-     *
-     * @param cmd
-     *            the command wrapping the volumeId (volume for which the snapshots are required) and policyId (to show
-     *            snapshots for only this policy).
-     * @return The list of snapshot schedules.
-     */
-    public List<? extends SnapshotSchedule> findRecurringSnapshotSchedule(ListRecurringSnapshotScheduleCmd cmd);
-
-    /**
-     * list all snapshot policies assigned to the specified volume
-     *
-     * @param cmd
-     *            the command that specifies the volume criteria
-     * @return list of snapshot policies
-     */
-    Pair<List<? extends SnapshotPolicy>, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd);
-
-    boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd);
-
-    Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
-
-    /**
-     * Create a snapshot of a volume
-     *
-     * @param snapshotOwner
-     *            TODO
-     * @param cmd
-     *            the API command wrapping the parameters for creating the snapshot (mainly volumeId)
-     *
-     * @return the Snapshot that was created
-     */
-    Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner);
-
-    /**
-     * @param vol
-     * @return
-     */
-    Long getHostIdForSnapshotOperation(Volume vol);
-
-    Snapshot revertSnapshot(Long snapshotId);
-
-    Snapshot backupSnapshotFromVmSnapshot(Long snapshotId, Long vmId, Long volumeId, Long vmSnapshotId);
-
-    SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd updateSnapshotPolicyCmd);
-}
diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java
deleted file mode 100644
index 564f3b9..0000000
--- a/api/src/com/cloud/template/VirtualMachineTemplate.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.template;
-
-import java.util.Date;
-import java.util.Map;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.Volume.Event;
-import com.cloud.storage.Volume.State;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.fsm.StateObject;
-
-public interface VirtualMachineTemplate extends ControlledEntity, Identity, InternalIdentity, StateObject<VirtualMachineTemplate.State> {
-    enum State {
-        Active,
-        Inactive,
-        NotUploaded,
-        UploadInProgress,
-        UploadError,
-        UploadAbandoned;
-
-        public static StateMachine2<State, Event, VirtualMachineTemplate> getStateMachine() {
-            return s_fsm;
-        }
-
-        private final static StateMachine2<State, Event, VirtualMachineTemplate> s_fsm = new StateMachine2<State, Event, VirtualMachineTemplate>();
-        static {
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationTimeout, UploadAbandoned, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.UploadRequested, UploadInProgress, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationSucceeded, Active, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationFailed, UploadError, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationSucceeded, Active, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationFailed, UploadError, null));
-            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationTimeout, UploadError, null));
-        }
-    }
-
-    enum Event {
-        OperationFailed,
-        OperationSucceeded,
-        UploadRequested,
-        OperationTimeout;
-    }
-
-    public static enum BootloaderType {
-        PyGrub, HVM, External, CD
-    };
-
-    public enum TemplateFilter {
-        featured, // returns templates that have been marked as featured and public
-        self, // returns templates that have been registered or created by the calling user
-        selfexecutable, // same as self, but only returns templates that are ready to be deployed with
-        shared, // including templates that have been granted to the calling user by another user
-        sharedexecutable, // ready templates that have been granted to the calling user by another user
-        executable, // templates that are owned by the calling user, or public templates, that can be used to deploy a
-        community, // returns templates that have been marked as public but not featured
-        all // all templates (only usable by admins)
-    }
-
-    @Override
-    State getState();
-
-    boolean isFeatured();
-
-    /**
-     * @return public or private template
-     */
-    boolean isPublicTemplate();
-
-    boolean isExtractable();
-
-    /**
-     * @return name
-     */
-    String getName();
-
-    ImageFormat getFormat();
-
-    boolean isRequiresHvm();
-
-    String getDisplayText();
-
-    boolean getEnablePassword();
-
-    boolean getEnableSshKey();
-
-    boolean isCrossZones();
-
-    Date getCreated();
-
-    long getGuestOSId();
-
-    boolean isBootable();
-
-    TemplateType getTemplateType();
-
-    HypervisorType getHypervisorType();
-
-    int getBits();
-
-    String getUniqueName();
-
-    String getUrl();
-
-    String getChecksum();
-
-    Long getSourceTemplateId();
-
-    String getTemplateTag();
-
-    Map getDetails();
-
-    boolean isDynamicallyScalable();
-
-    Long getParentTemplateId();
-
-    long getUpdatedCount();
-
-    void incrUpdatedCount();
-
-    Date getUpdated();
-}
diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java
deleted file mode 100644
index 9683d9f..0000000
--- a/api/src/com/cloud/user/AccountService.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.util.Map;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-
-import com.cloud.domain.Domain;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-
-
-public interface AccountService {
-
-    /**
-     * Creates a new user and account, stores the password as is so encrypted passwords are recommended.
-     *
-     * @param userName
-     *            TODO
-     * @param password
-     *            TODO
-     * @param firstName
-     *            TODO
-     * @param lastName
-     *            TODO
-     * @param email
-     *            TODO
-     * @param timezone
-     *            TODO
-     * @param accountName
-     *            TODO
-     * @param accountType
-     *            TODO
-     * @param domainId
-     *            TODO
-     * @param networkDomain
-     *            TODO
-     *
-     * @return the user if created successfully, null otherwise
-     */
-    UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName,
-        short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID);
-
-    UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId, String networkDomain,
-                                  Map<String, String> details, String accountUUID, String userUUID, User.Source source);
-
-    /**
-     * Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses
-     * allocated/etc.
-     *
-     * @param userId
-     * @return UserAccount object
-     */
-    UserAccount lockUser(long userId);
-
-    Account getSystemAccount();
-
-    User getSystemUser();
-
-    User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
-
-    User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
-                    User.Source source);
-
-    boolean isAdmin(Long accountId);
-
-    Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId);
-
-    Account getActiveAccountByName(String accountName, Long domainId);
-
-    UserAccount getActiveUserAccount(String username, Long domainId);
-
-    UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey, String timeZone);
-
-    Account getActiveAccountById(long accountId);
-
-    Account getAccount(long accountId);
-
-    User getActiveUser(long userId);
-
-    User getUserIncludingRemoved(long userId);
-
-    boolean isRootAdmin(Long accountId);
-
-    boolean isDomainAdmin(Long accountId);
-
-    boolean isNormalUser(long accountId);
-
-    User getActiveUserByRegistrationToken(String registrationToken);
-
-    void markUserRegistered(long userId);
-
-    public String[] createApiKeyAndSecretKey(RegisterCmd cmd);
-
-    public String[] createApiKeyAndSecretKey(final long userId);
-
-    UserAccount getUserByApiKey(String apiKey);
-
-    RoleType getRoleType(Account account);
-
-    void checkAccess(Account account, Domain domain) throws PermissionDeniedException;
-
-    void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
-
-    void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException;
-
-    void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException;
-
-    void checkAccess(User user, ControlledEntity entity);
-
-    void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
-            ControlledEntity... entities) throws PermissionDeniedException;
-
-    Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
-
-    /**
-     * returns the user account object for a given user id
-     * @param userId user id
-     * @return useraccount object if it exists else null
-     */
-    UserAccount getUserAccountById(Long userId);
-
-    public Map<String, String> getKeys(GetUserKeysCmd cmd);
-}
diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java
deleted file mode 100644
index d909774..0000000
--- a/api/src/com/cloud/vm/DiskProfile.java
+++ /dev/null
@@ -1,225 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.Volume;
-
-/**
- * DiskProfile describes a disk and what functionality is required from it.
- * and resources to allocate and create disks. There object is immutable once
- */
-public class DiskProfile {
-    private long size;
-    private String[] tags;
-    private Volume.Type type;
-    private String name;
-    private boolean useLocalStorage;
-    private boolean recreatable;
-    private long diskOfferingId;
-    private Long templateId;
-    private long volumeId;
-    private String path;
-    private ProvisioningType provisioningType;
-    private Long bytesReadRate;
-    private Long bytesWriteRate;
-    private Long iopsReadRate;
-    private Long iopsWriteRate;
-    private String cacheMode;
-
-    private HypervisorType hyperType;
-
-    protected DiskProfile() {
-    }
-
-    public DiskProfile(long volumeId, Volume.Type type, String name, long diskOfferingId, long size, String[] tags, boolean useLocalStorage, boolean recreatable,
-            Long templateId) {
-        this.type = type;
-        this.name = name;
-        this.size = size;
-        this.tags = tags;
-        this.useLocalStorage = useLocalStorage;
-        this.recreatable = recreatable;
-        this.diskOfferingId = diskOfferingId;
-        this.templateId = templateId;
-        this.volumeId = volumeId;
-    }
-
-    public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType) {
-        this(vol.getId(),
-            vol.getVolumeType(),
-            vol.getName(),
-            offering.getId(),
-            vol.getSize(),
-            offering.getTagsArray(),
-            offering.getUseLocalStorage(),
-            offering.isCustomized(),
-            null);
-        this.hyperType = hyperType;
-    }
-
-    public DiskProfile(DiskProfile dp) {
-
-    }
-
-    /**
-     * @return size of the disk requested in bytes.
-     */
-    public long getSize() {
-        return size;
-    }
-
-    /**
-     * @return id of the volume backing up this disk characteristics
-     */
-    public long getVolumeId() {
-        return volumeId;
-    }
-
-    /**
-     * @return Unique name for the disk.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @return tags for the disk. This can be used to match it to different storage pools.
-     */
-    public String[] getTags() {
-        return tags;
-    }
-
-    /**
-     * @return type of volume.
-     */
-    public Volume.Type getType() {
-        return type;
-    }
-
-    /**
-     * @return Does this volume require local storage?
-     */
-    public boolean useLocalStorage() {
-        return useLocalStorage;
-    }
-
-    public void setUseLocalStorage(boolean useLocalStorage) {
-        this.useLocalStorage = useLocalStorage;
-    }
-
-    /**
-     * @return Is this volume recreatable? A volume is recreatable if the disk's content can be
-     *         reconstructed from the template.
-     */
-    public boolean isRecreatable() {
-        return recreatable;
-    }
-
-    /**
-     * @return template id the disk is based on. Can be null if it is not based on any templates.
-     */
-    public Long getTemplateId() {
-        return templateId;
-    }
-
-    public void setTemplateId(Long templateId) {
-        this.templateId = templateId;
-    }
-
-    /**
-     * @return disk offering id that the disk is based on.
-     */
-    public long getDiskOfferingId() {
-        return diskOfferingId;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("DskChr[").append(type).append("|").append(size).append("|").append("]").toString();
-    }
-
-    public void setHyperType(HypervisorType hyperType) {
-        this.hyperType = hyperType;
-    }
-
-    public HypervisorType getHypervisorType() {
-        return this.hyperType;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public String getPath() {
-        return this.path;
-    }
-
-    public void setProvisioningType(ProvisioningType provisioningType){
-        this.provisioningType = provisioningType;
-    }
-
-    public ProvisioningType getProvisioningType(){
-        return this.provisioningType;
-    }
-
-    public void setSize(long size) {
-        this.size = size;
-    }
-
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public void setCacheMode(String cacheMode) {
-        this.cacheMode = cacheMode;
-    }
-
-    public String getCacheMode() {
-        return cacheMode;
-    }
-}
diff --git a/api/src/com/cloud/agent/api/Answer.java b/api/src/main/java/com/cloud/agent/api/Answer.java
similarity index 100%
rename from api/src/com/cloud/agent/api/Answer.java
rename to api/src/main/java/com/cloud/agent/api/Answer.java
diff --git a/api/src/com/cloud/agent/api/BadCommand.java b/api/src/main/java/com/cloud/agent/api/BadCommand.java
similarity index 100%
rename from api/src/com/cloud/agent/api/BadCommand.java
rename to api/src/main/java/com/cloud/agent/api/BadCommand.java
diff --git a/api/src/com/cloud/agent/api/Command.java b/api/src/main/java/com/cloud/agent/api/Command.java
similarity index 100%
rename from api/src/com/cloud/agent/api/Command.java
rename to api/src/main/java/com/cloud/agent/api/Command.java
diff --git a/api/src/com/cloud/agent/api/HostVmStateReportEntry.java b/api/src/main/java/com/cloud/agent/api/HostVmStateReportEntry.java
similarity index 100%
rename from api/src/com/cloud/agent/api/HostVmStateReportEntry.java
rename to api/src/main/java/com/cloud/agent/api/HostVmStateReportEntry.java
diff --git a/api/src/com/cloud/agent/api/LogLevel.java b/api/src/main/java/com/cloud/agent/api/LogLevel.java
similarity index 100%
rename from api/src/com/cloud/agent/api/LogLevel.java
rename to api/src/main/java/com/cloud/agent/api/LogLevel.java
diff --git a/api/src/com/cloud/agent/api/PvlanSetupCommand.java b/api/src/main/java/com/cloud/agent/api/PvlanSetupCommand.java
similarity index 100%
rename from api/src/com/cloud/agent/api/PvlanSetupCommand.java
rename to api/src/main/java/com/cloud/agent/api/PvlanSetupCommand.java
diff --git a/api/src/com/cloud/agent/api/StoragePoolInfo.java b/api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java
similarity index 100%
rename from api/src/com/cloud/agent/api/StoragePoolInfo.java
rename to api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java
diff --git a/api/src/com/cloud/agent/api/UnsupportedAnswer.java b/api/src/main/java/com/cloud/agent/api/UnsupportedAnswer.java
similarity index 100%
rename from api/src/com/cloud/agent/api/UnsupportedAnswer.java
rename to api/src/main/java/com/cloud/agent/api/UnsupportedAnswer.java
diff --git a/api/src/com/cloud/agent/api/VgpuTypesInfo.java b/api/src/main/java/com/cloud/agent/api/VgpuTypesInfo.java
similarity index 100%
rename from api/src/com/cloud/agent/api/VgpuTypesInfo.java
rename to api/src/main/java/com/cloud/agent/api/VgpuTypesInfo.java
diff --git a/api/src/com/cloud/agent/api/storage/CreateVolumeOVACommand.java b/api/src/main/java/com/cloud/agent/api/storage/CreateVolumeOVACommand.java
similarity index 100%
rename from api/src/com/cloud/agent/api/storage/CreateVolumeOVACommand.java
rename to api/src/main/java/com/cloud/agent/api/storage/CreateVolumeOVACommand.java
diff --git a/api/src/com/cloud/agent/api/storage/OVFHelper.java b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
similarity index 100%
rename from api/src/com/cloud/agent/api/storage/OVFHelper.java
rename to api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
diff --git a/api/src/com/cloud/agent/api/storage/PasswordAuth.java b/api/src/main/java/com/cloud/agent/api/storage/PasswordAuth.java
similarity index 100%
rename from api/src/com/cloud/agent/api/storage/PasswordAuth.java
rename to api/src/main/java/com/cloud/agent/api/storage/PasswordAuth.java
diff --git a/api/src/com/cloud/agent/api/storage/PrepareOVAPackingCommand.java b/api/src/main/java/com/cloud/agent/api/storage/PrepareOVAPackingCommand.java
similarity index 100%
rename from api/src/com/cloud/agent/api/storage/PrepareOVAPackingCommand.java
rename to api/src/main/java/com/cloud/agent/api/storage/PrepareOVAPackingCommand.java
diff --git a/api/src/com/cloud/agent/api/to/DataObjectType.java b/api/src/main/java/com/cloud/agent/api/to/DataObjectType.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DataObjectType.java
rename to api/src/main/java/com/cloud/agent/api/to/DataObjectType.java
diff --git a/api/src/com/cloud/agent/api/to/DataStoreTO.java b/api/src/main/java/com/cloud/agent/api/to/DataStoreTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DataStoreTO.java
rename to api/src/main/java/com/cloud/agent/api/to/DataStoreTO.java
diff --git a/api/src/com/cloud/agent/api/to/DataTO.java b/api/src/main/java/com/cloud/agent/api/to/DataTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DataTO.java
rename to api/src/main/java/com/cloud/agent/api/to/DataTO.java
diff --git a/api/src/com/cloud/agent/api/to/DatadiskTO.java b/api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DatadiskTO.java
rename to api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java
diff --git a/api/src/com/cloud/agent/api/to/DhcpTO.java b/api/src/main/java/com/cloud/agent/api/to/DhcpTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DhcpTO.java
rename to api/src/main/java/com/cloud/agent/api/to/DhcpTO.java
diff --git a/api/src/com/cloud/agent/api/to/DiskTO.java b/api/src/main/java/com/cloud/agent/api/to/DiskTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/DiskTO.java
rename to api/src/main/java/com/cloud/agent/api/to/DiskTO.java
diff --git a/api/src/com/cloud/agent/api/to/FirewallRuleTO.java b/api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/FirewallRuleTO.java
rename to api/src/main/java/com/cloud/agent/api/to/FirewallRuleTO.java
diff --git a/api/src/com/cloud/agent/api/to/GPUDeviceTO.java b/api/src/main/java/com/cloud/agent/api/to/GPUDeviceTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/GPUDeviceTO.java
rename to api/src/main/java/com/cloud/agent/api/to/GPUDeviceTO.java
diff --git a/api/src/com/cloud/agent/api/to/HostTO.java b/api/src/main/java/com/cloud/agent/api/to/HostTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/HostTO.java
rename to api/src/main/java/com/cloud/agent/api/to/HostTO.java
diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/main/java/com/cloud/agent/api/to/IpAddressTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/IpAddressTO.java
rename to api/src/main/java/com/cloud/agent/api/to/IpAddressTO.java
diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/LoadBalancerTO.java
rename to api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
diff --git a/api/src/com/cloud/agent/api/to/MonitorServiceTO.java b/api/src/main/java/com/cloud/agent/api/to/MonitorServiceTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/MonitorServiceTO.java
rename to api/src/main/java/com/cloud/agent/api/to/MonitorServiceTO.java
diff --git a/api/src/com/cloud/agent/api/to/NetworkACLTO.java b/api/src/main/java/com/cloud/agent/api/to/NetworkACLTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/NetworkACLTO.java
rename to api/src/main/java/com/cloud/agent/api/to/NetworkACLTO.java
diff --git a/api/src/com/cloud/agent/api/to/NetworkTO.java b/api/src/main/java/com/cloud/agent/api/to/NetworkTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/NetworkTO.java
rename to api/src/main/java/com/cloud/agent/api/to/NetworkTO.java
diff --git a/api/src/com/cloud/agent/api/to/NfsTO.java b/api/src/main/java/com/cloud/agent/api/to/NfsTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/NfsTO.java
rename to api/src/main/java/com/cloud/agent/api/to/NfsTO.java
diff --git a/api/src/main/java/com/cloud/agent/api/to/NicTO.java b/api/src/main/java/com/cloud/agent/api/to/NicTO.java
new file mode 100644
index 0000000..4861225
--- /dev/null
+++ b/api/src/main/java/com/cloud/agent/api/to/NicTO.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import com.cloud.offering.NetworkOffering;
+
+import java.util.List;
+import java.util.Map;
+
+public class NicTO extends NetworkTO {
+    int deviceId;
+    Integer networkRateMbps;
+    Integer networkRateMulticastMbps;
+    boolean defaultNic;
+    boolean pxeDisable;
+    String nicUuid;
+    List<String> nicSecIps;
+    Map<NetworkOffering.Detail, String> details;
+    boolean dpdkDisabled;
+
+    public NicTO() {
+        super();
+    }
+
+    public void setDeviceId(int deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public int getDeviceId() {
+        return deviceId;
+    }
+
+    public Integer getNetworkRateMbps() {
+        return networkRateMbps;
+    }
+
+    public void setNetworkRateMbps(Integer networkRateMbps) {
+        this.networkRateMbps = networkRateMbps;
+    }
+
+    public Integer getNetworkRateMulticastMbps() {
+        return networkRateMulticastMbps;
+    }
+
+    public boolean isDefaultNic() {
+        return defaultNic;
+    }
+
+    public void setDefaultNic(boolean defaultNic) {
+        this.defaultNic = defaultNic;
+    }
+
+    public void setPxeDisable(boolean pxeDisable) {
+        this.pxeDisable = pxeDisable;
+    }
+
+    public boolean getPxeDisable() {
+        return pxeDisable;
+    }
+
+    @Override
+    public String getUuid() {
+        return nicUuid;
+    }
+
+    @Override
+    public void setUuid(String uuid) {
+        this.nicUuid = uuid;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString();
+    }
+
+    public void setNicSecIps(List<String> secIps) {
+        this.nicSecIps = secIps;
+    }
+
+    public List<String> getNicSecIps() {
+        return nicSecIps;
+    }
+
+    public String getNetworkUuid() {
+        return super.getUuid();
+    }
+
+    public void setNetworkUuid(String uuid) {
+        super.setUuid(uuid);
+    }
+
+    public Map<NetworkOffering.Detail, String> getDetails() {
+        return details;
+    }
+
+    public void setDetails(final Map<NetworkOffering.Detail, String> details) {
+        this.details = details;
+    }
+
+    public boolean isDpdkDisabled() {
+        return dpdkDisabled;
+    }
+
+    public void setDpdkDisabled(boolean dpdkDisabled) {
+        this.dpdkDisabled = dpdkDisabled;
+    }
+}
diff --git a/api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java b/api/src/main/java/com/cloud/agent/api/to/PortForwardingRuleTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/PortForwardingRuleTO.java
rename to api/src/main/java/com/cloud/agent/api/to/PortForwardingRuleTO.java
diff --git a/api/src/main/java/com/cloud/agent/api/to/S3TO.java b/api/src/main/java/com/cloud/agent/api/to/S3TO.java
new file mode 100644
index 0000000..233238c
--- /dev/null
+++ b/api/src/main/java/com/cloud/agent/api/to/S3TO.java
@@ -0,0 +1,337 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import java.util.Date;
+
+import com.cloud.agent.api.LogLevel;
+import com.cloud.agent.api.LogLevel.Log4jLevel;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.utils.storage.S3.ClientOptions;
+
+public final class S3TO implements ClientOptions, DataStoreTO {
+
+    private Long id;
+    private String uuid;
+    @LogLevel(Log4jLevel.Off)
+    private String accessKey;
+    @LogLevel(Log4jLevel.Off)
+    private String secretKey;
+    private String endPoint;
+    private String bucketName;
+    private String signer;
+    private Boolean httpsFlag;
+    private Boolean useTCPKeepAlive;
+    private Integer connectionTimeout;
+    private Integer maxErrorRetry;
+    private Integer socketTimeout;
+    private Integer connectionTtl;
+    private Date created;
+    private boolean enableRRS;
+    private long maxSingleUploadSizeInBytes;
+    private static final String pathSeparator = "/";
+
+    public S3TO(final Long id, final String uuid, final String accessKey, final String secretKey, final String endPoint, final String bucketName,
+            final String signer, final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, final Integer socketTimeout,
+            final Date created, final boolean enableRRS, final long maxUploadSize, final Integer connectionTtl, final Boolean useTCPKeepAlive) {
+
+        this.id = id;
+        this.uuid = uuid;
+        this.accessKey = accessKey;
+        this.secretKey = secretKey;
+        this.endPoint = endPoint;
+        this.bucketName = bucketName;
+        this.signer = signer;
+        this.httpsFlag = httpsFlag;
+        this.connectionTimeout = connectionTimeout;
+        this.maxErrorRetry = maxErrorRetry;
+        this.socketTimeout = socketTimeout;
+        this.created = created;
+        this.enableRRS = enableRRS;
+        this.maxSingleUploadSizeInBytes = maxUploadSize;
+        this.connectionTtl = connectionTtl;
+        this.useTCPKeepAlive = useTCPKeepAlive;
+
+    }
+
+    public Long getId() {
+        return this.id;
+    }
+
+    public void setId(final Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getUuid() {
+        return this.uuid;
+    }
+
+    @Override
+    public String getUrl() {
+        return null;
+    }
+
+    public void setUuid(final String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public String getAccessKey() {
+        return this.accessKey;
+    }
+
+    public void setAccessKey(final String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    @Override
+    public String getSecretKey() {
+        return this.secretKey;
+    }
+
+    public void setSecretKey(final String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    @Override
+    public String getEndPoint() {
+        return this.endPoint;
+    }
+
+    public void setEndPoint(final String endPoint) {
+        this.endPoint = endPoint;
+    }
+
+    public String getBucketName() {
+        return this.bucketName;
+    }
+
+    public void setBucketName(final String bucketName) {
+        this.bucketName = bucketName;
+    }
+
+    @Override
+    public String getSigner() {
+        return this.signer;
+    }
+
+    public void setSigner(final String signer) {
+        this.signer = signer;
+    }
+
+    @Override
+    public Boolean isHttps() {
+        return this.httpsFlag;
+    }
+
+    public void setHttps(final Boolean httpsFlag) {
+        this.httpsFlag = httpsFlag;
+    }
+
+    @Override
+    public Integer getConnectionTimeout() {
+        return connectionTimeout;
+    }
+
+    public void setConnectionTimeout(final Integer connectionTimeout) {
+        this.connectionTimeout = connectionTimeout;
+    }
+
+    @Override
+    public Integer getMaxErrorRetry() {
+        return maxErrorRetry;
+    }
+
+    public void setMaxErrorRetry(final Integer maxErrorRetry) {
+        this.maxErrorRetry = maxErrorRetry;
+    }
+
+    @Override
+    public Integer getSocketTimeout() {
+        return socketTimeout;
+    }
+
+    public void setSocketTimeout(final Integer socketTimeout) {
+        this.socketTimeout = socketTimeout;
+    }
+
+    @Override
+    public Integer getConnectionTtl() {
+        return this.connectionTtl;
+    }
+
+    public void setConnectionTtl(final Integer connectionTtl) {
+        this.connectionTtl = connectionTtl;
+    }
+
+    @Override
+    public Boolean getUseTCPKeepAlive() {
+        return this.useTCPKeepAlive;
+    }
+
+    public void setUseTCPKeepAlive(final Boolean useTCPKeepAlive) {
+        this.useTCPKeepAlive = useTCPKeepAlive;
+    }
+
+    public Date getCreated() {
+        return this.created;
+    }
+
+    public void setCreated(final Date created) {
+        this.created = created;
+    }
+
+    @Override
+    public DataStoreRole getRole() {
+        return DataStoreRole.Image;
+    }
+
+    public boolean isEnableRRS() {
+        return enableRRS;
+    }
+
+    public void setEnableRRS(boolean enableRRS) {
+        this.enableRRS = enableRRS;
+    }
+
+    public long getMaxSingleUploadSizeInBytes() {
+        return maxSingleUploadSizeInBytes;
+    }
+
+    public void setMaxSingleUploadSizeInBytes(long maxSingleUploadSizeInBytes) {
+        this.maxSingleUploadSizeInBytes = maxSingleUploadSizeInBytes;
+    }
+
+    public boolean getSingleUpload(long objSize) {
+        if (maxSingleUploadSizeInBytes < 0) {
+            // always use single part upload
+            return true;
+        } else if (maxSingleUploadSizeInBytes == 0) {
+            // always use multi part upload
+            return false;
+        } else {
+            // check object size to set flag
+            if (objSize < maxSingleUploadSizeInBytes) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public String getPathSeparator() {
+        return pathSeparator;
+    }
+
+    @Override
+    public boolean equals(final Object thatObject) {
+
+        if (this == thatObject) {
+            return true;
+        }
+        if (thatObject == null || getClass() != thatObject.getClass()) {
+            return false;
+        }
+
+        final S3TO thatS3TO = (S3TO)thatObject;
+
+        if (httpsFlag != null ? !httpsFlag.equals(thatS3TO.httpsFlag) : thatS3TO.httpsFlag != null) {
+            return false;
+        }
+
+        if (accessKey != null ? !accessKey.equals(thatS3TO.accessKey) : thatS3TO.accessKey != null) {
+            return false;
+        }
+
+        if (connectionTimeout != null ? !connectionTimeout.equals(thatS3TO.connectionTimeout) : thatS3TO.connectionTimeout != null) {
+            return false;
+        }
+
+        if (endPoint != null ? !endPoint.equals(thatS3TO.endPoint) : thatS3TO.endPoint != null) {
+            return false;
+        }
+
+        if (id != null ? !id.equals(thatS3TO.id) : thatS3TO.id != null) {
+            return false;
+        }
+
+        if (uuid != null ? !uuid.equals(thatS3TO.uuid) : thatS3TO.uuid != null) {
+            return false;
+        }
+
+        if (maxErrorRetry != null ? !maxErrorRetry.equals(thatS3TO.maxErrorRetry) : thatS3TO.maxErrorRetry != null) {
+            return false;
+        }
+
+        if (secretKey != null ? !secretKey.equals(thatS3TO.secretKey) : thatS3TO.secretKey != null) {
+            return false;
+        }
+
+        if (socketTimeout != null ? !socketTimeout.equals(thatS3TO.socketTimeout) : thatS3TO.socketTimeout != null) {
+            return false;
+        }
+
+        if (connectionTtl != null ? !connectionTtl.equals(thatS3TO.connectionTtl) : thatS3TO.connectionTtl != null) {
+            return false;
+        }
+
+        if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatS3TO.useTCPKeepAlive) : thatS3TO.useTCPKeepAlive != null) {
+            return false;
+        }
+
+        if (bucketName != null ? !bucketName.equals(thatS3TO.bucketName) : thatS3TO.bucketName != null) {
+            return false;
+        }
+
+        if (signer != null ? !signer.equals(thatS3TO.signer) : thatS3TO.signer != null) {
+            return false;
+        }
+
+        if (created != null ? !created.equals(thatS3TO.created) : thatS3TO.created != null) {
+            return false;
+        }
+
+        if (enableRRS != thatS3TO.enableRRS) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    @Override
+    public int hashCode() {
+
+        int result = id != null ? id.hashCode() : 0;
+
+        result = 31 * result + (accessKey != null ? accessKey.hashCode() : 0);
+        result = 31 * result + (secretKey != null ? secretKey.hashCode() : 0);
+        result = 31 * result + (endPoint != null ? endPoint.hashCode() : 0);
+        result = 31 * result + (bucketName != null ? bucketName.hashCode() : 0);
+        result = 31 * result + (signer != null ? signer.hashCode() : 0);
+        result = 31 * result + (httpsFlag ? 1 : 0);
+        result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
+        result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
+        result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
+        result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
+        result = 31 * result + (useTCPKeepAlive ? 1 : 0);
+
+        return result;
+    }
+}
diff --git a/api/src/com/cloud/agent/api/to/StaticNatRuleTO.java b/api/src/main/java/com/cloud/agent/api/to/StaticNatRuleTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/StaticNatRuleTO.java
rename to api/src/main/java/com/cloud/agent/api/to/StaticNatRuleTO.java
diff --git a/api/src/com/cloud/agent/api/to/StorageFilerTO.java b/api/src/main/java/com/cloud/agent/api/to/StorageFilerTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/StorageFilerTO.java
rename to api/src/main/java/com/cloud/agent/api/to/StorageFilerTO.java
diff --git a/api/src/com/cloud/agent/api/to/SwiftTO.java b/api/src/main/java/com/cloud/agent/api/to/SwiftTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/SwiftTO.java
rename to api/src/main/java/com/cloud/agent/api/to/SwiftTO.java
diff --git a/api/src/com/cloud/agent/api/to/TemplateTO.java b/api/src/main/java/com/cloud/agent/api/to/TemplateTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/TemplateTO.java
rename to api/src/main/java/com/cloud/agent/api/to/TemplateTO.java
diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
new file mode 100644
index 0000000..e5623ac
--- /dev/null
+++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
@@ -0,0 +1,370 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+
+public class VirtualMachineTO {
+    private long id;
+    private String name;
+    private BootloaderType bootloader;
+    private VirtualMachine.State state;
+    Type type;
+    int cpus;
+
+    /**
+        'speed' is still here since 4.0.X/4.1.X management servers do not support
+         the overcommit feature yet.
+
+         The overcommit feature sends minSpeed and maxSpeed
+
+         So this is here for backwards compatibility with 4.0.X/4.1.X management servers
+         and newer agents.
+    */
+    Integer speed;
+    Integer minSpeed;
+    Integer maxSpeed;
+
+    long minRam;
+    long maxRam;
+    String hostName;
+    String arch;
+    String os;
+    String platformEmulator;
+    String bootArgs;
+    String[] bootupScripts;
+    boolean enableHA;
+    boolean limitCpuUse;
+    boolean enableDynamicallyScaleVm;
+    String vncPassword;
+    String vncAddr;
+    Map<String, String> params;
+    String uuid;
+
+    DiskTO[] disks;
+    NicTO[] nics;
+    GPUDeviceTO gpuDevice;
+    Integer vcpuMaxLimit;
+    List<String[]> vmData = null;
+
+    String configDriveLabel = null;
+    String configDriveIsoRootFolder = null;
+    String configDriveIsoFile = null;
+
+    Double cpuQuotaPercentage = null;
+
+    Map<String, String> guestOsDetails = new HashMap<String, String>();
+    Map<String, String> extraConfig = new HashMap<>();
+
+    public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
+            String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
+        this.id = id;
+        name = instanceName;
+        this.type = type;
+        this.cpus = cpus;
+        this.speed = speed;
+        this.minRam = minRam;
+        this.maxRam = maxRam;
+        this.bootloader = bootloader;
+        this.os = os;
+        this.enableHA = enableHA;
+        this.limitCpuUse = limitCpuUse;
+        this.vncPassword = vncPassword;
+    }
+
+    public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer minSpeed, Integer maxSpeed, long minRam, long maxRam,
+            BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
+        this.id = id;
+        name = instanceName;
+        this.type = type;
+        this.cpus = cpus;
+        this.minSpeed = minSpeed;
+        this.maxSpeed = maxSpeed;
+        this.minRam = minRam;
+        this.maxRam = maxRam;
+        this.bootloader = bootloader;
+        this.os = os;
+        this.enableHA = enableHA;
+        this.limitCpuUse = limitCpuUse;
+        this.vncPassword = vncPassword;
+    }
+
+    protected VirtualMachineTO() {
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public boolean isEnableDynamicallyScaleVm() {
+        return enableDynamicallyScaleVm;
+    }
+
+    public void setEnableDynamicallyScaleVm(boolean enableDynamicallyScaleVm) {
+        this.enableDynamicallyScaleVm = enableDynamicallyScaleVm;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public BootloaderType getBootloader() {
+        return bootloader;
+    }
+
+    public void setBootloader(BootloaderType bootloader) {
+        this.bootloader = bootloader;
+    }
+
+    public VirtualMachine.State getState() {
+        return state;
+    }
+
+    public void setState(VirtualMachine.State state) {
+        this.state = state;
+    }
+
+    public int getCpus() {
+        return cpus;
+    }
+
+    public void setCpus(int cpus) {
+        this.cpus = cpus;
+    }
+
+    public Integer getSpeed() {
+        return speed;
+    }
+
+    public Integer getMinSpeed() {
+        return minSpeed;
+    }
+
+    public Integer getMaxSpeed() {
+        return maxSpeed;
+    }
+
+    public boolean getLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public long getMinRam() {
+        return minRam;
+    }
+
+    public void setRam(long minRam, long maxRam) {
+        this.minRam = minRam;
+        this.maxRam = maxRam;
+    }
+
+    public long getMaxRam() {
+        return maxRam;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public String getArch() {
+        return arch;
+    }
+
+    public void setArch(String arch) {
+        this.arch = arch;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public String getBootArgs() {
+        return bootArgs;
+    }
+
+    public void setBootArgs(String bootArgs) {
+        this.bootArgs = bootArgs;
+    }
+
+    public void setBootArgs(Map<String, String> bootParams) {
+        StringBuilder buf = new StringBuilder();
+        for (Map.Entry<String, String> entry : bootParams.entrySet()) {
+            buf.append(" ").append(entry.getKey()).append("=").append(entry.getValue());
+        }
+        bootArgs = buf.toString();
+    }
+
+    public String[] getBootupScripts() {
+        return bootupScripts;
+    }
+
+    public void setBootupScripts(String[] bootupScripts) {
+        this.bootupScripts = bootupScripts;
+    }
+
+    public DiskTO[] getDisks() {
+        return disks;
+    }
+
+    public void setDisks(DiskTO[] disks) {
+        this.disks = disks;
+    }
+
+    public NicTO[] getNics() {
+        return nics;
+    }
+
+    public void setNics(NicTO[] nics) {
+        this.nics = nics;
+    }
+
+    public String getVncPassword() {
+        return vncPassword;
+    }
+
+    public void setVncPassword(String vncPassword) {
+        this.vncPassword = vncPassword;
+    }
+
+    public String getVncAddr() {
+        return vncAddr;
+    }
+
+    public void setVncAddr(String vncAddr) {
+        this.vncAddr = vncAddr;
+    }
+
+    public Map<String, String> getDetails() {
+        return params;
+    }
+
+    public void setDetails(Map<String, String> params) {
+        this.params = params;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public GPUDeviceTO getGpuDevice() {
+        return gpuDevice;
+    }
+
+    public void setGpuDevice(GPUDeviceTO gpuDevice) {
+        this.gpuDevice = gpuDevice;
+    }
+
+    public String getPlatformEmulator() {
+        return platformEmulator;
+    }
+
+    public void setPlatformEmulator(String platformEmulator) {
+        this.platformEmulator = platformEmulator;
+    }
+
+    public Integer getVcpuMaxLimit() {
+        return vcpuMaxLimit;
+    }
+
+    public void setVcpuMaxLimit(Integer vcpuMaxLimit) {
+        this.vcpuMaxLimit = vcpuMaxLimit;
+    }
+
+    public List<String[]> getVmData() {
+        return vmData;
+    }
+
+    public void setVmData(List<String[]> vmData) {
+        this.vmData = vmData;
+    }
+
+    public String getConfigDriveLabel() {
+        return configDriveLabel;
+    }
+
+    public void setConfigDriveLabel(String configDriveLabel) {
+        this.configDriveLabel = configDriveLabel;
+    }
+
+    public String getConfigDriveIsoRootFolder() {
+        return configDriveIsoRootFolder;
+    }
+
+    public void setConfigDriveIsoRootFolder(String configDriveIsoRootFolder) {
+        this.configDriveIsoRootFolder = configDriveIsoRootFolder;
+    }
+
+    public String getConfigDriveIsoFile() {
+        return configDriveIsoFile;
+    }
+
+    public void setConfigDriveIsoFile(String configDriveIsoFile) {
+        this.configDriveIsoFile = configDriveIsoFile;
+    }
+
+    public Map<String, String> getGuestOsDetails() {
+        return guestOsDetails;
+    }
+
+    public void setGuestOsDetails(Map<String, String> guestOsDetails) {
+        this.guestOsDetails = guestOsDetails;
+    }
+
+    public Double getCpuQuotaPercentage() {
+        return cpuQuotaPercentage;
+    }
+
+    public void setCpuQuotaPercentage(Double cpuQuotaPercentage) {
+        this.cpuQuotaPercentage = cpuQuotaPercentage;
+    }
+
+    public void addExtraConfig(String key, String value) {
+        extraConfig.put(key, value);
+    }
+    public Map<String, String> getExtraConfig() {
+        return extraConfig;
+    }
+}
diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/main/java/com/cloud/agent/api/to/VolumeTO.java
similarity index 100%
rename from api/src/com/cloud/agent/api/to/VolumeTO.java
rename to api/src/main/java/com/cloud/agent/api/to/VolumeTO.java
diff --git a/api/src/com/cloud/agent/manager/allocator/HostAllocator.java b/api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java
similarity index 100%
rename from api/src/com/cloud/agent/manager/allocator/HostAllocator.java
rename to api/src/main/java/com/cloud/agent/manager/allocator/HostAllocator.java
diff --git a/api/src/com/cloud/agent/manager/allocator/PodAllocator.java b/api/src/main/java/com/cloud/agent/manager/allocator/PodAllocator.java
similarity index 100%
rename from api/src/com/cloud/agent/manager/allocator/PodAllocator.java
rename to api/src/main/java/com/cloud/agent/manager/allocator/PodAllocator.java
diff --git a/api/src/main/java/com/cloud/alert/Alert.java b/api/src/main/java/com/cloud/alert/Alert.java
new file mode 100644
index 0000000..d85dca5
--- /dev/null
+++ b/api/src/main/java/com/cloud/alert/Alert.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 com.cloud.alert;
+
+import java.util.Date;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface Alert extends Identity, InternalIdentity {
+    short getType();
+
+    String getSubject();
+
+    Long getPodId();
+
+    long getDataCenterId();
+
+    int getSentCount();
+
+    Date getCreatedDate();
+
+    Date getLastSent();
+
+    Date getResolved();
+
+    boolean getArchived();
+
+    String getName();
+
+    String getContent();
+}
diff --git a/api/src/com/cloud/alert/AlertAdapter.java b/api/src/main/java/com/cloud/alert/AlertAdapter.java
similarity index 100%
rename from api/src/com/cloud/alert/AlertAdapter.java
rename to api/src/main/java/com/cloud/alert/AlertAdapter.java
diff --git a/api/src/com/cloud/api/commands/.gitignore b/api/src/main/java/com/cloud/api/commands/.gitignore
similarity index 100%
rename from api/src/com/cloud/api/commands/.gitignore
rename to api/src/main/java/com/cloud/api/commands/.gitignore
diff --git a/api/src/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java b/api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
similarity index 100%
rename from api/src/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
rename to api/src/main/java/com/cloud/api/commands/ListRecurringSnapshotScheduleCmd.java
diff --git a/api/src/com/cloud/capacity/Capacity.java b/api/src/main/java/com/cloud/capacity/Capacity.java
similarity index 100%
rename from api/src/com/cloud/capacity/Capacity.java
rename to api/src/main/java/com/cloud/capacity/Capacity.java
diff --git a/api/src/com/cloud/capacity/CapacityState.java b/api/src/main/java/com/cloud/capacity/CapacityState.java
similarity index 100%
rename from api/src/com/cloud/capacity/CapacityState.java
rename to api/src/main/java/com/cloud/capacity/CapacityState.java
diff --git a/api/src/com/cloud/configuration/ConfigurationService.java b/api/src/main/java/com/cloud/configuration/ConfigurationService.java
similarity index 100%
rename from api/src/com/cloud/configuration/ConfigurationService.java
rename to api/src/main/java/com/cloud/configuration/ConfigurationService.java
diff --git a/api/src/com/cloud/configuration/Resource.java b/api/src/main/java/com/cloud/configuration/Resource.java
similarity index 100%
rename from api/src/com/cloud/configuration/Resource.java
rename to api/src/main/java/com/cloud/configuration/Resource.java
diff --git a/api/src/com/cloud/configuration/ResourceCount.java b/api/src/main/java/com/cloud/configuration/ResourceCount.java
similarity index 100%
rename from api/src/com/cloud/configuration/ResourceCount.java
rename to api/src/main/java/com/cloud/configuration/ResourceCount.java
diff --git a/api/src/com/cloud/configuration/ResourceLimit.java b/api/src/main/java/com/cloud/configuration/ResourceLimit.java
similarity index 100%
rename from api/src/com/cloud/configuration/ResourceLimit.java
rename to api/src/main/java/com/cloud/configuration/ResourceLimit.java
diff --git a/api/src/com/cloud/consoleproxy/ConsoleProxyAllocator.java b/api/src/main/java/com/cloud/consoleproxy/ConsoleProxyAllocator.java
similarity index 100%
rename from api/src/com/cloud/consoleproxy/ConsoleProxyAllocator.java
rename to api/src/main/java/com/cloud/consoleproxy/ConsoleProxyAllocator.java
diff --git a/api/src/com/cloud/dc/DataCenter.java b/api/src/main/java/com/cloud/dc/DataCenter.java
similarity index 100%
rename from api/src/com/cloud/dc/DataCenter.java
rename to api/src/main/java/com/cloud/dc/DataCenter.java
diff --git a/api/src/com/cloud/dc/DedicatedResources.java b/api/src/main/java/com/cloud/dc/DedicatedResources.java
similarity index 100%
rename from api/src/com/cloud/dc/DedicatedResources.java
rename to api/src/main/java/com/cloud/dc/DedicatedResources.java
diff --git a/api/src/com/cloud/dc/Pod.java b/api/src/main/java/com/cloud/dc/Pod.java
similarity index 100%
rename from api/src/com/cloud/dc/Pod.java
rename to api/src/main/java/com/cloud/dc/Pod.java
diff --git a/api/src/com/cloud/dc/StorageNetworkIpRange.java b/api/src/main/java/com/cloud/dc/StorageNetworkIpRange.java
similarity index 100%
rename from api/src/com/cloud/dc/StorageNetworkIpRange.java
rename to api/src/main/java/com/cloud/dc/StorageNetworkIpRange.java
diff --git a/api/src/com/cloud/dc/Vlan.java b/api/src/main/java/com/cloud/dc/Vlan.java
similarity index 100%
rename from api/src/com/cloud/dc/Vlan.java
rename to api/src/main/java/com/cloud/dc/Vlan.java
diff --git a/api/src/com/cloud/deploy/DataCenterDeployment.java b/api/src/main/java/com/cloud/deploy/DataCenterDeployment.java
similarity index 100%
rename from api/src/com/cloud/deploy/DataCenterDeployment.java
rename to api/src/main/java/com/cloud/deploy/DataCenterDeployment.java
diff --git a/api/src/main/java/com/cloud/deploy/DeployDestination.java b/api/src/main/java/com/cloud/deploy/DeployDestination.java
new file mode 100644
index 0000000..18503fe
--- /dev/null
+++ b/api/src/main/java/com/cloud/deploy/DeployDestination.java
@@ -0,0 +1,163 @@
+// 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.deploy;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.host.Host;
+import com.cloud.org.Cluster;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.utils.NumbersUtil;
+
+public class DeployDestination implements Serializable {
+    private static final long serialVersionUID = 7113840781939014695L;
+
+    DataCenter _dc;
+    Pod _pod;
+    Cluster _cluster;
+    Host _host;
+    Map<Volume, StoragePool> _storage;
+
+    public DataCenter getDataCenter() {
+        return _dc;
+    }
+
+    public Pod getPod() {
+        return _pod;
+    }
+
+    public Cluster getCluster() {
+        return _cluster;
+    }
+
+    public Host getHost() {
+        return _host;
+    }
+
+    public Map<Volume, StoragePool> getStorageForDisks() {
+        return _storage;
+    }
+
+    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host) {
+        _dc = dc;
+        _pod = pod;
+        _cluster = cluster;
+        _host = host;
+    }
+
+    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host, Map<Volume, StoragePool> storage) {
+        this(dc, pod, cluster, host);
+        _storage = storage;
+    }
+
+    public DeployDestination() {
+    }
+
+    @Override
+    public int hashCode() {
+        return NumbersUtil.hash(_host.getId());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof DeployDestination)) {
+            return false;
+        }
+        DeployDestination that = (DeployDestination)obj;
+        if (this._dc == null || that._dc == null) {
+            return false;
+        }
+        if (this._dc.getId() != that._dc.getId()) {
+            return false;
+        }
+        if (this._pod == null || that._pod == null) {
+            return false;
+        }
+        if (this._pod.getId() != that._pod.getId()) {
+            return false;
+        }
+        if (this._cluster == null || that._cluster == null) {
+            return false;
+        }
+        if (this._cluster.getId() != that._cluster.getId()) {
+            return false;
+        }
+        if (this._host == null || that._host == null) {
+            return false;
+        }
+        return this._host.getId() == that._host.getId();
+    }
+
+    @Override
+    public String toString() {
+
+        Long dcId = null;
+        Long podId = null;
+        Long clusterId = null;
+        Long hostId = null;
+
+        if (_dc != null) {
+            dcId = _dc.getId();
+        }
+
+        if (_pod != null) {
+            podId = _pod.getId();
+        }
+
+        if (_cluster != null) {
+            clusterId = _cluster.getId();
+        }
+
+        if (_host != null) {
+            hostId = _host.getId();
+        }
+
+        StringBuilder destination = new StringBuilder("Dest[Zone(Id)-Pod(Id)-Cluster(Id)-Host(Id)-Storage(Volume(Id|Type-->Pool(Id))] : Dest[");
+        destination.append("Zone(").append(dcId).append(")").append("-");
+        destination.append("Pod(").append(podId).append(")").append("-");
+        destination.append("Cluster(").append(clusterId).append(")").append("-");
+        destination.append("Host(").append(hostId).append(")").append("-");
+        destination.append("Storage(");
+        if (_storage != null) {
+            StringBuffer storageBuf = new StringBuffer();
+            //String storageStr = "";
+            for (Volume vol : _storage.keySet()) {
+                if (!storageBuf.toString().equals("")) {
+                    storageBuf.append(storageBuf.toString());
+                    storageBuf.append(", ");
+                }
+                storageBuf.append(storageBuf);
+                storageBuf.append("Volume(");
+                storageBuf.append(vol.getId());
+                storageBuf.append("|");
+                storageBuf.append(vol.getVolumeType().name());
+                storageBuf.append("-->Pool(");
+                storageBuf.append(_storage.get(vol).getId());
+                storageBuf.append(")");
+            }
+            destination.append(storageBuf.toString());
+        }
+        return destination.append(")]").toString();
+    }
+}
diff --git a/api/src/com/cloud/deploy/DeploymentClusterPlanner.java b/api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java
similarity index 100%
rename from api/src/com/cloud/deploy/DeploymentClusterPlanner.java
rename to api/src/main/java/com/cloud/deploy/DeploymentClusterPlanner.java
diff --git a/api/src/com/cloud/deploy/DeploymentPlan.java b/api/src/main/java/com/cloud/deploy/DeploymentPlan.java
similarity index 100%
rename from api/src/com/cloud/deploy/DeploymentPlan.java
rename to api/src/main/java/com/cloud/deploy/DeploymentPlan.java
diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/main/java/com/cloud/deploy/DeploymentPlanner.java
similarity index 100%
rename from api/src/com/cloud/deploy/DeploymentPlanner.java
rename to api/src/main/java/com/cloud/deploy/DeploymentPlanner.java
diff --git a/api/src/com/cloud/deploy/HAPlanner.java b/api/src/main/java/com/cloud/deploy/HAPlanner.java
similarity index 100%
rename from api/src/com/cloud/deploy/HAPlanner.java
rename to api/src/main/java/com/cloud/deploy/HAPlanner.java
diff --git a/api/src/com/cloud/domain/Domain.java b/api/src/main/java/com/cloud/domain/Domain.java
similarity index 100%
rename from api/src/com/cloud/domain/Domain.java
rename to api/src/main/java/com/cloud/domain/Domain.java
diff --git a/api/src/com/cloud/domain/PartOf.java b/api/src/main/java/com/cloud/domain/PartOf.java
similarity index 100%
rename from api/src/com/cloud/domain/PartOf.java
rename to api/src/main/java/com/cloud/domain/PartOf.java
diff --git a/api/src/com/cloud/event/ActionEvent.java b/api/src/main/java/com/cloud/event/ActionEvent.java
similarity index 100%
rename from api/src/com/cloud/event/ActionEvent.java
rename to api/src/main/java/com/cloud/event/ActionEvent.java
diff --git a/api/src/com/cloud/event/ActionEvents.java b/api/src/main/java/com/cloud/event/ActionEvents.java
similarity index 100%
rename from api/src/com/cloud/event/ActionEvents.java
rename to api/src/main/java/com/cloud/event/ActionEvents.java
diff --git a/api/src/com/cloud/event/Event.java b/api/src/main/java/com/cloud/event/Event.java
similarity index 100%
rename from api/src/com/cloud/event/Event.java
rename to api/src/main/java/com/cloud/event/Event.java
diff --git a/api/src/com/cloud/event/EventCategory.java b/api/src/main/java/com/cloud/event/EventCategory.java
similarity index 100%
rename from api/src/com/cloud/event/EventCategory.java
rename to api/src/main/java/com/cloud/event/EventCategory.java
diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
new file mode 100644
index 0000000..f0e6ab6
--- /dev/null
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -0,0 +1,1007 @@
+// 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.event;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.StorageNetworkIpRange;
+import com.cloud.dc.Vlan;
+import com.cloud.domain.Domain;
+import com.cloud.host.Host;
+import com.cloud.network.GuestVlan;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteCustomerGateway;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnGateway;
+import com.cloud.network.as.AutoScaleCounter;
+import com.cloud.network.as.AutoScalePolicy;
+import com.cloud.network.as.AutoScaleVmGroup;
+import com.cloud.network.as.AutoScaleVmProfile;
+import com.cloud.network.as.Condition;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.HealthCheckPolicy;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StickinessPolicy;
+import com.cloud.network.security.SecurityGroup;
+import com.cloud.network.vpc.NetworkACL;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project;
+import com.cloud.server.ResourceTag;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.snapshot.SnapshotPolicy;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.VirtualMachine;
+import org.apache.cloudstack.acl.Role;
+import org.apache.cloudstack.acl.RolePermission;
+import org.apache.cloudstack.annotation.Annotation;
+import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.ha.HAConfig;
+import org.apache.cloudstack.usage.Usage;
+
+public class EventTypes {
+
+    //map of Event and corresponding entity for which Event is applicable
+    private static Map<String, Object> entityEventDetails = null;
+
+    // VM Events
+    public static final String EVENT_VM_CREATE = "VM.CREATE";
+    public static final String EVENT_VM_DESTROY = "VM.DESTROY";
+    public static final String EVENT_VM_START = "VM.START";
+    public static final String EVENT_VM_STOP = "VM.STOP";
+    public static final String EVENT_VM_REBOOT = "VM.REBOOT";
+    public static final String EVENT_VM_UPDATE = "VM.UPDATE";
+    public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
+    public static final String EVENT_VM_DYNAMIC_SCALE = "VM.DYNAMIC.SCALE";
+    public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
+    public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
+    public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
+    public static final String EVENT_VM_MOVE = "VM.MOVE";
+    public static final String EVENT_VM_RESTORE = "VM.RESTORE";
+    public static final String EVENT_VM_EXPUNGE = "VM.EXPUNGE";
+
+    // Domain Router
+    public static final String EVENT_ROUTER_CREATE = "ROUTER.CREATE";
+    public static final String EVENT_ROUTER_DESTROY = "ROUTER.DESTROY";
+    public static final String EVENT_ROUTER_START = "ROUTER.START";
+    public static final String EVENT_ROUTER_STOP = "ROUTER.STOP";
+    public static final String EVENT_ROUTER_REBOOT = "ROUTER.REBOOT";
+    public static final String EVENT_ROUTER_HA = "ROUTER.HA";
+    public static final String EVENT_ROUTER_UPGRADE = "ROUTER.UPGRADE";
+    public static final String EVENT_ROUTER_DIAGNOSTICS = "ROUTER.DIAGNOSTICS";
+
+    // Console proxy
+    public static final String EVENT_PROXY_CREATE = "PROXY.CREATE";
+    public static final String EVENT_PROXY_DESTROY = "PROXY.DESTROY";
+    public static final String EVENT_PROXY_START = "PROXY.START";
+    public static final String EVENT_PROXY_STOP = "PROXY.STOP";
+    public static final String EVENT_PROXY_REBOOT = "PROXY.REBOOT";
+    public static final String EVENT_PROXY_HA = "PROXY.HA";
+    public static final String EVENT_PROXY_DIAGNOSTICS = "PROXY.DIAGNOSTICS";
+
+    // VNC Console Events
+    public static final String EVENT_VNC_CONNECT = "VNC.CONNECT";
+    public static final String EVENT_VNC_DISCONNECT = "VNC.DISCONNECT";
+
+    // Network Events
+    public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN";
+    public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE";
+    public static final String EVENT_NET_IP_UPDATE = "NET.IPUPDATE";
+    public static final String EVENT_PORTABLE_IP_ASSIGN = "PORTABLE.IPASSIGN";
+    public static final String EVENT_PORTABLE_IP_RELEASE = "PORTABLE.IPRELEASE";
+    public static final String EVENT_NET_RULE_ADD = "NET.RULEADD";
+    public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE";
+    public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY";
+    public static final String EVENT_NETWORK_CREATE = "NETWORK.CREATE";
+    public static final String EVENT_NETWORK_DELETE = "NETWORK.DELETE";
+    public static final String EVENT_NETWORK_UPDATE = "NETWORK.UPDATE";
+    public static final String EVENT_NETWORK_MIGRATE = "NETWORK.MIGRATE";
+    public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN";
+    public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
+    public static final String EVENT_FIREWALL_UPDATE = "FIREWALL.UPDATE";
+
+    public static final String EVENT_FIREWALL_EGRESS_OPEN = "FIREWALL.EGRESS.OPEN";
+    public static final String EVENT_FIREWALL_EGRESS_CLOSE = "FIREWALL.EGRESS.CLOSE";
+    public static final String EVENT_FIREWALL_EGRESS_UPDATE = "FIREWALL.EGRESS.UPDATE";
+
+    //NIC Events
+    public static final String EVENT_NIC_CREATE = "NIC.CREATE";
+    public static final String EVENT_NIC_DELETE = "NIC.DELETE";
+    public static final String EVENT_NIC_UPDATE = "NIC.UPDATE";
+    public static final String EVENT_NIC_DETAIL_ADD = "NIC.DETAIL.ADD";
+    public static final String EVENT_NIC_DETAIL_UPDATE = "NIC.DETAIL.UPDATE";
+    public static final String EVENT_NIC_DETAIL_REMOVE = "NIC.DETAIL.REMOVE";
+
+    // Load Balancers
+    public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE";
+    public static final String EVENT_REMOVE_FROM_LOAD_BALANCER_RULE = "LB.REMOVE.FROM.RULE";
+    public static final String EVENT_LOAD_BALANCER_CREATE = "LB.CREATE";
+    public static final String EVENT_LOAD_BALANCER_DELETE = "LB.DELETE";
+    public static final String EVENT_LB_STICKINESSPOLICY_CREATE = "LB.STICKINESSPOLICY.CREATE";
+    public static final String EVENT_LB_STICKINESSPOLICY_UPDATE = "LB.STICKINESSPOLICY.UPDATE";
+    public static final String EVENT_LB_STICKINESSPOLICY_DELETE = "LB.STICKINESSPOLICY.DELETE";
+    public static final String EVENT_LB_HEALTHCHECKPOLICY_CREATE = "LB.HEALTHCHECKPOLICY.CREATE";
+    public static final String EVENT_LB_HEALTHCHECKPOLICY_DELETE = "LB.HEALTHCHECKPOLICY.DELETE";
+    public static final String EVENT_LB_HEALTHCHECKPOLICY_UPDATE = "LB.HEALTHCHECKPOLICY.UPDATE";
+    public static final String EVENT_LOAD_BALANCER_UPDATE = "LB.UPDATE";
+    public static final String EVENT_LB_CERT_UPLOAD = "LB.CERT.UPLOAD";
+    public static final String EVENT_LB_CERT_DELETE = "LB.CERT.DELETE";
+    public static final String EVENT_LB_CERT_ASSIGN = "LB.CERT.ASSIGN";
+    public static final String EVENT_LB_CERT_REMOVE = "LB.CERT.REMOVE";
+
+    // Global Load Balancer rules
+    public static final String EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.ASSIGN";
+    public static final String EVENT_REMOVE_FROM_GLOBAL_LOAD_BALANCER_RULE = "GLOBAL.LB.REMOVE";
+    public static final String EVENT_GLOBAL_LOAD_BALANCER_CREATE = "GLOBAL.LB.CREATE";
+    public static final String EVENT_GLOBAL_LOAD_BALANCER_DELETE = "GLOBAL.LB.DELETE";
+    public static final String EVENT_GLOBAL_LOAD_BALANCER_UPDATE = "GLOBAL.LB.UPDATE";
+
+    // Role events
+    public static final String EVENT_ROLE_CREATE = "ROLE.CREATE";
+    public static final String EVENT_ROLE_UPDATE = "ROLE.UPDATE";
+    public static final String EVENT_ROLE_DELETE = "ROLE.DELETE";
+    public static final String EVENT_ROLE_PERMISSION_CREATE = "ROLE.PERMISSION.CREATE";
+    public static final String EVENT_ROLE_PERMISSION_UPDATE = "ROLE.PERMISSION.UPDATE";
+    public static final String EVENT_ROLE_PERMISSION_DELETE = "ROLE.PERMISSION.DELETE";
+
+    // CA events
+    public static final String EVENT_CA_CERTIFICATE_ISSUE = "CA.CERTIFICATE.ISSUE";
+    public static final String EVENT_CA_CERTIFICATE_REVOKE = "CA.CERTIFICATE.REVOKE";
+    public static final String EVENT_CA_CERTIFICATE_PROVISION = "CA.CERTIFICATE.PROVISION";
+
+    // Account events
+    public static final String EVENT_ACCOUNT_ENABLE = "ACCOUNT.ENABLE";
+    public static final String EVENT_ACCOUNT_DISABLE = "ACCOUNT.DISABLE";
+    public static final String EVENT_ACCOUNT_CREATE = "ACCOUNT.CREATE";
+    public static final String EVENT_ACCOUNT_DELETE = "ACCOUNT.DELETE";
+    public static final String EVENT_ACCOUNT_UPDATE = "ACCOUNT.UPDATE";
+    public static final String EVENT_ACCOUNT_MARK_DEFAULT_ZONE = "ACCOUNT.MARK.DEFAULT.ZONE";
+
+    // UserVO Events
+    public static final String EVENT_USER_LOGIN = "USER.LOGIN";
+    public static final String EVENT_USER_LOGOUT = "USER.LOGOUT";
+    public static final String EVENT_USER_CREATE = "USER.CREATE";
+    public static final String EVENT_USER_DELETE = "USER.DELETE";
+    public static final String EVENT_USER_DISABLE = "USER.DISABLE";
+    public static final String EVENT_USER_MOVE = "USER.MOVE";
+    public static final String EVENT_USER_UPDATE = "USER.UPDATE";
+    public static final String EVENT_USER_ENABLE = "USER.ENABLE";
+    public static final String EVENT_USER_LOCK = "USER.LOCK";
+
+    //registering SSH keypair events
+    public static final String EVENT_REGISTER_SSH_KEYPAIR = "REGISTER.SSH.KEYPAIR";
+
+    //register for user API and secret keys
+    public static final String EVENT_REGISTER_FOR_SECRET_API_KEY = "REGISTER.USER.KEY";
+
+    // Template Events
+    public static final String EVENT_TEMPLATE_CREATE = "TEMPLATE.CREATE";
+    public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE";
+    public static final String EVENT_TEMPLATE_UPDATE = "TEMPLATE.UPDATE";
+    public static final String EVENT_TEMPLATE_DOWNLOAD_START = "TEMPLATE.DOWNLOAD.START";
+    public static final String EVENT_TEMPLATE_DOWNLOAD_SUCCESS = "TEMPLATE.DOWNLOAD.SUCCESS";
+    public static final String EVENT_TEMPLATE_DOWNLOAD_FAILED = "TEMPLATE.DOWNLOAD.FAILED";
+    public static final String EVENT_TEMPLATE_COPY = "TEMPLATE.COPY";
+    public static final String EVENT_TEMPLATE_EXTRACT = "TEMPLATE.EXTRACT";
+    public static final String EVENT_TEMPLATE_UPLOAD = "TEMPLATE.UPLOAD";
+    public static final String EVENT_TEMPLATE_CLEANUP = "TEMPLATE.CLEANUP";
+
+    // Volume Events
+    public static final String EVENT_VOLUME_CREATE = "VOLUME.CREATE";
+    public static final String EVENT_VOLUME_DELETE = "VOLUME.DELETE";
+    public static final String EVENT_VOLUME_ATTACH = "VOLUME.ATTACH";
+    public static final String EVENT_VOLUME_DETACH = "VOLUME.DETACH";
+    public static final String EVENT_VOLUME_EXTRACT = "VOLUME.EXTRACT";
+    public static final String EVENT_VOLUME_UPLOAD = "VOLUME.UPLOAD";
+    public static final String EVENT_VOLUME_MIGRATE = "VOLUME.MIGRATE";
+    public static final String EVENT_VOLUME_RESIZE = "VOLUME.RESIZE";
+    public static final String EVENT_VOLUME_DETAIL_UPDATE = "VOLUME.DETAIL.UPDATE";
+    public static final String EVENT_VOLUME_DETAIL_ADD = "VOLUME.DETAIL.ADD";
+    public static final String EVENT_VOLUME_DETAIL_REMOVE = "VOLUME.DETAIL.REMOVE";
+    public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
+
+    // Domains
+    public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
+    public static final String EVENT_DOMAIN_DELETE = "DOMAIN.DELETE";
+    public static final String EVENT_DOMAIN_UPDATE = "DOMAIN.UPDATE";
+
+    // Snapshots
+    public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE";
+    public static final String EVENT_SNAPSHOT_ON_PRIMARY = "SNAPSHOT.ON_PRIMARY";
+    public static final String EVENT_SNAPSHOT_OFF_PRIMARY = "SNAPSHOT.OFF_PRIMARY";
+    public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE";
+    public static final String EVENT_SNAPSHOT_REVERT = "SNAPSHOT.REVERT";
+    public static final String EVENT_SNAPSHOT_POLICY_CREATE = "SNAPSHOTPOLICY.CREATE";
+    public static final String EVENT_SNAPSHOT_POLICY_UPDATE = "SNAPSHOTPOLICY.UPDATE";
+    public static final String EVENT_SNAPSHOT_POLICY_DELETE = "SNAPSHOTPOLICY.DELETE";
+
+    // ISO
+    public static final String EVENT_ISO_CREATE = "ISO.CREATE";
+    public static final String EVENT_ISO_DELETE = "ISO.DELETE";
+    public static final String EVENT_ISO_COPY = "ISO.COPY";
+    public static final String EVENT_ISO_ATTACH = "ISO.ATTACH";
+    public static final String EVENT_ISO_DETACH = "ISO.DETACH";
+    public static final String EVENT_ISO_EXTRACT = "ISO.EXTRACT";
+    public static final String EVENT_ISO_UPLOAD = "ISO.UPLOAD";
+
+    // SSVM
+    public static final String EVENT_SSVM_CREATE = "SSVM.CREATE";
+    public static final String EVENT_SSVM_DESTROY = "SSVM.DESTROY";
+    public static final String EVENT_SSVM_START = "SSVM.START";
+    public static final String EVENT_SSVM_STOP = "SSVM.STOP";
+    public static final String EVENT_SSVM_REBOOT = "SSVM.REBOOT";
+    public static final String EVENT_SSVM_HA = "SSVM.HA";
+    public static final String EVENT_SSVM_DIAGNOSTICS = "SSVM.DIAGNOSTICS";
+
+    // Service Offerings
+    public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE";
+    public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT";
+    public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE";
+
+    // Disk Offerings
+    public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE";
+    public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT";
+    public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE";
+
+    // Network offerings
+    public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE";
+    public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN";
+    public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT";
+    public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE";
+    public static final String EVENT_NETWORK_OFFERING_DELETE = "NETWORK.OFFERING.DELETE";
+
+    // Pods
+    public static final String EVENT_POD_CREATE = "POD.CREATE";
+    public static final String EVENT_POD_EDIT = "POD.EDIT";
+    public static final String EVENT_POD_DELETE = "POD.DELETE";
+
+    // Zones
+    public static final String EVENT_ZONE_CREATE = "ZONE.CREATE";
+    public static final String EVENT_ZONE_EDIT = "ZONE.EDIT";
+    public static final String EVENT_ZONE_DELETE = "ZONE.DELETE";
+
+    // VLANs/IP ranges
+    public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE";
+    public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE";
+    public static final String EVENT_VLAN_IP_RANGE_DEDICATE = "VLAN.IP.RANGE.DEDICATE";
+    public static final String EVENT_VLAN_IP_RANGE_RELEASE = "VLAN.IP.RANGE.RELEASE";
+
+    public static final String EVENT_MANAGEMENT_IP_RANGE_CREATE = "MANAGEMENT.IP.RANGE.CREATE";
+    public static final String EVENT_MANAGEMENT_IP_RANGE_DELETE = "MANAGEMENT.IP.RANGE.DELETE";
+
+    public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE";
+    public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE";
+    public static final String EVENT_STORAGE_IP_RANGE_UPDATE = "STORAGE.IP.RANGE.UPDATE";
+
+    // Configuration Table
+    public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT";
+
+    // Security Groups
+    public static final String EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS = "SG.AUTH.INGRESS";
+    public static final String EVENT_SECURITY_GROUP_REVOKE_INGRESS = "SG.REVOKE.INGRESS";
+    public static final String EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS = "SG.AUTH.EGRESS";
+    public static final String EVENT_SECURITY_GROUP_REVOKE_EGRESS = "SG.REVOKE.EGRESS";
+    public static final String EVENT_SECURITY_GROUP_CREATE = "SG.CREATE";
+    public static final String EVENT_SECURITY_GROUP_DELETE = "SG.DELETE";
+    public static final String EVENT_SECURITY_GROUP_ASSIGN = "SG.ASSIGN";
+    public static final String EVENT_SECURITY_GROUP_REMOVE = "SG.REMOVE";
+
+    // Host
+    public static final String EVENT_HOST_RECONNECT = "HOST.RECONNECT";
+
+    // Host Out-of-band management
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_ENABLE = "HOST.OOBM.ENABLE";
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_DISABLE = "HOST.OOBM.DISABLE";
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_CONFIGURE = "HOST.OOBM.CONFIGURE";
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_ACTION = "HOST.OOBM.ACTION";
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_CHANGE_PASSWORD = "HOST.OOBM.CHANGEPASSWORD";
+    public static final String EVENT_HOST_OUTOFBAND_MANAGEMENT_POWERSTATE_TRANSITION = "HOST.OOBM.POWERSTATE.TRANSITION";
+
+    // HA
+    public static final String EVENT_HA_RESOURCE_ENABLE = "HA.RESOURCE.ENABLE";
+    public static final String EVENT_HA_RESOURCE_DISABLE = "HA.RESOURCE.DISABLE";
+    public static final String EVENT_HA_RESOURCE_CONFIGURE = "HA.RESOURCE.CONFIGURE";
+    public static final String EVENT_HA_STATE_TRANSITION = "HA.STATE.TRANSITION";
+
+    // Maintenance
+    public static final String EVENT_MAINTENANCE_CANCEL = "MAINT.CANCEL";
+    public static final String EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE = "MAINT.CANCEL.PS";
+    public static final String EVENT_MAINTENANCE_PREPARE = "MAINT.PREPARE";
+    public static final String EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE = "MAINT.PREPARE.PS";
+
+    // Primary storage pool
+    public static final String EVENT_ENABLE_PRIMARY_STORAGE = "ENABLE.PS";
+    public static final String EVENT_DISABLE_PRIMARY_STORAGE = "DISABLE.PS";
+
+    // VPN
+    public static final String EVENT_REMOTE_ACCESS_VPN_CREATE = "VPN.REMOTE.ACCESS.CREATE";
+    public static final String EVENT_REMOTE_ACCESS_VPN_DESTROY = "VPN.REMOTE.ACCESS.DESTROY";
+    public static final String EVENT_REMOTE_ACCESS_VPN_UPDATE = "VPN.REMOTE.ACCESS.UPDATE";
+    public static final String EVENT_VPN_USER_ADD = "VPN.USER.ADD";
+    public static final String EVENT_VPN_USER_REMOVE = "VPN.USER.REMOVE";
+    public static final String EVENT_S2S_VPN_GATEWAY_CREATE = "VPN.S2S.VPN.GATEWAY.CREATE";
+    public static final String EVENT_S2S_VPN_GATEWAY_DELETE = "VPN.S2S.VPN.GATEWAY.DELETE";
+    public static final String EVENT_S2S_VPN_GATEWAY_UPDATE = "VPN.S2S.VPN.GATEWAY.UPDATE";
+    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE";
+    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE";
+    public static final String EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE";
+    public static final String EVENT_S2S_VPN_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE";
+    public static final String EVENT_S2S_VPN_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE";
+    public static final String EVENT_S2S_VPN_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET";
+    public static final String EVENT_S2S_VPN_CONNECTION_UPDATE = "VPN.S2S.CONNECTION.UPDATE";
+
+    // Network
+    public static final String EVENT_NETWORK_RESTART = "NETWORK.RESTART";
+
+    // Custom certificates
+    public static final String EVENT_UPLOAD_CUSTOM_CERTIFICATE = "UPLOAD.CUSTOM.CERTIFICATE";
+
+    // OneToOnenat
+    public static final String EVENT_ENABLE_STATIC_NAT = "STATICNAT.ENABLE";
+    public static final String EVENT_DISABLE_STATIC_NAT = "STATICNAT.DISABLE";
+
+    public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN";
+    public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE";
+
+    // Projects
+    public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE";
+    public static final String EVENT_PROJECT_UPDATE = "PROJECT.UPDATE";
+    public static final String EVENT_PROJECT_DELETE = "PROJECT.DELETE";
+    public static final String EVENT_PROJECT_ACTIVATE = "PROJECT.ACTIVATE";
+    public static final String EVENT_PROJECT_SUSPEND = "PROJECT.SUSPEND";
+    public static final String EVENT_PROJECT_ACCOUNT_ADD = "PROJECT.ACCOUNT.ADD";
+    public static final String EVENT_PROJECT_INVITATION_UPDATE = "PROJECT.INVITATION.UPDATE";
+    public static final String EVENT_PROJECT_INVITATION_REMOVE = "PROJECT.INVITATION.REMOVE";
+    public static final String EVENT_PROJECT_ACCOUNT_REMOVE = "PROJECT.ACCOUNT.REMOVE";
+
+    // Network as a Service
+    public static final String EVENT_NETWORK_ELEMENT_CONFIGURE = "NETWORK.ELEMENT.CONFIGURE";
+
+    // Physical Network Events
+    public static final String EVENT_PHYSICAL_NETWORK_CREATE = "PHYSICAL.NETWORK.CREATE";
+    public static final String EVENT_PHYSICAL_NETWORK_DELETE = "PHYSICAL.NETWORK.DELETE";
+    public static final String EVENT_PHYSICAL_NETWORK_UPDATE = "PHYSICAL.NETWORK.UPDATE";
+
+    // Physical Network Service Provider Events
+    public static final String EVENT_SERVICE_PROVIDER_CREATE = "SERVICE.PROVIDER.CREATE";
+    public static final String EVENT_SERVICE_PROVIDER_DELETE = "SERVICE.PROVIDER.DELETE";
+    public static final String EVENT_SERVICE_PROVIDER_UPDATE = "SERVICE.PROVIDER.UPDATE";
+
+    // Physical Network TrafficType Events
+    public static final String EVENT_TRAFFIC_TYPE_CREATE = "TRAFFIC.TYPE.CREATE";
+    public static final String EVENT_TRAFFIC_TYPE_DELETE = "TRAFFIC.TYPE.DELETE";
+    public static final String EVENT_TRAFFIC_TYPE_UPDATE = "TRAFFIC.TYPE.UPDATE";
+
+    // external network device events
+    public static final String EVENT_EXTERNAL_LB_DEVICE_ADD = "PHYSICAL.LOADBALANCER.ADD";
+    public static final String EVENT_EXTERNAL_LB_DEVICE_DELETE = "PHYSICAL.LOADBALANCER.DELETE";
+    public static final String EVENT_EXTERNAL_LB_DEVICE_CONFIGURE = "PHYSICAL.LOADBALANCER.CONFIGURE";
+
+    // external NCC device events
+    public static final String EVENT_EXTERNAL_NCC_DEVICE_ADD = "PHYSICAL.NCC.ADD";
+    public static final String EVENT_EXTERNAL_NCC_DEVICE_DELETE = "PHYSICAL.NCC.DELETE";
+
+    // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module.
+    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD = "SWITCH.MGMT.ADD";
+    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE = "SWITCH.MGMT.DELETE";
+    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE = "SWITCH.MGMT.CONFIGURE";
+    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE = "SWITCH.MGMT.ENABLE";
+    public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE = "SWITCH.MGMT.DISABLE";
+
+    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_ADD = "PHYSICAL.FIREWALL.ADD";
+    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE = "PHYSICAL.FIREWALL.DELETE";
+    public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE = "PHYSICAL.FIREWALL.CONFIGURE";
+
+    // VPC
+    public static final String EVENT_VPC_CREATE = "VPC.CREATE";
+    public static final String EVENT_VPC_UPDATE = "VPC.UPDATE";
+    public static final String EVENT_VPC_DELETE = "VPC.DELETE";
+    public static final String EVENT_VPC_RESTART = "VPC.RESTART";
+
+    // Network ACL
+    public static final String EVENT_NETWORK_ACL_CREATE = "NETWORK.ACL.CREATE";
+    public static final String EVENT_NETWORK_ACL_DELETE = "NETWORK.ACL.DELETE";
+    public static final String EVENT_NETWORK_ACL_REPLACE = "NETWORK.ACL.REPLACE";
+    public static final String EVENT_NETWORK_ACL_UPDATE = "NETWORK.ACL.UPDATE";
+    public static final String EVENT_NETWORK_ACL_ITEM_CREATE = "NETWORK.ACL.ITEM.CREATE";
+    public static final String EVENT_NETWORK_ACL_ITEM_UPDATE = "NETWORK.ACL.ITEM.UPDATE";
+    public static final String EVENT_NETWORK_ACL_ITEM_DELETE = "NETWORK.ACL.ITEM.DELETE";
+
+    // VPC offerings
+    public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE";
+    public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE";
+    public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE";
+
+    // Private gateway
+    public static final String EVENT_PRIVATE_GATEWAY_CREATE = "PRIVATE.GATEWAY.CREATE";
+    public static final String EVENT_PRIVATE_GATEWAY_DELETE = "PRIVATE.GATEWAY.DELETE";
+
+    // Static routes
+    public static final String EVENT_STATIC_ROUTE_CREATE = "STATIC.ROUTE.CREATE";
+    public static final String EVENT_STATIC_ROUTE_DELETE = "STATIC.ROUTE.DELETE";
+
+    // tag related events
+    public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
+    public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
+
+    // meta data related events
+    public static final String EVENT_RESOURCE_DETAILS_CREATE = "CREATE_RESOURCE_DETAILS";
+    public static final String EVENT_RESOURCE_DETAILS_DELETE = "DELETE_RESOURCE_DETAILS";
+
+    // vm snapshot events
+    public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
+    public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
+    public static final String EVENT_VM_SNAPSHOT_ON_PRIMARY = "VMSNAPSHOT.ON_PRIMARY";
+    public static final String EVENT_VM_SNAPSHOT_OFF_PRIMARY = "VMSNAPSHOT.OFF_PRIMARY";
+    public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
+
+    // external network device events
+    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
+    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE";
+    public static final String EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE = "PHYSICAL.NVPCONTROLLER.CONFIGURE";
+    public static final String EVENT_EXTERNAL_OVS_CONTROLLER_ADD = "PHYSICAL.OVSCONTROLLER.ADD";
+    public static final String EVENT_EXTERNAL_OVS_CONTROLLER_DELETE = "PHYSICAL.OVSCONTROLLER.DELETE";
+
+    // external network mapping events
+    public static final String EVENT_EXTERNAL_VSP_VSD_ADD = "PHYSICAL.NUAGE.VSD.ADD";
+    public static final String EVENT_EXTERNAL_VSP_VSD_UPDATE = "PHYSICAL.NUAGE.VSD.UPDATE";
+    public static final String EVENT_EXTERNAL_VSP_VSD_DELETE = "PHYSICAL.NUAGE.VSD.DELETE";
+    // AutoScale
+    public static final String EVENT_COUNTER_CREATE = "COUNTER.CREATE";
+    public static final String EVENT_COUNTER_DELETE = "COUNTER.DELETE";
+    public static final String EVENT_CONDITION_CREATE = "CONDITION.CREATE";
+    public static final String EVENT_CONDITION_DELETE = "CONDITION.DELETE";
+    public static final String EVENT_AUTOSCALEPOLICY_CREATE = "AUTOSCALEPOLICY.CREATE";
+    public static final String EVENT_AUTOSCALEPOLICY_UPDATE = "AUTOSCALEPOLICY.UPDATE";
+    public static final String EVENT_AUTOSCALEPOLICY_DELETE = "AUTOSCALEPOLICY.DELETE";
+    public static final String EVENT_AUTOSCALEVMPROFILE_CREATE = "AUTOSCALEVMPROFILE.CREATE";
+    public static final String EVENT_AUTOSCALEVMPROFILE_DELETE = "AUTOSCALEVMPROFILE.DELETE";
+    public static final String EVENT_AUTOSCALEVMPROFILE_UPDATE = "AUTOSCALEVMPROFILE.UPDATE";
+    public static final String EVENT_AUTOSCALEVMGROUP_CREATE = "AUTOSCALEVMGROUP.CREATE";
+    public static final String EVENT_AUTOSCALEVMGROUP_DELETE = "AUTOSCALEVMGROUP.DELETE";
+    public static final String EVENT_AUTOSCALEVMGROUP_UPDATE = "AUTOSCALEVMGROUP.UPDATE";
+    public static final String EVENT_AUTOSCALEVMGROUP_ENABLE = "AUTOSCALEVMGROUP.ENABLE";
+    public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DISABLE";
+
+    public static final String EVENT_BAREMETAL_DHCP_SERVER_ADD = "PHYSICAL.DHCP.ADD";
+    public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE";
+    public static final String EVENT_BAREMETAL_PXE_SERVER_ADD = "PHYSICAL.PXE.ADD";
+    public static final String EVENT_BAREMETAL_PXE_SERVER_DELETE = "PHYSICAL.PXE.DELETE";
+    public static final String EVENT_BAREMETAL_RCT_ADD = "BAREMETAL.RCT.ADD";
+    public static final String EVENT_BAREMETAL_RCT_DELETE = "BAREMETAL.RCT.DELETE";
+    public static final String EVENT_BAREMETAL_PROVISION_DONE = "BAREMETAL.PROVISION.DONE";
+
+    public static final String EVENT_AFFINITY_GROUP_CREATE = "AG.CREATE";
+    public static final String EVENT_AFFINITY_GROUP_DELETE = "AG.DELETE";
+    public static final String EVENT_AFFINITY_GROUP_ASSIGN = "AG.ASSIGN";
+    public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
+    public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
+
+    public static final String EVENT_INTERNAL_LB_VM_START = "INTERNALLBVM.START";
+    public static final String EVENT_INTERNAL_LB_VM_STOP = "INTERNALLBVM.STOP";
+
+    public static final String EVENT_HOST_RESERVATION_RELEASE = "HOST.RESERVATION.RELEASE";
+    // Dedicated guest vlan range
+    public static final String EVENT_GUEST_VLAN_RANGE_DEDICATE = "GUESTVLANRANGE.DEDICATE";
+    public static final String EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE = "GUESTVLANRANGE.RELEASE";
+
+    public static final String EVENT_PORTABLE_IP_RANGE_CREATE = "PORTABLE.IP.RANGE.CREATE";
+    public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
+    public static final String EVENT_PORTABLE_IP_TRANSFER = "PORTABLE.IP.TRANSFER";
+
+    // Dedicated Resources
+    public static final String EVENT_DEDICATE_RESOURCE = "DEDICATE.RESOURCE";
+    public static final String EVENT_DEDICATE_RESOURCE_RELEASE = "DEDICATE.RESOURCE.RELEASE";
+
+    public static final String EVENT_CLEANUP_VM_RESERVATION = "VM.RESERVATION.CLEANUP";
+
+    public static final String EVENT_UCS_ASSOCIATED_PROFILE = "UCS.ASSOCIATEPROFILE";
+
+    // Object store migration
+    public static final String EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE = "MIGRATE.PREPARE.SS";
+
+    //Alert generation
+    public static final String ALERT_GENERATE = "ALERT.GENERATE";
+
+    // OpenDaylight
+    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER = "PHYSICAL.ODLCONTROLLER.ADD";
+    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.DELETE";
+    public static final String EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.CONFIGURE";
+
+    //Guest OS related events
+    public static final String EVENT_GUEST_OS_ADD = "GUEST.OS.ADD";
+    public static final String EVENT_GUEST_OS_REMOVE = "GUEST.OS.REMOVE";
+    public static final String EVENT_GUEST_OS_UPDATE = "GUEST.OS.UPDATE";
+    public static final String EVENT_GUEST_OS_MAPPING_ADD = "GUEST.OS.MAPPING.ADD";
+    public static final String EVENT_GUEST_OS_MAPPING_REMOVE = "GUEST.OS.MAPPING.REMOVE";
+    public static final String EVENT_GUEST_OS_MAPPING_UPDATE = "GUEST.OS.MAPPING.UPDATE";
+
+    public static final String EVENT_NIC_SECONDARY_IP_ASSIGN = "NIC.SECONDARY.IP.ASSIGN";
+    public static final String EVENT_NIC_SECONDARY_IP_UNASSIGN = "NIC.SECONDARY.IP.UNASSIGN";
+    public static final String EVENT_NIC_SECONDARY_IP_CONFIGURE = "NIC.SECONDARY.IP.CONFIGURE";
+    public static final String EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH = "EXTERNAL.DHCP.VM.IP.FETCH";
+
+    //Usage related events
+    public static final String EVENT_USAGE_REMOVE_USAGE_RECORDS = "USAGE.REMOVE.USAGE.RECORDS";
+
+    // Netscaler Service Package events
+    public static final String EVENT_NETSCALER_SERVICEPACKAGE_ADD = "NETSCALER.SERVICEPACKAGE.ADD";
+    public static final String EVENT_NETSCALER_SERVICEPACKAGE_DELETE = "NETSCALER.SERVICEPACKAGE.DELETE";
+
+    public static final String EVENT_NETSCALER_VM_START = "NETSCALERVM.START";
+    public static final String EVENT_NETSCALER_VM_STOP = "NETSCALERVM.STOP";
+
+    public static final String EVENT_ANNOTATION_CREATE = "ANNOTATION.CREATE";
+    public static final String EVENT_ANNOTATION_REMOVE = "ANNOTATION.REMOVE";
+
+    public static final String EVENT_TEMPLATE_DIRECT_DOWNLOAD_FAILURE = "TEMPLATE.DIRECT.DOWNLOAD.FAILURE";
+    public static final String EVENT_ISO_DIRECT_DOWNLOAD_FAILURE = "ISO.DIRECT.DOWNLOAD.FAILURE";
+
+    // Diagnostics Events
+    public static final String EVENT_SYSTEM_VM_DIAGNOSTICS = "SYSTEM.VM.DIAGNOSTICS";
+
+    static {
+
+        // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
+
+        entityEventDetails = new HashMap<String, Object>();
+
+        entityEventDetails.put(EVENT_VM_CREATE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_DESTROY, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_START, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_STOP, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class);
+
+        entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_START, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_STOP, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_REBOOT, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class);
+        entityEventDetails.put(EVENT_ROUTER_DIAGNOSTICS, VirtualRouter.class);
+
+        entityEventDetails.put(EVENT_PROXY_CREATE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_DESTROY, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_START, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_STOP, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_REBOOT, VirtualMachine.class);
+        entityEventDetails.put(EVENT_ROUTER_HA, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_HA, VirtualMachine.class);
+        entityEventDetails.put(EVENT_PROXY_DIAGNOSTICS, VirtualMachine.class);
+
+        entityEventDetails.put(EVENT_VNC_CONNECT, "VNC");
+        entityEventDetails.put(EVENT_VNC_DISCONNECT, "VNC");
+
+        // Network Events
+        entityEventDetails.put(EVENT_NETWORK_CREATE, Network.class);
+        entityEventDetails.put(EVENT_NETWORK_DELETE, Network.class);
+        entityEventDetails.put(EVENT_NETWORK_UPDATE, Network.class);
+        entityEventDetails.put(EVENT_NETWORK_RESTART, Network.class);
+        entityEventDetails.put(EVENT_NET_IP_ASSIGN, IpAddress.class);
+        entityEventDetails.put(EVENT_PORTABLE_IP_ASSIGN, IpAddress.class);
+        entityEventDetails.put(EVENT_PORTABLE_IP_RELEASE, IpAddress.class);
+        entityEventDetails.put(EVENT_NET_IP_RELEASE, IpAddress.class);
+        entityEventDetails.put(EVENT_NET_RULE_ADD, FirewallRule.class);
+        entityEventDetails.put(EVENT_NET_RULE_DELETE, FirewallRule.class);
+        entityEventDetails.put(EVENT_NET_RULE_MODIFY, FirewallRule.class);
+        entityEventDetails.put(EVENT_FIREWALL_OPEN, FirewallRule.class);
+        entityEventDetails.put(EVENT_FIREWALL_CLOSE, FirewallRule.class);
+        entityEventDetails.put(EVENT_FIREWALL_EGRESS_OPEN, FirewallRule.class);
+        entityEventDetails.put(EVENT_FIREWALL_EGRESS_CLOSE, FirewallRule.class);
+        entityEventDetails.put(EVENT_FIREWALL_EGRESS_UPDATE, FirewallRule.class);
+
+        // Nic Events
+        entityEventDetails.put(EVENT_NIC_CREATE, Nic.class);
+
+        // Load Balancers
+        entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class);
+        entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, FirewallRule.class);
+        entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class);
+        entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, FirewallRule.class);
+        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, StickinessPolicy.class);
+        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_UPDATE, StickinessPolicy.class);
+        entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, StickinessPolicy.class);
+        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_CREATE, HealthCheckPolicy.class);
+        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_UPDATE, HealthCheckPolicy.class);
+        entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_DELETE, HealthCheckPolicy.class);
+        entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class);
+        entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class);
+        entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class);
+        entityEventDetails.put(EVENT_LB_CERT_ASSIGN, LoadBalancer.class);
+        entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class);
+
+        // Role events
+        entityEventDetails.put(EVENT_ROLE_CREATE, Role.class);
+        entityEventDetails.put(EVENT_ROLE_UPDATE, Role.class);
+        entityEventDetails.put(EVENT_ROLE_DELETE, Role.class);
+        entityEventDetails.put(EVENT_ROLE_PERMISSION_CREATE, RolePermission.class);
+        entityEventDetails.put(EVENT_ROLE_PERMISSION_UPDATE, RolePermission.class);
+        entityEventDetails.put(EVENT_ROLE_PERMISSION_DELETE, RolePermission.class);
+
+        // Account events
+        entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class);
+        entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class);
+        entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class);
+        entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class);
+        entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class);
+        entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class);
+
+        // UserVO Events
+        entityEventDetails.put(EVENT_USER_LOGIN, User.class);
+        entityEventDetails.put(EVENT_USER_LOGOUT, User.class);
+        entityEventDetails.put(EVENT_USER_CREATE, User.class);
+        entityEventDetails.put(EVENT_USER_DELETE, User.class);
+        entityEventDetails.put(EVENT_USER_DISABLE, User.class);
+        entityEventDetails.put(EVENT_USER_UPDATE, User.class);
+        entityEventDetails.put(EVENT_USER_ENABLE, User.class);
+        entityEventDetails.put(EVENT_USER_LOCK, User.class);
+
+        // Template Events
+        entityEventDetails.put(EVENT_TEMPLATE_CREATE, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_DELETE, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_UPDATE, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_START, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_SUCCESS, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_FAILED, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_COPY, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_EXTRACT, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_UPLOAD, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_TEMPLATE_CLEANUP, VirtualMachineTemplate.class);
+
+        // Volume Events
+        entityEventDetails.put(EVENT_VOLUME_CREATE, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_DELETE, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_ATTACH, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_DETACH, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_EXTRACT, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_UPLOAD, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_MIGRATE, Volume.class);
+        entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class);
+
+        // Domains
+        entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class);
+        entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class);
+        entityEventDetails.put(EVENT_DOMAIN_UPDATE, Domain.class);
+
+        // Snapshots
+        entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_ON_PRIMARY, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_OFF_PRIMARY, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, SnapshotPolicy.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, SnapshotPolicy.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, SnapshotPolicy.class);
+
+        // ISO
+        entityEventDetails.put(EVENT_ISO_CREATE, "Iso");
+        entityEventDetails.put(EVENT_ISO_DELETE, "Iso");
+        entityEventDetails.put(EVENT_ISO_COPY, "Iso");
+        entityEventDetails.put(EVENT_ISO_ATTACH, "Iso");
+        entityEventDetails.put(EVENT_ISO_DETACH, "Iso");
+        entityEventDetails.put(EVENT_ISO_EXTRACT, "Iso");
+        entityEventDetails.put(EVENT_ISO_UPLOAD, "Iso");
+
+        // SSVM
+        entityEventDetails.put(EVENT_SSVM_CREATE, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_DESTROY, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_START, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_STOP, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_REBOOT, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_HA, VirtualMachine.class);
+        entityEventDetails.put(EVENT_SSVM_DIAGNOSTICS, VirtualMachine.class);
+
+        // Service Offerings
+        entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class);
+        entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class);
+        entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class);
+
+        // Disk Offerings
+        entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class);
+        entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class);
+        entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class);
+
+        // Network offerings
+        entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class);
+        entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class);
+        entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class);
+        entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class);
+        entityEventDetails.put(EVENT_NETWORK_OFFERING_DELETE, NetworkOffering.class);
+
+        // Pods
+        entityEventDetails.put(EVENT_POD_CREATE, Pod.class);
+        entityEventDetails.put(EVENT_POD_EDIT, Pod.class);
+        entityEventDetails.put(EVENT_POD_DELETE, Pod.class);
+
+        // Zones
+        entityEventDetails.put(EVENT_ZONE_CREATE, DataCenter.class);
+        entityEventDetails.put(EVENT_ZONE_EDIT, DataCenter.class);
+        entityEventDetails.put(EVENT_ZONE_DELETE, DataCenter.class);
+
+        // VLANs/IP ranges
+        entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class);
+        entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE, Vlan.class);
+        entityEventDetails.put(EVENT_VLAN_IP_RANGE_DEDICATE, Vlan.class);
+        entityEventDetails.put(EVENT_VLAN_IP_RANGE_RELEASE, Vlan.class);
+
+        entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_CREATE, Pod.class);
+        entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_DELETE, Pod.class);
+
+        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class);
+        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class);
+        entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class);
+
+        // Configuration Table
+        entityEventDetails.put(EVENT_CONFIGURATION_VALUE_EDIT, Configuration.class);
+
+        // Security Groups
+        entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_INGRESS, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_EGRESS, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_CREATE, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_DELETE, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_ASSIGN, SecurityGroup.class);
+        entityEventDetails.put(EVENT_SECURITY_GROUP_REMOVE, SecurityGroup.class);
+
+        // Host
+        entityEventDetails.put(EVENT_HOST_RECONNECT, Host.class);
+
+        // Host Out-of-band management
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_ENABLE, Host.class);
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_DISABLE, Host.class);
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_CONFIGURE, Host.class);
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_ACTION, Host.class);
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_CHANGE_PASSWORD, Host.class);
+        entityEventDetails.put(EVENT_HOST_OUTOFBAND_MANAGEMENT_POWERSTATE_TRANSITION, Host.class);
+
+        // HA
+        entityEventDetails.put(EVENT_HA_RESOURCE_ENABLE, HAConfig.class);
+        entityEventDetails.put(EVENT_HA_RESOURCE_DISABLE, HAConfig.class);
+        entityEventDetails.put(EVENT_HA_RESOURCE_CONFIGURE, HAConfig.class);
+        entityEventDetails.put(EVENT_HA_STATE_TRANSITION, HAConfig.class);
+
+        // Maintenance
+        entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class);
+        entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class);
+        entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class);
+        entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class);
+
+        // Primary storage pool
+        entityEventDetails.put(EVENT_ENABLE_PRIMARY_STORAGE, StoragePool.class);
+        entityEventDetails.put(EVENT_DISABLE_PRIMARY_STORAGE, StoragePool.class);
+
+        // VPN
+        entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class);
+        entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class);
+        entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class);
+        entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class);
+        entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, Site2SiteVpnGateway.class);
+        entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, Site2SiteVpnGateway.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class);
+        entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class);
+
+        // Custom certificates
+        entityEventDetails.put(EVENT_UPLOAD_CUSTOM_CERTIFICATE, "Certificate");
+
+        // OneToOnenat
+        entityEventDetails.put(EVENT_ENABLE_STATIC_NAT, StaticNat.class);
+        entityEventDetails.put(EVENT_DISABLE_STATIC_NAT, StaticNat.class);
+
+        entityEventDetails.put(EVENT_ZONE_VLAN_ASSIGN, Vlan.class);
+        entityEventDetails.put(EVENT_ZONE_VLAN_RELEASE, Vlan.class);
+
+        // Projects
+        entityEventDetails.put(EVENT_PROJECT_CREATE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_UPDATE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_DELETE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_ACTIVATE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_SUSPEND, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_ACCOUNT_ADD, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_INVITATION_UPDATE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_INVITATION_REMOVE, Project.class);
+        entityEventDetails.put(EVENT_PROJECT_ACCOUNT_REMOVE, Project.class);
+
+        // Network as a Service
+        entityEventDetails.put(EVENT_NETWORK_ELEMENT_CONFIGURE, Network.class);
+
+        // Physical Network Events
+        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_CREATE, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_DELETE, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_PHYSICAL_NETWORK_UPDATE, PhysicalNetwork.class);
+
+        // Physical Network Service Provider Events
+        entityEventDetails.put(EVENT_SERVICE_PROVIDER_CREATE, PhysicalNetworkServiceProvider.class);
+        entityEventDetails.put(EVENT_SERVICE_PROVIDER_DELETE, PhysicalNetworkServiceProvider.class);
+        entityEventDetails.put(EVENT_SERVICE_PROVIDER_UPDATE, PhysicalNetworkServiceProvider.class);
+
+        // Physical Network TrafficType Events
+        entityEventDetails.put(EVENT_TRAFFIC_TYPE_CREATE, PhysicalNetworkTrafficType.class);
+        entityEventDetails.put(EVENT_TRAFFIC_TYPE_DELETE, PhysicalNetworkTrafficType.class);
+        entityEventDetails.put(EVENT_TRAFFIC_TYPE_UPDATE, PhysicalNetworkTrafficType.class);
+
+        // external network device events
+        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_ADD, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_DELETE, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_CONFIGURE, PhysicalNetwork.class);
+
+        // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module.
+        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD, "Nexus1000v");
+        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE, "Nexus1000v");
+        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE, "Nexus1000v");
+        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE, "Nexus1000v");
+        entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE, "Nexus1000v");
+
+        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_ADD, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE, PhysicalNetwork.class);
+        entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE, PhysicalNetwork.class);
+
+        // Network ACL
+        entityEventDetails.put(EVENT_NETWORK_ACL_CREATE, NetworkACL.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_DELETE, NetworkACL.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_REPLACE, NetworkACL.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_UPDATE, NetworkACL.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_CREATE, NetworkACLItem.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_UPDATE, NetworkACLItem.class);
+        entityEventDetails.put(EVENT_NETWORK_ACL_ITEM_DELETE, NetworkACLItem.class);
+
+        // VPC
+        entityEventDetails.put(EVENT_VPC_CREATE, Vpc.class);
+        entityEventDetails.put(EVENT_VPC_UPDATE, Vpc.class);
+        entityEventDetails.put(EVENT_VPC_DELETE, Vpc.class);
+        entityEventDetails.put(EVENT_VPC_RESTART, Vpc.class);
+
+        // VPC offerings
+        entityEventDetails.put(EVENT_VPC_OFFERING_CREATE, Vpc.class);
+        entityEventDetails.put(EVENT_VPC_OFFERING_UPDATE, Vpc.class);
+        entityEventDetails.put(EVENT_VPC_OFFERING_DELETE, Vpc.class);
+
+        // Private gateway
+        entityEventDetails.put(EVENT_PRIVATE_GATEWAY_CREATE, PrivateGateway.class);
+        entityEventDetails.put(EVENT_PRIVATE_GATEWAY_DELETE, PrivateGateway.class);
+
+        // Static routes
+        entityEventDetails.put(EVENT_STATIC_ROUTE_CREATE, StaticRoute.class);
+        entityEventDetails.put(EVENT_STATIC_ROUTE_DELETE, StaticRoute.class);
+
+        // tag related events
+        entityEventDetails.put(EVENT_TAGS_CREATE, ResourceTag.class);
+        entityEventDetails.put(EVENT_TAGS_DELETE, ResourceTag.class);
+
+        // external network device events
+        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_ADD, "NvpController");
+        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_DELETE, "NvpController");
+        entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController");
+
+        // external network mapping events
+        entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_ADD,  "NuageVsp");
+        entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_DELETE,  "NuageVsp");
+
+        // AutoScale
+        entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class);
+        entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class);
+        entityEventDetails.put(EVENT_CONDITION_CREATE, Condition.class);
+        entityEventDetails.put(EVENT_CONDITION_DELETE, Condition.class);
+        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_CREATE, AutoScalePolicy.class);
+        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_UPDATE, AutoScalePolicy.class);
+        entityEventDetails.put(EVENT_AUTOSCALEPOLICY_DELETE, AutoScalePolicy.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_CREATE, AutoScaleVmProfile.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_DELETE, AutoScaleVmProfile.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_UPDATE, AutoScaleVmProfile.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_CREATE, AutoScaleVmGroup.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DELETE, AutoScaleVmGroup.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class);
+        entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class);
+        entityEventDetails.put(EVENT_GUEST_VLAN_RANGE_DEDICATE, GuestVlan.class);
+        entityEventDetails.put(EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, GuestVlan.class);
+
+        // OpenDaylight
+        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER, "OpenDaylightController");
+        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER, "OpenDaylightController");
+        entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER, "OpenDaylightController");
+
+        //Guest OS
+        entityEventDetails.put(EVENT_GUEST_OS_ADD, GuestOS.class);
+        entityEventDetails.put(EVENT_GUEST_OS_REMOVE, GuestOS.class);
+        entityEventDetails.put(EVENT_GUEST_OS_UPDATE, GuestOS.class);
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class);
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class);
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class);
+        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_ASSIGN, NicSecondaryIp.class);
+        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_UNASSIGN, NicSecondaryIp.class);
+        entityEventDetails.put(EVENT_NIC_SECONDARY_IP_CONFIGURE, NicSecondaryIp.class);
+
+        //Usage
+        entityEventDetails.put(EVENT_USAGE_REMOVE_USAGE_RECORDS, Usage.class);
+        // Netscaler Service Packages
+        entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_ADD, "NETSCALER.SERVICEPACKAGE.CREATE");
+        entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_DELETE, "NETSCALER.SERVICEPACKAGE.DELETE");
+
+        entityEventDetails.put(EVENT_ANNOTATION_CREATE, Annotation.class);
+        entityEventDetails.put(EVENT_ANNOTATION_REMOVE, Annotation.class);
+
+        entityEventDetails.put(EVENT_TEMPLATE_DIRECT_DOWNLOAD_FAILURE, VirtualMachineTemplate.class);
+        entityEventDetails.put(EVENT_ISO_DIRECT_DOWNLOAD_FAILURE, "Iso");
+        entityEventDetails.put(EVENT_SYSTEM_VM_DIAGNOSTICS, VirtualMachine.class);
+    }
+
+    public static String getEntityForEvent(String eventName) {
+        Object entityClass = entityEventDetails.get(eventName);
+        if (entityClass == null) {
+            return null;
+        } else if (entityClass instanceof String){
+            return (String)entityClass;
+        } else if (entityClass instanceof Class){
+            String entityClassName = ((Class)entityClass).getName();
+            int index = entityClassName.lastIndexOf(".");
+            String entityName = entityClassName;
+            if (index != -1) {
+                entityName = entityClassName.substring(index + 1);
+            }
+            return entityName;
+        }
+
+        return null;
+    }
+
+    public static Class getEntityClassForEvent(String eventName) {
+        Object clz = entityEventDetails.get(eventName);
+
+        if(clz instanceof Class){
+            return (Class)entityEventDetails.get(eventName);
+        }
+
+        return null;
+    }
+}
diff --git a/api/src/com/cloud/event/UsageEvent.java b/api/src/main/java/com/cloud/event/UsageEvent.java
similarity index 100%
rename from api/src/com/cloud/event/UsageEvent.java
rename to api/src/main/java/com/cloud/event/UsageEvent.java
diff --git a/api/src/com/cloud/exception/AccountLimitException.java b/api/src/main/java/com/cloud/exception/AccountLimitException.java
similarity index 100%
rename from api/src/com/cloud/exception/AccountLimitException.java
rename to api/src/main/java/com/cloud/exception/AccountLimitException.java
diff --git a/api/src/com/cloud/exception/AffinityConflictException.java b/api/src/main/java/com/cloud/exception/AffinityConflictException.java
similarity index 100%
rename from api/src/com/cloud/exception/AffinityConflictException.java
rename to api/src/main/java/com/cloud/exception/AffinityConflictException.java
diff --git a/api/src/com/cloud/exception/AgentControlChannelException.java b/api/src/main/java/com/cloud/exception/AgentControlChannelException.java
similarity index 100%
rename from api/src/com/cloud/exception/AgentControlChannelException.java
rename to api/src/main/java/com/cloud/exception/AgentControlChannelException.java
diff --git a/api/src/com/cloud/exception/AgentUnavailableException.java b/api/src/main/java/com/cloud/exception/AgentUnavailableException.java
similarity index 100%
rename from api/src/com/cloud/exception/AgentUnavailableException.java
rename to api/src/main/java/com/cloud/exception/AgentUnavailableException.java
diff --git a/api/src/com/cloud/exception/CloudAuthenticationException.java b/api/src/main/java/com/cloud/exception/CloudAuthenticationException.java
similarity index 100%
rename from api/src/com/cloud/exception/CloudAuthenticationException.java
rename to api/src/main/java/com/cloud/exception/CloudAuthenticationException.java
diff --git a/api/src/com/cloud/exception/CloudException.java b/api/src/main/java/com/cloud/exception/CloudException.java
similarity index 100%
rename from api/src/com/cloud/exception/CloudException.java
rename to api/src/main/java/com/cloud/exception/CloudException.java
diff --git a/api/src/com/cloud/exception/ConcurrentOperationException.java b/api/src/main/java/com/cloud/exception/ConcurrentOperationException.java
similarity index 100%
rename from api/src/com/cloud/exception/ConcurrentOperationException.java
rename to api/src/main/java/com/cloud/exception/ConcurrentOperationException.java
diff --git a/api/src/com/cloud/exception/ConflictingNetworkSettingsException.java b/api/src/main/java/com/cloud/exception/ConflictingNetworkSettingsException.java
similarity index 100%
rename from api/src/com/cloud/exception/ConflictingNetworkSettingsException.java
rename to api/src/main/java/com/cloud/exception/ConflictingNetworkSettingsException.java
diff --git a/api/src/com/cloud/exception/ConnectionException.java b/api/src/main/java/com/cloud/exception/ConnectionException.java
similarity index 100%
rename from api/src/com/cloud/exception/ConnectionException.java
rename to api/src/main/java/com/cloud/exception/ConnectionException.java
diff --git a/api/src/com/cloud/exception/DiscoveredWithErrorException.java b/api/src/main/java/com/cloud/exception/DiscoveredWithErrorException.java
similarity index 100%
rename from api/src/com/cloud/exception/DiscoveredWithErrorException.java
rename to api/src/main/java/com/cloud/exception/DiscoveredWithErrorException.java
diff --git a/api/src/com/cloud/exception/DiscoveryException.java b/api/src/main/java/com/cloud/exception/DiscoveryException.java
similarity index 100%
rename from api/src/com/cloud/exception/DiscoveryException.java
rename to api/src/main/java/com/cloud/exception/DiscoveryException.java
diff --git a/api/src/com/cloud/exception/HAStateException.java b/api/src/main/java/com/cloud/exception/HAStateException.java
similarity index 100%
rename from api/src/com/cloud/exception/HAStateException.java
rename to api/src/main/java/com/cloud/exception/HAStateException.java
diff --git a/api/src/com/cloud/exception/InsufficientAddressCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientAddressCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientAddressCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientAddressCapacityException.java
diff --git a/api/src/com/cloud/exception/InsufficientCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientCapacityException.java
diff --git a/api/src/com/cloud/exception/InsufficientNetworkCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientNetworkCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientNetworkCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientNetworkCapacityException.java
diff --git a/api/src/com/cloud/exception/InsufficientServerCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientServerCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientServerCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientServerCapacityException.java
diff --git a/api/src/com/cloud/exception/InsufficientStorageCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientStorageCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientStorageCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientStorageCapacityException.java
diff --git a/api/src/com/cloud/exception/InsufficientVirtualNetworkCapacityException.java b/api/src/main/java/com/cloud/exception/InsufficientVirtualNetworkCapacityException.java
similarity index 100%
rename from api/src/com/cloud/exception/InsufficientVirtualNetworkCapacityException.java
rename to api/src/main/java/com/cloud/exception/InsufficientVirtualNetworkCapacityException.java
diff --git a/api/src/com/cloud/exception/InternalErrorException.java b/api/src/main/java/com/cloud/exception/InternalErrorException.java
similarity index 100%
rename from api/src/com/cloud/exception/InternalErrorException.java
rename to api/src/main/java/com/cloud/exception/InternalErrorException.java
diff --git a/api/src/com/cloud/exception/InvalidParameterValueException.java b/api/src/main/java/com/cloud/exception/InvalidParameterValueException.java
similarity index 100%
rename from api/src/com/cloud/exception/InvalidParameterValueException.java
rename to api/src/main/java/com/cloud/exception/InvalidParameterValueException.java
diff --git a/api/src/com/cloud/exception/ManagementServerException.java b/api/src/main/java/com/cloud/exception/ManagementServerException.java
similarity index 100%
rename from api/src/com/cloud/exception/ManagementServerException.java
rename to api/src/main/java/com/cloud/exception/ManagementServerException.java
diff --git a/api/src/com/cloud/exception/NetworkRuleConflictException.java b/api/src/main/java/com/cloud/exception/NetworkRuleConflictException.java
similarity index 100%
rename from api/src/com/cloud/exception/NetworkRuleConflictException.java
rename to api/src/main/java/com/cloud/exception/NetworkRuleConflictException.java
diff --git a/api/src/com/cloud/exception/OperationTimedoutException.java b/api/src/main/java/com/cloud/exception/OperationTimedoutException.java
similarity index 100%
rename from api/src/com/cloud/exception/OperationTimedoutException.java
rename to api/src/main/java/com/cloud/exception/OperationTimedoutException.java
diff --git a/api/src/com/cloud/exception/PermissionDeniedException.java b/api/src/main/java/com/cloud/exception/PermissionDeniedException.java
similarity index 100%
rename from api/src/com/cloud/exception/PermissionDeniedException.java
rename to api/src/main/java/com/cloud/exception/PermissionDeniedException.java
diff --git a/api/src/com/cloud/exception/RequestLimitException.java b/api/src/main/java/com/cloud/exception/RequestLimitException.java
similarity index 100%
rename from api/src/com/cloud/exception/RequestLimitException.java
rename to api/src/main/java/com/cloud/exception/RequestLimitException.java
diff --git a/api/src/com/cloud/exception/ResourceAllocationException.java b/api/src/main/java/com/cloud/exception/ResourceAllocationException.java
similarity index 100%
rename from api/src/com/cloud/exception/ResourceAllocationException.java
rename to api/src/main/java/com/cloud/exception/ResourceAllocationException.java
diff --git a/api/src/com/cloud/exception/ResourceInUseException.java b/api/src/main/java/com/cloud/exception/ResourceInUseException.java
similarity index 100%
rename from api/src/com/cloud/exception/ResourceInUseException.java
rename to api/src/main/java/com/cloud/exception/ResourceInUseException.java
diff --git a/api/src/com/cloud/exception/ResourceUnavailableException.java b/api/src/main/java/com/cloud/exception/ResourceUnavailableException.java
similarity index 100%
rename from api/src/com/cloud/exception/ResourceUnavailableException.java
rename to api/src/main/java/com/cloud/exception/ResourceUnavailableException.java
diff --git a/api/src/com/cloud/exception/StorageConflictException.java b/api/src/main/java/com/cloud/exception/StorageConflictException.java
similarity index 100%
rename from api/src/com/cloud/exception/StorageConflictException.java
rename to api/src/main/java/com/cloud/exception/StorageConflictException.java
diff --git a/api/src/com/cloud/exception/StorageUnavailableException.java b/api/src/main/java/com/cloud/exception/StorageUnavailableException.java
similarity index 100%
rename from api/src/com/cloud/exception/StorageUnavailableException.java
rename to api/src/main/java/com/cloud/exception/StorageUnavailableException.java
diff --git a/api/src/com/cloud/exception/UnavailableCommandException.java b/api/src/main/java/com/cloud/exception/UnavailableCommandException.java
similarity index 100%
rename from api/src/com/cloud/exception/UnavailableCommandException.java
rename to api/src/main/java/com/cloud/exception/UnavailableCommandException.java
diff --git a/api/src/com/cloud/exception/UnsupportedServiceException.java b/api/src/main/java/com/cloud/exception/UnsupportedServiceException.java
similarity index 100%
rename from api/src/com/cloud/exception/UnsupportedServiceException.java
rename to api/src/main/java/com/cloud/exception/UnsupportedServiceException.java
diff --git a/api/src/com/cloud/exception/VirtualMachineMigrationException.java b/api/src/main/java/com/cloud/exception/VirtualMachineMigrationException.java
similarity index 100%
rename from api/src/com/cloud/exception/VirtualMachineMigrationException.java
rename to api/src/main/java/com/cloud/exception/VirtualMachineMigrationException.java
diff --git a/api/src/com/cloud/gpu/GPU.java b/api/src/main/java/com/cloud/gpu/GPU.java
similarity index 100%
rename from api/src/com/cloud/gpu/GPU.java
rename to api/src/main/java/com/cloud/gpu/GPU.java
diff --git a/api/src/com/cloud/ha/FenceBuilder.java b/api/src/main/java/com/cloud/ha/FenceBuilder.java
similarity index 100%
rename from api/src/com/cloud/ha/FenceBuilder.java
rename to api/src/main/java/com/cloud/ha/FenceBuilder.java
diff --git a/api/src/com/cloud/ha/Investigator.java b/api/src/main/java/com/cloud/ha/Investigator.java
similarity index 100%
rename from api/src/com/cloud/ha/Investigator.java
rename to api/src/main/java/com/cloud/ha/Investigator.java
diff --git a/api/src/com/cloud/host/Host.java b/api/src/main/java/com/cloud/host/Host.java
similarity index 100%
rename from api/src/com/cloud/host/Host.java
rename to api/src/main/java/com/cloud/host/Host.java
diff --git a/api/src/com/cloud/host/HostEnvironment.java b/api/src/main/java/com/cloud/host/HostEnvironment.java
similarity index 100%
rename from api/src/com/cloud/host/HostEnvironment.java
rename to api/src/main/java/com/cloud/host/HostEnvironment.java
diff --git a/api/src/com/cloud/host/HostStats.java b/api/src/main/java/com/cloud/host/HostStats.java
similarity index 100%
rename from api/src/com/cloud/host/HostStats.java
rename to api/src/main/java/com/cloud/host/HostStats.java
diff --git a/api/src/com/cloud/host/Status.java b/api/src/main/java/com/cloud/host/Status.java
similarity index 100%
rename from api/src/com/cloud/host/Status.java
rename to api/src/main/java/com/cloud/host/Status.java
diff --git a/api/src/com/cloud/hypervisor/Hypervisor.java b/api/src/main/java/com/cloud/hypervisor/Hypervisor.java
similarity index 100%
rename from api/src/com/cloud/hypervisor/Hypervisor.java
rename to api/src/main/java/com/cloud/hypervisor/Hypervisor.java
diff --git a/api/src/com/cloud/hypervisor/HypervisorCapabilities.java b/api/src/main/java/com/cloud/hypervisor/HypervisorCapabilities.java
similarity index 100%
rename from api/src/com/cloud/hypervisor/HypervisorCapabilities.java
rename to api/src/main/java/com/cloud/hypervisor/HypervisorCapabilities.java
diff --git a/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java b/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
new file mode 100644
index 0000000..da2c7d0
--- /dev/null
+++ b/api/src/main/java/com/cloud/hypervisor/HypervisorGuru.java
@@ -0,0 +1,97 @@
+// 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;
+
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.storage.StoragePool;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Adapter;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface HypervisorGuru extends Adapter {
+    ConfigKey<Boolean> VmwareFullClone = new ConfigKey<Boolean>("Advanced", Boolean.class, "vmware.create.full.clone", "true",
+            "If set to true, creates guest VMs as full clones on ESX", false);
+    HypervisorType getHypervisorType();
+
+    /**
+     * Convert from a virtual machine to the
+     * virtual machine that the hypervisor expects.
+     * @param vm
+     * @return
+     */
+    VirtualMachineTO implement(VirtualMachineProfile vm);
+
+    /**
+     * Gives hypervisor guru opportunity to decide if certain commands need to be delegated to another host, for instance, we may have the opportunity to change from a system VM (is considered a host) to a real host to execute commands.
+     *
+     * @param hostId original hypervisor host
+     * @param cmd command that is going to be sent, hypervisor guru usually needs to register various context objects into the command object
+     *
+     * @return delegated host id if the command will be delegated
+     */
+    Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd);
+
+    /**
+     *  @return true if VM can be migrated independently with CloudStack, and therefore CloudStack needs to track and reflect host change
+     *  into CloudStack database, false if CloudStack enforces VM sync logic
+     *
+     */
+    boolean trackVmHostChange();
+
+    /**
+     * @param profile
+     * @return
+     */
+    NicTO toNicTO(NicProfile profile);
+
+    /**
+     * Give hypervisor guru opportunity to decide if certain command needs to be done after expunge VM from DB
+     * @param vm
+     * @return a list of Commands
+     */
+    List<Command> finalizeExpunge(VirtualMachine vm);
+
+    /**
+     * Give the hypervisor guru the opportinity to decide if additional clean is
+     * required for nics before expunging the VM
+     *
+     */
+    List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics);
+
+    List<Command> finalizeExpungeVolumes(VirtualMachine vm);
+
+    Map<String, String> getClusterSettings(long vmId);
+
+    /**
+     * Will generate commands to migrate a vm to a pool. For now this will only work for stopped VMs on Vmware.
+     *
+     * @param vm the stopped vm to migrate
+     * @param destination the primary storage pool to migrate to
+     * @return a list of commands to perform for a successful migration
+     */
+    List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination);
+}
diff --git a/api/src/com/cloud/info/ConsoleProxyLoadInfo.java b/api/src/main/java/com/cloud/info/ConsoleProxyLoadInfo.java
similarity index 100%
rename from api/src/com/cloud/info/ConsoleProxyLoadInfo.java
rename to api/src/main/java/com/cloud/info/ConsoleProxyLoadInfo.java
diff --git a/api/src/com/cloud/info/RunningHostCountInfo.java b/api/src/main/java/com/cloud/info/RunningHostCountInfo.java
similarity index 100%
rename from api/src/com/cloud/info/RunningHostCountInfo.java
rename to api/src/main/java/com/cloud/info/RunningHostCountInfo.java
diff --git a/api/src/com/cloud/network/GuestVlan.java b/api/src/main/java/com/cloud/network/GuestVlan.java
similarity index 100%
rename from api/src/com/cloud/network/GuestVlan.java
rename to api/src/main/java/com/cloud/network/GuestVlan.java
diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/main/java/com/cloud/network/IpAddress.java
similarity index 100%
rename from api/src/com/cloud/network/IpAddress.java
rename to api/src/main/java/com/cloud/network/IpAddress.java
diff --git a/api/src/com/cloud/network/MonitoringService.java b/api/src/main/java/com/cloud/network/MonitoringService.java
similarity index 100%
rename from api/src/com/cloud/network/MonitoringService.java
rename to api/src/main/java/com/cloud/network/MonitoringService.java
diff --git a/api/src/com/cloud/network/Network.java b/api/src/main/java/com/cloud/network/Network.java
similarity index 100%
rename from api/src/com/cloud/network/Network.java
rename to api/src/main/java/com/cloud/network/Network.java
diff --git a/api/src/com/cloud/network/NetworkMigrationResponder.java b/api/src/main/java/com/cloud/network/NetworkMigrationResponder.java
similarity index 100%
rename from api/src/com/cloud/network/NetworkMigrationResponder.java
rename to api/src/main/java/com/cloud/network/NetworkMigrationResponder.java
diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java
new file mode 100644
index 0000000..002271a
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/NetworkModel.java
@@ -0,0 +1,320 @@
+// 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.network;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.cloud.dc.Vlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.user.Account;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+/**
+ * The NetworkModel presents a read-only view into the Network data such as L2 networks,
+ * Nics, PublicIps, NetworkOfferings, traffic labels, physical networks and the like
+ * The idea is that only the orchestration core should be able to modify the data, while other
+ * participants in the orchestration can use this interface to query the data.
+ */
+public interface NetworkModel {
+    String METATDATA_DIR = "metadata";
+    String USERDATA_DIR = "userdata";
+    String USERDATA_FILE = "user_data";
+    String PASSWORD_DIR = "password";
+    String PASSWORD_FILE = "vm_password";
+    String PASSWORD_CHECKSUM_FILE = "vm-password-md5checksum";
+    String SERVICE_OFFERING_FILE = "service-offering";
+    String AVAILABILITY_ZONE_FILE = "availability-zone";
+    String LOCAL_HOSTNAME_FILE = "local-hostname";
+    String LOCAL_IPV4_FILE = "local-ipv4";
+    String PUBLIC_HOSTNAME_FILE = "public-hostname";
+    String PUBLIC_IPV4_FILE = "public-ipv4";
+    String INSTANCE_ID_FILE = "instance-id";
+    String VM_ID_FILE = "vm-id";
+    String PUBLIC_KEYS_FILE = "public-keys";
+    String CLOUD_IDENTIFIER_FILE = "cloud-identifier";
+    int CONFIGDATA_DIR = 0;
+    int CONFIGDATA_FILE = 1;
+    int CONFIGDATA_CONTENT = 2;
+    ImmutableMap<String, String> openStackFileMapping = ImmutableMap.of(
+            AVAILABILITY_ZONE_FILE, "availability_zone",
+            LOCAL_HOSTNAME_FILE, "hostname",
+            VM_ID_FILE, "uuid",
+            PUBLIC_HOSTNAME_FILE, "name"
+    );
+
+    static final ConfigKey<Integer> MACIdentifier = new ConfigKey<Integer>("Advanced",Integer.class, "mac.identifier", "0",
+            "This value will be used while generating the mac addresses for isolated and shared networks. The hexadecimal equivalent value will be present at the 2nd octet of the mac address. Default value is null which means this feature is disabled.Its scope is global.", true, ConfigKey.Scope.Global);
+
+    /**
+     * Lists IP addresses that belong to VirtualNetwork VLANs
+     *
+     * @param accountId
+     *            - account that the IP address should belong to
+     * @param associatedNetworkId
+     *            TODO
+     * @param sourceNat
+     *            - (optional) true if the IP address should be a source NAT address
+     * @return - list of IP addresses
+     */
+    List<? extends IpAddress> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat);
+
+    List<? extends IpAddress> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat);
+
+    List<? extends NetworkOffering> getSystemAccountNetworkOfferings(String... offeringNames);
+
+    List<? extends Nic> getNics(long vmId);
+
+    String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
+
+    PublicIpAddress getPublicIpAddress(long ipAddressId);
+
+    List<? extends Vlan> listPodVlans(long podId);
+
+    List<? extends Network> listNetworksUsedByVm(long vmId, boolean isSystem);
+
+    Nic getNicInNetwork(long vmId, long networkId);
+
+    List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type);
+
+    Network getDefaultNetworkForVm(long vmId);
+
+    Nic getDefaultNic(long vmId);
+
+    UserDataServiceProvider getUserDataUpdateProvider(Network network);
+
+    boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId);
+
+    Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service);
+
+    boolean isSharedNetworkWithoutServices(long networkId);
+
+    boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services);
+
+    Network getNetworkWithSGWithFreeIPs(Long zoneId);
+
+    Network getNetworkWithSecurityGroupEnabled(Long zoneId);
+
+    String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId);
+
+    List<? extends Network> listNetworksForAccount(long accountId, long zoneId, Network.GuestType type);
+
+    List<? extends Network> listAllNetworksInAllZonesByType(Network.GuestType type);
+
+    String getStartIpAddress(long networkId);
+
+    String getIpInNetwork(long vmId, long networkId);
+
+    String getIpInNetworkIncludingRemoved(long vmId, long networkId);
+
+    Long getPodIdForVlan(long vlanDbId);
+
+    List<Long> listNetworkOfferingsForUpgrade(long networkId);
+
+    boolean isSecurityGroupSupportedInNetwork(Network network);
+
+    boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider);
+
+    boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName);
+
+    String getNetworkTag(HypervisorType hType, Network network);
+
+    List<Service> getElementServices(Provider provider);
+
+    boolean canElementEnableIndividualServices(Provider provider);
+
+    boolean areServicesSupportedInNetwork(long networkId, Service... services);
+
+    boolean isNetworkSystem(Network network);
+
+    Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service);
+
+    Long getPhysicalNetworkId(Network network);
+
+    boolean getAllowSubdomainAccessGlobal();
+
+    boolean isProviderForNetwork(Provider provider, long networkId);
+
+    boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId);
+
+    void canProviderSupportServices(Map<Provider, Set<Service>> providersMap);
+
+    List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType);
+
+    boolean canAddDefaultSecurityGroup();
+
+    List<Service> listNetworkOfferingServices(long networkOfferingId);
+
+    boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services);
+
+    Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall);
+
+    Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices);
+
+    boolean checkIpForService(IpAddress ip, Service service, Long networkId);
+
+    boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap);
+
+    void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue);
+
+    Provider getDefaultUniqueProviderForService(String serviceName);
+
+    void checkNetworkPermissions(Account owner, Network network);
+
+    String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType);
+
+    String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType);
+
+    String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware);
+
+    String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware);
+
+    /**
+     * @param providerName
+     * @return
+     */
+    NetworkElement getElementImplementingProvider(String providerName);
+
+    /**
+     * @param accountId
+     * @param zoneId
+     * @return
+     */
+    String getAccountNetworkDomain(long accountId, long zoneId);
+
+    /**
+     * @param ntwkOffId
+     * @return
+     */
+    List<Provider> getNtwkOffDistinctProviders(long ntwkOffId);
+
+    /**
+     * @param accountId
+     * @param dcId
+     * @param sourceNat
+     * @return
+     */
+    List<? extends IpAddress> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat);
+
+    /**
+     * @param zoneId
+     * @param trafficType
+     * @return
+     */
+    List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType);
+
+    /**
+     * @param ntwkId
+     * @return
+     */
+    boolean isPrivateGateway(long ntwkId);
+
+    Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId);
+
+    Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType);
+
+    Long getDedicatedNetworkDomain(long networkId);
+
+    Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId);
+
+    List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName);
+
+    List<? extends Network> listNetworksByVpc(long vpcId);
+
+    boolean canUseForDeploy(Network network);
+
+    Network getExclusiveGuestNetwork(long zoneId);
+
+    long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType);
+
+    Integer getNetworkRate(long networkId, Long vmId);
+
+    boolean isVmPartOfNetwork(long vmId, long ntwkId);
+
+    PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType);
+
+    Network getNetwork(long networkId);
+
+    IpAddress getIp(long sourceIpAddressId);
+
+    boolean isNetworkAvailableInDomain(long networkId, long domainId);
+
+    NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri);
+
+    Set<Long> getAvailableIps(Network network, String requestedIp);
+
+    String getDomainNetworkDomain(long domainId, long zoneId);
+
+    PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork);
+
+    boolean isNetworkInlineMode(Network network);
+
+    boolean areThereIPv6AddressAvailableInNetwork(long networkId);
+
+    boolean isIP6AddressAvailableInVlan(long vlanId);
+
+    void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException;
+
+    void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException;
+
+    String getStartIpv6Address(long id);
+
+    boolean isProviderEnabledInZone(long zoneId, String provider);
+
+    Nic getPlaceholderNicForRouter(Network network, Long podId);
+
+    IpAddress getPublicIpAddress(String ipAddress, long zoneId);
+
+    List<String> getUsedIpsInNetwork(Network network);
+
+    Map<Detail, String> getNtwkOffDetails(long offId);
+
+    Networks.IsolationType[] listNetworkIsolationMethods();
+
+    Nic getNicInNetworkIncludingRemoved(long vmId, long networkId);
+
+    boolean getExecuteInSeqNtwkElmtCmd();
+
+    boolean isNetworkReadyForGc(long networkId);
+
+    boolean getNetworkEgressDefaultPolicy(Long networkId);
+
+    List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
+                                  String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows);
+
+    String getValidNetworkCidr(Network guestNetwork);
+
+}
diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/main/java/com/cloud/network/NetworkProfile.java
similarity index 100%
rename from api/src/com/cloud/network/NetworkProfile.java
rename to api/src/main/java/com/cloud/network/NetworkProfile.java
diff --git a/api/src/com/cloud/network/NetworkRuleApplier.java b/api/src/main/java/com/cloud/network/NetworkRuleApplier.java
similarity index 100%
rename from api/src/com/cloud/network/NetworkRuleApplier.java
rename to api/src/main/java/com/cloud/network/NetworkRuleApplier.java
diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java
new file mode 100644
index 0000000..aa33def
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/NetworkService.java
@@ -0,0 +1,207 @@
+// 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.network;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
+import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+
+/**
+ * The NetworkService interface is the "public" api to entities that make requests to the orchestration engine
+ * Such entities are usually the admin and end-user API.
+ *
+ */
+public interface NetworkService {
+
+    List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner);
+
+    IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp) throws ResourceAllocationException, InsufficientAddressCapacityException,
+        ConcurrentOperationException;
+
+    boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
+
+    IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
+        InsufficientAddressCapacityException, ConcurrentOperationException;
+
+    boolean releasePortableIpAddress(long ipAddressId);
+
+    Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException;
+
+    Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd);
+
+    boolean deleteNetwork(long networkId, boolean forced);
+
+    boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
+
+    int getActiveNicsInNetwork(long networkId);
+
+    Network getNetwork(long networkId);
+
+    Network getNetwork(String networkUuid);
+
+    IpAddress getIp(long id);
+
+    Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId,
+        Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID, boolean updateInSequence, boolean forced);
+
+    /**
+     * Migrate a network from one physical network to another physical network
+     * @param networkId of the network that needs to be migrated
+     * @param networkOfferingId new network offering id for the network
+     * @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
+     * @return the migrated network
+     */
+    Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume);
+
+    /**
+     * Migrate a vpc from on physical network to another physical network
+     * @param vpcId the id of the vpc that needs to be migrated
+     * @param vpcNetworkofferingId the new vpc offering id
+     * @param resume if previous migration failed try to resume of just fail directly because anomaly is detected
+     * @return the migrated vpc
+     */
+    Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume);
+
+    PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange, Long domainId,
+        List<String> tags, String name);
+
+    Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name);
+
+    PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state);
+
+    boolean deletePhysicalNetwork(Long id);
+
+    List<? extends Service> listNetworkServices(String providerName);
+
+    PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId,
+        List<String> enabledServices);
+
+    Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex,
+        Long pageSize);
+
+    PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List<String> enabledServices);
+
+    boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException;
+
+    PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId);
+
+    PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId);
+
+    PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId);
+
+    PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId);
+
+    long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType);
+
+    PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
+        String simulatorLabel, String vlan, String hypervLabel, String ovm3label);
+
+    PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id);
+
+    PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3label);
+
+    boolean deletePhysicalNetworkTrafficType(Long id);
+
+    GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd);
+
+    Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd);
+
+    boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId);
+
+    Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId);
+
+    Network getExclusiveGuestNetwork(long zoneId);
+
+    List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd);
+
+    List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner);
+
+    IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException,
+        ConcurrentOperationException;
+
+    /**
+     *
+     * @param networkName
+     * @param displayText
+     * @param physicalNetworkId
+     * @param broadcastUri TODO set the guru name based on the broadcastUri?
+     * @param startIp
+     * @param endIP TODO
+     * @param gateway
+     * @param netmask
+     * @param networkOwnerId
+     * @param vpcId TODO
+     * @param sourceNat
+     * @return
+     * @throws InsufficientCapacityException
+     * @throws ConcurrentOperationException
+     * @throws ResourceAllocationException
+     */
+    Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String broadcastUri, String startIp, String endIP, String gateway,
+        String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException,
+        InsufficientCapacityException;
+
+    /**
+     * Requests an IP address for the guest NIC
+     */
+    NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair) throws InsufficientAddressCapacityException;
+
+    boolean releaseSecondaryIpFromNic(long ipAddressId);
+
+    /**
+     * lists the NIC information
+     */
+    List<? extends Nic> listNics(ListNicsCmd listNicsCmd);
+
+    Map<Network.Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service);
+
+    IpAddress updateIP(Long id, String customId, Boolean displayIp);
+
+    boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled);
+
+    List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd);
+
+    AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException;
+
+    boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException;
+}
diff --git a/api/src/com/cloud/network/NetworkUsageService.java b/api/src/main/java/com/cloud/network/NetworkUsageService.java
similarity index 100%
rename from api/src/com/cloud/network/NetworkUsageService.java
rename to api/src/main/java/com/cloud/network/NetworkUsageService.java
diff --git a/api/src/com/cloud/network/Networks.java b/api/src/main/java/com/cloud/network/Networks.java
similarity index 100%
rename from api/src/com/cloud/network/Networks.java
rename to api/src/main/java/com/cloud/network/Networks.java
diff --git a/api/src/com/cloud/network/OvsProvider.java b/api/src/main/java/com/cloud/network/OvsProvider.java
similarity index 100%
rename from api/src/com/cloud/network/OvsProvider.java
rename to api/src/main/java/com/cloud/network/OvsProvider.java
diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/main/java/com/cloud/network/PhysicalNetwork.java
similarity index 100%
rename from api/src/com/cloud/network/PhysicalNetwork.java
rename to api/src/main/java/com/cloud/network/PhysicalNetwork.java
diff --git a/api/src/com/cloud/network/PhysicalNetworkServiceProvider.java b/api/src/main/java/com/cloud/network/PhysicalNetworkServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/PhysicalNetworkServiceProvider.java
rename to api/src/main/java/com/cloud/network/PhysicalNetworkServiceProvider.java
diff --git a/api/src/com/cloud/network/PhysicalNetworkSetupInfo.java b/api/src/main/java/com/cloud/network/PhysicalNetworkSetupInfo.java
similarity index 100%
rename from api/src/com/cloud/network/PhysicalNetworkSetupInfo.java
rename to api/src/main/java/com/cloud/network/PhysicalNetworkSetupInfo.java
diff --git a/api/src/com/cloud/network/PhysicalNetworkTrafficType.java b/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
similarity index 100%
rename from api/src/com/cloud/network/PhysicalNetworkTrafficType.java
rename to api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
diff --git a/api/src/com/cloud/network/PublicIpAddress.java b/api/src/main/java/com/cloud/network/PublicIpAddress.java
similarity index 100%
rename from api/src/com/cloud/network/PublicIpAddress.java
rename to api/src/main/java/com/cloud/network/PublicIpAddress.java
diff --git a/api/src/com/cloud/network/RemoteAccessVpn.java b/api/src/main/java/com/cloud/network/RemoteAccessVpn.java
similarity index 100%
rename from api/src/com/cloud/network/RemoteAccessVpn.java
rename to api/src/main/java/com/cloud/network/RemoteAccessVpn.java
diff --git a/api/src/com/cloud/network/Site2SiteCustomerGateway.java b/api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java
similarity index 100%
rename from api/src/com/cloud/network/Site2SiteCustomerGateway.java
rename to api/src/main/java/com/cloud/network/Site2SiteCustomerGateway.java
diff --git a/api/src/com/cloud/network/Site2SiteVpnConnection.java b/api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java
similarity index 100%
rename from api/src/com/cloud/network/Site2SiteVpnConnection.java
rename to api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java
diff --git a/api/src/com/cloud/network/Site2SiteVpnGateway.java b/api/src/main/java/com/cloud/network/Site2SiteVpnGateway.java
similarity index 100%
rename from api/src/com/cloud/network/Site2SiteVpnGateway.java
rename to api/src/main/java/com/cloud/network/Site2SiteVpnGateway.java
diff --git a/api/src/com/cloud/network/StorageNetworkService.java b/api/src/main/java/com/cloud/network/StorageNetworkService.java
similarity index 100%
rename from api/src/com/cloud/network/StorageNetworkService.java
rename to api/src/main/java/com/cloud/network/StorageNetworkService.java
diff --git a/api/src/com/cloud/network/TrafficLabel.java b/api/src/main/java/com/cloud/network/TrafficLabel.java
similarity index 100%
rename from api/src/com/cloud/network/TrafficLabel.java
rename to api/src/main/java/com/cloud/network/TrafficLabel.java
diff --git a/api/src/com/cloud/network/UserIpv6Address.java b/api/src/main/java/com/cloud/network/UserIpv6Address.java
similarity index 100%
rename from api/src/com/cloud/network/UserIpv6Address.java
rename to api/src/main/java/com/cloud/network/UserIpv6Address.java
diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java
similarity index 100%
rename from api/src/com/cloud/network/VirtualNetworkApplianceService.java
rename to api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java
diff --git a/api/src/com/cloud/network/VirtualRouterProvider.java b/api/src/main/java/com/cloud/network/VirtualRouterProvider.java
similarity index 100%
rename from api/src/com/cloud/network/VirtualRouterProvider.java
rename to api/src/main/java/com/cloud/network/VirtualRouterProvider.java
diff --git a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java b/api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java
similarity index 100%
rename from api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java
rename to api/src/main/java/com/cloud/network/VpcVirtualNetworkApplianceService.java
diff --git a/api/src/com/cloud/network/VpnUser.java b/api/src/main/java/com/cloud/network/VpnUser.java
similarity index 100%
rename from api/src/com/cloud/network/VpnUser.java
rename to api/src/main/java/com/cloud/network/VpnUser.java
diff --git a/api/src/com/cloud/network/as/AutoScaleCounter.java b/api/src/main/java/com/cloud/network/as/AutoScaleCounter.java
similarity index 100%
rename from api/src/com/cloud/network/as/AutoScaleCounter.java
rename to api/src/main/java/com/cloud/network/as/AutoScaleCounter.java
diff --git a/api/src/com/cloud/network/as/AutoScalePolicy.java b/api/src/main/java/com/cloud/network/as/AutoScalePolicy.java
similarity index 100%
rename from api/src/com/cloud/network/as/AutoScalePolicy.java
rename to api/src/main/java/com/cloud/network/as/AutoScalePolicy.java
diff --git a/api/src/com/cloud/network/as/AutoScaleService.java b/api/src/main/java/com/cloud/network/as/AutoScaleService.java
similarity index 100%
rename from api/src/com/cloud/network/as/AutoScaleService.java
rename to api/src/main/java/com/cloud/network/as/AutoScaleService.java
diff --git a/api/src/com/cloud/network/as/AutoScaleVmGroup.java b/api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java
similarity index 100%
rename from api/src/com/cloud/network/as/AutoScaleVmGroup.java
rename to api/src/main/java/com/cloud/network/as/AutoScaleVmGroup.java
diff --git a/api/src/com/cloud/network/as/AutoScaleVmProfile.java b/api/src/main/java/com/cloud/network/as/AutoScaleVmProfile.java
similarity index 100%
rename from api/src/com/cloud/network/as/AutoScaleVmProfile.java
rename to api/src/main/java/com/cloud/network/as/AutoScaleVmProfile.java
diff --git a/api/src/com/cloud/network/as/Condition.java b/api/src/main/java/com/cloud/network/as/Condition.java
similarity index 100%
rename from api/src/com/cloud/network/as/Condition.java
rename to api/src/main/java/com/cloud/network/as/Condition.java
diff --git a/api/src/com/cloud/network/as/Counter.java b/api/src/main/java/com/cloud/network/as/Counter.java
similarity index 100%
rename from api/src/com/cloud/network/as/Counter.java
rename to api/src/main/java/com/cloud/network/as/Counter.java
diff --git a/api/src/com/cloud/network/element/AggregatedCommandExecutor.java b/api/src/main/java/com/cloud/network/element/AggregatedCommandExecutor.java
similarity index 100%
rename from api/src/com/cloud/network/element/AggregatedCommandExecutor.java
rename to api/src/main/java/com/cloud/network/element/AggregatedCommandExecutor.java
diff --git a/api/src/com/cloud/network/element/ConnectivityProvider.java b/api/src/main/java/com/cloud/network/element/ConnectivityProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/ConnectivityProvider.java
rename to api/src/main/java/com/cloud/network/element/ConnectivityProvider.java
diff --git a/api/src/com/cloud/network/element/DhcpServiceProvider.java b/api/src/main/java/com/cloud/network/element/DhcpServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/DhcpServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/DhcpServiceProvider.java
diff --git a/api/src/com/cloud/network/element/DnsServiceProvider.java b/api/src/main/java/com/cloud/network/element/DnsServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/DnsServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/DnsServiceProvider.java
diff --git a/api/src/com/cloud/network/element/FirewallServiceProvider.java b/api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/FirewallServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java
diff --git a/api/src/com/cloud/network/element/IpDeployer.java b/api/src/main/java/com/cloud/network/element/IpDeployer.java
similarity index 100%
rename from api/src/com/cloud/network/element/IpDeployer.java
rename to api/src/main/java/com/cloud/network/element/IpDeployer.java
diff --git a/api/src/com/cloud/network/element/IpDeployingRequester.java b/api/src/main/java/com/cloud/network/element/IpDeployingRequester.java
similarity index 100%
rename from api/src/com/cloud/network/element/IpDeployingRequester.java
rename to api/src/main/java/com/cloud/network/element/IpDeployingRequester.java
diff --git a/api/src/com/cloud/network/element/LoadBalancingServiceProvider.java b/api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/LoadBalancingServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/LoadBalancingServiceProvider.java
diff --git a/api/src/com/cloud/network/element/NetworkACLServiceProvider.java b/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/NetworkACLServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java
diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/main/java/com/cloud/network/element/NetworkElement.java
similarity index 100%
rename from api/src/com/cloud/network/element/NetworkElement.java
rename to api/src/main/java/com/cloud/network/element/NetworkElement.java
diff --git a/api/src/com/cloud/network/element/PortForwardingServiceProvider.java b/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/PortForwardingServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
diff --git a/api/src/com/cloud/network/element/RedundantResource.java b/api/src/main/java/com/cloud/network/element/RedundantResource.java
similarity index 100%
rename from api/src/com/cloud/network/element/RedundantResource.java
rename to api/src/main/java/com/cloud/network/element/RedundantResource.java
diff --git a/api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java b/api/src/main/java/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/RemoteAccessVPNServiceProvider.java
diff --git a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java b/api/src/main/java/com/cloud/network/element/Site2SiteVpnServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/Site2SiteVpnServiceProvider.java
diff --git a/api/src/com/cloud/network/element/SourceNatServiceProvider.java b/api/src/main/java/com/cloud/network/element/SourceNatServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/SourceNatServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/SourceNatServiceProvider.java
diff --git a/api/src/com/cloud/network/element/StaticNatServiceProvider.java b/api/src/main/java/com/cloud/network/element/StaticNatServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/StaticNatServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/StaticNatServiceProvider.java
diff --git a/api/src/com/cloud/network/element/UserDataServiceProvider.java b/api/src/main/java/com/cloud/network/element/UserDataServiceProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/UserDataServiceProvider.java
rename to api/src/main/java/com/cloud/network/element/UserDataServiceProvider.java
diff --git a/api/src/com/cloud/network/element/VirtualRouterElementService.java b/api/src/main/java/com/cloud/network/element/VirtualRouterElementService.java
similarity index 100%
rename from api/src/com/cloud/network/element/VirtualRouterElementService.java
rename to api/src/main/java/com/cloud/network/element/VirtualRouterElementService.java
diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/main/java/com/cloud/network/element/VpcProvider.java
similarity index 100%
rename from api/src/com/cloud/network/element/VpcProvider.java
rename to api/src/main/java/com/cloud/network/element/VpcProvider.java
diff --git a/api/src/com/cloud/network/firewall/FirewallService.java b/api/src/main/java/com/cloud/network/firewall/FirewallService.java
similarity index 100%
rename from api/src/com/cloud/network/firewall/FirewallService.java
rename to api/src/main/java/com/cloud/network/firewall/FirewallService.java
diff --git a/api/src/com/cloud/network/guru/NetworkGuru.java b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
similarity index 100%
rename from api/src/com/cloud/network/guru/NetworkGuru.java
rename to api/src/main/java/com/cloud/network/guru/NetworkGuru.java
diff --git a/api/src/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java b/api/src/main/java/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java
similarity index 100%
rename from api/src/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java
rename to api/src/main/java/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java
diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/main/java/com/cloud/network/lb/LoadBalancingRule.java
similarity index 100%
rename from api/src/com/cloud/network/lb/LoadBalancingRule.java
rename to api/src/main/java/com/cloud/network/lb/LoadBalancingRule.java
diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
similarity index 100%
rename from api/src/com/cloud/network/lb/LoadBalancingRulesService.java
rename to api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/main/java/com/cloud/network/router/VirtualRouter.java
similarity index 100%
rename from api/src/com/cloud/network/router/VirtualRouter.java
rename to api/src/main/java/com/cloud/network/router/VirtualRouter.java
diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/main/java/com/cloud/network/rules/FirewallRule.java
similarity index 100%
rename from api/src/com/cloud/network/rules/FirewallRule.java
rename to api/src/main/java/com/cloud/network/rules/FirewallRule.java
diff --git a/api/src/com/cloud/network/rules/HealthCheckPolicy.java b/api/src/main/java/com/cloud/network/rules/HealthCheckPolicy.java
similarity index 100%
rename from api/src/com/cloud/network/rules/HealthCheckPolicy.java
rename to api/src/main/java/com/cloud/network/rules/HealthCheckPolicy.java
diff --git a/api/src/com/cloud/network/rules/LbStickinessMethod.java b/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
similarity index 100%
rename from api/src/com/cloud/network/rules/LbStickinessMethod.java
rename to api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
diff --git a/api/src/com/cloud/network/rules/LoadBalancer.java b/api/src/main/java/com/cloud/network/rules/LoadBalancer.java
similarity index 100%
rename from api/src/com/cloud/network/rules/LoadBalancer.java
rename to api/src/main/java/com/cloud/network/rules/LoadBalancer.java
diff --git a/api/src/com/cloud/network/rules/LoadBalancerContainer.java b/api/src/main/java/com/cloud/network/rules/LoadBalancerContainer.java
similarity index 100%
rename from api/src/com/cloud/network/rules/LoadBalancerContainer.java
rename to api/src/main/java/com/cloud/network/rules/LoadBalancerContainer.java
diff --git a/api/src/com/cloud/network/rules/PortForwardingRule.java b/api/src/main/java/com/cloud/network/rules/PortForwardingRule.java
similarity index 100%
rename from api/src/com/cloud/network/rules/PortForwardingRule.java
rename to api/src/main/java/com/cloud/network/rules/PortForwardingRule.java
diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/main/java/com/cloud/network/rules/RulesService.java
similarity index 100%
rename from api/src/com/cloud/network/rules/RulesService.java
rename to api/src/main/java/com/cloud/network/rules/RulesService.java
diff --git a/api/src/com/cloud/network/rules/StaticNat.java b/api/src/main/java/com/cloud/network/rules/StaticNat.java
similarity index 100%
rename from api/src/com/cloud/network/rules/StaticNat.java
rename to api/src/main/java/com/cloud/network/rules/StaticNat.java
diff --git a/api/src/com/cloud/network/rules/StaticNatRule.java b/api/src/main/java/com/cloud/network/rules/StaticNatRule.java
similarity index 100%
rename from api/src/com/cloud/network/rules/StaticNatRule.java
rename to api/src/main/java/com/cloud/network/rules/StaticNatRule.java
diff --git a/api/src/com/cloud/network/rules/StickinessPolicy.java b/api/src/main/java/com/cloud/network/rules/StickinessPolicy.java
similarity index 100%
rename from api/src/com/cloud/network/rules/StickinessPolicy.java
rename to api/src/main/java/com/cloud/network/rules/StickinessPolicy.java
diff --git a/api/src/com/cloud/network/security/SecurityGroup.java b/api/src/main/java/com/cloud/network/security/SecurityGroup.java
similarity index 100%
rename from api/src/com/cloud/network/security/SecurityGroup.java
rename to api/src/main/java/com/cloud/network/security/SecurityGroup.java
diff --git a/api/src/com/cloud/network/security/SecurityGroupRules.java b/api/src/main/java/com/cloud/network/security/SecurityGroupRules.java
similarity index 100%
rename from api/src/com/cloud/network/security/SecurityGroupRules.java
rename to api/src/main/java/com/cloud/network/security/SecurityGroupRules.java
diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/main/java/com/cloud/network/security/SecurityGroupService.java
similarity index 100%
rename from api/src/com/cloud/network/security/SecurityGroupService.java
rename to api/src/main/java/com/cloud/network/security/SecurityGroupService.java
diff --git a/api/src/com/cloud/network/security/SecurityRule.java b/api/src/main/java/com/cloud/network/security/SecurityRule.java
similarity index 100%
rename from api/src/com/cloud/network/security/SecurityRule.java
rename to api/src/main/java/com/cloud/network/security/SecurityRule.java
diff --git a/api/src/com/cloud/network/vpc/NetworkACL.java b/api/src/main/java/com/cloud/network/vpc/NetworkACL.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/NetworkACL.java
rename to api/src/main/java/com/cloud/network/vpc/NetworkACL.java
diff --git a/api/src/main/java/com/cloud/network/vpc/NetworkACLItem.java b/api/src/main/java/com/cloud/network/vpc/NetworkACLItem.java
new file mode 100644
index 0000000..eeca375
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/vpc/NetworkACLItem.java
@@ -0,0 +1,80 @@
+// 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.network.vpc;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.Displayable;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface NetworkACLItem extends InternalIdentity, Identity, Displayable {
+
+    @Override
+    String getUuid();
+
+    Action getAction();
+
+    int getNumber();
+
+    enum State {
+        Staged, // Rule been created but has never got through network rule conflict detection.  Rules in this state can not be sent to network elements.
+        Add,    // Add means the rule has been created and has gone through network rule conflict detection.
+        Active, // Rule has been sent to the network elements and reported to be active.
+        Revoke  // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database.
+    }
+
+    enum TrafficType {
+        Ingress, Egress
+    }
+
+    enum Action {
+        Allow, Deny
+    }
+
+    /**
+     * @return first port of the source port range.
+     */
+    Integer getSourcePortStart();
+
+    /**
+     * @return last port of the source port range.  If this is null, that means only one port is mapped.
+     */
+    Integer getSourcePortEnd();
+
+    /**
+     * @return protocol to open these ports for.
+     */
+    String getProtocol();
+
+    State getState();
+
+    long getAclId();
+
+    Integer getIcmpCode();
+
+    Integer getIcmpType();
+
+    List<String> getSourceCidrList();
+
+    TrafficType getTrafficType();
+
+    @Override
+    boolean isDisplay();
+
+    String getReason();
+}
diff --git a/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java b/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java
new file mode 100644
index 0000000..7c4e8b4
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/vpc/NetworkACLService.java
@@ -0,0 +1,99 @@
+// 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.network.vpc;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
+import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.utils.Pair;
+
+public interface NetworkACLService {
+
+    /**
+     * Creates Network ACL for the specified VPC
+     */
+    NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay);
+
+    /**
+     * Get Network ACL with specified Id
+     */
+    NetworkACL getNetworkACL(long id);
+
+    /**
+     * List NetworkACLs by Id/Name/Network or VPC it belongs to
+     */
+    Pair<List<? extends NetworkACL>, Integer> listNetworkACLs(ListNetworkACLListsCmd cmd);
+
+    /**
+     * Delete specified network ACL. Deletion fails if the list is not empty
+     */
+    boolean deleteNetworkACL(long id);
+
+    /**
+     * Associates ACL with specified Network
+     */
+    boolean replaceNetworkACL(long aclId, long networkId) throws ResourceUnavailableException;
+
+    /**
+     * Applied ACL to associated networks
+     */
+    boolean applyNetworkACL(long aclId) throws ResourceUnavailableException;
+
+    /**
+     * Creates a Network ACL Item within an ACL and applies the ACL to associated networks
+     */
+    NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd);
+
+    /**
+     * Return ACL item with specified Id
+     */
+    NetworkACLItem getNetworkACLItem(long ruleId);
+
+    /**
+     * Lists Network ACL Items by Id, Network, ACLId, Traffic Type, protocol
+     */
+    Pair<List<? extends NetworkACLItem>, Integer> listNetworkACLItems(ListNetworkACLsCmd cmd);
+
+    /**
+     * Revoke ACL Item with specified Id
+     */
+    boolean revokeNetworkACLItem(long ruleId);
+
+    /**
+     * Updates existing aclItem applies to associated networks
+     */
+    NetworkACLItem updateNetworkACLItem(UpdateNetworkACLItemCmd updateNetworkACLItemCmd) throws ResourceUnavailableException;
+
+    /**
+     * Associates ACL with specified Network
+     */
+    boolean replaceNetworkACLonPrivateGw(long aclId, long privateGatewayId) throws ResourceUnavailableException;
+
+    NetworkACL updateNetworkACL(UpdateNetworkACLListCmd updateNetworkACLListCmd);
+
+    /**
+     * Updates a network item ACL to a new position. This method allows users to inform between which ACLs the given ACL will be placed. Therefore, the 'number' field will be filled out by the system in the best way possible to place the ACL accordingly.
+     */
+    NetworkACLItem moveNetworkAclRuleToNewPosition(MoveNetworkAclItemCmd moveNetworkAclItemCmd);
+}
\ No newline at end of file
diff --git a/api/src/com/cloud/network/vpc/PrivateGateway.java b/api/src/main/java/com/cloud/network/vpc/PrivateGateway.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/PrivateGateway.java
rename to api/src/main/java/com/cloud/network/vpc/PrivateGateway.java
diff --git a/api/src/com/cloud/network/vpc/PrivateIp.java b/api/src/main/java/com/cloud/network/vpc/PrivateIp.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/PrivateIp.java
rename to api/src/main/java/com/cloud/network/vpc/PrivateIp.java
diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/main/java/com/cloud/network/vpc/StaticRoute.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/StaticRoute.java
rename to api/src/main/java/com/cloud/network/vpc/StaticRoute.java
diff --git a/api/src/com/cloud/network/vpc/StaticRouteProfile.java b/api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/StaticRouteProfile.java
rename to api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java
diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/main/java/com/cloud/network/vpc/Vpc.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/Vpc.java
rename to api/src/main/java/com/cloud/network/vpc/Vpc.java
diff --git a/api/src/com/cloud/network/vpc/VpcGateway.java b/api/src/main/java/com/cloud/network/vpc/VpcGateway.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/VpcGateway.java
rename to api/src/main/java/com/cloud/network/vpc/VpcGateway.java
diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/VpcOffering.java
rename to api/src/main/java/com/cloud/network/vpc/VpcOffering.java
diff --git a/api/src/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/VpcProvisioningService.java
rename to api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/main/java/com/cloud/network/vpc/VpcService.java
similarity index 100%
rename from api/src/com/cloud/network/vpc/VpcService.java
rename to api/src/main/java/com/cloud/network/vpc/VpcService.java
diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/main/java/com/cloud/network/vpn/RemoteAccessVpnService.java
similarity index 100%
rename from api/src/com/cloud/network/vpn/RemoteAccessVpnService.java
rename to api/src/main/java/com/cloud/network/vpn/RemoteAccessVpnService.java
diff --git a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java b/api/src/main/java/com/cloud/network/vpn/Site2SiteVpnService.java
similarity index 100%
rename from api/src/com/cloud/network/vpn/Site2SiteVpnService.java
rename to api/src/main/java/com/cloud/network/vpn/Site2SiteVpnService.java
diff --git a/api/src/main/java/com/cloud/offering/DiskOffering.java b/api/src/main/java/com/cloud/offering/DiskOffering.java
new file mode 100644
index 0000000..98ba6c0
--- /dev/null
+++ b/api/src/main/java/com/cloud/offering/DiskOffering.java
@@ -0,0 +1,158 @@
+// 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.offering;
+
+import java.util.Date;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.storage.Storage.ProvisioningType;
+
+/**
+ * Represents a disk offering that specifies what the end user needs in
+ * the disk offering.
+ *
+ */
+public interface DiskOffering extends InfrastructureEntity, Identity, InternalIdentity {
+    enum State {
+        Inactive, Active,
+    }
+
+    public enum Type {
+        Disk, Service
+    };
+
+    State getState();
+
+    public enum DiskCacheMode {
+        NONE("none"), WRITEBACK("writeback"), WRITETHROUGH("writethrough");
+
+        private final String _diskCacheMode;
+
+        DiskCacheMode(String cacheMode) {
+            _diskCacheMode = cacheMode;
+        }
+
+        @Override
+        public String toString() {
+            return _diskCacheMode;
+        }
+    };
+
+    String getUniqueName();
+
+    boolean isUseLocalStorage();
+
+    Long getDomainId();
+
+    String getName();
+
+    boolean isSystemUse();
+
+    String getDisplayText();
+
+    public ProvisioningType getProvisioningType();
+
+    public String getTags();
+
+    public String[] getTagsArray();
+
+    Date getCreated();
+
+    boolean isCustomized();
+
+    void setDiskSize(long diskSize);
+
+    long getDiskSize();
+
+    void setCustomizedIops(Boolean customizedIops);
+
+    Boolean isCustomizedIops();
+
+    void setMinIops(Long minIops);
+
+    Long getMinIops();
+
+    void setMaxIops(Long maxIops);
+
+    Long getMaxIops();
+
+    boolean isRecreatable();
+
+    void setBytesReadRate(Long bytesReadRate);
+
+    Long getBytesReadRate();
+
+    void setBytesReadRateMax(Long bytesReadRateMax);
+
+    Long getBytesReadRateMax();
+
+    void setBytesReadRateMaxLength(Long bytesReadRateMaxLength);
+
+    Long getBytesReadRateMaxLength();
+
+
+    void setBytesWriteRate(Long bytesWriteRate);
+
+    Long getBytesWriteRate();
+
+    void setBytesWriteRateMax(Long bytesWriteMax);
+
+    Long getBytesWriteRateMax();
+
+    void setBytesWriteRateMaxLength(Long bytesWriteMaxLength);
+
+    Long getBytesWriteRateMaxLength();
+
+
+    void setIopsReadRate(Long iopsReadRate);
+
+    Long getIopsReadRate();
+
+    void setIopsReadRateMax(Long iopsReadRateMax);
+
+    Long getIopsReadRateMax();
+
+    void setIopsReadRateMaxLength(Long iopsReadRateMaxLength);
+
+    Long getIopsReadRateMaxLength();
+
+    void setIopsWriteRate(Long iopsWriteRate);
+
+    Long getIopsWriteRate();
+
+    void setIopsWriteRateMax(Long iopsWriteRateMax);
+
+    Long getIopsWriteRateMax();
+
+
+    void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength);
+
+    Long getIopsWriteRateMaxLength();
+
+    void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve);
+
+    Integer getHypervisorSnapshotReserve();
+
+    DiskCacheMode getCacheMode();
+
+    void setCacheMode(DiskCacheMode cacheMode);
+
+    Type getType();
+}
diff --git a/api/src/com/cloud/offering/DiskOfferingInfo.java b/api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
similarity index 100%
rename from api/src/com/cloud/offering/DiskOfferingInfo.java
rename to api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
diff --git a/api/src/main/java/com/cloud/offering/NetworkOffering.java b/api/src/main/java/com/cloud/offering/NetworkOffering.java
new file mode 100644
index 0000000..97db87b
--- /dev/null
+++ b/api/src/main/java/com/cloud/offering/NetworkOffering.java
@@ -0,0 +1,144 @@
+// 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.offering;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Networks.TrafficType;
+
+/**
+ * Describes network offering
+ *
+ */
+public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, Identity {
+
+    public enum Availability {
+        Required, Optional
+    }
+
+    public enum State {
+        Disabled, Enabled
+    }
+
+    public enum Detail {
+        InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, RelatedNetworkOffering
+    }
+
+    public final static String SystemPublicNetwork = "System-Public-Network";
+    public final static String SystemControlNetwork = "System-Control-Network";
+    public final static String SystemManagementNetwork = "System-Management-Network";
+    public final static String SystemStorageNetwork = "System-Storage-Network";
+    public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
+
+    public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
+    public final static String QuickCloudNoServices = "QuickCloudNoServices";
+    public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
+    public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
+    public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";
+    public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering";
+    public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering";
+    public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks";
+    public final static String DefaultIsolatedNetworkOfferingForVpcNetworksNoLB = "DefaultIsolatedNetworkOfferingForVpcNetworksNoLB";
+    public final static String DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB = "DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB";
+    public final static String DefaultL2NetworkOffering = "DefaultL2NetworkOffering";
+    public final static String DefaultL2NetworkOfferingVlan = "DefaultL2NetworkOfferingVlan";
+    public final static String DefaultL2NetworkOfferingConfigDrive = "DefaultL2NetworkOfferingConfigDrive";
+    public final static String DefaultL2NetworkOfferingConfigDriveVlan = "DefaultL2NetworkOfferingConfigDriveVlan";
+
+    /**
+     * @return name for the network offering.
+     */
+    String getName();
+
+    /**
+     * @return text to display to the end user.
+     */
+    String getDisplayText();
+
+    /**
+     * @return the rate in megabits per sec to which a VM's network interface is throttled to
+     */
+    Integer getRateMbps();
+
+    /**
+     * @return the rate megabits per sec to which a VM's multicast&broadcast traffic is throttled to
+     */
+    Integer getMulticastRateMbps();
+
+    boolean isForVpc();
+
+    TrafficType getTrafficType();
+
+    boolean isSpecifyVlan();
+
+    String getTags();
+
+    boolean isDefault();
+
+    boolean isSystemOnly();
+
+    Availability getAvailability();
+
+    String getUniqueName();
+
+    void setState(State state);
+
+    State getState();
+
+    GuestType getGuestType();
+
+    Long getServiceOfferingId();
+
+    boolean isDedicatedLB();
+
+    boolean isSharedSourceNat();
+
+    boolean isRedundantRouter();
+
+    boolean isConserveMode();
+
+    boolean isElasticIp();
+
+    boolean isAssociatePublicIP();
+
+    boolean isElasticLb();
+
+    boolean isSpecifyIpRanges();
+
+    boolean isInline();
+
+    boolean isPersistent();
+
+    boolean isInternalLb();
+
+    boolean isPublicLb();
+
+    boolean isEgressDefaultPolicy();
+
+    Integer getConcurrentConnections();
+
+    boolean isKeepAliveEnabled();
+
+    boolean isSupportingStrechedL2();
+
+    boolean isSupportingPublicAccess();
+
+    String getServicePackage();
+}
diff --git a/api/src/com/cloud/offering/OfferingManager.java b/api/src/main/java/com/cloud/offering/OfferingManager.java
similarity index 100%
rename from api/src/com/cloud/offering/OfferingManager.java
rename to api/src/main/java/com/cloud/offering/OfferingManager.java
diff --git a/api/src/main/java/com/cloud/offering/ServiceOffering.java b/api/src/main/java/com/cloud/offering/ServiceOffering.java
new file mode 100644
index 0000000..6f0116d
--- /dev/null
+++ b/api/src/main/java/com/cloud/offering/ServiceOffering.java
@@ -0,0 +1,122 @@
+// 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.offering;
+
+import java.util.Date;
+
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+/**
+ * offered.
+ */
+public interface ServiceOffering extends DiskOffering, InfrastructureEntity, InternalIdentity, Identity {
+    public static final String consoleProxyDefaultOffUniqueName = "Cloud.com-ConsoleProxy";
+    public static final String ssvmDefaultOffUniqueName = "Cloud.com-SecondaryStorage";
+    public static final String routerDefaultOffUniqueName = "Cloud.Com-SoftwareRouter";
+    public static final String elbVmDefaultOffUniqueName = "Cloud.Com-ElasticLBVm";
+    public static final String internalLbVmDefaultOffUniqueName = "Cloud.Com-InternalLBVm";
+    // leaving cloud.com references as these are identifyers and no real world addresses (check against DB)
+
+    public enum StorageType {
+        local, shared
+    }
+
+    @Override
+    String getDisplayText();
+
+    @Override
+    Date getCreated();
+
+    @Override
+    String getTags();
+
+    /**
+     * @return user readable description
+     */
+    @Override
+    String getName();
+
+    /**
+     * @return is this a system service offering
+     */
+    @Override
+    boolean isSystemUse();
+
+    /**
+     * @return # of cpu.
+     */
+    Integer getCpu();
+
+    /**
+     * @return speed in mhz
+     */
+    Integer getSpeed();
+
+    /**
+     * @return ram size in megabytes
+     */
+    Integer getRamSize();
+
+    /**
+     * @return Does this service plan offer HA?
+     */
+    boolean isOfferHA();
+
+    /**
+     * @return Does this service plan offer VM to use CPU resources beyond the service offering limits?
+     */
+    boolean getLimitCpuUse();
+
+    /**
+     * @return Does this service plan support Volatile VM that is, discard VM's root disk and create a new one on reboot?
+     */
+    boolean isVolatileVm();
+
+    /**
+     * @return the rate in megabits per sec to which a VM's network interface is throttled to
+     */
+    Integer getRateMbps();
+
+    /**
+     * @return the rate megabits per sec to which a VM's multicast&broadcast traffic is throttled to
+     */
+    Integer getMulticastRateMbps();
+
+    /**
+     * @return whether or not the service offering requires local storage
+     */
+    @Override
+    boolean isUseLocalStorage();
+
+    @Override
+    Long getDomainId();
+
+    /**
+     * @return tag that should be present on the host needed, optional parameter
+     */
+    String getHostTag();
+
+    boolean getDefaultUse();
+
+    String getSystemVmType();
+
+    String getDeploymentPlanner();
+
+    boolean isDynamic();
+}
diff --git a/api/src/com/cloud/org/Cluster.java b/api/src/main/java/com/cloud/org/Cluster.java
similarity index 100%
rename from api/src/com/cloud/org/Cluster.java
rename to api/src/main/java/com/cloud/org/Cluster.java
diff --git a/api/src/com/cloud/org/Grouping.java b/api/src/main/java/com/cloud/org/Grouping.java
similarity index 100%
rename from api/src/com/cloud/org/Grouping.java
rename to api/src/main/java/com/cloud/org/Grouping.java
diff --git a/api/src/com/cloud/org/Managed.java b/api/src/main/java/com/cloud/org/Managed.java
similarity index 100%
rename from api/src/com/cloud/org/Managed.java
rename to api/src/main/java/com/cloud/org/Managed.java
diff --git a/api/src/com/cloud/org/RunningIn.java b/api/src/main/java/com/cloud/org/RunningIn.java
similarity index 100%
rename from api/src/com/cloud/org/RunningIn.java
rename to api/src/main/java/com/cloud/org/RunningIn.java
diff --git a/api/src/com/cloud/projects/Project.java b/api/src/main/java/com/cloud/projects/Project.java
similarity index 100%
rename from api/src/com/cloud/projects/Project.java
rename to api/src/main/java/com/cloud/projects/Project.java
diff --git a/api/src/com/cloud/projects/ProjectAccount.java b/api/src/main/java/com/cloud/projects/ProjectAccount.java
similarity index 100%
rename from api/src/com/cloud/projects/ProjectAccount.java
rename to api/src/main/java/com/cloud/projects/ProjectAccount.java
diff --git a/api/src/com/cloud/projects/ProjectInvitation.java b/api/src/main/java/com/cloud/projects/ProjectInvitation.java
similarity index 100%
rename from api/src/com/cloud/projects/ProjectInvitation.java
rename to api/src/main/java/com/cloud/projects/ProjectInvitation.java
diff --git a/api/src/com/cloud/projects/ProjectService.java b/api/src/main/java/com/cloud/projects/ProjectService.java
similarity index 100%
rename from api/src/com/cloud/projects/ProjectService.java
rename to api/src/main/java/com/cloud/projects/ProjectService.java
diff --git a/api/src/com/cloud/region/ha/GlobalLoadBalancerRule.java b/api/src/main/java/com/cloud/region/ha/GlobalLoadBalancerRule.java
similarity index 100%
rename from api/src/com/cloud/region/ha/GlobalLoadBalancerRule.java
rename to api/src/main/java/com/cloud/region/ha/GlobalLoadBalancerRule.java
diff --git a/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java b/api/src/main/java/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
similarity index 100%
rename from api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
rename to api/src/main/java/com/cloud/region/ha/GlobalLoadBalancingRulesService.java
diff --git a/api/src/main/java/com/cloud/resource/ResourceService.java b/api/src/main/java/com/cloud/resource/ResourceService.java
new file mode 100644
index 0000000..7082308
--- /dev/null
+++ b/api/src/main/java/com/cloud/resource/ResourceService.java
@@ -0,0 +1,89 @@
+// 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.resource;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
+import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
+import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
+import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Cluster;
+import com.cloud.utils.fsm.NoTransitionException;
+
+public interface ResourceService {
+    /**
+     * Updates a host
+     *
+     * @param cmd - the command specifying hostId
+     */
+    Host updateHost(UpdateHostCmd cmd) throws NoTransitionException;
+
+    Host cancelMaintenance(CancelMaintenanceCmd cmd);
+
+    Host reconnectHost(ReconnectHostCmd cmd) throws AgentUnavailableException;
+
+    /**
+     * We will automatically create an Apache CloudStack cluster to attach to the external cluster and return a hyper host to perform
+     * host related operation within the cluster
+     */
+    List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException;
+
+    boolean deleteCluster(DeleteClusterCmd cmd);
+
+    Cluster updateCluster(Cluster cluster, String clusterType, String hypervisor, String allocationState, String managedstate);
+
+    List<? extends Host> discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
+
+    List<? extends Host> discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
+
+    Host maintain(PrepareForMaintenanceCmd cmd);
+
+    /**
+     * Deletes a host
+     * @param true if deleted, false otherwise
+     */
+    boolean deleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage);
+
+    boolean updateClusterPassword(UpdateHostPasswordCmd upasscmd);
+
+    boolean updateHostPassword(UpdateHostPasswordCmd upasscmd);
+
+    Host getHost(long hostId);
+
+    Cluster getCluster(Long clusterId);
+
+    DataCenter getZone(Long zoneId);
+
+    List<HypervisorType> getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId);
+
+    boolean releaseHostReservation(Long hostId);
+
+}
diff --git a/api/src/com/cloud/resource/ResourceState.java b/api/src/main/java/com/cloud/resource/ResourceState.java
similarity index 100%
rename from api/src/com/cloud/resource/ResourceState.java
rename to api/src/main/java/com/cloud/resource/ResourceState.java
diff --git a/api/src/com/cloud/resource/UnableDeleteHostException.java b/api/src/main/java/com/cloud/resource/UnableDeleteHostException.java
similarity index 100%
rename from api/src/com/cloud/resource/UnableDeleteHostException.java
rename to api/src/main/java/com/cloud/resource/UnableDeleteHostException.java
diff --git a/api/src/com/cloud/serializer/Param.java b/api/src/main/java/com/cloud/serializer/Param.java
similarity index 100%
rename from api/src/com/cloud/serializer/Param.java
rename to api/src/main/java/com/cloud/serializer/Param.java
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/main/java/com/cloud/server/ManagementService.java
similarity index 100%
rename from api/src/com/cloud/server/ManagementService.java
rename to api/src/main/java/com/cloud/server/ManagementService.java
diff --git a/api/src/com/cloud/server/ResourceMetaDataService.java b/api/src/main/java/com/cloud/server/ResourceMetaDataService.java
similarity index 100%
rename from api/src/com/cloud/server/ResourceMetaDataService.java
rename to api/src/main/java/com/cloud/server/ResourceMetaDataService.java
diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/main/java/com/cloud/server/ResourceTag.java
similarity index 100%
rename from api/src/com/cloud/server/ResourceTag.java
rename to api/src/main/java/com/cloud/server/ResourceTag.java
diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/main/java/com/cloud/server/TaggedResourceService.java
similarity index 100%
rename from api/src/com/cloud/server/TaggedResourceService.java
rename to api/src/main/java/com/cloud/server/TaggedResourceService.java
diff --git a/api/src/com/cloud/storage/DataStoreProviderApiService.java b/api/src/main/java/com/cloud/storage/DataStoreProviderApiService.java
similarity index 100%
rename from api/src/com/cloud/storage/DataStoreProviderApiService.java
rename to api/src/main/java/com/cloud/storage/DataStoreProviderApiService.java
diff --git a/api/src/com/cloud/storage/DataStoreRole.java b/api/src/main/java/com/cloud/storage/DataStoreRole.java
similarity index 100%
rename from api/src/com/cloud/storage/DataStoreRole.java
rename to api/src/main/java/com/cloud/storage/DataStoreRole.java
diff --git a/api/src/main/java/com/cloud/storage/GuestOS.java b/api/src/main/java/com/cloud/storage/GuestOS.java
new file mode 100644
index 0000000..33c0872
--- /dev/null
+++ b/api/src/main/java/com/cloud/storage/GuestOS.java
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.Date;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface GuestOS extends InternalIdentity, Identity {
+
+    String getName();
+
+    String getDisplayName();
+
+    long getCategoryId();
+
+    Date getCreated();
+
+    Date getRemoved();
+
+    boolean isUserDefined();
+}
diff --git a/api/src/com/cloud/storage/GuestOSHypervisor.java b/api/src/main/java/com/cloud/storage/GuestOSHypervisor.java
similarity index 100%
rename from api/src/com/cloud/storage/GuestOSHypervisor.java
rename to api/src/main/java/com/cloud/storage/GuestOSHypervisor.java
diff --git a/api/src/com/cloud/storage/GuestOsCategory.java b/api/src/main/java/com/cloud/storage/GuestOsCategory.java
similarity index 100%
rename from api/src/com/cloud/storage/GuestOsCategory.java
rename to api/src/main/java/com/cloud/storage/GuestOsCategory.java
diff --git a/api/src/com/cloud/storage/ImageStore.java b/api/src/main/java/com/cloud/storage/ImageStore.java
similarity index 100%
rename from api/src/com/cloud/storage/ImageStore.java
rename to api/src/main/java/com/cloud/storage/ImageStore.java
diff --git a/api/src/com/cloud/storage/ScopeType.java b/api/src/main/java/com/cloud/storage/ScopeType.java
similarity index 100%
rename from api/src/com/cloud/storage/ScopeType.java
rename to api/src/main/java/com/cloud/storage/ScopeType.java
diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/main/java/com/cloud/storage/Snapshot.java
similarity index 100%
rename from api/src/com/cloud/storage/Snapshot.java
rename to api/src/main/java/com/cloud/storage/Snapshot.java
diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/main/java/com/cloud/storage/Storage.java
similarity index 100%
rename from api/src/com/cloud/storage/Storage.java
rename to api/src/main/java/com/cloud/storage/Storage.java
diff --git a/api/src/com/cloud/storage/StorageGuru.java b/api/src/main/java/com/cloud/storage/StorageGuru.java
similarity index 100%
rename from api/src/com/cloud/storage/StorageGuru.java
rename to api/src/main/java/com/cloud/storage/StorageGuru.java
diff --git a/api/src/com/cloud/storage/StoragePool.java b/api/src/main/java/com/cloud/storage/StoragePool.java
similarity index 100%
rename from api/src/com/cloud/storage/StoragePool.java
rename to api/src/main/java/com/cloud/storage/StoragePool.java
diff --git a/api/src/com/cloud/storage/StoragePoolDiscoverer.java b/api/src/main/java/com/cloud/storage/StoragePoolDiscoverer.java
similarity index 100%
rename from api/src/com/cloud/storage/StoragePoolDiscoverer.java
rename to api/src/main/java/com/cloud/storage/StoragePoolDiscoverer.java
diff --git a/api/src/com/cloud/storage/StoragePoolStatus.java b/api/src/main/java/com/cloud/storage/StoragePoolStatus.java
similarity index 100%
rename from api/src/com/cloud/storage/StoragePoolStatus.java
rename to api/src/main/java/com/cloud/storage/StoragePoolStatus.java
diff --git a/api/src/main/java/com/cloud/storage/StorageService.java b/api/src/main/java/com/cloud/storage/StorageService.java
new file mode 100644
index 0000000..aebbbcd
--- /dev/null
+++ b/api/src/main/java/com/cloud/storage/StorageService.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 com.cloud.storage;
+
+import java.net.UnknownHostException;
+import java.util.Map;
+
+import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
+
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.exception.ResourceUnavailableException;
+
+public interface StorageService {
+    /**
+     * Create StoragePool based on uri
+     *
+     * @param cmd
+     *            The command object that specifies the zone, cluster/pod, URI, details, etc. to use to create the
+     *            storage pool.
+     * @return
+     *            The StoragePool created.
+     * @throws ResourceInUseException
+     * @throws IllegalArgumentException
+     * @throws UnknownHostException
+     * @throws ResourceUnavailableException
+     */
+    StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException;
+
+    ImageStore createSecondaryStagingStore(CreateSecondaryStagingStoreCmd cmd);
+
+    /**
+     * Delete the storage pool
+     *
+     * @param cmd
+     *            - the command specifying poolId
+     * @return success or failure
+     */
+    boolean deletePool(DeletePoolCmd cmd);
+
+    /**
+     * Enable maintenance for primary storage
+     *
+     * @param primaryStorageId
+     *            - the primaryStorageId
+     * @return the primary storage pool
+     * @throws ResourceUnavailableException
+     * @throws InsufficientCapacityException
+     */
+    StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException;
+
+    /**
+     * Complete maintenance for primary storage
+     *
+     * @param cmd
+     *            - the command specifying primaryStorageId
+     * @return the primary storage pool
+     * @throws ResourceUnavailableException
+     */
+    StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException;
+
+    StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException;
+
+    StoragePool getStoragePool(long id);
+
+    boolean deleteImageStore(DeleteImageStoreCmd cmd);
+
+    boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd);
+
+    ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
+
+    /**
+     * Migrate existing NFS to use object store.
+     * @param name object store name.
+     * @param url object store URL.
+     * @param providerName object store provider Name.
+     * @param details object store other details
+     * @return Object store created.
+     */
+    ImageStore migrateToObjectStore(String name, String url, String providerName, Map<String, String> details) throws DiscoveryException;
+
+}
diff --git a/api/src/com/cloud/storage/StorageStats.java b/api/src/main/java/com/cloud/storage/StorageStats.java
similarity index 100%
rename from api/src/com/cloud/storage/StorageStats.java
rename to api/src/main/java/com/cloud/storage/StorageStats.java
diff --git a/api/src/com/cloud/storage/Upload.java b/api/src/main/java/com/cloud/storage/Upload.java
similarity index 100%
rename from api/src/com/cloud/storage/Upload.java
rename to api/src/main/java/com/cloud/storage/Upload.java
diff --git a/api/src/com/cloud/storage/VMTemplateStorageResourceAssoc.java b/api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
similarity index 100%
rename from api/src/com/cloud/storage/VMTemplateStorageResourceAssoc.java
rename to api/src/main/java/com/cloud/storage/VMTemplateStorageResourceAssoc.java
diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/main/java/com/cloud/storage/Volume.java
similarity index 100%
rename from api/src/com/cloud/storage/Volume.java
rename to api/src/main/java/com/cloud/storage/Volume.java
diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java
new file mode 100644
index 0000000..7b38a6b
--- /dev/null
+++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.cloud.storage;
+
+import java.net.MalformedURLException;
+
+import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
+import org.apache.cloudstack.api.response.GetUploadParamsResponse;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.user.Account;
+
+public interface VolumeApiService {
+
+    ConfigKey<Long> ConcurrentMigrationsThresholdPerDatastore = new ConfigKey<Long>("Advanced"
+            , Long.class
+            , "concurrent.migrations.per.target.datastore"
+            , "0"
+            , "Limits number of migrations that can be handled per datastore concurrently; default is 0 - unlimited"
+            , true // not sure if this is to be dynamic
+            , ConfigKey.Scope.Global);
+
+    /**
+     * Creates the database object for a volume based on the given criteria
+     *
+     * @param cmd
+     *            the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
+     *            name)
+     * @return the volume object
+     */
+    Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
+
+    /**
+     * Creates the volume based on the given criteria
+     *
+     * @param cmd
+     *            the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
+     *            name)
+     * @return the volume object
+     */
+    Volume createVolume(CreateVolumeCmd cmd);
+
+    /**
+     * Resizes the volume based on the given criteria
+     *
+     * @param cmd
+     *            the API command wrapping the criteria
+     * @return the volume object
+     * @throws ResourceAllocationException
+     */
+    Volume resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException;
+
+    Volume migrateVolume(MigrateVolumeCmd cmd);
+
+    /**
+     * Uploads the volume to secondary storage
+     *
+     * @return Volume object
+     */
+    Volume uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException;
+
+    GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException;
+
+    boolean deleteVolume(long volumeId, Account caller);
+
+    Volume attachVolumeToVM(AttachVolumeCmd command);
+
+    Volume detachVolumeViaDestroyVM(long vmId, long volumeId);
+
+    Volume detachVolumeFromVM(DetachVolumeCmd cmd);
+
+    Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
+            throws ResourceAllocationException;
+
+    Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
+
+    Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo);
+
+    /**
+     * Extracts the volume to a particular location.
+     *
+     * @param cmd
+     *            the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume exists),
+     *            id (the id of the volume)
+     */
+    String extractVolume(ExtractVolumeCmd cmd);
+
+    boolean isDisplayResourceEnabled(Long id);
+
+    void updateDisplay(Volume volume, Boolean displayVolume);
+
+    Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException;
+
+    /**
+     *  Checks if the target storage supports the disk offering.
+     *  This validation is consistent with the mechanism used to select a storage pool to deploy a volume when a virtual machine is deployed or when a data disk is allocated.
+     *
+     *  The scenarios when this method returns true or false is presented in the following table.
+     *   <table border="1">
+     *      <tr>
+     *          <th>#</th><th>Disk offering tags</th><th>Storage tags</th><th>Does the storage support the disk offering?</th>
+     *      </tr>
+     *      <body>
+     *      <tr>
+     *          <td>1</td><td>A,B</td><td>A</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>2</td><td>A,B,C</td><td>A,B,C,D,X</td><td>YES</td>
+     *      </tr>
+     *      <tr>
+     *          <td>3</td><td>A,B,C</td><td>X,Y,Z</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>4</td><td>null</td><td>A,S,D</td><td>YES</td>
+     *      </tr>
+     *      <tr>
+     *          <td>5</td><td>A</td><td>null</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>6</td><td>null</td><td>null</td><td>YES</td>
+     *      </tr>
+     *      </body>
+     *   </table>
+     */
+    boolean doesTargetStorageSupportDiskOffering(StoragePool destPool, String diskOfferingTags);
+}
\ No newline at end of file
diff --git a/api/src/com/cloud/storage/VolumeStats.java b/api/src/main/java/com/cloud/storage/VolumeStats.java
similarity index 100%
rename from api/src/com/cloud/storage/VolumeStats.java
rename to api/src/main/java/com/cloud/storage/VolumeStats.java
diff --git a/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java
new file mode 100644
index 0000000..a80391b
--- /dev/null
+++ b/api/src/main/java/com/cloud/storage/snapshot/SnapshotApiService.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.snapshot;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
+
+import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
+
+public interface SnapshotApiService {
+
+    /**
+     * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval
+     *
+     * @param cmd
+     *            the command containing the search criteria (order by, limit, etc.)
+     * @return list of snapshots
+     */
+    Pair<List<? extends Snapshot>, Integer> listSnapshots(ListSnapshotsCmd cmd);
+
+    /**
+     * Delete specified snapshot from the specified. If no other policies are assigned it calls destroy snapshot. This
+     * will be
+     * used for manual snapshots too.
+     *
+     * @param snapshotId
+     *            TODO
+     */
+    boolean deleteSnapshot(long snapshotId);
+
+    /**
+     * Creates a policy with specified schedule. maxSnaps specifies the number of most recent snapshots that are to be
+     * retained.
+     * If the number of snapshots go beyond maxSnaps the oldest snapshot is deleted
+     *
+     * @param cmd
+     *            the command that
+     * @param policyOwner
+     *            TODO
+     * @return the newly created snapshot policy if success, null otherwise
+     */
+    SnapshotPolicy createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner);
+
+    /**
+     * Get the recurring snapshots scheduled for this volume currently along with the time at which they are scheduled
+     *
+     * @param cmd
+     *            the command wrapping the volumeId (volume for which the snapshots are required) and policyId (to show
+     *            snapshots for only this policy).
+     * @return The list of snapshot schedules.
+     */
+    public List<? extends SnapshotSchedule> findRecurringSnapshotSchedule(ListRecurringSnapshotScheduleCmd cmd);
+
+    /**
+     * list all snapshot policies assigned to the specified volume
+     *
+     * @param cmd
+     *            the command that specifies the volume criteria
+     * @return list of snapshot policies
+     */
+    Pair<List<? extends SnapshotPolicy>, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd);
+
+    boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd);
+
+    Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
+
+    /**
+     * Create a snapshot of a volume
+     *
+     * @param snapshotOwner
+     *            TODO
+     * @param cmd
+     *            the API command wrapping the parameters for creating the snapshot (mainly volumeId)
+     *
+     * @return the Snapshot that was created
+     */
+    Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner);
+
+    /**
+     * Archives a snapshot from primary storage to secondary storage.
+     * @param id Snapshot ID
+     * @return Archived Snapshot object
+     */
+    Snapshot archiveSnapshot(Long id);
+
+    /**
+     * @param vol
+     * @return
+     */
+    Long getHostIdForSnapshotOperation(Volume vol);
+
+    Snapshot revertSnapshot(Long snapshotId);
+
+    Snapshot backupSnapshotFromVmSnapshot(Long snapshotId, Long vmId, Long volumeId, Long vmSnapshotId);
+
+    SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd updateSnapshotPolicyCmd);
+}
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotPolicy.java b/api/src/main/java/com/cloud/storage/snapshot/SnapshotPolicy.java
similarity index 100%
rename from api/src/com/cloud/storage/snapshot/SnapshotPolicy.java
rename to api/src/main/java/com/cloud/storage/snapshot/SnapshotPolicy.java
diff --git a/api/src/com/cloud/storage/snapshot/SnapshotSchedule.java b/api/src/main/java/com/cloud/storage/snapshot/SnapshotSchedule.java
similarity index 100%
rename from api/src/com/cloud/storage/snapshot/SnapshotSchedule.java
rename to api/src/main/java/com/cloud/storage/snapshot/SnapshotSchedule.java
diff --git a/api/src/com/cloud/storage/template/TemplateProp.java b/api/src/main/java/com/cloud/storage/template/TemplateProp.java
similarity index 100%
rename from api/src/com/cloud/storage/template/TemplateProp.java
rename to api/src/main/java/com/cloud/storage/template/TemplateProp.java
diff --git a/api/src/com/cloud/template/BasedOn.java b/api/src/main/java/com/cloud/template/BasedOn.java
similarity index 100%
rename from api/src/com/cloud/template/BasedOn.java
rename to api/src/main/java/com/cloud/template/BasedOn.java
diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/main/java/com/cloud/template/TemplateApiService.java
similarity index 100%
rename from api/src/com/cloud/template/TemplateApiService.java
rename to api/src/main/java/com/cloud/template/TemplateApiService.java
diff --git a/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
new file mode 100644
index 0000000..ad2f636
--- /dev/null
+++ b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
@@ -0,0 +1,143 @@
+// 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.template;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.Volume.Event;
+import com.cloud.storage.Volume.State;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.fsm.StateObject;
+
+public interface VirtualMachineTemplate extends ControlledEntity, Identity, InternalIdentity, StateObject<VirtualMachineTemplate.State> {
+    enum State {
+        Active,
+        Inactive,
+        NotUploaded,
+        UploadInProgress,
+        UploadError,
+        UploadAbandoned;
+
+        public static StateMachine2<State, Event, VirtualMachineTemplate> getStateMachine() {
+            return s_fsm;
+        }
+
+        private final static StateMachine2<State, Event, VirtualMachineTemplate> s_fsm = new StateMachine2<State, Event, VirtualMachineTemplate>();
+        static {
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationTimeout, UploadAbandoned, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.UploadRequested, UploadInProgress, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationSucceeded, Active, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationFailed, UploadError, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationSucceeded, Active, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationFailed, UploadError, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationTimeout, UploadError, null));
+        }
+    }
+
+    enum Event {
+        OperationFailed,
+        OperationSucceeded,
+        UploadRequested,
+        OperationTimeout;
+    }
+
+    public static enum BootloaderType {
+        PyGrub, HVM, External, CD
+    };
+
+    public enum TemplateFilter {
+        featured, // returns templates that have been marked as featured and public
+        self, // returns templates that have been registered or created by the calling user
+        selfexecutable, // same as self, but only returns templates that are ready to be deployed with
+        shared, // including templates that have been granted to the calling user by another user
+        sharedexecutable, // ready templates that have been granted to the calling user by another user
+        executable, // templates that are owned by the calling user, or public templates, that can be used to deploy a
+        community, // returns templates that have been marked as public but not featured
+        all // all templates (only usable by admins)
+    }
+
+    @Override
+    State getState();
+
+    boolean isFeatured();
+
+    /**
+     * @return public or private template
+     */
+    boolean isPublicTemplate();
+
+    boolean isExtractable();
+
+    /**
+     * @return name
+     */
+    String getName();
+
+    ImageFormat getFormat();
+
+    boolean isRequiresHvm();
+
+    String getDisplayText();
+
+    boolean isEnablePassword();
+
+    boolean isEnableSshKey();
+
+    boolean isCrossZones();
+
+    Date getCreated();
+
+    long getGuestOSId();
+
+    boolean isBootable();
+
+    TemplateType getTemplateType();
+
+    HypervisorType getHypervisorType();
+
+    int getBits();
+
+    String getUniqueName();
+
+    String getUrl();
+
+    String getChecksum();
+
+    Long getSourceTemplateId();
+
+    String getTemplateTag();
+
+    Map getDetails();
+
+    boolean isDynamicallyScalable();
+
+    Long getParentTemplateId();
+
+    long getUpdatedCount();
+
+    void incrUpdatedCount();
+
+    Date getUpdated();
+}
diff --git a/api/src/com/cloud/user/Account.java b/api/src/main/java/com/cloud/user/Account.java
similarity index 100%
rename from api/src/com/cloud/user/Account.java
rename to api/src/main/java/com/cloud/user/Account.java
diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java
new file mode 100644
index 0000000..060861d
--- /dev/null
+++ b/api/src/main/java/com/cloud/user/AccountService.java
@@ -0,0 +1,117 @@
+// 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.user;
+
+import java.util.Map;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+
+import com.cloud.domain.Domain;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+
+public interface AccountService {
+
+    /**
+     * Creates a new user and account, stores the password as is so encrypted passwords are recommended.
+     * @return the user if created successfully, null otherwise
+     */
+    UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId,
+            String networkDomain, Map<String, String> details, String accountUUID, String userUUID);
+
+    UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId,
+            String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source);
+
+    /**
+     * Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses
+     * allocated/etc.
+     */
+    UserAccount lockUser(long userId);
+
+    Account getSystemAccount();
+
+    User getSystemUser();
+
+    User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
+
+    User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID, User.Source source);
+
+    boolean isAdmin(Long accountId);
+
+    Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId);
+
+    Account getActiveAccountByName(String accountName, Long domainId);
+
+    UserAccount getActiveUserAccount(String username, Long domainId);
+
+    UserAccount updateUser(UpdateUserCmd updateUserCmd);
+
+    Account getActiveAccountById(long accountId);
+
+    Account getAccount(long accountId);
+
+    User getActiveUser(long userId);
+
+    User getUserIncludingRemoved(long userId);
+
+    boolean isRootAdmin(Long accountId);
+
+    boolean isDomainAdmin(Long accountId);
+
+    boolean isNormalUser(long accountId);
+
+    User getActiveUserByRegistrationToken(String registrationToken);
+
+    void markUserRegistered(long userId);
+
+    public String[] createApiKeyAndSecretKey(RegisterCmd cmd);
+
+    public String[] createApiKeyAndSecretKey(final long userId);
+
+    UserAccount getUserByApiKey(String apiKey);
+
+    RoleType getRoleType(Account account);
+
+    void checkAccess(Account account, Domain domain) throws PermissionDeniedException;
+
+    void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
+
+    void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException;
+
+    void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException;
+
+    void checkAccess(User user, ControlledEntity entity);
+
+    void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
+
+    Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+
+    /**
+     * returns the user account object for a given user id
+     * @param userId user id
+     * @return {@link UserAccount} object if it exists else null
+     */
+    UserAccount getUserAccountById(Long userId);
+
+    public Map<String, String> getKeys(GetUserKeysCmd cmd);
+}
diff --git a/api/src/com/cloud/user/DomainService.java b/api/src/main/java/com/cloud/user/DomainService.java
similarity index 100%
rename from api/src/com/cloud/user/DomainService.java
rename to api/src/main/java/com/cloud/user/DomainService.java
diff --git a/api/src/com/cloud/user/OwnedBy.java b/api/src/main/java/com/cloud/user/OwnedBy.java
similarity index 100%
rename from api/src/com/cloud/user/OwnedBy.java
rename to api/src/main/java/com/cloud/user/OwnedBy.java
diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/main/java/com/cloud/user/ResourceLimitService.java
similarity index 100%
rename from api/src/com/cloud/user/ResourceLimitService.java
rename to api/src/main/java/com/cloud/user/ResourceLimitService.java
diff --git a/api/src/com/cloud/user/SSHKeyPair.java b/api/src/main/java/com/cloud/user/SSHKeyPair.java
similarity index 100%
rename from api/src/com/cloud/user/SSHKeyPair.java
rename to api/src/main/java/com/cloud/user/SSHKeyPair.java
diff --git a/api/src/com/cloud/user/User.java b/api/src/main/java/com/cloud/user/User.java
similarity index 100%
rename from api/src/com/cloud/user/User.java
rename to api/src/main/java/com/cloud/user/User.java
diff --git a/api/src/com/cloud/user/UserAccount.java b/api/src/main/java/com/cloud/user/UserAccount.java
similarity index 100%
rename from api/src/com/cloud/user/UserAccount.java
rename to api/src/main/java/com/cloud/user/UserAccount.java
diff --git a/api/src/com/cloud/uservm/UserVm.java b/api/src/main/java/com/cloud/uservm/UserVm.java
similarity index 100%
rename from api/src/com/cloud/uservm/UserVm.java
rename to api/src/main/java/com/cloud/uservm/UserVm.java
diff --git a/api/src/com/cloud/vm/BareMetalVmService.java b/api/src/main/java/com/cloud/vm/BareMetalVmService.java
similarity index 100%
rename from api/src/com/cloud/vm/BareMetalVmService.java
rename to api/src/main/java/com/cloud/vm/BareMetalVmService.java
diff --git a/api/src/com/cloud/vm/ConsoleProxy.java b/api/src/main/java/com/cloud/vm/ConsoleProxy.java
similarity index 100%
rename from api/src/com/cloud/vm/ConsoleProxy.java
rename to api/src/main/java/com/cloud/vm/ConsoleProxy.java
diff --git a/api/src/main/java/com/cloud/vm/DiskProfile.java b/api/src/main/java/com/cloud/vm/DiskProfile.java
new file mode 100644
index 0000000..2b76c68
--- /dev/null
+++ b/api/src/main/java/com/cloud/vm/DiskProfile.java
@@ -0,0 +1,226 @@
+// 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.vm;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Volume;
+
+/**
+ * DiskProfile describes a disk and what functionality is required from it.
+ * and resources to allocate and create disks. There object is immutable once
+ */
+public class DiskProfile {
+    private long size;
+    private String[] tags;
+    private Volume.Type type;
+    private String name;
+    private boolean useLocalStorage;
+    private boolean recreatable;
+    private long diskOfferingId;
+    private Long templateId;
+    private long volumeId;
+    private String path;
+    private ProvisioningType provisioningType;
+    private Long bytesReadRate;
+    private Long bytesWriteRate;
+    private Long iopsReadRate;
+    private Long iopsWriteRate;
+    private String cacheMode;
+
+    private HypervisorType hyperType;
+
+    protected DiskProfile() {
+    }
+
+    public DiskProfile(long volumeId, Volume.Type type, String name, long diskOfferingId, long size, String[] tags, boolean useLocalStorage, boolean recreatable,
+            Long templateId) {
+        this.type = type;
+        this.name = name;
+        this.size = size;
+        this.tags = tags;
+        this.useLocalStorage = useLocalStorage;
+        this.recreatable = recreatable;
+        this.diskOfferingId = diskOfferingId;
+        this.templateId = templateId;
+        this.volumeId = volumeId;
+    }
+
+    public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType) {
+        this(vol.getId(),
+            vol.getVolumeType(),
+            vol.getName(),
+            offering.getId(),
+            vol.getSize(),
+            offering.getTagsArray(),
+            offering.isUseLocalStorage(),
+            offering.isCustomized(),
+            null);
+        this.hyperType = hyperType;
+        this.provisioningType = offering.getProvisioningType();
+    }
+
+    public DiskProfile(DiskProfile dp) {
+
+    }
+
+    /**
+     * @return size of the disk requested in bytes.
+     */
+    public long getSize() {
+        return size;
+    }
+
+    /**
+     * @return id of the volume backing up this disk characteristics
+     */
+    public long getVolumeId() {
+        return volumeId;
+    }
+
+    /**
+     * @return Unique name for the disk.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return tags for the disk. This can be used to match it to different storage pools.
+     */
+    public String[] getTags() {
+        return tags;
+    }
+
+    /**
+     * @return type of volume.
+     */
+    public Volume.Type getType() {
+        return type;
+    }
+
+    /**
+     * @return Does this volume require local storage?
+     */
+    public boolean useLocalStorage() {
+        return useLocalStorage;
+    }
+
+    public void setUseLocalStorage(boolean useLocalStorage) {
+        this.useLocalStorage = useLocalStorage;
+    }
+
+    /**
+     * @return Is this volume recreatable? A volume is recreatable if the disk's content can be
+     *         reconstructed from the template.
+     */
+    public boolean isRecreatable() {
+        return recreatable;
+    }
+
+    /**
+     * @return template id the disk is based on. Can be null if it is not based on any templates.
+     */
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(Long templateId) {
+        this.templateId = templateId;
+    }
+
+    /**
+     * @return disk offering id that the disk is based on.
+     */
+    public long getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("DskChr[").append(type).append("|").append(size).append("|").append("]").toString();
+    }
+
+    public void setHyperType(HypervisorType hyperType) {
+        this.hyperType = hyperType;
+    }
+
+    public HypervisorType getHypervisorType() {
+        return this.hyperType;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getPath() {
+        return this.path;
+    }
+
+    public void setProvisioningType(ProvisioningType provisioningType){
+        this.provisioningType = provisioningType;
+    }
+
+    public ProvisioningType getProvisioningType(){
+        return this.provisioningType;
+    }
+
+    public void setSize(long size) {
+        this.size = size;
+    }
+
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public void setCacheMode(String cacheMode) {
+        this.cacheMode = cacheMode;
+    }
+
+    public String getCacheMode() {
+        return cacheMode;
+    }
+}
diff --git a/api/src/com/cloud/vm/InstanceGroup.java b/api/src/main/java/com/cloud/vm/InstanceGroup.java
similarity index 100%
rename from api/src/com/cloud/vm/InstanceGroup.java
rename to api/src/main/java/com/cloud/vm/InstanceGroup.java
diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/main/java/com/cloud/vm/Nic.java
similarity index 100%
rename from api/src/com/cloud/vm/Nic.java
rename to api/src/main/java/com/cloud/vm/Nic.java
diff --git a/api/src/com/cloud/vm/NicExtraDhcpOption.java b/api/src/main/java/com/cloud/vm/NicExtraDhcpOption.java
similarity index 100%
rename from api/src/com/cloud/vm/NicExtraDhcpOption.java
rename to api/src/main/java/com/cloud/vm/NicExtraDhcpOption.java
diff --git a/api/src/com/cloud/vm/NicIpAlias.java b/api/src/main/java/com/cloud/vm/NicIpAlias.java
similarity index 100%
rename from api/src/com/cloud/vm/NicIpAlias.java
rename to api/src/main/java/com/cloud/vm/NicIpAlias.java
diff --git a/api/src/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java
similarity index 100%
rename from api/src/com/cloud/vm/NicProfile.java
rename to api/src/main/java/com/cloud/vm/NicProfile.java
diff --git a/api/src/com/cloud/vm/NicSecondaryIp.java b/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
similarity index 100%
rename from api/src/com/cloud/vm/NicSecondaryIp.java
rename to api/src/main/java/com/cloud/vm/NicSecondaryIp.java
diff --git a/api/src/com/cloud/vm/ReservationContext.java b/api/src/main/java/com/cloud/vm/ReservationContext.java
similarity index 100%
rename from api/src/com/cloud/vm/ReservationContext.java
rename to api/src/main/java/com/cloud/vm/ReservationContext.java
diff --git a/api/src/com/cloud/vm/RunningOn.java b/api/src/main/java/com/cloud/vm/RunningOn.java
similarity index 100%
rename from api/src/com/cloud/vm/RunningOn.java
rename to api/src/main/java/com/cloud/vm/RunningOn.java
diff --git a/api/src/com/cloud/vm/SecondaryStorageVm.java b/api/src/main/java/com/cloud/vm/SecondaryStorageVm.java
similarity index 100%
rename from api/src/com/cloud/vm/SecondaryStorageVm.java
rename to api/src/main/java/com/cloud/vm/SecondaryStorageVm.java
diff --git a/api/src/com/cloud/vm/SystemVm.java b/api/src/main/java/com/cloud/vm/SystemVm.java
similarity index 100%
rename from api/src/com/cloud/vm/SystemVm.java
rename to api/src/main/java/com/cloud/vm/SystemVm.java
diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java
similarity index 100%
rename from api/src/com/cloud/vm/UserVmService.java
rename to api/src/main/java/com/cloud/vm/UserVmService.java
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java
similarity index 100%
rename from api/src/com/cloud/vm/VirtualMachine.java
rename to api/src/main/java/com/cloud/vm/VirtualMachine.java
diff --git a/api/src/com/cloud/vm/VirtualMachineName.java b/api/src/main/java/com/cloud/vm/VirtualMachineName.java
similarity index 100%
rename from api/src/com/cloud/vm/VirtualMachineName.java
rename to api/src/main/java/com/cloud/vm/VirtualMachineName.java
diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
similarity index 100%
rename from api/src/com/cloud/vm/VirtualMachineProfile.java
rename to api/src/main/java/com/cloud/vm/VirtualMachineProfile.java
diff --git a/api/src/com/cloud/vm/VmDetailConstants.java b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
similarity index 100%
rename from api/src/com/cloud/vm/VmDetailConstants.java
rename to api/src/main/java/com/cloud/vm/VmDetailConstants.java
diff --git a/api/src/com/cloud/vm/VmDiskStats.java b/api/src/main/java/com/cloud/vm/VmDiskStats.java
similarity index 100%
rename from api/src/com/cloud/vm/VmDiskStats.java
rename to api/src/main/java/com/cloud/vm/VmDiskStats.java
diff --git a/api/src/com/cloud/vm/VmNetworkStats.java b/api/src/main/java/com/cloud/vm/VmNetworkStats.java
similarity index 100%
rename from api/src/com/cloud/vm/VmNetworkStats.java
rename to api/src/main/java/com/cloud/vm/VmNetworkStats.java
diff --git a/api/src/com/cloud/vm/VmStats.java b/api/src/main/java/com/cloud/vm/VmStats.java
similarity index 100%
rename from api/src/com/cloud/vm/VmStats.java
rename to api/src/main/java/com/cloud/vm/VmStats.java
diff --git a/api/src/com/cloud/vm/snapshot/VMSnapshot.java b/api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java
similarity index 100%
rename from api/src/com/cloud/vm/snapshot/VMSnapshot.java
rename to api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java
diff --git a/api/src/com/cloud/vm/snapshot/VMSnapshotService.java b/api/src/main/java/com/cloud/vm/snapshot/VMSnapshotService.java
similarity index 100%
rename from api/src/com/cloud/vm/snapshot/VMSnapshotService.java
rename to api/src/main/java/com/cloud/vm/snapshot/VMSnapshotService.java
diff --git a/api/src/org/apache/cloudstack/acl/APIAclChecker.java b/api/src/main/java/org/apache/cloudstack/acl/APIAclChecker.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/APIAclChecker.java
rename to api/src/main/java/org/apache/cloudstack/acl/APIAclChecker.java
diff --git a/api/src/org/apache/cloudstack/acl/APIChecker.java b/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/APIChecker.java
rename to api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
diff --git a/api/src/org/apache/cloudstack/acl/APILimitChecker.java b/api/src/main/java/org/apache/cloudstack/acl/APILimitChecker.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/APILimitChecker.java
rename to api/src/main/java/org/apache/cloudstack/acl/APILimitChecker.java
diff --git a/api/src/org/apache/cloudstack/acl/ControlledEntity.java b/api/src/main/java/org/apache/cloudstack/acl/ControlledEntity.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/ControlledEntity.java
rename to api/src/main/java/org/apache/cloudstack/acl/ControlledEntity.java
diff --git a/api/src/org/apache/cloudstack/acl/InfrastructureEntity.java b/api/src/main/java/org/apache/cloudstack/acl/InfrastructureEntity.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/InfrastructureEntity.java
rename to api/src/main/java/org/apache/cloudstack/acl/InfrastructureEntity.java
diff --git a/api/src/org/apache/cloudstack/acl/PermissionScope.java b/api/src/main/java/org/apache/cloudstack/acl/PermissionScope.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/PermissionScope.java
rename to api/src/main/java/org/apache/cloudstack/acl/PermissionScope.java
diff --git a/api/src/org/apache/cloudstack/acl/QuerySelector.java b/api/src/main/java/org/apache/cloudstack/acl/QuerySelector.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/QuerySelector.java
rename to api/src/main/java/org/apache/cloudstack/acl/QuerySelector.java
diff --git a/api/src/org/apache/cloudstack/acl/Role.java b/api/src/main/java/org/apache/cloudstack/acl/Role.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/Role.java
rename to api/src/main/java/org/apache/cloudstack/acl/Role.java
diff --git a/api/src/org/apache/cloudstack/acl/RolePermission.java b/api/src/main/java/org/apache/cloudstack/acl/RolePermission.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/RolePermission.java
rename to api/src/main/java/org/apache/cloudstack/acl/RolePermission.java
diff --git a/api/src/org/apache/cloudstack/acl/RoleService.java b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/RoleService.java
rename to api/src/main/java/org/apache/cloudstack/acl/RoleService.java
diff --git a/api/src/org/apache/cloudstack/acl/RoleType.java b/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/RoleType.java
rename to api/src/main/java/org/apache/cloudstack/acl/RoleType.java
diff --git a/api/src/org/apache/cloudstack/acl/Rule.java b/api/src/main/java/org/apache/cloudstack/acl/Rule.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/Rule.java
rename to api/src/main/java/org/apache/cloudstack/acl/Rule.java
diff --git a/api/src/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
similarity index 100%
rename from api/src/org/apache/cloudstack/acl/SecurityChecker.java
rename to api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroup.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroup.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityGroup.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityGroup.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupProcessor.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityGroupResponse.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupResponse.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupService.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityGroupService.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupTypeResponse.java
diff --git a/api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
similarity index 100%
rename from api/src/org/apache/cloudstack/affinity/AffinityProcessorBase.java
rename to api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
diff --git a/api/src/org/apache/cloudstack/alert/AlertService.java b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/alert/AlertService.java
rename to api/src/main/java/org/apache/cloudstack/alert/AlertService.java
diff --git a/api/src/org/apache/cloudstack/annotation/Annotation.java b/api/src/main/java/org/apache/cloudstack/annotation/Annotation.java
similarity index 100%
rename from api/src/org/apache/cloudstack/annotation/Annotation.java
rename to api/src/main/java/org/apache/cloudstack/annotation/Annotation.java
diff --git a/api/src/org/apache/cloudstack/annotation/AnnotationService.java b/api/src/main/java/org/apache/cloudstack/annotation/AnnotationService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/annotation/AnnotationService.java
rename to api/src/main/java/org/apache/cloudstack/annotation/AnnotationService.java
diff --git a/api/src/org/apache/cloudstack/api/ACL.java b/api/src/main/java/org/apache/cloudstack/api/ACL.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ACL.java
rename to api/src/main/java/org/apache/cloudstack/api/ACL.java
diff --git a/api/src/org/apache/cloudstack/api/APICommand.java b/api/src/main/java/org/apache/cloudstack/api/APICommand.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/APICommand.java
rename to api/src/main/java/org/apache/cloudstack/api/APICommand.java
diff --git a/api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java b/api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/AbstractGetUploadParamsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/ApiArgValidator.java b/api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ApiArgValidator.java
rename to api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiCommandJobType.java b/api/src/main/java/org/apache/cloudstack/api/ApiCommandJobType.java
new file mode 100644
index 0000000..d35598b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandJobType.java
@@ -0,0 +1,57 @@
+// 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;
+
+public enum ApiCommandJobType {
+    None,
+    VirtualMachine,
+    DomainRouter,
+    Volume,
+    ConsoleProxy,
+    Snapshot,
+    Template,
+    Iso,
+    SystemVm,
+    Host,
+    StoragePool,
+    ImageStore,
+    IpAddress,
+    PortableIpAddress,
+    SecurityGroup,
+    PhysicalNetwork,
+    TrafficType,
+    PhysicalNetworkServiceProvider,
+    FirewallRule,
+    Account,
+    User,
+    PrivateGateway,
+    StaticRoute,
+    Counter,
+    Condition,
+    AutoScalePolicy,
+    AutoScaleVmProfile,
+    AutoScaleVmGroup,
+    GlobalLoadBalancerRule,
+    LoadBalancerRule,
+    AffinityGroup,
+    InternalLbVm,
+    DedicatedGuestVlanRange,
+    GuestOs,
+    GuestOsMapping,
+    Network,
+    Management
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
new file mode 100644
index 0000000..0c1f2b1
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -0,0 +1,738 @@
+// 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;
+
+public class ApiConstants {
+    public static final String ACCOUNT = "account";
+    public static final String ACCOUNTS = "accounts";
+    public static final String ACCOUNT_TYPE = "accounttype";
+    public static final String ACCOUNT_ID = "accountid";
+    public static final String ACTIVITY = "activity";
+    public static final String ADDRESS = "address";
+    public static final String ALGORITHM = "algorithm";
+    public static final String ALLOCATED_ONLY = "allocatedonly";
+    public static final String ANNOTATION = "annotation";
+    public static final String API_KEY = "apikey";
+    public static final String ASYNC_BACKUP = "asyncbackup";
+    public static final String USER_API_KEY = "userapikey";
+    public static final String APPLIED = "applied";
+    public static final String LIST_LB_VMIPS = "lbvmips";
+    public static final String AVAILABLE = "available";
+    public static final String BITS = "bits";
+    public static final String BOOTABLE = "bootable";
+    public static final String BIND_DN = "binddn";
+    public static final String BIND_PASSWORD = "bindpass";
+    public static final String BYTES_READ_RATE = "bytesreadrate";
+    public static final String BYTES_READ_RATE_MAX = "bytesreadratemax";
+    public static final String BYTES_READ_RATE_MAX_LENGTH = "bytesreadratemaxlength";
+    public static final String BYTES_WRITE_RATE = "byteswriterate";
+    public static final String BYTES_WRITE_RATE_MAX = "byteswriteratemax";
+    public static final String BYTES_WRITE_RATE_MAX_LENGTH = "byteswriteratemaxlength";
+    public static final String BYPASS_VLAN_OVERLAP_CHECK = "bypassvlanoverlapcheck";
+    public static final String CATEGORY = "category";
+    public static final String CAN_REVERT = "canrevert";
+    public static final String CA_CERTIFICATES = "cacertificates";
+    public static final String CERTIFICATE = "certificate";
+    public static final String CERTIFICATE_CHAIN = "certchain";
+    public static final String CERTIFICATE_FINGERPRINT = "fingerprint";
+    public static final String CERTIFICATE_ID = "certid";
+    public static final String CSR = "csr";
+    public static final String PRIVATE_KEY = "privatekey";
+    public static final String DOMAIN_SUFFIX = "domainsuffix";
+    public static final String DNS_SEARCH_ORDER = "dnssearchorder";
+    public static final String CHAIN_INFO = "chaininfo";
+    public static final String CIDR = "cidr";
+    public static final String IP6_CIDR = "ip6cidr";
+    public static final String CIDR_LIST = "cidrlist";
+    public static final String DEST_CIDR_LIST = "destcidrlist";
+    public static final String CLEANUP = "cleanup";
+    public static final String MAKEREDUNDANT = "makeredundant";
+    public static final String CLUSTER_ID = "clusterid";
+    public static final String CLUSTER_NAME = "clustername";
+    public static final String CLUSTER_TYPE = "clustertype";
+    public static final String CN = "cn";
+    public static final String COMMAND = "command";
+    public static final String CMD_EVENT_TYPE = "cmdeventtype";
+    public static final String COMPONENT = "component";
+    public static final String CPU_NUMBER = "cpunumber";
+    public static final String CPU_SPEED = "cpuspeed";
+    public static final String CREATED = "created";
+    public static final String CTX_ACCOUNT_ID = "ctxaccountid";
+    public static final String CTX_DETAILS = "ctxDetails";
+    public static final String CTX_USER_ID = "ctxuserid";
+    public static final String CTXSTARTEVENTID = "ctxstarteventid";
+    public static final String CTX_START_EVENT_ID = "ctxStartEventId";
+    public static final String CUSTOMIZED = "customized";
+    public static final String CUSTOMIZED_IOPS = "customizediops";
+    public static final String CUSTOM_ID = "customid";
+    public static final String CUSTOM_JOB_ID = "customjobid";
+    public static final String MIN_IOPS = "miniops";
+    public static final String MAX_IOPS = "maxiops";
+    public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
+    public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
+    public static final String DESCRIPTION = "description";
+    public static final String DESTINATION_ZONE_ID = "destzoneid";
+    public static final String DETAILS = "details";
+    public static final String DEVICE_ID = "deviceid";
+    public static final String DIRECT_DOWNLOAD = "directdownload";
+    public static final String DISK_OFFERING_ID = "diskofferingid";
+    public static final String NEW_DISK_OFFERING_ID = "newdiskofferingid";
+    public static final String DISK_SIZE = "disksize";
+    public static final String UTILIZATION = "utilization";
+    public static final String DRIVER = "driver";
+    public static final String ROOT_DISK_SIZE = "rootdisksize";
+    public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
+    public static final String DHCP_OPTIONS = "dhcpoptions";
+    public static final String DHCP_PREFIX = "dhcp:";
+    public static final String DISPLAY_NAME = "displayname";
+    public static final String DISPLAY_NETWORK = "displaynetwork";
+    public static final String DISPLAY_NIC = "displaynic";
+    public static final String DISPLAY_TEXT = "displaytext";
+    public static final String DISPLAY_VM = "displayvm";
+    public static final String DISPLAY_OFFERING = "displayoffering";
+    public static final String DISPLAY_VOLUME = "displayvolume";
+    public static final String DNS1 = "dns1";
+    public static final String DNS2 = "dns2";
+    public static final String IP6_DNS1 = "ip6dns1";
+    public static final String IP6_DNS2 = "ip6dns2";
+    public static final String DOMAIN = "domain";
+    public static final String DOMAIN_ID = "domainid";
+    public static final String DOMAIN__ID = "domainId";
+    public static final String DURATION = "duration";
+    public static final String ELIGIBLE = "eligible";
+    public static final String EMAIL = "email";
+    public static final String END_DATE = "enddate";
+    public static final String END_IP = "endip";
+    public static final String END_IPV6 = "endipv6";
+    public static final String END_PORT = "endport";
+    public static final String ENTRY_TIME = "entrytime";
+    public static final String EXPIRES = "expires";
+    public static final String EXTRA_CONFIG = "extraconfig";
+    public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
+    public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
+    public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
+    public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
+    public static final String FENCE = "fence";
+    public static final String FETCH_LATEST = "fetchlatest";
+    public static final String FIRSTNAME = "firstname";
+    public static final String FORCED = "forced";
+    public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
+    public static final String FORMAT = "format";
+    public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
+    public static final String FOR_SYSTEM_VMS = "forsystemvms";
+    public static final String GATEWAY = "gateway";
+    public static final String IP6_GATEWAY = "ip6gateway";
+    public static final String GROUP = "group";
+    public static final String GROUP_ID = "groupid";
+    public static final String GSLB_LB_METHOD = "gslblbmethod";
+    public static final String GSLB_SERVICE_DOMAIN_NAME = "gslbdomainname";
+    public static final String GSLB_SERVICE_TYPE = "gslbservicetype";
+    public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname";
+    public static final String GSLB_LBRULE_WEIGHT_MAP = "gslblbruleweightsmap";
+    public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
+    public static final String GUEST_VLAN_RANGE = "guestvlanrange";
+    public static final String HA_ENABLE = "haenable";
+    public static final String HA_PROVIDER = "haprovider";
+    public static final String HA_STATE = "hastate";
+    public static final String HEALTH = "health";
+    public static final String HOST_ID = "hostid";
+    public static final String HOST_NAME = "hostname";
+    public static final String HYPERVISOR = "hypervisor";
+    public static final String INLINE = "inline";
+    public static final String INSTANCE = "instance";
+    public static final String ICMP_CODE = "icmpcode";
+    public static final String ICMP_TYPE = "icmptype";
+    public static final String ID = "id";
+    public static final String IDS = "ids";
+    public static final String PREVIOUS_ACL_RULE_ID = "previousaclruleid";
+    public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
+    public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
+    public static final String INTERNAL_DNS1 = "internaldns1";
+    public static final String INTERNAL_DNS2 = "internaldns2";
+    public static final String INTERVAL_TYPE = "intervaltype";
+    public static final String LOCATION_TYPE = "locationtype";
+    public static final String IOPS_READ_RATE = "iopsreadrate";
+    public static final String IOPS_READ_RATE_MAX = "iopsreadratemax";
+    public static final String IOPS_READ_RATE_MAX_LENGTH = "iopsreadratemaxlength";
+    public static final String IOPS_WRITE_RATE = "iopswriterate";
+    public static final String IOPS_WRITE_RATE_MAX = "iopswriteratemax";
+    public static final String IOPS_WRITE_RATE_MAX_LENGTH = "iopswriteratemaxlength";
+    public static final String IP_ADDRESS = "ipaddress";
+    public static final String IP6_ADDRESS = "ip6address";
+    public static final String IP_ADDRESS_ID = "ipaddressid";
+    public static final String IS_ASYNC = "isasync";
+    public static final String IP_AVAILABLE = "ipavailable";
+    public static final String IP_LIMIT = "iplimit";
+    public static final String IP_TOTAL = "iptotal";
+    public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
+    public static final String IS_EXTRACTABLE = "isextractable";
+    public static final String IS_FEATURED = "isfeatured";
+    public static final String IS_PORTABLE = "isportable";
+    public static final String IS_PUBLIC = "ispublic";
+    public static final String IS_PERSISTENT = "ispersistent";
+    public static final String EGRESS_DEFAULT_POLICY = "egressdefaultpolicy";
+    public static final String IS_READY = "isready";
+    public static final String IS_RECURSIVE = "isrecursive";
+    public static final String ISO_FILTER = "isofilter";
+    public static final String ISO_GUEST_OS_NONE = "None";
+    public static final String JOB_ID = "jobid";
+    public static final String JOB_STATUS = "jobstatus";
+    public static final String LASTNAME = "lastname";
+    public static final String LEVEL = "level";
+    public static final String LENGTH = "length";
+    public static final String LIMIT_CPU_USE = "limitcpuuse";
+    public static final String LOCK = "lock";
+    public static final String LUN = "lun";
+    public static final String LBID = "lbruleid";
+    public static final String MAX = "max";
+    public static final String MAC_ADDRESS = "macaddress";
+    public static final String MAX_SNAPS = "maxsnaps";
+    public static final String MEMORY = "memory";
+    public static final String MODE = "mode";
+    public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
+    public static final String NAME = "name";
+    public static final String METHOD_NAME = "methodname";
+    public static final String NETWORK_DOMAIN = "networkdomain";
+    public static final String NETMASK = "netmask";
+    public static final String NEW_NAME = "newname";
+    public static final String NUM_RETRIES = "numretries";
+    public static final String OFFER_HA = "offerha";
+    public static final String IS_SYSTEM_OFFERING = "issystem";
+    public static final String IS_DEFAULT_USE = "defaultuse";
+    public static final String OP = "op";
+    public static final String OS_CATEGORY_ID = "oscategoryid";
+    public static final String OS_TYPE_ID = "ostypeid";
+    public static final String OS_DISPLAY_NAME = "osdisplayname";
+    public static final String OS_NAME_FOR_HYPERVISOR = "osnameforhypervisor";
+    public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
+    public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
+    public static final String PARAMS = "params";
+    public static final String PARENT_ID = "parentid";
+    public static final String PARENT_DOMAIN_ID = "parentdomainid";
+    public static final String PARENT_TEMPLATE_ID = "parenttemplateid";
+    public static final String PASSWORD = "password";
+    public static final String CURRENT_PASSWORD = "currentpassword";
+    public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
+    public static final String PASSWORD_ENABLED = "passwordenabled";
+    public static final String SSHKEY_ENABLED = "sshkeyenabled";
+    public static final String PATH = "path";
+    public static final String POD_ID = "podid";
+    public static final String POD_NAME = "podname";
+    public static final String POD_IDS = "podids";
+    public static final String POLICY_ID = "policyid";
+    public static final String PORT = "port";
+    public static final String PORTAL = "portal";
+    public static final String PORTABLE_IP_ADDRESS = "portableipaddress";
+    public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid";
+    public static final String POST_URL = "postURL";
+    public static final String POWER_STATE = "powerstate";
+    public static final String PRIVATE_INTERFACE = "privateinterface";
+    public static final String PRIVATE_IP = "privateip";
+    public static final String PRIVATE_PORT = "privateport";
+    public static final String PRIVATE_START_PORT = "privateport";
+    public static final String PRIVATE_END_PORT = "privateendport";
+    public static final String PRIVATE_ZONE = "privatezone";
+    public static final String PROTOCOL = "protocol";
+    public static final String PROVISIONINGTYPE = "provisioningtype";
+    public static final String PUBLIC_INTERFACE = "publicinterface";
+    public static final String PUBLIC_IP_ID = "publicipid";
+    public static final String PUBLIC_IP = "publicip";
+    public static final String PUBLIC_PORT = "publicport";
+    public static final String PUBLIC_START_PORT = "publicport";
+    public static final String PUBLIC_END_PORT = "publicendport";
+    public static final String PUBLIC_ZONE = "publiczone";
+    public static final String RECEIVED_BYTES = "receivedbytes";
+    public static final String RECONNECT = "reconnect";
+    public static final String RECOVER = "recover";
+    public static final String REQUIRES_HVM = "requireshvm";
+    public static final String RESOURCE_TYPE = "resourcetype";
+    public static final String RESOURCE_TYPE_NAME = "resourcetypename";
+    public static final String RESPONSE = "response";
+    public static final String REVERTABLE = "revertable";
+    public static final String REGISTERED = "registered";
+    public static final String QUERY_FILTER = "queryfilter";
+    public static final String SCHEDULE = "schedule";
+    public static final String SCOPE = "scope";
+    public static final String SECRET_KEY = "usersecretkey";
+    public static final String SECONDARY_IP = "secondaryip";
+    public static final String SINCE = "since";
+    public static final String KEY = "key";
+    public static final String SEARCH_BASE = "searchbase";
+    public static final String SECURITY_GROUP_IDS = "securitygroupids";
+    public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
+    public static final String SECURITY_GROUP_NAME = "securitygroupname";
+    public static final String SECURITY_GROUP_ID = "securitygroupid";
+    public static final String SENT = "sent";
+    public static final String SENT_BYTES = "sentbytes";
+    public static final String SERIAL = "serial";
+    public static final String SERVICE_OFFERING_ID = "serviceofferingid";
+    public static final String SESSIONKEY = "sessionkey";
+    public static final String SHOW_CAPACITIES = "showcapacities";
+    public static final String SHOW_REMOVED = "showremoved";
+    public static final String SIGNATURE = "signature";
+    public static final String SIGNATURE_VERSION = "signatureversion";
+    public static final String SIZE = "size";
+    public static final String SNAPSHOT = "snapshot";
+    public static final String SNAPSHOT_ID = "snapshotid";
+    public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
+    public static final String SNAPSHOT_TYPE = "snapshottype";
+    public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
+    public static final String SOURCE_ZONE_ID = "sourcezoneid";
+    public static final String START_DATE = "startdate";
+    public static final String START_ID = "startid";
+    public static final String START_IP = "startip";
+    public static final String START_IPV6 = "startipv6";
+    public static final String START_PORT = "startport";
+    public static final String STATE = "state";
+    public static final String STATUS = "status";
+    public static final String STORAGE_TYPE = "storagetype";
+    public static final String STORAGE_POLICY = "storagepolicy";
+    public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
+    public static final String STORAGE_CAPABILITIES = "storagecapabilities";
+    public static final String SYSTEM_VM_TYPE = "systemvmtype";
+    public static final String TAGS = "tags";
+    public static final String TARGET_IQN = "targetiqn";
+    public static final String TEMPLATE_FILTER = "templatefilter";
+    public static final String TEMPLATE_ID = "templateid";
+    public static final String ISO_ID = "isoid";
+    public static final String TIMEOUT = "timeout";
+    public static final String TIMEZONE = "timezone";
+    public static final String TIMEZONEOFFSET = "timezoneoffset";
+    public static final String TYPE = "type";
+    public static final String TRUST_STORE = "truststore";
+    public static final String TRUST_STORE_PASSWORD = "truststorepass";
+    public static final String URL = "url";
+    public static final String USAGE_INTERFACE = "usageinterface";
+    public static final String USER_DATA = "userdata";
+    public static final String USER_ID = "userid";
+    public static final String USE_SSL = "ssl";
+    public static final String USERNAME = "username";
+    public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
+    public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
+    public static final String Update_IN_SEQUENCE = "updateinsequence";
+    public static final String VALUE = "value";
+    public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
+    public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
+    public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
+    public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
+    public static final String USAGE_ID = "usageid";
+    public static final String USAGE_TYPE = "usagetype";
+    public static final String INCLUDE_TAGS = "includetags";
+
+    public static final String VLAN = "vlan";
+    public static final String VLAN_RANGE = "vlanrange";
+    public static final String REMOVE_VLAN = "removevlan";
+    public static final String VLAN_ID = "vlanid";
+    public static final String ISOLATED_PVLAN = "isolatedpvlan";
+    public static final String ISOLATION_URI = "isolationuri";
+    public static final String VM_AVAILABLE = "vmavailable";
+    public static final String VM_LIMIT = "vmlimit";
+    public static final String VM_TOTAL = "vmtotal";
+    public static final String VNET = "vnet";
+    public static final String IS_VOLATILE = "isvolatile";
+    public static final String VOLUME_ID = "volumeid";
+    public static final String ZONE_ID = "zoneid";
+    public static final String ZONE_NAME = "zonename";
+    public static final String NETWORK_TYPE = "networktype";
+    public static final String PAGE = "page";
+    public static final String PAGE_SIZE = "pagesize";
+    public static final String COUNT = "count";
+    public static final String TRAFFIC_TYPE = "traffictype";
+    public static final String NETWORK_OFFERING_ID = "networkofferingid";
+    public static final String TIER_NETWORK_OFFERINGS = "tiernetworkofferings";
+    public static final String NETWORK_IDS = "networkids";
+    public static final String NETWORK_ID = "networkid";
+    public static final String NIC_ID = "nicid";
+    public static final String SPECIFY_VLAN = "specifyvlan";
+    public static final String IS_DEFAULT = "isdefault";
+    public static final String IS_SYSTEM = "issystem";
+    public static final String IS_USER_DEFINED = "isuserdefined";
+    public static final String AVAILABILITY = "availability";
+    public static final String NETWORKRATE = "networkrate";
+    public static final String HOST_TAGS = "hosttags";
+    public static final String SSH_KEYPAIR = "keypair";
+    public static final String HTTPMETHOD = "httpmethod";
+    public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
+    public static final String HOST_CPU_NUM = "hostcpunum";
+    public static final String HOST_MEM_CAPACITY = "hostmemcapacity";
+    public static final String HOST_MAC = "hostmac";
+    public static final String HOST_TAG = "hosttag";
+    public static final String PXE_SERVER_TYPE = "pxeservertype";
+    public static final String LINMIN_USERNAME = "linminusername";
+    public static final String LINMIN_PASSWORD = "linminpassword";
+    public static final String LINMIN_APID = "linminapid";
+    public static final String DHCP_SERVER_TYPE = "dhcpservertype";
+    public static final String LINK_LOCAL_IP = "linklocalip";
+    public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress";
+    public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask";
+    public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid";
+    public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress";
+    public static final String PRIVATE_NETMASK = "privatenetmask";
+    public static final String PRIVATE_NETWORK_ID = "privatenetworkid";
+    public static final String ALLOCATION_STATE = "allocationstate";
+    public static final String MANAGED_STATE = "managedstate";
+    public static final String STORAGE_ID = "storageid";
+    public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
+    public static final String PING_DIR = "pingdir";
+    public static final String TFTP_DIR = "tftpdir";
+    public static final String PING_CIFS_USERNAME = "pingcifsusername";
+    public static final String PING_CIFS_PASSWORD = "pingcifspassword";
+    public static final String CHECKSUM = "checksum";
+    public static final String NETWORK_DEVICE_TYPE = "networkdevicetype";
+    public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist";
+    public static final String ZONE_TOKEN = "zonetoken";
+    public static final String DHCP_PROVIDER = "dhcpprovider";
+    public static final String RESULT = "success";
+    public static final String RESUME = "resume";
+    public static final String LUN_ID = "lunId";
+    public static final String IQN = "iqn";
+    public static final String AGGREGATE_NAME = "aggregatename";
+    public static final String POOL_NAME = "poolname";
+    public static final String VOLUME_NAME = "volumename";
+    public static final String SNAPSHOT_POLICY = "snapshotpolicy";
+    public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
+    public static final String IP_NETWORK_LIST = "iptonetworklist";
+    public static final String PARAM_LIST = "param";
+    public static final String FOR_LOAD_BALANCING = "forloadbalancing";
+    public static final String KEYBOARD = "keyboard";
+    public static final String OPEN_FIREWALL = "openfirewall";
+    public static final String TEMPLATE_TAG = "templatetag";
+    public static final String HYPERVISOR_VERSION = "hypervisorversion";
+    public static final String MAX_GUESTS_LIMIT = "maxguestslimit";
+    public static final String MAX_DATA_VOLUMES_LIMIT = "maxdatavolumeslimit";
+    public static final String MAX_HOSTS_PER_CLUSTER = "maxhostspercluster";
+    public static final String PROJECT_ID = "projectid";
+    public static final String PROJECT_IDS = "projectids";
+    public static final String PROJECT = "project";
+    public static final String ROLE = "role";
+    public static final String ROLE_ID = "roleid";
+    public static final String ROLE_TYPE = "roletype";
+    public static final String ROLE_NAME = "rolename";
+    public static final String PERMISSION = "permission";
+    public static final String RULE = "rule";
+    public static final String RULE_ID = "ruleid";
+    public static final String RULE_ORDER = "ruleorder";
+    public static final String USER = "user";
+    public static final String ACTIVE_ONLY = "activeonly";
+    public static final String TOKEN = "token";
+    public static final String ACCEPT = "accept";
+    public static final String SORT_KEY = "sortkey";
+    public static final String ACCOUNT_DETAILS = "accountdetails";
+    public static final String SERVICE_OFFERING_DETAILS = "serviceofferingdetails";
+    public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
+    public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
+    public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";
+    public static final String PROVIDER = "provider";
+    public static final String MANAGED = "managed";
+    public static final String CAPACITY_BYTES = "capacitybytes";
+    public static final String CAPACITY_IOPS = "capacityiops";
+    public static final String NETWORK_SPEED = "networkspeed";
+    public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
+    public static final String BROADCAST_URI = "broadcasturi";
+    public static final String ISOLATION_METHOD = "isolationmethod";
+    public static final String ISOLATION_METHODS = "isolationmethods";
+    public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
+    public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid";
+    public static final String ENABLE = "enable";
+    public static final String ENABLED = "enabled";
+    public static final String SERVICE_NAME = "servicename";
+    public static final String DHCP_RANGE = "dhcprange";
+    public static final String UUID = "uuid";
+    public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
+    public static final String LOCAL_STORAGE_ENABLED = "localstorageenabled";
+    public static final String GUEST_IP_TYPE = "guestiptype";
+    public static final String XENSERVER_NETWORK_LABEL = "xennetworklabel";
+    public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
+    public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
+    public static final String HYPERV_NETWORK_LABEL = "hypervnetworklabel";
+    public static final String OVM3_NETWORK_LABEL = "ovm3networklabel";
+    public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid";
+    public static final String SERVICE_LIST = "servicelist";
+    public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice";
+    public static final String SUPPORTED_SERVICES = "supportedservices";
+    public static final String NSP_ID = "nspid";
+    public static final String ACL_TYPE = "acltype";
+    public static final String ACL_REASON = "reason";
+    public static final String ACL_RULE_PARTIAL_UPGRADE = "partialupgrade";
+    public static final String SUBDOMAIN_ACCESS = "subdomainaccess";
+    public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid";
+    public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename";
+    public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate";
+    public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity";
+    public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated";
+    public static final String LOAD_BALANCER_RULE = "loadbalancerrule";
+    public static final String LOAD_BALANCER_RULE_LIST = "loadbalancerrulelist";
+    public static final String FIREWALL_DEVICE_ID = "fwdeviceid";
+    public static final String FIREWALL_DEVICE_NAME = "fwdevicename";
+    public static final String FIREWALL_DEVICE_STATE = "fwdevicestate";
+    public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity";
+    public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated";
+    public static final String SERVICE = "service";
+    public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
+    public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
+    public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
+    public static final String RESOURCE_STATE = "resourcestate";
+    public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired";
+    public static final String REQUIRED = "required";
+    public static final String RESTART_REQUIRED = "restartrequired";
+    public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
+    public static final String CONSERVE_MODE = "conservemode";
+    public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
+    public static final String KEYWORD = "keyword";
+    public static final String LIST_ALL = "listall";
+    public static final String SPECIFY_IP_RANGES = "specifyipranges";
+    public static final String IS_SOURCE_NAT = "issourcenat";
+    public static final String IS_STATIC_NAT = "isstaticnat";
+    public static final String SORT_BY = "sortby";
+    public static final String CHANGE_CIDR = "changecidr";
+    public static final String PURPOSE = "purpose";
+    public static final String IS_TAGGED = "istagged";
+    public static final String INSTANCE_NAME = "instancename";
+    public static final String START_VM = "startvm";
+    public static final String HA_HOST = "hahost";
+    public static final String CUSTOM_DISK_OFF_MIN_SIZE = "customdiskofferingminsize";
+    public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize";
+    public static final String DEFAULT_ZONE_ID = "defaultzoneid";
+    public static final String LIVE_MIGRATE = "livemigrate";
+    public static final String MIGRATE_TO = "migrateto";
+    public static final String GUID = "guid";
+    public static final String VSWITCH_TYPE_GUEST_TRAFFIC = "guestvswitchtype";
+    public static final String VSWITCH_TYPE_PUBLIC_TRAFFIC = "publicvswitchtype";
+    public static final String VSWITCH_NAME_GUEST_TRAFFIC = "guestvswitchname";
+    public static final String VSWITCH_NAME_PUBLIC_TRAFFIC = "publicvswitchname";
+    // Ovs controller
+    public static final String OVS_DEVICE_ID = "ovsdeviceid";
+    public static final String OVS_DEVICE_NAME = "ovsdevicename";
+    // OpenDaylight controller
+    public static final String ODL_DEVICE_ID = "odldeviceid";
+    public static final String ODL_DEVICE_NAME = "odldevicename";
+    public static final String ODL_TRANSPORT_ZONE_UUID = "transportzoneuuid";
+    public static final String ODL_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
+
+    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid";
+    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename";
+    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate";
+    // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this
+    // later.
+    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity";
+    public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
+    public static final String VSM_USERNAME = "vsmusername";
+    public static final String VSM_PASSWORD = "vsmpassword";
+    public static final String VSM_IPADDRESS = "vsmipaddress";
+    public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid";
+    public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid";
+    public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid";
+    public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid";
+    public static final String VSM_DOMAIN_ID = "vsmdomainid";
+    public static final String VSM_CONFIG_MODE = "vsmconfigmode";
+    public static final String VSM_CONFIG_STATE = "vsmconfigstate";
+    public static final String VSM_DEVICE_STATE = "vsmdevicestate";
+    public static final String VCENTER = "vcenter";
+    public static final String ADD_VSM_FLAG = "addvsmflag";
+    public static final String END_POINT = "endpoint";
+    public static final String REGION_ID = "regionid";
+    public static final String VPC_OFF_ID = "vpcofferingid";
+    public static final String NETWORK = "network";
+    public static final String VPC_ID = "vpcid";
+    public static final String GATEWAY_ID = "gatewayid";
+    public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
+    public static final String RESOURCE_IDS = "resourceids";
+    public static final String RESOURCE_ID = "resourceid";
+    public static final String CUSTOMER = "customer";
+    public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid";
+    public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid";
+    public static final String IPSEC_PSK = "ipsecpsk";
+    public static final String GUEST_IP = "guestip";
+    public static final String REMOVED = "removed";
+    public static final String COMPLETED = "completed";
+    public static final String IKE_POLICY = "ikepolicy";
+    public static final String ESP_POLICY = "esppolicy";
+    public static final String IKE_LIFETIME = "ikelifetime";
+    public static final String ESP_LIFETIME = "esplifetime";
+    public static final String DPD = "dpd";
+    public static final String FORCE_ENCAP = "forceencap";
+    public static final String FOR_VPC = "forvpc";
+    public static final String SHRINK_OK = "shrinkok";
+    public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
+    public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid";
+    public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
+    public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
+    public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
+    public static final String NSX_LOGICAL_SWITCH = "nsxlogicalswitch";
+    public static final String NSX_LOGICAL_SWITCH_PORT = "nsxlogicalswitchport";
+    public static final String S3_ACCESS_KEY = "accesskey";
+    public static final String S3_SECRET_KEY = "secretkey";
+    public static final String S3_END_POINT = "endpoint";
+    public static final String S3_BUCKET_NAME = "bucket";
+    public static final String S3_SIGNER = "s3signer";
+    public static final String S3_V3_SIGNER = "S3SignerType";
+    public static final String S3_V4_SIGNER = "AWSS3V4SignerType";
+    public static final String S3_HTTPS_FLAG = "usehttps";
+    public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
+    public static final String S3_CONNECTION_TTL = "connectionttl";
+    public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
+    public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
+    public static final String S3_USE_TCP_KEEPALIVE = "usetcpkeepalive";
+    public static final String INCL_ZONES = "includezones";
+    public static final String EXCL_ZONES = "excludezones";
+    public static final String SOURCE = "source";
+    public static final String COUNTER_ID = "counterid";
+    public static final String AGGR_OPERATOR = "aggroperator";
+    public static final String AGGR_FUNCTION = "aggrfunction";
+    public static final String AGGR_VALUE = "aggrvalue";
+    public static final String THRESHOLD = "threshold";
+    public static final String RELATIONAL_OPERATOR = "relationaloperator";
+    public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams";
+    public static final String MIN_MEMBERS = "minmembers";
+    public static final String MAX_MEMBERS = "maxmembers";
+    public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod";
+    public static final String VMPROFILE_ID = "vmprofileid";
+    public static final String VMGROUP_ID = "vmgroupid";
+    public static final String CS_URL = "csurl";
+    public static final String IDP_ID = "idpid";
+    public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids";
+    public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids";
+    public static final String SCALEUP_POLICIES = "scaleuppolicies";
+    public static final String SCALEDOWN_POLICIES = "scaledownpolicies";
+    public static final String INTERVAL = "interval";
+    public static final String QUIETTIME = "quiettime";
+    public static final String ACTION = "action";
+    public static final String CONDITION_ID = "conditionid";
+    public static final String CONDITION_IDS = "conditionids";
+    public static final String COUNTERPARAM_LIST = "counterparam";
+    public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
+    public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
+    public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
+    public static final String UCS_DN = "ucsdn";
+    public static final String GSLB_PROVIDER = "gslbprovider";
+    public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
+    public static final String GSLB_PROVIDER_PUBLIC_IP = "gslbproviderpublicip";
+    public static final String GSLB_PROVIDER_PRIVATE_IP = "gslbproviderprivateip";
+    public static final String VM_SNAPSHOT_DESCRIPTION = "description";
+    public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
+    public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
+    public static final String VM_SNAPSHOT_IDS = "vmsnapshotids";
+    public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
+    public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
+    public static final String VM_SNAPSHOT_QUIESCEVM = "quiescevm";
+    public static final String IMAGE_STORE_UUID = "imagestoreuuid";
+    public static final String GUEST_VM_CIDR = "guestvmcidr";
+    public static final String NETWORK_CIDR = "networkcidr";
+    public static final String RESERVED_IP_RANGE = "reservediprange";
+    public static final String UCS_MANAGER_ID = "ucsmanagerid";
+    public static final String UCS_PROFILE_DN = "profiledn";
+    public static final String UCS_BLADE_DN = "bladedn";
+    public static final String UCS_BLADE_ID = "bladeid";
+    public static final String VM_GUEST_IP = "vmguestip";
+    public static final String HEALTHCHECK_RESPONSE_TIMEOUT = "responsetimeout";
+    public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime";
+    public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold";
+    public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold";
+    public static final String HEALTHCHECK_PINGPATH = "pingpath";
+    public static final String SOURCE_PORT = "sourceport";
+    public static final String INSTANCE_PORT = "instanceport";
+    public static final String SOURCE_IP = "sourceipaddress";
+    public static final String SOURCE_IP_NETWORK_ID = "sourceipaddressnetworkid";
+    public static final String SCHEME = "scheme";
+    public static final String PROVIDER_TYPE = "providertype";
+    public static final String AFFINITY_GROUP_IDS = "affinitygroupids";
+    public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames";
+    public static final String ASA_INSIDE_PORT_PROFILE = "insideportprofile";
+    public static final String AFFINITY_GROUP_ID = "affinitygroupid";
+    public static final String DEPLOYMENT_PLANNER = "deploymentplanner";
+    public static final String ACL_ID = "aclid";
+    public static final String NUMBER = "number";
+    public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable";
+    public static final String ROUTING = "isrouting";
+    public static final String MAX_CONNECTIONS = "maxconnections";
+    public static final String SERVICE_STATE = "servicestate";
+
+    public static final String IAM_GROUPS = "groups";
+    public static final String ENTITY_TYPE = "entitytype";
+    public static final String ENTITY_ID = "entityid";
+    public static final String EXTERNAL_ID = "externalid";
+    public static final String ACCESS_TYPE = "accesstype";
+
+    public static final String RESOURCE_DETAILS = "resourcedetails";
+    public static final String EXPUNGE = "expunge";
+    public static final String FOR_DISPLAY = "fordisplay";
+    public static final String PASSIVE = "passive";
+    public static final String VERSION = "version";
+    public static final String START = "start";
+    public static final String GPUGROUP = "gpugroup";
+    public static final String GPUGROUPNAME = "gpugroupname";
+    public static final String VGPU = "vgpu";
+    public static final String VGPUTYPE = "vgputype";
+    public static final String VIDEORAM = "videoram";
+    public static final String MAXHEADS = "maxheads";
+    public static final String MAXRESOLUTIONX = "maxresolutionx";
+    public static final String MAXRESOLUTIONY = "maxresolutiony";
+    public static final String MAXVGPUPERPGPU = "maxvgpuperpgpu";
+    public static final String REMAININGCAPACITY = "remainingcapacity";
+    public static final String MAXCAPACITY = "maxcapacity";
+    public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
+    public static final String REDUNDANT_ROUTER = "redundantrouter";
+    public static final String REDUNDANT_VPC_ROUTER = "redundantvpcrouter";
+    public static final String READ_ONLY = "readonly";
+    public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc";
+    public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet";
+    public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
+    public static final String REGION_LEVEL_VPC = "regionlevelvpc";
+    public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
+    public static final String NETWORK_NAME = "networkname";
+    public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
+    public static final String METADATA = "metadata";
+    public static final String PHYSICAL_SIZE = "physicalsize";
+    public static final String OVM3_POOL = "ovm3pool";
+    public static final String OVM3_CLUSTER = "ovm3cluster";
+    public static final String OVM3_VIP = "ovm3vip";
+    public static final String CLEAN_UP_DETAILS = "cleanupdetails";
+    public static final String VIRTUAL_SIZE = "virtualsize";
+    public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
+    public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid";
+
+    public static final String ZONE_ID_LIST = "zoneids";
+    public static final String DESTINATION_ZONE_ID_LIST = "destzoneids";
+    public static final String ADMIN = "admin";
+    public static final String CHECKSUM_PARAMETER_PREFIX_DESCRIPTION = "The parameter containing the checksum will be considered a MD5sum if it is not prefixed\n"
+            + " and just a plain ascii/utf8 representation of a hexadecimal string. If it is required to\n"
+            + " use another algorithm the hexadecimal string is to be prefixed with a string of the form,\n"
+            + " \"{<algorithm>}\", not including the double quotes. In this <algorithm> is the exact string\n"
+            + " representing the java supported algorithm, i.e. MD5 or SHA-256. Note that java does not\n" + " contain an algorithm called SHA256 or one called sha-256, only SHA-256.";
+
+    public static final String HAS_ANNOTATION = "hasannotation";
+    public static final String LAST_ANNOTATED = "lastannotated";
+    public static final String LDAP_DOMAIN = "ldapdomain";
+
+    public static final String STDOUT = "stdout";
+    public static final String STDERR = "stderr";
+    public static final String EXITCODE = "exitcode";
+    public static final String TARGET_ID = "targetid";
+    public static final String VOLUME_IDS = "volumeids";
+
+    public enum HostDetails {
+        all, capacity, events, stats, min;
+    }
+
+    public enum VMDetails {
+        all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp;
+    }
+
+    public enum DomainDetails {
+        all, resource, min;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/ApiErrorCode.java b/api/src/main/java/org/apache/cloudstack/api/ApiErrorCode.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ApiErrorCode.java
rename to api/src/main/java/org/apache/cloudstack/api/ApiErrorCode.java
diff --git a/api/src/org/apache/cloudstack/api/ApiServerService.java b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ApiServerService.java
rename to api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
new file mode 100644
index 0000000..1c3822c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
@@ -0,0 +1,104 @@
+// 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.log4j.Logger;
+
+/**
+ * queryAsyncJobResult API command.
+ */
+public abstract class BaseAsyncCmd extends BaseCmd {
+
+    public static final String ipAddressSyncObject = "ipaddress";
+    public static final String networkSyncObject = "network";
+    public static final String vpcSyncObject = "vpc";
+    public static final String migrationSyncObject = "migration";
+    public static final String snapshotHostSyncObject = "snapshothost";
+    public static final String gslbSyncObject = "globalserverloadbalancer";
+    private static final Logger s_logger = Logger.getLogger(BaseAsyncCmd.class.getName());
+
+    private Object job;
+
+    @Parameter(name = "starteventid", type = CommandType.LONG)
+    private Long startEventId;
+
+    @Parameter(name = ApiConstants.CUSTOM_JOB_ID , type = CommandType.STRING)
+    private String injectedJobId;
+
+    public String getInjectedJobId() {
+        return this.injectedJobId;
+    }
+
+    /**
+     * For proper tracking of async commands through the system, events must be generated when the command is
+     * scheduled, started, and completed. Commands should specify the type of event so that when the scheduled,
+     * started, and completed events are saved to the events table, they have the proper type information.
+     *
+     * @return a string representing the type of event, e.g. VM.START, VOLUME.CREATE.
+     */
+    public abstract String getEventType();
+
+    /**
+     * For proper tracking of async commands through the system, events must be generated when the command is
+     * scheduled, started, and completed. Commands should specify a description for these events so that when
+     * the scheduled, started, and completed events are saved to the events table, they have a meaningful description.
+     *
+     * @return a string representing a description of the event
+     */
+    public abstract String getEventDescription();
+
+    public void setJob(Object job) {
+        this.job = job;
+    }
+
+    public Long getStartEventId() {
+        return startEventId;
+    }
+
+    public void setStartEventId(Long startEventId) {
+        this.startEventId = startEventId;
+    }
+
+    /**
+     * Async commands that want to be tracked as part of the listXXX commands need to
+     * provide implementations of the two following methods, getInstanceId() and getInstanceType()
+     *
+     * getObjectId() should return the id of the object the async command is executing on
+     * getObjectType() should return a type from the AsyncJob.Type enumeration
+     */
+    public Long getInstanceId() {
+        return null;
+    }
+
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.None;
+    }
+
+    public String getSyncObjType() {
+        return null;
+    }
+
+    public Long getSyncObjId() {
+        return null;
+    }
+
+    public Object getJob() {
+        return job;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCreateCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseAsyncCreateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseAsyncCustomIdCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseCustomIdCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseCustomIdCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListAccountResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListDomainResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListProjectAndAccountResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListTaggedResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListTaggedResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListTaggedResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListTaggedResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseListTemplateOrIsoPermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/BaseResponse.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseResponse.java
diff --git a/api/src/org/apache/cloudstack/api/BaseResponseWithTagInformation.java b/api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseResponseWithTagInformation.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
new file mode 100644
index 0000000..cd7aee7
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -0,0 +1,147 @@
+// 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.log4j.Logger;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+
+import java.util.Collection;
+import java.util.Map;
+
+public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateIsoCmd.class.getName());
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "true if image is bootable, false otherwise; available only for updateIso API")
+    private Boolean bootable;
+
+    @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if the template requres HVM, false otherwise; available only for updateTemplate API")
+    private Boolean requiresHvm;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the image", length = 4096)
+    private String displayText;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the image file")
+    private Long id;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the image file")
+    private String templateName;
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID,
+               type = CommandType.UUID,
+               entityType = GuestOSResponse.class,
+               description = "the ID of the OS type that best represents the OS of this image.")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, description = "the format for the image")
+    private String format;
+
+    @Parameter(name = ApiConstants.PASSWORD_ENABLED, type = CommandType.BOOLEAN, description = "true if the image supports the password reset feature; default is false")
+    private Boolean passwordEnabled;
+
+    @Parameter(name = ApiConstants.SSHKEY_ENABLED, type = CommandType.BOOLEAN, description = "true if the template supports the sshkey upload feature; default is false")
+    private Boolean sshKeyEnabled;
+
+    @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the template, integer")
+    private Integer sortKey;
+
+    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
+               type = CommandType.BOOLEAN,
+               description = "true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
+    private Boolean isDynamicallyScalable;
+
+    @Parameter(name = ApiConstants.ROUTING, type = CommandType.BOOLEAN, description = "true if the template type is routing i.e., if template is used to deploy router")
+    protected Boolean isRoutingType;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
+    protected Map details;
+
+    @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
+            type = CommandType.BOOLEAN,
+            description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
+    private Boolean cleanupDetails;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Boolean getBootable() {
+        return bootable;
+    }
+
+    public Boolean getRequiresHvm() {
+        return requiresHvm;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getTemplateName() {
+        return templateName;
+    }
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    public Boolean getPasswordEnabled() {
+        return passwordEnabled;
+    }
+
+    public Boolean isSshKeyEnabled() {
+        return sshKeyEnabled;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public Integer getSortKey() {
+        return sortKey;
+    }
+
+    public Boolean isDynamicallyScalable() {
+        return isDynamicallyScalable;
+    }
+
+    public Boolean isRoutingType() {
+        return isRoutingType;
+    }
+
+    public Map getDetails() {
+        if (this.details == null || this.details.isEmpty()) {
+            return null;
+        }
+
+        Collection paramsCollection = this.details.values();
+        return (Map) (paramsCollection.toArray())[0];
+    }
+
+    public boolean isCleanupDetails(){
+        return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoPermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/Displayable.java b/api/src/main/java/org/apache/cloudstack/api/Displayable.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/Displayable.java
rename to api/src/main/java/org/apache/cloudstack/api/Displayable.java
diff --git a/api/src/org/apache/cloudstack/api/EntityReference.java b/api/src/main/java/org/apache/cloudstack/api/EntityReference.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/EntityReference.java
rename to api/src/main/java/org/apache/cloudstack/api/EntityReference.java
diff --git a/api/src/org/apache/cloudstack/api/IBaseListAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/IBaseListAccountResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/IBaseListAccountResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/IBaseListAccountResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/IBaseListCmd.java b/api/src/main/java/org/apache/cloudstack/api/IBaseListCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/IBaseListCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/IBaseListCmd.java
diff --git a/api/src/org/apache/cloudstack/api/IBaseListDomainResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/IBaseListDomainResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/IBaseListDomainResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/IBaseListDomainResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/IBaseListProjectAndAccountResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/IBaseListProjectAndAccountResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/IBaseListProjectAndAccountResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/IBaseListProjectAndAccountResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/IBaseListTaggedResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/IBaseListTaggedResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/IBaseListTaggedResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/IBaseListTaggedResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/Identity.java b/api/src/main/java/org/apache/cloudstack/api/Identity.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/Identity.java
rename to api/src/main/java/org/apache/cloudstack/api/Identity.java
diff --git a/api/src/org/apache/cloudstack/api/InternalIdentity.java b/api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/InternalIdentity.java
rename to api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java
diff --git a/api/src/org/apache/cloudstack/api/LdapValidator.java b/api/src/main/java/org/apache/cloudstack/api/LdapValidator.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/LdapValidator.java
rename to api/src/main/java/org/apache/cloudstack/api/LdapValidator.java
diff --git a/api/src/org/apache/cloudstack/api/Parameter.java b/api/src/main/java/org/apache/cloudstack/api/Parameter.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/Parameter.java
rename to api/src/main/java/org/apache/cloudstack/api/Parameter.java
diff --git a/api/src/org/apache/cloudstack/api/ResourceDetail.java b/api/src/main/java/org/apache/cloudstack/api/ResourceDetail.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ResourceDetail.java
rename to api/src/main/java/org/apache/cloudstack/api/ResourceDetail.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
new file mode 100644
index 0000000..80d6d4b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -0,0 +1,469 @@
+// 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 java.text.DecimalFormat;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.ApiConstants.HostDetails;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
+import org.apache.cloudstack.api.response.CapacityResponse;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.ConditionResponse;
+import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.CounterResponse;
+import org.apache.cloudstack.api.response.CreateCmdResponse;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.EventResponse;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.FirewallResponse;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
+import org.apache.cloudstack.api.response.HostForMigrationResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
+import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
+import org.apache.cloudstack.api.response.IsolationMethodResponse;
+import org.apache.cloudstack.api.response.LBHealthCheckResponse;
+import org.apache.cloudstack.api.response.LBStickinessResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.LoadBalancerResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.api.response.NetworkACLResponse;
+import org.apache.cloudstack.api.response.NetworkOfferingResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.PortableIpRangeResponse;
+import org.apache.cloudstack.api.response.PortableIpResponse;
+import org.apache.cloudstack.api.response.PrivateGatewayResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import org.apache.cloudstack.api.response.ProjectInvitationResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ProviderResponse;
+import org.apache.cloudstack.api.response.RegionResponse;
+import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
+import org.apache.cloudstack.api.response.ResourceCountResponse;
+import org.apache.cloudstack.api.response.ResourceLimitResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
+import org.apache.cloudstack.api.response.SSHKeyPairResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.ServiceResponse;
+import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
+import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
+import org.apache.cloudstack.api.response.StaticRouteResponse;
+import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.TrafficMonitorResponse;
+import org.apache.cloudstack.api.response.TrafficTypeResponse;
+import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
+import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
+import org.apache.cloudstack.api.response.VlanIpRangeResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.VpcOfferingResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.VpnUsersResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpRange;
+import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.usage.Usage;
+
+import com.cloud.capacity.Capacity;
+import com.cloud.configuration.ResourceCount;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.StorageNetworkIpRange;
+import com.cloud.dc.Vlan;
+import com.cloud.domain.Domain;
+import com.cloud.event.Event;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.HypervisorCapabilities;
+import com.cloud.network.GuestVlan;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.OvsProvider;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteCustomerGateway;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnGateway;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.VpnUser;
+import com.cloud.network.as.AutoScalePolicy;
+import com.cloud.network.as.AutoScaleVmGroup;
+import com.cloud.network.as.AutoScaleVmProfile;
+import com.cloud.network.as.Condition;
+import com.cloud.network.as.Counter;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.HealthCheckPolicy;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.StickinessPolicy;
+import com.cloud.network.security.SecurityGroup;
+import com.cloud.network.security.SecurityRule;
+import com.cloud.network.vpc.NetworkACL;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcOffering;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.org.Cluster;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectAccount;
+import com.cloud.projects.ProjectInvitation;
+import com.cloud.region.ha.GlobalLoadBalancerRule;
+import com.cloud.server.ResourceTag;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.ImageStore;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.snapshot.SnapshotPolicy;
+import com.cloud.storage.snapshot.SnapshotSchedule;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.SSHKeyPair;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.net.Ip;
+import com.cloud.vm.InstanceGroup;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.snapshot.VMSnapshot;
+
+public interface ResponseGenerator {
+    UserResponse createUserResponse(UserAccount user);
+
+    AccountResponse createAccountResponse(ResponseView view, Account account);
+
+    DomainResponse createDomainResponse(Domain domain);
+
+    DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering);
+
+    ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit);
+
+    ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount);
+
+    ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering);
+
+    ConfigurationResponse createConfigurationResponse(Configuration cfg);
+
+    SnapshotResponse createSnapshotResponse(Snapshot snapshot);
+
+    SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy);
+
+    List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms);
+
+    List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms);
+
+    SystemVmResponse createSystemVmResponse(VirtualMachine systemVM);
+
+    DomainRouterResponse createDomainRouterResponse(VirtualRouter router);
+
+    HostResponse createHostResponse(Host host, EnumSet<HostDetails> details);
+
+    HostResponse createHostResponse(Host host);
+
+    HostForMigrationResponse createHostForMigrationResponse(Host host);
+
+    HostForMigrationResponse createHostForMigrationResponse(Host host, EnumSet<HostDetails> details);
+
+    VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan);
+
+    VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan);
+
+    IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddress);
+
+    GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result);
+
+    GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule);
+
+    LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer);
+
+    LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb);
+
+    LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb);
+
+    LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb);
+
+    LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb);
+
+    PodResponse createPodResponse(Pod pod, Boolean showCapacities);
+
+    ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities);
+
+    VolumeResponse createVolumeResponse(ResponseView view, Volume volume);
+
+    InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group);
+
+    StoragePoolResponse createStoragePoolResponse(StoragePool pool);
+
+    StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool);
+
+    ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities);
+
+    FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule);
+
+    IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule);
+
+    User findUserById(Long userId);
+
+    UserVm findUserVmById(Long vmId);
+
+    Volume findVolumeById(Long volumeId);
+
+    Account findAccountByNameDomain(String accountName, Long domainId);
+
+    VirtualMachineTemplate findTemplateById(Long templateId);
+
+    Host findHostById(Long hostId);
+
+    DiskOffering findDiskOfferingById(Long diskOfferingId);
+
+    VpnUsersResponse createVpnUserResponse(VpnUser user);
+
+    RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn);
+
+    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly);
+
+    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly);
+
+    SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules);
+
+    SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group);
+
+    ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
+
+    ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
+
+    String toSerializedString(CreateCmdResponse response, String responseType);
+
+    EventResponse createEventResponse(Event event);
+
+    TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result);
+
+    List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
+                                                   Long zoneId, boolean readyOnly);
+
+    List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
+                                                   List<Long> zoneIds, boolean readyOnly);
+
+    List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format);
+
+    TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id);
+
+    AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd);
+
+    NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering);
+
+    NetworkResponse createNetworkResponse(ResponseView view, Network network);
+
+    UserResponse createUserResponse(User user);
+
+    AccountResponse createUserAccountResponse(ResponseView view, UserAccount user);
+
+    Long getSecurityGroupId(String groupName, long accountId);
+
+    List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId, boolean readyOnly);
+
+    ProjectResponse createProjectResponse(Project project);
+
+    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long vmId);
+
+    FirewallResponse createFirewallResponse(FirewallRule fwRule);
+
+    HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities);
+
+    ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount);
+
+    ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite);
+
+    SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine systemVM);
+
+    PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result);
+
+    ServiceResponse createNetworkServiceResponse(Service service);
+
+    ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result);
+
+    TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result);
+
+    VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result);
+
+    OvsProviderResponse createOvsProviderResponse(OvsProvider result);
+
+    StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result);
+
+    RegionResponse createRegionResponse(Region region);
+
+    ImageStoreResponse createImageStoreResponse(ImageStore os);
+
+    /**
+     * @param resourceTag
+     * @param keyValueOnly TODO
+     * @return
+     */
+    ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly);
+
+    Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result);
+
+    /**
+     * @param offering
+     * @return
+     */
+    VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering);
+
+    /**
+     * @param vpc
+     * @return
+     */
+    VpcResponse createVpcResponse(ResponseView view, Vpc vpc);
+
+    /**
+     * @param networkACLItem
+     * @return
+     */
+    NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem networkACLItem);
+
+    /**
+     * @param networkACL
+     * @return
+     */
+    NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL);
+
+    /**
+     * @param result
+     * @return
+     */
+    PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result);
+
+    /**
+     * @param result
+     * @return
+     */
+    StaticRouteResponse createStaticRouteResponse(StaticRoute result);
+
+    Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result);
+
+    Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result);
+
+    CounterResponse createCounterResponse(Counter ctr);
+
+    ConditionResponse createConditionResponse(Condition cndn);
+
+    AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy);
+
+    AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile);
+
+    AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup);
+
+    GuestOSResponse createGuestOSResponse(GuestOS os);
+
+    GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
+
+    SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
+
+    UsageRecordResponse createUsageResponse(Usage usageRecord);
+
+    UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap);
+
+    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags();
+
+    TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
+
+    VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
+
+    NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result);
+
+    public NicResponse createNicResponse(Nic result);
+
+    ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances);
+
+    AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);
+
+    Long getAffinityGroupId(String name, long entityOwnerId);
+
+    PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange range);
+
+    PortableIpResponse createPortableIPResponse(PortableIp portableIp);
+
+    InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result);
+
+    IsolationMethodResponse createIsolationMethodResponse(IsolationType method);
+
+    ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds);
+
+    SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
+
+    ManagementServerResponse createManagementResponse(ManagementServerHost mgmt);
+}
diff --git a/api/src/org/apache/cloudstack/api/ResponseObject.java b/api/src/main/java/org/apache/cloudstack/api/ResponseObject.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ResponseObject.java
rename to api/src/main/java/org/apache/cloudstack/api/ResponseObject.java
diff --git a/api/src/org/apache/cloudstack/api/ServerApiException.java b/api/src/main/java/org/apache/cloudstack/api/ServerApiException.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/ServerApiException.java
rename to api/src/main/java/org/apache/cloudstack/api/ServerApiException.java
diff --git a/api/src/org/apache/cloudstack/api/Validate.java b/api/src/main/java/org/apache/cloudstack/api/Validate.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/Validate.java
rename to api/src/main/java/org/apache/cloudstack/api/Validate.java
diff --git a/api/src/org/apache/cloudstack/api/auth/APIAuthenticationManager.java b/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/auth/APIAuthenticationManager.java
rename to api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationManager.java
diff --git a/api/src/org/apache/cloudstack/api/auth/APIAuthenticationType.java b/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/auth/APIAuthenticationType.java
rename to api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticationType.java
diff --git a/api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java b/api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticator.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/auth/APIAuthenticator.java
rename to api/src/main/java/org/apache/cloudstack/api/auth/APIAuthenticator.java
diff --git a/api/src/org/apache/cloudstack/api/auth/PluggableAPIAuthenticator.java b/api/src/main/java/org/apache/cloudstack/api/auth/PluggableAPIAuthenticator.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/auth/PluggableAPIAuthenticator.java
rename to api/src/main/java/org/apache/cloudstack/api/auth/PluggableAPIAuthenticator.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/DeleteAccountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/EnableAccountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/ListAccountsCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/account/LockAccountCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
new file mode 100644
index 0000000..43377da
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.account;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.response.RoleResponse;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.region.RegionService;
+
+import com.cloud.user.Account;
+
+@APICommand(name = "updateAccount", description = "Updates account information for the authenticated user", responseObject = AccountResponse.class, entityType = {Account.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpdateAccountCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateAccountCmd.class.getName());
+    private static final String s_name = "updateaccountresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account UUID")
+    private Long id;
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Current account name")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "The UUID of the domain where the account exists")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "The UUID of the dynamic role to set for the account")
+    private Long roleId;
+
+    @Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, description = "New name for the account")
+    private String newName;
+
+    @Parameter(name = ApiConstants.NETWORK_DOMAIN,
+               type = CommandType.STRING,
+               description = "Network domain for the account's networks; empty string will update domainName with NULL value")
+    private String networkDomain;
+
+    @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "Details for the account used to store specific parameters")
+    private Map details;
+
+    @Inject
+    RegionService _regionService;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getRoleId() { return roleId; }
+
+    public String getNewName() {
+        return newName;
+    }
+
+    public String getNetworkDomain() {
+        return networkDomain;
+    }
+
+    public Map getDetails() {
+        if (details == null || details.isEmpty()) {
+            return null;
+        }
+
+        Collection paramsCollection = details.values();
+        Map params = (Map)(paramsCollection.toArray())[0];
+        return params;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = _entityMgr.findById(Account.class, getId());
+        if (account != null) {
+            return account.getAccountId();
+        }
+        account = _accountService.getActiveAccountByName(getAccountName(), getDomainId());
+        if (account != null) {
+            return account.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        Account result = _regionService.updateAccount(this);
+        if (result != null){
+            AccountResponse response = _responseGenerator.createAccountResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update account");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRoleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/ListRolePermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolePermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/ListRolePermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolePermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/ListRolesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/RoleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRoleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/address/AssociateIPAddrCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/address/ListPublicIpAddressesCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/affinitygroup/UpdateVMAffinityGroupCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/ListAnnotationsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/annotation/RemoveAnnotationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ca/ListCAProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ListCAProvidersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ca/ListCAProvidersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ListCAProvidersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ca/ListCaCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ListCaCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ca/ListCaCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ListCaCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ca/RevokeCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/DeleteClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/ListDeploymentPlannersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListDeploymentPlannersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/config/ListDeploymentPlannersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListDeploymentPlannersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListHypervisorCapabilitiesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateHypervisorCapabilitiesCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
new file mode 100644
index 0000000..03d6039
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
@@ -0,0 +1,172 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.diagnostics;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiArgValidator;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.RunDiagnosticsResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.diagnostics.DiagnosticsService;
+import org.apache.cloudstack.diagnostics.DiagnosticsType;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = RunDiagnosticsCmd.APINAME, responseObject = RunDiagnosticsResponse.class, entityType = {VirtualMachine.class},
+        responseHasSensitiveInfo = false,
+        requestHasSensitiveInfo = false,
+        description = "Execute network-utility command (ping/arping/tracert) on system VMs remotely",
+        authorized = {RoleType.Admin},
+        since = "4.12.0.0")
+public class RunDiagnosticsCmd extends BaseAsyncCmd {
+    private static final Logger LOGGER = Logger.getLogger(RunDiagnosticsCmd.class);
+    public static final String APINAME = "runDiagnostics";
+
+    @Inject
+    private DiagnosticsService diagnosticsService;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = SecurityChecker.AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.TARGET_ID, type = CommandType.UUID, required = true, entityType = SystemVmResponse.class,
+            validations = {ApiArgValidator.PositiveNumber},
+            description = "The ID of the system VM instance to diagnose")
+    private Long id;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true,
+            validations = {ApiArgValidator.NotNullOrEmpty},
+            description = "The IP/Domain address to test connection to")
+    private String address;
+
+    @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, required = true,
+            validations = {ApiArgValidator.NotNullOrEmpty},
+            description = "The system VM diagnostics type  valid options are: ping, traceroute, arping")
+    private String type;
+
+    @Parameter(name = ApiConstants.PARAMS, type = CommandType.STRING,
+            authorized = {RoleType.Admin},
+            description = "Additional command line options that apply for each command")
+    private String optionalArguments;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+    public Long getId() {
+        return id;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public DiagnosticsType getType() {
+        DiagnosticsType diagnosticsType = DiagnosticsType.getCommand(type);
+        if (diagnosticsType == null) {
+            throw new IllegalArgumentException(type + " Is not a valid diagnostics command type. ");
+        }
+        return diagnosticsType;
+    }
+
+    public String getOptionalArguments() {
+        return optionalArguments;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////////// Implementation //////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        VirtualMachine.Type vmType = _entityMgr.findById(VirtualMachine.class, getId()).getType();
+        String eventType = "";
+        switch (vmType) {
+            case ConsoleProxy:
+                eventType =  EventTypes.EVENT_PROXY_DIAGNOSTICS;
+            break;
+            case SecondaryStorageVm:
+                eventType = EventTypes.EVENT_SSVM_DIAGNOSTICS;
+                break;
+            case DomainRouter:
+                eventType = EventTypes.EVENT_ROUTER_DIAGNOSTICS;
+                break;
+        }
+        return eventType;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.SystemVm;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Executing diagnostics on system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException {
+        RunDiagnosticsResponse response = new RunDiagnosticsResponse();
+        try {
+            final Map<String, String> answerMap = diagnosticsService.runDiagnosticsCommand(this);
+            if (CollectionUtils.isNotEmpty(Collections.singleton(answerMap))) {
+                response.setStdout(answerMap.get(ApiConstants.STDOUT));
+                response.setStderr(answerMap.get(ApiConstants.STDERR));
+                response.setExitCode(answerMap.get(ApiConstants.EXITCODE));
+                response.setObjectName("diagnostics");
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            }
+        } catch (final ServerApiException e) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        }
+    }
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainChildrenCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/ListHostHAProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ListHostHAProvidersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/ListHostHAProvidersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ListHostHAProvidersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/ha/ListHostHAResourcesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ListHostHAResourcesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/ha/ListHostHAResourcesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ListHostHAResourcesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/CancelMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelMaintenanceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/CancelMaintenanceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelMaintenanceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeleteHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostTagsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/PrepareForMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForMaintenanceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/PrepareForMaintenanceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForMaintenanceCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
new file mode 100644
index 0000000..34e439f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
@@ -0,0 +1,116 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.host;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "reconnectHost", description = "Reconnects a host.", responseObject = HostResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ReconnectHostCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ReconnectHostCmd.class.getName());
+
+    private static final String s_name = "reconnecthostresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "host";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_HOST_RECONNECT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "reconnecting host: " + getId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Host;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        try {
+            Host result = _resourceService.reconnectHost(this);
+            HostResponse response = _responseGenerator.createHostResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        } catch (CloudRuntimeException e) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        } catch (AgentUnavailableException e) {
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, e.getMessage());
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostPasswordCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ListInternalLoadBalancerElementsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/AttachIsoCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/CopyIsoCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/DetachIsoCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/ListIsosCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsosCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/ListIsosCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsosCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/RegisterIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/RegisterIsoCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/RegisterIsoCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/RegisterIsoCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/iso/UpdateIsoCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/UpdateIsoCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/iso/UpdateIsoCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/iso/UpdateIsoCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/loadbalancer/ListLoadBalancerRuleInstancesCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java
new file mode 100644
index 0000000..1be4919
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java
@@ -0,0 +1,79 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.management;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
+import org.apache.log4j.Logger;
+
+@APICommand(name = ListMgmtsCmd.APINAME, description = "Lists management servers.", responseObject = ManagementServerResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListMgmtsCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(ListMgmtsCmd.class.getName());
+
+    public static final String APINAME = "listManagementServers";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, description = "the id of the management server")
+    private Long id;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the management server")
+    private String hostName;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Host;
+    }
+
+    @Override
+    public void execute() {
+        ListResponse<ManagementServerResponse> response = _queryService.listManagementServers(this);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkDeviceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
new file mode 100644
index 0000000..2dfd749
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
@@ -0,0 +1,77 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.network;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.response.NetworkResponse;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.network.Network;
+
+@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateNetworkCmdByAdmin.class.getName());
+
+    @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
+    private String vlan;
+
+    @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared and L2 networks")
+    private Boolean bypassVlanOverlapCheck;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getVlan() {
+        return vlan;
+    }
+
+    public Boolean getBypassVlanOverlapCheck() {
+        if (bypassVlanOverlapCheck != null) {
+            return bypassVlanOverlapCheck;
+        }
+        return false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    // an exception thrown by createNetwork() will be caught by the dispatcher.
+    public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{
+        Network result = _networkService.createGuestNetwork(this);
+        if (result != null) {
+            NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        }else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateStorageNetworkIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateGuestVlanRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkDeviceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkDeviceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkDeviceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkDeviceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListDedicatedGuestVlanRangesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkDeviceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkIsolationMethodsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkIsolationMethodsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkIsolationMethodsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkIsolationMethodsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworkServiceProvidersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListNetworksCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListPhysicalNetworksCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListSupportedNetworkServicesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/ReleaseDedicatedGuestVlanRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkServiceProviderCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdatePhysicalNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateStorageNetworkIpRangeCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
new file mode 100644
index 0000000..469f714
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
@@ -0,0 +1,262 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.offering;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+
+@APICommand(name = "createDiskOffering", description = "Creates a disk offering.", responseObject = DiskOfferingResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateDiskOfferingCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateDiskOfferingCmd.class.getName());
+
+    private static final String s_name = "creatediskofferingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.DISK_SIZE, type = CommandType.LONG, required = false, description = "size of the disk offering in GB (1GB = 1,073,741,824 bytes)")
+    private Long diskSize;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "alternate display text of the disk offering", length = 4096)
+    private String displayText;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the disk offering")
+    private String offeringName;
+
+    @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "tags for the disk offering", length = 4096)
+    private String tags;
+
+    @Parameter(name = ApiConstants.CUSTOMIZED, type = CommandType.BOOLEAN, description = "whether disk offering size is custom or not")
+    private Boolean customized;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "the ID of the containing domain, null for public offerings")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the disk offering. Values are local and shared.")
+    private String storageType = ServiceOffering.StorageType.shared.toString();
+
+    @Parameter(name = ApiConstants.PROVISIONINGTYPE,
+            type = CommandType.STRING,
+            description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
+    private String provisioningType = ProvisioningType.THIN.toString();
+
+    @Parameter(name = ApiConstants.DISPLAY_OFFERING,
+            type = CommandType.BOOLEAN,
+            description = "an optional field, whether to display the offering to the end user or not.")
+    private Boolean displayOffering;
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
+    private Long bytesReadRate;
+
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering")
+    private Long bytesReadRateMax;
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long bytesReadRateMaxLength;
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering")
+    private Long bytesWriteRateMax;
+
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long bytesWriteRateMaxLength;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering")
+    private Long iopsReadRateMax;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long iopsReadRateMaxLength;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
+    private Long iopsWriteRate;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering")
+    private Long iopsWriteRateMax;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long iopsWriteRateMaxLength;
+
+    @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether disk offering iops is custom or not")
+    private Boolean customizedIops;
+
+    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the disk offering")
+    private Long minIops;
+
+    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the disk offering")
+    private Long maxIops;
+
+    @Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
+            type = CommandType.INTEGER,
+            required = false,
+            description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)")
+    private Integer hypervisorSnapshotReserve;
+
+/////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getDiskSize() {
+        return diskSize;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public String getOfferingName() {
+        return offeringName;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public Boolean isCustomized() {
+        return customized;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public Long getBytesReadRateMax() {
+        return bytesReadRateMax;
+    }
+
+    public Long getBytesReadRateMaxLength() {
+        return bytesReadRateMaxLength;
+    }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public Long getBytesWriteRateMax() {
+        return bytesWriteRateMax;
+    }
+
+    public Long getBytesWriteRateMaxLength() {
+        return bytesWriteRateMaxLength;
+    }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public Long getIopsReadRateMax() {
+        return iopsReadRateMax;
+    }
+
+    public Long getIopsReadRateMaxLength() {
+        return iopsReadRateMaxLength;
+    }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public Long getIopsWriteRateMax() {
+        return iopsWriteRateMax;
+    }
+
+    public Long getIopsWriteRateMaxLength() {
+        return iopsWriteRateMaxLength;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public String getProvisioningType(){
+        return provisioningType;
+    }
+
+    public Boolean getDisplayOffering() {
+        return displayOffering;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        DiskOffering offering = _configService.createDiskOffering(this);
+        if (offering != null) {
+            DiskOfferingResponse response = _responseGenerator.createDiskOfferingResponse(offering);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create disk offering");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
new file mode 100644
index 0000000..ed87ad8
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -0,0 +1,344 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.offering;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.cloud.storage.Storage;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+
+@APICommand(name = "createServiceOffering", description = "Creates a service offering.", responseObject = ServiceOfferingResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateServiceOfferingCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateServiceOfferingCmd.class.getName());
+    private static final String s_name = "createserviceofferingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.CPU_NUMBER, type = CommandType.INTEGER, required = false, description = "the CPU number of the service offering")
+    private Integer cpuNumber;
+
+    @Parameter(name = ApiConstants.CPU_SPEED, type = CommandType.INTEGER, required = false, description = "the CPU speed of the service offering in MHz.")
+    private Integer cpuSpeed;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of the service offering")
+    private String displayText;
+
+    @Parameter(name = ApiConstants.PROVISIONINGTYPE, type = CommandType.STRING, description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
+    private String provisioningType = Storage.ProvisioningType.THIN.toString();
+
+    @Parameter(name = ApiConstants.MEMORY, type = CommandType.INTEGER, required = false, description = "the total memory of the service offering in MB")
+    private Integer memory;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the service offering")
+    private String serviceOfferingName;
+
+    @Parameter(name = ApiConstants.OFFER_HA, type = CommandType.BOOLEAN, description = "the HA for the service offering")
+    private Boolean offerHa;
+
+    @Parameter(name = ApiConstants.LIMIT_CPU_USE, type = CommandType.BOOLEAN, description = "restrict the CPU usage to committed service offering")
+    private Boolean limitCpuUse;
+
+    @Parameter(name = ApiConstants.IS_VOLATILE,
+               type = CommandType.BOOLEAN,
+               description = "true if the virtual machine needs to be volatile so that on every reboot of VM, original root disk is dettached then destroyed and a fresh root disk is created and attached to VM")
+    private Boolean isVolatile;
+
+    @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the service offering. Values are local and shared.")
+    private String storageType;
+
+    @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for this service offering.")
+    private String tags;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "the ID of the containing domain, null for public offerings")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.STRING, description = "the host tag for this service offering.")
+    private String hostTag;
+
+    @Parameter(name = ApiConstants.IS_SYSTEM_OFFERING, type = CommandType.BOOLEAN, description = "is this a system vm offering")
+    private Boolean isSystem;
+
+    @Parameter(name = ApiConstants.SYSTEM_VM_TYPE,
+               type = CommandType.STRING,
+               description = "the system VM type. Possible types are \"domainrouter\", \"consoleproxy\" and \"secondarystoragevm\".")
+    private String systemVmType;
+
+    @Parameter(name = ApiConstants.NETWORKRATE,
+               type = CommandType.INTEGER,
+               description = "data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
+    private Integer networkRate;
+
+    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER,
+               type = CommandType.STRING,
+               description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
+    private String deploymentPlanner;
+
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
+    private Map details;
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
+    private Long bytesReadRate;
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes read rate of the disk offering")
+    private Long bytesReadRateMax;
+
+    @Parameter(name = ApiConstants.BYTES_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long bytesReadRateMaxLength;
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst bytes write rate of the disk offering")
+    private Long bytesWriteRateMax;
+
+    @Parameter(name = ApiConstants.BYTES_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long bytesWriteRateMaxLength;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX, type = CommandType.LONG, required = false, description = "burst requests read rate of the disk offering")
+    private Long iopsReadRateMax;
+
+    @Parameter(name = ApiConstants.IOPS_READ_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long iopsReadRateMaxLength;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
+    private Long iopsWriteRate;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX, type = CommandType.LONG, required = false, description = "burst io requests write rate of the disk offering")
+    private Long iopsWriteRateMax;
+
+    @Parameter(name = ApiConstants.IOPS_WRITE_RATE_MAX_LENGTH, type = CommandType.LONG, required = false, description = "length (in seconds) of the burst")
+    private Long iopsWriteRateMaxLength;
+
+    @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not", since = "4.4")
+    private Boolean customizedIops;
+
+    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the compute offering", since = "4.4")
+    private Long minIops;
+
+    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the compute offering", since = "4.4")
+    private Long maxIops;
+
+    @Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
+            type = CommandType.INTEGER,
+            required = false,
+            description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)",
+            since = "4.4")
+    private Integer hypervisorSnapshotReserve;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Integer getCpuNumber() {
+        return cpuNumber;
+    }
+
+    public Integer getCpuSpeed() {
+        return cpuSpeed;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public String getProvisioningType(){
+        return provisioningType;
+    }
+
+    public Integer getMemory() {
+        return memory;
+    }
+
+    public String getServiceOfferingName() {
+        return serviceOfferingName;
+    }
+
+    public Boolean isOfferHa() {
+        return offerHa == null ? Boolean.FALSE : offerHa;
+    }
+
+    public Boolean isLimitCpuUse() {
+        return limitCpuUse == null ? Boolean.FALSE : limitCpuUse;
+    }
+
+    public Boolean isVolatileVm() {
+        return isVolatile == null ? Boolean.FALSE : isVolatile;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    public Boolean isSystem() {
+        return isSystem == null ? false : isSystem;
+    }
+
+    public String getSystemVmType() {
+        return systemVmType;
+    }
+
+    public Integer getNetworkRate() {
+        return networkRate;
+    }
+
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public boolean isCustomized() {
+        return (cpuNumber == null || memory == null || cpuSpeed == null);
+    }
+
+    public Map<String, String> getDetails() {
+        Map<String, String> detailsMap = null;
+        if (details != null && !details.isEmpty()) {
+            detailsMap = new HashMap<String, String>();
+            Collection<?> props = details.values();
+            Iterator<?> iter = props.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> detail = (HashMap<String, String>) iter.next();
+                detailsMap.put(detail.get("key"), detail.get("value"));
+            }
+        }
+        return detailsMap;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public Long getBytesReadRateMax() {
+        return bytesReadRateMax;
+    }
+
+    public Long getBytesReadRateMaxLength() {
+        return bytesReadRateMaxLength;
+    }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public Long getBytesWriteRateMax() {
+        return bytesWriteRateMax;
+    }
+
+    public Long getBytesWriteRateMaxLength() {
+        return bytesWriteRateMaxLength;
+    }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public Long getIopsReadRateMax() {
+        return iopsReadRateMax;
+    }
+
+    public Long getIopsReadRateMaxLength() {
+        return iopsReadRateMaxLength;
+    }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public Long getIopsWriteRateMax() {
+        return iopsWriteRateMax;
+    }
+
+    public Long getIopsWriteRateMaxLength() {
+        return iopsWriteRateMaxLength;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        ServiceOffering result = _configService.createServiceOffering(this);
+        if (result != null) {
+            ServiceOfferingResponse response = _responseGenerator.createServiceOfferingResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create service offering");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/DeleteDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteDiskOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/offering/DeleteDiskOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteDiskOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/offering/DeleteServiceOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateDiskOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/offering/UpdateServiceOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ChangeOutOfBandManagementPasswordCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/ConfigureOutOfBandManagementCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/DisableOutOfBandManagementForZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForClusterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForHostCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/EnableOutOfBandManagementForZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/outofbandmanagement/IssueOutOfBandManagementPowerActionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/pod/CreatePodCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/pod/DeletePodCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/pod/UpdatePodCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/AddRegionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/CreatePortableIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/DeletePortableIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/region/UpdateRegionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/CleanVMReservationsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListAlertsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/resource/UploadCustomCertificateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureOvsElementCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/ConfigureVirtualRouterElementCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java
new file mode 100644
index 0000000..4bb6d90
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java
@@ -0,0 +1,142 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.router;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ProviderResponse;
+import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.VirtualRouterProvider.Type;
+import com.cloud.network.element.VirtualRouterElementService;
+import com.cloud.user.Account;
+
+@APICommand(name = "createVirtualRouterElement", responseObject = VirtualRouterProviderResponse.class, description = "Create a virtual router element.",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateVirtualRouterElementCmd.class.getName());
+    private static final String s_name = "createvirtualrouterelementresponse";
+
+    @Inject
+    private List<VirtualRouterElementService> _service;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.NETWORK_SERVICE_PROVIDER_ID,
+               type = CommandType.UUID,
+               entityType = ProviderResponse.class,
+               required = true,
+               description = "the network service provider ID of the virtual router element")
+    private Long nspId;
+
+    @Parameter(name = ApiConstants.PROVIDER_TYPE,
+               type = CommandType.UUID,
+               entityType = ProviderResponse.class,
+               description = "The provider type. Supported types are VirtualRouter (default) and VPCVirtualRouter")
+    private String providerType;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public void setNspId(Long nspId) {
+        this.nspId = nspId;
+    }
+
+    public Long getNspId() {
+        return nspId;
+    }
+
+    public Type getProviderType() {
+        if (providerType != null) {
+            if (providerType.equalsIgnoreCase(Type.VirtualRouter.toString())) {
+                return Type.VirtualRouter;
+            } else if (providerType.equalsIgnoreCase(Type.VPCVirtualRouter.toString())) {
+                return Type.VPCVirtualRouter;
+            } else
+                throw new InvalidParameterValueException("Invalid providerType specified");
+        }
+        return Type.VirtualRouter;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Virtual router element Id: " + getEntityUuid());
+        VirtualRouterProvider result = _service.get(0).getCreatedElement(getEntityId());
+        if (result != null) {
+            VirtualRouterProviderResponse response = _responseGenerator.createVirtualRouterProviderResponse(result);
+            if(response != null) {
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            }
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Virtual Router entity to physical network");
+        }
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        VirtualRouterProvider result = _service.get(0).addElement(getNspId(), getProviderType());
+        if (result != null) {
+            setEntityId(result.getId());
+            setEntityUuid(result.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Virtual Router entity to physical network");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SERVICE_PROVIDER_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Adding physical network ServiceProvider Virtual Router: " + getEntityUuid();
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java
new file mode 100644
index 0000000..c460c66
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.router;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "destroyRouter", description = "Destroys a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DestroyRouterCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DestroyRouterCmd.class.getName());
+    private static final String s_name = "destroyrouterresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
+    private Long id;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
+        if (router != null) {
+            return router.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_ROUTER_DESTROY;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "destroying router: " + this._uuidMgr.getUuid(VirtualMachine.class,getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.DomainRouter;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
+        CallContext ctx = CallContext.current();
+        ctx.setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class,getId()));
+
+        VirtualRouter result = _routerService.destroyRouter(getId(), ctx.getCallingAccount(), ctx.getCallingUserId());
+        if (result != null) {
+            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy router");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListOvsElementsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/ListVirtualRouterElementsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java
new file mode 100644
index 0000000..802e3df
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java
@@ -0,0 +1,111 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.router;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "rebootRouter", description = "Starts a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RebootRouterCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RebootRouterCmd.class.getName());
+    private static final String s_name = "rebootrouterresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
+        if (router != null) {
+            return router.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_ROUTER_REBOOT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "rebooting router: " + this._uuidMgr.getUuid(VirtualMachine.class,getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.DomainRouter;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class,getId()));
+        VirtualRouter result = _routerService.rebootRouter(getId(), true);
+        if (result != null) {
+            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
+            response.setResponseName("router");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot router");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java
new file mode 100644
index 0000000..6d36a3c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.router;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "startRouter", responseObject = DomainRouterResponse.class, description = "Starts a router.", entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class StartRouterCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StartRouterCmd.class.getName());
+    private static final String s_name = "startrouterresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "router";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
+        if (router != null) {
+            return router.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_ROUTER_START;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "starting router: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.DomainRouter;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualRouter result = null;
+        VirtualRouter router = _routerService.findRouter(getId());
+        if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) {
+            throw new InvalidParameterValueException("Can't find router by id");
+        } else {
+            result = _routerService.startRouter(getId());
+        }
+        if (result != null) {
+            DomainRouterResponse routerResponse = _responseGenerator.createDomainRouterResponse(result);
+            routerResponse.setResponseName(getCommandName());
+            setResponseObject(routerResponse);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start router");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java
new file mode 100644
index 0000000..2474171
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java
@@ -0,0 +1,126 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.router;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "stopRouter", description = "Stops a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class StopRouterCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StopRouterCmd.class.getName());
+    private static final String s_name = "stoprouterresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
+    private Long id;
+
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM. The caller knows the VM is stopped.")
+    private Boolean forced;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
+        if (router != null) {
+            return router.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_ROUTER_STOP;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Stopping router: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.DomainRouter;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    @Override
+    public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
+        CallContext.current().setEventDetails("Router Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualRouter result = null;
+        VirtualRouter router = _routerService.findRouter(getId());
+        if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) {
+            throw new InvalidParameterValueException("Can't find router by id");
+        } else {
+            result = _routerService.stopRouter(getId(), isForced());
+        }
+
+        if (result != null) {
+            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop router");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/router/UpgradeRouterTemplateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreS3CMD.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreS3CMD.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreS3CMD.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/AddImageStoreS3CMD.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CancelPrimaryStorageMaintenanceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/CreateStoragePoolCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/DeletePoolCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeletePoolCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/DeletePoolCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeletePoolCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteSecondaryStagingStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeleteSecondaryStagingStoreCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/DeleteSecondaryStagingStoreCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/DeleteSecondaryStagingStoreCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
new file mode 100644
index 0000000..73c596c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
@@ -0,0 +1,118 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.storage;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.storage.StoragePool;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "findStoragePoolsForMigration", description = "Lists storage pools available for migration of a volume.", responseObject = StoragePoolResponse.class,
+requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(FindStoragePoolsForMigrationCmd.class.getName());
+
+    private static final String s_name = "findstoragepoolsformigrationresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the volume")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.StoragePool;
+    }
+
+    @Override
+    public void execute() {
+        Pair<List<? extends StoragePool>, List<? extends StoragePool>> pools = _mgr.listStoragePoolsForMigrationOfVolume(getId());
+        ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
+        List<StoragePoolResponse> poolResponses = new ArrayList<StoragePoolResponse>();
+
+        List<? extends StoragePool> allPools = pools.first();
+        List<? extends StoragePool> suitablePoolList = pools.second();
+        for (StoragePool pool : allPools) {
+            StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
+            Boolean suitableForMigration = false;
+            for (StoragePool suitablePool : suitablePoolList) {
+                if (StringUtils.equals(suitablePool.getUuid(), pool.getUuid())) {
+                    suitableForMigration = true;
+                    break;
+                }
+            }
+            poolResponse.setSuitableForMigration(suitableForMigration);
+            poolResponse.setObjectName("storagepool");
+            poolResponses.add(poolResponse);
+        }
+        sortPoolsBySuitabilityAndName(poolResponses);
+        response.setResponses(poolResponses);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+    }
+
+    protected void sortPoolsBySuitabilityAndName(List<StoragePoolResponse> poolResponses) {
+        Collections.sort(poolResponses, new Comparator<StoragePoolResponse>() {
+            @Override
+            public int compare(StoragePoolResponse o1, StoragePoolResponse o2) {
+                if (o1.getSuitableForMigration() && o2.getSuitableForMigration()) {
+                    return o1.getName().compareTo(o2.getName());
+                }
+                if (o1.getSuitableForMigration()) {
+                    return -1;
+                }
+                if (o2.getSuitableForMigration()) {
+                    return 1;
+                }
+                return 0;
+            }
+        });
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListSecondaryStagingStoresCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListSecondaryStagingStoresCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/ListSecondaryStagingStoresCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListSecondaryStagingStoresCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStorageProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStorageProvidersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/ListStorageProvidersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStorageProvidersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStorageTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStorageTagsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/ListStorageTagsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/ListStorageTagsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/PreparePrimaryStorageForMaintenanceCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateCloudToUseObjectStoreCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateStoragePoolCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java
new file mode 100644
index 0000000..f68f9dd
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "destroySystemVm", responseObject = SystemVmResponse.class, description = "Destroyes a system virtual machine.", entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DestroySystemVmCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DestroySystemVmCmd.class.getName());
+
+    private static final String s_name = "destroysystemvmresponse";
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = SystemVmResponse.class,
+               required = true,
+               description = "The ID of the system virtual machine")
+    private Long id;
+
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "systemvm";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
+        if (type == VirtualMachine.Type.ConsoleProxy) {
+            return EventTypes.EVENT_PROXY_DESTROY;
+        } else {
+            return EventTypes.EVENT_SSVM_DESTROY;
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "destroying system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.SystemVm;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualMachine instance = _mgr.destroySystemVM(this);
+        if (instance != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to destroy system vm");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java
new file mode 100644
index 0000000..ab0018b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java
@@ -0,0 +1,143 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.host.Host;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "migrateSystemVm", description = "Attempts Migration of a system virtual machine to the host specified.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class MigrateSystemVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(MigrateSystemVMCmd.class.getName());
+
+    private static final String s_name = "migratesystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.HOST_ID,
+               type = CommandType.UUID,
+               entityType = HostResponse.class,
+               required = true,
+               description = "destination Host ID to migrate VM to")
+    private Long hostId;
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+               type = CommandType.UUID,
+               entityType = SystemVmResponse.class,
+               required = true,
+               description = "the ID of the virtual machine")
+    private Long virtualMachineId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_MIGRATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Attempting to migrate VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId());
+    }
+
+    @Override
+    public void execute() {
+
+        Host destinationHost = _resourceService.getHost(getHostId());
+        if (destinationHost == null) {
+            throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
+        }
+        try {
+            CallContext.current().setEventDetails("VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId()));
+            //FIXME : Should not be calling UserVmService to migrate all types of VMs - need a generic VM layer
+            VirtualMachine migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), destinationHost);
+            if (migratedVm != null) {
+                // return the generic system VM instance response
+                SystemVmResponse response = _responseGenerator.createSystemVmResponse(migratedVm);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate the system vm");
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        } catch (ManagementServerException e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        } catch (VirtualMachineMigrationException e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java
new file mode 100644
index 0000000..ebc50ae
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java
@@ -0,0 +1,119 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "rebootSystemVm", description = "Reboots a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RebootSystemVmCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RebootSystemVmCmd.class.getName());
+
+    private static final String s_name = "rebootsystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = SystemVmResponse.class,
+               required = true,
+               description = "The ID of the system virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
+        if (type == VirtualMachine.Type.ConsoleProxy) {
+            return EventTypes.EVENT_PROXY_REBOOT;
+        } else {
+            return EventTypes.EVENT_SSVM_REBOOT;
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "rebooting system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.SystemVm;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualMachine result = _mgr.rebootSystemVM(this);
+        if (result != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java
new file mode 100644
index 0000000..c4a69a2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java
@@ -0,0 +1,145 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "scaleSystemVm", responseObject = SystemVmResponse.class, description = "Scale the service offering for a system vm (console proxy or secondary storage). "
+        + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ScaleSystemVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
+    private static final String s_name = "changeserviceforsystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SystemVmResponse.class, required = true, description = "The ID of the system vm")
+    private Long id;
+
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the service offering ID to apply to the system vm")
+    private Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
+    private Map<String, String> details;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("SystemVm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        VirtualMachine result = null;
+        try {
+            result = _mgr.upgradeSystemVM(this);
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (ManagementServerException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (VirtualMachineMigrationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+        if (result != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade system vm");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_UPGRADE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Upgrading system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()) + " to service offering: " + this._uuidMgr.getUuid(ServiceOffering.class, getServiceOfferingId());
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java
new file mode 100644
index 0000000..a2b70a6
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "startSystemVm", responseObject = SystemVmResponse.class, description = "Starts a system virtual machine.", entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class StartSystemVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StartSystemVMCmd.class.getName());
+
+    private static final String s_name = "startsystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = SystemVmResponse.class,
+               required = true,
+               description = "The ID of the system virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "systemvm";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
+        if (type == VirtualMachine.Type.ConsoleProxy) {
+            return EventTypes.EVENT_PROXY_START;
+        } else {
+            return EventTypes.EVENT_SSVM_START;
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "starting system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.SystemVm;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualMachine instance = _mgr.startSystemVM(getId());
+        if (instance != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to start system vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java
new file mode 100644
index 0000000..9237004
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java
@@ -0,0 +1,129 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "stopSystemVm", description = "Stops a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class StopSystemVmCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StopSystemVmCmd.class.getName());
+
+    private static final String s_name = "stopsystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = SystemVmResponse.class,
+               required = true,
+               description = "The ID of the system virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM.  The caller knows the VM is stopped.")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
+        if (type == VirtualMachine.Type.ConsoleProxy) {
+            return EventTypes.EVENT_PROXY_STOP;
+        } else {
+            return EventTypes.EVENT_SSVM_STOP;
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "stopping system vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.SystemVm;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        VirtualMachine result = _mgr.stopSystemVM(this);
+        if (result != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to stop system vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java
new file mode 100644
index 0000000..f266358
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.systemvm;
+
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "changeServiceForSystemVm", responseObject = SystemVmResponse.class, description = "Changes the service offering for a system vm (console proxy or secondary storage). "
+        + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpgradeSystemVMCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
+    private static final String s_name = "changeserviceforsystemvmresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SystemVmResponse.class, required = true, description = "The ID of the system vm")
+    private Long id;
+
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the service offering ID to apply to the system vm")
+    private Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
+    private Map<String, String> details;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        VirtualMachine result = _mgr.upgradeSystemVM(this);
+        if (result != null) {
+            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/CopyTemplateCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/CopyTemplateCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/CopyTemplateCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/CopyTemplateCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java
new file mode 100644
index 0000000..865bc15
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.template;
+
+import java.util.List;
+
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.template.VirtualMachineTemplate;
+
+@APICommand(name = "createTemplate", responseObject = TemplateResponse.class, description = "Creates a template of a virtual machine. " + "The virtual machine must be in a STOPPED state. "
+        + "A template created from this command is automatically designated as a private template visible to the account that created it.", responseView = ResponseView.Full,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateTemplateCmdByAdmin extends CreateTemplateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateTemplateCmdByAdmin.class.getName());
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Template Id: " + getEntityUuid()+((getSnapshotId() == null) ? " from volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) : " from snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId())));
+        VirtualMachineTemplate template = null;
+        template = _templateService.createPrivateTemplate(this);
+
+        if (template != null){
+            List<TemplateResponse> templateResponses;
+            if (isBareMetal()) {
+                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Full, template.getId(), vmId);
+            } else {
+                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Full, template.getId(), snapshotId, volumeId, false);
+            }
+            TemplateResponse response = new TemplateResponse();
+            if (templateResponses != null && !templateResponses.isEmpty()) {
+                response = templateResponses.get(0);
+            }
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private template");
+        }
+
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatePermissionsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/ListTemplatePermissionsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatePermissionsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/ListTemplatePermissionsCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/ListTemplatesCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/RegisterTemplateCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/RegisterTemplateCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/RegisterTemplateCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/RegisterTemplateCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/UpdateTemplateCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/template/UpdateTemplateCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/template/UpdateTemplateCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/template/UpdateTemplateCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficMonitorCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficMonitorCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficMonitorCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficMonitorCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficMonitorCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficMonitorCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficMonitorCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficMonitorCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/DeleteTrafficTypeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GenerateUsageRecordsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficMonitorsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficMonitorsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficMonitorsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficMonitorsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypeImplementorsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListTrafficTypesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageTypesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/RemoveRawUsageRecordsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/RemoveRawUsageRecordsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/RemoveRawUsageRecordsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/RemoveRawUsageRecordsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/DeleteUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/DisableUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/EnableUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/GetUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/GetUserKeysCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/GetUserKeysCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/GetUserKeysCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/GetUserKeysCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/LockUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/MoveUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
new file mode 100644
index 0000000..24624e2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
@@ -0,0 +1,177 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.user;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.region.RegionService;
+import org.apache.log4j.Logger;
+
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+
+@APICommand(name = "updateUser", description = "Updates a user account", responseObject = UserResponse.class,
+requestHasSensitiveInfo = true, responseHasSensitiveInfo = true)
+public class UpdateUserCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
+
+    private static final String s_name = "updateuserresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.USER_API_KEY, type = CommandType.STRING, description = "The API key for the user. Must be specified with userSecretKey")
+    private String apiKey;
+
+    @Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, description = "email")
+    private String email;
+
+    @Parameter(name = ApiConstants.FIRSTNAME, type = CommandType.STRING, description = "first name")
+    private String firstname;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserResponse.class, required = true, description = "User uuid")
+    private Long id;
+
+    @Parameter(name = ApiConstants.LASTNAME, type = CommandType.STRING, description = "last name")
+    private String lastname;
+
+    @Parameter(name = ApiConstants.PASSWORD,
+            type = CommandType.STRING,
+            description = "Clear text password (default hashed to SHA256SALT). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter. Can't be passed when command is executed via integration.api.port",
+            acceptedOnAdminPort = false)
+    private String password;
+
+    @Parameter(name = ApiConstants.CURRENT_PASSWORD, type = CommandType.STRING, description = "Current password that was being used by the user. You must inform the current password when updating the password.", acceptedOnAdminPort = false)
+    private String currentPassword;
+
+    @Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
+    private String secretKey;
+
+    @Parameter(name = ApiConstants.TIMEZONE,
+            type = CommandType.STRING,
+            description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
+    private String timezone;
+
+    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "Unique username")
+    private String username;
+
+    @Inject
+    private RegionService _regionService;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public String getFirstname() {
+        return firstname;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getLastname() {
+        return lastname;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String getCurrentPassword() {
+        return currentPassword;
+    }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public String getTimezone() {
+        return timezone;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        User user = _entityMgr.findById(User.class, getId());
+        if (user != null) {
+            return user.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("UserId: " + getId());
+        UserAccount user = _regionService.updateUser(this);
+
+        if (user != null) {
+            UserResponse response = _responseGenerator.createUserResponse(user);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update user");
+        }
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public void setFirstname(String firstname) {
+        this.firstname = firstname;
+    }
+
+    public void setLastname(String lastname) {
+        this.lastname = lastname;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/DedicatePublicIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/DedicatePublicIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vlan/DedicatePublicIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/DedicatePublicIpRangeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/DeleteVlanIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/DeleteVlanIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vlan/DeleteVlanIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/DeleteVlanIpRangeCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java
new file mode 100644
index 0000000..d5edd30
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java
@@ -0,0 +1,158 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vlan;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.VlanIpRangeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.dc.Vlan;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listVlanIpRanges", description = "Lists all VLAN IP ranges.", responseObject = VlanIpRangeResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListVlanIpRangesCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(ListVlanIpRangesCmd.class.getName());
+
+    private static final String s_name = "listvlaniprangesresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ACCOUNT,
+               type = CommandType.STRING,
+               description = "the account with which the VLAN IP range is associated. Must be used with the domainId parameter.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the VLAN")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "the domain ID with which the VLAN IP range is associated.  If used with the account parameter, " +
+                   "returns all VLAN IP ranges for that account in the specified domain.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = false, description = "the ID of the VLAN IP range")
+    private Long id;
+
+    @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "the Pod ID of the VLAN IP range")
+    private Long podId;
+
+    @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "the ID or VID of the VLAN. Default is an \"untagged\" VLAN.")
+    private String vlan;
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID of the VLAN IP range")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "network id of the VLAN IP range")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.FOR_VIRTUAL_NETWORK, type = CommandType.BOOLEAN, description = "true if VLAN is of Virtual type, false if Direct")
+    private Boolean forVirtualNetwork;
+
+    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = PhysicalNetworkResponse.class,
+               description = "physical network id of the VLAN IP range")
+    private Long physicalNetworkId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getPodId() {
+        return podId;
+    }
+
+    public String getVlan() {
+        return vlan;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Boolean isForVirtualNetwork() {
+        return forVirtualNetwork;
+    }
+
+    public Long getProjectId() {
+        return projectId;
+    }
+
+    public Long getPhysicalNetworkId() {
+        return physicalNetworkId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        Pair<List<? extends Vlan>, Integer> vlans = _mgr.searchForVlans(this);
+        ListResponse<VlanIpRangeResponse> response = new ListResponse<VlanIpRangeResponse>();
+        List<VlanIpRangeResponse> vlanResponses = new ArrayList<VlanIpRangeResponse>();
+        for (Vlan vlan : vlans.first()) {
+            VlanIpRangeResponse vlanResponse = _responseGenerator.createVlanIpRangeResponse(vlan);
+            vlanResponse.setObjectName("vlaniprange");
+            vlanResponses.add(vlanResponse);
+        }
+
+        response.setResponses(vlanResponses, vlans.second());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/ReleasePublicIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/ReleasePublicIpRangeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vlan/ReleasePublicIpRangeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/ReleasePublicIpRangeCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java
new file mode 100644
index 0000000..da0a087
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java
@@ -0,0 +1,58 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import com.cloud.network.Network;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+
+@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class AddNicToVMCmdByAdmin extends AddNicToVMCmd {
+    public static final Logger s_logger = Logger.getLogger(AddNicToVMCmdByAdmin.class);
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Network Id: " + this._uuidMgr.getUuid(Network.class, getNetworkId()));
+        UserVm result = _userVmService.addNicToVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NIC to vm. Refer to server logs for details.");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/AssignVMCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java
new file mode 100644
index 0000000..fa76db9
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+
+@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class DeployVMCmdByAdmin extends DeployVMCmd {
+    public static final Logger s_logger = Logger.getLogger(DeployVMCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute(){
+        UserVm result;
+
+        if (getStartVm()) {
+            try {
+                CallContext.current().setEventDetails("Vm Id: " + getEntityUuid());
+                result = _userVmService.startVirtualMachine(this);
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+            } catch (ConcurrentOperationException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+            } catch (InsufficientCapacityException ex) {
+                StringBuilder message = new StringBuilder(ex.getMessage());
+                if (ex instanceof InsufficientServerCapacityException) {
+                    if(((InsufficientServerCapacityException)ex).isAffinityApplied()){
+                        message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
+                    }
+                }
+                s_logger.info(ex);
+                s_logger.info(message.toString(), ex);
+                throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
+            }
+        } else {
+            result = _userVmService.getUserVm(getEntityId());
+        }
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm");
+        }
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java
new file mode 100644
index 0000000..bb59a17
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine. Once destroyed, only the administrator can recover it.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false,
+        responseHasSensitiveInfo = true)
+public class DestroyVMCmdByAdmin extends DestroyVMCmd {
+    public static final Logger s_logger = Logger.getLogger(DestroyVMCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result = _userVmService.destroyVm(this);
+
+        UserVmResponse response = new UserVmResponse();
+        if (result != null) {
+            List<UserVmResponse> responses = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result);
+            if (responses != null && !responses.isEmpty()) {
+                response = responses.get(0);
+            }
+            response.setResponseName("virtualmachine");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java
new file mode 100644
index 0000000..ea6cb00
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "expungeVirtualMachine", description = "Expunge a virtual machine. Once expunged, it cannot be recoverd.", responseObject = SuccessResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ExpungeVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ExpungeVMCmd.class.getName());
+
+    private static final String s_name = "expungevirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "The ID of the virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_EXPUNGE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Expunging vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        try {
+            UserVm result = _userVmService.expungeVm(this.getId());
+
+            if (result != null) {
+                SuccessResponse response = new SuccessResponse(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to expunge vm");
+            }
+        } catch (InvalidParameterValueException ipve) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ipve.getMessage());
+        } catch (CloudRuntimeException cre) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, cre.getMessage());
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ListVMsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListVMsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/ListVMsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListVMsCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java
new file mode 100644
index 0000000..9f73ae5
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java
@@ -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.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+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.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.host.Host;
+import com.cloud.storage.StoragePool;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "migrateVirtualMachine",
+        description = "Attempts Migration of a VM to a different host or Root volume of the vm to a different storage pool",
+        responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false,
+        responseHasSensitiveInfo = true)
+public class MigrateVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(MigrateVMCmd.class.getName());
+
+    private static final String s_name = "migratevirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.HOST_ID,
+            type = CommandType.UUID,
+            entityType = HostResponse.class,
+            required = false,
+            description = "Destination Host ID to migrate VM to. Required for live migrating a VM from host to host")
+    private Long hostId;
+
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+            type = CommandType.UUID,
+            entityType = UserVmResponse.class,
+            required = true,
+            description = "the ID of the virtual machine")
+    private Long virtualMachineId;
+
+    @Parameter(name = ApiConstants.STORAGE_ID,
+            type = CommandType.UUID,
+            entityType = StoragePoolResponse.class,
+            required = false,
+            description = "Destination storage pool ID to migrate VM volumes to. Required for migrating the root disk volume")
+    private Long storageId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    public Long getStoragePoolId() {
+        return storageId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getVirtualMachineId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_MIGRATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        String eventDescription;
+        if (getHostId() != null) {
+            eventDescription = String.format("Attempting to migrate VM id: %s to host Id: %s", getVirtualMachineId(), getHostId());
+        } else if (getStoragePoolId() != null) {
+            eventDescription = String.format("Attempting to migrate VM id: %s to storage pool Id: %s", getVirtualMachineId(), getStoragePoolId());
+        } else {
+            eventDescription = String.format("Attempting to migrate VM id: %s", getVirtualMachineId());
+        }
+        return eventDescription;
+    }
+
+    @Override
+    public void execute() {
+        if (getHostId() == null && getStoragePoolId() == null) {
+            throw new InvalidParameterValueException("Either hostId or storageId must be specified");
+        }
+
+        if (getHostId() != null && getStoragePoolId() != null) {
+            throw new InvalidParameterValueException("Only one of hostId and storageId can be specified");
+        }
+
+        UserVm userVm = _userVmService.getUserVm(getVirtualMachineId());
+        if (userVm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by id=" + getVirtualMachineId());
+        }
+
+        Host destinationHost = null;
+        if (getHostId() != null) {
+            destinationHost = _resourceService.getHost(getHostId());
+            if (destinationHost == null) {
+                throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
+            }
+            if (destinationHost.getType() != Host.Type.Routing) {
+                throw new InvalidParameterValueException("The specified host(" + destinationHost.getName() + ") is not suitable to migrate the VM, please specify another one");
+            }
+            CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId());
+        }
+
+        // OfflineMigration performed when this parameter is specified
+        StoragePool destStoragePool = null;
+        if (getStoragePoolId() != null) {
+            destStoragePool = _storageService.getStoragePool(getStoragePoolId());
+            if (destStoragePool == null) {
+                throw new InvalidParameterValueException("Unable to find the storage pool to migrate the VM");
+            }
+            CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to storage pool Id: " + getStoragePoolId());
+        }
+
+        try {
+            VirtualMachine migratedVm = null;
+            if (getHostId() != null) {
+                migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), destinationHost);
+            } else if (getStoragePoolId() != null) {
+                migratedVm = _userVmService.vmStorageMigration(getVirtualMachineId(), destStoragePool);
+            }
+            if (migratedVm != null) {
+                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", (UserVm) migratedVm).get(0);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vm");
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (VirtualMachineMigrationException | ConcurrentOperationException | ManagementServerException e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return (getSyncObjId() != null) ? BaseAsyncCmd.migrationSyncObject : null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (getStoragePoolId() != null) {
+            return getStoragePoolId();
+        }
+        // OfflineVmwareMigrations: undocumented feature;
+        // OfflineVmwareMigrations: on implementing a maximum queue size for per storage migrations it seems counter intuitive for the user to not enforce it for hosts as well.
+        if (getHostId() != null) {
+            return getHostId();
+        }
+        return null;
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java
new file mode 100644
index 0000000..65d71cc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java
@@ -0,0 +1,172 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.host.Host;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "migrateVirtualMachineWithVolume",
+            description = "Attempts Migration of a VM with its volumes to a different host",
+            responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
+            requestHasSensitiveInfo = false,
+            responseHasSensitiveInfo = true)
+public class MigrateVirtualMachineWithVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(MigrateVMCmd.class.getName());
+
+    private static final String s_name = "migratevirtualmachinewithvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.HOST_ID,
+               type = CommandType.UUID,
+               entityType = HostResponse.class,
+               required = true,
+               description = "Destination Host ID to migrate VM to.")
+    private Long hostId;
+
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+               type = CommandType.UUID,
+               entityType = UserVmResponse.class,
+               required = true,
+               description = "the ID of the virtual machine")
+    private Long virtualMachineId;
+
+    @Parameter(name = ApiConstants.MIGRATE_TO,
+               type = CommandType.MAP,
+               required = false,
+               description = "Storage to pool mapping. This parameter specifies the mapping between a volume and a pool where you want to migrate that volume. Format of this " +
+               "parameter: migrateto[volume-index].volume=<uuid>&migrateto[volume-index].pool=<uuid>Where, [volume-index] indicates the index to identify the volume that you " +
+               "want to migrate, volume=<uuid> indicates the UUID of the volume that you want to migrate, and pool=<uuid> indicates the UUID of the pool where you want to " +
+               "migrate the volume. Example: migrateto[0].volume=<71f43cd6-69b0-4d3b-9fbc-67f50963d60b>&migrateto[0].pool=<a382f181-3d2b-4413-b92d-b8931befa7e1>&" +
+               "migrateto[1].volume=<88de0173-55c0-4c1c-a269-83d0279eeedf>&migrateto[1].pool=<95d6e97c-6766-4d67-9a30-c449c15011d1>&migrateto[2].volume=" +
+               "<1b331390-59f2-4796-9993-bf11c6e76225>&migrateto[2].pool=<41fdb564-9d3b-447d-88ed-7628f7640cbc>")
+    private Map migrateVolumeTo;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    public Map<String, String> getVolumeToPool() {
+        Map<String, String> volumeToPoolMap = new HashMap<String, String>();
+        if (migrateVolumeTo != null && !migrateVolumeTo.isEmpty()) {
+            Collection<?> allValues = migrateVolumeTo.values();
+            Iterator<?> iter = allValues.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> volumeToPool = (HashMap<String, String>)iter.next();
+                String volume = volumeToPool.get("volume");
+                String pool = volumeToPool.get("pool");
+                volumeToPoolMap.put(volume, pool);
+            }
+        }
+        return volumeToPoolMap;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getVirtualMachineId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_MIGRATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Attempting to migrate VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) + " to host Id: " + this._uuidMgr.getUuid(Host.class, getHostId());
+    }
+
+    @Override
+    public void execute() {
+        UserVm userVm = _userVmService.getUserVm(getVirtualMachineId());
+        if (userVm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by id=" + getVirtualMachineId());
+        }
+
+        Host destinationHost = _resourceService.getHost(getHostId());
+        // OfflineVmwareMigration: destination host would have to not be a required parameter for stopped VMs
+        if (destinationHost == null) {
+            throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id =" + getHostId());
+        }
+
+        try {
+            VirtualMachine migratedVm = _userVmService.migrateVirtualMachineWithVolume(getVirtualMachineId(), destinationHost, getVolumeToPool());
+            if (migratedVm != null) {
+                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", (UserVm)migratedVm).get(0);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vm");
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException | ManagementServerException | VirtualMachineMigrationException e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java
new file mode 100644
index 0000000..c32f9ac
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RebootVMCmdByAdmin extends RebootVMCmd {
+    public static final Logger s_logger = Logger.getLogger(RebootVMCmdByAdmin.class.getName());
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result;
+        result = _userVmService.rebootVirtualMachine(this);
+
+        if (result !=null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot vm instance");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RecoverVMCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java
new file mode 100644
index 0000000..08c56df
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java
@@ -0,0 +1,57 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import com.cloud.vm.Nic;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RemoveNicFromVMCmdByAdmin extends RemoveNicFromVMCmd {
+    public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmdByAdmin.class);
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId()));
+        UserVm result = _userVmService.removeNicFromVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NIC from vm, see error log for details");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ResetVMPasswordCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ResetVMPasswordCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/ResetVMPasswordCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ResetVMPasswordCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ResetVMSSHKeyCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ResetVMSSHKeyCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/ResetVMSSHKeyCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ResetVMSSHKeyCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java
new file mode 100644
index 0000000..f607faf
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java
@@ -0,0 +1,57 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false,
+        responseHasSensitiveInfo = true)
+public class RestoreVMCmdByAdmin extends RestoreVMCmd {
+    public static final Logger s_logger = Logger.getLogger(RestoreVMCmdByAdmin.class);
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException {
+        UserVm result;
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()));
+        result = _userVmService.restoreVM(this);
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restore vm " + getVmId());
+        }
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ScaleVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ScaleVMCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vm/ScaleVMCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ScaleVMCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java
new file mode 100644
index 0000000..1230547
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class StartVMCmdByAdmin extends StartVMCmd {
+    public static final Logger s_logger = Logger.getLogger(StartVMCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException {
+        try {
+            CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+            UserVm result ;
+            result = _userVmService.startVirtualMachine(this);
+
+            if (result != null) {
+                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start a vm");
+            }
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (StorageUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ExecutionException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (InsufficientCapacityException ex) {
+            StringBuilder message = new StringBuilder(ex.getMessage());
+            if (ex instanceof InsufficientServerCapacityException) {
+                if (((InsufficientServerCapacityException) ex).isAffinityApplied()) {
+                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
+                }
+            }
+            s_logger.info(ex);
+            s_logger.info(message.toString(), ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
+        }
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java
new file mode 100644
index 0000000..ca85dfa
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java
@@ -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.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.StopVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class StopVMCmdByAdmin extends StopVMCmd {
+    public static final Logger s_logger = Logger.getLogger(StopVMCmdByAdmin.class.getName());
+
+
+
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result;
+
+        result = _userVmService.stopVirtualMachine(getId(), isForced());
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java
new file mode 100644
index 0000000..d666ae4
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java
@@ -0,0 +1,58 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import com.cloud.vm.Nic;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpdateDefaultNicForVMCmdByAdmin extends UpdateDefaultNicForVMCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmdByAdmin.class);
+
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId()));
+        UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set default nic for VM. Refer to server logs for details.");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java
new file mode 100644
index 0000000..5d2b2b7
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java
@@ -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.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+
+@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
+        "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
+        "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpdateVMCmdByAdmin extends UpdateVMCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateVMCmdByAdmin.class.getName());
+
+    @Override
+    public void execute() throws ResourceUnavailableException,
+            InsufficientCapacityException, ServerApiException {
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result = _userVmService.updateVirtualMachine(this);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java
new file mode 100644
index 0000000..6e3261a
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " +
+                                            "The virtual machine must be in a \"Stopped\" state for " +
+        "this command to take effect.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpgradeVMCmdByAdmin extends UpgradeVMCmd {
+    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute() throws ResourceAllocationException{
+        CallContext.current().setEventDetails("Vm Id: "+this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        UserVm result = _userVmService.upgradeVirtualMachine(this);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java
new file mode 100644
index 0000000..47cb99b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vmsnapshot;
+
+import java.util.logging.Logger;
+
+import com.cloud.vm.snapshot.VMSnapshot;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "revertToVMSnapshot", description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since = "4.2.0", responseView = ResponseView.Full,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RevertToVMSnapshotCmdByAdmin extends RevertToVMSnapshotCmd {
+    public static final Logger s_logger = Logger
+            .getLogger(RevertToVMSnapshotCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute() throws  ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
+        CallContext.current().setEventDetails(
+                "vmsnapshot id: " + this._uuidMgr.getUuid(VMSnapshot.class, getVmSnapShotId()));
+        UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full,
+                    "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,"Failed to revert VM snapshot");
+        }
+    }
+
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java
new file mode 100644
index 0000000..f70b410
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java
@@ -0,0 +1,49 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AttachVolumeCmdByAdmin extends AttachVolumeCmd {
+    public static final Logger s_logger = Logger.getLogger(AttachVolumeCmdByAdmin.class.getName());
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Volume Id: "+this._uuidMgr.getUuid(Volume.class, getId())+" VmId: "+this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()));
+        Volume result = _volumeService.attachVolumeToVM(this);
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to attach volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java
new file mode 100644
index 0000000..1dc4721
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full, entityType = {
+        Volume.class, VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateVolumeCmdByAdmin extends CreateVolumeCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateVolumeCmdByAdmin.class.getName());
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Volume Id: "+ getEntityUuid() + ((getSnapshotId() == null) ? "" : " from snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId())));
+        Volume volume = _volumeService.createVolume(this);
+        if (volume != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, volume);
+            //FIXME - have to be moved to ApiResponseHelper
+            if (getSnapshotId() != null) {
+                Snapshot snap = _entityMgr.findById(Snapshot.class, getSnapshotId());
+                if (snap != null) {
+                    response.setSnapshotId(snap.getUuid()); // if the volume was
+                    // created from a
+                    // snapshot,
+                    // snapshotId will
+                    // be set so we pass
+                    // it back in the
+                    // response
+                }
+            }
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java
new file mode 100644
index 0000000..f9d9cbd
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DetachVolumeCmdByAdmin extends DetachVolumeCmd {
+    public static final Logger s_logger = Logger.getLogger(DetachVolumeCmdByAdmin.class.getName());
+
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails(getEventDescription());
+        Volume result = _volumeService.detachVolumeFromVM(this);
+        if (result != null){
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
+            response.setResponseName("volume");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to detach volume");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/ListVolumesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/ListVolumesCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/volume/ListVolumesCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/volume/ListVolumesCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java
new file mode 100644
index 0000000..1a18b95
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.volume;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+
+import com.cloud.storage.Volume;
+
+@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {
+        Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class MigrateVolumeCmdByAdmin extends MigrateVolumeCmd {
+
+    @Override
+    public void execute() {
+        Volume result = _volumeService.migrateVolume(this);
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume");
+        }
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java
new file mode 100644
index 0000000..689e779
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.volume;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.storage.Volume;
+
+
+@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ResizeVolumeCmdByAdmin extends ResizeVolumeCmd {
+
+    @Override
+    public void execute() throws ResourceAllocationException{
+        Volume volume = null;
+        try {
+            CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()) + " to size " + getSize() + "G");
+            volume = _volumeService.resizeVolume(this);
+        } catch (InvalidParameterValueException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
+        }
+
+        if (volume != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, volume);
+            //FIXME - have to be moved to ApiResponseHelper
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to resize volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.java
new file mode 100644
index 0000000..b683435
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.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.api.command.admin.volume;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.storage.Volume;
+
+@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateVolumeCmdByAdmin extends UpdateVolumeCmd {
+
+    @Override
+    public void execute(){
+        CallContext.current().setEventDetails("Volume Id: "+this._uuidMgr.getUuid(Volume.class, getId()));
+        Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(),
+                getCustomId(), getEntityOwnerId(), getChainInfo());
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update volume");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/UploadVolumeCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UploadVolumeCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/volume/UploadVolumeCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/volume/UploadVolumeCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreatePrivateGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeletePrivateGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/DeleteVPCOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/ListVPCsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/ListVPCsCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/ListVPCsCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/ListVPCsCmdByAdmin.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java
new file mode 100644
index 0000000..d7761de
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.vpc;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.vpc.UpdateVPCCmd;
+import org.apache.cloudstack.api.response.VpcResponse;
+
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Full, entityType = {Vpc.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateVPCCmdByAdmin extends UpdateVPCCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateVPCCmdByAdmin.class.getName());
+
+    @Override
+    public void execute(){
+        Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), isDisplayVpc());
+        if (result != null) {
+            VpcResponse response = _responseGenerator.createVpcResponse(ResponseView.Full, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VPC");
+        }
+    }
+
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCOfferingCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/zone/DeleteZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/ListZonesCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListZonesCmdByAdmin.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/zone/ListZonesCmdByAdmin.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListZonesCmdByAdmin.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/zone/MarkDefaultZoneForAccountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/account/AddAccountToProjectCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteAccountFromProjectCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/account/ListProjectAccountsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/ListProjectAccountsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/account/ListProjectAccountsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/account/ListProjectAccountsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java
new file mode 100644
index 0000000..fea7f20
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java
@@ -0,0 +1,365 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.address;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.RegionResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.projects.Project;
+import com.cloud.user.Account;
+
+@APICommand(name = "associateIpAddress",
+        description = "Acquires and associates a public IP to an account. Either of the parameters are required, i.e. either zoneId, or networkId, or vpcId  ",
+        responseObject = IPAddressResponse.class,
+        responseView = ResponseView.Restricted,
+        requestHasSensitiveInfo = false,
+        responseHasSensitiveInfo = false)
+public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(AssociateIPAddrCmd.class.getName());
+    private static final String s_name = "associateipaddressresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ACCOUNT,
+            type = CommandType.STRING,
+            description = "the account to associate with this IP address")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+            type = CommandType.UUID,
+            entityType = DomainResponse.class,
+            description = "the ID of the domain to associate with this IP address")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.ZONE_ID,
+            type = CommandType.UUID,
+            entityType = ZoneResponse.class,
+            description = "the ID of the availability zone you want to acquire an public IP address from")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+            type = CommandType.UUID,
+            entityType = NetworkResponse.class,
+            description = "The network this IP address should be associated to.")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.PROJECT_ID,
+            type = CommandType.UUID,
+            entityType = ProjectResponse.class,
+            description = "Deploy VM for the project")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+            type = CommandType.UUID,
+            entityType = VpcResponse.class,
+            description = "the VPC you want the IP address to be associated with")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.IS_PORTABLE,
+            type = BaseCmd.CommandType.BOOLEAN,
+            description = "should be set to true if public IP is required to be transferable across zones, if not specified defaults to false")
+    private Boolean isPortable;
+
+    @Parameter(name = ApiConstants.REGION_ID,
+            type = CommandType.INTEGER,
+            entityType = RegionResponse.class,
+            required = false,
+            description = "region ID from where portable IP is to be associated.")
+    private Integer regionId;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY,
+            type = CommandType.BOOLEAN,
+            description = "an optional field, whether to the display the IP to the end user or not", since = "4.4",
+            authorized = {RoleType.Admin})
+    private Boolean display;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getAccountName() {
+        if (accountName != null) {
+            return accountName;
+        }
+        return CallContext.current().getCallingAccount().getAccountName();
+    }
+
+    public long getDomainId() {
+        if (domainId != null) {
+            return domainId;
+        }
+        return CallContext.current().getCallingAccount().getDomainId();
+    }
+
+    private long getZoneId() {
+        if (zoneId != null) {
+            return zoneId;
+        } else if (vpcId != null) {
+            Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+            if (vpc != null) {
+                return vpc.getZoneId();
+            }
+        } else if (networkId != null) {
+            Network ntwk = _entityMgr.findById(Network.class, networkId);
+            if (ntwk != null) {
+                return ntwk.getDataCenterId();
+            }
+        }
+
+        throw new InvalidParameterValueException("Unable to figure out zone to assign IP to."
+                + " Please specify either zoneId, or networkId, or vpcId in the call");
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public boolean isPortable() {
+        if (isPortable == null) {
+            return false;
+        } else {
+            return isPortable;
+        }
+    }
+
+    public Integer getRegionId() {
+        return regionId;
+    }
+
+    public Long getNetworkId() {
+        if (vpcId != null) {
+            return null;
+        }
+
+        if (networkId != null) {
+            return networkId;
+        }
+        Long zoneId = getZoneId();
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+        if (zone.getNetworkType() == NetworkType.Advanced) {
+            List<? extends Network> networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), _accountService.getAccount(getEntityOwnerId()));
+            if (networks.size() == 0) {
+                String domain = _domainService.getDomain(getDomainId()).getName();
+                throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" +
+                        zone.getName());
+            }
+
+            if (networks.size() < 1) {
+                throw new InvalidParameterValueException("Account doesn't have any isolated networks in the zone");
+            } else if (networks.size() > 1) {
+                throw new InvalidParameterValueException("Account has more than one isolated network in the zone");
+            }
+
+            return networks.get(0).getId();
+        } else {
+            Network defaultGuestNetwork = _networkService.getExclusiveGuestNetwork(zoneId);
+            if (defaultGuestNetwork == null) {
+                throw new InvalidParameterValueException("Unable to find a default guest network for account " + getAccountName() + " in domain ID=" + getDomainId());
+            } else {
+                return defaultGuestNetwork.getId();
+            }
+        }
+    }
+
+    @Deprecated
+    public Boolean getDisplayIp() {
+        return display;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        if (display == null)
+            return true;
+        else
+            return display;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        if (accountName != null && domainId != null) {
+            Account account = _accountService.finalizeOwner(caller, accountName, domainId, projectId);
+            return account.getId();
+        } else if (projectId != null) {
+            Project project = _projectService.getProject(projectId);
+            if (project != null) {
+                if (project.getState() == Project.State.Active) {
+                    return project.getProjectAccountId();
+                } else {
+                    throw new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
+                            " as it's no longer active");
+                }
+            } else {
+                throw new InvalidParameterValueException("Unable to find project by ID");
+            }
+        } else if (networkId != null) {
+            Network network = _networkService.getNetwork(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find network by network id specified");
+            }
+
+            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+
+            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+            if (zone.getNetworkType() == NetworkType.Basic && offering.isElasticIp() && offering.isElasticLb()) {
+                // Since the basic zone network is owned by 'Root' domain, domain access checkers will fail for the
+                // accounts in non-root domains while acquiring public IP. So add an exception for the 'Basic' zone
+                // shared network with EIP/ELB service.
+                return caller.getAccountId();
+            }
+
+            return network.getAccountId();
+        } else if (vpcId != null) {
+            Vpc vpc = _entityMgr.findById(Vpc.class, getVpcId());
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Can't find enabled VPC by ID specified");
+            }
+            return vpc.getAccountId();
+        }
+
+        return caller.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        if (isPortable()) {
+            return EventTypes.EVENT_PORTABLE_IP_ASSIGN;
+        } else {
+            return EventTypes.EVENT_NET_IP_ASSIGN;
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "associating IP to network ID: " + getNetworkId() + " in zone " + getZoneId();
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "addressinfo";
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        try {
+            IpAddress ip = null;
+
+            if (!isPortable()) {
+                ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId(), getDisplayIp());
+            } else {
+                ip = _networkService.allocatePortableIP(_accountService.getAccount(getEntityOwnerId()), 1, getZoneId(), getNetworkId(), getVpcId());
+            }
+
+            if (ip != null) {
+                setEntityId(ip.getId());
+                setEntityUuid(ip.getUuid());
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to allocate IP address");
+            }
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (InsufficientAddressCapacityException ex) {
+            s_logger.info(ex);
+            s_logger.trace(ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
+        CallContext.current().setEventDetails("IP ID: " + getEntityId());
+
+        IpAddress result = null;
+
+        if (getVpcId() != null) {
+            result = _vpcService.associateIPToVpc(getEntityId(), getVpcId());
+        } else if (getNetworkId() != null) {
+            result = _networkService.associateIPToNetwork(getEntityId(), getNetworkId());
+        }
+
+        if (result != null) {
+            IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(ResponseView.Restricted, result);
+            ipResponse.setResponseName(getCommandName());
+            setResponseObject(ipResponse);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign IP address");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getNetworkId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.IpAddress;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/address/DisassociateIPAddrCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
new file mode 100644
index 0000000..d590081
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
@@ -0,0 +1,200 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.address;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.VlanIpRangeResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.network.IpAddress;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listPublicIpAddresses", description = "Lists all public IP addresses", responseObject = IPAddressResponse.class, responseView = ResponseView.Restricted,
+ requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { IpAddress.class })
+public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd {
+    public static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName());
+
+    private static final String s_name = "listpublicipaddressesresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ALLOCATED_ONLY, type = CommandType.BOOLEAN, description = "limits search results to allocated public IP addresses")
+    private Boolean allocatedOnly;
+
+    @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "lists all public IP addresses by state")
+    private String state;
+
+    @Parameter(name = ApiConstants.FOR_VIRTUAL_NETWORK, type = CommandType.BOOLEAN, description = "the virtual network for the IP address")
+    private Boolean forVirtualNetwork;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IPAddressResponse.class, description = "lists IP address by ID")
+    private Long id;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "lists the specified IP address")
+    private String ipAddress;
+
+    @Parameter(name = ApiConstants.VLAN_ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, description = "lists all public IP addresses by VLAN ID")
+    private Long vlanId;
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "lists all public IP addresses by zone ID")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.FOR_LOAD_BALANCING, type = CommandType.BOOLEAN, description = "list only IPs used for load balancing")
+    private Boolean forLoadBalancing;
+
+    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = PhysicalNetworkResponse.class,
+               description = "lists all public IP addresses by physical network ID")
+    private Long physicalNetworkId;
+
+    @Parameter(name = ApiConstants.ASSOCIATED_NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "lists all public IP addresses associated to the network specified")
+    private Long associatedNetworkId;
+
+    @Parameter(name = ApiConstants.IS_SOURCE_NAT, type = CommandType.BOOLEAN, description = "list only source NAT IP addresses")
+    private Boolean isSourceNat;
+
+    @Parameter(name = ApiConstants.IS_STATIC_NAT, type = CommandType.BOOLEAN, description = "list only static NAT IP addresses")
+    private Boolean isStaticNat;
+
+    @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List IPs belonging to the VPC")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean display;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+    public Long getId() {
+        return id;
+    }
+
+    public Boolean isAllocatedOnly() {
+        return allocatedOnly;
+    }
+
+    public Boolean isForVirtualNetwork() {
+        return forVirtualNetwork;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public Long getVlanId() {
+        return vlanId;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public Long getPhysicalNetworkId() {
+        return physicalNetworkId;
+    }
+
+    public Long getAssociatedNetworkId() {
+        return associatedNetworkId;
+    }
+
+    public Boolean isSourceNat() {
+        return isSourceNat;
+    }
+
+    public Boolean isStaticNat() {
+        return isStaticNat;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    @Override
+    public Boolean getDisplay() {
+        if (display != null) {
+            return display;
+        }
+        return super.getDisplay();
+    }
+
+    public Boolean isForLoadBalancing() {
+        return forLoadBalancing;
+    }
+
+    public Boolean getForVirtualNetwork() {
+        return forVirtualNetwork;
+    }
+
+    public Boolean getForLoadBalancing() {
+        return forLoadBalancing;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        Pair<List<? extends IpAddress>, Integer> result = _mgr.searchForIPAddresses(this);
+        ListResponse<IPAddressResponse> response = new ListResponse<IPAddressResponse>();
+        List<IPAddressResponse> ipAddrResponses = new ArrayList<IPAddressResponse>();
+        for (IpAddress ipAddress : result.first()) {
+            IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(ResponseView.Restricted, ipAddress);
+            ipResponse.setObjectName("publicipaddress");
+            ipAddrResponses.add(ipResponse);
+        }
+
+        response.setResponses(ipAddrResponses, result.second());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.IpAddress;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/address/UpdateIPAddrCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/CreateAffinityGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/DeleteAffinityGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupTypesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupTypesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupTypesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/ListAffinityGroupsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/affinitygroup/UpdateVMAffinityGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScalePolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateAutoScaleVmProfileCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/CreateConditionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScalePolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteAutoScaleVmProfileCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DeleteConditionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/DisableAutoScaleVmGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/EnableAutoScaleVmGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScalePoliciesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmGroupsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListConditionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListConditionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/ListConditionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListConditionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListCountersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListCountersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/ListCountersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/ListCountersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScalePolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/autoscale/UpdateAutoScaleVmProfileCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ListEventTypesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/event/ListEventTypesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/event/ListEventTypesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/event/ListEventTypesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/event/ListEventsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
new file mode 100644
index 0000000..02c4255
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
@@ -0,0 +1,361 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.firewall;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.user.Account;
+import com.cloud.utils.net.NetUtils;
+
+@APICommand(name = "createFirewallRule", description = "Creates a firewall rule for a given IP address", responseObject = FirewallResponse.class, entityType = {FirewallRule.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule {
+    public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName());
+
+    private static final String s_name = "createfirewallruleresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.IP_ADDRESS_ID,
+               type = CommandType.UUID,
+               entityType = IPAddressResponse.class,
+               required = true,
+               description = "the IP address id of the port forwarding rule")
+    private Long ipAddressId;
+
+    @Parameter(name = ApiConstants.PROTOCOL,
+               type = CommandType.STRING,
+               required = true,
+               description = "the protocol for the firewall rule. Valid values are TCP/UDP/ICMP.")
+    private String protocol;
+
+    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of firewall rule")
+    private Integer publicStartPort;
+
+    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of firewall rule")
+    private Integer publicEndPort;
+
+    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to forward traffic from")
+    private List<String> cidrlist;
+
+    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
+    private Integer icmpType;
+
+    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message")
+    private Integer icmpCode;
+
+    @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "type of firewallrule: system/user")
+    private String type;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean display;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+
+    public Long getIpAddressId() {
+        return ipAddressId;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol.trim();
+    }
+
+    @Override
+    public List<String> getSourceCidrList() {
+        if (cidrlist != null) {
+            return cidrlist;
+        } else {
+            List<String> oneCidrList = new ArrayList<String>();
+            oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
+            return oneCidrList;
+        }
+
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public void setSourceCidrList(List<String> cidrs) {
+        cidrlist = cidrs;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        CallContext callerContext = CallContext.current();
+        boolean success = false;
+        FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
+        try {
+            CallContext.current().setEventDetails("Rule ID: " + getEntityId());
+            success = _firewallService.applyIngressFwRules(rule.getSourceIpAddressId(), callerContext.getCallingAccount());
+
+            // State is different after the rule is applied, so get new object here
+            rule = _entityMgr.findById(FirewallRule.class, getEntityId());
+            FirewallResponse fwResponse = new FirewallResponse();
+            if (rule != null) {
+                fwResponse = _responseGenerator.createFirewallResponse(rule);
+                setResponseObject(fwResponse);
+            }
+            fwResponse.setResponseName(getCommandName());
+        } finally {
+            if (!success || rule == null) {
+                _firewallService.revokeIngressFwRule(getEntityId(), true);
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create firewall rule");
+            }
+        }
+    }
+
+    @Override
+    public long getId() {
+        throw new UnsupportedOperationException("database ID can only provided by VO objects");
+    }
+
+    @Override
+    public String getXid() {
+        // FIXME: We should allow for end user to specify Xid.
+        return null;
+    }
+
+    @Override
+    public String getUuid() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Long getSourceIpAddressId() {
+        return ipAddressId;
+    }
+
+    @Override
+    public Integer getSourcePortStart() {
+        if (publicStartPort != null) {
+            return publicStartPort;
+        }
+        return null;
+    }
+
+    @Override
+    public Integer getSourcePortEnd() {
+        if (publicEndPort == null) {
+            if (publicStartPort != null) {
+                return publicStartPort;
+            }
+        } else {
+            return publicEndPort;
+        }
+
+        return null;
+    }
+
+    @Override
+    public Purpose getPurpose() {
+        return Purpose.Firewall;
+    }
+
+    @Override
+    public State getState() {
+        throw new UnsupportedOperationException("Should never call me to find the state");
+    }
+
+    @Override
+    public long getNetworkId() {
+        IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
+        Long ntwkId = null;
+
+        if (ip.getAssociatedWithNetworkId() != null) {
+            ntwkId = ip.getAssociatedWithNetworkId();
+        }
+
+        if (ntwkId == null) {
+            throw new InvalidParameterValueException("Unable to create firewall rule for the IP address ID=" + ipAddressId +
+                    " as IP is not associated with any network and no networkId is passed in");
+        }
+        return ntwkId;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public long getDomainId() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ip.getDomainId();
+    }
+
+    @Override
+    public void create() {
+        if (getSourceCidrList() != null) {
+            for (String cidr : getSourceCidrList()) {
+                if (!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source CIDRs formatting error " + cidr);
+                }
+            }
+        }
+        try {
+            FirewallRule result = _firewallService.createIngressFirewallRule(this);
+            if (result != null) {
+                setEntityId(result.getId());
+                setEntityUuid(result.getUuid());
+            }
+        } catch (NetworkRuleConflictException ex) {
+            s_logger.trace("Network Rule Conflict: ", ex);
+            throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage(), ex);
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_FIREWALL_OPEN;
+    }
+
+    @Override
+    public String getEventDescription() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ("Creating firewall rule for IP: " + ip.getAddress() + " for protocol:" + getProtocol());
+    }
+
+    @Override
+    public long getAccountId() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ip.getAccountId();
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getIp().getAssociatedWithNetworkId();
+    }
+
+    private IpAddress getIp() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        if (ip == null) {
+            throw new InvalidParameterValueException("Unable to find IP address by ID " + ipAddressId);
+        }
+        return ip;
+    }
+
+    @Override
+    public Integer getIcmpCode() {
+        if (icmpCode != null) {
+            return icmpCode;
+        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+            return -1;
+        }
+        return null;
+    }
+
+    @Override
+    public Integer getIcmpType() {
+        if (icmpType != null) {
+            return icmpType;
+        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+                return -1;
+
+        }
+        return null;
+    }
+
+    @Override
+    public Long getRelated() {
+        return null;
+    }
+
+    @Override
+    public FirewallRuleType getType() {
+        if (type != null && type.equalsIgnoreCase("system")) {
+            return FirewallRuleType.System;
+        } else {
+            return FirewallRuleType.User;
+        }
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.FirewallRule;
+    }
+
+    @Override
+    public TrafficType getTrafficType() {
+        return FirewallRule.TrafficType.Ingress;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        if (display != null) {
+            return display;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public List<String> getDestinationCidrList(){
+        return null;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return FirewallRule.class;
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
new file mode 100644
index 0000000..ff11395
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
@@ -0,0 +1,450 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.firewall;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.user.Account;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.VirtualMachine;
+
+
+@APICommand(name = "createPortForwardingRule", description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class, entityType = {FirewallRule.class,
+        VirtualMachine.class, IpAddress.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements PortForwardingRule {
+    public static final Logger s_logger = Logger.getLogger(CreatePortForwardingRuleCmd.class.getName());
+
+    private static final String s_name = "createportforwardingruleresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.IP_ADDRESS_ID,
+               type = CommandType.UUID,
+               entityType = IPAddressResponse.class,
+            required = true,
+    description = "the IP address id of the port forwarding rule")
+    private Long ipAddressId;
+
+    @Parameter(name = ApiConstants.PRIVATE_START_PORT,
+               type = CommandType.INTEGER,
+               required = true,
+            description = "the starting port of port forwarding rule's private port range")
+    private Integer privateStartPort;
+
+    @Parameter(name = ApiConstants.PROTOCOL,
+               type = CommandType.STRING,
+               required = true,
+            description = "the protocol for the port forwarding rule. Valid values are TCP or UDP.")
+    private String protocol;
+
+    @Parameter(name = ApiConstants.PRIVATE_END_PORT,
+               type = CommandType.INTEGER,
+               required = false,
+               description = "the ending port of port forwarding rule's private port range")
+    private Integer privateEndPort;
+
+    @Parameter(name = ApiConstants.PUBLIC_START_PORT,
+               type = CommandType.INTEGER,
+               required = true,
+            description = "the starting port of port forwarding rule's public port range")
+    private Integer publicStartPort;
+
+    @Parameter(name = ApiConstants.PUBLIC_END_PORT,
+               type = CommandType.INTEGER,
+               required = false,
+               description = "the ending port of port forwarding rule's private port range")
+    private Integer publicEndPort;
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+               type = CommandType.UUID,
+               entityType = UserVmResponse.class,
+            required = true,
+                description = "the ID of the virtual machine for the port forwarding rule")
+    private Long virtualMachineId;
+
+    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
+    private List<String> cidrlist;
+
+    @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end public port is automatically created; "
+        + "if false - firewall rule has to be created explicitly. If not specified 1) defaulted to false when PF"
+        + " rule is being created for VPC guest network 2) in all other cases defaulted to true")
+    private Boolean openFirewall;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the network of the virtual machine the port forwarding rule will be created for. "
+                   + "Required when public IP address is not associated with any guest network yet (VPC case).")
+    private Long networkId;
+    @Parameter(name = ApiConstants.VM_GUEST_IP,
+               type = CommandType.STRING,
+               required = false,
+    description = "VM guest nic secondary IP address for the port forwarding rule")
+    private String vmSecondaryIp;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean display;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getIpAddressId() {
+        return ipAddressId;
+    }
+
+    public Ip getVmSecondaryIp() {
+        if (vmSecondaryIp == null) {
+            return null;
+        }
+        return new Ip(vmSecondaryIp);
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol.trim();
+    }
+
+    @Override
+    public long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    @Override
+    public List<String> getSourceCidrList() {
+        if (cidrlist != null) {
+            throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall "
+                + "rule for the specific cidr, please refer to createFirewallRule command");
+        }
+        return null;
+    }
+
+    public Boolean getOpenFirewall() {
+        boolean isVpc = getVpcId() == null ? false : true;
+        if (openFirewall != null) {
+            if (isVpc && openFirewall) {
+                throw new InvalidParameterValueException("Can't have openFirewall=true when IP address belongs to VPC");
+            }
+            return openFirewall;
+        } else {
+            if (isVpc) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private Long getVpcId() {
+        if (ipAddressId != null) {
+            IpAddress ipAddr = _networkService.getIp(ipAddressId);
+            if (ipAddr == null || !ipAddr.readyToUse()) {
+                throw new InvalidParameterValueException("Unable to create PF rule, invalid IP address id " + ipAddressId);
+            } else {
+                return ipAddr.getVpcId();
+            }
+        }
+        return null;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        CallContext callerContext = CallContext.current();
+        boolean success = true;
+        PortForwardingRule rule = null;
+        try {
+            CallContext.current().setEventDetails("Rule Id: " + getEntityId());
+
+            if (getOpenFirewall()) {
+                success = success && _firewallService.applyIngressFirewallRules(ipAddressId, callerContext.getCallingAccount());
+            }
+
+            success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCallingAccount());
+
+            // State is different after the rule is applied, so get new object here
+            rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
+            FirewallRuleResponse fwResponse = new FirewallRuleResponse();
+            if (rule != null) {
+                fwResponse = _responseGenerator.createPortForwardingRuleResponse(rule);
+                setResponseObject(fwResponse);
+            }
+            fwResponse.setResponseName(getCommandName());
+        } finally {
+            if (!success || rule == null) {
+
+                if (getOpenFirewall()) {
+                    _firewallService.revokeRelatedFirewallRule(getEntityId(), true);
+                }
+
+                try {
+                    _rulesService.revokePortForwardingRule(getEntityId(), true);
+                } catch (Exception ex) {
+                    //Ignore e.g. failed to apply rules to device error
+                }
+
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to apply port forwarding rule");
+            }
+        }
+    }
+
+    @Override
+    public long getId() {
+        throw new UnsupportedOperationException("database id can only provided by VO objects");
+    }
+
+    @Override
+    public String getXid() {
+        // FIXME: We should allow for end user to specify Xid.
+        return null;
+    }
+
+    @Override
+    public String getUuid() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Long getSourceIpAddressId() {
+        return ipAddressId;
+    }
+
+    @Override
+    public Integer getSourcePortStart() {
+        return publicStartPort.intValue();
+    }
+
+    @Override
+    public Integer getSourcePortEnd() {
+        return (publicEndPort == null) ? publicStartPort.intValue() : publicEndPort.intValue();
+    }
+
+    @Override
+    public Purpose getPurpose() {
+        return Purpose.PortForwarding;
+    }
+
+    @Override
+    public State getState() {
+        throw new UnsupportedOperationException("Should never call me to find the state");
+    }
+
+    @Override
+    public long getNetworkId() {
+        IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
+        Long ntwkId = null;
+
+        if (ip.getAssociatedWithNetworkId() != null) {
+            ntwkId = ip.getAssociatedWithNetworkId();
+        } else {
+            ntwkId = networkId;
+        }
+        if (ntwkId == null) {
+            throw new InvalidParameterValueException("Unable to create port forwarding rule for the ipAddress id=" + ipAddressId +
+                    " as ip is not associated with any network and no networkId is passed in");
+        }
+        return ntwkId;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
+        // tracked
+    }
+
+    @Override
+    public long getDomainId() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ip.getDomainId();
+    }
+
+    @Override
+    public Ip getDestinationIpAddress() {
+        return null;
+    }
+
+    @Override
+    public void setDestinationIpAddress(Ip destinationIpAddress) {
+        return;
+    }
+
+    @Override
+    public int getDestinationPortStart() {
+        return privateStartPort.intValue();
+    }
+
+    @Override
+    public int getDestinationPortEnd() {
+        return (privateEndPort == null) ? privateStartPort.intValue() : privateEndPort.intValue();
+    }
+
+    @Override
+    public void create() {
+        // cidr list parameter is deprecated
+        if (cidrlist != null) {
+            throw new InvalidParameterValueException(
+                "Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
+        }
+
+        Ip privateIp = getVmSecondaryIp();
+        if (privateIp != null) {
+            if (!NetUtils.isValidIp4(privateIp.toString())) {
+                throw new InvalidParameterValueException("Invalid vm ip address");
+            }
+        }
+
+        try {
+            PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, privateIp, getOpenFirewall(), isDisplay());
+            setEntityId(result.getId());
+            setEntityUuid(result.getUuid());
+        } catch (NetworkRuleConflictException ex) {
+            s_logger.trace("Network Rule Conflict: ", ex);
+            throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage(), ex);
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NET_RULE_ADD;
+    }
+
+    @Override
+    public String getEventDescription() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ("Applying port forwarding  rule for Ip: " + ip.getAddress() + " with virtual machine:" + virtualMachineId);
+    }
+
+    @Override
+    public long getAccountId() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        return ip.getAccountId();
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getIp().getAssociatedWithNetworkId();
+    }
+
+    private IpAddress getIp() {
+        IpAddress ip = _networkService.getIp(ipAddressId);
+        if (ip == null) {
+            throw new InvalidParameterValueException("Unable to find ip address by id " + ipAddressId);
+        }
+        return ip;
+    }
+
+    @Override
+    public Integer getIcmpCode() {
+        return null;
+    }
+
+    @Override
+    public Integer getIcmpType() {
+        return null;
+    }
+
+    @Override
+    public Long getRelated() {
+        return null;
+    }
+
+    @Override
+    public FirewallRuleType getType() {
+        return FirewallRuleType.User;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.FirewallRule;
+    }
+
+    @Override
+    public TrafficType getTrafficType() {
+        return null;
+    }
+
+    @Override
+    public List<String> getDestinationCidrList(){
+        return null;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        if (display != null) {
+            return display;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return FirewallRule.class;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteEgressFirewallRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeleteFirewallRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/DeletePortForwardingRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/IListFirewallRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/IListFirewallRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/IListFirewallRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/IListFirewallRulesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListEgressFirewallRulesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/ListPortForwardingRulesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateEgressFirewallRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdateFirewallRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/guest/ListGuestOsCategoriesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCategoriesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/guest/ListGuestOsCategoriesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCategoriesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/guest/ListGuestOsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/AttachIsoCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/CopyIsoCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/DeleteIsoCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/DetachIsoCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ListIsoPermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/ListIsoPermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/ListIsoPermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
new file mode 100644
index 0000000..f3e884c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
@@ -0,0 +1,222 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.iso;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.template.VirtualMachineTemplate;
+
+@APICommand(name = "registerIso", responseObject = TemplateResponse.class, description = "Registers an existing ISO into the CloudStack Cloud.", responseView = ResponseView.Restricted,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RegisterIsoCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(RegisterIsoCmd.class.getName());
+
+    private static final String s_name = "registerisoresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "true if this ISO is bootable. If not passed explicitly its assumed to be true")
+    private Boolean bootable;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT,
+               type = CommandType.STRING,
+               required = true,
+               description = "the display text of the ISO. This is usually used for display purposes.",
+               length = 4096)
+    private String displayText;
+
+    @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true if you want this ISO to be featured")
+    private Boolean featured;
+
+    @Parameter(name = ApiConstants.IS_PUBLIC,
+               type = CommandType.BOOLEAN,
+               description = "true if you want to register the ISO to be publicly available to all users, false otherwise.")
+    private Boolean publicIso;
+
+    @Parameter(name = ApiConstants.IS_EXTRACTABLE, type = CommandType.BOOLEAN, description = "true if the ISO or its derivatives are extractable; default is false")
+    private Boolean extractable;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the ISO")
+    private String isoName;
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID,
+               type = CommandType.UUID,
+               entityType = GuestOSResponse.class,
+               description = "the ID of the OS type that best represents the OS of this ISO. If the ISO is bootable this parameter needs to be passed")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, length = 2048, description = "the URL to where the ISO is currently being hosted")
+    private String url;
+
+    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
+            required=true, description="the ID of the zone you wish to register the ISO to.")
+    protected Long zoneId;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "an optional domainId. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account name. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this ISO. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
+    private String checksum;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Register ISO for the project")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.IMAGE_STORE_UUID, type = CommandType.STRING, description = "Image store UUID")
+    private String imageStoreUuid;
+
+    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
+               type = CommandType.BOOLEAN,
+               description = "true if ISO contains XS/VMWare tools inorder to support dynamic scaling of VM CPU/memory")
+    protected Boolean isDynamicallyScalable;
+
+    @Parameter(name=ApiConstants.DIRECT_DOWNLOAD,
+            type = CommandType.BOOLEAN,
+            description = "true if ISO should bypass Secondary Storage and be downloaded to Primary Storage on deployment")
+    private Boolean directDownload;
+
+    @Parameter(name = ApiConstants.PASSWORD_ENABLED,
+            type = CommandType.BOOLEAN,
+            description = "true if password reset feature is supported; default is false")
+    private Boolean passwordEnabled;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Boolean isBootable() {
+        return bootable;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Boolean isFeatured() {
+        return featured;
+    }
+
+    public Boolean isPublic() {
+        return publicIso;
+    }
+
+    public Boolean isExtractable() {
+        return extractable;
+    }
+
+    public String getIsoName() {
+        return isoName;
+    }
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public String getChecksum() {
+        return checksum;
+    }
+
+    public String getImageStoreUuid() {
+        return imageStoreUuid;
+    }
+
+    public Boolean isDynamicallyScalable() {
+        return isDynamicallyScalable ==  null ? Boolean.FALSE : isDynamicallyScalable;
+    }
+
+    public boolean isDirectDownload() {
+        return directDownload == null ? false : directDownload;
+    }
+
+    public boolean isPasswordEnabled() {
+        return passwordEnabled == null ? false : passwordEnabled;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public void execute() throws ResourceAllocationException {
+        VirtualMachineTemplate template = _templateService.registerIso(this);
+        if (template != null) {
+            ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
+            List<TemplateResponse> templateResponses = _responseGenerator.createIsoResponses(ResponseView.Restricted, template, zoneId, false);
+            response.setResponses(templateResponses);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to register ISO");
+        }
+
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java
new file mode 100644
index 0000000..0d3c962
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.iso;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.TemplateResponse;
+
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateIso", description = "Updates an ISO file.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateIsoCmd extends BaseUpdateTemplateOrIsoCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateIsoCmd.class.getName());
+    private static final String s_name = "updateisoresponse";
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public Boolean getRequiresHvm() {
+        return null;
+    }
+
+    @Override
+    public String getFormat() {
+        return null;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
+        if (template != null) {
+            return template.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        VirtualMachineTemplate result = _templateService.updateTemplate(this);
+        if (result != null) {
+            TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(ResponseView.Restricted, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update ISO");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoPermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/iso/UpdateIsoPermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoPermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/iso/UpdateIsoPermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/job/ListAsyncJobsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/job/QueryAsyncJobResultCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/job/QueryAsyncJobResultCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/job/QueryAsyncJobResultCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/job/QueryAsyncJobResultCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateApplicationLoadBalancerCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBHealthCheckPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLBStickinessPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteApplicationLoadBalancerCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBHealthCheckPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLBStickinessPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteSslCertCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteSslCertCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/DeleteSslCertCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteSslCertCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListApplicationLoadBalancersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLBHealthCheckPoliciesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLBStickinessPoliciesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRuleInstancesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerRulesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListSslCertsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListSslCertsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/ListSslCertsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListSslCertsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveFromLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateApplicationLoadBalancerCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBHealthCheckPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLBStickinessPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/nat/DeleteIpForwardingRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/nat/DisableStaticNatCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/nat/EnableStaticNatCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/ListIpForwardingRulesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/nat/ListIpForwardingRulesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/nat/ListIpForwardingRulesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/nat/ListIpForwardingRulesCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java
new file mode 100644
index 0000000..2b2a3c6
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java
@@ -0,0 +1,250 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.api.response.NetworkACLResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.user.Account;
+import com.cloud.utils.net.NetUtils;
+
+@APICommand(name = "createNetworkACL", description = "Creates a ACL rule in the given network (the network has to belong to VPC)", responseObject = NetworkACLItemResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateNetworkACLCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateNetworkACLCmd.class.getName());
+
+    private static final String s_name = "createnetworkaclresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
+    private String protocol;
+
+    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of ACL")
+    private Integer publicStartPort;
+
+    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL")
+    private Integer publicEndPort;
+
+    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to allow traffic from/to")
+    private List<String> cidrlist;
+
+    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
+    private Integer icmpType;
+
+    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
+    private Integer icmpCode;
+
+    @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the ACL will be created for")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.ACL_ID, type = CommandType.UUID, entityType = NetworkACLResponse.class, description = "The network of the VM the ACL will be created for")
+    private Long aclId;
+
+    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the ACL," + "can be ingress or egress, defaulted to ingress if not specified")
+    private String trafficType;
+
+    @Parameter(name = ApiConstants.NUMBER, type = CommandType.INTEGER, description = "The number of the ACL item, its ordering")
+    private Integer number;
+
+    @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "scl entry action, allow or deny")
+    private String action;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {
+            RoleType.Admin})
+    private Boolean display;
+
+    @Parameter(name = ApiConstants.ACL_REASON, type = CommandType.STRING, description = "A description indicating why the ACL rule is required.")
+    private String reason;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public boolean isDisplay() {
+        if (display != null) {
+            return display;
+        } else {
+            return true;
+        }
+    }
+
+    public String getProtocol() {
+        String p = protocol.trim();
+        // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code
+        if (StringUtils.isNumeric(p)) {
+            int protoNumber = Integer.parseInt(p);
+            if (protoNumber == 1) {
+                p = "icmp";
+            }
+        }
+        return p;
+    }
+
+    public List<String> getSourceCidrList() {
+        if (cidrlist != null) {
+            return cidrlist;
+        } else {
+            List<String> oneCidrList = new ArrayList<String>();
+            oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
+            return oneCidrList;
+        }
+    }
+
+    public NetworkACLItem.TrafficType getTrafficType() {
+        if (trafficType == null) {
+            return NetworkACLItem.TrafficType.Ingress;
+        }
+        for (NetworkACLItem.TrafficType type : NetworkACLItem.TrafficType.values()) {
+            if (type.toString().equalsIgnoreCase(trafficType)) {
+                return type;
+            }
+        }
+        throw new InvalidParameterValueException("Invalid traffic type " + trafficType);
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public Integer getSourcePortStart() {
+        return publicStartPort;
+    }
+
+    public Integer getSourcePortEnd() {
+        if (publicEndPort == null) {
+            if (publicStartPort != null) {
+                return publicStartPort;
+            }
+        } else {
+            return publicEndPort;
+        }
+
+        return null;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        return caller.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Creating Network ACL Item";
+    }
+
+    public Integer getIcmpCode() {
+        if (icmpCode != null) {
+            return icmpCode;
+        } else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+            return -1;
+        }
+        return null;
+    }
+
+    public Integer getIcmpType() {
+        if (icmpType != null) {
+            return icmpType;
+        } else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+            return -1;
+
+        }
+        return null;
+    }
+
+    public Long getACLId() {
+        return aclId;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    @Override
+    public void create() {
+        NetworkACLItem result = _networkACLService.createNetworkACLItem(this);
+        setEntityId(result.getId());
+        setEntityUuid(result.getUuid());
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        boolean success = false;
+        NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId());
+        try {
+            CallContext.current().setEventDetails("Rule ID: " + getEntityId());
+            success = _networkACLService.applyNetworkACL(rule.getAclId());
+
+            // State is different after the rule is applied, so get new object here
+            rule = _networkACLService.getNetworkACLItem(getEntityId());
+            NetworkACLItemResponse aclResponse = new NetworkACLItemResponse();
+            if (rule != null) {
+                aclResponse = _responseGenerator.createNetworkACLItemResponse(rule);
+                setResponseObject(aclResponse);
+            }
+            aclResponse.setResponseName(getCommandName());
+        } finally {
+            if (!success || rule == null) {
+                _networkACLService.revokeNetworkACLItem(getEntityId());
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network ACL Item");
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkACLListCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/CreateNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkACLListCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/DeleteNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkACLListsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkACLsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworkOfferingsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java
new file mode 100644
index 0000000..a61c597
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.network.Network;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listNetworks", description = "Lists all available networks.", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListNetworksCmd extends BaseListTaggedResourcesCmd {
+    public static final Logger s_logger = Logger.getLogger(ListNetworksCmd.class.getName());
+    private static final String s_name = "listnetworksresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list networks by ID")
+    private Long id;
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone ID of the network")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "the type of the network. Supported values are: isolated and shared")
+    private String guestIpType;
+
+    @Parameter(name = ApiConstants.IS_SYSTEM, type = CommandType.BOOLEAN, description = "true if network is system, false otherwise")
+    private Boolean isSystem;
+
+    @Parameter(name = ApiConstants.ACL_TYPE, type = CommandType.STRING, description = "list networks by ACL (access control list) type. Supported values are account and domain")
+    private String aclType;
+
+    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "type of the traffic")
+    private String trafficType;
+
+    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "list networks by physical network id")
+    private Long physicalNetworkId;
+
+    @Parameter(name = ApiConstants.SUPPORTED_SERVICES, type = CommandType.LIST, collectionType = CommandType.STRING, description = "list networks supporting certain services")
+    private List<String> supportedServices;
+
+    @Parameter(name = ApiConstants.RESTART_REQUIRED, type = CommandType.BOOLEAN, description = "list networks by restartRequired")
+    private Boolean restartRequired;
+
+    @Parameter(name = ApiConstants.SPECIFY_IP_RANGES, type = CommandType.BOOLEAN, description = "true if need to list only networks which support specifying IP ranges")
+    private Boolean specifyIpRanges;
+
+    @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List networks by VPC")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.CAN_USE_FOR_DEPLOY, type = CommandType.BOOLEAN, description = "list networks available for VM deployment")
+    private Boolean canUseForDeploy;
+
+    @Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "the network belongs to VPC")
+    private Boolean forVpc;
+
+    @Parameter(name = ApiConstants.DISPLAY_NETWORK, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean display;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public String getGuestIpType() {
+        return guestIpType;
+    }
+
+    public Boolean getIsSystem() {
+        return isSystem;
+    }
+
+    public String getAclType() {
+        return aclType;
+    }
+
+    public String getTrafficType() {
+        return trafficType;
+    }
+
+    public Long getPhysicalNetworkId() {
+        return physicalNetworkId;
+    }
+
+    public List<String> getSupportedServices() {
+        return supportedServices;
+    }
+
+    public Boolean isRestartRequired() {
+        return restartRequired;
+    }
+
+    public Boolean isSpecifyIpRanges() {
+        return specifyIpRanges;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Boolean canUseForDeploy() {
+        return canUseForDeploy;
+    }
+
+    public Boolean getForVpc() {
+        return forVpc;
+    }
+
+    @Override
+    public Boolean getDisplay() {
+        if (display != null) {
+            return display;
+        }
+        return super.getDisplay();
+    }
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        Pair<List<? extends Network>, Integer> networks = _networkService.searchForNetworks(this);
+        ListResponse<NetworkResponse> response = new ListResponse<NetworkResponse>();
+        List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
+        for (Network network : networks.first()) {
+            NetworkResponse networkResponse = _responseGenerator.createNetworkResponse(ResponseView.Restricted, network);
+            networkResponses.add(networkResponse);
+        }
+        response.setResponses(networkResponses, networks.second());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java
new file mode 100644
index 0000000..0343e50
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/MoveNetworkAclItemCmd.java
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.network;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.user.Account;
+
+@APICommand(name = "moveNetworkAclItem", description = "Move an ACL rule to a position bettwen two other ACL rules of the same ACL network list", responseObject = NetworkACLItemResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class MoveNetworkAclItemCmd extends BaseAsyncCustomIdCmd {
+
+    public static final Logger s_logger = Logger.getLogger(MoveNetworkAclItemCmd.class.getName());
+    private static final String s_name = "moveNetworkAclItemResponse";
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true, description = "The ID of the network ACL rule that is being moved to a new position.")
+    private String uuidRuleBeingMoved;
+
+    @Parameter(name = ApiConstants.PREVIOUS_ACL_RULE_ID, type = CommandType.STRING, description = "The ID of the first rule that is right before the new position where the rule being moved is going to be placed. This value can be 'NULL' if the rule is being moved to the first position of the network ACL list.")
+    private String previousAclRuleUuid;
+
+    @Parameter(name = ApiConstants.NEXT_ACL_RULE_ID, type = CommandType.STRING, description = "The ID of the rule that is right after the new position where the rule being moved is going to be placed. This value can be 'NULL' if the rule is being moved to the last position of the network ACL list.")
+    private String nextAclRuleUuid;
+
+    @Parameter(name = ApiConstants.MOVE_ACL_CONSISTENCY_HASH, type = CommandType.STRING, description = "Md5 hash used to check the consistency of the ACL rule list before applying the ACL rule move. This check is useful to manage concurrency problems that may happen when multiple users are editing the same ACL rule listing. The parameter is not required. Therefore, if the user does not send it, he/she is assuming the risk of moving ACL rules without checking the consistency of the access control list before executing the move. We use MD5 hash function on a String that is composed of all UUIDs of the ACL rules in concatenated in their respective order (order defined via 'number' field).")
+    private String aclConsistencyHash;
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(getEventDescription());
+
+        NetworkACLItem aclItem = _networkACLService.moveNetworkAclRuleToNewPosition(this);
+
+        NetworkACLItemResponse aclResponse = _responseGenerator.createNetworkACLItemResponse(aclItem);
+        setResponseObject(aclResponse);
+        aclResponse.setResponseName(getCommandName());
+    }
+
+    public String getUuidRuleBeingMoved() {
+        return uuidRuleBeingMoved;
+    }
+
+    public String getPreviousAclRuleUuid() {
+        return previousAclRuleUuid;
+    }
+
+    public String getNextAclRuleUuid() {
+        return nextAclRuleUuid;
+    }
+
+    @Override
+    public void checkUuid() {
+        if (this.getCustomId() != null) {
+            _uuidMgr.checkUuid(this.getCustomId(), NetworkACLItem.class);
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NETWORK_ACL_ITEM_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return String.format("Placing network ACL item [%s] between [%s] and [%s].", uuidRuleBeingMoved, previousAclRuleUuid, nextAclRuleUuid);
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        return caller.getAccountId();
+    }
+
+    public String getAclConsistencyHash() {
+        return aclConsistencyHash;
+    }
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/ReplaceNetworkACLListCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/RestartNetworkCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java
new file mode 100644
index 0000000..1215f57
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java
@@ -0,0 +1,197 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.network;
+
+import java.util.List;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateNetworkACLItem", description = "Updates ACL item with specified ID", responseObject = NetworkACLItemResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateNetworkACLItemCmd extends BaseAsyncCustomIdCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateNetworkACLItemCmd.class.getName());
+
+    private static final String s_name = "createnetworkaclresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkACLItemResponse.class, required = true, description = "the ID of the network ACL item")
+    private Long id;
+
+    @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
+    private String protocol;
+
+    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of ACL")
+    private Integer publicStartPort;
+
+    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL")
+    private Integer publicEndPort;
+
+    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to allow traffic from/to")
+    private List<String> cidrlist;
+
+    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
+    private Integer icmpType;
+
+    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
+    private Integer icmpCode;
+
+    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the ACL, can be Ingress or Egress, defaulted to Ingress if not specified")
+    private String trafficType;
+
+    @Parameter(name = ApiConstants.NUMBER, type = CommandType.INTEGER, description = "The network of the vm the ACL will be created for")
+    private Integer number;
+
+    @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "scl entry action, allow or deny")
+    private String action;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {
+            RoleType.Admin})
+    private Boolean display;
+
+    @Parameter(name = ApiConstants.ACL_REASON, type = CommandType.STRING, description = "A description indicating why the ACL rule is required.")
+    private String reason;
+
+    @Parameter(name = ApiConstants.ACL_RULE_PARTIAL_UPGRADE, type = CommandType.BOOLEAN, required = false, description = "Indicates if the ACL rule is to be updated partially (merging the parameters sent with current configuration) or completely (disconsidering all of the current configurations). The default value is 'true'.")
+    private boolean partialUpgrade = true;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public boolean isDisplay() {
+        if (display != null) {
+            return display;
+        } else {
+            return true;
+        }
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getProtocol() {
+        if (protocol != null) {
+            return protocol.trim();
+        } else {
+            return null;
+        }
+    }
+
+    public List<String> getSourceCidrList() {
+        return cidrlist;
+    }
+
+    public NetworkACLItem.TrafficType getTrafficType() {
+        if (trafficType != null) {
+            for (NetworkACLItem.TrafficType type : NetworkACLItem.TrafficType.values()) {
+                if (type.toString().equalsIgnoreCase(trafficType)) {
+                    return type;
+                }
+            }
+        }
+        return null;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public Integer getSourcePortStart() {
+        return publicStartPort;
+    }
+
+    public Integer getSourcePortEnd() {
+        return publicEndPort;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        return caller.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NETWORK_ACL_ITEM_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Updating network ACL item";
+    }
+
+    public Integer getIcmpCode() {
+        return icmpCode;
+    }
+
+    public Integer getIcmpType() {
+        return icmpType;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        CallContext.current().setEventDetails("Rule Id: " + getId());
+        NetworkACLItem aclItem = _networkACLService.updateNetworkACLItem(this);
+        NetworkACLItemResponse aclResponse = _responseGenerator.createNetworkACLItemResponse(aclItem);
+        setResponseObject(aclResponse);
+        aclResponse.setResponseName(getCommandName());
+    }
+
+    @Override
+    public void checkUuid() {
+        if (this.getCustomId() != null) {
+            _uuidMgr.checkUuid(this.getCustomId(), NetworkACLItem.class);
+        }
+    }
+
+    public boolean isPartialUpgrade() {
+        return partialUpgrade;
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java
new file mode 100644
index 0000000..22eaf21
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.network;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.NetworkACLResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.vpc.NetworkACL;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateNetworkACLList", description = "Updates network ACL list", responseObject = SuccessResponse.class, since = "4.4", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateNetworkACLListCmd extends BaseAsyncCustomIdCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateNetworkACLListCmd.class.getName());
+    private static final String s_name = "updatenetworkacllistresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkACLResponse.class, required = true, description = "the ID of the network ACL")
+    private Long id;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the list to the end user or not", since = "4.4", authorized = {
+            RoleType.Admin})
+    private Boolean display;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the network ACL list")
+    private String name;
+
+    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Description of the network ACL list")
+    private String description;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Boolean getDisplay() {
+        return display;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NETWORK_ACL_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return ("Updating network ACL list ID=" + id);
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        return caller.getAccountId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        NetworkACL acl = _networkACLService.updateNetworkACL(this);
+        NetworkACLResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl);
+        setResponseObject(aclResponse);
+        aclResponse.setResponseName(getCommandName());
+    }
+
+    @Override
+    public void checkUuid() {
+        if (this.getCustomId() != null) {
+            _uuidMgr.checkUuid(this.getCustomId(), NetworkACL.class);
+        }
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/offering/ListDiskOfferingsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListDiskOfferingsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/offering/ListDiskOfferingsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListDiskOfferingsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/ActivateProjectCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java
new file mode 100644
index 0000000..79e372e
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.project;
+
+import org.apache.cloudstack.api.ApiArgValidator;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.projects.Project;
+import com.cloud.user.Account;
+
+@APICommand(name = "createProject", description = "Creates a project", responseObject = ProjectResponse.class, since = "3.0.0",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateProjectCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateProjectCmd.class.getName());
+
+    private static final String s_name = "createprojectresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will be Admin for the project")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning a project")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, validations = ApiArgValidator.NotNullOrEmpty, description = "name of the project")
+    private String name;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, validations = ApiArgValidator.NotNullOrEmpty, description = "display text of the project")
+    private String displayText;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public String getAccountName() {
+        if (accountName != null) {
+            return accountName;
+        } else {
+            return CallContext.current().getCallingAccount().getAccountName();
+        }
+    }
+
+    public Long getDomainId() {
+        if (domainId != null) {
+            return domainId;
+        } else {
+            return CallContext.current().getCallingAccount().getDomainId();
+        }
+
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+
+        if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
+            throw new InvalidParameterValueException("Account name and domain id must be specified together");
+        }
+
+        if (accountName != null) {
+            return _accountService.finalizeOwner(caller, accountName, domainId, null).getId();
+        }
+
+        return caller.getId();
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public void execute() {
+        Project project = _projectService.enableProject(this.getEntityId());
+        if (project != null) {
+            ProjectResponse response = _responseGenerator.createProjectResponse(project);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a project");
+        }
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        CallContext.current().setEventDetails("Project Name: " + getName());
+        Project project = _projectService.createProject(getName(), getDisplayText(), getAccountName(), getDomainId());
+        if (project != null) {
+            this.setEntityId(project.getId());
+            this.setEntityUuid(project.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a project");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_PROJECT_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "creating project";
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/DeleteProjectInvitationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/ListProjectInvitationsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/ListProjectsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/ListProjectsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/ListProjectsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/ListProjectsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/SuspendProjectCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/project/UpdateProjectInvitationCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ListRegionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ListRegionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ListRegionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ListRegionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/GetCloudIdentifierCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/resource/GetCloudIdentifierCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/resource/GetCloudIdentifierCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/resource/GetCloudIdentifierCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/ListHypervisorsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/resource/ListHypervisorsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/resource/ListHypervisorsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/resource/ListHypervisorsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/resource/ListResourceLimitsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/resource/UpdateResourceCountCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/resource/UpdateResourceLimitCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupEgressCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/AuthorizeSecurityGroupIngressCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/CreateSecurityGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/DeleteSecurityGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/ListSecurityGroupsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupEgressCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/securitygroup/RevokeSecurityGroupIngressCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java
new file mode 100644
index 0000000..4cf6e85
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ArchiveSnapshotCmd.java
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.snapshot;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.storage.Snapshot;
+import com.cloud.user.Account;
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+@APICommand(name = "archiveSnapshot", description = "Archives (moves) a snapshot on primary storage to secondary storage",
+        responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ArchiveSnapshotCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateSnapshotCmd.class.getName());
+    private static final String s_name = "createsnapshotresponse";
+
+    @ACL(accessType = SecurityChecker.AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = SnapshotResponse.class,
+            required=true, description="The ID of the snapshot")
+    private Long id;
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SNAPSHOT_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Archiving snapshot " + id + " to secondary storage";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+        CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class,getId()));
+        Snapshot snapshot = _snapshotService.archiveSnapshot(getId());
+        if (snapshot != null) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to archive snapshot");
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Snapshot snapshot = _entityMgr.findById(Snapshot.class, getId());
+        if (snapshot != null) {
+            return snapshot.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    public Long getId() {
+        return id;
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java
new file mode 100644
index 0000000..8c2a7e4
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java
@@ -0,0 +1,252 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.snapshot;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.projects.Project;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.log4j.Logger;
+
+@APICommand(name = "createSnapshot", description = "Creates an instant snapshot of a volume.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateSnapshotCmd.class.getName());
+    private static final String s_name = "createsnapshotresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ACCOUNT,
+               type = CommandType.STRING,
+               description = "The account of the snapshot. The account parameter must be used with the domainId parameter.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+            description = "The domain ID of the snapshot. If used with the account parameter, specifies a domain for the account associated with the disk volume.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "The ID of the disk volume")
+    private Long volumeId;
+
+    @Parameter(name = ApiConstants.POLICY_ID,
+               type = CommandType.UUID,
+               entityType = SnapshotPolicyResponse.class,
+            description = "policy id of the snapshot, if this is null, then use MANUAL_POLICY.")
+    private Long policyId;
+
+    @Parameter(name = ApiConstants.SNAPSHOT_QUIESCEVM, type = CommandType.BOOLEAN, required = false, description = "quiesce vm if true")
+    private Boolean quiescevm;
+
+    @Parameter(name = ApiConstants.LOCATION_TYPE, type = CommandType.STRING, required = false, description = "Currently applicable only for managed storage. " +
+            "Valid location types: 'primary', 'secondary'. Default = 'primary'.")
+    private String locationType;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the snapshot")
+    private String snapshotName;
+
+    @Parameter(name = ApiConstants.ASYNC_BACKUP, type = CommandType.BOOLEAN, required = false, description = "asynchronous backup if true")
+    private Boolean asyncBackup;
+
+    private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Boolean getQuiescevm() {
+        if (quiescevm == null) {
+            return false;
+        } else {
+            return quiescevm;
+        }
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public String getSnapshotName() {
+        return snapshotName;
+    }
+
+    public Long getPolicyId() {
+        if (policyId != null) {
+            return policyId;
+        } else {
+            return Snapshot.MANUAL_POLICY_ID;
+        }
+    }
+
+    private Long getHostId() {
+        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
+        if (volume == null) {
+            throw new InvalidParameterValueException("Unable to find volume by id");
+        }
+        return _snapshotService.getHostIdForSnapshotOperation(volume);
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return ApiConstants.SNAPSHOT;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+
+        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
+        if (volume == null) {
+            throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
+        }
+
+        Account account = _accountService.getAccount(volume.getAccountId());
+        //Can create templates for enabled projects/accounts only
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            Project project = _projectService.findByProjectAccountId(volume.getAccountId());
+            if (project.getState() != Project.State.Active) {
+                throw new PermissionDeniedException("Can't add resources to the project id=" + project.getId() + " in state=" + project.getState() +
+                    " as it's no longer active");
+            }
+        } else if (account.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of template is disabled: " + account);
+        }
+
+        return volume.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SNAPSHOT_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "creating snapshot for volume: " + this._uuidMgr.getUuid(Volume.class, getVolumeId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Snapshot;
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        Snapshot snapshot = _volumeService.allocSnapshot(getVolumeId(), getPolicyId(), getSnapshotName(), getLocationType());
+        if (snapshot != null) {
+            setEntityId(snapshot.getId());
+            setEntityUuid(snapshot.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot");
+        }
+    }
+
+    @Override
+    public void execute() {
+        Snapshot snapshot;
+        try {
+            snapshot =
+                _volumeService.takeSnapshot(getVolumeId(), getPolicyId(), getEntityId(), _accountService.getAccount(getEntityOwnerId()), getQuiescevm(), getLocationType(), getAsyncBackup());
+
+            if (snapshot != null) {
+                SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + getVolumeId());
+            }
+        } catch (Exception e) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + getVolumeId());
+        }
+    }
+
+    private Snapshot.LocationType getLocationType() {
+
+        if (Snapshot.LocationType.values() == null || Snapshot.LocationType.values().length == 0 || locationType == null) {
+            return null;
+        }
+
+        try {
+            String lType = locationType.trim().toUpperCase();
+            return Snapshot.LocationType.valueOf(lType);
+        } catch (IllegalArgumentException e) {
+            String errMesg = "Invalid locationType " + locationType + "Specified for volume " + getVolumeId()
+                        + " Valid values are: primary,secondary ";
+            s_logger.warn(errMesg);
+            throw  new CloudRuntimeException(errMesg);
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (getSyncObjId() != null) {
+            return syncObjectType;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (getHostId() != null) {
+            return getHostId();
+        }
+        return null;
+    }
+
+    public Boolean getAsyncBackup() {
+        if (asyncBackup == null) {
+            return false;
+        } else {
+            return asyncBackup;
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java
new file mode 100644
index 0000000..556b041
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java
@@ -0,0 +1,219 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.snapshot;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.projects.Project;
+import com.cloud.storage.Snapshot;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.snapshot.VMSnapshot;
+
+@APICommand(name = "createSnapshotFromVMSnapshot", description = "Creates an instant snapshot of a volume from existing vm snapshot.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, since = "4.10.0",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateSnapshotFromVMSnapshotCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateSnapshotFromVMSnapshotCmd.class.getName());
+    private static final String s_name = "createsnapshotfromvmsnapshotresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "The ID of the disk volume")
+    private Long volumeId;
+
+    @Parameter(name=ApiConstants.VM_SNAPSHOT_ID, type=CommandType.UUID, entityType=VMSnapshotResponse.class,
+            required=true, description="The ID of the VM snapshot")
+    private Long vmSnapshotId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the snapshot")
+    private String snapshotName;
+
+    private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public Long getVMSnapshotId() {
+        return vmSnapshotId;
+    }
+
+    public String getSnapshotName() {
+        return snapshotName;
+    }
+
+    private Long getVmId() {
+        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
+        if (vmsnapshot == null) {
+            throw new InvalidParameterValueException("Unable to find vm snapshot by id=" + getVMSnapshotId());
+        }
+        UserVm vm = _entityMgr.findById(UserVm.class, vmsnapshot.getVmId());
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find vm by vm snapshot id=" + getVMSnapshotId());
+        }
+        return vm.getId();
+    }
+    private Long getHostId() {
+        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
+        if (vmsnapshot == null) {
+            throw new InvalidParameterValueException("Unable to find vm snapshot by id=" + getVMSnapshotId());
+        }
+        UserVm vm = _entityMgr.findById(UserVm.class, vmsnapshot.getVmId());
+        if (vm != null) {
+            if(vm.getHostId() != null) {
+                return vm.getHostId();
+            } else if(vm.getLastHostId() != null) {
+                return vm.getLastHostId();
+            }
+        }
+        return null;
+    }
+
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return ApiConstants.SNAPSHOT;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+
+        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
+        if (vmsnapshot == null) {
+            throw new InvalidParameterValueException("Unable to find vmsnapshot by id=" + getVMSnapshotId());
+        }
+
+        Account account = _accountService.getAccount(vmsnapshot.getAccountId());
+        //Can create templates for enabled projects/accounts only
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            Project project = _projectService.findByProjectAccountId(vmsnapshot.getAccountId());
+            if (project == null) {
+                throw new InvalidParameterValueException("Unable to find project by account id=" + account.getUuid());
+            }
+            if (project.getState() != Project.State.Active) {
+                throw new PermissionDeniedException("Can't add resources to the project id=" + project.getUuid() + " in state=" + project.getState() + " as it's no longer active");
+            }
+        } else if (account.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of template is disabled: " + account);
+        }
+
+        return vmsnapshot.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SNAPSHOT_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "creating snapshot from vm snapshot : " + this._uuidMgr.getUuid(VMSnapshot.class, getVMSnapshotId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Snapshot;
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        Snapshot snapshot = this._volumeService.allocSnapshotForVm(getVmId(), getVolumeId(), getSnapshotName());
+        if (snapshot != null) {
+            this.setEntityId(snapshot.getId());
+            this.setEntityUuid(snapshot.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot from vm snapshot");
+        }
+    }
+
+    @Override
+    public void execute() {
+        s_logger.info("CreateSnapshotFromVMSnapshotCmd with vm snapshot id:" + getVMSnapshotId() + " and snapshot id:" + getEntityId() + " starts:" + System.currentTimeMillis());
+        CallContext.current().setEventDetails("Vm Snapshot Id: "+ this._uuidMgr.getUuid(VMSnapshot.class, getVMSnapshotId()));
+        Snapshot snapshot = null;
+        try {
+            snapshot = _snapshotService.backupSnapshotFromVmSnapshot(getEntityId(), getVmId(), getVolumeId(), getVMSnapshotId());
+            if (snapshot != null) {
+                SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot from vm snapshot " + getVMSnapshotId());
+            }
+        } catch (InvalidParameterValueException ex) {
+            throw ex;
+        } catch (Exception e) {
+            s_logger.debug("Failed to create snapshot", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot from vm snapshot " + getVMSnapshotId());
+        } finally {
+            if (snapshot == null) {
+                try {
+                    _snapshotService.deleteSnapshot(getEntityId());
+                } catch (Exception e) {
+                    s_logger.debug("Failed to clean failed snapshot" + getEntityId());
+                }
+            }
+        }
+    }
+
+
+    @Override
+    public String getSyncObjType() {
+        if (getSyncObjId() != null) {
+            return syncObjectType;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (getHostId() != null) {
+            return getHostId();
+        }
+        return null;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotPolicyCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java
new file mode 100644
index 0000000..452135f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java
@@ -0,0 +1,111 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.snapshot;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Snapshot;
+import com.cloud.user.Account;
+
+@APICommand(name = "deleteSnapshot", description = "Deletes a snapshot of a disk volume.", responseObject = SuccessResponse.class, entityType = {Snapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DeleteSnapshotCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DeleteSnapshotCmd.class.getName());
+    private static final String s_name = "deletesnapshotresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = SnapshotResponse.class,
+            required=true, description="The ID of the snapshot")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Snapshot snapshot = _entityMgr.findById(Snapshot.class, getId());
+        if (snapshot != null) {
+            return snapshot.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SNAPSHOT_DELETE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "deleting snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Snapshot;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getId()));
+        boolean result = _snapshotService.deleteSnapshot(getId());
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete snapshot");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotPoliciesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotPoliciesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotPoliciesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotPoliciesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java
new file mode 100644
index 0000000..20a638c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.api.command.user.snapshot;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Snapshot;
+import com.cloud.user.Account;
+
+@APICommand(name = "revertSnapshot", description = "This is supposed to revert a volume snapshot. This command is only supported with KVM so far", responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RevertSnapshotCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RevertSnapshotCmd.class.getName());
+    private static final String s_name = "revertsnapshotresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name= ApiConstants.ID, type= BaseCmd.CommandType.UUID, entityType = SnapshotResponse.class,
+            required=true, description="The ID of the snapshot")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Snapshot snapshot = _entityMgr.findById(Snapshot.class, getId());
+        if (snapshot != null) {
+            return snapshot.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_SNAPSHOT_REVERT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "revert snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Snapshot;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getId()));
+        Snapshot snapshot = _snapshotService.revertSnapshot(getId());
+        if (snapshot != null) {
+            SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to revert snapshot");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/UpdateSnapshotPolicyCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/ssh/CreateSSHKeyPairCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/ssh/DeleteSSHKeyPairCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/ssh/ListSSHKeyPairsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/ssh/RegisterSSHKeyPairCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/tag/CreateTagsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/tag/DeleteTagsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/tag/ListTagsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java
new file mode 100644
index 0000000..db45f75
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java
@@ -0,0 +1,198 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.template;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.cloud.dc.DataCenter;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "copyTemplate", description = "Copies a template from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CopyTemplateCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(CopyTemplateCmd.class.getName());
+    private static final String s_name = "copytemplateresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.DESTINATION_ZONE_ID,
+               type = CommandType.UUID,
+               entityType = ZoneResponse.class,
+               required = false,
+               description = "ID of the zone the template is being copied to.")
+    protected Long destZoneId;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
+            entityType = TemplateResponse.class, required = true, description = "Template ID.")
+    private Long id;
+
+    @Parameter(name = ApiConstants.SOURCE_ZONE_ID,
+               type = CommandType.UUID,
+               entityType = ZoneResponse.class,
+            description = "ID of the zone the template is currently hosted on. " +
+                    "If not specified and template is cross-zone, " +
+                    "then we will sync this template to region wide image store.")
+    private Long sourceZoneId;
+
+    @Parameter(name = ApiConstants.DESTINATION_ZONE_ID_LIST,
+                    type=CommandType.LIST,
+                    collectionType = CommandType.UUID,
+                    entityType = ZoneResponse.class,
+                    required = false,
+                    description = "A list of IDs of the zones that the template needs to be copied to." +
+                            "Specify this list if the template needs to copied to multiple zones in one go. " +
+                            "Do not specify destzoneid and destzoneids together, however one of them is required.")
+    protected List<Long> destZoneIds;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public List<Long> getDestinationZoneIds() {
+        if (destZoneIds != null && destZoneIds.size() != 0) {
+            return destZoneIds;
+        }
+        if (destZoneId != null) {
+            List < Long > destIds = new ArrayList<>();
+            destIds.add(destZoneId);
+            return destIds;
+        }
+        return null;
+    }
+
+    public Long getDestinationZoneId() {
+        return destZoneId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getSourceZoneId() {
+        return sourceZoneId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getStaticName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
+        if (template != null) {
+            return template.getAccountId();
+        }
+
+        // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_TEMPLATE_COPY;
+    }
+
+    @Override
+    public String getEventDescription() {
+        StringBuilder descBuilder = new StringBuilder();
+        if (getDestinationZoneIds() != null) {
+
+            for (Long destId : getDestinationZoneIds()) {
+                descBuilder.append(", ");
+                descBuilder.append(this._uuidMgr.getUuid(DataCenter.class, destId));
+            }
+            if (descBuilder.length() > 0) {
+                descBuilder.deleteCharAt(0);
+            }
+        }
+
+        return  "copying template: " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()) +((getSourceZoneId() != null) ? " from zone: " + this._uuidMgr.getUuid(DataCenter.class, getSourceZoneId()) : "") + ((descBuilder.length() > 0) ? " to zones: " + descBuilder.toString() : "");
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Template;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceAllocationException {
+        try {
+            if (destZoneId == null && (destZoneIds == null || destZoneIds.size() == 0))
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
+                        "Either destzoneid or destzoneids parameters have to be specified.");
+
+            if (destZoneId != null && destZoneIds != null && destZoneIds.size() != 0)
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
+                        "Both destzoneid and destzoneids cannot be specified at the same time.");
+
+            CallContext.current().setEventDetails(getEventDescription());
+            VirtualMachineTemplate template = _templateService.copyTemplate(this);
+
+            if (template != null){
+                List<TemplateResponse> listResponse = _responseGenerator.createTemplateResponses(ResponseView.Restricted,
+                                                            template, getDestinationZoneIds(), false);
+                TemplateResponse response = new TemplateResponse();
+                if (listResponse != null && !listResponse.isEmpty()) {
+                    response = listResponse.get(0);
+                }
+
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to copy template");
+            }
+        } catch (StorageUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
new file mode 100644
index 0000000..aa8ecee
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
@@ -0,0 +1,325 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.template;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.projects.Project;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "createTemplate", responseObject = TemplateResponse.class, description = "Creates a template of a virtual machine. " + "The virtual machine must be in a STOPPED state. "
+        + "A template created from this command is automatically designated as a private template visible to the account that created it.", responseView = ResponseView.Restricted,
+    requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateTemplateCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateTemplateCmd.class.getName());
+    private static final String s_name = "createtemplateresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.BITS, type = CommandType.INTEGER, description = "32 or 64 bit")
+    private Integer bits;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT,
+               type = CommandType.STRING,
+               required = true,
+               description = "the display text of the template. This is usually used for display purposes.",
+               length = 4096)
+    private String displayText;
+
+    @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true if this template is a featured template, false otherwise")
+    private Boolean featured;
+
+    @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, description = "true if this template is a public template, false otherwise")
+    private Boolean publicTemplate;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the template")
+    private String templateName;
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID,
+               type = CommandType.UUID,
+               entityType = GuestOSResponse.class,
+               required = true,
+               description = "the ID of the OS Type that best represents the OS of this template.")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.PASSWORD_ENABLED,
+               type = CommandType.BOOLEAN,
+               description = "true if the template supports the password reset feature; default is false")
+    private Boolean passwordEnabled;
+
+    @Parameter(name = ApiConstants.SSHKEY_ENABLED, type = CommandType.BOOLEAN, description = "true if the template supports the sshkey upload feature; default is false")
+    private Boolean sshKeyEnabled;
+
+    @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if the template requres HVM, false otherwise")
+    private Boolean requiresHvm;
+
+    @Parameter(name = ApiConstants.SNAPSHOT_ID,
+               type = CommandType.UUID,
+               entityType = SnapshotResponse.class,
+            description = "the ID of the snapshot the template is being created from. Either this parameter, or volumeId has to be passed in")
+    protected Long snapshotId;
+
+    @Parameter(name = ApiConstants.VOLUME_ID,
+               type = CommandType.UUID,
+               entityType = VolumeResponse.class,
+            description = "the ID of the disk volume the template is being created from. Either this parameter, or snapshotId has to be passed in")
+    protected Long volumeId;
+
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
+            description="Optional, VM ID. If this presents, it is going to create a baremetal template for VM this ID refers to. This is only for VM whose hypervisor type is BareMetal")
+    protected Long vmId;
+
+    @Parameter(name = ApiConstants.URL,
+               type = CommandType.STRING,
+               length = 2048,
+               description = "Optional, only for baremetal hypervisor. The directory name where template stored on CIFS server")
+    private String url;
+
+    @Parameter(name = ApiConstants.TEMPLATE_TAG, type = CommandType.STRING, description = "the tag for this template.")
+    private String templateTag;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Template details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
+    protected Map details;
+
+    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
+               type = CommandType.BOOLEAN,
+               description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
+    protected Boolean isDynamicallyScalable;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "create template for the project")
+    private Long projectId;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Integer getBits() {
+        return bits;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Boolean isFeatured() {
+        return featured;
+    }
+
+    public Boolean isPublic() {
+        return publicTemplate;
+    }
+
+    public String getTemplateName() {
+        return templateName;
+    }
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    public Boolean isPasswordEnabled() {
+        return passwordEnabled;
+    }
+
+    public Boolean isSshKeyEnabled() {
+        return sshKeyEnabled;
+    }
+
+    public Boolean getRequiresHvm() {
+        return requiresHvm;
+    }
+
+    public Long getSnapshotId() {
+        return snapshotId;
+    }
+
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public String getTemplateTag() {
+        return templateTag;
+    }
+
+    public Map getDetails() {
+        if (details == null || details.isEmpty()) {
+            return null;
+        }
+
+        Collection paramsCollection = details.values();
+        Map params = (Map)(paramsCollection.toArray())[0];
+        return params;
+    }
+
+    public boolean isDynamicallyScalable() {
+        return isDynamicallyScalable == null ? false : isDynamicallyScalable;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "template";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long volumeId = getVolumeId();
+        Long snapshotId = getSnapshotId();
+        Account callingAccount = CallContext.current().getCallingAccount();
+        if (volumeId != null) {
+            Volume volume = _entityMgr.findById(Volume.class, volumeId);
+            if (volume != null) {
+                _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, volume);
+            } else {
+                throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
+            }
+        } else {
+            Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
+            if (snapshot != null) {
+                _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, snapshot);
+            } else {
+                throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
+            }
+        }
+
+        if(projectId != null){
+            final Project project = _projectService.getProject(projectId);
+            if (project != null) {
+                if (project.getState() == Project.State.Active) {
+                    Account projectAccount= _accountService.getAccount(project.getProjectAccountId());
+                    _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, projectAccount);
+                    return project.getProjectAccountId();
+                } else {
+                    final PermissionDeniedException ex =
+                            new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
+                                    " as it's no longer active");
+                    ex.addProxyObject(project.getUuid(), "projectId");
+                    throw ex;
+                }
+            } else {
+                throw new InvalidParameterValueException("Unable to find project by id");
+            }
+        }
+
+        return callingAccount.getId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_TEMPLATE_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "creating template: " + getTemplateName();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Template;
+    }
+
+    protected boolean isBareMetal() {
+        return (getVmId() != null && getUrl() != null);
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        VirtualMachineTemplate template = null;
+        //TemplateOwner should be the caller https://issues.citrite.net/browse/CS-17530
+        template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId()));
+        if (template != null) {
+            setEntityId(template.getId());
+            setEntityUuid(template.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a template");
+        }
+
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(
+            "Template Id: " + getEntityUuid() + ((getSnapshotId() == null) ? " from volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) : " from snapshot Id: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId())));
+        VirtualMachineTemplate template = null;
+        template = _templateService.createPrivateTemplate(this);
+
+        if (template != null) {
+            List<TemplateResponse> templateResponses;
+            if (isBareMetal()) {
+                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Restricted, template.getId(), vmId);
+            } else {
+                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Restricted, template.getId(), snapshotId, volumeId, false);
+            }
+            TemplateResponse response = new TemplateResponse();
+            if (templateResponses != null && !templateResponses.isEmpty()) {
+                response = templateResponses.get(0);
+            }
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private template");
+        }
+
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java
new file mode 100755
index 0000000..3cee148
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java
@@ -0,0 +1,127 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.template;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "deleteTemplate",
+            responseObject = SuccessResponse.class,
+            description = "Deletes a template from the system. All virtual machines using the deleted template will not be affected.",
+            requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DeleteTemplateCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DeleteTemplateCmd.class.getName());
+    private static final String s_name = "deletetemplateresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template")
+    private Long id;
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of zone of the template")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force delete a template.", since = "4.9+")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : true;
+    }
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getStaticName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
+        if (template != null) {
+            return template.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_TEMPLATE_DELETE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Deleting template " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Template;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Template Id: " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()));
+        boolean result = _templateService.deleteTemplate(this);
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete template");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
new file mode 100644
index 0000000..f0e7b08
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
@@ -0,0 +1,147 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.template;
+
+import com.cloud.dc.DataCenter;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "extractTemplate", description = "Extracts a template", responseObject = ExtractResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ExtractTemplateCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ExtractTemplateCmd.class.getName());
+
+    private static final String s_name = "extracttemplateresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template")
+    private Long id;
+
+    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, length = 2048, description = "the url to which the ISO would be extracted")
+    private String url;
+
+    @Parameter(name = ApiConstants.ZONE_ID,
+               type = CommandType.UUID,
+               entityType = ZoneResponse.class,
+               required = false,
+               description = "the ID of the zone where the ISO is originally located")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.MODE, type = CommandType.STRING, required = true, description = "the mode of extraction - HTTP_DOWNLOAD or FTP_UPLOAD")
+    private String mode;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getStaticName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
+        if (template != null) {
+            return template.getAccountId();
+        }
+
+        // invalid id, parent this command to SYSTEM so ERROR events are tracked
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_TEMPLATE_EXTRACT;
+    }
+
+    @Override
+    public String getEventDescription() {
+     return "extracting template: " + this._uuidMgr.getUuid(VirtualMachineTemplate.class, getId()) + ((getZoneId() != null) ? " from zone: " + this._uuidMgr.getUuid(DataCenter.class, getZoneId()) : "");
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Template;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() {
+        try {
+            CallContext.current().setEventDetails(getEventDescription());
+            String uploadUrl = _templateService.extract(this);
+            if (uploadUrl != null) {
+                ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract template");
+            }
+        } catch (InternalErrorException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatePermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatePermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/ListTemplatePermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatePermissionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/template/UpdateTemplatePermissionsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
new file mode 100644
index 0000000..ba465ad
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
@@ -0,0 +1,178 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "addIpToNic", description = "Assigns secondary IP to NIC", responseObject = NicSecondaryIpResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AddIpToVmNicCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
+    private static final String s_name = "addiptovmnicresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "the ID of the nic to which you want to assign private IP")
+    private Long nicId;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false, description = "Secondary IP Address")
+    private String ipAddr;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getEntityTable() {
+        return "nic_secondary_ips";
+    }
+
+    private long getNetworkId() {
+        Nic nic = _entityMgr.findById(Nic.class, nicId);
+        if (nic == null) {
+            throw new InvalidParameterValueException("Can't find network id for specified nic");
+        }
+        return nic.getNetworkId();
+    }
+
+    public long getNicId() {
+        return nicId;
+    }
+
+    private boolean isZoneSGEnabled() {
+        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
+        return dc.isSecurityGroupEnabled();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "associating ip to nic id=" + this._uuidMgr.getUuid(Nic.class, getNicId()) + " belonging to network id=" + this._uuidMgr.getUuid(Network.class, getNetworkId());
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "addressinfo";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
+
+        CallContext.current().setEventDetails("Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId()));
+        NicSecondaryIp result = _entityMgr.findById(NicSecondaryIp.class, getEntityId());
+
+        if (result != null) {
+            CallContext.current().setEventDetails("secondary Ip Id: " + getEntityUuid());
+            boolean success = false;
+            success = _networkService.configureNicSecondaryIp(result, isZoneSGEnabled());
+
+            if (success == false) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
+            }
+
+            NicSecondaryIpResponse response = _responseGenerator.createSecondaryIPToNicResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
+        }
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getNetworkId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.IpAddress;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Nic nic = _entityMgr.findById(Nic.class, nicId);
+        if (nic == null) {
+            throw new InvalidParameterValueException("Can't find nic for id specified");
+        }
+        long vmId = nic.getInstanceId();
+        VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, vmId);
+
+        return vm.getAccountId();
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        NicSecondaryIp result;
+
+        IpAddresses requestedIpPair = new IpAddresses(ipAddr, null);
+        if (!NetUtils.isIpv4(ipAddr)) {
+            requestedIpPair = new IpAddresses(null, ipAddr);
+        }
+
+        try {
+            result = _networkService.allocateSecondaryGuestIP(getNicId(), requestedIpPair);
+            if (result != null) {
+                setEntityId(result.getId());
+                setEntityUuid(result.getUuid());
+            }
+        } catch (InsufficientAddressCapacityException e) {
+            throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage());
+        }
+
+        if (result == null) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java
new file mode 100644
index 0000000..a5a3f6e
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.cloud.network.Network;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class AddNicToVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(AddNicToVMCmd.class);
+    private static final String s_name = "addnictovirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="Virtual Machine ID")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "Network ID")
+    private Long netId;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "IP Address for the new network")
+    private String ipaddr;
+
+    @Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "Mac Address for the new network")
+    private String macaddr;
+
+    @Parameter(name = ApiConstants.DHCP_OPTIONS, type = CommandType.MAP, description = "DHCP options which are passed to the nic"
+            + " Example: dhcpoptions[0].dhcp:114=url&dhcpoptions[0].dhcp:66=www.test.com")
+    private Map dhcpOptions;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    public Long getNetworkId() {
+        return netId;
+    }
+
+    public String getIpAddress() {
+        return ipaddr;
+    }
+
+    public String getMacAddress() {
+        if (macaddr == null) {
+            return null;
+        }
+        if(!NetUtils.isValidMac(macaddr)) {
+            throw new InvalidParameterValueException("Mac address is not valid: " + macaddr);
+        } else if(!NetUtils.isUnicastMac(macaddr)) {
+            throw new InvalidParameterValueException("Mac address is not unicast: " + macaddr);
+        }
+        return NetUtils.standardizeMacAddress(macaddr);
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NIC_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "Adding network " + this._uuidMgr.getUuid(Network.class, getNetworkId()) + " to user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId());
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getVmId());
+        if (vm == null) {
+             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return vm.getAccountId();
+    }
+
+    public Map<Integer, String> getDhcpOptionsMap() {
+        Map<Integer, String> dhcpOptionsMap = new HashMap<>();
+        if (dhcpOptions != null && !dhcpOptions.isEmpty()) {
+
+            Collection<Map<String, String>> paramsCollection = this.dhcpOptions.values();
+            for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
+                for (String key : dhcpNetworkOptions.keySet()) {
+                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
+                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
+                        dhcpOptionsMap.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
+                    } else {
+                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
+                        dhcpOptionsMap.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
+                    }
+                }
+
+            }
+        }
+
+        return dhcpOptionsMap;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Network Id: " + this._uuidMgr.getUuid(Network.class, getNetworkId()));
+        UserVm result = _userVmService.addNicToVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NIC to vm. Refer to server logs for details.");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
new file mode 100644
index 0000000..0874b4e
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -0,0 +1,605 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.commons.collections.MapUtils;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.offering.DiskOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityGroupAction {
+    public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName());
+
+    private static final String s_name = "deployvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "availability zone for the virtual machine")
+    private Long zoneId;
+
+    @ACL
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the ID of the service offering for the virtual machine")
+    private Long serviceOfferingId;
+
+    @ACL
+    @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template for the virtual machine")
+    private Long templateId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "host name for the virtual machine")
+    private String name;
+
+    @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "an optional user generated name for the virtual machine")
+    private String displayName;
+
+    //Owner information
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    //Network information
+    //@ACL(accessType = AccessType.UseEntry)
+    @Parameter(name = ApiConstants.NETWORK_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = NetworkResponse.class, description = "list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
+    private List<Long> networkIds;
+
+    //DataDisk information
+    @ACL
+    @Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering for the virtual machine. If the template is of ISO format,"
+            + " the diskOfferingId is for the root disk volume. Otherwise this parameter is used to indicate the "
+            + "offering for the data disk volume. If the templateId parameter passed is from a Template object,"
+            + " the diskOfferingId refers to a DATA Disk Volume created. If the templateId parameter passed is "
+            + "from an ISO object, the diskOfferingId refers to a ROOT Disk Volume created.")
+    private Long diskOfferingId;
+
+    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId")
+    private Long size;
+
+    @Parameter(name = ApiConstants.ROOT_DISK_SIZE,
+            type = CommandType.LONG,
+            description = "Optional field to resize root disk on deploy. Value is in GB. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided",
+            since = "4.4")
+    private Long rootdisksize;
+
+    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
+    private String group;
+
+    @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "the hypervisor on which to deploy the virtual machine. "
+            + "The parameter is required and respected only when hypervisor info is not set on the ISO/Template passed to the call")
+    private String hypervisor;
+
+    @Parameter(name = ApiConstants.USER_DATA, type = CommandType.STRING, description = "an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.", length = 32768)
+    private String userData;
+
+    @Parameter(name = ApiConstants.SSH_KEYPAIR, type = CommandType.STRING, description = "name of the ssh key pair used to login to the virtual machine")
+    private String sshKeyPairName;
+
+    @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "destination Host ID to deploy the VM to - parameter available for root admin only")
+    private Long hostId;
+
+    @ACL
+    @Parameter(name = ApiConstants.SECURITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = SecurityGroupResponse.class, description = "comma separated list of security groups id that going to be applied to the virtual machine. "
+            + "Should be passed only when vm is created from a zone with Basic Network support." + " Mutually exclusive with securitygroupnames parameter")
+    private List<Long> securityGroupIdList;
+
+    @ACL
+    @Parameter(name = ApiConstants.SECURITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = SecurityGroupResponse.class, description = "comma separated list of security groups names that going to be applied to the virtual machine."
+            + " Should be passed only when vm is created from a zone with Basic Network support. " + "Mutually exclusive with securitygroupids parameter")
+    private List<String> securityGroupNameList;
+
+    @Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP, description = "ip to network mapping. Can't be specified with networkIds parameter."
+            + " Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid&iptonetworklist[0].mac=aa:bb:cc:dd:ee::ff - requests to use ip 10.10.10.11 in network id=uuid")
+    private Map ipToNetworkList;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "the ip address for default vm's network")
+    private String ipAddress;
+
+    @Parameter(name = ApiConstants.IP6_ADDRESS, type = CommandType.STRING, description = "the ipv6 address for default vm's network")
+    private String ip6Address;
+
+    @Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "the mac address for default vm's network")
+    private String macAddress;
+
+    @Parameter(name = ApiConstants.KEYBOARD, type = CommandType.STRING, description = "an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us")
+    private String keyboard;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Deploy vm for the project")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.START_VM, type = CommandType.BOOLEAN, description = "true if start vm after creating; defaulted to true if not specified")
+    private Boolean startVm;
+
+    @ACL
+    @Parameter(name = ApiConstants.AFFINITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups id that are going to be applied to the virtual machine."
+            + " Mutually exclusive with affinitygroupnames parameter")
+    private List<Long> affinityGroupIdList;
+
+    @ACL
+    @Parameter(name = ApiConstants.AFFINITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups names that are going to be applied to the virtual machine."
+            + "Mutually exclusive with affinitygroupids parameter")
+    private List<String> affinityGroupNameList;
+
+    @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, since = "4.2", description = "an optional field, whether to the display the vm to the end user or not.", authorized = {RoleType.Admin})
+    private Boolean displayVm;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.3", description = "used to specify the custom parameters.")
+    private Map details;
+
+    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
+    private String deploymentPlanner;
+
+    @Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
+            + " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
+    private Map dhcpOptionsNetworkList;
+
+    @Parameter(name = ApiConstants.DATADISK_OFFERING_LIST, type = CommandType.MAP, since = "4.11", description = "datadisk template to disk-offering mapping;" +
+            " an optional parameter used to create additional data disks from datadisk templates; can't be specified with diskOfferingId parameter")
+    private Map dataDiskTemplateToDiskOfferingList;
+
+    @Parameter(name = ApiConstants.EXTRA_CONFIG, type = CommandType.STRING, since = "4.12", description = "an optional URL encoded string that can be passed to the virtual machine upon successful deployment", length = 5120)
+    private String extraConfig;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getAccountName() {
+        if (accountName == null) {
+            return CallContext.current().getCallingAccount().getAccountName();
+        }
+        return accountName;
+    }
+
+    public Long getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public Long getDomainId() {
+        if (domainId == null) {
+            return CallContext.current().getCallingAccount().getDomainId();
+        }
+        return domainId;
+    }
+
+    public Map<String, String> getDetails() {
+        Map<String, String> customparameterMap = new HashMap<String, String>();
+        if (details != null && details.size() != 0) {
+            Collection parameterCollection = details.values();
+            Iterator iter = parameterCollection.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> value = (HashMap<String, String>)iter.next();
+                for (Map.Entry<String,String> entry: value.entrySet()) {
+                    customparameterMap.put(entry.getKey(),entry.getValue());
+                }
+            }
+        }
+        if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) {
+            customparameterMap.put("rootdisksize", rootdisksize.toString());
+        }
+        return customparameterMap;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public HypervisorType getHypervisor() {
+        return HypervisorType.getType(hypervisor);
+    }
+
+    public Boolean isDisplayVm() {
+        return displayVm;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        if(displayVm == null)
+            return true;
+        else
+            return displayVm;
+    }
+
+    public List<String> getSecurityGroupNameList() {
+        return securityGroupNameList;
+    }
+
+    public List<Long> getSecurityGroupIdList() {
+        return securityGroupIdList;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    public String getUserData() {
+        return userData;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public List<Long> getNetworkIds() {
+       if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
+           if ((networkIds != null && !networkIds.isEmpty()) || ipAddress != null || getIp6Address() != null) {
+               throw new InvalidParameterValueException("ipToNetworkMap can't be specified along with networkIds or ipAddress");
+           } else {
+               List<Long> networks = new ArrayList<Long>();
+               networks.addAll(getIpToNetworkMap().keySet());
+               return networks;
+           }
+       }
+        return networkIds;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getSSHKeyPairName() {
+        return sshKeyPairName;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public boolean getStartVm() {
+        return startVm == null ? true : startVm;
+    }
+
+    public Map<Long, IpAddresses> getIpToNetworkMap() {
+        if ((networkIds != null || ipAddress != null || getIp6Address() != null) && ipToNetworkList != null) {
+            throw new InvalidParameterValueException("NetworkIds and ipAddress can't be specified along with ipToNetworkMap parameter");
+        }
+        LinkedHashMap<Long, IpAddresses> ipToNetworkMap = null;
+        if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
+            ipToNetworkMap = new LinkedHashMap<Long, IpAddresses>();
+            Collection ipsCollection = ipToNetworkList.values();
+            Iterator iter = ipsCollection.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> ips = (HashMap<String, String>)iter.next();
+                Long networkId;
+                Network network = _networkService.getNetwork(ips.get("networkid"));
+                if (network != null) {
+                    networkId = network.getId();
+                } else {
+                    try {
+                        networkId = Long.parseLong(ips.get("networkid"));
+                    } catch (NumberFormatException e) {
+                        throw new InvalidParameterValueException("Unable to translate and find entity with networkId: " + ips.get("networkid"));
+                    }
+                }
+                String requestedIp = ips.get("ip");
+                String requestedIpv6 = ips.get("ipv6");
+                String requestedMac = ips.get("mac");
+                if (requestedIpv6 != null) {
+                    requestedIpv6 = NetUtils.standardizeIp6Address(requestedIpv6);
+                }
+                if (requestedMac != null) {
+                    if(!NetUtils.isValidMac(requestedMac)) {
+                        throw new InvalidParameterValueException("Mac address is not valid: " + requestedMac);
+                    } else if(!NetUtils.isUnicastMac(requestedMac)) {
+                        throw new InvalidParameterValueException("Mac address is not unicast: " + requestedMac);
+                    }
+                    requestedMac = NetUtils.standardizeMacAddress(requestedMac);
+                }
+                IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6, requestedMac);
+                ipToNetworkMap.put(networkId, addrs);
+            }
+        }
+
+        return ipToNetworkMap;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public String getIp6Address() {
+        if (ip6Address == null) {
+            return null;
+        }
+        return NetUtils.standardizeIp6Address(ip6Address);
+    }
+
+
+    public String getMacAddress() {
+        if (macAddress == null) {
+            return null;
+        }
+        if(!NetUtils.isValidMac(macAddress)) {
+            throw new InvalidParameterValueException("Mac address is not valid: " + macAddress);
+        } else if(!NetUtils.isUnicastMac(macAddress)) {
+            throw new InvalidParameterValueException("Mac address is not unicast: " + macAddress);
+        }
+        return NetUtils.standardizeMacAddress(macAddress);
+    }
+
+    public List<Long> getAffinityGroupIdList() {
+        if (affinityGroupNameList != null && affinityGroupIdList != null) {
+            throw new InvalidParameterValueException("affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
+        }
+
+        // transform group names to ids here
+        if (affinityGroupNameList != null) {
+            List<Long> affinityGroupIds = new ArrayList<Long>();
+            for (String groupName : affinityGroupNameList) {
+                Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
+                if (groupId == null) {
+                    throw new InvalidParameterValueException("Unable to find affinity group by name " + groupName);
+                } else {
+                    affinityGroupIds.add(groupId);
+                }
+            }
+            return affinityGroupIds;
+        } else {
+            return affinityGroupIdList;
+        }
+    }
+
+    public String getKeyboard() {
+        // TODO Auto-generated method stub
+        return keyboard;
+    }
+
+    public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
+        Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
+        if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
+
+            Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
+            for (Map<String, String> dhcpNetworkOptions : paramsCollection) {
+                String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
+
+                if (networkId == null) {
+                    throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
+                }
+
+                Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
+                dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
+
+                for (String key : dhcpNetworkOptions.keySet()) {
+                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
+                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
+                        dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
+                    } else if (!key.equals(ApiConstants.NETWORK_ID)) {
+                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
+                        dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
+                    }
+                }
+
+            }
+        }
+
+        return dhcpOptionsMap;
+    }
+
+    public Map<Long, DiskOffering> getDataDiskTemplateToDiskOfferingMap() {
+        if (diskOfferingId != null && dataDiskTemplateToDiskOfferingList != null) {
+            throw new InvalidParameterValueException("diskofferingid paramter can't be specified along with datadisktemplatetodiskofferinglist parameter");
+        }
+        if (MapUtils.isEmpty(dataDiskTemplateToDiskOfferingList)) {
+            return new HashMap<Long, DiskOffering>();
+        }
+
+        HashMap<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = new HashMap<Long, DiskOffering>();
+        for (Object objDataDiskTemplates : dataDiskTemplateToDiskOfferingList.values()) {
+            HashMap<String, String> dataDiskTemplates = (HashMap<String, String>) objDataDiskTemplates;
+            Long dataDiskTemplateId;
+            DiskOffering dataDiskOffering = null;
+            VirtualMachineTemplate dataDiskTemplate= _entityMgr.findByUuid(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid"));
+            if (dataDiskTemplate == null) {
+                dataDiskTemplate = _entityMgr.findById(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid"));
+                if (dataDiskTemplate == null)
+                    throw new InvalidParameterValueException("Unable to translate and find entity with datadisktemplateid " + dataDiskTemplates.get("datadisktemplateid"));
+            }
+            dataDiskTemplateId = dataDiskTemplate.getId();
+            dataDiskOffering = _entityMgr.findByUuid(DiskOffering.class, dataDiskTemplates.get("diskofferingid"));
+            if (dataDiskOffering == null) {
+                dataDiskOffering = _entityMgr.findById(DiskOffering.class, dataDiskTemplates.get("diskofferingid"));
+                if (dataDiskOffering == null)
+                    throw new InvalidParameterValueException("Unable to translate and find entity with diskofferingId " + dataDiskTemplates.get("diskofferingid"));
+            }
+            dataDiskTemplateToDiskOfferingMap.put(dataDiskTemplateId, dataDiskOffering);
+        }
+        return dataDiskTemplateToDiskOfferingMap;
+    }
+
+    public String getExtraConfig() {
+        return extraConfig;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getCreateEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getCreateEventDescription() {
+        return "creating Vm";
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "starting Vm. Vm Id: " + getEntityUuid();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public void execute() {
+        UserVm result;
+
+        if (getStartVm()) {
+            try {
+                CallContext.current().setEventDetails("Vm Id: " + getEntityUuid());
+                result = _userVmService.startVirtualMachine(this);
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+            } catch (ConcurrentOperationException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+            } catch (InsufficientCapacityException ex) {
+                StringBuilder message = new StringBuilder(ex.getMessage());
+                if (ex instanceof InsufficientServerCapacityException) {
+                    if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
+                        message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
+                    }
+                }
+                s_logger.info(ex);
+                s_logger.info(message.toString(), ex);
+                throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
+            }
+        } else {
+            result = _userVmService.getUserVm(getEntityId());
+        }
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm uuid:"+getEntityUuid());
+        }
+    }
+
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        try {
+            UserVm vm = _userVmService.createVirtualMachine(this);
+
+            if (vm != null) {
+                setEntityId(vm.getId());
+                setEntityUuid(vm.getUuid());
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm");
+            }
+        } catch (InsufficientCapacityException ex) {
+            s_logger.info(ex);
+            s_logger.trace(ex.getMessage(), ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        }  catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (ResourceAllocationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
new file mode 100644
index 0000000..7b359b7
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+            requestHasSensitiveInfo = false,
+            responseHasSensitiveInfo = true)
+public class DestroyVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DestroyVMCmd.class.getName());
+
+    private static final String s_name = "destroyvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.EXPUNGE,
+               type = CommandType.BOOLEAN,
+               description = "If true is passed, the vm is expunged immediately. False by default.",
+               since = "4.2.1")
+    private Boolean expunge;
+
+    @Parameter( name = ApiConstants.VOLUME_IDS,
+                type = CommandType.LIST,
+                collectionType = CommandType.UUID,
+                entityType = VolumeResponse.class,
+                description = "Comma separated list of UUIDs for volumes that will be deleted",
+                since = "4.12.0")
+    private List<Long> volumeIds;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public boolean getExpunge() {
+        if (expunge == null) {
+            return false;
+        }
+        return expunge;
+    }
+
+    public List<Long> getVolumeIds() {
+        return volumeIds;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_DESTROY;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "destroying vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result = _userVmService.destroyVm(this);
+
+        UserVmResponse response = new UserVmResponse();
+        if (result != null) {
+            List<UserVmResponse> responses = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result);
+            if (responses != null && !responses.isEmpty()) {
+                response = responses.get(0);
+            }
+            response.setResponseName("virtualmachine");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy vm");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListNicsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
new file mode 100644
index 0000000..b524257
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RebootVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RebootVMCmd.class.getName());
+    private static final String s_name = "rebootvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_REBOOT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "rebooting user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result;
+        result = _userVmService.rebootVirtualMachine(this);
+        if (result !=null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot vm instance");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
new file mode 100644
index 0000000..db84dc9
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
@@ -0,0 +1,187 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.user.Account;
+import com.cloud.vm.NicSecondaryIp;
+
+
+@APICommand(name = "removeIpFromNic", description = "Removes secondary IP from the NIC.", responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName());
+    private static final String s_name = "removeipfromnicresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.ID,
+            type = CommandType.UUID,
+            required = true,
+            entityType = NicSecondaryIpResponse.class,
+            description = "the ID of the secondary ip address to nic")
+    private Long id;
+
+    // unexposed parameter needed for events logging
+    @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, expose = false)
+    private Long ownerId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getEntityTable() {
+        return "nic_secondary_ips";
+    }
+
+    public Long getIpAddressId() {
+        return id;
+    }
+
+    public String getAccountName() {
+        return CallContext.current().getCallingAccount().getAccountName();
+    }
+
+    public long getDomainId() {
+        return CallContext.current().getCallingAccount().getDomainId();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account caller = CallContext.current().getCallingAccount();
+        return caller.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN;
+    }
+
+    public NicSecondaryIp getIpEntry() {
+        NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
+        return nicSecIp;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  ("Disassociating ip address with id=" + id);
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "addressinfo";
+    }
+
+    public Long getNetworkId() {
+        NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
+        if (nicSecIp != null) {
+            Long networkId = nicSecIp.getNetworkId();
+            return networkId;
+        } else {
+            return null;
+        }
+    }
+
+    public NetworkType getNetworkType() {
+        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+        if (ntwk != null) {
+            DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
+            return dc.getNetworkType();
+        }
+        return null;
+    }
+
+
+    private boolean isZoneSGEnabled() {
+        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
+        return dc.isSecurityGroupEnabled();
+    }
+
+    @Override
+    public void execute() throws InvalidParameterValueException {
+        CallContext.current().setEventDetails("Ip Id: " + id);
+        NicSecondaryIp nicSecIp = getIpEntry();
+
+        if (nicSecIp == null) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed");
+        }
+
+        String secIp = nicSecIp.getIp4Address();
+        if (secIp == null) {
+            secIp = nicSecIp.getIp6Address();
+        }
+
+        if (isZoneSGEnabled()) {
+            //remove the security group rules for this secondary ip
+            boolean success = false;
+            success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), secIp, false);
+            if (success == false) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
+            }
+        }
+
+        try {
+            boolean result = _networkService.releaseSecondaryIpFromNic(id);
+            if (result) {
+                SuccessResponse response = new SuccessResponse(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary  ip address for the nic");
+            }
+        } catch (InvalidParameterValueException e) {
+            throw new InvalidParameterValueException("Removing guest ip from nic failed");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.IpAddress;
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java
new file mode 100644
index 0000000..677b482
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java
@@ -0,0 +1,120 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import com.cloud.vm.Nic;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RemoveNicFromVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmd.class);
+    private static final String s_name = "removenicfromvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="Virtual Machine ID")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "NIC ID")
+    private Long nicId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    public Long getNicId() {
+        return nicId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NIC_DELETE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "Removing NIC " + this._uuidMgr.getUuid(Nic.class, getNicId()) + " from user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId());
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getVmId());
+        if (vm == null) {
+             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return vm.getAccountId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId()));
+        UserVm result = _userVmService.removeNicFromVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NIC from vm, see error log for details");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/ResetVMSSHKeyCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
new file mode 100644
index 0000000..b2b4d03
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+            requestHasSensitiveInfo = false,
+            responseHasSensitiveInfo = true)
+public class RestoreVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RestoreVMCmd.class);
+    private static final String s_name = "restorevmresponse";
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="Virtual Machine ID")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.TEMPLATE_ID,
+               type = CommandType.UUID,
+               entityType = TemplateResponse.class,
+               description = "an optional template Id to restore vm from the new template. This can be an ISO id in case of restore vm deployed using ISO")
+    private Long templateId;
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_RESTORE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Restore a VM to orignal template or specific snapshot";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException {
+        UserVm result;
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()));
+        result = _userVmService.restoreVM(this);
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restore vm " + getVmId());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getVmId());
+        if (vm == null) {
+             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return vm.getAccountId();
+    }
+
+    public long getVmId() {
+        return vmId;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    // TODO - Remove vmid param and make it "id" in 5.0 so that we dont have two getters
+    public Long getId() {
+        return getVmId();
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java
new file mode 100644
index 0000000..631cef2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java
@@ -0,0 +1,163 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.offering.ServiceOffering;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+
+@APICommand(name = "scaleVirtualMachine", description = "Scales the virtual machine to a new service offering.", responseObject = SuccessResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ScaleVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
+    private static final String s_name = "scalevirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
+            required=true, description="the ID of the service offering for the virtual machine")
+    private Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.DETAILS, type = BaseCmd.CommandType.MAP, description = "name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value")
+    private Map<String, String> details;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    //instead of reading a map directly we are using collections.
+    //it is because details.values() cannot be cast to a map.
+    //it gives a exception
+    public Map<String, String> getDetails() {
+        Map<String, String> customparameterMap = new HashMap<String, String>();
+        if (details != null && details.size() != 0) {
+            Collection parameterCollection = details.values();
+            Iterator iter = parameterCollection.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> value = (HashMap<String, String>)iter.next();
+                for (String key : value.keySet()) {
+                    customparameterMap.put(key, value.get(key));
+                }
+            }
+        }
+        return customparameterMap;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_UPGRADE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "upgrading vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()) + " to service offering: " + this._uuidMgr.getUuid(ServiceOffering.class, getServiceOfferingId());
+    }
+
+    @Override
+    public void execute() {
+        UserVm result;
+        try {
+            result = _userVmService.upgradeVirtualMachine(this);
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (ManagementServerException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (VirtualMachineMigrationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+        if (result != null){
+            List<UserVmResponse> responseList = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result);
+            UserVmResponse response = responseList.get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/SecurityGroupAction.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/SecurityGroupAction.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vm/SecurityGroupAction.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vm/SecurityGroupAction.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
new file mode 100644
index 0000000..b87c7de
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
@@ -0,0 +1,170 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class StartVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StartVMCmd.class.getName());
+
+    private static final String s_name = "startvirtualmachineresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
+            required = true, description = "The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.HOST_ID,
+               type = CommandType.UUID,
+               entityType = HostResponse.class,
+               description = "destination Host ID to deploy the VM to - parameter available for root admin only",
+               since = "3.0.1")
+    private Long hostId;
+
+    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
+    private String deploymentPlanner;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
+        // tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_START;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "starting user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException {
+        try {
+            CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+            UserVm result;
+            result = _userVmService.startVirtualMachine(this);
+
+            if (result != null) {
+                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start a vm");
+            }
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (StorageUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ExecutionException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (InsufficientCapacityException ex) {
+            StringBuilder message = new StringBuilder(ex.getMessage());
+            if (ex instanceof InsufficientServerCapacityException) {
+                if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
+                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
+                }
+            }
+            s_logger.info(ex);
+            s_logger.info(message.toString(), ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
+        }
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
new file mode 100644
index 0000000..bab8552
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class StopVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StopVMCmd.class.getName());
+
+    private static final String s_name = "stopvirtualmachineresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
+            required = true, description = "The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM "
+        + "(vm is marked as Stopped even when command fails to be send to the backend, otherwise a force poweroff is attempted).  The caller knows the VM is stopped.")
+    private Boolean forced;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
+// tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_STOP;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "stopping user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result;
+
+        result = _userVmService.stopVirtualMachine(getId(), isForced());
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop vm");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java
new file mode 100644
index 0000000..7262e23
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import com.cloud.vm.Nic;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpdateDefaultNicForVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmd.class);
+    private static final String s_name = "updatedefaultnicforvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="Virtual Machine ID")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "NIC ID")
+    private Long nicId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    public Long getNicId() {
+        return nicId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NIC_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "Updating NIC " + this._uuidMgr.getUuid(Nic.class, getNicId()) + " on user vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId());
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getVmId());
+        if (vm == null) {
+             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return vm.getAccountId();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()) + " Nic Id: " + this._uuidMgr.getUuid(Nic.class, getNicId()));
+        UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set default nic for VM. Refer to server logs for details.");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
new file mode 100644
index 0000000..b040f79
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -0,0 +1,277 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
+        "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
+        "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+    requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction {
+    public static final Logger s_logger = Logger.getLogger(UpdateVMCmd.class.getName());
+    private static final String s_name = "updatevirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "user generated name")
+    private String displayName;
+
+    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "group of the virtual machine")
+    private String group;
+
+    @Parameter(name = ApiConstants.HA_ENABLE, type = CommandType.BOOLEAN, description = "true if high-availability is enabled for the virtual machine, false otherwise")
+    private Boolean haEnable;
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID,
+               type = CommandType.UUID,
+               entityType = GuestOSResponse.class,
+               description = "the ID of the OS type that best represents this VM.")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.USER_DATA,
+               type = CommandType.STRING,
+               description = "an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.",
+               length = 32768)
+    private String userData;
+
+    @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vm to the end user or not.", authorized = {RoleType.Admin})
+    private Boolean displayVm;
+
+    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
+               type = CommandType.BOOLEAN,
+               description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
+    protected Boolean isDynamicallyScalable;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "new host name of the vm. The VM has to be stopped/started for this update to take affect", since = "4.4")
+    private String name;
+
+    @Parameter(name = ApiConstants.INSTANCE_NAME, type = CommandType.STRING, description = "instance name of the user vm", since = "4.4", authorized = {RoleType.Admin})
+    private String instanceName;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs.")
+    protected Map<String, String> details;
+
+    @ACL
+    @Parameter(name = ApiConstants.SECURITY_GROUP_IDS,
+               type = CommandType.LIST,
+               collectionType = CommandType.UUID,
+               entityType = SecurityGroupResponse.class,
+               description = "list of security group ids to be applied on the virtual machine.")
+    private List<Long> securityGroupIdList;
+
+    @ACL
+    @Parameter(name = ApiConstants.SECURITY_GROUP_NAMES,
+               type = CommandType.LIST,
+               collectionType = CommandType.STRING,
+               entityType = SecurityGroupResponse.class,
+               description = "comma separated list of security groups names that going to be applied to the virtual machine. " +
+                       "Should be passed only when vm is created from a zone with Basic Network support. " +
+                       "Mutually exclusive with securitygroupids parameter"
+            )
+    private List<String> securityGroupNameList;
+
+    @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
+            type = CommandType.BOOLEAN,
+            description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
+    private Boolean cleanupDetails;
+
+    @Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
+            + " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
+    private Map dhcpOptionsNetworkList;
+
+    @Parameter(name = ApiConstants.EXTRA_CONFIG, type = CommandType.STRING, since = "4.12", description = "an optional URL encoded string that can be passed to the virtual machine upon successful deployment", authorized = { RoleType.Admin }, length = 5120)
+    private String extraConfig;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public Boolean getHaEnable() {
+        return haEnable;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getUserData() {
+        return userData;
+    }
+
+    public Boolean getDisplayVm() {
+        return displayVm;
+    }
+
+    public Boolean isDynamicallyScalable() {
+        return isDynamicallyScalable;
+    }
+
+    public String getHostName() {
+        return name;
+    }
+
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    public Map<String, String> getDetails() {
+        if (this.details == null || this.details.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = this.details.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];
+    }
+
+    public List<Long> getSecurityGroupIdList() {
+        return securityGroupIdList;
+    }
+
+    public List<String> getSecurityGroupNameList() {
+        return securityGroupNameList;
+    }
+
+    public boolean isCleanupDetails(){
+        return cleanupDetails == null ? false : cleanupDetails.booleanValue();
+    }
+
+    public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
+        Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
+        if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
+
+            Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
+            for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
+                String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
+
+                if(networkId == null) {
+                    throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
+                }
+
+                Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
+                dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
+
+                for (String key : dhcpNetworkOptions.keySet()) {
+                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
+                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
+                        dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
+                    } else if (!key.equals(ApiConstants.NETWORK_ID)) {
+                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
+                        dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
+                    }
+                }
+
+            }
+        }
+
+        return dhcpOptionsMap;
+    }
+
+    public String getExtraConfig() {
+        return extraConfig;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+        UserVm result = _userVmService.updateVirtualMachine(this);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm");
+        }
+    }
+
+    @Override
+    public void checkUuid() {
+        if (getCustomId() != null) {
+            _uuidMgr.checkUuid(getCustomId(), UserVm.class);
+
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java
new file mode 100644
index 0000000..9d184f9
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java
@@ -0,0 +1,186 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+
+@APICommand(name = "updateVmNicIp", description = "Update the default Ip of a VM Nic", responseObject = UserVmResponse.class)
+public class UpdateVmNicIpCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
+    private static final String s_name = "updatevmnicipresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = true,
+            description="the ID of the nic to which you want to assign private IP")
+            private Long nicId;
+
+    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false,
+            description = "Secondary IP Address")
+            private String ipAddr;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getEntityTable() {
+        return "nic_secondary_ips";
+    }
+
+    public String getAccountName() {
+        return CallContext.current().getCallingAccount().getAccountName();
+    }
+
+    public long getDomainId() {
+        return CallContext.current().getCallingAccount().getDomainId();
+    }
+
+    private long getZoneId() {
+        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+        if (ntwk == null) {
+            throw new InvalidParameterValueException("Can't find zone id for specified");
+        }
+        return ntwk.getDataCenterId();
+    }
+
+    public Long getNetworkId() {
+        Nic nic = _entityMgr.findById(Nic.class, nicId);
+        if (nic == null) {
+            throw new InvalidParameterValueException("Can't find network id for specified nic");
+        }
+        Long networkId = nic.getNetworkId();
+        return networkId;
+    }
+
+    public Long getNicId() {
+        return nicId;
+    }
+
+    public String getIpaddress () {
+        if (ipAddr != null) {
+            return ipAddr;
+        } else {
+            return null;
+        }
+    }
+
+    public NetworkType getNetworkType() {
+        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
+        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
+        return dc.getNetworkType();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NET_IP_ASSIGN;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "associating ip to nic id: " + this._uuidMgr.getUuid(Network.class, getNetworkId()) + " in zone " + this._uuidMgr.getUuid(DataCenter.class, getZoneId());
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "addressinfo";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException,
+    ConcurrentOperationException, InsufficientCapacityException {
+
+        CallContext.current().setEventDetails("Nic Id: " + getNicId() );
+        String ip;
+        if ((ip = getIpaddress()) != null) {
+            if (!NetUtils.isValidIp4(ip)) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
+            }
+        }
+
+        UserVm vm = _userVmService.updateNicIpForVirtualMachine(this);
+        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+        dc.add(VMDetails.valueOf("nics"));
+        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
+        if (vm != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, vm).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update ip address on vm NIC. Refer to server logs for details.");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getNetworkId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.IpAddress;
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
new file mode 100644
index 0000000..216833b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
@@ -0,0 +1,139 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " +
+                                            "The virtual machine must be in a \"Stopped\" state for " +
+        "this command to take effect.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class UpgradeVMCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
+    private static final String s_name = "changeserviceforvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
+            required=true, description="the service offering ID to apply to the virtual machine")
+    protected Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
+    private Map<String, String> details;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Map<String, String> getDetails() {
+        Map<String, String> customparameterMap = new HashMap<String, String>();
+        if (details != null && details.size() != 0) {
+            Collection parameterCollection = details.values();
+            Iterator iter = parameterCollection.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> value = (HashMap<String, String>)iter.next();
+                for (String key : value.keySet()) {
+                    customparameterMap.put(key, value.get(key));
+                }
+            }
+        }
+        return customparameterMap;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() throws ResourceAllocationException {
+        CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        UserVm result = _userVmService.upgradeVirtualMachine(this);
+
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade vm");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vmgroup/UpdateVMGroupCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
new file mode 100644
index 0000000..e89f6cc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
@@ -0,0 +1,135 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.api.command.user.vmsnapshot;
+
+import java.util.logging.Logger;
+
+import com.cloud.vm.VirtualMachine;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.snapshot.VMSnapshot;
+
+@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
+
+    public static final Logger s_logger = Logger.getLogger(CreateVMSnapshotCmd.class.getName());
+    private static final String s_name = "createvmsnapshotresponse";
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, required = true, entityType = UserVmResponse.class, description = "The ID of the vm")
+    private Long vmId;
+
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_DESCRIPTION, type = CommandType.STRING, required = false, description = "The description of the snapshot")
+    private String description;
+
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_DISPLAYNAME, type = CommandType.STRING, required = false, description = "The display name of the snapshot")
+    private String displayName;
+
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_MEMORY, type = CommandType.BOOLEAN, required = false, description = "snapshot memory if true")
+    private Boolean snapshotMemory;
+
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_QUIESCEVM, type = CommandType.BOOLEAN, required = false, description = "quiesce vm if true")
+    private Boolean quiescevm;
+
+    public Boolean snapshotMemory() {
+        if (snapshotMemory == null) {
+            return false;
+        } else {
+            return snapshotMemory;
+        }
+    }
+
+    public Boolean getQuiescevm() {
+        if (quiescevm == null) {
+            return false;
+        } else {
+            return quiescevm;
+        }
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+        VMSnapshot vmsnapshot = _vmSnapshotService.allocVMSnapshot(getVmId(), getDisplayName(), getDescription(), snapshotMemory());
+        if (vmsnapshot != null) {
+            setEntityId(vmsnapshot.getId());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create vm snapshot");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "creating snapshot for VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId());
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_SNAPSHOT_CREATE;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("VM Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getVmId()));
+        VMSnapshot result = _vmSnapshotService.createVMSnapshot(getVmId(), getEntityId(), getQuiescevm());
+        if (result != null) {
+            VMSnapshotResponse response = _responseGenerator.createVMSnapshotResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create vm snapshot due to an internal error creating snapshot for vm " + getVmId());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVM = _userVmService.getUserVm(vmId);
+        return userVM.getAccountId();
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
new file mode 100644
index 0000000..03c9d43
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.api.command.user.vmsnapshot;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+import com.cloud.vm.snapshot.VMSnapshot;
+
+@APICommand(name = "deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DeleteVMSnapshotCmd.class.getName());
+    private static final String s_name = "deletevmsnapshotresponse";
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_ID,
+               type = CommandType.UUID,
+               entityType = VMSnapshotResponse.class,
+               required = true,
+               description = "The ID of the VM snapshot")
+    private Long id;
+
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getId());
+        if (vmSnapshot != null) {
+            return vmSnapshot.getAccountId();
+        }
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("vmsnapshot id: " + this._uuidMgr.getUuid(VMSnapshot.class, getId()));
+        boolean result = _vmSnapshotService.deleteVMSnapshot(getId());
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete vm snapshot");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Delete VM snapshot: " + this._uuidMgr.getUuid(VMSnapshot.class, getId());
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_SNAPSHOT_DELETE;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/ListVMSnapshotCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java
new file mode 100644
index 0000000..8c3510b
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java
@@ -0,0 +1,99 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vmsnapshot;
+
+import java.util.logging.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.snapshot.VMSnapshot;
+
+@APICommand(name = "revertToVMSnapshot", description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since = "4.2.0", responseView = ResponseView.Restricted,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
+public class RevertToVMSnapshotCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RevertToVMSnapshotCmd.class.getName());
+    private static final String s_name = "reverttovmsnapshotresponse";
+
+    @ACL(accessType = AccessType.OperateEntry, pointerToEntity = "getVmId()")
+    @Parameter(name = ApiConstants.VM_SNAPSHOT_ID,
+               type = CommandType.UUID,
+               required = true,
+               entityType = VMSnapshotResponse.class,
+               description = "The ID of the vm snapshot")
+    private Long vmSnapShotId;
+
+    public Long getVmSnapShotId() {
+        return vmSnapShotId;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getVmSnapShotId());
+        if (vmSnapshot != null) {
+            return vmSnapshot.getAccountId();
+        }
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() throws  ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
+        CallContext.current().setEventDetails("vmsnapshot id: " + this._uuidMgr.getUuid(VMSnapshot.class, getVmSnapShotId()));
+        UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted,
+                    "virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to revert VM snapshot");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Revert from VM snapshot: " + this._uuidMgr.getUuid(VMSnapshot.class, getVmSnapShotId());
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_SNAPSHOT_REVERT;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/volume/AddResourceDetailCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
new file mode 100644
index 0000000..7e2b155
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
@@ -0,0 +1,129 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AttachVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(AttachVolumeCmd.class.getName());
+    private static final String s_name = "attachvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.DEVICE_ID, type = CommandType.LONG, description = "the ID of the device to map the volume to within the guest OS. "
+            + "If no deviceId is passed in, the next available deviceId will be chosen. " + "Possible values for a Linux OS are:" + "* 0 - /dev/xvda" + "* 1 - /dev/xvdb" + "* 2 - /dev/xvdc"
+        + "* 4 - /dev/xvde" + "* 5 - /dev/xvdf" + "* 6 - /dev/xvdg" + "* 7 - /dev/xvdh" + "* 8 - /dev/xvdi" + "* 9 - /dev/xvdj")
+    private Long deviceId;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume")
+    private Long id;
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="    the ID of the virtual machine")
+    private Long virtualMachineId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Volume volume = _responseGenerator.findVolumeById(getId());
+        if (volume == null) {
+            return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return volume.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_ATTACH;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "attaching volume: " + this._uuidMgr.getUuid(Volume.class, getId()) + " to vm: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId());
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()) + " VmId: " + this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()));
+        Volume result = _volumeService.attachVolumeToVM(this);
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to attach volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
new file mode 100644
index 0000000..6528109
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
@@ -0,0 +1,246 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+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.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = {
+        Volume.class, VirtualMachine.class},
+            requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateVolumeCmd.class.getName());
+    private static final String s_name = "createvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ACCOUNT,
+               type = BaseCmd.CommandType.STRING,
+               description = "the account associated with the disk volume. Must be used with the domainId parameter.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.PROJECT_ID,
+               type = CommandType.UUID,
+               entityType = ProjectResponse.class,
+               description = "the project associated with the volume. Mutually exclusive with account parameter")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "the domain ID associated with the disk offering. If used with the account parameter"
+                   + " returns the disk volume associated with the account for the specified domain.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.DISK_OFFERING_ID,
+               required = false,
+               type = CommandType.UUID,
+               entityType = DiskOfferingResponse.class,
+               description = "the ID of the disk offering. Either diskOfferingId or snapshotId must be passed in.")
+    private Long diskOfferingId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the disk volume")
+    private String volumeName;
+
+    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "Arbitrary volume size")
+    private Long size;
+
+    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, description = "min iops")
+    private Long minIops;
+
+    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, description = "max iops")
+    private Long maxIops;
+
+    @Parameter(name = ApiConstants.SNAPSHOT_ID,
+               type = CommandType.UUID,
+               entityType = SnapshotResponse.class,
+               description = "the snapshot ID for the disk volume. Either diskOfferingId or snapshotId must be passed in.")
+    private Long snapshotId;
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of the availability zone")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "an optional field, whether to display the volume to the end user or not.", authorized = {RoleType.Admin})
+    private Boolean displayVolume;
+
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+               type = CommandType.UUID,
+               entityType = UserVmResponse.class,
+               description = "the ID of the virtual machine; to be used with snapshot Id, VM to which the volume gets attached after creation")
+    private Long virtualMachineId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public String getVolumeName() {
+        return volumeName;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Long getSnapshotId() {
+        return snapshotId;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    private Long getProjectId() {
+        return projectId;
+    }
+
+    public Boolean getDisplayVolume() {
+        return displayVolume;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        if(displayVolume == null)
+            return true;
+        else
+            return displayVolume;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "volume";
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "creating volume: " + getVolumeName() + ((getSnapshotId() == null) ? "" : " from snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId()));
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException {
+
+        Volume volume = _volumeService.allocVolume(this);
+        if (volume != null) {
+            setEntityId(volume.getId());
+            setEntityUuid(volume.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create volume");
+        }
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Volume Id: " + getEntityUuid() + ((getSnapshotId() == null) ? "" : " from snapshot: " + this._uuidMgr.getUuid(Snapshot.class, getSnapshotId())));
+        Volume volume = _volumeService.createVolume(this);
+        if (volume != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
+            //FIXME - have to be moved to ApiResponseHelper
+            if (getSnapshotId() != null) {
+                Snapshot snap = _entityMgr.findById(Snapshot.class, getSnapshotId());
+                if (snap != null) {
+                    response.setSnapshotId(snap.getUuid()); // if the volume was
+                    // created from a
+                    // snapshot,
+                    // snapshotId will
+                    // be set so we pass
+                    // it back in the
+                    // response
+                }
+            }
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java
new file mode 100644
index 0000000..070ec5f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java
@@ -0,0 +1,93 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+
+@APICommand(name = "deleteVolume", description = "Deletes a detached disk volume.", responseObject = SuccessResponse.class, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DeleteVolumeCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(DeleteVolumeCmd.class.getName());
+    private static final String s_name = "deletevolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
+            required=true, description="The ID of the disk volume")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "volume";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Volume volume = _entityMgr.findById(Volume.class, getId());
+        if (volume != null) {
+            return volume.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() throws ConcurrentOperationException {
+        CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()));
+        boolean result = _volumeService.deleteVolume(id, CallContext.current().getCallingAccount());
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java
new file mode 100644
index 0000000..55d30e3
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java
@@ -0,0 +1,153 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class DetachVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DetachVolumeCmd.class.getName());
+    private static final String s_name = "detachvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
+            description="the ID of the disk volume")
+    private Long id;
+
+    @Parameter(name = ApiConstants.DEVICE_ID, type = CommandType.LONG, description = "the device ID on the virtual machine where volume is detached from")
+    private Long deviceId;
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+               type = CommandType.UUID,
+               entityType = UserVmResponse.class,
+               description = "the ID of the virtual machine where the volume is detached from")
+    private Long virtualMachineId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public Long getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "volume";
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long volumeId = getId();
+        if (volumeId != null) {
+            Volume volume = _responseGenerator.findVolumeById(volumeId);
+            if (volume != null) {
+                return volume.getAccountId();
+            }
+        } else if (getVirtualMachineId() != null) {
+            UserVm vm = _responseGenerator.findUserVmById(getVirtualMachineId());
+            if (vm != null) {
+                return vm.getAccountId();
+            }
+        }
+
+        // invalid id, parent this command to SYSTEM so ERROR events are tracked
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_DETACH;
+    }
+
+    @Override
+    public String getEventDescription() {
+        StringBuilder sb = new StringBuilder();
+        if (id != null) {
+            sb.append(": " + this._uuidMgr.getUuid(Volume.class, id));
+        } else if ((deviceId != null) && (virtualMachineId != null)) {
+            sb.append(" with device id: " + deviceId + " from vm: " + ((getVirtualMachineId() != null) ? this._uuidMgr.getUuid(VirtualMachine.class, getVirtualMachineId()) : "" ));
+        } else {
+            sb.append(" <error:  either volume id or deviceId/vmId need to be specified>");
+        }
+        return  "detaching volume" + sb.toString();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(getEventDescription());
+        Volume result = _volumeService.detachVolumeFromVM(this);
+        if (result != null){
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
+            response.setResponseName("volume");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to detach volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java
new file mode 100644
index 0000000..f482366
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java
@@ -0,0 +1,158 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Upload;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+
+@APICommand(name = "extractVolume", description = "Extracts volume", responseObject = ExtractResponse.class, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ExtractVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ExtractVolumeCmd.class.getName());
+
+    private static final String s_name = "extractvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
+            required=true, description="the ID of the volume")
+    private Long id;
+
+    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, length = 2048, description = "the url to which the volume would be extracted")
+    private String url;
+
+    @Parameter(name = ApiConstants.ZONE_ID,
+               type = CommandType.UUID,
+               entityType = ZoneResponse.class,
+               required = true,
+               description = "the ID of the zone where the volume is located")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.MODE, type = CommandType.STRING, required = true, description = "the mode of extraction - HTTP_DOWNLOAD or FTP_UPLOAD")
+    private String mode;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getStaticName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Volume volume = _entityMgr.findById(Volume.class, getId());
+        if (volume != null) {
+            return volume.getAccountId();
+        }
+
+        // invalid id, parent this command to SYSTEM so ERROR events are tracked
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_EXTRACT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "Extraction job";
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()));
+        String uploadUrl = _volumeService.extractVolume(this);
+        if (uploadUrl != null) {
+            ExtractResponse response = new ExtractResponse();
+            response.setResponseName(getCommandName());
+            response.setObjectName("volume");
+            Volume vol = _entityMgr.findById(Volume.class, id);
+            response.setId(vol.getUuid());
+            response.setName(vol.getName());
+            DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+            response.setMode(mode);
+            response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
+            Account account = _entityMgr.findById(Account.class, getEntityOwnerId());
+            response.setAccountId(account.getUuid());
+            response.setUrl(uploadUrl);
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume");
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolumeCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/volume/ListResourceDetailsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/volume/ListVolumesCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java
new file mode 100644
index 0000000..f5d5e8c
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java
@@ -0,0 +1,135 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import com.cloud.storage.StoragePool;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+
+@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {
+        Volume.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class MigrateVolumeCmd extends BaseAsyncCmd {
+    private static final String s_name = "migratevolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the volume")
+    private Long volumeId;
+
+    @Parameter(name = ApiConstants.STORAGE_ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, required = true, description = "destination storage pool ID to migrate the volume to")
+    private Long storageId;
+
+    @Parameter(name = ApiConstants.LIVE_MIGRATE, type = CommandType.BOOLEAN, required = false, description = "if the volume should be live migrated when it is attached to a running vm")
+    private Boolean liveMigrate;
+
+    @Parameter(name = ApiConstants.NEW_DISK_OFFERING_ID, type = CommandType.STRING, description = "The new disk offering ID that replaces the current one used by the volume. This new disk offering is used to better reflect the new storage where the volume is going to be migrated to.")
+    private String newDiskOfferingUuid;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    // TODO remove this in 5.0 and use id as param instead.
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public Long getId() {
+        return getVolumeId();
+    }
+
+    public Long getStoragePoolId() {
+        return storageId;
+    }
+
+    public boolean isLiveMigrate() {
+        return (liveMigrate != null) ? liveMigrate : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
+        if (volume != null) {
+            return volume.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_MIGRATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Attempting to migrate volume Id: " + this._uuidMgr.getUuid(Volume.class, getVolumeId()) + " to storage pool Id: " + this._uuidMgr.getUuid(StoragePool.class, getStoragePoolId());
+    }
+
+    public String getNewDiskOfferingUuid() {
+        return newDiskOfferingUuid;
+    }
+
+    @Override
+    public void execute() {
+        Volume result;
+
+        result = _volumeService.migrateVolume(this);
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return (getSyncObjId() != null) ? BaseAsyncCmd.migrationSyncObject : null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (getStoragePoolId() != null) {
+            return getStoragePoolId();
+        }
+        return null;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/volume/RemoveResourceDetailCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java
new file mode 100644
index 0000000..21127a7
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java
@@ -0,0 +1,189 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.projects.Project;
+import com.cloud.storage.Volume;
+import com.cloud.user.Account;
+
+
+@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ResizeVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ResizeVolumeCmd.class.getName());
+
+    private static final String s_name = "resizevolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the disk volume")
+    private Long id;
+
+    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS")
+    private Long minIops;
+
+    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS")
+    private Long maxIops;
+
+    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in GB")
+    private Long size;
+
+    @Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink")
+    private boolean shrinkOk;
+
+    @Parameter(name = ApiConstants.DISK_OFFERING_ID,
+               entityType = DiskOfferingResponse.class,
+               type = CommandType.UUID,
+               required = false,
+               description = "new disk offering id")
+    private Long newDiskOfferingId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public ResizeVolumeCmd() {}
+
+    public ResizeVolumeCmd(Long id, Long minIops, Long maxIops) {
+        this.id = id;
+        this.minIops = minIops;
+        this.maxIops = maxIops;
+    }
+
+    //TODO use the method getId() instead of this one.
+    public Long getEntityId() {
+        return id;
+    }
+
+    public Long getId() {
+        return getEntityId();
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public boolean isShrinkOk() {
+        return shrinkOk;
+    }
+
+    public Long getNewDiskOfferingId() {
+        return newDiskOfferingId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    public static String getResultObjectName() {
+        return "volume";
+    }
+
+   @Override
+    public long getEntityOwnerId() {
+
+        Volume volume = _entityMgr.findById(Volume.class, getEntityId());
+        if (volume == null) {
+                throw new InvalidParameterValueException("Unable to find volume by id=" + id);
+        }
+
+        Account account = _accountService.getAccount(volume.getAccountId());
+        //Can resize volumes for enabled projects/accounts only
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                Project project = _projectService.findByProjectAccountId(volume.getAccountId());
+            if (project.getState() != Project.State.Active) {
+                throw new PermissionDeniedException("Can't add resources to  project id=" + project.getId() + " in state=" + project.getState() +
+                    " as it's no longer active");
+            }
+        } else if (account.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of volume " + id + "  is disabled: " + account);
+        }
+
+        return volume.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_RESIZE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()) + " to size " + getSize() + "G";
+    }
+
+    @Override
+    public void execute() throws ResourceAllocationException {
+        Volume volume = null;
+        try {
+            CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getEntityId()) + " to size " + getSize() + "G");
+            volume = _volumeService.resizeVolume(this);
+        } catch (InvalidParameterValueException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
+        }
+
+        if (volume != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
+            //FIXME - have to be moved to ApiResponseHelper
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to resize volume");
+        }
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
new file mode 100644
index 0000000..b4f8642
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
@@ -0,0 +1,176 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.storage.Volume;
+
+@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateVolumeCmd.class.getName());
+    private static final String s_name = "updatevolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class, description="the ID of the disk volume")
+    private Long id;
+
+    @Parameter(name = ApiConstants.PATH, type = CommandType.STRING, description = "The path of the volume")
+    private String path;
+
+    @Parameter(name = ApiConstants.CHAIN_INFO,
+            type = CommandType.STRING,
+            description = "The chain info of the volume",
+            since = "4.4")
+    private String chainInfo;
+
+    @Parameter(name = ApiConstants.STORAGE_ID,
+               type = CommandType.UUID,
+               entityType = StoragePoolResponse.class,
+               description = "Destination storage pool UUID for the volume",
+               since = "4.3")
+    private Long storageId;
+
+    @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the volume", since = "4.3")
+    private String state;
+
+    @Parameter(name = ApiConstants.DISPLAY_VOLUME,
+               type = CommandType.BOOLEAN,
+ description = "an optional field, whether to the display the volume to the end user or not.", authorized = {RoleType.Admin})
+    private Boolean displayVolume;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getPath() {
+        return path;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getStorageId() {
+        return storageId;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public Boolean getDisplayVolume() {
+        return displayVolume;
+    }
+
+    public String getChainInfo() {
+        return chainInfo;
+    }
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.Volume;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Volume volume = _responseGenerator.findVolumeById(getId());
+        if (volume == null) {
+            throw new InvalidParameterValueException("Invalid volume id was provided");
+        }
+        return volume.getAccountId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        StringBuilder desc = new StringBuilder("Updating volume: ");
+        desc.append(getId()).append(" with");
+        if (getPath() != null) {
+            desc.append(" path " + getPath());
+        }
+        if (getStorageId() != null) {
+            desc.append(", storage id " + getStorageId());
+        }
+
+        if (getState() != null) {
+            desc.append(", state " + getState());
+        }
+        return desc.toString();
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()));
+        Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(),
+                getCustomId(), getEntityOwnerId(), getChainInfo());
+        if (result != null) {
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update volume");
+        }
+    }
+
+    @Override
+    public void checkUuid() {
+        if (getCustomId() != null) {
+            _uuidMgr.checkUuid(getCustomId(), Volume.class);
+        }
+    }
+
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
new file mode 100644
index 0000000..2802c00
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
@@ -0,0 +1,181 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.volume;
+
+import com.cloud.dc.DataCenter;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.storage.Volume;
+
+@APICommand(name = "uploadVolume", description = "Uploads a data disk.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UploadVolumeCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(UploadVolumeCmd.class.getName());
+    private static final String s_name = "uploadvolumeresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.FORMAT,
+               type = CommandType.STRING,
+               required = true,
+               description = "the format for the volume. Possible values include QCOW2, OVA, and VHD.")
+    private String format;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume")
+    private String volumeName;
+
+    @Parameter(name = ApiConstants.URL,
+               type = CommandType.STRING,
+               required = true,
+               length = 2048,
+               description = "the URL of where the volume is hosted. Possible URL include http:// and https://")
+    private String url;
+
+    @Parameter(name = ApiConstants.ZONE_ID,
+               type = CommandType.UUID,
+               entityType = ZoneResponse.class,
+               required = true,
+               description = "the ID of the zone the volume is to be hosted on")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID,
+               type = CommandType.UUID,
+               entityType = DomainResponse.class,
+               description = "an optional domainId. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional accountName. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this volume. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
+    private String checksum;
+
+    @Parameter(name = ApiConstants.IMAGE_STORE_UUID, type = CommandType.STRING, description = "Image store uuid")
+    private String imageStoreUuid;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume for the project")
+    private Long projectId;
+
+    @Parameter(name = ApiConstants.DISK_OFFERING_ID, required = false, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering. This must be a custom sized offering since during uploadVolume volume size is unknown.")
+    private Long diskOfferingId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getFormat() {
+        return format;
+    }
+
+    public String getVolumeName() {
+        return volumeName;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public String getChecksum() {
+        return checksum;
+    }
+
+    public String getImageStoreUuid() {
+        return imageStoreUuid;
+    }
+
+    public Long getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+        ResourceAllocationException, NetworkRuleConflictException {
+
+            Volume volume = _volumeService.uploadVolume(this);
+            if (volume != null){
+            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
+                response.setResponseName(getCommandName());
+                setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upload volume");
+            }
+    }
+
+    @Override
+    public String getCommandName() {
+           return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "uploading volume: " + getVolumeName() + " in the zone " + this._uuidMgr.getUuid(DataCenter.class, getZoneId());
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VOLUME_UPLOAD;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteStaticRouteCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/DeleteVPCCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListPrivateGatewaysCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListStaticRoutesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListVPCOfferingsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/ListVPCsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpc/RestartVPCCmd.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
new file mode 100644
index 0000000..1309334
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
@@ -0,0 +1,136 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vpc;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.VpcResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {Vpc.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateVPCCmd extends BaseAsyncCustomIdCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateVPCCmd.class.getName());
+    private static final String s_name = "updatevpcresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VpcResponse.class, required = true, description = "the id of the VPC")
+    private Long id;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the VPC")
+    private String vpcName;
+
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the VPC")
+    private String displayText;
+
+    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vpc to the end user or not", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean display;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getVpcName() {
+        return vpcName;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Boolean isDisplayVpc() {
+        return display;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Vpc vpc = _entityMgr.findById(Vpc.class, getId());
+        if (vpc != null) {
+            return vpc.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), isDisplayVpc());
+        if (result != null) {
+            VpcResponse response = _responseGenerator.createVpcResponse(ResponseView.Restricted, result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VPC");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VPC_UPDATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "updating VPC id=" + getId();
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.vpcSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getId();
+    }
+
+    @Override
+    public void checkUuid() {
+        if (getCustomId() != null) {
+            _uuidMgr.checkUuid(getCustomId(), Vpc.class);
+        }
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/AddVpnUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateRemoteAccessVpnCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnConnectionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnCustomerGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/DeleteVpnGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListRemoteAccessVpnsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnConnectionsCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnCustomerGatewaysCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnGatewaysCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ListVpnUsersCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/RemoveVpnUserCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/ResetVpnConnectionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateRemoteAccessVpnCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateRemoteAccessVpnCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/UpdateRemoteAccessVpnCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateRemoteAccessVpnCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnConnectionCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/vpn/UpdateVpnGatewayCmd.java
diff --git a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/zone/ListZonesCmd.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/command/user/zone/ListZonesCmd.java
rename to api/src/main/java/org/apache/cloudstack/api/command/user/zone/ListZonesCmd.java
diff --git a/api/src/org/apache/cloudstack/api/response/AccountResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AccountResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AlertResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AlertResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AlertResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AlertResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AnnotationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AnnotationResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AnnotationResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AnnotationResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerInstanceResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ApplicationLoadBalancerRuleResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java
new file mode 100644
index 0000000..eecd6be
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java
@@ -0,0 +1,130 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.Date;
+
+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 org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.jobs.JobInfo;
+
+import com.cloud.serializer.Param;
+
+@EntityReference(value = JobInfo.class)
+public class AsyncJobResponse extends BaseResponse {
+
+    @SerializedName("accountid")
+    @Param(description = "the account that executed the async command")
+    private String accountId;
+
+    @SerializedName(ApiConstants.USER_ID)
+    @Param(description = "the user that executed the async command")
+    private String userId;
+
+    @SerializedName("cmd")
+    @Param(description = "the async command executed")
+    private String cmd;
+
+    @SerializedName("jobstatus")
+    @Param(description = "the current job status-should be 0 for PENDING")
+    private Integer jobStatus;
+
+    @SerializedName("jobprocstatus")
+    @Param(description = "the progress information of the PENDING job")
+    private Integer jobProcStatus;
+
+    @SerializedName("jobresultcode")
+    @Param(description = "the result code for the job")
+    private Integer jobResultCode;
+
+    @SerializedName("jobresulttype")
+    @Param(description = "the result type")
+    private String jobResultType;
+
+    @SerializedName("jobresult")
+    @Param(description = "the result reason")
+    private ResponseObject jobResult;
+
+    @SerializedName("jobinstancetype")
+    @Param(description = "the instance/entity object related to the job")
+    private String jobInstanceType;
+
+    @SerializedName("jobinstanceid")
+    @Param(description = "the unique ID of the instance/entity object related to the job")
+    private String jobInstanceId;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "  the created date of the job")
+    private Date created;
+
+    @SerializedName(ApiConstants.COMPLETED)
+    @Param(description = "  the completed date of the job")
+    private Date removed;
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public void setCmd(String cmd) {
+        this.cmd = cmd;
+    }
+
+    @Override
+    public void setJobStatus(Integer jobStatus) {
+        this.jobStatus = jobStatus;
+    }
+
+    public void setJobProcStatus(Integer jobProcStatus) {
+        this.jobProcStatus = jobProcStatus;
+    }
+
+    public void setJobResultCode(Integer jobResultCode) {
+        this.jobResultCode = jobResultCode;
+    }
+
+    public void setJobResultType(String jobResultType) {
+        this.jobResultType = jobResultType;
+    }
+
+    public void setJobResult(ResponseObject jobResult) {
+        this.jobResult = jobResult;
+    }
+
+    public void setJobInstanceType(String jobInstanceType) {
+        this.jobInstanceType = jobInstanceType;
+    }
+
+    public void setJobInstanceId(String jobInstanceId) {
+        this.jobInstanceId = jobInstanceId;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public void setRemoved(final Date removed) {
+        this.removed = removed;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/AuthenticationCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AuthenticationCmdResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AuthenticationCmdResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AuthenticationCmdResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AutoScalePolicyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AutoScalePolicyResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AutoScalePolicyResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AutoScalePolicyResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AutoScaleVmGroupResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AutoScaleVmGroupResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AutoScaleVmGroupResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AutoScaleVmGroupResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/AutoScaleVmProfileResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AutoScaleVmProfileResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/AutoScaleVmProfileResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/AutoScaleVmProfileResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CAProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CAProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CAProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CAProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CapabilityResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CapabilityResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CapabilityResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CapabilityResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CapacityResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CapacityResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CapacityResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CapacityResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CertificateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CertificateResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CertificateResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CertificateResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ChildTemplateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ChildTemplateResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ChildTemplateResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ChildTemplateResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CloudIdentifierResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CloudIdentifierResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CloudIdentifierResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CloudIdentifierResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ClusterResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ClusterResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ClusterResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ConditionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ConditionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ConditionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ConditionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ConfigurationResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ConfigurationResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ControlledEntityResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ControlledEntityResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ControlledEntityResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ControlledEntityResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ControlledViewEntityResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ControlledViewEntityResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ControlledViewEntityResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ControlledViewEntityResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CounterResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CounterResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CounterResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CounterResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CreateCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CreateCmdResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CreateCmdResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CreateCmdResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CreateSSHKeyPairResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/CustomCertificateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/CustomCertificateResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/CustomCertificateResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/CustomCertificateResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/DeploymentPlannersResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DeploymentPlannersResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/DeploymentPlannersResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/DeploymentPlannersResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java
new file mode 100644
index 0000000..5f22c91
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java
@@ -0,0 +1,331 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.Date;
+
+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.offering.DiskOffering;
+import com.cloud.serializer.Param;
+
+@EntityReference(value = DiskOffering.class)
+public class DiskOfferingResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "unique ID of the disk offering")
+    private String id;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "the domain ID this disk offering belongs to. Ignore this information as it is not currently applicable.")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "the domain name this disk offering belongs to. Ignore this information as it is not currently applicable.")
+    private String domain;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the name of the disk offering")
+    private String name;
+
+    @SerializedName(ApiConstants.DISPLAY_TEXT)
+    @Param(description = "an alternate display text of the disk offering.")
+    private String displayText;
+
+    @SerializedName(ApiConstants.DISK_SIZE)
+    @Param(description = "the size of the disk offering in GB")
+    private Long diskSize;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "the date this disk offering was created")
+    private Date created;
+
+    @SerializedName("iscustomized")
+    @Param(description = "true if disk offering uses custom size, false otherwise")
+    private Boolean customized;
+
+    @SerializedName("iscustomizediops")
+    @Param(description = "true if disk offering uses custom iops, false otherwise")
+    private Boolean customizedIops;
+
+    @SerializedName(ApiConstants.MIN_IOPS)
+    @Param(description = "the min iops of the disk offering")
+    private Long minIops;
+
+    @SerializedName(ApiConstants.MAX_IOPS)
+    @Param(description = "the max iops of the disk offering")
+    private Long maxIops;
+
+    @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE)
+    @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4")
+    private Integer hypervisorSnapshotReserve;
+
+    @SerializedName(ApiConstants.TAGS)
+    @Param(description = "the tags for the disk offering")
+    private String tags;
+
+    @SerializedName("storagetype")
+    @Param(description = "the storage type for this disk offering")
+    private String storageType;
+
+    @SerializedName("provisioningtype") @Param(description="provisioning type used to create volumes. Valid values are thin, sparse, fat.", since = "4.4.0")
+    private String provisioningType;
+
+    @SerializedName("diskBytesReadRate")
+    @Param(description = "bytes read rate of the disk offering")
+    private Long bytesReadRate;
+
+    @SerializedName("diskBytesReadRateMax")
+    @Param(description = "burst bytes read rate of the disk offering")
+    private Long bytesReadRateMax;
+
+    @SerializedName("diskBytesReadRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long bytesReadRateMaxLength;
+
+    @SerializedName("diskBytesWriteRate")
+    @Param(description = "bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskBytesWriteRateMax")
+    @Param(description = "burst bytes write rate of the disk offering")
+    private Long bytesWriteRateMax;
+
+    @SerializedName("diskBytesWriteRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long bytesWriteRateMaxLength;
+
+    @SerializedName("diskIopsReadRate")
+    @Param(description = "io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsReadRateMax")
+    @Param(description = "burst io requests read rate of the disk offering")
+    private Long iopsReadRateMax;
+
+    @SerializedName("diskIopsReadRateMaxLength")
+    @Param(description = "length (in second) of the burst")
+    private Long iopsReadRateMaxLength;
+
+    @SerializedName("diskIopsWriteRate")
+    @Param(description = "io requests write rate of the disk offering")
+    private Long iopsWriteRate;
+
+    @SerializedName("diskIopsWriteRateMax")
+    @Param(description = "burst io requests write rate of the disk offering")
+    private Long iopsWriteRateMax;
+
+    @SerializedName("diskIopsWriteRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long iopsWriteRateMaxLength;
+
+    @SerializedName("cacheMode")
+    @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough", since = "4.4")
+    private String cacheMode;
+
+    @SerializedName("displayoffering")
+    @Param(description = "whether to display the offering to the end user or not.")
+    private Boolean displayOffering;
+
+    public Boolean getDisplayOffering() {
+        return displayOffering;
+    }
+
+    public void setDisplayOffering(Boolean displayOffering) {
+        this.displayOffering = displayOffering;
+    }
+
+    public String getId() {
+        return id;
+
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    public Long getDiskSize() {
+        return diskSize;
+    }
+
+    public void setDiskSize(Long diskSize) {
+        this.diskSize = diskSize;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public Boolean isCustomized() {
+        return customized;
+    }
+
+    public void setCustomized(Boolean customized) {
+        this.customized = customized;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public void setCustomizedIops(Boolean customizedIops) {
+        this.customizedIops = customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public void setMinIops(Long minIops) {
+        this.minIops = minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public void setMaxIops(Long maxIops) {
+        this.maxIops = maxIops;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
+        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
+    }
+
+    public String getCacheMode() {
+        return cacheMode;
+    }
+
+    public void setCacheMode(String cacheMode) {
+        this.cacheMode = cacheMode;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public void setStorageType(String storageType) {
+        this.storageType = storageType;
+    }
+
+    public String getProvisioningType(){
+        return provisioningType;
+    }
+
+    public void setProvisioningType(String provisioningType){
+        this.provisioningType = provisioningType;
+    }
+
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public void setBytesReadRateMax(Long bytesReadRateMax) {
+        this.bytesReadRateMax = bytesReadRateMax;
+    }
+
+    public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) {
+        this.bytesReadRateMaxLength = bytesReadRateMaxLength;
+    }
+
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public void setBytesWriteRateMax(Long bytesWriteRateMax) {
+        this.bytesWriteRateMax = bytesWriteRateMax;
+    }
+
+    public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) {
+        this.bytesWriteRateMaxLength = bytesWriteRateMaxLength;
+    }
+
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public void setIopsReadRateMax(Long iopsReadRateMax) {
+        this.iopsReadRateMax = iopsReadRateMax;
+    }
+
+    public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) {
+        this.iopsReadRateMaxLength = iopsReadRateMaxLength;
+    }
+
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public void setIopsWriteRateMax(Long iopsWriteRateMax) {
+        this.iopsWriteRateMax = iopsWriteRateMax;
+    }
+
+    public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) {
+        this.iopsWriteRateMaxLength = iopsWriteRateMaxLength;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/DomainResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/DomainResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/DomainRouterResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/EventResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/EventResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/EventResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/EventResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/EventTypeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/EventTypeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/EventTypeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/EventTypeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ExceptionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ExceptionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ExceptionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ExceptionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ExternalFirewallResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ExternalFirewallResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ExternalFirewallResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ExternalFirewallResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ExternalLoadBalancerResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ExternalLoadBalancerResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ExternalLoadBalancerResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ExternalLoadBalancerResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ExtractResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ExtractResponse.java
new file mode 100644
index 0000000..3d22dfe
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ExtractResponse.java
@@ -0,0 +1,207 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.Date;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+
+public class ExtractResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the id of extracted object")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the name of the extracted object")
+    private String name;
+
+    @SerializedName("extractId")
+    @Param(description = "the upload id of extracted object")
+    private String uploadId;
+
+    @SerializedName("uploadpercentage")
+    @Param(description = "the percentage of the entity uploaded to the specified location")
+    private Integer uploadPercent;
+
+    @SerializedName("status")
+    @Param(description = "the status of the extraction")
+    private String status;
+
+    @SerializedName("accountid")
+    @Param(description = "the account id to which the extracted object belongs")
+    private String accountId;
+
+    @SerializedName("resultstring")
+    @Param(includeInApiDoc = false)
+    private String resultString;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "the time and date the object was created")
+    private Date createdDate;
+
+    @SerializedName(ApiConstants.STATE)
+    @Param(description = "the state of the extracted object")
+    private String state;
+
+    @SerializedName("storagetype")
+    @Param(description = "type of the storage")
+    private String storageType;
+
+    @SerializedName(ApiConstants.ZONE_ID)
+    @Param(description = "zone ID the object was extracted from")
+    private String zoneId;
+
+    @SerializedName(ApiConstants.ZONE_NAME)
+    @Param(description = "zone name the object was extracted from")
+    private String zoneName;
+
+    @SerializedName("extractMode")
+    @Param(description = "the mode of extraction - upload or download")
+    private String mode;
+
+    @SerializedName(ApiConstants.URL)
+    @Param(description = "if mode = upload then url of the uploaded entity. if mode = download the url from which the entity can be downloaded")
+    private String url;
+
+    public ExtractResponse() {
+    }
+
+    public ExtractResponse(String typeId, String typeName, String accountId, String state, String uploadId) {
+        this.id = typeId;
+        this.name = typeName;
+        this.accountId = accountId;
+        this.state = state;
+        this.uploadId = uploadId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUploadId() {
+        return uploadId;
+    }
+
+    public void setUploadId(String uploadId) {
+        this.uploadId = uploadId;
+    }
+
+    public Integer getUploadPercent() {
+        return uploadPercent;
+    }
+
+    public void setUploadPercent(int uploadPercent) {
+        this.uploadPercent = uploadPercent;
+    }
+
+    public String getUploadStatus() {
+        return status;
+    }
+
+    public void setUploadStatus(String status) {
+        this.status = status;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    public String getResultString() {
+        return resultString;
+    }
+
+    public void setResultString(String resultString) {
+        this.resultString = resultString;
+    }
+
+    public Date getCreatedDate() {
+        return createdDate;
+    }
+
+    public void setCreatedDate(Date createdDate) {
+        this.createdDate = createdDate;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public void setStorageType(String storageType) {
+        this.storageType = storageType;
+    }
+
+    public String getZoneId() {
+        return zoneId;
+    }
+
+    public void setZoneId(String zoneId) {
+        this.zoneId = zoneId;
+    }
+
+    public String getZoneName() {
+        return zoneName;
+    }
+
+    public void setZoneName(String zoneName) {
+        this.zoneName = zoneName;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    public void setMode(String mode) {
+        this.mode = mode;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/FirewallResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/FirewallResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/FirewallResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/FirewallResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/FirewallRuleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/FirewallRuleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/FirewallRuleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/FirewallRuleResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GetUploadParamsResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GetUploadParamsResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GetVMPasswordResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GetVMPasswordResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GetVMPasswordResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GpuResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GpuResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GpuResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GpuResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GuestOSCategoryResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GuestOSCategoryResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GuestOSCategoryResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GuestOSCategoryResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GuestOSResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GuestOSResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GuestOSResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GuestOSResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/GuestVlanRangeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/GuestVlanRangeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/GuestVlanRangeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/GuestVlanRangeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/HAProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HAProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HAProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HAProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/HostForMigrationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HostForMigrationResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HostForMigrationResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HostForMigrationResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/HostHAResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HostHAResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HostHAResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HostHAResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
new file mode 100644
index 0000000..3d53682
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java
@@ -0,0 +1,664 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+import org.apache.cloudstack.ha.HAConfig;
+import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@EntityReference(value = Host.class)
+public class HostResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the host")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the name of the host")
+    private String name;
+
+    @SerializedName(ApiConstants.STATE)
+    @Param(description = "the state of the host")
+    private Status state;
+
+    @SerializedName("disconnected")
+    @Param(description = "true if the host is disconnected. False otherwise.")
+    private Date disconnectedOn;
+
+    @SerializedName(ApiConstants.TYPE)
+    @Param(description = "the host type")
+    private Host.Type hostType;
+
+    @SerializedName("oscategoryid")
+    @Param(description = "the OS category ID of the host")
+    private String osCategoryId;
+
+    @SerializedName("oscategoryname")
+    @Param(description = "the OS category name of the host")
+    private String osCategoryName;
+
+    @SerializedName(ApiConstants.IP_ADDRESS)
+    @Param(description = "the IP address of the host")
+    private String ipAddress;
+
+    @SerializedName(ApiConstants.ZONE_ID)
+    @Param(description = "the Zone ID of the host")
+    private String zoneId;
+
+    @SerializedName(ApiConstants.ZONE_NAME)
+    @Param(description = "the Zone name of the host")
+    private String zoneName;
+
+    @SerializedName(ApiConstants.POD_ID)
+    @Param(description = "the Pod ID of the host")
+    private String podId;
+
+    @SerializedName("podname")
+    @Param(description = "the Pod name of the host")
+    private String podName;
+
+    @SerializedName("version")
+    @Param(description = "the host version")
+    private String version;
+
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "the host hypervisor")
+    private HypervisorType hypervisor;
+
+    @SerializedName("cpusockets")
+    @Param(description = "the number of CPU sockets on the host")
+    private Integer cpuSockets;
+
+    @SerializedName("cpunumber")
+    @Param(description = "the CPU number of the host")
+    private Integer cpuNumber;
+
+    @SerializedName("cpuspeed")
+    @Param(description = "the CPU speed of the host")
+    private Long cpuSpeed;
+
+    @SerializedName("cpuallocated")
+    @Param(description = "the amount of the host's CPU currently allocated")
+    private String cpuAllocated;
+
+    @SerializedName("cpuused")
+    @Param(description = "the amount of the host's CPU currently used")
+    private String cpuUsed;
+
+    @SerializedName("cpuwithoverprovisioning")
+    @Param(description = "the amount of the host's CPU after applying the cpu.overprovisioning.factor ")
+    private String cpuWithOverprovisioning;
+
+    @SerializedName("averageload")
+    @Param(description = "the cpu average load on the host")
+    private Long averageLoad;
+
+    @SerializedName("networkkbsread")
+    @Param(description = "the incoming network traffic on the host")
+    private Long networkKbsRead;
+
+    @SerializedName("networkkbswrite")
+    @Param(description = "the outgoing network traffic on the host")
+    private Long networkKbsWrite;
+
+    @Deprecated
+    @SerializedName("memorytotal")
+    @Param(description = "the memory total of the host, this parameter is deprecated use memorywithoverprovisioning")
+    private Long memoryTotal;
+
+    @SerializedName("memorywithoverprovisioning")
+    @Param(description = "the amount of the host's memory after applying the mem.overprovisioning.factor")
+    private String memWithOverprovisioning;
+
+    @SerializedName("memoryallocated")
+    @Param(description = "the amount of the host's memory currently allocated")
+    private long memoryAllocated;
+
+    @SerializedName("memoryused")
+    @Param(description = "the amount of the host's memory currently used")
+    private Long memoryUsed;
+
+    @SerializedName(ApiConstants.GPUGROUP)
+    @Param(description = "GPU cards present in the host", responseObject = GpuResponse.class, since = "4.4")
+    private List<GpuResponse> gpuGroup;
+
+    @SerializedName("disksizetotal")
+    @Param(description = "the total disk size of the host")
+    private Long diskSizeTotal;
+
+    @SerializedName("disksizeallocated")
+    @Param(description = "the host's currently allocated disk size")
+    private Long diskSizeAllocated;
+
+    @SerializedName("capabilities")
+    @Param(description = "capabilities of the host")
+    private String capabilities;
+
+    @SerializedName("lastpinged")
+    @Param(description = "the date and time the host was last pinged")
+    private Date lastPinged;
+
+    @SerializedName("managementserverid")
+    @Param(description = "the management server ID of the host")
+    private Long managementServerId;
+
+    @SerializedName("clusterid")
+    @Param(description = "the cluster ID of the host")
+    private String clusterId;
+
+    @SerializedName("clustername")
+    @Param(description = "the cluster name of the host")
+    private String clusterName;
+
+    @SerializedName("clustertype")
+    @Param(description = "the cluster type of the cluster that host belongs to")
+    private String clusterType;
+
+    @SerializedName("islocalstorageactive")
+    @Param(description = "true if local storage is active, false otherwise")
+    private Boolean localStorageActive;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "the date and time the host was created")
+    private Date created;
+
+    @SerializedName("removed")
+    @Param(description = "the date and time the host was removed")
+    private Date removed;
+
+    @SerializedName("events")
+    @Param(description = "events available for the host")
+    private String events;
+
+    @SerializedName("hosttags")
+    @Param(description = "comma-separated list of tags for the host")
+    private String hostTags;
+
+    @SerializedName("hasenoughcapacity")
+    @Param(description = "true if this host has enough CPU and RAM capacity to migrate a VM to it, false otherwise")
+    private Boolean hasEnoughCapacity;
+
+    @SerializedName("suitableformigration")
+    @Param(description = "true if this host is suitable(has enough capacity and satisfies all conditions like hosttags, max guests vm limit etc) to migrate a VM to it , false otherwise")
+    private Boolean suitableForMigration;
+
+    @SerializedName("hostha")
+    @Param(description = "the host HA information information")
+    private HostHAResponse hostHAResponse;
+
+    @SerializedName("outofbandmanagement")
+    @Param(description = "the host out-of-band management information")
+    private OutOfBandManagementResponse outOfBandManagementResponse;
+
+    @SerializedName("resourcestate")
+    @Param(description = "the resource state of the host")
+    private String resourceState;
+
+    @SerializedName(ApiConstants.HYPERVISOR_VERSION)
+    @Param(description = "the hypervisor version")
+    private String hypervisorVersion;
+
+    @SerializedName(ApiConstants.HA_HOST)
+    @Param(description = "true if the host is Ha host (dedicated to vms started by HA process; false otherwise")
+    private Boolean haHost;
+
+    @SerializedName(ApiConstants.DETAILS)
+    @Param(description = "Host details in key/value pairs.", since = "4.5")
+    private Map details;
+
+    @SerializedName(ApiConstants.ANNOTATION)
+    @Param(description = "the last annotation set on this host by an admin", since = "4.11")
+    private String annotation;
+
+    @SerializedName(ApiConstants.LAST_ANNOTATED)
+    @Param(description = "the last time this host was annotated", since = "4.11")
+    private Date lastAnnotated;
+
+    @SerializedName(ApiConstants.USERNAME)
+    @Param(description = "the admin that annotated this host", since = "4.11")
+    private String username;
+
+    // Default visibility to support accessing the details from unit tests
+    Map getDetails() {
+        return details;
+    }
+
+    @Override
+    public String getObjectId() {
+        return this.getId();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setState(Status state) {
+        this.state = state;
+    }
+
+    public void setDisconnectedOn(Date disconnectedOn) {
+        this.disconnectedOn = disconnectedOn;
+    }
+
+    public void setHostType(Host.Type hostType) {
+        this.hostType = hostType;
+    }
+
+    public void setOsCategoryId(String osCategoryId) {
+        this.osCategoryId = osCategoryId;
+    }
+
+    public void setOsCategoryName(String osCategoryName) {
+        this.osCategoryName = osCategoryName;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public void setZoneId(String zoneId) {
+        this.zoneId = zoneId;
+    }
+
+    public void setZoneName(String zoneName) {
+        this.zoneName = zoneName;
+    }
+
+    public void setPodId(String podId) {
+        this.podId = podId;
+    }
+
+    public void setPodName(String podName) {
+        this.podName = podName;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public void setHypervisor(HypervisorType hypervisor) {
+        this.hypervisor = hypervisor;
+    }
+
+    public void setCpuSockets(Integer cpuSockets) {
+        this.cpuSockets = cpuSockets;
+    }
+
+    public void setCpuNumber(Integer cpuNumber) {
+        this.cpuNumber = cpuNumber;
+    }
+
+    public void setCpuSpeed(Long cpuSpeed) {
+        this.cpuSpeed = cpuSpeed;
+    }
+
+    public String getCpuAllocated() {
+        return cpuAllocated;
+    }
+
+    public void setCpuAllocated(String cpuAllocated) {
+        this.cpuAllocated = cpuAllocated;
+    }
+
+    public void setCpuUsed(String cpuUsed) {
+        this.cpuUsed = cpuUsed;
+    }
+
+    public void setAverageLoad(Long averageLoad) {
+        this.averageLoad = averageLoad;
+    }
+
+    public void setNetworkKbsRead(Long networkKbsRead) {
+        this.networkKbsRead = networkKbsRead;
+    }
+
+    public void setNetworkKbsWrite(Long networkKbsWrite) {
+        this.networkKbsWrite = networkKbsWrite;
+    }
+
+    public void setMemWithOverprovisioning(String memWithOverprovisioning){
+        this.memWithOverprovisioning=memWithOverprovisioning;
+    }
+
+    public void setMemoryAllocated(long memoryAllocated) {
+        this.memoryAllocated = memoryAllocated;
+    }
+
+    public void setMemoryUsed(Long memoryUsed) {
+        this.memoryUsed = memoryUsed;
+    }
+
+    public void setGpuGroups(List<GpuResponse> gpuGroup) {
+        this.gpuGroup = gpuGroup;
+    }
+
+    public void setDiskSizeTotal(Long diskSizeTotal) {
+        this.diskSizeTotal = diskSizeTotal;
+    }
+
+    public void setDiskSizeAllocated(Long diskSizeAllocated) {
+        this.diskSizeAllocated = diskSizeAllocated;
+    }
+
+    public void setCapabilities(String capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    public void setLastPinged(Date lastPinged) {
+        this.lastPinged = lastPinged;
+    }
+
+    public void setManagementServerId(Long managementServerId) {
+        this.managementServerId = managementServerId;
+    }
+
+    public void setClusterId(String clusterId) {
+        this.clusterId = clusterId;
+    }
+
+    public void setClusterName(String clusterName) {
+        this.clusterName = clusterName;
+    }
+
+    public void setClusterType(String clusterType) {
+        this.clusterType = clusterType;
+    }
+
+    public void setLocalStorageActive(Boolean localStorageActive) {
+        this.localStorageActive = localStorageActive;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public void setEvents(String events) {
+        this.events = events;
+    }
+
+    public String getHostTags() {
+        return hostTags;
+    }
+
+    public void setHostTags(String hostTags) {
+        this.hostTags = hostTags;
+    }
+
+    public void setHasEnoughCapacity(Boolean hasEnoughCapacity) {
+        this.hasEnoughCapacity = hasEnoughCapacity;
+    }
+
+    public void setSuitableForMigration(Boolean suitableForMigration) {
+        this.suitableForMigration = suitableForMigration;
+    }
+
+    public HostHAResponse getHostHAResponse() {
+        return hostHAResponse;
+    }
+
+    public void setHostHAResponse(final HAConfig config) {
+        this.hostHAResponse = new HostHAResponse(config);
+    }
+
+    public OutOfBandManagementResponse getOutOfBandManagementResponse() {
+        return outOfBandManagementResponse;
+    }
+
+    public void setOutOfBandManagementResponse(final OutOfBandManagement outOfBandManagementConfig) {
+        this.outOfBandManagementResponse =  new OutOfBandManagementResponse(outOfBandManagementConfig);
+    }
+
+    public String getResourceState() {
+        return resourceState;
+    }
+
+    public void setResourceState(String resourceState) {
+        this.resourceState = resourceState;
+    }
+
+    public String getCpuWithOverprovisioning() {
+        return cpuWithOverprovisioning;
+    }
+
+    public void setCpuWithOverprovisioning(String cpuWithOverprovisioning) {
+        this.cpuWithOverprovisioning = cpuWithOverprovisioning;
+    }
+
+    public void setHypervisorVersion(String hypervisorVersion) {
+        this.hypervisorVersion = hypervisorVersion;
+    }
+
+    public void setHaHost(Boolean haHost) {
+        this.haHost = haHost;
+    }
+
+    public void setAnnotation(String annotation) {
+        this.annotation = annotation;
+    }
+
+    public void setLastAnnotated(Date lastAnnotated) {
+        this.lastAnnotated = lastAnnotated;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public void setDetails(Map details) {
+
+        if (details == null) {
+            return;
+        }
+
+        final Map detailsCopy = new HashMap(details);
+
+        // Fix for CVE ID 2015-3251
+        // Remove sensitive host credential information from
+        // the details to prevent leakage through API calls
+        detailsCopy.remove("username");
+        detailsCopy.remove("password");
+
+        this.details = detailsCopy;
+
+    }
+
+    public void setMemoryTotal(Long memoryTotal) {
+        this.memoryTotal = memoryTotal;
+    }
+    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 isLocalStorageActive() {
+        return localStorageActive;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public String getEvents() {
+        return events;
+    }
+
+    public Boolean hasEnoughCapacity() {
+        return hasEnoughCapacity;
+    }
+
+    public Boolean isSuitableForMigration() {
+        return suitableForMigration;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    public Boolean getHaHost() {
+        return haHost;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/HostTagResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HostTagResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HostTagResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HostTagResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/HypervisorResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/HypervisorResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/HypervisorResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/HypervisorResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/IPAddressResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ImageStoreResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ImageStoreResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/InstanceGroupResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/InstanceGroupResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/InstanceGroupResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/InstanceGroupResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/InternalLoadBalancerElementResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/IpForwardingRuleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/IpForwardingRuleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/IpForwardingRuleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/IpForwardingRuleResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/IsoVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/IsoVmResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/IsoVmResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/IsoVmResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/IsolationMethodResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/IsolationMethodResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/IsolationMethodResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/IsolationMethodResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LBHealthCheckPolicyResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LBHealthCheckResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LBHealthCheckResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LBHealthCheckResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LBHealthCheckResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LBStickinessPolicyResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LBStickinessResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LBStickinessResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LBStickinessResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LBStickinessResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ListResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ListResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ListResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ListResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LoadBalancerResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LoadBalancerResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LoadBalancerRuleVmMapResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LoginCmdResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LoginCmdResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/LogoutCmdResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/LogoutCmdResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/LogoutCmdResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/LogoutCmdResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ManagementServerResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ManagementServerResponse.java
new file mode 100644
index 0000000..efb7d87
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ManagementServerResponse.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+@EntityReference(value = ManagementServerHost.class)
+public class ManagementServerResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the management server")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the name of the management server")
+    private String name;
+
+    @SerializedName(ApiConstants.STATE)
+    @Param(description = "the state of the management server")
+    private ManagementServerHost.State state;
+
+    @SerializedName(ApiConstants.VERSION)
+    @Param(description = "the version of the management server")
+    private String version;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setState(ManagementServerHost.State state) {
+        this.state = state;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/NetworkACLItemResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkACLItemResponse.java
new file mode 100644
index 0000000..97f5042
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/NetworkACLItemResponse.java
@@ -0,0 +1,155 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.List;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = NetworkACLItem.class)
+public class NetworkACLItemResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the ACL Item")
+    private String id;
+
+    @SerializedName(ApiConstants.PROTOCOL)
+    @Param(description = "the protocol of the ACL")
+    private String protocol;
+
+    @SerializedName(ApiConstants.START_PORT)
+    @Param(description = "the starting port of ACL's port range")
+    private String startPort;
+
+    @SerializedName(ApiConstants.END_PORT)
+    @Param(description = "the ending port of ACL's port range")
+    private String endPort;
+
+    @SerializedName(ApiConstants.TRAFFIC_TYPE)
+    @Param(description = "the traffic type for the ACL")
+    private String trafficType;
+
+    @SerializedName(ApiConstants.STATE)
+    @Param(description = "the state of the rule")
+    private String state;
+
+    @SerializedName(ApiConstants.CIDR_LIST)
+    @Param(description = "the cidr list to forward traffic from")
+    private String cidrList;
+
+    @SerializedName(ApiConstants.ICMP_TYPE)
+    @Param(description = "type of the icmp message being sent")
+    private Integer icmpType;
+
+    @SerializedName(ApiConstants.ICMP_CODE)
+    @Param(description = "error code for this icmp message")
+    private Integer icmpCode;
+
+    @SerializedName(ApiConstants.TAGS)
+    @Param(description = "the list of resource tags associated with the network ACLs", responseObject = ResourceTagResponse.class)
+    private List<ResourceTagResponse> tags;
+
+    @SerializedName(ApiConstants.ACL_ID)
+    @Param(description = "the ID of the ACL this item belongs to")
+    private String aclId;
+
+    @SerializedName(ApiConstants.NUMBER)
+    @Param(description = "Number of the ACL Item")
+    private Integer number;
+
+    @SerializedName(ApiConstants.ACTION)
+    @Param(description = "Action of ACL Item. Allow/Deny")
+    private String action;
+
+    @SerializedName(ApiConstants.FOR_DISPLAY)
+    @Param(description = "is rule for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean forDisplay;
+
+    @SerializedName(ApiConstants.ACL_REASON)
+    @Param(description = "an explanation on why this ACL rule is being applied", since = "4.12")
+    private String reason;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public void setStartPort(String startPort) {
+        this.startPort = startPort;
+    }
+
+    public void setEndPort(String endPort) {
+        this.endPort = endPort;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public void setCidrList(String cidrList) {
+        this.cidrList = cidrList;
+    }
+
+    public void setIcmpType(Integer icmpType) {
+        this.icmpType = icmpType;
+    }
+
+    public void setIcmpCode(Integer icmpCode) {
+        this.icmpCode = icmpCode;
+    }
+
+    public void setTrafficType(String trafficType) {
+        this.trafficType = trafficType;
+    }
+
+    public void setTags(List<ResourceTagResponse> tags) {
+        this.tags = tags;
+    }
+
+    public void setAclId(String aclId) {
+        this.aclId = aclId;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public void setForDisplay(Boolean forDisplay) {
+        this.forDisplay = forDisplay;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkACLResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NetworkACLResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NetworkACLResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkDeviceResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkDeviceResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NetworkDeviceResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NetworkDeviceResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NetworkResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NicExtraDhcpOptionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NicExtraDhcpOptionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NicExtraDhcpOptionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NicExtraDhcpOptionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NicResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NicResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NicResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/NicSecondaryIpResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/OutOfBandManagementResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/OutOfBandManagementResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/OutOfBandManagementResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/OutOfBandManagementResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/OvsProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/OvsProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/OvsProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/PhysicalNetworkResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/PhysicalNetworkResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/PhysicalNetworkResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/PhysicalNetworkResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/PodResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/PodResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/PodResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/PodResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/PortableIpRangeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/PortableIpRangeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/PortableIpRangeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/PortableIpRangeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/PortableIpResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/PortableIpResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/PortableIpResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/PortableIpResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/PrivateGatewayResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/PrivateGatewayResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/PrivateGatewayResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/PrivateGatewayResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ProjectAccountResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ProjectAccountResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ProjectAccountResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ProjectAccountResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ProjectInvitationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ProjectInvitationResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ProjectInvitationResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ProjectInvitationResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ProjectResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ProjectResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ProjectResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ProjectResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/RegionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RegionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/RegionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/RegionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/RegisterResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RegisterResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/RegisterResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/RegisterResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ResourceCountResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ResourceCountResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ResourceCountResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ResourceCountResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ResourceDetailResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ResourceDetailResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ResourceDetailResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ResourceDetailResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ResourceLimitAndCountResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ResourceLimitAndCountResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ResourceLimitAndCountResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ResourceLimitAndCountResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ResourceLimitResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ResourceLimitResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ResourceLimitResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ResourceTagResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ResourceTagResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ResourceTagResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/RolePermissionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RolePermissionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/RolePermissionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/RolePermissionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/RoleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RoleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/RoleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/RoleResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/RunDiagnosticsResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/RunDiagnosticsResponse.java
new file mode 100644
index 0000000..4c8a923
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/RunDiagnosticsResponse.java
@@ -0,0 +1,67 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.api.response;
+
+import com.cloud.serializer.Param;
+import com.cloud.vm.VirtualMachine;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+@EntityReference(value = VirtualMachine.class)
+public class RunDiagnosticsResponse extends BaseResponse {
+    @SerializedName(ApiConstants.STDOUT)
+    @Param(description = "the standard output from the command execution")
+    private String stdout;
+
+    @SerializedName(ApiConstants.STDERR)
+    @Param(description = "the standard error output from the command execution")
+    private String stderr;
+
+    @SerializedName(ApiConstants.EXITCODE)
+    @Param(description = "the command execution return code")
+    private String exitCode;
+
+    public String getStdout() {
+        return stdout;
+    }
+
+    public void setStdout(String stdout) {
+        this.stdout = stdout;
+    }
+
+    public String getStderr() {
+        return stderr;
+    }
+
+    public void setStderr(String stderr) {
+        this.stderr = stderr;
+    }
+
+    public String getExitCode() {
+        return exitCode;
+    }
+
+    public void setExitCode(String exitCode) {
+        this.exitCode = exitCode;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SSHKeyPairResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SecurityGroupResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SecurityGroupResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SecurityGroupResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SecurityGroupRuleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SecurityGroupRuleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SecurityGroupRuleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SecurityGroupRuleResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
new file mode 100644
index 0000000..51b5c1f
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
@@ -0,0 +1,428 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.Date;
+import java.util.Map;
+
+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.offering.ServiceOffering;
+import com.cloud.serializer.Param;
+
+@EntityReference(value = ServiceOffering.class)
+public class ServiceOfferingResponse extends BaseResponse {
+    @SerializedName("id")
+    @Param(description = "the id of the service offering")
+    private String id;
+
+    @SerializedName("name")
+    @Param(description = "the name of the service offering")
+    private String name;
+
+    @SerializedName("displaytext")
+    @Param(description = "an alternate display text of the service offering.")
+    private String displayText;
+
+    @SerializedName("cpunumber")
+    @Param(description = "the number of CPU")
+    private Integer cpuNumber;
+
+    @SerializedName("cpuspeed")
+    @Param(description = "the clock rate CPU speed in Mhz")
+    private Integer cpuSpeed;
+
+    @SerializedName("memory")
+    @Param(description = "the memory in MB")
+    private Integer memory;
+
+    @SerializedName("created")
+    @Param(description = "the date this service offering was created")
+    private Date created;
+
+    @SerializedName("storagetype")
+    @Param(description = "the storage type for this service offering")
+    private String storageType;
+
+    @SerializedName("provisioningtype") @Param(description="provisioning type used to create volumes. Valid values are thin, sparse, fat.", since = "4.4.0")
+    private String provisioningType;
+
+    @SerializedName("offerha")
+    @Param(description = "the ha support in the service offering")
+    private Boolean offerHa;
+
+    @SerializedName("limitcpuuse")
+    @Param(description = "restrict the CPU usage to committed service offering")
+    private Boolean limitCpuUse;
+
+    @SerializedName("isvolatile")
+    @Param(description = "true if the vm needs to be volatile, i.e., on every reboot of vm from API root disk is discarded and creates a new root disk")
+    private Boolean isVolatile;
+
+    @SerializedName("tags")
+    @Param(description = "the tags for the service offering")
+    private String tags;
+
+    @SerializedName("domainid")
+    @Param(description = "the domain id of the service offering")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "Domain name for the offering")
+    private String domain;
+
+    @SerializedName(ApiConstants.HOST_TAGS)
+    @Param(description = "the host tag for the service offering")
+    private String hostTag;
+
+    @SerializedName(ApiConstants.IS_SYSTEM_OFFERING)
+    @Param(description = "is this a system vm offering")
+    private Boolean isSystem;
+
+    @SerializedName(ApiConstants.IS_DEFAULT_USE)
+    @Param(description = "is this a  default system vm offering")
+    private Boolean defaultUse;
+
+    @SerializedName(ApiConstants.SYSTEM_VM_TYPE)
+    @Param(description = "is this a the systemvm type for system vm offering")
+    private String vmType;
+
+    @SerializedName(ApiConstants.NETWORKRATE)
+    @Param(description = "data transfer rate in megabits per second allowed.")
+    private Integer networkRate;
+
+    @SerializedName("iscustomizediops")
+    @Param(description = "true if disk offering uses custom iops, false otherwise", since = "4.4")
+    private Boolean customizedIops;
+
+    @SerializedName(ApiConstants.MIN_IOPS)
+    @Param(description = "the min iops of the disk offering", since = "4.4")
+    private Long minIops;
+
+    @SerializedName(ApiConstants.MAX_IOPS)
+    @Param(description = "the max iops of the disk offering", since = "4.4")
+    private Long maxIops;
+
+    @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE)
+    @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4")
+    private Integer hypervisorSnapshotReserve;
+
+    @SerializedName("diskBytesReadRate")
+    @Param(description = "bytes read rate of the service offering")
+    private Long bytesReadRate;
+
+    @SerializedName("diskBytesReadRateMax")
+    @Param(description = "burst bytes read rate of the disk offering")
+    private Long bytesReadRateMax;
+
+    @SerializedName("diskBytesReadRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long bytesReadRateMaxLength;
+
+    @SerializedName("diskBytesWriteRate")
+    @Param(description = "bytes write rate of the service offering")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskBytesWriteRateMax")
+    @Param(description = "burst bytes write rate of the disk offering")
+    private Long bytesWriteRateMax;
+
+    @SerializedName("diskBytesWriteRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long bytesWriteRateMaxLength;
+
+    @SerializedName("diskIopsReadRate")
+    @Param(description = "io requests read rate of the service offering")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsReadRateMax")
+    @Param(description = "burst io requests read rate of the disk offering")
+    private Long iopsReadRateMax;
+
+    @SerializedName("diskIopsReadRateMaxLength")
+    @Param(description = "length (in second) of the burst")
+    private Long iopsReadRateMaxLength;
+
+    @SerializedName("diskIopsWriteRate")
+    @Param(description = "io requests write rate of the service offering")
+    private Long iopsWriteRate;
+
+    @SerializedName("diskIopsWriteRateMax")
+    @Param(description = "burst io requests write rate of the disk offering")
+    private Long iopsWriteRateMax;
+
+    @SerializedName("diskIopsWriteRateMaxLength")
+    @Param(description = "length (in seconds) of the burst")
+    private Long iopsWriteRateMaxLength;
+
+    @SerializedName(ApiConstants.DEPLOYMENT_PLANNER)
+    @Param(description = "deployment strategy used to deploy VM.")
+    private String deploymentPlanner;
+
+    @SerializedName(ApiConstants.SERVICE_OFFERING_DETAILS)
+    @Param(description = "additional key/value details tied with this service offering", since = "4.2.0")
+    private Map<String, String> details;
+
+    @SerializedName("iscustomized")
+    @Param(description = "is true if the offering is customized", since = "4.3.0")
+    private Boolean isCustomized;
+
+    public ServiceOfferingResponse() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Boolean getIsSystem() {
+        return isSystem;
+    }
+
+    public void setIsSystemOffering(Boolean isSystem) {
+        this.isSystem = isSystem;
+    }
+
+    public Boolean isDefaultUse() {
+        return defaultUse;
+    }
+
+    public void setDefaultUse(Boolean defaultUse) {
+        this.defaultUse = defaultUse;
+    }
+
+    public String getSystemVmType() {
+        return vmType;
+    }
+
+    public void setSystemVmType(String vmtype) {
+        vmType = vmtype;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    public int getCpuNumber() {
+        return cpuNumber;
+    }
+
+    public void setCpuNumber(Integer cpuNumber) {
+        this.cpuNumber = cpuNumber;
+    }
+
+    public int getCpuSpeed() {
+        return cpuSpeed;
+    }
+
+    public void setCpuSpeed(Integer cpuSpeed) {
+        this.cpuSpeed = cpuSpeed;
+    }
+
+    public int getMemory() {
+        return memory;
+    }
+
+    public void setMemory(Integer memory) {
+        this.memory = memory;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public void setStorageType(String storageType) {
+        this.storageType = storageType;
+    }
+
+    public String getProvisioningType(){
+        return provisioningType;
+    }
+
+    public void setProvisioningType(String provisioningType){
+        this.provisioningType = provisioningType;
+    }
+
+    public Boolean getOfferHa() {
+        return offerHa;
+    }
+
+    public void setOfferHa(Boolean offerHa) {
+        this.offerHa = offerHa;
+    }
+
+    public Boolean getLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public void setLimitCpuUse(Boolean limitCpuUse) {
+        this.limitCpuUse = limitCpuUse;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    public void setHostTag(String hostTag) {
+        this.hostTag = hostTag;
+    }
+
+    public void setNetworkRate(Integer networkRate) {
+        this.networkRate = networkRate;
+    }
+
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public void setDeploymentPlanner(String deploymentPlanner) {
+        this.deploymentPlanner = deploymentPlanner;
+    }
+
+    public boolean getVolatileVm() {
+        return isVolatile;
+    }
+
+    public void setVolatileVm(boolean isVolatile) {
+        this.isVolatile = isVolatile;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public void setCustomizedIops(Boolean customizedIops) {
+        this.customizedIops = customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public void setMinIops(Long minIops) {
+        this.minIops = minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public void setMaxIops(Long maxIops) {
+        this.maxIops = maxIops;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
+        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
+    }
+
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public void setBytesReadRateMax(Long bytesReadRateMax) { this.bytesReadRateMax = bytesReadRateMax; }
+
+    public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { this.bytesReadRateMaxLength = bytesReadRateMaxLength; }
+
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public void setBytesWriteRateMax(Long bytesWriteRateMax) { this.bytesWriteRateMax = bytesWriteRateMax; }
+
+    public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; }
+
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public void setIopsReadRateMax(Long iopsReadRateMax) { this.iopsReadRateMax = iopsReadRateMax; }
+
+    public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { this.iopsReadRateMaxLength = iopsReadRateMaxLength; }
+
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public void setIopsWriteRateMax(Long iopsWriteRateMax) { this.iopsWriteRateMax = iopsWriteRateMax; }
+
+    public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
+    }
+
+    public void setIscutomized(boolean iscutomized) {
+        this.isCustomized = iscutomized;
+
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/response/ServiceResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/ServiceResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/ServiceResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnGatewayResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnGatewayResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/Site2SiteVpnGatewayResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/Site2SiteVpnGatewayResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java
new file mode 100644
index 0000000..10710c6
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.acl.RoleType;
+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.storage.snapshot.SnapshotPolicy;
+
+@EntityReference(value = SnapshotPolicy.class)
+public class SnapshotPolicyResponse extends BaseResponse {
+    @SerializedName("id")
+    @Param(description = "the ID of the snapshot policy")
+    private String id;
+
+    @SerializedName("volumeid")
+    @Param(description = "the ID of the disk volume")
+    private String volumeId;
+
+    @SerializedName("schedule")
+    @Param(description = "time the snapshot is scheduled to be taken.")
+    private String schedule;
+
+    @SerializedName("intervaltype")
+    @Param(description = "the interval type of the snapshot policy")
+    private short intervalType;
+
+    @SerializedName("maxsnaps")
+    @Param(description = "maximum number of snapshots retained")
+    private int maxSnaps;
+
+    @SerializedName("timezone")
+    @Param(description = "the time zone of the snapshot policy")
+    private String timezone;
+
+    @SerializedName(ApiConstants.FOR_DISPLAY)
+    @Param(description = "is this policy for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
+    private Boolean forDisplay;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getVolumeId() {
+        return volumeId;
+    }
+
+    public void setVolumeId(String volumeId) {
+        this.volumeId = volumeId;
+    }
+
+    public String getSchedule() {
+        return schedule;
+    }
+
+    public void setSchedule(String schedule) {
+        this.schedule = schedule;
+    }
+
+    public short getIntervalType() {
+        return intervalType;
+    }
+
+    public void setIntervalType(short intervalType) {
+        this.intervalType = intervalType;
+    }
+
+    public int getMaxSnaps() {
+        return maxSnaps;
+    }
+
+    public void setMaxSnaps(int maxSnaps) {
+        this.maxSnaps = maxSnaps;
+    }
+
+    public String getTimezone() {
+        return timezone;
+    }
+
+    public void setTimezone(String timezone) {
+        this.timezone = timezone;
+    }
+
+    public Boolean isForDisplay() {
+        return forDisplay;
+    }
+
+    public void setForDisplay(Boolean forDisplay) {
+        this.forDisplay = forDisplay;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SnapshotResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SnapshotResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SnapshotResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotScheduleResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SnapshotScheduleResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SnapshotScheduleResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SnapshotScheduleResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SslCertResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SslCertResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SslCertResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SslCertResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/StaticRouteResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/StaticRouteResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/StorageNetworkIpRangeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StorageNetworkIpRangeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/StorageNetworkIpRangeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/StorageNetworkIpRangeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/StoragePoolResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/StorageProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StorageProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/StorageProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/StorageProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/StorageTagResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StorageTagResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/StorageTagResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/StorageTagResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SuccessResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SuccessResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SuccessResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SuccessResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmInstanceResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmInstanceResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SystemVmInstanceResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SystemVmInstanceResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/SystemVmResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/TemplatePermissionsResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TemplatePermissionsResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/TemplatePermissionsResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/TemplatePermissionsResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java
new file mode 100644
index 0000000..a83fe42
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java
@@ -0,0 +1,405 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+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.Storage.ImageFormat;
+import com.cloud.template.VirtualMachineTemplate;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = VirtualMachineTemplate.class)
+@SuppressWarnings("unused")
+public class TemplateResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the template ID")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the template name")
+    private String name;
+
+    @SerializedName(ApiConstants.DISPLAY_TEXT)
+    @Param(description = "the template display text")
+    private String displayText;
+
+    @SerializedName(ApiConstants.IS_PUBLIC)
+    // propName="public"  (FIXME:  this used to be part of Param annotation, do we need it?)
+    @Param(description = "true if this template is a public template, false otherwise")
+    private boolean isPublic;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "the date this template was created")
+    private Date created;
+
+    @SerializedName("removed")
+    @Param(description = "the date this template was removed")
+    private Date removed;
+
+    @SerializedName(ApiConstants.IS_READY)
+    // propName="ready"  (FIXME:  this used to be part of Param annotation, do we need it?)
+    @Param(description = "true if the template is ready to be deployed from, false otherwise.")
+    private boolean isReady;
+
+    @SerializedName(ApiConstants.PASSWORD_ENABLED)
+    @Param(description = "true if the reset password feature is enabled, false otherwise")
+    private Boolean passwordEnabled;
+
+    @SerializedName(ApiConstants.FORMAT)
+    @Param(description = "the format of the template.")
+    private ImageFormat format;
+
+    @SerializedName(ApiConstants.BOOTABLE)
+    @Param(description = "true if the ISO is bootable, false otherwise")
+    private Boolean bootable;
+
+    @SerializedName(ApiConstants.IS_FEATURED)
+    @Param(description = "true if this template is a featured template, false otherwise")
+    private boolean featured;
+
+    @SerializedName("crossZones")
+    @Param(description = "true if the template is managed across all Zones, false otherwise")
+    private boolean crossZones;
+
+    @SerializedName(ApiConstants.OS_TYPE_ID)
+    @Param(description = "the ID of the OS type for this template.")
+    private String osTypeId;
+
+    @SerializedName("ostypename")
+    @Param(description = "the name of the OS type for this template.")
+    private String osTypeName;
+
+    @SerializedName(ApiConstants.ACCOUNT_ID)
+    @Param(description = "the account id to which the template belongs")
+    private String accountId;
+
+    @SerializedName(ApiConstants.ACCOUNT)
+    @Param(description = "the account name to which the template belongs")
+    private String account;
+
+    //TODO: since a template can be associated to more than one zones, this model is not accurate. For backward-compatibility, keep these fields
+    // here, but add a zones field to capture multiple zones.
+    @SerializedName(ApiConstants.ZONE_ID)
+    @Param(description = "the ID of the zone for this template")
+    private String zoneId;
+
+    @SerializedName(ApiConstants.ZONE_NAME)
+    @Param(description = "the name of the zone for this template")
+    private String zoneName;
+
+    @SerializedName(ApiConstants.STATUS)
+    @Param(description = "the status of the template")
+    private String status;
+
+    @SerializedName(ApiConstants.SIZE)
+    @Param(description = "the size of the template")
+    private Long size;
+
+    @SerializedName(ApiConstants.PHYSICAL_SIZE)
+    @Param(description = "the physical size of the template")
+    private Long physicalSize;
+
+    @SerializedName("templatetype")
+    @Param(description = "the type of the template")
+    private String templateType;
+
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "the hypervisor on which the template runs")
+    private String hypervisor;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "the name of the domain to which the template belongs")
+    private String domainName;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "the ID of the domain to which the template belongs")
+    private String domainId;
+
+    @SerializedName(ApiConstants.IS_EXTRACTABLE)
+    @Param(description = "true if the template is extractable, false otherwise")
+    private Boolean extractable;
+
+    @SerializedName(ApiConstants.CHECKSUM)
+    @Param(description = "checksum of the template")
+    private String checksum;
+
+    @SerializedName("sourcetemplateid")
+    @Param(description = "the template ID of the parent template if present")
+    private String sourcetemplateId;
+
+    @SerializedName(ApiConstants.HOST_ID)
+    @Param(description = "the ID of the secondary storage host for the template")
+    private String hostId;
+
+    @SerializedName("hostname")
+    @Param(description = "the name of the secondary storage host for the template")
+    private String hostName;
+
+    @SerializedName(ApiConstants.TEMPLATE_TAG)
+    @Param(description = "the tag of this template")
+    private String templateTag;
+
+    @SerializedName(ApiConstants.PROJECT_ID)
+    @Param(description = "the project id of the template")
+    private String projectId;
+
+    @SerializedName(ApiConstants.PROJECT)
+    @Param(description = "the project name of the template")
+    private String projectName;
+
+    @SerializedName(ApiConstants.DETAILS)
+    @Param(description = "additional key/value details tied with template")
+    private Map details;
+
+    @SerializedName(ApiConstants.BITS)
+    @Param(description = "the processor bit size", since = "4.10")
+    private int bits;
+
+    @SerializedName(ApiConstants.SSHKEY_ENABLED)
+    @Param(description = "true if template is sshkey enabled, false otherwise")
+    private Boolean sshKeyEnabled;
+
+    @SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE)
+    @Param(description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
+    private Boolean isDynamicallyScalable;
+
+    @SerializedName(ApiConstants.DIRECT_DOWNLOAD)
+    @Param(description = "KVM Only: true if template is directly downloaded to Primary Storage bypassing Secondary Storage")
+    private Boolean directDownload;
+
+    @SerializedName("parenttemplateid")
+    @Param(description = "if Datadisk template, then id of the root disk template this template belongs to")
+    private String parentTemplateId;
+
+    @SerializedName("childtemplates")
+    @Param(description = "if root disk template, then ids of the datas disk templates this template owns")
+    private Set<ChildTemplateResponse> childTemplates;
+
+    @SerializedName(ApiConstants.REQUIRES_HVM)
+    @Param(description = "true if template requires HVM enabled, false otherwise")
+    private Boolean requiresHvm;
+
+    public TemplateResponse() {
+        tags = new LinkedHashSet<ResourceTagResponse>();
+    }
+
+    @Override
+    public String getObjectId() {
+        return this.getId();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setZoneId(String zoneId) {
+        this.zoneId = zoneId;
+    }
+
+    public void setZoneName(String zoneName) {
+        this.zoneName = zoneName;
+    }
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    @Override
+    public void setAccountName(String account) {
+        this.account = account;
+    }
+
+    public void setOsTypeId(String osTypeId) {
+        this.osTypeId = osTypeId;
+    }
+
+    public void setOsTypeName(String osTypeName) {
+        this.osTypeName = osTypeName;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    public void setPublic(boolean isPublic) {
+        this.isPublic = isPublic;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public void setReady(boolean isReady) {
+        this.isReady = isReady;
+    }
+
+    public void setPasswordEnabled(boolean passwordEnabled) {
+        this.passwordEnabled = passwordEnabled;
+    }
+
+    public void setFormat(ImageFormat format) {
+        this.format = format;
+    }
+
+    public void setBootable(Boolean bootable) {
+        this.bootable = bootable;
+    }
+
+    public void setFeatured(boolean featured) {
+        this.featured = featured;
+    }
+
+    public void setCrossZones(boolean crossZones) {
+        this.crossZones = crossZones;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public void setSize(Long size) {
+        this.size = size;
+    }
+
+    public void setPhysicalSize(Long physicalSize) {
+        this.physicalSize = physicalSize;
+    }
+
+    public void setTemplateType(String templateType) {
+        this.templateType = templateType;
+    }
+
+    public void setHypervisor(String hypervisor) {
+        this.hypervisor = hypervisor;
+    }
+
+    @Override
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    @Override
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    public void setExtractable(Boolean extractable) {
+        this.extractable = extractable;
+    }
+
+    public void setChecksum(String checksum) {
+        this.checksum = checksum;
+    }
+
+    public void setSourceTemplateId(String sourcetemplateId) {
+        this.sourcetemplateId = sourcetemplateId;
+    }
+
+    public void setHostId(String hostId) {
+        this.hostId = hostId;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public void setTemplateTag(String templateTag) {
+        this.templateTag = templateTag;
+    }
+
+    @Override
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    public Map getDetails() {
+        return this.details;
+    }
+
+    public void setDetails(Map details) {
+        this.details = details;
+    }
+
+    public void setTags(Set<ResourceTagResponse> tags) {
+        this.tags = tags;
+    }
+
+    public void setSshKeyEnabled(boolean sshKeyEnabled) {
+        this.sshKeyEnabled = sshKeyEnabled;
+    }
+
+    public void setDynamicallyScalable(boolean isDynamicallyScalable) {
+        this.isDynamicallyScalable = isDynamicallyScalable;
+    }
+
+    public String getZoneId() {
+        return zoneId;
+    }
+
+    public void setBits(int bits) {
+        this.bits = bits;
+    }
+
+    public void setDirectDownload(Boolean directDownload) {
+        this.directDownload = directDownload;
+    }
+
+    public Boolean getDirectDownload() {
+        return directDownload;
+    }
+
+    public void setParentTemplateId(String parentTemplateId) {
+        this.parentTemplateId = parentTemplateId;
+    }
+
+    public void setChildTemplates(Set<ChildTemplateResponse> childTemplateIds) {
+        this.childTemplates = childTemplateIds;
+    }
+
+    public Boolean isRequiresHvm() {
+        return requiresHvm;
+    }
+
+    public void setRequiresHvm(Boolean requiresHvm) {
+        this.requiresHvm = requiresHvm;
+    }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/TrafficMonitorResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TrafficMonitorResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/TrafficMonitorResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/TrafficMonitorResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/TrafficTypeImplementorResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeImplementorResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/TrafficTypeImplementorResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeImplementorResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/TrafficTypeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/UpgradeRouterTemplateResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UsageRecordResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/UsageRecordResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/UsageTypeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UsageTypeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/UsageTypeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/UsageTypeResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/UserResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UserResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/UserResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/UserResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/UserVmResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VMSnapshotResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VMSnapshotResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VMSnapshotResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VMSnapshotResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VMUserDataResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VMUserDataResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VMUserDataResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VMUserDataResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VgpuResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VgpuResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VgpuResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VgpuResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VirtualRouterProviderResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VlanIpRangeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java
new file mode 100644
index 0000000..d845e41
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java
@@ -0,0 +1,736 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import com.cloud.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 java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+@EntityReference(value = Volume.class)
+@SuppressWarnings("unused")
+public class VolumeResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "ID of the disk volume")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "name of the disk volume")
+    private String name;
+
+    @SerializedName(ApiConstants.ZONE_ID)
+    @Param(description = "ID of the availability zone")
+    private String zoneId;
+
+    @SerializedName(ApiConstants.ZONE_NAME)
+    @Param(description = "name of the availability zone")
+    private String zoneName;
+
+    @SerializedName(ApiConstants.TYPE)
+    @Param(description = "type of the disk volume (ROOT or DATADISK)")
+    private String volumeType;
+
+    @SerializedName(ApiConstants.DEVICE_ID)
+    @Param(description = "the ID of the device on user vm the volume is attahed to. This tag is not returned when the volume is detached.")
+    private Long deviceId;
+
+    @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
+    @Param(description = "id of the virtual machine")
+    private String virtualMachineId;
+
+    @SerializedName("isoid")
+    @Param(description = "the ID of the ISO attached to the virtual machine")
+    private String isoId;
+
+    @SerializedName("isoname")
+    @Param(description = "the name of the ISO attached to the virtual machine")
+    private String isoName;
+
+    @SerializedName("isodisplaytext")
+    @Param(description = "an alternate display text of the ISO attached to the virtual machine")
+    private String isoDisplayText;
+
+    @SerializedName(ApiConstants.TEMPLATE_ID)
+    @Param(description = "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.")
+    private String templateId;
+
+    @SerializedName("templatename")
+    @Param(description = "the name of the template for the virtual machine")
+    private String templateName;
+
+    @SerializedName("templatedisplaytext")
+    @Param(description = " an alternate display text of the template for the virtual machine")
+    private String templateDisplayText;
+
+    @SerializedName("vmname")
+    @Param(description = "name of the virtual machine")
+    private String virtualMachineName;
+
+    @SerializedName("vmdisplayname")
+    @Param(description = "display name of the virtual machine")
+    private String virtualMachineDisplayName;
+
+    @SerializedName("vmstate")
+    @Param(description = "state of the virtual machine")
+    private String virtualMachineState;
+
+    @SerializedName(ApiConstants.PROVISIONINGTYPE)
+    @Param(description = "provisioning type used to create volumes.")
+    private String provisioningType;
+
+    @SerializedName(ApiConstants.SIZE)
+    @Param(description = "size of the disk volume")
+    private Long size;
+
+    @SerializedName(ApiConstants.MIN_IOPS)
+    @Param(description = "min iops of the disk volume")
+    private Long minIops;
+
+    @SerializedName(ApiConstants.MAX_IOPS)
+    @Param(description = "max iops of the disk volume")
+    private Long maxIops;
+
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description = "the date the disk volume was created")
+    private Date created;
+
+    @SerializedName(ApiConstants.STATE)
+    @Param(description = "the state of the disk volume")
+    private String state;
+
+    @SerializedName(ApiConstants.ACCOUNT)
+    @Param(description = "the account associated with the disk volume")
+    private String accountName;
+
+    @SerializedName(ApiConstants.PROJECT_ID)
+    @Param(description = "the project id of the vpn")
+    private String projectId;
+
+    @SerializedName(ApiConstants.PROJECT)
+    @Param(description = "the project name of the vpn")
+    private String projectName;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "the ID of the domain associated with the disk volume")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "the domain associated with the disk volume")
+    private String domainName;
+
+    @SerializedName("storagetype")
+    @Param(description = "shared or local storage")
+    private String storageType;
+
+    @SerializedName("diskBytesReadRate")
+    @Param(description = "bytes read rate of the disk volume")
+    private Long bytesReadRate;
+
+    @SerializedName("diskBytesWriteRate")
+    @Param(description = "bytes write rate of the disk volume")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskIopsReadRate")
+    @Param(description = "io requests read rate of the disk volume")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsWriteRate")
+    @Param(description = "io requests write rate of the disk volume")
+    private Long iopsWriteRate;
+
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "Hypervisor the volume belongs to")
+    private String hypervisor;
+
+    @SerializedName(ApiConstants.DISK_OFFERING_ID)
+    @Param(description = "ID of the disk offering")
+    private String diskOfferingId;
+
+    @SerializedName("diskofferingname")
+    @Param(description = "name of the disk offering")
+    private String diskOfferingName;
+
+    @SerializedName("diskofferingdisplaytext")
+    @Param(description = "the display text of the disk offering")
+    private String diskOfferingDisplayText;
+
+    @SerializedName("storage")
+    @Param(description = "name of the primary storage hosting the disk volume")
+    private String storagePoolName;
+
+    @SerializedName(ApiConstants.SNAPSHOT_ID)
+    @Param(description = "ID of the snapshot from which this volume was created")
+    private String snapshotId;
+
+    @SerializedName("attached")
+    @Param(description = "the date the volume was attached to a VM instance")
+    private Date attached;
+
+    @SerializedName("destroyed")
+    @Param(description = "the boolean state of whether the volume is destroyed or not")
+    private Boolean destroyed;
+
+    @SerializedName(ApiConstants.SERVICE_OFFERING_ID)
+    @Param(description = "ID of the service offering for root disk")
+    private String serviceOfferingId;
+
+    @SerializedName("serviceofferingname")
+    @Param(description = "name of the service offering for root disk")
+    private String serviceOfferingName;
+
+    @SerializedName("serviceofferingdisplaytext")
+    @Param(description = "the display text of the service offering for root disk")
+    private String serviceOfferingDisplayText;
+
+    @SerializedName("isextractable")
+    @Param(description = "true if the volume is extractable, false otherwise")
+    private Boolean extractable;
+
+    @SerializedName(ApiConstants.STATUS)
+    @Param(description = "the status of the volume")
+    private String status;
+
+    @SerializedName(ApiConstants.DISPLAY_VOLUME)
+    @Param(description = "an optional field whether to the display the volume to the end user or not.", authorized = {RoleType.Admin})
+    private Boolean displayVolume;
+
+    @SerializedName(ApiConstants.PATH)
+    @Param(description = "the path of the volume")
+    private String path;
+
+    @SerializedName(ApiConstants.STORAGE_ID)
+    @Param(description = "id of the primary storage hosting the disk volume; returned to admin user only", since = "4.3")
+    private String storagePoolId;
+
+    @SerializedName(ApiConstants.CHAIN_INFO)
+    @Param(description = "the chain info of the volume", since = "4.4")
+    String chainInfo;
+
+    @SerializedName(ApiConstants.SNAPSHOT_QUIESCEVM)
+    @Param(description = "need quiesce vm or not when taking snapshot", since = "4.3")
+    private boolean needQuiescevm;
+
+    @SerializedName(ApiConstants.PHYSICAL_SIZE)
+    @Param(description = "the bytes alloaated")
+    private Long physicalsize;
+
+    @SerializedName(ApiConstants.VIRTUAL_SIZE)
+    @Param(description = "the bytes actually consumed on disk")
+    private Long virtualsize;
+
+    @SerializedName(ApiConstants.UTILIZATION)
+    @Param(description = "the disk utilization")
+    private String utilization;
+
+    @SerializedName(ApiConstants.CLUSTER_ID)
+    @Param(description = "cluster id of the volume")
+    private String clusterid;
+
+    @SerializedName(ApiConstants.CLUSTER_NAME)
+    @Param(description = "cluster name where the volume is allocated")
+    private String clustername;
+
+    @SerializedName(ApiConstants.POD_ID)
+    @Param(description = "pod id of the volume")
+    private String podid;
+
+    @SerializedName(ApiConstants.POD_NAME)
+    @Param(description = "pod name of the volume")
+    private String podname;
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public VolumeResponse() {
+        tags = new LinkedHashSet<ResourceTagResponse>();
+    }
+
+    @Override
+    public String getObjectId() {
+        return this.getId();
+    }
+
+    public Boolean isDestroyed() {
+        return destroyed;
+    }
+
+    public void setDestroyed(Boolean destroyed) {
+        this.destroyed = destroyed;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setZoneId(String zoneId) {
+        this.zoneId = zoneId;
+    }
+
+    public void setZoneName(String zoneName) {
+        this.zoneName = zoneName;
+    }
+
+    public void setVolumeType(String volumeType) {
+        this.volumeType = volumeType;
+    }
+
+    public void setDeviceId(Long deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public void setVirtualMachineId(String virtualMachineId) {
+        this.virtualMachineId = virtualMachineId;
+    }
+
+    public void setVirtualMachineName(String virtualMachineName) {
+        this.virtualMachineName = virtualMachineName;
+    }
+
+    public void setVirtualMachineDisplayName(String virtualMachineDisplayName) {
+        this.virtualMachineDisplayName = virtualMachineDisplayName;
+    }
+
+    public void setVirtualMachineState(String virtualMachineState) {
+        this.virtualMachineState = virtualMachineState;
+    }
+
+    public void setProvisioningType(String provisioningType) {
+        this.provisioningType = provisioningType;
+    }
+
+    public void setSize(Long size) {
+        this.size = size;
+    }
+
+    public void setMinIops(Long minIops) {
+        this.minIops = minIops;
+    }
+
+    public void setMaxIops(Long maxIops) {
+        this.maxIops = maxIops;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    @Override
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    @Override
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    public void setStorageType(String storageType) {
+        this.storageType = storageType;
+    }
+
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public void setHypervisor(String hypervisor) {
+        this.hypervisor = hypervisor;
+    }
+
+    public void setDiskOfferingId(String diskOfferingId) {
+        this.diskOfferingId = diskOfferingId;
+    }
+
+    public void setDiskOfferingName(String diskOfferingName) {
+        this.diskOfferingName = diskOfferingName;
+    }
+
+    public void setDiskOfferingDisplayText(String diskOfferingDisplayText) {
+        this.diskOfferingDisplayText = diskOfferingDisplayText;
+    }
+
+    public void setStoragePoolName(String storagePoolName) {
+        this.storagePoolName = storagePoolName;
+    }
+
+    public void setSnapshotId(String snapshotId) {
+        this.snapshotId = snapshotId;
+    }
+
+    public void setAttached(Date attached) {
+        this.attached = attached;
+    }
+
+    public void setServiceOfferingId(String serviceOfferingId) {
+        this.serviceOfferingId = serviceOfferingId;
+    }
+
+    public void setServiceOfferingName(String serviceOfferingName) {
+        this.serviceOfferingName = serviceOfferingName;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public void setServiceOfferingDisplayText(String serviceOfferingDisplayText) {
+        this.serviceOfferingDisplayText = serviceOfferingDisplayText;
+    }
+
+    public void setExtractable(Boolean extractable) {
+        this.extractable = extractable;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    @Override
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    public void setDisplayVolume(Boolean displayVm) {
+        this.displayVolume = displayVm;
+    }
+
+    public void setStoragePoolId(String storagePoolId) {
+        this.storagePoolId = storagePoolId;
+    }
+
+    public String getChainInfo() {
+        return chainInfo;
+    }
+
+    public void setChainInfo(String chainInfo) {
+        this.chainInfo = chainInfo;
+    }
+
+    public String getStoragePoolId() {
+        return storagePoolId;
+    }
+
+    public void setNeedQuiescevm(boolean quiescevm) {
+        this.needQuiescevm = quiescevm;
+    }
+
+    public boolean isNeedQuiescevm() {
+        return this.needQuiescevm;
+    }
+
+    public String getIsoId() {
+        return isoId;
+    }
+
+    public void setIsoId(String isoId) {
+        this.isoId = isoId;
+    }
+
+    public String getIsoName() {
+        return isoName;
+    }
+
+    public void setIsoName(String isoName) {
+        this.isoName = isoName;
+    }
+
+    public String getIsoDisplayText() {
+        return isoDisplayText;
+    }
+
+    public void setIsoDisplayText(String isoDisplayText) {
+        this.isoDisplayText = isoDisplayText;
+    }
+
+    public String getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(String templateId) {
+        this.templateId = templateId;
+    }
+
+    public String getTemplateName() {
+        return templateName;
+    }
+
+    public void setTemplateName(String templateName) {
+        this.templateName = templateName;
+    }
+
+    public String getTemplateDisplayText() {
+        return templateDisplayText;
+    }
+
+    public void setTemplateDisplayText(String templateDisplayText) {
+        this.templateDisplayText = templateDisplayText;
+    }
+
+    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;
+    }
+
+    public Long getPhysicalsize() {
+        return physicalsize;
+    }
+
+    public void setPhysicalsize(Long physicalsize) {
+        this.physicalsize = physicalsize;
+    }
+
+    public Long getVirtualsize() {
+        return virtualsize;
+    }
+
+    public void setVirtualsize(Long virtualsize) {
+        this.virtualsize = virtualsize;
+    }
+
+    public String getUtilization() {
+        return utilization;
+    }
+
+    public void setUtilization(String utilization) {
+        this.utilization = utilization;
+    }
+
+    public String getClusterId() {
+        return clusterid;
+    }
+
+    public void setClusterId(String clusterid) {
+        this.clusterid = clusterid;
+    }
+
+    public String getClusterName() {
+        return clustername;
+    }
+
+    public void setClusterName(String clustername) {
+        this.clustername = clustername;
+    }
+
+    public String getPodId() {
+        return podid;
+    }
+
+    public void setPodId(String podid) {
+        this.podid = podid;
+    }
+
+    public String getPodName() {
+        return podname;
+    }
+
+    public void setPodName(String podname) {
+        this.podname = podname;
+    }
+
+}
diff --git a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VpcResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VpcResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VpcResponse.java
diff --git a/api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VpnUsersResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/api/response/VpnUsersResponse.java
rename to api/src/main/java/org/apache/cloudstack/api/response/VpnUsersResponse.java
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
new file mode 100644
index 0000000..efd3b79
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -0,0 +1,318 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@SuppressWarnings("unused")
+@EntityReference(value = DataCenter.class)
+public class ZoneResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "Zone id")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "Zone name")
+    private String name;
+
+    @SerializedName(ApiConstants.DESCRIPTION)
+    @Param(description = "Zone description")
+    private String description;
+
+    @SerializedName(ApiConstants.DNS1)
+    @Param(description = "the first DNS for the Zone")
+    private String dns1;
+
+    @SerializedName(ApiConstants.DNS2)
+    @Param(description = "the second DNS for the Zone")
+    private String dns2;
+
+    @SerializedName(ApiConstants.IP6_DNS1)
+    @Param(description = "the first IPv6 DNS for the Zone")
+    private String ip6Dns1;
+
+    @SerializedName(ApiConstants.IP6_DNS2)
+    @Param(description = "the second IPv6 DNS for the Zone")
+    private String ip6Dns2;
+
+    @SerializedName(ApiConstants.INTERNAL_DNS1)
+    @Param(description = "the first internal DNS for the Zone")
+    private String internalDns1;
+
+    @SerializedName(ApiConstants.INTERNAL_DNS2)
+    @Param(description = "the second internal DNS for the Zone")
+    private String internalDns2;
+
+    @SerializedName(ApiConstants.GUEST_CIDR_ADDRESS)
+    @Param(description = "the guest CIDR address for the Zone")
+    private String guestCidrAddress;
+
+    @SerializedName(ApiConstants.DISPLAY_TEXT)
+    @Param(description = "the display text of the zone")
+    private String displayText;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "Network domain name for the networks in the zone")
+    private String domain;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "the UUID of the containing domain, null for public zones")
+    private String domainId;
+
+    @SerializedName("domainname")
+    @Param(description = "the name of the containing domain, null for public zones")
+    private String domainName;
+
+    @SerializedName(ApiConstants.NETWORK_TYPE)
+    @Param(description = "the network type of the zone; can be Basic or Advanced")
+    private String networkType;
+
+    @SerializedName("securitygroupsenabled")
+    @Param(description = "true if security groups support is enabled, false otherwise")
+    private boolean securityGroupsEnabled;
+
+    @SerializedName("allocationstate")
+    @Param(description = "the allocation state of the cluster")
+    private String allocationState;
+
+    @SerializedName(ApiConstants.ZONE_TOKEN)
+    @Param(description = "Zone Token")
+    private String zoneToken;
+
+    @SerializedName(ApiConstants.DHCP_PROVIDER)
+    @Param(description = "the dhcp Provider for the Zone")
+    private String dhcpProvider;
+
+    @SerializedName("capacity")
+    @Param(description = "the capacity of the Zone", responseObject = CapacityResponse.class)
+    private List<CapacityResponse> capacitites;
+
+    @SerializedName(ApiConstants.LOCAL_STORAGE_ENABLED)
+    @Param(description = "true if local storage offering enabled, false otherwise")
+    private boolean localStorageEnabled;
+
+    @SerializedName(ApiConstants.TAGS)
+    @Param(description = "the list of resource tags associated with zone.", responseObject = ResourceTagResponse.class, since = "4.3")
+    private Set<ResourceTagResponse> tags;
+
+    @SerializedName(ApiConstants.RESOURCE_DETAILS)
+    @Param(description = "Meta data associated with the zone (key/value pairs)", since = "4.3.0")
+    private Map<String, String> resourceDetails;
+
+    public ZoneResponse() {
+        tags = new LinkedHashSet<ResourceTagResponse>();
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setDns1(String dns1) {
+        this.dns1 = dns1;
+    }
+
+    public void setDns2(String dns2) {
+        this.dns2 = dns2;
+    }
+
+    public void setInternalDns1(String internalDns1) {
+        this.internalDns1 = internalDns1;
+    }
+
+    public void setInternalDns2(String internalDns2) {
+        this.internalDns2 = internalDns2;
+    }
+
+    public void setGuestCidrAddress(String guestCidrAddress) {
+        this.guestCidrAddress = guestCidrAddress;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    public void setType(String networkType) {
+        this.networkType = networkType;
+    }
+
+    public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
+        this.securityGroupsEnabled = securityGroupsEnabled;
+    }
+
+    public void setAllocationState(String allocationState) {
+        this.allocationState = allocationState;
+    }
+
+    public void setZoneToken(String zoneToken) {
+        this.zoneToken = zoneToken;
+    }
+
+    public void setDhcpProvider(String dhcpProvider) {
+        this.dhcpProvider = dhcpProvider;
+    }
+
+    public void setCapacitites(List<CapacityResponse> capacitites) {
+        this.capacitites = capacitites;
+    }
+
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    public void setLocalStorageEnabled(boolean localStorageEnabled) {
+        this.localStorageEnabled = localStorageEnabled;
+    }
+
+    public String getIp6Dns1() {
+        return ip6Dns1;
+    }
+
+    public void setIp6Dns1(String ip6Dns1) {
+        this.ip6Dns1 = ip6Dns1;
+    }
+
+    public String getIp6Dns2() {
+        return ip6Dns2;
+    }
+
+    public void setIp6Dns2(String ip6Dns2) {
+        this.ip6Dns2 = ip6Dns2;
+    }
+
+    public void addTag(ResourceTagResponse tag) {
+        this.tags.add(tag);
+    }
+
+    public void setResourceDetails(Map<String, String> details) {
+        if (details == null) {
+            return;
+        }
+        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 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/api/src/org/apache/cloudstack/ca/CAManager.java b/api/src/main/java/org/apache/cloudstack/ca/CAManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/ca/CAManager.java
rename to api/src/main/java/org/apache/cloudstack/ca/CAManager.java
diff --git a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java
similarity index 100%
rename from api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java
rename to api/src/main/java/org/apache/cloudstack/config/ApiServiceConfiguration.java
diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/main/java/org/apache/cloudstack/context/CallContext.java
similarity index 100%
rename from api/src/org/apache/cloudstack/context/CallContext.java
rename to api/src/main/java/org/apache/cloudstack/context/CallContext.java
diff --git a/api/src/org/apache/cloudstack/context/CallContextListener.java b/api/src/main/java/org/apache/cloudstack/context/CallContextListener.java
similarity index 100%
rename from api/src/org/apache/cloudstack/context/CallContextListener.java
rename to api/src/main/java/org/apache/cloudstack/context/CallContextListener.java
diff --git a/api/src/org/apache/cloudstack/context/LogContext.java b/api/src/main/java/org/apache/cloudstack/context/LogContext.java
similarity index 100%
rename from api/src/org/apache/cloudstack/context/LogContext.java
rename to api/src/main/java/org/apache/cloudstack/context/LogContext.java
diff --git a/api/src/org/apache/cloudstack/context/LogContextListener.java b/api/src/main/java/org/apache/cloudstack/context/LogContextListener.java
similarity index 100%
rename from api/src/org/apache/cloudstack/context/LogContextListener.java
rename to api/src/main/java/org/apache/cloudstack/context/LogContextListener.java
diff --git a/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsService.java b/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsService.java
new file mode 100644
index 0000000..a9177af
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsService.java
@@ -0,0 +1,29 @@
+//
+// 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.diagnostics;
+
+import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd;
+
+import java.util.Map;
+
+public interface DiagnosticsService {
+
+    Map<String, String> runDiagnosticsCommand(RunDiagnosticsCmd cmd);
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsType.java b/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsType.java
new file mode 100644
index 0000000..0e3a1da
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsType.java
@@ -0,0 +1,42 @@
+//
+// 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.diagnostics;
+
+public enum DiagnosticsType {
+    PING("ping"), TRACEROUTE("traceroute"), ARPING("arping");
+
+    private String value;
+
+    DiagnosticsType(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public static DiagnosticsType getCommand(String cmd) {
+        for (DiagnosticsType type : DiagnosticsType.values()) {
+            if (type.value.equalsIgnoreCase(cmd)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java b/api/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/direct/download/DirectDownloadManager.java
rename to api/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManager.java
diff --git a/api/src/org/apache/cloudstack/ha/HAConfig.java b/api/src/main/java/org/apache/cloudstack/ha/HAConfig.java
similarity index 100%
rename from api/src/org/apache/cloudstack/ha/HAConfig.java
rename to api/src/main/java/org/apache/cloudstack/ha/HAConfig.java
diff --git a/api/src/org/apache/cloudstack/ha/HAConfigManager.java b/api/src/main/java/org/apache/cloudstack/ha/HAConfigManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/ha/HAConfigManager.java
rename to api/src/main/java/org/apache/cloudstack/ha/HAConfigManager.java
diff --git a/api/src/org/apache/cloudstack/ha/HAResource.java b/api/src/main/java/org/apache/cloudstack/ha/HAResource.java
similarity index 100%
rename from api/src/org/apache/cloudstack/ha/HAResource.java
rename to api/src/main/java/org/apache/cloudstack/ha/HAResource.java
diff --git a/api/src/main/java/org/apache/cloudstack/jobs/JobInfo.java b/api/src/main/java/org/apache/cloudstack/jobs/JobInfo.java
new file mode 100644
index 0000000..5b63e62
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/jobs/JobInfo.java
@@ -0,0 +1,80 @@
+// 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.jobs;
+
+import java.util.Date;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+public interface JobInfo extends Identity, InternalIdentity {
+    public enum Status {
+        IN_PROGRESS(false), SUCCEEDED(true), FAILED(true), CANCELLED(true);
+
+        private final boolean done;
+
+        private Status(boolean done) {
+            this.done = done;
+        }
+
+        public boolean done() {
+            return done;
+        }
+    }
+
+    String getType();
+
+    String getDispatcher();
+
+    int getPendingSignals();
+
+    long getUserId();
+
+    long getAccountId();
+
+    String getCmd();
+
+    int getCmdVersion();
+
+    String getCmdInfo();
+
+    Status getStatus();
+
+    int getProcessStatus();
+
+    int getResultCode();
+
+    String getResult();
+
+    Long getInitMsid();
+
+    Long getExecutingMsid();
+
+    Long getCompleteMsid();
+
+    Date getCreated();
+
+    Date getRemoved();
+
+    Date getLastUpdated();
+
+    Date getLastPolled();
+
+    String getInstanceType();
+
+    Long getInstanceId();
+}
diff --git a/api/src/org/apache/cloudstack/kernel/Partition.java b/api/src/main/java/org/apache/cloudstack/kernel/Partition.java
similarity index 100%
rename from api/src/org/apache/cloudstack/kernel/Partition.java
rename to api/src/main/java/org/apache/cloudstack/kernel/Partition.java
diff --git a/api/src/main/java/org/apache/cloudstack/management/ManagementServerHost.java b/api/src/main/java/org/apache/cloudstack/management/ManagementServerHost.java
new file mode 100644
index 0000000..11e1cae
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/management/ManagementServerHost.java
@@ -0,0 +1,37 @@
+// 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.management;
+
+public interface ManagementServerHost {
+    enum State {
+        Up, Down
+    }
+
+    long getId();
+
+    String getUuid();
+
+    long getMsid();
+
+    State getState();
+
+    String getName();
+
+    String getVersion();
+
+    String getServiceIP();
+}
diff --git a/api/src/main/java/org/apache/cloudstack/management/ManagementServerHostPeer.java b/api/src/main/java/org/apache/cloudstack/management/ManagementServerHostPeer.java
new file mode 100644
index 0000000..d41d1b7
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/management/ManagementServerHostPeer.java
@@ -0,0 +1,30 @@
+// 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.management;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+import java.util.Date;
+
+public interface ManagementServerHostPeer extends InternalIdentity {
+
+    long getOwnerMshost();
+    long getPeerMshost();
+    long getPeerRunid();
+    ManagementServerHost.State getPeerState();
+    Date getLastUpdateTime();
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java b/api/src/main/java/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java
rename to api/src/main/java/org/apache/cloudstack/network/ExternalNetworkDeviceManager.java
diff --git a/api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java b/api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java
rename to api/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElementService.java
diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java b/api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java
rename to api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerContainer.java
diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java b/api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java
rename to api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerRule.java
diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java b/api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
rename to api/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
diff --git a/api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java b/api/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java
rename to api/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMService.java
diff --git a/api/src/org/apache/cloudstack/network/tls/CertService.java b/api/src/main/java/org/apache/cloudstack/network/tls/CertService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/tls/CertService.java
rename to api/src/main/java/org/apache/cloudstack/network/tls/CertService.java
diff --git a/api/src/org/apache/cloudstack/network/tls/SslCert.java b/api/src/main/java/org/apache/cloudstack/network/tls/SslCert.java
similarity index 100%
rename from api/src/org/apache/cloudstack/network/tls/SslCert.java
rename to api/src/main/java/org/apache/cloudstack/network/tls/SslCert.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagement.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagement.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagement.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagement.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementDriver.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementDriver.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementDriver.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementDriver.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementService.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementService.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementService.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverChangePasswordCommand.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverChangePasswordCommand.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverChangePasswordCommand.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverChangePasswordCommand.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverCommand.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverCommand.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverCommand.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverCommand.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverPowerCommand.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverPowerCommand.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverPowerCommand.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverPowerCommand.java
diff --git a/api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverResponse.java b/api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverResponse.java
similarity index 100%
rename from api/src/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverResponse.java
rename to api/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/OutOfBandManagementDriverResponse.java
diff --git a/api/src/org/apache/cloudstack/poll/BackgroundPollManager.java b/api/src/main/java/org/apache/cloudstack/poll/BackgroundPollManager.java
similarity index 100%
rename from api/src/org/apache/cloudstack/poll/BackgroundPollManager.java
rename to api/src/main/java/org/apache/cloudstack/poll/BackgroundPollManager.java
diff --git a/api/src/org/apache/cloudstack/poll/BackgroundPollTask.java b/api/src/main/java/org/apache/cloudstack/poll/BackgroundPollTask.java
similarity index 100%
rename from api/src/org/apache/cloudstack/poll/BackgroundPollTask.java
rename to api/src/main/java/org/apache/cloudstack/poll/BackgroundPollTask.java
diff --git a/api/src/main/java/org/apache/cloudstack/query/QueryService.java b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
new file mode 100644
index 0000000..ac29dff
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
@@ -0,0 +1,148 @@
+// 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.query;
+
+import java.util.List;
+
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
+import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
+import org.apache.cloudstack.api.command.admin.management.ListMgmtsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
+import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
+import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
+import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.EventResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import org.apache.cloudstack.api.response.ProjectInvitationResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ResourceDetailResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.StorageTagResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+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.framework.config.ConfigKey;
+
+import com.cloud.exception.PermissionDeniedException;
+
+/**
+ * Service used for list api query.
+ *
+ */
+public interface QueryService {
+
+    // Config keys
+    static final ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
+            "Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
+
+    ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
+
+    ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd);
+
+    ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd);
+
+    ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd);
+
+    ListResponse<UserVmResponse> searchForUserVMs(ListVMsCmd cmd);
+
+    ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd);
+
+    ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd);
+
+    ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd);
+
+    ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd);
+
+    ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd);
+
+    ListResponse<HostResponse> searchForServers(ListHostsCmd cmd);
+
+    ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd);
+
+    ListResponse<StoragePoolResponse> searchForStoragePools(ListStoragePoolsCmd cmd);
+
+    ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd);
+
+    ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd);
+
+    ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd);
+
+    ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd);
+
+    ListResponse<AsyncJobResponse>  searchForAsyncJobs(ListAsyncJobsCmd cmd);
+
+    ListResponse<DiskOfferingResponse>  searchForDiskOfferings(ListDiskOfferingsCmd cmd);
+
+    ListResponse<ServiceOfferingResponse>  searchForServiceOfferings(ListServiceOfferingsCmd cmd);
+
+    ListResponse<ZoneResponse>  listDataCenters(ListZonesCmd cmd);
+
+    ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd);
+
+    ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd);
+
+    ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd);
+
+    List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd);
+
+    ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd);
+
+    ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
+
+    ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd);
+
+    ListResponse<ManagementServerResponse> listManagementServers(ListMgmtsCmd cmd);
+}
diff --git a/api/src/org/apache/cloudstack/region/PortableIp.java b/api/src/main/java/org/apache/cloudstack/region/PortableIp.java
similarity index 100%
rename from api/src/org/apache/cloudstack/region/PortableIp.java
rename to api/src/main/java/org/apache/cloudstack/region/PortableIp.java
diff --git a/api/src/org/apache/cloudstack/region/PortableIpRange.java b/api/src/main/java/org/apache/cloudstack/region/PortableIpRange.java
similarity index 100%
rename from api/src/org/apache/cloudstack/region/PortableIpRange.java
rename to api/src/main/java/org/apache/cloudstack/region/PortableIpRange.java
diff --git a/api/src/org/apache/cloudstack/region/Region.java b/api/src/main/java/org/apache/cloudstack/region/Region.java
similarity index 100%
rename from api/src/org/apache/cloudstack/region/Region.java
rename to api/src/main/java/org/apache/cloudstack/region/Region.java
diff --git a/api/src/org/apache/cloudstack/region/RegionService.java b/api/src/main/java/org/apache/cloudstack/region/RegionService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/region/RegionService.java
rename to api/src/main/java/org/apache/cloudstack/region/RegionService.java
diff --git a/api/src/org/apache/cloudstack/region/RegionSync.java b/api/src/main/java/org/apache/cloudstack/region/RegionSync.java
similarity index 100%
rename from api/src/org/apache/cloudstack/region/RegionSync.java
rename to api/src/main/java/org/apache/cloudstack/region/RegionSync.java
diff --git a/api/src/org/apache/cloudstack/usage/Usage.java b/api/src/main/java/org/apache/cloudstack/usage/Usage.java
similarity index 100%
rename from api/src/org/apache/cloudstack/usage/Usage.java
rename to api/src/main/java/org/apache/cloudstack/usage/Usage.java
diff --git a/api/src/org/apache/cloudstack/usage/UsageService.java b/api/src/main/java/org/apache/cloudstack/usage/UsageService.java
similarity index 100%
rename from api/src/org/apache/cloudstack/usage/UsageService.java
rename to api/src/main/java/org/apache/cloudstack/usage/UsageService.java
diff --git a/api/src/org/apache/cloudstack/usage/UsageTypes.java b/api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java
similarity index 100%
rename from api/src/org/apache/cloudstack/usage/UsageTypes.java
rename to api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java
diff --git a/api/resources/META-INF/cloudstack/api-config/module.properties b/api/src/main/resources/META-INF/cloudstack/api-config/module.properties
similarity index 100%
rename from api/resources/META-INF/cloudstack/api-config/module.properties
rename to api/src/main/resources/META-INF/cloudstack/api-config/module.properties
diff --git a/api/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml b/api/src/main/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml
similarity index 100%
rename from api/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml
rename to api/src/main/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml
diff --git a/api/resources/META-INF/cloudstack/api-planner/module.properties b/api/src/main/resources/META-INF/cloudstack/api-planner/module.properties
similarity index 100%
rename from api/resources/META-INF/cloudstack/api-planner/module.properties
rename to api/src/main/resources/META-INF/cloudstack/api-planner/module.properties
diff --git a/api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml b/api/src/main/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml
similarity index 100%
rename from api/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml
rename to api/src/main/resources/META-INF/cloudstack/api-planner/spring-api-planner-context.xml
diff --git a/api/src/org/apache/cloudstack/api/ApiCommandJobType.java b/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
deleted file mode 100644
index ead6ce1..0000000
--- a/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-public enum ApiCommandJobType {
-    None,
-    VirtualMachine,
-    DomainRouter,
-    Volume,
-    ConsoleProxy,
-    Snapshot,
-    Template,
-    Iso,
-    SystemVm,
-    Host,
-    StoragePool,
-    ImageStore,
-    IpAddress,
-    PortableIpAddress,
-    SecurityGroup,
-    PhysicalNetwork,
-    TrafficType,
-    PhysicalNetworkServiceProvider,
-    FirewallRule,
-    Account,
-    User,
-    PrivateGateway,
-    StaticRoute,
-    Counter,
-    Condition,
-    AutoScalePolicy,
-    AutoScaleVmProfile,
-    AutoScaleVmGroup,
-    GlobalLoadBalancerRule,
-    LoadBalancerRule,
-    AffinityGroup,
-    InternalLbVm,
-    DedicatedGuestVlanRange,
-    IAMPolicy,
-    IAMGroup,
-    GuestOs,
-    GuestOsMapping,
-    Network
-}
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
deleted file mode 100644
index 03ee7fc..0000000
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ /dev/null
@@ -1,730 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-public class ApiConstants {
-    public static final String ACCOUNT = "account";
-    public static final String ACCOUNTS = "accounts";
-    public static final String ACCOUNT_TYPE = "accounttype";
-    public static final String ACCOUNT_ID = "accountid";
-    public static final String ACTIVITY = "activity";
-    public static final String ADDRESS = "address";
-    public static final String ALGORITHM = "algorithm";
-    public static final String ALLOCATED_ONLY = "allocatedonly";
-    public static final String ANNOTATION = "annotation";
-    public static final String API_KEY = "apikey";
-    public static final String ASYNC_BACKUP = "asyncbackup";
-    public static final String USER_API_KEY = "userapikey";
-    public static final String APPLIED = "applied";
-    public static final String LIST_LB_VMIPS = "lbvmips";
-    public static final String AVAILABLE = "available";
-    public static final String BITS = "bits";
-    public static final String BOOTABLE = "bootable";
-    public static final String BIND_DN = "binddn";
-    public static final String BIND_PASSWORD = "bindpass";
-    public static final String BYTES_READ_RATE = "bytesreadrate";
-    public static final String BYTES_WRITE_RATE = "byteswriterate";
-    public static final String BYPASS_VLAN_OVERLAP_CHECK = "bypassvlanoverlapcheck";
-    public static final String CATEGORY = "category";
-    public static final String CAN_REVERT = "canrevert";
-    public static final String CA_CERTIFICATES = "cacertificates";
-    public static final String CERTIFICATE = "certificate";
-    public static final String CERTIFICATE_CHAIN = "certchain";
-    public static final String CERTIFICATE_FINGERPRINT = "fingerprint";
-    public static final String CERTIFICATE_ID = "certid";
-    public static final String CSR = "csr";
-    public static final String PRIVATE_KEY = "privatekey";
-    public static final String DOMAIN_SUFFIX = "domainsuffix";
-    public static final String DNS_SEARCH_ORDER = "dnssearchorder";
-    public static final String CHAIN_INFO = "chaininfo";
-    public static final String CIDR = "cidr";
-    public static final String IP6_CIDR = "ip6cidr";
-    public static final String CIDR_LIST = "cidrlist";
-    public static final String DEST_CIDR_LIST = "destcidrlist";
-    public static final String CLEANUP = "cleanup";
-    public static final String MAKEREDUNDANT = "makeredundant";
-    public static final String CLUSTER_ID = "clusterid";
-    public static final String CLUSTER_NAME = "clustername";
-    public static final String CLUSTER_TYPE = "clustertype";
-    public static final String CN = "cn";
-    public static final String COMMAND = "command";
-    public static final String CMD_EVENT_TYPE = "cmdeventtype";
-    public static final String COMPONENT = "component";
-    public static final String CPU_NUMBER = "cpunumber";
-    public static final String CPU_SPEED = "cpuspeed";
-    public static final String CREATED = "created";
-    public static final String CTX_ACCOUNT_ID = "ctxaccountid";
-    public static final String CTX_DETAILS = "ctxDetails";
-    public static final String CTX_USER_ID = "ctxuserid";
-    public static final String CTXSTARTEVENTID = "ctxstarteventid";
-    public static final String CTX_START_EVENT_ID = "ctxStartEventId";
-    public static final String CUSTOMIZED = "customized";
-    public static final String CUSTOMIZED_IOPS = "customizediops";
-    public static final String CUSTOM_ID = "customid";
-    public static final String CUSTOM_JOB_ID = "customjobid";
-    public static final String MIN_IOPS = "miniops";
-    public static final String MAX_IOPS = "maxiops";
-    public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
-    public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
-    public static final String DESCRIPTION = "description";
-    public static final String DESTINATION_ZONE_ID = "destzoneid";
-    public static final String DETAILS = "details";
-    public static final String DEVICE_ID = "deviceid";
-    public static final String DIRECT_DOWNLOAD = "directdownload";
-    public static final String DISK_OFFERING_ID = "diskofferingid";
-    public static final String DISK_SIZE = "disksize";
-    public static final String UTILIZATION = "utilization";
-    public static final String DRIVER = "driver";
-    public static final String ROOT_DISK_SIZE = "rootdisksize";
-    public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
-    public static final String DHCP_OPTIONS = "dhcpoptions";
-    public static final String DHCP_PREFIX = "dhcp:";
-    public static final String DISPLAY_NAME = "displayname";
-    public static final String DISPLAY_NETWORK = "displaynetwork";
-    public static final String DISPLAY_NIC = "displaynic";
-    public static final String DISPLAY_TEXT = "displaytext";
-    public static final String DISPLAY_VM = "displayvm";
-    public static final String DISPLAY_OFFERING = "displayoffering";
-    public static final String DISPLAY_VOLUME = "displayvolume";
-    public static final String DNS1 = "dns1";
-    public static final String DNS2 = "dns2";
-    public static final String IP6_DNS1 = "ip6dns1";
-    public static final String IP6_DNS2 = "ip6dns2";
-    public static final String DOMAIN = "domain";
-    public static final String DOMAIN_ID = "domainid";
-    public static final String DOMAIN__ID = "domainId";
-    public static final String DURATION = "duration";
-    public static final String ELIGIBLE = "eligible";
-    public static final String EMAIL = "email";
-    public static final String END_DATE = "enddate";
-    public static final String END_IP = "endip";
-    public static final String END_IPV6 = "endipv6";
-    public static final String END_PORT = "endport";
-    public static final String ENTRY_TIME = "entrytime";
-    public static final String EXPIRES = "expires";
-    public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
-    public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
-    public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
-    public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
-    public static final String FENCE = "fence";
-    public static final String FETCH_LATEST = "fetchlatest";
-    public static final String FIRSTNAME = "firstname";
-    public static final String FORCED = "forced";
-    public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
-    public static final String FORMAT = "format";
-    public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
-    public static final String FOR_SYSTEM_VMS = "forsystemvms";
-    public static final String GATEWAY = "gateway";
-    public static final String IP6_GATEWAY = "ip6gateway";
-    public static final String GROUP = "group";
-    public static final String GROUP_ID = "groupid";
-    public static final String GSLB_LB_METHOD = "gslblbmethod";
-    public static final String GSLB_SERVICE_DOMAIN_NAME = "gslbdomainname";
-    public static final String GSLB_SERVICE_TYPE = "gslbservicetype";
-    public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname";
-    public static final String GSLB_LBRULE_WEIGHT_MAP = "gslblbruleweightsmap";
-    public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
-    public static final String GUEST_VLAN_RANGE = "guestvlanrange";
-    public static final String HA_ENABLE = "haenable";
-    public static final String HA_PROVIDER = "haprovider";
-    public static final String HA_STATE = "hastate";
-    public static final String HEALTH = "health";
-    public static final String HOST_ID = "hostid";
-    public static final String HOST_NAME = "hostname";
-    public static final String HYPERVISOR = "hypervisor";
-    public static final String INLINE = "inline";
-    public static final String INSTANCE = "instance";
-    public static final String ICMP_CODE = "icmpcode";
-    public static final String ICMP_TYPE = "icmptype";
-    public static final String ID = "id";
-    public static final String IDS = "ids";
-    public static final String INTERNAL_DNS1 = "internaldns1";
-    public static final String INTERNAL_DNS2 = "internaldns2";
-    public static final String INTERVAL_TYPE = "intervaltype";
-    public static final String LOCATION_TYPE = "locationtype";
-    public static final String IOPS_READ_RATE = "iopsreadrate";
-    public static final String IOPS_WRITE_RATE = "iopswriterate";
-    public static final String IP_ADDRESS = "ipaddress";
-    public static final String IP6_ADDRESS = "ip6address";
-    public static final String IP_ADDRESS_ID = "ipaddressid";
-    public static final String IS_ASYNC = "isasync";
-    public static final String IP_AVAILABLE = "ipavailable";
-    public static final String IP_LIMIT = "iplimit";
-    public static final String IP_TOTAL = "iptotal";
-    public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
-    public static final String IS_EXTRACTABLE = "isextractable";
-    public static final String IS_FEATURED = "isfeatured";
-    public static final String IS_PORTABLE = "isportable";
-    public static final String IS_PUBLIC = "ispublic";
-    public static final String IS_PERSISTENT = "ispersistent";
-    public static final String EGRESS_DEFAULT_POLICY = "egressdefaultpolicy";
-    public static final String IS_READY = "isready";
-    public static final String IS_RECURSIVE = "isrecursive";
-    public static final String ISO_FILTER = "isofilter";
-    public static final String ISO_GUEST_OS_NONE = "None";
-    public static final String JOB_ID = "jobid";
-    public static final String JOB_STATUS = "jobstatus";
-    public static final String LASTNAME = "lastname";
-    public static final String LEVEL = "level";
-    public static final String LENGTH = "length";
-    public static final String LIMIT_CPU_USE = "limitcpuuse";
-    public static final String LOCK = "lock";
-    public static final String LUN = "lun";
-    public static final String LBID = "lbruleid";
-    public static final String MAX = "max";
-    public static final String MAC_ADDRESS = "macaddress";
-    public static final String MAX_SNAPS = "maxsnaps";
-    public static final String MEMORY = "memory";
-    public static final String MODE = "mode";
-    public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
-    public static final String NAME = "name";
-    public static final String METHOD_NAME = "methodname";
-    public static final String NETWORK_DOMAIN = "networkdomain";
-    public static final String NETMASK = "netmask";
-    public static final String NEW_NAME = "newname";
-    public static final String NUM_RETRIES = "numretries";
-    public static final String OFFER_HA = "offerha";
-    public static final String IS_SYSTEM_OFFERING = "issystem";
-    public static final String IS_DEFAULT_USE = "defaultuse";
-    public static final String OP = "op";
-    public static final String OS_CATEGORY_ID = "oscategoryid";
-    public static final String OS_TYPE_ID = "ostypeid";
-    public static final String OS_DISPLAY_NAME = "osdisplayname";
-    public static final String OS_NAME_FOR_HYPERVISOR = "osnameforhypervisor";
-    public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
-    public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
-    public static final String PARAMS = "params";
-    public static final String PARENT_ID = "parentid";
-    public static final String PARENT_DOMAIN_ID = "parentdomainid";
-    public static final String PARENT_TEMPLATE_ID = "parenttemplateid";
-    public static final String PASSWORD = "password";
-    public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
-    public static final String NEW_PASSWORD = "new_password";
-    public static final String PASSWORD_ENABLED = "passwordenabled";
-    public static final String SSHKEY_ENABLED = "sshkeyenabled";
-    public static final String PATH = "path";
-    public static final String POD_ID = "podid";
-    public static final String POD_NAME = "podname";
-    public static final String POD_IDS = "podids";
-    public static final String POLICY_ID = "policyid";
-    public static final String PORT = "port";
-    public static final String PORTAL = "portal";
-    public static final String PORTABLE_IP_ADDRESS = "portableipaddress";
-    public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid";
-    public static final String POST_URL = "postURL";
-    public static final String POWER_STATE = "powerstate";
-    public static final String PRIVATE_INTERFACE = "privateinterface";
-    public static final String PRIVATE_IP = "privateip";
-    public static final String PRIVATE_PORT = "privateport";
-    public static final String PRIVATE_START_PORT = "privateport";
-    public static final String PRIVATE_END_PORT = "privateendport";
-    public static final String PRIVATE_ZONE = "privatezone";
-    public static final String PROTOCOL = "protocol";
-    public static final String PROVISIONINGTYPE = "provisioningtype";
-    public static final String PUBLIC_INTERFACE = "publicinterface";
-    public static final String PUBLIC_IP_ID = "publicipid";
-    public static final String PUBLIC_IP = "publicip";
-    public static final String PUBLIC_PORT = "publicport";
-    public static final String PUBLIC_START_PORT = "publicport";
-    public static final String PUBLIC_END_PORT = "publicendport";
-    public static final String PUBLIC_ZONE = "publiczone";
-    public static final String RECEIVED_BYTES = "receivedbytes";
-    public static final String RECONNECT = "reconnect";
-    public static final String RECOVER = "recover";
-    public static final String REQUIRES_HVM = "requireshvm";
-    public static final String RESOURCE_TYPE = "resourcetype";
-    public static final String RESOURCE_TYPE_NAME = "resourcetypename";
-    public static final String RESPONSE = "response";
-    public static final String REVERTABLE = "revertable";
-    public static final String REGISTERED = "registered";
-    public static final String QUERY_FILTER = "queryfilter";
-    public static final String SCHEDULE = "schedule";
-    public static final String SCOPE = "scope";
-    public static final String SECRET_KEY = "usersecretkey";
-    public static final String SECONDARY_IP = "secondaryip";
-    public static final String SINCE = "since";
-    public static final String KEY = "key";
-    public static final String SEARCH_BASE = "searchbase";
-    public static final String SECURITY_GROUP_IDS = "securitygroupids";
-    public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
-    public static final String SECURITY_GROUP_NAME = "securitygroupname";
-    public static final String SECURITY_GROUP_ID = "securitygroupid";
-    public static final String SENT = "sent";
-    public static final String SENT_BYTES = "sentbytes";
-    public static final String SERIAL = "serial";
-    public static final String SERVICE_OFFERING_ID = "serviceofferingid";
-    public static final String SESSIONKEY = "sessionkey";
-    public static final String SHOW_CAPACITIES = "showcapacities";
-    public static final String SHOW_REMOVED = "showremoved";
-    public static final String SIGNATURE = "signature";
-    public static final String SIGNATURE_VERSION = "signatureversion";
-    public static final String SIZE = "size";
-    public static final String SNAPSHOT = "snapshot";
-    public static final String SNAPSHOT_ID = "snapshotid";
-    public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
-    public static final String SNAPSHOT_TYPE = "snapshottype";
-    public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
-    public static final String SOURCE_ZONE_ID = "sourcezoneid";
-    public static final String START_DATE = "startdate";
-    public static final String START_ID = "startid";
-    public static final String START_IP = "startip";
-    public static final String START_IPV6 = "startipv6";
-    public static final String START_PORT = "startport";
-    public static final String STATE = "state";
-    public static final String STATUS = "status";
-    public static final String STORAGE_TYPE = "storagetype";
-    public static final String STORAGE_POLICY = "storagepolicy";
-    public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
-    public static final String STORAGE_CAPABILITIES = "storagecapabilities";
-    public static final String SYSTEM_VM_TYPE = "systemvmtype";
-    public static final String TAGS = "tags";
-    public static final String TARGET_IQN = "targetiqn";
-    public static final String TEMPLATE_FILTER = "templatefilter";
-    public static final String TEMPLATE_ID = "templateid";
-    public static final String ISO_ID = "isoid";
-    public static final String TIMEOUT = "timeout";
-    public static final String TIMEZONE = "timezone";
-    public static final String TIMEZONEOFFSET = "timezoneoffset";
-    public static final String TYPE = "type";
-    public static final String TRUST_STORE = "truststore";
-    public static final String TRUST_STORE_PASSWORD = "truststorepass";
-    public static final String URL = "url";
-    public static final String USAGE_INTERFACE = "usageinterface";
-    public static final String USER_DATA = "userdata";
-    public static final String USER_ID = "userid";
-    public static final String USE_SSL = "ssl";
-    public static final String USERNAME = "username";
-    public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
-    public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
-    public static final String Update_IN_SEQUENCE ="updateinsequence";
-    public static final String VALUE = "value";
-    public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
-    public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
-    public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
-    public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
-    public static final String USAGE_ID = "usageid";
-    public static final String USAGE_TYPE = "usagetype";
-    public static final String INCLUDE_TAGS = "includetags";
-
-    public static final String VLAN = "vlan";
-    public static final String VLAN_RANGE = "vlanrange";
-    public static final String REMOVE_VLAN = "removevlan";
-    public static final String VLAN_ID = "vlanid";
-    public static final String ISOLATED_PVLAN = "isolatedpvlan";
-    public static final String ISOLATION_URI = "isolationuri";
-    public static final String VM_AVAILABLE = "vmavailable";
-    public static final String VM_LIMIT = "vmlimit";
-    public static final String VM_TOTAL = "vmtotal";
-    public static final String VNET = "vnet";
-    public static final String IS_VOLATILE = "isvolatile";
-    public static final String VOLUME_ID = "volumeid";
-    public static final String ZONE_ID = "zoneid";
-    public static final String ZONE_NAME = "zonename";
-    public static final String NETWORK_TYPE = "networktype";
-    public static final String PAGE = "page";
-    public static final String PAGE_SIZE = "pagesize";
-    public static final String COUNT = "count";
-    public static final String TRAFFIC_TYPE = "traffictype";
-    public static final String NETWORK_OFFERING_ID = "networkofferingid";
-    public static final String TIER_NETWORK_OFFERINGS = "tiernetworkofferings";
-    public static final String NETWORK_IDS = "networkids";
-    public static final String NETWORK_ID = "networkid";
-    public static final String NIC_ID = "nicid";
-    public static final String SPECIFY_VLAN = "specifyvlan";
-    public static final String IS_DEFAULT = "isdefault";
-    public static final String IS_SYSTEM = "issystem";
-    public static final String IS_USER_DEFINED = "isuserdefined";
-    public static final String AVAILABILITY = "availability";
-    public static final String NETWORKRATE = "networkrate";
-    public static final String HOST_TAGS = "hosttags";
-    public static final String SSH_KEYPAIR = "keypair";
-    public static final String HTTPMETHOD = "httpmethod";
-    public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
-    public static final String HOST_CPU_NUM = "hostcpunum";
-    public static final String HOST_MEM_CAPACITY = "hostmemcapacity";
-    public static final String HOST_MAC = "hostmac";
-    public static final String HOST_TAG = "hosttag";
-    public static final String PXE_SERVER_TYPE = "pxeservertype";
-    public static final String LINMIN_USERNAME = "linminusername";
-    public static final String LINMIN_PASSWORD = "linminpassword";
-    public static final String LINMIN_APID = "linminapid";
-    public static final String DHCP_SERVER_TYPE = "dhcpservertype";
-    public static final String LINK_LOCAL_IP = "linklocalip";
-    public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress";
-    public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask";
-    public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid";
-    public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress";
-    public static final String PRIVATE_NETMASK = "privatenetmask";
-    public static final String PRIVATE_NETWORK_ID = "privatenetworkid";
-    public static final String ALLOCATION_STATE = "allocationstate";
-    public static final String MANAGED_STATE = "managedstate";
-    public static final String STORAGE_ID = "storageid";
-    public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
-    public static final String PING_DIR = "pingdir";
-    public static final String TFTP_DIR = "tftpdir";
-    public static final String PING_CIFS_USERNAME = "pingcifsusername";
-    public static final String PING_CIFS_PASSWORD = "pingcifspassword";
-    public static final String CHECKSUM = "checksum";
-    public static final String NETWORK_DEVICE_TYPE = "networkdevicetype";
-    public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist";
-    public static final String ZONE_TOKEN = "zonetoken";
-    public static final String DHCP_PROVIDER = "dhcpprovider";
-    public static final String RESULT = "success";
-    public static final String RESUME = "resume";
-    public static final String LUN_ID = "lunId";
-    public static final String IQN = "iqn";
-    public static final String AGGREGATE_NAME = "aggregatename";
-    public static final String POOL_NAME = "poolname";
-    public static final String VOLUME_NAME = "volumename";
-    public static final String SNAPSHOT_POLICY = "snapshotpolicy";
-    public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
-    public static final String IP_NETWORK_LIST = "iptonetworklist";
-    public static final String PARAM_LIST = "param";
-    public static final String FOR_LOAD_BALANCING = "forloadbalancing";
-    public static final String KEYBOARD = "keyboard";
-    public static final String OPEN_FIREWALL = "openfirewall";
-    public static final String TEMPLATE_TAG = "templatetag";
-    public static final String HYPERVISOR_VERSION = "hypervisorversion";
-    public static final String MAX_GUESTS_LIMIT = "maxguestslimit";
-    public static final String MAX_DATA_VOLUMES_LIMIT = "maxdatavolumeslimit";
-    public static final String MAX_HOSTS_PER_CLUSTER = "maxhostspercluster";
-    public static final String PROJECT_ID = "projectid";
-    public static final String PROJECT_IDS = "projectids";
-    public static final String PROJECT = "project";
-    public static final String ROLE = "role";
-    public static final String ROLE_ID = "roleid";
-    public static final String ROLE_TYPE = "roletype";
-    public static final String ROLE_NAME = "rolename";
-    public static final String PERMISSION = "permission";
-    public static final String RULE = "rule";
-    public static final String RULE_ID = "ruleid";
-    public static final String RULE_ORDER = "ruleorder";
-    public static final String USER = "user";
-    public static final String ACTIVE_ONLY = "activeonly";
-    public static final String TOKEN = "token";
-    public static final String ACCEPT = "accept";
-    public static final String SORT_KEY = "sortkey";
-    public static final String ACCOUNT_DETAILS = "accountdetails";
-    public static final String SERVICE_OFFERING_DETAILS = "serviceofferingdetails";
-    public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
-    public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
-    public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";
-    public static final String PROVIDER = "provider";
-    public static final String MANAGED = "managed";
-    public static final String CAPACITY_BYTES = "capacitybytes";
-    public static final String CAPACITY_IOPS = "capacityiops";
-    public static final String NETWORK_SPEED = "networkspeed";
-    public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
-    public static final String BROADCAST_URI = "broadcasturi";
-    public static final String ISOLATION_METHOD = "isolationmethod";
-    public static final String ISOLATION_METHODS = "isolationmethods";
-    public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
-    public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid";
-    public static final String ENABLE = "enable";
-    public static final String ENABLED = "enabled";
-    public static final String SERVICE_NAME = "servicename";
-    public static final String DHCP_RANGE = "dhcprange";
-    public static final String UUID = "uuid";
-    public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
-    public static final String LOCAL_STORAGE_ENABLED = "localstorageenabled";
-    public static final String GUEST_IP_TYPE = "guestiptype";
-    public static final String XENSERVER_NETWORK_LABEL = "xennetworklabel";
-    public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
-    public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
-    public static final String HYPERV_NETWORK_LABEL = "hypervnetworklabel";
-    public static final String OVM3_NETWORK_LABEL = "ovm3networklabel";
-    public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid";
-    public static final String SERVICE_LIST = "servicelist";
-    public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice";
-    public static final String SUPPORTED_SERVICES = "supportedservices";
-    public static final String NSP_ID = "nspid";
-    public static final String ACL_TYPE = "acltype";
-    public static final String SUBDOMAIN_ACCESS = "subdomainaccess";
-    public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid";
-    public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename";
-    public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate";
-    public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity";
-    public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated";
-    public static final String LOAD_BALANCER_RULE = "loadbalancerrule";
-    public static final String LOAD_BALANCER_RULE_LIST = "loadbalancerrulelist";
-    public static final String FIREWALL_DEVICE_ID = "fwdeviceid";
-    public static final String FIREWALL_DEVICE_NAME = "fwdevicename";
-    public static final String FIREWALL_DEVICE_STATE = "fwdevicestate";
-    public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity";
-    public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated";
-    public static final String SERVICE = "service";
-    public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
-    public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
-    public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
-    public static final String RESOURCE_STATE = "resourcestate";
-    public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired";
-    public static final String REQUIRED = "required";
-    public static final String RESTART_REQUIRED = "restartrequired";
-    public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
-    public static final String CONSERVE_MODE = "conservemode";
-    public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
-    public static final String KEYWORD = "keyword";
-    public static final String LIST_ALL = "listall";
-    public static final String SPECIFY_IP_RANGES = "specifyipranges";
-    public static final String IS_SOURCE_NAT = "issourcenat";
-    public static final String IS_STATIC_NAT = "isstaticnat";
-    public static final String SORT_BY = "sortby";
-    public static final String CHANGE_CIDR = "changecidr";
-    public static final String PURPOSE = "purpose";
-    public static final String IS_TAGGED = "istagged";
-    public static final String INSTANCE_NAME = "instancename";
-    public static final String START_VM = "startvm";
-    public static final String HA_HOST = "hahost";
-    public static final String CUSTOM_DISK_OFF_MIN_SIZE = "customdiskofferingminsize";
-    public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize";
-    public static final String DEFAULT_ZONE_ID = "defaultzoneid";
-    public static final String LIVE_MIGRATE = "livemigrate";
-    public static final String MIGRATE_TO = "migrateto";
-    public static final String GUID = "guid";
-    public static final String VSWITCH_TYPE_GUEST_TRAFFIC = "guestvswitchtype";
-    public static final String VSWITCH_TYPE_PUBLIC_TRAFFIC = "publicvswitchtype";
-    public static final String VSWITCH_NAME_GUEST_TRAFFIC = "guestvswitchname";
-    public static final String VSWITCH_NAME_PUBLIC_TRAFFIC = "publicvswitchname";
-    // Ovs controller
-    public static final String OVS_DEVICE_ID = "ovsdeviceid";
-    public static final String OVS_DEVICE_NAME = "ovsdevicename";
-    // OpenDaylight controller
-    public static final String ODL_DEVICE_ID = "odldeviceid";
-    public static final String ODL_DEVICE_NAME = "odldevicename";
-    public static final String ODL_TRANSPORT_ZONE_UUID = "transportzoneuuid";
-    public static final String ODL_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
-
-    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid";
-    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename";
-    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate";
-    // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this
-    // later.
-    public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity";
-    public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
-    public static final String VSM_USERNAME = "vsmusername";
-    public static final String VSM_PASSWORD = "vsmpassword";
-    public static final String VSM_IPADDRESS = "vsmipaddress";
-    public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid";
-    public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid";
-    public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid";
-    public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid";
-    public static final String VSM_DOMAIN_ID = "vsmdomainid";
-    public static final String VSM_CONFIG_MODE = "vsmconfigmode";
-    public static final String VSM_CONFIG_STATE = "vsmconfigstate";
-    public static final String VSM_DEVICE_STATE = "vsmdevicestate";
-    public static final String VCENTER = "vcenter";
-    public static final String ADD_VSM_FLAG = "addvsmflag";
-    public static final String END_POINT = "endpoint";
-    public static final String REGION_ID = "regionid";
-    public static final String VPC_OFF_ID = "vpcofferingid";
-    public static final String NETWORK = "network";
-    public static final String VPC_ID = "vpcid";
-    public static final String GATEWAY_ID = "gatewayid";
-    public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
-    public static final String RESOURCE_IDS = "resourceids";
-    public static final String RESOURCE_ID = "resourceid";
-    public static final String CUSTOMER = "customer";
-    public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid";
-    public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid";
-    public static final String IPSEC_PSK = "ipsecpsk";
-    public static final String GUEST_IP = "guestip";
-    public static final String REMOVED = "removed";
-    public static final String IKE_POLICY = "ikepolicy";
-    public static final String ESP_POLICY = "esppolicy";
-    public static final String IKE_LIFETIME = "ikelifetime";
-    public static final String ESP_LIFETIME = "esplifetime";
-    public static final String DPD = "dpd";
-    public static final String FORCE_ENCAP = "forceencap";
-    public static final String FOR_VPC = "forvpc";
-    public static final String SHRINK_OK = "shrinkok";
-    public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
-    public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid";
-    public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
-    public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
-    public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
-    public static final String NSX_LOGICAL_SWITCH = "nsxlogicalswitch";
-    public static final String NSX_LOGICAL_SWITCH_PORT = "nsxlogicalswitchport";
-    public static final String S3_ACCESS_KEY = "accesskey";
-    public static final String S3_SECRET_KEY = "secretkey";
-    public static final String S3_END_POINT = "endpoint";
-    public static final String S3_BUCKET_NAME = "bucket";
-    public static final String S3_SIGNER = "s3signer";
-    public static final String S3_V3_SIGNER = "S3SignerType";
-    public static final String S3_V4_SIGNER = "AWSS3V4SignerType";
-    public static final String S3_HTTPS_FLAG = "usehttps";
-    public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
-    public static final String S3_CONNECTION_TTL = "connectionttl";
-    public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
-    public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
-    public static final String S3_USE_TCP_KEEPALIVE = "usetcpkeepalive";
-    public static final String INCL_ZONES = "includezones";
-    public static final String EXCL_ZONES = "excludezones";
-    public static final String SOURCE = "source";
-    public static final String COUNTER_ID = "counterid";
-    public static final String AGGR_OPERATOR = "aggroperator";
-    public static final String AGGR_FUNCTION = "aggrfunction";
-    public static final String AGGR_VALUE = "aggrvalue";
-    public static final String THRESHOLD = "threshold";
-    public static final String RELATIONAL_OPERATOR = "relationaloperator";
-    public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams";
-    public static final String MIN_MEMBERS = "minmembers";
-    public static final String MAX_MEMBERS = "maxmembers";
-    public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod";
-    public static final String VMPROFILE_ID = "vmprofileid";
-    public static final String VMGROUP_ID = "vmgroupid";
-    public static final String CS_URL = "csurl";
-    public static final String IDP_ID = "idpid";
-    public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids";
-    public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids";
-    public static final String SCALEUP_POLICIES = "scaleuppolicies";
-    public static final String SCALEDOWN_POLICIES = "scaledownpolicies";
-    public static final String INTERVAL = "interval";
-    public static final String QUIETTIME = "quiettime";
-    public static final String ACTION = "action";
-    public static final String CONDITION_ID = "conditionid";
-    public static final String CONDITION_IDS = "conditionids";
-    public static final String COUNTERPARAM_LIST = "counterparam";
-    public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
-    public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
-    public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
-    public static final String UCS_DN = "ucsdn";
-    public static final String GSLB_PROVIDER = "gslbprovider";
-    public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
-    public static final String GSLB_PROVIDER_PUBLIC_IP = "gslbproviderpublicip";
-    public static final String GSLB_PROVIDER_PRIVATE_IP = "gslbproviderprivateip";
-    public static final String VM_SNAPSHOT_DESCRIPTION = "description";
-    public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
-    public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
-    public static final String VM_SNAPSHOT_IDS = "vmsnapshotids";
-    public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
-    public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
-    public static final String VM_SNAPSHOT_QUIESCEVM = "quiescevm";
-    public static final String IMAGE_STORE_UUID = "imagestoreuuid";
-    public static final String GUEST_VM_CIDR = "guestvmcidr";
-    public static final String NETWORK_CIDR = "networkcidr";
-    public static final String RESERVED_IP_RANGE = "reservediprange";
-    public static final String UCS_MANAGER_ID = "ucsmanagerid";
-    public static final String UCS_PROFILE_DN = "profiledn";
-    public static final String UCS_BLADE_DN = "bladedn";
-    public static final String UCS_BLADE_ID = "bladeid";
-    public static final String VM_GUEST_IP = "vmguestip";
-    public static final String HEALTHCHECK_RESPONSE_TIMEOUT = "responsetimeout";
-    public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime";
-    public static final String HEALTHCHECK_HEALTHY_THRESHOLD = "healthythreshold";
-    public static final String HEALTHCHECK_UNHEALTHY_THRESHOLD = "unhealthythreshold";
-    public static final String HEALTHCHECK_PINGPATH = "pingpath";
-    public static final String SOURCE_PORT = "sourceport";
-    public static final String INSTANCE_PORT = "instanceport";
-    public static final String SOURCE_IP = "sourceipaddress";
-    public static final String SOURCE_IP_NETWORK_ID = "sourceipaddressnetworkid";
-    public static final String SCHEME = "scheme";
-    public static final String PROVIDER_TYPE = "providertype";
-    public static final String AFFINITY_GROUP_IDS = "affinitygroupids";
-    public static final String AFFINITY_GROUP_NAMES = "affinitygroupnames";
-    public static final String ASA_INSIDE_PORT_PROFILE = "insideportprofile";
-    public static final String AFFINITY_GROUP_ID = "affinitygroupid";
-    public static final String DEPLOYMENT_PLANNER = "deploymentplanner";
-    public static final String ACL_ID = "aclid";
-    public static final String NUMBER = "number";
-    public static final String IS_DYNAMICALLY_SCALABLE = "isdynamicallyscalable";
-    public static final String ROUTING = "isrouting";
-    public static final String MAX_CONNECTIONS = "maxconnections";
-    public static final String SERVICE_STATE = "servicestate";
-
-    public static final String IAM_ACCOUNT_IDS = "accountids";
-    public static final String IAM_MEMBER_ACCOUNTS = "memberaccounts";
-    public static final String IAM_PARENT_POLICY_ID = "parentpolicyid";
-    public static final String IAM_PARENT_POLICY_NAME = "parentpolicyname";
-    public static final String IAM_POLICY_IDS = "policyids";
-    public static final String IAM_POLICIES = "policies";
-    public static final String IAM_APIS = "apis";
-    public static final String IAM_GROUPS = "groups";
-    public static final String IAM_PERMISSIONS = "permission";
-    public static final String IAM_ACTION = "action";
-    public static final String IAM_SCOPE = "scope";
-    public static final String IAM_SCOPE_ID = "scopeid";
-    public static final String IAM_ALLOW_DENY = "permission";
-    public static final String ENTITY_TYPE = "entitytype";
-    public static final String ENTITY_ID = "entityid";
-    public static final String EXTERNAL_ID = "externalid";
-    public static final String ACCESS_TYPE = "accesstype";
-
-    public static final String RESOURCE_DETAILS = "resourcedetails";
-    public static final String EXPUNGE = "expunge";
-    public static final String FOR_DISPLAY = "fordisplay";
-    public static final String PASSIVE = "passive";
-    public static final String VERSION = "version";
-    public static final String START = "start";
-    public static final String GPUGROUP = "gpugroup";
-    public static final String GPUGROUPNAME = "gpugroupname";
-    public static final String VGPU = "vgpu";
-    public static final String VGPUTYPE = "vgputype";
-    public static final String VIDEORAM = "videoram";
-    public static final String MAXHEADS = "maxheads";
-    public static final String MAXRESOLUTIONX = "maxresolutionx";
-    public static final String MAXRESOLUTIONY = "maxresolutiony";
-    public static final String MAXVGPUPERPGPU = "maxvgpuperpgpu";
-    public static final String REMAININGCAPACITY = "remainingcapacity";
-    public static final String MAXCAPACITY = "maxcapacity";
-    public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
-    public static final String REDUNDANT_ROUTER = "redundantrouter";
-    public static final String REDUNDANT_VPC_ROUTER = "redundantvpcrouter";
-    public static final String READ_ONLY = "readonly";
-    public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc";
-    public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet";
-    public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
-    public static final String REGION_LEVEL_VPC = "regionlevelvpc";
-    public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
-    public static final String NETWORK_NAME = "networkname";
-    public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
-    public static final String METADATA = "metadata";
-    public static final String PHYSICAL_SIZE = "physicalsize";
-    public static final String OVM3_POOL = "ovm3pool";
-    public static final String OVM3_CLUSTER = "ovm3cluster";
-    public static final String OVM3_VIP = "ovm3vip";
-    public static final String CLEAN_UP_DETAILS = "cleanupdetails";
-    public static final String VIRTUAL_SIZE = "virtualsize";
-    public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
-    public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid";
-
-    public static final String ZONE_ID_LIST = "zoneids";
-    public static final String DESTINATION_ZONE_ID_LIST = "destzoneids";
-    public static final String ADMIN = "admin";
-    public static final String CHECKSUM_PARAMETER_PREFIX_DESCRIPTION = "The parameter containing the checksum will be considered a MD5sum if it is not prefixed\n"
-            + " and just a plain ascii/utf8 representation of a hexadecimal string. If it is required to\n"
-            + " use another algorithm the hexadecimal string is to be prefixed with a string of the form,\n"
-            + " \"{<algorithm>}\", not including the double quotes. In this <algorithm> is the exact string\n"
-            + " representing the java supported algorithm, i.e. MD5 or SHA-256. Note that java does not\n"
-            + " contain an algorithm called SHA256 or one called sha-256, only SHA-256.";
-
-    public static final String HAS_ANNOTATION = "hasannotation";
-    public static final String LAST_ANNOTATED = "lastannotated";
-    public static final String LDAP_DOMAIN = "ldapdomain";
-
-
-    public enum HostDetails {
-        all, capacity, events, stats, min;
-    }
-
-    public enum VMDetails {
-        all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp;
-    }
-
-    public enum DomainDetails {
-        all, resource, min;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
deleted file mode 100644
index 8963415..0000000
--- a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-
-import org.apache.log4j.Logger;
-
-/**
- * queryAsyncJobResult API command.
- */
-public abstract class BaseAsyncCmd extends BaseCmd {
-
-    public static final String ipAddressSyncObject = "ipaddress";
-    public static final String networkSyncObject = "network";
-    public static final String vpcSyncObject = "vpc";
-    public static final String snapshotHostSyncObject = "snapshothost";
-    public static final String gslbSyncObject = "globalserverloadbalancer";
-    private static final Logger s_logger = Logger.getLogger(BaseAsyncCmd.class.getName());
-
-    private Object job;
-
-    @Parameter(name = "starteventid", type = CommandType.LONG)
-    private Long startEventId;
-
-    @Parameter(name = ApiConstants.CUSTOM_JOB_ID , type = CommandType.STRING)
-    private String injectedJobId;
-
-    public String getInjectedJobId() {
-        return this.injectedJobId;
-    }
-
-    /**
-     * For proper tracking of async commands through the system, events must be generated when the command is
-     * scheduled, started, and completed. Commands should specify the type of event so that when the scheduled,
-     * started, and completed events are saved to the events table, they have the proper type information.
-     *
-     * @return a string representing the type of event, e.g. VM.START, VOLUME.CREATE.
-     */
-    public abstract String getEventType();
-
-    /**
-     * For proper tracking of async commands through the system, events must be generated when the command is
-     * scheduled, started, and completed. Commands should specify a description for these events so that when
-     * the scheduled, started, and completed events are saved to the events table, they have a meaningful description.
-     *
-     * @return a string representing a description of the event
-     */
-    public abstract String getEventDescription();
-
-    public void setJob(Object job) {
-        this.job = job;
-    }
-
-    public Long getStartEventId() {
-        return startEventId;
-    }
-
-    public void setStartEventId(Long startEventId) {
-        this.startEventId = startEventId;
-    }
-
-    /**
-     * Async commands that want to be tracked as part of the listXXX commands need to
-     * provide implementations of the two following methods, getInstanceId() and getInstanceType()
-     *
-     * getObjectId() should return the id of the object the async command is executing on
-     * getObjectType() should return a type from the AsyncJob.Type enumeration
-     */
-    public Long getInstanceId() {
-        return null;
-    }
-
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.None;
-    }
-
-    public String getSyncObjType() {
-        return null;
-    }
-
-    public Long getSyncObjId() {
-        return null;
-    }
-
-    public Object getJob() {
-        return job;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
deleted file mode 100644
index 3676734..0000000
--- a/api/src/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-import org.apache.log4j.Logger;
-import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-
-import java.util.Collection;
-import java.util.Map;
-
-public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateIsoCmd.class.getName());
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "true if image is bootable, false otherwise; available only for updateIso API")
-    private Boolean bootable;
-
-    @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if the template requres HVM, false otherwise; available only for updateTemplate API")
-    private Boolean requiresHvm;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the image", length = 4096)
-    private String displayText;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the image file")
-    private Long id;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the image file")
-    private String templateName;
-
-    @Parameter(name = ApiConstants.OS_TYPE_ID,
-               type = CommandType.UUID,
-               entityType = GuestOSResponse.class,
-               description = "the ID of the OS type that best represents the OS of this image.")
-    private Long osTypeId;
-
-    @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, description = "the format for the image")
-    private String format;
-
-    @Parameter(name = ApiConstants.PASSWORD_ENABLED, type = CommandType.BOOLEAN, description = "true if the image supports the password reset feature; default is false")
-    private Boolean passwordEnabled;
-
-    @Parameter(name = ApiConstants.SORT_KEY, type = CommandType.INTEGER, description = "sort key of the template, integer")
-    private Integer sortKey;
-
-    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
-               type = CommandType.BOOLEAN,
-               description = "true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
-    private Boolean isDynamicallyScalable;
-
-    @Parameter(name = ApiConstants.ROUTING, type = CommandType.BOOLEAN, description = "true if the template type is routing i.e., if template is used to deploy router")
-    protected Boolean isRoutingType;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
-    protected Map details;
-
-    @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
-            type = CommandType.BOOLEAN,
-            description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
-    private Boolean cleanupDetails;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Boolean getBootable() {
-        return bootable;
-    }
-
-    public Boolean getRequiresHvm() {
-        return requiresHvm;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getTemplateName() {
-        return templateName;
-    }
-
-    public Long getOsTypeId() {
-        return osTypeId;
-    }
-
-    public Boolean getPasswordEnabled() {
-        return passwordEnabled;
-    }
-
-    public String getFormat() {
-        return format;
-    }
-
-    public Integer getSortKey() {
-        return sortKey;
-    }
-
-    public Boolean isDynamicallyScalable() {
-        return isDynamicallyScalable;
-    }
-
-    public Boolean isRoutingType() {
-        return isRoutingType;
-    }
-
-    public Map getDetails() {
-        if (this.details == null || this.details.isEmpty()) {
-            return null;
-        }
-
-        Collection paramsCollection = this.details.values();
-        return (Map) (paramsCollection.toArray())[0];
-    }
-
-    public boolean isCleanupDetails(){
-        return cleanupDetails == null ? false : cleanupDetails.booleanValue();
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
deleted file mode 100644
index 4fb248c..0000000
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ /dev/null
@@ -1,465 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api;
-
-import java.text.DecimalFormat;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.api.ApiConstants.HostDetails;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
-import org.apache.cloudstack.api.response.CapacityResponse;
-import org.apache.cloudstack.api.response.ClusterResponse;
-import org.apache.cloudstack.api.response.ConditionResponse;
-import org.apache.cloudstack.api.response.ConfigurationResponse;
-import org.apache.cloudstack.api.response.CounterResponse;
-import org.apache.cloudstack.api.response.CreateCmdResponse;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.EventResponse;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.api.response.FirewallResponse;
-import org.apache.cloudstack.api.response.FirewallRuleResponse;
-import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.GuestOsMappingResponse;
-import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
-import org.apache.cloudstack.api.response.HostForMigrationResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.api.response.InstanceGroupResponse;
-import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
-import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
-import org.apache.cloudstack.api.response.IsolationMethodResponse;
-import org.apache.cloudstack.api.response.LBHealthCheckResponse;
-import org.apache.cloudstack.api.response.LBStickinessResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.LoadBalancerResponse;
-import org.apache.cloudstack.api.response.NetworkACLItemResponse;
-import org.apache.cloudstack.api.response.NetworkACLResponse;
-import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.OvsProviderResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.PodResponse;
-import org.apache.cloudstack.api.response.PortableIpRangeResponse;
-import org.apache.cloudstack.api.response.PortableIpResponse;
-import org.apache.cloudstack.api.response.PrivateGatewayResponse;
-import org.apache.cloudstack.api.response.ProjectAccountResponse;
-import org.apache.cloudstack.api.response.ProjectInvitationResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.ProviderResponse;
-import org.apache.cloudstack.api.response.RegionResponse;
-import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
-import org.apache.cloudstack.api.response.ResourceCountResponse;
-import org.apache.cloudstack.api.response.ResourceLimitResponse;
-import org.apache.cloudstack.api.response.ResourceTagResponse;
-import org.apache.cloudstack.api.response.SSHKeyPairResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.ServiceResponse;
-import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
-import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
-import org.apache.cloudstack.api.response.StaticRouteResponse;
-import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.TrafficMonitorResponse;
-import org.apache.cloudstack.api.response.TrafficTypeResponse;
-import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
-import org.apache.cloudstack.api.response.UsageRecordResponse;
-import org.apache.cloudstack.api.response.UserResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
-import org.apache.cloudstack.api.response.VlanIpRangeResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.VpcOfferingResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.VpnUsersResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.config.Configuration;
-import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
-import org.apache.cloudstack.region.PortableIp;
-import org.apache.cloudstack.region.PortableIpRange;
-import org.apache.cloudstack.region.Region;
-import org.apache.cloudstack.usage.Usage;
-
-import com.cloud.capacity.Capacity;
-import com.cloud.configuration.ResourceCount;
-import com.cloud.configuration.ResourceLimit;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.dc.StorageNetworkIpRange;
-import com.cloud.dc.Vlan;
-import com.cloud.domain.Domain;
-import com.cloud.event.Event;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.HypervisorCapabilities;
-import com.cloud.network.GuestVlan;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.OvsProvider;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PhysicalNetworkTrafficType;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteCustomerGateway;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.Site2SiteVpnGateway;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.VpnUser;
-import com.cloud.network.as.AutoScalePolicy;
-import com.cloud.network.as.AutoScaleVmGroup;
-import com.cloud.network.as.AutoScaleVmProfile;
-import com.cloud.network.as.Condition;
-import com.cloud.network.as.Counter;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.HealthCheckPolicy;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.rules.StickinessPolicy;
-import com.cloud.network.security.SecurityGroup;
-import com.cloud.network.security.SecurityRule;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcOffering;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.org.Cluster;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectAccount;
-import com.cloud.projects.ProjectInvitation;
-import com.cloud.region.ha.GlobalLoadBalancerRule;
-import com.cloud.server.ResourceTag;
-import com.cloud.storage.GuestOS;
-import com.cloud.storage.GuestOSHypervisor;
-import com.cloud.storage.ImageStore;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.storage.snapshot.SnapshotPolicy;
-import com.cloud.storage.snapshot.SnapshotSchedule;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.SSHKeyPair;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.net.Ip;
-import com.cloud.vm.InstanceGroup;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-public interface ResponseGenerator {
-    UserResponse createUserResponse(UserAccount user);
-
-    AccountResponse createAccountResponse(ResponseView view, Account account);
-
-    DomainResponse createDomainResponse(Domain domain);
-
-    DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering);
-
-    ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit);
-
-    ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount);
-
-    ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering);
-
-    ConfigurationResponse createConfigurationResponse(Configuration cfg);
-
-    SnapshotResponse createSnapshotResponse(Snapshot snapshot);
-
-    SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy);
-
-    List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms);
-
-    List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms);
-
-    SystemVmResponse createSystemVmResponse(VirtualMachine systemVM);
-
-    DomainRouterResponse createDomainRouterResponse(VirtualRouter router);
-
-    HostResponse createHostResponse(Host host, EnumSet<HostDetails> details);
-
-    HostResponse createHostResponse(Host host);
-
-    HostForMigrationResponse createHostForMigrationResponse(Host host);
-
-    HostForMigrationResponse createHostForMigrationResponse(Host host, EnumSet<HostDetails> details);
-
-    VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan);
-
-    VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan);
-
-    IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddress);
-
-    GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result);
-
-    GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule);
-
-    LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer);
-
-    LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb);
-
-    LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb);
-
-    LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb);
-
-    LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb);
-
-    PodResponse createPodResponse(Pod pod, Boolean showCapacities);
-
-    ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities);
-
-    VolumeResponse createVolumeResponse(ResponseView view, Volume volume);
-
-    InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group);
-
-    StoragePoolResponse createStoragePoolResponse(StoragePool pool);
-
-    StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool);
-
-    ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities);
-
-    FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule);
-
-    IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule);
-
-    User findUserById(Long userId);
-
-    UserVm findUserVmById(Long vmId);
-
-    Volume findVolumeById(Long volumeId);
-
-    Account findAccountByNameDomain(String accountName, Long domainId);
-
-    VirtualMachineTemplate findTemplateById(Long templateId);
-
-    Host findHostById(Long hostId);
-
-    DiskOffering findDiskOfferingById(Long diskOfferingId);
-
-    VpnUsersResponse createVpnUserResponse(VpnUser user);
-
-    RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn);
-
-    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly);
-
-    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly);
-
-    SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules);
-
-    SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group);
-
-    ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url);
-
-    ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url);
-
-    String toSerializedString(CreateCmdResponse response, String responseType);
-
-    EventResponse createEventResponse(Event event);
-
-    TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result);
-
-    List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
-                                                   Long zoneId, boolean readyOnly);
-
-    List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
-                                                   List<Long> zoneIds, boolean readyOnly);
-
-    List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format);
-
-    TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id);
-
-    AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd);
-
-    NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering);
-
-    NetworkResponse createNetworkResponse(ResponseView view, Network network);
-
-    UserResponse createUserResponse(User user);
-
-    AccountResponse createUserAccountResponse(ResponseView view, UserAccount user);
-
-    Long getSecurityGroupId(String groupName, long accountId);
-
-    List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId, boolean readyOnly);
-
-    ProjectResponse createProjectResponse(Project project);
-
-    List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long vmId);
-
-    FirewallResponse createFirewallResponse(FirewallRule fwRule);
-
-    HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities);
-
-    ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount);
-
-    ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite);
-
-    SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine systemVM);
-
-    PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result);
-
-    ServiceResponse createNetworkServiceResponse(Service service);
-
-    ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result);
-
-    TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result);
-
-    VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result);
-
-    OvsProviderResponse createOvsProviderResponse(OvsProvider result);
-
-    StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result);
-
-    RegionResponse createRegionResponse(Region region);
-
-    ImageStoreResponse createImageStoreResponse(ImageStore os);
-
-    /**
-     * @param resourceTag
-     * @param keyValueOnly TODO
-     * @return
-     */
-    ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly);
-
-    Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result);
-
-    /**
-     * @param offering
-     * @return
-     */
-    VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering);
-
-    /**
-     * @param vpc
-     * @return
-     */
-    VpcResponse createVpcResponse(ResponseView view, Vpc vpc);
-
-    /**
-     * @param networkACLItem
-     * @return
-     */
-    NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem networkACLItem);
-
-    /**
-     * @param networkACL
-     * @return
-     */
-    NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL);
-
-    /**
-     * @param result
-     * @return
-     */
-    PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result);
-
-    /**
-     * @param result
-     * @return
-     */
-    StaticRouteResponse createStaticRouteResponse(StaticRoute result);
-
-    Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result);
-
-    Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result);
-
-    CounterResponse createCounterResponse(Counter ctr);
-
-    ConditionResponse createConditionResponse(Condition cndn);
-
-    AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy);
-
-    AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile);
-
-    AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup);
-
-    GuestOSResponse createGuestOSResponse(GuestOS os);
-
-    GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
-
-    SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
-
-    UsageRecordResponse createUsageResponse(Usage usageRecord);
-
-    UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap);
-
-    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags();
-
-    TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
-
-    VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
-
-    NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result);
-
-    public NicResponse createNicResponse(Nic result);
-
-    ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances);
-
-    AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);
-
-    Long getAffinityGroupId(String name, long entityOwnerId);
-
-    PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange range);
-
-    PortableIpResponse createPortableIPResponse(PortableIp portableIp);
-
-    InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result);
-
-    IsolationMethodResponse createIsolationMethodResponse(IsolationType method);
-
-    ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds);
-
-    SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
deleted file mode 100644
index a7ce74a..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.account;
-
-import java.util.Collection;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.region.RegionService;
-
-import com.cloud.user.Account;
-
-@APICommand(name = "updateAccount", description = "Updates account information for the authenticated user", responseObject = AccountResponse.class, entityType = {Account.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpdateAccountCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateAccountCmd.class.getName());
-    private static final String s_name = "updateaccountresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "Account id")
-    private Long id;
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the current account name")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the ID of the domain where the account exists")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.NEW_NAME, type = CommandType.STRING, required = true, description = "new name for the account")
-    private String newName;
-
-    @Parameter(name = ApiConstants.NETWORK_DOMAIN,
-               type = CommandType.STRING,
-               description = "Network domain for the account's networks; empty string will update domainName with NULL value")
-    private String networkDomain;
-
-    @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
-    private Map details;
-
-    @Inject
-    RegionService _regionService;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getNewName() {
-        return newName;
-    }
-
-    public String getNetworkDomain() {
-        return networkDomain;
-    }
-
-    public Map getDetails() {
-        if (details == null || details.isEmpty()) {
-            return null;
-        }
-
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = _entityMgr.findById(Account.class, getId());
-        if (account != null) {
-            return account.getAccountId();
-        }
-        account = _accountService.getActiveAccountByName(getAccountName(), getDomainId());
-        if (account != null) {
-            return account.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        Account result = _regionService.updateAccount(this);
-        if (result != null){
-            AccountResponse response = _responseGenerator.createAccountResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update account");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
deleted file mode 100644
index 5e15637..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.host;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.host.Host;
-import com.cloud.user.Account;
-
-@APICommand(name = "reconnectHost", description = "Reconnects a host.", responseObject = HostResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ReconnectHostCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ReconnectHostCmd.class.getName());
-
-    private static final String s_name = "reconnecthostresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = HostResponse.class, required = true, description = "the host ID")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "host";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_HOST_RECONNECT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "reconnecting host: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Host;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        try {
-            Host result = _resourceService.reconnectHost(this);
-            if (result != null) {
-                HostResponse response = _responseGenerator.createHostResponse(result);
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reconnect host");
-            }
-        } catch (Exception ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
deleted file mode 100644
index 6d346e9..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.network;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.response.NetworkResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.network.Network;
-
-@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateNetworkCmdByAdmin.class.getName());
-
-    @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network")
-    private String vlan;
-
-    @Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared networks")
-    private Boolean bypassVlanOverlapCheck;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getVlan() {
-        return vlan;
-    }
-
-    public Boolean getBypassVlanOverlapCheck() {
-        if (bypassVlanOverlapCheck != null) {
-            return bypassVlanOverlapCheck;
-        }
-        return false;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    // an exception thrown by createNetwork() will be caught by the dispatcher.
-    public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{
-        Network result = _networkService.createGuestNetwork(this);
-        if (result != null) {
-            NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        }else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
deleted file mode 100644
index 747da05..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.offering;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.user.Account;
-
-@APICommand(name = "createDiskOffering", description = "Creates a disk offering.", responseObject = DiskOfferingResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateDiskOfferingCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateDiskOfferingCmd.class.getName());
-
-    private static final String s_name = "creatediskofferingresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.DISK_SIZE, type = CommandType.LONG, required = false, description = "size of the disk offering in GB (1GB = 1,073,741,824 bytes)")
-    private Long diskSize;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "alternate display text of the disk offering", length = 4096)
-    private String displayText;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the disk offering")
-    private String offeringName;
-
-    @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "tags for the disk offering", length = 4096)
-    private String tags;
-
-    @Parameter(name = ApiConstants.CUSTOMIZED, type = CommandType.BOOLEAN, description = "whether disk offering size is custom or not")
-    private Boolean customized;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "the ID of the containing domain, null for public offerings")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the disk offering. Values are local and shared.")
-    private String storageType = ServiceOffering.StorageType.shared.toString();
-
-    @Parameter(name = ApiConstants.PROVISIONINGTYPE,
-            type = CommandType.STRING,
-            description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
-    private String provisioningType = ProvisioningType.THIN.toString();
-
-    @Parameter(name = ApiConstants.DISPLAY_OFFERING,
-            type = CommandType.BOOLEAN,
-            description = "an optional field, whether to display the offering to the end user or not.")
-    private Boolean displayOffering;
-
-    @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
-    private Long bytesReadRate;
-
-    @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
-    private Long bytesWriteRate;
-
-    @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
-    private Long iopsReadRate;
-
-    @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
-    private Long iopsWriteRate;
-
-    @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether disk offering iops is custom or not")
-    private Boolean customizedIops;
-
-    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the disk offering")
-    private Long minIops;
-
-    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the disk offering")
-    private Long maxIops;
-
-    @Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
-            type = CommandType.INTEGER,
-            required = false,
-            description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)")
-    private Integer hypervisorSnapshotReserve;
-
-/////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getDiskSize() {
-        return diskSize;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public String getOfferingName() {
-        return offeringName;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public Boolean isCustomized() {
-        return customized;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public String getStorageType() {
-        return storageType;
-    }
-
-    public String getProvisioningType(){
-        return provisioningType;
-    }
-
-    public Boolean getDisplayOffering() {
-        return displayOffering;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute() {
-        DiskOffering offering = _configService.createDiskOffering(this);
-        if (offering != null) {
-            DiskOfferingResponse response = _responseGenerator.createDiskOfferingResponse(offering);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create disk offering");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
deleted file mode 100644
index 0bde79b..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ /dev/null
@@ -1,288 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.offering;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.cloud.storage.Storage;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.log4j.Logger;
-
-import com.cloud.offering.ServiceOffering;
-import com.cloud.user.Account;
-
-@APICommand(name = "createServiceOffering", description = "Creates a service offering.", responseObject = ServiceOfferingResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateServiceOfferingCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateServiceOfferingCmd.class.getName());
-    private static final String s_name = "createserviceofferingresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.CPU_NUMBER, type = CommandType.INTEGER, required = false, description = "the CPU number of the service offering")
-    private Integer cpuNumber;
-
-    @Parameter(name = ApiConstants.CPU_SPEED, type = CommandType.INTEGER, required = false, description = "the CPU speed of the service offering in MHz.")
-    private Integer cpuSpeed;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of the service offering")
-    private String displayText;
-
-    @Parameter(name = ApiConstants.PROVISIONINGTYPE, type = CommandType.STRING, description = "provisioning type used to create volumes. Valid values are thin, sparse, fat.")
-    private String provisioningType = Storage.ProvisioningType.THIN.toString();
-
-    @Parameter(name = ApiConstants.MEMORY, type = CommandType.INTEGER, required = false, description = "the total memory of the service offering in MB")
-    private Integer memory;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the service offering")
-    private String serviceOfferingName;
-
-    @Parameter(name = ApiConstants.OFFER_HA, type = CommandType.BOOLEAN, description = "the HA for the service offering")
-    private Boolean offerHa;
-
-    @Parameter(name = ApiConstants.LIMIT_CPU_USE, type = CommandType.BOOLEAN, description = "restrict the CPU usage to committed service offering")
-    private Boolean limitCpuUse;
-
-    @Parameter(name = ApiConstants.IS_VOLATILE,
-               type = CommandType.BOOLEAN,
-               description = "true if the virtual machine needs to be volatile so that on every reboot of VM, original root disk is dettached then destroyed and a fresh root disk is created and attached to VM")
-    private Boolean isVolatile;
-
-    @Parameter(name = ApiConstants.STORAGE_TYPE, type = CommandType.STRING, description = "the storage type of the service offering. Values are local and shared.")
-    private String storageType;
-
-    @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for this service offering.")
-    private String tags;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "the ID of the containing domain, null for public offerings")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.STRING, description = "the host tag for this service offering.")
-    private String hostTag;
-
-    @Parameter(name = ApiConstants.IS_SYSTEM_OFFERING, type = CommandType.BOOLEAN, description = "is this a system vm offering")
-    private Boolean isSystem;
-
-    @Parameter(name = ApiConstants.SYSTEM_VM_TYPE,
-               type = CommandType.STRING,
-               description = "the system VM type. Possible types are \"domainrouter\", \"consoleproxy\" and \"secondarystoragevm\".")
-    private String systemVmType;
-
-    @Parameter(name = ApiConstants.NETWORKRATE,
-               type = CommandType.INTEGER,
-               description = "data transfer rate in megabits per second allowed. Supported only for non-System offering and system offerings having \"domainrouter\" systemvmtype")
-    private Integer networkRate;
-
-    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER,
-               type = CommandType.STRING,
-               description = "The deployment planner heuristics used to deploy a VM of this offering. If null, value of global config vm.deployment.planner is used")
-    private String deploymentPlanner;
-
-    @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
-    private Map details;
-
-    @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
-    private Long bytesReadRate;
-
-    @Parameter(name = ApiConstants.BYTES_WRITE_RATE, type = CommandType.LONG, required = false, description = "bytes write rate of the disk offering")
-    private Long bytesWriteRate;
-
-    @Parameter(name = ApiConstants.IOPS_READ_RATE, type = CommandType.LONG, required = false, description = "io requests read rate of the disk offering")
-    private Long iopsReadRate;
-
-    @Parameter(name = ApiConstants.IOPS_WRITE_RATE, type = CommandType.LONG, required = false, description = "io requests write rate of the disk offering")
-    private Long iopsWriteRate;
-
-    @Parameter(name = ApiConstants.CUSTOMIZED_IOPS, type = CommandType.BOOLEAN, required = false, description = "whether compute offering iops is custom or not", since = "4.4")
-    private Boolean customizedIops;
-
-    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "min iops of the compute offering", since = "4.4")
-    private Long minIops;
-
-    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "max iops of the compute offering", since = "4.4")
-    private Long maxIops;
-
-    @Parameter(name = ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE,
-            type = CommandType.INTEGER,
-            required = false,
-            description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)",
-            since = "4.4")
-    private Integer hypervisorSnapshotReserve;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Integer getCpuNumber() {
-        return cpuNumber;
-    }
-
-    public Integer getCpuSpeed() {
-        return cpuSpeed;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public String getProvisioningType(){
-        return provisioningType;
-    }
-
-    public Integer getMemory() {
-        return memory;
-    }
-
-    public String getServiceOfferingName() {
-        return serviceOfferingName;
-    }
-
-    public Boolean getOfferHa() {
-        return offerHa == null ? Boolean.FALSE : offerHa;
-    }
-
-    public Boolean GetLimitCpuUse() {
-        return limitCpuUse == null ? Boolean.FALSE : limitCpuUse;
-    }
-
-    public Boolean getVolatileVm() {
-        return isVolatile == null ? Boolean.FALSE : isVolatile;
-    }
-
-    public String getStorageType() {
-        return storageType;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getHostTag() {
-        return hostTag;
-    }
-
-    public Boolean getIsSystem() {
-        return isSystem == null ? false : isSystem;
-    }
-
-    public String getSystemVmType() {
-        return systemVmType;
-    }
-
-    public Integer getNetworkRate() {
-        return networkRate;
-    }
-
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public boolean getCustomized() {
-        return (cpuNumber == null || memory == null || cpuSpeed == null);
-    }
-
-    public Map<String, String> getDetails() {
-        Map<String, String> detailsMap = null;
-        if (details != null && !details.isEmpty()) {
-            detailsMap = new HashMap<String, String>();
-            Collection<?> props = details.values();
-            Iterator<?> iter = props.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> detail = (HashMap<String, String>) iter.next();
-                detailsMap.put(detail.get("key"), detail.get("value"));
-            }
-        }
-        return detailsMap;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute() {
-        ServiceOffering result = _configService.createServiceOffering(this);
-        if (result != null) {
-            ServiceOfferingResponse response = _responseGenerator.createServiceOfferingResponse(result);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create service offering");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java
deleted file mode 100644
index 10cf00f..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/router/CreateVirtualRouterElementCmd.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.router;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ProviderResponse;
-import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.VirtualRouterProvider.Type;
-import com.cloud.network.element.VirtualRouterElementService;
-import com.cloud.user.Account;
-
-@APICommand(name = "createVirtualRouterElement", responseObject = VirtualRouterProviderResponse.class, description = "Create a virtual router element.",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateVirtualRouterElementCmd.class.getName());
-    private static final String s_name = "createvirtualrouterelementresponse";
-
-    @Inject
-    private List<VirtualRouterElementService> _service;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NETWORK_SERVICE_PROVIDER_ID,
-               type = CommandType.UUID,
-               entityType = ProviderResponse.class,
-               required = true,
-               description = "the network service provider ID of the virtual router element")
-    private Long nspId;
-
-    @Parameter(name = ApiConstants.PROVIDER_TYPE,
-               type = CommandType.UUID,
-               entityType = ProviderResponse.class,
-               description = "The provider type. Supported types are VirtualRouter (default) and VPCVirtualRouter")
-    private String providerType;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public void setNspId(Long nspId) {
-        this.nspId = nspId;
-    }
-
-    public Long getNspId() {
-        return nspId;
-    }
-
-    public Type getProviderType() {
-        if (providerType != null) {
-            if (providerType.equalsIgnoreCase(Type.VirtualRouter.toString())) {
-                return Type.VirtualRouter;
-            } else if (providerType.equalsIgnoreCase(Type.VPCVirtualRouter.toString())) {
-                return Type.VPCVirtualRouter;
-            } else
-                throw new InvalidParameterValueException("Invalid providerType specified");
-        }
-        return Type.VirtualRouter;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Virtual router element Id: " + getEntityId());
-        VirtualRouterProvider result = _service.get(0).getCreatedElement(getEntityId());
-        if (result != null) {
-            VirtualRouterProviderResponse response = _responseGenerator.createVirtualRouterProviderResponse(result);
-            if(response != null) {
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            }
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Virtual Router entity to physical network");
-        }
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        VirtualRouterProvider result = _service.get(0).addElement(getNspId(), getProviderType());
-        if (result != null) {
-            setEntityId(result.getId());
-            setEntityUuid(result.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Virtual Router entity to physical network");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_SERVICE_PROVIDER_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Adding physical network ServiceProvider Virtual Router: " + getEntityId();
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java
deleted file mode 100644
index 4513e2e..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/router/DestroyRouterCmd.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.router;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "destroyRouter", description = "Destroys a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DestroyRouterCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DestroyRouterCmd.class.getName());
-    private static final String s_name = "destroyrouterresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
-    private Long id;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
-        if (router != null) {
-            return router.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_ROUTER_DESTROY;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "destroying router: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.DomainRouter;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
-        CallContext ctx = CallContext.current();
-        ctx.setEventDetails("Router Id: " + getId());
-
-        VirtualRouter result = _routerService.destroyRouter(getId(), ctx.getCallingAccount(), ctx.getCallingUserId());
-        if (result != null) {
-            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy router");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java
deleted file mode 100644
index 4b138f3..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/router/RebootRouterCmd.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.router;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "rebootRouter", description = "Starts a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class RebootRouterCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RebootRouterCmd.class.getName());
-    private static final String s_name = "rebootrouterresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
-        if (router != null) {
-            return router.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_ROUTER_REBOOT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "rebooting router: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.DomainRouter;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        CallContext.current().setEventDetails("Router Id: " + getId());
-        VirtualRouter result = _routerService.rebootRouter(getId(), true);
-        if (result != null) {
-            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
-            response.setResponseName("router");
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot router");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java
deleted file mode 100644
index 173833c..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/router/StartRouterCmd.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.router;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "startRouter", responseObject = DomainRouterResponse.class, description = "Starts a router.", entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class StartRouterCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StartRouterCmd.class.getName());
-    private static final String s_name = "startrouterresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "router";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
-        if (router != null) {
-            return router.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_ROUTER_START;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "starting router: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.DomainRouter;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        CallContext.current().setEventDetails("Router Id: " + getId());
-        VirtualRouter result = null;
-        VirtualRouter router = _routerService.findRouter(getId());
-        if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) {
-            throw new InvalidParameterValueException("Can't find router by id");
-        } else {
-            result = _routerService.startRouter(getId());
-        }
-        if (result != null) {
-            DomainRouterResponse routerResponse = _responseGenerator.createDomainRouterResponse(result);
-            routerResponse.setResponseName(getCommandName());
-            setResponseObject(routerResponse);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start router");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java
deleted file mode 100644
index 2592cae..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/router/StopRouterCmd.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.router;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "stopRouter", description = "Stops a router.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class StopRouterCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StopRouterCmd.class.getName());
-    private static final String s_name = "stoprouterresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the router")
-    private Long id;
-
-    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM. The caller knows the VM is stopped.")
-    private Boolean forced;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualRouter router = _entityMgr.findById(VirtualRouter.class, getId());
-        if (router != null) {
-            return router.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_ROUTER_STOP;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "stopping router: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.DomainRouter;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    public boolean isForced() {
-        return (forced != null) ? forced : false;
-    }
-
-    @Override
-    public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
-        CallContext.current().setEventDetails("Router Id: " + getId());
-        VirtualRouter result = null;
-        VirtualRouter router = _routerService.findRouter(getId());
-        if (router == null || router.getRole() != Role.VIRTUAL_ROUTER) {
-            throw new InvalidParameterValueException("Can't find router by id");
-        } else {
-            result = _routerService.stopRouter(getId(), isForced());
-        }
-
-        if (result != null) {
-            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop router");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
deleted file mode 100644
index 47fa965..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmd.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.storage;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-
-import com.cloud.storage.StoragePool;
-import com.cloud.utils.Pair;
-
-@APICommand(name = "findStoragePoolsForMigration", description = "Lists storage pools available for migration of a volume.", responseObject = StoragePoolResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class FindStoragePoolsForMigrationCmd extends BaseListCmd {
-    public static final Logger s_logger = Logger.getLogger(FindStoragePoolsForMigrationCmd.class.getName());
-
-    private static final String s_name = "findstoragepoolsformigrationresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the volume")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.StoragePool;
-    }
-
-    @Override
-    public void execute() {
-        Pair<List<? extends StoragePool>, List<? extends StoragePool>> pools = _mgr.listStoragePoolsForMigrationOfVolume(getId());
-        ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
-        List<StoragePoolResponse> poolResponses = new ArrayList<StoragePoolResponse>();
-
-        List<? extends StoragePool> allPools = pools.first();
-        List<? extends StoragePool> suitablePoolList = pools.second();
-        for (StoragePool pool : allPools) {
-            StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
-            Boolean suitableForMigration = false;
-            for (StoragePool suitablePool : suitablePoolList) {
-                if (suitablePool.getId() == pool.getId()) {
-                    suitableForMigration = true;
-                    break;
-                }
-            }
-            poolResponse.setSuitableForMigration(suitableForMigration);
-            poolResponse.setObjectName("storagepool");
-            poolResponses.add(poolResponse);
-        }
-
-        response.setResponses(poolResponses);
-        response.setResponseName(getCommandName());
-        this.setResponseObject(response);
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java
deleted file mode 100644
index 47dfe8b..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/DestroySystemVmCmd.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "destroySystemVm", responseObject = SystemVmResponse.class, description = "Destroyes a system virtual machine.", entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DestroySystemVmCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DestroySystemVmCmd.class.getName());
-
-    private static final String s_name = "destroysystemvmresponse";
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID,
-               type = CommandType.UUID,
-               entityType = SystemVmResponse.class,
-               required = true,
-               description = "The ID of the system virtual machine")
-    private Long id;
-
-    public Long getId() {
-        return id;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "systemvm";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
-        if (type == VirtualMachine.Type.ConsoleProxy) {
-            return EventTypes.EVENT_PROXY_DESTROY;
-        } else {
-            return EventTypes.EVENT_SSVM_DESTROY;
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "destroying system vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.SystemVm;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        VirtualMachine instance = _mgr.destroySystemVM(this);
-        if (instance != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to destroy system vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java
deleted file mode 100644
index 97acfe0..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/MigrateSystemVMCmd.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.host.Host;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "migrateSystemVm", description = "Attempts Migration of a system virtual machine to the host specified.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class MigrateSystemVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(MigrateSystemVMCmd.class.getName());
-
-    private static final String s_name = "migratesystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.HOST_ID,
-               type = CommandType.UUID,
-               entityType = HostResponse.class,
-               required = true,
-               description = "destination Host ID to migrate VM to")
-    private Long hostId;
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = SystemVmResponse.class,
-               required = true,
-               description = "the ID of the virtual machine")
-    private Long virtualMachineId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getHostId() {
-        return hostId;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_MIGRATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Attempting to migrate VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId();
-    }
-
-    @Override
-    public void execute() {
-
-        Host destinationHost = _resourceService.getHost(getHostId());
-        if (destinationHost == null) {
-            throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
-        }
-        try {
-            CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId());
-            //FIXME : Should not be calling UserVmService to migrate all types of VMs - need a generic VM layer
-            VirtualMachine migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), destinationHost);
-            if (migratedVm != null) {
-                // return the generic system VM instance response
-                SystemVmResponse response = _responseGenerator.createSystemVmResponse(migratedVm);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate the system vm");
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (ManagementServerException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (VirtualMachineMigrationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java
deleted file mode 100644
index f439ddf4d..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/RebootSystemVmCmd.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "rebootSystemVm", description = "Reboots a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class RebootSystemVmCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RebootSystemVmCmd.class.getName());
-
-    private static final String s_name = "rebootsystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID,
-               type = CommandType.UUID,
-               entityType = SystemVmResponse.class,
-               required = true,
-               description = "The ID of the system virtual machine")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
-        if (type == VirtualMachine.Type.ConsoleProxy) {
-            return EventTypes.EVENT_PROXY_REBOOT;
-        } else {
-            return EventTypes.EVENT_SSVM_REBOOT;
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "rebooting system vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.SystemVm;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        VirtualMachine result = _mgr.rebootSystemVM(this);
-        if (result != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java
deleted file mode 100644
index d53da36..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ScaleSystemVMCmd.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "scaleSystemVm", responseObject = SystemVmResponse.class, description = "Scale the service offering for a system vm (console proxy or secondary storage). "
-        + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ScaleSystemVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
-    private static final String s_name = "changeserviceforsystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SystemVmResponse.class, required = true, description = "The ID of the system vm")
-    private Long id;
-
-    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the service offering ID to apply to the system vm")
-    private Long serviceOfferingId;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
-    private Map<String, String> details;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    public Map<String, String> getDetails() {
-        return details;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("SystemVm Id: " + getId());
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-        }
-
-        VirtualMachine result = null;
-        try {
-            result = _mgr.upgradeSystemVM(this);
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (ManagementServerException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (VirtualMachineMigrationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        }
-        if (result != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade system vm");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_UPGRADE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Upgrading system vm: " + getId() + " to service offering: " + getServiceOfferingId();
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java
deleted file mode 100644
index c456592..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StartSystemVMCmd.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "startSystemVm", responseObject = SystemVmResponse.class, description = "Starts a system virtual machine.", entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class StartSystemVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StartSystemVMCmd.class.getName());
-
-    private static final String s_name = "startsystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID,
-               type = CommandType.UUID,
-               entityType = SystemVmResponse.class,
-               required = true,
-               description = "The ID of the system virtual machine")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "systemvm";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
-        if (type == VirtualMachine.Type.ConsoleProxy) {
-            return EventTypes.EVENT_PROXY_START;
-        } else {
-            return EventTypes.EVENT_SSVM_START;
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "starting system vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.SystemVm;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        VirtualMachine instance = _mgr.startSystemVM(getId());
-        if (instance != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(instance);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to start system vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java
deleted file mode 100644
index d60460c..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/StopSystemVmCmd.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "stopSystemVm", description = "Stops a system VM.", responseObject = SystemVmResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class StopSystemVmCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StopSystemVmCmd.class.getName());
-
-    private static final String s_name = "stopsystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID,
-               type = CommandType.UUID,
-               entityType = SystemVmResponse.class,
-               required = true,
-               description = "The ID of the system virtual machine")
-    private Long id;
-
-    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM.  The caller knows the VM is stopped.")
-    private Boolean forced;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        VirtualMachine.Type type = _mgr.findSystemVMTypeById(getId());
-        if (type == VirtualMachine.Type.ConsoleProxy) {
-            return EventTypes.EVENT_PROXY_STOP;
-        } else {
-            return EventTypes.EVENT_SSVM_STOP;
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "stopping system vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.SystemVm;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    public boolean isForced() {
-        return (forced != null) ? forced : false;
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        VirtualMachine result = _mgr.stopSystemVM(this);
-        if (result != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to stop system vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java
deleted file mode 100644
index 4e0547a..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/UpgradeSystemVMCmd.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.systemvm;
-
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "changeServiceForSystemVm", responseObject = SystemVmResponse.class, description = "Changes the service offering for a system vm (console proxy or secondary storage). "
-        + "The system vm must be in a \"Stopped\" state for " + "this command to take effect.", entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpgradeSystemVMCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
-    private static final String s_name = "changeserviceforsystemvmresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = SystemVmResponse.class, required = true, description = "The ID of the system vm")
-    private Long id;
-
-    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the service offering ID to apply to the system vm")
-    private Long serviceOfferingId;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
-    private Map<String, String> details;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    public Map<String, String> getDetails() {
-        return details;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-        }
-
-        VirtualMachine result = _mgr.upgradeSystemVM(this);
-        if (result != null) {
-            SystemVmResponse response = _responseGenerator.createSystemVmResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to reboot system vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java
deleted file mode 100644
index 51d9c8d..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/template/CreateTemplateCmdByAdmin.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.template;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.template.VirtualMachineTemplate;
-
-@APICommand(name = "createTemplate", responseObject = TemplateResponse.class, description = "Creates a template of a virtual machine. " + "The virtual machine must be in a STOPPED state. "
-        + "A template created from this command is automatically designated as a private template visible to the account that created it.", responseView = ResponseView.Full,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateTemplateCmdByAdmin extends CreateTemplateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateTemplateCmdByAdmin.class.getName());
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Template Id: "+getEntityId()+((getSnapshotId() == null) ? " from volume Id: " + getVolumeId() : " from snapshot Id: " + getSnapshotId()));
-        VirtualMachineTemplate template = null;
-        template = _templateService.createPrivateTemplate(this);
-
-        if (template != null){
-            List<TemplateResponse> templateResponses;
-            if (isBareMetal()) {
-                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Full, template.getId(), vmId);
-            } else {
-                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Full, template.getId(), snapshotId, volumeId, false);
-            }
-            TemplateResponse response = new TemplateResponse();
-            if (templateResponses != null && !templateResponses.isEmpty()) {
-                response = templateResponses.get(0);
-            }
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private template");
-        }
-
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
deleted file mode 100644
index e6ac367..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
+++ /dev/null
@@ -1,155 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.user;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.region.RegionService;
-import org.apache.log4j.Logger;
-
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-
-@APICommand(name = "updateUser", description = "Updates a user account", responseObject = UserResponse.class,
-        requestHasSensitiveInfo = true, responseHasSensitiveInfo = true)
-public class UpdateUserCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
-
-    private static final String s_name = "updateuserresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.USER_API_KEY, type = CommandType.STRING, description = "The API key for the user. Must be specified with userSecretKey")
-    private String apiKey;
-
-    @Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, description = "email")
-    private String email;
-
-    @Parameter(name = ApiConstants.FIRSTNAME, type = CommandType.STRING, description = "first name")
-    private String firstname;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserResponse.class, required = true, description = "User uuid")
-    private Long id;
-
-    @Parameter(name = ApiConstants.LASTNAME, type = CommandType.STRING, description = "last name")
-    private String lastname;
-
-    @Parameter(name = ApiConstants.PASSWORD,
-            type = CommandType.STRING,
-            description = "Clear text password (default hashed to SHA256SALT). If you wish to use any other hasing algorithm, you would need to write a custom authentication adapter. Can't be passed when command is executed via integration.api.port",
-            acceptedOnAdminPort = false)
-    private String password;
-
-
-    @Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userSecretKey")
-    private String secretKey;
-
-    @Parameter(name = ApiConstants.TIMEZONE,
-               type = CommandType.STRING,
-               description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
-    private String timezone;
-
-    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "Unique username")
-    private String username;
-
-    @Inject
-    RegionService _regionService;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getApiKey() {
-        return apiKey;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public String getFirstname() {
-        return firstname;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getLastname() {
-        return lastname;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public String getSecretKey() {
-        return secretKey;
-    }
-
-    public String getTimezone() {
-        return timezone;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        User user = _entityMgr.findById(User.class, getId());
-        if (user != null) {
-            return user.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("UserId: " + getId());
-        UserAccount user = _regionService.updateUser(this);
-
-        if (user != null) {
-            UserResponse response = _responseGenerator.createUserResponse(user);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update user");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java
deleted file mode 100644
index d4f2d5a..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vlan/ListVlanIpRangesCmd.java
+++ /dev/null
@@ -1,158 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vlan;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.PodResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.VlanIpRangeResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-
-import com.cloud.dc.Vlan;
-import com.cloud.utils.Pair;
-
-@APICommand(name = "listVlanIpRanges", description = "Lists all VLAN IP ranges.", responseObject = VlanIpRangeResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListVlanIpRangesCmd extends BaseListCmd {
-    public static final Logger s_logger = Logger.getLogger(ListVlanIpRangesCmd.class.getName());
-
-    private static final String s_name = "listvlaniprangesresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT,
-               type = CommandType.STRING,
-               description = "the account with which the VLAN IP range is associated. Must be used with the domainId parameter.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "project who will own the VLAN")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "the domain ID with which the VLAN IP range is associated.  If used with the account parameter, " +
-                   "returns all VLAN IP ranges for that account in the specified domain.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = false, description = "the ID of the VLAN IP range")
-    private Long id;
-
-    @Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, description = "the Pod ID of the VLAN IP range")
-    private Long podId;
-
-    @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "the ID or VID of the VLAN. Default is an \"untagged\" VLAN.")
-    private String vlan;
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the Zone ID of the VLAN IP range")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "network id of the VLAN IP range")
-    private Long networkId;
-
-    @Parameter(name = ApiConstants.FOR_VIRTUAL_NETWORK, type = CommandType.BOOLEAN, description = "true if VLAN is of Virtual type, false if Direct")
-    private Boolean forVirtualNetwork;
-
-    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = PhysicalNetworkResponse.class,
-               description = "physical network id of the VLAN IP range")
-    private Long physicalNetworkId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getPodId() {
-        return podId;
-    }
-
-    public String getVlan() {
-        return vlan;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public Long getNetworkId() {
-        return networkId;
-    }
-
-    public Boolean getForVirtualNetwork() {
-        return forVirtualNetwork;
-    }
-
-    public Long getProjectId() {
-        return projectId;
-    }
-
-    public Long getPhysicalNetworkId() {
-        return physicalNetworkId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute() {
-        Pair<List<? extends Vlan>, Integer> vlans = _mgr.searchForVlans(this);
-        ListResponse<VlanIpRangeResponse> response = new ListResponse<VlanIpRangeResponse>();
-        List<VlanIpRangeResponse> vlanResponses = new ArrayList<VlanIpRangeResponse>();
-        for (Vlan vlan : vlans.first()) {
-            VlanIpRangeResponse vlanResponse = _responseGenerator.createVlanIpRangeResponse(vlan);
-            vlanResponse.setObjectName("vlaniprange");
-            vlanResponses.add(vlanResponse);
-        }
-
-        response.setResponses(vlanResponses, vlans.second());
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java
deleted file mode 100644
index 945f849..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/AddNicToVMCmdByAdmin.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-
-@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class AddNicToVMCmdByAdmin extends AddNicToVMCmd {
-    public static final Logger s_logger = Logger.getLogger(AddNicToVMCmdByAdmin.class);
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Vm Id: " + getVmId() + " Network Id: " + getNetworkId());
-        UserVm result = _userVmService.addNicToVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NIC to vm. Refer to server logs for details.");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java
deleted file mode 100644
index 03bb4c6..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/DeployVMCmdByAdmin.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-
-@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class DeployVMCmdByAdmin extends DeployVMCmd {
-    public static final Logger s_logger = Logger.getLogger(DeployVMCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute(){
-        UserVm result;
-
-        if (getStartVm()) {
-            try {
-                CallContext.current().setEventDetails("Vm Id: "+getEntityId());
-                result = _userVmService.startVirtualMachine(this);
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Exception: ", ex);
-                throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-            } catch (ConcurrentOperationException ex) {
-                s_logger.warn("Exception: ", ex);
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-            } catch (InsufficientCapacityException ex) {
-                StringBuilder message = new StringBuilder(ex.getMessage());
-                if (ex instanceof InsufficientServerCapacityException) {
-                    if(((InsufficientServerCapacityException)ex).isAffinityApplied()){
-                        message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
-                    }
-                }
-                s_logger.info(ex);
-                s_logger.info(message.toString(), ex);
-                throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
-            }
-        } else {
-            result = _userVmService.getUserVm(getEntityId());
-        }
-
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm");
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java
deleted file mode 100644
index 73a80d5..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/DestroyVMCmdByAdmin.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine. Once destroyed, only the administrator can recover it.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false,
-        responseHasSensitiveInfo = true)
-public class DestroyVMCmdByAdmin extends DestroyVMCmd {
-    public static final Logger s_logger = Logger.getLogger(DestroyVMCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
-        CallContext.current().setEventDetails("Vm Id: "+getId());
-        UserVm result = _userVmService.destroyVm(this);
-
-        UserVmResponse response = new UserVmResponse();
-        if (result != null) {
-            List<UserVmResponse> responses = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result);
-            if (responses != null && !responses.isEmpty()) {
-                response = responses.get(0);
-            }
-            response.setResponseName("virtualmachine");
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java
deleted file mode 100644
index 155fcff..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/ExpungeVMCmd.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "expungeVirtualMachine", description = "Expunge a virtual machine. Once expunged, it cannot be recoverd.", responseObject = SuccessResponse.class, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ExpungeVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ExpungeVMCmd.class.getName());
-
-    private static final String s_name = "expungevirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "The ID of the virtual machine")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getId());
-        if (vm != null) {
-            return vm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_EXPUNGE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Expunging vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        try {
-            UserVm result = _userVmService.expungeVm(this.getId());
-
-            if (result != null) {
-                SuccessResponse response = new SuccessResponse(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to expunge vm");
-            }
-        } catch (InvalidParameterValueException ipve) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ipve.getMessage());
-        } catch (CloudRuntimeException cre) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, cre.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java
deleted file mode 100644
index d6d6272..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java
+++ /dev/null
@@ -1,189 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-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.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.host.Host;
-import com.cloud.storage.StoragePool;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "migrateVirtualMachine",
-            description = "Attempts Migration of a VM to a different host or Root volume of the vm to a different storage pool",
-        responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
-            requestHasSensitiveInfo = false,
-            responseHasSensitiveInfo = true)
-public class MigrateVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(MigrateVMCmd.class.getName());
-
-    private static final String s_name = "migratevirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.HOST_ID,
-               type = CommandType.UUID,
-               entityType = HostResponse.class,
-               required = false,
-               description = "Destination Host ID to migrate VM to. Required for live migrating a VM from host to host")
-    private Long hostId;
-
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = UserVmResponse.class,
-               required = true,
-               description = "the ID of the virtual machine")
-    private Long virtualMachineId;
-
-    @Parameter(name = ApiConstants.STORAGE_ID,
-               type = CommandType.UUID,
-               entityType = StoragePoolResponse.class,
-               required = false,
-               description = "Destination storage pool ID to migrate VM volumes to. Required for migrating the root disk volume")
-    private Long storageId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getHostId() {
-        return hostId;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    public Long getStoragePoolId() {
-        return storageId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVm = _entityMgr.findById(UserVm.class, getVirtualMachineId());
-        if (userVm != null) {
-            return userVm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_MIGRATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Attempting to migrate VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId();
-    }
-
-    @Override
-    public void execute() {
-        if (getHostId() == null && getStoragePoolId() == null) {
-            throw new InvalidParameterValueException("Either hostId or storageId must be specified");
-        }
-
-        if (getHostId() != null && getStoragePoolId() != null) {
-            throw new InvalidParameterValueException("Only one of hostId and storageId can be specified");
-        }
-
-        UserVm userVm = _userVmService.getUserVm(getVirtualMachineId());
-        if (userVm == null) {
-            throw new InvalidParameterValueException("Unable to find the VM by id=" + getVirtualMachineId());
-        }
-
-        Host destinationHost = null;
-        if (getHostId() != null) {
-            destinationHost = _resourceService.getHost(getHostId());
-            if (destinationHost == null) {
-                throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id=" + getHostId());
-            }
-            if (destinationHost.getType() != Host.Type.Routing) {
-                throw new InvalidParameterValueException("The specified host(" + destinationHost.getName() + ") is not suitable to migrate the VM, please specify another one");
-            }
-            CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId());
-        }
-
-        StoragePool destStoragePool = null;
-        if (getStoragePoolId() != null) {
-            destStoragePool = _storageService.getStoragePool(getStoragePoolId());
-            if (destStoragePool == null) {
-                throw new InvalidParameterValueException("Unable to find the storage pool to migrate the VM");
-            }
-            CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to storage pool Id: " + getStoragePoolId());
-        }
-
-        try {
-            VirtualMachine migratedVm = null;
-            if (getHostId() != null) {
-                migratedVm = _userVmService.migrateVirtualMachine(getVirtualMachineId(), destinationHost);
-            } else if (getStoragePoolId() != null) {
-                migratedVm = _userVmService.vmStorageMigration(getVirtualMachineId(), destStoragePool);
-            }
-            if (migratedVm != null) {
-                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", (UserVm)migratedVm).get(0);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vm");
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (ManagementServerException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (VirtualMachineMigrationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java
deleted file mode 100644
index 32000c6..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java
+++ /dev/null
@@ -1,177 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.host.Host;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "migrateVirtualMachineWithVolume",
-            description = "Attempts Migration of a VM with its volumes to a different host",
-        responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
-            requestHasSensitiveInfo = false,
-            responseHasSensitiveInfo = true)
-public class MigrateVirtualMachineWithVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(MigrateVMCmd.class.getName());
-
-    private static final String s_name = "migratevirtualmachinewithvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.HOST_ID,
-               type = CommandType.UUID,
-               entityType = HostResponse.class,
-               required = true,
-               description = "Destination Host ID to migrate VM to.")
-    private Long hostId;
-
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = UserVmResponse.class,
-               required = true,
-               description = "the ID of the virtual machine")
-    private Long virtualMachineId;
-
-    @Parameter(name = ApiConstants.MIGRATE_TO,
-               type = CommandType.MAP,
-               required = false,
-               description = "Storage to pool mapping. This parameter specifies the mapping between a volume and a pool where you want to migrate that volume. Format of this " +
-               "parameter: migrateto[volume-index].volume=<uuid>&migrateto[volume-index].pool=<uuid>Where, [volume-index] indicates the index to identify the volume that you " +
-               "want to migrate, volume=<uuid> indicates the UUID of the volume that you want to migrate, and pool=<uuid> indicates the UUID of the pool where you want to " +
-               "migrate the volume. Example: migrateto[0].volume=<71f43cd6-69b0-4d3b-9fbc-67f50963d60b>&migrateto[0].pool=<a382f181-3d2b-4413-b92d-b8931befa7e1>&" +
-               "migrateto[1].volume=<88de0173-55c0-4c1c-a269-83d0279eeedf>&migrateto[1].pool=<95d6e97c-6766-4d67-9a30-c449c15011d1>&migrateto[2].volume=" +
-               "<1b331390-59f2-4796-9993-bf11c6e76225>&migrateto[2].pool=<41fdb564-9d3b-447d-88ed-7628f7640cbc>")
-    private Map migrateVolumeTo;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getHostId() {
-        return hostId;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    public Map<String, String> getVolumeToPool() {
-        Map<String, String> volumeToPoolMap = new HashMap<String, String>();
-        if (migrateVolumeTo != null && !migrateVolumeTo.isEmpty()) {
-            Collection<?> allValues = migrateVolumeTo.values();
-            Iterator<?> iter = allValues.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> volumeToPool = (HashMap<String, String>)iter.next();
-                String volume = volumeToPool.get("volume");
-                String pool = volumeToPool.get("pool");
-                volumeToPoolMap.put(volume, pool);
-            }
-        }
-        return volumeToPoolMap;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVm = _entityMgr.findById(UserVm.class, getVirtualMachineId());
-        if (userVm != null) {
-            return userVm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_MIGRATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Attempting to migrate VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId();
-    }
-
-    @Override
-    public void execute() {
-        UserVm userVm = _userVmService.getUserVm(getVirtualMachineId());
-        if (userVm == null) {
-            throw new InvalidParameterValueException("Unable to find the VM by id=" + getVirtualMachineId());
-        }
-
-        Host destinationHost = _resourceService.getHost(getHostId());
-        if (destinationHost == null) {
-            throw new InvalidParameterValueException("Unable to find the host to migrate the VM, host id =" + getHostId());
-        }
-
-        try {
-            VirtualMachine migratedVm = _userVmService.migrateVirtualMachineWithVolume(getVirtualMachineId(), destinationHost, getVolumeToPool());
-            if (migratedVm != null) {
-                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", (UserVm)migratedVm).get(0);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate vm");
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (ManagementServerException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        } catch (VirtualMachineMigrationException e) {
-            s_logger.warn("Exception: ", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java
deleted file mode 100644
index e0c3668..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/RebootVMCmdByAdmin.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RebootVMCmdByAdmin extends RebootVMCmd {
-    public static final Logger s_logger = Logger.getLogger(RebootVMCmdByAdmin.class.getName());
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
-        CallContext.current().setEventDetails("Vm Id: "+getId());
-        UserVm result;
-        result = _userVmService.rebootVirtualMachine(this);
-
-        if (result !=null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot vm instance");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java
deleted file mode 100644
index ff1c54c..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/RemoveNicFromVMCmdByAdmin.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RemoveNicFromVMCmdByAdmin extends RemoveNicFromVMCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmdByAdmin.class);
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId());
-        UserVm result = _userVmService.removeNicFromVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NIC from vm, see error log for details");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java
deleted file mode 100644
index 9a741b6..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/RestoreVMCmdByAdmin.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false,
-        responseHasSensitiveInfo = true)
-public class RestoreVMCmdByAdmin extends RestoreVMCmd {
-    public static final Logger s_logger = Logger.getLogger(RestoreVMCmdByAdmin.class);
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-            ResourceAllocationException {
-        UserVm result;
-        CallContext.current().setEventDetails("Vm Id: " + getVmId());
-        result = _userVmService.restoreVM(this);
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restore vm " + getVmId());
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java
deleted file mode 100644
index f968835..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/StartVMCmdByAdmin.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class StartVMCmdByAdmin extends StartVMCmd {
-    public static final Logger s_logger = Logger.getLogger(StartVMCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ResourceAllocationException {
-        try {
-            CallContext.current().setEventDetails("Vm Id: " + getId());
-
-            UserVm result ;
-            result = _userVmService.startVirtualMachine(this);
-
-            if (result != null) {
-                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start a vm");
-            }
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (StorageUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ExecutionException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (InsufficientCapacityException ex) {
-            StringBuilder message = new StringBuilder(ex.getMessage());
-            if (ex instanceof InsufficientServerCapacityException) {
-                if (((InsufficientServerCapacityException) ex).isAffinityApplied()) {
-                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
-                }
-            }
-            s_logger.info(ex);
-            s_logger.info(message.toString(), ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java
deleted file mode 100644
index 4cd1418..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/StopVMCmdByAdmin.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.StopVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class StopVMCmdByAdmin extends StopVMCmd {
-    public static final Logger s_logger = Logger.getLogger(StopVMCmdByAdmin.class.getName());
-
-
-
-    @Override
-    public void execute() throws ServerApiException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        UserVm result;
-
-        result = _userVmService.stopVirtualMachine(getId(), isForced());
-
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java
deleted file mode 100644
index 9a06309..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateDefaultNicForVMCmdByAdmin.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpdateDefaultNicForVMCmdByAdmin extends UpdateDefaultNicForVMCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmdByAdmin.class);
-
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId());
-        UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set default nic for VM. Refer to server logs for details.");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java
deleted file mode 100644
index fcafef8..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/UpdateVMCmdByAdmin.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-
-@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
-        "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
-        "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpdateVMCmdByAdmin extends UpdateVMCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateVMCmdByAdmin.class.getName());
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("Vm Id: "+getId());
-        UserVm result = _userVmService.updateVirtualMachine(this);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java
deleted file mode 100644
index 6df400a..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vm/UpgradeVMCmdByAdmin.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " +
-                                            "The virtual machine must be in a \"Stopped\" state for " +
-        "this command to take effect.", responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpgradeVMCmdByAdmin extends UpgradeVMCmd {
-    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute() throws ResourceAllocationException{
-        CallContext.current().setEventDetails("Vm Id: "+getId());
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-        }
-
-        UserVm result = _userVmService.upgradeVirtualMachine(this);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java
deleted file mode 100644
index facce1e..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vmsnapshot/RevertToVMSnapshotCmdByAdmin.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vmsnapshot;
-
-import java.util.logging.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.uservm.UserVm;
-
-@APICommand(name = "revertToVMSnapshot", description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since = "4.2.0", responseView = ResponseView.Full,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RevertToVMSnapshotCmdByAdmin extends RevertToVMSnapshotCmd {
-    public static final Logger s_logger = Logger
-            .getLogger(RevertToVMSnapshotCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute() throws  ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
-        CallContext.current().setEventDetails(
-                "vmsnapshot id: " + getVmSnapShotId());
-        UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Full,
-                    "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,"Failed to revert VM snapshot");
-        }
-    }
-
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java
deleted file mode 100644
index c51c1e2..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/AttachVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.storage.Volume;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class AttachVolumeCmdByAdmin extends AttachVolumeCmd {
-    public static final Logger s_logger = Logger.getLogger(AttachVolumeCmdByAdmin.class.getName());
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Volume Id: "+getId()+" VmId: "+getVirtualMachineId());
-        Volume result = _volumeService.attachVolumeToVM(this);
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to attach volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java
deleted file mode 100644
index 8ff3993..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/CreateVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Full, entityType = {
-        Volume.class, VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateVolumeCmdByAdmin extends CreateVolumeCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateVolumeCmdByAdmin.class.getName());
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Volume Id: "+getEntityId()+((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId()));
-        Volume volume = _volumeService.createVolume(this);
-        if (volume != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, volume);
-            //FIXME - have to be moved to ApiResponseHelper
-            if (getSnapshotId() != null) {
-                Snapshot snap = _entityMgr.findById(Snapshot.class, getSnapshotId());
-                if (snap != null) {
-                    response.setSnapshotId(snap.getUuid()); // if the volume was
-                    // created from a
-                    // snapshot,
-                    // snapshotId will
-                    // be set so we pass
-                    // it back in the
-                    // response
-                }
-            }
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java
deleted file mode 100644
index 353a068..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/DetachVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.storage.Volume;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DetachVolumeCmdByAdmin extends DetachVolumeCmd {
-    public static final Logger s_logger = Logger.getLogger(DetachVolumeCmdByAdmin.class.getName());
-
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Volume Id: "+getId()+" VmId: "+getVirtualMachineId());
-        Volume result = _volumeService.detachVolumeFromVM(this);
-        if (result != null){
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
-            response.setResponseName("volume");
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to detach volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java
deleted file mode 100644
index c312cfc..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/MigrateVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-
-import com.cloud.storage.Volume;
-
-
-@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Full, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class MigrateVolumeCmdByAdmin extends MigrateVolumeCmd {
-
-
-    @Override
-    public void execute(){
-        Volume result;
-
-        result = _volumeService.migrateVolume(this);
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume");
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java
deleted file mode 100644
index 6ef142f..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/ResizeVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.storage.Volume;
-
-
-@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ResizeVolumeCmdByAdmin extends ResizeVolumeCmd {
-
-    @Override
-    public void execute() throws ResourceAllocationException{
-        Volume volume = null;
-        try {
-            CallContext.current().setEventDetails("Volume Id: " + getEntityId() + " to size " + getSize() + "G");
-            volume = _volumeService.resizeVolume(this);
-        } catch (InvalidParameterValueException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
-        }
-
-        if (volume != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, volume);
-            //FIXME - have to be moved to ApiResponseHelper
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to resize volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.java
deleted file mode 100644
index 6b110e5..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/volume/UpdateVolumeCmdByAdmin.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.volume;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.storage.Volume;
-
-@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Full, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateVolumeCmdByAdmin extends UpdateVolumeCmd {
-
-    @Override
-    public void execute(){
-        CallContext.current().setEventDetails("Volume Id: "+getId());
-        Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(),
-                getCustomId(), getEntityOwnerId(), getChainInfo());
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java
deleted file mode 100644
index 8606c32..0000000
--- a/api/src/org/apache/cloudstack/api/command/admin/vpc/UpdateVPCCmdByAdmin.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.vpc;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.vpc.UpdateVPCCmd;
-import org.apache.cloudstack.api.response.VpcResponse;
-
-import com.cloud.network.vpc.Vpc;
-
-@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Full, entityType = {Vpc.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateVPCCmdByAdmin extends UpdateVPCCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateVPCCmdByAdmin.class.getName());
-
-    @Override
-    public void execute(){
-        Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), getDisplayVpc());
-        if (result != null) {
-            VpcResponse response = _responseGenerator.createVpcResponse(ResponseView.Full, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VPC");
-        }
-    }
-
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java
deleted file mode 100644
index 15072ca..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java
+++ /dev/null
@@ -1,350 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.address;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.RegionResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.projects.Project;
-import com.cloud.user.Account;
-
-@APICommand(name = "associateIpAddress", description = "Acquires and associates a public IP to an account. Either of the parameters are required, i.e. either zoneId, or networkId, or vpcId  ", responseObject = IPAddressResponse.class, responseView = ResponseView.Restricted,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(AssociateIPAddrCmd.class.getName());
-    private static final String s_name = "associateipaddressresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account to associate with this IP address")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "the ID of the domain to associate with this IP address")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-               description = "the ID of the availability zone you want to acquire an public IP address from")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = NetworkResponse.class,
-               description = "The network this IP address should be associated to.")
-    private Long networkId;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Deploy VM for the project")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "the VPC you want the IP address to "
-        + "be associated with")
-    private Long vpcId;
-
-    @Parameter(name = ApiConstants.IS_PORTABLE, type = BaseCmd.CommandType.BOOLEAN, description = "should be set to true "
-        + "if public IP is required to be transferable across zones, if not specified defaults to false")
-    private Boolean isPortable;
-
-    @Parameter(name = ApiConstants.REGION_ID,
-               type = CommandType.INTEGER,
-               entityType = RegionResponse.class,
-               required = false,
-               description = "region ID from where portable IP is to be associated.")
-    private Integer regionId;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the IP to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getAccountName() {
-        if (accountName != null) {
-            return accountName;
-        }
-        return CallContext.current().getCallingAccount().getAccountName();
-    }
-
-    public long getDomainId() {
-        if (domainId != null) {
-            return domainId;
-        }
-        return CallContext.current().getCallingAccount().getDomainId();
-    }
-
-    private long getZoneId() {
-        if (zoneId != null) {
-            return zoneId;
-        } else if (vpcId != null) {
-            Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
-            if (vpc != null) {
-                return vpc.getZoneId();
-            }
-        } else if (networkId != null) {
-            Network ntwk = _entityMgr.findById(Network.class, networkId);
-            if (ntwk != null) {
-                return ntwk.getDataCenterId();
-            }
-        }
-
-        throw new InvalidParameterValueException("Unable to figure out zone to assign IP to."
-                + " Please specify either zoneId, or networkId, or vpcId in the call");
-    }
-
-    public Long getVpcId() {
-        return vpcId;
-    }
-
-    public boolean isPortable() {
-        if (isPortable == null) {
-            return false;
-        } else {
-            return isPortable;
-        }
-    }
-
-    public Integer getRegionId() {
-        return regionId;
-    }
-
-    public Long getNetworkId() {
-        if (vpcId != null) {
-            return null;
-        }
-
-        if (networkId != null) {
-            return networkId;
-        }
-        Long zoneId = getZoneId();
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-        if (zone.getNetworkType() == NetworkType.Advanced) {
-            List<? extends Network> networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), _accountService.getAccount(getEntityOwnerId()));
-            if (networks.size() == 0) {
-                String domain = _domainService.getDomain(getDomainId()).getName();
-                throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" +
-                    zone.getName());
-            }
-
-            if (networks.size() < 1) {
-                throw new InvalidParameterValueException("Account doesn't have any isolated networks in the zone");
-            } else if (networks.size() > 1) {
-                throw new InvalidParameterValueException("Account has more than one isolated network in the zone");
-            }
-
-            return networks.get(0).getId();
-        } else {
-            Network defaultGuestNetwork = _networkService.getExclusiveGuestNetwork(zoneId);
-            if (defaultGuestNetwork == null) {
-                throw new InvalidParameterValueException("Unable to find a default guest network for account " + getAccountName() + " in domain ID=" + getDomainId());
-            } else {
-                return defaultGuestNetwork.getId();
-            }
-        }
-    }
-
-    @Deprecated
-    public Boolean getDisplayIp() {
-        return display;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if(display == null)
-            return true;
-        else
-            return display;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-        if (accountName != null && domainId != null) {
-            Account account = _accountService.finalizeOwner(caller, accountName, domainId, projectId);
-            return account.getId();
-        } else if (projectId != null) {
-            Project project = _projectService.getProject(projectId);
-            if (project != null) {
-                if (project.getState() == Project.State.Active) {
-                    return project.getProjectAccountId();
-                } else {
-                    throw new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
-                        " as it's no longer active");
-                }
-            } else {
-                throw new InvalidParameterValueException("Unable to find project by ID");
-            }
-        } else if (networkId != null) {
-            Network network = _networkService.getNetwork(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find network by network id specified");
-            }
-
-            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-
-            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-            if (zone.getNetworkType() == NetworkType.Basic && offering.getElasticIp() && offering.getElasticLb()) {
-                // Since the basic zone network is owned by 'Root' domain, domain access checkers will fail for the
-                // accounts in non-root domains while acquiring public IP. So add an exception for the 'Basic' zone
-                // shared network with EIP/ELB service.
-                return caller.getAccountId();
-            }
-
-            return network.getAccountId();
-        } else if (vpcId != null) {
-            Vpc vpc = _entityMgr.findById(Vpc.class, getVpcId());
-            if (vpc == null) {
-                throw new InvalidParameterValueException("Can't find enabled VPC by ID specified");
-            }
-            return vpc.getAccountId();
-        }
-
-        return caller.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        if (isPortable()) {
-            return EventTypes.EVENT_PORTABLE_IP_ASSIGN;
-        } else {
-            return EventTypes.EVENT_NET_IP_ASSIGN;
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "associating IP to network ID: " + getNetworkId() + " in zone " + getZoneId();
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "addressinfo";
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        try {
-            IpAddress ip = null;
-
-            if (!isPortable()) {
-                ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId(), getDisplayIp());
-            } else {
-                ip = _networkService.allocatePortableIP(_accountService.getAccount(getEntityOwnerId()), 1, getZoneId(), getNetworkId(), getVpcId());
-            }
-
-            if (ip != null) {
-                setEntityId(ip.getId());
-                setEntityUuid(ip.getUuid());
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to allocate IP address");
-            }
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (InsufficientAddressCapacityException ex) {
-            s_logger.info(ex);
-            s_logger.trace(ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
-        }
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
-        CallContext.current().setEventDetails("IP ID: " + getEntityId());
-
-        IpAddress result = null;
-
-        if (getVpcId() != null) {
-            result = _vpcService.associateIPToVpc(getEntityId(), getVpcId());
-        } else if (getNetworkId() != null) {
-            result = _networkService.associateIPToNetwork(getEntityId(), getNetworkId());
-        }
-
-        if (result != null) {
-            IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(ResponseView.Restricted, result);
-            ipResponse.setResponseName(getCommandName());
-            setResponseObject(ipResponse);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign IP address");
-        }
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.networkSyncObject;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        return getNetworkId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IpAddress;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
deleted file mode 100644
index 0a0e7a1..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
+++ /dev/null
@@ -1,200 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.address;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.VlanIpRangeResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-
-import com.cloud.network.IpAddress;
-import com.cloud.utils.Pair;
-
-@APICommand(name = "listPublicIpAddresses", description = "Lists all public IP addresses", responseObject = IPAddressResponse.class, responseView = ResponseView.Restricted,
- requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, entityType = { IpAddress.class })
-public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd {
-    public static final Logger s_logger = Logger.getLogger(ListPublicIpAddressesCmd.class.getName());
-
-    private static final String s_name = "listpublicipaddressesresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ALLOCATED_ONLY, type = CommandType.BOOLEAN, description = "limits search results to allocated public IP addresses")
-    private Boolean allocatedOnly;
-
-    @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "lists all public IP addresses by state")
-    private String state;
-
-    @Parameter(name = ApiConstants.FOR_VIRTUAL_NETWORK, type = CommandType.BOOLEAN, description = "the virtual network for the IP address")
-    private Boolean forVirtualNetwork;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IPAddressResponse.class, description = "lists IP address by ID")
-    private Long id;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "lists the specified IP address")
-    private String ipAddress;
-
-    @Parameter(name = ApiConstants.VLAN_ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, description = "lists all public IP addresses by VLAN ID")
-    private Long vlanId;
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "lists all public IP addresses by zone ID")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.FOR_LOAD_BALANCING, type = CommandType.BOOLEAN, description = "list only IPs used for load balancing")
-    private Boolean forLoadBalancing;
-
-    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = PhysicalNetworkResponse.class,
-               description = "lists all public IP addresses by physical network ID")
-    private Long physicalNetworkId;
-
-    @Parameter(name = ApiConstants.ASSOCIATED_NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = NetworkResponse.class,
-               description = "lists all public IP addresses associated to the network specified")
-    private Long associatedNetworkId;
-
-    @Parameter(name = ApiConstants.IS_SOURCE_NAT, type = CommandType.BOOLEAN, description = "list only source NAT IP addresses")
-    private Boolean isSourceNat;
-
-    @Parameter(name = ApiConstants.IS_STATIC_NAT, type = CommandType.BOOLEAN, description = "list only static NAT IP addresses")
-    private Boolean isStaticNat;
-
-    @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List IPs belonging to the VPC")
-    private Long vpcId;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-    public Long getId() {
-        return id;
-    }
-
-    public Boolean isAllocatedOnly() {
-        return allocatedOnly;
-    }
-
-    public Boolean isForVirtualNetwork() {
-        return forVirtualNetwork;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public Long getVlanId() {
-        return vlanId;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public Long getPhysicalNetworkId() {
-        return physicalNetworkId;
-    }
-
-    public Long getAssociatedNetworkId() {
-        return associatedNetworkId;
-    }
-
-    public Boolean getIsSourceNat() {
-        return isSourceNat;
-    }
-
-    public Boolean getIsStaticNat() {
-        return isStaticNat;
-    }
-
-    public Long getVpcId() {
-        return vpcId;
-    }
-
-    @Override
-    public Boolean getDisplay() {
-        if (display != null) {
-            return display;
-        }
-        return super.getDisplay();
-    }
-
-    public Boolean isForLoadBalancing() {
-        return forLoadBalancing;
-    }
-
-    public Boolean getForVirtualNetwork() {
-        return forVirtualNetwork;
-    }
-
-    public Boolean getForLoadBalancing() {
-        return forLoadBalancing;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute() {
-        Pair<List<? extends IpAddress>, Integer> result = _mgr.searchForIPAddresses(this);
-        ListResponse<IPAddressResponse> response = new ListResponse<IPAddressResponse>();
-        List<IPAddressResponse> ipAddrResponses = new ArrayList<IPAddressResponse>();
-        for (IpAddress ipAddress : result.first()) {
-            IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(ResponseView.Restricted, ipAddress);
-            ipResponse.setObjectName("publicipaddress");
-            ipAddrResponses.add(ipResponse);
-        }
-
-        response.setResponses(ipAddrResponses, result.second());
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IpAddress;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
deleted file mode 100644
index fab7d9e..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
+++ /dev/null
@@ -1,362 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.firewall;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.FirewallResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.user.Account;
-import com.cloud.utils.net.NetUtils;
-
-@APICommand(name = "createFirewallRule", description = "Creates a firewall rule for a given IP address", responseObject = FirewallResponse.class, entityType = {FirewallRule.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule {
-    public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName());
-
-    private static final String s_name = "createfirewallruleresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.IP_ADDRESS_ID,
-               type = CommandType.UUID,
-               entityType = IPAddressResponse.class,
-               required = true,
-               description = "the IP address id of the port forwarding rule")
-    private Long ipAddressId;
-
-    @Parameter(name = ApiConstants.PROTOCOL,
-               type = CommandType.STRING,
-               required = true,
-               description = "the protocol for the firewall rule. Valid values are TCP/UDP/ICMP.")
-    private String protocol;
-
-    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of firewall rule")
-    private Integer publicStartPort;
-
-    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of firewall rule")
-    private Integer publicEndPort;
-
-    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to forward traffic from")
-    private List<String> cidrlist;
-
-    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
-    private Integer icmpType;
-
-    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message")
-    private Integer icmpCode;
-
-    @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "type of firewallrule: system/user")
-    private String type;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-
-    public Long getIpAddressId() {
-        return ipAddressId;
-    }
-
-    @Override
-    public String getProtocol() {
-        return protocol.trim();
-    }
-
-    @Override
-    public List<String> getSourceCidrList() {
-        if (cidrlist != null) {
-            return cidrlist;
-        } else {
-            List<String> oneCidrList = new ArrayList<String>();
-            oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
-            return oneCidrList;
-        }
-
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public void setSourceCidrList(List<String> cidrs) {
-        cidrlist = cidrs;
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException {
-        CallContext callerContext = CallContext.current();
-        boolean success = false;
-        FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
-        try {
-            CallContext.current().setEventDetails("Rule ID: " + getEntityId());
-            success = _firewallService.applyIngressFwRules(rule.getSourceIpAddressId(), callerContext.getCallingAccount());
-
-            // State is different after the rule is applied, so get new object here
-            rule = _entityMgr.findById(FirewallRule.class, getEntityId());
-            FirewallResponse fwResponse = new FirewallResponse();
-            if (rule != null) {
-                fwResponse = _responseGenerator.createFirewallResponse(rule);
-                setResponseObject(fwResponse);
-            }
-            fwResponse.setResponseName(getCommandName());
-        } finally {
-            if (!success || rule == null) {
-                _firewallService.revokeIngressFwRule(getEntityId(), true);
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create firewall rule");
-            }
-        }
-    }
-
-    @Override
-    public long getId() {
-        throw new UnsupportedOperationException("database ID can only provided by VO objects");
-    }
-
-    @Override
-    public String getXid() {
-        // FIXME: We should allow for end user to specify Xid.
-        return null;
-    }
-
-    @Override
-    public String getUuid() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Long getSourceIpAddressId() {
-        return ipAddressId;
-    }
-
-    @Override
-    public Integer getSourcePortStart() {
-        if (publicStartPort != null) {
-            return publicStartPort;
-        }
-        return null;
-    }
-
-    @Override
-    public Integer getSourcePortEnd() {
-        if (publicEndPort == null) {
-            if (publicStartPort != null) {
-                return publicStartPort;
-            }
-        } else {
-            return publicEndPort;
-        }
-
-        return null;
-    }
-
-    @Override
-    public Purpose getPurpose() {
-        return Purpose.Firewall;
-    }
-
-    @Override
-    public State getState() {
-        throw new UnsupportedOperationException("Should never call me to find the state");
-    }
-
-    @Override
-    public long getNetworkId() {
-        IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
-        Long ntwkId = null;
-
-        if (ip.getAssociatedWithNetworkId() != null) {
-            ntwkId = ip.getAssociatedWithNetworkId();
-        }
-
-        if (ntwkId == null) {
-            throw new InvalidParameterValueException("Unable to create firewall rule for the IP address ID=" + ipAddressId +
-                    " as IP is not associated with any network and no networkId is passed in");
-        }
-        return ntwkId;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public long getDomainId() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ip.getDomainId();
-    }
-
-    @Override
-    public void create() {
-        if (getSourceCidrList() != null) {
-            for (String cidr : getSourceCidrList()) {
-                if (!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source CIDRs formatting error " + cidr);
-                }
-            }
-        }
-        try {
-            FirewallRule result = _firewallService.createIngressFirewallRule(this);
-            if (result != null) {
-                setEntityId(result.getId());
-                setEntityUuid(result.getUuid());
-            }
-        } catch (NetworkRuleConflictException ex) {
-            s_logger.info("Network rule conflict: " + ex.getMessage());
-            s_logger.trace("Network Rule Conflict: ", ex);
-            throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_FIREWALL_OPEN;
-    }
-
-    @Override
-    public String getEventDescription() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ("Creating firewall rule for IP: " + ip.getAddress() + " for protocol:" + getProtocol());
-    }
-
-    @Override
-    public long getAccountId() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ip.getAccountId();
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.networkSyncObject;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        return getIp().getAssociatedWithNetworkId();
-    }
-
-    private IpAddress getIp() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        if (ip == null) {
-            throw new InvalidParameterValueException("Unable to find IP address by ID " + ipAddressId);
-        }
-        return ip;
-    }
-
-    @Override
-    public Integer getIcmpCode() {
-        if (icmpCode != null) {
-            return icmpCode;
-        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
-            return -1;
-        }
-        return null;
-    }
-
-    @Override
-    public Integer getIcmpType() {
-        if (icmpType != null) {
-            return icmpType;
-        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
-                return -1;
-
-        }
-        return null;
-    }
-
-    @Override
-    public Long getRelated() {
-        return null;
-    }
-
-    @Override
-    public FirewallRuleType getType() {
-        if (type != null && type.equalsIgnoreCase("system")) {
-            return FirewallRuleType.System;
-        } else {
-            return FirewallRuleType.User;
-        }
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.FirewallRule;
-    }
-
-    @Override
-    public TrafficType getTrafficType() {
-        return FirewallRule.TrafficType.Ingress;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if (display != null) {
-            return display;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public List<String> getDestinationCidrList(){
-        return null;
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return FirewallRule.class;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
deleted file mode 100644
index ea0cb00..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
+++ /dev/null
@@ -1,451 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.firewall;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.FirewallRuleResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.user.Account;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.VirtualMachine;
-
-
-@APICommand(name = "createPortForwardingRule", description = "Creates a port forwarding rule", responseObject = FirewallRuleResponse.class, entityType = {FirewallRule.class,
-        VirtualMachine.class, IpAddress.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements PortForwardingRule {
-    public static final Logger s_logger = Logger.getLogger(CreatePortForwardingRuleCmd.class.getName());
-
-    private static final String s_name = "createportforwardingruleresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.IP_ADDRESS_ID,
-               type = CommandType.UUID,
-               entityType = IPAddressResponse.class,
-            required = true,
-    description = "the IP address id of the port forwarding rule")
-    private Long ipAddressId;
-
-    @Parameter(name = ApiConstants.PRIVATE_START_PORT,
-               type = CommandType.INTEGER,
-               required = true,
-            description = "the starting port of port forwarding rule's private port range")
-    private Integer privateStartPort;
-
-    @Parameter(name = ApiConstants.PROTOCOL,
-               type = CommandType.STRING,
-               required = true,
-            description = "the protocol for the port forwarding rule. Valid values are TCP or UDP.")
-    private String protocol;
-
-    @Parameter(name = ApiConstants.PRIVATE_END_PORT,
-               type = CommandType.INTEGER,
-               required = false,
-               description = "the ending port of port forwarding rule's private port range")
-    private Integer privateEndPort;
-
-    @Parameter(name = ApiConstants.PUBLIC_START_PORT,
-               type = CommandType.INTEGER,
-               required = true,
-            description = "the starting port of port forwarding rule's public port range")
-    private Integer publicStartPort;
-
-    @Parameter(name = ApiConstants.PUBLIC_END_PORT,
-               type = CommandType.INTEGER,
-               required = false,
-               description = "the ending port of port forwarding rule's private port range")
-    private Integer publicEndPort;
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = UserVmResponse.class,
-            required = true,
-                description = "the ID of the virtual machine for the port forwarding rule")
-    private Long virtualMachineId;
-
-    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
-    private List<String> cidrlist;
-
-    @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end public port is automatically created; "
-        + "if false - firewall rule has to be created explicitly. If not specified 1) defaulted to false when PF"
-        + " rule is being created for VPC guest network 2) in all other cases defaulted to true")
-    private Boolean openFirewall;
-
-    @Parameter(name = ApiConstants.NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = NetworkResponse.class,
-               description = "the network of the virtual machine the port forwarding rule will be created for. "
-                   + "Required when public IP address is not associated with any guest network yet (VPC case).")
-    private Long networkId;
-    @Parameter(name = ApiConstants.VM_GUEST_IP,
-               type = CommandType.STRING,
-               required = false,
-    description = "VM guest nic secondary IP address for the port forwarding rule")
-    private String vmSecondaryIp;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getIpAddressId() {
-        return ipAddressId;
-    }
-
-    public Ip getVmSecondaryIp() {
-        if (vmSecondaryIp == null) {
-            return null;
-        }
-        return new Ip(vmSecondaryIp);
-    }
-
-    @Override
-    public String getProtocol() {
-        return protocol.trim();
-    }
-
-    @Override
-    public long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    @Override
-    public List<String> getSourceCidrList() {
-        if (cidrlist != null) {
-            throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall "
-                + "rule for the specific cidr, please refer to createFirewallRule command");
-        }
-        return null;
-    }
-
-    public Boolean getOpenFirewall() {
-        boolean isVpc = getVpcId() == null ? false : true;
-        if (openFirewall != null) {
-            if (isVpc && openFirewall) {
-                throw new InvalidParameterValueException("Can't have openFirewall=true when IP address belongs to VPC");
-            }
-            return openFirewall;
-        } else {
-            if (isVpc) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    private Long getVpcId() {
-        if (ipAddressId != null) {
-            IpAddress ipAddr = _networkService.getIp(ipAddressId);
-            if (ipAddr == null || !ipAddr.readyToUse()) {
-                throw new InvalidParameterValueException("Unable to create PF rule, invalid IP address id " + ipAddressId);
-            } else {
-                return ipAddr.getVpcId();
-            }
-        }
-        return null;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException {
-        CallContext callerContext = CallContext.current();
-        boolean success = true;
-        PortForwardingRule rule = null;
-        try {
-            CallContext.current().setEventDetails("Rule Id: " + getEntityId());
-
-            if (getOpenFirewall()) {
-                success = success && _firewallService.applyIngressFirewallRules(ipAddressId, callerContext.getCallingAccount());
-            }
-
-            success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCallingAccount());
-
-            // State is different after the rule is applied, so get new object here
-            rule = _entityMgr.findById(PortForwardingRule.class, getEntityId());
-            FirewallRuleResponse fwResponse = new FirewallRuleResponse();
-            if (rule != null) {
-                fwResponse = _responseGenerator.createPortForwardingRuleResponse(rule);
-                setResponseObject(fwResponse);
-            }
-            fwResponse.setResponseName(getCommandName());
-        } finally {
-            if (!success || rule == null) {
-
-                if (getOpenFirewall()) {
-                    _firewallService.revokeRelatedFirewallRule(getEntityId(), true);
-                }
-
-                try {
-                    _rulesService.revokePortForwardingRule(getEntityId(), true);
-                } catch (Exception ex) {
-                    //Ignore e.g. failed to apply rules to device error
-                }
-
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to apply port forwarding rule");
-            }
-        }
-    }
-
-    @Override
-    public long getId() {
-        throw new UnsupportedOperationException("database id can only provided by VO objects");
-    }
-
-    @Override
-    public String getXid() {
-        // FIXME: We should allow for end user to specify Xid.
-        return null;
-    }
-
-    @Override
-    public String getUuid() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Long getSourceIpAddressId() {
-        return ipAddressId;
-    }
-
-    @Override
-    public Integer getSourcePortStart() {
-        return publicStartPort.intValue();
-    }
-
-    @Override
-    public Integer getSourcePortEnd() {
-        return (publicEndPort == null) ? publicStartPort.intValue() : publicEndPort.intValue();
-    }
-
-    @Override
-    public Purpose getPurpose() {
-        return Purpose.PortForwarding;
-    }
-
-    @Override
-    public State getState() {
-        throw new UnsupportedOperationException("Should never call me to find the state");
-    }
-
-    @Override
-    public long getNetworkId() {
-        IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
-        Long ntwkId = null;
-
-        if (ip.getAssociatedWithNetworkId() != null) {
-            ntwkId = ip.getAssociatedWithNetworkId();
-        } else {
-            ntwkId = networkId;
-        }
-        if (ntwkId == null) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule for the ipAddress id=" + ipAddressId +
-                    " as ip is not associated with any network and no networkId is passed in");
-        }
-        return ntwkId;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
-        // tracked
-    }
-
-    @Override
-    public long getDomainId() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ip.getDomainId();
-    }
-
-    @Override
-    public Ip getDestinationIpAddress() {
-        return null;
-    }
-
-    @Override
-    public void setDestinationIpAddress(Ip destinationIpAddress) {
-        return;
-    }
-
-    @Override
-    public int getDestinationPortStart() {
-        return privateStartPort.intValue();
-    }
-
-    @Override
-    public int getDestinationPortEnd() {
-        return (privateEndPort == null) ? privateStartPort.intValue() : privateEndPort.intValue();
-    }
-
-    @Override
-    public void create() {
-        // cidr list parameter is deprecated
-        if (cidrlist != null) {
-            throw new InvalidParameterValueException(
-                "Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
-        }
-
-        Ip privateIp = getVmSecondaryIp();
-        if (privateIp != null) {
-            if (!NetUtils.isValidIp4(privateIp.toString())) {
-                throw new InvalidParameterValueException("Invalid vm ip address");
-            }
-        }
-
-        try {
-            PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, privateIp, getOpenFirewall(), isDisplay());
-            setEntityId(result.getId());
-            setEntityUuid(result.getUuid());
-        } catch (NetworkRuleConflictException ex) {
-            s_logger.info("Network rule conflict: ", ex);
-            s_logger.trace("Network Rule Conflict: ", ex);
-            throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NET_RULE_ADD;
-    }
-
-    @Override
-    public String getEventDescription() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ("Applying port forwarding  rule for Ip: " + ip.getAddress() + " with virtual machine:" + virtualMachineId);
-    }
-
-    @Override
-    public long getAccountId() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        return ip.getAccountId();
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.networkSyncObject;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        return getIp().getAssociatedWithNetworkId();
-    }
-
-    private IpAddress getIp() {
-        IpAddress ip = _networkService.getIp(ipAddressId);
-        if (ip == null) {
-            throw new InvalidParameterValueException("Unable to find ip address by id " + ipAddressId);
-        }
-        return ip;
-    }
-
-    @Override
-    public Integer getIcmpCode() {
-        return null;
-    }
-
-    @Override
-    public Integer getIcmpType() {
-        return null;
-    }
-
-    @Override
-    public Long getRelated() {
-        return null;
-    }
-
-    @Override
-    public FirewallRuleType getType() {
-        return FirewallRuleType.User;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.FirewallRule;
-    }
-
-    @Override
-    public TrafficType getTrafficType() {
-        return null;
-    }
-
-    @Override
-    public List<String> getDestinationCidrList(){
-        return null;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if (display != null) {
-            return display;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return FirewallRule.class;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
deleted file mode 100644
index 745b87d..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java
+++ /dev/null
@@ -1,213 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.iso;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.template.VirtualMachineTemplate;
-
-@APICommand(name = "registerIso", responseObject = TemplateResponse.class, description = "Registers an existing ISO into the CloudStack Cloud.", responseView = ResponseView.Restricted,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class RegisterIsoCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(RegisterIsoCmd.class.getName());
-
-    private static final String s_name = "registerisoresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.BOOTABLE, type = CommandType.BOOLEAN, description = "true if this ISO is bootable. If not passed explicitly its assumed to be true")
-    private Boolean bootable;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT,
-               type = CommandType.STRING,
-               required = true,
-               description = "the display text of the ISO. This is usually used for display purposes.",
-               length = 4096)
-    private String displayText;
-
-    @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true if you want this ISO to be featured")
-    private Boolean featured;
-
-    @Parameter(name = ApiConstants.IS_PUBLIC,
-               type = CommandType.BOOLEAN,
-               description = "true if you want to register the ISO to be publicly available to all users, false otherwise.")
-    private Boolean publicIso;
-
-    @Parameter(name = ApiConstants.IS_EXTRACTABLE, type = CommandType.BOOLEAN, description = "true if the ISO or its derivatives are extractable; default is false")
-    private Boolean extractable;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the ISO")
-    private String isoName;
-
-    @Parameter(name = ApiConstants.OS_TYPE_ID,
-               type = CommandType.UUID,
-               entityType = GuestOSResponse.class,
-               description = "the ID of the OS type that best represents the OS of this ISO. If the ISO is bootable this parameter needs to be passed")
-    private Long osTypeId;
-
-    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, length = 2048, description = "the URL to where the ISO is currently being hosted")
-    private String url;
-
-    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class,
-            required=true, description="the ID of the zone you wish to register the ISO to.")
-    protected Long zoneId;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "an optional domainId. If the account parameter is used, domainId must also be used.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account name. Must be used with domainId.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this ISO. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
-    private String checksum;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Register ISO for the project")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.IMAGE_STORE_UUID, type = CommandType.STRING, description = "Image store UUID")
-    private String imageStoreUuid;
-
-    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
-               type = CommandType.BOOLEAN,
-               description = "true if ISO contains XS/VMWare tools inorder to support dynamic scaling of VM CPU/memory")
-    protected Boolean isDynamicallyScalable;
-
-    @Parameter(name=ApiConstants.DIRECT_DOWNLOAD,
-            type = CommandType.BOOLEAN,
-            description = "true if ISO should bypass Secondary Storage and be downloaded to Primary Storage on deployment")
-    private Boolean directDownload;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Boolean isBootable() {
-        return bootable;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Boolean isFeatured() {
-        return featured;
-    }
-
-    public Boolean isPublic() {
-        return publicIso;
-    }
-
-    public Boolean isExtractable() {
-        return extractable;
-    }
-
-    public String getIsoName() {
-        return isoName;
-    }
-
-    public Long getOsTypeId() {
-        return osTypeId;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public String getChecksum() {
-        return checksum;
-    }
-
-    public String getImageStoreUuid() {
-        return imageStoreUuid;
-    }
-
-    public Boolean isDynamicallyScalable() {
-        return isDynamicallyScalable ==  null ? Boolean.FALSE : isDynamicallyScalable;
-    }
-
-    public boolean isDirectDownload() {
-        return directDownload == null ? false : directDownload;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
-        if (accountId == null) {
-            return CallContext.current().getCallingAccount().getId();
-        }
-
-        return accountId;
-    }
-
-    @Override
-    public void execute() throws ResourceAllocationException {
-        VirtualMachineTemplate template = _templateService.registerIso(this);
-        if (template != null) {
-            ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
-            List<TemplateResponse> templateResponses = _responseGenerator.createIsoResponses(ResponseView.Restricted, template, zoneId, false);
-            response.setResponses(templateResponses);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to register ISO");
-        }
-
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java
deleted file mode 100644
index ccf5b8a..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.iso;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.TemplateResponse;
-
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-
-@APICommand(name = "updateIso", description = "Updates an ISO file.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateIsoCmd extends BaseUpdateTemplateOrIsoCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateIsoCmd.class.getName());
-    private static final String s_name = "updateisoresponse";
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public Boolean getRequiresHvm() {
-        return null;
-    }
-
-    @Override
-    public Boolean getPasswordEnabled() {
-        return null;
-    }
-
-    @Override
-    public String getFormat() {
-        return null;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
-        if (template != null) {
-            return template.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        VirtualMachineTemplate result = _templateService.updateTemplate(this);
-        if (result != null) {
-            TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(ResponseView.Restricted, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update ISO");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java
deleted file mode 100644
index 4b6a836..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java
+++ /dev/null
@@ -1,261 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.network;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NetworkACLItemResponse;
-import org.apache.cloudstack.api.response.NetworkACLResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.user.Account;
-import com.cloud.utils.net.NetUtils;
-
-@APICommand(name = "createNetworkACL",
-            description = "Creates a ACL rule in the given network (the network has to belong to VPC)",
-            responseObject = NetworkACLItemResponse.class,
-            requestHasSensitiveInfo = false,
-            responseHasSensitiveInfo = false)
-public class CreateNetworkACLCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateNetworkACLCmd.class.getName());
-
-    private static final String s_name = "createnetworkaclresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.PROTOCOL,
-               type = CommandType.STRING,
-               required = true,
-               description = "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
-    private String protocol;
-
-    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of ACL")
-    private Integer publicStartPort;
-
-    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL")
-    private Integer publicEndPort;
-
-    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the CIDR list to allow traffic from/to")
-    private List<String> cidrlist;
-
-    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
-    private Integer icmpType;
-
-    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
-    private Integer icmpCode;
-
-    @Parameter(name = ApiConstants.NETWORK_ID,
-               type = CommandType.UUID,
-               entityType = NetworkResponse.class,
-               description = "The network of the VM the ACL will be created for")
-    private Long networkId;
-
-    @Parameter(name = ApiConstants.ACL_ID,
-               type = CommandType.UUID,
-               entityType = NetworkACLResponse.class,
-               description = "The network of the VM the ACL will be created for")
-    private Long aclId;
-
-    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the ACL,"
-        + "can be ingress or egress, defaulted to ingress if not specified")
-    private String trafficType;
-
-    @Parameter(name = ApiConstants.NUMBER, type = CommandType.INTEGER, description = "The network of the VM the ACL will be created for")
-    private Integer number;
-
-    @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "scl entry action, allow or deny")
-    private String action;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-    @Deprecated
-    public Boolean getDisplay() {
-        return display;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if (display != null) {
-            return display;
-        } else {
-            return true;
-        }
-    }
-
-    public String getProtocol() {
-        String p = protocol.trim();
-        // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code
-        if (StringUtils.isNumeric(p)) {
-            int protoNumber = Integer.parseInt(p);
-            if (protoNumber == 1) {
-                p = "icmp";
-            }
-        }
-        return p;
-    }
-
-    public List<String> getSourceCidrList() {
-        if (cidrlist != null) {
-            return cidrlist;
-        } else {
-            List<String> oneCidrList = new ArrayList<String>();
-            oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
-            return oneCidrList;
-        }
-    }
-
-    public NetworkACLItem.TrafficType getTrafficType() {
-        if (trafficType == null) {
-            return NetworkACLItem.TrafficType.Ingress;
-        }
-        for (NetworkACLItem.TrafficType type : NetworkACLItem.TrafficType.values()) {
-            if (type.toString().equalsIgnoreCase(trafficType)) {
-                return type;
-            }
-        }
-        throw new InvalidParameterValueException("Invalid traffic type " + trafficType);
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public String getAction() {
-        return action;
-    }
-
-    public Integer getNumber() {
-        return number;
-    }
-
-    public Integer getSourcePortStart() {
-        return publicStartPort;
-    }
-
-    public Integer getSourcePortEnd() {
-        if (publicEndPort == null) {
-            if (publicStartPort != null) {
-                return publicStartPort;
-            }
-        } else {
-            return publicEndPort;
-        }
-
-        return null;
-    }
-
-    public Long getNetworkId() {
-        return networkId;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-        return caller.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Creating Network ACL Item";
-    }
-
-    public Integer getIcmpCode() {
-        if (icmpCode != null) {
-            return icmpCode;
-        } else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
-            return -1;
-        }
-        return null;
-    }
-
-    public Integer getIcmpType() {
-        if (icmpType != null) {
-            return icmpType;
-        } else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
-            return -1;
-
-        }
-        return null;
-    }
-
-    public Long getACLId() {
-        return aclId;
-    }
-
-    @Override
-    public void create() {
-        NetworkACLItem result = _networkACLService.createNetworkACLItem(this);
-        setEntityId(result.getId());
-        setEntityUuid(result.getUuid());
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException {
-        boolean success = false;
-        NetworkACLItem rule = _networkACLService.getNetworkACLItem(getEntityId());
-        try {
-            CallContext.current().setEventDetails("Rule ID: " + getEntityId());
-            success = _networkACLService.applyNetworkACL(rule.getAclId());
-
-            // State is different after the rule is applied, so get new object here
-            rule = _networkACLService.getNetworkACLItem(getEntityId());
-            NetworkACLItemResponse aclResponse = new NetworkACLItemResponse();
-            if (rule != null) {
-                aclResponse = _responseGenerator.createNetworkACLItemResponse(rule);
-                setResponseObject(aclResponse);
-            }
-            aclResponse.setResponseName(getCommandName());
-        } finally {
-            if (!success || rule == null) {
-                _networkACLService.revokeNetworkACLItem(getEntityId());
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create network ACL Item");
-            }
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java
deleted file mode 100644
index 041d641..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.network;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-
-import com.cloud.network.Network;
-import com.cloud.utils.Pair;
-
-@APICommand(name = "listNetworks", description = "Lists all available networks.", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListNetworksCmd extends BaseListTaggedResourcesCmd {
-    public static final Logger s_logger = Logger.getLogger(ListNetworksCmd.class.getName());
-    private static final String s_name = "listnetworksresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list networks by ID")
-    private Long id;
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone ID of the network")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "the type of the network. Supported values are: isolated and shared")
-    private String guestIpType;
-
-    @Parameter(name = ApiConstants.IS_SYSTEM, type = CommandType.BOOLEAN, description = "true if network is system, false otherwise")
-    private Boolean isSystem;
-
-    @Parameter(name = ApiConstants.ACL_TYPE, type = CommandType.STRING, description = "list networks by ACL (access control list) type. Supported values are account and domain")
-    private String aclType;
-
-    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "type of the traffic")
-    private String trafficType;
-
-    @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "list networks by physical network id")
-    private Long physicalNetworkId;
-
-    @Parameter(name = ApiConstants.SUPPORTED_SERVICES, type = CommandType.LIST, collectionType = CommandType.STRING, description = "list networks supporting certain services")
-    private List<String> supportedServices;
-
-    @Parameter(name = ApiConstants.RESTART_REQUIRED, type = CommandType.BOOLEAN, description = "list networks by restartRequired")
-    private Boolean restartRequired;
-
-    @Parameter(name = ApiConstants.SPECIFY_IP_RANGES, type = CommandType.BOOLEAN, description = "true if need to list only networks which support specifying IP ranges")
-    private Boolean specifyIpRanges;
-
-    @Parameter(name = ApiConstants.VPC_ID, type = CommandType.UUID, entityType = VpcResponse.class, description = "List networks by VPC")
-    private Long vpcId;
-
-    @Parameter(name = ApiConstants.CAN_USE_FOR_DEPLOY, type = CommandType.BOOLEAN, description = "list networks available for VM deployment")
-    private Boolean canUseForDeploy;
-
-    @Parameter(name = ApiConstants.FOR_VPC, type = CommandType.BOOLEAN, description = "the network belongs to VPC")
-    private Boolean forVpc;
-
-    @Parameter(name = ApiConstants.DISPLAY_NETWORK, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public String getGuestIpType() {
-        return guestIpType;
-    }
-
-    public Boolean getIsSystem() {
-        return isSystem;
-    }
-
-    public String getAclType() {
-        return aclType;
-    }
-
-    public String getTrafficType() {
-        return trafficType;
-    }
-
-    public Long getPhysicalNetworkId() {
-        return physicalNetworkId;
-    }
-
-    public List<String> getSupportedServices() {
-        return supportedServices;
-    }
-
-    public Boolean getRestartRequired() {
-        return restartRequired;
-    }
-
-    public Boolean getSpecifyIpRanges() {
-        return specifyIpRanges;
-    }
-
-    public Long getVpcId() {
-        return vpcId;
-    }
-
-    public Boolean canUseForDeploy() {
-        return canUseForDeploy;
-    }
-
-    public Boolean getForVpc() {
-        return forVpc;
-    }
-
-    @Override
-    public Boolean getDisplay() {
-        if (display != null) {
-            return display;
-        }
-        return super.getDisplay();
-    }
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute() {
-        Pair<List<? extends Network>, Integer> networks = _networkService.searchForNetworks(this);
-        ListResponse<NetworkResponse> response = new ListResponse<NetworkResponse>();
-        List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
-        for (Network network : networks.first()) {
-            NetworkResponse networkResponse = _responseGenerator.createNetworkResponse(ResponseView.Restricted, network);
-            networkResponses.add(networkResponse);
-        }
-        response.setResponses(networkResponses, networks.second());
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java
deleted file mode 100644
index acc2ae8..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLItemCmd.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.network;
-
-import java.util.List;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NetworkACLItemResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.user.Account;
-
-@APICommand(name = "updateNetworkACLItem", description = "Updates ACL item with specified ID", responseObject = NetworkACLItemResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateNetworkACLItemCmd extends BaseAsyncCustomIdCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateNetworkACLItemCmd.class.getName());
-
-    private static final String s_name = "createnetworkaclresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID,
-               type = CommandType.UUID,
-               entityType = NetworkACLItemResponse.class,
-               required = true,
-               description = "the ID of the network ACL item")
-    private Long id;
-
-    @Parameter(name = ApiConstants.PROTOCOL,
-               type = CommandType.STRING,
-               description = "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
-    private String protocol;
-
-    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of ACL")
-    private Integer publicStartPort;
-
-    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL")
-    private Integer publicEndPort;
-
-    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to allow traffic from/to")
-    private List<String> cidrlist;
-
-    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
-    private Integer icmpType;
-
-    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
-    private Integer icmpCode;
-
-    @Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the ACL,"
-        + "can be Ingress or Egress, defaulted to Ingress if not specified")
-    private String trafficType;
-
-    @Parameter(name = ApiConstants.NUMBER, type = CommandType.INTEGER, description = "The network of the vm the ACL will be created for")
-    private Integer number;
-
-    @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "scl entry action, allow or deny")
-    private String action;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public boolean isDisplay() {
-        if (display != null) {
-            return display;
-        } else {
-            return true;
-        }
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getProtocol() {
-        if (protocol != null) {
-            return protocol.trim();
-        } else
-            return null;
-    }
-
-    public List<String> getSourceCidrList() {
-        return cidrlist;
-    }
-
-    public NetworkACLItem.TrafficType getTrafficType() {
-        if (trafficType != null) {
-            for (NetworkACLItem.TrafficType type : NetworkACLItem.TrafficType.values()) {
-                if (type.toString().equalsIgnoreCase(trafficType)) {
-                    return type;
-                }
-            }
-        }
-        return null;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public String getAction() {
-        return action;
-    }
-
-    public Integer getNumber() {
-        return number;
-    }
-
-    public Integer getSourcePortStart() {
-        return publicStartPort;
-    }
-
-    public Integer getSourcePortEnd() {
-        return publicEndPort;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-        return caller.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NETWORK_ACL_ITEM_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Updating network ACL item";
-    }
-
-    public Integer getIcmpCode() {
-        return icmpCode;
-    }
-
-    public Integer getIcmpType() {
-        return icmpType;
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException {
-        CallContext.current().setEventDetails("Rule Id: " + getId());
-        NetworkACLItem aclItem =
-            _networkACLService.updateNetworkACLItem(getId(), getProtocol(), getSourceCidrList(), getTrafficType(), getAction(), getNumber(), getSourcePortStart(),
-                getSourcePortEnd(), getIcmpCode(), getIcmpType(), this.getCustomId(), this.isDisplay());
-        if (aclItem == null) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network ACL item");
-        }
-        NetworkACLItemResponse aclResponse = _responseGenerator.createNetworkACLItemResponse(aclItem);
-        setResponseObject(aclResponse);
-        aclResponse.setResponseName(getCommandName());
-    }
-
-    @Override
-    public void checkUuid() {
-        if (this.getCustomId() != null) {
-            _uuidMgr.checkUuid(this.getCustomId(), NetworkACLItem.class);
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java
deleted file mode 100644
index aa1f557..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/network/UpdateNetworkACLListCmd.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.network;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.NetworkACLResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.user.Account;
-
-@APICommand(name = "updateNetworkACLList", description = "Updates network ACL list", responseObject = SuccessResponse.class, since = "4.4",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateNetworkACLListCmd extends BaseAsyncCustomIdCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateNetworkACLListCmd.class.getName());
-    private static final String s_name = "updatenetworkacllistresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetworkACLResponse.class, required = true, description = "the ID of the network ACL")
-    private Long id;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the list to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Boolean getDisplay() {
-        return display;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NETWORK_ACL_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return ("Updating network ACL list ID=" + id);
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-        return caller.getAccountId();
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException {
-        NetworkACL acl = _networkACLService.updateNetworkACL(id, this.getCustomId(), getDisplay());
-        NetworkACLResponse aclResponse = _responseGenerator.createNetworkACLResponse(acl);
-        setResponseObject(aclResponse);
-        aclResponse.setResponseName(getCommandName());
-    }
-
-    @Override
-    public void checkUuid() {
-        if (this.getCustomId() != null) {
-            _uuidMgr.checkUuid(this.getCustomId(), NetworkACL.class);
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java b/api/src/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java
deleted file mode 100644
index e8a045c..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/project/CreateProjectCmd.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.project;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.projects.Project;
-import com.cloud.user.Account;
-
-@APICommand(name = "createProject", description = "Creates a project", responseObject = ProjectResponse.class, since = "3.0.0",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateProjectCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateProjectCmd.class.getName());
-
-    private static final String s_name = "createprojectresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will be Admin for the project")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning a project")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the project")
-    private String name;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "display text of the project")
-    private String displayText;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public String getAccountName() {
-        if (accountName != null) {
-            return accountName;
-        } else {
-            return CallContext.current().getCallingAccount().getAccountName();
-        }
-    }
-
-    public Long getDomainId() {
-        if (domainId != null) {
-            return domainId;
-        } else {
-            return CallContext.current().getCallingAccount().getDomainId();
-        }
-
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-
-        if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
-            throw new InvalidParameterValueException("Account name and domain id must be specified together");
-        }
-
-        if (accountName != null) {
-            return _accountService.finalizeOwner(caller, accountName, domainId, null).getId();
-        }
-
-        return caller.getId();
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public void execute() {
-        Project project = _projectService.enableProject(this.getEntityId());
-        if (project != null) {
-            ProjectResponse response = _responseGenerator.createProjectResponse(project);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a project");
-        }
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        CallContext.current().setEventDetails("Project Name: " + getName());
-        Project project = _projectService.createProject(getName(), getDisplayText(), getAccountName(), getDomainId());
-        if (project != null) {
-            this.setEntityId(project.getId());
-            this.setEntityUuid(project.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a project");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_PROJECT_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating project";
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java
deleted file mode 100644
index d66b649..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java
+++ /dev/null
@@ -1,260 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.snapshot;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.projects.Project;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-import com.cloud.utils.exception.CloudRuntimeException;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.log4j.Logger;
-
-@APICommand(name = "createSnapshot", description = "Creates an instant snapshot of a volume.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateSnapshotCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateSnapshotCmd.class.getName());
-    private static final String s_name = "createsnapshotresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT,
-               type = CommandType.STRING,
-               description = "The account of the snapshot. The account parameter must be used with the domainId parameter.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-            description = "The domain ID of the snapshot. If used with the account parameter, specifies a domain for the account associated with the disk volume.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "The ID of the disk volume")
-    private Long volumeId;
-
-    @Parameter(name = ApiConstants.POLICY_ID,
-               type = CommandType.UUID,
-               entityType = SnapshotPolicyResponse.class,
-            description = "policy id of the snapshot, if this is null, then use MANUAL_POLICY.")
-    private Long policyId;
-
-    @Parameter(name = ApiConstants.SNAPSHOT_QUIESCEVM, type = CommandType.BOOLEAN, required = false, description = "quiesce vm if true")
-    private Boolean quiescevm;
-
-    @Parameter(name = ApiConstants.LOCATION_TYPE, type = CommandType.STRING, required = false, description = "Currently applicable only for managed storage. " +
-            "Valid location types: 'primary', 'secondary'. Default = 'primary'.")
-    private String locationType;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the snapshot")
-    private String snapshotName;
-
-    @Parameter(name = ApiConstants.ASYNC_BACKUP, type = CommandType.BOOLEAN, required = false, description = "asynchronous backup if true")
-    private Boolean asyncBackup;
-
-    private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Boolean getQuiescevm() {
-        if (quiescevm == null) {
-            return false;
-        } else {
-            return quiescevm;
-        }
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public String getSnapshotName() {
-        return snapshotName;
-    }
-
-    public String getVolumeUuid() {
-        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume's UUID");
-        }
-        return volume.getUuid();
-    }
-
-    public Long getPolicyId() {
-        if (policyId != null) {
-            return policyId;
-        } else {
-            return Snapshot.MANUAL_POLICY_ID;
-        }
-    }
-
-    private Long getHostId() {
-        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume by id");
-        }
-        return _snapshotService.getHostIdForSnapshotOperation(volume);
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return ApiConstants.SNAPSHOT;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-
-        Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
-        }
-
-        Account account = _accountService.getAccount(volume.getAccountId());
-        //Can create templates for enabled projects/accounts only
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            Project project = _projectService.findByProjectAccountId(volume.getAccountId());
-            if (project.getState() != Project.State.Active) {
-                throw new PermissionDeniedException("Can't add resources to the project id=" + project.getId() + " in state=" + project.getState() +
-                    " as it's no longer active");
-            }
-        } else if (account.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of template is disabled: " + account);
-        }
-
-        return volume.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_SNAPSHOT_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating snapshot for volume: " + getVolumeUuid();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Snapshot;
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        Snapshot snapshot = _volumeService.allocSnapshot(getVolumeId(), getPolicyId(), getSnapshotName(), getLocationType());
-        if (snapshot != null) {
-            setEntityId(snapshot.getId());
-            setEntityUuid(snapshot.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot");
-        }
-    }
-
-    @Override
-    public void execute() {
-        Snapshot snapshot;
-        try {
-            snapshot =
-                _volumeService.takeSnapshot(getVolumeId(), getPolicyId(), getEntityId(), _accountService.getAccount(getEntityOwnerId()), getQuiescevm(), getLocationType(), getAsyncBackup());
-
-            if (snapshot != null) {
-                SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + getVolumeId());
-            }
-        } catch (Exception e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + getVolumeId());
-        }
-    }
-
-    private Snapshot.LocationType getLocationType() {
-
-        if (Snapshot.LocationType.values() == null || Snapshot.LocationType.values().length == 0 || locationType == null) {
-            return null;
-        }
-
-        try {
-            String lType = locationType.trim().toUpperCase();
-            return Snapshot.LocationType.valueOf(lType);
-        } catch (IllegalArgumentException e) {
-            String errMesg = "Invalid locationType " + locationType + "Specified for volume " + getVolumeId()
-                        + " Valid values are: primary,secondary ";
-            s_logger.warn(errMesg);
-            throw  new CloudRuntimeException(errMesg);
-        }
-    }
-
-    @Override
-    public String getSyncObjType() {
-        if (getSyncObjId() != null) {
-            return syncObjectType;
-        }
-        return null;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        if (getHostId() != null) {
-            return getHostId();
-        }
-        return null;
-    }
-
-    public Boolean getAsyncBackup() {
-        if (asyncBackup == null) {
-            return false;
-        } else {
-            return asyncBackup;
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java
deleted file mode 100644
index 7a35d34..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java
+++ /dev/null
@@ -1,219 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.snapshot;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.projects.Project;
-import com.cloud.storage.Snapshot;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-@APICommand(name = "createSnapshotFromVMSnapshot", description = "Creates an instant snapshot of a volume from existing vm snapshot.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, since = "4.10.0",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateSnapshotFromVMSnapshotCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateSnapshotFromVMSnapshotCmd.class.getName());
-    private static final String s_name = "createsnapshotfromvmsnapshotresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "The ID of the disk volume")
-    private Long volumeId;
-
-    @Parameter(name=ApiConstants.VM_SNAPSHOT_ID, type=CommandType.UUID, entityType=VMSnapshotResponse.class,
-            required=true, description="The ID of the VM snapshot")
-    private Long vmSnapshotId;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the snapshot")
-    private String snapshotName;
-
-    private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public Long getVMSnapshotId() {
-        return vmSnapshotId;
-    }
-
-    public String getSnapshotName() {
-        return snapshotName;
-    }
-
-    private Long getVmId() {
-        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
-        if (vmsnapshot == null) {
-            throw new InvalidParameterValueException("Unable to find vm snapshot by id=" + getVMSnapshotId());
-        }
-        UserVm vm = _entityMgr.findById(UserVm.class, vmsnapshot.getVmId());
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find vm by vm snapshot id=" + getVMSnapshotId());
-        }
-        return vm.getId();
-    }
-    private Long getHostId() {
-        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
-        if (vmsnapshot == null) {
-            throw new InvalidParameterValueException("Unable to find vm snapshot by id=" + getVMSnapshotId());
-        }
-        UserVm vm = _entityMgr.findById(UserVm.class, vmsnapshot.getVmId());
-        if (vm != null) {
-            if(vm.getHostId() != null) {
-                return vm.getHostId();
-            } else if(vm.getLastHostId() != null) {
-                return vm.getLastHostId();
-            }
-        }
-        return null;
-    }
-
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return ApiConstants.SNAPSHOT;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-
-        VMSnapshot vmsnapshot = _entityMgr.findById(VMSnapshot.class, getVMSnapshotId());
-        if (vmsnapshot == null) {
-            throw new InvalidParameterValueException("Unable to find vmsnapshot by id=" + getVMSnapshotId());
-        }
-
-        Account account = _accountService.getAccount(vmsnapshot.getAccountId());
-        //Can create templates for enabled projects/accounts only
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            Project project = _projectService.findByProjectAccountId(vmsnapshot.getAccountId());
-            if (project == null) {
-                throw new InvalidParameterValueException("Unable to find project by account id=" + account.getUuid());
-            }
-            if (project.getState() != Project.State.Active) {
-                throw new PermissionDeniedException("Can't add resources to the project id=" + project.getUuid() + " in state=" + project.getState() + " as it's no longer active");
-            }
-        } else if (account.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of template is disabled: " + account);
-        }
-
-        return vmsnapshot.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_SNAPSHOT_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating snapshot from vm snapshot : " + getVMSnapshotId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Snapshot;
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        Snapshot snapshot = this._volumeService.allocSnapshotForVm(getVmId(), getVolumeId(), getSnapshotName());
-        if (snapshot != null) {
-            this.setEntityId(snapshot.getId());
-            this.setEntityUuid(snapshot.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot from vm snapshot");
-        }
-    }
-
-    @Override
-    public void execute() {
-        s_logger.info("CreateSnapshotFromVMSnapshotCmd with vm snapshot id:" + getVMSnapshotId() + " and snapshot id:" + getEntityId() + " starts:" + System.currentTimeMillis());
-        CallContext.current().setEventDetails("Vm Snapshot Id: "+ getVMSnapshotId());
-        Snapshot snapshot = null;
-        try {
-            snapshot = _snapshotService.backupSnapshotFromVmSnapshot(getEntityId(), getVmId(), getVolumeId(), getVMSnapshotId());
-            if (snapshot != null) {
-                SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot from vm snapshot " + getVMSnapshotId());
-            }
-        } catch (InvalidParameterValueException ex) {
-            throw ex;
-        } catch (Exception e) {
-            s_logger.debug("Failed to create snapshot", e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot from vm snapshot " + getVMSnapshotId());
-        } finally {
-            if (snapshot == null) {
-                try {
-                    _snapshotService.deleteSnapshot(getEntityId());
-                } catch (Exception e) {
-                    s_logger.debug("Failed to clean failed snapshot" + getEntityId());
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public String getSyncObjType() {
-        if (getSyncObjId() != null) {
-            return syncObjectType;
-        }
-        return null;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        if (getHostId() != null) {
-            return getHostId();
-        }
-        return null;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java
deleted file mode 100644
index 64a432d..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/snapshot/DeleteSnapshotCmd.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.snapshot;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Snapshot;
-import com.cloud.user.Account;
-
-@APICommand(name = "deleteSnapshot", description = "Deletes a snapshot of a disk volume.", responseObject = SuccessResponse.class, entityType = {Snapshot.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DeleteSnapshotCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteSnapshotCmd.class.getName());
-    private static final String s_name = "deletesnapshotresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = SnapshotResponse.class,
-            required=true, description="The ID of the snapshot")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Snapshot snapshot = _entityMgr.findById(Snapshot.class, getId());
-        if (snapshot != null) {
-            return snapshot.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_SNAPSHOT_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "deleting snapshot: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Snapshot;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Snapshot Id: " + getId());
-        boolean result = _snapshotService.deleteSnapshot(getId());
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete snapshot");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java
deleted file mode 100644
index 4708aff..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.api.command.user.snapshot;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Snapshot;
-import com.cloud.user.Account;
-
-@APICommand(name = "revertSnapshot", description = "This is supposed to revert a volume snapshot. This command is only supported with KVM so far", responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class RevertSnapshotCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RevertSnapshotCmd.class.getName());
-    private static final String s_name = "revertsnapshotresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name= ApiConstants.ID, type= BaseCmd.CommandType.UUID, entityType = SnapshotResponse.class,
-            required=true, description="The ID of the snapshot")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Snapshot snapshot = _entityMgr.findById(Snapshot.class, getId());
-        if (snapshot != null) {
-            return snapshot.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_SNAPSHOT_REVERT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "revert snapshot: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Snapshot;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Snapshot Id: " + getId());
-        Snapshot snapshot = _snapshotService.revertSnapshot(getId());
-        if (snapshot != null) {
-            SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to revert snapshot");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java
deleted file mode 100644
index d16b87cd9..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java
+++ /dev/null
@@ -1,182 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.template;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-
-@APICommand(name = "copyTemplate", description = "Copies a template from one zone to another.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CopyTemplateCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(CopyTemplateCmd.class.getName());
-    private static final String s_name = "copytemplateresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.DESTINATION_ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-               required = false,
-               description = "ID of the zone the template is being copied to.")
-    protected Long destZoneId;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
-            entityType = TemplateResponse.class, required = true, description = "Template ID.")
-    private Long id;
-
-    @Parameter(name = ApiConstants.SOURCE_ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-            description = "ID of the zone the template is currently hosted on. " +
-                    "If not specified and template is cross-zone, " +
-                    "then we will sync this template to region wide image store.")
-    private Long sourceZoneId;
-
-    @Parameter(name = ApiConstants.DESTINATION_ZONE_ID_LIST,
-                    type=CommandType.LIST,
-                    collectionType = CommandType.UUID,
-                    entityType = ZoneResponse.class,
-                    required = false,
-                    description = "A list of IDs of the zones that the template needs to be copied to." +
-                            "Specify this list if the template needs to copied to multiple zones in one go. " +
-                            "Do not specify destzoneid and destzoneids together, however one of them is required.")
-    protected List<Long> destZoneIds;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public List<Long> getDestinationZoneIds() {
-        if (destZoneIds != null && destZoneIds.size() != 0) {
-            return destZoneIds;
-        }
-        if (destZoneId != null) {
-            List < Long > destIds = new ArrayList<>();
-            destIds.add(destZoneId);
-            return destIds;
-        }
-        return null;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getSourceZoneId() {
-        return sourceZoneId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getStaticName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
-        if (template != null) {
-            return template.getAccountId();
-        }
-
-        // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_TEMPLATE_COPY;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "copying template: " + getId() + " from zone: " + getSourceZoneId()
-                + " to zone: " + getDestinationZoneIds();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Template;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ResourceAllocationException {
-        try {
-            if (destZoneId == null && (destZoneIds == null || destZoneIds.size() == 0))
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
-                        "Either destzoneid or destzoneids parameters have to be specified.");
-
-            if (destZoneId != null && destZoneIds != null && destZoneIds.size() != 0)
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
-                        "Both destzoneid and destzoneids cannot be specified at the same time.");
-
-            CallContext.current().setEventDetails(getEventDescription());
-            VirtualMachineTemplate template = _templateService.copyTemplate(this);
-
-            if (template != null){
-                List<TemplateResponse> listResponse = _responseGenerator.createTemplateResponses(ResponseView.Restricted,
-                                                            template, getDestinationZoneIds(), false);
-                TemplateResponse response = new TemplateResponse();
-                if (listResponse != null && !listResponse.isEmpty()) {
-                    response = listResponse.get(0);
-                }
-
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to copy template");
-            }
-        } catch (StorageUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
deleted file mode 100644
index 59c4abe..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/template/CreateTemplateCmd.java
+++ /dev/null
@@ -1,318 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.template;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.projects.Project;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-
-@APICommand(name = "createTemplate", responseObject = TemplateResponse.class, description = "Creates a template of a virtual machine. " + "The virtual machine must be in a STOPPED state. "
-        + "A template created from this command is automatically designated as a private template visible to the account that created it.", responseView = ResponseView.Restricted,
-    requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateTemplateCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateTemplateCmd.class.getName());
-    private static final String s_name = "createtemplateresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.BITS, type = CommandType.INTEGER, description = "32 or 64 bit")
-    private Integer bits;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT,
-               type = CommandType.STRING,
-               required = true,
-               description = "the display text of the template. This is usually used for display purposes.",
-               length = 4096)
-    private String displayText;
-
-    @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true if this template is a featured template, false otherwise")
-    private Boolean featured;
-
-    @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, description = "true if this template is a public template, false otherwise")
-    private Boolean publicTemplate;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the template")
-    private String templateName;
-
-    @Parameter(name = ApiConstants.OS_TYPE_ID,
-               type = CommandType.UUID,
-               entityType = GuestOSResponse.class,
-               required = true,
-               description = "the ID of the OS Type that best represents the OS of this template.")
-    private Long osTypeId;
-
-    @Parameter(name = ApiConstants.PASSWORD_ENABLED,
-               type = CommandType.BOOLEAN,
-               description = "true if the template supports the password reset feature; default is false")
-    private Boolean passwordEnabled;
-
-    @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if the template requres HVM, false otherwise")
-    private Boolean requiresHvm;
-
-    @Parameter(name = ApiConstants.SNAPSHOT_ID,
-               type = CommandType.UUID,
-               entityType = SnapshotResponse.class,
-            description = "the ID of the snapshot the template is being created from. Either this parameter, or volumeId has to be passed in")
-    protected Long snapshotId;
-
-    @Parameter(name = ApiConstants.VOLUME_ID,
-               type = CommandType.UUID,
-               entityType = VolumeResponse.class,
-            description = "the ID of the disk volume the template is being created from. Either this parameter, or snapshotId has to be passed in")
-    protected Long volumeId;
-
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType = UserVmResponse.class,
-            description="Optional, VM ID. If this presents, it is going to create a baremetal template for VM this ID refers to. This is only for VM whose hypervisor type is BareMetal")
-    protected Long vmId;
-
-    @Parameter(name = ApiConstants.URL,
-               type = CommandType.STRING,
-               length = 2048,
-               description = "Optional, only for baremetal hypervisor. The directory name where template stored on CIFS server")
-    private String url;
-
-    @Parameter(name = ApiConstants.TEMPLATE_TAG, type = CommandType.STRING, description = "the tag for this template.")
-    private String templateTag;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Template details in key/value pairs using format details[i].keyname=keyvalue. Example: details[0].hypervisortoolsversion=xenserver61")
-    protected Map details;
-
-    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
-               type = CommandType.BOOLEAN,
-               description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
-    protected Boolean isDynamicallyScalable;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "create template for the project")
-    private Long projectId;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Integer getBits() {
-        return bits;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Boolean isFeatured() {
-        return featured;
-    }
-
-    public Boolean isPublic() {
-        return publicTemplate;
-    }
-
-    public String getTemplateName() {
-        return templateName;
-    }
-
-    public Long getOsTypeId() {
-        return osTypeId;
-    }
-
-    public Boolean isPasswordEnabled() {
-        return passwordEnabled;
-    }
-
-    public Boolean getRequiresHvm() {
-        return requiresHvm;
-    }
-
-    public Long getSnapshotId() {
-        return snapshotId;
-    }
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public String getTemplateTag() {
-        return templateTag;
-    }
-
-    public Map getDetails() {
-        if (details == null || details.isEmpty()) {
-            return null;
-        }
-
-        Collection paramsCollection = details.values();
-        Map params = (Map)(paramsCollection.toArray())[0];
-        return params;
-    }
-
-    public boolean isDynamicallyScalable() {
-        return isDynamicallyScalable == null ? false : isDynamicallyScalable;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "template";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long volumeId = getVolumeId();
-        Long snapshotId = getSnapshotId();
-        Account callingAccount = CallContext.current().getCallingAccount();
-        if (volumeId != null) {
-            Volume volume = _entityMgr.findById(Volume.class, volumeId);
-            if (volume != null) {
-                _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, volume);
-            } else {
-                throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
-            }
-        } else {
-            Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
-            if (snapshot != null) {
-                _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, snapshot);
-            } else {
-                throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
-            }
-        }
-
-        if(projectId != null){
-            final Project project = _projectService.getProject(projectId);
-            if (project != null) {
-                if (project.getState() == Project.State.Active) {
-                    Account projectAccount= _accountService.getAccount(project.getProjectAccountId());
-                    _accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, projectAccount);
-                    return project.getProjectAccountId();
-                } else {
-                    final PermissionDeniedException ex =
-                            new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
-                                    " as it's no longer active");
-                    ex.addProxyObject(project.getUuid(), "projectId");
-                    throw ex;
-                }
-            } else {
-                throw new InvalidParameterValueException("Unable to find project by id");
-            }
-        }
-
-        return callingAccount.getId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_TEMPLATE_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating template: " + getTemplateName();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Template;
-    }
-
-    protected boolean isBareMetal() {
-        return (getVmId() != null && getUrl() != null);
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        VirtualMachineTemplate template = null;
-        //TemplateOwner should be the caller https://issues.citrite.net/browse/CS-17530
-        template = _templateService.createPrivateTemplateRecord(this, _accountService.getAccount(getEntityOwnerId()));
-        if (template != null) {
-            setEntityId(template.getId());
-            setEntityUuid(template.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a template");
-        }
-
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails(
-            "Template Id: " + getEntityId() + ((getSnapshotId() == null) ? " from volume Id: " + getVolumeId() : " from snapshot Id: " + getSnapshotId()));
-        VirtualMachineTemplate template = null;
-        template = _templateService.createPrivateTemplate(this);
-
-        if (template != null) {
-            List<TemplateResponse> templateResponses;
-            if (isBareMetal()) {
-                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Restricted, template.getId(), vmId);
-            } else {
-                templateResponses = _responseGenerator.createTemplateResponses(ResponseView.Restricted, template.getId(), snapshotId, volumeId, false);
-            }
-            TemplateResponse response = new TemplateResponse();
-            if (templateResponses != null && !templateResponses.isEmpty()) {
-                response = templateResponses.get(0);
-            }
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private template");
-        }
-
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java
deleted file mode 100755
index 95b3eee..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/template/DeleteTemplateCmd.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.template;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-
-@APICommand(name = "deleteTemplate",
-            responseObject = SuccessResponse.class,
-            description = "Deletes a template from the system. All virtual machines using the deleted template will not be affected.",
-            requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DeleteTemplateCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteTemplateCmd.class.getName());
-    private static final String s_name = "deletetemplateresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template")
-    private Long id;
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of zone of the template")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force delete a template.", since = "4.9+")
-    private Boolean forced;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public boolean isForced() {
-        return (forced != null) ? forced : true;
-    }
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getStaticName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
-        if (template != null) {
-            return template.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_TEMPLATE_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Deleting template " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Template;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Template Id: " + getId());
-        boolean result = _templateService.deleteTemplate(this);
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete template");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
deleted file mode 100644
index 48d3e14..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.template;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-
-@APICommand(name = "extractTemplate", description = "Extracts a template", responseObject = ExtractResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ExtractTemplateCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ExtractTemplateCmd.class.getName());
-
-    private static final String s_name = "extracttemplateresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template")
-    private Long id;
-
-    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, length = 2048, description = "the url to which the ISO would be extracted")
-    private String url;
-
-    @Parameter(name = ApiConstants.ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-               required = false,
-               description = "the ID of the zone where the ISO is originally located")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.MODE, type = CommandType.STRING, required = true, description = "the mode of extraction - HTTP_DOWNLOAD or FTP_UPLOAD")
-    private String mode;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public String getMode() {
-        return mode;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getStaticName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, getId());
-        if (template != null) {
-            return template.getAccountId();
-        }
-
-        // invalid id, parent this command to SYSTEM so ERROR events are tracked
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_TEMPLATE_EXTRACT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "extracting template: " + getId() + " from zone: " + getZoneId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Template;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() {
-        try {
-            CallContext.current().setEventDetails(getEventDescription());
-            String uploadUrl = _templateService.extract(this);
-            if (uploadUrl != null) {
-                ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl);
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract template");
-            }
-        } catch (InternalErrorException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
deleted file mode 100644
index 41481c8..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java
+++ /dev/null
@@ -1,195 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "addIpToNic", description = "Assigns secondary IP to NIC", responseObject = NicSecondaryIpResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class AddIpToVmNicCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
-    private static final String s_name = "addiptovmnicresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "the ID of the nic to which you want to assign private IP")
-    private Long nicId;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false, description = "Secondary IP Address")
-    private String ipAddr;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getEntityTable() {
-        return "nic_secondary_ips";
-    }
-
-    private long getNetworkId() {
-        Nic nic = _entityMgr.findById(Nic.class, nicId);
-        if (nic == null) {
-            throw new InvalidParameterValueException("Can't find network id for specified nic");
-        }
-        return nic.getNetworkId();
-    }
-
-    public long getNicId() {
-        return nicId;
-    }
-
-    private String getIpaddress() {
-        if (ipAddr != null) {
-            return ipAddr;
-        } else {
-            return null;
-        }
-    }
-
-    private NetworkType getNetworkType() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
-        return dc.getNetworkType();
-    }
-
-    private boolean isZoneSGEnabled() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
-        return dc.isSecurityGroupEnabled();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "associating ip to nic id=" + getNicId() + " belonging to network id=" + getNetworkId();
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "addressinfo";
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
-
-        CallContext.current().setEventDetails("Nic Id: " + getNicId());
-        NicSecondaryIp result = _entityMgr.findById(NicSecondaryIp.class, getEntityId());
-
-        if (result != null) {
-            CallContext.current().setEventDetails("secondary Ip Id: " + getEntityId());
-            boolean success = false;
-            success = _networkService.configureNicSecondaryIp(result, isZoneSGEnabled());
-
-            if (success == false) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
-            }
-
-            NicSecondaryIpResponse response = _responseGenerator.createSecondaryIPToNicResponse(result);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
-        }
-    }
-
-
-    @Override
-    public Long getSyncObjId() {
-        return getNetworkId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IpAddress;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Nic nic = _entityMgr.findById(Nic.class, nicId);
-        if (nic == null) {
-            throw new InvalidParameterValueException("Can't find nic for id specified");
-        }
-        long vmId = nic.getInstanceId();
-        VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, vmId);
-
-        return vm.getAccountId();
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        String ip;
-        NicSecondaryIp result;
-        String secondaryIp = null;
-        if ((ip = getIpaddress()) != null) {
-            if (!NetUtils.isValidIp4(ip)) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
-            }
-        }
-
-        try {
-            result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress());
-            if (result != null) {
-                setEntityId(result.getId());
-                setEntityUuid(result.getUuid());
-            }
-        } catch (InsufficientAddressCapacityException e) {
-            throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage());
-        }
-
-        if (result == null) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign secondary ip to nic");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java
deleted file mode 100644
index ed2a4b5..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java
+++ /dev/null
@@ -1,173 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class AddNicToVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AddNicToVMCmd.class);
-    private static final String s_name = "addnictovirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="Virtual Machine ID")
-    private Long vmId;
-
-    @Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "Network ID")
-    private Long netId;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "IP Address for the new network")
-    private String ipaddr;
-
-    @Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "Mac Address for the new network")
-    private String macaddr;
-
-    @Parameter(name = ApiConstants.DHCP_OPTIONS, type = CommandType.MAP, description = "DHCP options which are passed to the nic"
-            + " Example: dhcpoptions[0].dhcp:114=url&dhcpoptions[0].dhcp:66=www.test.com")
-    private Map dhcpOptions;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    public Long getNetworkId() {
-        return netId;
-    }
-
-    public String getIpAddress() {
-        return ipaddr;
-    }
-
-    public String getMacAddress() {
-        if (macaddr == null) {
-            return null;
-        }
-        if(!NetUtils.isValidMac(macaddr)) {
-            throw new InvalidParameterValueException("Mac address is not valid: " + macaddr);
-        } else if(!NetUtils.isUnicastMac(macaddr)) {
-            throw new InvalidParameterValueException("Mac address is not unicast: " + macaddr);
-        }
-        return NetUtils.standardizeMacAddress(macaddr);
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NIC_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "Adding network " + getNetworkId() + " to user vm: " + getVmId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getVmId());
-        if (vm == null) {
-             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        }
-        return vm.getAccountId();
-    }
-
-    public Map<Integer, String> getDhcpOptionsMap() {
-        Map<Integer, String> dhcpOptionsMap = new HashMap<>();
-        if (dhcpOptions != null && !dhcpOptions.isEmpty()) {
-
-            Collection<Map<String, String>> paramsCollection = this.dhcpOptions.values();
-            for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
-                for (String key : dhcpNetworkOptions.keySet()) {
-                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
-                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
-                        dhcpOptionsMap.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
-                    } else {
-                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
-                        dhcpOptionsMap.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
-                    }
-                }
-
-            }
-        }
-
-        return dhcpOptionsMap;
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getVmId() + " Network Id: " + getNetworkId());
-        UserVm result = _userVmService.addNicToVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NIC to vm. Refer to server logs for details.");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
deleted file mode 100644
index 8161fb2..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
+++ /dev/null
@@ -1,598 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.commons.collections.MapUtils;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.offering.DiskOffering;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityGroupAction {
-    public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName());
-
-    private static final String s_name = "deployvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "availability zone for the virtual machine")
-    private Long zoneId;
-
-    @ACL
-    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the ID of the service offering for the virtual machine")
-    private Long serviceOfferingId;
-
-    @ACL
-    @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template for the virtual machine")
-    private Long templateId;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "host name for the virtual machine")
-    private String name;
-
-    @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "an optional user generated name for the virtual machine")
-    private String displayName;
-
-    //Owner information
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
-    private Long domainId;
-
-    //Network information
-    //@ACL(accessType = AccessType.UseEntry)
-    @Parameter(name = ApiConstants.NETWORK_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = NetworkResponse.class, description = "list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
-    private List<Long> networkIds;
-
-    //DataDisk information
-    @ACL
-    @Parameter(name = ApiConstants.DISK_OFFERING_ID, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering for the virtual machine. If the template is of ISO format,"
-            + " the diskOfferingId is for the root disk volume. Otherwise this parameter is used to indicate the "
-            + "offering for the data disk volume. If the templateId parameter passed is from a Template object,"
-            + " the diskOfferingId refers to a DATA Disk Volume created. If the templateId parameter passed is "
-            + "from an ISO object, the diskOfferingId refers to a ROOT Disk Volume created.")
-    private Long diskOfferingId;
-
-    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId")
-    private Long size;
-
-    @Parameter(name = ApiConstants.ROOT_DISK_SIZE,
-            type = CommandType.LONG,
-            description = "Optional field to resize root disk on deploy. Value is in GB. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided",
-            since = "4.4")
-    private Long rootdisksize;
-
-    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
-    private String group;
-
-    @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, description = "the hypervisor on which to deploy the virtual machine. "
-            + "The parameter is required and respected only when hypervisor info is not set on the ISO/Template passed to the call")
-    private String hypervisor;
-
-    @Parameter(name = ApiConstants.USER_DATA, type = CommandType.STRING, description = "an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.", length = 32768)
-    private String userData;
-
-    @Parameter(name = ApiConstants.SSH_KEYPAIR, type = CommandType.STRING, description = "name of the ssh key pair used to login to the virtual machine")
-    private String sshKeyPairName;
-
-    @Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "destination Host ID to deploy the VM to - parameter available for root admin only")
-    private Long hostId;
-
-    @ACL
-    @Parameter(name = ApiConstants.SECURITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = SecurityGroupResponse.class, description = "comma separated list of security groups id that going to be applied to the virtual machine. "
-            + "Should be passed only when vm is created from a zone with Basic Network support." + " Mutually exclusive with securitygroupnames parameter")
-    private List<Long> securityGroupIdList;
-
-    @ACL
-    @Parameter(name = ApiConstants.SECURITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = SecurityGroupResponse.class, description = "comma separated list of security groups names that going to be applied to the virtual machine."
-            + " Should be passed only when vm is created from a zone with Basic Network support. " + "Mutually exclusive with securitygroupids parameter")
-    private List<String> securityGroupNameList;
-
-    @Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP, description = "ip to network mapping. Can't be specified with networkIds parameter."
-            + " Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid&iptonetworklist[0].mac=aa:bb:cc:dd:ee::ff - requests to use ip 10.10.10.11 in network id=uuid")
-    private Map ipToNetworkList;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "the ip address for default vm's network")
-    private String ipAddress;
-
-    @Parameter(name = ApiConstants.IP6_ADDRESS, type = CommandType.STRING, description = "the ipv6 address for default vm's network")
-    private String ip6Address;
-
-    @Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "the mac address for default vm's network")
-    private String macAddress;
-
-    @Parameter(name = ApiConstants.KEYBOARD, type = CommandType.STRING, description = "an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us")
-    private String keyboard;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Deploy vm for the project")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.START_VM, type = CommandType.BOOLEAN, description = "true if start vm after creating; defaulted to true if not specified")
-    private Boolean startVm;
-
-    @ACL
-    @Parameter(name = ApiConstants.AFFINITY_GROUP_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups id that are going to be applied to the virtual machine."
-            + " Mutually exclusive with affinitygroupnames parameter")
-    private List<Long> affinityGroupIdList;
-
-    @ACL
-    @Parameter(name = ApiConstants.AFFINITY_GROUP_NAMES, type = CommandType.LIST, collectionType = CommandType.STRING, entityType = AffinityGroupResponse.class, description = "comma separated list of affinity groups names that are going to be applied to the virtual machine."
-            + "Mutually exclusive with affinitygroupids parameter")
-    private List<String> affinityGroupNameList;
-
-    @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, since = "4.2", description = "an optional field, whether to the display the vm to the end user or not.", authorized = {RoleType.Admin})
-    private Boolean displayVm;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.3", description = "used to specify the custom parameters.")
-    private Map details;
-
-    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
-    private String deploymentPlanner;
-
-    @Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
-            + " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
-    private Map dhcpOptionsNetworkList;
-
-    @Parameter(name = ApiConstants.DATADISK_OFFERING_LIST, type = CommandType.MAP, since = "4.11", description = "datadisk template to disk-offering mapping;" +
-            " an optional parameter used to create additional data disks from datadisk templates; can't be specified with diskOfferingId parameter")
-    private Map dataDiskTemplateToDiskOfferingList;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getAccountName() {
-        if (accountName == null) {
-            return CallContext.current().getCallingAccount().getAccountName();
-        }
-        return accountName;
-    }
-
-    public Long getDiskOfferingId() {
-        return diskOfferingId;
-    }
-
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public String getDisplayName() {
-        return displayName;
-    }
-
-    public Long getDomainId() {
-        if (domainId == null) {
-            return CallContext.current().getCallingAccount().getDomainId();
-        }
-        return domainId;
-    }
-
-    public Map<String, String> getDetails() {
-        Map<String, String> customparameterMap = new HashMap<String, String>();
-        if (details != null && details.size() != 0) {
-            Collection parameterCollection = details.values();
-            Iterator iter = parameterCollection.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> value = (HashMap<String, String>)iter.next();
-                for (Map.Entry<String,String> entry: value.entrySet()) {
-                    customparameterMap.put(entry.getKey(),entry.getValue());
-                }
-            }
-        }
-        if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) {
-            customparameterMap.put("rootdisksize", rootdisksize.toString());
-        }
-        return customparameterMap;
-    }
-
-    public String getGroup() {
-        return group;
-    }
-
-    public HypervisorType getHypervisor() {
-        return HypervisorType.getType(hypervisor);
-    }
-
-    public Boolean getDisplayVm() {
-        return displayVm;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if(displayVm == null)
-            return true;
-        else
-            return displayVm;
-    }
-
-    public List<String> getSecurityGroupNameList() {
-        return securityGroupNameList;
-    }
-
-    public List<Long> getSecurityGroupIdList() {
-        return securityGroupIdList;
-    }
-
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    public Long getTemplateId() {
-        return templateId;
-    }
-
-    public String getUserData() {
-        return userData;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public List<Long> getNetworkIds() {
-       if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
-           if ((networkIds != null && !networkIds.isEmpty()) || ipAddress != null || getIp6Address() != null) {
-               throw new InvalidParameterValueException("ipToNetworkMap can't be specified along with networkIds or ipAddress");
-           } else {
-               List<Long> networks = new ArrayList<Long>();
-               networks.addAll(getIpToNetworkMap().keySet());
-               return networks;
-           }
-       }
-        return networkIds;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getSSHKeyPairName() {
-        return sshKeyPairName;
-    }
-
-    public Long getHostId() {
-        return hostId;
-    }
-
-    public boolean getStartVm() {
-        return startVm == null ? true : startVm;
-    }
-
-    public Map<Long, IpAddresses> getIpToNetworkMap() {
-        if ((networkIds != null || ipAddress != null || getIp6Address() != null) && ipToNetworkList != null) {
-            throw new InvalidParameterValueException("NetworkIds and ipAddress can't be specified along with ipToNetworkMap parameter");
-        }
-        LinkedHashMap<Long, IpAddresses> ipToNetworkMap = null;
-        if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
-            ipToNetworkMap = new LinkedHashMap<Long, IpAddresses>();
-            Collection ipsCollection = ipToNetworkList.values();
-            Iterator iter = ipsCollection.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> ips = (HashMap<String, String>)iter.next();
-                Long networkId;
-                Network network = _networkService.getNetwork(ips.get("networkid"));
-                if (network != null) {
-                    networkId = network.getId();
-                } else {
-                    try {
-                        networkId = Long.parseLong(ips.get("networkid"));
-                    } catch (NumberFormatException e) {
-                        throw new InvalidParameterValueException("Unable to translate and find entity with networkId: " + ips.get("networkid"));
-                    }
-                }
-                String requestedIp = ips.get("ip");
-                String requestedIpv6 = ips.get("ipv6");
-                String requestedMac = ips.get("mac");
-                if (requestedIpv6 != null) {
-                    requestedIpv6 = NetUtils.standardizeIp6Address(requestedIpv6);
-                }
-                if (requestedMac != null) {
-                    if(!NetUtils.isValidMac(requestedMac)) {
-                        throw new InvalidParameterValueException("Mac address is not valid: " + requestedMac);
-                    } else if(!NetUtils.isUnicastMac(requestedMac)) {
-                        throw new InvalidParameterValueException("Mac address is not unicast: " + requestedMac);
-                    }
-                    requestedMac = NetUtils.standardizeMacAddress(requestedMac);
-                }
-                IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6, requestedMac);
-                ipToNetworkMap.put(networkId, addrs);
-            }
-        }
-
-        return ipToNetworkMap;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public String getIp6Address() {
-        if (ip6Address == null) {
-            return null;
-        }
-        return NetUtils.standardizeIp6Address(ip6Address);
-    }
-
-
-    public String getMacAddress() {
-        if (macAddress == null) {
-            return null;
-        }
-        if(!NetUtils.isValidMac(macAddress)) {
-            throw new InvalidParameterValueException("Mac address is not valid: " + macAddress);
-        } else if(!NetUtils.isUnicastMac(macAddress)) {
-            throw new InvalidParameterValueException("Mac address is not unicast: " + macAddress);
-        }
-        return NetUtils.standardizeMacAddress(macAddress);
-    }
-
-    public List<Long> getAffinityGroupIdList() {
-        if (affinityGroupNameList != null && affinityGroupIdList != null) {
-            throw new InvalidParameterValueException("affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
-        }
-
-        // transform group names to ids here
-        if (affinityGroupNameList != null) {
-            List<Long> affinityGroupIds = new ArrayList<Long>();
-            for (String groupName : affinityGroupNameList) {
-                Long groupId = _responseGenerator.getAffinityGroupId(groupName, getEntityOwnerId());
-                if (groupId == null) {
-                    throw new InvalidParameterValueException("Unable to find affinity group by name " + groupName);
-                } else {
-                    affinityGroupIds.add(groupId);
-                }
-            }
-            return affinityGroupIds;
-        } else {
-            return affinityGroupIdList;
-        }
-    }
-
-    public String getKeyboard() {
-        // TODO Auto-generated method stub
-        return keyboard;
-    }
-
-    public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
-        Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
-        if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
-
-            Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
-            for (Map<String, String> dhcpNetworkOptions : paramsCollection) {
-                String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
-
-                if (networkId == null) {
-                    throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
-                }
-
-                Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
-                dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
-
-                for (String key : dhcpNetworkOptions.keySet()) {
-                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
-                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
-                        dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
-                    } else if (!key.equals(ApiConstants.NETWORK_ID)) {
-                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
-                        dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
-                    }
-                }
-
-            }
-        }
-
-        return dhcpOptionsMap;
-    }
-
-    public Map<Long, DiskOffering> getDataDiskTemplateToDiskOfferingMap() {
-        if (diskOfferingId != null && dataDiskTemplateToDiskOfferingList != null) {
-            throw new InvalidParameterValueException("diskofferingid paramter can't be specified along with datadisktemplatetodiskofferinglist parameter");
-        }
-        if (MapUtils.isEmpty(dataDiskTemplateToDiskOfferingList)) {
-            return new HashMap<Long, DiskOffering>();
-        }
-
-        HashMap<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = new HashMap<Long, DiskOffering>();
-        for (Object objDataDiskTemplates : dataDiskTemplateToDiskOfferingList.values()) {
-            HashMap<String, String> dataDiskTemplates = (HashMap<String, String>) objDataDiskTemplates;
-            Long dataDiskTemplateId;
-            DiskOffering dataDiskOffering = null;
-            VirtualMachineTemplate dataDiskTemplate= _entityMgr.findByUuid(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid"));
-            if (dataDiskTemplate == null) {
-                dataDiskTemplate = _entityMgr.findById(VirtualMachineTemplate.class, dataDiskTemplates.get("datadisktemplateid"));
-                if (dataDiskTemplate == null)
-                    throw new InvalidParameterValueException("Unable to translate and find entity with datadisktemplateid " + dataDiskTemplates.get("datadisktemplateid"));
-            }
-            dataDiskTemplateId = dataDiskTemplate.getId();
-            dataDiskOffering = _entityMgr.findByUuid(DiskOffering.class, dataDiskTemplates.get("diskofferingid"));
-            if (dataDiskOffering == null) {
-                dataDiskOffering = _entityMgr.findById(DiskOffering.class, dataDiskTemplates.get("diskofferingid"));
-                if (dataDiskOffering == null)
-                    throw new InvalidParameterValueException("Unable to translate and find entity with diskofferingId " + dataDiskTemplates.get("diskofferingid"));
-            }
-            dataDiskTemplateToDiskOfferingMap.put(dataDiskTemplateId, dataDiskOffering);
-        }
-        return dataDiskTemplateToDiskOfferingMap;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
-        if (accountId == null) {
-            return CallContext.current().getCallingAccount().getId();
-        }
-
-        return accountId;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_CREATE;
-    }
-
-    @Override
-    public String getCreateEventType() {
-        return EventTypes.EVENT_VM_CREATE;
-    }
-
-    @Override
-    public String getCreateEventDescription() {
-        return "creating Vm";
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "starting Vm. Vm Id: " + getEntityId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public void execute() {
-        UserVm result;
-
-        if (getStartVm()) {
-            try {
-                CallContext.current().setEventDetails("Vm Id: " + getEntityId());
-                result = _userVmService.startVirtualMachine(this);
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Exception: ", ex);
-                throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-            } catch (ConcurrentOperationException ex) {
-                s_logger.warn("Exception: ", ex);
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-            } catch (InsufficientCapacityException ex) {
-                StringBuilder message = new StringBuilder(ex.getMessage());
-                if (ex instanceof InsufficientServerCapacityException) {
-                    if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
-                        message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
-                    }
-                }
-                s_logger.info(ex);
-                s_logger.info(message.toString(), ex);
-                throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
-            }
-        } else {
-            result = _userVmService.getUserVm(getEntityId());
-        }
-
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm uuid:"+getEntityUuid());
-        }
-    }
-
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        try {
-            UserVm vm = _userVmService.createVirtualMachine(this);
-
-            if (vm != null) {
-                setEntityId(vm.getId());
-                setEntityUuid(vm.getUuid());
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm");
-            }
-        } catch (InsufficientCapacityException ex) {
-            s_logger.info(ex);
-            s_logger.trace(ex.getMessage(), ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        }  catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (ResourceAllocationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
deleted file mode 100644
index f23e03a..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
+++ /dev/null
@@ -1,137 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "destroyVirtualMachine", description = "Destroys a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-            requestHasSensitiveInfo = false,
-            responseHasSensitiveInfo = true)
-public class DestroyVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DestroyVMCmd.class.getName());
-
-    private static final String s_name = "destroyvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name = ApiConstants.EXPUNGE,
-               type = CommandType.BOOLEAN,
-               description = "If true is passed, the vm is expunged immediately. False by default.",
-               since = "4.2.1")
-    private Boolean expunge;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public boolean getExpunge() {
-        if (expunge == null) {
-            return false;
-        }
-        return expunge;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getId());
-        if (vm != null) {
-            return vm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_DESTROY;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "destroying vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        UserVm result = _userVmService.destroyVm(this);
-
-        UserVmResponse response = new UserVmResponse();
-        if (result != null) {
-            List<UserVmResponse> responses = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result);
-            if (responses != null && !responses.isEmpty()) {
-                response = responses.get(0);
-            }
-            response.setResponseName("virtualmachine");
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
deleted file mode 100644
index e7a0c16..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "rebootVirtualMachine", description = "Reboots a virtual machine.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RebootVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RebootVMCmd.class.getName());
-    private static final String s_name = "rebootvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="The ID of the virtual machine")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getId());
-        if (vm != null) {
-            return vm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_REBOOT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "rebooting user vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        UserVm result;
-        result = _userVmService.rebootVirtualMachine(this);
-        if (result !=null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reboot vm instance");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
deleted file mode 100644
index 19da39a..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveIpFromVmNicCmd.java
+++ /dev/null
@@ -1,182 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.Network;
-import com.cloud.user.Account;
-import com.cloud.vm.NicSecondaryIp;
-
-
-@APICommand(name = "removeIpFromNic", description = "Removes secondary IP from the NIC.", responseObject = SuccessResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveIpFromVmNicCmd.class.getName());
-    private static final String s_name = "removeipfromnicresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @Parameter(name = ApiConstants.ID,
-            type = CommandType.UUID,
-            required = true,
-            entityType = NicSecondaryIpResponse.class,
-            description = "the ID of the secondary ip address to nic")
-    private Long id;
-
-    // unexposed parameter needed for events logging
-    @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, expose = false)
-    private Long ownerId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getEntityTable() {
-        return "nic_secondary_ips";
-    }
-
-    public Long getIpAddressId() {
-        return id;
-    }
-
-    public String getAccountName() {
-        return CallContext.current().getCallingAccount().getAccountName();
-    }
-
-    public long getDomainId() {
-        return CallContext.current().getCallingAccount().getDomainId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account caller = CallContext.current().getCallingAccount();
-        return caller.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN;
-    }
-
-    public NicSecondaryIp getIpEntry() {
-        NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
-        return nicSecIp;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  ("Disassociating ip address with id=" + id);
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "addressinfo";
-    }
-
-    public Long getNetworkId() {
-        NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
-        if (nicSecIp != null) {
-            Long networkId = nicSecIp.getNetworkId();
-            return networkId;
-        } else {
-            return null;
-        }
-    }
-
-    public NetworkType getNetworkType() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        if (ntwk != null) {
-            DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
-            return dc.getNetworkType();
-        }
-        return null;
-    }
-
-
-    private boolean isZoneSGEnabled() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
-        return dc.isSecurityGroupEnabled();
-    }
-
-    @Override
-    public void execute() throws InvalidParameterValueException {
-        CallContext.current().setEventDetails("Ip Id: " + id);
-        NicSecondaryIp nicSecIp = getIpEntry();
-
-        if (nicSecIp == null) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed");
-        }
-
-        if (isZoneSGEnabled()) {
-            //remove the security group rules for this secondary ip
-            boolean success = false;
-            success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getIp4Address(), false);
-            if (success == false) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
-            }
-        }
-
-        try {
-            boolean result = _networkService.releaseSecondaryIpFromNic(id);
-            if (result) {
-                SuccessResponse response = new SuccessResponse(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove secondary  ip address for the nic");
-            }
-        } catch (InvalidParameterValueException e) {
-            throw new InvalidParameterValueException("Removing guest ip from nic failed");
-        }
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.networkSyncObject;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IpAddress;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java
deleted file mode 100644
index d740260..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/RemoveNicFromVMCmd.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "removeNicFromVirtualMachine", description = "Removes VM from specified network by deleting a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RemoveNicFromVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmd.class);
-    private static final String s_name = "removenicfromvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="Virtual Machine ID")
-    private Long vmId;
-
-    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "NIC ID")
-    private Long nicId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    public Long getNicId() {
-        return nicId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NIC_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "Removing NIC " + getNicId() + " from user vm: " + getVmId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getVmId());
-        if (vm == null) {
-             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        }
-        return vm.getAccountId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getVmId() + " Nic Id: " + getNicId());
-        UserVm result = _userVmService.removeNicFromVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NIC from vm, see error log for details");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
deleted file mode 100644
index 44265a3..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "restoreVirtualMachine", description = "Restore a VM to original template/ISO or new template/ISO", responseObject = UserVmResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-            requestHasSensitiveInfo = false,
-            responseHasSensitiveInfo = true)
-public class RestoreVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RestoreVMCmd.class);
-    private static final String s_name = "restorevmresponse";
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="Virtual Machine ID")
-    private Long vmId;
-
-    @Parameter(name = ApiConstants.TEMPLATE_ID,
-               type = CommandType.UUID,
-               entityType = TemplateResponse.class,
-               description = "an optional template Id to restore vm from the new template. This can be an ISO id in case of restore vm deployed using ISO")
-    private Long templateId;
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_RESTORE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Restore a VM to orignal template or specific snapshot";
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-            ResourceAllocationException {
-        UserVm result;
-        CallContext.current().setEventDetails("Vm Id: " + getVmId());
-        result = _userVmService.restoreVM(this);
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to restore vm " + getVmId());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getVmId());
-        if (vm == null) {
-             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        }
-        return vm.getAccountId();
-    }
-
-    public long getVmId() {
-        return vmId;
-    }
-
-    public Long getTemplateId() {
-        return templateId;
-    }
-
-    // TODO - Remove vmid param and make it "id" in 5.0 so that we dont have two getters
-    public Long getId() {
-        return getVmId();
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java
deleted file mode 100644
index 661100b..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/ScaleVMCmd.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-
-@APICommand(name = "scaleVirtualMachine", description = "Scales the virtual machine to a new service offering.", responseObject = SuccessResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ScaleVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ScaleVMCmd.class.getName());
-    private static final String s_name = "scalevirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
-            required=true, description="the ID of the service offering for the virtual machine")
-    private Long serviceOfferingId;
-
-    @Parameter(name = ApiConstants.DETAILS, type = BaseCmd.CommandType.MAP, description = "name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value")
-    private Map<String, String> details;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    //instead of reading a map directly we are using collections.
-    //it is because details.values() cannot be cast to a map.
-    //it gives a exception
-    public Map<String, String> getDetails() {
-        Map<String, String> customparameterMap = new HashMap<String, String>();
-        if (details != null && details.size() != 0) {
-            Collection parameterCollection = details.values();
-            Iterator iter = parameterCollection.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> value = (HashMap<String, String>)iter.next();
-                for (String key : value.keySet()) {
-                    customparameterMap.put(key, value.get(key));
-                }
-            }
-        }
-        return customparameterMap;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
-        if (userVm != null) {
-            return userVm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_UPGRADE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "upgrading vm: " + getId() + " to service offering: " + getServiceOfferingId();
-    }
-
-    @Override
-    public void execute() {
-        UserVm result;
-        try {
-            result = _userVmService.upgradeVirtualMachine(this);
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (ManagementServerException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (VirtualMachineMigrationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        }
-        if (result != null){
-            List<UserVmResponse> responseList = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result);
-            UserVmResponse response = responseList.get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to scale vm");
-        }
-    }
-}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
deleted file mode 100644
index 8289412..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
+++ /dev/null
@@ -1,170 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class StartVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StartVMCmd.class.getName());
-
-    private static final String s_name = "startvirtualmachineresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
-            required = true, description = "The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name = ApiConstants.HOST_ID,
-               type = CommandType.UUID,
-               entityType = HostResponse.class,
-               description = "destination Host ID to deploy the VM to - parameter available for root admin only",
-               since = "3.0.1")
-    private Long hostId;
-
-    @Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
-    private String deploymentPlanner;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getHostId() {
-        return hostId;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getId());
-        if (vm != null) {
-            return vm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
-        // tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_START;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "starting user vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ResourceAllocationException {
-        try {
-            CallContext.current().setEventDetails("Vm Id: " + getId());
-
-            UserVm result;
-            result = _userVmService.startVirtualMachine(this);
-
-            if (result != null) {
-                UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to start a vm");
-            }
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (StorageUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ExecutionException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (InsufficientCapacityException ex) {
-            StringBuilder message = new StringBuilder(ex.getMessage());
-            if (ex instanceof InsufficientServerCapacityException) {
-                if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
-                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
-                }
-            }
-            s_logger.info(ex);
-            s_logger.info(message.toString(), ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
deleted file mode 100644
index 5b2f020..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class StopVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(StopVMCmd.class.getName());
-
-    private static final String s_name = "stopvirtualmachineresponse";
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
-            required = true, description = "The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM "
-        + "(vm is marked as Stopped even when command fails to be send to the backend, otherwise a force poweroff is attempted).  The caller knows the VM is stopped.")
-    private Boolean forced;
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getId());
-        if (vm != null) {
-            return vm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
-// tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_STOP;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "stopping user vm: " + getId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.VirtualMachine;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    public boolean isForced() {
-        return (forced != null) ? forced : false;
-    }
-
-    @Override
-    public void execute() throws ServerApiException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        UserVm result;
-
-        result = _userVmService.stopVirtualMachine(getId(), isForced());
-
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java
deleted file mode 100644
index cffd903..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateDefaultNicForVMCmd.java
+++ /dev/null
@@ -1,120 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "updateDefaultNicForVirtualMachine", description = "Changes the default NIC on a VM", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpdateDefaultNicForVMCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmd.class);
-    private static final String s_name = "updatedefaultnicforvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="Virtual Machine ID")
-    private Long vmId;
-
-    @Parameter(name = ApiConstants.NIC_ID, type = CommandType.UUID, entityType = NicResponse.class, required = true, description = "NIC ID")
-    private Long nicId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    public Long getNicId() {
-        return nicId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NIC_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "Updating NIC " + getNicId() + " on user vm: " + getVmId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm vm = _responseGenerator.findUserVmById(getVmId());
-        if (vm == null) {
-             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        }
-        return vm.getAccountId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Vm Id: " + getVmId() + " Nic Id: " + getNicId());
-        UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set default nic for VM. Refer to server logs for details.");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
deleted file mode 100644
index 57e2e9c..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
+++ /dev/null
@@ -1,271 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
-        "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
-        "Therefore, stop the VM manually before issuing this call.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-    requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction {
-    public static final Logger s_logger = Logger.getLogger(UpdateVMCmd.class.getName());
-    private static final String s_name = "updatevirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.DISPLAY_NAME, type = CommandType.STRING, description = "user generated name")
-    private String displayName;
-
-    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "group of the virtual machine")
-    private String group;
-
-    @Parameter(name = ApiConstants.HA_ENABLE, type = CommandType.BOOLEAN, description = "true if high-availability is enabled for the virtual machine, false otherwise")
-    private Boolean haEnable;
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name = ApiConstants.OS_TYPE_ID,
-               type = CommandType.UUID,
-               entityType = GuestOSResponse.class,
-               description = "the ID of the OS type that best represents this VM.")
-    private Long osTypeId;
-
-    @Parameter(name = ApiConstants.USER_DATA,
-               type = CommandType.STRING,
-               description = "an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding.",
-               length = 32768)
-    private String userData;
-
-    @Parameter(name = ApiConstants.DISPLAY_VM, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vm to the end user or not.", authorized = {RoleType.Admin})
-    private Boolean displayVm;
-
-    @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE,
-               type = CommandType.BOOLEAN,
-               description = "true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
-    protected Boolean isDynamicallyScalable;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "new host name of the vm. The VM has to be stopped/started for this update to take affect", since = "4.4")
-    private String name;
-
-    @Parameter(name = ApiConstants.INSTANCE_NAME, type = CommandType.STRING, description = "instance name of the user vm", since = "4.4", authorized = {RoleType.Admin})
-    private String instanceName;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs.")
-    protected Map<String, String> details;
-
-    @ACL
-    @Parameter(name = ApiConstants.SECURITY_GROUP_IDS,
-               type = CommandType.LIST,
-               collectionType = CommandType.UUID,
-               entityType = SecurityGroupResponse.class,
-               description = "list of security group ids to be applied on the virtual machine.")
-    private List<Long> securityGroupIdList;
-
-    @ACL
-    @Parameter(name = ApiConstants.SECURITY_GROUP_NAMES,
-               type = CommandType.LIST,
-               collectionType = CommandType.STRING,
-               entityType = SecurityGroupResponse.class,
-               description = "comma separated list of security groups names that going to be applied to the virtual machine. " +
-                       "Should be passed only when vm is created from a zone with Basic Network support. " +
-                       "Mutually exclusive with securitygroupids parameter"
-            )
-    private List<String> securityGroupNameList;
-
-    @Parameter(name = ApiConstants.CLEAN_UP_DETAILS,
-            type = CommandType.BOOLEAN,
-            description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
-    private Boolean cleanupDetails;
-
-    @Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
-            + " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
-    private Map dhcpOptionsNetworkList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getDisplayName() {
-        return displayName;
-    }
-
-    public String getGroup() {
-        return group;
-    }
-
-    public Boolean getHaEnable() {
-        return haEnable;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getUserData() {
-        return userData;
-    }
-
-    public Boolean getDisplayVm() {
-        return displayVm;
-    }
-
-    public Boolean isDynamicallyScalable() {
-        return isDynamicallyScalable;
-    }
-
-    public String getHostName() {
-        return name;
-    }
-
-    public String getInstanceName() {
-        return instanceName;
-    }
-
-    public Map<String, String> getDetails() {
-        if (this.details == null || this.details.isEmpty()) {
-            return null;
-        }
-
-        Collection<String> paramsCollection = this.details.values();
-        return (Map<String, String>) (paramsCollection.toArray())[0];
-    }
-
-    public List<Long> getSecurityGroupIdList() {
-        return securityGroupIdList;
-    }
-
-    public List<String> getSecurityGroupNameList() {
-        return securityGroupNameList;
-    }
-
-    public boolean isCleanupDetails(){
-        return cleanupDetails == null ? false : cleanupDetails.booleanValue();
-    }
-
-    public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
-        Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
-        if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
-
-            Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
-            for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
-                String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
-
-                if(networkId == null) {
-                    throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
-                }
-
-                Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
-                dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
-
-                for (String key : dhcpNetworkOptions.keySet()) {
-                    if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
-                        int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
-                        dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
-                    } else if (!key.equals(ApiConstants.NETWORK_ID)) {
-                        Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
-                        dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
-                    }
-                }
-
-            }
-        }
-
-        return dhcpOptionsMap;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getOsTypeId() {
-        return osTypeId;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
-        if (userVm != null) {
-            return userVm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-        UserVm result = _userVmService.updateVirtualMachine(this);
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update vm");
-        }
-    }
-
-    @Override
-    public void checkUuid() {
-        if (getCustomId() != null) {
-            _uuidMgr.checkUuid(getCustomId(), UserVm.class);
-
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java
deleted file mode 100644
index 83fe72e..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-
-@APICommand(name = "updateVmNicIp", description = "Update the default Ip of a VM Nic", responseObject = UserVmResponse.class)
-public class UpdateVmNicIpCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AddIpToVmNicCmd.class.getName());
-    private static final String s_name = "updatevmnicipresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType = NicResponse.class, required = true,
-            description="the ID of the nic to which you want to assign private IP")
-            private Long nicId;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = false,
-            description = "Secondary IP Address")
-            private String ipAddr;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getEntityTable() {
-        return "nic_secondary_ips";
-    }
-
-    public String getAccountName() {
-        return CallContext.current().getCallingAccount().getAccountName();
-    }
-
-    public long getDomainId() {
-        return CallContext.current().getCallingAccount().getDomainId();
-    }
-
-    private long getZoneId() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        if (ntwk == null) {
-            throw new InvalidParameterValueException("Can't find zone id for specified");
-        }
-        return ntwk.getDataCenterId();
-    }
-
-    public Long getNetworkId() {
-        Nic nic = _entityMgr.findById(Nic.class, nicId);
-        if (nic == null) {
-            throw new InvalidParameterValueException("Can't find network id for specified nic");
-        }
-        Long networkId = nic.getNetworkId();
-        return networkId;
-    }
-
-    public Long getNicId() {
-        return nicId;
-    }
-
-    public String getIpaddress () {
-        if (ipAddr != null) {
-            return ipAddr;
-        } else {
-            return null;
-        }
-    }
-
-    public NetworkType getNetworkType() {
-        Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
-        DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
-        return dc.getNetworkType();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NET_IP_ASSIGN;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "associating ip to nic id: " + getNetworkId() + " in zone " + getZoneId();
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "addressinfo";
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, ResourceAllocationException,
-    ConcurrentOperationException, InsufficientCapacityException {
-
-        CallContext.current().setEventDetails("Nic Id: " + getNicId() );
-        String ip;
-        if ((ip = getIpaddress()) != null) {
-            if (!NetUtils.isValidIp4(ip)) {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
-            }
-        }
-
-        UserVm vm = _userVmService.updateNicIpForVirtualMachine(this);
-        ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
-        dc.add(VMDetails.valueOf("nics"));
-        EnumSet<VMDetails> details = EnumSet.copyOf(dc);
-        if (vm != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", details, vm).get(0);
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update ip address on vm NIC. Refer to server logs for details.");
-        }
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.networkSyncObject;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        return getNetworkId();
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IpAddress;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
deleted file mode 100644
index b105555..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
+++ /dev/null
@@ -1,139 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vm;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " +
-                                            "The virtual machine must be in a \"Stopped\" state for " +
-        "this command to take effect.", responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class UpgradeVMCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
-    private static final String s_name = "changeserviceforvirtualmachineresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="The ID of the virtual machine")
-    private Long id;
-
-    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
-            required=true, description="the service offering ID to apply to the virtual machine")
-    protected Long serviceOfferingId;
-
-    @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value")
-    private Map<String, String> details;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    public Map<String, String> getDetails() {
-        Map<String, String> customparameterMap = new HashMap<String, String>();
-        if (details != null && details.size() != 0) {
-            Collection parameterCollection = details.values();
-            Iterator iter = parameterCollection.iterator();
-            while (iter.hasNext()) {
-                HashMap<String, String> value = (HashMap<String, String>)iter.next();
-                for (String key : value.keySet()) {
-                    customparameterMap.put(key, value.get(key));
-                }
-            }
-        }
-        return customparameterMap;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "virtualmachine";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
-        if (userVm != null) {
-            return userVm.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceAllocationException {
-        CallContext.current().setEventDetails("Vm Id: " + getId());
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-        }
-
-        UserVm result = _userVmService.upgradeVirtualMachine(this);
-
-        if (result != null){
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted, "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upgrade vm");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
deleted file mode 100644
index 3e37bbe..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/CreateVMSnapshotCmd.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.api.command.user.vmsnapshot;
-
-import java.util.logging.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
-
-    public static final Logger s_logger = Logger.getLogger(CreateVMSnapshotCmd.class.getName());
-    private static final String s_name = "createvmsnapshotresponse";
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, required = true, entityType = UserVmResponse.class, description = "The ID of the vm")
-    private Long vmId;
-
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_DESCRIPTION, type = CommandType.STRING, required = false, description = "The description of the snapshot")
-    private String description;
-
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_DISPLAYNAME, type = CommandType.STRING, required = false, description = "The display name of the snapshot")
-    private String displayName;
-
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_MEMORY, type = CommandType.BOOLEAN, required = false, description = "snapshot memory if true")
-    private Boolean snapshotMemory;
-
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_QUIESCEVM, type = CommandType.BOOLEAN, required = false, description = "quiesce vm if true")
-    private Boolean quiescevm;
-
-    public Boolean snapshotMemory() {
-        if (snapshotMemory == null) {
-            return false;
-        } else {
-            return snapshotMemory;
-        }
-    }
-
-    public Boolean getQuiescevm() {
-        if (quiescevm == null) {
-            return false;
-        } else {
-            return quiescevm;
-        }
-    }
-
-    public String getDisplayName() {
-        return displayName;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        VMSnapshot vmsnapshot = _vmSnapshotService.allocVMSnapshot(getVmId(), getDisplayName(), getDescription(), snapshotMemory());
-        if (vmsnapshot != null) {
-            setEntityId(vmsnapshot.getId());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create vm snapshot");
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating snapshot for VM: " + getVmId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_SNAPSHOT_CREATE;
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("VM Id: " + getVmId());
-        VMSnapshot result = _vmSnapshotService.createVMSnapshot(getVmId(), getEntityId(), getQuiescevm());
-        if (result != null) {
-            VMSnapshotResponse response = _responseGenerator.createVMSnapshotResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create vm snapshot due to an internal error creating snapshot for vm " + getVmId());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        UserVm userVM = _userVmService.getUserVm(vmId);
-        return userVM.getAccountId();
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
deleted file mode 100644
index 7baad7c..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/DeleteVMSnapshotCmd.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.api.command.user.vmsnapshot;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-@APICommand(name = "deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class, since = "4.2.0", entityType = {VMSnapshot.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteVMSnapshotCmd.class.getName());
-    private static final String s_name = "deletevmsnapshotresponse";
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_ID,
-               type = CommandType.UUID,
-               entityType = VMSnapshotResponse.class,
-               required = true,
-               description = "The ID of the VM snapshot")
-    private Long id;
-
-    public Long getId() {
-        return id;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getId());
-        if (vmSnapshot != null) {
-            return vmSnapshot.getAccountId();
-        }
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("vmsnapshot id: " + getId());
-        boolean result = _vmSnapshotService.deleteVMSnapshot(getId());
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete vm snapshot");
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Delete VM snapshot: " + getId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_SNAPSHOT_DELETE;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java
deleted file mode 100644
index 0ca5009..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vmsnapshot/RevertToVMSnapshotCmd.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vmsnapshot;
-
-import java.util.logging.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-@APICommand(name = "revertToVMSnapshot", description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since = "4.2.0", responseView = ResponseView.Restricted,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
-public class RevertToVMSnapshotCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RevertToVMSnapshotCmd.class.getName());
-    private static final String s_name = "reverttovmsnapshotresponse";
-
-    @ACL(accessType = AccessType.OperateEntry, pointerToEntity = "getVmId()")
-    @Parameter(name = ApiConstants.VM_SNAPSHOT_ID,
-               type = CommandType.UUID,
-               required = true,
-               entityType = VMSnapshotResponse.class,
-               description = "The ID of the vm snapshot")
-    private Long vmSnapShotId;
-
-    public Long getVmSnapShotId() {
-        return vmSnapShotId;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getVmSnapShotId());
-        if (vmSnapshot != null) {
-            return vmSnapshot.getAccountId();
-        }
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute() throws  ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
-        CallContext.current().setEventDetails("vmsnapshot id: " + getVmSnapShotId());
-        UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
-        if (result != null) {
-            UserVmResponse response = _responseGenerator.createUserVmResponse(ResponseView.Restricted,
-                    "virtualmachine", result).get(0);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to revert VM snapshot");
-        }
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Revert from VM snapshot: " + getVmSnapShotId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VM_SNAPSHOT_REVERT;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
deleted file mode 100644
index 7c2a329..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "attachVolume", description = "Attaches a disk volume to a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class AttachVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AttachVolumeCmd.class.getName());
-    private static final String s_name = "attachvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.DEVICE_ID, type = CommandType.LONG, description = "the ID of the device to map the volume to within the guest OS. "
-            + "If no deviceId is passed in, the next available deviceId will be chosen. " + "Possible values for a Linux OS are:" + "* 0 - /dev/xvda" + "* 1 - /dev/xvdb" + "* 2 - /dev/xvdc"
-        + "* 4 - /dev/xvde" + "* 5 - /dev/xvdf" + "* 6 - /dev/xvdg" + "* 7 - /dev/xvdh" + "* 8 - /dev/xvdi" + "* 9 - /dev/xvdj")
-    private Long deviceId;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the disk volume")
-    private Long id;
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
-            required=true, description="    the ID of the virtual machine")
-    private Long virtualMachineId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getDeviceId() {
-        return deviceId;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Volume volume = _responseGenerator.findVolumeById(getId());
-        if (volume == null) {
-            return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
-        }
-        return volume.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_ATTACH;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "attaching volume: " + getId() + " to vm: " + getVirtualMachineId();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Volume Id: " + getId() + " VmId: " + getVirtualMachineId());
-        Volume result = _volumeService.attachVolumeToVM(this);
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to attach volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
deleted file mode 100644
index 54c376e..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
+++ /dev/null
@@ -1,246 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCustomIdCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-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.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Volume;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "createVolume", responseObject = VolumeResponse.class, description = "Creates a disk volume from a disk offering. This disk volume must still be attached to a virtual machine to make use of it.", responseView = ResponseView.Restricted, entityType = {
-        Volume.class, VirtualMachine.class},
-            requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateVolumeCmd.class.getName());
-    private static final String s_name = "createvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT,
-               type = BaseCmd.CommandType.STRING,
-               description = "the account associated with the disk volume. Must be used with the domainId parameter.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.PROJECT_ID,
-               type = CommandType.UUID,
-               entityType = ProjectResponse.class,
-               description = "the project associated with the volume. Mutually exclusive with account parameter")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "the domain ID associated with the disk offering. If used with the account parameter"
-                   + " returns the disk volume associated with the account for the specified domain.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.DISK_OFFERING_ID,
-               required = false,
-               type = CommandType.UUID,
-               entityType = DiskOfferingResponse.class,
-               description = "the ID of the disk offering. Either diskOfferingId or snapshotId must be passed in.")
-    private Long diskOfferingId;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the disk volume")
-    private String volumeName;
-
-    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "Arbitrary volume size")
-    private Long size;
-
-    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, description = "min iops")
-    private Long minIops;
-
-    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, description = "max iops")
-    private Long maxIops;
-
-    @Parameter(name = ApiConstants.SNAPSHOT_ID,
-               type = CommandType.UUID,
-               entityType = SnapshotResponse.class,
-               description = "the snapshot ID for the disk volume. Either diskOfferingId or snapshotId must be passed in.")
-    private Long snapshotId;
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the ID of the availability zone")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.DISPLAY_VOLUME, type = CommandType.BOOLEAN, description = "an optional field, whether to display the volume to the end user or not.", authorized = {RoleType.Admin})
-    private Boolean displayVolume;
-
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = UserVmResponse.class,
-               description = "the ID of the virtual machine; to be used with snapshot Id, VM to which the volume gets attached after creation")
-    private Long virtualMachineId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public Long getDiskOfferingId() {
-        return diskOfferingId;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getVolumeName() {
-        return volumeName;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Long getSnapshotId() {
-        return snapshotId;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    private Long getProjectId() {
-        return projectId;
-    }
-
-    public Boolean getDisplayVolume() {
-        return displayVolume;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        if(displayVolume == null)
-            return true;
-        else
-            return displayVolume;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "volume";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
-        if (accountId == null) {
-            return CallContext.current().getCallingAccount().getId();
-        }
-
-        return accountId;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "creating volume: " + getVolumeName() + ((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId());
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-
-        Volume volume = _volumeService.allocVolume(this);
-        if (volume != null) {
-            setEntityId(volume.getId());
-            setEntityUuid(volume.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create volume");
-        }
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Volume Id: " + getEntityId() + ((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId()));
-        Volume volume = _volumeService.createVolume(this);
-        if (volume != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
-            //FIXME - have to be moved to ApiResponseHelper
-            if (getSnapshotId() != null) {
-                Snapshot snap = _entityMgr.findById(Snapshot.class, getSnapshotId());
-                if (snap != null) {
-                    response.setSnapshotId(snap.getUuid()); // if the volume was
-                    // created from a
-                    // snapshot,
-                    // snapshotId will
-                    // be set so we pass
-                    // it back in the
-                    // response
-                }
-            }
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java
deleted file mode 100644
index 0b0c1b7..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/DeleteVolumeCmd.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-
-@APICommand(name = "deleteVolume", description = "Deletes a detached disk volume.", responseObject = SuccessResponse.class, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DeleteVolumeCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteVolumeCmd.class.getName());
-    private static final String s_name = "deletevolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
-            required=true, description="The ID of the disk volume")
-    private Long id;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "volume";
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Volume volume = _entityMgr.findById(Volume.class, getId());
-        if (volume != null) {
-            return volume.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ConcurrentOperationException {
-        CallContext.current().setEventDetails("Volume Id: " + getId());
-        boolean result = _volumeService.deleteVolume(id, CallContext.current().getCallingAccount());
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java
deleted file mode 100644
index cad0a7f..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/DetachVolumeCmd.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.vm.VirtualMachine;
-
-@APICommand(name = "detachVolume", description = "Detaches a disk volume from a virtual machine.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DetachVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DetachVolumeCmd.class.getName());
-    private static final String s_name = "detachvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
-            description="the ID of the disk volume")
-    private Long id;
-
-    @Parameter(name = ApiConstants.DEVICE_ID, type = CommandType.LONG, description = "the device ID on the virtual machine where volume is detached from")
-    private Long deviceId;
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
-               type = CommandType.UUID,
-               entityType = UserVmResponse.class,
-               description = "the ID of the virtual machine where the volume is detached from")
-    private Long virtualMachineId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getDeviceId() {
-        return deviceId;
-    }
-
-    public Long getVirtualMachineId() {
-        return virtualMachineId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getResultObjectName() {
-        return "volume";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long volumeId = getId();
-        if (volumeId != null) {
-            Volume volume = _responseGenerator.findVolumeById(volumeId);
-            if (volume != null) {
-                return volume.getAccountId();
-            }
-        } else if (getVirtualMachineId() != null) {
-            UserVm vm = _responseGenerator.findUserVmById(getVirtualMachineId());
-            if (vm != null) {
-                return vm.getAccountId();
-            }
-        }
-
-        // invalid id, parent this command to SYSTEM so ERROR events are tracked
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_DETACH;
-    }
-
-    @Override
-    public String getEventDescription() {
-        StringBuilder sb = new StringBuilder();
-        if (id != null) {
-            sb.append(": " + id);
-        } else if ((deviceId != null) && (virtualMachineId != null)) {
-            sb.append(" with device id: " + deviceId + " from vm: " + virtualMachineId);
-        } else {
-            sb.append(" <error:  either volume id or deviceId/vmId need to be specified>");
-        }
-        return  "detaching volume" + sb.toString();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Volume Id: " + getId() + " VmId: " + getVirtualMachineId());
-        Volume result = _volumeService.detachVolumeFromVM(this);
-        if (result != null){
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
-            response.setResponseName("volume");
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to detach volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java
deleted file mode 100644
index fc536d3..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java
+++ /dev/null
@@ -1,158 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Upload;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-
-@APICommand(name = "extractVolume", description = "Extracts volume", responseObject = ExtractResponse.class, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ExtractVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ExtractVolumeCmd.class.getName());
-
-    private static final String s_name = "extractvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
-            required=true, description="the ID of the volume")
-    private Long id;
-
-    @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = false, length = 2048, description = "the url to which the volume would be extracted")
-    private String url;
-
-    @Parameter(name = ApiConstants.ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-               required = true,
-               description = "the ID of the zone where the volume is located")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.MODE, type = CommandType.STRING, required = true, description = "the mode of extraction - HTTP_DOWNLOAD or FTP_UPLOAD")
-    private String mode;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public String getMode() {
-        return mode;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public static String getStaticName() {
-        return s_name;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Volume volume = _entityMgr.findById(Volume.class, getId());
-        if (volume != null) {
-            return volume.getAccountId();
-        }
-
-        // invalid id, parent this command to SYSTEM so ERROR events are tracked
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_EXTRACT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "Extraction job";
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Volume Id: " + getId());
-        String uploadUrl = _volumeService.extractVolume(this);
-        if (uploadUrl != null) {
-            ExtractResponse response = new ExtractResponse();
-            response.setResponseName(getCommandName());
-            response.setObjectName("volume");
-            Volume vol = _entityMgr.findById(Volume.class, id);
-            response.setId(vol.getUuid());
-            response.setName(vol.getName());
-            DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-            response.setMode(mode);
-            response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
-            Account account = _entityMgr.findById(Account.class, getEntityOwnerId());
-            response.setAccountId(account.getUuid());
-            response.setUrl(uploadUrl);
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java
deleted file mode 100644
index e751da3..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-
-import com.cloud.event.EventTypes;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-
-@APICommand(name = "migrateVolume", description = "Migrate volume", responseObject = VolumeResponse.class, since = "3.0.0", responseView = ResponseView.Restricted, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class MigrateVolumeCmd extends BaseAsyncCmd {
-    private static final String s_name = "migratevolumeresponse";
-
-     /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true, description = "the ID of the volume")
-    private Long volumeId;
-
-    @Parameter(name = ApiConstants.STORAGE_ID,
-               type = CommandType.UUID,
-               entityType = StoragePoolResponse.class,
-               required = true,
-               description = "destination storage pool ID to migrate the volume to")
-    private Long storageId;
-
-    @Parameter(name = ApiConstants.LIVE_MIGRATE,
-               type = CommandType.BOOLEAN,
-               required = false,
-               description = "if the volume should be live migrated when it is attached to a running vm")
-    private Boolean liveMigrate;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    // TODO remove this in 5.0 and use id as param instead.
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public Long getId() {
-        return getVolumeId();
-    }
-
-    public Long getStoragePoolId() {
-        return storageId;
-    }
-
-    public boolean isLiveMigrate() {
-        return (liveMigrate != null) ? liveMigrate : false;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-          Volume volume = _entityMgr.findById(Volume.class, getVolumeId());
-          if (volume != null) {
-              return volume.getAccountId();
-          }
-
-          return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_MIGRATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Attempting to migrate volume Id: " + getVolumeId() + " to storage pool Id: " + getStoragePoolId();
-    }
-
-    @Override
-    public void execute() {
-        Volume result;
-
-        result = _volumeService.migrateVolume(this);
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume");
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java
deleted file mode 100644
index 8eea632..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java
+++ /dev/null
@@ -1,189 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.projects.Project;
-import com.cloud.storage.Volume;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "resizeVolume", description = "Resizes a volume", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ResizeVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(ResizeVolumeCmd.class.getName());
-
-    private static final String s_name = "resizevolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the disk volume")
-    private Long id;
-
-    @Parameter(name = ApiConstants.MIN_IOPS, type = CommandType.LONG, required = false, description = "New minimum number of IOPS")
-    private Long minIops;
-
-    @Parameter(name = ApiConstants.MAX_IOPS, type = CommandType.LONG, required = false, description = "New maximum number of IOPS")
-    private Long maxIops;
-
-    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in GB")
-    private Long size;
-
-    @Parameter(name = ApiConstants.SHRINK_OK, type = CommandType.BOOLEAN, required = false, description = "Verify OK to Shrink")
-    private boolean shrinkOk;
-
-    @Parameter(name = ApiConstants.DISK_OFFERING_ID,
-               entityType = DiskOfferingResponse.class,
-               type = CommandType.UUID,
-               required = false,
-               description = "new disk offering id")
-    private Long newDiskOfferingId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public ResizeVolumeCmd() {}
-
-    public ResizeVolumeCmd(Long id, Long minIops, Long maxIops) {
-        this.id = id;
-        this.minIops = minIops;
-        this.maxIops = maxIops;
-    }
-
-    //TODO use the method getId() instead of this one.
-    public Long getEntityId() {
-        return id;
-    }
-
-    public Long getId() {
-        return getEntityId();
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    public boolean getShrinkOk() {
-        return shrinkOk;
-    }
-
-    public Long getNewDiskOfferingId() {
-        return newDiskOfferingId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    public static String getResultObjectName() {
-        return "volume";
-    }
-
-   @Override
-    public long getEntityOwnerId() {
-
-        Volume volume = _entityMgr.findById(Volume.class, getEntityId());
-        if (volume == null) {
-                throw new InvalidParameterValueException("Unable to find volume by id=" + id);
-        }
-
-        Account account = _accountService.getAccount(volume.getAccountId());
-        //Can resize volumes for enabled projects/accounts only
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                Project project = _projectService.findByProjectAccountId(volume.getAccountId());
-            if (project.getState() != Project.State.Active) {
-                throw new PermissionDeniedException("Can't add resources to  project id=" + project.getId() + " in state=" + project.getState() +
-                    " as it's no longer active");
-            }
-        } else if (account.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of volume " + id + "  is disabled: " + account);
-        }
-
-        return volume.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_RESIZE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Volume Id: " + getEntityId() + " to size " + getSize() + "G";
-    }
-
-    @Override
-    public void execute() throws ResourceAllocationException {
-        Volume volume = null;
-        try {
-            CallContext.current().setEventDetails("Volume Id: " + getEntityId() + " to size " + getSize() + "G");
-            volume = _volumeService.resizeVolume(this);
-        } catch (InvalidParameterValueException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
-        }
-
-        if (volume != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
-            //FIXME - have to be moved to ApiResponseHelper
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to resize volume");
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
deleted file mode 100644
index e7e3820..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java
+++ /dev/null
@@ -1,176 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.storage.Volume;
-
-@APICommand(name = "updateVolume", description = "Updates the volume.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateVolumeCmd.class.getName());
-    private static final String s_name = "updatevolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class, description="the ID of the disk volume")
-    private Long id;
-
-    @Parameter(name = ApiConstants.PATH, type = CommandType.STRING, description = "The path of the volume")
-    private String path;
-
-    @Parameter(name = ApiConstants.CHAIN_INFO,
-            type = CommandType.STRING,
-            description = "The chain info of the volume",
-            since = "4.4")
-    private String chainInfo;
-
-    @Parameter(name = ApiConstants.STORAGE_ID,
-               type = CommandType.UUID,
-               entityType = StoragePoolResponse.class,
-               description = "Destination storage pool UUID for the volume",
-               since = "4.3")
-    private Long storageId;
-
-    @Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the volume", since = "4.3")
-    private String state;
-
-    @Parameter(name = ApiConstants.DISPLAY_VOLUME,
-               type = CommandType.BOOLEAN,
- description = "an optional field, whether to the display the volume to the end user or not.", authorized = {RoleType.Admin})
-    private Boolean displayVolume;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getPath() {
-        return path;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public Long getStorageId() {
-        return storageId;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public Boolean getDisplayVolume() {
-        return displayVolume;
-    }
-
-    public String getChainInfo() {
-        return chainInfo;
-    }
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Volume;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return getId();
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Volume volume = _responseGenerator.findVolumeById(getId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("Invalid volume id was provided");
-        }
-        return volume.getAccountId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        StringBuilder desc = new StringBuilder("Updating volume: ");
-        desc.append(getId()).append(" with");
-        if (getPath() != null) {
-            desc.append(" path " + getPath());
-        }
-        if (getStorageId() != null) {
-            desc.append(", storage id " + getStorageId());
-        }
-
-        if (getState() != null) {
-            desc.append(", state " + getState());
-        }
-        return desc.toString();
-    }
-
-    @Override
-    public void execute() {
-        CallContext.current().setEventDetails("Volume Id: " + getId());
-        Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(),
-                getCustomId(), getEntityOwnerId(), getChainInfo());
-        if (result != null) {
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update volume");
-        }
-    }
-
-    @Override
-    public void checkUuid() {
-        if (getCustomId() != null) {
-            _uuidMgr.checkUuid(getCustomId(), Volume.class);
-        }
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
deleted file mode 100644
index a48a89b..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/volume/UploadVolumeCmd.java
+++ /dev/null
@@ -1,180 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.volume;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.storage.Volume;
-
-@APICommand(name = "uploadVolume", description = "Uploads a data disk.", responseObject = VolumeResponse.class, responseView = ResponseView.Restricted, entityType = {Volume.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UploadVolumeCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(UploadVolumeCmd.class.getName());
-    private static final String s_name = "uploadvolumeresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.FORMAT,
-               type = CommandType.STRING,
-               required = true,
-               description = "the format for the volume. Possible values include QCOW2, OVA, and VHD.")
-    private String format;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume")
-    private String volumeName;
-
-    @Parameter(name = ApiConstants.URL,
-               type = CommandType.STRING,
-               required = true,
-               length = 2048,
-               description = "the URL of where the volume is hosted. Possible URL include http:// and https://")
-    private String url;
-
-    @Parameter(name = ApiConstants.ZONE_ID,
-               type = CommandType.UUID,
-               entityType = ZoneResponse.class,
-               required = true,
-               description = "the ID of the zone the volume is to be hosted on")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "an optional domainId. If the account parameter is used, domainId must also be used.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional accountName. Must be used with domainId.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the checksum value of this volume. " + ApiConstants.CHECKSUM_PARAMETER_PREFIX_DESCRIPTION)
-    private String checksum;
-
-    @Parameter(name = ApiConstants.IMAGE_STORE_UUID, type = CommandType.STRING, description = "Image store uuid")
-    private String imageStoreUuid;
-
-    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume for the project")
-    private Long projectId;
-
-    @Parameter(name = ApiConstants.DISK_OFFERING_ID, required = false, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk offering. This must be a custom sized offering since during uploadVolume volume size is unknown.")
-    private Long diskOfferingId;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getFormat() {
-        return format;
-    }
-
-    public String getVolumeName() {
-        return volumeName;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public String getChecksum() {
-        return checksum;
-    }
-
-    public String getImageStoreUuid() {
-        return imageStoreUuid;
-    }
-
-    public Long getDiskOfferingId() {
-        return diskOfferingId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException, NetworkRuleConflictException {
-
-            Volume volume = _volumeService.uploadVolume(this);
-            if (volume != null){
-            VolumeResponse response = _responseGenerator.createVolumeResponse(ResponseView.Restricted, volume);
-                response.setResponseName(getCommandName());
-                setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upload volume");
-            }
-    }
-
-    @Override
-    public String getCommandName() {
-           return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
-        if (accountId == null) {
-            return CallContext.current().getCallingAccount().getId();
-        }
-
-        return accountId;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return  "uploading volume: " + getVolumeName() + " in the zone " + getZoneId();
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VOLUME_UPLOAD;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
deleted file mode 100644
index 94d0e6e..0000000
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/UpdateVPCCmd.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.user.vpc;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.VpcResponse;
-
-import com.cloud.event.EventTypes;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.user.Account;
-
-@APICommand(name = "updateVPC", description = "Updates a VPC", responseObject = VpcResponse.class, responseView = ResponseView.Restricted, entityType = {Vpc.class},
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class UpdateVPCCmd extends BaseAsyncCustomIdCmd {
-    public static final Logger s_logger = Logger.getLogger(UpdateVPCCmd.class.getName());
-    private static final String s_name = "updatevpcresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @ACL(accessType = AccessType.OperateEntry)
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VpcResponse.class, required = true, description = "the id of the VPC")
-    private Long id;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the VPC")
-    private String vpcName;
-
-    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the VPC")
-    private String displayText;
-
-    @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vpc to the end user or not", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean display;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getVpcName() {
-        return vpcName;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public Boolean getDisplayVpc() {
-        return display;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Vpc vpc = _entityMgr.findById(Vpc.class, getId());
-        if (vpc != null) {
-            return vpc.getAccountId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), getDisplayVpc());
-        if (result != null) {
-            VpcResponse response = _responseGenerator.createVpcResponse(ResponseView.Restricted, result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VPC");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_VPC_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "updating VPC id=" + getId();
-    }
-
-    @Override
-    public String getSyncObjType() {
-        return BaseAsyncCmd.vpcSyncObject;
-    }
-
-    @Override
-    public Long getSyncObjId() {
-        return getId();
-    }
-
-    @Override
-    public void checkUuid() {
-        if (getCustomId() != null) {
-            _uuidMgr.checkUuid(getCustomId(), Vpc.class);
-        }
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java b/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
deleted file mode 100644
index 70bbeee..0000000
--- a/api/src/org/apache/cloudstack/api/response/AsyncJobResponse.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.Date;
-
-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 org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.jobs.JobInfo;
-
-import com.cloud.serializer.Param;
-
-@EntityReference(value = JobInfo.class)
-public class AsyncJobResponse extends BaseResponse {
-
-    @SerializedName("accountid")
-    @Param(description = "the account that executed the async command")
-    private String accountId;
-
-    @SerializedName(ApiConstants.USER_ID)
-    @Param(description = "the user that executed the async command")
-    private String userId;
-
-    @SerializedName("cmd")
-    @Param(description = "the async command executed")
-    private String cmd;
-
-    @SerializedName("jobstatus")
-    @Param(description = "the current job status-should be 0 for PENDING")
-    private Integer jobStatus;
-
-    @SerializedName("jobprocstatus")
-    @Param(description = "the progress information of the PENDING job")
-    private Integer jobProcStatus;
-
-    @SerializedName("jobresultcode")
-    @Param(description = "the result code for the job")
-    private Integer jobResultCode;
-
-    @SerializedName("jobresulttype")
-    @Param(description = "the result type")
-    private String jobResultType;
-
-    @SerializedName("jobresult")
-    @Param(description = "the result reason")
-    private ResponseObject jobResult;
-
-    @SerializedName("jobinstancetype")
-    @Param(description = "the instance/entity object related to the job")
-    private String jobInstanceType;
-
-    @SerializedName("jobinstanceid")
-    @Param(description = "the unique ID of the instance/entity object related to the job")
-    private String jobInstanceId;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "  the created date of the job")
-    private Date created;
-
-    public void setAccountId(String accountId) {
-        this.accountId = accountId;
-    }
-
-    public void setUserId(String userId) {
-        this.userId = userId;
-    }
-
-    public void setCmd(String cmd) {
-        this.cmd = cmd;
-    }
-
-    @Override
-    public void setJobStatus(Integer jobStatus) {
-        this.jobStatus = jobStatus;
-    }
-
-    public void setJobProcStatus(Integer jobProcStatus) {
-        this.jobProcStatus = jobProcStatus;
-    }
-
-    public void setJobResultCode(Integer jobResultCode) {
-        this.jobResultCode = jobResultCode;
-    }
-
-    public void setJobResultType(String jobResultType) {
-        this.jobResultType = jobResultType;
-    }
-
-    public void setJobResult(ResponseObject jobResult) {
-        this.jobResult = jobResult;
-    }
-
-    public void setJobInstanceType(String jobInstanceType) {
-        this.jobInstanceType = jobInstanceType;
-    }
-
-    public void setJobInstanceId(String jobInstanceId) {
-        this.jobInstanceId = jobInstanceId;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
deleted file mode 100644
index f579119..0000000
--- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
+++ /dev/null
@@ -1,267 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.Date;
-
-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.offering.DiskOffering;
-import com.cloud.serializer.Param;
-
-@EntityReference(value = DiskOffering.class)
-public class DiskOfferingResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "unique ID of the disk offering")
-    private String id;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the domain ID this disk offering belongs to. Ignore this information as it is not currently applicable.")
-    private String domainId;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "the domain name this disk offering belongs to. Ignore this information as it is not currently applicable.")
-    private String domain;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the disk offering")
-    private String name;
-
-    @SerializedName(ApiConstants.DISPLAY_TEXT)
-    @Param(description = "an alternate display text of the disk offering.")
-    private String displayText;
-
-    @SerializedName(ApiConstants.DISK_SIZE)
-    @Param(description = "the size of the disk offering in GB")
-    private Long diskSize;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "the date this disk offering was created")
-    private Date created;
-
-    @SerializedName("iscustomized")
-    @Param(description = "true if disk offering uses custom size, false otherwise")
-    private Boolean customized;
-
-    @SerializedName("iscustomizediops")
-    @Param(description = "true if disk offering uses custom iops, false otherwise")
-    private Boolean customizedIops;
-
-    @SerializedName(ApiConstants.MIN_IOPS)
-    @Param(description = "the min iops of the disk offering")
-    private Long minIops;
-
-    @SerializedName(ApiConstants.MAX_IOPS)
-    @Param(description = "the max iops of the disk offering")
-    private Long maxIops;
-
-    @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE)
-    @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4")
-    private Integer hypervisorSnapshotReserve;
-
-    @SerializedName(ApiConstants.TAGS)
-    @Param(description = "the tags for the disk offering")
-    private String tags;
-
-    @SerializedName("storagetype")
-    @Param(description = "the storage type for this disk offering")
-    private String storageType;
-
-    @SerializedName("provisioningtype") @Param(description="provisioning type used to create volumes. Valid values are thin, sparse, fat.", since = "4.4.0")
-    private String provisioningType;
-
-    @SerializedName("diskBytesReadRate")
-    @Param(description = "bytes read rate of the disk offering")
-    private Long bytesReadRate;
-
-    @SerializedName("diskBytesWriteRate")
-    @Param(description = "bytes write rate of the disk offering")
-    private Long bytesWriteRate;
-
-    @SerializedName("diskIopsReadRate")
-    @Param(description = "io requests read rate of the disk offering")
-    private Long iopsReadRate;
-
-    @SerializedName("diskIopsWriteRate")
-    @Param(description = "io requests write rate of the disk offering")
-    private Long iopsWriteRate;
-
-    @SerializedName("cacheMode")
-    @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough", since = "4.4")
-    private String cacheMode;
-
-    @SerializedName("displayoffering")
-    @Param(description = "whether to display the offering to the end user or not.")
-    private Boolean displayOffering;
-
-    public Boolean getDisplayOffering() {
-        return displayOffering;
-    }
-
-    public void setDisplayOffering(Boolean displayOffering) {
-        this.displayOffering = displayOffering;
-    }
-
-    public String getId() {
-        return id;
-
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getDomainId() {
-        return domainId;
-    }
-
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-
-    public void setDomain(String domain) {
-        this.domain = domain;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    public Long getDiskSize() {
-        return diskSize;
-    }
-
-    public void setDiskSize(Long diskSize) {
-        this.diskSize = diskSize;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public void setTags(String tags) {
-        this.tags = tags;
-    }
-
-    public Boolean isCustomized() {
-        return customized;
-    }
-
-    public void setCustomized(Boolean customized) {
-        this.customized = customized;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public void setCustomizedIops(Boolean customizedIops) {
-        this.customizedIops = customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public void setMinIops(Long minIops) {
-        this.minIops = minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public void setMaxIops(Long maxIops) {
-        this.maxIops = maxIops;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
-        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
-    }
-
-    public String getCacheMode() {
-        return cacheMode;
-    }
-
-    public void setCacheMode(String cacheMode) {
-        this.cacheMode = cacheMode;
-    }
-
-    public String getStorageType() {
-        return storageType;
-    }
-
-    public void setStorageType(String storageType) {
-        this.storageType = storageType;
-    }
-
-    public String getProvisioningType(){
-        return provisioningType;
-    }
-
-    public void setProvisioningType(String provisioningType){
-        this.provisioningType = provisioningType;
-    }
-
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/ExtractResponse.java b/api/src/org/apache/cloudstack/api/response/ExtractResponse.java
deleted file mode 100644
index fa7488f..0000000
--- a/api/src/org/apache/cloudstack/api/response/ExtractResponse.java
+++ /dev/null
@@ -1,218 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.Date;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class ExtractResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the id of extracted object")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the extracted object")
-    private String name;
-
-    @SerializedName("extractId")
-    @Param(description = "the upload id of extracted object")
-    private String uploadId;
-
-    @SerializedName("uploadpercentage")
-    @Param(description = "the percentage of the entity uploaded to the specified location")
-    private Integer uploadPercent;
-
-    @SerializedName("status")
-    @Param(description = "the status of the extraction")
-    private String status;
-
-    @SerializedName("accountid")
-    @Param(description = "the account id to which the extracted object belongs")
-    private String accountId;
-
-    @SerializedName("resultstring")
-    @Param(includeInApiDoc = false)
-    private String resultString;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "the time and date the object was created")
-    private Date createdDate;
-
-    @SerializedName(ApiConstants.STATE)
-    @Param(description = "the state of the extracted object")
-    private String state;
-
-    @SerializedName("storagetype")
-    @Param(description = "type of the storage")
-    private String storageType;
-
-    @SerializedName("storage")
-    private String storage;
-
-    @SerializedName(ApiConstants.ZONE_ID)
-    @Param(description = "zone ID the object was extracted from")
-    private String zoneId;
-
-    @SerializedName(ApiConstants.ZONE_NAME)
-    @Param(description = "zone name the object was extracted from")
-    private String zoneName;
-
-    @SerializedName("extractMode")
-    @Param(description = "the mode of extraction - upload or download")
-    private String mode;
-
-    @SerializedName(ApiConstants.URL)
-    @Param(description = "if mode = upload then url of the uploaded entity. if mode = download the url from which the entity can be downloaded")
-    private String url;
-
-    public ExtractResponse() {
-    }
-
-    public ExtractResponse(String typeId, String typeName, String accountId, String state, String uploadId) {
-        this.id = typeId;
-        this.name = typeName;
-        this.accountId = accountId;
-        this.state = state;
-        this.uploadId = uploadId;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getUploadId() {
-        return uploadId;
-    }
-
-    public void setUploadId(String uploadId) {
-        this.uploadId = uploadId;
-    }
-
-    public Integer getUploadPercent() {
-        return uploadPercent;
-    }
-
-    public void setUploadPercent(int uploadPercent) {
-        this.uploadPercent = uploadPercent;
-    }
-
-    public String getUploadStatus() {
-        return status;
-    }
-
-    public void setUploadStatus(String status) {
-        this.status = status;
-    }
-
-    public String getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(String accountId) {
-        this.accountId = accountId;
-    }
-
-    public String getResultString() {
-        return resultString;
-    }
-
-    public void setResultString(String resultString) {
-        this.resultString = resultString;
-    }
-
-    public Date getCreatedDate() {
-        return createdDate;
-    }
-
-    public void setCreatedDate(Date createdDate) {
-        this.createdDate = createdDate;
-    }
-
-    public String getState() {
-        return state;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    public String getStorageType() {
-        return storageType;
-    }
-
-    public void setStorageType(String storageType) {
-        this.storageType = storageType;
-    }
-
-    public String getStorage() {
-        return storage;
-    }
-
-    public void setStorage(String storage) {
-        this.storage = storage;
-    }
-
-    public String getZoneId() {
-        return zoneId;
-    }
-
-    public void setZoneId(String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    public String getZoneName() {
-        return zoneName;
-    }
-
-    public void setZoneName(String zoneName) {
-        this.zoneName = zoneName;
-    }
-
-    public String getMode() {
-        return mode;
-    }
-
-    public void setMode(String mode) {
-        this.mode = mode;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java
deleted file mode 100644
index b9667ec..0000000
--- a/api/src/org/apache/cloudstack/api/response/HostResponse.java
+++ /dev/null
@@ -1,664 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import com.cloud.host.Host;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-import org.apache.cloudstack.ha.HAConfig;
-import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@EntityReference(value = Host.class)
-public class HostResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the ID of the host")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the host")
-    private String name;
-
-    @SerializedName(ApiConstants.STATE)
-    @Param(description = "the state of the host")
-    private Status state;
-
-    @SerializedName("disconnected")
-    @Param(description = "true if the host is disconnected. False otherwise.")
-    private Date disconnectedOn;
-
-    @SerializedName(ApiConstants.TYPE)
-    @Param(description = "the host type")
-    private Host.Type hostType;
-
-    @SerializedName("oscategoryid")
-    @Param(description = "the OS category ID of the host")
-    private String osCategoryId;
-
-    @SerializedName("oscategoryname")
-    @Param(description = "the OS category name of the host")
-    private String osCategoryName;
-
-    @SerializedName(ApiConstants.IP_ADDRESS)
-    @Param(description = "the IP address of the host")
-    private String ipAddress;
-
-    @SerializedName(ApiConstants.ZONE_ID)
-    @Param(description = "the Zone ID of the host")
-    private String zoneId;
-
-    @SerializedName(ApiConstants.ZONE_NAME)
-    @Param(description = "the Zone name of the host")
-    private String zoneName;
-
-    @SerializedName(ApiConstants.POD_ID)
-    @Param(description = "the Pod ID of the host")
-    private String podId;
-
-    @SerializedName("podname")
-    @Param(description = "the Pod name of the host")
-    private String podName;
-
-    @SerializedName("version")
-    @Param(description = "the host version")
-    private String version;
-
-    @SerializedName(ApiConstants.HYPERVISOR)
-    @Param(description = "the host hypervisor")
-    private HypervisorType hypervisor;
-
-    @SerializedName("cpusockets")
-    @Param(description = "the number of CPU sockets on the host")
-    private Integer cpuSockets;
-
-    @SerializedName("cpunumber")
-    @Param(description = "the CPU number of the host")
-    private Integer cpuNumber;
-
-    @SerializedName("cpuspeed")
-    @Param(description = "the CPU speed of the host")
-    private Long cpuSpeed;
-
-    @SerializedName("cpuallocated")
-    @Param(description = "the amount of the host's CPU currently allocated")
-    private String cpuAllocated;
-
-    @SerializedName("cpuused")
-    @Param(description = "the amount of the host's CPU currently used")
-    private String cpuUsed;
-
-    @SerializedName("cpuwithoverprovisioning")
-    @Param(description = "the amount of the host's CPU after applying the cpu.overprovisioning.factor ")
-    private String cpuWithOverprovisioning;
-
-    @SerializedName("averageload")
-    @Param(description = "the cpu average load on the host")
-    private Long averageLoad;
-
-    @SerializedName("networkkbsread")
-    @Param(description = "the incoming network traffic on the host")
-    private Long networkKbsRead;
-
-    @SerializedName("networkkbswrite")
-    @Param(description = "the outgoing network traffic on the host")
-    private Long networkKbsWrite;
-
-    @Deprecated
-    @SerializedName("memorytotal")
-    @Param(description = "the memory total of the host, this parameter is deprecated use memorywithoverprovisioning")
-    private Long memoryTotal;
-
-    @SerializedName("memorywithoverprovisioning")
-    @Param(description = "the amount of the host's memory after applying the mem.overprovisioning.factor")
-    private String memWithOverprovisioning;
-
-    @SerializedName("memoryallocated")
-    @Param(description = "the amount of the host's memory currently allocated")
-    private long memoryAllocated;
-
-    @SerializedName("memoryused")
-    @Param(description = "the amount of the host's memory currently used")
-    private Long memoryUsed;
-
-    @SerializedName(ApiConstants.GPUGROUP)
-    @Param(description = "GPU cards present in the host", responseObject = GpuResponse.class, since = "4.4")
-    private List<GpuResponse> gpuGroup;
-
-    @SerializedName("disksizetotal")
-    @Param(description = "the total disk size of the host")
-    private Long diskSizeTotal;
-
-    @SerializedName("disksizeallocated")
-    @Param(description = "the host's currently allocated disk size")
-    private Long diskSizeAllocated;
-
-    @SerializedName("capabilities")
-    @Param(description = "capabilities of the host")
-    private String capabilities;
-
-    @SerializedName("lastpinged")
-    @Param(description = "the date and time the host was last pinged")
-    private Date lastPinged;
-
-    @SerializedName("managementserverid")
-    @Param(description = "the management server ID of the host")
-    private Long managementServerId;
-
-    @SerializedName("clusterid")
-    @Param(description = "the cluster ID of the host")
-    private String clusterId;
-
-    @SerializedName("clustername")
-    @Param(description = "the cluster name of the host")
-    private String clusterName;
-
-    @SerializedName("clustertype")
-    @Param(description = "the cluster type of the cluster that host belongs to")
-    private String clusterType;
-
-    @SerializedName("islocalstorageactive")
-    @Param(description = "true if local storage is active, false otherwise")
-    private Boolean localStorageActive;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "the date and time the host was created")
-    private Date created;
-
-    @SerializedName("removed")
-    @Param(description = "the date and time the host was removed")
-    private Date removed;
-
-    @SerializedName("events")
-    @Param(description = "events available for the host")
-    private String events;
-
-    @SerializedName("hosttags")
-    @Param(description = "comma-separated list of tags for the host")
-    private String hostTags;
-
-    @SerializedName("hasenoughcapacity")
-    @Param(description = "true if this host has enough CPU and RAM capacity to migrate a VM to it, false otherwise")
-    private Boolean hasEnoughCapacity;
-
-    @SerializedName("suitableformigration")
-    @Param(description = "true if this host is suitable(has enough capacity and satisfies all conditions like hosttags, max guests vm limit etc) to migrate a VM to it , false otherwise")
-    private Boolean suitableForMigration;
-
-    @SerializedName("hostha")
-    @Param(description = "the host HA information information")
-    private HostHAResponse hostHAResponse;
-
-    @SerializedName("outofbandmanagement")
-    @Param(description = "the host out-of-band management information")
-    private OutOfBandManagementResponse outOfBandManagementResponse;
-
-    @SerializedName("resourcestate")
-    @Param(description = "the resource state of the host")
-    private String resourceState;
-
-    @SerializedName(ApiConstants.HYPERVISOR_VERSION)
-    @Param(description = "the hypervisor version")
-    private String hypervisorVersion;
-
-    @SerializedName(ApiConstants.HA_HOST)
-    @Param(description = "true if the host is Ha host (dedicated to vms started by HA process; false otherwise")
-    private Boolean haHost;
-
-    @SerializedName(ApiConstants.DETAILS)
-    @Param(description = "Host details in key/value pairs.", since = "4.5")
-    private Map details;
-
-    @SerializedName(ApiConstants.ANNOTATION)
-    @Param(description = "the last annotation set on this host by an admin", since = "4.11")
-    private String annotation;
-
-    @SerializedName(ApiConstants.LAST_ANNOTATED)
-    @Param(description = "the last time this host was annotated", since = "4.11")
-    private Date lastAnnotated;
-
-    @SerializedName(ApiConstants.USERNAME)
-    @Param(description = "the admin that annotated this host", since = "4.11")
-    private String username;
-
-    // Default visibility to support accessing the details from unit tests
-    Map getDetails() {
-        return details;
-    }
-
-    @Override
-    public String getObjectId() {
-        return this.getId();
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setState(Status state) {
-        this.state = state;
-    }
-
-    public void setDisconnectedOn(Date disconnectedOn) {
-        this.disconnectedOn = disconnectedOn;
-    }
-
-    public void setHostType(Host.Type hostType) {
-        this.hostType = hostType;
-    }
-
-    public void setOsCategoryId(String osCategoryId) {
-        this.osCategoryId = osCategoryId;
-    }
-
-    public void setOsCategoryName(String osCategoryName) {
-        this.osCategoryName = osCategoryName;
-    }
-
-    public void setIpAddress(String ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-
-    public void setZoneId(String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    public void setZoneName(String zoneName) {
-        this.zoneName = zoneName;
-    }
-
-    public void setPodId(String podId) {
-        this.podId = podId;
-    }
-
-    public void setPodName(String podName) {
-        this.podName = podName;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    public void setHypervisor(HypervisorType hypervisor) {
-        this.hypervisor = hypervisor;
-    }
-
-    public void setCpuSockets(Integer cpuSockets) {
-        this.cpuSockets = cpuSockets;
-    }
-
-    public void setCpuNumber(Integer cpuNumber) {
-        this.cpuNumber = cpuNumber;
-    }
-
-    public void setCpuSpeed(Long cpuSpeed) {
-        this.cpuSpeed = cpuSpeed;
-    }
-
-    public String getCpuAllocated() {
-        return cpuAllocated;
-    }
-
-    public void setCpuAllocated(String cpuAllocated) {
-        this.cpuAllocated = cpuAllocated;
-    }
-
-    public void setCpuUsed(String cpuUsed) {
-        this.cpuUsed = cpuUsed;
-    }
-
-    public void setAverageLoad(Long averageLoad) {
-        this.averageLoad = averageLoad;
-    }
-
-    public void setNetworkKbsRead(Long networkKbsRead) {
-        this.networkKbsRead = networkKbsRead;
-    }
-
-    public void setNetworkKbsWrite(Long networkKbsWrite) {
-        this.networkKbsWrite = networkKbsWrite;
-    }
-
-    public void setMemWithOverprovisioning(String memWithOverprovisioning){
-        this.memWithOverprovisioning=memWithOverprovisioning;
-    }
-
-    public void setMemoryAllocated(long memoryAllocated) {
-        this.memoryAllocated = memoryAllocated;
-    }
-
-    public void setMemoryUsed(Long memoryUsed) {
-        this.memoryUsed = memoryUsed;
-    }
-
-    public void setGpuGroups(List<GpuResponse> gpuGroup) {
-        this.gpuGroup = gpuGroup;
-    }
-
-    public void setDiskSizeTotal(Long diskSizeTotal) {
-        this.diskSizeTotal = diskSizeTotal;
-    }
-
-    public void setDiskSizeAllocated(Long diskSizeAllocated) {
-        this.diskSizeAllocated = diskSizeAllocated;
-    }
-
-    public void setCapabilities(String capabilities) {
-        this.capabilities = capabilities;
-    }
-
-    public void setLastPinged(Date lastPinged) {
-        this.lastPinged = lastPinged;
-    }
-
-    public void setManagementServerId(Long managementServerId) {
-        this.managementServerId = managementServerId;
-    }
-
-    public void setClusterId(String clusterId) {
-        this.clusterId = clusterId;
-    }
-
-    public void setClusterName(String clusterName) {
-        this.clusterName = clusterName;
-    }
-
-    public void setClusterType(String clusterType) {
-        this.clusterType = clusterType;
-    }
-
-    public void setLocalStorageActive(Boolean localStorageActive) {
-        this.localStorageActive = localStorageActive;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public void setRemoved(Date removed) {
-        this.removed = removed;
-    }
-
-    public void setEvents(String events) {
-        this.events = events;
-    }
-
-    public String getHostTags() {
-        return hostTags;
-    }
-
-    public void setHostTags(String hostTags) {
-        this.hostTags = hostTags;
-    }
-
-    public void setHasEnoughCapacity(Boolean hasEnoughCapacity) {
-        this.hasEnoughCapacity = hasEnoughCapacity;
-    }
-
-    public void setSuitableForMigration(Boolean suitableForMigration) {
-        this.suitableForMigration = suitableForMigration;
-    }
-
-    public HostHAResponse getHostHAResponse() {
-        return hostHAResponse;
-    }
-
-    public void setHostHAResponse(final HAConfig config) {
-        this.hostHAResponse = new HostHAResponse(config);
-    }
-
-    public OutOfBandManagementResponse getOutOfBandManagementResponse() {
-        return outOfBandManagementResponse;
-    }
-
-    public void setOutOfBandManagementResponse(final OutOfBandManagement outOfBandManagementConfig) {
-        this.outOfBandManagementResponse =  new OutOfBandManagementResponse(outOfBandManagementConfig);
-    }
-
-    public String getResourceState() {
-        return resourceState;
-    }
-
-    public void setResourceState(String resourceState) {
-        this.resourceState = resourceState;
-    }
-
-    public String getCpuWithOverprovisioning() {
-        return cpuWithOverprovisioning;
-    }
-
-    public void setCpuWithOverprovisioning(String cpuWithOverprovisioning) {
-        this.cpuWithOverprovisioning = cpuWithOverprovisioning;
-    }
-
-    public void setHypervisorVersion(String hypervisorVersion) {
-        this.hypervisorVersion = hypervisorVersion;
-    }
-
-    public void setHaHost(Boolean haHost) {
-        this.haHost = haHost;
-    }
-
-    public void setAnnotation(String annotation) {
-        this.annotation = annotation;
-    }
-
-    public void setLastAnnotated(Date lastAnnotated) {
-        this.lastAnnotated = lastAnnotated;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public void setDetails(Map details) {
-
-        if (details == null) {
-            return;
-        }
-
-        final Map detailsCopy = new HashMap(details);
-
-        // Fix for CVE ID 2015-3251
-        // Remove sensitive host credential information from
-        // the details to prevent leakage through API calls
-        detailsCopy.remove("username");
-        detailsCopy.remove("password");
-
-        this.details = detailsCopy;
-
-    }
-
-    public void setMemoryTotal(Long memoryTotal) {
-        this.memoryTotal = memoryTotal;
-    }
-    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/NetworkACLItemResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java
deleted file mode 100644
index 0101295..0000000
--- a/api/src/org/apache/cloudstack/api/response/NetworkACLItemResponse.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.List;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
-
-@EntityReference(value = NetworkACLItem.class)
-public class NetworkACLItemResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the ID of the ACL Item")
-    private String id;
-
-    @SerializedName(ApiConstants.PROTOCOL)
-    @Param(description = "the protocol of the ACL")
-    private String protocol;
-
-    @SerializedName(ApiConstants.START_PORT)
-    @Param(description = "the starting port of ACL's port range")
-    private String startPort;
-
-    @SerializedName(ApiConstants.END_PORT)
-    @Param(description = "the ending port of ACL's port range")
-    private String endPort;
-
-    @SerializedName(ApiConstants.TRAFFIC_TYPE)
-    @Param(description = "the traffic type for the ACL")
-    private String trafficType;
-
-    @SerializedName(ApiConstants.STATE)
-    @Param(description = "the state of the rule")
-    private String state;
-
-    @SerializedName(ApiConstants.CIDR_LIST)
-    @Param(description = "the cidr list to forward traffic from")
-    private String cidrList;
-
-    @SerializedName(ApiConstants.ICMP_TYPE)
-    @Param(description = "type of the icmp message being sent")
-    private Integer icmpType;
-
-    @SerializedName(ApiConstants.ICMP_CODE)
-    @Param(description = "error code for this icmp message")
-    private Integer icmpCode;
-
-    @SerializedName(ApiConstants.TAGS)
-    @Param(description = "the list of resource tags associated with the network ACLs", responseObject = ResourceTagResponse.class)
-    private List<ResourceTagResponse> tags;
-
-    @SerializedName(ApiConstants.ACL_ID)
-    @Param(description = "the ID of the ACL this item belongs to")
-    private String aclId;
-
-    @SerializedName(ApiConstants.NUMBER)
-    @Param(description = "Number of the ACL Item")
-    private Integer number;
-
-    @SerializedName(ApiConstants.ACTION)
-    @Param(description = "Action of ACL Item. Allow/Deny")
-    private String action;
-
-    @SerializedName(ApiConstants.FOR_DISPLAY)
-    @Param(description = "is rule for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean forDisplay;
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setProtocol(String protocol) {
-        this.protocol = protocol;
-    }
-
-    public void setStartPort(String startPort) {
-        this.startPort = startPort;
-    }
-
-    public void setEndPort(String endPort) {
-        this.endPort = endPort;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    public void setCidrList(String cidrList) {
-        this.cidrList = cidrList;
-    }
-
-    public void setIcmpType(Integer icmpType) {
-        this.icmpType = icmpType;
-    }
-
-    public void setIcmpCode(Integer icmpCode) {
-        this.icmpCode = icmpCode;
-    }
-
-    public void setTrafficType(String trafficType) {
-        this.trafficType = trafficType;
-    }
-
-    public void setTags(List<ResourceTagResponse> tags) {
-        this.tags = tags;
-    }
-
-    public void setAclId(String aclId) {
-        this.aclId = aclId;
-    }
-
-    public void setNumber(Integer number) {
-        this.number = number;
-    }
-
-    public void setAction(String action) {
-        this.action = action;
-    }
-
-    public void setForDisplay(Boolean forDisplay) {
-        this.forDisplay = forDisplay;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
deleted file mode 100644
index d004e7e..0000000
--- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
+++ /dev/null
@@ -1,380 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.Date;
-import java.util.Map;
-
-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.offering.ServiceOffering;
-import com.cloud.serializer.Param;
-
-@EntityReference(value = ServiceOffering.class)
-public class ServiceOfferingResponse extends BaseResponse {
-    @SerializedName("id")
-    @Param(description = "the id of the service offering")
-    private String id;
-
-    @SerializedName("name")
-    @Param(description = "the name of the service offering")
-    private String name;
-
-    @SerializedName("displaytext")
-    @Param(description = "an alternate display text of the service offering.")
-    private String displayText;
-
-    @SerializedName("cpunumber")
-    @Param(description = "the number of CPU")
-    private Integer cpuNumber;
-
-    @SerializedName("cpuspeed")
-    @Param(description = "the clock rate CPU speed in Mhz")
-    private Integer cpuSpeed;
-
-    @SerializedName("memory")
-    @Param(description = "the memory in MB")
-    private Integer memory;
-
-    @SerializedName("created")
-    @Param(description = "the date this service offering was created")
-    private Date created;
-
-    @SerializedName("storagetype")
-    @Param(description = "the storage type for this service offering")
-    private String storageType;
-
-    @SerializedName("provisioningtype") @Param(description="provisioning type used to create volumes. Valid values are thin, sparse, fat.", since = "4.4.0")
-    private String provisioningType;
-
-    @SerializedName("offerha")
-    @Param(description = "the ha support in the service offering")
-    private Boolean offerHa;
-
-    @SerializedName("limitcpuuse")
-    @Param(description = "restrict the CPU usage to committed service offering")
-    private Boolean limitCpuUse;
-
-    @SerializedName("isvolatile")
-    @Param(description = "true if the vm needs to be volatile, i.e., on every reboot of vm from API root disk is discarded and creates a new root disk")
-    private Boolean isVolatile;
-
-    @SerializedName("tags")
-    @Param(description = "the tags for the service offering")
-    private String tags;
-
-    @SerializedName("domainid")
-    @Param(description = "the domain id of the service offering")
-    private String domainId;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "Domain name for the offering")
-    private String domain;
-
-    @SerializedName(ApiConstants.HOST_TAGS)
-    @Param(description = "the host tag for the service offering")
-    private String hostTag;
-
-    @SerializedName(ApiConstants.IS_SYSTEM_OFFERING)
-    @Param(description = "is this a system vm offering")
-    private Boolean isSystem;
-
-    @SerializedName(ApiConstants.IS_DEFAULT_USE)
-    @Param(description = "is this a  default system vm offering")
-    private Boolean defaultUse;
-
-    @SerializedName(ApiConstants.SYSTEM_VM_TYPE)
-    @Param(description = "is this a the systemvm type for system vm offering")
-    private String vmType;
-
-    @SerializedName(ApiConstants.NETWORKRATE)
-    @Param(description = "data transfer rate in megabits per second allowed.")
-    private Integer networkRate;
-
-    @SerializedName("iscustomizediops")
-    @Param(description = "true if disk offering uses custom iops, false otherwise", since = "4.4")
-    private Boolean customizedIops;
-
-    @SerializedName(ApiConstants.MIN_IOPS)
-    @Param(description = "the min iops of the disk offering", since = "4.4")
-    private Long minIops;
-
-    @SerializedName(ApiConstants.MAX_IOPS)
-    @Param(description = "the max iops of the disk offering", since = "4.4")
-    private Long maxIops;
-
-    @SerializedName(ApiConstants.HYPERVISOR_SNAPSHOT_RESERVE)
-    @Param(description = "Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)", since = "4.4")
-    private Integer hypervisorSnapshotReserve;
-
-    @SerializedName("diskBytesReadRate")
-    @Param(description = "bytes read rate of the service offering")
-    private Long bytesReadRate;
-
-    @SerializedName("diskBytesWriteRate")
-    @Param(description = "bytes write rate of the service offering")
-    private Long bytesWriteRate;
-
-    @SerializedName("diskIopsReadRate")
-    @Param(description = "io requests read rate of the service offering")
-    private Long iopsReadRate;
-
-    @SerializedName("diskIopsWriteRate")
-    @Param(description = "io requests write rate of the service offering")
-    private Long iopsWriteRate;
-
-    @SerializedName(ApiConstants.DEPLOYMENT_PLANNER)
-    @Param(description = "deployment strategy used to deploy VM.")
-    private String deploymentPlanner;
-
-    @SerializedName(ApiConstants.SERVICE_OFFERING_DETAILS)
-    @Param(description = "additional key/value details tied with this service offering", since = "4.2.0")
-    private Map<String, String> details;
-
-    @SerializedName("iscustomized")
-    @Param(description = "is true if the offering is customized", since = "4.3.0")
-    private Boolean isCustomized;
-
-    public ServiceOfferingResponse() {
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Boolean getIsSystem() {
-        return isSystem;
-    }
-
-    public void setIsSystemOffering(Boolean isSystem) {
-        this.isSystem = isSystem;
-    }
-
-    public Boolean getDefaultUse() {
-        return defaultUse;
-    }
-
-    public void setDefaultUse(Boolean defaultUse) {
-        this.defaultUse = defaultUse;
-    }
-
-    public String getSystemVmType() {
-        return vmType;
-    }
-
-    public void setSystemVmType(String vmtype) {
-        vmType = vmtype;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    public int getCpuNumber() {
-        return cpuNumber;
-    }
-
-    public void setCpuNumber(Integer cpuNumber) {
-        this.cpuNumber = cpuNumber;
-    }
-
-    public int getCpuSpeed() {
-        return cpuSpeed;
-    }
-
-    public void setCpuSpeed(Integer cpuSpeed) {
-        this.cpuSpeed = cpuSpeed;
-    }
-
-    public int getMemory() {
-        return memory;
-    }
-
-    public void setMemory(Integer memory) {
-        this.memory = memory;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public String getStorageType() {
-        return storageType;
-    }
-
-    public void setStorageType(String storageType) {
-        this.storageType = storageType;
-    }
-
-    public String getProvisioningType(){
-        return provisioningType;
-    }
-
-    public void setProvisioningType(String provisioningType){
-        this.provisioningType = provisioningType;
-    }
-
-    public Boolean getOfferHa() {
-        return offerHa;
-    }
-
-    public void setOfferHa(Boolean offerHa) {
-        this.offerHa = offerHa;
-    }
-
-    public Boolean getLimitCpuUse() {
-        return limitCpuUse;
-    }
-
-    public void setLimitCpuUse(Boolean limitCpuUse) {
-        this.limitCpuUse = limitCpuUse;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public void setTags(String tags) {
-        this.tags = tags;
-    }
-
-    public String getDomainId() {
-        return domainId;
-    }
-
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    public String getDomain() {
-        return domain;
-    }
-
-    public void setDomain(String domain) {
-        this.domain = domain;
-    }
-
-    public String getHostTag() {
-        return hostTag;
-    }
-
-    public void setHostTag(String hostTag) {
-        this.hostTag = hostTag;
-    }
-
-    public void setNetworkRate(Integer networkRate) {
-        this.networkRate = networkRate;
-    }
-
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public void setDeploymentPlanner(String deploymentPlanner) {
-        this.deploymentPlanner = deploymentPlanner;
-    }
-
-    public boolean getVolatileVm() {
-        return isVolatile;
-    }
-
-    public void setVolatileVm(boolean isVolatile) {
-        this.isVolatile = isVolatile;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public void setCustomizedIops(Boolean customizedIops) {
-        this.customizedIops = customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public void setMinIops(Long minIops) {
-        this.minIops = minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public void setMaxIops(Long maxIops) {
-        this.maxIops = maxIops;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
-        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
-    }
-
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-
-    public void setDetails(Map<String, String> details) {
-        this.details = details;
-    }
-
-    public void setIscutomized(boolean iscutomized) {
-        this.isCustomized = iscutomized;
-
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java
deleted file mode 100644
index 39178a3..0000000
--- a/api/src/org/apache/cloudstack/api/response/SnapshotPolicyResponse.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.acl.RoleType;
-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.storage.snapshot.SnapshotPolicy;
-
-@EntityReference(value = SnapshotPolicy.class)
-public class SnapshotPolicyResponse extends BaseResponse {
-    @SerializedName("id")
-    @Param(description = "the ID of the snapshot policy")
-    private String id;
-
-    @SerializedName("volumeid")
-    @Param(description = "the ID of the disk volume")
-    private String volumeId;
-
-    @SerializedName("schedule")
-    @Param(description = "time the snapshot is scheduled to be taken.")
-    private String schedule;
-
-    @SerializedName("intervaltype")
-    @Param(description = "the interval type of the snapshot policy")
-    private short intervalType;
-
-    @SerializedName("maxsnaps")
-    @Param(description = "maximum number of snapshots retained")
-    private int maxSnaps;
-
-    @SerializedName("timezone")
-    @Param(description = "the time zone of the snapshot policy")
-    private String timezone;
-
-    @SerializedName(ApiConstants.FOR_DISPLAY)
-    @Param(description = "is this policy for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
-    private Boolean forDisplay;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getVolumeId() {
-        return volumeId;
-    }
-
-    public void setVolumeId(String volumeId) {
-        this.volumeId = volumeId;
-    }
-
-    public String getSchedule() {
-        return schedule;
-    }
-
-    public void setSchedule(String schedule) {
-        this.schedule = schedule;
-    }
-
-    public short getIntervalType() {
-        return intervalType;
-    }
-
-    public void setIntervalType(short intervalType) {
-        this.intervalType = intervalType;
-    }
-
-    public int getMaxSnaps() {
-        return maxSnaps;
-    }
-
-    public void setMaxSnaps(int maxSnaps) {
-        this.maxSnaps = maxSnaps;
-    }
-
-    public String getTimezone() {
-        return timezone;
-    }
-
-    public void setTimezone(String timezone) {
-        this.timezone = timezone;
-    }
-
-    public Boolean getForDisplay() {
-        return forDisplay;
-    }
-
-    public void setForDisplay(Boolean forDisplay) {
-        this.forDisplay = forDisplay;
-    }
-}
diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java
deleted file mode 100644
index 373198e..0000000
--- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java
+++ /dev/null
@@ -1,394 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-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.Storage.ImageFormat;
-import com.cloud.template.VirtualMachineTemplate;
-import com.google.gson.annotations.SerializedName;
-
-@EntityReference(value = VirtualMachineTemplate.class)
-@SuppressWarnings("unused")
-public class TemplateResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the template ID")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the template name")
-    private String name;
-
-    @SerializedName(ApiConstants.DISPLAY_TEXT)
-    @Param(description = "the template display text")
-    private String displayText;
-
-    @SerializedName(ApiConstants.IS_PUBLIC)
-    // propName="public"  (FIXME:  this used to be part of Param annotation, do we need it?)
-    @Param(description = "true if this template is a public template, false otherwise")
-    private boolean isPublic;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "the date this template was created")
-    private Date created;
-
-    @SerializedName("removed")
-    @Param(description = "the date this template was removed")
-    private Date removed;
-
-    @SerializedName(ApiConstants.IS_READY)
-    // propName="ready"  (FIXME:  this used to be part of Param annotation, do we need it?)
-    @Param(description = "true if the template is ready to be deployed from, false otherwise.")
-    private boolean isReady;
-
-    @SerializedName(ApiConstants.PASSWORD_ENABLED)
-    @Param(description = "true if the reset password feature is enabled, false otherwise")
-    private Boolean passwordEnabled;
-
-    @SerializedName(ApiConstants.FORMAT)
-    @Param(description = "the format of the template.")
-    private ImageFormat format;
-
-    @SerializedName(ApiConstants.BOOTABLE)
-    @Param(description = "true if the ISO is bootable, false otherwise")
-    private Boolean bootable;
-
-    @SerializedName(ApiConstants.IS_FEATURED)
-    @Param(description = "true if this template is a featured template, false otherwise")
-    private boolean featured;
-
-    @SerializedName("crossZones")
-    @Param(description = "true if the template is managed across all Zones, false otherwise")
-    private boolean crossZones;
-
-    @SerializedName(ApiConstants.OS_TYPE_ID)
-    @Param(description = "the ID of the OS type for this template.")
-    private String osTypeId;
-
-    @SerializedName("ostypename")
-    @Param(description = "the name of the OS type for this template.")
-    private String osTypeName;
-
-    @SerializedName(ApiConstants.ACCOUNT_ID)
-    @Param(description = "the account id to which the template belongs")
-    private String accountId;
-
-    @SerializedName(ApiConstants.ACCOUNT)
-    @Param(description = "the account name to which the template belongs")
-    private String account;
-
-    //TODO: since a template can be associated to more than one zones, this model is not accurate. For backward-compatibility, keep these fields
-    // here, but add a zones field to capture multiple zones.
-    @SerializedName(ApiConstants.ZONE_ID)
-    @Param(description = "the ID of the zone for this template")
-    private String zoneId;
-
-    @SerializedName(ApiConstants.ZONE_NAME)
-    @Param(description = "the name of the zone for this template")
-    private String zoneName;
-
-    @SerializedName(ApiConstants.STATUS)
-    @Param(description = "the status of the template")
-    private String status;
-
-    @SerializedName(ApiConstants.SIZE)
-    @Param(description = "the size of the template")
-    private Long size;
-
-    @SerializedName(ApiConstants.PHYSICAL_SIZE)
-    @Param(description = "the physical size of the template")
-    private Long physicalSize;
-
-    @SerializedName("templatetype")
-    @Param(description = "the type of the template")
-    private String templateType;
-
-    @SerializedName(ApiConstants.HYPERVISOR)
-    @Param(description = "the hypervisor on which the template runs")
-    private String hypervisor;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "the name of the domain to which the template belongs")
-    private String domainName;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the ID of the domain to which the template belongs")
-    private String domainId;
-
-    @SerializedName(ApiConstants.IS_EXTRACTABLE)
-    @Param(description = "true if the template is extractable, false otherwise")
-    private Boolean extractable;
-
-    @SerializedName(ApiConstants.CHECKSUM)
-    @Param(description = "checksum of the template")
-    private String checksum;
-
-    @SerializedName("sourcetemplateid")
-    @Param(description = "the template ID of the parent template if present")
-    private String sourcetemplateId;
-
-    @SerializedName(ApiConstants.HOST_ID)
-    @Param(description = "the ID of the secondary storage host for the template")
-    private String hostId;
-
-    @SerializedName("hostname")
-    @Param(description = "the name of the secondary storage host for the template")
-    private String hostName;
-
-    @SerializedName(ApiConstants.TEMPLATE_TAG)
-    @Param(description = "the tag of this template")
-    private String templateTag;
-
-    @SerializedName(ApiConstants.PROJECT_ID)
-    @Param(description = "the project id of the template")
-    private String projectId;
-
-    @SerializedName(ApiConstants.PROJECT)
-    @Param(description = "the project name of the template")
-    private String projectName;
-
-    @SerializedName(ApiConstants.DETAILS)
-    @Param(description = "additional key/value details tied with template")
-    private Map details;
-
-    @SerializedName(ApiConstants.BITS)
-    @Param(description = "the processor bit size", since = "4.10")
-    private int bits;
-
-    @SerializedName(ApiConstants.SSHKEY_ENABLED)
-    @Param(description = "true if template is sshkey enabled, false otherwise")
-    private Boolean sshKeyEnabled;
-
-    @SerializedName(ApiConstants.IS_DYNAMICALLY_SCALABLE)
-    @Param(description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory")
-    private Boolean isDynamicallyScalable;
-
-    @SerializedName(ApiConstants.DIRECT_DOWNLOAD)
-    @Param(description = "KVM Only: true if template is directly downloaded to Primary Storage bypassing Secondary Storage")
-    private Boolean directDownload;
-
-    @SerializedName("parenttemplateid")
-    @Param(description = "if Datadisk template, then id of the root disk template this template belongs to")
-    private String parentTemplateId;
-
-    @SerializedName("childtemplates")
-    @Param(description = "if root disk template, then ids of the datas disk templates this template owns")
-    private Set<ChildTemplateResponse> childTemplates;
-
-    public TemplateResponse() {
-        tags = new LinkedHashSet<ResourceTagResponse>();
-    }
-
-    @Override
-    public String getObjectId() {
-        return this.getId();
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setZoneId(String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    public void setZoneName(String zoneName) {
-        this.zoneName = zoneName;
-    }
-
-    public void setAccountId(String accountId) {
-        this.accountId = accountId;
-    }
-
-    @Override
-    public void setAccountName(String account) {
-        this.account = account;
-    }
-
-    public void setOsTypeId(String osTypeId) {
-        this.osTypeId = osTypeId;
-    }
-
-    public void setOsTypeName(String osTypeName) {
-        this.osTypeName = osTypeName;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    public void setPublic(boolean isPublic) {
-        this.isPublic = isPublic;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public void setRemoved(Date removed) {
-        this.removed = removed;
-    }
-
-    public void setReady(boolean isReady) {
-        this.isReady = isReady;
-    }
-
-    public void setPasswordEnabled(boolean passwordEnabled) {
-        this.passwordEnabled = passwordEnabled;
-    }
-
-    public void setFormat(ImageFormat format) {
-        this.format = format;
-    }
-
-    public void setBootable(Boolean bootable) {
-        this.bootable = bootable;
-    }
-
-    public void setFeatured(boolean featured) {
-        this.featured = featured;
-    }
-
-    public void setCrossZones(boolean crossZones) {
-        this.crossZones = crossZones;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public void setSize(Long size) {
-        this.size = size;
-    }
-
-    public void setPhysicalSize(Long physicalSize) {
-        this.physicalSize = physicalSize;
-    }
-
-    public void setTemplateType(String templateType) {
-        this.templateType = templateType;
-    }
-
-    public void setHypervisor(String hypervisor) {
-        this.hypervisor = hypervisor;
-    }
-
-    @Override
-    public void setDomainName(String domainName) {
-        this.domainName = domainName;
-    }
-
-    @Override
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    public void setExtractable(Boolean extractable) {
-        this.extractable = extractable;
-    }
-
-    public void setChecksum(String checksum) {
-        this.checksum = checksum;
-    }
-
-    public void setSourceTemplateId(String sourcetemplateId) {
-        this.sourcetemplateId = sourcetemplateId;
-    }
-
-    public void setHostId(String hostId) {
-        this.hostId = hostId;
-    }
-
-    public void setHostName(String hostName) {
-        this.hostName = hostName;
-    }
-
-    public void setTemplateTag(String templateTag) {
-        this.templateTag = templateTag;
-    }
-
-    @Override
-    public void setProjectId(String projectId) {
-        this.projectId = projectId;
-    }
-
-    @Override
-    public void setProjectName(String projectName) {
-        this.projectName = projectName;
-    }
-
-    public Map getDetails() {
-        return this.details;
-    }
-
-    public void setDetails(Map details) {
-        this.details = details;
-    }
-
-    public void setTags(Set<ResourceTagResponse> tags) {
-        this.tags = tags;
-    }
-
-    public void setSshKeyEnabled(boolean sshKeyEnabled) {
-        this.sshKeyEnabled = sshKeyEnabled;
-    }
-
-    public void setDynamicallyScalable(boolean isDynamicallyScalable) {
-        this.isDynamicallyScalable = isDynamicallyScalable;
-    }
-
-    public String getZoneId() {
-        return zoneId;
-    }
-
-    public void setBits(int bits) {
-        this.bits = bits;
-    }
-
-    public void setDirectDownload(Boolean directDownload) {
-        this.directDownload = directDownload;
-    }
-
-    public Boolean getDirectDownload() {
-        return directDownload;
-    }
-
-    public void setParentTemplateId(String parentTemplateId) {
-        this.parentTemplateId = parentTemplateId;
-    }
-
-    public void setChildTemplates(Set<ChildTemplateResponse> childTemplateIds) {
-        this.childTemplates = childTemplateIds;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
deleted file mode 100644
index 895e13c..0000000
--- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
+++ /dev/null
@@ -1,736 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import com.cloud.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 java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-@EntityReference(value = Volume.class)
-@SuppressWarnings("unused")
-public class VolumeResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "ID of the disk volume")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "name of the disk volume")
-    private String name;
-
-    @SerializedName(ApiConstants.ZONE_ID)
-    @Param(description = "ID of the availability zone")
-    private String zoneId;
-
-    @SerializedName(ApiConstants.ZONE_NAME)
-    @Param(description = "name of the availability zone")
-    private String zoneName;
-
-    @SerializedName(ApiConstants.TYPE)
-    @Param(description = "type of the disk volume (ROOT or DATADISK)")
-    private String volumeType;
-
-    @SerializedName(ApiConstants.DEVICE_ID)
-    @Param(description = "the ID of the device on user vm the volume is attahed to. This tag is not returned when the volume is detached.")
-    private Long deviceId;
-
-    @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
-    @Param(description = "id of the virtual machine")
-    private String virtualMachineId;
-
-    @SerializedName("isoid")
-    @Param(description = "the ID of the ISO attached to the virtual machine")
-    private String isoId;
-
-    @SerializedName("isoname")
-    @Param(description = "the name of the ISO attached to the virtual machine")
-    private String isoName;
-
-    @SerializedName("isodisplaytext")
-    @Param(description = "an alternate display text of the ISO attached to the virtual machine")
-    private String isoDisplayText;
-
-    @SerializedName(ApiConstants.TEMPLATE_ID)
-    @Param(description = "the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file.")
-    private String templateId;
-
-    @SerializedName("templatename")
-    @Param(description = "the name of the template for the virtual machine")
-    private String templateName;
-
-    @SerializedName("templatedisplaytext")
-    @Param(description = " an alternate display text of the template for the virtual machine")
-    private String templateDisplayText;
-
-    @SerializedName("vmname")
-    @Param(description = "name of the virtual machine")
-    private String virtualMachineName;
-
-    @SerializedName("vmdisplayname")
-    @Param(description = "display name of the virtual machine")
-    private String virtualMachineDisplayName;
-
-    @SerializedName("vmstate")
-    @Param(description = "state of the virtual machine")
-    private String virtualMachineState;
-
-    @SerializedName(ApiConstants.PROVISIONINGTYPE)
-    @Param(description = "provisioning type used to create volumes.")
-    private String provisioningType;
-
-    @SerializedName(ApiConstants.SIZE)
-    @Param(description = "size of the disk volume")
-    private Long size;
-
-    @SerializedName(ApiConstants.MIN_IOPS)
-    @Param(description = "min iops of the disk volume")
-    private Long minIops;
-
-    @SerializedName(ApiConstants.MAX_IOPS)
-    @Param(description = "max iops of the disk volume")
-    private Long maxIops;
-
-    @SerializedName(ApiConstants.CREATED)
-    @Param(description = "the date the disk volume was created")
-    private Date created;
-
-    @SerializedName(ApiConstants.STATE)
-    @Param(description = "the state of the disk volume")
-    private String state;
-
-    @SerializedName(ApiConstants.ACCOUNT)
-    @Param(description = "the account associated with the disk volume")
-    private String accountName;
-
-    @SerializedName(ApiConstants.PROJECT_ID)
-    @Param(description = "the project id of the vpn")
-    private String projectId;
-
-    @SerializedName(ApiConstants.PROJECT)
-    @Param(description = "the project name of the vpn")
-    private String projectName;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the ID of the domain associated with the disk volume")
-    private String domainId;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "the domain associated with the disk volume")
-    private String domainName;
-
-    @SerializedName("storagetype")
-    @Param(description = "shared or local storage")
-    private String storageType;
-
-    @SerializedName("diskBytesReadRate")
-    @Param(description = "bytes read rate of the disk volume")
-    private Long bytesReadRate;
-
-    @SerializedName("diskBytesWriteRate")
-    @Param(description = "bytes write rate of the disk volume")
-    private Long bytesWriteRate;
-
-    @SerializedName("diskIopsReadRate")
-    @Param(description = "io requests read rate of the disk volume")
-    private Long iopsReadRate;
-
-    @SerializedName("diskIopsWriteRate")
-    @Param(description = "io requests write rate of the disk volume")
-    private Long iopsWriteRate;
-
-    @SerializedName(ApiConstants.HYPERVISOR)
-    @Param(description = "Hypervisor the volume belongs to")
-    private String hypervisor;
-
-    @SerializedName(ApiConstants.DISK_OFFERING_ID)
-    @Param(description = "ID of the disk offering")
-    private String diskOfferingId;
-
-    @SerializedName("diskofferingname")
-    @Param(description = "name of the disk offering")
-    private String diskOfferingName;
-
-    @SerializedName("diskofferingdisplaytext")
-    @Param(description = "the display text of the disk offering")
-    private String diskOfferingDisplayText;
-
-    @SerializedName("storage")
-    @Param(description = "name of the primary storage hosting the disk volume")
-    private String storagePoolName;
-
-    @SerializedName(ApiConstants.SNAPSHOT_ID)
-    @Param(description = "ID of the snapshot from which this volume was created")
-    private String snapshotId;
-
-    @SerializedName("attached")
-    @Param(description = "the date the volume was attached to a VM instance")
-    private Date attached;
-
-    @SerializedName("destroyed")
-    @Param(description = "the boolean state of whether the volume is destroyed or not")
-    private Boolean destroyed;
-
-    @SerializedName(ApiConstants.SERVICE_OFFERING_ID)
-    @Param(description = "ID of the service offering for root disk")
-    private String serviceOfferingId;
-
-    @SerializedName("serviceofferingname")
-    @Param(description = "name of the service offering for root disk")
-    private String serviceOfferingName;
-
-    @SerializedName("serviceofferingdisplaytext")
-    @Param(description = "the display text of the service offering for root disk")
-    private String serviceOfferingDisplayText;
-
-    @SerializedName("isextractable")
-    @Param(description = "true if the volume is extractable, false otherwise")
-    private Boolean extractable;
-
-    @SerializedName(ApiConstants.STATUS)
-    @Param(description = "the status of the volume")
-    private String status;
-
-    @SerializedName(ApiConstants.DISPLAY_VOLUME)
-    @Param(description = "an optional field whether to the display the volume to the end user or not.", authorized = {RoleType.Admin})
-    private Boolean displayVolume;
-
-    @SerializedName(ApiConstants.PATH)
-    @Param(description = "the path of the volume")
-    private String path;
-
-    @SerializedName(ApiConstants.STORAGE_ID)
-    @Param(description = "id of the primary storage hosting the disk volume; returned to admin user only", since = "4.3")
-    private String storagePoolId;
-
-    @SerializedName(ApiConstants.CHAIN_INFO)
-    @Param(description = "the chain info of the volume", since = "4.4")
-    String chainInfo;
-
-    @SerializedName(ApiConstants.SNAPSHOT_QUIESCEVM)
-    @Param(description = "need quiesce vm or not when taking snapshot", since = "4.3")
-    private boolean needQuiescevm;
-
-    @SerializedName(ApiConstants.PHYSICAL_SIZE)
-    @Param(description = "the bytes alloaated")
-    private Long physicalsize;
-
-    @SerializedName(ApiConstants.VIRTUAL_SIZE)
-    @Param(description = "the bytes actually consumed on disk")
-    private Long virtualsize;
-
-    @SerializedName(ApiConstants.UTILIZATION)
-    @Param(description = "the disk utilization")
-    private String utilization;
-
-    @SerializedName(ApiConstants.CLUSTER_ID)
-    @Param(description = "cluster id of the volume")
-    private String clusterid;
-
-    @SerializedName(ApiConstants.CLUSTER_NAME)
-    @Param(description = "cluster name where the volume is allocated")
-    private String clustername;
-
-    @SerializedName(ApiConstants.POD_ID)
-    @Param(description = "pod id of the volume")
-    private String podid;
-
-    @SerializedName(ApiConstants.POD_NAME)
-    @Param(description = "pod name of the volume")
-    private String podname;
-
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public VolumeResponse() {
-        tags = new LinkedHashSet<ResourceTagResponse>();
-    }
-
-    @Override
-    public String getObjectId() {
-        return this.getId();
-    }
-
-    public Boolean getDestroyed() {
-        return destroyed;
-    }
-
-    public void setDestroyed(Boolean destroyed) {
-        this.destroyed = destroyed;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setZoneId(String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    public void setZoneName(String zoneName) {
-        this.zoneName = zoneName;
-    }
-
-    public void setVolumeType(String volumeType) {
-        this.volumeType = volumeType;
-    }
-
-    public void setDeviceId(Long deviceId) {
-        this.deviceId = deviceId;
-    }
-
-    public void setVirtualMachineId(String virtualMachineId) {
-        this.virtualMachineId = virtualMachineId;
-    }
-
-    public void setVirtualMachineName(String virtualMachineName) {
-        this.virtualMachineName = virtualMachineName;
-    }
-
-    public void setVirtualMachineDisplayName(String virtualMachineDisplayName) {
-        this.virtualMachineDisplayName = virtualMachineDisplayName;
-    }
-
-    public void setVirtualMachineState(String virtualMachineState) {
-        this.virtualMachineState = virtualMachineState;
-    }
-
-    public void setProvisioningType(String provisioningType) {
-        this.provisioningType = provisioningType;
-    }
-
-    public void setSize(Long size) {
-        this.size = size;
-    }
-
-    public void setMinIops(Long minIops) {
-        this.minIops = minIops;
-    }
-
-    public void setMaxIops(Long maxIops) {
-        this.maxIops = maxIops;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    @Override
-    public void setAccountName(String accountName) {
-        this.accountName = accountName;
-    }
-
-    @Override
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    @Override
-    public void setDomainName(String domainName) {
-        this.domainName = domainName;
-    }
-
-    public void setStorageType(String storageType) {
-        this.storageType = storageType;
-    }
-
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public void setHypervisor(String hypervisor) {
-        this.hypervisor = hypervisor;
-    }
-
-    public void setDiskOfferingId(String diskOfferingId) {
-        this.diskOfferingId = diskOfferingId;
-    }
-
-    public void setDiskOfferingName(String diskOfferingName) {
-        this.diskOfferingName = diskOfferingName;
-    }
-
-    public void setDiskOfferingDisplayText(String diskOfferingDisplayText) {
-        this.diskOfferingDisplayText = diskOfferingDisplayText;
-    }
-
-    public void setStoragePoolName(String storagePoolName) {
-        this.storagePoolName = storagePoolName;
-    }
-
-    public void setSnapshotId(String snapshotId) {
-        this.snapshotId = snapshotId;
-    }
-
-    public void setAttached(Date attached) {
-        this.attached = attached;
-    }
-
-    public void setServiceOfferingId(String serviceOfferingId) {
-        this.serviceOfferingId = serviceOfferingId;
-    }
-
-    public void setServiceOfferingName(String serviceOfferingName) {
-        this.serviceOfferingName = serviceOfferingName;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public void setServiceOfferingDisplayText(String serviceOfferingDisplayText) {
-        this.serviceOfferingDisplayText = serviceOfferingDisplayText;
-    }
-
-    public void setExtractable(Boolean extractable) {
-        this.extractable = extractable;
-    }
-
-    public void setState(String state) {
-        this.state = state;
-    }
-
-    @Override
-    public void setProjectId(String projectId) {
-        this.projectId = projectId;
-    }
-
-    @Override
-    public void setProjectName(String projectName) {
-        this.projectName = projectName;
-    }
-
-    public void setDisplayVolume(Boolean displayVm) {
-        this.displayVolume = displayVm;
-    }
-
-    public void setStoragePoolId(String storagePoolId) {
-        this.storagePoolId = storagePoolId;
-    }
-
-    public String getChainInfo() {
-        return chainInfo;
-    }
-
-    public void setChainInfo(String chainInfo) {
-        this.chainInfo = chainInfo;
-    }
-
-    public String getStoragePoolId() {
-        return storagePoolId;
-    }
-
-    public void setNeedQuiescevm(boolean quiescevm) {
-        this.needQuiescevm = quiescevm;
-    }
-
-    public boolean isNeedQuiescevm() {
-        return this.needQuiescevm;
-    }
-
-    public String getIsoId() {
-        return isoId;
-    }
-
-    public void setIsoId(String isoId) {
-        this.isoId = isoId;
-    }
-
-    public String getIsoName() {
-        return isoName;
-    }
-
-    public void setIsoName(String isoName) {
-        this.isoName = isoName;
-    }
-
-    public String getIsoDisplayText() {
-        return isoDisplayText;
-    }
-
-    public void setIsoDisplayText(String isoDisplayText) {
-        this.isoDisplayText = isoDisplayText;
-    }
-
-    public String getTemplateId() {
-        return templateId;
-    }
-
-    public void setTemplateId(String templateId) {
-        this.templateId = templateId;
-    }
-
-    public String getTemplateName() {
-        return templateName;
-    }
-
-    public void setTemplateName(String templateName) {
-        this.templateName = templateName;
-    }
-
-    public String getTemplateDisplayText() {
-        return templateDisplayText;
-    }
-
-    public void setTemplateDisplayText(String templateDisplayText) {
-        this.templateDisplayText = templateDisplayText;
-    }
-
-    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;
-    }
-
-    public Long getPhysicalsize() {
-        return physicalsize;
-    }
-
-    public void setPhysicalsize(Long physicalsize) {
-        this.physicalsize = physicalsize;
-    }
-
-    public Long getVirtualsize() {
-        return virtualsize;
-    }
-
-    public void setVirtualsize(Long virtualsize) {
-        this.virtualsize = virtualsize;
-    }
-
-    public String getUtilization() {
-        return utilization;
-    }
-
-    public void setUtilization(String utilization) {
-        this.utilization = utilization;
-    }
-
-    public String getClusterId() {
-        return clusterid;
-    }
-
-    public void setClusterId(String clusterid) {
-        this.clusterid = clusterid;
-    }
-
-    public String getClusterName() {
-        return clustername;
-    }
-
-    public void setClusterName(String clustername) {
-        this.clustername = clustername;
-    }
-
-    public String getPodId() {
-        return podid;
-    }
-
-    public void setPodId(String podid) {
-        this.podid = podid;
-    }
-
-    public String getPodName() {
-        return podname;
-    }
-
-    public void setPodName(String podname) {
-        this.podname = podname;
-    }
-
-}
diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
deleted file mode 100644
index 61bab02..0000000
--- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
+++ /dev/null
@@ -1,330 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
-
-@SuppressWarnings("unused")
-@EntityReference(value = DataCenter.class)
-public class ZoneResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "Zone id")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "Zone name")
-    private String name;
-
-    @SerializedName(ApiConstants.DESCRIPTION)
-    @Param(description = "Zone description")
-    private String description;
-
-    @SerializedName(ApiConstants.DNS1)
-    @Param(description = "the first DNS for the Zone")
-    private String dns1;
-
-    @SerializedName(ApiConstants.DNS2)
-    @Param(description = "the second DNS for the Zone")
-    private String dns2;
-
-    @SerializedName(ApiConstants.IP6_DNS1)
-    @Param(description = "the first IPv6 DNS for the Zone")
-    private String ip6Dns1;
-
-    @SerializedName(ApiConstants.IP6_DNS2)
-    @Param(description = "the second IPv6 DNS for the Zone")
-    private String ip6Dns2;
-
-    @SerializedName(ApiConstants.INTERNAL_DNS1)
-    @Param(description = "the first internal DNS for the Zone")
-    private String internalDns1;
-
-    @SerializedName(ApiConstants.INTERNAL_DNS2)
-    @Param(description = "the second internal DNS for the Zone")
-    private String internalDns2;
-
-    @SerializedName(ApiConstants.GUEST_CIDR_ADDRESS)
-    @Param(description = "the guest CIDR address for the Zone")
-    private String guestCidrAddress;
-
-    //TODO - generate description
-    @SerializedName("status")
-    private String status;
-
-    @SerializedName(ApiConstants.DISPLAY_TEXT)
-    @Param(description = "the display text of the zone")
-    private String displayText;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "Network domain name for the networks in the zone")
-    private String domain;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the UUID of the containing domain, null for public zones")
-    private String domainId;
-
-    @SerializedName("domainname")
-    @Param(description = "the name of the containing domain, null for public zones")
-    private String domainName;
-
-    @SerializedName(ApiConstants.NETWORK_TYPE)
-    @Param(description = "the network type of the zone; can be Basic or Advanced")
-    private String networkType;
-
-    @SerializedName("securitygroupsenabled")
-    @Param(description = "true if security groups support is enabled, false otherwise")
-    private boolean securityGroupsEnabled;
-
-    @SerializedName("allocationstate")
-    @Param(description = "the allocation state of the cluster")
-    private String allocationState;
-
-    @SerializedName(ApiConstants.ZONE_TOKEN)
-    @Param(description = "Zone Token")
-    private String zoneToken;
-
-    @SerializedName(ApiConstants.DHCP_PROVIDER)
-    @Param(description = "the dhcp Provider for the Zone")
-    private String dhcpProvider;
-
-    @SerializedName("capacity")
-    @Param(description = "the capacity of the Zone", responseObject = CapacityResponse.class)
-    private List<CapacityResponse> capacitites;
-
-    @SerializedName(ApiConstants.LOCAL_STORAGE_ENABLED)
-    @Param(description = "true if local storage offering enabled, false otherwise")
-    private boolean localStorageEnabled;
-
-    @SerializedName(ApiConstants.TAGS)
-    @Param(description = "the list of resource tags associated with zone.", responseObject = ResourceTagResponse.class, since = "4.3")
-    private Set<ResourceTagResponse> tags;
-
-    @SerializedName(ApiConstants.RESOURCE_DETAILS)
-    @Param(description = "Meta data associated with the zone (key/value pairs)", since = "4.3.0")
-    private Map<String, String> resourceDetails;
-
-    public ZoneResponse() {
-        tags = new LinkedHashSet<ResourceTagResponse>();
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public void setDns1(String dns1) {
-        this.dns1 = dns1;
-    }
-
-    public void setDns2(String dns2) {
-        this.dns2 = dns2;
-    }
-
-    public void setInternalDns1(String internalDns1) {
-        this.internalDns1 = internalDns1;
-    }
-
-    public void setInternalDns2(String internalDns2) {
-        this.internalDns2 = internalDns2;
-    }
-
-    public void setGuestCidrAddress(String guestCidrAddress) {
-        this.guestCidrAddress = guestCidrAddress;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    public void setDomain(String domain) {
-        this.domain = domain;
-    }
-
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    public void setType(String networkType) {
-        this.networkType = networkType;
-    }
-
-    public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
-        this.securityGroupsEnabled = securityGroupsEnabled;
-    }
-
-    public void setAllocationState(String allocationState) {
-        this.allocationState = allocationState;
-    }
-
-    public void setZoneToken(String zoneToken) {
-        this.zoneToken = zoneToken;
-    }
-
-    public void setDhcpProvider(String dhcpProvider) {
-        this.dhcpProvider = dhcpProvider;
-    }
-
-    public void setCapacitites(List<CapacityResponse> capacitites) {
-        this.capacitites = capacitites;
-    }
-
-    public void setDomainName(String domainName) {
-        this.domainName = domainName;
-    }
-
-    public void setLocalStorageEnabled(boolean localStorageEnabled) {
-        this.localStorageEnabled = localStorageEnabled;
-    }
-
-    public String getIp6Dns1() {
-        return ip6Dns1;
-    }
-
-    public void setIp6Dns1(String ip6Dns1) {
-        this.ip6Dns1 = ip6Dns1;
-    }
-
-    public String getIp6Dns2() {
-        return ip6Dns2;
-    }
-
-    public void setIp6Dns2(String ip6Dns2) {
-        this.ip6Dns2 = ip6Dns2;
-    }
-
-    public void addTag(ResourceTagResponse tag) {
-        this.tags.add(tag);
-    }
-
-    public void setResourceDetails(Map<String, String> details) {
-        if (details == null) {
-            return;
-        }
-        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/api/src/org/apache/cloudstack/jobs/JobInfo.java b/api/src/org/apache/cloudstack/jobs/JobInfo.java
deleted file mode 100644
index c7c9b96..0000000
--- a/api/src/org/apache/cloudstack/jobs/JobInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.jobs;
-
-import java.util.Date;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface JobInfo extends Identity, InternalIdentity {
-    public enum Status {
-        IN_PROGRESS(false), SUCCEEDED(true), FAILED(true), CANCELLED(true);
-
-        private final boolean done;
-
-        private Status(boolean done) {
-            this.done = done;
-        }
-
-        public boolean done() {
-            return done;
-        }
-    }
-
-    String getType();
-
-    String getDispatcher();
-
-    int getPendingSignals();
-
-    long getUserId();
-
-    long getAccountId();
-
-    String getCmd();
-
-    int getCmdVersion();
-
-    String getCmdInfo();
-
-    Status getStatus();
-
-    int getProcessStatus();
-
-    int getResultCode();
-
-    String getResult();
-
-    Long getInitMsid();
-
-    Long getExecutingMsid();
-
-    Long getCompleteMsid();
-
-    Date getCreated();
-
-    Date getLastUpdated();
-
-    Date getLastPolled();
-
-    String getInstanceType();
-
-    Long getInstanceId();
-}
diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java
deleted file mode 100644
index de9fbb5..0000000
--- a/api/src/org/apache/cloudstack/query/QueryService.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.query;
-
-import java.util.List;
-
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
-import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
-import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
-import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
-import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
-import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
-import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
-import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
-import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
-import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
-import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
-import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
-import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.EventResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.HostTagResponse;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.api.response.InstanceGroupResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.ProjectAccountResponse;
-import org.apache.cloudstack.api.response.ProjectInvitationResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.ResourceDetailResponse;
-import org.apache.cloudstack.api.response.ResourceTagResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.StorageTagResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserResponse;
-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.framework.config.ConfigKey;
-
-import com.cloud.exception.PermissionDeniedException;
-
-/**
- * Service used for list api query.
- *
- */
-public interface QueryService {
-
-    // Config keys
-    static final ConfigKey<Boolean> AllowUserViewDestroyedVM = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.user.view.destroyed.vm", "false",
-            "Determines whether users can view their destroyed or expunging vm ", true, ConfigKey.Scope.Account);
-
-    ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException;
-
-    ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd);
-
-    ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd);
-
-    ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd);
-
-    ListResponse<UserVmResponse> searchForUserVMs(ListVMsCmd cmd);
-
-    ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd);
-
-    ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd);
-
-    ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd);
-
-    ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd);
-
-    ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd);
-
-    ListResponse<HostResponse> searchForServers(ListHostsCmd cmd);
-
-    ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd);
-
-    ListResponse<StoragePoolResponse> searchForStoragePools(ListStoragePoolsCmd cmd);
-
-    ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd);
-
-    ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd);
-
-    ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd);
-
-    ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd);
-
-    ListResponse<AsyncJobResponse>  searchForAsyncJobs(ListAsyncJobsCmd cmd);
-
-    ListResponse<DiskOfferingResponse>  searchForDiskOfferings(ListDiskOfferingsCmd cmd);
-
-    ListResponse<ServiceOfferingResponse>  searchForServiceOfferings(ListServiceOfferingsCmd cmd);
-
-    ListResponse<ZoneResponse>  listDataCenters(ListZonesCmd cmd);
-
-    ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd);
-
-    ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd);
-
-    ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd);
-
-    List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd);
-
-    ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd);
-
-    ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
-
-    ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd);
-}
diff --git a/api/test/com/cloud/network/IsolationMethodTest.java b/api/src/test/java/com/cloud/network/IsolationMethodTest.java
similarity index 100%
rename from api/test/com/cloud/network/IsolationMethodTest.java
rename to api/src/test/java/com/cloud/network/IsolationMethodTest.java
diff --git a/api/test/com/cloud/network/NetworksTest.java b/api/src/test/java/com/cloud/network/NetworksTest.java
similarity index 100%
rename from api/test/com/cloud/network/NetworksTest.java
rename to api/src/test/java/com/cloud/network/NetworksTest.java
diff --git a/api/test/com/cloud/storage/StorageTest.java b/api/src/test/java/com/cloud/storage/StorageTest.java
similarity index 100%
rename from api/test/com/cloud/storage/StorageTest.java
rename to api/src/test/java/com/cloud/storage/StorageTest.java
diff --git a/api/test/org/apache/cloudstack/acl/RoleTypeTest.java b/api/src/test/java/org/apache/cloudstack/acl/RoleTypeTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/acl/RoleTypeTest.java
rename to api/src/test/java/org/apache/cloudstack/acl/RoleTypeTest.java
diff --git a/api/test/org/apache/cloudstack/acl/RuleTest.java b/api/src/test/java/org/apache/cloudstack/acl/RuleTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/acl/RuleTest.java
rename to api/src/test/java/org/apache/cloudstack/acl/RuleTest.java
diff --git a/api/test/org/apache/cloudstack/api/ApiCmdTestUtil.java b/api/src/test/java/org/apache/cloudstack/api/ApiCmdTestUtil.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/ApiCmdTestUtil.java
rename to api/src/test/java/org/apache/cloudstack/api/ApiCmdTestUtil.java
diff --git a/api/test/org/apache/cloudstack/api/BaseCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/BaseCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/BaseCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/BaseCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/admin/account/CreateAccountCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/admin/account/CreateAccountCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/admin/annotation/AddAnnotationCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/admin/storage/CreateSecondaryStagingStoreCmdTest.java
diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmdTest.java
new file mode 100644
index 0000000..2297946
--- /dev/null
+++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/storage/FindStoragePoolsForMigrationCmdTest.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class FindStoragePoolsForMigrationCmdTest {
+
+    private FindStoragePoolsForMigrationCmd findStoragePoolsForMigrationCmd = new FindStoragePoolsForMigrationCmd();
+
+    @Test
+    public void sortPoolsBySuitability() {
+        List<StoragePoolResponse> storagePoolsResponse = new ArrayList<>();
+        StoragePoolResponse storagePoolResponse1 = new StoragePoolResponse();
+        storagePoolResponse1.setSuitableForMigration(true);
+        storagePoolResponse1.setId("1");
+        storagePoolResponse1.setName("1");
+
+        StoragePoolResponse storagePoolResponse2 = new StoragePoolResponse();
+        storagePoolResponse2.setSuitableForMigration(false);
+        storagePoolResponse2.setId("2");
+        storagePoolResponse2.setName("2");
+
+        StoragePoolResponse storagePoolResponse3 = new StoragePoolResponse();
+        storagePoolResponse3.setSuitableForMigration(true);
+        storagePoolResponse3.setId("3");
+        storagePoolResponse3.setName("3");
+
+        storagePoolsResponse.add(storagePoolResponse3);
+        storagePoolsResponse.add(storagePoolResponse2);
+        storagePoolsResponse.add(storagePoolResponse1);
+
+        findStoragePoolsForMigrationCmd.sortPoolsBySuitabilityAndName(storagePoolsResponse);
+
+        Assert.assertEquals("1", storagePoolsResponse.get(0).getId());
+        Assert.assertEquals("3", storagePoolsResponse.get(1).getId());
+        Assert.assertEquals("2", storagePoolsResponse.get(2).getId());
+
+    }
+
+}
\ No newline at end of file
diff --git a/api/test/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/admin/user/CreateUserCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/ActivateProjectCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/ActivateProjectCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/ActivateProjectCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/ActivateProjectCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddAccountToProjectCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddAccountToProjectCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddAccountToProjectCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddAccountToProjectCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddClusterCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddClusterCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddClusterCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddClusterCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddHostCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddHostCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddHostCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddHostCmdTest.java
diff --git a/api/src/test/java/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
new file mode 100644
index 0000000..8a28305
--- /dev/null
+++ b/api/src/test/java/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
@@ -0,0 +1,125 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.test;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.apache.cloudstack.api.ResponseGenerator;
+import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
+import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.NetworkService;
+import com.cloud.vm.NicSecondaryIp;
+
+public class AddIpToVmNicTest extends TestCase {
+
+    private AddIpToVmNicCmd addIpToVmNicCmd;
+    private RemoveIpFromVmNicCmd removeIpFromVmNicCmd;
+    private ResponseGenerator responseGenerator;
+    private SuccessResponse successResponseGenerator;
+
+    @Override
+    @Before
+    public void setUp() {
+
+    }
+
+    @Test
+    public void testCreateSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+        NetworkService networkService = Mockito.mock(NetworkService.class);
+        AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
+        NicSecondaryIp secIp = Mockito.mock(NicSecondaryIp.class);
+
+        Mockito.when(
+            networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.any()))
+            .thenReturn(secIp);
+
+        ipTonicCmd._networkService = networkService;
+        responseGenerator = Mockito.mock(ResponseGenerator.class);
+
+        NicSecondaryIpResponse ipres = Mockito.mock(NicSecondaryIpResponse.class);
+        Mockito.when(responseGenerator.createSecondaryIPToNicResponse(secIp)).thenReturn(ipres);
+
+        ipTonicCmd._responseGenerator = responseGenerator;
+        ipTonicCmd.execute();
+    }
+
+    @Test
+    public void testCreateFailure() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+        NetworkService networkService = Mockito.mock(NetworkService.class);
+        AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
+
+        Mockito.when(
+            networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.any()))
+            .thenReturn(null);
+
+        ipTonicCmd._networkService = networkService;
+
+        try {
+            ipTonicCmd.execute();
+        } catch (InsufficientAddressCapacityException e) {
+            throw new InvalidParameterValueException("Allocating guest ip for nic failed");
+        }
+    }
+
+    @Test
+    public void testRemoveIpFromVmNicSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException,
+        InsufficientCapacityException {
+
+        NetworkService networkService = Mockito.mock(NetworkService.class);
+        RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
+
+        Mockito.when(networkService.releaseSecondaryIpFromNic(Matchers.anyInt())).thenReturn(true);
+
+        removeIpFromNic._networkService = networkService;
+        removeIpFromNic.execute();
+    }
+
+    @Test
+    public void testRemoveIpFromVmNicFailure() throws InsufficientAddressCapacityException {
+        NetworkService networkService = Mockito.mock(NetworkService.class);
+        RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
+
+        Mockito.when(networkService.releaseSecondaryIpFromNic(Matchers.anyInt())).thenReturn(false);
+
+        removeIpFromNic._networkService = networkService;
+        successResponseGenerator = Mockito.mock(SuccessResponse.class);
+
+        try {
+            removeIpFromNic.execute();
+        } catch (InvalidParameterValueException exception) {
+            Assert.assertEquals("Failed to remove secondary  ip address for the nic", exception.getLocalizedMessage());
+        }
+    }
+}
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddNetworkServiceProviderCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddNetworkServiceProviderCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddNetworkServiceProviderCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddNetworkServiceProviderCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddVpnUserCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/AddVpnUserCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/AddVpnUserCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/AddVpnUserCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/CreateSnapshotCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/ListCfgCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/RegionCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/RegionCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/RegionCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/ScaleVMCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/ScaleVMCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/ScaleVMCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/ScaleVMCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/UpdateCfgCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/UpdateHostPasswordCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateHostPasswordCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/UpdateHostPasswordCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/UpdateHostPasswordCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/UpdateRoleCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateRoleCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/UpdateRoleCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/UpdateRoleCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/UpdateVmNicIpTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UpdateVmNicIpTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/UpdateVmNicIpTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/UpdateVmNicIpTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/UsageCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/test/UsageCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/test/UsageCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/test/UsageCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdByAdminTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdByAdminTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdByAdminTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdByAdminTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/user/template/CopyTemplateCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdByAdminTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdByAdminTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdByAdminTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdByAdminTest.java
diff --git a/api/test/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdTest.java
rename to api/src/test/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmdTest.java
diff --git a/api/test/org/apache/cloudstack/api/response/HostResponseTest.java b/api/src/test/java/org/apache/cloudstack/api/response/HostResponseTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/api/response/HostResponseTest.java
rename to api/src/test/java/org/apache/cloudstack/api/response/HostResponseTest.java
diff --git a/api/test/org/apache/cloudstack/context/CallContextTest.java b/api/src/test/java/org/apache/cloudstack/context/CallContextTest.java
similarity index 100%
rename from api/test/org/apache/cloudstack/context/CallContextTest.java
rename to api/src/test/java/org/apache/cloudstack/context/CallContextTest.java
diff --git a/api/test/org/apache/cloudstack/test/utils/SpringUtils.java b/api/src/test/java/org/apache/cloudstack/test/utils/SpringUtils.java
similarity index 100%
rename from api/test/org/apache/cloudstack/test/utils/SpringUtils.java
rename to api/src/test/java/org/apache/cloudstack/test/utils/SpringUtils.java
diff --git a/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java b/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
deleted file mode 100644
index 4139543..0000000
--- a/api/test/org/apache/cloudstack/api/command/test/AddIpToVmNicTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.test;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.apache.cloudstack.api.ResponseGenerator;
-import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
-import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.NetworkService;
-import com.cloud.vm.NicSecondaryIp;
-
-public class AddIpToVmNicTest extends TestCase {
-
-    private AddIpToVmNicCmd addIpToVmNicCmd;
-    private RemoveIpFromVmNicCmd removeIpFromVmNicCmd;
-    private ResponseGenerator responseGenerator;
-    private SuccessResponse successResponseGenerator;
-
-    @Override
-    @Before
-    public void setUp() {
-
-    }
-
-    @Test
-    public void testCreateSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
-
-        NetworkService networkService = Mockito.mock(NetworkService.class);
-        AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
-        NicSecondaryIp secIp = Mockito.mock(NicSecondaryIp.class);
-
-        Mockito.when(
-            networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.anyString()))
-            .thenReturn(secIp);
-
-        ipTonicCmd._networkService = networkService;
-        responseGenerator = Mockito.mock(ResponseGenerator.class);
-
-        NicSecondaryIpResponse ipres = Mockito.mock(NicSecondaryIpResponse.class);
-        Mockito.when(responseGenerator.createSecondaryIPToNicResponse(secIp)).thenReturn(ipres);
-
-        ipTonicCmd._responseGenerator = responseGenerator;
-        ipTonicCmd.execute();
-    }
-
-    @Test
-    public void testCreateFailure() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
-
-        NetworkService networkService = Mockito.mock(NetworkService.class);
-        AddIpToVmNicCmd ipTonicCmd = Mockito.mock(AddIpToVmNicCmd.class);
-
-        Mockito.when(
-            networkService.allocateSecondaryGuestIP(Matchers.anyLong(), Matchers.anyString()))
-            .thenReturn(null);
-
-        ipTonicCmd._networkService = networkService;
-
-        try {
-            ipTonicCmd.execute();
-        } catch (InsufficientAddressCapacityException e) {
-            throw new InvalidParameterValueException("Allocating guest ip for nic failed");
-        }
-    }
-
-    @Test
-    public void testRemoveIpFromVmNicSuccess() throws ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException,
-        InsufficientCapacityException {
-
-        NetworkService networkService = Mockito.mock(NetworkService.class);
-        RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
-
-        Mockito.when(networkService.releaseSecondaryIpFromNic(Matchers.anyInt())).thenReturn(true);
-
-        removeIpFromNic._networkService = networkService;
-        removeIpFromNic.execute();
-    }
-
-    @Test
-    public void testRemoveIpFromVmNicFailure() throws InsufficientAddressCapacityException {
-        NetworkService networkService = Mockito.mock(NetworkService.class);
-        RemoveIpFromVmNicCmd removeIpFromNic = Mockito.mock(RemoveIpFromVmNicCmd.class);
-
-        Mockito.when(networkService.releaseSecondaryIpFromNic(Matchers.anyInt())).thenReturn(false);
-
-        removeIpFromNic._networkService = networkService;
-        successResponseGenerator = Mockito.mock(SuccessResponse.class);
-
-        try {
-            removeIpFromNic.execute();
-        } catch (InvalidParameterValueException exception) {
-            Assert.assertEquals("Failed to remove secondary  ip address for the nic", exception.getLocalizedMessage());
-        }
-    }
-}
diff --git a/client/conf/server.properties.in b/client/conf/server.properties.in
index 6cb5692..7846df1 100644
--- a/client/conf/server.properties.in
+++ b/client/conf/server.properties.in
@@ -23,6 +23,7 @@
 context.path=/client
 
 # The HTTP port to be used by the management server
+http.enable=true
 http.port=8080
 
 # Max inactivity time in minutes for the session
@@ -34,6 +35,7 @@
 # keystore file should exists and be readable by the management server.
 https.enable=false
 https.port=8443
+
 # The keystore and manager passwords are assumed to be same.
 https.keystore=/etc/cloudstack/management/cloud.jks
 https.keystore.password=vmops.com
diff --git a/client/pom.xml b/client/pom.xml
index 5c142a5..6e814f1 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -1,1200 +1,944 @@
-<!-- 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-client-ui</artifactId>
-  <name>Apache CloudStack Client UI</name>
-  <packaging>jar</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
+<!--
+  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
 
-  <repositories>
-    <repository>
-      <id>juniper-contrail</id>
-      <url>http://juniper.github.io/contrail-maven/snapshots</url>
-    </repository>
-  </repositories>
+    http://www.apache.org/licenses/LICENSE-2.0
 
-  <dependencies>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>javax.servlet-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-servlets</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-webapp</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-jmx</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-spring-module</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-spring-lifecycle</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-solidfire</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-cloudbyte</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-acl-static-role-based</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-acl-dynamic-role-based</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-ca-rootca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-dedicated-resources</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-api-limit-account-based</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-api-discovery</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-ldap</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-md5</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-pbkdf2</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-plaintext</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-saml2</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-user-authenticator-sha256salted</artifactId>
-      <version>${project.version}</version>
-    </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>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-contrail</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-palo-alto</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-netscaler</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-ovs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-elb</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-bigswitch</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-ssp</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-internallb</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-vxlan</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-opendaylight</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-vcs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-vsp</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-ucs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-ovm</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-ovm3</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-kvm</artifactId>
-      <version>${project.version}</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>servlet-api</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-hyperv</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-allocator-random</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-planner-user-dispersing</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-       <artifactId>cloud-plugin-planner-skip-heurestics</artifactId>
-       <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-planner-implicit-dedication</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-explicit-dedication</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-host-allocator-random</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-outofbandmanagement-driver-ipmitool</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-outofbandmanagement-driver-nested-cloudstack</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-mom-rabbitmq</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-mom-inmemory</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-mom-kafka</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-agent-lb</artifactId>
-     <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-direct-download</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-quota</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-rest</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-network</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-orchestration</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-cache</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-configdrive</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-controller-secondary-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-datamotion</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-default</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-default</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-s3</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-swift</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-syslog-alerts</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-snmp-alerts</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-host-anti-affinity</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-host-affinity</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
+  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-client-ui</artifactId>
+    <name>Apache CloudStack Client UI</name>
+    <packaging>jar</packaging>
+    <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-plugin-api-solidfire-intg-test</artifactId>
-        <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-globodns</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-database-quota</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-integrations-cloudian-connector</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-integrations-prometheus-exporter</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>ru.concerteza.buildnumber</groupId>
-        <artifactId>maven-jgit-buildnumber-plugin</artifactId>
-        <version>1.2.6</version>
-        <executions>
-          <execution>
-            <id>git-buildnumber</id>
-            <goals>
-              <goal>extract-buildnumber</goal>
-            </goals>
-            <phase>prepare-package</phase>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <configuration>
-          <archive>
-            <manifest>
-              <mainClass>org.apache.cloudstack.ServerDaemon</mainClass>
-            </manifest>
-            <manifestEntries>
-              <X-Git-Branch>${git.branch}</X-Git-Branch>
-              <X-Git-Tag>${git.tag}</X-Git-Tag>
-              <X-Git-Revision>${git.revision}</X-Git-Revision>
-              <Implementation-Revision>${git.revision}</Implementation-Revision>
-              <Implementation-Branch>${git.branch}</Implementation-Branch>
-            </manifestEntries>
-          </archive>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-maven-plugin</artifactId>
-        <version>${cs.jetty-maven-plugin.version}</version>
-        <dependencies>
-          <!-- specify the dependent jdbc driver here -->
-          <dependency>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <repositories>
+        <repository>
+            <id>juniper-contrail</id>
+            <url>http://juniper.github.io/contrail-maven/snapshots</url>
+        </repository>
+    </repositories>
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlets</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+        </dependency>
+        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
-            <version>${cs.mysql.version}</version>
-          </dependency>
-          <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcprov-jdk15on</artifactId>
-            <version>${cs.bcprov.version}</version>
-          </dependency>
-          <dependency>
-            <groupId>org.bouncycastle</groupId>
-            <artifactId>bcpkix-jdk15on</artifactId>
-            <version>${cs.bcprov.version}</version>
-          </dependency>
-        </dependencies>
-        <configuration>
-          <scanIntervalSeconds>0</scanIntervalSeconds>
-          <stopPort>9966</stopPort>
-          <stopKey>stop-jetty</stopKey>
-          <connectors>
-            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-              <port>8080</port>
-              <maxIdleTime>60000</maxIdleTime>
-            </connector>
-          </connectors>
-          <webXml>${project.build.directory}/classes/META-INF/webapp/WEB-INF/web.xml</webXml>
-          <webAppSourceDirectory>${project.build.directory}/classes/META-INF/webapp/</webAppSourceDirectory>
-          <webAppConfig>
-            <contextPath>/client</contextPath>
-            <extraClasspath>${project.build.directory}/conf/;${project.build.directory}/common;${project.build.directory}/utilities/scripts/db/;${project.build.directory}/utilities/scripts/db/db/</extraClasspath>
-            <webInfIncludeJarPattern>.*/cloud.*jar$|.*/classes/.*</webInfIncludeJarPattern>
-          </webAppConfig>
-          <systemProperties>
-              <systemProperty>
-                 <name>log4j.configuration</name>
-                 <value>log4j-cloud.xml</value>
-              </systemProperty>
-          </systemProperties>
-        </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 todir="${project.build.directory}/common/scripts">
-                  <fileset dir="${basedir}/../scripts"/>
-                </copy>
-                <!-- CLOUDSTACK-1304 -->
-                <chmod perm="755"
-                  file="${project.build.directory}/common/scripts/**" type="both"/>
-                <copy todir="${project.build.directory}/classes/META-INF/webapp/WEB-INF/">
-                  <fileset dir="${basedir}/WEB-INF/">
-                    <include name="web.xml"/>
-                  </fileset>
-                </copy>
-                <copy todir="${project.build.directory}/classes/META-INF/webapp">
-                  <fileset dir="${basedir}/../ui"/>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/utilities/bin">
-                  <fileset dir="${basedir}/../setup/bindir">
-                    <include name="*.in"/>
-                  </fileset>
-                  <globmapper from="*.in" to="*"/>
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}"/>
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/utilities/bin">
-                  <fileset dir="${basedir}/bindir">
-                    <include name="*.in"/>
-                  </fileset>
-                  <globmapper from="*.in" to="*"/>
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}"/>
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/utilities/scripts/db">
-                  <fileset dir="${basedir}/../setup/db">
-                    <include name="*"/>
-                  </fileset>
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}"/>
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/conf">
-                  <fileset dir="${basedir}/conf">
-                    <include name="*.in"/>
-                  </fileset>
-                  <globmapper from="*.in" to="*"/>
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}"/>
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/conf">
-                  <fileset dir="${basedir}/conf">
-                    <exclude name="*.in"/>
-                  </fileset>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-          <execution>
-            <id>process-noredist</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target if="${noredist}">
-                <echo>test</echo>
-                <replaceregexp
-                  file="${basedir}/target/conf/environment.properties"
-                  match="cloud-stack-components-specification=.*"
-                  replace="cloud-stack-components-specification=components-nonoss.xml" byline="true"
-                />
-              </target>
-            </configuration>
-          </execution>
-          <execution>
-            <id>process-noredist-spring-context</id>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target if="${noredist}">
-                <replaceregexp file="${basedir}/target/classes/META-INF/webapp/WEB-INF/web.xml"
-                  match="classpath:componentContext.xml"
-                  replace="classpath:nonossComponentContext.xml" byline="true"/>
-                <copy overwrite="true"
-                  todir="${basedir}/target/common/scripts">
-                  <fileset dir="${basedir}/../plugins/network-elements/cisco-vnmc/scripts">
-                    <include name="**/*"/>
-                  </fileset>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <!-- there are the jasypt libs requires by some of the python scripts -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy</id>
-            <phase>package</phase>
-            <goals>
-              <goal>copy</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.jasypt</groupId>
-                  <artifactId>jasypt</artifactId>
-                  <version>1.9.2</version>
-                  <overWrite>false</overWrite>
-                  <outputDirectory>${project.build.directory}/pythonlibs</outputDirectory>
-                </artifactItem>
-                <artifactItem>
-                  <groupId>org.bouncycastle</groupId>
-                  <artifactId>bcprov-jdk15on</artifactId>
-                  <overWrite>false</overWrite>
-                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
-                </artifactItem>
-                <artifactItem>
-                  <groupId>org.bouncycastle</groupId>
-                  <artifactId>bcpkix-jdk15on</artifactId>
-                  <overWrite>false</overWrite>
-                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>none</phase>
-              <inherited>false</inherited>
-            </execution>
-          </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <version>3.0.0</version>
-        <executions>
-          <execution>
-            <id>rebuild-war</id>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <createDependencyReducedPom>false</createDependencyReducedPom>
-              <artifactSet>
-                <includes>
-                  <include>*:*</include>
-                </includes>
-                <excludes>
-                  <exclude>junit:junit</exclude>
-                  <exclude>com.tngtech.java:junit-dataprovider</exclude>
-                  <exclude>org.mockito:mockito-all</exclude>
-                  <exclude>org.hamcrest:hamcrest-all</exclude>
-                  <exclude>org.powermock:powermock-module-junit4</exclude>
-                  <exclude>org.powermock:powermock-api-mockito</exclude>
-                  <exclude>org.springframework:spring-test</exclude>
-                  <exclude>org.apache.tomcat.embed:tomcat-embed-core</exclude>
-                  <exclude>org.apache.geronimo.specs:geronimo-servlet_3.0_spec</exclude>
-                  <exclude>org.apache.geronimo.specs:geronimo-javamail_1.4_spec</exclude>
-                  <exclude>org.bouncycastle:bcprov-jdk15on</exclude>
-                  <exclude>org.bouncycastle:bcpkix-jdk15on</exclude>
-                  <exclude>mysql:mysql-connector-java</exclude>
-                </excludes>
-              </artifactSet>
-              <transformers>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer" />
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                  <mainClass>org.apache.cloudstack.ServerDaemon</mainClass>
-                </transformer>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                  <resource>META-INF/spring.handlers</resource>
-                </transformer>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                  <resource>META-INF/spring.schemas</resource>
-                </transformer>
-              </transformers>
-              <filters>
-                <filter>
-                  <artifact>*:*</artifact>
-                  <excludes>
-                    <exclude>META-INF/VERSION.txt</exclude>
-                    <exclude>META-INF/LICENSE.txt</exclude>
-                    <exclude>META-INF/*.SF</exclude>
-                    <exclude>META-INF/*.DSA</exclude>
-                    <exclude>META-INF/*.RSA</exclude>
-                    <exclude>META-INF/MANIFEST.MF</exclude>
-                    <exclude>META-INF/maven/**</exclude>
-                  </excludes>
-                </filter>
-              </filters>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>systemvm</id>
-      <activation>
-        <property>
-          <name>systemvm</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-systemvm</artifactId>
-          <version>${project.version}</version>
-          <type>pom</type>
+            <scope>runtime</scope>
         </dependency>
-      </dependencies>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-antrun-plugin</artifactId>
-            <version>1.7</version>
-            <executions>
-              <!-- Copy the systemvm in the package phase as it is generated by console-proxy
-            in the package phase. -->
-              <execution>
-                <id>copy-systemvm</id>
-                <phase>process-resources</phase>
-                <goals>
-                  <goal>run</goal>
-                </goals>
-                <configuration>
-                  <target>
-                    <copy todir="${basedir}/target/common/vms">
-                      <fileset dir="${basedir}/../systemvm/dist">
-                        <include name="systemvm.iso"/>
-                      </fileset>
-                    </copy>
-                  </target>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>buildw</id>
-      <activation>
-        <property>
-          <name>buildw</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <artifactId>maven-antrun-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>generate-resource-windows</id>
-                <phase>generate-resources</phase>
-                <goals>
-                  <goal>run</goal>
-                </goals>
-                <configuration>
-                  <target>
-                    <copy todir="./target">
-                      <fileset dir="../scripts/installer/windows/">
-                        <include name="start.bat"/>
-                        <include name="acs_license.rtf"/>
-                        <include name="optionstheme.xml"/>
-                        <include name="*.wxl"/>
-                      </fileset>
-                    </copy>
-                    <copy todir="./target/client">
-                      <fileset dir="./target/generated-webapp">
-                        <include name="**/*"/>
-                      </fileset>
-                    </copy>
-                    <copy todir="./target/setup">
-                      <fileset dir="./target/utilities/scripts/db">
-                        <include name="**/*" />
-                      </fileset>
-                    </copy>
-                    <copy file="../scripts/storage/secondary/cloud-install-sys-tmplt.py" tofile="target/scripts/cloud-install-sys-tmplt.py" />
-                    <copy todir="./target/scripts">
-                      <fileset dir="./target/utilities/bin">
-                        <include name="**/*" />
-                      </fileset>
-                    </copy>
-                    <copy todir="./target/python-site-packages">
-                      <fileset dir="../python/lib">
-                        <include name="**/*" />
-                      </fileset>
-                    </copy>
-                   </target>
-                  </configuration>
-                 </execution>
-                 <execution>
-                  <id>download-files</id>
-                  <phase>prepare-package</phase>
-                  <goals>
-                    <goal>run</goal>
-                  </goals>
-                  <configuration>
-                    <target>
-                      <!-- download file -->
-                      <get src="http://downloads.sourceforge.net/sevenzip/7z920-x64.msi" dest="target" verbose="false" usetimestamp="true"/>
-                      <get src="https://www.python.org/ftp/python/2.7.6/python-2.7.6.amd64.msi" dest="target" verbose="false" usetimestamp="true"/>
-                      <get src="http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.73-winx64.msi" dest="target" verbose="false" usetimestamp="true"/>
-                      <get src="http://downloads.sourceforge.net/project/cdrtoolswin/1.0/Binaries/CDR-Tools.exe?r=&amp;ts=1398764640&amp;use_mirror=kaz" dest="target" verbose="false" usetimestamp="true"/>
-                      <get src="https://bootstrap.pypa.io/ez_setup.py" dest="target" verbose="false" usetimestamp="true"/>
-                    </target>
-                  </configuration>
-                 </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-war-plugin</artifactId>
-            <version>2.5</version>
-            <configuration>
-              <webappDirectory>target/client</webappDirectory>
-              <webXml>./target/generated-webapp/WEB-INF/web.xml</webXml>
-              <warSourceDirectory>./target/generated-webapp</warSourceDirectory>
-              <archive>
-                <manifest>
-                  <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                </manifest>
-                <manifestEntries>
-                  <Implementation-Revision>${git.revision}</Implementation-Revision>
-                  <Implementation-Branch>${git.branch}</Implementation-Branch>
-                </manifestEntries>
-              </archive>
-            </configuration>
-          </plugin>
-          <plugin>
+        <dependency>
             <groupId>org.apache.cloudstack</groupId>
-            <artifactId>Wix-cloudstack-maven-plugin</artifactId>
+            <artifactId>cloud-framework-spring-module</artifactId>
             <version>${project.version}</version>
-            <executions>
-              <execution>
-                <id>wix-cs</id>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-spring-lifecycle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-solidfire</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-cloudbyte</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-acl-static-role-based</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-acl-dynamic-role-based</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-ca-rootca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-dedicated-resources</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-api-limit-account-based</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-api-discovery</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-ldap</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-md5</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-pbkdf2</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-plaintext</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-saml2</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-user-authenticator-sha256salted</artifactId>
+            <version>${project.version}</version>
+        </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>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-contrail</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-palo-alto</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-netscaler</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-ovs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-elb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-bigswitch</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-ssp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-internallb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-vxlan</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-opendaylight</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-vcs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-vsp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-ucs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-ovm</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-ovm3</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-kvm</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mortbay.jetty</groupId>
+                    <artifactId>servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-hyperv</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-allocator-random</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-planner-user-dispersing</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-planner-skip-heurestics</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-planner-user-concentrated-pod</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-planner-implicit-dedication</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-explicit-dedication</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-host-allocator-random</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-outofbandmanagement-driver-ipmitool</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-outofbandmanagement-driver-nested-cloudstack</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-mom-rabbitmq</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-mom-inmemory</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-mom-kafka</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-agent-lb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-direct-download</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-quota</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-network</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-orchestration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-cache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-configdrive</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-controller-secondary-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-datamotion</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-s3</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-swift</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-syslog-alerts</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-snmp-alerts</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-host-anti-affinity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-host-affinity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-api-solidfire-intg-test</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-globodns</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-database-quota</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-integrations-cloudian-connector</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-integrations-prometheus-exporter</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>ru.concerteza.buildnumber</groupId>
+                <artifactId>maven-jgit-buildnumber-plugin</artifactId>
+                <version>1.2.6</version>
+                <executions>
+                    <execution>
+                        <id>git-buildnumber</id>
+                        <goals>
+                            <goal>extract-buildnumber</goal>
+                        </goals>
+                        <phase>prepare-package</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
                 <configuration>
-                  <vars>-var wix.SourceClient</vars>
-                  <workingDirectory>${basedir}/target</workingDirectory>
-                  <dir>client</dir>
-                  <template>fragment</template>
-                  <directoryName>WEBAPPS</directoryName>
-                  <outputFile>target/client.wxs</outputFile>
-                  <componentGroup>ClientPath</componentGroup>
+                    <archive>
+                        <manifest>
+                            <mainClass>org.apache.cloudstack.ServerDaemon</mainClass>
+                        </manifest>
+                        <manifestEntries>
+                            <X-Git-Branch>${git.branch}</X-Git-Branch>
+                            <X-Git-Tag>${git.tag}</X-Git-Tag>
+                            <X-Git-Revision>${git.revision}</X-Git-Revision>
+                            <Implementation-Revision>${git.revision}</Implementation-Revision>
+                            <Implementation-Branch>${git.branch}</Implementation-Branch>
+                        </manifestEntries>
+                    </archive>
                 </configuration>
-                <goals>
-                  <goal>heat</goal>
-                </goals>
-                </execution>
-                <execution>
-                  <id>wix-cs-setup-db</id>
-                  <configuration>
-                    <vars>-var wix.SetupPathDir</vars>
-                    <workingDirectory>${basedir}/target</workingDirectory>
-                    <dir>setup</dir>
-                    <template>fragment</template>
-                    <directoryName>CSMANAGEMENT</directoryName>
-                    <outputFile>target/setupdb.wxs</outputFile>
-                    <componentGroup>SetupPath</componentGroup>
-                  </configuration>
-                  <goals>
-                    <goal>heat</goal>
-                  </goals>
-                </execution>
-                <execution>
-                  <id>wix-cs-utilities</id>
-                  <configuration>
-                    <vars>-var wix.UtilitiesPathDir</vars>
-                    <workingDirectory>${basedir}/target</workingDirectory>
-                    <dir>scripts</dir>
-                    <template>fragment</template>
-                    <directoryName>INSTALLDIR</directoryName>
-                    <outputFile>target/utilities.wxs</outputFile>
-                    <componentGroup>UtilitiesPath</componentGroup>
-                  </configuration>
-                  <goals>
-                    <goal>heat</goal>
-                  </goals>
-                </execution>
-                <execution>
-                  <id>python-site-packages</id>
-                  <configuration>
-                    <vars>-var wix.PythonSitePackagesDir</vars>
-                    <workingDirectory>${basedir}/target</workingDirectory>
-                    <dir>python-site-packages</dir>
-                    <template>fragment</template>
-                    <directoryName>INSTALLDIR</directoryName>
-                    <outputFile>target/python-site-packages.wxs</outputFile>
-                    <componentGroup>PythonSitePackagesPath</componentGroup>
-                  </configuration>
-                  <goals>
-                    <goal>heat</goal>
-                  </goals>
-                </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.bitbucket.joxley</groupId>
-            <artifactId>wix-maven-plugin</artifactId>
-            <version>1.1.1</version>
-            <executions>
-              <execution>
-                <id>wix-acs</id>
-                  <configuration>
-                    <workingDirectory>${basedir}/target</workingDirectory>
-                    <extensions>
-                      <extension>WixFirewallExtension</extension>
-                      <extension>WixUIExtension</extension>
-                      <extension>WixUtilExtension</extension>
-                    </extensions>
-                    <arguments>-dSourceClient=SourceDir\client -dSetupPathDir=SourceDir\setup -dUtilitiesPathDir=SourceDir\scripts -dPythonSitePackagesDir=SourceDir\python-site-packages</arguments>
-                    <sourceFiles>
-                      <sourceFile>../scripts/installer/windows/acs.wxs</sourceFile>
-                      <sourceFile>../scripts/installer/windows/WixInstallerDialog.wxs</sourceFile>
-                      <sourceFile>../scripts/installer/windows/Setup_Databases.wxs</sourceFile>
-                      <sourceFile>target/client.wxs</sourceFile>
-                      <sourceFile>target/setupdb.wxs</sourceFile>
-                      <sourceFile>target/utilities.wxs</sourceFile>
-                      <sourceFile>target/python-site-packages.wxs</sourceFile>
-                    </sourceFiles>
-                    <outputDirectory>target</outputDirectory>
-                    <objectFiles>
-                      <objectFile>target/acs.wixobj</objectFile>
-                      <objectFile>target/client.wixobj</objectFile>
-                      <objectFile>target/setupdb.wixobj</objectFile>
-                      <objectFile>target/utilities.wixobj</objectFile>
-                      <objectFile>target/WixInstallerDialog.wixobj</objectFile>
-                      <objectFile>target/Setup_Databases.wixobj</objectFile>
-                      <objectFile>target/python-site-packages.wixobj</objectFile>
-                    </objectFiles>
-                    <cultures>
-                      <culture>en-us</culture>
-                    </cultures>
-                    <localizationFiles>
-                      <localizationFile>target/en-us.wxl</localizationFile>
-                    </localizationFiles>
-                    <outputFile>target/acs.msi</outputFile>
-                  </configuration>
-                  <goals>
-                    <goal>candle</goal>
-                    <goal>light</goal>
-                  </goals>
-              </execution>
-              <execution>
-                <id>wix-final</id>
-                  <configuration>
-                    <workingDirectory>${basedir}/target</workingDirectory>
-                    <extensions>
-                      <extension>WixBalExtension</extension>
-                      <extension>WixUtilExtension</extension>
-                    </extensions>
-                    <sourceFiles>
-                      <sourceFile>../scripts/installer/windows/dependencies.wxs</sourceFile>
-                    </sourceFiles>
-                    <outputDirectory>target</outputDirectory>
-                    <objectFiles>
-                      <objectFile>target/dependencies.wixobj</objectFile>
-                    </objectFiles>
-                    <cultures>
-                      <culture>en-US</culture>
-                    </cultures>
-                    <localizationFiles>
-                      <localizationFile>target/en-us.wxl</localizationFile>
-                    </localizationFiles>
-                    <outputFile>target/acs-${project.version}.exe</outputFile>
-                  </configuration>
-                  <goals>
-                    <goal>candle</goal>
-                    <goal>light</goal>
-                  </goals>
-              </execution>
-            </executions>
-          </plugin>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${cs.jetty-maven-plugin.version}</version>
+                <dependencies>
+                    <!-- specify the dependent jdbc driver here -->
+                    <dependency>
+                        <groupId>mysql</groupId>
+                        <artifactId>mysql-connector-java</artifactId>
+                        <version>${cs.mysql.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.bouncycastle</groupId>
+                        <artifactId>bcprov-jdk15on</artifactId>
+                        <version>${cs.bcprov.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.bouncycastle</groupId>
+                        <artifactId>bcpkix-jdk15on</artifactId>
+                        <version>${cs.bcprov.version}</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <scanIntervalSeconds>0</scanIntervalSeconds>
+                    <stopPort>9966</stopPort>
+                    <stopKey>stop-jetty</stopKey>
+                    <connectors>
+                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+                            <port>8080</port>
+                            <maxIdleTime>60000</maxIdleTime>
+                        </connector>
+                    </connectors>
+                    <webXml>${project.build.directory}/classes/META-INF/webapp/WEB-INF/web.xml</webXml>
+                    <webAppSourceDirectory>${project.build.directory}/classes/META-INF/webapp/</webAppSourceDirectory>
+                    <webAppConfig>
+                        <contextPath>/client</contextPath>
+                        <extraClasspath>${project.build.directory}/conf/;${project.build.directory}/common;${project.build.directory}/utilities/scripts/db/;${project.build.directory}/utilities/scripts/db/db/</extraClasspath>
+                        <webInfIncludeJarPattern>.*/cloud.*jar$|.*/classes/.*</webInfIncludeJarPattern>
+                    </webAppConfig>
+                    <systemProperties>
+                        <systemProperty>
+                            <name>log4j.configuration</name>
+                            <value>log4j-cloud.xml</value>
+                        </systemProperty>
+                    </systemProperties>
+                </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 todir="${project.build.directory}/common/scripts">
+                                    <fileset dir="${basedir}/../scripts" />
+                                </copy>
+                                <!-- CLOUDSTACK-1304 -->
+                                <chmod perm="755" file="${project.build.directory}/common/scripts/**" type="both" />
+                                <copy todir="${project.build.directory}/classes/META-INF/webapp/WEB-INF/">
+                                    <fileset dir="${basedir}/src/main/webapp/WEB-INF/">
+                                        <include name="web.xml" />
+                                    </fileset>
+                                </copy>
+                                <copy todir="${project.build.directory}/classes/META-INF/webapp">
+                                    <fileset dir="${basedir}/../ui" />
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/utilities/bin">
+                                    <fileset dir="${basedir}/../setup/bindir">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader
+                                            classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/utilities/bin">
+                                    <fileset dir="${basedir}/bindir">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/utilities/scripts/db">
+                                    <fileset dir="${basedir}/../setup/db">
+                                        <include name="*" />
+                                    </fileset>
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/conf">
+                                    <fileset dir="${basedir}/conf">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/conf">
+                                    <fileset dir="${basedir}/conf">
+                                        <exclude name="*.in" />
+                                    </fileset>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>process-noredist</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target if="${noredist}">
+                                <echo>test</echo>
+                                <replaceregexp
+                                    file="${basedir}/target/conf/environment.properties"
+                                    match="cloud-stack-components-specification=.*"
+                                    replace="cloud-stack-components-specification=components-nonoss.xml"
+                                    byline="true" />
+                            </target>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>process-noredist-spring-context</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target if="${noredist}">
+                                <replaceregexp
+                                    file="${basedir}/target/classes/META-INF/webapp/WEB-INF/web.xml"
+                                    match="classpath:componentContext.xml"
+                                    replace="classpath:nonossComponentContext.xml"
+                                    byline="true" />
+                                <copy overwrite="true" todir="${basedir}/target/common/scripts">
+                                    <fileset dir="${basedir}/../plugins/network-elements/cisco-vnmc/src/main/scripts">
+                                        <include name="**/*" />
+                                    </fileset>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- there are the jasypt libs requires by some of the python scripts -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.jasypt</groupId>
+                                    <artifactId>jasypt</artifactId>
+                                    <version>${cs.jasypt.version}</version>
+                                    <overWrite>false</overWrite>
+                                    <outputDirectory>${project.build.directory}/pythonlibs</outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.bouncycastle</groupId>
+                                    <artifactId>bcprov-jdk15on</artifactId>
+                                    <overWrite>false</overWrite>
+                                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.bouncycastle</groupId>
+                                    <artifactId>bcpkix-jdk15on</artifactId>
+                                    <overWrite>false</overWrite>
+                                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <id>rebuild-war</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <createDependencyReducedPom>false</createDependencyReducedPom>
+                            <artifactSet>
+                                <includes>
+                                    <include>*:*</include>
+                                </includes>
+                                <excludes>
+                                    <exclude>junit:junit</exclude>
+                                    <exclude>com.tngtech.java:junit-dataprovider</exclude>
+                                    <exclude>org.mockito:mockito-all</exclude>
+                                    <exclude>org.hamcrest:hamcrest-all</exclude>
+                                    <exclude>org.powermock:powermock-module-junit4</exclude>
+                                    <exclude>org.powermock:powermock-api-mockito</exclude>
+                                    <exclude>org.springframework:spring-test</exclude>
+                                    <exclude>org.apache.tomcat.embed:tomcat-embed-core</exclude>
+                                    <exclude>org.apache.geronimo.specs:geronimo-servlet_3.0_spec</exclude>
+                                    <exclude>org.apache.geronimo.specs:geronimo-javamail_1.4_spec</exclude>
+                                    <exclude>org.bouncycastle:bcprov-jdk15on</exclude>
+                                    <exclude>org.bouncycastle:bcpkix-jdk15on</exclude>
+                                    <exclude>mysql:mysql-connector-java</exclude>
+                                </excludes>
+                            </artifactSet>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer" />
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>org.apache.cloudstack.ServerDaemon</mainClass>
+                                </transformer>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/spring.handlers</resource>
+                                </transformer>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                                    <resource>META-INF/spring.schemas</resource>
+                                </transformer>
+                            </transformers>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>META-INF/VERSION.txt</exclude>
+                                        <exclude>META-INF/LICENSE.txt</exclude>
+                                        <exclude>META-INF/*.SF</exclude>
+                                        <exclude>META-INF/*.DSA</exclude>
+                                        <exclude>META-INF/*.RSA</exclude>
+                                        <exclude>META-INF/MANIFEST.MF</exclude>
+                                        <exclude>META-INF/maven/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>simulator</id>
-      <activation>
-        <property>
-          <name>simulator</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-hypervisor-simulator</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>netapp</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-netapp</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>f5</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-network-f5</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>srx</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-network-srx</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>vmware</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-vmware-base</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-network-cisco-vnmc</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>mysqlha</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-database-mysqlha</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-        <id>vmwaresioc</id>
-        <activation>
-            <property>
-                <name>noredist</name>
-            </property>
-        </activation>
-        <dependencies>
-            <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-plugin-api-vmware-sioc</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-        </dependencies>
-    </profile>
-    <profile>
-      <id>quickcloud</id>
-      <activation>
-        <property>
-          <name>quickcloud</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-quickcloud</artifactId>
-          <version>${project.version}</version>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
+    </build>
+    <profiles>
+        <profile>
+            <id>systemvm</id>
+            <activation>
+                <property>
+                    <name>systemvm</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-systemvm</artifactId>
+                    <version>${project.version}</version>
+                    <type>pom</type>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <version>1.7</version>
+                        <executions>
+                            <!-- Copy the systemvm in the package phase as it is generated by console-proxy in the package 
+                                phase. -->
+                            <execution>
+                                <id>copy-systemvm</id>
+                                <phase>process-resources</phase>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <target>
+                                        <copy todir="${basedir}/target/common/vms">
+                                            <fileset dir="${basedir}/../systemvm/dist">
+                                                <include name="systemvm.iso" />
+                                            </fileset>
+                                        </copy>
+                                    </target>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>simulator</id>
+            <activation>
+                <property>
+                    <name>simulator</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-hypervisor-simulator</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>f5</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-network-f5</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>srx</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-network-srx</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>vmware</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-vmware-base</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-network-cisco-vnmc</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>mysqlha</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-database-mysqlha</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>vmwaresioc</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-api-vmware-sioc</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>quickcloud</id>
+            <activation>
+                <property>
+                    <name>quickcloud</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-quickcloud</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
 </project>
diff --git a/client/src/main/java/org/apache/cloudstack/ServerDaemon.java b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java
new file mode 100644
index 0000000..1e47aef
--- /dev/null
+++ b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java
@@ -0,0 +1,342 @@
+//
+// 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.commons.daemon.Daemon;
+import org.apache.commons.daemon.DaemonContext;
+import org.eclipse.jetty.jmx.MBeanContainer;
+import org.eclipse.jetty.server.ForwardedRequestCustomizer;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.MovedContextHandler;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.cloud.utils.PropertiesUtil;
+import com.google.common.base.Strings;
+
+/***
+ * The ServerDaemon class implements the embedded server, it can be started either
+ * using JSVC or directly from the JAR along with additional jars not shaded in the uber-jar.
+ * Configuration parameters are read from server.properties file available on the classpath.
+ */
+public class ServerDaemon implements Daemon {
+    private static final Logger LOG = LoggerFactory.getLogger(ServerDaemon.class);
+    private static final String WEB_XML = "META-INF/webapp/WEB-INF/web.xml";
+
+    /////////////////////////////////////////////////////
+    /////////////// Server Properties ///////////////////
+    /////////////////////////////////////////////////////
+
+    private static final String BIND_INTERFACE = "bind.interface";
+    private static final String CONTEXT_PATH = "context.path";
+    private static final String SESSION_TIMEOUT = "session.timeout";
+    private static final String HTTP_ENABLE = "http.enable";
+    private static final String HTTP_PORT = "http.port";
+    private static final String HTTPS_ENABLE = "https.enable";
+    private static final String HTTPS_PORT = "https.port";
+    private static final String KEYSTORE_FILE = "https.keystore";
+    private static final String KEYSTORE_PASSWORD = "https.keystore.password";
+    private static final String WEBAPP_DIR = "webapp.dir";
+    private static final String ACCESS_LOG = "access.log";
+
+    ////////////////////////////////////////////////////////
+    /////////////// Server Configuration ///////////////////
+    ////////////////////////////////////////////////////////
+
+    private Server server;
+
+    private boolean httpEnable = true;
+    private int httpPort = 8080;
+    private int httpsPort = 8443;
+    private int sessionTimeout = 30;
+    private boolean httpsEnable = false;
+    private String accessLogFile = "access.log";
+    private String bindInterface = null;
+    private String contextPath = "/client";
+    private String keystoreFile;
+    private String keystorePassword;
+    private String webAppLocation;
+
+    //////////////////////////////////////////////////
+    /////////////// Public methods ///////////////////
+    //////////////////////////////////////////////////
+
+    public static void main(final String... anArgs) throws Exception {
+        final ServerDaemon daemon = new ServerDaemon();
+        daemon.init(null);
+        daemon.start();
+    }
+
+    @Override
+    public void init(final DaemonContext context) {
+        final File confFile = PropertiesUtil.findConfigFile("server.properties");
+        if (confFile == null) {
+            LOG.warn(String.format("Server configuration file not found. Initializing server daemon on %s, with http.enable=%s, http.port=%s, https.enable=%s, https.port=%s, context.path=%s",
+                    bindInterface, httpEnable, httpPort, httpsEnable, httpsPort, contextPath));
+            return;
+        }
+
+        LOG.info("Server configuration file found: " + confFile.getAbsolutePath());
+
+        try {
+            final Properties properties = PropertiesUtil.loadFromFile(confFile);
+            if (properties == null) {
+                return;
+            }
+            setBindInterface(properties.getProperty(BIND_INTERFACE, null));
+            setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
+            setHttpEnable(Boolean.valueOf(properties.getProperty(HTTP_ENABLE, "true")));
+            setHttpPort(Integer.valueOf(properties.getProperty(HTTP_PORT, "8080")));
+            setHttpsEnable(Boolean.valueOf(properties.getProperty(HTTPS_ENABLE, "false")));
+            setHttpsPort(Integer.valueOf(properties.getProperty(HTTPS_PORT, "8443")));
+            setKeystoreFile(properties.getProperty(KEYSTORE_FILE));
+            setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
+            setWebAppLocation(properties.getProperty(WEBAPP_DIR));
+            setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
+            setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
+        } catch (final IOException e) {
+            LOG.warn("Failed to load configuration from server.properties file", e);
+        } finally {
+            // make sure that at least HTTP is enabled if both of them are set to false (misconfiguration)
+            if (!httpEnable && !httpsEnable) {
+                setHttpEnable(true);
+                LOG.warn("Server configuration malformed, neither http nor https is enabled, http will be enabled.");
+            }
+        }
+        LOG.info(String.format("Initializing server daemon on %s, with http.enable=%s, http.port=%s, https.enable=%s, https.port=%s, context.path=%s",
+                bindInterface, httpEnable, httpPort, httpsEnable, httpsPort, contextPath));
+    }
+
+    @Override
+    public void start() throws Exception {
+        // Thread pool
+        final QueuedThreadPool threadPool = new QueuedThreadPool();
+        threadPool.setMinThreads(10);
+        threadPool.setMaxThreads(500);
+
+        // Jetty Server
+        server = new Server(threadPool);
+
+        // Setup Scheduler
+        server.addBean(new ScheduledExecutorScheduler());
+
+        // Setup JMX
+        final MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
+        server.addBean(mbeanContainer);
+
+        // HTTP config
+        final HttpConfiguration httpConfig = new HttpConfiguration();
+        httpConfig.addCustomizer( new ForwardedRequestCustomizer() );
+        httpConfig.setSecureScheme("https");
+        httpConfig.setSecurePort(httpsPort);
+        httpConfig.setOutputBufferSize(32768);
+        httpConfig.setRequestHeaderSize(8192);
+        httpConfig.setResponseHeaderSize(8192);
+        httpConfig.setSendServerVersion(false);
+        httpConfig.setSendDateHeader(false);
+
+        // HTTP Connector
+        createHttpConnector(httpConfig);
+
+        // Setup handlers
+        server.setHandler(createHandlers());
+
+        // Extra config options
+        server.setStopAtShutdown(true);
+
+        // HTTPS Connector
+        createHttpsConnector(httpConfig);
+
+        server.start();
+        server.join();
+    }
+
+    @Override
+    public void stop() throws Exception {
+        server.stop();
+    }
+
+    @Override
+    public void destroy() {
+        server.destroy();
+    }
+
+    ///////////////////////////////////////////////////
+    /////////////// Private methods ///////////////////
+    ///////////////////////////////////////////////////
+
+    private void createHttpConnector(final HttpConfiguration httpConfig) {
+        if (httpEnable) {
+            final ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
+            httpConnector.setPort(httpPort);
+            httpConnector.setHost(bindInterface);
+            httpConnector.setIdleTimeout(30000);
+            server.addConnector(httpConnector);
+        }
+    }
+
+    private void createHttpsConnector(final HttpConfiguration httpConfig) {
+        // Configure SSL
+        if (httpsEnable && !Strings.isNullOrEmpty(keystoreFile) && new File(keystoreFile).exists()) {
+            // SSL Context
+            final SslContextFactory sslContextFactory = new SslContextFactory();
+
+            // Define keystore path and passwords
+            sslContextFactory.setKeyStorePath(keystoreFile);
+            sslContextFactory.setKeyStorePassword(keystorePassword);
+            sslContextFactory.setKeyManagerPassword(keystorePassword);
+
+            // HTTPS config
+            final HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
+            httpsConfig.addCustomizer(new SecureRequestCustomizer());
+
+            // HTTPS Connector
+            final ServerConnector sslConnector = new ServerConnector(server,
+                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
+                    new HttpConnectionFactory(httpsConfig));
+            sslConnector.setPort(httpsPort);
+            sslConnector.setHost(bindInterface);
+            server.addConnector(sslConnector);
+        }
+    }
+
+    private HandlerCollection createHandlers() {
+        final WebAppContext webApp = new WebAppContext();
+        webApp.setContextPath(contextPath);
+        webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
+        webApp.getSessionHandler().setMaxInactiveInterval(sessionTimeout * 60);
+
+        // GZIP handler
+        final GzipHandler gzipHandler = new GzipHandler();
+        gzipHandler.addIncludedMimeTypes("text/html", "text/xml", "text/css", "text/plain", "text/javascript", "application/javascript", "application/json", "application/xml");
+        gzipHandler.setIncludedMethods("GET", "POST");
+        gzipHandler.setCompressionLevel(9);
+        gzipHandler.setHandler(webApp);
+
+        if (Strings.isNullOrEmpty(webAppLocation)) {
+            webApp.setWar(getShadedWarUrl());
+        } else {
+            webApp.setWar(webAppLocation);
+        }
+
+        // Request log handler
+        final RequestLogHandler log = new RequestLogHandler();
+        log.setRequestLog(createRequestLog());
+
+        // Redirect root context handler
+        MovedContextHandler rootRedirect = new MovedContextHandler();
+        rootRedirect.setContextPath("/");
+        rootRedirect.setNewContextURL(contextPath);
+        rootRedirect.setPermanent(true);
+
+        // Put rootRedirect at the end!
+        return new HandlerCollection(log, gzipHandler, rootRedirect);
+    }
+
+    private RequestLog createRequestLog() {
+        final NCSARequestLog log = new NCSARequestLog();
+        final File logPath = new File(accessLogFile);
+        final File parentFile = logPath.getParentFile();
+        if (parentFile != null) {
+            parentFile.mkdirs();
+        }
+        log.setFilename(logPath.getPath());
+        log.setAppend(true);
+        log.setLogTimeZone("GMT");
+        log.setLogLatency(true);
+        return log;
+    }
+
+    private URL getResource(String aResource) {
+        return Thread.currentThread().getContextClassLoader().getResource(aResource);
+    }
+
+    private String getShadedWarUrl() {
+        final String urlStr = getResource(WEB_XML).toString();
+        return urlStr.substring(0, urlStr.length() - 15);
+    }
+
+    ///////////////////////////////////////////
+    /////////////// Setters ///////////////////
+    ///////////////////////////////////////////
+
+    public void setBindInterface(String bindInterface) {
+        this.bindInterface = bindInterface;
+    }
+
+    public void setHttpPort(int httpPort) {
+        this.httpPort = httpPort;
+    }
+
+    public void setHttpEnable(boolean httpEnable) {
+        this.httpEnable = httpEnable;
+    }
+
+    public void setHttpsPort(int httpsPort) {
+        this.httpsPort = httpsPort;
+    }
+
+    public void setContextPath(String contextPath) {
+        this.contextPath = contextPath;
+    }
+
+    public void setHttpsEnable(boolean httpsEnable) {
+        this.httpsEnable = httpsEnable;
+    }
+
+    public void setKeystoreFile(String keystoreFile) {
+        this.keystoreFile = keystoreFile;
+    }
+
+    public void setKeystorePassword(String keystorePassword) {
+        this.keystorePassword = keystorePassword;
+    }
+
+    public void setAccessLogFile(String accessLogFile) {
+        this.accessLogFile = accessLogFile;
+    }
+
+    public void setWebAppLocation(String webAppLocation) {
+        this.webAppLocation = webAppLocation;
+    }
+
+    public void setSessionTimeout(int sessionTimeout) {
+        this.sessionTimeout = sessionTimeout;
+    }
+}
diff --git a/client/resources/META-INF/cloudstack/webApplicationContext.xml b/client/src/main/resources/META-INF/cloudstack/webApplicationContext.xml
similarity index 100%
rename from client/resources/META-INF/cloudstack/webApplicationContext.xml
rename to client/src/main/resources/META-INF/cloudstack/webApplicationContext.xml
diff --git a/client/WEB-INF/web.xml b/client/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from client/WEB-INF/web.xml
rename to client/src/main/webapp/WEB-INF/web.xml
diff --git a/client/src/org/apache/cloudstack/ServerDaemon.java b/client/src/org/apache/cloudstack/ServerDaemon.java
deleted file mode 100644
index 6d27383..0000000
--- a/client/src/org/apache/cloudstack/ServerDaemon.java
+++ /dev/null
@@ -1,317 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package org.apache.cloudstack;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.net.URL;
-import java.util.Properties;
-
-import org.apache.commons.daemon.Daemon;
-import org.apache.commons.daemon.DaemonContext;
-import org.eclipse.jetty.jmx.MBeanContainer;
-import org.eclipse.jetty.server.ForwardedRequestCustomizer;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.NCSARequestLog;
-import org.eclipse.jetty.server.RequestLog;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.MovedContextHandler;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
-import org.eclipse.jetty.server.handler.gzip.GzipHandler;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.cloud.utils.PropertiesUtil;
-import com.google.common.base.Strings;
-
-/***
- * The ServerDaemon class implements the embedded server, it can be started either
- * using JSVC or directly from the JAR along with additional jars not shaded in the uber-jar.
- * Configuration parameters are read from server.properties file available on the classpath.
- */
-public class ServerDaemon implements Daemon {
-    private static final Logger LOG = LoggerFactory.getLogger(ServerDaemon.class);
-    private static final String WEB_XML = "META-INF/webapp/WEB-INF/web.xml";
-
-    /////////////////////////////////////////////////////
-    /////////////// Server Properties ///////////////////
-    /////////////////////////////////////////////////////
-
-    private static final String BIND_INTERFACE = "bind.interface";
-    private static final String CONTEXT_PATH = "context.path";
-    private static final String SESSION_TIMEOUT = "session.timeout";
-    private static final String HTTP_PORT = "http.port";
-    private static final String HTTPS_ENABLE = "https.enable";
-    private static final String HTTPS_PORT = "https.port";
-    private static final String KEYSTORE_FILE = "https.keystore";
-    private static final String KEYSTORE_PASSWORD = "https.keystore.password";
-    private static final String WEBAPP_DIR = "webapp.dir";
-    private static final String ACCESS_LOG = "access.log";
-
-    ////////////////////////////////////////////////////////
-    /////////////// Server Configuration ///////////////////
-    ////////////////////////////////////////////////////////
-
-    private Server server;
-
-    private int httpPort = 8080;
-    private int httpsPort = 8443;
-    private int sessionTimeout = 30;
-    private boolean httpsEnable = false;
-    private String accessLogFile = "access.log";
-    private String bindInterface = null;
-    private String contextPath = "/client";
-    private String keystoreFile;
-    private String keystorePassword;
-    private String webAppLocation;
-
-    //////////////////////////////////////////////////
-    /////////////// Public methods ///////////////////
-    //////////////////////////////////////////////////
-
-    public static void main(final String... anArgs) throws Exception {
-        final ServerDaemon daemon = new ServerDaemon();
-        daemon.init(null);
-        daemon.start();
-    }
-
-    @Override
-    public void init(final DaemonContext context) {
-        final File confFile = PropertiesUtil.findConfigFile("server.properties");
-        if (confFile == null) {
-            LOG.warn(String.format("Server configuration file not found. Initializing server daemon on %s:%s, with https.enabled=%s, https.port=%s, context.path=%s",
-                    bindInterface, httpPort, httpsEnable, httpsPort, contextPath));
-            return;
-        }
-
-        LOG.info("Server configuration file found: " + confFile.getAbsolutePath());
-
-        try {
-            final Properties properties = PropertiesUtil.loadFromFile(confFile);
-            if (properties == null) {
-                return;
-            }
-            setBindInterface(properties.getProperty(BIND_INTERFACE, null));
-            setContextPath(properties.getProperty(CONTEXT_PATH, "/client"));
-            setHttpPort(Integer.valueOf(properties.getProperty(HTTP_PORT, "8080")));
-            setHttpsEnable(Boolean.valueOf(properties.getProperty(HTTPS_ENABLE, "false")));
-            setHttpsPort(Integer.valueOf(properties.getProperty(HTTPS_PORT, "8443")));
-            setKeystoreFile(properties.getProperty(KEYSTORE_FILE));
-            setKeystorePassword(properties.getProperty(KEYSTORE_PASSWORD));
-            setWebAppLocation(properties.getProperty(WEBAPP_DIR));
-            setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log"));
-            setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30")));
-        } catch (final IOException e) {
-            LOG.warn("Failed to load configuration from server.properties file", e);
-        }
-        LOG.info(String.format("Initializing server daemon on %s:%s, with https.enabled=%s, https.port=%s, context.path=%s",
-                bindInterface, httpPort, httpsEnable, httpsPort, contextPath));
-    }
-
-    @Override
-    public void start() throws Exception {
-        // Thread pool
-        final QueuedThreadPool threadPool = new QueuedThreadPool();
-        threadPool.setMinThreads(10);
-        threadPool.setMaxThreads(500);
-
-        // Jetty Server
-        server = new Server(threadPool);
-
-        // Setup Scheduler
-        server.addBean(new ScheduledExecutorScheduler());
-
-        // Setup JMX
-        final MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
-        server.addBean(mbeanContainer);
-
-        // HTTP config
-        final HttpConfiguration httpConfig = new HttpConfiguration();
-        httpConfig.addCustomizer( new ForwardedRequestCustomizer() );
-        httpConfig.setSecureScheme("https");
-        httpConfig.setSecurePort(httpsPort);
-        httpConfig.setOutputBufferSize(32768);
-        httpConfig.setRequestHeaderSize(8192);
-        httpConfig.setResponseHeaderSize(8192);
-        httpConfig.setSendServerVersion(false);
-        httpConfig.setSendDateHeader(false);
-
-        // HTTP Connector
-        final ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
-        httpConnector.setPort(httpPort);
-        httpConnector.setHost(bindInterface);
-        httpConnector.setIdleTimeout(30000);
-        server.addConnector(httpConnector);
-
-        // Setup handlers
-        server.setHandler(createHandlers());
-
-        // Extra config options
-        server.setStopAtShutdown(true);
-
-        // Configure SSL
-        if (httpsEnable && !Strings.isNullOrEmpty(keystoreFile) && new File(keystoreFile).exists()) {
-            // SSL Context
-            final SslContextFactory sslContextFactory = new SslContextFactory();
-            // Define keystore path and passwords
-            sslContextFactory.setKeyStorePath(keystoreFile);
-            sslContextFactory.setKeyStorePassword(keystorePassword);
-            sslContextFactory.setKeyManagerPassword(keystorePassword);
-
-            // HTTPS config
-            final HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
-            httpsConfig.addCustomizer(new SecureRequestCustomizer());
-
-            // HTTPS connector
-            final ServerConnector sslConnector = new ServerConnector(server,
-                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
-                    new HttpConnectionFactory(httpsConfig));
-            sslConnector.setPort(httpsPort);
-            sslConnector.setHost(bindInterface);
-            server.addConnector(sslConnector);
-        }
-
-        server.start();
-        server.join();
-    }
-
-    @Override
-    public void stop() throws Exception {
-        server.stop();
-    }
-
-    @Override
-    public void destroy() {
-        server.destroy();
-    }
-
-    ///////////////////////////////////////////////////
-    /////////////// Private methods ///////////////////
-    ///////////////////////////////////////////////////
-
-    private HandlerCollection createHandlers() {
-        final WebAppContext webApp = new WebAppContext();
-        webApp.setContextPath(contextPath);
-        webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
-        webApp.getSessionHandler().setMaxInactiveInterval(sessionTimeout * 60);
-
-        // GZIP handler
-        final GzipHandler gzipHandler = new GzipHandler();
-        gzipHandler.addIncludedMimeTypes("text/html", "text/xml", "text/css", "text/plain", "text/javascript", "application/javascript", "application/json", "application/xml");
-        gzipHandler.setIncludedMethods("GET", "POST");
-        gzipHandler.setCompressionLevel(9);
-        gzipHandler.setHandler(webApp);
-
-        if (Strings.isNullOrEmpty(webAppLocation)) {
-            webApp.setWar(getShadedWarUrl());
-        } else {
-            webApp.setWar(webAppLocation);
-        }
-
-        // Request log handler
-        final RequestLogHandler log = new RequestLogHandler();
-        log.setRequestLog(createRequestLog());
-
-        // Redirect root context handler
-        MovedContextHandler rootRedirect = new MovedContextHandler();
-        rootRedirect.setContextPath("/");
-        rootRedirect.setNewContextURL(contextPath);
-        rootRedirect.setPermanent(true);
-
-        // Put rootRedirect at the end!
-        return new HandlerCollection(log, gzipHandler, rootRedirect);
-    }
-
-    private RequestLog createRequestLog() {
-        final NCSARequestLog log = new NCSARequestLog();
-        final File logPath = new File(accessLogFile);
-        final File parentFile = logPath.getParentFile();
-        if (parentFile != null) {
-            parentFile.mkdirs();
-        }
-        log.setFilename(logPath.getPath());
-        log.setAppend(true);
-        log.setLogTimeZone("GMT");
-        log.setLogLatency(true);
-        return log;
-    }
-
-    private URL getResource(String aResource) {
-        return Thread.currentThread().getContextClassLoader().getResource(aResource);
-    }
-
-    private String getShadedWarUrl() {
-        final String urlStr = getResource(WEB_XML).toString();
-        return urlStr.substring(0, urlStr.length() - 15);
-    }
-
-    ///////////////////////////////////////////
-    /////////////// Setters ///////////////////
-    ///////////////////////////////////////////
-
-    public void setBindInterface(String bindInterface) {
-        this.bindInterface = bindInterface;
-    }
-
-    public void setHttpPort(int httpPort) {
-        this.httpPort = httpPort;
-    }
-
-    public void setHttpsPort(int httpsPort) {
-        this.httpsPort = httpsPort;
-    }
-
-    public void setContextPath(String contextPath) {
-        this.contextPath = contextPath;
-    }
-
-    public void setHttpsEnable(boolean httpsEnable) {
-        this.httpsEnable = httpsEnable;
-    }
-
-    public void setKeystoreFile(String keystoreFile) {
-        this.keystoreFile = keystoreFile;
-    }
-
-    public void setKeystorePassword(String keystorePassword) {
-        this.keystorePassword = keystorePassword;
-    }
-
-    public void setAccessLogFile(String accessLogFile) {
-        this.accessLogFile = accessLogFile;
-    }
-
-    public void setWebAppLocation(String webAppLocation) {
-        this.webAppLocation = webAppLocation;
-    }
-
-    public void setSessionTimeout(int sessionTimeout) {
-        this.sessionTimeout = sessionTimeout;
-    }
-}
diff --git a/cloud-cli/bindir/cloudvoladm b/cloud-cli/bindir/cloudvoladm
deleted file mode 100755
index 16f31bd..0000000
--- a/cloud-cli/bindir/cloudvoladm
+++ /dev/null
@@ -1,607 +0,0 @@
-#!/usr/bin/env python
-
-# 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 sys
-import os
-import subprocess
-import cloudtool
-import urllib2
-from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
-import xml.dom.minidom
-
-NetAppServerIP=None
-NetAppUserName=None
-NetAppPassword=None
-CloudStackSvrIP=None
-CloudStackSvrPort=8096
-
-
-cmds=["createvol","deletevol", "listvol", "createlun", "listlun", "destroylun", "assoclun", "disassoclun", "createpool", "modifypool", "destroypool", "listpools"]
-header = "Volume Manager CLI, the available COMMANDS are:"
-
-
-def cmd_help():
-    print header
-    print
-    print "createpool    add a new pool to the system"
-    print "modifypool    change the allocation algorithm for a pool"
-    print "destroypool   destroy a pool"
-    print "listpools     list all the pools"
-    print "createvol     add volume to a storage server"
-    print "deletevol     delete volume on a storage server"
-    print "listvol       list volume on a storage server"
-    print "createlun     create LUN on a storage server"
-    print "listlun       list LUN on a storage server"
-    print "destroylun    destroy LUN on a storage server"
-    print "assoclun      assoc LUN on a storage server"
-    print "disassoclun   disassoc LUN on a storage server"
-    print
-    print "\"cloudvoladm COMMAND --help\" for more information on a specific command"
-    print
-    print "Global Options:"
-    print "--cloudStackMgtSvrIP the IP address of CloudStack Management Server"
-    print 
-    print "Config file is ~/.cloudvoladmrc, Config options including: "
-    print "cloudStackMgtSvrIP=Cloudstack Management Server Address, which can be overriden by --cloudStackMgtSvrIP. If neither is provided, localhost is used."
-
-usage="Volume Manager CLI: add a new volume to a storage pool"
-addvolParser= OptionParser(usage)
-addvolParser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
-addvolParser.add_option("-u", metavar="username", dest="username", help="username to access the storage server with")
-addvolParser.add_option("-w", metavar="password", dest="password", help="the password to access the storage server with")
-addvolParser.add_option("-p", dest="pool_name", help="the name of the pool to allocate from") 
-addvolParser.add_option("-a", dest="aggregate_name", help="the name of aggregate") 
-addvolParser.add_option("-v", dest="vol_name", help="the name of volume") 
-addvolParser.add_option("-s", dest="size", help="size in GB eg.1") 
-optionalGroup = OptionGroup(addvolParser, "Optional")
-optionalGroup.add_option("-r", dest="percentage", help="Percentage used for snapshot reserve") 
-optionalGroup.add_option("-S", dest="snapshots", help="Snapshot schedule in <weeks> <days> <hours>@<which-hours> <minutes>@<which-minutes> e.g. \"2 4 5@1,4 6@2,5\"") 
-addvolParser.add_option_group(optionalGroup)
-
-usage="Volume Manager CLI: remove a volume from a pool"
-delvolParser= OptionParser(usage)
-delvolParser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
-delvolParser.add_option("-a", dest="aggregate_name", help="The name of aggregate") 
-delvolParser.add_option("-v", dest="vol_name", help="The name of volume") 
-
-usage="Volume Manager CLI: list all volumes known to exist in a pool"
-listvolParser= OptionParser(usage)
-listvolParser.add_option("-p", dest="pool_name", help="The name of the pool to list volumes from") 
-
-usage="Volume Manager CLI: create a LUN on a pool"
-createlunParser = OptionParser(usage)
-createlunParser.add_option("-p", dest="pool_name", help="The name of the pool to add the volume to") 
-createlunParser.add_option("-s", dest="size", help="The size in GB e.g. 100") 
-
-usage="Volume Manager CLI: list LUN on a pool"
-listlunParser = OptionParser(usage)
-listlunParser.add_option("-p", dest="pool_name", help="The pool name") 
-
-usage="Volume Manager CLI: destroy a LUN "
-destroylunParser = OptionParser(usage)
-destroylunParser.add_option("-l", dest="lun_name", help="The LUN name") 
-
-usage="Volume Manager CLI: Add a new pool to the system"
-createPoolParser = OptionParser(usage)
-createPoolParser.add_option("-p", dest="pool_name", help="The pool name") 
-createPoolParser.add_option("-A", dest="algorithm", help="roundrobin or leastfull") 
-
-
-usage="Volume Manager CLI: change the allocation algorithm for a pool"
-modifyPoolParser = OptionParser(usage)
-modifyPoolParser.add_option("-p", dest="pool_name", help="The pool name") 
-modifyPoolParser.add_option("-A", dest="algorithm", help="roundrobin or leastfull") 
-
-usage="Volume Manager CLI: destroy a pool"
-destroyPoolParser = OptionParser(usage)
-destroyPoolParser.add_option("-p", dest="pool_name", help="The pool name") 
-
-usage="Volume Manager CLI: list pools"
-listPoolParser = OptionParser(usage)
-
-usage="Volume Manager CLI: associate a LUN with a guest that uses the stated IQN as client"
-assocLunParser = OptionParser(usage)
-assocLunParser.add_option("-g", dest="guest_iqn", help="the guest IQN. By default, it reads from /etc/iscsi/initiatorname.iscsi") 
-assocLunParser.add_option("-l", dest="lun_name", help="The LUN name") 
-
-usage="Volume Manager CLI: disassociate a LUN with a guest that uses the stated IQN as client"
-disassocLunParser = OptionParser(usage)
-disassocLunParser.add_option("-g", dest="guest_iqn", help="the guest IQN. By default, it reads from /etc/iscsi/initiatorname.iscsi") 
-disassocLunParser.add_option("-l", dest="lun_name", help="The LUN name") 
-
-cmdParsers = {cmds[0]:addvolParser, cmds[1]:delvolParser, cmds[2]:listvolParser,  cmds[3]:createlunParser, cmds[4]:listlunParser, 
-          cmds[5]:destroylunParser, cmds[6]:assocLunParser, cmds[7]:disassocLunParser, cmds[8]:createPoolParser, cmds[9]:modifyPoolParser, cmds[10]:destroyPoolParser, cmds[11]:listPoolParser}
-
-
-def validate_parameter(input, signature):
-    (options, args) =  signature.parse_args([])
-    inputDict = input.__dict__
-    sigDict = options.__dict__
-    for k,v in sigDict.iteritems():
-        inputValue = inputDict[k]
-        if inputValue == None:
-            print "Volume Manager CLI: missing operand "
-            print
-            signature.parse_args(["--help"])
-
-def help_callback(option, opt, value, parser):
-    argv = sys.argv[1:]
-    try:
-        argv.remove(opt)
-    except:
-        argv.remove("--h")
-
-    if len(argv) == 0:
-        cmd_help()
-        return
-    (options, args) = parser.parse_args(argv)
-    for cmd in cmds:
-        if cmd == args[0]:
-            cmdParsers[cmd].parse_args(["--help"])      
-
-def Help():
-    usage = "usage: %prog cmd[createpool|listpools|modifypool|destroypool|createvol|deletevol|listvol|createlun|listlun|destroylun|assoclun|disassoclun] arg1 arg2 [--help, -h]"
-    parser = OptionParser(usage=usage, add_help_option=False)   
-    parser.add_option("-h", "--help", action="callback", callback=help_callback);
-    parser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
-    parser.add_option("--cloudstackSvr", dest="cloudstackSvr", help="cloudStack Server IP") 
-    parser.add_option("-u", metavar="username", dest="username", help="username to access the storage server with")
-    parser.add_option("-w", metavar="password", dest="password", help="the password to access the storage server with")
-    parser.add_option("-p", dest="pool_name", help="the name of the pool to allocate from") 
-    parser.add_option("-v", dest="vol_name", help="the name of volume") 
-    parser.add_option("-A", dest="algorithm", help="roundrobin or leastfull") 
-    parser.add_option("-a", dest="aggregate_name", help="The name of aggregate") 
-    parser.add_option("-o", dest="options", help="requested option string for the NFS export or attach") 
-    parser.add_option("-S", dest="snapshots", help="Snapshot schedule e.g.2 4 5@1,4 6@2,5") 
-    parser.add_option("-r", dest="percentage", help="Percentage used for snapshot reservation") 
-    parser.add_option("-s", dest="size", help="size in GB eg.1") 
-    parser.add_option("-t", dest="target_iqn", help="the target IQN") 
-    parser.add_option("-g", dest="guest_iqn", help="the guest IQN") 
-    parser.add_option("-l", dest="lun_name", help="the LUN name") 
-    
-    return parser
-
-def httpErrorHandler(code, msg):
-    try:
-        errtext = xml.dom.minidom.parseString(msg) 
-        if errtext.getElementsByTagName("errortext") is not None:
-            err = getText(errtext.getElementsByTagName("errortext")[0].childNodes).strip()
-            print err
-    except:
-        print "Internal Error %s"%msg
-    
-def getText(nodelist):
-    rc = []
-    for node in nodelist:
-        if node.nodeType == node.TEXT_NODE: rc.append(node.data)
-    return ''.join(rc)
-
-def createvol(options):
-    args = []
-    if options.pool_name == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-    if options.aggregate_name == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-    if options.vol_name == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-    
-    if options.snapshots != None:
-        args += ['--snapshotpolicy=' + options.snapshots]
-        
-    if options.size == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-        
-    if options.percentage != None:
-        args += ['--snapshotreservation=' + options.percentage]
-
-    if NetAppServerIP == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-
-    if NetAppUserName == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-    
-    if NetAppPassword == None:
-        print "Volume Manager CLI: missing operand "
-        print
-        addvolParser.parse_args(["--help"])
-
-    '''
-    snapshot = options.snapshots
-    tokens = snapshot.split(" ")
-    print tokens
-    pos = 0;
-    for token in tokens:
-        if pos == 0:
-            #week
-            try:
-                week = int(token)           
-                if week < 0:
-                    raise
-            except:
-                print "Pls input correct week"
-                sys.exit(1)
-        elif pos == 1:
-            try:
-                day = int(token)
-                if day < 0:
-                    raise
-            except:
-                print "Pls input correct day"
-                sys.exit(1)
-        
-        elif pos == 2:
-            try:
-                hours = token.split("@")
-                if int(hours[0]) < 0:
-                    raise
-                hourlists = hours[1].split(",")
-                for hour in hourlists:
-                    if int(hour) < 0 or int(hour) > 24:
-                        raise
-            except:
-                print "Pls input correct hour"
-                sys.exit(1)
-        elif pos == 3:
-            try:
-                minutes = token.split("@")
-                if int(minutes[0]) < 0:
-                    raise
-                
-                minuteslist = minutes[1].split(",")
-                for minute in minuteslist:
-                    if int(minute) < 0 or int(minute) > 60:
-                        raise
-            except:
-                print "Pls input correct hour"
-                sys.exit(1)
-                
-    '''
-    
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'createVolumeOnFiler', '--ipaddress=' + NetAppServerIP ,  '--aggregatename=' + options.aggregate_name,
-                            '--poolname=' + options.pool_name, '--volumename=' + options.vol_name,
-                            '--size=' + options.size,                  
-                            '--username=' + NetAppUserName, '--password=' + NetAppPassword, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"] + args)
-        print "Successfully added volume"
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing createvol cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing createvol cmd failed: %s" % (err.reason)
-        sys.exit(1)
-
-
-def deletevol(options):
-    validate_parameter(options, delvolParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'destroyVolumeOnFiler', '--ipaddress=' + NetAppServerIP,  '--aggregatename=' + options.aggregate_name,
-                             '--volumename=' + options.vol_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully deleted volume"
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing deletevol cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing deletevol cmd failed: %s" % (err.reason)
-        sys.exit(1)
-        
-def listvol(options):
-    validate_parameter(options, listvolParser)
-    
-    try:
-        output = cloudtool.main(['cloud-tool', 'listVolumesOnFiler', '--poolname=' + options.pool_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"]).strip("\n")
-
-        xmlResult = xml.dom.minidom.parseString(output) 
-        print "%-10s %-20s %-20s %-40s %-20s %-30s "%('Id', 'Address', 'Aggregate', 'Volume', 'Size(GB)', 'snapshotPolicy', )
-        for volume in xmlResult.getElementsByTagName("volume"):
-            aggregatename = getText(volume.getElementsByTagName('aggregatename')[0].childNodes).strip()
-            id = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
-            volumeName = getText(volume.getElementsByTagName('volumename')[0].childNodes).strip()
-            snapshotPolicy = getText(volume.getElementsByTagName('snapshotpolicy')[0].childNodes).strip()
-            ipaddress = getText(volume.getElementsByTagName('ipaddress')[0].childNodes).strip()
-            volSize = getText(volume.getElementsByTagName('size')[0].childNodes).strip()
-            print "%-10s %-20s %-20s %-40s %-20s %-30s "%(id, ipaddress, aggregatename, volumeName, volSize, snapshotPolicy)
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing listvol cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing listvol cmd failed: %s" % (err.reason)
-        sys.exit(1)
-
-
-def createlun(options):
-    validate_parameter(options, createlunParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'createLunOnFiler', '--name=' + options.pool_name,
-                                              '--size=' + options.size, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-
-        xmlResult = xml.dom.minidom.parseString(output.strip("\n"))
-        path = getText(xmlResult.getElementsByTagName("path")[0].childNodes).strip()
-        iqn = getText(xmlResult.getElementsByTagName("iqn")[0].childNodes).strip()
-        ipAddr = getText(xmlResult.getElementsByTagName('ipaddress')[0].childNodes).strip()
-        print "%-30s %-30s %-50s "%('LUN Name', 'Address', 'Target IQN')
-        print "%-30s %-30s %-50s "%(path, ipAddr, iqn)
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing createlun cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing createlun cmd failed: %s" % (err.reason)
-        sys.exit(1)
-
-def listlun(options):
-    validate_parameter(options, listlunParser)
-
-    args = ["--poolname=" + options.pool_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"]
-    try:
-        output = cloudtool.main(['cloud-tool', 'listLunsOnFiler'] + args).strip("\n")
-        xmlResult = xml.dom.minidom.parseString(output)
-        
-        print "%-10s %-10s %-50s %-30s "%('LUN Id', 'Volume Id', 'Target IQN', 'LUN Name')
-        for volume in xmlResult.getElementsByTagName("lun"):
-            uuid = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
-            path = getText(volume.getElementsByTagName('name')[0].childNodes).strip()
-            targetiqn = getText(volume.getElementsByTagName('iqn')[0].childNodes).strip()
-            volumeId = getText(volume.getElementsByTagName('volumeid')[0].childNodes).strip()
-            print "%-10s %-10s %-50s %-30s "%(uuid, volumeId, targetiqn, path)
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing listlun cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing listlun cmd failed: %s" % (err.reason)
-        sys.exit(1)
-
-def destroylun(options):
-    validate_parameter(options, destroylunParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'destroyLunOnFiler', '--path=' + options.lun_name,
-                                              "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully destroyed LUN"
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing destroylun cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing destroylun failed: %s" % (err.reason)
-        sys.exit(1)
-
-def assoclun(options):
-    validate_parameter(options, assocLunParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'associateLun', '--name=' + options.lun_name,
-                                              '--iqn=' + options.guest_iqn, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        xmlResult = xml.dom.minidom.parseString(output.strip("\n"))
-        lunid = getText(xmlResult.getElementsByTagName("id")[0].childNodes).strip()
-        iqn = getText(xmlResult.getElementsByTagName("targetiqn")[0].childNodes).strip()
-        ipAddr = getText(xmlResult.getElementsByTagName('ipaddress')[0].childNodes).strip()
-        print "%-30s %-30s %-50s "%('LUN Id', 'Address', 'Target IQN')
-        print "%-30s %-30s %-50s" % (lunid, ipAddr, iqn)
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing assoclun cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing assoclun failed: %s" % (err.reason)
-        sys.exit(1)
-        
-def disassoclun(options):
-    validate_parameter(options, disassocLunParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'dissociateLun', '--path=' + options.lun_name,
-                                              '--iqn=' + options.guest_iqn, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully dissociated LUN"
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing disassoclun cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing disassoclun failed: %s" % (err.reason)
-        sys.exit(1)
-
-def createpool(options):
-    validate_parameter(options, createPoolParser)
-
-    if not (options.algorithm == "roundrobin" or options.algorithm == "leastfull"):
-        print "Only roundrobin or leastfull algorithm is supported"
-        sys.exit(1)
-    try:
-        output = cloudtool.main(['cloud-tool', 'createPool', '--name=' + options.pool_name,
-                                              '--algorithm=' + options.algorithm, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully created pool"
-    except urllib2.HTTPError, err:
-        code = err.code
-        print "executing createpool cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, err.read())
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing createpool failed: %s" % (err.reason)
-        sys.exit(1)
-
-def listpools(options):
-    try:
-        output = cloudtool.main(['cloud-tool', 'listPools',
-                                 "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        output = output.strip("\n")
-        xmlResult = xml.dom.minidom.parseString(output) 
-        print "%-10s %-40s %-10s" %('Id', 'Pool Name', 'Algorithm')
-        for volume in xmlResult.getElementsByTagName("pool"):
-            id = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
-            poolname = getText(volume.getElementsByTagName('name')[0].childNodes).strip()
-            alg = getText(volume.getElementsByTagName('algorithm')[0].childNodes).strip()
-            print "%-10s %-40s %-10s"%(id, poolname, alg)
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing listpools cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing listpools failed, due to: %s" % (err.reason)
-        sys.exit(1)
-
-def modifypool(options):
-    validate_parameter(options, modifyPoolParser)
-    
-    try:
-        output = cloudtool.main(['cloud-tool', 'modifyPool', '--poolname=' + options.pool_name,
-                                              '--algorithm=' + options.algorithm, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully modified pool"
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing modifypool cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing modifypool failed, due to: %s" % (err.reason)
-        sys.exit(1)
-
-def destroypool(options):
-    validate_parameter(options, destroyPoolParser)
-
-    try:
-        output = cloudtool.main(['cloud-tool', 'deletePool', '--poolname=' + options.pool_name,
-                                         "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
-        print "Successfully destroyed pool: " + options.pool_name
-    except urllib2.HTTPError, err:
-        code = err.code
-        msg = err.read()
-        print "executing destroypool cmd failed, http returning error code: %s" % (code)
-        httpErrorHandler(code, msg)
-        sys.exit(1)
-    except urllib2.URLError, err:
-        print "executing destroypool failed, due to: %s" % (err.reason)
-        sys.exit(1)
-
-def loadCfgFile():
-    options = dict()
-    try:
-        cfgFile = open(os.environ['HOME'] + "/.cloudvoladmrc")
-        for line in cfgFile:
-            option = line.split("=")
-            if option[0] == "cloudStackMgtSvrIP":
-                options["cloudStackMgtSvrIP"] = option[1].strip("\n")
-
-    except:
-        return None
-
-    return options
-        
-def getGuestIQN():
-    try:
-        initialFile = open("/etc/iscsi/initiatorname.iscsi")    
-        for line in initialFile:
-            iqn = line.split("=")
-            if iqn[0] == "InitiatorName":
-                return iqn[1].strip("\n")
-    except:
-        return None
-    return None
-
-if __name__ == '__main__':
-    parser = Help()
-    (options, args) = parser.parse_args()
-    
-    globalCfg = loadCfgFile()
-
-    NetAppServerIP= options.server_ip
-
-    NetAppUserName = options.username
-    
-    NetAppPassword = options.password
-    
-    CloudStackSvrIP = options.cloudstackSvr
-    if CloudStackSvrIP == None:
-        if globalCfg != None and "cloudStackMgtSvrIP" in globalCfg:
-            CloudStackSvrIP = globalCfg["cloudStackMgtSvrIP"]
-        if CloudStackSvrIP == None:
-            CloudStackSvrIP = "127.0.0.1"
-
-    if options.guest_iqn == None:
-        GuestIQN = getGuestIQN()    
-        options.__dict__["guest_iqn"] = GuestIQN
-
-    if len(args) == 0:
-        sys.exit(1)
-    cmd = args[0]
-    if cmd == "createvol":
-        createvol(options)
-    elif cmd == "deletevol":
-        deletevol(options)
-    elif cmd == "listvol":
-        listvol(options)
-    elif cmd == "createlun":
-        createlun(options)
-    elif cmd == "listlun":
-        listlun(options)
-    elif cmd == "destroylun":
-        destroylun(options)
-    elif cmd == "assoclun":
-        assoclun(options)
-    elif cmd == "disassoclun":
-        disassoclun(options)
-    elif cmd == "createpool":
-        createpool(options)
-    elif cmd == "modifypool":
-        modifypool(options)
-    elif cmd == "destroypool":
-        destroypool(options)
-    elif cmd == "listpools":
-        listpools(options)
-    else:
-        print "Unrecoginzied command"   
-        cmd_help()
-        sys.exit(1)
diff --git a/configure-info.in b/configure-info.in
deleted file mode 100644
index f00cdf0..0000000
--- a/configure-info.in
+++ /dev/null
@@ -1,20 +0,0 @@
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-
-These are the configure-time variables used to compile this CloudStack:
-
-@CONFIGUREVARS@
diff --git a/core/pom.xml b/core/pom.xml
index 7198a04..1b93142 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1,66 +1,59 @@
 <!--
+  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
 
-    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
 
-      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.
-
+  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-core</artifactId>
-  <name>Apache CloudStack Core</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </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-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-security</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-      <dependency>
-          <groupId>org.apache.commons</groupId>
-          <artifactId>commons-compress</artifactId>
-          <version>1.15</version>
-      </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-pmd-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-
+<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-core</artifactId>
+    <name>Apache CloudStack Core</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </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-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-security</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/core/src/com/cloud/agent/api/CheckStateAnswer.java b/core/src/com/cloud/agent/api/CheckStateAnswer.java
deleted file mode 100644
index 5e3a709..0000000
--- a/core/src/com/cloud/agent/api/CheckStateAnswer.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import com.cloud.vm.VirtualMachine.State;
-
-/**
- */
-public class CheckStateAnswer extends Answer {
-    State state;
-
-    public CheckStateAnswer() {
-    }
-
-    public CheckStateAnswer(CheckStateCommand cmd, State state) {
-        this(cmd, state, null);
-    }
-
-    public CheckStateAnswer(CheckStateCommand cmd, String details) {
-        super(cmd, false, details);
-        this.state = null;
-    }
-
-    public CheckStateAnswer(CheckStateCommand cmd, State state, String details) {
-        super(cmd, true, details);
-        this.state = state;
-    }
-
-    public State getState() {
-        return state;
-    }
-}
diff --git a/core/src/com/cloud/agent/api/HostStatsEntry.java b/core/src/com/cloud/agent/api/HostStatsEntry.java
deleted file mode 100644
index 82041a6..0000000
--- a/core/src/com/cloud/agent/api/HostStatsEntry.java
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import com.cloud.host.HostStats;
-
-public class HostStatsEntry implements HostStats {
-
-    long hostId;
-    String entityType;
-    double cpuUtilization;
-    double networkReadKBs;
-    double networkWriteKBs;
-    double totalMemoryKBs;
-    double freeMemoryKBs;
-
-    public HostStatsEntry() {
-    }
-
-    public HostStatsEntry(long hostId, double cpuUtilization, double networkReadKBs, double networkWriteKBs, String entityType, double totalMemoryKBs,
-            double freeMemoryKBs, double xapiMemoryUsageKBs, double averageLoad) {
-        this.hostId = hostId;
-        this.entityType = entityType;
-        this.cpuUtilization = cpuUtilization;
-        this.networkReadKBs = networkReadKBs;
-        this.networkWriteKBs = networkWriteKBs;
-        this.totalMemoryKBs = totalMemoryKBs;
-        this.freeMemoryKBs = freeMemoryKBs;
-    }
-
-    @Override
-    public double getNetworkReadKBs() {
-        return networkReadKBs;
-    }
-
-    public void setNetworkReadKBs(double networkReadKBs) {
-        this.networkReadKBs = networkReadKBs;
-    }
-
-    @Override
-    public double getNetworkWriteKBs() {
-        return networkWriteKBs;
-    }
-
-    public void setNetworkWriteKBs(double networkWriteKBs) {
-        this.networkWriteKBs = networkWriteKBs;
-    }
-
-    @Override
-    public String getEntityType() {
-        return this.entityType;
-    }
-
-    public void setEntityType(String entityType) {
-        this.entityType = entityType;
-    }
-
-    @Override
-    public double getTotalMemoryKBs() {
-        return this.totalMemoryKBs;
-    }
-
-    public void setTotalMemoryKBs(double totalMemoryKBs) {
-        this.totalMemoryKBs = totalMemoryKBs;
-    }
-
-    @Override
-    public double getFreeMemoryKBs() {
-        return this.freeMemoryKBs;
-    }
-
-    public void setFreeMemoryKBs(double freeMemoryKBs) {
-        this.freeMemoryKBs = freeMemoryKBs;
-    }
-
-    @Override
-    public double getCpuUtilization() {
-        return this.cpuUtilization;
-    }
-
-    public void setCpuUtilization(double cpuUtilization) {
-        this.cpuUtilization = cpuUtilization;
-    }
-
-    @Override
-    public double getUsedMemory() {
-        return (totalMemoryKBs - freeMemoryKBs) * 1024;
-    }
-
-    @Override
-    public HostStats getHostStats() {
-        return this;
-    }
-
-    public void setHostId(long hostId) {
-        this.hostId = hostId;
-    }
-}
diff --git a/core/src/com/cloud/agent/api/MigrateCommand.java b/core/src/com/cloud/agent/api/MigrateCommand.java
deleted file mode 100644
index 3e7dfc1..0000000
--- a/core/src/com/cloud/agent/api/MigrateCommand.java
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.cloud.agent.api.to.VirtualMachineTO;
-
-public class MigrateCommand extends Command {
-    private String vmName;
-    private String destIp;
-    private Map<String, MigrateDiskInfo> migrateStorage;
-    private boolean autoConvergence;
-    private String hostGuid;
-    private boolean isWindows;
-    private VirtualMachineTO vmTO;
-    private boolean executeInSequence = false;
-
-    protected MigrateCommand() {
-    }
-
-    public MigrateCommand(String vmName, String destIp, boolean isWindows, VirtualMachineTO vmTO, boolean executeInSequence) {
-        this.vmName = vmName;
-        this.destIp = destIp;
-        this.isWindows = isWindows;
-        this.vmTO = vmTO;
-        this.executeInSequence = executeInSequence;
-    }
-
-    public void setMigrateStorage(Map<String, MigrateDiskInfo> migrateStorage) {
-        this.migrateStorage = migrateStorage;
-    }
-
-    public Map<String, MigrateDiskInfo> getMigrateStorage() {
-        return migrateStorage != null ? new HashMap<>(migrateStorage) : new HashMap<String, MigrateDiskInfo>();
-    }
-
-    public void setAutoConvergence(boolean autoConvergence) {
-        this.autoConvergence = autoConvergence;
-    }
-
-    public boolean isAutoConvergence() {
-        return autoConvergence;
-    }
-
-    public boolean isWindows() {
-        return isWindows;
-    }
-
-    public VirtualMachineTO getVirtualMachine() {
-        return vmTO;
-    }
-
-    public String getDestinationIp() {
-        return destIp;
-    }
-
-    public String getVmName() {
-        return vmName;
-    }
-
-    public void setHostGuid(String guid) {
-        this.hostGuid = guid;
-    }
-
-    public String getHostGuid() {
-        return this.hostGuid;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return executeInSequence;
-    }
-
-    public static class MigrateDiskInfo {
-        public enum DiskType {
-            FILE, BLOCK;
-
-            @Override
-            public String toString() {
-                return name().toLowerCase();
-            }
-        }
-
-        public enum DriverType {
-            QCOW2, RAW;
-
-            @Override
-            public String toString() {
-                return name().toLowerCase();
-            }
-        }
-
-        public enum Source {
-            FILE, DEV;
-
-            @Override
-            public String toString() {
-                return name().toLowerCase();
-            }
-        }
-
-        private final String serialNumber;
-        private final DiskType diskType;
-        private final DriverType driverType;
-        private final Source source;
-        private final String sourceText;
-
-        public MigrateDiskInfo(final String serialNumber, final DiskType diskType, final DriverType driverType, final Source source, final String sourceText) {
-            this.serialNumber = serialNumber;
-            this.diskType = diskType;
-            this.driverType = driverType;
-            this.source = source;
-            this.sourceText = sourceText;
-        }
-
-        public String getSerialNumber() {
-            return serialNumber;
-        }
-
-        public DiskType getDiskType() {
-            return diskType;
-        }
-
-        public DriverType getDriverType() {
-            return driverType;
-        }
-
-        public Source getSource() {
-            return source;
-        }
-
-        public String getSourceText() {
-            return sourceText;
-        }
-    }
-}
diff --git a/core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java b/core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java
deleted file mode 100644
index 47da7f8..0000000
--- a/core/src/com/cloud/agent/api/SecurityGroupRulesCmd.java
+++ /dev/null
@@ -1,278 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.DeflaterOutputStream;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.LogLevel.Log4jLevel;
-import com.cloud.utils.net.NetUtils;
-
-public class SecurityGroupRulesCmd extends Command {
-    private static final String CIDR_LENGTH_SEPARATOR = "/";
-    private static final char RULE_TARGET_SEPARATOR = ',';
-    private static final char RULE_COMMAND_SEPARATOR = ';';
-    protected static final String EGRESS_RULE = "E:";
-    protected static final String INGRESS_RULE = "I:";
-    private static final Logger LOGGER = Logger.getLogger(SecurityGroupRulesCmd.class);
-
-    private final String guestIp;
-    private final String guestIp6;
-    private final String vmName;
-    private final String guestMac;
-    private final String signature;
-    private final Long seqNum;
-    private final Long vmId;
-    private Long msId;
-    private List<IpPortAndProto> ingressRuleSet;
-    private List<IpPortAndProto> egressRuleSet;
-    private final List<String> secIps;
-
-    public static class IpPortAndProto {
-        private final String proto;
-        private final int startPort;
-        private final int endPort;
-        @LogLevel(Log4jLevel.Trace)
-        private List<String> allowedCidrs;
-
-        public IpPortAndProto(final String proto, final int startPort, final int endPort, final String... allowedCidrs) {
-            super();
-            this.proto = proto;
-            this.startPort = startPort;
-            this.endPort = endPort;
-            setAllowedCidrs(allowedCidrs);
-        }
-
-        public List<String> getAllowedCidrs() {
-            return allowedCidrs;
-        }
-
-        public void setAllowedCidrs(final String... allowedCidrs) {
-            this.allowedCidrs = new ArrayList<String>();
-            for (final String allowedCidr : allowedCidrs) {
-                this.allowedCidrs.add(allowedCidr);
-            }
-        }
-
-        public String getProto() {
-            return proto;
-        }
-
-        public int getStartPort() {
-            return startPort;
-        }
-
-        public int getEndPort() {
-            return endPort;
-        }
-
-    }
-
-    public SecurityGroupRulesCmd(
-            final String guestIp,
-            final String guestIp6,
-            final String guestMac,
-            final String vmName,
-            final Long vmId,
-            final String signature,
-            final Long seqNum,
-            final IpPortAndProto[] ingressRuleSet,
-            final IpPortAndProto[] egressRuleSet,
-            final List<String> secIps) {
-        this.guestIp = guestIp;
-        this.guestIp6 = guestIp6;
-        this.vmName = vmName;
-        setIngressRuleSet(ingressRuleSet);
-        this.setEgressRuleSet(egressRuleSet);
-        this.guestMac = guestMac;
-        this.seqNum = seqNum;
-        this.vmId = vmId;
-        if (signature == null) {
-            final String stringified = stringifyRules();
-            this.signature = DigestUtils.md5Hex(stringified);
-        } else {
-            this.signature = signature;
-        }
-        this.secIps = secIps;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return true;
-    }
-
-    public List<IpPortAndProto> getIngressRuleSet() {
-        return ingressRuleSet;
-    }
-
-    public void setIngressRuleSet(final IpPortAndProto... ingressRuleSet) {
-        this.ingressRuleSet = new ArrayList<IpPortAndProto>();
-        for(final IpPortAndProto rule: ingressRuleSet) {
-            this.ingressRuleSet.add(rule);
-        }
-    }
-
-    public List<IpPortAndProto> getEgressRuleSet() {
-        return egressRuleSet;
-    }
-
-    public void setEgressRuleSet(final IpPortAndProto... egressRuleSet) {
-        this.egressRuleSet = new ArrayList<IpPortAndProto>();
-        for(final IpPortAndProto rule: egressRuleSet) {
-            this.egressRuleSet.add(rule);
-        }
-    }
-
-    public String getGuestIp() {
-        return guestIp;
-    }
-
-    public String getGuestIp6() {
-        return guestIp6;
-    }
-
-    public List<String> getSecIps() {
-        return secIps;
-    }
-
-    public String getVmName() {
-        return vmName;
-    }
-
-    private String compressCidrToHexRepresentation(final String cidr) {
-        final String[] toks = cidr.split(CIDR_LENGTH_SEPARATOR);
-        final long ipnum = NetUtils.ip2Long(toks[0]);
-        return Long.toHexString(ipnum) + CIDR_LENGTH_SEPARATOR + toks[1];
-    }
-
-    public String getSecIpsString() {
-        final StringBuilder sb = new StringBuilder();
-        final List<String> ips = getSecIps();
-        if (ips == null) {
-            sb.append("0:");
-        } else {
-            for (final String ip : ips) {
-                sb.append(ip).append(RULE_COMMAND_SEPARATOR);
-            }
-        }
-        return sb.toString();
-    }
-
-    public String stringifyRules() {
-        final StringBuilder ruleBuilder = new StringBuilder();
-        stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, false, ruleBuilder);
-        stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, false, ruleBuilder);
-        return ruleBuilder.toString();
-    }
-
-    public String stringifyCompressedRules() {
-        final StringBuilder ruleBuilder = new StringBuilder();
-        stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, true, ruleBuilder);
-        stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, true, ruleBuilder);
-        return ruleBuilder.toString();
-    }
-
-    private void stringifyRulesFor(final List<IpPortAndProto> ipPortAndProtocols, final String inOrEgress, final boolean compressed, final StringBuilder ruleBuilder) {
-        for (final IpPortAndProto ipPandP : ipPortAndProtocols) {
-            ruleBuilder.append(inOrEgress).append(ipPandP.getProto()).append(RULE_COMMAND_SEPARATOR).append(ipPandP.getStartPort()).append(RULE_COMMAND_SEPARATOR)
-                    .append(ipPandP.getEndPort()).append(RULE_COMMAND_SEPARATOR);
-            for (final String cidr : ipPandP.getAllowedCidrs()) {
-                ruleBuilder.append(represent(cidr, compressed)).append(RULE_TARGET_SEPARATOR);
-            }
-            ruleBuilder.append("NEXT ");
-        }
-    }
-
-    private String represent(final String cidr, final boolean compressed) {
-        if (compressed) {
-            return compressCidrToHexRepresentation(cidr);
-        } else {
-            return cidr;
-        }
-    }
-
-    /**
-     * Compress the security group rules using zlib compression to allow the call to the hypervisor
-     * to scale beyond 8k cidrs.
-     * Note : not using {@see GZipOutputStream} since that is for files, using {@see DeflaterOutputStream} instead.
-     * {@see GZipOutputStream} gives a different header, although the compression is the same
-     */
-    public String compressStringifiedRules() {
-        final String stringified = stringifyRules();
-        final ByteArrayOutputStream out = new ByteArrayOutputStream();
-        String encodedResult = null;
-        try {
-            final DeflaterOutputStream dzip = new DeflaterOutputStream(out);
-            dzip.write(stringified.getBytes());
-            dzip.close();
-            encodedResult = Base64.encodeBase64String(out.toByteArray());
-        } catch (final IOException e) {
-            LOGGER.warn("Exception while compressing security group rules");
-        }
-        return encodedResult;
-    }
-
-    public String getSignature() {
-        return signature;
-    }
-
-    public String getGuestMac() {
-        return guestMac;
-    }
-
-    public Long getSeqNum() {
-        return seqNum;
-    }
-
-    public Long getVmId() {
-        return vmId;
-    }
-
-    /**
-     * used for logging
-     * @return the number of Cidrs in the in and egress rule sets for this security group rules command.
-     */
-    public int getTotalNumCidrs() {
-        int count = 0;
-        for (final IpPortAndProto i : ingressRuleSet) {
-            count += i.allowedCidrs.size();
-        }
-        for (final IpPortAndProto i : egressRuleSet) {
-            count += i.allowedCidrs.size();
-        }
-        return count;
-    }
-
-    public void setMsId(final long msId) {
-        this.msId = msId;
-    }
-
-    public Long getMsId() {
-        return msId;
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/StartupVMMAgentCommand.java b/core/src/com/cloud/agent/api/StartupVMMAgentCommand.java
deleted file mode 100644
index 7c9ad1a..0000000
--- a/core/src/com/cloud/agent/api/StartupVMMAgentCommand.java
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import com.cloud.host.Host;
-
-/**
- * Implementation of bootstrap command sent from management server to agent running on
- * System Center Virtual Machine Manager host
- **/
-
-public class StartupVMMAgentCommand extends Command {
-    Host.Type type;
-    long dataCenter;
-    Long pod;
-    String clusterName;
-    String guid;
-    String managementServerIP;
-    String port;
-    String version;
-
-    public StartupVMMAgentCommand() {
-
-    }
-
-    public StartupVMMAgentCommand(long dataCenter, Long pod, String clusterName, String guid, String managementServerIP, String port, String version) {
-        super();
-        this.dataCenter = dataCenter;
-        this.pod = pod;
-        this.clusterName = clusterName;
-        this.guid = guid;
-        this.type = Host.Type.Routing;
-        this.managementServerIP = managementServerIP;
-        this.port = port;
-    }
-
-    public long getDataCenter() {
-        return dataCenter;
-    }
-
-    public Long getPod() {
-        return pod;
-    }
-
-    public String getClusterName() {
-        return clusterName;
-    }
-
-    public String getGuid() {
-        return guid;
-    }
-
-    public String getManagementServerIP() {
-        return managementServerIP;
-    }
-
-    public String getport() {
-        return port;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/api/UnregisterVMCommand.java b/core/src/com/cloud/agent/api/UnregisterVMCommand.java
deleted file mode 100644
index 16eb4ba..0000000
--- a/core/src/com/cloud/agent/api/UnregisterVMCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-public class UnregisterVMCommand extends Command {
-    String vmName;
-    boolean cleanupVmFiles = false;
-
-    public UnregisterVMCommand(String vmName) {
-        this.vmName = vmName;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-
-    public String getVmName() {
-        return vmName;
-    }
-
-    public void setCleanupVmFiles(boolean cleanupVmFiles) {
-        this.cleanupVmFiles = cleanupVmFiles;
-    }
-
-    public boolean getCleanupVmFiles() {
-        return this.cleanupVmFiles;
-    }
-}
diff --git a/core/src/com/cloud/agent/api/VmStatsEntry.java b/core/src/com/cloud/agent/api/VmStatsEntry.java
deleted file mode 100644
index e6063b9..0000000
--- a/core/src/com/cloud/agent/api/VmStatsEntry.java
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api;
-
-import com.cloud.vm.VmStats;
-
-public class VmStatsEntry implements VmStats {
-
-    double cpuUtilization;
-    double networkReadKBs;
-    double networkWriteKBs;
-    double diskReadIOs;
-    double diskWriteIOs;
-    double diskReadKBs;
-    double diskWriteKBs;
-    double memoryKBs;
-    double intfreememoryKBs;
-    double targetmemoryKBs;
-    int numCPUs;
-    String entityType;
-
-    public VmStatsEntry() {
-    }
-
-    public VmStatsEntry(double memoryKBs,double intfreememoryKBs,double targetmemoryKBs, double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) {
-        this.memoryKBs = memoryKBs;
-        this.intfreememoryKBs = intfreememoryKBs;
-        this.targetmemoryKBs = targetmemoryKBs;
-        this.cpuUtilization = cpuUtilization;
-        this.networkReadKBs = networkReadKBs;
-        this.networkWriteKBs = networkWriteKBs;
-        this.numCPUs = numCPUs;
-        this.entityType = entityType;
-    }
-
-    public VmStatsEntry(double cpuUtilization, double networkReadKBs, double networkWriteKBs, double diskReadKBs, double diskWriteKBs, int numCPUs, String entityType) {
-        this.cpuUtilization = cpuUtilization;
-        this.networkReadKBs = networkReadKBs;
-        this.networkWriteKBs = networkWriteKBs;
-        this.diskReadKBs = diskReadKBs;
-        this.diskWriteKBs = diskWriteKBs;
-        this.numCPUs = numCPUs;
-        this.entityType = entityType;
-    }
-
-    @Override
-    public double getCPUUtilization() {
-        return cpuUtilization;
-    }
-
-    public void setCPUUtilization(double cpuUtilization) {
-        this.cpuUtilization = cpuUtilization;
-    }
-
-    @Override
-    public double getNetworkReadKBs() {
-        return networkReadKBs;
-    }
-
-    public void setNetworkReadKBs(double networkReadKBs) {
-        this.networkReadKBs = networkReadKBs;
-    }
-
-    @Override
-    public double getNetworkWriteKBs() {
-        return networkWriteKBs;
-    }
-
-    public void setNetworkWriteKBs(double networkWriteKBs) {
-        this.networkWriteKBs = networkWriteKBs;
-    }
-
-    @Override
-    public double getDiskReadIOs() {
-        return diskReadIOs;
-    }
-
-    public void setDiskReadIOs(double diskReadIOs) {
-        this.diskReadIOs = diskReadIOs;
-    }
-
-    @Override
-    public double getDiskWriteIOs() {
-        return diskWriteIOs;
-    }
-
-    public void setDiskWriteIOs(double diskWriteIOs) {
-        this.diskWriteIOs = diskWriteIOs;
-    }
-
-    @Override
-    public double getDiskReadKBs() {
-        return diskReadKBs;
-    }
-
-    public void setDiskReadKBs(double diskReadKBs) {
-        this.diskReadKBs = diskReadKBs;
-    }
-
-    @Override
-    public double getDiskWriteKBs() {
-        return diskWriteKBs;
-    }
-
-    public void setDiskWriteKBs(double diskWriteKBs) {
-        this.diskWriteKBs = diskWriteKBs;
-    }
-
-    @Override
-    public double getMemoryKBs() {
-        return memoryKBs;
-    }
-
-    public void setMemoryKBs(double memoryKBs) {
-        this.memoryKBs = memoryKBs;
-    }
-
-    @Override
-    public double getIntFreeMemoryKBs() {
-        return intfreememoryKBs;
-    }
-
-    public void setIntFreeMemoryKBs(double intfreememoryKBs) {
-        this.intfreememoryKBs = intfreememoryKBs;
-    }
-
-    @Override
-    public double getTargetMemoryKBs() {
-        return targetmemoryKBs;
-    }
-
-    public void setTargetMemoryKBs(double targetmemoryKBs) {
-        this.targetmemoryKBs = targetmemoryKBs;
-    }
-
-    public int getNumCPUs() {
-        return numCPUs;
-    }
-
-    public void setNumCPUs(int numCPUs) {
-        this.numCPUs = numCPUs;
-    }
-
-    public String getEntityType() {
-        return this.entityType;
-    }
-
-    public void setEntityType(String entityType) {
-        this.entityType = entityType;
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java
deleted file mode 100644
index c04bb17..0000000
--- a/core/src/com/cloud/agent/api/routing/UserDataCommand.java
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.routing;
-
-public class UserDataCommand extends NetworkElementCommand {
-
-    String userData;
-    String vmIpAddress;
-    String routerPrivateIpAddress;
-    String vmName;
-    boolean executeInSequence = false;
-
-    protected UserDataCommand() {
-
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return executeInSequence;
-    }
-
-    public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName, boolean executeInSequence) {
-        this.userData = userData;
-        this.vmIpAddress = vmIpAddress;
-        this.routerPrivateIpAddress = routerPrivateIpAddress;
-        this.vmName = vmName;
-        this.executeInSequence = executeInSequence;
-    }
-
-    public String getRouterPrivateIpAddress() {
-        return routerPrivateIpAddress;
-    }
-
-    public String getVmIpAddress() {
-        return vmIpAddress;
-    }
-
-    public String getVmName() {
-        return vmName;
-    }
-
-    public String getUserData() {
-        return userData;
-    }
-
-    public void setUserData(String userData) {
-        this.userData = userData;
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java b/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java
deleted file mode 100644
index b636dab..0000000
--- a/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateCommand.java
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-public class CreatePrivateTemplateCommand extends StorageCommand {
-    private String _snapshotFolder;
-    private String _snapshotPath;
-    private String _userFolder;
-    private String _userSpecifiedName;
-    private String _uniqueName;
-    private long _templateId;
-    private long _accountId;
-
-    // For XenServer
-    private String _secondaryStorageURL;
-    private String _snapshotName;
-
-    public CreatePrivateTemplateCommand() {
-    }
-
-    public CreatePrivateTemplateCommand(String secondaryStorageURL, long templateId, long accountId, String userSpecifiedName, String uniqueName, String snapshotFolder,
-            String snapshotPath, String snapshotName, String userFolder) {
-        _secondaryStorageURL = secondaryStorageURL;
-        _templateId = templateId;
-        _accountId = accountId;
-        _userSpecifiedName = userSpecifiedName;
-        _uniqueName = uniqueName;
-        _snapshotFolder = snapshotFolder;
-        _snapshotPath = snapshotPath;
-        _snapshotName = snapshotName;
-        _userFolder = userFolder;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-
-    public String getSecondaryStorageURL() {
-        return _secondaryStorageURL;
-    }
-
-    public String getTemplateName() {
-        return _userSpecifiedName;
-    }
-
-    public String getUniqueName() {
-        return _uniqueName;
-    }
-
-    public String getSnapshotFolder() {
-        return _snapshotFolder;
-    }
-
-    public String getSnapshotPath() {
-        return _snapshotPath;
-    }
-
-    public String getSnapshotName() {
-        return _snapshotName;
-    }
-
-    public String getUserFolder() {
-        return _userFolder;
-    }
-
-    public long getTemplateId() {
-        return _templateId;
-    }
-
-    public long getAccountId() {
-        return _accountId;
-    }
-
-    public void setTemplateId(long templateId) {
-        _templateId = templateId;
-    }
-}
diff --git a/core/src/com/cloud/agent/api/storage/DestroyAnswer.java b/core/src/com/cloud/agent/api/storage/DestroyAnswer.java
deleted file mode 100644
index 4af320a..0000000
--- a/core/src/com/cloud/agent/api/storage/DestroyAnswer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-import com.cloud.agent.api.Answer;
-
-public class DestroyAnswer extends Answer {
-    public DestroyAnswer(DestroyCommand cmd, boolean result, String details) {
-        super(cmd, result, details);
-    }
-
-    // Constructor for gson.
-    protected DestroyAnswer() {
-        super();
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java
deleted file mode 100644
index c1a71d2..0000000
--- a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-
-public class ManageVolumeAvailabilityAnswer extends Answer {
-
-    protected ManageVolumeAvailabilityAnswer() {
-        super();
-    }
-
-    public ManageVolumeAvailabilityAnswer(Command command, boolean success, String details) {
-        super(command, success, details);
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java
deleted file mode 100644
index 0cd402c..0000000
--- a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityCommand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-import com.cloud.agent.api.Command;
-
-public class ManageVolumeAvailabilityCommand extends Command {
-
-    boolean attach;
-    String primaryStorageSRUuid;
-    String volumeUuid;
-
-    public ManageVolumeAvailabilityCommand() {
-    }
-
-    public ManageVolumeAvailabilityCommand(boolean attach, String primaryStorageSRUuid, String volumeUuid) {
-        this.attach = attach;
-        this.primaryStorageSRUuid = primaryStorageSRUuid;
-        this.volumeUuid = volumeUuid;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-
-    public boolean getAttach() {
-        return attach;
-    }
-
-    public String getPrimaryStorageSRUuid() {
-        return primaryStorageSRUuid;
-    }
-
-    public String getVolumeUuid() {
-        return volumeUuid;
-    }
-
-}
diff --git a/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java b/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
deleted file mode 100644
index 77430c3..0000000
--- a/core/src/com/cloud/agent/api/storage/MigrateVolumeCommand.java
+++ /dev/null
@@ -1,111 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-import java.util.Map;
-
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-
-public class MigrateVolumeCommand extends Command {
-    long volumeId;
-    String volumePath;
-    StorageFilerTO pool;
-    String attachedVmName;
-    Volume.Type volumeType;
-
-    private DataTO srcData;
-    private DataTO destData;
-    private Map<String, String> srcDetails;
-    private Map<String, String> destDetails;
-
-    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, int timeout) {
-        this.volumeId = volumeId;
-        this.volumePath = volumePath;
-        this.pool = new StorageFilerTO(pool);
-        this.setWait(timeout);
-    }
-
-    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName, Volume.Type volumeType, int timeout) {
-        this.volumeId = volumeId;
-        this.volumePath = volumePath;
-        this.pool = new StorageFilerTO(pool);
-        this.attachedVmName = attachedVmName;
-        this.volumeType = volumeType;
-        this.setWait(timeout);
-    }
-
-    public MigrateVolumeCommand(DataTO srcData, DataTO destData, Map<String, String> srcDetails, Map<String, String> destDetails, int timeout) {
-        this.srcData = srcData;
-        this.destData = destData;
-        this.srcDetails = srcDetails;
-        this.destDetails = destDetails;
-
-        setWait(timeout);
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return true;
-    }
-
-    public String getVolumePath() {
-        return volumePath;
-    }
-
-    public long getVolumeId() {
-        return volumeId;
-    }
-
-    public StorageFilerTO getPool() {
-        return pool;
-    }
-
-    public String getAttachedVmName() {
-        return attachedVmName;
-    }
-
-    public Volume.Type getVolumeType() {
-        return volumeType;
-    }
-
-    public DataTO getSrcData() {
-        return srcData;
-    }
-
-    public DataTO getDestData() {
-        return destData;
-    }
-
-    public Map<String, String> getSrcDetails() {
-        return srcDetails;
-    }
-
-    public Map<String, String> getDestDetails() {
-        return destDetails;
-    }
-
-    public int getWaitInMillSeconds() {
-        return getWait() * 1000;
-    }
-}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java b/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java
deleted file mode 100644
index d57625b..0000000
--- a/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-
-public class UpgradeDiskAnswer extends Answer {
-
-    public UpgradeDiskAnswer() {
-        super();
-    }
-
-    public UpgradeDiskAnswer(Command cmd, boolean success, String details) {
-        super(cmd, success, details);
-    }
-}
diff --git a/core/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java b/core/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java
deleted file mode 100644
index 49d63be..0000000
--- a/core/src/com/cloud/agent/api/storage/UpgradeDiskCommand.java
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.api.storage;
-
-public class UpgradeDiskCommand extends StorageCommand {
-
-    private String _imagePath;
-    private String _newSize;
-
-    public UpgradeDiskCommand() {
-    }
-
-    public UpgradeDiskCommand(String imagePath, String newSize) {
-        _imagePath = imagePath;
-        _newSize = newSize;
-    }
-
-    public String getImagePath() {
-        return _imagePath;
-    }
-
-    public void setImagePath(String imagePath) {
-        _imagePath = imagePath;
-    }
-
-    public String getNewSize() {
-        return _newSize;
-    }
-
-    public void setNewSize(String newSize) {
-        _newSize = newSize;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return true;
-    }
-}
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java b/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java
deleted file mode 100644
index bd108a9..0000000
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VRScripts.java
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.resource.virtualnetwork;
-
-import org.joda.time.Duration;
-
-public class VRScripts {
-    public final static String CONFIG_PERSIST_LOCATION = "/var/cache/cloud/";
-    public final static String IP_ASSOCIATION_CONFIG = "ip_associations.json";
-    public final static String GUEST_NETWORK_CONFIG = "guest_network.json";
-    public final static String NETWORK_ACL_CONFIG = "network_acl.json";
-    public final static String VM_METADATA_CONFIG = "vm_metadata.json";
-    public final static String VM_DHCP_CONFIG = "vm_dhcp_entry.json";
-    public final static String VM_PASSWORD_CONFIG = "vm_password.json";
-    public static final String FORWARDING_RULES_CONFIG = "forwarding_rules.json";
-    public static final String FIREWALL_RULES_CONFIG = "firewall_rules.json";
-    public static final String VPN_USER_LIST_CONFIG = "vpn_user_list.json";
-    public static final String STATICNAT_RULES_CONFIG = "staticnat_rules.json";
-    public static final String SITE_2_SITE_VPN_CONFIG = "site_2_site_vpn.json";
-    public static final String STATIC_ROUTES_CONFIG = "static_routes.json";
-    public static final String REMOTE_ACCESS_VPN_CONFIG = "remote_access_vpn.json";
-    public static final String MONITOR_SERVICE_CONFIG = "monitor_service.json";
-    public static final String DHCP_CONFIG = "dhcp.json";
-    public static final String IP_ALIAS_CONFIG = "ip_aliases.json";
-    public static final String LOAD_BALANCER_CONFIG = "load_balancer.json";
-
-    public final static String CONFIG_CACHE_LOCATION = "/var/cache/cloud/";
-    public final static Duration VR_SCRIPT_EXEC_TIMEOUT = Duration.standardMinutes(10);
-    public final static Duration CONNECTION_TIMEOUT = Duration.standardMinutes(1);
-
-    // New scripts for use with chef
-    public static final String UPDATE_CONFIG = "update_config.py";
-
-    // Script still in use - mostly by HyperV
-    public static final String S2SVPN_CHECK = "checkbatchs2svpn.sh";
-    public static final String S2SVPN_IPSEC = "ipsectunnel.sh";
-    public static final String DHCP = "edithosts.sh";
-    public static final String DNSMASQ_CONFIG = "dnsmasq.sh";
-    public static final String IPASSOC = "ipassoc.sh";
-    public static final String LB = "loadbalancer.sh";
-    public static final String MONITOR_SERVICE = "monitor_service.sh";
-    public static final String PASSWORD = "savepassword.sh";
-    public static final String ROUTER_ALERTS = "getRouterAlerts.sh";
-    public static final String RVR_CHECK = "checkrouter.sh";
-    public static final String VMDATA = "vmdata.py";
-    public static final String RVR_BUMPUP_PRI = "bumpup_priority.sh";
-    public static final String VERSION = "get_template_version.sh";
-    public static final String VPC_SOURCE_NAT = "vpc_snat.sh";
-    public static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh";
-    public static final String VPN_L2TP = "vpn_l2tp.sh";
-    public static final String UPDATE_HOST_PASSWD = "update_host_passwd.sh";
-
-    public static final String VR_CFG = "vr_cfg.sh";
-}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
deleted file mode 100644
index 8dd0620..0000000
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ /dev/null
@@ -1,459 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.agent.resource.virtualnetwork;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.UUID;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.ca.SetupCertificateAnswer;
-import org.apache.cloudstack.ca.SetupCertificateCommand;
-import org.apache.cloudstack.ca.SetupKeyStoreCommand;
-import org.apache.cloudstack.ca.SetupKeystoreAnswer;
-import org.apache.cloudstack.utils.security.KeyStoreUtils;
-import org.apache.log4j.Logger;
-import org.joda.time.Duration;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckRouterAnswer;
-import com.cloud.agent.api.CheckRouterCommand;
-import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
-import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
-import com.cloud.agent.api.GetDomRVersionAnswer;
-import com.cloud.agent.api.GetDomRVersionCmd;
-import com.cloud.agent.api.GetRouterAlertsAnswer;
-import com.cloud.agent.api.routing.AggregationControlCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand.Action;
-import com.cloud.agent.api.routing.GetRouterAlertsCommand;
-import com.cloud.agent.api.routing.GroupAnswer;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.resource.virtualnetwork.facade.AbstractConfigItemFacade;
-import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * VirtualNetworkResource controls and configures virtual networking
- *
- * @config
- * {@table
- *    || Param Name | Description | Values | Default ||
- *  }
- **/
-public class VirtualRoutingResource {
-
-    private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class);
-    private VirtualRouterDeployer _vrDeployer;
-    private Map<String, Queue<NetworkElementCommand>> _vrAggregateCommandsSet;
-    protected Map<String, Lock> _vrLockMap = new HashMap<String, Lock>();
-
-    private String _name;
-    private int _sleep;
-    private int _retry;
-    private int _port;
-    private Duration _eachTimeout;
-    private Map<String, Object> _params;
-
-    private String _cfgVersion = "1.0";
-
-    public VirtualRoutingResource(VirtualRouterDeployer deployer) {
-        _vrDeployer = deployer;
-    }
-
-    public Answer executeRequest(final NetworkElementCommand cmd) {
-        boolean aggregated = false;
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        Lock lock;
-        if (_vrLockMap.containsKey(routerName)) {
-            lock = _vrLockMap.get(routerName);
-        } else {
-            lock = new ReentrantLock();
-            _vrLockMap.put(routerName, lock);
-        }
-        lock.lock();
-
-        try {
-            ExecutionResult rc = _vrDeployer.prepareCommand(cmd);
-            if (!rc.isSuccess()) {
-                s_logger.error("Failed to prepare VR command due to " + rc.getDetails());
-                return new Answer(cmd, false, rc.getDetails());
-            }
-
-            assert cmd.getRouterAccessIp() != null : "Why there is no access IP for VR?";
-
-            if (cmd.isQuery()) {
-                return executeQueryCommand(cmd);
-            }
-
-            if (cmd instanceof SetupKeyStoreCommand) {
-                return execute((SetupKeyStoreCommand) cmd);
-            }
-
-            if (cmd instanceof SetupCertificateCommand) {
-                return execute((SetupCertificateCommand) cmd);
-            }
-
-            if (cmd instanceof AggregationControlCommand) {
-                return execute((AggregationControlCommand)cmd);
-            }
-
-            if (_vrAggregateCommandsSet.containsKey(routerName)) {
-                _vrAggregateCommandsSet.get(routerName).add(cmd);
-                aggregated = true;
-                // Clean up would be done after command has been executed
-                //TODO: Deal with group answer as well
-                return new Answer(cmd);
-            }
-
-            List<ConfigItem> cfg = generateCommandCfg(cmd);
-            if (cfg == null) {
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
-            return applyConfig(cmd, cfg);
-        } catch (final IllegalArgumentException e) {
-            return new Answer(cmd, false, e.getMessage());
-        } finally {
-            lock.unlock();
-            if (!aggregated) {
-                ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
-                if (!rc.isSuccess()) {
-                    s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
-                }
-            }
-        }
-    }
-
-    private Answer execute(final SetupKeyStoreCommand cmd) {
-        final String args = String.format("/usr/local/cloud/systemvm/conf/agent.properties " +
-                        "/usr/local/cloud/systemvm/conf/%s " +
-                        "%s %d " +
-                        "/usr/local/cloud/systemvm/conf/%s",
-                KeyStoreUtils.KS_FILENAME,
-                cmd.getKeystorePassword(),
-                cmd.getValidityDays(),
-                KeyStoreUtils.CSR_FILENAME);
-        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), KeyStoreUtils.KS_SETUP_SCRIPT, args, Duration.standardMinutes(15));
-        return new SetupKeystoreAnswer(result.getDetails());
-    }
-
-    private Answer execute(final SetupCertificateCommand cmd) {
-        final String args = String.format("/usr/local/cloud/systemvm/conf/agent.properties " +
-                        "/usr/local/cloud/systemvm/conf/%s %s " +
-                        "/usr/local/cloud/systemvm/conf/%s \"%s\" " +
-                        "/usr/local/cloud/systemvm/conf/%s \"%s\" " +
-                        "/usr/local/cloud/systemvm/conf/%s \"%s\"",
-                KeyStoreUtils.KS_FILENAME,
-                KeyStoreUtils.SSH_MODE,
-                KeyStoreUtils.CERT_FILENAME,
-                cmd.getEncodedCertificate(),
-                KeyStoreUtils.CACERT_FILENAME,
-                cmd.getEncodedCaCertificates(),
-                KeyStoreUtils.PKEY_FILENAME,
-                cmd.getEncodedPrivateKey());
-        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), KeyStoreUtils.KS_IMPORT_SCRIPT, args, Duration.standardMinutes(15));
-        return new SetupCertificateAnswer(result.isSuccess());
-    }
-
-    private Answer executeQueryCommand(NetworkElementCommand cmd) {
-        if (cmd instanceof CheckRouterCommand) {
-            return execute((CheckRouterCommand)cmd);
-        } else if (cmd instanceof GetDomRVersionCmd) {
-            return execute((GetDomRVersionCmd)cmd);
-        } else if (cmd instanceof CheckS2SVpnConnectionsCommand) {
-            return execute((CheckS2SVpnConnectionsCommand) cmd);
-        } else if (cmd instanceof GetRouterAlertsCommand) {
-            return execute((GetRouterAlertsCommand)cmd);
-        } else {
-            s_logger.error("Unknown query command in VirtualRoutingResource!");
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c) {
-        return applyConfigToVR(routerAccessIp, c, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
-    }
-
-    private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, Duration timeout) {
-        if (c instanceof FileConfigItem) {
-            FileConfigItem configItem = (FileConfigItem)c;
-            return _vrDeployer.createFileInVR(routerAccessIp, configItem.getFilePath(), configItem.getFileName(), configItem.getFileContents());
-        } else if (c instanceof ScriptConfigItem) {
-            ScriptConfigItem configItem = (ScriptConfigItem)c;
-            return _vrDeployer.executeInVR(routerAccessIp, configItem.getScript(), configItem.getArgs(), timeout);
-        }
-        throw new CloudRuntimeException("Unable to apply unknown configitem of type " + c.getClass().getSimpleName());
-    }
-
-
-    private Answer applyConfig(NetworkElementCommand cmd, List<ConfigItem> cfg) {
-
-
-        if (cfg.isEmpty()) {
-            return new Answer(cmd, true, "Nothing to do");
-        }
-
-        List<ExecutionResult> results = new ArrayList<ExecutionResult>();
-        List<String> details = new ArrayList<String>();
-        boolean finalResult = false;
-        for (ConfigItem configItem : cfg) {
-            long startTimestamp = System.currentTimeMillis();
-            ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), configItem, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
-            if (s_logger.isDebugEnabled()) {
-                long elapsed = System.currentTimeMillis() - startTimestamp;
-                s_logger.debug("Processing " + configItem + " took " + elapsed + "ms");
-            }
-            if (result == null) {
-                result = new ExecutionResult(false, "null execution result");
-            }
-            results.add(result);
-            details.add(configItem.getInfo() + (result.isSuccess() ? " - success: " : " - failed: ") + result.getDetails());
-            finalResult = result.isSuccess();
-        }
-
-        // Not sure why this matters, but log it anyway
-        if (cmd.getAnswersCount() != results.size()) {
-            s_logger.warn("Expected " + cmd.getAnswersCount() + " answers while executing " + cmd.getClass().getSimpleName() + " but received " + results.size());
-        }
-
-
-        if (results.size() == 1) {
-            return new Answer(cmd, finalResult, results.get(0).getDetails());
-        } else {
-            return new GroupAnswer(cmd, finalResult, results.size(), details.toArray(new String[details.size()]));
-        }
-    }
-
-    private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {
-
-        StringBuffer buff = new StringBuffer();
-        for (String ip : cmd.getVpnIps()) {
-            buff.append(ip);
-            buff.append(" ");
-        }
-        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.S2SVPN_CHECK, buff.toString());
-        return new CheckS2SVpnConnectionsAnswer(cmd, result.isSuccess(), result.getDetails());
-    }
-
-    private GetRouterAlertsAnswer execute(GetRouterAlertsCommand cmd) {
-
-        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        String args = cmd.getPreviousAlertTimeStamp();
-
-        ExecutionResult result = _vrDeployer.executeInVR(routerIp, VRScripts.ROUTER_ALERTS, args);
-        String alerts[] = null;
-        String lastAlertTimestamp = null;
-
-        if (result.isSuccess()) {
-            if (!result.getDetails().isEmpty() && !result.getDetails().trim().equals("No Alerts")) {
-                alerts = result.getDetails().trim().split("\\\\n");
-                String[] lastAlert = alerts[alerts.length - 1].split(",");
-                lastAlertTimestamp = lastAlert[0];
-            }
-            return new GetRouterAlertsAnswer(cmd, alerts, lastAlertTimestamp);
-        } else {
-            return new GetRouterAlertsAnswer(cmd, result.getDetails());
-        }
-    }
-
-    private Answer execute(CheckRouterCommand cmd) {
-        final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.RVR_CHECK, null);
-        if (!result.isSuccess()) {
-            return new CheckRouterAnswer(cmd, result.getDetails());
-        }
-        return new CheckRouterAnswer(cmd, result.getDetails(), true);
-    }
-
-    private Answer execute(GetDomRVersionCmd cmd) {
-        final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VERSION, null);
-        if (!result.isSuccess()) {
-            return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed");
-        }
-        String[] lines = result.getDetails().split("&");
-        if (lines.length != 2) {
-            return new GetDomRVersionAnswer(cmd, result.getDetails());
-        }
-        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;
-
-        value = (String)params.get("ssh.retry");
-        _retry = NumbersUtil.parseInt(value, 36);
-
-        value = (String)params.get("ssh.port");
-        _port = NumbersUtil.parseInt(value, 3922);
-
-        value = (String)params.get("router.aggregation.command.each.timeout");
-        _eachTimeout = Duration.standardSeconds(NumbersUtil.parseInt(value, (int)VRScripts.VR_SCRIPT_EXEC_TIMEOUT.getStandardSeconds()));
-        if (s_logger.isDebugEnabled()){
-            s_logger.debug("The router.aggregation.command.each.timeout in seconds is set to " + _eachTimeout.getStandardSeconds());
-        }
-
-        if (_vrDeployer == null) {
-            throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!");
-        }
-
-        _vrAggregateCommandsSet = new HashMap<>();
-        return true;
-    }
-
-    public boolean connect(final String ipAddress) {
-        return connect(ipAddress, _port);
-    }
-
-    public boolean connect(final String ipAddress, final int port) {
-        return connect(ipAddress, port, _sleep);
-    }
-
-    public boolean connect(final String ipAddress, int retry, int sleep) {
-        for (int i = 0; i <= retry; i++) {
-            SocketChannel sch = null;
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Trying to connect to " + ipAddress);
-                }
-                sch = SocketChannel.open();
-                sch.configureBlocking(true);
-
-                final InetSocketAddress addr = new InetSocketAddress(ipAddress, _port);
-                sch.connect(addr);
-                return true;
-            } catch (final IOException e) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Could not connect to " + ipAddress);
-                }
-            } finally {
-                if (sch != null) {
-                    try {
-                        sch.close();
-                    } catch (final IOException e) {
-                    }
-                }
-            }
-            try {
-                Thread.sleep(sleep);
-            } catch (final InterruptedException e) {
-            }
-        }
-
-        s_logger.debug("Unable to logon to " + ipAddress);
-
-        return false;
-    }
-
-    private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
-        /*
-         * [TODO] Still have to migrate LoadBalancerConfigCommand and BumpUpPriorityCommand
-         * [FIXME] Have a look at SetSourceNatConfigItem
-         */
-        s_logger.debug("Transforming " + cmd.getClass().getCanonicalName() + " to ConfigItems");
-
-        final AbstractConfigItemFacade configItemFacade = AbstractConfigItemFacade.getInstance(cmd.getClass());
-
-        return configItemFacade.generateConfig(cmd);
-    }
-
-    private Answer execute(AggregationControlCommand cmd) {
-        Action action = cmd.getAction();
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        assert routerName != null;
-        assert cmd.getRouterAccessIp() != null;
-
-        if (action == Action.Start) {
-            assert (!_vrAggregateCommandsSet.containsKey(routerName));
-
-            Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
-            _vrAggregateCommandsSet.put(routerName, queue);
-            return new Answer(cmd, true, "Command aggregation started");
-        } else if (action == Action.Finish) {
-            Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
-            int answerCounts = 0;
-            try {
-                StringBuilder sb = new StringBuilder();
-                sb.append("#Apache CloudStack Virtual Router Config File\n");
-                sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
-                for (NetworkElementCommand command : queue) {
-                    answerCounts += command.getAnswersCount();
-                    List<ConfigItem> cfg = generateCommandCfg(command);
-                    if (cfg == null) {
-                        s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
-                        continue;
-                    }
-
-                    for (ConfigItem c : cfg) {
-                        sb.append(c.getAggregateCommand());
-                    }
-                }
-
-                // TODO replace with applyConfig with a stop on fail
-                String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
-                FileConfigItem fileConfigItem = new FileConfigItem(VRScripts.CONFIG_CACHE_LOCATION, cfgFileName, sb.toString());
-                ScriptConfigItem scriptConfigItem = new ScriptConfigItem(VRScripts.VR_CFG, "-c " + VRScripts.CONFIG_CACHE_LOCATION + cfgFileName);
-                // 120s is the minimal timeout
-                Duration timeout = _eachTimeout.withDurationAdded(_eachTimeout.getStandardSeconds(), answerCounts);
-                if (s_logger.isDebugEnabled()){
-                    s_logger.debug("Aggregate action timeout in seconds is " + timeout.getStandardSeconds());
-                }
-
-                ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), fileConfigItem, timeout);
-                if (!result.isSuccess()) {
-                    return new Answer(cmd, false, result.getDetails());
-                }
-
-                result = applyConfigToVR(cmd.getRouterAccessIp(), scriptConfigItem, timeout);
-                if (!result.isSuccess()) {
-                    return new Answer(cmd, false, result.getDetails());
-                }
-
-                return new Answer(cmd, true, "Command aggregation finished");
-            } finally {
-                queue.clear();
-                _vrAggregateCommandsSet.remove(routerName);
-            }
-        }
-        return new Answer(cmd, false, "Fail to recongize aggregation action " + action.toString());
-    }
-}
diff --git a/core/src/com/cloud/exception/UsageServerException.java b/core/src/com/cloud/exception/UsageServerException.java
deleted file mode 100644
index be107a6..0000000
--- a/core/src/com/cloud/exception/UsageServerException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.exception;
-
-public class UsageServerException extends CloudException {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -8398313106067116466L;
-
-    public UsageServerException() {
-
-    }
-
-    public UsageServerException(String message) {
-        super(message);
-    }
-
-}
diff --git a/core/src/com/cloud/info/SecStorageVmLoadInfo.java b/core/src/com/cloud/info/SecStorageVmLoadInfo.java
deleted file mode 100644
index e10d5cc..0000000
--- a/core/src/com/cloud/info/SecStorageVmLoadInfo.java
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.info;
-
-public class SecStorageVmLoadInfo {
-
-    private long id;
-    private String name;
-    private int count;
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-    public void setCount(int count) {
-        this.count = count;
-    }
-}
diff --git a/core/src/com/cloud/serializer/SerializerHelper.java b/core/src/com/cloud/serializer/SerializerHelper.java
deleted file mode 100644
index 5ce05ab..0000000
--- a/core/src/com/cloud/serializer/SerializerHelper.java
+++ /dev/null
@@ -1,193 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.serializer;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import com.google.gson.Gson;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Pair;
-
-/**
- * Note: toPairList and appendPairList only support simple POJO objects currently
- */
-public class SerializerHelper {
-    public static final Logger s_logger = Logger.getLogger(SerializerHelper.class.getName());
-    public static final String token = "/";
-
-    public static String toSerializedStringOld(Object result) {
-        if (result != null) {
-            Class<?> clz = result.getClass();
-            Gson gson = GsonHelper.getGson();
-            return clz.getName() + token + gson.toJson(result);
-        }
-        return null;
-    }
-
-    public static Object fromSerializedString(String result) {
-        try {
-            if (result != null && !result.isEmpty()) {
-
-                String[] serializedParts = result.split(token);
-
-                if (serializedParts.length < 2) {
-                    return null;
-                }
-                String clzName = serializedParts[0];
-                String nameField = null;
-                String content = null;
-                if (serializedParts.length == 2) {
-                    content = serializedParts[1];
-                } else {
-                    nameField = serializedParts[1];
-                    int index = result.indexOf(token + nameField + token);
-                    content = result.substring(index + nameField.length() + 2);
-                }
-
-                Class<?> clz;
-                try {
-                    clz = Class.forName(clzName);
-                } catch (ClassNotFoundException e) {
-                    return null;
-                }
-
-                Gson gson = GsonHelper.getGson();
-                Object obj = gson.fromJson(content, clz);
-                return obj;
-            }
-            return null;
-        } catch (RuntimeException e) {
-            s_logger.error("Caught runtime exception when doing GSON deserialization on: " + result);
-            throw e;
-        }
-    }
-
-    public static List<Pair<String, Object>> toPairList(Object o, String name) {
-        List<Pair<String, Object>> l = new ArrayList<Pair<String, Object>>();
-        return appendPairList(l, o, name);
-    }
-
-    public static List<Pair<String, Object>> appendPairList(List<Pair<String, Object>> l, Object o, String name) {
-        if (o != null) {
-            Class<?> clz = o.getClass();
-
-            if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) {
-                l.add(new Pair<String, Object>(name, o.toString()));
-                return l;
-            }
-
-            for (Field f : clz.getDeclaredFields()) {
-                if ((f.getModifiers() & Modifier.STATIC) != 0) {
-                    continue;
-                }
-
-                Param param = f.getAnnotation(Param.class);
-                if (param == null) {
-                    continue;
-                }
-
-                String propName = f.getName();
-                if (!param.propName().isEmpty()) {
-                    propName = param.propName();
-                }
-
-                String paramName = param.name();
-                if (paramName.isEmpty()) {
-                    paramName = propName;
-                }
-
-                Method method = getGetMethod(o, propName);
-                if (method != null) {
-                    try {
-                        Object fieldValue = method.invoke(o);
-                        if (fieldValue != null) {
-                            if (f.getType() == Date.class) {
-                                l.add(new Pair<String, Object>(paramName, DateUtil.getOutputString((Date)fieldValue)));
-                            } else {
-                                l.add(new Pair<String, Object>(paramName, fieldValue.toString()));
-                            }
-                        }
-                        //else
-                        //    l.add(new Pair<String, Object>(paramName, ""));
-                    } catch (IllegalArgumentException e) {
-                        s_logger.error("Illegal argument exception when calling POJO " + o.getClass().getName() + " get method for property: " + propName);
-
-                    } catch (IllegalAccessException e) {
-                        s_logger.error("Illegal access exception when calling POJO " + o.getClass().getName() + " get method for property: " + propName);
-                    } catch (InvocationTargetException e) {
-                        s_logger.error("Invocation target exception when calling POJO " + o.getClass().getName() + " get method for property: " + propName);
-                    }
-                }
-            }
-        }
-        return l;
-    }
-
-    private static Method getGetMethod(Object o, String propName) {
-        Method method = null;
-        String methodName = getGetMethodName("get", propName);
-        try {
-            method = o.getClass().getMethod(methodName);
-        } catch (SecurityException e1) {
-            s_logger.error("Security exception in getting POJO " + o.getClass().getName() + " get method for property: " + propName);
-        } catch (NoSuchMethodException e1) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("POJO " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName +
-                    ", will check is-prefixed method to see if it is boolean property");
-            }
-        }
-
-        if (method != null) {
-            return method;
-        }
-
-        methodName = getGetMethodName("is", propName);
-        try {
-            method = o.getClass().getMethod(methodName);
-        } catch (SecurityException e1) {
-            s_logger.error("Security exception in getting POJO " + o.getClass().getName() + " get method for property: " + propName);
-        } catch (NoSuchMethodException e1) {
-            s_logger.warn("POJO " + o.getClass().getName() + " does not have " + methodName + "() method for property: " + propName);
-        }
-        return method;
-    }
-
-    private static String getGetMethodName(String prefix, String fieldName) {
-        StringBuffer sb = new StringBuffer(prefix);
-
-        if (fieldName.length() >= prefix.length() && fieldName.substring(0, prefix.length()).equals(prefix)) {
-            return fieldName;
-        } else {
-            sb.append(fieldName.substring(0, 1).toUpperCase());
-            sb.append(fieldName.substring(1));
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/core/src/com/cloud/storage/resource/StoragePoolResource.java b/core/src/com/cloud/storage/resource/StoragePoolResource.java
deleted file mode 100644
index a618e00..0000000
--- a/core/src/com/cloud/storage/resource/StoragePoolResource.java
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.storage.resource;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.DestroyCommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
-
-public interface StoragePoolResource {
-    // FIXME: Should have a PrimaryStorageDownloadAnswer
-    PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd);
-
-    // FIXME: Should have an DestroyAnswer
-    Answer execute(DestroyCommand cmd);
-
-    CopyVolumeAnswer execute(CopyVolumeCommand cmd);
-}
diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java
deleted file mode 100644
index d584cdf..0000000
--- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java
+++ /dev/null
@@ -1,376 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.storage.template;
-
-import com.amazonaws.event.ProgressEvent;
-import com.amazonaws.event.ProgressEventType;
-import com.amazonaws.event.ProgressListener;
-import com.amazonaws.services.s3.model.ObjectMetadata;
-import com.amazonaws.services.s3.model.PutObjectRequest;
-import com.amazonaws.services.s3.model.StorageClass;
-import com.amazonaws.services.s3.transfer.Upload;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.utils.net.HTTPUtils;
-import com.cloud.utils.net.Proxy;
-import com.cloud.utils.storage.S3.S3Utils;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.URIException;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-
-import static com.cloud.utils.StringUtils.join;
-import static java.util.Arrays.asList;
-
-/**
- * Download a template file using HTTP(S)
- *
- * This class, once instantiated, has the purpose to download a single Template to an S3 Image Store.
- *
- * Execution of the instance is started when runInContext() is called.
- */
-public class S3TemplateDownloader extends ManagedContextRunnable implements TemplateDownloader {
-    private static final Logger LOGGER = Logger.getLogger(S3TemplateDownloader.class.getName());
-
-    private final String downloadUrl;
-    private final String s3Key;
-    private final String fileExtension;
-    private final HttpClient httpClient;
-    private final GetMethod getMethod;
-    private final DownloadCompleteCallback downloadCompleteCallback;
-    private final S3TO s3TO;
-    private String errorString = "";
-    private TemplateDownloader.Status status = TemplateDownloader.Status.NOT_STARTED;
-    private ResourceType resourceType = ResourceType.TEMPLATE;
-    private long remoteSize;
-    private long downloadTime;
-    private long totalBytes;
-    private long maxTemplateSizeInByte;
-
-    private boolean resume = false;
-
-    public S3TemplateDownloader(S3TO s3TO, String downloadUrl, String installPath, DownloadCompleteCallback downloadCompleteCallback,
-            long maxTemplateSizeInBytes, String username, String password, Proxy proxy, ResourceType resourceType) {
-        this.downloadUrl = downloadUrl;
-        this.s3TO = s3TO;
-        this.resourceType = resourceType;
-        this.maxTemplateSizeInByte = maxTemplateSizeInBytes;
-        this.httpClient = HTTPUtils.getHTTPClient();
-        this.downloadCompleteCallback = downloadCompleteCallback;
-
-        // Create a GET method for the download url.
-        this.getMethod = new GetMethod(downloadUrl);
-
-        // Set the retry handler, default to retry 5 times.
-        this.getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, HTTPUtils.getHttpMethodRetryHandler(5));
-
-        // Follow redirects
-        this.getMethod.setFollowRedirects(true);
-
-        // Set file extension.
-        this.fileExtension = StringUtils.substringAfterLast(StringUtils.substringAfterLast(downloadUrl, "/"), ".");
-
-        // Calculate and set S3 Key.
-        this.s3Key = join(asList(installPath, StringUtils.substringAfterLast(downloadUrl, "/")), S3Utils.SEPARATOR);
-
-        // Set proxy if available.
-        HTTPUtils.setProxy(proxy, this.httpClient);
-
-        // Set credentials if available.
-        HTTPUtils.setCredentials(username, password, this.httpClient);
-    }
-
-    @Override
-    public long download(boolean resume, DownloadCompleteCallback callback) {
-        if (!status.equals(Status.NOT_STARTED)) {
-            // Only start downloading if we haven't started yet.
-            LOGGER.debug("Template download is already started, not starting again. Template: " + downloadUrl);
-
-            return 0;
-        }
-
-        int responseCode;
-        if ((responseCode = HTTPUtils.executeMethod(httpClient, getMethod)) == -1) {
-            errorString = "Exception while executing HttpMethod " + getMethod.getName() + " on URL " + downloadUrl;
-            LOGGER.warn(errorString);
-
-            status = Status.UNRECOVERABLE_ERROR;
-            return 0;
-        }
-
-        if (!HTTPUtils.verifyResponseCode(responseCode)) {
-            errorString = "Response code for GetMethod of " + downloadUrl + " is incorrect, responseCode: " + responseCode;
-            LOGGER.warn(errorString);
-
-            status = Status.UNRECOVERABLE_ERROR;
-            return 0;
-        }
-
-        // Headers
-        Header contentLengthHeader = getMethod.getResponseHeader("Content-Length");
-        Header contentTypeHeader = getMethod.getResponseHeader("Content-Type");
-
-        // Check the contentLengthHeader and transferEncodingHeader.
-        if (contentLengthHeader == null) {
-            errorString = "The ContentLengthHeader of " + downloadUrl + " isn't supplied";
-            LOGGER.warn(errorString);
-
-            status = Status.UNRECOVERABLE_ERROR;
-            return 0;
-        } else {
-            // The ContentLengthHeader is supplied, parse it's value.
-            remoteSize = Long.parseLong(contentLengthHeader.getValue());
-        }
-
-        if (remoteSize > maxTemplateSizeInByte) {
-            errorString = "Remote size is too large for template " + downloadUrl + " remote size is " + remoteSize + " max allowed is " + maxTemplateSizeInByte;
-            LOGGER.warn(errorString);
-
-            status = Status.UNRECOVERABLE_ERROR;
-            return 0;
-        }
-
-        InputStream inputStream;
-
-        try {
-            inputStream = new BufferedInputStream(getMethod.getResponseBodyAsStream());
-        } catch (IOException e) {
-            errorString = "Exception occurred while opening InputStream for template " + downloadUrl;
-            LOGGER.warn(errorString);
-
-            status = Status.UNRECOVERABLE_ERROR;
-            return 0;
-        }
-
-        LOGGER.info("Starting download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " and size " + remoteSize + " bytes");
-
-        // Time the upload starts.
-        final Date start = new Date();
-
-        ObjectMetadata objectMetadata = new ObjectMetadata();
-        objectMetadata.setContentLength(remoteSize);
-
-        if (contentTypeHeader.getValue() != null) {
-            objectMetadata.setContentType(contentTypeHeader.getValue());
-        }
-
-        // Create the PutObjectRequest.
-        PutObjectRequest putObjectRequest = new PutObjectRequest(s3TO.getBucketName(), s3Key, inputStream, objectMetadata);
-
-        // If reduced redundancy is enabled, set it.
-        if (s3TO.getEnableRRS()) {
-            putObjectRequest.withStorageClass(StorageClass.ReducedRedundancy);
-        }
-
-        Upload upload = S3Utils.putObject(s3TO, putObjectRequest);
-
-        upload.addProgressListener(new ProgressListener() {
-            @Override
-            public void progressChanged(ProgressEvent progressEvent) {
-
-                // Record the amount of bytes transferred.
-                totalBytes += progressEvent.getBytesTransferred();
-
-                LOGGER.trace("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + ((new Date().getTime() - start.getTime()) / 1000) + " seconds");
-
-                if (progressEvent.getEventType() == ProgressEventType.TRANSFER_STARTED_EVENT) {
-                    status = Status.IN_PROGRESS;
-                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
-                    status = Status.DOWNLOAD_FINISHED;
-                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_CANCELED_EVENT) {
-                    status = Status.ABORTED;
-                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
-                    status = Status.UNRECOVERABLE_ERROR;
-                }
-            }
-        });
-
-        try {
-            // Wait for the upload to complete.
-            upload.waitForCompletion();
-        } catch (InterruptedException e) {
-            // Interruption while waiting for the upload to complete.
-            LOGGER.warn("Interruption occurred while waiting for upload of " + downloadUrl + " to complete");
-        }
-
-        downloadTime = new Date().getTime() - start.getTime();
-
-        if (status == Status.DOWNLOAD_FINISHED) {
-            LOGGER.info("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + (downloadTime / 1000) + " seconds, completed successfully!");
-        } else {
-            LOGGER.warn("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + (downloadTime / 1000) + " seconds, completed with status " + status.toString());
-        }
-
-        // Close input stream
-        getMethod.releaseConnection();
-
-        // Call the callback!
-        if (callback != null) {
-            callback.downloadComplete(status);
-        }
-
-        return totalBytes;
-    }
-
-    public String getDownloadUrl() {
-        try {
-            return getMethod.getURI().toString();
-        } catch (URIException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public Status getStatus() {
-        return status;
-    }
-
-    @Override
-    public long getDownloadTime() {
-        return downloadTime;
-    }
-
-    @Override
-    public long getDownloadedBytes() {
-        return totalBytes;
-    }
-
-    /**
-     * Returns an InputStream only when the status is DOWNLOAD_FINISHED.
-     *
-     * The caller of this method must close the InputStream to prevent resource leaks!
-     *
-     * @return S3ObjectInputStream of the object.
-     */
-    public InputStream getS3ObjectInputStream() {
-        // Check if the download is finished
-        if (status != Status.DOWNLOAD_FINISHED) {
-            return null;
-        }
-
-        return S3Utils.getObjectStream(s3TO, s3TO.getBucketName(), s3Key);
-    }
-
-    public void cleanupAfterError() {
-        LOGGER.warn("Cleanup after error, trying to remove object: " + s3Key);
-
-        S3Utils.deleteObject(s3TO, s3TO.getBucketName(), s3Key);
-    }
-
-    @Override
-    public boolean stopDownload() {
-        switch (status) {
-            case IN_PROGRESS:
-                if (getMethod != null) {
-                    getMethod.abort();
-                }
-                break;
-            case UNKNOWN:
-            case NOT_STARTED:
-            case RECOVERABLE_ERROR:
-            case UNRECOVERABLE_ERROR:
-            case ABORTED:
-            case DOWNLOAD_FINISHED:
-                // Remove the object if it already has been uploaded.
-                S3Utils.deleteObject(s3TO, s3TO.getBucketName(), s3Key);
-                break;
-            default:
-                break;
-        }
-
-        status = TemplateDownloader.Status.ABORTED;
-        return true;
-    }
-
-    @Override
-    public int getDownloadPercent() {
-        if (remoteSize == 0) {
-            return 0;
-        }
-
-        return (int) (100.0 * totalBytes / remoteSize);
-    }
-
-    @Override
-    protected void runInContext() {
-        // Start the download!
-        download(resume, downloadCompleteCallback);
-    }
-
-    @Override
-    public void setStatus(Status status) {
-        this.status = status;
-    }
-
-    public boolean isResume() {
-        return resume;
-    }
-
-    @Override
-    public String getDownloadError() {
-        return errorString;
-    }
-
-    @Override
-    public String getDownloadLocalPath() {
-        return s3Key;
-    }
-
-    @Override
-    public void setResume(boolean resume) {
-        this.resume = resume;
-    }
-
-    @Override
-    public long getMaxTemplateSizeInBytes() {
-        return maxTemplateSizeInByte;
-    }
-
-    @Override
-    public void setDownloadError(String error) {
-        errorString = error;
-    }
-
-    @Override
-    public boolean isInited() {
-        return true;
-    }
-
-    public ResourceType getResourceType() {
-        return resourceType;
-    }
-
-    public long getTotalBytes() {
-        return totalBytes;
-    }
-
-    public String getFileExtension() {
-        return fileExtension;
-    }
-}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/IAgentControl.java b/core/src/main/java/com/cloud/agent/IAgentControl.java
similarity index 100%
rename from core/src/com/cloud/agent/IAgentControl.java
rename to core/src/main/java/com/cloud/agent/IAgentControl.java
diff --git a/core/src/com/cloud/agent/IAgentControlListener.java b/core/src/main/java/com/cloud/agent/IAgentControlListener.java
similarity index 100%
rename from core/src/com/cloud/agent/IAgentControlListener.java
rename to core/src/main/java/com/cloud/agent/IAgentControlListener.java
diff --git a/core/src/com/cloud/agent/StartupCommandProcessor.java b/core/src/main/java/com/cloud/agent/StartupCommandProcessor.java
similarity index 100%
rename from core/src/com/cloud/agent/StartupCommandProcessor.java
rename to core/src/main/java/com/cloud/agent/StartupCommandProcessor.java
diff --git a/core/src/com/cloud/agent/api/AgentControlAnswer.java b/core/src/main/java/com/cloud/agent/api/AgentControlAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/AgentControlAnswer.java
rename to core/src/main/java/com/cloud/agent/api/AgentControlAnswer.java
diff --git a/core/src/com/cloud/agent/api/AgentControlCommand.java b/core/src/main/java/com/cloud/agent/api/AgentControlCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/AgentControlCommand.java
rename to core/src/main/java/com/cloud/agent/api/AgentControlCommand.java
diff --git a/core/src/com/cloud/agent/api/AttachIsoAnswer.java b/core/src/main/java/com/cloud/agent/api/AttachIsoAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/AttachIsoAnswer.java
rename to core/src/main/java/com/cloud/agent/api/AttachIsoAnswer.java
diff --git a/core/src/com/cloud/agent/api/AttachIsoCommand.java b/core/src/main/java/com/cloud/agent/api/AttachIsoCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/AttachIsoCommand.java
rename to core/src/main/java/com/cloud/agent/api/AttachIsoCommand.java
diff --git a/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java b/core/src/main/java/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java
rename to core/src/main/java/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java
diff --git a/core/src/com/cloud/agent/api/BackupSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/BackupSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/BackupSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/BackupSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/BackupSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/BackupSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/BackupSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/BackupSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/BumpUpPriorityCommand.java b/core/src/main/java/com/cloud/agent/api/BumpUpPriorityCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/BumpUpPriorityCommand.java
rename to core/src/main/java/com/cloud/agent/api/BumpUpPriorityCommand.java
diff --git a/core/src/com/cloud/agent/api/CancelCommand.java b/core/src/main/java/com/cloud/agent/api/CancelCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CancelCommand.java
rename to core/src/main/java/com/cloud/agent/api/CancelCommand.java
diff --git a/core/src/com/cloud/agent/api/ChangeAgentAnswer.java b/core/src/main/java/com/cloud/agent/api/ChangeAgentAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ChangeAgentAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ChangeAgentAnswer.java
diff --git a/core/src/com/cloud/agent/api/ChangeAgentCommand.java b/core/src/main/java/com/cloud/agent/api/ChangeAgentCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ChangeAgentCommand.java
rename to core/src/main/java/com/cloud/agent/api/ChangeAgentCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckHealthAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckHealthAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckHealthAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckHealthAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckHealthCommand.java b/core/src/main/java/com/cloud/agent/api/CheckHealthCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckHealthCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckHealthCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckNetworkAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckNetworkAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckNetworkAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckNetworkAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckNetworkCommand.java b/core/src/main/java/com/cloud/agent/api/CheckNetworkCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckNetworkCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckNetworkCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckOnHostAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckOnHostAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckOnHostAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckOnHostAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckOnHostCommand.java b/core/src/main/java/com/cloud/agent/api/CheckOnHostCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckOnHostCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckOnHostCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckRouterAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckRouterAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckRouterAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckRouterAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckRouterCommand.java b/core/src/main/java/com/cloud/agent/api/CheckRouterCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckRouterCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckRouterCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java b/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckStateCommand.java b/core/src/main/java/com/cloud/agent/api/CheckStateCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckStateCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckStateCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckVMActivityOnStoragePoolCommand.java b/core/src/main/java/com/cloud/agent/api/CheckVMActivityOnStoragePoolCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckVMActivityOnStoragePoolCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckVMActivityOnStoragePoolCommand.java
diff --git a/core/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckVirtualMachineAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckVirtualMachineAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CheckVirtualMachineAnswer.java
diff --git a/core/src/com/cloud/agent/api/CheckVirtualMachineCommand.java b/core/src/main/java/com/cloud/agent/api/CheckVirtualMachineCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CheckVirtualMachineCommand.java
rename to core/src/main/java/com/cloud/agent/api/CheckVirtualMachineCommand.java
diff --git a/core/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java b/core/src/main/java/com/cloud/agent/api/CleanupNetworkRulesCmd.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CleanupNetworkRulesCmd.java
rename to core/src/main/java/com/cloud/agent/api/CleanupNetworkRulesCmd.java
diff --git a/core/src/com/cloud/agent/api/ClusterVMMetaDataSyncAnswer.java b/core/src/main/java/com/cloud/agent/api/ClusterVMMetaDataSyncAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ClusterVMMetaDataSyncAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ClusterVMMetaDataSyncAnswer.java
diff --git a/core/src/com/cloud/agent/api/ClusterVMMetaDataSyncCommand.java b/core/src/main/java/com/cloud/agent/api/ClusterVMMetaDataSyncCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ClusterVMMetaDataSyncCommand.java
rename to core/src/main/java/com/cloud/agent/api/ClusterVMMetaDataSyncCommand.java
diff --git a/core/src/com/cloud/agent/api/ComputeChecksumCommand.java b/core/src/main/java/com/cloud/agent/api/ComputeChecksumCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ComputeChecksumCommand.java
rename to core/src/main/java/com/cloud/agent/api/ComputeChecksumCommand.java
diff --git a/core/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java b/core/src/main/java/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ConsoleAccessAuthenticationAnswer.java
diff --git a/core/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java b/core/src/main/java/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java
rename to core/src/main/java/com/cloud/agent/api/ConsoleAccessAuthenticationCommand.java
diff --git a/core/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java b/core/src/main/java/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java
rename to core/src/main/java/com/cloud/agent/api/ConsoleProxyLoadReportCommand.java
diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java b/core/src/main/java/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
diff --git a/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java b/core/src/main/java/com/cloud/agent/api/CreateStoragePoolCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateStoragePoolCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreateStoragePoolCommand.java
diff --git a/core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/CreateVMSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CreateVMSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/CreateVMSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreateVMSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CreateVolumeFromSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/CreateVolumeFromVMSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/CreateVolumeFromVMSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/CronCommand.java b/core/src/main/java/com/cloud/agent/api/CronCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/CronCommand.java
rename to core/src/main/java/com/cloud/agent/api/CronCommand.java
diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java b/core/src/main/java/com/cloud/agent/api/DeleteSnapshotsDirCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java
rename to core/src/main/java/com/cloud/agent/api/DeleteSnapshotsDirCommand.java
diff --git a/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java b/core/src/main/java/com/cloud/agent/api/DeleteStoragePoolCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java
rename to core/src/main/java/com/cloud/agent/api/DeleteStoragePoolCommand.java
diff --git a/core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/DeleteVMSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/DeleteVMSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/DirectNetworkUsageAnswer.java b/core/src/main/java/com/cloud/agent/api/DirectNetworkUsageAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DirectNetworkUsageAnswer.java
rename to core/src/main/java/com/cloud/agent/api/DirectNetworkUsageAnswer.java
diff --git a/core/src/com/cloud/agent/api/DirectNetworkUsageCommand.java b/core/src/main/java/com/cloud/agent/api/DirectNetworkUsageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/DirectNetworkUsageCommand.java
rename to core/src/main/java/com/cloud/agent/api/DirectNetworkUsageCommand.java
diff --git a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageAnswer.java b/core/src/main/java/com/cloud/agent/api/ExternalNetworkResourceUsageAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ExternalNetworkResourceUsageAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ExternalNetworkResourceUsageAnswer.java
diff --git a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java b/core/src/main/java/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
rename to core/src/main/java/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
diff --git a/core/src/com/cloud/agent/api/FenceAnswer.java b/core/src/main/java/com/cloud/agent/api/FenceAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/FenceAnswer.java
rename to core/src/main/java/com/cloud/agent/api/FenceAnswer.java
diff --git a/core/src/com/cloud/agent/api/FenceCommand.java b/core/src/main/java/com/cloud/agent/api/FenceCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/FenceCommand.java
rename to core/src/main/java/com/cloud/agent/api/FenceCommand.java
diff --git a/core/src/com/cloud/agent/api/GetDomRVersionAnswer.java b/core/src/main/java/com/cloud/agent/api/GetDomRVersionAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetDomRVersionAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetDomRVersionAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetDomRVersionCmd.java b/core/src/main/java/com/cloud/agent/api/GetDomRVersionCmd.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetDomRVersionCmd.java
rename to core/src/main/java/com/cloud/agent/api/GetDomRVersionCmd.java
diff --git a/core/src/com/cloud/agent/api/GetGPUStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetGPUStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetGPUStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetGPUStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetGPUStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetGPUStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetGPUStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetGPUStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetHostStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetHostStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetHostStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetHostStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetHostStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetHostStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetHostStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetHostStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetRouterAlertsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetRouterAlertsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetRouterAlertsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetStorageStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetStorageStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetStorageStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetStorageStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetStorageStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetStorageStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetStorageStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVmConfigAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmConfigAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVmConfigAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVmConfigCommand.java b/core/src/main/java/com/cloud/agent/api/GetVmConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVmConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVmDiskStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVmDiskStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVmDiskStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetVmDiskStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmDiskStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVmDiskStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVmIpAddressCommand.java b/core/src/main/java/com/cloud/agent/api/GetVmIpAddressCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmIpAddressCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVmIpAddressCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVmNetworkStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVmNetworkStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetVmNetworkStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVmNetworkStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVmStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVmStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVmStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVmStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetVmStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVmStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVmStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVncPortAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVncPortAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVncPortAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVncPortAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVncPortCommand.java b/core/src/main/java/com/cloud/agent/api/GetVncPortCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVncPortCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVncPortCommand.java
diff --git a/core/src/com/cloud/agent/api/GetVolumeStatsAnswer.java b/core/src/main/java/com/cloud/agent/api/GetVolumeStatsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVolumeStatsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/GetVolumeStatsAnswer.java
diff --git a/core/src/com/cloud/agent/api/GetVolumeStatsCommand.java b/core/src/main/java/com/cloud/agent/api/GetVolumeStatsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/GetVolumeStatsCommand.java
rename to core/src/main/java/com/cloud/agent/api/GetVolumeStatsCommand.java
diff --git a/core/src/com/cloud/agent/api/HandleConfigDriveIsoCommand.java b/core/src/main/java/com/cloud/agent/api/HandleConfigDriveIsoCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/HandleConfigDriveIsoCommand.java
rename to core/src/main/java/com/cloud/agent/api/HandleConfigDriveIsoCommand.java
diff --git a/core/src/main/java/com/cloud/agent/api/HostStatsEntry.java b/core/src/main/java/com/cloud/agent/api/HostStatsEntry.java
new file mode 100644
index 0000000..5fd1c51
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/HostStatsEntry.java
@@ -0,0 +1,129 @@
+//
+// 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 com.cloud.host.HostStats;
+import com.cloud.host.HostVO;
+
+public class HostStatsEntry implements HostStats {
+
+    long hostId;
+    HostVO hostVo;
+    String entityType;
+    double cpuUtilization;
+    double networkReadKBs;
+    double networkWriteKBs;
+    double totalMemoryKBs;
+    double freeMemoryKBs;
+
+    public HostStatsEntry() {
+    }
+
+    public HostStatsEntry(long hostId, double cpuUtilization, double networkReadKBs, double networkWriteKBs, String entityType, double totalMemoryKBs,
+            double freeMemoryKBs, double xapiMemoryUsageKBs, double averageLoad) {
+        this.hostId = hostId;
+        this.entityType = entityType;
+        this.cpuUtilization = cpuUtilization;
+        this.networkReadKBs = networkReadKBs;
+        this.networkWriteKBs = networkWriteKBs;
+        this.totalMemoryKBs = totalMemoryKBs;
+        this.freeMemoryKBs = freeMemoryKBs;
+    }
+
+    @Override
+    public double getNetworkReadKBs() {
+        return networkReadKBs;
+    }
+
+    public void setNetworkReadKBs(double networkReadKBs) {
+        this.networkReadKBs = networkReadKBs;
+    }
+
+    @Override
+    public double getNetworkWriteKBs() {
+        return networkWriteKBs;
+    }
+
+    public void setNetworkWriteKBs(double networkWriteKBs) {
+        this.networkWriteKBs = networkWriteKBs;
+    }
+
+    @Override
+    public String getEntityType() {
+        return this.entityType;
+    }
+
+    public void setEntityType(String entityType) {
+        this.entityType = entityType;
+    }
+
+    @Override
+    public double getTotalMemoryKBs() {
+        return this.totalMemoryKBs;
+    }
+
+    public void setTotalMemoryKBs(double totalMemoryKBs) {
+        this.totalMemoryKBs = totalMemoryKBs;
+    }
+
+    @Override
+    public double getFreeMemoryKBs() {
+        return this.freeMemoryKBs;
+    }
+
+    public void setFreeMemoryKBs(double freeMemoryKBs) {
+        this.freeMemoryKBs = freeMemoryKBs;
+    }
+
+    @Override
+    public double getCpuUtilization() {
+        return this.cpuUtilization;
+    }
+
+    public void setCpuUtilization(double cpuUtilization) {
+        this.cpuUtilization = cpuUtilization;
+    }
+
+    @Override
+    public double getUsedMemory() {
+        return (totalMemoryKBs - freeMemoryKBs) * 1024;
+    }
+
+    @Override
+    public HostStats getHostStats() {
+        return this;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public HostVO getHostVo() {
+        return hostVo;
+    }
+
+    public void setHostVo(HostVO hostVo) {
+        this.hostVo = hostVo;
+    }
+}
diff --git a/core/src/com/cloud/agent/api/MaintainAnswer.java b/core/src/main/java/com/cloud/agent/api/MaintainAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MaintainAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MaintainAnswer.java
diff --git a/core/src/com/cloud/agent/api/MaintainCommand.java b/core/src/main/java/com/cloud/agent/api/MaintainCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MaintainCommand.java
rename to core/src/main/java/com/cloud/agent/api/MaintainCommand.java
diff --git a/core/src/com/cloud/agent/api/ManageSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/ManageSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ManageSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ManageSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/ManageSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/ManageSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ManageSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/ManageSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/MigrateAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MigrateAnswer.java
diff --git a/core/src/main/java/com/cloud/agent/api/MigrateCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateCommand.java
new file mode 100644
index 0000000..e31287c
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/MigrateCommand.java
@@ -0,0 +1,175 @@
+//
+// 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+
+public class MigrateCommand extends Command {
+    private String vmName;
+    private String destIp;
+    private Map<String, MigrateDiskInfo> migrateStorage;
+    private boolean autoConvergence;
+    private String hostGuid;
+    private boolean isWindows;
+    private VirtualMachineTO vmTO;
+    private boolean executeInSequence = false;
+    private List<MigrateDiskInfo> migrateDiskInfoList = new ArrayList<>();
+
+    protected MigrateCommand() {
+    }
+
+    public MigrateCommand(String vmName, String destIp, boolean isWindows, VirtualMachineTO vmTO, boolean executeInSequence) {
+        this.vmName = vmName;
+        this.destIp = destIp;
+        this.isWindows = isWindows;
+        this.vmTO = vmTO;
+        this.executeInSequence = executeInSequence;
+    }
+
+    public void setMigrateStorage(Map<String, MigrateDiskInfo> migrateStorage) {
+        this.migrateStorage = migrateStorage;
+    }
+
+    public Map<String, MigrateDiskInfo> getMigrateStorage() {
+        return migrateStorage != null ? new HashMap<>(migrateStorage) : new HashMap<String, MigrateDiskInfo>();
+    }
+
+    public void setAutoConvergence(boolean autoConvergence) {
+        this.autoConvergence = autoConvergence;
+    }
+
+    public boolean isAutoConvergence() {
+        return autoConvergence;
+    }
+
+    public boolean isWindows() {
+        return isWindows;
+    }
+
+    public VirtualMachineTO getVirtualMachine() {
+        return vmTO;
+    }
+
+    public String getDestinationIp() {
+        return destIp;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public void setHostGuid(String guid) {
+        this.hostGuid = guid;
+    }
+
+    public String getHostGuid() {
+        return this.hostGuid;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return executeInSequence;
+    }
+
+    public List<MigrateDiskInfo> getMigrateDiskInfoList() {
+        return migrateDiskInfoList;
+    }
+
+    public void setMigrateDiskInfoList(List<MigrateDiskInfo> migrateDiskInfoList) {
+        this.migrateDiskInfoList = migrateDiskInfoList;
+    }
+
+    public static class MigrateDiskInfo {
+        public enum DiskType {
+            FILE, BLOCK;
+
+            @Override
+            public String toString() {
+                return name().toLowerCase();
+            }
+        }
+
+        public enum DriverType {
+            QCOW2, RAW;
+
+            @Override
+            public String toString() {
+                return name().toLowerCase();
+            }
+        }
+
+        public enum Source {
+            FILE, DEV;
+
+            @Override
+            public String toString() {
+                return name().toLowerCase();
+            }
+        }
+
+        private final String serialNumber;
+        private final DiskType diskType;
+        private final DriverType driverType;
+        private final Source source;
+        private final String sourceText;
+        private boolean isSourceDiskOnStorageFileSystem;
+
+        public MigrateDiskInfo(final String serialNumber, final DiskType diskType, final DriverType driverType, final Source source, final String sourceText) {
+            this.serialNumber = serialNumber;
+            this.diskType = diskType;
+            this.driverType = driverType;
+            this.source = source;
+            this.sourceText = sourceText;
+        }
+
+        public String getSerialNumber() {
+            return serialNumber;
+        }
+
+        public DiskType getDiskType() {
+            return diskType;
+        }
+
+        public DriverType getDriverType() {
+            return driverType;
+        }
+
+        public Source getSource() {
+            return source;
+        }
+
+        public String getSourceText() {
+            return sourceText;
+        }
+
+        public boolean isSourceDiskOnStorageFileSystem() {
+            return isSourceDiskOnStorageFileSystem;
+        }
+
+        public void setSourceDiskOnStorageFileSystem(boolean isDiskOnFileSystemStorage) {
+            this.isSourceDiskOnStorageFileSystem = isDiskOnFileSystemStorage;
+        }
+    }
+}
diff --git a/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolAnswer.java
new file mode 100644
index 0000000..bc9ae6f
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolAnswer.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 org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import java.util.List;
+
+public class MigrateVmToPoolAnswer extends Answer {
+
+    List<VolumeObjectTO> volumeTos;
+
+    public MigrateVmToPoolAnswer(MigrateVmToPoolCommand cmd, Exception ex) {
+        super(cmd, ex);
+        volumeTos = null;
+    }
+
+    public MigrateVmToPoolAnswer(MigrateVmToPoolCommand cmd, List<VolumeObjectTO> volumeTos) {
+        super(cmd, true, null);
+        this.volumeTos = volumeTos;
+    }
+
+    public List<VolumeObjectTO> getVolumeTos() {
+        return volumeTos;
+    }
+}
diff --git a/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolCommand.java
new file mode 100644
index 0000000..91a911d
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/MigrateVmToPoolCommand.java
@@ -0,0 +1,70 @@
+//
+// 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 com.cloud.agent.api.to.VolumeTO;
+
+import java.util.Collection;
+
+/**
+ * used to tell the agent to migrate a vm to a different primary storage pool.
+ * It is for now only implemented on Vmware and is supposed to work irrespective of whether the VM is started or not.
+ *
+ */
+public class MigrateVmToPoolCommand extends Command {
+    private Collection<VolumeTO> volumes;
+    private String vmName;
+    private String destinationPool;
+    private boolean executeInSequence = false;
+
+    protected MigrateVmToPoolCommand() {
+    }
+
+    /**
+     *
+     * @param vmName the name of the VM to migrate
+     * @param volumes used to supply feedback on vmware generated names
+     * @param destinationPool the primary storage pool to migrate the VM to
+     * @param executeInSequence
+     */
+    public MigrateVmToPoolCommand(String vmName, Collection<VolumeTO> volumes, String destinationPool, boolean executeInSequence) {
+        this.vmName = vmName;
+        this.volumes = volumes;
+        this.destinationPool = destinationPool;
+        this.executeInSequence = executeInSequence;
+    }
+
+    public Collection<VolumeTO> getVolumes() {
+        return volumes;
+    }
+
+    public String getDestinationPool() {
+        return destinationPool;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return executeInSequence;
+    }
+
+}
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageAnswer.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageCommand.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageCommand.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageCompleteCommand.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageReceiveAnswer.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageReceiveCommand.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageSendAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageSendAnswer.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageSendAnswer.java
diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java b/core/src/main/java/com/cloud/agent/api/MigrateWithStorageSendCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/MigrateWithStorageSendCommand.java
rename to core/src/main/java/com/cloud/agent/api/MigrateWithStorageSendCommand.java
diff --git a/core/src/com/cloud/agent/api/ModifySshKeysCommand.java b/core/src/main/java/com/cloud/agent/api/ModifySshKeysCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifySshKeysCommand.java
rename to core/src/main/java/com/cloud/agent/api/ModifySshKeysCommand.java
diff --git a/core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java
diff --git a/core/src/com/cloud/agent/api/ModifyStoragePoolCommand.java b/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyStoragePoolCommand.java
rename to core/src/main/java/com/cloud/agent/api/ModifyStoragePoolCommand.java
diff --git a/core/src/com/cloud/agent/api/ModifyTargetsAnswer.java b/core/src/main/java/com/cloud/agent/api/ModifyTargetsAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyTargetsAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ModifyTargetsAnswer.java
diff --git a/core/src/com/cloud/agent/api/ModifyTargetsCommand.java b/core/src/main/java/com/cloud/agent/api/ModifyTargetsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyTargetsCommand.java
rename to core/src/main/java/com/cloud/agent/api/ModifyTargetsCommand.java
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java b/core/src/main/java/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/main/java/com/cloud/agent/api/ModifyVmNicConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/ModifyVmNicConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java b/core/src/main/java/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
rename to core/src/main/java/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
diff --git a/core/src/com/cloud/agent/api/NetworkRulesSystemVmCommand.java b/core/src/main/java/com/cloud/agent/api/NetworkRulesSystemVmCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/NetworkRulesSystemVmCommand.java
rename to core/src/main/java/com/cloud/agent/api/NetworkRulesSystemVmCommand.java
diff --git a/core/src/com/cloud/agent/api/NetworkRulesVmSecondaryIpCommand.java b/core/src/main/java/com/cloud/agent/api/NetworkRulesVmSecondaryIpCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/NetworkRulesVmSecondaryIpCommand.java
rename to core/src/main/java/com/cloud/agent/api/NetworkRulesVmSecondaryIpCommand.java
diff --git a/core/src/com/cloud/agent/api/NetworkUsageAnswer.java b/core/src/main/java/com/cloud/agent/api/NetworkUsageAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/NetworkUsageAnswer.java
rename to core/src/main/java/com/cloud/agent/api/NetworkUsageAnswer.java
diff --git a/core/src/com/cloud/agent/api/NetworkUsageCommand.java b/core/src/main/java/com/cloud/agent/api/NetworkUsageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/NetworkUsageCommand.java
rename to core/src/main/java/com/cloud/agent/api/NetworkUsageCommand.java
diff --git a/core/src/com/cloud/agent/api/PerformanceMonitorAnswer.java b/core/src/main/java/com/cloud/agent/api/PerformanceMonitorAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PerformanceMonitorAnswer.java
rename to core/src/main/java/com/cloud/agent/api/PerformanceMonitorAnswer.java
diff --git a/core/src/com/cloud/agent/api/PerformanceMonitorCommand.java b/core/src/main/java/com/cloud/agent/api/PerformanceMonitorCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PerformanceMonitorCommand.java
rename to core/src/main/java/com/cloud/agent/api/PerformanceMonitorCommand.java
diff --git a/core/src/com/cloud/agent/api/PingAnswer.java b/core/src/main/java/com/cloud/agent/api/PingAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingAnswer.java
rename to core/src/main/java/com/cloud/agent/api/PingAnswer.java
diff --git a/core/src/com/cloud/agent/api/PingCommand.java b/core/src/main/java/com/cloud/agent/api/PingCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingCommand.java
diff --git a/core/src/com/cloud/agent/api/PingRoutingCommand.java b/core/src/main/java/com/cloud/agent/api/PingRoutingCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingRoutingCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingRoutingCommand.java
diff --git a/core/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java b/core/src/main/java/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingRoutingWithNwGroupsCommand.java
diff --git a/core/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java b/core/src/main/java/com/cloud/agent/api/PingRoutingWithOvsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingRoutingWithOvsCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingRoutingWithOvsCommand.java
diff --git a/core/src/com/cloud/agent/api/PingStorageCommand.java b/core/src/main/java/com/cloud/agent/api/PingStorageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingStorageCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingStorageCommand.java
diff --git a/core/src/com/cloud/agent/api/PingTestCommand.java b/core/src/main/java/com/cloud/agent/api/PingTestCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PingTestCommand.java
rename to core/src/main/java/com/cloud/agent/api/PingTestCommand.java
diff --git a/core/src/com/cloud/agent/api/PlugNicAnswer.java b/core/src/main/java/com/cloud/agent/api/PlugNicAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PlugNicAnswer.java
rename to core/src/main/java/com/cloud/agent/api/PlugNicAnswer.java
diff --git a/core/src/com/cloud/agent/api/PlugNicCommand.java b/core/src/main/java/com/cloud/agent/api/PlugNicCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PlugNicCommand.java
rename to core/src/main/java/com/cloud/agent/api/PlugNicCommand.java
diff --git a/core/src/com/cloud/agent/api/PrepareForMigrationAnswer.java b/core/src/main/java/com/cloud/agent/api/PrepareForMigrationAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PrepareForMigrationAnswer.java
rename to core/src/main/java/com/cloud/agent/api/PrepareForMigrationAnswer.java
diff --git a/core/src/com/cloud/agent/api/PrepareForMigrationCommand.java b/core/src/main/java/com/cloud/agent/api/PrepareForMigrationCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PrepareForMigrationCommand.java
rename to core/src/main/java/com/cloud/agent/api/PrepareForMigrationCommand.java
diff --git a/core/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java b/core/src/main/java/com/cloud/agent/api/PrepareOCFS2NodesCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PrepareOCFS2NodesCommand.java
rename to core/src/main/java/com/cloud/agent/api/PrepareOCFS2NodesCommand.java
diff --git a/core/src/com/cloud/agent/api/PropagateResourceEventCommand.java b/core/src/main/java/com/cloud/agent/api/PropagateResourceEventCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/PropagateResourceEventCommand.java
rename to core/src/main/java/com/cloud/agent/api/PropagateResourceEventCommand.java
diff --git a/core/src/com/cloud/agent/api/ReadyAnswer.java b/core/src/main/java/com/cloud/agent/api/ReadyAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ReadyAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ReadyAnswer.java
diff --git a/core/src/com/cloud/agent/api/ReadyCommand.java b/core/src/main/java/com/cloud/agent/api/ReadyCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ReadyCommand.java
rename to core/src/main/java/com/cloud/agent/api/ReadyCommand.java
diff --git a/core/src/com/cloud/agent/api/RebootAnswer.java b/core/src/main/java/com/cloud/agent/api/RebootAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RebootAnswer.java
rename to core/src/main/java/com/cloud/agent/api/RebootAnswer.java
diff --git a/core/src/com/cloud/agent/api/RebootCommand.java b/core/src/main/java/com/cloud/agent/api/RebootCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RebootCommand.java
rename to core/src/main/java/com/cloud/agent/api/RebootCommand.java
diff --git a/core/src/com/cloud/agent/api/RebootRouterCommand.java b/core/src/main/java/com/cloud/agent/api/RebootRouterCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RebootRouterCommand.java
rename to core/src/main/java/com/cloud/agent/api/RebootRouterCommand.java
diff --git a/core/src/com/cloud/agent/api/RecurringNetworkUsageAnswer.java b/core/src/main/java/com/cloud/agent/api/RecurringNetworkUsageAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RecurringNetworkUsageAnswer.java
rename to core/src/main/java/com/cloud/agent/api/RecurringNetworkUsageAnswer.java
diff --git a/core/src/com/cloud/agent/api/RecurringNetworkUsageCommand.java b/core/src/main/java/com/cloud/agent/api/RecurringNetworkUsageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RecurringNetworkUsageCommand.java
rename to core/src/main/java/com/cloud/agent/api/RecurringNetworkUsageCommand.java
diff --git a/core/src/com/cloud/agent/api/ReplugNicAnswer.java b/core/src/main/java/com/cloud/agent/api/ReplugNicAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ReplugNicAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ReplugNicAnswer.java
diff --git a/core/src/com/cloud/agent/api/ReplugNicCommand.java b/core/src/main/java/com/cloud/agent/api/ReplugNicCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ReplugNicCommand.java
rename to core/src/main/java/com/cloud/agent/api/ReplugNicCommand.java
diff --git a/core/src/com/cloud/agent/api/RestoreVMSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/RestoreVMSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RestoreVMSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/RestoreVMSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/RestoreVMSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/RestoreVMSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RestoreVMSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/RestoreVMSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/RevertToVMSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/RevertToVMSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/ScaleVmAnswer.java b/core/src/main/java/com/cloud/agent/api/ScaleVmAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ScaleVmAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ScaleVmAnswer.java
diff --git a/core/src/com/cloud/agent/api/ScaleVmCommand.java b/core/src/main/java/com/cloud/agent/api/ScaleVmCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ScaleVmCommand.java
rename to core/src/main/java/com/cloud/agent/api/ScaleVmCommand.java
diff --git a/core/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java b/core/src/main/java/com/cloud/agent/api/ScheduleHostScanTaskCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ScheduleHostScanTaskCommand.java
rename to core/src/main/java/com/cloud/agent/api/ScheduleHostScanTaskCommand.java
diff --git a/core/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java b/core/src/main/java/com/cloud/agent/api/SecStorageFirewallCfgCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SecStorageFirewallCfgCommand.java
rename to core/src/main/java/com/cloud/agent/api/SecStorageFirewallCfgCommand.java
diff --git a/core/src/com/cloud/agent/api/SecStorageSetupAnswer.java b/core/src/main/java/com/cloud/agent/api/SecStorageSetupAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SecStorageSetupAnswer.java
rename to core/src/main/java/com/cloud/agent/api/SecStorageSetupAnswer.java
diff --git a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java b/core/src/main/java/com/cloud/agent/api/SecStorageSetupCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SecStorageSetupCommand.java
rename to core/src/main/java/com/cloud/agent/api/SecStorageSetupCommand.java
diff --git a/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java b/core/src/main/java/com/cloud/agent/api/SecStorageVMSetupCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java
rename to core/src/main/java/com/cloud/agent/api/SecStorageVMSetupCommand.java
diff --git a/core/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java b/core/src/main/java/com/cloud/agent/api/SecurityGroupRuleAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SecurityGroupRuleAnswer.java
rename to core/src/main/java/com/cloud/agent/api/SecurityGroupRuleAnswer.java
diff --git a/core/src/main/java/com/cloud/agent/api/SecurityGroupRulesCmd.java b/core/src/main/java/com/cloud/agent/api/SecurityGroupRulesCmd.java
new file mode 100644
index 0000000..1d3d154
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/SecurityGroupRulesCmd.java
@@ -0,0 +1,278 @@
+//
+// 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.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.DeflaterOutputStream;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.LogLevel.Log4jLevel;
+import com.cloud.utils.net.NetUtils;
+
+public class SecurityGroupRulesCmd extends Command {
+    private static final String CIDR_LENGTH_SEPARATOR = "/";
+    private static final char RULE_TARGET_SEPARATOR = ',';
+    private static final char RULE_COMMAND_SEPARATOR = ';';
+    protected static final String EGRESS_RULE = "E:";
+    protected static final String INGRESS_RULE = "I:";
+    private static final Logger LOGGER = Logger.getLogger(SecurityGroupRulesCmd.class);
+
+    private final String guestIp;
+    private final String guestIp6;
+    private final String vmName;
+    private final String guestMac;
+    private final String signature;
+    private final Long seqNum;
+    private final Long vmId;
+    private Long msId;
+    private List<IpPortAndProto> ingressRuleSet;
+    private List<IpPortAndProto> egressRuleSet;
+    private final List<String> secIps;
+
+    public static class IpPortAndProto {
+        private final String proto;
+        private final int startPort;
+        private final int endPort;
+        @LogLevel(Log4jLevel.Trace)
+        private List<String> allowedCidrs;
+
+        public IpPortAndProto(final String proto, final int startPort, final int endPort, final String... allowedCidrs) {
+            super();
+            this.proto = proto;
+            this.startPort = startPort;
+            this.endPort = endPort;
+            setAllowedCidrs(allowedCidrs);
+        }
+
+        public List<String> getAllowedCidrs() {
+            return allowedCidrs;
+        }
+
+        public void setAllowedCidrs(final String... allowedCidrs) {
+            this.allowedCidrs = new ArrayList<String>();
+            for (final String allowedCidr : allowedCidrs) {
+                this.allowedCidrs.add(allowedCidr);
+            }
+        }
+
+        public String getProto() {
+            return proto;
+        }
+
+        public int getStartPort() {
+            return startPort;
+        }
+
+        public int getEndPort() {
+            return endPort;
+        }
+
+    }
+
+    public SecurityGroupRulesCmd(
+            final String guestIp,
+            final String guestIp6,
+            final String guestMac,
+            final String vmName,
+            final Long vmId,
+            final String signature,
+            final Long seqNum,
+            final IpPortAndProto[] ingressRuleSet,
+            final IpPortAndProto[] egressRuleSet,
+            final List<String> secIps) {
+        this.guestIp = guestIp;
+        this.guestIp6 = guestIp6;
+        this.vmName = vmName;
+        setIngressRuleSet(ingressRuleSet);
+        this.setEgressRuleSet(egressRuleSet);
+        this.guestMac = guestMac;
+        this.seqNum = seqNum;
+        this.vmId = vmId;
+        if (signature == null) {
+            final String stringified = stringifyRules();
+            this.signature = DigestUtils.md5Hex(stringified);
+        } else {
+            this.signature = signature;
+        }
+        this.secIps = secIps;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+
+    public List<IpPortAndProto> getIngressRuleSet() {
+        return ingressRuleSet;
+    }
+
+    public void setIngressRuleSet(final IpPortAndProto... ingressRuleSet) {
+        this.ingressRuleSet = new ArrayList<IpPortAndProto>();
+        for(final IpPortAndProto rule: ingressRuleSet) {
+            this.ingressRuleSet.add(rule);
+        }
+    }
+
+    public List<IpPortAndProto> getEgressRuleSet() {
+        return egressRuleSet;
+    }
+
+    public void setEgressRuleSet(final IpPortAndProto... egressRuleSet) {
+        this.egressRuleSet = new ArrayList<IpPortAndProto>();
+        for(final IpPortAndProto rule: egressRuleSet) {
+            this.egressRuleSet.add(rule);
+        }
+    }
+
+    public String getGuestIp() {
+        return guestIp;
+    }
+
+    public String getGuestIp6() {
+        return guestIp6;
+    }
+
+    public List<String> getSecIps() {
+        return secIps;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    private String compressCidrToHexRepresentation(final String cidr) {
+        final String[] toks = cidr.split(CIDR_LENGTH_SEPARATOR);
+        final long ipnum = NetUtils.ip2Long(toks[0]);
+        return Long.toHexString(ipnum) + CIDR_LENGTH_SEPARATOR + toks[1];
+    }
+
+    public String getSecIpsString() {
+        final StringBuilder sb = new StringBuilder();
+        final List<String> ips = getSecIps();
+        if (ips == null) {
+            sb.append("0").append(RULE_COMMAND_SEPARATOR);
+        } else {
+            for (final String ip : ips) {
+                sb.append(ip).append(RULE_COMMAND_SEPARATOR);
+            }
+        }
+        return sb.toString();
+    }
+
+    public String stringifyRules() {
+        final StringBuilder ruleBuilder = new StringBuilder();
+        stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, false, ruleBuilder);
+        stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, false, ruleBuilder);
+        return ruleBuilder.toString();
+    }
+
+    public String stringifyCompressedRules() {
+        final StringBuilder ruleBuilder = new StringBuilder();
+        stringifyRulesFor(getIngressRuleSet(), INGRESS_RULE, true, ruleBuilder);
+        stringifyRulesFor(getEgressRuleSet(), EGRESS_RULE, true, ruleBuilder);
+        return ruleBuilder.toString();
+    }
+
+    private void stringifyRulesFor(final List<IpPortAndProto> ipPortAndProtocols, final String inOrEgress, final boolean compressed, final StringBuilder ruleBuilder) {
+        for (final IpPortAndProto ipPandP : ipPortAndProtocols) {
+            ruleBuilder.append(inOrEgress).append(ipPandP.getProto()).append(RULE_COMMAND_SEPARATOR).append(ipPandP.getStartPort()).append(RULE_COMMAND_SEPARATOR)
+                    .append(ipPandP.getEndPort()).append(RULE_COMMAND_SEPARATOR);
+            for (final String cidr : ipPandP.getAllowedCidrs()) {
+                ruleBuilder.append(represent(cidr, compressed)).append(RULE_TARGET_SEPARATOR);
+            }
+            ruleBuilder.append("NEXT ");
+        }
+    }
+
+    private String represent(final String cidr, final boolean compressed) {
+        if (compressed) {
+            return compressCidrToHexRepresentation(cidr);
+        } else {
+            return cidr;
+        }
+    }
+
+    /**
+     * Compress the security group rules using zlib compression to allow the call to the hypervisor
+     * to scale beyond 8k cidrs.
+     * Note : not using {@see GZipOutputStream} since that is for files, using {@see DeflaterOutputStream} instead.
+     * {@see GZipOutputStream} gives a different header, although the compression is the same
+     */
+    public String compressStringifiedRules() {
+        final String stringified = stringifyRules();
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        String encodedResult = null;
+        try {
+            final DeflaterOutputStream dzip = new DeflaterOutputStream(out);
+            dzip.write(stringified.getBytes());
+            dzip.close();
+            encodedResult = Base64.encodeBase64String(out.toByteArray());
+        } catch (final IOException e) {
+            LOGGER.warn("Exception while compressing security group rules");
+        }
+        return encodedResult;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public String getGuestMac() {
+        return guestMac;
+    }
+
+    public Long getSeqNum() {
+        return seqNum;
+    }
+
+    public Long getVmId() {
+        return vmId;
+    }
+
+    /**
+     * used for logging
+     * @return the number of Cidrs in the in and egress rule sets for this security group rules command.
+     */
+    public int getTotalNumCidrs() {
+        int count = 0;
+        for (final IpPortAndProto i : ingressRuleSet) {
+            count += i.allowedCidrs.size();
+        }
+        for (final IpPortAndProto i : egressRuleSet) {
+            count += i.allowedCidrs.size();
+        }
+        return count;
+    }
+
+    public void setMsId(final long msId) {
+        this.msId = msId;
+    }
+
+    public Long getMsId() {
+        return msId;
+    }
+
+}
diff --git a/core/src/com/cloud/agent/api/SetHostParamsCommand.java b/core/src/main/java/com/cloud/agent/api/SetHostParamsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SetHostParamsCommand.java
rename to core/src/main/java/com/cloud/agent/api/SetHostParamsCommand.java
diff --git a/core/src/com/cloud/agent/api/SetupAnswer.java b/core/src/main/java/com/cloud/agent/api/SetupAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SetupAnswer.java
rename to core/src/main/java/com/cloud/agent/api/SetupAnswer.java
diff --git a/core/src/com/cloud/agent/api/SetupCommand.java b/core/src/main/java/com/cloud/agent/api/SetupCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SetupCommand.java
rename to core/src/main/java/com/cloud/agent/api/SetupCommand.java
diff --git a/core/src/com/cloud/agent/api/SetupGuestNetworkCommand.java b/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SetupGuestNetworkCommand.java
rename to core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java
diff --git a/core/src/com/cloud/agent/api/ShutdownCommand.java b/core/src/main/java/com/cloud/agent/api/ShutdownCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ShutdownCommand.java
rename to core/src/main/java/com/cloud/agent/api/ShutdownCommand.java
diff --git a/core/src/com/cloud/agent/api/SnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/SnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/SnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/SnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/StartAnswer.java b/core/src/main/java/com/cloud/agent/api/StartAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartAnswer.java
rename to core/src/main/java/com/cloud/agent/api/StartAnswer.java
diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/main/java/com/cloud/agent/api/StartCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupAnswer.java b/core/src/main/java/com/cloud/agent/api/StartupAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupAnswer.java
rename to core/src/main/java/com/cloud/agent/api/StartupAnswer.java
diff --git a/core/src/com/cloud/agent/api/StartupCommand.java b/core/src/main/java/com/cloud/agent/api/StartupCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupExternalDhcpCommand.java b/core/src/main/java/com/cloud/agent/api/StartupExternalDhcpCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupExternalDhcpCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupExternalDhcpCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupExternalFirewallCommand.java b/core/src/main/java/com/cloud/agent/api/StartupExternalFirewallCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupExternalFirewallCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupExternalFirewallCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/core/src/main/java/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupProxyCommand.java b/core/src/main/java/com/cloud/agent/api/StartupProxyCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupProxyCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupProxyCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupPxeServerCommand.java b/core/src/main/java/com/cloud/agent/api/StartupPxeServerCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupPxeServerCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupPxeServerCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupRoutingCommand.java b/core/src/main/java/com/cloud/agent/api/StartupRoutingCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupRoutingCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupRoutingCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java b/core/src/main/java/com/cloud/agent/api/StartupSecondaryStorageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupSecondaryStorageCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupSecondaryStorageCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupStorageCommand.java b/core/src/main/java/com/cloud/agent/api/StartupStorageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupStorageCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupStorageCommand.java
diff --git a/core/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java b/core/src/main/java/com/cloud/agent/api/StartupTrafficMonitorCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StartupTrafficMonitorCommand.java
rename to core/src/main/java/com/cloud/agent/api/StartupTrafficMonitorCommand.java
diff --git a/core/src/com/cloud/agent/api/StopAnswer.java b/core/src/main/java/com/cloud/agent/api/StopAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StopAnswer.java
rename to core/src/main/java/com/cloud/agent/api/StopAnswer.java
diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/main/java/com/cloud/agent/api/StopCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/StopCommand.java
rename to core/src/main/java/com/cloud/agent/api/StopCommand.java
diff --git a/core/src/com/cloud/agent/api/TransferAgentCommand.java b/core/src/main/java/com/cloud/agent/api/TransferAgentCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/TransferAgentCommand.java
rename to core/src/main/java/com/cloud/agent/api/TransferAgentCommand.java
diff --git a/core/src/com/cloud/agent/api/UnPlugNicAnswer.java b/core/src/main/java/com/cloud/agent/api/UnPlugNicAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/UnPlugNicAnswer.java
rename to core/src/main/java/com/cloud/agent/api/UnPlugNicAnswer.java
diff --git a/core/src/com/cloud/agent/api/UnPlugNicCommand.java b/core/src/main/java/com/cloud/agent/api/UnPlugNicCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/UnPlugNicCommand.java
rename to core/src/main/java/com/cloud/agent/api/UnPlugNicCommand.java
diff --git a/core/src/com/cloud/agent/api/UnregisterNicCommand.java b/core/src/main/java/com/cloud/agent/api/UnregisterNicCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/UnregisterNicCommand.java
rename to core/src/main/java/com/cloud/agent/api/UnregisterNicCommand.java
diff --git a/core/src/main/java/com/cloud/agent/api/UnregisterVMCommand.java b/core/src/main/java/com/cloud/agent/api/UnregisterVMCommand.java
new file mode 100644
index 0000000..4c5f138
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/UnregisterVMCommand.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 com.cloud.agent.api;
+
+public class UnregisterVMCommand extends Command {
+    String vmName;
+    boolean cleanupVmFiles = false;
+    boolean executeInSequence;
+
+    public UnregisterVMCommand(String vmName) {
+        this(vmName, false);
+    }
+    public UnregisterVMCommand(String vmName, boolean executeInSequence) {
+        this.vmName = vmName;
+        this.executeInSequence = executeInSequence;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return executeInSequence;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public void setCleanupVmFiles(boolean cleanupVmFiles) {
+        this.cleanupVmFiles = cleanupVmFiles;
+    }
+
+    public boolean getCleanupVmFiles() {
+        return this.cleanupVmFiles;
+    }
+}
diff --git a/core/src/com/cloud/agent/api/UpdateHostPasswordCommand.java b/core/src/main/java/com/cloud/agent/api/UpdateHostPasswordCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/UpdateHostPasswordCommand.java
rename to core/src/main/java/com/cloud/agent/api/UpdateHostPasswordCommand.java
diff --git a/core/src/com/cloud/agent/api/UpgradeSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/UpgradeSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/UpgradeSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/UpgradeSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java b/core/src/main/java/com/cloud/agent/api/VMSnapshotBaseCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
rename to core/src/main/java/com/cloud/agent/api/VMSnapshotBaseCommand.java
diff --git a/core/src/com/cloud/agent/api/VMSnapshotTO.java b/core/src/main/java/com/cloud/agent/api/VMSnapshotTO.java
similarity index 100%
rename from core/src/com/cloud/agent/api/VMSnapshotTO.java
rename to core/src/main/java/com/cloud/agent/api/VMSnapshotTO.java
diff --git a/core/src/com/cloud/agent/api/ValidateSnapshotAnswer.java b/core/src/main/java/com/cloud/agent/api/ValidateSnapshotAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ValidateSnapshotAnswer.java
rename to core/src/main/java/com/cloud/agent/api/ValidateSnapshotAnswer.java
diff --git a/core/src/com/cloud/agent/api/ValidateSnapshotCommand.java b/core/src/main/java/com/cloud/agent/api/ValidateSnapshotCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/ValidateSnapshotCommand.java
rename to core/src/main/java/com/cloud/agent/api/ValidateSnapshotCommand.java
diff --git a/core/src/com/cloud/agent/api/VmDiskStatsEntry.java b/core/src/main/java/com/cloud/agent/api/VmDiskStatsEntry.java
similarity index 100%
rename from core/src/com/cloud/agent/api/VmDiskStatsEntry.java
rename to core/src/main/java/com/cloud/agent/api/VmDiskStatsEntry.java
diff --git a/core/src/com/cloud/agent/api/VmNetworkStatsEntry.java b/core/src/main/java/com/cloud/agent/api/VmNetworkStatsEntry.java
similarity index 100%
rename from core/src/com/cloud/agent/api/VmNetworkStatsEntry.java
rename to core/src/main/java/com/cloud/agent/api/VmNetworkStatsEntry.java
diff --git a/core/src/main/java/com/cloud/agent/api/VmStatsEntry.java b/core/src/main/java/com/cloud/agent/api/VmStatsEntry.java
new file mode 100644
index 0000000..9f82808
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/VmStatsEntry.java
@@ -0,0 +1,178 @@
+//
+// 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 com.cloud.vm.UserVmVO;
+import com.cloud.vm.VmStats;
+
+public class VmStatsEntry implements VmStats {
+
+    private long vmId;
+    private UserVmVO userVmVO;
+    private double cpuUtilization;
+    private double networkReadKBs;
+    private double networkWriteKBs;
+    private double diskReadIOs;
+    private double diskWriteIOs;
+    private double diskReadKBs;
+    private double diskWriteKBs;
+    private double memoryKBs;
+    private double intfreememoryKBs;
+    private double targetmemoryKBs;
+    private int numCPUs;
+    private String entityType;
+
+    public VmStatsEntry() {
+    }
+
+    public VmStatsEntry(double memoryKBs,double intfreememoryKBs,double targetmemoryKBs, double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) {
+        this.memoryKBs = memoryKBs;
+        this.intfreememoryKBs = intfreememoryKBs;
+        this.targetmemoryKBs = targetmemoryKBs;
+        this.cpuUtilization = cpuUtilization;
+        this.networkReadKBs = networkReadKBs;
+        this.networkWriteKBs = networkWriteKBs;
+        this.numCPUs = numCPUs;
+        this.entityType = entityType;
+    }
+
+    public long getVmId() {
+        return vmId;
+    }
+
+    public void setVmId(long vmId) {
+        this.vmId = vmId;
+    }
+
+    @Override
+    public double getCPUUtilization() {
+        return cpuUtilization;
+    }
+
+    public void setCPUUtilization(double cpuUtilization) {
+        this.cpuUtilization = cpuUtilization;
+    }
+
+    @Override
+    public double getNetworkReadKBs() {
+        return networkReadKBs;
+    }
+
+    public void setNetworkReadKBs(double networkReadKBs) {
+        this.networkReadKBs = networkReadKBs;
+    }
+
+    @Override
+    public double getNetworkWriteKBs() {
+        return networkWriteKBs;
+    }
+
+    public void setNetworkWriteKBs(double networkWriteKBs) {
+        this.networkWriteKBs = networkWriteKBs;
+    }
+
+    @Override
+    public double getDiskReadIOs() {
+        return diskReadIOs;
+    }
+
+    public void setDiskReadIOs(double diskReadIOs) {
+        this.diskReadIOs = diskReadIOs;
+    }
+
+    @Override
+    public double getDiskWriteIOs() {
+        return diskWriteIOs;
+    }
+
+    public void setDiskWriteIOs(double diskWriteIOs) {
+        this.diskWriteIOs = diskWriteIOs;
+    }
+
+    @Override
+    public double getDiskReadKBs() {
+        return diskReadKBs;
+    }
+
+    public void setDiskReadKBs(double diskReadKBs) {
+        this.diskReadKBs = diskReadKBs;
+    }
+
+    @Override
+    public double getDiskWriteKBs() {
+        return diskWriteKBs;
+    }
+
+    public void setDiskWriteKBs(double diskWriteKBs) {
+        this.diskWriteKBs = diskWriteKBs;
+    }
+
+    @Override
+    public double getMemoryKBs() {
+        return memoryKBs;
+    }
+
+    public void setMemoryKBs(double memoryKBs) {
+        this.memoryKBs = memoryKBs;
+    }
+
+    @Override
+    public double getIntFreeMemoryKBs() {
+        return intfreememoryKBs;
+    }
+
+    public void setIntFreeMemoryKBs(double intfreememoryKBs) {
+        this.intfreememoryKBs = intfreememoryKBs;
+    }
+
+    @Override
+    public double getTargetMemoryKBs() {
+        return targetmemoryKBs;
+    }
+
+    public void setTargetMemoryKBs(double targetmemoryKBs) {
+        this.targetmemoryKBs = targetmemoryKBs;
+    }
+
+    public int getNumCPUs() {
+        return numCPUs;
+    }
+
+    public void setNumCPUs(int numCPUs) {
+        this.numCPUs = numCPUs;
+    }
+
+    public String getEntityType() {
+        return this.entityType;
+    }
+
+    public void setEntityType(String entityType) {
+        this.entityType = entityType;
+    }
+
+    public UserVmVO getUserVmVO() {
+        return userVmVO;
+    }
+
+    public void setUserVmVO(UserVmVO userVmVO) {
+        this.userVmVO = userVmVO;
+    }
+
+}
diff --git a/core/src/com/cloud/agent/api/VolumeStatsEntry.java b/core/src/main/java/com/cloud/agent/api/VolumeStatsEntry.java
similarity index 100%
rename from core/src/com/cloud/agent/api/VolumeStatsEntry.java
rename to core/src/main/java/com/cloud/agent/api/VolumeStatsEntry.java
diff --git a/core/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java b/core/src/main/java/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java
rename to core/src/main/java/com/cloud/agent/api/baremetal/IpmISetBootDevCommand.java
diff --git a/core/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java b/core/src/main/java/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java
rename to core/src/main/java/com/cloud/agent/api/baremetal/IpmiBootorResetCommand.java
diff --git a/core/src/com/cloud/agent/api/baremetal/PrepareCreateTemplateCommand.java b/core/src/main/java/com/cloud/agent/api/baremetal/PrepareCreateTemplateCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/baremetal/PrepareCreateTemplateCommand.java
rename to core/src/main/java/com/cloud/agent/api/baremetal/PrepareCreateTemplateCommand.java
diff --git a/core/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java b/core/src/main/java/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java
rename to core/src/main/java/com/cloud/agent/api/baremetal/PreparePxeServerAnswer.java
diff --git a/core/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java b/core/src/main/java/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java
rename to core/src/main/java/com/cloud/agent/api/baremetal/PreparePxeServerCommand.java
diff --git a/core/src/com/cloud/agent/api/check/CheckSshAnswer.java b/core/src/main/java/com/cloud/agent/api/check/CheckSshAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/check/CheckSshAnswer.java
rename to core/src/main/java/com/cloud/agent/api/check/CheckSshAnswer.java
diff --git a/core/src/com/cloud/agent/api/check/CheckSshCommand.java b/core/src/main/java/com/cloud/agent/api/check/CheckSshCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/check/CheckSshCommand.java
rename to core/src/main/java/com/cloud/agent/api/check/CheckSshCommand.java
diff --git a/core/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java b/core/src/main/java/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java
rename to core/src/main/java/com/cloud/agent/api/proxy/CheckConsoleProxyLoadCommand.java
diff --git a/core/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java b/core/src/main/java/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java
rename to core/src/main/java/com/cloud/agent/api/proxy/ConsoleProxyLoadAnswer.java
diff --git a/core/src/com/cloud/agent/api/proxy/ProxyCommand.java b/core/src/main/java/com/cloud/agent/api/proxy/ProxyCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/proxy/ProxyCommand.java
rename to core/src/main/java/com/cloud/agent/api/proxy/ProxyCommand.java
diff --git a/core/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java b/core/src/main/java/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java
rename to core/src/main/java/com/cloud/agent/api/proxy/StartConsoleProxyAgentHttpHandlerCommand.java
diff --git a/core/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java b/core/src/main/java/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java
rename to core/src/main/java/com/cloud/agent/api/proxy/WatchConsoleProxyLoadCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/AggregationControlCommand.java b/core/src/main/java/com/cloud/agent/api/routing/AggregationControlCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/AggregationControlCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/AggregationControlCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/CreateIpAliasCommand.java b/core/src/main/java/com/cloud/agent/api/routing/CreateIpAliasCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/CreateIpAliasCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/CreateIpAliasCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java b/core/src/main/java/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/CreateLoadBalancerApplianceCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/DeleteIpAliasCommand.java b/core/src/main/java/com/cloud/agent/api/routing/DeleteIpAliasCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/DeleteIpAliasCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/DeleteIpAliasCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java b/core/src/main/java/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/DestroyLoadBalancerApplianceCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/main/java/com/cloud/agent/api/routing/DhcpEntryCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/DhcpEntryCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java b/core/src/main/java/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/DnsMasqConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/GetRouterAlertsCommand.java b/core/src/main/java/com/cloud/agent/api/routing/GetRouterAlertsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/GetRouterAlertsCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/GetRouterAlertsCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/GlobalLoadBalancerConfigAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java b/core/src/main/java/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/GlobalLoadBalancerConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/GroupAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/GroupAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/GroupAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/GroupAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/HealthCheckLBConfigAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java b/core/src/main/java/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/IpAliasTO.java b/core/src/main/java/com/cloud/agent/api/routing/IpAliasTO.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/IpAliasTO.java
rename to core/src/main/java/com/cloud/agent/api/routing/IpAliasTO.java
diff --git a/core/src/com/cloud/agent/api/routing/IpAssocAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/IpAssocAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/IpAssocAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/IpAssocAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/IpAssocCommand.java b/core/src/main/java/com/cloud/agent/api/routing/IpAssocCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/IpAssocCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/IpAssocCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java b/core/src/main/java/com/cloud/agent/api/routing/IpAssocVpcCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/IpAssocVpcCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java b/core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/main/java/com/cloud/agent/api/routing/NetworkElementCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/NetworkElementCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/NetworkElementCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java b/core/src/main/java/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/RemoteAccessVpnCfgCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SavePasswordCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SavePasswordCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SavePasswordCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetFirewallRulesAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetFirewallRulesCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetFirewallRulesCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetNetworkACLCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetNetworkACLCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetSourceNatAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetSourceNatAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetSourceNatAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetSourceNatCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetSourceNatCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetSourceNatCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetSourceNatCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetStaticNatRulesAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java b/core/src/main/java/com/cloud/agent/api/routing/SetStaticRouteAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetStaticRouteAnswer.java
diff --git a/core/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java b/core/src/main/java/com/cloud/agent/api/routing/SetStaticRouteCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/SetStaticRouteCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java b/core/src/main/java/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java
rename to core/src/main/java/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java
diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/main/java/com/cloud/agent/api/routing/VmDataCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/VmDataCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/VmDataCommand.java
diff --git a/core/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java b/core/src/main/java/com/cloud/agent/api/routing/VpnUsersCfgCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/routing/VpnUsersCfgCommand.java
rename to core/src/main/java/com/cloud/agent/api/routing/VpnUsersCfgCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/core/src/main/java/com/cloud/agent/api/storage/AbstractDownloadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/AbstractDownloadCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/AbstractUploadCommand.java b/core/src/main/java/com/cloud/agent/api/storage/AbstractUploadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/AbstractUploadCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/AbstractUploadCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/CopyVolumeAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/CopyVolumeAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/main/java/com/cloud/agent/api/storage/CopyVolumeCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/CopyVolumeCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/CreateAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateCommand.java b/core/src/main/java/com/cloud/agent/api/storage/CreateCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/CreateDatadiskTemplateAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateDatadiskTemplateAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java b/core/src/main/java/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateEntityDownloadURLAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java b/core/src/main/java/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreateEntityDownloadURLCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java b/core/src/main/java/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/DeleteEntityDownloadURLCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/DestroyCommand.java b/core/src/main/java/com/cloud/agent/api/storage/DestroyCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/DestroyCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/DestroyCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/DownloadAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/DownloadAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/GetDatadisksAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/GetDatadisksCommand.java b/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/GetDatadisksCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/ListTemplateAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/ListTemplateAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/core/src/main/java/com/cloud/agent/api/storage/ListTemplateCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ListTemplateCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/ListTemplateCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/ListVolumeAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/ListVolumeAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/ListVolumeCommand.java b/core/src/main/java/com/cloud/agent/api/storage/ListVolumeCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ListVolumeCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/ListVolumeCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/MigrateVolumeAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/MigrateVolumeAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/MigrateVolumeAnswer.java
diff --git a/core/src/main/java/com/cloud/agent/api/storage/MigrateVolumeCommand.java b/core/src/main/java/com/cloud/agent/api/storage/MigrateVolumeCommand.java
new file mode 100644
index 0000000..9902a86
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/api/storage/MigrateVolumeCommand.java
@@ -0,0 +1,131 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.agent.api.storage;
+
+import java.util.Map;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+
+public class MigrateVolumeCommand extends Command {
+    long volumeId;
+    String volumePath;
+    StorageFilerTO pool;
+    StorageFilerTO sourcePool;
+    String attachedVmName;
+    Volume.Type volumeType;
+
+    private DataTO srcData;
+    private DataTO destData;
+    private Map<String, String> srcDetails;
+    private Map<String, String> destDetails;
+
+    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, int timeout) {
+        this.volumeId = volumeId;
+        this.volumePath = volumePath;
+        this.pool = new StorageFilerTO(pool);
+        this.setWait(timeout);
+    }
+
+    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName, Volume.Type volumeType, int timeout) {
+        this(volumeId,volumePath,pool,timeout);
+        this.attachedVmName = attachedVmName;
+        this.volumeType = volumeType;
+        this.setWait(timeout);
+    }
+
+    public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool sourcePool, StoragePool targetPool) {
+        this(volumeId,volumePath,targetPool, null, Volume.Type.UNKNOWN, -1);
+        this.sourcePool = new StorageFilerTO(sourcePool);
+    }
+
+    public MigrateVolumeCommand(DataTO srcData, DataTO destData, Map<String, String> srcDetails, Map<String, String> destDetails, int timeout) {
+        this.srcData = srcData;
+        this.destData = destData;
+        this.srcDetails = srcDetails;
+        this.destDetails = destDetails;
+
+        setWait(timeout);
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+
+    public String getVolumePath() {
+        return volumePath;
+    }
+
+    public long getVolumeId() {
+        return volumeId;
+    }
+
+    public StorageFilerTO getPool() {
+        return pool;
+    }
+
+    public StorageFilerTO getSourcePool() {
+        return sourcePool;
+    }
+
+    public StorageFilerTO getTargetPool() {
+        return pool;
+    }
+
+    public String getAttachedVmName() {
+        return attachedVmName;
+    }
+
+    public Volume.Type getVolumeType() {
+        return volumeType;
+    }
+
+    public DataTO getSrcData() {
+        return srcData;
+    }
+
+    public DataTO getDestData() {
+        return destData;
+    }
+
+    public void setSrcDetails(Map<String, String> details) {
+        srcDetails = details;
+    }
+
+    public Map<String, String> getSrcDetails() {
+        return srcDetails;
+    }
+
+    public void setDestDetails(Map<String, String> details) {
+        destDetails = details;
+    }
+
+    public Map<String, String> getDestDetails() {
+        return destDetails;
+    }
+
+    public int getWaitInMillSeconds() {
+        return getWait() * 1000;
+    }
+}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/core/src/main/java/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/ResizeVolumeAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/ResizeVolumeAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java b/core/src/main/java/com/cloud/agent/api/storage/ResizeVolumeCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/ResizeVolumeCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/ResizeVolumeCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/SsCommand.java b/core/src/main/java/com/cloud/agent/api/storage/SsCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/SsCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/SsCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/StorageCommand.java b/core/src/main/java/com/cloud/agent/api/storage/StorageCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/StorageCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/StorageCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/StorageNfsVersionCommand.java b/core/src/main/java/com/cloud/agent/api/storage/StorageNfsVersionCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/StorageNfsVersionCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/StorageNfsVersionCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/UploadAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/UploadAnswer.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/UploadAnswer.java
rename to core/src/main/java/com/cloud/agent/api/storage/UploadAnswer.java
diff --git a/core/src/com/cloud/agent/api/storage/UploadCommand.java b/core/src/main/java/com/cloud/agent/api/storage/UploadCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/UploadCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/UploadCommand.java
diff --git a/core/src/com/cloud/agent/api/storage/UploadProgressCommand.java b/core/src/main/java/com/cloud/agent/api/storage/UploadProgressCommand.java
similarity index 100%
rename from core/src/com/cloud/agent/api/storage/UploadProgressCommand.java
rename to core/src/main/java/com/cloud/agent/api/storage/UploadProgressCommand.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/ConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/ConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/ConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/FileConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/ScriptConfigItem.java
diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VRScripts.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VRScripts.java
new file mode 100644
index 0000000..2c75a78
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VRScripts.java
@@ -0,0 +1,73 @@
+//
+// 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.resource.virtualnetwork;
+
+import org.joda.time.Duration;
+
+public class VRScripts {
+    public final static String CONFIG_PERSIST_LOCATION = "/var/cache/cloud/";
+    public final static String IP_ASSOCIATION_CONFIG = "ip_associations.json";
+    public final static String GUEST_NETWORK_CONFIG = "guest_network.json";
+    public final static String NETWORK_ACL_CONFIG = "network_acl.json";
+    public final static String VM_METADATA_CONFIG = "vm_metadata.json";
+    public final static String VM_DHCP_CONFIG = "vm_dhcp_entry.json";
+    public final static String VM_PASSWORD_CONFIG = "vm_password.json";
+    public static final String FORWARDING_RULES_CONFIG = "forwarding_rules.json";
+    public static final String FIREWALL_RULES_CONFIG = "firewall_rules.json";
+    public static final String VPN_USER_LIST_CONFIG = "vpn_user_list.json";
+    public static final String STATICNAT_RULES_CONFIG = "staticnat_rules.json";
+    public static final String SITE_2_SITE_VPN_CONFIG = "site_2_site_vpn.json";
+    public static final String STATIC_ROUTES_CONFIG = "static_routes.json";
+    public static final String REMOTE_ACCESS_VPN_CONFIG = "remote_access_vpn.json";
+    public static final String MONITOR_SERVICE_CONFIG = "monitor_service.json";
+    public static final String DHCP_CONFIG = "dhcp.json";
+    public static final String IP_ALIAS_CONFIG = "ip_aliases.json";
+    public static final String LOAD_BALANCER_CONFIG = "load_balancer.json";
+
+    public final static String CONFIG_CACHE_LOCATION = "/var/cache/cloud/";
+    public final static Duration VR_SCRIPT_EXEC_TIMEOUT = Duration.standardMinutes(10);
+    public final static Duration CONNECTION_TIMEOUT = Duration.standardMinutes(1);
+
+    // New scripts for use with chef
+    public static final String UPDATE_CONFIG = "update_config.py";
+
+    // Script still in use - mostly by HyperV
+    public static final String S2SVPN_CHECK = "checkbatchs2svpn.sh";
+    public static final String S2SVPN_IPSEC = "ipsectunnel.sh";
+    public static final String DHCP = "edithosts.sh";
+    public static final String DNSMASQ_CONFIG = "dnsmasq.sh";
+    public static final String IPASSOC = "ipassoc.sh";
+    public static final String LB = "loadbalancer.sh";
+    public static final String MONITOR_SERVICE = "monitor_service.sh";
+    public static final String PASSWORD = "savepassword.sh";
+    public static final String ROUTER_ALERTS = "getRouterAlerts.sh";
+    public static final String RVR_CHECK = "checkrouter.sh";
+    public static final String VMDATA = "vmdata.py";
+    public static final String RVR_BUMPUP_PRI = "bumpup_priority.sh";
+    public static final String VERSION = "get_template_version.sh";
+    public static final String VPC_SOURCE_NAT = "vpc_snat.sh";
+    public static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh";
+    public static final String VPN_L2TP = "vpn_l2tp.sh";
+    public static final String UPDATE_HOST_PASSWD = "update_host_passwd.sh";
+
+    public static final String VR_CFG = "vr_cfg.sh";
+
+    public static final String DIAGNOSTICS = "diagnostics.py";
+}
\ No newline at end of file
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java
diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
new file mode 100644
index 0000000..21372a1
--- /dev/null
+++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -0,0 +1,473 @@
+//
+// 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.resource.virtualnetwork;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SocketChannel;
+
+import org.apache.cloudstack.diagnostics.DiagnosticsAnswer;
+import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
+import org.joda.time.Duration;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.ca.SetupCertificateAnswer;
+import org.apache.cloudstack.ca.SetupCertificateCommand;
+import org.apache.cloudstack.ca.SetupKeyStoreCommand;
+import org.apache.cloudstack.ca.SetupKeystoreAnswer;
+import org.apache.cloudstack.utils.security.KeyStoreUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckRouterAnswer;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetRouterAlertsAnswer;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
+import com.cloud.agent.api.routing.GetRouterAlertsCommand;
+import com.cloud.agent.api.routing.GroupAnswer;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.resource.virtualnetwork.facade.AbstractConfigItemFacade;
+import com.cloud.utils.ExecutionResult;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * VirtualNetworkResource controls and configures virtual networking
+ *
+ * @config
+ * {@table
+ *    || Param Name | Description | Values | Default ||
+ *  }
+ **/
+public class VirtualRoutingResource {
+
+    private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class);
+    private VirtualRouterDeployer _vrDeployer;
+    private Map<String, Queue<NetworkElementCommand>> _vrAggregateCommandsSet;
+    protected Map<String, Lock> _vrLockMap = new HashMap<String, Lock>();
+
+    private String _name;
+    private int _sleep;
+    private int _retry;
+    private int _port;
+    private Duration _eachTimeout;
+    private Map<String, Object> _params;
+
+    private String _cfgVersion = "1.0";
+
+    public VirtualRoutingResource(VirtualRouterDeployer deployer) {
+        _vrDeployer = deployer;
+    }
+
+    public Answer executeRequest(final NetworkElementCommand cmd) {
+        boolean aggregated = false;
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        Lock lock;
+        if (_vrLockMap.containsKey(routerName)) {
+            lock = _vrLockMap.get(routerName);
+        } else {
+            lock = new ReentrantLock();
+            _vrLockMap.put(routerName, lock);
+        }
+        lock.lock();
+
+        try {
+            ExecutionResult rc = _vrDeployer.prepareCommand(cmd);
+            if (!rc.isSuccess()) {
+                s_logger.error("Failed to prepare VR command due to " + rc.getDetails());
+                return new Answer(cmd, false, rc.getDetails());
+            }
+
+            assert cmd.getRouterAccessIp() != null : "Why there is no access IP for VR?";
+
+            if (cmd.isQuery()) {
+                return executeQueryCommand(cmd);
+            }
+
+            if (cmd instanceof SetupKeyStoreCommand) {
+                return execute((SetupKeyStoreCommand) cmd);
+            }
+
+            if (cmd instanceof SetupCertificateCommand) {
+                return execute((SetupCertificateCommand) cmd);
+            }
+
+            if (cmd instanceof AggregationControlCommand) {
+                return execute((AggregationControlCommand)cmd);
+            }
+
+            if (_vrAggregateCommandsSet.containsKey(routerName)) {
+                _vrAggregateCommandsSet.get(routerName).add(cmd);
+                aggregated = true;
+                // Clean up would be done after command has been executed
+                //TODO: Deal with group answer as well
+                return new Answer(cmd);
+            }
+
+            List<ConfigItem> cfg = generateCommandCfg(cmd);
+            if (cfg == null) {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            return applyConfig(cmd, cfg);
+        } catch (final IllegalArgumentException e) {
+            return new Answer(cmd, false, e.getMessage());
+        } finally {
+            lock.unlock();
+            if (!aggregated) {
+                ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
+                if (!rc.isSuccess()) {
+                    s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
+                }
+            }
+        }
+    }
+
+    private Answer execute(final SetupKeyStoreCommand cmd) {
+        final String args = String.format("/usr/local/cloud/systemvm/conf/agent.properties " +
+                        "/usr/local/cloud/systemvm/conf/%s " +
+                        "%s %d " +
+                        "/usr/local/cloud/systemvm/conf/%s",
+                KeyStoreUtils.KS_FILENAME,
+                cmd.getKeystorePassword(),
+                cmd.getValidityDays(),
+                KeyStoreUtils.CSR_FILENAME);
+        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), KeyStoreUtils.KS_SETUP_SCRIPT, args, Duration.standardMinutes(15));
+        return new SetupKeystoreAnswer(result.getDetails());
+    }
+
+    private Answer execute(final SetupCertificateCommand cmd) {
+        final String args = String.format("/usr/local/cloud/systemvm/conf/agent.properties " +
+                        "/usr/local/cloud/systemvm/conf/%s %s " +
+                        "/usr/local/cloud/systemvm/conf/%s \"%s\" " +
+                        "/usr/local/cloud/systemvm/conf/%s \"%s\" " +
+                        "/usr/local/cloud/systemvm/conf/%s \"%s\"",
+                KeyStoreUtils.KS_FILENAME,
+                KeyStoreUtils.SSH_MODE,
+                KeyStoreUtils.CERT_FILENAME,
+                cmd.getEncodedCertificate(),
+                KeyStoreUtils.CACERT_FILENAME,
+                cmd.getEncodedCaCertificates(),
+                KeyStoreUtils.PKEY_FILENAME,
+                cmd.getEncodedPrivateKey());
+        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), KeyStoreUtils.KS_IMPORT_SCRIPT, args, Duration.standardMinutes(15));
+        return new SetupCertificateAnswer(result.isSuccess());
+    }
+
+    private Answer executeQueryCommand(NetworkElementCommand cmd) {
+        if (cmd instanceof CheckRouterCommand) {
+            return execute((CheckRouterCommand)cmd);
+        } else if (cmd instanceof GetDomRVersionCmd) {
+            return execute((GetDomRVersionCmd)cmd);
+        } else if (cmd instanceof CheckS2SVpnConnectionsCommand) {
+            return execute((CheckS2SVpnConnectionsCommand)cmd);
+        } else if (cmd instanceof GetRouterAlertsCommand) {
+            return execute((GetRouterAlertsCommand)cmd);
+        } else if (cmd instanceof DiagnosticsCommand) {
+            return execute((DiagnosticsCommand)cmd);
+        } else {
+            s_logger.error("Unknown query command in VirtualRoutingResource!");
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c) {
+        return applyConfigToVR(routerAccessIp, c, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
+    }
+
+    private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c, Duration timeout) {
+        if (c instanceof FileConfigItem) {
+            FileConfigItem configItem = (FileConfigItem)c;
+            return _vrDeployer.createFileInVR(routerAccessIp, configItem.getFilePath(), configItem.getFileName(), configItem.getFileContents());
+        } else if (c instanceof ScriptConfigItem) {
+            ScriptConfigItem configItem = (ScriptConfigItem)c;
+            return _vrDeployer.executeInVR(routerAccessIp, configItem.getScript(), configItem.getArgs(), timeout);
+        }
+        throw new CloudRuntimeException("Unable to apply unknown configitem of type " + c.getClass().getSimpleName());
+    }
+
+
+    private Answer applyConfig(NetworkElementCommand cmd, List<ConfigItem> cfg) {
+
+
+        if (cfg.isEmpty()) {
+            return new Answer(cmd, true, "Nothing to do");
+        }
+
+        List<ExecutionResult> results = new ArrayList<ExecutionResult>();
+        List<String> details = new ArrayList<String>();
+        boolean finalResult = false;
+        for (ConfigItem configItem : cfg) {
+            long startTimestamp = System.currentTimeMillis();
+            ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), configItem, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
+            if (s_logger.isDebugEnabled()) {
+                long elapsed = System.currentTimeMillis() - startTimestamp;
+                s_logger.debug("Processing " + configItem + " took " + elapsed + "ms");
+            }
+            if (result == null) {
+                result = new ExecutionResult(false, "null execution result");
+            }
+            results.add(result);
+            details.add(configItem.getInfo() + (result.isSuccess() ? " - success: " : " - failed: ") + result.getDetails());
+            finalResult = result.isSuccess();
+        }
+
+        // Not sure why this matters, but log it anyway
+        if (cmd.getAnswersCount() != results.size()) {
+            s_logger.warn("Expected " + cmd.getAnswersCount() + " answers while executing " + cmd.getClass().getSimpleName() + " but received " + results.size());
+        }
+
+
+        if (results.size() == 1) {
+            return new Answer(cmd, finalResult, results.get(0).getDetails());
+        } else {
+            return new GroupAnswer(cmd, finalResult, results.size(), details.toArray(new String[details.size()]));
+        }
+    }
+
+    private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {
+
+        StringBuffer buff = new StringBuffer();
+        for (String ip : cmd.getVpnIps()) {
+            buff.append(ip);
+            buff.append(" ");
+        }
+        ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.S2SVPN_CHECK, buff.toString());
+        return new CheckS2SVpnConnectionsAnswer(cmd, result.isSuccess(), result.getDetails());
+    }
+
+    private GetRouterAlertsAnswer execute(GetRouterAlertsCommand cmd) {
+
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String args = cmd.getPreviousAlertTimeStamp();
+
+        ExecutionResult result = _vrDeployer.executeInVR(routerIp, VRScripts.ROUTER_ALERTS, args);
+        String alerts[] = null;
+        String lastAlertTimestamp = null;
+
+        if (result.isSuccess()) {
+            if (!result.getDetails().isEmpty() && !result.getDetails().trim().equals("No Alerts")) {
+                alerts = result.getDetails().trim().split("\\\\n");
+                String[] lastAlert = alerts[alerts.length - 1].split(",");
+                lastAlertTimestamp = lastAlert[0];
+            }
+            return new GetRouterAlertsAnswer(cmd, alerts, lastAlertTimestamp);
+        } else {
+            return new GetRouterAlertsAnswer(cmd, result.getDetails());
+        }
+    }
+
+    private Answer execute(CheckRouterCommand cmd) {
+        final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.RVR_CHECK, null);
+        if (!result.isSuccess()) {
+            return new CheckRouterAnswer(cmd, result.getDetails());
+        }
+        return new CheckRouterAnswer(cmd, result.getDetails(), true);
+    }
+
+    private Answer execute(DiagnosticsCommand cmd) {
+        _eachTimeout = Duration.standardSeconds(NumbersUtil.parseInt("60", 60));
+        final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.DIAGNOSTICS, cmd.getSrciptArguments(), _eachTimeout);
+        if (!result.isSuccess()) {
+            return new DiagnosticsAnswer(cmd, false, result.getDetails());
+        }
+        return new DiagnosticsAnswer(cmd, result.isSuccess(), result.getDetails());
+    }
+
+    private Answer execute(GetDomRVersionCmd cmd) {
+        final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VERSION, null);
+        if (!result.isSuccess()) {
+            return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed");
+        }
+        String[] lines = result.getDetails().split("&");
+        if (lines.length != 2) {
+            return new GetDomRVersionAnswer(cmd, result.getDetails());
+        }
+        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;
+
+        value = (String)params.get("ssh.retry");
+        _retry = NumbersUtil.parseInt(value, 36);
+
+        value = (String)params.get("ssh.port");
+        _port = NumbersUtil.parseInt(value, 3922);
+
+        value = (String)params.get("router.aggregation.command.each.timeout");
+        _eachTimeout = Duration.standardSeconds(NumbersUtil.parseInt(value, (int)VRScripts.VR_SCRIPT_EXEC_TIMEOUT.getStandardSeconds()));
+        if (s_logger.isDebugEnabled()){
+            s_logger.debug("The router.aggregation.command.each.timeout in seconds is set to " + _eachTimeout.getStandardSeconds());
+        }
+
+        if (_vrDeployer == null) {
+            throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!");
+        }
+
+        _vrAggregateCommandsSet = new HashMap<>();
+        return true;
+    }
+
+    public boolean connect(final String ipAddress) {
+        return connect(ipAddress, _port);
+    }
+
+    public boolean connect(final String ipAddress, final int port) {
+        return connect(ipAddress, port, _sleep);
+    }
+
+    public boolean connect(final String ipAddress, int retry, int sleep) {
+        for (int i = 0; i <= retry; i++) {
+            SocketChannel sch = null;
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Trying to connect to " + ipAddress);
+                }
+                sch = SocketChannel.open();
+                sch.configureBlocking(true);
+
+                final InetSocketAddress addr = new InetSocketAddress(ipAddress, _port);
+                sch.connect(addr);
+                return true;
+            } catch (final IOException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Could not connect to " + ipAddress);
+                }
+            } finally {
+                if (sch != null) {
+                    try {
+                        sch.close();
+                    } catch (final IOException e) {
+                    }
+                }
+            }
+            try {
+                Thread.sleep(sleep);
+            } catch (final InterruptedException e) {
+            }
+        }
+
+        s_logger.debug("Unable to logon to " + ipAddress);
+
+        return false;
+    }
+
+    private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
+        /*
+         * [TODO] Still have to migrate LoadBalancerConfigCommand and BumpUpPriorityCommand
+         * [FIXME] Have a look at SetSourceNatConfigItem
+         */
+        s_logger.debug("Transforming " + cmd.getClass().getCanonicalName() + " to ConfigItems");
+
+        final AbstractConfigItemFacade configItemFacade = AbstractConfigItemFacade.getInstance(cmd.getClass());
+
+        return configItemFacade.generateConfig(cmd);
+    }
+
+    private Answer execute(AggregationControlCommand cmd) {
+        Action action = cmd.getAction();
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        assert routerName != null;
+        assert cmd.getRouterAccessIp() != null;
+
+        if (action == Action.Start) {
+            assert (!_vrAggregateCommandsSet.containsKey(routerName));
+
+            Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
+            _vrAggregateCommandsSet.put(routerName, queue);
+            return new Answer(cmd, true, "Command aggregation started");
+        } else if (action == Action.Finish) {
+            Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
+            int answerCounts = 0;
+            try {
+                StringBuilder sb = new StringBuilder();
+                sb.append("#Apache CloudStack Virtual Router Config File\n");
+                sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
+                for (NetworkElementCommand command : queue) {
+                    answerCounts += command.getAnswersCount();
+                    List<ConfigItem> cfg = generateCommandCfg(command);
+                    if (cfg == null) {
+                        s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
+                        continue;
+                    }
+
+                    for (ConfigItem c : cfg) {
+                        sb.append(c.getAggregateCommand());
+                    }
+                }
+
+                // TODO replace with applyConfig with a stop on fail
+                String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
+                FileConfigItem fileConfigItem = new FileConfigItem(VRScripts.CONFIG_CACHE_LOCATION, cfgFileName, sb.toString());
+                ScriptConfigItem scriptConfigItem = new ScriptConfigItem(VRScripts.VR_CFG, "-c " + VRScripts.CONFIG_CACHE_LOCATION + cfgFileName);
+                // 120s is the minimal timeout
+                Duration timeout = _eachTimeout.withDurationAdded(_eachTimeout.getStandardSeconds(), answerCounts);
+                if (s_logger.isDebugEnabled()){
+                    s_logger.debug("Aggregate action timeout in seconds is " + timeout.getStandardSeconds());
+                }
+
+                ExecutionResult result = applyConfigToVR(cmd.getRouterAccessIp(), fileConfigItem, timeout);
+                if (!result.isSuccess()) {
+                    return new Answer(cmd, false, result.getDetails());
+                }
+
+                result = applyConfigToVR(cmd.getRouterAccessIp(), scriptConfigItem, timeout);
+                if (!result.isSuccess()) {
+                    return new Answer(cmd, false, result.getDetails());
+                }
+
+                return new Answer(cmd, true, "Command aggregation finished");
+            } finally {
+                queue.clear();
+                _vrAggregateCommandsSet.remove(routerName);
+            }
+        }
+        return new Answer(cmd, false, "Fail to recognize aggregation action " + action.toString());
+    }
+}
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/AbstractConfigItemFacade.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/AbstractConfigItemFacade.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/AbstractConfigItemFacade.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/AbstractConfigItemFacade.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/BumpUpPriorityConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/BumpUpPriorityConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/BumpUpPriorityConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/BumpUpPriorityConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/CreateIpAliasConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/CreateIpAliasConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/CreateIpAliasConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/CreateIpAliasConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/DeleteIpAliasConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DeleteIpAliasConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/DeleteIpAliasConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DeleteIpAliasConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/DhcpEntryConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DhcpEntryConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/DhcpEntryConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DhcpEntryConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/DnsMasqConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DnsMasqConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/DnsMasqConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/DnsMasqConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/IpAssociationConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/IpAssociationConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/IpAssociationConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/IpAssociationConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/LoadBalancerConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/LoadBalancerConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/LoadBalancerConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/LoadBalancerConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/RemoteAccessVpnConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/RemoteAccessVpnConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/RemoteAccessVpnConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/RemoteAccessVpnConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SavePasswordConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SavePasswordConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SavePasswordConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SavePasswordConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetFirewallRulesConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetFirewallRulesConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetFirewallRulesConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetFirewallRulesConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetMonitorServiceConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetMonitorServiceConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetMonitorServiceConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetMonitorServiceConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetNetworkAclConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetNetworkAclConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetNetworkAclConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetNetworkAclConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesVpcConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesVpcConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesVpcConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesVpcConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetSourceNatConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetSourceNatConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetSourceNatConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetSourceNatConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetStaticNatRulesConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetStaticNatRulesConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetStaticNatRulesConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetStaticNatRulesConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/SetStaticRouteConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetStaticRouteConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/SetStaticRouteConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetStaticRouteConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/VmDataConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/VmDataConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/VmDataConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/VmDataConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/VpnUsersConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/VpnUsersConfigItem.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/facade/VpnUsersConfigItem.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/VpnUsersConfigItem.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/AclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/AclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/AclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/AclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/AllAclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/AllAclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/AllAclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/AllAclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/ConfigBase.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ConfigBase.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/ConfigBase.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ConfigBase.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/DhcpConfig.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/DhcpConfig.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/DhcpConfig.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/DhcpConfig.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/DhcpConfigEntry.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/DhcpConfigEntry.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/DhcpConfigEntry.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/DhcpConfigEntry.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/FirewallRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/FirewallRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/FirewallRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/FirewallRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/FirewallRules.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/FirewallRules.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/FirewallRules.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/FirewallRules.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/ForwardingRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ForwardingRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/ForwardingRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ForwardingRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/ForwardingRules.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ForwardingRules.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/ForwardingRules.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ForwardingRules.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/IcmpAclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IcmpAclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/IcmpAclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IcmpAclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/IpAddress.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAddress.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/IpAddress.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAddress.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/IpAddressAlias.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAddressAlias.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/IpAddressAlias.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAddressAlias.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/IpAliases.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAliases.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/IpAliases.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAliases.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/IpAssociation.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAssociation.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/IpAssociation.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/IpAssociation.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRules.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRules.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRules.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/LoadBalancerRules.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/MonitorService.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/MonitorService.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/MonitorService.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/MonitorService.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/NetworkACL.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/NetworkACL.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/NetworkACL.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/NetworkACL.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/ProtocolAclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ProtocolAclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/ProtocolAclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ProtocolAclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/RemoteAccessVpn.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/RemoteAccessVpn.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/RemoteAccessVpn.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/RemoteAccessVpn.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/StaticNatRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticNatRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/StaticNatRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticNatRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/StaticNatRules.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticNatRules.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/StaticNatRules.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticNatRules.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/StaticRoute.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticRoute.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/StaticRoute.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticRoute.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/StaticRoutes.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticRoutes.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/StaticRoutes.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/StaticRoutes.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/TcpAclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/TcpAclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/TcpAclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/TcpAclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/UdpAclRule.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/UdpAclRule.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/UdpAclRule.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/UdpAclRule.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/VmData.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmData.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/VmData.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmData.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/VmDhcpConfig.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmDhcpConfig.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/VmDhcpConfig.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmDhcpConfig.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/VmPassword.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmPassword.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/VmPassword.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VmPassword.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/VpnUser.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VpnUser.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/VpnUser.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VpnUser.java
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/VpnUserList.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VpnUserList.java
similarity index 100%
rename from core/src/com/cloud/agent/resource/virtualnetwork/model/VpnUserList.java
rename to core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/VpnUserList.java
diff --git a/core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java b/core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java
similarity index 100%
rename from core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java
rename to core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java
diff --git a/core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java b/core/src/main/java/com/cloud/agent/transport/InterfaceTypeAdaptor.java
similarity index 100%
rename from core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java
rename to core/src/main/java/com/cloud/agent/transport/InterfaceTypeAdaptor.java
diff --git a/core/src/com/cloud/agent/transport/LoggingExclusionStrategy.java b/core/src/main/java/com/cloud/agent/transport/LoggingExclusionStrategy.java
similarity index 100%
rename from core/src/com/cloud/agent/transport/LoggingExclusionStrategy.java
rename to core/src/main/java/com/cloud/agent/transport/LoggingExclusionStrategy.java
diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/main/java/com/cloud/agent/transport/Request.java
similarity index 100%
rename from core/src/com/cloud/agent/transport/Request.java
rename to core/src/main/java/com/cloud/agent/transport/Request.java
diff --git a/core/src/com/cloud/agent/transport/Response.java b/core/src/main/java/com/cloud/agent/transport/Response.java
similarity index 100%
rename from core/src/com/cloud/agent/transport/Response.java
rename to core/src/main/java/com/cloud/agent/transport/Response.java
diff --git a/core/src/com/cloud/exception/UnsupportedVersionException.java b/core/src/main/java/com/cloud/exception/UnsupportedVersionException.java
similarity index 100%
rename from core/src/com/cloud/exception/UnsupportedVersionException.java
rename to core/src/main/java/com/cloud/exception/UnsupportedVersionException.java
diff --git a/core/src/com/cloud/host/HostInfo.java b/core/src/main/java/com/cloud/host/HostInfo.java
similarity index 100%
rename from core/src/com/cloud/host/HostInfo.java
rename to core/src/main/java/com/cloud/host/HostInfo.java
diff --git a/core/src/com/cloud/info/ConsoleProxyConnectionInfo.java b/core/src/main/java/com/cloud/info/ConsoleProxyConnectionInfo.java
similarity index 100%
rename from core/src/com/cloud/info/ConsoleProxyConnectionInfo.java
rename to core/src/main/java/com/cloud/info/ConsoleProxyConnectionInfo.java
diff --git a/core/src/com/cloud/info/ConsoleProxyInfo.java b/core/src/main/java/com/cloud/info/ConsoleProxyInfo.java
similarity index 100%
rename from core/src/com/cloud/info/ConsoleProxyInfo.java
rename to core/src/main/java/com/cloud/info/ConsoleProxyInfo.java
diff --git a/core/src/com/cloud/info/ConsoleProxyStatus.java b/core/src/main/java/com/cloud/info/ConsoleProxyStatus.java
similarity index 100%
rename from core/src/com/cloud/info/ConsoleProxyStatus.java
rename to core/src/main/java/com/cloud/info/ConsoleProxyStatus.java
diff --git a/core/src/com/cloud/info/RunningHostInfoAgregator.java b/core/src/main/java/com/cloud/info/RunningHostInfoAgregator.java
similarity index 100%
rename from core/src/com/cloud/info/RunningHostInfoAgregator.java
rename to core/src/main/java/com/cloud/info/RunningHostInfoAgregator.java
diff --git a/core/src/com/cloud/network/HAProxyConfigurator.java b/core/src/main/java/com/cloud/network/HAProxyConfigurator.java
similarity index 100%
rename from core/src/com/cloud/network/HAProxyConfigurator.java
rename to core/src/main/java/com/cloud/network/HAProxyConfigurator.java
diff --git a/core/src/com/cloud/network/LoadBalancerConfigurator.java b/core/src/main/java/com/cloud/network/LoadBalancerConfigurator.java
similarity index 100%
rename from core/src/com/cloud/network/LoadBalancerConfigurator.java
rename to core/src/main/java/com/cloud/network/LoadBalancerConfigurator.java
diff --git a/core/src/com/cloud/network/LoadBalancerValidator.java b/core/src/main/java/com/cloud/network/LoadBalancerValidator.java
similarity index 100%
rename from core/src/com/cloud/network/LoadBalancerValidator.java
rename to core/src/main/java/com/cloud/network/LoadBalancerValidator.java
diff --git a/core/src/com/cloud/network/resource/CreateLoadBalancerApplianceAnswer.java b/core/src/main/java/com/cloud/network/resource/CreateLoadBalancerApplianceAnswer.java
similarity index 100%
rename from core/src/com/cloud/network/resource/CreateLoadBalancerApplianceAnswer.java
rename to core/src/main/java/com/cloud/network/resource/CreateLoadBalancerApplianceAnswer.java
diff --git a/core/src/com/cloud/network/resource/DestroyLoadBalancerApplianceAnswer.java b/core/src/main/java/com/cloud/network/resource/DestroyLoadBalancerApplianceAnswer.java
similarity index 100%
rename from core/src/com/cloud/network/resource/DestroyLoadBalancerApplianceAnswer.java
rename to core/src/main/java/com/cloud/network/resource/DestroyLoadBalancerApplianceAnswer.java
diff --git a/core/src/com/cloud/network/resource/TrafficSentinelResource.java b/core/src/main/java/com/cloud/network/resource/TrafficSentinelResource.java
similarity index 100%
rename from core/src/com/cloud/network/resource/TrafficSentinelResource.java
rename to core/src/main/java/com/cloud/network/resource/TrafficSentinelResource.java
diff --git a/core/src/com/cloud/resource/CommandWrapper.java b/core/src/main/java/com/cloud/resource/CommandWrapper.java
similarity index 100%
rename from core/src/com/cloud/resource/CommandWrapper.java
rename to core/src/main/java/com/cloud/resource/CommandWrapper.java
diff --git a/core/src/com/cloud/resource/RequestWrapper.java b/core/src/main/java/com/cloud/resource/RequestWrapper.java
similarity index 100%
rename from core/src/com/cloud/resource/RequestWrapper.java
rename to core/src/main/java/com/cloud/resource/RequestWrapper.java
diff --git a/core/src/com/cloud/resource/ResourceListener.java b/core/src/main/java/com/cloud/resource/ResourceListener.java
similarity index 100%
rename from core/src/com/cloud/resource/ResourceListener.java
rename to core/src/main/java/com/cloud/resource/ResourceListener.java
diff --git a/core/src/com/cloud/resource/ResourceWrapper.java b/core/src/main/java/com/cloud/resource/ResourceWrapper.java
similarity index 100%
rename from core/src/com/cloud/resource/ResourceWrapper.java
rename to core/src/main/java/com/cloud/resource/ResourceWrapper.java
diff --git a/core/src/com/cloud/resource/ServerResource.java b/core/src/main/java/com/cloud/resource/ServerResource.java
similarity index 100%
rename from core/src/com/cloud/resource/ServerResource.java
rename to core/src/main/java/com/cloud/resource/ServerResource.java
diff --git a/core/src/com/cloud/resource/ServerResourceBase.java b/core/src/main/java/com/cloud/resource/ServerResourceBase.java
similarity index 100%
rename from core/src/com/cloud/resource/ServerResourceBase.java
rename to core/src/main/java/com/cloud/resource/ServerResourceBase.java
diff --git a/core/src/com/cloud/resource/hypervisor/HypervisorResource.java b/core/src/main/java/com/cloud/resource/hypervisor/HypervisorResource.java
similarity index 100%
rename from core/src/com/cloud/resource/hypervisor/HypervisorResource.java
rename to core/src/main/java/com/cloud/resource/hypervisor/HypervisorResource.java
diff --git a/core/src/com/cloud/serializer/GsonHelper.java b/core/src/main/java/com/cloud/serializer/GsonHelper.java
similarity index 100%
rename from core/src/com/cloud/serializer/GsonHelper.java
rename to core/src/main/java/com/cloud/serializer/GsonHelper.java
diff --git a/core/src/com/cloud/storage/JavaStorageLayer.java b/core/src/main/java/com/cloud/storage/JavaStorageLayer.java
similarity index 100%
rename from core/src/com/cloud/storage/JavaStorageLayer.java
rename to core/src/main/java/com/cloud/storage/JavaStorageLayer.java
diff --git a/core/src/com/cloud/storage/StorageLayer.java b/core/src/main/java/com/cloud/storage/StorageLayer.java
similarity index 100%
rename from core/src/com/cloud/storage/StorageLayer.java
rename to core/src/main/java/com/cloud/storage/StorageLayer.java
diff --git a/core/src/main/java/com/cloud/storage/resource/StoragePoolResource.java b/core/src/main/java/com/cloud/storage/resource/StoragePoolResource.java
new file mode 100644
index 0000000..d8f4240
--- /dev/null
+++ b/core/src/main/java/com/cloud/storage/resource/StoragePoolResource.java
@@ -0,0 +1,36 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.storage.resource;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+
+public interface StoragePoolResource {
+    // FIXME: Should have a PrimaryStorageDownloadAnswer
+    PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd);
+
+    Answer execute(DestroyCommand cmd);
+
+    CopyVolumeAnswer execute(CopyVolumeCommand cmd);
+}
diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/main/java/com/cloud/storage/resource/StorageProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/resource/StorageProcessor.java
rename to core/src/main/java/com/cloud/storage/resource/StorageProcessor.java
diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java b/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandler.java
similarity index 100%
rename from core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java
rename to core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandler.java
diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
similarity index 100%
rename from core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
rename to core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
diff --git a/core/src/com/cloud/storage/template/FtpTemplateUploader.java b/core/src/main/java/com/cloud/storage/template/FtpTemplateUploader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/FtpTemplateUploader.java
rename to core/src/main/java/com/cloud/storage/template/FtpTemplateUploader.java
diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/HttpTemplateDownloader.java
rename to core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java
diff --git a/core/src/com/cloud/storage/template/IsoProcessor.java b/core/src/main/java/com/cloud/storage/template/IsoProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/IsoProcessor.java
rename to core/src/main/java/com/cloud/storage/template/IsoProcessor.java
diff --git a/core/src/com/cloud/storage/template/LocalTemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/LocalTemplateDownloader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/LocalTemplateDownloader.java
rename to core/src/main/java/com/cloud/storage/template/LocalTemplateDownloader.java
diff --git a/core/src/com/cloud/storage/template/MetalinkTemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/MetalinkTemplateDownloader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/MetalinkTemplateDownloader.java
rename to core/src/main/java/com/cloud/storage/template/MetalinkTemplateDownloader.java
diff --git a/core/src/com/cloud/storage/template/OVAProcessor.java b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/OVAProcessor.java
rename to core/src/main/java/com/cloud/storage/template/OVAProcessor.java
diff --git a/core/src/com/cloud/storage/template/Processor.java b/core/src/main/java/com/cloud/storage/template/Processor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/Processor.java
rename to core/src/main/java/com/cloud/storage/template/Processor.java
diff --git a/core/src/com/cloud/storage/template/QCOW2Processor.java b/core/src/main/java/com/cloud/storage/template/QCOW2Processor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/QCOW2Processor.java
rename to core/src/main/java/com/cloud/storage/template/QCOW2Processor.java
diff --git a/core/src/com/cloud/storage/template/RawImageProcessor.java b/core/src/main/java/com/cloud/storage/template/RawImageProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/RawImageProcessor.java
rename to core/src/main/java/com/cloud/storage/template/RawImageProcessor.java
diff --git a/core/src/main/java/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/S3TemplateDownloader.java
new file mode 100644
index 0000000..0506dab
--- /dev/null
+++ b/core/src/main/java/com/cloud/storage/template/S3TemplateDownloader.java
@@ -0,0 +1,376 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.storage.template;
+
+import com.amazonaws.event.ProgressEvent;
+import com.amazonaws.event.ProgressEventType;
+import com.amazonaws.event.ProgressListener;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.model.StorageClass;
+import com.amazonaws.services.s3.transfer.Upload;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.utils.net.HTTPUtils;
+import com.cloud.utils.net.Proxy;
+import com.cloud.utils.storage.S3.S3Utils;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.URIException;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import static com.cloud.utils.StringUtils.join;
+import static java.util.Arrays.asList;
+
+/**
+ * Download a template file using HTTP(S)
+ *
+ * This class, once instantiated, has the purpose to download a single Template to an S3 Image Store.
+ *
+ * Execution of the instance is started when runInContext() is called.
+ */
+public class S3TemplateDownloader extends ManagedContextRunnable implements TemplateDownloader {
+    private static final Logger LOGGER = Logger.getLogger(S3TemplateDownloader.class.getName());
+
+    private final String downloadUrl;
+    private final String s3Key;
+    private final String fileExtension;
+    private final HttpClient httpClient;
+    private final GetMethod getMethod;
+    private final DownloadCompleteCallback downloadCompleteCallback;
+    private final S3TO s3TO;
+    private String errorString = "";
+    private TemplateDownloader.Status status = TemplateDownloader.Status.NOT_STARTED;
+    private ResourceType resourceType = ResourceType.TEMPLATE;
+    private long remoteSize;
+    private long downloadTime;
+    private long totalBytes;
+    private long maxTemplateSizeInByte;
+
+    private boolean resume = false;
+
+    public S3TemplateDownloader(S3TO s3TO, String downloadUrl, String installPath, DownloadCompleteCallback downloadCompleteCallback,
+            long maxTemplateSizeInBytes, String username, String password, Proxy proxy, ResourceType resourceType) {
+        this.downloadUrl = downloadUrl;
+        this.s3TO = s3TO;
+        this.resourceType = resourceType;
+        this.maxTemplateSizeInByte = maxTemplateSizeInBytes;
+        this.httpClient = HTTPUtils.getHTTPClient();
+        this.downloadCompleteCallback = downloadCompleteCallback;
+
+        // Create a GET method for the download url.
+        this.getMethod = new GetMethod(downloadUrl);
+
+        // Set the retry handler, default to retry 5 times.
+        this.getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, HTTPUtils.getHttpMethodRetryHandler(5));
+
+        // Follow redirects
+        this.getMethod.setFollowRedirects(true);
+
+        // Set file extension.
+        this.fileExtension = StringUtils.substringAfterLast(StringUtils.substringAfterLast(downloadUrl, "/"), ".");
+
+        // Calculate and set S3 Key.
+        this.s3Key = join(asList(installPath, StringUtils.substringAfterLast(downloadUrl, "/")), S3Utils.SEPARATOR);
+
+        // Set proxy if available.
+        HTTPUtils.setProxy(proxy, this.httpClient);
+
+        // Set credentials if available.
+        HTTPUtils.setCredentials(username, password, this.httpClient);
+    }
+
+    @Override
+    public long download(boolean resume, DownloadCompleteCallback callback) {
+        if (!status.equals(Status.NOT_STARTED)) {
+            // Only start downloading if we haven't started yet.
+            LOGGER.debug("Template download is already started, not starting again. Template: " + downloadUrl);
+
+            return 0;
+        }
+
+        int responseCode;
+        if ((responseCode = HTTPUtils.executeMethod(httpClient, getMethod)) == -1) {
+            errorString = "Exception while executing HttpMethod " + getMethod.getName() + " on URL " + downloadUrl;
+            LOGGER.warn(errorString);
+
+            status = Status.UNRECOVERABLE_ERROR;
+            return 0;
+        }
+
+        if (!HTTPUtils.verifyResponseCode(responseCode)) {
+            errorString = "Response code for GetMethod of " + downloadUrl + " is incorrect, responseCode: " + responseCode;
+            LOGGER.warn(errorString);
+
+            status = Status.UNRECOVERABLE_ERROR;
+            return 0;
+        }
+
+        // Headers
+        Header contentLengthHeader = getMethod.getResponseHeader("Content-Length");
+        Header contentTypeHeader = getMethod.getResponseHeader("Content-Type");
+
+        // Check the contentLengthHeader and transferEncodingHeader.
+        if (contentLengthHeader == null) {
+            errorString = "The ContentLengthHeader of " + downloadUrl + " isn't supplied";
+            LOGGER.warn(errorString);
+
+            status = Status.UNRECOVERABLE_ERROR;
+            return 0;
+        } else {
+            // The ContentLengthHeader is supplied, parse it's value.
+            remoteSize = Long.parseLong(contentLengthHeader.getValue());
+        }
+
+        if (remoteSize > maxTemplateSizeInByte) {
+            errorString = "Remote size is too large for template " + downloadUrl + " remote size is " + remoteSize + " max allowed is " + maxTemplateSizeInByte;
+            LOGGER.warn(errorString);
+
+            status = Status.UNRECOVERABLE_ERROR;
+            return 0;
+        }
+
+        InputStream inputStream;
+
+        try {
+            inputStream = new BufferedInputStream(getMethod.getResponseBodyAsStream());
+        } catch (IOException e) {
+            errorString = "Exception occurred while opening InputStream for template " + downloadUrl;
+            LOGGER.warn(errorString);
+
+            status = Status.UNRECOVERABLE_ERROR;
+            return 0;
+        }
+
+        LOGGER.info("Starting download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " and size " + remoteSize + " bytes");
+
+        // Time the upload starts.
+        final Date start = new Date();
+
+        ObjectMetadata objectMetadata = new ObjectMetadata();
+        objectMetadata.setContentLength(remoteSize);
+
+        if (contentTypeHeader.getValue() != null) {
+            objectMetadata.setContentType(contentTypeHeader.getValue());
+        }
+
+        // Create the PutObjectRequest.
+        PutObjectRequest putObjectRequest = new PutObjectRequest(s3TO.getBucketName(), s3Key, inputStream, objectMetadata);
+
+        // If reduced redundancy is enabled, set it.
+        if (s3TO.isEnableRRS()) {
+            putObjectRequest.withStorageClass(StorageClass.ReducedRedundancy);
+        }
+
+        Upload upload = S3Utils.putObject(s3TO, putObjectRequest);
+
+        upload.addProgressListener(new ProgressListener() {
+            @Override
+            public void progressChanged(ProgressEvent progressEvent) {
+
+                // Record the amount of bytes transferred.
+                totalBytes += progressEvent.getBytesTransferred();
+
+                LOGGER.trace("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + ((new Date().getTime() - start.getTime()) / 1000) + " seconds");
+
+                if (progressEvent.getEventType() == ProgressEventType.TRANSFER_STARTED_EVENT) {
+                    status = Status.IN_PROGRESS;
+                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
+                    status = Status.DOWNLOAD_FINISHED;
+                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_CANCELED_EVENT) {
+                    status = Status.ABORTED;
+                } else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
+                    status = Status.UNRECOVERABLE_ERROR;
+                }
+            }
+        });
+
+        try {
+            // Wait for the upload to complete.
+            upload.waitForCompletion();
+        } catch (InterruptedException e) {
+            // Interruption while waiting for the upload to complete.
+            LOGGER.warn("Interruption occurred while waiting for upload of " + downloadUrl + " to complete");
+        }
+
+        downloadTime = new Date().getTime() - start.getTime();
+
+        if (status == Status.DOWNLOAD_FINISHED) {
+            LOGGER.info("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + (downloadTime / 1000) + " seconds, completed successfully!");
+        } else {
+            LOGGER.warn("Template download from " + downloadUrl + " to S3 bucket " + s3TO.getBucketName() + " transferred  " + totalBytes + " in " + (downloadTime / 1000) + " seconds, completed with status " + status.toString());
+        }
+
+        // Close input stream
+        getMethod.releaseConnection();
+
+        // Call the callback!
+        if (callback != null) {
+            callback.downloadComplete(status);
+        }
+
+        return totalBytes;
+    }
+
+    public String getDownloadUrl() {
+        try {
+            return getMethod.getURI().toString();
+        } catch (URIException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
+    }
+
+    @Override
+    public long getDownloadTime() {
+        return downloadTime;
+    }
+
+    @Override
+    public long getDownloadedBytes() {
+        return totalBytes;
+    }
+
+    /**
+     * Returns an InputStream only when the status is DOWNLOAD_FINISHED.
+     *
+     * The caller of this method must close the InputStream to prevent resource leaks!
+     *
+     * @return S3ObjectInputStream of the object.
+     */
+    public InputStream getS3ObjectInputStream() {
+        // Check if the download is finished
+        if (status != Status.DOWNLOAD_FINISHED) {
+            return null;
+        }
+
+        return S3Utils.getObjectStream(s3TO, s3TO.getBucketName(), s3Key);
+    }
+
+    public void cleanupAfterError() {
+        LOGGER.warn("Cleanup after error, trying to remove object: " + s3Key);
+
+        S3Utils.deleteObject(s3TO, s3TO.getBucketName(), s3Key);
+    }
+
+    @Override
+    public boolean stopDownload() {
+        switch (status) {
+            case IN_PROGRESS:
+                if (getMethod != null) {
+                    getMethod.abort();
+                }
+                break;
+            case UNKNOWN:
+            case NOT_STARTED:
+            case RECOVERABLE_ERROR:
+            case UNRECOVERABLE_ERROR:
+            case ABORTED:
+            case DOWNLOAD_FINISHED:
+                // Remove the object if it already has been uploaded.
+                S3Utils.deleteObject(s3TO, s3TO.getBucketName(), s3Key);
+                break;
+            default:
+                break;
+        }
+
+        status = TemplateDownloader.Status.ABORTED;
+        return true;
+    }
+
+    @Override
+    public int getDownloadPercent() {
+        if (remoteSize == 0) {
+            return 0;
+        }
+
+        return (int) (100.0 * totalBytes / remoteSize);
+    }
+
+    @Override
+    protected void runInContext() {
+        // Start the download!
+        download(resume, downloadCompleteCallback);
+    }
+
+    @Override
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public boolean isResume() {
+        return resume;
+    }
+
+    @Override
+    public String getDownloadError() {
+        return errorString;
+    }
+
+    @Override
+    public String getDownloadLocalPath() {
+        return s3Key;
+    }
+
+    @Override
+    public void setResume(boolean resume) {
+        this.resume = resume;
+    }
+
+    @Override
+    public long getMaxTemplateSizeInBytes() {
+        return maxTemplateSizeInByte;
+    }
+
+    @Override
+    public void setDownloadError(String error) {
+        errorString = error;
+    }
+
+    @Override
+    public boolean isInited() {
+        return true;
+    }
+
+    public ResourceType getResourceType() {
+        return resourceType;
+    }
+
+    public long getTotalBytes() {
+        return totalBytes;
+    }
+
+    public String getFileExtension() {
+        return fileExtension;
+    }
+}
\ No newline at end of file
diff --git a/core/src/com/cloud/storage/template/ScpTemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/ScpTemplateDownloader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/ScpTemplateDownloader.java
rename to core/src/main/java/com/cloud/storage/template/ScpTemplateDownloader.java
diff --git a/core/src/com/cloud/storage/template/TARProcessor.java b/core/src/main/java/com/cloud/storage/template/TARProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TARProcessor.java
rename to core/src/main/java/com/cloud/storage/template/TARProcessor.java
diff --git a/core/src/com/cloud/storage/template/TemplateConstants.java b/core/src/main/java/com/cloud/storage/template/TemplateConstants.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TemplateConstants.java
rename to core/src/main/java/com/cloud/storage/template/TemplateConstants.java
diff --git a/core/src/com/cloud/storage/template/TemplateDownloader.java b/core/src/main/java/com/cloud/storage/template/TemplateDownloader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TemplateDownloader.java
rename to core/src/main/java/com/cloud/storage/template/TemplateDownloader.java
diff --git a/core/src/com/cloud/storage/template/TemplateDownloaderBase.java b/core/src/main/java/com/cloud/storage/template/TemplateDownloaderBase.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TemplateDownloaderBase.java
rename to core/src/main/java/com/cloud/storage/template/TemplateDownloaderBase.java
diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/main/java/com/cloud/storage/template/TemplateLocation.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TemplateLocation.java
rename to core/src/main/java/com/cloud/storage/template/TemplateLocation.java
diff --git a/core/src/com/cloud/storage/template/TemplateUploader.java b/core/src/main/java/com/cloud/storage/template/TemplateUploader.java
similarity index 100%
rename from core/src/com/cloud/storage/template/TemplateUploader.java
rename to core/src/main/java/com/cloud/storage/template/TemplateUploader.java
diff --git a/core/src/com/cloud/storage/template/VhdProcessor.java b/core/src/main/java/com/cloud/storage/template/VhdProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/VhdProcessor.java
rename to core/src/main/java/com/cloud/storage/template/VhdProcessor.java
diff --git a/core/src/com/cloud/storage/template/VmdkProcessor.java b/core/src/main/java/com/cloud/storage/template/VmdkProcessor.java
similarity index 100%
rename from core/src/com/cloud/storage/template/VmdkProcessor.java
rename to core/src/main/java/com/cloud/storage/template/VmdkProcessor.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/CheckUrlAnswer.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/CheckUrlAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/CheckUrlAnswer.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/CheckUrlAnswer.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/CheckUrlCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/CheckUrlCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/CheckUrlCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/CheckUrlCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/DirectDownloadAnswer.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/DirectDownloadAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/DirectDownloadAnswer.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/DirectDownloadAnswer.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/DirectDownloadCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/DirectDownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/DirectDownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/DirectDownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/HttpDirectDownloadCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpDirectDownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/HttpDirectDownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpDirectDownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/HttpsDirectDownloadCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpsDirectDownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/HttpsDirectDownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpsDirectDownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/MetalinkDirectDownloadCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/MetalinkDirectDownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/MetalinkDirectDownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/MetalinkDirectDownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/NfsDirectDownloadCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/NfsDirectDownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/NfsDirectDownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/NfsDirectDownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/directdownload/SetupDirectDownloadCertificateCommand.java b/core/src/main/java/org/apache/cloudstack/agent/directdownload/SetupDirectDownloadCertificateCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/directdownload/SetupDirectDownloadCertificateCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/directdownload/SetupDirectDownloadCertificateCommand.java
diff --git a/core/src/org/apache/cloudstack/agent/lb/SetupMSListAnswer.java b/core/src/main/java/org/apache/cloudstack/agent/lb/SetupMSListAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/lb/SetupMSListAnswer.java
rename to core/src/main/java/org/apache/cloudstack/agent/lb/SetupMSListAnswer.java
diff --git a/core/src/org/apache/cloudstack/agent/lb/SetupMSListCommand.java b/core/src/main/java/org/apache/cloudstack/agent/lb/SetupMSListCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/agent/lb/SetupMSListCommand.java
rename to core/src/main/java/org/apache/cloudstack/agent/lb/SetupMSListCommand.java
diff --git a/core/src/org/apache/cloudstack/ca/PostCertificateRenewalCommand.java b/core/src/main/java/org/apache/cloudstack/ca/PostCertificateRenewalCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/ca/PostCertificateRenewalCommand.java
rename to core/src/main/java/org/apache/cloudstack/ca/PostCertificateRenewalCommand.java
diff --git a/core/src/org/apache/cloudstack/ca/SetupCertificateAnswer.java b/core/src/main/java/org/apache/cloudstack/ca/SetupCertificateAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/ca/SetupCertificateAnswer.java
rename to core/src/main/java/org/apache/cloudstack/ca/SetupCertificateAnswer.java
diff --git a/core/src/org/apache/cloudstack/ca/SetupCertificateCommand.java b/core/src/main/java/org/apache/cloudstack/ca/SetupCertificateCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/ca/SetupCertificateCommand.java
rename to core/src/main/java/org/apache/cloudstack/ca/SetupCertificateCommand.java
diff --git a/core/src/org/apache/cloudstack/ca/SetupKeyStoreCommand.java b/core/src/main/java/org/apache/cloudstack/ca/SetupKeyStoreCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/ca/SetupKeyStoreCommand.java
rename to core/src/main/java/org/apache/cloudstack/ca/SetupKeyStoreCommand.java
diff --git a/core/src/org/apache/cloudstack/ca/SetupKeystoreAnswer.java b/core/src/main/java/org/apache/cloudstack/ca/SetupKeystoreAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/ca/SetupKeystoreAnswer.java
rename to core/src/main/java/org/apache/cloudstack/ca/SetupKeystoreAnswer.java
diff --git a/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsAnswer.java b/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsAnswer.java
new file mode 100644
index 0000000..006f043
--- /dev/null
+++ b/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsAnswer.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.diagnostics;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.base.Strings;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DiagnosticsAnswer extends Answer {
+    public static final Logger LOGGER = Logger.getLogger(DiagnosticsAnswer.class);
+
+    public DiagnosticsAnswer(DiagnosticsCommand cmd, boolean result, String details) {
+        super(cmd, result, details);
+    }
+
+    public Map<String, String> getExecutionDetails() {
+        final Map<String, String> executionDetailsMap = new HashMap<>();
+        if (result == true && !Strings.isNullOrEmpty(details)) {
+            final String[] parseDetails = details.split("&&");
+            if (parseDetails.length >= 3) {
+                executionDetailsMap.put(ApiConstants.STDOUT, parseDetails[0].trim());
+                executionDetailsMap.put(ApiConstants.STDERR, parseDetails[1].trim());
+                executionDetailsMap.put(ApiConstants.EXITCODE, String.valueOf(parseDetails[2]).trim());
+            } else {
+                throw new CloudRuntimeException("Unsupported diagnostics command type supplied");
+            }
+        } else {
+            executionDetailsMap.put(ApiConstants.STDOUT, "");
+            executionDetailsMap.put(ApiConstants.STDERR, details);
+            executionDetailsMap.put(ApiConstants.EXITCODE, "-1");
+        }
+        return executionDetailsMap;
+    }
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsCommand.java b/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsCommand.java
new file mode 100644
index 0000000..14d9da9
--- /dev/null
+++ b/core/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsCommand.java
@@ -0,0 +1,44 @@
+// 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.diagnostics;
+
+import com.cloud.agent.api.routing.NetworkElementCommand;
+
+public class DiagnosticsCommand extends NetworkElementCommand {
+
+    private final String scriptArguments;
+    private final boolean executeInSequence;
+
+    public DiagnosticsCommand(String scriptArguments, boolean executeInSequence) {
+        this.scriptArguments = scriptArguments;
+        this.executeInSequence = executeInSequence;
+    }
+
+    public String getSrciptArguments() {
+        return scriptArguments;
+    }
+
+    @Override
+    public boolean isQuery() {
+        return true;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return this.executeInSequence;
+    }
+}
\ No newline at end of file
diff --git a/core/src/org/apache/cloudstack/storage/command/AttachAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/AttachAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/AttachAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/AttachAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/AttachCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/AttachCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/AttachCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/AttachCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/core/src/main/java/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java
diff --git a/core/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/CopyCmdAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/CopyCmdAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/CopyCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/CopyCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/CopyCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/CreateObjectAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/CreateObjectCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/CreateObjectCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/core/src/main/java/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java
diff --git a/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/DeleteCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/DeleteCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/DeleteCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/DettachAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/DettachAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/DettachAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/DettachAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/DettachCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/DettachCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/DettachCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/DettachCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/DownloadCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/DownloadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/DownloadCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/DownloadCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/DownloadProgressCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/DownloadProgressCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java b/core/src/main/java/org/apache/cloudstack/storage/command/ForgetObjectCmd.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/ForgetObjectCmd.java
diff --git a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/IntroduceObjectAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/IntroduceObjectAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/IntroduceObjectAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java b/core/src/main/java/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java
diff --git a/core/src/org/apache/cloudstack/storage/command/ResignatureAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/ResignatureAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/ResignatureAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/ResignatureAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/ResignatureCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/ResignatureCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/ResignatureCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/ResignatureCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/RevertSnapshotCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/RevertSnapshotCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/RevertSnapshotCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/RevertSnapshotCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/SnapshotAndCopyAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/SnapshotAndCopyAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/UploadStatusAnswer.java
diff --git a/core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/UploadStatusCommand.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/command/UploadStatusCommand.java
rename to core/src/main/java/org/apache/cloudstack/storage/command/UploadStatusCommand.java
diff --git a/core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/ImageStoreTO.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/to/ImageStoreTO.java
rename to core/src/main/java/org/apache/cloudstack/storage/to/ImageStoreTO.java
diff --git a/core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
rename to core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
diff --git a/core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
rename to core/src/main/java/org/apache/cloudstack/storage/to/SnapshotObjectTO.java
diff --git a/core/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java
similarity index 100%
rename from core/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java
rename to core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java
diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java
new file mode 100644
index 0000000..2d240c4
--- /dev/null
+++ b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java
@@ -0,0 +1,303 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.storage.to;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.offering.DiskOffering.DiskCacheMode;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Volume;
+
+public class VolumeObjectTO implements DataTO {
+    private String uuid;
+    private Volume.Type volumeType;
+    private DataStoreTO dataStore;
+    private String name;
+    private Long size;
+    private String path;
+    private Long volumeId;
+    private String vmName;
+    private long accountId;
+    private String chainInfo;
+    private Storage.ImageFormat format;
+    private Storage.ProvisioningType provisioningType;
+    private long id;
+
+    private Long deviceId;
+    private Long bytesReadRate;
+    private Long bytesReadRateMax;
+    private Long bytesReadRateMaxLength;
+    private Long bytesWriteRate;
+    private Long bytesWriteRateMax;
+    private Long bytesWriteRateMaxLength;
+    private Long iopsReadRate;
+    private Long iopsReadRateMax;
+    private Long iopsReadRateMaxLength;
+    private Long iopsWriteRate;
+    private Long iopsWriteRateMax;
+    private Long iopsWriteRateMaxLength;
+    private DiskCacheMode cacheMode;
+    private Hypervisor.HypervisorType hypervisorType;
+
+    public VolumeObjectTO() {
+
+    }
+
+    public VolumeObjectTO(VolumeInfo volume) {
+        uuid = volume.getUuid();
+        path = volume.getPath();
+        accountId = volume.getAccountId();
+        if (volume.getDataStore() != null) {
+            dataStore = volume.getDataStore().getTO();
+        } else {
+            dataStore = null;
+        }
+        vmName = volume.getAttachedVmName();
+        size = volume.getSize();
+        setVolumeId(volume.getId());
+        chainInfo = volume.getChainInfo();
+        volumeType = volume.getVolumeType();
+        name = volume.getName();
+        setId(volume.getId());
+        format = volume.getFormat();
+        provisioningType = volume.getProvisioningType();
+        bytesReadRate = volume.getBytesReadRate();
+        bytesReadRateMax = volume.getBytesReadRateMax();
+        bytesReadRateMaxLength = volume.getBytesReadRateMaxLength();
+        bytesWriteRate = volume.getBytesWriteRate();
+        bytesWriteRateMax = volume.getBytesWriteRateMax();
+        bytesWriteRateMaxLength = volume.getBytesWriteRateMaxLength();
+        iopsReadRate = volume.getIopsReadRate();
+        iopsReadRateMax = volume.getIopsReadRateMax();
+        iopsReadRateMaxLength = volume.getIopsReadRateMaxLength();
+        iopsWriteRate = volume.getIopsWriteRate();
+        iopsWriteRateMax = volume.getIopsWriteRateMax();
+        iopsWriteRateMaxLength = volume.getIopsWriteRateMaxLength();
+        cacheMode = volume.getCacheMode();
+        hypervisorType = volume.getHypervisorType();
+        setDeviceId(volume.getDeviceId());
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    @Override
+    public String getPath() {
+        return path;
+    }
+
+    public Volume.Type getVolumeType() {
+        return volumeType;
+    }
+
+    @Override
+    public DataStoreTO getDataStore() {
+        return dataStore;
+    }
+
+    @Override
+    public Hypervisor.HypervisorType getHypervisorType() {
+        return hypervisorType;
+    }
+
+    public void setDataStore(DataStoreTO store) {
+        dataStore = store;
+    }
+
+    public void setDataStore(PrimaryDataStoreTO dataStore) {
+        this.dataStore = dataStore;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    @Override
+    public DataObjectType getObjectType() {
+        return DataObjectType.VOLUME;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setSize(long size) {
+        this.size = size;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public Long getVolumeId() {
+        return volumeId;
+    }
+
+    public void setVolumeId(Long volumeId) {
+        this.volumeId = volumeId;
+    }
+
+    public long getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    public String getVmName() {
+        return vmName;
+    }
+
+    public void setVmName(String vmName) {
+        this.vmName = vmName;
+    }
+
+    public String getChainInfo() {
+        return chainInfo;
+    }
+
+    public void setChainInfo(String chainInfo) {
+        this.chainInfo = chainInfo;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public Storage.ImageFormat getFormat() {
+        return format;
+    }
+
+    public void setFormat(Storage.ImageFormat format) {
+        this.format = format;
+    }
+
+    public Storage.ProvisioningType getProvisioningType(){
+        return provisioningType;
+    }
+
+    public void setProvisioningType(Storage.ProvisioningType provisioningType){
+        this.provisioningType = provisioningType;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("volumeTO[uuid=").append(uuid).append("|path=").append(path).append("|datastore=").append(dataStore).append("]").toString();
+    }
+
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public Long getBytesReadRateMax() { return bytesReadRateMax; }
+
+    public void setBytesReadRateMax(Long bytesReadRateMax) { this.bytesReadRateMax = bytesReadRateMax; }
+
+    public Long getBytesReadRateMaxLength() { return bytesReadRateMaxLength; }
+
+    public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) { this.bytesReadRateMaxLength = bytesReadRateMaxLength; }
+
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public Long getBytesWriteRateMax() { return bytesWriteRateMax; }
+
+    public void setBytesWriteRateMax(Long bytesWriteRateMax) { this.bytesWriteRateMax = bytesWriteRateMax; }
+
+    public Long getBytesWriteRateMaxLength() { return bytesWriteRateMaxLength; }
+
+    public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) { this.bytesWriteRateMaxLength = bytesWriteRateMaxLength; }
+
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public Long getIopsReadRateMax() { return iopsReadRateMax; }
+
+    public void setIopsReadRateMax(Long iopsReadRateMax) { this.iopsReadRateMax = iopsReadRateMax; }
+
+    public Long getIopsReadRateMaxLength() { return iopsReadRateMaxLength; }
+
+    public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) { this.iopsReadRateMaxLength = iopsReadRateMaxLength; }
+
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public Long getIopsWriteRateMax() { return iopsWriteRateMax; }
+
+    public void setIopsWriteRateMax(Long iopsWriteRateMax) { this.iopsWriteRateMax = iopsWriteRateMax; }
+
+    public Long getIopsWriteRateMaxLength() { return iopsWriteRateMaxLength; }
+
+    public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) { this.iopsWriteRateMaxLength = iopsWriteRateMaxLength; }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(Long deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public void setCacheMode(DiskCacheMode cacheMode) {
+        this.cacheMode = cacheMode;
+    }
+
+    public DiskCacheMode getCacheMode() {
+        return cacheMode;
+    }
+}
diff --git a/core/resources/META-INF/cloudstack/allocator/module.properties b/core/src/main/resources/META-INF/cloudstack/allocator/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/allocator/module.properties
rename to core/src/main/resources/META-INF/cloudstack/allocator/module.properties
diff --git a/core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml b/core/src/main/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml
rename to core/src/main/resources/META-INF/cloudstack/allocator/spring-core-allocator-context.xml
diff --git a/core/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/allocator/spring-core-lifecycle-allocator-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/api/module.properties b/core/src/main/resources/META-INF/cloudstack/api/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/api/module.properties
rename to core/src/main/resources/META-INF/cloudstack/api/module.properties
diff --git a/core/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/api/spring-core-lifecycle-api-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/backend/module.properties b/core/src/main/resources/META-INF/cloudstack/backend/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/backend/module.properties
rename to core/src/main/resources/META-INF/cloudstack/backend/module.properties
diff --git a/core/resources/META-INF/cloudstack/bootstrap/module.properties b/core/src/main/resources/META-INF/cloudstack/bootstrap/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/bootstrap/module.properties
rename to core/src/main/resources/META-INF/cloudstack/bootstrap/module.properties
diff --git a/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml b/core/src/main/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml
rename to core/src/main/resources/META-INF/cloudstack/bootstrap/spring-bootstrap-context.xml
diff --git a/core/resources/META-INF/cloudstack/ca/module.properties b/core/src/main/resources/META-INF/cloudstack/ca/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/ca/module.properties
rename to core/src/main/resources/META-INF/cloudstack/ca/module.properties
diff --git a/core/resources/META-INF/cloudstack/ca/spring-core-lifecycle-ca-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/ca/spring-core-lifecycle-ca-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/ca/spring-core-lifecycle-ca-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/ca/spring-core-lifecycle-ca-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/direct-download/module.properties b/core/src/main/resources/META-INF/cloudstack/cloudstack/direct-download/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/direct-download/module.properties
rename to core/src/main/resources/META-INF/cloudstack/cloudstack/direct-download/module.properties
diff --git a/core/resources/META-INF/cloudstack/direct-download/spring-lifecycle-direct-download-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/cloudstack/direct-download/spring-lifecycle-direct-download-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/direct-download/spring-lifecycle-direct-download-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/cloudstack/direct-download/spring-lifecycle-direct-download-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/compute/module.properties b/core/src/main/resources/META-INF/cloudstack/compute/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/compute/module.properties
rename to core/src/main/resources/META-INF/cloudstack/compute/module.properties
diff --git a/core/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/compute/spring-core-lifecycle-compute-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/core/module.properties b/core/src/main/resources/META-INF/cloudstack/core/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/core/module.properties
rename to core/src/main/resources/META-INF/cloudstack/core/module.properties
diff --git a/core/resources/META-INF/cloudstack/core/spring-core-context.xml b/core/src/main/resources/META-INF/cloudstack/core/spring-core-context.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/core/spring-core-context.xml
rename to core/src/main/resources/META-INF/cloudstack/core/spring-core-context.xml
diff --git a/core/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/core/spring-core-lifecycle-core-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
rename to core/src/main/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
diff --git a/core/resources/META-INF/cloudstack/discoverer/module.properties b/core/src/main/resources/META-INF/cloudstack/discoverer/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/discoverer/module.properties
rename to core/src/main/resources/META-INF/cloudstack/discoverer/module.properties
diff --git a/core/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/discoverer/spring-core-lifecycle-discoverer-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/network/module.properties b/core/src/main/resources/META-INF/cloudstack/network/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/network/module.properties
rename to core/src/main/resources/META-INF/cloudstack/network/module.properties
diff --git a/core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/network/spring-core-lifecycle-network-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/outofbandmanagement/module.properties b/core/src/main/resources/META-INF/cloudstack/outofbandmanagement/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/outofbandmanagement/module.properties
rename to core/src/main/resources/META-INF/cloudstack/outofbandmanagement/module.properties
diff --git a/core/resources/META-INF/cloudstack/outofbandmanagement/spring-core-lifecycle-outofbandmanagement-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/outofbandmanagement/spring-core-lifecycle-outofbandmanagement-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/outofbandmanagement/spring-core-lifecycle-outofbandmanagement-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/outofbandmanagement/spring-core-lifecycle-outofbandmanagement-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/planner/module.properties b/core/src/main/resources/META-INF/cloudstack/planner/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/planner/module.properties
rename to core/src/main/resources/META-INF/cloudstack/planner/module.properties
diff --git a/core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/planner/spring-core-lifecycle-planner-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/storage/module.properties b/core/src/main/resources/META-INF/cloudstack/storage/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/storage/module.properties
rename to core/src/main/resources/META-INF/cloudstack/storage/module.properties
diff --git a/core/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/storage/spring-lifecycle-storage-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/system/module.properties b/core/src/main/resources/META-INF/cloudstack/system/module.properties
similarity index 100%
rename from core/resources/META-INF/cloudstack/system/module.properties
rename to core/src/main/resources/META-INF/cloudstack/system/module.properties
diff --git a/core/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml b/core/src/main/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml
rename to core/src/main/resources/META-INF/cloudstack/system/spring-core-system-context-inheritable.xml
diff --git a/core/resources/META-INF/cloudstack/system/spring-core-system-context.xml b/core/src/main/resources/META-INF/cloudstack/system/spring-core-system-context.xml
similarity index 100%
rename from core/resources/META-INF/cloudstack/system/spring-core-system-context.xml
rename to core/src/main/resources/META-INF/cloudstack/system/spring-core-system-context.xml
diff --git a/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
deleted file mode 100644
index 509cc3a..0000000
--- a/core/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java
+++ /dev/null
@@ -1,255 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package org.apache.cloudstack.storage.to;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.offering.DiskOffering.DiskCacheMode;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Volume;
-
-public class VolumeObjectTO implements DataTO {
-    private String uuid;
-    private Volume.Type volumeType;
-    private DataStoreTO dataStore;
-    private String name;
-    private Long size;
-    private String path;
-    private Long volumeId;
-    private String vmName;
-    private long accountId;
-    private String chainInfo;
-    private Storage.ImageFormat format;
-    private Storage.ProvisioningType provisioningType;
-    private long id;
-
-    private Long deviceId;
-    private Long bytesReadRate;
-    private Long bytesWriteRate;
-    private Long iopsReadRate;
-    private Long iopsWriteRate;
-    private DiskCacheMode cacheMode;
-    private Hypervisor.HypervisorType hypervisorType;
-
-    public VolumeObjectTO() {
-
-    }
-
-    public VolumeObjectTO(VolumeInfo volume) {
-        uuid = volume.getUuid();
-        path = volume.getPath();
-        accountId = volume.getAccountId();
-        if (volume.getDataStore() != null) {
-            dataStore = volume.getDataStore().getTO();
-        } else {
-            dataStore = null;
-        }
-        vmName = volume.getAttachedVmName();
-        size = volume.getSize();
-        setVolumeId(volume.getId());
-        chainInfo = volume.getChainInfo();
-        volumeType = volume.getVolumeType();
-        name = volume.getName();
-        setId(volume.getId());
-        format = volume.getFormat();
-        provisioningType = volume.getProvisioningType();
-        bytesReadRate = volume.getBytesReadRate();
-        bytesWriteRate = volume.getBytesWriteRate();
-        iopsReadRate = volume.getIopsReadRate();
-        iopsWriteRate = volume.getIopsWriteRate();
-        cacheMode = volume.getCacheMode();
-        hypervisorType = volume.getHypervisorType();
-        setDeviceId(volume.getDeviceId());
-    }
-
-    public String getUuid() {
-        return uuid;
-    }
-
-    @Override
-    public String getPath() {
-        return path;
-    }
-
-    public Volume.Type getVolumeType() {
-        return volumeType;
-    }
-
-    @Override
-    public DataStoreTO getDataStore() {
-        return dataStore;
-    }
-
-    @Override
-    public Hypervisor.HypervisorType getHypervisorType() {
-        return hypervisorType;
-    }
-
-    public void setDataStore(DataStoreTO store) {
-        dataStore = store;
-    }
-
-    public void setDataStore(PrimaryDataStoreTO dataStore) {
-        this.dataStore = dataStore;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    @Override
-    public DataObjectType getObjectType() {
-        return DataObjectType.VOLUME;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setSize(long size) {
-        this.size = size;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public void setVolumeId(Long volumeId) {
-        this.volumeId = volumeId;
-    }
-
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(long accountId) {
-        this.accountId = accountId;
-    }
-
-    public String getVmName() {
-        return vmName;
-    }
-
-    public void setVmName(String vmName) {
-        this.vmName = vmName;
-    }
-
-    public String getChainInfo() {
-        return chainInfo;
-    }
-
-    public void setChainInfo(String chainInfo) {
-        this.chainInfo = chainInfo;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public Storage.ImageFormat getFormat() {
-        return format;
-    }
-
-    public void setFormat(Storage.ImageFormat format) {
-        this.format = format;
-    }
-
-    public Storage.ProvisioningType getProvisioningType(){
-        return provisioningType;
-    }
-
-    public void setProvisioningType(Storage.ProvisioningType provisioningType){
-        this.provisioningType = provisioningType;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("volumeTO[uuid=").append(uuid).append("|path=").append(path).append("|datastore=").append(dataStore).append("]").toString();
-    }
-
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public Long getDeviceId() {
-        return deviceId;
-    }
-
-    public void setDeviceId(Long deviceId) {
-        this.deviceId = deviceId;
-    }
-
-    public void setCacheMode(DiskCacheMode cacheMode) {
-        this.cacheMode = cacheMode;
-    }
-
-    public DiskCacheMode getCacheMode() {
-        return cacheMode;
-    }
-}
diff --git a/core/test/com/cloud/agent/api/SecurityGroupRulesCmdTest.java b/core/src/test/java/com/cloud/agent/api/SecurityGroupRulesCmdTest.java
similarity index 100%
rename from core/test/com/cloud/agent/api/SecurityGroupRulesCmdTest.java
rename to core/src/test/java/com/cloud/agent/api/SecurityGroupRulesCmdTest.java
diff --git a/core/test/com/cloud/agent/api/routing/SetNetworkACLCommandTest.java b/core/src/test/java/com/cloud/agent/api/routing/SetNetworkACLCommandTest.java
similarity index 100%
rename from core/test/com/cloud/agent/api/routing/SetNetworkACLCommandTest.java
rename to core/src/test/java/com/cloud/agent/api/routing/SetNetworkACLCommandTest.java
diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/ConfigHelperTest.java b/core/src/test/java/com/cloud/agent/resource/virtualnetwork/ConfigHelperTest.java
similarity index 100%
rename from core/test/com/cloud/agent/resource/virtualnetwork/ConfigHelperTest.java
rename to core/src/test/java/com/cloud/agent/resource/virtualnetwork/ConfigHelperTest.java
diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
similarity index 100%
rename from core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
rename to core/src/test/java/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/src/test/java/com/cloud/agent/transport/RequestTest.java
similarity index 100%
rename from core/test/com/cloud/agent/transport/RequestTest.java
rename to core/src/test/java/com/cloud/agent/transport/RequestTest.java
diff --git a/core/src/test/java/com/cloud/info/ConsoleProxyInfoTest.java b/core/src/test/java/com/cloud/info/ConsoleProxyInfoTest.java
new file mode 100644
index 0000000..62a4b76
--- /dev/null
+++ b/core/src/test/java/com/cloud/info/ConsoleProxyInfoTest.java
@@ -0,0 +1,64 @@
+//
+// 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.info;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConsoleProxyInfoTest {
+
+    @Test
+    public void testGetProxyImageUrlHttps() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(true, "10.10.10.10", 443, 443 , "console.example.com");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("https://console.example.com", url);
+    }
+    @Test
+    public void testGetProxyImageUrlHttp() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(false, "10.10.10.10", 80, 80 , "console.example.com");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("http://console.example.com", url);
+    }
+    @Test
+    public void testGetProxyImageUrlWildcardHttps() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(true, "1.2.3.4", 443, 8443 , "*.example.com");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("https://1-2-3-4.example.com:8443", url);
+    }
+    @Test
+    public void testGetProxyImageUrlWildcardHttp() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(false, "1.2.3.4", 80, 8888 , "*.example.com");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("http://1-2-3-4.example.com:8888", url);
+    }
+    @Test
+    public void testGetProxyImageUrlIpHttp() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(false, "1.2.3.4", 80, 8888, "");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("http://1.2.3.4:8888", url);
+    }
+    @Test
+    public void testGetProxyImageUrlIpHttps() {
+        ConsoleProxyInfo cpi = new ConsoleProxyInfo(true, "1.2.3.4", 80, 8443, "");
+        String url = cpi.getProxyImageUrl();
+        assertEquals("https://1.2.3.4:8443", url);
+    }
+}
\ No newline at end of file
diff --git a/core/test/com/cloud/network/HAProxyConfiguratorTest.java b/core/src/test/java/com/cloud/network/HAProxyConfiguratorTest.java
similarity index 100%
rename from core/test/com/cloud/network/HAProxyConfiguratorTest.java
rename to core/src/test/java/com/cloud/network/HAProxyConfiguratorTest.java
diff --git a/core/test/com/cloud/storage/template/LocalTemplateDownloaderTest.java b/core/src/test/java/com/cloud/storage/template/LocalTemplateDownloaderTest.java
similarity index 100%
rename from core/test/com/cloud/storage/template/LocalTemplateDownloaderTest.java
rename to core/src/test/java/com/cloud/storage/template/LocalTemplateDownloaderTest.java
diff --git a/core/test/com/cloud/storage/template/OVAProcessorTest.java b/core/src/test/java/com/cloud/storage/template/OVAProcessorTest.java
similarity index 100%
rename from core/test/com/cloud/storage/template/OVAProcessorTest.java
rename to core/src/test/java/com/cloud/storage/template/OVAProcessorTest.java
diff --git a/core/test/com/cloud/storage/template/QCOW2ProcessorTest.java b/core/src/test/java/com/cloud/storage/template/QCOW2ProcessorTest.java
similarity index 100%
rename from core/test/com/cloud/storage/template/QCOW2ProcessorTest.java
rename to core/src/test/java/com/cloud/storage/template/QCOW2ProcessorTest.java
diff --git a/core/test/com/cloud/storage/template/VhdProcessorTest.java b/core/src/test/java/com/cloud/storage/template/VhdProcessorTest.java
similarity index 100%
rename from core/test/com/cloud/storage/template/VhdProcessorTest.java
rename to core/src/test/java/com/cloud/storage/template/VhdProcessorTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/AgentControlAnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/AgentControlCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/AnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/AnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/AttachIsoCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotAnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/BumpUpPriorityCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CancelCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CancelCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CancelCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/ChangeAgentAnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/ChangeAgentCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CheckHealthAnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CheckHealthCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/CheckOnHostCommandTest.java
diff --git a/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
similarity index 100%
rename from core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
rename to core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
diff --git a/core/test/resources/vhds/test.vhd b/core/src/test/resources/vhds/test.vhd
similarity index 100%
rename from core/test/resources/vhds/test.vhd
rename to core/src/test/resources/vhds/test.vhd
Binary files differ
diff --git a/core/test/resources/vhds/test.vhd.bz2 b/core/src/test/resources/vhds/test.vhd.bz2
similarity index 100%
rename from core/test/resources/vhds/test.vhd.bz2
rename to core/src/test/resources/vhds/test.vhd.bz2
Binary files differ
diff --git a/core/test/resources/vhds/test.vhd.gz b/core/src/test/resources/vhds/test.vhd.gz
similarity index 100%
rename from core/test/resources/vhds/test.vhd.gz
rename to core/src/test/resources/vhds/test.vhd.gz
Binary files differ
diff --git a/core/test/resources/vhds/test.vhd.zip b/core/src/test/resources/vhds/test.vhd.zip
similarity index 100%
rename from core/test/resources/vhds/test.vhd.zip
rename to core/src/test/resources/vhds/test.vhd.zip
Binary files differ
diff --git a/debian/changelog b/debian/changelog
index aa71b34..52a2ee4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,38 +1,14 @@
-cloudstack (4.11.4.0-SNAPSHOT) unstable; urgency=low
+cloudstack (4.12.0.0) unstable; urgency=low
 
-  * Update the version to 4.11.4.0-SNAPSHOT
+  * Update the version to 4.12.0.0
 
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Tue, 25 Jun 2019 20:45:11 +0100
+ -- the Apache CloudStack project <dev@cloudstack.apache.org>  Thu, 14 Mar 2019 10:11:46 -0300
 
-cloudstack (4.11.4.0-SNAPSHOT) unstable; urgency=low
+cloudstack (4.12.0.0-SNAPSHOT) unstable; urgency=low
 
-  * Update the version to 4.11.4.0-SNAPSHOT
+  * Update the version to 4.12.0.0-SNAPSHOT
 
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Mon, 10 Jun 2019 16:15:05 +0100
-
-cloudstack (4.11.4.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low
-
-  * Update the version to 4.11.4.0-SNAPSHOT-SNAPSHOT
-
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Thu, 26 Jun 2018 18:24:36 +0100
-
-cloudstack (4.11.1.0) unstable; urgency=low
-
-  * Update the version to 4.11.1.0
-
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Thu, 21 Jun 2018 15:52:43 +0100
-
-cloudstack (4.11.1.0-SNAPSHOT) unstable; urgency=low
-
-  * Update the version to 4.11.1.0-SNAPSHOT
-
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Mon, 05 Feb 2018 11:10:37 +0100
-
-cloudstack (4.11.0.0) unstable; urgency=low
-
-  * Update the version to 4.11.0.0
-
- -- the Apache CloudStack project <dev@cloudstack.apache.org>  Fri, 26 Jan 2018 13:13:37 +0100
+ -- the Apache CloudStack project <dev@cloudstack.apache.org>  Mon, 15 Jan 2018 17:42:30 +0530
 
 cloudstack (4.11.0.0-SNAPSHOT) unstable; urgency=low
 
@@ -40,7 +16,7 @@
 
  -- the Apache CloudStack project <dev@cloudstack.apache.org>  Mon, 03 Jul 2017 10:06:42 +0530
 
-cloudstack (4.11.0.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low
+cloudstack (4.10.0.0-SNAPSHOT) unstable; urgency=low
 
   * Update the version to 4.10.0.snapshot
 
diff --git a/debian/cloudstack-agent.install b/debian/cloudstack-agent.install
index 184d922..60f4237 100644
--- a/debian/cloudstack-agent.install
+++ b/debian/cloudstack-agent.install
@@ -21,7 +21,6 @@
 /etc/default/cloudstack-agent
 /etc/profile.d/cloudstack-agent-profile.sh
 /etc/logrotate.d/cloudstack-agent
-/etc/init.d/cloudstack-agent
 /usr/bin/cloudstack-setup-agent
 /usr/bin/cloudstack-ssh
 /usr/bin/cloudstack-agent-upgrade
diff --git a/debian/cloudstack-management.install b/debian/cloudstack-management.install
index bb241fb..289a495 100644
--- a/debian/cloudstack-management.install
+++ b/debian/cloudstack-management.install
@@ -22,7 +22,6 @@
 /etc/cloudstack/management/java.security.ciphers
 /etc/cloudstack/management/log4j-cloud.xml
 /etc/default/cloudstack-management
-/etc/init.d/cloudstack-management
 /etc/security/limits.d/cloudstack-limits.conf
 /etc/sudoers.d/cloudstack
 /var/cache/cloudstack/management
diff --git a/debian/cloudstack-usage.install b/debian/cloudstack-usage.install
index c0cc95a..6fa9f60 100644
--- a/debian/cloudstack-usage.install
+++ b/debian/cloudstack-usage.install
@@ -17,6 +17,5 @@
 
 /usr/share/cloudstack-usage/lib/*
 /usr/share/cloudstack-usage/plugins
-/etc/init.d/cloudstack-usage
 /etc/cloudstack/usage/*
 /etc/default/cloudstack-usage
diff --git a/debian/control b/debian/control
index b444cfa..7ef3c1e 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@
 Section: libs
 Priority: extra
 Maintainer: Wido den Hollander <wido@widodh.nl>
-Build-Depends: debhelper (>= 9), openjdk-8-jdk | java8-sdk | java8-jdk, genisoimage,
+Build-Depends: debhelper (>= 9), openjdk-8-jdk | java8-sdk | java8-jdk | openjdk-9-jdk, genisoimage,
  python-mysql.connector, maven (>= 3) | maven3, python (>= 2.7), lsb-release, dh-systemd, python-setuptools
 Standards-Version: 3.8.1
 Homepage: http://www.cloudstack.org/
@@ -15,14 +15,14 @@
 
 Package: cloudstack-management
 Architecture: all
-Depends: ${python:Depends}, openjdk-8-jre-headless | java8-runtime-headless | java8-runtime, cloudstack-common (= ${source:Version}), sudo, jsvc, python-mysql.connector, libmysql-java, augeas-tools, mysql-client, adduser, bzip2, ipmitool, lsb-release, init-system-helpers (>= 1.14~)
+Depends: ${python:Depends}, openjdk-8-jre-headless | java8-runtime-headless | java8-runtime | openjdk-9-jre-headless, cloudstack-common (= ${source:Version}), sudo, python-mysql.connector, libmysql-java, augeas-tools, mysql-client, adduser, bzip2, ipmitool, lsb-release, init-system-helpers (>= 1.14~)
 Conflicts: cloud-server, cloud-client, cloud-client-ui
 Description: CloudStack server library
  The CloudStack management server
 
 Package: cloudstack-agent
 Architecture: all
-Depends: ${python:Depends}, openjdk-8-jre-headless | java8-runtime-headless | java8-runtime, cloudstack-common (= ${source:Version}), lsb-base (>= 4.0), libcommons-daemon-java, openssh-client, qemu-kvm (>= 1.0), libvirt-bin (>= 1.2.2), uuid-runtime, iproute2, ebtables, vlan, jsvc, ipset, python-libvirt, ethtool, iptables, lsb-release, init-system-helpers (>= 1.14~), aria2
+Depends: ${python:Depends}, openjdk-8-jre-headless | java8-runtime-headless | java8-runtime | openjdk-9-jre-headless, cloudstack-common (= ${source:Version}), lsb-base (>= 9), libcommons-daemon-java, openssh-client, qemu-kvm (>= 2.5), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), uuid-runtime, iproute2, ebtables, vlan, ipset, python-libvirt, ethtool, iptables, lsb-release, aria2
 Recommends: init-system-helpers
 Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
 Description: CloudStack agent
@@ -32,7 +32,7 @@
 
 Package: cloudstack-usage
 Architecture: all
-Depends: openjdk-8-jre-headless | java8-runtime-headless | java8-runtime, cloudstack-common (= ${source:Version}), jsvc, libmysql-java, init-system-helpers (>= 1.14~)
+Depends: openjdk-8-jre-headless | java8-runtime-headless | java8-runtime | openjdk-9-jre-headless, cloudstack-common (= ${source:Version}), libmysql-java, init-system-helpers
 Description: CloudStack usage monitor
  The CloudStack usage monitor provides usage accounting across the entire cloud for
  cloud operators to charge based on usage parameters.
diff --git a/debian/rules b/debian/rules
index a41b3f9..07f5715 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,6 +1,6 @@
 #!/usr/bin/make -f
 # -*- makefile -*-
-VERSION := $(shell grep '^  <version>' pom.xml| cut -d'>' -f2 |cut -d'<' -f1)
+VERSION := $(shell grep '<version>' pom.xml | head -2 | tail -1 | cut -d'>' -f2 |cut -d'<' -f1)
 PACKAGE = $(shell dh_listpackages|head -n 1|cut -d '-' -f 1)
 SYSCONFDIR = "/etc"
 DESTDIR = "debian/tmp"
@@ -25,7 +25,6 @@
 override_dh_auto_install:
 	# Common packages
 	mkdir -p $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)
-	mkdir -p $(DESTDIR)/$(SYSCONFDIR)/init.d
 	mkdir -p $(DESTDIR)/$(SYSCONFDIR)/default
 
 	mkdir -p $(DESTDIR)/var/cache/$(PACKAGE)
@@ -43,11 +42,7 @@
 	install -D plugins/hypervisors/kvm/target/cloud-plugin-hypervisor-kvm-$(VERSION).jar $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/
 	install -D plugins/hypervisors/kvm/target/dependencies/* $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/
 
-	install -m0755 packaging/debian/$(PACKAGE)-agent.init $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-agent
 	install -d -m0755 debian/$(PACKAGE)-agent/lib/systemd/system
-	# Fix libvirt service name for Debian/Ubuntu
-	sed -i 's/Requires=libvirtd.service/Requires=libvirt-bin.service/g' packaging/systemd/$(PACKAGE)-agent.service
-	sed -i 's/After=libvirtd.service/After=libvirt-bin.service/g' packaging/systemd/$(PACKAGE)-agent.service
 	install -m0644 packaging/systemd/$(PACKAGE)-agent.service debian/$(PACKAGE)-agent/lib/systemd/system/$(PACKAGE)-agent.service
 	install -m0644 packaging/systemd/$(PACKAGE)-agent.default $(DESTDIR)/$(SYSCONFDIR)/default/$(PACKAGE)-agent
 
@@ -85,7 +80,6 @@
 	mv $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/server/cloudstack-sudoers $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/$(PACKAGE)
 	chmod 0440 $(DESTDIR)/$(SYSCONFDIR)/sudoers.d/$(PACKAGE)
 
-	install -D packaging/debian/init/cloud-management $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-management
 	install -D client/target/utilities/bin/cloud-update-xenserver-licenses $(DESTDIR)/usr/bin/cloudstack-update-xenserver-licenses
 	# Remove configuration in /ur/share/cloudstack-management/webapps/client/WEB-INF
 	# This should all be in /etc/cloudstack/management
@@ -130,7 +124,6 @@
 	cp usage/target/transformed/db.properties $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/usage/
 	cp usage/target/transformed/log4j-cloud_usage.xml $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/usage/log4j-cloud.xml
 
-	install -D -m0755 packaging/debian/$(PACKAGE)-usage.init $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-usage
 	install -d -m0755 debian/$(PACKAGE)-usage/lib/systemd/system
 	install -m0644 packaging/systemd/$(PACKAGE)-usage.service debian/$(PACKAGE)-usage/lib/systemd/system/$(PACKAGE)-usage.service
 	install -m0644 packaging/systemd/$(PACKAGE)-usage.default $(DESTDIR)/$(SYSCONFDIR)/default/$(PACKAGE)-usage
@@ -143,9 +136,6 @@
 	mkdir -p $(DESTDIR)/usr/share/$(PACKAGE)-integration-tests
 	cp -r test/integration/* $(DESTDIR)/usr/share/$(PACKAGE)-integration-tests/
 
-override_dh_installinit:
-	dh_installinit -pcloudstack-management -pcloudstack-agent -pcloudstack-usage --onlyscripts --no-start
-
 override_dh_systemd_enable:
 	dh_systemd_enable -pcloudstack-management -pcloudstack-agent -pcloudstack-usage
 
diff --git a/deps/install-non-oss.sh b/deps/install-non-oss.sh
index ee7482d..632e718 100755
--- a/deps/install-non-oss.sh
+++ b/deps/install-non-oss.sh
@@ -24,11 +24,6 @@
 # Version: unknown
 mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx   -Dversion=1.0   -Dpackaging=jar
 
-# From http://support.netapp.com/  (not available online, contact your support representative)
-# Version: 4.0
-if [ -e cloud-manageontap.jar ]; then mv cloud-manageontap.jar manageontap.jar;  fi
-mvn install:install-file -Dfile=manageontap.jar   -DgroupId=com.cloud.com.netapp -DartifactId=manageontap     -Dversion=4.0   -Dpackaging=jar
-
 # From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSP510-WEBSDK-510
 # Version: 5.1, Release-date: 2012-09-10, Build: 774886
 mvn install:install-file -Dfile=vim25_51.jar        -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25    -Dversion=5.1   -Dpackaging=jar
diff --git a/developer/pom.xml b/developer/pom.xml
index a8ad817..ae6463b 100644
--- a/developer/pom.xml
+++ b/developer/pom.xml
@@ -1,280 +1,287 @@
-<!-- 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"
+<!--
+  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
 
-         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-developer</artifactId>
-  <name>Apache CloudStack Developer Mode</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-dbcp2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-pool2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jasypt</groupId>
-      <artifactId>jasypt</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>properties-maven-plugin</artifactId>
-        <version>1.0-alpha-2</version>
-        <executions>
-          <execution>
-            <phase>initialize</phase>
-            <goals>
-              <goal>read-project-properties</goal>
-            </goals>
-            <configuration>
-              <files>
-                <file>${basedir}/../utils/conf/db.properties</file>
-                <file>${basedir}/../utils/conf/db.properties.override</file>
-              </files>
-              <quiet>true</quiet>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>generate-resources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <filter token="VERSION" value="${project.version}"/>
-                <copy todir="${basedir}/target/db" filtering="true">
-                  <fileset dir="${basedir}/../setup/db/"/>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <!-- default deploydb property -->
-      <id>deploydb</id>
-      <activation>
-        <property>
-          <name>deploydb</name>
-        </property>
-      </activation>
-      <build>
+    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-developer</artifactId>
+    <name>Apache CloudStack Developer Mode</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-dbcp2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jasypt</groupId>
+            <artifactId>jasypt</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
         <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-             <dependencies>
-              <!-- specify the dependent jdbc driver here -->
-              <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${cs.mysql.version}</version>
-              </dependency>
-            </dependencies>
-            <executions>
-              <execution>
-                <phase>process-resources</phase>
-                <id>create-schema</id>
-                <goals>
-                  <goal>java</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
-              <includePluginDependencies>true</includePluginDependencies>
-              <arguments>
-                <!-- db properties file -->
-                <argument>${basedir}/../utils/conf/db.properties</argument>
-                <argument>${basedir}/../utils/conf/db.properties.override</argument>
-                <!-- Create default schema and db table views -->
-                <argument>${basedir}/target/db/create-schema.sql</argument>
-                <argument>${basedir}/target/db/create-schema-premium.sql</argument>
-                <!-- Seed templates -->
-                <argument>${basedir}/target/db/templates.sql</argument>
-                <!-- Seed the database -->
-                <argument>${basedir}/developer-prefill.sql</argument>
-                <argument>${basedir}/developer-prefill.sql.override</argument>
-                <!-- Do database upgrade-->
-                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
-                <argument>--database=cloud,usage</argument>
-                <argument>--rootpassword=${db.root.password}</argument>
-                <!-- Print help using -h or dash-dash-help -->
-                <!-- Do dry run using -d or dash-dash-dry -->
-                <!-- Enable verbosity by -v or dash-dash-verbose -->
-              </arguments>
-              <systemProperties>
-                <systemProperty>
-                  <key>catalina.home</key>
-                  <value>${basedir}/../utils</value>
-                </systemProperty>
-                <systemProperty>
-                  <key>paths.script</key>
-                  <value>${basedir}/target/db</value>
-                </systemProperty>
-              </systemProperties>
-            </configuration>
-          </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>properties-maven-plugin</artifactId>
+                <version>1.0-alpha-2</version>
+                <executions>
+                    <execution>
+                        <phase>initialize</phase>
+                        <goals>
+                            <goal>read-project-properties</goal>
+                        </goals>
+                        <configuration>
+                            <files>
+                                <file>${basedir}/../utils/conf/db.properties</file>
+                                <file>${basedir}/../utils/conf/db.properties.override</file>
+                            </files>
+                            <quiet>true</quiet>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target>
+                                <filter token="VERSION" value="${project.version}" />
+                                <copy todir="${basedir}/target/db" filtering="true">
+                                    <fileset dir="${basedir}/../setup/db/" />
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-    <profile>
-      <!-- saml deploydb property -->
-      <id>deploydb-saml</id>
-      <activation>
-        <property>
-          <name>deploydb-saml</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <dependencies>
-              <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${cs.mysql.version}</version>
-              </dependency>
-            </dependencies>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <phase>process-resources</phase>
-                <id>create-schema-simulator</id>
-                <goals>
-                  <goal>java</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
-              <includePluginDependencies>true</includePluginDependencies>
-              <arguments>
-                <!-- db properties file -->
-                <argument>${basedir}/../utils/conf/db.properties</argument>
-                <argument>${basedir}/../utils/conf/db.properties.override</argument>
-                <!-- simulator sql files -->
-                <argument>${basedir}/developer-saml.sql</argument>
-                <!-- upgrade -->
-                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
-                <argument>--rootpassword=${db.root.password}</argument>
-              </arguments>
-              <systemProperties>
-                <systemProperty>
-                  <key>catalina.home</key>
-                  <value>${basedir}/../utils</value>
-                </systemProperty>
-                <systemProperty>
-                  <key>paths.script</key>
-                  <value>${basedir}/target/db</value>
-                </systemProperty>
-              </systemProperties>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <!-- simulator deploydb property -->
-      <id>deploydb-simulator</id>
-      <activation>
-        <property>
-          <name>deploydb-simulator</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <dependencies>
-              <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${cs.mysql.version}</version>
-              </dependency>
-	    </dependencies>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <phase>process-resources</phase>
-                <id>create-schema-simulator</id>
-                <goals>
-                  <goal>java</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
-              <includePluginDependencies>true</includePluginDependencies>
-              <arguments>
-                <!-- db properties file -->
-                <argument>${basedir}/../utils/conf/db.properties</argument>
-                <argument>${basedir}/../utils/conf/db.properties.override</argument>
-                <!-- simulator sql files -->
-                <argument>${basedir}/target/db/create-schema-simulator.sql</argument>
-                <argument>${basedir}/target/db/templates.simulator.sql</argument>
-                <argument>${basedir}/target/db/hypervisor_capabilities.simulator.sql</argument>
-                <!-- upgrade -->
-                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
-                <argument>--database=simulator</argument>
-                <argument>--rootpassword=${db.root.password}</argument>
-              </arguments>
-              <systemProperties>
-                <systemProperty>
-                  <key>catalina.home</key>
-                  <value>${basedir}/../utils</value>
-                </systemProperty>
-                <systemProperty>
-                  <key>paths.script</key>
-                  <value>${basedir}/target/db</value>
-                </systemProperty>
-              </systemProperties>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+    </build>
+    <profiles>
+        <profile>
+            <!-- default deploydb property -->
+            <id>deploydb</id>
+            <activation>
+                <property>
+                    <name>deploydb</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <dependencies>
+                            <!-- specify the dependent jdbc driver here -->
+                            <dependency>
+                                <groupId>mysql</groupId>
+                                <artifactId>mysql-connector-java</artifactId>
+                                <version>${cs.mysql.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <phase>process-resources</phase>
+                                <id>create-schema</id>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
+                            <includePluginDependencies>true</includePluginDependencies>
+                            <arguments>
+                                <!-- db properties file -->
+                                <argument>${basedir}/../utils/conf/db.properties</argument>
+                                <argument>${basedir}/../utils/conf/db.properties.override</argument>
+                                <!-- Create default schema and db table views -->
+                                <argument>${basedir}/target/db/create-schema.sql</argument>
+                                <argument>${basedir}/target/db/create-schema-premium.sql</argument>
+                                <!-- Seed templates -->
+                                <argument>${basedir}/target/db/templates.sql</argument>
+                                <!-- Seed the database -->
+                                <argument>${basedir}/developer-prefill.sql</argument>
+                                <argument>${basedir}/developer-prefill.sql.override</argument>
+                                <!-- Do database upgrade -->
+                                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
+                                <argument>--database=cloud,usage</argument>
+                                <argument>--rootpassword=${db.root.password}</argument>
+                                <!-- Print help using -h or dash-dash-help -->
+                                <!-- Do dry run using -d or dash-dash-dry -->
+                                <!-- Enable verbosity by -v or dash-dash-verbose -->
+                            </arguments>
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>catalina.home</key>
+                                    <value>${basedir}/../utils</value>
+                                </systemProperty>
+                                <systemProperty>
+                                    <key>paths.script</key>
+                                    <value>${basedir}/target/db</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <!-- saml deploydb property -->
+            <id>deploydb-saml</id>
+            <activation>
+                <property>
+                    <name>deploydb-saml</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <dependencies>
+                            <dependency>
+                                <groupId>mysql</groupId>
+                                <artifactId>mysql-connector-java</artifactId>
+                                <version>${cs.mysql.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <phase>process-resources</phase>
+                                <id>create-schema-simulator</id>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
+                            <includePluginDependencies>true</includePluginDependencies>
+                            <arguments>
+                                <!-- db properties file -->
+                                <argument>${basedir}/../utils/conf/db.properties</argument>
+                                <argument>${basedir}/../utils/conf/db.properties.override</argument>
+                                <!-- simulator sql files -->
+                                <argument>${basedir}/developer-saml.sql</argument>
+                                <!-- upgrade -->
+                                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
+                                <argument>--rootpassword=${db.root.password}</argument>
+                            </arguments>
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>catalina.home</key>
+                                    <value>${basedir}/../utils</value>
+                                </systemProperty>
+                                <systemProperty>
+                                    <key>paths.script</key>
+                                    <value>${basedir}/target/db</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <!-- simulator deploydb property -->
+            <id>deploydb-simulator</id>
+            <activation>
+                <property>
+                    <name>deploydb-simulator</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <dependencies>
+                            <dependency>
+                                <groupId>mysql</groupId>
+                                <artifactId>mysql-connector-java</artifactId>
+                                <version>${cs.mysql.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <phase>process-resources</phase>
+                                <id>create-schema-simulator</id>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>com.cloud.upgrade.DatabaseCreator</mainClass>
+                            <includePluginDependencies>true</includePluginDependencies>
+                            <arguments>
+                                <!-- db properties file -->
+                                <argument>${basedir}/../utils/conf/db.properties</argument>
+                                <argument>${basedir}/../utils/conf/db.properties.override</argument>
+                                <!-- simulator sql files -->
+                                <argument>${basedir}/target/db/create-schema-simulator.sql</argument>
+                                <argument>${basedir}/target/db/templates.simulator.sql</argument>
+                                <argument>${basedir}/target/db/hypervisor_capabilities.simulator.sql</argument>
+                                <!-- upgrade -->
+                                <argument>com.cloud.upgrade.DatabaseUpgradeChecker</argument>
+                                <argument>--database=simulator</argument>
+                                <argument>--rootpassword=${db.root.password}</argument>
+                            </arguments>
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>catalina.home</key>
+                                    <value>${basedir}/../utils</value>
+                                </systemProperty>
+                                <systemProperty>
+                                    <key>paths.script</key>
+                                    <value>${basedir}/target/db</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/engine/api/pom.xml b/engine/api/pom.xml
index 5624ab1..e2b0634 100644
--- a/engine/api/pom.xml
+++ b/engine/api/pom.xml
@@ -1,54 +1,62 @@
-<!-- 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. -->
+<!--
+  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-engine-api</artifactId>
-  <name>Apache CloudStack Cloud Engine API</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-rest</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-api</artifactId>
+    <name>Apache CloudStack Cloud Engine API</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/api/src/com/cloud/vm/VirtualMachineGuru.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineGuru.java
similarity index 100%
rename from engine/api/src/com/cloud/vm/VirtualMachineGuru.java
rename to engine/api/src/main/java/com/cloud/vm/VirtualMachineGuru.java
diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java
similarity index 100%
rename from engine/api/src/com/cloud/vm/VirtualMachineManager.java
rename to engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/BackupEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/BackupEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/BackupEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/BackupEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/EdgeService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/EdgeService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/EdgeService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/EdgeService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/NetworkEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/NetworkEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/NetworkEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/NetworkEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/NicEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/NicEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/NicEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/NicEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/SnapshotEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/SnapshotEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/SnapshotEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/SnapshotEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/TemplateEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/TemplateEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/TemplateEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/TemplateEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VolumeEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/HostEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/OrganizationScope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/OrganizationScope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/OrganizationScope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/OrganizationScope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/PodEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/StorageEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/StorageEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/StorageEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/StorageEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/entity/api/CloudStackEntity.java b/engine/api/src/main/java/org/apache/cloudstack/engine/entity/api/CloudStackEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/entity/api/CloudStackEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/entity/api/CloudStackEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/exception/InsufficientCapacityException.java b/engine/api/src/main/java/org/apache/cloudstack/engine/exception/InsufficientCapacityException.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/exception/InsufficientCapacityException.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/exception/InsufficientCapacityException.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/ClusterRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/ClusterRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/ClusterRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/ClusterRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/NetworkRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/NetworkRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/NetworkRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/NetworkRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/PodRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/PodRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/PodRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/PodRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/VirtualMachineRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/VirtualMachineRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/VirtualMachineRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/VirtualMachineRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/VolumeRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/VolumeRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/VolumeRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/VolumeRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/rest/service/api/ZoneRestService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/ZoneRestService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/rest/service/api/ZoneRestService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/rest/service/api/ZoneRestService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/DirectoryService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/DirectoryService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/service/api/DirectoryService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/service/api/DirectoryService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/EntityService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/EntityService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/service/api/EntityService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/service/api/EntityService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/OperationsServices.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OperationsServices.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/service/api/OperationsServices.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OperationsServices.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/service/api/OrchestrationService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/ProvisioningService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/service/api/ProvisioningService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/service/api/ProvisioningService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/hypervisor/ComputeSubsystem.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/hypervisor/ComputeSubsystem.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/hypervisor/ComputeSubsystem.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/hypervisor/ComputeSubsystem.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/network/NetworkServiceProvider.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/network/NetworkServiceProvider.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/network/NetworkServiceProvider.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/network/NetworkServiceProvider.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/network/NetworkSubsystem.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/network/NetworkSubsystem.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/network/NetworkSubsystem.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/network/NetworkSubsystem.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/AbstractScope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/AbstractScope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/AbstractScope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/AbstractScope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ChapInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ChapInfo.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ChapInfo.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ChapInfo.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
new file mode 100644
index 0000000..2afece4
--- /dev/null
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
@@ -0,0 +1,53 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import java.util.Map;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.Host;
+
+/**
+ * Interface to query how to move data around and to commision the moving
+ */
+public interface DataMotionStrategy {
+    /**
+     * Reports whether this instance can do a move from source to destination
+     * @param srcData object to move
+     * @param destData location to move it to
+     * @return the expertise level with which this instance knows how to handle the move
+     */
+    StrategyPriority canHandle(DataObject srcData, DataObject destData);
+
+    StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost);
+
+    /**
+     * Copy the source volume to its destination (on a host if not null)
+     *
+     * @param srcData volume to move
+     * @param destData volume description as intended after the move
+     * @param destHost if not null destData should be reachable from here
+     * @param callback where to report completion or failure to
+     */
+    void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback);
+
+    void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback);
+}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreCapabilities.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreCapabilities.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreCapabilities.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreCapabilities.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
new file mode 100644
index 0000000..6021a43
--- /dev/null
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
@@ -0,0 +1,75 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
+
+import com.cloud.host.Host;
+import com.cloud.storage.StoragePool;
+
+public interface PrimaryDataStoreDriver extends DataStoreDriver {
+    enum QualityOfServiceState { MIGRATION, NO_MIGRATION }
+
+    String BASIC_CREATE = "basicCreate";
+    String BASIC_DELETE = "basicDelete";
+    String BASIC_DELETE_FAILURE = "basicDeleteFailure";
+    String BASIC_DELETE_BY_FOLDER = "basicDeleteByFolder";
+    String BASIC_GRANT_ACCESS = "basicGrantAccess";
+    String BASIC_REVOKE_ACCESS = "basicRevokeAccess";
+    String BASIC_IQN = "basicIqn";
+
+    ChapInfo getChapInfo(DataObject dataObject);
+
+    boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore);
+
+    void revokeAccess(DataObject dataObject, Host host, DataStore dataStore);
+
+    /**
+     * intended for managed storage (cloud.storage_pool.managed = true)
+     * if not managed, return volume.getSize()
+     */
+    long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool storagePool);
+
+    /**
+     * intended for zone-wide primary storage that is capable of storing a template once and using it in multiple clusters
+     * if not this kind of storage, return 0
+     */
+    long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool);
+
+    /**
+     * intended for managed storage (cloud.storage_pool.managed = true)
+     * if managed storage, return the total number of bytes currently in use for the storage pool in question
+     * if not managed storage, return 0
+     */
+    long getUsedBytes(StoragePool storagePool);
+
+    /**
+     * intended for managed storage (cloud.storage_pool.managed = true)
+     * if managed storage, return the total number of IOPS currently in use for the storage pool in question
+     * if not managed storage, return 0
+     */
+    long getUsedIops(StoragePool storagePool);
+
+    void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback);
+
+    void revertSnapshot(SnapshotInfo snapshotOnImageStore, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback);
+
+    void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState);
+}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageAction.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StorageStrategyFactory.java
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java
new file mode 100644
index 0000000..4bfc748
--- /dev/null
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java
@@ -0,0 +1,21 @@
+// 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.engine.subsystem.api.storage;
+
+public enum StrategyPriority {
+    CANT_HANDLE, DEFAULT, HYPERVISOR, HIGHEST
+}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotOptions.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotOptions.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotOptions.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotOptions.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
new file mode 100644
index 0000000..6794272
--- /dev/null
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
@@ -0,0 +1,74 @@
+/*
+ * 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.engine.subsystem.api.storage;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering.DiskCacheMode;
+import com.cloud.storage.Volume;
+import com.cloud.vm.VirtualMachine;
+
+public interface VolumeInfo extends DataObject, Volume {
+
+    boolean isAttachedVM();
+
+    void addPayload(Object data);
+
+    Object getpayload();
+
+    HypervisorType getHypervisorType();
+
+    Long getLastPoolId();
+
+    String getAttachedVmName();
+
+    VirtualMachine getAttachedVM();
+
+    void processEventOnly(ObjectInDataStoreStateMachine.Event event);
+
+    void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer);
+
+    boolean stateTransit(Volume.Event event);
+
+    Long getBytesReadRate();
+
+    Long getBytesReadRateMax();
+
+    Long getBytesReadRateMaxLength();
+
+    Long getBytesWriteRate();
+
+    Long getBytesWriteRateMax();
+
+    Long getBytesWriteRateMaxLength();
+
+    Long getIopsReadRate();
+
+    Long getIopsReadRateMax();
+
+    Long getIopsReadRateMaxLength();
+
+    Long getIopsWriteRate();
+
+    Long getIopsWriteRateMax();
+
+    Long getIopsWriteRateMaxLength();
+
+    DiskCacheMode getCacheMode();
+}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeType.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeType.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeType.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeType.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java
rename to engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java
diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java b/engine/api/src/main/java/org/apache/cloudstack/storage/command/CommandResult.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java
rename to engine/api/src/main/java/org/apache/cloudstack/storage/command/CommandResult.java
diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
rename to engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java b/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java
similarity index 100%
rename from engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java
rename to engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java
diff --git a/engine/api/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml b/engine/api/src/main/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml
similarity index 100%
rename from engine/api/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml
rename to engine/api/src/main/resources/META-INF/cloudstack/core/spring-engine-api-core-context.xml
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
deleted file mode 100644
index 5d552c4..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-import java.util.Map;
-
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.host.Host;
-
-public interface DataMotionStrategy {
-    StrategyPriority canHandle(DataObject srcData, DataObject destData);
-
-    StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost);
-
-    void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback);
-
-    void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback);
-}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
deleted file mode 100644
index 8749589..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CommandResult;
-
-import com.cloud.host.Host;
-import com.cloud.storage.StoragePool;
-
-public interface PrimaryDataStoreDriver extends DataStoreDriver {
-    String BASIC_CREATE = "basicCreate";
-    String BASIC_DELETE = "basicDelete";
-    String BASIC_DELETE_FAILURE = "basicDeleteFailure";
-    String BASIC_GRANT_ACCESS = "basicGrantAccess";
-    String BASIC_REVOKE_ACCESS = "basicRevokeAccess";
-    String BASIC_IQN = "basicIqn";
-
-    ChapInfo getChapInfo(DataObject dataObject);
-
-    boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore);
-
-    void revokeAccess(DataObject dataObject, Host host, DataStore dataStore);
-
-    /**
-     * intended for managed storage (cloud.storage_pool.managed = true)
-     * if not managed, return volume.getSize()
-     */
-    long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool storagePool);
-
-    /**
-     * intended for zone-wide primary storage that is capable of storing a template once and using it in multiple clusters
-     * if not this kind of storage, return 0
-     */
-    long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool);
-
-    /**
-     * intended for managed storage (cloud.storage_pool.managed = true)
-     * if managed storage, return the total number of bytes currently in use for the storage pool in question
-     * if not managed storage, return 0
-     */
-    long getUsedBytes(StoragePool storagePool);
-
-    /**
-     * intended for managed storage (cloud.storage_pool.managed = true)
-     * if managed storage, return the total number of IOPS currently in use for the storage pool in question
-     * if not managed storage, return 0
-     */
-    long getUsedIops(StoragePool storagePool);
-
-    void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback);
-
-    void revertSnapshot(SnapshotInfo snapshotOnImageStore, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback);
-}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java
deleted file mode 100644
index 7c0015b..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriority.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-public enum StrategyPriority {
-    CANT_HANDLE, DEFAULT, HYPERVISOR, PLUGIN, HIGHEST
-}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
deleted file mode 100644
index e27b751..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering.DiskCacheMode;
-import com.cloud.storage.Volume;
-import com.cloud.vm.VirtualMachine;
-
-public interface VolumeInfo extends DataObject, Volume {
-
-    boolean isAttachedVM();
-
-    void addPayload(Object data);
-
-    Object getpayload();
-
-    HypervisorType getHypervisorType();
-
-    Long getLastPoolId();
-
-    String getAttachedVmName();
-
-    VirtualMachine getAttachedVM();
-
-    void processEventOnly(ObjectInDataStoreStateMachine.Event event);
-
-    void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer);
-
-    boolean stateTransit(Volume.Event event);
-
-    Long getBytesReadRate();
-
-    Long getBytesWriteRate();
-
-    Long getIopsReadRate();
-
-    Long getIopsWriteRate();
-
-    DiskCacheMode getCacheMode();
-}
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/QCOW2.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/QCOW2.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/QCOW2.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/Unknown.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/Unknown.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/Unknown.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHD.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHD.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHD.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHDX.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHDX.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VHDX.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VMDK.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VMDK.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VMDK.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskType.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskType.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskType.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeBase.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeBase.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeBase.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeHelper.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeHelper.java
deleted file mode 100644
index b248758..0000000
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/VolumeDiskTypeHelper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java b/engine/api/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java
similarity index 100%
rename from engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java
rename to engine/api/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java
diff --git a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelperTest.java b/engine/api/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelperTest.java
similarity index 100%
rename from engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelperTest.java
rename to engine/api/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelperTest.java
diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml
index 1ecd3c7..5a9c4d4 100644
--- a/engine/components-api/pom.xml
+++ b/engine/components-api/pom.xml
@@ -1,62 +1,62 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine-components-api</artifactId>
-  <name>Apache CloudStack Cloud Engine Internal Components API</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-jobs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-components-api</artifactId>
+    <name>Apache CloudStack Cloud Engine Internal Components API</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-jobs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml b/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml
deleted file mode 100644
index b644176..0000000
--- a/engine/components-api/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context.xsd"
-                      >                     
-
-</beans>
diff --git a/engine/components-api/src/com/cloud/agent/AgentManager.java b/engine/components-api/src/com/cloud/agent/AgentManager.java
deleted file mode 100644
index 933c3ea..0000000
--- a/engine/components-api/src/com/cloud/agent/AgentManager.java
+++ /dev/null
@@ -1,155 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent;
-
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.manager.Commands;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ServerResource;
-
-/**
- * AgentManager manages hosts. It directly coordinates between the DAOs and the connections it manages.
- */
-public interface AgentManager {
-    static final ConfigKey<Integer> Wait = new ConfigKey<Integer>("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return",
-        true);
-
-    public enum TapAgentsAction {
-        Add, Del, Contains,
-    }
-
-    boolean handleDirectConnectAgent(Host host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance, boolean newHost) throws ConnectionException;
-
-    /**
-     * easy send method that returns null if there's any errors. It handles all exceptions.
-     *
-     * @param hostId
-     *            host id
-     * @param cmd
-     *            command to send.
-     * @return Answer if successful; null if not.
-     */
-    Answer easySend(Long hostId, Command cmd);
-
-    /**
-     * Synchronous sending a command to the agent.
-     *
-     * @param hostId
-     *            id of the agent on host
-     * @param cmd
-     *            command
-     * @return an Answer
-     */
-
-    Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException;
-
-    /**
-     * Synchronous sending a list of commands to the agent.
-     *
-     * @param hostId
-     *            id of the agent on host
-     * @param cmds
-     *            array of commands
-     * @param isControl
-     *            Commands sent contains control commands
-     * @param stopOnError
-     *            should the agent stop execution on the first error.
-     * @return an array of Answer
-     */
-    Answer[] send(Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException;
-
-    Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, OperationTimedoutException;
-
-    /**
-     * Asynchronous sending of a command to the agent.
-     *
-     * @param hostId
-     *            id of the agent on the host.
-     * @param cmds
-     *            Commands to send.
-     * @param stopOnError
-     *            should the agent stop execution on the first error.
-     * @param listener
-     *            the listener to process the answer.
-     * @return sequence number.
-     */
-    long send(Long hostId, Commands cmds, Listener listener) throws AgentUnavailableException;
-
-    /**
-     * Register to listen for host events. These are mostly connection and disconnection events.
-     *
-     * @param listener
-     * @param connections
-     *            listen for connections
-     * @param commands
-     *            listen for connections
-     * @param priority
-     *            in listening for events.
-     * @return id to unregister if needed.
-     */
-    int registerForHostEvents(Listener listener, boolean connections, boolean commands, boolean priority);
-
-    /**
-     * Register to listen for initial agent connections.
-     * @param creator
-     * @param priority in listening for events.
-     * @return id to unregister if needed.
-     */
-    int registerForInitialConnects(StartupCommandProcessor creator, boolean priority);
-
-    /**
-     * Unregister for listening to host events.
-     *
-     * @param id
-     *            returned from registerForHostEvents
-     */
-    void unregisterForHostEvents(int id);
-
-    Answer sendTo(Long dcId, HypervisorType type, Command cmd);
-
-    public boolean agentStatusTransitTo(HostVO host, Status.Event e, long msId);
-
-    boolean isAgentAttached(long hostId);
-
-    void disconnectWithoutInvestigation(long hostId, Status.Event event);
-
-    void disconnectWithInvestigation(long hostId, Status.Event event);
-
-    public void pullAgentToMaintenance(long hostId);
-
-    public void pullAgentOutMaintenance(long hostId);
-
-    boolean reconnect(long hostId);
-
-    void rescan();
-
-    void notifyMonitorsOfNewlyAddedHost(long hostId);
-
-    void notifyMonitorsOfHostAboutToBeRemoved(long hostId);
-
-    void notifyMonitorsOfRemovedHost(long hostId, long clusterId);
-}
diff --git a/engine/components-api/src/com/cloud/network/IpAddressManager.java b/engine/components-api/src/com/cloud/network/IpAddressManager.java
deleted file mode 100644
index 256f026..0000000
--- a/engine/components-api/src/com/cloud/network/IpAddressManager.java
+++ /dev/null
@@ -1,192 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.user.Account;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-public interface IpAddressManager {
-    String UseSystemPublicIpsCK = "use.system.public.ips";
-    ConfigKey<Boolean> UseSystemPublicIps = new ConfigKey<Boolean>("Advanced", Boolean.class, UseSystemPublicIpsCK, "true",
-            "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool",
-            true, ConfigKey.Scope.Account);
-
-    ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
-            "When true, ip address delete (ipassoc) failures are  ignored", true);
-
-    /**
-     * Assigns a new public ip address.
-     *
-     * @param dcId
-     * @param podId
-     * @param owner
-     * @param type
-     * @param networkId
-     * @param requestedIp
-     * @param isSystem
-     * @return
-     * @throws InsufficientAddressCapacityException
-     */
-    PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
-            throws InsufficientAddressCapacityException;
-
-    /**
-     * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects.
-     *
-     * @param userId
-     * @param caller
-     * @param caller
-     * @return true if it did; false if it didn't
-     */
-    boolean disassociatePublicIpAddress(long id, long userId, Account caller);
-
-    boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
-            throws ResourceUnavailableException;
-
-    /**
-     * @param userId
-     * @param accountId
-     * @param zoneId
-     * @param vlanId
-     * @param guestNetwork
-     * @throws InsufficientCapacityException
-     * @throws ConcurrentOperationException
-     * @throws ResourceUnavailableException
-     * @throws ResourceAllocationException
-     *             Associates an ip address list to an account. The list of ip addresses are all addresses associated
-     *             with the
-     *             given vlan id.
-     */
-    boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException,
-            ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;
-
-    boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException;
-
-    boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<? extends PublicIpAddress> publicIps)
-            throws ResourceUnavailableException;
-
-    IPAddressVO markIpAsUnavailable(long addrId);
-
-    String acquireGuestIpAddress(Network network, String requestedIp);
-
-    boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException;
-
-    IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException;
-
-    boolean handleSystemIpRelease(IpAddress ip);
-
-    void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
-
-    /**
-     * @param owner
-     * @param guestNetwork
-     * @return
-     * @throws ConcurrentOperationException
-     * @throws InsufficientAddressCapacityException
-     */
-    PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException;
-
-    /**
-     *
-     * @param ipAddrId
-     * @param networkId
-     * @param releaseOnFailure
-     * @return
-     * @throws ResourceAllocationException
-     * @throws ResourceUnavailableException
-     * @throws InsufficientAddressCapacityException
-     * @throws ConcurrentOperationException
-     */
-    IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException;
-
-    IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) throws ConcurrentOperationException,
-            ResourceAllocationException, InsufficientAddressCapacityException;
-
-    boolean releasePortableIpAddress(long addrId);
-
-    IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException,
-            ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException;
-
-    IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException;
-
-    boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId);
-
-    void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException;;
-
-    /**
-     * @param addr
-     */
-    void markPublicIpAsAllocated(IPAddressVO addr);
-
-    /**
-     * @param owner
-     * @param guestNtwkId
-     * @param vpcId
-     * @param dcId
-     * @param isSourceNat
-     * @return
-     * @throws ConcurrentOperationException
-     * @throws InsufficientAddressCapacityException
-     */
-    PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException,
-            InsufficientAddressCapacityException;
-
-    IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp) throws ConcurrentOperationException,
-            ResourceAllocationException, InsufficientAddressCapacityException;
-
-    PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp,
-            boolean isSystem) throws InsufficientAddressCapacityException;
-
-    @DB
-    void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4,
-            String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
-
-    int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
-
-    String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException;
-
-    String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
-
-    AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException;
-
-    void releasePodIp(Long id) throws CloudRuntimeException;
-}
-
diff --git a/engine/components-api/src/com/cloud/network/vpc/NetworkACLManager.java b/engine/components-api/src/com/cloud/network/vpc/NetworkACLManager.java
deleted file mode 100644
index 0377c5f..0000000
--- a/engine/components-api/src/com/cloud/network/vpc/NetworkACLManager.java
+++ /dev/null
@@ -1,155 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.List;
-
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.dao.NetworkVO;
-
-public interface NetworkACLManager {
-
-    /**
-     * Creates Network ACL for the specified VPC
-     * @param name
-     * @param description
-     * @param vpcId
-     * @param forDisplay TODO
-     * @return
-     */
-    NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay);
-
-    /**
-     * Fetches Network ACL with specified Id
-     * @param id
-     * @return
-     */
-    NetworkACL getNetworkACL(long id);
-
-    /**
-     * Applies the items in the ACL to all associated networks
-     * @param aclId
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean applyNetworkACL(long aclId) throws ResourceUnavailableException;
-
-    /**
-     * Deletes the specified Network ACL
-     * @param id
-     * @return
-     */
-    boolean deleteNetworkACL(NetworkACL acl);
-
-    /**
-     * Associates acl with a network and applies the ACLItems
-     * @param acl
-     * @param network
-     * @return
-     */
-    boolean replaceNetworkACL(NetworkACL acl, NetworkVO network) throws ResourceUnavailableException;
-
-    /**
-     * Creates a Network ACL Item within an ACL and applies it to associated networks
-     * @param sourcePortStart
-     * @param sourcePortEnd
-     * @param protocol
-     * @param sourceCidrList
-     * @param icmpCode
-     * @param icmpType
-     * @param trafficType
-     * @param aclId
-     * @param action
-     * @param number
-     * @param forDisplay TODO
-     * @return
-     */
-    NetworkACLItem createNetworkACLItem(Integer sourcePortStart, Integer sourcePortEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
-        NetworkACLItem.TrafficType trafficType, Long aclId, String action, Integer number, Boolean forDisplay);
-
-    /**
-     * Returns Network ACL Item with specified Id
-     * @param ruleId
-     * @return
-     */
-    NetworkACLItem getNetworkACLItem(long ruleId);
-
-    /**
-     * Revoke ACL Item and apply changes
-     * @param ruleId
-     * @return
-     */
-    boolean revokeNetworkACLItem(long ruleId);
-
-    /**
-     * Revoke ACL Items for network and remove them in back-end. Db is not updated
-     * @param networkId
-     * @param userId
-     * @param caller
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean revokeACLItemsForNetwork(long networkId) throws ResourceUnavailableException;
-
-    /**
-     * List network ACL items by network
-     * @param guestNtwkId
-     * @return
-     */
-    List<NetworkACLItemVO> listNetworkACLItems(long guestNtwkId);
-
-    /**
-     * Applies asscociated ACL to specified network
-     * @param networkId
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    boolean applyACLToNetwork(long networkId) throws ResourceUnavailableException;
-
-    /**
-     * Updates and existing network ACL Item
-     * @param id
-     * @param protocol
-     * @param sourceCidrList
-     * @param trafficType
-     * @param action
-     * @param number
-     * @param sourcePortStart
-     * @param sourcePortEnd
-     * @param icmpCode
-     * @param icmpType
-     * @param customId TODO
-     * @param forDisplay TODO
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    NetworkACLItem updateNetworkACLItem(Long id, String protocol, List<String> sourceCidrList, NetworkACLItem.TrafficType trafficType, String action, Integer number,
-        Integer sourcePortStart, Integer sourcePortEnd, Integer icmpCode, Integer icmpType, String customId, Boolean forDisplay) throws ResourceUnavailableException;
-
-    /**
-     * Associates acl with a network and applies the ACLItems
-     * @param acl
-     * @param gateway
-     * @return
-     */
-
-    boolean replaceNetworkACLForPrivateGw(NetworkACL acl, PrivateGateway gateway) throws ResourceUnavailableException;
-
-    boolean revokeACLItemsForPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException;
-
-    boolean applyACLToPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException;
-}
diff --git a/engine/components-api/src/com/cloud/storage/StorageManager.java b/engine/components-api/src/com/cloud/storage/StorageManager.java
deleted file mode 100644
index a532a4f..0000000
--- a/engine/components-api/src/com/cloud/storage/StorageManager.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.StorageConflictException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.utils.Pair;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VMInstanceVO;
-
-public interface StorageManager extends StorageService {
-    ConfigKey<Integer> StorageCleanupInterval = new ConfigKey<>(Integer.class,
-            "storage.cleanup.interval",
-            "Advanced",
-            "86400",
-            "The interval (in seconds) to wait before running the storage cleanup thread.",
-            false,
-            ConfigKey.Scope.Global,
-            null);
-    ConfigKey<Integer> StorageCleanupDelay = new ConfigKey<>(Integer.class,
-            "storage.cleanup.delay",
-            "Advanced",
-            "86400",
-            "Determines how long (in seconds) to wait before actually expunging destroyed volumes. The default value = the default value of storage.cleanup.interval.",
-            false,
-            ConfigKey.Scope.Global,
-            null);
-    ConfigKey<Boolean> StorageCleanupEnabled = new ConfigKey<>(Boolean.class,
-            "storage.cleanup.enabled",
-            "Advanced",
-            "true",
-            "Enables/disables the storage cleanup thread.",
-            false,
-            ConfigKey.Scope.Global,
-            null);
-    ConfigKey<Boolean> TemplateCleanupEnabled = new ConfigKey<>(Boolean.class,
-            "storage.template.cleanup.enabled",
-            "Storage",
-            "true",
-            "Enable/disable template cleanup activity, only take effect when overall storage cleanup is enabled",
-            false,
-            ConfigKey.Scope.Global,
-            null);
-    ConfigKey<Integer> KvmStorageOfflineMigrationWait = new ConfigKey<>(Integer.class,
-            "kvm.storage.offline.migration.wait",
-            "Storage",
-            "10800",
-            "Timeout in seconds for offline (non-live) storage migration to complete on KVM",
-            true,
-            ConfigKey.Scope.Global,
-            null);
-    ConfigKey<Integer> KvmStorageOnlineMigrationWait = new ConfigKey<>(Integer.class,
-            "kvm.storage.online.migration.wait",
-            "Storage",
-            "10800",
-            "Timeout in seconds for online (live) storage migration to complete on KVM (migrateVirtualMachineWithVolume)",
-            true,
-            ConfigKey.Scope.Global,
-            null);
-
-    /**
-     * Returns a comma separated list of tags for the specified storage pool
-     * @param poolId
-     * @return comma separated list of tags
-     */
-    public String getStoragePoolTags(long poolId);
-
-    Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException;
-
-    Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException;
-
-    Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException;
-
-    Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException;
-
-    Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException;
-
-    Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
-
-    /**
-     * Checks if a host has running VMs that are using its local storage pool.
-     * @return true if local storage is active on the host
-     */
-    boolean isLocalStorageActiveOnHost(Long hostId);
-
-    /**
-     * Cleans up storage pools by removing unused templates.
-     * @param recurring - true if this cleanup is part of a recurring garbage collection thread
-     */
-    void cleanupStorage(boolean recurring);
-
-    String getPrimaryStorageNameLabel(VolumeVO volume);
-
-    void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated);
-
-    Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException;
-
-    CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId);
-
-    CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId);
-
-    List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type);
-
-    List<VMInstanceVO> listByStoragePool(long storagePoolId);
-
-    StoragePoolVO findLocalStorageOnHost(long hostId);
-
-    Host updateSecondaryStorage(long secStorageId, String newUrl);
-
-    void removeStoragePoolFromCluster(long hostId, String iScsiName, StoragePool storagePool);
-
-    List<Long> getUpHostsInPool(long poolId);
-
-    void cleanupSecondaryStorage(boolean recurring);
-
-    HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
-
-    boolean storagePoolHasEnoughIops(List<Volume> volume, StoragePool pool);
-
-    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
-
-    /**
-     * This comment is relevant to managed storage only.
-     *
-     *  Long clusterId = only used for managed storage
-     *
-     *  Some managed storage can be more efficient handling VM templates (via cloning) if it knows the capabilities of the compute cluster it is dealing with.
-     *  If the compute cluster supports UUID resigning and the storage system can clone a volume from a volume, then this determines how much more space a
-     *  new root volume (that makes use of a template) will take up on the storage system.
-     *
-     *  For example, if a storage system can clone a volume from a volume and the compute cluster supports UUID resigning (relevant for hypervisors like
-     *  XenServer and ESXi that put virtual disks in clustered file systems), then the storage system will need to determine if it already has a copy of
-     *  the template or if it will need to create one first before cloning the template to a new volume to be used for the new root disk (assuming the root
-     *  disk is being deployed from a template). If the template doesn't already exists on the storage system, then you need to take into consideration space
-     *  required for that template (stored in one volume) and space required for a new volume created from that template volume (for your new root volume).
-     *
-     *  If UUID resigning is not available in the compute cluster or the storage system doesn't support cloning a volume from a volume, then for each new
-     *  root disk that uses a template, CloudStack will have the template be copied down to a newly created volume on the storage system (i.e. no need
-     *  to take into consideration the possible need to first create a volume on the storage system for a template that will be used for the root disk
-     *  via cloning).
-     *
-     *  Cloning volumes on the back-end instead of copying down a new template for each new volume helps to alleviate load on the hypervisors.
-     */
-    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool, Long clusterId);
-
-    boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSiz);
-
-    boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
-
-    void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
-
-    void createCapacityEntry(long poolId);
-
-    DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws ConnectionException;
-
-    BigDecimal getStorageOverProvisioningFactor(Long dcId);
-
-    Long getDiskBytesReadRate(ServiceOffering offering, DiskOffering diskOffering);
-
-    Long getDiskBytesWriteRate(ServiceOffering offering, DiskOffering diskOffering);
-
-    Long getDiskIopsReadRate(ServiceOffering offering, DiskOffering diskOffering);
-
-    Long getDiskIopsWriteRate(ServiceOffering offering, DiskOffering diskOffering);
-
-    void cleanupDownloadUrls();
-
-    void setDiskProfileThrottling(DiskProfile dskCh, ServiceOffering offering, DiskOffering diskOffering);
-
-    DiskTO getDiskWithThrottling(DataTO volTO, Volume.Type volumeType, long deviceId, String path, long offeringId, long diskOfferingId);
-
-}
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkMigrateVolume.java b/engine/components-api/src/com/cloud/vm/VmWorkMigrateVolume.java
deleted file mode 100644
index 994b492..0000000
--- a/engine/components-api/src/com/cloud/vm/VmWorkMigrateVolume.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm;
-
-public class VmWorkMigrateVolume extends VmWork {
-    private static final long serialVersionUID = -565778516928408602L;
-
-    private long volumeId;
-    private long destPoolId;
-    private boolean liveMigrate;
-
-    public VmWorkMigrateVolume(long userId, long accountId, long vmId, String handlerName, long volumeId, long destPoolId, boolean liveMigrate) {
-        super(userId, accountId, vmId, handlerName);
-        this.volumeId = volumeId;
-        this.destPoolId = destPoolId;
-        this.liveMigrate = liveMigrate;
-    }
-
-    public long getVolumeId() {
-        return volumeId;
-    }
-
-    public long getDestPoolId() {
-        return destPoolId;
-    }
-
-    public boolean isLiveMigrate() {
-        return liveMigrate;
-    }
-}
diff --git a/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java
new file mode 100644
index 0000000..c51970c
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/agent/AgentManager.java
@@ -0,0 +1,155 @@
+// 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;
+
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.manager.Commands;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ServerResource;
+
+/**
+ * AgentManager manages hosts. It directly coordinates between the DAOs and the connections it manages.
+ */
+public interface AgentManager {
+    static final ConfigKey<Integer> Wait = new ConfigKey<Integer>("Advanced", Integer.class, "wait", "1800", "Time in seconds to wait for control commands to return",
+            true);
+
+    public enum TapAgentsAction {
+        Add, Del, Contains,
+    }
+
+    boolean handleDirectConnectAgent(Host host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance, boolean newHost) throws ConnectionException;
+
+    /**
+     * easy send method that returns null if there's any errors. It handles all exceptions.
+     *
+     * @param hostId
+     *            host id
+     * @param cmd
+     *            command to send.
+     * @return Answer if successful; null if not.
+     */
+    Answer easySend(Long hostId, Command cmd);
+
+    /**
+     * Synchronous sending a command to the agent.
+     *
+     * @param hostId
+     *            id of the agent on host
+     * @param cmd
+     *            command
+     * @return an Answer
+     */
+
+    Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException;
+
+    /**
+     * Synchronous sending a list of commands to the agent.
+     *
+     * @param hostId
+     *            id of the agent on host
+     * @param cmds
+     *            array of commands
+     * @param isControl
+     *            Commands sent contains control commands
+     * @param stopOnError
+     *            should the agent stop execution on the first error.
+     * @return an array of Answer
+     */
+    Answer[] send(Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException;
+
+    Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, OperationTimedoutException;
+
+    /**
+     * Asynchronous sending of a command to the agent.
+     *
+     * @param hostId
+     *            id of the agent on the host.
+     * @param cmds
+     *            Commands to send.
+     * @param stopOnError
+     *            should the agent stop execution on the first error.
+     * @param listener
+     *            the listener to process the answer.
+     * @return sequence number.
+     */
+    long send(Long hostId, Commands cmds, Listener listener) throws AgentUnavailableException;
+
+    /**
+     * Register to listen for host events. These are mostly connection and disconnection events.
+     *
+     * @param listener
+     * @param connections
+     *            listen for connections
+     * @param commands
+     *            listen for connections
+     * @param priority
+     *            in listening for events.
+     * @return id to unregister if needed.
+     */
+    int registerForHostEvents(Listener listener, boolean connections, boolean commands, boolean priority);
+
+    /**
+     * Register to listen for initial agent connections.
+     * @param creator
+     * @param priority in listening for events.
+     * @return id to unregister if needed.
+     */
+    int registerForInitialConnects(StartupCommandProcessor creator, boolean priority);
+
+    /**
+     * Unregister for listening to host events.
+     *
+     * @param id
+     *            returned from registerForHostEvents
+     */
+    void unregisterForHostEvents(int id);
+
+    Answer sendTo(Long dcId, HypervisorType type, Command cmd);
+
+    public boolean agentStatusTransitTo(HostVO host, Status.Event e, long msId);
+
+    boolean isAgentAttached(long hostId);
+
+    void disconnectWithoutInvestigation(long hostId, Status.Event event);
+
+    void disconnectWithInvestigation(long hostId, Status.Event event);
+
+    public void pullAgentToMaintenance(long hostId);
+
+    public void pullAgentOutMaintenance(long hostId);
+
+    void reconnect(long hostId) throws AgentUnavailableException;
+
+    void rescan();
+
+    void notifyMonitorsOfNewlyAddedHost(long hostId);
+
+    void notifyMonitorsOfHostAboutToBeRemoved(long hostId);
+
+    void notifyMonitorsOfRemovedHost(long hostId, long clusterId);
+}
diff --git a/engine/components-api/src/com/cloud/agent/Listener.java b/engine/components-api/src/main/java/com/cloud/agent/Listener.java
similarity index 100%
rename from engine/components-api/src/com/cloud/agent/Listener.java
rename to engine/components-api/src/main/java/com/cloud/agent/Listener.java
diff --git a/engine/components-api/src/com/cloud/alert/AlertManager.java b/engine/components-api/src/main/java/com/cloud/alert/AlertManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/alert/AlertManager.java
rename to engine/components-api/src/main/java/com/cloud/alert/AlertManager.java
diff --git a/engine/components-api/src/com/cloud/capacity/CapacityManager.java b/engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/capacity/CapacityManager.java
rename to engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java
diff --git a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
rename to engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
diff --git a/engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java b/engine/components-api/src/main/java/com/cloud/deploy/DeploymentPlanningManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/deploy/DeploymentPlanningManager.java
rename to engine/components-api/src/main/java/com/cloud/deploy/DeploymentPlanningManager.java
diff --git a/engine/components-api/src/com/cloud/event/UsageEventUtils.java b/engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java
similarity index 100%
rename from engine/components-api/src/com/cloud/event/UsageEventUtils.java
rename to engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java
diff --git a/engine/components-api/src/com/cloud/ha/HighAvailabilityManager.java b/engine/components-api/src/main/java/com/cloud/ha/HighAvailabilityManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/ha/HighAvailabilityManager.java
rename to engine/components-api/src/main/java/com/cloud/ha/HighAvailabilityManager.java
diff --git a/engine/components-api/src/com/cloud/hypervisor/HypervisorGuruManager.java b/engine/components-api/src/main/java/com/cloud/hypervisor/HypervisorGuruManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/hypervisor/HypervisorGuruManager.java
rename to engine/components-api/src/main/java/com/cloud/hypervisor/HypervisorGuruManager.java
diff --git a/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java b/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java
new file mode 100644
index 0000000..a551278
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java
@@ -0,0 +1,194 @@
+// 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.network;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.user.Account;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface IpAddressManager {
+    String UseSystemPublicIpsCK = "use.system.public.ips";
+    ConfigKey<Boolean> UseSystemPublicIps = new ConfigKey<Boolean>("Advanced", Boolean.class, UseSystemPublicIpsCK, "true",
+            "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool",
+            true, ConfigKey.Scope.Account);
+
+    ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
+            "When true, ip address delete (ipassoc) failures are  ignored", true);
+
+    /**
+     * Assigns a new public ip address.
+     *
+     * @param dcId
+     * @param podId
+     * @param owner
+     * @param type
+     * @param networkId
+     * @param requestedIp
+     * @param isSystem
+     * @return
+     * @throws InsufficientAddressCapacityException
+     */
+    PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
+            throws InsufficientAddressCapacityException;
+
+    /**
+     * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects.
+     *
+     * @param userId
+     * @param caller
+     * @param caller
+     * @return true if it did; false if it didn't
+     */
+    boolean disassociatePublicIpAddress(long id, long userId, Account caller);
+
+    boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
+            throws ResourceUnavailableException;
+
+    /**
+     * @param userId
+     * @param accountId
+     * @param zoneId
+     * @param vlanId
+     * @param guestNetwork
+     * @throws InsufficientCapacityException
+     * @throws ConcurrentOperationException
+     * @throws ResourceUnavailableException
+     * @throws ResourceAllocationException
+     *             Associates an ip address list to an account. The list of ip addresses are all addresses associated
+     *             with the
+     *             given vlan id.
+     */
+    boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException,
+            ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;
+
+    boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException;
+
+    boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<? extends PublicIpAddress> publicIps)
+            throws ResourceUnavailableException;
+
+    IPAddressVO markIpAsUnavailable(long addrId);
+
+    String acquireGuestIpAddress(Network network, String requestedIp);
+
+    boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException;
+
+    IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException;
+
+    boolean handleSystemIpRelease(IpAddress ip);
+
+    void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
+
+    /**
+     * @param owner
+     * @param guestNetwork
+     * @return
+     * @throws ConcurrentOperationException
+     * @throws InsufficientAddressCapacityException
+     */
+    PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException;
+
+    /**
+     *
+     * @param ipAddrId
+     * @param networkId
+     * @param releaseOnFailure
+     * @return
+     * @throws ResourceAllocationException
+     * @throws ResourceUnavailableException
+     * @throws InsufficientAddressCapacityException
+     * @throws ConcurrentOperationException
+     */
+    IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException;
+
+    IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) throws ConcurrentOperationException,
+            ResourceAllocationException, InsufficientAddressCapacityException;
+
+    boolean releasePortableIpAddress(long addrId);
+
+    IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException,
+            ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException;
+
+    IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException;
+
+    boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId);
+
+    void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException;;
+
+    /**
+     * @param addr
+     */
+    void markPublicIpAsAllocated(IPAddressVO addr);
+
+    /**
+     * @param owner
+     * @param guestNtwkId
+     * @param vpcId
+     * @param dcId
+     * @param isSourceNat
+     * @return
+     * @throws ConcurrentOperationException
+     * @throws InsufficientAddressCapacityException
+     */
+    PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat)
+            throws ConcurrentOperationException, InsufficientAddressCapacityException;
+
+    IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp)
+            throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException;
+
+    PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
+            throws InsufficientAddressCapacityException;
+
+    @DB
+    void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
+
+    int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
+
+    String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException;
+
+    String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
+
+    AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException;
+
+    public boolean isIpEqualsGatewayOrNetworkOfferingsEmpty(Network network, String requestedIp);
+
+    void releasePodIp(Long id) throws CloudRuntimeException;
+}
+
diff --git a/engine/components-api/src/com/cloud/network/NetworkStateListener.java b/engine/components-api/src/main/java/com/cloud/network/NetworkStateListener.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/NetworkStateListener.java
rename to engine/components-api/src/main/java/com/cloud/network/NetworkStateListener.java
diff --git a/engine/components-api/src/com/cloud/network/addr/PublicIp.java b/engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/addr/PublicIp.java
rename to engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java
diff --git a/engine/components-api/src/com/cloud/network/lb/LoadBalancingRulesManager.java b/engine/components-api/src/main/java/com/cloud/network/lb/LoadBalancingRulesManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/lb/LoadBalancingRulesManager.java
rename to engine/components-api/src/main/java/com/cloud/network/lb/LoadBalancingRulesManager.java
diff --git a/engine/components-api/src/com/cloud/network/rules/FirewallManager.java b/engine/components-api/src/main/java/com/cloud/network/rules/FirewallManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/rules/FirewallManager.java
rename to engine/components-api/src/main/java/com/cloud/network/rules/FirewallManager.java
diff --git a/engine/components-api/src/com/cloud/network/rules/RulesManager.java b/engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/rules/RulesManager.java
rename to engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java
diff --git a/engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java b/engine/components-api/src/main/java/com/cloud/network/rules/StaticNatRuleImpl.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/rules/StaticNatRuleImpl.java
rename to engine/components-api/src/main/java/com/cloud/network/rules/StaticNatRuleImpl.java
diff --git a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
new file mode 100644
index 0000000..4200ea8
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
@@ -0,0 +1,94 @@
+// 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.network.vpc;
+
+import java.util.List;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.dao.NetworkVO;
+
+public interface NetworkACLManager {
+
+    /**
+     * Creates Network ACL for the specified VPC
+     */
+    NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay);
+
+    /**
+     * Fetches Network ACL with specified Id
+     */
+    NetworkACL getNetworkACL(long id);
+
+    /**
+     * Applies the items in the ACL to all associated networks
+     */
+    boolean applyNetworkACL(long aclId) throws ResourceUnavailableException;
+
+    /**
+     * Deletes the specified Network ACL
+     */
+    boolean deleteNetworkACL(NetworkACL acl);
+
+    /**
+     * Associates ACL with a network and applies the ACLItems
+     */
+    boolean replaceNetworkACL(NetworkACL acl, NetworkVO network) throws ResourceUnavailableException;
+
+    /**
+     * Creates a Network ACL Item within an ACL and applies it to associated networks
+     */
+    NetworkACLItem createNetworkACLItem(NetworkACLItemVO networkACLItemVO);
+
+    /**
+     * Returns Network ACL Item with specified Id
+     */
+    NetworkACLItem getNetworkACLItem(long ruleId);
+
+    /**
+     * Revoke ACL Item and apply changes
+     */
+    boolean revokeNetworkACLItem(long ruleId);
+
+    /**
+     * Revoke ACL Items for network and remove them in back-end. Db is not updated
+     */
+    boolean revokeACLItemsForNetwork(long networkId) throws ResourceUnavailableException;
+
+    /**
+     * List network ACL items by network
+     */
+    List<NetworkACLItemVO> listNetworkACLItems(long guestNtwkId);
+
+    /**
+     * Applies associated ACL to specified network
+     */
+    boolean applyACLToNetwork(long networkId) throws ResourceUnavailableException;
+
+    /**
+     * Updates and existing network ACL Item
+     */
+    NetworkACLItem updateNetworkACLItem(NetworkACLItemVO networkACLItemVO) throws ResourceUnavailableException;
+
+    /**
+     * Associates ACL with a network and applies the ACLItems
+     */
+    boolean replaceNetworkACLForPrivateGw(NetworkACL acl, PrivateGateway gateway) throws ResourceUnavailableException;
+
+    boolean revokeACLItemsForPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException;
+
+    boolean applyACLToPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException;
+}
diff --git a/engine/components-api/src/com/cloud/network/vpc/VpcManager.java b/engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/network/vpc/VpcManager.java
rename to engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java
diff --git a/engine/components-api/src/com/cloud/resource/Discoverer.java b/engine/components-api/src/main/java/com/cloud/resource/Discoverer.java
similarity index 100%
rename from engine/components-api/src/com/cloud/resource/Discoverer.java
rename to engine/components-api/src/main/java/com/cloud/resource/Discoverer.java
diff --git a/engine/components-api/src/com/cloud/resource/ResourceManager.java b/engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/resource/ResourceManager.java
rename to engine/components-api/src/main/java/com/cloud/resource/ResourceManager.java
diff --git a/engine/components-api/src/com/cloud/resource/ResourceStateAdapter.java b/engine/components-api/src/main/java/com/cloud/resource/ResourceStateAdapter.java
similarity index 100%
rename from engine/components-api/src/com/cloud/resource/ResourceStateAdapter.java
rename to engine/components-api/src/main/java/com/cloud/resource/ResourceStateAdapter.java
diff --git a/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java
new file mode 100644
index 0000000..fd98101
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java
@@ -0,0 +1,225 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.StorageConflictException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.utils.Pair;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VMInstanceVO;
+
+public interface StorageManager extends StorageService {
+    ConfigKey<Integer> StorageCleanupInterval = new ConfigKey<>(Integer.class,
+            "storage.cleanup.interval",
+            "Advanced",
+            "86400",
+            "The interval (in seconds) to wait before running the storage cleanup thread.",
+            false,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Integer> StorageCleanupDelay = new ConfigKey<>(Integer.class,
+            "storage.cleanup.delay",
+            "Advanced",
+            "86400",
+            "Determines how long (in seconds) to wait before actually expunging destroyed volumes. The default value = the default value of storage.cleanup.interval.",
+            false,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Boolean> StorageCleanupEnabled = new ConfigKey<>(Boolean.class,
+            "storage.cleanup.enabled",
+            "Advanced",
+            "true",
+            "Enables/disables the storage cleanup thread.",
+            false,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Boolean> TemplateCleanupEnabled = new ConfigKey<>(Boolean.class,
+            "storage.template.cleanup.enabled",
+            "Storage",
+            "true",
+            "Enable/disable template cleanup activity, only take effect when overall storage cleanup is enabled",
+            false,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Integer> KvmStorageOfflineMigrationWait = new ConfigKey<>(Integer.class,
+            "kvm.storage.offline.migration.wait",
+            "Storage",
+            "10800",
+            "Timeout in seconds for offline (non-live) storage migration to complete on KVM",
+            true,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Integer> KvmStorageOnlineMigrationWait = new ConfigKey<>(Integer.class,
+            "kvm.storage.online.migration.wait",
+            "Storage",
+            "10800",
+            "Timeout in seconds for online (live) storage migration to complete on KVM (migrateVirtualMachineWithVolume)",
+            true,
+            ConfigKey.Scope.Global,
+            null);
+    ConfigKey<Integer> MaxNumberOfManagedClusteredFileSystems = new ConfigKey<>(Integer.class,
+            "max.number.managed.clustered.file.systems",
+            "Storage",
+            "200",
+            "XenServer and VMware only: Maximum number of managed SRs or datastores per compute cluster",
+            true,
+            ConfigKey.Scope.Cluster,
+            null);
+
+    ConfigKey<Integer> PRIMARY_STORAGE_DOWNLOAD_WAIT = new ConfigKey<Integer>("Storage", Integer.class, "primary.storage.download.wait", "10800",
+            "In second, timeout for download template to primary storage", false);
+
+    /**
+     * Returns a comma separated list of tags for the specified storage pool
+     * @param poolId
+     * @return comma separated list of tags
+     */
+    String getStoragePoolTags(long poolId);
+
+    /**
+     * Returns a list of Strings with tags for the specified storage pool
+     * @param poolId
+     * @return comma separated list of tags
+     */
+    List<String> getStoragePoolTagList(long poolId);
+
+    Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException;
+
+    Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException;
+
+    Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException;
+
+    Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException;
+
+    Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException;
+
+    Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
+
+    /**
+     * Checks if a host has running VMs that are using its local storage pool.
+     * @return true if local storage is active on the host
+     */
+    boolean isLocalStorageActiveOnHost(Long hostId);
+
+    /**
+     * Cleans up storage pools by removing unused templates.
+     * @param recurring - true if this cleanup is part of a recurring garbage collection thread
+     */
+    void cleanupStorage(boolean recurring);
+
+    String getPrimaryStorageNameLabel(VolumeVO volume);
+
+    void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated);
+
+    Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException;
+
+    CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId);
+
+    CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId);
+
+    List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type);
+
+    List<VMInstanceVO> listByStoragePool(long storagePoolId);
+
+    StoragePoolVO findLocalStorageOnHost(long hostId);
+
+    Host updateSecondaryStorage(long secStorageId, String newUrl);
+
+    void removeStoragePoolFromCluster(long hostId, String iScsiName, StoragePool storagePool);
+
+    List<Long> getUpHostsInPool(long poolId);
+
+    void cleanupSecondaryStorage(boolean recurring);
+
+    HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
+
+    boolean storagePoolHasEnoughIops(List<Volume> volume, StoragePool pool);
+
+    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
+
+    /**
+     * This comment is relevant to managed storage only.
+     *
+     *  Long clusterId = only used for managed storage
+     *
+     *  Some managed storage can be more efficient handling VM templates (via cloning) if it knows the capabilities of the compute cluster it is dealing with.
+     *  If the compute cluster supports UUID resigning and the storage system can clone a volume from a volume, then this determines how much more space a
+     *  new root volume (that makes use of a template) will take up on the storage system.
+     *
+     *  For example, if a storage system can clone a volume from a volume and the compute cluster supports UUID resigning (relevant for hypervisors like
+     *  XenServer and ESXi that put virtual disks in clustered file systems), then the storage system will need to determine if it already has a copy of
+     *  the template or if it will need to create one first before cloning the template to a new volume to be used for the new root disk (assuming the root
+     *  disk is being deployed from a template). If the template doesn't already exists on the storage system, then you need to take into consideration space
+     *  required for that template (stored in one volume) and space required for a new volume created from that template volume (for your new root volume).
+     *
+     *  If UUID resigning is not available in the compute cluster or the storage system doesn't support cloning a volume from a volume, then for each new
+     *  root disk that uses a template, CloudStack will have the template be copied down to a newly created volume on the storage system (i.e. no need
+     *  to take into consideration the possible need to first create a volume on the storage system for a template that will be used for the root disk
+     *  via cloning).
+     *
+     *  Cloning volumes on the back-end instead of copying down a new template for each new volume helps to alleviate load on the hypervisors.
+     */
+    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool, Long clusterId);
+
+    boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSiz);
+
+    boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
+
+    void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
+
+    void createCapacityEntry(long poolId);
+
+    DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws ConnectionException;
+
+    BigDecimal getStorageOverProvisioningFactor(Long dcId);
+
+    Long getDiskBytesReadRate(ServiceOffering offering, DiskOffering diskOffering);
+
+    Long getDiskBytesWriteRate(ServiceOffering offering, DiskOffering diskOffering);
+
+    Long getDiskIopsReadRate(ServiceOffering offering, DiskOffering diskOffering);
+
+    Long getDiskIopsWriteRate(ServiceOffering offering, DiskOffering diskOffering);
+
+    void cleanupDownloadUrls();
+
+    void setDiskProfileThrottling(DiskProfile dskCh, ServiceOffering offering, DiskOffering diskOffering);
+
+    DiskTO getDiskWithThrottling(DataTO volTO, Volume.Type volumeType, long deviceId, String path, long offeringId, long diskOfferingId);
+
+}
diff --git a/engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java b/engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java
new file mode 100644
index 0000000..97354e2
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/storage/StorageUtil.java
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.List;
+import javax.inject.Inject;
+
+public class StorageUtil {
+    @Inject private ClusterDao clusterDao;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private VMInstanceDao vmInstanceDao;
+    @Inject private VolumeDao volumeDao;
+
+    private Long getClusterId(Long hostId) {
+        if (hostId == null) {
+            return null;
+        }
+
+        HostVO hostVO = hostDao.findById(hostId);
+
+        if (hostVO == null) {
+            return null;
+        }
+
+        return hostVO.getClusterId();
+    }
+
+    /**
+     * This method relates to managed storage only. CloudStack currently supports managed storage with XenServer, vSphere, and KVM.
+     * With managed storage on XenServer and vSphere, CloudStack needs to use an iSCSI SR (XenServer) or datastore (vSphere) per CloudStack
+     * volume. Since XenServer and vSphere are limited to the hundreds with regards to how many SRs or datastores can be leveraged per
+     * compute cluster, this method is used to check a Global Setting (that specifies the maximum number of SRs or datastores per compute cluster)
+     * against what is being requested. KVM does not apply here here because it does not suffer from the same scalability limits as XenServer and
+     * vSphere do. With XenServer and vSphere, each host is configured to see all the SRs/datastores of the cluster. With KVM, each host typically
+     * is only configured to see the managed volumes of the VMs that are currently running on that host.
+     *
+     * If the clusterId is passed in, we use it. Otherwise, we use the hostId. If neither leads to a cluster, we just return true.
+     */
+    public boolean managedStoragePoolCanScale(StoragePool storagePool, Long clusterId, Long hostId) {
+        if (clusterId == null) {
+            clusterId = getClusterId(hostId);
+
+            if (clusterId == null) {
+                return true;
+            }
+        }
+
+        ClusterVO clusterVO = clusterDao.findById(clusterId);
+
+        if (clusterVO == null) {
+            return true;
+        }
+
+        Hypervisor.HypervisorType hypervisorType = clusterVO.getHypervisorType();
+
+        if (hypervisorType == null) {
+            return true;
+        }
+
+        if (Hypervisor.HypervisorType.XenServer.equals(hypervisorType) || Hypervisor.HypervisorType.VMware.equals(hypervisorType)) {
+            int maxValue = StorageManager.MaxNumberOfManagedClusteredFileSystems.valueIn(clusterId);
+
+            return getNumberOfManagedClusteredFileSystemsInComputeCluster(storagePool.getDataCenterId(), clusterId) < maxValue;
+        }
+
+        return true;
+    }
+
+    private int getNumberOfManagedClusteredFileSystemsInComputeCluster(long zoneId, long clusterId) {
+        int numberOfManagedClusteredFileSystemsInComputeCluster = 0;
+
+        List<VolumeVO> volumes = volumeDao.findByDc(zoneId);
+
+        if (CollectionUtils.isEmpty(volumes)) {
+            return numberOfManagedClusteredFileSystemsInComputeCluster;
+        }
+
+        for (VolumeVO volume : volumes) {
+            Long instanceId = volume.getInstanceId();
+
+            if (instanceId == null) {
+                continue;
+            }
+
+            VMInstanceVO vmInstanceVO = vmInstanceDao.findById(instanceId);
+
+            if (vmInstanceVO == null) {
+                continue;
+            }
+
+            Long vmHostId = vmInstanceVO.getHostId();
+
+            if (vmHostId == null) {
+                vmHostId = vmInstanceVO.getLastHostId();
+            }
+
+            if (vmHostId == null) {
+                continue;
+            }
+
+            HostVO vmHostVO = hostDao.findById(vmHostId);
+
+            if (vmHostVO == null) {
+                continue;
+            }
+
+            Long vmHostClusterId = vmHostVO.getClusterId();
+
+            if (vmHostClusterId != null && vmHostClusterId == clusterId) {
+                StoragePoolVO storagePoolVO = storagePoolDao.findById(volume.getPoolId());
+
+                if (storagePoolVO != null && storagePoolVO.isManaged()) {
+                    numberOfManagedClusteredFileSystemsInComputeCluster++;
+                }
+            }
+        }
+
+        return numberOfManagedClusteredFileSystemsInComputeCluster;
+    }
+}
diff --git a/engine/components-api/src/com/cloud/template/TemplateManager.java b/engine/components-api/src/main/java/com/cloud/template/TemplateManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/template/TemplateManager.java
rename to engine/components-api/src/main/java/com/cloud/template/TemplateManager.java
diff --git a/engine/components-api/src/com/cloud/vm/ReservationContextImpl.java b/engine/components-api/src/main/java/com/cloud/vm/ReservationContextImpl.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/ReservationContextImpl.java
rename to engine/components-api/src/main/java/com/cloud/vm/ReservationContextImpl.java
diff --git a/engine/components-api/src/com/cloud/vm/VirtualMachineProfileImpl.java b/engine/components-api/src/main/java/com/cloud/vm/VirtualMachineProfileImpl.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VirtualMachineProfileImpl.java
rename to engine/components-api/src/main/java/com/cloud/vm/VirtualMachineProfileImpl.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWork.java b/engine/components-api/src/main/java/com/cloud/vm/VmWork.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWork.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWork.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkAttachVolume.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkAttachVolume.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkAttachVolume.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkAttachVolume.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkConstants.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkConstants.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkConstants.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkConstants.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkDetachVolume.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkDetachVolume.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkDetachVolume.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkDetachVolume.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkExtractVolume.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkExtractVolume.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkExtractVolume.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkExtractVolume.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkJobHandler.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkJobHandler.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkJobHandler.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkJobHandler.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkJobHandlerProxy.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkJobHandlerProxy.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkJobHandlerProxy.java
diff --git a/engine/components-api/src/main/java/com/cloud/vm/VmWorkMigrateVolume.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkMigrateVolume.java
new file mode 100644
index 0000000..e8ddf9b
--- /dev/null
+++ b/engine/components-api/src/main/java/com/cloud/vm/VmWorkMigrateVolume.java
@@ -0,0 +1,50 @@
+// 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.vm;
+
+public class VmWorkMigrateVolume extends VmWork {
+    private static final long serialVersionUID = -565778516928408602L;
+
+    private long volumeId;
+    private long destPoolId;
+    private boolean liveMigrate;
+    private Long newDiskOfferingId;
+
+    public VmWorkMigrateVolume(long userId, long accountId, long vmId, String handlerName, long volumeId, long destPoolId, boolean liveMigrate, Long newDiskOfferingId) {
+        super(userId, accountId, vmId, handlerName);
+        this.volumeId = volumeId;
+        this.destPoolId = destPoolId;
+        this.liveMigrate = liveMigrate;
+        this.newDiskOfferingId = newDiskOfferingId;
+    }
+
+    public long getVolumeId() {
+        return volumeId;
+    }
+
+    public long getDestPoolId() {
+        return destPoolId;
+    }
+
+    public boolean isLiveMigrate() {
+        return liveMigrate;
+    }
+
+    public Long getNewDiskOfferingId() {
+        return newDiskOfferingId;
+    }
+}
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkResizeVolume.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkResizeVolume.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkResizeVolume.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkResizeVolume.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkSerializer.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkSerializer.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkSerializer.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkSerializer.java
diff --git a/engine/components-api/src/com/cloud/vm/VmWorkTakeVolumeSnapshot.java b/engine/components-api/src/main/java/com/cloud/vm/VmWorkTakeVolumeSnapshot.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/VmWorkTakeVolumeSnapshot.java
rename to engine/components-api/src/main/java/com/cloud/vm/VmWorkTakeVolumeSnapshot.java
diff --git a/engine/components-api/src/com/cloud/vm/snapshot/VMSnapshotManager.java b/engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java
similarity index 100%
rename from engine/components-api/src/com/cloud/vm/snapshot/VMSnapshotManager.java
rename to engine/components-api/src/main/java/com/cloud/vm/snapshot/VMSnapshotManager.java
diff --git a/engine/components-api/src/org/apache/cloudstack/compute/ComputeGuru.java b/engine/components-api/src/main/java/org/apache/cloudstack/compute/ComputeGuru.java
similarity index 100%
rename from engine/components-api/src/org/apache/cloudstack/compute/ComputeGuru.java
rename to engine/components-api/src/main/java/org/apache/cloudstack/compute/ComputeGuru.java
diff --git a/engine/components-api/src/main/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml b/engine/components-api/src/main/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml
new file mode 100644
index 0000000..be02640
--- /dev/null
+++ b/engine/components-api/src/main/resources/META-INF/cloudstack/core/spring-engine-components-api-core-context.xml
@@ -0,0 +1,30 @@
+<!--
+  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"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context.xsd"
+                      >
+    <bean id="storageUtil" class="com.cloud.storage.StorageUtil" />
+</beans>
diff --git a/engine/network/pom.xml b/engine/network/pom.xml
index 7a8ce52..4e34bc1 100644
--- a/engine/network/pom.xml
+++ b/engine/network/pom.xml
@@ -1,52 +1,47 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine-network</artifactId>
-  <name>Apache CloudStack Cloud Engine API</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-  </build>
+    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-engine-network</artifactId>
+    <name>Apache CloudStack Cloud Engine API</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/network/src/org/apache/cloudstack/network/NetworkOrchestrator.java b/engine/network/src/main/java/org/apache/cloudstack/network/NetworkOrchestrator.java
similarity index 100%
rename from engine/network/src/org/apache/cloudstack/network/NetworkOrchestrator.java
rename to engine/network/src/main/java/org/apache/cloudstack/network/NetworkOrchestrator.java
diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml
index 2699cda..b677004 100755
--- a/engine/orchestration/pom.xml
+++ b/engine/orchestration/pom.xml
@@ -1,90 +1,90 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine-orchestration</artifactId>
-  <name>Apache CloudStack Cloud Engine Orchestration Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-agent-lb</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-engine-orchestration</artifactId>
+    <name>Apache CloudStack Cloud Engine Orchestration Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-agent-lb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java
deleted file mode 100644
index 9626385..0000000
--- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ /dev/null
@@ -1,1806 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.manager;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.channels.ClosedChannelException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.agent.lb.IndirectAgentLB;
-import org.apache.cloudstack.ca.CAManager;
-import com.cloud.configuration.ManagementServiceConfiguration;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-import org.slf4j.MDC;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.StartupCommandProcessor;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.PingAnswer;
-import com.cloud.agent.api.PingCommand;
-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;
-import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.agent.transport.Request;
-import com.cloud.agent.transport.Response;
-import com.cloud.alert.AlertManager;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.UnsupportedVersionException;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Status.Event;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.resource.Discoverer;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.resource.ServerResource;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.HypervisorVersionChangedException;
-import com.cloud.utils.exception.NioConnectionException;
-import com.cloud.utils.exception.TaskExecutionException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.nio.HandlerFactory;
-import com.cloud.utils.nio.Link;
-import com.cloud.utils.nio.NioServer;
-import com.cloud.utils.nio.Task;
-import com.cloud.utils.time.InaccurateClock;
-import com.google.common.base.Strings;
-
-/**
- * Implementation of the Agent Manager. This class controls the connection to the agents.
- **/
-public class AgentManagerImpl extends ManagerBase implements AgentManager, HandlerFactory, Configurable {
-    protected static final Logger s_logger = Logger.getLogger(AgentManagerImpl.class);
-    protected static final Logger status_logger = Logger.getLogger(Status.class);
-
-    /**
-     * _agents is a ConcurrentHashMap, but it is used from within a synchronized block. This will be reported by findbugs as JLM_JSR166_UTILCONCURRENT_MONITORENTER. Maybe a
-     * ConcurrentHashMap is not the right thing to use here, but i'm not sure so i leave it alone.
-     */
-    protected ConcurrentHashMap<Long, AgentAttache> _agents = new ConcurrentHashMap<Long, AgentAttache>(10007);
-    protected List<Pair<Integer, Listener>> _hostMonitors = new ArrayList<Pair<Integer, Listener>>(17);
-    protected List<Pair<Integer, Listener>> _cmdMonitors = new ArrayList<Pair<Integer, Listener>>(17);
-    protected List<Pair<Integer, StartupCommandProcessor>> _creationMonitors = new ArrayList<Pair<Integer, StartupCommandProcessor>>(17);
-    protected List<Long> _loadingAgents = new ArrayList<Long>();
-    protected int _monitorId = 0;
-    private final Lock _agentStatusLock = new ReentrantLock();
-
-    @Inject
-    protected CAManager caService;
-    @Inject
-    protected EntityManager _entityMgr;
-
-    protected NioServer _connection;
-    @Inject
-    protected HostDao _hostDao = null;
-    @Inject
-    protected OutOfBandManagementDao outOfBandManagementDao;
-    @Inject
-    protected DataCenterDao _dcDao = null;
-    @Inject
-    protected HostPodDao _podDao = null;
-    @Inject
-    protected ConfigurationDao _configDao = null;
-    @Inject
-    protected ClusterDao _clusterDao = null;
-
-    @Inject
-    protected HighAvailabilityManager _haMgr = null;
-    @Inject
-    protected AlertManager _alertMgr = null;
-
-    @Inject
-    protected HypervisorGuruManager _hvGuruMgr;
-
-    @Inject
-    protected IndirectAgentLB indirectAgentLB;
-
-    protected int _retry = 2;
-
-    protected long _nodeId = -1;
-
-    protected ExecutorService _executor;
-    protected ThreadPoolExecutor _connectExecutor;
-    protected ScheduledExecutorService _directAgentExecutor;
-    protected ScheduledExecutorService _cronJobExecutor;
-    protected ScheduledExecutorService _monitorExecutor;
-
-    private int _directAgentThreadCap;
-
-    protected StateMachine2<Status, Status.Event, Host> _statusStateMachine = Status.getStateMachine();
-    private final ConcurrentHashMap<Long, Long> _pingMap = new ConcurrentHashMap<Long, Long>(10007);
-
-    @Inject
-    ResourceManager _resourceMgr;
-
-    @Inject
-    ManagementServiceConfiguration mgmtServiceConf;
-
-    protected final ConfigKey<Integer> Workers = new ConfigKey<Integer>("Advanced", Integer.class, "workers", "5",
-                    "Number of worker threads handling remote agent connections.", false);
-    protected final ConfigKey<Integer> Port = new ConfigKey<Integer>("Advanced", Integer.class, "port", "8250", "Port to listen on for remote agent connections.", false);
-    protected final ConfigKey<Integer> AlertWait = new ConfigKey<Integer>("Advanced", Integer.class, "alert.wait", "1800",
-                    "Seconds to wait before alerting on a disconnected agent", true);
-    protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.load.size", "16",
-                    "The number of direct agents to load each time", false);
-    protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.pool.size", "500",
-                    "Default size for DirectAgentPool", false);
-    protected final ConfigKey<Float> DirectAgentThreadCap = new ConfigKey<Float>("Advanced", Float.class, "direct.agent.thread.cap", "1",
-                    "Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false);
-    protected final ConfigKey<Boolean> CheckTxnBeforeSending = new ConfigKey<Boolean>(
-                    "Developer",
-                    Boolean.class,
-                    "check.txn.before.sending.agent.commands",
-                    "false",
-                    "This parameter allows developers to enable a check to see if a transaction wraps commands that are sent to the resource.  This is not to be enabled on production systems.",
-                    true);
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        s_logger.info("Ping Timeout is " + mgmtServiceConf.getPingTimeout());
-
-        final int threads = DirectAgentLoadSize.value();
-
-        _nodeId = ManagementServerNode.getManagementServerId();
-        s_logger.info("Configuring AgentManagerImpl. management server node id(msid): " + _nodeId);
-
-        final long lastPing = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
-        _hostDao.markHostsAsDisconnected(_nodeId, lastPing);
-
-        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"));
-        // allow core threads to time out even when there are no items in the queue
-        _connectExecutor.allowCoreThreadTimeOut(true);
-
-        _connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10, this, caService);
-        s_logger.info("Listening on " + Port.value() + " with " + Workers.value() + " workers");
-
-        // executes all agent commands other than cron and ping
-        _directAgentExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgent"));
-        // executes cron and ping agent commands
-        _cronJobExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgentCronJob"));
-        s_logger.debug("Created DirectAgentAttache pool with size: " + DirectAgentPoolSize.value());
-        _directAgentThreadCap = Math.round(DirectAgentPoolSize.value() * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0
-
-        _monitorExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("AgentMonitor"));
-
-        return true;
-    }
-
-
-    @Override
-    public Task create(final Task.Type type, final Link link, final byte[] data) {
-        return new AgentHandler(type, link, data);
-    }
-
-    @Override
-    public int registerForHostEvents(final Listener listener, final boolean connections, final boolean commands, final boolean priority) {
-        synchronized (_hostMonitors) {
-            _monitorId++;
-            if (connections) {
-                if (priority) {
-                    _hostMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
-                } else {
-                    _hostMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
-                }
-            }
-            if (commands) {
-                if (priority) {
-                    _cmdMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
-                } else {
-                    _cmdMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
-                }
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Registering listener " + listener.getClass().getSimpleName() + " with id " + _monitorId);
-            }
-            return _monitorId;
-        }
-    }
-
-    @Override
-    public int registerForInitialConnects(final StartupCommandProcessor creator, final boolean priority) {
-        synchronized (_hostMonitors) {
-            _monitorId++;
-            if (priority) {
-                _creationMonitors.add(0, new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
-            } else {
-                _creationMonitors.add(new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
-            }
-            return _monitorId;
-        }
-    }
-
-    @Override
-    public void unregisterForHostEvents(final int id) {
-        s_logger.debug("Deregistering " + id);
-        _hostMonitors.remove(id);
-    }
-
-    private AgentControlAnswer handleControlCommand(final AgentAttache attache, final AgentControlCommand cmd) {
-        AgentControlAnswer answer = null;
-
-        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
-            answer = listener.second().processControlCommand(attache.getId(), cmd);
-
-            if (answer != null) {
-                return answer;
-            }
-        }
-
-        s_logger.warn("No handling of agent control command: " + cmd + " sent from " + attache.getId());
-        return new AgentControlAnswer(cmd);
-    }
-
-    public void handleCommands(final AgentAttache attache, final long sequence, final Command[] cmds) {
-        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
-            final boolean processed = listener.second().processCommands(attache.getId(), sequence, cmds);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("SeqA " + attache.getId() + "-" + sequence + ": " + (processed ? "processed" : "not processed") + " by " + listener.getClass());
-            }
-        }
-    }
-
-    public void notifyAnswersToMonitors(final long agentId, final long seq, final Answer[] answers) {
-        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
-            listener.second().processAnswers(agentId, seq, answers);
-        }
-    }
-
-    public AgentAttache findAttache(final long hostId) {
-        AgentAttache attache = null;
-        synchronized (_agents) {
-            attache = _agents.get(hostId);
-        }
-        return attache;
-    }
-
-    @Override
-    public Answer sendTo(final Long dcId, final HypervisorType type, final Command cmd) {
-        final List<ClusterVO> clusters = _clusterDao.listByDcHyType(dcId, type.toString());
-        int retry = 0;
-        for (final ClusterVO cluster : clusters) {
-            final List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), null, dcId);
-            for (final HostVO host : hosts) {
-                retry++;
-                if (retry > _retry) {
-                    return null;
-                }
-                Answer answer = null;
-                try {
-
-                    final long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(host.getId(), cmd);
-                    answer = easySend(targetHostId, cmd);
-                } catch (final Exception e) {
-                }
-                if (answer != null) {
-                    return answer;
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Answer send(final Long hostId, final Command cmd) throws AgentUnavailableException, OperationTimedoutException {
-        final Commands cmds = new Commands(Command.OnError.Stop);
-        cmds.addCommand(cmd);
-        send(hostId, cmds, cmd.getWait());
-        final Answer[] answers = cmds.getAnswers();
-        if (answers != null && !(answers[0] instanceof UnsupportedAnswer)) {
-            return answers[0];
-        }
-
-        if (answers != null && answers[0] instanceof UnsupportedAnswer) {
-            s_logger.warn("Unsupported Command: " + answers[0].getDetails());
-            return answers[0];
-        }
-
-        return null;
-    }
-
-    @DB
-    protected boolean noDbTxn() {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        return !txn.dbTxnStarted();
-    }
-
-    private static void tagCommand(final Command cmd) {
-        final AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrent();
-        if (context != null && context.getJob() != null) {
-            final AsyncJob job = context.getJob();
-
-            if (job.getRelated() != null && !job.getRelated().isEmpty()) {
-                cmd.setContextParam("job", "job-" + job.getRelated() + "/" + "job-" + job.getId());
-            } else {
-                cmd.setContextParam("job", "job-" + job.getId());
-            }
-        }
-        if (MDC.get("logcontextid") != null && !MDC.get("logcontextid").isEmpty()) {
-            cmd.setContextParam("logid", MDC.get("logcontextid"));
-        }
-    }
-
-    /**
-     * @param commands
-     * @return
-     */
-    private Command[] checkForCommandsAndTag(final Commands commands) {
-        final Command[] cmds = commands.toCommands();
-
-        assert cmds.length > 0 : "Ask yourself this about a hundred times.  Why am I  sending zero length commands?";
-
-        setEmptyAnswers(commands, cmds);
-
-        for (final Command cmd : cmds) {
-            tagCommand(cmd);
-        }
-        return cmds;
-    }
-
-    /**
-     * @param commands
-     * @param cmds
-     */
-    private void setEmptyAnswers(final Commands commands, final Command[] cmds) {
-        if (cmds.length == 0) {
-            commands.setAnswers(new Answer[0]);
-        }
-    }
-
-    @Override
-    public Answer[] send(final Long hostId, final Commands commands, int timeout) throws AgentUnavailableException, OperationTimedoutException {
-        assert hostId != null : "Who's not checking the agent id before sending?  ... (finger wagging)";
-        if (hostId == null) {
-            throw new AgentUnavailableException(-1);
-        }
-
-        if (timeout <= 0) {
-            timeout = Wait.value();
-        }
-
-        if (CheckTxnBeforeSending.value()) {
-            if (!noDbTxn()) {
-                throw new CloudRuntimeException("We do not allow transactions to be wrapped around commands sent to be executed on remote agents.  "
-                                + "We cannot predict how long it takes a command to complete.  "
-                                + "The transaction may be rolled back because the connection took too long.");
-            }
-        } else {
-            assert noDbTxn() : "I know, I know.  Why are we so strict as to not allow txn across an agent call?  ...  Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!";
-        }
-
-        final Command[] cmds = checkForCommandsAndTag(commands);
-
-        //check what agent is returned.
-        final AgentAttache agent = getAttache(hostId);
-        if (agent == null || agent.isClosed()) {
-            throw new AgentUnavailableException("agent not logged into this management server", hostId);
-        }
-
-        final Request req = new Request(hostId, agent.getName(), _nodeId, cmds, commands.stopOnError(), true);
-        req.setSequence(agent.getNextSequence());
-        final Answer[] answers = agent.send(req, timeout);
-        notifyAnswersToMonitors(hostId, req.getSequence(), answers);
-        commands.setAnswers(answers);
-        return answers;
-    }
-
-    protected Status investigate(final AgentAttache agent) {
-        final Long hostId = agent.getId();
-        final HostVO host = _hostDao.findById(hostId);
-        if (host != null && host.getType() != null && !host.getType().isVirtual()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("checking if agent (" + hostId + ") is alive");
-            }
-            final Answer answer = easySend(hostId, new CheckHealthCommand());
-            if (answer != null && answer.getResult()) {
-                final Status status = Status.Up;
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is " + status);
-                }
-                return status;
-            }
-            return _haMgr.investigate(hostId);
-        }
-        return Status.Alert;
-    }
-
-    protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
-        if (hostId == null) {
-            return null;
-        }
-        final AgentAttache agent = findAttache(hostId);
-        if (agent == null) {
-            s_logger.debug("Unable to find agent for " + hostId);
-            throw new AgentUnavailableException("Unable to find agent ", hostId);
-        }
-
-        return agent;
-    }
-
-    @Override
-    public long send(final Long hostId, final Commands commands, final Listener listener) throws AgentUnavailableException {
-        final AgentAttache agent = getAttache(hostId);
-        if (agent.isClosed()) {
-            throw new AgentUnavailableException("Agent " + agent.getId() + " is closed", agent.getId());
-        }
-
-        final Command[] cmds = checkForCommandsAndTag(commands);
-
-        final Request req = new Request(hostId, agent.getName(), _nodeId, cmds, commands.stopOnError(), true);
-        req.setSequence(agent.getNextSequence());
-
-        agent.send(req, listener);
-        return req.getSequence();
-    }
-
-    public void removeAgent(final AgentAttache attache, final Status nextState) {
-        if (attache == null) {
-            return;
-        }
-        final long hostId = attache.getId();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Remove Agent : " + hostId);
-        }
-        AgentAttache removed = null;
-        boolean conflict = false;
-        synchronized (_agents) {
-            removed = _agents.remove(hostId);
-            if (removed != null && removed != attache) {
-                conflict = true;
-                _agents.put(hostId, removed);
-                removed = attache;
-            }
-        }
-        if (conflict) {
-            s_logger.debug("Agent for host " + hostId + " is created when it is being disconnected");
-        }
-        if (removed != null) {
-            removed.disconnect(nextState);
-        }
-
-        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Sending Disconnect to listener: " + monitor.second().getClass().getName());
-            }
-            monitor.second().processDisconnect(hostId, nextState);
-        }
-    }
-
-    @Override
-    public void notifyMonitorsOfNewlyAddedHost(long hostId) {
-        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Sending host added to listener: " + monitor.second().getClass().getSimpleName());
-            }
-
-            monitor.second().processHostAdded(hostId);
-        }
-    }
-
-    protected AgentAttache notifyMonitorsOfConnection(final AgentAttache attache, final StartupCommand[] cmd, final boolean forRebalance) throws ConnectionException {
-        final long hostId = attache.getId();
-        final HostVO host = _hostDao.findById(hostId);
-        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Sending Connect to listener: " + monitor.second().getClass().getSimpleName());
-            }
-            for (int i = 0; i < cmd.length; i++) {
-                try {
-                    monitor.second().processConnect(host, cmd[i], forRebalance);
-                } catch (final Exception e) {
-                    if (e instanceof ConnectionException) {
-                        final ConnectionException ce = (ConnectionException) e;
-                        if (ce.isSetupError()) {
-                            s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId +
-                                            " due to " + e.getMessage());
-                            handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
-                            throw ce;
-                        } else {
-                            s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId +
-                                            " due to " + e.getMessage());
-                            handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true);
-                            return attache;
-                        }
-                    } else if (e instanceof HypervisorVersionChangedException) {
-                        handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true);
-                        throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
-                    } else {
-                        s_logger.error("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId +
-                                        " due to " + e.getMessage(), e);
-                        handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
-                        throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
-                    }
-                }
-            }
-        }
-
-        final Long dcId = host.getDataCenterId();
-        final ReadyCommand ready = new ReadyCommand(dcId, host.getId());
-        final Answer answer = easySend(hostId, ready);
-        if (answer == null || !answer.getResult()) {
-            // this is tricky part for secondary storage
-            // make it as disconnected, wait for secondary storage VM to be up
-            // return the attache instead of null, even it is disconnectede
-            handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
-        }
-
-        agentStatusTransitTo(host, Event.Ready, _nodeId);
-        attache.ready();
-        return attache;
-    }
-
-    @Override
-    public boolean start() {
-        startDirectlyConnectedHosts();
-
-        if (_connection != null) {
-            try {
-                _connection.start();
-            } catch (final NioConnectionException e) {
-                s_logger.error("Error when connecting to the NioServer!", e);
-            }
-        }
-
-        _monitorExecutor.scheduleWithFixedDelay(new MonitorTask(), mgmtServiceConf.getPingInterval(), mgmtServiceConf.getPingInterval(), TimeUnit.SECONDS);
-
-        return true;
-    }
-
-    public void startDirectlyConnectedHosts() {
-        final List<HostVO> hosts = _resourceMgr.findDirectlyConnectedHosts();
-        for (final HostVO host : hosts) {
-            loadDirectlyConnectedHost(host, false);
-        }
-    }
-
-    private ServerResource loadResourcesWithoutHypervisor(final HostVO host) {
-        final String resourceName = host.getResource();
-        ServerResource resource = null;
-        try {
-            final Class<?> clazz = Class.forName(resourceName);
-            final Constructor<?> constructor = clazz.getConstructor();
-            resource = (ServerResource) constructor.newInstance();
-        } catch (final ClassNotFoundException e) {
-            s_logger.warn("Unable to find class " + host.getResource(), e);
-        } catch (final InstantiationException e) {
-            s_logger.warn("Unablet to instantiate class " + host.getResource(), e);
-        } catch (final IllegalAccessException e) {
-            s_logger.warn("Illegal access " + host.getResource(), e);
-        } catch (final SecurityException e) {
-            s_logger.warn("Security error on " + host.getResource(), e);
-        } catch (final NoSuchMethodException e) {
-            s_logger.warn("NoSuchMethodException error on " + host.getResource(), e);
-        } catch (final IllegalArgumentException e) {
-            s_logger.warn("IllegalArgumentException error on " + host.getResource(), e);
-        } catch (final InvocationTargetException e) {
-            s_logger.warn("InvocationTargetException error on " + host.getResource(), e);
-        }
-
-        if (resource != null) {
-            _hostDao.loadDetails(host);
-
-            final HashMap<String, Object> params = new HashMap<String, Object>(host.getDetails().size() + 5);
-            params.putAll(host.getDetails());
-
-            params.put("guid", host.getGuid());
-            params.put("zone", Long.toString(host.getDataCenterId()));
-            if (host.getPodId() != null) {
-                params.put("pod", Long.toString(host.getPodId()));
-            }
-            if (host.getClusterId() != null) {
-                params.put("cluster", Long.toString(host.getClusterId()));
-                String guid = null;
-                final ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-                if (cluster.getGuid() == null) {
-                    guid = host.getDetail("pool");
-                } else {
-                    guid = cluster.getGuid();
-                }
-                if (guid != null && !guid.isEmpty()) {
-                    params.put("pool", guid);
-                }
-            }
-
-            params.put("ipaddress", host.getPrivateIpAddress());
-            params.put("secondary.storage.vm", "false");
-
-            try {
-                resource.configure(host.getName(), params);
-            } catch (final ConfigurationException e) {
-                s_logger.warn("Unable to configure resource due to " + e.getMessage());
-                return null;
-            }
-
-            if (!resource.start()) {
-                s_logger.warn("Unable to start the resource");
-                return null;
-            }
-        }
-        return resource;
-    }
-
-    @Override
-    public void rescan() {
-    }
-
-    protected boolean loadDirectlyConnectedHost(final HostVO host, final boolean forRebalance) {
-        boolean initialized = false;
-        ServerResource resource = null;
-        try {
-            // load the respective discoverer
-            final Discoverer discoverer = _resourceMgr.getMatchingDiscover(host.getHypervisorType());
-            if (discoverer == null) {
-                s_logger.info("Could not to find a Discoverer to load the resource: " + host.getId() + " for hypervisor type: " + host.getHypervisorType());
-                resource = loadResourcesWithoutHypervisor(host);
-            } else {
-                resource = discoverer.reloadResource(host);
-            }
-
-            if (resource == null) {
-                s_logger.warn("Unable to load the resource: " + host.getId());
-                return false;
-            }
-
-            initialized = true;
-        } finally {
-            if (!initialized) {
-                if (host != null) {
-                    agentStatusTransitTo(host, Event.AgentDisconnected, _nodeId);
-                }
-            }
-        }
-
-        if (forRebalance) {
-            tapLoadingAgents(host.getId(), TapAgentsAction.Add);
-            final Host h = _resourceMgr.createHostAndAgent(host.getId(), resource, host.getDetails(), false, null, true);
-            tapLoadingAgents(host.getId(), TapAgentsAction.Del);
-
-            return h == null ? false : true;
-        } else {
-            _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails()));
-            return true;
-        }
-    }
-
-    protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) throws ConnectionException {
-        s_logger.debug("create DirectAgentAttache for " + host.getId());
-        final DirectAgentAttache attache = new DirectAgentAttache(this, host.getId(), host.getName(), resource, host.isInMaintenanceStates());
-
-        AgentAttache old = null;
-        synchronized (_agents) {
-            old = _agents.put(host.getId(), attache);
-        }
-        if (old != null) {
-            old.disconnect(Status.Removed);
-        }
-
-        return attache;
-    }
-
-    @Override
-    public boolean stop() {
-
-        if (_connection != null) {
-            _connection.stop();
-        }
-
-        s_logger.info("Disconnecting agents: " + _agents.size());
-        synchronized (_agents) {
-            for (final AgentAttache agent : _agents.values()) {
-                final HostVO host = _hostDao.findById(agent.getId());
-                if (host == null) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Cant not find host " + agent.getId());
-                    }
-                } else {
-                    if (!agent.forForward()) {
-                        agentStatusTransitTo(host, Event.ManagementServerDown, _nodeId);
-                    }
-                }
-            }
-        }
-
-        _connectExecutor.shutdownNow();
-        _monitorExecutor.shutdownNow();
-        return true;
-    }
-
-    protected boolean handleDisconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event, final boolean transitState, final boolean removeAgent) {
-        final long hostId = attache.getId();
-
-        s_logger.info("Host " + hostId + " is disconnecting with event " + event);
-        Status nextStatus = null;
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            s_logger.warn("Can't find host with " + hostId);
-            nextStatus = Status.Removed;
-        } else {
-            final Status currentStatus = host.getStatus();
-            if (currentStatus == Status.Down || currentStatus == Status.Alert || currentStatus == Status.Removed) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Host " + hostId + " is already " + currentStatus);
-                }
-                nextStatus = currentStatus;
-            } else {
-                try {
-                    nextStatus = currentStatus.getNextStatus(event);
-                } catch (final NoTransitionException e) {
-                    final String err = "Cannot find next status for " + event + " as current status is " + currentStatus + " for agent " + hostId;
-                    s_logger.debug(err);
-                    throw new CloudRuntimeException(err);
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("The next status of agent " + hostId + "is " + nextStatus + ", current status is " + currentStatus);
-                }
-            }
-            caService.purgeHostCertificate(host);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deregistering link for " + hostId + " with state " + nextStatus);
-        }
-
-        removeAgent(attache, nextStatus);
-        // update the DB
-        if (host != null && transitState) {
-            disconnectAgent(host, event, _nodeId);
-        }
-
-        return true;
-    }
-
-    protected boolean handleDisconnectWithInvestigation(final AgentAttache attache, Status.Event event) {
-        final long hostId = attache.getId();
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host != null) {
-            Status nextStatus = null;
-            try {
-                nextStatus = host.getStatus().getNextStatus(event);
-            } catch (final NoTransitionException ne) {
-                /*
-                 * Agent may be currently in status of Down, Alert, Removed, namely there is no next status for some events. Why this can happen? Ask God not me. I hate there was
-                 * no piece of comment for code handling race condition. God knew what race condition the code dealt with!
-                 */
-                s_logger.debug("Caught exception while getting agent's next status", ne);
-            }
-
-            if (nextStatus == Status.Alert) {
-                /* OK, we are going to the bad status, let's see what happened */
-                s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event);
-
-                Status determinedState = investigate(attache);
-                // if state cannot be determined do nothing and bail out
-                if (determinedState == null) {
-                    if ((System.currentTimeMillis() >> 10) - host.getLastPinged() > AlertWait.value()) {
-                        s_logger.warn("Agent " + hostId + " state cannot be determined for more than " + AlertWait + "(" + AlertWait.value() + ") seconds, will go to Alert state");
-                        determinedState = Status.Alert;
-                    } else {
-                        s_logger.warn("Agent " + hostId + " state cannot be determined, do nothing");
-                        return false;
-                    }
-                }
-
-                final Status currentStatus = host.getStatus();
-                s_logger.info("The agent from host " + hostId + " state determined is " + determinedState);
-
-                if (determinedState == Status.Down) {
-                    final String message = "Host is down: " + host.getId() + "-" + host.getName() + ". Starting HA on the VMs";
-                    s_logger.error(message);
-                    if (host.getType() != Host.Type.SecondaryStorage && host.getType() != Host.Type.ConsoleProxy) {
-                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host down, " + host.getId(), message);
-                    }
-                    event = Status.Event.HostDown;
-                } else if (determinedState == Status.Up) {
-                    /* Got ping response from host, bring it back */
-                    s_logger.info("Agent is determined to be up and running");
-                    agentStatusTransitTo(host, Status.Event.Ping, _nodeId);
-                    return false;
-                } else if (determinedState == Status.Disconnected) {
-                    s_logger.warn("Agent is disconnected but the host is still up: " + host.getId() + "-" + host.getName());
-                    if (currentStatus == Status.Disconnected) {
-                        if ((System.currentTimeMillis() >> 10) - host.getLastPinged() > AlertWait.value()) {
-                            s_logger.warn("Host " + host.getId() + " has been disconnected past the wait time it should be disconnected.");
-                            event = Status.Event.WaitedTooLong;
-                        } else {
-                            s_logger.debug("Host " + host.getId() + " has been determined to be disconnected but it hasn't passed the wait time yet.");
-                            return false;
-                        }
-                    } else if (currentStatus == Status.Up) {
-                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-                        final HostPodVO podVO = _podDao.findById(host.getPodId());
-                        final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-                        if (host.getType() != Host.Type.SecondaryStorage && host.getType() != Host.Type.ConsoleProxy) {
-                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc,
-                                            "If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, host will go to Alert state");
-                        }
-                        event = Status.Event.AgentDisconnected;
-                    }
-                } else {
-                    // if we end up here we are in alert state, send an alert
-                    final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-                    final HostPodVO podVO = _podDao.findById(host.getPodId());
-                    final String podName = podVO != null ? podVO.getName() : "NO POD";
-                    final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podName;
-                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc,
-                                    "In availability zone " + host.getDataCenterId() + ", host is in alert state: " + host.getId() + "-" + host.getName());
-                }
-            } else {
-                s_logger.debug("The next status of agent " + host.getId() + " is not Alert, no need to investigate what happened");
-            }
-        }
-        handleDisconnectWithoutInvestigation(attache, event, true, true);
-        host = _hostDao.findById(hostId); // Maybe the host magically reappeared?
-        if (host != null && host.getStatus() == Status.Down) {
-            _haMgr.scheduleRestartForVmsOnHost(host, true);
-        }
-        return true;
-    }
-
-    protected class DisconnectTask extends ManagedContextRunnable {
-        AgentAttache _attache;
-        Status.Event _event;
-        boolean _investigate;
-
-        DisconnectTask(final AgentAttache attache, final Status.Event event, final boolean investigate) {
-            _attache = attache;
-            _event = event;
-            _investigate = investigate;
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                if (_investigate == true) {
-                    handleDisconnectWithInvestigation(_attache, _event);
-                } else {
-                    handleDisconnectWithoutInvestigation(_attache, _event, true, false);
-                }
-            } catch (final Exception e) {
-                s_logger.error("Exception caught while handling disconnect: ", e);
-            }
-        }
-    }
-
-    @Override
-    public Answer easySend(final Long hostId, final Command cmd) {
-        try {
-            final Host h = _hostDao.findById(hostId);
-            if (h == null || h.getRemoved() != null) {
-                s_logger.debug("Host with id " + hostId + " doesn't exist");
-                return null;
-            }
-            final Status status = h.getStatus();
-            if (!status.equals(Status.Up) && !status.equals(Status.Connecting)) {
-                s_logger.debug("Can not send command " + cmd + " due to Host " + hostId + " is not up");
-                return null;
-            }
-            final Answer answer = send(hostId, cmd);
-            if (answer == null) {
-                s_logger.warn("send returns null answer");
-                return null;
-            }
-
-            if (s_logger.isDebugEnabled() && answer.getDetails() != null) {
-                s_logger.debug("Details from executing " + cmd.getClass() + ": " + answer.getDetails());
-            }
-
-            return answer;
-
-        } catch (final AgentUnavailableException e) {
-            s_logger.warn(e.getMessage());
-            return null;
-        } catch (final OperationTimedoutException e) {
-            s_logger.warn("Operation timed out: " + e.getMessage());
-            return null;
-        } catch (final Exception e) {
-            s_logger.warn("Exception while sending", e);
-            return null;
-        }
-    }
-
-    @Override
-    public Answer[] send(final Long hostId, final Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
-        int wait = 0;
-        for (final Command cmd : cmds) {
-            if (cmd.getWait() > wait) {
-                wait = cmd.getWait();
-            }
-        }
-        return send(hostId, cmds, wait);
-    }
-
-    @Override
-    public boolean reconnect(final long hostId) {
-        HostVO host;
-
-        host = _hostDao.findById(hostId);
-        if (host == null || host.getRemoved() != null) {
-            s_logger.warn("Unable to find host " + hostId);
-            return false;
-        }
-
-        if (host.getStatus() == Status.Disconnected) {
-            s_logger.info("Host is already disconnected, no work to be done");
-            return true;
-        }
-
-        if (host.getStatus() != Status.Up && host.getStatus() != Status.Alert && host.getStatus() != Status.Rebalancing) {
-            s_logger.info("Unable to disconnect host because it is not in the correct state: host=" + hostId + "; Status=" + host.getStatus());
-            return false;
-        }
-
-        final AgentAttache attache = findAttache(hostId);
-        if (attache == null) {
-            s_logger.info("Unable to disconnect host because it is not connected to this server: " + hostId);
-            return false;
-        }
-
-        disconnectWithoutInvestigation(attache, Event.ShutdownRequested);
-        return true;
-    }
-
-    @Override
-    public void notifyMonitorsOfHostAboutToBeRemoved(long hostId) {
-        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Sending host about to be removed to listener: " + monitor.second().getClass().getSimpleName());
-            }
-
-            monitor.second().processHostAboutToBeRemoved(hostId);
-        }
-    }
-
-    @Override
-    public void notifyMonitorsOfRemovedHost(long hostId, long clusterId) {
-        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Sending host removed to listener: " + monitor.second().getClass().getSimpleName());
-            }
-
-            monitor.second().processHostRemoved(hostId, clusterId);
-        }
-    }
-
-    public boolean executeUserRequest(final long hostId, final Event event) throws AgentUnavailableException {
-        if (event == Event.AgentDisconnected) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Received agent disconnect event for host " + hostId);
-            }
-            AgentAttache attache = null;
-            attache = findAttache(hostId);
-            if (attache != null) {
-                handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
-            }
-            return true;
-        } else if (event == Event.ShutdownRequested) {
-            return reconnect(hostId);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isAgentAttached(final long hostId) {
-        final AgentAttache agentAttache = findAttache(hostId);
-        return agentAttache != null;
-    }
-
-    protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) throws ConnectionException {
-        s_logger.debug("create ConnectedAgentAttache for " + host.getId());
-        final AgentAttache attache = new ConnectedAgentAttache(this, host.getId(), host.getName(), link, host.isInMaintenanceStates());
-        link.attach(attache);
-
-        AgentAttache old = null;
-        synchronized (_agents) {
-            old = _agents.put(host.getId(), attache);
-        }
-        if (old != null) {
-            old.disconnect(Status.Removed);
-        }
-
-        return attache;
-    }
-
-    private AgentAttache handleConnectedAgent(final Link link, final StartupCommand[] startup, final Request request) {
-        AgentAttache attache = null;
-        ReadyCommand ready = null;
-        try {
-            final List<String> agentMSHostList = new ArrayList<>();
-            if (startup != null && startup.length > 0) {
-                final String agentMSHosts = startup[0].getMsHostList();
-                if (!Strings.isNullOrEmpty(agentMSHosts)) {
-                    agentMSHostList.addAll(Arrays.asList(agentMSHosts.split(",")));
-                }
-            }
-
-            final HostVO host = _resourceMgr.createHostVOForConnectedAgent(startup);
-            if (host != null) {
-                ready = new ReadyCommand(host.getDataCenterId(), host.getId());
-
-                if (!indirectAgentLB.compareManagementServerList(host.getId(), host.getDataCenterId(), agentMSHostList)) {
-                    final List<String> newMSList = indirectAgentLB.getManagementServerList(host.getId(), host.getDataCenterId(), null);
-                    ready.setMsHostList(newMSList);
-                    ready.setLbAlgorithm(indirectAgentLB.getLBAlgorithmName());
-                    ready.setLbCheckInterval(indirectAgentLB.getLBPreferredHostCheckInterval(host.getClusterId()));
-                    s_logger.debug("Agent's management server host list is not up to date, sending list update:" + newMSList);
-                }
-
-                attache = createAttacheForConnect(host, link);
-                attache = notifyMonitorsOfConnection(attache, startup, false);
-            }
-        } catch (final Exception e) {
-            s_logger.debug("Failed to handle host connection: ", e);
-            ready = new ReadyCommand(null);
-            ready.setDetails(e.toString());
-        } finally {
-            if (ready == null) {
-                ready = new ReadyCommand(null);
-            }
-        }
-
-        try {
-            if (attache == null) {
-                final Request readyRequest = new Request(-1, -1, ready, false);
-                link.send(readyRequest.getBytes());
-            } else {
-                easySend(attache.getId(), ready);
-            }
-        } catch (final Exception e) {
-            s_logger.debug("Failed to send ready command:" + e.toString());
-        }
-        return attache;
-    }
-
-    protected class SimulateStartTask extends ManagedContextRunnable {
-        ServerResource resource;
-        Map<String, String> details;
-        long id;
-
-        public SimulateStartTask(final long id, final ServerResource resource, final Map<String, String> details) {
-            this.id = id;
-            this.resource = resource;
-            this.details = details;
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id);
-                }
-
-                if (tapLoadingAgents(id, TapAgentsAction.Add)) {
-                    try {
-                        final AgentAttache agentattache = findAttache(id);
-                        if (agentattache == null) {
-                            s_logger.debug("Creating agent for host " + id);
-                            _resourceMgr.createHostAndAgent(id, resource, details, false, null, false);
-                            s_logger.debug("Completed creating agent for host " + id);
-                        } else {
-                            s_logger.debug("Agent already created in another thread for host " + id + ", ignore this");
-                        }
-                    } finally {
-                        tapLoadingAgents(id, TapAgentsAction.Del);
-                    }
-                } else {
-                    s_logger.debug("Agent creation already getting processed in another thread for host " + id + ", ignore this");
-                }
-            } catch (final Exception e) {
-                s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e);
-            }
-        }
-    }
-
-    protected class HandleAgentConnectTask extends ManagedContextRunnable {
-        Link _link;
-        Command[] _cmds;
-        Request _request;
-
-        HandleAgentConnectTask(final Link link, final Command[] cmds, final Request request) {
-            _link = link;
-            _cmds = cmds;
-            _request = request;
-        }
-
-        @Override
-        protected void runInContext() {
-            _request.logD("Processing the first command ");
-            final StartupCommand[] startups = new StartupCommand[_cmds.length];
-            for (int i = 0; i < _cmds.length; i++) {
-                startups[i] = (StartupCommand) _cmds[i];
-            }
-
-            final AgentAttache attache = handleConnectedAgent(_link, startups, _request);
-            if (attache == null) {
-                s_logger.warn("Unable to create attache for agent: " + _request);
-            }
-        }
-    }
-
-    protected void connectAgent(final Link link, final Command[] cmds, final Request request) {
-        // send startupanswer to agent in the very beginning, so agent can move on without waiting for the answer for an undetermined time, if we put this logic into another
-        // thread pool.
-        final StartupAnswer[] answers = new StartupAnswer[cmds.length];
-        Command cmd;
-        for (int i = 0; i < cmds.length; i++) {
-            cmd = cmds[i];
-            if (cmd instanceof StartupRoutingCommand || cmd instanceof StartupProxyCommand || cmd instanceof StartupSecondaryStorageCommand ||
-                            cmd instanceof StartupStorageCommand) {
-                answers[i] = new StartupAnswer((StartupCommand) cmds[i], 0, mgmtServiceConf.getPingInterval());
-                break;
-            }
-        }
-        Response response = null;
-        response = new Response(request, answers[0], _nodeId, -1);
-        try {
-            link.send(response.toBytes());
-        } catch (final ClosedChannelException e) {
-            s_logger.debug("Failed to send startupanswer: " + e.toString());
-        }
-        _connectExecutor.execute(new HandleAgentConnectTask(link, cmds, request));
-    }
-
-    public class AgentHandler extends Task {
-        public AgentHandler(final Task.Type type, final Link link, final byte[] data) {
-            super(type, link, data);
-        }
-
-        protected void processRequest(final Link link, final Request request) {
-            final AgentAttache attache = (AgentAttache) link.attachment();
-            final Command[] cmds = request.getCommands();
-            Command cmd = cmds[0];
-            boolean logD = true;
-
-            if (attache == null) {
-                if (!(cmd instanceof StartupCommand)) {
-                    s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request);
-                } else {
-                    // submit the task for execution
-                    request.logD("Scheduling the first command ");
-                    connectAgent(link, cmds, request);
-                }
-                return;
-            }
-
-            final long hostId = attache.getId();
-            final String hostName = attache.getName();
-
-            if (s_logger.isDebugEnabled()) {
-                if (cmd instanceof PingRoutingCommand) {
-                    logD = false;
-                    s_logger.debug("Ping from " + hostId + "(" + hostName + ")");
-                    s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
-                } else if (cmd instanceof PingCommand) {
-                    logD = false;
-                    s_logger.debug("Ping from " + hostId + "(" + hostName + ")");
-                    s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
-                } else {
-                    s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
-                }
-            }
-
-            final Answer[] answers = new Answer[cmds.length];
-            for (int i = 0; i < cmds.length; i++) {
-                cmd = cmds[i];
-                Answer answer = null;
-                try {
-                    if (cmd instanceof StartupRoutingCommand) {
-                        final StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
-                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
-                    } else if (cmd instanceof StartupProxyCommand) {
-                        final StartupProxyCommand startup = (StartupProxyCommand) cmd;
-                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
-                    } else if (cmd instanceof StartupSecondaryStorageCommand) {
-                        final StartupSecondaryStorageCommand startup = (StartupSecondaryStorageCommand) cmd;
-                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
-                    } else if (cmd instanceof StartupStorageCommand) {
-                        final StartupStorageCommand startup = (StartupStorageCommand) cmd;
-                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
-                    } else if (cmd instanceof ShutdownCommand) {
-                        final ShutdownCommand shutdown = (ShutdownCommand) cmd;
-                        final String reason = shutdown.getReason();
-                        s_logger.info("Host " + attache.getId() + " has informed us that it is shutting down with reason " + reason + " and detail " +
-                                        shutdown.getDetail());
-                        if (reason.equals(ShutdownCommand.Update)) {
-                            // disconnectWithoutInvestigation(attache, Event.UpdateNeeded);
-                            throw new CloudRuntimeException("Agent update not implemented");
-                        } else if (reason.equals(ShutdownCommand.Requested)) {
-                            disconnectWithoutInvestigation(attache, Event.ShutdownRequested);
-                        }
-                        return;
-                    } else if (cmd instanceof AgentControlCommand) {
-                        answer = handleControlCommand(attache, (AgentControlCommand) cmd);
-                    } else {
-                        handleCommands(attache, request.getSequence(), new Command[] { cmd });
-                        if (cmd instanceof PingCommand) {
-                            final long cmdHostId = ((PingCommand) cmd).getHostId();
-
-                            // if the router is sending a ping, verify the
-                            // gateway was pingable
-                            if (cmd instanceof PingRoutingCommand) {
-                                final boolean gatewayAccessible = ((PingRoutingCommand) cmd).isGatewayAccessible();
-                                final HostVO host = _hostDao.findById(Long.valueOf(cmdHostId));
-
-                                if (host != null) {
-                                    if (!gatewayAccessible) {
-                                        // alert that host lost connection to
-                                        // gateway (cannot ping the default route)
-                                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-                                        final HostPodVO podVO = _podDao.findById(host.getPodId());
-                                        final String hostDesc =
-                                                        "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: "
-                                                                        + podVO.getName();
-
-                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(),
-                                                        "Host lost connection to gateway, " + hostDesc, "Host [" + hostDesc +
-                                                                        "] lost connection to gateway (default route) and is possibly having network connection issues.");
-                                    } else {
-                                        _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId());
-                                    }
-                                } else {
-                                    s_logger.debug("Not processing " + PingRoutingCommand.class.getSimpleName() + " for agent id=" + cmdHostId +
-                                                    "; can't find the host in the DB");
-                                }
-                            }
-                            answer = new PingAnswer((PingCommand) cmd);
-                        } else if (cmd instanceof ReadyAnswer) {
-                            final HostVO host = _hostDao.findById(attache.getId());
-                            if (host == null) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Cant not find host " + attache.getId());
-                                }
-                            }
-                            answer = new Answer(cmd);
-                        } else {
-                            answer = new Answer(cmd);
-                        }
-                    }
-                } catch (final Throwable th) {
-                    s_logger.warn("Caught: ", th);
-                    answer = new Answer(cmd, false, th.getMessage());
-                }
-                answers[i] = answer;
-            }
-
-            final Response response = new Response(request, answers, _nodeId, attache.getId());
-            if (s_logger.isDebugEnabled()) {
-                if (logD) {
-                    s_logger.debug("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
-                } else {
-                    s_logger.trace("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
-                }
-            }
-            try {
-                link.send(response.toBytes());
-            } catch (final ClosedChannelException e) {
-                s_logger.warn("Unable to send response because connection is closed: " + response);
-            }
-        }
-
-        protected void processResponse(final Link link, final Response response) {
-            final AgentAttache attache = (AgentAttache) link.attachment();
-            if (attache == null) {
-                s_logger.warn("Unable to process: " + response);
-            } else if (!attache.processAnswers(response.getSequence(), response)) {
-                s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response);
-            }
-        }
-
-        @Override
-        protected void doTask(final Task task) throws TaskExecutionException {
-            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            try {
-                final Type type = task.getType();
-                if (type == Task.Type.DATA) {
-                    final byte[] data = task.getData();
-                    try {
-                        final Request event = Request.parse(data);
-                        if (event instanceof Response) {
-                            processResponse(task.getLink(), (Response) event);
-                        } else {
-                            processRequest(task.getLink(), event);
-                        }
-                    } catch (final UnsupportedVersionException e) {
-                        s_logger.warn(e.getMessage());
-                        // upgradeAgent(task.getLink(), data, e.getReason());
-                    } catch (final ClassNotFoundException e) {
-                        final String message = String.format("Exception occured when executing taks! Error '%s'", e.getMessage());
-                        s_logger.error(message);
-                        throw new TaskExecutionException(message, e);
-                    }
-                } else if (type == Task.Type.CONNECT) {
-                } else if (type == Task.Type.DISCONNECT) {
-                    final Link link = task.getLink();
-                    final AgentAttache attache = (AgentAttache) link.attachment();
-                    if (attache != null) {
-                        disconnectWithInvestigation(attache, Event.AgentDisconnected);
-                    } else {
-                        s_logger.info("Connection from " + link.getIpAddress() + " closed but no cleanup was done.");
-                        link.close();
-                        link.terminated();
-                    }
-                }
-            } finally {
-                txn.close();
-            }
-        }
-    }
-
-    protected AgentManagerImpl() {
-    }
-
-    public boolean tapLoadingAgents(final Long hostId, final TapAgentsAction action) {
-        synchronized (_loadingAgents) {
-            if (action == TapAgentsAction.Add) {
-                if (_loadingAgents.contains(hostId)) {
-                    return false;
-                } else {
-                    _loadingAgents.add(hostId);
-                }
-            } else if (action == TapAgentsAction.Del) {
-                _loadingAgents.remove(hostId);
-            } else if (action == TapAgentsAction.Contains) {
-                return _loadingAgents.contains(hostId);
-            } else {
-                throw new CloudRuntimeException("Unkonwn TapAgentsAction " + action);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean agentStatusTransitTo(final HostVO host, final Status.Event e, final long msId) {
-        try {
-            _agentStatusLock.lock();
-            if (status_logger.isDebugEnabled()) {
-                final ResourceState state = host.getResourceState();
-                final StringBuilder msg = new StringBuilder("Transition:");
-                msg.append("[Resource state = ").append(state);
-                msg.append(", Agent event = ").append(e.toString());
-                msg.append(", Host id = ").append(host.getId()).append(", name = " + host.getName()).append("]");
-                status_logger.debug(msg);
-            }
-
-            host.setManagementServerId(msId);
-            try {
-                return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
-            } catch (final NoTransitionException e1) {
-                status_logger.debug("Cannot transit agent status with event " + e + " for host " + host.getId() + ", name=" + host.getName() +
-                                ", mangement server id is " + msId);
-                throw new CloudRuntimeException("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId + "," +
-                                e1.getMessage());
-            }
-        } finally {
-            _agentStatusLock.unlock();
-        }
-    }
-
-    public boolean disconnectAgent(final HostVO host, final Status.Event e, final long msId) {
-        host.setDisconnectedOn(new Date());
-        if (e.equals(Status.Event.Remove)) {
-            host.setGuid(null);
-            host.setClusterId(null);
-        }
-
-        return agentStatusTransitTo(host, e, msId);
-    }
-
-    protected void disconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event) {
-        _executor.submit(new DisconnectTask(attache, event, false));
-    }
-
-    public void disconnectWithInvestigation(final AgentAttache attache, final Status.Event event) {
-        _executor.submit(new DisconnectTask(attache, event, true));
-    }
-
-    protected boolean isHostOwnerSwitched(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            s_logger.warn("Can't find the host " + hostId);
-            return false;
-        }
-        return isHostOwnerSwitched(host);
-    }
-
-    protected boolean isHostOwnerSwitched(final HostVO host) {
-        if (host.getStatus() == Status.Up && host.getManagementServerId() != null && host.getManagementServerId() != _nodeId) {
-            return true;
-        }
-        return false;
-    }
-
-    private void disconnectInternal(final long hostId, final Status.Event event, final boolean invstigate) {
-        final AgentAttache attache = findAttache(hostId);
-
-        if (attache != null) {
-            if (!invstigate) {
-                disconnectWithoutInvestigation(attache, event);
-            } else {
-                disconnectWithInvestigation(attache, event);
-            }
-        } else {
-            /* Agent is still in connecting process, don't allow to disconnect right away */
-            if (tapLoadingAgents(hostId, TapAgentsAction.Contains)) {
-                s_logger.info("Host " + hostId + " is being loaded so no disconnects needed.");
-                return;
-            }
-
-            final HostVO host = _hostDao.findById(hostId);
-            if (host != null && host.getRemoved() == null) {
-                disconnectAgent(host, event, _nodeId);
-            }
-        }
-    }
-
-    public void disconnectWithInvestigation(final long hostId, final Status.Event event) {
-        disconnectInternal(hostId, event, true);
-    }
-
-    @Override
-    public void disconnectWithoutInvestigation(final long hostId, final Status.Event event) {
-        disconnectInternal(hostId, event, false);
-    }
-
-    @Override
-    public boolean handleDirectConnectAgent(final Host host, final StartupCommand[] cmds, final ServerResource resource,
-            final boolean forRebalance, boolean newHost) throws ConnectionException {
-        AgentAttache attache;
-
-        attache = createAttacheForDirectConnect(host, resource);
-        final StartupAnswer[] answers = new StartupAnswer[cmds.length];
-        for (int i = 0; i < answers.length; i++) {
-            answers[i] = new StartupAnswer(cmds[i], attache.getId(), mgmtServiceConf.getPingInterval());
-        }
-        attache.process(answers);
-
-        if (newHost) {
-            notifyMonitorsOfNewlyAddedHost(host.getId());
-        }
-
-        attache = notifyMonitorsOfConnection(attache, cmds, forRebalance);
-
-        return attache != null;
-    }
-
-    @Override
-    public void pullAgentToMaintenance(final long hostId) {
-        final AgentAttache attache = findAttache(hostId);
-        if (attache != null) {
-            attache.setMaintenanceMode(true);
-            // Now cancel all of the commands except for the active one.
-            attache.cancelAllCommands(Status.Disconnected, false);
-        }
-    }
-
-    @Override
-    public void pullAgentOutMaintenance(final long hostId) {
-        final AgentAttache attache = findAttache(hostId);
-        if (attache != null) {
-            attache.setMaintenanceMode(false);
-        }
-    }
-
-    public ScheduledExecutorService getDirectAgentPool() {
-        return _directAgentExecutor;
-    }
-
-    public ScheduledExecutorService getCronJobPool() {
-        return _cronJobExecutor;
-    }
-
-    public int getDirectAgentThreadCap() {
-        return _directAgentThreadCap;
-    }
-
-    public Long getAgentPingTime(final long agentId) {
-        return _pingMap.get(agentId);
-    }
-
-    public void pingBy(final long agentId) {
-        // Update PingMap with the latest time if agent entry exists in the PingMap
-        if (_pingMap.replace(agentId, InaccurateClock.getTimeInSeconds()) == null) {
-            s_logger.info("PingMap for agent: " + agentId + " will not be updated because agent is no longer in the PingMap");
-        }
-    }
-
-    protected class MonitorTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            s_logger.trace("Agent Monitor is started.");
-
-            try {
-                final List<Long> behindAgents = findAgentsBehindOnPing();
-                for (final Long agentId : behindAgents) {
-                    final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-                    sc.and(sc.entity().getId(), Op.EQ, agentId);
-                    final HostVO h = sc.find();
-                    if (h != null) {
-                        final ResourceState resourceState = h.getResourceState();
-                        if (resourceState == ResourceState.Disabled || resourceState == ResourceState.Maintenance || resourceState == ResourceState.ErrorInMaintenance) {
-                            /*
-                             * Host is in non-operation state, so no investigation and direct put agent to Disconnected
-                             */
-                            status_logger.debug("Ping timeout but agent " + agentId + " is in resource state of " + resourceState + ", so no investigation");
-                            disconnectWithoutInvestigation(agentId, Event.ShutdownRequested);
-                        } else {
-                            final HostVO host = _hostDao.findById(agentId);
-                            if (host != null && (host.getType() == Host.Type.ConsoleProxy || host.getType() == Host.Type.SecondaryStorageVM
-                                            || host.getType() == Host.Type.SecondaryStorageCmdExecutor)) {
-
-                                s_logger.warn("Disconnect agent for CPVM/SSVM due to physical connection close. host: " + host.getId());
-                                disconnectWithoutInvestigation(agentId, Event.ShutdownRequested);
-                            } else {
-                                status_logger.debug("Ping timeout for agent " + agentId + ", do invstigation");
-                                disconnectWithInvestigation(agentId, Event.PingTimeout);
-                            }
-                        }
-                    }
-                }
-
-                final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-                sc.and(sc.entity().getResourceState(), Op.IN, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
-                final List<HostVO> hosts = sc.list();
-
-                for (final HostVO host : hosts) {
-                    if (_resourceMgr.checkAndMaintain(host.getId())) {
-                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-                        final HostPodVO podVO = _podDao.findById(host.getPodId());
-                        final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Migration Complete for host " + hostDesc, "Host ["
-                                        + hostDesc + "] is ready for maintenance");
-                    }
-                }
-            } catch (final Throwable th) {
-                s_logger.error("Caught the following exception: ", th);
-            }
-
-            s_logger.trace("Agent Monitor is leaving the building!");
-        }
-
-        protected List<Long> findAgentsBehindOnPing() {
-            final List<Long> agentsBehind = new ArrayList<Long>();
-            final long cutoffTime = InaccurateClock.getTimeInSeconds() - mgmtServiceConf.getTimeout();
-            for (final Map.Entry<Long, Long> entry : _pingMap.entrySet()) {
-                if (entry.getValue() < cutoffTime) {
-                    agentsBehind.add(entry.getKey());
-                }
-            }
-
-            if (agentsBehind.size() > 0) {
-                s_logger.info("Found the following agents behind on ping: " + agentsBehind);
-            }
-
-            return agentsBehind;
-        }
-    }
-
-    protected class BehindOnPingListener implements Listener {
-        @Override
-        public boolean isRecurring() {
-            return true;
-        }
-
-        @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) {
-            final boolean processed = false;
-            for (final Command cmd : commands) {
-                if (cmd instanceof PingCommand) {
-                    pingBy(agentId);
-                }
-            }
-            return processed;
-        }
-
-        @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 (host.getType().equals(Host.Type.TrafficMonitor) || host.getType().equals(Host.Type.SecondaryStorage)) {
-                return;
-            }
-
-            // NOTE: We don't use pingBy here because we're initiating.
-            _pingMap.put(host.getId(), InaccurateClock.getTimeInSeconds());
-        }
-
-        @Override
-        public boolean processDisconnect(final long agentId, final Status state) {
-            _pingMap.remove(agentId);
-            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 true;
-        }
-
-        @Override
-        public int getTimeout() {
-            return -1;
-        }
-
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return AgentManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize,
-                        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/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
deleted file mode 100644
index 7a9678e..0000000
--- a/engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
+++ /dev/null
@@ -1,1473 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.manager;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-
-import org.apache.cloudstack.ca.CAManager;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.cloudstack.utils.security.SSLUtils;
-import org.apache.cloudstack.ha.dao.HAConfigDao;
-import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CancelCommand;
-import com.cloud.agent.api.ChangeAgentAnswer;
-import com.cloud.agent.api.ChangeAgentCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.PropagateResourceEventCommand;
-import com.cloud.agent.api.ScheduleHostScanTaskCommand;
-import com.cloud.agent.api.TransferAgentCommand;
-import com.cloud.agent.transport.Request;
-import com.cloud.agent.transport.Request.Version;
-import com.cloud.agent.transport.Response;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ClusterServicePdu;
-import com.cloud.cluster.ClusteredAgentRebalanceService;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerHostVO;
-import com.cloud.cluster.agentlb.AgentLoadBalancerPlanner;
-import com.cloud.cluster.agentlb.HostTransferMapVO;
-import com.cloud.cluster.agentlb.HostTransferMapVO.HostTransferState;
-import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
-import com.cloud.cluster.dao.ManagementServerHostDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.UnsupportedVersionException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Status.Event;
-import com.cloud.resource.ServerResource;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.TaskExecutionException;
-import com.cloud.utils.nio.Link;
-import com.cloud.utils.nio.Task;
-import com.google.gson.Gson;
-
-public class ClusteredAgentManagerImpl extends AgentManagerImpl implements ClusterManagerListener, ClusteredAgentRebalanceService {
-    final static Logger s_logger = Logger.getLogger(ClusteredAgentManagerImpl.class);
-    private static final ScheduledExecutorService s_transferExecutor = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Cluster-AgentRebalancingExecutor"));
-    private final long rebalanceTimeOut = 300000; // 5 mins - after this time remove the agent from the transfer list
-
-    public final static long STARTUP_DELAY = 5000;
-    public final static long SCAN_INTERVAL = 90000; // 90 seconds, it takes 60 sec for xenserver to fail login
-    public final static int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
-    protected Set<Long> _agentToTransferIds = new HashSet<Long>();
-    Gson _gson;
-    protected HashMap<String, SocketChannel> _peers;
-    protected HashMap<String, SSLEngine> _sslEngines;
-    private final Timer _timer = new Timer("ClusteredAgentManager Timer");
-    boolean _agentLbHappened = false;
-
-    @Inject
-    protected ClusterManager _clusterMgr = null;
-    @Inject
-    protected ManagementServerHostDao _mshostDao;
-    @Inject
-    protected HostTransferMapDao _hostTransferDao;
-    @Inject
-    protected List<AgentLoadBalancerPlanner> _lbPlanners;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ConfigDepot _configDepot;
-    @Inject
-    private OutOfBandManagementDao outOfBandManagementDao;
-    @Inject
-    private HAConfigDao haConfigDao;
-    @Inject
-    private CAManager caService;
-
-    protected ClusteredAgentManagerImpl() {
-        super();
-    }
-
-    protected final ConfigKey<Boolean> EnableLB = new ConfigKey<Boolean>(Boolean.class, "agent.lb.enabled", "Advanced", "false",
-            "Enable agent load balancing between management server nodes", true);
-    protected final ConfigKey<Double> ConnectedAgentThreshold = new ConfigKey<Double>(Double.class, "agent.load.threshold", "Advanced", "0.7",
-            "What percentage of the agents can be held by one management server before load balancing happens", true);
-    protected final ConfigKey<Integer> LoadSize = new ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advanced", "16",
-            "How many agents to connect to in each round", true);
-    protected final ConfigKey<Integer> ScanInterval = new ConfigKey<Integer>(Integer.class, "direct.agent.scan.interval", "Advanced", "90",
-            "Interval between scans to load agents", false, ConfigKey.Scope.Global, 1000);
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
-        _peers = new HashMap<String, SocketChannel>(7);
-        _sslEngines = new HashMap<String, SSLEngine>(7);
-        _nodeId = ManagementServerNode.getManagementServerId();
-
-        s_logger.info("Configuring ClusterAgentManagerImpl. management server node id(msid): " + _nodeId);
-
-        ClusteredAgentAttache.initialize(this);
-
-        _clusterMgr.registerListener(this);
-        _clusterMgr.registerDispatcher(new ClusterDispatcher());
-
-        _gson = GsonHelper.getGson();
-
-        return super.configure(name, xmlParams);
-    }
-
-    @Override
-    public boolean start() {
-        if (!super.start()) {
-            return false;
-        }
-        _timer.schedule(new DirectAgentScanTimerTask(), STARTUP_DELAY, ScanInterval.value());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Scheduled direct agent scan task to run at an interval of " + ScanInterval.value() + " seconds");
-        }
-
-        // Schedule tasks for agent rebalancing
-        if (isAgentRebalanceEnabled()) {
-            cleanupTransferMap(_nodeId);
-            s_transferExecutor.scheduleAtFixedRate(getAgentRebalanceScanTask(), 60000, 60000, TimeUnit.MILLISECONDS);
-            s_transferExecutor.scheduleAtFixedRate(getTransferScanTask(), 60000, ClusteredAgentRebalanceService.DEFAULT_TRANSFER_CHECK_INTERVAL, TimeUnit.MILLISECONDS);
-        }
-
-        return true;
-    }
-
-    public void scheduleHostScanTask() {
-        _timer.schedule(new DirectAgentScanTimerTask(), 0);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Scheduled a direct agent scan task");
-        }
-    }
-
-    private void runDirectAgentScanTimerTask() {
-        scanDirectAgentToLoad();
-    }
-
-    private void scanDirectAgentToLoad() {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Begin scanning directly connected hosts");
-        }
-
-        // for agents that are self-managed, threshold to be considered as disconnected after pingtimeout
-        final long cutSeconds = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
-        final List<HostVO> hosts = _hostDao.findAndUpdateDirectAgentToLoad(cutSeconds, LoadSize.value().longValue(), _nodeId);
-        final List<HostVO> appliances = _hostDao.findAndUpdateApplianceToLoad(cutSeconds, _nodeId);
-
-        if (hosts != null) {
-            hosts.addAll(appliances);
-            if (hosts.size() > 0) {
-                s_logger.debug("Found " + hosts.size() + " unmanaged direct hosts, processing connect for them...");
-                for (final HostVO host : hosts) {
-                    try {
-                        final AgentAttache agentattache = findAttache(host.getId());
-                        if (agentattache != null) {
-                            // already loaded, skip
-                            if (agentattache.forForward()) {
-                                if (s_logger.isInfoEnabled()) {
-                                    s_logger.info(host + " is detected down, but we have a forward attache running, disconnect this one before launching the host");
-                                }
-                                removeAgent(agentattache, Status.Disconnected);
-                            } else {
-                                continue;
-                            }
-                        }
-
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Loading directly connected host " + host.getId() + "(" + host.getName() + ")");
-                        }
-                        loadDirectlyConnectedHost(host, false);
-                    } catch (final Throwable e) {
-                        s_logger.warn(" can not load directly connected host " + host.getId() + "(" + host.getName() + ") due to ", e);
-                    }
-                }
-            }
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("End scanning directly connected hosts");
-        }
-    }
-
-    private class DirectAgentScanTimerTask extends ManagedContextTimerTask {
-        @Override
-        protected void runInContext() {
-            try {
-                runDirectAgentScanTimerTask();
-            } catch (final Throwable e) {
-                s_logger.error("Unexpected exception " + e.getMessage(), e);
-            }
-        }
-    }
-
-    @Override
-    public Task create(final Task.Type type, final Link link, final byte[] data) {
-        return new ClusteredAgentHandler(type, link, data);
-    }
-
-    protected AgentAttache createAttache(final long id) {
-        s_logger.debug("create forwarding ClusteredAgentAttache for " + id);
-        final HostVO host = _hostDao.findById(id);
-        final AgentAttache attache = new ClusteredAgentAttache(this, id, host.getName());
-        AgentAttache old = null;
-        synchronized (_agents) {
-            old = _agents.get(id);
-            _agents.put(id, attache);
-        }
-        if (old != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Remove stale agent attache from current management server");
-            }
-            removeAgent(old, Status.Removed);
-        }
-        return attache;
-    }
-
-    @Override
-    protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) {
-        s_logger.debug("create ClusteredAgentAttache for " + host.getId());
-        final AgentAttache attache = new ClusteredAgentAttache(this, host.getId(), host.getName(), link, host.isInMaintenanceStates());
-        link.attach(attache);
-        AgentAttache old = null;
-        synchronized (_agents) {
-            old = _agents.get(host.getId());
-            _agents.put(host.getId(), attache);
-        }
-        if (old != null) {
-            old.disconnect(Status.Removed);
-        }
-        return attache;
-    }
-
-    @Override
-    protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) {
-        s_logger.debug("create ClusteredDirectAgentAttache for " + host.getId());
-        final DirectAgentAttache attache = new ClusteredDirectAgentAttache(this, host.getId(), host.getName(), _nodeId, resource, host.isInMaintenanceStates());
-        AgentAttache old = null;
-        synchronized (_agents) {
-            old = _agents.get(host.getId());
-            _agents.put(host.getId(), attache);
-        }
-        if (old != null) {
-            old.disconnect(Status.Removed);
-        }
-        return attache;
-    }
-
-    @Override
-    protected boolean handleDisconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event, final boolean transitState, final boolean removeAgent) {
-        return handleDisconnect(attache, event, false, true, removeAgent);
-    }
-
-    @Override
-    protected boolean handleDisconnectWithInvestigation(final AgentAttache attache, final Status.Event event) {
-        return handleDisconnect(attache, event, true, true, true);
-    }
-
-    protected boolean handleDisconnect(final AgentAttache agent, final Status.Event event, final boolean investigate, final boolean broadcast, final boolean removeAgent) {
-        boolean res;
-        if (!investigate) {
-            res = super.handleDisconnectWithoutInvestigation(agent, event, true, removeAgent);
-        } else {
-            res = super.handleDisconnectWithInvestigation(agent, event);
-        }
-
-        if (res) {
-            if (broadcast) {
-                notifyNodesInCluster(agent);
-            }
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean executeUserRequest(final long hostId, final Event event) throws AgentUnavailableException {
-        if (event == Event.AgentDisconnected) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Received agent disconnect event for host " + hostId);
-            }
-            final AgentAttache attache = findAttache(hostId);
-            if (attache != null) {
-                // don't process disconnect if the host is being rebalanced
-                if (isAgentRebalanceEnabled()) {
-                    final HostTransferMapVO transferVO = _hostTransferDao.findById(hostId);
-                    if (transferVO != null) {
-                        if (transferVO.getFutureOwner() == _nodeId && transferVO.getState() == HostTransferState.TransferStarted) {
-                            s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId + " as the host is being connected to " +
-                                    _nodeId);
-                            return true;
-                        }
-                    }
-                }
-
-                // don't process disconnect if the disconnect came for the host via delayed cluster notification,
-                // but the host has already reconnected to the current management server
-                if (!attache.forForward()) {
-                    s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId +
-                            " as the host is directly connected to the current management server " + _nodeId);
-                    return true;
-                }
-
-                return super.handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, false, true);
-            }
-
-            return true;
-        } else {
-            return super.executeUserRequest(hostId, event);
-        }
-    }
-
-    @Override
-    public boolean reconnect(final long hostId) {
-        Boolean result;
-        try {
-            result = propagateAgentEvent(hostId, Event.ShutdownRequested);
-            if (result != null) {
-                return result;
-            }
-        } catch (final AgentUnavailableException e) {
-            s_logger.debug("cannot propagate agent reconnect because agent is not available", e);
-            return false;
-        }
-
-        return super.reconnect(hostId);
-    }
-
-    public void notifyNodesInCluster(final AgentAttache attache) {
-        s_logger.debug("Notifying other nodes of to disconnect");
-        final Command[] cmds = new Command[] {new ChangeAgentCommand(attache.getId(), Event.AgentDisconnected)};
-        _clusterMgr.broadcast(attache.getId(), _gson.toJson(cmds));
-    }
-
-    // notifies MS peers to schedule a host scan task immediately, triggered during addHost operation
-    public void notifyNodesInClusterToScheduleHostScanTask() {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Notifying other MS nodes to run host scan task");
-        }
-        final Command[] cmds = new Command[] {new ScheduleHostScanTaskCommand()};
-        _clusterMgr.broadcast(0, _gson.toJson(cmds));
-    }
-
-    protected static void logT(final byte[] bytes, final String msg) {
-        s_logger.trace("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " +
-                (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
-    }
-
-    protected static void logD(final byte[] bytes, final String msg) {
-        s_logger.debug("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " +
-                (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
-    }
-
-    protected static void logI(final byte[] bytes, final String msg) {
-        s_logger.info("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": " +
-                (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
-    }
-
-    public boolean routeToPeer(final String peer, final byte[] bytes) {
-        int i = 0;
-        SocketChannel ch = null;
-        SSLEngine sslEngine = null;
-        while (i++ < 5) {
-            ch = connectToPeer(peer, ch);
-            if (ch == null) {
-                try {
-                    logD(bytes, "Unable to route to peer: " + Request.parse(bytes).toString());
-                } catch (ClassNotFoundException | UnsupportedVersionException e) {
-                    // Request.parse thrown exception when we try to log it, log as much as we can
-                    logD(bytes, "Unable to route to peer, and Request.parse further caught exception" + e.getMessage());
-                }
-                return false;
-            }
-            sslEngine = getSSLEngine(peer);
-            if (sslEngine == null) {
-                logD(bytes, "Unable to get SSLEngine of peer: " + peer);
-                return false;
-            }
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    logD(bytes, "Routing to peer");
-                }
-                Link.write(ch, new ByteBuffer[] {ByteBuffer.wrap(bytes)}, sslEngine);
-                return true;
-            } catch (final IOException e) {
-                try {
-                    logI(bytes, "Unable to route to peer: " + Request.parse(bytes).toString() + " due to " + e.getMessage());
-                } catch (ClassNotFoundException | UnsupportedVersionException ex) {
-                    // Request.parse thrown exception when we try to log it, log as much as we can
-                    logI(bytes, "Unable to route to peer due to" + e.getMessage()
-                            + ". Also caught exception when parsing request: " + ex.getMessage());
-                }
-            }
-        }
-        return false;
-    }
-
-    public String findPeer(final long hostId) {
-        return getPeerName(hostId);
-    }
-
-    public SSLEngine getSSLEngine(final String peerName) {
-        return _sslEngines.get(peerName);
-    }
-
-    public void cancel(final String peerName, final long hostId, final long sequence, final String reason) {
-        final CancelCommand cancel = new CancelCommand(sequence, reason);
-        final Request req = new Request(hostId, _nodeId, cancel, true);
-        req.setControl(true);
-        routeToPeer(peerName, req.getBytes());
-    }
-
-    public void closePeer(final String peerName) {
-        synchronized (_peers) {
-            final SocketChannel ch = _peers.get(peerName);
-            if (ch != null) {
-                try {
-                    ch.close();
-                } catch (final IOException e) {
-                    s_logger.warn("Unable to close peer socket connection to " + peerName);
-                }
-            }
-            _peers.remove(peerName);
-            _sslEngines.remove(peerName);
-        }
-    }
-
-    public SocketChannel connectToPeer(final String peerName, final SocketChannel prevCh) {
-        synchronized (_peers) {
-            final SocketChannel ch = _peers.get(peerName);
-            SSLEngine sslEngine = null;
-            if (prevCh != null) {
-                try {
-                    prevCh.close();
-                } catch (final Exception e) {
-                    s_logger.info("[ignored]"
-                            + "failed to get close resource for previous channel Socket: " + e.getLocalizedMessage());
-                }
-            }
-            if (ch == null || ch == prevCh) {
-                final ManagementServerHost ms = _clusterMgr.getPeer(peerName);
-                if (ms == null) {
-                    s_logger.info("Unable to find peer: " + peerName);
-                    return null;
-                }
-                final String ip = ms.getServiceIP();
-                InetAddress addr;
-                int port = Port.value();
-                try {
-                    addr = InetAddress.getByName(ip);
-                } catch (final UnknownHostException e) {
-                    throw new CloudRuntimeException("Unable to resolve " + ip);
-                }
-                SocketChannel ch1 = null;
-                try {
-                    ch1 = SocketChannel.open(new InetSocketAddress(addr, port));
-                    ch1.configureBlocking(false);
-                    ch1.socket().setKeepAlive(true);
-                    ch1.socket().setSoTimeout(60 * 1000);
-                    try {
-                        SSLContext sslContext = Link.initManagementSSLContext(caService);
-                        sslEngine = sslContext.createSSLEngine(ip, port);
-                        sslEngine.setUseClientMode(true);
-                        sslEngine.setEnabledProtocols(SSLUtils.getSupportedProtocols(sslEngine.getEnabledProtocols()));
-                        sslEngine.beginHandshake();
-                        if (!Link.doHandshake(ch1, sslEngine)) {
-                            ch1.close();
-                            throw new IOException(String.format("SSL: Handshake failed with peer management server '%s' on %s:%d ", peerName, ip, port));
-                        }
-                        s_logger.info(String.format("SSL: Handshake done with peer management server '%s' on %s:%d ", peerName, ip, port));
-                    } catch (final Exception e) {
-                        ch1.close();
-                        throw new IOException("SSL: Fail to init SSL! " + e);
-                    }
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Connection to peer opened: " + peerName + ", ip: " + ip);
-                    }
-                    _peers.put(peerName, ch1);
-                    _sslEngines.put(peerName, sslEngine);
-                    return ch1;
-                } catch (final IOException e) {
-                    if (ch1 != null) {
-                        try {
-                            ch1.close();
-                        } catch (final IOException ex) {
-                            s_logger.error("failed to close failed peer socket: " + ex);
-                        }
-                    }
-                    s_logger.warn("Unable to connect to peer management server: " + peerName + ", ip: " + ip + " due to " + e.getMessage(), e);
-                    return null;
-                }
-            }
-
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Found open channel for peer: " + peerName);
-            }
-            return ch;
-        }
-    }
-
-    public SocketChannel connectToPeer(final long hostId, final SocketChannel prevCh) {
-        final String peerName = getPeerName(hostId);
-        if (peerName == null) {
-            return null;
-        }
-
-        return connectToPeer(peerName, prevCh);
-    }
-
-    @Override
-    protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
-        assert hostId != null : "Who didn't check their id value?";
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new AgentUnavailableException("Can't find the host ", hostId);
-        }
-
-        AgentAttache agent = findAttache(hostId);
-        if (agent == null || !agent.forForward()) {
-            if (isHostOwnerSwitched(host)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Host " + hostId + " has switched to another management server, need to update agent map with a forwarding agent attache");
-                }
-                agent = createAttache(hostId);
-            }
-        }
-        if (agent == null) {
-            final AgentUnavailableException ex = new AgentUnavailableException("Host with specified id is not in the right state: " + host.getStatus(), hostId);
-            ex.addProxyObject(_entityMgr.findById(Host.class, hostId).getUuid());
-            throw ex;
-        }
-
-        return agent;
-    }
-
-    @Override
-    public boolean stop() {
-        if (_peers != null) {
-            for (final SocketChannel ch : _peers.values()) {
-                try {
-                    s_logger.info("Closing: " + ch.toString());
-                    ch.close();
-                } catch (final IOException e) {
-                    s_logger.info("[ignored] error on closing channel: " +ch.toString(), e);
-                }
-            }
-        }
-        _timer.cancel();
-
-        // cancel all transfer tasks
-        s_transferExecutor.shutdownNow();
-        cleanupTransferMap(_nodeId);
-
-        return super.stop();
-    }
-
-    @Override
-    public void startDirectlyConnectedHosts() {
-        // override and let it be dummy for purpose, we will scan and load direct agents periodically.
-        // We may also pickup agents that have been left over from other crashed management server
-    }
-
-    public class ClusteredAgentHandler extends AgentHandler {
-
-        public ClusteredAgentHandler(final Task.Type type, final Link link, final byte[] data) {
-            super(type, link, data);
-        }
-
-        @Override
-        protected void doTask(final Task task) throws TaskExecutionException {
-            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            try {
-                if (task.getType() != Task.Type.DATA) {
-                    super.doTask(task);
-                    return;
-                }
-
-                final byte[] data = task.getData();
-                final Version ver = Request.getVersion(data);
-                if (ver.ordinal() != Version.v1.ordinal() && ver.ordinal() != Version.v3.ordinal()) {
-                    s_logger.warn("Wrong version for clustered agent request");
-                    super.doTask(task);
-                    return;
-                }
-
-                final long hostId = Request.getAgentId(data);
-                final Link link = task.getLink();
-
-                if (Request.fromServer(data)) {
-
-                    final AgentAttache agent = findAttache(hostId);
-
-                    if (Request.isControl(data)) {
-                        if (agent == null) {
-                            logD(data, "No attache to process cancellation");
-                            return;
-                        }
-                        final Request req = Request.parse(data);
-                        final Command[] cmds = req.getCommands();
-                        final CancelCommand cancel = (CancelCommand)cmds[0];
-                        if (s_logger.isDebugEnabled()) {
-                            logD(data, "Cancel request received");
-                        }
-                        agent.cancel(cancel.getSequence());
-                        final Long current = agent._currentSequence;
-                        // if the request is the current request, always have to trigger sending next request in
-                        // sequence,
-                        // otherwise the agent queue will be blocked
-                        if (req.executeInSequence() && current != null && current == Request.getSequence(data)) {
-                            agent.sendNext(Request.getSequence(data));
-                        }
-                        return;
-                    }
-
-                    try {
-                        if (agent == null || agent.isClosed()) {
-                            throw new AgentUnavailableException("Unable to route to agent ", hostId);
-                        }
-
-                        if (Request.isRequest(data) && Request.requiresSequentialExecution(data)) {
-                            // route it to the agent.
-                            // But we have the serialize the control commands here so we have
-                            // to deserialize this and send it through the agent attache.
-                            final Request req = Request.parse(data);
-                            agent.send(req, null);
-                            return;
-                        } else {
-                            if (agent instanceof Routable) {
-                                final Routable cluster = (Routable)agent;
-                                cluster.routeToAgent(data);
-                            } else {
-                                agent.send(Request.parse(data));
-                            }
-                            return;
-                        }
-                    } catch (final AgentUnavailableException e) {
-                        logD(data, e.getMessage());
-                        cancel(Long.toString(Request.getManagementServerId(data)), hostId, Request.getSequence(data), e.getMessage());
-                    }
-                } else {
-
-                    final long mgmtId = Request.getManagementServerId(data);
-                    if (mgmtId != -1 && mgmtId != _nodeId) {
-                        routeToPeer(Long.toString(mgmtId), data);
-                        if (Request.requiresSequentialExecution(data)) {
-                            final AgentAttache attache = (AgentAttache)link.attachment();
-                            if (attache != null) {
-                                attache.sendNext(Request.getSequence(data));
-                            } else if (s_logger.isDebugEnabled()) {
-                                logD(data, "No attache to process " + Request.parse(data).toString());
-                            }
-                        }
-                        return;
-                    } else {
-                        if (Request.isRequest(data)) {
-                            super.doTask(task);
-                        } else {
-                            // received an answer.
-                            final Response response = Response.parse(data);
-                            final AgentAttache attache = findAttache(response.getAgentId());
-                            if (attache == null) {
-                                s_logger.info("SeqA " + response.getAgentId() + "-" + response.getSequence() + "Unable to find attache to forward " + response.toString());
-                                return;
-                            }
-                            if (!attache.processAnswers(response.getSequence(), response)) {
-                                s_logger.info("SeqA " + attache.getId() + "-" + response.getSequence() + ": Response is not processed: " + response.toString());
-                            }
-                        }
-                        return;
-                    }
-                }
-            } catch (final ClassNotFoundException e) {
-                final String message = String.format("ClassNotFoundException occured when executing taks! Error '%s'", e.getMessage());
-                s_logger.error(message);
-                throw new TaskExecutionException(message, e);
-            } catch (final UnsupportedVersionException e) {
-                final String message = String.format("UnsupportedVersionException occured when executing taks! Error '%s'", e.getMessage());
-                s_logger.error(message);
-                throw new TaskExecutionException(message, e);
-            } finally {
-                txn.close();
-            }
-        }
-    }
-
-    @Override
-    public void onManagementNodeJoined(final List<? extends ManagementServerHost> nodeList, final long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(final List<? extends ManagementServerHost> nodeList, final long selfNodeId) {
-        for (final ManagementServerHost vo : nodeList) {
-            s_logger.info("Marking hosts as disconnected on Management server" + vo.getMsid());
-            final long lastPing = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
-            _hostDao.markHostsAsDisconnected(vo.getMsid(), lastPing);
-            outOfBandManagementDao.expireServerOwnership(vo.getMsid());
-            haConfigDao.expireServerOwnership(vo.getMsid());
-            s_logger.info("Deleting entries from op_host_transfer table for Management server " + vo.getMsid());
-            cleanupTransferMap(vo.getMsid());
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public void removeAgent(final AgentAttache attache, final Status nextState) {
-        if (attache == null) {
-            return;
-        }
-
-        super.removeAgent(attache, nextState);
-    }
-
-    @Override
-    public boolean executeRebalanceRequest(final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event) throws AgentUnavailableException,
-    OperationTimedoutException {
-        boolean result = false;
-        if (event == Event.RequestAgentRebalance) {
-            return setToWaitForRebalance(agentId, currentOwnerId, futureOwnerId);
-        } else if (event == Event.StartAgentRebalance) {
-            try {
-                result = rebalanceHost(agentId, currentOwnerId, futureOwnerId);
-            } catch (final Exception e) {
-                s_logger.warn("Unable to rebalance host id=" + agentId, e);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public void scheduleRebalanceAgents() {
-        _timer.schedule(new AgentLoadBalancerTask(), 30000);
-    }
-
-    public class AgentLoadBalancerTask extends ManagedContextTimerTask {
-        protected volatile boolean cancelled = false;
-
-        public AgentLoadBalancerTask() {
-            s_logger.debug("Agent load balancer task created");
-        }
-
-        @Override
-        public synchronized boolean cancel() {
-            if (!cancelled) {
-                cancelled = true;
-                s_logger.debug("Agent load balancer task cancelled");
-                return super.cancel();
-            }
-            return true;
-        }
-
-        @Override
-        protected synchronized void runInContext() {
-            try {
-                if (!cancelled) {
-                    startRebalanceAgents();
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("The agent load balancer task is now being cancelled");
-                    }
-                    cancelled = true;
-                }
-            } catch (final Throwable e) {
-                s_logger.error("Unexpected exception " + e.toString(), e);
-            }
-        }
-    }
-
-    public void startRebalanceAgents() {
-        s_logger.debug("Management server " + _nodeId + " is asking other peers to rebalance their agents");
-        final List<ManagementServerHostVO> allMS = _mshostDao.listBy(ManagementServerHost.State.Up);
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getManagementServerId(), Op.NNULL);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
-        final List<HostVO> allManagedAgents = sc.list();
-
-        int avLoad = 0;
-
-        if (!allManagedAgents.isEmpty() && !allMS.isEmpty()) {
-            avLoad = allManagedAgents.size() / allMS.size();
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("There are no hosts to rebalance in the system. Current number of active management server nodes in the system is " + allMS.size() +
-                        "; number of managed agents is " + allManagedAgents.size());
-            }
-            return;
-        }
-
-        if (avLoad == 0L) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("As calculated average load is less than 1, rounding it to 1");
-            }
-            avLoad = 1;
-        }
-
-        for (final ManagementServerHostVO node : allMS) {
-            if (node.getMsid() != _nodeId) {
-
-                List<HostVO> hostsToRebalance = new ArrayList<HostVO>();
-                for (final AgentLoadBalancerPlanner lbPlanner : _lbPlanners) {
-                    hostsToRebalance = lbPlanner.getHostsToRebalance(node.getMsid(), avLoad);
-                    if (hostsToRebalance != null && !hostsToRebalance.isEmpty()) {
-                        break;
-                    } else {
-                        s_logger.debug("Agent load balancer planner " + lbPlanner.getName() + " found no hosts to be rebalanced from management server " + node.getMsid());
-                    }
-                }
-
-                if (hostsToRebalance != null && !hostsToRebalance.isEmpty()) {
-                    s_logger.debug("Found " + hostsToRebalance.size() + " hosts to rebalance from management server " + node.getMsid());
-                    for (final HostVO host : hostsToRebalance) {
-                        final long hostId = host.getId();
-                        s_logger.debug("Asking management server " + node.getMsid() + " to give away host id=" + hostId);
-                        boolean result = true;
-
-                        if (_hostTransferDao.findById(hostId) != null) {
-                            s_logger.warn("Somebody else is already rebalancing host id: " + hostId);
-                            continue;
-                        }
-
-                        HostTransferMapVO transfer = null;
-                        try {
-                            transfer = _hostTransferDao.startAgentTransfering(hostId, node.getMsid(), _nodeId);
-                            final Answer[] answer = sendRebalanceCommand(node.getMsid(), hostId, node.getMsid(), _nodeId, Event.RequestAgentRebalance);
-                            if (answer == null) {
-                                s_logger.warn("Failed to get host id=" + hostId + " from management server " + node.getMsid());
-                                result = false;
-                            }
-                        } catch (final Exception ex) {
-                            s_logger.warn("Failed to get host id=" + hostId + " from management server " + node.getMsid(), ex);
-                            result = false;
-                        } finally {
-                            if (transfer != null) {
-                                final HostTransferMapVO transferState = _hostTransferDao.findByIdAndFutureOwnerId(transfer.getId(), _nodeId);
-                                if (!result && transferState != null && transferState.getState() == HostTransferState.TransferRequested) {
-                                    if (s_logger.isDebugEnabled()) {
-                                        s_logger.debug("Removing mapping from op_host_transfer as it failed to be set to transfer mode");
-                                    }
-                                    // just remove the mapping (if exists) as nothing was done on the peer management
-                                    // server yet
-                                    _hostTransferDao.remove(transfer.getId());
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    s_logger.debug("Found no hosts to rebalance from the management server " + node.getMsid());
-                }
-            }
-        }
-    }
-
-    private Answer[] sendRebalanceCommand(final long peer, final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event) {
-        final TransferAgentCommand transfer = new TransferAgentCommand(agentId, currentOwnerId, futureOwnerId, event);
-        final Commands commands = new Commands(Command.OnError.Stop);
-        commands.addCommand(transfer);
-
-        final Command[] cmds = commands.toCommands();
-
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Forwarding " + cmds[0].toString() + " to " + peer);
-            }
-            final String peerName = Long.toString(peer);
-            final String cmdStr = _gson.toJson(cmds);
-            final String ansStr = _clusterMgr.execute(peerName, agentId, cmdStr, true);
-            final Answer[] answers = _gson.fromJson(ansStr, Answer[].class);
-            return answers;
-        } catch (final Exception e) {
-            s_logger.warn("Caught exception while talking to " + currentOwnerId, e);
-            return null;
-        }
-    }
-
-    public String getPeerName(final long agentHostId) {
-
-        final HostVO host = _hostDao.findById(agentHostId);
-        if (host != null && host.getManagementServerId() != null) {
-            if (_clusterMgr.getSelfPeerName().equals(Long.toString(host.getManagementServerId()))) {
-                return null;
-            }
-
-            return Long.toString(host.getManagementServerId());
-        }
-        return null;
-    }
-
-    public Boolean propagateAgentEvent(final long agentId, final Event event) throws AgentUnavailableException {
-        final String msPeer = getPeerName(agentId);
-        if (msPeer == null) {
-            return null;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Propagating agent change request event:" + event.toString() + " to agent:" + agentId);
-        }
-        final Command[] cmds = new Command[1];
-        cmds[0] = new ChangeAgentCommand(agentId, event);
-
-        final String ansStr = _clusterMgr.execute(msPeer, agentId, _gson.toJson(cmds), true);
-        if (ansStr == null) {
-            throw new AgentUnavailableException(agentId);
-        }
-
-        final Answer[] answers = _gson.fromJson(ansStr, Answer[].class);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Result for agent change is " + answers[0].getResult());
-        }
-
-        return answers[0].getResult();
-    }
-
-    private Runnable getTransferScanTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                try {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Clustered agent transfer scan check, management server id:" + _nodeId);
-                    }
-                    synchronized (_agentToTransferIds) {
-                        if (_agentToTransferIds.size() > 0) {
-                            s_logger.debug("Found " + _agentToTransferIds.size() + " agents to transfer");
-                            // for (Long hostId : _agentToTransferIds) {
-                            for (final Iterator<Long> iterator = _agentToTransferIds.iterator(); iterator.hasNext();) {
-                                final Long hostId = iterator.next();
-                                final AgentAttache attache = findAttache(hostId);
-
-                                // if the thread:
-                                // 1) timed out waiting for the host to reconnect
-                                // 2) recipient management server is not active any more
-                                // 3) if the management server doesn't own the host any more
-                                // remove the host from re-balance list and delete from op_host_transfer DB
-                                // no need to do anything with the real attache as we haven't modified it yet
-                                final Date cutTime = DateUtil.currentGMTTime();
-                                final HostTransferMapVO transferMap =
-                                        _hostTransferDao.findActiveHostTransferMapByHostId(hostId, new Date(cutTime.getTime() - rebalanceTimeOut));
-
-                                if (transferMap == null) {
-                                    s_logger.debug("Timed out waiting for the host id=" + hostId + " to be ready to transfer, skipping rebalance for the host");
-                                    iterator.remove();
-                                    _hostTransferDao.completeAgentTransfer(hostId);
-                                    continue;
-                                }
-
-                                if (transferMap.getInitialOwner() != _nodeId || attache == null || attache.forForward()) {
-                                    s_logger.debug("Management server " + _nodeId + " doesn't own host id=" + hostId + " any more, skipping rebalance for the host");
-                                    iterator.remove();
-                                    _hostTransferDao.completeAgentTransfer(hostId);
-                                    continue;
-                                }
-
-                                final ManagementServerHostVO ms = _mshostDao.findByMsid(transferMap.getFutureOwner());
-                                if (ms != null && ms.getState() != ManagementServerHost.State.Up) {
-                                    s_logger.debug("Can't transfer host " + hostId + " as it's future owner is not in UP state: " + ms +
-                                            ", skipping rebalance for the host");
-                                    iterator.remove();
-                                    _hostTransferDao.completeAgentTransfer(hostId);
-                                    continue;
-                                }
-
-                                if (attache.getQueueSize() == 0 && attache.getNonRecurringListenersSize() == 0) {
-                                    iterator.remove();
-                                    try {
-                                        _executor.execute(new RebalanceTask(hostId, transferMap.getInitialOwner(), transferMap.getFutureOwner()));
-                                    } catch (final RejectedExecutionException ex) {
-                                        s_logger.warn("Failed to submit rebalance task for host id=" + hostId + "; postponing the execution");
-                                        continue;
-                                    }
-
-                                } else {
-                                    s_logger.debug("Agent " + hostId + " can't be transfered yet as its request queue size is " + attache.getQueueSize() +
-                                            " and listener queue size is " + attache.getNonRecurringListenersSize());
-                                }
-                            }
-                        } else {
-                            if (s_logger.isTraceEnabled()) {
-                                s_logger.trace("Found no agents to be transfered by the management server " + _nodeId);
-                            }
-                        }
-                    }
-
-                } catch (final Throwable e) {
-                    s_logger.error("Problem with the clustered agent transfer scan check!", e);
-                }
-            }
-        };
-    }
-
-    private boolean setToWaitForRebalance(final long hostId, final long currentOwnerId, final long futureOwnerId) {
-        s_logger.debug("Adding agent " + hostId + " to the list of agents to transfer");
-        synchronized (_agentToTransferIds) {
-            return _agentToTransferIds.add(hostId);
-        }
-    }
-
-    protected boolean rebalanceHost(final long hostId, final long currentOwnerId, final long futureOwnerId) throws AgentUnavailableException {
-
-        boolean result = true;
-        if (currentOwnerId == _nodeId) {
-            if (!startRebalance(hostId)) {
-                s_logger.debug("Failed to start agent rebalancing");
-                finishRebalance(hostId, futureOwnerId, Event.RebalanceFailed);
-                return false;
-            }
-            try {
-                final Answer[] answer = sendRebalanceCommand(futureOwnerId, hostId, currentOwnerId, futureOwnerId, Event.StartAgentRebalance);
-                if (answer == null || !answer[0].getResult()) {
-                    result = false;
-                }
-
-            } catch (final Exception ex) {
-                s_logger.warn("Host " + hostId + " failed to connect to the management server " + futureOwnerId + " as a part of rebalance process", ex);
-                result = false;
-            }
-
-            if (result) {
-                s_logger.debug("Successfully transfered host id=" + hostId + " to management server " + futureOwnerId);
-                finishRebalance(hostId, futureOwnerId, Event.RebalanceCompleted);
-            } else {
-                s_logger.warn("Failed to transfer host id=" + hostId + " to management server " + futureOwnerId);
-                finishRebalance(hostId, futureOwnerId, Event.RebalanceFailed);
-            }
-
-        } else if (futureOwnerId == _nodeId) {
-            final HostVO host = _hostDao.findById(hostId);
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Disconnecting host " + host.getId() + "(" + host.getName() + " as a part of rebalance process without notification");
-                }
-
-                final AgentAttache attache = findAttache(hostId);
-                if (attache != null) {
-                    result = handleDisconnect(attache, Event.AgentDisconnected, false, false, true);
-                }
-
-                if (result) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Loading directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId +
-                                " as a part of rebalance process");
-                    }
-                    result = loadDirectlyConnectedHost(host, true);
-                } else {
-                    s_logger.warn("Failed to disconnect " + host.getId() + "(" + host.getName() + " as a part of rebalance process without notification");
-                }
-
-            } catch (final Exception ex) {
-                s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId +
-                        " as a part of rebalance process due to:", ex);
-                result = false;
-            }
-
-            if (result) {
-                s_logger.debug("Successfully loaded directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId +
-                        " as a part of rebalance process");
-            } else {
-                s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId +
-                        " as a part of rebalance process");
-            }
-        }
-
-        return result;
-    }
-
-    protected void finishRebalance(final long hostId, final long futureOwnerId, final Event event) {
-
-        final boolean success = event == Event.RebalanceCompleted ? true : false;
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Finishing rebalancing for the agent " + hostId + " with event " + event);
-        }
-
-        final AgentAttache attache = findAttache(hostId);
-        if (attache == null || !(attache instanceof ClusteredAgentAttache)) {
-            s_logger.debug("Unable to find forward attache for the host id=" + hostId + ", assuming that the agent disconnected already");
-            _hostTransferDao.completeAgentTransfer(hostId);
-            return;
-        }
-
-        final ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)attache;
-
-        if (success) {
-
-            // 1) Set transfer mode to false - so the agent can start processing requests normally
-            forwardAttache.setTransferMode(false);
-
-            // 2) Get all transfer requests and route them to peer
-            Request requestToTransfer = forwardAttache.getRequestToTransfer();
-            while (requestToTransfer != null) {
-                s_logger.debug("Forwarding request " + requestToTransfer.getSequence() + " held in transfer attache " + hostId + " from the management server " +
-                        _nodeId + " to " + futureOwnerId);
-                final boolean routeResult = routeToPeer(Long.toString(futureOwnerId), requestToTransfer.getBytes());
-                if (!routeResult) {
-                    logD(requestToTransfer.getBytes(), "Failed to route request to peer");
-                }
-
-                requestToTransfer = forwardAttache.getRequestToTransfer();
-            }
-
-            s_logger.debug("Management server " + _nodeId + " completed agent " + hostId + " rebalance to " + futureOwnerId);
-
-        } else {
-            failRebalance(hostId);
-        }
-
-        s_logger.debug("Management server " + _nodeId + " completed agent " + hostId + " rebalance");
-        _hostTransferDao.completeAgentTransfer(hostId);
-    }
-
-    protected void failRebalance(final long hostId) {
-        try {
-            s_logger.debug("Management server " + _nodeId + " failed to rebalance agent " + hostId);
-            _hostTransferDao.completeAgentTransfer(hostId);
-            handleDisconnectWithoutInvestigation(findAttache(hostId), Event.RebalanceFailed, true, true);
-        } catch (final Exception ex) {
-            s_logger.warn("Failed to reconnect host id=" + hostId + " as a part of failed rebalance task cleanup");
-        }
-    }
-
-    protected boolean startRebalance(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-
-        if (host == null || host.getRemoved() != null) {
-            s_logger.warn("Unable to find host record, fail start rebalancing process");
-            return false;
-        }
-
-        synchronized (_agents) {
-            final ClusteredDirectAgentAttache attache = (ClusteredDirectAgentAttache)_agents.get(hostId);
-            if (attache != null && attache.getQueueSize() == 0 && attache.getNonRecurringListenersSize() == 0) {
-                handleDisconnectWithoutInvestigation(attache, Event.StartAgentRebalance, true, true);
-                final ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)createAttache(hostId);
-                if (forwardAttache == null) {
-                    s_logger.warn("Unable to create a forward attache for the host " + hostId + " as a part of rebalance process");
-                    return false;
-                }
-                s_logger.debug("Putting agent id=" + hostId + " to transfer mode");
-                forwardAttache.setTransferMode(true);
-                _agents.put(hostId, forwardAttache);
-            } else {
-                if (attache == null) {
-                    s_logger.warn("Attache for the agent " + hostId + " no longer exists on management server " + _nodeId + ", can't start host rebalancing");
-                } else {
-                    s_logger.warn("Attache for the agent " + hostId + " has request queue size= " + attache.getQueueSize() + " and listener queue size " +
-                            attache.getNonRecurringListenersSize() + ", can't start host rebalancing");
-                }
-                return false;
-            }
-        }
-        _hostTransferDao.startAgentTransfer(hostId);
-        return true;
-    }
-
-    protected void cleanupTransferMap(final long msId) {
-        final List<HostTransferMapVO> hostsJoingingCluster = _hostTransferDao.listHostsJoiningCluster(msId);
-
-        for (final HostTransferMapVO hostJoingingCluster : hostsJoingingCluster) {
-            _hostTransferDao.remove(hostJoingingCluster.getId());
-        }
-
-        final List<HostTransferMapVO> hostsLeavingCluster = _hostTransferDao.listHostsLeavingCluster(msId);
-        for (final HostTransferMapVO hostLeavingCluster : hostsLeavingCluster) {
-            _hostTransferDao.remove(hostLeavingCluster.getId());
-        }
-    }
-
-    protected class RebalanceTask extends ManagedContextRunnable {
-        Long hostId = null;
-        Long currentOwnerId = null;
-        Long futureOwnerId = null;
-
-        public RebalanceTask(final long hostId, final long currentOwnerId, final long futureOwnerId) {
-            this.hostId = hostId;
-            this.currentOwnerId = currentOwnerId;
-            this.futureOwnerId = futureOwnerId;
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Rebalancing host id=" + hostId);
-                }
-                rebalanceHost(hostId, currentOwnerId, futureOwnerId);
-            } catch (final Exception e) {
-                s_logger.warn("Unable to rebalance host id=" + hostId, e);
-            }
-        }
-    }
-
-    private String handleScheduleHostScanTaskCommand(final ScheduleHostScanTaskCommand cmd) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Intercepting resource manager command: " + _gson.toJson(cmd));
-        }
-
-        try {
-            scheduleHostScanTask();
-        } catch (final Exception e) {
-            // Scheduling host scan task in peer MS is a best effort operation during host add, regular host scan
-            // happens at fixed intervals anyways. So handling any exceptions that may be thrown
-            s_logger.warn("Exception happened while trying to schedule host scan task on mgmt server " + _clusterMgr.getSelfPeerName() +
-                    ", ignoring as regular host scan happens at fixed interval anyways", e);
-            return null;
-        }
-
-        final Answer[] answers = new Answer[1];
-        answers[0] = new Answer(cmd, true, null);
-        return _gson.toJson(answers);
-    }
-
-    public Answer[] sendToAgent(final Long hostId, final Command[] cmds, final boolean stopOnError) throws AgentUnavailableException, OperationTimedoutException {
-        final Commands commands = new Commands(stopOnError ? Command.OnError.Stop : Command.OnError.Continue);
-        for (final Command cmd : cmds) {
-            commands.addCommand(cmd);
-        }
-        return send(hostId, commands);
-    }
-
-    protected class ClusterDispatcher implements ClusterManager.Dispatcher {
-        @Override
-        public String getName() {
-            return "ClusterDispatcher";
-        }
-
-        @Override
-        public String dispatch(final ClusterServicePdu pdu) {
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Dispatch ->" + pdu.getAgentId() + ", json: " + pdu.getJsonPackage());
-            }
-
-            Command[] cmds = null;
-            try {
-                cmds = _gson.fromJson(pdu.getJsonPackage(), Command[].class);
-            } catch (final Throwable e) {
-                assert false;
-                s_logger.error("Excection in gson decoding : ", e);
-            }
-
-            if (cmds.length == 1 && cmds[0] instanceof ChangeAgentCommand) { // intercepted
-                final ChangeAgentCommand cmd = (ChangeAgentCommand)cmds[0];
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Intercepting command for agent change: agent " + cmd.getAgentId() + " event: " + cmd.getEvent());
-                }
-                boolean result = false;
-                try {
-                    result = executeAgentUserRequest(cmd.getAgentId(), cmd.getEvent());
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Result is " + result);
-                    }
-
-                } catch (final AgentUnavailableException e) {
-                    s_logger.warn("Agent is unavailable", e);
-                    return null;
-                }
-
-                final Answer[] answers = new Answer[1];
-                answers[0] = new ChangeAgentAnswer(cmd, result);
-                return _gson.toJson(answers);
-            } else if (cmds.length == 1 && cmds[0] instanceof TransferAgentCommand) {
-                final TransferAgentCommand cmd = (TransferAgentCommand)cmds[0];
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Intercepting command for agent rebalancing: agent " + cmd.getAgentId() + " event: " + cmd.getEvent());
-                }
-                boolean result = false;
-                try {
-                    result = rebalanceAgent(cmd.getAgentId(), cmd.getEvent(), cmd.getCurrentOwner(), cmd.getFutureOwner());
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Result is " + result);
-                    }
-
-                } catch (final AgentUnavailableException e) {
-                    s_logger.warn("Agent is unavailable", e);
-                    return null;
-                } catch (final OperationTimedoutException e) {
-                    s_logger.warn("Operation timed out", e);
-                    return null;
-                }
-                final Answer[] answers = new Answer[1];
-                answers[0] = new Answer(cmd, result, null);
-                return _gson.toJson(answers);
-            } else if (cmds.length == 1 && cmds[0] instanceof PropagateResourceEventCommand) {
-                final PropagateResourceEventCommand cmd = (PropagateResourceEventCommand)cmds[0];
-
-                s_logger.debug("Intercepting command to propagate event " + cmd.getEvent().name() + " for host " + cmd.getHostId());
-
-                boolean result = false;
-                try {
-                    result = _resourceMgr.executeUserRequest(cmd.getHostId(), cmd.getEvent());
-                    s_logger.debug("Result is " + result);
-                } catch (final AgentUnavailableException ex) {
-                    s_logger.warn("Agent is unavailable", ex);
-                    return null;
-                }
-
-                final Answer[] answers = new Answer[1];
-                answers[0] = new Answer(cmd, result, null);
-                return _gson.toJson(answers);
-            } else if (cmds.length == 1 && cmds[0] instanceof ScheduleHostScanTaskCommand) {
-                final ScheduleHostScanTaskCommand cmd = (ScheduleHostScanTaskCommand)cmds[0];
-                final String response = handleScheduleHostScanTaskCommand(cmd);
-                return response;
-            }
-
-            try {
-                final long startTick = System.currentTimeMillis();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Dispatch -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage());
-                }
-
-                final Answer[] answers = sendToAgent(pdu.getAgentId(), cmds, pdu.isStopOnError());
-                if (answers != null) {
-                    final String jsonReturn = _gson.toJson(answers);
-
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " +
-                                (System.currentTimeMillis() - startTick) + " ms, return result: " + jsonReturn);
-                    }
-
-                    return jsonReturn;
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " +
-                                (System.currentTimeMillis() - startTick) + " ms, return null result");
-                    }
-                }
-            } catch (final AgentUnavailableException e) {
-                s_logger.warn("Agent is unavailable", e);
-            } catch (final OperationTimedoutException e) {
-                s_logger.warn("Timed Out", e);
-            }
-
-            return null;
-        }
-
-    }
-
-    public boolean executeAgentUserRequest(final long agentId, final Event event) throws AgentUnavailableException {
-        return executeUserRequest(agentId, event);
-    }
-
-    public boolean rebalanceAgent(final long agentId, final Event event, final long currentOwnerId, final long futureOwnerId) throws AgentUnavailableException, OperationTimedoutException {
-        return executeRebalanceRequest(agentId, currentOwnerId, futureOwnerId, event);
-    }
-
-    public boolean isAgentRebalanceEnabled() {
-        return EnableLB.value();
-    }
-
-    private Runnable getAgentRebalanceScanTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                try {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Agent rebalance task check, management server id:" + _nodeId);
-                    }
-                    // initiate agent lb task will be scheduled and executed only once, and only when number of agents
-                    // loaded exceeds _connectedAgentsThreshold
-                    if (!_agentLbHappened) {
-                        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-                        sc.and(sc.entity().getManagementServerId(), Op.NNULL);
-                        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
-                        final List<HostVO> allManagedRoutingAgents = sc.list();
-
-                        sc = QueryBuilder.create(HostVO.class);
-                        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
-                        final List<HostVO> allAgents = sc.list();
-                        final double allHostsCount = allAgents.size();
-                        final double managedHostsCount = allManagedRoutingAgents.size();
-                        if (allHostsCount > 0.0) {
-                            final double load = managedHostsCount / allHostsCount;
-                            if (load > ConnectedAgentThreshold.value()) {
-                                s_logger.debug("Scheduling agent rebalancing task as the average agent load " + load + " is more than the threshold " + ConnectedAgentThreshold.value());
-                                scheduleRebalanceAgents();
-                                _agentLbHappened = true;
-                            } else {
-                                s_logger.debug("Not scheduling agent rebalancing task as the average load " + load + " has not crossed the threshold " + ConnectedAgentThreshold.value());
-                            }
-                        }
-                    }
-                } catch (final Throwable e) {
-                    s_logger.error("Problem with the clustered agent transfer scan check!", e);
-                }
-            }
-        };
-    }
-
-    @Override
-    public void rescan() {
-        // schedule a scan task immediately
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Scheduling a host scan task");
-        }
-        // schedule host scan task on current MS
-        scheduleHostScanTask();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Notifying all peer MS to schedule host scan task");
-        }
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        final ConfigKey<?>[] keys = super.getConfigKeys();
-
-        final List<ConfigKey<?>> keysLst = new ArrayList<ConfigKey<?>>();
-        keysLst.addAll(Arrays.asList(keys));
-        keysLst.add(EnableLB);
-        keysLst.add(ConnectedAgentThreshold);
-        keysLst.add(LoadSize);
-        keysLst.add(ScanInterval);
-        return keysLst.toArray(new ConfigKey<?>[keysLst.size()]);
-    }
-}
diff --git a/engine/orchestration/src/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java
deleted file mode 100644
index 77c69f3..0000000
--- a/engine/orchestration/src/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.cluster.ClusterManager;
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-
-public class ClusteredVirtualMachineManagerImpl extends VirtualMachineManagerImpl implements ClusterManagerListener {
-
-    @Inject
-    ClusterManager _clusterMgr;
-
-    protected ClusteredVirtualMachineManagerImpl() {
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (ManagementServerHost node : nodeList) {
-            cancelWorkItems(node.getMsid());
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> xmlParams) throws ConfigurationException {
-        super.configure(name, xmlParams);
-
-        _clusterMgr.registerListener(this);
-
-        return true;
-    }
-
-}
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
deleted file mode 100755
index 682bfb9..0000000
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ /dev/null
@@ -1,5121 +0,0 @@
-// Licensed to the Apacohe 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.vm;
-
-import java.net.URI;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.ca.CAManager;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.ca.Certificate;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.Outcome;
-import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
-import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
-import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
-import org.apache.cloudstack.framework.messagebus.MessageHandler;
-import org.apache.cloudstack.jobs.JobInfo;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.AttachOrDettachConfigDriveCommand;
-import com.cloud.agent.api.CheckVirtualMachineAnswer;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
-import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PlugNicAnswer;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.RebootAnswer;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.ReplugNicAnswer;
-import com.cloud.agent.api.ReplugNicCommand;
-import com.cloud.agent.api.RestoreVMSnapshotAnswer;
-import com.cloud.agent.api.RestoreVMSnapshotCommand;
-import com.cloud.agent.api.ScaleVmCommand;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.agent.api.UnPlugNicAnswer;
-import com.cloud.agent.api.UnPlugNicCommand;
-import com.cloud.agent.api.UnregisterVMCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.GPUDeviceTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.agent.manager.allocator.HostAllocator;
-import com.cloud.alert.AlertManager;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.deploy.DeploymentPlanningManager;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.AffinityConflictException;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.gpu.dao.VGPUTypesDao;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.ha.HighAvailabilityManager.WorkType;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuru;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.DiskOfferingInfo;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.org.Cluster;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.Type;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Journal;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Predicate;
-import com.cloud.utils.ReflectionUse;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.ItWorkVO.Step;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import com.google.common.base.Strings;
-
-public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, VmWorkJobHandler, Listener, Configurable {
-    private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
-
-    public static final String VM_WORK_JOB_HANDLER = VirtualMachineManagerImpl.class.getSimpleName();
-
-    private static final String VM_SYNC_ALERT_SUBJECT = "VM state sync alert";
-
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    protected NetworkOrchestrationService _networkMgr;
-    @Inject
-    protected NetworkModel _networkModel;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    protected VMInstanceDao _vmDao;
-    @Inject
-    protected ServiceOfferingDao _offeringDao;
-    @Inject
-    protected DiskOfferingDao _diskOfferingDao;
-    @Inject
-    protected VMTemplateDao _templateDao;
-    @Inject
-    protected DomainDao _domainDao;
-    @Inject
-    protected ItWorkDao _workDao;
-    @Inject
-    protected UserVmDao _userVmDao;
-    @Inject
-    protected UserVmService _userVmService;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    protected NicDao _nicsDao;
-    @Inject
-    protected HostDao _hostDao;
-    @Inject
-    protected AlertManager _alertMgr;
-    @Inject
-    protected GuestOSCategoryDao _guestOsCategoryDao;
-    @Inject
-    protected GuestOSDao _guestOsDao;
-    @Inject
-    protected VolumeDao _volsDao;
-    @Inject
-    protected HighAvailabilityManager _haMgr;
-    @Inject
-    protected HostPodDao _podDao;
-    @Inject
-    protected DataCenterDao _dcDao;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    protected HypervisorGuruManager _hvGuruMgr;
-    @Inject
-    protected NetworkDao _networkDao;
-    @Inject
-    protected StoragePoolHostDao _poolHostDao;
-    @Inject
-    protected VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    protected RulesManager rulesMgr;
-    @Inject
-    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
-    @Inject
-    protected VGPUTypesDao _vgpuTypesDao;
-    @Inject
-    protected EntityManager _entityMgr;
-    @Inject
-    protected GuestOSCategoryDao _guestOSCategoryDao;
-    @Inject
-    protected GuestOSDao _guestOSDao = null;
-    @Inject
-    protected UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    protected ServiceOfferingDao _serviceOfferingDao = null;
-    @Inject
-    protected CAManager caManager;
-
-    @Inject
-    ConfigDepot _configDepot;
-
-    protected List<HostAllocator> hostAllocators;
-
-    public List<HostAllocator> getHostAllocators() {
-        return hostAllocators;
-    }
-
-    public void setHostAllocators(final List<HostAllocator> hostAllocators) {
-        this.hostAllocators = hostAllocators;
-    }
-
-    protected List<StoragePoolAllocator> _storagePoolAllocators;
-
-    @Inject
-    protected ResourceManager _resourceMgr;
-
-    @Inject
-    protected VMSnapshotManager _vmSnapshotMgr = null;
-    @Inject
-    protected ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    protected UserVmDetailsDao _uservmDetailsDao;
-
-    @Inject
-    protected ConfigurationDao _configDao;
-    @Inject
-    VolumeOrchestrationService volumeMgr;
-
-    @Inject
-    DeploymentPlanningManager _dpMgr;
-
-    @Inject
-    protected MessageBus _messageBus;
-    @Inject
-    protected VirtualMachinePowerStateSync _syncMgr;
-    @Inject
-    protected VmWorkJobDao _workJobDao;
-    @Inject
-    protected AsyncJobManager _jobMgr;
-
-    VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
-
-    Map<VirtualMachine.Type, VirtualMachineGuru> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru>();
-    protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
-
-    static final ConfigKey<Integer> StartRetry = new ConfigKey<Integer>("Advanced", Integer.class, "start.retry", "10",
-            "Number of times to retry create and start commands", true);
-    static final ConfigKey<Integer> VmOpWaitInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.op.wait.interval", "120",
-            "Time (in seconds) to wait before checking if a previous operation has succeeded", true);
-
-    static final ConfigKey<Integer> VmOpLockStateRetry = new ConfigKey<Integer>("Advanced", Integer.class, "vm.op.lock.state.retry", "5",
-            "Times to retry locking the state of a VM for operations, -1 means forever", true);
-    static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cleanup.interval", "86400",
-            "Interval to run the thread that cleans up the vm operations (in seconds)", false);
-    static final ConfigKey<Long> VmOpCleanupWait = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cleanup.wait", "3600",
-            "Time (in seconds) to wait before cleanuping up any vm work items", true);
-    static final ConfigKey<Long> VmOpCancelInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cancel.interval", "3600",
-            "Time (in seconds) to wait before cancelling a operation", false);
-    static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
-            "On destroy, force-stop takes this value ", true);
-    static final ConfigKey<Integer> ClusterDeltaSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "sync.interval", "60",
-            "Cluster Delta sync interval in seconds",
-            false);
-    static final ConfigKey<Integer> ClusterVMMetaDataSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vmmetadata.sync.interval", "180", "Cluster VM metadata sync interval in seconds",
-            false);
-
-    static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced",
-            Long.class, "vm.job.check.interval", "3000",
-            "Interval in milliseconds to check if the job is complete", false);
-    static final ConfigKey<Long> VmJobTimeout = new ConfigKey<Long>("Advanced",
-            Long.class, "vm.job.timeout", "600000",
-            "Time in milliseconds to wait before attempting to cancel a job", false);
-    static final ConfigKey<Integer> VmJobStateReportInterval = new ConfigKey<Integer>("Advanced",
-            Integer.class, "vm.job.report.interval", "60",
-            "Interval to send application level pings to make sure the connection is still working", false);
-
-    static final ConfigKey<Boolean> HaVmRestartHostUp = new ConfigKey<Boolean>("Advanced", Boolean.class, "ha.vm.restart.hostup", "true",
-            "If an out-of-band stop of a VM is detected and its host is up, then power on the VM", true);
-
-    ScheduledExecutorService _executor = null;
-
-    protected long _nodeId;
-
-    @Override
-    public void registerGuru(final VirtualMachine.Type type, final VirtualMachineGuru guru) {
-        synchronized (_vmGurus) {
-            _vmGurus.put(type, guru);
-        }
-    }
-
-    @Override
-    @DB
-    public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
-            final DiskOfferingInfo rootDiskOfferingInfo, final List<DiskOfferingInfo> dataDiskOfferings,
-            final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, final DeploymentPlan plan, final HypervisorType hyperType, final Map<String, Map<Integer, String>> extraDhcpOptions, final Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap)
-                    throws InsufficientCapacityException {
-
-        final VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName);
-        final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Allocating entries for VM: " + vm);
-        }
-
-        vm.setDataCenterId(plan.getDataCenterId());
-        if (plan.getPodId() != null) {
-            vm.setPodIdToDeployIn(plan.getPodId());
-        }
-        assert plan.getClusterId() == null && plan.getPoolId() == null : "We currently don't support cluster and pool preset yet";
-        final VMInstanceVO vmFinal = _vmDao.persist(vm);
-
-        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null);
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Allocating nics for " + vmFinal);
-                }
-
-                try {
-                    if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm"))
-                        _networkMgr.allocate(vmProfile, auxiliaryNetworks, extraDhcpOptions);
-                } catch (final ConcurrentOperationException e) {
-                    throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e);
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Allocating disks for " + vmFinal);
-                }
-
-                if (template.getFormat() == ImageFormat.ISO) {
-                    volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
-                            rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
-                } else if (template.getFormat() == ImageFormat.BAREMETAL) {
-                    // Do nothing
-                } else {
-                    volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
-                            rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner);
-                }
-
-                if (dataDiskOfferings != null) {
-                    for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
-                        volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
-                                dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
-                    }
-                }
-                if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
-                    int diskNumber = 1;
-                    for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
-                        DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
-                        long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
-                        VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
-                        volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
-                                vmFinal, dataDiskTemplate, owner, Long.valueOf(diskNumber));
-                        diskNumber++;
-                    }
-                }
-            }
-        });
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Allocation completed for VM: " + vmFinal);
-        }
-    }
-
-    @Override
-    public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
-            final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
-        allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList<DiskOfferingInfo>(), networks, plan, hyperType, null, null);
-    }
-
-    private VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
-        if(vm != null) {
-            return _vmGurus.get(vm.getType());
-        }
-        return null;
-    }
-
-    @Override
-    public void expunge(final String vmUuid) throws ResourceUnavailableException {
-        try {
-            advanceExpunge(vmUuid);
-        } catch (final OperationTimedoutException e) {
-            throw new CloudRuntimeException("Operation timed out", e);
-        } catch (final ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Concurrent operation ", e);
-        }
-    }
-
-    @Override
-    public void advanceExpunge(final String vmUuid) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        advanceExpunge(vm);
-    }
-
-    protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-        if (vm == null || vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
-            }
-            return;
-        }
-
-        advanceStop(vm.getUuid(), false);
-        vm = _vmDao.findByUuid(vm.getUuid());
-
-        try {
-            if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) {
-                s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
-                throw new CloudRuntimeException("Unable to destroy " + vm);
-
-            }
-        } catch (final NoTransitionException e) {
-            s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
-            throw new CloudRuntimeException("Unable to destroy " + vm, e);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Destroying vm " + vm);
-        }
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
-
-        s_logger.debug("Cleaning up NICS");
-        final List<Command> nicExpungeCommands = hvGuru.finalizeExpungeNics(vm, profile.getNics());
-        _networkMgr.cleanupNics(profile);
-
-        s_logger.debug("Cleaning up hypervisor data structures (ex. SRs in XenServer) for managed storage");
-
-        final List<Command> volumeExpungeCommands = hvGuru.finalizeExpungeVolumes(vm);
-
-        final Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
-
-        List<Map<String, String>> targets = getTargets(hostId, vm.getId());
-
-        if (volumeExpungeCommands != null && volumeExpungeCommands.size() > 0 && hostId != null) {
-            final Commands cmds = new Commands(Command.OnError.Stop);
-
-            for (final Command volumeExpungeCommand : volumeExpungeCommands) {
-                cmds.addCommand(volumeExpungeCommand);
-            }
-
-            _agentMgr.send(hostId, cmds);
-
-            if (!cmds.isSuccessful()) {
-                for (final Answer answer : cmds.getAnswers()) {
-                    if (!answer.getResult()) {
-                        s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
-
-                        throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails());
-                    }
-                }
-            }
-        }
-
-        if (hostId != null) {
-            volumeMgr.revokeAccess(vm.getId(), hostId);
-        }
-
-        // Clean up volumes based on the vm's instance id
-        volumeMgr.cleanupVolumes(vm.getId());
-
-        if (hostId != null && CollectionUtils.isNotEmpty(targets)) {
-            removeDynamicTargets(hostId, targets);
-        }
-
-        final VirtualMachineGuru guru = getVmGuru(vm);
-        guru.finalizeExpunge(vm);
-        //remove the overcommit detials from the uservm details
-        _uservmDetailsDao.removeDetails(vm.getId());
-
-        // send hypervisor-dependent commands before removing
-        final List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm);
-        if (finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0) {
-            if (hostId != null) {
-                final Commands cmds = new Commands(Command.OnError.Stop);
-                for (final Command command : finalizeExpungeCommands) {
-                    cmds.addCommand(command);
-                }
-                if (nicExpungeCommands != null) {
-                    for (final Command command : nicExpungeCommands) {
-                        cmds.addCommand(command);
-                    }
-                }
-                _agentMgr.send(hostId, cmds);
-                if (!cmds.isSuccessful()) {
-                    for (final Answer answer : cmds.getAnswers()) {
-                        if (!answer.getResult()) {
-                            s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
-                            throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails());
-                        }
-                    }
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Expunged " + vm);
-        }
-
-    }
-
-    private List<Map<String, String>> getTargets(Long hostId, long vmId) {
-        List<Map<String, String>> targets = new ArrayList<>();
-
-        HostVO hostVO = _hostDao.findById(hostId);
-
-        if (hostVO == null || hostVO.getHypervisorType() != HypervisorType.VMware) {
-            return targets;
-        }
-
-        List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
-
-        if (CollectionUtils.isEmpty(volumes)) {
-            return targets;
-        }
-
-        for (VolumeVO volume : volumes) {
-            StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
-
-            if (storagePoolVO != null && storagePoolVO.isManaged()) {
-                Map<String, String> target = new HashMap<>();
-
-                target.put(ModifyTargetsCommand.STORAGE_HOST, storagePoolVO.getHostAddress());
-                target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
-                target.put(ModifyTargetsCommand.IQN, volume.get_iScsiName());
-
-                targets.add(target);
-            }
-        }
-
-        return targets;
-    }
-
-    private void removeDynamicTargets(long hostId, List<Map<String, String>> targets) {
-        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-        cmd.setTargets(targets);
-        cmd.setApplyToAllHostsInCluster(true);
-        cmd.setAdd(false);
-        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-
-        sendModifyTargetsCommand(cmd, hostId);
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            String msg = "Unable to get an answer to the modify targets command";
-
-            s_logger.warn(msg);
-        }
-        else if (!answer.getResult()) {
-            String msg = "Unable to modify target on the following host: " + hostId;
-
-            s_logger.warn(msg);
-        }
-    }
-
-    @Override
-    public boolean start() {
-        // TODO, initial delay is hardcoded
-        _executor.scheduleAtFixedRate(new CleanupTask(), 5, VmJobStateReportInterval.value(), TimeUnit.SECONDS);
-        _executor.scheduleAtFixedRate(new TransitionTask(),  VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS);
-        cancelWorkItems(_nodeId);
-
-        volumeMgr.cleanupStorageJobs();
-        // cleanup left over place holder works
-        _workJobDao.expungeLeftoverWorkJobs(ManagementServerNode.getManagementServerId());
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
-        ReservationContextImpl.init(_entityMgr);
-        VirtualMachineProfileImpl.init(_entityMgr);
-        VmWorkMigrate.init(_entityMgr);
-
-        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
-        _nodeId = ManagementServerNode.getManagementServerId();
-
-        _agentMgr.registerForHostEvents(this, true, true, true);
-
-        _messageBus.subscribe(VirtualMachineManager.Topics.VM_POWER_STATE, MessageDispatcher.getDispatcher(this));
-
-        return true;
-    }
-
-    protected VirtualMachineManagerImpl() {
-        setStateMachine();
-    }
-
-    @Override
-    public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) {
-        start(vmUuid, params, null, null);
-    }
-
-    @Override
-    public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner) {
-        try {
-            advanceStart(vmUuid, params, planToDeploy, planner);
-        } catch (final ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e).add(VirtualMachine.class, vmUuid);
-        } catch (final InsufficientCapacityException e) {
-            throw new CloudRuntimeException("Unable to start a VM due to insufficient capacity", e).add(VirtualMachine.class, vmUuid);
-        } catch (final ResourceUnavailableException e) {
-            if(e.getScope() != null && e.getScope().equals(VirtualRouter.class)){
-                throw new CloudRuntimeException("Network is unavailable. Please contact administrator", e).add(VirtualMachine.class, vmUuid);
-            }
-            throw new CloudRuntimeException("Unable to start a VM due to unavailable resources", e).add(VirtualMachine.class, vmUuid);
-        }
-
-    }
-
-    protected boolean checkWorkItems(final VMInstanceVO vm, final State state) throws ConcurrentOperationException {
-        while (true) {
-            final ItWorkVO vo = _workDao.findByOutstandingWork(vm.getId(), state);
-            if (vo == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to find work for VM: " + vm + " and state: " + state);
-                }
-                return true;
-            }
-
-            if (vo.getStep() == Step.Done) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Work for " + vm + " is " + vo.getStep());
-                }
-                return true;
-            }
-
-            // also check DB to get latest VM state to detect vm update from concurrent process before idle waiting to get an early exit
-            final VMInstanceVO instance = _vmDao.findById(vm.getId());
-            if (instance != null && instance.getState() == State.Running) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("VM is already started in DB: " + vm);
-                }
-                return true;
-            }
-
-            if (vo.getSecondsTaskIsInactive() > VmOpCancelInterval.value()) {
-                s_logger.warn("The task item for vm " + vm + " has been inactive for " + vo.getSecondsTaskIsInactive());
-                return false;
-            }
-
-            try {
-                Thread.sleep(VmOpWaitInterval.value()*1000);
-            } catch (final InterruptedException e) {
-                s_logger.info("Waiting for " + vm + " but is interrupted");
-                throw new ConcurrentOperationException("Waiting for " + vm + " but is interrupted");
-            }
-            s_logger.debug("Waiting some more to make sure there's no activity on " + vm);
-        }
-
-    }
-
-    @DB
-    protected Ternary<VMInstanceVO, ReservationContext, ItWorkVO> changeToStartState(final VirtualMachineGuru vmGuru, final VMInstanceVO vm, final User caller,
-            final Account account) throws ConcurrentOperationException {
-        final long vmId = vm.getId();
-
-        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId());
-        int retry = VmOpLockStateRetry.value();
-        while (retry-- != 0) {
-            try {
-                final ItWorkVO workFinal = work;
-                final Ternary<VMInstanceVO, ReservationContext, ItWorkVO> result =
-                        Transaction.execute(new TransactionCallbackWithException<Ternary<VMInstanceVO, ReservationContext, ItWorkVO>, NoTransitionException>() {
-                            @Override
-                            public Ternary<VMInstanceVO, ReservationContext, ItWorkVO> doInTransaction(final TransactionStatus status) throws NoTransitionException {
-                                final Journal journal = new Journal.LogJournal("Creating " + vm, s_logger);
-                                final ItWorkVO work = _workDao.persist(workFinal);
-                                final ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account);
-
-                                if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) {
-                                    if (s_logger.isDebugEnabled()) {
-                                        s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId());
-                                    }
-                                    return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(vm, context, work);
-                                }
-
-                                return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(null, null, work);
-                            }
-                        });
-
-                work = result.third();
-                if (result.first() != null) {
-                    return result;
-                }
-            } catch (final NoTransitionException e) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to transition into Starting state due to " + e.getMessage());
-                }
-            }
-
-            final VMInstanceVO instance = _vmDao.findById(vmId);
-            if (instance == null) {
-                throw new ConcurrentOperationException("Unable to acquire lock on " + vm);
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Determining why we're unable to update the state to Starting for " + instance + ".  Retry=" + retry);
-            }
-
-            final State state = instance.getState();
-            if (state == State.Running) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("VM is already started: " + vm);
-                }
-                return null;
-            }
-
-            if (state.isTransitional()) {
-                if (!checkWorkItems(vm, state)) {
-                    throw new ConcurrentOperationException("There are concurrent operations on " + vm);
-                } else {
-                    continue;
-                }
-            }
-
-            if (state != State.Stopped) {
-                s_logger.debug("VM " + vm + " is not in a state to be started: " + state);
-                return null;
-            }
-        }
-
-        throw new ConcurrentOperationException("Unable to change the state of " + vm);
-    }
-
-    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.
-        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 && work != null) {
-                _workDao.updateStep(work, previousStep);
-            }
-        }
-    }
-
-    protected boolean areAffinityGroupsAssociated(final VirtualMachineProfile vmProfile) {
-        final VirtualMachine vm = vmProfile.getVirtualMachine();
-        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
-
-        if (vmGroupCount > 0) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void advanceStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlanner planner)
-            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-        advanceStart(vmUuid, params, null, planner);
-    }
-
-    @Override
-    public void advanceStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner)
-            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if ( jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateStart(vmUuid, params, planToDeploy, planner);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy, planner);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof InsufficientCapacityException) {
-                    throw (InsufficientCapacityException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-            }
-        }
-    }
-
-    private void setupAgentSecurity(final Host vmHost, final Map<String, String> sshAccessDetails, final VirtualMachine vm) throws AgentUnavailableException, OperationTimedoutException {
-        final String csr = caManager.generateKeyStoreAndCsr(vmHost, sshAccessDetails);
-        if (!Strings.isNullOrEmpty(csr)) {
-            final Map<String, String> ipAddressDetails = new HashMap<>(sshAccessDetails);
-            ipAddressDetails.remove(NetworkElementCommand.ROUTER_NAME);
-            final Certificate certificate = caManager.issueCertificate(csr, Arrays.asList(vm.getHostName(), vm.getInstanceName()),
-                    new ArrayList<>(ipAddressDetails.values()), CAManager.CertValidityPeriod.value(), null);
-            final boolean result = caManager.deployCertificate(vmHost, certificate, false, sshAccessDetails);
-            if (!result) {
-                s_logger.error("Failed to setup certificate for system vm: " + vm.getInstanceName());
-            }
-        } else {
-            s_logger.error("Failed to setup keystore and generate CSR for system vm: " + vm.getInstanceName());
-        }
-    }
-
-    @Override
-    public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner)
-            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-
-        final CallContext cctxt = CallContext.current();
-        final Account account = cctxt.getCallingAccount();
-        final User caller = cctxt.getCallingUser();
-
-        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-
-        final Ternary<VMInstanceVO, ReservationContext, ItWorkVO> start = changeToStartState(vmGuru, vm, caller, account);
-        if (start == null) {
-            return;
-        }
-
-        vm = start.first();
-        final ReservationContext ctx = start.second();
-        ItWorkVO work = start.third();
-
-        VMInstanceVO startedVm = null;
-        final ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
-        final VirtualMachineTemplate template = _entityMgr.findByIdIncludingRemoved(VirtualMachineTemplate.class, vm.getTemplateId());
-
-        DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null, ctx);
-        if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() +
-                        ", clusterId: " + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId());
-            }
-            plan =
-                    new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(),
-                            planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx);
-        }
-
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
-
-        boolean canRetry = true;
-        ExcludeList avoids = null;
-        try {
-            final Journal journal = start.second().getJournal();
-
-            if (planToDeploy != null) {
-                avoids = planToDeploy.getAvoids();
-            }
-            if (avoids == null) {
-                avoids = new ExcludeList();
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
-            }
-
-            boolean planChangedByVolume = false;
-            boolean reuseVolume = true;
-            final DataCenterDeployment originalPlan = plan;
-
-            int retry = StartRetry.value();
-            while (retry-- != 0) { // It's != so that it can match -1.
-
-                if (reuseVolume) {
-                    // edit plan if this vm's ROOT volume is in READY state already
-                    final List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
-                    for (final VolumeVO vol : vols) {
-                        // make sure if the templateId is unchanged. If it is changed,
-                        // let planner
-                        // reassign pool for the volume even if it ready.
-                        final Long volTemplateId = vol.getTemplateId();
-                        if (volTemplateId != null && volTemplateId.longValue() != template.getId()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool");
-                            }
-                            continue;
-                        }
-
-                        final StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(vol.getPoolId());
-                        if (!pool.isInMaintenance()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Root volume is ready, need to place VM in volume's cluster");
-                            }
-                            final long rootVolDcId = pool.getDataCenterId();
-                            final Long rootVolPodId = pool.getPodId();
-                            final Long rootVolClusterId = pool.getClusterId();
-                            if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) {
-                                final Long clusterIdSpecified = planToDeploy.getClusterId();
-                                if (clusterIdSpecified != null && rootVolClusterId != null) {
-                                    if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) {
-                                        // cannot satisfy the plan passed in to the
-                                        // planner
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: " +
-                                                    rootVolClusterId + ", cluster specified: " + clusterIdSpecified);
-                                        }
-                                        throw new ResourceUnavailableException(
-                                                "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " +
-                                                        vm, Cluster.class, clusterIdSpecified);
-                                    }
-                                }
-                                plan =
-                                        new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(),
-                                                planToDeploy.getHostId(), vol.getPoolId(), null, ctx);
-                            } else {
-                                plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx);
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId +
-                                            " , and clusterId: " + rootVolClusterId);
-                                }
-                                planChangedByVolume = true;
-                            }
-                        }
-                    }
-                }
-
-                final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
-                final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
-                DeployDestination dest = null;
-                try {
-                    dest = _dpMgr.planDeployment(vmProfile, plan, avoids, planner);
-                } catch (final AffinityConflictException e2) {
-                    s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
-                    throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
-
-                }
-
-                if (dest == null) {
-                    if (planChangedByVolume) {
-                        plan = originalPlan;
-                        planChangedByVolume = false;
-                        //do not enter volume reuse for next retry, since we want to look for resources outside the volume's cluster
-                        reuseVolume = false;
-                        continue;
-                    }
-                    throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(),
-                            areAffinityGroupsAssociated(vmProfile));
-                }
-
-                if (dest != null) {
-                    avoids.addHost(dest.getHost().getId());
-                    journal.record("Deployment found ", vmProfile, dest);
-                }
-
-                long destHostId = dest.getHost().getId();
-                vm.setPodIdToDeployIn(dest.getPod().getId());
-                final Long cluster_id = dest.getCluster().getId();
-                final ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, "cpuOvercommitRatio");
-                final ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio");
-                //storing the value of overcommit in the vm_details table for doing a capacity check in case the cluster overcommit ratio is changed.
-                if (_uservmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") == null &&
-                        (Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f)) {
-                    _uservmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true);
-                    _uservmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true);
-                } else if (_uservmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") != null) {
-                    _uservmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true);
-                    _uservmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true);
-                }
-
-                vmProfile.setCpuOvercommitRatio(Float.parseFloat(cluster_detail_cpu.getValue()));
-                vmProfile.setMemoryOvercommitRatio(Float.parseFloat(cluster_detail_ram.getValue()));
-                StartAnswer startAnswer = null;
-
-                try {
-                    if (!changeState(vm, Event.OperationRetry, destHostId, work, Step.Prepare)) {
-                        throw new ConcurrentOperationException("Unable to update the state of the Virtual Machine "+vm.getUuid()+" oldstate: "+vm.getState()+ "Event :"+Event.OperationRetry);
-                    }
-                } catch (final NoTransitionException e1) {
-                    throw new ConcurrentOperationException(e1.getMessage());
-                }
-
-                try {
-                    _networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null, dest.getStorageForDisks()), ctx);
-                    if (vm.getHypervisorType() != HypervisorType.BareMetal) {
-                        volumeMgr.prepare(vmProfile, dest);
-                    }
-
-                    //since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity
-                    if (!reuseVolume) {
-                        reuseVolume = true;
-                    }
-
-                    Commands cmds = null;
-                    vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx);
-
-                    final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
-
-                    handlePath(vmTO.getDisks(), vm.getHypervisorType());
-
-                    cmds = new Commands(Command.OnError.Stop);
-
-                    cmds.addCommand(new StartCommand(vmTO, dest.getHost(), getExecuteInSequence(vm.getHypervisorType())));
-
-                    vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx);
-
-                    work = _workDao.findById(work.getId());
-                    if (work == null || work.getStep() != Step.Prepare) {
-                        throw new ConcurrentOperationException("Work steps have been changed: " + work);
-                    }
-
-                    _workDao.updateStep(work, Step.Starting);
-
-                    _agentMgr.send(destHostId, cmds);
-
-                    _workDao.updateStep(work, Step.Started);
-
-                    startAnswer = cmds.getAnswer(StartAnswer.class);
-                    if (startAnswer != null && startAnswer.getResult()) {
-                        handlePath(vmTO.getDisks(), startAnswer.getIqnToData());
-
-                        final String host_guid = startAnswer.getHost_guid();
-
-                        if (host_guid != null) {
-                            final HostVO finalHost = _resourceMgr.findHostByGuid(host_guid);
-                            if (finalHost == null) {
-                                throw new CloudRuntimeException("Host Guid " + host_guid + " doesn't exist in DB, something went wrong while processing start answer: "+startAnswer);
-                            }
-                            destHostId = finalHost.getId();
-                        }
-                        if (vmGuru.finalizeStart(vmProfile, destHostId, cmds, ctx)) {
-                            syncDiskChainChange(startAnswer);
-
-                            if (!changeState(vm, Event.OperationSucceeded, destHostId, work, Step.Done)) {
-                                s_logger.error("Unable to transition to a new state. VM uuid: "+vm.getUuid()+    "VM oldstate:"+vm.getState()+"Event:"+Event.OperationSucceeded);
-                                throw new ConcurrentOperationException("Failed to deploy VM"+ vm.getUuid());
-                            }
-
-                            // Update GPU device capacity
-                            final GPUDeviceTO gpuDevice = startAnswer.getVirtualMachine().getGpuDevice();
-                            if (gpuDevice != null) {
-                                _resourceMgr.updateGPUDetails(destHostId, gpuDevice.getGroupDetails());
-                            }
-
-                            // Remove the information on whether it was a deploy vm request.The deployvm=true information
-                            // is set only when the vm is being deployed. When a vm is started from a stop state the
-                            // information isn't set,
-                            if (_uservmDetailsDao.findDetail(vm.getId(), "deployvm") != null) {
-                                _uservmDetailsDao.removeDetail(vm.getId(), "deployvm");
-                            }
-
-                            startedVm = vm;
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Start completed for VM " + vm);
-                            }
-                            final Host vmHost = _hostDao.findById(destHostId);
-                            if (vmHost != null && (VirtualMachine.Type.ConsoleProxy.equals(vm.getType()) ||
-                                    VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) && caManager.canProvisionCertificates()) {
-                                final Map<String, String> sshAccessDetails = _networkMgr.getSystemVMAccessDetails(vm);
-                                for (int retries = 3; retries > 0; retries--) {
-                                    try {
-                                        setupAgentSecurity(vmHost, sshAccessDetails, vm);
-                                        return;
-                                    } catch (final Exception e) {
-                                        s_logger.error("Retrying after catching exception while trying to secure agent for systemvm id=" + vm.getId(), e);
-                                    }
-                                }
-                                throw new CloudRuntimeException("Failed to setup and secure agent for systemvm id=" + vm.getId());
-                            }
-                            return;
-                        } else {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.info("The guru did not like the answers so stopping " + vm);
-                            }
-                            StopCommand stopCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
-                            stopCmd.setControlIp(getControlNicIpForVM(vm));
-                            final StopCommand cmd = stopCmd;
-                            final Answer answer = _agentMgr.easySend(destHostId, cmd);
-                            if (answer != null && answer instanceof StopAnswer) {
-                                final StopAnswer stopAns = (StopAnswer)answer;
-                                if (vm.getType() == VirtualMachine.Type.User) {
-                                    final String platform = stopAns.getPlatform();
-                                    if (platform != null) {
-                                        final Map<String,String> vmmetadata = new HashMap<String,String>();
-                                        vmmetadata.put(vm.getInstanceName(), platform);
-                                        syncVMMetaData(vmmetadata);
-                                    }
-                                }
-                            }
-
-                            if (answer == null || !answer.getResult()) {
-                                s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers"));
-                                _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop);
-                                throw new ExecutionException("Unable to stop this VM, "+vm.getUuid()+" so we are unable to retry the start operation");
-                            }
-                            throw new ExecutionException("Unable to start  VM:"+vm.getUuid()+" due to error in finalizeStart, not retrying");
-                        }
-                    }
-                    s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails()));
-                    if (startAnswer != null && startAnswer.getContextParam("stopRetry") != null) {
-                        break;
-                    }
-
-                } catch (OperationTimedoutException e) {
-                    s_logger.debug("Unable to send the start command to host " + dest.getHost()+" failed to start VM: "+vm.getUuid());
-                    if (e.isActive()) {
-                        _haMgr.scheduleStop(vm, destHostId, WorkType.CheckStop);
-                    }
-                    canRetry = false;
-                    throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e);
-                } catch (final ResourceUnavailableException e) {
-                    s_logger.info("Unable to contact resource.", e);
-                    if (!avoids.add(e)) {
-                        if (e.getScope() == Volume.class || e.getScope() == Nic.class) {
-                            throw e;
-                        } else {
-                            s_logger.warn("unexpected ResourceUnavailableException : " + e.getScope().getName(), e);
-                            throw e;
-                        }
-                    }
-                } catch (final InsufficientCapacityException e) {
-                    s_logger.info("Insufficient capacity ", e);
-                    if (!avoids.add(e)) {
-                        if (e.getScope() == Volume.class || e.getScope() == Nic.class) {
-                            throw e;
-                        } else {
-                            s_logger.warn("unexpected InsufficientCapacityException : " + e.getScope().getName(), e);
-                        }
-                    }
-                } catch (final ExecutionException e) {
-                    s_logger.error("Failed to start instance " + vm, e);
-                    throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e);
-                } catch (final NoTransitionException e) {
-                    s_logger.error("Failed to start instance " + vm, e);
-                    throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e);
-                } finally {
-                    if (startedVm == null && canRetry) {
-                        final Step prevStep = work.getStep();
-                        _workDao.updateStep(work, Step.Release);
-                        // If previous step was started/ing && we got a valid answer
-                        if ((prevStep == Step.Started || prevStep == Step.Starting) && startAnswer != null && startAnswer.getResult()) {  //TODO check the response of cleanup and record it in DB for retry
-                            cleanup(vmGuru, vmProfile, work, Event.OperationFailed, false);
-                        } else {
-                            //if step is not starting/started, send cleanup command with force=true
-                            cleanup(vmGuru, vmProfile, work, Event.OperationFailed, true);
-                        }
-                    }
-                }
-            }
-        } finally {
-            if (startedVm == null) {
-                if (canRetry) {
-                    try {
-                        changeState(vm, Event.OperationFailed, null, work, Step.Done);
-                    } catch (final NoTransitionException e) {
-                        throw new ConcurrentOperationException(e.getMessage());
-                    }
-                }
-            }
-
-            if (planToDeploy != null) {
-                planToDeploy.setAvoids(avoids);
-            }
-        }
-
-        if (startedVm == null) {
-            throw new CloudRuntimeException("Unable to start instance '" + vm.getHostName() + "' (" + vm.getUuid() + "), see management server log for details");
-        }
-    }
-
-    // for managed storage on KVM, need to make sure the path field of the volume in question is populated with the IQN
-    private void handlePath(final DiskTO[] disks, final HypervisorType hypervisorType) {
-        if (hypervisorType != HypervisorType.KVM) {
-            return;
-        }
-
-        if (disks != null) {
-            for (final DiskTO disk : disks) {
-                final Map<String, String> details = disk.getDetails();
-                final boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-
-                if (isManaged && disk.getPath() == null) {
-                    final Long volumeId = disk.getData().getId();
-                    final VolumeVO volume = _volsDao.findById(volumeId);
-
-                    disk.setPath(volume.get_iScsiName());
-
-                    if (disk.getData() instanceof VolumeObjectTO) {
-                        final VolumeObjectTO volTo = (VolumeObjectTO)disk.getData();
-
-                        volTo.setPath(volume.get_iScsiName());
-                    }
-
-                    volume.setPath(volume.get_iScsiName());
-
-                    _volsDao.update(volumeId, volume);
-                }
-            }
-        }
-    }
-
-    // for managed storage on XenServer and VMware, need to update the DB with a path if the VDI/VMDK file was newly created
-    private void handlePath(final DiskTO[] disks, final Map<String, Map<String, String>> iqnToData) {
-        if (disks != null && iqnToData != null) {
-            for (final DiskTO disk : disks) {
-                final Map<String, String> details = disk.getDetails();
-                final boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-
-                if (isManaged) {
-                    final Long volumeId = disk.getData().getId();
-                    final VolumeVO volume = _volsDao.findById(volumeId);
-                    final String iScsiName = volume.get_iScsiName();
-
-                    boolean update = false;
-
-                    final Map<String, String> data = iqnToData.get(iScsiName);
-
-                    if (data != null) {
-                        final String path = data.get(StartAnswer.PATH);
-
-                        if (path != null) {
-                            volume.setPath(path);
-
-                            update = true;
-                        }
-
-                        final String imageFormat = data.get(StartAnswer.IMAGE_FORMAT);
-
-                        if (imageFormat != null) {
-                            volume.setFormat(ImageFormat.valueOf(imageFormat));
-
-                            update = true;
-                        }
-
-                        if (update) {
-                            _volsDao.update(volumeId, volume);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void syncDiskChainChange(final StartAnswer answer) {
-        final VirtualMachineTO vmSpec = answer.getVirtualMachine();
-
-        for (final DiskTO disk : vmSpec.getDisks()) {
-            if (disk.getType() != Volume.Type.ISO) {
-                final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
-                final VolumeVO volume = _volsDao.findById(vol.getId());
-
-                // Use getPath() from VolumeVO to get a fresh copy of what's in the DB.
-                // Before doing this, in a certain situation, getPath() from VolumeObjectTO
-                // returned null instead of an actual path (because it was out of date with the DB).
-                if(vol.getPath() != null) {
-                    volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo());
-                } else {
-                    volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo());
-                }
-            }
-        }
-    }
-
-    @Override
-    public void stop(final String vmUuid) throws ResourceUnavailableException {
-        try {
-            advanceStop(vmUuid, false);
-        } catch (final OperationTimedoutException e) {
-            throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", e.getAgentId(), e);
-        } catch (final ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e);
-        }
-
-    }
-
-    @Override
-    public void stopForced(String vmUuid) throws ResourceUnavailableException {
-        try {
-            advanceStop(vmUuid, true);
-        } catch (final OperationTimedoutException e) {
-            throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", e.getAgentId(), e);
-        } catch (final ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e);
-        }
-    }
-
-    @Override
-    public boolean getExecuteInSequence(final HypervisorType hypervisorType) {
-        if (HypervisorType.KVM == hypervisorType || HypervisorType.XenServer == hypervisorType || HypervisorType.Hyperv == hypervisorType || HypervisorType.LXC == hypervisorType) {
-            return false;
-        } else if (HypervisorType.VMware == hypervisorType) {
-            final Boolean fullClone = HypervisorGuru.VmwareFullClone.value();
-            return fullClone;
-        } else {
-            return ExecuteInSequence.value();
-        }
-    }
-
-    private List<Map<String, String>> getVolumesToDisconnect(VirtualMachine vm) {
-        List<Map<String, String>> volumesToDisconnect = new ArrayList<>();
-
-        List<VolumeVO> volumes = _volsDao.findByInstance(vm.getId());
-
-        if (CollectionUtils.isEmpty(volumes)) {
-            return volumesToDisconnect;
-        }
-
-        for (VolumeVO volume : volumes) {
-            StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
-
-            if (storagePool != null && storagePool.isManaged()) {
-                Map<String, String> info = new HashMap<>(3);
-
-                info.put(DiskTO.STORAGE_HOST, storagePool.getHostAddress());
-                info.put(DiskTO.STORAGE_PORT, String.valueOf(storagePool.getPort()));
-                info.put(DiskTO.IQN, volume.get_iScsiName());
-
-                volumesToDisconnect.add(info);
-            }
-        }
-
-        return volumesToDisconnect;
-    }
-
-    protected boolean sendStop(final VirtualMachineGuru guru, final VirtualMachineProfile profile, final boolean force, final boolean checkBeforeCleanup) {
-        final VirtualMachine vm = profile.getVirtualMachine();
-        StopCommand stpCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), checkBeforeCleanup);
-        stpCmd.setControlIp(getControlNicIpForVM(vm));
-        stpCmd.setVolumesToDisconnect(getVolumesToDisconnect(vm));
-        final StopCommand stop = stpCmd;
-        try {
-            Answer answer = null;
-            if(vm.getHostId() != null) {
-                answer = _agentMgr.send(vm.getHostId(), stop);
-            }
-            if (answer != null && answer instanceof StopAnswer) {
-                final StopAnswer stopAns = (StopAnswer)answer;
-                if (vm.getType() == VirtualMachine.Type.User) {
-                    final String platform = stopAns.getPlatform();
-                    if (platform != null) {
-                        final UserVmVO userVm = _userVmDao.findById(vm.getId());
-                        _userVmDao.loadDetails(userVm);
-                        userVm.setDetail("platform", platform);
-                        _userVmDao.saveDetails(userVm);
-                    }
-                }
-
-                final GPUDeviceTO gpuDevice = stop.getGpuDevice();
-                if (gpuDevice != null) {
-                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
-                }
-                if (!answer.getResult()) {
-                    final String details = answer.getDetails();
-                    s_logger.debug("Unable to stop VM due to " + details);
-                    return false;
-                }
-
-                guru.finalizeStop(profile, answer);
-            } else {
-                s_logger.error("Invalid answer received in response to a StopCommand for " + vm.getInstanceName());
-                return false;
-            }
-
-        } catch (final AgentUnavailableException e) {
-            if (!force) {
-                return false;
-            }
-        } catch (final OperationTimedoutException e) {
-            if (!force) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    protected boolean cleanup(final VirtualMachineGuru guru, final VirtualMachineProfile profile, final ItWorkVO work, final Event event, final boolean cleanUpEvenIfUnableToStop) {
-        final VirtualMachine vm = profile.getVirtualMachine();
-        final State state = vm.getState();
-        s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state");
-        try {
-            if (state == State.Starting) {
-                if (work != null) {
-                    final Step step = work.getStep();
-                    if (step == Step.Starting && !cleanUpEvenIfUnableToStop) {
-                        s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step);
-                        return false;
-                    }
-
-                    if (step == Step.Started || step == Step.Starting || step == Step.Release) {
-                        if (vm.getHostId() != null) {
-                            if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                                s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
-                                return false;
-                            }
-                        }
-                    }
-
-                    if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) {
-                        s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step);
-                        return true;
-                    }
-                } else {
-                    if (vm.getHostId() != null) {
-                        if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                            s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
-                            return false;
-                        }
-                    }
-                }
-
-            } else if (state == State.Stopping) {
-                if (vm.getHostId() != null) {
-                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process");
-                        return false;
-                    }
-                }
-            } else if (state == State.Migrating) {
-                if (vm.getHostId() != null) {
-                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process");
-                        return false;
-                    }
-                }
-                if (vm.getLastHostId() != null) {
-                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process");
-                        return false;
-                    }
-                }
-            } else if (state == State.Running) {
-                if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
-                    s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process");
-                    return false;
-                }
-            }
-        } finally {
-            try {
-                _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
-                s_logger.debug("Successfully released network resources for the vm " + vm);
-            } catch (final Exception e) {
-                s_logger.warn("Unable to release some network resources.", e);
-            }
-
-            volumeMgr.release(profile);
-            s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state");
-        }
-
-        return true;
-    }
-
-    @Override
-    public void advanceStop(final String vmUuid, final boolean cleanUpEvenIfUnableToStop)
-            throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateStop(vmUuid, cleanUpEvenIfUnableToStop);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-
-        } else {
-            final Outcome<VirtualMachine> outcome = stopVmThroughJobQueue(vmUuid, cleanUpEvenIfUnableToStop);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof AgentUnavailableException) {
-                    throw (AgentUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof OperationTimedoutException) {
-                    throw (OperationTimedoutException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-            }
-        }
-    }
-
-    private void orchestrateStop(final String vmUuid, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        advanceStop(vm, cleanUpEvenIfUnableToStop);
-    }
-
-    private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException,
-    ConcurrentOperationException {
-        final State state = vm.getState();
-        if (state == State.Stopped) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is already stopped: " + vm);
-            }
-            return;
-        }
-
-        if (state == State.Destroyed || state == State.Expunging || state == State.Error) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Stopped called on " + vm + " but the state is " + state);
-            }
-            return;
-        }
-        // grab outstanding work item if any
-        final ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState());
-        if (work != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId());
-            }
-        }
-        final Long hostId = vm.getHostId();
-        if (hostId == null) {
-            if (!cleanUpEvenIfUnableToStop) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState());
-                }
-                throw new CloudRuntimeException("Unable to stop " + vm);
-            }
-            try {
-                stateTransitTo(vm, Event.AgentReportStopped, null, null);
-            } catch (final NoTransitionException e) {
-                s_logger.warn(e.getMessage());
-            }
-            // mark outstanding work item if any as done
-            if (work != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Updating work item to Done, id:" + work.getId());
-                }
-                work.setStep(Step.Done);
-                _workDao.update(work.getId(), work);
-            }
-            return;
-        } else {
-            HostVO host = _hostDao.findById(hostId);
-            if (!cleanUpEvenIfUnableToStop && vm.getState() == State.Running && host.getResourceState() == ResourceState.PrepareForMaintenance) {
-                s_logger.debug("Host is in PrepareForMaintenance state - Stop VM operation on the VM id: " + vm.getId() + " is not allowed");
-                throw new CloudRuntimeException("Stop VM operation on the VM id: " + vm.getId() + " is not allowed as host is preparing for maintenance mode");
-            }
-        }
-
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-
-        try {
-            if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) {
-                throw new ConcurrentOperationException("VM is being operated on.");
-            }
-        } catch (final NoTransitionException e1) {
-            if (!cleanUpEvenIfUnableToStop) {
-                throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState());
-            }
-            final boolean doCleanup = true;
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to transition the state but we're moving on because it's forced stop");
-            }
-
-            if (doCleanup) {
-                if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {
-                    try {
-                        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);
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Failed to cleanup VM: " + vm);
-                    }
-                    throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState());
-                }
-            }
-        }
-
-        if (vm.getState() != State.Stopping) {
-            throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState());
-        }
-
-        vmGuru.prepareStop(profile);
-
-        final StopCommand stop = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false, cleanUpEvenIfUnableToStop);
-        stop.setControlIp(getControlNicIpForVM(vm));
-
-        boolean stopped = false;
-        Answer answer = null;
-        try {
-            answer = _agentMgr.send(vm.getHostId(), stop);
-            if (answer != null) {
-                if (answer instanceof StopAnswer) {
-                    final StopAnswer stopAns = (StopAnswer)answer;
-                    if (vm.getType() == VirtualMachine.Type.User) {
-                        final String platform = stopAns.getPlatform();
-                        if (platform != null) {
-                            final UserVmVO userVm = _userVmDao.findById(vm.getId());
-                            _userVmDao.loadDetails(userVm);
-                            userVm.setDetail("platform", platform);
-                            _userVmDao.saveDetails(userVm);
-                        }
-                    }
-                }
-                stopped = answer.getResult();
-                if (!stopped) {
-                    throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
-                }
-                vmGuru.finalizeStop(profile, answer);
-                final GPUDeviceTO gpuDevice = stop.getGpuDevice();
-                if (gpuDevice != null) {
-                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
-                }
-            } else {
-                throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName);
-            }
-
-        } catch (final AgentUnavailableException e) {
-            s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString());
-        } catch (final OperationTimedoutException e) {
-            s_logger.warn("Unable to stop vm, operation timed out: " + e.toString());
-        } finally {
-            if (!stopped) {
-                if (!cleanUpEvenIfUnableToStop) {
-                    s_logger.warn("Unable to stop vm " + vm);
-                    try {
-                        stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
-                    } catch (final NoTransitionException e) {
-                        s_logger.warn("Unable to transition the state " + vm);
-                    }
-                    throw new CloudRuntimeException("Unable to stop " + vm);
-                } else {
-                    s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop");
-                    vmGuru.finalizeStop(profile, answer);
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(vm + " is stopped on the host.  Proceeding to release resource held.");
-        }
-
-        try {
-            _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
-            s_logger.debug("Successfully released network resources for the vm " + vm);
-        } catch (final Exception e) {
-            s_logger.warn("Unable to release some network resources.", e);
-        }
-
-        try {
-            if (vm.getHypervisorType() != HypervisorType.BareMetal) {
-                volumeMgr.release(profile);
-                s_logger.debug("Successfully released storage resources for the vm " + vm);
-            }
-        } catch (final Exception e) {
-            s_logger.warn("Unable to release storage resources.", e);
-        }
-
-        try {
-            if (work != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId());
-                }
-                work.setStep(Step.Done);
-                _workDao.update(work.getId(), work);
-            }
-
-            if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
-                throw new CloudRuntimeException("unable to stop " + vm);
-            }
-        } catch (final NoTransitionException e) {
-            s_logger.warn(e.getMessage());
-            throw new CloudRuntimeException("Unable to stop " + vm);
-        }
-    }
-
-    private void setStateMachine() {
-        _stateMachine = VirtualMachine.State.getStateMachine();
-    }
-
-    protected boolean stateTransitTo(final VMInstanceVO vm, final VirtualMachine.Event e, final Long hostId, final String reservationId) throws NoTransitionException {
-        // if there are active vm snapshots task, state change is not allowed
-
-        // Disable this hacking thing, VM snapshot task need to be managed by its orchestartion flow istelf instead of
-        // hacking it here at general VM manager
-        /*
-                if (_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())) {
-                    s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
-                    return false;
-                }
-         */
-        vm.setReservationId(reservationId);
-        return _stateMachine.transitTo(vm, e, new Pair<Long, Long>(vm.getHostId(), hostId), _vmDao);
-    }
-
-    @Override
-    public boolean stateTransitTo(final VirtualMachine vm1, final VirtualMachine.Event e, final Long hostId) throws NoTransitionException {
-        final VMInstanceVO vm = (VMInstanceVO)vm1;
-
-        /*
-         *  Remove the hacking logic here.
-                // if there are active vm snapshots task, state change is not allowed
-                if (_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())) {
-                    s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
-                    return false;
-                }
-         */
-
-        final State oldState = vm.getState();
-        if (oldState == State.Starting) {
-            if (e == Event.OperationSucceeded) {
-                vm.setLastHostId(hostId);
-            }
-        } else if (oldState == State.Stopping) {
-            if (e == Event.OperationSucceeded) {
-                vm.setLastHostId(vm.getHostId());
-            }
-        }
-        return _stateMachine.transitTo(vm, e, new Pair<Long, Long>(vm.getHostId(), hostId), _vmDao);
-    }
-
-    @Override
-    public void destroy(final String vmUuid, final boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
-            }
-            return;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Destroying vm " + vm + ", expunge flag " + (expunge ? "on" : "off"));
-        }
-
-        advanceStop(vmUuid, VmDestroyForcestop.value());
-
-        deleteVMSnapshots(vm, expunge);
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<CloudRuntimeException>() {
-            public void doInTransactionWithoutResult(final TransactionStatus status) throws CloudRuntimeException {
-                VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-                try {
-                    if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) {
-                        s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
-                        throw new CloudRuntimeException("Unable to destroy " + vm);
-                    } else {
-                        if (expunge) {
-                            if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) {
-                                s_logger.debug("Unable to expunge the vm because it is not in the correct state: " + vm);
-                                throw new CloudRuntimeException("Unable to expunge " + vm);
-                            }
-                        }
-                    }
-                } catch (final NoTransitionException e) {
-                    s_logger.debug(e.getMessage());
-                    throw new CloudRuntimeException("Unable to destroy " + vm, e);
-                }
-            }
-        });
-    }
-
-    /**
-     * Delete vm snapshots depending on vm's hypervisor type. For Vmware, vm snapshots removal is delegated to vm cleanup thread
-     * to reduce tasks sent to hypervisor (one tasks to delete vm snapshots and vm itself
-     * instead of one task for each vm snapshot plus another for the vm)
-     * @param vm vm
-     * @param expunge indicates if vm should be expunged
-     */
-    private void deleteVMSnapshots(VMInstanceVO vm, boolean expunge) {
-        if (! vm.getHypervisorType().equals(HypervisorType.VMware)) {
-            if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(), null)) {
-                s_logger.debug("Unable to delete all snapshots for " + vm);
-                throw new CloudRuntimeException("Unable to delete vm snapshots for " + vm);
-            }
-        }
-        else {
-            if (expunge) {
-                _vmSnapshotMgr.deleteVMSnapshotsFromDB(vm.getId());
-            }
-        }
-    }
-
-    protected boolean checkVmOnHost(final VirtualMachine vm, final long hostId) throws AgentUnavailableException, OperationTimedoutException {
-        final Answer answer = _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName()));
-        if (answer == null || !answer.getResult()) {
-            return false;
-        }
-        if (answer instanceof CheckVirtualMachineAnswer) {
-            final CheckVirtualMachineAnswer vmAnswer = (CheckVirtualMachineAnswer)answer;
-            if (vmAnswer.getState() == PowerState.PowerOff) {
-                return false;
-            }
-        }
-
-        UserVmVO userVm = _userVmDao.findById(vm.getId());
-        if (userVm != null) {
-            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vm.getId());
-            RestoreVMSnapshotCommand command = _vmSnapshotMgr.createRestoreCommand(userVm, vmSnapshots);
-            if (command != null) {
-                RestoreVMSnapshotAnswer restoreVMSnapshotAnswer = (RestoreVMSnapshotAnswer) _agentMgr.send(hostId, command);
-                if (restoreVMSnapshotAnswer == null || !restoreVMSnapshotAnswer.getResult()) {
-                    s_logger.warn("Unable to restore the vm snapshot from image file after live migration of vm with vmsnapshots: " + restoreVMSnapshotAnswer.getDetails());
-                }
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public void storageMigration(final String vmUuid, final StoragePool destPool) {
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateStorageMigration(vmUuid, destPool);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = migrateVmStorageThroughJobQueue(vmUuid, destPool);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-            }
-        }
-    }
-
-    private void orchestrateStorageMigration(final String vmUuid, final StoragePool destPool) {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        if (destPool == null) {
-            throw new CloudRuntimeException("Unable to migrate vm: missing destination storage pool");
-        }
-
-        try {
-            stateTransitTo(vm, VirtualMachine.Event.StorageMigrationRequested, null);
-        } catch (final NoTransitionException e) {
-            s_logger.debug("Unable to migrate vm: " + e.toString());
-            throw new CloudRuntimeException("Unable to migrate vm: " + e.toString());
-        }
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        boolean migrationResult = false;
-        try {
-            migrationResult = volumeMgr.storageMigration(profile, destPool);
-
-            if (migrationResult) {
-                //if the vm is migrated to different pod in basic mode, need to reallocate ip
-
-                if (destPool.getPodId() != null && !destPool.getPodId().equals(vm.getPodIdToDeployIn())) {
-                    final DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), destPool.getPodId(), null, null, null, null);
-                    final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, null, null, null, null);
-                    _networkMgr.reallocate(vmProfile, plan);
-                }
-
-                //when start the vm next time, don;'t look at last_host_id, only choose the host based on volume/storage pool
-                vm.setLastHostId(null);
-                vm.setPodIdToDeployIn(destPool.getPodId());
-
-                // If VM was cold migrated between clusters belonging to two different VMware DCs,
-                // unregister the VM from the source host and cleanup the associated VM files.
-                if (vm.getHypervisorType().equals(HypervisorType.VMware)) {
-                    Long srcClusterId = null;
-                    Long srcHostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
-                    if (srcHostId != null) {
-                        HostVO srcHost = _hostDao.findById(srcHostId);
-                        srcClusterId = srcHost.getClusterId();
-                    }
-
-                    final Long destClusterId = destPool.getClusterId();
-                    if (srcClusterId != null && destClusterId != null && ! srcClusterId.equals(destClusterId)) {
-                        final String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
-                        final String destDcName = _clusterDetailsDao.getVmwareDcName(destClusterId);
-                        if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
-                            s_logger.debug("Since VM's storage was successfully migrated across VMware Datacenters, unregistering VM: " + vm.getInstanceName() +
-                                    " from source host: " + srcHostId);
-                            final UnregisterVMCommand uvc = new UnregisterVMCommand(vm.getInstanceName());
-                            uvc.setCleanupVmFiles(true);
-                            try {
-                                _agentMgr.send(srcHostId, uvc);
-                            } catch (final AgentUnavailableException | OperationTimedoutException e) {
-                                throw new CloudRuntimeException("Failed to unregister VM: " + vm.getInstanceName() + " from source host: " + srcHostId +
-                                        " after successfully migrating VM's storage across VMware Datacenters");
-                            }
-                        }
-                    }
-                }
-
-            } else {
-                s_logger.debug("Storage migration failed");
-            }
-        } catch (final ConcurrentOperationException e) {
-            s_logger.debug("Failed to migration: " + e.toString());
-            throw new CloudRuntimeException("Failed to migration: " + e.toString());
-        } catch (final InsufficientVirtualNetworkCapacityException e) {
-            s_logger.debug("Failed to migration: " + e.toString());
-            throw new CloudRuntimeException("Failed to migration: " + e.toString());
-        } catch (final InsufficientAddressCapacityException e) {
-            s_logger.debug("Failed to migration: " + e.toString());
-            throw new CloudRuntimeException("Failed to migration: " + e.toString());
-        } catch (final InsufficientCapacityException e) {
-            s_logger.debug("Failed to migration: " + e.toString());
-            throw new CloudRuntimeException("Failed to migration: " + e.toString());
-        } catch (final StorageUnavailableException e) {
-            s_logger.debug("Failed to migration: " + e.toString());
-            throw new CloudRuntimeException("Failed to migration: " + e.toString());
-        } finally {
-            try {
-                stateTransitTo(vm, VirtualMachine.Event.AgentReportStopped, null);
-            } catch (final NoTransitionException e) {
-                s_logger.debug("Failed to change vm state: " + e.toString());
-                throw new CloudRuntimeException("Failed to change vm state: " + e.toString());
-            }
-        }
-    }
-
-    @Override
-    public void migrate(final String vmUuid, final long srcHostId, final DeployDestination dest)
-            throws ResourceUnavailableException, ConcurrentOperationException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateMigrate(vmUuid, srcHostId, dest);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-
-            }
-        }
-    }
-
-    private void orchestrateMigrate(final String vmUuid, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        if (vm == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find the vm " + vmUuid);
-            }
-            throw new CloudRuntimeException("Unable to find a virtual machine with id " + vmUuid);
-        }
-        migrate(vm, srcHostId, dest);
-    }
-
-    protected void migrate(final VMInstanceVO vm, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException {
-        s_logger.info("Migrating " + vm + " to " + dest);
-
-        final long dstHostId = dest.getHost().getId();
-        final Host fromHost = _hostDao.findById(srcHostId);
-        if (fromHost == null) {
-            s_logger.info("Unable to find the host to migrate from: " + srcHostId);
-            throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
-        }
-
-        if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
-            final List<VolumeVO> volumes = _volsDao.findCreatedByInstance(vm.getId());
-            for (final VolumeVO volume : volumes) {
-                if (!_storagePoolDao.findById(volume.getPoolId()).getScope().equals(ScopeType.ZONE)) {
-                    s_logger.info("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: "
-                            + dest.getHost().getId());
-                    throw new CloudRuntimeException(
-                            "Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: "
-                                    + dest.getHost().getId());
-                }
-            }
-        }
-
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-
-        if (vm.getState() != State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
-            }
-            throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
-        }
-
-        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
-        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
-        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
-        }
-
-        final VirtualMachineProfile vmSrc = new VirtualMachineProfileImpl(vm);
-        for (final NicProfile nic : _networkMgr.getNicProfiles(vm)) {
-            vmSrc.addNic(nic);
-        }
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null);
-        _networkMgr.prepareNicForMigration(profile, dest);
-        volumeMgr.prepareForMigration(profile, dest);
-        profile.setConfigDriveLabel(VmConfigDriveLabel.value());
-
-        final VirtualMachineTO to = toVmTO(profile);
-        final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
-
-        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
-        work.setStep(Step.Prepare);
-        work.setResourceType(ItWorkVO.ResourceType.Host);
-        work.setResourceId(dstHostId);
-        work = _workDao.persist(work);
-
-        Answer pfma = null;
-        try {
-            pfma = _agentMgr.send(dstHostId, pfmc);
-            if (pfma == null || !pfma.getResult()) {
-                final String details = pfma != null ? pfma.getDetails() : "null answer returned";
-                final String msg = "Unable to prepare for migration due to " + details;
-                pfma = null;
-                throw new AgentUnavailableException(msg, dstHostId);
-            }
-        } catch (final OperationTimedoutException e1) {
-            throw new AgentUnavailableException("Operation timed out", dstHostId);
-        } finally {
-            if (pfma == null) {
-                _networkMgr.rollbackNicForMigration(vmSrc, profile);
-                work.setStep(Step.Done);
-                _workDao.update(work.getId(), work);
-            }
-        }
-
-        vm.setLastHostId(srcHostId);
-        try {
-            if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
-                _networkMgr.rollbackNicForMigration(vmSrc, profile);
-                s_logger.info("Migration cancelled because state has changed: " + vm);
-                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
-            }
-        } catch (final NoTransitionException e1) {
-            _networkMgr.rollbackNicForMigration(vmSrc, profile);
-            s_logger.info("Migration cancelled because " + e1.getMessage());
-            throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
-        }
-
-        boolean migrated = false;
-        try {
-            final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-            final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
-
-            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
-            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
-
-            mc.setAutoConvergence(kvmAutoConvergence);
-
-            mc.setHostGuid(dest.getHost().getGuid());
-
-            try {
-                final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
-                if (ma == null || !ma.getResult()) {
-                    final String details = ma != null ? ma.getDetails() : "null answer returned";
-                    throw new CloudRuntimeException(details);
-                }
-            } catch (final OperationTimedoutException e) {
-                if (e.isActive()) {
-                    s_logger.warn("Active migration command so scheduling a restart for " + vm);
-                    _haMgr.scheduleRestart(vm, true);
-                }
-                throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
-            }
-
-            try {
-                if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
-                    throw new ConcurrentOperationException("Unable to change the state for " + vm);
-                }
-            } catch (final NoTransitionException e1) {
-                throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
-            }
-
-            try {
-                if (!checkVmOnHost(vm, dstHostId)) {
-                    s_logger.error("Unable to complete migration for " + vm);
-                    try {
-                        _agentMgr.send(srcHostId, new Commands(cleanup(vm)), null);
-                    } catch (final AgentUnavailableException e) {
-                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
-                    }
-                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
-                    throw new CloudRuntimeException("Unable to complete migration for " + vm);
-                }
-            } catch (final OperationTimedoutException e) {
-                s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
-            }
-
-            migrated = true;
-        } finally {
-            if (!migrated) {
-                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
-                _networkMgr.rollbackNicForMigration(vmSrc, profile);
-
-                _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(),
-                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " +
-                                dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
-                try {
-                    _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null);
-                } catch (final AgentUnavailableException ae) {
-                    s_logger.info("Looks like the destination Host is unavailable for cleanup");
-                }
-
-                try {
-                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
-                } catch (final NoTransitionException e) {
-                    s_logger.warn(e.getMessage());
-                }
-            } else {
-                _networkMgr.commitNicForMigration(vmSrc, profile);
-            }
-
-            work.setStep(Step.Done);
-            _workDao.update(work.getId(), work);
-        }
-    }
-
-    private Map<Volume, StoragePool> getPoolListForVolumesForMigration(final VirtualMachineProfile profile, final Host host, final Map<Long, Long> volumeToPool) {
-        final List<VolumeVO> allVolumes = _volsDao.findUsableVolumesForInstance(profile.getId());
-        final Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
-
-        for (final VolumeVO volume : allVolumes) {
-            final Long poolId = volumeToPool.get(volume.getId());
-            final StoragePoolVO destPool = _storagePoolDao.findById(poolId);
-            final StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId());
-            final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-
-            if (destPool != null) {
-                if (currentPool.isManaged()) {
-                    if (destPool.getId() == currentPool.getId()) {
-                        volumeToPoolObjectMap.put(volume, currentPool);
-                    }
-                    else {
-                        throw new CloudRuntimeException("Currently, a volume on managed storage can only be 'migrated' to itself.");
-                    }
-                }
-                else {
-                    // Check if pool is accessible from the destination host and disk offering with which the volume was
-                    // created is compliant with the pool type.
-                    if (_poolHostDao.findByPoolHost(destPool.getId(), host.getId()) == null || destPool.isLocal() != diskOffering.getUseLocalStorage()) {
-                        // Cannot find a pool for the volume. Throw an exception.
-                        throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + destPool + " while migrating vm to host " + host +
-                                ". Either the pool is not accessible from the host or because of the offering with which the volume is created it cannot be placed on " +
-                                "the given pool.");
-                    } else if (destPool.getId() == currentPool.getId()) {
-                        // If the pool to migrate to is the same as current pool, the volume doesn't need to be migrated.
-                    } else {
-                        volumeToPoolObjectMap.put(volume, destPool);
-                    }
-                }
-            } else {
-                if (currentPool.isManaged()) {
-                    if (currentPool.getScope() == ScopeType.ZONE) {
-                        volumeToPoolObjectMap.put(volume, currentPool);
-                    }
-                    else {
-                        throw new CloudRuntimeException("Currently, you can only 'migrate' a volume on managed storage if its storage pool is zone wide.");
-                    }
-                } else {
-                    // Find a suitable pool for the volume. Call the storage pool allocator to find the list of pools.
-
-                    final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, profile.getHypervisorType());
-                    final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(),
-                            host.getId(), null, null);
-
-                    final List<StoragePool> poolList = new ArrayList<>();
-                    final ExcludeList avoid = new ExcludeList();
-
-                    for (final StoragePoolAllocator allocator : _storagePoolAllocators) {
-                        final List<StoragePool> poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
-
-                        if (poolListFromAllocator != null && !poolListFromAllocator.isEmpty()) {
-                            poolList.addAll(poolListFromAllocator);
-                        }
-                    }
-
-                    boolean currentPoolAvailable = false;
-
-                    if (poolList != null && !poolList.isEmpty()) {
-                        // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the
-                        // volume to a pool only if it is required; that is the current pool on which the volume resides
-                        // is not available on the destination host.
-
-                        final Iterator<StoragePool> iter = poolList.iterator();
-
-                        while (iter.hasNext()) {
-                            if (currentPool.getId() == iter.next().getId()) {
-                                currentPoolAvailable = true;
-
-                                break;
-                            }
-                        }
-
-                        if (!currentPoolAvailable) {
-                            volumeToPoolObjectMap.put(volume, _storagePoolDao.findByUuid(poolList.get(0).getUuid()));
-                        }
-                    }
-
-                    if (!currentPoolAvailable && !volumeToPoolObjectMap.containsKey(volume)) {
-                        // Cannot find a pool for the volume. Throw an exception.
-                        throw new CloudRuntimeException("Cannot find a storage pool which is available for volume " + volume + " while migrating virtual machine " +
-                                profile.getVirtualMachine() + " to host " + host);
-                    }
-                }
-            }
-        }
-
-        return volumeToPoolObjectMap;
-    }
-
-    private <T extends VMInstanceVO> void moveVmToMigratingState(final T vm, final Long hostId, final ItWorkVO work) throws ConcurrentOperationException {
-        // Put the vm in migrating state.
-        try {
-            if (!changeState(vm, Event.MigrationRequested, hostId, work, Step.Migrating)) {
-                s_logger.info("Migration cancelled because state has changed: " + vm);
-                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
-            }
-        } catch (final NoTransitionException e) {
-            s_logger.info("Migration cancelled because " + e.getMessage());
-            throw new ConcurrentOperationException("Migration cancelled because " + e.getMessage());
-        }
-    }
-
-    private <T extends VMInstanceVO> void moveVmOutofMigratingStateOnSuccess(final T vm, final Long hostId, final ItWorkVO work) throws ConcurrentOperationException {
-        // Put the vm in running state.
-        try {
-            if (!changeState(vm, Event.OperationSucceeded, hostId, work, Step.Started)) {
-                s_logger.error("Unable to change the state for " + vm);
-                throw new ConcurrentOperationException("Unable to change the state for " + vm);
-            }
-        } catch (final NoTransitionException e) {
-            s_logger.error("Unable to change state due to " + e.getMessage());
-            throw new ConcurrentOperationException("Unable to change state due to " + e.getMessage());
-        }
-    }
-
-    @Override
-    public void migrateWithStorage(final String vmUuid, final long srcHostId, final long destHostId, final Map<Long, Long> volumeToPool)
-            throws ResourceUnavailableException, ConcurrentOperationException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-
-        } else {
-            final Outcome<VirtualMachine> outcome = migrateVmWithStorageThroughJobQueue(vmUuid, srcHostId, destHostId, volumeToPool);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobException != null) {
-                if (jobException instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobException;
-                } else if (jobException instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobException;
-                } else if (jobException instanceof RuntimeException) {
-                    throw (RuntimeException)jobException;
-                } else if (jobException instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
-                }
-            }
-        }
-    }
-
-    private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHostId, final long destHostId, final Map<Long, Long> volumeToPool) throws ResourceUnavailableException,
-    ConcurrentOperationException {
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final HostVO srcHost = _hostDao.findById(srcHostId);
-        final HostVO destHost = _hostDao.findById(destHostId);
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-
-        final DataCenterVO dc = _dcDao.findById(destHost.getDataCenterId());
-        final HostPodVO pod = _podDao.findById(destHost.getPodId());
-        final Cluster cluster = _clusterDao.findById(destHost.getClusterId());
-        final DeployDestination destination = new DeployDestination(dc, pod, cluster, destHost);
-
-        // Create a map of which volume should go in which storage pool.
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        final Map<Volume, StoragePool> volumeToPoolMap = getPoolListForVolumesForMigration(profile, destHost, volumeToPool);
-
-        // If none of the volumes have to be migrated, fail the call. Administrator needs to make a call for migrating
-        // a vm and not migrating a vm with storage.
-        if (volumeToPoolMap == null || volumeToPoolMap.isEmpty()) {
-            throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost +
-                    " doesn't involve migrating the volumes.");
-        }
-
-        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
-        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
-        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
-        }
-
-        _networkMgr.prepareNicForMigration(profile, destination);
-        volumeMgr.prepareForMigration(profile, destination);
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
-        final VirtualMachineTO to = hvGuru.implement(profile);
-
-        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
-        work.setStep(Step.Prepare);
-        work.setResourceType(ItWorkVO.ResourceType.Host);
-        work.setResourceId(destHostId);
-        work = _workDao.persist(work);
-
-
-        // Put the vm in migrating state.
-        vm.setLastHostId(srcHostId);
-        vm.setPodIdToDeployIn(destHost.getPodId());
-        moveVmToMigratingState(vm, destHostId, work);
-
-        boolean migrated = false;
-        try {
-
-            // config drive: Detach the config drive at source host
-            // After migration successful attach the config drive in destination host
-            // On migration failure VM will be stopped, So configIso will be deleted
-
-            Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
-
-            List<String[]> vmData = null;
-            if (defaultNic != null) {
-                UserVmVO userVm = _userVmDao.findById(vm.getId());
-                Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
-                userVm.setDetails(details);
-
-                Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
-                if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                    final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
-                    boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-
-                    vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
-                            vm.getUuid(), defaultNic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
-                    String vmName = vm.getInstanceName();
-                    String configDriveIsoRootFolder = "/tmp";
-                    String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
-                    profile.setVmData(vmData);
-                    profile.setConfigDriveLabel(VmConfigDriveLabel.value());
-                    profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder);
-                    profile.setConfigDriveIsoFile(isoFile);
-
-                    // At source host detach the config drive iso.
-                    AttachOrDettachConfigDriveCommand dettachCommand = new AttachOrDettachConfigDriveCommand(vm.getInstanceName(), vmData, VmConfigDriveLabel.value(), false);
-                    try {
-                        _agentMgr.send(srcHost.getId(), dettachCommand);
-                        s_logger.debug("Deleted config drive ISO for  vm " + vm.getInstanceName() + " In host " + srcHost);
-                    } catch (OperationTimedoutException e) {
-                        s_logger.debug("TIme out occured while exeuting command AttachOrDettachConfigDrive " + e.getMessage());
-
-                    }
-
-                }
-            }
-
-            // Migrate the vm and its volume.
-            volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap);
-
-            // Put the vm back to running state.
-            moveVmOutofMigratingStateOnSuccess(vm, destHost.getId(), work);
-
-            try {
-                if (!checkVmOnHost(vm, destHostId)) {
-                    s_logger.error("Vm not found on destination host. Unable to complete migration for " + vm);
-                    try {
-                        _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
-                    } catch (final AgentUnavailableException e) {
-                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
-                    }
-                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
-                    throw new CloudRuntimeException("VM not found on desintation host. Unable to complete migration for " + vm);
-                }
-            } catch (final OperationTimedoutException e) {
-                s_logger.warn("Error while checking the vm " + vm + " is on host " + destHost, e);
-            }
-
-            migrated = true;
-        } finally {
-            if (!migrated) {
-                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
-                _alertMgr.sendAlert(alertType, srcHost.getDataCenterId(), srcHost.getPodId(),
-                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + srcHost.getName() + " in zone " + dc.getName() + " and pod " + dc.getName(),
-                        "Migrate Command failed.  Please check logs.");
-                try {
-                    _agentMgr.send(destHostId, new Commands(cleanup(vm.getInstanceName())), null);
-                    vm.setPodIdToDeployIn(srcHost.getPodId());
-                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
-                } catch (final AgentUnavailableException e) {
-                    s_logger.warn("Looks like the destination Host is unavailable for cleanup.", e);
-                } catch (final NoTransitionException e) {
-                    s_logger.error("Error while transitioning vm from migrating to running state.", e);
-                }
-            }
-
-            work.setStep(Step.Done);
-            _workDao.update(work.getId(), work);
-        }
-    }
-
-    @Override
-    public VirtualMachineTO toVmTO(final VirtualMachineProfile profile) {
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getVirtualMachine().getHypervisorType());
-        final VirtualMachineTO to = hvGuru.implement(profile);
-        return to;
-    }
-
-    protected void cancelWorkItems(final long nodeId) {
-        final GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem");
-
-        try {
-            if (scanLock.lock(3)) {
-                try {
-                    final List<ItWorkVO> works = _workDao.listWorkInProgressFor(nodeId);
-                    for (final ItWorkVO work : works) {
-                        s_logger.info("Handling unfinished work item: " + work);
-                        try {
-                            final VMInstanceVO vm = _vmDao.findById(work.getInstanceId());
-                            if (vm != null) {
-                                if (work.getType() == State.Starting) {
-                                    _haMgr.scheduleRestart(vm, true);
-                                    work.setManagementServerId(_nodeId);
-                                    work.setStep(Step.Done);
-                                    _workDao.update(work.getId(), work);
-                                } else if (work.getType() == State.Stopping) {
-                                    _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop);
-                                    work.setManagementServerId(_nodeId);
-                                    work.setStep(Step.Done);
-                                    _workDao.update(work.getId(), work);
-                                } else if (work.getType() == State.Migrating) {
-                                    _haMgr.scheduleMigration(vm);
-                                    work.setStep(Step.Done);
-                                    _workDao.update(work.getId(), work);
-                                }
-                            }
-                        } catch (final Exception e) {
-                            s_logger.error("Error while handling " + work, e);
-                        }
-                    }
-                } finally {
-                    scanLock.unlock();
-                }
-            }
-        } finally {
-            scanLock.releaseRef();
-        }
-    }
-
-    @Override
-    public void migrateAway(final String vmUuid, final long srcHostId) throws InsufficientServerCapacityException {
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                try {
-                    orchestrateMigrateAway(vmUuid, srcHostId, null);
-                } catch (final InsufficientServerCapacityException e) {
-                    s_logger.warn("Failed to deploy vm " + vmUuid + " with original planner, sending HAPlanner");
-                    orchestrateMigrateAway(vmUuid, srcHostId, _haMgr.getHAPlanner());
-                }
-            } finally {
-                _workJobDao.expunge(placeHolder.getId());
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = migrateVmAwayThroughJobQueue(vmUuid, srcHostId);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobException != null) {
-                if (jobException instanceof InsufficientServerCapacityException) {
-                    throw (InsufficientServerCapacityException)jobException;
-                } else if (jobException instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobException;
-                } else if (jobException instanceof RuntimeException) {
-                    throw (RuntimeException)jobException;
-                } else if (jobException instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
-                }
-            }
-        }
-    }
-
-    private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, final DeploymentPlanner planner) throws InsufficientServerCapacityException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        if (vm == null) {
-            s_logger.debug("Unable to find a VM for " + vmUuid);
-            throw new CloudRuntimeException("Unable to find " + vmUuid);
-        }
-
-        ServiceOfferingVO offeringVO = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, offeringVO, null, null);
-
-        final Long hostId = vm.getHostId();
-        if (hostId == null) {
-            s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm);
-            throw new CloudRuntimeException("Unable to migrate " + vmUuid);
-        }
-
-        final Host host = _hostDao.findById(hostId);
-        Long poolId = null;
-        final List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
-        for (final VolumeVO rootVolumeOfVm : vols) {
-            final StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
-            if (rootDiskPool != null) {
-                poolId = rootDiskPool.getId();
-            }
-        }
-
-        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, poolId, null);
-        final ExcludeList excludes = new ExcludeList();
-        excludes.addHost(hostId);
-
-        DeployDestination dest = null;
-        while (true) {
-
-            try {
-                dest = _dpMgr.planDeployment(profile, plan, excludes, planner);
-            } catch (final AffinityConflictException e2) {
-                s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
-                throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
-            }
-
-            if (dest != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Found destination " + dest + " for migrating to.");
-                }
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to find destination for migrating the vm " + profile);
-                }
-                throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId());
-            }
-
-            excludes.addHost(dest.getHost().getId());
-            try {
-                migrate(vm, srcHostId, dest);
-                return;
-            } catch (final ResourceUnavailableException e) {
-                s_logger.debug("Unable to migrate to unavailable " + dest);
-            } catch (final ConcurrentOperationException e) {
-                s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
-            }
-
-            try {
-                advanceStop(vmUuid, true);
-                throw new CloudRuntimeException("Unable to migrate " + vm);
-            } catch (final ResourceUnavailableException e) {
-                s_logger.debug("Unable to stop VM due to " + e.getMessage());
-                throw new CloudRuntimeException("Unable to migrate " + vm);
-            } catch (final ConcurrentOperationException e) {
-                s_logger.debug("Unable to stop VM due to " + e.getMessage());
-                throw new CloudRuntimeException("Unable to migrate " + vm);
-            } catch (final OperationTimedoutException e) {
-                s_logger.debug("Unable to stop VM due to " + e.getMessage());
-                throw new CloudRuntimeException("Unable to migrate " + vm);
-            }
-        }
-    }
-
-    protected class CleanupTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            s_logger.trace("VM Operation Thread Running");
-            try {
-                _workDao.cleanup(VmOpCleanupWait.value());
-                final Date cutDate = new Date(DateUtil.currentGMTTime().getTime() - VmOpCleanupInterval.value() * 1000);
-                _workJobDao.expungeCompletedWorkJobs(cutDate);
-            } catch (final Exception e) {
-                s_logger.error("VM Operations failed due to ", e);
-            }
-        }
-    }
-
-    @Override
-    public boolean isVirtualMachineUpgradable(final VirtualMachine vm, final ServiceOffering offering) {
-        boolean isMachineUpgradable = true;
-        for (final HostAllocator allocator : hostAllocators) {
-            isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering);
-            if (isMachineUpgradable) {
-                continue;
-            } else {
-                break;
-            }
-        }
-
-        return isMachineUpgradable;
-    }
-
-    @Override
-    public void reboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException {
-        try {
-            advanceReboot(vmUuid, params);
-        } catch (final ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Unable to reboot a VM due to concurrent operation", e);
-        }
-    }
-
-    @Override
-    public void advanceReboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params)
-            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if ( jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateReboot(vmUuid, params);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = rebootVmThroughJobQueue(vmUuid, params);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof InsufficientCapacityException) {
-                    throw (InsufficientCapacityException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-            }
-        }
-    }
-
-    private void orchestrateReboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ConcurrentOperationException,
-    ResourceUnavailableException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        // if there are active vm snapshots task, state change is not allowed
-        if(_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())){
-            s_logger.error("Unable to reboot VM " + vm + " due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
-            throw new CloudRuntimeException("Unable to reboot VM " + vm + " due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
-        }
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
-        final Host host = _hostDao.findById(vm.getHostId());
-        if (host == null) {
-            // Should findById throw an Exception is the host is not found?
-            throw new CloudRuntimeException("Unable to retrieve host with id " + vm.getHostId());
-        }
-        final Cluster cluster = _entityMgr.findById(Cluster.class, host.getClusterId());
-        final Pod pod = _entityMgr.findById(Pod.class, host.getPodId());
-        final DeployDestination dest = new DeployDestination(dc, pod, cluster, host);
-
-        try {
-
-            final Commands cmds = new Commands(Command.OnError.Stop);
-            cmds.addCommand(new RebootCommand(vm.getInstanceName(), getExecuteInSequence(vm.getHypervisorType())));
-            _agentMgr.send(host.getId(), cmds);
-
-            final Answer rebootAnswer = cmds.getAnswer(RebootAnswer.class);
-            if (rebootAnswer != null && rebootAnswer.getResult()) {
-                return;
-            }
-            s_logger.info("Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? " no reboot answer" : rebootAnswer.getDetails()));
-        } catch (final OperationTimedoutException e) {
-            s_logger.warn("Unable to send the reboot command to host " + dest.getHost() + " for the vm " + vm + " due to operation timeout", e);
-            throw new CloudRuntimeException("Failed to reboot the vm on host " + dest.getHost());
-        }
-    }
-
-    public Command cleanup(final VirtualMachine vm) {
-        StopCommand cmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
-        cmd.setControlIp(getControlNicIpForVM(vm));
-        return cmd;
-    }
-
-    private String getControlNicIpForVM(VirtualMachine vm) {
-        if (vm.getType() == VirtualMachine.Type.ConsoleProxy || vm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
-            NicVO nic = _nicsDao.getControlNicForVM(vm.getId());
-            return nic.getIPv4Address();
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter) return vm.getPrivateIpAddress();
-        else return null;
-    }
-    public Command cleanup(final String vmName) {
-        VirtualMachine vm = _vmDao.findVMByInstanceName(vmName);
-
-        StopCommand cmd = new StopCommand(vmName, getExecuteInSequence(null), false);
-        cmd.setControlIp(getControlNicIpForVM(vm));
-        return cmd;
-    }
-
-
-    // this is XenServer specific
-    public void syncVMMetaData(final Map<String, String> vmMetadatum) {
-        if (vmMetadatum == null || vmMetadatum.isEmpty()) {
-            return;
-        }
-        List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmDetails = _userVmDao.getVmsDetailByNames(vmMetadatum.keySet(), "platform");
-        for (final Map.Entry<String, String> entry : vmMetadatum.entrySet()) {
-            final String name = entry.getKey();
-            final String platform = entry.getValue();
-            if (platform == null || platform.isEmpty()) {
-                continue;
-            }
-
-            boolean found = false;
-            for(Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>> vmDetail : vmDetails ) {
-                Pair<String, VirtualMachine.Type> vmNameTypePair = vmDetail.first();
-                if(vmNameTypePair.first().equals(name)) {
-                    found = true;
-                    if(vmNameTypePair.second() == VirtualMachine.Type.User) {
-                        Pair<Long, String> detailPair = vmDetail.second();
-                        String platformDetail = detailPair.second();
-
-                        if (platformDetail != null && platformDetail.equals(platform)) {
-                            break;
-                        }
-                        updateVmMetaData(detailPair.first(), platform);
-                    }
-                    break;
-                }
-            }
-
-            if(!found) {
-                VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
-                if(vm != null && vm.getType() == VirtualMachine.Type.User) {
-                    updateVmMetaData(vm.getId(), platform);
-                }
-            }
-        }
-    }
-
-    // this is XenServer specific
-    private void updateVmMetaData(Long vmId, String platform) {
-        UserVmVO userVm = _userVmDao.findById(vmId);
-        _userVmDao.loadDetails(userVm);
-        if ( userVm.details.containsKey("timeoffset")) {
-            userVm.details.remove("timeoffset");
-        }
-        userVm.setDetail("platform",  platform);
-        String pvdriver = "xenserver56";
-        if ( platform.contains("device_id")) {
-            pvdriver = "xenserver61";
-        }
-        if (!userVm.details.containsKey("hypervisortoolsversion") || !userVm.details.get("hypervisortoolsversion").equals(pvdriver)) {
-            userVm.setDetail("hypervisortoolsversion", pvdriver);
-        }
-        _userVmDao.saveDetails(userVm);
-    }
-
-    private void ensureVmRunningContext(final long hostId, VMInstanceVO vm, final Event cause) throws OperationTimedoutException, ResourceUnavailableException,
-    NoTransitionException, InsufficientAddressCapacityException {
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-
-        s_logger.debug("VM state is starting on full sync so updating it to running");
-        vm = _vmDao.findById(vm.getId());
-
-        // grab outstanding work item if any
-        final ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState());
-        if (work != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found an outstanding work item for this vm " + vm + " in state:" + vm.getState() + ", work id:" + work.getId());
-            }
-        }
-
-        try {
-            stateTransitTo(vm, cause, hostId);
-        } catch (final NoTransitionException e1) {
-            s_logger.warn(e1.getMessage());
-        }
-
-        s_logger.debug("VM's " + vm + " state is starting on full sync so updating it to Running");
-        vm = _vmDao.findById(vm.getId()); // this should ensure vm has the most
-        // up to date info
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        final List<NicVO> nics = _nicsDao.listByVmId(profile.getId());
-        for (final NicVO nic : nics) {
-            final Network network = _networkModel.getNetwork(nic.getNetworkId());
-            final NicProfile nicProfile =
-                    new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel.isSecurityGroupSupportedInNetwork(network),
-                            _networkModel.getNetworkTag(profile.getHypervisorType(), network));
-            profile.addNic(nicProfile);
-        }
-
-        final Commands cmds = new Commands(Command.OnError.Stop);
-        s_logger.debug("Finalizing commands that need to be send to complete Start process for the vm " + vm);
-
-        if (vmGuru.finalizeCommandsOnStart(cmds, profile)) {
-            if (cmds.size() != 0) {
-                _agentMgr.send(vm.getHostId(), cmds);
-            }
-
-            if (vmGuru.finalizeStart(profile, vm.getHostId(), cmds, null)) {
-                stateTransitTo(vm, cause, vm.getHostId());
-            } else {
-                s_logger.error("Unable to finish finialization for running vm: " + vm);
-            }
-        } else {
-            s_logger.error("Unable to finalize commands on start for vm: " + vm);
-        }
-
-        if (work != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Updating outstanding work item to Done, id:" + work.getId());
-            }
-            work.setStep(Step.Done);
-            _workDao.update(work.getId(), work);
-        }
-    }
-
-    @Override
-    public boolean isRecurring() {
-        return true;
-    }
-
-    @Override
-    public boolean processAnswers(final long agentId, final long seq, final Answer[] answers) {
-        for (final Answer answer : answers) {
-            if ( answer instanceof ClusterVMMetaDataSyncAnswer) {
-                final ClusterVMMetaDataSyncAnswer cvms = (ClusterVMMetaDataSyncAnswer)answer;
-                if (!cvms.isExecuted()) {
-                    syncVMMetaData(cvms.getVMMetaDatum());
-                    cvms.setExecuted();
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean processTimeout(final long agentId, final long seq) {
-        return true;
-    }
-
-    @Override
-    public int getTimeout() {
-        return -1;
-    }
-
-    @Override
-    public boolean processCommands(final long agentId, final long seq, final Command[] cmds) {
-        boolean processed = false;
-        for (final Command cmd : cmds) {
-            if (cmd instanceof PingRoutingCommand) {
-                final PingRoutingCommand ping = (PingRoutingCommand)cmd;
-                if (ping.getHostVmStateReport() != null) {
-                    _syncMgr.processHostVmStatePingReport(agentId, ping.getHostVmStateReport());
-                }
-
-                // take the chance to scan VMs that are stuck in transitional states
-                // and are missing from the report
-                scanStalledVMInTransitionStateOnUpHost(agentId);
-                processed = true;
-            }
-        }
-        return processed;
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(final long agentId, final AgentControlCommand cmd) {
-        return null;
-    }
-
-    @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 void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(final Host agent, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
-        if (!(cmd instanceof StartupRoutingCommand)) {
-            return;
-        }
-
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Received startup command from hypervisor host. host id: " + agent.getId());
-        }
-
-        _syncMgr.resetHostSyncState(agent.getId());
-
-        if (forRebalance) {
-            s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process");
-            return;
-        }
-        final Long clusterId = agent.getClusterId();
-        final long agentId = agent.getId();
-
-        if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen
-            // initiate the cron job
-            final ClusterVMMetaDataSyncCommand syncVMMetaDataCmd = new ClusterVMMetaDataSyncCommand(ClusterVMMetaDataSyncInterval.value(), clusterId);
-            try {
-                final long seq_no = _agentMgr.send(agentId, new Commands(syncVMMetaDataCmd), this);
-                s_logger.debug("Cluster VM metadata sync started with jobid " + seq_no);
-            } catch (final AgentUnavailableException e) {
-                s_logger.fatal("The Cluster VM metadata sync process failed for cluster id " + clusterId + " with ", e);
-            }
-        }
-    }
-
-    protected class TransitionTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            final GlobalLock lock = GlobalLock.getInternLock("TransitionChecking");
-            if (lock == null) {
-                s_logger.debug("Couldn't get the global lock");
-                return;
-            }
-
-            if (!lock.lock(30)) {
-                s_logger.debug("Couldn't lock the db");
-                return;
-            }
-            try {
-                scanStalledVMInTransitionStateOnDisconnectedHosts();
-
-                final List<VMInstanceVO> instances = _vmDao.findVMInTransition(new Date(DateUtil.currentGMTTime().getTime() - AgentManager.Wait.value() * 1000), State.Starting, State.Stopping);
-                for (final VMInstanceVO instance : instances) {
-                    final State state = instance.getState();
-                    if (state == State.Stopping) {
-                        _haMgr.scheduleStop(instance, instance.getHostId(), WorkType.CheckStop);
-                    } else if (state == State.Starting) {
-                        _haMgr.scheduleRestart(instance, true);
-                    }
-                }
-            } catch (final Exception e) {
-                s_logger.warn("Caught the following exception on transition checking", e);
-            } finally {
-                lock.unlock();
-            }
-        }
-    }
-
-    @Override
-    public VMInstanceVO findById(final long vmId) {
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public void checkIfCanUpgrade(final VirtualMachine vmInstance, final ServiceOffering newServiceOffering) {
-        if (newServiceOffering == null) {
-            throw new InvalidParameterValueException("Invalid parameter, newServiceOffering can't be null");
-        }
-
-        // Check that the VM is stopped / running
-        if (!(vmInstance.getState().equals(State.Stopped) || vmInstance.getState().equals(State.Running))) {
-            s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState());
-            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState() +
-                    "; make sure the virtual machine is stopped/running");
-        }
-
-        // Check if the service offering being upgraded to is what the VM is already running with
-        if (!newServiceOffering.isDynamic() && vmInstance.getServiceOfferingId() == newServiceOffering.getId()) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + "service offering (" + newServiceOffering.getName() +
-                        ")");
-            }
-
-            throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + "has the requested service offering (" +
-                    newServiceOffering.getName() + ")");
-        }
-
-        final ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
-
-        // Check that the service offering being upgraded to has the same Guest IP type as the VM's current service offering
-        // NOTE: With the new network refactoring in 2.2, we shouldn't need the check for same guest IP type anymore.
-        /*
-         * if (!currentServiceOffering.getGuestIpType().equals(newServiceOffering.getGuestIpType())) { String errorMsg =
-         * "The service offering being upgraded to has a guest IP type: " + newServiceOffering.getGuestIpType(); errorMsg +=
-         * ". Please select a service offering with the same guest IP type as the VM's current service offering (" +
-         * currentServiceOffering.getGuestIpType() + ")."; throw new InvalidParameterValueException(errorMsg); }
-         */
-
-        // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service
-        // offering
-        if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) {
-            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() +
-                    ", cannot switch between local storage and shared storage service offerings.  Current offering " + "useLocalStorage=" +
-                    currentServiceOffering.getUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.getUseLocalStorage());
-        }
-
-        // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms
-        if (currentServiceOffering.getSystemUse() != newServiceOffering.getSystemUse()) {
-            throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering");
-        }
-
-        // Check that there are enough resources to upgrade the service offering
-        if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) {
-            throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + "for an offering of " +
-                    newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
-        }
-
-        // Check that the service offering being upgraded to has all the tags of the current service offering.
-        final List<String> currentTags = StringUtils.csvTagsToList(currentServiceOffering.getTags());
-        final List<String> newTags = StringUtils.csvTagsToList(newServiceOffering.getTags());
-        if (!newTags.containsAll(currentTags)) {
-            throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " +
-                    "the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
-        }
-    }
-
-    @Override
-    public boolean upgradeVmDb(final long vmId, final long serviceOfferingId) {
-        final VMInstanceVO vmForUpdate = _vmDao.createForUpdate();
-        vmForUpdate.setServiceOfferingId(serviceOfferingId);
-        final ServiceOffering newSvcOff = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        vmForUpdate.setHaEnabled(newSvcOff.getOfferHA());
-        vmForUpdate.setLimitCpuUse(newSvcOff.getLimitCpuUse());
-        vmForUpdate.setServiceOfferingId(newSvcOff.getId());
-        return _vmDao.update(vmId, vmForUpdate);
-    }
-
-    @Override
-    public NicProfile addVmToNetwork(final VirtualMachine vm, final Network network, final NicProfile requested)
-            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                return orchestrateAddVmToNetwork(vm, network, requested);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = addVmToNetworkThroughJobQueue(vm, network, requested);
-
-            try {
-                outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution exception", e);
-            }
-
-            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobException != null) {
-                if (jobException instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobException;
-                } else if (jobException instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobException;
-                } else if (jobException instanceof InsufficientCapacityException) {
-                    throw (InsufficientCapacityException)jobException;
-                } else if (jobException instanceof RuntimeException) {
-                    throw (RuntimeException)jobException;
-                } else if (jobException instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
-                } else if (jobException instanceof NicProfile) {
-                    return (NicProfile)jobException;
-                }
-            }
-
-            throw new RuntimeException("Unexpected job execution result");
-        }
-    }
-
-    private NicProfile orchestrateAddVmToNetwork(final VirtualMachine vm, final Network network, final NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-        final CallContext cctx = CallContext.current();
-
-        s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
-        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
-        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
-
-        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
-
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        final Host host = _hostDao.findById(vm.getHostId());
-        final DeployDestination dest = new DeployDestination(dc, null, null, host);
-
-        //check vm state
-        if (vm.getState() == State.Running) {
-            //1) allocate and prepare nic
-            final NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true);
-
-            //2) Convert vmProfile to vmTO
-            final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
-            final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
-
-            //3) Convert nicProfile to NicTO
-            final NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType());
-
-            //4) plug the nic to the vm
-            s_logger.debug("Plugging nic for vm " + vm + " in network " + network);
-
-            boolean result = false;
-            try {
-                result = plugNic(network, nicTO, vmTO, context, dest);
-                if (result) {
-                    s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm  is a part of network now");
-                    final long isDefault = nic.isDefaultNic() ? 1 : 0;
-                    // insert nic's Id into DB as resource_name
-                    if(VirtualMachine.Type.User.equals(vmVO.getType())) {
-                        //Log usage event for user Vms only
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(), vmVO.getDataCenterId(), vmVO.getId(),
-                                Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid(), vm.isDisplay());
-                    }
-                    return nic;
-                } else {
-                    s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network);
-                    return null;
-                }
-            } finally {
-                if (!result) {
-                    s_logger.debug("Removing nic " + nic + " from vm " + vmProfile.getVirtualMachine() + " as nic plug failed on the backend");
-                    _networkMgr.removeNic(vmProfile, _nicsDao.findById(nic.getId()));
-                }
-            }
-        } else if (vm.getState() == State.Stopped) {
-            //1) allocate nic
-            return _networkMgr.createNicForVm(network, requested, context, vmProfile, false);
-        } else {
-            s_logger.warn("Unable to add vm " + vm + " to network  " + network);
-            throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", DataCenter.class, vm.getDataCenterId());
-        }
-    }
-
-    @Override
-    public NicTO toNicTO(final NicProfile nic, final HypervisorType hypervisorType) {
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType);
-
-        final NicTO nicTO = hvGuru.toNicTO(nic);
-        return nicTO;
-    }
-
-    @Override
-    public boolean removeNicFromVm(final VirtualMachine vm, final Nic nic)
-            throws ConcurrentOperationException, ResourceUnavailableException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                return orchestrateRemoveNicFromVm(vm, nic);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-
-        } else {
-            final Outcome<VirtualMachine> outcome = removeNicFromVmThroughJobQueue(vm, nic);
-
-            try {
-                outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                } else if (jobResult instanceof Boolean) {
-                    return (Boolean)jobResult;
-                }
-            }
-
-            throw new RuntimeException("Job failed with un-handled exception");
-        }
-    }
-
-    private boolean orchestrateRemoveNicFromVm(final VirtualMachine vm, final Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
-        final CallContext cctx = CallContext.current();
-        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
-        final NetworkVO network = _networkDao.findById(nic.getNetworkId());
-        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
-
-        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
-
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        final Host host = _hostDao.findById(vm.getHostId());
-        final DeployDestination dest = new DeployDestination(dc, null, null, host);
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
-        final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
-
-        final NicProfile nicProfile =
-                new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()),
-                        _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
-
-        //1) Unplug the nic
-        if (vm.getState() == State.Running) {
-            final NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
-            s_logger.debug("Un-plugging nic " + nic + " for vm " + vm + " from network " + network);
-            final boolean result = unplugNic(network, nicTO, vmTO, context, dest);
-            if (result) {
-                s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network);
-                final long isDefault = nic.isDefaultNic() ? 1 : 0;
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                        Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
-            } else {
-                s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
-                return false;
-            }
-        } else if (vm.getState() != State.Stopped) {
-            s_logger.warn("Unable to remove vm " + vm + " from network  " + network);
-            throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state", DataCenter.class, vm.getDataCenterId());
-        }
-
-        //2) Release the nic
-        _networkMgr.releaseNic(vmProfile, nic);
-        s_logger.debug("Successfully released nic " + nic + "for vm " + vm);
-
-        //3) Remove the nic
-        _networkMgr.removeNic(vmProfile, nic);
-        _nicsDao.expunge(nic.getId());
-        return true;
-    }
-
-    @Override
-    @DB
-    public boolean removeVmFromNetwork(final VirtualMachine vm, final Network network, final URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO will serialize on the VM object later to resolve operation conflicts
-        return orchestrateRemoveVmFromNetwork(vm, network, broadcastUri);
-    }
-
-    @DB
-    private boolean orchestrateRemoveVmFromNetwork(final VirtualMachine vm, final Network network, final URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException {
-        final CallContext cctx = CallContext.current();
-        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
-        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
-
-        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
-
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        final Host host = _hostDao.findById(vm.getHostId());
-        final DeployDestination dest = new DeployDestination(dc, null, null, host);
-        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
-        final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
-
-        Nic nic = null;
-        if (broadcastUri != null) {
-            nic = _nicsDao.findByNetworkIdInstanceIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri.toString());
-        } else {
-            nic = _networkModel.getNicInNetwork(vm.getId(), network.getId());
-        }
-
-        if (nic == null) {
-            s_logger.warn("Could not get a nic with " + network);
-            return false;
-        }
-
-        // don't delete default NIC on a user VM
-        if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User) {
-            s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
-            throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
-        }
-
-        //Lock on nic is needed here
-        final Nic lock = _nicsDao.acquireInLockTable(nic.getId());
-        if (lock == null) {
-            //check if nic is still there. Return if it was released already
-            if (_nicsDao.findById(nic.getId()) == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Not need to remove the vm " + vm + " from network " + network + " as the vm doesn't have nic in this network");
-                }
-                return true;
-            }
-            throw new ConcurrentOperationException("Unable to lock nic " + nic.getId());
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Lock is acquired for nic id " + lock.getId() + " as a part of remove vm " + vm + " from network " + network);
-        }
-
-        try {
-            final NicProfile nicProfile =
-                    new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()),
-                            _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
-
-            //1) Unplug the nic
-            if (vm.getState() == State.Running) {
-                final NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
-                s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network);
-                final boolean result = unplugNic(network, nicTO, vmTO, context, dest);
-                if (result) {
-                    s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network);
-                } else {
-                    s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
-                    return false;
-                }
-            } else if (vm.getState() != State.Stopped) {
-                s_logger.warn("Unable to remove vm " + vm + " from network  " + network);
-                throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state", DataCenter.class, vm.getDataCenterId());
-            }
-
-            //2) Release the nic
-            _networkMgr.releaseNic(vmProfile, nic);
-            s_logger.debug("Successfully released nic " + nic + "for vm " + vm);
-
-            //3) Remove the nic
-            _networkMgr.removeNic(vmProfile, nic);
-            return true;
-        } finally {
-            if (lock != null) {
-                _nicsDao.releaseFromLockTable(lock.getId());
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Lock is released for nic id " + lock.getId() + " as a part of remove vm " + vm + " from network " + network);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException,
-    ResourceUnavailableException {
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        if (vm == null) {
-            throw new CloudRuntimeException("Unable to find " + vmUuid);
-        }
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-
-        final Long srcHostId = vm.getHostId();
-        final Long oldSvcOfferingId = vm.getServiceOfferingId();
-        if (srcHostId == null) {
-            throw new CloudRuntimeException("Unable to scale the vm because it doesn't have a host id");
-        }
-        final Host host = _hostDao.findById(srcHostId);
-        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null);
-        excludes.addHost(vm.getHostId());
-        vm.setServiceOfferingId(newSvcOfferingId); // Need to find the destination host based on new svc offering
-
-        DeployDestination dest = null;
-
-        try {
-            dest = _dpMgr.planDeployment(profile, plan, excludes, null);
-        } catch (final AffinityConflictException e2) {
-            s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
-            throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
-        }
-
-        if (dest != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(" Found " + dest + " for scaling the vm to.");
-            }
-        }
-
-        if (dest == null) {
-            throw new InsufficientServerCapacityException("Unable to find a server to scale the vm to.", host.getClusterId());
-        }
-
-        excludes.addHost(dest.getHost().getId());
-        try {
-            migrateForScale(vm.getUuid(), srcHostId, dest, oldSvcOfferingId);
-        } catch (final ResourceUnavailableException e) {
-            s_logger.debug("Unable to migrate to unavailable " + dest);
-            throw e;
-        } catch (final ConcurrentOperationException e) {
-            s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
-            throw e;
-        }
-    }
-
-    @Override
-    public void migrateForScale(final String vmUuid, final long srcHostId, final DeployDestination dest, final Long oldSvcOfferingId)
-            throws ResourceUnavailableException, ConcurrentOperationException {
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                orchestrateMigrateForScale(vmUuid, srcHostId, dest, oldSvcOfferingId);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = migrateVmForScaleThroughJobQueue(vmUuid, srcHostId, dest, oldSvcOfferingId);
-
-            try {
-                final VirtualMachine vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                }
-            }
-        }
-    }
-
-    private void orchestrateMigrateForScale(final String vmUuid, final long srcHostId, final DeployDestination dest, final Long oldSvcOfferingId)
-            throws ResourceUnavailableException, ConcurrentOperationException {
-
-        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-        s_logger.info("Migrating " + vm + " to " + dest);
-
-        vm.getServiceOfferingId();
-        final long dstHostId = dest.getHost().getId();
-        final Host fromHost = _hostDao.findById(srcHostId);
-        if (fromHost == null) {
-            s_logger.info("Unable to find the host to migrate from: " + srcHostId);
-            throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
-        }
-
-        if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
-            s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dstHostId);
-            throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
-        }
-
-        final VirtualMachineGuru vmGuru = getVmGuru(vm);
-
-        final long vmId = vm.getId();
-        vm = _vmDao.findByUuid(vmUuid);
-        if (vm == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find the vm " + vm);
-            }
-            throw new CloudRuntimeException("Unable to find a virtual machine with id " + vmId);
-        }
-
-        if (vm.getState() != State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
-            }
-            throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
-        }
-
-        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
-        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
-        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
-        }
-
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        _networkMgr.prepareNicForMigration(profile, dest);
-
-        volumeMgr.prepareForMigration(profile, dest);
-
-        final VirtualMachineTO to = toVmTO(profile);
-        final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
-
-        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
-        work.setStep(Step.Prepare);
-        work.setResourceType(ItWorkVO.ResourceType.Host);
-        work.setResourceId(dstHostId);
-        work = _workDao.persist(work);
-
-        Answer pfma = null;
-        try {
-            pfma = _agentMgr.send(dstHostId, pfmc);
-            if (pfma == null || !pfma.getResult()) {
-                final String details = pfma != null ? pfma.getDetails() : "null answer returned";
-                final String msg = "Unable to prepare for migration due to " + details;
-                pfma = null;
-                throw new AgentUnavailableException(msg, dstHostId);
-            }
-        } catch (final OperationTimedoutException e1) {
-            throw new AgentUnavailableException("Operation timed out", dstHostId);
-        } finally {
-            if (pfma == null) {
-                work.setStep(Step.Done);
-                _workDao.update(work.getId(), work);
-            }
-        }
-
-        vm.setLastHostId(srcHostId);
-        try {
-            if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
-                s_logger.info("Migration cancelled because state has changed: " + vm);
-                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
-            }
-        } catch (final NoTransitionException e1) {
-            s_logger.info("Migration cancelled because " + e1.getMessage());
-            throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
-        }
-
-        boolean migrated = false;
-        try {
-            final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-            final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
-
-            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
-            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
-
-            mc.setAutoConvergence(kvmAutoConvergence);
-
-            mc.setHostGuid(dest.getHost().getGuid());
-
-            try {
-                final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
-                if (ma == null || !ma.getResult()) {
-                    final String details = ma != null ? ma.getDetails() : "null answer returned";
-                    final String msg = "Unable to migrate due to " + details;
-                    s_logger.error(msg);
-                    throw new CloudRuntimeException(msg);
-                }
-            } catch (final OperationTimedoutException e) {
-                if (e.isActive()) {
-                    s_logger.warn("Active migration command so scheduling a restart for " + vm);
-                    _haMgr.scheduleRestart(vm, true);
-                }
-                throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
-            }
-
-            try {
-                final long newServiceOfferingId = vm.getServiceOfferingId();
-                vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
-                if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
-                    throw new ConcurrentOperationException("Unable to change the state for " + vm);
-                }
-                vm.setServiceOfferingId(newServiceOfferingId);
-            } catch (final NoTransitionException e1) {
-                throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
-            }
-
-            try {
-                if (!checkVmOnHost(vm, dstHostId)) {
-                    s_logger.error("Unable to complete migration for " + vm);
-                    try {
-                        _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
-                    } catch (final AgentUnavailableException e) {
-                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
-                    }
-                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
-                    throw new CloudRuntimeException("Unable to complete migration for " + vm);
-                }
-            } catch (final OperationTimedoutException e) {
-                s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
-            }
-
-            migrated = true;
-        } finally {
-            if (!migrated) {
-                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
-
-                _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(),
-                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " +
-                                dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
-                try {
-                    _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
-                } catch (final AgentUnavailableException ae) {
-                    s_logger.info("Looks like the destination Host is unavailable for cleanup");
-                }
-
-                try {
-                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
-                } catch (final NoTransitionException e) {
-                    s_logger.warn(e.getMessage());
-                }
-            }
-
-            work.setStep(Step.Done);
-            _workDao.update(work.getId(), work);
-        }
-    }
-
-    @Override
-    public boolean replugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
-            ResourceUnavailableException, InsufficientCapacityException {
-        boolean result = true;
-
-        final VMInstanceVO router = _vmDao.findById(vm.getId());
-        if (router.getState() == State.Running) {
-            try {
-                final ReplugNicCommand replugNicCmd = new ReplugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
-                final Commands cmds = new Commands(Command.OnError.Stop);
-                cmds.addCommand("replugnic", replugNicCmd);
-                _agentMgr.send(dest.getHost().getId(), cmds);
-                final ReplugNicAnswer replugNicAnswer = cmds.getAnswer(ReplugNicAnswer.class);
-                if (replugNicAnswer == null || !replugNicAnswer.getResult()) {
-                    s_logger.warn("Unable to replug nic for vm " + vm.getName());
-                    result = false;
-                }
-            } catch (final OperationTimedoutException e) {
-                throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
-            }
-        } else {
-            s_logger.warn("Unable to apply ReplugNic, vm " + router + " is not in the right state " + router.getState());
-
-            throw new ResourceUnavailableException("Unable to apply ReplugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class,
-                                                   router.getDataCenterId());
-        }
-
-        return result;
-    }
-
-    public boolean plugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
-    ResourceUnavailableException, InsufficientCapacityException {
-        boolean result = true;
-
-        final VMInstanceVO router = _vmDao.findById(vm.getId());
-        if (router.getState() == State.Running) {
-            try {
-                final PlugNicCommand plugNicCmd = new PlugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
-                final Commands cmds = new Commands(Command.OnError.Stop);
-                cmds.addCommand("plugnic", plugNicCmd);
-                _agentMgr.send(dest.getHost().getId(), cmds);
-                final PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class);
-                if (plugNicAnswer == null || !plugNicAnswer.getResult()) {
-                    s_logger.warn("Unable to plug nic for vm " + vm.getName());
-                    result = false;
-                }
-            } catch (final OperationTimedoutException e) {
-                throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
-            }
-        } else {
-            s_logger.warn("Unable to apply PlugNic, vm " + router + " is not in the right state " + router.getState());
-
-            throw new ResourceUnavailableException("Unable to apply PlugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-
-        return result;
-    }
-
-    public boolean unplugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-
-        boolean result = true;
-        final VMInstanceVO router = _vmDao.findById(vm.getId());
-
-        if (router.getState() == State.Running) {
-            // collect vm network statistics before unplug a nic
-            UserVmVO userVm = _userVmDao.findById(vm.getId());
-            if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
-                _userVmService.collectVmNetworkStatistics(userVm);
-            }
-            try {
-                final Commands cmds = new Commands(Command.OnError.Stop);
-                final UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(nic, vm.getName());
-                cmds.addCommand("unplugnic", unplugNicCmd);
-                _agentMgr.send(dest.getHost().getId(), cmds);
-
-                final UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class);
-                if (unplugNicAnswer == null || !unplugNicAnswer.getResult()) {
-                    s_logger.warn("Unable to unplug nic from router " + router);
-                    result = false;
-                }
-            } catch (final OperationTimedoutException e) {
-                throw new AgentUnavailableException("Unable to unplug nic from rotuer " + router + " from network " + network, dest.getHost().getId(), e);
-            }
-        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
-            s_logger.debug("Vm " + router.getInstanceName() + " is in " + router.getState() + ", so not sending unplug nic command to the backend");
-        } else {
-            s_logger.warn("Unable to apply unplug nic, Vm " + router + " is not in the right state " + router.getState());
-
-            throw new ResourceUnavailableException("Unable to apply unplug nic on the backend," + " vm " + router + " is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-
-        return result;
-    }
-
-    @Override
-    public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering oldServiceOffering,
-            final boolean reconfiguringOnExistingHost)
-                    throws ResourceUnavailableException, InsufficientServerCapacityException, ConcurrentOperationException {
-
-        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
-            placeHolder = createPlaceHolderWork(vm.getId());
-            try {
-                return orchestrateReConfigureVm(vmUuid, oldServiceOffering, reconfiguringOnExistingHost);
-            } finally {
-                if (placeHolder != null) {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            }
-        } else {
-            final Outcome<VirtualMachine> outcome = reconfigureVmThroughJobQueue(vmUuid, oldServiceOffering, reconfiguringOnExistingHost);
-
-            VirtualMachine vm = null;
-            try {
-                vm = outcome.get();
-            } catch (final InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (final java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ResourceUnavailableException) {
-                    throw (ResourceUnavailableException)jobResult;
-                } else if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof InsufficientServerCapacityException) {
-                    throw (InsufficientServerCapacityException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    s_logger.error("Unhandled exception", (Throwable)jobResult);
-                    throw new RuntimeException("Unhandled exception", (Throwable)jobResult);
-                }
-            }
-
-            return (VMInstanceVO)vm;
-        }
-    }
-
-    private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final ServiceOffering oldServiceOffering, final boolean reconfiguringOnExistingHost) throws ResourceUnavailableException,
-    ConcurrentOperationException {
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final long newServiceofferingId = vm.getServiceOfferingId();
-        final ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), newServiceofferingId);
-        final HostVO hostVo = _hostDao.findById(vm.getHostId());
-
-        final Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(hostVo.getClusterId());
-        final Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(hostVo.getClusterId());
-        final long minMemory = (long)(newServiceOffering.getRamSize() / memoryOvercommitRatio);
-        final ScaleVmCommand reconfigureCmd =
-                new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio),
-                        newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse());
-
-        final Long dstHostId = vm.getHostId();
-        if(vm.getHypervisorType().equals(HypervisorType.VMware)) {
-            final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
-            Map<String, String> details = null;
-            details = hvGuru.getClusterSettings(vm.getId());
-            reconfigureCmd.getVirtualMachine().setDetails(details);
-        }
-
-        final ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId());
-
-        work.setStep(Step.Prepare);
-        work.setResourceType(ItWorkVO.ResourceType.Host);
-        work.setResourceId(vm.getHostId());
-        _workDao.persist(work);
-        boolean success = false;
-        try {
-            if (reconfiguringOnExistingHost) {
-                vm.setServiceOfferingId(oldServiceOffering.getId());
-                _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); //release the old capacity
-                vm.setServiceOfferingId(newServiceofferingId);
-                _capacityMgr.allocateVmCapacity(vm, false); // lock the new capacity
-            }
-
-            final Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd);
-            if (reconfigureAnswer == null || !reconfigureAnswer.getResult()) {
-                s_logger.error("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
-                throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
-            }
-
-            success = true;
-        } catch (final OperationTimedoutException e) {
-            throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId);
-        } catch (final AgentUnavailableException e) {
-            throw e;
-        } finally {
-            if (!success) {
-                _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); // release the new capacity
-                vm.setServiceOfferingId(oldServiceOffering.getId());
-                _capacityMgr.allocateVmCapacity(vm, false); // allocate the old capacity
-            }
-        }
-
-        return vm;
-
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return VirtualMachineManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait,
-                VmOpLockStateRetry,
-                VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp};
-    }
-
-    public List<StoragePoolAllocator> getStoragePoolAllocators() {
-        return _storagePoolAllocators;
-    }
-
-    @Inject
-    public void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators) {
-        _storagePoolAllocators = storagePoolAllocators;
-    }
-
-    //
-    // PowerState report handling for out-of-band changes and handling of left-over transitional VM states
-    //
-
-    @MessageHandler(topic = Topics.VM_POWER_STATE)
-    protected void HandlePowerStateReport(final String subject, final String senderAddress, final Object args) {
-        assert args != null;
-        final Long vmId = (Long)args;
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vmId);
-        if (pendingWorkJobs.size() == 0 && !_haMgr.hasPendingHaWork(vmId)) {
-            // there is no pending operation job
-            final VMInstanceVO vm = _vmDao.findById(vmId);
-            if (vm != null) {
-                switch (vm.getPowerState()) {
-                case PowerOn:
-                    handlePowerOnReportWithNoPendingJobsOnVM(vm);
-                    break;
-
-                case PowerOff:
-                case PowerReportMissing:
-                    handlePowerOffReportWithNoPendingJobsOnVM(vm);
-                    break;
-
-                    // PowerUnknown shouldn't be reported, it is a derived
-                    // VM power state from host state (host un-reachable)
-                case PowerUnknown:
-                default:
-                    assert false;
-                    break;
-                }
-            } else {
-                s_logger.warn("VM " + vmId + " no longer exists when processing VM state report");
-            }
-        } else {
-            s_logger.info("There is pending job or HA tasks working on the VM. vm id: " + vmId + ", postpone power-change report by resetting power-change counters");
-
-            // reset VM power state tracking so that we won't lost signal when VM has
-            // been translated to
-            _vmDao.resetVmPowerStateTracking(vmId);
-        }
-    }
-
-    private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
-        //
-        //    1) handle left-over transitional VM states
-        //    2) handle out of band VM live migration
-        //    3) handle out of sync stationary states, marking VM from Stopped to Running with
-        //       alert messages
-        //
-        switch (vm.getState()) {
-        case Starting:
-            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
-
-            try {
-                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
-            } catch (final NoTransitionException e) {
-                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
-            }
-
-            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
-
-            // we need to alert admin or user about this risky state transition
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
-                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName()
-                    + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset");
-            break;
-
-        case Running:
-            try {
-                if (vm.getHostId() != null && vm.getHostId().longValue() != vm.getPowerHostId().longValue()) {
-                    s_logger.info("Detected out of band VM migration from host " + vm.getHostId() + " to host " + vm.getPowerHostId());
-                }
-                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
-            } catch (final NoTransitionException e) {
-                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
-            }
-
-            break;
-
-        case Stopping:
-        case Stopped:
-            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
-
-            try {
-                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
-            } catch (final NoTransitionException e) {
-                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
-            }
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
-                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState()
-                    + " -> Running) from out-of-context transition. VM network environment may need to be reset");
-
-            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
-            break;
-
-        case Destroyed:
-        case Expunging:
-            s_logger.info("Receive power on report when VM is in destroyed or expunging state. vm: "
-                    + vm.getId() + ", state: " + vm.getState());
-            break;
-
-        case Migrating:
-            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
-            try {
-                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
-            } catch (final NoTransitionException e) {
-                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
-            }
-            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
-            break;
-
-        case Error:
-        default:
-            s_logger.info("Receive power on report when VM is in error or unexpected state. vm: "
-                    + vm.getId() + ", state: " + vm.getState());
-            break;
-        }
-    }
-
-    private void handlePowerOffReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
-
-        //    1) handle left-over transitional VM states
-        //    2) handle out of sync stationary states, schedule force-stop to release resources
-        //
-        switch (vm.getState()) {
-        case Starting:
-        case Stopping:
-        case Running:
-        case Stopped:
-        case Migrating:
-            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-off report while there is no pending jobs on it");
-            if(vm.isHaEnabled() && vm.getState() == State.Running && HaVmRestartHostUp.value() && vm.getHypervisorType() != HypervisorType.VMware && vm.getHypervisorType() != HypervisorType.Hyperv) {
-                s_logger.info("Detected out-of-band stop of a HA enabled VM " + vm.getInstanceName() + ", will schedule restart");
-                if(!_haMgr.hasPendingHaWork(vm.getId())) {
-                    _haMgr.scheduleRestart(vm, true);
-                } else {
-                    s_logger.info("VM " + vm.getInstanceName() + " already has an pending HA task working on it");
-                }
-                return;
-            }
-
-            final VirtualMachineGuru vmGuru = getVmGuru(vm);
-            final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-            if (!sendStop(vmGuru, profile, true, true)) {
-                // In case StopCommand fails, don't proceed further
-                return;
-            }
-
-            try {
-                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOffReport, null);
-            } catch (final NoTransitionException e) {
-                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
-            }
-
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
-                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState()
-                    + " -> Stopped) from out-of-context transition.");
-
-            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Stopped state according to power-off report from hypervisor");
-
-            break;
-
-        case Destroyed:
-        case Expunging:
-            break;
-
-        case Error:
-        default:
-            break;
-        }
-    }
-
-    private void scanStalledVMInTransitionStateOnUpHost(final long hostId) {
-        //
-        // Check VM that is stuck in Starting, Stopping, Migrating states, we won't check
-        // VMs in expunging state (this need to be handled specially)
-        //
-        // checking condition
-        //    1) no pending VmWork job
-        //    2) on hostId host and host is UP
-        //
-        // When host is UP, soon or later we will get a report from the host about the VM,
-        // however, if VM is missing from the host report (it may happen in out of band changes
-        // or from designed behave of XS/KVM), the VM may not get a chance to run the state-sync logic
-        //
-        // Therefore, we will scan thoses VMs on UP host based on last update timestamp, if the host is UP
-        // and a VM stalls for status update, we will consider them to be powered off
-        // (which is relatively safe to do so)
-
-        final long stallThresholdInMs = VmJobStateReportInterval.value() + (VmJobStateReportInterval.value() >> 1);
-        final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - stallThresholdInMs);
-        final List<Long> mostlikelyStoppedVMs = listStalledVMInTransitionStateOnUpHost(hostId, cutTime);
-        for (final Long vmId : mostlikelyStoppedVMs) {
-            final VMInstanceVO vm = _vmDao.findById(vmId);
-            assert vm != null;
-            handlePowerOffReportWithNoPendingJobsOnVM(vm);
-        }
-
-        final List<Long> vmsWithRecentReport = listVMInTransitionStateWithRecentReportOnUpHost(hostId, cutTime);
-        for (final Long vmId : vmsWithRecentReport) {
-            final VMInstanceVO vm = _vmDao.findById(vmId);
-            assert vm != null;
-            if (vm.getPowerState() == PowerState.PowerOn) {
-                handlePowerOnReportWithNoPendingJobsOnVM(vm);
-            } else {
-                handlePowerOffReportWithNoPendingJobsOnVM(vm);
-            }
-        }
-    }
-
-    private void scanStalledVMInTransitionStateOnDisconnectedHosts() {
-        final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - VmOpWaitInterval.value() * 1000);
-        final List<Long> stuckAndUncontrollableVMs = listStalledVMInTransitionStateOnDisconnectedHosts(cutTime);
-        for (final Long vmId : stuckAndUncontrollableVMs) {
-            final VMInstanceVO vm = _vmDao.findById(vmId);
-
-            // We now only alert administrator about this situation
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
-                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") is stuck in " + vm.getState()
-                    + " state and its host is unreachable for too long");
-        }
-    }
-
-    // VMs that in transitional state without recent power state report
-    private List<Long> listStalledVMInTransitionStateOnUpHost(final long hostId, final Date cutTime) {
-        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
-                "AND h.id = ? AND i.power_state_update_time < ? AND i.host_id = h.id " +
-                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
-                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
-                "AND i.removed IS NULL";
-
-        final List<Long> l = new ArrayList<Long>();
-        TransactionLegacy txn = null;
-        try {
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-
-            PreparedStatement pstmt = null;
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-
-                pstmt.setLong(1, hostId);
-                pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
-                pstmt.setInt(3, JobInfo.Status.IN_PROGRESS.ordinal());
-                final ResultSet rs = pstmt.executeQuery();
-                while (rs.next()) {
-                    l.add(rs.getLong(1));
-                }
-            } catch (final SQLException e) {
-            } catch (final Throwable e) {
-            }
-
-        } finally {
-            if (txn != null) {
-                txn.close();
-            }
-        }
-        return l;
-    }
-
-    // VMs that in transitional state and recently have power state update
-    private List<Long> listVMInTransitionStateWithRecentReportOnUpHost(final long hostId, final Date cutTime) {
-        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
-                "AND h.id = ? AND i.power_state_update_time > ? AND i.host_id = h.id " +
-                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
-                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
-                "AND i.removed IS NULL";
-
-        final List<Long> l = new ArrayList<Long>();
-        TransactionLegacy txn = null;
-        try {
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            PreparedStatement pstmt = null;
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-
-                pstmt.setLong(1, hostId);
-                pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
-                pstmt.setInt(3, JobInfo.Status.IN_PROGRESS.ordinal());
-                final ResultSet rs = pstmt.executeQuery();
-                while (rs.next()) {
-                    l.add(rs.getLong(1));
-                }
-            } catch (final SQLException e) {
-            } catch (final Throwable e) {
-            }
-            return l;
-        } finally {
-            if (txn != null) {
-                txn.close();
-            }
-        }
-    }
-
-    private List<Long> listStalledVMInTransitionStateOnDisconnectedHosts(final Date cutTime) {
-        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " +
-                "AND i.power_state_update_time < ? AND i.host_id = h.id " +
-                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
-                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
-                "AND i.removed IS NULL";
-
-        final List<Long> l = new ArrayList<Long>();
-        TransactionLegacy txn = null;
-        try {
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            PreparedStatement pstmt = null;
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-
-                pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
-                pstmt.setInt(2, JobInfo.Status.IN_PROGRESS.ordinal());
-                final ResultSet rs = pstmt.executeQuery();
-                while (rs.next()) {
-                    l.add(rs.getLong(1));
-                }
-            } catch (final SQLException e) {
-            } catch (final Throwable e) {
-            }
-            return l;
-        } finally {
-            if (txn != null) {
-                txn.close();
-            }
-        }
-    }
-
-    //
-    // VM operation based on new sync model
-    //
-
-    public class VmStateSyncOutcome extends OutcomeImpl<VirtualMachine> {
-        private long _vmId;
-
-        public VmStateSyncOutcome(final AsyncJob job, final PowerState desiredPowerState, final long vmId, final Long srcHostIdForMigration) {
-            super(VirtualMachine.class, job, VmJobCheckInterval.value(), new Predicate() {
-                @Override
-                public boolean checkCondition() {
-                    final AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
-                    assert jobVo != null;
-                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                        return true;
-                    }
-                    return false;
-                }
-            }, Topics.VM_POWER_STATE, AsyncJob.Topics.JOB_STATE);
-            _vmId = vmId;
-        }
-
-        @Override
-        protected VirtualMachine retrieve() {
-            return _vmDao.findById(_vmId);
-        }
-    }
-
-    public class VmJobVirtualMachineOutcome extends OutcomeImpl<VirtualMachine> {
-        private long _vmId;
-
-        public VmJobVirtualMachineOutcome(final AsyncJob job, final long vmId) {
-            super(VirtualMachine.class, job, VmJobCheckInterval.value(), new Predicate() {
-                @Override
-                public boolean checkCondition() {
-                    final AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
-                    assert jobVo != null;
-                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                        return true;
-                    }
-
-                    return false;
-                }
-            }, AsyncJob.Topics.JOB_STATE);
-            _vmId = vmId;
-        }
-
-        @Override
-        protected VirtualMachine retrieve() {
-            return _vmDao.findById(_vmId);
-        }
-    }
-
-    //
-    // TODO build a common pattern to reduce code duplication in following methods
-    // no time for this at current iteration
-    //
-    public Outcome<VirtualMachine> startVmThroughJobQueue(final String vmUuid,
-            final Map<VirtualMachineProfile.Param, Object> params,
-            final DeploymentPlan planToDeploy, final DeploymentPlanner planner) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        VmWorkJobVO workJob = null;
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance,
-                vm.getId(), VmWorkStart.class.getName());
-
-        if (pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkStart.class.getName());
-
-            workJob.setAccountId(callingAccount.getId());
-            workJob.setUserId(callingUser.getId());
-            workJob.setStep(VmWorkJobVO.Step.Starting);
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkStart workInfo = new VmWorkStart(callingUser.getId(), callingAccount.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER);
-            workInfo.setPlan(planToDeploy);
-            workInfo.setParams(params);
-            if (planner != null) {
-                workInfo.setDeploymentPlanner(planner.getName());
-            }
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmStateSyncOutcome(workJob,
-                VirtualMachine.PowerState.PowerOn, vm.getId(), null);
-    }
-
-    public Outcome<VirtualMachine> stopVmThroughJobQueue(final String vmUuid, final boolean cleanup) {
-        final CallContext context = CallContext.current();
-        final Account account = context.getCallingAccount();
-        final User user = context.getCallingUser();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                vm.getType(), vm.getId(),
-                VmWorkStop.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkStop.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setStep(VmWorkJobVO.Step.Prepare);
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkStop workInfo = new VmWorkStop(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, cleanup);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmStateSyncOutcome(workJob,
-                VirtualMachine.PowerState.PowerOff, vm.getId(), null);
-    }
-
-    public Outcome<VirtualMachine> rebootVmThroughJobQueue(final String vmUuid,
-            final Map<VirtualMachineProfile.Param, Object> params) {
-
-        final CallContext context = CallContext.current();
-        final Account account = context.getCallingAccount();
-        final User user = context.getCallingUser();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkReboot.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkReboot.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setStep(VmWorkJobVO.Step.Prepare);
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkReboot workInfo = new VmWorkReboot(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, params);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob,
-                vm.getId());
-    }
-
-    public Outcome<VirtualMachine> migrateVmThroughJobQueue(final String vmUuid, final long srcHostId, final DeployDestination dest) {
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkMigrate.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkMigrate.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkMigrate workInfo = new VmWorkMigrate(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmStateSyncOutcome(workJob,
-                VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
-    }
-
-    public Outcome<VirtualMachine> migrateVmAwayThroughJobQueue(final String vmUuid, final long srcHostId) {
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkMigrateAway.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkMigrateAway.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkMigrateAway workInfo = new VmWorkMigrateAway(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-        }
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmStateSyncOutcome(workJob, VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
-    }
-
-    public Outcome<VirtualMachine> migrateVmWithStorageThroughJobQueue(
-            final String vmUuid, final long srcHostId, final long destHostId,
-            final Map<Long, Long> volumeToPool) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkMigrateWithStorage.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkMigrateWithStorage.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkMigrateWithStorage workInfo = new VmWorkMigrateWithStorage(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, destHostId, volumeToPool);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmStateSyncOutcome(workJob,
-                VirtualMachine.PowerState.PowerOn, vm.getId(), destHostId);
-    }
-
-    public Outcome<VirtualMachine> migrateVmForScaleThroughJobQueue(
-            final String vmUuid, final long srcHostId, final DeployDestination dest, final Long newSvcOfferingId) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkMigrateForScale.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkMigrateForScale.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkMigrateForScale workInfo = new VmWorkMigrateForScale(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest, newSvcOfferingId);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    public Outcome<VirtualMachine> migrateVmStorageThroughJobQueue(
-            final String vmUuid, final StoragePool destPool) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkStorageMigration.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkStorageMigration.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkStorageMigration workInfo = new VmWorkStorageMigration(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, destPool.getId());
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    public Outcome<VirtualMachine> addVmToNetworkThroughJobQueue(
-            final VirtualMachine vm, final Network network, final NicProfile requested) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkAddVmToNetwork.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
-            final VirtualMachine vm, final Nic nic) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkRemoveNicFromVm.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkRemoveNicFromVm workInfo = new VmWorkRemoveNicFromVm(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, nic.getId());
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    public Outcome<VirtualMachine> removeVmFromNetworkThroughJobQueue(
-            final VirtualMachine vm, final Network network, final URI broadcastUri) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkRemoveVmFromNetwork.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkRemoveVmFromNetwork.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkRemoveVmFromNetwork workInfo = new VmWorkRemoveVmFromNetwork(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network, broadcastUri);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    public Outcome<VirtualMachine> reconfigureVmThroughJobQueue(
-            final String vmUuid, final ServiceOffering newServiceOffering, final boolean reconfiguringOnExistingHost) {
-
-        final CallContext context = CallContext.current();
-        final User user = context.getCallingUser();
-        final Account account = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
-
-        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
-                VirtualMachine.Type.Instance, vm.getId(),
-                VmWorkReconfigure.class.getName());
-
-        VmWorkJobVO workJob = null;
-        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
-            assert pendingWorkJobs.size() == 1;
-            workJob = pendingWorkJobs.get(0);
-        } else {
-
-            workJob = new VmWorkJobVO(context.getContextId());
-
-            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-            workJob.setCmd(VmWorkReconfigure.class.getName());
-
-            workJob.setAccountId(account.getId());
-            workJob.setUserId(user.getId());
-            workJob.setVmType(VirtualMachine.Type.Instance);
-            workJob.setVmInstanceId(vm.getId());
-            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-            // save work context info (there are some duplications)
-            final VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(),
-                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newServiceOffering.getId(), reconfiguringOnExistingHost);
-            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-        }
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateStart(final VmWorkStart work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-
-        try{
-            orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner()));
-        }
-        catch (CloudRuntimeException e){
-            e.printStackTrace();
-            s_logger.info("Caught CloudRuntimeException, returning job failed " + e);
-            CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM instance");
-            return new Pair<JobInfo.Status, String>(JobInfo.Status.FAILED, JobSerializerHelper.toObjectSerializedString(ex));
-        }
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateStop(final VmWorkStop work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-            throw new CloudRuntimeException("Unable to find VM id=" + work.getVmId());
-        }
-
-        orchestrateStop(vm.getUuid(), work.isCleanup());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateMigrate(final VmWorkMigrate work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-
-        orchestrateMigrate(vm.getUuid(), work.getSrcHostId(), work.getDeployDestination());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateMigrateAway(final VmWorkMigrateAway work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-
-        try {
-            orchestrateMigrateAway(vm.getUuid(), work.getSrcHostId(), null);
-        } catch (final InsufficientServerCapacityException e) {
-            s_logger.warn("Failed to deploy vm " + vm.getId() + " with original planner, sending HAPlanner");
-            orchestrateMigrateAway(vm.getUuid(), work.getSrcHostId(), _haMgr.getHAPlanner());
-        }
-
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateMigrateWithStorage(final VmWorkMigrateWithStorage work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        orchestrateMigrateWithStorage(vm.getUuid(),
-                work.getSrcHostId(),
-                work.getDestHostId(),
-                work.getVolumeToPool());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateMigrateForScale(final VmWorkMigrateForScale work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        orchestrateMigrateForScale(vm.getUuid(),
-                work.getSrcHostId(),
-                work.getDeployDestination(),
-                work.getNewServiceOfferringId());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateReboot(final VmWorkReboot work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        orchestrateReboot(vm.getUuid(), work.getParams());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateAddVmToNetwork(final VmWorkAddVmToNetwork work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-
-        final Network network = _networkDao.findById(work.getNetworkId());
-        final NicProfile nic = orchestrateAddVmToNetwork(vm, network,
-                work.getRequestedNicProfile());
-
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(nic));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateRemoveNicFromVm(final VmWorkRemoveNicFromVm work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        final NicVO nic = _entityMgr.findById(NicVO.class, work.getNicId());
-        final boolean result = orchestrateRemoveNicFromVm(vm, nic);
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED,
-                _jobMgr.marshallResultObject(result));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateRemoveVmFromNetwork(final VmWorkRemoveVmFromNetwork work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        final boolean result = orchestrateRemoveVmFromNetwork(vm,
-                work.getNetwork(), work.getBroadcastUri());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED,
-                _jobMgr.marshallResultObject(result));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateReconfigure(final VmWorkReconfigure work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-
-        final ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), work.getNewServiceOfferingId());
-
-        reConfigureVm(vm.getUuid(), newServiceOffering,
-                work.isSameHost());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateStorageMigration(final VmWorkStorageMigration work) throws Exception {
-        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm " + work.getVmId());
-        }
-        assert vm != null;
-        final StoragePool pool = (PrimaryDataStoreInfo)dataStoreMgr.getPrimaryDataStore(work.getDestStoragePoolId());
-        orchestrateStorageMigration(vm.getUuid(), pool);
-
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
-    }
-
-    @Override
-    public Pair<JobInfo.Status, String> handleVmWorkJob(final VmWork work) throws Exception {
-        return _jobHandlerProxy.handleVmWorkJob(work);
-    }
-
-    private VmWorkJobVO createPlaceHolderWork(final long instanceId) {
-        final VmWorkJobVO workJob = new VmWorkJobVO("");
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
-        workJob.setCmd("");
-        workJob.setCmdInfo("");
-
-        workJob.setAccountId(0);
-        workJob.setUserId(0);
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(instanceId);
-        workJob.setInitMsid(ManagementServerNode.getManagementServerId());
-
-        _workJobDao.persist(workJob);
-
-        return workJob;
-    }
-}
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
deleted file mode 100644
index f8aad26..0000000
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
+++ /dev/null
@@ -1,184 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import com.cloud.configuration.ManagementServiceConfiguration;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-
-import com.cloud.agent.api.HostVmStateReportEntry;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStateSync {
-    private static final Logger s_logger = Logger.getLogger(VirtualMachinePowerStateSyncImpl.class);
-
-    @Inject MessageBus _messageBus;
-    @Inject VMInstanceDao _instanceDao;
-    @Inject VirtualMachineManager _vmMgr;
-    @Inject ManagementServiceConfiguration mgmtServiceConf;
-
-    public VirtualMachinePowerStateSyncImpl() {
-    }
-
-    @Override
-    public void resetHostSyncState(long hostId) {
-        s_logger.info("Reset VM power state sync for host: " + hostId);
-        _instanceDao.resetHostPowerStateTracking(hostId);
-    }
-
-    @Override
-    public void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report) {
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Process host VM state report from ping process. host: " + hostId);
-
-        Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
-        processReport(hostId, translatedInfo);
-    }
-
-    @Override
-    public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report) {
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Process host VM state report from ping process. host: " + hostId);
-
-        Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
-        processReport(hostId, translatedInfo);
-    }
-
-    private void processReport(long hostId, Map<Long, VirtualMachine.PowerState> translatedInfo) {
-
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Process VM state report. host: " + hostId + ", number of records in report: " + translatedInfo.size());
-
-        for (Map.Entry<Long, VirtualMachine.PowerState> entry : translatedInfo.entrySet()) {
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("VM state report. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
-
-            if (_instanceDao.updatePowerState(entry.getKey(), hostId, entry.getValue())) {
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
-
-                _messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, entry.getKey());
-            } else {
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("VM power state does not change, skip DB writing. vm id: " + entry.getKey());
-            }
-        }
-
-        // for all running/stopping VMs, we provide monitoring of missing report
-        List<VMInstanceVO> vmsThatAreMissingReport = _instanceDao.findByHostInStates(hostId, VirtualMachine.State.Running,
-                VirtualMachine.State.Stopping, VirtualMachine.State.Starting);
-        java.util.Iterator<VMInstanceVO> it = vmsThatAreMissingReport.iterator();
-        while (it.hasNext()) {
-            VMInstanceVO instance = it.next();
-            if (translatedInfo.get(instance.getId()) != null)
-                it.remove();
-        }
-
-        if (vmsThatAreMissingReport.size() > 0) {
-            Date currentTime = DateUtil.currentGMTTime();
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Run missing VM report. current time: " + currentTime.getTime());
-
-            // 2 times of sync-update interval for graceful period
-            long milliSecondsGracefullPeriod = mgmtServiceConf.getPingInterval() * 2000L;
-
-            for (VMInstanceVO instance : vmsThatAreMissingReport) {
-
-                // Make sure powerState is up to date for missing VMs
-                try {
-                    if (!_instanceDao.isPowerStateUpToDate(instance.getId())) {
-                        s_logger.warn("Detected missing VM but power state is outdated, wait for another process report run for VM id: " + instance.getId());
-                        _instanceDao.resetVmPowerStateTracking(instance.getId());
-                        continue;
-                    }
-                } catch (CloudRuntimeException e) {
-                    s_logger.warn("Checked for missing powerstate of a none existing vm", e);
-                    continue;
-                }
-
-                Date vmStateUpdateTime = instance.getPowerStateUpdateTime();
-                if (vmStateUpdateTime == null) {
-                    s_logger.warn("VM power state update time is null, falling back to update time for vm id: " + instance.getId());
-                    vmStateUpdateTime = instance.getUpdateTime();
-                    if (vmStateUpdateTime == null) {
-                        s_logger.warn("VM update time is null, falling back to creation time for vm id: " + instance.getId());
-                        vmStateUpdateTime = instance.getCreated();
-                    }
-                }
-
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("Detected missing VM. host: " + hostId + ", vm id: " + instance.getId() +
-                            ", power state: PowerReportMissing, last state update: " + vmStateUpdateTime.getTime());
-
-                long milliSecondsSinceLastStateUpdate = currentTime.getTime() - vmStateUpdateTime.getTime();
-
-                if (milliSecondsSinceLastStateUpdate > milliSecondsGracefullPeriod) {
-                    s_logger.debug("vm id: " + instance.getId() + " - time since last state update(" + milliSecondsSinceLastStateUpdate + "ms) has passed graceful period");
-
-                    if (_instanceDao.updatePowerState(instance.getId(), hostId, VirtualMachine.PowerState.PowerReportMissing)) {
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + instance.getId() + ", power state: PowerReportMissing ");
-
-                        _messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, instance.getId());
-                    } else {
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("VM power state does not change, skip DB writing. vm id: " + instance.getId());
-                    }
-                } else {
-                    s_logger.debug("vm id: " + instance.getId() + " - time since last state update(" + milliSecondsSinceLastStateUpdate + "ms) has not passed graceful period yet");
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Done with process of VM state report. host: " + hostId);
-    }
-
-    @Override
-    public Map<Long, VirtualMachine.PowerState> convertVmStateReport(Map<String, HostVmStateReportEntry> states) {
-        final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<Long, VirtualMachine.PowerState>();
-        if (states == null) {
-            return map;
-        }
-
-        for (Map.Entry<String, HostVmStateReportEntry> entry : states.entrySet()) {
-            VMInstanceVO vm = findVM(entry.getKey());
-            if (vm != null) {
-                map.put(vm.getId(), entry.getValue().getState());
-            } else {
-                s_logger.info("Unable to find matched VM in CloudStack DB. name: " + entry.getKey());
-            }
-        }
-
-        return map;
-    }
-
-    private VMInstanceVO findVM(String vmName) {
-        return _instanceDao.findVMByInstanceName(vmName);
-    }
-}
diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/AgentAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/AgentAttache.java
diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java
new file mode 100644
index 0000000..6091131
--- /dev/null
+++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/AgentManagerImpl.java
@@ -0,0 +1,1791 @@
+// 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.manager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.channels.ClosedChannelException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.agent.lb.IndirectAgentLB;
+import org.apache.cloudstack.ca.CAManager;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+import org.slf4j.MDC;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.StartupCommandProcessor;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingAnswer;
+import com.cloud.agent.api.PingCommand;
+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;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.agent.transport.Request;
+import com.cloud.agent.transport.Response;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.ManagementServiceConfiguration;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.UnsupportedVersionException;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.Status.Event;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.HypervisorVersionChangedException;
+import com.cloud.utils.exception.NioConnectionException;
+import com.cloud.utils.exception.TaskExecutionException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.nio.HandlerFactory;
+import com.cloud.utils.nio.Link;
+import com.cloud.utils.nio.NioServer;
+import com.cloud.utils.nio.Task;
+import com.cloud.utils.time.InaccurateClock;
+import com.google.common.base.Strings;
+
+/**
+ * Implementation of the Agent Manager. This class controls the connection to the agents.
+ **/
+public class AgentManagerImpl extends ManagerBase implements AgentManager, HandlerFactory, Configurable {
+    protected static final Logger s_logger = Logger.getLogger(AgentManagerImpl.class);
+
+    /**
+     * _agents is a ConcurrentHashMap, but it is used from within a synchronized block. This will be reported by findbugs as JLM_JSR166_UTILCONCURRENT_MONITORENTER. Maybe a
+     * ConcurrentHashMap is not the right thing to use here, but i'm not sure so i leave it alone.
+     */
+    protected ConcurrentHashMap<Long, AgentAttache> _agents = new ConcurrentHashMap<Long, AgentAttache>(10007);
+    protected List<Pair<Integer, Listener>> _hostMonitors = new ArrayList<Pair<Integer, Listener>>(17);
+    protected List<Pair<Integer, Listener>> _cmdMonitors = new ArrayList<Pair<Integer, Listener>>(17);
+    protected List<Pair<Integer, StartupCommandProcessor>> _creationMonitors = new ArrayList<Pair<Integer, StartupCommandProcessor>>(17);
+    protected List<Long> _loadingAgents = new ArrayList<Long>();
+    private int _monitorId = 0;
+    private final Lock _agentStatusLock = new ReentrantLock();
+
+    @Inject
+    protected CAManager caService;
+    @Inject
+    protected EntityManager _entityMgr;
+
+    protected NioServer _connection;
+    @Inject
+    protected HostDao _hostDao = null;
+    @Inject
+    protected OutOfBandManagementDao outOfBandManagementDao;
+    @Inject
+    protected DataCenterDao _dcDao = null;
+    @Inject
+    protected HostPodDao _podDao = null;
+    @Inject
+    protected ConfigurationDao _configDao = null;
+    @Inject
+    protected ClusterDao _clusterDao = null;
+
+    @Inject
+    protected HighAvailabilityManager _haMgr = null;
+    @Inject
+    protected AlertManager _alertMgr = null;
+
+    @Inject
+    protected HypervisorGuruManager _hvGuruMgr;
+
+    @Inject
+    protected IndirectAgentLB indirectAgentLB;
+
+    protected int _retry = 2;
+
+    protected long _nodeId = -1;
+
+    protected ExecutorService _executor;
+    protected ThreadPoolExecutor _connectExecutor;
+    protected ScheduledExecutorService _directAgentExecutor;
+    protected ScheduledExecutorService _cronJobExecutor;
+    protected ScheduledExecutorService _monitorExecutor;
+
+    private int _directAgentThreadCap;
+
+    protected StateMachine2<Status, Status.Event, Host> _statusStateMachine = Status.getStateMachine();
+    private final ConcurrentHashMap<Long, Long> _pingMap = new ConcurrentHashMap<Long, Long>(10007);
+
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    ManagementServiceConfiguration mgmtServiceConf;
+
+    protected final ConfigKey<Integer> Workers = new ConfigKey<Integer>("Advanced", Integer.class, "workers", "5",
+            "Number of worker threads handling remote agent connections.", false);
+    protected final ConfigKey<Integer> Port = new ConfigKey<Integer>("Advanced", Integer.class, "port", "8250", "Port to listen on for remote agent connections.", false);
+    protected final ConfigKey<Integer> AlertWait = new ConfigKey<Integer>("Advanced", Integer.class, "alert.wait", "1800",
+            "Seconds to wait before alerting on a disconnected agent", true);
+    protected final ConfigKey<Integer> DirectAgentLoadSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.load.size", "16",
+            "The number of direct agents to load each time", false);
+    protected final ConfigKey<Integer> DirectAgentPoolSize = new ConfigKey<Integer>("Advanced", Integer.class, "direct.agent.pool.size", "500",
+            "Default size for DirectAgentPool", false);
+    protected final ConfigKey<Float> DirectAgentThreadCap = new ConfigKey<Float>("Advanced", Float.class, "direct.agent.thread.cap", "1",
+            "Percentage (as a value between 0 and 1) of direct.agent.pool.size to be used as upper thread cap for a single direct agent to process requests", false);
+    protected final ConfigKey<Boolean> CheckTxnBeforeSending = new ConfigKey<Boolean>("Developer", Boolean.class, "check.txn.before.sending.agent.commands", "false",
+            "This parameter allows developers to enable a check to see if a transaction wraps commands that are sent to the resource.  This is not to be enabled on production systems.", true);
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+
+        s_logger.info("Ping Timeout is " + mgmtServiceConf.getPingTimeout());
+
+        final int threads = DirectAgentLoadSize.value();
+
+        _nodeId = ManagementServerNode.getManagementServerId();
+        s_logger.info("Configuring AgentManagerImpl. management server node id(msid): " + _nodeId);
+
+        final long lastPing = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
+        _hostDao.markHostsAsDisconnected(_nodeId, lastPing);
+
+        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"));
+        // allow core threads to time out even when there are no items in the queue
+        _connectExecutor.allowCoreThreadTimeOut(true);
+
+        _connection = new NioServer("AgentManager", Port.value(), Workers.value() + 10, this, caService);
+        s_logger.info("Listening on " + Port.value() + " with " + Workers.value() + " workers");
+
+        // executes all agent commands other than cron and ping
+        _directAgentExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgent"));
+        // executes cron and ping agent commands
+        _cronJobExecutor = new ScheduledThreadPoolExecutor(DirectAgentPoolSize.value(), new NamedThreadFactory("DirectAgentCronJob"));
+        s_logger.debug("Created DirectAgentAttache pool with size: " + DirectAgentPoolSize.value());
+        _directAgentThreadCap = Math.round(DirectAgentPoolSize.value() * DirectAgentThreadCap.value()) + 1; // add 1 to always make the value > 0
+
+        _monitorExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("AgentMonitor"));
+
+        return true;
+    }
+
+    @Override
+    public Task create(final Task.Type type, final Link link, final byte[] data) {
+        return new AgentHandler(type, link, data);
+    }
+
+    @Override
+    public int registerForHostEvents(final Listener listener, final boolean connections, final boolean commands, final boolean priority) {
+        synchronized (_hostMonitors) {
+            _monitorId++;
+            if (connections) {
+                if (priority) {
+                    _hostMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
+                } else {
+                    _hostMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
+                }
+            }
+            if (commands) {
+                if (priority) {
+                    _cmdMonitors.add(0, new Pair<Integer, Listener>(_monitorId, listener));
+                } else {
+                    _cmdMonitors.add(new Pair<Integer, Listener>(_monitorId, listener));
+                }
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Registering listener " + listener.getClass().getSimpleName() + " with id " + _monitorId);
+            }
+            return _monitorId;
+        }
+    }
+
+    @Override
+    public int registerForInitialConnects(final StartupCommandProcessor creator, final boolean priority) {
+        synchronized (_hostMonitors) {
+            _monitorId++;
+            if (priority) {
+                _creationMonitors.add(0, new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
+            } else {
+                _creationMonitors.add(new Pair<Integer, StartupCommandProcessor>(_monitorId, creator));
+            }
+            return _monitorId;
+        }
+    }
+
+    @Override
+    public void unregisterForHostEvents(final int id) {
+        s_logger.debug("Deregistering " + id);
+        _hostMonitors.remove(id);
+    }
+
+    private AgentControlAnswer handleControlCommand(final AgentAttache attache, final AgentControlCommand cmd) {
+        AgentControlAnswer answer = null;
+
+        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
+            answer = listener.second().processControlCommand(attache.getId(), cmd);
+
+            if (answer != null) {
+                return answer;
+            }
+        }
+
+        s_logger.warn("No handling of agent control command: " + cmd + " sent from " + attache.getId());
+        return new AgentControlAnswer(cmd);
+    }
+
+    public void handleCommands(final AgentAttache attache, final long sequence, final Command[] cmds) {
+        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
+            final boolean processed = listener.second().processCommands(attache.getId(), sequence, cmds);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("SeqA " + attache.getId() + "-" + sequence + ": " + (processed ? "processed" : "not processed") + " by " + listener.getClass());
+            }
+        }
+    }
+
+    public void notifyAnswersToMonitors(final long agentId, final long seq, final Answer[] answers) {
+        for (final Pair<Integer, Listener> listener : _cmdMonitors) {
+            listener.second().processAnswers(agentId, seq, answers);
+        }
+    }
+
+    public AgentAttache findAttache(final long hostId) {
+        AgentAttache attache = null;
+        synchronized (_agents) {
+            attache = _agents.get(hostId);
+        }
+        return attache;
+    }
+
+    @Override
+    public Answer sendTo(final Long dcId, final HypervisorType type, final Command cmd) {
+        final List<ClusterVO> clusters = _clusterDao.listByDcHyType(dcId, type.toString());
+        int retry = 0;
+        for (final ClusterVO cluster : clusters) {
+            final List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), null, dcId);
+            for (final HostVO host : hosts) {
+                retry++;
+                if (retry > _retry) {
+                    return null;
+                }
+                Answer answer = null;
+                try {
+
+                    final long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(host.getId(), cmd);
+                    answer = easySend(targetHostId, cmd);
+                } catch (final Exception e) {
+                }
+                if (answer != null) {
+                    return answer;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Answer send(final Long hostId, final Command cmd) throws AgentUnavailableException, OperationTimedoutException {
+        final Commands cmds = new Commands(Command.OnError.Stop);
+        cmds.addCommand(cmd);
+        send(hostId, cmds, cmd.getWait());
+        final Answer[] answers = cmds.getAnswers();
+        if (answers != null && !(answers[0] instanceof UnsupportedAnswer)) {
+            return answers[0];
+        }
+
+        if (answers != null && answers[0] instanceof UnsupportedAnswer) {
+            s_logger.warn("Unsupported Command: " + answers[0].getDetails());
+            return answers[0];
+        }
+
+        return null;
+    }
+
+    @DB
+    protected boolean noDbTxn() {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        return !txn.dbTxnStarted();
+    }
+
+    private static void tagCommand(final Command cmd) {
+        final AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrent();
+        if (context != null && context.getJob() != null) {
+            final AsyncJob job = context.getJob();
+
+            if (job.getRelated() != null && !job.getRelated().isEmpty()) {
+                cmd.setContextParam("job", "job-" + job.getRelated() + "/" + "job-" + job.getId());
+            } else {
+                cmd.setContextParam("job", "job-" + job.getId());
+            }
+        }
+        if (MDC.get("logcontextid") != null && !MDC.get("logcontextid").isEmpty()) {
+            cmd.setContextParam("logid", MDC.get("logcontextid"));
+        }
+    }
+
+    /**
+     * @param commands
+     * @return
+     */
+    private Command[] checkForCommandsAndTag(final Commands commands) {
+        final Command[] cmds = commands.toCommands();
+
+        assert cmds.length > 0 : "Ask yourself this about a hundred times.  Why am I  sending zero length commands?";
+
+        setEmptyAnswers(commands, cmds);
+
+        for (final Command cmd : cmds) {
+            tagCommand(cmd);
+        }
+        return cmds;
+    }
+
+    /**
+     * @param commands
+     * @param cmds
+     */
+    private void setEmptyAnswers(final Commands commands, final Command[] cmds) {
+        if (cmds.length == 0) {
+            commands.setAnswers(new Answer[0]);
+        }
+    }
+
+    @Override
+    public Answer[] send(final Long hostId, final Commands commands, int timeout) throws AgentUnavailableException, OperationTimedoutException {
+        assert hostId != null : "Who's not checking the agent id before sending?  ... (finger wagging)";
+        if (hostId == null) {
+            throw new AgentUnavailableException(-1);
+        }
+
+        if (timeout <= 0) {
+            timeout = Wait.value();
+        }
+
+        if (CheckTxnBeforeSending.value()) {
+            if (!noDbTxn()) {
+                throw new CloudRuntimeException("We do not allow transactions to be wrapped around commands sent to be executed on remote agents.  "
+                        + "We cannot predict how long it takes a command to complete.  " + "The transaction may be rolled back because the connection took too long.");
+            }
+        } else {
+            assert noDbTxn() : "I know, I know.  Why are we so strict as to not allow txn across an agent call?  ...  Why are we so cruel ... Why are we such a dictator .... Too bad... Sorry...but NO AGENT COMMANDS WRAPPED WITHIN DB TRANSACTIONS!";
+        }
+
+        final Command[] cmds = checkForCommandsAndTag(commands);
+
+        //check what agent is returned.
+        final AgentAttache agent = getAttache(hostId);
+        if (agent == null || agent.isClosed()) {
+            throw new AgentUnavailableException("agent not logged into this management server", hostId);
+        }
+
+        final Request req = new Request(hostId, agent.getName(), _nodeId, cmds, commands.stopOnError(), true);
+        req.setSequence(agent.getNextSequence());
+        final Answer[] answers = agent.send(req, timeout);
+        notifyAnswersToMonitors(hostId, req.getSequence(), answers);
+        commands.setAnswers(answers);
+        return answers;
+    }
+
+    protected Status investigate(final AgentAttache agent) {
+        final Long hostId = agent.getId();
+        final HostVO host = _hostDao.findById(hostId);
+        if (host != null && host.getType() != null && !host.getType().isVirtual()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("checking if agent (" + hostId + ") is alive");
+            }
+            final Answer answer = easySend(hostId, new CheckHealthCommand());
+            if (answer != null && answer.getResult()) {
+                final Status status = Status.Up;
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("agent (" + hostId + ") responded to checkHeathCommand, reporting that agent is " + status);
+                }
+                return status;
+            }
+            return _haMgr.investigate(hostId);
+        }
+        return Status.Alert;
+    }
+
+    protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
+        if (hostId == null) {
+            return null;
+        }
+        final AgentAttache agent = findAttache(hostId);
+        if (agent == null) {
+            s_logger.debug("Unable to find agent for " + hostId);
+            throw new AgentUnavailableException("Unable to find agent ", hostId);
+        }
+
+        return agent;
+    }
+
+    @Override
+    public long send(final Long hostId, final Commands commands, final Listener listener) throws AgentUnavailableException {
+        final AgentAttache agent = getAttache(hostId);
+        if (agent.isClosed()) {
+            throw new AgentUnavailableException("Agent " + agent.getId() + " is closed", agent.getId());
+        }
+
+        final Command[] cmds = checkForCommandsAndTag(commands);
+
+        final Request req = new Request(hostId, agent.getName(), _nodeId, cmds, commands.stopOnError(), true);
+        req.setSequence(agent.getNextSequence());
+
+        agent.send(req, listener);
+        return req.getSequence();
+    }
+
+    public void removeAgent(final AgentAttache attache, final Status nextState) {
+        if (attache == null) {
+            return;
+        }
+        final long hostId = attache.getId();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Remove Agent : " + hostId);
+        }
+        AgentAttache removed = null;
+        boolean conflict = false;
+        synchronized (_agents) {
+            removed = _agents.remove(hostId);
+            if (removed != null && removed != attache) {
+                conflict = true;
+                _agents.put(hostId, removed);
+                removed = attache;
+            }
+        }
+        if (conflict) {
+            s_logger.debug("Agent for host " + hostId + " is created when it is being disconnected");
+        }
+        if (removed != null) {
+            removed.disconnect(nextState);
+        }
+
+        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Sending Disconnect to listener: " + monitor.second().getClass().getName());
+            }
+            monitor.second().processDisconnect(hostId, nextState);
+        }
+    }
+
+    @Override
+    public void notifyMonitorsOfNewlyAddedHost(long hostId) {
+        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Sending host added to listener: " + monitor.second().getClass().getSimpleName());
+            }
+
+            monitor.second().processHostAdded(hostId);
+        }
+    }
+
+    protected AgentAttache notifyMonitorsOfConnection(final AgentAttache attache, final StartupCommand[] cmd, final boolean forRebalance) throws ConnectionException {
+        final long hostId = attache.getId();
+        final HostVO host = _hostDao.findById(hostId);
+        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Sending Connect to listener: " + monitor.second().getClass().getSimpleName());
+            }
+            for (int i = 0; i < cmd.length; i++) {
+                try {
+                    monitor.second().processConnect(host, cmd[i], forRebalance);
+                } catch (final Exception e) {
+                    if (e instanceof ConnectionException) {
+                        final ConnectionException ce = (ConnectionException)e;
+                        if (ce.isSetupError()) {
+                            s_logger.warn("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage());
+                            handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
+                            throw ce;
+                        } else {
+                            s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId + " due to " + e.getMessage());
+                            handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true);
+                            return attache;
+                        }
+                    } else if (e instanceof HypervisorVersionChangedException) {
+                        handleDisconnectWithoutInvestigation(attache, Event.ShutdownRequested, true, true);
+                        throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
+                    } else {
+                        s_logger.error("Monitor " + monitor.second().getClass().getSimpleName() + " says there is an error in the connect process for " + hostId + " due to " + e.getMessage(), e);
+                        handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
+                        throw new CloudRuntimeException("Unable to connect " + attache.getId(), e);
+                    }
+                }
+            }
+        }
+
+        final Long dcId = host.getDataCenterId();
+        final ReadyCommand ready = new ReadyCommand(dcId, host.getId());
+        final Answer answer = easySend(hostId, ready);
+        if (answer == null || !answer.getResult()) {
+            // this is tricky part for secondary storage
+            // make it as disconnected, wait for secondary storage VM to be up
+            // return the attache instead of null, even it is disconnectede
+            handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
+        }
+
+        agentStatusTransitTo(host, Event.Ready, _nodeId);
+        attache.ready();
+        return attache;
+    }
+
+    @Override
+    public boolean start() {
+        startDirectlyConnectedHosts();
+
+        if (_connection != null) {
+            try {
+                _connection.start();
+            } catch (final NioConnectionException e) {
+                s_logger.error("Error when connecting to the NioServer!", e);
+            }
+        }
+
+        _monitorExecutor.scheduleWithFixedDelay(new MonitorTask(), mgmtServiceConf.getPingInterval(), mgmtServiceConf.getPingInterval(), TimeUnit.SECONDS);
+
+        return true;
+    }
+
+    public void startDirectlyConnectedHosts() {
+        final List<HostVO> hosts = _resourceMgr.findDirectlyConnectedHosts();
+        for (final HostVO host : hosts) {
+            loadDirectlyConnectedHost(host, false);
+        }
+    }
+
+    private ServerResource loadResourcesWithoutHypervisor(final HostVO host) {
+        final String resourceName = host.getResource();
+        ServerResource resource = null;
+        try {
+            final Class<?> clazz = Class.forName(resourceName);
+            final Constructor<?> constructor = clazz.getConstructor();
+            resource = (ServerResource)constructor.newInstance();
+        } catch (final ClassNotFoundException e) {
+            s_logger.warn("Unable to find class " + host.getResource(), e);
+        } catch (final InstantiationException e) {
+            s_logger.warn("Unablet to instantiate class " + host.getResource(), e);
+        } catch (final IllegalAccessException e) {
+            s_logger.warn("Illegal access " + host.getResource(), e);
+        } catch (final SecurityException e) {
+            s_logger.warn("Security error on " + host.getResource(), e);
+        } catch (final NoSuchMethodException e) {
+            s_logger.warn("NoSuchMethodException error on " + host.getResource(), e);
+        } catch (final IllegalArgumentException e) {
+            s_logger.warn("IllegalArgumentException error on " + host.getResource(), e);
+        } catch (final InvocationTargetException e) {
+            s_logger.warn("InvocationTargetException error on " + host.getResource(), e);
+        }
+
+        if (resource != null) {
+            _hostDao.loadDetails(host);
+
+            final HashMap<String, Object> params = new HashMap<String, Object>(host.getDetails().size() + 5);
+            params.putAll(host.getDetails());
+
+            params.put("guid", host.getGuid());
+            params.put("zone", Long.toString(host.getDataCenterId()));
+            if (host.getPodId() != null) {
+                params.put("pod", Long.toString(host.getPodId()));
+            }
+            if (host.getClusterId() != null) {
+                params.put("cluster", Long.toString(host.getClusterId()));
+                String guid = null;
+                final ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+                if (cluster.getGuid() == null) {
+                    guid = host.getDetail("pool");
+                } else {
+                    guid = cluster.getGuid();
+                }
+                if (guid != null && !guid.isEmpty()) {
+                    params.put("pool", guid);
+                }
+            }
+
+            params.put("ipaddress", host.getPrivateIpAddress());
+            params.put("secondary.storage.vm", "false");
+
+            try {
+                resource.configure(host.getName(), params);
+            } catch (final ConfigurationException e) {
+                s_logger.warn("Unable to configure resource due to " + e.getMessage());
+                return null;
+            }
+
+            if (!resource.start()) {
+                s_logger.warn("Unable to start the resource");
+                return null;
+            }
+        }
+        return resource;
+    }
+
+    @Override
+    public void rescan() {
+    }
+
+    protected boolean loadDirectlyConnectedHost(final HostVO host, final boolean forRebalance) {
+        boolean initialized = false;
+        ServerResource resource = null;
+        try {
+            // load the respective discoverer
+            final Discoverer discoverer = _resourceMgr.getMatchingDiscover(host.getHypervisorType());
+            if (discoverer == null) {
+                s_logger.info("Could not to find a Discoverer to load the resource: " + host.getId() + " for hypervisor type: " + host.getHypervisorType());
+                resource = loadResourcesWithoutHypervisor(host);
+            } else {
+                resource = discoverer.reloadResource(host);
+            }
+
+            if (resource == null) {
+                s_logger.warn("Unable to load the resource: " + host.getId());
+                return false;
+            }
+
+            initialized = true;
+        } finally {
+            if (!initialized) {
+                if (host != null) {
+                    agentStatusTransitTo(host, Event.AgentDisconnected, _nodeId);
+                }
+            }
+        }
+
+        if (forRebalance) {
+            tapLoadingAgents(host.getId(), TapAgentsAction.Add);
+            final Host h = _resourceMgr.createHostAndAgent(host.getId(), resource, host.getDetails(), false, null, true);
+            tapLoadingAgents(host.getId(), TapAgentsAction.Del);
+
+            return h == null ? false : true;
+        } else {
+            _executor.execute(new SimulateStartTask(host.getId(), resource, host.getDetails()));
+            return true;
+        }
+    }
+
+    protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) throws ConnectionException {
+        s_logger.debug("create DirectAgentAttache for " + host.getId());
+        final DirectAgentAttache attache = new DirectAgentAttache(this, host.getId(), host.getName(), resource, host.isInMaintenanceStates());
+
+        AgentAttache old = null;
+        synchronized (_agents) {
+            old = _agents.put(host.getId(), attache);
+        }
+        if (old != null) {
+            old.disconnect(Status.Removed);
+        }
+
+        return attache;
+    }
+
+    @Override
+    public boolean stop() {
+
+        if (_connection != null) {
+            _connection.stop();
+        }
+
+        s_logger.info("Disconnecting agents: " + _agents.size());
+        synchronized (_agents) {
+            for (final AgentAttache agent : _agents.values()) {
+                final HostVO host = _hostDao.findById(agent.getId());
+                if (host == null) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cant not find host " + agent.getId());
+                    }
+                } else {
+                    if (!agent.forForward()) {
+                        agentStatusTransitTo(host, Event.ManagementServerDown, _nodeId);
+                    }
+                }
+            }
+        }
+
+        _connectExecutor.shutdownNow();
+        _monitorExecutor.shutdownNow();
+        return true;
+    }
+
+    protected boolean handleDisconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event, final boolean transitState, final boolean removeAgent) {
+        final long hostId = attache.getId();
+
+        s_logger.info("Host " + hostId + " is disconnecting with event " + event);
+        Status nextStatus = null;
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            s_logger.warn("Can't find host with " + hostId);
+            nextStatus = Status.Removed;
+        } else {
+            final Status currentStatus = host.getStatus();
+            if (currentStatus == Status.Down || currentStatus == Status.Alert || currentStatus == Status.Removed) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Host " + hostId + " is already " + currentStatus);
+                }
+                nextStatus = currentStatus;
+            } else {
+                try {
+                    nextStatus = currentStatus.getNextStatus(event);
+                } catch (final NoTransitionException e) {
+                    final String err = "Cannot find next status for " + event + " as current status is " + currentStatus + " for agent " + hostId;
+                    s_logger.debug(err);
+                    throw new CloudRuntimeException(err);
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("The next status of agent " + hostId + "is " + nextStatus + ", current status is " + currentStatus);
+                }
+            }
+            caService.purgeHostCertificate(host);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deregistering link for " + hostId + " with state " + nextStatus);
+        }
+
+        removeAgent(attache, nextStatus);
+        // update the DB
+        if (host != null && transitState) {
+            disconnectAgent(host, event, _nodeId);
+        }
+
+        return true;
+    }
+
+    protected boolean handleDisconnectWithInvestigation(final AgentAttache attache, Status.Event event) {
+        final long hostId = attache.getId();
+        HostVO host = _hostDao.findById(hostId);
+
+        if (host != null) {
+            Status nextStatus = null;
+            try {
+                nextStatus = host.getStatus().getNextStatus(event);
+            } catch (final NoTransitionException ne) {
+                /*
+                 * Agent may be currently in status of Down, Alert, Removed, namely there is no next status for some events. Why this can happen? Ask God not me. I hate there was
+                 * no piece of comment for code handling race condition. God knew what race condition the code dealt with!
+                 */
+                s_logger.debug("Caught exception while getting agent's next status", ne);
+            }
+
+            if (nextStatus == Status.Alert) {
+                /* OK, we are going to the bad status, let's see what happened */
+                s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event);
+
+                Status determinedState = investigate(attache);
+                // if state cannot be determined do nothing and bail out
+                if (determinedState == null) {
+                    if ((System.currentTimeMillis() >> 10) - host.getLastPinged() > AlertWait.value()) {
+                        s_logger.warn("Agent " + hostId + " state cannot be determined for more than " + AlertWait + "(" + AlertWait.value() + ") seconds, will go to Alert state");
+                        determinedState = Status.Alert;
+                    } else {
+                        s_logger.warn("Agent " + hostId + " state cannot be determined, do nothing");
+                        return false;
+                    }
+                }
+
+                final Status currentStatus = host.getStatus();
+                s_logger.info("The agent from host " + hostId + " state determined is " + determinedState);
+
+                if (determinedState == Status.Down) {
+                    final String message = "Host is down: " + host.getId() + "-" + host.getName() + ". Starting HA on the VMs";
+                    s_logger.error(message);
+                    if (host.getType() != Host.Type.SecondaryStorage && host.getType() != Host.Type.ConsoleProxy) {
+                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host down, " + host.getId(), message);
+                    }
+                    event = Status.Event.HostDown;
+                } else if (determinedState == Status.Up) {
+                    /* Got ping response from host, bring it back */
+                    s_logger.info("Agent is determined to be up and running");
+                    agentStatusTransitTo(host, Status.Event.Ping, _nodeId);
+                    return false;
+                } else if (determinedState == Status.Disconnected) {
+                    s_logger.warn("Agent is disconnected but the host is still up: " + host.getId() + "-" + host.getName());
+                    if (currentStatus == Status.Disconnected) {
+                        if ((System.currentTimeMillis() >> 10) - host.getLastPinged() > AlertWait.value()) {
+                            s_logger.warn("Host " + host.getId() + " has been disconnected past the wait time it should be disconnected.");
+                            event = Status.Event.WaitedTooLong;
+                        } else {
+                            s_logger.debug("Host " + host.getId() + " has been determined to be disconnected but it hasn't passed the wait time yet.");
+                            return false;
+                        }
+                    } else if (currentStatus == Status.Up) {
+                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+                        final HostPodVO podVO = _podDao.findById(host.getPodId());
+                        final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+                        if (host.getType() != Host.Type.SecondaryStorage && host.getType() != Host.Type.ConsoleProxy) {
+                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host disconnected, " + hostDesc,
+                                    "If the agent for host [" + hostDesc + "] is not restarted within " + AlertWait + " seconds, host will go to Alert state");
+                        }
+                        event = Status.Event.AgentDisconnected;
+                    }
+                } else {
+                    // if we end up here we are in alert state, send an alert
+                    final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+                    final HostPodVO podVO = _podDao.findById(host.getPodId());
+                    final String podName = podVO != null ? podVO.getName() : "NO POD";
+                    final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podName;
+                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host in ALERT state, " + hostDesc,
+                            "In availability zone " + host.getDataCenterId() + ", host is in alert state: " + host.getId() + "-" + host.getName());
+                }
+            } else {
+                s_logger.debug("The next status of agent " + host.getId() + " is not Alert, no need to investigate what happened");
+            }
+        }
+        handleDisconnectWithoutInvestigation(attache, event, true, true);
+        host = _hostDao.findById(hostId); // Maybe the host magically reappeared?
+        if (host != null && host.getStatus() == Status.Down) {
+            _haMgr.scheduleRestartForVmsOnHost(host, true);
+        }
+        return true;
+    }
+
+    protected class DisconnectTask extends ManagedContextRunnable {
+        AgentAttache _attache;
+        Status.Event _event;
+        boolean _investigate;
+
+        DisconnectTask(final AgentAttache attache, final Status.Event event, final boolean investigate) {
+            _attache = attache;
+            _event = event;
+            _investigate = investigate;
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                if (_investigate == true) {
+                    handleDisconnectWithInvestigation(_attache, _event);
+                } else {
+                    handleDisconnectWithoutInvestigation(_attache, _event, true, false);
+                }
+            } catch (final Exception e) {
+                s_logger.error("Exception caught while handling disconnect: ", e);
+            }
+        }
+    }
+
+    @Override
+    public Answer easySend(final Long hostId, final Command cmd) {
+        try {
+            final Host h = _hostDao.findById(hostId);
+            if (h == null || h.getRemoved() != null) {
+                s_logger.debug("Host with id " + hostId + " doesn't exist");
+                return null;
+            }
+            final Status status = h.getStatus();
+            if (!status.equals(Status.Up) && !status.equals(Status.Connecting)) {
+                s_logger.debug("Can not send command " + cmd + " due to Host " + hostId + " is not up");
+                return null;
+            }
+            final Answer answer = send(hostId, cmd);
+            if (answer == null) {
+                s_logger.warn("send returns null answer");
+                return null;
+            }
+
+            if (s_logger.isDebugEnabled() && answer.getDetails() != null) {
+                s_logger.debug("Details from executing " + cmd.getClass() + ": " + answer.getDetails());
+            }
+
+            return answer;
+
+        } catch (final AgentUnavailableException e) {
+            s_logger.warn(e.getMessage());
+            return null;
+        } catch (final OperationTimedoutException e) {
+            s_logger.warn("Operation timed out: " + e.getMessage());
+            return null;
+        } catch (final Exception e) {
+            s_logger.warn("Exception while sending", e);
+            return null;
+        }
+    }
+
+    @Override
+    public Answer[] send(final Long hostId, final Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
+        int wait = 0;
+        for (final Command cmd : cmds) {
+            if (cmd.getWait() > wait) {
+                wait = cmd.getWait();
+            }
+        }
+        return send(hostId, cmds, wait);
+    }
+
+    @Override
+    public void reconnect(final long hostId) throws AgentUnavailableException {
+        HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new CloudRuntimeException("Unable to find host: " + hostId);
+        }
+
+        if (host.getRemoved() != null) {
+            throw new CloudRuntimeException("Host has already been removed: " + hostId);
+        }
+
+        if (host.getStatus() == Status.Disconnected) {
+            s_logger.debug("Host is already disconnected, no work to be done: " + hostId);
+            return;
+        }
+
+        if (host.getStatus() != Status.Up && host.getStatus() != Status.Alert && host.getStatus() != Status.Rebalancing) {
+            throw new CloudRuntimeException("Unable to disconnect host because it is not in the correct state: host=" + hostId + "; Status=" + host.getStatus());
+        }
+
+        AgentAttache attache = findAttache(hostId);
+        if (attache == null) {
+            throw new CloudRuntimeException("Unable to disconnect host because it is not connected to this server: " + hostId);
+        }
+        disconnectWithoutInvestigation(attache, Event.ShutdownRequested);
+    }
+
+    @Override
+    public void notifyMonitorsOfHostAboutToBeRemoved(long hostId) {
+        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Sending host about to be removed to listener: " + monitor.second().getClass().getSimpleName());
+            }
+
+            monitor.second().processHostAboutToBeRemoved(hostId);
+        }
+    }
+
+    @Override
+    public void notifyMonitorsOfRemovedHost(long hostId, long clusterId) {
+        for (final Pair<Integer, Listener> monitor : _hostMonitors) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Sending host removed to listener: " + monitor.second().getClass().getSimpleName());
+            }
+
+            monitor.second().processHostRemoved(hostId, clusterId);
+        }
+    }
+
+    public boolean executeUserRequest(final long hostId, final Event event) throws AgentUnavailableException {
+        if (event == Event.AgentDisconnected) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Received agent disconnect event for host " + hostId);
+            }
+            AgentAttache attache = null;
+            attache = findAttache(hostId);
+            if (attache != null) {
+                handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, true, true);
+            }
+            return true;
+        }
+        if (event == Event.ShutdownRequested) {
+            try {
+                reconnect(hostId);
+            } catch (CloudRuntimeException e) {
+                s_logger.debug("Error on shutdown request for hostID: " + hostId, e);
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isAgentAttached(final long hostId) {
+        final AgentAttache agentAttache = findAttache(hostId);
+        return agentAttache != null;
+    }
+
+    protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) throws ConnectionException {
+        s_logger.debug("create ConnectedAgentAttache for " + host.getId());
+        final AgentAttache attache = new ConnectedAgentAttache(this, host.getId(), host.getName(), link, host.isInMaintenanceStates());
+        link.attach(attache);
+
+        AgentAttache old = null;
+        synchronized (_agents) {
+            old = _agents.put(host.getId(), attache);
+        }
+        if (old != null) {
+            old.disconnect(Status.Removed);
+        }
+
+        return attache;
+    }
+
+    private AgentAttache handleConnectedAgent(final Link link, final StartupCommand[] startup, final Request request) {
+        AgentAttache attache = null;
+        ReadyCommand ready = null;
+        try {
+            final List<String> agentMSHostList = new ArrayList<>();
+            if (startup != null && startup.length > 0) {
+                final String agentMSHosts = startup[0].getMsHostList();
+                if (!Strings.isNullOrEmpty(agentMSHosts)) {
+                    agentMSHostList.addAll(Arrays.asList(agentMSHosts.split(",")));
+                }
+            }
+
+            final HostVO host = _resourceMgr.createHostVOForConnectedAgent(startup);
+            if (host != null) {
+                ready = new ReadyCommand(host.getDataCenterId(), host.getId());
+
+                if (!indirectAgentLB.compareManagementServerList(host.getId(), host.getDataCenterId(), agentMSHostList)) {
+                    final List<String> newMSList = indirectAgentLB.getManagementServerList(host.getId(), host.getDataCenterId(), null);
+                    ready.setMsHostList(newMSList);
+                    ready.setLbAlgorithm(indirectAgentLB.getLBAlgorithmName());
+                    ready.setLbCheckInterval(indirectAgentLB.getLBPreferredHostCheckInterval(host.getClusterId()));
+                    s_logger.debug("Agent's management server host list is not up to date, sending list update:" + newMSList);
+                }
+
+                attache = createAttacheForConnect(host, link);
+                attache = notifyMonitorsOfConnection(attache, startup, false);
+            }
+        } catch (final Exception e) {
+            s_logger.debug("Failed to handle host connection: ", e);
+            ready = new ReadyCommand(null);
+            ready.setDetails(e.toString());
+        } finally {
+            if (ready == null) {
+                ready = new ReadyCommand(null);
+            }
+        }
+
+        try {
+            if (attache == null) {
+                final Request readyRequest = new Request(-1, -1, ready, false);
+                link.send(readyRequest.getBytes());
+            } else {
+                easySend(attache.getId(), ready);
+            }
+        } catch (final Exception e) {
+            s_logger.debug("Failed to send ready command:" + e.toString());
+        }
+        return attache;
+    }
+
+    protected class SimulateStartTask extends ManagedContextRunnable {
+        ServerResource resource;
+        Map<String, String> details;
+        long id;
+
+        public SimulateStartTask(final long id, final ServerResource resource, final Map<String, String> details) {
+            this.id = id;
+            this.resource = resource;
+            this.details = details;
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Simulating start for resource " + resource.getName() + " id " + id);
+                }
+
+                if (tapLoadingAgents(id, TapAgentsAction.Add)) {
+                    try {
+                        final AgentAttache agentattache = findAttache(id);
+                        if (agentattache == null) {
+                            s_logger.debug("Creating agent for host " + id);
+                            _resourceMgr.createHostAndAgent(id, resource, details, false, null, false);
+                            s_logger.debug("Completed creating agent for host " + id);
+                        } else {
+                            s_logger.debug("Agent already created in another thread for host " + id + ", ignore this");
+                        }
+                    } finally {
+                        tapLoadingAgents(id, TapAgentsAction.Del);
+                    }
+                } else {
+                    s_logger.debug("Agent creation already getting processed in another thread for host " + id + ", ignore this");
+                }
+            } catch (final Exception e) {
+                s_logger.warn("Unable to simulate start on resource " + id + " name " + resource.getName(), e);
+            }
+        }
+    }
+
+    protected class HandleAgentConnectTask extends ManagedContextRunnable {
+        Link _link;
+        Command[] _cmds;
+        Request _request;
+
+        HandleAgentConnectTask(final Link link, final Command[] cmds, final Request request) {
+            _link = link;
+            _cmds = cmds;
+            _request = request;
+        }
+
+        @Override
+        protected void runInContext() {
+            _request.logD("Processing the first command ");
+            final StartupCommand[] startups = new StartupCommand[_cmds.length];
+            for (int i = 0; i < _cmds.length; i++) {
+                startups[i] = (StartupCommand)_cmds[i];
+            }
+
+            final AgentAttache attache = handleConnectedAgent(_link, startups, _request);
+            if (attache == null) {
+                s_logger.warn("Unable to create attache for agent: " + _request);
+            }
+        }
+    }
+
+    protected void connectAgent(final Link link, final Command[] cmds, final Request request) {
+        // send startupanswer to agent in the very beginning, so agent can move on without waiting for the answer for an undetermined time, if we put this logic into another
+        // thread pool.
+        final StartupAnswer[] answers = new StartupAnswer[cmds.length];
+        Command cmd;
+        for (int i = 0; i < cmds.length; i++) {
+            cmd = cmds[i];
+            if (cmd instanceof StartupRoutingCommand || cmd instanceof StartupProxyCommand || cmd instanceof StartupSecondaryStorageCommand ||
+                    cmd instanceof StartupStorageCommand) {
+                answers[i] = new StartupAnswer((StartupCommand) cmds[i], 0, mgmtServiceConf.getPingInterval());
+                break;
+            }
+        }
+        Response response = null;
+        response = new Response(request, answers[0], _nodeId, -1);
+        try {
+            link.send(response.toBytes());
+        } catch (final ClosedChannelException e) {
+            s_logger.debug("Failed to send startupanswer: " + e.toString());
+        }
+        _connectExecutor.execute(new HandleAgentConnectTask(link, cmds, request));
+    }
+
+    public class AgentHandler extends Task {
+        public AgentHandler(final Task.Type type, final Link link, final byte[] data) {
+            super(type, link, data);
+        }
+
+        protected void processRequest(final Link link, final Request request) {
+            final AgentAttache attache = (AgentAttache)link.attachment();
+            final Command[] cmds = request.getCommands();
+            Command cmd = cmds[0];
+            boolean logD = true;
+
+            if (attache == null) {
+                if (!(cmd instanceof StartupCommand)) {
+                    s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request);
+                } else {
+                    // submit the task for execution
+                    request.logD("Scheduling the first command ");
+                    connectAgent(link, cmds, request);
+                }
+                return;
+            }
+
+            final long hostId = attache.getId();
+            final String hostName = attache.getName();
+
+            if (s_logger.isDebugEnabled()) {
+                if (cmd instanceof PingRoutingCommand) {
+                    logD = false;
+                    s_logger.debug("Ping from " + hostId + "(" + hostName + ")");
+                    s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
+                } else if (cmd instanceof PingCommand) {
+                    logD = false;
+                    s_logger.debug("Ping from " + hostId + "(" + hostName + ")");
+                    s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
+                } else {
+                    s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
+                }
+            }
+
+            final Answer[] answers = new Answer[cmds.length];
+            for (int i = 0; i < cmds.length; i++) {
+                cmd = cmds[i];
+                Answer answer = null;
+                try {
+                    if (cmd instanceof StartupRoutingCommand) {
+                        final StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
+                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
+                    } else if (cmd instanceof StartupProxyCommand) {
+                        final StartupProxyCommand startup = (StartupProxyCommand) cmd;
+                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
+                    } else if (cmd instanceof StartupSecondaryStorageCommand) {
+                        final StartupSecondaryStorageCommand startup = (StartupSecondaryStorageCommand) cmd;
+                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
+                    } else if (cmd instanceof StartupStorageCommand) {
+                        final StartupStorageCommand startup = (StartupStorageCommand) cmd;
+                        answer = new StartupAnswer(startup, attache.getId(), mgmtServiceConf.getPingInterval());
+                    } else if (cmd instanceof ShutdownCommand) {
+                        final ShutdownCommand shutdown = (ShutdownCommand)cmd;
+                        final String reason = shutdown.getReason();
+                        s_logger.info("Host " + attache.getId() + " has informed us that it is shutting down with reason " + reason + " and detail " + shutdown.getDetail());
+                        if (reason.equals(ShutdownCommand.Update)) {
+                            // disconnectWithoutInvestigation(attache, Event.UpdateNeeded);
+                            throw new CloudRuntimeException("Agent update not implemented");
+                        } else if (reason.equals(ShutdownCommand.Requested)) {
+                            disconnectWithoutInvestigation(attache, Event.ShutdownRequested);
+                        }
+                        return;
+                    } else if (cmd instanceof AgentControlCommand) {
+                        answer = handleControlCommand(attache, (AgentControlCommand)cmd);
+                    } else {
+                        handleCommands(attache, request.getSequence(), new Command[] {cmd});
+                        if (cmd instanceof PingCommand) {
+                            final long cmdHostId = ((PingCommand)cmd).getHostId();
+
+                            // if the router is sending a ping, verify the
+                            // gateway was pingable
+                            if (cmd instanceof PingRoutingCommand) {
+                                final boolean gatewayAccessible = ((PingRoutingCommand)cmd).isGatewayAccessible();
+                                final HostVO host = _hostDao.findById(Long.valueOf(cmdHostId));
+
+                                if (host != null) {
+                                    if (!gatewayAccessible) {
+                                        // alert that host lost connection to
+                                        // gateway (cannot ping the default route)
+                                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+                                        final HostPodVO podVO = _podDao.findById(host.getPodId());
+                                        final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+
+                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId(), "Host lost connection to gateway, " + hostDesc,
+                                                "Host [" + hostDesc + "] lost connection to gateway (default route) and is possibly having network connection issues.");
+                                    } else {
+                                        _alertMgr.clearAlert(AlertManager.AlertType.ALERT_TYPE_ROUTING, host.getDataCenterId(), host.getPodId());
+                                    }
+                                } else {
+                                    s_logger.debug("Not processing " + PingRoutingCommand.class.getSimpleName() + " for agent id=" + cmdHostId + "; can't find the host in the DB");
+                                }
+                            }
+                            answer = new PingAnswer((PingCommand)cmd);
+                        } else if (cmd instanceof ReadyAnswer) {
+                            final HostVO host = _hostDao.findById(attache.getId());
+                            if (host == null) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Cant not find host " + attache.getId());
+                                }
+                            }
+                            answer = new Answer(cmd);
+                        } else {
+                            answer = new Answer(cmd);
+                        }
+                    }
+                } catch (final Throwable th) {
+                    s_logger.warn("Caught: ", th);
+                    answer = new Answer(cmd, false, th.getMessage());
+                }
+                answers[i] = answer;
+            }
+
+            final Response response = new Response(request, answers, _nodeId, attache.getId());
+            if (s_logger.isDebugEnabled()) {
+                if (logD) {
+                    s_logger.debug("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
+                } else {
+                    s_logger.trace("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
+                }
+            }
+            try {
+                link.send(response.toBytes());
+            } catch (final ClosedChannelException e) {
+                s_logger.warn("Unable to send response because connection is closed: " + response);
+            }
+        }
+
+        protected void processResponse(final Link link, final Response response) {
+            final AgentAttache attache = (AgentAttache)link.attachment();
+            if (attache == null) {
+                s_logger.warn("Unable to process: " + response);
+            } else if (!attache.processAnswers(response.getSequence(), response)) {
+                s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response);
+            }
+        }
+
+        @Override
+        protected void doTask(final Task task) throws TaskExecutionException {
+            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            try {
+                final Type type = task.getType();
+                if (type == Task.Type.DATA) {
+                    final byte[] data = task.getData();
+                    try {
+                        final Request event = Request.parse(data);
+                        if (event instanceof Response) {
+                            processResponse(task.getLink(), (Response)event);
+                        } else {
+                            processRequest(task.getLink(), event);
+                        }
+                    } catch (final UnsupportedVersionException e) {
+                        s_logger.warn(e.getMessage());
+                        // upgradeAgent(task.getLink(), data, e.getReason());
+                    } catch (final ClassNotFoundException e) {
+                        final String message = String.format("Exception occured when executing taks! Error '%s'", e.getMessage());
+                        s_logger.error(message);
+                        throw new TaskExecutionException(message, e);
+                    }
+                } else if (type == Task.Type.CONNECT) {
+                } else if (type == Task.Type.DISCONNECT) {
+                    final Link link = task.getLink();
+                    final AgentAttache attache = (AgentAttache)link.attachment();
+                    if (attache != null) {
+                        disconnectWithInvestigation(attache, Event.AgentDisconnected);
+                    } else {
+                        s_logger.info("Connection from " + link.getIpAddress() + " closed but no cleanup was done.");
+                        link.close();
+                        link.terminated();
+                    }
+                }
+            } finally {
+                txn.close();
+            }
+        }
+    }
+
+    protected AgentManagerImpl() {
+    }
+
+    public boolean tapLoadingAgents(final Long hostId, final TapAgentsAction action) {
+        synchronized (_loadingAgents) {
+            if (action == TapAgentsAction.Add) {
+                if (_loadingAgents.contains(hostId)) {
+                    return false;
+                } else {
+                    _loadingAgents.add(hostId);
+                }
+            } else if (action == TapAgentsAction.Del) {
+                _loadingAgents.remove(hostId);
+            } else if (action == TapAgentsAction.Contains) {
+                return _loadingAgents.contains(hostId);
+            } else {
+                throw new CloudRuntimeException("Unkonwn TapAgentsAction " + action);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean agentStatusTransitTo(final HostVO host, final Status.Event e, final long msId) {
+        try {
+            _agentStatusLock.lock();
+            if (s_logger.isDebugEnabled()) {
+                final ResourceState state = host.getResourceState();
+                final StringBuilder msg = new StringBuilder("Transition:");
+                msg.append("[Resource state = ").append(state);
+                msg.append(", Agent event = ").append(e.toString());
+                msg.append(", Host id = ").append(host.getId()).append(", name = " + host.getName()).append("]");
+                s_logger.debug(msg);
+            }
+
+            host.setManagementServerId(msId);
+            try {
+                return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
+            } catch (final NoTransitionException e1) {
+                s_logger.debug("Cannot transit agent status with event " + e + " for host " + host.getId() + ", name=" + host.getName() + ", mangement server id is " + msId);
+                throw new CloudRuntimeException("Cannot transit agent status with event " + e + " for host " + host.getId() + ", mangement server id is " + msId + "," + e1.getMessage());
+            }
+        } finally {
+            _agentStatusLock.unlock();
+        }
+    }
+
+    public boolean disconnectAgent(final HostVO host, final Status.Event e, final long msId) {
+        host.setDisconnectedOn(new Date());
+        if (e.equals(Status.Event.Remove)) {
+            host.setGuid(null);
+            host.setClusterId(null);
+        }
+
+        return agentStatusTransitTo(host, e, msId);
+    }
+
+    protected void disconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event) {
+        _executor.submit(new DisconnectTask(attache, event, false));
+    }
+
+    public void disconnectWithInvestigation(final AgentAttache attache, final Status.Event event) {
+        _executor.submit(new DisconnectTask(attache, event, true));
+    }
+
+    protected boolean isHostOwnerSwitched(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            s_logger.warn("Can't find the host " + hostId);
+            return false;
+        }
+        return isHostOwnerSwitched(host);
+    }
+
+    protected boolean isHostOwnerSwitched(final HostVO host) {
+        if (host.getStatus() == Status.Up && host.getManagementServerId() != null && host.getManagementServerId() != _nodeId) {
+            return true;
+        }
+        return false;
+    }
+
+    private void disconnectInternal(final long hostId, final Status.Event event, final boolean invstigate) {
+        final AgentAttache attache = findAttache(hostId);
+
+        if (attache != null) {
+            if (!invstigate) {
+                disconnectWithoutInvestigation(attache, event);
+            } else {
+                disconnectWithInvestigation(attache, event);
+            }
+        } else {
+            /* Agent is still in connecting process, don't allow to disconnect right away */
+            if (tapLoadingAgents(hostId, TapAgentsAction.Contains)) {
+                s_logger.info("Host " + hostId + " is being loaded so no disconnects needed.");
+                return;
+            }
+
+            final HostVO host = _hostDao.findById(hostId);
+            if (host != null && host.getRemoved() == null) {
+                disconnectAgent(host, event, _nodeId);
+            }
+        }
+    }
+
+    @Override
+    public void disconnectWithInvestigation(final long hostId, final Status.Event event) {
+        disconnectInternal(hostId, event, true);
+    }
+
+    @Override
+    public void disconnectWithoutInvestigation(final long hostId, final Status.Event event) {
+        disconnectInternal(hostId, event, false);
+    }
+
+    @Override
+    public boolean handleDirectConnectAgent(final Host host, final StartupCommand[] cmds, final ServerResource resource, final boolean forRebalance, boolean newHost) throws ConnectionException {
+        AgentAttache attache;
+
+        attache = createAttacheForDirectConnect(host, resource);
+        final StartupAnswer[] answers = new StartupAnswer[cmds.length];
+        for (int i = 0; i < answers.length; i++) {
+            answers[i] = new StartupAnswer(cmds[i], attache.getId(), mgmtServiceConf.getPingInterval());
+        }
+        attache.process(answers);
+
+        if (newHost) {
+            notifyMonitorsOfNewlyAddedHost(host.getId());
+        }
+
+        attache = notifyMonitorsOfConnection(attache, cmds, forRebalance);
+
+        return attache != null;
+    }
+
+    @Override
+    public void pullAgentToMaintenance(final long hostId) {
+        final AgentAttache attache = findAttache(hostId);
+        if (attache != null) {
+            attache.setMaintenanceMode(true);
+            // Now cancel all of the commands except for the active one.
+            attache.cancelAllCommands(Status.Disconnected, false);
+        }
+    }
+
+    @Override
+    public void pullAgentOutMaintenance(final long hostId) {
+        final AgentAttache attache = findAttache(hostId);
+        if (attache != null) {
+            attache.setMaintenanceMode(false);
+        }
+    }
+
+    public ScheduledExecutorService getDirectAgentPool() {
+        return _directAgentExecutor;
+    }
+
+    public ScheduledExecutorService getCronJobPool() {
+        return _cronJobExecutor;
+    }
+
+    public int getDirectAgentThreadCap() {
+        return _directAgentThreadCap;
+    }
+
+    public Long getAgentPingTime(final long agentId) {
+        return _pingMap.get(agentId);
+    }
+
+    public void pingBy(final long agentId) {
+        // Update PingMap with the latest time if agent entry exists in the PingMap
+        if (_pingMap.replace(agentId, InaccurateClock.getTimeInSeconds()) == null) {
+            s_logger.info("PingMap for agent: " + agentId + " will not be updated because agent is no longer in the PingMap");
+        }
+    }
+
+    protected class MonitorTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            s_logger.trace("Agent Monitor is started.");
+
+            try {
+                final List<Long> behindAgents = findAgentsBehindOnPing();
+                for (final Long agentId : behindAgents) {
+                    final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+                    sc.and(sc.entity().getId(), Op.EQ, agentId);
+                    final HostVO h = sc.find();
+                    if (h != null) {
+                        final ResourceState resourceState = h.getResourceState();
+                        if (resourceState == ResourceState.Disabled || resourceState == ResourceState.Maintenance || resourceState == ResourceState.ErrorInMaintenance) {
+                            /*
+                             * Host is in non-operation state, so no investigation and direct put agent to Disconnected
+                             */
+                            s_logger.debug("Ping timeout but agent " + agentId + " is in resource state of " + resourceState + ", so no investigation");
+                            disconnectWithoutInvestigation(agentId, Event.ShutdownRequested);
+                        } else {
+                            final HostVO host = _hostDao.findById(agentId);
+                            if (host != null
+                                    && (host.getType() == Host.Type.ConsoleProxy || host.getType() == Host.Type.SecondaryStorageVM || host.getType() == Host.Type.SecondaryStorageCmdExecutor)) {
+
+                                s_logger.warn("Disconnect agent for CPVM/SSVM due to physical connection close. host: " + host.getId());
+                                disconnectWithoutInvestigation(agentId, Event.ShutdownRequested);
+                            } else {
+                                s_logger.debug("Ping timeout for agent " + agentId + ", do invstigation");
+                                disconnectWithInvestigation(agentId, Event.PingTimeout);
+                            }
+                        }
+                    }
+                }
+
+                final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+                sc.and(sc.entity().getResourceState(), Op.IN, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
+                final List<HostVO> hosts = sc.list();
+
+                for (final HostVO host : hosts) {
+                    if (_resourceMgr.checkAndMaintain(host.getId())) {
+                        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+                        final HostPodVO podVO = _podDao.findById(host.getPodId());
+                        final String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Migration Complete for host " + hostDesc,
+                                "Host [" + hostDesc + "] is ready for maintenance");
+                    }
+                }
+            } catch (final Throwable th) {
+                s_logger.error("Caught the following exception: ", th);
+            }
+
+            s_logger.trace("Agent Monitor is leaving the building!");
+        }
+
+        protected List<Long> findAgentsBehindOnPing() {
+            final List<Long> agentsBehind = new ArrayList<Long>();
+            final long cutoffTime = InaccurateClock.getTimeInSeconds() - mgmtServiceConf.getTimeout();
+            for (final Map.Entry<Long, Long> entry : _pingMap.entrySet()) {
+                if (entry.getValue() < cutoffTime) {
+                    agentsBehind.add(entry.getKey());
+                }
+            }
+
+            if (agentsBehind.size() > 0) {
+                s_logger.info("Found the following agents behind on ping: " + agentsBehind);
+            }
+
+            return agentsBehind;
+        }
+    }
+
+    protected class BehindOnPingListener implements Listener {
+        @Override
+        public boolean isRecurring() {
+            return true;
+        }
+
+        @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) {
+            final boolean processed = false;
+            for (final Command cmd : commands) {
+                if (cmd instanceof PingCommand) {
+                    pingBy(agentId);
+                }
+            }
+            return processed;
+        }
+
+        @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 (host.getType().equals(Host.Type.TrafficMonitor) || host.getType().equals(Host.Type.SecondaryStorage)) {
+                return;
+            }
+
+            // NOTE: We don't use pingBy here because we're initiating.
+            _pingMap.put(host.getId(), InaccurateClock.getTimeInSeconds());
+        }
+
+        @Override
+        public boolean processDisconnect(final long agentId, final Status state) {
+            _pingMap.remove(agentId);
+            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 true;
+        }
+
+        @Override
+        public int getTimeout() {
+            return -1;
+        }
+
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return AgentManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize, DirectAgentPoolSize,
+            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/agent/manager/ClusteredAgentAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/ClusteredAgentAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentAttache.java
diff --git a/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
new file mode 100644
index 0000000..7a16971
--- /dev/null
+++ b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
@@ -0,0 +1,1457 @@
+// 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.manager;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+import org.apache.cloudstack.ca.CAManager;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.ha.dao.HAConfigDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
+import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.cloudstack.utils.security.SSLUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CancelCommand;
+import com.cloud.agent.api.ChangeAgentAnswer;
+import com.cloud.agent.api.ChangeAgentCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PropagateResourceEventCommand;
+import com.cloud.agent.api.ScheduleHostScanTaskCommand;
+import com.cloud.agent.api.TransferAgentCommand;
+import com.cloud.agent.transport.Request;
+import com.cloud.agent.transport.Request.Version;
+import com.cloud.agent.transport.Response;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.cluster.ClusterManagerListener;
+import com.cloud.cluster.ClusterServicePdu;
+import com.cloud.cluster.ClusteredAgentRebalanceService;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.cluster.agentlb.AgentLoadBalancerPlanner;
+import com.cloud.cluster.agentlb.HostTransferMapVO;
+import com.cloud.cluster.agentlb.HostTransferMapVO.HostTransferState;
+import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.UnsupportedVersionException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.Status.Event;
+import com.cloud.resource.ServerResource;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.TaskExecutionException;
+import com.cloud.utils.nio.Link;
+import com.cloud.utils.nio.Task;
+import com.google.gson.Gson;
+
+public class ClusteredAgentManagerImpl extends AgentManagerImpl implements ClusterManagerListener, ClusteredAgentRebalanceService {
+    final static Logger s_logger = Logger.getLogger(ClusteredAgentManagerImpl.class);
+    private static final ScheduledExecutorService s_transferExecutor = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Cluster-AgentRebalancingExecutor"));
+    private final long rebalanceTimeOut = 300000; // 5 mins - after this time remove the agent from the transfer list
+
+    public final static long STARTUP_DELAY = 5000;
+    public final static long SCAN_INTERVAL = 90000; // 90 seconds, it takes 60 sec for xenserver to fail login
+    public final static int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
+    protected Set<Long> _agentToTransferIds = new HashSet<Long>();
+    Gson _gson;
+    protected HashMap<String, SocketChannel> _peers;
+    protected HashMap<String, SSLEngine> _sslEngines;
+    private final Timer _timer = new Timer("ClusteredAgentManager Timer");
+    boolean _agentLbHappened = false;
+
+    @Inject
+    protected ClusterManager _clusterMgr = null;
+    @Inject
+    protected ManagementServerHostDao _mshostDao;
+    @Inject
+    protected HostTransferMapDao _hostTransferDao;
+    @Inject
+    protected List<AgentLoadBalancerPlanner> _lbPlanners;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ConfigDepot _configDepot;
+    @Inject
+    private OutOfBandManagementDao outOfBandManagementDao;
+    @Inject
+    private HAConfigDao haConfigDao;
+    @Inject
+    private CAManager caService;
+
+    protected ClusteredAgentManagerImpl() {
+        super();
+    }
+
+    protected final ConfigKey<Boolean> EnableLB = new ConfigKey<Boolean>(Boolean.class, "agent.lb.enabled", "Advanced", "false", "Enable agent load balancing between management server nodes", true);
+    protected final ConfigKey<Double> ConnectedAgentThreshold = new ConfigKey<Double>(Double.class, "agent.load.threshold", "Advanced", "0.7",
+            "What percentage of the agents can be held by one management server before load balancing happens", true);
+    protected final ConfigKey<Integer> LoadSize = new ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advanced", "16", "How many agents to connect to in each round", true);
+    protected final ConfigKey<Integer> ScanInterval = new ConfigKey<Integer>(Integer.class, "direct.agent.scan.interval", "Advanced", "90", "Interval between scans to load agents", false,
+            ConfigKey.Scope.Global, 1000);
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
+        _peers = new HashMap<String, SocketChannel>(7);
+        _sslEngines = new HashMap<String, SSLEngine>(7);
+        _nodeId = ManagementServerNode.getManagementServerId();
+
+        s_logger.info("Configuring ClusterAgentManagerImpl. management server node id(msid): " + _nodeId);
+
+        ClusteredAgentAttache.initialize(this);
+
+        _clusterMgr.registerListener(this);
+        _clusterMgr.registerDispatcher(new ClusterDispatcher());
+
+        _gson = GsonHelper.getGson();
+
+        return super.configure(name, xmlParams);
+    }
+
+    @Override
+    public boolean start() {
+        if (!super.start()) {
+            return false;
+        }
+        _timer.schedule(new DirectAgentScanTimerTask(), STARTUP_DELAY, ScanInterval.value());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Scheduled direct agent scan task to run at an interval of " + ScanInterval.value() + " seconds");
+        }
+
+        // Schedule tasks for agent rebalancing
+        if (isAgentRebalanceEnabled()) {
+            cleanupTransferMap(_nodeId);
+            s_transferExecutor.scheduleAtFixedRate(getAgentRebalanceScanTask(), 60000, 60000, TimeUnit.MILLISECONDS);
+            s_transferExecutor.scheduleAtFixedRate(getTransferScanTask(), 60000, ClusteredAgentRebalanceService.DEFAULT_TRANSFER_CHECK_INTERVAL, TimeUnit.MILLISECONDS);
+        }
+
+        return true;
+    }
+
+    public void scheduleHostScanTask() {
+        _timer.schedule(new DirectAgentScanTimerTask(), 0);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Scheduled a direct agent scan task");
+        }
+    }
+
+    private void runDirectAgentScanTimerTask() {
+        scanDirectAgentToLoad();
+    }
+
+    private void scanDirectAgentToLoad() {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Begin scanning directly connected hosts");
+        }
+
+        // for agents that are self-managed, threshold to be considered as disconnected after pingtimeout
+        final long cutSeconds = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
+        final List<HostVO> hosts = _hostDao.findAndUpdateDirectAgentToLoad(cutSeconds, LoadSize.value().longValue(), _nodeId);
+        final List<HostVO> appliances = _hostDao.findAndUpdateApplianceToLoad(cutSeconds, _nodeId);
+
+        if (hosts != null) {
+            hosts.addAll(appliances);
+            if (hosts.size() > 0) {
+                s_logger.debug("Found " + hosts.size() + " unmanaged direct hosts, processing connect for them...");
+                for (final HostVO host : hosts) {
+                    try {
+                        final AgentAttache agentattache = findAttache(host.getId());
+                        if (agentattache != null) {
+                            // already loaded, skip
+                            if (agentattache.forForward()) {
+                                if (s_logger.isInfoEnabled()) {
+                                    s_logger.info(host + " is detected down, but we have a forward attache running, disconnect this one before launching the host");
+                                }
+                                removeAgent(agentattache, Status.Disconnected);
+                            } else {
+                                continue;
+                            }
+                        }
+
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Loading directly connected host " + host.getId() + "(" + host.getName() + ")");
+                        }
+                        loadDirectlyConnectedHost(host, false);
+                    } catch (final Throwable e) {
+                        s_logger.warn(" can not load directly connected host " + host.getId() + "(" + host.getName() + ") due to ", e);
+                    }
+                }
+            }
+        }
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("End scanning directly connected hosts");
+        }
+    }
+
+    private class DirectAgentScanTimerTask extends ManagedContextTimerTask {
+        @Override
+        protected void runInContext() {
+            try {
+                runDirectAgentScanTimerTask();
+            } catch (final Throwable e) {
+                s_logger.error("Unexpected exception " + e.getMessage(), e);
+            }
+        }
+    }
+
+    @Override
+    public Task create(final Task.Type type, final Link link, final byte[] data) {
+        return new ClusteredAgentHandler(type, link, data);
+    }
+
+    protected AgentAttache createAttache(final long id) {
+        s_logger.debug("create forwarding ClusteredAgentAttache for " + id);
+        final HostVO host = _hostDao.findById(id);
+        final AgentAttache attache = new ClusteredAgentAttache(this, id, host.getName());
+        AgentAttache old = null;
+        synchronized (_agents) {
+            old = _agents.get(id);
+            _agents.put(id, attache);
+        }
+        if (old != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Remove stale agent attache from current management server");
+            }
+            removeAgent(old, Status.Removed);
+        }
+        return attache;
+    }
+
+    @Override
+    protected AgentAttache createAttacheForConnect(final HostVO host, final Link link) {
+        s_logger.debug("create ClusteredAgentAttache for " + host.getId());
+        final AgentAttache attache = new ClusteredAgentAttache(this, host.getId(), host.getName(), link, host.isInMaintenanceStates());
+        link.attach(attache);
+        AgentAttache old = null;
+        synchronized (_agents) {
+            old = _agents.get(host.getId());
+            _agents.put(host.getId(), attache);
+        }
+        if (old != null) {
+            old.disconnect(Status.Removed);
+        }
+        return attache;
+    }
+
+    @Override
+    protected AgentAttache createAttacheForDirectConnect(final Host host, final ServerResource resource) {
+        s_logger.debug("create ClusteredDirectAgentAttache for " + host.getId());
+        final DirectAgentAttache attache = new ClusteredDirectAgentAttache(this, host.getId(), host.getName(), _nodeId, resource, host.isInMaintenanceStates());
+        AgentAttache old = null;
+        synchronized (_agents) {
+            old = _agents.get(host.getId());
+            _agents.put(host.getId(), attache);
+        }
+        if (old != null) {
+            old.disconnect(Status.Removed);
+        }
+        return attache;
+    }
+
+    @Override
+    protected boolean handleDisconnectWithoutInvestigation(final AgentAttache attache, final Status.Event event, final boolean transitState, final boolean removeAgent) {
+        return handleDisconnect(attache, event, false, true, removeAgent);
+    }
+
+    @Override
+    protected boolean handleDisconnectWithInvestigation(final AgentAttache attache, final Status.Event event) {
+        return handleDisconnect(attache, event, true, true, true);
+    }
+
+    protected boolean handleDisconnect(final AgentAttache agent, final Status.Event event, final boolean investigate, final boolean broadcast, final boolean removeAgent) {
+        boolean res;
+        if (!investigate) {
+            res = super.handleDisconnectWithoutInvestigation(agent, event, true, removeAgent);
+        } else {
+            res = super.handleDisconnectWithInvestigation(agent, event);
+        }
+
+        if (res) {
+            if (broadcast) {
+                notifyNodesInCluster(agent);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean executeUserRequest(final long hostId, final Event event) throws AgentUnavailableException {
+        if (event == Event.AgentDisconnected) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Received agent disconnect event for host " + hostId);
+            }
+            final AgentAttache attache = findAttache(hostId);
+            if (attache != null) {
+                // don't process disconnect if the host is being rebalanced
+                if (isAgentRebalanceEnabled()) {
+                    final HostTransferMapVO transferVO = _hostTransferDao.findById(hostId);
+                    if (transferVO != null) {
+                        if (transferVO.getFutureOwner() == _nodeId && transferVO.getState() == HostTransferState.TransferStarted) {
+                            s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId + " as the host is being connected to " + _nodeId);
+                            return true;
+                        }
+                    }
+                }
+
+                // don't process disconnect if the disconnect came for the host via delayed cluster notification,
+                // but the host has already reconnected to the current management server
+                if (!attache.forForward()) {
+                    s_logger.debug("Not processing " + Event.AgentDisconnected + " event for the host id=" + hostId + " as the host is directly connected to the current management server " + _nodeId);
+                    return true;
+                }
+
+                return super.handleDisconnectWithoutInvestigation(attache, Event.AgentDisconnected, false, true);
+            }
+
+            return true;
+        } else {
+            return super.executeUserRequest(hostId, event);
+        }
+    }
+
+    @Override
+    public void reconnect(final long hostId) throws CloudRuntimeException, AgentUnavailableException {
+        Boolean result = propagateAgentEvent(hostId, Event.ShutdownRequested);
+        if (result == null) {
+            super.reconnect(hostId);
+            return;
+        }
+        if (!result) {
+                throw new CloudRuntimeException("Failed to propagate agent change request event:" + Event.ShutdownRequested + " to host:" + hostId);
+        }
+    }
+
+    public void notifyNodesInCluster(final AgentAttache attache) {
+        s_logger.debug("Notifying other nodes of to disconnect");
+        final Command[] cmds = new Command[] {new ChangeAgentCommand(attache.getId(), Event.AgentDisconnected)};
+        _clusterMgr.broadcast(attache.getId(), _gson.toJson(cmds));
+    }
+
+    // notifies MS peers to schedule a host scan task immediately, triggered during addHost operation
+    public void notifyNodesInClusterToScheduleHostScanTask() {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Notifying other MS nodes to run host scan task");
+        }
+        final Command[] cmds = new Command[] {new ScheduleHostScanTaskCommand()};
+        _clusterMgr.broadcast(0, _gson.toJson(cmds));
+    }
+
+    protected static void logT(final byte[] bytes, final String msg) {
+        s_logger.trace("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": "
+                + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
+    }
+
+    protected static void logD(final byte[] bytes, final String msg) {
+        s_logger.debug("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": "
+                + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
+    }
+
+    protected static void logI(final byte[] bytes, final String msg) {
+        s_logger.info("Seq " + Request.getAgentId(bytes) + "-" + Request.getSequence(bytes) + ": MgmtId " + Request.getManagementServerId(bytes) + ": "
+                + (Request.isRequest(bytes) ? "Req: " : "Resp: ") + msg);
+    }
+
+    public boolean routeToPeer(final String peer, final byte[] bytes) {
+        int i = 0;
+        SocketChannel ch = null;
+        SSLEngine sslEngine = null;
+        while (i++ < 5) {
+            ch = connectToPeer(peer, ch);
+            if (ch == null) {
+                try {
+                    logD(bytes, "Unable to route to peer: " + Request.parse(bytes).toString());
+                } catch (ClassNotFoundException | UnsupportedVersionException e) {
+                    // Request.parse thrown exception when we try to log it, log as much as we can
+                    logD(bytes, "Unable to route to peer, and Request.parse further caught exception" + e.getMessage());
+                }
+                return false;
+            }
+            sslEngine = getSSLEngine(peer);
+            if (sslEngine == null) {
+                logD(bytes, "Unable to get SSLEngine of peer: " + peer);
+                return false;
+            }
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    logD(bytes, "Routing to peer");
+                }
+                Link.write(ch, new ByteBuffer[] {ByteBuffer.wrap(bytes)}, sslEngine);
+                return true;
+            } catch (final IOException e) {
+                try {
+                    logI(bytes, "Unable to route to peer: " + Request.parse(bytes).toString() + " due to " + e.getMessage());
+                } catch (ClassNotFoundException | UnsupportedVersionException ex) {
+                    // Request.parse thrown exception when we try to log it, log as much as we can
+                    logI(bytes, "Unable to route to peer due to" + e.getMessage() + ". Also caught exception when parsing request: " + ex.getMessage());
+                }
+            }
+        }
+        return false;
+    }
+
+    public String findPeer(final long hostId) {
+        return getPeerName(hostId);
+    }
+
+    public SSLEngine getSSLEngine(final String peerName) {
+        return _sslEngines.get(peerName);
+    }
+
+    public void cancel(final String peerName, final long hostId, final long sequence, final String reason) {
+        final CancelCommand cancel = new CancelCommand(sequence, reason);
+        final Request req = new Request(hostId, _nodeId, cancel, true);
+        req.setControl(true);
+        routeToPeer(peerName, req.getBytes());
+    }
+
+    public void closePeer(final String peerName) {
+        synchronized (_peers) {
+            final SocketChannel ch = _peers.get(peerName);
+            if (ch != null) {
+                try {
+                    ch.close();
+                } catch (final IOException e) {
+                    s_logger.warn("Unable to close peer socket connection to " + peerName);
+                }
+            }
+            _peers.remove(peerName);
+            _sslEngines.remove(peerName);
+        }
+    }
+
+    public SocketChannel connectToPeer(final String peerName, final SocketChannel prevCh) {
+        synchronized (_peers) {
+            final SocketChannel ch = _peers.get(peerName);
+            SSLEngine sslEngine = null;
+            if (prevCh != null) {
+                try {
+                    prevCh.close();
+                } catch (final Exception e) {
+                    s_logger.info("[ignored]" + "failed to get close resource for previous channel Socket: " + e.getLocalizedMessage());
+                }
+            }
+            if (ch == null || ch == prevCh) {
+                final ManagementServerHost ms = _clusterMgr.getPeer(peerName);
+                if (ms == null) {
+                    s_logger.info("Unable to find peer: " + peerName);
+                    return null;
+                }
+                final String ip = ms.getServiceIP();
+                InetAddress addr;
+                int port = Port.value();
+                try {
+                    addr = InetAddress.getByName(ip);
+                } catch (final UnknownHostException e) {
+                    throw new CloudRuntimeException("Unable to resolve " + ip);
+                }
+                SocketChannel ch1 = null;
+                try {
+                    ch1 = SocketChannel.open(new InetSocketAddress(addr, port));
+                    ch1.configureBlocking(false);
+                    ch1.socket().setKeepAlive(true);
+                    ch1.socket().setSoTimeout(60 * 1000);
+                    try {
+                        SSLContext sslContext = Link.initManagementSSLContext(caService);
+                        sslEngine = sslContext.createSSLEngine(ip, port);
+                        sslEngine.setUseClientMode(true);
+                        sslEngine.setEnabledProtocols(SSLUtils.getSupportedProtocols(sslEngine.getEnabledProtocols()));
+                        sslEngine.beginHandshake();
+                        if (!Link.doHandshake(ch1, sslEngine)) {
+                            ch1.close();
+                            throw new IOException(String.format("SSL: Handshake failed with peer management server '%s' on %s:%d ", peerName, ip, port));
+                        }
+                        s_logger.info(String.format("SSL: Handshake done with peer management server '%s' on %s:%d ", peerName, ip, port));
+                    } catch (final Exception e) {
+                        ch1.close();
+                        throw new IOException("SSL: Fail to init SSL! " + e);
+                    }
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Connection to peer opened: " + peerName + ", ip: " + ip);
+                    }
+                    _peers.put(peerName, ch1);
+                    _sslEngines.put(peerName, sslEngine);
+                    return ch1;
+                } catch (final IOException e) {
+                    if (ch1 != null) {
+                        try {
+                            ch1.close();
+                        } catch (final IOException ex) {
+                            s_logger.error("failed to close failed peer socket: " + ex);
+                        }
+                    }
+                    s_logger.warn("Unable to connect to peer management server: " + peerName + ", ip: " + ip + " due to " + e.getMessage(), e);
+                    return null;
+                }
+            }
+
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Found open channel for peer: " + peerName);
+            }
+            return ch;
+        }
+    }
+
+    public SocketChannel connectToPeer(final long hostId, final SocketChannel prevCh) {
+        final String peerName = getPeerName(hostId);
+        if (peerName == null) {
+            return null;
+        }
+
+        return connectToPeer(peerName, prevCh);
+    }
+
+    @Override
+    protected AgentAttache getAttache(final Long hostId) throws AgentUnavailableException {
+        assert hostId != null : "Who didn't check their id value?";
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new AgentUnavailableException("Can't find the host ", hostId);
+        }
+
+        AgentAttache agent = findAttache(hostId);
+        if (agent == null || !agent.forForward()) {
+            if (isHostOwnerSwitched(host)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Host " + hostId + " has switched to another management server, need to update agent map with a forwarding agent attache");
+                }
+                agent = createAttache(hostId);
+            }
+        }
+        if (agent == null) {
+            final AgentUnavailableException ex = new AgentUnavailableException("Host with specified id is not in the right state: " + host.getStatus(), hostId);
+            ex.addProxyObject(_entityMgr.findById(Host.class, hostId).getUuid());
+            throw ex;
+        }
+
+        return agent;
+    }
+
+    @Override
+    public boolean stop() {
+        if (_peers != null) {
+            for (final SocketChannel ch : _peers.values()) {
+                try {
+                    s_logger.info("Closing: " + ch.toString());
+                    ch.close();
+                } catch (final IOException e) {
+                    s_logger.info("[ignored] error on closing channel: " + ch.toString(), e);
+                }
+            }
+        }
+        _timer.cancel();
+
+        // cancel all transfer tasks
+        s_transferExecutor.shutdownNow();
+        cleanupTransferMap(_nodeId);
+
+        return super.stop();
+    }
+
+    @Override
+    public void startDirectlyConnectedHosts() {
+        // override and let it be dummy for purpose, we will scan and load direct agents periodically.
+        // We may also pickup agents that have been left over from other crashed management server
+    }
+
+    public class ClusteredAgentHandler extends AgentHandler {
+
+        public ClusteredAgentHandler(final Task.Type type, final Link link, final byte[] data) {
+            super(type, link, data);
+        }
+
+        @Override
+        protected void doTask(final Task task) throws TaskExecutionException {
+            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            try {
+                if (task.getType() != Task.Type.DATA) {
+                    super.doTask(task);
+                    return;
+                }
+
+                final byte[] data = task.getData();
+                final Version ver = Request.getVersion(data);
+                if (ver.ordinal() != Version.v1.ordinal() && ver.ordinal() != Version.v3.ordinal()) {
+                    s_logger.warn("Wrong version for clustered agent request");
+                    super.doTask(task);
+                    return;
+                }
+
+                final long hostId = Request.getAgentId(data);
+                final Link link = task.getLink();
+
+                if (Request.fromServer(data)) {
+
+                    final AgentAttache agent = findAttache(hostId);
+
+                    if (Request.isControl(data)) {
+                        if (agent == null) {
+                            logD(data, "No attache to process cancellation");
+                            return;
+                        }
+                        final Request req = Request.parse(data);
+                        final Command[] cmds = req.getCommands();
+                        final CancelCommand cancel = (CancelCommand)cmds[0];
+                        if (s_logger.isDebugEnabled()) {
+                            logD(data, "Cancel request received");
+                        }
+                        agent.cancel(cancel.getSequence());
+                        final Long current = agent._currentSequence;
+                        // if the request is the current request, always have to trigger sending next request in
+                        // sequence,
+                        // otherwise the agent queue will be blocked
+                        if (req.executeInSequence() && current != null && current == Request.getSequence(data)) {
+                            agent.sendNext(Request.getSequence(data));
+                        }
+                        return;
+                    }
+
+                    try {
+                        if (agent == null || agent.isClosed()) {
+                            throw new AgentUnavailableException("Unable to route to agent ", hostId);
+                        }
+
+                        if (Request.isRequest(data) && Request.requiresSequentialExecution(data)) {
+                            // route it to the agent.
+                            // But we have the serialize the control commands here so we have
+                            // to deserialize this and send it through the agent attache.
+                            final Request req = Request.parse(data);
+                            agent.send(req, null);
+                            return;
+                        } else {
+                            if (agent instanceof Routable) {
+                                final Routable cluster = (Routable)agent;
+                                cluster.routeToAgent(data);
+                            } else {
+                                agent.send(Request.parse(data));
+                            }
+                            return;
+                        }
+                    } catch (final AgentUnavailableException e) {
+                        logD(data, e.getMessage());
+                        cancel(Long.toString(Request.getManagementServerId(data)), hostId, Request.getSequence(data), e.getMessage());
+                    }
+                } else {
+
+                    final long mgmtId = Request.getManagementServerId(data);
+                    if (mgmtId != -1 && mgmtId != _nodeId) {
+                        routeToPeer(Long.toString(mgmtId), data);
+                        if (Request.requiresSequentialExecution(data)) {
+                            final AgentAttache attache = (AgentAttache)link.attachment();
+                            if (attache != null) {
+                                attache.sendNext(Request.getSequence(data));
+                            } else if (s_logger.isDebugEnabled()) {
+                                logD(data, "No attache to process " + Request.parse(data).toString());
+                            }
+                        }
+                        return;
+                    } else {
+                        if (Request.isRequest(data)) {
+                            super.doTask(task);
+                        } else {
+                            // received an answer.
+                            final Response response = Response.parse(data);
+                            final AgentAttache attache = findAttache(response.getAgentId());
+                            if (attache == null) {
+                                s_logger.info("SeqA " + response.getAgentId() + "-" + response.getSequence() + "Unable to find attache to forward " + response.toString());
+                                return;
+                            }
+                            if (!attache.processAnswers(response.getSequence(), response)) {
+                                s_logger.info("SeqA " + attache.getId() + "-" + response.getSequence() + ": Response is not processed: " + response.toString());
+                            }
+                        }
+                        return;
+                    }
+                }
+            } catch (final ClassNotFoundException e) {
+                final String message = String.format("ClassNotFoundException occured when executing taks! Error '%s'", e.getMessage());
+                s_logger.error(message);
+                throw new TaskExecutionException(message, e);
+            } catch (final UnsupportedVersionException e) {
+                final String message = String.format("UnsupportedVersionException occured when executing taks! Error '%s'", e.getMessage());
+                s_logger.error(message);
+                throw new TaskExecutionException(message, e);
+            } finally {
+                txn.close();
+            }
+        }
+    }
+
+    @Override
+    public void onManagementNodeJoined(final List<? extends ManagementServerHost> nodeList, final long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(final List<? extends ManagementServerHost> nodeList, final long selfNodeId) {
+        for (final ManagementServerHost vo : nodeList) {
+            s_logger.info("Marking hosts as disconnected on Management server" + vo.getMsid());
+            final long lastPing = (System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout();
+            _hostDao.markHostsAsDisconnected(vo.getMsid(), lastPing);
+            outOfBandManagementDao.expireServerOwnership(vo.getMsid());
+            haConfigDao.expireServerOwnership(vo.getMsid());
+            s_logger.info("Deleting entries from op_host_transfer table for Management server " + vo.getMsid());
+            cleanupTransferMap(vo.getMsid());
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public void removeAgent(final AgentAttache attache, final Status nextState) {
+        if (attache == null) {
+            return;
+        }
+
+        super.removeAgent(attache, nextState);
+    }
+
+    @Override
+    public boolean executeRebalanceRequest(final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event) throws AgentUnavailableException, OperationTimedoutException {
+        boolean result = false;
+        if (event == Event.RequestAgentRebalance) {
+            return setToWaitForRebalance(agentId, currentOwnerId, futureOwnerId);
+        } else if (event == Event.StartAgentRebalance) {
+            try {
+                result = rebalanceHost(agentId, currentOwnerId, futureOwnerId);
+            } catch (final Exception e) {
+                s_logger.warn("Unable to rebalance host id=" + agentId, e);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void scheduleRebalanceAgents() {
+        _timer.schedule(new AgentLoadBalancerTask(), 30000);
+    }
+
+    public class AgentLoadBalancerTask extends ManagedContextTimerTask {
+        protected volatile boolean cancelled = false;
+
+        public AgentLoadBalancerTask() {
+            s_logger.debug("Agent load balancer task created");
+        }
+
+        @Override
+        public synchronized boolean cancel() {
+            if (!cancelled) {
+                cancelled = true;
+                s_logger.debug("Agent load balancer task cancelled");
+                return super.cancel();
+            }
+            return true;
+        }
+
+        @Override
+        protected synchronized void runInContext() {
+            try {
+                if (!cancelled) {
+                    startRebalanceAgents();
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("The agent load balancer task is now being cancelled");
+                    }
+                    cancelled = true;
+                }
+            } catch (final Throwable e) {
+                s_logger.error("Unexpected exception " + e.toString(), e);
+            }
+        }
+    }
+
+    public void startRebalanceAgents() {
+        s_logger.debug("Management server " + _nodeId + " is asking other peers to rebalance their agents");
+        final List<ManagementServerHostVO> allMS = _mshostDao.listBy(ManagementServerHost.State.Up);
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getManagementServerId(), Op.NNULL);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
+        final List<HostVO> allManagedAgents = sc.list();
+
+        int avLoad = 0;
+
+        if (!allManagedAgents.isEmpty() && !allMS.isEmpty()) {
+            avLoad = allManagedAgents.size() / allMS.size();
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("There are no hosts to rebalance in the system. Current number of active management server nodes in the system is " + allMS.size() + "; number of managed agents is "
+                        + allManagedAgents.size());
+            }
+            return;
+        }
+
+        if (avLoad == 0L) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("As calculated average load is less than 1, rounding it to 1");
+            }
+            avLoad = 1;
+        }
+
+        for (final ManagementServerHostVO node : allMS) {
+            if (node.getMsid() != _nodeId) {
+
+                List<HostVO> hostsToRebalance = new ArrayList<HostVO>();
+                for (final AgentLoadBalancerPlanner lbPlanner : _lbPlanners) {
+                    hostsToRebalance = lbPlanner.getHostsToRebalance(node.getMsid(), avLoad);
+                    if (hostsToRebalance != null && !hostsToRebalance.isEmpty()) {
+                        break;
+                    } else {
+                        s_logger.debug("Agent load balancer planner " + lbPlanner.getName() + " found no hosts to be rebalanced from management server " + node.getMsid());
+                    }
+                }
+
+                if (hostsToRebalance != null && !hostsToRebalance.isEmpty()) {
+                    s_logger.debug("Found " + hostsToRebalance.size() + " hosts to rebalance from management server " + node.getMsid());
+                    for (final HostVO host : hostsToRebalance) {
+                        final long hostId = host.getId();
+                        s_logger.debug("Asking management server " + node.getMsid() + " to give away host id=" + hostId);
+                        boolean result = true;
+
+                        if (_hostTransferDao.findById(hostId) != null) {
+                            s_logger.warn("Somebody else is already rebalancing host id: " + hostId);
+                            continue;
+                        }
+
+                        HostTransferMapVO transfer = null;
+                        try {
+                            transfer = _hostTransferDao.startAgentTransfering(hostId, node.getMsid(), _nodeId);
+                            final Answer[] answer = sendRebalanceCommand(node.getMsid(), hostId, node.getMsid(), _nodeId, Event.RequestAgentRebalance);
+                            if (answer == null) {
+                                s_logger.warn("Failed to get host id=" + hostId + " from management server " + node.getMsid());
+                                result = false;
+                            }
+                        } catch (final Exception ex) {
+                            s_logger.warn("Failed to get host id=" + hostId + " from management server " + node.getMsid(), ex);
+                            result = false;
+                        } finally {
+                            if (transfer != null) {
+                                final HostTransferMapVO transferState = _hostTransferDao.findByIdAndFutureOwnerId(transfer.getId(), _nodeId);
+                                if (!result && transferState != null && transferState.getState() == HostTransferState.TransferRequested) {
+                                    if (s_logger.isDebugEnabled()) {
+                                        s_logger.debug("Removing mapping from op_host_transfer as it failed to be set to transfer mode");
+                                    }
+                                    // just remove the mapping (if exists) as nothing was done on the peer management
+                                    // server yet
+                                    _hostTransferDao.remove(transfer.getId());
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    s_logger.debug("Found no hosts to rebalance from the management server " + node.getMsid());
+                }
+            }
+        }
+    }
+
+    private Answer[] sendRebalanceCommand(final long peer, final long agentId, final long currentOwnerId, final long futureOwnerId, final Event event) {
+        final TransferAgentCommand transfer = new TransferAgentCommand(agentId, currentOwnerId, futureOwnerId, event);
+        final Commands commands = new Commands(Command.OnError.Stop);
+        commands.addCommand(transfer);
+
+        final Command[] cmds = commands.toCommands();
+
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Forwarding " + cmds[0].toString() + " to " + peer);
+            }
+            final String peerName = Long.toString(peer);
+            final String cmdStr = _gson.toJson(cmds);
+            final String ansStr = _clusterMgr.execute(peerName, agentId, cmdStr, true);
+            final Answer[] answers = _gson.fromJson(ansStr, Answer[].class);
+            return answers;
+        } catch (final Exception e) {
+            s_logger.warn("Caught exception while talking to " + currentOwnerId, e);
+            return null;
+        }
+    }
+
+    public String getPeerName(final long agentHostId) {
+
+        final HostVO host = _hostDao.findById(agentHostId);
+        if (host != null && host.getManagementServerId() != null) {
+            if (_clusterMgr.getSelfPeerName().equals(Long.toString(host.getManagementServerId()))) {
+                return null;
+            }
+
+            return Long.toString(host.getManagementServerId());
+        }
+        return null;
+    }
+
+    public Boolean propagateAgentEvent(final long agentId, final Event event) throws AgentUnavailableException {
+        final String msPeer = getPeerName(agentId);
+        if (msPeer == null) {
+            return null;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Propagating agent change request event:" + event.toString() + " to agent:" + agentId);
+        }
+        final Command[] cmds = new Command[1];
+        cmds[0] = new ChangeAgentCommand(agentId, event);
+
+        final String ansStr = _clusterMgr.execute(msPeer, agentId, _gson.toJson(cmds), true);
+        if (ansStr == null) {
+            throw new AgentUnavailableException(agentId);
+        }
+
+        final Answer[] answers = _gson.fromJson(ansStr, Answer[].class);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Result for agent change is " + answers[0].getResult());
+        }
+
+        return answers[0].getResult();
+    }
+
+    private Runnable getTransferScanTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                try {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Clustered agent transfer scan check, management server id:" + _nodeId);
+                    }
+                    synchronized (_agentToTransferIds) {
+                        if (_agentToTransferIds.size() > 0) {
+                            s_logger.debug("Found " + _agentToTransferIds.size() + " agents to transfer");
+                            // for (Long hostId : _agentToTransferIds) {
+                            for (final Iterator<Long> iterator = _agentToTransferIds.iterator(); iterator.hasNext();) {
+                                final Long hostId = iterator.next();
+                                final AgentAttache attache = findAttache(hostId);
+
+                                // if the thread:
+                                // 1) timed out waiting for the host to reconnect
+                                // 2) recipient management server is not active any more
+                                // 3) if the management server doesn't own the host any more
+                                // remove the host from re-balance list and delete from op_host_transfer DB
+                                // no need to do anything with the real attache as we haven't modified it yet
+                                final Date cutTime = DateUtil.currentGMTTime();
+                                final HostTransferMapVO transferMap = _hostTransferDao.findActiveHostTransferMapByHostId(hostId, new Date(cutTime.getTime() - rebalanceTimeOut));
+
+                                if (transferMap == null) {
+                                    s_logger.debug("Timed out waiting for the host id=" + hostId + " to be ready to transfer, skipping rebalance for the host");
+                                    iterator.remove();
+                                    _hostTransferDao.completeAgentTransfer(hostId);
+                                    continue;
+                                }
+
+                                if (transferMap.getInitialOwner() != _nodeId || attache == null || attache.forForward()) {
+                                    s_logger.debug("Management server " + _nodeId + " doesn't own host id=" + hostId + " any more, skipping rebalance for the host");
+                                    iterator.remove();
+                                    _hostTransferDao.completeAgentTransfer(hostId);
+                                    continue;
+                                }
+
+                                final ManagementServerHostVO ms = _mshostDao.findByMsid(transferMap.getFutureOwner());
+                                if (ms != null && ms.getState() != ManagementServerHost.State.Up) {
+                                    s_logger.debug("Can't transfer host " + hostId + " as it's future owner is not in UP state: " + ms + ", skipping rebalance for the host");
+                                    iterator.remove();
+                                    _hostTransferDao.completeAgentTransfer(hostId);
+                                    continue;
+                                }
+
+                                if (attache.getQueueSize() == 0 && attache.getNonRecurringListenersSize() == 0) {
+                                    iterator.remove();
+                                    try {
+                                        _executor.execute(new RebalanceTask(hostId, transferMap.getInitialOwner(), transferMap.getFutureOwner()));
+                                    } catch (final RejectedExecutionException ex) {
+                                        s_logger.warn("Failed to submit rebalance task for host id=" + hostId + "; postponing the execution");
+                                        continue;
+                                    }
+
+                                } else {
+                                    s_logger.debug("Agent " + hostId + " can't be transfered yet as its request queue size is " + attache.getQueueSize() + " and listener queue size is "
+                                            + attache.getNonRecurringListenersSize());
+                                }
+                            }
+                        } else {
+                            if (s_logger.isTraceEnabled()) {
+                                s_logger.trace("Found no agents to be transfered by the management server " + _nodeId);
+                            }
+                        }
+                    }
+
+                } catch (final Throwable e) {
+                    s_logger.error("Problem with the clustered agent transfer scan check!", e);
+                }
+            }
+        };
+    }
+
+    private boolean setToWaitForRebalance(final long hostId, final long currentOwnerId, final long futureOwnerId) {
+        s_logger.debug("Adding agent " + hostId + " to the list of agents to transfer");
+        synchronized (_agentToTransferIds) {
+            return _agentToTransferIds.add(hostId);
+        }
+    }
+
+    protected boolean rebalanceHost(final long hostId, final long currentOwnerId, final long futureOwnerId) throws AgentUnavailableException {
+
+        boolean result = true;
+        if (currentOwnerId == _nodeId) {
+            if (!startRebalance(hostId)) {
+                s_logger.debug("Failed to start agent rebalancing");
+                finishRebalance(hostId, futureOwnerId, Event.RebalanceFailed);
+                return false;
+            }
+            try {
+                final Answer[] answer = sendRebalanceCommand(futureOwnerId, hostId, currentOwnerId, futureOwnerId, Event.StartAgentRebalance);
+                if (answer == null || !answer[0].getResult()) {
+                    result = false;
+                }
+
+            } catch (final Exception ex) {
+                s_logger.warn("Host " + hostId + " failed to connect to the management server " + futureOwnerId + " as a part of rebalance process", ex);
+                result = false;
+            }
+
+            if (result) {
+                s_logger.debug("Successfully transfered host id=" + hostId + " to management server " + futureOwnerId);
+                finishRebalance(hostId, futureOwnerId, Event.RebalanceCompleted);
+            } else {
+                s_logger.warn("Failed to transfer host id=" + hostId + " to management server " + futureOwnerId);
+                finishRebalance(hostId, futureOwnerId, Event.RebalanceFailed);
+            }
+
+        } else if (futureOwnerId == _nodeId) {
+            final HostVO host = _hostDao.findById(hostId);
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Disconnecting host " + host.getId() + "(" + host.getName() + " as a part of rebalance process without notification");
+                }
+
+                final AgentAttache attache = findAttache(hostId);
+                if (attache != null) {
+                    result = handleDisconnect(attache, Event.AgentDisconnected, false, false, true);
+                }
+
+                if (result) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Loading directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + " as a part of rebalance process");
+                    }
+                    result = loadDirectlyConnectedHost(host, true);
+                } else {
+                    s_logger.warn("Failed to disconnect " + host.getId() + "(" + host.getName() + " as a part of rebalance process without notification");
+                }
+
+            } catch (final Exception ex) {
+                s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + " as a part of rebalance process due to:",
+                        ex);
+                result = false;
+            }
+
+            if (result) {
+                s_logger.debug("Successfully loaded directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + " as a part of rebalance process");
+            } else {
+                s_logger.warn("Failed to load directly connected host " + host.getId() + "(" + host.getName() + ") to the management server " + _nodeId + " as a part of rebalance process");
+            }
+        }
+
+        return result;
+    }
+
+    protected void finishRebalance(final long hostId, final long futureOwnerId, final Event event) {
+
+        final boolean success = event == Event.RebalanceCompleted ? true : false;
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Finishing rebalancing for the agent " + hostId + " with event " + event);
+        }
+
+        final AgentAttache attache = findAttache(hostId);
+        if (attache == null || !(attache instanceof ClusteredAgentAttache)) {
+            s_logger.debug("Unable to find forward attache for the host id=" + hostId + ", assuming that the agent disconnected already");
+            _hostTransferDao.completeAgentTransfer(hostId);
+            return;
+        }
+
+        final ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)attache;
+
+        if (success) {
+
+            // 1) Set transfer mode to false - so the agent can start processing requests normally
+            forwardAttache.setTransferMode(false);
+
+            // 2) Get all transfer requests and route them to peer
+            Request requestToTransfer = forwardAttache.getRequestToTransfer();
+            while (requestToTransfer != null) {
+                s_logger.debug("Forwarding request " + requestToTransfer.getSequence() + " held in transfer attache " + hostId + " from the management server " + _nodeId + " to " + futureOwnerId);
+                final boolean routeResult = routeToPeer(Long.toString(futureOwnerId), requestToTransfer.getBytes());
+                if (!routeResult) {
+                    logD(requestToTransfer.getBytes(), "Failed to route request to peer");
+                }
+
+                requestToTransfer = forwardAttache.getRequestToTransfer();
+            }
+
+            s_logger.debug("Management server " + _nodeId + " completed agent " + hostId + " rebalance to " + futureOwnerId);
+
+        } else {
+            failRebalance(hostId);
+        }
+
+        s_logger.debug("Management server " + _nodeId + " completed agent " + hostId + " rebalance");
+        _hostTransferDao.completeAgentTransfer(hostId);
+    }
+
+    protected void failRebalance(final long hostId) {
+        try {
+            s_logger.debug("Management server " + _nodeId + " failed to rebalance agent " + hostId);
+            _hostTransferDao.completeAgentTransfer(hostId);
+            handleDisconnectWithoutInvestigation(findAttache(hostId), Event.RebalanceFailed, true, true);
+        } catch (final Exception ex) {
+            s_logger.warn("Failed to reconnect host id=" + hostId + " as a part of failed rebalance task cleanup");
+        }
+    }
+
+    protected boolean startRebalance(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+
+        if (host == null || host.getRemoved() != null) {
+            s_logger.warn("Unable to find host record, fail start rebalancing process");
+            return false;
+        }
+
+        synchronized (_agents) {
+            final ClusteredDirectAgentAttache attache = (ClusteredDirectAgentAttache)_agents.get(hostId);
+            if (attache != null && attache.getQueueSize() == 0 && attache.getNonRecurringListenersSize() == 0) {
+                handleDisconnectWithoutInvestigation(attache, Event.StartAgentRebalance, true, true);
+                final ClusteredAgentAttache forwardAttache = (ClusteredAgentAttache)createAttache(hostId);
+                if (forwardAttache == null) {
+                    s_logger.warn("Unable to create a forward attache for the host " + hostId + " as a part of rebalance process");
+                    return false;
+                }
+                s_logger.debug("Putting agent id=" + hostId + " to transfer mode");
+                forwardAttache.setTransferMode(true);
+                _agents.put(hostId, forwardAttache);
+            } else {
+                if (attache == null) {
+                    s_logger.warn("Attache for the agent " + hostId + " no longer exists on management server " + _nodeId + ", can't start host rebalancing");
+                } else {
+                    s_logger.warn("Attache for the agent " + hostId + " has request queue size= " + attache.getQueueSize() + " and listener queue size " + attache.getNonRecurringListenersSize()
+                    + ", can't start host rebalancing");
+                }
+                return false;
+            }
+        }
+        _hostTransferDao.startAgentTransfer(hostId);
+        return true;
+    }
+
+    protected void cleanupTransferMap(final long msId) {
+        final List<HostTransferMapVO> hostsJoingingCluster = _hostTransferDao.listHostsJoiningCluster(msId);
+
+        for (final HostTransferMapVO hostJoingingCluster : hostsJoingingCluster) {
+            _hostTransferDao.remove(hostJoingingCluster.getId());
+        }
+
+        final List<HostTransferMapVO> hostsLeavingCluster = _hostTransferDao.listHostsLeavingCluster(msId);
+        for (final HostTransferMapVO hostLeavingCluster : hostsLeavingCluster) {
+            _hostTransferDao.remove(hostLeavingCluster.getId());
+        }
+    }
+
+    protected class RebalanceTask extends ManagedContextRunnable {
+        Long hostId = null;
+        Long currentOwnerId = null;
+        Long futureOwnerId = null;
+
+        public RebalanceTask(final long hostId, final long currentOwnerId, final long futureOwnerId) {
+            this.hostId = hostId;
+            this.currentOwnerId = currentOwnerId;
+            this.futureOwnerId = futureOwnerId;
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Rebalancing host id=" + hostId);
+                }
+                rebalanceHost(hostId, currentOwnerId, futureOwnerId);
+            } catch (final Exception e) {
+                s_logger.warn("Unable to rebalance host id=" + hostId, e);
+            }
+        }
+    }
+
+    private String handleScheduleHostScanTaskCommand(final ScheduleHostScanTaskCommand cmd) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Intercepting resource manager command: " + _gson.toJson(cmd));
+        }
+
+        try {
+            scheduleHostScanTask();
+        } catch (final Exception e) {
+            // Scheduling host scan task in peer MS is a best effort operation during host add, regular host scan
+            // happens at fixed intervals anyways. So handling any exceptions that may be thrown
+            s_logger.warn(
+                    "Exception happened while trying to schedule host scan task on mgmt server " + _clusterMgr.getSelfPeerName() + ", ignoring as regular host scan happens at fixed interval anyways",
+                    e);
+            return null;
+        }
+
+        final Answer[] answers = new Answer[1];
+        answers[0] = new Answer(cmd, true, null);
+        return _gson.toJson(answers);
+    }
+
+    public Answer[] sendToAgent(final Long hostId, final Command[] cmds, final boolean stopOnError) throws AgentUnavailableException, OperationTimedoutException {
+        final Commands commands = new Commands(stopOnError ? Command.OnError.Stop : Command.OnError.Continue);
+        for (final Command cmd : cmds) {
+            commands.addCommand(cmd);
+        }
+        return send(hostId, commands);
+    }
+
+    protected class ClusterDispatcher implements ClusterManager.Dispatcher {
+        @Override
+        public String getName() {
+            return "ClusterDispatcher";
+        }
+
+        @Override
+        public String dispatch(final ClusterServicePdu pdu) {
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Dispatch ->" + pdu.getAgentId() + ", json: " + pdu.getJsonPackage());
+            }
+
+            Command[] cmds = null;
+            try {
+                cmds = _gson.fromJson(pdu.getJsonPackage(), Command[].class);
+            } catch (final Throwable e) {
+                assert false;
+                s_logger.error("Excection in gson decoding : ", e);
+            }
+
+            if (cmds.length == 1 && cmds[0] instanceof ChangeAgentCommand) { // intercepted
+                final ChangeAgentCommand cmd = (ChangeAgentCommand)cmds[0];
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Intercepting command for agent change: agent " + cmd.getAgentId() + " event: " + cmd.getEvent());
+                }
+                boolean result = false;
+                try {
+                    result = executeAgentUserRequest(cmd.getAgentId(), cmd.getEvent());
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Result is " + result);
+                    }
+
+                } catch (final AgentUnavailableException e) {
+                    s_logger.warn("Agent is unavailable", e);
+                    return null;
+                }
+
+                final Answer[] answers = new Answer[1];
+                answers[0] = new ChangeAgentAnswer(cmd, result);
+                return _gson.toJson(answers);
+            } else if (cmds.length == 1 && cmds[0] instanceof TransferAgentCommand) {
+                final TransferAgentCommand cmd = (TransferAgentCommand)cmds[0];
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Intercepting command for agent rebalancing: agent " + cmd.getAgentId() + " event: " + cmd.getEvent());
+                }
+                boolean result = false;
+                try {
+                    result = rebalanceAgent(cmd.getAgentId(), cmd.getEvent(), cmd.getCurrentOwner(), cmd.getFutureOwner());
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Result is " + result);
+                    }
+
+                } catch (final AgentUnavailableException e) {
+                    s_logger.warn("Agent is unavailable", e);
+                    return null;
+                } catch (final OperationTimedoutException e) {
+                    s_logger.warn("Operation timed out", e);
+                    return null;
+                }
+                final Answer[] answers = new Answer[1];
+                answers[0] = new Answer(cmd, result, null);
+                return _gson.toJson(answers);
+            } else if (cmds.length == 1 && cmds[0] instanceof PropagateResourceEventCommand) {
+                final PropagateResourceEventCommand cmd = (PropagateResourceEventCommand)cmds[0];
+
+                s_logger.debug("Intercepting command to propagate event " + cmd.getEvent().name() + " for host " + cmd.getHostId());
+
+                boolean result = false;
+                try {
+                    result = _resourceMgr.executeUserRequest(cmd.getHostId(), cmd.getEvent());
+                    s_logger.debug("Result is " + result);
+                } catch (final AgentUnavailableException ex) {
+                    s_logger.warn("Agent is unavailable", ex);
+                    return null;
+                }
+
+                final Answer[] answers = new Answer[1];
+                answers[0] = new Answer(cmd, result, null);
+                return _gson.toJson(answers);
+            } else if (cmds.length == 1 && cmds[0] instanceof ScheduleHostScanTaskCommand) {
+                final ScheduleHostScanTaskCommand cmd = (ScheduleHostScanTaskCommand)cmds[0];
+                final String response = handleScheduleHostScanTaskCommand(cmd);
+                return response;
+            }
+
+            try {
+                final long startTick = System.currentTimeMillis();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Dispatch -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage());
+                }
+
+                final Answer[] answers = sendToAgent(pdu.getAgentId(), cmds, pdu.isStopOnError());
+                if (answers != null) {
+                    final String jsonReturn = _gson.toJson(answers);
+
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " + (System.currentTimeMillis() - startTick) + " ms, return result: "
+                                + jsonReturn);
+                    }
+
+                    return jsonReturn;
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug(
+                                "Completed dispatching -> " + pdu.getAgentId() + ", json: " + pdu.getJsonPackage() + " in " + (System.currentTimeMillis() - startTick) + " ms, return null result");
+                    }
+                }
+            } catch (final AgentUnavailableException e) {
+                s_logger.warn("Agent is unavailable", e);
+            } catch (final OperationTimedoutException e) {
+                s_logger.warn("Timed Out", e);
+            }
+
+            return null;
+        }
+
+    }
+
+    public boolean executeAgentUserRequest(final long agentId, final Event event) throws AgentUnavailableException {
+        return executeUserRequest(agentId, event);
+    }
+
+    public boolean rebalanceAgent(final long agentId, final Event event, final long currentOwnerId, final long futureOwnerId) throws AgentUnavailableException, OperationTimedoutException {
+        return executeRebalanceRequest(agentId, currentOwnerId, futureOwnerId, event);
+    }
+
+    public boolean isAgentRebalanceEnabled() {
+        return EnableLB.value();
+    }
+
+    private Runnable getAgentRebalanceScanTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                try {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Agent rebalance task check, management server id:" + _nodeId);
+                    }
+                    // initiate agent lb task will be scheduled and executed only once, and only when number of agents
+                    // loaded exceeds _connectedAgentsThreshold
+                    if (!_agentLbHappened) {
+                        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+                        sc.and(sc.entity().getManagementServerId(), Op.NNULL);
+                        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
+                        final List<HostVO> allManagedRoutingAgents = sc.list();
+
+                        sc = QueryBuilder.create(HostVO.class);
+                        sc.and(sc.entity().getType(), Op.EQ, Host.Type.Routing);
+                        final List<HostVO> allAgents = sc.list();
+                        final double allHostsCount = allAgents.size();
+                        final double managedHostsCount = allManagedRoutingAgents.size();
+                        if (allHostsCount > 0.0) {
+                            final double load = managedHostsCount / allHostsCount;
+                            if (load > ConnectedAgentThreshold.value()) {
+                                s_logger.debug("Scheduling agent rebalancing task as the average agent load " + load + " is more than the threshold " + ConnectedAgentThreshold.value());
+                                scheduleRebalanceAgents();
+                                _agentLbHappened = true;
+                            } else {
+                                s_logger.debug("Not scheduling agent rebalancing task as the average load " + load + " has not crossed the threshold " + ConnectedAgentThreshold.value());
+                            }
+                        }
+                    }
+                } catch (final Throwable e) {
+                    s_logger.error("Problem with the clustered agent transfer scan check!", e);
+                }
+            }
+        };
+    }
+
+    @Override
+    public void rescan() {
+        // schedule a scan task immediately
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Scheduling a host scan task");
+        }
+        // schedule host scan task on current MS
+        scheduleHostScanTask();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Notifying all peer MS to schedule host scan task");
+        }
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        final ConfigKey<?>[] keys = super.getConfigKeys();
+
+        final List<ConfigKey<?>> keysLst = new ArrayList<ConfigKey<?>>();
+        keysLst.addAll(Arrays.asList(keys));
+        keysLst.add(EnableLB);
+        keysLst.add(ConnectedAgentThreshold);
+        keysLst.add(LoadSize);
+        keysLst.add(ScanInterval);
+        return keysLst.toArray(new ConfigKey<?>[keysLst.size()]);
+    }
+}
diff --git a/engine/orchestration/src/com/cloud/agent/manager/ClusteredDirectAgentAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredDirectAgentAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/ClusteredDirectAgentAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/ClusteredDirectAgentAttache.java
diff --git a/engine/orchestration/src/com/cloud/agent/manager/ConnectedAgentAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/ConnectedAgentAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/ConnectedAgentAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/ConnectedAgentAttache.java
diff --git a/engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/DirectAgentAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/DirectAgentAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/DirectAgentAttache.java
diff --git a/engine/orchestration/src/com/cloud/agent/manager/DummyAttache.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/DummyAttache.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/DummyAttache.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/DummyAttache.java
diff --git a/engine/orchestration/src/com/cloud/agent/manager/Routable.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/Routable.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/Routable.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/Routable.java
diff --git a/engine/orchestration/src/com/cloud/agent/manager/SynchronousListener.java b/engine/orchestration/src/main/java/com/cloud/agent/manager/SynchronousListener.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/agent/manager/SynchronousListener.java
rename to engine/orchestration/src/main/java/com/cloud/agent/manager/SynchronousListener.java
diff --git a/engine/orchestration/src/com/cloud/cluster/ClusteredAgentRebalanceService.java b/engine/orchestration/src/main/java/com/cloud/cluster/ClusteredAgentRebalanceService.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/cluster/ClusteredAgentRebalanceService.java
rename to engine/orchestration/src/main/java/com/cloud/cluster/ClusteredAgentRebalanceService.java
diff --git a/engine/orchestration/src/com/cloud/cluster/agentlb/AgentLoadBalancerPlanner.java b/engine/orchestration/src/main/java/com/cloud/cluster/agentlb/AgentLoadBalancerPlanner.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/cluster/agentlb/AgentLoadBalancerPlanner.java
rename to engine/orchestration/src/main/java/com/cloud/cluster/agentlb/AgentLoadBalancerPlanner.java
diff --git a/engine/orchestration/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java b/engine/orchestration/src/main/java/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
rename to engine/orchestration/src/main/java/com/cloud/cluster/agentlb/ClusterBasedAgentLoadBalancerPlanner.java
diff --git a/engine/orchestration/src/main/java/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java
new file mode 100644
index 0000000..b8995f6
--- /dev/null
+++ b/engine/orchestration/src/main/java/com/cloud/vm/ClusteredVirtualMachineManagerImpl.java
@@ -0,0 +1,62 @@
+// 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.vm;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.cluster.ClusterManager;
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+
+public class ClusteredVirtualMachineManagerImpl extends VirtualMachineManagerImpl implements ClusterManagerListener {
+
+    @Inject
+    ClusterManager _clusterMgr;
+
+    protected ClusteredVirtualMachineManagerImpl() {
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (ManagementServerHost node : nodeList) {
+            cancelWorkItems(node.getMsid());
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> xmlParams) throws ConfigurationException {
+        super.configure(name, xmlParams);
+
+        _clusterMgr.registerListener(this);
+
+        return true;
+    }
+
+}
diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
new file mode 100755
index 0000000..7d218e2
--- /dev/null
+++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -0,0 +1,5299 @@
+// Licensed to the Apacohe 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.vm;
+
+import java.net.URI;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
+import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.ca.CAManager;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.ca.Certificate;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.Outcome;
+import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.framework.jobs.impl.JobSerializerHelper;
+import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
+import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
+import org.apache.cloudstack.framework.messagebus.MessageHandler;
+import org.apache.cloudstack.jobs.JobInfo;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachOrDettachConfigDriveCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer;
+import com.cloud.agent.api.ClusterVMMetaDataSyncCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.MigrateVmToPoolAnswer;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.ReplugNicAnswer;
+import com.cloud.agent.api.ReplugNicCommand;
+import com.cloud.agent.api.RestoreVMSnapshotAnswer;
+import com.cloud.agent.api.RestoreVMSnapshotCommand;
+import com.cloud.agent.api.ScaleVmCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.UnregisterVMCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.GPUDeviceTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.agent.manager.allocator.HostAllocator;
+import com.cloud.alert.AlertManager;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.AffinityConflictException;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.ha.HighAvailabilityManager.WorkType;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.DiskOfferingInfo;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.org.Cluster;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Journal;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Predicate;
+import com.cloud.utils.ReflectionUse;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.ItWorkVO.Step;
+import com.cloud.vm.VirtualMachine.Event;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import com.google.common.base.Strings;
+
+public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, VmWorkJobHandler, Listener, Configurable {
+    private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
+
+    public static final String VM_WORK_JOB_HANDLER = VirtualMachineManagerImpl.class.getSimpleName();
+
+    private static final String VM_SYNC_ALERT_SUBJECT = "VM state sync alert";
+
+    @Inject
+    private DataStoreManager dataStoreMgr;
+    @Inject
+    private NetworkOrchestrationService _networkMgr;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private ItWorkDao _workDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private UserVmService _userVmService;
+    @Inject
+    private CapacityManager _capacityMgr;
+    @Inject
+    private NicDao _nicsDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    private GuestOSCategoryDao _guestOsCategoryDao;
+    @Inject
+    private GuestOSDao _guestOsDao;
+    @Inject
+    private VolumeDao _volsDao;
+    @Inject
+    private HighAvailabilityManager _haMgr;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private HypervisorGuruManager _hvGuruMgr;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private StoragePoolHostDao _poolHostDao;
+    @Inject
+    private VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    private AffinityGroupVMMapDao _affinityGroupVMMapDao;
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private GuestOSCategoryDao _guestOSCategoryDao;
+    @Inject
+    private GuestOSDao _guestOSDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private CAManager caManager;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private VMSnapshotManager _vmSnapshotMgr;
+    @Inject
+    private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private UserVmDetailsDao userVmDetailsDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private VolumeOrchestrationService volumeMgr;
+    @Inject
+    private DeploymentPlanningManager _dpMgr;
+    @Inject
+    private MessageBus _messageBus;
+    @Inject
+    private VirtualMachinePowerStateSync _syncMgr;
+    @Inject
+    private VmWorkJobDao _workJobDao;
+    @Inject
+    private AsyncJobManager _jobMgr;
+    @Inject
+    private StorageManager storageMgr;
+
+    VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
+
+    Map<VirtualMachine.Type, VirtualMachineGuru> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru>();
+    protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
+
+    static final ConfigKey<Integer> StartRetry = new ConfigKey<Integer>("Advanced", Integer.class, "start.retry", "10",
+            "Number of times to retry create and start commands", true);
+    static final ConfigKey<Integer> VmOpWaitInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.op.wait.interval", "120",
+            "Time (in seconds) to wait before checking if a previous operation has succeeded", true);
+
+    static final ConfigKey<Integer> VmOpLockStateRetry = new ConfigKey<Integer>("Advanced", Integer.class, "vm.op.lock.state.retry", "5",
+            "Times to retry locking the state of a VM for operations, -1 means forever", true);
+    static final ConfigKey<Long> VmOpCleanupInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cleanup.interval", "86400",
+            "Interval to run the thread that cleans up the vm operations (in seconds)", false);
+    static final ConfigKey<Long> VmOpCleanupWait = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cleanup.wait", "3600",
+            "Time (in seconds) to wait before cleanuping up any vm work items", true);
+    static final ConfigKey<Long> VmOpCancelInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.op.cancel.interval", "3600",
+            "Time (in seconds) to wait before cancelling a operation", false);
+    static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
+            "On destroy, force-stop takes this value ", true);
+    static final ConfigKey<Integer> ClusterDeltaSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "sync.interval", "60",
+            "Cluster Delta sync interval in seconds",
+            false);
+    static final ConfigKey<Integer> ClusterVMMetaDataSyncInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vmmetadata.sync.interval", "180", "Cluster VM metadata sync interval in seconds",
+            false);
+
+    static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced",
+            Long.class, "vm.job.check.interval", "3000",
+            "Interval in milliseconds to check if the job is complete", false);
+    static final ConfigKey<Long> VmJobTimeout = new ConfigKey<Long>("Advanced",
+            Long.class, "vm.job.timeout", "600000",
+            "Time in milliseconds to wait before attempting to cancel a job", false);
+    static final ConfigKey<Integer> VmJobStateReportInterval = new ConfigKey<Integer>("Advanced",
+            Integer.class, "vm.job.report.interval", "60",
+            "Interval to send application level pings to make sure the connection is still working", false);
+
+    static final ConfigKey<Boolean> HaVmRestartHostUp = new ConfigKey<Boolean>("Advanced", Boolean.class, "ha.vm.restart.hostup", "true",
+            "If an out-of-band stop of a VM is detected and its host is up, then power on the VM", true);
+
+    ScheduledExecutorService _executor = null;
+
+    private long _nodeId;
+
+    private List<StoragePoolAllocator> _storagePoolAllocators;
+
+    private List<HostAllocator> hostAllocators;
+
+    public List<HostAllocator> getHostAllocators() {
+        return hostAllocators;
+    }
+
+    public void setHostAllocators(final List<HostAllocator> hostAllocators) {
+        this.hostAllocators = hostAllocators;
+    }
+
+    @Override
+    public void registerGuru(final VirtualMachine.Type type, final VirtualMachineGuru guru) {
+        synchronized (_vmGurus) {
+            _vmGurus.put(type, guru);
+        }
+    }
+
+    @Override
+    @DB
+    public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
+            final DiskOfferingInfo rootDiskOfferingInfo, final List<DiskOfferingInfo> dataDiskOfferings,
+            final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, final DeploymentPlan plan, final HypervisorType hyperType, final Map<String, Map<Integer, String>> extraDhcpOptions, final Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap)
+                    throws InsufficientCapacityException {
+
+        final VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName);
+        final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Allocating entries for VM: " + vm);
+        }
+
+        vm.setDataCenterId(plan.getDataCenterId());
+        if (plan.getPodId() != null) {
+            vm.setPodIdToDeployIn(plan.getPodId());
+        }
+        assert plan.getClusterId() == null && plan.getPoolId() == null : "We currently don't support cluster and pool preset yet";
+        final VMInstanceVO vmFinal = _vmDao.persist(vm);
+
+        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmFinal, template, serviceOffering, null, null);
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Allocating nics for " + vmFinal);
+                }
+
+                try {
+                    if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm")) {
+                        _networkMgr.allocate(vmProfile, auxiliaryNetworks, extraDhcpOptions);
+                    }
+                } catch (final ConcurrentOperationException e) {
+                    throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e);
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Allocating disks for " + vmFinal);
+                }
+
+                if (template.getFormat() == ImageFormat.ISO) {
+                    volumeMgr.allocateRawVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
+                            rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
+                } else if (template.getFormat() == ImageFormat.BAREMETAL) {
+                    // Do nothing
+                } else {
+                    volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
+                            rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner);
+                }
+
+                if (dataDiskOfferings != null) {
+                    for (final DiskOfferingInfo dataDiskOfferingInfo : dataDiskOfferings) {
+                        volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId(), dataDiskOfferingInfo.getDiskOffering(), dataDiskOfferingInfo.getSize(),
+                                dataDiskOfferingInfo.getMinIops(), dataDiskOfferingInfo.getMaxIops(), vmFinal, template, owner, null);
+                    }
+                }
+                if (datadiskTemplateToDiskOfferingMap != null && !datadiskTemplateToDiskOfferingMap.isEmpty()) {
+                    int diskNumber = 1;
+                    for (Entry<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap : datadiskTemplateToDiskOfferingMap.entrySet()) {
+                        DiskOffering diskOffering = dataDiskTemplateToDiskOfferingMap.getValue();
+                        long diskOfferingSize = diskOffering.getDiskSize() / (1024 * 1024 * 1024);
+                        VMTemplateVO dataDiskTemplate = _templateDao.findById(dataDiskTemplateToDiskOfferingMap.getKey());
+                        volumeMgr.allocateRawVolume(Type.DATADISK, "DATA-" + vmFinal.getId() + "-" + String.valueOf(diskNumber), diskOffering, diskOfferingSize, null, null,
+                                vmFinal, dataDiskTemplate, owner, Long.valueOf(diskNumber));
+                        diskNumber++;
+                    }
+                }
+            }
+        });
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Allocation completed for VM: " + vmFinal);
+        }
+    }
+
+    @Override
+    public void allocate(final String vmInstanceName, final VirtualMachineTemplate template, final ServiceOffering serviceOffering,
+            final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final DeploymentPlan plan, final HypervisorType hyperType) throws InsufficientCapacityException {
+        allocate(vmInstanceName, template, serviceOffering, new DiskOfferingInfo(serviceOffering), new ArrayList<DiskOfferingInfo>(), networks, plan, hyperType, null, null);
+    }
+
+    private VirtualMachineGuru getVmGuru(final VirtualMachine vm) {
+        if(vm != null) {
+            return _vmGurus.get(vm.getType());
+        }
+        return null;
+    }
+
+    @Override
+    public void expunge(final String vmUuid) throws ResourceUnavailableException {
+        try {
+            advanceExpunge(vmUuid);
+        } catch (final OperationTimedoutException e) {
+            throw new CloudRuntimeException("Operation timed out", e);
+        } catch (final ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Concurrent operation ", e);
+        }
+    }
+
+    @Override
+    public void advanceExpunge(final String vmUuid) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        advanceExpunge(vm);
+    }
+
+    protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+        if (vm == null || vm.getRemoved() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
+            }
+            return;
+        }
+
+        advanceStop(vm.getUuid(), false);
+        vm = _vmDao.findByUuid(vm.getUuid());
+
+        try {
+            if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) {
+                s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
+                throw new CloudRuntimeException("Unable to destroy " + vm);
+
+            }
+        } catch (final NoTransitionException e) {
+            s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
+            throw new CloudRuntimeException("Unable to destroy " + vm, e);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Destroying vm " + vm);
+        }
+
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
+
+        s_logger.debug("Cleaning up NICS");
+        final List<Command> nicExpungeCommands = hvGuru.finalizeExpungeNics(vm, profile.getNics());
+        _networkMgr.cleanupNics(profile);
+
+        s_logger.debug("Cleaning up hypervisor data structures (ex. SRs in XenServer) for managed storage");
+
+        final List<Command> volumeExpungeCommands = hvGuru.finalizeExpungeVolumes(vm);
+
+        final Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
+
+        List<Map<String, String>> targets = getTargets(hostId, vm.getId());
+
+        if (volumeExpungeCommands != null && volumeExpungeCommands.size() > 0 && hostId != null) {
+            final Commands cmds = new Commands(Command.OnError.Stop);
+
+            for (final Command volumeExpungeCommand : volumeExpungeCommands) {
+                cmds.addCommand(volumeExpungeCommand);
+            }
+
+            _agentMgr.send(hostId, cmds);
+
+            if (!cmds.isSuccessful()) {
+                for (final Answer answer : cmds.getAnswers()) {
+                    if (!answer.getResult()) {
+                        s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
+
+                        throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails());
+                    }
+                }
+            }
+        }
+
+        if (hostId != null) {
+            volumeMgr.revokeAccess(vm.getId(), hostId);
+        }
+
+        // Clean up volumes based on the vm's instance id
+        volumeMgr.cleanupVolumes(vm.getId());
+
+        if (hostId != null && CollectionUtils.isNotEmpty(targets)) {
+            removeDynamicTargets(hostId, targets);
+        }
+
+        final VirtualMachineGuru guru = getVmGuru(vm);
+        guru.finalizeExpunge(vm);
+        //remove the overcommit details from the uservm details
+        userVmDetailsDao.removeDetails(vm.getId());
+
+        // send hypervisor-dependent commands before removing
+        final List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm);
+        if (finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0) {
+            if (hostId != null) {
+                final Commands cmds = new Commands(Command.OnError.Stop);
+                for (final Command command : finalizeExpungeCommands) {
+                    cmds.addCommand(command);
+                }
+                if (nicExpungeCommands != null) {
+                    for (final Command command : nicExpungeCommands) {
+                        cmds.addCommand(command);
+                    }
+                }
+                _agentMgr.send(hostId, cmds);
+                if (!cmds.isSuccessful()) {
+                    for (final Answer answer : cmds.getAnswers()) {
+                        if (!answer.getResult()) {
+                            s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
+                            throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails());
+                        }
+                    }
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Expunged " + vm);
+        }
+
+    }
+
+    private List<Map<String, String>> getTargets(Long hostId, long vmId) {
+        List<Map<String, String>> targets = new ArrayList<>();
+
+        HostVO hostVO = _hostDao.findById(hostId);
+
+        if (hostVO == null || hostVO.getHypervisorType() != HypervisorType.VMware) {
+            return targets;
+        }
+
+        List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
+
+        if (CollectionUtils.isEmpty(volumes)) {
+            return targets;
+        }
+
+        for (VolumeVO volume : volumes) {
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
+
+            if (storagePoolVO != null && storagePoolVO.isManaged()) {
+                Map<String, String> target = new HashMap<>();
+
+                target.put(ModifyTargetsCommand.STORAGE_HOST, storagePoolVO.getHostAddress());
+                target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
+                target.put(ModifyTargetsCommand.IQN, volume.get_iScsiName());
+
+                targets.add(target);
+            }
+        }
+
+        return targets;
+    }
+
+    private void removeDynamicTargets(long hostId, List<Map<String, String>> targets) {
+        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+        cmd.setTargets(targets);
+        cmd.setApplyToAllHostsInCluster(true);
+        cmd.setAdd(false);
+        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+
+        sendModifyTargetsCommand(cmd, hostId);
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            String msg = "Unable to get an answer to the modify targets command";
+
+            s_logger.warn(msg);
+        }
+        else if (!answer.getResult()) {
+            String msg = "Unable to modify target on the following host: " + hostId;
+
+            s_logger.warn(msg);
+        }
+    }
+
+    @Override
+    public boolean start() {
+        // TODO, initial delay is hardcoded
+        _executor.scheduleAtFixedRate(new CleanupTask(), 5, VmJobStateReportInterval.value(), TimeUnit.SECONDS);
+        _executor.scheduleAtFixedRate(new TransitionTask(),  VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS);
+        cancelWorkItems(_nodeId);
+
+        volumeMgr.cleanupStorageJobs();
+        // cleanup left over place holder works
+        _workJobDao.expungeLeftoverWorkJobs(ManagementServerNode.getManagementServerId());
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
+        ReservationContextImpl.init(_entityMgr);
+        VirtualMachineProfileImpl.init(_entityMgr);
+        VmWorkMigrate.init(_entityMgr);
+
+        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
+        _nodeId = ManagementServerNode.getManagementServerId();
+
+        _agentMgr.registerForHostEvents(this, true, true, true);
+
+        _messageBus.subscribe(VirtualMachineManager.Topics.VM_POWER_STATE, MessageDispatcher.getDispatcher(this));
+
+        return true;
+    }
+
+    protected VirtualMachineManagerImpl() {
+        setStateMachine();
+    }
+
+    @Override
+    public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) {
+        start(vmUuid, params, null, null);
+    }
+
+    @Override
+    public void start(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner) {
+        try {
+            advanceStart(vmUuid, params, planToDeploy, planner);
+        } catch (final ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e).add(VirtualMachine.class, vmUuid);
+        } catch (final InsufficientCapacityException e) {
+            throw new CloudRuntimeException("Unable to start a VM due to insufficient capacity", e).add(VirtualMachine.class, vmUuid);
+        } catch (final ResourceUnavailableException e) {
+            if(e.getScope() != null && e.getScope().equals(VirtualRouter.class)){
+                throw new CloudRuntimeException("Network is unavailable. Please contact administrator", e).add(VirtualMachine.class, vmUuid);
+            }
+            throw new CloudRuntimeException("Unable to start a VM due to unavailable resources", e).add(VirtualMachine.class, vmUuid);
+        }
+
+    }
+
+    protected boolean checkWorkItems(final VMInstanceVO vm, final State state) throws ConcurrentOperationException {
+        while (true) {
+            final ItWorkVO vo = _workDao.findByOutstandingWork(vm.getId(), state);
+            if (vo == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to find work for VM: " + vm + " and state: " + state);
+                }
+                return true;
+            }
+
+            if (vo.getStep() == Step.Done) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Work for " + vm + " is " + vo.getStep());
+                }
+                return true;
+            }
+
+            // also check DB to get latest VM state to detect vm update from concurrent process before idle waiting to get an early exit
+            final VMInstanceVO instance = _vmDao.findById(vm.getId());
+            if (instance != null && instance.getState() == State.Running) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("VM is already started in DB: " + vm);
+                }
+                return true;
+            }
+
+            if (vo.getSecondsTaskIsInactive() > VmOpCancelInterval.value()) {
+                s_logger.warn("The task item for vm " + vm + " has been inactive for " + vo.getSecondsTaskIsInactive());
+                return false;
+            }
+
+            try {
+                Thread.sleep(VmOpWaitInterval.value()*1000);
+            } catch (final InterruptedException e) {
+                s_logger.info("Waiting for " + vm + " but is interrupted");
+                throw new ConcurrentOperationException("Waiting for " + vm + " but is interrupted");
+            }
+            s_logger.debug("Waiting some more to make sure there's no activity on " + vm);
+        }
+
+    }
+
+    @DB
+    protected Ternary<VMInstanceVO, ReservationContext, ItWorkVO> changeToStartState(final VirtualMachineGuru vmGuru, final VMInstanceVO vm, final User caller,
+            final Account account) throws ConcurrentOperationException {
+        final long vmId = vm.getId();
+
+        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getType(), vm.getId());
+        int retry = VmOpLockStateRetry.value();
+        while (retry-- != 0) {
+            try {
+                final ItWorkVO workFinal = work;
+                final Ternary<VMInstanceVO, ReservationContext, ItWorkVO> result =
+                        Transaction.execute(new TransactionCallbackWithException<Ternary<VMInstanceVO, ReservationContext, ItWorkVO>, NoTransitionException>() {
+                            @Override
+                            public Ternary<VMInstanceVO, ReservationContext, ItWorkVO> doInTransaction(final TransactionStatus status) throws NoTransitionException {
+                                final Journal journal = new Journal.LogJournal("Creating " + vm, s_logger);
+                                final ItWorkVO work = _workDao.persist(workFinal);
+                                final ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account);
+
+                                if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) {
+                                    if (s_logger.isDebugEnabled()) {
+                                        s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId());
+                                    }
+                                    return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(vm, context, work);
+                                }
+
+                                return new Ternary<VMInstanceVO, ReservationContext, ItWorkVO>(null, null, work);
+                            }
+                        });
+
+                work = result.third();
+                if (result.first() != null) {
+                    return result;
+                }
+            } catch (final NoTransitionException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to transition into Starting state due to " + e.getMessage());
+                }
+            }
+
+            final VMInstanceVO instance = _vmDao.findById(vmId);
+            if (instance == null) {
+                throw new ConcurrentOperationException("Unable to acquire lock on " + vm);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Determining why we're unable to update the state to Starting for " + instance + ".  Retry=" + retry);
+            }
+
+            final State state = instance.getState();
+            if (state == State.Running) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("VM is already started: " + vm);
+                }
+                return null;
+            }
+
+            if (state.isTransitional()) {
+                if (!checkWorkItems(vm, state)) {
+                    throw new ConcurrentOperationException("There are concurrent operations on " + vm);
+                } else {
+                    continue;
+                }
+            }
+
+            if (state != State.Stopped) {
+                s_logger.debug("VM " + vm + " is not in a state to be started: " + state);
+                return null;
+            }
+        }
+
+        throw new ConcurrentOperationException("Unable to change the state of " + vm);
+    }
+
+    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.
+        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 && work != null) {
+                _workDao.updateStep(work, previousStep);
+            }
+        }
+    }
+
+    protected boolean areAffinityGroupsAssociated(final VirtualMachineProfile vmProfile) {
+        final VirtualMachine vm = vmProfile.getVirtualMachine();
+        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
+
+        if (vmGroupCount > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void advanceStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlanner planner)
+            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+        advanceStart(vmUuid, params, null, planner);
+    }
+
+    @Override
+    public void advanceStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner)
+            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if ( jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateStart(vmUuid, params, planToDeploy, planner);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy, planner);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof InsufficientCapacityException) {
+                    throw (InsufficientCapacityException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+            }
+        }
+    }
+
+    private void setupAgentSecurity(final Host vmHost, final Map<String, String> sshAccessDetails, final VirtualMachine vm) throws AgentUnavailableException, OperationTimedoutException {
+        final String csr = caManager.generateKeyStoreAndCsr(vmHost, sshAccessDetails);
+        if (!Strings.isNullOrEmpty(csr)) {
+            final Map<String, String> ipAddressDetails = new HashMap<>(sshAccessDetails);
+            ipAddressDetails.remove(NetworkElementCommand.ROUTER_NAME);
+            final Certificate certificate = caManager.issueCertificate(csr, Arrays.asList(vm.getHostName(), vm.getInstanceName()),
+                    new ArrayList<>(ipAddressDetails.values()), CAManager.CertValidityPeriod.value(), null);
+            final boolean result = caManager.deployCertificate(vmHost, certificate, false, sshAccessDetails);
+            if (!result) {
+                s_logger.error("Failed to setup certificate for system vm: " + vm.getInstanceName());
+            }
+        } else {
+            s_logger.error("Failed to setup keystore and generate CSR for system vm: " + vm.getInstanceName());
+        }
+    }
+
+    @Override
+    public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params, final DeploymentPlan planToDeploy, final DeploymentPlanner planner)
+            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+
+        final CallContext cctxt = CallContext.current();
+        final Account account = cctxt.getCallingAccount();
+        final User caller = cctxt.getCallingUser();
+
+        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final VirtualMachineGuru vmGuru = getVmGuru(vm);
+
+        final Ternary<VMInstanceVO, ReservationContext, ItWorkVO> start = changeToStartState(vmGuru, vm, caller, account);
+        if (start == null) {
+            return;
+        }
+
+        vm = start.first();
+        final ReservationContext ctx = start.second();
+        ItWorkVO work = start.third();
+
+        VMInstanceVO startedVm = null;
+        final ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
+        final VirtualMachineTemplate template = _entityMgr.findByIdIncludingRemoved(VirtualMachineTemplate.class, vm.getTemplateId());
+
+        DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodIdToDeployIn(), null, null, null, null, ctx);
+        if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("advanceStart: DeploymentPlan is provided, using dcId:" + planToDeploy.getDataCenterId() + ", podId: " + planToDeploy.getPodId() +
+                        ", clusterId: " + planToDeploy.getClusterId() + ", hostId: " + planToDeploy.getHostId() + ", poolId: " + planToDeploy.getPoolId());
+            }
+            plan =
+                    new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(),
+                            planToDeploy.getPoolId(), planToDeploy.getPhysicalNetworkId(), ctx);
+        }
+
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
+
+        boolean canRetry = true;
+        ExcludeList avoids = null;
+        try {
+            final Journal journal = start.second().getJournal();
+
+            if (planToDeploy != null) {
+                avoids = planToDeploy.getAvoids();
+            }
+            if (avoids == null) {
+                avoids = new ExcludeList();
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
+            }
+
+            boolean planChangedByVolume = false;
+            boolean reuseVolume = true;
+            final DataCenterDeployment originalPlan = plan;
+
+            int retry = StartRetry.value();
+            while (retry-- != 0) { // It's != so that it can match -1.
+
+                if (reuseVolume) {
+                    // edit plan if this vm's ROOT volume is in READY state already
+                    final List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
+                    for (final VolumeVO vol : vols) {
+                        // make sure if the templateId is unchanged. If it is changed,
+                        // let planner
+                        // reassign pool for the volume even if it ready.
+                        final Long volTemplateId = vol.getTemplateId();
+                        if (volTemplateId != null && volTemplateId.longValue() != template.getId()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool");
+                            }
+                            continue;
+                        }
+
+                        final StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(vol.getPoolId());
+                        if (!pool.isInMaintenance()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Root volume is ready, need to place VM in volume's cluster");
+                            }
+                            final long rootVolDcId = pool.getDataCenterId();
+                            final Long rootVolPodId = pool.getPodId();
+                            final Long rootVolClusterId = pool.getClusterId();
+                            if (planToDeploy != null && planToDeploy.getDataCenterId() != 0) {
+                                final Long clusterIdSpecified = planToDeploy.getClusterId();
+                                if (clusterIdSpecified != null && rootVolClusterId != null) {
+                                    if (rootVolClusterId.longValue() != clusterIdSpecified.longValue()) {
+                                        // cannot satisfy the plan passed in to the
+                                        // planner
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: " +
+                                                    rootVolClusterId + ", cluster specified: " + clusterIdSpecified);
+                                        }
+                                        throw new ResourceUnavailableException(
+                                                "Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " +
+                                                        vm, Cluster.class, clusterIdSpecified);
+                                    }
+                                }
+                                plan =
+                                        new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(),
+                                                planToDeploy.getHostId(), vol.getPoolId(), null, ctx);
+                            } else {
+                                plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId(), null, ctx);
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId +
+                                            " , and clusterId: " + rootVolClusterId);
+                                }
+                                planChangedByVolume = true;
+                            }
+                        }
+                    }
+                }
+
+                final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
+                final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
+                DeployDestination dest = null;
+                try {
+                    dest = _dpMgr.planDeployment(vmProfile, plan, avoids, planner);
+                } catch (final AffinityConflictException e2) {
+                    s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
+                    throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
+
+                }
+
+                if (dest == null) {
+                    if (planChangedByVolume) {
+                        plan = originalPlan;
+                        planChangedByVolume = false;
+                        //do not enter volume reuse for next retry, since we want to look for resources outside the volume's cluster
+                        reuseVolume = false;
+                        continue;
+                    }
+                    throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId(),
+                            areAffinityGroupsAssociated(vmProfile));
+                }
+
+                if (dest != null) {
+                    avoids.addHost(dest.getHost().getId());
+                    journal.record("Deployment found ", vmProfile, dest);
+                }
+
+                long destHostId = dest.getHost().getId();
+                vm.setPodIdToDeployIn(dest.getPod().getId());
+                final Long cluster_id = dest.getCluster().getId();
+                final ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, "cpuOvercommitRatio");
+                final ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio");
+                //storing the value of overcommit in the vm_details table for doing a capacity check in case the cluster overcommit ratio is changed.
+                if (userVmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") == null &&
+                        (Float.parseFloat(cluster_detail_cpu.getValue()) > 1f || Float.parseFloat(cluster_detail_ram.getValue()) > 1f)) {
+                    userVmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true);
+                    userVmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true);
+                } else if (userVmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio") != null) {
+                    userVmDetailsDao.addDetail(vm.getId(), "cpuOvercommitRatio", cluster_detail_cpu.getValue(), true);
+                    userVmDetailsDao.addDetail(vm.getId(), "memoryOvercommitRatio", cluster_detail_ram.getValue(), true);
+                }
+
+                vmProfile.setCpuOvercommitRatio(Float.parseFloat(cluster_detail_cpu.getValue()));
+                vmProfile.setMemoryOvercommitRatio(Float.parseFloat(cluster_detail_ram.getValue()));
+                StartAnswer startAnswer = null;
+
+                try {
+                    if (!changeState(vm, Event.OperationRetry, destHostId, work, Step.Prepare)) {
+                        throw new ConcurrentOperationException("Unable to update the state of the Virtual Machine "+vm.getUuid()+" oldstate: "+vm.getState()+ "Event :"+Event.OperationRetry);
+                    }
+                } catch (final NoTransitionException e1) {
+                    throw new ConcurrentOperationException(e1.getMessage());
+                }
+
+                try {
+                    _networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null, dest.getStorageForDisks()), ctx);
+                    if (vm.getHypervisorType() != HypervisorType.BareMetal) {
+                        volumeMgr.prepare(vmProfile, dest);
+                    }
+
+                    //since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity
+                    if (!reuseVolume) {
+                        reuseVolume = true;
+                    }
+
+                    Commands cmds = null;
+                    vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx);
+
+                    final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
+
+                    handlePath(vmTO.getDisks(), vm.getHypervisorType());
+
+                    cmds = new Commands(Command.OnError.Stop);
+
+                    cmds.addCommand(new StartCommand(vmTO, dest.getHost(), getExecuteInSequence(vm.getHypervisorType())));
+
+                    vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx);
+
+                    addExtraConfig(vmTO);
+
+                    work = _workDao.findById(work.getId());
+                    if (work == null || work.getStep() != Step.Prepare) {
+                        throw new ConcurrentOperationException("Work steps have been changed: " + work);
+                    }
+
+                    _workDao.updateStep(work, Step.Starting);
+
+                    _agentMgr.send(destHostId, cmds);
+
+                    _workDao.updateStep(work, Step.Started);
+
+                    startAnswer = cmds.getAnswer(StartAnswer.class);
+                    if (startAnswer != null && startAnswer.getResult()) {
+                        handlePath(vmTO.getDisks(), startAnswer.getIqnToData());
+
+                        final String host_guid = startAnswer.getHost_guid();
+
+                        if (host_guid != null) {
+                            final HostVO finalHost = _resourceMgr.findHostByGuid(host_guid);
+                            if (finalHost == null) {
+                                throw new CloudRuntimeException("Host Guid " + host_guid + " doesn't exist in DB, something went wrong while processing start answer: "+startAnswer);
+                            }
+                            destHostId = finalHost.getId();
+                        }
+                        if (vmGuru.finalizeStart(vmProfile, destHostId, cmds, ctx)) {
+                            syncDiskChainChange(startAnswer);
+
+                            if (!changeState(vm, Event.OperationSucceeded, destHostId, work, Step.Done)) {
+                                s_logger.error("Unable to transition to a new state. VM uuid: "+vm.getUuid()+    "VM oldstate:"+vm.getState()+"Event:"+Event.OperationSucceeded);
+                                throw new ConcurrentOperationException("Failed to deploy VM"+ vm.getUuid());
+                            }
+
+                            // Update GPU device capacity
+                            final GPUDeviceTO gpuDevice = startAnswer.getVirtualMachine().getGpuDevice();
+                            if (gpuDevice != null) {
+                                _resourceMgr.updateGPUDetails(destHostId, gpuDevice.getGroupDetails());
+                            }
+
+                            // Remove the information on whether it was a deploy vm request.The deployvm=true information
+                            // is set only when the vm is being deployed. When a vm is started from a stop state the
+                            // information isn't set,
+                            if (userVmDetailsDao.findDetail(vm.getId(), "deployvm") != null) {
+                                userVmDetailsDao.removeDetail(vm.getId(), "deployvm");
+                            }
+
+                            startedVm = vm;
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Start completed for VM " + vm);
+                            }
+                            final Host vmHost = _hostDao.findById(destHostId);
+                            if (vmHost != null && (VirtualMachine.Type.ConsoleProxy.equals(vm.getType()) ||
+                                    VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) && caManager.canProvisionCertificates()) {
+                                final Map<String, String> sshAccessDetails = _networkMgr.getSystemVMAccessDetails(vm);
+                                for (int retries = 3; retries > 0; retries--) {
+                                    try {
+                                        setupAgentSecurity(vmHost, sshAccessDetails, vm);
+                                        return;
+                                    } catch (final Exception e) {
+                                        s_logger.error("Retrying after catching exception while trying to secure agent for systemvm id=" + vm.getId(), e);
+                                    }
+                                }
+                                throw new CloudRuntimeException("Failed to setup and secure agent for systemvm id=" + vm.getId());
+                            }
+                            return;
+                        } else {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.info("The guru did not like the answers so stopping " + vm);
+                            }
+                            StopCommand stopCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
+                            stopCmd.setControlIp(getControlNicIpForVM(vm));
+                            final StopCommand cmd = stopCmd;
+                            final Answer answer = _agentMgr.easySend(destHostId, cmd);
+                            if (answer != null && answer instanceof StopAnswer) {
+                                final StopAnswer stopAns = (StopAnswer)answer;
+                                if (vm.getType() == VirtualMachine.Type.User) {
+                                    final String platform = stopAns.getPlatform();
+                                    if (platform != null) {
+                                        final Map<String,String> vmmetadata = new HashMap<String,String>();
+                                        vmmetadata.put(vm.getInstanceName(), platform);
+                                        syncVMMetaData(vmmetadata);
+                                    }
+                                }
+                            }
+
+                            if (answer == null || !answer.getResult()) {
+                                s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers"));
+                                _haMgr.scheduleStop(vm, destHostId, WorkType.ForceStop);
+                                throw new ExecutionException("Unable to stop this VM, "+vm.getUuid()+" so we are unable to retry the start operation");
+                            }
+                            throw new ExecutionException("Unable to start  VM:"+vm.getUuid()+" due to error in finalizeStart, not retrying");
+                        }
+                    }
+                    s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + (startAnswer == null ? " no start answer" : startAnswer.getDetails()));
+                    if (startAnswer != null && startAnswer.getContextParam("stopRetry") != null) {
+                        break;
+                    }
+
+                } catch (OperationTimedoutException e) {
+                    s_logger.debug("Unable to send the start command to host " + dest.getHost()+" failed to start VM: "+vm.getUuid());
+                    if (e.isActive()) {
+                        _haMgr.scheduleStop(vm, destHostId, WorkType.CheckStop);
+                    }
+                    canRetry = false;
+                    throw new AgentUnavailableException("Unable to start " + vm.getHostName(), destHostId, e);
+                } catch (final ResourceUnavailableException e) {
+                    s_logger.info("Unable to contact resource.", e);
+                    if (!avoids.add(e)) {
+                        if (e.getScope() == Volume.class || e.getScope() == Nic.class) {
+                            throw e;
+                        } else {
+                            s_logger.warn("unexpected ResourceUnavailableException : " + e.getScope().getName(), e);
+                            throw e;
+                        }
+                    }
+                } catch (final InsufficientCapacityException e) {
+                    s_logger.info("Insufficient capacity ", e);
+                    if (!avoids.add(e)) {
+                        if (e.getScope() == Volume.class || e.getScope() == Nic.class) {
+                            throw e;
+                        } else {
+                            s_logger.warn("unexpected InsufficientCapacityException : " + e.getScope().getName(), e);
+                        }
+                    }
+                } catch (final ExecutionException e) {
+                    s_logger.error("Failed to start instance " + vm, e);
+                    throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e);
+                } catch (final NoTransitionException e) {
+                    s_logger.error("Failed to start instance " + vm, e);
+                    throw new AgentUnavailableException("Unable to start instance due to " + e.getMessage(), destHostId, e);
+                } finally {
+                    if (startedVm == null && canRetry) {
+                        final Step prevStep = work.getStep();
+                        _workDao.updateStep(work, Step.Release);
+                        // If previous step was started/ing && we got a valid answer
+                        if ((prevStep == Step.Started || prevStep == Step.Starting) && startAnswer != null && startAnswer.getResult()) {  //TODO check the response of cleanup and record it in DB for retry
+                            cleanup(vmGuru, vmProfile, work, Event.OperationFailed, false);
+                        } else {
+                            //if step is not starting/started, send cleanup command with force=true
+                            cleanup(vmGuru, vmProfile, work, Event.OperationFailed, true);
+                        }
+                    }
+                }
+            }
+        } finally {
+            if (startedVm == null) {
+                if (canRetry) {
+                    try {
+                        changeState(vm, Event.OperationFailed, null, work, Step.Done);
+                    } catch (final NoTransitionException e) {
+                        throw new ConcurrentOperationException(e.getMessage());
+                    }
+                }
+            }
+
+            if (planToDeploy != null) {
+                planToDeploy.setAvoids(avoids);
+            }
+        }
+
+        if (startedVm == null) {
+            throw new CloudRuntimeException("Unable to start instance '" + vm.getHostName() + "' (" + vm.getUuid() + "), see management server log for details");
+        }
+    }
+
+    private void addExtraConfig(VirtualMachineTO vmTO) {
+        Map<String, String> details = vmTO.getDetails();
+        for (String key : details.keySet()) {
+            if (key.startsWith(ApiConstants.EXTRA_CONFIG)) {
+                vmTO.addExtraConfig(key, details.get(key));
+            }
+        }
+    }
+
+    // for managed storage on KVM, need to make sure the path field of the volume in question is populated with the IQN
+    private void handlePath(final DiskTO[] disks, final HypervisorType hypervisorType) {
+        if (hypervisorType != HypervisorType.KVM) {
+            return;
+        }
+
+        if (disks != null) {
+            for (final DiskTO disk : disks) {
+                final Map<String, String> details = disk.getDetails();
+                final boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+                if (isManaged && disk.getPath() == null) {
+                    final Long volumeId = disk.getData().getId();
+                    final VolumeVO volume = _volsDao.findById(volumeId);
+
+                    disk.setPath(volume.get_iScsiName());
+
+                    if (disk.getData() instanceof VolumeObjectTO) {
+                        final VolumeObjectTO volTo = (VolumeObjectTO)disk.getData();
+
+                        volTo.setPath(volume.get_iScsiName());
+                    }
+
+                    volume.setPath(volume.get_iScsiName());
+
+                    _volsDao.update(volumeId, volume);
+                }
+            }
+        }
+    }
+
+    // for managed storage on XenServer and VMware, need to update the DB with a path if the VDI/VMDK file was newly created
+    private void handlePath(final DiskTO[] disks, final Map<String, Map<String, String>> iqnToData) {
+        if (disks != null && iqnToData != null) {
+            for (final DiskTO disk : disks) {
+                final Map<String, String> details = disk.getDetails();
+                final boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+                if (isManaged) {
+                    final Long volumeId = disk.getData().getId();
+                    final VolumeVO volume = _volsDao.findById(volumeId);
+                    final String iScsiName = volume.get_iScsiName();
+
+                    boolean update = false;
+
+                    final Map<String, String> data = iqnToData.get(iScsiName);
+
+                    if (data != null) {
+                        final String path = data.get(StartAnswer.PATH);
+
+                        if (path != null) {
+                            volume.setPath(path);
+
+                            update = true;
+                        }
+
+                        final String imageFormat = data.get(StartAnswer.IMAGE_FORMAT);
+
+                        if (imageFormat != null) {
+                            volume.setFormat(ImageFormat.valueOf(imageFormat));
+
+                            update = true;
+                        }
+
+                        if (update) {
+                            _volsDao.update(volumeId, volume);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void syncDiskChainChange(final StartAnswer answer) {
+        final VirtualMachineTO vmSpec = answer.getVirtualMachine();
+
+        for (final DiskTO disk : vmSpec.getDisks()) {
+            if (disk.getType() != Volume.Type.ISO) {
+                final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
+                final VolumeVO volume = _volsDao.findById(vol.getId());
+
+                // Use getPath() from VolumeVO to get a fresh copy of what's in the DB.
+                // Before doing this, in a certain situation, getPath() from VolumeObjectTO
+                // returned null instead of an actual path (because it was out of date with the DB).
+                if(vol.getPath() != null) {
+                    volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo());
+                } else {
+                    volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo());
+                }
+            }
+        }
+    }
+
+    @Override
+    public void stop(final String vmUuid) throws ResourceUnavailableException {
+        try {
+            advanceStop(vmUuid, false);
+        } catch (final OperationTimedoutException e) {
+            throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", e.getAgentId(), e);
+        } catch (final ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e);
+        }
+
+    }
+
+    @Override
+    public void stopForced(String vmUuid) throws ResourceUnavailableException {
+        try {
+            advanceStop(vmUuid, true);
+        } catch (final OperationTimedoutException e) {
+            throw new AgentUnavailableException("Unable to stop vm because the operation to stop timed out", e.getAgentId(), e);
+        } catch (final ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Unable to stop vm because of a concurrent operation", e);
+        }
+    }
+
+    @Override
+    public boolean getExecuteInSequence(final HypervisorType hypervisorType) {
+        if (HypervisorType.KVM == hypervisorType || HypervisorType.XenServer == hypervisorType || HypervisorType.Hyperv == hypervisorType || HypervisorType.LXC == hypervisorType) {
+            return false;
+        } else if (HypervisorType.VMware == hypervisorType) {
+            final Boolean fullClone = HypervisorGuru.VmwareFullClone.value();
+            return fullClone;
+        } else {
+            return ExecuteInSequence.value();
+        }
+    }
+
+    private List<Map<String, String>> getVolumesToDisconnect(VirtualMachine vm) {
+        List<Map<String, String>> volumesToDisconnect = new ArrayList<>();
+
+        List<VolumeVO> volumes = _volsDao.findByInstance(vm.getId());
+
+        if (CollectionUtils.isEmpty(volumes)) {
+            return volumesToDisconnect;
+        }
+
+        for (VolumeVO volume : volumes) {
+            StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+
+            if (storagePool != null && storagePool.isManaged()) {
+                Map<String, String> info = new HashMap<>(3);
+
+                info.put(DiskTO.STORAGE_HOST, storagePool.getHostAddress());
+                info.put(DiskTO.STORAGE_PORT, String.valueOf(storagePool.getPort()));
+                info.put(DiskTO.IQN, volume.get_iScsiName());
+
+                volumesToDisconnect.add(info);
+            }
+        }
+
+        return volumesToDisconnect;
+    }
+
+    protected boolean sendStop(final VirtualMachineGuru guru, final VirtualMachineProfile profile, final boolean force, final boolean checkBeforeCleanup) {
+        final VirtualMachine vm = profile.getVirtualMachine();
+        StopCommand stpCmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), checkBeforeCleanup);
+        stpCmd.setControlIp(getControlNicIpForVM(vm));
+        stpCmd.setVolumesToDisconnect(getVolumesToDisconnect(vm));
+        final StopCommand stop = stpCmd;
+        try {
+            Answer answer = null;
+            if(vm.getHostId() != null) {
+                answer = _agentMgr.send(vm.getHostId(), stop);
+            }
+            if (answer != null && answer instanceof StopAnswer) {
+                final StopAnswer stopAns = (StopAnswer)answer;
+                if (vm.getType() == VirtualMachine.Type.User) {
+                    final String platform = stopAns.getPlatform();
+                    if (platform != null) {
+                        final UserVmVO userVm = _userVmDao.findById(vm.getId());
+                        _userVmDao.loadDetails(userVm);
+                        userVm.setDetail("platform", platform);
+                        _userVmDao.saveDetails(userVm);
+                    }
+                }
+
+                final GPUDeviceTO gpuDevice = stop.getGpuDevice();
+                if (gpuDevice != null) {
+                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
+                }
+                if (!answer.getResult()) {
+                    final String details = answer.getDetails();
+                    s_logger.debug("Unable to stop VM due to " + details);
+                    return false;
+                }
+
+                guru.finalizeStop(profile, answer);
+            } else {
+                s_logger.error("Invalid answer received in response to a StopCommand for " + vm.getInstanceName());
+                return false;
+            }
+
+        } catch (final AgentUnavailableException e) {
+            if (!force) {
+                return false;
+            }
+        } catch (final OperationTimedoutException e) {
+            if (!force) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected boolean cleanup(final VirtualMachineGuru guru, final VirtualMachineProfile profile, final ItWorkVO work, final Event event, final boolean cleanUpEvenIfUnableToStop) {
+        final VirtualMachine vm = profile.getVirtualMachine();
+        final State state = vm.getState();
+        s_logger.debug("Cleaning up resources for the vm " + vm + " in " + state + " state");
+        try {
+            if (state == State.Starting) {
+                if (work != null) {
+                    final Step step = work.getStep();
+                    if (step == Step.Starting && !cleanUpEvenIfUnableToStop) {
+                        s_logger.warn("Unable to cleanup vm " + vm + "; work state is incorrect: " + step);
+                        return false;
+                    }
+
+                    if (step == Step.Started || step == Step.Starting || step == Step.Release) {
+                        if (vm.getHostId() != null) {
+                            if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                                s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
+                                return false;
+                            }
+                        }
+                    }
+
+                    if (step != Step.Release && step != Step.Prepare && step != Step.Started && step != Step.Starting) {
+                        s_logger.debug("Cleanup is not needed for vm " + vm + "; work state is incorrect: " + step);
+                        return true;
+                    }
+                } else {
+                    if (vm.getHostId() != null) {
+                        if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                            s_logger.warn("Failed to stop vm " + vm + " in " + State.Starting + " state as a part of cleanup process");
+                            return false;
+                        }
+                    }
+                }
+
+            } else if (state == State.Stopping) {
+                if (vm.getHostId() != null) {
+                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Stopping + " state as a part of cleanup process");
+                        return false;
+                    }
+                }
+            } else if (state == State.Migrating) {
+                if (vm.getHostId() != null) {
+                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process");
+                        return false;
+                    }
+                }
+                if (vm.getLastHostId() != null) {
+                    if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                        s_logger.warn("Failed to stop vm " + vm + " in " + State.Migrating + " state as a part of cleanup process");
+                        return false;
+                    }
+                }
+            } else if (state == State.Running) {
+                if (!sendStop(guru, profile, cleanUpEvenIfUnableToStop, false)) {
+                    s_logger.warn("Failed to stop vm " + vm + " in " + State.Running + " state as a part of cleanup process");
+                    return false;
+                }
+            }
+        } finally {
+            try {
+                _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
+                s_logger.debug("Successfully released network resources for the vm " + vm);
+            } catch (final Exception e) {
+                s_logger.warn("Unable to release some network resources.", e);
+            }
+
+            volumeMgr.release(profile);
+            s_logger.debug(String.format("Successfully cleaned up resources for the VM %s in %s state", vm, state));
+        }
+
+        return true;
+    }
+
+    @Override
+    public void advanceStop(final String vmUuid, final boolean cleanUpEvenIfUnableToStop)
+            throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateStop(vmUuid, cleanUpEvenIfUnableToStop);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+
+        } else {
+            final Outcome<VirtualMachine> outcome = stopVmThroughJobQueue(vmUuid, cleanUpEvenIfUnableToStop);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof AgentUnavailableException) {
+                    throw (AgentUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof OperationTimedoutException) {
+                    throw (OperationTimedoutException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+            }
+        }
+    }
+
+    private void orchestrateStop(final String vmUuid, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        advanceStop(vm, cleanUpEvenIfUnableToStop);
+    }
+
+    private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnableToStop) throws AgentUnavailableException, OperationTimedoutException,
+    ConcurrentOperationException {
+        final State state = vm.getState();
+        if (state == State.Stopped) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is already stopped: " + vm);
+            }
+            return;
+        }
+
+        if (state == State.Destroyed || state == State.Expunging || state == State.Error) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Stopped called on " + vm + " but the state is " + state);
+            }
+            return;
+        }
+        // grab outstanding work item if any
+        final ItWorkVO work = _workDao.findByOutstandingWork(vm.getId(), vm.getState());
+        if (work != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found an outstanding work item for this vm " + vm + " with state:" + vm.getState() + ", work id:" + work.getId());
+            }
+        }
+        final Long hostId = vm.getHostId();
+        if (hostId == null) {
+            if (!cleanUpEvenIfUnableToStop) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("HostId is null but this is not a forced stop, cannot stop vm " + vm + " with state:" + vm.getState());
+                }
+                throw new CloudRuntimeException("Unable to stop " + vm);
+            }
+            try {
+                stateTransitTo(vm, Event.AgentReportStopped, null, null);
+            } catch (final NoTransitionException e) {
+                s_logger.warn(e.getMessage());
+            }
+            // mark outstanding work item if any as done
+            if (work != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Updating work item to Done, id:" + work.getId());
+                }
+                work.setStep(Step.Done);
+                _workDao.update(work.getId(), work);
+            }
+            return;
+        } else {
+            HostVO host = _hostDao.findById(hostId);
+            if (!cleanUpEvenIfUnableToStop && vm.getState() == State.Running && host.getResourceState() == ResourceState.PrepareForMaintenance) {
+                s_logger.debug("Host is in PrepareForMaintenance state - Stop VM operation on the VM id: " + vm.getId() + " is not allowed");
+                throw new CloudRuntimeException("Stop VM operation on the VM id: " + vm.getId() + " is not allowed as host is preparing for maintenance mode");
+            }
+        }
+
+        final VirtualMachineGuru vmGuru = getVmGuru(vm);
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+
+        try {
+            if (!stateTransitTo(vm, Event.StopRequested, vm.getHostId())) {
+                throw new ConcurrentOperationException("VM is being operated on.");
+            }
+        } catch (final NoTransitionException e1) {
+            if (!cleanUpEvenIfUnableToStop) {
+                throw new CloudRuntimeException("We cannot stop " + vm + " when it is in state " + vm.getState());
+            }
+            final boolean doCleanup = true;
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to transition the state but we're moving on because it's forced stop");
+            }
+
+            if (doCleanup) {
+                if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {
+                    try {
+                        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);
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Failed to cleanup VM: " + vm);
+                    }
+                    throw new CloudRuntimeException("Failed to cleanup " + vm + " , current state " + vm.getState());
+                }
+            }
+        }
+
+        if (vm.getState() != State.Stopping) {
+            throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState());
+        }
+
+        vmGuru.prepareStop(profile);
+
+        final StopCommand stop = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false, cleanUpEvenIfUnableToStop);
+        stop.setControlIp(getControlNicIpForVM(vm));
+
+        boolean stopped = false;
+        Answer answer = null;
+        try {
+            answer = _agentMgr.send(vm.getHostId(), stop);
+            if (answer != null) {
+                if (answer instanceof StopAnswer) {
+                    final StopAnswer stopAns = (StopAnswer)answer;
+                    if (vm.getType() == VirtualMachine.Type.User) {
+                        final String platform = stopAns.getPlatform();
+                        if (platform != null) {
+                            final UserVmVO userVm = _userVmDao.findById(vm.getId());
+                            _userVmDao.loadDetails(userVm);
+                            userVm.setDetail("platform", platform);
+                            _userVmDao.saveDetails(userVm);
+                        }
+                    }
+                }
+                stopped = answer.getResult();
+                if (!stopped) {
+                    throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails());
+                }
+                vmGuru.finalizeStop(profile, answer);
+                final GPUDeviceTO gpuDevice = stop.getGpuDevice();
+                if (gpuDevice != null) {
+                    _resourceMgr.updateGPUDetails(vm.getHostId(), gpuDevice.getGroupDetails());
+                }
+            } else {
+                throw new CloudRuntimeException("Invalid answer received in response to a StopCommand on " + vm.instanceName);
+            }
+
+        } catch (final AgentUnavailableException e) {
+            s_logger.warn("Unable to stop vm, agent unavailable: " + e.toString());
+        } catch (final OperationTimedoutException e) {
+            s_logger.warn("Unable to stop vm, operation timed out: " + e.toString());
+        } finally {
+            if (!stopped) {
+                if (!cleanUpEvenIfUnableToStop) {
+                    s_logger.warn("Unable to stop vm " + vm);
+                    try {
+                        stateTransitTo(vm, Event.OperationFailed, vm.getHostId());
+                    } catch (final NoTransitionException e) {
+                        s_logger.warn("Unable to transition the state " + vm);
+                    }
+                    throw new CloudRuntimeException("Unable to stop " + vm);
+                } else {
+                    s_logger.warn("Unable to actually stop " + vm + " but continue with release because it's a force stop");
+                    vmGuru.finalizeStop(profile, answer);
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(vm + " is stopped on the host.  Proceeding to release resource held.");
+        }
+
+        try {
+            _networkMgr.release(profile, cleanUpEvenIfUnableToStop);
+            s_logger.debug("Successfully released network resources for the vm " + vm);
+        } catch (final Exception e) {
+            s_logger.warn("Unable to release some network resources.", e);
+        }
+
+        try {
+            if (vm.getHypervisorType() != HypervisorType.BareMetal) {
+                volumeMgr.release(profile);
+                s_logger.debug("Successfully released storage resources for the vm " + vm);
+            }
+        } catch (final Exception e) {
+            s_logger.warn("Unable to release storage resources.", e);
+        }
+
+        try {
+            if (work != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Updating the outstanding work item to Done, id:" + work.getId());
+                }
+                work.setStep(Step.Done);
+                _workDao.update(work.getId(), work);
+            }
+
+            if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
+                throw new CloudRuntimeException("unable to stop " + vm);
+            }
+        } catch (final NoTransitionException e) {
+            s_logger.warn(e.getMessage());
+            throw new CloudRuntimeException("Unable to stop " + vm);
+        }
+    }
+
+    private void setStateMachine() {
+        _stateMachine = VirtualMachine.State.getStateMachine();
+    }
+
+    protected boolean stateTransitTo(final VMInstanceVO vm, final VirtualMachine.Event e, final Long hostId, final String reservationId) throws NoTransitionException {
+        // if there are active vm snapshots task, state change is not allowed
+
+        vm.setReservationId(reservationId);
+        return _stateMachine.transitTo(vm, e, new Pair<Long, Long>(vm.getHostId(), hostId), _vmDao);
+    }
+
+    @Override
+    public boolean stateTransitTo(final VirtualMachine vm1, final VirtualMachine.Event e, final Long hostId) throws NoTransitionException {
+        final VMInstanceVO vm = (VMInstanceVO)vm1;
+
+        final State oldState = vm.getState();
+        if (oldState == State.Starting) {
+            if (e == Event.OperationSucceeded) {
+                vm.setLastHostId(hostId);
+            }
+        } else if (oldState == State.Stopping) {
+            if (e == Event.OperationSucceeded) {
+                vm.setLastHostId(vm.getHostId());
+            }
+        }
+        return _stateMachine.transitTo(vm, e, new Pair<Long, Long>(vm.getHostId(), hostId), _vmDao);
+    }
+
+    @Override
+    public void destroy(final String vmUuid, final boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
+            }
+            return;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Destroying vm " + vm + ", expunge flag " + (expunge ? "on" : "off"));
+        }
+
+        advanceStop(vmUuid, VmDestroyForcestop.value());
+
+        deleteVMSnapshots(vm, expunge);
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<CloudRuntimeException>() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) throws CloudRuntimeException {
+                VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+                try {
+                    if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) {
+                        s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
+                        throw new CloudRuntimeException("Unable to destroy " + vm);
+                    } else {
+                        if (expunge) {
+                            if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) {
+                                s_logger.debug("Unable to expunge the vm because it is not in the correct state: " + vm);
+                                throw new CloudRuntimeException("Unable to expunge " + vm);
+                            }
+                        }
+                    }
+                } catch (final NoTransitionException e) {
+                    s_logger.debug(e.getMessage());
+                    throw new CloudRuntimeException("Unable to destroy " + vm, e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Delete vm snapshots depending on vm's hypervisor type. For Vmware, vm snapshots removal is delegated to vm cleanup thread
+     * to reduce tasks sent to hypervisor (one tasks to delete vm snapshots and vm itself
+     * instead of one task for each vm snapshot plus another for the vm)
+     * @param vm vm
+     * @param expunge indicates if vm should be expunged
+     */
+    private void deleteVMSnapshots(VMInstanceVO vm, boolean expunge) {
+        if (! vm.getHypervisorType().equals(HypervisorType.VMware)) {
+            if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(), null)) {
+                s_logger.debug("Unable to delete all snapshots for " + vm);
+                throw new CloudRuntimeException("Unable to delete vm snapshots for " + vm);
+            }
+        }
+        else {
+            if (expunge) {
+                _vmSnapshotMgr.deleteVMSnapshotsFromDB(vm.getId());
+            }
+        }
+    }
+
+    protected boolean checkVmOnHost(final VirtualMachine vm, final long hostId) throws AgentUnavailableException, OperationTimedoutException {
+        final Answer answer = _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName()));
+        if (answer == null || !answer.getResult()) {
+            return false;
+        }
+        if (answer instanceof CheckVirtualMachineAnswer) {
+            final CheckVirtualMachineAnswer vmAnswer = (CheckVirtualMachineAnswer)answer;
+            if (vmAnswer.getState() == PowerState.PowerOff) {
+                return false;
+            }
+        }
+
+        UserVmVO userVm = _userVmDao.findById(vm.getId());
+        if (userVm != null) {
+            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vm.getId());
+            RestoreVMSnapshotCommand command = _vmSnapshotMgr.createRestoreCommand(userVm, vmSnapshots);
+            if (command != null) {
+                RestoreVMSnapshotAnswer restoreVMSnapshotAnswer = (RestoreVMSnapshotAnswer) _agentMgr.send(hostId, command);
+                if (restoreVMSnapshotAnswer == null || !restoreVMSnapshotAnswer.getResult()) {
+                    s_logger.warn("Unable to restore the vm snapshot from image file after live migration of vm with vmsnapshots: " + restoreVMSnapshotAnswer.getDetails());
+                }
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public void storageMigration(final String vmUuid, final StoragePool destPool) {
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateStorageMigration(vmUuid, destPool);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = migrateVmStorageThroughJobQueue(vmUuid, destPool);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+            }
+        }
+    }
+
+    private void orchestrateStorageMigration(final String vmUuid, final StoragePool destPool) {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        preStorageMigrationStateCheck(destPool, vm);
+
+        try {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug(String.format("Offline migration of %s vm %s with volumes",
+                                vm.getHypervisorType().toString(),
+                                vm.getInstanceName()));
+            }
+
+            migrateThroughHypervisorOrStorage(destPool, vm);
+
+        } catch (ConcurrentOperationException
+                | InsufficientCapacityException // possibly InsufficientVirtualNetworkCapacityException or InsufficientAddressCapacityException
+                | StorageUnavailableException e) {
+            String msg = String.format("Failed to migrate VM: %s", vmUuid);
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        } finally {
+            try {
+                stateTransitTo(vm, Event.AgentReportStopped, null);
+            } catch (final NoTransitionException e) {
+                String anotherMEssage = String.format("failed to change vm state of VM: %s", vmUuid);
+                s_logger.debug(anotherMEssage);
+                throw new CloudRuntimeException(anotherMEssage, e);
+            }
+        }
+    }
+
+    private Answer[] attemptHypervisorMigration(StoragePool destPool, VMInstanceVO vm) {
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
+        // OfflineVmwareMigration: in case of vmware call vcenter to do it for us.
+        // OfflineVmwareMigration: should we check the proximity of source and destination
+        // OfflineVmwareMigration: if we are in the same cluster/datacentre/pool or whatever?
+        // OfflineVmwareMigration: we are checking on success to optionally delete an old vm if we are not
+        List<Command> commandsToSend = hvGuru.finalizeMigrate(vm, destPool);
+
+        Long hostId = vm.getHostId();
+        // OfflineVmwareMigration: probably this is null when vm is stopped
+        if(hostId == null) {
+            hostId = vm.getLastHostId();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(String.format("host id is null, using last host id %d", hostId) );
+            }
+        }
+
+        if(CollectionUtils.isNotEmpty(commandsToSend)) {
+            Commands commandsContainer = new Commands(Command.OnError.Stop);
+            commandsContainer.addCommands(commandsToSend);
+            try {
+                // OfflineVmwareMigration: change to the call back variety?
+                // OfflineVmwareMigration: getting a Long seq to be filled with _agentMgr.send(hostId, commandsContainer, this)
+                return  _agentMgr.send(hostId, commandsContainer);
+            } catch (AgentUnavailableException | OperationTimedoutException e) {
+                throw new CloudRuntimeException(String.format("Failed to migrate VM: %s", vm.getUuid()),e);
+            }
+        }
+        return null;
+    }
+
+    private void afterHypervisorMigrationCleanup(StoragePool destPool, VMInstanceVO vm, HostVO srcHost, Long srcClusterId, Answer[] hypervisorMigrationResults) throws InsufficientCapacityException {
+        boolean isDebugEnabled = s_logger.isDebugEnabled();
+        if(isDebugEnabled) {
+            String msg = String.format("cleaning up after hypervisor pool migration volumes for VM %s(%s) to pool %s(%s)", vm.getInstanceName(), vm.getUuid(), destPool.getName(), destPool.getUuid());
+            s_logger.debug(msg);
+        }
+        setDestinationPoolAndReallocateNetwork(destPool, vm);
+        // OfflineVmwareMigration: don't set this to null or have another way to address the command; twice migrating will lead to an NPE
+        Long destPodId = destPool.getPodId();
+        Long vmPodId = vm.getPodIdToDeployIn();
+        if (destPodId == null || ! destPodId.equals(vmPodId)) {
+            if(isDebugEnabled) {
+                String msg = String.format("resetting lasHost for VM %s(%s) as pod (%s) is no good.", vm.getInstanceName(), vm.getUuid(), destPodId);
+                s_logger.debug(msg);
+            }
+
+            vm.setLastHostId(null);
+            vm.setPodIdToDeployIn(destPodId);
+            // OfflineVmwareMigration: a consecutive migration will fail probably (no host not pod)
+        }// else keep last host set for this vm
+        markVolumesInPool(vm,destPool, hypervisorMigrationResults);
+        // OfflineVmwareMigration: deal with answers, if (hypervisorMigrationResults.length > 0)
+        // OfflineVmwareMigration: iterate over the volumes for data updates
+    }
+
+    private void markVolumesInPool(VMInstanceVO vm, StoragePool destPool, Answer[] hypervisorMigrationResults) {
+        MigrateVmToPoolAnswer relevantAnswer = null;
+        for (Answer answer : hypervisorMigrationResults) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace(String.format("received an %s: %s", answer.getClass().getSimpleName(), answer));
+            }
+            if (answer instanceof MigrateVmToPoolAnswer) {
+                relevantAnswer = (MigrateVmToPoolAnswer) answer;
+            }
+        }
+        if (relevantAnswer == null) {
+            throw new CloudRuntimeException("no relevant migration results found");
+        }
+        List<VolumeVO> volumes = _volsDao.findUsableVolumesForInstance(vm.getId());
+        if(s_logger.isDebugEnabled()) {
+            String msg = String.format("found %d volumes for VM %s(uuid:%s, id:%d)", volumes.size(), vm.getInstanceName(), vm.getUuid(), vm.getId());
+            s_logger.debug(msg);
+        }
+        for (VolumeObjectTO result : relevantAnswer.getVolumeTos() ) {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug(String.format("updating volume (%d) with path '%s' on pool '%d'", result.getId(), result.getPath(), destPool.getId()));
+            }
+            VolumeVO volume = _volsDao.findById(result.getId());
+            volume.setPath(result.getPath());
+            volume.setPoolId(destPool.getId());
+            _volsDao.update(volume.getId(), volume);
+        }
+    }
+
+    private void migrateThroughHypervisorOrStorage(StoragePool destPool, VMInstanceVO vm) throws StorageUnavailableException, InsufficientCapacityException {
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+        final Long srchostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
+        final HostVO srcHost = _hostDao.findById(srchostId);
+        final Long srcClusterId = srcHost.getClusterId();
+        Answer[] hypervisorMigrationResults = attemptHypervisorMigration(destPool, vm);
+        boolean migrationResult = false;
+        if (hypervisorMigrationResults == null) {
+            // OfflineVmwareMigration: if the HypervisorGuru can't do it, let the volume manager take care of it.
+            migrationResult = volumeMgr.storageMigration(profile, destPool);
+            if (migrationResult) {
+                afterStorageMigrationCleanup(destPool, vm, srcHost, srcClusterId);
+            } else {
+                s_logger.debug("Storage migration failed");
+            }
+        } else {
+            afterHypervisorMigrationCleanup(destPool, vm, srcHost, srcClusterId, hypervisorMigrationResults);
+        }
+    }
+
+    private void preStorageMigrationStateCheck(StoragePool destPool, VMInstanceVO vm) {
+        if (destPool == null) {
+            throw new CloudRuntimeException("Unable to migrate vm: missing destination storage pool");
+        }
+
+        checkDestinationForTags(destPool, vm);
+        try {
+            stateTransitTo(vm, Event.StorageMigrationRequested, null);
+        } catch (final NoTransitionException e) {
+            String msg = String.format("Unable to migrate vm: %s", vm.getUuid());
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        }
+    }
+
+    private void checkDestinationForTags(StoragePool destPool, VMInstanceVO vm) {
+        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
+        // OfflineVmwareMigration: iterate over volumes
+        // OfflineVmwareMigration: get disk offering
+        List<String> storageTags = storageMgr.getStoragePoolTagList(destPool.getId());
+        for(Volume vol : vols) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
+            List<String> volumeTags = StringUtils.csvTagsToList(diskOffering.getTags());
+            if(! matches(volumeTags, storageTags)) {
+                String msg = String.format("destination pool '%s' with tags '%s', does not support the volume diskoffering for volume '%s' (tags: '%s') ",
+                        destPool.getName(),
+                        StringUtils.listToCsvTags(storageTags),
+                        vol.getName(),
+                        StringUtils.listToCsvTags(volumeTags)
+                );
+                throw new CloudRuntimeException(msg);
+            }
+        }
+    }
+
+    static boolean matches(List<String> volumeTags, List<String> storagePoolTags) {
+        // OfflineVmwareMigration: commons collections 4 allows for Collections.containsAll(volumeTags,storagePoolTags);
+        boolean result = true;
+        if (volumeTags != null) {
+            for (String tag : volumeTags) {
+                // there is a volume tags so
+                if (storagePoolTags == null || !storagePoolTags.contains(tag)) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+
+    private void afterStorageMigrationCleanup(StoragePool destPool, VMInstanceVO vm, HostVO srcHost, Long srcClusterId) throws InsufficientCapacityException {
+        setDestinationPoolAndReallocateNetwork(destPool, vm);
+
+        //when start the vm next time, don;'t look at last_host_id, only choose the host based on volume/storage pool
+        vm.setLastHostId(null);
+        vm.setPodIdToDeployIn(destPool.getPodId());
+
+        // If VM was cold migrated between clusters belonging to two different VMware DCs,
+        // unregister the VM from the source host and cleanup the associated VM files.
+        if (vm.getHypervisorType().equals(HypervisorType.VMware)) {
+            afterStorageMigrationVmwareVMcleanup(destPool, vm, srcHost, srcClusterId);
+        }
+    }
+
+    private void setDestinationPoolAndReallocateNetwork(StoragePool destPool, VMInstanceVO vm) throws InsufficientCapacityException {
+        //if the vm is migrated to different pod in basic mode, need to reallocate ip
+
+        if (destPool.getPodId() != null && !destPool.getPodId().equals(vm.getPodIdToDeployIn())) {
+            if (s_logger.isDebugEnabled()) {
+                String msg = String.format("as the pod for vm %s has changed we are reallocating its network", vm.getInstanceName());
+                s_logger.debug(msg);
+            }
+            final DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), destPool.getPodId(), null, null, null, null);
+            final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, null, null, null, null);
+            _networkMgr.reallocate(vmProfile, plan);
+        }
+    }
+
+    private void afterStorageMigrationVmwareVMcleanup(StoragePool destPool, VMInstanceVO vm, HostVO srcHost, Long srcClusterId) {
+        // OfflineVmwareMigration: this should only happen on storage migration, else the guru would already have issued the command
+        final Long destClusterId = destPool.getClusterId();
+        if (srcClusterId != null && destClusterId != null && ! srcClusterId.equals(destClusterId)) {
+            final String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
+            final String destDcName = _clusterDetailsDao.getVmwareDcName(destClusterId);
+            if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
+                removeStaleVmFromSource(vm, srcHost);
+            }
+        }
+    }
+
+    // OfflineVmwareMigration: on port forward refator this to be done in two
+    // OfflineVmwareMigration: command creation in the guru.migrat method
+    // OfflineVmwareMigration: sending up in the attemptHypevisorMigration with execute in sequence (responsibility of the guru)
+    private void removeStaleVmFromSource(VMInstanceVO vm, HostVO srcHost) {
+        s_logger.debug("Since VM's storage was successfully migrated across VMware Datacenters, unregistering VM: " + vm.getInstanceName() +
+                " from source host: " + srcHost.getId());
+        final UnregisterVMCommand uvc = new UnregisterVMCommand(vm.getInstanceName());
+        uvc.setCleanupVmFiles(true);
+        try {
+            _agentMgr.send(srcHost.getId(), uvc);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Failed to unregister VM: " + vm.getInstanceName() + " from source host: " + srcHost.getId() +
+                    " after successfully migrating VM's storage across VMware Datacenters");
+        }
+    }
+
+    @Override
+    public void migrate(final String vmUuid, final long srcHostId, final DeployDestination dest)
+            throws ResourceUnavailableException, ConcurrentOperationException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateMigrate(vmUuid, srcHostId, dest);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+
+            }
+        }
+    }
+
+    private void orchestrateMigrate(final String vmUuid, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        if (vm == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find the vm " + vmUuid);
+            }
+            throw new CloudRuntimeException("Unable to find a virtual machine with id " + vmUuid);
+        }
+        migrate(vm, srcHostId, dest);
+    }
+
+    protected void migrate(final VMInstanceVO vm, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException {
+        s_logger.info("Migrating " + vm + " to " + dest);
+
+        final long dstHostId = dest.getHost().getId();
+        final Host fromHost = _hostDao.findById(srcHostId);
+        if (fromHost == null) {
+            s_logger.info("Unable to find the host to migrate from: " + srcHostId);
+            throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
+        }
+
+        if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
+            final List<VolumeVO> volumes = _volsDao.findCreatedByInstance(vm.getId());
+            for (final VolumeVO volume : volumes) {
+                if (!_storagePoolDao.findById(volume.getPoolId()).getScope().equals(ScopeType.ZONE)) {
+                    s_logger.info("Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: "
+                            + dest.getHost().getId());
+                    throw new CloudRuntimeException(
+                            "Source and destination host are not in same cluster and all volumes are not on zone wide primary store, unable to migrate to host: "
+                                    + dest.getHost().getId());
+                }
+            }
+        }
+
+        final VirtualMachineGuru vmGuru = getVmGuru(vm);
+
+        if (vm.getState() != State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
+            }
+            throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
+        }
+
+        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
+        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
+        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
+        }
+
+        final VirtualMachineProfile vmSrc = new VirtualMachineProfileImpl(vm);
+        for (final NicProfile nic : _networkMgr.getNicProfiles(vm)) {
+            vmSrc.addNic(nic);
+        }
+
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null);
+        _networkMgr.prepareNicForMigration(profile, dest);
+        volumeMgr.prepareForMigration(profile, dest);
+        profile.setConfigDriveLabel(VmConfigDriveLabel.value());
+
+        final VirtualMachineTO to = toVmTO(profile);
+        final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
+
+        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
+        work.setStep(Step.Prepare);
+        work.setResourceType(ItWorkVO.ResourceType.Host);
+        work.setResourceId(dstHostId);
+        work = _workDao.persist(work);
+
+        Answer pfma = null;
+        try {
+            pfma = _agentMgr.send(dstHostId, pfmc);
+            if (pfma == null || !pfma.getResult()) {
+                final String details = pfma != null ? pfma.getDetails() : "null answer returned";
+                final String msg = "Unable to prepare for migration due to " + details;
+                pfma = null;
+                throw new AgentUnavailableException(msg, dstHostId);
+            }
+        } catch (final OperationTimedoutException e1) {
+            throw new AgentUnavailableException("Operation timed out", dstHostId);
+        } finally {
+            if (pfma == null) {
+                _networkMgr.rollbackNicForMigration(vmSrc, profile);
+                work.setStep(Step.Done);
+                _workDao.update(work.getId(), work);
+            }
+        }
+
+        vm.setLastHostId(srcHostId);
+        try {
+            if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
+                _networkMgr.rollbackNicForMigration(vmSrc, profile);
+                s_logger.info("Migration cancelled because state has changed: " + vm);
+                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
+            }
+        } catch (final NoTransitionException e1) {
+            _networkMgr.rollbackNicForMigration(vmSrc, profile);
+            s_logger.info("Migration cancelled because " + e1.getMessage());
+            throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
+        }
+
+        boolean migrated = false;
+        try {
+            final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+            final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
+
+            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
+            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
+
+            mc.setAutoConvergence(kvmAutoConvergence);
+
+            mc.setHostGuid(dest.getHost().getGuid());
+
+            try {
+                final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
+                if (ma == null || !ma.getResult()) {
+                    final String details = ma != null ? ma.getDetails() : "null answer returned";
+                    throw new CloudRuntimeException(details);
+                }
+            } catch (final OperationTimedoutException e) {
+                if (e.isActive()) {
+                    s_logger.warn("Active migration command so scheduling a restart for " + vm);
+                    _haMgr.scheduleRestart(vm, true);
+                }
+                throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
+            }
+
+            try {
+                if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
+                    throw new ConcurrentOperationException("Unable to change the state for " + vm);
+                }
+            } catch (final NoTransitionException e1) {
+                throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
+            }
+
+            try {
+                if (!checkVmOnHost(vm, dstHostId)) {
+                    s_logger.error("Unable to complete migration for " + vm);
+                    try {
+                        _agentMgr.send(srcHostId, new Commands(cleanup(vm)), null);
+                    } catch (final AgentUnavailableException e) {
+                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
+                    }
+                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
+                    throw new CloudRuntimeException("Unable to complete migration for " + vm);
+                }
+            } catch (final OperationTimedoutException e) {
+                s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
+            }
+
+            migrated = true;
+        } finally {
+            if (!migrated) {
+                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
+                _networkMgr.rollbackNicForMigration(vmSrc, profile);
+
+                _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(),
+                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " +
+                                dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
+                try {
+                    _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null);
+                } catch (final AgentUnavailableException ae) {
+                    s_logger.info("Looks like the destination Host is unavailable for cleanup");
+                }
+
+                try {
+                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
+                } catch (final NoTransitionException e) {
+                    s_logger.warn(e.getMessage());
+                }
+            } else {
+                _networkMgr.commitNicForMigration(vmSrc, profile);
+            }
+
+            work.setStep(Step.Done);
+            _workDao.update(work.getId(), work);
+        }
+    }
+
+    /**
+     * We create the mapping of volumes and storage pool to migrate the VMs according to the information sent by the user.
+     * If the user did not enter a complete mapping, the volumes that were left behind will be auto mapped using {@link #createStoragePoolMappingsForVolumes(VirtualMachineProfile, Host, Map, List)}
+     */
+    protected Map<Volume, StoragePool> createMappingVolumeAndStoragePool(VirtualMachineProfile profile, Host targetHost, Map<Long, Long> userDefinedMapOfVolumesAndStoragePools) {
+        Map<Volume, StoragePool> volumeToPoolObjectMap = buildMapUsingUserInformation(profile, targetHost, userDefinedMapOfVolumesAndStoragePools);
+
+        List<Volume> volumesNotMapped = findVolumesThatWereNotMappedByTheUser(profile, volumeToPoolObjectMap);
+        createStoragePoolMappingsForVolumes(profile, targetHost, volumeToPoolObjectMap, volumesNotMapped);
+        return volumeToPoolObjectMap;
+    }
+
+    /**
+     *  Given the map of volume to target storage pool entered by the user, we check for other volumes that the VM might have and were not configured.
+     *  This map can be then used by CloudStack to find new target storage pools according to the target host.
+     */
+    protected List<Volume> findVolumesThatWereNotMappedByTheUser(VirtualMachineProfile profile, Map<Volume, StoragePool> volumeToStoragePoolObjectMap) {
+        List<VolumeVO> allVolumes = _volsDao.findUsableVolumesForInstance(profile.getId());
+        List<Volume> volumesNotMapped = new ArrayList<>();
+        for (Volume volume : allVolumes) {
+            if (!volumeToStoragePoolObjectMap.containsKey(volume)) {
+                volumesNotMapped.add(volume);
+            }
+        }
+        return volumesNotMapped;
+    }
+
+    /**
+     *  Builds the map of storage pools and volumes with the information entered by the user. Before creating the an entry we validate if the migration is feasible checking if the migration is allowed and if the target host can access the defined target storage pool.
+     */
+    protected Map<Volume, StoragePool> buildMapUsingUserInformation(VirtualMachineProfile profile, Host targetHost, Map<Long, Long> userDefinedVolumeToStoragePoolMap) {
+        Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+        if (MapUtils.isEmpty(userDefinedVolumeToStoragePoolMap)) {
+            return volumeToPoolObjectMap;
+        }
+        for(Long volumeId: userDefinedVolumeToStoragePoolMap.keySet()) {
+            VolumeVO volume = _volsDao.findById(volumeId);
+
+            Long poolId = userDefinedVolumeToStoragePoolMap.get(volumeId);
+            StoragePoolVO targetPool = _storagePoolDao.findById(poolId);
+            StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId());
+
+            executeManagedStorageChecksWhenTargetStoragePoolProvided(currentPool, volume, targetPool);
+            if (_poolHostDao.findByPoolHost(targetPool.getId(), targetHost.getId()) == null) {
+                throw new CloudRuntimeException(
+                        String.format("Cannot migrate the volume [%s] to the storage pool [%s] while migrating VM [%s] to target host [%s]. The host does not have access to the storage pool entered.",
+                                volume.getUuid(), targetPool.getUuid(), profile.getUuid(), targetHost.getUuid()));
+            }
+            if (currentPool.getId() == targetPool.getId()) {
+                s_logger.info(String.format("The volume [%s] is already allocated in storage pool [%s].", volume.getUuid(), targetPool.getUuid()));
+            }
+            volumeToPoolObjectMap.put(volume, targetPool);
+        }
+        return volumeToPoolObjectMap;
+    }
+
+    /**
+     *  Executes the managed storage checks for the mapping<volume, storage pool> entered by the user. The checks execute by this method are the following.
+     *  <ul>
+     *      <li> If the current storage pool of the volume is not a managed storage, we do not need to validate anything here.
+     *      <li> If the current storage pool is a managed storage and the target storage pool ID is different from the current one, we throw an exception.
+     *  </ul>
+     */
+    protected void executeManagedStorageChecksWhenTargetStoragePoolProvided(StoragePoolVO currentPool, VolumeVO volume, StoragePoolVO targetPool) {
+        if (!currentPool.isManaged()) {
+            return;
+        }
+        if (currentPool.getId() == targetPool.getId()) {
+            return;
+        }
+        throw new CloudRuntimeException(String.format("Currently, a volume on managed storage can only be 'migrated' to itself " + "[volumeId=%s, currentStoragePoolId=%s, targetStoragePoolId=%s].",
+                volume.getUuid(), currentPool.getUuid(), targetPool.getUuid()));
+    }
+
+    /**
+     * For each one of the volumes we will map it to a storage pool that is available via the target host.
+     * An exception is thrown if we cannot find a storage pool that is accessible in the target host to migrate the volume to.
+     */
+    protected void createStoragePoolMappingsForVolumes(VirtualMachineProfile profile, Host targetHost, Map<Volume, StoragePool> volumeToPoolObjectMap, List<Volume> allVolumes) {
+        for (Volume volume : allVolumes) {
+            StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId());
+
+            executeManagedStorageChecksWhenTargetStoragePoolNotProvided(targetHost, currentPool, volume);
+            if (ScopeType.HOST.equals(currentPool.getScope()) || isStorageCrossClusterMigration(targetHost, currentPool)) {
+                createVolumeToStoragePoolMappingIfPossible(profile, targetHost, volumeToPoolObjectMap, volume, currentPool);
+            } else {
+                volumeToPoolObjectMap.put(volume, currentPool);
+            }
+        }
+    }
+
+    /**
+     *  Executes the managed storage checks for the volumes that the user has not entered a mapping of <volume, storage pool>. The following checks are performed.
+     *   <ul>
+     *      <li> If the current storage pool is not a managed storage, we do not need to proceed with this method;
+     *      <li> We check if the target host has access to the current managed storage pool. If it does not have an exception will be thrown.
+     *   </ul>
+     */
+    protected void executeManagedStorageChecksWhenTargetStoragePoolNotProvided(Host targetHost, StoragePoolVO currentPool, Volume volume) {
+        if (!currentPool.isManaged()) {
+            return;
+        }
+        if (_poolHostDao.findByPoolHost(currentPool.getId(), targetHost.getId()) == null) {
+            throw new CloudRuntimeException(String.format("The target host does not have access to the volume's managed storage pool. [volumeId=%s, storageId=%s, targetHostId=%s].", volume.getUuid(),
+                    currentPool.getUuid(), targetHost.getUuid()));
+        }
+    }
+
+    /**
+     *  Return true if the VM migration is a cross cluster migration. To execute that, we check if the volume current storage pool cluster is different from the target host cluster.
+     */
+    protected boolean isStorageCrossClusterMigration(Host targetHost, StoragePoolVO currentPool) {
+        return ScopeType.CLUSTER.equals(currentPool.getScope()) && currentPool.getClusterId() != targetHost.getClusterId();
+    }
+
+    /**
+     * We will add a mapping of volume to storage pool if needed. The conditions to add a mapping are the following:
+     * <ul>
+     *  <li> The candidate storage pool where the volume is to be allocated can be accessed by the target host
+     *  <li> If no storage pool is found to allocate the volume we throw an exception.
+     * </ul>
+     *
+     * Side note: this method should only be called if the volume is on local storage or if we are executing a cross cluster migration.
+     */
+    protected void createVolumeToStoragePoolMappingIfPossible(VirtualMachineProfile profile, Host targetHost, Map<Volume, StoragePool> volumeToPoolObjectMap, Volume volume,
+            StoragePoolVO currentPool) {
+        List<StoragePool> storagePoolList = getCandidateStoragePoolsToMigrateLocalVolume(profile, targetHost, volume);
+
+        if (CollectionUtils.isEmpty(storagePoolList)) {
+            throw new CloudRuntimeException(String.format("There is not storage pools available at the target host [%s] to migrate volume [%s]", targetHost.getUuid(), volume.getUuid()));
+        }
+
+        Collections.shuffle(storagePoolList);
+        boolean canTargetHostAccessVolumeCurrentStoragePool = false;
+        for (StoragePool storagePool : storagePoolList) {
+            if (storagePool.getId() == currentPool.getId()) {
+                canTargetHostAccessVolumeCurrentStoragePool = true;
+                break;
+            }
+
+        }
+        if (!canTargetHostAccessVolumeCurrentStoragePool) {
+            volumeToPoolObjectMap.put(volume, _storagePoolDao.findByUuid(storagePoolList.get(0).getUuid()));
+        }
+    }
+
+    /**
+     * We use {@link StoragePoolAllocator} objects to find storage pools connected to the targetHost where we would be able to allocate the given volume.
+     */
+    protected List<StoragePool> getCandidateStoragePoolsToMigrateLocalVolume(VirtualMachineProfile profile, Host targetHost, Volume volume) {
+        List<StoragePool> poolList = new ArrayList<>();
+
+        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+        DiskProfile diskProfile = new DiskProfile(volume, diskOffering, profile.getHypervisorType());
+        DataCenterDeployment plan = new DataCenterDeployment(targetHost.getDataCenterId(), targetHost.getPodId(), targetHost.getClusterId(), targetHost.getId(), null, null);
+        ExcludeList avoid = new ExcludeList();
+
+        StoragePoolVO volumeStoragePool = _storagePoolDao.findById(volume.getPoolId());
+        if (volumeStoragePool.isLocal()) {
+            diskProfile.setUseLocalStorage(true);
+        }
+        for (StoragePoolAllocator allocator : _storagePoolAllocators) {
+            List<StoragePool> poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
+            if (CollectionUtils.isEmpty(poolListFromAllocator)) {
+                continue;
+            }
+            for (StoragePool pool : poolListFromAllocator) {
+                if (pool.isLocal() || isStorageCrossClusterMigration(targetHost, volumeStoragePool)) {
+                    poolList.add(pool);
+                }
+            }
+        }
+        return poolList;
+    }
+
+    private <T extends VMInstanceVO> void moveVmToMigratingState(final T vm, final Long hostId, final ItWorkVO work) throws ConcurrentOperationException {
+        // Put the vm in migrating state.
+        try {
+            if (!changeState(vm, Event.MigrationRequested, hostId, work, Step.Migrating)) {
+                s_logger.info("Migration cancelled because state has changed: " + vm);
+                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
+            }
+        } catch (final NoTransitionException e) {
+            s_logger.info("Migration cancelled because " + e.getMessage());
+            throw new ConcurrentOperationException("Migration cancelled because " + e.getMessage());
+        }
+    }
+
+    private <T extends VMInstanceVO> void moveVmOutofMigratingStateOnSuccess(final T vm, final Long hostId, final ItWorkVO work) throws ConcurrentOperationException {
+        // Put the vm in running state.
+        try {
+            if (!changeState(vm, Event.OperationSucceeded, hostId, work, Step.Started)) {
+                s_logger.error("Unable to change the state for " + vm);
+                throw new ConcurrentOperationException("Unable to change the state for " + vm);
+            }
+        } catch (final NoTransitionException e) {
+            s_logger.error("Unable to change state due to " + e.getMessage());
+            throw new ConcurrentOperationException("Unable to change state due to " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void migrateWithStorage(final String vmUuid, final long srcHostId, final long destHostId, final Map<Long, Long> volumeToPool)
+            throws ResourceUnavailableException, ConcurrentOperationException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+
+        } else {
+            final Outcome<VirtualMachine> outcome = migrateVmWithStorageThroughJobQueue(vmUuid, srcHostId, destHostId, volumeToPool);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobException != null) {
+                if (jobException instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobException;
+                } else if (jobException instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobException;
+                } else if (jobException instanceof RuntimeException) {
+                    throw (RuntimeException)jobException;
+                } else if (jobException instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
+                }
+            }
+        }
+    }
+
+    private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHostId, final long destHostId, final Map<Long, Long> volumeToPool) throws ResourceUnavailableException,
+    ConcurrentOperationException {
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final HostVO srcHost = _hostDao.findById(srcHostId);
+        final HostVO destHost = _hostDao.findById(destHostId);
+        final VirtualMachineGuru vmGuru = getVmGuru(vm);
+
+        final DataCenterVO dc = _dcDao.findById(destHost.getDataCenterId());
+        final HostPodVO pod = _podDao.findById(destHost.getPodId());
+        final Cluster cluster = _clusterDao.findById(destHost.getClusterId());
+        final DeployDestination destination = new DeployDestination(dc, pod, cluster, destHost);
+
+        // Create a map of which volume should go in which storage pool.
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+        final Map<Volume, StoragePool> volumeToPoolMap = createMappingVolumeAndStoragePool(profile, destHost, volumeToPool);
+
+        // If none of the volumes have to be migrated, fail the call. Administrator needs to make a call for migrating
+        // a vm and not migrating a vm with storage.
+        if (volumeToPoolMap == null || volumeToPoolMap.isEmpty()) {
+            throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost +
+                    " doesn't involve migrating the volumes.");
+        }
+
+        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
+        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
+        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
+        }
+
+        _networkMgr.prepareNicForMigration(profile, destination);
+        volumeMgr.prepareForMigration(profile, destination);
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
+        final VirtualMachineTO to = hvGuru.implement(profile);
+
+        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
+        work.setStep(Step.Prepare);
+        work.setResourceType(ItWorkVO.ResourceType.Host);
+        work.setResourceId(destHostId);
+        work = _workDao.persist(work);
+
+
+        // Put the vm in migrating state.
+        vm.setLastHostId(srcHostId);
+        vm.setPodIdToDeployIn(destHost.getPodId());
+        moveVmToMigratingState(vm, destHostId, work);
+
+        boolean migrated = false;
+        try {
+
+            // config drive: Detach the config drive at source host
+            // After migration successful attach the config drive in destination host
+            // On migration failure VM will be stopped, So configIso will be deleted
+
+            Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
+
+            List<String[]> vmData = null;
+            if (defaultNic != null) {
+                UserVmVO userVm = _userVmDao.findById(vm.getId());
+                Map<String, String> details = userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+                userVm.setDetails(details);
+
+                Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
+                if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                    final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
+                    boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+
+                    vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
+                            vm.getUuid(), defaultNic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
+                    String vmName = vm.getInstanceName();
+                    String configDriveIsoRootFolder = "/tmp";
+                    String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
+                    profile.setVmData(vmData);
+                    profile.setConfigDriveLabel(VmConfigDriveLabel.value());
+                    profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder);
+                    profile.setConfigDriveIsoFile(isoFile);
+
+                    // At source host detach the config drive iso.
+                    AttachOrDettachConfigDriveCommand dettachCommand = new AttachOrDettachConfigDriveCommand(vm.getInstanceName(), vmData, VmConfigDriveLabel.value(), false);
+                    try {
+                        _agentMgr.send(srcHost.getId(), dettachCommand);
+                        s_logger.debug("Deleted config drive ISO for  vm " + vm.getInstanceName() + " In host " + srcHost);
+                    } catch (OperationTimedoutException e) {
+                        s_logger.debug("TIme out occured while exeuting command AttachOrDettachConfigDrive " + e.getMessage());
+
+                    }
+
+                }
+            }
+
+            // Migrate the vm and its volume.
+            volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap);
+
+            // Put the vm back to running state.
+            moveVmOutofMigratingStateOnSuccess(vm, destHost.getId(), work);
+
+            try {
+                if (!checkVmOnHost(vm, destHostId)) {
+                    s_logger.error("Vm not found on destination host. Unable to complete migration for " + vm);
+                    try {
+                        _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
+                    } catch (final AgentUnavailableException e) {
+                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
+                    }
+                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
+                    throw new CloudRuntimeException("VM not found on desintation host. Unable to complete migration for " + vm);
+                }
+            } catch (final OperationTimedoutException e) {
+                s_logger.warn("Error while checking the vm " + vm + " is on host " + destHost, e);
+            }
+
+            migrated = true;
+        } finally {
+            if (!migrated) {
+                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
+                _alertMgr.sendAlert(alertType, srcHost.getDataCenterId(), srcHost.getPodId(),
+                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + srcHost.getName() + " in zone " + dc.getName() + " and pod " + dc.getName(),
+                        "Migrate Command failed.  Please check logs.");
+                try {
+                    _agentMgr.send(destHostId, new Commands(cleanup(vm.getInstanceName())), null);
+                    vm.setPodIdToDeployIn(srcHost.getPodId());
+                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
+                } catch (final AgentUnavailableException e) {
+                    s_logger.warn("Looks like the destination Host is unavailable for cleanup.", e);
+                } catch (final NoTransitionException e) {
+                    s_logger.error("Error while transitioning vm from migrating to running state.", e);
+                }
+            }
+
+            work.setStep(Step.Done);
+            _workDao.update(work.getId(), work);
+        }
+    }
+
+    @Override
+    public VirtualMachineTO toVmTO(final VirtualMachineProfile profile) {
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getVirtualMachine().getHypervisorType());
+        final VirtualMachineTO to = hvGuru.implement(profile);
+        return to;
+    }
+
+    protected void cancelWorkItems(final long nodeId) {
+        final GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem");
+
+        try {
+            if (scanLock.lock(3)) {
+                try {
+                    final List<ItWorkVO> works = _workDao.listWorkInProgressFor(nodeId);
+                    for (final ItWorkVO work : works) {
+                        s_logger.info("Handling unfinished work item: " + work);
+                        try {
+                            final VMInstanceVO vm = _vmDao.findById(work.getInstanceId());
+                            if (vm != null) {
+                                if (work.getType() == State.Starting) {
+                                    _haMgr.scheduleRestart(vm, true);
+                                    work.setManagementServerId(_nodeId);
+                                    work.setStep(Step.Done);
+                                    _workDao.update(work.getId(), work);
+                                } else if (work.getType() == State.Stopping) {
+                                    _haMgr.scheduleStop(vm, vm.getHostId(), WorkType.CheckStop);
+                                    work.setManagementServerId(_nodeId);
+                                    work.setStep(Step.Done);
+                                    _workDao.update(work.getId(), work);
+                                } else if (work.getType() == State.Migrating) {
+                                    _haMgr.scheduleMigration(vm);
+                                    work.setStep(Step.Done);
+                                    _workDao.update(work.getId(), work);
+                                }
+                            }
+                        } catch (final Exception e) {
+                            s_logger.error("Error while handling " + work, e);
+                        }
+                    }
+                } finally {
+                    scanLock.unlock();
+                }
+            }
+        } finally {
+            scanLock.releaseRef();
+        }
+    }
+
+    @Override
+    public void migrateAway(final String vmUuid, final long srcHostId) throws InsufficientServerCapacityException {
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                try {
+                    orchestrateMigrateAway(vmUuid, srcHostId, null);
+                } catch (final InsufficientServerCapacityException e) {
+                    s_logger.warn("Failed to deploy vm " + vmUuid + " with original planner, sending HAPlanner");
+                    orchestrateMigrateAway(vmUuid, srcHostId, _haMgr.getHAPlanner());
+                }
+            } finally {
+                _workJobDao.expunge(placeHolder.getId());
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = migrateVmAwayThroughJobQueue(vmUuid, srcHostId);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobException != null) {
+                if (jobException instanceof InsufficientServerCapacityException) {
+                    throw (InsufficientServerCapacityException)jobException;
+                } else if (jobException instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobException;
+                } else if (jobException instanceof RuntimeException) {
+                    throw (RuntimeException)jobException;
+                } else if (jobException instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
+                }
+            }
+        }
+    }
+
+    private void orchestrateMigrateAway(final String vmUuid, final long srcHostId, final DeploymentPlanner planner) throws InsufficientServerCapacityException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        if (vm == null) {
+            s_logger.debug("Unable to find a VM for " + vmUuid);
+            throw new CloudRuntimeException("Unable to find " + vmUuid);
+        }
+
+        ServiceOfferingVO offeringVO = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, offeringVO, null, null);
+
+        final Long hostId = vm.getHostId();
+        if (hostId == null) {
+            s_logger.debug("Unable to migrate because the VM doesn't have a host id: " + vm);
+            throw new CloudRuntimeException("Unable to migrate " + vmUuid);
+        }
+
+        final Host host = _hostDao.findById(hostId);
+        Long poolId = null;
+        final List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vm.getId());
+        for (final VolumeVO rootVolumeOfVm : vols) {
+            final StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
+            if (rootDiskPool != null) {
+                poolId = rootDiskPool.getId();
+            }
+        }
+
+        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, poolId, null);
+        final ExcludeList excludes = new ExcludeList();
+        excludes.addHost(hostId);
+
+        DeployDestination dest = null;
+        while (true) {
+
+            try {
+                dest = _dpMgr.planDeployment(profile, plan, excludes, planner);
+            } catch (final AffinityConflictException e2) {
+                s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
+                throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
+            }
+
+            if (dest != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Found destination " + dest + " for migrating to.");
+                }
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to find destination for migrating the vm " + profile);
+                }
+                throw new InsufficientServerCapacityException("Unable to find a server to migrate to.", host.getClusterId());
+            }
+
+            excludes.addHost(dest.getHost().getId());
+            try {
+                migrate(vm, srcHostId, dest);
+                return;
+            } catch (final ResourceUnavailableException e) {
+                s_logger.debug("Unable to migrate to unavailable " + dest);
+            } catch (final ConcurrentOperationException e) {
+                s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
+            }
+
+            try {
+                advanceStop(vmUuid, true);
+                throw new CloudRuntimeException("Unable to migrate " + vm);
+            } catch (final ResourceUnavailableException e) {
+                s_logger.debug("Unable to stop VM due to " + e.getMessage());
+                throw new CloudRuntimeException("Unable to migrate " + vm);
+            } catch (final ConcurrentOperationException e) {
+                s_logger.debug("Unable to stop VM due to " + e.getMessage());
+                throw new CloudRuntimeException("Unable to migrate " + vm);
+            } catch (final OperationTimedoutException e) {
+                s_logger.debug("Unable to stop VM due to " + e.getMessage());
+                throw new CloudRuntimeException("Unable to migrate " + vm);
+            }
+        }
+    }
+
+    protected class CleanupTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            s_logger.trace("VM Operation Thread Running");
+            try {
+                _workDao.cleanup(VmOpCleanupWait.value());
+                final Date cutDate = new Date(DateUtil.currentGMTTime().getTime() - VmOpCleanupInterval.value() * 1000);
+                _workJobDao.expungeCompletedWorkJobs(cutDate);
+            } catch (final Exception e) {
+                s_logger.error("VM Operations failed due to ", e);
+            }
+        }
+    }
+
+    @Override
+    public boolean isVirtualMachineUpgradable(final VirtualMachine vm, final ServiceOffering offering) {
+        boolean isMachineUpgradable = true;
+        for (final HostAllocator allocator : hostAllocators) {
+            isMachineUpgradable = allocator.isVirtualMachineUpgradable(vm, offering);
+            if (isMachineUpgradable) {
+                continue;
+            } else {
+                break;
+            }
+        }
+
+        return isMachineUpgradable;
+    }
+
+    @Override
+    public void reboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException {
+        try {
+            advanceReboot(vmUuid, params);
+        } catch (final ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Unable to reboot a VM due to concurrent operation", e);
+        }
+    }
+
+    @Override
+    public void advanceReboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params)
+            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if ( jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateReboot(vmUuid, params);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = rebootVmThroughJobQueue(vmUuid, params);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof InsufficientCapacityException) {
+                    throw (InsufficientCapacityException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+            }
+        }
+    }
+
+    private void orchestrateReboot(final String vmUuid, final Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ConcurrentOperationException,
+    ResourceUnavailableException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        // if there are active vm snapshots task, state change is not allowed
+        if(_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())){
+            s_logger.error("Unable to reboot VM " + vm + " due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
+            throw new CloudRuntimeException("Unable to reboot VM " + vm + " due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
+        }
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
+        final Host host = _hostDao.findById(vm.getHostId());
+        if (host == null) {
+            // Should findById throw an Exception is the host is not found?
+            throw new CloudRuntimeException("Unable to retrieve host with id " + vm.getHostId());
+        }
+        final Cluster cluster = _entityMgr.findById(Cluster.class, host.getClusterId());
+        final Pod pod = _entityMgr.findById(Pod.class, host.getPodId());
+        final DeployDestination dest = new DeployDestination(dc, pod, cluster, host);
+
+        try {
+
+            final Commands cmds = new Commands(Command.OnError.Stop);
+            cmds.addCommand(new RebootCommand(vm.getInstanceName(), getExecuteInSequence(vm.getHypervisorType())));
+            _agentMgr.send(host.getId(), cmds);
+
+            final Answer rebootAnswer = cmds.getAnswer(RebootAnswer.class);
+            if (rebootAnswer != null && rebootAnswer.getResult()) {
+                return;
+            }
+            s_logger.info("Unable to reboot VM " + vm + " on " + dest.getHost() + " due to " + (rebootAnswer == null ? " no reboot answer" : rebootAnswer.getDetails()));
+        } catch (final OperationTimedoutException e) {
+            s_logger.warn("Unable to send the reboot command to host " + dest.getHost() + " for the vm " + vm + " due to operation timeout", e);
+            throw new CloudRuntimeException("Failed to reboot the vm on host " + dest.getHost());
+        }
+    }
+
+    public Command cleanup(final VirtualMachine vm) {
+        StopCommand cmd = new StopCommand(vm, getExecuteInSequence(vm.getHypervisorType()), false);
+        cmd.setControlIp(getControlNicIpForVM(vm));
+        return cmd;
+    }
+
+    private String getControlNicIpForVM(VirtualMachine vm) {
+        if (vm.getType() == VirtualMachine.Type.ConsoleProxy || vm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
+            NicVO nic = _nicsDao.getControlNicForVM(vm.getId());
+            return nic.getIPv4Address();
+        } else if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+            return vm.getPrivateIpAddress();
+        } else {
+            return null;
+        }
+    }
+    public Command cleanup(final String vmName) {
+        VirtualMachine vm = _vmDao.findVMByInstanceName(vmName);
+
+        StopCommand cmd = new StopCommand(vmName, getExecuteInSequence(null), false);
+        cmd.setControlIp(getControlNicIpForVM(vm));
+        return cmd;
+    }
+
+
+    // this is XenServer specific
+    public void syncVMMetaData(final Map<String, String> vmMetadatum) {
+        if (vmMetadatum == null || vmMetadatum.isEmpty()) {
+            return;
+        }
+        List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmDetails = _userVmDao.getVmsDetailByNames(vmMetadatum.keySet(), "platform");
+        for (final Map.Entry<String, String> entry : vmMetadatum.entrySet()) {
+            final String name = entry.getKey();
+            final String platform = entry.getValue();
+            if (platform == null || platform.isEmpty()) {
+                continue;
+            }
+
+            boolean found = false;
+            for(Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>> vmDetail : vmDetails ) {
+                Pair<String, VirtualMachine.Type> vmNameTypePair = vmDetail.first();
+                if(vmNameTypePair.first().equals(name)) {
+                    found = true;
+                    if(vmNameTypePair.second() == VirtualMachine.Type.User) {
+                        Pair<Long, String> detailPair = vmDetail.second();
+                        String platformDetail = detailPair.second();
+
+                        if (platformDetail != null && platformDetail.equals(platform)) {
+                            break;
+                        }
+                        updateVmMetaData(detailPair.first(), platform);
+                    }
+                    break;
+                }
+            }
+
+            if(!found) {
+                VMInstanceVO vm = _vmDao.findVMByInstanceName(name);
+                if(vm != null && vm.getType() == VirtualMachine.Type.User) {
+                    updateVmMetaData(vm.getId(), platform);
+                }
+            }
+        }
+    }
+
+    // this is XenServer specific
+    private void updateVmMetaData(Long vmId, String platform) {
+        UserVmVO userVm = _userVmDao.findById(vmId);
+        _userVmDao.loadDetails(userVm);
+        if ( userVm.details.containsKey("timeoffset")) {
+            userVm.details.remove("timeoffset");
+        }
+        userVm.setDetail("platform",  platform);
+        String pvdriver = "xenserver56";
+        if ( platform.contains("device_id")) {
+            pvdriver = "xenserver61";
+        }
+        if (!userVm.details.containsKey("hypervisortoolsversion") || !userVm.details.get("hypervisortoolsversion").equals(pvdriver)) {
+            userVm.setDetail("hypervisortoolsversion", pvdriver);
+        }
+        _userVmDao.saveDetails(userVm);
+    }
+
+    @Override
+    public boolean isRecurring() {
+        return true;
+    }
+
+    @Override
+    public boolean processAnswers(final long agentId, final long seq, final Answer[] answers) {
+        for (final Answer answer : answers) {
+            if ( answer instanceof ClusterVMMetaDataSyncAnswer) {
+                final ClusterVMMetaDataSyncAnswer cvms = (ClusterVMMetaDataSyncAnswer)answer;
+                if (!cvms.isExecuted()) {
+                    syncVMMetaData(cvms.getVMMetaDatum());
+                    cvms.setExecuted();
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean processTimeout(final long agentId, final long seq) {
+        return true;
+    }
+
+    @Override
+    public int getTimeout() {
+        return -1;
+    }
+
+    @Override
+    public boolean processCommands(final long agentId, final long seq, final Command[] cmds) {
+        boolean processed = false;
+        for (final Command cmd : cmds) {
+            if (cmd instanceof PingRoutingCommand) {
+                final PingRoutingCommand ping = (PingRoutingCommand)cmd;
+                if (ping.getHostVmStateReport() != null) {
+                    _syncMgr.processHostVmStatePingReport(agentId, ping.getHostVmStateReport());
+                }
+
+                // take the chance to scan VMs that are stuck in transitional states
+                // and are missing from the report
+                scanStalledVMInTransitionStateOnUpHost(agentId);
+                processed = true;
+            }
+        }
+        return processed;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(final long agentId, final AgentControlCommand cmd) {
+        return null;
+    }
+
+    @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 void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(final Host agent, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
+        if (!(cmd instanceof StartupRoutingCommand)) {
+            return;
+        }
+
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Received startup command from hypervisor host. host id: " + agent.getId());
+        }
+
+        _syncMgr.resetHostSyncState(agent.getId());
+
+        if (forRebalance) {
+            s_logger.debug("Not processing listener " + this + " as connect happens on rebalance process");
+            return;
+        }
+        final Long clusterId = agent.getClusterId();
+        final long agentId = agent.getId();
+
+        if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen
+            // initiate the cron job
+            final ClusterVMMetaDataSyncCommand syncVMMetaDataCmd = new ClusterVMMetaDataSyncCommand(ClusterVMMetaDataSyncInterval.value(), clusterId);
+            try {
+                final long seq_no = _agentMgr.send(agentId, new Commands(syncVMMetaDataCmd), this);
+                s_logger.debug("Cluster VM metadata sync started with jobid " + seq_no);
+            } catch (final AgentUnavailableException e) {
+                s_logger.fatal("The Cluster VM metadata sync process failed for cluster id " + clusterId + " with ", e);
+            }
+        }
+    }
+
+    protected class TransitionTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            final GlobalLock lock = GlobalLock.getInternLock("TransitionChecking");
+            if (lock == null) {
+                s_logger.debug("Couldn't get the global lock");
+                return;
+            }
+
+            if (!lock.lock(30)) {
+                s_logger.debug("Couldn't lock the db");
+                return;
+            }
+            try {
+                scanStalledVMInTransitionStateOnDisconnectedHosts();
+
+                final List<VMInstanceVO> instances = _vmDao.findVMInTransition(new Date(DateUtil.currentGMTTime().getTime() - AgentManager.Wait.value() * 1000), State.Starting, State.Stopping);
+                for (final VMInstanceVO instance : instances) {
+                    final State state = instance.getState();
+                    if (state == State.Stopping) {
+                        _haMgr.scheduleStop(instance, instance.getHostId(), WorkType.CheckStop);
+                    } else if (state == State.Starting) {
+                        _haMgr.scheduleRestart(instance, true);
+                    }
+                }
+            } catch (final Exception e) {
+                s_logger.warn("Caught the following exception on transition checking", e);
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
+
+    @Override
+    public VMInstanceVO findById(final long vmId) {
+        return _vmDao.findById(vmId);
+    }
+
+    @Override
+    public void checkIfCanUpgrade(final VirtualMachine vmInstance, final ServiceOffering newServiceOffering) {
+        if (newServiceOffering == null) {
+            throw new InvalidParameterValueException("Invalid parameter, newServiceOffering can't be null");
+        }
+
+        // Check that the VM is stopped / running
+        if (!(vmInstance.getState().equals(State.Stopped) || vmInstance.getState().equals(State.Running))) {
+            s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState());
+            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState() +
+                    "; make sure the virtual machine is stopped/running");
+        }
+
+        // Check if the service offering being upgraded to is what the VM is already running with
+        if (!newServiceOffering.isDynamic() && vmInstance.getServiceOfferingId() == newServiceOffering.getId()) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Not upgrading vm " + vmInstance.toString() + " since it already has the requested " + "service offering (" + newServiceOffering.getName() +
+                        ")");
+            }
+
+            throw new InvalidParameterValueException("Not upgrading vm " + vmInstance.toString() + " since it already " + "has the requested service offering (" +
+                    newServiceOffering.getName() + ")");
+        }
+
+        final ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+
+        // Check that the service offering being upgraded to has the same Guest IP type as the VM's current service offering
+        // NOTE: With the new network refactoring in 2.2, we shouldn't need the check for same guest IP type anymore.
+        /*
+         * if (!currentServiceOffering.getGuestIpType().equals(newServiceOffering.getGuestIpType())) { String errorMsg =
+         * "The service offering being upgraded to has a guest IP type: " + newServiceOffering.getGuestIpType(); errorMsg +=
+         * ". Please select a service offering with the same guest IP type as the VM's current service offering (" +
+         * currentServiceOffering.getGuestIpType() + ")."; throw new InvalidParameterValueException(errorMsg); }
+         */
+
+        // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service
+        // offering
+        if (currentServiceOffering.isUseLocalStorage() != newServiceOffering.isUseLocalStorage()) {
+            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() +
+                    ", cannot switch between local storage and shared storage service offerings.  Current offering " + "useLocalStorage=" +
+                    currentServiceOffering.isUseLocalStorage() + ", target offering useLocalStorage=" + newServiceOffering.isUseLocalStorage());
+        }
+
+        // if vm is a system vm, check if it is a system service offering, if yes return with error as it cannot be used for user vms
+        if (currentServiceOffering.isSystemUse() != newServiceOffering.isSystemUse()) {
+            throw new InvalidParameterValueException("isSystem property is different for current service offering and new service offering");
+        }
+
+        // Check that there are enough resources to upgrade the service offering
+        if (!isVirtualMachineUpgradable(vmInstance, newServiceOffering)) {
+            throw new InvalidParameterValueException("Unable to upgrade virtual machine, not enough resources available " + "for an offering of " +
+                    newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
+        }
+
+        // Check that the service offering being upgraded to has all the tags of the current service offering.
+        final List<String> currentTags = StringUtils.csvTagsToList(currentServiceOffering.getTags());
+        final List<String> newTags = StringUtils.csvTagsToList(newServiceOffering.getTags());
+        if (!newTags.containsAll(currentTags)) {
+            throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " +
+                    "the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
+        }
+    }
+
+    @Override
+    public boolean upgradeVmDb(final long vmId, final long serviceOfferingId) {
+        final VMInstanceVO vmForUpdate = _vmDao.createForUpdate();
+        vmForUpdate.setServiceOfferingId(serviceOfferingId);
+        final ServiceOffering newSvcOff = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        vmForUpdate.setHaEnabled(newSvcOff.isOfferHA());
+        vmForUpdate.setLimitCpuUse(newSvcOff.getLimitCpuUse());
+        vmForUpdate.setServiceOfferingId(newSvcOff.getId());
+        return _vmDao.update(vmId, vmForUpdate);
+    }
+
+    @Override
+    public NicProfile addVmToNetwork(final VirtualMachine vm, final Network network, final NicProfile requested)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                return orchestrateAddVmToNetwork(vm, network, requested);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = addVmToNetworkThroughJobQueue(vm, network, requested);
+
+            try {
+                outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution exception", e);
+            }
+
+            final Object jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobException != null) {
+                if (jobException instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobException;
+                } else if (jobException instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobException;
+                } else if (jobException instanceof InsufficientCapacityException) {
+                    throw (InsufficientCapacityException)jobException;
+                } else if (jobException instanceof RuntimeException) {
+                    throw (RuntimeException)jobException;
+                } else if (jobException instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobException);
+                } else if (jobException instanceof NicProfile) {
+                    return (NicProfile)jobException;
+                }
+            }
+
+            throw new RuntimeException("Unexpected job execution result");
+        }
+    }
+
+    private NicProfile orchestrateAddVmToNetwork(final VirtualMachine vm, final Network network, final NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+        final CallContext cctx = CallContext.current();
+
+        s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
+        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
+        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
+
+        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
+
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        final Host host = _hostDao.findById(vm.getHostId());
+        final DeployDestination dest = new DeployDestination(dc, null, null, host);
+
+        //check vm state
+        if (vm.getState() == State.Running) {
+            //1) allocate and prepare nic
+            final NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true);
+
+            //2) Convert vmProfile to vmTO
+            final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
+            final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
+
+            //3) Convert nicProfile to NicTO
+            final NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType());
+
+            //4) plug the nic to the vm
+            s_logger.debug("Plugging nic for vm " + vm + " in network " + network);
+
+            boolean result = false;
+            try {
+                result = plugNic(network, nicTO, vmTO, context, dest);
+                if (result) {
+                    s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm  is a part of network now");
+                    final long isDefault = nic.isDefaultNic() ? 1 : 0;
+                    // insert nic's Id into DB as resource_name
+                    if(VirtualMachine.Type.User.equals(vmVO.getType())) {
+                        //Log usage event for user Vms only
+                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmVO.getAccountId(), vmVO.getDataCenterId(), vmVO.getId(),
+                                Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vmVO.getUuid(), vm.isDisplay());
+                    }
+                    return nic;
+                } else {
+                    s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network);
+                    return null;
+                }
+            } finally {
+                if (!result) {
+                    s_logger.debug("Removing nic " + nic + " from vm " + vmProfile.getVirtualMachine() + " as nic plug failed on the backend");
+                    _networkMgr.removeNic(vmProfile, _nicsDao.findById(nic.getId()));
+                }
+            }
+        } else if (vm.getState() == State.Stopped) {
+            //1) allocate nic
+            return _networkMgr.createNicForVm(network, requested, context, vmProfile, false);
+        } else {
+            s_logger.warn("Unable to add vm " + vm + " to network  " + network);
+            throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state", DataCenter.class, vm.getDataCenterId());
+        }
+    }
+
+    @Override
+    public NicTO toNicTO(final NicProfile nic, final HypervisorType hypervisorType) {
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType);
+
+        final NicTO nicTO = hvGuru.toNicTO(nic);
+        return nicTO;
+    }
+
+    @Override
+    public boolean removeNicFromVm(final VirtualMachine vm, final Nic nic)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                return orchestrateRemoveNicFromVm(vm, nic);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+
+        } else {
+            final Outcome<VirtualMachine> outcome = removeNicFromVmThroughJobQueue(vm, nic);
+
+            try {
+                outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                } else if (jobResult instanceof Boolean) {
+                    return (Boolean)jobResult;
+                }
+            }
+
+            throw new RuntimeException("Job failed with un-handled exception");
+        }
+    }
+
+    private boolean orchestrateRemoveNicFromVm(final VirtualMachine vm, final Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
+        final CallContext cctx = CallContext.current();
+        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
+        final NetworkVO network = _networkDao.findById(nic.getNetworkId());
+        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
+
+        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
+
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        final Host host = _hostDao.findById(vm.getHostId());
+        final DeployDestination dest = new DeployDestination(dc, null, null, host);
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
+        final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
+
+        final NicProfile nicProfile =
+                new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()),
+                        _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
+
+        //1) Unplug the nic
+        if (vm.getState() == State.Running) {
+            final NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
+            s_logger.debug("Un-plugging nic " + nic + " for vm " + vm + " from network " + network);
+            final boolean result = unplugNic(network, nicTO, vmTO, context, dest);
+            if (result) {
+                s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network);
+                final long isDefault = nic.isDefaultNic() ? 1 : 0;
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                        Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
+            } else {
+                s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
+                return false;
+            }
+        } else if (vm.getState() != State.Stopped) {
+            s_logger.warn("Unable to remove vm " + vm + " from network  " + network);
+            throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state", DataCenter.class, vm.getDataCenterId());
+        }
+
+        //2) Release the nic
+        _networkMgr.releaseNic(vmProfile, nic);
+        s_logger.debug("Successfully released nic " + nic + "for vm " + vm);
+
+        //3) Remove the nic
+        _networkMgr.removeNic(vmProfile, nic);
+        _nicsDao.expunge(nic.getId());
+        return true;
+    }
+
+    @Override
+    @DB
+    public boolean removeVmFromNetwork(final VirtualMachine vm, final Network network, final URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO will serialize on the VM object later to resolve operation conflicts
+        return orchestrateRemoveVmFromNetwork(vm, network, broadcastUri);
+    }
+
+    @DB
+    private boolean orchestrateRemoveVmFromNetwork(final VirtualMachine vm, final Network network, final URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException {
+        final CallContext cctx = CallContext.current();
+        final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
+        final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
+
+        final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, null, null, null);
+
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        final Host host = _hostDao.findById(vm.getHostId());
+        final DeployDestination dest = new DeployDestination(dc, null, null, host);
+        final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
+        final VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
+
+        Nic nic = null;
+        if (broadcastUri != null) {
+            nic = _nicsDao.findByNetworkIdInstanceIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri.toString());
+        } else {
+            nic = _networkModel.getNicInNetwork(vm.getId(), network.getId());
+        }
+
+        if (nic == null) {
+            s_logger.warn("Could not get a nic with " + network);
+            return false;
+        }
+
+        // don't delete default NIC on a user VM
+        if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User) {
+            s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
+            throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
+        }
+
+        //Lock on nic is needed here
+        final Nic lock = _nicsDao.acquireInLockTable(nic.getId());
+        if (lock == null) {
+            //check if nic is still there. Return if it was released already
+            if (_nicsDao.findById(nic.getId()) == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Not need to remove the vm " + vm + " from network " + network + " as the vm doesn't have nic in this network");
+                }
+                return true;
+            }
+            throw new ConcurrentOperationException("Unable to lock nic " + nic.getId());
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Lock is acquired for nic id " + lock.getId() + " as a part of remove vm " + vm + " from network " + network);
+        }
+
+        try {
+            final NicProfile nicProfile =
+                    new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(network.getId(), vm.getId()),
+                            _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
+
+            //1) Unplug the nic
+            if (vm.getState() == State.Running) {
+                final NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
+                s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network);
+                final boolean result = unplugNic(network, nicTO, vmTO, context, dest);
+                if (result) {
+                    s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network);
+                } else {
+                    s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
+                    return false;
+                }
+            } else if (vm.getState() != State.Stopped) {
+                s_logger.warn("Unable to remove vm " + vm + " from network  " + network);
+                throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state", DataCenter.class, vm.getDataCenterId());
+            }
+
+            //2) Release the nic
+            _networkMgr.releaseNic(vmProfile, nic);
+            s_logger.debug("Successfully released nic " + nic + "for vm " + vm);
+
+            //3) Remove the nic
+            _networkMgr.removeNic(vmProfile, nic);
+            return true;
+        } finally {
+            if (lock != null) {
+                _nicsDao.releaseFromLockTable(lock.getId());
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Lock is released for nic id " + lock.getId() + " as a part of remove vm " + vm + " from network " + network);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void findHostAndMigrate(final String vmUuid, final Long newSvcOfferingId, final ExcludeList excludes) throws InsufficientCapacityException, ConcurrentOperationException,
+    ResourceUnavailableException {
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        if (vm == null) {
+            throw new CloudRuntimeException("Unable to find " + vmUuid);
+        }
+
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+
+        final Long srcHostId = vm.getHostId();
+        final Long oldSvcOfferingId = vm.getServiceOfferingId();
+        if (srcHostId == null) {
+            throw new CloudRuntimeException("Unable to scale the vm because it doesn't have a host id");
+        }
+        final Host host = _hostDao.findById(srcHostId);
+        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), null, null, null);
+        excludes.addHost(vm.getHostId());
+        vm.setServiceOfferingId(newSvcOfferingId); // Need to find the destination host based on new svc offering
+
+        DeployDestination dest = null;
+
+        try {
+            dest = _dpMgr.planDeployment(profile, plan, excludes, null);
+        } catch (final AffinityConflictException e2) {
+            s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
+            throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
+        }
+
+        if (dest != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(" Found " + dest + " for scaling the vm to.");
+            }
+        }
+
+        if (dest == null) {
+            throw new InsufficientServerCapacityException("Unable to find a server to scale the vm to.", host.getClusterId());
+        }
+
+        excludes.addHost(dest.getHost().getId());
+        try {
+            migrateForScale(vm.getUuid(), srcHostId, dest, oldSvcOfferingId);
+        } catch (final ResourceUnavailableException e) {
+            s_logger.debug("Unable to migrate to unavailable " + dest);
+            throw e;
+        } catch (final ConcurrentOperationException e) {
+            s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
+            throw e;
+        }
+    }
+
+    @Override
+    public void migrateForScale(final String vmUuid, final long srcHostId, final DeployDestination dest, final Long oldSvcOfferingId)
+            throws ResourceUnavailableException, ConcurrentOperationException {
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                orchestrateMigrateForScale(vmUuid, srcHostId, dest, oldSvcOfferingId);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = migrateVmForScaleThroughJobQueue(vmUuid, srcHostId, dest, oldSvcOfferingId);
+
+            try {
+                final VirtualMachine vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                }
+            }
+        }
+    }
+
+    private void orchestrateMigrateForScale(final String vmUuid, final long srcHostId, final DeployDestination dest, final Long oldSvcOfferingId)
+            throws ResourceUnavailableException, ConcurrentOperationException {
+
+        VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+        s_logger.info("Migrating " + vm + " to " + dest);
+
+        vm.getServiceOfferingId();
+        final long dstHostId = dest.getHost().getId();
+        final Host fromHost = _hostDao.findById(srcHostId);
+        if (fromHost == null) {
+            s_logger.info("Unable to find the host to migrate from: " + srcHostId);
+            throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
+        }
+
+        if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
+            s_logger.info("Source and destination host are not in same cluster, unable to migrate to host: " + dstHostId);
+            throw new CloudRuntimeException("Source and destination host are not in same cluster, unable to migrate to host: " + dest.getHost().getId());
+        }
+
+        final VirtualMachineGuru vmGuru = getVmGuru(vm);
+
+        final long vmId = vm.getId();
+        vm = _vmDao.findByUuid(vmUuid);
+        if (vm == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find the vm " + vm);
+            }
+            throw new CloudRuntimeException("Unable to find a virtual machine with id " + vmId);
+        }
+
+        if (vm.getState() != State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
+            }
+            throw new CloudRuntimeException("VM is not Running, unable to migrate the vm currently " + vm + " , current state: " + vm.getState().toString());
+        }
+
+        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM_MIGRATE;
+        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER_MIGRATE;
+        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY_MIGRATE;
+        }
+
+        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+        _networkMgr.prepareNicForMigration(profile, dest);
+
+        volumeMgr.prepareForMigration(profile, dest);
+
+        final VirtualMachineTO to = toVmTO(profile);
+        final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
+
+        ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
+        work.setStep(Step.Prepare);
+        work.setResourceType(ItWorkVO.ResourceType.Host);
+        work.setResourceId(dstHostId);
+        work = _workDao.persist(work);
+
+        Answer pfma = null;
+        try {
+            pfma = _agentMgr.send(dstHostId, pfmc);
+            if (pfma == null || !pfma.getResult()) {
+                final String details = pfma != null ? pfma.getDetails() : "null answer returned";
+                final String msg = "Unable to prepare for migration due to " + details;
+                pfma = null;
+                throw new AgentUnavailableException(msg, dstHostId);
+            }
+        } catch (final OperationTimedoutException e1) {
+            throw new AgentUnavailableException("Operation timed out", dstHostId);
+        } finally {
+            if (pfma == null) {
+                work.setStep(Step.Done);
+                _workDao.update(work.getId(), work);
+            }
+        }
+
+        vm.setLastHostId(srcHostId);
+        try {
+            if (vm == null || vm.getHostId() == null || vm.getHostId() != srcHostId || !changeState(vm, Event.MigrationRequested, dstHostId, work, Step.Migrating)) {
+                s_logger.info("Migration cancelled because state has changed: " + vm);
+                throw new ConcurrentOperationException("Migration cancelled because state has changed: " + vm);
+            }
+        } catch (final NoTransitionException e1) {
+            s_logger.info("Migration cancelled because " + e1.getMessage());
+            throw new ConcurrentOperationException("Migration cancelled because " + e1.getMessage());
+        }
+
+        boolean migrated = false;
+        try {
+            final boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+            final MigrateCommand mc = new MigrateCommand(vm.getInstanceName(), dest.getHost().getPrivateIpAddress(), isWindows, to, getExecuteInSequence(vm.getHypervisorType()));
+
+            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
+            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
+
+            mc.setAutoConvergence(kvmAutoConvergence);
+
+            mc.setHostGuid(dest.getHost().getGuid());
+
+            try {
+                final Answer ma = _agentMgr.send(vm.getLastHostId(), mc);
+                if (ma == null || !ma.getResult()) {
+                    final String details = ma != null ? ma.getDetails() : "null answer returned";
+                    final String msg = "Unable to migrate due to " + details;
+                    s_logger.error(msg);
+                    throw new CloudRuntimeException(msg);
+                }
+            } catch (final OperationTimedoutException e) {
+                if (e.isActive()) {
+                    s_logger.warn("Active migration command so scheduling a restart for " + vm);
+                    _haMgr.scheduleRestart(vm, true);
+                }
+                throw new AgentUnavailableException("Operation timed out on migrating " + vm, dstHostId);
+            }
+
+            try {
+                final long newServiceOfferingId = vm.getServiceOfferingId();
+                vm.setServiceOfferingId(oldSvcOfferingId); // release capacity for the old service offering only
+                if (!changeState(vm, VirtualMachine.Event.OperationSucceeded, dstHostId, work, Step.Started)) {
+                    throw new ConcurrentOperationException("Unable to change the state for " + vm);
+                }
+                vm.setServiceOfferingId(newServiceOfferingId);
+            } catch (final NoTransitionException e1) {
+                throw new ConcurrentOperationException("Unable to change state due to " + e1.getMessage());
+            }
+
+            try {
+                if (!checkVmOnHost(vm, dstHostId)) {
+                    s_logger.error("Unable to complete migration for " + vm);
+                    try {
+                        _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
+                    } catch (final AgentUnavailableException e) {
+                        s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
+                    }
+                    cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.AgentReportStopped, true);
+                    throw new CloudRuntimeException("Unable to complete migration for " + vm);
+                }
+            } catch (final OperationTimedoutException e) {
+                s_logger.debug("Error while checking the vm " + vm + " on host " + dstHostId, e);
+            }
+
+            migrated = true;
+        } finally {
+            if (!migrated) {
+                s_logger.info("Migration was unsuccessful.  Cleaning up: " + vm);
+
+                _alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(),
+                        "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone " + dest.getDataCenter().getName() + " and pod " +
+                                dest.getPod().getName(), "Migrate Command failed.  Please check logs.");
+                try {
+                    _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
+                } catch (final AgentUnavailableException ae) {
+                    s_logger.info("Looks like the destination Host is unavailable for cleanup");
+                }
+
+                try {
+                    stateTransitTo(vm, Event.OperationFailed, srcHostId);
+                } catch (final NoTransitionException e) {
+                    s_logger.warn(e.getMessage());
+                }
+            }
+
+            work.setStep(Step.Done);
+            _workDao.update(work.getId(), work);
+        }
+    }
+
+    @Override
+    public boolean replugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        boolean result = true;
+
+        final VMInstanceVO router = _vmDao.findById(vm.getId());
+        if (router.getState() == State.Running) {
+            try {
+                final ReplugNicCommand replugNicCmd = new ReplugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
+                final Commands cmds = new Commands(Command.OnError.Stop);
+                cmds.addCommand("replugnic", replugNicCmd);
+                _agentMgr.send(dest.getHost().getId(), cmds);
+                final ReplugNicAnswer replugNicAnswer = cmds.getAnswer(ReplugNicAnswer.class);
+                if (replugNicAnswer == null || !replugNicAnswer.getResult()) {
+                    s_logger.warn("Unable to replug nic for vm " + vm.getName());
+                    result = false;
+                }
+            } catch (final OperationTimedoutException e) {
+                throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
+            }
+        } else {
+            s_logger.warn("Unable to apply ReplugNic, vm " + router + " is not in the right state " + router.getState());
+
+            throw new ResourceUnavailableException("Unable to apply ReplugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        return result;
+    }
+
+    public boolean plugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        boolean result = true;
+
+        final VMInstanceVO router = _vmDao.findById(vm.getId());
+        if (router.getState() == State.Running) {
+            try {
+                final PlugNicCommand plugNicCmd = new PlugNicCommand(nic, vm.getName(), vm.getType(), vm.getDetails());
+                final Commands cmds = new Commands(Command.OnError.Stop);
+                cmds.addCommand("plugnic", plugNicCmd);
+                _agentMgr.send(dest.getHost().getId(), cmds);
+                final PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class);
+                if (plugNicAnswer == null || !plugNicAnswer.getResult()) {
+                    s_logger.warn("Unable to plug nic for vm " + vm.getName());
+                    result = false;
+                }
+            } catch (final OperationTimedoutException e) {
+                throw new AgentUnavailableException("Unable to plug nic for router " + vm.getName() + " in network " + network, dest.getHost().getId(), e);
+            }
+        } else {
+            s_logger.warn("Unable to apply PlugNic, vm " + router + " is not in the right state " + router.getState());
+
+            throw new ResourceUnavailableException("Unable to apply PlugNic on the backend," + " vm " + vm + " is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        return result;
+    }
+
+    public boolean unplugNic(final Network network, final NicTO nic, final VirtualMachineTO vm, final ReservationContext context, final DeployDestination dest) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+
+        boolean result = true;
+        final VMInstanceVO router = _vmDao.findById(vm.getId());
+
+        if (router.getState() == State.Running) {
+            // collect vm network statistics before unplug a nic
+            UserVmVO userVm = _userVmDao.findById(vm.getId());
+            if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
+                _userVmService.collectVmNetworkStatistics(userVm);
+            }
+            try {
+                final Commands cmds = new Commands(Command.OnError.Stop);
+                final UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(nic, vm.getName());
+                cmds.addCommand("unplugnic", unplugNicCmd);
+                _agentMgr.send(dest.getHost().getId(), cmds);
+
+                final UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class);
+                if (unplugNicAnswer == null || !unplugNicAnswer.getResult()) {
+                    s_logger.warn("Unable to unplug nic from router " + router);
+                    result = false;
+                }
+            } catch (final OperationTimedoutException e) {
+                throw new AgentUnavailableException("Unable to unplug nic from rotuer " + router + " from network " + network, dest.getHost().getId(), e);
+            }
+        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
+            s_logger.debug("Vm " + router.getInstanceName() + " is in " + router.getState() + ", so not sending unplug nic command to the backend");
+        } else {
+            s_logger.warn("Unable to apply unplug nic, Vm " + router + " is not in the right state " + router.getState());
+
+            throw new ResourceUnavailableException("Unable to apply unplug nic on the backend," + " vm " + router + " is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        return result;
+    }
+
+    @Override
+    public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering oldServiceOffering,
+            final boolean reconfiguringOnExistingHost)
+                    throws ResourceUnavailableException, InsufficientServerCapacityException, ConcurrentOperationException {
+
+        final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
+            placeHolder = createPlaceHolderWork(vm.getId());
+            try {
+                return orchestrateReConfigureVm(vmUuid, oldServiceOffering, reconfiguringOnExistingHost);
+            } finally {
+                if (placeHolder != null) {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            }
+        } else {
+            final Outcome<VirtualMachine> outcome = reconfigureVmThroughJobQueue(vmUuid, oldServiceOffering, reconfiguringOnExistingHost);
+
+            VirtualMachine vm = null;
+            try {
+                vm = outcome.get();
+            } catch (final InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (final java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            final Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ResourceUnavailableException) {
+                    throw (ResourceUnavailableException)jobResult;
+                } else if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof InsufficientServerCapacityException) {
+                    throw (InsufficientServerCapacityException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    s_logger.error("Unhandled exception", (Throwable)jobResult);
+                    throw new RuntimeException("Unhandled exception", (Throwable)jobResult);
+                }
+            }
+
+            return (VMInstanceVO)vm;
+        }
+    }
+
+    private VMInstanceVO orchestrateReConfigureVm(final String vmUuid, final ServiceOffering oldServiceOffering, final boolean reconfiguringOnExistingHost) throws ResourceUnavailableException,
+    ConcurrentOperationException {
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final long newServiceofferingId = vm.getServiceOfferingId();
+        final ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), newServiceofferingId);
+        final HostVO hostVo = _hostDao.findById(vm.getHostId());
+
+        final Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(hostVo.getClusterId());
+        final Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(hostVo.getClusterId());
+        final long minMemory = (long)(newServiceOffering.getRamSize() / memoryOvercommitRatio);
+        final ScaleVmCommand reconfigureCmd =
+                new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), (int)(newServiceOffering.getSpeed() / cpuOvercommitRatio),
+                        newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse());
+
+        final Long dstHostId = vm.getHostId();
+        if(vm.getHypervisorType().equals(HypervisorType.VMware)) {
+            final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
+            Map<String, String> details = null;
+            details = hvGuru.getClusterSettings(vm.getId());
+            reconfigureCmd.getVirtualMachine().setDetails(details);
+        }
+
+        final ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Running, vm.getType(), vm.getId());
+
+        work.setStep(Step.Prepare);
+        work.setResourceType(ItWorkVO.ResourceType.Host);
+        work.setResourceId(vm.getHostId());
+        _workDao.persist(work);
+        boolean success = false;
+        try {
+            if (reconfiguringOnExistingHost) {
+                vm.setServiceOfferingId(oldServiceOffering.getId());
+                _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); //release the old capacity
+                vm.setServiceOfferingId(newServiceofferingId);
+                _capacityMgr.allocateVmCapacity(vm, false); // lock the new capacity
+            }
+
+            final Answer reconfigureAnswer = _agentMgr.send(vm.getHostId(), reconfigureCmd);
+            if (reconfigureAnswer == null || !reconfigureAnswer.getResult()) {
+                s_logger.error("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
+                throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
+            }
+
+            success = true;
+        } catch (final OperationTimedoutException e) {
+            throw new AgentUnavailableException("Operation timed out on reconfiguring " + vm, dstHostId);
+        } catch (final AgentUnavailableException e) {
+            throw e;
+        } finally {
+            if (!success) {
+                _capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId()); // release the new capacity
+                vm.setServiceOfferingId(oldServiceOffering.getId());
+                _capacityMgr.allocateVmCapacity(vm, false); // allocate the old capacity
+            }
+        }
+
+        return vm;
+
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VirtualMachineManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait,
+            VmOpLockStateRetry,
+            VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp};
+    }
+
+    public List<StoragePoolAllocator> getStoragePoolAllocators() {
+        return _storagePoolAllocators;
+    }
+
+    @Inject
+    public void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators) {
+        _storagePoolAllocators = storagePoolAllocators;
+    }
+
+    //
+    // PowerState report handling for out-of-band changes and handling of left-over transitional VM states
+    //
+
+    @MessageHandler(topic = Topics.VM_POWER_STATE)
+    protected void HandlePowerStateReport(final String subject, final String senderAddress, final Object args) {
+        assert args != null;
+        final Long vmId = (Long)args;
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vmId);
+        if (pendingWorkJobs.size() == 0 && !_haMgr.hasPendingHaWork(vmId)) {
+            // there is no pending operation job
+            final VMInstanceVO vm = _vmDao.findById(vmId);
+            if (vm != null) {
+                switch (vm.getPowerState()) {
+                case PowerOn:
+                    handlePowerOnReportWithNoPendingJobsOnVM(vm);
+                    break;
+
+                case PowerOff:
+                case PowerReportMissing:
+                    handlePowerOffReportWithNoPendingJobsOnVM(vm);
+                    break;
+
+                    // PowerUnknown shouldn't be reported, it is a derived
+                    // VM power state from host state (host un-reachable)
+                case PowerUnknown:
+                default:
+                    assert false;
+                    break;
+                }
+            } else {
+                s_logger.warn("VM " + vmId + " no longer exists when processing VM state report");
+            }
+        } else {
+            s_logger.info("There is pending job or HA tasks working on the VM. vm id: " + vmId + ", postpone power-change report by resetting power-change counters");
+
+            // reset VM power state tracking so that we won't lost signal when VM has
+            // been translated to
+            _vmDao.resetVmPowerStateTracking(vmId);
+        }
+    }
+
+    private void handlePowerOnReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
+        //
+        //    1) handle left-over transitional VM states
+        //    2) handle out of band VM live migration
+        //    3) handle out of sync stationary states, marking VM from Stopped to Running with
+        //       alert messages
+        //
+        switch (vm.getState()) {
+        case Starting:
+            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
+
+            try {
+                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
+            } catch (final NoTransitionException e) {
+                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
+            }
+
+            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
+
+            // we need to alert admin or user about this risky state transition
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
+                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName()
+                    + ") state is sync-ed (Starting -> Running) from out-of-context transition. VM network environment may need to be reset");
+            break;
+
+        case Running:
+            try {
+                if (vm.getHostId() != null && vm.getHostId().longValue() != vm.getPowerHostId().longValue()) {
+                    s_logger.info("Detected out of band VM migration from host " + vm.getHostId() + " to host " + vm.getPowerHostId());
+                }
+                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
+            } catch (final NoTransitionException e) {
+                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
+            }
+
+            break;
+
+        case Stopping:
+        case Stopped:
+            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
+
+            try {
+                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
+            } catch (final NoTransitionException e) {
+                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
+            }
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
+                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState()
+                    + " -> Running) from out-of-context transition. VM network environment may need to be reset");
+
+            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
+            break;
+
+        case Destroyed:
+        case Expunging:
+            s_logger.info("Receive power on report when VM is in destroyed or expunging state. vm: "
+                    + vm.getId() + ", state: " + vm.getState());
+            break;
+
+        case Migrating:
+            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-on report while there is no pending jobs on it");
+            try {
+                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOnReport, vm.getPowerHostId());
+            } catch (final NoTransitionException e) {
+                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
+            }
+            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Running state according to power-on report from hypervisor");
+            break;
+
+        case Error:
+        default:
+            s_logger.info("Receive power on report when VM is in error or unexpected state. vm: "
+                    + vm.getId() + ", state: " + vm.getState());
+            break;
+        }
+    }
+
+    private void handlePowerOffReportWithNoPendingJobsOnVM(final VMInstanceVO vm) {
+
+        //    1) handle left-over transitional VM states
+        //    2) handle out of sync stationary states, schedule force-stop to release resources
+        //
+        switch (vm.getState()) {
+        case Starting:
+        case Stopping:
+        case Running:
+        case Stopped:
+        case Migrating:
+            s_logger.info("VM " + vm.getInstanceName() + " is at " + vm.getState() + " and we received a power-off report while there is no pending jobs on it");
+            if(vm.isHaEnabled() && vm.getState() == State.Running && HaVmRestartHostUp.value() && vm.getHypervisorType() != HypervisorType.VMware && vm.getHypervisorType() != HypervisorType.Hyperv) {
+                s_logger.info("Detected out-of-band stop of a HA enabled VM " + vm.getInstanceName() + ", will schedule restart");
+                if(!_haMgr.hasPendingHaWork(vm.getId())) {
+                    _haMgr.scheduleRestart(vm, true);
+                } else {
+                    s_logger.info("VM " + vm.getInstanceName() + " already has an pending HA task working on it");
+                }
+                return;
+            }
+
+            final VirtualMachineGuru vmGuru = getVmGuru(vm);
+            final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+            if (!sendStop(vmGuru, profile, true, true)) {
+                // In case StopCommand fails, don't proceed further
+                return;
+            }
+
+            try {
+                stateTransitTo(vm, VirtualMachine.Event.FollowAgentPowerOffReport, null);
+            } catch (final NoTransitionException e) {
+                s_logger.warn("Unexpected VM state transition exception, race-condition?", e);
+            }
+
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
+                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") state is sync-ed (" + vm.getState()
+                    + " -> Stopped) from out-of-context transition.");
+
+            s_logger.info("VM " + vm.getInstanceName() + " is sync-ed to at Stopped state according to power-off report from hypervisor");
+
+            break;
+
+        case Destroyed:
+        case Expunging:
+            break;
+
+        case Error:
+        default:
+            break;
+        }
+    }
+
+    private void scanStalledVMInTransitionStateOnUpHost(final long hostId) {
+        //
+        // Check VM that is stuck in Starting, Stopping, Migrating states, we won't check
+        // VMs in expunging state (this need to be handled specially)
+        //
+        // checking condition
+        //    1) no pending VmWork job
+        //    2) on hostId host and host is UP
+        //
+        // When host is UP, soon or later we will get a report from the host about the VM,
+        // however, if VM is missing from the host report (it may happen in out of band changes
+        // or from designed behave of XS/KVM), the VM may not get a chance to run the state-sync logic
+        //
+        // Therefore, we will scan thoses VMs on UP host based on last update timestamp, if the host is UP
+        // and a VM stalls for status update, we will consider them to be powered off
+        // (which is relatively safe to do so)
+
+        final long stallThresholdInMs = VmJobStateReportInterval.value() + (VmJobStateReportInterval.value() >> 1);
+        final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - stallThresholdInMs);
+        final List<Long> mostlikelyStoppedVMs = listStalledVMInTransitionStateOnUpHost(hostId, cutTime);
+        for (final Long vmId : mostlikelyStoppedVMs) {
+            final VMInstanceVO vm = _vmDao.findById(vmId);
+            assert vm != null;
+            handlePowerOffReportWithNoPendingJobsOnVM(vm);
+        }
+
+        final List<Long> vmsWithRecentReport = listVMInTransitionStateWithRecentReportOnUpHost(hostId, cutTime);
+        for (final Long vmId : vmsWithRecentReport) {
+            final VMInstanceVO vm = _vmDao.findById(vmId);
+            assert vm != null;
+            if (vm.getPowerState() == PowerState.PowerOn) {
+                handlePowerOnReportWithNoPendingJobsOnVM(vm);
+            } else {
+                handlePowerOffReportWithNoPendingJobsOnVM(vm);
+            }
+        }
+    }
+
+    private void scanStalledVMInTransitionStateOnDisconnectedHosts() {
+        final Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - VmOpWaitInterval.value() * 1000);
+        final List<Long> stuckAndUncontrollableVMs = listStalledVMInTransitionStateOnDisconnectedHosts(cutTime);
+        for (final Long vmId : stuckAndUncontrollableVMs) {
+            final VMInstanceVO vm = _vmDao.findById(vmId);
+
+            // We now only alert administrator about this situation
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_SYNC, vm.getDataCenterId(), vm.getPodIdToDeployIn(),
+                    VM_SYNC_ALERT_SUBJECT, "VM " + vm.getHostName() + "(" + vm.getInstanceName() + ") is stuck in " + vm.getState()
+                    + " state and its host is unreachable for too long");
+        }
+    }
+
+    // VMs that in transitional state without recent power state report
+    private List<Long> listStalledVMInTransitionStateOnUpHost(final long hostId, final Date cutTime) {
+        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
+                "AND h.id = ? AND i.power_state_update_time < ? AND i.host_id = h.id " +
+                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
+                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
+                "AND i.removed IS NULL";
+
+        final List<Long> l = new ArrayList<Long>();
+        TransactionLegacy txn = null;
+        try {
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+
+            PreparedStatement pstmt = null;
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+
+                pstmt.setLong(1, hostId);
+                pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
+                pstmt.setInt(3, JobInfo.Status.IN_PROGRESS.ordinal());
+                final ResultSet rs = pstmt.executeQuery();
+                while (rs.next()) {
+                    l.add(rs.getLong(1));
+                }
+            } catch (final SQLException e) {
+            } catch (final Throwable e) {
+            }
+
+        } finally {
+            if (txn != null) {
+                txn.close();
+            }
+        }
+        return l;
+    }
+
+    // VMs that in transitional state and recently have power state update
+    private List<Long> listVMInTransitionStateWithRecentReportOnUpHost(final long hostId, final Date cutTime) {
+        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status = 'UP' " +
+                "AND h.id = ? AND i.power_state_update_time > ? AND i.host_id = h.id " +
+                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
+                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
+                "AND i.removed IS NULL";
+
+        final List<Long> l = new ArrayList<Long>();
+        TransactionLegacy txn = null;
+        try {
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            PreparedStatement pstmt = null;
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+
+                pstmt.setLong(1, hostId);
+                pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
+                pstmt.setInt(3, JobInfo.Status.IN_PROGRESS.ordinal());
+                final ResultSet rs = pstmt.executeQuery();
+                while (rs.next()) {
+                    l.add(rs.getLong(1));
+                }
+            } catch (final SQLException e) {
+            } catch (final Throwable e) {
+            }
+            return l;
+        } finally {
+            if (txn != null) {
+                txn.close();
+            }
+        }
+    }
+
+    private List<Long> listStalledVMInTransitionStateOnDisconnectedHosts(final Date cutTime) {
+        final String sql = "SELECT i.* FROM vm_instance as i, host as h WHERE h.status != 'UP' " +
+                "AND i.power_state_update_time < ? AND i.host_id = h.id " +
+                "AND (i.state ='Starting' OR i.state='Stopping' OR i.state='Migrating') " +
+                "AND i.id NOT IN (SELECT w.vm_instance_id FROM vm_work_job AS w JOIN async_job AS j ON w.id = j.id WHERE j.job_status = ?)" +
+                "AND i.removed IS NULL";
+
+        final List<Long> l = new ArrayList<Long>();
+        TransactionLegacy txn = null;
+        try {
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            PreparedStatement pstmt = null;
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+
+                pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime));
+                pstmt.setInt(2, JobInfo.Status.IN_PROGRESS.ordinal());
+                final ResultSet rs = pstmt.executeQuery();
+                while (rs.next()) {
+                    l.add(rs.getLong(1));
+                }
+            } catch (final SQLException e) {
+            } catch (final Throwable e) {
+            }
+            return l;
+        } finally {
+            if (txn != null) {
+                txn.close();
+            }
+        }
+    }
+
+    //
+    // VM operation based on new sync model
+    //
+
+    public class VmStateSyncOutcome extends OutcomeImpl<VirtualMachine> {
+        private long _vmId;
+
+        public VmStateSyncOutcome(final AsyncJob job, final PowerState desiredPowerState, final long vmId, final Long srcHostIdForMigration) {
+            super(VirtualMachine.class, job, VmJobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    final AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
+                    assert jobVo != null;
+                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                        return true;
+                    }
+                    return false;
+                }
+            }, Topics.VM_POWER_STATE, AsyncJob.Topics.JOB_STATE);
+            _vmId = vmId;
+        }
+
+        @Override
+        protected VirtualMachine retrieve() {
+            return _vmDao.findById(_vmId);
+        }
+    }
+
+    public class VmJobVirtualMachineOutcome extends OutcomeImpl<VirtualMachine> {
+        private long _vmId;
+
+        public VmJobVirtualMachineOutcome(final AsyncJob job, final long vmId) {
+            super(VirtualMachine.class, job, VmJobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    final AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
+                    assert jobVo != null;
+                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                        return true;
+                    }
+
+                    return false;
+                }
+            }, AsyncJob.Topics.JOB_STATE);
+            _vmId = vmId;
+        }
+
+        @Override
+        protected VirtualMachine retrieve() {
+            return _vmDao.findById(_vmId);
+        }
+    }
+
+    //
+    // TODO build a common pattern to reduce code duplication in following methods
+    // no time for this at current iteration
+    //
+    public Outcome<VirtualMachine> startVmThroughJobQueue(final String vmUuid,
+            final Map<VirtualMachineProfile.Param, Object> params,
+            final DeploymentPlan planToDeploy, final DeploymentPlanner planner) {
+
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        VmWorkJobVO workJob = null;
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(VirtualMachine.Type.Instance,
+                vm.getId(), VmWorkStart.class.getName());
+
+        if (pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkStart.class.getName());
+
+            workJob.setAccountId(callingAccount.getId());
+            workJob.setUserId(callingUser.getId());
+            workJob.setStep(VmWorkJobVO.Step.Starting);
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkStart workInfo = new VmWorkStart(callingUser.getId(), callingAccount.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER);
+            workInfo.setPlan(planToDeploy);
+            workInfo.setParams(params);
+            if (planner != null) {
+                workInfo.setDeploymentPlanner(planner.getName());
+            }
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob,
+                VirtualMachine.PowerState.PowerOn, vm.getId(), null);
+    }
+
+    public Outcome<VirtualMachine> stopVmThroughJobQueue(final String vmUuid, final boolean cleanup) {
+        final CallContext context = CallContext.current();
+        final Account account = context.getCallingAccount();
+        final User user = context.getCallingUser();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                vm.getType(), vm.getId(),
+                VmWorkStop.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkStop.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setStep(VmWorkJobVO.Step.Prepare);
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkStop workInfo = new VmWorkStop(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, cleanup);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob,
+                VirtualMachine.PowerState.PowerOff, vm.getId(), null);
+    }
+
+    public Outcome<VirtualMachine> rebootVmThroughJobQueue(final String vmUuid,
+            final Map<VirtualMachineProfile.Param, Object> params) {
+
+        final CallContext context = CallContext.current();
+        final Account account = context.getCallingAccount();
+        final User user = context.getCallingUser();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkReboot.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkReboot.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setStep(VmWorkJobVO.Step.Prepare);
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkReboot workInfo = new VmWorkReboot(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, params);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob,
+                vm.getId());
+    }
+
+    public Outcome<VirtualMachine> migrateVmThroughJobQueue(final String vmUuid, final long srcHostId, final DeployDestination dest) {
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        Map<Volume, StoragePool> volumeStorageMap = dest.getStorageForDisks();
+        if (volumeStorageMap != null) {
+            for (Volume vol : volumeStorageMap.keySet()) {
+                checkConcurrentJobsPerDatastoreThreshhold(volumeStorageMap.get(vol));
+            }
+        }
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrate.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrate.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkMigrate workInfo = new VmWorkMigrate(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob,
+                VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
+    }
+
+    public Outcome<VirtualMachine> migrateVmAwayThroughJobQueue(final String vmUuid, final long srcHostId) {
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateAway.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrateAway.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkMigrateAway workInfo = new VmWorkMigrateAway(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+        }
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob, VirtualMachine.PowerState.PowerOn, vm.getId(), vm.getPowerHostId());
+    }
+
+    public Outcome<VirtualMachine> migrateVmWithStorageThroughJobQueue(
+            final String vmUuid, final long srcHostId, final long destHostId,
+            final Map<Long, Long> volumeToPool) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateWithStorage.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrateWithStorage.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkMigrateWithStorage workInfo = new VmWorkMigrateWithStorage(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, destHostId, volumeToPool);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmStateSyncOutcome(workJob,
+                VirtualMachine.PowerState.PowerOn, vm.getId(), destHostId);
+    }
+
+    public Outcome<VirtualMachine> migrateVmForScaleThroughJobQueue(
+            final String vmUuid, final long srcHostId, final DeployDestination dest, final Long newSvcOfferingId) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkMigrateForScale.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkMigrateForScale.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkMigrateForScale workInfo = new VmWorkMigrateForScale(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest, newSvcOfferingId);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    private void checkConcurrentJobsPerDatastoreThreshhold(final StoragePool destPool) {
+        final Long threshold = VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value();
+        if (threshold != null && threshold > 0) {
+            long count = _jobMgr.countPendingJobs("\"storageid\":\"" + destPool.getUuid() + "\"", MigrateVMCmd.class.getName(), MigrateVolumeCmd.class.getName(), MigrateVolumeCmdByAdmin.class.getName());
+            if (count > threshold) {
+                throw new CloudRuntimeException("Number of concurrent migration jobs per datastore exceeded the threshold: " + threshold.toString() + ". Please try again after some time.");
+            }
+        }
+    }
+
+    public Outcome<VirtualMachine> migrateVmStorageThroughJobQueue(
+            final String vmUuid, final StoragePool destPool) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkStorageMigration.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkStorageMigration.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkStorageMigration workInfo = new VmWorkStorageMigration(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, destPool.getId());
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    public Outcome<VirtualMachine> addVmToNetworkThroughJobQueue(
+            final VirtualMachine vm, final Network network, final NicProfile requested) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkAddVmToNetwork.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
+            final VirtualMachine vm, final Nic nic) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkRemoveNicFromVm.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkRemoveNicFromVm.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkRemoveNicFromVm workInfo = new VmWorkRemoveNicFromVm(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, nic.getId());
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    public Outcome<VirtualMachine> removeVmFromNetworkThroughJobQueue(
+            final VirtualMachine vm, final Network network, final URI broadcastUri) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkRemoveVmFromNetwork.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkRemoveVmFromNetwork.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkRemoveVmFromNetwork workInfo = new VmWorkRemoveVmFromNetwork(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network, broadcastUri);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    public Outcome<VirtualMachine> reconfigureVmThroughJobQueue(
+            final String vmUuid, final ServiceOffering newServiceOffering, final boolean reconfiguringOnExistingHost) {
+
+        final CallContext context = CallContext.current();
+        final User user = context.getCallingUser();
+        final Account account = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
+
+        final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
+                VirtualMachine.Type.Instance, vm.getId(),
+                VmWorkReconfigure.class.getName());
+
+        VmWorkJobVO workJob = null;
+        if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
+            assert pendingWorkJobs.size() == 1;
+            workJob = pendingWorkJobs.get(0);
+        } else {
+
+            workJob = new VmWorkJobVO(context.getContextId());
+
+            workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+            workJob.setCmd(VmWorkReconfigure.class.getName());
+
+            workJob.setAccountId(account.getId());
+            workJob.setUserId(user.getId());
+            workJob.setVmType(VirtualMachine.Type.Instance);
+            workJob.setVmInstanceId(vm.getId());
+            workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+            // save work context info (there are some duplications)
+            final VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(),
+                    VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, newServiceOffering.getId(), reconfiguringOnExistingHost);
+            workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+            _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+        }
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVirtualMachineOutcome(workJob, vm.getId());
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateStart(final VmWorkStart work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+
+        try{
+            orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner()));
+        }
+        catch (CloudRuntimeException e){
+            e.printStackTrace();
+            s_logger.info("Caught CloudRuntimeException, returning job failed " + e);
+            CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM instance");
+            return new Pair<JobInfo.Status, String>(JobInfo.Status.FAILED, JobSerializerHelper.toObjectSerializedString(ex));
+        }
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateStop(final VmWorkStop work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+            throw new CloudRuntimeException("Unable to find VM id=" + work.getVmId());
+        }
+
+        orchestrateStop(vm.getUuid(), work.isCleanup());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateMigrate(final VmWorkMigrate work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+
+        orchestrateMigrate(vm.getUuid(), work.getSrcHostId(), work.getDeployDestination());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateMigrateAway(final VmWorkMigrateAway work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+
+        try {
+            orchestrateMigrateAway(vm.getUuid(), work.getSrcHostId(), null);
+        } catch (final InsufficientServerCapacityException e) {
+            s_logger.warn("Failed to deploy vm " + vm.getId() + " with original planner, sending HAPlanner");
+            orchestrateMigrateAway(vm.getUuid(), work.getSrcHostId(), _haMgr.getHAPlanner());
+        }
+
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateMigrateWithStorage(final VmWorkMigrateWithStorage work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        orchestrateMigrateWithStorage(vm.getUuid(),
+                work.getSrcHostId(),
+                work.getDestHostId(),
+                work.getVolumeToPool());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateMigrateForScale(final VmWorkMigrateForScale work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        orchestrateMigrateForScale(vm.getUuid(),
+                work.getSrcHostId(),
+                work.getDeployDestination(),
+                work.getNewServiceOfferringId());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateReboot(final VmWorkReboot work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        orchestrateReboot(vm.getUuid(), work.getParams());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateAddVmToNetwork(final VmWorkAddVmToNetwork work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+
+        final Network network = _networkDao.findById(work.getNetworkId());
+        final NicProfile nic = orchestrateAddVmToNetwork(vm, network,
+                work.getRequestedNicProfile());
+
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(nic));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateRemoveNicFromVm(final VmWorkRemoveNicFromVm work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        final NicVO nic = _entityMgr.findById(NicVO.class, work.getNicId());
+        final boolean result = orchestrateRemoveNicFromVm(vm, nic);
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED,
+                _jobMgr.marshallResultObject(result));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateRemoveVmFromNetwork(final VmWorkRemoveVmFromNetwork work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        final boolean result = orchestrateRemoveVmFromNetwork(vm,
+                work.getNetwork(), work.getBroadcastUri());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED,
+                _jobMgr.marshallResultObject(result));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateReconfigure(final VmWorkReconfigure work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+
+        final ServiceOffering newServiceOffering = _offeringDao.findById(vm.getId(), work.getNewServiceOfferingId());
+
+        reConfigureVm(vm.getUuid(), newServiceOffering,
+                work.isSameHost());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateStorageMigration(final VmWorkStorageMigration work) throws Exception {
+        final VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, work.getVmId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm " + work.getVmId());
+        }
+        assert vm != null;
+        final StoragePool pool = (PrimaryDataStoreInfo)dataStoreMgr.getPrimaryDataStore(work.getDestStoragePoolId());
+        orchestrateStorageMigration(vm.getUuid(), pool);
+
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
+    }
+
+    @Override
+    public Pair<JobInfo.Status, String> handleVmWorkJob(final VmWork work) throws Exception {
+        return _jobHandlerProxy.handleVmWorkJob(work);
+    }
+
+    private VmWorkJobVO createPlaceHolderWork(final long instanceId) {
+        final VmWorkJobVO workJob = new VmWorkJobVO("");
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
+        workJob.setCmd("");
+        workJob.setCmdInfo("");
+
+        workJob.setAccountId(0);
+        workJob.setUserId(0);
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(instanceId);
+        workJob.setInitMsid(ManagementServerNode.getManagementServerId());
+
+        _workJobDao.persist(workJob);
+
+        return workJob;
+    }
+}
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSync.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSync.java
diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
new file mode 100644
index 0000000..80a4225
--- /dev/null
+++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java
@@ -0,0 +1,183 @@
+// 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.vm;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import com.cloud.configuration.ManagementServiceConfiguration;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStateSync {
+    private static final Logger s_logger = Logger.getLogger(VirtualMachinePowerStateSyncImpl.class);
+
+    @Inject MessageBus _messageBus;
+    @Inject VMInstanceDao _instanceDao;
+    @Inject VirtualMachineManager _vmMgr;
+    @Inject ManagementServiceConfiguration mgmtServiceConf;
+
+    public VirtualMachinePowerStateSyncImpl() {
+    }
+
+    @Override
+    public void resetHostSyncState(long hostId) {
+        s_logger.info("Reset VM power state sync for host: " + hostId);
+        _instanceDao.resetHostPowerStateTracking(hostId);
+    }
+
+    @Override
+    public void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report) {
+            s_logger.debug("Process host VM state report. host: " + hostId);
+
+        Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
+        processReport(hostId, translatedInfo);
+    }
+
+    @Override
+    public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report) {
+        if (s_logger.isDebugEnabled())
+            s_logger.debug("Process host VM state report from ping process. host: " + hostId);
+
+        Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
+        processReport(hostId, translatedInfo);
+    }
+
+    private void processReport(long hostId, Map<Long, VirtualMachine.PowerState> translatedInfo) {
+
+        if (s_logger.isDebugEnabled())
+            s_logger.debug("Process VM state report. host: " + hostId + ", number of records in report: " + translatedInfo.size());
+
+        for (Map.Entry<Long, VirtualMachine.PowerState> entry : translatedInfo.entrySet()) {
+
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("VM state report. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
+
+            if (_instanceDao.updatePowerState(entry.getKey(), hostId, entry.getValue())) {
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
+
+                _messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, entry.getKey());
+            } else {
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("VM power state does not change, skip DB writing. vm id: " + entry.getKey());
+            }
+        }
+
+        // for all running/stopping VMs, we provide monitoring of missing report
+        List<VMInstanceVO> vmsThatAreMissingReport = _instanceDao.findByHostInStates(hostId, VirtualMachine.State.Running,
+                VirtualMachine.State.Stopping, VirtualMachine.State.Starting);
+        java.util.Iterator<VMInstanceVO> it = vmsThatAreMissingReport.iterator();
+        while (it.hasNext()) {
+            VMInstanceVO instance = it.next();
+            if (translatedInfo.get(instance.getId()) != null)
+                it.remove();
+        }
+
+        if (vmsThatAreMissingReport.size() > 0) {
+            Date currentTime = DateUtil.currentGMTTime();
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Run missing VM report. current time: " + currentTime.getTime());
+
+            // 2 times of sync-update interval for graceful period
+            long milliSecondsGracefullPeriod = mgmtServiceConf.getPingInterval() * 2000L;
+
+            for (VMInstanceVO instance : vmsThatAreMissingReport) {
+
+                // Make sure powerState is up to date for missing VMs
+                try {
+                    if (!_instanceDao.isPowerStateUpToDate(instance.getId())) {
+                        s_logger.warn("Detected missing VM but power state is outdated, wait for another process report run for VM id: " + instance.getId());
+                        _instanceDao.resetVmPowerStateTracking(instance.getId());
+                        continue;
+                    }
+                } catch (CloudRuntimeException e) {
+                    s_logger.warn("Checked for missing powerstate of a none existing vm", e);
+                    continue;
+                }
+
+                Date vmStateUpdateTime = instance.getPowerStateUpdateTime();
+                if (vmStateUpdateTime == null) {
+                    s_logger.warn("VM power state update time is null, falling back to update time for vm id: " + instance.getId());
+                    vmStateUpdateTime = instance.getUpdateTime();
+                    if (vmStateUpdateTime == null) {
+                        s_logger.warn("VM update time is null, falling back to creation time for vm id: " + instance.getId());
+                        vmStateUpdateTime = instance.getCreated();
+                    }
+                }
+
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("Detected missing VM. host: " + hostId + ", vm id: " + instance.getId() +
+                            ", power state: PowerReportMissing, last state update: " + vmStateUpdateTime.getTime());
+
+                long milliSecondsSinceLastStateUpdate = currentTime.getTime() - vmStateUpdateTime.getTime();
+
+                if (milliSecondsSinceLastStateUpdate > milliSecondsGracefullPeriod) {
+                    s_logger.debug("vm id: " + instance.getId() + " - time since last state update(" + milliSecondsSinceLastStateUpdate + "ms) has passed graceful period");
+
+                    if (_instanceDao.updatePowerState(instance.getId(), hostId, VirtualMachine.PowerState.PowerReportMissing)) {
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + instance.getId() + ", power state: PowerReportMissing ");
+
+                        _messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, instance.getId());
+                    } else {
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("VM power state does not change, skip DB writing. vm id: " + instance.getId());
+                    }
+                } else {
+                    s_logger.debug("vm id: " + instance.getId() + " - time since last state update(" + milliSecondsSinceLastStateUpdate + "ms) has not passed graceful period yet");
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled())
+            s_logger.debug("Done with process of VM state report. host: " + hostId);
+    }
+
+    @Override
+    public Map<Long, VirtualMachine.PowerState> convertVmStateReport(Map<String, HostVmStateReportEntry> states) {
+        final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<Long, VirtualMachine.PowerState>();
+        if (states == null) {
+            return map;
+        }
+
+        for (Map.Entry<String, HostVmStateReportEntry> entry : states.entrySet()) {
+            VMInstanceVO vm = findVM(entry.getKey());
+            if (vm != null) {
+                map.put(vm.getId(), entry.getValue().getState());
+            } else {
+                s_logger.info("Unable to find matched VM in CloudStack DB. name: " + entry.getKey());
+            }
+        }
+
+        return map;
+    }
+
+    private VMInstanceVO findVM(String vmName) {
+        return _instanceDao.findVMByInstanceName(vmName);
+    }
+}
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkAddVmToNetwork.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkAddVmToNetwork.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkAddVmToNetwork.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkAddVmToNetwork.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkJobDispatcher.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkJobDispatcher.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobWakeupDispatcher.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkJobWakeupDispatcher.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkJobWakeupDispatcher.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkJobWakeupDispatcher.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrate.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkMigrate.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateAway.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateAway.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkMigrateAway.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateAway.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateForScale.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateForScale.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkMigrateForScale.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateForScale.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateWithStorage.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrateWithStorage.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkReboot.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkReboot.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkReboot.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkReboot.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkReconfigure.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkReconfigure.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkReconfigure.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkRemoveNicFromVm.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkRemoveNicFromVm.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkRemoveNicFromVm.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkRemoveNicFromVm.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkRemoveVmFromNetwork.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkRemoveVmFromNetwork.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkRemoveVmFromNetwork.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkRemoveVmFromNetwork.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkStart.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkStart.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkStart.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkStart.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkStop.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkStop.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkStop.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkStop.java
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkStorageMigration.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkStorageMigration.java
similarity index 100%
rename from engine/orchestration/src/com/cloud/vm/VmWorkStorageMigration.java
rename to engine/orchestration/src/main/java/com/cloud/vm/VmWorkStorageMigration.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntityImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntityImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntityImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ClusterEntityImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManager.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/DataCenterResourceManagerImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/HostEntityImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntityImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/PodEntityImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/PodEntityImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/PodEntityImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntityImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntityImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntityImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/ZoneEntityImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/ClusterDetailsVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/ClusterDetailsVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/ClusterDetailsVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/ClusterDetailsVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/DcDetailVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/DcDetailVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/DcDetailVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/DcDetailVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineCluster.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineCluster.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineCluster.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineCluster.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineClusterVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineClusterVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineClusterVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineClusterVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenter.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenter.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenter.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenter.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenterVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenterVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenterVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineDataCenterVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHost.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHost.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHost.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHost.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostPodVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostPodVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostPodVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostPodVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostVO.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostVO.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostVO.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EngineHostVO.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EnginePod.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EnginePod.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/EnginePod.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/EnginePod.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/DcDetailsDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineClusterDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineDataCenterDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/EngineHostPodDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostDetailsDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDao.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/datacenter/entity/api/db/dao/HostTagsDaoImpl.java
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
new file mode 100644
index 0000000..2b2460e
--- /dev/null
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -0,0 +1,3960 @@
+// 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.engine.orchestration;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
+import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.ConfigKey.Scope;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DataCenterVnetVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Event;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationResponder;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.NetworkStateListener;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.VpcVirtualNetworkApplianceService;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.AccountGuestVlanMapVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkAccountDao;
+import com.cloud.network.dao.NetworkAccountVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDomainDao;
+import com.cloud.network.dao.NetworkDomainVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkServiceMapVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.RemoteAccessVpnVO;
+import com.cloud.network.element.AggregatedCommandExecutor;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.element.DnsServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.RedundantResource;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.StaticNatRuleImpl;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.UuidUtils;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicExtraDhcpOptionVO;
+import com.cloud.vm.NicIpAlias;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicExtraDhcpOptionDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.common.base.Strings;
+
+/**
+ * NetworkManagerImpl implements NetworkManager.
+ */
+public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestrationService, Listener, Configurable {
+    static final Logger s_logger = Logger.getLogger(NetworkOrchestrator.class);
+
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    NetworkDao _networksDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    RulesManager _rulesMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    RemoteAccessVpnService _vpnMgr;
+    @Inject
+    PodVlanMapDao _podVlanMapDao;
+    @Inject
+    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
+    @Inject
+    AccountGuestVlanMapDao _accountGuestVlanMapDao;
+    @Inject
+    DataCenterVnetDao _datacenterVnetDao;
+    @Inject
+    NetworkAccountDao _networkAccountDao;
+    @Inject
+    protected NicIpAliasDao _nicIpAliasDao;
+    @Inject
+    protected NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
+    @Inject
+    protected IPAddressDao _publicIpAddressDao;
+    @Inject
+    protected IpAddressManager _ipAddrMgr;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    VMNetworkMapDao _vmNetworkMapDao;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    RemoteAccessVpnDao _remoteAccessVpnDao;
+    @Inject
+    VpcVirtualNetworkApplianceService _routerService;
+
+    List<NetworkGuru> networkGurus;
+
+    @Override
+    public List<NetworkGuru> getNetworkGurus() {
+        return networkGurus;
+    }
+
+    public void setNetworkGurus(final List<NetworkGuru> networkGurus) {
+        this.networkGurus = networkGurus;
+    }
+
+    List<NetworkElement> networkElements;
+
+    public List<NetworkElement> getNetworkElements() {
+        return networkElements;
+    }
+
+    public void setNetworkElements(final List<NetworkElement> networkElements) {
+        this.networkElements = networkElements;
+    }
+
+    @Inject
+    NetworkDomainDao _networkDomainDao;
+
+    List<IpDeployer> ipDeployers;
+
+    public List<IpDeployer> getIpDeployers() {
+        return ipDeployers;
+    }
+
+    public void setIpDeployers(final List<IpDeployer> ipDeployers) {
+        this.ipDeployers = ipDeployers;
+    }
+
+    List<DhcpServiceProvider> _dhcpProviders;
+
+    public List<DhcpServiceProvider> getDhcpProviders() {
+        return _dhcpProviders;
+    }
+
+    public void setDhcpProviders(final List<DhcpServiceProvider> dhcpProviders) {
+        _dhcpProviders = dhcpProviders;
+    }
+
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    FirewallManager _firewallMgr;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _pNSPDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingRulesDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    PrivateIpDao _privateIpDao;
+    @Inject
+    NetworkACLManager _networkACLMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+
+    protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
+    ScheduledExecutorService _executor;
+
+    SearchBuilder<IPAddressVO> AssignIpAddressSearch;
+    SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
+
+    HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
+
+    @Override
+    @DB
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        // populate providers
+        final Map<Network.Service, Set<Network.Provider>> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
+
+        defaultProviders.add(Network.Provider.VirtualRouter);
+        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+
+        final Map<Network.Service, Set<Network.Provider>> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
+        defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+        final Map<Network.Service, Set<Network.Provider>> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        final Set<Provider> sgProviders = new HashSet<Provider>();
+        sgProviders.add(Provider.SecurityGroupProvider);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders);
+
+        final Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultProviders.clear();
+        defaultProviders.add(Network.Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+        final Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultProviders.clear();
+        defaultProviders.add(Network.Provider.VPCVirtualRouter);
+        defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
+        defaultVPCOffProviders.put(Service.Dns, defaultProviders);
+        defaultVPCOffProviders.put(Service.UserData, defaultProviders);
+        defaultVPCOffProviders.put(Service.NetworkACL, defaultProviders);
+        defaultVPCOffProviders.put(Service.Gateway, defaultProviders);
+        defaultVPCOffProviders.put(Service.Lb, defaultProviders);
+        defaultVPCOffProviders.put(Service.SourceNat, defaultProviders);
+        defaultVPCOffProviders.put(Service.StaticNat, defaultProviders);
+        defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders);
+        defaultVPCOffProviders.put(Service.Vpn, defaultProviders);
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                NetworkOfferingVO offering = null;
+                //#1 - quick cloud network offering
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
+                            Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true, Network.GuestType.Shared, false, null, true, null, true,
+                            false, null, false, null, true, false);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#2 - SG enabled network offering
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
+                            TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
+                            null, true, false, null, false, null, true, false);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#3 - shared network offering with no SG service
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true,
+                            Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false,
+                            null, true, false);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#4 - default isolated offering with Source nat service
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
+                            "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null,
+                            defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null,
+                            true, false);
+
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#5 - default vpc offering with LB service
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
+                            "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null,
+                            defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#6 - default vpc offering with no LB service
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) {
+                    //remove LB service
+                    defaultVPCOffProviders.remove(Service.Lb);
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
+                            "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional,
+                            null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#7 - isolated offering with source nat disabled
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service",
+                            TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null,
+                            true, null, true, false, null, false, null, true, false);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                //#8 - network offering with internal lb service
+                final Map<Network.Service, Set<Network.Provider>> internalLbOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+                final Set<Network.Provider> defaultVpcProvider = new HashSet<Network.Provider>();
+                defaultVpcProvider.add(Network.Provider.VPCVirtualRouter);
+
+                final Set<Network.Provider> defaultInternalLbProvider = new HashSet<Network.Provider>();
+                defaultInternalLbProvider.add(Network.Provider.InternalLbVm);
+
+                internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider);
+                internalLbOffProviders.put(Service.Dns, defaultVpcProvider);
+                internalLbOffProviders.put(Service.UserData, defaultVpcProvider);
+                internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider);
+                internalLbOffProviders.put(Service.Gateway, defaultVpcProvider);
+                internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider);
+                internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider);
+
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
+                            "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders,
+                            true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    offering.setInternalLb(true);
+                    offering.setPublicLb(false);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                final Map<Network.Service, Set<Network.Provider>> netscalerServiceProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+                final Set<Network.Provider> vrProvider = new HashSet<Network.Provider>();
+                vrProvider.add(Provider.VirtualRouter);
+                final Set<Network.Provider> sgProvider = new HashSet<Network.Provider>();
+                sgProvider.add(Provider.SecurityGroupProvider);
+                final Set<Network.Provider> nsProvider = new HashSet<Network.Provider>();
+                nsProvider.add(Provider.Netscaler);
+                netscalerServiceProviders.put(Service.Dhcp, vrProvider);
+                netscalerServiceProviders.put(Service.Dns, vrProvider);
+                netscalerServiceProviders.put(Service.UserData, vrProvider);
+                netscalerServiceProviders.put(Service.SecurityGroup, sgProvider);
+                netscalerServiceProviders.put(Service.StaticNat, nsProvider);
+                netscalerServiceProviders.put(Service.Lb, nsProvider);
+
+                final Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
+                final Map<Capability, String> elb = new HashMap<Capability, String>();
+                elb.put(Capability.ElasticLb, "true");
+                final Map<Capability, String> eip = new HashMap<Capability, String>();
+                eip.put(Capability.ElasticIp, "true");
+                serviceCapabilityMap.put(Service.Lb, elb);
+                serviceCapabilityMap.put(Service.StaticNat, eip);
+
+                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
+                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
+                            "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null,
+                            netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false);
+                    offering.setState(NetworkOffering.State.Enabled);
+                    offering.setDedicatedLB(false);
+                    _networkOfferingDao.update(offering.getId(), offering);
+                }
+
+                _networkOfferingDao.persistDefaultL2NetworkOfferings();
+            }
+        });
+
+        AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
+        AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
+        AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
+        AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
+        final SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
+        vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
+        vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
+        AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
+        AssignIpAddressSearch.done();
+
+        AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder();
+        AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ);
+        AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL);
+        AssignIpAddressFromPodVlanSearch.and("vlanId", AssignIpAddressFromPodVlanSearch.entity().getVlanId(), Op.IN);
+
+        final SearchBuilder<VlanVO> podVlanSearch = _vlanDao.createSearchBuilder();
+        podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ);
+        podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ);
+        final SearchBuilder<PodVlanMapVO> podVlanMapSB = _podVlanMapDao.createSearchBuilder();
+        podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ);
+        AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(),
+                JoinType.INNER);
+        AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
+
+        AssignIpAddressFromPodVlanSearch.done();
+
+        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger"));
+
+        _agentMgr.registerForHostEvents(this, true, false, true);
+
+        Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao));
+
+        s_logger.info("Network Manager is configured.");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        final int netGcInterval = NumbersUtil.parseInt(_configDao.getValue(NetworkGcInterval.key()), 60);
+        s_logger.info("Network Manager will run the NetworkGarbageCollector every '" + netGcInterval + "' seconds.");
+
+        _executor.scheduleWithFixedDelay(new NetworkGarbageCollector(), netGcInterval, netGcInterval, TimeUnit.SECONDS);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    protected NetworkOrchestrator() {
+        setStateMachine();
+    }
+
+    @Override
+    public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
+            throws ConcurrentOperationException {
+        return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null, null, true);
+    }
+
+    @Override
+    @DB
+    public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final Network predefined, final DeploymentPlan plan, final String name,
+            final String displayText, final boolean errorIfAlreadySetup, final Long domainId, final ACLType aclType, final Boolean subdomainAccess, final Long vpcId,
+            final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException {
+
+        final Account locked = _accountDao.acquireInLockTable(owner.getId());
+        if (locked == null) {
+            throw new ConcurrentOperationException("Unable to acquire lock on " + owner);
+        }
+
+        try {
+            if (predefined == null
+                    || offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && !(predefined
+                            .getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch || predefined
+                            .getBroadcastDomainType() == BroadcastDomainType.Vxlan)) {
+                final List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
+                if (configs.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
+                    }
+
+                    if (errorIfAlreadySetup) {
+                        final InvalidParameterValueException ex = new InvalidParameterValueException(
+                                "Found existing network configuration (with specified id) for offering (with specified id)");
+                        ex.addProxyObject(offering.getUuid(), "offeringId");
+                        ex.addProxyObject(configs.get(0).getUuid(), "networkConfigId");
+                        throw ex;
+                    } else {
+                        return configs;
+                    }
+                }
+            }
+
+            final List<NetworkVO> networks = new ArrayList<NetworkVO>();
+
+            long related = -1;
+
+            for (final NetworkGuru guru : networkGurus) {
+                final Network network = guru.design(offering, plan, predefined, owner);
+                if (network == null) {
+                    continue;
+                }
+
+                if (network.getId() != -1) {
+                    if (network instanceof NetworkVO) {
+                        networks.add((NetworkVO)network);
+                    } else {
+                        networks.add(_networksDao.findById(network.getId()));
+                    }
+                    continue;
+                }
+
+                final long id = _networksDao.getNextInSequence(Long.class, "id");
+                if (related == -1) {
+                    related = id;
+                }
+
+                final long relatedFile = related;
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        final NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, predefined
+                                .getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.isSpecifyIpRanges(),
+                                vpcId, offering.isRedundantRouter(), predefined.getExternalId());
+                        vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
+                        vo.setStrechedL2Network(offering.isSupportingStrechedL2());
+                        final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
+                                finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()));
+                        networks.add(networkPersisted);
+
+                        if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
+                            final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
+                            functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
+                        }
+
+                        if (domainId != null && aclType == ACLType.Domain) {
+                            _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
+                        }
+                    }
+                });
+            }
+
+            if (networks.size() < 1) {
+                // see networkOfferingVO.java
+                final CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering with specified id to network profile");
+                ex.addProxyObject(offering.getUuid(), "offeringId");
+                throw ex;
+            }
+
+            return networks;
+        } finally {
+            s_logger.debug("Releasing lock for " + locked);
+            _accountDao.releaseFromLockTable(locked.getId());
+        }
+    }
+
+    @Override
+    @DB
+    public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
+    ConcurrentOperationException {
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
+                int deviceId = 0;
+                int size = 0;
+                for (final Network ntwk : networks.keySet()) {
+                    final List<? extends NicProfile> profiles = networks.get(ntwk);
+                    if (profiles != null && !profiles.isEmpty()) {
+                        size = size + profiles.size();
+                    } else {
+                        size = size + 1;
+                    }
+                }
+
+                final boolean[] deviceIds = new boolean[size];
+                Arrays.fill(deviceIds, false);
+
+                final List<NicProfile> nics = new ArrayList<NicProfile>(size);
+                NicProfile defaultNic = null;
+
+                for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
+                    final Network config = network.getKey();
+                    List<? extends NicProfile> requestedProfiles = network.getValue();
+                    if (requestedProfiles == null) {
+                        requestedProfiles = new ArrayList<NicProfile>();
+                    }
+                    if (requestedProfiles.isEmpty()) {
+                        requestedProfiles.add(null);
+                    }
+
+                    for (final NicProfile requested : requestedProfiles) {
+                        Boolean isDefaultNic = false;
+                        if (vm != null && requested != null && requested.isDefaultNic()) {
+                            isDefaultNic = true;
+                        }
+
+                        while (deviceIds[deviceId] && deviceId < deviceIds.length) {
+                            deviceId++;
+                        }
+
+                        final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, config, isDefaultNic, deviceId, vm);
+                        NicProfile vmNic = null;
+                        if (vmNicPair != null) {
+                            vmNic = vmNicPair.first();
+                            if (vmNic == null) {
+                                continue;
+                            }
+                            deviceId = vmNicPair.second();
+                        }
+
+                        final int devId = vmNic.getDeviceId();
+                        if (devId >= deviceIds.length) {
+                            throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
+                        }
+                        if (deviceIds[devId]) {
+                            throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
+                        }
+
+                        deviceIds[devId] = true;
+
+                        if (vmNic.isDefaultNic()) {
+                            if (defaultNic != null) {
+                                throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
+                            }
+                            defaultNic = vmNic;
+                        }
+
+                        nics.add(vmNic);
+                        vm.addNic(vmNic);
+                        saveExtraDhcpOptions(config.getUuid(), vmNic.getId(), extraDhcpOptions);
+                    }
+                }
+                if (nics.size() != size) {
+                    s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
+                    throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
+                }
+
+                if (nics.size() == 1) {
+                    nics.get(0).setDefaultNic(true);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void saveExtraDhcpOptions(final String networkUuid, final Long nicId, final Map<String, Map<Integer, String>> extraDhcpOptionMap) {
+
+        if(extraDhcpOptionMap != null) {
+            Map<Integer, String> extraDhcpOption = extraDhcpOptionMap.get(networkUuid);
+            if(extraDhcpOption != null) {
+                List<NicExtraDhcpOptionVO> nicExtraDhcpOptionList = new LinkedList<>();
+
+                for (Integer code : extraDhcpOption.keySet()) {
+                    Dhcp.DhcpOptionCode.valueOfInt(code); //check if code is supported or not.
+                    NicExtraDhcpOptionVO nicExtraDhcpOptionVO = new NicExtraDhcpOptionVO(nicId, code, extraDhcpOption.get(code));
+                    nicExtraDhcpOptionList.add(nicExtraDhcpOptionVO);
+                }
+                _nicExtraDhcpOptionDao.saveExtraDhcpOptions(nicExtraDhcpOptionList);
+            }
+        }
+    }
+
+    @DB
+    @Override
+    public Pair<NicProfile, Integer> allocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        final NetworkVO ntwkVO = _networksDao.findById(network.getId());
+        s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network + " with requested profile " + requested);
+        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, ntwkVO.getGuruName());
+
+        if (requested != null && requested.getMode() == null) {
+            requested.setMode(network.getMode());
+        }
+        final NicProfile profile = guru.allocate(network, requested, vm);
+        if (profile == null) {
+            return null;
+        }
+
+        if (isDefaultNic != null) {
+            profile.setDefaultNic(isDefaultNic);
+        }
+
+        if (requested != null && requested.getMode() == null) {
+            profile.setMode(requested.getMode());
+        } else {
+            profile.setMode(network.getMode());
+        }
+
+        NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType());
+
+        DataCenterVO dcVo = _dcDao.findById(network.getDataCenterId());
+        if (dcVo.getNetworkType() == NetworkType.Basic) {
+            configureNicProfileBasedOnRequestedIp(requested, profile, network);
+        }
+
+        deviceId = applyProfileToNic(vo, profile, deviceId);
+
+        vo = _nicDao.persist(vo);
+
+        final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+        final NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
+                _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+
+        return new Pair<NicProfile, Integer>(vmNic, Integer.valueOf(deviceId));
+    }
+
+    /**
+     * If the requested IPv4 address from the NicProfile was configured then it configures the IPv4 address, Netmask and Gateway to deploy the VM with the requested IP.
+     */
+    protected void configureNicProfileBasedOnRequestedIp(NicProfile requestedNicProfile, NicProfile nicProfile, Network network) {
+        if (requestedNicProfile == null) {
+            return;
+        }
+        String requestedIpv4Address = requestedNicProfile.getRequestedIPv4();
+        if (requestedIpv4Address == null) {
+            return;
+        }
+        if (!NetUtils.isValidIp4(requestedIpv4Address)) {
+            throw new InvalidParameterValueException(String.format("The requested [IPv4 address='%s'] is not a valid IP address", requestedIpv4Address));
+        }
+
+        VlanVO vlanVo = _vlanDao.findByNetworkIdAndIpv4(network.getId(), requestedIpv4Address);
+        if (vlanVo == null) {
+            throw new InvalidParameterValueException(String.format("Trying to configure a Nic with the requested [IPv4='%s'] but cannot find a Vlan for the [network id='%s']",
+                    requestedIpv4Address, network.getId()));
+        }
+
+        String ipv4Gateway = vlanVo.getVlanGateway();
+        String ipv4Netmask = vlanVo.getVlanNetmask();
+
+        if (!NetUtils.isValidIp4(ipv4Gateway)) {
+            throw new InvalidParameterValueException(String.format("The [IPv4Gateway='%s'] from [VlanId='%s'] is not valid", ipv4Gateway, vlanVo.getId()));
+        }
+        if (!NetUtils.isValidIp4Netmask(ipv4Netmask)) {
+            throw new InvalidParameterValueException(String.format("The [IPv4Netmask='%s'] from [VlanId='%s'] is not valid", ipv4Netmask, vlanVo.getId()));
+        }
+
+        acquireLockAndCheckIfIpv4IsFree(network, requestedIpv4Address);
+
+        nicProfile.setIPv4Address(requestedIpv4Address);
+        nicProfile.setIPv4Gateway(ipv4Gateway);
+        nicProfile.setIPv4Netmask(ipv4Netmask);
+
+        if (nicProfile.getMacAddress() == null) {
+            try {
+                String macAddress = _networkModel.getNextAvailableMacAddressInNetwork(network.getId());
+                nicProfile.setMacAddress(macAddress);
+            } catch (InsufficientAddressCapacityException e) {
+                throw new CloudRuntimeException(String.format("Cannot get next available mac address in [network id='%s']", network.getId()), e);
+            }
+        }
+    }
+
+    /**
+     *  Acquires lock in "user_ip_address" and checks if the requested IPv4 address is Free.
+     */
+    protected void acquireLockAndCheckIfIpv4IsFree(Network network, String requestedIpv4Address) {
+        IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), requestedIpv4Address);
+        if (ipVO == null) {
+            throw new InvalidParameterValueException(
+                    String.format("Cannot find IPAddressVO for guest [IPv4 address='%s'] and [network id='%s']", requestedIpv4Address, network.getId()));
+        }
+        try {
+            IPAddressVO lockedIpVO = _ipAddressDao.acquireInLockTable(ipVO.getId());
+            validateLockedRequestedIp(ipVO, lockedIpVO);
+            lockedIpVO.setState(IPAddressVO.State.Allocated);
+            _ipAddressDao.update(lockedIpVO.getId(), lockedIpVO);
+        } finally {
+            _ipAddressDao.releaseFromLockTable(ipVO.getId());
+        }
+    }
+
+    /**
+     * Validates the locked IP, throwing an exeption if the locked IP is null or the locked IP is not in 'Free' state.
+     */
+    protected void validateLockedRequestedIp(IPAddressVO ipVO, IPAddressVO lockedIpVO) {
+        if (lockedIpVO == null) {
+            throw new InvalidParameterValueException(String.format("Cannot acquire guest [IPv4 address='%s'] as it was removed while acquiring lock", ipVO.getAddress()));
+        }
+        if (lockedIpVO.getState() != IPAddressVO.State.Free) {
+            throw new InvalidParameterValueException(
+                    String.format("Cannot acquire guest [IPv4 address='%s']; The Ip address is in [state='%s']", ipVO.getAddress(), lockedIpVO.getState().toString()));
+        }
+    }
+
+    protected Integer applyProfileToNic(final NicVO vo, final NicProfile profile, Integer deviceId) {
+        if (profile.getDeviceId() != null) {
+            vo.setDeviceId(profile.getDeviceId());
+        } else if (deviceId != null) {
+            vo.setDeviceId(deviceId++);
+        }
+
+        if (profile.getReservationStrategy() != null) {
+            vo.setReservationStrategy(profile.getReservationStrategy());
+        }
+
+        vo.setDefaultNic(profile.isDefaultNic());
+
+        vo.setIPv4Address(profile.getIPv4Address());
+        vo.setAddressFormat(profile.getFormat());
+
+        if (profile.getMacAddress() != null) {
+            vo.setMacAddress(profile.getMacAddress());
+        }
+
+        vo.setMode(profile.getMode());
+        vo.setIPv4Netmask(profile.getIPv4Netmask());
+        vo.setIPv4Gateway(profile.getIPv4Gateway());
+
+        if (profile.getBroadCastUri() != null) {
+            vo.setBroadcastUri(profile.getBroadCastUri());
+        }
+
+        if (profile.getIsolationUri() != null) {
+            vo.setIsolationUri(profile.getIsolationUri());
+        }
+
+        vo.setState(Nic.State.Allocated);
+
+        vo.setIPv6Address(profile.getIPv6Address());
+        vo.setIPv6Gateway(profile.getIPv6Gateway());
+        vo.setIPv6Cidr(profile.getIPv6Cidr());
+
+        return deviceId;
+    }
+
+    protected void applyProfileToNicForRelease(final NicVO vo, final NicProfile profile) {
+        vo.setIPv4Gateway(profile.getIPv4Gateway());
+        vo.setAddressFormat(profile.getFormat());
+        vo.setIPv4Address(profile.getIPv4Address());
+        vo.setIPv6Address(profile.getIPv6Address());
+        vo.setMacAddress(profile.getMacAddress());
+        if (profile.getReservationStrategy() != null) {
+            vo.setReservationStrategy(profile.getReservationStrategy());
+        }
+        vo.setBroadcastUri(profile.getBroadCastUri());
+        vo.setIsolationUri(profile.getIsolationUri());
+        vo.setIPv4Netmask(profile.getIPv4Netmask());
+    }
+
+    protected void applyProfileToNetwork(final NetworkVO network, final NetworkProfile profile) {
+        network.setBroadcastUri(profile.getBroadcastUri());
+        network.setDns1(profile.getDns1());
+        network.setDns2(profile.getDns2());
+        network.setPhysicalNetworkId(profile.getPhysicalNetworkId());
+    }
+
+    protected NicTO toNicTO(final NicVO nic, final NicProfile profile, final NetworkVO config) {
+        final NicTO to = new NicTO();
+        to.setDeviceId(nic.getDeviceId());
+        to.setBroadcastType(config.getBroadcastDomainType());
+        to.setType(config.getTrafficType());
+        to.setIp(nic.getIPv4Address());
+        to.setNetmask(nic.getIPv4Netmask());
+        to.setMac(nic.getMacAddress());
+        to.setDns1(profile.getIPv4Dns1());
+        to.setDns2(profile.getIPv4Dns2());
+        if (nic.getIPv4Gateway() != null) {
+            to.setGateway(nic.getIPv4Gateway());
+        } else {
+            to.setGateway(config.getGateway());
+        }
+        if (nic.getVmType() != VirtualMachine.Type.User) {
+            to.setPxeDisable(true);
+        }
+        to.setDefaultNic(nic.isDefaultNic());
+        to.setBroadcastUri(nic.getBroadcastUri());
+        to.setIsolationuri(nic.getIsolationUri());
+        if (profile != null) {
+            to.setDns1(profile.getIPv4Dns1());
+            to.setDns2(profile.getIPv4Dns2());
+        }
+
+        final Integer networkRate = _networkModel.getNetworkRate(config.getId(), null);
+        to.setNetworkRateMbps(networkRate);
+
+        to.setUuid(config.getUuid());
+
+        return to;
+    }
+
+    boolean isNetworkImplemented(final NetworkVO network) {
+        final Network.State state = network.getState();
+        if (state == Network.State.Implemented) {
+            return true;
+        } else if (state == Network.State.Setup) {
+            final DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
+            if (!isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) || zone.getNetworkType() == NetworkType.Basic) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context, final boolean isRouter) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        Pair<NetworkGuru, NetworkVO> implemented = null;
+        if (!isRouter) {
+            implemented = implementNetwork(networkId, dest, context);
+        } else {
+            // At the time of implementing network (using implementNetwork() method), if the VR needs to be deployed then
+            // it follows the same path of regular VM deployment. This leads to a nested call to implementNetwork() while
+            // preparing VR nics. This flow creates issues in dealing with network state transitions. The original call
+            // puts network in "Implementing" state and then the nested call again tries to put it into same state resulting
+            // in issues. In order to avoid it, implementNetwork() call for VR is replaced with below code.
+            final NetworkVO network = _networksDao.findById(networkId);
+            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            implemented = new Pair<NetworkGuru, NetworkVO>(guru, network);
+        }
+        return implemented;
+    }
+
+    @Override
+    @DB
+    public Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException, InsufficientCapacityException {
+        final Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
+
+        NetworkVO network = _networksDao.findById(networkId);
+        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+        if (isNetworkImplemented(network)) {
+            s_logger.debug("Network id=" + networkId + " is already implemented");
+            implemented.set(guru, network);
+            return implemented;
+        }
+
+        // Acquire lock only when network needs to be implemented
+        network = _networksDao.acquireInLockTable(networkId, NetworkLockTimeout.value());
+        if (network == null) {
+            // see NetworkVO.java
+            final ConcurrentOperationException ex = new ConcurrentOperationException("Unable to acquire network configuration");
+            ex.addProxyObject(_entityMgr.findById(Network.class, networkId).getUuid());
+            throw ex;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Lock is acquired for network id " + networkId + " as a part of network implement");
+        }
+
+        try {
+            if (isNetworkImplemented(network)) {
+                s_logger.debug("Network id=" + networkId + " is already implemented");
+                implemented.set(guru, network);
+                return implemented;
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Asking " + guru.getName() + " to implement " + network);
+            }
+
+            final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+
+            network.setReservationId(context.getReservationId());
+            if (isSharedNetworkWithServices(network)) {
+                network.setState(Network.State.Implementing);
+            } else {
+                stateTransitTo(network, Event.ImplementNetwork);
+            }
+
+            final Network result = guru.implement(network, offering, dest, context);
+            network.setCidr(result.getCidr());
+            network.setBroadcastUri(result.getBroadcastUri());
+            network.setGateway(result.getGateway());
+            network.setMode(result.getMode());
+            network.setPhysicalNetworkId(result.getPhysicalNetworkId());
+            _networksDao.update(networkId, network);
+
+            // implement network elements and re-apply all the network rules
+            implementNetworkElementsAndResources(dest, context, network, offering);
+
+            if (isSharedNetworkWithServices(network)) {
+                network.setState(Network.State.Implemented);
+            } else {
+                stateTransitTo(network, Event.OperationSucceeded);
+            }
+
+            network.setRestartRequired(false);
+            _networksDao.update(network.getId(), network);
+            implemented.set(guru, network);
+            return implemented;
+        } catch (final NoTransitionException e) {
+            s_logger.error(e.getMessage());
+            return null;
+        } catch (final CloudRuntimeException e) {
+            s_logger.error("Caught exception: " + e.getMessage());
+            return null;
+        } finally {
+            if (implemented.first() == null) {
+                s_logger.debug("Cleaning up because we're unable to implement the network " + network);
+                try {
+                    if (isSharedNetworkWithServices(network)) {
+                        network.setState(Network.State.Shutdown);
+                        _networksDao.update(networkId, network);
+                    } else {
+                        stateTransitTo(network, Event.OperationFailed);
+                    }
+                } catch (final NoTransitionException e) {
+                    s_logger.error(e.getMessage());
+                }
+
+                try {
+                    shutdownNetwork(networkId, context, false);
+                } catch (final Exception e) {
+                    // Don't throw this exception as it would hide the original thrown exception, just log
+                    s_logger.error("Exception caught while shutting down a network as part of a failed implementation", e);
+                }
+            }
+
+            _networksDao.releaseFromLockTable(networkId);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Lock is released for network id " + networkId + " as a part of network implement");
+            }
+        }
+    }
+
+    @Override
+    public void implementNetworkElementsAndResources(final DeployDestination dest, final ReservationContext context, final Network network, final NetworkOffering offering)
+            throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException {
+
+        // Associate a source NAT IP (if one isn't already associated with the network) if this is a
+        //     1) 'Isolated' or 'Shared' guest virtual network in the advance zone
+        //     2) network has sourceNat service
+        //     3) network offering does not support a shared source NAT rule
+
+        final boolean sharedSourceNat = offering.isSharedSourceNat();
+        final DataCenter zone = _dcDao.findById(network.getDataCenterId());
+
+        if (!sharedSourceNat && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
+                && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
+
+            List<IPAddressVO> ips = null;
+            final Account owner = _entityMgr.findById(Account.class, network.getAccountId());
+            if (network.getVpcId() != null) {
+                ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
+                if (ips.isEmpty()) {
+                    final Vpc vpc = _vpcMgr.getActiveVpc(network.getVpcId());
+                    s_logger.debug("Creating a source nat ip for vpc " + vpc);
+                    _vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
+                }
+            } else {
+                ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
+                if (ips.isEmpty()) {
+                    s_logger.debug("Creating a source nat ip for network " + network);
+                    _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
+                }
+            }
+        }
+        // get providers to implement
+        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+        implementNetworkElements(dest, context, network, offering, providersToImplement);
+
+        //Reset the extra DHCP option that may have been cleared per nic.
+        List<NicVO> nicVOs = _nicDao.listByNetworkId(network.getId());
+        for(NicVO nicVO : nicVOs) {
+            if(nicVO.getState() == Nic.State.Reserved) {
+                configureExtraDhcpOptions(network, nicVO.getId());
+            }
+        }
+
+        for (final NetworkElement element : networkElements) {
+            if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
+                ((AggregatedCommandExecutor)element).prepareAggregatedExecution(network, dest);
+            }
+        }
+
+        try {
+            // reapply all the firewall/staticNat/lb rules
+            s_logger.debug("Reprogramming network " + network + " as a part of network implement");
+            if (!reprogramNetworkRules(network.getId(), CallContext.current().getCallingAccount(), network)) {
+                s_logger.warn("Failed to re-program the network as a part of network " + network + " implement");
+                // see DataCenterVO.java
+                final ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
+                        network.getDataCenterId());
+                ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
+                throw ex;
+            }
+            for (final NetworkElement element : networkElements) {
+                if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
+                    if (!((AggregatedCommandExecutor)element).completeAggregatedExecution(network, dest)) {
+                        s_logger.warn("Failed to re-program the network as a part of network " + network + " implement due to aggregated commands execution failure!");
+                        // see DataCenterVO.java
+                        final ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
+                                network.getDataCenterId());
+                        ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
+                        throw ex;
+                    }
+                }
+            }
+        } finally {
+            for (final NetworkElement element : networkElements) {
+                if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
+                    ((AggregatedCommandExecutor)element).cleanupAggregatedExecution(network, dest);
+                }
+            }
+        }
+    }
+
+    private void implementNetworkElements(final DeployDestination dest, final ReservationContext context, final Network network, final NetworkOffering offering, final List<Provider> providersToImplement)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        for (NetworkElement element : networkElements) {
+            if (providersToImplement.contains(element.getProvider())) {
+                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                    // The physicalNetworkId will not get translated into a uuid by the reponse serializer,
+                    // because the serializer would look up the NetworkVO class's table and retrieve the
+                    // network id instead of the physical network id.
+                    // So just throw this exception as is. We may need to TBD by changing the serializer.
+                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                            + network.getPhysicalNetworkId());
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Asking " + element.getName() + " to implemenet " + network);
+                }
+
+                if (!element.implement(network, offering, dest, context)) {
+                    CloudRuntimeException ex = new CloudRuntimeException("Failed to implement provider " + element.getProvider().getName() + " for network with specified id");
+                    ex.addProxyObject(network.getUuid(), "networkId");
+                    throw ex;
+                }
+            }
+        }
+    }
+
+    // This method re-programs the rules/ips for existing network
+    protected boolean reprogramNetworkRules(final long networkId, final Account caller, final Network network) throws ResourceUnavailableException {
+        boolean success = true;
+
+        //Apply egress rules first to effect the egress policy early on the guest traffic
+        final List<FirewallRuleVO> firewallEgressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        final DataCenter zone = _dcDao.findById(network.getDataCenterId());
+        if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall) && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall)
+                && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
+            // add default egress rule to accept the traffic
+            _firewallMgr.applyDefaultEgressFirewallRule(network.getId(), offering.isEgressDefaultPolicy(), true);
+        }
+        if (!_firewallMgr.applyFirewallRules(firewallEgressRulesToApply, false, caller)) {
+            s_logger.warn("Failed to reapply firewall Egress rule(s) as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // associate all ip addresses
+        if (!_ipAddrMgr.applyIpAssociations(network, false)) {
+            s_logger.warn("Failed to apply ip addresses as a part of network id" + networkId + " restart");
+            success = false;
+        }
+
+        // apply static nat
+        if (!_rulesMgr.applyStaticNatsForNetwork(networkId, false, caller)) {
+            s_logger.warn("Failed to apply static nats a part of network id" + networkId + " restart");
+            success = false;
+        }
+
+        // apply firewall rules
+        final List<FirewallRuleVO> firewallIngressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
+        if (!_firewallMgr.applyFirewallRules(firewallIngressRulesToApply, false, caller)) {
+            s_logger.warn("Failed to reapply Ingress firewall rule(s) as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // apply port forwarding rules
+        if (!_rulesMgr.applyPortForwardingRulesForNetwork(networkId, false, caller)) {
+            s_logger.warn("Failed to reapply port forwarding rule(s) as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // apply static nat rules
+        if (!_rulesMgr.applyStaticNatRulesForNetwork(networkId, false, caller)) {
+            s_logger.warn("Failed to reapply static nat rule(s) as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // apply public load balancer rules
+        if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Public)) {
+            s_logger.warn("Failed to reapply Public load balancer rules as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // apply internal load balancer rules
+        if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Internal)) {
+            s_logger.warn("Failed to reapply internal load balancer rules as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        // apply vpn rules
+        final List<? extends RemoteAccessVpn> vpnsToReapply = _vpnMgr.listRemoteAccessVpns(networkId);
+        if (vpnsToReapply != null) {
+            for (final RemoteAccessVpn vpn : vpnsToReapply) {
+                // Start remote access vpn per ip
+                if (_vpnMgr.startRemoteAccessVpn(vpn.getServerAddressId(), false) == null) {
+                    s_logger.warn("Failed to reapply vpn rules as a part of network id=" + networkId + " restart");
+                    success = false;
+                }
+            }
+        }
+
+        //apply network ACLs
+        if (!_networkACLMgr.applyACLToNetwork(networkId)) {
+            s_logger.warn("Failed to reapply network ACLs as a part of  of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        return success;
+    }
+
+    protected boolean prepareElement(final NetworkElement element, final Network network, final NicProfile profile, final VirtualMachineProfile vmProfile, final DeployDestination dest,
+            final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+        element.prepare(network, profile, vmProfile, dest, context);
+        if (vmProfile.getType() == Type.User && element.getProvider() != null) {
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)
+                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) && element instanceof DhcpServiceProvider) {
+                final DhcpServiceProvider sp = (DhcpServiceProvider)element;
+                if (isDhcpAccrossMultipleSubnetsSupported(sp)) {
+                    if (!sp.configDhcpSupportForSubnet(network, profile, vmProfile, dest, context)) {
+                        return false;
+                    }
+                }
+                if(!sp.addDhcpEntry(network, profile, vmProfile, dest, context)) {
+                    return false;
+                }
+            }
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns)
+                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, element.getProvider()) && element instanceof DnsServiceProvider) {
+                final DnsServiceProvider sp = (DnsServiceProvider)element;
+                if (profile.getIPv6Address() == null) {
+                    if (!sp.configDnsSupportForSubnet(network, profile, vmProfile, dest, context)) {
+                        return false;
+                    }
+                }
+                if(!sp.addDnsEntry(network, profile, vmProfile, dest, context)) {
+                    return false;
+                }
+            }
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.UserData)
+                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.UserData, element.getProvider()) && element instanceof UserDataServiceProvider) {
+                final UserDataServiceProvider sp = (UserDataServiceProvider)element;
+                if(!sp.addPasswordAndUserdata(network, profile, vmProfile, dest, context)){
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean canUpdateInSequence(Network network, boolean forced){
+        List<Provider> providers = getNetworkProviders(network.getId());
+
+        //check if the there are no service provider other than virtualrouter.
+        for(Provider provider : providers) {
+            if (provider != Provider.VirtualRouter)
+                throw new UnsupportedOperationException("Cannot update the network resources in sequence when providers other than virtualrouter are used");
+        }
+        //check if routers are in correct state before proceeding with the update
+        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
+        for (DomainRouterVO router : routers){
+            if (router.getRedundantState() == VirtualRouter.RedundantState.UNKNOWN) {
+                if (!forced) {
+                    throw new CloudRuntimeException("Domain router: "+router.getInstanceName()+" is in unknown state, Cannot update network. set parameter forced to true for forcing an update");
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public List<String> getServicesNotSupportedInNewOffering(Network network,long newNetworkOfferingId){
+        NetworkOffering offering =_networkOfferingDao.findById(newNetworkOfferingId);
+        List<String> services=_ntwkOfferingSrvcDao.listServicesForNetworkOffering(offering.getId());
+        List<NetworkServiceMapVO> serviceMap= _ntwkSrvcDao.getServicesInNetwork(network.getId());
+        List<String> servicesNotInNewOffering=new ArrayList<>();
+        for(NetworkServiceMapVO serviceVO :serviceMap){
+            boolean inlist=false;
+            for(String service: services){
+                if(serviceVO.getService().equalsIgnoreCase(service)){
+                    inlist=true;
+                    break;
+                }
+            }
+            if(!inlist){
+                //ignore Gateway service as this has no effect on the
+                //behaviour of network.
+                if(!serviceVO.getService().equalsIgnoreCase(Service.Gateway.getName()))
+                    servicesNotInNewOffering.add(serviceVO.getService());
+            }
+        }
+        return servicesNotInNewOffering;
+    }
+
+    @Override
+    public void cleanupConfigForServicesInNetwork(List<String> services, final Network network){
+        long networkId=network.getId();
+        Account caller=_accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
+        long userId=User.UID_SYSTEM;
+        //remove all PF/Static Nat rules for the network
+        s_logger.info("Services:"+services+" are no longer supported in network:"+network.getUuid()+
+                " after applying new network offering:"+network.getNetworkOfferingId()+" removing the related configuration");
+        if(services.contains(Service.StaticNat.getName())|| services.contains(Service.PortForwarding.getName())) {
+            try {
+                if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, userId, caller)) {
+                    s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId);
+                } else {
+                    s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup");
+                }
+                if(services.contains(Service.StaticNat.getName())){
+                    //removing static nat configured on ips.
+                    //optimizing the db operations using transaction.
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(network.getId());
+                            for (IPAddressVO ip : ips) {
+                                ip.setOneToOneNat(false);
+                                ip.setAssociatedWithVmId(null);
+                                ip.setVmIp(null);
+                                _ipAddressDao.update(ip.getId(),ip);
+                            }
+                        }
+                    });
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
+            }
+        }
+        if(services.contains(Service.SourceNat.getName())){
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    List<IPAddressVO> ips = _ipAddressDao.listByAssociatedNetwork(network.getId(),true);
+                    //removing static nat configured on ips.
+                    for (IPAddressVO ip : ips) {
+                        ip.setSourceNat(false);
+                        _ipAddressDao.update(ip.getId(),ip);
+                    }
+                }
+            });
+        }
+        if(services.contains(Service.Lb.getName())){
+            //remove all LB rules for the network
+            if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, userId)) {
+                s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId);
+            } else {
+                s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
+            }
+        }
+
+        if(services.contains(Service.Firewall.getName())){
+            //revoke all firewall rules for the network
+            try {
+                if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, userId, caller)) {
+                    s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
+                } else {
+                    s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup");
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
+            }
+        }
+
+        //do not remove vpn service for vpc networks.
+        if(services.contains(Service.Vpn.getName()) && network.getVpcId()==null){
+            RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByAccountAndNetwork(network.getAccountId(),networkId);
+            try {
+                _vpnMgr.destroyRemoteAccessVpnForIp(vpn.getServerAddressId(), caller, true);
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to cleanup remote access vpn resources of network:"+network.getUuid() + " due to Exception: ", ex);
+            }
+        }
+    }
+
+    @Override
+    public void configureUpdateInSequence(Network network) {
+        List<Provider> providers = getNetworkProviders(network.getId());
+        for (NetworkElement element : networkElements) {
+            if (providers.contains(element.getProvider())) {
+                if (element instanceof RedundantResource) {
+                    ((RedundantResource) element).configureResource(network);
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getResourceCount(Network network){
+        List<Provider> providers = getNetworkProviders(network.getId());
+        int resourceCount=0;
+        for (NetworkElement element : networkElements) {
+            if (providers.contains(element.getProvider())) {
+                //currently only one element implements the redundant resource interface
+                if (element instanceof RedundantResource) {
+                    resourceCount= ((RedundantResource) element).getResourceCount(network);
+                    break;
+                    }
+                }
+            }
+        return resourceCount;
+        }
+
+    @Override
+    public void configureExtraDhcpOptions(Network network, long nicId, Map<Integer, String> extraDhcpOptions) {
+        if(_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)) {
+            if (_networkModel.getNetworkServiceCapabilities(network.getId(), Service.Dhcp).containsKey(Capability.ExtraDhcpOptions)) {
+                DhcpServiceProvider sp = getDhcpServiceProvider(network);
+                sp.setExtraDhcpOptions(network, nicId, extraDhcpOptions);
+            }
+        }
+    }
+
+    @Override
+    public void configureExtraDhcpOptions(Network network, long nicId) {
+        Map<Integer, String> extraDhcpOptions = getExtraDhcpOptions(nicId);
+        configureExtraDhcpOptions(network, nicId, extraDhcpOptions);
+    }
+
+    @Override
+    public void finalizeUpdateInSequence(Network network, boolean success) {
+        List<Provider> providers = getNetworkProviders(network.getId());
+        for (NetworkElement element : networkElements) {
+            if (providers.contains(element.getProvider())) {
+                //currently only one element implements the redundant resource interface
+                if (element instanceof RedundantResource) {
+                    ((RedundantResource) element).finalize(network,success);
+                    break;
+                }
+            }
+        }
+    }
+
+
+    @DB
+    protected void updateNic(final NicVO nic, final long networkId, final int count) {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                _nicDao.update(nic.getId(), nic);
+
+                if (nic.getVmType() == VirtualMachine.Type.User) {
+                    s_logger.debug("Changing active number of nics for network id=" + networkId + " on " + count);
+                    _networksDao.changeActiveNicsBy(networkId, count);
+                }
+
+                if (nic.getVmType() == VirtualMachine.Type.User
+                        || nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest) {
+                    _networksDao.setCheckForGc(networkId);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void prepare(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException,
+    ResourceUnavailableException {
+        final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
+
+        // we have to implement default nics first - to ensure that default network elements start up first in multiple
+        //nics case
+        // (need for setting DNS on Dhcp to domR's Ip4 address)
+        Collections.sort(nics, new Comparator<NicVO>() {
+
+            @Override
+            public int compare(final NicVO nic1, final NicVO nic2) {
+                final boolean isDefault1 = nic1.isDefaultNic();
+                final boolean isDefault2 = nic2.isDefaultNic();
+
+                return isDefault1 ^ isDefault2 ? isDefault1 ^ true ? 1 : -1 : 0;
+            }
+        });
+
+        for (final NicVO nic : nics) {
+            final Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
+            if (implemented == null || implemented.first() == null) {
+                s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
+                throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
+            }
+
+            final NetworkVO network = implemented.second();
+            final NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network);
+            vmProfile.addNic(profile);
+        }
+    }
+
+    @Override
+    public NicProfile prepareNic(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context, final long nicId, final Network network)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
+            ResourceUnavailableException {
+
+        final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vmProfile.getId());
+        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+        final NicVO nic = _nicDao.findById(nicId);
+
+        NicProfile profile = null;
+        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
+            nic.setState(Nic.State.Reserving);
+            nic.setReservationId(context.getReservationId());
+            _nicDao.update(nic.getId(), nic);
+            URI broadcastUri = nic.getBroadcastUri();
+            if (broadcastUri == null) {
+                broadcastUri = network.getBroadcastUri();
+            }
+
+            final URI isolationUri = nic.getIsolationUri();
+
+            profile = new NicProfile(nic, network, broadcastUri, isolationUri,
+
+                    networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+            guru.reserve(profile, network, vmProfile, dest, context);
+            nic.setIPv4Address(profile.getIPv4Address());
+            nic.setAddressFormat(profile.getFormat());
+            nic.setIPv6Address(profile.getIPv6Address());
+            nic.setIPv6Cidr(profile.getIPv6Cidr());
+            nic.setIPv6Gateway(profile.getIPv6Gateway());
+            nic.setMacAddress(profile.getMacAddress());
+            nic.setIsolationUri(profile.getIsolationUri());
+            nic.setBroadcastUri(profile.getBroadCastUri());
+            nic.setReserver(guru.getName());
+            nic.setState(Nic.State.Reserved);
+            nic.setIPv4Netmask(profile.getIPv4Netmask());
+            nic.setIPv4Gateway(profile.getIPv4Gateway());
+
+            if (profile.getReservationStrategy() != null) {
+                nic.setReservationStrategy(profile.getReservationStrategy());
+            }
+
+            updateNic(nic, network.getId(), 1);
+        } else {
+            profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
+                    _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+            guru.updateNicProfile(profile, network);
+            nic.setState(Nic.State.Reserved);
+            updateNic(nic, network.getId(), 1);
+        }
+
+        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+        for (final NetworkElement element : networkElements) {
+            if (providersToImplement.contains(element.getProvider())) {
+                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                            + network.getPhysicalNetworkId());
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Asking " + element.getName() + " to prepare for " + nic);
+                }
+                if (!prepareElement(element, network, profile, vmProfile, dest, context)) {
+                    throw new InsufficientAddressCapacityException("unable to configure the dhcp service, due to insufficiant address capacity", Network.class, network.getId());
+                }
+            }
+        }
+
+        profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
+        guru.updateNicProfile(profile, network);
+
+        configureExtraDhcpOptions(network, nicId);
+        return profile;
+    }
+
+    @Override
+    public Map<Integer, String> getExtraDhcpOptions(long nicId) {
+        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOList = _nicExtraDhcpOptionDao.listByNicId(nicId);
+        return nicExtraDhcpOptionVOList
+                .stream()
+                .collect(Collectors.toMap(NicExtraDhcpOptionVO::getCode, NicExtraDhcpOptionVO::getValue));
+    }
+
+
+    @Override
+    public void prepareNicForMigration(final VirtualMachineProfile vm, final DeployDestination dest) {
+        if(vm.getType().equals(VirtualMachine.Type.DomainRouter) && (vm.getHypervisorType().equals(HypervisorType.KVM) || vm.getHypervisorType().equals(HypervisorType.VMware))) {
+            //Include nics hot plugged and not stored in DB
+            prepareAllNicsForMigration(vm, dest);
+            return;
+        }
+        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        final ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), null, null);
+        for (final NicVO nic : nics) {
+            final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+            final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+
+            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
+                    _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+            if (guru instanceof NetworkMigrationResponder) {
+                if (!((NetworkMigrationResponder)guru).prepareMigration(profile, network, vm, dest, context)) {
+                    s_logger.error("NetworkGuru " + guru + " prepareForMigration failed."); // XXX: Transaction error
+                }
+            }
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                                + network.getPhysicalNetworkId());
+                    }
+                    if (element instanceof NetworkMigrationResponder) {
+                        if (!((NetworkMigrationResponder)element).prepareMigration(profile, network, vm, dest, context)) {
+                            s_logger.error("NetworkElement " + element + " prepareForMigration failed."); // XXX: Transaction error
+                        }
+                    }
+                }
+            }
+            guru.updateNicProfile(profile, network);
+            vm.addNic(profile);
+        }
+    }
+
+    /*
+    Prepare All Nics for migration including the nics dynamically created and not stored in DB
+    This is a temporary workaround work KVM migration
+    Once clean fix is added by stored dynamically nics is DB, this workaround won't be needed
+     */
+    @Override
+    public void prepareAllNicsForMigration(final VirtualMachineProfile vm, final DeployDestination dest) {
+        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        final ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), null, null);
+        Long guestNetworkId = null;
+        for (final NicVO nic : nics) {
+            final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+            if(network.getTrafficType().equals(TrafficType.Guest) && network.getGuestType().equals(GuestType.Isolated)){
+                guestNetworkId = network.getId();
+            }
+            final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+
+            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate,
+                    _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+            if(guru instanceof NetworkMigrationResponder){
+                if(!((NetworkMigrationResponder) guru).prepareMigration(profile, network, vm, dest, context)){
+                    s_logger.error("NetworkGuru "+guru+" prepareForMigration failed."); // XXX: Transaction error
+                }
+            }
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
+                    }
+                    if(element instanceof NetworkMigrationResponder){
+                        if(!((NetworkMigrationResponder) element).prepareMigration(profile, network, vm, dest, context)){
+                            s_logger.error("NetworkElement "+element+" prepareForMigration failed."); // XXX: Transaction error
+                        }
+                    }
+                }
+            }
+            guru.updateNicProfile(profile, network);
+            vm.addNic(profile);
+        }
+
+        final List<String> addedURIs = new ArrayList<String>();
+        if(guestNetworkId != null){
+            final List<IPAddressVO> publicIps = _ipAddressDao.listByAssociatedNetwork(guestNetworkId, null);
+            for (final IPAddressVO userIp : publicIps){
+                final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                final URI broadcastUri = BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag());
+                final long ntwkId = publicIp.getNetworkId();
+                final Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(ntwkId, vm.getId(),
+                        broadcastUri.toString());
+                if(nic == null && !addedURIs.contains(broadcastUri.toString())){
+                    //Nic details are not available in DB
+                    //Create nic profile for migration
+                    s_logger.debug("Creating nic profile for migration. BroadcastUri: "+broadcastUri.toString()+" NetworkId: "+ntwkId+" Vm: "+vm.getId());
+                    final NetworkVO network = _networksDao.findById(ntwkId);
+                    _networkModel.getNetworkRate(network.getId(), vm.getId());
+                    final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+                    final NicProfile profile = new NicProfile();
+                    profile.setDeviceId(255); //dummyId
+                    profile.setIPv4Address(userIp.getAddress().toString());
+                    profile.setIPv4Netmask(publicIp.getNetmask());
+                    profile.setIPv4Gateway(publicIp.getGateway());
+                    profile.setMacAddress(publicIp.getMacAddress());
+                    profile.setBroadcastType(network.getBroadcastDomainType());
+                    profile.setTrafficType(network.getTrafficType());
+                    profile.setBroadcastUri(broadcastUri);
+                    profile.setIsolationUri(Networks.IsolationType.Vlan.toUri(publicIp.getVlanTag()));
+                    profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
+                    profile.setName(_networkModel.getNetworkTag(vm.getHypervisorType(), network));
+                    profile.setNetworId(network.getId());
+
+                    guru.updateNicProfile(profile, network);
+                    vm.addNic(profile);
+                    addedURIs.add(broadcastUri.toString());
+                }
+            }
+        }
+    }
+
+    private NicProfile findNicProfileById(final VirtualMachineProfile vm, final long id) {
+        for (final NicProfile nic : vm.getNics()) {
+            if (nic.getId() == id) {
+                return nic;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void commitNicForMigration(final VirtualMachineProfile src, final VirtualMachineProfile dst) {
+        for (final NicProfile nicSrc : src.getNics()) {
+            final NetworkVO network = _networksDao.findById(nicSrc.getNetworkId());
+            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            final NicProfile nicDst = findNicProfileById(dst, nicSrc.getId());
+            final ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
+            final ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
+
+            if (guru instanceof NetworkMigrationResponder) {
+                ((NetworkMigrationResponder)guru).commitMigration(nicSrc, network, src, src_context, dst_context);
+            }
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                                + network.getPhysicalNetworkId());
+                    }
+                    if (element instanceof NetworkMigrationResponder) {
+                        ((NetworkMigrationResponder)element).commitMigration(nicSrc, network, src, src_context, dst_context);
+                    }
+                }
+            }
+            // update the reservation id
+            final NicVO nicVo = _nicDao.findById(nicDst.getId());
+            nicVo.setReservationId(nicDst.getReservationId());
+            _nicDao.persist(nicVo);
+        }
+    }
+
+    @Override
+    public void rollbackNicForMigration(final VirtualMachineProfile src, final VirtualMachineProfile dst) {
+        for (final NicProfile nicDst : dst.getNics()) {
+            final NetworkVO network = _networksDao.findById(nicDst.getNetworkId());
+            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+            final NicProfile nicSrc = findNicProfileById(src, nicDst.getId());
+            final ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
+            final ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
+
+            if (guru instanceof NetworkMigrationResponder) {
+                ((NetworkMigrationResponder)guru).rollbackMigration(nicDst, network, dst, src_context, dst_context);
+            }
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                                + network.getPhysicalNetworkId());
+                    }
+                    if (element instanceof NetworkMigrationResponder) {
+                        ((NetworkMigrationResponder)element).rollbackMigration(nicDst, network, dst, src_context, dst_context);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB
+    public void release(final VirtualMachineProfile vmProfile, final boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
+        final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
+        for (final NicVO nic : nics) {
+            releaseNic(vmProfile, nic.getId());
+        }
+    }
+
+    @Override
+    @DB
+    public void releaseNic(final VirtualMachineProfile vmProfile, final Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
+        releaseNic(vmProfile, nic.getId());
+    }
+
+    @DB
+    protected void releaseNic(final VirtualMachineProfile vmProfile, final long nicId) throws ConcurrentOperationException, ResourceUnavailableException {
+        final Pair<Network, NicProfile> networkToRelease = Transaction.execute(new TransactionCallback<Pair<Network, NicProfile>>() {
+            @Override
+            public Pair<Network, NicProfile> doInTransaction(final TransactionStatus status) {
+                final NicVO nic = _nicDao.lockRow(nicId, true);
+                if (nic == null) {
+                    throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic);
+                }
+
+                final Nic.State originalState = nic.getState();
+                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+
+                if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) {
+                    if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
+                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+                        nic.setState(Nic.State.Releasing);
+                        _nicDao.update(nic.getId(), nic);
+                        final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel
+                                .isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
+                        if (guru.release(profile, vmProfile, nic.getReservationId())) {
+                            applyProfileToNicForRelease(nic, profile);
+                            nic.setState(Nic.State.Allocated);
+                            if (originalState == Nic.State.Reserved) {
+                                updateNic(nic, network.getId(), -1);
+                            } else {
+                                _nicDao.update(nic.getId(), nic);
+                            }
+                        }
+                        // Perform release on network elements
+                        return new Pair<Network, NicProfile>(network, profile);
+                    } else {
+                        nic.setState(Nic.State.Allocated);
+                        updateNic(nic, network.getId(), -1);
+                    }
+                }
+
+                return null;
+            }
+        });
+
+        // cleanup the entry in vm_network_map
+        if(vmProfile.getType().equals(VirtualMachine.Type.User)) {
+            final NicVO nic = _nicDao.findById(nicId);
+            if(nic != null) {
+                final NetworkVO vmNetwork = _networksDao.findById(nic.getNetworkId());
+                final VMNetworkMapVO vno = _vmNetworkMapDao.findByVmAndNetworkId(vmProfile.getVirtualMachine().getId(), vmNetwork.getId());
+                if(vno != null) {
+                    _vmNetworkMapDao.remove(vno.getId());
+                }
+            }
+        }
+
+        if (networkToRelease != null) {
+            final Network network = networkToRelease.first();
+            final NicProfile profile = networkToRelease.second();
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Asking " + element.getName() + " to release " + profile);
+                    }
+                    //NOTE: Context appear to never be used in release method
+                    //implementations. Consider removing it from interface Element
+                    element.release(network, profile, vmProfile, null);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void cleanupNics(final VirtualMachineProfile vm) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Cleaning network for vm: " + vm.getId());
+        }
+
+        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        for (final NicVO nic : nics) {
+            removeNic(vm, nic);
+        }
+    }
+
+    @Override
+    public void removeNic(final VirtualMachineProfile vm, final Nic nic) {
+        removeNic(vm, _nicDao.findById(nic.getId()));
+    }
+
+    protected void removeNic(final VirtualMachineProfile vm, final NicVO nic) {
+
+        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start && nic.getState() != Nic.State.Allocated) {
+            // Nics with reservation strategy 'Start' should go through release phase in the Nic life cycle.
+            // Ensure that release is performed before Nic is to be removed to avoid resource leaks.
+            try {
+                releaseNic(vm, nic.getId());
+            } catch (final Exception ex) {
+                s_logger.warn("Failed to release nic: " + nic.toString() + " as part of remove operation due to", ex);
+            }
+        }
+
+        nic.setState(Nic.State.Deallocating);
+        _nicDao.update(nic.getId(), nic);
+        final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+        final NicProfile profile = new NicProfile(nic, network, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(
+                vm.getHypervisorType(), network));
+
+        /*
+         * We need to release the nics with a Create ReservationStrategy here
+         * because the nic is now being removed.
+         */
+        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Create) {
+            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+            for (final NetworkElement element : networkElements) {
+                if (providersToImplement.contains(element.getProvider())) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Asking " + element.getName() + " to release " + nic);
+                    }
+                    try {
+                        element.release(network, profile, vm, null);
+                    } catch (final ConcurrentOperationException ex) {
+                        s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
+                    } catch (final ResourceUnavailableException ex) {
+                        s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
+                    }
+                }
+            }
+        }
+
+        if (vm.getType() == Type.User
+                && network.getTrafficType() == TrafficType.Guest
+                && network.getGuestType() == GuestType.Shared
+                && isLastNicInSubnet(nic)) {
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)) {
+                // remove the dhcpservice ip if this is the last nic in subnet.
+                final DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
+                if (dhcpServiceProvider != null
+                        && isDhcpAccrossMultipleSubnetsSupported(dhcpServiceProvider)) {
+                    removeDhcpServiceInSubnet(nic);
+                }
+            }
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns)){
+                final DnsServiceProvider dnsServiceProvider = getDnsServiceProvider(network);
+                if (dnsServiceProvider != null) {
+                    try {
+                        if(!dnsServiceProvider.removeDnsSupportForSubnet(network)) {
+                            s_logger.warn("Failed to remove the ip alias on the dns server");
+                        }
+                    } catch (final ResourceUnavailableException e) {
+                        //failed to remove the dnsconfig.
+                        s_logger.info("Unable to delete the ip alias due to unable to contact the dns server.");
+                    }
+                }
+            }
+        }
+
+        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+        guru.deallocate(network, profile, vm);
+        _nicDao.remove(nic.getId());
+
+        s_logger.debug("Removed nic id=" + nic.getId());
+        //remove the secondary ip addresses corresponding to to this nic
+        if (!removeVmSecondaryIpsOfNic(nic.getId())) {
+            s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed");
+        }
+    }
+
+    public boolean isDhcpAccrossMultipleSubnetsSupported(final DhcpServiceProvider dhcpServiceProvider) {
+
+        final Map<Network.Capability, String> capabilities = dhcpServiceProvider.getCapabilities().get(Network.Service.Dhcp);
+        final String supportsMultipleSubnets = capabilities.get(Network.Capability.DhcpAccrossMultipleSubnets);
+        if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isLastNicInSubnet(final NicVO nic) {
+        if (_nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getIPv4Gateway(), nic.getBroadcastUri()).size() > 1) {
+            return false;
+        }
+        return true;
+    }
+
+    @DB
+    @Override
+    public void removeDhcpServiceInSubnet(final Nic nic) {
+        final Network network = _networksDao.findById(nic.getNetworkId());
+        final DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
+        try {
+            final NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getIPv4Gateway(), network.getId(), NicIpAlias.State.active);
+            if (ipAlias != null) {
+                ipAlias.setState(NicIpAlias.State.revoked);
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        _nicIpAliasDao.update(ipAlias.getId(), ipAlias);
+                        final IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address());
+                        _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId());
+                    }
+                });
+                if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) {
+                    s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address());
+                }
+            }
+        } catch (final ResourceUnavailableException e) {
+            //failed to remove the dhcpconfig on the router.
+            s_logger.info("Unable to delete the ip alias due to unable to contact the virtualrouter.");
+        }
+
+    }
+
+    @Override
+    public void expungeNics(final VirtualMachineProfile vm) {
+        final List<NicVO> nics = _nicDao.listByVmIdIncludingRemoved(vm.getId());
+        for (final NicVO nic : nics) {
+            _nicDao.expunge(nic.getId());
+        }
+    }
+
+    @Override
+    @DB
+    public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
+                                      boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
+                                      final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
+                                      final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
+
+        final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
+        // this method supports only guest network creation
+        if (ntwkOff.getTrafficType() != TrafficType.Guest) {
+            s_logger.warn("Only guest networks can be created using this method");
+            return null;
+        }
+
+        final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
+        //check resource limits
+        if (updateResourceCount) {
+            _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
+        }
+
+        // Validate network offering
+        if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
+            // see NetworkOfferingVO
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled);
+            ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
+            throw ex;
+        }
+
+        // Validate physical network
+        if (pNtwk.getState() != PhysicalNetwork.State.Enabled) {
+            // see PhysicalNetworkVO.java
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + " in incorrect state:" + pNtwk.getState());
+            ex.addProxyObject(pNtwk.getUuid(), "physicalNetworkId");
+            throw ex;
+        }
+
+        boolean ipv6 = false;
+
+        if (StringUtils.isNotBlank(ip6Gateway) && StringUtils.isNotBlank(ip6Cidr)) {
+            ipv6 = true;
+        }
+        // Validate zone
+        final DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone.getNetworkType() == NetworkType.Basic) {
+            // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
+            if (aclType == null || aclType != ACLType.Domain) {
+                throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
+            }
+
+            // Only one guest network is supported in Basic zone
+            final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
+            if (!guestNetworks.isEmpty()) {
+                throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
+            }
+
+            // if zone is basic, only Shared network offerings w/o source nat service are allowed
+            if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
+                throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled "
+                        + Service.SourceNat.getName() + " service are allowed");
+            }
+
+            if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
+                throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
+            }
+
+            if (subdomainAccess == null) {
+                subdomainAccess = true;
+            } else if (!subdomainAccess) {
+                throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
+            }
+
+            if (vlanId == null) {
+                vlanId = Vlan.UNTAGGED;
+            } else {
+                if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
+                    throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
+                }
+            }
+
+        } else if (zone.getNetworkType() == NetworkType.Advanced) {
+            if (zone.isSecurityGroupEnabled()) {
+                if (isolatedPvlan != null) {
+                    throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
+                }
+                // Only Account specific Isolated network with sourceNat service disabled are allowed in security group
+                // enabled zone
+                if (ntwkOff.getGuestType() != GuestType.Shared) {
+                    throw new InvalidParameterValueException("Only shared guest network can be created in security group enabled zone");
+                }
+                if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
+                    throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
+                }
+            }
+
+            //don't allow eip/elb networks in Advance zone
+            if (ntwkOff.isElasticIp() || ntwkOff.isElasticLb()) {
+                throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
+            }
+        }
+
+        if (ipv6 && NetUtils.getIp6CidrSize(ip6Cidr) != 64) {
+            throw new InvalidParameterValueException("IPv6 subnet should be exactly 64-bits in size");
+        }
+
+        //TODO(VXLAN): Support VNI specified
+        // VlanId can be specified only when network offering supports it
+        final boolean vlanSpecified = vlanId != null;
+        if (vlanSpecified != ntwkOff.isSpecifyVlan()) {
+            if (vlanSpecified) {
+                throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
+            } else {
+                throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
+            }
+        }
+
+        if (vlanSpecified) {
+            URI uri = BroadcastDomainType.fromString(vlanId);
+            //don't allow to specify vlan tag used by physical network for dynamic vlan allocation
+            if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
+                throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+                        + zone.getName());
+            }
+            if (! UuidUtils.validateUUID(vlanId)){
+                // For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone
+                if (ntwkOff.getGuestType() == GuestType.Isolated || !hasGuestBypassVlanOverlapCheck(bypassVlanOverlapCheck, ntwkOff)) {
+                    if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
+                        throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId);
+                    } else {
+                        final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
+                        //for the network that is created as part of private gateway,
+                        //the vnet is not coming from the data center vnet table, so the list can be empty
+                        if (!dcVnets.isEmpty()) {
+                            final DataCenterVnetVO dcVnet = dcVnets.get(0);
+                            // Fail network creation if specified vlan is dedicated to a different account
+                            if (dcVnet.getAccountGuestVlanMapId() != null) {
+                                final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
+                                final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
+                                if (map.getAccountId() != owner.getAccountId()) {
+                                    throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
+                                }
+                                // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
+                            } else {
+                                final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
+                                if (maps != null && !maps.isEmpty()) {
+                                    final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
+                                    final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
+                                    if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
+                                        throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
+                                                + owner.getAccountName());
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
+                    // shared network with same Vlan ID in the zone
+                    if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0 ) {
+                        throw new InvalidParameterValueException("There is an existing isolated/shared network that overlaps with vlan id:" + vlanId + " in zone " + zoneId);
+                    }
+                }
+            }
+
+        }
+
+        // If networkDomain is not specified, take it from the global configuration
+        if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
+            final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId),
+                    Service.Dns);
+            final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
+            if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
+                if (networkDomain != null) {
+                    // TBD: NetworkOfferingId and zoneId. Send uuids instead.
+                    throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId);
+                }
+            } else {
+                if (networkDomain == null) {
+                    // 1) Get networkDomain from the corresponding account/domain/zone
+                    if (aclType == ACLType.Domain) {
+                        networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
+                    } else if (aclType == ACLType.Account) {
+                        networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
+                    }
+
+                    // 2) If null, generate networkDomain using domain suffix from the global config variables
+                    if (networkDomain == null) {
+                        networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
+                    }
+
+                } else {
+                    // validate network domain
+                    if (!NetUtils.verifyDomainName(networkDomain)) {
+                        throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
+                                + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+                    }
+                }
+            }
+        }
+
+        // In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
+        // limitation, remove after we introduce support for multiple ip ranges
+        // with different Cidrs for the same Shared network
+        final boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced
+                && ntwkOff.getTrafficType() == TrafficType.Guest
+                && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated
+                && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)));
+        if (cidr == null && ip6Cidr == null && cidrRequired) {
+            throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of" + " type " + Network.GuestType.Shared
+                    + " and network of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
+        }
+
+        checkL2OfferingServices(ntwkOff);
+
+        // No cidr can be specified in Basic zone
+        if (zone.getNetworkType() == NetworkType.Basic && cidr != null) {
+            throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
+        }
+
+        // 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 RFC 1918 or 6598 compliant");
+            }
+        }
+
+        final String networkDomainFinal = networkDomain;
+        final String vlanIdFinal = vlanId;
+        final Boolean subdomainAccessFinal = subdomainAccess;
+        final Network network = Transaction.execute(new TransactionCallback<Network>() {
+            @Override
+            public Network doInTransaction(final TransactionStatus status) {
+                Long physicalNetworkId = null;
+                if (pNtwk != null) {
+                    physicalNetworkId = pNtwk.getId();
+                }
+                final DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId);
+                final NetworkVO userNetwork = new NetworkVO();
+                userNetwork.setNetworkDomain(networkDomainFinal);
+
+                if (cidr != null && gateway != null) {
+                    userNetwork.setCidr(cidr);
+                    userNetwork.setGateway(gateway);
+                }
+
+                if (StringUtils.isNotBlank(ip6Gateway) && StringUtils.isNotBlank(ip6Cidr)) {
+                    userNetwork.setIp6Cidr(ip6Cidr);
+                    userNetwork.setIp6Gateway(ip6Gateway);
+                }
+
+                if (externalId != null) {
+                    userNetwork.setExternalId(externalId);
+                }
+
+                if (vlanIdFinal != null) {
+                    if (isolatedPvlan == null) {
+                        URI uri = null;
+                        if (UuidUtils.validateUUID(vlanIdFinal)){
+                            //Logical router's UUID provided as VLAN_ID
+                            userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
+                        } else {
+                            uri = BroadcastDomainType.fromString(vlanIdFinal);
+                        }
+                        userNetwork.setBroadcastUri(uri);
+                        if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
+                            userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
+                        } else {
+                            userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
+                        }
+                    } else {
+                        if (vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
+                            throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
+                        }
+                        userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanIdFinal, isolatedPvlan));
+                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
+                    }
+                }
+
+                final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
+                        isDisplayNetworkEnabled);
+
+                Network network = null;
+                if (networks == null || networks.isEmpty()) {
+                    throw new CloudRuntimeException("Fail to create a network");
+                } else {
+                    if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) {
+                        Network defaultGuestNetwork = networks.get(0);
+                        for (final Network nw : networks) {
+                            if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) {
+                                defaultGuestNetwork = nw;
+                            }
+                        }
+                        network = defaultGuestNetwork;
+                    } else {
+                        // For shared network
+                        network = networks.get(0);
+                    }
+                }
+
+                if (updateResourceCount) {
+                    _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
+                }
+
+                return network;
+            }
+        });
+
+        CallContext.current().setEventDetails("Network Id: " + network.getId());
+        CallContext.current().putContextParameter(Network.class, network.getUuid());
+        return network;
+    }
+
+  /**
+   * Checks bypass VLAN id/range overlap check during network creation for guest networks
+   * @param bypassVlanOverlapCheck bypass VLAN id/range overlap check
+   * @param ntwkOff network offering
+   */
+  private boolean hasGuestBypassVlanOverlapCheck(final boolean bypassVlanOverlapCheck, final NetworkOfferingVO ntwkOff) {
+    return bypassVlanOverlapCheck && ntwkOff.getGuestType() != GuestType.Isolated;
+  }
+
+  /**
+     * Checks for L2 network offering services. Only 2 cases allowed:
+     * - No services
+     * - User Data service only, provided by ConfigDrive
+     * @param ntwkOff network offering
+     */
+    protected void checkL2OfferingServices(NetworkOfferingVO ntwkOff) {
+        if (ntwkOff.getGuestType() == GuestType.L2 && !_networkModel.listNetworkOfferingServices(ntwkOff.getId()).isEmpty() &&
+                (!_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.UserData) ||
+                        (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.UserData) &&
+                                _networkModel.listNetworkOfferingServices(ntwkOff.getId()).size() > 1))) {
+            throw new InvalidParameterValueException("For L2 networks, only UserData service is allowed");
+        }
+    }
+
+    @Override
+    @DB
+    public boolean shutdownNetwork(final long networkId, final ReservationContext context, final boolean cleanupElements) {
+        NetworkVO network = _networksDao.findById(networkId);
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("Network is already shutdown: " + network);
+            return true;
+        }
+
+        if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
+            s_logger.debug("Network is not implemented: " + network);
+            return false;
+        }
+
+        try {
+            //do global lock for the network
+            network = _networksDao.acquireInLockTable(networkId, NetworkLockTimeout.value());
+            if (network == null) {
+                s_logger.warn("Unable to acquire lock for the network " + network + " as a part of network shutdown");
+                return false;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Lock is acquired for network " + network + " as a part of network shutdown");
+            }
+
+            if (network.getState() == Network.State.Allocated) {
+                s_logger.debug("Network is already shutdown: " + network);
+                return true;
+            }
+
+            if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
+                s_logger.debug("Network is not implemented: " + network);
+                return false;
+            }
+
+            if (isSharedNetworkWithServices(network)) {
+                network.setState(Network.State.Shutdown);
+                _networksDao.update(network.getId(), network);
+            } else {
+                try {
+                    stateTransitTo(network, Event.DestroyNetwork);
+                } catch (final NoTransitionException e) {
+                    network.setState(Network.State.Shutdown);
+                    _networksDao.update(network.getId(), network);
+                }
+            }
+
+            final boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
+
+            final NetworkVO networkFinal = network;
+            final boolean result = Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(final TransactionStatus status) {
+                    boolean result = false;
+
+                    if (success) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now.");
+                        }
+                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, networkFinal.getGuruName());
+                        final NetworkProfile profile = convertNetworkToNetworkProfile(networkFinal.getId());
+                        guru.shutdown(profile, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()));
+
+                        applyProfileToNetwork(networkFinal, profile);
+                        final DataCenterVO zone = _dcDao.findById(networkFinal.getDataCenterId());
+                        if (isSharedNetworkOfferingWithServices(networkFinal.getNetworkOfferingId()) && zone.getNetworkType() == NetworkType.Advanced) {
+                            networkFinal.setState(Network.State.Setup);
+                        } else {
+                            try {
+                                stateTransitTo(networkFinal, Event.OperationSucceeded);
+                            } catch (final NoTransitionException e) {
+                                networkFinal.setState(Network.State.Allocated);
+                                networkFinal.setRestartRequired(false);
+                            }
+                        }
+                        _networksDao.update(networkFinal.getId(), networkFinal);
+                        _networksDao.clearCheckForGc(networkId);
+                        result = true;
+                    } else {
+                        try {
+                            stateTransitTo(networkFinal, Event.OperationFailed);
+                        } catch (final NoTransitionException e) {
+                            networkFinal.setState(Network.State.Implemented);
+                            _networksDao.update(networkFinal.getId(), networkFinal);
+                        }
+                        result = false;
+                    }
+
+                    return result;
+                }
+            });
+
+            return result;
+        } finally {
+            if (network != null) {
+                _networksDao.releaseFromLockTable(network.getId());
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Lock is released for network " + network + " as a part of network shutdown");
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean shutdownNetworkElementsAndResources(final ReservationContext context, final boolean cleanupElements, final Network network) {
+
+        // get providers to shutdown
+        final List<Provider> providersToShutdown = getNetworkProviders(network.getId());
+
+        // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down
+        // the elements
+        boolean cleanupResult = true;
+        boolean cleanupNeeded = false;
+        try {
+            for (final Provider provider: providersToShutdown) {
+                if (provider.cleanupNeededOnShutdown()) {
+                    cleanupNeeded = true;
+                    break;
+                }
+            }
+            if (cleanupNeeded) {
+                cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId());
+            }
+        } catch (final Exception ex) {
+            s_logger.warn("shutdownNetworkRules failed during the network " + network + " shutdown due to ", ex);
+        } finally {
+            // just warn the administrator that the network elements failed to shutdown
+            if (!cleanupResult) {
+                s_logger.warn("Failed to cleanup network id=" + network.getId() + " resources as a part of shutdownNetwork");
+            }
+        }
+
+        // 2) Shutdown all the network elements
+        boolean success = true;
+        for (final NetworkElement element : networkElements) {
+            if (providersToShutdown.contains(element.getProvider())) {
+                try {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Sending network shutdown to " + element.getName());
+                    }
+                    if (!element.shutdown(network, context, cleanupElements)) {
+                        s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName());
+                        success = false;
+                    }
+                } catch (final ResourceUnavailableException e) {
+                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
+                    success = false;
+                } catch (final ConcurrentOperationException e) {
+                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
+                    success = false;
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
+                    success = false;
+                }
+            }
+        }
+        return success;
+    }
+
+    @Override
+    @DB
+    public boolean destroyNetwork(final long networkId, final ReservationContext context, final boolean forced) {
+        final Account callerAccount = context.getAccount();
+
+        NetworkVO network = _networksDao.findById(networkId);
+        if (network == null) {
+            s_logger.debug("Unable to find network with id: " + networkId);
+            return false;
+        }
+        // Make sure that there are no user vms in the network that are not Expunged/Error
+        final List<UserVmVO> userVms = _userVmDao.listByNetworkIdAndStates(networkId);
+
+        for (final UserVmVO vm : userVms) {
+            if (!(vm.getState() == VirtualMachine.State.Expunging && vm.getRemoved() != null)) {
+                s_logger.warn("Can't delete the network, not all user vms are expunged. Vm " + vm + " is in " + vm.getState() + " state");
+                return false;
+            }
+        }
+
+        // Don't allow to delete network via api call when it has vms assigned to it
+        final int nicCount = getActiveNicsInNetwork(networkId);
+        if (nicCount > 0) {
+            s_logger.debug("The network id=" + networkId + " has active Nics, but shouldn't.");
+            // at this point we have already determined that there are no active user vms in network
+            // if the op_networks table shows active nics, it's a bug in releasing nics updating op_networks
+            _networksDao.changeActiveNicsBy(networkId, -1 * nicCount);
+        }
+
+        //In Basic zone, make sure that there are no non-removed console proxies and SSVMs using the network
+        final DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        if (zone.getNetworkType() == NetworkType.Basic) {
+            final List<VMInstanceVO> systemVms = _vmDao.listNonRemovedVmsByTypeAndNetwork(network.getId(), Type.ConsoleProxy, Type.SecondaryStorageVm);
+            if (systemVms != null && !systemVms.isEmpty()) {
+                s_logger.warn("Can't delete the network, not all consoleProxy/secondaryStorage vms are expunged");
+                return false;
+            }
+        }
+
+        // Shutdown network first
+        shutdownNetwork(networkId, context, false);
+
+        // get updated state for the network
+        network = _networksDao.findById(networkId);
+        if (network.getState() != Network.State.Allocated && network.getState() != Network.State.Setup && !forced) {
+            s_logger.debug("Network is not not in the correct state to be destroyed: " + network.getState());
+            return false;
+        }
+
+        boolean success = true;
+        if (!cleanupNetworkResources(networkId, callerAccount, context.getCaller().getId())) {
+            s_logger.warn("Unable to delete network id=" + networkId + ": failed to cleanup network resources");
+            return false;
+        }
+
+        // get providers to destroy
+        final List<Provider> providersToDestroy = getNetworkProviders(network.getId());
+        for (final NetworkElement element : networkElements) {
+            if (providersToDestroy.contains(element.getProvider())) {
+                try {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Sending destroy to " + element);
+                    }
+
+                    if (!element.destroy(network, context)) {
+                        success = false;
+                        s_logger.warn("Unable to complete destroy of the network: failed to destroy network element " + element.getName());
+                    }
+                } catch (final ResourceUnavailableException e) {
+                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
+                    success = false;
+                } catch (final ConcurrentOperationException e) {
+                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
+                    success = false;
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
+                    success = false;
+                }
+            }
+        }
+
+        if (success) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Network id=" + networkId + " is destroyed successfully, cleaning up corresponding resources now.");
+            }
+
+            final NetworkVO networkFinal = network;
+            try {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, networkFinal.getGuruName());
+
+                        if (!guru.trash(networkFinal, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()))) {
+                            throw new CloudRuntimeException("Failed to trash network.");
+                        }
+
+                        if (!deleteVlansInNetwork(networkFinal.getId(), context.getCaller().getId(), callerAccount)) {
+                            s_logger.warn("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
+                            throw new CloudRuntimeException("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
+                        } else {
+                            // commit transaction only when ips and vlans for the network are released successfully
+                            try {
+                                stateTransitTo(networkFinal, Event.DestroyNetwork);
+                            } catch (final NoTransitionException e) {
+                                s_logger.debug(e.getMessage());
+                            }
+                            if (_networksDao.remove(networkFinal.getId())) {
+                                final NetworkDomainVO networkDomain = _networkDomainDao.getDomainNetworkMapByNetworkId(networkFinal.getId());
+                                if (networkDomain != null) {
+                                    _networkDomainDao.remove(networkDomain.getId());
+                                }
+
+                                final NetworkAccountVO networkAccount = _networkAccountDao.getAccountNetworkMapByNetworkId(networkFinal.getId());
+                                if (networkAccount != null) {
+                                    _networkAccountDao.remove(networkAccount.getId());
+                                }
+                            }
+
+                            final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId());
+                            final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, networkFinal.getAclType());
+                            if (updateResourceCount) {
+                                _resourceLimitMgr.decrementResourceCount(networkFinal.getAccountId(), ResourceType.network, networkFinal.getDisplayNetwork());
+                            }
+                        }
+                    }
+                });
+                if (_networksDao.findById(network.getId()) == null) {
+                    // remove its related ACL permission
+                    final Pair<Class<?>, Long> networkMsg = new Pair<Class<?>, Long>(Network.class, networkFinal.getId());
+                    _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg);
+                }
+                return true;
+            } catch (final CloudRuntimeException e) {
+                s_logger.error("Failed to delete network", e);
+                return false;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean resourceCountNeedsUpdate(final NetworkOffering ntwkOff, final ACLType aclType) {
+        //Update resource count only for Isolated account specific non-system networks
+        final boolean updateResourceCount = ntwkOff.getGuestType() == GuestType.Isolated && !ntwkOff.isSystemOnly() && aclType == ACLType.Account;
+        return updateResourceCount;
+    }
+
+    protected boolean deleteVlansInNetwork(final long networkId, final long userId, final Account callerAccount) {
+
+        //cleanup Public vlans
+        final List<VlanVO> publicVlans = _vlanDao.listVlansByNetworkId(networkId);
+        boolean result = true;
+        for (final VlanVO vlan : publicVlans) {
+            if (!_configMgr.deleteVlanAndPublicIpRange(userId, vlan.getId(), callerAccount)) {
+                s_logger.warn("Failed to delete vlan " + vlan.getId() + ");");
+                result = false;
+            }
+        }
+
+        //cleanup private vlans
+        final int privateIpAllocCount = _privateIpDao.countAllocatedByNetworkId(networkId);
+        if (privateIpAllocCount > 0) {
+            s_logger.warn("Can't delete Private ip range for network " + networkId + " as it has allocated ip addresses");
+            result = false;
+        } else {
+            _privateIpDao.deleteByNetworkId(networkId);
+            s_logger.debug("Deleted ip range for private network id=" + networkId);
+        }
+        return result;
+    }
+
+    public class NetworkGarbageCollector extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            final GlobalLock gcLock = GlobalLock.getInternLock("Network.GC.Lock");
+            try {
+                if (gcLock.lock(3)) {
+                    try {
+                        reallyRun();
+                    } finally {
+                        gcLock.unlock();
+                    }
+                }
+            } finally {
+                gcLock.releaseRef();
+            }
+        }
+
+        public void reallyRun() {
+            try {
+                final List<Long> shutdownList = new ArrayList<Long>();
+                final long currentTime = System.currentTimeMillis() / 1000;
+                final HashMap<Long, Long> stillFree = new HashMap<Long, Long>();
+
+                final List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
+                final int netGcWait = NumbersUtil.parseInt(_configDao.getValue(NetworkGcWait.key()), 60);
+                s_logger.info("NetworkGarbageCollector uses '" + netGcWait + "' seconds for GC interval.");
+
+                for (final Long networkId : networkIds) {
+
+                    if (!_networkModel.isNetworkReadyForGc(networkId)) {
+                        continue;
+                    }
+
+                    final Long time = _lastNetworkIdsToFree.remove(networkId);
+                    if (time == null) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("We found network " + networkId + " to be free for the first time.  Adding it to the list: " + currentTime);
+                        }
+                        stillFree.put(networkId, currentTime);
+                    } else if (time > currentTime - netGcWait) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Network " + networkId + " is still free but it's not time to shutdown yet: " + time);
+                        }
+                        stillFree.put(networkId, time);
+                    } else {
+                        shutdownList.add(networkId);
+                    }
+                }
+
+                _lastNetworkIdsToFree = stillFree;
+
+                final CallContext cctx = CallContext.current();
+
+                for (final Long networkId : shutdownList) {
+
+                    // If network is removed, unset gc flag for it
+                    if (_networksDao.findById(networkId) == null) {
+                        s_logger.debug("Network id=" + networkId + " is removed, so clearing up corresponding gc check");
+                        _networksDao.clearCheckForGc(networkId);
+                    } else {
+                        try {
+
+                            final User caller = cctx.getCallingUser();
+                            final Account owner = cctx.getCallingAccount();
+
+                            final ReservationContext context = new ReservationContextImpl(null, null, caller, owner);
+
+                            shutdownNetwork(networkId, context, false);
+                        } catch (final Exception e) {
+                            s_logger.warn("Unable to shutdown network: " + networkId);
+                        }
+                    }
+                }
+            } catch (final Exception e) {
+                s_logger.warn("Caught exception while running network gc: ", e);
+            }
+        }
+    }
+
+    @Override
+    public boolean startNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+
+        // Check if network exists
+        final NetworkVO network = _networksDao.findById(networkId);
+        if (network == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id doesn't exist");
+            ex.addProxyObject(String.valueOf(networkId), "networkId");
+            throw ex;
+        }
+
+        // implement the network
+        s_logger.debug("Starting network " + network + "...");
+        final Pair<NetworkGuru, NetworkVO> implementedNetwork = implementNetwork(networkId, dest, context);
+        if (implementedNetwork== null || implementedNetwork.first() == null) {
+            s_logger.warn("Failed to start the network " + network);
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public boolean restartNetwork(final Long networkId, final Account callerAccount, final User callerUser, final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+
+        final NetworkVO network = _networksDao.findById(networkId);
+
+        s_logger.debug("Restarting network " + networkId + "...");
+
+        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
+        final NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        final DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
+
+        if (cleanup) {
+            if (!rollingRestartRouters(network, offering, dest, context)) {
+                setRestartRequired(network, true);
+                return false;
+            }
+            return true;
+        }
+
+        s_logger.debug("Implementing the network " + network + " elements and resources as a part of network restart without cleanup");
+        try {
+            implementNetworkElementsAndResources(dest, context, network, offering);
+            setRestartRequired(network, true);
+            return true;
+        } catch (final Exception ex) {
+            s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network restart due to ", ex);
+            return false;
+        }
+    }
+
+    @Override
+    public void destroyExpendableRouters(final List<? extends VirtualRouter> routers, final ReservationContext context) throws ResourceUnavailableException {
+        final List<VirtualRouter> remainingRouters = new ArrayList<>();
+        for (final VirtualRouter router : routers) {
+            if (router.getState() == VirtualMachine.State.Stopped ||
+                    router.getState() == VirtualMachine.State.Error ||
+                    router.getState() == VirtualMachine.State.Shutdowned ||
+                    router.getState() == VirtualMachine.State.Unknown) {
+                s_logger.debug("Destroying old router " + router);
+                _routerService.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId());
+            } else {
+                remainingRouters.add(router);
+            }
+        }
+
+        if (remainingRouters.size() < 2) {
+            return;
+        }
+
+        VirtualRouter backupRouter = null;
+        for (final VirtualRouter router : remainingRouters) {
+            if (router.getRedundantState() == VirtualRouter.RedundantState.BACKUP) {
+                backupRouter = router;
+            }
+        }
+        if (backupRouter == null) {
+            backupRouter = routers.get(routers.size() - 1);
+        }
+        if (backupRouter != null) {
+            _routerService.destroyRouter(backupRouter.getId(), context.getAccount(), context.getCaller().getId());
+        }
+    }
+
+    @Override
+    public boolean areRoutersRunning(final List<? extends VirtualRouter> routers) {
+        for (final VirtualRouter router : routers) {
+            if (router.getState() != VirtualMachine.State.Running) {
+                s_logger.debug("Found new router " + router.getInstanceName() + " to be in non-Running state: " + router.getState() + ". Please try restarting network again.");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Cleanup entry on VR file specified by type
+     */
+    @Override
+    public void cleanupNicDhcpDnsEntry(Network network, VirtualMachineProfile vmProfile, NicProfile nicProfile) {
+
+        final List<Provider> networkProviders = getNetworkProviders(network.getId());
+        for (final NetworkElement element : networkElements) {
+            if (networkProviders.contains(element.getProvider())) {
+                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
+                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
+                            + network.getPhysicalNetworkId());
+                }
+                if (vmProfile.getType() == Type.User && element.getProvider() != null) {
+                    if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)
+                            && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) && element instanceof DhcpServiceProvider) {
+                        final DhcpServiceProvider sp = (DhcpServiceProvider) element;
+                        try {
+                            sp.removeDhcpEntry(network, nicProfile, vmProfile);
+                        } catch (ResourceUnavailableException e) {
+                            s_logger.error("Failed to remove dhcp-dns entry due to: ", e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * rollingRestartRouters performs restart of routers of a network by first
+     * deploying a new VR and then destroying old VRs in rolling fashion. For
+     * non-redundant network, it will re-program the new router as final step
+     * otherwise deploys a backup router for the network.
+     * @param network network to be restarted
+     * @param offering network offering
+     * @param dest deployment destination
+     * @param context reservation context
+     * @return returns true when the rolling restart operation succeeds
+     * @throws ResourceUnavailableException
+     * @throws ConcurrentOperationException
+     * @throws InsufficientCapacityException
+     */
+    private boolean rollingRestartRouters(final NetworkVO network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+        if (!NetworkOrchestrationService.RollingRestartEnabled.value()) {
+            if (shutdownNetworkElementsAndResources(context, true, network)) {
+                implementNetworkElementsAndResources(dest, context, network, offering);
+                return true;
+            }
+            s_logger.debug("Failed to shutdown the network elements and resources as a part of network restart: " + network.getState());
+            return false;
+        }
+        s_logger.debug("Performing rolling restart of routers of network " + network);
+        destroyExpendableRouters(_routerDao.findByNetwork(network.getId()), context);
+
+        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
+        final List<DomainRouterVO> oldRouters = _routerDao.findByNetwork(network.getId());
+
+        // Deploy a new router
+        if (oldRouters.size() > 0) {
+            network.setRollingRestart(true);
+        }
+        implementNetworkElements(dest, context, network, offering, providersToImplement);
+        if (oldRouters.size() > 0) {
+            network.setRollingRestart(false);
+        }
+
+        // For redundant network wait for 3*advert_int+skew_seconds for VRRP to kick in
+        if (network.isRedundant() || (oldRouters.size() == 1 && oldRouters.get(0).getIsRedundantRouter())) {
+            try {
+                Thread.sleep(NetworkOrchestrationService.RVRHandoverTime);
+            } catch (final InterruptedException ignored) {}
+        }
+
+        // Destroy old routers
+        for (final DomainRouterVO oldRouter : oldRouters) {
+            _routerService.stopRouter(oldRouter.getId(), true);
+            _routerService.destroyRouter(oldRouter.getId(), context.getAccount(), context.getCaller().getId());
+        }
+
+        if (network.isRedundant()) {
+            // Add a new backup router for redundant network
+            implementNetworkElements(dest, context, network, offering, providersToImplement);
+        } else {
+            // Re-apply rules for non-redundant network
+            implementNetworkElementsAndResources(dest, context, network, offering);
+        }
+
+        return areRoutersRunning(_routerDao.findByNetwork(network.getId()));
+    }
+
+    private void setRestartRequired(final NetworkVO network, final boolean restartRequired) {
+        s_logger.debug("Marking network " + network + " with restartRequired=" + restartRequired);
+        network.setRestartRequired(restartRequired);
+        _networksDao.update(network.getId(), network);
+    }
+
+    protected int getActiveNicsInNetwork(final long networkId) {
+        return _networksDao.getActiveNicsIn(networkId);
+    }
+
+    @Override
+    public NetworkProfile convertNetworkToNetworkProfile(final long networkId) {
+        final NetworkVO network = _networksDao.findById(networkId);
+        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+        final NetworkProfile profile = new NetworkProfile(network);
+        guru.updateNetworkProfile(profile);
+
+        return profile;
+    }
+
+    @Override
+    public UserDataServiceProvider getPasswordResetProvider(final Network network) {
+        final String passwordProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
+
+        if (passwordProvider == null) {
+            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
+            return null;
+        }
+
+        return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(passwordProvider);
+    }
+
+    @Override
+    public UserDataServiceProvider getSSHKeyResetProvider(final Network network) {
+        final String SSHKeyProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
+
+        if (SSHKeyProvider == null) {
+            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
+            return null;
+        }
+
+        return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(SSHKeyProvider);
+    }
+
+    @Override
+    public DhcpServiceProvider getDhcpServiceProvider(final Network network) {
+        final String DhcpProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
+
+        if (DhcpProvider == null) {
+            s_logger.debug("Network " + network + " doesn't support service " + Service.Dhcp.getName());
+            return null;
+        }
+
+        final NetworkElement element = _networkModel.getElementImplementingProvider(DhcpProvider);
+        if ( element instanceof DhcpServiceProvider ) {
+            return (DhcpServiceProvider)element;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public DnsServiceProvider getDnsServiceProvider(final Network network) {
+        final String dnsProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Dns);
+
+        if (dnsProvider == null) {
+            s_logger.debug("Network " + network + " doesn't support service " + Service.Dhcp.getName());
+            return null;
+        }
+
+        return  (DnsServiceProvider) _networkModel.getElementImplementingProvider(dnsProvider);
+    }
+
+    protected boolean isSharedNetworkWithServices(final Network network) {
+        assert network != null;
+        final DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        if (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced
+                && isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+            return true;
+        }
+        return false;
+    }
+
+    protected boolean isSharedNetworkOfferingWithServices(final long networkOfferingId) {
+        final NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
+        if (networkOffering.getGuestType() == Network.GuestType.Shared
+                && (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
+                                networkOfferingId, Service.Lb))) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public List<? extends Nic> listVmNics(final long vmId, final Long nicId, final Long networkId, String keyword) {
+        List<NicVO> result = null;
+
+        if (keyword == null || keyword.isEmpty()) {
+            if (nicId == null && networkId == null) {
+                result = _nicDao.listByVmId(vmId);
+            } else {
+                result = _nicDao.listByVmIdAndNicIdAndNtwkId(vmId, nicId, networkId);
+            }
+        } else {
+            result = _nicDao.listByVmIdAndKeyword(vmId, keyword);
+        }
+
+        for (final NicVO nic : result) {
+            if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) {
+                //For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result
+                s_logger.info("Listing NSX logical switch and logical switch por for each nic");
+                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+                final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+                final NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru;
+
+                final Map<String, ? extends Object> nsxParams = guruFunctions.listAdditionalNicParams(nic.getUuid());
+                if (nsxParams != null){
+                    final String lswitchUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID)
+                            ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) : null;
+                    final String lswitchPortUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID)
+                            ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) : null;
+                    nic.setNsxLogicalSwitchUuid(lswitchUuuid);
+                    nic.setNsxLogicalSwitchPortUuid(lswitchPortUuuid);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @DB
+    @Override
+    public boolean reallocate(final VirtualMachineProfile vm, final DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException {
+        final VMInstanceVO vmInstance = _vmDao.findById(vm.getId());
+        final DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
+        if (dc.getNetworkType() == NetworkType.Basic) {
+            final List<NicVO> nics = _nicDao.listByVmId(vmInstance.getId());
+            final NetworkVO network = _networksDao.findById(nics.get(0).getNetworkId());
+            final LinkedHashMap<Network, List<? extends NicProfile>> profiles = new LinkedHashMap<Network, List<? extends NicProfile>>();
+            profiles.put(network, new ArrayList<NicProfile>());
+
+            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
+                    cleanupNics(vm);
+                    allocate(vm, profiles, null);
+                }
+            });
+        }
+        return true;
+    }
+
+    private boolean cleanupNetworkResources(final long networkId, final Account caller, final long callerUserId) {
+        boolean success = true;
+        final Network network = _networksDao.findById(networkId);
+
+        //remove all PF/Static Nat rules for the network
+        try {
+            if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, callerUserId, caller)) {
+                s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId);
+            } else {
+                success = false;
+                s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup");
+            }
+        } catch (final ResourceUnavailableException ex) {
+            success = false;
+            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
+            s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
+        }
+
+        //remove all LB rules for the network
+        if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, callerUserId)) {
+            s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId);
+        } else {
+            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
+            success = false;
+            s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
+        }
+
+        //revoke all firewall rules for the network
+        try {
+            if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, callerUserId, caller)) {
+                s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
+            } else {
+                success = false;
+                s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup");
+            }
+        } catch (final ResourceUnavailableException ex) {
+            success = false;
+            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
+            s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
+        }
+
+        //revoke all network ACLs for network
+        try {
+            if (_networkACLMgr.revokeACLItemsForNetwork(networkId)) {
+                s_logger.debug("Successfully cleaned up NetworkACLs for network id=" + networkId);
+            } else {
+                success = false;
+                s_logger.warn("Failed to cleanup NetworkACLs as a part of network id=" + networkId + " cleanup");
+            }
+        } catch (final ResourceUnavailableException ex) {
+            success = false;
+            s_logger.warn("Failed to cleanup Network ACLs as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
+        }
+
+        //release all ip addresses
+        final List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null);
+        for (final IPAddressVO ipToRelease : ipsToRelease) {
+            if (ipToRelease.getVpcId() == null) {
+                if (!ipToRelease.isPortable()) {
+                    final IPAddressVO ip = _ipAddrMgr.markIpAsUnavailable(ipToRelease.getId());
+                    assert ip != null : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable.";
+                } else {
+                    // portable IP address are associated with owner, until explicitly requested to be disassociated
+                    // so as part of network clean up just break IP association with guest network
+                    ipToRelease.setAssociatedWithNetworkId(null);
+                    _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
+                    s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any network");
+                }
+            } else {
+                _vpcMgr.unassignIPFromVpcNetwork(ipToRelease.getId(), network.getId());
+            }
+        }
+
+        try {
+            if (!_ipAddrMgr.applyIpAssociations(network, true)) {
+                s_logger.warn("Unable to apply ip address associations for " + network);
+                success = false;
+            }
+        } catch (final ResourceUnavailableException e) {
+            throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
+        }
+
+        return success;
+    }
+
+    private boolean shutdownNetworkResources(final long networkId, final Account caller, final long callerUserId) {
+        // This method cleans up network rules on the backend w/o touching them in the DB
+        boolean success = true;
+        final Network network = _networksDao.findById(networkId);
+
+        // Mark all PF rules as revoked and apply them on the backend (not in the DB)
+        final List<PortForwardingRuleVO> pfRules = _portForwardingRulesDao.listByNetwork(networkId);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+        }
+
+        for (final PortForwardingRuleVO pfRule : pfRules) {
+            s_logger.trace("Marking pf rule " + pfRule + " with Revoke state");
+            pfRule.setState(FirewallRule.State.Revoke);
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(pfRules, true, false)) {
+                s_logger.warn("Failed to cleanup pf rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup pf rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        // Mark all static rules as revoked and apply them on the backend (not in the DB)
+        final List<FirewallRuleVO> firewallStaticNatRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
+        final List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + firewallStaticNatRules.size() + " static nat rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+        }
+
+        for (final FirewallRuleVO firewallStaticNatRule : firewallStaticNatRules) {
+            s_logger.trace("Marking static nat rule " + firewallStaticNatRule + " with Revoke state");
+            final IpAddress ip = _ipAddressDao.findById(firewallStaticNatRule.getSourceIpAddressId());
+            final FirewallRuleVO ruleVO = _firewallDao.findById(firewallStaticNatRule.getId());
+
+            if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) {
+                throw new InvalidParameterValueException("Source ip address of the rule id=" + firewallStaticNatRule.getId() + " is not static nat enabled");
+            }
+
+            //String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), firewallStaticNatRule.getNetworkId());
+            ruleVO.setState(FirewallRule.State.Revoke);
+            staticNatRules.add(new StaticNatRuleImpl(ruleVO, ip.getVmIp()));
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(staticNatRules, true, false)) {
+                s_logger.warn("Failed to cleanup static nat rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup static nat rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        try {
+            if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Public)) {
+                s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        try {
+            if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Internal)) {
+                s_logger.warn("Failed to cleanup internal lb rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        // revoke all firewall rules for the network w/o applying them on the DB
+        final List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + firewallRules.size() + " firewall ingress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+        }
+
+        for (final FirewallRuleVO firewallRule : firewallRules) {
+            s_logger.trace("Marking firewall ingress rule " + firewallRule + " with Revoke state");
+            firewallRule.setState(FirewallRule.State.Revoke);
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(firewallRules, true, false)) {
+                s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        final List<FirewallRuleVO> firewallEgressRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + firewallEgressRules.size() + " firewall egress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+        }
+
+        try {
+            // delete default egress rule
+            final DataCenter zone = _dcDao.findById(network.getDataCenterId());
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall)
+                    && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
+                // add default egress rule to accept the traffic
+                _firewallMgr.applyDefaultEgressFirewallRule(network.getId(), _networkModel.getNetworkEgressDefaultPolicy(networkId), false);
+            }
+
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup firewall default egress rule as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        for (final FirewallRuleVO firewallRule : firewallEgressRules) {
+            s_logger.trace("Marking firewall egress rule " + firewallRule + " with Revoke state");
+            firewallRule.setState(FirewallRule.State.Revoke);
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(firewallEgressRules, true, false)) {
+                s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        if (network.getVpcId() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Releasing Network ACL Items for network id=" + networkId + " as a part of shutdownNetworkRules");
+            }
+
+            try {
+                //revoke all Network ACLs for the network w/o applying them in the DB
+                if (!_networkACLMgr.revokeACLItemsForNetwork(networkId)) {
+                    s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules");
+                    success = false;
+                }
+            } catch (final ResourceUnavailableException ex) {
+                s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules due to ", ex);
+                success = false;
+            }
+
+        }
+
+        //release all static nats for the network
+        if (!_rulesMgr.applyStaticNatForNetwork(networkId, false, caller, true)) {
+            s_logger.warn("Failed to disable static nats as part of shutdownNetworkRules for network id " + networkId);
+            success = false;
+        }
+
+        // Get all ip addresses, mark as releasing and release them on the backend
+        final List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(networkId, null);
+        final List<PublicIp> publicIpsToRelease = new ArrayList<PublicIp>();
+        if (userIps != null && !userIps.isEmpty()) {
+            for (final IPAddressVO userIp : userIps) {
+                userIp.setState(IpAddress.State.Releasing);
+                final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                publicIpsToRelease.add(publicIp);
+            }
+        }
+
+        try {
+            if (!_ipAddrMgr.applyIpAssociations(network, true, true, publicIpsToRelease)) {
+                s_logger.warn("Unable to apply ip address associations for " + network + " as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (final ResourceUnavailableException e) {
+            throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
+        }
+
+        return success;
+    }
+
+    @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;
+    }
+
+    public void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(final Host host, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
+        if (!(cmd instanceof StartupRoutingCommand)) {
+            return;
+        }
+        final long hostId = host.getId();
+        final StartupRoutingCommand startup = (StartupRoutingCommand)cmd;
+
+        final String dataCenter = startup.getDataCenter();
+
+        long dcId = -1;
+        DataCenterVO dc = _dcDao.findByName(dataCenter);
+        if (dc == null) {
+            try {
+                dcId = Long.parseLong(dataCenter);
+                dc = _dcDao.findById(dcId);
+            } catch (final NumberFormatException e) {
+            }
+        }
+        if (dc == null) {
+            throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
+        }
+        dcId = dc.getId();
+        final HypervisorType hypervisorType = startup.getHypervisorType();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Host's hypervisorType is: " + hypervisorType);
+        }
+
+        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+
+        // list all physicalnetworks in the zone & for each get the network names
+        final List<PhysicalNetworkVO> physicalNtwkList = _physicalNetworkDao.listByZone(dcId);
+        for (final PhysicalNetworkVO pNtwk : physicalNtwkList) {
+            final String publicName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Public, hypervisorType);
+            final String privateName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Management, hypervisorType);
+            final String guestName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Guest, hypervisorType);
+            final String storageName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Storage, hypervisorType);
+            // String controlName = _pNTrafficTypeDao._networkModel.getNetworkTag(pNtwk.getId(), TrafficType.Control, hypervisorType);
+            final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
+            info.setPhysicalNetworkId(pNtwk.getId());
+            info.setGuestNetworkName(guestName);
+            info.setPrivateNetworkName(privateName);
+            info.setPublicNetworkName(publicName);
+            info.setStorageNetworkName(storageName);
+            final PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(pNtwk.getId(), TrafficType.Management);
+            if (mgmtTraffic != null) {
+                final String vlan = mgmtTraffic.getVlan();
+                info.setMgmtVlan(vlan);
+            }
+            networkInfoList.add(info);
+        }
+
+        // send the names to the agent
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Sending CheckNetworkCommand to check the Network is setup correctly on Agent");
+        }
+        final CheckNetworkCommand nwCmd = new CheckNetworkCommand(networkInfoList);
+
+        final CheckNetworkAnswer answer = (CheckNetworkAnswer)_agentMgr.easySend(hostId, nwCmd);
+
+        if (answer == null) {
+            s_logger.warn("Unable to get an answer to the CheckNetworkCommand from agent:" + host.getId());
+            throw new ConnectionException(true, "Unable to get an answer to the CheckNetworkCommand from agent: " + host.getId());
+        }
+
+        if (!answer.getResult()) {
+            s_logger.warn("Unable to setup agent " + hostId + " due to " + answer.getDetails() );
+            final String msg = "Incorrect Network setup on agent, Reinitialize agent after network names are setup, details : " + answer.getDetails();
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, host.getPodId(), msg, msg);
+            throw new ConnectionException(true, msg);
+        } else {
+            if (answer.needReconnect()) {
+                throw new ConnectionException(false, "Reinitialize agent after network setup.");
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Network setup is correct on Agent");
+            }
+            return;
+        }
+    }
+
+    @Override
+    public boolean processDisconnect(final long agentId, final Status state) {
+        return false;
+    }
+
+    @Override
+    public void processHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void processHostRemoved(long hostId, long clusterId) {
+    }
+
+    @Override
+    public boolean isRecurring() {
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(final long agentId, final long seq) {
+        return false;
+    }
+
+    @Override
+    public Map<String, String> finalizeServicesAndProvidersForNetwork(final NetworkOffering offering, final Long physicalNetworkId) {
+        final Map<String, String> svcProviders = new HashMap<String, String>();
+        final Map<String, List<String>> providerSvcs = new HashMap<String, List<String>>();
+        final List<NetworkOfferingServiceMapVO> servicesMap = _ntwkOfferingSrvcDao.listByNetworkOfferingId(offering.getId());
+
+        final boolean checkPhysicalNetwork = physicalNetworkId != null ? true : false;
+
+        for (final NetworkOfferingServiceMapVO serviceMap : servicesMap) {
+            if (svcProviders.containsKey(serviceMap.getService())) {
+                // FIXME - right now we pick up the first provider from the list, need to add more logic based on
+                // provider load, etc
+                continue;
+            }
+
+            final String service = serviceMap.getService();
+            String provider = serviceMap.getProvider();
+
+            if (provider == null) {
+                provider = _networkModel.getDefaultUniqueProviderForService(service).getName();
+            }
+
+            // check that provider is supported
+            if (checkPhysicalNetwork) {
+                if (!_pNSPDao.isServiceProviderEnabled(physicalNetworkId, provider, service)) {
+                    throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't " + "support service " + service + " in physical network id="
+                            + physicalNetworkId);
+                }
+            }
+
+            svcProviders.put(service, provider);
+            List<String> l = providerSvcs.get(provider);
+            if (l == null) {
+                providerSvcs.put(provider, l = new ArrayList<String>());
+            }
+            l.add(service);
+        }
+
+        return svcProviders;
+    }
+
+    private List<Provider> getNetworkProviders(final long networkId) {
+        final List<String> providerNames = _ntwkSrvcDao.getDistinctProviders(networkId);
+        final List<Provider> providers = new ArrayList<Provider>();
+        for (final String providerName : providerNames) {
+            providers.add(Network.Provider.getProvider(providerName));
+        }
+
+        return providers;
+    }
+
+    @Override
+    public boolean setupDns(final Network network, final Provider provider) {
+        final boolean dnsProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, provider);
+        final boolean dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, provider);
+
+        final boolean setupDns = dnsProvided || dhcpProvided;
+        return setupDns;
+    }
+
+    protected NicProfile getNicProfileForVm(final Network network, final NicProfile requested, final VirtualMachine vm) {
+        NicProfile nic = null;
+        if (requested != null && requested.getBroadCastUri() != null) {
+            final String broadcastUri = requested.getBroadCastUri().toString();
+            final String ipAddress = requested.getIPv4Address();
+            final NicVO nicVO = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri);
+            if (nicVO != null) {
+                if (ipAddress == null || nicVO.getIPv4Address().equals(ipAddress)) {
+                    nic = _networkModel.getNicProfile(vm, network.getId(), broadcastUri);
+                }
+            }
+        } else {
+            final NicVO nicVO = _nicDao.findByNtwkIdAndInstanceId(network.getId(), vm.getId());
+            if (nicVO != null) {
+                nic = _networkModel.getNicProfile(vm, network.getId(), null);
+            }
+        }
+        return nic;
+    }
+
+    @Override
+    public NicProfile createNicForVm(final Network network, final NicProfile requested, final ReservationContext context, final VirtualMachineProfile vmProfile, final boolean prepare)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
+            ResourceUnavailableException {
+
+        final VirtualMachine vm = vmProfile.getVirtualMachine();
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        final Host host = _hostDao.findById(vm.getHostId());
+        final DeployDestination dest = new DeployDestination(dc, null, null, host);
+
+        NicProfile nic = getNicProfileForVm(network, requested, vm);
+
+        //1) allocate nic (if needed) Always allocate if it is a user vm
+        if (nic == null || vmProfile.getType() == VirtualMachine.Type.User) {
+            final int deviceId = _nicDao.getFreeDeviceId(vm.getId());
+
+            nic = allocateNic(requested, network, false, deviceId, vmProfile).first();
+
+            if (nic == null) {
+                throw new CloudRuntimeException("Failed to allocate nic for vm " + vm + " in network " + network);
+            }
+
+            //Update vm_network_map table
+            if(vmProfile.getType() == VirtualMachine.Type.User) {
+                final VMNetworkMapVO vno = new VMNetworkMapVO(vm.getId(), network.getId());
+                _vmNetworkMapDao.persist(vno);
+            }
+            s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network);
+        }
+
+        //2) prepare nic
+        if (prepare) {
+            final Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
+            if (implemented == null || implemented.first() == null) {
+                s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
+                throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
+            }
+            nic = prepareNic(vmProfile, dest, context, nic.getId(), implemented.second());
+            s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network);
+        }
+
+        return nic;
+    }
+
+    @Override
+    public List<NicProfile> getNicProfiles(final VirtualMachine vm) {
+        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        final List<NicProfile> profiles = new ArrayList<NicProfile>();
+
+        if (nics != null) {
+            for (final Nic nic : nics) {
+                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
+                final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
+
+                final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
+                final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate,
+                        _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
+                guru.updateNicProfile(profile, network);
+                profiles.add(profile);
+            }
+        }
+        return profiles;
+    }
+
+    @Override
+    public Map<String, String> getSystemVMAccessDetails(final VirtualMachine vm) {
+        final Map<String, String> accessDetails = new HashMap<>();
+        accessDetails.put(NetworkElementCommand.ROUTER_NAME, vm.getInstanceName());
+        String privateIpAddress = null;
+        for (final NicProfile profile : getNicProfiles(vm)) {
+            if (profile == null) {
+                continue;
+            }
+            final Network network = _networksDao.findById(profile.getNetworkId());
+            if (network == null) {
+                continue;
+            }
+            final String address = profile.getIPv4Address();
+            if (network.getTrafficType() == Networks.TrafficType.Control) {
+                accessDetails.put(NetworkElementCommand.ROUTER_IP, address);
+            }
+            if (network.getTrafficType() == Networks.TrafficType.Guest) {
+                accessDetails.put(NetworkElementCommand.ROUTER_GUEST_IP, address);
+            }
+            if (network.getTrafficType() == Networks.TrafficType.Management) {
+                privateIpAddress = address;
+            }
+            if (network.getTrafficType() != null && !Strings.isNullOrEmpty(address)) {
+                accessDetails.put(network.getTrafficType().name(), address);
+            }
+        }
+        if (privateIpAddress != null && Strings.isNullOrEmpty(accessDetails.get(NetworkElementCommand.ROUTER_IP))) {
+            accessDetails.put(NetworkElementCommand.ROUTER_IP,  privateIpAddress);
+        }
+        return accessDetails;
+    }
+
+    protected boolean stateTransitTo(final NetworkVO network, final Network.Event e) throws NoTransitionException {
+        return _stateMachine.transitTo(network, e, null, _networksDao);
+    }
+
+    private void setStateMachine() {
+        _stateMachine = Network.State.getStateMachine();
+    }
+
+    private Map<Service, Set<Provider>> getServiceProvidersMap(final long networkId) {
+        final Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
+        final List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
+        for (final NetworkServiceMapVO nsm : nsms) {
+            Set<Provider> providers = map.get(Service.getService(nsm.getService()));
+            if (providers == null) {
+                providers = new HashSet<Provider>();
+            }
+            providers.add(Provider.getProvider(nsm.getProvider()));
+            map.put(Service.getService(nsm.getService()), providers);
+        }
+        return map;
+    }
+
+    @Override
+    public List<Provider> getProvidersForServiceInNetwork(final Network network, final Service service) {
+        final Map<Service, Set<Provider>> service2ProviderMap = getServiceProvidersMap(network.getId());
+        if (service2ProviderMap.get(service) != null) {
+            final List<Provider> providers = new ArrayList<Provider>(service2ProviderMap.get(service));
+            return providers;
+        }
+        return null;
+    }
+
+    protected List<NetworkElement> getElementForServiceInNetwork(final Network network, final Service service) {
+        final List<NetworkElement> elements = new ArrayList<NetworkElement>();
+        final List<Provider> providers = getProvidersForServiceInNetwork(network, service);
+        //Only support one provider now
+        if (providers == null) {
+            s_logger.error("Cannot find " + service.getName() + " provider for network " + network.getId());
+            return null;
+        }
+        if (providers.size() != 1 && service != Service.Lb) {
+            //support more than one LB providers only
+            s_logger.error("Found " + providers.size() + " " + service.getName() + " providers for network!" + network.getId());
+            return null;
+        }
+
+        for (final Provider provider : providers) {
+            final NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
+            s_logger.info("Let " + element.getName() + " handle " + service.getName() + " in network " + network.getId());
+            elements.add(element);
+        }
+        return elements;
+    }
+
+    @Override
+    public StaticNatServiceProvider getStaticNatProviderForNetwork(final Network network) {
+        //only one provider per Static nat service is supoprted
+        final NetworkElement element = getElementForServiceInNetwork(network, Service.StaticNat).get(0);
+        assert element instanceof StaticNatServiceProvider;
+        return (StaticNatServiceProvider)element;
+    }
+
+    @Override
+    public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(final Network network, final Scheme lbScheme) {
+        final List<NetworkElement> lbElements = getElementForServiceInNetwork(network, Service.Lb);
+        NetworkElement lbElement = null;
+        if (lbElements.size() > 1) {
+            String providerName = null;
+            //get network offering details
+            final NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+            if (lbScheme == Scheme.Public) {
+                providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.PublicLbProvider);
+            } else {
+                providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.InternalLbProvider);
+            }
+            if (providerName == null) {
+                throw new InvalidParameterValueException("Can't find Lb provider supporting scheme " + lbScheme.toString() + " in network " + network);
+            }
+            lbElement = _networkModel.getElementImplementingProvider(providerName);
+        } else if (lbElements.size() == 1) {
+            lbElement = lbElements.get(0);
+        }
+
+        assert lbElement != null;
+        assert lbElement instanceof LoadBalancingServiceProvider;
+        return (LoadBalancingServiceProvider)lbElement;
+    }
+
+    @Override
+    public boolean isNetworkInlineMode(final Network network) {
+        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        return offering.isInline();
+    }
+
+    @Override
+    public boolean isSecondaryIpSetForNic(final long nicId) {
+        final NicVO nic = _nicDao.findById(nicId);
+        return nic.getSecondaryIp();
+    }
+
+    private boolean removeVmSecondaryIpsOfNic(final long nicId) {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                final List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
+                if (ipList != null) {
+                    for (final NicSecondaryIpVO ip : ipList) {
+                        _nicSecondaryIpDao.remove(ip.getId());
+                    }
+                    s_logger.debug("Revoving nic secondary ip entry ...");
+                }
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    public NicVO savePlaceholderNic(final Network network, final String ip4Address, final String ip6Address, final Type vmType) {
+        final NicVO nic = new NicVO(null, null, network.getId(), null);
+        nic.setIPv4Address(ip4Address);
+        nic.setIPv6Address(ip6Address);
+        nic.setReservationStrategy(ReservationStrategy.PlaceHolder);
+        nic.setState(Nic.State.Reserved);
+        nic.setVmType(vmType);
+        return _nicDao.persist(nic);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return NetworkOrchestrationService.class.getSimpleName();
+    }
+
+    public static final ConfigKey<Integer> NetworkGcWait = new ConfigKey<Integer>(Integer.class, "network.gc.wait", "Advanced", "600",
+            "Time (in seconds) to wait before shutting down a network that's not in used", false, Scope.Global, null);
+    public static final ConfigKey<Integer> NetworkGcInterval = new ConfigKey<Integer>(Integer.class, "network.gc.interval", "Advanced", "600",
+            "Seconds to wait before checking for networks to shutdown", true, Scope.Global, null);
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
+                GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
+                PromiscuousMode, MacAddressChanges, ForgedTransmits, RollingRestartEnabled};
+    }
+}
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
new file mode 100644
index 0000000..6e71864
--- /dev/null
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -0,0 +1,1629 @@
+/*
+ * 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.engine.orchestration;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.storage.VolumeApiService;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
+import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+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;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.manager.allocator.PodAllocator;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientStorageCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.org.Cluster;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.UserVmCloneSettingVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachineProfileImpl;
+import com.cloud.vm.VmWorkAttachVolume;
+import com.cloud.vm.VmWorkMigrateVolume;
+import com.cloud.vm.VmWorkSerializer;
+import com.cloud.vm.VmWorkTakeVolumeSnapshot;
+import com.cloud.vm.dao.UserVmCloneSettingDao;
+import com.cloud.vm.dao.UserVmDao;
+
+public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable {
+
+    public enum UserVmCloneType {
+        full, linked
+    }
+
+    private static final Logger s_logger = Logger.getLogger(VolumeOrchestrator.class);
+
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    protected TemplateManager _tmpltMgr;
+    @Inject
+    protected VolumeDao _volsDao;
+    @Inject
+    protected PrimaryDataStoreDao _storagePoolDao = null;
+    @Inject
+    protected TemplateDataStoreDao _vmTemplateStoreDao = null;
+    @Inject
+    protected VolumeDao _volumeDao;
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    @Inject
+    protected SnapshotDataStoreDao _snapshotDataStoreDao;
+    @Inject
+    protected ResourceLimitService _resourceLimitMgr;
+    @Inject
+    VolumeDetailsDao _volDetailDao;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    VolumeService volService;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    TemplateDataFactory tmplFactory;
+    @Inject
+    SnapshotDataFactory snapshotFactory;
+    @Inject
+    ConfigDepot _configDepot;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    SnapshotService _snapshotSrv;
+    @Inject
+    protected UserVmDao _userVmDao;
+    @Inject
+    protected AsyncJobManager _jobMgr;
+    @Inject
+    ClusterManager clusterManager;
+    @Inject
+    StorageManager storageMgr;
+    @Inject
+    protected UserVmCloneSettingDao _vmCloneSettingDao;
+    @Inject
+    StorageStrategyFactory _storageStrategyFactory;
+
+    private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
+    protected List<StoragePoolAllocator> _storagePoolAllocators;
+
+    public List<StoragePoolAllocator> getStoragePoolAllocators() {
+        return _storagePoolAllocators;
+    }
+
+    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
+        _storagePoolAllocators = storagePoolAllocators;
+    }
+
+    protected List<PodAllocator> _podAllocators;
+
+    public List<PodAllocator> getPodAllocators() {
+        return _podAllocators;
+    }
+
+    public void setPodAllocators(List<PodAllocator> podAllocators) {
+        _podAllocators = podAllocators;
+    }
+
+    protected VolumeOrchestrator() {
+        _volStateMachine = Volume.State.getStateMachine();
+    }
+
+    @Override
+    public VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType)
+            throws ConcurrentOperationException, StorageUnavailableException {
+
+        // Find a destination storage pool with the specified criteria
+        DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
+        DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
+                diskOffering.isUseLocalStorage(), diskOffering.isRecreatable(), null);
+        dskCh.setHyperType(dataDiskHyperType);
+        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
+
+        DataCenter destPoolDataCenter = _entityMgr.findById(DataCenter.class, destPoolDcId);
+        Pod destPoolPod = _entityMgr.findById(Pod.class, destPoolPodId);
+
+        StoragePool destPool = findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, null, new HashSet<StoragePool>());
+
+        if (destPool == null) {
+            throw new CloudRuntimeException("Failed to find a storage pool with enough capacity to move the volume to.");
+        }
+
+        Volume newVol = migrateVolume(volume, destPool);
+        return volFactory.getVolume(newVol.getId());
+    }
+
+    @Override
+    public Volume allocateDuplicateVolume(Volume oldVol, Long templateId) {
+        return allocateDuplicateVolumeVO(oldVol, templateId);
+    }
+
+    public VolumeVO allocateDuplicateVolumeVO(Volume oldVol, Long templateId) {
+        VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(),
+                oldVol.getProvisioningType(), oldVol.getSize(), oldVol.getMinIops(), oldVol.getMaxIops(), oldVol.get_iScsiName());
+        if (templateId != null) {
+            newVol.setTemplateId(templateId);
+        } else {
+            newVol.setTemplateId(oldVol.getTemplateId());
+        }
+        newVol.setDeviceId(oldVol.getDeviceId());
+        newVol.setInstanceId(oldVol.getInstanceId());
+        newVol.setRecreatable(oldVol.isRecreatable());
+        newVol.setFormat(oldVol.getFormat());
+        return _volsDao.persist(newVol);
+    }
+
+    @Override
+    public StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, final Set<StoragePool> avoid) {
+        Long podId = null;
+        if (pod != null) {
+            podId = pod.getId();
+        } else if (clusterId != null) {
+            Cluster cluster = _entityMgr.findById(Cluster.class, clusterId);
+            if (cluster != null) {
+                podId = cluster.getPodId();
+            }
+        }
+
+        VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+        for (StoragePoolAllocator allocator : _storagePoolAllocators) {
+
+            ExcludeList avoidList = new ExcludeList();
+            for (StoragePool pool : avoid) {
+                avoidList.addPool(pool.getId());
+            }
+            DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null);
+
+            final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1);
+            if (poolList != null && !poolList.isEmpty()) {
+                return (StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
+            }
+        }
+        return null;
+    }
+
+    public Pair<Pod, Long> findPod(VirtualMachineTemplate template, ServiceOffering offering, DataCenter dc, long accountId, Set<Long> avoids) {
+        for (PodAllocator allocator : _podAllocators) {
+            final Pair<Pod, Long> pod = allocator.allocateTo(template, offering, dc, accountId, avoids);
+            if (pod != null) {
+                return pod;
+            }
+        }
+        return null;
+    }
+
+    @DB
+    @Override
+    public VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, UserVm vm) throws StorageUnavailableException {
+        Account account = _entityMgr.findById(Account.class, volume.getAccountId());
+
+        final HashSet<StoragePool> poolsToAvoid = new HashSet<StoragePool>();
+        StoragePool pool = null;
+
+        Set<Long> podsToAvoid = new HashSet<Long>();
+        Pair<Pod, Long> pod = null;
+
+        DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
+        DataCenter dc = _entityMgr.findById(DataCenter.class, volume.getDataCenterId());
+        DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
+
+        String msg = "There are no available storage pools to store the volume in";
+
+        if (vm != null) {
+            Pod podofVM = _entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
+            if (podofVM != null) {
+                pod = new Pair<Pod, Long>(podofVM, podofVM.getId());
+            }
+        }
+
+        if (vm != null && pod != null) {
+            //if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
+            Long hostId = null;
+            Long clusterId = null;
+            if (vm.getState() == State.Running) {
+                hostId = vm.getHostId();
+                if (hostId != null) {
+                    Host vmHost = _entityMgr.findById(Host.class, hostId);
+                    clusterId = vmHost.getClusterId();
+                }
+            } else {
+                List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
+                if (rootVolumesOfVm.size() != 1) {
+                    throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
+                } else {
+                    VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
+                    StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
+                    clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
+                }
+            }
+            // Determine what storage pool to store the volume in
+            while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
+                break;
+            }
+
+            if (pool == null) {
+                //pool could not be found in the VM's pod/cluster.
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
+                }
+                StringBuilder addDetails = new StringBuilder(msg);
+                addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
+                addDetails.append(vm.getUuid());
+                msg = addDetails.toString();
+            }
+        } else {
+            // Determine what pod to store the volume in
+            while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
+                podsToAvoid.add(pod.first().getId());
+                // Determine what storage pool to store the volume in
+                while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
+                    break;
+                }
+
+                if (pool != null) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
+                    }
+                    break;
+                }
+            }
+        }
+
+        if (pool == null) {
+            s_logger.info(msg);
+            throw new StorageUnavailableException(msg, -1);
+        }
+
+        VolumeInfo vol = volFactory.getVolume(volume.getId());
+        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+        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 {
+                // sync snapshot to region store if necessary
+                DataStore snapStore = snapInfo.getDataStore();
+                long snapVolId = snapInfo.getVolumeId();
+
+                _snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
+            } catch (Exception ex) {
+                // log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
+                s_logger.warn(ex.getMessage(), ex);
+            }
+        }
+
+        // create volume on primary from snapshot
+        AsyncCallFuture<VolumeApiResult> future = volService.createVolumeFromSnapshot(vol, store, snapInfo);
+        try {
+            VolumeApiResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
+                throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
+            }
+            return result.getVolume();
+        } catch (InterruptedException e) {
+            s_logger.debug("Failed to create volume from snapshot", e);
+            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
+        } catch (ExecutionException e) {
+            s_logger.debug("Failed to create volume from snapshot", e);
+            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
+        }
+
+    }
+
+    public DataStoreRole getDataStoreRole(Snapshot snapshot) {
+        SnapshotDataStoreVO snapshotStore = _snapshotDataStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+        if (snapshotStore == null) {
+            return DataStoreRole.Image;
+        }
+
+        long storagePoolId = snapshotStore.getDataStoreId();
+        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
+
+        if (mapCapabilities != null) {
+            String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
+            Boolean supportsStorageSystemSnapshots = new Boolean(value);
+
+            if (supportsStorageSystemSnapshots) {
+                return DataStoreRole.Primary;
+            }
+        }
+
+        return DataStoreRole.Image;
+    }
+
+    protected DiskProfile createDiskCharacteristics(VolumeInfo volume, VirtualMachineTemplate template, DataCenter dc, DiskOffering diskOffering) {
+        if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
+            TemplateDataStoreVO ss = _vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dc.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+            if (ss == null) {
+                throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId());
+            }
+
+            return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(), diskOffering.isUseLocalStorage(),
+                    diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null);
+        } else {
+            return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
+                    diskOffering.isUseLocalStorage(), diskOffering.isRecreatable(), null);
+        }
+    }
+
+    @DB
+    public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
+            DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
+
+        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
+        DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
+        dskCh.setHyperType(vm.getHypervisorType());
+        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
+
+        // Find a suitable storage to create volume on
+        StoragePool destPool = findStoragePool(dskCh, dc, pod, clusterId, null, vm, avoidPools);
+        if (destPool == null) {
+            throw new CloudRuntimeException("Failed to find a suitable storage pool to create Volume in the pod/cluster of the provided VM "+ vm.getUuid());
+        }
+        DataStore destStore = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
+        AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(volume, destStore);
+
+        try {
+            VolumeApiResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.debug("copy volume failed: " + result.getResult());
+                throw new CloudRuntimeException("copy volume failed: " + result.getResult());
+            }
+            return result.getVolume();
+        } catch (InterruptedException e) {
+            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
+            throw new CloudRuntimeException("Failed to copy volume", e);
+        } catch (ExecutionException e) {
+            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
+            throw new CloudRuntimeException("Failed to copy volume", e);
+        }
+    }
+
+    @DB
+    public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering,
+            List<StoragePool> avoids, long size, HypervisorType hyperType) {
+        // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+        volume = volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
+
+        StoragePool pool = null;
+
+        DiskProfile dskCh = null;
+        if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
+            dskCh = createDiskCharacteristics(volume, template, dc, offering);
+            storageMgr.setDiskProfileThrottling(dskCh, offering, diskOffering);
+        } else {
+            dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
+            storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
+        }
+
+        if (diskOffering != null && diskOffering.isCustomized()) {
+            dskCh.setSize(size);
+        }
+
+        dskCh.setHyperType(hyperType);
+
+        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
+
+        pool = findStoragePool(dskCh, dc, pod, clusterId, vm.getHostId(), vm, avoidPools);
+        if (pool == null) {
+            s_logger.warn("Unable to find suitable primary storage when creating volume " + volume.getName());
+            throw new CloudRuntimeException("Unable to find suitable primary storage when creating volume " + volume.getName());
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Trying to create " + volume + " on " + pool);
+        }
+        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+        for (int i = 0; i < 2; i++) {
+            // retry one more time in case of template reload is required for Vmware case
+            AsyncCallFuture<VolumeApiResult> future = null;
+            boolean isNotCreatedFromTemplate = volume.getTemplateId() == null ? true : false;
+            if (isNotCreatedFromTemplate) {
+                future = volService.createVolumeAsync(volume, store);
+            } else {
+                TemplateInfo templ = tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
+                future = volService.createVolumeFromTemplateAsync(volume, store.getId(), templ);
+            }
+            try {
+                VolumeApiResult result = future.get();
+                if (result.isFailed()) {
+                    if (result.getResult().contains("request template reload") && (i == 0)) {
+                        s_logger.debug("Retry template re-deploy for vmware");
+                        continue;
+                    } else {
+                        s_logger.debug("create volume failed: " + result.getResult());
+                        throw new CloudRuntimeException("create volume failed:" + result.getResult());
+                    }
+                }
+
+                return result.getVolume();
+            } catch (InterruptedException e) {
+                s_logger.error("create volume failed", e);
+                throw new CloudRuntimeException("create volume failed", e);
+            } catch (ExecutionException e) {
+                s_logger.error("create volume failed", e);
+                throw new CloudRuntimeException("create volume failed", e);
+            }
+        }
+        throw new CloudRuntimeException("create volume failed even after template re-deploy");
+    }
+
+    public String getRandomVolumeName() {
+        return UUID.randomUUID().toString();
+    }
+
+    @Override
+    public boolean volumeOnSharedStoragePool(Volume volume) {
+        Long poolId = volume.getPoolId();
+        if (poolId == null) {
+            return false;
+        } else {
+            StoragePoolVO pool = _storagePoolDao.findById(poolId);
+
+            if (pool == null) {
+                return false;
+            } else {
+                return (pool.getScope() == ScopeType.HOST) ? false : true;
+            }
+        }
+    }
+
+    @Override
+    public boolean volumeInactive(Volume volume) {
+        Long vmId = volume.getInstanceId();
+
+        if (vmId == null) {
+            return true;
+        }
+
+        UserVm vm = _entityMgr.findById(UserVm.class, vmId);
+
+        if (vm == null) {
+            return true;
+        }
+
+        State state = vm.getState();
+
+        if (state.equals(State.Stopped) || state.equals(State.Destroyed)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String getVmNameOnVolume(Volume volume) {
+        Long vmId = volume.getInstanceId();
+        if (vmId != null) {
+            VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, vmId);
+
+            if (vm == null) {
+                return null;
+            }
+            return vm.getInstanceName();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean validateVolumeSizeRange(long size) {
+        if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
+            throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
+        } else if (size > (MaxVolumeSize.value() * 1024 * 1024 * 1024)) {
+            throw new InvalidParameterValueException("volume size " + size + ", but the maximum size allowed is " + MaxVolumeSize + " GB.");
+        }
+
+        return true;
+    }
+
+    protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) {
+        return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.isUseLocalStorage(), offering.isRecreatable(),
+                vol.getTemplateId());
+    }
+
+    @Override
+    public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
+            Long deviceId) {
+        if (size == null) {
+            size = offering.getDiskSize();
+        } else {
+            size = (size * 1024 * 1024 * 1024);
+        }
+
+        minIops = minIops != null ? minIops : offering.getMinIops();
+        maxIops = maxIops != null ? maxIops : offering.getMaxIops();
+
+        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
+        if (vm != null) {
+            vol.setInstanceId(vm.getId());
+        }
+
+        if (deviceId != null) {
+            vol.setDeviceId(deviceId);
+        } else if (type.equals(Type.ROOT)) {
+            vol.setDeviceId(0l);
+        } else {
+            vol.setDeviceId(1l);
+        }
+        if (template.getFormat() == ImageFormat.ISO) {
+            vol.setIsoId(template.getId());
+        } else if (template.getTemplateType().equals(Storage.TemplateType.DATADISK)) {
+            vol.setTemplateId(template.getId());
+        }
+        // display flag matters only for the User vms
+        if (vm.getType() == VirtualMachine.Type.User) {
+            UserVmVO userVm = _userVmDao.findById(vm.getId());
+            vol.setDisplayVolume(userVm.isDisplayVm());
+        }
+
+        vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
+        vol = _volsDao.persist(vol);
+
+        // Save usage event and update resource count for user vm volumes
+        if (vm.getType() == VirtualMachine.Type.User) {
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
+                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
+
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
+        }
+        return toDiskProfile(vol, offering);
+    }
+
+    @Override
+    public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
+            Account owner) {
+        assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
+
+        Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
+        if (rootDisksize != null) {
+            rootDisksize = rootDisksize * 1024 * 1024 * 1024;
+            if (rootDisksize > size) {
+                s_logger.debug("Using root disk size of " + rootDisksize + " Bytes for volume " + name);
+                size = rootDisksize;
+            } else {
+                s_logger.debug("Using root disk size of " + size + " Bytes for volume " + name + "since specified root disk size of " + rootDisksize + " Bytes is smaller than template");
+            }
+        }
+
+        minIops = minIops != null ? minIops : offering.getMinIops();
+        maxIops = maxIops != null ? maxIops : offering.getMaxIops();
+
+        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
+        vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
+        if (vm != null) {
+            vol.setInstanceId(vm.getId());
+        }
+        vol.setTemplateId(template.getId());
+
+        if (type.equals(Type.ROOT)) {
+            vol.setDeviceId(0l);
+            if (!vm.getType().equals(VirtualMachine.Type.User)) {
+                vol.setRecreatable(true);
+            }
+        } else {
+            vol.setDeviceId(1l);
+        }
+
+        if (vm.getType() == VirtualMachine.Type.User) {
+            UserVmVO userVm = _userVmDao.findById(vm.getId());
+            vol.setDisplayVolume(userVm.isDisplayVm());
+        }
+
+        vol = _volsDao.persist(vol);
+
+        // Create event and update resource count for volumes if vm is a user vm
+        if (vm.getType() == VirtualMachine.Type.User) {
+
+            Long offeringId = null;
+
+            if (offering.getType() == DiskOffering.Type.Disk) {
+                offeringId = offering.getId();
+            }
+
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
+                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
+
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
+        }
+        return toDiskProfile(vol, offering);
+    }
+
+    private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) {
+        if (hyperType == HypervisorType.XenServer) {
+            return ImageFormat.VHD;
+        } else if (hyperType == HypervisorType.KVM) {
+            return ImageFormat.QCOW2;
+        } else if (hyperType == HypervisorType.VMware) {
+            return ImageFormat.OVA;
+        } else if (hyperType == HypervisorType.Ovm) {
+            return ImageFormat.RAW;
+        } else if (hyperType == HypervisorType.Hyperv) {
+            return ImageFormat.VHDX;
+        } else {
+            return null;
+        }
+    }
+
+    private boolean isSupportedImageFormatForCluster(VolumeInfo volume, HypervisorType rootDiskHyperType) {
+        ImageFormat volumeFormat = volume.getFormat();
+        if (rootDiskHyperType == HypervisorType.Hyperv) {
+            if (volumeFormat.equals(ImageFormat.VHDX) || volumeFormat.equals(ImageFormat.VHD)) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return volume.getFormat().equals(getSupportedImageFormatForCluster(rootDiskHyperType));
+        }
+    }
+
+    private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod, DiskOffering diskVO,
+            ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
+
+        if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) {
+            throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type");
+        }
+
+        VolumeInfo volumeOnPrimary = copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePool>(), volume.getSize(),
+                rootDiskHyperType);
+
+        return volumeOnPrimary;
+    }
+
+    @Override
+    public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException {
+        VirtualMachineTemplate rootDiskTmplt = _entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
+        DataCenter dcVO = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
+        Pod pod = _entityMgr.findById(Pod.class, storagePool.getPodId());
+
+        ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
+        DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
+        Long clusterId = storagePool.getClusterId();
+
+        VolumeInfo vol = null;
+        if (volume.getState() == Volume.State.Allocated) {
+            vol = createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<StoragePool>(), volume.getSize(), rootDiskHyperType);
+        } else if (volume.getState() == Volume.State.Uploaded) {
+            vol = copyVolume(storagePool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, svo, rootDiskHyperType);
+            if (vol != null) {
+                // Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
+                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize());
+                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize());
+            }
+        }
+
+        if (vol == null) {
+            throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId());
+        }
+        VolumeVO volVO = _volsDao.findById(vol.getId());
+        if (volVO.getFormat() == null) {
+            volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
+        }
+        _volsDao.update(volVO.getId(), volVO);
+        return volFactory.getVolume(volVO.getId());
+    }
+
+    @DB
+    protected VolumeVO switchVolume(final VolumeVO existingVolume, final VirtualMachineProfile vm) throws StorageUnavailableException {
+        Long templateIdToUse = null;
+        Long volTemplateId = existingVolume.getTemplateId();
+        long vmTemplateId = vm.getTemplateId();
+        if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId + ", updating templateId in the new Volume");
+            }
+            templateIdToUse = vmTemplateId;
+        }
+
+        final Long templateIdToUseFinal = templateIdToUse;
+        return Transaction.execute(new TransactionCallback<VolumeVO>() {
+            @Override
+            public VolumeVO doInTransaction(TransactionStatus status) {
+                VolumeVO newVolume = allocateDuplicateVolumeVO(existingVolume, templateIdToUseFinal);
+                try {
+                    stateTransitTo(existingVolume, Volume.Event.DestroyRequested);
+                } catch (NoTransitionException e) {
+                    s_logger.debug("Unable to destroy existing volume: " + e.toString());
+                }
+                // In case of VMware VM will continue to use the old root disk until expunged, so force expunge old root disk
+                if (vm.getHypervisorType() == HypervisorType.VMware) {
+                    s_logger.info("Expunging volume " + existingVolume.getId() + " from primary data store");
+                    AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(existingVolume.getId()));
+                    try {
+                        future.get();
+                    } catch (Exception e) {
+                        s_logger.debug("Failed to expunge volume:" + existingVolume.getId(), e);
+                    }
+                }
+
+                return newVolume;
+            }
+        });
+    }
+
+    @Override
+    public void release(VirtualMachineProfile profile) {
+        // add code here
+    }
+
+    @Override
+    @DB
+    public void cleanupVolumes(long vmId) throws ConcurrentOperationException {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Cleaning storage for vm: " + vmId);
+        }
+        final List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
+        final List<VolumeVO> toBeExpunged = new ArrayList<VolumeVO>();
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                for (VolumeVO vol : volumesForVm) {
+                    if (vol.getVolumeType().equals(Type.ROOT)) {
+                        // Destroy volume if not already destroyed
+                        boolean volumeAlreadyDestroyed = (vol.getState() == Volume.State.Destroy || vol.getState() == Volume.State.Expunged || vol.getState() == Volume.State.Expunging);
+                        if (!volumeAlreadyDestroyed) {
+                            volService.destroyVolume(vol.getId());
+                        } else {
+                            s_logger.debug("Skipping destroy for the volume " + vol + " as its in state " + vol.getState().toString());
+                        }
+                        toBeExpunged.add(vol);
+                    } else {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Detaching " + vol);
+                        }
+                        _volsDao.detachVolume(vol.getId());
+                    }
+                }
+            }
+        });
+
+        AsyncCallFuture<VolumeApiResult> future = null;
+        for (VolumeVO expunge : toBeExpunged) {
+            future = volService.expungeVolumeAsync(volFactory.getVolume(expunge.getId()));
+            try {
+                future.get();
+            } catch (InterruptedException e) {
+                s_logger.debug("failed expunge volume" + expunge.getId(), e);
+            } catch (ExecutionException e) {
+                s_logger.debug("failed expunge volume" + expunge.getId(), e);
+            }
+        }
+    }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
+
+        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
+            ((PrimaryDataStoreDriver)dataStoreDriver).revokeAccess(dataObject, host, dataStore);
+        }
+    }
+
+    @Override
+    public void revokeAccess(long vmId, long hostId) {
+        HostVO host = _hostDao.findById(hostId);
+
+        List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
+
+        if (volumesForVm != null) {
+            for (VolumeVO volumeForVm : volumesForVm) {
+                VolumeInfo volumeInfo = volFactory.getVolume(volumeForVm.getId());
+
+                // pool id can be null for the VM's volumes in Allocated state
+                if (volumeForVm.getPoolId() != null) {
+                    DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary);
+
+                    volService.revokeAccess(volumeInfo, host, dataStore);
+                }
+            }
+        }
+    }
+
+    private void checkConcurrentJobsPerDatastoreThreshhold(final StoragePool destPool) {
+        final Long threshold = VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value();
+        if (threshold != null && threshold > 0) {
+            long count = _jobMgr.countPendingJobs("\"storageid\":\"" + destPool.getUuid() + "\"", MigrateVMCmd.class.getName(), MigrateVolumeCmd.class.getName(), MigrateVolumeCmdByAdmin.class.getName());
+            if (count > threshold) {
+                throw new CloudRuntimeException("Number of concurrent migration jobs per datastore exceeded the threshold: " + threshold.toString() + ". Please try again after some time.");
+            }
+        }
+    }
+
+
+    @Override
+    @DB
+    public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
+        VolumeInfo vol = volFactory.getVolume(volume.getId());
+        if (vol == null){
+            throw new CloudRuntimeException("Migrate volume failed because volume object of volume " + volume.getName()+ "is null");
+        }
+        if (destPool == null) {
+            throw new CloudRuntimeException("Migrate volume failed because destination storage pool is not available!!");
+        }
+
+        checkConcurrentJobsPerDatastoreThreshhold(destPool);
+
+        DataStore dataStoreTarget = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
+        AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(vol, dataStoreTarget);
+        try {
+            VolumeApiResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.error("Migrate volume failed:" + result.getResult());
+                throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
+            } else {
+                // update the volumeId for snapshots on secondary
+                if (!_snapshotDao.listByVolumeId(vol.getId()).isEmpty()) {
+                    _snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
+                    _snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
+                }
+            }
+            return result.getVolume();
+        } catch (InterruptedException e) {
+            s_logger.debug("migrate volume failed", e);
+            throw new CloudRuntimeException(e.getMessage());
+        } catch (ExecutionException e) {
+            s_logger.debug("migrate volume failed", e);
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @DB
+    protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) {
+        VolumeInfo vol = volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore)destPool);
+        try {
+            VolumeApiResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.debug("migrate volume failed:" + result.getResult());
+                return null;
+            }
+            return result.getVolume();
+        } catch (InterruptedException e) {
+            s_logger.debug("migrate volume failed", e);
+            return null;
+        } catch (ExecutionException e) {
+            s_logger.debug("migrate volume failed", e);
+            return null;
+        }
+    }
+
+    @Override
+    public void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map<Volume, StoragePool> volumeToPool) {
+        // Check if all the vms being migrated belong to the vm.
+        // Check if the storage pool is of the right type.
+        // Create a VolumeInfo to DataStore map too.
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        for (Map.Entry<Volume, StoragePool> entry : volumeToPool.entrySet()) {
+            Volume volume = entry.getKey();
+            StoragePool storagePool = entry.getValue();
+            StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(storagePool.getId(), DataStoreRole.Primary);
+
+            if (volume.getInstanceId() != vm.getId()) {
+                throw new CloudRuntimeException("Volume " + volume + " that has to be migrated doesn't belong to the" + " instance " + vm);
+            }
+
+            if (destPool == null) {
+                throw new CloudRuntimeException("Failed to find the destination storage pool " + storagePool.getId());
+            }
+
+            volumeMap.put(volFactory.getVolume(volume.getId()), (DataStore)destPool);
+        }
+
+        AsyncCallFuture<CommandResult> future = volService.migrateVolumes(volumeMap, vmTo, srcHost, destHost);
+        try {
+            CommandResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.debug("Failed to migrated vm " + vm + " along with its volumes. " + result.getResult());
+                throw new CloudRuntimeException("Failed to migrated vm " + vm + " along with its volumes. ");
+            }
+        } catch (InterruptedException e) {
+            s_logger.debug("Failed to migrated vm " + vm + " along with its volumes.", e);
+        } catch (ExecutionException e) {
+            s_logger.debug("Failed to migrated vm " + vm + " along with its volumes.", e);
+        }
+    }
+
+    @Override
+    public boolean storageMigration(VirtualMachineProfile vm, StoragePool destPool) throws StorageUnavailableException {
+        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
+        List<Volume> volumesNeedToMigrate = new ArrayList<Volume>();
+
+        for (VolumeVO volume : vols) {
+            if (volume.getState() != Volume.State.Ready) {
+                s_logger.debug("volume: " + volume.getId() + " is in " + volume.getState() + " state");
+                throw new CloudRuntimeException("volume: " + volume.getId() + " is in " + volume.getState() + " state");
+            }
+
+            if (volume.getPoolId() == destPool.getId()) {
+                s_logger.debug("volume: " + volume.getId() + " is on the same storage pool: " + destPool.getId());
+                continue;
+            }
+
+            volumesNeedToMigrate.add(volume);
+        }
+
+        if (volumesNeedToMigrate.isEmpty()) {
+            s_logger.debug("No volume need to be migrated");
+            return true;
+        }
+
+        // OfflineVmwareMigration: in case we can (vmware?) don't itterate over volumes but tell the hypervisor to do the thing
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Offline vm migration was not done up the stack in VirtualMachineManager so trying here.");
+        }
+        for (Volume vol : volumesNeedToMigrate) {
+            Volume result = migrateVolume(vol, destPool);
+            if (result == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) {
+        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Preparing " + vols.size() + " volumes for " + vm);
+        }
+
+        for (VolumeVO vol : vols) {
+            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
+            DataTO volTO = volumeInfo.getTO();
+            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
+            DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
+
+            disk.setDetails(getDetails(volumeInfo, dataStore));
+
+            vm.addDisk(disk);
+        }
+
+        //if (vm.getType() == VirtualMachine.Type.User && vm.getTemplate().getFormat() == ImageFormat.ISO) {
+        if (vm.getType() == VirtualMachine.Type.User) {
+            _tmpltMgr.prepareIsoForVmProfile(vm, dest);
+            //DataTO dataTO = tmplFactory.getTemplate(vm.getTemplate().getId(), DataStoreRole.Image, vm.getVirtualMachine().getDataCenterId()).getTO();
+            //DiskTO iso = new DiskTO(dataTO, 3L, null, Volume.Type.ISO);
+            //vm.addDisk(iso);
+        }
+    }
+
+    private Map<String, String> getDetails(VolumeInfo volumeInfo, DataStore dataStore) {
+        Map<String, String> details = new HashMap<String, String>();
+
+        StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
+
+        details.put(DiskTO.MANAGED, String.valueOf(storagePool.isManaged()));
+        details.put(DiskTO.STORAGE_HOST, storagePool.getHostAddress());
+        details.put(DiskTO.STORAGE_PORT, String.valueOf(storagePool.getPort()));
+        details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeInfo.getSize()));
+        details.put(DiskTO.IQN, volumeInfo.get_iScsiName());
+        details.put(DiskTO.MOUNT_POINT, volumeInfo.get_iScsiName());
+
+        VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
+
+        details.put(DiskTO.PROTOCOL_TYPE, (volume.getPoolType() != null) ? volume.getPoolType().toString() : null);
+
+        ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
+
+        if (chapInfo != null) {
+            details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+            details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+            details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+            details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
+        }
+
+        return details;
+    }
+
+    private static enum VolumeTaskType {
+        RECREATE, NOP, MIGRATE
+    }
+
+    private static class VolumeTask {
+        final VolumeTaskType type;
+        final StoragePoolVO pool;
+        final VolumeVO volume;
+
+        VolumeTask(VolumeTaskType type, VolumeVO volume, StoragePoolVO pool) {
+            this.type = type;
+            this.pool = pool;
+            this.volume = volume;
+        }
+    }
+
+    private List<VolumeTask> getTasks(List<VolumeVO> vols, Map<Volume, StoragePool> destVols, VirtualMachineProfile vm) throws StorageUnavailableException {
+        boolean recreate = RecreatableSystemVmEnabled.value();
+        List<VolumeTask> tasks = new ArrayList<VolumeTask>();
+        for (VolumeVO vol : vols) {
+            StoragePoolVO assignedPool = null;
+            if (destVols != null) {
+                StoragePool pool = destVols.get(vol);
+                if (pool != null) {
+                    assignedPool = _storagePoolDao.findById(pool.getId());
+                }
+            }
+            if (assignedPool == null && recreate) {
+                assignedPool = _storagePoolDao.findById(vol.getPoolId());
+            }
+            if (assignedPool != null) {
+                Volume.State state = vol.getState();
+                if (state == Volume.State.Allocated || state == Volume.State.Creating) {
+                    VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
+                    tasks.add(task);
+                } else {
+                    if (vol.isRecreatable()) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
+                        }
+                        VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
+                        tasks.add(task);
+                    } else {
+                        if (assignedPool.getId() != vol.getPoolId()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Mismatch in storage pool " + assignedPool + " assigned by deploymentPlanner and the one associated with volume " + vol);
+                            }
+                            DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
+                            if (diskOffering.isUseLocalStorage()) {
+                                // Currently migration of local volume is not supported so bail out
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
+                                }
+                                throw new CloudRuntimeException("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
+                            } else {
+                                //Check if storage migration is enabled in config
+                                Boolean isHAOperation = (Boolean)vm.getParameter(VirtualMachineProfile.Param.HaOperation);
+                                Boolean storageMigrationEnabled = true;
+                                if (isHAOperation != null && isHAOperation) {
+                                    storageMigrationEnabled = StorageHAMigrationEnabled.value();
+                                } else {
+                                    storageMigrationEnabled = StorageMigrationEnabled.value();
+                                }
+                                if (storageMigrationEnabled) {
+                                    if (s_logger.isDebugEnabled()) {
+                                        s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
+                                    }
+                                    VolumeTask task = new VolumeTask(VolumeTaskType.MIGRATE, vol, assignedPool);
+                                    tasks.add(task);
+                                } else {
+                                    throw new CloudRuntimeException("Cannot migrate volumes. Volume Migration is disabled");
+                                }
+                            }
+                        } else {
+                            StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
+                            VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
+                            tasks.add(task);
+                        }
+
+                    }
+                }
+            } else {
+                if (vol.getPoolId() == null) {
+                    throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol, Volume.class, vol.getId());
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
+                }
+                StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
+                VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
+                tasks.add(task);
+            }
+        }
+
+        return tasks;
+    }
+
+    private Pair<VolumeVO, DataStore> recreateVolume(VolumeVO vol, VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException {
+        VolumeVO newVol;
+        boolean recreate = RecreatableSystemVmEnabled.value();
+        DataStore destPool = null;
+        if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) {
+            destPool = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
+            s_logger.debug("existing pool: " + destPool.getId());
+        } else {
+            StoragePool pool = dest.getStorageForDisks().get(vol);
+            destPool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+        }
+        if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
+            newVol = vol;
+        } else {
+            newVol = switchVolume(vol, vm);
+            // update the volume->PrimaryDataStoreVO map since volumeId has
+            // changed
+            if (dest.getStorageForDisks() != null && dest.getStorageForDisks().containsKey(vol)) {
+                StoragePool poolWithOldVol = dest.getStorageForDisks().get(vol);
+                dest.getStorageForDisks().put(newVol, poolWithOldVol);
+                dest.getStorageForDisks().remove(vol);
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
+            }
+        }
+        VolumeInfo volume = volFactory.getVolume(newVol.getId(), destPool);
+        Long templateId = newVol.getTemplateId();
+        for (int i = 0; i < 2; i++) {
+            // retry one more time in case of template reload is required for VMware case
+            AsyncCallFuture<VolumeApiResult> future;
+
+            if (templateId == null) {
+                DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
+                HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
+
+                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+                volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
+
+                volume = volFactory.getVolume(newVol.getId(), destPool);
+
+                future = volService.createVolumeAsync(volume, destPool);
+            } else {
+                TemplateInfo templ = tmplFactory.getReadyTemplateOnImageStore(templateId, dest.getDataCenter().getId());
+
+                if (templ == null) {
+                    if (tmplFactory.isTemplateMarkedForDirectDownload(templateId)) {
+                        // Template is marked for direct download bypassing Secondary Storage
+                        templ = tmplFactory.getReadyBypassedTemplateOnPrimaryStore(templateId, destPool.getId(), dest.getHost().getId());
+                    } else {
+                        s_logger.debug("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
+                        throw new CloudRuntimeException("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
+                    }
+                }
+
+                PrimaryDataStore primaryDataStore = (PrimaryDataStore)destPool;
+
+                if (primaryDataStore.isManaged()) {
+                    DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
+                    HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
+
+                    // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+                    volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
+
+                    long hostId = vm.getVirtualMachine().getHostId();
+
+                    future = volService.createManagedStorageVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
+                } else {
+                    future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
+                }
+            }
+            VolumeApiResult result;
+            try {
+                result = future.get();
+                if (result.isFailed()) {
+                    if (result.getResult().contains("request template reload") && (i == 0)) {
+                        s_logger.debug("Retry template re-deploy for vmware");
+                        continue;
+                    } else {
+                        s_logger.debug("Unable to create " + newVol + ":" + result.getResult());
+                        throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId());
+                    }
+                }
+
+                StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId());
+
+                if (storagePool.isManaged()) {
+                    long hostId = vm.getVirtualMachine().getHostId();
+                    Host host = _hostDao.findById(hostId);
+
+                    volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
+                }
+
+                newVol = _volsDao.findById(newVol.getId());
+                break; //break out of template-redeploy retry loop
+            } catch (InterruptedException | ExecutionException e) {
+                s_logger.error("Unable to create " + newVol, e);
+                throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId());
+            }
+        }
+
+        return new Pair<VolumeVO, DataStore>(newVol, destPool);
+    }
+
+    @Override
+    public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException {
+
+        if (dest == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("DeployDestination cannot be null, cannot prepare Volumes for the vm: " + vm);
+            }
+            throw new CloudRuntimeException("Unable to prepare Volume for vm because DeployDestination is null, vm:" + vm);
+        }
+
+        // don't allow to start vm that doesn't have a root volume
+        if (_volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT).isEmpty()) {
+            throw new CloudRuntimeException("Unable to prepare volumes for vm as ROOT volume is missing");
+        }
+
+        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
+
+        List<VolumeTask> tasks = getTasks(vols, dest.getStorageForDisks(), vm);
+        Volume vol = null;
+        StoragePool pool;
+        for (VolumeTask task : tasks) {
+            if (task.type == VolumeTaskType.NOP) {
+                vol = task.volume;
+
+                pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
+
+                // For zone-wide managed storage, it is possible that the VM can be started in another
+                // cluster. In that case, make sure that the volume is in the right access group.
+                if (pool.isManaged()) {
+                    Host lastHost = _hostDao.findById(vm.getVirtualMachine().getLastHostId());
+                    Host host = _hostDao.findById(vm.getVirtualMachine().getHostId());
+
+                    long lastClusterId = lastHost == null || lastHost.getClusterId() == null ? -1 : lastHost.getClusterId();
+                    long clusterId = host == null || host.getClusterId() == null ? -1 : host.getClusterId();
+
+                    if (lastClusterId != clusterId) {
+                        if (lastHost != null) {
+                            storageMgr.removeStoragePoolFromCluster(lastHost.getId(), vol.get_iScsiName(), pool);
+
+                            DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+
+                            volService.revokeAccess(volFactory.getVolume(vol.getId()), lastHost, storagePool);
+                        }
+
+                        volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore)pool);
+                    }
+                }
+            } else if (task.type == VolumeTaskType.MIGRATE) {
+                pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
+                vol = migrateVolume(task.volume, pool);
+            } else if (task.type == VolumeTaskType.RECREATE) {
+                Pair<VolumeVO, DataStore> result = recreateVolume(task.volume, vm, dest);
+                pool = (StoragePool)dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary);
+                vol = result.first();
+            }
+
+            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
+            DataTO volTO = volumeInfo.getTO();
+            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
+            DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
+
+            disk.setDetails(getDetails(volumeInfo, dataStore));
+
+            vm.addDisk(disk);
+
+            // If hypervisor is vSphere, check for clone type setting.
+            if (vm.getHypervisorType().equals(HypervisorType.VMware)) {
+                // retrieve clone flag.
+                UserVmCloneType cloneType = UserVmCloneType.linked;
+                Boolean value = CapacityManager.VmwareCreateCloneFull.valueIn(vol.getPoolId());
+                if (value != null && value) {
+                    cloneType = UserVmCloneType.full;
+                }
+                UserVmCloneSettingVO cloneSettingVO = _vmCloneSettingDao.findByVmId(vm.getId());
+                if (cloneSettingVO != null) {
+                    if (!cloneSettingVO.getCloneType().equals(cloneType.toString())) {
+                        cloneSettingVO.setCloneType(cloneType.toString());
+                        _vmCloneSettingDao.update(cloneSettingVO.getId(), cloneSettingVO);
+                    }
+                } else {
+                    UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(vm.getId(), cloneType.toString());
+                    _vmCloneSettingDao.persist(vmCloneSettingVO);
+                }
+            }
+
+        }
+    }
+
+    private boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException {
+        return _volStateMachine.transitTo(vol, event, null, _volsDao);
+    }
+
+    @Override
+    public boolean canVmRestartOnAnotherServer(long vmId) {
+        List<VolumeVO> vols = _volsDao.findCreatedByInstance(vmId);
+        for (VolumeVO vol : vols) {
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(vol.getPoolId());
+            if (!vol.isRecreatable() && storagePoolVO != null && storagePoolVO.getPoolType() != null && !(storagePoolVO.getPoolType().isShared())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static final ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).", true);
+
+    public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false",
+            "If true, will recreate system vm root disk whenever starting system vm", true);
+
+    public static final ConfigKey<Boolean> StorageHAMigrationEnabled = new ConfigKey<Boolean>(Boolean.class, "enable.ha.storage.migration", "Storage", "true",
+            "Enable/disable storage migration across primary storage during HA", true);
+
+    public static final ConfigKey<Boolean> StorageMigrationEnabled = new ConfigKey<Boolean>(Boolean.class, "enable.storage.migration", "Storage", "true",
+            "Enable/disable storage migration across primary storage", true);
+
+    static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
+            "Check the url for a volume before downloading it from the management server. Set to flase when you managment has no internet access.", true);
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {RecreatableSystemVmEnabled, MaxVolumeSize, StorageHAMigrationEnabled, StorageMigrationEnabled, CustomDiskOfferingMaxSize, CustomDiskOfferingMinSize, VolumeUrlCheck};
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VolumeOrchestrationService.class.getSimpleName();
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        return true;
+    }
+
+    private void cleanupVolumeDuringAttachFailure(Long volumeId, Long vmId) {
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null) {
+            return;
+        }
+
+        if (volume.getState().equals(Volume.State.Creating)) {
+            s_logger.debug("Remove volume: " + volume.getId() + ", as it's leftover from last mgt server stop");
+            _volsDao.remove(volume.getId());
+        }
+
+        if (volume.getState().equals(Volume.State.Attaching)) {
+            s_logger.warn("Vol: " + volume.getName() + " failed to attach to VM: " + _userVmDao.findById(vmId).getHostName() + " on last mgt server stop, changing state back to Ready");
+            volume.setState(Volume.State.Ready);
+            _volsDao.update(volumeId, volume);
+        }
+    }
+
+    private void cleanupVolumeDuringMigrationFailure(Long volumeId, Long destPoolId) {
+        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destPoolId, DataStoreRole.Primary);
+        if (destPool == null) {
+            return;
+        }
+
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume.getState() == Volume.State.Migrating) {
+            VolumeVO duplicateVol = _volsDao.findByPoolIdName(destPoolId, volume.getName());
+            if (duplicateVol != null) {
+                s_logger.debug("Remove volume " + duplicateVol.getId() + " on storage pool " + destPoolId);
+                _volsDao.remove(duplicateVol.getId());
+            }
+
+            s_logger.debug("change volume state to ready from migrating in case migration failure for vol: " + volumeId);
+            volume.setState(Volume.State.Ready);
+            _volsDao.update(volumeId, volume);
+        }
+
+    }
+
+    private void cleanupVolumeDuringSnapshotFailure(Long volumeId, Long snapshotId) {
+        _snapshotSrv.cleanupVolumeDuringSnapshotFailure(volumeId, snapshotId);
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume.getState() == Volume.State.Snapshotting) {
+            s_logger.debug("change volume state back to Ready: " + volume.getId());
+            volume.setState(Volume.State.Ready);
+            _volsDao.update(volume.getId(), volume);
+        }
+    }
+
+    @Override
+    public void cleanupStorageJobs() {
+        //clean up failure jobs related to volume
+        List<AsyncJobVO> jobs = _jobMgr.findFailureAsyncJobs(VmWorkAttachVolume.class.getName(), VmWorkMigrateVolume.class.getName(), VmWorkTakeVolumeSnapshot.class.getName());
+
+        for (AsyncJobVO job : jobs) {
+            try {
+                if (job.getCmd().equalsIgnoreCase(VmWorkAttachVolume.class.getName())) {
+                    VmWorkAttachVolume work = VmWorkSerializer.deserialize(VmWorkAttachVolume.class, job.getCmdInfo());
+                    cleanupVolumeDuringAttachFailure(work.getVolumeId(), work.getVmId());
+                } else if (job.getCmd().equalsIgnoreCase(VmWorkMigrateVolume.class.getName())) {
+                    VmWorkMigrateVolume work = VmWorkSerializer.deserialize(VmWorkMigrateVolume.class, job.getCmdInfo());
+                    cleanupVolumeDuringMigrationFailure(work.getVolumeId(), work.getDestPoolId());
+                } else if (job.getCmd().equalsIgnoreCase(VmWorkTakeVolumeSnapshot.class.getName())) {
+                    VmWorkTakeVolumeSnapshot work = VmWorkSerializer.deserialize(VmWorkTakeVolumeSnapshot.class, job.getCmdInfo());
+                    cleanupVolumeDuringSnapshotFailure(work.getVolumeId(), work.getSnapshotId());
+                }
+            } catch (Exception e) {
+                s_logger.debug("clean up job failure, will continue", e);
+            }
+        }
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return "Volume Manager";
+    }
+
+    @Override
+    public void destroyVolume(Volume volume) {
+        try {
+            // Mark volume as removed if volume has not been created on primary
+            if (volume.getState() == Volume.State.Allocated) {
+                _volsDao.remove(volume.getId());
+                stateTransitTo(volume, Volume.Event.DestroyRequested);
+            } else {
+                volService.destroyVolume(volume.getId());
+            }
+            // FIXME - All this is boiler plate code and should be done as part of state transition. This shouldn't be part of orchestrator.
+            // publish usage event for the volume
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
+                    volume.getUuid(), volume.isDisplayVolume());
+            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
+            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
+        } catch (Exception e) {
+            s_logger.debug("Failed to destroy volume" + volume.getId(), e);
+            throw new CloudRuntimeException("Failed to destroy volume" + volume.getId(), e);
+        }
+    }
+
+    @Override
+    public String getVmNameFromVolumeId(long volumeId) {
+        VolumeVO volume = _volsDao.findById(volumeId);
+        return getVmNameOnVolume(volume);
+    }
+
+    @Override
+    public String getStoragePoolOfVolume(long volumeId) {
+        VolumeVO vol = _volsDao.findById(volumeId);
+        return dataStoreMgr.getPrimaryDataStore(vol.getPoolId()).getUuid();
+    }
+
+    @Override
+    public void updateVolumeDiskChain(long volumeId, String path, String chainInfo) {
+        VolumeVO vol = _volsDao.findById(volumeId);
+        boolean needUpdate = false;
+        // Volume path is not getting updated in the DB, need to find reason and fix the issue.
+        if (vol.getPath() == null) {
+            return;
+        }
+        if (!vol.getPath().equalsIgnoreCase(path)) {
+            needUpdate = true;
+        }
+
+        if (chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo()))) {
+            needUpdate = true;
+        }
+
+        if (needUpdate) {
+            s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
+            vol.setPath(path);
+            vol.setChainInfo(chainInfo);
+            _volsDao.update(volumeId, vol);
+        }
+    }
+}
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java
similarity index 100%
rename from engine/orchestration/src/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java
rename to engine/orchestration/src/main/java/org/apache/cloudstack/engine/service/api/ProvisioningServiceImpl.java
diff --git a/engine/orchestration/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml b/engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml
similarity index 100%
rename from engine/orchestration/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml
rename to engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
deleted file mode 100644
index 9cceee8..0000000
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ /dev/null
@@ -1,3873 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.engine.orchestration;
-
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
-import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.ConfigKey.Scope;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckNetworkAnswer;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DataCenterVnetVO;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterVnetDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.domain.Domain;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.Host;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Event;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkMigrationResponder;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.NetworkStateListener;
-import com.cloud.network.Networks;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkSetupInfo;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.VpcVirtualNetworkApplianceService;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.AccountGuestVlanMapDao;
-import com.cloud.network.dao.AccountGuestVlanMapVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkAccountDao;
-import com.cloud.network.dao.NetworkAccountVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDomainDao;
-import com.cloud.network.dao.NetworkDomainVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkServiceMapVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.RemoteAccessVpnVO;
-import com.cloud.network.element.AggregatedCommandExecutor;
-import com.cloud.network.element.DhcpServiceProvider;
-import com.cloud.network.element.DnsServiceProvider;
-import com.cloud.network.element.IpDeployer;
-import com.cloud.network.element.LoadBalancingServiceProvider;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.RedundantResource;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.rules.StaticNatRuleImpl;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.NetworkACLManager;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.network.vpn.RemoteAccessVpnService;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.UuidUtils;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicExtraDhcpOptionVO;
-import com.cloud.vm.NicIpAlias;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicExtraDhcpOptionDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicIpAliasVO;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.google.common.base.Strings;
-
-/**
- * NetworkManagerImpl implements NetworkManager.
- */
-public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestrationService, Listener, Configurable {
-    static final Logger s_logger = Logger.getLogger(NetworkOrchestrator.class);
-
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    VlanDao _vlanDao = null;
-    @Inject
-    IPAddressDao _ipAddressDao = null;
-    @Inject
-    AccountDao _accountDao = null;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    UserVmDao _userVmDao = null;
-    @Inject
-    AlertManager _alertMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao = null;
-    @Inject
-    NetworkDao _networksDao = null;
-    @Inject
-    NicDao _nicDao = null;
-    @Inject
-    RulesManager _rulesMgr;
-    @Inject
-    LoadBalancingRulesManager _lbMgr;
-    @Inject
-    RemoteAccessVpnService _vpnMgr;
-    @Inject
-    PodVlanMapDao _podVlanMapDao;
-    @Inject
-    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
-    @Inject
-    AccountGuestVlanMapDao _accountGuestVlanMapDao;
-    @Inject
-    DataCenterVnetDao _datacenterVnetDao;
-    @Inject
-    NetworkAccountDao _networkAccountDao;
-    @Inject
-    protected NicIpAliasDao _nicIpAliasDao;
-    @Inject
-    protected NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
-    @Inject
-    protected IPAddressDao _publicIpAddressDao;
-    @Inject
-    protected IpAddressManager _ipAddrMgr;
-    @Inject
-    MessageBus _messageBus;
-    @Inject
-    VMNetworkMapDao _vmNetworkMapDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    RemoteAccessVpnDao _remoteAccessVpnDao;
-    @Inject
-    VpcVirtualNetworkApplianceService _routerService;
-
-    List<NetworkGuru> networkGurus;
-
-    @Override
-    public List<NetworkGuru> getNetworkGurus() {
-        return networkGurus;
-    }
-
-    public void setNetworkGurus(final List<NetworkGuru> networkGurus) {
-        this.networkGurus = networkGurus;
-    }
-
-    List<NetworkElement> networkElements;
-
-    public List<NetworkElement> getNetworkElements() {
-        return networkElements;
-    }
-
-    public void setNetworkElements(final List<NetworkElement> networkElements) {
-        this.networkElements = networkElements;
-    }
-
-    @Inject
-    NetworkDomainDao _networkDomainDao;
-
-    List<IpDeployer> ipDeployers;
-
-    public List<IpDeployer> getIpDeployers() {
-        return ipDeployers;
-    }
-
-    public void setIpDeployers(final List<IpDeployer> ipDeployers) {
-        this.ipDeployers = ipDeployers;
-    }
-
-    List<DhcpServiceProvider> _dhcpProviders;
-
-    public List<DhcpServiceProvider> getDhcpProviders() {
-        return _dhcpProviders;
-    }
-
-    public void setDhcpProviders(final List<DhcpServiceProvider> dhcpProviders) {
-        _dhcpProviders = dhcpProviders;
-    }
-
-    @Inject
-    VMInstanceDao _vmDao;
-    @Inject
-    FirewallManager _firewallMgr;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _pNSPDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingRulesDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    PrivateIpDao _privateIpDao;
-    @Inject
-    NetworkACLManager _networkACLMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-
-    protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
-    ScheduledExecutorService _executor;
-
-    SearchBuilder<IPAddressVO> AssignIpAddressSearch;
-    SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
-
-    HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
-
-    @Override
-    @DB
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        // populate providers
-        final Map<Network.Service, Set<Network.Provider>> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
-
-        defaultProviders.add(Network.Provider.VirtualRouter);
-        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-
-        final Map<Network.Service, Set<Network.Provider>> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
-        defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
-
-        final Map<Network.Service, Set<Network.Provider>> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        final Set<Provider> sgProviders = new HashSet<Provider>();
-        sgProviders.add(Provider.SecurityGroupProvider);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders);
-
-        final Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultProviders.clear();
-        defaultProviders.add(Network.Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
-
-        final Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultProviders.clear();
-        defaultProviders.add(Network.Provider.VPCVirtualRouter);
-        defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
-        defaultVPCOffProviders.put(Service.Dns, defaultProviders);
-        defaultVPCOffProviders.put(Service.UserData, defaultProviders);
-        defaultVPCOffProviders.put(Service.NetworkACL, defaultProviders);
-        defaultVPCOffProviders.put(Service.Gateway, defaultProviders);
-        defaultVPCOffProviders.put(Service.Lb, defaultProviders);
-        defaultVPCOffProviders.put(Service.SourceNat, defaultProviders);
-        defaultVPCOffProviders.put(Service.StaticNat, defaultProviders);
-        defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders);
-        defaultVPCOffProviders.put(Service.Vpn, defaultProviders);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                NetworkOfferingVO offering = null;
-                //#1 - quick cloud network offering
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
-                            Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true, Network.GuestType.Shared, false, null, true, null, true,
-                            false, null, false, null, true, false);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#2 - SG enabled network offering
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
-                            TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
-                            null, true, false, null, false, null, true, false);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#3 - shared network offering with no SG service
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true,
-                            Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false,
-                            null, true, false);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#4 - default isolated offering with Source nat service
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
-                            "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null,
-                            defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null,
-                            true, false);
-
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#5 - default vpc offering with LB service
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
-                            "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null,
-                            defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#6 - default vpc offering with no LB service
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) {
-                    //remove LB service
-                    defaultVPCOffProviders.remove(Service.Lb);
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
-                            "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional,
-                            null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#7 - isolated offering with source nat disabled
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service",
-                            TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null,
-                            true, null, true, false, null, false, null, true, false);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                //#8 - network offering with internal lb service
-                final Map<Network.Service, Set<Network.Provider>> internalLbOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-                final Set<Network.Provider> defaultVpcProvider = new HashSet<Network.Provider>();
-                defaultVpcProvider.add(Network.Provider.VPCVirtualRouter);
-
-                final Set<Network.Provider> defaultInternalLbProvider = new HashSet<Network.Provider>();
-                defaultInternalLbProvider.add(Network.Provider.InternalLbVm);
-
-                internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider);
-                internalLbOffProviders.put(Service.Dns, defaultVpcProvider);
-                internalLbOffProviders.put(Service.UserData, defaultVpcProvider);
-                internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider);
-                internalLbOffProviders.put(Service.Gateway, defaultVpcProvider);
-                internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider);
-                internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider);
-
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
-                            "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders,
-                            true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    offering.setInternalLb(true);
-                    offering.setPublicLb(false);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                final Map<Network.Service, Set<Network.Provider>> netscalerServiceProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-                final Set<Network.Provider> vrProvider = new HashSet<Network.Provider>();
-                vrProvider.add(Provider.VirtualRouter);
-                final Set<Network.Provider> sgProvider = new HashSet<Network.Provider>();
-                sgProvider.add(Provider.SecurityGroupProvider);
-                final Set<Network.Provider> nsProvider = new HashSet<Network.Provider>();
-                nsProvider.add(Provider.Netscaler);
-                netscalerServiceProviders.put(Service.Dhcp, vrProvider);
-                netscalerServiceProviders.put(Service.Dns, vrProvider);
-                netscalerServiceProviders.put(Service.UserData, vrProvider);
-                netscalerServiceProviders.put(Service.SecurityGroup, sgProvider);
-                netscalerServiceProviders.put(Service.StaticNat, nsProvider);
-                netscalerServiceProviders.put(Service.Lb, nsProvider);
-
-                final Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
-                final Map<Capability, String> elb = new HashMap<Capability, String>();
-                elb.put(Capability.ElasticLb, "true");
-                final Map<Capability, String> eip = new HashMap<Capability, String>();
-                eip.put(Capability.ElasticIp, "true");
-                serviceCapabilityMap.put(Service.Lb, elb);
-                serviceCapabilityMap.put(Service.StaticNat, eip);
-
-                if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
-                    offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
-                            "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null,
-                            netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false);
-                    offering.setState(NetworkOffering.State.Enabled);
-                    offering.setDedicatedLB(false);
-                    _networkOfferingDao.update(offering.getId(), offering);
-                }
-
-                _networkOfferingDao.persistDefaultL2NetworkOfferings();
-            }
-        });
-
-        AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
-        AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
-        AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
-        AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
-        final SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
-        vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
-        vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
-        AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
-        AssignIpAddressSearch.done();
-
-        AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder();
-        AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ);
-        AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL);
-        AssignIpAddressFromPodVlanSearch.and("vlanId", AssignIpAddressFromPodVlanSearch.entity().getVlanId(), Op.IN);
-
-        final SearchBuilder<VlanVO> podVlanSearch = _vlanDao.createSearchBuilder();
-        podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ);
-        podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ);
-        final SearchBuilder<PodVlanMapVO> podVlanMapSB = _podVlanMapDao.createSearchBuilder();
-        podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ);
-        AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(),
-                JoinType.INNER);
-        AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
-
-        AssignIpAddressFromPodVlanSearch.done();
-
-        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger"));
-
-        _agentMgr.registerForHostEvents(this, true, false, true);
-
-        Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao));
-
-        s_logger.info("Network Manager is configured.");
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        final int netGcInterval = NumbersUtil.parseInt(_configDao.getValue(NetworkGcInterval.key()), 60);
-        s_logger.info("Network Manager will run the NetworkGarbageCollector every '" + netGcInterval + "' seconds.");
-
-        _executor.scheduleWithFixedDelay(new NetworkGarbageCollector(), netGcInterval, netGcInterval, TimeUnit.SECONDS);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    protected NetworkOrchestrator() {
-        setStateMachine();
-    }
-
-    @Override
-    public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
-            throws ConcurrentOperationException {
-        return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null, null, true);
-    }
-
-    @Override
-    @DB
-    public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final Network predefined, final DeploymentPlan plan, final String name,
-            final String displayText, final boolean errorIfAlreadySetup, final Long domainId, final ACLType aclType, final Boolean subdomainAccess, final Long vpcId,
-            final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException {
-
-        final Account locked = _accountDao.acquireInLockTable(owner.getId());
-        if (locked == null) {
-            throw new ConcurrentOperationException("Unable to acquire lock on " + owner);
-        }
-
-        try {
-            if (predefined == null
-                    || offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && !(predefined
-                            .getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch || predefined
-                            .getBroadcastDomainType() == BroadcastDomainType.Vxlan)) {
-                final List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
-                if (configs.size() > 0) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
-                    }
-
-                    if (errorIfAlreadySetup) {
-                        final InvalidParameterValueException ex = new InvalidParameterValueException(
-                                "Found existing network configuration (with specified id) for offering (with specified id)");
-                        ex.addProxyObject(offering.getUuid(), "offeringId");
-                        ex.addProxyObject(configs.get(0).getUuid(), "networkConfigId");
-                        throw ex;
-                    } else {
-                        return configs;
-                    }
-                }
-            }
-
-            final List<NetworkVO> networks = new ArrayList<NetworkVO>();
-
-            long related = -1;
-
-            for (final NetworkGuru guru : networkGurus) {
-                final Network network = guru.design(offering, plan, predefined, owner);
-                if (network == null) {
-                    continue;
-                }
-
-                if (network.getId() != -1) {
-                    if (network instanceof NetworkVO) {
-                        networks.add((NetworkVO)network);
-                    } else {
-                        networks.add(_networksDao.findById(network.getId()));
-                    }
-                    continue;
-                }
-
-                final long id = _networksDao.getNextInSequence(Long.class, "id");
-                if (related == -1) {
-                    related = id;
-                }
-
-                final long relatedFile = related;
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        final NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, predefined
-                                .getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(),
-                                vpcId, offering.getRedundantRouter(), predefined.getExternalId());
-                        vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
-                        vo.setStrechedL2Network(offering.getSupportsStrechedL2());
-                        final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
-                                finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()));
-                        networks.add(networkPersisted);
-
-                        if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
-                            final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
-                            functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
-                        }
-
-                        if (domainId != null && aclType == ACLType.Domain) {
-                            _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
-                        }
-                    }
-                });
-            }
-
-            if (networks.size() < 1) {
-                // see networkOfferingVO.java
-                final CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering with specified id to network profile");
-                ex.addProxyObject(offering.getUuid(), "offeringId");
-                throw ex;
-            }
-
-            return networks;
-        } finally {
-            s_logger.debug("Releasing lock for " + locked);
-            _accountDao.releaseFromLockTable(locked.getId());
-        }
-    }
-
-    @Override
-    @DB
-    public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
-    ConcurrentOperationException {
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
-                int deviceId = 0;
-                int size = 0;
-                for (final Network ntwk : networks.keySet()) {
-                    final List<? extends NicProfile> profiles = networks.get(ntwk);
-                    if (profiles != null && !profiles.isEmpty()) {
-                        size = size + profiles.size();
-                    } else {
-                        size = size + 1;
-                    }
-                }
-
-                final boolean[] deviceIds = new boolean[size];
-                Arrays.fill(deviceIds, false);
-
-                final List<NicProfile> nics = new ArrayList<NicProfile>(size);
-                NicProfile defaultNic = null;
-
-                for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
-                    final Network config = network.getKey();
-                    List<? extends NicProfile> requestedProfiles = network.getValue();
-                    if (requestedProfiles == null) {
-                        requestedProfiles = new ArrayList<NicProfile>();
-                    }
-                    if (requestedProfiles.isEmpty()) {
-                        requestedProfiles.add(null);
-                    }
-
-                    for (final NicProfile requested : requestedProfiles) {
-                        Boolean isDefaultNic = false;
-                        if (vm != null && requested != null && requested.isDefaultNic()) {
-                            isDefaultNic = true;
-                        }
-
-                        while (deviceIds[deviceId] && deviceId < deviceIds.length) {
-                            deviceId++;
-                        }
-
-                        final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, config, isDefaultNic, deviceId, vm);
-                        NicProfile vmNic = null;
-                        if (vmNicPair != null) {
-                            vmNic = vmNicPair.first();
-                            if (vmNic == null) {
-                                continue;
-                            }
-                            deviceId = vmNicPair.second();
-                        }
-
-                        final int devId = vmNic.getDeviceId();
-                        if (devId > deviceIds.length) {
-                            throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
-                        }
-                        if (deviceIds[devId]) {
-                            throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
-                        }
-
-                        deviceIds[devId] = true;
-
-                        if (vmNic.isDefaultNic()) {
-                            if (defaultNic != null) {
-                                throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
-                            }
-                            defaultNic = vmNic;
-                        }
-
-                        nics.add(vmNic);
-                        vm.addNic(vmNic);
-                        saveExtraDhcpOptions(config.getUuid(), vmNic.getId(), extraDhcpOptions);
-                    }
-                }
-                if (nics.size() != size) {
-                    s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
-                    throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
-                }
-
-                if (nics.size() == 1) {
-                    nics.get(0).setDefaultNic(true);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void saveExtraDhcpOptions(final String networkUuid, final Long nicId, final Map<String, Map<Integer, String>> extraDhcpOptionMap) {
-
-        if(extraDhcpOptionMap != null) {
-            Map<Integer, String> extraDhcpOption = extraDhcpOptionMap.get(networkUuid);
-            if(extraDhcpOption != null) {
-                List<NicExtraDhcpOptionVO> nicExtraDhcpOptionList = new LinkedList<>();
-
-                for (Integer code : extraDhcpOption.keySet()) {
-                    Dhcp.DhcpOptionCode.valueOfInt(code); //check if code is supported or not.
-                    NicExtraDhcpOptionVO nicExtraDhcpOptionVO = new NicExtraDhcpOptionVO(nicId, code, extraDhcpOption.get(code));
-                    nicExtraDhcpOptionList.add(nicExtraDhcpOptionVO);
-                }
-                _nicExtraDhcpOptionDao.saveExtraDhcpOptions(nicExtraDhcpOptionList);
-            }
-        }
-    }
-
-    @DB
-    @Override
-    public Pair<NicProfile, Integer> allocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        final NetworkVO ntwkVO = _networksDao.findById(network.getId());
-        s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network + " with requested profile " + requested);
-        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, ntwkVO.getGuruName());
-
-        if (requested != null && requested.getMode() == null) {
-            requested.setMode(network.getMode());
-        }
-        final NicProfile profile = guru.allocate(network, requested, vm);
-        if (profile == null) {
-            return null;
-        }
-
-        if (isDefaultNic != null) {
-            profile.setDefaultNic(isDefaultNic);
-        }
-
-        if (requested != null && requested.getMode() == null) {
-            profile.setMode(requested.getMode());
-        } else {
-            profile.setMode(network.getMode());
-        }
-
-        NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType());
-
-        deviceId = applyProfileToNic(vo, profile, deviceId);
-
-        vo = _nicDao.persist(vo);
-
-        final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
-        final NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
-                _networkModel.getNetworkTag(vm.getHypervisorType(), network));
-
-        return new Pair<NicProfile, Integer>(vmNic, Integer.valueOf(deviceId));
-    }
-
-    protected Integer applyProfileToNic(final NicVO vo, final NicProfile profile, Integer deviceId) {
-        if (profile.getDeviceId() != null) {
-            vo.setDeviceId(profile.getDeviceId());
-        } else if (deviceId != null) {
-            vo.setDeviceId(deviceId++);
-        }
-
-        if (profile.getReservationStrategy() != null) {
-            vo.setReservationStrategy(profile.getReservationStrategy());
-        }
-
-        vo.setDefaultNic(profile.isDefaultNic());
-
-        vo.setIPv4Address(profile.getIPv4Address());
-        vo.setAddressFormat(profile.getFormat());
-
-        if (profile.getMacAddress() != null) {
-            vo.setMacAddress(profile.getMacAddress());
-        }
-
-        vo.setMode(profile.getMode());
-        vo.setIPv4Netmask(profile.getIPv4Netmask());
-        vo.setIPv4Gateway(profile.getIPv4Gateway());
-
-        if (profile.getBroadCastUri() != null) {
-            vo.setBroadcastUri(profile.getBroadCastUri());
-        }
-
-        if (profile.getIsolationUri() != null) {
-            vo.setIsolationUri(profile.getIsolationUri());
-        }
-
-        vo.setState(Nic.State.Allocated);
-
-        vo.setIPv6Address(profile.getIPv6Address());
-        vo.setIPv6Gateway(profile.getIPv6Gateway());
-        vo.setIPv6Cidr(profile.getIPv6Cidr());
-
-        return deviceId;
-    }
-
-    protected void applyProfileToNicForRelease(final NicVO vo, final NicProfile profile) {
-        vo.setIPv4Gateway(profile.getIPv4Gateway());
-        vo.setAddressFormat(profile.getFormat());
-        vo.setIPv4Address(profile.getIPv4Address());
-        vo.setIPv6Address(profile.getIPv6Address());
-        vo.setMacAddress(profile.getMacAddress());
-        if (profile.getReservationStrategy() != null) {
-            vo.setReservationStrategy(profile.getReservationStrategy());
-        }
-        vo.setBroadcastUri(profile.getBroadCastUri());
-        vo.setIsolationUri(profile.getIsolationUri());
-        vo.setIPv4Netmask(profile.getIPv4Netmask());
-    }
-
-    protected void applyProfileToNetwork(final NetworkVO network, final NetworkProfile profile) {
-        network.setBroadcastUri(profile.getBroadcastUri());
-        network.setDns1(profile.getDns1());
-        network.setDns2(profile.getDns2());
-        network.setPhysicalNetworkId(profile.getPhysicalNetworkId());
-    }
-
-    protected NicTO toNicTO(final NicVO nic, final NicProfile profile, final NetworkVO config) {
-        final NicTO to = new NicTO();
-        to.setDeviceId(nic.getDeviceId());
-        to.setBroadcastType(config.getBroadcastDomainType());
-        to.setType(config.getTrafficType());
-        to.setIp(nic.getIPv4Address());
-        to.setNetmask(nic.getIPv4Netmask());
-        to.setMac(nic.getMacAddress());
-        to.setDns1(profile.getIPv4Dns1());
-        to.setDns2(profile.getIPv4Dns2());
-        if (nic.getIPv4Gateway() != null) {
-            to.setGateway(nic.getIPv4Gateway());
-        } else {
-            to.setGateway(config.getGateway());
-        }
-        if (nic.getVmType() != VirtualMachine.Type.User) {
-            to.setPxeDisable(true);
-        }
-        to.setDefaultNic(nic.isDefaultNic());
-        to.setBroadcastUri(nic.getBroadcastUri());
-        to.setIsolationuri(nic.getIsolationUri());
-        if (profile != null) {
-            to.setDns1(profile.getIPv4Dns1());
-            to.setDns2(profile.getIPv4Dns2());
-        }
-
-        final Integer networkRate = _networkModel.getNetworkRate(config.getId(), null);
-        to.setNetworkRateMbps(networkRate);
-
-        to.setUuid(config.getUuid());
-
-        return to;
-    }
-
-    boolean isNetworkImplemented(final NetworkVO network) {
-        final Network.State state = network.getState();
-        if (state == Network.State.Implemented) {
-            return true;
-        } else if (state == Network.State.Setup) {
-            final DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
-            if (!isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) || zone.getNetworkType() == NetworkType.Basic) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context, final boolean isRouter) throws ConcurrentOperationException,
-    ResourceUnavailableException, InsufficientCapacityException {
-        Pair<NetworkGuru, NetworkVO> implemented = null;
-        if (!isRouter) {
-            implemented = implementNetwork(networkId, dest, context);
-        } else {
-            // At the time of implementing network (using implementNetwork() method), if the VR needs to be deployed then
-            // it follows the same path of regular VM deployment. This leads to a nested call to implementNetwork() while
-            // preparing VR nics. This flow creates issues in dealing with network state transitions. The original call
-            // puts network in "Implementing" state and then the nested call again tries to put it into same state resulting
-            // in issues. In order to avoid it, implementNetwork() call for VR is replaced with below code.
-            final NetworkVO network = _networksDao.findById(networkId);
-            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-            implemented = new Pair<NetworkGuru, NetworkVO>(guru, network);
-        }
-        return implemented;
-    }
-
-    @Override
-    @DB
-    public Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException,
-    ResourceUnavailableException, InsufficientCapacityException {
-        final Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
-
-        NetworkVO network = _networksDao.findById(networkId);
-        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-        if (isNetworkImplemented(network)) {
-            s_logger.debug("Network id=" + networkId + " is already implemented");
-            implemented.set(guru, network);
-            return implemented;
-        }
-
-        // Acquire lock only when network needs to be implemented
-        network = _networksDao.acquireInLockTable(networkId, NetworkLockTimeout.value());
-        if (network == null) {
-            // see NetworkVO.java
-            final ConcurrentOperationException ex = new ConcurrentOperationException("Unable to acquire network configuration");
-            ex.addProxyObject(_entityMgr.findById(Network.class, networkId).getUuid());
-            throw ex;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Lock is acquired for network id " + networkId + " as a part of network implement");
-        }
-
-        try {
-            if (isNetworkImplemented(network)) {
-                s_logger.debug("Network id=" + networkId + " is already implemented");
-                implemented.set(guru, network);
-                return implemented;
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Asking " + guru.getName() + " to implement " + network);
-            }
-
-            final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-
-            network.setReservationId(context.getReservationId());
-            if (isSharedNetworkWithServices(network)) {
-                network.setState(Network.State.Implementing);
-            } else {
-                stateTransitTo(network, Event.ImplementNetwork);
-            }
-
-            final Network result = guru.implement(network, offering, dest, context);
-            network.setCidr(result.getCidr());
-            network.setBroadcastUri(result.getBroadcastUri());
-            network.setGateway(result.getGateway());
-            network.setMode(result.getMode());
-            network.setPhysicalNetworkId(result.getPhysicalNetworkId());
-            _networksDao.update(networkId, network);
-
-            // implement network elements and re-apply all the network rules
-            implementNetworkElementsAndResources(dest, context, network, offering);
-
-            if (isSharedNetworkWithServices(network)) {
-                network.setState(Network.State.Implemented);
-            } else {
-                stateTransitTo(network, Event.OperationSucceeded);
-            }
-
-            network.setRestartRequired(false);
-            _networksDao.update(network.getId(), network);
-            implemented.set(guru, network);
-            return implemented;
-        } catch (final NoTransitionException e) {
-            s_logger.error(e.getMessage());
-            return null;
-        } catch (final CloudRuntimeException e) {
-            s_logger.error("Caught exception: " + e.getMessage());
-            return null;
-        } finally {
-            if (implemented.first() == null) {
-                s_logger.debug("Cleaning up because we're unable to implement the network " + network);
-                try {
-                    if (isSharedNetworkWithServices(network)) {
-                        network.setState(Network.State.Shutdown);
-                        _networksDao.update(networkId, network);
-                    } else {
-                        stateTransitTo(network, Event.OperationFailed);
-                    }
-                } catch (final NoTransitionException e) {
-                    s_logger.error(e.getMessage());
-                }
-
-                try {
-                    shutdownNetwork(networkId, context, false);
-                } catch (final Exception e) {
-                    // Don't throw this exception as it would hide the original thrown exception, just log
-                    s_logger.error("Exception caught while shutting down a network as part of a failed implementation", e);
-                }
-            }
-
-            _networksDao.releaseFromLockTable(networkId);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Lock is released for network id " + networkId + " as a part of network implement");
-            }
-        }
-    }
-
-    @Override
-    public void implementNetworkElementsAndResources(final DeployDestination dest, final ReservationContext context, final Network network, final NetworkOffering offering)
-            throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException {
-
-        // Associate a source NAT IP (if one isn't already associated with the network) if this is a
-        //     1) 'Isolated' or 'Shared' guest virtual network in the advance zone
-        //     2) network has sourceNat service
-        //     3) network offering does not support a shared source NAT rule
-
-        final boolean sharedSourceNat = offering.getSharedSourceNat();
-        final DataCenter zone = _dcDao.findById(network.getDataCenterId());
-
-        if (!sharedSourceNat && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
-                && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
-
-            List<IPAddressVO> ips = null;
-            final Account owner = _entityMgr.findById(Account.class, network.getAccountId());
-            if (network.getVpcId() != null) {
-                ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
-                if (ips.isEmpty()) {
-                    final Vpc vpc = _vpcMgr.getActiveVpc(network.getVpcId());
-                    s_logger.debug("Creating a source nat ip for vpc " + vpc);
-                    _vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
-                }
-            } else {
-                ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
-                if (ips.isEmpty()) {
-                    s_logger.debug("Creating a source nat ip for network " + network);
-                    _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
-                }
-            }
-        }
-        // get providers to implement
-        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-        implementNetworkElements(dest, context, network, offering, providersToImplement);
-
-        //Reset the extra DHCP option that may have been cleared per nic.
-        List<NicVO> nicVOs = _nicDao.listByNetworkId(network.getId());
-        for(NicVO nicVO : nicVOs) {
-            if(nicVO.getState() == Nic.State.Reserved) {
-                configureExtraDhcpOptions(network, nicVO.getId());
-            }
-        }
-
-        for (final NetworkElement element : networkElements) {
-            if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
-                ((AggregatedCommandExecutor)element).prepareAggregatedExecution(network, dest);
-            }
-        }
-
-        try {
-            // reapply all the firewall/staticNat/lb rules
-            s_logger.debug("Reprogramming network " + network + " as a part of network implement");
-            if (!reprogramNetworkRules(network.getId(), CallContext.current().getCallingAccount(), network)) {
-                s_logger.warn("Failed to re-program the network as a part of network " + network + " implement");
-                // see DataCenterVO.java
-                final ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
-                        network.getDataCenterId());
-                ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
-                throw ex;
-            }
-            for (final NetworkElement element : networkElements) {
-                if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
-                    if (!((AggregatedCommandExecutor)element).completeAggregatedExecution(network, dest)) {
-                        s_logger.warn("Failed to re-program the network as a part of network " + network + " implement due to aggregated commands execution failure!");
-                        // see DataCenterVO.java
-                        final ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
-                                network.getDataCenterId());
-                        ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
-                        throw ex;
-                    }
-                }
-            }
-        } finally {
-            for (final NetworkElement element : networkElements) {
-                if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
-                    ((AggregatedCommandExecutor)element).cleanupAggregatedExecution(network, dest);
-                }
-            }
-        }
-    }
-
-    private void implementNetworkElements(final DeployDestination dest, final ReservationContext context, final Network network, final NetworkOffering offering, final List<Provider> providersToImplement)
-            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        for (NetworkElement element : networkElements) {
-            if (providersToImplement.contains(element.getProvider())) {
-                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                    // The physicalNetworkId will not get translated into a uuid by the reponse serializer,
-                    // because the serializer would look up the NetworkVO class's table and retrieve the
-                    // network id instead of the physical network id.
-                    // So just throw this exception as is. We may need to TBD by changing the serializer.
-                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                            + network.getPhysicalNetworkId());
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Asking " + element.getName() + " to implemenet " + network);
-                }
-
-                if (!element.implement(network, offering, dest, context)) {
-                    CloudRuntimeException ex = new CloudRuntimeException("Failed to implement provider " + element.getProvider().getName() + " for network with specified id");
-                    ex.addProxyObject(network.getUuid(), "networkId");
-                    throw ex;
-                }
-            }
-        }
-    }
-
-    // This method re-programs the rules/ips for existing network
-    protected boolean reprogramNetworkRules(final long networkId, final Account caller, final Network network) throws ResourceUnavailableException {
-        boolean success = true;
-
-        //Apply egress rules first to effect the egress policy early on the guest traffic
-        final List<FirewallRuleVO> firewallEgressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
-        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        final DataCenter zone = _dcDao.findById(network.getDataCenterId());
-        if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall) && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall)
-                && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
-            // add default egress rule to accept the traffic
-            _firewallMgr.applyDefaultEgressFirewallRule(network.getId(), offering.getEgressDefaultPolicy(), true);
-        }
-        if (!_firewallMgr.applyFirewallRules(firewallEgressRulesToApply, false, caller)) {
-            s_logger.warn("Failed to reapply firewall Egress rule(s) as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // associate all ip addresses
-        if (!_ipAddrMgr.applyIpAssociations(network, false)) {
-            s_logger.warn("Failed to apply ip addresses as a part of network id" + networkId + " restart");
-            success = false;
-        }
-
-        // apply static nat
-        if (!_rulesMgr.applyStaticNatsForNetwork(networkId, false, caller)) {
-            s_logger.warn("Failed to apply static nats a part of network id" + networkId + " restart");
-            success = false;
-        }
-
-        // apply firewall rules
-        final List<FirewallRuleVO> firewallIngressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
-        if (!_firewallMgr.applyFirewallRules(firewallIngressRulesToApply, false, caller)) {
-            s_logger.warn("Failed to reapply Ingress firewall rule(s) as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // apply port forwarding rules
-        if (!_rulesMgr.applyPortForwardingRulesForNetwork(networkId, false, caller)) {
-            s_logger.warn("Failed to reapply port forwarding rule(s) as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // apply static nat rules
-        if (!_rulesMgr.applyStaticNatRulesForNetwork(networkId, false, caller)) {
-            s_logger.warn("Failed to reapply static nat rule(s) as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // apply public load balancer rules
-        if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Public)) {
-            s_logger.warn("Failed to reapply Public load balancer rules as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // apply internal load balancer rules
-        if (!_lbMgr.applyLoadBalancersForNetwork(networkId, Scheme.Internal)) {
-            s_logger.warn("Failed to reapply internal load balancer rules as a part of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        // apply vpn rules
-        final List<? extends RemoteAccessVpn> vpnsToReapply = _vpnMgr.listRemoteAccessVpns(networkId);
-        if (vpnsToReapply != null) {
-            for (final RemoteAccessVpn vpn : vpnsToReapply) {
-                // Start remote access vpn per ip
-                if (_vpnMgr.startRemoteAccessVpn(vpn.getServerAddressId(), false) == null) {
-                    s_logger.warn("Failed to reapply vpn rules as a part of network id=" + networkId + " restart");
-                    success = false;
-                }
-            }
-        }
-
-        //apply network ACLs
-        if (!_networkACLMgr.applyACLToNetwork(networkId)) {
-            s_logger.warn("Failed to reapply network ACLs as a part of  of network id=" + networkId + " restart");
-            success = false;
-        }
-
-        return success;
-    }
-
-    protected boolean prepareElement(final NetworkElement element, final Network network, final NicProfile profile, final VirtualMachineProfile vmProfile, final DeployDestination dest,
-            final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-        element.prepare(network, profile, vmProfile, dest, context);
-        if (vmProfile.getType() == Type.User && element.getProvider() != null) {
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)
-                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) && element instanceof DhcpServiceProvider) {
-                final DhcpServiceProvider sp = (DhcpServiceProvider)element;
-                if (isDhcpAccrossMultipleSubnetsSupported(sp)) {
-                    if (!sp.configDhcpSupportForSubnet(network, profile, vmProfile, dest, context)) {
-                        return false;
-                    }
-                }
-                if(!sp.addDhcpEntry(network, profile, vmProfile, dest, context)) {
-                    return false;
-                }
-            }
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns)
-                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, element.getProvider()) && element instanceof DnsServiceProvider) {
-                final DnsServiceProvider sp = (DnsServiceProvider)element;
-                if (profile.getIPv6Address() == null) {
-                    if (!sp.configDnsSupportForSubnet(network, profile, vmProfile, dest, context)) {
-                        return false;
-                    }
-                }
-                if(!sp.addDnsEntry(network, profile, vmProfile, dest, context)) {
-                    return false;
-                }
-            }
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.UserData)
-                    && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.UserData, element.getProvider()) && element instanceof UserDataServiceProvider) {
-                final UserDataServiceProvider sp = (UserDataServiceProvider)element;
-                if(!sp.addPasswordAndUserdata(network, profile, vmProfile, dest, context)){
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean canUpdateInSequence(Network network, boolean forced){
-        List<Provider> providers = getNetworkProviders(network.getId());
-
-        //check if the there are no service provider other than virtualrouter.
-        for(Provider provider : providers) {
-            if (provider != Provider.VirtualRouter)
-                throw new UnsupportedOperationException("Cannot update the network resources in sequence when providers other than virtualrouter are used");
-        }
-        //check if routers are in correct state before proceeding with the update
-        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
-        for (DomainRouterVO router : routers){
-            if (router.getRedundantState() == VirtualRouter.RedundantState.UNKNOWN) {
-                if (!forced) {
-                    throw new CloudRuntimeException("Domain router: "+router.getInstanceName()+" is in unknown state, Cannot update network. set parameter forced to true for forcing an update");
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public List<String> getServicesNotSupportedInNewOffering(Network network,long newNetworkOfferingId){
-        NetworkOffering offering =_networkOfferingDao.findById(newNetworkOfferingId);
-        List<String> services=_ntwkOfferingSrvcDao.listServicesForNetworkOffering(offering.getId());
-        List<NetworkServiceMapVO> serviceMap= _ntwkSrvcDao.getServicesInNetwork(network.getId());
-        List<String> servicesNotInNewOffering=new ArrayList<>();
-        for(NetworkServiceMapVO serviceVO :serviceMap){
-            boolean inlist=false;
-            for(String service: services){
-                if(serviceVO.getService().equalsIgnoreCase(service)){
-                    inlist=true;
-                    break;
-                }
-            }
-            if(!inlist){
-                //ignore Gateway service as this has no effect on the
-                //behaviour of network.
-                if(!serviceVO.getService().equalsIgnoreCase(Service.Gateway.getName()))
-                    servicesNotInNewOffering.add(serviceVO.getService());
-            }
-        }
-        return servicesNotInNewOffering;
-    }
-
-    @Override
-    public void cleanupConfigForServicesInNetwork(List<String> services, final Network network){
-        long networkId=network.getId();
-        Account caller=_accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
-        long userId=User.UID_SYSTEM;
-        //remove all PF/Static Nat rules for the network
-        s_logger.info("Services:"+services+" are no longer supported in network:"+network.getUuid()+
-                " after applying new network offering:"+network.getNetworkOfferingId()+" removing the related configuration");
-        if(services.contains(Service.StaticNat.getName())|| services.contains(Service.PortForwarding.getName())) {
-            try {
-                if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, userId, caller)) {
-                    s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId);
-                } else {
-                    s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup");
-                }
-                if(services.contains(Service.StaticNat.getName())){
-                    //removing static nat configured on ips.
-                    //optimizing the db operations using transaction.
-                    Transaction.execute(new TransactionCallbackNoReturn() {
-                        @Override
-                        public void doInTransactionWithoutResult(TransactionStatus status) {
-                            List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(network.getId());
-                            for (IPAddressVO ip : ips) {
-                                ip.setOneToOneNat(false);
-                                ip.setAssociatedWithVmId(null);
-                                ip.setVmIp(null);
-                                _ipAddressDao.update(ip.getId(),ip);
-                            }
-                        }
-                    });
-                }
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
-            }
-        }
-        if(services.contains(Service.SourceNat.getName())){
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    List<IPAddressVO> ips = _ipAddressDao.listByAssociatedNetwork(network.getId(),true);
-                    //removing static nat configured on ips.
-                    for (IPAddressVO ip : ips) {
-                        ip.setSourceNat(false);
-                        _ipAddressDao.update(ip.getId(),ip);
-                    }
-                }
-            });
-        }
-        if(services.contains(Service.Lb.getName())){
-            //remove all LB rules for the network
-            if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, userId)) {
-                s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId);
-            } else {
-                s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
-            }
-        }
-
-        if(services.contains(Service.Firewall.getName())){
-            //revoke all firewall rules for the network
-            try {
-                if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, userId, caller)) {
-                    s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
-                } else {
-                    s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup");
-                }
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
-            }
-        }
-
-        //do not remove vpn service for vpc networks.
-        if(services.contains(Service.Vpn.getName()) && network.getVpcId()==null){
-            RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByAccountAndNetwork(network.getAccountId(),networkId);
-            try {
-                _vpnMgr.destroyRemoteAccessVpnForIp(vpn.getServerAddressId(), caller, true);
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to cleanup remote access vpn resources of network:"+network.getUuid() + " due to Exception: ", ex);
-            }
-        }
-    }
-
-    @Override
-    public void configureUpdateInSequence(Network network) {
-        List<Provider> providers = getNetworkProviders(network.getId());
-        for (NetworkElement element : networkElements) {
-            if (providers.contains(element.getProvider())) {
-                if (element instanceof RedundantResource) {
-                    ((RedundantResource) element).configureResource(network);
-                }
-            }
-        }
-    }
-
-    @Override
-    public int getResourceCount(Network network){
-        List<Provider> providers = getNetworkProviders(network.getId());
-        int resourceCount=0;
-        for (NetworkElement element : networkElements) {
-            if (providers.contains(element.getProvider())) {
-                //currently only one element implements the redundant resource interface
-                if (element instanceof RedundantResource) {
-                    resourceCount= ((RedundantResource) element).getResourceCount(network);
-                    break;
-                    }
-                }
-            }
-        return resourceCount;
-        }
-
-    @Override
-    public void configureExtraDhcpOptions(Network network, long nicId, Map<Integer, String> extraDhcpOptions) {
-        if(_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)) {
-            if (_networkModel.getNetworkServiceCapabilities(network.getId(), Service.Dhcp).containsKey(Capability.ExtraDhcpOptions)) {
-                DhcpServiceProvider sp = getDhcpServiceProvider(network);
-                sp.setExtraDhcpOptions(network, nicId, extraDhcpOptions);
-            }
-        }
-    }
-
-    @Override
-    public void configureExtraDhcpOptions(Network network, long nicId) {
-        Map<Integer, String> extraDhcpOptions = getExtraDhcpOptions(nicId);
-        configureExtraDhcpOptions(network, nicId, extraDhcpOptions);
-    }
-
-    @Override
-    public void finalizeUpdateInSequence(Network network, boolean success) {
-        List<Provider> providers = getNetworkProviders(network.getId());
-        for (NetworkElement element : networkElements) {
-            if (providers.contains(element.getProvider())) {
-                //currently only one element implements the redundant resource interface
-                if (element instanceof RedundantResource) {
-                    ((RedundantResource) element).finalize(network,success);
-                    break;
-                }
-            }
-        }
-    }
-
-
-    @DB
-    protected void updateNic(final NicVO nic, final long networkId, final int count) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                _nicDao.update(nic.getId(), nic);
-
-                if (nic.getVmType() == VirtualMachine.Type.User) {
-                    s_logger.debug("Changing active number of nics for network id=" + networkId + " on " + count);
-                    _networksDao.changeActiveNicsBy(networkId, count);
-                }
-
-                if (nic.getVmType() == VirtualMachine.Type.User
-                        || nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest) {
-                    _networksDao.setCheckForGc(networkId);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void prepare(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException,
-    ResourceUnavailableException {
-        final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
-
-        // we have to implement default nics first - to ensure that default network elements start up first in multiple
-        //nics case
-        // (need for setting DNS on Dhcp to domR's Ip4 address)
-        Collections.sort(nics, new Comparator<NicVO>() {
-
-            @Override
-            public int compare(final NicVO nic1, final NicVO nic2) {
-                final boolean isDefault1 = nic1.isDefaultNic();
-                final boolean isDefault2 = nic2.isDefaultNic();
-
-                return isDefault1 ^ isDefault2 ? isDefault1 ^ true ? 1 : -1 : 0;
-            }
-        });
-
-        for (final NicVO nic : nics) {
-            final Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
-            if (implemented == null || implemented.first() == null) {
-                s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
-                throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
-            }
-
-            final NetworkVO network = implemented.second();
-            final NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network);
-            vmProfile.addNic(profile);
-        }
-    }
-
-    @Override
-    public NicProfile prepareNic(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context, final long nicId, final Network network)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
-            ResourceUnavailableException {
-
-        final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vmProfile.getId());
-        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-        final NicVO nic = _nicDao.findById(nicId);
-
-        NicProfile profile = null;
-        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
-            nic.setState(Nic.State.Reserving);
-            nic.setReservationId(context.getReservationId());
-            _nicDao.update(nic.getId(), nic);
-            URI broadcastUri = nic.getBroadcastUri();
-            if (broadcastUri == null) {
-                broadcastUri = network.getBroadcastUri();
-            }
-
-            final URI isolationUri = nic.getIsolationUri();
-
-            profile = new NicProfile(nic, network, broadcastUri, isolationUri,
-
-                    networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
-            guru.reserve(profile, network, vmProfile, dest, context);
-            nic.setIPv4Address(profile.getIPv4Address());
-            nic.setAddressFormat(profile.getFormat());
-            nic.setIPv6Address(profile.getIPv6Address());
-            nic.setIPv6Cidr(profile.getIPv6Cidr());
-            nic.setIPv6Gateway(profile.getIPv6Gateway());
-            nic.setMacAddress(profile.getMacAddress());
-            nic.setIsolationUri(profile.getIsolationUri());
-            nic.setBroadcastUri(profile.getBroadCastUri());
-            nic.setReserver(guru.getName());
-            nic.setState(Nic.State.Reserved);
-            nic.setIPv4Netmask(profile.getIPv4Netmask());
-            nic.setIPv4Gateway(profile.getIPv4Gateway());
-
-            if (profile.getReservationStrategy() != null) {
-                nic.setReservationStrategy(profile.getReservationStrategy());
-            }
-
-            updateNic(nic, network.getId(), 1);
-        } else {
-            profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
-                    _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
-            guru.updateNicProfile(profile, network);
-            nic.setState(Nic.State.Reserved);
-            updateNic(nic, network.getId(), 1);
-        }
-
-        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-        for (final NetworkElement element : networkElements) {
-            if (providersToImplement.contains(element.getProvider())) {
-                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                            + network.getPhysicalNetworkId());
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Asking " + element.getName() + " to prepare for " + nic);
-                }
-                if (!prepareElement(element, network, profile, vmProfile, dest, context)) {
-                    throw new InsufficientAddressCapacityException("unable to configure the dhcp service, due to insufficiant address capacity", Network.class, network.getId());
-                }
-            }
-        }
-
-        profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
-        guru.updateNicProfile(profile, network);
-
-        configureExtraDhcpOptions(network, nicId);
-        return profile;
-    }
-
-    @Override
-    public Map<Integer, String> getExtraDhcpOptions(long nicId) {
-        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOList = _nicExtraDhcpOptionDao.listByNicId(nicId);
-        return nicExtraDhcpOptionVOList
-                .stream()
-                .collect(Collectors.toMap(NicExtraDhcpOptionVO::getCode, NicExtraDhcpOptionVO::getValue));
-    }
-
-
-    @Override
-    public void prepareNicForMigration(final VirtualMachineProfile vm, final DeployDestination dest) {
-        if(vm.getType().equals(VirtualMachine.Type.DomainRouter) && (vm.getHypervisorType().equals(HypervisorType.KVM) || vm.getHypervisorType().equals(HypervisorType.VMware))) {
-            //Include nics hot plugged and not stored in DB
-            prepareAllNicsForMigration(vm, dest);
-            return;
-        }
-        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        final ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), null, null);
-        for (final NicVO nic : nics) {
-            final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-            final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
-
-            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-            final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
-                    _networkModel.getNetworkTag(vm.getHypervisorType(), network));
-            if (guru instanceof NetworkMigrationResponder) {
-                if (!((NetworkMigrationResponder)guru).prepareMigration(profile, network, vm, dest, context)) {
-                    s_logger.error("NetworkGuru " + guru + " prepareForMigration failed."); // XXX: Transaction error
-                }
-            }
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                                + network.getPhysicalNetworkId());
-                    }
-                    if (element instanceof NetworkMigrationResponder) {
-                        if (!((NetworkMigrationResponder)element).prepareMigration(profile, network, vm, dest, context)) {
-                            s_logger.error("NetworkElement " + element + " prepareForMigration failed."); // XXX: Transaction error
-                        }
-                    }
-                }
-            }
-            guru.updateNicProfile(profile, network);
-            vm.addNic(profile);
-        }
-    }
-
-    /*
-    Prepare All Nics for migration including the nics dynamically created and not stored in DB
-    This is a temporary workaround work KVM migration
-    Once clean fix is added by stored dynamically nics is DB, this workaround won't be needed
-     */
-    @Override
-    public void prepareAllNicsForMigration(final VirtualMachineProfile vm, final DeployDestination dest) {
-        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        final ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), null, null);
-        Long guestNetworkId = null;
-        for (final NicVO nic : nics) {
-            final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-            if(network.getTrafficType().equals(TrafficType.Guest) && network.getGuestType().equals(GuestType.Isolated)){
-                guestNetworkId = network.getId();
-            }
-            final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
-
-            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-            final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate,
-                    _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
-            if(guru instanceof NetworkMigrationResponder){
-                if(!((NetworkMigrationResponder) guru).prepareMigration(profile, network, vm, dest, context)){
-                    s_logger.error("NetworkGuru "+guru+" prepareForMigration failed."); // XXX: Transaction error
-                }
-            }
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId());
-                    }
-                    if(element instanceof NetworkMigrationResponder){
-                        if(!((NetworkMigrationResponder) element).prepareMigration(profile, network, vm, dest, context)){
-                            s_logger.error("NetworkElement "+element+" prepareForMigration failed."); // XXX: Transaction error
-                        }
-                    }
-                }
-            }
-            guru.updateNicProfile(profile, network);
-            vm.addNic(profile);
-        }
-
-        final List<String> addedURIs = new ArrayList<String>();
-        if(guestNetworkId != null){
-            final List<IPAddressVO> publicIps = _ipAddressDao.listByAssociatedNetwork(guestNetworkId, null);
-            for (final IPAddressVO userIp : publicIps){
-                final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                final URI broadcastUri = BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag());
-                final long ntwkId = publicIp.getNetworkId();
-                final Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(ntwkId, vm.getId(),
-                        broadcastUri.toString());
-                if(nic == null && !addedURIs.contains(broadcastUri.toString())){
-                    //Nic details are not available in DB
-                    //Create nic profile for migration
-                    s_logger.debug("Creating nic profile for migration. BroadcastUri: "+broadcastUri.toString()+" NetworkId: "+ntwkId+" Vm: "+vm.getId());
-                    final NetworkVO network = _networksDao.findById(ntwkId);
-                    _networkModel.getNetworkRate(network.getId(), vm.getId());
-                    final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-                    final NicProfile profile = new NicProfile();
-                    profile.setDeviceId(255); //dummyId
-                    profile.setIPv4Address(userIp.getAddress().toString());
-                    profile.setIPv4Netmask(publicIp.getNetmask());
-                    profile.setIPv4Gateway(publicIp.getGateway());
-                    profile.setMacAddress(publicIp.getMacAddress());
-                    profile.setBroadcastType(network.getBroadcastDomainType());
-                    profile.setTrafficType(network.getTrafficType());
-                    profile.setBroadcastUri(broadcastUri);
-                    profile.setIsolationUri(Networks.IsolationType.Vlan.toUri(publicIp.getVlanTag()));
-                    profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
-                    profile.setName(_networkModel.getNetworkTag(vm.getHypervisorType(), network));
-                    profile.setNetworId(network.getId());
-
-                    guru.updateNicProfile(profile, network);
-                    vm.addNic(profile);
-                    addedURIs.add(broadcastUri.toString());
-                }
-            }
-        }
-    }
-
-    private NicProfile findNicProfileById(final VirtualMachineProfile vm, final long id) {
-        for (final NicProfile nic : vm.getNics()) {
-            if (nic.getId() == id) {
-                return nic;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void commitNicForMigration(final VirtualMachineProfile src, final VirtualMachineProfile dst) {
-        for (final NicProfile nicSrc : src.getNics()) {
-            final NetworkVO network = _networksDao.findById(nicSrc.getNetworkId());
-            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-            final NicProfile nicDst = findNicProfileById(dst, nicSrc.getId());
-            final ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
-            final ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
-
-            if (guru instanceof NetworkMigrationResponder) {
-                ((NetworkMigrationResponder)guru).commitMigration(nicSrc, network, src, src_context, dst_context);
-            }
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                                + network.getPhysicalNetworkId());
-                    }
-                    if (element instanceof NetworkMigrationResponder) {
-                        ((NetworkMigrationResponder)element).commitMigration(nicSrc, network, src, src_context, dst_context);
-                    }
-                }
-            }
-            // update the reservation id
-            final NicVO nicVo = _nicDao.findById(nicDst.getId());
-            nicVo.setReservationId(nicDst.getReservationId());
-            _nicDao.persist(nicVo);
-        }
-    }
-
-    @Override
-    public void rollbackNicForMigration(final VirtualMachineProfile src, final VirtualMachineProfile dst) {
-        for (final NicProfile nicDst : dst.getNics()) {
-            final NetworkVO network = _networksDao.findById(nicDst.getNetworkId());
-            final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-            final NicProfile nicSrc = findNicProfileById(src, nicDst.getId());
-            final ReservationContext src_context = new ReservationContextImpl(nicSrc.getReservationId(), null, null);
-            final ReservationContext dst_context = new ReservationContextImpl(nicDst.getReservationId(), null, null);
-
-            if (guru instanceof NetworkMigrationResponder) {
-                ((NetworkMigrationResponder)guru).rollbackMigration(nicDst, network, dst, src_context, dst_context);
-            }
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                        throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                                + network.getPhysicalNetworkId());
-                    }
-                    if (element instanceof NetworkMigrationResponder) {
-                        ((NetworkMigrationResponder)element).rollbackMigration(nicDst, network, dst, src_context, dst_context);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public void release(final VirtualMachineProfile vmProfile, final boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
-        final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
-        for (final NicVO nic : nics) {
-            releaseNic(vmProfile, nic.getId());
-        }
-    }
-
-    @Override
-    @DB
-    public void releaseNic(final VirtualMachineProfile vmProfile, final Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
-        releaseNic(vmProfile, nic.getId());
-    }
-
-    @DB
-    protected void releaseNic(final VirtualMachineProfile vmProfile, final long nicId) throws ConcurrentOperationException, ResourceUnavailableException {
-        final Pair<Network, NicProfile> networkToRelease = Transaction.execute(new TransactionCallback<Pair<Network, NicProfile>>() {
-            @Override
-            public Pair<Network, NicProfile> doInTransaction(final TransactionStatus status) {
-                final NicVO nic = _nicDao.lockRow(nicId, true);
-                if (nic == null) {
-                    throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic);
-                }
-
-                final Nic.State originalState = nic.getState();
-                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-
-                if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) {
-                    if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
-                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-                        nic.setState(Nic.State.Releasing);
-                        _nicDao.update(nic.getId(), nic);
-                        final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel
-                                .isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
-                        if (guru.release(profile, vmProfile, nic.getReservationId())) {
-                            applyProfileToNicForRelease(nic, profile);
-                            nic.setState(Nic.State.Allocated);
-                            if (originalState == Nic.State.Reserved) {
-                                updateNic(nic, network.getId(), -1);
-                            } else {
-                                _nicDao.update(nic.getId(), nic);
-                            }
-                        }
-                        // Perform release on network elements
-                        return new Pair<Network, NicProfile>(network, profile);
-                    } else {
-                        nic.setState(Nic.State.Allocated);
-                        updateNic(nic, network.getId(), -1);
-                    }
-                }
-
-                return null;
-            }
-        });
-
-        // cleanup the entry in vm_network_map
-        if(vmProfile.getType().equals(VirtualMachine.Type.User)) {
-            final NicVO nic = _nicDao.findById(nicId);
-            if(nic != null) {
-                final NetworkVO vmNetwork = _networksDao.findById(nic.getNetworkId());
-                final VMNetworkMapVO vno = _vmNetworkMapDao.findByVmAndNetworkId(vmProfile.getVirtualMachine().getId(), vmNetwork.getId());
-                if(vno != null) {
-                    _vmNetworkMapDao.remove(vno.getId());
-                }
-            }
-        }
-
-        if (networkToRelease != null) {
-            final Network network = networkToRelease.first();
-            final NicProfile profile = networkToRelease.second();
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Asking " + element.getName() + " to release " + profile);
-                    }
-                    //NOTE: Context appear to never be used in release method
-                    //implementations. Consider removing it from interface Element
-                    element.release(network, profile, vmProfile, null);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void cleanupNics(final VirtualMachineProfile vm) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Cleaning network for vm: " + vm.getId());
-        }
-
-        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        for (final NicVO nic : nics) {
-            removeNic(vm, nic);
-        }
-    }
-
-    @Override
-    public void removeNic(final VirtualMachineProfile vm, final Nic nic) {
-        removeNic(vm, _nicDao.findById(nic.getId()));
-    }
-
-    protected void removeNic(final VirtualMachineProfile vm, final NicVO nic) {
-
-        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start && nic.getState() != Nic.State.Allocated) {
-            // Nics with reservation strategy 'Start' should go through release phase in the Nic life cycle.
-            // Ensure that release is performed before Nic is to be removed to avoid resource leaks.
-            try {
-                releaseNic(vm, nic.getId());
-            } catch (final Exception ex) {
-                s_logger.warn("Failed to release nic: " + nic.toString() + " as part of remove operation due to", ex);
-            }
-        }
-
-        nic.setState(Nic.State.Deallocating);
-        _nicDao.update(nic.getId(), nic);
-        final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-        final NicProfile profile = new NicProfile(nic, network, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(
-                vm.getHypervisorType(), network));
-
-        /*
-         * We need to release the nics with a Create ReservationStrategy here
-         * because the nic is now being removed.
-         */
-        if (nic.getReservationStrategy() == Nic.ReservationStrategy.Create) {
-            final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-            for (final NetworkElement element : networkElements) {
-                if (providersToImplement.contains(element.getProvider())) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Asking " + element.getName() + " to release " + nic);
-                    }
-                    try {
-                        element.release(network, profile, vm, null);
-                    } catch (final ConcurrentOperationException ex) {
-                        s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
-                    } catch (final ResourceUnavailableException ex) {
-                        s_logger.warn("release failed during the nic " + nic.toString() + " removeNic due to ", ex);
-                    }
-                }
-            }
-        }
-
-        if (vm.getType() == Type.User
-                && network.getTrafficType() == TrafficType.Guest
-                && network.getGuestType() == GuestType.Shared
-                && isLastNicInSubnet(nic)) {
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)) {
-                // remove the dhcpservice ip if this is the last nic in subnet.
-                final DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
-                if (dhcpServiceProvider != null
-                        && isDhcpAccrossMultipleSubnetsSupported(dhcpServiceProvider)) {
-                    removeDhcpServiceInSubnet(nic);
-                }
-            }
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns)){
-                final DnsServiceProvider dnsServiceProvider = getDnsServiceProvider(network);
-                if (dnsServiceProvider != null) {
-                    try {
-                        if(!dnsServiceProvider.removeDnsSupportForSubnet(network)) {
-                            s_logger.warn("Failed to remove the ip alias on the dns server");
-                        }
-                    } catch (final ResourceUnavailableException e) {
-                        //failed to remove the dnsconfig.
-                        s_logger.info("Unable to delete the ip alias due to unable to contact the dns server.");
-                    }
-                }
-            }
-        }
-
-        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-        guru.deallocate(network, profile, vm);
-        _nicDao.remove(nic.getId());
-
-        s_logger.debug("Removed nic id=" + nic.getId());
-        //remove the secondary ip addresses corresponding to to this nic
-        if (!removeVmSecondaryIpsOfNic(nic.getId())) {
-            s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed");
-        }
-    }
-
-    public boolean isDhcpAccrossMultipleSubnetsSupported(final DhcpServiceProvider dhcpServiceProvider) {
-
-        final Map<Network.Capability, String> capabilities = dhcpServiceProvider.getCapabilities().get(Network.Service.Dhcp);
-        final String supportsMultipleSubnets = capabilities.get(Network.Capability.DhcpAccrossMultipleSubnets);
-        if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isLastNicInSubnet(final NicVO nic) {
-        if (_nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getIPv4Gateway(), nic.getBroadcastUri()).size() > 1) {
-            return false;
-        }
-        return true;
-    }
-
-    @DB
-    @Override
-    public void removeDhcpServiceInSubnet(final Nic nic) {
-        final Network network = _networksDao.findById(nic.getNetworkId());
-        final DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network);
-        try {
-            final NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getIPv4Gateway(), network.getId(), NicIpAlias.State.active);
-            if (ipAlias != null) {
-                ipAlias.setState(NicIpAlias.State.revoked);
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        _nicIpAliasDao.update(ipAlias.getId(), ipAlias);
-                        final IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address());
-                        _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId());
-                    }
-                });
-                if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) {
-                    s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address());
-                }
-            }
-        } catch (final ResourceUnavailableException e) {
-            //failed to remove the dhcpconfig on the router.
-            s_logger.info("Unable to delete the ip alias due to unable to contact the virtualrouter.");
-        }
-
-    }
-
-    @Override
-    public void expungeNics(final VirtualMachineProfile vm) {
-        final List<NicVO> nics = _nicDao.listByVmIdIncludingRemoved(vm.getId());
-        for (final NicVO nic : nics) {
-            _nicDao.expunge(nic.getId());
-        }
-    }
-
-    @Override
-    @DB
-    public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
-                                      boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
-                                      final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
-                                      final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
-
-        final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
-        // this method supports only guest network creation
-        if (ntwkOff.getTrafficType() != TrafficType.Guest) {
-            s_logger.warn("Only guest networks can be created using this method");
-            return null;
-        }
-
-        final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
-        //check resource limits
-        if (updateResourceCount) {
-            _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
-        }
-
-        // Validate network offering
-        if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
-            // see NetworkOfferingVO
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled);
-            ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
-            throw ex;
-        }
-
-        // Validate physical network
-        if (pNtwk.getState() != PhysicalNetwork.State.Enabled) {
-            // see PhysicalNetworkVO.java
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + " in incorrect state:" + pNtwk.getState());
-            ex.addProxyObject(pNtwk.getUuid(), "physicalNetworkId");
-            throw ex;
-        }
-
-        boolean ipv6 = false;
-
-        if (StringUtils.isNotBlank(ip6Gateway) && StringUtils.isNotBlank(ip6Cidr)) {
-            ipv6 = true;
-        }
-        // Validate zone
-        final DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone.getNetworkType() == NetworkType.Basic) {
-            // In Basic zone the network should have aclType=Domain, domainId=1, subdomainAccess=true
-            if (aclType == null || aclType != ACLType.Domain) {
-                throw new InvalidParameterValueException("Only AclType=Domain can be specified for network creation in Basic zone");
-            }
-
-            // Only one guest network is supported in Basic zone
-            final List<NetworkVO> guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest);
-            if (!guestNetworks.isEmpty()) {
-                throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic);
-            }
-
-            // if zone is basic, only Shared network offerings w/o source nat service are allowed
-            if (!(ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
-                throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + "guestType " + GuestType.Shared + " with disabled "
-                        + Service.SourceNat.getName() + " service are allowed");
-            }
-
-            if (domainId == null || domainId != Domain.ROOT_DOMAIN) {
-                throw new InvalidParameterValueException("Guest network in Basic zone should be dedicated to ROOT domain");
-            }
-
-            if (subdomainAccess == null) {
-                subdomainAccess = true;
-            } else if (!subdomainAccess) {
-                throw new InvalidParameterValueException("Subdomain access should be set to true for the" + " guest network in the Basic zone");
-            }
-
-            if (vlanId == null) {
-                vlanId = Vlan.UNTAGGED;
-            } else {
-                if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
-                    throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + "the zone of type " + NetworkType.Basic);
-                }
-            }
-
-        } else if (zone.getNetworkType() == NetworkType.Advanced) {
-            if (zone.isSecurityGroupEnabled()) {
-                if (ipv6) {
-                    throw new InvalidParameterValueException("IPv6 is not supported with security group!");
-                }
-                if (isolatedPvlan != null) {
-                    throw new InvalidParameterValueException("Isolated Private VLAN is not supported with security group!");
-                }
-                // Only Account specific Isolated network with sourceNat service disabled are allowed in security group
-                // enabled zone
-                if (ntwkOff.getGuestType() != GuestType.Shared) {
-                    throw new InvalidParameterValueException("Only shared guest network can be created in security group enabled zone");
-                }
-                if (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)) {
-                    throw new InvalidParameterValueException("Service SourceNat is not allowed in security group enabled zone");
-                }
-                if (!_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SecurityGroup)) {
-                    throw new InvalidParameterValueException("network must have SecurityGroup provider in security group enabled zone");
-                }
-            }
-
-            //don't allow eip/elb networks in Advance zone
-            if (ntwkOff.getElasticIp() || ntwkOff.getElasticLb()) {
-                throw new InvalidParameterValueException("Elastic IP and Elastic LB services are supported in zone of type " + NetworkType.Basic);
-            }
-        }
-
-        if (ipv6 && !NetUtils.isValidIp6Cidr(ip6Cidr)) {
-            throw new InvalidParameterValueException("Invalid IPv6 cidr specified");
-        }
-
-        //TODO(VXLAN): Support VNI specified
-        // VlanId can be specified only when network offering supports it
-        final boolean vlanSpecified = vlanId != null;
-        if (vlanSpecified != ntwkOff.getSpecifyVlan()) {
-            if (vlanSpecified) {
-                throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
-            } else {
-                throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
-            }
-        }
-
-        if (vlanSpecified) {
-            URI uri = BroadcastDomainType.fromString(vlanId);
-            //don't allow to specify vlan tag used by physical network for dynamic vlan allocation
-            if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
-                throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
-                        + zone.getName());
-            }
-            if (! UuidUtils.validateUUID(vlanId)){
-                // For Isolated and L2 networks, don't allow to create network with vlan that already exists in the zone
-                if (ntwkOff.getGuestType() == GuestType.Isolated || ntwkOff.getGuestType() == GuestType.L2) {
-                    if (_networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), null).size() > 0) {
-                        throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists or overlaps with other network vlans in zone " + zoneId);
-                    } else {
-                        final List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, BroadcastDomainType.getValue(uri));
-                        //for the network that is created as part of private gateway,
-                        //the vnet is not coming from the data center vnet table, so the list can be empty
-                        if (!dcVnets.isEmpty()) {
-                            final DataCenterVnetVO dcVnet = dcVnets.get(0);
-                            // Fail network creation if specified vlan is dedicated to a different account
-                            if (dcVnet.getAccountGuestVlanMapId() != null) {
-                                final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
-                                final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
-                                if (map.getAccountId() != owner.getAccountId()) {
-                                    throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
-                                }
-                                // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
-                            } else {
-                                final List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
-                                if (maps != null && !maps.isEmpty()) {
-                                    final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
-                                    final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
-                                    if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
-                                        throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
-                                                + owner.getAccountName());
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
-                    // shared network with same Vlan ID in the zone
-                    if (!bypassVlanOverlapCheck && _networksDao.listByZoneAndUriAndGuestType(zoneId, uri.toString(), GuestType.Isolated).size() > 0 ) {
-                        throw new InvalidParameterValueException("There is an existing isolated/shared network that overlaps with vlan id:" + vlanId + " in zone " + zoneId);
-                    }
-                }
-            }
-
-        }
-
-        // If networkDomain is not specified, take it from the global configuration
-        if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
-            final Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, networkOfferingId),
-                    Service.Dns);
-            final String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
-            if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
-                if (networkDomain != null) {
-                    // TBD: NetworkOfferingId and zoneId. Send uuids instead.
-                    throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId);
-                }
-            } else {
-                if (networkDomain == null) {
-                    // 1) Get networkDomain from the corresponding account/domain/zone
-                    if (aclType == ACLType.Domain) {
-                        networkDomain = _networkModel.getDomainNetworkDomain(domainId, zoneId);
-                    } else if (aclType == ACLType.Account) {
-                        networkDomain = _networkModel.getAccountNetworkDomain(owner.getId(), zoneId);
-                    }
-
-                    // 2) If null, generate networkDomain using domain suffix from the global config variables
-                    if (networkDomain == null) {
-                        networkDomain = "cs" + Long.toHexString(owner.getId()) + GuestDomainSuffix.valueIn(zoneId);
-                    }
-
-                } else {
-                    // validate network domain
-                    if (!NetUtils.verifyDomainName(networkDomain)) {
-                        throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
-                                + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-                    }
-                }
-            }
-        }
-
-        // In Advance zone Cidr for Shared networks and Isolated networks w/o source nat service can't be NULL - 2.2.x
-        // limitation, remove after we introduce support for multiple ip ranges
-        // with different Cidrs for the same Shared network
-        final boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced
-                && ntwkOff.getTrafficType() == TrafficType.Guest
-                && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated
-                && !_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)));
-        if (cidr == null && ip6Cidr == null && cidrRequired) {
-            throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of" + " type " + Network.GuestType.Shared
-                    + " and network of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled");
-        }
-
-        checkL2OfferingServices(ntwkOff);
-
-        // No cidr can be specified in Basic zone
-        if (zone.getNetworkType() == NetworkType.Basic && cidr != null) {
-            throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask can't be specified for zone of type " + NetworkType.Basic);
-        }
-
-        // 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 RFC 1918 or 6598 compliant");
-            }
-        }
-
-        final String networkDomainFinal = networkDomain;
-        final String vlanIdFinal = vlanId;
-        final Boolean subdomainAccessFinal = subdomainAccess;
-        final Network network = Transaction.execute(new TransactionCallback<Network>() {
-            @Override
-            public Network doInTransaction(final TransactionStatus status) {
-                Long physicalNetworkId = null;
-                if (pNtwk != null) {
-                    physicalNetworkId = pNtwk.getId();
-                }
-                final DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null, null, physicalNetworkId);
-                final NetworkVO userNetwork = new NetworkVO();
-                userNetwork.setNetworkDomain(networkDomainFinal);
-
-                if (cidr != null && gateway != null) {
-                    userNetwork.setCidr(cidr);
-                    userNetwork.setGateway(gateway);
-                }
-
-                if (StringUtils.isNotBlank(ip6Gateway) && StringUtils.isNotBlank(ip6Cidr)) {
-                    userNetwork.setIp6Cidr(ip6Cidr);
-                    userNetwork.setIp6Gateway(ip6Gateway);
-                }
-
-                if (externalId != null) {
-                    userNetwork.setExternalId(externalId);
-                }
-
-                if (vlanIdFinal != null) {
-                    if (isolatedPvlan == null) {
-                        URI uri = null;
-                        if (UuidUtils.validateUUID(vlanIdFinal)){
-                            //Logical router's UUID provided as VLAN_ID
-                            userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
-                        } else {
-                            uri = BroadcastDomainType.fromString(vlanIdFinal);
-                        }
-                        userNetwork.setBroadcastUri(uri);
-                        if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
-                            userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
-                        } else {
-                            userNetwork.setBroadcastDomainType(BroadcastDomainType.Native);
-                        }
-                    } else {
-                        if (vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
-                            throw new InvalidParameterValueException("Cannot support pvlan with untagged primary vlan!");
-                        }
-                        userNetwork.setBroadcastUri(NetUtils.generateUriForPvlan(vlanIdFinal, isolatedPvlan));
-                        userNetwork.setBroadcastDomainType(BroadcastDomainType.Pvlan);
-                    }
-                }
-
-                final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
-                        isDisplayNetworkEnabled);
-
-                Network network = null;
-                if (networks == null || networks.isEmpty()) {
-                    throw new CloudRuntimeException("Fail to create a network");
-                } else {
-                    if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) {
-                        Network defaultGuestNetwork = networks.get(0);
-                        for (final Network nw : networks) {
-                            if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) {
-                                defaultGuestNetwork = nw;
-                            }
-                        }
-                        network = defaultGuestNetwork;
-                    } else {
-                        // For shared network
-                        network = networks.get(0);
-                    }
-                }
-
-                if (updateResourceCount) {
-                    _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
-                }
-
-                return network;
-            }
-        });
-
-        CallContext.current().setEventDetails("Network Id: " + network.getId());
-        CallContext.current().putContextParameter(Network.class, network.getUuid());
-        return network;
-    }
-
-    /**
-     * Checks for L2 network offering services. Only 2 cases allowed:
-     * - No services
-     * - User Data service only, provided by ConfigDrive
-     * @param ntwkOff network offering
-     */
-    protected void checkL2OfferingServices(NetworkOfferingVO ntwkOff) {
-        if (ntwkOff.getGuestType() == GuestType.L2 && !_networkModel.listNetworkOfferingServices(ntwkOff.getId()).isEmpty() &&
-                (!_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.UserData) ||
-                        (_networkModel.areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.UserData) &&
-                                _networkModel.listNetworkOfferingServices(ntwkOff.getId()).size() > 1))) {
-            throw new InvalidParameterValueException("For L2 networks, only UserData service is allowed");
-        }
-    }
-
-    @Override
-    @DB
-    public boolean shutdownNetwork(final long networkId, final ReservationContext context, final boolean cleanupElements) {
-        NetworkVO network = _networksDao.findById(networkId);
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("Network is already shutdown: " + network);
-            return true;
-        }
-
-        if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
-            s_logger.debug("Network is not implemented: " + network);
-            return false;
-        }
-
-        try {
-            //do global lock for the network
-            network = _networksDao.acquireInLockTable(networkId, NetworkLockTimeout.value());
-            if (network == null) {
-                s_logger.warn("Unable to acquire lock for the network " + network + " as a part of network shutdown");
-                return false;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Lock is acquired for network " + network + " as a part of network shutdown");
-            }
-
-            if (network.getState() == Network.State.Allocated) {
-                s_logger.debug("Network is already shutdown: " + network);
-                return true;
-            }
-
-            if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
-                s_logger.debug("Network is not implemented: " + network);
-                return false;
-            }
-
-            if (isSharedNetworkWithServices(network)) {
-                network.setState(Network.State.Shutdown);
-                _networksDao.update(network.getId(), network);
-            } else {
-                try {
-                    stateTransitTo(network, Event.DestroyNetwork);
-                } catch (final NoTransitionException e) {
-                    network.setState(Network.State.Shutdown);
-                    _networksDao.update(network.getId(), network);
-                }
-            }
-
-            final boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
-
-            final NetworkVO networkFinal = network;
-            final boolean result = Transaction.execute(new TransactionCallback<Boolean>() {
-                @Override
-                public Boolean doInTransaction(final TransactionStatus status) {
-                    boolean result = false;
-
-                    if (success) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now.");
-                        }
-                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, networkFinal.getGuruName());
-                        final NetworkProfile profile = convertNetworkToNetworkProfile(networkFinal.getId());
-                        guru.shutdown(profile, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()));
-
-                        applyProfileToNetwork(networkFinal, profile);
-                        final DataCenterVO zone = _dcDao.findById(networkFinal.getDataCenterId());
-                        if (isSharedNetworkOfferingWithServices(networkFinal.getNetworkOfferingId()) && zone.getNetworkType() == NetworkType.Advanced) {
-                            networkFinal.setState(Network.State.Setup);
-                        } else {
-                            try {
-                                stateTransitTo(networkFinal, Event.OperationSucceeded);
-                            } catch (final NoTransitionException e) {
-                                networkFinal.setState(Network.State.Allocated);
-                                networkFinal.setRestartRequired(false);
-                            }
-                        }
-                        _networksDao.update(networkFinal.getId(), networkFinal);
-                        _networksDao.clearCheckForGc(networkId);
-                        result = true;
-                    } else {
-                        try {
-                            stateTransitTo(networkFinal, Event.OperationFailed);
-                        } catch (final NoTransitionException e) {
-                            networkFinal.setState(Network.State.Implemented);
-                            _networksDao.update(networkFinal.getId(), networkFinal);
-                        }
-                        result = false;
-                    }
-
-                    return result;
-                }
-            });
-
-            return result;
-        } finally {
-            if (network != null) {
-                _networksDao.releaseFromLockTable(network.getId());
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Lock is released for network " + network + " as a part of network shutdown");
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean shutdownNetworkElementsAndResources(final ReservationContext context, final boolean cleanupElements, final Network network) {
-
-        // get providers to shutdown
-        final List<Provider> providersToShutdown = getNetworkProviders(network.getId());
-
-        // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down
-        // the elements
-        boolean cleanupResult = true;
-        boolean cleanupNeeded = false;
-        try {
-            for (final Provider provider: providersToShutdown) {
-                if (provider.cleanupNeededOnShutdown()) {
-                    cleanupNeeded = true;
-                    break;
-                }
-            }
-            if (cleanupNeeded) {
-                cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId());
-            }
-        } catch (final Exception ex) {
-            s_logger.warn("shutdownNetworkRules failed during the network " + network + " shutdown due to ", ex);
-        } finally {
-            // just warn the administrator that the network elements failed to shutdown
-            if (!cleanupResult) {
-                s_logger.warn("Failed to cleanup network id=" + network.getId() + " resources as a part of shutdownNetwork");
-            }
-        }
-
-        // 2) Shutdown all the network elements
-        boolean success = true;
-        for (final NetworkElement element : networkElements) {
-            if (providersToShutdown.contains(element.getProvider())) {
-                try {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Sending network shutdown to " + element.getName());
-                    }
-                    if (!element.shutdown(network, context, cleanupElements)) {
-                        s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName());
-                        success = false;
-                    }
-                } catch (final ResourceUnavailableException e) {
-                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
-                    success = false;
-                } catch (final ConcurrentOperationException e) {
-                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
-                    success = false;
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName(), e);
-                    success = false;
-                }
-            }
-        }
-        return success;
-    }
-
-    @Override
-    @DB
-    public boolean destroyNetwork(final long networkId, final ReservationContext context, final boolean forced) {
-        final Account callerAccount = context.getAccount();
-
-        NetworkVO network = _networksDao.findById(networkId);
-        if (network == null) {
-            s_logger.debug("Unable to find network with id: " + networkId);
-            return false;
-        }
-        // Make sure that there are no user vms in the network that are not Expunged/Error
-        final List<UserVmVO> userVms = _userVmDao.listByNetworkIdAndStates(networkId);
-
-        for (final UserVmVO vm : userVms) {
-            if (!(vm.getState() == VirtualMachine.State.Expunging && vm.getRemoved() != null)) {
-                s_logger.warn("Can't delete the network, not all user vms are expunged. Vm " + vm + " is in " + vm.getState() + " state");
-                return false;
-            }
-        }
-
-        // Don't allow to delete network via api call when it has vms assigned to it
-        final int nicCount = getActiveNicsInNetwork(networkId);
-        if (nicCount > 0) {
-            s_logger.debug("The network id=" + networkId + " has active Nics, but shouldn't.");
-            // at this point we have already determined that there are no active user vms in network
-            // if the op_networks table shows active nics, it's a bug in releasing nics updating op_networks
-            _networksDao.changeActiveNicsBy(networkId, -1 * nicCount);
-        }
-
-        //In Basic zone, make sure that there are no non-removed console proxies and SSVMs using the network
-        final DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        if (zone.getNetworkType() == NetworkType.Basic) {
-            final List<VMInstanceVO> systemVms = _vmDao.listNonRemovedVmsByTypeAndNetwork(network.getId(), Type.ConsoleProxy, Type.SecondaryStorageVm);
-            if (systemVms != null && !systemVms.isEmpty()) {
-                s_logger.warn("Can't delete the network, not all consoleProxy/secondaryStorage vms are expunged");
-                return false;
-            }
-        }
-
-        // Shutdown network first
-        shutdownNetwork(networkId, context, false);
-
-        // get updated state for the network
-        network = _networksDao.findById(networkId);
-        if (network.getState() != Network.State.Allocated && network.getState() != Network.State.Setup && !forced) {
-            s_logger.debug("Network is not not in the correct state to be destroyed: " + network.getState());
-            return false;
-        }
-
-        boolean success = true;
-        if (!cleanupNetworkResources(networkId, callerAccount, context.getCaller().getId())) {
-            s_logger.warn("Unable to delete network id=" + networkId + ": failed to cleanup network resources");
-            return false;
-        }
-
-        // get providers to destroy
-        final List<Provider> providersToDestroy = getNetworkProviders(network.getId());
-        for (final NetworkElement element : networkElements) {
-            if (providersToDestroy.contains(element.getProvider())) {
-                try {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Sending destroy to " + element);
-                    }
-
-                    if (!element.destroy(network, context)) {
-                        success = false;
-                        s_logger.warn("Unable to complete destroy of the network: failed to destroy network element " + element.getName());
-                    }
-                } catch (final ResourceUnavailableException e) {
-                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
-                    success = false;
-                } catch (final ConcurrentOperationException e) {
-                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
-                    success = false;
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e);
-                    success = false;
-                }
-            }
-        }
-
-        if (success) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Network id=" + networkId + " is destroyed successfully, cleaning up corresponding resources now.");
-            }
-
-            final NetworkVO networkFinal = network;
-            try {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, networkFinal.getGuruName());
-
-                        if (!guru.trash(networkFinal, _networkOfferingDao.findById(networkFinal.getNetworkOfferingId()))) {
-                            throw new CloudRuntimeException("Failed to trash network.");
-                        }
-
-                        if (!deleteVlansInNetwork(networkFinal.getId(), context.getCaller().getId(), callerAccount)) {
-                            s_logger.warn("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
-                            throw new CloudRuntimeException("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
-                        } else {
-                            // commit transaction only when ips and vlans for the network are released successfully
-                            try {
-                                stateTransitTo(networkFinal, Event.DestroyNetwork);
-                            } catch (final NoTransitionException e) {
-                                s_logger.debug(e.getMessage());
-                            }
-                            if (_networksDao.remove(networkFinal.getId())) {
-                                final NetworkDomainVO networkDomain = _networkDomainDao.getDomainNetworkMapByNetworkId(networkFinal.getId());
-                                if (networkDomain != null) {
-                                    _networkDomainDao.remove(networkDomain.getId());
-                                }
-
-                                final NetworkAccountVO networkAccount = _networkAccountDao.getAccountNetworkMapByNetworkId(networkFinal.getId());
-                                if (networkAccount != null) {
-                                    _networkAccountDao.remove(networkAccount.getId());
-                                }
-                            }
-
-                            final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId());
-                            final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, networkFinal.getAclType());
-                            if (updateResourceCount) {
-                                _resourceLimitMgr.decrementResourceCount(networkFinal.getAccountId(), ResourceType.network, networkFinal.getDisplayNetwork());
-                            }
-                        }
-                    }
-                });
-                if (_networksDao.findById(network.getId()) == null) {
-                    // remove its related ACL permission
-                    final Pair<Class<?>, Long> networkMsg = new Pair<Class<?>, Long>(Network.class, networkFinal.getId());
-                    _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg);
-                }
-                return true;
-            } catch (final CloudRuntimeException e) {
-                s_logger.error("Failed to delete network", e);
-                return false;
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    public boolean resourceCountNeedsUpdate(final NetworkOffering ntwkOff, final ACLType aclType) {
-        //Update resource count only for Isolated account specific non-system networks
-        final boolean updateResourceCount = ntwkOff.getGuestType() == GuestType.Isolated && !ntwkOff.isSystemOnly() && aclType == ACLType.Account;
-        return updateResourceCount;
-    }
-
-    protected boolean deleteVlansInNetwork(final long networkId, final long userId, final Account callerAccount) {
-
-        //cleanup Public vlans
-        final List<VlanVO> publicVlans = _vlanDao.listVlansByNetworkId(networkId);
-        boolean result = true;
-        for (final VlanVO vlan : publicVlans) {
-            if (!_configMgr.deleteVlanAndPublicIpRange(userId, vlan.getId(), callerAccount)) {
-                s_logger.warn("Failed to delete vlan " + vlan.getId() + ");");
-                result = false;
-            }
-        }
-
-        //cleanup private vlans
-        final int privateIpAllocCount = _privateIpDao.countAllocatedByNetworkId(networkId);
-        if (privateIpAllocCount > 0) {
-            s_logger.warn("Can't delete Private ip range for network " + networkId + " as it has allocated ip addresses");
-            result = false;
-        } else {
-            _privateIpDao.deleteByNetworkId(networkId);
-            s_logger.debug("Deleted ip range for private network id=" + networkId);
-        }
-        return result;
-    }
-
-    public class NetworkGarbageCollector extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            final GlobalLock gcLock = GlobalLock.getInternLock("Network.GC.Lock");
-            try {
-                if (gcLock.lock(3)) {
-                    try {
-                        reallyRun();
-                    } finally {
-                        gcLock.unlock();
-                    }
-                }
-            } finally {
-                gcLock.releaseRef();
-            }
-        }
-
-        public void reallyRun() {
-            try {
-                final List<Long> shutdownList = new ArrayList<Long>();
-                final long currentTime = System.currentTimeMillis() / 1000;
-                final HashMap<Long, Long> stillFree = new HashMap<Long, Long>();
-
-                final List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
-                final int netGcWait = NumbersUtil.parseInt(_configDao.getValue(NetworkGcWait.key()), 60);
-                s_logger.info("NetworkGarbageCollector uses '" + netGcWait + "' seconds for GC interval.");
-
-                for (final Long networkId : networkIds) {
-
-                    if (!_networkModel.isNetworkReadyForGc(networkId)) {
-                        continue;
-                    }
-
-                    final Long time = _lastNetworkIdsToFree.remove(networkId);
-                    if (time == null) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("We found network " + networkId + " to be free for the first time.  Adding it to the list: " + currentTime);
-                        }
-                        stillFree.put(networkId, currentTime);
-                    } else if (time > currentTime - netGcWait) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Network " + networkId + " is still free but it's not time to shutdown yet: " + time);
-                        }
-                        stillFree.put(networkId, time);
-                    } else {
-                        shutdownList.add(networkId);
-                    }
-                }
-
-                _lastNetworkIdsToFree = stillFree;
-
-                final CallContext cctx = CallContext.current();
-
-                for (final Long networkId : shutdownList) {
-
-                    // If network is removed, unset gc flag for it
-                    if (_networksDao.findById(networkId) == null) {
-                        s_logger.debug("Network id=" + networkId + " is removed, so clearing up corresponding gc check");
-                        _networksDao.clearCheckForGc(networkId);
-                    } else {
-                        try {
-
-                            final User caller = cctx.getCallingUser();
-                            final Account owner = cctx.getCallingAccount();
-
-                            final ReservationContext context = new ReservationContextImpl(null, null, caller, owner);
-
-                            shutdownNetwork(networkId, context, false);
-                        } catch (final Exception e) {
-                            s_logger.warn("Unable to shutdown network: " + networkId);
-                        }
-                    }
-                }
-            } catch (final Exception e) {
-                s_logger.warn("Caught exception while running network gc: ", e);
-            }
-        }
-    }
-
-    @Override
-    public boolean startNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-
-        // Check if network exists
-        final NetworkVO network = _networksDao.findById(networkId);
-        if (network == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id doesn't exist");
-            ex.addProxyObject(String.valueOf(networkId), "networkId");
-            throw ex;
-        }
-
-        // implement the network
-        s_logger.debug("Starting network " + network + "...");
-        final Pair<NetworkGuru, NetworkVO> implementedNetwork = implementNetwork(networkId, dest, context);
-        if (implementedNetwork== null || implementedNetwork.first() == null) {
-            s_logger.warn("Failed to start the network " + network);
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public boolean restartNetwork(final Long networkId, final Account callerAccount, final User callerUser, final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-
-        final NetworkVO network = _networksDao.findById(networkId);
-
-        s_logger.debug("Restarting network " + networkId + "...");
-
-        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
-        final NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        final DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
-
-        if (cleanup) {
-            if (!rollingRestartRouters(network, offering, dest, context)) {
-                setRestartRequired(network, true);
-                return false;
-            }
-            return true;
-        }
-
-        s_logger.debug("Implementing the network " + network + " elements and resources as a part of network restart without cleanup");
-        try {
-            implementNetworkElementsAndResources(dest, context, network, offering);
-            setRestartRequired(network, false);
-            return true;
-        } catch (final Exception ex) {
-            s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network restart due to ", ex);
-            return false;
-        }
-    }
-
-    @Override
-    public void destroyExpendableRouters(final List<? extends VirtualRouter> routers, final ReservationContext context) throws ResourceUnavailableException {
-        final List<VirtualRouter> remainingRouters = new ArrayList<>();
-        for (final VirtualRouter router : routers) {
-            if (router.getState() == VirtualMachine.State.Stopped ||
-                    router.getState() == VirtualMachine.State.Error ||
-                    router.getState() == VirtualMachine.State.Shutdowned ||
-                    router.getState() == VirtualMachine.State.Unknown) {
-                s_logger.debug("Destroying old router " + router);
-                _routerService.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId());
-            } else {
-                remainingRouters.add(router);
-            }
-        }
-
-        if (remainingRouters.size() < 2) {
-            return;
-        }
-
-        VirtualRouter backupRouter = null;
-        for (final VirtualRouter router : remainingRouters) {
-            if (router.getRedundantState() == VirtualRouter.RedundantState.BACKUP) {
-                backupRouter = router;
-            }
-        }
-        if (backupRouter == null) {
-            backupRouter = routers.get(routers.size() - 1);
-        }
-        if (backupRouter != null) {
-            _routerService.destroyRouter(backupRouter.getId(), context.getAccount(), context.getCaller().getId());
-        }
-    }
-
-    @Override
-    public boolean areRoutersRunning(final List<? extends VirtualRouter> routers) {
-        for (final VirtualRouter router : routers) {
-            if (router.getState() != VirtualMachine.State.Running) {
-                s_logger.debug("Found new router " + router.getInstanceName() + " to be in non-Running state: " + router.getState() + ". Please try restarting network again.");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Cleanup entry on VR file specified by type
-     */
-    @Override
-    public void cleanupNicDhcpDnsEntry(Network network, VirtualMachineProfile vmProfile, NicProfile nicProfile) {
-
-        final List<Provider> networkProviders = getNetworkProviders(network.getId());
-        for (final NetworkElement element : networkElements) {
-            if (networkProviders.contains(element.getProvider())) {
-                if (!_networkModel.isProviderEnabledInPhysicalNetwork(_networkModel.getPhysicalNetworkId(network), element.getProvider().getName())) {
-                    throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + " either doesn't exist or is not enabled in physical network id: "
-                            + network.getPhysicalNetworkId());
-                }
-                if (vmProfile.getType() == Type.User && element.getProvider() != null) {
-                    if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)
-                            && _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, element.getProvider()) && element instanceof DhcpServiceProvider) {
-                        final DhcpServiceProvider sp = (DhcpServiceProvider) element;
-                        try {
-                            sp.removeDhcpEntry(network, nicProfile, vmProfile);
-                        } catch (ResourceUnavailableException e) {
-                            s_logger.error("Failed to remove dhcp-dns entry due to: ", e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * rollingRestartRouters performs restart of routers of a network by first
-     * deploying a new VR and then destroying old VRs in rolling fashion. For
-     * non-redundant network, it will re-program the new router as final step
-     * otherwise deploys a backup router for the network.
-     * @param network network to be restarted
-     * @param offering network offering
-     * @param dest deployment destination
-     * @param context reservation context
-     * @return returns true when the rolling restart operation succeeds
-     * @throws ResourceUnavailableException
-     * @throws ConcurrentOperationException
-     * @throws InsufficientCapacityException
-     */
-    private boolean rollingRestartRouters(final NetworkVO network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
-        if (!NetworkOrchestrationService.RollingRestartEnabled.value()) {
-            if (shutdownNetworkElementsAndResources(context, true, network)) {
-                implementNetworkElementsAndResources(dest, context, network, offering);
-                return true;
-            }
-            s_logger.debug("Failed to shutdown the network elements and resources as a part of network restart: " + network.getState());
-            return false;
-        }
-        s_logger.debug("Performing rolling restart of routers of network " + network);
-        destroyExpendableRouters(_routerDao.findByNetwork(network.getId()), context);
-
-        final List<Provider> providersToImplement = getNetworkProviders(network.getId());
-        final List<DomainRouterVO> oldRouters = _routerDao.findByNetwork(network.getId());
-
-        // Deploy a new router
-        if (oldRouters.size() > 0) {
-            network.setRollingRestart(true);
-        }
-        implementNetworkElements(dest, context, network, offering, providersToImplement);
-        if (oldRouters.size() > 0) {
-            network.setRollingRestart(false);
-        }
-
-        // For redundant network wait for 3*advert_int+skew_seconds for VRRP to kick in
-        if (network.isRedundant() || (oldRouters.size() == 1 && oldRouters.get(0).getIsRedundantRouter())) {
-            try {
-                Thread.sleep(NetworkOrchestrationService.RVRHandoverTime);
-            } catch (final InterruptedException ignored) {}
-        }
-
-        // Destroy old routers
-        for (final DomainRouterVO oldRouter : oldRouters) {
-            _routerService.stopRouter(oldRouter.getId(), true);
-            _routerService.destroyRouter(oldRouter.getId(), context.getAccount(), context.getCaller().getId());
-        }
-
-        if (network.isRedundant()) {
-            // Add a new backup router for redundant network
-            implementNetworkElements(dest, context, network, offering, providersToImplement);
-        } else {
-            // Re-apply rules for non-redundant network
-            implementNetworkElementsAndResources(dest, context, network, offering);
-        }
-
-        return areRoutersRunning(_routerDao.findByNetwork(network.getId()));
-    }
-
-    private void setRestartRequired(final NetworkVO network, final boolean restartRequired) {
-        s_logger.debug("Marking network " + network + " with restartRequired=" + restartRequired);
-        network.setRestartRequired(restartRequired);
-        _networksDao.update(network.getId(), network);
-    }
-
-    protected int getActiveNicsInNetwork(final long networkId) {
-        return _networksDao.getActiveNicsIn(networkId);
-    }
-
-    @Override
-    public NetworkProfile convertNetworkToNetworkProfile(final long networkId) {
-        final NetworkVO network = _networksDao.findById(networkId);
-        final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-        final NetworkProfile profile = new NetworkProfile(network);
-        guru.updateNetworkProfile(profile);
-
-        return profile;
-    }
-
-    @Override
-    public UserDataServiceProvider getPasswordResetProvider(final Network network) {
-        final String passwordProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
-
-        if (passwordProvider == null) {
-            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
-            return null;
-        }
-
-        return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(passwordProvider);
-    }
-
-    @Override
-    public UserDataServiceProvider getSSHKeyResetProvider(final Network network) {
-        final String SSHKeyProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
-
-        if (SSHKeyProvider == null) {
-            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
-            return null;
-        }
-
-        return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(SSHKeyProvider);
-    }
-
-    @Override
-    public DhcpServiceProvider getDhcpServiceProvider(final Network network) {
-        final String DhcpProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
-
-        if (DhcpProvider == null) {
-            s_logger.debug("Network " + network + " doesn't support service " + Service.Dhcp.getName());
-            return null;
-        }
-
-        final NetworkElement element = _networkModel.getElementImplementingProvider(DhcpProvider);
-        if ( element instanceof DhcpServiceProvider ) {
-            return (DhcpServiceProvider)element;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public DnsServiceProvider getDnsServiceProvider(final Network network) {
-        final String dnsProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Dns);
-
-        if (dnsProvider == null) {
-            s_logger.debug("Network " + network + " doesn't support service " + Service.Dhcp.getName());
-            return null;
-        }
-
-        return  (DnsServiceProvider) _networkModel.getElementImplementingProvider(dnsProvider);
-    }
-
-    protected boolean isSharedNetworkWithServices(final Network network) {
-        assert network != null;
-        final DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        if (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced
-                && isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
-            return true;
-        }
-        return false;
-    }
-
-    protected boolean isSharedNetworkOfferingWithServices(final long networkOfferingId) {
-        final NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
-        if (networkOffering.getGuestType() == Network.GuestType.Shared
-                && (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
-                                networkOfferingId, Service.Lb))) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public List<? extends Nic> listVmNics(final long vmId, final Long nicId, final Long networkId, String keyword) {
-        List<NicVO> result = null;
-
-        if (keyword == null || keyword.isEmpty()) {
-            if (nicId == null && networkId == null) {
-                result = _nicDao.listByVmId(vmId);
-            } else {
-                result = _nicDao.listByVmIdAndNicIdAndNtwkId(vmId, nicId, networkId);
-            }
-        } else {
-            result = _nicDao.listByVmIdAndKeyword(vmId, keyword);
-        }
-
-        for (final NicVO nic : result) {
-            if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) {
-                //For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result
-                s_logger.info("Listing NSX logical switch and logical switch por for each nic");
-                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-                final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-                final NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru;
-
-                final Map<String, ? extends Object> nsxParams = guruFunctions.listAdditionalNicParams(nic.getUuid());
-                if (nsxParams != null){
-                    final String lswitchUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID)
-                            ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) : null;
-                    final String lswitchPortUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID)
-                            ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) : null;
-                    nic.setNsxLogicalSwitchUuid(lswitchUuuid);
-                    nic.setNsxLogicalSwitchPortUuid(lswitchPortUuuid);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    @DB
-    @Override
-    public boolean reallocate(final VirtualMachineProfile vm, final DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException {
-        final VMInstanceVO vmInstance = _vmDao.findById(vm.getId());
-        final DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
-        if (dc.getNetworkType() == NetworkType.Basic) {
-            final List<NicVO> nics = _nicDao.listByVmId(vmInstance.getId());
-            final NetworkVO network = _networksDao.findById(nics.get(0).getNetworkId());
-            final LinkedHashMap<Network, List<? extends NicProfile>> profiles = new LinkedHashMap<Network, List<? extends NicProfile>>();
-            profiles.put(network, new ArrayList<NicProfile>());
-
-            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
-                    cleanupNics(vm);
-                    allocate(vm, profiles, null);
-                }
-            });
-        }
-        return true;
-    }
-
-    private boolean cleanupNetworkResources(final long networkId, final Account caller, final long callerUserId) {
-        boolean success = true;
-        final Network network = _networksDao.findById(networkId);
-
-        //remove all PF/Static Nat rules for the network
-        try {
-            if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, callerUserId, caller)) {
-                s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId);
-            } else {
-                success = false;
-                s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup");
-            }
-        } catch (final ResourceUnavailableException ex) {
-            success = false;
-            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
-            s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
-        }
-
-        //remove all LB rules for the network
-        if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, callerUserId)) {
-            s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId);
-        } else {
-            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
-            success = false;
-            s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
-        }
-
-        //revoke all firewall rules for the network
-        try {
-            if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, callerUserId, caller)) {
-                s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
-            } else {
-                success = false;
-                s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup");
-            }
-        } catch (final ResourceUnavailableException ex) {
-            success = false;
-            // shouldn't even come here as network is being cleaned up after all network elements are shutdown
-            s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
-        }
-
-        //revoke all network ACLs for network
-        try {
-            if (_networkACLMgr.revokeACLItemsForNetwork(networkId)) {
-                s_logger.debug("Successfully cleaned up NetworkACLs for network id=" + networkId);
-            } else {
-                success = false;
-                s_logger.warn("Failed to cleanup NetworkACLs as a part of network id=" + networkId + " cleanup");
-            }
-        } catch (final ResourceUnavailableException ex) {
-            success = false;
-            s_logger.warn("Failed to cleanup Network ACLs as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
-        }
-
-        //release all ip addresses
-        final List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null);
-        for (final IPAddressVO ipToRelease : ipsToRelease) {
-            if (ipToRelease.getVpcId() == null) {
-                if (!ipToRelease.isPortable()) {
-                    final IPAddressVO ip = _ipAddrMgr.markIpAsUnavailable(ipToRelease.getId());
-                    assert ip != null : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable.";
-                } else {
-                    // portable IP address are associated with owner, until explicitly requested to be disassociated
-                    // so as part of network clean up just break IP association with guest network
-                    ipToRelease.setAssociatedWithNetworkId(null);
-                    _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
-                    s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any network");
-                }
-            } else {
-                _vpcMgr.unassignIPFromVpcNetwork(ipToRelease.getId(), network.getId());
-            }
-        }
-
-        try {
-            if (!_ipAddrMgr.applyIpAssociations(network, true)) {
-                s_logger.warn("Unable to apply ip address associations for " + network);
-                success = false;
-            }
-        } catch (final ResourceUnavailableException e) {
-            throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
-        }
-
-        return success;
-    }
-
-    private boolean shutdownNetworkResources(final long networkId, final Account caller, final long callerUserId) {
-        // This method cleans up network rules on the backend w/o touching them in the DB
-        boolean success = true;
-        final Network network = _networksDao.findById(networkId);
-
-        // Mark all PF rules as revoked and apply them on the backend (not in the DB)
-        final List<PortForwardingRuleVO> pfRules = _portForwardingRulesDao.listByNetwork(networkId);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for network id=" + networkId + " as a part of shutdownNetworkRules");
-        }
-
-        for (final PortForwardingRuleVO pfRule : pfRules) {
-            s_logger.trace("Marking pf rule " + pfRule + " with Revoke state");
-            pfRule.setState(FirewallRule.State.Revoke);
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(pfRules, true, false)) {
-                s_logger.warn("Failed to cleanup pf rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup pf rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        // Mark all static rules as revoked and apply them on the backend (not in the DB)
-        final List<FirewallRuleVO> firewallStaticNatRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
-        final List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + firewallStaticNatRules.size() + " static nat rules for network id=" + networkId + " as a part of shutdownNetworkRules");
-        }
-
-        for (final FirewallRuleVO firewallStaticNatRule : firewallStaticNatRules) {
-            s_logger.trace("Marking static nat rule " + firewallStaticNatRule + " with Revoke state");
-            final IpAddress ip = _ipAddressDao.findById(firewallStaticNatRule.getSourceIpAddressId());
-            final FirewallRuleVO ruleVO = _firewallDao.findById(firewallStaticNatRule.getId());
-
-            if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) {
-                throw new InvalidParameterValueException("Source ip address of the rule id=" + firewallStaticNatRule.getId() + " is not static nat enabled");
-            }
-
-            //String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), firewallStaticNatRule.getNetworkId());
-            ruleVO.setState(FirewallRule.State.Revoke);
-            staticNatRules.add(new StaticNatRuleImpl(ruleVO, ip.getVmIp()));
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(staticNatRules, true, false)) {
-                s_logger.warn("Failed to cleanup static nat rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup static nat rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        try {
-            if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Public)) {
-                s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        try {
-            if (!_lbMgr.revokeLoadBalancersForNetwork(networkId, Scheme.Internal)) {
-                s_logger.warn("Failed to cleanup internal lb rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup public lb rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        // revoke all firewall rules for the network w/o applying them on the DB
-        final List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + firewallRules.size() + " firewall ingress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
-        }
-
-        for (final FirewallRuleVO firewallRule : firewallRules) {
-            s_logger.trace("Marking firewall ingress rule " + firewallRule + " with Revoke state");
-            firewallRule.setState(FirewallRule.State.Revoke);
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(firewallRules, true, false)) {
-                s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        final List<FirewallRuleVO> firewallEgressRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + firewallEgressRules.size() + " firewall egress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
-        }
-
-        try {
-            // delete default egress rule
-            final DataCenter zone = _dcDao.findById(network.getDataCenterId());
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Firewall)
-                    && (network.getGuestType() == Network.GuestType.Isolated || network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
-                // add default egress rule to accept the traffic
-                _firewallMgr.applyDefaultEgressFirewallRule(network.getId(), _networkModel.getNetworkEgressDefaultPolicy(networkId), false);
-            }
-
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup firewall default egress rule as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        for (final FirewallRuleVO firewallRule : firewallEgressRules) {
-            s_logger.trace("Marking firewall egress rule " + firewallRule + " with Revoke state");
-            firewallRule.setState(FirewallRule.State.Revoke);
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(firewallEgressRules, true, false)) {
-                s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules due to ", ex);
-            success = false;
-        }
-
-        if (network.getVpcId() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Releasing Network ACL Items for network id=" + networkId + " as a part of shutdownNetworkRules");
-            }
-
-            try {
-                //revoke all Network ACLs for the network w/o applying them in the DB
-                if (!_networkACLMgr.revokeACLItemsForNetwork(networkId)) {
-                    s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules");
-                    success = false;
-                }
-            } catch (final ResourceUnavailableException ex) {
-                s_logger.warn("Failed to cleanup network ACLs as a part of shutdownNetworkRules due to ", ex);
-                success = false;
-            }
-
-        }
-
-        //release all static nats for the network
-        if (!_rulesMgr.applyStaticNatForNetwork(networkId, false, caller, true)) {
-            s_logger.warn("Failed to disable static nats as part of shutdownNetworkRules for network id " + networkId);
-            success = false;
-        }
-
-        // Get all ip addresses, mark as releasing and release them on the backend
-        final List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(networkId, null);
-        final List<PublicIp> publicIpsToRelease = new ArrayList<PublicIp>();
-        if (userIps != null && !userIps.isEmpty()) {
-            for (final IPAddressVO userIp : userIps) {
-                userIp.setState(IpAddress.State.Releasing);
-                final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                publicIpsToRelease.add(publicIp);
-            }
-        }
-
-        try {
-            if (!_ipAddrMgr.applyIpAssociations(network, true, true, publicIpsToRelease)) {
-                s_logger.warn("Unable to apply ip address associations for " + network + " as a part of shutdownNetworkRules");
-                success = false;
-            }
-        } catch (final ResourceUnavailableException e) {
-            throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
-        }
-
-        return success;
-    }
-
-    @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;
-    }
-
-    public void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(final Host host, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
-        if (!(cmd instanceof StartupRoutingCommand)) {
-            return;
-        }
-        final long hostId = host.getId();
-        final StartupRoutingCommand startup = (StartupRoutingCommand)cmd;
-
-        final String dataCenter = startup.getDataCenter();
-
-        long dcId = -1;
-        DataCenterVO dc = _dcDao.findByName(dataCenter);
-        if (dc == null) {
-            try {
-                dcId = Long.parseLong(dataCenter);
-                dc = _dcDao.findById(dcId);
-            } catch (final NumberFormatException e) {
-            }
-        }
-        if (dc == null) {
-            throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
-        }
-        dcId = dc.getId();
-        final HypervisorType hypervisorType = startup.getHypervisorType();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Host's hypervisorType is: " + hypervisorType);
-        }
-
-        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-
-        // list all physicalnetworks in the zone & for each get the network names
-        final List<PhysicalNetworkVO> physicalNtwkList = _physicalNetworkDao.listByZone(dcId);
-        for (final PhysicalNetworkVO pNtwk : physicalNtwkList) {
-            final String publicName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Public, hypervisorType);
-            final String privateName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Management, hypervisorType);
-            final String guestName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Guest, hypervisorType);
-            final String storageName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Storage, hypervisorType);
-            // String controlName = _pNTrafficTypeDao._networkModel.getNetworkTag(pNtwk.getId(), TrafficType.Control, hypervisorType);
-            final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
-            info.setPhysicalNetworkId(pNtwk.getId());
-            info.setGuestNetworkName(guestName);
-            info.setPrivateNetworkName(privateName);
-            info.setPublicNetworkName(publicName);
-            info.setStorageNetworkName(storageName);
-            final PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(pNtwk.getId(), TrafficType.Management);
-            if (mgmtTraffic != null) {
-                final String vlan = mgmtTraffic.getVlan();
-                info.setMgmtVlan(vlan);
-            }
-            networkInfoList.add(info);
-        }
-
-        // send the names to the agent
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Sending CheckNetworkCommand to check the Network is setup correctly on Agent");
-        }
-        final CheckNetworkCommand nwCmd = new CheckNetworkCommand(networkInfoList);
-
-        final CheckNetworkAnswer answer = (CheckNetworkAnswer)_agentMgr.easySend(hostId, nwCmd);
-
-        if (answer == null) {
-            s_logger.warn("Unable to get an answer to the CheckNetworkCommand from agent:" + host.getId());
-            throw new ConnectionException(true, "Unable to get an answer to the CheckNetworkCommand from agent: " + host.getId());
-        }
-
-        if (!answer.getResult()) {
-            s_logger.warn("Unable to setup agent " + hostId + " due to " + answer.getDetails() );
-            final String msg = "Incorrect Network setup on agent, Reinitialize agent after network names are setup, details : " + answer.getDetails();
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, host.getPodId(), msg, msg);
-            throw new ConnectionException(true, msg);
-        } else {
-            if (answer.needReconnect()) {
-                throw new ConnectionException(false, "Reinitialize agent after network setup.");
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Network setup is correct on Agent");
-            }
-            return;
-        }
-    }
-
-    @Override
-    public boolean processDisconnect(final long agentId, final Status state) {
-        return false;
-    }
-
-    @Override
-    public void processHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void processHostRemoved(long hostId, long clusterId) {
-    }
-
-    @Override
-    public boolean isRecurring() {
-        return false;
-    }
-
-    @Override
-    public int getTimeout() {
-        return 0;
-    }
-
-    @Override
-    public boolean processTimeout(final long agentId, final long seq) {
-        return false;
-    }
-
-    @Override
-    public Map<String, String> finalizeServicesAndProvidersForNetwork(final NetworkOffering offering, final Long physicalNetworkId) {
-        final Map<String, String> svcProviders = new HashMap<String, String>();
-        final Map<String, List<String>> providerSvcs = new HashMap<String, List<String>>();
-        final List<NetworkOfferingServiceMapVO> servicesMap = _ntwkOfferingSrvcDao.listByNetworkOfferingId(offering.getId());
-
-        final boolean checkPhysicalNetwork = physicalNetworkId != null ? true : false;
-
-        for (final NetworkOfferingServiceMapVO serviceMap : servicesMap) {
-            if (svcProviders.containsKey(serviceMap.getService())) {
-                // FIXME - right now we pick up the first provider from the list, need to add more logic based on
-                // provider load, etc
-                continue;
-            }
-
-            final String service = serviceMap.getService();
-            String provider = serviceMap.getProvider();
-
-            if (provider == null) {
-                provider = _networkModel.getDefaultUniqueProviderForService(service).getName();
-            }
-
-            // check that provider is supported
-            if (checkPhysicalNetwork) {
-                if (!_pNSPDao.isServiceProviderEnabled(physicalNetworkId, provider, service)) {
-                    throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't " + "support service " + service + " in physical network id="
-                            + physicalNetworkId);
-                }
-            }
-
-            svcProviders.put(service, provider);
-            List<String> l = providerSvcs.get(provider);
-            if (l == null) {
-                providerSvcs.put(provider, l = new ArrayList<String>());
-            }
-            l.add(service);
-        }
-
-        return svcProviders;
-    }
-
-    private List<Provider> getNetworkProviders(final long networkId) {
-        final List<String> providerNames = _ntwkSrvcDao.getDistinctProviders(networkId);
-        final List<Provider> providers = new ArrayList<Provider>();
-        for (final String providerName : providerNames) {
-            providers.add(Network.Provider.getProvider(providerName));
-        }
-
-        return providers;
-    }
-
-    @Override
-    public boolean setupDns(final Network network, final Provider provider) {
-        final boolean dnsProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, provider);
-        final boolean dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, provider);
-
-        final boolean setupDns = dnsProvided || dhcpProvided;
-        return setupDns;
-    }
-
-    protected NicProfile getNicProfileForVm(final Network network, final NicProfile requested, final VirtualMachine vm) {
-        NicProfile nic = null;
-        if (requested != null && requested.getBroadCastUri() != null) {
-            final String broadcastUri = requested.getBroadCastUri().toString();
-            final String ipAddress = requested.getIPv4Address();
-            final NicVO nicVO = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri);
-            if (nicVO != null) {
-                if (ipAddress == null || nicVO.getIPv4Address().equals(ipAddress)) {
-                    nic = _networkModel.getNicProfile(vm, network.getId(), broadcastUri);
-                }
-            }
-        } else {
-            final NicVO nicVO = _nicDao.findByNtwkIdAndInstanceId(network.getId(), vm.getId());
-            if (nicVO != null) {
-                nic = _networkModel.getNicProfile(vm, network.getId(), null);
-            }
-        }
-        return nic;
-    }
-
-    @Override
-    public NicProfile createNicForVm(final Network network, final NicProfile requested, final ReservationContext context, final VirtualMachineProfile vmProfile, final boolean prepare)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
-            ResourceUnavailableException {
-
-        final VirtualMachine vm = vmProfile.getVirtualMachine();
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        final Host host = _hostDao.findById(vm.getHostId());
-        final DeployDestination dest = new DeployDestination(dc, null, null, host);
-
-        NicProfile nic = getNicProfileForVm(network, requested, vm);
-
-        //1) allocate nic (if needed) Always allocate if it is a user vm
-        if (nic == null || vmProfile.getType() == VirtualMachine.Type.User) {
-            final int deviceId = _nicDao.getFreeDeviceId(vm.getId());
-
-            nic = allocateNic(requested, network, false, deviceId, vmProfile).first();
-
-            if (nic == null) {
-                throw new CloudRuntimeException("Failed to allocate nic for vm " + vm + " in network " + network);
-            }
-
-            //Update vm_network_map table
-            if(vmProfile.getType() == VirtualMachine.Type.User) {
-                final VMNetworkMapVO vno = new VMNetworkMapVO(vm.getId(), network.getId());
-                _vmNetworkMapDao.persist(vno);
-            }
-            s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network);
-        }
-
-        //2) prepare nic
-        if (prepare) {
-            final Pair<NetworkGuru, NetworkVO> implemented = implementNetwork(nic.getNetworkId(), dest, context, vmProfile.getVirtualMachine().getType() == Type.DomainRouter);
-            if (implemented == null || implemented.first() == null) {
-                s_logger.warn("Failed to implement network id=" + nic.getNetworkId() + " as a part of preparing nic id=" + nic.getId());
-                throw new CloudRuntimeException("Failed to implement network id=" + nic.getNetworkId() + " as a part preparing nic id=" + nic.getId());
-            }
-            nic = prepareNic(vmProfile, dest, context, nic.getId(), implemented.second());
-            s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network);
-        }
-
-        return nic;
-    }
-
-    @Override
-    public List<NicProfile> getNicProfiles(final VirtualMachine vm) {
-        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        final List<NicProfile> profiles = new ArrayList<NicProfile>();
-
-        if (nics != null) {
-            for (final Nic nic : nics) {
-                final NetworkVO network = _networksDao.findById(nic.getNetworkId());
-                final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
-
-                final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
-                final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate,
-                        _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(), network));
-                guru.updateNicProfile(profile, network);
-                profiles.add(profile);
-            }
-        }
-        return profiles;
-    }
-
-    @Override
-    public Map<String, String> getSystemVMAccessDetails(final VirtualMachine vm) {
-        final Map<String, String> accessDetails = new HashMap<>();
-        accessDetails.put(NetworkElementCommand.ROUTER_NAME, vm.getInstanceName());
-        String privateIpAddress = null;
-        for (final NicProfile profile : getNicProfiles(vm)) {
-            if (profile == null) {
-                continue;
-            }
-            final Network network = _networksDao.findById(profile.getNetworkId());
-            if (network == null) {
-                continue;
-            }
-            final String address = profile.getIPv4Address();
-            if (network.getTrafficType() == Networks.TrafficType.Control) {
-                accessDetails.put(NetworkElementCommand.ROUTER_IP, address);
-            }
-            if (network.getTrafficType() == Networks.TrafficType.Guest) {
-                accessDetails.put(NetworkElementCommand.ROUTER_GUEST_IP, address);
-            }
-            if (network.getTrafficType() == Networks.TrafficType.Management) {
-                privateIpAddress = address;
-            }
-            if (network.getTrafficType() != null && !Strings.isNullOrEmpty(address)) {
-                accessDetails.put(network.getTrafficType().name(), address);
-            }
-        }
-        if (privateIpAddress != null && Strings.isNullOrEmpty(accessDetails.get(NetworkElementCommand.ROUTER_IP))) {
-            accessDetails.put(NetworkElementCommand.ROUTER_IP,  privateIpAddress);
-        }
-        return accessDetails;
-    }
-
-    protected boolean stateTransitTo(final NetworkVO network, final Network.Event e) throws NoTransitionException {
-        return _stateMachine.transitTo(network, e, null, _networksDao);
-    }
-
-    private void setStateMachine() {
-        _stateMachine = Network.State.getStateMachine();
-    }
-
-    private Map<Service, Set<Provider>> getServiceProvidersMap(final long networkId) {
-        final Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
-        final List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
-        for (final NetworkServiceMapVO nsm : nsms) {
-            Set<Provider> providers = map.get(Service.getService(nsm.getService()));
-            if (providers == null) {
-                providers = new HashSet<Provider>();
-            }
-            providers.add(Provider.getProvider(nsm.getProvider()));
-            map.put(Service.getService(nsm.getService()), providers);
-        }
-        return map;
-    }
-
-    @Override
-    public List<Provider> getProvidersForServiceInNetwork(final Network network, final Service service) {
-        final Map<Service, Set<Provider>> service2ProviderMap = getServiceProvidersMap(network.getId());
-        if (service2ProviderMap.get(service) != null) {
-            final List<Provider> providers = new ArrayList<Provider>(service2ProviderMap.get(service));
-            return providers;
-        }
-        return null;
-    }
-
-    protected List<NetworkElement> getElementForServiceInNetwork(final Network network, final Service service) {
-        final List<NetworkElement> elements = new ArrayList<NetworkElement>();
-        final List<Provider> providers = getProvidersForServiceInNetwork(network, service);
-        //Only support one provider now
-        if (providers == null) {
-            s_logger.error("Cannot find " + service.getName() + " provider for network " + network.getId());
-            return null;
-        }
-        if (providers.size() != 1 && service != Service.Lb) {
-            //support more than one LB providers only
-            s_logger.error("Found " + providers.size() + " " + service.getName() + " providers for network!" + network.getId());
-            return null;
-        }
-
-        for (final Provider provider : providers) {
-            final NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
-            s_logger.info("Let " + element.getName() + " handle " + service.getName() + " in network " + network.getId());
-            elements.add(element);
-        }
-        return elements;
-    }
-
-    @Override
-    public StaticNatServiceProvider getStaticNatProviderForNetwork(final Network network) {
-        //only one provider per Static nat service is supoprted
-        final NetworkElement element = getElementForServiceInNetwork(network, Service.StaticNat).get(0);
-        assert element instanceof StaticNatServiceProvider;
-        return (StaticNatServiceProvider)element;
-    }
-
-    @Override
-    public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(final Network network, final Scheme lbScheme) {
-        final List<NetworkElement> lbElements = getElementForServiceInNetwork(network, Service.Lb);
-        NetworkElement lbElement = null;
-        if (lbElements.size() > 1) {
-            String providerName = null;
-            //get network offering details
-            final NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-            if (lbScheme == Scheme.Public) {
-                providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.PublicLbProvider);
-            } else {
-                providerName = _ntwkOffDetailsDao.getDetail(off.getId(), NetworkOffering.Detail.InternalLbProvider);
-            }
-            if (providerName == null) {
-                throw new InvalidParameterValueException("Can't find Lb provider supporting scheme " + lbScheme.toString() + " in network " + network);
-            }
-            lbElement = _networkModel.getElementImplementingProvider(providerName);
-        } else if (lbElements.size() == 1) {
-            lbElement = lbElements.get(0);
-        }
-
-        assert lbElement != null;
-        assert lbElement instanceof LoadBalancingServiceProvider;
-        return (LoadBalancingServiceProvider)lbElement;
-    }
-
-    @Override
-    public boolean isNetworkInlineMode(final Network network) {
-        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        return offering.isInline();
-    }
-
-    @Override
-    public boolean isSecondaryIpSetForNic(final long nicId) {
-        final NicVO nic = _nicDao.findById(nicId);
-        return nic.getSecondaryIp();
-    }
-
-    private boolean removeVmSecondaryIpsOfNic(final long nicId) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                final List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
-                if (ipList != null) {
-                    for (final NicSecondaryIpVO ip : ipList) {
-                        _nicSecondaryIpDao.remove(ip.getId());
-                    }
-                    s_logger.debug("Revoving nic secondary ip entry ...");
-                }
-            }
-        });
-
-        return true;
-    }
-
-    @Override
-    public NicVO savePlaceholderNic(final Network network, final String ip4Address, final String ip6Address, final Type vmType) {
-        final NicVO nic = new NicVO(null, null, network.getId(), null);
-        nic.setIPv4Address(ip4Address);
-        nic.setIPv6Address(ip6Address);
-        nic.setReservationStrategy(ReservationStrategy.PlaceHolder);
-        nic.setState(Nic.State.Reserved);
-        nic.setVmType(vmType);
-        return _nicDao.persist(nic);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return NetworkOrchestrationService.class.getSimpleName();
-    }
-
-    public static final ConfigKey<Integer> NetworkGcWait = new ConfigKey<Integer>(Integer.class, "network.gc.wait", "Advanced", "600",
-            "Time (in seconds) to wait before shutting down a network that's not in used", false, Scope.Global, null);
-    public static final ConfigKey<Integer> NetworkGcInterval = new ConfigKey<Integer>(Integer.class, "network.gc.interval", "Advanced", "600",
-            "Seconds to wait before checking for networks to shutdown", true, Scope.Global, null);
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
-                GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
-                PromiscuousMode, MacAddressChanges, ForgedTransmits, RollingRestartEnabled};
-    }
-}
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
deleted file mode 100644
index 7435a3e..0000000
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ /dev/null
@@ -1,1597 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.engine.orchestration;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-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;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.manager.allocator.PodAllocator;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientStorageCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.org.Cluster;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.Type;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.UserVmCloneSettingVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.VirtualMachineProfileImpl;
-import com.cloud.vm.VmWorkAttachVolume;
-import com.cloud.vm.VmWorkMigrateVolume;
-import com.cloud.vm.VmWorkSerializer;
-import com.cloud.vm.VmWorkTakeVolumeSnapshot;
-import com.cloud.vm.dao.UserVmCloneSettingDao;
-import com.cloud.vm.dao.UserVmDao;
-
-public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable {
-
-    public enum UserVmCloneType {
-        full, linked
-    }
-
-    private static final Logger s_logger = Logger.getLogger(VolumeOrchestrator.class);
-
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    protected TemplateManager _tmpltMgr;
-    @Inject
-    protected VolumeDao _volsDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao = null;
-    @Inject
-    protected TemplateDataStoreDao _vmTemplateStoreDao = null;
-    @Inject
-    protected VolumeDao _volumeDao;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected SnapshotDataStoreDao _snapshotDataStoreDao;
-    @Inject
-    protected ResourceLimitService _resourceLimitMgr;
-    @Inject
-    VolumeDetailsDao _volDetailDao;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    VolumeService volService;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    TemplateDataFactory tmplFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    ConfigDepot _configDepot;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    SnapshotService _snapshotSrv;
-    @Inject
-    protected UserVmDao _userVmDao;
-    @Inject
-    protected AsyncJobManager _jobMgr;
-    @Inject
-    ClusterManager clusterManager;
-    @Inject
-    StorageManager storageMgr;
-    @Inject
-    protected UserVmCloneSettingDao _vmCloneSettingDao;
-    @Inject
-    StorageStrategyFactory _storageStrategyFactory;
-
-    private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
-    protected List<StoragePoolAllocator> _storagePoolAllocators;
-
-    public List<StoragePoolAllocator> getStoragePoolAllocators() {
-        return _storagePoolAllocators;
-    }
-
-    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
-        _storagePoolAllocators = storagePoolAllocators;
-    }
-
-    protected List<PodAllocator> _podAllocators;
-
-    public List<PodAllocator> getPodAllocators() {
-        return _podAllocators;
-    }
-
-    public void setPodAllocators(List<PodAllocator> podAllocators) {
-        _podAllocators = podAllocators;
-    }
-
-    protected VolumeOrchestrator() {
-        _volStateMachine = Volume.State.getStateMachine();
-    }
-
-    @Override
-    public VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType)
-            throws ConcurrentOperationException, StorageUnavailableException {
-
-        // Find a destination storage pool with the specified criteria
-        DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
-        DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
-                diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
-        dskCh.setHyperType(dataDiskHyperType);
-        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
-
-        DataCenter destPoolDataCenter = _entityMgr.findById(DataCenter.class, destPoolDcId);
-        Pod destPoolPod = _entityMgr.findById(Pod.class, destPoolPodId);
-
-        StoragePool destPool = findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, null, new HashSet<StoragePool>());
-
-        if (destPool == null) {
-            throw new CloudRuntimeException("Failed to find a storage pool with enough capacity to move the volume to.");
-        }
-
-        Volume newVol = migrateVolume(volume, destPool);
-        return volFactory.getVolume(newVol.getId());
-    }
-
-    @Override
-    public Volume allocateDuplicateVolume(Volume oldVol, Long templateId) {
-        return allocateDuplicateVolumeVO(oldVol, templateId);
-    }
-
-    public VolumeVO allocateDuplicateVolumeVO(Volume oldVol, Long templateId) {
-        VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(),
-                oldVol.getProvisioningType(), oldVol.getSize(), oldVol.getMinIops(), oldVol.getMaxIops(), oldVol.get_iScsiName());
-        if (templateId != null) {
-            newVol.setTemplateId(templateId);
-        } else {
-            newVol.setTemplateId(oldVol.getTemplateId());
-        }
-        newVol.setDeviceId(oldVol.getDeviceId());
-        newVol.setInstanceId(oldVol.getInstanceId());
-        newVol.setRecreatable(oldVol.isRecreatable());
-        newVol.setFormat(oldVol.getFormat());
-        return _volsDao.persist(newVol);
-    }
-
-    @Override
-    public StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, final Set<StoragePool> avoid) {
-        Long podId = null;
-        if (pod != null) {
-            podId = pod.getId();
-        } else if (clusterId != null) {
-            Cluster cluster = _entityMgr.findById(Cluster.class, clusterId);
-            if (cluster != null) {
-                podId = cluster.getPodId();
-            }
-        }
-
-        VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        for (StoragePoolAllocator allocator : _storagePoolAllocators) {
-
-            ExcludeList avoidList = new ExcludeList();
-            for (StoragePool pool : avoid) {
-                avoidList.addPool(pool.getId());
-            }
-            DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null);
-
-            final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1);
-            if (poolList != null && !poolList.isEmpty()) {
-                return (StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
-            }
-        }
-        return null;
-    }
-
-    public Pair<Pod, Long> findPod(VirtualMachineTemplate template, ServiceOffering offering, DataCenter dc, long accountId, Set<Long> avoids) {
-        for (PodAllocator allocator : _podAllocators) {
-            final Pair<Pod, Long> pod = allocator.allocateTo(template, offering, dc, accountId, avoids);
-            if (pod != null) {
-                return pod;
-            }
-        }
-        return null;
-    }
-
-    @DB
-    @Override
-    public VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, UserVm vm) throws StorageUnavailableException {
-        Account account = _entityMgr.findById(Account.class, volume.getAccountId());
-
-        final HashSet<StoragePool> poolsToAvoid = new HashSet<StoragePool>();
-        StoragePool pool = null;
-
-        Set<Long> podsToAvoid = new HashSet<Long>();
-        Pair<Pod, Long> pod = null;
-
-        DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
-        DataCenter dc = _entityMgr.findById(DataCenter.class, volume.getDataCenterId());
-        DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
-
-        String msg = "There are no available storage pools to store the volume in";
-
-        if (vm != null) {
-            Pod podofVM = _entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
-            if (podofVM != null) {
-                pod = new Pair<Pod, Long>(podofVM, podofVM.getId());
-            }
-        }
-
-        if (vm != null && pod != null) {
-            //if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
-            Long hostId = null;
-            Long clusterId = null;
-            if (vm.getState() == State.Running) {
-                hostId = vm.getHostId();
-                if (hostId != null) {
-                    Host vmHost = _entityMgr.findById(Host.class, hostId);
-                    clusterId = vmHost.getClusterId();
-                }
-            } else {
-                List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
-                if (rootVolumesOfVm.size() != 1) {
-                    throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
-                } else {
-                    VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
-                    StoragePoolVO rootDiskPool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId());
-                    clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
-                }
-            }
-            // Determine what storage pool to store the volume in
-            while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
-                break;
-            }
-
-            if (pool == null) {
-                //pool could not be found in the VM's pod/cluster.
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
-                }
-                StringBuilder addDetails = new StringBuilder(msg);
-                addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
-                addDetails.append(vm.getUuid());
-                msg = addDetails.toString();
-            }
-        } else {
-            // Determine what pod to store the volume in
-            while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
-                podsToAvoid.add(pod.first().getId());
-                // Determine what storage pool to store the volume in
-                while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
-                    break;
-                }
-
-                if (pool != null) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
-                    }
-                    break;
-                }
-            }
-        }
-
-        if (pool == null) {
-            s_logger.info(msg);
-            throw new StorageUnavailableException(msg, -1);
-        }
-
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-        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 {
-                // sync snapshot to region store if necessary
-                DataStore snapStore = snapInfo.getDataStore();
-                long snapVolId = snapInfo.getVolumeId();
-
-                _snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
-            } catch (Exception ex) {
-                // log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
-                s_logger.warn(ex.getMessage(), ex);
-            }
-        }
-
-        // create volume on primary from snapshot
-        AsyncCallFuture<VolumeApiResult> future = volService.createVolumeFromSnapshot(vol, store, snapInfo);
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
-                throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to create volume from snapshot", e);
-            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to create volume from snapshot", e);
-            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
-        }
-
-    }
-
-    public DataStoreRole getDataStoreRole(Snapshot snapshot) {
-        SnapshotDataStoreVO snapshotStore = _snapshotDataStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
-
-        if (snapshotStore == null) {
-            return DataStoreRole.Image;
-        }
-
-        long storagePoolId = snapshotStore.getDataStoreId();
-        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-
-        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
-
-        if (mapCapabilities != null) {
-            String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
-            Boolean supportsStorageSystemSnapshots = new Boolean(value);
-
-            if (supportsStorageSystemSnapshots) {
-                return DataStoreRole.Primary;
-            }
-        }
-
-        return DataStoreRole.Image;
-    }
-
-    protected DiskProfile createDiskCharacteristics(VolumeInfo volume, VirtualMachineTemplate template, DataCenter dc, DiskOffering diskOffering) {
-        if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
-            TemplateDataStoreVO ss = _vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dc.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-            if (ss == null) {
-                throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId());
-            }
-
-            return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(), diskOffering.getUseLocalStorage(),
-                    diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null);
-        } else {
-            return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
-                    diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
-        }
-    }
-
-    @DB
-    public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
-            DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
-
-        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
-        DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
-        dskCh.setHyperType(vm.getHypervisorType());
-        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
-
-        // Find a suitable storage to create volume on
-        StoragePool destPool = findStoragePool(dskCh, dc, pod, clusterId, null, vm, avoidPools);
-        DataStore destStore = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
-        AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(volume, destStore);
-
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("copy volume failed: " + result.getResult());
-                throw new CloudRuntimeException("copy volume failed: " + result.getResult());
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
-            throw new CloudRuntimeException("Failed to copy volume", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
-            throw new CloudRuntimeException("Failed to copy volume", e);
-        }
-    }
-
-    @DB
-    public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering,
-            List<StoragePool> avoids, long size, HypervisorType hyperType) {
-        // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-        volume = volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
-
-        StoragePool pool = null;
-
-        DiskProfile dskCh = null;
-        if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
-            dskCh = createDiskCharacteristics(volume, template, dc, offering);
-            storageMgr.setDiskProfileThrottling(dskCh, offering, diskOffering);
-        } else {
-            dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
-            storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
-        }
-
-        if (diskOffering != null && diskOffering.isCustomized()) {
-            dskCh.setSize(size);
-        }
-
-        dskCh.setHyperType(hyperType);
-
-        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
-
-        pool = findStoragePool(dskCh, dc, pod, clusterId, vm.getHostId(), vm, avoidPools);
-        if (pool == null) {
-            s_logger.warn("Unable to find suitable primary storage when creating volume " + volume.getName());
-            throw new CloudRuntimeException("Unable to find suitable primary storage when creating volume " + volume.getName());
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Trying to create " + volume + " on " + pool);
-        }
-        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-        for (int i = 0; i < 2; i++) {
-            // retry one more time in case of template reload is required for Vmware case
-            AsyncCallFuture<VolumeApiResult> future = null;
-            boolean isNotCreatedFromTemplate = volume.getTemplateId() == null ? true : false;
-            if (isNotCreatedFromTemplate) {
-                future = volService.createVolumeAsync(volume, store);
-            } else {
-                TemplateInfo templ = tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
-                future = volService.createVolumeFromTemplateAsync(volume, store.getId(), templ);
-            }
-            try {
-                VolumeApiResult result = future.get();
-                if (result.isFailed()) {
-                    if (result.getResult().contains("request template reload") && (i == 0)) {
-                        s_logger.debug("Retry template re-deploy for vmware");
-                        continue;
-                    } else {
-                        s_logger.debug("create volume failed: " + result.getResult());
-                        throw new CloudRuntimeException("create volume failed:" + result.getResult());
-                    }
-                }
-
-                return result.getVolume();
-            } catch (InterruptedException e) {
-                s_logger.error("create volume failed", e);
-                throw new CloudRuntimeException("create volume failed", e);
-            } catch (ExecutionException e) {
-                s_logger.error("create volume failed", e);
-                throw new CloudRuntimeException("create volume failed", e);
-            }
-        }
-        throw new CloudRuntimeException("create volume failed even after template re-deploy");
-    }
-
-    public String getRandomVolumeName() {
-        return UUID.randomUUID().toString();
-    }
-
-    @Override
-    public boolean volumeOnSharedStoragePool(Volume volume) {
-        Long poolId = volume.getPoolId();
-        if (poolId == null) {
-            return false;
-        } else {
-            StoragePoolVO pool = _storagePoolDao.findById(poolId);
-
-            if (pool == null) {
-                return false;
-            } else {
-                return (pool.getScope() == ScopeType.HOST) ? false : true;
-            }
-        }
-    }
-
-    @Override
-    public boolean volumeInactive(Volume volume) {
-        Long vmId = volume.getInstanceId();
-
-        if (vmId == null) {
-            return true;
-        }
-
-        UserVm vm = _entityMgr.findById(UserVm.class, vmId);
-
-        if (vm == null) {
-            return true;
-        }
-
-        State state = vm.getState();
-
-        if (state.equals(State.Stopped) || state.equals(State.Destroyed)) {
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public String getVmNameOnVolume(Volume volume) {
-        Long vmId = volume.getInstanceId();
-        if (vmId != null) {
-            VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, vmId);
-
-            if (vm == null) {
-                return null;
-            }
-            return vm.getInstanceName();
-        }
-        return null;
-    }
-
-    @Override
-    public boolean validateVolumeSizeRange(long size) {
-        if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
-            throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
-        } else if (size > (MaxVolumeSize.value() * 1024 * 1024 * 1024)) {
-            throw new InvalidParameterValueException("volume size " + size + ", but the maximum size allowed is " + MaxVolumeSize + " GB.");
-        }
-
-        return true;
-    }
-
-    protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) {
-        return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.isRecreatable(),
-                vol.getTemplateId());
-    }
-
-    @Override
-    public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
-            Long deviceId) {
-        if (size == null) {
-            size = offering.getDiskSize();
-        } else {
-            size = (size * 1024 * 1024 * 1024);
-        }
-
-        minIops = minIops != null ? minIops : offering.getMinIops();
-        maxIops = maxIops != null ? maxIops : offering.getMaxIops();
-
-        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
-        if (vm != null) {
-            vol.setInstanceId(vm.getId());
-        }
-
-        if (deviceId != null) {
-            vol.setDeviceId(deviceId);
-        } else if (type.equals(Type.ROOT)) {
-            vol.setDeviceId(0l);
-        } else {
-            vol.setDeviceId(1l);
-        }
-        if (template.getFormat() == ImageFormat.ISO) {
-            vol.setIsoId(template.getId());
-        } else if (template.getTemplateType().equals(Storage.TemplateType.DATADISK)) {
-            vol.setTemplateId(template.getId());
-        }
-        // display flag matters only for the User vms
-        if (vm.getType() == VirtualMachine.Type.User) {
-            UserVmVO userVm = _userVmDao.findById(vm.getId());
-            vol.setDisplayVolume(userVm.isDisplayVm());
-        }
-
-        vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
-        vol = _volsDao.persist(vol);
-
-        // Save usage event and update resource count for user vm volumes
-        if (vm.getType() == VirtualMachine.Type.User) {
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
-                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
-
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
-        }
-        return toDiskProfile(vol, offering);
-    }
-
-    @Override
-    public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
-            Account owner) {
-        assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
-
-        Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
-        if (rootDisksize != null) {
-            rootDisksize = rootDisksize * 1024 * 1024 * 1024;
-            if (rootDisksize > size) {
-                s_logger.debug("Using root disk size of " + rootDisksize + " Bytes for volume " + name);
-                size = rootDisksize;
-            } else {
-                s_logger.debug("Using root disk size of " + size + " Bytes for volume " + name + "since specified root disk size of " + rootDisksize + " Bytes is smaller than template");
-            }
-        }
-
-        minIops = minIops != null ? minIops : offering.getMinIops();
-        maxIops = maxIops != null ? maxIops : offering.getMaxIops();
-
-        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
-        vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
-        if (vm != null) {
-            vol.setInstanceId(vm.getId());
-        }
-        vol.setTemplateId(template.getId());
-
-        if (type.equals(Type.ROOT)) {
-            vol.setDeviceId(0l);
-            if (!vm.getType().equals(VirtualMachine.Type.User)) {
-                vol.setRecreatable(true);
-            }
-        } else {
-            vol.setDeviceId(1l);
-        }
-
-        if (vm.getType() == VirtualMachine.Type.User) {
-            UserVmVO userVm = _userVmDao.findById(vm.getId());
-            vol.setDisplayVolume(userVm.isDisplayVm());
-        }
-
-        vol = _volsDao.persist(vol);
-
-        // Create event and update resource count for volumes if vm is a user vm
-        if (vm.getType() == VirtualMachine.Type.User) {
-
-            Long offeringId = null;
-
-            if (offering.getType() == DiskOffering.Type.Disk) {
-                offeringId = offering.getId();
-            }
-
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
-                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
-
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
-        }
-        return toDiskProfile(vol, offering);
-    }
-
-    private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) {
-        if (hyperType == HypervisorType.XenServer) {
-            return ImageFormat.VHD;
-        } else if (hyperType == HypervisorType.KVM) {
-            return ImageFormat.QCOW2;
-        } else if (hyperType == HypervisorType.VMware) {
-            return ImageFormat.OVA;
-        } else if (hyperType == HypervisorType.Ovm) {
-            return ImageFormat.RAW;
-        } else if (hyperType == HypervisorType.Hyperv) {
-            return ImageFormat.VHDX;
-        } else {
-            return null;
-        }
-    }
-
-    private boolean isSupportedImageFormatForCluster(VolumeInfo volume, HypervisorType rootDiskHyperType) {
-        ImageFormat volumeFormat = volume.getFormat();
-        if (rootDiskHyperType == HypervisorType.Hyperv) {
-            if (volumeFormat.equals(ImageFormat.VHDX) || volumeFormat.equals(ImageFormat.VHD)) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            return volume.getFormat().equals(getSupportedImageFormatForCluster(rootDiskHyperType));
-        }
-    }
-
-    private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod, DiskOffering diskVO,
-            ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
-
-        if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) {
-            throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type");
-        }
-
-        VolumeInfo volumeOnPrimary = copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePool>(), volume.getSize(),
-                rootDiskHyperType);
-
-        return volumeOnPrimary;
-    }
-
-    @Override
-    public VolumeInfo createVolumeOnPrimaryStorage(VirtualMachine vm, VolumeInfo volume, HypervisorType rootDiskHyperType, StoragePool storagePool) throws NoTransitionException {
-        VirtualMachineTemplate rootDiskTmplt = _entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
-        DataCenter dcVO = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
-        Pod pod = _entityMgr.findById(Pod.class, storagePool.getPodId());
-
-        ServiceOffering svo = _entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
-        DiskOffering diskVO = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
-        Long clusterId = storagePool.getClusterId();
-
-        VolumeInfo vol = null;
-        if (volume.getState() == Volume.State.Allocated) {
-            vol = createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<StoragePool>(), volume.getSize(), rootDiskHyperType);
-        } else if (volume.getState() == Volume.State.Uploaded) {
-            vol = copyVolume(storagePool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, svo, rootDiskHyperType);
-            if (vol != null) {
-                // Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize());
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize());
-            }
-        }
-
-        if (vol == null) {
-            throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId());
-        }
-        VolumeVO volVO = _volsDao.findById(vol.getId());
-        if (volVO.getFormat() == null) {
-            volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
-        }
-        _volsDao.update(volVO.getId(), volVO);
-        return volFactory.getVolume(volVO.getId());
-    }
-
-    @DB
-    protected VolumeVO switchVolume(final VolumeVO existingVolume, final VirtualMachineProfile vm) throws StorageUnavailableException {
-        Long templateIdToUse = null;
-        Long volTemplateId = existingVolume.getTemplateId();
-        long vmTemplateId = vm.getTemplateId();
-        if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId + ", updating templateId in the new Volume");
-            }
-            templateIdToUse = vmTemplateId;
-        }
-
-        final Long templateIdToUseFinal = templateIdToUse;
-        return Transaction.execute(new TransactionCallback<VolumeVO>() {
-            @Override
-            public VolumeVO doInTransaction(TransactionStatus status) {
-                VolumeVO newVolume = allocateDuplicateVolumeVO(existingVolume, templateIdToUseFinal);
-                try {
-                    stateTransitTo(existingVolume, Volume.Event.DestroyRequested);
-                } catch (NoTransitionException e) {
-                    s_logger.debug("Unable to destroy existing volume: " + e.toString());
-                }
-                // In case of VMware VM will continue to use the old root disk until expunged, so force expunge old root disk
-                if (vm.getHypervisorType() == HypervisorType.VMware) {
-                    s_logger.info("Expunging volume " + existingVolume.getId() + " from primary data store");
-                    AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(existingVolume.getId()));
-                    try {
-                        future.get();
-                    } catch (Exception e) {
-                        s_logger.debug("Failed to expunge volume:" + existingVolume.getId(), e);
-                    }
-                }
-
-                return newVolume;
-            }
-        });
-    }
-
-    @Override
-    public void release(VirtualMachineProfile profile) {
-        // add code here
-    }
-
-    @Override
-    @DB
-    public void cleanupVolumes(long vmId) throws ConcurrentOperationException {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Cleaning storage for vm: " + vmId);
-        }
-        final List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
-        final List<VolumeVO> toBeExpunged = new ArrayList<VolumeVO>();
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                for (VolumeVO vol : volumesForVm) {
-                    if (vol.getVolumeType().equals(Type.ROOT)) {
-                        // Destroy volume if not already destroyed
-                        boolean volumeAlreadyDestroyed = (vol.getState() == Volume.State.Destroy || vol.getState() == Volume.State.Expunged || vol.getState() == Volume.State.Expunging);
-                        if (!volumeAlreadyDestroyed) {
-                            volService.destroyVolume(vol.getId());
-                        } else {
-                            s_logger.debug("Skipping destroy for the volume " + vol + " as its in state " + vol.getState().toString());
-                        }
-                        toBeExpunged.add(vol);
-                    } else {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Detaching " + vol);
-                        }
-                        _volsDao.detachVolume(vol.getId());
-                    }
-                }
-            }
-        });
-
-        AsyncCallFuture<VolumeApiResult> future = null;
-        for (VolumeVO expunge : toBeExpunged) {
-            future = volService.expungeVolumeAsync(volFactory.getVolume(expunge.getId()));
-            try {
-                future.get();
-            } catch (InterruptedException e) {
-                s_logger.debug("failed expunge volume" + expunge.getId(), e);
-            } catch (ExecutionException e) {
-                s_logger.debug("failed expunge volume" + expunge.getId(), e);
-            }
-        }
-    }
-
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
-
-        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
-            ((PrimaryDataStoreDriver)dataStoreDriver).revokeAccess(dataObject, host, dataStore);
-        }
-    }
-
-    @Override
-    public void revokeAccess(long vmId, long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-
-        List<VolumeVO> volumesForVm = _volsDao.findByInstance(vmId);
-
-        if (volumesForVm != null) {
-            for (VolumeVO volumeForVm : volumesForVm) {
-                VolumeInfo volumeInfo = volFactory.getVolume(volumeForVm.getId());
-
-                // pool id can be null for the VM's volumes in Allocated state
-                if (volumeForVm.getPoolId() != null) {
-                    DataStore dataStore = dataStoreMgr.getDataStore(volumeForVm.getPoolId(), DataStoreRole.Primary);
-
-                    volService.revokeAccess(volumeInfo, host, dataStore);
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(vol, (DataStore)destPool);
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.error("Migrate volume failed:" + result.getResult());
-                throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
-            } else {
-                // update the volumeId for snapshots on secondary
-                if (!_snapshotDao.listByVolumeId(vol.getId()).isEmpty()) {
-                    _snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
-                    _snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId());
-                }
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("migrate volume failed", e);
-            throw new CloudRuntimeException(e.getMessage());
-        } catch (ExecutionException e) {
-            s_logger.debug("migrate volume failed", e);
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @DB
-    protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) {
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore)destPool);
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("migrate volume failed:" + result.getResult());
-                return null;
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("migrate volume failed", e);
-            return null;
-        } catch (ExecutionException e) {
-            s_logger.debug("migrate volume failed", e);
-            return null;
-        }
-    }
-
-    @Override
-    public void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map<Volume, StoragePool> volumeToPool) {
-        // Check if all the vms being migrated belong to the vm.
-        // Check if the storage pool is of the right type.
-        // Create a VolumeInfo to DataStore map too.
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        for (Map.Entry<Volume, StoragePool> entry : volumeToPool.entrySet()) {
-            Volume volume = entry.getKey();
-            StoragePool storagePool = entry.getValue();
-            StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(storagePool.getId(), DataStoreRole.Primary);
-
-            if (volume.getInstanceId() != vm.getId()) {
-                throw new CloudRuntimeException("Volume " + volume + " that has to be migrated doesn't belong to the" + " instance " + vm);
-            }
-
-            if (destPool == null) {
-                throw new CloudRuntimeException("Failed to find the destination storage pool " + storagePool.getId());
-            }
-
-            volumeMap.put(volFactory.getVolume(volume.getId()), (DataStore)destPool);
-        }
-
-        AsyncCallFuture<CommandResult> future = volService.migrateVolumes(volumeMap, vmTo, srcHost, destHost);
-        try {
-            CommandResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("Failed to migrated vm " + vm + " along with its volumes. " + result.getResult());
-                throw new CloudRuntimeException("Failed to migrated vm " + vm + " along with its volumes. ");
-            }
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to migrated vm " + vm + " along with its volumes.", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to migrated vm " + vm + " along with its volumes.", e);
-        }
-    }
-
-    @Override
-    public boolean storageMigration(VirtualMachineProfile vm, StoragePool destPool) throws StorageUnavailableException {
-        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
-        List<Volume> volumesNeedToMigrate = new ArrayList<Volume>();
-
-        for (VolumeVO volume : vols) {
-            if (volume.getState() != Volume.State.Ready) {
-                s_logger.debug("volume: " + volume.getId() + " is in " + volume.getState() + " state");
-                throw new CloudRuntimeException("volume: " + volume.getId() + " is in " + volume.getState() + " state");
-            }
-
-            if (volume.getPoolId() == destPool.getId()) {
-                s_logger.debug("volume: " + volume.getId() + " is on the same storage pool: " + destPool.getId());
-                continue;
-            }
-
-            volumesNeedToMigrate.add(volume);
-        }
-
-        if (volumesNeedToMigrate.isEmpty()) {
-            s_logger.debug("No volume need to be migrated");
-            return true;
-        }
-
-        for (Volume vol : volumesNeedToMigrate) {
-            Volume result = migrateVolume(vol, destPool);
-            if (result == null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest) {
-        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Preparing " + vols.size() + " volumes for " + vm);
-        }
-
-        for (VolumeVO vol : vols) {
-            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
-            DataTO volTO = volumeInfo.getTO();
-            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
-            DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
-
-            disk.setDetails(getDetails(volumeInfo, dataStore));
-
-            vm.addDisk(disk);
-        }
-
-        //if (vm.getType() == VirtualMachine.Type.User && vm.getTemplate().getFormat() == ImageFormat.ISO) {
-        if (vm.getType() == VirtualMachine.Type.User) {
-            _tmpltMgr.prepareIsoForVmProfile(vm, dest);
-            //DataTO dataTO = tmplFactory.getTemplate(vm.getTemplate().getId(), DataStoreRole.Image, vm.getVirtualMachine().getDataCenterId()).getTO();
-            //DiskTO iso = new DiskTO(dataTO, 3L, null, Volume.Type.ISO);
-            //vm.addDisk(iso);
-        }
-    }
-
-    private Map<String, String> getDetails(VolumeInfo volumeInfo, DataStore dataStore) {
-        Map<String, String> details = new HashMap<String, String>();
-
-        StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
-
-        details.put(DiskTO.MANAGED, String.valueOf(storagePool.isManaged()));
-        details.put(DiskTO.STORAGE_HOST, storagePool.getHostAddress());
-        details.put(DiskTO.STORAGE_PORT, String.valueOf(storagePool.getPort()));
-        details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeInfo.getSize()));
-        details.put(DiskTO.IQN, volumeInfo.get_iScsiName());
-        details.put(DiskTO.MOUNT_POINT, volumeInfo.get_iScsiName());
-
-        VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
-
-        details.put(DiskTO.PROTOCOL_TYPE, (volume.getPoolType() != null) ? volume.getPoolType().toString() : null);
-
-        ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
-
-        if (chapInfo != null) {
-            details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
-            details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
-            details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
-            details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
-        }
-
-        return details;
-    }
-
-    private static enum VolumeTaskType {
-        RECREATE, NOP, MIGRATE
-    }
-
-    private static class VolumeTask {
-        final VolumeTaskType type;
-        final StoragePoolVO pool;
-        final VolumeVO volume;
-
-        VolumeTask(VolumeTaskType type, VolumeVO volume, StoragePoolVO pool) {
-            this.type = type;
-            this.pool = pool;
-            this.volume = volume;
-        }
-    }
-
-    private List<VolumeTask> getTasks(List<VolumeVO> vols, Map<Volume, StoragePool> destVols, VirtualMachineProfile vm) throws StorageUnavailableException {
-        boolean recreate = RecreatableSystemVmEnabled.value();
-        List<VolumeTask> tasks = new ArrayList<VolumeTask>();
-        for (VolumeVO vol : vols) {
-            StoragePoolVO assignedPool = null;
-            if (destVols != null) {
-                StoragePool pool = destVols.get(vol);
-                if (pool != null) {
-                    assignedPool = _storagePoolDao.findById(pool.getId());
-                }
-            }
-            if (assignedPool == null && recreate) {
-                assignedPool = _storagePoolDao.findById(vol.getPoolId());
-            }
-            if (assignedPool != null) {
-                Volume.State state = vol.getState();
-                if (state == Volume.State.Allocated || state == Volume.State.Creating) {
-                    VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
-                    tasks.add(task);
-                } else {
-                    if (vol.isRecreatable()) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
-                        }
-                        VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
-                        tasks.add(task);
-                    } else {
-                        if (assignedPool.getId() != vol.getPoolId()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Mismatch in storage pool " + assignedPool + " assigned by deploymentPlanner and the one associated with volume " + vol);
-                            }
-                            DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
-                            if (diskOffering.getUseLocalStorage()) {
-                                // Currently migration of local volume is not supported so bail out
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
-                                }
-                                throw new CloudRuntimeException("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
-                            } else {
-                                //Check if storage migration is enabled in config
-                                Boolean isHAOperation = (Boolean)vm.getParameter(VirtualMachineProfile.Param.HaOperation);
-                                Boolean storageMigrationEnabled = true;
-                                if (isHAOperation != null && isHAOperation) {
-                                    storageMigrationEnabled = StorageHAMigrationEnabled.value();
-                                } else {
-                                    storageMigrationEnabled = StorageMigrationEnabled.value();
-                                }
-                                if (storageMigrationEnabled) {
-                                    if (s_logger.isDebugEnabled()) {
-                                        s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
-                                    }
-                                    VolumeTask task = new VolumeTask(VolumeTaskType.MIGRATE, vol, assignedPool);
-                                    tasks.add(task);
-                                } else {
-                                    throw new CloudRuntimeException("Cannot migrate volumes. Volume Migration is disabled");
-                                }
-                            }
-                        } else {
-                            StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
-                            VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
-                            tasks.add(task);
-                        }
-
-                    }
-                }
-            } else {
-                if (vol.getPoolId() == null) {
-                    throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol, Volume.class, vol.getId());
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
-                }
-                StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId());
-                VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
-                tasks.add(task);
-            }
-        }
-
-        return tasks;
-    }
-
-    private Pair<VolumeVO, DataStore> recreateVolume(VolumeVO vol, VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException {
-        VolumeVO newVol;
-        boolean recreate = RecreatableSystemVmEnabled.value();
-        DataStore destPool = null;
-        if (recreate && (dest.getStorageForDisks() == null || dest.getStorageForDisks().get(vol) == null)) {
-            destPool = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
-            s_logger.debug("existing pool: " + destPool.getId());
-        } else {
-            StoragePool pool = dest.getStorageForDisks().get(vol);
-            destPool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-        }
-        if (vol.getState() == Volume.State.Allocated || vol.getState() == Volume.State.Creating) {
-            newVol = vol;
-        } else {
-            newVol = switchVolume(vol, vm);
-            // update the volume->PrimaryDataStoreVO map since volumeId has
-            // changed
-            if (dest.getStorageForDisks() != null && dest.getStorageForDisks().containsKey(vol)) {
-                StoragePool poolWithOldVol = dest.getStorageForDisks().get(vol);
-                dest.getStorageForDisks().put(newVol, poolWithOldVol);
-                dest.getStorageForDisks().remove(vol);
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Created new volume " + newVol + " for old volume " + vol);
-            }
-        }
-        VolumeInfo volume = volFactory.getVolume(newVol.getId(), destPool);
-        Long templateId = newVol.getTemplateId();
-        for (int i = 0; i < 2; i++) {
-            // retry one more time in case of template reload is required for VMware case
-            AsyncCallFuture<VolumeApiResult> future;
-
-            if (templateId == null) {
-                DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
-                HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
-
-                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-                volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
-
-                volume = volFactory.getVolume(newVol.getId(), destPool);
-
-                future = volService.createVolumeAsync(volume, destPool);
-            } else {
-                TemplateInfo templ = tmplFactory.getReadyTemplateOnImageStore(templateId, dest.getDataCenter().getId());
-
-                if (templ == null) {
-                    if (tmplFactory.isTemplateMarkedForDirectDownload(templateId)) {
-                        // Template is marked for direct download bypassing Secondary Storage
-                        templ = tmplFactory.getReadyBypassedTemplateOnPrimaryStore(templateId, destPool.getId(), dest.getHost().getId());
-                    } else {
-                        s_logger.debug("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
-                        throw new CloudRuntimeException("can't find ready template: " + templateId + " for data center " + dest.getDataCenter().getId());
-                    }
-                }
-
-                PrimaryDataStore primaryDataStore = (PrimaryDataStore)destPool;
-
-                if (primaryDataStore.isManaged()) {
-                    DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
-                    HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType();
-
-                    // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-                    volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
-
-                    long hostId = vm.getVirtualMachine().getHostId();
-
-                    future = volService.createManagedStorageVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
-                } else {
-                    future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
-                }
-            }
-            VolumeApiResult result;
-            try {
-                result = future.get();
-                if (result.isFailed()) {
-                    if (result.getResult().contains("request template reload") && (i == 0)) {
-                        s_logger.debug("Retry template re-deploy for vmware");
-                        continue;
-                    } else {
-                        s_logger.debug("Unable to create " + newVol + ":" + result.getResult());
-                        throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId());
-                    }
-                }
-
-                StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId());
-
-                if (storagePool.isManaged()) {
-                    long hostId = vm.getVirtualMachine().getHostId();
-                    Host host = _hostDao.findById(hostId);
-
-                    volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
-                }
-
-                newVol = _volsDao.findById(newVol.getId());
-                break; //break out of template-redeploy retry loop
-            } catch (InterruptedException | ExecutionException e) {
-                s_logger.error("Unable to create " + newVol, e);
-                throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId());
-            }
-        }
-
-        return new Pair<VolumeVO, DataStore>(newVol, destPool);
-    }
-
-    @Override
-    public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException {
-
-        if (dest == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("DeployDestination cannot be null, cannot prepare Volumes for the vm: " + vm);
-            }
-            throw new CloudRuntimeException("Unable to prepare Volume for vm because DeployDestination is null, vm:" + vm);
-        }
-
-        // don't allow to start vm that doesn't have a root volume
-        if (_volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT).isEmpty()) {
-            throw new CloudRuntimeException("Unable to prepare volumes for vm as ROOT volume is missing");
-        }
-
-        List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
-
-        List<VolumeTask> tasks = getTasks(vols, dest.getStorageForDisks(), vm);
-        Volume vol = null;
-        StoragePool pool;
-        for (VolumeTask task : tasks) {
-            if (task.type == VolumeTaskType.NOP) {
-                vol = task.volume;
-
-                pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
-
-                // For zone-wide managed storage, it is possible that the VM can be started in another
-                // cluster. In that case, make sure that the volume is in the right access group.
-                if (pool.isManaged()) {
-                    Host lastHost = _hostDao.findById(vm.getVirtualMachine().getLastHostId());
-                    Host host = _hostDao.findById(vm.getVirtualMachine().getHostId());
-
-                    long lastClusterId = lastHost == null || lastHost.getClusterId() == null ? -1 : lastHost.getClusterId();
-                    long clusterId = host == null || host.getClusterId() == null ? -1 : host.getClusterId();
-
-                    if (lastClusterId != clusterId) {
-                        if (lastHost != null) {
-                            storageMgr.removeStoragePoolFromCluster(lastHost.getId(), vol.get_iScsiName(), pool);
-
-                            DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-
-                            volService.revokeAccess(volFactory.getVolume(vol.getId()), lastHost, storagePool);
-                        }
-
-                        volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore)pool);
-                    }
-                }
-            } else if (task.type == VolumeTaskType.MIGRATE) {
-                pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
-                vol = migrateVolume(task.volume, pool);
-            } else if (task.type == VolumeTaskType.RECREATE) {
-                Pair<VolumeVO, DataStore> result = recreateVolume(task.volume, vm, dest);
-                pool = (StoragePool)dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary);
-                vol = result.first();
-            }
-
-            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
-            DataTO volTO = volumeInfo.getTO();
-            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
-            DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
-
-            disk.setDetails(getDetails(volumeInfo, dataStore));
-
-            vm.addDisk(disk);
-
-            // If hypervisor is vSphere, check for clone type setting.
-            if (vm.getHypervisorType().equals(HypervisorType.VMware)) {
-                // retrieve clone flag.
-                UserVmCloneType cloneType = UserVmCloneType.linked;
-                Boolean value = CapacityManager.VmwareCreateCloneFull.valueIn(vol.getPoolId());
-                if (value != null && value) {
-                    cloneType = UserVmCloneType.full;
-                }
-                UserVmCloneSettingVO cloneSettingVO = _vmCloneSettingDao.findByVmId(vm.getId());
-                if (cloneSettingVO != null) {
-                    if (!cloneSettingVO.getCloneType().equals(cloneType.toString())) {
-                        cloneSettingVO.setCloneType(cloneType.toString());
-                        _vmCloneSettingDao.update(cloneSettingVO.getId(), cloneSettingVO);
-                    }
-                } else {
-                    UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(vm.getId(), cloneType.toString());
-                    _vmCloneSettingDao.persist(vmCloneSettingVO);
-                }
-            }
-
-        }
-    }
-
-    private boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException {
-        return _volStateMachine.transitTo(vol, event, null, _volsDao);
-    }
-
-    @Override
-    public boolean canVmRestartOnAnotherServer(long vmId) {
-        List<VolumeVO> vols = _volsDao.findCreatedByInstance(vmId);
-        for (VolumeVO vol : vols) {
-            StoragePoolVO storagePoolVO = _storagePoolDao.findById(vol.getPoolId());
-            if (!vol.isRecreatable() && storagePoolVO != null && storagePoolVO.getPoolType() != null && !(storagePoolVO.getPoolType().isShared())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public static final ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).", true);
-
-    public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false",
-            "If true, will recreate system vm root disk whenever starting system vm", true);
-
-    public static final ConfigKey<Boolean> StorageHAMigrationEnabled = new ConfigKey<Boolean>(Boolean.class, "enable.ha.storage.migration", "Storage", "true",
-            "Enable/disable storage migration across primary storage during HA", true);
-
-    public static final ConfigKey<Boolean> StorageMigrationEnabled = new ConfigKey<Boolean>(Boolean.class, "enable.storage.migration", "Storage", "true",
-            "Enable/disable storage migration across primary storage", true);
-
-    static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
-            "Check the url for a volume before downloading it from the management server. Set to flase when you managment has no internet access.", true);
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {RecreatableSystemVmEnabled, MaxVolumeSize, StorageHAMigrationEnabled, StorageMigrationEnabled, CustomDiskOfferingMaxSize, CustomDiskOfferingMinSize, VolumeUrlCheck};
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return VolumeOrchestrationService.class.getSimpleName();
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    private void cleanupVolumeDuringAttachFailure(Long volumeId, Long vmId) {
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume == null) {
-            return;
-        }
-
-        if (volume.getState().equals(Volume.State.Creating)) {
-            s_logger.debug("Remove volume: " + volume.getId() + ", as it's leftover from last mgt server stop");
-            _volsDao.remove(volume.getId());
-        }
-
-        if (volume.getState().equals(Volume.State.Attaching)) {
-            s_logger.warn("Vol: " + volume.getName() + " failed to attach to VM: " + _userVmDao.findById(vmId).getHostName() + " on last mgt server stop, changing state back to Ready");
-            volume.setState(Volume.State.Ready);
-            _volsDao.update(volumeId, volume);
-        }
-    }
-
-    private void cleanupVolumeDuringMigrationFailure(Long volumeId, Long destPoolId) {
-        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destPoolId, DataStoreRole.Primary);
-        if (destPool == null) {
-            return;
-        }
-
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume.getState() == Volume.State.Migrating) {
-            VolumeVO duplicateVol = _volsDao.findByPoolIdName(destPoolId, volume.getName());
-            if (duplicateVol != null) {
-                s_logger.debug("Remove volume " + duplicateVol.getId() + " on storage pool " + destPoolId);
-                _volsDao.remove(duplicateVol.getId());
-            }
-
-            s_logger.debug("change volume state to ready from migrating in case migration failure for vol: " + volumeId);
-            volume.setState(Volume.State.Ready);
-            _volsDao.update(volumeId, volume);
-        }
-
-    }
-
-    private void cleanupVolumeDuringSnapshotFailure(Long volumeId, Long snapshotId) {
-        _snapshotSrv.cleanupVolumeDuringSnapshotFailure(volumeId, snapshotId);
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume.getState() == Volume.State.Snapshotting) {
-            s_logger.debug("change volume state back to Ready: " + volume.getId());
-            volume.setState(Volume.State.Ready);
-            _volsDao.update(volume.getId(), volume);
-        }
-    }
-
-    @Override
-    public void cleanupStorageJobs() {
-        //clean up failure jobs related to volume
-        List<AsyncJobVO> jobs = _jobMgr.findFailureAsyncJobs(VmWorkAttachVolume.class.getName(), VmWorkMigrateVolume.class.getName(), VmWorkTakeVolumeSnapshot.class.getName());
-
-        for (AsyncJobVO job : jobs) {
-            try {
-                if (job.getCmd().equalsIgnoreCase(VmWorkAttachVolume.class.getName())) {
-                    VmWorkAttachVolume work = VmWorkSerializer.deserialize(VmWorkAttachVolume.class, job.getCmdInfo());
-                    cleanupVolumeDuringAttachFailure(work.getVolumeId(), work.getVmId());
-                } else if (job.getCmd().equalsIgnoreCase(VmWorkMigrateVolume.class.getName())) {
-                    VmWorkMigrateVolume work = VmWorkSerializer.deserialize(VmWorkMigrateVolume.class, job.getCmdInfo());
-                    cleanupVolumeDuringMigrationFailure(work.getVolumeId(), work.getDestPoolId());
-                } else if (job.getCmd().equalsIgnoreCase(VmWorkTakeVolumeSnapshot.class.getName())) {
-                    VmWorkTakeVolumeSnapshot work = VmWorkSerializer.deserialize(VmWorkTakeVolumeSnapshot.class, job.getCmdInfo());
-                    cleanupVolumeDuringSnapshotFailure(work.getVolumeId(), work.getSnapshotId());
-                }
-            } catch (Exception e) {
-                s_logger.debug("clean up job failure, will continue", e);
-            }
-        }
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return "Volume Manager";
-    }
-
-    @Override
-    public void destroyVolume(Volume volume) {
-        try {
-            // Mark volume as removed if volume has not been created on primary
-            if (volume.getState() == Volume.State.Allocated) {
-                _volsDao.remove(volume.getId());
-                stateTransitTo(volume, Volume.Event.DestroyRequested);
-            } else {
-                volService.destroyVolume(volume.getId());
-            }
-            // FIXME - All this is boiler plate code and should be done as part of state transition. This shouldn't be part of orchestrator.
-            // publish usage event for the volume
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
-                    volume.getUuid(), volume.isDisplayVolume());
-            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
-            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
-        } catch (Exception e) {
-            s_logger.debug("Failed to destroy volume" + volume.getId(), e);
-            throw new CloudRuntimeException("Failed to destroy volume" + volume.getId(), e);
-        }
-    }
-
-    @Override
-    public String getVmNameFromVolumeId(long volumeId) {
-        VolumeVO volume = _volsDao.findById(volumeId);
-        return getVmNameOnVolume(volume);
-    }
-
-    @Override
-    public String getStoragePoolOfVolume(long volumeId) {
-        VolumeVO vol = _volsDao.findById(volumeId);
-        return dataStoreMgr.getPrimaryDataStore(vol.getPoolId()).getUuid();
-    }
-
-    @Override
-    public void updateVolumeDiskChain(long volumeId, String path, String chainInfo) {
-        VolumeVO vol = _volsDao.findById(volumeId);
-        boolean needUpdate = false;
-        // Volume path is not getting updated in the DB, need to find reason and fix the issue.
-        if (vol.getPath() == null) {
-            return;
-        }
-        if (!vol.getPath().equalsIgnoreCase(path)) {
-            needUpdate = true;
-        }
-
-        if (chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo()))) {
-            needUpdate = true;
-        }
-
-        if (needUpdate) {
-            s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
-            vol.setPath(path);
-            vol.setChainInfo(chainInfo);
-            _volsDao.update(volumeId, vol);
-        }
-    }
-}
diff --git a/engine/orchestration/test/com/cloud/agent/manager/AgentManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/agent/manager/AgentManagerImplTest.java
similarity index 100%
rename from engine/orchestration/test/com/cloud/agent/manager/AgentManagerImplTest.java
rename to engine/orchestration/src/test/java/com/cloud/agent/manager/AgentManagerImplTest.java
diff --git a/engine/orchestration/test/com/cloud/agent/manager/ConnectedAgentAttacheTest.java b/engine/orchestration/src/test/java/com/cloud/agent/manager/ConnectedAgentAttacheTest.java
similarity index 100%
rename from engine/orchestration/test/com/cloud/agent/manager/ConnectedAgentAttacheTest.java
rename to engine/orchestration/src/test/java/com/cloud/agent/manager/ConnectedAgentAttacheTest.java
diff --git a/engine/orchestration/test/com/cloud/agent/manager/DirectAgentAttacheTest.java b/engine/orchestration/src/test/java/com/cloud/agent/manager/DirectAgentAttacheTest.java
similarity index 100%
rename from engine/orchestration/test/com/cloud/agent/manager/DirectAgentAttacheTest.java
rename to engine/orchestration/src/test/java/com/cloud/agent/manager/DirectAgentAttacheTest.java
diff --git a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
new file mode 100644
index 0000000..0e7579e
--- /dev/null
+++ b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java
@@ -0,0 +1,626 @@
+// 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.vm;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VirtualMachineManagerImplTest {
+
+    @Spy
+    @InjectMocks
+    private VirtualMachineManagerImpl virtualMachineManagerImpl;
+    @Mock
+    private AgentManager agentManagerMock;
+    @Mock
+    private VMInstanceDao vmInstanceDaoMock;
+    @Mock
+    private ServiceOfferingDao serviceOfferingDaoMock;
+    @Mock
+    private VolumeDao volumeDaoMock;
+    @Mock
+    private PrimaryDataStoreDao storagePoolDaoMock;
+    @Mock
+    private VMInstanceVO vmInstanceMock;
+    private long vmInstanceVoMockId = 1L;
+
+    @Mock
+    private ServiceOfferingVO serviceOfferingMock;
+
+    private long hostMockId = 1L;
+    @Mock
+    private HostVO hostMock;
+
+    @Mock
+    private VirtualMachineProfile virtualMachineProfileMock;
+    @Mock
+    private StoragePoolVO storagePoolVoMock;
+    private long storagePoolVoMockId = 11L;
+    private long storagePoolVoMockClusterId = 234L;
+
+    @Mock
+    private VolumeVO volumeVoMock;
+    private long volumeMockId = 1111L;
+
+    @Mock
+    private StoragePoolHostDao storagePoolHostDaoMock;
+
+    @Mock
+    private StoragePoolAllocator storagePoolAllocatorMock;
+
+    @Mock
+    private DiskOfferingDao diskOfferingDaoMock;
+
+    @Before
+    public void setup() {
+        virtualMachineManagerImpl.setHostAllocators(new ArrayList<>());
+
+        when(vmInstanceMock.getId()).thenReturn(vmInstanceVoMockId);
+        when(vmInstanceMock.getServiceOfferingId()).thenReturn(2L);
+        when(vmInstanceMock.getInstanceName()).thenReturn("myVm");
+        when(vmInstanceMock.getHostId()).thenReturn(2L);
+        when(vmInstanceMock.getType()).thenReturn(VirtualMachine.Type.User);
+        when(hostMock.getId()).thenReturn(hostMockId);
+
+        Mockito.doReturn(vmInstanceVoMockId).when(virtualMachineProfileMock).getId();
+
+        Mockito.doReturn(storagePoolVoMockId).when(storagePoolVoMock).getId();
+        Mockito.doReturn(storagePoolVoMockClusterId).when(storagePoolVoMock).getClusterId();
+
+        Mockito.doReturn(volumeMockId).when(volumeVoMock).getId();
+        Mockito.doReturn(storagePoolVoMockId).when(volumeVoMock).getPoolId();
+
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(storagePoolVoMock).when(storagePoolDaoMock).findById(storagePoolVoMockId);
+
+        ArrayList<StoragePoolAllocator> storagePoolAllocators = new ArrayList<>();
+        storagePoolAllocators.add(storagePoolAllocatorMock);
+        virtualMachineManagerImpl.setStoragePoolAllocators(storagePoolAllocators);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testScaleVM3() throws Exception {
+        when(vmInstanceMock.getHostId()).thenReturn(null);
+        when(vmInstanceDaoMock.findById(anyLong())).thenReturn(vmInstanceMock);
+        when(vmInstanceDaoMock.findByUuid(any(String.class))).thenReturn(vmInstanceMock);
+        DeploymentPlanner.ExcludeList excludeHostList = new DeploymentPlanner.ExcludeList();
+        virtualMachineManagerImpl.findHostAndMigrate(vmInstanceMock.getUuid(), 2l, excludeHostList);
+    }
+
+    @Test
+    public void testSendStopWithOkAnswer() throws Exception {
+        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
+        VirtualMachine vm = mock(VirtualMachine.class);
+        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
+        StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "ok", true);
+        when(profile.getVirtualMachine()).thenReturn(vm);
+        when(vm.getHostId()).thenReturn(1L);
+        when(agentManagerMock.send(anyLong(), (Command)any())).thenReturn(answer);
+
+        boolean actual = virtualMachineManagerImpl.sendStop(guru, profile, false, false);
+
+        Assert.assertTrue(actual);
+    }
+
+    @Test
+    public void testSendStopWithFailAnswer() throws Exception {
+        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
+        VirtualMachine vm = mock(VirtualMachine.class);
+        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
+        StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "fail", false);
+        when(profile.getVirtualMachine()).thenReturn(vm);
+        when(vm.getHostId()).thenReturn(1L);
+        when(agentManagerMock.send(anyLong(), (Command)any())).thenReturn(answer);
+
+        boolean actual = virtualMachineManagerImpl.sendStop(guru, profile, false, false);
+
+        assertFalse(actual);
+    }
+
+    @Test
+    public void testSendStopWithNullAnswer() throws Exception {
+        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
+        VirtualMachine vm = mock(VirtualMachine.class);
+        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
+        when(profile.getVirtualMachine()).thenReturn(vm);
+        when(vm.getHostId()).thenReturn(1L);
+        when(agentManagerMock.send(anyLong(), (Command)any())).thenReturn(null);
+
+        boolean actual = virtualMachineManagerImpl.sendStop(guru, profile, false, false);
+
+        assertFalse(actual);
+    }
+
+    @Test
+    public void testExeceuteInSequence() {
+        assertTrue(virtualMachineManagerImpl.getExecuteInSequence(HypervisorType.XenServer) == false);
+        assertTrue(virtualMachineManagerImpl.getExecuteInSequence(HypervisorType.KVM) == false);
+        assertTrue(virtualMachineManagerImpl.getExecuteInSequence(HypervisorType.VMware) == HypervisorGuru.VmwareFullClone.value());
+        assertTrue(virtualMachineManagerImpl.getExecuteInSequence(HypervisorType.Ovm3) == VirtualMachineManager.ExecuteInSequence.value());
+    }
+
+    @Test
+    public void testCheckIfCanUpgrade() throws Exception {
+        when(vmInstanceMock.getState()).thenReturn(State.Stopped);
+        when(serviceOfferingMock.isDynamic()).thenReturn(true);
+        when(vmInstanceMock.getServiceOfferingId()).thenReturn(1l);
+        when(serviceOfferingMock.getId()).thenReturn(2l);
+
+        ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);
+
+        when(serviceOfferingDaoMock.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
+        when(mockCurrentServiceOffering.isUseLocalStorage()).thenReturn(true);
+        when(serviceOfferingMock.isUseLocalStorage()).thenReturn(true);
+        when(mockCurrentServiceOffering.isSystemUse()).thenReturn(true);
+        when(serviceOfferingMock.isSystemUse()).thenReturn(true);
+        when(mockCurrentServiceOffering.getTags()).thenReturn("x,y");
+        when(serviceOfferingMock.getTags()).thenReturn("z,x,y");
+
+        virtualMachineManagerImpl.checkIfCanUpgrade(vmInstanceMock, serviceOfferingMock);
+    }
+
+    @Test
+    public void isStorageCrossClusterMigrationTestStorageTypeEqualsCluster() {
+        Mockito.doReturn(1L).when(hostMock).getClusterId();
+        Mockito.doReturn(2L).when(storagePoolVoMock).getClusterId();
+        Mockito.doReturn(ScopeType.CLUSTER).when(storagePoolVoMock).getScope();
+
+        boolean returnedValue = virtualMachineManagerImpl.isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+
+        Assert.assertTrue(returnedValue);
+    }
+
+    @Test
+    public void isStorageCrossClusterMigrationTestStorageSameCluster() {
+        Mockito.doReturn(1L).when(hostMock).getClusterId();
+        Mockito.doReturn(1L).when(storagePoolVoMock).getClusterId();
+        Mockito.doReturn(ScopeType.CLUSTER).when(storagePoolVoMock).getScope();
+
+        boolean returnedValue = virtualMachineManagerImpl.isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+
+        assertFalse(returnedValue);
+    }
+
+    @Test
+    public void isStorageCrossClusterMigrationTestStorageTypeEqualsZone() {
+        Mockito.doReturn(1L).when(hostMock).getClusterId();
+        Mockito.doReturn(2L).when(storagePoolVoMock).getClusterId();
+        Mockito.doReturn(ScopeType.ZONE).when(storagePoolVoMock).getScope();
+
+        boolean returnedValue = virtualMachineManagerImpl.isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+
+        assertFalse(returnedValue);
+    }
+
+    @Test
+    public void executeManagedStorageChecksWhenTargetStoragePoolProvidedTestCurrentStoragePoolNotManaged() {
+        Mockito.doReturn(false).when(storagePoolVoMock).isManaged();
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolProvided(storagePoolVoMock, volumeVoMock, Mockito.mock(StoragePoolVO.class));
+
+        Mockito.verify(storagePoolVoMock).isManaged();
+        Mockito.verify(storagePoolVoMock, Mockito.times(0)).getId();
+    }
+
+    @Test
+    public void executeManagedStorageChecksWhenTargetStoragePoolProvidedTestCurrentStoragePoolEqualsTargetPool() {
+        Mockito.doReturn(true).when(storagePoolVoMock).isManaged();
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolProvided(storagePoolVoMock, volumeVoMock, storagePoolVoMock);
+
+        Mockito.verify(storagePoolVoMock).isManaged();
+        Mockito.verify(storagePoolVoMock, Mockito.times(2)).getId();
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void executeManagedStorageChecksWhenTargetStoragePoolProvidedTestCurrentStoragePoolNotEqualsTargetPool() {
+        Mockito.doReturn(true).when(storagePoolVoMock).isManaged();
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolProvided(storagePoolVoMock, volumeVoMock, Mockito.mock(StoragePoolVO.class));
+    }
+
+    @Test
+    public void buildMapUsingUserInformationTestUserDefinedMigrationMapEmpty() {
+        HashMap<Long, Long> userDefinedVolumeToStoragePoolMap = Mockito.spy(new HashMap<>());
+
+        Map<Volume, StoragePool> volumeToPoolObjectMap = virtualMachineManagerImpl.buildMapUsingUserInformation(virtualMachineProfileMock, hostMock, userDefinedVolumeToStoragePoolMap);
+
+        Assert.assertTrue(volumeToPoolObjectMap.isEmpty());
+
+        Mockito.verify(userDefinedVolumeToStoragePoolMap, times(0)).keySet();
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void buildMapUsingUserInformationTestTargetHostDoesNotHaveAccessToPool() {
+        HashMap<Long, Long> userDefinedVolumeToStoragePoolMap = new HashMap<>();
+        userDefinedVolumeToStoragePoolMap.put(volumeMockId, storagePoolVoMockId);
+
+        Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(Mockito.any(StoragePoolVO.class), Mockito.any(VolumeVO.class), Mockito.any(StoragePoolVO.class));
+        Mockito.doReturn(null).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId, hostMockId);
+
+        virtualMachineManagerImpl.buildMapUsingUserInformation(virtualMachineProfileMock, hostMock, userDefinedVolumeToStoragePoolMap);
+
+    }
+
+    @Test
+    public void buildMapUsingUserInformationTestTargetHostHasAccessToPool() {
+        HashMap<Long, Long> userDefinedVolumeToStoragePoolMap = Mockito.spy(new HashMap<>());
+        userDefinedVolumeToStoragePoolMap.put(volumeMockId, storagePoolVoMockId);
+
+        Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolProvided(Mockito.any(StoragePoolVO.class), Mockito.any(VolumeVO.class),
+                Mockito.any(StoragePoolVO.class));
+        Mockito.doReturn(Mockito.mock(StoragePoolHostVO.class)).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId, hostMockId);
+
+        Map<Volume, StoragePool> volumeToPoolObjectMap = virtualMachineManagerImpl.buildMapUsingUserInformation(virtualMachineProfileMock, hostMock, userDefinedVolumeToStoragePoolMap);
+
+        assertFalse(volumeToPoolObjectMap.isEmpty());
+        Assert.assertEquals(storagePoolVoMock, volumeToPoolObjectMap.get(volumeVoMock));
+
+        Mockito.verify(userDefinedVolumeToStoragePoolMap, times(1)).keySet();
+    }
+
+    @Test
+    public void findVolumesThatWereNotMappedByTheUserTest() {
+        Map<Volume, StoragePool> volumeToStoragePoolObjectMap = Mockito.spy(new HashMap<>());
+        volumeToStoragePoolObjectMap.put(volumeVoMock, storagePoolVoMock);
+
+        Volume volumeVoMock2 = Mockito.mock(Volume.class);
+
+        List<Volume> volumesOfVm = new ArrayList<>();
+        volumesOfVm.add(volumeVoMock);
+        volumesOfVm.add(volumeVoMock2);
+
+        Mockito.doReturn(volumesOfVm).when(volumeDaoMock).findUsableVolumesForInstance(vmInstanceVoMockId);
+        List<Volume> volumesNotMapped = virtualMachineManagerImpl.findVolumesThatWereNotMappedByTheUser(virtualMachineProfileMock, volumeToStoragePoolObjectMap);
+
+        Assert.assertEquals(1, volumesNotMapped.size());
+        Assert.assertEquals(volumeVoMock2, volumesNotMapped.get(0));
+    }
+
+    @Test
+    public void executeManagedStorageChecksWhenTargetStoragePoolNotProvidedTestCurrentStoragePoolNotManaged() {
+        Mockito.doReturn(false).when(storagePoolVoMock).isManaged();
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+
+        Mockito.verify(storagePoolVoMock).isManaged();
+        Mockito.verify(storagePoolHostDaoMock, Mockito.times(0)).findByPoolHost(Mockito.anyLong(), Mockito.anyLong());
+    }
+
+    @Test
+    public void executeManagedStorageChecksWhenTargetStoragePoolNotProvidedTestCurrentStoragePoolManagedIsConnectedToHost() {
+        Mockito.doReturn(true).when(storagePoolVoMock).isManaged();
+        Mockito.doReturn(Mockito.mock(StoragePoolHostVO.class)).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId, hostMockId);
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+
+        Mockito.verify(storagePoolVoMock).isManaged();
+        Mockito.verify(storagePoolHostDaoMock, Mockito.times(1)).findByPoolHost(storagePoolVoMockId, hostMockId);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void executeManagedStorageChecksWhenTargetStoragePoolNotProvidedTestCurrentStoragePoolManagedIsNotConnectedToHost() {
+        Mockito.doReturn(true).when(storagePoolVoMock).isManaged();
+        Mockito.doReturn(null).when(storagePoolHostDaoMock).findByPoolHost(storagePoolVoMockId, hostMockId);
+
+        virtualMachineManagerImpl.executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+    }
+
+    @Test
+    public void getCandidateStoragePoolsToMigrateLocalVolumeTestLocalVolume() {
+        Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
+        Mockito.doReturn(true).when(storagePoolVoMock).isLocal();
+
+        List<StoragePool> poolListMock = new ArrayList<>();
+        poolListMock.add(storagePoolVoMock);
+
+        Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        List<StoragePool> poolList = virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        Assert.assertEquals(1, poolList.size());
+        Assert.assertEquals(storagePoolVoMock, poolList.get(0));
+    }
+
+    @Test
+    public void getCandidateStoragePoolsToMigrateLocalVolumeTestCrossClusterMigration() {
+        Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
+        Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
+
+        List<StoragePool> poolListMock = new ArrayList<>();
+        poolListMock.add(storagePoolVoMock);
+
+        Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        Mockito.doReturn(true).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+        List<StoragePool> poolList = virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        Assert.assertEquals(1, poolList.size());
+        Assert.assertEquals(storagePoolVoMock, poolList.get(0));
+    }
+
+    @Test
+    public void getCandidateStoragePoolsToMigrateLocalVolumeTestWithinClusterMigration() {
+        Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
+        Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
+
+        List<StoragePool> poolListMock = new ArrayList<>();
+        poolListMock.add(storagePoolVoMock);
+
+        Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+        List<StoragePool> poolList = virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        Assert.assertTrue(poolList.isEmpty());
+    }
+
+    @Test
+    public void getCandidateStoragePoolsToMigrateLocalVolumeTestMoreThanOneAllocator() {
+        StoragePoolAllocator storagePoolAllocatorMock2 = Mockito.mock(StoragePoolAllocator.class);
+        StoragePoolAllocator storagePoolAllocatorMock3 = Mockito.mock(StoragePoolAllocator.class);
+
+        List<StoragePoolAllocator> storagePoolAllocatorsMock = new ArrayList<>();
+        storagePoolAllocatorsMock.add(storagePoolAllocatorMock);
+        storagePoolAllocatorsMock.add(storagePoolAllocatorMock2);
+        storagePoolAllocatorsMock.add(storagePoolAllocatorMock3);
+
+        virtualMachineManagerImpl.setStoragePoolAllocators(storagePoolAllocatorsMock);
+
+        Mockito.doReturn(Mockito.mock(DiskOfferingVO.class)).when(diskOfferingDaoMock).findById(Mockito.anyLong());
+
+        Mockito.doReturn(false).when(storagePoolVoMock).isLocal();
+
+        List<StoragePool> poolListMock = new ArrayList<>();
+        poolListMock.add(storagePoolVoMock);
+
+        Mockito.doReturn(poolListMock).when(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        Mockito.doReturn(null).when(storagePoolAllocatorMock2).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        Mockito.doReturn(new ArrayList<>()).when(storagePoolAllocatorMock3).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+
+        Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+        List<StoragePool> poolList = virtualMachineManagerImpl.getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        Assert.assertTrue(poolList.isEmpty());
+
+        Mockito.verify(storagePoolAllocatorMock).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+        Mockito.verify(storagePoolAllocatorMock2).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+        Mockito.verify(storagePoolAllocatorMock3).allocateToPool(Mockito.any(DiskProfile.class), Mockito.any(VirtualMachineProfile.class), Mockito.any(DeploymentPlan.class),
+                Mockito.any(ExcludeList.class), Mockito.eq(StoragePoolAllocator.RETURN_UPTO_ALL));
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createVolumeToStoragePoolMappingIfPossibleTestNotStoragePoolsAvailable() {
+        Mockito.doReturn(null).when(virtualMachineManagerImpl).getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        virtualMachineManagerImpl.createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, new HashMap<>(), volumeVoMock, storagePoolVoMock);
+    }
+
+    @Test
+    public void createVolumeToStoragePoolMappingIfPossibleTestTargetHostAccessCurrentStoragePool() {
+        List<StoragePool> storagePoolList = new ArrayList<>();
+        storagePoolList.add(storagePoolVoMock);
+
+        Mockito.doReturn(storagePoolList).when(virtualMachineManagerImpl).getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+        virtualMachineManagerImpl.createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+
+        Assert.assertTrue(volumeToPoolObjectMap.isEmpty());
+    }
+
+    @Test
+    public void createVolumeToStoragePoolMappingIfPossibleTestTargetHostDoesNotAccessCurrentStoragePool() {
+        StoragePoolVO storagePoolMockOther = Mockito.mock(StoragePoolVO.class);
+        String storagePoolMockOtherUuid = "storagePoolMockOtherUuid";
+        Mockito.doReturn(storagePoolMockOtherUuid).when(storagePoolMockOther).getUuid();
+        Mockito.doReturn(storagePoolMockOther).when(storagePoolDaoMock).findByUuid(storagePoolMockOtherUuid);
+
+        List<StoragePool> storagePoolList = new ArrayList<>();
+        storagePoolList.add(storagePoolMockOther);
+
+        Mockito.doReturn(storagePoolList).when(virtualMachineManagerImpl).getCandidateStoragePoolsToMigrateLocalVolume(virtualMachineProfileMock, hostMock, volumeVoMock);
+
+        HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+        virtualMachineManagerImpl.createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+
+        assertFalse(volumeToPoolObjectMap.isEmpty());
+        Assert.assertEquals(storagePoolMockOther, volumeToPoolObjectMap.get(volumeVoMock));
+    }
+
+    @Test
+    public void createStoragePoolMappingsForVolumesTestLocalStoragevolume() {
+        ArrayList<Volume> allVolumes = new ArrayList<>();
+        allVolumes.add(volumeVoMock);
+
+        HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+
+        Mockito.doReturn(ScopeType.HOST).when(storagePoolVoMock).getScope();
+        Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.doNothing().when(virtualMachineManagerImpl).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock,
+                storagePoolVoMock);
+
+        virtualMachineManagerImpl.createStoragePoolMappingsForVolumes(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, allVolumes);
+
+        Assert.assertTrue(volumeToPoolObjectMap.isEmpty());
+        Mockito.verify(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.verify(virtualMachineManagerImpl).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+    }
+
+    @Test
+    public void createStoragePoolMappingsForVolumesTestCrossCluterMigration() {
+        ArrayList<Volume> allVolumes = new ArrayList<>();
+        allVolumes.add(volumeVoMock);
+
+        HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+
+        Mockito.doReturn(ScopeType.CLUSTER).when(storagePoolVoMock).getScope();
+        Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.doNothing().when(virtualMachineManagerImpl).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+        Mockito.doReturn(true).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+
+        virtualMachineManagerImpl.createStoragePoolMappingsForVolumes(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, allVolumes);
+
+        Assert.assertTrue(volumeToPoolObjectMap.isEmpty());
+        Mockito.verify(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.verify(virtualMachineManagerImpl).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+        Mockito.verify(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+    }
+
+    @Test
+    public void createStoragePoolMappingsForVolumesTestNotCrossCluterMigrationWithClusterStorage() {
+        ArrayList<Volume> allVolumes = new ArrayList<>();
+        allVolumes.add(volumeVoMock);
+
+        HashMap<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+
+        Mockito.doReturn(ScopeType.CLUSTER).when(storagePoolVoMock).getScope();
+        Mockito.doNothing().when(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.doNothing().when(virtualMachineManagerImpl).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock, storagePoolVoMock);
+        Mockito.doReturn(false).when(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+
+        virtualMachineManagerImpl.createStoragePoolMappingsForVolumes(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, allVolumes);
+
+        assertFalse(volumeToPoolObjectMap.isEmpty());
+        Assert.assertEquals(storagePoolVoMock, volumeToPoolObjectMap.get(volumeVoMock));
+
+        Mockito.verify(virtualMachineManagerImpl).executeManagedStorageChecksWhenTargetStoragePoolNotProvided(hostMock, storagePoolVoMock, volumeVoMock);
+        Mockito.verify(virtualMachineManagerImpl).isStorageCrossClusterMigration(hostMock, storagePoolVoMock);
+        Mockito.verify(virtualMachineManagerImpl, Mockito.times(0)).createVolumeToStoragePoolMappingIfPossible(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumeVoMock,
+                storagePoolVoMock);
+    }
+
+    @Test
+    public void createMappingVolumeAndStoragePoolTest() {
+        Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>();
+        List<Volume> volumesNotMapped = new ArrayList<>();
+
+        Mockito.doReturn(volumeToPoolObjectMap).when(virtualMachineManagerImpl).buildMapUsingUserInformation(Mockito.eq(virtualMachineProfileMock), Mockito.eq(hostMock),
+                Mockito.anyMapOf(Long.class, Long.class));
+
+        Mockito.doReturn(volumesNotMapped).when(virtualMachineManagerImpl).findVolumesThatWereNotMappedByTheUser(virtualMachineProfileMock, volumeToPoolObjectMap);
+        Mockito.doNothing().when(virtualMachineManagerImpl).createStoragePoolMappingsForVolumes(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumesNotMapped);
+
+        Map<Volume, StoragePool> mappingVolumeAndStoragePool = virtualMachineManagerImpl.createMappingVolumeAndStoragePool(virtualMachineProfileMock, hostMock, new HashMap<>());
+
+        Assert.assertEquals(mappingVolumeAndStoragePool, volumeToPoolObjectMap);
+
+        InOrder inOrder = Mockito.inOrder(virtualMachineManagerImpl);
+        inOrder.verify(virtualMachineManagerImpl).buildMapUsingUserInformation(Mockito.eq(virtualMachineProfileMock), Mockito.eq(hostMock), Mockito.anyMapOf(Long.class, Long.class));
+        inOrder.verify(virtualMachineManagerImpl).findVolumesThatWereNotMappedByTheUser(virtualMachineProfileMock, volumeToPoolObjectMap);
+        inOrder.verify(virtualMachineManagerImpl).createStoragePoolMappingsForVolumes(virtualMachineProfileMock, hostMock, volumeToPoolObjectMap, volumesNotMapped);
+    }
+
+    @Test
+    public void matchesOfSorts() {
+        List<String> nothing = null;
+        List<String> empty = new ArrayList<>();
+        List<String> tag = Arrays.asList("bla");
+        List<String> tags = Arrays.asList("bla", "blob");
+        List<String> others = Arrays.asList("bla", "blieb");
+        List<String> three = Arrays.asList("bla", "blob", "blieb");
+
+        // single match
+        assertTrue(VirtualMachineManagerImpl.matches(tag,tags));
+        assertTrue(VirtualMachineManagerImpl.matches(tag,others));
+
+        // no requirements
+        assertTrue(VirtualMachineManagerImpl.matches(nothing,tags));
+        assertTrue(VirtualMachineManagerImpl.matches(empty,tag));
+
+        // mis(sing)match
+        assertFalse(VirtualMachineManagerImpl.matches(tags,tag));
+        assertFalse(VirtualMachineManagerImpl.matches(tag,nothing));
+        assertFalse(VirtualMachineManagerImpl.matches(tag,empty));
+
+        // disjunct sets
+        assertFalse(VirtualMachineManagerImpl.matches(tags,others));
+        assertFalse(VirtualMachineManagerImpl.matches(others,tags));
+
+        // everything matches the larger set
+        assertTrue(VirtualMachineManagerImpl.matches(nothing,three));
+        assertTrue(VirtualMachineManagerImpl.matches(empty,three));
+        assertTrue(VirtualMachineManagerImpl.matches(tag,three));
+        assertTrue(VirtualMachineManagerImpl.matches(tags,three));
+        assertTrue(VirtualMachineManagerImpl.matches(others,three));
+    }
+}
diff --git a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
new file mode 100644
index 0000000..3450c09
--- /dev/null
+++ b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
@@ -0,0 +1,466 @@
+// 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.engine.orchestration;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.utils.net.Ip;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+
+import junit.framework.TestCase;
+
+/**
+ * NetworkManagerImpl implements NetworkManager.
+ */
+@RunWith(JUnit4.class)
+public class NetworkOrchestratorTest extends TestCase {
+    static final Logger s_logger = Logger.getLogger(NetworkOrchestratorTest.class);
+
+    NetworkOrchestrator testOrchastrator = Mockito.spy(new NetworkOrchestrator());
+
+    private String guruName = "GuestNetworkGuru";
+    private String dhcpProvider = "VirtualRouter";
+    private NetworkGuru guru = mock(NetworkGuru.class);
+
+    NetworkOfferingVO networkOffering = mock(NetworkOfferingVO.class);
+
+    private static final long networkOfferingId = 1l;
+
+    @Override
+    @Before
+    public void setUp() {
+        // make class-scope mocks
+        testOrchastrator._nicDao = mock(NicDao.class);
+        testOrchastrator._networksDao = mock(NetworkDao.class);
+        testOrchastrator._networkModel = mock(NetworkModel.class);
+        testOrchastrator._nicSecondaryIpDao = mock(NicSecondaryIpDao.class);
+        testOrchastrator._ntwkSrvcDao = mock(NetworkServiceMapDao.class);
+        testOrchastrator._nicIpAliasDao = mock(NicIpAliasDao.class);
+        testOrchastrator._ipAddressDao = mock(IPAddressDao.class);
+        testOrchastrator._vlanDao = mock(VlanDao.class);
+        DhcpServiceProvider provider = mock(DhcpServiceProvider.class);
+
+        Map<Network.Capability, String> capabilities = new HashMap<Network.Capability, String>();
+        Map<Network.Service, Map<Network.Capability, String>> services = new HashMap<Network.Service, Map<Network.Capability, String>>();
+        services.put(Network.Service.Dhcp, capabilities);
+        when(provider.getCapabilities()).thenReturn(services);
+        capabilities.put(Network.Capability.DhcpAccrossMultipleSubnets, "true");
+
+        when(testOrchastrator._ntwkSrvcDao.getProviderForServiceInNetwork(Matchers.anyLong(), Matchers.eq(Service.Dhcp))).thenReturn(dhcpProvider);
+        when(testOrchastrator._networkModel.getElementImplementingProvider(dhcpProvider)).thenReturn(provider);
+
+        when(guru.getName()).thenReturn(guruName);
+        List<NetworkGuru> networkGurus = new ArrayList<NetworkGuru>();
+        networkGurus.add(guru);
+        testOrchastrator.networkGurus = networkGurus;
+
+        when(networkOffering.getGuestType()).thenReturn(GuestType.L2);
+        when(networkOffering.getId()).thenReturn(networkOfferingId);
+    }
+
+    @Test
+    public void testRemoveDhcpServiceWithNic() {
+        // make local mocks
+        VirtualMachineProfile vm = mock(VirtualMachineProfile.class);
+        NicVO nic = mock(NicVO.class);
+        NetworkVO network = mock(NetworkVO.class);
+
+        // make sure that release dhcp will be called
+        when(vm.getType()).thenReturn(Type.User);
+        when(testOrchastrator._networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)).thenReturn(true);
+        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(network.getGuestType()).thenReturn(GuestType.Shared);
+        when(testOrchastrator._nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getIPv4Gateway(), nic.getBroadcastUri()))
+                .thenReturn(new ArrayList<NicVO>());
+
+        when(network.getGuruName()).thenReturn(guruName);
+        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
+
+        testOrchastrator.removeNic(vm, nic);
+
+        verify(nic, times(1)).setState(Nic.State.Deallocating);
+        verify(testOrchastrator._networkModel, times(2)).getElementImplementingProvider(dhcpProvider);
+        verify(testOrchastrator._ntwkSrvcDao, times(2)).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
+        verify(testOrchastrator._networksDao, times(2)).findById(nic.getNetworkId());
+    }
+    @Test
+    public void testDontRemoveDhcpServiceFromDomainRouter() {
+        // make local mocks
+        VirtualMachineProfile vm = mock(VirtualMachineProfile.class);
+        NicVO nic = mock(NicVO.class);
+        NetworkVO network = mock(NetworkVO.class);
+
+        // make sure that release dhcp won't be called
+        when(vm.getType()).thenReturn(Type.DomainRouter);
+
+        when(network.getGuruName()).thenReturn(guruName);
+        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
+
+        testOrchastrator.removeNic(vm, nic);
+
+        verify(nic, times(1)).setState(Nic.State.Deallocating);
+        verify(testOrchastrator._networkModel, never()).getElementImplementingProvider(dhcpProvider);
+        verify(testOrchastrator._ntwkSrvcDao, never()).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
+        verify(testOrchastrator._networksDao, times(1)).findById(nic.getNetworkId());
+    }
+    @Test
+    public void testDontRemoveDhcpServiceWhenNotProvided() {
+        // make local mocks
+        VirtualMachineProfile vm = mock(VirtualMachineProfile.class);
+        NicVO nic = mock(NicVO.class);
+        NetworkVO network = mock(NetworkVO.class);
+
+        // make sure that release dhcp will *not* be called
+        when(vm.getType()).thenReturn(Type.User);
+        when(testOrchastrator._networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)).thenReturn(false);
+
+        when(network.getGuruName()).thenReturn(guruName);
+        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
+
+        testOrchastrator.removeNic(vm, nic);
+
+        verify(nic, times(1)).setState(Nic.State.Deallocating);
+        verify(testOrchastrator._networkModel, never()).getElementImplementingProvider(dhcpProvider);
+        verify(testOrchastrator._ntwkSrvcDao, never()).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
+        verify(testOrchastrator._networksDao, times(1)).findById(nic.getNetworkId());
+    }
+
+    @Test
+    public void testCheckL2OfferingServicesEmptyServices() {
+        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(new ArrayList<>());
+        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(false);
+        testOrchastrator.checkL2OfferingServices(networkOffering);
+    }
+
+    @Test
+    public void testCheckL2OfferingServicesUserDataOnly() {
+        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.UserData));
+        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(true);
+        testOrchastrator.checkL2OfferingServices(networkOffering);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testCheckL2OfferingServicesMultipleServicesIncludingUserData() {
+        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.UserData, Service.Dhcp));
+        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(true);
+        testOrchastrator.checkL2OfferingServices(networkOffering);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testCheckL2OfferingServicesMultipleServicesNotIncludingUserData() {
+        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.Dns, Service.Dhcp));
+        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(false);
+        testOrchastrator.checkL2OfferingServices(networkOffering);
+    }
+
+    @Test
+    public void testConfigureNicProfileBasedOnRequestedIpTestMacNull() {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, "192.168.100.1", "255.255.255.0", "00-88-14-4D-4C-FB",
+                requestedNicProfile, null, "192.168.100.150");
+
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+
+        verifyAndAssert("192.168.100.150", "192.168.100.1", "255.255.255.0", nicProfile, 1, 1);
+    }
+
+    @Test
+    public void testConfigureNicProfileBasedOnRequestedIpTestNicProfileMacNotNull() {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, "192.168.100.1", "255.255.255.0", "00-88-14-4D-4C-FB",
+                requestedNicProfile, "00-88-14-4D-4C-FB", "192.168.100.150");
+
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+
+        verifyAndAssert("192.168.100.150", "192.168.100.1", "255.255.255.0", nicProfile, 1, 0);
+    }
+
+    @Test
+    public void testConfigureNicProfileBasedOnRequestedIpTestRequestedIpNull() {
+        testConfigureNicProfileBasedOnRequestedIpTestRequestedIp(null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestRequestedIpIsBlank() {
+        testConfigureNicProfileBasedOnRequestedIpTestRequestedIp("");
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestRequestedIpIsNotValid() {
+        testConfigureNicProfileBasedOnRequestedIpTestRequestedIp("123");
+    }
+
+    private void testConfigureNicProfileBasedOnRequestedIpTestRequestedIp(String requestedIpv4Address) {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, "192.168.100.1", "255.255.255.0", "00-88-14-4D-4C-FB",
+                requestedNicProfile, null, requestedIpv4Address);
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+
+        verifyAndAssert(null, null, null, nicProfile, 0, 0);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestGatewayIsBlank() {
+        testConfigureNicProfileBasedOnRequestedIpTestGateway("");
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestGatewayIsNotValid() {
+        testConfigureNicProfileBasedOnRequestedIpTestGateway("123");
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestGatewayIsNull() {
+        testConfigureNicProfileBasedOnRequestedIpTestGateway(null);
+    }
+
+    private void testConfigureNicProfileBasedOnRequestedIpTestGateway(String ipv4Gateway) {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, ipv4Gateway, "255.255.255.0", "00-88-14-4D-4C-FB",
+                requestedNicProfile, "00-88-14-4D-4C-FB", "192.168.100.150");
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+        verifyAndAssert(null, null, null, nicProfile, 1, 0);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestNetmaskIsNull() {
+        testConfigureNicProfileBasedOnRequestedIpTestNetmask(null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestNetmaskIsBlank() {
+        testConfigureNicProfileBasedOnRequestedIpTestNetmask("");
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestNetmaskIsNotValid() {
+        testConfigureNicProfileBasedOnRequestedIpTestNetmask("123");
+    }
+
+    private void testConfigureNicProfileBasedOnRequestedIpTestNetmask(String ipv4Netmask) {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, "192.168.100.1", ipv4Netmask, "00-88-14-4D-4C-FB",
+                requestedNicProfile, "00-88-14-4D-4C-FB", "192.168.100.150");
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+        verifyAndAssert(null, null, null, nicProfile, 1, 0);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testConfigureNicProfileBasedOnRequestedIpTestIPAddressVONull() {
+        Network network = mock(Network.class);
+        NicProfile requestedNicProfile = new NicProfile();
+        NicProfile nicProfile = Mockito.spy(new NicProfile());
+
+        configureTestConfigureNicProfileBasedOnRequestedIpTests(nicProfile, 0l, false, IPAddressVO.State.Free, "192.168.100.1", "255.255.255.0", "00-88-14-4D-4C-FB",
+                requestedNicProfile, "00-88-14-4D-4C-FB", "192.168.100.150");
+        when(testOrchastrator._vlanDao.findByNetworkIdAndIpv4(Mockito.anyLong(), Mockito.anyString())).thenReturn(null);
+
+        testOrchastrator.configureNicProfileBasedOnRequestedIp(requestedNicProfile, nicProfile, network);
+        verifyAndAssert(null, null, null, nicProfile, 0, 0);
+    }
+
+    private void configureTestConfigureNicProfileBasedOnRequestedIpTests(NicProfile nicProfile, long ipvoId, boolean ipVoIsNull, IPAddressVO.State state, String vlanGateway,
+            String vlanNetmask, String macAddress, NicProfile requestedNicProfile, String nicProfileMacAddress, String requestedIpv4Address) {
+        IPAddressVO ipVoSpy = Mockito.spy(new IPAddressVO(new Ip("192.168.100.100"), 0l, 0l, 0l, true));
+        ipVoSpy.setState(state);
+
+        requestedNicProfile.setRequestedIPv4(requestedIpv4Address);
+        nicProfile.setMacAddress(nicProfileMacAddress);
+
+        when(ipVoSpy.getId()).thenReturn(ipvoId);
+        when(ipVoSpy.getState()).thenReturn(state);
+
+        if (ipVoIsNull) {
+            when(testOrchastrator._ipAddressDao.findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString())).thenReturn(ipVoSpy);
+        } else {
+            when(testOrchastrator._ipAddressDao.findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString())).thenReturn(ipVoSpy);
+        }
+
+        VlanVO vlanSpy = Mockito.spy(new VlanVO(Vlan.VlanType.DirectAttached, "vlanTag", vlanGateway, vlanNetmask, 0l, "192.168.100.100 - 192.168.100.200", 0l, new Long(0l),
+                "ip6Gateway", "ip6Cidr", "ip6Range"));
+
+        Mockito.doReturn(0l).when(vlanSpy).getId();
+        when(testOrchastrator._vlanDao.findByNetworkIdAndIpv4(Mockito.anyLong(), Mockito.anyString())).thenReturn(vlanSpy);
+        when(testOrchastrator._ipAddressDao.acquireInLockTable(Mockito.anyLong())).thenReturn(ipVoSpy);
+        when(testOrchastrator._ipAddressDao.update(Mockito.anyLong(), Mockito.any(IPAddressVO.class))).thenReturn(true);
+        when(testOrchastrator._ipAddressDao.releaseFromLockTable(Mockito.anyLong())).thenReturn(true);
+        try {
+            when(testOrchastrator._networkModel.getNextAvailableMacAddressInNetwork(Mockito.anyLong())).thenReturn(macAddress);
+        } catch (InsufficientAddressCapacityException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void verifyAndAssert(String requestedIpv4Address, String ipv4Gateway, String ipv4Netmask, NicProfile nicProfile, int acquireLockAndCheckIfIpv4IsFreeTimes,
+            int nextMacAddressTimes) {
+        verify(testOrchastrator, times(acquireLockAndCheckIfIpv4IsFreeTimes)).acquireLockAndCheckIfIpv4IsFree(Mockito.any(Network.class), Mockito.anyString());
+        try {
+            verify(testOrchastrator._networkModel, times(nextMacAddressTimes)).getNextAvailableMacAddressInNetwork(Mockito.anyLong());
+        } catch (InsufficientAddressCapacityException e) {
+            e.printStackTrace();
+        }
+
+        assertEquals(requestedIpv4Address, nicProfile.getIPv4Address());
+        assertEquals(ipv4Gateway, nicProfile.getIPv4Gateway());
+        assertEquals(ipv4Netmask, nicProfile.getIPv4Netmask());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testAcquireLockAndCheckIfIpv4IsFreeTestIpvoNull() {
+        executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State.Free, true, 1, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void testAcquireLockAndCheckIfIpv4IsFreeTestExpectedFlow() {
+        executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State.Free, false, 1, 1, 1, 1, 1);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testAcquireLockAndCheckIfIpv4IsFreeTestAllocatedIp() {
+        executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State.Allocated, false, 1, 1, 1, 0, 1);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testAcquireLockAndCheckIfIpv4IsFreeTestAllocatingIp() {
+        executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State.Allocating, false, 1, 1, 1, 0, 1);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testAcquireLockAndCheckIfIpv4IsFreeTestReleasingIp() {
+        executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State.Releasing, false, 1, 1, 1, 0, 1);
+    }
+
+    private void executeTestAcquireLockAndCheckIfIpv4IsFree(IPAddressVO.State state, boolean isIPAddressVONull, int findByIpTimes, int acquireLockTimes, int releaseFromLockTimes,
+            int updateTimes, int validateTimes) {
+        Network network = Mockito.spy(new NetworkVO());
+        IPAddressVO ipVoSpy = Mockito.spy(new IPAddressVO(new Ip("192.168.100.100"), 0l, 0l, 0l, true));
+        ipVoSpy.setState(state);
+        ipVoSpy.setState(state);
+        if (isIPAddressVONull) {
+            when(testOrchastrator._ipAddressDao.findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString())).thenReturn(null);
+        } else {
+            when(testOrchastrator._ipAddressDao.findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString())).thenReturn(ipVoSpy);
+        }
+        when(testOrchastrator._ipAddressDao.acquireInLockTable(Mockito.anyLong())).thenReturn(ipVoSpy);
+        when(testOrchastrator._ipAddressDao.releaseFromLockTable(Mockito.anyLong())).thenReturn(true);
+        when(testOrchastrator._ipAddressDao.update(Mockito.anyLong(), Mockito.any(IPAddressVO.class))).thenReturn(true);
+
+        testOrchastrator.acquireLockAndCheckIfIpv4IsFree(network, "192.168.100.150");
+
+        verify(testOrchastrator._ipAddressDao, Mockito.times(findByIpTimes)).findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString());
+        verify(testOrchastrator._ipAddressDao, Mockito.times(acquireLockTimes)).acquireInLockTable(Mockito.anyLong());
+        verify(testOrchastrator._ipAddressDao, Mockito.times(releaseFromLockTimes)).releaseFromLockTable(Mockito.anyLong());
+        verify(testOrchastrator._ipAddressDao, Mockito.times(updateTimes)).update(Mockito.anyLong(), Mockito.any(IPAddressVO.class));
+        verify(testOrchastrator, Mockito.times(validateTimes)).validateLockedRequestedIp(Mockito.any(IPAddressVO.class), Mockito.any(IPAddressVO.class));
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateLockedRequestedIpTestNullLockedIp() {
+        IPAddressVO ipVoSpy = Mockito.spy(new IPAddressVO(new Ip("192.168.100.100"), 0l, 0l, 0l, true));
+        testOrchastrator.validateLockedRequestedIp(ipVoSpy, null);
+    }
+
+    @Test
+    public void validateLockedRequestedIpTestNotFreeLockedIp() {
+        IPAddressVO ipVoSpy = Mockito.spy(new IPAddressVO(new Ip("192.168.100.100"), 0l, 0l, 0l, true));
+        State[] states = State.values();
+        for(int i=0; i < states.length;i++) {
+            boolean expectedException = false;
+            if (states[i] == State.Free) {
+                continue;
+            }
+            IPAddressVO lockedIp = ipVoSpy;
+            lockedIp.setState(states[i]);
+            try {
+                testOrchastrator.validateLockedRequestedIp(ipVoSpy, lockedIp);
+            } catch (InvalidParameterValueException e) {
+                expectedException = true;
+            }
+            Assert.assertTrue(expectedException);
+        }
+    }
+
+    @Test
+    public void validateLockedRequestedIpTestFreeAndNotNullIp() {
+        IPAddressVO ipVoSpy = Mockito.spy(new IPAddressVO(new Ip("192.168.100.100"), 0l, 0l, 0l, true));
+        IPAddressVO lockedIp = ipVoSpy;
+        lockedIp.setState(State.Free);
+        testOrchastrator.validateLockedRequestedIp(ipVoSpy, lockedIp);
+    }
+
+}
diff --git a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java
similarity index 100%
rename from engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java
rename to engine/orchestration/src/test/java/org/apache/cloudstack/engine/provisioning/test/ChildTestConfiguration.java
diff --git a/engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java
similarity index 100%
rename from engine/orchestration/test/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java
rename to engine/orchestration/src/test/java/org/apache/cloudstack/engine/provisioning/test/ProvisioningTest.java
diff --git a/engine/orchestration/test/resource/provisioningContext.xml b/engine/orchestration/src/test/resources/provisioningContext.xml
similarity index 100%
rename from engine/orchestration/test/resource/provisioningContext.xml
rename to engine/orchestration/src/test/resources/provisioningContext.xml
diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
deleted file mode 100644
index 9bc22c4..0000000
--- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
+++ /dev/null
@@ -1,545 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.vm;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.ArrayList;
-
-import com.cloud.service.dao.ServiceOfferingDao;
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.CheckVirtualMachineAnswer;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.MigrateWithStorageAnswer;
-import com.cloud.agent.api.MigrateWithStorageCommand;
-import com.cloud.agent.api.MigrateWithStorageCompleteAnswer;
-import com.cloud.agent.api.MigrateWithStorageCompleteCommand;
-import com.cloud.agent.api.MigrateWithStorageReceiveAnswer;
-import com.cloud.agent.api.MigrateWithStorageReceiveCommand;
-import com.cloud.agent.api.MigrateWithStorageSendAnswer;
-import com.cloud.agent.api.MigrateWithStorageSendCommand;
-import com.cloud.agent.api.PrepareForMigrationAnswer;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.ScaleVmAnswer;
-import com.cloud.agent.api.ScaleVmCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuru;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.user.Account;
-import com.cloud.user.AccountVO;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-
-public class VirtualMachineManagerImplTest {
-
-    @Spy
-    VirtualMachineManagerImpl _vmMgr = new VirtualMachineManagerImpl();
-    @Mock
-    VolumeOrchestrationService _storageMgr;
-    @Mock
-    Account _account;
-    @Mock
-    CapacityManager _capacityMgr;
-    @Mock
-    AgentManager _agentMgr;
-    @Mock
-    AccountDao _accountDao;
-    @Mock
-    ConfigurationDao _configDao;
-    @Mock
-    HostDao _hostDao;
-    @Mock
-    UserDao _userDao;
-    @Mock
-    UserVmDao _vmDao;
-    @Mock
-    ItWorkDao _workDao;
-    @Mock
-    VMInstanceDao _vmInstanceDao;
-    @Mock
-    ServiceOfferingDao _offeringDao;
-    @Mock
-    VMTemplateDao _templateDao;
-    @Mock
-    VolumeDao _volsDao;
-    @Mock
-    RestoreVMCmd _restoreVMCmd;
-    @Mock
-    AccountVO _accountMock;
-    @Mock
-    UserVO _userMock;
-    @Mock
-    UserVmVO _vmMock;
-    @Mock
-    VMInstanceVO _vmInstance;
-    @Mock
-    ServiceOfferingVO _serviceOfferingMock;
-    @Mock
-    HostVO _host;
-    @Mock
-    VMTemplateVO _templateMock;
-    @Mock
-    VolumeVO _volumeMock;
-    @Mock
-    List<VolumeVO> _rootVols;
-    @Mock
-    ItWorkVO _work;
-    @Mock
-    HostVO hostVO;
-    @Mock
-    UserVmDetailVO _vmDetailVO;
-
-    @Mock
-    ClusterDao _clusterDao;
-    @Mock
-    HostPodDao _podDao;
-    @Mock
-    DataCenterDao _dcDao;
-    @Mock
-    DiskOfferingDao _diskOfferingDao;
-    @Mock
-    PrimaryDataStoreDao _storagePoolDao;
-    @Mock
-    UserVmDetailsDao _vmDetailsDao;
-    @Mock
-    StoragePoolHostDao _poolHostDao;
-    @Mock
-    NetworkOrchestrationService _networkMgr;
-    @Mock
-    HypervisorGuruManager _hvGuruMgr;
-    @Mock
-    VMSnapshotManager _vmSnapshotMgr;
-
-    // Mock objects for vm migration with storage test.
-    @Mock
-    DiskOfferingVO _diskOfferingMock;
-    @Mock
-    StoragePoolVO _srcStoragePoolMock;
-    @Mock
-    StoragePoolVO _destStoragePoolMock;
-    @Mock
-    HostVO _srcHostMock;
-    @Mock
-    HostVO _destHostMock;
-    @Mock
-    Map<Long, Long> _volumeToPoolMock;
-    @Mock
-    EntityManager _entityMgr;
-    @Mock
-    ConfigDepot _configDepot;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        _vmMgr._templateDao = _templateDao;
-        _vmMgr._volsDao = _volsDao;
-        _vmMgr.volumeMgr = _storageMgr;
-        _vmMgr._capacityMgr = _capacityMgr;
-        _vmMgr._hostDao = _hostDao;
-        _vmMgr._nodeId = 1L;
-        _vmMgr._workDao = _workDao;
-        _vmMgr._agentMgr = _agentMgr;
-        _vmMgr._podDao = _podDao;
-        _vmMgr._clusterDao = _clusterDao;
-        _vmMgr._dcDao = _dcDao;
-        _vmMgr._diskOfferingDao = _diskOfferingDao;
-        _vmMgr._storagePoolDao = _storagePoolDao;
-        _vmMgr._poolHostDao = _poolHostDao;
-        _vmMgr._networkMgr = _networkMgr;
-        _vmMgr._hvGuruMgr = _hvGuruMgr;
-        _vmMgr._vmSnapshotMgr = _vmSnapshotMgr;
-        _vmMgr._vmDao = _vmInstanceDao;
-        _vmMgr._uservmDetailsDao = _vmDetailsDao;
-        _vmMgr._entityMgr = _entityMgr;
-        _vmMgr._configDepot = _configDepot;
-        _vmMgr._offeringDao = _offeringDao;
-        _vmMgr.hostAllocators = new ArrayList<>();
-
-        when(_vmMock.getId()).thenReturn(314l);
-        when(_vmInstance.getId()).thenReturn(1L);
-        when(_vmInstance.getServiceOfferingId()).thenReturn(2L);
-        when(_vmInstance.getInstanceName()).thenReturn("myVm");
-        when(_vmInstance.getHostId()).thenReturn(2L);
-        when(_vmInstance.getType()).thenReturn(VirtualMachine.Type.User);
-        when(_host.getId()).thenReturn(1L);
-        when(_hostDao.findById(anyLong())).thenReturn(null);
-        when(_entityMgr.findById(Matchers.eq(ServiceOffering.class), anyLong())).thenReturn(getSvcoffering(512));
-        when(_workDao.persist(_work)).thenReturn(_work);
-        when(_workDao.update("1", _work)).thenReturn(true);
-        when(_work.getId()).thenReturn("1");
-        doNothing().when(_work).setStep(ItWorkVO.Step.Done);
-        when(_vmInstanceDao.findByUuid(any(String.class))).thenReturn(_vmMock);
-        //doNothing().when(_volsDao).detachVolume(anyLong());
-        //when(_work.setStep(ItWorkVO.Step.Done)).thenReturn("1");
-
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    public void testScaleVM1() throws Exception {
-
-        DeployDestination dest = new DeployDestination(null, null, null, _host);
-        long l = 1L;
-
-        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
-        _vmMgr.migrateForScale(_vmInstance.getUuid(), l, dest, l);
-
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    public void testScaleVM2() throws Exception {
-
-        new DeployDestination(null, null, null, _host);
-        doReturn(3L).when(_vmInstance).getId();
-        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
-        ServiceOfferingVO newServiceOffering = getSvcoffering(512);
-        doReturn(1L).when(_vmInstance).getHostId();
-        doReturn(hostVO).when(_hostDao).findById(1L);
-        doReturn(1L).when(_vmInstance).getDataCenterId();
-        doReturn(1L).when(hostVO).getClusterId();
-        when(CapacityManager.CpuOverprovisioningFactor.valueIn(1L)).thenReturn(1.0f);
-        ScaleVmCommand reconfigureCmd =
-                new ScaleVmCommand("myVmName", newServiceOffering.getCpu(), newServiceOffering.getSpeed(), newServiceOffering.getSpeed(), newServiceOffering.getRamSize(),
-                        newServiceOffering.getRamSize(), newServiceOffering.getLimitCpuUse());
-        new ScaleVmAnswer(reconfigureCmd, true, "details");
-        when(_agentMgr.send(2l, reconfigureCmd)).thenReturn(null);
-        _vmMgr.reConfigureVm(_vmInstance.getUuid(), getSvcoffering(256), false);
-
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    public void testScaleVM3() throws Exception {
-
-        /*VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-
-        Long srcHostId = vm.getHostId();
-        Long oldSvcOfferingId = vm.getServiceOfferingId();
-        if (srcHostId == null) {
-            throw new CloudRuntimeException("Unable to scale the vm because it doesn't have a host id");
-        }*/
-
-        when(_vmInstance.getHostId()).thenReturn(null);
-        when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance);
-        when(_vmInstanceDao.findByUuid(any(String.class))).thenReturn(_vmInstance);
-        DeploymentPlanner.ExcludeList excludeHostList = new DeploymentPlanner.ExcludeList();
-        _vmMgr.findHostAndMigrate(_vmInstance.getUuid(), 2l, excludeHostList);
-
-    }
-
-    private ServiceOfferingVO getSvcoffering(int ramSize) {
-
-        String name = "name";
-        String displayText = "displayText";
-        int cpu = 1;
-        //int ramSize = 256;
-        int speed = 128;
-
-        boolean ha = false;
-        boolean useLocalStorage = false;
-
-        ServiceOfferingVO serviceOffering =
-                new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, ProvisioningType.THIN, useLocalStorage, false, null, false, null, false);
-        return serviceOffering;
-    }
-
-    private void initializeMockConfigForMigratingVmWithVolumes() throws OperationTimedoutException, ResourceUnavailableException {
-
-        // Mock the source and destination hosts.
-        when(_srcHostMock.getId()).thenReturn(5L);
-        when(_destHostMock.getId()).thenReturn(6L);
-        when(_hostDao.findById(5L)).thenReturn(_srcHostMock);
-        when(_hostDao.findById(6L)).thenReturn(_destHostMock);
-
-        // Mock the vm being migrated.
-        when(_vmMock.getId()).thenReturn(1L);
-        when(_vmMock.getHypervisorType()).thenReturn(HypervisorType.XenServer);
-        when(_vmMock.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating).thenReturn(State.Migrating);
-        when(_vmMock.getHostId()).thenReturn(5L);
-        when(_vmInstance.getId()).thenReturn(1L);
-        when(_vmInstance.getServiceOfferingId()).thenReturn(2L);
-        when(_vmInstance.getInstanceName()).thenReturn("myVm");
-        when(_vmInstance.getHostId()).thenReturn(5L);
-        when(_vmInstance.getType()).thenReturn(VirtualMachine.Type.User);
-        when(_vmInstance.getState()).thenReturn(State.Running).thenReturn(State.Running).thenReturn(State.Migrating).thenReturn(State.Migrating);
-
-        // Mock the work item.
-        when(_workDao.persist(any(ItWorkVO.class))).thenReturn(_work);
-        when(_workDao.update("1", _work)).thenReturn(true);
-        when(_work.getId()).thenReturn("1");
-        doNothing().when(_work).setStep(ItWorkVO.Step.Done);
-
-        // Mock the vm guru and the user vm object that gets returned.
-        _vmMgr._vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru>();
-//        UserVmManagerImpl userVmManager = mock(UserVmManagerImpl.class);
-//        _vmMgr.registerGuru(VirtualMachine.Type.User, userVmManager);
-
-        // Mock the iteration over all the volumes of an instance.
-        Iterator<VolumeVO> volumeIterator = mock(Iterator.class);
-        when(_volsDao.findUsableVolumesForInstance(anyLong())).thenReturn(_rootVols);
-        when(_rootVols.iterator()).thenReturn(volumeIterator);
-        when(volumeIterator.hasNext()).thenReturn(true, false);
-        when(volumeIterator.next()).thenReturn(_volumeMock);
-
-        // Mock the disk offering and pool objects for a volume.
-        when(_volumeMock.getDiskOfferingId()).thenReturn(5L);
-        when(_volumeMock.getPoolId()).thenReturn(200L);
-        when(_volumeMock.getId()).thenReturn(5L);
-        when(_diskOfferingDao.findById(anyLong())).thenReturn(_diskOfferingMock);
-        when(_storagePoolDao.findById(200L)).thenReturn(_srcStoragePoolMock);
-        when(_storagePoolDao.findById(201L)).thenReturn(_destStoragePoolMock);
-
-        // Mock the volume to pool mapping.
-        when(_volumeToPoolMock.get(5L)).thenReturn(201L);
-        when(_destStoragePoolMock.getId()).thenReturn(201L);
-        when(_srcStoragePoolMock.getId()).thenReturn(200L);
-        when(_destStoragePoolMock.isLocal()).thenReturn(false);
-        when(_diskOfferingMock.getUseLocalStorage()).thenReturn(false);
-        when(_poolHostDao.findByPoolHost(anyLong(), anyLong())).thenReturn(mock(StoragePoolHostVO.class));
-
-        // Mock hypervisor guru.
-        HypervisorGuru guruMock = mock(HypervisorGuru.class);
-        when(_hvGuruMgr.getGuru(HypervisorType.XenServer)).thenReturn(guruMock);
-
-        when(_srcHostMock.getClusterId()).thenReturn(3L);
-        when(_destHostMock.getClusterId()).thenReturn(3L);
-
-        // Mock the commands and answers to the agent.
-        PrepareForMigrationAnswer prepAnswerMock = mock(PrepareForMigrationAnswer.class);
-        when(prepAnswerMock.getResult()).thenReturn(true);
-        when(_agentMgr.send(anyLong(), isA(PrepareForMigrationCommand.class))).thenReturn(prepAnswerMock);
-
-        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
-        when(migAnswerMock.getResult()).thenReturn(true);
-        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
-
-        MigrateWithStorageReceiveAnswer migRecAnswerMock = mock(MigrateWithStorageReceiveAnswer.class);
-        when(migRecAnswerMock.getResult()).thenReturn(true);
-        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageReceiveCommand.class))).thenReturn(migRecAnswerMock);
-
-        MigrateWithStorageSendAnswer migSendAnswerMock = mock(MigrateWithStorageSendAnswer.class);
-        when(migSendAnswerMock.getResult()).thenReturn(true);
-        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageSendCommand.class))).thenReturn(migSendAnswerMock);
-
-        MigrateWithStorageCompleteAnswer migCompleteAnswerMock = mock(MigrateWithStorageCompleteAnswer.class);
-        when(migCompleteAnswerMock.getResult()).thenReturn(true);
-        when(_agentMgr.send(anyLong(), isA(MigrateWithStorageCompleteCommand.class))).thenReturn(migCompleteAnswerMock);
-
-        CheckVirtualMachineAnswer checkVmAnswerMock = mock(CheckVirtualMachineAnswer.class);
-        when(checkVmAnswerMock.getResult()).thenReturn(true);
-        when(checkVmAnswerMock.getState()).thenReturn(PowerState.PowerOn);
-        when(_agentMgr.send(anyLong(), isA(CheckVirtualMachineCommand.class))).thenReturn(checkVmAnswerMock);
-
-        // Mock the state transitions of vm.
-        Pair<Long, Long> opaqueMock = new Pair<Long, Long>(_vmMock.getHostId(), _destHostMock.getId());
-        when(_vmSnapshotMgr.hasActiveVMSnapshotTasks(anyLong())).thenReturn(false);
-        when(_vmInstanceDao.updateState(State.Running, Event.MigrationRequested, State.Migrating, _vmMock, opaqueMock)).thenReturn(true);
-        when(_vmInstanceDao.updateState(State.Migrating, Event.OperationSucceeded, State.Running, _vmMock, opaqueMock)).thenReturn(true);
-    }
-
-    // Check migration of a vm with its volumes within a cluster.
-    @Test
-    public void testMigrateWithVolumeWithinCluster() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException, OperationTimedoutException {
-
-        initializeMockConfigForMigratingVmWithVolumes();
-        when(_srcHostMock.getClusterId()).thenReturn(3L);
-        when(_destHostMock.getClusterId()).thenReturn(3L);
-
-        _vmMgr.migrateWithStorage(_vmInstance.getUuid(), _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
-    }
-
-    // Check migration of a vm with its volumes across a cluster.
-    @Test
-    public void testMigrateWithVolumeAcrossCluster() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException, OperationTimedoutException {
-
-        initializeMockConfigForMigratingVmWithVolumes();
-        when(_srcHostMock.getClusterId()).thenReturn(3L);
-        when(_destHostMock.getClusterId()).thenReturn(4L);
-
-        _vmMgr.migrateWithStorage(_vmInstance.getUuid(), _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
-    }
-
-    // Check migration of a vm fails when src and destination pool are not of same type; that is, one is shared and
-    // other is local.
-    @Test(expected = CloudRuntimeException.class)
-    public void testMigrateWithVolumeFail1() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException, OperationTimedoutException {
-
-        initializeMockConfigForMigratingVmWithVolumes();
-        when(_srcHostMock.getClusterId()).thenReturn(3L);
-        when(_destHostMock.getClusterId()).thenReturn(3L);
-
-        when(_destStoragePoolMock.isLocal()).thenReturn(true);
-        when(_diskOfferingMock.getUseLocalStorage()).thenReturn(false);
-
-        _vmMgr.migrateWithStorage(_vmInstance.getUuid(), _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
-    }
-
-    // Check migration of a vm fails when vm is not in Running state.
-    @Test(expected = ConcurrentOperationException.class)
-    public void testMigrateWithVolumeFail2() throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException, OperationTimedoutException {
-
-        initializeMockConfigForMigratingVmWithVolumes();
-        when(_srcHostMock.getClusterId()).thenReturn(3L);
-        when(_destHostMock.getClusterId()).thenReturn(3L);
-
-        when(_vmMock.getState()).thenReturn(State.Stopped);
-
-        _vmMgr.migrateWithStorage(_vmInstance.getUuid(), _srcHostMock.getId(), _destHostMock.getId(), _volumeToPoolMock);
-    }
-
-    @Test
-    public void testSendStopWithOkAnswer() throws Exception {
-        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
-        VirtualMachine vm = mock(VirtualMachine.class);
-        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
-        StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "ok", true);
-        when(profile.getVirtualMachine()).thenReturn(vm);
-        when(vm.getHostId()).thenReturn(1L);
-        when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer);
-
-        boolean actual = _vmMgr.sendStop(guru, profile, false, false);
-
-        Assert.assertTrue(actual);
-    }
-
-    @Test
-    public void testSendStopWithFailAnswer() throws Exception {
-        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
-        VirtualMachine vm = mock(VirtualMachine.class);
-        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
-        StopAnswer answer = new StopAnswer(new StopCommand(vm, false, false), "fail", false);
-        when(profile.getVirtualMachine()).thenReturn(vm);
-        when(vm.getHostId()).thenReturn(1L);
-        when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(answer);
-
-        boolean actual = _vmMgr.sendStop(guru, profile, false, false);
-
-        Assert.assertFalse(actual);
-    }
-
-    @Test
-    public void testSendStopWithNullAnswer() throws Exception {
-        VirtualMachineGuru guru = mock(VirtualMachineGuru.class);
-        VirtualMachine vm = mock(VirtualMachine.class);
-        VirtualMachineProfile profile = mock(VirtualMachineProfile.class);
-        when(profile.getVirtualMachine()).thenReturn(vm);
-        when(vm.getHostId()).thenReturn(1L);
-        when(_agentMgr.send(anyLong(), (Command)any())).thenReturn(null);
-
-        boolean actual = _vmMgr.sendStop(guru, profile, false, false);
-
-        Assert.assertFalse(actual);
-    }
-
-    @Test
-    public void testExeceuteInSequence() {
-        assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.XenServer) == false);
-        assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.KVM) == false);
-        assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.VMware) == HypervisorGuru.VmwareFullClone.value());
-        assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.Ovm3) == VirtualMachineManager.ExecuteInSequence.value());
-    }
-
-    @Test
-    public void testCheckIfCanUpgrade() throws Exception {
-        when(_vmInstance.getState()).thenReturn(State.Stopped);
-        when(_serviceOfferingMock.isDynamic()).thenReturn(true);
-        when(_vmInstance.getServiceOfferingId()).thenReturn(1l);
-        when(_serviceOfferingMock.getId()).thenReturn(2l);
-
-        ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);
-
-        when(_offeringDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
-        when(mockCurrentServiceOffering.getUseLocalStorage()).thenReturn(true);
-        when(_serviceOfferingMock.getUseLocalStorage()).thenReturn(true);
-        when(mockCurrentServiceOffering.getSystemUse()).thenReturn(true);
-        when(_serviceOfferingMock.getSystemUse()).thenReturn(true);
-        when(mockCurrentServiceOffering.getTags()).thenReturn("x,y");
-        when(_serviceOfferingMock.getTags()).thenReturn("z,x,y");
-
-        _vmMgr.checkIfCanUpgrade(_vmInstance, _serviceOfferingMock);
-    }
-}
diff --git a/engine/orchestration/test/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java b/engine/orchestration/test/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
deleted file mode 100644
index b0283f3..0000000
--- a/engine/orchestration/test/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.engine.orchestration;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.offerings.NetworkOfferingVO;
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Matchers;
-
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.DhcpServiceProvider;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-
-import junit.framework.TestCase;
-
-/**
- * NetworkManagerImpl implements NetworkManager.
- */
-@RunWith(JUnit4.class)
-public class NetworkOrchestratorTest extends TestCase {
-    static final Logger s_logger = Logger.getLogger(NetworkOrchestratorTest.class);
-
-    NetworkOrchestrator testOrchastrator = new NetworkOrchestrator();
-
-    String guruName = "GuestNetworkGuru";
-    String dhcpProvider = "VirtualRouter";
-    NetworkGuru guru = mock(NetworkGuru.class);
-
-    NetworkOfferingVO networkOffering = mock(NetworkOfferingVO.class);
-
-    private static final long networkOfferingId = 1l;
-
-    @Override
-    @Before
-    public void setUp() {
-        // make class-scope mocks
-        testOrchastrator._nicDao = mock(NicDao.class);
-        testOrchastrator._networksDao = mock(NetworkDao.class);
-        testOrchastrator._networkModel = mock(NetworkModel.class);
-        testOrchastrator._nicSecondaryIpDao = mock(NicSecondaryIpDao.class);
-        testOrchastrator._ntwkSrvcDao = mock(NetworkServiceMapDao.class);
-        testOrchastrator._nicIpAliasDao = mock(NicIpAliasDao.class);
-        DhcpServiceProvider provider = mock(DhcpServiceProvider.class);
-
-        Map<Network.Capability, String> capabilities = new HashMap<Network.Capability, String>();
-        Map<Network.Service,Map<Network.Capability, String>> services = new HashMap<Network.Service,Map<Network.Capability, String>>();
-        services.put(Network.Service.Dhcp,capabilities);
-        when(provider.getCapabilities()).thenReturn(services);
-        capabilities.put(Network.Capability.DhcpAccrossMultipleSubnets, "true");
-
-        when(testOrchastrator._ntwkSrvcDao.getProviderForServiceInNetwork(Matchers.anyLong(), Matchers.eq(Service.Dhcp))).thenReturn(dhcpProvider);
-        when(testOrchastrator._networkModel.getElementImplementingProvider(dhcpProvider)).thenReturn(provider);
-
-        when(guru.getName()).thenReturn(guruName);
-        List<NetworkGuru> networkGurus = new ArrayList<NetworkGuru>();
-        networkGurus.add(guru);
-        testOrchastrator.networkGurus = networkGurus;
-
-        when(networkOffering.getGuestType()).thenReturn(GuestType.L2);
-        when(networkOffering.getId()).thenReturn(networkOfferingId);
-    }
-
-    @Test
-    public void testRemoveDhcpServiceWithNic() {
-        // make local mocks
-        VirtualMachineProfile vm =  mock(VirtualMachineProfile.class);
-        NicVO nic = mock(NicVO.class);
-        NetworkVO network = mock(NetworkVO.class);
-
-        // make sure that release dhcp will be called
-        when(vm.getType()).thenReturn(Type.User);
-        when(testOrchastrator._networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)).thenReturn(true);
-        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(network.getGuestType()).thenReturn(GuestType.Shared);
-        when(testOrchastrator._nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getIPv4Gateway(), nic.getBroadcastUri())).thenReturn(new ArrayList<NicVO>());
-
-
-
-        when(network.getGuruName()).thenReturn(guruName);
-        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
-
-        testOrchastrator.removeNic(vm, nic);
-
-        verify(nic, times(1)).setState(Nic.State.Deallocating);
-        verify(testOrchastrator._networkModel, times(2)).getElementImplementingProvider(dhcpProvider);
-        verify(testOrchastrator._ntwkSrvcDao, times(2)).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
-        verify(testOrchastrator._networksDao, times(2)).findById(nic.getNetworkId());
-    }
-    @Test
-    public void testDontRemoveDhcpServiceFromDomainRouter() {
-        // make local mocks
-        VirtualMachineProfile vm =  mock(VirtualMachineProfile.class);
-        NicVO nic = mock(NicVO.class);
-        NetworkVO network = mock(NetworkVO.class);
-
-        // make sure that release dhcp won't be called
-        when(vm.getType()).thenReturn(Type.DomainRouter);
-
-        when(network.getGuruName()).thenReturn(guruName);
-        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
-
-        testOrchastrator.removeNic(vm, nic);
-
-        verify(nic, times(1)).setState(Nic.State.Deallocating);
-        verify(testOrchastrator._networkModel, never()).getElementImplementingProvider(dhcpProvider);
-        verify(testOrchastrator._ntwkSrvcDao, never()).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
-        verify(testOrchastrator._networksDao, times(1)).findById(nic.getNetworkId());
-    }
-    @Test
-    public void testDontRemoveDhcpServiceWhenNotProvided() {
-        // make local mocks
-        VirtualMachineProfile vm =  mock(VirtualMachineProfile.class);
-        NicVO nic = mock(NicVO.class);
-        NetworkVO network = mock(NetworkVO.class);
-
-        // make sure that release dhcp will *not* be called
-        when(vm.getType()).thenReturn(Type.User);
-        when(testOrchastrator._networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)).thenReturn(false);
-
-        when(network.getGuruName()).thenReturn(guruName);
-        when(testOrchastrator._networksDao.findById(nic.getNetworkId())).thenReturn(network);
-
-        testOrchastrator.removeNic(vm, nic);
-
-        verify(nic, times(1)).setState(Nic.State.Deallocating);
-        verify(testOrchastrator._networkModel, never()).getElementImplementingProvider(dhcpProvider);
-        verify(testOrchastrator._ntwkSrvcDao, never()).getProviderForServiceInNetwork(network.getId(), Service.Dhcp);
-        verify(testOrchastrator._networksDao, times(1)).findById(nic.getNetworkId());
-    }
-
-    @Test
-    public void testCheckL2OfferingServicesEmptyServices() {
-        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(new ArrayList<>());
-        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(false);
-        testOrchastrator.checkL2OfferingServices(networkOffering);
-    }
-
-    @Test
-    public void testCheckL2OfferingServicesUserDataOnly() {
-        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.UserData));
-        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(true);
-        testOrchastrator.checkL2OfferingServices(networkOffering);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testCheckL2OfferingServicesMultipleServicesIncludingUserData() {
-        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.UserData, Service.Dhcp));
-        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(true);
-        testOrchastrator.checkL2OfferingServices(networkOffering);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testCheckL2OfferingServicesMultipleServicesNotIncludingUserData() {
-        when(testOrchastrator._networkModel.listNetworkOfferingServices(networkOfferingId)).thenReturn(Arrays.asList(Service.Dns, Service.Dhcp));
-        when(testOrchastrator._networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.UserData)).thenReturn(false);
-        testOrchastrator.checkL2OfferingServices(networkOffering);
-    }
-}
diff --git a/engine/pom.xml b/engine/pom.xml
index caf561c..63454d0 100644
--- a/engine/pom.xml
+++ b/engine/pom.xml
@@ -1,69 +1,70 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine</artifactId>
-  <name>Apache CloudStack Cloud Engine</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>none</phase>
-              <inherited>false</inherited>
-            </execution>
-          </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <modules>
-    <module>api</module>
-    <module>orchestration</module>
-    <module>schema</module>
-    <module>storage</module>
-    <module>storage/volume</module>
-    <module>storage/image</module>
-    <module>storage/datamotion</module>
-    <module>storage/cache</module>
-    <module>storage/snapshot</module>
-    <module>storage/configdrive</module>
-    <module>components-api</module>
-    <module>network</module>
-    <module>service</module>
-  </modules>
-  <profiles>
-  <profile>
-      <id>integration-test</id>
-      <modules>
-        <module>storage/integration-test</module>
-      </modules>
-  </profile>
-  </profiles>
+<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-engine</artifactId>
+    <name>Apache CloudStack Cloud Engine</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <!-- keep in alphabetic order -->
+        <module>api</module>
+        <module>components-api</module>
+        <module>network</module>
+        <module>orchestration</module>
+        <module>schema</module>
+        <module>service</module>
+        <module>storage</module>
+        <module>storage/cache</module>
+        <module>storage/configdrive</module>
+        <module>storage/datamotion</module>
+        <module>storage/image</module>
+        <module>storage/snapshot</module>
+        <module>storage/volume</module>
+    </modules>
+    <profiles>
+        <profile>
+            <id>integration-test</id>
+            <modules>
+                <module>storage/integration-test</module>
+            </modules>
+        </profile>
+    </profiles>
 </project>
diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml
index ab02646..f363356 100644
--- a/engine/schema/pom.xml
+++ b/engine/schema/pom.xml
@@ -1,52 +1,52 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine-schema</artifactId>
-  <name>Apache CloudStack Cloud Engine Schema Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-schema</artifactId>
+    <name>Apache CloudStack Cloud Engine Schema Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/schema/resources/META-INF/db/schema-227to228-premium.sql b/engine/schema/resources/META-INF/db/schema-227to228-premium.sql
deleted file mode 100755
index 8c3af0c..0000000
--- a/engine/schema/resources/META-INF/db/schema-227to228-premium.sql
+++ /dev/null
@@ -1,76 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
--- 
---   http://www.apache.org/licenses/LICENSE-2.0
--- 
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---;
--- Schema upgrade from 2.2.7 to 2.2.8;
---;
-CREATE TABLE IF NOT EXISTS `cloud`.`netapp_pool` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `name` varchar(255) NOT NULL UNIQUE COMMENT 'name for the pool',
-  `algorithm` varchar(255) NOT NULL COMMENT 'algorithm',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `cloud`.`netapp_volume` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `ip_address` varchar(255) NOT NULL COMMENT 'ip address/fqdn of the volume',
-  `pool_id` bigint unsigned NOT NULL COMMENT 'id for the pool',
-  `pool_name` varchar(255) NOT NULL COMMENT 'name for the pool',
-  `aggregate_name` varchar(255) NOT NULL COMMENT 'name for the aggregate',
-  `volume_name` varchar(255) NOT NULL COMMENT 'name for the volume',
-  `volume_size` varchar(255) NOT NULL COMMENT 'volume size',
-  `snapshot_policy` varchar(255) NOT NULL COMMENT 'snapshot policy',
-  `snapshot_reservation` int NOT NULL COMMENT 'snapshot reservation',  
-  `username` varchar(255) NOT NULL COMMENT 'username',  
-  `password` varchar(200) COMMENT 'password',
-  `round_robin_marker` int COMMENT 'This marks the volume to be picked up for lun creation, RR fashion',
-  PRIMARY KEY (`ip_address`,`aggregate_name`,`volume_name`),
-  CONSTRAINT `fk_netapp_volume__pool_id` FOREIGN KEY `fk_netapp_volume__pool_id` (`pool_id`) REFERENCES `netapp_pool` (`id`) ON DELETE CASCADE,
-  INDEX `i_netapp_volume__pool_id`(`pool_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `cloud`.`netapp_lun` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `lun_name` varchar(255) NOT NULL COMMENT 'lun name',
-  `target_iqn` varchar(255) NOT NULL COMMENT 'target iqn',
-  `path` varchar(255) NOT NULL COMMENT 'lun path',
-  `size` bigint NOT NULL COMMENT 'lun size',
-  `volume_id` bigint unsigned NOT NULL COMMENT 'parent volume id',
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_netapp_lun__volume_id` FOREIGN KEY `fk_netapp_lun__volume_id` (`volume_id`) REFERENCES `netapp_volume` (`id`) ON DELETE CASCADE,
-  INDEX `i_netapp_lun__volume_id`(`volume_id`),
-  INDEX `i_netapp_lun__lun_name`(`lun_name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
---;
--- Cleanup usage records for bug # 10727;
---;
-
-
-create table `cloud_usage`.`temp_usage` (  `vol_id` bigint unsigned, `created` DATETIME);
-
-insert into `cloud_usage`.`temp_usage` (vol_id, created) select id, max(created) from `cloud_usage`.`usage_volume` where deleted is null group by id having count(id) > 1;
-
-delete `cloud_usage`.`usage_volume` from `cloud_usage`.`usage_volume` inner join `cloud_usage`.`temp_usage` where `cloud_usage`.`usage_volume`.created = `cloud_usage`.`temp_usage`.created and `cloud_usage`.`usage_volume`.id = `cloud_usage`.`temp_usage`.vol_id and `cloud_usage`.`usage_volume`.deleted is null;
-
-drop table `cloud_usage`.`temp_usage`;
-
-update `cloud_usage`.`cloud_usage` set raw_usage = (raw_usage % 24) where usage_type =6 and raw_usage > 24 and (raw_usage % 24) <> 0;
-update `cloud_usage`.`cloud_usage` set raw_usage = 24 where usage_type =6 and raw_usage > 24 and (raw_usage % 24) = 0;
-
diff --git a/engine/schema/resources/META-INF/db/schema-41000to41100-cleanup.sql b/engine/schema/resources/META-INF/db/schema-41000to41100-cleanup.sql
deleted file mode 100644
index d7a080e..0000000
--- a/engine/schema/resources/META-INF/db/schema-41000to41100-cleanup.sql
+++ /dev/null
@@ -1,69 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---;
--- Schema upgrade cleanup from 4.10.0.0 to 4.11.0.0
---;
-
-DELETE FROM `cloud`.`configuration` WHERE name='snapshot.backup.rightafter';
--- CLOUDSTACK-9914: Alter quota_tariff to support currency values up to 5 decimal places
-ALTER TABLE `cloud_usage`.`quota_tariff` MODIFY `currency_value` DECIMAL(15,5) not null;
-
-DROP VIEW IF EXISTS `cloud`.`user_view`;
-CREATE VIEW `cloud`.`user_view` AS
-    select
-        user.id,
-        user.uuid,
-        user.username,
-        user.password,
-        user.firstname,
-        user.lastname,
-        user.email,
-        user.state,
-        user.api_key,
-        user.secret_key,
-        user.created,
-        user.removed,
-        user.timezone,
-        user.registration_token,
-        user.is_registered,
-        user.incorrect_login_attempts,
-        user.source,
-        user.default,
-        account.id account_id,
-        account.uuid account_uuid,
-        account.account_name account_name,
-        account.type account_type,
-        account.role_id account_role_id,
-        domain.id domain_id,
-        domain.uuid domain_uuid,
-        domain.name domain_name,
-        domain.path domain_path,
-        async_job.id job_id,
-        async_job.uuid job_uuid,
-        async_job.job_status job_status,
-        async_job.account_id job_account_id
-    from
-        `cloud`.`user`
-            inner join
-        `cloud`.`account` ON user.account_id = account.id
-            inner join
-        `cloud`.`domain` ON account.domain_id = domain.id
-            left join
-        `cloud`.`async_job` ON async_job.instance_id = user.id
-            and async_job.instance_type = 'User'
-            and async_job.job_status = 0;
diff --git a/engine/schema/resources/META-INF/db/schema-41000to41100.sql b/engine/schema/resources/META-INF/db/schema-41000to41100.sql
deleted file mode 100644
index b3efce4..0000000
--- a/engine/schema/resources/META-INF/db/schema-41000to41100.sql
+++ /dev/null
@@ -1,610 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---;
--- Schema upgrade from 4.10.0.0 to 4.11.0.0
---;
-
---;
--- Stored procedure to do idempotent column add;
---;
-DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_ADD_COLUMN`;
-
-CREATE PROCEDURE `cloud`.`IDEMPOTENT_ADD_COLUMN` (
-		IN in_table_name VARCHAR(200)
-    , IN in_column_name VARCHAR(200)
-    , IN in_column_definition VARCHAR(1000)
-)
-BEGIN
-
-    DECLARE CONTINUE HANDLER FOR 1060 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', 'ADD COLUMN') ; SET @ddl = CONCAT(@ddl, ' ', in_column_name); SET @ddl = CONCAT(@ddl, ' ', in_column_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
-
-DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`;
-
-CREATE PROCEDURE `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY` (
-		IN in_table_name VARCHAR(200)
-    , IN in_foreign_key_name VARCHAR(200)
-)
-BEGIN
-
-    DECLARE CONTINUE HANDLER FOR 1091 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', ' DROP FOREIGN KEY '); SET @ddl = CONCAT(@ddl, ' ', in_foreign_key_name); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
-
-DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_DROP_INDEX`;
-
-CREATE PROCEDURE `cloud`.`IDEMPOTENT_DROP_INDEX` (
-		IN in_index_name VARCHAR(200)
-    , IN in_table_name VARCHAR(200)
-)
-BEGIN
-
-    DECLARE CONTINUE HANDLER FOR 1091 BEGIN END; SET @ddl = CONCAT('DROP INDEX ', in_index_name); SET @ddl = CONCAT(@ddl, ' ', ' ON ') ; SET @ddl = CONCAT(@ddl, ' ', in_table_name); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
-
-DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX`;
-
-CREATE PROCEDURE `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX` (
-		IN in_index_name VARCHAR(200)
-    , IN in_table_name VARCHAR(200)
-    , IN in_index_definition VARCHAR(1000)
-)
-BEGIN
-
-    DECLARE CONTINUE HANDLER FOR 1061 BEGIN END; SET @ddl = CONCAT('CREATE UNIQUE INDEX ', in_index_name); SET @ddl = CONCAT(@ddl, ' ', ' ON ') ; SET @ddl = CONCAT(@ddl, ' ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', in_index_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
-
--- Add For VPC flag
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','for_vpc', 'INT(1) NOT NULL DEFAULT 0');
-
-UPDATE cloud.network_offerings o
-SET for_vpc = 1
-where
-  o.conserve_mode = 0
-  and o.guest_type = 'Isolated'
-  and exists(
-    SELECT id
-    from cloud.ntwk_offering_service_map
-    where network_offering_id = o.id and (
-      provider in ('VpcVirtualRouter', 'InternalLbVm', 'JuniperContrailVpcRouter')
-      or service in ('NetworkACL')
-    )
-  );
-
-UPDATE `cloud`.`configuration` SET value = '600', default_value = '600' WHERE category = 'Advanced' AND name = 'router.aggregation.command.each.timeout';
-
--- CA framework changes
-DELETE from `cloud`.`configuration` where name='ssl.keystore';
-
--- Certificate Revocation List
-CREATE TABLE IF NOT EXISTS `cloud`.`crl` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `serial` varchar(255) UNIQUE NOT NULL COMMENT 'certificate\'s serial number as hex string',
-  `cn` varchar(255) COMMENT 'certificate\'s common name',
-  `revoker_uuid` varchar(40) COMMENT 'revoker user account uuid',
-  `revoked` datetime COMMENT 'date of revocation',
-  PRIMARY KEY (`id`),
-  KEY (`serial`),
-  UNIQUE KEY (`serial`, `cn`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
--- Host HA feature
-CREATE TABLE IF NOT EXISTS `cloud`.`ha_config` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `resource_id` bigint(20) unsigned DEFAULT NULL COMMENT 'id of the resource',
-  `resource_type` varchar(255) NOT NULL COMMENT 'the type of the resource',
-  `enabled` int(1) unsigned DEFAULT '0' COMMENT 'is HA enabled for the resource',
-  `ha_state` varchar(255) DEFAULT 'Disabled' COMMENT 'HA state',
-  `provider` varchar(255) DEFAULT NULL COMMENT 'HA provider',
-  `update_count` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'state based incr-only counter for atomic ha_state updates',
-  `update_time` datetime COMMENT 'last ha_state update datetime',
-  `mgmt_server_id` bigint(20) unsigned DEFAULT NULL COMMENT 'management server id that is responsible for the HA for the resource',
-  PRIMARY KEY (`id`),
-  KEY `i_ha_config__enabled` (`enabled`),
-  KEY `i_ha_config__ha_state` (`ha_state`),
-  KEY `i_ha_config__mgmt_server_id` (`mgmt_server_id`),
-  UNIQUE KEY (`resource_id`, `resource_type`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-DELETE from `cloud`.`configuration` where name='outofbandmanagement.sync.interval';
-
--- Annotations specifc changes following
-CREATE TABLE IF NOT EXISTS `cloud`.`annotations` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `uuid` varchar(40) UNIQUE,
-  `annotation` text,
-  `entity_uuid` varchar(40),
-  `entity_type` varchar(32),
-  `user_uuid` varchar(40),
-  `created` datetime COMMENT 'date of creation',
-  `removed` datetime COMMENT 'date of removal',
-  PRIMARY KEY (`id`),
-  KEY (`uuid`),
-  KEY `i_entity` (`entity_uuid`, `entity_type`, `created`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-DROP VIEW IF EXISTS `cloud`.`last_annotation_view`;
-CREATE VIEW `cloud`.`last_annotation_view` AS
-    SELECT
-        `annotations`.`uuid` AS `uuid`,
-        `annotations`.`annotation` AS `annotation`,
-        `annotations`.`entity_uuid` AS `entity_uuid`,
-        `annotations`.`entity_type` AS `entity_type`,
-        `annotations`.`user_uuid` AS `user_uuid`,
-        `annotations`.`created` AS `created`,
-        `annotations`.`removed` AS `removed`
-    FROM
-        `annotations`
-    WHERE
-        `annotations`.`created` IN (SELECT
-                                        MAX(`annotations`.`created`)
-                                    FROM
-                                        `annotations`
-                                    WHERE
-                                        `annotations`.`removed` IS NULL
-                                    GROUP BY `annotations`.`entity_uuid`);
-
--- Host HA changes:
-DROP VIEW IF EXISTS `cloud`.`host_view`;
-CREATE VIEW `cloud`.`host_view` AS
-    SELECT
-        host.id,
-        host.uuid,
-        host.name,
-        host.status,
-        host.disconnected,
-        host.type,
-        host.private_ip_address,
-        host.version,
-        host.hypervisor_type,
-        host.hypervisor_version,
-        host.capabilities,
-        host.last_ping,
-        host.created,
-        host.removed,
-        host.resource_state,
-        host.mgmt_server_id,
-        host.cpu_sockets,
-        host.cpus,
-        host.speed,
-        host.ram,
-        cluster.id cluster_id,
-        cluster.uuid cluster_uuid,
-        cluster.name cluster_name,
-        cluster.cluster_type,
-        data_center.id data_center_id,
-        data_center.uuid data_center_uuid,
-        data_center.name data_center_name,
-        data_center.networktype data_center_type,
-        host_pod_ref.id pod_id,
-        host_pod_ref.uuid pod_uuid,
-        host_pod_ref.name pod_name,
-        host_tags.tag,
-        guest_os_category.id guest_os_category_id,
-        guest_os_category.uuid guest_os_category_uuid,
-        guest_os_category.name guest_os_category_name,
-        mem_caps.used_capacity memory_used_capacity,
-        mem_caps.reserved_capacity memory_reserved_capacity,
-        cpu_caps.used_capacity cpu_used_capacity,
-        cpu_caps.reserved_capacity cpu_reserved_capacity,
-        async_job.id job_id,
-        async_job.uuid job_uuid,
-        async_job.job_status job_status,
-        async_job.account_id job_account_id,
-        oobm.enabled AS `oobm_enabled`,
-        oobm.power_state AS `oobm_power_state`,
-        ha_config.enabled AS `ha_enabled`,
-        ha_config.ha_state AS `ha_state`,
-        ha_config.provider AS `ha_provider`,
-        `last_annotation_view`.`annotation` AS `annotation`,
-        `last_annotation_view`.`created` AS `last_annotated`,
-        `user`.`username` AS `username`
-    FROM
-        `cloud`.`host`
-            LEFT JOIN
-        `cloud`.`cluster` ON host.cluster_id = cluster.id
-            LEFT JOIN
-        `cloud`.`data_center` ON host.data_center_id = data_center.id
-            LEFT JOIN
-        `cloud`.`host_pod_ref` ON host.pod_id = host_pod_ref.id
-            LEFT JOIN
-        `cloud`.`host_details` ON host.id = host_details.host_id
-            AND host_details.name = 'guest.os.category.id'
-            LEFT JOIN
-        `cloud`.`guest_os_category` ON guest_os_category.id = CONVERT ( host_details.value, UNSIGNED )
-            LEFT JOIN
-        `cloud`.`host_tags` ON host_tags.host_id = host.id
-            LEFT JOIN
-        `cloud`.`op_host_capacity` mem_caps ON host.id = mem_caps.host_id
-            AND mem_caps.capacity_type = 0
-            LEFT JOIN
-        `cloud`.`op_host_capacity` cpu_caps ON host.id = cpu_caps.host_id
-            AND cpu_caps.capacity_type = 1
-            LEFT JOIN
-        `cloud`.`async_job` ON async_job.instance_id = host.id
-            AND async_job.instance_type = 'Host'
-            AND async_job.job_status = 0
-            LEFT JOIN
-        `cloud`.`oobm` ON oobm.host_id = host.id
-            left join
-        `cloud`.`ha_config` ON ha_config.resource_id=host.id
-            and ha_config.resource_type='Host'
-            LEFT JOIN
-        `cloud`.`last_annotation_view` ON `last_annotation_view`.`entity_uuid` = `host`.`uuid`
-            LEFT JOIN
-        `cloud`.`user` ON `user`.`uuid` = `last_annotation_view`.`user_uuid`;
--- End Of Annotations specific changes
-
--- Out-of-band management driver for nested-cloudstack
-ALTER TABLE `cloud`.`oobm` MODIFY COLUMN port VARCHAR(255);
-
--- CLOUDSTACK-9902: Console proxy SSL toggle
-INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `description`, `default_value`, `is_dynamic`) VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.sslEnabled', 'false', 'Enable SSL for console proxy', 'false', 0);
-
--- CLOUDSTACK-9859: Retirement of midonet plugin (final removal)
-delete from `cloud`.`configuration` where name in ('midonet.apiserver.address', 'midonet.providerrouter.id');
-
--- CLOUDSTACK-9972: Enhance listVolumes API
-INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Premium', 'DEFAULT', 'management-server', 'volume.stats.interval', '600000', 'Interval (in seconds) to report volume statistics', '600000', now(), NULL, NULL);
-
-DROP VIEW IF EXISTS `cloud`.`volume_view`;
-CREATE VIEW `cloud`.`volume_view` AS
-    SELECT
-        volumes.id,
-        volumes.uuid,
-        volumes.name,
-        volumes.device_id,
-        volumes.volume_type,
-        volumes.provisioning_type,
-        volumes.size,
-        volumes.min_iops,
-        volumes.max_iops,
-        volumes.created,
-        volumes.state,
-        volumes.attached,
-        volumes.removed,
-        volumes.display_volume,
-        volumes.format,
-        volumes.path,
-        volumes.chain_info,
-        account.id account_id,
-        account.uuid account_uuid,
-        account.account_name account_name,
-        account.type account_type,
-        domain.id domain_id,
-        domain.uuid domain_uuid,
-        domain.name domain_name,
-        domain.path domain_path,
-        projects.id project_id,
-        projects.uuid project_uuid,
-        projects.name project_name,
-        data_center.id data_center_id,
-        data_center.uuid data_center_uuid,
-        data_center.name data_center_name,
-        data_center.networktype data_center_type,
-        vm_instance.id vm_id,
-        vm_instance.uuid vm_uuid,
-        vm_instance.name vm_name,
-        vm_instance.state vm_state,
-        vm_instance.vm_type,
-        user_vm.display_name vm_display_name,
-        volume_store_ref.size volume_store_size,
-        volume_store_ref.download_pct,
-        volume_store_ref.download_state,
-        volume_store_ref.error_str,
-        volume_store_ref.created created_on_store,
-        disk_offering.id disk_offering_id,
-        disk_offering.uuid disk_offering_uuid,
-        disk_offering.name disk_offering_name,
-        disk_offering.display_text disk_offering_display_text,
-        disk_offering.use_local_storage,
-        disk_offering.system_use,
-        disk_offering.bytes_read_rate,
-        disk_offering.bytes_write_rate,
-        disk_offering.iops_read_rate,
-        disk_offering.iops_write_rate,
-        disk_offering.cache_mode,
-        storage_pool.id pool_id,
-        storage_pool.uuid pool_uuid,
-        storage_pool.name pool_name,
-        cluster.id cluster_id,
-        cluster.name cluster_name,
-        cluster.uuid cluster_uuid,
-        cluster.hypervisor_type,
-        vm_template.id template_id,
-        vm_template.uuid template_uuid,
-        vm_template.extractable,
-        vm_template.type template_type,
-        vm_template.name template_name,
-        vm_template.display_text template_display_text,
-        iso.id iso_id,
-        iso.uuid iso_uuid,
-        iso.name iso_name,
-        iso.display_text iso_display_text,
-        resource_tags.id tag_id,
-        resource_tags.uuid tag_uuid,
-        resource_tags.key tag_key,
-        resource_tags.value tag_value,
-        resource_tags.domain_id tag_domain_id,
-        resource_tags.account_id tag_account_id,
-        resource_tags.resource_id tag_resource_id,
-        resource_tags.resource_uuid tag_resource_uuid,
-        resource_tags.resource_type tag_resource_type,
-        resource_tags.customer tag_customer,
-        async_job.id job_id,
-        async_job.uuid job_uuid,
-        async_job.job_status job_status,
-        async_job.account_id job_account_id,
-        host_pod_ref.id pod_id,
-        host_pod_ref.uuid pod_uuid,
-        host_pod_ref.name pod_name,
-        resource_tag_account.account_name tag_account_name,
-        resource_tag_domain.uuid tag_domain_uuid,
-        resource_tag_domain.name tag_domain_name
-    from
-        `cloud`.`volumes`
-            inner join
-        `cloud`.`account` ON volumes.account_id = account.id
-            inner join
-        `cloud`.`domain` ON volumes.domain_id = domain.id
-            left join
-        `cloud`.`projects` ON projects.project_account_id = account.id
-            left join
-        `cloud`.`data_center` ON volumes.data_center_id = data_center.id
-            left join
-        `cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id
-            left join
-        `cloud`.`user_vm` ON user_vm.id = vm_instance.id
-            left join
-        `cloud`.`volume_store_ref` ON volumes.id = volume_store_ref.volume_id
-            left join
-        `cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id
-            left join
-        `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id
-            left join
-        `cloud`.`host_pod_ref` ON storage_pool.pod_id = host_pod_ref.id
-            left join
-        `cloud`.`cluster` ON storage_pool.cluster_id = cluster.id
-            left join
-        `cloud`.`vm_template` ON volumes.template_id = vm_template.id
-            left join
-        `cloud`.`vm_template` iso ON iso.id = volumes.iso_id
-            left join
-        `cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id
-            and resource_tags.resource_type = 'Volume'
-            left join
-        `cloud`.`async_job` ON async_job.instance_id = volumes.id
-            and async_job.instance_type = 'Volume'
-            and async_job.job_status = 0
-            left join
-        `cloud`.`account` resource_tag_account ON resource_tag_account.id = resource_tags.account_id
-            left join
-        `cloud`.`domain` resource_tag_domain ON resource_tag_domain.id = resource_tags.domain_id;
-
--- Extra Dhcp Options
-CREATE TABLE IF NOT EXISTS `cloud`.`nic_extra_dhcp_options` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `uuid` varchar(255) UNIQUE,
-  `nic_id` bigint unsigned NOT NULL COMMENT ' nic id where dhcp options are applied',
-  `code` int(32),
-  `value` text,
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_nic_extra_dhcp_options_nic_id` FOREIGN KEY (`nic_id`) REFERENCES `nics`(`id`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
--- Add new OS versions
-
--- Add XenServer 7.1 and 7.2 hypervisor capabilities
-INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, storage_motion_supported) values (UUID(), 'XenServer', '7.1.0', 500, 13, 1);
-INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, storage_motion_supported) values (UUID(), 'XenServer', '7.2.0', 500, 13, 1);
-
--- Add XenServer 7.0 support for windows 10
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.0.0', 'Windows 10 (64-bit)', 258, now(), 0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.0.0', 'Windows 10 (32-bit)', 257, now(), 0);
-
--- Add XenServer 7.1 hypervisor guest OS mappings (copy 7.0.0)
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '7.1.0', guest_os_name, guest_os_id, utc_timestamp(), 0  FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='7.0.0';
-
--- Add XenServer 7.1 hypervisor guest OS (see https://docs.citrix.com/content/dam/docs/en-us/xenserver/7-1/downloads/xenserver-7-1-release-notes.pdf)
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Windows Server 2016 (64-bit)', 259, now(), 0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'SUSE Linux Enterprise Server 11 SP4', 187, now(),  0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 240, now(),  0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Red Hat Enterprise Linux 7', 245, now(),  0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Oracle Enterprise Linux 6 (64-bit)', 251, now(),  0);
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Oracle Linux 7', 247, now(),  0);
-
--- Add XenServer 7.2 hypervisor guest OS mappings (copy 7.1.0 & remove Windows Vista, Windows XP, Windows 2003, CentOS 4.x, RHEL 4.xS, LES 10 (all versions) as per XenServer 7.2 Release Notes)
-INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '7.2.0', guest_os_name, guest_os_id, utc_timestamp(), 0  FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='7.1.0' AND guest_os_id not in (1,2,3,4,56,101,56,58,93,94,50,51,87,88,89,90,91,92,26,27,28,29,40,41,42,43,44,45,96,97,107,108,109,110,151,152,153);
-
--- Add table to track primary storage in use for snapshots
-CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_snapshot_on_primary` (
-  `id` bigint(20) unsigned NOT NULL,
-  `zone_id` bigint(20) unsigned NOT NULL,
-  `account_id` bigint(20) unsigned NOT NULL,
-  `domain_id` bigint(20) unsigned NOT NULL,
-  `vm_id` bigint(20) unsigned NOT NULL,
-  `name` varchar(128),
-  `type` int(1) unsigned NOT NULL,
-  `physicalsize` bigint(20),
-  `virtualsize` bigint(20),
-  `created` datetime NOT NULL,
-  `deleted` datetime,
-  INDEX `i_usage_snapshot_on_primary` (`account_id`,`id`,`vm_id`,`created`)
-) ENGINE=InnoDB CHARSET=utf8;
-
--- Change monitor patch for apache2 in systemvm
-UPDATE `cloud`.`monitoring_services` SET pidfile="/var/run/apache2/apache2.pid" WHERE process_name="apache2" AND service_name="apache2";
-
--- Use 'Other Linux 64-bit' as guest os for the default systemvmtemplate for VMware
--- This fixes a memory allocation issue to systemvms on VMware/ESXi
-UPDATE `cloud`.`vm_template` SET guest_os_id=99 WHERE id=8;
-
--- Network External Ids
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.networks','external_id', 'varchar(255)');
-
--- Separate Subnet for CPVM and SSVM (system vms)
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.op_dc_ip_address_alloc','forsystemvms', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''Indicates if IP is dedicated for CPVM or SSVM'' ');
-
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.op_dc_ip_address_alloc','vlan', 'INT(10) UNSIGNED NULL COMMENT ''Vlan the management network range is on'' ');
-
--- CLOUDSTACK-4757: Support multidisk OVA
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_template','parent_template_id', 'bigint(20) unsigned DEFAULT NULL COMMENT ''If datadisk template, then id of the root template this template belongs to'' ');
-
--- CLOUDSTACK-10146: Bypass Secondary Storage for KVM templates
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_template','direct_download', 'TINYINT(1) DEFAULT 0 COMMENT ''Indicates if Secondary Storage is bypassed and template is downloaded to Primary Storage'' ');
-
--- Changes to template_view for both multidisk OVA and bypass secondary storage for KVM templates
-DROP VIEW IF EXISTS `cloud`.`template_view`;
-CREATE VIEW `cloud`.`template_view` AS
-     SELECT
-         `vm_template`.`id` AS `id`,
-         `vm_template`.`uuid` AS `uuid`,
-         `vm_template`.`unique_name` AS `unique_name`,
-         `vm_template`.`name` AS `name`,
-         `vm_template`.`public` AS `public`,
-         `vm_template`.`featured` AS `featured`,
-         `vm_template`.`type` AS `type`,
-         `vm_template`.`hvm` AS `hvm`,
-         `vm_template`.`bits` AS `bits`,
-         `vm_template`.`url` AS `url`,
-         `vm_template`.`format` AS `format`,
-         `vm_template`.`created` AS `created`,
-         `vm_template`.`checksum` AS `checksum`,
-         `vm_template`.`display_text` AS `display_text`,
-         `vm_template`.`enable_password` AS `enable_password`,
-         `vm_template`.`dynamically_scalable` AS `dynamically_scalable`,
-         `vm_template`.`state` AS `template_state`,
-         `vm_template`.`guest_os_id` AS `guest_os_id`,
-         `guest_os`.`uuid` AS `guest_os_uuid`,
-         `guest_os`.`display_name` AS `guest_os_name`,
-         `vm_template`.`bootable` AS `bootable`,
-         `vm_template`.`prepopulate` AS `prepopulate`,
-         `vm_template`.`cross_zones` AS `cross_zones`,
-         `vm_template`.`hypervisor_type` AS `hypervisor_type`,
-         `vm_template`.`extractable` AS `extractable`,
-         `vm_template`.`template_tag` AS `template_tag`,
-         `vm_template`.`sort_key` AS `sort_key`,
-         `vm_template`.`removed` AS `removed`,
-         `vm_template`.`enable_sshkey` AS `enable_sshkey`,
-         `parent_template`.`id` AS `parent_template_id`,
-         `parent_template`.`uuid` AS `parent_template_uuid`,
-         `source_template`.`id` AS `source_template_id`,
-         `source_template`.`uuid` AS `source_template_uuid`,
-         `account`.`id` AS `account_id`,
-         `account`.`uuid` AS `account_uuid`,
-         `account`.`account_name` AS `account_name`,
-         `account`.`type` AS `account_type`,
-         `domain`.`id` AS `domain_id`,
-         `domain`.`uuid` AS `domain_uuid`,
-         `domain`.`name` AS `domain_name`,
-         `domain`.`path` AS `domain_path`,
-         `projects`.`id` AS `project_id`,
-         `projects`.`uuid` AS `project_uuid`,
-         `projects`.`name` AS `project_name`,
-         `data_center`.`id` AS `data_center_id`,
-         `data_center`.`uuid` AS `data_center_uuid`,
-         `data_center`.`name` AS `data_center_name`,
-         `launch_permission`.`account_id` AS `lp_account_id`,
-         `template_store_ref`.`store_id` AS `store_id`,
-         `image_store`.`scope` AS `store_scope`,
-         `template_store_ref`.`state` AS `state`,
-         `template_store_ref`.`download_state` AS `download_state`,
-         `template_store_ref`.`download_pct` AS `download_pct`,
-         `template_store_ref`.`error_str` AS `error_str`,
-         `template_store_ref`.`size` AS `size`,
-         `template_store_ref`.physical_size AS `physical_size`,
-         `template_store_ref`.`destroyed` AS `destroyed`,
-         `template_store_ref`.`created` AS `created_on_store`,
-         `vm_template_details`.`name` AS `detail_name`,
-         `vm_template_details`.`value` AS `detail_value`,
-         `resource_tags`.`id` AS `tag_id`,
-         `resource_tags`.`uuid` AS `tag_uuid`,
-         `resource_tags`.`key` AS `tag_key`,
-         `resource_tags`.`value` AS `tag_value`,
-         `resource_tags`.`domain_id` AS `tag_domain_id`,
-         `domain`.`uuid` AS `tag_domain_uuid`,
-         `domain`.`name` AS `tag_domain_name`,
-         `resource_tags`.`account_id` AS `tag_account_id`,
-         `account`.`account_name` AS `tag_account_name`,
-         `resource_tags`.`resource_id` AS `tag_resource_id`,
-         `resource_tags`.`resource_uuid` AS `tag_resource_uuid`,
-         `resource_tags`.`resource_type` AS `tag_resource_type`,
-         `resource_tags`.`customer` AS `tag_customer`,
-          CONCAT(`vm_template`.`id`,
-                 '_',
-                 IFNULL(`data_center`.`id`, 0)) AS `temp_zone_pair`,
-          `vm_template`.`direct_download` AS `direct_download`
-     FROM
-         (((((((((((((`vm_template`
-         JOIN `guest_os` ON ((`guest_os`.`id` = `vm_template`.`guest_os_id`)))
-         JOIN `account` ON ((`account`.`id` = `vm_template`.`account_id`)))
-         JOIN `domain` ON ((`domain`.`id` = `account`.`domain_id`)))
-         LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`)))
-         LEFT JOIN `vm_template_details` ON ((`vm_template_details`.`template_id` = `vm_template`.`id`)))
-         LEFT JOIN `vm_template` `source_template` ON ((`source_template`.`id` = `vm_template`.`source_template_id`)))
-         LEFT JOIN `template_store_ref` ON (((`template_store_ref`.`template_id` = `vm_template`.`id`)
-             AND (`template_store_ref`.`store_role` = 'Image')
-             AND (`template_store_ref`.`destroyed` = 0))))
-         LEFT JOIN `vm_template` `parent_template` ON ((`parent_template`.`id` = `vm_template`.`parent_template_id`)))
-         LEFT JOIN `image_store` ON ((ISNULL(`image_store`.`removed`)
-             AND (`template_store_ref`.`store_id` IS NOT NULL)
-             AND (`image_store`.`id` = `template_store_ref`.`store_id`))))
-         LEFT JOIN `template_zone_ref` ON (((`template_zone_ref`.`template_id` = `vm_template`.`id`)
-             AND ISNULL(`template_store_ref`.`store_id`)
-             AND ISNULL(`template_zone_ref`.`removed`))))
-         LEFT JOIN `data_center` ON (((`image_store`.`data_center_id` = `data_center`.`id`)
-             OR (`template_zone_ref`.`zone_id` = `data_center`.`id`))))
-         LEFT JOIN `launch_permission` ON ((`launch_permission`.`template_id` = `vm_template`.`id`)))
-         LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_template`.`id`)
-             AND ((`resource_tags`.`resource_type` = 'Template')
-             OR (`resource_tags`.`resource_type` = 'ISO')))));
-
--- CLOUDSTACK-10109: Enable dedication of public IPs to SSVM and CPVM
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user_ip_address','forsystemvms', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''true if IP is set to system vms, false if not'' ');
-
--- ldap binding on domain level
-CREATE TABLE IF NOT EXISTS `cloud`.`domain_details` (
-    `id` bigint unsigned NOT NULL auto_increment,
-    `domain_id` bigint unsigned NOT NULL COMMENT 'account id',
-    `name` varchar(255) NOT NULL,
-    `value` varchar(255) NULL,
-    PRIMARY KEY (`id`),
-    CONSTRAINT `fk_domain_details__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE
-)ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.ldap_configuration','domain_id', 'BIGINT(20) DEFAULT NULL');
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.ldap_trust_map','account_id', 'BIGINT(20) DEFAULT 0');
-CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.ldap_trust_map','fk_ldap_trust_map__domain_id');
-CALL `cloud`.`IDEMPOTENT_DROP_INDEX`('uk_ldap_trust_map__domain_id','cloud.ldap_trust_map');
-CALL `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX`('uk_ldap_trust_map__bind_location','cloud.ldap_trust_map', '(domain_id, account_id)');
-
-CREATE TABLE IF NOT EXISTS `cloud`.`netscaler_servicepackages` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `uuid` varchar(255) UNIQUE,
-  `name` varchar(255) UNIQUE COMMENT 'name of the service package',
-  `description` varchar(255) COMMENT 'description of the service package',
-  PRIMARY KEY  (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `cloud`.`external_netscaler_controlcenter` (
-  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `uuid` varchar(255) UNIQUE,
-  `username` varchar(255) COMMENT 'username of the NCC',
-  `password` varchar(255) COMMENT 'password of NCC',
-  `ncc_ip` varchar(255) COMMENT 'IP of NCC Manager',
-  `num_retries` bigint unsigned NOT NULL default 2 COMMENT 'Number of retries in ncc for command failure',
-  PRIMARY KEY  (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.sslcerts','name', 'varchar(255) NULL default NULL COMMENT ''Name of the Certificate'' ');
-CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','service_package_id', 'varchar(255) NULL default NULL COMMENT ''Netscaler ControlCenter Service Package'' ');
\ No newline at end of file
diff --git a/engine/schema/resources/META-INF/db/schema-41100to41110-cleanup.sql b/engine/schema/resources/META-INF/db/schema-41100to41110-cleanup.sql
deleted file mode 100644
index 2c5855e..0000000
--- a/engine/schema/resources/META-INF/db/schema-41100to41110-cleanup.sql
+++ /dev/null
@@ -1,22 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---;
--- Schema upgrade from 4.11.0.0 to 4.11.1.0
---;
-
-DELETE FROM `cloud`.`configuration` WHERE `name`='vmware.ports.per.dvportgroup';
diff --git a/engine/schema/resources/META-INF/db/schema-481to490-cleanup.sql b/engine/schema/resources/META-INF/db/schema-481to490-cleanup.sql
deleted file mode 100644
index adf566e..0000000
--- a/engine/schema/resources/META-INF/db/schema-481to490-cleanup.sql
+++ /dev/null
@@ -1,274 +0,0 @@
--- Licensed to the Apache Software Foundation (ASF) under one
--- or more contributor license agreements.  See the NOTICE file
--- distributed with this work for additional information
--- regarding copyright ownership.  The ASF licenses this file
--- to you under the Apache License, Version 2.0 (the
--- "License"); you may not use this file except in compliance
--- with the License.  You may obtain a copy of the License at
---
---   http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing,
--- software distributed under the License is distributed on an
--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
--- KIND, either express or implied.  See the License for the
--- specific language governing permissions and limitations
--- under the License.
-
---;
--- Schema cleanup from 4.8.1 to 4.9.0;
---;
-
--- Added in CLOUDSTACK-9340: General DB optimization, 4 cases:
-
------ 1) Incorrect PRIMARY key
-ALTER TABLE `cloud`.`ovs_tunnel_network` 
-DROP PRIMARY KEY,
-ADD PRIMARY KEY (`id`),
-DROP INDEX `id` ,
-ADD UNIQUE INDEX `i_to_from_network_id` (`to` ASC, `from` ASC, `network_id` ASC);
-
------ 2) Duplicate PRIMARY KEY
-ALTER TABLE `cloud`.`user_vm` DROP INDEX `id_2` ,DROP INDEX `id` ;
-ALTER TABLE `cloud`.`domain_router` DROP INDEX `id_2` ,DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vm_instance` DROP INDEX `id_2` ,DROP INDEX `id` ;
-ALTER TABLE `cloud`.`account_vlan_map` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`account_vnet_map` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`baremetal_rct` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`cluster` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`conditions` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`counter` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`data_center` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`dc_storage_network_ip_range` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`dedicated_resources` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`host_pod_ref` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`iam_group` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`iam_policy` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`iam_policy_permission` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`image_store_details` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`instance_group` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`netapp_lun` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`netapp_pool` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`netapp_volume` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`network_acl_item_cidrs` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`network_offerings` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`nic_secondary_ips` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`nics` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_ha_work` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_host` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_host_transfer` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_networks` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_nwgrp_work` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_vm_ruleset_log` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`op_vpc_distributed_router_sequence_no` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`pod_vlan_map` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`portable_ip_address` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`portable_ip_range` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`region` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`remote_access_vpn` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`snapshot_details` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`snapshots` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`storage_pool` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`storage_pool_details` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`storage_pool_work` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`user_ip_address` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`user_ipv6_address` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`user_statistics` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`version` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vlan` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vm_disk_statistics` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vm_snapshot_details` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vm_work_job` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vpc_gateways` DROP INDEX `id` ;
-ALTER TABLE `cloud`.`vpn_users` DROP INDEX `id` ;
-
--- Dynamic roles changes
-DROP VIEW IF EXISTS `cloud`.`account_view`;
-CREATE VIEW `cloud`.`account_view` AS
-    select
-        account.id,
-        account.uuid,
-        account.account_name,
-        account.type,
-        account.role_id,
-        account.state,
-        account.removed,
-        account.cleanup_needed,
-        account.network_domain,
-        account.default,
-        domain.id domain_id,
-        domain.uuid domain_uuid,
-        domain.name domain_name,
-        domain.path domain_path,
-        data_center.id data_center_id,
-        data_center.uuid data_center_uuid,
-        data_center.name data_center_name,
-        account_netstats_view.bytesReceived,
-        account_netstats_view.bytesSent,
-        vmlimit.max vmLimit,
-        vmcount.count vmTotal,
-        runningvm.vmcount runningVms,
-        stoppedvm.vmcount stoppedVms,
-        iplimit.max ipLimit,
-        ipcount.count ipTotal,
-        free_ip_view.free_ip ipFree,
-        volumelimit.max volumeLimit,
-        volumecount.count volumeTotal,
-        snapshotlimit.max snapshotLimit,
-        snapshotcount.count snapshotTotal,
-        templatelimit.max templateLimit,
-        templatecount.count templateTotal,
-        vpclimit.max vpcLimit,
-        vpccount.count vpcTotal,
-        projectlimit.max projectLimit,
-        projectcount.count projectTotal,
-        networklimit.max networkLimit,
-        networkcount.count networkTotal,
-        cpulimit.max cpuLimit,
-        cpucount.count cpuTotal,
-        memorylimit.max memoryLimit,
-        memorycount.count memoryTotal,
-        primary_storage_limit.max primaryStorageLimit,
-        primary_storage_count.count primaryStorageTotal,
-        secondary_storage_limit.max secondaryStorageLimit,
-        secondary_storage_count.count secondaryStorageTotal,
-        async_job.id job_id,
-        async_job.uuid job_uuid,
-        async_job.job_status job_status,
-        async_job.account_id job_account_id
-    from
-        `cloud`.`free_ip_view`,
-        `cloud`.`account`
-            inner join
-        `cloud`.`domain` ON account.domain_id = domain.id
-            left join
-        `cloud`.`data_center` ON account.default_zone_id = data_center.id
-            left join
-        `cloud`.`account_netstats_view` ON account.id = account_netstats_view.account_id
-            left join
-        `cloud`.`resource_limit` vmlimit ON account.id = vmlimit.account_id
-            and vmlimit.type = 'user_vm'
-            left join
-        `cloud`.`resource_count` vmcount ON account.id = vmcount.account_id
-            and vmcount.type = 'user_vm'
-            left join
-        `cloud`.`account_vmstats_view` runningvm ON account.id = runningvm.account_id
-            and runningvm.state = 'Running'
-            left join
-        `cloud`.`account_vmstats_view` stoppedvm ON account.id = stoppedvm.account_id
-           and stoppedvm.state = 'Stopped'
-            left join
-        `cloud`.`resource_limit` iplimit ON account.id = iplimit.account_id
-            and iplimit.type = 'public_ip'
-            left join
-        `cloud`.`resource_count` ipcount ON account.id = ipcount.account_id
-            and ipcount.type = 'public_ip'
-            left join
-        `cloud`.`resource_limit` volumelimit ON account.id = volumelimit.account_id
-            and volumelimit.type = 'volume'
-            left join
-        `cloud`.`resource_count` volumecount ON account.id = volumecount.account_id
-            and volumecount.type = 'volume'
-            left join
-        `cloud`.`resource_limit` snapshotlimit ON account.id = snapshotlimit.account_id
-            and snapshotlimit.type = 'snapshot'
-            left join
-        `cloud`.`resource_count` snapshotcount ON account.id = snapshotcount.account_id
-            and snapshotcount.type = 'snapshot'
-            left join
-        `cloud`.`resource_limit` templatelimit ON account.id = templatelimit.account_id
-            and templatelimit.type = 'template'
-            left join
-        `cloud`.`resource_count` templatecount ON account.id = templatecount.account_id
-            and templatecount.type = 'template'
-            left join
-        `cloud`.`resource_limit` vpclimit ON account.id = vpclimit.account_id
-            and vpclimit.type = 'vpc'
-            left join
-        `cloud`.`resource_count` vpccount ON account.id = vpccount.account_id
-            and vpccount.type = 'vpc'
-            left join
-        `cloud`.`resource_limit` projectlimit ON account.id = projectlimit.account_id
-            and projectlimit.type = 'project'
-            left join
-        `cloud`.`resource_count` projectcount ON account.id = projectcount.account_id
-            and projectcount.type = 'project'
-            left join
-        `cloud`.`resource_limit` networklimit ON account.id = networklimit.account_id
-            and networklimit.type = 'network'
-            left join
-        `cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
-            and networkcount.type = 'network'
-            left join
-        `cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
-            and cpulimit.type = 'cpu'
-            left join
-        `cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
-            and cpucount.type = 'cpu'
-            left join
-        `cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
-            and memorylimit.type = 'memory'
-            left join
-        `cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
-            and memorycount.type = 'memory'
-            left join
-        `cloud`.`resource_limit` primary_storage_limit ON account.id = primary_storage_limit.account_id
-            and primary_storage_limit.type = 'primary_storage'
-            left join
-        `cloud`.`resource_count` primary_storage_count ON account.id = primary_storage_count.account_id
-            and primary_storage_count.type = 'primary_storage'
-            left join
-        `cloud`.`resource_limit` secondary_storage_limit ON account.id = secondary_storage_limit.account_id
-            and secondary_storage_limit.type = 'secondary_storage'
-            left join
-        `cloud`.`resource_count` secondary_storage_count ON account.id = secondary_storage_count.account_id
-            and secondary_storage_count.type = 'secondary_storage'
-            left join
-        `cloud`.`async_job` ON async_job.instance_id = account.id
-            and async_job.instance_type = 'Account'
-            and async_job.job_status = 0;
-
-DROP VIEW IF EXISTS `cloud`.`user_view`;
-CREATE VIEW `cloud`.`user_view` AS
-    select
-        user.id,
-        user.uuid,
-        user.username,
-        user.password,
-        user.firstname,
-        user.lastname,
-        user.email,
-        user.state,
-        user.api_key,
-        user.secret_key,
-        user.created,
-        user.removed,
-        user.timezone,
-        user.registration_token,
-        user.is_registered,
-        user.incorrect_login_attempts,
-        user.default,
-        account.id account_id,
-        account.uuid account_uuid,
-        account.account_name account_name,
-        account.type account_type,
-        account.role_id account_role_id,
-        domain.id domain_id,
-        domain.uuid domain_uuid,
-        domain.name domain_name,
-        domain.path domain_path,
-        async_job.id job_id,
-        async_job.uuid job_uuid,
-        async_job.job_status job_status,
-        async_job.account_id job_account_id
-    from
-        `cloud`.`user`
-            inner join
-        `cloud`.`account` ON user.account_id = account.id
-            inner join
-        `cloud`.`domain` ON account.domain_id = domain.id
-            left join
-        `cloud`.`async_job` ON async_job.instance_id = user.id
-            and async_job.instance_type = 'User'
-            and async_job.job_status = 0;
-
diff --git a/engine/schema/src/com/cloud/alert/AlertVO.java b/engine/schema/src/com/cloud/alert/AlertVO.java
deleted file mode 100644
index 70ef469..0000000
--- a/engine/schema/src/com/cloud/alert/AlertVO.java
+++ /dev/null
@@ -1,194 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.alert;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "alert")
-public class AlertVO implements Alert {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "type")
-    private short type;
-
-    @Column(name = "cluster_id")
-    private Long clusterId = null;
-
-    @Column(name = "pod_id")
-    private Long podId = null;
-
-    @Column(name = "data_center_id")
-    private long dataCenterId = 0;
-
-    @Column(name = "subject", length = 999)
-    private String subject;
-
-    @Column(name = "sent_count")
-    private int sentCount = 0;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date createdDate;
-
-    @Temporal(TemporalType.TIMESTAMP)
-    @Column(name = "last_sent", updatable = true, nullable = true)
-    private Date lastSent;
-
-    @Temporal(TemporalType.TIMESTAMP)
-    @Column(name = "resolved", updatable = true, nullable = true)
-    private Date resolved;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "archived")
-    private boolean archived;
-
-    @Column(name = "name")
-    private String name;
-
-    public AlertVO() {
-        this.uuid = UUID.randomUUID().toString();
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public short getType() {
-        return type;
-    }
-
-    public void setType(short type) {
-        this.type = type;
-    }
-
-    @Override
-    public String getSubject() {
-        return subject;
-    }
-
-    public void setSubject(String subject) {
-        this.subject = subject;
-    }
-
-    public Long getClusterId() {
-        return clusterId;
-    }
-
-    public void setClusterId(Long clusterId) {
-        this.clusterId = clusterId;
-    }
-
-    @Override
-    public Long getPodId() {
-        return podId;
-    }
-
-    public void setPodId(Long podId) {
-        this.podId = podId;
-    }
-
-    @Override
-    public long getDataCenterId() {
-        return dataCenterId;
-    }
-
-    public void setDataCenterId(long dataCenterId) {
-        this.dataCenterId = dataCenterId;
-    }
-
-    @Override
-    public int getSentCount() {
-        return sentCount;
-    }
-
-    public void setSentCount(int sentCount) {
-        this.sentCount = sentCount;
-    }
-
-    @Override
-    public Date getCreatedDate() {
-        return createdDate;
-    }
-
-    public void setCreatedDate(Date createdDate) {
-        this.createdDate = createdDate;
-    }
-
-    @Override
-    public Date getLastSent() {
-        return lastSent;
-    }
-
-    public void setLastSent(Date lastSent) {
-        this.lastSent = lastSent;
-    }
-
-    @Override
-    public Date getResolved() {
-        return resolved;
-    }
-
-    public void setResolved(Date resolved) {
-        this.resolved = resolved;
-    }
-
-    @Override
-    public String getUuid() {
-        return this.uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public boolean getArchived() {
-        return archived;
-    }
-
-    public void setArchived(Boolean archived) {
-        this.archived = archived;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
diff --git a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDao.java b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDao.java
deleted file mode 100644
index c1ad254..0000000
--- a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDao.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.configuration.dao;
-
-import java.util.List;
-import java.util.Set;
-
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.configuration.ResourceCountVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
-    /**
-     * @param domainId the id of the domain to get the resource count
-     * @param type the type of resource (e.g. user_vm, public_ip, volume)
-     * @return the count of resources in use for the given type and domain
-     */
-    long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type);
-
-    /**
-     * @param domainId the id of the domain to set the resource count
-     * @param type the type of resource (e.g. user_vm, public_ip, volume)
-     * @param the count of resources in use for the given type and domain
-     */
-    void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count);
-
-    @Deprecated
-    void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta);
-
-    boolean updateById(long id, boolean increment, long delta);
-
-    void createResourceCounts(long ownerId, ResourceOwnerType ownerType);
-
-    List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType);
-
-    ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type);
-
-    List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType);
-
-    Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type);
-
-    Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
-
-    long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
-
-    /**
-     * Counts the number of CPU cores allocated for the given account.
-     * Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
-     */
-    long countCpuNumberAllocatedToAccount(long accountId);
-
-    /**
-     * Counts the amount of memory allocated for the given account.
-     * Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
-     */
-    long countMemoryAllocatedToAccount(long accountId);
-}
\ No newline at end of file
diff --git a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java
deleted file mode 100644
index 8290310..0000000
--- a/engine/schema/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java
+++ /dev/null
@@ -1,293 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.configuration.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import com.cloud.domain.DomainVO;
-import com.cloud.user.AccountVO;
-import com.cloud.utils.db.JoinBuilder;
-import org.springframework.stereotype.Component;
-
-import com.cloud.configuration.Resource;
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.configuration.ResourceCountVO;
-import com.cloud.configuration.ResourceLimit;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
-    private final SearchBuilder<ResourceCountVO> TypeSearch;
-
-    private final SearchBuilder<ResourceCountVO> AccountSearch;
-    private final SearchBuilder<ResourceCountVO> DomainSearch;
-
-    @Inject
-    protected DomainDao _domainDao;
-    @Inject
-    protected AccountDao _accountDao;
-
-    public ResourceCountDaoImpl() {
-        TypeSearch = createSearchBuilder();
-        TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeSearch.and("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
-        TypeSearch.done();
-
-        AccountSearch = createSearchBuilder();
-        DomainSearch = createSearchBuilder();
-    }
-
-    @PostConstruct
-    protected void configure() {
-        AccountSearch.and("accountId", AccountSearch.entity().getAccountId(), SearchCriteria.Op.NNULL);
-        SearchBuilder<AccountVO> joinAccount = _accountDao.createSearchBuilder();
-        joinAccount.and("notremoved", joinAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
-        AccountSearch.join("account", joinAccount, AccountSearch.entity().getAccountId(), joinAccount.entity().getId(), JoinBuilder.JoinType.INNER);
-        AccountSearch.done();
-
-        DomainSearch.and("domainId", DomainSearch.entity().getDomainId(), SearchCriteria.Op.NNULL);
-        SearchBuilder<DomainVO> joinDomain = _domainDao.createSearchBuilder();
-        joinDomain.and("notremoved", joinDomain.entity().getRemoved(), SearchCriteria.Op.NULL);
-        DomainSearch.join("domain", joinDomain, DomainSearch.entity().getDomainId(), joinDomain.entity().getId(), JoinBuilder.JoinType.INNER);
-        DomainSearch.done();
-    }
-
-    @Override
-    public ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
-        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
-        sc.setParameters("type", type);
-
-        if (ownerType == ResourceOwnerType.Account) {
-            sc.setParameters("accountId", ownerId);
-            return findOneIncludingRemovedBy(sc);
-        } else if (ownerType == ResourceOwnerType.Domain) {
-            sc.setParameters("domainId", ownerId);
-            return findOneIncludingRemovedBy(sc);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
-        ResourceCountVO vo = findByOwnerAndType(ownerId, ownerType, type);
-        if (vo != null) {
-            return vo.getCount();
-        } else {
-            return 0;
-        }
-    }
-
-    @Override
-    public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count) {
-        ResourceCountVO resourceCountVO = findByOwnerAndType(ownerId, ownerType, type);
-        if (resourceCountVO != null && count != resourceCountVO.getCount()) {
-            resourceCountVO.setCount(count);
-            update(resourceCountVO.getId(), resourceCountVO);
-        }
-    }
-
-    @Override
-    @Deprecated
-    public void updateDomainCount(long domainId, ResourceType type, boolean increment, long delta) {
-        delta = increment ? delta : delta * -1;
-
-        ResourceCountVO resourceCountVO = findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
-        resourceCountVO.setCount(resourceCountVO.getCount() + delta);
-        update(resourceCountVO.getId(), resourceCountVO);
-    }
-
-    @Override
-    public boolean updateById(long id, boolean increment, long delta) {
-        delta = increment ? delta : delta * -1;
-
-        ResourceCountVO resourceCountVO = findById(id);
-        resourceCountVO.setCount(resourceCountVO.getCount() + delta);
-        return update(resourceCountVO.getId(), resourceCountVO);
-    }
-
-    @Override
-    public Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type) {
-        Set<Long> rowIds = new HashSet<Long>();
-        Set<Long> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
-        for (Long domainIdToUpdate : domainIdsToUpdate) {
-            ResourceCountVO domainCountRecord = findByOwnerAndType(domainIdToUpdate, ResourceOwnerType.Domain, type);
-            if (domainCountRecord != null) {
-                rowIds.add(domainCountRecord.getId());
-            }
-        }
-        return rowIds;
-    }
-
-    @Override
-    public Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
-        Set<Long> rowIds = new HashSet<Long>();
-
-        if (ownerType == ResourceOwnerType.Account) {
-            //get records for account
-            ResourceCountVO accountCountRecord = findByOwnerAndType(ownerId, ResourceOwnerType.Account, type);
-            if (accountCountRecord != null) {
-                rowIds.add(accountCountRecord.getId());
-            }
-
-            //get records for account's domain and all its parent domains
-            rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type));
-        } else if (ownerType == ResourceOwnerType.Domain) {
-            return listRowsToUpdateForDomain(ownerId, type);
-        }
-
-        return rowIds;
-    }
-
-    @Override
-    @DB
-    public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType) {
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        ResourceType[] resourceTypes = Resource.ResourceType.values();
-        for (ResourceType resourceType : resourceTypes) {
-            if (!resourceType.supportsOwner(ownerType)) {
-                continue;
-            }
-            ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
-            persist(resourceCountVO);
-        }
-
-        txn.commit();
-    }
-
-    private List<ResourceCountVO> listByDomainId(long domainId) {
-        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
-        sc.setParameters("domainId", domainId);
-
-        return listBy(sc);
-    }
-
-    private List<ResourceCountVO> listByAccountId(long accountId) {
-        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
-        sc.setParameters("accountId", accountId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType) {
-        if (ownerType == ResourceOwnerType.Account) {
-            return listByAccountId(ownerId);
-        } else if (ownerType == ResourceOwnerType.Domain) {
-            return listByDomainId(ownerId);
-        } else {
-            return new ArrayList<ResourceCountVO>();
-        }
-    }
-
-    @Override
-    public List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType) {
-        if (ownerType == ResourceOwnerType.Account) {
-            return listBy(AccountSearch.create());
-        } else if (ownerType == ResourceOwnerType.Domain) {
-            return listBy(DomainSearch.create());
-        } else {
-            return new ArrayList<ResourceCountVO>();
-        }
-    }
-
-    @Override
-    public ResourceCountVO persist(ResourceCountVO resourceCountVO) {
-        ResourceOwnerType ownerType = resourceCountVO.getResourceOwnerType();
-        ResourceType resourceType = resourceCountVO.getType();
-        if (!resourceType.supportsOwner(ownerType)) {
-            throw new UnsupportedServiceException("Resource type " + resourceType + " is not supported for owner of type " + ownerType.getName());
-        }
-
-        return super.persist(resourceCountVO);
-    }
-
-    @Override
-    public long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType) {
-        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
-
-        if (ownerType == ResourceOwnerType.Account) {
-            sc.setParameters("accountId", ownerId);
-            return remove(sc);
-        } else if (ownerType == ResourceOwnerType.Domain) {
-            sc.setParameters("domainId", ownerId);
-            return remove(sc);
-        }
-        return 0;
-    }
-
-    private String baseSqlCountComputingResourceAllocatedToAccount = "Select "
-            + " SUM((CASE "
-            + "        WHEN so.%s is not null THEN so.%s "
-            + "        ELSE CONVERT(vmd.value, UNSIGNED INTEGER) "
-            + "    END)) as total "
-            + " from vm_instance vm "
-            + " join service_offering so on so.id = vm.service_offering_id "
-            + " left join user_vm_details vmd on vmd.vm_id = vm.id and vmd.name = '%s' "
-            + " where vm.type = 'User' and state not in ('Destroyed', 'Error', 'Expunging') and display_vm = true and account_id = ? ";
-
-    @Override
-    public long countCpuNumberAllocatedToAccount(long accountId) {
-        String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, ResourceType.cpu, ResourceType.cpu, "cpuNumber");
-        return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
-    }
-
-    @Override
-    public long countMemoryAllocatedToAccount(long accountId) {
-        String serviceOfferingRamSizeField = "ram_size";
-        String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, serviceOfferingRamSizeField, serviceOfferingRamSizeField, "memory");
-        return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
-    }
-
-    private long executeSqlCountComputingResourcesForAccount(long accountId, String sqlCountComputingResourcesAllocatedToAccount) {
-        TransactionLegacy tx = TransactionLegacy.currentTxn();
-        try {
-            PreparedStatement pstmt = tx.prepareAutoCloseStatement(sqlCountComputingResourcesAllocatedToAccount);
-            pstmt.setLong(1, accountId);
-
-            ResultSet rs = pstmt.executeQuery();
-            if (!rs.next()) {
-                return 0L;
-            }
-            return rs.getLong("total");
-        } catch (SQLException e) {
-            throw new CloudRuntimeException(e);
-        }
-    }
-}
diff --git a/engine/schema/src/com/cloud/dc/VlanVO.java b/engine/schema/src/com/cloud/dc/VlanVO.java
deleted file mode 100644
index 50106e0..0000000
--- a/engine/schema/src/com/cloud/dc/VlanVO.java
+++ /dev/null
@@ -1,239 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dc;
-
-import com.cloud.utils.db.GenericDao;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "vlan")
-public class VlanVO implements Vlan {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    Long id;
-
-    @Column(name = "vlan_id")
-    String vlanTag;
-
-    @Column(name = "vlan_gateway")
-    String vlanGateway;
-
-    @Column(name = "vlan_netmask")
-    String vlanNetmask;
-
-    @Column(name = "ip6_gateway")
-    String ip6Gateway;
-
-    @Column(name = "ip6_cidr")
-    String ip6Cidr;
-
-    @Column(name = "data_center_id")
-    long dataCenterId;
-
-    @Column(name = "description")
-    String ipRange;
-
-    @Column(name = "ip6_range")
-    String ip6Range;
-
-    @Column(name = "network_id")
-    Long networkId;
-
-    @Column(name = "physical_network_id")
-    Long physicalNetworkId;
-
-    @Column(name = "vlan_type")
-    @Enumerated(EnumType.STRING)
-    VlanType vlanType;
-
-    @Column(name = "uuid")
-    String uuid;
-
-    @Column(name= GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-
-    public VlanVO(VlanType vlanType, String vlanTag, String vlanGateway, String vlanNetmask, long dataCenterId, String ipRange, Long networkId, Long physicalNetworkId,
-            String ip6Gateway, String ip6Cidr, String ip6Range) {
-        this.vlanType = vlanType;
-        this.vlanTag = vlanTag;
-        this.vlanGateway = vlanGateway;
-        this.vlanNetmask = vlanNetmask;
-        this.ip6Gateway = ip6Gateway;
-        this.ip6Cidr = ip6Cidr;
-        this.dataCenterId = dataCenterId;
-        this.ipRange = ipRange;
-        this.ip6Range = ip6Range;
-        this.networkId = networkId;
-        this.uuid = UUID.randomUUID().toString();
-        this.physicalNetworkId = physicalNetworkId;
-    }
-
-    public VlanVO() {
-        this.uuid = UUID.randomUUID().toString();
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getVlanTag() {
-        return vlanTag;
-    }
-
-    @Override
-    public String getVlanGateway() {
-        return vlanGateway;
-    }
-
-    @Override
-    public String getVlanNetmask() {
-        return vlanNetmask;
-    }
-
-    @Override
-    public long getDataCenterId() {
-        return dataCenterId;
-    }
-
-    public void setDataCenterId(long dcId) {
-        this.dataCenterId = dcId;
-    }
-
-    @Override
-    public String getIpRange() {
-        return ipRange;
-    }
-
-    @Override
-    public VlanType getVlanType() {
-        return vlanType;
-    }
-
-    @Override
-    public Long getNetworkId() {
-        return networkId;
-    }
-
-    public void setNetworkId(Long networkId) {
-        this.networkId = networkId;
-    }
-
-    @Override
-    public String getUuid() {
-        return this.uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public Date getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public Date getCreated() {
-        return created;
-    }
-
-    @Override
-    public Long getPhysicalNetworkId() {
-        return physicalNetworkId;
-    }
-
-    public void setPhysicalNetworkId(Long physicalNetworkId) {
-        this.physicalNetworkId = physicalNetworkId;
-    }
-
-    transient String toString;
-
-    @Override
-    public String toString() {
-        if (toString == null) {
-            toString =
-                new StringBuilder("Vlan[").append(vlanTag)
-                    .append("|")
-                    .append(vlanGateway)
-                    .append("|")
-                    .append(vlanNetmask)
-                    .append("|")
-                    .append(ip6Gateway)
-                    .append("|")
-                    .append(ip6Cidr)
-                    .append("|")
-                    .append(ipRange)
-                    .append("|")
-                    .append("|")
-                    .append(ip6Range)
-                    .append(networkId)
-                    .append("]")
-                    .toString();
-        }
-        return toString;
-    }
-
-    @Override
-    public String getIp6Gateway() {
-        return ip6Gateway;
-    }
-
-    public void setIp6Gateway(String ip6Gateway) {
-        this.ip6Gateway = ip6Gateway;
-    }
-
-    @Override
-    public String getIp6Cidr() {
-        return ip6Cidr;
-    }
-
-    public void setIp6Cidr(String ip6Cidr) {
-        this.ip6Cidr = ip6Cidr;
-    }
-
-    @Override
-    public String getIp6Range() {
-        return ip6Range;
-    }
-
-    public void setIp6Range(String ip6Range) {
-        this.ip6Range = ip6Range;
-    }
-
-    public void setIpRange(String ipRange) {
-        this.ip6Range = ipRange;
-    }
-}
diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/com/cloud/dc/dao/VlanDao.java
deleted file mode 100644
index e92a5cc..0000000
--- a/engine/schema/src/com/cloud/dc/dao/VlanDao.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dc.dao;
-
-import java.util.List;
-
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface VlanDao extends GenericDao<VlanVO, Long> {
-
-    VlanVO findByZoneAndVlanId(long zoneId, String vlanId);
-
-    List<VlanVO> listByZone(long zoneId);
-
-    List<VlanVO> listByType(Vlan.VlanType vlanType);
-
-    List<VlanVO> listByZoneAndType(long zoneId, Vlan.VlanType vlanType);
-
-    List<VlanVO> listVlansForPod(long podId);
-
-    List<VlanVO> listVlansForPodByType(long podId, Vlan.VlanType vlanType);
-
-    void addToPod(long podId, long vlanDbId);
-
-    List<VlanVO> listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType);
-
-    boolean zoneHasDirectAttachUntaggedVlans(long zoneId);
-
-    List<VlanVO> listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId);
-
-    List<VlanVO> searchForZoneWideVlans(long dcId, String vlanType, String vlanId);
-
-    List<VlanVO> listVlansByNetworkId(long networkId);
-
-    List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId);
-
-    List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId);
-
-    List<VlanVO> listZoneWideNonDedicatedVlans(long zoneId);
-
-    List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway);
-
-    List<VlanVO> listDedicatedVlans(long accountId);
-}
diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java
deleted file mode 100644
index 0c59148..0000000
--- a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java
+++ /dev/null
@@ -1,374 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dc.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.springframework.stereotype.Component;
-
-import com.cloud.dc.AccountVlanMapVO;
-import com.cloud.dc.DomainVlanMapVO;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao {
-
-    private final String FindZoneWideVlans =
-        "SELECT * FROM vlan WHERE data_center_id=? and vlan_type=? and vlan_id!=? and id not in (select vlan_db_id from account_vlan_map)";
-
-    protected SearchBuilder<VlanVO> ZoneVlanIdSearch;
-    protected SearchBuilder<VlanVO> ZoneSearch;
-    protected SearchBuilder<VlanVO> ZoneTypeSearch;
-    protected SearchBuilder<VlanVO> ZoneTypeAllPodsSearch;
-    protected SearchBuilder<VlanVO> ZoneTypePodSearch;
-    protected SearchBuilder<VlanVO> ZoneVlanSearch;
-    protected SearchBuilder<VlanVO> NetworkVlanSearch;
-    protected SearchBuilder<VlanVO> PhysicalNetworkVlanSearch;
-    protected SearchBuilder<VlanVO> ZoneWideNonDedicatedVlanSearch;
-    protected SearchBuilder<VlanVO> VlanGatewaysearch;
-    protected SearchBuilder<VlanVO> DedicatedVlanSearch;
-
-    protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch;
-    protected SearchBuilder<DomainVlanMapVO> DomainVlanMapSearch;
-
-    @Inject
-    protected PodVlanMapDao _podVlanMapDao;
-    @Inject
-    protected AccountVlanMapDao _accountVlanMapDao;
-    @Inject
-    protected DomainVlanMapDao _domainVlanMapDao;
-    @Inject
-    protected IPAddressDao _ipAddressDao;
-
-    @Override
-    public VlanVO findByZoneAndVlanId(long zoneId, String vlanId) {
-        SearchCriteria<VlanVO> sc = ZoneVlanIdSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("vlanId", vlanId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listByZone(long zoneId) {
-        SearchCriteria<VlanVO> sc = ZoneSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        return listBy(sc);
-    }
-
-    public VlanDaoImpl() {
-        ZoneVlanIdSearch = createSearchBuilder();
-        ZoneVlanIdSearch.and("zoneId", ZoneVlanIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        ZoneVlanIdSearch.and("vlanId", ZoneVlanIdSearch.entity().getVlanTag(), SearchCriteria.Op.EQ);
-        ZoneVlanIdSearch.done();
-
-        ZoneSearch = createSearchBuilder();
-        ZoneSearch.and("zoneId", ZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        ZoneSearch.done();
-
-        ZoneTypeSearch = createSearchBuilder();
-        ZoneTypeSearch.and("zoneId", ZoneTypeSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        ZoneTypeSearch.and("vlanType", ZoneTypeSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
-        ZoneTypeSearch.done();
-
-        NetworkVlanSearch = createSearchBuilder();
-        NetworkVlanSearch.and("networkId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        NetworkVlanSearch.done();
-
-        PhysicalNetworkVlanSearch = createSearchBuilder();
-        PhysicalNetworkVlanSearch.and("physicalNetworkId", PhysicalNetworkVlanSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
-        PhysicalNetworkVlanSearch.done();
-
-        VlanGatewaysearch = createSearchBuilder();
-        VlanGatewaysearch.and("gateway", VlanGatewaysearch.entity().getVlanGateway(), SearchCriteria.Op.EQ);
-        VlanGatewaysearch.and("networkid", VlanGatewaysearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        VlanGatewaysearch.done();
-    }
-
-    @Override
-    public List<VlanVO> listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId) {
-        SearchCriteria<VlanVO> sc = ZoneVlanSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("vlanId", vlanId);
-        sc.setParameters("vlanType", vlanType);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listByZoneAndType(long zoneId, VlanType vlanType) {
-        SearchCriteria<VlanVO> sc = ZoneTypeSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("vlanType", vlanType);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listByType(VlanType vlanType) {
-        SearchCriteria<VlanVO> sc = ZoneTypeSearch.create();
-        sc.setParameters("vlanType", vlanType);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listVlansForPod(long podId) {
-        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two
-        List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId);
-        List<VlanVO> result = new ArrayList<VlanVO>();
-        for (PodVlanMapVO pvmvo : vlanMaps) {
-            result.add(findById(pvmvo.getVlanDbId()));
-        }
-        return result;
-    }
-
-    @Override
-    public List<VlanVO> listVlansForPodByType(long podId, VlanType vlanType) {
-        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two)
-        List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId);
-        List<VlanVO> result = new ArrayList<VlanVO>();
-        for (PodVlanMapVO pvmvo : vlanMaps) {
-            VlanVO vlan = findById(pvmvo.getVlanDbId());
-            if (vlan.getVlanType() == vlanType) {
-                result.add(vlan);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public List<VlanVO> listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType) {
-        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two)
-        List<AccountVlanMapVO> vlanMaps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId);
-        List<VlanVO> result = new ArrayList<VlanVO>();
-        for (AccountVlanMapVO acvmvo : vlanMaps) {
-            VlanVO vlan = findById(acvmvo.getVlanDbId());
-            if (vlan.getVlanType() == vlanType && (zoneId == null || vlan.getDataCenterId() == zoneId)) {
-                result.add(vlan);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public void addToPod(long podId, long vlanDbId) {
-        PodVlanMapVO pvmvo = new PodVlanMapVO(podId, vlanDbId);
-        _podVlanMapDao.persist(pvmvo);
-
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        boolean result = super.configure(name, params);
-        ZoneTypeAllPodsSearch = createSearchBuilder();
-        ZoneTypeAllPodsSearch.and("zoneId", ZoneTypeAllPodsSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        ZoneTypeAllPodsSearch.and("vlanType", ZoneTypeAllPodsSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
-
-        SearchBuilder<PodVlanMapVO> PodVlanSearch = _podVlanMapDao.createSearchBuilder();
-        PodVlanSearch.and("podId", PodVlanSearch.entity().getPodId(), SearchCriteria.Op.NNULL);
-        ZoneTypeAllPodsSearch.join("vlan", PodVlanSearch, PodVlanSearch.entity().getVlanDbId(), ZoneTypeAllPodsSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-
-        ZoneTypeAllPodsSearch.done();
-        PodVlanSearch.done();
-
-        ZoneTypePodSearch = createSearchBuilder();
-        ZoneTypePodSearch.and("zoneId", ZoneTypePodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        ZoneTypePodSearch.and("vlanType", ZoneTypePodSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
-
-        SearchBuilder<PodVlanMapVO> PodVlanSearch2 = _podVlanMapDao.createSearchBuilder();
-        PodVlanSearch2.and("podId", PodVlanSearch2.entity().getPodId(), SearchCriteria.Op.EQ);
-        ZoneTypePodSearch.join("vlan", PodVlanSearch2, PodVlanSearch2.entity().getVlanDbId(), ZoneTypePodSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        PodVlanSearch2.done();
-        ZoneTypePodSearch.done();
-
-        ZoneWideNonDedicatedVlanSearch = createSearchBuilder();
-        ZoneWideNonDedicatedVlanSearch.and("zoneId", ZoneWideNonDedicatedVlanSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
-        AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
-        ZoneWideNonDedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, ZoneWideNonDedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity()
-            .getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER);
-        DomainVlanMapSearch = _domainVlanMapDao.createSearchBuilder();
-        DomainVlanMapSearch.and("domainId", DomainVlanMapSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
-        ZoneWideNonDedicatedVlanSearch.join("DomainVlanMapSearch", DomainVlanMapSearch, ZoneWideNonDedicatedVlanSearch.entity().getId(), DomainVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER);
-        ZoneWideNonDedicatedVlanSearch.done();
-        AccountVlanMapSearch.done();
-        DomainVlanMapSearch.done();
-
-        DedicatedVlanSearch = createSearchBuilder();
-        AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
-        AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        DedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, DedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity().getVlanDbId(),
-            JoinBuilder.JoinType.LEFTOUTER);
-        DedicatedVlanSearch.done();
-        AccountVlanMapSearch.done();
-
-        return result;
-    }
-
-    private VlanVO findNextVlan(long zoneId, Vlan.VlanType vlanType) {
-        List<VlanVO> allVlans = listByZoneAndType(zoneId, vlanType);
-        List<VlanVO> emptyVlans = new ArrayList<VlanVO>();
-        List<VlanVO> fullVlans = new ArrayList<VlanVO>();
-
-        // Try to find a VLAN that is partially allocated
-        for (VlanVO vlan : allVlans) {
-            long vlanDbId = vlan.getId();
-
-            int countOfAllocatedIps = _ipAddressDao.countIPs(zoneId, vlanDbId, true);
-            int countOfAllIps = _ipAddressDao.countIPs(zoneId, vlanDbId, false);
-
-            if ((countOfAllocatedIps > 0) && (countOfAllocatedIps < countOfAllIps)) {
-                return vlan;
-            } else if (countOfAllocatedIps == 0) {
-                emptyVlans.add(vlan);
-            } else if (countOfAllocatedIps == countOfAllIps) {
-                fullVlans.add(vlan);
-            }
-        }
-
-        if (emptyVlans.isEmpty()) {
-            return null;
-        }
-
-        // Try to find an empty VLAN with the same tag/subnet as a VLAN that is full
-        for (VlanVO fullVlan : fullVlans) {
-            for (VlanVO emptyVlan : emptyVlans) {
-                if (fullVlan.getVlanTag().equals(emptyVlan.getVlanTag()) && fullVlan.getVlanGateway().equals(emptyVlan.getVlanGateway()) &&
-                    fullVlan.getVlanNetmask().equals(emptyVlan.getVlanNetmask())) {
-                    return emptyVlan;
-                }
-            }
-        }
-
-        // Return a random empty VLAN
-        return emptyVlans.get(0);
-    }
-
-    @Override
-    public boolean zoneHasDirectAttachUntaggedVlans(long zoneId) {
-        SearchCriteria<VlanVO> sc = ZoneTypeAllPodsSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("vlanType", VlanType.DirectAttached);
-
-        return listIncludingRemovedBy(sc).size() > 0;
-    }
-
-    public Pair<String, VlanVO> assignPodDirectAttachIpAddress(long zoneId, long podId, long accountId, long domainId) {
-        SearchCriteria<VlanVO> sc = ZoneTypePodSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("vlanType", VlanType.DirectAttached);
-        sc.setJoinParameters("vlan", "podId", podId);
-
-        VlanVO vlan = findOneIncludingRemovedBy(sc);
-        if (vlan == null) {
-            return null;
-        }
-
-        return null;
-//        String ipAddress = _ipAddressDao.assignIpAddress(accountId, domainId, vlan.getId(), false).getAddress();
-//        if (ipAddress == null) {
-//            return null;
-//        }
-//        return new Pair<String, VlanVO>(ipAddress, vlan);
-
-    }
-
-    @Override
-    @DB
-    public List<VlanVO> searchForZoneWideVlans(long dcId, String vlanType, String vlanId) {
-        StringBuilder sql = new StringBuilder(FindZoneWideVlans);
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        List<VlanVO> zoneWideVlans = new ArrayList<VlanVO>();
-        try(PreparedStatement pstmt = txn.prepareStatement(sql.toString());){
-            if(pstmt != null) {
-                pstmt.setLong(1, dcId);
-                pstmt.setString(2, vlanType);
-                pstmt.setString(3, vlanId);
-                try(ResultSet rs = pstmt.executeQuery();) {
-                    while (rs.next()) {
-                        zoneWideVlans.add(toEntityBean(rs, false));
-                    }
-                }catch (SQLException e) {
-                    throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e);
-                }
-            }
-            return zoneWideVlans;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public List<VlanVO> listVlansByNetworkId(long networkId) {
-        SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
-        sc.setParameters("networkId", networkId);
-        return listBy(sc);
-    }
-
-    @Override public List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId) {
-        SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
-        sc.setParameters("networkId", networkId);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway) {
-        SearchCriteria<VlanVO> sc = VlanGatewaysearch.create();
-        sc.setParameters("networkid", networkid);
-        sc.setParameters("gateway", gateway);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId) {
-        SearchCriteria<VlanVO> sc = PhysicalNetworkVlanSearch.create();
-        sc.setParameters("physicalNetworkId", physicalNetworkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listZoneWideNonDedicatedVlans(long zoneId) {
-        SearchCriteria<VlanVO> sc = ZoneWideNonDedicatedVlanSearch.create();
-        sc.setParameters("zoneId", zoneId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VlanVO> listDedicatedVlans(long accountId) {
-        SearchCriteria<VlanVO> sc = DedicatedVlanSearch.create();
-        sc.setJoinParameters("AccountVlanMapSearch", "accountId", accountId);
-        return listBy(sc);
-    }
-
-}
diff --git a/engine/schema/src/com/cloud/host/dao/HostDao.java b/engine/schema/src/com/cloud/host/dao/HostDao.java
deleted file mode 100644
index 71c9cd2..0000000
--- a/engine/schema/src/com/cloud/host/dao/HostDao.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.host.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.resource.ResourceState;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.fsm.StateDao;
-
-/**
- * Data Access Object for server
- *
- */
-public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Status.Event, Host> {
-    long countBy(long clusterId, ResourceState... states);
-
-    /**
-     * Mark all hosts associated with a certain management server
-     * as disconnected.
-     *
-     * @param msId management server id.
-     */
-    void markHostsAsDisconnected(long msId, long lastPing);
-
-    List<HostVO> findLostHosts(long timeout);
-
-    List<HostVO> findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId);
-
-    List<RunningHostCountInfo> getRunningHostCounts(Date cutTime);
-
-    long getNextSequence(long hostId);
-
-    void loadDetails(HostVO host);
-
-    void saveDetails(HostVO host);
-
-    void loadHostTags(HostVO host);
-
-    List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag);
-
-    long countRoutingHostsByDataCenter(long dcId);
-
-    List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
-
-    boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo);
-
-    HostVO findByGuid(String guid);
-
-    HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type);
-
-    List<HostVO> findHypervisorHostInCluster(long clusterId);
-
-    List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag);
-
-    List<HostVO> findByDataCenterId(Long zoneId);
-
-    List<HostVO> findByPodId(Long podId);
-
-    List<HostVO> findByClusterId(Long clusterId);
-
-    List<HostVO> listByDataCenterId(long id);
-
-    List<HostVO> listByDataCenterIdAndHypervisorType(long zoneId, Hypervisor.HypervisorType hypervisorType);
-
-    List<Long> listAllHosts(long zoneId);
-
-    List<HostVO> listAllHostsByType(Host.Type type);
-
-    HostVO findByPublicIp(String publicIp);
-
-    List<Long> listClustersByHostTag(String hostTagOnOffering);
-
-    List<HostVO> listByType(Type type);
-
-    HostVO findByIp(String ip);
-
-    /**
-     * This method will look for a host that is of the same hypervisor and zone as indicated in its parameters.
-     * <ul>
-     * <li>We give priority to 'Enabled' hosts, but if no 'Enabled' hosts are found, we use 'Disabled' hosts
-     * <li>If no host is found, we throw a runtime exception
-     * </ul>
-     *
-     * Side note: this method is currently only used in XenServerGuru; therefore, it was designed to meet XenServer deployment scenarios requirements.
-     */
-    HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType);
-}
diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
deleted file mode 100644
index e48bfd5..0000000
--- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
+++ /dev/null
@@ -1,1209 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.host.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.TimeZone;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.persistence.TableGenerator;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.api.VgpuTypesInfo;
-import com.cloud.cluster.agentlb.HostTransferMapVO;
-import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
-import com.cloud.configuration.ManagementServiceConfiguration;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.gpu.dao.HostGpuGroupsDao;
-import com.cloud.gpu.dao.VGPUTypesDao;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostTagVO;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Status.Event;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.org.Grouping;
-import com.cloud.org.Managed;
-import com.cloud.resource.ResourceState;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.db.Attribute;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UpdateBuilder;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-@DB
-@TableGenerator(name = "host_req_sq", table = "op_host", pkColumnName = "id", valueColumnName = "sequence", allocationSize = 1)
-public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao { //FIXME: , ExternalIdDao {
-    private static final Logger s_logger = Logger.getLogger(HostDaoImpl.class);
-    private static final Logger status_logger = Logger.getLogger(Status.class);
-    private static final Logger state_logger = Logger.getLogger(ResourceState.class);
-
-    private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join host_tags on host.id = host_tags.host_id and host_tags.tag = ?";
-
-
-    protected SearchBuilder<HostVO> TypePodDcStatusSearch;
-
-    protected SearchBuilder<HostVO> IdStatusSearch;
-    protected SearchBuilder<HostVO> TypeDcSearch;
-    protected SearchBuilder<HostVO> TypeDcStatusSearch;
-    protected SearchBuilder<HostVO> TypeClusterStatusSearch;
-    protected SearchBuilder<HostVO> MsStatusSearch;
-    protected SearchBuilder<HostVO> DcPrivateIpAddressSearch;
-    protected SearchBuilder<HostVO> DcStorageIpAddressSearch;
-    protected SearchBuilder<HostVO> PublicIpAddressSearch;
-    protected SearchBuilder<HostVO> AnyIpAddressSearch;
-
-    protected SearchBuilder<HostVO> GuidSearch;
-    protected SearchBuilder<HostVO> DcSearch;
-    protected SearchBuilder<HostVO> PodSearch;
-    protected SearchBuilder<HostVO> ClusterSearch;
-    protected SearchBuilder<HostVO> TypeSearch;
-    protected SearchBuilder<HostVO> StatusSearch;
-    protected SearchBuilder<HostVO> ResourceStateSearch;
-    protected SearchBuilder<HostVO> NameLikeSearch;
-    protected SearchBuilder<HostVO> NameSearch;
-    protected SearchBuilder<HostVO> SequenceSearch;
-    protected SearchBuilder<HostVO> DirectlyConnectedSearch;
-    protected SearchBuilder<HostVO> UnmanagedDirectConnectSearch;
-    protected SearchBuilder<HostVO> UnmanagedApplianceSearch;
-    protected SearchBuilder<HostVO> MaintenanceCountSearch;
-    protected SearchBuilder<HostVO> ClusterStatusSearch;
-    protected SearchBuilder<HostVO> TypeNameZoneSearch;
-    protected SearchBuilder<HostVO> AvailHypevisorInZone;
-
-    protected SearchBuilder<HostVO> DirectConnectSearch;
-    protected SearchBuilder<HostVO> ManagedDirectConnectSearch;
-    protected SearchBuilder<HostVO> ManagedRoutingServersSearch;
-    protected SearchBuilder<HostVO> SecondaryStorageVMSearch;
-
-    protected GenericSearchBuilder<HostVO, Long> HostIdSearch;
-    protected GenericSearchBuilder<HostVO, Long> HostsInStatusSearch;
-    protected GenericSearchBuilder<HostVO, Long> CountRoutingByDc;
-    protected SearchBuilder<HostTransferMapVO> HostTransferSearch;
-    protected SearchBuilder<ClusterVO> ClusterManagedSearch;
-    protected SearchBuilder<HostVO> RoutingSearch;
-
-    protected SearchBuilder<HostVO> HostsForReconnectSearch;
-    protected GenericSearchBuilder<HostVO, Long> ClustersOwnedByMSSearch;
-    protected GenericSearchBuilder<HostVO, Long> ClustersForHostsNotOwnedByAnyMSSearch;
-    protected GenericSearchBuilder<ClusterVO, Long> AllClustersSearch;
-    protected SearchBuilder<HostVO> HostsInClusterSearch;
-
-    protected Attribute _statusAttr;
-    protected Attribute _resourceStateAttr;
-    protected Attribute _msIdAttr;
-    protected Attribute _pingTimeAttr;
-
-    @Inject
-    protected HostDetailsDao _detailsDao;
-    @Inject
-    protected HostGpuGroupsDao _hostGpuGroupsDao;
-    @Inject
-    protected VGPUTypesDao _vgpuTypesDao;
-    @Inject
-    protected HostTagsDao _hostTagsDao;
-    @Inject
-    protected HostTransferMapDao _hostTransferDao;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    ManagementServiceConfiguration mgmtServiceConf;
-
-    public HostDaoImpl() {
-        super();
-    }
-
-    @PostConstruct
-    public void init() {
-
-        MaintenanceCountSearch = createSearchBuilder();
-        MaintenanceCountSearch.and("cluster", MaintenanceCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        MaintenanceCountSearch.and("resourceState", MaintenanceCountSearch.entity().getResourceState(), SearchCriteria.Op.IN);
-        MaintenanceCountSearch.done();
-
-        TypePodDcStatusSearch = createSearchBuilder();
-        HostVO entity = TypePodDcStatusSearch.entity();
-        TypePodDcStatusSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
-        TypePodDcStatusSearch.done();
-
-        MsStatusSearch = createSearchBuilder();
-        MsStatusSearch.and("ms", MsStatusSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-        MsStatusSearch.and("type", MsStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
-        MsStatusSearch.and("resourceState", MsStatusSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
-        MsStatusSearch.done();
-
-        TypeDcSearch = createSearchBuilder();
-        TypeDcSearch.and("type", TypeDcSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeDcSearch.and("dc", TypeDcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        TypeDcSearch.done();
-
-        SecondaryStorageVMSearch = createSearchBuilder();
-        SecondaryStorageVMSearch.and("type", SecondaryStorageVMSearch.entity().getType(), SearchCriteria.Op.EQ);
-        SecondaryStorageVMSearch.and("dc", SecondaryStorageVMSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        SecondaryStorageVMSearch.and("status", SecondaryStorageVMSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        SecondaryStorageVMSearch.done();
-
-        TypeDcStatusSearch = createSearchBuilder();
-        TypeDcStatusSearch.and("type", TypeDcStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeDcStatusSearch.and("dc", TypeDcStatusSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        TypeDcStatusSearch.and("status", TypeDcStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        TypeDcStatusSearch.and("resourceState", TypeDcStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
-        TypeDcStatusSearch.done();
-
-        TypeClusterStatusSearch = createSearchBuilder();
-        TypeClusterStatusSearch.and("type", TypeClusterStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeClusterStatusSearch.and("cluster", TypeClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        TypeClusterStatusSearch.and("status", TypeClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        TypeClusterStatusSearch.and("resourceState", TypeClusterStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
-        TypeClusterStatusSearch.done();
-
-        IdStatusSearch = createSearchBuilder();
-        IdStatusSearch.and("id", IdStatusSearch.entity().getId(), SearchCriteria.Op.EQ);
-        IdStatusSearch.and("states", IdStatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
-        IdStatusSearch.done();
-
-        DcPrivateIpAddressSearch = createSearchBuilder();
-        DcPrivateIpAddressSearch.and("privateIpAddress", DcPrivateIpAddressSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ);
-        DcPrivateIpAddressSearch.and("dc", DcPrivateIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcPrivateIpAddressSearch.done();
-
-        DcStorageIpAddressSearch = createSearchBuilder();
-        DcStorageIpAddressSearch.and("storageIpAddress", DcStorageIpAddressSearch.entity().getStorageIpAddress(), SearchCriteria.Op.EQ);
-        DcStorageIpAddressSearch.and("dc", DcStorageIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcStorageIpAddressSearch.done();
-
-        PublicIpAddressSearch = createSearchBuilder();
-        PublicIpAddressSearch.and("publicIpAddress", PublicIpAddressSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ);
-        PublicIpAddressSearch.done();
-
-        AnyIpAddressSearch = createSearchBuilder();
-        AnyIpAddressSearch.or("publicIpAddress", AnyIpAddressSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ);
-        AnyIpAddressSearch.or("privateIpAddress", AnyIpAddressSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ);
-        AnyIpAddressSearch.done();
-
-        GuidSearch = createSearchBuilder();
-        GuidSearch.and("guid", GuidSearch.entity().getGuid(), SearchCriteria.Op.EQ);
-        GuidSearch.done();
-
-        DcSearch = createSearchBuilder();
-        DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcSearch.and("type", DcSearch.entity().getType(), Op.EQ);
-        DcSearch.and("status", DcSearch.entity().getStatus(), Op.EQ);
-        DcSearch.and("resourceState", DcSearch.entity().getResourceState(), Op.EQ);
-        DcSearch.done();
-
-        ClusterStatusSearch = createSearchBuilder();
-        ClusterStatusSearch.and("cluster", ClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        ClusterStatusSearch.and("status", ClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        ClusterStatusSearch.done();
-
-        TypeNameZoneSearch = createSearchBuilder();
-        TypeNameZoneSearch.and("name", TypeNameZoneSearch.entity().getName(), SearchCriteria.Op.EQ);
-        TypeNameZoneSearch.and("type", TypeNameZoneSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeNameZoneSearch.and("zoneId", TypeNameZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        TypeNameZoneSearch.done();
-
-        PodSearch = createSearchBuilder();
-        PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
-        PodSearch.done();
-
-        ClusterSearch = createSearchBuilder();
-        ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        ClusterSearch.done();
-
-        TypeSearch = createSearchBuilder();
-        TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
-        TypeSearch.done();
-
-        StatusSearch = createSearchBuilder();
-        StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
-        StatusSearch.done();
-
-        ResourceStateSearch = createSearchBuilder();
-        ResourceStateSearch.and("resourceState", ResourceStateSearch.entity().getResourceState(), SearchCriteria.Op.IN);
-        ResourceStateSearch.done();
-
-        NameLikeSearch = createSearchBuilder();
-        NameLikeSearch.and("name", NameLikeSearch.entity().getName(), SearchCriteria.Op.LIKE);
-        NameLikeSearch.done();
-
-        NameSearch = createSearchBuilder();
-        NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
-        NameSearch.done();
-
-        SequenceSearch = createSearchBuilder();
-        SequenceSearch.and("id", SequenceSearch.entity().getId(), SearchCriteria.Op.EQ);
-        // SequenceSearch.addRetrieve("sequence", SequenceSearch.entity().getSequence());
-        SequenceSearch.done();
-
-        DirectlyConnectedSearch = createSearchBuilder();
-        DirectlyConnectedSearch.and("resource", DirectlyConnectedSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        DirectlyConnectedSearch.and("ms", DirectlyConnectedSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-        DirectlyConnectedSearch.and("statuses", DirectlyConnectedSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        DirectlyConnectedSearch.and("resourceState", DirectlyConnectedSearch.entity().getResourceState(), SearchCriteria.Op.NOTIN);
-        DirectlyConnectedSearch.done();
-
-        UnmanagedDirectConnectSearch = createSearchBuilder();
-        UnmanagedDirectConnectSearch.and("resource", UnmanagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        UnmanagedDirectConnectSearch.and("server", UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-        UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
-        UnmanagedDirectConnectSearch.and("resourceStates", UnmanagedDirectConnectSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
-        UnmanagedDirectConnectSearch.and("clusterIn", UnmanagedDirectConnectSearch.entity().getClusterId(), SearchCriteria.Op.IN);
-        /*
-         * UnmanagedDirectConnectSearch.op(SearchCriteria.Op.OR, "managementServerId",
-         * UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-         * UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(),
-         * SearchCriteria.Op.LTEQ); UnmanagedDirectConnectSearch.cp(); UnmanagedDirectConnectSearch.cp();
-         */
-        try {
-            HostTransferSearch = _hostTransferDao.createSearchBuilder();
-        } catch (Throwable e) {
-            s_logger.debug("error", e);
-        }
-        HostTransferSearch.and("id", HostTransferSearch.entity().getId(), SearchCriteria.Op.NULL);
-        UnmanagedDirectConnectSearch.join("hostTransferSearch", HostTransferSearch, HostTransferSearch.entity().getId(), UnmanagedDirectConnectSearch.entity().getId(),
-                JoinType.LEFTOUTER);
-        ClusterManagedSearch = _clusterDao.createSearchBuilder();
-        ClusterManagedSearch.and("managed", ClusterManagedSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
-        UnmanagedDirectConnectSearch.join("ClusterManagedSearch", ClusterManagedSearch, ClusterManagedSearch.entity().getId(), UnmanagedDirectConnectSearch.entity().getClusterId(),
-                JoinType.INNER);
-        UnmanagedDirectConnectSearch.done();
-
-        DirectConnectSearch = createSearchBuilder();
-        DirectConnectSearch.and("resource", DirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        DirectConnectSearch.and("id", DirectConnectSearch.entity().getId(), SearchCriteria.Op.EQ);
-        DirectConnectSearch.and().op("nullserver", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-        DirectConnectSearch.or("server", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-        DirectConnectSearch.cp();
-        DirectConnectSearch.done();
-
-        UnmanagedApplianceSearch = createSearchBuilder();
-        UnmanagedApplianceSearch.and("resource", UnmanagedApplianceSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        UnmanagedApplianceSearch.and("server", UnmanagedApplianceSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-        UnmanagedApplianceSearch.and("types", UnmanagedApplianceSearch.entity().getType(), SearchCriteria.Op.IN);
-        UnmanagedApplianceSearch.and("lastPinged", UnmanagedApplianceSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
-        UnmanagedApplianceSearch.done();
-
-        AvailHypevisorInZone = createSearchBuilder();
-        AvailHypevisorInZone.and("zoneId", AvailHypevisorInZone.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        AvailHypevisorInZone.and("hostId", AvailHypevisorInZone.entity().getId(), SearchCriteria.Op.NEQ);
-        AvailHypevisorInZone.and("type", AvailHypevisorInZone.entity().getType(), SearchCriteria.Op.EQ);
-        AvailHypevisorInZone.groupBy(AvailHypevisorInZone.entity().getHypervisorType());
-        AvailHypevisorInZone.done();
-
-        HostsInStatusSearch = createSearchBuilder(Long.class);
-        HostsInStatusSearch.selectFields(HostsInStatusSearch.entity().getId());
-        HostsInStatusSearch.and("dc", HostsInStatusSearch.entity().getDataCenterId(), Op.EQ);
-        HostsInStatusSearch.and("pod", HostsInStatusSearch.entity().getPodId(), Op.EQ);
-        HostsInStatusSearch.and("cluster", HostsInStatusSearch.entity().getClusterId(), Op.EQ);
-        HostsInStatusSearch.and("type", HostsInStatusSearch.entity().getType(), Op.EQ);
-        HostsInStatusSearch.and("statuses", HostsInStatusSearch.entity().getStatus(), Op.IN);
-        HostsInStatusSearch.done();
-
-        CountRoutingByDc = createSearchBuilder(Long.class);
-        CountRoutingByDc.select(null, Func.COUNT, null);
-        CountRoutingByDc.and("dc", CountRoutingByDc.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        CountRoutingByDc.and("type", CountRoutingByDc.entity().getType(), SearchCriteria.Op.EQ);
-        CountRoutingByDc.and("status", CountRoutingByDc.entity().getStatus(), SearchCriteria.Op.EQ);
-        CountRoutingByDc.done();
-
-        ManagedDirectConnectSearch = createSearchBuilder();
-        ManagedDirectConnectSearch.and("resource", ManagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        ManagedDirectConnectSearch.and("server", ManagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-        ManagedDirectConnectSearch.done();
-
-        ManagedRoutingServersSearch = createSearchBuilder();
-        ManagedRoutingServersSearch.and("server", ManagedRoutingServersSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
-        ManagedRoutingServersSearch.and("type", ManagedRoutingServersSearch.entity().getType(), SearchCriteria.Op.EQ);
-        ManagedRoutingServersSearch.done();
-
-        RoutingSearch = createSearchBuilder();
-        RoutingSearch.and("type", RoutingSearch.entity().getType(), SearchCriteria.Op.EQ);
-        RoutingSearch.done();
-
-        HostsForReconnectSearch = createSearchBuilder();
-        HostsForReconnectSearch.and("resource", HostsForReconnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        HostsForReconnectSearch.and("server", HostsForReconnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-        HostsForReconnectSearch.and("lastPinged", HostsForReconnectSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
-        HostsForReconnectSearch.and("resourceStates", HostsForReconnectSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
-        HostsForReconnectSearch.and("cluster", HostsForReconnectSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
-        HostsForReconnectSearch.and("status", HostsForReconnectSearch.entity().getStatus(), SearchCriteria.Op.IN);
-        HostsForReconnectSearch.done();
-
-        ClustersOwnedByMSSearch = createSearchBuilder(Long.class);
-        ClustersOwnedByMSSearch.select(null, Func.DISTINCT, ClustersOwnedByMSSearch.entity().getClusterId());
-        ClustersOwnedByMSSearch.and("resource", ClustersOwnedByMSSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        ClustersOwnedByMSSearch.and("cluster", ClustersOwnedByMSSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
-        ClustersOwnedByMSSearch.and("server", ClustersOwnedByMSSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-        ClustersOwnedByMSSearch.done();
-
-        ClustersForHostsNotOwnedByAnyMSSearch = createSearchBuilder(Long.class);
-        ClustersForHostsNotOwnedByAnyMSSearch.select(null, Func.DISTINCT, ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId());
-        ClustersForHostsNotOwnedByAnyMSSearch.and("resource", ClustersForHostsNotOwnedByAnyMSSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        ClustersForHostsNotOwnedByAnyMSSearch.and("cluster", ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
-        ClustersForHostsNotOwnedByAnyMSSearch.and("server", ClustersForHostsNotOwnedByAnyMSSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-
-        ClusterManagedSearch = _clusterDao.createSearchBuilder();
-        ClusterManagedSearch.and("managed", ClusterManagedSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
-        ClustersForHostsNotOwnedByAnyMSSearch.join("ClusterManagedSearch", ClusterManagedSearch, ClusterManagedSearch.entity().getId(),
-                ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId(), JoinType.INNER);
-
-        ClustersForHostsNotOwnedByAnyMSSearch.done();
-
-        AllClustersSearch = _clusterDao.createSearchBuilder(Long.class);
-        AllClustersSearch.select(null, Func.NATIVE, AllClustersSearch.entity().getId());
-        AllClustersSearch.and("managed", AllClustersSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
-        AllClustersSearch.done();
-
-        HostsInClusterSearch = createSearchBuilder();
-        HostsInClusterSearch.and("resource", HostsInClusterSearch.entity().getResource(), SearchCriteria.Op.NNULL);
-        HostsInClusterSearch.and("cluster", HostsInClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        HostsInClusterSearch.and("server", HostsInClusterSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
-        HostsInClusterSearch.done();
-
-        HostIdSearch = createSearchBuilder(Long.class);
-        HostIdSearch.selectFields(HostIdSearch.entity().getId());
-        HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ);
-        HostIdSearch.done();
-
-        _statusAttr = _allAttributes.get("status");
-        _msIdAttr = _allAttributes.get("managementServerId");
-        _pingTimeAttr = _allAttributes.get("lastPinged");
-        _resourceStateAttr = _allAttributes.get("resourceState");
-
-        assert (_statusAttr != null && _msIdAttr != null && _pingTimeAttr != null) : "Couldn't find one of these attributes";
-    }
-
-    @Override
-    public long countBy(long clusterId, ResourceState... states) {
-        SearchCriteria<HostVO> sc = MaintenanceCountSearch.create();
-
-        sc.setParameters("resourceState", (Object[])states);
-        sc.setParameters("cluster", clusterId);
-
-        List<HostVO> hosts = listBy(sc);
-        return hosts.size();
-    }
-
-    @Override
-    public List<HostVO> listByDataCenterId(long id) {
-        SearchCriteria<HostVO> sc = DcSearch.create();
-        sc.setParameters("dc", id);
-        sc.setParameters("status", Status.Up);
-        sc.setParameters("type", Host.Type.Routing);
-        sc.setParameters("resourceState", ResourceState.Enabled);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<HostVO> listByDataCenterIdAndHypervisorType(long zoneId, Hypervisor.HypervisorType hypervisorType) {
-        SearchBuilder<ClusterVO> clusterSearch = _clusterDao.createSearchBuilder();
-
-        clusterSearch.and("allocationState", clusterSearch.entity().getAllocationState(), SearchCriteria.Op.EQ);
-        clusterSearch.and("hypervisorType", clusterSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-
-        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
-
-        hostSearch.and("dc", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        hostSearch.and("type", hostSearch.entity().getType(), Op.EQ);
-        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
-        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), Op.EQ);
-
-        hostSearch.join("clusterSearch", clusterSearch, hostSearch.entity().getClusterId(), clusterSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-
-        hostSearch.done();
-
-        SearchCriteria<HostVO> sc = hostSearch.create();
-
-        sc.setParameters("dc", zoneId);
-        sc.setParameters("type", Host.Type.Routing);
-        sc.setParameters("status", Status.Up);
-        sc.setParameters("resourceState", ResourceState.Enabled);
-
-        sc.setJoinParameters("clusterSearch", "allocationState", Grouping.AllocationState.Enabled);
-        sc.setJoinParameters("clusterSearch", "hypervisorType", hypervisorType.toString());
-
-        return listBy(sc);
-    }
-
-    @Override
-    public HostVO findByGuid(String guid) {
-        SearchCriteria<HostVO> sc = GuidSearch.create("guid", guid);
-        return findOneBy(sc);
-    }
-
-    /*
-     * Find hosts which is in Disconnected, Down, Alert and ping timeout and server is not null, set server to null
-     */
-    private void resetHosts(long managementServerId, long lastPingSecondsAfter) {
-        SearchCriteria<HostVO> sc = HostsForReconnectSearch.create();
-        sc.setParameters("server", managementServerId);
-        sc.setParameters("lastPinged", lastPingSecondsAfter);
-        sc.setParameters("status", Status.Disconnected, Status.Down, Status.Alert);
-
-        StringBuilder sb = new StringBuilder();
-        List<HostVO> hosts = lockRows(sc, null, true); // exclusive lock
-        for (HostVO host : hosts) {
-            host.setManagementServerId(null);
-            update(host.getId(), host);
-            sb.append(host.getId());
-            sb.append(" ");
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Following hosts got reset: " + sb.toString());
-        }
-    }
-
-    /*
-     * Returns a list of cluster owned by @managementServerId
-     */
-    private List<Long> findClustersOwnedByManagementServer(long managementServerId) {
-        SearchCriteria<Long> sc = ClustersOwnedByMSSearch.create();
-        sc.setParameters("server", managementServerId);
-
-        List<Long> clusters = customSearch(sc, null);
-        return clusters;
-    }
-
-    /*
-     * Returns clusters based on the list of hosts not owned by any MS
-     */
-    private List<Long> findClustersForHostsNotOwnedByAnyManagementServer() {
-        SearchCriteria<Long> sc = ClustersForHostsNotOwnedByAnyMSSearch.create();
-        sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
-
-        List<Long> clusters = customSearch(sc, null);
-        return clusters;
-    }
-
-    /**
-     * This determines if hosts belonging to cluster(@clusterId) are up for grabs
-     *
-     * This is used for handling following cases:
-     * 1. First host added in cluster
-     * 2. During MS restart all hosts in a cluster are without any MS
-     */
-    private boolean canOwnCluster(long clusterId) {
-        SearchCriteria<HostVO> sc = HostsInClusterSearch.create();
-        sc.setParameters("cluster", clusterId);
-
-        List<HostVO> hosts = search(sc, null);
-        boolean ownCluster = (hosts == null || hosts.size() == 0);
-
-        return ownCluster;
-    }
-
-    @Override
-    @DB
-    public List<HostVO> findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Resetting hosts suitable for reconnect");
-        }
-        // reset hosts that are suitable candidates for reconnect
-        resetHosts(managementServerId, lastPingSecondsAfter);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Completed resetting hosts suitable for reconnect");
-        }
-
-        List<HostVO> assignedHosts = new ArrayList<HostVO>();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Acquiring hosts for clusters already owned by this management server");
-        }
-        List<Long> clusters = findClustersOwnedByManagementServer(managementServerId);
-        txn.start();
-        if (clusters.size() > 0) {
-            // handle clusters already owned by @managementServerId
-            SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
-            sc.setParameters("lastPinged", lastPingSecondsAfter);
-            sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
-            sc.setParameters("clusterIn", clusters.toArray());
-            List<HostVO> unmanagedHosts = lockRows(sc, new Filter(HostVO.class, "clusterId", true, 0L, limit), true); // host belongs to clusters owned by @managementServerId
-            StringBuilder sb = new StringBuilder();
-            for (HostVO host : unmanagedHosts) {
-                host.setManagementServerId(managementServerId);
-                update(host.getId(), host);
-                assignedHosts.add(host);
-                sb.append(host.getId());
-                sb.append(" ");
-            }
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Following hosts got acquired for clusters already owned: " + sb.toString());
-            }
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Completed acquiring hosts for clusters already owned by this management server");
-        }
-
-        if (assignedHosts.size() < limit) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Acquiring hosts for clusters not owned by any management server");
-            }
-            // for remaining hosts not owned by any MS check if they can be owned (by owning full cluster)
-            clusters = findClustersForHostsNotOwnedByAnyManagementServer();
-            List<Long> updatedClusters = clusters;
-            if (clusters.size() > limit) {
-                updatedClusters = clusters.subList(0, limit.intValue());
-            }
-            if (updatedClusters.size() > 0) {
-                SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
-                sc.setParameters("lastPinged", lastPingSecondsAfter);
-                sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
-                sc.setParameters("clusterIn", updatedClusters.toArray());
-                List<HostVO> unmanagedHosts = lockRows(sc, null, true);
-
-                // group hosts based on cluster
-                Map<Long, List<HostVO>> hostMap = new HashMap<Long, List<HostVO>>();
-                for (HostVO host : unmanagedHosts) {
-                    if (hostMap.get(host.getClusterId()) == null) {
-                        hostMap.put(host.getClusterId(), new ArrayList<HostVO>());
-                    }
-                    hostMap.get(host.getClusterId()).add(host);
-                }
-
-                StringBuilder sb = new StringBuilder();
-                for (Long clusterId : hostMap.keySet()) {
-                    if (canOwnCluster(clusterId)) { // cluster is not owned by any other MS, so @managementServerId can own it
-                        List<HostVO> hostList = hostMap.get(clusterId);
-                        for (HostVO host : hostList) {
-                            host.setManagementServerId(managementServerId);
-                            update(host.getId(), host);
-                            assignedHosts.add(host);
-                            sb.append(host.getId());
-                            sb.append(" ");
-                        }
-                    }
-                    if (assignedHosts.size() > limit) {
-                        break;
-                    }
-                }
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Following hosts got acquired from newly owned clusters: " + sb.toString());
-                }
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Completed acquiring hosts for clusters not owned by any management server");
-            }
-        }
-        txn.commit();
-
-        return assignedHosts;
-    }
-
-    @Override
-    @DB
-    public List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-
-        txn.start();
-        SearchCriteria<HostVO> sc = UnmanagedApplianceSearch.create();
-        sc.setParameters("lastPinged", lastPingSecondsAfter);
-        sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.BaremetalDhcp, Type.BaremetalPxe, Type.TrafficMonitor,
-                Type.L2Networking, Type.NetScalerControlCenter);
-        List<HostVO> hosts = lockRows(sc, null, true);
-
-        for (HostVO host : hosts) {
-            host.setManagementServerId(managementServerId);
-            update(host.getId(), host);
-        }
-
-        txn.commit();
-
-        return hosts;
-    }
-
-    @Override
-    public void markHostsAsDisconnected(long msId, long lastPing) {
-        SearchCriteria<HostVO> sc = MsStatusSearch.create();
-        sc.setParameters("ms", msId);
-
-        HostVO host = createForUpdate();
-        host.setLastPinged(lastPing);
-        host.setDisconnectedOn(new Date());
-        UpdateBuilder ub = getUpdateBuilder(host);
-        ub.set(host, "status", Status.Disconnected);
-
-        update(ub, sc, null);
-
-        sc = MsStatusSearch.create();
-        sc.setParameters("ms", msId);
-
-        host = createForUpdate();
-        host.setManagementServerId(null);
-        host.setLastPinged(lastPing);
-        host.setDisconnectedOn(new Date());
-        ub = getUpdateBuilder(host);
-        update(ub, sc, null);
-    }
-
-    @Override
-    public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) {
-
-        SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
-        HostTagVO tagEntity = hostTagSearch.entity();
-        hostTagSearch.and("tag", tagEntity.getTag(), SearchCriteria.Op.EQ);
-
-        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
-        HostVO entity = hostSearch.entity();
-        hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
-        hostSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ);
-        hostSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ);
-        hostSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ);
-        hostSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ);
-        hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
-        hostSearch.join("hostTagSearch", hostTagSearch, entity.getId(), tagEntity.getHostId(), JoinBuilder.JoinType.INNER);
-
-        SearchCriteria<HostVO> sc = hostSearch.create();
-        sc.setJoinParameters("hostTagSearch", "tag", hostTag);
-        sc.setParameters("type", type.toString());
-        if (podId != null) {
-            sc.setParameters("pod", podId);
-        }
-        if (clusterId != null) {
-            sc.setParameters("cluster", clusterId);
-        }
-        sc.setParameters("dc", dcId);
-        sc.setParameters("status", Status.Up.toString());
-        sc.setParameters("resourceState", ResourceState.Enabled.toString());
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
-        SearchBuilder<HostTagVO> hostTagSearch = null;
-        if (haTag != null && !haTag.isEmpty()) {
-            hostTagSearch = _hostTagsDao.createSearchBuilder();
-            hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
-            hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
-            hostTagSearch.cp();
-        }
-
-        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
-
-        hostSearch.and("type", hostSearch.entity().getType(), SearchCriteria.Op.EQ);
-        hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        hostSearch.and("podId", hostSearch.entity().getPodId(), SearchCriteria.Op.EQ);
-        hostSearch.and("zoneId", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
-
-        if (haTag != null && !haTag.isEmpty()) {
-            hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
-        }
-
-        SearchCriteria<HostVO> sc = hostSearch.create();
-
-        if (haTag != null && !haTag.isEmpty()) {
-            sc.setJoinParameters("hostTagSearch", "tag", haTag);
-        }
-
-        if (type != null) {
-            sc.setParameters("type", type);
-        }
-
-        if (clusterId != null) {
-            sc.setParameters("clusterId", clusterId);
-        }
-
-        if (podId != null) {
-            sc.setParameters("podId", podId);
-        }
-
-        sc.setParameters("zoneId", dcId);
-        sc.setParameters("status", Status.Up);
-        sc.setParameters("resourceState", ResourceState.Enabled);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public void loadDetails(HostVO host) {
-        Map<String, String> details = _detailsDao.findDetails(host.getId());
-        host.setDetails(details);
-    }
-
-    @Override
-    public void loadHostTags(HostVO host) {
-        List<String> hostTags = _hostTagsDao.gethostTags(host.getId());
-        host.setHostTags(hostTags);
-    }
-
-    @DB
-    @Override
-    public List<HostVO> findLostHosts(long timeout) {
-        List<HostVO> result = new ArrayList<HostVO>();
-        String sql = "select h.id from host h left join  cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage', 'L2Networking') and (h.cluster_id is null or c.managed_state = 'Managed') ;";
-        try (TransactionLegacy txn = TransactionLegacy.currentTxn();
-                PreparedStatement pstmt = txn.prepareStatement(sql);) {
-            pstmt.setLong(1, timeout);
-            try (ResultSet rs = pstmt.executeQuery();) {
-                while (rs.next()) {
-                    long id = rs.getLong(1); //ID column
-                    result.add(findById(id));
-                }
-            }
-        } catch (SQLException e) {
-            s_logger.warn("Exception: ", e);
-        }
-        return result;
-    }
-
-    @Override
-    public void saveDetails(HostVO host) {
-        Map<String, String> details = host.getDetails();
-        if (details == null) {
-            return;
-        }
-        _detailsDao.persist(host.getId(), details);
-    }
-
-    protected void saveHostTags(HostVO host) {
-        List<String> hostTags = host.getHostTags();
-        if (hostTags == null || (hostTags != null && hostTags.isEmpty())) {
-            return;
-        }
-        _hostTagsDao.persist(host.getId(), hostTags);
-    }
-
-    protected void saveGpuRecords(HostVO host) {
-        HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = host.getGpuGroupDetails();
-        if (groupDetails != null) {
-            // Create/Update GPU group entries
-            _hostGpuGroupsDao.persist(host.getId(), new ArrayList<String>(groupDetails.keySet()));
-            // Create/Update VGPU types entries
-            _vgpuTypesDao.persist(host.getId(), groupDetails);
-        }
-    }
-
-    @Override
-    @DB
-    public HostVO persist(HostVO host) {
-        final String InsertSequenceSql = "INSERT INTO op_host(id) VALUES(?)";
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        HostVO dbHost = super.persist(host);
-
-        try {
-            PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertSequenceSql);
-            pstmt.setLong(1, dbHost.getId());
-            pstmt.executeUpdate();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to persist the sequence number for this host");
-        }
-
-        saveDetails(host);
-        loadDetails(dbHost);
-        saveHostTags(host);
-        loadHostTags(dbHost);
-        saveGpuRecords(host);
-
-        txn.commit();
-
-        return dbHost;
-    }
-
-    @Override
-    @DB
-    public boolean update(Long hostId, HostVO host) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        boolean persisted = super.update(hostId, host);
-        if (!persisted) {
-            return persisted;
-        }
-
-        saveDetails(host);
-        saveHostTags(host);
-        saveGpuRecords(host);
-
-        txn.commit();
-
-        return persisted;
-    }
-
-    @Override
-    @DB
-    public List<RunningHostCountInfo> getRunningHostCounts(Date cutTime) {
-        String sql = "select * from (" + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid "
-                + "where h.status='Up' and h.type='SecondaryStorage' and m.last_update > ? " + "group by h.data_center_id, h.type " + "UNION ALL "
-                + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid "
-                + "where h.status='Up' and h.type='Routing' and m.last_update > ? " + "group by h.data_center_id, h.type) as t " + "ORDER by t.data_center_id, t.type";
-
-        ArrayList<RunningHostCountInfo> l = new ArrayList<RunningHostCountInfo>();
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        ;
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
-            pstmt.setString(1, gmtCutTime);
-            pstmt.setString(2, gmtCutTime);
-
-            ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                RunningHostCountInfo info = new RunningHostCountInfo();
-                info.setDcId(rs.getLong(1));
-                info.setHostType(rs.getString(2));
-                info.setCount(rs.getInt(3));
-
-                l.add(info);
-            }
-        } catch (SQLException e) {
-            s_logger.debug("SQLException caught", e);
-        }
-        return l;
-    }
-
-    @Override
-    public long getNextSequence(long hostId) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("getNextSequence(), hostId: " + hostId);
-        }
-
-        TableGenerator tg = _tgs.get("host_req_sq");
-        assert tg != null : "how can this be wrong!";
-
-        return s_seqFetcher.getNextSequence(Long.class, tg, hostId);
-    }
-
-    /*TODO: this is used by mycloud, check if it needs resource state Enabled */
-    @Override
-    public long countRoutingHostsByDataCenter(long dcId) {
-        SearchCriteria<Long> sc = CountRoutingByDc.create();
-        sc.setParameters("dc", dcId);
-        sc.setParameters("type", Host.Type.Routing);
-        sc.setParameters("status", Status.Up.toString());
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public boolean updateState(Status oldStatus, Event event, Status newStatus, Host vo, Object data) {
-        // lock target row from beginning to avoid lock-promotion caused deadlock
-        HostVO host = lockRow(vo.getId(), true);
-        if (host == null) {
-            if (event == Event.Remove && newStatus == Status.Removed) {
-                host = findByIdIncludingRemoved(vo.getId());
-            }
-        }
-
-        if (host == null) {
-            return false;
-        }
-        long oldPingTime = host.getLastPinged();
-
-        SearchBuilder<HostVO> sb = createSearchBuilder();
-        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("update", sb.entity().getUpdated(), SearchCriteria.Op.EQ);
-        if (newStatus.checkManagementServer()) {
-            sb.and("ping", sb.entity().getLastPinged(), SearchCriteria.Op.EQ);
-            sb.and().op("nullmsid", sb.entity().getManagementServerId(), SearchCriteria.Op.NULL);
-            sb.or("msid", sb.entity().getManagementServerId(), SearchCriteria.Op.EQ);
-            sb.cp();
-        }
-        sb.done();
-
-        SearchCriteria<HostVO> sc = sb.create();
-
-        sc.setParameters("status", oldStatus);
-        sc.setParameters("id", host.getId());
-        sc.setParameters("update", host.getUpdated());
-        long oldUpdateCount = host.getUpdated();
-        if (newStatus.checkManagementServer()) {
-            sc.setParameters("ping", oldPingTime);
-            sc.setParameters("msid", host.getManagementServerId());
-        }
-
-        long newUpdateCount = host.incrUpdated();
-        UpdateBuilder ub = getUpdateBuilder(host);
-        ub.set(host, _statusAttr, newStatus);
-        if (newStatus.updateManagementServer()) {
-            if (newStatus.lostConnection()) {
-                ub.set(host, _msIdAttr, null);
-            } else {
-                ub.set(host, _msIdAttr, host.getManagementServerId());
-            }
-            if (event.equals(Event.Ping) || event.equals(Event.AgentConnected)) {
-                ub.set(host, _pingTimeAttr, System.currentTimeMillis() >> 10);
-            }
-        }
-        if (event.equals(Event.ManagementServerDown)) {
-            ub.set(host, _pingTimeAttr, ((System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout()));
-        }
-        int result = update(ub, sc, null);
-        assert result <= 1 : "How can this update " + result + " rows? ";
-
-        if (result == 0) {
-            HostVO ho = findById(host.getId());
-            assert ho != null : "How how how? : " + host.getId();
-
-            if (status_logger.isDebugEnabled()) {
-
-                StringBuilder str = new StringBuilder("Unable to update host for event:").append(event.toString());
-                str.append(". Name=").append(host.getName());
-                str.append("; New=[status=").append(newStatus.toString()).append(":msid=").append(newStatus.lostConnection() ? "null" : host.getManagementServerId())
-                .append(":lastpinged=").append(host.getLastPinged()).append("]");
-                str.append("; Old=[status=").append(oldStatus.toString()).append(":msid=").append(host.getManagementServerId()).append(":lastpinged=").append(oldPingTime)
-                .append("]");
-                str.append("; DB=[status=").append(vo.getStatus().toString()).append(":msid=").append(vo.getManagementServerId()).append(":lastpinged=").append(vo.getLastPinged())
-                .append(":old update count=").append(oldUpdateCount).append("]");
-                status_logger.debug(str.toString());
-            } else {
-                StringBuilder msg = new StringBuilder("Agent status update: [");
-                msg.append("id = " + host.getId());
-                msg.append("; name = " + host.getName());
-                msg.append("; old status = " + oldStatus);
-                msg.append("; event = " + event);
-                msg.append("; new status = " + newStatus);
-                msg.append("; old update count = " + oldUpdateCount);
-                msg.append("; new update count = " + newUpdateCount + "]");
-                status_logger.debug(msg.toString());
-            }
-
-            if (ho.getState() == newStatus) {
-                status_logger.debug("Host " + ho.getName() + " state has already been updated to " + newStatus);
-                return true;
-            }
-        }
-
-        return result > 0;
-    }
-
-    @Override
-    public boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo) {
-        HostVO host = (HostVO)vo;
-        SearchBuilder<HostVO> sb = createSearchBuilder();
-        sb.and("resource_state", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.done();
-
-        SearchCriteria<HostVO> sc = sb.create();
-
-        sc.setParameters("resource_state", oldState);
-        sc.setParameters("id", host.getId());
-
-        UpdateBuilder ub = getUpdateBuilder(host);
-        ub.set(host, _resourceStateAttr, newState);
-        int result = update(ub, sc, null);
-        assert result <= 1 : "How can this update " + result + " rows? ";
-
-        if (state_logger.isDebugEnabled() && result == 0) {
-            HostVO ho = findById(host.getId());
-            assert ho != null : "How how how? : " + host.getId();
-
-            StringBuilder str = new StringBuilder("Unable to update resource state: [");
-            str.append("m = " + host.getId());
-            str.append("; name = " + host.getName());
-            str.append("; old state = " + oldState);
-            str.append("; event = " + event);
-            str.append("; new state = " + newState + "]");
-            state_logger.debug(str.toString());
-        } else {
-            StringBuilder msg = new StringBuilder("Resource state update: [");
-            msg.append("id = " + host.getId());
-            msg.append("; name = " + host.getName());
-            msg.append("; old state = " + oldState);
-            msg.append("; event = " + event);
-            msg.append("; new state = " + newState + "]");
-            state_logger.debug(msg.toString());
-        }
-
-        return result > 0;
-    }
-
-    @Override
-    public HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type) {
-        SearchCriteria<HostVO> sc = TypeNameZoneSearch.create();
-        sc.setParameters("type", type);
-        sc.setParameters("name", name);
-        sc.setParameters("zoneId", zoneId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<HostVO> findByDataCenterId(Long zoneId) {
-        SearchCriteria<HostVO> sc = DcSearch.create();
-        sc.setParameters("dc", zoneId);
-        sc.setParameters("type", Type.Routing);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<HostVO> findByPodId(Long podId) {
-        SearchCriteria<HostVO> sc = PodSearch.create();
-        sc.setParameters("podId", podId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<HostVO> findByClusterId(Long clusterId) {
-        SearchCriteria<HostVO> sc = ClusterSearch.create();
-        sc.setParameters("clusterId", clusterId);
-        return listBy(sc);
-    }
-
-    @Override
-    public HostVO findByPublicIp(String publicIp) {
-        SearchCriteria<HostVO> sc = PublicIpAddressSearch.create();
-        sc.setParameters("publicIpAddress", publicIp);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public HostVO findByIp(final String ipAddress) {
-        SearchCriteria<HostVO> sc = AnyIpAddressSearch.create();
-        sc.setParameters("publicIpAddress", ipAddress);
-        sc.setParameters("privateIpAddress", ipAddress);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<HostVO> findHypervisorHostInCluster(long clusterId) {
-        SearchCriteria<HostVO> sc = TypeClusterStatusSearch.create();
-        sc.setParameters("type", Host.Type.Routing);
-        sc.setParameters("cluster", clusterId);
-        sc.setParameters("status", Status.Up);
-        sc.setParameters("resourceState", ResourceState.Enabled);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<Long> listAllHosts(long zoneId) {
-        SearchCriteria<Long> sc = HostIdSearch.create();
-        sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        return customSearch(sc, null);
-    }
-
-    @Override
-    public List<Long> listClustersByHostTag(String hostTagOnOffering) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        List<Long> result = new ArrayList<Long>();
-        StringBuilder sql = new StringBuilder(LIST_CLUSTERID_FOR_HOST_TAG);
-        // during listing the clusters that cross the threshold
-        // we need to check with disabled thresholds of each cluster if not defined at cluster consider the global value
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-            pstmt.setString(1, hostTagOnOffering);
-            ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(rs.getLong(1));
-            }
-            return result;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + sql, e);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Caught: " + sql, e);
-        }
-    }
-
-    @Override
-    public List<HostVO> listAllHostsByType(Host.Type type) {
-        SearchCriteria<HostVO> sc = TypeSearch.create();
-        sc.setParameters("type", type);
-        sc.setParameters("resourceState", ResourceState.Enabled);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<HostVO> listByType(Host.Type type) {
-        SearchCriteria<HostVO> sc = TypeSearch.create();
-        sc.setParameters("type", type);
-        return listBy(sc);
-    }
-
-    String sqlFindHostInZoneToExecuteCommand = "Select  id from host "
-            + " where type = 'Routing' and hypervisor_type = ? and data_center_id = ? and status = 'Up' "
-            + " and resource_state = '%s' "
-            + " ORDER by rand() limit 1";
-
-    @Override
-    public HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType) {
-        try (TransactionLegacy tx = TransactionLegacy.currentTxn()) {
-            String sql = createSqlFindHostToExecuteCommand(false);
-            ResultSet rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
-            if (rs.next()) {
-                return findById(rs.getLong("id"));
-            }
-            sql = createSqlFindHostToExecuteCommand(true);
-            rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
-            if (!rs.next()) {
-                throw new CloudRuntimeException(String.format("Could not find a host in zone [zoneId=%d] to operate on. ", zoneId));
-            }
-            return findById(rs.getLong("id"));
-        } catch (SQLException e) {
-            throw new CloudRuntimeException(e);
-        }
-    }
-
-    private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException {
-        PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql);
-        pstmt.setString(1, Objects.toString(hypervisorType));
-        pstmt.setLong(2, zoneId);
-        return pstmt.executeQuery();
-    }
-
-    private String createSqlFindHostToExecuteCommand(boolean useDisabledHosts) {
-        String hostResourceStatus = "Enabled";
-        if (useDisabledHosts) {
-            hostResourceStatus = "Disabled";
-        }
-        return String.format(sqlFindHostInZoneToExecuteCommand, hostResourceStatus);
-    }
-}
diff --git a/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java
deleted file mode 100644
index b4d2f6f..0000000
--- a/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase<HypervisorCapabilitiesVO, Long> implements HypervisorCapabilitiesDao {
-
-    private static final Logger s_logger = Logger.getLogger(HypervisorCapabilitiesDaoImpl.class);
-
-    protected final SearchBuilder<HypervisorCapabilitiesVO> HypervisorTypeSearch;
-    protected final SearchBuilder<HypervisorCapabilitiesVO> HypervisorTypeAndVersionSearch;
-
-    private static final String DEFAULT_VERSION = "default";
-
-    protected HypervisorCapabilitiesDaoImpl() {
-        HypervisorTypeSearch = createSearchBuilder();
-        HypervisorTypeSearch.and("hypervisorType", HypervisorTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        HypervisorTypeSearch.done();
-
-        HypervisorTypeAndVersionSearch = createSearchBuilder();
-        HypervisorTypeAndVersionSearch.and("hypervisorType", HypervisorTypeAndVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        HypervisorTypeAndVersionSearch.and("hypervisorVersion", HypervisorTypeAndVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
-        HypervisorTypeAndVersionSearch.done();
-    }
-
-    HypervisorCapabilitiesVO getCapabilities(HypervisorType hypervisorType, String hypervisorVersion) {
-        HypervisorCapabilitiesVO result = findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
-        if (result == null) { // if data is not available for a specific version then use 'default' as version
-            result = findByHypervisorTypeAndVersion(hypervisorType, DEFAULT_VERSION);
-        }
-        return result;
-    }
-
-    @Override
-    public List<HypervisorCapabilitiesVO> listAllByHypervisorType(HypervisorType hypervisorType) {
-        SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeSearch.create();
-        sc.setParameters("hypervisorType", hypervisorType);
-        return search(sc, null);
-    }
-
-    @Override
-    public HypervisorCapabilitiesVO findByHypervisorTypeAndVersion(HypervisorType hypervisorType, String hypervisorVersion) {
-        SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeAndVersionSearch.create();
-        sc.setParameters("hypervisorType", hypervisorType);
-        sc.setParameters("hypervisorVersion", hypervisorVersion);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public Long getMaxGuestsLimit(HypervisorType hypervisorType, String hypervisorVersion) {
-        Long defaultLimit = new Long(50);
-        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
-        if (result == null)
-            return defaultLimit;
-        Long limit = result.getMaxGuestsLimit();
-        if (limit == null)
-            return defaultLimit;
-        return limit;
-    }
-
-    @Override
-    public Integer getMaxDataVolumesLimit(HypervisorType hypervisorType, String hypervisorVersion) {
-        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
-        return result.getMaxDataVolumesLimit();
-    }
-
-    @Override
-    public Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion) {
-        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
-        return result.getMaxHostsPerCluster();
-    }
-
-    @Override
-    public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion) {
-        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
-        return result.getVmSnapshotEnabled();
-    }
-}
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
deleted file mode 100644
index 1e33b6a..0000000
--- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ /dev/null
@@ -1,700 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.dao;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.persistence.TableGenerator;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.springframework.stereotype.Component;
-
-import com.cloud.network.Network;
-import com.cloud.network.Network.Event;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Network.State;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.SequenceFetcher;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.net.NetUtils;
-
-@Component
-@DB()
-public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements NetworkDao {
-    SearchBuilder<NetworkVO> AllFieldsSearch;
-    SearchBuilder<NetworkVO> AccountSearch;
-    SearchBuilder<NetworkVO> RelatedConfigSearch;
-    SearchBuilder<NetworkVO> AccountNetworkSearch;
-    SearchBuilder<NetworkVO> ZoneBroadcastUriSearch;
-    SearchBuilder<NetworkVO> ZoneSecurityGroupSearch;
-    GenericSearchBuilder<NetworkVO, Integer> CountBy;
-    SearchBuilder<NetworkVO> PhysicalNetworkSearch;
-    SearchBuilder<NetworkVO> SecurityGroupSearch;
-    GenericSearchBuilder<NetworkVO, Long> NetworksRegularUserCanCreateSearch;
-    GenericSearchBuilder<NetworkVO, Integer> NetworksCount;
-    SearchBuilder<NetworkVO> SourceNATSearch;
-    GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
-    SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
-
-    GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
-
-    @Inject
-    ResourceTagDao _tagsDao;
-    @Inject
-    NetworkAccountDao _accountsDao;
-    @Inject
-    NetworkDomainDao _domainsDao;
-    @Inject
-    NetworkOpDao _opDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSvcMap;
-    @Inject
-    NetworkOfferingDao _ntwkOffDao;
-    @Inject
-    NetworkOpDao _ntwkOpDao;
-
-    TableGenerator _tgMacAddress;
-
-    Random _rand = new Random(System.currentTimeMillis());
-    long _prefix = 0x2;
-
-    public NetworkDaoImpl() {
-    }
-
-    @PostConstruct
-    protected void init() {
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
-        AllFieldsSearch.and("cidr", AllFieldsSearch.entity().getCidr(), Op.EQ);
-        AllFieldsSearch.and("broadcastType", AllFieldsSearch.entity().getBroadcastDomainType(), Op.EQ);
-        AllFieldsSearch.and("offering", AllFieldsSearch.entity().getNetworkOfferingId(), Op.EQ);
-        AllFieldsSearch.and("datacenter", AllFieldsSearch.entity().getDataCenterId(), Op.EQ);
-        AllFieldsSearch.and("account", AllFieldsSearch.entity().getAccountId(), Op.EQ);
-        AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ);
-        AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), Op.EQ);
-        AllFieldsSearch.and("physicalNetwork", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ);
-        AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ);
-        AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ);
-        AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getNetworkACLId(), Op.EQ);
-        AllFieldsSearch.and("redundant", AllFieldsSearch.entity().isRedundant(), Op.EQ);
-        final SearchBuilder<NetworkOfferingVO> join1 = _ntwkOffDao.createSearchBuilder();
-        join1.and("isSystem", join1.entity().isSystemOnly(), Op.EQ);
-        join1.and("isRedundant", join1.entity().getRedundantRouter(), Op.EQ);
-        AllFieldsSearch.join("offerings", join1, AllFieldsSearch.entity().getNetworkOfferingId(), join1.entity().getId(), JoinBuilder.JoinType.INNER);
-        AllFieldsSearch.done();
-
-        AccountSearch = createSearchBuilder();
-        AccountSearch.and("offering", AccountSearch.entity().getNetworkOfferingId(), Op.EQ);
-        final SearchBuilder<NetworkAccountVO> join = _accountsDao.createSearchBuilder();
-        join.and("account", join.entity().getAccountId(), Op.EQ);
-        AccountSearch.join("accounts", join, AccountSearch.entity().getId(), join.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
-        AccountSearch.and("datacenter", AccountSearch.entity().getDataCenterId(), Op.EQ);
-        AccountSearch.and("cidr", AccountSearch.entity().getCidr(), Op.EQ);
-        AccountSearch.and("vpcId", AccountSearch.entity().getVpcId(), Op.EQ);
-        AccountSearch.done();
-
-        RelatedConfigSearch = createSearchBuilder();
-        RelatedConfigSearch.and("offering", RelatedConfigSearch.entity().getNetworkOfferingId(), Op.EQ);
-        RelatedConfigSearch.and("datacenter", RelatedConfigSearch.entity().getDataCenterId(), Op.EQ);
-        final SearchBuilder<NetworkAccountVO> join2 = _accountsDao.createSearchBuilder();
-        join2.and("account", join2.entity().getAccountId(), Op.EQ);
-        RelatedConfigSearch.join("account", join2, join2.entity().getNetworkId(), RelatedConfigSearch.entity().getId(), JoinType.INNER);
-        RelatedConfigSearch.done();
-
-        AccountNetworkSearch = createSearchBuilder();
-        AccountNetworkSearch.and("networkId", AccountNetworkSearch.entity().getId(), Op.EQ);
-        final SearchBuilder<NetworkAccountVO> mapJoin = _accountsDao.createSearchBuilder();
-        mapJoin.and("accountId", mapJoin.entity().getAccountId(), Op.EQ);
-        AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
-        AccountNetworkSearch.done();
-
-        ZoneBroadcastUriSearch = createSearchBuilder();
-        ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ);
-        ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
-        ZoneBroadcastUriSearch.and("guestType", ZoneBroadcastUriSearch.entity().getGuestType(), Op.EQ);
-        ZoneBroadcastUriSearch.done();
-
-        ZoneSecurityGroupSearch = createSearchBuilder();
-        ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
-        final SearchBuilder<NetworkServiceMapVO> offJoin = _ntwkSvcMap.createSearchBuilder();
-        offJoin.and("service", offJoin.entity().getService(), Op.EQ);
-        ZoneSecurityGroupSearch.join("services", offJoin, ZoneSecurityGroupSearch.entity().getId(), offJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
-        ZoneSecurityGroupSearch.done();
-
-        CountBy = createSearchBuilder(Integer.class);
-        CountBy.select(null, Func.COUNT, CountBy.entity().getId());
-        CountBy.and("offeringId", CountBy.entity().getNetworkOfferingId(), Op.EQ);
-        CountBy.and("vpcId", CountBy.entity().getVpcId(), Op.EQ);
-        CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL);
-        final SearchBuilder<NetworkOfferingVO> ntwkOffJoin = _ntwkOffDao.createSearchBuilder();
-        ntwkOffJoin.and("isSystem", ntwkOffJoin.entity().isSystemOnly(), Op.EQ);
-        CountBy.join("offerings", ntwkOffJoin, CountBy.entity().getNetworkOfferingId(), ntwkOffJoin.entity().getId(), JoinBuilder.JoinType.INNER);
-        CountBy.done();
-
-        PhysicalNetworkSearch = createSearchBuilder();
-        PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ);
-        PhysicalNetworkSearch.done();
-
-        SecurityGroupSearch = createSearchBuilder();
-        final SearchBuilder<NetworkServiceMapVO> join3 = _ntwkSvcMap.createSearchBuilder();
-        join3.and("service", join3.entity().getService(), Op.EQ);
-        SecurityGroupSearch.join("services", join3, SecurityGroupSearch.entity().getId(), join3.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
-        SecurityGroupSearch.done();
-
-        NetworksCount = createSearchBuilder(Integer.class);
-        NetworksCount.select(null, Func.COUNT, NetworksCount.entity().getId());
-        NetworksCount.and("networkOfferingId", NetworksCount.entity().getNetworkOfferingId(), SearchCriteria.Op.EQ);
-        NetworksCount.done();
-
-        NetworksRegularUserCanCreateSearch = createSearchBuilder(Long.class);
-        NetworksRegularUserCanCreateSearch.and("aclType", NetworksRegularUserCanCreateSearch.entity().getAclType(), Op.EQ);
-        NetworksRegularUserCanCreateSearch.and("displayNetwork", NetworksRegularUserCanCreateSearch.entity().getDisplayNetwork(), Op.EQ);
-        NetworksRegularUserCanCreateSearch.select(null, Func.COUNT, NetworksRegularUserCanCreateSearch.entity().getId());
-        final SearchBuilder<NetworkAccountVO> join4 = _accountsDao.createSearchBuilder();
-        join4.and("account", join4.entity().getAccountId(), Op.EQ);
-        join4.and("isOwner", join4.entity().isOwner(), Op.EQ);
-        NetworksRegularUserCanCreateSearch.join("accounts", join4, NetworksRegularUserCanCreateSearch.entity().getId(), join4.entity().getNetworkId(),
-                JoinBuilder.JoinType.INNER);
-        final SearchBuilder<NetworkOfferingVO> join5 = _ntwkOffDao.createSearchBuilder();
-        join5.and("specifyVlan", join5.entity().getSpecifyVlan(), Op.EQ);
-        NetworksRegularUserCanCreateSearch.join("ntwkOff", join5, NetworksRegularUserCanCreateSearch.entity().getNetworkOfferingId(), join5.entity().getId(),
-                JoinBuilder.JoinType.INNER);
-        NetworksRegularUserCanCreateSearch.done();
-
-        _tgMacAddress = _tgs.get("macAddress");
-
-        SourceNATSearch = createSearchBuilder();
-        SourceNATSearch.and("account", SourceNATSearch.entity().getAccountId(), Op.EQ);
-        SourceNATSearch.and("datacenter", SourceNATSearch.entity().getDataCenterId(), Op.EQ);
-        SourceNATSearch.and("guestType", SourceNATSearch.entity().getGuestType(), Op.EQ);
-        final SearchBuilder<NetworkServiceMapVO> join6 = _ntwkSvcMap.createSearchBuilder();
-        join6.and("service", join6.entity().getService(), Op.EQ);
-        SourceNATSearch.join("services", join6, SourceNATSearch.entity().getId(), join6.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
-        SourceNATSearch.done();
-
-        VpcNetworksCount = createSearchBuilder(Long.class);
-        VpcNetworksCount.and("vpcId", VpcNetworksCount.entity().getVpcId(), Op.EQ);
-        VpcNetworksCount.select(null, Func.COUNT, VpcNetworksCount.entity().getId());
-        final SearchBuilder<NetworkOfferingVO> join9 = _ntwkOffDao.createSearchBuilder();
-        join9.and("isSystem", join9.entity().isSystemOnly(), Op.EQ);
-        VpcNetworksCount.join("offerings", join9, VpcNetworksCount.entity().getNetworkOfferingId(), join9.entity().getId(), JoinBuilder.JoinType.INNER);
-        VpcNetworksCount.done();
-
-        OfferingAccountNetworkSearch = createSearchBuilder();
-        OfferingAccountNetworkSearch.select(null, Func.DISTINCT, OfferingAccountNetworkSearch.entity().getId());
-        final SearchBuilder<NetworkOfferingVO> ntwkOfferingJoin = _ntwkOffDao.createSearchBuilder();
-        ntwkOfferingJoin.and("isSystem", ntwkOfferingJoin.entity().isSystemOnly(), Op.EQ);
-        OfferingAccountNetworkSearch.join("ntwkOfferingSearch", ntwkOfferingJoin, OfferingAccountNetworkSearch.entity().getNetworkOfferingId(), ntwkOfferingJoin.entity()
-                .getId(), JoinBuilder.JoinType.LEFT);
-        final SearchBuilder<NetworkAccountVO> ntwkAccountJoin = _accountsDao.createSearchBuilder();
-        ntwkAccountJoin.and("accountId", ntwkAccountJoin.entity().getAccountId(), Op.EQ);
-        OfferingAccountNetworkSearch.join("ntwkAccountSearch", ntwkAccountJoin, OfferingAccountNetworkSearch.entity().getId(), ntwkAccountJoin.entity().getNetworkId(),
-                JoinBuilder.JoinType.INNER);
-        OfferingAccountNetworkSearch.and("zoneId", OfferingAccountNetworkSearch.entity().getDataCenterId(), Op.EQ);
-        OfferingAccountNetworkSearch.and("type", OfferingAccountNetworkSearch.entity().getGuestType(), Op.EQ);
-        OfferingAccountNetworkSearch.done();
-
-        GarbageCollectedSearch = createSearchBuilder(Long.class);
-        GarbageCollectedSearch.selectFields(GarbageCollectedSearch.entity().getId());
-        final SearchBuilder<NetworkOpVO> join7 = _ntwkOpDao.createSearchBuilder();
-        join7.and("activenics", join7.entity().getActiveNicsCount(), Op.EQ);
-        join7.and("gc", join7.entity().isGarbageCollected(), Op.EQ);
-        join7.and("check", join7.entity().isCheckForGc(), Op.EQ);
-        GarbageCollectedSearch.join("ntwkOpGC", join7, GarbageCollectedSearch.entity().getId(), join7.entity().getId(), JoinBuilder.JoinType.INNER);
-        final SearchBuilder<NetworkOfferingVO> join8 = _ntwkOffDao.createSearchBuilder();
-        join8.and("isPersistent", join8.entity().getIsPersistent(), Op.EQ);
-        GarbageCollectedSearch.join("ntwkOffGC", join8, GarbageCollectedSearch.entity().getNetworkOfferingId(), join8.entity().getId(), JoinBuilder.JoinType.INNER);
-        GarbageCollectedSearch.done();
-
-    }
-
-    @Override
-    public List<NetworkVO> listByZoneAndGuestType(final long accountId, final long dataCenterId, final Network.GuestType type, final Boolean isSystem) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("datacenter", dataCenterId);
-        sc.setParameters("account", accountId);
-        if (type != null) {
-            sc.setParameters("guestType", type);
-        }
-
-        if (isSystem != null) {
-            sc.setJoinParameters("offerings", "isSystem", isSystem);
-        }
-
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<NetworkVO> listByGuestType(Network.GuestType type) {
-        SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("guestType", type);
-        return listBy(sc, null);
-    }
-
-    public List<NetworkVO> findBy(final TrafficType trafficType, final Mode mode, final BroadcastDomainType broadcastType, final long networkOfferingId, final long dataCenterId) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("trafficType", trafficType);
-        sc.setParameters("broadcastType", broadcastType);
-        sc.setParameters("offering", networkOfferingId);
-        sc.setParameters("datacenter", dataCenterId);
-
-        return search(sc, null);
-    }
-
-    @Override
-    public List<NetworkVO> listBy(final long accountId, final long offeringId, final long dataCenterId) {
-        final SearchCriteria<NetworkVO> sc = AccountSearch.create();
-        sc.setParameters("offering", offeringId);
-        sc.setJoinParameters("accounts", "account", accountId);
-        sc.setParameters("datacenter", dataCenterId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final String cidr, final boolean skipVpc) {
-        final SearchCriteria<NetworkVO> sc = AccountSearch.create();
-        sc.setJoinParameters("accounts", "account", accountId);
-        sc.setParameters("datacenter", dataCenterId);
-        sc.setParameters("cidr", cidr);
-        if (skipVpc) {
-            sc.setParameters("vpcId", (Object)null);
-        }
-
-        return listBy(sc);
-    }
-
-    @Override
-    @DB
-    public NetworkVO persist(final NetworkVO network, final boolean gc, final Map<String, String> serviceProviderMap) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        // 1) create network
-        final NetworkVO newNetwork = super.persist(network);
-        // 2) add account to the network
-        addAccountToNetwork(network.getId(), network.getAccountId(), true);
-        // 3) add network to gc monitor table
-        final NetworkOpVO op = new NetworkOpVO(network.getId(), gc);
-        _opDao.persist(op);
-        // 4) add services/providers for the network
-        persistNetworkServiceProviders(newNetwork.getId(), serviceProviderMap);
-
-        txn.commit();
-        return newNetwork;
-    }
-
-    @Override
-    @DB
-    public boolean update(final Long networkId, final NetworkVO network, final Map<String, String> serviceProviderMap) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        super.update(networkId, network);
-        if (serviceProviderMap != null) {
-            _ntwkSvcMap.deleteByNetworkId(networkId);
-            persistNetworkServiceProviders(networkId, serviceProviderMap);
-        }
-
-        txn.commit();
-        return true;
-    }
-
-    @Override
-    @DB
-    public void persistNetworkServiceProviders(final long networkId, final Map<String, String> serviceProviderMap) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        for (final String service : serviceProviderMap.keySet()) {
-            final NetworkServiceMapVO serviceMap = new NetworkServiceMapVO(networkId, Service.getService(service), Provider.getProvider(serviceProviderMap.get(service)));
-            _ntwkSvcMap.persist(serviceMap);
-        }
-        txn.commit();
-    }
-
-    protected void addAccountToNetwork(final long networkId, final long accountId, final boolean isOwner) {
-        final NetworkAccountVO account = new NetworkAccountVO(networkId, accountId, isOwner);
-        _accountsDao.persist(account);
-    }
-
-    @Override
-    public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() {
-        return _accountsDao.createSearchBuilder();
-    }
-
-    @Override
-    public List<NetworkVO> getNetworksForOffering(final long offeringId, final long dataCenterId, final long accountId) {
-        final SearchCriteria<NetworkVO> sc = RelatedConfigSearch.create();
-        sc.setParameters("offering", offeringId);
-        sc.setParameters("dc", dataCenterId);
-        sc.setJoinParameters("account", "account", accountId);
-        return search(sc, null);
-    }
-
-    @Override
-    public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
-        final SequenceFetcher fetch = SequenceFetcher.getInstance();
-        long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
-        if(zoneMacIdentifier != null && zoneMacIdentifier.intValue() != 0 ){
-            seq = seq | _prefix << 40 | (long)zoneMacIdentifier << 32 | networkConfigId << 16 & 0x00000000ffff0000l;
-        }
-        else {
-            seq = seq | _prefix << 40 | _rand.nextInt(Short.MAX_VALUE) << 16 & 0x00000000ffff0000l;
-        }
-        return NetUtils.long2Mac(seq);
-    }
-
-    @Override
-    public List<NetworkVO> listBy(final long accountId, final long networkId) {
-        final SearchCriteria<NetworkVO> sc = AccountNetworkSearch.create();
-        sc.setParameters("networkId", networkId);
-        sc.setJoinParameters("networkSearch", "accountId", accountId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
-        final URI searchUri = BroadcastDomainType.fromString(broadcastUri);
-        final String searchRange = BroadcastDomainType.getValue(searchUri);
-        final List<Integer> searchVlans = UriUtils.expandVlanUri(searchRange);
-        final List<NetworkVO> overlappingNetworks = new ArrayList<>();
-
-        final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
-        sc.setParameters("dataCenterId", zoneId);
-        if (guestType != null) {
-            sc.setParameters("guestType", guestType);
-        }
-
-        for (final NetworkVO network : listBy(sc)) {
-            if (network.getBroadcastUri() == null || !network.getBroadcastUri().getScheme().equalsIgnoreCase(searchUri.getScheme())) {
-                continue;
-            }
-            final String networkVlanRange = BroadcastDomainType.getValue(network.getBroadcastUri());
-            if (networkVlanRange == null || networkVlanRange.isEmpty()) {
-                continue;
-            }
-            for (final Integer networkVlan : UriUtils.expandVlanUri(networkVlanRange)) {
-                if (searchVlans.contains(networkVlan)) {
-                    overlappingNetworks.add(network);
-                    break;
-                }
-            }
-        }
-
-        return overlappingNetworks;
-    }
-
-    @Override
-    public List<NetworkVO> listByZone(final long zoneId) {
-        final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
-        sc.setParameters("dataCenterId", zoneId);
-        return search(sc, null);
-    }
-
-    @Override
-    public List<NetworkVO> listByZoneSecurityGroup(final Long zoneId) {
-        final SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        sc.setJoinParameters("services", "service", Service.SecurityGroup.getName());
-        return search(sc, null);
-    }
-
-    @Override
-    public void changeActiveNicsBy(final long networkId, final int count) {
-        _opDao.changeActiveNicsBy(networkId, count);
-    }
-
-    @Override
-    public int getActiveNicsIn(final long networkId) {
-        return _opDao.getActiveNics(networkId);
-    }
-
-    @Override
-    public List<Long> findNetworksToGarbageCollect() {
-        final SearchCriteria<Long> sc = GarbageCollectedSearch.create();
-        sc.setJoinParameters("ntwkOffGC", "isPersistent", false);
-        sc.setJoinParameters("ntwkOpGC", "activenics", 0);
-        sc.setJoinParameters("ntwkOpGC", "gc", true);
-        sc.setJoinParameters("ntwkOpGC", "check", true);
-        return customSearch(sc, null);
-    }
-
-    @Override
-    public void clearCheckForGc(final long networkId) {
-        _opDao.clearCheckForGc(networkId);
-    }
-
-    @Override
-    public void setCheckForGc(final long networkId) {
-        _opDao.setCheckForGc(networkId);
-    }
-
-    @Override
-    public List<NetworkVO> listByOwner(final long ownerId) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("account", ownerId);
-        return listBy(sc);
-    }
-
-    @Override
-    public void addDomainToNetwork(final long networkId, final long domainId, final Boolean subdomainAccess) {
-        addDomainToNetworknetwork(networkId, domainId, subdomainAccess);
-    }
-
-    protected void addDomainToNetworknetwork(final long networkId, final long domainId, final Boolean subdomainAccess) {
-        final NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId, subdomainAccess);
-        _domainsDao.persist(domain);
-    }
-
-    @Override
-    public int getNetworkCountByVpcId(final long vpcId) {
-        final SearchCriteria<Integer> sc = CountBy.create();
-        sc.setParameters("vpcId", vpcId);
-        final List<Integer> results = customSearch(sc, null);
-        return results.get(0);
-    }
-
-    @Override
-    public List<NetworkVO> listSecurityGroupEnabledNetworks() {
-        final SearchCriteria<NetworkVO> sc = SecurityGroupSearch.create();
-        sc.setJoinParameters("services", "service", Service.SecurityGroup.getName());
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByPhysicalNetwork(final long physicalNetworkId) {
-        final SearchCriteria<NetworkVO> sc = PhysicalNetworkSearch.create();
-        sc.setParameters("physicalNetworkId", physicalNetworkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByPhysicalNetworkTrafficType(final long physicalNetworkId, final TrafficType trafficType) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("trafficType", trafficType);
-        sc.setParameters("physicalNetworkId", physicalNetworkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByPhysicalNetworkAndProvider(final long physicalNetworkId, final String providerName) {
-        final SearchBuilder<NetworkServiceMapVO> svcProviderMapSearch = _ntwkSvcMap.createSearchBuilder();
-        final NetworkServiceMapVO svcProviderEntry = svcProviderMapSearch.entity();
-        svcProviderMapSearch.and("Provider", svcProviderMapSearch.entity().getProvider(), SearchCriteria.Op.EQ);
-
-        final SearchBuilder<NetworkVO> networksSearch = createSearchBuilder();
-        networksSearch.and("physicalNetworkId", networksSearch.entity().getPhysicalNetworkId(), Op.EQ);
-        networksSearch.join("svcProviderMapSearch", svcProviderMapSearch, networksSearch.entity().getId(), svcProviderEntry.getNetworkId(), JoinBuilder.JoinType.INNER);
-
-        final SearchCriteria<NetworkVO> sc = networksSearch.create();
-        sc.setJoinParameters("svcProviderMapSearch", "Provider", providerName);
-        sc.setParameters("physicalNetworkId", physicalNetworkId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final Network.GuestType type, final TrafficType trafficType) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("datacenter", dataCenterId);
-        sc.setParameters("account", accountId);
-        sc.setParameters("guestType", type);
-        sc.setParameters("trafficType", trafficType);
-
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("datacenter", zoneId);
-        sc.setParameters("trafficType", trafficType);
-
-        return listBy(sc, null);
-    }
-
-    @Override
-    public int getNetworkCountByNetworkOffId(final long networkOfferingId) {
-        final SearchCriteria<Integer> sc = NetworksCount.create();
-        sc.setParameters("networkOfferingId", networkOfferingId);
-        final List<Integer> count = customSearch(sc, null);
-        return count.get(0);
-    }
-
-    @Override
-    public long countNetworksUserCanCreate(final long ownerId) {
-        final SearchCriteria<Long> sc = NetworksRegularUserCanCreateSearch.create();
-        sc.setParameters("aclType", ACLType.Account);
-        sc.setParameters("displayNetwork", 1);
-        sc.setJoinParameters("accounts", "account", ownerId);
-        sc.setJoinParameters("ntwkOff", "specifyVlan", false);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public List<NetworkVO> listSourceNATEnabledNetworks(final long accountId, final long dataCenterId, final Network.GuestType type) {
-        final SearchCriteria<NetworkVO> sc = SourceNATSearch.create();
-        sc.setParameters("datacenter", dataCenterId);
-        sc.setParameters("account", accountId);
-        sc.setParameters("guestType", type);
-        sc.setJoinParameters("services", "service", Service.SourceNat.getName());
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByVpc(final long vpcId) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("vpcId", vpcId);
-
-        return listBy(sc, null);
-    }
-
-    @Override
-    public NetworkVO getPrivateNetwork(final String broadcastUri, final String cidr, final long accountId, final long zoneId, Long networkOfferingId) {
-        if (networkOfferingId == null) {
-            networkOfferingId = _ntwkOffDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOffering).getId();
-        }
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("datacenter", zoneId);
-        sc.setParameters("broadcastUri", broadcastUri);
-        sc.setParameters("cidr", cidr);
-        sc.setParameters("account", accountId);
-        sc.setParameters("offering", networkOfferingId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    @DB
-    public boolean remove(final Long id) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        final NetworkVO entry = findById(id);
-        if (entry != null) {
-            _tagsDao.removeByIdAndType(id, ResourceObjectType.Network);
-        }
-        final boolean result = super.remove(id);
-        txn.commit();
-        return result;
-    }
-
-    @Override
-    public long countVpcNetworks(final long vpcId) {
-        final SearchCriteria<Long> sc = VpcNetworksCount.create();
-        sc.setParameters("vpcId", vpcId);
-        //offering shouldn't be system (the one used by the private gateway)
-        sc.setJoinParameters("offerings", "isSystem", false);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public boolean updateState(final State currentState, final Event event, final State nextState, final Network vo, final Object data) {
-        // TODO: ensure this update is correct
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        final NetworkVO networkVo = (NetworkVO)vo;
-        networkVo.setState(nextState);
-        super.update(networkVo.getId(), networkVo);
-
-        txn.commit();
-        return true;
-    }
-
-    @Override
-    public List<NetworkVO> listNetworksByAccount(final long accountId, final long zoneId, final Network.GuestType type, final boolean isSystem) {
-        final SearchCriteria<NetworkVO> sc = OfferingAccountNetworkSearch.create();
-        sc.setJoinParameters("ntwkOfferingSearch", "isSystem", isSystem);
-        sc.setJoinParameters("ntwkAccountSearch", "accountId", accountId);
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("type", type);
-
-        final List<NetworkVO> networks = search(sc, null);
-        return networks;
-    }
-
-    @Override
-    public List<NetworkVO> listRedundantNetworks() {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("redundant", true);
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<NetworkVO> listVpcNetworks() {
-        final SearchBuilder<NetworkVO> sb = createSearchBuilder();
-        sb.and("vpcId", sb.entity().getVpcId(), Op.NNULL);
-        sb.done();
-
-        final SearchCriteria<NetworkVO> sc = sb.create();
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NetworkVO> listByAclId(final long aclId) {
-        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
-        sc.setParameters("aclId", aclId);
-
-        return listBy(sc, null);
-    }
-
-    @Override
-    public int getNonSystemNetworkCountByVpcId(final long vpcId) {
-        final SearchCriteria<Integer> sc = CountBy.create();
-        sc.setParameters("vpcId", vpcId);
-        sc.setJoinParameters("offerings", "isSystem", false);
-        final List<Integer> results = customSearch(sc, null);
-        return results.get(0);
-    }
-
-    @Override
-    public List<NetworkVO> listNetworkVO(List<Long> idset) {
-        final SearchCriteria<NetworkVO> sc_2 = createSearchCriteria();
-        final Filter searchFilter_2 = new Filter(NetworkVO.class, "id", false, null, null);
-        sc_2.addAnd("networkOfferingId", SearchCriteria.Op.IN, idset);
-        sc_2.addAnd("removed", SearchCriteria.Op.EQ, null);
-        return this.search(sc_2, searchFilter_2);
-    }
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java
deleted file mode 100644
index 21794cb..0000000
--- a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemDao.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.List;
-
-import com.cloud.utils.db.GenericDao;
-
-/*
- * Data Access Object for network_acl_item table
- */
-public interface NetworkACLItemDao extends GenericDao<NetworkACLItemVO, Long> {
-
-    boolean setStateToAdd(NetworkACLItemVO rule);
-
-    boolean revoke(NetworkACLItemVO rule);
-
-    List<NetworkACLItemVO> listByACL(Long aclId);
-
-    int getMaxNumberByACL(long aclId);
-
-    NetworkACLItemVO findByAclAndNumber(long aclId, int number);
-
-    void loadCidrs(NetworkACLItemVO item);
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
deleted file mode 100644
index 6eb9cb0..0000000
--- a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
+++ /dev/null
@@ -1,255 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.net.NetUtils;
-
-@Entity
-@Table(name = "network_acl_item")
-public class NetworkACLItemVO implements NetworkACLItem {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 2790623532888742060L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    long id;
-
-    @Column(name = "start_port", updatable = false)
-    Integer sourcePortStart;
-
-    @Column(name = "end_port", updatable = false)
-    Integer sourcePortEnd;
-
-    @Column(name = "protocol", updatable = false)
-    String protocol = NetUtils.TCP_PROTO;
-
-    @Enumerated(value = EnumType.STRING)
-    @Column(name = "state")
-    State state;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    Date created;
-
-    @Column(name = "acl_id")
-    long aclId;
-
-    @Column(name = "icmp_code")
-    Integer icmpCode;
-
-    @Column(name = "icmp_type")
-    Integer icmpType;
-
-    @Column(name = "traffic_type")
-    @Enumerated(value = EnumType.STRING)
-    TrafficType trafficType;
-
-    // This is a delayed load value.  If the value is null,
-    // then this field has not been loaded yet.
-    // Call the NetworkACLItem dao to load it.
-    @Transient
-    List<String> sourceCidrs;
-
-    @Column(name = "uuid")
-    String uuid;
-
-    @Column(name = "number")
-    int number;
-
-    @Column(name = "action")
-    @Enumerated(value = EnumType.STRING)
-    Action action;
-
-    @Column(name = "display", updatable = true, nullable = false)
-    protected boolean display = true;
-
-    public NetworkACLItemVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-
-    public NetworkACLItemVO(Integer portStart, Integer portEnd, String protocol, long aclId, List<String> sourceCidrs, Integer icmpCode, Integer icmpType,
-            TrafficType trafficType, Action action, int number) {
-        sourcePortStart = portStart;
-        sourcePortEnd = portEnd;
-        this.protocol = protocol;
-        this.aclId = aclId;
-        state = State.Staged;
-        this.icmpCode = icmpCode;
-        this.icmpType = icmpType;
-        setSourceCidrList(sourceCidrs);
-        uuid = UUID.randomUUID().toString();
-        this.trafficType = trafficType;
-        this.action = action;
-        this.number = number;
-    }
-
-    public void setSourceCidrList(List<String> sourceCidrs) {
-        this.sourceCidrs = sourceCidrs;
-    }
-
-    @Override
-    public List<String> getSourceCidrList() {
-        return sourceCidrs;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public Integer getSourcePortStart() {
-        return sourcePortStart;
-    }
-
-    @Override
-    public Integer getSourcePortEnd() {
-        return sourcePortEnd;
-    }
-
-    @Override
-    public String getProtocol() {
-        return protocol;
-    }
-
-    public void setState(State state) {
-        this.state = state;
-    }
-
-    @Override
-    public State getState() {
-        return state;
-    }
-
-    @Override
-    public long getAclId() {
-        return aclId;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("Rule[").append(id).append("-").append("NetworkACL").append("-").append(state).append("]").toString();
-    }
-
-    @Override
-    public Integer getIcmpCode() {
-        return icmpCode;
-    }
-
-    @Override
-    public Integer getIcmpType() {
-        return icmpType;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    @Override
-    public Action getAction() {
-        return action;
-    }
-
-    @Override
-    public int getNumber() {
-        return number;
-    }
-
-    @Override
-    public TrafficType getTrafficType() {
-        return trafficType;
-    }
-
-    public void setSourcePortStart(Integer sourcePortStart) {
-        this.sourcePortStart = sourcePortStart;
-    }
-
-    public void setSourcePortEnd(Integer sourcePortEnd) {
-        this.sourcePortEnd = sourcePortEnd;
-    }
-
-    public void setProtocol(String protocol) {
-        this.protocol = protocol;
-    }
-
-    public void setIcmpCode(Integer icmpCode) {
-        this.icmpCode = icmpCode;
-    }
-
-    public void setIcmpType(Integer icmpType) {
-        this.icmpType = icmpType;
-    }
-
-    public void setTrafficType(TrafficType trafficType) {
-        this.trafficType = trafficType;
-    }
-
-    public void setSourceCidrs(String sourceCidrs) {
-        List<String> srcCidrs = new LinkedList<String>();
-        StringTokenizer st = new StringTokenizer(sourceCidrs,",;");
-        while(st.hasMoreTokens()) {
-            srcCidrs.add(st.nextToken());
-        }
-        this.sourceCidrs = srcCidrs;
-    }
-
-    public void setNumber(int number) {
-        this.number = number;
-    }
-
-    public void setAction(Action action) {
-        this.action = action;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public void setDisplay(boolean display) {
-        this.display = display;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        return display;
-    }
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLVO.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLVO.java
deleted file mode 100644
index fb6a239..0000000
--- a/engine/schema/src/com/cloud/network/vpc/NetworkACLVO.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.vpc;
-
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "network_acl")
-public class NetworkACLVO implements NetworkACL {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "vpc_id")
-    Long vpcId;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "description")
-    private String description;
-
-    @Column(name = "display", updatable = true, nullable = false)
-    protected boolean display = true;
-
-    public NetworkACLVO() {
-    }
-
-    protected NetworkACLVO(String name, String description, long vpcId) {
-        this.uuid = UUID.randomUUID().toString();
-        this.name = name;
-        this.description = description;
-        this.vpcId = vpcId;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    @Override
-    public Long getVpcId() {
-        return vpcId;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public void setDisplay(boolean display) {
-        this.display = display;
-    }
-
-    public void setVpcId(long vpcId) {
-        this.vpcId = vpcId;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        return display;
-    }
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/PrivateIpVO.java b/engine/schema/src/com/cloud/network/vpc/PrivateIpVO.java
deleted file mode 100644
index ad17eb1..0000000
--- a/engine/schema/src/com/cloud/network/vpc/PrivateIpVO.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.apache.cloudstack.api.InternalIdentity;
-
-@Entity
-@Table(name = "private_ip_address")
-public class PrivateIpVO implements InternalIdentity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    long id;
-
-    @Column(name = "ip_address", updatable = false, nullable = false)
-    String ipAddress;
-
-    @Column(name = "mac_address")
-    private long macAddress;
-
-    @Column(name = "taken")
-    @Temporal(value = TemporalType.TIMESTAMP)
-    private Date takenAt;
-
-    @Column(name = "network_id", updatable = false, nullable = false)
-    private long networkId;
-
-    @Column(name = "vpc_id")
-    private Long vpcId;
-
-    @Column(name = "source_nat")
-    private boolean sourceNat;
-
-    public PrivateIpVO() {
-    }
-
-    public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId, boolean sourceNat) {
-        this.ipAddress = ipAddress;
-        this.networkId = networkId;
-        this.macAddress = macAddress;
-        this.vpcId = vpcId;
-        this.sourceNat = sourceNat;
-    }
-
-    public void setTakenAt(Date takenDate) {
-        this.takenAt = takenDate;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public long getNetworkId() {
-        return networkId;
-    }
-
-    public Date getTakenAt() {
-        return takenAt;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public long getMacAddress() {
-        return macAddress;
-    }
-
-    public Long getVpcId() {
-        return vpcId;
-    }
-
-    public boolean getSourceNat() {
-        return sourceNat;
-    }
-
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java
deleted file mode 100644
index 395c9b2..0000000
--- a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.network.vpc.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.network.vpc.NetworkACLItemCidrsDao;
-import com.cloud.network.vpc.NetworkACLItemCidrsVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-
-/**
- * @author daan
- *
- */
-@Component
-public class NetworkACLItemCidrsDaoImpl extends GenericDaoBase<NetworkACLItemCidrsVO, Long> implements NetworkACLItemCidrsDao {
-    private static final Logger s_logger = Logger.getLogger(NetworkACLItemCidrsDaoImpl.class);
-    protected final SearchBuilder<NetworkACLItemCidrsVO> cidrsSearch;
-
-    protected NetworkACLItemCidrsDaoImpl() {
-        cidrsSearch = createSearchBuilder();
-        cidrsSearch.and("networkAclItemId", cidrsSearch.entity().getNetworkACLItemId(), SearchCriteria.Op.EQ);
-        cidrsSearch.done();
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkAclItemCidrsDao#persist(long, java.util.List)
-     */
-    @Override
-    public void persist(long networkACLItemId, List<String> cidrs) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-
-        txn.start();
-        for (String cidr : cidrs) {
-            NetworkACLItemCidrsVO vo = new NetworkACLItemCidrsVO(networkACLItemId, cidr);
-            persist(vo);
-        }
-        txn.commit();
-    }
-
-    @Override
-    public void updateCidrs(long networkACLItemId, List<String> cidrs) {
-        List<String> oldCidrs = getCidrs(networkACLItemId);
-        if (!(oldCidrs.size() == cidrs.size() && oldCidrs.equals(cidrs))) {
-            SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
-            sc.setParameters("networkAclItemId", networkACLItemId);
-            remove(sc);
-            persist(networkACLItemId, cidrs);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkAclItemCidrsDao#getCidrs(long)
-     */
-    @Override
-    public List<String> getCidrs(long networkACLItemId) {
-        SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
-        sc.setParameters("networkAclItemId", networkACLItemId);
-
-        List<NetworkACLItemCidrsVO> results = search(sc, null);
-        List<String> cidrs = new ArrayList<String>(results.size());
-        for (NetworkACLItemCidrsVO result : results) {
-            cidrs.add(result.getCidr());
-        }
-
-        return cidrs;
-    }
-
-    @Override
-    public List<NetworkACLItemCidrsVO> listByNetworkACLItemId(long networkACLItemId) {
-        SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
-        sc.setParameters("networkAclItemId", networkACLItemId);
-
-        List<NetworkACLItemCidrsVO> results = search(sc, null);
-
-        return results;
-    }
-
-}
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
deleted file mode 100644
index eb957a9..0000000
--- a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
+++ /dev/null
@@ -1,175 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc.dao;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import com.google.common.collect.Lists;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.network.vpc.NetworkACLItem.State;
-import com.cloud.network.vpc.NetworkACLItemCidrsDao;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-
-@Component
-@DB()
-public class NetworkACLItemDaoImpl extends GenericDaoBase<NetworkACLItemVO, Long> implements NetworkACLItemDao {
-    private static final Logger s_logger = Logger.getLogger(NetworkACLItemDaoImpl.class);
-
-    protected final SearchBuilder<NetworkACLItemVO> AllFieldsSearch;
-    protected final SearchBuilder<NetworkACLItemVO> NotRevokedSearch;
-    protected final SearchBuilder<NetworkACLItemVO> ReleaseSearch;
-    protected final GenericSearchBuilder<NetworkACLItemVO, Integer> MaxNumberSearch;
-
-    @Inject
-    protected NetworkACLItemCidrsDao _networkACLItemCidrsDao;
-
-    protected NetworkACLItemDaoImpl() {
-        super();
-
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("protocol", AllFieldsSearch.entity().getProtocol(), Op.EQ);
-        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
-        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
-        AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getAclId(), Op.EQ);
-        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
-        AllFieldsSearch.and("number", AllFieldsSearch.entity().getNumber(), Op.EQ);
-        AllFieldsSearch.and("action", AllFieldsSearch.entity().getAction(), Op.EQ);
-        AllFieldsSearch.done();
-
-        NotRevokedSearch = createSearchBuilder();
-        NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ);
-        NotRevokedSearch.and("protocol", NotRevokedSearch.entity().getProtocol(), Op.EQ);
-        NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(), Op.EQ);
-        NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(), Op.EQ);
-        NotRevokedSearch.and("aclId", NotRevokedSearch.entity().getAclId(), Op.EQ);
-        NotRevokedSearch.and("trafficType", NotRevokedSearch.entity().getTrafficType(), Op.EQ);
-        NotRevokedSearch.done();
-
-        ReleaseSearch = createSearchBuilder();
-        ReleaseSearch.and("protocol", ReleaseSearch.entity().getProtocol(), Op.EQ);
-        ReleaseSearch.and("ports", ReleaseSearch.entity().getSourcePortStart(), Op.IN);
-        ReleaseSearch.done();
-
-        MaxNumberSearch = createSearchBuilder(Integer.class);
-        MaxNumberSearch.select(null, SearchCriteria.Func.MAX, MaxNumberSearch.entity().getNumber());
-        MaxNumberSearch.and("aclId", MaxNumberSearch.entity().getAclId(), Op.EQ);
-        MaxNumberSearch.done();
-    }
-
-    @Override
-    public NetworkACLItemVO findById(Long id) {
-        NetworkACLItemVO item = super.findById(id);
-        loadCidrs(item);
-        return item;
-    }
-
-    @Override
-    public boolean update(Long id, NetworkACLItemVO item) {
-        boolean result = super.update(id, item);
-        _networkACLItemCidrsDao.updateCidrs(item.getId(), item.getSourceCidrList());
-        return result;
-    }
-
-    @Override
-    public boolean setStateToAdd(NetworkACLItemVO rule) {
-        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
-        sc.setParameters("id", rule.getId());
-        sc.setParameters("state", State.Staged);
-
-        rule.setState(State.Add);
-
-        return update(rule, sc) > 0;
-    }
-
-    @Override
-    public boolean revoke(NetworkACLItemVO rule) {
-        rule.setState(State.Revoke);
-        return update(rule.getId(), rule);
-    }
-
-    @Override
-    public List<NetworkACLItemVO> listByACL(Long aclId) {
-        if (aclId == null) return Lists.newArrayList();
-
-        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
-        sc.setParameters("aclId", aclId);
-        List<NetworkACLItemVO> list = listBy(sc);
-        for(NetworkACLItemVO item :list) {
-            loadCidrs(item);
-        }
-        return list;
-    }
-
-    @Override
-    public int getMaxNumberByACL(long aclId) {
-        SearchCriteria<Integer> sc = MaxNumberSearch.create();
-        sc.setParameters("aclId", aclId);
-        Integer max = customSearch(sc, null).get(0);
-        return (max == null) ? 0 : max;
-    }
-
-    @Override
-    public NetworkACLItemVO findByAclAndNumber(long aclId, int number) {
-        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
-        sc.setParameters("aclId", aclId);
-        sc.setParameters("number", number);
-        NetworkACLItemVO vo = findOneBy(sc);
-        if(vo != null) {
-            loadCidrs(vo);
-        }
-        return vo;
-    }
-
-    @Override
-    @DB
-    public NetworkACLItemVO persist(NetworkACLItemVO networkAclItem) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        NetworkACLItemVO dbNetworkACLItem = super.persist(networkAclItem);
-        saveCidrs(networkAclItem, networkAclItem.getSourceCidrList());
-        loadCidrs(dbNetworkACLItem);
-
-        txn.commit();
-        return dbNetworkACLItem;
-    }
-
-    public void saveCidrs(NetworkACLItemVO networkACLItem, List<String> cidrList) {
-        if (cidrList == null) {
-            return;
-        }
-        _networkACLItemCidrsDao.persist(networkACLItem.getId(), cidrList);
-    }
-
-    @Override
-    public void loadCidrs(NetworkACLItemVO item) {
-        List<String> cidrs = _networkACLItemCidrsDao.getCidrs(item.getId());
-        item.setSourceCidrList(cidrs);
-    }
-}
diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
deleted file mode 100644
index e317143..0000000
--- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
+++ /dev/null
@@ -1,537 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.offerings;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.network.Network;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "network_offerings")
-public class NetworkOfferingVO implements NetworkOffering {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    long id;
-
-    @Column(name = "name")
-    String name;
-
-    @Column(name = "unique_name")
-    private String uniqueName;
-
-    @Column(name = "display_text")
-    String displayText;
-
-    @Column(name = "nw_rate")
-    Integer rateMbps;
-
-    @Column(name = "mc_rate")
-    Integer multicastRateMbps;
-
-    @Column(name = "traffic_type")
-    @Enumerated(value = EnumType.STRING)
-    TrafficType trafficType;
-
-    @Column(name = "specify_vlan")
-    boolean specifyVlan;
-
-    @Column(name = "system_only")
-    boolean systemOnly;
-
-    @Column(name = "service_offering_id")
-    Long serviceOfferingId;
-
-    @Column(name = "tags", length = 4096)
-    String tags;
-
-    @Column(name = "default")
-    boolean isDefault;
-
-    @Column(name = "availability")
-    @Enumerated(value = EnumType.STRING)
-    Availability availability;
-
-    @Column(name = "state")
-    @Enumerated(value = EnumType.STRING)
-    State state = State.Disabled;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    Date created;
-
-    @Column(name = "guest_type")
-    @Enumerated(value = EnumType.STRING)
-    Network.GuestType guestType;
-
-    @Column(name = "dedicated_lb_service")
-    boolean dedicatedLB;
-
-    @Column(name = "shared_source_nat_service")
-    boolean sharedSourceNat;
-
-    @Column(name = "specify_ip_ranges")
-    boolean specifyIpRanges = false;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "uuid")
-    String uuid;
-
-    @Column(name = "redundant_router_service")
-    boolean redundantRouter;
-
-    @Column(name = "conserve_mode")
-    boolean conserveMode;
-
-    @Column(name = "elastic_ip_service")
-    boolean elasticIp;
-
-    @Column(name = "eip_associate_public_ip")
-    boolean eipAssociatePublicIp;
-
-    @Column(name = "elastic_lb_service")
-    boolean elasticLb;
-
-    @Column(name = "inline")
-    boolean inline;
-
-    @Column(name = "is_persistent")
-    boolean isPersistent;
-
-    @Column(name = "for_vpc")
-    boolean forVpc;
-
-    @Column(name = "egress_default_policy")
-    boolean egressdefaultpolicy;
-
-    @Column(name = "concurrent_connections")
-    Integer concurrentConnections;
-
-    @Column(name = "keep_alive_enabled")
-    boolean keepAliveEnabled = false;
-
-    @Column(name="supports_streched_l2")
-    boolean supportsStrechedL2 = false;
-
-    @Column(name="supports_public_access")
-    boolean supportsPublicAccess = false;
-
-    @Override
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    @Column(name = "internal_lb")
-    boolean internalLb;
-
-    @Column(name = "public_lb")
-    boolean publicLb;
-
-    @Column(name="service_package_id")
-    String servicePackageUuid = null;
-
-    @Override
-    public boolean isKeepAliveEnabled() {
-        return keepAliveEnabled;
-    }
-
-    public void setKeepAliveEnabled(boolean keepAliveEnabled) {
-        this.keepAliveEnabled = keepAliveEnabled;
-    }
-
-    @Override
-    public boolean getForVpc() {
-        return forVpc;
-    }
-
-    public void setForVpc(boolean isForVpc) {
-        this.forVpc = isForVpc;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public TrafficType getTrafficType() {
-        return trafficType;
-    }
-
-    @Override
-    public Integer getMulticastRateMbps() {
-        return multicastRateMbps;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public Integer getRateMbps() {
-        return rateMbps;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    @Override
-    public boolean isSystemOnly() {
-        return systemOnly;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public String getTags() {
-        return tags;
-    }
-
-    public void setTags(String tags) {
-        this.tags = tags;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    public void setRateMbps(Integer rateMbps) {
-        this.rateMbps = rateMbps;
-    }
-
-    public void setMulticastRateMbps(Integer multicastRateMbps) {
-        this.multicastRateMbps = multicastRateMbps;
-    }
-
-    @Override
-    public boolean isDefault() {
-        return isDefault;
-    }
-
-    @Override
-    public boolean getSpecifyVlan() {
-        return specifyVlan;
-    }
-
-    @Override
-    public Availability getAvailability() {
-        return availability;
-    }
-
-    public void setAvailability(Availability availability) {
-        this.availability = availability;
-    }
-
-    @Override
-    public String getUniqueName() {
-        return uniqueName;
-    }
-
-    @Override
-    public void setState(State state) {
-        this.state = state;
-    }
-
-    @Override
-    public State getState() {
-        return state;
-    }
-
-    @Override
-    public Network.GuestType getGuestType() {
-        return guestType;
-    }
-
-    public void setServiceOfferingId(Long serviceOfferingId) {
-        this.serviceOfferingId = serviceOfferingId;
-    }
-
-    @Override
-    public Long getServiceOfferingId() {
-        return serviceOfferingId;
-    }
-
-    @Override
-    public boolean getDedicatedLB() {
-        return dedicatedLB;
-    }
-
-    public void setDedicatedLB(boolean dedicatedLB) {
-        this.dedicatedLB = dedicatedLB;
-    }
-
-    @Override
-    public boolean getSharedSourceNat() {
-        return sharedSourceNat;
-    }
-
-    public void setSharedSourceNat(boolean sharedSourceNat) {
-        this.sharedSourceNat = sharedSourceNat;
-    }
-
-    @Override
-    public boolean getRedundantRouter() {
-        return redundantRouter;
-    }
-
-    public void setRedundantRouter(boolean redundantRouter) {
-        this.redundantRouter = redundantRouter;
-    }
-
-    @Override
-    public boolean getEgressDefaultPolicy() {
-        return egressdefaultpolicy;
-    }
-
-    public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps,
-            Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode,
-            boolean specifyIpRanges, boolean isPersistent, boolean internalLb, boolean publicLb, boolean isForVpc) {
-        this.name = name;
-        this.displayText = displayText;
-        this.rateMbps = rateMbps;
-        this.multicastRateMbps = multicastRateMbps;
-        this.trafficType = trafficType;
-        this.systemOnly = systemOnly;
-        this.specifyVlan = specifyVlan;
-        this.isDefault = isDefault;
-        this.availability = availability;
-        this.uniqueName = name;
-        this.uuid = UUID.randomUUID().toString();
-        this.tags = tags;
-        this.guestType = guestType;
-        this.conserveMode = conserveMode;
-        this.dedicatedLB = true;
-        this.sharedSourceNat = false;
-        this.redundantRouter = false;
-        this.elasticIp = false;
-        this.eipAssociatePublicIp = true;
-        this.elasticLb = false;
-        this.inline = false;
-        this.specifyIpRanges = specifyIpRanges;
-        this.isPersistent = isPersistent;
-        this.publicLb = publicLb;
-        this.internalLb = internalLb;
-        this.forVpc = isForVpc;
-    }
-
-    public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps,
-            Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb,
-            boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, boolean specifyIpRanges, boolean inline, boolean isPersistent,
-            boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean isForVpc, boolean egressdefaultpolicy, boolean supportsStrechedL2, boolean supportsPublicAccess) {
-        this(name,
-            displayText,
-            trafficType,
-            systemOnly,
-            specifyVlan,
-            rateMbps,
-            multicastRateMbps,
-            isDefault,
-            availability,
-            tags,
-            guestType,
-            conserveMode,
-            specifyIpRanges,
-            isPersistent,
-            internalLb,
-            publicLb, isForVpc);
-        this.dedicatedLB = dedicatedLb;
-        this.sharedSourceNat = sharedSourceNat;
-        this.redundantRouter = redundantRouter;
-        this.elasticIp = elasticIp;
-        this.elasticLb = elasticLb;
-        this.inline = inline;
-        this.eipAssociatePublicIp = associatePublicIP;
-        this.egressdefaultpolicy = egressdefaultpolicy;
-        this.supportsStrechedL2 = supportsStrechedL2;
-        this.supportsPublicAccess = supportsPublicAccess;
-    }
-
-    public NetworkOfferingVO() {
-    }
-
-    /**
-     * Network Offering for all system vms.
-     *
-     * @param name
-     * @param trafficType
-     * @param specifyIpRanges
-     *            TODO
-     */
-    public NetworkOfferingVO(String name, TrafficType trafficType, boolean specifyIpRanges) {
-        this(name, "System Offering for " + name, trafficType, true, false, 0, 0, true, Availability.Required, null, null, true, specifyIpRanges, false, false, false, false);
-        this.state = State.Enabled;
-    }
-
-    public NetworkOfferingVO(String name, Network.GuestType guestType) {
-        this(name,
-            "System Offering for " + name,
-            TrafficType.Guest,
-            true,
-            true,
-            0,
-            0,
-            true,
-            Availability.Optional,
-            null,
-            Network.GuestType.Isolated,
-            true,
-            false,
-            false,
-            false,
-            false,
-            false);
-        this.state = State.Enabled;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder buf = new StringBuilder("[Network Offering [");
-        return buf.append(id).append("-").append(trafficType).append("-").append(name).append("]").toString();
-    }
-
-    @Override
-    public String getUuid() {
-        return this.uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public void setSortKey(int key) {
-        sortKey = key;
-    }
-
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    public void setUniqueName(String uniqueName) {
-        this.uniqueName = uniqueName;
-    }
-
-    @Override
-    public boolean isConserveMode() {
-        return conserveMode;
-    }
-
-    @Override
-    public boolean getElasticIp() {
-        return elasticIp;
-    }
-
-    @Override
-    public boolean getAssociatePublicIP() {
-        return eipAssociatePublicIp;
-    }
-
-    @Override
-    public boolean getElasticLb() {
-        return elasticLb;
-    }
-
-    @Override
-    public boolean getSpecifyIpRanges() {
-        return specifyIpRanges;
-    }
-
-    @Override
-    public boolean isInline() {
-        return inline;
-    }
-
-    public void setIsPersistent(Boolean isPersistent) {
-        this.isPersistent = isPersistent;
-    }
-
-    @Override
-    public boolean getIsPersistent() {
-        return isPersistent;
-    }
-
-    @Override
-    public boolean getInternalLb() {
-        return internalLb;
-    }
-
-    @Override
-    public boolean getPublicLb() {
-        return publicLb;
-    }
-
-    public void setInternalLb(boolean internalLb) {
-        this.internalLb = internalLb;
-    }
-
-    @Override
-    public Integer getConcurrentConnections() {
-        return this.concurrentConnections;
-    }
-
-    public void setConcurrentConnections(Integer concurrentConnections) {
-        this.concurrentConnections = concurrentConnections;
-    }
-
-    public void setPublicLb(boolean publicLb) {
-        this.publicLb = publicLb;
-    }
-
-    @Override
-    public boolean getSupportsStrechedL2() {
-        return supportsStrechedL2;
-    }
-
-    public void  setServicePackage(String servicePackageUuid) {
-        this.servicePackageUuid = servicePackageUuid;
-    }
-
-    @Override
-    public boolean getSupportsPublicAccess() {
-        return supportsPublicAccess;
-    }
-
-    @Override
-    public String getServicePackage() {
-        return servicePackageUuid;
-    }
-}
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
deleted file mode 100644
index 5c40795..0000000
--- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
+++ /dev/null
@@ -1,272 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.offerings.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.persistence.EntityExistsException;
-
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import org.apache.commons.collections.CollectionUtils;
-import org.springframework.stereotype.Component;
-
-import com.cloud.network.Network;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offerings.NetworkOfferingDetailsVO;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-
-@Component
-@DB()
-public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Long> implements NetworkOfferingDao {
-    final SearchBuilder<NetworkOfferingVO> NameSearch;
-    final SearchBuilder<NetworkOfferingVO> SystemOfferingSearch;
-    final SearchBuilder<NetworkOfferingVO> AvailabilitySearch;
-    final SearchBuilder<NetworkOfferingVO> AllFieldsSearch;
-    private final GenericSearchBuilder<NetworkOfferingVO, Long> UpgradeSearch;
-    @Inject
-    NetworkOfferingDetailsDao _detailsDao;
-    @Inject
-    private NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
-
-    protected NetworkOfferingDaoImpl() {
-        super();
-
-        NameSearch = createSearchBuilder();
-        NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
-        NameSearch.and("uniqueName", NameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
-        NameSearch.done();
-
-        SystemOfferingSearch = createSearchBuilder();
-        SystemOfferingSearch.and("system", SystemOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
-        SystemOfferingSearch.done();
-
-        AvailabilitySearch = createSearchBuilder();
-        AvailabilitySearch.and("availability", AvailabilitySearch.entity().getAvailability(), SearchCriteria.Op.EQ);
-        AvailabilitySearch.and("isSystem", AvailabilitySearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
-        AvailabilitySearch.done();
-
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), SearchCriteria.Op.EQ);
-        AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), SearchCriteria.Op.EQ);
-        AllFieldsSearch.and("isSystem", AllFieldsSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
-        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
-        AllFieldsSearch.done();
-
-        UpgradeSearch = createSearchBuilder(Long.class);
-        UpgradeSearch.selectFields(UpgradeSearch.entity().getId());
-        UpgradeSearch.and("physicalNetworkId", UpgradeSearch.entity().getId(), Op.NEQ);
-        UpgradeSearch.and("physicalNetworkId", UpgradeSearch.entity().isSystemOnly(), Op.EQ);
-        UpgradeSearch.and("trafficType", UpgradeSearch.entity().getTrafficType(), Op.EQ);
-        UpgradeSearch.and("guestType", UpgradeSearch.entity().getGuestType(), Op.EQ);
-        UpgradeSearch.and("state", UpgradeSearch.entity().getState(), Op.EQ);
-        UpgradeSearch.done();
-    }
-
-    @Override
-    public NetworkOfferingVO findByUniqueName(String uniqueName) {
-        SearchCriteria<NetworkOfferingVO> sc = NameSearch.create();
-
-        sc.setParameters("uniqueName", uniqueName);
-
-        return findOneBy(sc);
-
-    }
-
-    @Override
-    public NetworkOfferingVO persistDefaultNetworkOffering(NetworkOfferingVO offering) {
-        assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
-        NetworkOfferingVO vo = findByUniqueName(offering.getUniqueName());
-        if (vo != null) {
-            return vo;
-        }
-        try {
-            vo = persist(offering);
-            return vo;
-        } catch (EntityExistsException e) {
-            // Assume it's conflict on unique name from two different management servers.
-            return findByUniqueName(offering.getName());
-        }
-    }
-
-    @Override
-    public List<NetworkOfferingVO> listSystemNetworkOfferings() {
-        SearchCriteria<NetworkOfferingVO> sc = SystemOfferingSearch.create();
-        sc.setParameters("system", true);
-        return this.listIncludingRemovedBy(sc, null);
-    }
-
-    @Override
-    public List<NetworkOfferingVO> listByAvailability(Availability availability, boolean isSystem) {
-        SearchCriteria<NetworkOfferingVO> sc = AvailabilitySearch.create();
-        sc.setParameters("availability", availability);
-        sc.setParameters("isSystem", isSystem);
-        return listBy(sc, null);
-    }
-
-    @Override
-    @DB
-    public boolean remove(Long networkOfferingId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        NetworkOfferingVO offering = findById(networkOfferingId);
-        offering.setUniqueName(null);
-        update(networkOfferingId, offering);
-        boolean result = super.remove(networkOfferingId);
-        txn.commit();
-        return result;
-    }
-
-    @Override
-    public List<Long> getOfferingIdsToUpgradeFrom(NetworkOffering originalOffering) {
-        SearchCriteria<Long> sc = UpgradeSearch.create();
-        // exclude original offering
-        sc.addAnd("id", SearchCriteria.Op.NEQ, originalOffering.getId());
-
-        // list only non-system offerings
-        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, false);
-
-        // Type of the network should be the same
-        sc.addAnd("guestType", SearchCriteria.Op.EQ, originalOffering.getGuestType());
-
-        // Traffic types should be the same
-        sc.addAnd("trafficType", SearchCriteria.Op.EQ, originalOffering.getTrafficType());
-
-        sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled);
-
-        //specify Vlan should be the same
-        sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, originalOffering.getSpecifyVlan());
-
-        return customSearch(sc, null);
-    }
-
-    @Override
-    public List<NetworkOfferingVO> listByTrafficTypeGuestTypeAndState(NetworkOffering.State state, TrafficType trafficType, Network.GuestType type) {
-        SearchCriteria<NetworkOfferingVO> sc = AllFieldsSearch.create();
-        sc.setParameters("trafficType", trafficType);
-        sc.setParameters("guestType", type);
-        sc.setParameters("state", state);
-        return listBy(sc, null);
-    }
-
-    @Override
-    @DB
-    public NetworkOfferingVO persist(NetworkOfferingVO off, Map<Detail, String> details) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        //1) persist the offering
-        NetworkOfferingVO vo = super.persist(off);
-
-        //2) persist the details
-        if (details != null && !details.isEmpty()) {
-            for (NetworkOffering.Detail detail : details.keySet()) {
-                _detailsDao.persist(new NetworkOfferingDetailsVO(off.getId(), detail, details.get(detail)));
-            }
-        }
-
-        txn.commit();
-        return vo;
-    }
-
-    @Override
-    public List<Long> listNetworkOfferingID() {
-        final SearchCriteria<NetworkOfferingVO> sc_1 = createSearchCriteria();
-        final Filter searchFilter_1 = new Filter(NetworkOfferingVO.class, "created", false, null, null);
-        sc_1.addAnd("servicePackageUuid", SearchCriteria.Op.NEQ, null);
-        sc_1.addAnd("removed", SearchCriteria.Op.EQ, null);
-        List<NetworkOfferingVO> set_of_servicePackageUuid = this.search(sc_1, searchFilter_1);
-        List<Long> id_set = new ArrayList<Long>();
-        for (NetworkOfferingVO node : set_of_servicePackageUuid) {
-            if (node.getServicePackage() != null && !node.getServicePackage().isEmpty()) {
-                id_set.add(node.getId());
-            }
-        }
-        return id_set;
-    }
-
-    @Override
-    public boolean isUsingServicePackage(String uuid) {
-        final SearchCriteria<NetworkOfferingVO> sc = createSearchCriteria();
-        final Filter searchFilter= new Filter(NetworkOfferingVO.class, "created", false, null, null);
-        sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled);
-        sc.addAnd("servicePackageUuid", SearchCriteria.Op.EQ, uuid);
-        List<NetworkOfferingVO> list = this.search(sc, searchFilter);
-
-        if(CollectionUtils.isNotEmpty(list))
-            return true;
-
-        return false;
-    }
-
-    /**
-     * Persist L2 deafult Network offering
-     */
-    private void persistL2DefaultNetworkOffering(String name, String displayText, boolean specifyVlan, boolean configDriveEnabled) {
-        NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, TrafficType.Guest, false, specifyVlan,
-                null, null, true, Availability.Optional, null, Network.GuestType.L2,
-                true,false, false, false, false, false);
-        offering.setState(NetworkOffering.State.Enabled);
-        persistDefaultNetworkOffering(offering);
-
-        if (configDriveEnabled) {
-            NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(),
-                    Network.Service.UserData, Network.Provider.ConfigDrive);
-            networkOfferingServiceMapDao.persist(offService);
-        }
-    }
-
-    /**
-     * Check for default L2 Network Offerings, create them if they are not already created
-     */
-    private void checkPersistL2NetworkOffering(String name, String displayText, boolean specifyVlan, boolean configDriveEnabled) {
-        if (findByUniqueName(name) == null) {
-            persistL2DefaultNetworkOffering(name, displayText, specifyVlan, configDriveEnabled);
-        }
-    }
-
-    @Override
-    public void persistDefaultL2NetworkOfferings() {
-        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOffering,
-                "Offering for L2 networks",
-                false, false);
-
-        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingVlan,
-                "Offering for L2 networks VLAN",
-                true, false);
-
-        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingConfigDrive,
-                "Offering for L2 networks with config drive user data",
-                false, true);
-
-        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingConfigDriveVlan,
-                "Offering for L2 networks with config drive user data VLAN",
-                true, true);
-    }
-}
diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/com/cloud/service/ServiceOfferingVO.java
deleted file mode 100644
index 9c755df..0000000
--- a/engine/schema/src/com/cloud/service/ServiceOfferingVO.java
+++ /dev/null
@@ -1,334 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.service;
-
-import java.util.Map;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-import com.cloud.offering.ServiceOffering;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.vm.VirtualMachine;
-
-@Entity
-@Table(name = "service_offering")
-@DiscriminatorValue(value = "Service")
-@PrimaryKeyJoinColumn(name = "id")
-public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
-    @Column(name = "cpu")
-    private Integer cpu;
-
-    @Column(name = "speed")
-    private Integer speed;
-
-    @Column(name = "ram_size")
-    private Integer ramSize;
-
-    @Column(name = "nw_rate")
-    private Integer rateMbps;
-
-    @Column(name = "mc_rate")
-    private Integer multicastRateMbps;
-
-    @Column(name = "ha_enabled")
-    private boolean offerHA;
-
-    @Column(name = "limit_cpu_use")
-    private boolean limitCpuUse;
-
-    @Column(name = "is_volatile")
-    private boolean volatileVm;
-
-    @Column(name = "host_tag")
-    private String hostTag;
-
-    @Column(name = "default_use")
-    private boolean defaultUse;
-
-    @Column(name = "vm_type")
-    private String vmType;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "deployment_planner")
-    private String deploymentPlanner = null;
-
-    // This is a delayed load value.  If the value is null,
-    // then this field has not been loaded yet.
-    // Call service offering dao to load it.
-    @Transient
-    Map<String, String> details;
-
-    // This flag is required to tell if the offering is dynamic once the cpu, memory and speed are set.
-    // In some cases cpu, memory and speed are set to non-null values even if the offering is dynamic.
-    @Transient
-    boolean isDynamic;
-
-    protected ServiceOfferingVO() {
-        super();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
-            ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
-        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
-        this.cpu = cpu;
-        this.ramSize = ramSize;
-        this.speed = speed;
-        this.rateMbps = rateMbps;
-        this.multicastRateMbps = multicastRateMbps;
-        this.offerHA = offerHA;
-        limitCpuUse = false;
-        volatileVm = false;
-        this.defaultUse = defaultUse;
-        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
-            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, Long domainId) {
-        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
-        this.cpu = cpu;
-        this.ramSize = ramSize;
-        this.speed = speed;
-        this.rateMbps = rateMbps;
-        this.multicastRateMbps = multicastRateMbps;
-        this.offerHA = offerHA;
-        this.limitCpuUse = limitCpuUse;
-        this.volatileVm = volatileVm;
-        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
-            boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
-            VirtualMachine.Type vmType, Long domainId, String hostTag) {
-        this(name,
-            cpu,
-            ramSize,
-            speed,
-            rateMbps,
-            multicastRateMbps,
-            offerHA,
-            limitResourceUse,
-            volatileVm,
-            displayText,
-            provisioningType,
-            useLocalStorage,
-            recreatable,
-            tags,
-            systemUse,
-            vmType,
-            domainId);
-        this.hostTag = hostTag;
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
-            boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
-            VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
-        this(name,
-            cpu,
-            ramSize,
-            speed,
-            rateMbps,
-            multicastRateMbps,
-            offerHA,
-            limitResourceUse,
-            volatileVm,
-            displayText,
-            provisioningType,
-            useLocalStorage,
-            recreatable,
-            tags,
-            systemUse,
-            vmType,
-            domainId,
-            hostTag);
-        this.deploymentPlanner = deploymentPlanner;
-    }
-
-    public ServiceOfferingVO(ServiceOfferingVO offering) {
-        super(offering.getId(),
-            offering.getName(),
-            offering.getDisplayText(),
-            offering.getProvisioningType(),
-            false,
-            offering.getTags(),
-            offering.isRecreatable(),
-            offering.getUseLocalStorage(),
-            offering.getSystemUse(),
-            true,
-            offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(),
-            offering.getDomainId(),
-            offering.getMinIops(),
-            offering.getMaxIops());
-        cpu = offering.getCpu();
-        ramSize = offering.getRamSize();
-        speed = offering.getSpeed();
-        rateMbps = offering.getRateMbps();
-        multicastRateMbps = offering.getMulticastRateMbps();
-        offerHA = offering.getOfferHA();
-        limitCpuUse = offering.getLimitCpuUse();
-        volatileVm = offering.getVolatileVm();
-        hostTag = offering.getHostTag();
-        vmType = offering.getSystemVmType();
-    }
-
-    @Override
-    public boolean getOfferHA() {
-        return offerHA;
-    }
-
-    public void setOfferHA(boolean offerHA) {
-        this.offerHA = offerHA;
-    }
-
-    @Override
-    public boolean getLimitCpuUse() {
-        return limitCpuUse;
-    }
-
-    public void setLimitResourceUse(boolean limitCpuUse) {
-        this.limitCpuUse = limitCpuUse;
-    }
-
-    @Override
-    public boolean getDefaultUse() {
-        return defaultUse;
-    }
-
-    @Override
-    @Transient
-    public String[] getTagsArray() {
-        String tags = getTags();
-        if (tags == null || tags.length() == 0) {
-            return new String[0];
-        }
-
-        return tags.split(",");
-    }
-
-    @Override
-    public Integer getCpu() {
-        return cpu;
-    }
-
-    public void setCpu(int cpu) {
-        this.cpu = cpu;
-    }
-
-    public void setSpeed(int speed) {
-        this.speed = speed;
-    }
-
-    public void setRamSize(int ramSize) {
-        this.ramSize = ramSize;
-    }
-
-    @Override
-    public Integer getSpeed() {
-        return speed;
-    }
-
-    @Override
-    public Integer getRamSize() {
-        return ramSize;
-    }
-
-    public void setRateMbps(Integer rateMbps) {
-        this.rateMbps = rateMbps;
-    }
-
-    @Override
-    public Integer getRateMbps() {
-        return rateMbps;
-    }
-
-    public void setMulticastRateMbps(Integer multicastRateMbps) {
-        this.multicastRateMbps = multicastRateMbps;
-    }
-
-    @Override
-    public Integer getMulticastRateMbps() {
-        return multicastRateMbps;
-    }
-
-    public void setHostTag(String hostTag) {
-        this.hostTag = hostTag;
-    }
-
-    @Override
-    public String getHostTag() {
-        return hostTag;
-    }
-
-    @Override
-    public String getSystemVmType() {
-        return vmType;
-    }
-
-    @Override
-    public void setSortKey(int key) {
-        sortKey = key;
-    }
-
-    @Override
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    @Override
-    public boolean getVolatileVm() {
-        return volatileVm;
-    }
-
-    @Override
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public Map<String, String> getDetails() {
-        return details;
-    }
-
-    public String getDetail(String name) {
-        return details != null ? details.get(name) : null ;
-    }
-
-    public void setDetail(String name, String value) {
-        assert (details != null) : "Did you forget to load the details?";
-
-        details.put(name, value);
-    }
-
-    public void setDetails(Map<String, String> details) {
-        this.details = details;
-    }
-
-    @Override
-    public boolean isDynamic() {
-        return cpu == null || speed == null || ramSize == null || isDynamic;
-    }
-
-    public void setDynamicFlag(boolean isdynamic) {
-        isDynamic = isdynamic;
-    }
-}
diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java b/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java
deleted file mode 100644
index f54c558..0000000
--- a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDaoImpl.java
+++ /dev/null
@@ -1,292 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.service.dao;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.persistence.EntityExistsException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.event.UsageEventVO;
-import com.cloud.service.ServiceOfferingDetailsVO;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.UserVmDetailsDao;
-
-@Component
-@DB()
-public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Long> implements ServiceOfferingDao {
-    protected static final Logger s_logger = Logger.getLogger(ServiceOfferingDaoImpl.class);
-
-    @Inject
-    protected ServiceOfferingDetailsDao detailsDao;
-    @Inject
-    protected UserVmDetailsDao userVmDetailsDao;
-
-    protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
-    protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByDomainIdSearch;
-    protected final SearchBuilder<ServiceOfferingVO> SystemServiceOffering;
-    protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
-    protected final SearchBuilder<ServiceOfferingVO> PublicServiceOfferingSearch;
-
-    public ServiceOfferingDaoImpl() {
-        super();
-
-        UniqueNameSearch = createSearchBuilder();
-        UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
-        UniqueNameSearch.and("system", UniqueNameSearch.entity().getSystemUse(), SearchCriteria.Op.EQ);
-        UniqueNameSearch.done();
-
-        ServiceOfferingsByDomainIdSearch = createSearchBuilder();
-        ServiceOfferingsByDomainIdSearch.and("domainId", ServiceOfferingsByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
-        ServiceOfferingsByDomainIdSearch.done();
-
-        SystemServiceOffering = createSearchBuilder();
-        SystemServiceOffering.and("domainId", SystemServiceOffering.entity().getDomainId(), SearchCriteria.Op.EQ);
-        SystemServiceOffering.and("system", SystemServiceOffering.entity().getSystemUse(), SearchCriteria.Op.EQ);
-        SystemServiceOffering.and("vm_type", SystemServiceOffering.entity().getSpeed(), SearchCriteria.Op.EQ);
-        SystemServiceOffering.and("removed", SystemServiceOffering.entity().getRemoved(), SearchCriteria.Op.NULL);
-        SystemServiceOffering.done();
-
-        PublicServiceOfferingSearch = createSearchBuilder();
-        PublicServiceOfferingSearch.and("domainId", PublicServiceOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
-        PublicServiceOfferingSearch.and("system", PublicServiceOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.EQ);
-        PublicServiceOfferingSearch.and("removed", PublicServiceOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-        PublicServiceOfferingSearch.done();
-
-        ServiceOfferingsByKeywordSearch = createSearchBuilder();
-        ServiceOfferingsByKeywordSearch.or("name", ServiceOfferingsByKeywordSearch.entity().getName(), SearchCriteria.Op.EQ);
-        ServiceOfferingsByKeywordSearch.or("displayText", ServiceOfferingsByKeywordSearch.entity().getDisplayText(), SearchCriteria.Op.EQ);
-        ServiceOfferingsByKeywordSearch.done();
-    }
-
-    @Override
-    public ServiceOfferingVO findByName(String name) {
-        SearchCriteria<ServiceOfferingVO> sc = UniqueNameSearch.create();
-        sc.setParameters("name", name);
-        sc.setParameters("system", true);
-        List<ServiceOfferingVO> vos = search(sc, null, null, false);
-        if (vos.size() == 0) {
-            return null;
-        }
-
-        return vos.get(0);
-    }
-
-    @Override
-    @DB
-    public ServiceOfferingVO persistSystemServiceOffering(ServiceOfferingVO offering) {
-        assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
-        ServiceOfferingVO vo = findByName(offering.getUniqueName());
-        if (vo != null) {
-            // check invalid CPU speed in system service offering, set it to default value of 500 Mhz if 0 CPU speed is found
-            if (vo.getSpeed() <= 0) {
-                vo.setSpeed(500);
-                update(vo.getId(), vo);
-            }
-            if (!vo.getUniqueName().endsWith("-Local")) {
-                if (vo.getUseLocalStorage()) {
-                    vo.setUniqueName(vo.getUniqueName() + "-Local");
-                    vo.setName(vo.getName() + " - Local Storage");
-                    update(vo.getId(), vo);
-                }
-            }
-            return vo;
-        }
-        try {
-            return persist(offering);
-        } catch (EntityExistsException e) {
-            // Assume it's conflict on unique name
-            return findByName(offering.getUniqueName());
-        }
-    }
-
-    @Override
-    public List<ServiceOfferingVO> findServiceOfferingByDomainId(Long domainId) {
-        SearchCriteria<ServiceOfferingVO> sc = ServiceOfferingsByDomainIdSearch.create();
-        sc.setParameters("domainId", domainId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<ServiceOfferingVO> findSystemOffering(Long domainId, Boolean isSystem, String vmType) {
-        SearchCriteria<ServiceOfferingVO> sc = SystemServiceOffering.create();
-        sc.setParameters("domainId", domainId);
-        sc.setParameters("system", isSystem);
-        sc.setParameters("vm_type", vmType);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<ServiceOfferingVO> findPublicServiceOfferings() {
-        SearchCriteria<ServiceOfferingVO> sc = PublicServiceOfferingSearch.create();
-        sc.setParameters("system", false);
-        return listBy(sc);
-    }
-
-    @Override
-    @DB
-    public ServiceOfferingVO persistDeafultServiceOffering(ServiceOfferingVO offering) {
-        assert offering.getUniqueName() != null : "unique name should be set for the service offering";
-        ServiceOfferingVO vo = findByName(offering.getUniqueName());
-        if (vo != null) {
-            return vo;
-        }
-        try {
-            return persist(offering);
-        } catch (EntityExistsException e) {
-            // Assume it's conflict on unique name
-            return findByName(offering.getUniqueName());
-        }
-    }
-
-    @Override
-    public boolean remove(Long id) {
-        ServiceOfferingVO offering = createForUpdate();
-        offering.setRemoved(new Date());
-
-        return update(id, offering);
-    }
-
-    @Override
-    public void loadDetails(ServiceOfferingVO serviceOffering) {
-        Map<String, String> details = detailsDao.listDetailsKeyPairs(serviceOffering.getId());
-        serviceOffering.setDetails(details);
-    }
-
-    @Override
-    public void saveDetails(ServiceOfferingVO serviceOffering) {
-        Map<String, String> details = serviceOffering.getDetails();
-        if (details == null) {
-            return;
-        }
-
-        List<ServiceOfferingDetailsVO> resourceDetails = new ArrayList<ServiceOfferingDetailsVO>();
-        for (String key : details.keySet()) {
-            resourceDetails.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), key, details.get(key), true));
-        }
-
-        detailsDao.saveDetails(resourceDetails);
-    }
-
-    @Override
-    public ServiceOfferingVO findById(Long vmId, long serviceOfferingId) {
-        ServiceOfferingVO offering = super.findById(serviceOfferingId);
-        if (offering.isDynamic()) {
-            offering.setDynamicFlag(true);
-            if (vmId == null) {
-                throw new CloudRuntimeException("missing argument vmId");
-            }
-            Map<String, String> dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId);
-            return getcomputeOffering(offering, dynamicOffering);
-        }
-        return offering;
-    }
-
-    @Override
-    public ServiceOfferingVO findByIdIncludingRemoved(Long vmId, long serviceOfferingId) {
-        ServiceOfferingVO offering = super.findByIdIncludingRemoved(serviceOfferingId);
-        if (offering.isDynamic()) {
-            offering.setDynamicFlag(true);
-            if (vmId == null) {
-                throw new CloudRuntimeException("missing argument vmId");
-            }
-            Map<String, String> dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId);
-            return getcomputeOffering(offering, dynamicOffering);
-        }
-        return offering;
-    }
-
-    @Override
-    public boolean isDynamic(long serviceOfferingId) {
-        ServiceOfferingVO offering = super.findById(serviceOfferingId);
-        return offering.getCpu() == null || offering.getSpeed() == null || offering.getRamSize() == null;
-    }
-
-    @Override
-    public ServiceOfferingVO getcomputeOffering(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
-        ServiceOfferingVO dummyoffering = new ServiceOfferingVO(serviceOffering);
-        dummyoffering.setDynamicFlag(true);
-        if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
-            dummyoffering.setCpu(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name())));
-        }
-        if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
-            dummyoffering.setSpeed(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name())));
-        }
-        if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
-            dummyoffering.setRamSize(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name())));
-        }
-
-        return dummyoffering;
-    }
-
-    @Override
-    public List<ServiceOfferingVO> createSystemServiceOfferings(String name, String uniqueName, int cpuCount, int ramSize, int cpuSpeed,
-            Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, ProvisioningType provisioningType,
-            boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
-        List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
-        ServiceOfferingVO offering = new ServiceOfferingVO(name, cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
-                provisioningType, false, recreatable, tags, systemUse, vmType, defaultUse);
-        offering.setUniqueName(uniqueName);
-        offering = persistSystemServiceOffering(offering);
-        if (offering != null) {
-            list.add(offering);
-        }
-
-        boolean useLocal = true;
-        if (offering.getUseLocalStorage()) { // if 1st one is already local then 2nd needs to be shared
-            useLocal = false;
-        }
-
-        offering = new ServiceOfferingVO(name + (useLocal ? " - Local Storage" : ""), cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
-                provisioningType, useLocal, recreatable, tags, systemUse, vmType, defaultUse);
-        offering.setUniqueName(uniqueName + (useLocal ? "-Local" : ""));
-        offering = persistSystemServiceOffering(offering);
-        if (offering != null) {
-            list.add(offering);
-        }
-
-        return list;
-    }
-
-    @Override
-    public ServiceOfferingVO findDefaultSystemOffering(String offeringName, Boolean useLocalStorage) {
-        String name = offeringName;
-        if (useLocalStorage != null && useLocalStorage.booleanValue()) {
-            name += "-Local";
-        }
-        ServiceOfferingVO serviceOffering = findByName(name);
-        if (serviceOffering == null) {
-            String message = "System service offering " + name + " not found";
-            s_logger.error(message);
-            throw new CloudRuntimeException(message);
-        }
-        return serviceOffering;
-    }
-}
diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
deleted file mode 100644
index 5de7f98..0000000
--- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
+++ /dev/null
@@ -1,517 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-
-import com.cloud.offering.DiskOffering;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "disk_offering")
-@Inheritance(strategy = InheritanceType.JOINED)
-@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32)
-public class DiskOfferingVO implements DiskOffering {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    long id;
-
-    @Column(name = "domain_id")
-    Long domainId;
-
-    @Column(name = "unique_name")
-    private String uniqueName;
-
-    @Column(name = "name")
-    private String name = null;
-
-    @Column(name = "display_text", length = 4096)
-    private String displayText = null;
-
-    @Column(name = "disk_size")
-    long diskSize;
-
-    @Column(name = "tags", length = 4096)
-    String tags;
-
-    @Column(name = "type")
-    Type type;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = "recreatable")
-    private boolean recreatable;
-
-    @Column(name = "use_local_storage")
-    private boolean useLocalStorage;
-
-    @Column(name = "system_use")
-    private boolean systemUse;
-
-    @Column(name = "customized")
-    private boolean customized;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "customized_iops")
-    private Boolean customizedIops;
-
-    @Column(name = "min_iops")
-    private Long minIops;
-
-    @Column(name = "max_iops")
-    private Long maxIops;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "bytes_read_rate")
-    Long bytesReadRate;
-
-    @Column(name = "bytes_write_rate")
-    Long bytesWriteRate;
-
-    @Column(name = "iops_read_rate")
-    Long iopsReadRate;
-
-    @Column(name = "iops_write_rate")
-    Long iopsWriteRate;
-
-    @Column(name = "cache_mode", updatable = true, nullable = false)
-    @Enumerated(value = EnumType.STRING)
-    private DiskCacheMode cacheMode;
-
-    @Column(name="provisioning_type")
-    Storage.ProvisioningType provisioningType;
-
-    @Column(name="display_offering")
-    boolean displayOffering = true;
-
-    @Enumerated(EnumType.STRING)
-    @Column(name = "state")
-    State state;
-
-    @Column(name = "hv_ss_reserve")
-    Integer hypervisorSnapshotReserve;
-
-    public DiskOfferingVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-
-    public DiskOfferingVO(Long domainId, String name, String displayText, Storage.ProvisioningType provisioningType, long diskSize, String tags, boolean isCustomized,
-            Boolean isCustomizedIops, Long minIops, Long maxIops, DiskCacheMode cacheMode) {
-        this.domainId = domainId;
-        this.name = name;
-        this.displayText = displayText;
-        this.provisioningType = provisioningType;
-        this.diskSize = diskSize;
-        this.tags = tags;
-        recreatable = false;
-        type = Type.Disk;
-        useLocalStorage = false;
-        customized = isCustomized;
-        uuid = UUID.randomUUID().toString();
-        customizedIops = isCustomizedIops;
-        this.minIops = minIops;
-        this.maxIops = maxIops;
-        this.cacheMode = cacheMode;
-    }
-
-    public DiskOfferingVO(Long domainId, String name, String displayText, Storage.ProvisioningType provisioningType, long diskSize, String tags, boolean isCustomized,
-            Boolean isCustomizedIops, Long minIops, Long maxIops) {
-        this.domainId = domainId;
-        this.name = name;
-        this.displayText = displayText;
-        this.provisioningType = provisioningType;
-        this.diskSize = diskSize;
-        this.tags = tags;
-        recreatable = false;
-        type = Type.Disk;
-        useLocalStorage = false;
-        customized = isCustomized;
-        uuid = UUID.randomUUID().toString();
-        customizedIops = isCustomizedIops;
-        this.minIops = minIops;
-        this.maxIops = maxIops;
-        state = State.Active;
-    }
-
-    public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable,
-            boolean useLocalStorage, boolean systemUse, boolean customized) {
-        domainId = null;
-        type = Type.Service;
-        this.name = name;
-        this.displayText = displayText;
-        this.provisioningType = provisioningType;
-        this.tags = tags;
-        this.recreatable = recreatable;
-        this.useLocalStorage = useLocalStorage;
-        this.systemUse = systemUse;
-        this.customized = customized;
-        uuid = UUID.randomUUID().toString();
-        state = State.Active;
-    }
-
-    // domain specific offerings constructor (null domainId implies public
-    // offering)
-    public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable,
-            boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) {
-        type = Type.Service;
-        this.name = name;
-        this.displayText = displayText;
-        this.provisioningType = provisioningType;
-        this.tags = tags;
-        this.recreatable = recreatable;
-        this.useLocalStorage = useLocalStorage;
-        this.systemUse = systemUse;
-        this.customized = customized;
-        this.domainId = domainId;
-        uuid = UUID.randomUUID().toString();
-        state = State.Active;
-    }
-
-    public DiskOfferingVO(long id, String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable,
-            boolean useLocalStorage, boolean systemUse, boolean customized, boolean customizedIops, Long domainId, Long minIops, Long maxIops) {
-        this.id = id;
-        type = Type.Service;
-        this.name = name;
-        this.displayText = displayText;
-        this.provisioningType = provisioningType;
-        this.tags = tags;
-        this.recreatable = recreatable;
-        this.useLocalStorage = useLocalStorage;
-        this.systemUse = systemUse;
-        this.customized = customized;
-        this.customizedIops = customizedIops;
-        this.domainId = domainId;
-        uuid = UUID.randomUUID().toString();
-        state = State.Active;
-        this.minIops = minIops;
-        this.maxIops = maxIops;
-    }
-
-    @Override
-    public State getState() {
-        return state;
-    }
-
-    public void setState(State state) {
-        this.state = state;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public boolean isCustomized() {
-        return customized;
-    }
-
-    public void setCustomized(boolean customized) {
-        this.customized = customized;
-    }
-
-    @Override
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    @Override
-    public void setCustomizedIops(Boolean customizedIops) {
-        this.customizedIops = customizedIops;
-    }
-
-    @Override
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    @Override
-    public void setMinIops(Long minIops) {
-        this.minIops = minIops;
-    }
-
-    @Override
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    @Override
-    public void setMaxIops(Long maxIops) {
-        this.maxIops = maxIops;
-    }
-
-    @Override
-    public DiskCacheMode getCacheMode() {
-        return cacheMode;
-    }
-
-    @Override
-    public void setCacheMode(DiskCacheMode cacheMode) {
-        this.cacheMode = cacheMode;
-    }
-
-    @Override
-    public String getUniqueName() {
-        return uniqueName;
-    }
-
-    @Override
-    public boolean getUseLocalStorage() {
-        return useLocalStorage;
-    }
-
-    @Override
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    @Override
-    public boolean isRecreatable() {
-        return recreatable;
-    }
-
-    public void setDomainId(Long domainId) {
-        this.domainId = domainId;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public boolean getSystemUse() {
-        return systemUse;
-    }
-
-    public void setSystemUse(boolean systemUse) {
-        this.systemUse = systemUse;
-    }
-
-    @Override
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    @Override
-    public Storage.ProvisioningType getProvisioningType(){
-        return provisioningType;
-    }
-
-    @Override
-    public long getDiskSize() {
-        return diskSize;
-    }
-
-    @Override
-    public void setDiskSize(long diskSize) {
-        this.diskSize = diskSize;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public Date getCreated() {
-        return created;
-    }
-
-    protected void setTags(String tags) {
-        this.tags = tags;
-    }
-
-    @Override
-    public String getTags() {
-        return tags;
-    }
-
-    public void setUniqueName(String name) {
-        uniqueName = name;
-    }
-
-    @Override
-    @Transient
-    public String[] getTagsArray() {
-        String tags = getTags();
-        if (tags == null || tags.isEmpty()) {
-            return new String[0];
-        }
-
-        return tags.split(",");
-    }
-
-    @Transient
-    public boolean containsTag(String... tags) {
-        if (this.tags == null) {
-            return false;
-        }
-
-        for (String tag : tags) {
-            if (!this.tags.matches(tag)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Transient
-    public void setTagsArray(List<String> newTags) {
-        if (newTags.isEmpty()) {
-            setTags(null);
-            return;
-        }
-
-        StringBuilder buf = new StringBuilder();
-        for (String tag : newTags) {
-            buf.append(tag).append(",");
-        }
-
-        buf.delete(buf.length() - 1, buf.length());
-
-        setTags(buf.toString());
-    }
-
-    public void setUseLocalStorage(boolean useLocalStorage) {
-        this.useLocalStorage = useLocalStorage;
-    }
-
-    public void setRemoved(Date removed) {
-        this.removed = removed;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public void setSortKey(int key) {
-        sortKey = key;
-    }
-
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    public void setRecreatable(boolean recreatable) {
-        this.recreatable = recreatable;
-    }
-
-    public boolean getDisplayOffering() {
-        return displayOffering;
-    }
-
-    public void setDisplayOffering(boolean displayOffering) {
-        this.displayOffering = displayOffering;
-    }
-
-    @Override
-    public void setBytesReadRate(Long bytesReadRate) {
-        this.bytesReadRate = bytesReadRate;
-    }
-
-    @Override
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    @Override
-    public void setBytesWriteRate(Long bytesWriteRate) {
-        this.bytesWriteRate = bytesWriteRate;
-    }
-
-    @Override
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    @Override
-    public void setIopsReadRate(Long iopsReadRate) {
-        this.iopsReadRate = iopsReadRate;
-    }
-
-    @Override
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    @Override
-    public void setIopsWriteRate(Long iopsWriteRate) {
-        this.iopsWriteRate = iopsWriteRate;
-    }
-
-    @Override
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    @Override
-    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
-        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
-    }
-
-    @Override
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-}
diff --git a/engine/schema/src/com/cloud/storage/GuestOSVO.java b/engine/schema/src/com/cloud/storage/GuestOSVO.java
deleted file mode 100644
index f04f9a4..0000000
--- a/engine/schema/src/com/cloud/storage/GuestOSVO.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "guest_os")
-public class GuestOSVO implements GuestOS {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    long id;
-
-    @Column(name = "category_id")
-    private long categoryId;
-
-    @Column(name = "name")
-    String name;
-
-    @Column(name = "display_name")
-    String displayName;
-
-    @Column(name = "uuid")
-    String uuid = UUID.randomUUID().toString();
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = "is_user_defined")
-    private boolean isUserDefined;
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public long getCategoryId() {
-        return categoryId;
-    }
-
-    public void setCategoryId(long categoryId) {
-        this.categoryId = categoryId;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public String getDisplayName() {
-        return displayName;
-    }
-
-    public void setDisplayName(String displayName) {
-        this.displayName = displayName;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setRemoved(Date removed) {
-        this.removed = removed;
-    }
-
-    @Override
-    public Date getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public boolean getIsUserDefined() {
-        return isUserDefined;
-    }
-
-    public void setIsUserDefined(boolean isUserDefined) {
-        this.isUserDefined = isUserDefined;
-    }
-}
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java
deleted file mode 100644
index d206835..0000000
--- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java
+++ /dev/null
@@ -1,633 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.util.Date;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "vm_template")
-public class VMTemplateVO implements VirtualMachineTemplate {
-    @Id
-    @TableGenerator(name = "vm_template_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_template_seq", allocationSize = 1)
-    @Column(name = "id", nullable = false)
-    private long id;
-
-    @Column(name = "format")
-    private Storage.ImageFormat format;
-
-    @Column(name = "unique_name")
-    private String uniqueName;
-
-    @Column(name = "name")
-    private String name = null;
-
-    @Column(name = "public")
-    private boolean publicTemplate = true;
-
-    @Column(name = "featured")
-    private boolean featured;
-
-    @Column(name = "type")
-    private Storage.TemplateType templateType;
-
-    @Column(name = "url", length = 2048)
-    private String url = null;
-
-    @Column(name = "hvm")
-    private boolean requiresHvm;
-
-    @Column(name = "bits")
-    private int bits;
-
-    @Temporal(value = TemporalType.TIMESTAMP)
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created = null;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date removed;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = "checksum")
-    private String checksum;
-
-    @Column(name = "display_text", length = 4096)
-    private String displayText;
-
-    @Column(name = "enable_password")
-    private boolean enablePassword;
-
-    @Column(name = "guest_os_id")
-    private long guestOSId;
-
-    @Column(name = "bootable")
-    private boolean bootable = true;
-
-    @Column(name = "prepopulate")
-    private boolean prepopulate = false;
-
-    @Column(name = "cross_zones")
-    private boolean crossZones = false;
-
-    @Column(name = "hypervisor_type")
-    @Enumerated(value = EnumType.STRING)
-    private HypervisorType hypervisorType;
-
-    @Column(name = "extractable")
-    private boolean extractable = true;
-
-    @Column(name = "source_template_id")
-    private Long sourceTemplateId;
-
-    @Column(name = "state")
-    @Enumerated(EnumType.STRING)
-    private State state;
-
-    @Column(name = "template_tag")
-    private String templateTag;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "sort_key")
-    private int sortKey;
-
-    @Column(name = "enable_sshkey")
-    private boolean enableSshKey;
-
-    @Column(name = "size")
-    private Long size;
-
-    @Column(name = "update_count", updatable = true)
-    protected long updatedCount;
-
-    @Column(name = "updated")
-    @Temporal(value = TemporalType.TIMESTAMP)
-    Date updated;
-
-    @Transient
-    Map<String, String> details;
-
-    @Column(name = "dynamically_scalable")
-    protected boolean dynamicallyScalable;
-
-    @Column(name = "direct_download")
-    private boolean directDownload;
-
-    @Column(name = "parent_template_id")
-    private Long parentTemplateId;
-
-    @Override
-    public String getUniqueName() {
-        return uniqueName;
-    }
-
-    public void setUniqueName(String uniqueName) {
-        this.uniqueName = uniqueName;
-    }
-
-    public VMTemplateVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-
-    //FIXME - Remove unwanted constructors.
-    private VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url,
-            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
-            HypervisorType hyperType, Map<String, String> details) {
-        this(id,
-            generateUniqueName(id, accountId, name),
-            name,
-            format,
-            isPublic,
-            featured,
-            isExtractable,
-            type,
-            url,
-            null,
-            requiresHvm,
-            bits,
-            accountId,
-            cksum,
-            displayText,
-            enablePassword,
-            guestOSId,
-            bootable,
-            hyperType,
-            details);
-        uuid = UUID.randomUUID().toString();
-    }
-
-    public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url,
-            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
-            HypervisorType hyperType, String templateTag, Map<String, String> details, boolean sshKeyEnabled, boolean isDynamicallyScalable, boolean directDownload) {
-        this(id,
-            name,
-            format,
-            isPublic,
-            featured,
-            isExtractable,
-            type,
-            url,
-            requiresHvm,
-            bits,
-            accountId,
-            cksum,
-            displayText,
-            enablePassword,
-            guestOSId,
-            bootable,
-            hyperType,
-            details);
-        this.templateTag = templateTag;
-        uuid = UUID.randomUUID().toString();
-        enableSshKey = sshKeyEnabled;
-        dynamicallyScalable = isDynamicallyScalable;
-        state = State.Active;
-        this.directDownload = directDownload;
-    }
-
-    public static VMTemplateVO createPreHostIso(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type,
-        String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId,
-        boolean bootable, HypervisorType hyperType) {
-        VMTemplateVO template =
-            new VMTemplateVO(id, uniqueName, name, format, isPublic, featured, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword,
-                guestOSId, bootable, hyperType);
-        return template;
-    }
-
-    public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type, String url, Date created,
-            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
-            HypervisorType hyperType) {
-        this.id = id;
-        this.name = name;
-        publicTemplate = isPublic;
-        this.featured = featured;
-        templateType = type;
-        this.url = url;
-        this.requiresHvm = requiresHvm;
-        this.bits = bits;
-        this.accountId = accountId;
-        checksum = cksum;
-        this.uniqueName = uniqueName;
-        this.displayText = displayText;
-        this.enablePassword = enablePassword;
-        this.format = format;
-        this.created = created;
-        this.guestOSId = guestOSId;
-        this.bootable = bootable;
-        hypervisorType = hyperType;
-        uuid = UUID.randomUUID().toString();
-        state = State.Active;
-    }
-
-    //FIXME - Remove unwanted constructors. Made them private for now
-    private VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type,
-            String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId,
-            boolean bootable, HypervisorType hyperType, Map<String, String> details) {
-        this(id,
-            uniqueName,
-            name,
-            format,
-            isPublic,
-            featured,
-            type,
-            url,
-            created,
-            requiresHvm,
-            bits,
-            accountId,
-            cksum,
-            displayText,
-            enablePassword,
-            guestOSId,
-            bootable,
-            hyperType);
-        extractable = isExtractable;
-        uuid = UUID.randomUUID().toString();
-        this.details = details;
-        state = State.Active;
-    }
-
-    @Override
-    public boolean getEnablePassword() {
-        return enablePassword;
-    }
-
-    @Override
-    public Storage.ImageFormat getFormat() {
-        return format;
-    }
-
-    public void setEnablePassword(boolean enablePassword) {
-        this.enablePassword = enablePassword;
-    }
-
-    public void setFormat(ImageFormat format) {
-        this.format = format;
-    }
-
-    private static String generateUniqueName(long id, long userId, String displayName) {
-        StringBuilder name = new StringBuilder();
-        name.append(id);
-        name.append("-");
-        name.append(userId);
-        name.append("-");
-        name.append(UUID.nameUUIDFromBytes((displayName + System.currentTimeMillis()).getBytes()).toString());
-        return name.toString();
-    }
-
-    @Override
-    public State getState() {
-        return state;
-    }
-
-    public void setState(State state) {
-        this.state = state;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public TemplateType getTemplateType() {
-        return templateType;
-    }
-
-    public void setTemplateType(TemplateType type) {
-        templateType = type;
-    }
-
-    public boolean requiresHvm() {
-        return requiresHvm;
-    }
-
-    @Override
-    public int getBits() {
-        return bits;
-    }
-
-    public void setBits(int bits) {
-        this.bits = bits;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    @Override
-    public boolean isPublicTemplate() {
-        return publicTemplate;
-    }
-
-    public void setPublicTemplate(boolean publicTemplate) {
-        this.publicTemplate = publicTemplate;
-    }
-
-    @Override
-    public boolean isFeatured() {
-        return featured;
-    }
-
-    public void setFeatured(boolean featured) {
-        this.featured = featured;
-    }
-
-    @Override
-    public Date getCreated() {
-        return created;
-    }
-
-    @Override
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    @Override
-    public boolean isRequiresHvm() {
-        return requiresHvm;
-    }
-
-    public void setRequiresHvm(boolean value) {
-        requiresHvm = value;
-    }
-
-    @Override
-    public long getAccountId() {
-        return accountId;
-    }
-
-    @Override
-    public String getChecksum() {
-        return checksum;
-    }
-
-    public void setChecksum(String checksum) {
-        this.checksum = checksum;
-    }
-
-    @Override
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public void setDisplayText(String displayText) {
-        this.displayText = displayText;
-    }
-
-    @Override
-    public long getGuestOSId() {
-        return guestOSId;
-    }
-
-    public void setGuestOSId(long guestOSId) {
-        this.guestOSId = guestOSId;
-    }
-
-    @Override
-    public boolean isBootable() {
-        return bootable;
-    }
-
-    public void setBootable(boolean bootable) {
-        this.bootable = bootable;
-    }
-
-    public void setPrepopulate(boolean prepopulate) {
-        this.prepopulate = prepopulate;
-    }
-
-    public boolean isPrepopulate() {
-        return prepopulate;
-    }
-
-    public void setCrossZones(boolean crossZones) {
-        this.crossZones = crossZones;
-    }
-
-    @Override
-    public boolean isCrossZones() {
-        return crossZones;
-    }
-
-    @Override
-    public HypervisorType getHypervisorType() {
-        return hypervisorType;
-    }
-
-    public void setHypervisorType(HypervisorType hyperType) {
-        hypervisorType = hyperType;
-    }
-
-    @Override
-    public boolean isExtractable() {
-        return extractable;
-    }
-
-    public void setExtractable(boolean extractable) {
-        this.extractable = extractable;
-    }
-
-    @Override
-    public Long getSourceTemplateId() {
-        return sourceTemplateId;
-    }
-
-    public void setSourceTemplateId(Long sourceTemplateId) {
-        this.sourceTemplateId = sourceTemplateId;
-    }
-
-    @Override
-    public String getTemplateTag() {
-        return templateTag;
-    }
-
-    public void setTemplateTag(String templateTag) {
-        this.templateTag = templateTag;
-    }
-
-    @Override
-    public long getDomainId() {
-        return -1;
-    }
-
-    public void setAccountId(long accountId) {
-        this.accountId = accountId;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public Map<String, String> getDetails() {
-        return details;
-    }
-
-    public void setDetails(Map<String, String> details) {
-        this.details = details;
-    }
-
-    @Override
-    public boolean equals(Object that) {
-        if (this == that) {
-            return true;
-        }
-        if (!(that instanceof VMTemplateVO)) {
-            return false;
-        }
-        VMTemplateVO other = (VMTemplateVO)that;
-
-        return ((getUniqueName().equals(other.getUniqueName())));
-    }
-
-    @Override
-    public int hashCode() {
-        return uniqueName.hashCode();
-    }
-
-    @Transient
-    String toString;
-
-    @Override
-    public String toString() {
-        if (toString == null) {
-            toString = new StringBuilder("Tmpl[").append(id).append("-").append(format).append("-").append(uniqueName).toString();
-        }
-        return toString;
-    }
-
-    public void setRemoved(Date removed) {
-        this.removed = removed;
-    }
-
-    public void setSortKey(int key) {
-        sortKey = key;
-    }
-
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    public void setDynamicallyScalable(boolean dynamicallyScalable) {
-        this.dynamicallyScalable = dynamicallyScalable;
-    }
-
-    @Override
-    public boolean isDynamicallyScalable() {
-        return dynamicallyScalable;
-    }
-
-    @Override
-    public boolean getEnableSshKey() {
-        return enableSshKey;
-    }
-
-    public void setEnableSshKey(boolean enable) {
-        enableSshKey = enable;
-    }
-
-    public void setSize(Long size) {
-        this.size = size;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    @Override
-    public long getUpdatedCount() {
-        return updatedCount;
-    }
-
-    @Override
-    public void incrUpdatedCount() {
-        updatedCount++;
-    }
-
-    public void decrUpdatedCount() {
-        updatedCount--;
-    }
-
-    @Override
-    public Date getUpdated() {
-        return updated;
-    }
-
-    public void setUpdated(Date updated) {
-        this.updated = updated;
-    }
-
-    public boolean isDirectDownload() {
-        return directDownload;
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return VirtualMachineTemplate.class;
-    }
-
-    @Override
-    public Long getParentTemplateId() {
-        return parentTemplateId;
-    }
-
-    public void setParentTemplateId(Long parentTemplateId) {
-        this.parentTemplateId = parentTemplateId;
-    }
-
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java
deleted file mode 100644
index 41993b6..0000000
--- a/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import javax.persistence.EntityExistsException;
-
-import org.springframework.stereotype.Component;
-
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.offering.DiskOffering.Type;
-import com.cloud.utils.db.Attribute;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-
-@Component
-public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> implements DiskOfferingDao {
-    private final SearchBuilder<DiskOfferingVO> DomainIdSearch;
-    private final SearchBuilder<DiskOfferingVO> PrivateDiskOfferingSearch;
-    private final SearchBuilder<DiskOfferingVO> PublicDiskOfferingSearch;
-    protected final SearchBuilder<DiskOfferingVO> UniqueNameSearch;
-    private final Attribute _typeAttr;
-
-    protected DiskOfferingDaoImpl() {
-        DomainIdSearch = createSearchBuilder();
-        DomainIdSearch.and("domainId", DomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
-        DomainIdSearch.and("removed", DomainIdSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-        DomainIdSearch.done();
-
-        PrivateDiskOfferingSearch = createSearchBuilder();
-        PrivateDiskOfferingSearch.and("diskSize", PrivateDiskOfferingSearch.entity().getDiskSize(), SearchCriteria.Op.EQ);
-        PrivateDiskOfferingSearch.done();
-
-        PublicDiskOfferingSearch = createSearchBuilder();
-        PublicDiskOfferingSearch.and("domainId", PublicDiskOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
-        PublicDiskOfferingSearch.and("system", PublicDiskOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.EQ);
-        PublicDiskOfferingSearch.and("removed", PublicDiskOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-        PublicDiskOfferingSearch.done();
-
-        UniqueNameSearch = createSearchBuilder();
-        UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
-        UniqueNameSearch.done();
-
-        _typeAttr = _allAttributes.get("type");
-    }
-
-    @Override
-    public List<DiskOfferingVO> listByDomainId(long domainId) {
-        SearchCriteria<DiskOfferingVO> sc = DomainIdSearch.create();
-        sc.setParameters("domainId", domainId);
-        // FIXME: this should not be exact match, but instead should find all
-        // available disk offerings from parent domains
-        return listBy(sc);
-    }
-
-    @Override
-    public List<DiskOfferingVO> findPrivateDiskOffering() {
-        SearchCriteria<DiskOfferingVO> sc = PrivateDiskOfferingSearch.create();
-        sc.setParameters("diskSize", 0);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<DiskOfferingVO> searchIncludingRemoved(SearchCriteria<DiskOfferingVO> sc, final Filter filter, final Boolean lock, final boolean cache) {
-        sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
-        return super.searchIncludingRemoved(sc, filter, lock, cache);
-    }
-
-    @Override
-    public <K> List<K> customSearchIncludingRemoved(SearchCriteria<K> sc, final Filter filter) {
-        sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
-        return super.customSearchIncludingRemoved(sc, filter);
-    }
-
-    @Override
-    protected List<DiskOfferingVO> executeList(final String sql, final Object... params) {
-        StringBuilder builder = new StringBuilder(sql);
-        int index = builder.indexOf("WHERE");
-        if (index == -1) {
-            builder.append(" WHERE type=?");
-        } else {
-            builder.insert(index + 6, "type=? ");
-        }
-
-        return super.executeList(sql, Type.Disk, params);
-    }
-
-    @Override
-    public List<DiskOfferingVO> findPublicDiskOfferings() {
-        SearchCriteria<DiskOfferingVO> sc = PublicDiskOfferingSearch.create();
-        sc.setParameters("system", false);
-        return listBy(sc);
-    }
-
-    @Override
-    public DiskOfferingVO findByUniqueName(String uniqueName) {
-        SearchCriteria<DiskOfferingVO> sc = UniqueNameSearch.create();
-        sc.setParameters("name", uniqueName);
-        List<DiskOfferingVO> vos = search(sc, null, null, false);
-        if (vos.size() == 0) {
-            return null;
-        }
-
-        return vos.get(0);
-    }
-
-    @Override
-    public DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering) {
-        assert offering.getUniqueName() != null : "unique name shouldn't be null for the disk offering";
-        DiskOfferingVO vo = findByUniqueName(offering.getUniqueName());
-        if (vo != null) {
-            return vo;
-        }
-        try {
-            return persist(offering);
-        } catch (EntityExistsException e) {
-            // Assume it's conflict on unique name
-            return findByUniqueName(offering.getUniqueName());
-        }
-    }
-
-    @Override
-    public boolean remove(Long id) {
-        DiskOfferingVO diskOffering = createForUpdate();
-        diskOffering.setRemoved(new Date());
-
-        return update(id, diskOffering);
-    }
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java
deleted file mode 100755
index 1c11f9b..0000000
--- a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.util.List;
-
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Type;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.fsm.StateDao;
-
-public interface SnapshotDao extends GenericDao<SnapshotVO, Long>, StateDao<Snapshot.State, Snapshot.Event, SnapshotVO> {
-    List<SnapshotVO> listByVolumeId(long volumeId);
-
-    List<SnapshotVO> listByVolumeId(Filter filter, long volumeId);
-
-    SnapshotVO findNextSnapshot(long parentSnapId);
-
-    long getLastSnapshot(long volumeId, DataStoreRole role);
-
-    List<SnapshotVO> listByVolumeIdType(long volumeId, Type type);
-
-    List<SnapshotVO> listByVolumeIdTypeNotDestroyed(long volumeId, Type type);
-
-    List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId);
-
-    List<SnapshotVO> listByBackupUuid(long volumeId, String backupUuid);
-
-    long updateSnapshotVersion(long volumeId, String from, String to);
-
-    List<SnapshotVO> listByVolumeIdVersion(long volumeId, String version);
-
-    Long getSecHostId(long volumeId);
-
-    long updateSnapshotSecHost(long dcId, long secHostId);
-
-    public Long countSnapshotsForAccount(long accountId);
-
-    List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status);
-
-    List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status);
-
-    List<SnapshotVO> listAllByStatus(Snapshot.State... status);
-
-    void updateVolumeIds(long oldVolId, long newVolId);
-
-    List<SnapshotVO> listByStatusNotIn(long volumeId, Snapshot.State... status);
-
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java
deleted file mode 100755
index 560edc9..0000000
--- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java
+++ /dev/null
@@ -1,369 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.List;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Event;
-import com.cloud.storage.Snapshot.State;
-import com.cloud.storage.Snapshot.Type;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UpdateBuilder;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao {
-    public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName());
-    // TODO: we should remove these direct sqls
-    private static final String GET_LAST_SNAPSHOT =
-        "SELECT snapshots.id FROM snapshot_store_ref, snapshots where snapshots.id = snapshot_store_ref.snapshot_id AND snapshosts.volume_id = ? AND snapshot_store_ref.role = ? ORDER BY created DESC";
-    private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?";
-    private static final String GET_SECHOST_ID =
-        "SELECT store_id FROM snapshots, snapshot_store_ref where snapshots.id = snapshot_store_ref.snapshot_id AND volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1";
-    private static final String UPDATE_SECHOST_ID = "UPDATE snapshots SET sechost_id = ? WHERE data_center_id = ?";
-
-    private SearchBuilder<SnapshotVO> VolumeIdSearch;
-    private SearchBuilder<SnapshotVO> VolumeIdTypeSearch;
-    private SearchBuilder<SnapshotVO> VolumeIdTypeNotDestroyedSearch;
-    private SearchBuilder<SnapshotVO> ParentIdSearch;
-    private SearchBuilder<SnapshotVO> backupUuidSearch;
-    private SearchBuilder<SnapshotVO> VolumeIdVersionSearch;
-    private SearchBuilder<SnapshotVO> AccountIdSearch;
-    private SearchBuilder<SnapshotVO> InstanceIdSearch;
-    private SearchBuilder<SnapshotVO> StatusSearch;
-    private SearchBuilder<SnapshotVO> notInStatusSearch;
-    private GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount;
-    @Inject
-    ResourceTagDao _tagsDao;
-    @Inject
-    protected VMInstanceDao _instanceDao;
-    @Inject
-    protected VolumeDao _volumeDao;
-
-    @Override
-    public SnapshotVO findNextSnapshot(long snapshotId) {
-        SearchCriteria<SnapshotVO> sc = ParentIdSearch.create();
-        sc.setParameters("prevSnapshotId", snapshotId);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<SnapshotVO> listByBackupUuid(long volumeId, String backupUuid) {
-        SearchCriteria<SnapshotVO> sc = backupUuidSearch.create();
-        sc.setParameters("backupUuid", backupUuid);
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeIdType(long volumeId, Type type) {
-        return listByVolumeIdType(null, volumeId, type);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeIdTypeNotDestroyed(long volumeId, Type type) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdTypeNotDestroyedSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        sc.setParameters("type", type.ordinal());
-        sc.setParameters("status", State.Destroyed);
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeIdVersion(long volumeId, String version) {
-        return listByVolumeIdVersion(null, volumeId, version);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeId(long volumeId) {
-        return listByVolumeId(null, volumeId);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeId(Filter filter, long volumeId) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        return listBy(sc, filter);
-    }
-
-    @Override
-    public List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        return listIncludingRemovedBy(sc, null);
-    }
-
-    public List<SnapshotVO> listByVolumeIdType(Filter filter, long volumeId, Type type) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdTypeSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        sc.setParameters("type", type.ordinal());
-        return listBy(sc, filter);
-    }
-
-    public List<SnapshotVO> listByVolumeIdVersion(Filter filter, long volumeId, String version) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdVersionSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        sc.setParameters("version", version);
-        return listBy(sc, filter);
-    }
-
-    public SnapshotDaoImpl() {
-    }
-
-    @PostConstruct
-    protected void init() {
-        VolumeIdSearch = createSearchBuilder();
-        VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        VolumeIdSearch.done();
-
-        VolumeIdTypeSearch = createSearchBuilder();
-        VolumeIdTypeSearch.and("volumeId", VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ);
-        VolumeIdTypeSearch.done();
-
-        VolumeIdTypeNotDestroyedSearch = createSearchBuilder();
-        VolumeIdTypeNotDestroyedSearch.and("volumeId", VolumeIdTypeNotDestroyedSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        VolumeIdTypeNotDestroyedSearch.and("type", VolumeIdTypeNotDestroyedSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ);
-        VolumeIdTypeNotDestroyedSearch.and("status", VolumeIdTypeNotDestroyedSearch.entity().getState(), SearchCriteria.Op.NEQ);
-        VolumeIdTypeNotDestroyedSearch.done();
-
-        VolumeIdVersionSearch = createSearchBuilder();
-        VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ);
-        VolumeIdVersionSearch.done();
-        /*
-         * ParentIdSearch = createSearchBuilder();
-         * ParentIdSearch.and("prevSnapshotId",
-         * ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ);
-         * ParentIdSearch.done();
-         *
-         * backupUuidSearch = createSearchBuilder();
-         * backupUuidSearch.and("backupUuid",
-         * backupUuidSearch.entity().getBackupSnapshotId(),
-         * SearchCriteria.Op.EQ); backupUuidSearch.done();
-         */
-        AccountIdSearch = createSearchBuilder();
-        AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountIdSearch.done();
-
-        StatusSearch = createSearchBuilder();
-        StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN);
-        StatusSearch.done();
-
-        notInStatusSearch  = createSearchBuilder();
-        notInStatusSearch.and("volumeId", notInStatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        notInStatusSearch.and("status", notInStatusSearch.entity().getState(), SearchCriteria.Op.NOTIN);
-        notInStatusSearch.done();
-
-        CountSnapshotsByAccount = createSearchBuilder(Long.class);
-        CountSnapshotsByAccount.select(null, Func.COUNT, null);
-        CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
-        CountSnapshotsByAccount.and("status", CountSnapshotsByAccount.entity().getState(), SearchCriteria.Op.NIN);
-        CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
-        CountSnapshotsByAccount.done();
-
-        InstanceIdSearch = createSearchBuilder();
-        InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
-
-        SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
-        instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
-
-        SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
-        volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
-        volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
-
-        InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
-        InstanceIdSearch.done();
-    }
-
-    @Override
-    public Long getSecHostId(long volumeId) {
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_SECHOST_ID;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, volumeId);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                return rs.getLong(1);
-            }
-        } catch (Exception ex) {
-            s_logger.info("[ignored]"
-                    + "caught something while getting sec. host id: " + ex.getLocalizedMessage());
-        }
-        return null;
-    }
-
-    @Override
-    public long getLastSnapshot(long volumeId, DataStoreRole role) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_LAST_SNAPSHOT;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, volumeId);
-            pstmt.setString(2, role.toString());
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                return rs.getLong(1);
-            }
-        } catch (Exception ex) {
-            s_logger.error("error getting last snapshot", ex);
-        }
-        return 0;
-    }
-
-    @Override
-    public long updateSnapshotVersion(long volumeId, String from, String to) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = UPDATE_SNAPSHOT_VERSION;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setString(1, to);
-            pstmt.setLong(2, volumeId);
-            pstmt.setString(3, from);
-            pstmt.executeUpdate();
-            return 1;
-        } catch (Exception ex) {
-            s_logger.error("error getting last snapshot", ex);
-        }
-        return 0;
-    }
-
-    @Override
-    public long updateSnapshotSecHost(long dcId, long secHostId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = UPDATE_SECHOST_ID;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, secHostId);
-            pstmt.setLong(2, dcId);
-            pstmt.executeUpdate();
-            return 1;
-        } catch (Exception ex) {
-            s_logger.error("error set secondary storage host id", ex);
-        }
-        return 0;
-    }
-
-    @Override
-    public Long countSnapshotsForAccount(long accountId) {
-        SearchCriteria<Long> sc = CountSnapshotsByAccount.create();
-        sc.setParameters("account", accountId);
-        sc.setParameters("status", State.Error, State.Destroyed);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status) {
-        SearchCriteria<SnapshotVO> sc = InstanceIdSearch.create();
-
-        if (status != null && status.length != 0) {
-            sc.setParameters("status", (Object[])status);
-        }
-
-        sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready);
-        sc.setJoinParameters("instanceVolumes", "instanceId", instanceId);
-        return listBy(sc, null);
-    }
-
-    @Override
-    public List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status) {
-        SearchCriteria<SnapshotVO> sc = StatusSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        sc.setParameters("status", (Object[])status);
-        return listBy(sc, null);
-    }
-
-    @Override
-    @DB
-    public boolean remove(Long id) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        SnapshotVO entry = findById(id);
-        if (entry != null) {
-            _tagsDao.removeByIdAndType(id, ResourceObjectType.Snapshot);
-        }
-        boolean result = super.remove(id);
-        txn.commit();
-        return result;
-    }
-
-    @Override
-    public List<SnapshotVO> listAllByStatus(Snapshot.State... status) {
-        SearchCriteria<SnapshotVO> sc = StatusSearch.create();
-        sc.setParameters("status", (Object[])status);
-        return listBy(sc, null);
-    }
-
-    @Override
-    public boolean updateState(State currentState, Event event, State nextState, SnapshotVO snapshot, Object data) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        SnapshotVO snapshotVO = snapshot;
-        snapshotVO.setState(nextState);
-        super.update(snapshotVO.getId(), snapshotVO);
-        txn.commit();
-        return true;
-    }
-
-    @Override
-    public void updateVolumeIds(long oldVolId, long newVolId) {
-        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
-        sc.setParameters("volumeId", oldVolId);
-        SnapshotVO snapshot = createForUpdate();
-        snapshot.setVolumeId(newVolId);
-        UpdateBuilder ub = getUpdateBuilder(snapshot);
-        update(ub, sc, null);
-    }
-
-    @Override
-    public List<SnapshotVO> listByStatusNotIn(long volumeId, Snapshot.State... status) {
-        SearchCriteria<SnapshotVO> sc = this.notInStatusSearch.create();
-        sc.setParameters("volumeId", volumeId);
-        sc.setParameters("status", (Object[]) status);
-        return listBy(sc, null);
-    }
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
deleted file mode 100644
index bffe209..0000000
--- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-
-@Component
-public class VMTemplateZoneDaoImpl extends GenericDaoBase<VMTemplateZoneVO, Long> implements VMTemplateZoneDao {
-    public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName());
-
-    protected final SearchBuilder<VMTemplateZoneVO> ZoneSearch;
-    protected final SearchBuilder<VMTemplateZoneVO> TemplateSearch;
-    protected final SearchBuilder<VMTemplateZoneVO> ZoneTemplateSearch;
-
-    public VMTemplateZoneDaoImpl() {
-        ZoneSearch = createSearchBuilder();
-        ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
-        ZoneSearch.done();
-
-        TemplateSearch = createSearchBuilder();
-        TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
-        TemplateSearch.done();
-
-        ZoneTemplateSearch = createSearchBuilder();
-        ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
-        ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
-        ZoneTemplateSearch.done();
-    }
-
-    @Override
-    public List<VMTemplateZoneVO> listByZoneId(long id) {
-        SearchCriteria<VMTemplateZoneVO> sc = ZoneSearch.create();
-        sc.setParameters("zone_id", id);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<VMTemplateZoneVO> listByTemplateId(long templateId) {
-        SearchCriteria<VMTemplateZoneVO> sc = TemplateSearch.create();
-        sc.setParameters("template_id", templateId);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId) {
-        SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
-        sc.setParameters("zone_id", zoneId);
-        sc.setParameters("template_id", templateId);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId) {
-        SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
-        if (zoneId != null) {
-            sc.setParameters("zone_id", zoneId);
-        }
-        sc.setParameters("template_id", templateId);
-        return listBy(sc);
-    }
-
-    @Override
-    public void deletePrimaryRecordsForTemplate(long templateId) {
-        SearchCriteria<VMTemplateZoneVO> sc = TemplateSearch.create();
-        sc.setParameters("template_id", templateId);
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        remove(sc);
-        txn.commit();
-
-    }
-
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java
deleted file mode 100644
index a05dc1f..0000000
--- a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.fsm.StateDao;
-
-public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.State, Volume.Event, Volume> {
-
-    List<VolumeVO> findDetachedByAccount(long accountId);
-
-    List<VolumeVO> findByAccount(long accountId);
-
-    Pair<Long, Long> getCountAndTotalByPool(long poolId);
-
-    Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId);
-
-    long getVMSnapshotSizeByPool(long poolId);
-
-    List<VolumeVO> findByInstance(long id);
-
-    List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
-
-    List<VolumeVO> findByInstanceIdDestroyed(long vmId);
-
-    List<VolumeVO> findByPod(long podId);
-
-    List<VolumeVO> findByDc(long dcId);
-
-    List<VolumeVO> findByAccountAndPod(long accountId, long podId);
-
-    List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId);
-
-    void deleteVolumesByInstance(long instanceId);
-
-    void attachVolume(long volumeId, long vmId, long deviceId);
-
-    void detachVolume(long volumeId);
-
-    boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId);
-
-    List<VolumeVO> findCreatedByInstance(long id);
-
-    List<VolumeVO> findByPoolId(long poolId);
-
-    VolumeVO findByPoolIdName(long poolId, String name);
-
-    List<VolumeVO> findByPoolId(long poolId, Volume.Type volumeType);
-
-    List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
-
-    List<VolumeVO> findUsableVolumesForInstance(long instanceId);
-
-    Long countAllocatedVolumesForAccount(long accountId);
-
-    HypervisorType getHypervisorType(long volumeId);
-
-    List<VolumeVO> listVolumesToBeDestroyed();
-
-    List<VolumeVO> listVolumesToBeDestroyed(Date date);
-
-    ImageFormat getImageFormat(Long volumeId);
-
-    List<VolumeVO> findReadyRootVolumesByInstance(long instanceId);
-
-    List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId);
-
-    List<Long> listZoneWidePoolIdsByVolumeCount(long dcId, long accountId);
-
-    /**
-     * Gets the Total Primary Storage space allocated for an account
-     *
-     * @param account
-     * @param list of ids of virtual router VMs under this account
-     * @return total Primary Storage space (in bytes) used
-     */
-    long primaryStorageUsedForAccount(long accountId, List<Long> virtualRouters);
-
-    /**
-     * Gets the Total Secondary Storage space used by volumes allocated for an
-     * account
-     *
-     * @param account
-     * @return total Secondary Storage space (in bytes) used
-     */
-    long secondaryStorageUsedForAccount(long accountId);
-
-    /***
-     *
-     * @param volumeId
-     * @return the scope of the storage pool where the volume is present (ZONE/CLUSTER)
-     */
-    ScopeType getVolumeStoragePoolScope(long volumeId);
-
-    /***
-     * Updates the destVol uuid with srcVol uuid and sets the srcVol uuid as null.
-     * @param srcVolId
-     * @param destVolId
-     * @return returns true if transaction is successful.
-     */
-    boolean updateUuid(long srcVolId, long destVolId);
-}
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java
deleted file mode 100644
index f691e30..0000000
--- a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java
+++ /dev/null
@@ -1,688 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.Event;
-import com.cloud.storage.Volume.State;
-import com.cloud.storage.Volume.Type;
-import com.cloud.storage.VolumeVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UpdateBuilder;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements VolumeDao {
-    private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
-    protected final SearchBuilder<VolumeVO> DetachedAccountIdSearch;
-    protected final SearchBuilder<VolumeVO> TemplateZoneSearch;
-    protected final GenericSearchBuilder<VolumeVO, SumCount> TotalSizeByPoolSearch;
-    protected final GenericSearchBuilder<VolumeVO, SumCount> TotalVMSnapshotSizeByPoolSearch;
-    protected final GenericSearchBuilder<VolumeVO, Long> ActiveTemplateSearch;
-    protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
-    protected final SearchBuilder<VolumeVO> AllFieldsSearch;
-    protected GenericSearchBuilder<VolumeVO, Long> CountByAccount;
-    protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch;
-    protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch2;
-    protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
-    @Inject
-    ResourceTagDao _tagsDao;
-
-    protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
-    // need to account for zone-wide primary storage where storage_pool has
-    // null-value pod and cluster, where hypervisor information is stored in
-    // storage_pool
-    protected static final String SELECT_HYPERTYPE_FROM_CLUSTER_VOLUME =
-        "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?";
-    protected static final String SELECT_HYPERTYPE_FROM_ZONE_VOLUME = "SELECT s.hypervisor from volumes v, storage_pool s where v.pool_id = s.id and v.id = ?";
-    protected static final String SELECT_POOLSCOPE = "SELECT s.scope from storage_pool s, volumes v where s.id = v.pool_id and v.id = ?";
-
-    private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT =
-        "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? "
-            + " AND pool.pod_id = ? AND pool.cluster_id = ? " + " GROUP BY pool.id ORDER BY 2 ASC ";
-    private static final String ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT =
-        "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? "
-            + " AND pool.scope = 'ZONE' AND pool.status='Up' " + " GROUP BY pool.id ORDER BY 2 ASC ";
-
-    @Override
-    public List<VolumeVO> findDetachedByAccount(long accountId) {
-        SearchCriteria<VolumeVO> sc = DetachedAccountIdSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("destroyed", Volume.State.Destroy);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByAccount(long accountId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("accountId", accountId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByInstance(long id) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", id);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", instanceId);
-        sc.setParameters("deviceId", deviceId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByPoolId(long poolId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("poolId", poolId);
-        sc.setParameters("notDestroyed", Volume.State.Destroy);
-        sc.setParameters("vType", Volume.Type.ROOT.toString());
-        return listBy(sc);
-    }
-
-    @Override
-    public VolumeVO findByPoolIdName(long poolId, String name) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("poolId", poolId);
-        sc.setParameters("name", name);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByPoolId(long poolId, Volume.Type volumeType) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("poolId", poolId);
-        sc.setParameters("notDestroyed", Volume.State.Destroy);
-
-        if (volumeType != null) {
-            sc.setParameters("vType", volumeType.toString());
-        }
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findCreatedByInstance(long id) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", id);
-        sc.setParameters("state", Volume.State.Ready);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findUsableVolumesForInstance(long instanceId) {
-        SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create();
-        sc.setParameters("instance", instanceId);
-        sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByInstanceAndType(long id, Type vType) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", id);
-        sc.setParameters("vType", vType.toString());
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByInstanceIdDestroyed(long vmId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", vmId);
-        sc.setParameters("destroyed", Volume.State.Destroy);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findReadyRootVolumesByInstance(long instanceId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", instanceId);
-        sc.setParameters("state", Volume.State.Ready);
-        sc.setParameters("vType", Volume.Type.ROOT);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByPod(long podId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("pod", podId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByDc(long dcId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("dcId", dcId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByAccountAndPod(long accountId, long podId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("pod", podId);
-        sc.setParameters("state", Volume.State.Ready);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId) {
-        SearchCriteria<VolumeVO> sc = TemplateZoneSearch.create();
-        sc.setParameters("template", templateId);
-        sc.setParameters("zone", zoneId);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) {
-        SearchCriteria<Long> sc = ActiveTemplateSearch.create();
-        sc.setParameters("template", templateId);
-        sc.setParameters("pool", poolId);
-
-        List<Long> results = customSearchIncludingRemoved(sc, null);
-        assert results.size() > 0 : "How can this return a size of " + results.size();
-
-        return results.get(0) > 0;
-    }
-
-    @Override
-    public void deleteVolumesByInstance(long instanceId) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", instanceId);
-        expunge(sc);
-    }
-
-    @Override
-    public void attachVolume(long volumeId, long vmId, long deviceId) {
-        VolumeVO volume = createForUpdate(volumeId);
-        volume.setInstanceId(vmId);
-        volume.setDeviceId(deviceId);
-        volume.setUpdated(new Date());
-        volume.setAttached(new Date());
-        if (deviceId == 0L) {
-            volume.setVolumeType(Type.ROOT);
-        }
-        update(volumeId, volume);
-    }
-
-    @Override
-    public void detachVolume(long volumeId) {
-        VolumeVO volume = createForUpdate(volumeId);
-        volume.setInstanceId(null);
-        volume.setDeviceId(null);
-        volume.setUpdated(new Date());
-        volume.setAttached(null);
-        if (findById(volumeId).getVolumeType() == Type.ROOT) {
-            volume.setVolumeType(Type.DATADISK);
-        }
-        update(volumeId, volume);
-    }
-
-    @Override
-    @DB
-    public HypervisorType getHypervisorType(long volumeId) {
-        /* lookup from cluster of pool */
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = null;
-        try {
-            ScopeType scope = getVolumeStoragePoolScope(volumeId);
-            if (scope != null) {
-                if (scope == ScopeType.CLUSTER || scope == ScopeType.HOST)
-                    sql = SELECT_HYPERTYPE_FROM_CLUSTER_VOLUME;
-                else if (scope == ScopeType.ZONE)
-                    sql = SELECT_HYPERTYPE_FROM_ZONE_VOLUME;
-                else
-                    s_logger.error("Unhandled scope type '" + scope + "' when running getHypervisorType on volume id " + volumeId);
-
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setLong(1, volumeId);
-                ResultSet rs = pstmt.executeQuery();
-                if (rs.next()) {
-                    if (rs.getString(1) != null) {
-                        return HypervisorType.getType(rs.getString(1));
-                    }
-                }
-            }
-            return HypervisorType.None;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + sql, e);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Caught: " + sql, e);
-        }
-    }
-
-    @Override
-    public ImageFormat getImageFormat(Long volumeId) {
-        HypervisorType type = getHypervisorType(volumeId);
-        if (type.equals(HypervisorType.KVM)) {
-            return ImageFormat.QCOW2;
-        } else if (type.equals(HypervisorType.XenServer)) {
-            return ImageFormat.VHD;
-        } else if (type.equals(HypervisorType.VMware)) {
-            return ImageFormat.OVA;
-        } else {
-            s_logger.warn("Do not support hypervisor " + type.toString());
-            return null;
-        }
-    }
-
-    public VolumeDaoImpl() {
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
-        AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
-        AllFieldsSearch.and("dcId", AllFieldsSearch.entity().getDataCenterId(), Op.EQ);
-        AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ);
-        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ);
-        AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
-        AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ);
-        AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ);
-        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
-        AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ);
-        AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ);
-        AllFieldsSearch.and("updateTime", AllFieldsSearch.entity().getUpdated(), SearchCriteria.Op.LT);
-        AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ);
-        AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ);
-        AllFieldsSearch.done();
-
-        DetachedAccountIdSearch = createSearchBuilder();
-        DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ);
-        DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ);
-        DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL);
-        DetachedAccountIdSearch.done();
-
-        TemplateZoneSearch = createSearchBuilder();
-        TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ);
-        TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ);
-        TemplateZoneSearch.done();
-
-        TotalSizeByPoolSearch = createSearchBuilder(SumCount.class);
-        TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize());
-        TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null);
-        TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ);
-        TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL);
-        TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ);
-        TotalSizeByPoolSearch.done();
-
-        TotalVMSnapshotSizeByPoolSearch = createSearchBuilder(SumCount.class);
-        TotalVMSnapshotSizeByPoolSearch.select("sum", Func.SUM, TotalVMSnapshotSizeByPoolSearch.entity().getVmSnapshotChainSize());
-        TotalVMSnapshotSizeByPoolSearch.and("poolId", TotalVMSnapshotSizeByPoolSearch.entity().getPoolId(), Op.EQ);
-        TotalVMSnapshotSizeByPoolSearch.and("removed", TotalVMSnapshotSizeByPoolSearch.entity().getRemoved(), Op.NULL);
-        TotalVMSnapshotSizeByPoolSearch.and("state", TotalVMSnapshotSizeByPoolSearch.entity().getState(), Op.NEQ);
-        TotalVMSnapshotSizeByPoolSearch.and("vType", TotalVMSnapshotSizeByPoolSearch.entity().getVolumeType(), Op.EQ);
-        TotalVMSnapshotSizeByPoolSearch.and("instanceId", TotalVMSnapshotSizeByPoolSearch.entity().getInstanceId(), Op.NNULL);
-        TotalVMSnapshotSizeByPoolSearch.done();
-
-        ActiveTemplateSearch = createSearchBuilder(Long.class);
-        ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ);
-        ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ);
-        ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL);
-        ActiveTemplateSearch.select(null, Func.COUNT, null);
-        ActiveTemplateSearch.done();
-
-        InstanceStatesSearch = createSearchBuilder();
-        InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ);
-        InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN);
-        InstanceStatesSearch.done();
-
-        CountByAccount = createSearchBuilder(Long.class);
-        CountByAccount.select(null, Func.COUNT, null);
-        CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
-        CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
-        CountByAccount.and("displayVolume", CountByAccount.entity().isDisplayVolume(), Op.EQ);
-        CountByAccount.done();
-
-        primaryStorageSearch = createSearchBuilder(SumCount.class);
-        primaryStorageSearch.select("sum", Func.SUM, primaryStorageSearch.entity().getSize());
-        primaryStorageSearch.and("accountId", primaryStorageSearch.entity().getAccountId(), Op.EQ);
-        primaryStorageSearch.and().op("path", primaryStorageSearch.entity().getPath(), Op.NNULL);
-        primaryStorageSearch.or("states", primaryStorageSearch.entity().getState(), Op.IN);
-        primaryStorageSearch.cp();
-        primaryStorageSearch.and("displayVolume", primaryStorageSearch.entity().isDisplayVolume(), Op.EQ);
-        primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL);
-        primaryStorageSearch.done();
-
-        primaryStorageSearch2 = createSearchBuilder(SumCount.class);
-        primaryStorageSearch2.select("sum", Func.SUM, primaryStorageSearch2.entity().getSize());
-        primaryStorageSearch2.and("accountId", primaryStorageSearch2.entity().getAccountId(), Op.EQ);
-        primaryStorageSearch2.and().op("instanceId", primaryStorageSearch2.entity().getInstanceId(), Op.NULL);
-        primaryStorageSearch2.or("virtualRouterVmIds", primaryStorageSearch2.entity().getInstanceId(), Op.NIN);
-        primaryStorageSearch2.cp();
-        primaryStorageSearch2.and().op("path", primaryStorageSearch2.entity().getPath(), Op.NNULL);
-        primaryStorageSearch2.or("states", primaryStorageSearch2.entity().getState(), Op.IN);
-        primaryStorageSearch2.cp();
-        primaryStorageSearch2.and("displayVolume", primaryStorageSearch2.entity().isDisplayVolume(), Op.EQ);
-        primaryStorageSearch2.and("isRemoved", primaryStorageSearch2.entity().getRemoved(), Op.NULL);
-        primaryStorageSearch2.done();
-
-        secondaryStorageSearch = createSearchBuilder(SumCount.class);
-        secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize());
-        secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ);
-        secondaryStorageSearch.and("path", secondaryStorageSearch.entity().getPath(), Op.NULL);
-        secondaryStorageSearch.and("states", secondaryStorageSearch.entity().getState(), Op.NIN);
-        secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL);
-        secondaryStorageSearch.done();
-    }
-
-    @Override
-    @DB()
-    public Pair<Long, Long> getCountAndTotalByPool(long poolId) {
-        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
-        sc.setParameters("poolId", poolId);
-        List<SumCount> results = customSearch(sc, null);
-        SumCount sumCount = results.get(0);
-        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
-    }
-
-    @Override
-    public Long countAllocatedVolumesForAccount(long accountId) {
-        SearchCriteria<Long> sc = CountByAccount.create();
-        sc.setParameters("account", accountId);
-        sc.setParameters("state", Volume.State.Destroy);
-        sc.setParameters("displayVolume", 1);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public long primaryStorageUsedForAccount(long accountId, List<Long> virtualRouters) {
-        SearchCriteria<SumCount> sc;
-        if (!virtualRouters.isEmpty()) {
-            sc = primaryStorageSearch2.create();
-            sc.setParameters("virtualRouterVmIds", virtualRouters.toArray(new Object[virtualRouters.size()]));
-        } else {
-            sc = primaryStorageSearch.create();
-        }
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("states", State.Allocated);
-        sc.setParameters("displayVolume", 1);
-        List<SumCount> storageSpace = customSearch(sc, null);
-        if (storageSpace != null) {
-            return storageSpace.get(0).sum;
-        } else {
-            return 0;
-        }
-    }
-
-    @Override
-    public long secondaryStorageUsedForAccount(long accountId) {
-        SearchCriteria<SumCount> sc = secondaryStorageSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("states", State.Allocated);
-        List<SumCount> storageSpace = customSearch(sc, null);
-        if (storageSpace != null) {
-            return storageSpace.get(0).sum;
-        } else {
-            return 0;
-        }
-    }
-
-    public static class SumCount {
-        public long sum;
-        public long count;
-
-        public SumCount() {
-        }
-    }
-
-    @Override
-    public List<VolumeVO> listVolumesToBeDestroyed() {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("state", Volume.State.Destroy);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<VolumeVO> listVolumesToBeDestroyed(Date date) {
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("state", Volume.State.Destroy);
-        sc.setParameters("updateTime", date);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public boolean updateState(com.cloud.storage.Volume.State currentState, Event event, com.cloud.storage.Volume.State nextState, Volume vo, Object data) {
-
-        Long oldUpdated = vo.getUpdatedCount();
-        Date oldUpdatedTime = vo.getUpdated();
-
-        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
-        sc.setParameters("id", vo.getId());
-        sc.setParameters("state", currentState);
-        sc.setParameters("updatedCount", vo.getUpdatedCount());
-
-        vo.incrUpdatedCount();
-
-        UpdateBuilder builder = getUpdateBuilder(vo);
-        builder.set(vo, "state", nextState);
-        builder.set(vo, "updated", new Date());
-
-        int rows = update((VolumeVO)vo, sc);
-        if (rows == 0 && s_logger.isDebugEnabled()) {
-            VolumeVO dbVol = findByIdIncludingRemoved(vo.getId());
-            if (dbVol != null) {
-                StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
-                str.append(": DB Data={id=")
-                    .append(dbVol.getId())
-                    .append("; state=")
-                    .append(dbVol.getState())
-                    .append("; updatecount=")
-                    .append(dbVol.getUpdatedCount())
-                    .append(";updatedTime=")
-                    .append(dbVol.getUpdated());
-                str.append(": New Data={id=")
-                    .append(vo.getId())
-                    .append("; state=")
-                    .append(nextState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(vo.getUpdatedCount())
-                    .append("; updatedTime=")
-                    .append(vo.getUpdated());
-                str.append(": stale Data={id=")
-                    .append(vo.getId())
-                    .append("; state=")
-                    .append(currentState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(oldUpdated)
-                    .append("; updatedTime=")
-                    .append(oldUpdatedTime);
-            } else {
-                s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore");
-            }
-        }
-        return rows > 0;
-    }
-
-    @Override
-    public List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        List<Long> result = new ArrayList<Long>();
-        try {
-            String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT;
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, accountId);
-            pstmt.setLong(2, dcId);
-            pstmt.setLong(3, podId);
-            pstmt.setLong(4, clusterId);
-
-            ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(rs.getLong(1));
-            }
-            return result;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
-        }
-    }
-
-    @Override
-    public List<Long> listZoneWidePoolIdsByVolumeCount(long dcId, long accountId) {
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        List<Long> result = new ArrayList<Long>();
-        try {
-            String sql = ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT;
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, accountId);
-            pstmt.setLong(2, dcId);
-
-            ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(rs.getLong(1));
-            }
-            return result;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Caught: " + ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
-        }
-    }
-
-    @Override
-    @DB()
-    public Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId) {
-        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
-        sc.setParameters("poolId", poolId);
-        sc.setParameters("state", State.Destroy);
-        List<SumCount> results = customSearch(sc, null);
-        SumCount sumCount = results.get(0);
-        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
-    }
-
-    @Override
-    public long getVMSnapshotSizeByPool(long poolId) {
-        SearchCriteria<SumCount> sc = TotalVMSnapshotSizeByPoolSearch.create();
-        sc.setParameters("poolId", poolId);
-        sc.setParameters("state", State.Destroy);
-        sc.setParameters("vType", Volume.Type.ROOT.toString());
-        List<SumCount> results = customSearch(sc, null);
-        if (results != null) {
-            return results.get(0).sum;
-        } else {
-            return 0;
-        }
-    }
-
-    @Override
-    @DB
-    public boolean remove(Long id) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        VolumeVO entry = findById(id);
-        if (entry != null) {
-            _tagsDao.removeByIdAndType(id, ResourceObjectType.Volume);
-        }
-        boolean result = super.remove(id);
-        txn.commit();
-        return result;
-    }
-
-    @Override
-    @DB
-    public boolean updateUuid(long srcVolId, long destVolId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        try {
-            VolumeVO srcVol = findById(srcVolId);
-            VolumeVO destVol = findById(destVolId);
-            String uuid = srcVol.getUuid();
-            Long instanceId = srcVol.getInstanceId();
-            srcVol.setUuid(null);
-            destVol.setUuid(uuid);
-            destVol.setInstanceId(instanceId);
-            update(srcVolId, srcVol);
-            update(destVolId, destVol);
-            _tagsDao.updateResourceId(srcVolId, destVolId, ResourceObjectType.Volume);
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Unable to persist the sequence number for this host");
-        }
-        txn.commit();
-        return true;
-    }
-
-    @Override
-    public ScopeType getVolumeStoragePoolScope(long volumeId) {
-        // finding the storage scope where the volume is present
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-
-        try {
-            String sql = SELECT_POOLSCOPE;
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, volumeId);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                String scope = rs.getString(1);
-                if (scope != null) {
-                    try {
-                        return Enum.valueOf(ScopeType.class, scope.toUpperCase());
-                    } catch (Exception e) {
-                        throw new InvalidParameterValueException("invalid scope for pool " + scope);
-                    }
-                }
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + SELECT_POOLSCOPE, e);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Caught: " + SELECT_POOLSCOPE, e);
-        }
-        return null;
-    }
-}
diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java
deleted file mode 100644
index 6111fb1..0000000
--- a/engine/schema/src/com/cloud/upgrade/DatabaseIntegrityChecker.java
+++ /dev/null
@@ -1,305 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.upgrade;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.maint.Version;
-import com.cloud.upgrade.dao.VersionDao;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.SystemIntegrityChecker;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class DatabaseIntegrityChecker extends AdapterBase implements SystemIntegrityChecker {
-    private static final Logger s_logger = Logger.getLogger(DatabaseIntegrityChecker.class);
-
-    @Inject
-    VersionDao _dao;
-
-    public DatabaseIntegrityChecker() {
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP);
-    }
-
-    /*
-     * Check if there were multiple hosts connect to the same local storage. This is from a 2.1.x bug,
-     * we didn't prevent adding host with the same IP.
-     */
-    private String formatDuplicateHostToReadText(Long poolId, ResultSet rs) throws SQLException {
-        boolean has = false;
-        StringBuffer buf = new StringBuffer();
-        String fmt = "|%1$-8s|%2$-16s|%3$-16s|%4$-24s|%5$-8s|\n";
-        String head = String.format(fmt, "id", "status", "removed", "private_ip_address", "pool_id");
-        buf.append(head);
-        while (rs.next()) {
-            String h = String.format(fmt, rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(4), poolId);
-            buf.append(h);
-            has = true;
-        }
-
-        if (!has) {
-            throw new CloudRuntimeException(
-                "Local storage with Id " +
-                    poolId +
-                    " shows there are multiple hosts connect to it, but 'select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)' returns nothing");
-        } else {
-            return buf.toString();
-        }
-    }
-
-    private Boolean checkDuplicateHostWithTheSameLocalStorage() {
-
-        TransactionLegacy txn = TransactionLegacy.open("Integrity");
-        try {
-            txn.start();
-            Connection conn = txn.getConnection();
-            try (PreparedStatement pstmt =
-                             conn.prepareStatement("SELECT pool_id FROM host INNER JOIN storage_pool_host_ref INNER JOIN storage_pool WHERE storage_pool.id = storage_pool_host_ref.pool_id and storage_pool.pool_type='LVM' AND host.id=storage_pool_host_ref.host_id AND host.removed IS NULL group by pool_id having count(*) > 1");
-                 ResultSet rs = pstmt.executeQuery();)
-            {
-                    boolean noDuplicate = true;
-                    StringBuffer helpInfo = new StringBuffer();
-                    String note =
-                        "DATABASE INTEGRITY ERROR\nManagement server detected there are some hosts connect to the same loacal storage, please contact CloudStack support team for solution. Below are detialed info, please attach all of them to CloudStack support. Thank you\n";
-                    helpInfo.append(note);
-                    while (rs.next()) {
-                        try ( PreparedStatement sel_pstmt =
-                                conn.prepareStatement("select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)");
-                        ){
-                                long poolId = rs.getLong(1);
-                                pstmt.setLong(1, poolId);
-                                try(ResultSet dhrs = sel_pstmt.executeQuery();) {
-                                    String help = formatDuplicateHostToReadText(poolId, dhrs);
-                                    helpInfo.append(help);
-                                    helpInfo.append("\n");
-                                    noDuplicate = false;
-                                }
-                                catch (Exception e)
-                                {
-                                    s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
-                                    throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
-                                }
-                        }
-                        catch (Exception e)
-                        {
-                                s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
-                                throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
-                        }
-                    }
-                    if (noDuplicate) {
-                        s_logger.debug("No duplicate hosts with the same local storage found in database");
-                    } else {
-                        s_logger.error(helpInfo.toString());
-                    }
-                    txn.commit();
-                    return noDuplicate;
-            }catch (Exception e)
-            {
-                  s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
-                  throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
-            }
-        }
-        catch (Exception e)
-        {
-            s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
-            throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
-        }
-        finally
-        {
-            try {
-                if (txn != null) {
-                    txn.close();
-                }
-            }catch(Exception e)
-            {
-                s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception:"+ e.getMessage());
-            }
-        }
-    }
-
-    private boolean check21to22PremiumUprage(Connection conn) throws SQLException {
-        try (PreparedStatement pstmt = conn.prepareStatement("show tables in cloud_usage");
-             ResultSet rs = pstmt.executeQuery();) {
-            int num = 0;
-            while (rs.next()) {
-                String tableName = rs.getString(1);
-                if (tableName.equalsIgnoreCase("usage_event") || tableName.equalsIgnoreCase("usage_port_forwarding") || tableName.equalsIgnoreCase("usage_network_offering")) {
-                    num++;
-                    s_logger.debug("Checking 21to22PremiumUprage table " + tableName + " found");
-                }
-                if (num == 3) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    private boolean isColumnExisted(Connection conn, String dbName, String tableName, String column) throws SQLException {
-        try (PreparedStatement pstmt = conn.prepareStatement(String.format("describe %1$s.%2$s", dbName, tableName));
-             ResultSet rs = pstmt.executeQuery();) {
-            boolean found = false;
-            while (rs.next()) {
-                if (column.equalsIgnoreCase(rs.getString(1))) {
-                    s_logger.debug(String.format("Column %1$s.%2$s.%3$s found", dbName, tableName, column));
-                    found = true;
-                    break;
-                }
-            }
-            return found;
-        }
-    }
-
-    private boolean check221to222PremiumUprage(Connection conn) throws SQLException {
-        if (!isColumnExisted(conn, "cloud_usage", "cloud_usage", "network_id")) {
-            return false;
-        }
-
-        if (!isColumnExisted(conn, "cloud_usage", "usage_network", "network_id")) {
-            return false;
-        }
-
-        return isColumnExisted(conn, "cloud_usage", "user_statistics", "network_id");
-    }
-
-    private boolean check222to224PremiumUpgrade(Connection conn) throws SQLException {
-        if (!isColumnExisted(conn, "cloud_usage", "usage_vm_instance", "hypervisor_type")) {
-            return false;
-        }
-
-        return isColumnExisted(conn, "cloud_usage", "usage_event", "resource_type");
-    }
-
-    private boolean checkMissedPremiumUpgradeFor228() {
-        TransactionLegacy txn = TransactionLegacy.open("Integrity");
-        try {
-            txn.start();
-            Connection conn = txn.getConnection();
-            try (
-                PreparedStatement pstmt = conn.prepareStatement("show databases");
-                ResultSet rs = pstmt.executeQuery();) {
-                String dbVersion = _dao.getCurrentVersion();
-
-                if (dbVersion == null) {
-                    txn.commit();
-                    return false;
-                }
-
-                if (Version.compare(Version.trimToPatch(dbVersion), Version.trimToPatch("2.2.8")) != 0) {
-                    txn.commit();
-                    return true;
-                }
-                boolean hasUsage = false;
-                while (rs.next()) {
-                    String dbName = rs.getString(1);
-                    if (dbName.equalsIgnoreCase("cloud_usage")) {
-                        hasUsage = true;
-                        break;
-                    }
-                }
-                if (!hasUsage) {
-                    s_logger.debug("No cloud_usage found in database, no need to check missed premium upgrade");
-                    txn.commit();
-                    return true;
-                }
-                if (!check21to22PremiumUprage(conn)) {
-                    s_logger.error("21to22 premium upgrade missed");
-                    txn.commit();
-                    return false;
-                }
-                if (!check221to222PremiumUprage(conn)) {
-                    s_logger.error("221to222 premium upgrade missed");
-                    txn.commit();
-                    return false;
-                }
-                if (!check222to224PremiumUpgrade(conn)) {
-                    s_logger.error("222to224 premium upgrade missed");
-                    txn.commit();
-                    return false;
-                }
-                txn.commit();
-                return true;
-            } catch (Exception e) {
-                s_logger.error("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage());
-                throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(), e);
-            }
-        }catch (Exception e) {
-            s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage());
-            throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(),e);
-        }
-        finally
-        {
-            try {
-                if (txn != null) {
-                    txn.close();
-                }
-            }catch(Exception e)
-            {
-                s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage());
-            }
-        }
-    }
-
-    @Override
-    public void check() {
-        GlobalLock lock = GlobalLock.getInternLock("DatabaseIntegrity");
-        try {
-            s_logger.info("Grabbing lock to check for database integrity.");
-            if (!lock.lock(20 * 60)) {
-                throw new CloudRuntimeException("Unable to acquire lock to check for database integrity.");
-            }
-
-            try {
-                s_logger.info("Performing database integrity check");
-                if (!checkDuplicateHostWithTheSameLocalStorage()) {
-                    throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage detected error");
-                }
-
-                if (!checkMissedPremiumUpgradeFor228()) {
-                    s_logger.error("Your current database version is 2.2.8, management server detected some missed premium upgrade, please contact CloudStack support and attach log file. Thank you!");
-                    throw new CloudRuntimeException("Detected missed premium upgrade");
-                }
-            } finally {
-                lock.unlock();
-            }
-        } finally {
-            lock.releaseRef();
-        }
-    }
-
-    @Override
-    public boolean start() {
-        try {
-            check();
-        } catch (Exception e) {
-            s_logger.error("System integrity check exception", e);
-            System.exit(1);
-        }
-        return true;
-    }
-}
diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
deleted file mode 100644
index 1e2d19e..0000000
--- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
+++ /dev/null
@@ -1,720 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.upgrade;
-
-import com.cloud.upgrade.dao.DbUpgrade;
-import com.cloud.upgrade.dao.Upgrade217to218;
-import com.cloud.upgrade.dao.Upgrade218to22;
-import com.cloud.upgrade.dao.Upgrade218to224DomainVlans;
-import com.cloud.upgrade.dao.Upgrade2210to2211;
-import com.cloud.upgrade.dao.Upgrade2211to2212;
-import com.cloud.upgrade.dao.Upgrade2212to2213;
-import com.cloud.upgrade.dao.Upgrade2213to2214;
-import com.cloud.upgrade.dao.Upgrade2214to30;
-import com.cloud.upgrade.dao.Upgrade221to222;
-import com.cloud.upgrade.dao.Upgrade222to224;
-import com.cloud.upgrade.dao.Upgrade224to225;
-import com.cloud.upgrade.dao.Upgrade225to226;
-import com.cloud.upgrade.dao.Upgrade227to228;
-import com.cloud.upgrade.dao.Upgrade228to229;
-import com.cloud.upgrade.dao.Upgrade229to2210;
-import com.cloud.upgrade.dao.Upgrade301to302;
-import com.cloud.upgrade.dao.Upgrade302to303;
-import com.cloud.upgrade.dao.Upgrade302to40;
-import com.cloud.upgrade.dao.Upgrade303to304;
-import com.cloud.upgrade.dao.Upgrade304to305;
-import com.cloud.upgrade.dao.Upgrade305to306;
-import com.cloud.upgrade.dao.Upgrade306to307;
-import com.cloud.upgrade.dao.Upgrade307to410;
-import com.cloud.upgrade.dao.Upgrade30to301;
-import com.cloud.upgrade.dao.Upgrade40to41;
-import com.cloud.upgrade.dao.Upgrade410to420;
-import com.cloud.upgrade.dao.Upgrade420to421;
-import com.cloud.upgrade.dao.Upgrade421to430;
-import com.cloud.upgrade.dao.Upgrade430to440;
-import com.cloud.upgrade.dao.Upgrade431to440;
-import com.cloud.upgrade.dao.Upgrade432to440;
-import com.cloud.upgrade.dao.Upgrade440to441;
-import com.cloud.upgrade.dao.Upgrade441to442;
-import com.cloud.upgrade.dao.Upgrade442to450;
-import com.cloud.upgrade.dao.Upgrade443to450;
-import com.cloud.upgrade.dao.Upgrade444to450;
-import com.cloud.upgrade.dao.Upgrade450to451;
-import com.cloud.upgrade.dao.Upgrade451to452;
-import com.cloud.upgrade.dao.Upgrade452to460;
-import com.cloud.upgrade.dao.Upgrade453to460;
-import com.cloud.upgrade.dao.Upgrade460to461;
-import com.cloud.upgrade.dao.Upgrade461to470;
-import com.cloud.upgrade.dao.Upgrade470to471;
-import com.cloud.upgrade.dao.Upgrade471to480;
-import com.cloud.upgrade.dao.Upgrade480to481;
-import com.cloud.upgrade.dao.Upgrade481to490;
-import com.cloud.upgrade.dao.Upgrade490to4910;
-import com.cloud.upgrade.dao.Upgrade4910to4920;
-import com.cloud.upgrade.dao.Upgrade4920to4930;
-import com.cloud.upgrade.dao.Upgrade4930to41000;
-import com.cloud.upgrade.dao.Upgrade41000to41100;
-import com.cloud.upgrade.dao.Upgrade41100to41110;
-import com.cloud.upgrade.dao.Upgrade41110to41120;
-import com.cloud.upgrade.dao.Upgrade41120to41130;
-import com.cloud.upgrade.dao.UpgradeSnapshot217to224;
-import com.cloud.upgrade.dao.UpgradeSnapshot223to224;
-import com.cloud.upgrade.dao.VersionDao;
-import com.cloud.upgrade.dao.VersionDaoImpl;
-import com.cloud.upgrade.dao.VersionVO;
-import com.cloud.upgrade.dao.VersionVO.Step;
-import com.cloud.utils.component.SystemIntegrityChecker;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.ScriptRunner;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.google.common.collect.ImmutableList;
-import org.apache.cloudstack.utils.CloudStackVersion;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Lists.reverse;
-import static com.google.common.collect.ObjectArrays.concat;
-import static java.util.Collections.sort;
-
-public class DatabaseUpgradeChecker implements SystemIntegrityChecker {
-    private static final Logger s_logger = Logger.getLogger(DatabaseUpgradeChecker.class);
-    private final ImmutableList<CloudStackVersion> availableVersions;
-    protected Map<CloudStackVersion, DbUpgrade[]> _upgradeMap = new HashMap<>();
-
-    @Inject
-    VersionDao _dao;
-
-    public DatabaseUpgradeChecker() {
-        _dao = new VersionDaoImpl();
-
-        _upgradeMap.put(CloudStackVersion.parse("2.1.7"),
-            new DbUpgrade[] {new Upgrade217to218(), new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade224to225(),
-                new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(),
-                new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(),
-                new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(),
-                new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(),
-                new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.1.8"),
-            new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(),
-                new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(),
-                new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(),
-                new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.1.9"),
-            new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(),
-                new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(),
-                new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(),
-                new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.1"),
-            new DbUpgrade[] {new Upgrade221to222(), new UpgradeSnapshot223to224(), new Upgrade222to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(),
-                new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(),
-                new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(),
-                new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.2"),
-            new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(),
-                new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(),
-                new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(),
-                new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.3"),
-            new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(),
-                new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(),
-                new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(),
-                new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.4"),
-            new DbUpgrade[] {new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(),
-                new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(),
-                new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.5"),
-            new DbUpgrade[] {new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(),
-                new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(),
-                new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(),
-                new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(),
-                new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.6"),
-            new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(),
-                new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(),
-                new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(),
-                new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.7"),
-            new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(),
-                new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(),
-                new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(),
-                new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.8"),
-            new DbUpgrade[] {new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(),
-                new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(),
-                new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.9"),
-            new DbUpgrade[] {new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(),
-                new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(),
-                new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.10"),
-            new DbUpgrade[] {new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(),
-                new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(),
-                new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.12"),
-            new DbUpgrade[] {new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(),
-                new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.13"),
-            new DbUpgrade[] {new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(),
-                new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(),
-                new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(),
-                new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.14"),
-            new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(),
-                new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(),
-                new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.0"),
-            new DbUpgrade[] {new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(),
-                new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.1"),
-            new DbUpgrade[] {new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(),
-                new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.2"),
-            new DbUpgrade[] {new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(),
-                new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.0.0"),
-            new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(),
-                new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.0.1"),
-            new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(),
-                new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.0.2"),
-            new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(),
-                new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.1.0"),
-            new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.1.1"),
-            new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(),
-                new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.2.0"),
-            new DbUpgrade[] {new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(),
-                new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(),
-                new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.2.1"),
-            new DbUpgrade[] {new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(),
-                new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.3.0"),
-            new DbUpgrade[] {new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.3.1"),
-            new DbUpgrade[] {new Upgrade431to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.3.2"),
-            new DbUpgrade[] {new Upgrade432to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.4.0"),
-            new DbUpgrade[] {new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.4.1"),
-            new DbUpgrade[] {new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.4.2"),
-            new DbUpgrade[] {new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.4.3"),
-            new DbUpgrade[] {new Upgrade443to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.4.4"),
-            new DbUpgrade[] {new Upgrade444to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.5.0"),
-            new DbUpgrade[] {new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(),
-                new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.5.1"),
-            new DbUpgrade[] {new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(),
-                new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.5.2"),
-            new DbUpgrade[] {new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                    new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.5.3"),
-            new DbUpgrade[] {new Upgrade453to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.6.0"),
-            new DbUpgrade[] {new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.6.1"),
-            new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.6.2"),
-            new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.7.0"),
-            new DbUpgrade[] {new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.7.1"),
-            new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.7.2"),
-            new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(),
-                new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.8.0"),
-            new DbUpgrade[] {new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(),
-                new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.8.1"),
-            new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.8.2.0"),
-            new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.9.0"),
-            new DbUpgrade[] {new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.9.1.0"),
-            new DbUpgrade[] {new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.9.2.0"),
-            new DbUpgrade[] {new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.9.3.0"),
-            new DbUpgrade[] {new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.9.3.1"),
-                new DbUpgrade[] {new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.10.0.0"),
-            new DbUpgrade[] {new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.11.0.0"),
-            new DbUpgrade[] {new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.11.1.0"),
-            new DbUpgrade[] {new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("4.11.2.0"),
-                new DbUpgrade[] {new Upgrade41120to41130()});
-
-        //CP Upgrades
-        _upgradeMap.put(CloudStackVersion.parse("3.0.3"),
-            new DbUpgrade[] {new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(),
-                new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(),
-                new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(),
-                new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(),
-                new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.4"),
-            new DbUpgrade[] {new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(),
-                new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(),
-                new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(),
-                new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.5"),
-            new DbUpgrade[] {new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(),
-                new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(),
-                new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(),
-                new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.6"),
-            new DbUpgrade[] {new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(),
-                new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("3.0.7"),
-            new DbUpgrade[] {new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(),
-                new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(),
-                new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.15"),
-            new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(),
-                new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(),
-                new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        _upgradeMap.put(CloudStackVersion.parse("2.2.16"),
-            new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(),
-                new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(),
-                new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(),
-                new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(),
-                new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100(), new Upgrade41100to41110(), new Upgrade41110to41120(), new Upgrade41120to41130()});
-
-        final List<CloudStackVersion> sortedVersions = newArrayList(_upgradeMap.keySet());
-        sort(sortedVersions);
-
-        availableVersions = ImmutableList.copyOf(sortedVersions);
-    }
-
-    protected void runScript(Connection conn, InputStream file) {
-
-        try (InputStreamReader reader = new InputStreamReader(file)) {
-            ScriptRunner runner = new ScriptRunner(conn, false, true);
-            runner.runScript(reader);
-        } catch (IOException e) {
-            s_logger.error("Unable to read upgrade script", e);
-            throw new CloudRuntimeException("Unable to read upgrade script", e);
-        } catch (SQLException e) {
-            s_logger.error("Unable to execute upgrade script", e);
-            throw new CloudRuntimeException("Unable to execute upgrade script", e);
-        }
-
-    }
-
-    /**
-     *
-     * Calculates an upgrade path for the passed <code>dbVersion</code>.  The calculation assumes that the
-     * <code>dbVersion</code> required no schema migrations or data conversions and no upgrade path was defined
-     * for it.  Therefore, we find the most recent version with database migrations before the <code>dbVersion</code>
-     * and adopt that list.
-     *
-     * @param dbVersion The version from which the upgrade will occur
-     *
-     * @return The upgrade path from <code>dbVersion</code> to <code>currentVersion</code>
-     *
-     * @since 4.8.2.0
-     *
-     */
-    private DbUpgrade[] findMostRecentUpgradePath(final CloudStackVersion dbVersion) {
-
-        // Find the most recent version before dbVersion
-        for (CloudStackVersion version : reverse(availableVersions)) {
-            if (dbVersion.compareTo(version) < 0) {
-                return _upgradeMap.get(version);
-            }
-        }
-
-        // The current version was the latest and didn't have any migrations ...
-        return new DbUpgrade[0];
-
-    }
-
-    // Default visibility to support unit testing ...
-    DbUpgrade[] calculateUpgradePath(final CloudStackVersion dbVersion, final CloudStackVersion currentVersion) {
-
-        checkArgument(dbVersion != null);
-        checkArgument(currentVersion != null);
-        checkArgument(currentVersion.compareTo(dbVersion) > 0);
-
-        final DbUpgrade[] upgrades = _upgradeMap.containsKey(dbVersion) ? _upgradeMap.get(dbVersion) : findMostRecentUpgradePath(dbVersion);
-
-        // When there is no upgrade defined for the target version, we assume that there were no schema changes or
-        // data migrations required.  Based on that assumption, we add a noop DbUpgrade to the end of the list ...
-        final CloudStackVersion tailVersion = upgrades.length > 0 ? CloudStackVersion.parse(upgrades[upgrades.length - 1].getUpgradedVersion()) : dbVersion;
-
-        if (currentVersion.compareTo(tailVersion) != 0) {
-            return concat(upgrades, new NoopDbUpgrade(tailVersion, currentVersion));
-        }
-
-        return upgrades;
-
-    }
-
-    protected void upgrade(CloudStackVersion dbVersion, CloudStackVersion currentVersion) {
-        s_logger.info("Database upgrade must be performed from " + dbVersion + " to " + currentVersion);
-
-        final DbUpgrade[] upgrades = calculateUpgradePath(dbVersion, currentVersion);
-
-        boolean supportsRollingUpgrade = true;
-        for (DbUpgrade upgrade : upgrades) {
-            if (!upgrade.supportsRollingUpgrade()) {
-                supportsRollingUpgrade = false;
-                break;
-            }
-        }
-
-        if (!supportsRollingUpgrade && false) { // FIXME: Needs to detect if there are management servers running
-            // ClusterManagerImpl.arePeersRunning(null)) {
-            String errorMessage = "Unable to run upgrade because the upgrade sequence does not support rolling update and there are other management server nodes running";
-            s_logger.error(errorMessage);
-            throw new CloudRuntimeException(errorMessage);
-        }
-
-        for (DbUpgrade upgrade : upgrades) {
-            VersionVO version;
-            s_logger.debug("Running upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade
-                .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion());
-            TransactionLegacy txn = TransactionLegacy.open("Upgrade");
-            txn.start();
-            try {
-                Connection conn;
-                try {
-                    conn = txn.getConnection();
-                } catch (SQLException e) {
-                    String errorMessage = "Unable to upgrade the database";
-                    s_logger.error(errorMessage, e);
-                    throw new CloudRuntimeException(errorMessage, e);
-                }
-                InputStream[] scripts = upgrade.getPrepareScripts();
-                if (scripts != null) {
-                    for (InputStream script : scripts) {
-                        runScript(conn, script);
-                    }
-                }
-
-                upgrade.performDataMigration(conn);
-
-                version = new VersionVO(upgrade.getUpgradedVersion());
-                version = _dao.persist(version);
-
-                txn.commit();
-            } catch (CloudRuntimeException e) {
-                String errorMessage = "Unable to upgrade the database";
-                s_logger.error(errorMessage, e);
-                throw new CloudRuntimeException(errorMessage, e);
-            } finally {
-                txn.close();
-            }
-
-            // Run the corresponding '-cleanup.sql' script
-            txn = TransactionLegacy.open("Cleanup");
-            try {
-                s_logger.info("Cleanup upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade
-                    .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion());
-
-                txn.start();
-                Connection conn;
-                try {
-                    conn = txn.getConnection();
-                } catch (SQLException e) {
-                    s_logger.error("Unable to cleanup the database", e);
-                    throw new CloudRuntimeException("Unable to cleanup the database", e);
-                }
-
-                InputStream[] scripts = upgrade.getCleanupScripts();
-                if (scripts != null) {
-                    for (InputStream script : scripts) {
-                        runScript(conn, script);
-                        s_logger.debug("Cleanup script " + upgrade.getClass().getSimpleName() + " is executed successfully");
-                    }
-                }
-                txn.commit();
-
-                txn.start();
-                version.setStep(Step.Complete);
-                version.setUpdated(new Date());
-                _dao.update(version.getId(), version);
-                txn.commit();
-                s_logger.debug("Upgrade completed for version " + version.getVersion());
-            } finally {
-                txn.close();
-            }
-        }
-    }
-
-    @Override
-    public void check() {
-        GlobalLock lock = GlobalLock.getInternLock("DatabaseUpgrade");
-        try {
-            s_logger.info("Grabbing lock to check for database upgrade.");
-            if (!lock.lock(20 * 60)) {
-                throw new CloudRuntimeException("Unable to acquire lock to check for database integrity.");
-            }
-
-            try {
-
-                final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
-                final String currentVersionValue = this.getClass().getPackage().getImplementationVersion();
-
-                if (StringUtils.isBlank(currentVersionValue)) {
-                    return;
-                }
-
-                final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
-                s_logger.info("DB version = " + dbVersion + " Code Version = " + currentVersion);
-
-                if (dbVersion.compareTo(currentVersion) > 0) {
-                    throw new CloudRuntimeException("Database version " + dbVersion + " is higher than management software version " + currentVersionValue);
-                }
-
-                if (dbVersion.compareTo(currentVersion) == 0) {
-                    s_logger.info("DB version and code version matches so no upgrade needed.");
-                    return;
-                }
-
-                upgrade(dbVersion, currentVersion);
-            } finally {
-                lock.unlock();
-            }
-        } finally {
-            lock.releaseRef();
-        }
-    }
-
-    private static final class NoopDbUpgrade implements DbUpgrade {
-
-        private final String upgradedVersion;
-        private final String[] upgradeRange;
-
-        private NoopDbUpgrade(final CloudStackVersion fromVersion, final CloudStackVersion toVersion) {
-
-            super();
-
-            upgradedVersion = toVersion.toString();
-            upgradeRange = new String[] {fromVersion.toString(), toVersion.toString()};
-
-        }
-
-        @Override
-        public String[] getUpgradableVersionRange() {
-            return Arrays.copyOf(upgradeRange, upgradeRange.length);
-        }
-
-        @Override
-        public String getUpgradedVersion() {
-            return upgradedVersion;
-        }
-
-        @Override
-        public boolean supportsRollingUpgrade() {
-            return false;
-        }
-
-        @Override
-        public InputStream[] getPrepareScripts() {
-            return new InputStream[0];
-        }
-
-        @Override
-        public void performDataMigration(Connection conn) {
-
-        }
-
-        @Override
-        public InputStream[] getCleanupScripts() {
-            return new InputStream[0];
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java
deleted file mode 100644
index f155d6f..0000000
--- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2213to2214.java
+++ /dev/null
@@ -1,286 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.upgrade.dao;
-
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class Upgrade2213to2214 implements DbUpgrade {
-    final static Logger s_logger = Logger.getLogger(Upgrade2213to2214.class);
-
-    @Override
-    public String[] getUpgradableVersionRange() {
-        return new String[] {"2.2.13", "2.2.14"};
-    }
-
-    @Override
-    public String getUpgradedVersion() {
-        return "2.2.14";
-    }
-
-    @Override
-    public boolean supportsRollingUpgrade() {
-        return true;
-    }
-
-    @Override
-    public InputStream[] getPrepareScripts() {
-        final String scriptFile = "META-INF/db/schema-2213to2214.sql";
-        final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
-        if (script == null) {
-            throw new CloudRuntimeException("Unable to find " + scriptFile);
-        }
-
-        return new InputStream[] {script};
-    }
-
-    @Override
-    public void performDataMigration(Connection conn) {
-        fixIndexes(conn);
-    }
-
-    @Override
-    public InputStream[] getCleanupScripts() {
-        return null;
-    }
-
-    private void fixIndexes(Connection conn) {
-        //Drop i_usage_event__created key (if exists) and re-add it again
-        List<String> keys = new ArrayList<String>();
-        keys.add("i_usage_event__created");
-        DbUpgradeUtils.dropKeysIfExist(conn, "usage_event", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`usage_event` ADD INDEX `i_usage_event__created`(`created`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute usage_event table update", e);
-        }
-
-        //In cloud_usage DB, drop i_usage_event__created key (if exists) and re-add it again
-        keys = new ArrayList<String>();
-        keys.add("i_usage_event__created");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud_usage.usage_event", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud_usage`.`usage_event` ADD INDEX `i_usage_event__created`(`created`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute cloud_usage usage_event table update", e);
-        }
-
-        //Drop netapp_volume primary key and add it again
-        DbUpgradeUtils.dropPrimaryKeyIfExists(conn, "cloud.netapp_volume");
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`netapp_volume` add PRIMARY KEY (`id`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to update primary key for netapp_volume", e);
-        }
-
-        //Drop i_snapshots__removed key (if exists) and re-add it again
-        keys = new ArrayList<String>();
-        keys.add("i_snapshots__removed");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.snapshots", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`snapshots` ADD INDEX `i_snapshots__removed`(`removed`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert index for removed column in snapshots", e);
-        }
-        //Drop i_op_vm_ruleset_log__instance_id, u_op_vm_ruleset_log__instance_id key (if exists) and re-add u_op_vm_ruleset_log__instance_id again
-        keys = new ArrayList<String>();
-        keys.add("i_op_vm_ruleset_log__instance_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.op_vm_ruleset_log", keys, false);
-
-        keys = new ArrayList<String>();
-        keys.add("u_op_vm_ruleset_log__instance_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.op_vm_ruleset_log", keys, false);
-        try {
-            PreparedStatement pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`op_vm_ruleset_log` ADD CONSTRAINT `u_op_vm_ruleset_log__instance_id` UNIQUE (`instance_id`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute changes for op_vm_ruleset_log", e);
-        }
-
-        //Drop i_async__removed, i_async_job__removed  (if exists) and add i_async_job__removed
-        keys = new ArrayList<String>();
-        keys.add("i_async__removed");
-        keys.add("i_async_job__removed");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.async_job", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`async_job` ADD INDEX `i_async_job__removed`(`removed`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e);
-        }
-
-        keys = new ArrayList<String>();
-        keys.add("fk_ssh_keypair__account_id");
-        keys.add("fk_ssh_keypair__domain_id");
-        keys.add("fk_ssh_keypairs__account_id");
-        keys.add("fk_ssh_keypairs__domain_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, true);
-
-        keys = new ArrayList<String>();
-        keys.add("fk_ssh_keypair__account_id");
-        keys.add("fk_ssh_keypair__domain_id");
-        keys.add("fk_ssh_keypairs__account_id");
-        keys.add("fk_ssh_keypairs__domain_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, false);
-
-        try {
-            PreparedStatement pstmt;
-            pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__account_id` FOREIGN KEY `fk_ssh_keypairs__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding account_id foreign key", e);
-        }
-
-        try {
-            PreparedStatement pstmt;
-            pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__domain_id` FOREIGN KEY `fk_ssh_keypairs__domain_id` (`domain_id`) REFERENCES `domain` (`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding domain_id foreign key", e);
-        }
-
-        //Drop i_async__removed, i_async_job__removed  (if exists) and add i_async_job__removed
-        keys = new ArrayList<String>();
-        keys.add("i_async__removed");
-        keys.add("i_async_job__removed");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.async_job", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`async_job` ADD INDEX `i_async_job__removed`(`removed`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e);
-        }
-
-        //Drop storage pool details keys (if exists) and insert one with correct name
-        keys = new ArrayList<String>();
-        keys.add("fk_storage_pool__pool_id");
-        keys.add("fk_storage_pool_details__pool_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.storage_pool_details", keys, true);
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.storage_pool_details", keys, false);
-        try {
-            PreparedStatement pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`storage_pool_details` ADD CONSTRAINT `fk_storage_pool_details__pool_id` FOREIGN KEY `fk_storage_pool_details__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert foreign key in storage_pool_details ", e);
-        }
-
-        //Drop securityGroup keys (if exists) and insert one with correct name
-        keys = new ArrayList<String>();
-        keys.add("fk_security_group___account_id");
-        keys.add("fk_security_group__account_id");
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.security_group", keys, true);
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.security_group", keys, false);
-        try {
-            PreparedStatement pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`security_group` ADD CONSTRAINT `fk_security_group__account_id` FOREIGN KEY `fk_security_group__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert foreign key in security_group table ", e);
-        }
-
-        //Drop vmInstance keys (if exists) and insert one with correct name
-        keys = new ArrayList<String>();
-        keys.add("i_vm_instance__host_id");
-        keys.add("fk_vm_instance__host_id");
-
-        keys.add("fk_vm_instance__last_host_id");
-        keys.add("i_vm_instance__last_host_id");
-
-        keys.add("fk_vm_instance__service_offering_id");
-        keys.add("i_vm_instance__service_offering_id");
-
-        keys.add("fk_vm_instance__account_id");
-        keys.add("i_vm_instance__account_id");
-
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, true);
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, false);
-        try {
-            PreparedStatement pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`)");
-            pstmt.executeUpdate();
-            pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__last_host_id` FOREIGN KEY (`last_host_id`) REFERENCES `host` (`id`)");
-            pstmt.executeUpdate();
-            pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`)");
-            pstmt.executeUpdate();
-            pstmt =
-                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY (`service_offering_id`) REFERENCES `service_offering` (`id`)");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert foreign key in vm_instance table ", e);
-        }
-
-        //Drop user_ip_address keys (if exists) and insert one with correct name
-        keys = new ArrayList<String>();
-        keys.add("fk_user_ip_address__account_id");
-        keys.add("i_user_ip_address__account_id");
-
-        keys.add("fk_user_ip_address__vlan_db_id");
-        keys.add("i_user_ip_address__vlan_db_id");
-
-        keys.add("fk_user_ip_address__data_center_id");
-        keys.add("i_user_ip_address__data_center_id");
-
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, true);
-        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, false);
-        try {
-            PreparedStatement pstmt = conn.prepareStatement(
-                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`)");
-            pstmt.executeUpdate();
-            pstmt = conn.prepareStatement(
-                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__vlan_db_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt = conn.prepareStatement(
-                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__data_center_id`" +
-                    " FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE");
-            pstmt.executeUpdate();
-            pstmt.close();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to insert foreign key in vm_instance table ", e);
-        }
-
-    }
-}
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java b/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java
deleted file mode 100644
index 626b8cc..0000000
--- a/engine/schema/src/com/cloud/usage/dao/UsageDaoImpl.java
+++ /dev/null
@@ -1,515 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.usage.dao;
-
-import com.cloud.usage.UsageVO;
-import com.cloud.user.AccountVO;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.user.VmDiskStatisticsVO;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.TimeZone;
-
-@Component
-public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements UsageDao {
-    public static final Logger s_logger = Logger.getLogger(UsageDaoImpl.class.getName());
-    private static final String DELETE_ALL = "DELETE FROM cloud_usage";
-    private static final String DELETE_ALL_BY_ACCOUNTID = "DELETE FROM cloud_usage WHERE account_id = ?";
-    private static final String DELETE_ALL_BY_INTERVAL = "DELETE FROM cloud_usage WHERE end_date < DATE_SUB(CURRENT_DATE(), INTERVAL ? DAY)";
-    private static final String INSERT_ACCOUNT = "INSERT INTO cloud_usage.account (id, account_name, type, role_id, domain_id, removed, cleanup_needed) VALUES (?,?,?,?,?,?,?)";
-    private static final String INSERT_USER_STATS = "INSERT INTO cloud_usage.user_statistics (id, data_center_id, account_id, public_ip_address, device_id, device_type, network_id, net_bytes_received,"
-            + " net_bytes_sent, current_bytes_received, current_bytes_sent, agg_bytes_received, agg_bytes_sent) VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?)";
-
-    private static final String UPDATE_ACCOUNT = "UPDATE cloud_usage.account SET account_name=?, removed=? WHERE id=?";
-    private static final String UPDATE_USER_STATS = "UPDATE cloud_usage.user_statistics SET net_bytes_received=?, net_bytes_sent=?, current_bytes_received=?, current_bytes_sent=?, agg_bytes_received=?, agg_bytes_sent=? WHERE id=?";
-
-    private static final String GET_LAST_ACCOUNT = "SELECT id FROM cloud_usage.account ORDER BY id DESC LIMIT 1";
-    private static final String GET_LAST_USER_STATS = "SELECT id FROM cloud_usage.user_statistics ORDER BY id DESC LIMIT 1";
-    private static final String GET_PUBLIC_TEMPLATES_BY_ACCOUNTID = "SELECT id FROM cloud.vm_template WHERE account_id = ? AND public = '1' AND removed IS NULL";
-
-    private static final String GET_LAST_VM_DISK_STATS = "SELECT id FROM cloud_usage.vm_disk_statistics ORDER BY id DESC LIMIT 1";
-    private static final String INSERT_VM_DISK_STATS = "INSERT INTO cloud_usage.vm_disk_statistics (id, data_center_id, account_id, vm_id, volume_id, net_io_read, net_io_write, current_io_read, "
-            + "current_io_write, agg_io_read, agg_io_write, net_bytes_read, net_bytes_write, current_bytes_read, current_bytes_write, agg_bytes_read, agg_bytes_write) "
-            + " VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)";
-    private static final String UPDATE_VM_DISK_STATS = "UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, "
-            + "net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=?  WHERE id=?";
-    private static final String INSERT_USAGE_RECORDS = "INSERT INTO cloud_usage.cloud_usage (zone_id, account_id, domain_id, description, usage_display, "
-            + "usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, "
-            + "usage_id, type, size, network_id, start_date, end_date, virtual_size) VALUES (?,?,?,?,?,?,?,?,?, ?, ?, ?,?,?,?,?,?,?)";
-
-    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
-
-    public UsageDaoImpl() {
-    }
-
-    @Override
-    public void deleteRecordsForAccount(Long accountId) {
-        String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID);
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            if (accountId != null) {
-                pstmt.setLong(1, accountId.longValue());
-            }
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error retrieving usage vm instances for account id: " + accountId);
-        } finally {
-            txn.close();
-        }
-    }
-
-    @Override
-    public Pair<List<UsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<UsageVO> sc, Filter filter) {
-        return listAndCountIncludingRemovedBy(sc, filter);
-    }
-
-    @Override
-    public void saveAccounts(List<AccountVO> accounts) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = INSERT_ACCOUNT;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (AccountVO acct : accounts) {
-                pstmt.setLong(1, acct.getId());
-                pstmt.setString(2, acct.getAccountName());
-                pstmt.setShort(3, acct.getType());
-
-                //prevent autoboxing NPE by defaulting to User role
-                if(acct.getRoleId() == null){
-                    pstmt.setLong(4, RoleType.User.getId());
-                }else{
-                    pstmt.setLong(4, acct.getRoleId());
-                }
-
-                pstmt.setLong(5, acct.getDomainId());
-
-                Date removed = acct.getRemoved();
-                if (removed == null) {
-                    pstmt.setString(6, null);
-                } else {
-                    pstmt.setString(6, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), acct.getRemoved()));
-                }
-
-                pstmt.setBoolean(7, acct.getNeedsCleanup());
-
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving account to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    @Override
-    public void updateAccounts(List<AccountVO> accounts) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = UPDATE_ACCOUNT;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (AccountVO acct : accounts) {
-                pstmt.setString(1, acct.getAccountName());
-
-                Date removed = acct.getRemoved();
-                if (removed == null) {
-                    pstmt.setString(2, null);
-                } else {
-                    pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), acct.getRemoved()));
-                }
-
-                pstmt.setLong(3, acct.getId());
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving account to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    @Override
-    public void saveUserStats(List<UserStatisticsVO> userStats) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = INSERT_USER_STATS;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (UserStatisticsVO userStat : userStats) {
-                pstmt.setLong(1, userStat.getId());
-                pstmt.setLong(2, userStat.getDataCenterId());
-                pstmt.setLong(3, userStat.getAccountId());
-                pstmt.setString(4, userStat.getPublicIpAddress());
-                if (userStat.getDeviceId() != null) {
-                    pstmt.setLong(5, userStat.getDeviceId());
-                } else {
-                    pstmt.setNull(5, Types.BIGINT);
-                }
-                pstmt.setString(6, userStat.getDeviceType());
-                if (userStat.getNetworkId() != null) {
-                    pstmt.setLong(7, userStat.getNetworkId());
-                } else {
-                    pstmt.setNull(7, Types.BIGINT);
-                }
-                pstmt.setLong(8, userStat.getNetBytesReceived());
-                pstmt.setLong(9, userStat.getNetBytesSent());
-                pstmt.setLong(10, userStat.getCurrentBytesReceived());
-                pstmt.setLong(11, userStat.getCurrentBytesSent());
-                pstmt.setLong(12, userStat.getAggBytesReceived());
-                pstmt.setLong(13, userStat.getAggBytesSent());
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving user stats to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    @Override
-    public void updateUserStats(List<UserStatisticsVO> userStats) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = UPDATE_USER_STATS;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (UserStatisticsVO userStat : userStats) {
-                pstmt.setLong(1, userStat.getNetBytesReceived());
-                pstmt.setLong(2, userStat.getNetBytesSent());
-                pstmt.setLong(3, userStat.getCurrentBytesReceived());
-                pstmt.setLong(4, userStat.getCurrentBytesSent());
-                pstmt.setLong(5, userStat.getAggBytesReceived());
-                pstmt.setLong(6, userStat.getAggBytesSent());
-                pstmt.setLong(7, userStat.getId());
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving user stats to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    @Override
-    public Long getLastAccountId() {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_LAST_ACCOUNT;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                return Long.valueOf(rs.getLong(1));
-            }
-        } catch (Exception ex) {
-            s_logger.error("error getting last account id", ex);
-        }
-        return null;
-    }
-
-    @Override
-    public Long getLastUserStatsId() {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_LAST_USER_STATS;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                return Long.valueOf(rs.getLong(1));
-            }
-        } catch (Exception ex) {
-            s_logger.error("error getting last user stats id", ex);
-        }
-        return null;
-    }
-
-    @Override
-    public List<Long> listPublicTemplatesByAccount(long accountId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_PUBLIC_TEMPLATES_BY_ACCOUNTID;
-        List<Long> templateList = new ArrayList<Long>();
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, accountId);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                templateList.add(Long.valueOf(rs.getLong(1)));
-            }
-        } catch (Exception ex) {
-            s_logger.error("error listing public templates", ex);
-        }
-        return templateList;
-    }
-
-    @Override
-    public Long getLastVmDiskStatsId() {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = GET_LAST_VM_DISK_STATS;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            ResultSet rs = pstmt.executeQuery();
-            if (rs.next()) {
-                return Long.valueOf(rs.getLong(1));
-            }
-        } catch (Exception ex) {
-            s_logger.error("error getting last vm disk stats id", ex);
-        }
-        return null;
-    }
-
-    @Override
-    public void updateVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = UPDATE_VM_DISK_STATS;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
-                pstmt.setLong(1, vmDiskStat.getNetIORead());
-                pstmt.setLong(2, vmDiskStat.getNetIOWrite());
-                pstmt.setLong(3, vmDiskStat.getCurrentIORead());
-                pstmt.setLong(4, vmDiskStat.getCurrentIOWrite());
-                pstmt.setLong(5, vmDiskStat.getAggIORead());
-                pstmt.setLong(6, vmDiskStat.getAggIOWrite());
-                pstmt.setLong(7, vmDiskStat.getNetBytesRead());
-                pstmt.setLong(8, vmDiskStat.getNetBytesWrite());
-                pstmt.setLong(9, vmDiskStat.getCurrentBytesRead());
-                pstmt.setLong(10, vmDiskStat.getCurrentBytesWrite());
-                pstmt.setLong(11, vmDiskStat.getAggBytesRead());
-                pstmt.setLong(12, vmDiskStat.getAggBytesWrite());
-                pstmt.setLong(13, vmDiskStat.getId());
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving vm disk stats to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-
-    }
-
-    @Override
-    public void saveVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = INSERT_VM_DISK_STATS;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
-                pstmt.setLong(1, vmDiskStat.getId());
-                pstmt.setLong(2, vmDiskStat.getDataCenterId());
-                pstmt.setLong(3, vmDiskStat.getAccountId());
-                if (vmDiskStat.getVmId() != null) {
-                    pstmt.setLong(4, vmDiskStat.getVmId());
-                } else {
-                    pstmt.setNull(4, Types.BIGINT);
-                }
-                if (vmDiskStat.getVolumeId() != null) {
-                    pstmt.setLong(5, vmDiskStat.getVolumeId());
-                } else {
-                    pstmt.setNull(5, Types.BIGINT);
-                }
-                pstmt.setLong(6, vmDiskStat.getNetIORead());
-                pstmt.setLong(7, vmDiskStat.getNetIOWrite());
-                pstmt.setLong(8, vmDiskStat.getCurrentIORead());
-                pstmt.setLong(9, vmDiskStat.getCurrentIOWrite());
-                pstmt.setLong(10, vmDiskStat.getAggIORead());
-                pstmt.setLong(11, vmDiskStat.getAggIOWrite());
-                pstmt.setLong(12, vmDiskStat.getNetBytesRead());
-                pstmt.setLong(13, vmDiskStat.getNetBytesWrite());
-                pstmt.setLong(14, vmDiskStat.getCurrentBytesRead());
-                pstmt.setLong(15, vmDiskStat.getCurrentBytesWrite());
-                pstmt.setLong(16, vmDiskStat.getAggBytesRead());
-                pstmt.setLong(17, vmDiskStat.getAggBytesWrite());
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving vm disk stats to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-
-    }
-
-    @Override
-    public void saveUsageRecords(List<UsageVO> usageRecords) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-            String sql = INSERT_USAGE_RECORDS;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
-            for (UsageVO usageRecord : usageRecords) {
-                pstmt.setLong(1, usageRecord.getZoneId());
-                pstmt.setLong(2, usageRecord.getAccountId());
-                pstmt.setLong(3, usageRecord.getDomainId());
-                pstmt.setString(4, usageRecord.getDescription());
-                pstmt.setString(5, usageRecord.getUsageDisplay());
-                pstmt.setInt(6, usageRecord.getUsageType());
-                pstmt.setDouble(7, usageRecord.getRawUsage());
-                if (usageRecord.getVmInstanceId() != null) {
-                    pstmt.setLong(8, usageRecord.getVmInstanceId());
-                } else {
-                    pstmt.setNull(8, Types.BIGINT);
-                }
-                pstmt.setString(9, usageRecord.getVmName());
-                if (usageRecord.getOfferingId() != null) {
-                    pstmt.setLong(10, usageRecord.getOfferingId());
-                } else {
-                    pstmt.setNull(10, Types.BIGINT);
-                }
-                if (usageRecord.getTemplateId() != null) {
-                    pstmt.setLong(11, usageRecord.getTemplateId());
-                } else {
-                    pstmt.setNull(11, Types.BIGINT);
-                }
-                if (usageRecord.getUsageId() != null) {
-                    pstmt.setLong(12, usageRecord.getUsageId());
-                } else {
-                    pstmt.setNull(12, Types.BIGINT);
-                }
-                pstmt.setString(13, usageRecord.getType());
-                if (usageRecord.getSize() != null) {
-                    pstmt.setLong(14, usageRecord.getSize());
-                } else {
-                    pstmt.setNull(14, Types.BIGINT);
-                }
-                if (usageRecord.getNetworkId() != null) {
-                    pstmt.setLong(15, usageRecord.getNetworkId());
-                } else {
-                    pstmt.setNull(15, Types.BIGINT);
-                }
-                pstmt.setString(16, DateUtil.getDateDisplayString(s_gmtTimeZone, usageRecord.getStartDate()));
-                pstmt.setString(17, DateUtil.getDateDisplayString(s_gmtTimeZone, usageRecord.getEndDate()));
-                if (usageRecord.getVirtualSize() != null) {
-                    pstmt.setLong(18, usageRecord.getVirtualSize());
-                } else {
-                    pstmt.setNull(18, Types.BIGINT);
-                }
-                pstmt.addBatch();
-            }
-            pstmt.executeBatch();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error saving usage records to cloud_usage db", ex);
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    @Override
-    public void removeOldUsageRecords(int days) {
-        String sql = DELETE_ALL_BY_INTERVAL;
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, days);
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception ex) {
-            txn.rollback();
-            s_logger.error("error removing old cloud_usage records for interval: " + days);
-        } finally {
-            txn.close();
-        }
-    }
-
-    public UsageVO persistUsage(final UsageVO usage) {
-        return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<UsageVO>() {
-            @Override
-            public UsageVO doInTransaction(final TransactionStatus status) {
-                return persist(usage);
-            }
-        });
-    }
-
-    public Pair<List<? extends UsageVO>, Integer> getUsageRecordsPendingQuotaAggregation(final long accountId, final long domainId) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Getting usage records for account: " + accountId + ", domainId: " + domainId);
-        }
-        return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Pair<List<? extends UsageVO>, Integer>>() {
-            @Override
-            public Pair<List<? extends UsageVO>, Integer> doInTransaction(final TransactionStatus status) {
-                Pair<List<UsageVO>, Integer> usageRecords = new Pair<List<UsageVO>, Integer>(new ArrayList<UsageVO>(), 0);
-                Filter usageFilter = new Filter(UsageVO.class, "startDate", true, 0L, Long.MAX_VALUE);
-                QueryBuilder<UsageVO> qb = QueryBuilder.create(UsageVO.class);
-                if (accountId != -1) {
-                    qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId);
-                }
-                if (domainId != -1) {
-                    qb.and(qb.entity().getDomainId(), SearchCriteria.Op.EQ, domainId);
-                }
-                qb.and(qb.entity().getQuotaCalculated(), SearchCriteria.Op.NEQ, 1);
-                qb.and(qb.entity().getRawUsage(), SearchCriteria.Op.GT, 0);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Getting usage records" + usageFilter.getOrderBy());
-                }
-                usageRecords = searchAndCountAllRecords(qb.create(), usageFilter);
-                return new Pair<List<? extends UsageVO>, Integer>(usageRecords.first(), usageRecords.second());
-            }
-        });
-    }
-}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicIpAliasDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicIpAliasDaoImpl.java
deleted file mode 100644
index d1453aa..0000000
--- a/engine/schema/src/com/cloud/vm/dao/NicIpAliasDaoImpl.java
+++ /dev/null
@@ -1,185 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.vm.NicIpAlias;
-
-@Component
-public class NicIpAliasDaoImpl extends GenericDaoBase<NicIpAliasVO, Long> implements NicIpAliasDao {
-    private final SearchBuilder<NicIpAliasVO> AllFieldsSearch;
-    private final GenericSearchBuilder<NicIpAliasVO, String> IpSearch;
-
-    protected NicIpAliasDaoImpl() {
-        super();
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
-        AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
-        AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ);
-        AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
-        AllFieldsSearch.and("gateway", AllFieldsSearch.entity().getGateway(), Op.EQ);
-        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
-        AllFieldsSearch.done();
-
-        IpSearch = createSearchBuilder(String.class);
-        IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
-        IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
-        IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL);
-        IpSearch.done();
-    }
-
-    @Override
-    public List<NicIpAliasVO> listByVmId(long instanceId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", instanceId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicIpAliasVO> listByNicId(long nicId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<String> listAliasIpAddressInNetwork(long networkId) {
-        SearchCriteria<String> sc = IpSearch.create();
-        sc.setParameters("network", networkId);
-        return customSearch(sc, null);
-    }
-
-    @Override
-    public List<NicIpAliasVO> listByNetworkId(long networkId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicIpAliasVO> listByNetworkIdAndState(long networkId, NicIpAlias.State state) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        sc.setParameters("state", state);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicIpAliasVO> listByNicIdAndVmid(long nicId, long vmId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        sc.setParameters("instanceId", vmId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicIpAliasVO> getAliasIpForVm(long vmId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", vmId);
-        sc.setParameters("state", NicIpAlias.State.active);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<String> getAliasIpAddressesForNic(long nicId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        List<NicIpAliasVO> results = search(sc, null);
-        List<String> ips = new ArrayList<String>(results.size());
-        for (NicIpAliasVO result : results) {
-            ips.add(result.getIp4Address());
-        }
-        return ips;
-    }
-
-    @Override
-    public NicIpAliasVO findByInstanceIdAndNetworkId(long networkId, long instanceId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        sc.setParameters("instanceId", instanceId);
-        sc.setParameters("state", NicIpAlias.State.active);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicIpAliasVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public NicIpAliasVO findByGatewayAndNetworkIdAndState(String gateway, long networkId, NicIpAlias.State state) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("gateway", gateway);
-        sc.setParameters("network", networkId);
-        sc.setParameters("state", state);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicIpAliasVO findByIp4AddressAndVmId(String ip4Address, long vmId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("address", ip4Address);
-        sc.setParameters("instanceId", vmId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicIpAliasVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("address", ip4Address);
-        sc.setParameters("nicId", nicId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicIpAliasVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        sc.setParameters("instanceId", vmId);
-        sc.setParameters("address", vmIp);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public Integer countAliasIps(long id) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", id);
-        List<NicIpAliasVO> list = listBy(sc);
-        return list.size();
-    }
-
-    @Override
-    public int moveIpAliases(long fromNicId, long toNicId) {
-        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", fromNicId);
-
-        NicIpAliasVO update = createForUpdate();
-        update.setNicId(toNicId);
-        return update(update, sc);
-    }
-}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java
deleted file mode 100644
index 96b80b8..0000000
--- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm.dao;
-
-import java.util.List;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
-    List<NicSecondaryIpVO> listByVmId(long instanceId);
-
-    List<String> listSecondaryIpAddressInNetwork(long networkConfigId);
-
-    List<NicSecondaryIpVO> listByNetworkId(long networkId);
-
-    NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId);
-
-    //    void removeNicsForInstance(long instanceId);
-    //    void removeSecondaryIpForNic(long nicId);
-
-    NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId);
-
-    /**
-     * @param networkId
-     * @param instanceId
-     * @return
-     */
-
-    List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId);
-
-    List<NicSecondaryIpVO> listByNicId(long nicId);
-
-    List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId);
-
-    NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId);
-
-    NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp);
-
-    NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp);
-
-    List<String> getSecondaryIpAddressesForNic(long nicId);
-
-    Long countByNicId(long nicId);
-
-    List<NicSecondaryIpVO> listSecondaryIpUsingKeyword(long nicId, String keyword);
-
-    int moveSecondaryIps(long fromNicId, long toNicId);
-}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java
deleted file mode 100644
index 01f53bc..0000000
--- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-import com.cloud.utils.StringUtils;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-
-@Component
-public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long> implements NicSecondaryIpDao {
-    private final SearchBuilder<NicSecondaryIpVO> AllFieldsSearch;
-    private final GenericSearchBuilder<NicSecondaryIpVO, String> IpSearch;
-    protected GenericSearchBuilder<NicSecondaryIpVO, Long> CountByNicId;
-
-    protected NicSecondaryIpDaoImpl() {
-        super();
-        AllFieldsSearch = createSearchBuilder();
-        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
-        AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
-        AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.LIKE);
-        AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
-        AllFieldsSearch.done();
-
-        IpSearch = createSearchBuilder(String.class);
-        IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
-        IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
-        IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL);
-        IpSearch.done();
-
-        CountByNicId = createSearchBuilder(Long.class);
-        CountByNicId.select(null, Func.COUNT, null);
-        CountByNicId.and("nic", CountByNicId.entity().getNicId(), SearchCriteria.Op.EQ);
-        CountByNicId.done();
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> listByVmId(long instanceId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", instanceId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> listByNicId(long nicId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<String> listSecondaryIpAddressInNetwork(long networkId) {
-        SearchCriteria<String> sc = IpSearch.create();
-        sc.setParameters("network", networkId);
-        return customSearch(sc, null);
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> listByNetworkId(long networkId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        sc.setParameters("instanceId", vmId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", vmId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<String> getSecondaryIpAddressesForNic(long nicId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        List<NicSecondaryIpVO> results = search(sc, null);
-        List<String> ips = new ArrayList<String>(results.size());
-        for (NicSecondaryIpVO result : results) {
-            if (StringUtils.isNotBlank(result.getIp4Address())) {
-                ips.add(result.getIp4Address());
-            }
-
-            if (StringUtils.isNotBlank(result.getIp6Address())) {
-                ips.add(result.getIp6Address());
-            }
-        }
-        return ips;
-    }
-
-    @Override
-    public NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        sc.setParameters("address", ip4Address);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("address", ip4Address);
-        sc.setParameters("nicId", nicId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("instanceId", vmId);
-        sc.setParameters("address", vmIp);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("network", networkId);
-        sc.setParameters("instanceId", vmId);
-        sc.setParameters("address", vmIp);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public Long countByNicId(long nicId) {
-        SearchCriteria<Long> sc = CountByNicId.create();
-        sc.setParameters("nic", nicId);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public List<NicSecondaryIpVO> listSecondaryIpUsingKeyword(long nicId, String keyword)
-    {
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", nicId);
-        sc.setParameters("address", "%" + keyword + "%");
-        return listBy(sc);
-    }
-
-    @Override
-    public int moveSecondaryIps(long fromNicId, long toNicId) {
-        NicSecondaryIpVO update = createForUpdate();
-        update.setNicId(toNicId);
-
-        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
-        sc.setParameters("nicId", fromNicId);
-
-        return update(update, sc);
-    }
-}
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
deleted file mode 100644
index 66f7638..0000000
--- a/engine/schema/src/com/cloud/vm/dao/UserVmDaoImpl.java
+++ /dev/null
@@ -1,683 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.network.Network;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.Attribute;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.UserVmDetailVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.UserVmData.NicData;
-import com.cloud.vm.dao.UserVmData.SecurityGroupData;
-
-public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements UserVmDao {
-    public static final Logger s_logger = Logger.getLogger(UserVmDaoImpl.class);
-
-    protected SearchBuilder<UserVmVO> AccountPodSearch;
-    protected SearchBuilder<UserVmVO> AccountDataCenterSearch;
-    protected SearchBuilder<UserVmVO> AccountSearch;
-    protected SearchBuilder<UserVmVO> HostSearch;
-    protected SearchBuilder<UserVmVO> LastHostSearch;
-    protected SearchBuilder<UserVmVO> HostUpSearch;
-    protected SearchBuilder<UserVmVO> HostRunningSearch;
-    protected SearchBuilder<UserVmVO> StateChangeSearch;
-    protected SearchBuilder<UserVmVO> AccountHostSearch;
-
-    protected SearchBuilder<UserVmVO> DestroySearch;
-    protected SearchBuilder<UserVmVO> AccountDataCenterVirtualSearch;
-    protected GenericSearchBuilder<UserVmVO, Long> CountByAccountPod;
-    protected GenericSearchBuilder<UserVmVO, Long> CountByAccount;
-    protected GenericSearchBuilder<UserVmVO, Long> PodsHavingVmsForAccount;
-
-    protected SearchBuilder<UserVmVO> UserVmSearch;
-    protected SearchBuilder<UserVmVO> UserVmByIsoSearch;
-    protected Attribute _updateTimeAttr;
-    // ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class);
-    @Inject
-    ResourceTagDao _tagsDao;
-    @Inject
-    NetworkDao networkDao;
-
-    private static final String LIST_PODS_HAVING_VMS_FOR_ACCOUNT =
-            "SELECT pod_id FROM cloud.vm_instance WHERE data_center_id = ? AND account_id = ? AND pod_id IS NOT NULL AND (state = 'Running' OR state = 'Stopped') "
-                    + "GROUP BY pod_id HAVING count(id) > 0 ORDER BY count(id) DESC";
-
-    private static final String VM_DETAILS = "select vm_instance.id, "
-            + "account.id, account.account_name, account.type, domain.name, instance_group.id, instance_group.name,"
-            + "data_center.id, data_center.name, data_center.is_security_group_enabled, host.id, host.name, "
-            + "vm_template.id, vm_template.name, vm_template.display_text, iso.id, iso.name, "
-            + "vm_template.enable_password, service_offering.id, disk_offering.name, storage_pool.id, storage_pool.pool_type, "
-            + "service_offering.cpu, service_offering.speed, service_offering.ram_size, volumes.id, volumes.device_id, volumes.volume_type, security_group.id, security_group.name, "
-            + "security_group.description, nics.id, nics.ip4_address, nics.default_nic, nics.gateway, nics.network_id, nics.netmask, nics.mac_address, nics.broadcast_uri, " +
-            "nics.isolation_uri, "
-            + "networks.traffic_type, networks.guest_type, user_ip_address.id, user_ip_address.public_ip_address from vm_instance "
-            + "left join account on vm_instance.account_id=account.id  " + "left join domain on vm_instance.domain_id=domain.id "
-            + "left join instance_group_vm_map on vm_instance.id=instance_group_vm_map.instance_id "
-            + "left join instance_group on instance_group_vm_map.group_id=instance_group.id " + "left join data_center on vm_instance.data_center_id=data_center.id "
-            + "left join host on vm_instance.host_id=host.id " + "left join vm_template on vm_instance.vm_template_id=vm_template.id "
-            + "left join user_vm on vm_instance.id=user_vm.id " + "left join vm_template iso on iso.id=user_vm.iso_id "
-            + "left join service_offering on vm_instance.service_offering_id=service_offering.id "
-            + "left join disk_offering  on vm_instance.service_offering_id=disk_offering.id " + "left join volumes on vm_instance.id=volumes.instance_id "
-            + "left join storage_pool on volumes.pool_id=storage_pool.id " + "left join security_group_vm_map on vm_instance.id=security_group_vm_map.instance_id "
-            + "left join security_group on security_group_vm_map.security_group_id=security_group.id " + "left join nics on vm_instance.id=nics.instance_id "
-            + "left join networks on nics.network_id=networks.id " + "left join user_ip_address on user_ip_address.vm_id=vm_instance.id " + "where vm_instance.id in (";
-
-    private static final String VMS_DETAIL_BY_NAME = "select vm_instance.instance_name, vm_instance.vm_type, vm_instance.id , user_vm_details.value, user_vm_details.name from vm_instance "
-            + "left join user_vm_details on vm_instance.id = user_vm_details.vm_id where (user_vm_details.name is null or user_vm_details.name = ? ) and vm_instance.instance_name in (";
-
-    private static final int VM_DETAILS_BATCH_SIZE = 100;
-
-    @Inject
-    protected UserVmDetailsDao _detailsDao;
-    @Inject
-    protected NicDao _nicDao;
-
-    public UserVmDaoImpl() {
-    }
-
-    @PostConstruct
-    void init() {
-        AccountSearch = createSearchBuilder();
-        AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountSearch.done();
-
-        HostSearch = createSearchBuilder();
-        HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        HostSearch.done();
-
-        LastHostSearch = createSearchBuilder();
-        LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ);
-        LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ);
-        LastHostSearch.done();
-
-        HostUpSearch = createSearchBuilder();
-        HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN);
-        HostUpSearch.done();
-
-        HostRunningSearch = createSearchBuilder();
-        HostRunningSearch.and("host", HostRunningSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        HostRunningSearch.and("state", HostRunningSearch.entity().getState(), SearchCriteria.Op.EQ);
-        HostRunningSearch.done();
-
-        AccountPodSearch = createSearchBuilder();
-        AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountPodSearch.and("pod", AccountPodSearch.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
-        AccountPodSearch.done();
-
-        AccountDataCenterSearch = createSearchBuilder();
-        AccountDataCenterSearch.and("account", AccountDataCenterSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountDataCenterSearch.and("dc", AccountDataCenterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        AccountDataCenterSearch.done();
-
-        StateChangeSearch = createSearchBuilder();
-        StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ);
-        StateChangeSearch.and("states", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ);
-        StateChangeSearch.and("host", StateChangeSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        StateChangeSearch.and("update", StateChangeSearch.entity().getUpdated(), SearchCriteria.Op.EQ);
-        StateChangeSearch.done();
-
-        DestroySearch = createSearchBuilder();
-        DestroySearch.and("state", DestroySearch.entity().getState(), SearchCriteria.Op.IN);
-        DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT);
-        DestroySearch.done();
-
-        AccountHostSearch = createSearchBuilder();
-        AccountHostSearch.and("accountId", AccountHostSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountHostSearch.and("hostId", AccountHostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        AccountHostSearch.done();
-
-        CountByAccountPod = createSearchBuilder(Long.class);
-        CountByAccountPod.select(null, Func.COUNT, null);
-        CountByAccountPod.and("account", CountByAccountPod.entity().getAccountId(), SearchCriteria.Op.EQ);
-        CountByAccountPod.and("pod", CountByAccountPod.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
-        CountByAccountPod.done();
-
-        CountByAccount = createSearchBuilder(Long.class);
-        CountByAccount.select(null, Func.COUNT, null);
-        CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
-        CountByAccount.and("type", CountByAccount.entity().getType(), SearchCriteria.Op.EQ);
-        CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
-        CountByAccount.and("displayVm", CountByAccount.entity().isDisplayVm(), SearchCriteria.Op.EQ);
-        CountByAccount.done();
-
-        SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
-        nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        nicSearch.and("ip4Address", nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
-
-        AccountDataCenterVirtualSearch = createSearchBuilder();
-        AccountDataCenterVirtualSearch.and("account", AccountDataCenterVirtualSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        AccountDataCenterVirtualSearch.and("dc", AccountDataCenterVirtualSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(),
-                JoinBuilder.JoinType.INNER);
-        AccountDataCenterVirtualSearch.done();
-
-        UserVmByIsoSearch = createSearchBuilder();
-        UserVmByIsoSearch.and("isoId", UserVmByIsoSearch.entity().getIsoId(), SearchCriteria.Op.EQ);
-        UserVmByIsoSearch.done();
-
-        _updateTimeAttr = _allAttributes.get("updateTime");
-        assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
-    }
-
-    @Override
-    public List<UserVmVO> listByAccountAndPod(long accountId, long podId) {
-        SearchCriteria<UserVmVO> sc = AccountPodSearch.create();
-        sc.setParameters("account", accountId);
-        sc.setParameters("pod", podId);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByAccountAndDataCenter(long accountId, long dcId) {
-        SearchCriteria<UserVmVO> sc = AccountDataCenterSearch.create();
-        sc.setParameters("account", accountId);
-        sc.setParameters("dc", dcId);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm,
-            boolean isDynamicallyScalable, String customId, String hostName, String instanceName) {
-        UserVmVO vo = createForUpdate();
-        vo.setDisplayName(displayName);
-        vo.setHaEnabled(enable);
-        vo.setGuestOSId(osTypeId);
-        vo.setUserData(userData);
-        vo.setDisplayVm(displayVm);
-        vo.setDynamicallyScalable(isDynamicallyScalable);
-        if (hostName != null) {
-            vo.setHostName(hostName);
-        }
-        if (customId != null) {
-            vo.setUuid(customId);
-        }
-        if(instanceName != null){
-            vo.setInstanceName(instanceName);
-        }
-
-        update(id, vo);
-    }
-
-    @Override
-    public List<UserVmVO> findDestroyedVms(Date date) {
-        SearchCriteria<UserVmVO> sc = DestroySearch.create();
-        sc.setParameters("state", State.Destroyed, State.Expunging, State.Error);
-        sc.setParameters("updateTime", date);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByAccountId(long id) {
-        SearchCriteria<UserVmVO> sc = AccountSearch.create();
-        sc.setParameters("account", id);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByHostId(Long id) {
-        SearchCriteria<UserVmVO> sc = HostSearch.create();
-        sc.setParameters("host", id);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByIsoId(Long isoId) {
-        SearchCriteria<UserVmVO> sc = UserVmByIsoSearch.create();
-        sc.setParameters("isoId", isoId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listUpByHostId(Long hostId) {
-        SearchCriteria<UserVmVO> sc = HostUpSearch.create();
-        sc.setParameters("host", hostId);
-        sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging});
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listRunningByHostId(long hostId) {
-        SearchCriteria<UserVmVO> sc = HostRunningSearch.create();
-        sc.setParameters("host", hostId);
-        sc.setParameters("state", State.Running);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId) {
-
-        SearchCriteria<UserVmVO> sc = AccountDataCenterVirtualSearch.create();
-        sc.setParameters("account", accountId);
-        sc.setJoinParameters("nicSearch", "networkId", networkId);
-
-        return listBy(sc);
-    }
-
-    /**
-     * Recreates UserVmSearch depending on network type, as nics on L2 networks have no ip addresses
-     * @param network network
-     */
-    private void recreateUserVmSeach(NetworkVO network) {
-        if (network != null) {
-            SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
-            nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
-            nicSearch.and("removed", nicSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-            if (!Network.GuestType.L2.equals(network.getGuestType())) {
-                nicSearch.and().op("ip4Address", nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
-                nicSearch.or("ip6Address", nicSearch.entity().getIPv6Address(), SearchCriteria.Op.NNULL);
-                nicSearch.cp();
-            }
-
-            UserVmSearch = createSearchBuilder();
-            UserVmSearch.and("states", UserVmSearch.entity().getState(), SearchCriteria.Op.IN);
-            UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
-            UserVmSearch.done();
-        }
-    }
-
-    @Override
-    public List<UserVmVO> listByNetworkIdAndStates(long networkId, State... states) {
-        NetworkVO network = networkDao.findById(networkId);
-        recreateUserVmSeach(network);
-
-        SearchCriteria<UserVmVO> sc = UserVmSearch.create();
-        if (states != null && states.length != 0) {
-            sc.setParameters("states", (Object[])states);
-        }
-        sc.setJoinParameters("nicSearch", "networkId", networkId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByLastHostId(Long hostId) {
-        SearchCriteria<UserVmVO> sc = LastHostSearch.create();
-        sc.setParameters("lastHost", hostId);
-        sc.setParameters("state", State.Stopped);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<UserVmVO> listByAccountIdAndHostId(long accountId, long hostId) {
-        SearchCriteria<UserVmVO> sc = AccountHostSearch.create();
-        sc.setParameters("hostId", hostId);
-        sc.setParameters("accountId", accountId);
-        return listBy(sc);
-    }
-
-    @Override
-    public void loadDetails(UserVmVO vm) {
-        Map<String, String> details = _detailsDao.listDetailsKeyPairs(vm.getId());
-        vm.setDetails(details);
-    }
-
-    @Override
-    public void saveDetails(UserVmVO vm) {
-        Map<String, String> detailsStr = vm.getDetails();
-        if (detailsStr == null) {
-            return;
-        }
-
-        final Map<String, Boolean> visibilityMap = _detailsDao.listDetailsVisibility(vm.getId());
-
-        List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>();
-        for (Map.Entry<String, String> entry : detailsStr.entrySet()) {
-            boolean display = visibilityMap.getOrDefault(entry.getKey(), true);
-            details.add(new UserVmDetailVO(vm.getId(), entry.getKey(), entry.getValue(), display));
-        }
-
-        _detailsDao.saveDetails(details);
-    }
-
-    @Override
-    public List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        List<Long> result = new ArrayList<Long>();
-        String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT;
-
-        try(PreparedStatement pstmt = txn.prepareStatement(sql)) {
-            pstmt.setLong(1, zoneId);
-            pstmt.setLong(2, accountId);
-            try(ResultSet rs = pstmt.executeQuery();)
-            {
-                while (rs.next()) {
-                    result.add(rs.getLong(1));
-                }
-            }
-            catch (Exception e) {
-                s_logger.error("listPodIdsHavingVmsforAccount:Exception: " +  e.getMessage());
-                throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e);
-            }
-            txn.commit();
-            return result;
-        } catch (Exception e) {
-            s_logger.error("listPodIdsHavingVmsforAccount:Exception : " +  e.getMessage());
-            throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e);
-        }
-        finally {
-            try{
-                if (txn != null)
-                {
-                    txn.close();
-                }
-            }
-            catch (Exception e)
-            {
-                s_logger.error("listVmDetails:Exception:" + e.getMessage());
-            }
-        }
-
-    }
-
-    @Override
-    public Hashtable<Long, UserVmData> listVmDetails(Hashtable<Long, UserVmData> userVmDataHash) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            int curr_index = 0;
-            List<UserVmData> userVmDataList = new ArrayList(userVmDataHash.values());
-            if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE)
-            {
-                try (PreparedStatement pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE));)
-                {
-                    while ((curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()) {
-                        // set the vars value
-                        for (int k = 1, j = curr_index; j < curr_index + VM_DETAILS_BATCH_SIZE; j++, k++) {
-                            pstmt.setLong(k, userVmDataList.get(j).getId());
-                        }
-                        try(ResultSet rs = pstmt.executeQuery();)
-                        {
-                            while (rs.next()) {
-                                long vm_id = rs.getLong("vm_instance.id");
-                                //check if the entry is already there
-                                UserVmData uvm = userVmDataHash.get(vm_id);
-                                if (uvm == null) {
-                                    uvm = new UserVmData();
-                                    uvm.setId(vm_id);
-                                }
-                                // initialize the data with this row
-                                setUserVmData(uvm, rs);
-                            }
-                        }
-                        catch (Exception e)
-                        {
-                            s_logger.error("listVmDetails:Exception:" + e.getMessage());
-                            throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
-                        }
-                        curr_index += VM_DETAILS_BATCH_SIZE;
-                    }
-                }
-                catch (Exception e)
-                {
-                    s_logger.error("listVmDetails:Exception:" + e.getMessage());
-                    throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
-                }
-            }
-
-            if (curr_index < userVmDataList.size()) {
-                int batch_size = (userVmDataList.size() - curr_index);
-                try (PreparedStatement vm_details_pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(batch_size)))
-                {
-                    // set the vars value
-                    for (int k = 1, j = curr_index; j < curr_index + batch_size; j++, k++) {
-                        vm_details_pstmt.setLong(k, userVmDataList.get(j).getId());
-                    }
-                    try(ResultSet rs = vm_details_pstmt.executeQuery();) {
-                        while (rs.next()) {
-                            long vm_id = rs.getLong("vm_instance.id");
-                            //check if the entry is already there
-                            UserVmData uvm = userVmDataHash.get(vm_id);
-                            if (uvm == null) {
-                                uvm = new UserVmData();
-                                uvm.setId(vm_id);
-                            }
-                            // initialize the data with this row
-                            setUserVmData(uvm, rs);
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        s_logger.error("listVmDetails: Exception:" + e.getMessage());
-                        throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
-                    }
-                }
-                catch (Exception e)
-                {
-                    s_logger.error("listVmDetails:Exception:" + e.getMessage());
-                    throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
-                }
-            }
-            txn.commit();
-            return userVmDataHash;
-        } catch (Exception e) {
-            s_logger.error("listVmDetails:Exception:" + e.getMessage());
-            throw new CloudRuntimeException("listVmDetails:Exception : ", e);
-        }
-        finally {
-            try{
-                if (txn != null)
-                {
-                    txn.close();
-                }
-            }
-            catch (Exception e)
-            {
-                s_logger.error("listVmDetails:Exception:" + e.getMessage());
-            }
-        }
-
-    }
-
-    public static UserVmData setUserVmData(UserVmData userVmData, ResultSet rs) throws SQLException {
-
-        if (!userVmData.isInitialized()) {
-
-            //account.account_name, account.type, domain.name,  instance_group.id, instance_group.name,"
-            userVmData.setAccountId(rs.getLong("account.id"));
-            userVmData.setAccountName(rs.getString("account.account_name"));
-            userVmData.setDomainName(rs.getString("domain.name"));
-
-            long grp_id = rs.getLong("instance_group.id");
-            if (grp_id > 0) {
-                userVmData.setGroupId(grp_id);
-                userVmData.setGroup(rs.getString("instance_group.name"));
-            }
-
-            //"data_center.id, data_center.name, host.id, host.name, vm_template.id, vm_template.name, vm_template.display_text, vm_template.enable_password,
-            userVmData.setZoneId(rs.getLong("data_center.id"));
-            userVmData.setZoneName(rs.getString("data_center.name"));
-
-            userVmData.setHostId(rs.getLong("host.id"));
-            userVmData.setHostName(rs.getString("host.name"));
-
-            long template_id = rs.getLong("vm_template.id");
-            if (template_id > 0) {
-                userVmData.setTemplateId(template_id);
-                userVmData.setTemplateName(rs.getString("vm_template.name"));
-                userVmData.setTemplateDisplayText(rs.getString("vm_template.display_text"));
-                userVmData.setPasswordEnabled(rs.getBoolean("vm_template.enable_password"));
-            } else {
-                userVmData.setTemplateId(-1L);
-                userVmData.setTemplateName("ISO Boot");
-                userVmData.setTemplateDisplayText("ISO Boot");
-                userVmData.setPasswordEnabled(false);
-            }
-
-            long iso_id = rs.getLong("iso.id");
-            if (iso_id > 0) {
-                userVmData.setIsoId(iso_id);
-                userVmData.setIsoName(rs.getString("iso.name"));
-            }
-
-            //service_offering.id, disk_offering.name, "
-            //"service_offering.cpu, service_offering.speed, service_offering.ram_size,
-            userVmData.setServiceOfferingId(rs.getLong("service_offering.id"));
-            userVmData.setServiceOfferingName(rs.getString("disk_offering.name"));
-            userVmData.setCpuNumber(rs.getInt("service_offering.cpu"));
-            userVmData.setCpuSpeed(rs.getInt("service_offering.speed"));
-            userVmData.setMemory(rs.getInt("service_offering.ram_size"));
-
-            // volumes.device_id, volumes.volume_type,
-            long vol_id = rs.getLong("volumes.id");
-            if (vol_id > 0) {
-                userVmData.setRootDeviceId(rs.getLong("volumes.device_id"));
-                userVmData.setRootDeviceType(rs.getString("volumes.volume_type"));
-                // storage pool
-                long pool_id = rs.getLong("storage_pool.id");
-                if (pool_id > 0) {
-                    userVmData.setRootDeviceType(rs.getString("storage_pool.pool_type"));
-                } else {
-                    userVmData.setRootDeviceType("Not created");
-                }
-            }
-            userVmData.setInitialized();
-        }
-
-        Long securityGroupId = rs.getLong("security_group.id");
-        if (securityGroupId != null && securityGroupId.longValue() != 0) {
-            SecurityGroupData resp = userVmData.newSecurityGroupData();
-            resp.setId(rs.getLong("security_group.id"));
-            resp.setName(rs.getString("security_group.name"));
-            resp.setDescription(rs.getString("security_group.description"));
-            resp.setObjectName("securitygroup");
-            userVmData.addSecurityGroup(resp);
-        }
-
-        long nic_id = rs.getLong("nics.id");
-        if (nic_id > 0) {
-            NicData nicResponse = userVmData.newNicData();
-            nicResponse.setId(nic_id);
-            nicResponse.setIpaddress(rs.getString("nics.ip4_address"));
-            nicResponse.setGateway(rs.getString("nics.gateway"));
-            nicResponse.setNetmask(rs.getString("nics.netmask"));
-            nicResponse.setNetworkid(rs.getLong("nics.network_id"));
-            nicResponse.setMacAddress(rs.getString("nics.mac_address"));
-
-            int account_type = rs.getInt("account.type");
-            if (account_type == Account.ACCOUNT_TYPE_ADMIN) {
-                nicResponse.setBroadcastUri(rs.getString("nics.broadcast_uri"));
-                nicResponse.setIsolationUri(rs.getString("nics.isolation_uri"));
-            }
-
-            nicResponse.setTrafficType(rs.getString("networks.traffic_type"));
-            nicResponse.setType(rs.getString("networks.guest_type"));
-            nicResponse.setIsDefault(rs.getBoolean("nics.default_nic"));
-            nicResponse.setObjectName("nic");
-            userVmData.addNic(nicResponse);
-        }
-
-        long publicIpId = rs.getLong("user_ip_address.id");
-        if (publicIpId > 0) {
-            userVmData.setPublicIpId(publicIpId);
-            userVmData.setPublicIp(rs.getString("user_ip_address.public_ip_address"));
-        }
-
-        return userVmData;
-    }
-
-    public String getQueryBatchAppender(int count) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < count; i++) {
-            sb.append(" ?,");
-        }
-        sb.deleteCharAt(sb.length() - 1).append(")");
-        return sb.toString();
-    }
-
-    @Override
-    public Long countAllocatedVMsForAccount(long accountId) {
-        SearchCriteria<Long> sc = CountByAccount.create();
-        sc.setParameters("account", accountId);
-        sc.setParameters("type", VirtualMachine.Type.User);
-        sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
-        sc.setParameters("displayVm", 1);
-        return customSearch(sc, null).get(0);
-    }
-
-    @Override
-    public boolean remove(Long id) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        _tagsDao.removeByIdAndType(id, ResourceObjectType.UserVm);
-        boolean result = super.remove(id);
-        txn.commit();
-        return result;
-    }
-
-    @Override
-    public List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> getVmsDetailByNames(Set<String> vmNames, String detail) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmsDetailByNames = new ArrayList<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>>();
-
-        try (PreparedStatement pstmt = txn.prepareStatement(VMS_DETAIL_BY_NAME + getQueryBatchAppender(vmNames.size()));) {
-            pstmt.setString(1, detail);
-            int i = 2;
-            for(String name : vmNames) {
-                pstmt.setString(i, name);
-                i++;
-            }
-            try (ResultSet rs = pstmt.executeQuery();) {
-                while (rs.next()) {
-                    vmsDetailByNames.add(new Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>(new Pair<String, VirtualMachine.Type>(
-                            rs.getString("vm_instance.instance_name"), VirtualMachine.Type.valueOf(rs.getString("vm_type"))),
-                            new Pair<Long, String>(rs.getLong("vm_instance.id"), rs.getString("user_vm_details.value"))));
-                }
-            }
-        } catch (SQLException e) {
-            s_logger.error("GetVmsDetailsByNames: Exception in sql: " + e.getMessage());
-            throw new CloudRuntimeException("GetVmsDetailsByNames: Exception: " + e.getMessage());
-        }
-
-        return vmsDetailByNames;
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/alert/AlertVO.java b/engine/schema/src/main/java/com/cloud/alert/AlertVO.java
new file mode 100644
index 0000000..1f2cd9d
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/alert/AlertVO.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 com.cloud.alert;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "alert")
+public class AlertVO implements Alert {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "type")
+    private short type;
+
+    @Column(name = "cluster_id")
+    private Long clusterId = null;
+
+    @Column(name = "pod_id")
+    private Long podId = null;
+
+    @Column(name = "data_center_id")
+    private long dataCenterId = 0;
+
+    @Column(name = "subject", length = 999)
+    private String subject;
+
+    @Column(name = "content", length = 5000)
+    private String content;
+
+    @Column(name = "sent_count")
+    private int sentCount = 0;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date createdDate;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "last_sent", updatable = true, nullable = true)
+    private Date lastSent;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "resolved", updatable = true, nullable = true)
+    private Date resolved;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "archived")
+    private boolean archived;
+
+    @Column(name = "name")
+    private String name;
+
+    public AlertVO() {
+        this.uuid = UUID.randomUUID().toString();
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public short getType() {
+        return type;
+    }
+
+    public void setType(short type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public Long getClusterId() {
+        return clusterId;
+    }
+
+    public void setClusterId(Long clusterId) {
+        this.clusterId = clusterId;
+    }
+
+    @Override
+    public Long getPodId() {
+        return podId;
+    }
+
+    public void setPodId(Long podId) {
+        this.podId = podId;
+    }
+
+    @Override
+    public long getDataCenterId() {
+        return dataCenterId;
+    }
+
+    public void setDataCenterId(long dataCenterId) {
+        this.dataCenterId = dataCenterId;
+    }
+
+    @Override
+    public int getSentCount() {
+        return sentCount;
+    }
+
+    public void setSentCount(int sentCount) {
+        this.sentCount = sentCount;
+    }
+
+    @Override
+    public Date getCreatedDate() {
+        return createdDate;
+    }
+
+    public void setCreatedDate(Date createdDate) {
+        this.createdDate = createdDate;
+    }
+
+    @Override
+    public Date getLastSent() {
+        return lastSent;
+    }
+
+    public void setLastSent(Date lastSent) {
+        this.lastSent = lastSent;
+    }
+
+    @Override
+    public Date getResolved() {
+        return resolved;
+    }
+
+    public void setResolved(Date resolved) {
+        this.resolved = resolved;
+    }
+
+    @Override
+    public String getUuid() {
+        return this.uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public boolean getArchived() {
+        return archived;
+    }
+
+    public void setArchived(Boolean archived) {
+        this.archived = archived;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}
diff --git a/engine/schema/src/com/cloud/alert/dao/AlertDao.java b/engine/schema/src/main/java/com/cloud/alert/dao/AlertDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/alert/dao/AlertDao.java
rename to engine/schema/src/main/java/com/cloud/alert/dao/AlertDao.java
diff --git a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java b/engine/schema/src/main/java/com/cloud/alert/dao/AlertDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/alert/dao/AlertDaoImpl.java
diff --git a/engine/schema/src/com/cloud/capacity/CapacityVO.java b/engine/schema/src/main/java/com/cloud/capacity/CapacityVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/capacity/CapacityVO.java
rename to engine/schema/src/main/java/com/cloud/capacity/CapacityVO.java
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDao.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/capacity/dao/CapacityDao.java
rename to engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDao.java
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/capacity/dao/CapacityDaoImpl.java
diff --git a/engine/schema/src/com/cloud/certificate/CertificateVO.java b/engine/schema/src/main/java/com/cloud/certificate/CertificateVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/CertificateVO.java
rename to engine/schema/src/main/java/com/cloud/certificate/CertificateVO.java
diff --git a/engine/schema/src/com/cloud/certificate/CrlVO.java b/engine/schema/src/main/java/com/cloud/certificate/CrlVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/CrlVO.java
rename to engine/schema/src/main/java/com/cloud/certificate/CrlVO.java
diff --git a/engine/schema/src/com/cloud/certificate/dao/CertificateDao.java b/engine/schema/src/main/java/com/cloud/certificate/dao/CertificateDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/dao/CertificateDao.java
rename to engine/schema/src/main/java/com/cloud/certificate/dao/CertificateDao.java
diff --git a/engine/schema/src/com/cloud/certificate/dao/CertificateDaoImpl.java b/engine/schema/src/main/java/com/cloud/certificate/dao/CertificateDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/dao/CertificateDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/certificate/dao/CertificateDaoImpl.java
diff --git a/engine/schema/src/com/cloud/certificate/dao/CrlDao.java b/engine/schema/src/main/java/com/cloud/certificate/dao/CrlDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/dao/CrlDao.java
rename to engine/schema/src/main/java/com/cloud/certificate/dao/CrlDao.java
diff --git a/engine/schema/src/com/cloud/certificate/dao/CrlDaoImpl.java b/engine/schema/src/main/java/com/cloud/certificate/dao/CrlDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/certificate/dao/CrlDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/certificate/dao/CrlDaoImpl.java
diff --git a/engine/schema/src/com/cloud/cluster/agentlb/HostTransferMapVO.java b/engine/schema/src/main/java/com/cloud/cluster/agentlb/HostTransferMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/cluster/agentlb/HostTransferMapVO.java
rename to engine/schema/src/main/java/com/cloud/cluster/agentlb/HostTransferMapVO.java
diff --git a/engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java b/engine/schema/src/main/java/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java
rename to engine/schema/src/main/java/com/cloud/cluster/agentlb/dao/HostTransferMapDao.java
diff --git a/engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/cluster/agentlb/dao/HostTransferMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/configuration/ManagementServiceConfiguration.java b/engine/schema/src/main/java/com/cloud/configuration/ManagementServiceConfiguration.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/ManagementServiceConfiguration.java
rename to engine/schema/src/main/java/com/cloud/configuration/ManagementServiceConfiguration.java
diff --git a/engine/schema/src/com/cloud/configuration/ManagementServiceConfigurationImpl.java b/engine/schema/src/main/java/com/cloud/configuration/ManagementServiceConfigurationImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/ManagementServiceConfigurationImpl.java
rename to engine/schema/src/main/java/com/cloud/configuration/ManagementServiceConfigurationImpl.java
diff --git a/engine/schema/src/com/cloud/configuration/ResourceCountVO.java b/engine/schema/src/main/java/com/cloud/configuration/ResourceCountVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/ResourceCountVO.java
rename to engine/schema/src/main/java/com/cloud/configuration/ResourceCountVO.java
diff --git a/engine/schema/src/com/cloud/configuration/ResourceLimitVO.java b/engine/schema/src/main/java/com/cloud/configuration/ResourceLimitVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/ResourceLimitVO.java
rename to engine/schema/src/main/java/com/cloud/configuration/ResourceLimitVO.java
diff --git a/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDao.java b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDao.java
new file mode 100644
index 0000000..28f2a53
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDao.java
@@ -0,0 +1,71 @@
+// 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.configuration.dao;
+
+import java.util.List;
+import java.util.Set;
+
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.ResourceCountVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
+    /**
+     * @param domainId the id of the domain to get the resource count
+     * @param type the type of resource (e.g. user_vm, public_ip, volume)
+     * @return the count of resources in use for the given type and domain
+     */
+    long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type);
+
+    /**
+     * @param domainId the id of the domain to set the resource count
+     * @param type the type of resource (e.g. user_vm, public_ip, volume)
+     * @param the count of resources in use for the given type and domain
+     */
+    void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count);
+
+    boolean updateById(long id, boolean increment, long delta);
+
+    void createResourceCounts(long ownerId, ResourceOwnerType ownerType);
+
+    List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType);
+
+    ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type);
+
+    List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType);
+
+    Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type);
+
+    Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
+
+    long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
+
+    /**
+     * Counts the number of CPU cores allocated for the given account.
+     *
+     * Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
+     */
+    long countCpuNumberAllocatedToAccount(long accountId);
+
+    /**
+     * Counts the amount of memory allocated for the given account.
+     *
+     * Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
+     */
+    long countMemoryAllocatedToAccount(long accountId);
+}
diff --git a/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDaoImpl.java
new file mode 100644
index 0000000..e724d8e
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDaoImpl.java
@@ -0,0 +1,284 @@
+// 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.configuration.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.ResourceCountVO;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
+    private final SearchBuilder<ResourceCountVO> TypeSearch;
+
+    private final SearchBuilder<ResourceCountVO> AccountSearch;
+    private final SearchBuilder<ResourceCountVO> DomainSearch;
+
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private AccountDao _accountDao;
+
+    public ResourceCountDaoImpl() {
+        TypeSearch = createSearchBuilder();
+        TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeSearch.and("accountId", TypeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        TypeSearch.and("domainId", TypeSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
+        TypeSearch.done();
+
+        AccountSearch = createSearchBuilder();
+        DomainSearch = createSearchBuilder();
+    }
+
+    @PostConstruct
+    protected void configure() {
+        AccountSearch.and("accountId", AccountSearch.entity().getAccountId(), SearchCriteria.Op.NNULL);
+        SearchBuilder<AccountVO> joinAccount = _accountDao.createSearchBuilder();
+        joinAccount.and("notremoved", joinAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
+        AccountSearch.join("account", joinAccount, AccountSearch.entity().getAccountId(), joinAccount.entity().getId(), JoinBuilder.JoinType.INNER);
+        AccountSearch.done();
+
+        DomainSearch.and("domainId", DomainSearch.entity().getDomainId(), SearchCriteria.Op.NNULL);
+        SearchBuilder<DomainVO> joinDomain = _domainDao.createSearchBuilder();
+        joinDomain.and("notremoved", joinDomain.entity().getRemoved(), SearchCriteria.Op.NULL);
+        DomainSearch.join("domain", joinDomain, DomainSearch.entity().getDomainId(), joinDomain.entity().getId(), JoinBuilder.JoinType.INNER);
+        DomainSearch.done();
+    }
+
+    @Override
+    public ResourceCountVO findByOwnerAndType(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
+        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
+        sc.setParameters("type", type);
+
+        if (ownerType == ResourceOwnerType.Account) {
+            sc.setParameters("accountId", ownerId);
+            return findOneIncludingRemovedBy(sc);
+        } else if (ownerType == ResourceOwnerType.Domain) {
+            sc.setParameters("domainId", ownerId);
+            return findOneIncludingRemovedBy(sc);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public long getResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
+        ResourceCountVO vo = findByOwnerAndType(ownerId, ownerType, type);
+        if (vo != null) {
+            return vo.getCount();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public void setResourceCount(long ownerId, ResourceOwnerType ownerType, ResourceType type, long count) {
+        ResourceCountVO resourceCountVO = findByOwnerAndType(ownerId, ownerType, type);
+        if (resourceCountVO != null && count != resourceCountVO.getCount()) {
+            resourceCountVO.setCount(count);
+            update(resourceCountVO.getId(), resourceCountVO);
+        }
+    }
+
+    @Override
+    public boolean updateById(long id, boolean increment, long delta) {
+        delta = increment ? delta : delta * -1;
+
+        ResourceCountVO resourceCountVO = findById(id);
+        resourceCountVO.setCount(resourceCountVO.getCount() + delta);
+        return update(resourceCountVO.getId(), resourceCountVO);
+    }
+
+    @Override
+    public Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type) {
+        Set<Long> rowIds = new HashSet<Long>();
+        Set<Long> domainIdsToUpdate = _domainDao.getDomainParentIds(domainId);
+        for (Long domainIdToUpdate : domainIdsToUpdate) {
+            ResourceCountVO domainCountRecord = findByOwnerAndType(domainIdToUpdate, ResourceOwnerType.Domain, type);
+            if (domainCountRecord != null) {
+                rowIds.add(domainCountRecord.getId());
+            }
+        }
+        return rowIds;
+    }
+
+    @Override
+    public Set<Long> listAllRowsToUpdate(long ownerId, ResourceOwnerType ownerType, ResourceType type) {
+        Set<Long> rowIds = new HashSet<Long>();
+
+        if (ownerType == ResourceOwnerType.Account) {
+            //get records for account
+            ResourceCountVO accountCountRecord = findByOwnerAndType(ownerId, ResourceOwnerType.Account, type);
+            if (accountCountRecord != null) {
+                rowIds.add(accountCountRecord.getId());
+            }
+
+            //get records for account's domain and all its parent domains
+            rowIds.addAll(listRowsToUpdateForDomain(_accountDao.findByIdIncludingRemoved(ownerId).getDomainId(), type));
+        } else if (ownerType == ResourceOwnerType.Domain) {
+            return listRowsToUpdateForDomain(ownerId, type);
+        }
+
+        return rowIds;
+    }
+
+    @Override
+    @DB
+    public void createResourceCounts(long ownerId, ResourceLimit.ResourceOwnerType ownerType) {
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        ResourceType[] resourceTypes = Resource.ResourceType.values();
+        for (ResourceType resourceType : resourceTypes) {
+            if (!resourceType.supportsOwner(ownerType)) {
+                continue;
+            }
+            ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, ownerId, ownerType);
+            persist(resourceCountVO);
+        }
+
+        txn.commit();
+    }
+
+    private List<ResourceCountVO> listByDomainId(long domainId) {
+        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
+        sc.setParameters("domainId", domainId);
+
+        return listBy(sc);
+    }
+
+    private List<ResourceCountVO> listByAccountId(long accountId) {
+        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
+        sc.setParameters("accountId", accountId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<ResourceCountVO> listByOwnerId(long ownerId, ResourceOwnerType ownerType) {
+        if (ownerType == ResourceOwnerType.Account) {
+            return listByAccountId(ownerId);
+        } else if (ownerType == ResourceOwnerType.Domain) {
+            return listByDomainId(ownerId);
+        } else {
+            return new ArrayList<ResourceCountVO>();
+        }
+    }
+
+    @Override
+    public List<ResourceCountVO> listResourceCountByOwnerType(ResourceOwnerType ownerType) {
+        if (ownerType == ResourceOwnerType.Account) {
+            return listBy(AccountSearch.create());
+        } else if (ownerType == ResourceOwnerType.Domain) {
+            return listBy(DomainSearch.create());
+        } else {
+            return new ArrayList<ResourceCountVO>();
+        }
+    }
+
+    @Override
+    public ResourceCountVO persist(ResourceCountVO resourceCountVO) {
+        ResourceOwnerType ownerType = resourceCountVO.getResourceOwnerType();
+        ResourceType resourceType = resourceCountVO.getType();
+        if (!resourceType.supportsOwner(ownerType)) {
+            throw new UnsupportedServiceException("Resource type " + resourceType + " is not supported for owner of type " + ownerType.getName());
+        }
+
+        return super.persist(resourceCountVO);
+    }
+
+    @Override
+    public long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType) {
+        SearchCriteria<ResourceCountVO> sc = TypeSearch.create();
+
+        if (ownerType == ResourceOwnerType.Account) {
+            sc.setParameters("accountId", ownerId);
+            return remove(sc);
+        } else if (ownerType == ResourceOwnerType.Domain) {
+            sc.setParameters("domainId", ownerId);
+            return remove(sc);
+        }
+        return 0;
+    }
+
+    private String baseSqlCountComputingResourceAllocatedToAccount = "Select "
+            + " SUM((CASE "
+            + "        WHEN so.%s is not null THEN so.%s "
+            + "        ELSE CONVERT(vmd.value, UNSIGNED INTEGER) "
+            + "    END)) as total "
+            + " from vm_instance vm "
+            + " join service_offering so on so.id = vm.service_offering_id "
+            + " left join user_vm_details vmd on vmd.vm_id = vm.id and vmd.name = '%s' "
+            + " where vm.type = 'User' and state not in ('Destroyed', 'Error', 'Expunging') and display_vm = true and account_id = ? ";
+
+    @Override
+    public long countCpuNumberAllocatedToAccount(long accountId) {
+        String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, ResourceType.cpu, ResourceType.cpu, "cpuNumber");
+        return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
+    }
+
+    @Override
+    public long countMemoryAllocatedToAccount(long accountId) {
+        String serviceOfferingRamSizeField = "ram_size";
+        String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, serviceOfferingRamSizeField, serviceOfferingRamSizeField, "memory");
+        return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
+    }
+
+    private long executeSqlCountComputingResourcesForAccount(long accountId, String sqlCountComputingResourcesAllocatedToAccount) {
+        TransactionLegacy tx = TransactionLegacy.currentTxn();
+        try {
+            PreparedStatement pstmt = tx.prepareAutoCloseStatement(sqlCountComputingResourcesAllocatedToAccount);
+            pstmt.setLong(1, accountId);
+
+            ResultSet rs = pstmt.executeQuery();
+            if (!rs.next()) {
+                return 0L;
+            }
+            return rs.getLong("total");
+        } catch (SQLException e) {
+            throw new CloudRuntimeException(e);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/engine/schema/src/com/cloud/configuration/dao/ResourceLimitDao.java b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceLimitDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/dao/ResourceLimitDao.java
rename to engine/schema/src/main/java/com/cloud/configuration/dao/ResourceLimitDao.java
diff --git a/engine/schema/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java b/engine/schema/src/main/java/com/cloud/configuration/dao/ResourceLimitDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/configuration/dao/ResourceLimitDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/configuration/dao/ResourceLimitDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/AccountVlanMapVO.java b/engine/schema/src/main/java/com/cloud/dc/AccountVlanMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/AccountVlanMapVO.java
rename to engine/schema/src/main/java/com/cloud/dc/AccountVlanMapVO.java
diff --git a/engine/schema/src/com/cloud/dc/ClusterDetailsDao.java b/engine/schema/src/main/java/com/cloud/dc/ClusterDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/ClusterDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/dc/ClusterDetailsDao.java
diff --git a/engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/ClusterDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/ClusterDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/ClusterDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/ClusterDetailsVO.java b/engine/schema/src/main/java/com/cloud/dc/ClusterDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/ClusterDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/dc/ClusterDetailsVO.java
diff --git a/engine/schema/src/com/cloud/dc/ClusterVO.java b/engine/schema/src/main/java/com/cloud/dc/ClusterVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/ClusterVO.java
rename to engine/schema/src/main/java/com/cloud/dc/ClusterVO.java
diff --git a/engine/schema/src/com/cloud/dc/ClusterVSMMapVO.java b/engine/schema/src/main/java/com/cloud/dc/ClusterVSMMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/ClusterVSMMapVO.java
rename to engine/schema/src/main/java/com/cloud/dc/ClusterVSMMapVO.java
diff --git a/engine/schema/src/com/cloud/dc/DataCenterDetailVO.java b/engine/schema/src/main/java/com/cloud/dc/DataCenterDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DataCenterDetailVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DataCenterDetailVO.java
diff --git a/engine/schema/src/com/cloud/dc/DataCenterIpAddressVO.java b/engine/schema/src/main/java/com/cloud/dc/DataCenterIpAddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DataCenterIpAddressVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DataCenterIpAddressVO.java
diff --git a/engine/schema/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java b/engine/schema/src/main/java/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DataCenterLinkLocalIpAddressVO.java
diff --git a/engine/schema/src/com/cloud/dc/DataCenterVO.java b/engine/schema/src/main/java/com/cloud/dc/DataCenterVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DataCenterVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DataCenterVO.java
diff --git a/engine/schema/src/com/cloud/dc/DataCenterVnetVO.java b/engine/schema/src/main/java/com/cloud/dc/DataCenterVnetVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DataCenterVnetVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DataCenterVnetVO.java
diff --git a/engine/schema/src/com/cloud/dc/DomainVlanMapVO.java b/engine/schema/src/main/java/com/cloud/dc/DomainVlanMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/DomainVlanMapVO.java
rename to engine/schema/src/main/java/com/cloud/dc/DomainVlanMapVO.java
diff --git a/engine/schema/src/com/cloud/dc/HostPodVO.java b/engine/schema/src/main/java/com/cloud/dc/HostPodVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/HostPodVO.java
rename to engine/schema/src/main/java/com/cloud/dc/HostPodVO.java
diff --git a/engine/schema/src/com/cloud/dc/PodCluster.java b/engine/schema/src/main/java/com/cloud/dc/PodCluster.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/PodCluster.java
rename to engine/schema/src/main/java/com/cloud/dc/PodCluster.java
diff --git a/engine/schema/src/com/cloud/dc/PodVlanMapVO.java b/engine/schema/src/main/java/com/cloud/dc/PodVlanMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/PodVlanMapVO.java
rename to engine/schema/src/main/java/com/cloud/dc/PodVlanMapVO.java
diff --git a/engine/schema/src/com/cloud/dc/PodVlanVO.java b/engine/schema/src/main/java/com/cloud/dc/PodVlanVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/PodVlanVO.java
rename to engine/schema/src/main/java/com/cloud/dc/PodVlanVO.java
diff --git a/engine/schema/src/com/cloud/dc/StorageNetworkIpAddressVO.java b/engine/schema/src/main/java/com/cloud/dc/StorageNetworkIpAddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/StorageNetworkIpAddressVO.java
rename to engine/schema/src/main/java/com/cloud/dc/StorageNetworkIpAddressVO.java
diff --git a/engine/schema/src/com/cloud/dc/StorageNetworkIpRangeVO.java b/engine/schema/src/main/java/com/cloud/dc/StorageNetworkIpRangeVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/StorageNetworkIpRangeVO.java
rename to engine/schema/src/main/java/com/cloud/dc/StorageNetworkIpRangeVO.java
diff --git a/engine/schema/src/com/cloud/dc/VlanDetailsVO.java b/engine/schema/src/main/java/com/cloud/dc/VlanDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/VlanDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/dc/VlanDetailsVO.java
diff --git a/engine/schema/src/main/java/com/cloud/dc/VlanVO.java b/engine/schema/src/main/java/com/cloud/dc/VlanVO.java
new file mode 100644
index 0000000..ebbd4bd
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/dc/VlanVO.java
@@ -0,0 +1,239 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.dc;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "vlan")
+public class VlanVO implements Vlan {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    Long id;
+
+    @Column(name = "vlan_id")
+    String vlanTag;
+
+    @Column(name = "vlan_gateway")
+    String vlanGateway;
+
+    @Column(name = "vlan_netmask")
+    String vlanNetmask;
+
+    @Column(name = "ip6_gateway")
+    String ip6Gateway;
+
+    @Column(name = "ip6_cidr")
+    String ip6Cidr;
+
+    @Column(name = "data_center_id")
+    long dataCenterId;
+
+    @Column(name = "ip4_range")
+    String ipRange;
+
+    @Column(name = "ip6_range")
+    String ip6Range;
+
+    @Column(name = "network_id")
+    Long networkId;
+
+    @Column(name = "physical_network_id")
+    Long physicalNetworkId;
+
+    @Column(name = "vlan_type")
+    @Enumerated(EnumType.STRING)
+    VlanType vlanType;
+
+    @Column(name = "uuid")
+    String uuid;
+
+    @Column(name= GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+
+    public VlanVO(VlanType vlanType, String vlanTag, String vlanGateway, String vlanNetmask, long dataCenterId, String ipRange, Long networkId, Long physicalNetworkId,
+            String ip6Gateway, String ip6Cidr, String ip6Range) {
+        this.vlanType = vlanType;
+        this.vlanTag = vlanTag;
+        this.vlanGateway = vlanGateway;
+        this.vlanNetmask = vlanNetmask;
+        this.ip6Gateway = ip6Gateway;
+        this.ip6Cidr = ip6Cidr;
+        this.dataCenterId = dataCenterId;
+        this.ipRange = ipRange;
+        this.ip6Range = ip6Range;
+        this.networkId = networkId;
+        this.uuid = UUID.randomUUID().toString();
+        this.physicalNetworkId = physicalNetworkId;
+    }
+
+    public VlanVO() {
+        this.uuid = UUID.randomUUID().toString();
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getVlanTag() {
+        return vlanTag;
+    }
+
+    @Override
+    public String getVlanGateway() {
+        return vlanGateway;
+    }
+
+    @Override
+    public String getVlanNetmask() {
+        return vlanNetmask;
+    }
+
+    @Override
+    public long getDataCenterId() {
+        return dataCenterId;
+    }
+
+    public void setDataCenterId(long dcId) {
+        this.dataCenterId = dcId;
+    }
+
+    @Override
+    public String getIpRange() {
+        return ipRange;
+    }
+
+    @Override
+    public VlanType getVlanType() {
+        return vlanType;
+    }
+
+    @Override
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public void setNetworkId(Long networkId) {
+        this.networkId = networkId;
+    }
+
+    @Override
+    public String getUuid() {
+        return this.uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
+    public Long getPhysicalNetworkId() {
+        return physicalNetworkId;
+    }
+
+    public void setPhysicalNetworkId(Long physicalNetworkId) {
+        this.physicalNetworkId = physicalNetworkId;
+    }
+
+    transient String toString;
+
+    @Override
+    public String toString() {
+        if (toString == null) {
+            toString =
+                    new StringBuilder("Vlan[").append(vlanTag)
+                    .append("|")
+                    .append(vlanGateway)
+                    .append("|")
+                    .append(vlanNetmask)
+                    .append("|")
+                    .append(ip6Gateway)
+                    .append("|")
+                    .append(ip6Cidr)
+                    .append("|")
+                    .append(ipRange)
+                    .append("|")
+                    .append("|")
+                    .append(ip6Range)
+                    .append(networkId)
+                    .append("]")
+                    .toString();
+        }
+        return toString;
+    }
+
+    @Override
+    public String getIp6Gateway() {
+        return ip6Gateway;
+    }
+
+    public void setIp6Gateway(String ip6Gateway) {
+        this.ip6Gateway = ip6Gateway;
+    }
+
+    @Override
+    public String getIp6Cidr() {
+        return ip6Cidr;
+    }
+
+    public void setIp6Cidr(String ip6Cidr) {
+        this.ip6Cidr = ip6Cidr;
+    }
+
+    @Override
+    public String getIp6Range() {
+        return ip6Range;
+    }
+
+    public void setIp6Range(String ip6Range) {
+        this.ip6Range = ip6Range;
+    }
+
+    public void setIpRange(String ipRange) {
+        this.ip6Range = ipRange;
+    }
+}
diff --git a/engine/schema/src/com/cloud/dc/dao/AccountVlanMapDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/AccountVlanMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/AccountVlanMapDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/AccountVlanMapDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/AccountVlanMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/AccountVlanMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/AccountVlanMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/ClusterDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/ClusterDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/ClusterDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterVSMMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/ClusterVSMMapDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/ClusterVSMMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDetailsDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDetailsDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterIpAddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterIpAddressDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterLinkLocalIpAddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterVnetDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterVnetDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterVnetDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DataCenterVnetDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DomainVlanMapDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/DomainVlanMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DomainVlanMapDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DomainVlanMapDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/DomainVlanMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/DomainVlanMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/DomainVlanMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/DomainVlanMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/HostPodDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/HostPodDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/HostPodDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/HostPodDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/HostPodDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/PodVlanDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/PodVlanDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/PodVlanDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/PodVlanDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/PodVlanDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/PodVlanDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/PodVlanDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/PodVlanMapDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/PodVlanMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/PodVlanMapDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/PodVlanMapDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/PodVlanMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/PodVlanMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/PodVlanMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpAddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpAddressDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpRangeDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpRangeDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
new file mode 100644
index 0000000..a3e3c60
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.dc.dao;
+
+import java.util.List;
+
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VlanDao extends GenericDao<VlanVO, Long> {
+
+    VlanVO findByZoneAndVlanId(long zoneId, String vlanId);
+
+    VlanVO findByNetworkIdAndIpv4(long networkId, String ipv4Address);
+
+    List<VlanVO> listByZone(long zoneId);
+
+    List<VlanVO> listByType(Vlan.VlanType vlanType);
+
+    List<VlanVO> listByZoneAndType(long zoneId, Vlan.VlanType vlanType);
+
+    List<VlanVO> listVlansForPod(long podId);
+
+    List<VlanVO> listVlansForPodByType(long podId, Vlan.VlanType vlanType);
+
+    void addToPod(long podId, long vlanDbId);
+
+    List<VlanVO> listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType);
+
+    boolean zoneHasDirectAttachUntaggedVlans(long zoneId);
+
+    List<VlanVO> listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId);
+
+    List<VlanVO> searchForZoneWideVlans(long dcId, String vlanType, String vlanId);
+
+    List<VlanVO> listVlansByNetworkId(long networkId);
+
+    List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId);
+
+    List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId);
+
+    List<VlanVO> listZoneWideNonDedicatedVlans(long zoneId);
+
+    List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway);
+
+    List<VlanVO> listDedicatedVlans(long accountId);
+}
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
new file mode 100644
index 0000000..2737beb
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
@@ -0,0 +1,393 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.dc.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.DomainVlanMapVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+@Component
+public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao {
+
+    private final String FindZoneWideVlans =
+        "SELECT * FROM vlan WHERE data_center_id=? and vlan_type=? and vlan_id!=? and id not in (select vlan_db_id from account_vlan_map)";
+
+    protected SearchBuilder<VlanVO> ZoneVlanIdSearch;
+    protected SearchBuilder<VlanVO> ZoneSearch;
+    protected SearchBuilder<VlanVO> ZoneTypeSearch;
+    protected SearchBuilder<VlanVO> ZoneTypeAllPodsSearch;
+    protected SearchBuilder<VlanVO> ZoneTypePodSearch;
+    protected SearchBuilder<VlanVO> ZoneVlanSearch;
+    protected SearchBuilder<VlanVO> NetworkVlanSearch;
+    protected SearchBuilder<VlanVO> PhysicalNetworkVlanSearch;
+    protected SearchBuilder<VlanVO> ZoneWideNonDedicatedVlanSearch;
+    protected SearchBuilder<VlanVO> VlanGatewaysearch;
+    protected SearchBuilder<VlanVO> DedicatedVlanSearch;
+
+    protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch;
+    protected SearchBuilder<DomainVlanMapVO> DomainVlanMapSearch;
+
+    @Inject
+    protected PodVlanMapDao _podVlanMapDao;
+    @Inject
+    protected AccountVlanMapDao _accountVlanMapDao;
+    @Inject
+    protected DomainVlanMapDao _domainVlanMapDao;
+    @Inject
+    protected IPAddressDao _ipAddressDao;
+
+    @Override
+    public VlanVO findByZoneAndVlanId(long zoneId, String vlanId) {
+        SearchCriteria<VlanVO> sc = ZoneVlanIdSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("vlanId", vlanId);
+        return findOneBy(sc);
+    }
+
+    /**
+     * Returns a vlan by the network id and if the given IPv4 is in the network IP range.
+     */
+    @Override
+    public VlanVO findByNetworkIdAndIpv4(long networkId, String ipv4Address) {
+        List<VlanVO> vlanVoList = listVlansByNetworkId(networkId);
+        for (VlanVO vlan : vlanVoList) {
+            String ipRange = vlan.getIpRange();
+            String[] ipRangeParts = ipRange.split("-");
+            String startIP = ipRangeParts[0];
+            String endIP = ipRangeParts[1];
+            if (NetUtils.isIpInRange(ipv4Address, startIP, endIP)) {
+                return vlan;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<VlanVO> listByZone(long zoneId) {
+        SearchCriteria<VlanVO> sc = ZoneSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        return listBy(sc);
+    }
+
+    public VlanDaoImpl() {
+        ZoneVlanIdSearch = createSearchBuilder();
+        ZoneVlanIdSearch.and("zoneId", ZoneVlanIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        ZoneVlanIdSearch.and("vlanId", ZoneVlanIdSearch.entity().getVlanTag(), SearchCriteria.Op.EQ);
+        ZoneVlanIdSearch.done();
+
+        ZoneSearch = createSearchBuilder();
+        ZoneSearch.and("zoneId", ZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        ZoneSearch.done();
+
+        ZoneTypeSearch = createSearchBuilder();
+        ZoneTypeSearch.and("zoneId", ZoneTypeSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        ZoneTypeSearch.and("vlanType", ZoneTypeSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
+        ZoneTypeSearch.done();
+
+        NetworkVlanSearch = createSearchBuilder();
+        NetworkVlanSearch.and("networkId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        NetworkVlanSearch.done();
+
+        PhysicalNetworkVlanSearch = createSearchBuilder();
+        PhysicalNetworkVlanSearch.and("physicalNetworkId", PhysicalNetworkVlanSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
+        PhysicalNetworkVlanSearch.done();
+
+        VlanGatewaysearch = createSearchBuilder();
+        VlanGatewaysearch.and("gateway", VlanGatewaysearch.entity().getVlanGateway(), SearchCriteria.Op.EQ);
+        VlanGatewaysearch.and("networkid", VlanGatewaysearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        VlanGatewaysearch.done();
+    }
+
+    @Override
+    public List<VlanVO> listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId) {
+        SearchCriteria<VlanVO> sc = ZoneVlanSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("vlanId", vlanId);
+        sc.setParameters("vlanType", vlanType);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listByZoneAndType(long zoneId, VlanType vlanType) {
+        SearchCriteria<VlanVO> sc = ZoneTypeSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("vlanType", vlanType);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listByType(VlanType vlanType) {
+        SearchCriteria<VlanVO> sc = ZoneTypeSearch.create();
+        sc.setParameters("vlanType", vlanType);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listVlansForPod(long podId) {
+        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two
+        List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId);
+        List<VlanVO> result = new ArrayList<VlanVO>();
+        for (PodVlanMapVO pvmvo : vlanMaps) {
+            result.add(findById(pvmvo.getVlanDbId()));
+        }
+        return result;
+    }
+
+    @Override
+    public List<VlanVO> listVlansForPodByType(long podId, VlanType vlanType) {
+        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two)
+        List<PodVlanMapVO> vlanMaps = _podVlanMapDao.listPodVlanMapsByPod(podId);
+        List<VlanVO> result = new ArrayList<VlanVO>();
+        for (PodVlanMapVO pvmvo : vlanMaps) {
+            VlanVO vlan = findById(pvmvo.getVlanDbId());
+            if (vlan.getVlanType() == vlanType) {
+                result.add(vlan);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public List<VlanVO> listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType) {
+        //FIXME: use a join statement to improve the performance (should be minor since we expect only one or two)
+        List<AccountVlanMapVO> vlanMaps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId);
+        List<VlanVO> result = new ArrayList<VlanVO>();
+        for (AccountVlanMapVO acvmvo : vlanMaps) {
+            VlanVO vlan = findById(acvmvo.getVlanDbId());
+            if (vlan.getVlanType() == vlanType && (zoneId == null || vlan.getDataCenterId() == zoneId)) {
+                result.add(vlan);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void addToPod(long podId, long vlanDbId) {
+        PodVlanMapVO pvmvo = new PodVlanMapVO(podId, vlanDbId);
+        _podVlanMapDao.persist(pvmvo);
+
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        boolean result = super.configure(name, params);
+        ZoneTypeAllPodsSearch = createSearchBuilder();
+        ZoneTypeAllPodsSearch.and("zoneId", ZoneTypeAllPodsSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        ZoneTypeAllPodsSearch.and("vlanType", ZoneTypeAllPodsSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
+
+        SearchBuilder<PodVlanMapVO> PodVlanSearch = _podVlanMapDao.createSearchBuilder();
+        PodVlanSearch.and("podId", PodVlanSearch.entity().getPodId(), SearchCriteria.Op.NNULL);
+        ZoneTypeAllPodsSearch.join("vlan", PodVlanSearch, PodVlanSearch.entity().getVlanDbId(), ZoneTypeAllPodsSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        ZoneTypeAllPodsSearch.done();
+        PodVlanSearch.done();
+
+        ZoneTypePodSearch = createSearchBuilder();
+        ZoneTypePodSearch.and("zoneId", ZoneTypePodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        ZoneTypePodSearch.and("vlanType", ZoneTypePodSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
+
+        SearchBuilder<PodVlanMapVO> PodVlanSearch2 = _podVlanMapDao.createSearchBuilder();
+        PodVlanSearch2.and("podId", PodVlanSearch2.entity().getPodId(), SearchCriteria.Op.EQ);
+        ZoneTypePodSearch.join("vlan", PodVlanSearch2, PodVlanSearch2.entity().getVlanDbId(), ZoneTypePodSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        PodVlanSearch2.done();
+        ZoneTypePodSearch.done();
+
+        ZoneWideNonDedicatedVlanSearch = createSearchBuilder();
+        ZoneWideNonDedicatedVlanSearch.and("zoneId", ZoneWideNonDedicatedVlanSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
+        AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.NULL);
+        ZoneWideNonDedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, ZoneWideNonDedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity()
+            .getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER);
+        DomainVlanMapSearch = _domainVlanMapDao.createSearchBuilder();
+        DomainVlanMapSearch.and("domainId", DomainVlanMapSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
+        ZoneWideNonDedicatedVlanSearch.join("DomainVlanMapSearch", DomainVlanMapSearch, ZoneWideNonDedicatedVlanSearch.entity().getId(), DomainVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER);
+        ZoneWideNonDedicatedVlanSearch.done();
+        AccountVlanMapSearch.done();
+        DomainVlanMapSearch.done();
+
+        DedicatedVlanSearch = createSearchBuilder();
+        AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
+        AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        DedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, DedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity().getVlanDbId(),
+            JoinBuilder.JoinType.LEFTOUTER);
+        DedicatedVlanSearch.done();
+        AccountVlanMapSearch.done();
+
+        return result;
+    }
+
+    private VlanVO findNextVlan(long zoneId, Vlan.VlanType vlanType) {
+        List<VlanVO> allVlans = listByZoneAndType(zoneId, vlanType);
+        List<VlanVO> emptyVlans = new ArrayList<VlanVO>();
+        List<VlanVO> fullVlans = new ArrayList<VlanVO>();
+
+        // Try to find a VLAN that is partially allocated
+        for (VlanVO vlan : allVlans) {
+            long vlanDbId = vlan.getId();
+
+            int countOfAllocatedIps = _ipAddressDao.countIPs(zoneId, vlanDbId, true);
+            int countOfAllIps = _ipAddressDao.countIPs(zoneId, vlanDbId, false);
+
+            if ((countOfAllocatedIps > 0) && (countOfAllocatedIps < countOfAllIps)) {
+                return vlan;
+            } else if (countOfAllocatedIps == 0) {
+                emptyVlans.add(vlan);
+            } else if (countOfAllocatedIps == countOfAllIps) {
+                fullVlans.add(vlan);
+            }
+        }
+
+        if (emptyVlans.isEmpty()) {
+            return null;
+        }
+
+        // Try to find an empty VLAN with the same tag/subnet as a VLAN that is full
+        for (VlanVO fullVlan : fullVlans) {
+            for (VlanVO emptyVlan : emptyVlans) {
+                if (fullVlan.getVlanTag().equals(emptyVlan.getVlanTag()) && fullVlan.getVlanGateway().equals(emptyVlan.getVlanGateway()) &&
+                    fullVlan.getVlanNetmask().equals(emptyVlan.getVlanNetmask())) {
+                    return emptyVlan;
+                }
+            }
+        }
+
+        // Return a random empty VLAN
+        return emptyVlans.get(0);
+    }
+
+    @Override
+    public boolean zoneHasDirectAttachUntaggedVlans(long zoneId) {
+        SearchCriteria<VlanVO> sc = ZoneTypeAllPodsSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("vlanType", VlanType.DirectAttached);
+
+        return listIncludingRemovedBy(sc).size() > 0;
+    }
+
+    public Pair<String, VlanVO> assignPodDirectAttachIpAddress(long zoneId, long podId, long accountId, long domainId) {
+        SearchCriteria<VlanVO> sc = ZoneTypePodSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("vlanType", VlanType.DirectAttached);
+        sc.setJoinParameters("vlan", "podId", podId);
+
+        VlanVO vlan = findOneIncludingRemovedBy(sc);
+        if (vlan == null) {
+            return null;
+        }
+
+        return null;
+//        String ipAddress = _ipAddressDao.assignIpAddress(accountId, domainId, vlan.getId(), false).getAddress();
+//        if (ipAddress == null) {
+//            return null;
+//        }
+//        return new Pair<String, VlanVO>(ipAddress, vlan);
+
+    }
+
+    @Override
+    @DB
+    public List<VlanVO> searchForZoneWideVlans(long dcId, String vlanType, String vlanId) {
+        StringBuilder sql = new StringBuilder(FindZoneWideVlans);
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        List<VlanVO> zoneWideVlans = new ArrayList<VlanVO>();
+        try(PreparedStatement pstmt = txn.prepareStatement(sql.toString());){
+            if(pstmt != null) {
+                pstmt.setLong(1, dcId);
+                pstmt.setString(2, vlanType);
+                pstmt.setString(3, vlanId);
+                try(ResultSet rs = pstmt.executeQuery();) {
+                    while (rs.next()) {
+                        zoneWideVlans.add(toEntityBean(rs, false));
+                    }
+                }catch (SQLException e) {
+                    throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e);
+                }
+            }
+            return zoneWideVlans;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("searchForZoneWideVlans:Exception:" + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public List<VlanVO> listVlansByNetworkId(long networkId) {
+        SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
+        sc.setParameters("networkId", networkId);
+        return listBy(sc);
+    }
+
+    @Override public List<VlanVO> listVlansByNetworkIdIncludingRemoved(long networkId) {
+        SearchCriteria<VlanVO> sc = NetworkVlanSearch.create();
+        sc.setParameters("networkId", networkId);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway) {
+        SearchCriteria<VlanVO> sc = VlanGatewaysearch.create();
+        sc.setParameters("networkid", networkid);
+        sc.setParameters("gateway", gateway);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listVlansByPhysicalNetworkId(long physicalNetworkId) {
+        SearchCriteria<VlanVO> sc = PhysicalNetworkVlanSearch.create();
+        sc.setParameters("physicalNetworkId", physicalNetworkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listZoneWideNonDedicatedVlans(long zoneId) {
+        SearchCriteria<VlanVO> sc = ZoneWideNonDedicatedVlanSearch.create();
+        sc.setParameters("zoneId", zoneId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VlanVO> listDedicatedVlans(long accountId) {
+        SearchCriteria<VlanVO> sc = DedicatedVlanSearch.create();
+        sc.setJoinParameters("AccountVlanMapSearch", "accountId", accountId);
+        return listBy(sc);
+    }
+
+}
diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/VlanDetailsDao.java
diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/dc/dao/VlanDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/domain/DomainDetailVO.java b/engine/schema/src/main/java/com/cloud/domain/DomainDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/DomainDetailVO.java
rename to engine/schema/src/main/java/com/cloud/domain/DomainDetailVO.java
diff --git a/engine/schema/src/com/cloud/domain/DomainVO.java b/engine/schema/src/main/java/com/cloud/domain/DomainVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/DomainVO.java
rename to engine/schema/src/main/java/com/cloud/domain/DomainVO.java
diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDao.java b/engine/schema/src/main/java/com/cloud/domain/dao/DomainDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/dao/DomainDao.java
rename to engine/schema/src/main/java/com/cloud/domain/dao/DomainDao.java
diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java b/engine/schema/src/main/java/com/cloud/domain/dao/DomainDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/domain/dao/DomainDaoImpl.java
diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDetailsDao.java b/engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/dao/DomainDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDao.java
diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/domain/dao/DomainDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/event/EventVO.java b/engine/schema/src/main/java/com/cloud/event/EventVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/EventVO.java
rename to engine/schema/src/main/java/com/cloud/event/EventVO.java
diff --git a/engine/schema/src/com/cloud/event/UsageEventDetailsVO.java b/engine/schema/src/main/java/com/cloud/event/UsageEventDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/UsageEventDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/event/UsageEventDetailsVO.java
diff --git a/engine/schema/src/com/cloud/event/UsageEventVO.java b/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/UsageEventVO.java
rename to engine/schema/src/main/java/com/cloud/event/UsageEventVO.java
diff --git a/engine/schema/src/com/cloud/event/dao/EventDao.java b/engine/schema/src/main/java/com/cloud/event/dao/EventDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/EventDao.java
rename to engine/schema/src/main/java/com/cloud/event/dao/EventDao.java
diff --git a/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java b/engine/schema/src/main/java/com/cloud/event/dao/EventDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/EventDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/event/dao/EventDaoImpl.java
diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDao.java b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/UsageEventDao.java
rename to engine/schema/src/main/java/com/cloud/event/dao/UsageEventDao.java
diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/UsageEventDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java
diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDao.java b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/UsageEventDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/event/dao/UsageEventDetailsDao.java
diff --git a/engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/event/dao/UsageEventDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/event/dao/UsageEventDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java b/engine/schema/src/main/java/com/cloud/gpu/HostGpuGroupsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/HostGpuGroupsVO.java
rename to engine/schema/src/main/java/com/cloud/gpu/HostGpuGroupsVO.java
diff --git a/engine/schema/src/com/cloud/gpu/VGPUTypesVO.java b/engine/schema/src/main/java/com/cloud/gpu/VGPUTypesVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/VGPUTypesVO.java
rename to engine/schema/src/main/java/com/cloud/gpu/VGPUTypesVO.java
diff --git a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java b/engine/schema/src/main/java/com/cloud/gpu/dao/HostGpuGroupsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDao.java
rename to engine/schema/src/main/java/com/cloud/gpu/dao/HostGpuGroupsDao.java
diff --git a/engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java b/engine/schema/src/main/java/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/gpu/dao/HostGpuGroupsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java b/engine/schema/src/main/java/com/cloud/gpu/dao/VGPUTypesDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/dao/VGPUTypesDao.java
rename to engine/schema/src/main/java/com/cloud/gpu/dao/VGPUTypesDao.java
diff --git a/engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java b/engine/schema/src/main/java/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/gpu/dao/VGPUTypesDaoImpl.java
diff --git a/engine/schema/src/com/cloud/host/DetailVO.java b/engine/schema/src/main/java/com/cloud/host/DetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/DetailVO.java
rename to engine/schema/src/main/java/com/cloud/host/DetailVO.java
diff --git a/engine/schema/src/com/cloud/host/HostTagVO.java b/engine/schema/src/main/java/com/cloud/host/HostTagVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/HostTagVO.java
rename to engine/schema/src/main/java/com/cloud/host/HostTagVO.java
diff --git a/engine/schema/src/com/cloud/host/HostVO.java b/engine/schema/src/main/java/com/cloud/host/HostVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/HostVO.java
rename to engine/schema/src/main/java/com/cloud/host/HostVO.java
diff --git a/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java
new file mode 100644
index 0000000..1fca86c
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/host/dao/HostDao.java
@@ -0,0 +1,110 @@
+// 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.host.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.resource.ResourceState;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+/**
+ * Data Access Object for server
+ *
+ */
+public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Status.Event, Host> {
+    long countBy(long clusterId, ResourceState... states);
+
+    /**
+     * Mark all hosts associated with a certain management server
+     * as disconnected.
+     *
+     * @param msId management server id.
+     */
+    void markHostsAsDisconnected(long msId, long lastPing);
+
+    List<HostVO> findLostHosts(long timeout);
+
+    List<HostVO> findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId);
+
+    List<RunningHostCountInfo> getRunningHostCounts(Date cutTime);
+
+    long getNextSequence(long hostId);
+
+    void loadDetails(HostVO host);
+
+    void saveDetails(HostVO host);
+
+    void loadHostTags(HostVO host);
+
+    List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag);
+
+    List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId);
+
+    boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo);
+
+    HostVO findByGuid(String guid);
+
+    HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type);
+
+    List<HostVO> findHypervisorHostInCluster(long clusterId);
+
+    List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag);
+
+    List<HostVO> findByDataCenterId(Long zoneId);
+
+    List<HostVO> findByPodId(Long podId);
+
+    List<HostVO> findByClusterId(Long clusterId);
+
+    List<HostVO> listByDataCenterId(long id);
+
+    List<HostVO> listByDataCenterIdAndHypervisorType(long zoneId, Hypervisor.HypervisorType hypervisorType);
+
+    List<Long> listAllHosts(long zoneId);
+
+    List<HostVO> listAllHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType);
+
+    List<HostVO> listAllHostsByType(Host.Type type);
+
+    HostVO findByPublicIp(String publicIp);
+
+    List<Long> listClustersByHostTag(String hostTagOnOffering);
+
+    List<HostVO> listByType(Type type);
+
+    HostVO findByIp(String ip);
+
+    /**
+     * This method will look for a host that is of the same hypervisor and zone as indicated in its parameters.
+     * <ul>
+     * <li>We give priority to 'Enabled' hosts, but if no 'Enabled' hosts are found, we use 'Disabled' hosts
+     * <li>If no host is found, we throw a runtime exception
+     * </ul>
+     *
+     * Side note: this method is currently only used in XenServerGuru; therefore, it was designed to meet XenServer deployment scenarios requirements.
+     */
+    HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType);
+}
diff --git a/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java
new file mode 100644
index 0000000..8c8c082
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java
@@ -0,0 +1,1207 @@
+// 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.host.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TimeZone;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.persistence.TableGenerator;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.VgpuTypesInfo;
+import com.cloud.cluster.agentlb.HostTransferMapVO;
+import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
+import com.cloud.configuration.ManagementServiceConfiguration;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.gpu.dao.VGPUTypesDao;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostTagVO;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.Status.Event;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.org.Grouping;
+import com.cloud.org.Managed;
+import com.cloud.resource.ResourceState;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.Attribute;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@DB
+@TableGenerator(name = "host_req_sq", table = "op_host", pkColumnName = "id", valueColumnName = "sequence", allocationSize = 1)
+public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao { //FIXME: , ExternalIdDao {
+    private static final Logger s_logger = Logger.getLogger(HostDaoImpl.class);
+    private static final Logger status_logger = Logger.getLogger(Status.class);
+    private static final Logger state_logger = Logger.getLogger(ResourceState.class);
+
+    private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join host_tags on host.id = host_tags.host_id and host_tags.tag = ?";
+
+    protected SearchBuilder<HostVO> TypePodDcStatusSearch;
+
+    protected SearchBuilder<HostVO> IdStatusSearch;
+    protected SearchBuilder<HostVO> TypeDcSearch;
+    protected SearchBuilder<HostVO> TypeDcStatusSearch;
+    protected SearchBuilder<HostVO> TypeClusterStatusSearch;
+    protected SearchBuilder<HostVO> MsStatusSearch;
+    protected SearchBuilder<HostVO> DcPrivateIpAddressSearch;
+    protected SearchBuilder<HostVO> DcStorageIpAddressSearch;
+    protected SearchBuilder<HostVO> PublicIpAddressSearch;
+    protected SearchBuilder<HostVO> AnyIpAddressSearch;
+
+    protected SearchBuilder<HostVO> GuidSearch;
+    protected SearchBuilder<HostVO> DcSearch;
+    protected SearchBuilder<HostVO> PodSearch;
+    protected SearchBuilder<HostVO> ClusterSearch;
+    protected SearchBuilder<HostVO> TypeSearch;
+    protected SearchBuilder<HostVO> StatusSearch;
+    protected SearchBuilder<HostVO> ResourceStateSearch;
+    protected SearchBuilder<HostVO> NameLikeSearch;
+    protected SearchBuilder<HostVO> NameSearch;
+    protected SearchBuilder<HostVO> SequenceSearch;
+    protected SearchBuilder<HostVO> DirectlyConnectedSearch;
+    protected SearchBuilder<HostVO> UnmanagedDirectConnectSearch;
+    protected SearchBuilder<HostVO> UnmanagedApplianceSearch;
+    protected SearchBuilder<HostVO> MaintenanceCountSearch;
+    protected SearchBuilder<HostVO> ClusterStatusSearch;
+    protected SearchBuilder<HostVO> TypeNameZoneSearch;
+    protected SearchBuilder<HostVO> AvailHypevisorInZone;
+
+    protected SearchBuilder<HostVO> DirectConnectSearch;
+    protected SearchBuilder<HostVO> ManagedDirectConnectSearch;
+    protected SearchBuilder<HostVO> ManagedRoutingServersSearch;
+    protected SearchBuilder<HostVO> SecondaryStorageVMSearch;
+
+    protected GenericSearchBuilder<HostVO, Long> HostIdSearch;
+    protected GenericSearchBuilder<HostVO, Long> HostsInStatusSearch;
+    protected GenericSearchBuilder<HostVO, Long> CountRoutingByDc;
+    protected SearchBuilder<HostTransferMapVO> HostTransferSearch;
+    protected SearchBuilder<ClusterVO> ClusterManagedSearch;
+    protected SearchBuilder<HostVO> RoutingSearch;
+
+    protected SearchBuilder<HostVO> HostsForReconnectSearch;
+    protected GenericSearchBuilder<HostVO, Long> ClustersOwnedByMSSearch;
+    protected GenericSearchBuilder<HostVO, Long> ClustersForHostsNotOwnedByAnyMSSearch;
+    protected GenericSearchBuilder<ClusterVO, Long> AllClustersSearch;
+    protected SearchBuilder<HostVO> HostsInClusterSearch;
+
+    protected Attribute _statusAttr;
+    protected Attribute _resourceStateAttr;
+    protected Attribute _msIdAttr;
+    protected Attribute _pingTimeAttr;
+
+    @Inject
+    protected HostDetailsDao _detailsDao;
+    @Inject
+    protected HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    protected VGPUTypesDao _vgpuTypesDao;
+    @Inject
+    protected HostTagsDao _hostTagsDao;
+    @Inject
+    protected HostTransferMapDao _hostTransferDao;
+    @Inject
+    protected ClusterDao _clusterDao;
+    @Inject
+    ManagementServiceConfiguration mgmtServiceConf;
+
+    public HostDaoImpl() {
+        super();
+    }
+
+    @PostConstruct
+    public void init() {
+
+        MaintenanceCountSearch = createSearchBuilder();
+        MaintenanceCountSearch.and("cluster", MaintenanceCountSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        MaintenanceCountSearch.and("resourceState", MaintenanceCountSearch.entity().getResourceState(), SearchCriteria.Op.IN);
+        MaintenanceCountSearch.done();
+
+        TypePodDcStatusSearch = createSearchBuilder();
+        HostVO entity = TypePodDcStatusSearch.entity();
+        TypePodDcStatusSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
+        TypePodDcStatusSearch.done();
+
+        MsStatusSearch = createSearchBuilder();
+        MsStatusSearch.and("ms", MsStatusSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+        MsStatusSearch.and("type", MsStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
+        MsStatusSearch.and("resourceState", MsStatusSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
+        MsStatusSearch.done();
+
+        TypeDcSearch = createSearchBuilder();
+        TypeDcSearch.and("type", TypeDcSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeDcSearch.and("dc", TypeDcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        TypeDcSearch.done();
+
+        SecondaryStorageVMSearch = createSearchBuilder();
+        SecondaryStorageVMSearch.and("type", SecondaryStorageVMSearch.entity().getType(), SearchCriteria.Op.EQ);
+        SecondaryStorageVMSearch.and("dc", SecondaryStorageVMSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        SecondaryStorageVMSearch.and("status", SecondaryStorageVMSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        SecondaryStorageVMSearch.done();
+
+        TypeDcStatusSearch = createSearchBuilder();
+        TypeDcStatusSearch.and("type", TypeDcStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeDcStatusSearch.and("dc", TypeDcStatusSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        TypeDcStatusSearch.and("status", TypeDcStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        TypeDcStatusSearch.and("resourceState", TypeDcStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
+        TypeDcStatusSearch.done();
+
+        TypeClusterStatusSearch = createSearchBuilder();
+        TypeClusterStatusSearch.and("type", TypeClusterStatusSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeClusterStatusSearch.and("cluster", TypeClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        TypeClusterStatusSearch.and("status", TypeClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        TypeClusterStatusSearch.and("resourceState", TypeClusterStatusSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
+        TypeClusterStatusSearch.done();
+
+        IdStatusSearch = createSearchBuilder();
+        IdStatusSearch.and("id", IdStatusSearch.entity().getId(), SearchCriteria.Op.EQ);
+        IdStatusSearch.and("states", IdStatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        IdStatusSearch.done();
+
+        DcPrivateIpAddressSearch = createSearchBuilder();
+        DcPrivateIpAddressSearch.and("privateIpAddress", DcPrivateIpAddressSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ);
+        DcPrivateIpAddressSearch.and("dc", DcPrivateIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcPrivateIpAddressSearch.done();
+
+        DcStorageIpAddressSearch = createSearchBuilder();
+        DcStorageIpAddressSearch.and("storageIpAddress", DcStorageIpAddressSearch.entity().getStorageIpAddress(), SearchCriteria.Op.EQ);
+        DcStorageIpAddressSearch.and("dc", DcStorageIpAddressSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcStorageIpAddressSearch.done();
+
+        PublicIpAddressSearch = createSearchBuilder();
+        PublicIpAddressSearch.and("publicIpAddress", PublicIpAddressSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ);
+        PublicIpAddressSearch.done();
+
+        AnyIpAddressSearch = createSearchBuilder();
+        AnyIpAddressSearch.or("publicIpAddress", AnyIpAddressSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ);
+        AnyIpAddressSearch.or("privateIpAddress", AnyIpAddressSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ);
+        AnyIpAddressSearch.done();
+
+        GuidSearch = createSearchBuilder();
+        GuidSearch.and("guid", GuidSearch.entity().getGuid(), SearchCriteria.Op.EQ);
+        GuidSearch.done();
+
+        DcSearch = createSearchBuilder();
+        DcSearch.and("dc", DcSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcSearch.and("hypervisorType", DcSearch.entity().getHypervisorType(), Op.EQ);
+        DcSearch.and("type", DcSearch.entity().getType(), Op.EQ);
+        DcSearch.and("status", DcSearch.entity().getStatus(), Op.EQ);
+        DcSearch.and("resourceState", DcSearch.entity().getResourceState(), Op.EQ);
+        DcSearch.done();
+
+        ClusterStatusSearch = createSearchBuilder();
+        ClusterStatusSearch.and("cluster", ClusterStatusSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        ClusterStatusSearch.and("status", ClusterStatusSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        ClusterStatusSearch.done();
+
+        TypeNameZoneSearch = createSearchBuilder();
+        TypeNameZoneSearch.and("name", TypeNameZoneSearch.entity().getName(), SearchCriteria.Op.EQ);
+        TypeNameZoneSearch.and("type", TypeNameZoneSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeNameZoneSearch.and("zoneId", TypeNameZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        TypeNameZoneSearch.done();
+
+        PodSearch = createSearchBuilder();
+        PodSearch.and("podId", PodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        PodSearch.done();
+
+        ClusterSearch = createSearchBuilder();
+        ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        ClusterSearch.done();
+
+        TypeSearch = createSearchBuilder();
+        TypeSearch.and("type", TypeSearch.entity().getType(), SearchCriteria.Op.EQ);
+        TypeSearch.done();
+
+        StatusSearch = createSearchBuilder();
+        StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        StatusSearch.done();
+
+        ResourceStateSearch = createSearchBuilder();
+        ResourceStateSearch.and("resourceState", ResourceStateSearch.entity().getResourceState(), SearchCriteria.Op.IN);
+        ResourceStateSearch.done();
+
+        NameLikeSearch = createSearchBuilder();
+        NameLikeSearch.and("name", NameLikeSearch.entity().getName(), SearchCriteria.Op.LIKE);
+        NameLikeSearch.done();
+
+        NameSearch = createSearchBuilder();
+        NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
+        NameSearch.done();
+
+        SequenceSearch = createSearchBuilder();
+        SequenceSearch.and("id", SequenceSearch.entity().getId(), SearchCriteria.Op.EQ);
+        // SequenceSearch.addRetrieve("sequence", SequenceSearch.entity().getSequence());
+        SequenceSearch.done();
+
+        DirectlyConnectedSearch = createSearchBuilder();
+        DirectlyConnectedSearch.and("resource", DirectlyConnectedSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        DirectlyConnectedSearch.and("ms", DirectlyConnectedSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+        DirectlyConnectedSearch.and("statuses", DirectlyConnectedSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        DirectlyConnectedSearch.and("resourceState", DirectlyConnectedSearch.entity().getResourceState(), SearchCriteria.Op.NOTIN);
+        DirectlyConnectedSearch.done();
+
+        UnmanagedDirectConnectSearch = createSearchBuilder();
+        UnmanagedDirectConnectSearch.and("resource", UnmanagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        UnmanagedDirectConnectSearch.and("server", UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+        UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
+        UnmanagedDirectConnectSearch.and("resourceStates", UnmanagedDirectConnectSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
+        UnmanagedDirectConnectSearch.and("clusterIn", UnmanagedDirectConnectSearch.entity().getClusterId(), SearchCriteria.Op.IN);
+        /*
+         * UnmanagedDirectConnectSearch.op(SearchCriteria.Op.OR, "managementServerId",
+         * UnmanagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+         * UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(),
+         * SearchCriteria.Op.LTEQ); UnmanagedDirectConnectSearch.cp(); UnmanagedDirectConnectSearch.cp();
+         */
+        try {
+            HostTransferSearch = _hostTransferDao.createSearchBuilder();
+        } catch (Throwable e) {
+            s_logger.debug("error", e);
+        }
+        HostTransferSearch.and("id", HostTransferSearch.entity().getId(), SearchCriteria.Op.NULL);
+        UnmanagedDirectConnectSearch.join("hostTransferSearch", HostTransferSearch, HostTransferSearch.entity().getId(), UnmanagedDirectConnectSearch.entity().getId(),
+                JoinType.LEFTOUTER);
+        ClusterManagedSearch = _clusterDao.createSearchBuilder();
+        ClusterManagedSearch.and("managed", ClusterManagedSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
+        UnmanagedDirectConnectSearch.join("ClusterManagedSearch", ClusterManagedSearch, ClusterManagedSearch.entity().getId(), UnmanagedDirectConnectSearch.entity().getClusterId(),
+                JoinType.INNER);
+        UnmanagedDirectConnectSearch.done();
+
+        DirectConnectSearch = createSearchBuilder();
+        DirectConnectSearch.and("resource", DirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        DirectConnectSearch.and("id", DirectConnectSearch.entity().getId(), SearchCriteria.Op.EQ);
+        DirectConnectSearch.and().op("nullserver", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+        DirectConnectSearch.or("server", DirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+        DirectConnectSearch.cp();
+        DirectConnectSearch.done();
+
+        UnmanagedApplianceSearch = createSearchBuilder();
+        UnmanagedApplianceSearch.and("resource", UnmanagedApplianceSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        UnmanagedApplianceSearch.and("server", UnmanagedApplianceSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+        UnmanagedApplianceSearch.and("types", UnmanagedApplianceSearch.entity().getType(), SearchCriteria.Op.IN);
+        UnmanagedApplianceSearch.and("lastPinged", UnmanagedApplianceSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
+        UnmanagedApplianceSearch.done();
+
+        AvailHypevisorInZone = createSearchBuilder();
+        AvailHypevisorInZone.and("zoneId", AvailHypevisorInZone.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AvailHypevisorInZone.and("hostId", AvailHypevisorInZone.entity().getId(), SearchCriteria.Op.NEQ);
+        AvailHypevisorInZone.and("type", AvailHypevisorInZone.entity().getType(), SearchCriteria.Op.EQ);
+        AvailHypevisorInZone.groupBy(AvailHypevisorInZone.entity().getHypervisorType());
+        AvailHypevisorInZone.done();
+
+        HostsInStatusSearch = createSearchBuilder(Long.class);
+        HostsInStatusSearch.selectFields(HostsInStatusSearch.entity().getId());
+        HostsInStatusSearch.and("dc", HostsInStatusSearch.entity().getDataCenterId(), Op.EQ);
+        HostsInStatusSearch.and("pod", HostsInStatusSearch.entity().getPodId(), Op.EQ);
+        HostsInStatusSearch.and("cluster", HostsInStatusSearch.entity().getClusterId(), Op.EQ);
+        HostsInStatusSearch.and("type", HostsInStatusSearch.entity().getType(), Op.EQ);
+        HostsInStatusSearch.and("statuses", HostsInStatusSearch.entity().getStatus(), Op.IN);
+        HostsInStatusSearch.done();
+
+        CountRoutingByDc = createSearchBuilder(Long.class);
+        CountRoutingByDc.select(null, Func.COUNT, null);
+        CountRoutingByDc.and("dc", CountRoutingByDc.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        CountRoutingByDc.and("type", CountRoutingByDc.entity().getType(), SearchCriteria.Op.EQ);
+        CountRoutingByDc.and("status", CountRoutingByDc.entity().getStatus(), SearchCriteria.Op.EQ);
+        CountRoutingByDc.done();
+
+        ManagedDirectConnectSearch = createSearchBuilder();
+        ManagedDirectConnectSearch.and("resource", ManagedDirectConnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        ManagedDirectConnectSearch.and("server", ManagedDirectConnectSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+        ManagedDirectConnectSearch.done();
+
+        ManagedRoutingServersSearch = createSearchBuilder();
+        ManagedRoutingServersSearch.and("server", ManagedRoutingServersSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
+        ManagedRoutingServersSearch.and("type", ManagedRoutingServersSearch.entity().getType(), SearchCriteria.Op.EQ);
+        ManagedRoutingServersSearch.done();
+
+        RoutingSearch = createSearchBuilder();
+        RoutingSearch.and("type", RoutingSearch.entity().getType(), SearchCriteria.Op.EQ);
+        RoutingSearch.done();
+
+        HostsForReconnectSearch = createSearchBuilder();
+        HostsForReconnectSearch.and("resource", HostsForReconnectSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        HostsForReconnectSearch.and("server", HostsForReconnectSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+        HostsForReconnectSearch.and("lastPinged", HostsForReconnectSearch.entity().getLastPinged(), SearchCriteria.Op.LTEQ);
+        HostsForReconnectSearch.and("resourceStates", HostsForReconnectSearch.entity().getResourceState(), SearchCriteria.Op.NIN);
+        HostsForReconnectSearch.and("cluster", HostsForReconnectSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
+        HostsForReconnectSearch.and("status", HostsForReconnectSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        HostsForReconnectSearch.done();
+
+        ClustersOwnedByMSSearch = createSearchBuilder(Long.class);
+        ClustersOwnedByMSSearch.select(null, Func.DISTINCT, ClustersOwnedByMSSearch.entity().getClusterId());
+        ClustersOwnedByMSSearch.and("resource", ClustersOwnedByMSSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        ClustersOwnedByMSSearch.and("cluster", ClustersOwnedByMSSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
+        ClustersOwnedByMSSearch.and("server", ClustersOwnedByMSSearch.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+        ClustersOwnedByMSSearch.done();
+
+        ClustersForHostsNotOwnedByAnyMSSearch = createSearchBuilder(Long.class);
+        ClustersForHostsNotOwnedByAnyMSSearch.select(null, Func.DISTINCT, ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId());
+        ClustersForHostsNotOwnedByAnyMSSearch.and("resource", ClustersForHostsNotOwnedByAnyMSSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        ClustersForHostsNotOwnedByAnyMSSearch.and("cluster", ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId(), SearchCriteria.Op.NNULL);
+        ClustersForHostsNotOwnedByAnyMSSearch.and("server", ClustersForHostsNotOwnedByAnyMSSearch.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+
+        ClusterManagedSearch = _clusterDao.createSearchBuilder();
+        ClusterManagedSearch.and("managed", ClusterManagedSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
+        ClustersForHostsNotOwnedByAnyMSSearch.join("ClusterManagedSearch", ClusterManagedSearch, ClusterManagedSearch.entity().getId(),
+                ClustersForHostsNotOwnedByAnyMSSearch.entity().getClusterId(), JoinType.INNER);
+
+        ClustersForHostsNotOwnedByAnyMSSearch.done();
+
+        AllClustersSearch = _clusterDao.createSearchBuilder(Long.class);
+        AllClustersSearch.select(null, Func.NATIVE, AllClustersSearch.entity().getId());
+        AllClustersSearch.and("managed", AllClustersSearch.entity().getManagedState(), SearchCriteria.Op.EQ);
+        AllClustersSearch.done();
+
+        HostsInClusterSearch = createSearchBuilder();
+        HostsInClusterSearch.and("resource", HostsInClusterSearch.entity().getResource(), SearchCriteria.Op.NNULL);
+        HostsInClusterSearch.and("cluster", HostsInClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        HostsInClusterSearch.and("server", HostsInClusterSearch.entity().getManagementServerId(), SearchCriteria.Op.NNULL);
+        HostsInClusterSearch.done();
+
+        HostIdSearch = createSearchBuilder(Long.class);
+        HostIdSearch.selectFields(HostIdSearch.entity().getId());
+        HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ);
+        HostIdSearch.done();
+
+        _statusAttr = _allAttributes.get("status");
+        _msIdAttr = _allAttributes.get("managementServerId");
+        _pingTimeAttr = _allAttributes.get("lastPinged");
+        _resourceStateAttr = _allAttributes.get("resourceState");
+
+        assert (_statusAttr != null && _msIdAttr != null && _pingTimeAttr != null) : "Couldn't find one of these attributes";
+    }
+
+    @Override
+    public long countBy(long clusterId, ResourceState... states) {
+        SearchCriteria<HostVO> sc = MaintenanceCountSearch.create();
+
+        sc.setParameters("resourceState", (Object[])states);
+        sc.setParameters("cluster", clusterId);
+
+        List<HostVO> hosts = listBy(sc);
+        return hosts.size();
+    }
+
+    @Override
+    public List<HostVO> listByDataCenterId(long id) {
+        SearchCriteria<HostVO> sc = DcSearch.create();
+        sc.setParameters("dc", id);
+        sc.setParameters("status", Status.Up);
+        sc.setParameters("type", Host.Type.Routing);
+        sc.setParameters("resourceState", ResourceState.Enabled);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<HostVO> listByDataCenterIdAndHypervisorType(long zoneId, Hypervisor.HypervisorType hypervisorType) {
+        SearchBuilder<ClusterVO> clusterSearch = _clusterDao.createSearchBuilder();
+
+        clusterSearch.and("allocationState", clusterSearch.entity().getAllocationState(), SearchCriteria.Op.EQ);
+        clusterSearch.and("hypervisorType", clusterSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+
+        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
+
+        hostSearch.and("dc", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        hostSearch.and("type", hostSearch.entity().getType(), Op.EQ);
+        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
+        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), Op.EQ);
+
+        hostSearch.join("clusterSearch", clusterSearch, hostSearch.entity().getClusterId(), clusterSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        hostSearch.done();
+
+        SearchCriteria<HostVO> sc = hostSearch.create();
+
+        sc.setParameters("dc", zoneId);
+        sc.setParameters("type", Host.Type.Routing);
+        sc.setParameters("status", Status.Up);
+        sc.setParameters("resourceState", ResourceState.Enabled);
+
+        sc.setJoinParameters("clusterSearch", "allocationState", Grouping.AllocationState.Enabled);
+        sc.setJoinParameters("clusterSearch", "hypervisorType", hypervisorType.toString());
+
+        return listBy(sc);
+    }
+
+    @Override
+    public HostVO findByGuid(String guid) {
+        SearchCriteria<HostVO> sc = GuidSearch.create("guid", guid);
+        return findOneBy(sc);
+    }
+
+    /*
+     * Find hosts which is in Disconnected, Down, Alert and ping timeout and server is not null, set server to null
+     */
+    private void resetHosts(long managementServerId, long lastPingSecondsAfter) {
+        SearchCriteria<HostVO> sc = HostsForReconnectSearch.create();
+        sc.setParameters("server", managementServerId);
+        sc.setParameters("lastPinged", lastPingSecondsAfter);
+        sc.setParameters("status", Status.Disconnected, Status.Down, Status.Alert);
+
+        StringBuilder sb = new StringBuilder();
+        List<HostVO> hosts = lockRows(sc, null, true); // exclusive lock
+        for (HostVO host : hosts) {
+            host.setManagementServerId(null);
+            update(host.getId(), host);
+            sb.append(host.getId());
+            sb.append(" ");
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Following hosts got reset: " + sb.toString());
+        }
+    }
+
+    /*
+     * Returns a list of cluster owned by @managementServerId
+     */
+    private List<Long> findClustersOwnedByManagementServer(long managementServerId) {
+        SearchCriteria<Long> sc = ClustersOwnedByMSSearch.create();
+        sc.setParameters("server", managementServerId);
+
+        List<Long> clusters = customSearch(sc, null);
+        return clusters;
+    }
+
+    /*
+     * Returns clusters based on the list of hosts not owned by any MS
+     */
+    private List<Long> findClustersForHostsNotOwnedByAnyManagementServer() {
+        SearchCriteria<Long> sc = ClustersForHostsNotOwnedByAnyMSSearch.create();
+        sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
+
+        List<Long> clusters = customSearch(sc, null);
+        return clusters;
+    }
+
+    /**
+     * This determines if hosts belonging to cluster(@clusterId) are up for grabs
+     *
+     * This is used for handling following cases:
+     * 1. First host added in cluster
+     * 2. During MS restart all hosts in a cluster are without any MS
+     */
+    private boolean canOwnCluster(long clusterId) {
+        SearchCriteria<HostVO> sc = HostsInClusterSearch.create();
+        sc.setParameters("cluster", clusterId);
+
+        List<HostVO> hosts = search(sc, null);
+        boolean ownCluster = (hosts == null || hosts.size() == 0);
+
+        return ownCluster;
+    }
+
+    @Override
+    @DB
+    public List<HostVO> findAndUpdateDirectAgentToLoad(long lastPingSecondsAfter, Long limit, long managementServerId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Resetting hosts suitable for reconnect");
+        }
+        // reset hosts that are suitable candidates for reconnect
+        resetHosts(managementServerId, lastPingSecondsAfter);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Completed resetting hosts suitable for reconnect");
+        }
+
+        List<HostVO> assignedHosts = new ArrayList<HostVO>();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Acquiring hosts for clusters already owned by this management server");
+        }
+        List<Long> clusters = findClustersOwnedByManagementServer(managementServerId);
+        txn.start();
+        if (clusters.size() > 0) {
+            // handle clusters already owned by @managementServerId
+            SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
+            sc.setParameters("lastPinged", lastPingSecondsAfter);
+            sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
+            sc.setParameters("clusterIn", clusters.toArray());
+            List<HostVO> unmanagedHosts = lockRows(sc, new Filter(HostVO.class, "clusterId", true, 0L, limit), true); // host belongs to clusters owned by @managementServerId
+            StringBuilder sb = new StringBuilder();
+            for (HostVO host : unmanagedHosts) {
+                host.setManagementServerId(managementServerId);
+                update(host.getId(), host);
+                assignedHosts.add(host);
+                sb.append(host.getId());
+                sb.append(" ");
+            }
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Following hosts got acquired for clusters already owned: " + sb.toString());
+            }
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Completed acquiring hosts for clusters already owned by this management server");
+        }
+
+        if (assignedHosts.size() < limit) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Acquiring hosts for clusters not owned by any management server");
+            }
+            // for remaining hosts not owned by any MS check if they can be owned (by owning full cluster)
+            clusters = findClustersForHostsNotOwnedByAnyManagementServer();
+            List<Long> updatedClusters = clusters;
+            if (clusters.size() > limit) {
+                updatedClusters = clusters.subList(0, limit.intValue());
+            }
+            if (updatedClusters.size() > 0) {
+                SearchCriteria<HostVO> sc = UnmanagedDirectConnectSearch.create();
+                sc.setParameters("lastPinged", lastPingSecondsAfter);
+                sc.setJoinParameters("ClusterManagedSearch", "managed", Managed.ManagedState.Managed);
+                sc.setParameters("clusterIn", updatedClusters.toArray());
+                List<HostVO> unmanagedHosts = lockRows(sc, null, true);
+
+                // group hosts based on cluster
+                Map<Long, List<HostVO>> hostMap = new HashMap<Long, List<HostVO>>();
+                for (HostVO host : unmanagedHosts) {
+                    if (hostMap.get(host.getClusterId()) == null) {
+                        hostMap.put(host.getClusterId(), new ArrayList<HostVO>());
+                    }
+                    hostMap.get(host.getClusterId()).add(host);
+                }
+
+                StringBuilder sb = new StringBuilder();
+                for (Long clusterId : hostMap.keySet()) {
+                    if (canOwnCluster(clusterId)) { // cluster is not owned by any other MS, so @managementServerId can own it
+                        List<HostVO> hostList = hostMap.get(clusterId);
+                        for (HostVO host : hostList) {
+                            host.setManagementServerId(managementServerId);
+                            update(host.getId(), host);
+                            assignedHosts.add(host);
+                            sb.append(host.getId());
+                            sb.append(" ");
+                        }
+                    }
+                    if (assignedHosts.size() > limit) {
+                        break;
+                    }
+                }
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Following hosts got acquired from newly owned clusters: " + sb.toString());
+                }
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Completed acquiring hosts for clusters not owned by any management server");
+            }
+        }
+        txn.commit();
+
+        return assignedHosts;
+    }
+
+    @Override
+    @DB
+    public List<HostVO> findAndUpdateApplianceToLoad(long lastPingSecondsAfter, long managementServerId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+
+        txn.start();
+        SearchCriteria<HostVO> sc = UnmanagedApplianceSearch.create();
+        sc.setParameters("lastPinged", lastPingSecondsAfter);
+        sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.BaremetalDhcp, Type.BaremetalPxe, Type.TrafficMonitor,
+                Type.L2Networking, Type.NetScalerControlCenter);
+        List<HostVO> hosts = lockRows(sc, null, true);
+
+        for (HostVO host : hosts) {
+            host.setManagementServerId(managementServerId);
+            update(host.getId(), host);
+        }
+
+        txn.commit();
+
+        return hosts;
+    }
+
+    @Override
+    public void markHostsAsDisconnected(long msId, long lastPing) {
+        SearchCriteria<HostVO> sc = MsStatusSearch.create();
+        sc.setParameters("ms", msId);
+
+        HostVO host = createForUpdate();
+        host.setLastPinged(lastPing);
+        host.setDisconnectedOn(new Date());
+        UpdateBuilder ub = getUpdateBuilder(host);
+        ub.set(host, "status", Status.Disconnected);
+
+        update(ub, sc, null);
+
+        sc = MsStatusSearch.create();
+        sc.setParameters("ms", msId);
+
+        host = createForUpdate();
+        host.setManagementServerId(null);
+        host.setLastPinged(lastPing);
+        host.setDisconnectedOn(new Date());
+        ub = getUpdateBuilder(host);
+        update(ub, sc, null);
+    }
+
+    @Override
+    public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) {
+
+        SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
+        HostTagVO tagEntity = hostTagSearch.entity();
+        hostTagSearch.and("tag", tagEntity.getTag(), SearchCriteria.Op.EQ);
+
+        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
+        HostVO entity = hostSearch.entity();
+        hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
+        hostSearch.and("pod", entity.getPodId(), SearchCriteria.Op.EQ);
+        hostSearch.and("dc", entity.getDataCenterId(), SearchCriteria.Op.EQ);
+        hostSearch.and("cluster", entity.getClusterId(), SearchCriteria.Op.EQ);
+        hostSearch.and("status", entity.getStatus(), SearchCriteria.Op.EQ);
+        hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
+        hostSearch.join("hostTagSearch", hostTagSearch, entity.getId(), tagEntity.getHostId(), JoinBuilder.JoinType.INNER);
+
+        SearchCriteria<HostVO> sc = hostSearch.create();
+        sc.setJoinParameters("hostTagSearch", "tag", hostTag);
+        sc.setParameters("type", type.toString());
+        if (podId != null) {
+            sc.setParameters("pod", podId);
+        }
+        if (clusterId != null) {
+            sc.setParameters("cluster", clusterId);
+        }
+        sc.setParameters("dc", dcId);
+        sc.setParameters("status", Status.Up.toString());
+        sc.setParameters("resourceState", ResourceState.Enabled.toString());
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
+        SearchBuilder<HostTagVO> hostTagSearch = null;
+        if (haTag != null && !haTag.isEmpty()) {
+            hostTagSearch = _hostTagsDao.createSearchBuilder();
+            hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
+            hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
+            hostTagSearch.cp();
+        }
+
+        SearchBuilder<HostVO> hostSearch = createSearchBuilder();
+
+        hostSearch.and("type", hostSearch.entity().getType(), SearchCriteria.Op.EQ);
+        hostSearch.and("clusterId", hostSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        hostSearch.and("podId", hostSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        hostSearch.and("zoneId", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
+
+        if (haTag != null && !haTag.isEmpty()) {
+            hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
+        }
+
+        SearchCriteria<HostVO> sc = hostSearch.create();
+
+        if (haTag != null && !haTag.isEmpty()) {
+            sc.setJoinParameters("hostTagSearch", "tag", haTag);
+        }
+
+        if (type != null) {
+            sc.setParameters("type", type);
+        }
+
+        if (clusterId != null) {
+            sc.setParameters("clusterId", clusterId);
+        }
+
+        if (podId != null) {
+            sc.setParameters("podId", podId);
+        }
+
+        sc.setParameters("zoneId", dcId);
+        sc.setParameters("status", Status.Up);
+        sc.setParameters("resourceState", ResourceState.Enabled);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public void loadDetails(HostVO host) {
+        Map<String, String> details = _detailsDao.findDetails(host.getId());
+        host.setDetails(details);
+    }
+
+    @Override
+    public void loadHostTags(HostVO host) {
+        List<String> hostTags = _hostTagsDao.gethostTags(host.getId());
+        host.setHostTags(hostTags);
+    }
+
+    @DB
+    @Override
+    public List<HostVO> findLostHosts(long timeout) {
+        List<HostVO> result = new ArrayList<HostVO>();
+        String sql = "select h.id from host h left join  cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage', 'L2Networking') and (h.cluster_id is null or c.managed_state = 'Managed') ;";
+        try (TransactionLegacy txn = TransactionLegacy.currentTxn();
+                PreparedStatement pstmt = txn.prepareStatement(sql);) {
+            pstmt.setLong(1, timeout);
+            try (ResultSet rs = pstmt.executeQuery();) {
+                while (rs.next()) {
+                    long id = rs.getLong(1); //ID column
+                    result.add(findById(id));
+                }
+            }
+        } catch (SQLException e) {
+            s_logger.warn("Exception: ", e);
+        }
+        return result;
+    }
+
+    @Override
+    public void saveDetails(HostVO host) {
+        Map<String, String> details = host.getDetails();
+        if (details == null) {
+            return;
+        }
+        _detailsDao.persist(host.getId(), details);
+    }
+
+    protected void saveHostTags(HostVO host) {
+        List<String> hostTags = host.getHostTags();
+        if (hostTags == null || (hostTags != null && hostTags.isEmpty())) {
+            return;
+        }
+        _hostTagsDao.persist(host.getId(), hostTags);
+    }
+
+    protected void saveGpuRecords(HostVO host) {
+        HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = host.getGpuGroupDetails();
+        if (groupDetails != null) {
+            // Create/Update GPU group entries
+            _hostGpuGroupsDao.persist(host.getId(), new ArrayList<String>(groupDetails.keySet()));
+            // Create/Update VGPU types entries
+            _vgpuTypesDao.persist(host.getId(), groupDetails);
+        }
+    }
+
+    @Override
+    @DB
+    public HostVO persist(HostVO host) {
+        final String InsertSequenceSql = "INSERT INTO op_host(id) VALUES(?)";
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        HostVO dbHost = super.persist(host);
+
+        try {
+            PreparedStatement pstmt = txn.prepareAutoCloseStatement(InsertSequenceSql);
+            pstmt.setLong(1, dbHost.getId());
+            pstmt.executeUpdate();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to persist the sequence number for this host");
+        }
+
+        saveDetails(host);
+        loadDetails(dbHost);
+        saveHostTags(host);
+        loadHostTags(dbHost);
+        saveGpuRecords(host);
+
+        txn.commit();
+
+        return dbHost;
+    }
+
+    @Override
+    @DB
+    public boolean update(Long hostId, HostVO host) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        boolean persisted = super.update(hostId, host);
+        if (!persisted) {
+            return persisted;
+        }
+
+        saveDetails(host);
+        saveHostTags(host);
+        saveGpuRecords(host);
+
+        txn.commit();
+
+        return persisted;
+    }
+
+    @Override
+    @DB
+    public List<RunningHostCountInfo> getRunningHostCounts(Date cutTime) {
+        String sql = "select * from (" + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid "
+                + "where h.status='Up' and h.type='SecondaryStorage' and m.last_update > ? " + "group by h.data_center_id, h.type " + "UNION ALL "
+                + "select h.data_center_id, h.type, count(*) as count from host as h INNER JOIN mshost as m ON h.mgmt_server_id=m.msid "
+                + "where h.status='Up' and h.type='Routing' and m.last_update > ? " + "group by h.data_center_id, h.type) as t " + "ORDER by t.data_center_id, t.type";
+
+        ArrayList<RunningHostCountInfo> l = new ArrayList<RunningHostCountInfo>();
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        ;
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            String gmtCutTime = DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutTime);
+            pstmt.setString(1, gmtCutTime);
+            pstmt.setString(2, gmtCutTime);
+
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                RunningHostCountInfo info = new RunningHostCountInfo();
+                info.setDcId(rs.getLong(1));
+                info.setHostType(rs.getString(2));
+                info.setCount(rs.getInt(3));
+
+                l.add(info);
+            }
+        } catch (SQLException e) {
+            s_logger.debug("SQLException caught", e);
+        }
+        return l;
+    }
+
+    @Override
+    public long getNextSequence(long hostId) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("getNextSequence(), hostId: " + hostId);
+        }
+
+        TableGenerator tg = _tgs.get("host_req_sq");
+        assert tg != null : "how can this be wrong!";
+
+        return s_seqFetcher.getNextSequence(Long.class, tg, hostId);
+    }
+
+    @Override
+    public boolean updateState(Status oldStatus, Event event, Status newStatus, Host vo, Object data) {
+        // lock target row from beginning to avoid lock-promotion caused deadlock
+        HostVO host = lockRow(vo.getId(), true);
+        if (host == null) {
+            if (event == Event.Remove && newStatus == Status.Removed) {
+                host = findByIdIncludingRemoved(vo.getId());
+            }
+        }
+
+        if (host == null) {
+            return false;
+        }
+        long oldPingTime = host.getLastPinged();
+
+        SearchBuilder<HostVO> sb = createSearchBuilder();
+        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("update", sb.entity().getUpdated(), SearchCriteria.Op.EQ);
+        if (newStatus.checkManagementServer()) {
+            sb.and("ping", sb.entity().getLastPinged(), SearchCriteria.Op.EQ);
+            sb.and().op("nullmsid", sb.entity().getManagementServerId(), SearchCriteria.Op.NULL);
+            sb.or("msid", sb.entity().getManagementServerId(), SearchCriteria.Op.EQ);
+            sb.cp();
+        }
+        sb.done();
+
+        SearchCriteria<HostVO> sc = sb.create();
+
+        sc.setParameters("status", oldStatus);
+        sc.setParameters("id", host.getId());
+        sc.setParameters("update", host.getUpdated());
+        long oldUpdateCount = host.getUpdated();
+        if (newStatus.checkManagementServer()) {
+            sc.setParameters("ping", oldPingTime);
+            sc.setParameters("msid", host.getManagementServerId());
+        }
+
+        long newUpdateCount = host.incrUpdated();
+        UpdateBuilder ub = getUpdateBuilder(host);
+        ub.set(host, _statusAttr, newStatus);
+        if (newStatus.updateManagementServer()) {
+            if (newStatus.lostConnection()) {
+                ub.set(host, _msIdAttr, null);
+            } else {
+                ub.set(host, _msIdAttr, host.getManagementServerId());
+            }
+            if (event.equals(Event.Ping) || event.equals(Event.AgentConnected)) {
+                ub.set(host, _pingTimeAttr, System.currentTimeMillis() >> 10);
+            }
+        }
+        if (event.equals(Event.ManagementServerDown)) {
+            ub.set(host, _pingTimeAttr, ((System.currentTimeMillis() >> 10) - mgmtServiceConf.getTimeout()));
+        }
+        int result = update(ub, sc, null);
+        assert result <= 1 : "How can this update " + result + " rows? ";
+
+        if (result == 0) {
+            HostVO ho = findById(host.getId());
+            assert ho != null : "How how how? : " + host.getId();
+
+            if (status_logger.isDebugEnabled()) {
+
+                StringBuilder str = new StringBuilder("Unable to update host for event:").append(event.toString());
+                str.append(". Name=").append(host.getName());
+                str.append("; New=[status=").append(newStatus.toString()).append(":msid=").append(newStatus.lostConnection() ? "null" : host.getManagementServerId())
+                .append(":lastpinged=").append(host.getLastPinged()).append("]");
+                str.append("; Old=[status=").append(oldStatus.toString()).append(":msid=").append(host.getManagementServerId()).append(":lastpinged=").append(oldPingTime)
+                .append("]");
+                str.append("; DB=[status=").append(vo.getStatus().toString()).append(":msid=").append(vo.getManagementServerId()).append(":lastpinged=").append(vo.getLastPinged())
+                .append(":old update count=").append(oldUpdateCount).append("]");
+                status_logger.debug(str.toString());
+            } else {
+                StringBuilder msg = new StringBuilder("Agent status update: [");
+                msg.append("id = " + host.getId());
+                msg.append("; name = " + host.getName());
+                msg.append("; old status = " + oldStatus);
+                msg.append("; event = " + event);
+                msg.append("; new status = " + newStatus);
+                msg.append("; old update count = " + oldUpdateCount);
+                msg.append("; new update count = " + newUpdateCount + "]");
+                status_logger.debug(msg.toString());
+            }
+
+            if (ho.getState() == newStatus) {
+                status_logger.debug("Host " + ho.getName() + " state has already been updated to " + newStatus);
+                return true;
+            }
+        }
+
+        return result > 0;
+    }
+
+    @Override
+    public boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo) {
+        HostVO host = (HostVO)vo;
+        SearchBuilder<HostVO> sb = createSearchBuilder();
+        sb.and("resource_state", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.done();
+
+        SearchCriteria<HostVO> sc = sb.create();
+
+        sc.setParameters("resource_state", oldState);
+        sc.setParameters("id", host.getId());
+
+        UpdateBuilder ub = getUpdateBuilder(host);
+        ub.set(host, _resourceStateAttr, newState);
+        int result = update(ub, sc, null);
+        assert result <= 1 : "How can this update " + result + " rows? ";
+
+        if (state_logger.isDebugEnabled() && result == 0) {
+            HostVO ho = findById(host.getId());
+            assert ho != null : "How how how? : " + host.getId();
+
+            StringBuilder str = new StringBuilder("Unable to update resource state: [");
+            str.append("m = " + host.getId());
+            str.append("; name = " + host.getName());
+            str.append("; old state = " + oldState);
+            str.append("; event = " + event);
+            str.append("; new state = " + newState + "]");
+            state_logger.debug(str.toString());
+        } else {
+            StringBuilder msg = new StringBuilder("Resource state update: [");
+            msg.append("id = " + host.getId());
+            msg.append("; name = " + host.getName());
+            msg.append("; old state = " + oldState);
+            msg.append("; event = " + event);
+            msg.append("; new state = " + newState + "]");
+            state_logger.debug(msg.toString());
+        }
+
+        return result > 0;
+    }
+
+    @Override
+    public HostVO findByTypeNameAndZoneId(long zoneId, String name, Host.Type type) {
+        SearchCriteria<HostVO> sc = TypeNameZoneSearch.create();
+        sc.setParameters("type", type);
+        sc.setParameters("name", name);
+        sc.setParameters("zoneId", zoneId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<HostVO> findByDataCenterId(Long zoneId) {
+        SearchCriteria<HostVO> sc = DcSearch.create();
+        sc.setParameters("dc", zoneId);
+        sc.setParameters("type", Type.Routing);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<HostVO> findByPodId(Long podId) {
+        SearchCriteria<HostVO> sc = PodSearch.create();
+        sc.setParameters("podId", podId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<HostVO> findByClusterId(Long clusterId) {
+        SearchCriteria<HostVO> sc = ClusterSearch.create();
+        sc.setParameters("clusterId", clusterId);
+        return listBy(sc);
+    }
+
+    @Override
+    public HostVO findByPublicIp(String publicIp) {
+        SearchCriteria<HostVO> sc = PublicIpAddressSearch.create();
+        sc.setParameters("publicIpAddress", publicIp);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public HostVO findByIp(final String ipAddress) {
+        SearchCriteria<HostVO> sc = AnyIpAddressSearch.create();
+        sc.setParameters("publicIpAddress", ipAddress);
+        sc.setParameters("privateIpAddress", ipAddress);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<HostVO> findHypervisorHostInCluster(long clusterId) {
+        SearchCriteria<HostVO> sc = TypeClusterStatusSearch.create();
+        sc.setParameters("type", Host.Type.Routing);
+        sc.setParameters("cluster", clusterId);
+        sc.setParameters("status", Status.Up);
+        sc.setParameters("resourceState", ResourceState.Enabled);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<Long> listAllHosts(long zoneId) {
+        SearchCriteria<Long> sc = HostIdSearch.create();
+        sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public List<HostVO> listAllHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType) {
+        SearchCriteria<HostVO> sc = DcSearch.create();
+        sc.setParameters("dc", zoneId);
+        if (hypervisorType != null) {
+            sc.setParameters("hypervisorType", hypervisorType.toString());
+        }
+        return listBy(sc);
+    }
+
+    @Override
+    public List<Long> listClustersByHostTag(String hostTagOnOffering) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        List<Long> result = new ArrayList<Long>();
+        StringBuilder sql = new StringBuilder(LIST_CLUSTERID_FOR_HOST_TAG);
+        // during listing the clusters that cross the threshold
+        // we need to check with disabled thresholds of each cluster if not defined at cluster consider the global value
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+            pstmt.setString(1, hostTagOnOffering);
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(rs.getLong(1));
+            }
+            return result;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + sql, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + sql, e);
+        }
+    }
+
+    @Override
+    public List<HostVO> listAllHostsByType(Host.Type type) {
+        SearchCriteria<HostVO> sc = TypeSearch.create();
+        sc.setParameters("type", type);
+        sc.setParameters("resourceState", ResourceState.Enabled);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<HostVO> listByType(Host.Type type) {
+        SearchCriteria<HostVO> sc = TypeSearch.create();
+        sc.setParameters("type", type);
+        return listBy(sc);
+    }
+
+    String sqlFindHostInZoneToExecuteCommand = "Select  id from host "
+            + " where type = 'Routing' and hypervisor_type = ? and data_center_id = ? and status = 'Up' "
+            + " and resource_state = '%s' "
+            + " ORDER by rand() limit 1";
+
+    @Override
+    public HostVO findHostInZoneToExecuteCommand(long zoneId, HypervisorType hypervisorType) {
+        try (TransactionLegacy tx = TransactionLegacy.currentTxn()) {
+            String sql = createSqlFindHostToExecuteCommand(false);
+            ResultSet rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
+            if (rs.next()) {
+                return findById(rs.getLong("id"));
+            }
+            sql = createSqlFindHostToExecuteCommand(true);
+            rs = executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(hypervisorType, zoneId, tx, sql);
+            if (!rs.next()) {
+                throw new CloudRuntimeException(String.format("Could not find a host in zone [zoneId=%d] to operate on. ", zoneId));
+            }
+            return findById(rs.getLong("id"));
+        } catch (SQLException e) {
+            throw new CloudRuntimeException(e);
+        }
+    }
+
+    private ResultSet executeSqlGetResultsetForMethodFindHostInZoneToExecuteCommand(HypervisorType hypervisorType, long zoneId, TransactionLegacy tx, String sql) throws SQLException {
+        PreparedStatement pstmt = tx.prepareAutoCloseStatement(sql);
+        pstmt.setString(1, Objects.toString(hypervisorType));
+        pstmt.setLong(2, zoneId);
+        return pstmt.executeQuery();
+    }
+
+    private String createSqlFindHostToExecuteCommand(boolean useDisabledHosts) {
+        String hostResourceStatus = "Enabled";
+        if (useDisabledHosts) {
+            hostResourceStatus = "Disabled";
+        }
+        return String.format(sqlFindHostInZoneToExecuteCommand, hostResourceStatus);
+    }
+}
diff --git a/engine/schema/src/com/cloud/host/dao/HostDetailsDao.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/dao/HostDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/host/dao/HostDetailsDao.java
diff --git a/engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/host/dao/HostDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/dao/HostDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/host/dao/HostDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/host/dao/HostTagsDao.java b/engine/schema/src/main/java/com/cloud/host/dao/HostTagsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/dao/HostTagsDao.java
rename to engine/schema/src/main/java/com/cloud/host/dao/HostTagsDao.java
diff --git a/engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java b/engine/schema/src/main/java/com/cloud/host/dao/HostTagsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/host/dao/HostTagsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/host/dao/HostTagsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java b/engine/schema/src/main/java/com/cloud/hypervisor/HypervisorCapabilitiesVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/hypervisor/HypervisorCapabilitiesVO.java
rename to engine/schema/src/main/java/com/cloud/hypervisor/HypervisorCapabilitiesVO.java
diff --git a/engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java
rename to engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDao.java
diff --git a/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java
new file mode 100644
index 0000000..a434138
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/hypervisor/dao/HypervisorCapabilitiesDaoImpl.java
@@ -0,0 +1,109 @@
+// 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.dao;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilitiesVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase<HypervisorCapabilitiesVO, Long> implements HypervisorCapabilitiesDao {
+
+    private static final Logger s_logger = Logger.getLogger(HypervisorCapabilitiesDaoImpl.class);
+
+    protected final SearchBuilder<HypervisorCapabilitiesVO> HypervisorTypeSearch;
+    protected final SearchBuilder<HypervisorCapabilitiesVO> HypervisorTypeAndVersionSearch;
+
+    private static final String DEFAULT_VERSION = "default";
+
+    protected HypervisorCapabilitiesDaoImpl() {
+        HypervisorTypeSearch = createSearchBuilder();
+        HypervisorTypeSearch.and("hypervisorType", HypervisorTypeSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        HypervisorTypeSearch.done();
+
+        HypervisorTypeAndVersionSearch = createSearchBuilder();
+        HypervisorTypeAndVersionSearch.and("hypervisorType", HypervisorTypeAndVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        HypervisorTypeAndVersionSearch.and("hypervisorVersion", HypervisorTypeAndVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
+        HypervisorTypeAndVersionSearch.done();
+    }
+
+    HypervisorCapabilitiesVO getCapabilities(HypervisorType hypervisorType, String hypervisorVersion) {
+        HypervisorCapabilitiesVO result = findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
+        if (result == null) { // if data is not available for a specific version then use 'default' as version
+            result = findByHypervisorTypeAndVersion(hypervisorType, DEFAULT_VERSION);
+        }
+        return result;
+    }
+
+    @Override
+    public List<HypervisorCapabilitiesVO> listAllByHypervisorType(HypervisorType hypervisorType) {
+        SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeSearch.create();
+        sc.setParameters("hypervisorType", hypervisorType);
+        return search(sc, null);
+    }
+
+    @Override
+    public HypervisorCapabilitiesVO findByHypervisorTypeAndVersion(HypervisorType hypervisorType, String hypervisorVersion) {
+        if (StringUtils.isBlank(hypervisorVersion)) {
+            hypervisorVersion = DEFAULT_VERSION;
+        }
+        SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeAndVersionSearch.create();
+        sc.setParameters("hypervisorType", hypervisorType);
+        sc.setParameters("hypervisorVersion", hypervisorVersion);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public Long getMaxGuestsLimit(HypervisorType hypervisorType, String hypervisorVersion) {
+        Long defaultLimit = new Long(50);
+        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
+        if (result == null) {
+            return defaultLimit;
+        }
+        Long limit = result.getMaxGuestsLimit();
+        if (limit == null) {
+            return defaultLimit;
+        }
+        return limit;
+    }
+
+    @Override
+    public Integer getMaxDataVolumesLimit(HypervisorType hypervisorType, String hypervisorVersion) {
+        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
+        return result.getMaxDataVolumesLimit();
+    }
+
+    @Override
+    public Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion) {
+        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
+        return result.getMaxHostsPerCluster();
+    }
+
+    @Override
+    public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion) {
+        HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
+        return result.getVmSnapshotEnabled();
+    }
+}
diff --git a/engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java b/engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/LBHealthCheckPolicyVO.java
rename to engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java
diff --git a/engine/schema/src/com/cloud/network/UserIpv6AddressVO.java b/engine/schema/src/main/java/com/cloud/network/UserIpv6AddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/UserIpv6AddressVO.java
rename to engine/schema/src/main/java/com/cloud/network/UserIpv6AddressVO.java
diff --git a/engine/schema/src/com/cloud/network/VpnUserVO.java b/engine/schema/src/main/java/com/cloud/network/VpnUserVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/VpnUserVO.java
rename to engine/schema/src/main/java/com/cloud/network/VpnUserVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScalePolicyConditionMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScalePolicyConditionMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScalePolicyConditionMapVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScalePolicyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScalePolicyVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScalePolicyVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupPolicyMapVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVmMapVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupVmMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScaleVmGroupVmMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmGroupVmMapVO.java
diff --git a/engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java b/engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmProfileVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/AutoScaleVmProfileVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/AutoScaleVmProfileVO.java
diff --git a/engine/schema/src/com/cloud/network/as/ConditionVO.java b/engine/schema/src/main/java/com/cloud/network/as/ConditionVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/ConditionVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/ConditionVO.java
diff --git a/engine/schema/src/com/cloud/network/as/CounterVO.java b/engine/schema/src/main/java/com/cloud/network/as/CounterVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/CounterVO.java
rename to engine/schema/src/main/java/com/cloud/network/as/CounterVO.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyConditionMapDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyConditionMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScalePolicyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupPolicyMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmGroupVmMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmProfileDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmProfileDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/AutoScaleVmProfileDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/ConditionDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/ConditionDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/ConditionDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/ConditionDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/ConditionDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/ConditionDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/ConditionDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/ConditionDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/CounterDao.java b/engine/schema/src/main/java/com/cloud/network/as/dao/CounterDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/CounterDao.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/CounterDao.java
diff --git a/engine/schema/src/com/cloud/network/as/dao/CounterDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/as/dao/CounterDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/as/dao/CounterDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/as/dao/CounterDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDao.java b/engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapVO.java b/engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/AccountGuestVlanMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/AccountGuestVlanMapVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalFirewallDeviceVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalFirewallDeviceVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java b/engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/ExternalLoadBalancerDeviceVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDao.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsVO.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesCidrsVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDao.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDcidrsDao.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDcidrsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesDcidrsDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDcidrsDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDcidrsDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDcidrsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesDcidrsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDcidrsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/FirewallRulesDestCidrsVO.java b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDestCidrsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/FirewallRulesDestCidrsVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDestCidrsVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressDao.java b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/IPAddressDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/IPAddressDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/IPAddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressVO.java b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/IPAddressVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java b/engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java b/engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/InlineLoadBalancerNicMapVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java b/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LBStickinessPolicyVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapDao.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapVO.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerCertMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerDao.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerVMMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/LoadBalancerVO.java b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/LoadBalancerVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java b/engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java b/engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/MonitoringServiceVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkAccountDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkAccountDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkAccountDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkAccountDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkAccountVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkAccountVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkAccountVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDao.java
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java
new file mode 100644
index 0000000..23936cb
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java
@@ -0,0 +1,700 @@
+// 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.network.dao;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.persistence.TableGenerator;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.Network;
+import com.cloud.network.Network.Event;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SequenceFetcher;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.net.NetUtils;
+
+@Component
+@DB()
+public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements NetworkDao {
+    SearchBuilder<NetworkVO> AllFieldsSearch;
+    SearchBuilder<NetworkVO> AccountSearch;
+    SearchBuilder<NetworkVO> RelatedConfigSearch;
+    SearchBuilder<NetworkVO> AccountNetworkSearch;
+    SearchBuilder<NetworkVO> ZoneBroadcastUriSearch;
+    SearchBuilder<NetworkVO> ZoneSecurityGroupSearch;
+    GenericSearchBuilder<NetworkVO, Integer> CountBy;
+    SearchBuilder<NetworkVO> PhysicalNetworkSearch;
+    SearchBuilder<NetworkVO> SecurityGroupSearch;
+    GenericSearchBuilder<NetworkVO, Long> NetworksRegularUserCanCreateSearch;
+    GenericSearchBuilder<NetworkVO, Integer> NetworksCount;
+    SearchBuilder<NetworkVO> SourceNATSearch;
+    GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
+    SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
+
+    GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
+
+    @Inject
+    ResourceTagDao _tagsDao;
+    @Inject
+    NetworkAccountDao _accountsDao;
+    @Inject
+    NetworkDomainDao _domainsDao;
+    @Inject
+    NetworkOpDao _opDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSvcMap;
+    @Inject
+    NetworkOfferingDao _ntwkOffDao;
+    @Inject
+    NetworkOpDao _ntwkOpDao;
+
+    TableGenerator _tgMacAddress;
+
+    Random _rand = new Random(System.currentTimeMillis());
+    long _prefix = 0x2;
+
+    public NetworkDaoImpl() {
+    }
+
+    @PostConstruct
+    protected void init() {
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
+        AllFieldsSearch.and("cidr", AllFieldsSearch.entity().getCidr(), Op.EQ);
+        AllFieldsSearch.and("broadcastType", AllFieldsSearch.entity().getBroadcastDomainType(), Op.EQ);
+        AllFieldsSearch.and("offering", AllFieldsSearch.entity().getNetworkOfferingId(), Op.EQ);
+        AllFieldsSearch.and("datacenter", AllFieldsSearch.entity().getDataCenterId(), Op.EQ);
+        AllFieldsSearch.and("account", AllFieldsSearch.entity().getAccountId(), Op.EQ);
+        AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ);
+        AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), Op.EQ);
+        AllFieldsSearch.and("physicalNetwork", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ);
+        AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ);
+        AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ);
+        AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getNetworkACLId(), Op.EQ);
+        AllFieldsSearch.and("redundant", AllFieldsSearch.entity().isRedundant(), Op.EQ);
+        final SearchBuilder<NetworkOfferingVO> join1 = _ntwkOffDao.createSearchBuilder();
+        join1.and("isSystem", join1.entity().isSystemOnly(), Op.EQ);
+        join1.and("isRedundant", join1.entity().isRedundantRouter(), Op.EQ);
+        AllFieldsSearch.join("offerings", join1, AllFieldsSearch.entity().getNetworkOfferingId(), join1.entity().getId(), JoinBuilder.JoinType.INNER);
+        AllFieldsSearch.done();
+
+        AccountSearch = createSearchBuilder();
+        AccountSearch.and("offering", AccountSearch.entity().getNetworkOfferingId(), Op.EQ);
+        final SearchBuilder<NetworkAccountVO> join = _accountsDao.createSearchBuilder();
+        join.and("account", join.entity().getAccountId(), Op.EQ);
+        AccountSearch.join("accounts", join, AccountSearch.entity().getId(), join.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
+        AccountSearch.and("datacenter", AccountSearch.entity().getDataCenterId(), Op.EQ);
+        AccountSearch.and("cidr", AccountSearch.entity().getCidr(), Op.EQ);
+        AccountSearch.and("vpcId", AccountSearch.entity().getVpcId(), Op.EQ);
+        AccountSearch.done();
+
+        RelatedConfigSearch = createSearchBuilder();
+        RelatedConfigSearch.and("offering", RelatedConfigSearch.entity().getNetworkOfferingId(), Op.EQ);
+        RelatedConfigSearch.and("datacenter", RelatedConfigSearch.entity().getDataCenterId(), Op.EQ);
+        final SearchBuilder<NetworkAccountVO> join2 = _accountsDao.createSearchBuilder();
+        join2.and("account", join2.entity().getAccountId(), Op.EQ);
+        RelatedConfigSearch.join("account", join2, join2.entity().getNetworkId(), RelatedConfigSearch.entity().getId(), JoinType.INNER);
+        RelatedConfigSearch.done();
+
+        AccountNetworkSearch = createSearchBuilder();
+        AccountNetworkSearch.and("networkId", AccountNetworkSearch.entity().getId(), Op.EQ);
+        final SearchBuilder<NetworkAccountVO> mapJoin = _accountsDao.createSearchBuilder();
+        mapJoin.and("accountId", mapJoin.entity().getAccountId(), Op.EQ);
+        AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
+        AccountNetworkSearch.done();
+
+        ZoneBroadcastUriSearch = createSearchBuilder();
+        ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ);
+        ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
+        ZoneBroadcastUriSearch.and("guestType", ZoneBroadcastUriSearch.entity().getGuestType(), Op.EQ);
+        ZoneBroadcastUriSearch.done();
+
+        ZoneSecurityGroupSearch = createSearchBuilder();
+        ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
+        final SearchBuilder<NetworkServiceMapVO> offJoin = _ntwkSvcMap.createSearchBuilder();
+        offJoin.and("service", offJoin.entity().getService(), Op.EQ);
+        ZoneSecurityGroupSearch.join("services", offJoin, ZoneSecurityGroupSearch.entity().getId(), offJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
+        ZoneSecurityGroupSearch.done();
+
+        CountBy = createSearchBuilder(Integer.class);
+        CountBy.select(null, Func.COUNT, CountBy.entity().getId());
+        CountBy.and("offeringId", CountBy.entity().getNetworkOfferingId(), Op.EQ);
+        CountBy.and("vpcId", CountBy.entity().getVpcId(), Op.EQ);
+        CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL);
+        final SearchBuilder<NetworkOfferingVO> ntwkOffJoin = _ntwkOffDao.createSearchBuilder();
+        ntwkOffJoin.and("isSystem", ntwkOffJoin.entity().isSystemOnly(), Op.EQ);
+        CountBy.join("offerings", ntwkOffJoin, CountBy.entity().getNetworkOfferingId(), ntwkOffJoin.entity().getId(), JoinBuilder.JoinType.INNER);
+        CountBy.done();
+
+        PhysicalNetworkSearch = createSearchBuilder();
+        PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ);
+        PhysicalNetworkSearch.done();
+
+        SecurityGroupSearch = createSearchBuilder();
+        final SearchBuilder<NetworkServiceMapVO> join3 = _ntwkSvcMap.createSearchBuilder();
+        join3.and("service", join3.entity().getService(), Op.EQ);
+        SecurityGroupSearch.join("services", join3, SecurityGroupSearch.entity().getId(), join3.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
+        SecurityGroupSearch.done();
+
+        NetworksCount = createSearchBuilder(Integer.class);
+        NetworksCount.select(null, Func.COUNT, NetworksCount.entity().getId());
+        NetworksCount.and("networkOfferingId", NetworksCount.entity().getNetworkOfferingId(), SearchCriteria.Op.EQ);
+        NetworksCount.done();
+
+        NetworksRegularUserCanCreateSearch = createSearchBuilder(Long.class);
+        NetworksRegularUserCanCreateSearch.and("aclType", NetworksRegularUserCanCreateSearch.entity().getAclType(), Op.EQ);
+        NetworksRegularUserCanCreateSearch.and("displayNetwork", NetworksRegularUserCanCreateSearch.entity().getDisplayNetwork(), Op.EQ);
+        NetworksRegularUserCanCreateSearch.select(null, Func.COUNT, NetworksRegularUserCanCreateSearch.entity().getId());
+        final SearchBuilder<NetworkAccountVO> join4 = _accountsDao.createSearchBuilder();
+        join4.and("account", join4.entity().getAccountId(), Op.EQ);
+        join4.and("isOwner", join4.entity().isOwner(), Op.EQ);
+        NetworksRegularUserCanCreateSearch.join("accounts", join4, NetworksRegularUserCanCreateSearch.entity().getId(), join4.entity().getNetworkId(),
+                JoinBuilder.JoinType.INNER);
+        final SearchBuilder<NetworkOfferingVO> join5 = _ntwkOffDao.createSearchBuilder();
+        join5.and("specifyVlan", join5.entity().isSpecifyVlan(), Op.EQ);
+        NetworksRegularUserCanCreateSearch.join("ntwkOff", join5, NetworksRegularUserCanCreateSearch.entity().getNetworkOfferingId(), join5.entity().getId(),
+                JoinBuilder.JoinType.INNER);
+        NetworksRegularUserCanCreateSearch.done();
+
+        _tgMacAddress = _tgs.get("macAddress");
+
+        SourceNATSearch = createSearchBuilder();
+        SourceNATSearch.and("account", SourceNATSearch.entity().getAccountId(), Op.EQ);
+        SourceNATSearch.and("datacenter", SourceNATSearch.entity().getDataCenterId(), Op.EQ);
+        SourceNATSearch.and("guestType", SourceNATSearch.entity().getGuestType(), Op.EQ);
+        final SearchBuilder<NetworkServiceMapVO> join6 = _ntwkSvcMap.createSearchBuilder();
+        join6.and("service", join6.entity().getService(), Op.EQ);
+        SourceNATSearch.join("services", join6, SourceNATSearch.entity().getId(), join6.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
+        SourceNATSearch.done();
+
+        VpcNetworksCount = createSearchBuilder(Long.class);
+        VpcNetworksCount.and("vpcId", VpcNetworksCount.entity().getVpcId(), Op.EQ);
+        VpcNetworksCount.select(null, Func.COUNT, VpcNetworksCount.entity().getId());
+        final SearchBuilder<NetworkOfferingVO> join9 = _ntwkOffDao.createSearchBuilder();
+        join9.and("isSystem", join9.entity().isSystemOnly(), Op.EQ);
+        VpcNetworksCount.join("offerings", join9, VpcNetworksCount.entity().getNetworkOfferingId(), join9.entity().getId(), JoinBuilder.JoinType.INNER);
+        VpcNetworksCount.done();
+
+        OfferingAccountNetworkSearch = createSearchBuilder();
+        OfferingAccountNetworkSearch.select(null, Func.DISTINCT, OfferingAccountNetworkSearch.entity().getId());
+        final SearchBuilder<NetworkOfferingVO> ntwkOfferingJoin = _ntwkOffDao.createSearchBuilder();
+        ntwkOfferingJoin.and("isSystem", ntwkOfferingJoin.entity().isSystemOnly(), Op.EQ);
+        OfferingAccountNetworkSearch.join("ntwkOfferingSearch", ntwkOfferingJoin, OfferingAccountNetworkSearch.entity().getNetworkOfferingId(), ntwkOfferingJoin.entity()
+                .getId(), JoinBuilder.JoinType.LEFT);
+        final SearchBuilder<NetworkAccountVO> ntwkAccountJoin = _accountsDao.createSearchBuilder();
+        ntwkAccountJoin.and("accountId", ntwkAccountJoin.entity().getAccountId(), Op.EQ);
+        OfferingAccountNetworkSearch.join("ntwkAccountSearch", ntwkAccountJoin, OfferingAccountNetworkSearch.entity().getId(), ntwkAccountJoin.entity().getNetworkId(),
+                JoinBuilder.JoinType.INNER);
+        OfferingAccountNetworkSearch.and("zoneId", OfferingAccountNetworkSearch.entity().getDataCenterId(), Op.EQ);
+        OfferingAccountNetworkSearch.and("type", OfferingAccountNetworkSearch.entity().getGuestType(), Op.EQ);
+        OfferingAccountNetworkSearch.done();
+
+        GarbageCollectedSearch = createSearchBuilder(Long.class);
+        GarbageCollectedSearch.selectFields(GarbageCollectedSearch.entity().getId());
+        final SearchBuilder<NetworkOpVO> join7 = _ntwkOpDao.createSearchBuilder();
+        join7.and("activenics", join7.entity().getActiveNicsCount(), Op.EQ);
+        join7.and("gc", join7.entity().isGarbageCollected(), Op.EQ);
+        join7.and("check", join7.entity().isCheckForGc(), Op.EQ);
+        GarbageCollectedSearch.join("ntwkOpGC", join7, GarbageCollectedSearch.entity().getId(), join7.entity().getId(), JoinBuilder.JoinType.INNER);
+        final SearchBuilder<NetworkOfferingVO> join8 = _ntwkOffDao.createSearchBuilder();
+        join8.and("isPersistent", join8.entity().isPersistent(), Op.EQ);
+        GarbageCollectedSearch.join("ntwkOffGC", join8, GarbageCollectedSearch.entity().getNetworkOfferingId(), join8.entity().getId(), JoinBuilder.JoinType.INNER);
+        GarbageCollectedSearch.done();
+
+    }
+
+    @Override
+    public List<NetworkVO> listByZoneAndGuestType(final long accountId, final long dataCenterId, final Network.GuestType type, final Boolean isSystem) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("datacenter", dataCenterId);
+        sc.setParameters("account", accountId);
+        if (type != null) {
+            sc.setParameters("guestType", type);
+        }
+
+        if (isSystem != null) {
+            sc.setJoinParameters("offerings", "isSystem", isSystem);
+        }
+
+        return listBy(sc, null);
+    }
+
+    @Override
+    public List<NetworkVO> listByGuestType(Network.GuestType type) {
+        SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("guestType", type);
+        return listBy(sc, null);
+    }
+
+    public List<NetworkVO> findBy(final TrafficType trafficType, final Mode mode, final BroadcastDomainType broadcastType, final long networkOfferingId, final long dataCenterId) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("trafficType", trafficType);
+        sc.setParameters("broadcastType", broadcastType);
+        sc.setParameters("offering", networkOfferingId);
+        sc.setParameters("datacenter", dataCenterId);
+
+        return search(sc, null);
+    }
+
+    @Override
+    public List<NetworkVO> listBy(final long accountId, final long offeringId, final long dataCenterId) {
+        final SearchCriteria<NetworkVO> sc = AccountSearch.create();
+        sc.setParameters("offering", offeringId);
+        sc.setJoinParameters("accounts", "account", accountId);
+        sc.setParameters("datacenter", dataCenterId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final String cidr, final boolean skipVpc) {
+        final SearchCriteria<NetworkVO> sc = AccountSearch.create();
+        sc.setJoinParameters("accounts", "account", accountId);
+        sc.setParameters("datacenter", dataCenterId);
+        sc.setParameters("cidr", cidr);
+        if (skipVpc) {
+            sc.setParameters("vpcId", (Object)null);
+        }
+
+        return listBy(sc);
+    }
+
+    @Override
+    @DB
+    public NetworkVO persist(final NetworkVO network, final boolean gc, final Map<String, String> serviceProviderMap) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        // 1) create network
+        final NetworkVO newNetwork = super.persist(network);
+        // 2) add account to the network
+        addAccountToNetwork(network.getId(), network.getAccountId(), true);
+        // 3) add network to gc monitor table
+        final NetworkOpVO op = new NetworkOpVO(network.getId(), gc);
+        _opDao.persist(op);
+        // 4) add services/providers for the network
+        persistNetworkServiceProviders(newNetwork.getId(), serviceProviderMap);
+
+        txn.commit();
+        return newNetwork;
+    }
+
+    @Override
+    @DB
+    public boolean update(final Long networkId, final NetworkVO network, final Map<String, String> serviceProviderMap) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        super.update(networkId, network);
+        if (serviceProviderMap != null) {
+            _ntwkSvcMap.deleteByNetworkId(networkId);
+            persistNetworkServiceProviders(networkId, serviceProviderMap);
+        }
+
+        txn.commit();
+        return true;
+    }
+
+    @Override
+    @DB
+    public void persistNetworkServiceProviders(final long networkId, final Map<String, String> serviceProviderMap) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        for (final String service : serviceProviderMap.keySet()) {
+            final NetworkServiceMapVO serviceMap = new NetworkServiceMapVO(networkId, Service.getService(service), Provider.getProvider(serviceProviderMap.get(service)));
+            _ntwkSvcMap.persist(serviceMap);
+        }
+        txn.commit();
+    }
+
+    protected void addAccountToNetwork(final long networkId, final long accountId, final boolean isOwner) {
+        final NetworkAccountVO account = new NetworkAccountVO(networkId, accountId, isOwner);
+        _accountsDao.persist(account);
+    }
+
+    @Override
+    public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() {
+        return _accountsDao.createSearchBuilder();
+    }
+
+    @Override
+    public List<NetworkVO> getNetworksForOffering(final long offeringId, final long dataCenterId, final long accountId) {
+        final SearchCriteria<NetworkVO> sc = RelatedConfigSearch.create();
+        sc.setParameters("offering", offeringId);
+        sc.setParameters("dc", dataCenterId);
+        sc.setJoinParameters("account", "account", accountId);
+        return search(sc, null);
+    }
+
+    @Override
+    public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
+        final SequenceFetcher fetch = SequenceFetcher.getInstance();
+        long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
+        if(zoneMacIdentifier != null && zoneMacIdentifier.intValue() != 0 ){
+            seq = seq | _prefix << 40 | (long)zoneMacIdentifier << 32 | networkConfigId << 16 & 0x00000000ffff0000l;
+        }
+        else {
+            seq = seq | _prefix << 40 | _rand.nextInt(Short.MAX_VALUE) << 16 & 0x00000000ffff0000l;
+        }
+        return NetUtils.long2Mac(seq);
+    }
+
+    @Override
+    public List<NetworkVO> listBy(final long accountId, final long networkId) {
+        final SearchCriteria<NetworkVO> sc = AccountNetworkSearch.create();
+        sc.setParameters("networkId", networkId);
+        sc.setJoinParameters("networkSearch", "accountId", accountId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByZoneAndUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) {
+        final URI searchUri = BroadcastDomainType.fromString(broadcastUri);
+        final String searchRange = BroadcastDomainType.getValue(searchUri);
+        final List<Integer> searchVlans = UriUtils.expandVlanUri(searchRange);
+        final List<NetworkVO> overlappingNetworks = new ArrayList<>();
+
+        final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
+        sc.setParameters("dataCenterId", zoneId);
+        if (guestType != null) {
+            sc.setParameters("guestType", guestType);
+        }
+
+        for (final NetworkVO network : listBy(sc)) {
+            if (network.getBroadcastUri() == null || !network.getBroadcastUri().getScheme().equalsIgnoreCase(searchUri.getScheme())) {
+                continue;
+            }
+            final String networkVlanRange = BroadcastDomainType.getValue(network.getBroadcastUri());
+            if (networkVlanRange == null || networkVlanRange.isEmpty()) {
+                continue;
+            }
+            for (final Integer networkVlan : UriUtils.expandVlanUri(networkVlanRange)) {
+                if (searchVlans.contains(networkVlan)) {
+                    overlappingNetworks.add(network);
+                    break;
+                }
+            }
+        }
+
+        return overlappingNetworks;
+    }
+
+    @Override
+    public List<NetworkVO> listByZone(final long zoneId) {
+        final SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
+        sc.setParameters("dataCenterId", zoneId);
+        return search(sc, null);
+    }
+
+    @Override
+    public List<NetworkVO> listByZoneSecurityGroup(final Long zoneId) {
+        final SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        sc.setJoinParameters("services", "service", Service.SecurityGroup.getName());
+        return search(sc, null);
+    }
+
+    @Override
+    public void changeActiveNicsBy(final long networkId, final int count) {
+        _opDao.changeActiveNicsBy(networkId, count);
+    }
+
+    @Override
+    public int getActiveNicsIn(final long networkId) {
+        return _opDao.getActiveNics(networkId);
+    }
+
+    @Override
+    public List<Long> findNetworksToGarbageCollect() {
+        final SearchCriteria<Long> sc = GarbageCollectedSearch.create();
+        sc.setJoinParameters("ntwkOffGC", "isPersistent", false);
+        sc.setJoinParameters("ntwkOpGC", "activenics", 0);
+        sc.setJoinParameters("ntwkOpGC", "gc", true);
+        sc.setJoinParameters("ntwkOpGC", "check", true);
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public void clearCheckForGc(final long networkId) {
+        _opDao.clearCheckForGc(networkId);
+    }
+
+    @Override
+    public void setCheckForGc(final long networkId) {
+        _opDao.setCheckForGc(networkId);
+    }
+
+    @Override
+    public List<NetworkVO> listByOwner(final long ownerId) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("account", ownerId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void addDomainToNetwork(final long networkId, final long domainId, final Boolean subdomainAccess) {
+        addDomainToNetworknetwork(networkId, domainId, subdomainAccess);
+    }
+
+    protected void addDomainToNetworknetwork(final long networkId, final long domainId, final Boolean subdomainAccess) {
+        final NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId, subdomainAccess);
+        _domainsDao.persist(domain);
+    }
+
+    @Override
+    public int getNetworkCountByVpcId(final long vpcId) {
+        final SearchCriteria<Integer> sc = CountBy.create();
+        sc.setParameters("vpcId", vpcId);
+        final List<Integer> results = customSearch(sc, null);
+        return results.get(0);
+    }
+
+    @Override
+    public List<NetworkVO> listSecurityGroupEnabledNetworks() {
+        final SearchCriteria<NetworkVO> sc = SecurityGroupSearch.create();
+        sc.setJoinParameters("services", "service", Service.SecurityGroup.getName());
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByPhysicalNetwork(final long physicalNetworkId) {
+        final SearchCriteria<NetworkVO> sc = PhysicalNetworkSearch.create();
+        sc.setParameters("physicalNetworkId", physicalNetworkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByPhysicalNetworkTrafficType(final long physicalNetworkId, final TrafficType trafficType) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("trafficType", trafficType);
+        sc.setParameters("physicalNetworkId", physicalNetworkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByPhysicalNetworkAndProvider(final long physicalNetworkId, final String providerName) {
+        final SearchBuilder<NetworkServiceMapVO> svcProviderMapSearch = _ntwkSvcMap.createSearchBuilder();
+        final NetworkServiceMapVO svcProviderEntry = svcProviderMapSearch.entity();
+        svcProviderMapSearch.and("Provider", svcProviderMapSearch.entity().getProvider(), SearchCriteria.Op.EQ);
+
+        final SearchBuilder<NetworkVO> networksSearch = createSearchBuilder();
+        networksSearch.and("physicalNetworkId", networksSearch.entity().getPhysicalNetworkId(), Op.EQ);
+        networksSearch.join("svcProviderMapSearch", svcProviderMapSearch, networksSearch.entity().getId(), svcProviderEntry.getNetworkId(), JoinBuilder.JoinType.INNER);
+
+        final SearchCriteria<NetworkVO> sc = networksSearch.create();
+        sc.setJoinParameters("svcProviderMapSearch", "Provider", providerName);
+        sc.setParameters("physicalNetworkId", physicalNetworkId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final Network.GuestType type, final TrafficType trafficType) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("datacenter", dataCenterId);
+        sc.setParameters("account", accountId);
+        sc.setParameters("guestType", type);
+        sc.setParameters("trafficType", trafficType);
+
+        return listBy(sc, null);
+    }
+
+    @Override
+    public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("datacenter", zoneId);
+        sc.setParameters("trafficType", trafficType);
+
+        return listBy(sc, null);
+    }
+
+    @Override
+    public int getNetworkCountByNetworkOffId(final long networkOfferingId) {
+        final SearchCriteria<Integer> sc = NetworksCount.create();
+        sc.setParameters("networkOfferingId", networkOfferingId);
+        final List<Integer> count = customSearch(sc, null);
+        return count.get(0);
+    }
+
+    @Override
+    public long countNetworksUserCanCreate(final long ownerId) {
+        final SearchCriteria<Long> sc = NetworksRegularUserCanCreateSearch.create();
+        sc.setParameters("aclType", ACLType.Account);
+        sc.setParameters("displayNetwork", 1);
+        sc.setJoinParameters("accounts", "account", ownerId);
+        sc.setJoinParameters("ntwkOff", "specifyVlan", false);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public List<NetworkVO> listSourceNATEnabledNetworks(final long accountId, final long dataCenterId, final Network.GuestType type) {
+        final SearchCriteria<NetworkVO> sc = SourceNATSearch.create();
+        sc.setParameters("datacenter", dataCenterId);
+        sc.setParameters("account", accountId);
+        sc.setParameters("guestType", type);
+        sc.setJoinParameters("services", "service", Service.SourceNat.getName());
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByVpc(final long vpcId) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("vpcId", vpcId);
+
+        return listBy(sc, null);
+    }
+
+    @Override
+    public NetworkVO getPrivateNetwork(final String broadcastUri, final String cidr, final long accountId, final long zoneId, Long networkOfferingId) {
+        if (networkOfferingId == null) {
+            networkOfferingId = _ntwkOffDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOffering).getId();
+        }
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("datacenter", zoneId);
+        sc.setParameters("broadcastUri", broadcastUri);
+        sc.setParameters("cidr", cidr);
+        sc.setParameters("account", accountId);
+        sc.setParameters("offering", networkOfferingId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    @DB
+    public boolean remove(final Long id) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        final NetworkVO entry = findById(id);
+        if (entry != null) {
+            _tagsDao.removeByIdAndType(id, ResourceObjectType.Network);
+        }
+        final boolean result = super.remove(id);
+        txn.commit();
+        return result;
+    }
+
+    @Override
+    public long countVpcNetworks(final long vpcId) {
+        final SearchCriteria<Long> sc = VpcNetworksCount.create();
+        sc.setParameters("vpcId", vpcId);
+        //offering shouldn't be system (the one used by the private gateway)
+        sc.setJoinParameters("offerings", "isSystem", false);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public boolean updateState(final State currentState, final Event event, final State nextState, final Network vo, final Object data) {
+        // TODO: ensure this update is correct
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        final NetworkVO networkVo = (NetworkVO)vo;
+        networkVo.setState(nextState);
+        super.update(networkVo.getId(), networkVo);
+
+        txn.commit();
+        return true;
+    }
+
+    @Override
+    public List<NetworkVO> listNetworksByAccount(final long accountId, final long zoneId, final Network.GuestType type, final boolean isSystem) {
+        final SearchCriteria<NetworkVO> sc = OfferingAccountNetworkSearch.create();
+        sc.setJoinParameters("ntwkOfferingSearch", "isSystem", isSystem);
+        sc.setJoinParameters("ntwkAccountSearch", "accountId", accountId);
+        sc.setParameters("zoneId", zoneId);
+        sc.setParameters("type", type);
+
+        final List<NetworkVO> networks = search(sc, null);
+        return networks;
+    }
+
+    @Override
+    public List<NetworkVO> listRedundantNetworks() {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("redundant", true);
+        return listBy(sc, null);
+    }
+
+    @Override
+    public List<NetworkVO> listVpcNetworks() {
+        final SearchBuilder<NetworkVO> sb = createSearchBuilder();
+        sb.and("vpcId", sb.entity().getVpcId(), Op.NNULL);
+        sb.done();
+
+        final SearchCriteria<NetworkVO> sc = sb.create();
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkVO> listByAclId(final long aclId) {
+        final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+        sc.setParameters("aclId", aclId);
+
+        return listBy(sc, null);
+    }
+
+    @Override
+    public int getNonSystemNetworkCountByVpcId(final long vpcId) {
+        final SearchCriteria<Integer> sc = CountBy.create();
+        sc.setParameters("vpcId", vpcId);
+        sc.setJoinParameters("offerings", "isSystem", false);
+        final List<Integer> results = customSearch(sc, null);
+        return results.get(0);
+    }
+
+    @Override
+    public List<NetworkVO> listNetworkVO(List<Long> idset) {
+        final SearchCriteria<NetworkVO> sc_2 = createSearchCriteria();
+        final Filter searchFilter_2 = new Filter(NetworkVO.class, "id", false, null, null);
+        sc_2.addAnd("networkOfferingId", SearchCriteria.Op.IN, idset);
+        sc_2.addAnd("removed", SearchCriteria.Op.EQ, null);
+        return this.search(sc_2, searchFilter_2);
+    }
+}
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDetailVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDetailVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDetailsDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailsDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDomainDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDomainDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDomainDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDomainDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDomainVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkDomainVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkDomainVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalFirewallVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalFirewallVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkExternalLoadBalancerVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkOpDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkOpDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkOpDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkOpDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkOpDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkOpDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkOpDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkOpDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkOpVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkOpVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkOpVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkOpVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkRuleConfigVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkRuleConfigVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkRuleConfigVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkServiceMapDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkServiceMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkServiceMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkServiceMapVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkServiceMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkServiceMapVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/main/java/com/cloud/network/dao/NetworkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/NetworkVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/NetworkVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceDao.java b/engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceVO.java b/engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/OpRouterMonitorServiceVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/OpRouterMonitorServiceVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/OvsProviderDao.java b/engine/schema/src/main/java/com/cloud/network/dao/OvsProviderDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/OvsProviderDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/OvsProviderDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/OvsProviderDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/OvsProviderDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/OvsProviderDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkDao.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkIsolationMethodDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkIsolationMethodVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTagDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTagVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkTagVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTagVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PhysicalNetworkVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PhysicalNetworkVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/PortProfileDao.java b/engine/schema/src/main/java/com/cloud/network/dao/PortProfileDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PortProfileDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PortProfileDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/PortProfileDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PortProfileDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PortProfileDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/PortProfileVO.java b/engine/schema/src/main/java/com/cloud/network/dao/PortProfileVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/PortProfileVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/PortProfileVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDao.java b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RemoteAccessVpnVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/RouterNetworkDao.java b/engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RouterNetworkDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/RouterNetworkDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RouterNetworkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/RouterNetworkVO.java b/engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/RouterNetworkVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/RouterNetworkVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnConnectionVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/Site2SiteVpnGatewayVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/SslCertDao.java b/engine/schema/src/main/java/com/cloud/network/dao/SslCertDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/SslCertDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/SslCertDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/SslCertDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/SslCertDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/SslCertDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/SslCertDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/SslCertVO.java b/engine/schema/src/main/java/com/cloud/network/dao/SslCertVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/SslCertVO.java
rename to engine/schema/src/main/java/com/cloud/network/dao/SslCertVO.java
diff --git a/engine/schema/src/com/cloud/network/dao/UserIpv6AddressDao.java b/engine/schema/src/main/java/com/cloud/network/dao/UserIpv6AddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/UserIpv6AddressDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/UserIpv6AddressDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/UserIpv6AddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/UserIpv6AddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDao.java b/engine/schema/src/main/java/com/cloud/network/dao/VirtualRouterProviderDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/VirtualRouterProviderDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/VirtualRouterProviderDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/dao/VpnUserDao.java b/engine/schema/src/main/java/com/cloud/network/dao/VpnUserDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/VpnUserDao.java
rename to engine/schema/src/main/java/com/cloud/network/dao/VpnUserDao.java
diff --git a/engine/schema/src/com/cloud/network/dao/VpnUserDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/VpnUserDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/dao/VpnUserDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/dao/VpnUserDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/element/OvsProviderVO.java b/engine/schema/src/main/java/com/cloud/network/element/OvsProviderVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/element/OvsProviderVO.java
rename to engine/schema/src/main/java/com/cloud/network/element/OvsProviderVO.java
diff --git a/engine/schema/src/com/cloud/network/element/VirtualRouterProviderVO.java b/engine/schema/src/main/java/com/cloud/network/element/VirtualRouterProviderVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/element/VirtualRouterProviderVO.java
rename to engine/schema/src/main/java/com/cloud/network/element/VirtualRouterProviderVO.java
diff --git a/engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java b/engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/rules/FirewallRuleVO.java
rename to engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java
diff --git a/engine/schema/src/com/cloud/network/rules/PortForwardingRuleVO.java b/engine/schema/src/main/java/com/cloud/network/rules/PortForwardingRuleVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/rules/PortForwardingRuleVO.java
rename to engine/schema/src/main/java/com/cloud/network/rules/PortForwardingRuleVO.java
diff --git a/engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java b/engine/schema/src/main/java/com/cloud/network/rules/dao/PortForwardingRulesDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDao.java
rename to engine/schema/src/main/java/com/cloud/network/rules/dao/PortForwardingRulesDao.java
diff --git a/engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupRuleVO.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupRuleVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupRuleVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupRuleVO.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupRulesVO.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupRulesVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupRulesVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupRulesVO.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupVMMapVO.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupVMMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupVMMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupVMMapVO.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupVO.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupVO.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupWork.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupWork.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupWork.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupWork.java
diff --git a/engine/schema/src/com/cloud/network/security/SecurityGroupWorkVO.java b/engine/schema/src/main/java/com/cloud/network/security/SecurityGroupWorkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/SecurityGroupWorkVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/SecurityGroupWorkVO.java
diff --git a/engine/schema/src/com/cloud/network/security/VmRulesetLogVO.java b/engine/schema/src/main/java/com/cloud/network/security/VmRulesetLogVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/VmRulesetLogVO.java
rename to engine/schema/src/main/java/com/cloud/network/security/VmRulesetLogVO.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRuleDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRuleDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRuleDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRulesDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRulesDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupRulesDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupVMMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupVMMapDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupVMMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupWorkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupWorkDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/SecurityGroupWorkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/VmRulesetLogDao.java b/engine/schema/src/main/java/com/cloud/network/security/dao/VmRulesetLogDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/VmRulesetLogDao.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/VmRulesetLogDao.java
diff --git a/engine/schema/src/com/cloud/network/security/dao/VmRulesetLogDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/security/dao/VmRulesetLogDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/security/dao/VmRulesetLogDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/security/dao/VmRulesetLogDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemCidrsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemCidrsDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemCidrsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/NetworkACLItemCidrsVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemCidrsVO.java
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemDao.java
new file mode 100644
index 0000000..5903172
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemDao.java
@@ -0,0 +1,47 @@
+// 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.network.vpc;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+
+/**
+ * Data Access Object for network_acl_item table
+ */
+public interface NetworkACLItemDao extends GenericDao<NetworkACLItemVO, Long> {
+
+    boolean setStateToAdd(NetworkACLItemVO rule);
+
+    boolean revoke(NetworkACLItemVO rule);
+
+    List<NetworkACLItemVO> listByACL(Long aclId);
+
+    int getMaxNumberByACL(long aclId);
+
+    NetworkACLItemVO findByAclAndNumber(long aclId, int number);
+
+    void loadCidrs(NetworkACLItemVO item);
+
+    /**
+     * Updated the network ACL item 'number' field.
+     *
+     * @param networkItemId is the ID of the network ACL rule that will have its 'number' field updated.
+     * @param newNumberValue is the new value that will be assigned to the 'number' field.
+     */
+    void updateNumberFieldNetworkItem(long networkItemId, int newNumberValue);
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemVO.java
new file mode 100644
index 0000000..f28b312
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemVO.java
@@ -0,0 +1,275 @@
+// 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.network.vpc;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+@Entity
+@Table(name = "network_acl_item")
+public class NetworkACLItemVO implements NetworkACLItem, Cloneable {
+
+    private static final long serialVersionUID = 2790623532888742060L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "start_port", updatable = false)
+    Integer sourcePortStart;
+
+    @Column(name = "end_port", updatable = false)
+    Integer sourcePortEnd;
+
+    @Column(name = "protocol", updatable = false)
+    String protocol = NetUtils.TCP_PROTO;
+
+    @Enumerated(value = EnumType.STRING)
+    @Column(name = "state")
+    State state;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    Date created;
+
+    @Column(name = "acl_id")
+    long aclId;
+
+    @Column(name = "icmp_code")
+    Integer icmpCode;
+
+    @Column(name = "icmp_type")
+    Integer icmpType;
+
+    @Column(name = "traffic_type")
+    @Enumerated(value = EnumType.STRING)
+    TrafficType trafficType;
+
+    // This is a delayed load value.  If the value is null,
+    // then this field has not been loaded yet.
+    // Call the NetworkACLItem dao to load it.
+    @Transient
+    List<String> sourceCidrs;
+
+    @Column(name = "uuid")
+    String uuid;
+
+    @Column(name = "number")
+    int number;
+
+    @Column(name = "action")
+    @Enumerated(value = EnumType.STRING)
+    Action action;
+
+    @Column(name = "display", updatable = true, nullable = false)
+    protected boolean display = true;
+
+    @Column(name = "reason", length = 2500)
+    private String reason;
+
+    public NetworkACLItemVO() {
+        uuid = UUID.randomUUID().toString();
+    }
+
+    public NetworkACLItemVO(Integer portStart, Integer portEnd, String protocol, long aclId, List<String> sourceCidrs, Integer icmpCode, Integer icmpType, TrafficType trafficType, Action action,
+            int number, String reason) {
+        sourcePortStart = portStart;
+        sourcePortEnd = portEnd;
+        this.protocol = protocol;
+        this.aclId = aclId;
+        state = State.Staged;
+        this.icmpCode = icmpCode;
+        this.icmpType = icmpType;
+        setSourceCidrList(sourceCidrs);
+        uuid = UUID.randomUUID().toString();
+        this.trafficType = trafficType;
+        this.action = action;
+        this.number = number;
+        this.reason = reason;
+    }
+
+    public void setSourceCidrList(List<String> sourceCidrs) {
+        this.sourceCidrs = sourceCidrs;
+    }
+
+    @Override
+    public List<String> getSourceCidrList() {
+        return sourceCidrs;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public Integer getSourcePortStart() {
+        return sourcePortStart;
+    }
+
+    @Override
+    public Integer getSourcePortEnd() {
+        return sourcePortEnd;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    @Override
+    public long getAclId() {
+        return aclId;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("Rule[").append(id).append("-").append("NetworkACL").append("-").append(state).append("]").toString();
+    }
+
+    @Override
+    public Integer getIcmpCode() {
+        return icmpCode;
+    }
+
+    @Override
+    public Integer getIcmpType() {
+        return icmpType;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    @Override
+    public Action getAction() {
+        return action;
+    }
+
+    @Override
+    public int getNumber() {
+        return number;
+    }
+
+    @Override
+    public TrafficType getTrafficType() {
+        return trafficType;
+    }
+
+    public void setSourcePortStart(Integer sourcePortStart) {
+        this.sourcePortStart = sourcePortStart;
+    }
+
+    public void setSourcePortEnd(Integer sourcePortEnd) {
+        this.sourcePortEnd = sourcePortEnd;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public void setIcmpCode(Integer icmpCode) {
+        this.icmpCode = icmpCode;
+    }
+
+    public void setIcmpType(Integer icmpType) {
+        this.icmpType = icmpType;
+    }
+
+    public void setTrafficType(TrafficType trafficType) {
+        this.trafficType = trafficType;
+    }
+
+    public void setSourceCidrs(String sourceCidrs) {
+        List<String> srcCidrs = new LinkedList<String>();
+        StringTokenizer st = new StringTokenizer(sourceCidrs, ",;");
+        while (st.hasMoreTokens()) {
+            srcCidrs.add(st.nextToken());
+        }
+        this.sourceCidrs = srcCidrs;
+    }
+
+    public void setNumber(int number) {
+        this.number = number;
+    }
+
+    public void setAction(Action action) {
+        this.action = action;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setDisplay(boolean display) {
+        this.display = display;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        return display;
+    }
+
+    @Override
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    @Override
+    protected NetworkACLItemVO clone() {
+        try {
+            return (NetworkACLItemVO)super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new CloudRuntimeException(e);
+        }
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLVO.java
new file mode 100644
index 0000000..4eaa2b5
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLVO.java
@@ -0,0 +1,112 @@
+// 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.network.vpc;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "network_acl")
+public class NetworkACLVO implements NetworkACL {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "vpc_id")
+    Long vpcId;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "description")
+    private String description;
+
+    @Column(name = "display", updatable = true, nullable = false)
+    protected boolean display = true;
+
+    public NetworkACLVO() {
+    }
+
+    protected NetworkACLVO(String name, String description, long vpcId) {
+        this.uuid = UUID.randomUUID().toString();
+        this.name = name;
+        this.description = description;
+        this.vpcId = vpcId;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    @Override
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setDisplay(boolean display) {
+        this.display = display;
+    }
+
+    public void setVpcId(long vpcId) {
+        this.vpcId = vpcId;
+    }
+
+    @Override
+    public boolean isDisplay() {
+        return display;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/PrivateIpVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/PrivateIpVO.java
new file mode 100644
index 0000000..d03e55d
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/PrivateIpVO.java
@@ -0,0 +1,104 @@
+// 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.network.vpc;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+@Entity
+@Table(name = "private_ip_address")
+public class PrivateIpVO implements InternalIdentity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "ip_address", updatable = false, nullable = false)
+    String ipAddress;
+
+    @Column(name = "mac_address")
+    private long macAddress;
+
+    @Column(name = "taken")
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date takenAt;
+
+    @Column(name = "network_id", updatable = false, nullable = false)
+    private long networkId;
+
+    @Column(name = "vpc_id")
+    private Long vpcId;
+
+    @Column(name = "source_nat")
+    private boolean sourceNat;
+
+    public PrivateIpVO() {
+    }
+
+    public PrivateIpVO(String ipAddress, long networkId, long macAddress, long vpcId, boolean sourceNat) {
+        this.ipAddress = ipAddress;
+        this.networkId = networkId;
+        this.macAddress = macAddress;
+        this.vpcId = vpcId;
+        this.sourceNat = sourceNat;
+    }
+
+    public void setTakenAt(Date takenDate) {
+        this.takenAt = takenDate;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public long getNetworkId() {
+        return networkId;
+    }
+
+    public Date getTakenAt() {
+        return takenAt;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public long getMacAddress() {
+        return macAddress;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public boolean isSourceNat() {
+        return sourceNat;
+    }
+
+}
diff --git a/engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/StaticRouteVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcGatewayVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/VpcGatewayVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/VpcGatewayVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingServiceMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingServiceMapVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcServiceMapVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcServiceMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/VpcServiceMapVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/VpcServiceMapVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/VpcVO.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/VpcVO.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/NetworkACLDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/NetworkACLDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/NetworkACLDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLDaoImpl.java
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java
new file mode 100644
index 0000000..4501f14
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java
@@ -0,0 +1,102 @@
+/**
+ * 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.network.vpc.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.vpc.NetworkACLItemCidrsDao;
+import com.cloud.network.vpc.NetworkACLItemCidrsVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+
+/**
+ * @author daan
+ *
+ */
+@Component
+public class NetworkACLItemCidrsDaoImpl extends GenericDaoBase<NetworkACLItemCidrsVO, Long> implements NetworkACLItemCidrsDao {
+    private static final Logger s_logger = Logger.getLogger(NetworkACLItemCidrsDaoImpl.class);
+    protected final SearchBuilder<NetworkACLItemCidrsVO> cidrsSearch;
+
+    protected NetworkACLItemCidrsDaoImpl() {
+        cidrsSearch = createSearchBuilder();
+        cidrsSearch.and("networkAclItemId", cidrsSearch.entity().getNetworkACLItemId(), SearchCriteria.Op.EQ);
+        cidrsSearch.done();
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.dao.NetworkAclItemCidrsDao#persist(long, java.util.List)
+     */
+    @Override
+    public void persist(long networkACLItemId, List<String> cidrs) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+
+        txn.start();
+        for (String cidr : cidrs) {
+            NetworkACLItemCidrsVO vo = new NetworkACLItemCidrsVO(networkACLItemId, cidr);
+            persist(vo);
+        }
+        txn.commit();
+    }
+
+    @Override
+    public void updateCidrs(long networkACLItemId, List<String> cidrs) {
+        List<String> oldCidrs = getCidrs(networkACLItemId);
+        if (!(oldCidrs.size() == cidrs.size() && oldCidrs.equals(cidrs))) {
+            SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
+            sc.setParameters("networkAclItemId", networkACLItemId);
+            remove(sc);
+            persist(networkACLItemId, cidrs);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.dao.NetworkAclItemCidrsDao#getCidrs(long)
+     */
+    @Override
+    public List<String> getCidrs(long networkACLItemId) {
+        SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
+        sc.setParameters("networkAclItemId", networkACLItemId);
+
+        List<NetworkACLItemCidrsVO> results = search(sc, null);
+        List<String> cidrs = new ArrayList<String>(results.size());
+        for (NetworkACLItemCidrsVO result : results) {
+            cidrs.add(result.getCidr());
+        }
+
+        return cidrs;
+    }
+
+    @Override
+    public List<NetworkACLItemCidrsVO> listByNetworkACLItemId(long networkACLItemId) {
+        SearchCriteria<NetworkACLItemCidrsVO> sc = cidrsSearch.create();
+        sc.setParameters("networkAclItemId", networkACLItemId);
+
+        List<NetworkACLItemCidrsVO> results = search(sc, null);
+
+        return results;
+    }
+
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
new file mode 100644
index 0000000..b88cc0d
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
@@ -0,0 +1,193 @@
+// 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.network.vpc.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.vpc.NetworkACLItem.State;
+import com.cloud.network.vpc.NetworkACLItemCidrsDao;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.collect.Lists;
+
+@DB()
+@Component
+public class NetworkACLItemDaoImpl extends GenericDaoBase<NetworkACLItemVO, Long> implements NetworkACLItemDao {
+
+    protected final SearchBuilder<NetworkACLItemVO> AllFieldsSearch;
+    protected final SearchBuilder<NetworkACLItemVO> NotRevokedSearch;
+    protected final SearchBuilder<NetworkACLItemVO> ReleaseSearch;
+    protected final GenericSearchBuilder<NetworkACLItemVO, Integer> MaxNumberSearch;
+
+    @Inject
+    protected NetworkACLItemCidrsDao _networkACLItemCidrsDao;
+
+    protected NetworkACLItemDaoImpl() {
+        super();
+
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("protocol", AllFieldsSearch.entity().getProtocol(), Op.EQ);
+        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
+        AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getAclId(), Op.EQ);
+        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
+        AllFieldsSearch.and("number", AllFieldsSearch.entity().getNumber(), Op.EQ);
+        AllFieldsSearch.and("action", AllFieldsSearch.entity().getAction(), Op.EQ);
+        AllFieldsSearch.done();
+
+        NotRevokedSearch = createSearchBuilder();
+        NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ);
+        NotRevokedSearch.and("protocol", NotRevokedSearch.entity().getProtocol(), Op.EQ);
+        NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(), Op.EQ);
+        NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(), Op.EQ);
+        NotRevokedSearch.and("aclId", NotRevokedSearch.entity().getAclId(), Op.EQ);
+        NotRevokedSearch.and("trafficType", NotRevokedSearch.entity().getTrafficType(), Op.EQ);
+        NotRevokedSearch.done();
+
+        ReleaseSearch = createSearchBuilder();
+        ReleaseSearch.and("protocol", ReleaseSearch.entity().getProtocol(), Op.EQ);
+        ReleaseSearch.and("ports", ReleaseSearch.entity().getSourcePortStart(), Op.IN);
+        ReleaseSearch.done();
+
+        MaxNumberSearch = createSearchBuilder(Integer.class);
+        MaxNumberSearch.select(null, SearchCriteria.Func.MAX, MaxNumberSearch.entity().getNumber());
+        MaxNumberSearch.and("aclId", MaxNumberSearch.entity().getAclId(), Op.EQ);
+        MaxNumberSearch.done();
+    }
+
+    @Override
+    public NetworkACLItemVO findById(Long id) {
+        NetworkACLItemVO item = super.findById(id);
+        loadCidrs(item);
+        return item;
+    }
+
+    @Override
+    public boolean update(Long id, NetworkACLItemVO item) {
+        boolean result = super.update(id, item);
+        _networkACLItemCidrsDao.updateCidrs(item.getId(), item.getSourceCidrList());
+        return result;
+    }
+
+    @Override
+    public boolean setStateToAdd(NetworkACLItemVO rule) {
+        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
+        sc.setParameters("id", rule.getId());
+        sc.setParameters("state", State.Staged);
+
+        rule.setState(State.Add);
+
+        return update(rule, sc) > 0;
+    }
+
+    @Override
+    public boolean revoke(NetworkACLItemVO rule) {
+        rule.setState(State.Revoke);
+        return update(rule.getId(), rule);
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listByACL(Long aclId) {
+        if (aclId == null) {
+            return Lists.newArrayList();
+        }
+
+        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
+        sc.setParameters("aclId", aclId);
+        List<NetworkACLItemVO> list = listBy(sc);
+        for (NetworkACLItemVO item : list) {
+            loadCidrs(item);
+        }
+        return list;
+    }
+
+    @Override
+    public int getMaxNumberByACL(long aclId) {
+        SearchCriteria<Integer> sc = MaxNumberSearch.create();
+        sc.setParameters("aclId", aclId);
+        Integer max = customSearch(sc, null).get(0);
+        return (max == null) ? 0 : max;
+    }
+
+    @Override
+    public NetworkACLItemVO findByAclAndNumber(long aclId, int number) {
+        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
+        sc.setParameters("aclId", aclId);
+        sc.setParameters("number", number);
+        NetworkACLItemVO vo = findOneBy(sc);
+        if (vo != null) {
+            loadCidrs(vo);
+        }
+        return vo;
+    }
+
+    @Override
+    @DB
+    public NetworkACLItemVO persist(NetworkACLItemVO networkAclItem) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        NetworkACLItemVO dbNetworkACLItem = super.persist(networkAclItem);
+        saveCidrs(networkAclItem, networkAclItem.getSourceCidrList());
+        loadCidrs(dbNetworkACLItem);
+
+        txn.commit();
+        return dbNetworkACLItem;
+    }
+
+    public void saveCidrs(NetworkACLItemVO networkACLItem, List<String> cidrList) {
+        if (cidrList == null) {
+            return;
+        }
+        _networkACLItemCidrsDao.persist(networkACLItem.getId(), cidrList);
+    }
+
+    @Override
+    public void loadCidrs(NetworkACLItemVO item) {
+        List<String> cidrs = _networkACLItemCidrsDao.getCidrs(item.getId());
+        item.setSourceCidrList(cidrs);
+    }
+
+    private String sqlUpdateNumberFieldNetworkItem = "UPDATE network_acl_item SET number = ? where id =?";
+
+    @Override
+    public void updateNumberFieldNetworkItem(long networkItemId, int newNumberValue) {
+        try (TransactionLegacy txn = TransactionLegacy.currentTxn();
+                PreparedStatement pstmt = txn.prepareAutoCloseStatement(sqlUpdateNumberFieldNetworkItem)) {
+            pstmt.setLong(1, newNumberValue);
+            pstmt.setLong(2, networkItemId);
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException(e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/PrivateIpDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/PrivateIpDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/StaticRouteDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcGatewayDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcGatewayDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcGatewayDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcServiceMapDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcServiceMapDao.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDao.java
diff --git a/engine/schema/src/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingDetailsVO.java b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/NetworkOfferingDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingDetailsVO.java
diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingServiceMapVO.java b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingServiceMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/NetworkOfferingServiceMapVO.java
rename to engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingServiceMapVO.java
diff --git a/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java
new file mode 100644
index 0000000..338ef57
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java
@@ -0,0 +1,537 @@
+// 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.offerings;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "network_offerings")
+public class NetworkOfferingVO implements NetworkOffering {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "name")
+    String name;
+
+    @Column(name = "unique_name")
+    private String uniqueName;
+
+    @Column(name = "display_text")
+    String displayText;
+
+    @Column(name = "nw_rate")
+    Integer rateMbps;
+
+    @Column(name = "mc_rate")
+    Integer multicastRateMbps;
+
+    @Column(name = "traffic_type")
+    @Enumerated(value = EnumType.STRING)
+    TrafficType trafficType;
+
+    @Column(name = "specify_vlan")
+    boolean specifyVlan;
+
+    @Column(name = "system_only")
+    boolean systemOnly;
+
+    @Column(name = "service_offering_id")
+    Long serviceOfferingId;
+
+    @Column(name = "tags", length = 4096)
+    String tags;
+
+    @Column(name = "default")
+    boolean isDefault;
+
+    @Column(name = "availability")
+    @Enumerated(value = EnumType.STRING)
+    Availability availability;
+
+    @Column(name = "state")
+    @Enumerated(value = EnumType.STRING)
+    State state = State.Disabled;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    Date created;
+
+    @Column(name = "guest_type")
+    @Enumerated(value = EnumType.STRING)
+    Network.GuestType guestType;
+
+    @Column(name = "dedicated_lb_service")
+    boolean dedicatedLB;
+
+    @Column(name = "shared_source_nat_service")
+    boolean sharedSourceNat;
+
+    @Column(name = "specify_ip_ranges")
+    boolean specifyIpRanges = false;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "uuid")
+    String uuid;
+
+    @Column(name = "redundant_router_service")
+    boolean redundantRouter;
+
+    @Column(name = "conserve_mode")
+    boolean conserveMode;
+
+    @Column(name = "elastic_ip_service")
+    boolean elasticIp;
+
+    @Column(name = "eip_associate_public_ip")
+    boolean eipAssociatePublicIp;
+
+    @Column(name = "elastic_lb_service")
+    boolean elasticLb;
+
+    @Column(name = "inline")
+    boolean inline;
+
+    @Column(name = "is_persistent")
+    boolean persistent;
+
+    @Column(name = "for_vpc")
+    boolean forVpc;
+
+    @Column(name = "egress_default_policy")
+    boolean egressdefaultpolicy;
+
+    @Column(name = "concurrent_connections")
+    Integer concurrentConnections;
+
+    @Column(name = "keep_alive_enabled")
+    boolean keepAliveEnabled = false;
+
+    @Column(name="supports_streched_l2")
+    boolean supportsStrechedL2 = false;
+
+    @Column(name="supports_public_access")
+    boolean supportsPublicAccess = false;
+
+    @Override
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    @Column(name = "internal_lb")
+    boolean internalLb;
+
+    @Column(name = "public_lb")
+    boolean publicLb;
+
+    @Column(name="service_package_id")
+    String servicePackageUuid = null;
+
+    @Override
+    public boolean isKeepAliveEnabled() {
+        return keepAliveEnabled;
+    }
+
+    public void setKeepAliveEnabled(boolean keepAliveEnabled) {
+        this.keepAliveEnabled = keepAliveEnabled;
+    }
+
+    @Override
+    public boolean isForVpc() {
+        return forVpc;
+    }
+
+    public void setForVpc(boolean isForVpc) {
+        this.forVpc = isForVpc;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public TrafficType getTrafficType() {
+        return trafficType;
+    }
+
+    @Override
+    public Integer getMulticastRateMbps() {
+        return multicastRateMbps;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Integer getRateMbps() {
+        return rateMbps;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
+    public boolean isSystemOnly() {
+        return systemOnly;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    public void setRateMbps(Integer rateMbps) {
+        this.rateMbps = rateMbps;
+    }
+
+    public void setMulticastRateMbps(Integer multicastRateMbps) {
+        this.multicastRateMbps = multicastRateMbps;
+    }
+
+    @Override
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    @Override
+    public boolean isSpecifyVlan() {
+        return specifyVlan;
+    }
+
+    @Override
+    public Availability getAvailability() {
+        return availability;
+    }
+
+    public void setAvailability(Availability availability) {
+        this.availability = availability;
+    }
+
+    @Override
+    public String getUniqueName() {
+        return uniqueName;
+    }
+
+    @Override
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    @Override
+    public Network.GuestType getGuestType() {
+        return guestType;
+    }
+
+    public void setServiceOfferingId(Long serviceOfferingId) {
+        this.serviceOfferingId = serviceOfferingId;
+    }
+
+    @Override
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    @Override
+    public boolean isDedicatedLB() {
+        return dedicatedLB;
+    }
+
+    public void setDedicatedLB(boolean dedicatedLB) {
+        this.dedicatedLB = dedicatedLB;
+    }
+
+    @Override
+    public boolean isSharedSourceNat() {
+        return sharedSourceNat;
+    }
+
+    public void setSharedSourceNat(boolean sharedSourceNat) {
+        this.sharedSourceNat = sharedSourceNat;
+    }
+
+    @Override
+    public boolean isRedundantRouter() {
+        return redundantRouter;
+    }
+
+    public void setRedundantRouter(boolean redundantRouter) {
+        this.redundantRouter = redundantRouter;
+    }
+
+    @Override
+    public boolean isEgressDefaultPolicy() {
+        return egressdefaultpolicy;
+    }
+
+    public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps,
+            Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode,
+            boolean specifyIpRanges, boolean isPersistent, boolean internalLb, boolean publicLb, boolean isForVpc) {
+        this.name = name;
+        this.displayText = displayText;
+        this.rateMbps = rateMbps;
+        this.multicastRateMbps = multicastRateMbps;
+        this.trafficType = trafficType;
+        this.systemOnly = systemOnly;
+        this.specifyVlan = specifyVlan;
+        this.isDefault = isDefault;
+        this.availability = availability;
+        this.uniqueName = name;
+        this.uuid = UUID.randomUUID().toString();
+        this.tags = tags;
+        this.guestType = guestType;
+        this.conserveMode = conserveMode;
+        this.dedicatedLB = true;
+        this.sharedSourceNat = false;
+        this.redundantRouter = false;
+        this.elasticIp = false;
+        this.eipAssociatePublicIp = true;
+        this.elasticLb = false;
+        this.inline = false;
+        this.specifyIpRanges = specifyIpRanges;
+        this.persistent = isPersistent;
+        this.publicLb = publicLb;
+        this.internalLb = internalLb;
+        this.forVpc = isForVpc;
+    }
+
+    public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps,
+            Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb,
+            boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, boolean specifyIpRanges, boolean inline, boolean isPersistent,
+            boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean isForVpc, boolean egressdefaultpolicy, boolean supportsStrechedL2, boolean supportsPublicAccess) {
+        this(name,
+            displayText,
+            trafficType,
+            systemOnly,
+            specifyVlan,
+            rateMbps,
+            multicastRateMbps,
+            isDefault,
+            availability,
+            tags,
+            guestType,
+            conserveMode,
+            specifyIpRanges,
+            isPersistent,
+            internalLb,
+            publicLb, isForVpc);
+        this.dedicatedLB = dedicatedLb;
+        this.sharedSourceNat = sharedSourceNat;
+        this.redundantRouter = redundantRouter;
+        this.elasticIp = elasticIp;
+        this.elasticLb = elasticLb;
+        this.inline = inline;
+        this.eipAssociatePublicIp = associatePublicIP;
+        this.egressdefaultpolicy = egressdefaultpolicy;
+        this.supportsStrechedL2 = supportsStrechedL2;
+        this.supportsPublicAccess = supportsPublicAccess;
+    }
+
+    public NetworkOfferingVO() {
+    }
+
+    /**
+     * Network Offering for all system vms.
+     *
+     * @param name
+     * @param trafficType
+     * @param specifyIpRanges
+     *            TODO
+     */
+    public NetworkOfferingVO(String name, TrafficType trafficType, boolean specifyIpRanges) {
+        this(name, "System Offering for " + name, trafficType, true, false, 0, 0, true, Availability.Required, null, null, true, specifyIpRanges, false, false, false, false);
+        this.state = State.Enabled;
+    }
+
+    public NetworkOfferingVO(String name, Network.GuestType guestType) {
+        this(name,
+            "System Offering for " + name,
+            TrafficType.Guest,
+            true,
+            true,
+            0,
+            0,
+            true,
+            Availability.Optional,
+            null,
+            Network.GuestType.Isolated,
+            true,
+            false,
+            false,
+            false,
+            false,
+            false);
+        this.state = State.Enabled;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("[Network Offering [");
+        return buf.append(id).append("-").append(trafficType).append("-").append(name).append("]").toString();
+    }
+
+    @Override
+    public String getUuid() {
+        return this.uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setSortKey(int key) {
+        sortKey = key;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public void setUniqueName(String uniqueName) {
+        this.uniqueName = uniqueName;
+    }
+
+    @Override
+    public boolean isConserveMode() {
+        return conserveMode;
+    }
+
+    @Override
+    public boolean isElasticIp() {
+        return elasticIp;
+    }
+
+    @Override
+    public boolean isAssociatePublicIP() {
+        return eipAssociatePublicIp;
+    }
+
+    @Override
+    public boolean isElasticLb() {
+        return elasticLb;
+    }
+
+    @Override
+    public boolean isSpecifyIpRanges() {
+        return specifyIpRanges;
+    }
+
+    @Override
+    public boolean isInline() {
+        return inline;
+    }
+
+    public void setIsPersistent(Boolean isPersistent) {
+        this.persistent = isPersistent;
+    }
+
+    @Override
+    public boolean isPersistent() {
+        return persistent;
+    }
+
+    @Override
+    public boolean isInternalLb() {
+        return internalLb;
+    }
+
+    @Override
+    public boolean isPublicLb() {
+        return publicLb;
+    }
+
+    public void setInternalLb(boolean internalLb) {
+        this.internalLb = internalLb;
+    }
+
+    @Override
+    public Integer getConcurrentConnections() {
+        return this.concurrentConnections;
+    }
+
+    public void setConcurrentConnections(Integer concurrentConnections) {
+        this.concurrentConnections = concurrentConnections;
+    }
+
+    public void setPublicLb(boolean publicLb) {
+        this.publicLb = publicLb;
+    }
+
+    @Override
+    public boolean isSupportingStrechedL2() {
+        return supportsStrechedL2;
+    }
+
+    public void  setServicePackage(String servicePackageUuid) {
+        this.servicePackageUuid = servicePackageUuid;
+    }
+
+    @Override
+    public boolean isSupportingPublicAccess() {
+        return supportsPublicAccess;
+    }
+
+    @Override
+    public String getServicePackage() {
+        return servicePackageUuid;
+    }
+}
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java
rename to engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDao.java
diff --git a/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
new file mode 100644
index 0000000..dd607ed
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
@@ -0,0 +1,272 @@
+// 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.offerings.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.persistence.EntityExistsException;
+
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offerings.NetworkOfferingDetailsVO;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+
+@Component
+@DB()
+public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Long> implements NetworkOfferingDao {
+    final SearchBuilder<NetworkOfferingVO> NameSearch;
+    final SearchBuilder<NetworkOfferingVO> SystemOfferingSearch;
+    final SearchBuilder<NetworkOfferingVO> AvailabilitySearch;
+    final SearchBuilder<NetworkOfferingVO> AllFieldsSearch;
+    private final GenericSearchBuilder<NetworkOfferingVO, Long> UpgradeSearch;
+    @Inject
+    NetworkOfferingDetailsDao _detailsDao;
+    @Inject
+    private NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
+
+    protected NetworkOfferingDaoImpl() {
+        super();
+
+        NameSearch = createSearchBuilder();
+        NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
+        NameSearch.and("uniqueName", NameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
+        NameSearch.done();
+
+        SystemOfferingSearch = createSearchBuilder();
+        SystemOfferingSearch.and("system", SystemOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
+        SystemOfferingSearch.done();
+
+        AvailabilitySearch = createSearchBuilder();
+        AvailabilitySearch.and("availability", AvailabilitySearch.entity().getAvailability(), SearchCriteria.Op.EQ);
+        AvailabilitySearch.and("isSystem", AvailabilitySearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
+        AvailabilitySearch.done();
+
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("isSystem", AllFieldsSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.done();
+
+        UpgradeSearch = createSearchBuilder(Long.class);
+        UpgradeSearch.selectFields(UpgradeSearch.entity().getId());
+        UpgradeSearch.and("physicalNetworkId", UpgradeSearch.entity().getId(), Op.NEQ);
+        UpgradeSearch.and("physicalNetworkId", UpgradeSearch.entity().isSystemOnly(), Op.EQ);
+        UpgradeSearch.and("trafficType", UpgradeSearch.entity().getTrafficType(), Op.EQ);
+        UpgradeSearch.and("guestType", UpgradeSearch.entity().getGuestType(), Op.EQ);
+        UpgradeSearch.and("state", UpgradeSearch.entity().getState(), Op.EQ);
+        UpgradeSearch.done();
+    }
+
+    @Override
+    public NetworkOfferingVO findByUniqueName(String uniqueName) {
+        SearchCriteria<NetworkOfferingVO> sc = NameSearch.create();
+
+        sc.setParameters("uniqueName", uniqueName);
+
+        return findOneBy(sc);
+
+    }
+
+    @Override
+    public NetworkOfferingVO persistDefaultNetworkOffering(NetworkOfferingVO offering) {
+        assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
+        NetworkOfferingVO vo = findByUniqueName(offering.getUniqueName());
+        if (vo != null) {
+            return vo;
+        }
+        try {
+            vo = persist(offering);
+            return vo;
+        } catch (EntityExistsException e) {
+            // Assume it's conflict on unique name from two different management servers.
+            return findByUniqueName(offering.getName());
+        }
+    }
+
+    @Override
+    public List<NetworkOfferingVO> listSystemNetworkOfferings() {
+        SearchCriteria<NetworkOfferingVO> sc = SystemOfferingSearch.create();
+        sc.setParameters("system", true);
+        return this.listIncludingRemovedBy(sc, null);
+    }
+
+    @Override
+    public List<NetworkOfferingVO> listByAvailability(Availability availability, boolean isSystem) {
+        SearchCriteria<NetworkOfferingVO> sc = AvailabilitySearch.create();
+        sc.setParameters("availability", availability);
+        sc.setParameters("isSystem", isSystem);
+        return listBy(sc, null);
+    }
+
+    @Override
+    @DB
+    public boolean remove(Long networkOfferingId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        NetworkOfferingVO offering = findById(networkOfferingId);
+        offering.setUniqueName(null);
+        update(networkOfferingId, offering);
+        boolean result = super.remove(networkOfferingId);
+        txn.commit();
+        return result;
+    }
+
+    @Override
+    public List<Long> getOfferingIdsToUpgradeFrom(NetworkOffering originalOffering) {
+        SearchCriteria<Long> sc = UpgradeSearch.create();
+        // exclude original offering
+        sc.addAnd("id", SearchCriteria.Op.NEQ, originalOffering.getId());
+
+        // list only non-system offerings
+        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, false);
+
+        // Type of the network should be the same
+        sc.addAnd("guestType", SearchCriteria.Op.EQ, originalOffering.getGuestType());
+
+        // Traffic types should be the same
+        sc.addAnd("trafficType", SearchCriteria.Op.EQ, originalOffering.getTrafficType());
+
+        sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled);
+
+        //specify Vlan should be the same
+        sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, originalOffering.isSpecifyVlan());
+
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public List<NetworkOfferingVO> listByTrafficTypeGuestTypeAndState(NetworkOffering.State state, TrafficType trafficType, Network.GuestType type) {
+        SearchCriteria<NetworkOfferingVO> sc = AllFieldsSearch.create();
+        sc.setParameters("trafficType", trafficType);
+        sc.setParameters("guestType", type);
+        sc.setParameters("state", state);
+        return listBy(sc, null);
+    }
+
+    @Override
+    @DB
+    public NetworkOfferingVO persist(NetworkOfferingVO off, Map<Detail, String> details) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        //1) persist the offering
+        NetworkOfferingVO vo = super.persist(off);
+
+        //2) persist the details
+        if (details != null && !details.isEmpty()) {
+            for (NetworkOffering.Detail detail : details.keySet()) {
+                _detailsDao.persist(new NetworkOfferingDetailsVO(off.getId(), detail, details.get(detail)));
+            }
+        }
+
+        txn.commit();
+        return vo;
+    }
+
+    @Override
+    public List<Long> listNetworkOfferingID() {
+        final SearchCriteria<NetworkOfferingVO> sc_1 = createSearchCriteria();
+        final Filter searchFilter_1 = new Filter(NetworkOfferingVO.class, "created", false, null, null);
+        sc_1.addAnd("servicePackageUuid", SearchCriteria.Op.NEQ, null);
+        sc_1.addAnd("removed", SearchCriteria.Op.EQ, null);
+        List<NetworkOfferingVO> set_of_servicePackageUuid = this.search(sc_1, searchFilter_1);
+        List<Long> id_set = new ArrayList<Long>();
+        for (NetworkOfferingVO node : set_of_servicePackageUuid) {
+            if (node.getServicePackage() != null && !node.getServicePackage().isEmpty()) {
+                id_set.add(node.getId());
+            }
+        }
+        return id_set;
+    }
+
+    @Override
+    public boolean isUsingServicePackage(String uuid) {
+        final SearchCriteria<NetworkOfferingVO> sc = createSearchCriteria();
+        final Filter searchFilter= new Filter(NetworkOfferingVO.class, "created", false, null, null);
+        sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled);
+        sc.addAnd("servicePackageUuid", SearchCriteria.Op.EQ, uuid);
+        List<NetworkOfferingVO> list = this.search(sc, searchFilter);
+
+        if(CollectionUtils.isNotEmpty(list))
+            return true;
+
+        return false;
+    }
+
+    /**
+     * Persist L2 deafult Network offering
+     */
+    private void persistL2DefaultNetworkOffering(String name, String displayText, boolean specifyVlan, boolean configDriveEnabled) {
+        NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, TrafficType.Guest, false, specifyVlan,
+                null, null, true, Availability.Optional, null, Network.GuestType.L2,
+                true,false, false, false, false, false);
+        offering.setState(NetworkOffering.State.Enabled);
+        persistDefaultNetworkOffering(offering);
+
+        if (configDriveEnabled) {
+            NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(),
+                    Network.Service.UserData, Network.Provider.ConfigDrive);
+            networkOfferingServiceMapDao.persist(offService);
+        }
+    }
+
+    /**
+     * Check for default L2 Network Offerings, create them if they are not already created
+     */
+    private void checkPersistL2NetworkOffering(String name, String displayText, boolean specifyVlan, boolean configDriveEnabled) {
+        if (findByUniqueName(name) == null) {
+            persistL2DefaultNetworkOffering(name, displayText, specifyVlan, configDriveEnabled);
+        }
+    }
+
+    @Override
+    public void persistDefaultL2NetworkOfferings() {
+        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOffering,
+                "Offering for L2 networks",
+                false, false);
+
+        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingVlan,
+                "Offering for L2 networks VLAN",
+                true, false);
+
+        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingConfigDrive,
+                "Offering for L2 networks with config drive user data",
+                false, true);
+
+        checkPersistL2NetworkOffering(NetworkOffering.DefaultL2NetworkOfferingConfigDriveVlan,
+                "Offering for L2 networks with config drive user data VLAN",
+                true, true);
+    }
+}
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDao.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDetailsDao.java
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java
rename to engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/projects/ProjectAccountVO.java b/engine/schema/src/main/java/com/cloud/projects/ProjectAccountVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/ProjectAccountVO.java
rename to engine/schema/src/main/java/com/cloud/projects/ProjectAccountVO.java
diff --git a/engine/schema/src/com/cloud/projects/ProjectInvitationVO.java b/engine/schema/src/main/java/com/cloud/projects/ProjectInvitationVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/ProjectInvitationVO.java
rename to engine/schema/src/main/java/com/cloud/projects/ProjectInvitationVO.java
diff --git a/engine/schema/src/com/cloud/projects/ProjectVO.java b/engine/schema/src/main/java/com/cloud/projects/ProjectVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/ProjectVO.java
rename to engine/schema/src/main/java/com/cloud/projects/ProjectVO.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectAccountDao.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectAccountDao.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectAccountDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectDao.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectDao.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectDao.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectDaoImpl.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectInvitationDao.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectInvitationDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectInvitationDao.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectInvitationDao.java
diff --git a/engine/schema/src/com/cloud/projects/dao/ProjectInvitationDaoImpl.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectInvitationDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/projects/dao/ProjectInvitationDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/projects/dao/ProjectInvitationDaoImpl.java
diff --git a/engine/schema/src/com/cloud/secstorage/CommandExecLogDao.java b/engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/secstorage/CommandExecLogDao.java
rename to engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogDao.java
diff --git a/engine/schema/src/com/cloud/secstorage/CommandExecLogDaoImpl.java b/engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/secstorage/CommandExecLogDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogDaoImpl.java
diff --git a/engine/schema/src/com/cloud/secstorage/CommandExecLogVO.java b/engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/secstorage/CommandExecLogVO.java
rename to engine/schema/src/main/java/com/cloud/secstorage/CommandExecLogVO.java
diff --git a/engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/service/ServiceOfferingDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/service/ServiceOfferingDetailsVO.java
diff --git a/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java
new file mode 100644
index 0000000..efaadcf
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java
@@ -0,0 +1,334 @@
+// 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.service;
+
+import java.util.Map;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.vm.VirtualMachine;
+
+@Entity
+@Table(name = "service_offering")
+@DiscriminatorValue(value = "Service")
+@PrimaryKeyJoinColumn(name = "id")
+public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
+    @Column(name = "cpu")
+    private Integer cpu;
+
+    @Column(name = "speed")
+    private Integer speed;
+
+    @Column(name = "ram_size")
+    private Integer ramSize;
+
+    @Column(name = "nw_rate")
+    private Integer rateMbps;
+
+    @Column(name = "mc_rate")
+    private Integer multicastRateMbps;
+
+    @Column(name = "ha_enabled")
+    private boolean offerHA;
+
+    @Column(name = "limit_cpu_use")
+    private boolean limitCpuUse;
+
+    @Column(name = "is_volatile")
+    private boolean volatileVm;
+
+    @Column(name = "host_tag")
+    private String hostTag;
+
+    @Column(name = "default_use")
+    private boolean defaultUse;
+
+    @Column(name = "vm_type")
+    private String vmType;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "deployment_planner")
+    private String deploymentPlanner = null;
+
+    // This is a delayed load value.  If the value is null,
+    // then this field has not been loaded yet.
+    // Call service offering dao to load it.
+    @Transient
+    Map<String, String> details;
+
+    // This flag is required to tell if the offering is dynamic once the cpu, memory and speed are set.
+    // In some cases cpu, memory and speed are set to non-null values even if the offering is dynamic.
+    @Transient
+    boolean isDynamic;
+
+    protected ServiceOfferingVO() {
+        super();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
+            ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
+        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
+        this.cpu = cpu;
+        this.ramSize = ramSize;
+        this.speed = speed;
+        this.rateMbps = rateMbps;
+        this.multicastRateMbps = multicastRateMbps;
+        this.offerHA = offerHA;
+        limitCpuUse = false;
+        volatileVm = false;
+        this.defaultUse = defaultUse;
+        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
+            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, Long domainId) {
+        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
+        this.cpu = cpu;
+        this.ramSize = ramSize;
+        this.speed = speed;
+        this.rateMbps = rateMbps;
+        this.multicastRateMbps = multicastRateMbps;
+        this.offerHA = offerHA;
+        this.limitCpuUse = limitCpuUse;
+        this.volatileVm = volatileVm;
+        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
+            boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
+            VirtualMachine.Type vmType, Long domainId, String hostTag) {
+        this(name,
+            cpu,
+            ramSize,
+            speed,
+            rateMbps,
+            multicastRateMbps,
+            offerHA,
+            limitResourceUse,
+            volatileVm,
+            displayText,
+            provisioningType,
+            useLocalStorage,
+            recreatable,
+            tags,
+            systemUse,
+            vmType,
+            domainId);
+        this.hostTag = hostTag;
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
+            boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
+            VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
+        this(name,
+            cpu,
+            ramSize,
+            speed,
+            rateMbps,
+            multicastRateMbps,
+            offerHA,
+            limitResourceUse,
+            volatileVm,
+            displayText,
+            provisioningType,
+            useLocalStorage,
+            recreatable,
+            tags,
+            systemUse,
+            vmType,
+            domainId,
+            hostTag);
+        this.deploymentPlanner = deploymentPlanner;
+    }
+
+    public ServiceOfferingVO(ServiceOfferingVO offering) {
+        super(offering.getId(),
+            offering.getName(),
+            offering.getDisplayText(),
+            offering.getProvisioningType(),
+            false,
+            offering.getTags(),
+            offering.isRecreatable(),
+            offering.isUseLocalStorage(),
+            offering.isSystemUse(),
+            true,
+            offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(),
+            offering.getDomainId(),
+            offering.getMinIops(),
+            offering.getMaxIops());
+        cpu = offering.getCpu();
+        ramSize = offering.getRamSize();
+        speed = offering.getSpeed();
+        rateMbps = offering.getRateMbps();
+        multicastRateMbps = offering.getMulticastRateMbps();
+        offerHA = offering.isOfferHA();
+        limitCpuUse = offering.getLimitCpuUse();
+        volatileVm = offering.isVolatileVm();
+        hostTag = offering.getHostTag();
+        vmType = offering.getSystemVmType();
+    }
+
+    @Override
+    public boolean isOfferHA() {
+        return offerHA;
+    }
+
+    public void setOfferHA(boolean offerHA) {
+        this.offerHA = offerHA;
+    }
+
+    @Override
+    public boolean getLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public void setLimitResourceUse(boolean limitCpuUse) {
+        this.limitCpuUse = limitCpuUse;
+    }
+
+    @Override
+    public boolean getDefaultUse() {
+        return defaultUse;
+    }
+
+    @Override
+    @Transient
+    public String[] getTagsArray() {
+        String tags = getTags();
+        if (tags == null || tags.length() == 0) {
+            return new String[0];
+        }
+
+        return tags.split(",");
+    }
+
+    @Override
+    public Integer getCpu() {
+        return cpu;
+    }
+
+    public void setCpu(int cpu) {
+        this.cpu = cpu;
+    }
+
+    public void setSpeed(int speed) {
+        this.speed = speed;
+    }
+
+    public void setRamSize(int ramSize) {
+        this.ramSize = ramSize;
+    }
+
+    @Override
+    public Integer getSpeed() {
+        return speed;
+    }
+
+    @Override
+    public Integer getRamSize() {
+        return ramSize;
+    }
+
+    public void setRateMbps(Integer rateMbps) {
+        this.rateMbps = rateMbps;
+    }
+
+    @Override
+    public Integer getRateMbps() {
+        return rateMbps;
+    }
+
+    public void setMulticastRateMbps(Integer multicastRateMbps) {
+        this.multicastRateMbps = multicastRateMbps;
+    }
+
+    @Override
+    public Integer getMulticastRateMbps() {
+        return multicastRateMbps;
+    }
+
+    public void setHostTag(String hostTag) {
+        this.hostTag = hostTag;
+    }
+
+    @Override
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    @Override
+    public String getSystemVmType() {
+        return vmType;
+    }
+
+    @Override
+    public void setSortKey(int key) {
+        sortKey = key;
+    }
+
+    @Override
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    @Override
+    public boolean isVolatileVm() {
+        return volatileVm;
+    }
+
+    @Override
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    public String getDetail(String name) {
+        return details != null ? details.get(name) : null ;
+    }
+
+    public void setDetail(String name, String value) {
+        assert (details != null) : "Did you forget to load the details?";
+
+        details.put(name, value);
+    }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
+    }
+
+    @Override
+    public boolean isDynamic() {
+        return cpu == null || speed == null || ramSize == null || isDynamic;
+    }
+
+    public void setDynamicFlag(boolean isdynamic) {
+        isDynamic = isdynamic;
+    }
+}
diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/service/dao/ServiceOfferingDao.java
rename to engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDao.java
diff --git a/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDaoImpl.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDaoImpl.java
new file mode 100644
index 0000000..81ecc67
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDaoImpl.java
@@ -0,0 +1,292 @@
+// 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.service.dao;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.persistence.EntityExistsException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.event.UsageEventVO;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.UserVmDetailsDao;
+
+@Component
+@DB()
+public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Long> implements ServiceOfferingDao {
+    protected static final Logger s_logger = Logger.getLogger(ServiceOfferingDaoImpl.class);
+
+    @Inject
+    protected ServiceOfferingDetailsDao detailsDao;
+    @Inject
+    protected UserVmDetailsDao userVmDetailsDao;
+
+    protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
+    protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByDomainIdSearch;
+    protected final SearchBuilder<ServiceOfferingVO> SystemServiceOffering;
+    protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
+    protected final SearchBuilder<ServiceOfferingVO> PublicServiceOfferingSearch;
+
+    public ServiceOfferingDaoImpl() {
+        super();
+
+        UniqueNameSearch = createSearchBuilder();
+        UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
+        UniqueNameSearch.and("system", UniqueNameSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
+        UniqueNameSearch.done();
+
+        ServiceOfferingsByDomainIdSearch = createSearchBuilder();
+        ServiceOfferingsByDomainIdSearch.and("domainId", ServiceOfferingsByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
+        ServiceOfferingsByDomainIdSearch.done();
+
+        SystemServiceOffering = createSearchBuilder();
+        SystemServiceOffering.and("domainId", SystemServiceOffering.entity().getDomainId(), SearchCriteria.Op.EQ);
+        SystemServiceOffering.and("system", SystemServiceOffering.entity().isSystemUse(), SearchCriteria.Op.EQ);
+        SystemServiceOffering.and("vm_type", SystemServiceOffering.entity().getSpeed(), SearchCriteria.Op.EQ);
+        SystemServiceOffering.and("removed", SystemServiceOffering.entity().getRemoved(), SearchCriteria.Op.NULL);
+        SystemServiceOffering.done();
+
+        PublicServiceOfferingSearch = createSearchBuilder();
+        PublicServiceOfferingSearch.and("domainId", PublicServiceOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
+        PublicServiceOfferingSearch.and("system", PublicServiceOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
+        PublicServiceOfferingSearch.and("removed", PublicServiceOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        PublicServiceOfferingSearch.done();
+
+        ServiceOfferingsByKeywordSearch = createSearchBuilder();
+        ServiceOfferingsByKeywordSearch.or("name", ServiceOfferingsByKeywordSearch.entity().getName(), SearchCriteria.Op.EQ);
+        ServiceOfferingsByKeywordSearch.or("displayText", ServiceOfferingsByKeywordSearch.entity().getDisplayText(), SearchCriteria.Op.EQ);
+        ServiceOfferingsByKeywordSearch.done();
+    }
+
+    @Override
+    public ServiceOfferingVO findByName(String name) {
+        SearchCriteria<ServiceOfferingVO> sc = UniqueNameSearch.create();
+        sc.setParameters("name", name);
+        sc.setParameters("system", true);
+        List<ServiceOfferingVO> vos = search(sc, null, null, false);
+        if (vos.size() == 0) {
+            return null;
+        }
+
+        return vos.get(0);
+    }
+
+    @Override
+    @DB
+    public ServiceOfferingVO persistSystemServiceOffering(ServiceOfferingVO offering) {
+        assert offering.getUniqueName() != null : "how are you going to find this later if you don't set it?";
+        ServiceOfferingVO vo = findByName(offering.getUniqueName());
+        if (vo != null) {
+            // check invalid CPU speed in system service offering, set it to default value of 500 Mhz if 0 CPU speed is found
+            if (vo.getSpeed() <= 0) {
+                vo.setSpeed(500);
+                update(vo.getId(), vo);
+            }
+            if (!vo.getUniqueName().endsWith("-Local")) {
+                if (vo.isUseLocalStorage()) {
+                    vo.setUniqueName(vo.getUniqueName() + "-Local");
+                    vo.setName(vo.getName() + " - Local Storage");
+                    update(vo.getId(), vo);
+                }
+            }
+            return vo;
+        }
+        try {
+            return persist(offering);
+        } catch (EntityExistsException e) {
+            // Assume it's conflict on unique name
+            return findByName(offering.getUniqueName());
+        }
+    }
+
+    @Override
+    public List<ServiceOfferingVO> findServiceOfferingByDomainId(Long domainId) {
+        SearchCriteria<ServiceOfferingVO> sc = ServiceOfferingsByDomainIdSearch.create();
+        sc.setParameters("domainId", domainId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<ServiceOfferingVO> findSystemOffering(Long domainId, Boolean isSystem, String vmType) {
+        SearchCriteria<ServiceOfferingVO> sc = SystemServiceOffering.create();
+        sc.setParameters("domainId", domainId);
+        sc.setParameters("system", isSystem);
+        sc.setParameters("vm_type", vmType);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<ServiceOfferingVO> findPublicServiceOfferings() {
+        SearchCriteria<ServiceOfferingVO> sc = PublicServiceOfferingSearch.create();
+        sc.setParameters("system", false);
+        return listBy(sc);
+    }
+
+    @Override
+    @DB
+    public ServiceOfferingVO persistDeafultServiceOffering(ServiceOfferingVO offering) {
+        assert offering.getUniqueName() != null : "unique name should be set for the service offering";
+        ServiceOfferingVO vo = findByName(offering.getUniqueName());
+        if (vo != null) {
+            return vo;
+        }
+        try {
+            return persist(offering);
+        } catch (EntityExistsException e) {
+            // Assume it's conflict on unique name
+            return findByName(offering.getUniqueName());
+        }
+    }
+
+    @Override
+    public boolean remove(Long id) {
+        ServiceOfferingVO offering = createForUpdate();
+        offering.setRemoved(new Date());
+
+        return update(id, offering);
+    }
+
+    @Override
+    public void loadDetails(ServiceOfferingVO serviceOffering) {
+        Map<String, String> details = detailsDao.listDetailsKeyPairs(serviceOffering.getId());
+        serviceOffering.setDetails(details);
+    }
+
+    @Override
+    public void saveDetails(ServiceOfferingVO serviceOffering) {
+        Map<String, String> details = serviceOffering.getDetails();
+        if (details == null) {
+            return;
+        }
+
+        List<ServiceOfferingDetailsVO> resourceDetails = new ArrayList<ServiceOfferingDetailsVO>();
+        for (String key : details.keySet()) {
+            resourceDetails.add(new ServiceOfferingDetailsVO(serviceOffering.getId(), key, details.get(key), true));
+        }
+
+        detailsDao.saveDetails(resourceDetails);
+    }
+
+    @Override
+    public ServiceOfferingVO findById(Long vmId, long serviceOfferingId) {
+        ServiceOfferingVO offering = super.findById(serviceOfferingId);
+        if (offering.isDynamic()) {
+            offering.setDynamicFlag(true);
+            if (vmId == null) {
+                throw new CloudRuntimeException("missing argument vmId");
+            }
+            Map<String, String> dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId);
+            return getcomputeOffering(offering, dynamicOffering);
+        }
+        return offering;
+    }
+
+    @Override
+    public ServiceOfferingVO findByIdIncludingRemoved(Long vmId, long serviceOfferingId) {
+        ServiceOfferingVO offering = super.findByIdIncludingRemoved(serviceOfferingId);
+        if (offering.isDynamic()) {
+            offering.setDynamicFlag(true);
+            if (vmId == null) {
+                throw new CloudRuntimeException("missing argument vmId");
+            }
+            Map<String, String> dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId);
+            return getcomputeOffering(offering, dynamicOffering);
+        }
+        return offering;
+    }
+
+    @Override
+    public boolean isDynamic(long serviceOfferingId) {
+        ServiceOfferingVO offering = super.findById(serviceOfferingId);
+        return offering.getCpu() == null || offering.getSpeed() == null || offering.getRamSize() == null;
+    }
+
+    @Override
+    public ServiceOfferingVO getcomputeOffering(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
+        ServiceOfferingVO dummyoffering = new ServiceOfferingVO(serviceOffering);
+        dummyoffering.setDynamicFlag(true);
+        if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
+            dummyoffering.setCpu(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name())));
+        }
+        if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
+            dummyoffering.setSpeed(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name())));
+        }
+        if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
+            dummyoffering.setRamSize(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name())));
+        }
+
+        return dummyoffering;
+    }
+
+    @Override
+    public List<ServiceOfferingVO> createSystemServiceOfferings(String name, String uniqueName, int cpuCount, int ramSize, int cpuSpeed,
+            Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, ProvisioningType provisioningType,
+            boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
+        List<ServiceOfferingVO> list = new ArrayList<ServiceOfferingVO>();
+        ServiceOfferingVO offering = new ServiceOfferingVO(name, cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
+                provisioningType, false, recreatable, tags, systemUse, vmType, defaultUse);
+        offering.setUniqueName(uniqueName);
+        offering = persistSystemServiceOffering(offering);
+        if (offering != null) {
+            list.add(offering);
+        }
+
+        boolean useLocal = true;
+        if (offering.isUseLocalStorage()) { // if 1st one is already local then 2nd needs to be shared
+            useLocal = false;
+        }
+
+        offering = new ServiceOfferingVO(name + (useLocal ? " - Local Storage" : ""), cpuCount, ramSize, cpuSpeed, rateMbps, multicastRateMbps, offerHA, displayText,
+                provisioningType, useLocal, recreatable, tags, systemUse, vmType, defaultUse);
+        offering.setUniqueName(uniqueName + (useLocal ? "-Local" : ""));
+        offering = persistSystemServiceOffering(offering);
+        if (offering != null) {
+            list.add(offering);
+        }
+
+        return list;
+    }
+
+    @Override
+    public ServiceOfferingVO findDefaultSystemOffering(String offeringName, Boolean useLocalStorage) {
+        String name = offeringName;
+        if (useLocalStorage != null && useLocalStorage.booleanValue()) {
+            name += "-Local";
+        }
+        ServiceOfferingVO serviceOffering = findByName(name);
+        if (serviceOffering == null) {
+            String message = "System service offering " + name + " not found";
+            s_logger.error(message);
+            throw new CloudRuntimeException(message);
+        }
+        return serviceOffering;
+    }
+}
diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDao.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java
diff --git a/engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java
new file mode 100644
index 0000000..e8e91ea
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/DiskOfferingVO.java
@@ -0,0 +1,625 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import com.cloud.offering.DiskOffering;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "disk_offering")
+@Inheritance(strategy = InheritanceType.JOINED)
+@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32)
+public class DiskOfferingVO implements DiskOffering {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "domain_id")
+    Long domainId;
+
+    @Column(name = "unique_name")
+    private String uniqueName;
+
+    @Column(name = "name")
+    private String name = null;
+
+    @Column(name = "display_text", length = 4096)
+    private String displayText = null;
+
+    @Column(name = "disk_size")
+    long diskSize;
+
+    @Column(name = "tags", length = 4096)
+    String tags;
+
+    @Column(name = "type")
+    Type type;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name = "recreatable")
+    private boolean recreatable;
+
+    @Column(name = "use_local_storage")
+    private boolean useLocalStorage;
+
+    @Column(name = "system_use")
+    private boolean systemUse;
+
+    @Column(name = "customized")
+    private boolean customized;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "customized_iops")
+    private Boolean customizedIops;
+
+    @Column(name = "min_iops")
+    private Long minIops;
+
+    @Column(name = "max_iops")
+    private Long maxIops;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "bytes_read_rate")
+    private Long bytesReadRate;
+
+    @Column(name = "bytes_read_rate_max")
+    private Long bytesReadRateMax;
+
+    @Column(name = "bytes_read_rate_max_length")
+    private Long bytesReadRateMaxLength;
+
+    @Column(name = "bytes_write_rate")
+    private Long bytesWriteRate;
+
+    @Column(name = "bytes_write_rate_max")
+    private Long bytesWriteRateMax;
+
+    @Column(name = "bytes_write_rate_max_length")
+    private Long bytesWriteRateMaxLength;
+
+    @Column(name = "iops_read_rate")
+    private Long iopsReadRate;
+
+    @Column(name = "iops_read_rate_max")
+    private Long iopsReadRateMax;
+
+    @Column(name = "iops_read_rate_max_length")
+    private Long iopsReadRateMaxLength;
+
+    @Column(name = "iops_write_rate")
+    private Long iopsWriteRate;
+
+    @Column(name = "iops_write_rate_max")
+    private Long iopsWriteRateMax;
+
+    @Column(name = "iops_write_rate_max_length")
+    private Long iopsWriteRateMaxLength;
+
+
+    @Column(name = "cache_mode", updatable = true, nullable = false)
+    @Enumerated(value = EnumType.STRING)
+    private DiskCacheMode cacheMode;
+
+    @Column(name = "provisioning_type")
+    Storage.ProvisioningType provisioningType;
+
+    @Column(name = "display_offering")
+    boolean displayOffering = true;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "state")
+    State state;
+
+    @Column(name = "hv_ss_reserve")
+    Integer hypervisorSnapshotReserve;
+
+    public DiskOfferingVO() {
+        uuid = UUID.randomUUID().toString();
+    }
+
+    public DiskOfferingVO(Long domainId, String name, String displayText, Storage.ProvisioningType provisioningType, long diskSize, String tags, boolean isCustomized, Boolean isCustomizedIops,
+            Long minIops, Long maxIops, DiskCacheMode cacheMode) {
+        this.domainId = domainId;
+        this.name = name;
+        this.displayText = displayText;
+        this.provisioningType = provisioningType;
+        this.diskSize = diskSize;
+        this.tags = tags;
+        recreatable = false;
+        type = Type.Disk;
+        useLocalStorage = false;
+        customized = isCustomized;
+        uuid = UUID.randomUUID().toString();
+        customizedIops = isCustomizedIops;
+        this.minIops = minIops;
+        this.maxIops = maxIops;
+        this.cacheMode = cacheMode;
+    }
+
+    public DiskOfferingVO(Long domainId, String name, String displayText, Storage.ProvisioningType provisioningType, long diskSize, String tags, boolean isCustomized, Boolean isCustomizedIops,
+            Long minIops, Long maxIops) {
+        this.domainId = domainId;
+        this.name = name;
+        this.displayText = displayText;
+        this.provisioningType = provisioningType;
+        this.diskSize = diskSize;
+        this.tags = tags;
+        recreatable = false;
+        type = Type.Disk;
+        useLocalStorage = false;
+        customized = isCustomized;
+        uuid = UUID.randomUUID().toString();
+        customizedIops = isCustomizedIops;
+        this.minIops = minIops;
+        this.maxIops = maxIops;
+        state = State.Active;
+    }
+
+    public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse,
+            boolean customized) {
+        domainId = null;
+        type = Type.Service;
+        this.name = name;
+        this.displayText = displayText;
+        this.provisioningType = provisioningType;
+        this.tags = tags;
+        this.recreatable = recreatable;
+        this.useLocalStorage = useLocalStorage;
+        this.systemUse = systemUse;
+        this.customized = customized;
+        uuid = UUID.randomUUID().toString();
+        state = State.Active;
+    }
+
+    // domain specific offerings constructor (null domainId implies public
+    // offering)
+    public DiskOfferingVO(String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse,
+            boolean customized, Long domainId) {
+        type = Type.Service;
+        this.name = name;
+        this.displayText = displayText;
+        this.provisioningType = provisioningType;
+        this.tags = tags;
+        this.recreatable = recreatable;
+        this.useLocalStorage = useLocalStorage;
+        this.systemUse = systemUse;
+        this.customized = customized;
+        this.domainId = domainId;
+        uuid = UUID.randomUUID().toString();
+        state = State.Active;
+    }
+
+    public DiskOfferingVO(long id, String name, String displayText, Storage.ProvisioningType provisioningType, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage,
+            boolean systemUse, boolean customized, boolean customizedIops, Long domainId, Long minIops, Long maxIops) {
+        this.id = id;
+        type = Type.Service;
+        this.name = name;
+        this.displayText = displayText;
+        this.provisioningType = provisioningType;
+        this.tags = tags;
+        this.recreatable = recreatable;
+        this.useLocalStorage = useLocalStorage;
+        this.systemUse = systemUse;
+        this.customized = customized;
+        this.customizedIops = customizedIops;
+        this.domainId = domainId;
+        uuid = UUID.randomUUID().toString();
+        state = State.Active;
+        this.minIops = minIops;
+        this.maxIops = maxIops;
+    }
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public boolean isCustomized() {
+        return customized;
+    }
+
+    public void setCustomized(boolean customized) {
+        this.customized = customized;
+    }
+
+    @Override
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    @Override
+    public void setCustomizedIops(Boolean customizedIops) {
+        this.customizedIops = customizedIops;
+    }
+
+    @Override
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    @Override
+    public void setMinIops(Long minIops) {
+        this.minIops = minIops;
+    }
+
+    @Override
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    @Override
+    public void setMaxIops(Long maxIops) {
+        this.maxIops = maxIops;
+    }
+
+    @Override
+    public DiskCacheMode getCacheMode() {
+        return cacheMode;
+    }
+
+    @Override
+    public void setCacheMode(DiskCacheMode cacheMode) {
+        this.cacheMode = cacheMode;
+    }
+
+    @Override
+    public String getUniqueName() {
+        return uniqueName;
+    }
+
+    @Override
+    public boolean isUseLocalStorage() {
+        return useLocalStorage;
+    }
+
+    @Override
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    @Override
+    public boolean isRecreatable() {
+        return recreatable;
+    }
+
+    public void setDomainId(Long domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean isSystemUse() {
+        return systemUse;
+    }
+
+    public void setSystemUse(boolean systemUse) {
+        this.systemUse = systemUse;
+    }
+
+    @Override
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    @Override
+    public Storage.ProvisioningType getProvisioningType() {
+        return provisioningType;
+    }
+
+    @Override
+    public long getDiskSize() {
+        return diskSize;
+    }
+
+    @Override
+    public void setDiskSize(long diskSize) {
+        this.diskSize = diskSize;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    protected void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    @Override
+    public String getTags() {
+        return tags;
+    }
+
+    public void setUniqueName(String name) {
+        uniqueName = name;
+    }
+
+    @Override
+    @Transient
+    public String[] getTagsArray() {
+        String tags = getTags();
+        if (tags == null || tags.isEmpty()) {
+            return new String[0];
+        }
+
+        return tags.split(",");
+    }
+
+    @Transient
+    public boolean containsTag(String... tags) {
+        if (this.tags == null) {
+            return false;
+        }
+
+        for (String tag : tags) {
+            if (!this.tags.matches(tag)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Transient
+    public void setTagsArray(List<String> newTags) {
+        if (newTags.isEmpty()) {
+            setTags(null);
+            return;
+        }
+
+        StringBuilder buf = new StringBuilder();
+        for (String tag : newTags) {
+            buf.append(tag).append(",");
+        }
+
+        buf.delete(buf.length() - 1, buf.length());
+
+        setTags(buf.toString());
+    }
+
+    public void setUseLocalStorage(boolean useLocalStorage) {
+        this.useLocalStorage = useLocalStorage;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setSortKey(int key) {
+        sortKey = key;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public void setRecreatable(boolean recreatable) {
+        this.recreatable = recreatable;
+    }
+
+    public boolean getDisplayOffering() {
+        return displayOffering;
+    }
+
+    public void setDisplayOffering(boolean displayOffering) {
+        this.displayOffering = displayOffering;
+    }
+
+    @Override
+    public void setBytesReadRate(Long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    @Override
+    public Long getBytesReadRate() { return bytesReadRate; }
+
+
+
+    @Override
+    public void setBytesWriteRate(Long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    @Override
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    @Override
+    public Long getBytesWriteRateMax() {
+        return bytesWriteRateMax;
+    }
+
+    public void setBytesWriteRateMax(Long bytesWriteRateMax) {
+        this.bytesWriteRateMax = bytesWriteRateMax;
+    }
+
+    @Override
+    public Long getBytesWriteRateMaxLength() {
+        return bytesWriteRateMaxLength;
+    }
+
+    public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) {
+        this.bytesWriteRateMaxLength = bytesWriteRateMaxLength;
+    }
+
+    @Override
+    public Long getBytesReadRateMax() {
+        return bytesReadRateMax;
+    }
+
+    @Override
+    public void setBytesReadRateMax(Long bytesReadRateMax) {
+        this.bytesReadRateMax = bytesReadRateMax;
+    }
+
+    @Override
+    public Long getBytesReadRateMaxLength() {
+        return bytesReadRateMaxLength;
+    }
+
+    @Override
+    public void setBytesReadRateMaxLength(Long bytesReadRateMaxLength) {
+        this.bytesReadRateMaxLength = bytesReadRateMaxLength;
+    }
+
+    @Override
+    public void setIopsReadRate(Long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    @Override
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    @Override
+    public Long getIopsReadRateMax() {
+        return iopsReadRateMax;
+    }
+
+    @Override
+    public void setIopsReadRateMax(Long iopsReadRateMax) {
+        this.iopsReadRateMax = iopsReadRateMax;
+    }
+
+    @Override
+    public Long getIopsReadRateMaxLength() {
+        return iopsReadRateMaxLength;
+    }
+
+    @Override
+    public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) {
+        this.iopsReadRateMaxLength = iopsReadRateMaxLength;
+    }
+
+    @Override
+    public void setIopsWriteRate(Long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    @Override
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    @Override
+    public Long getIopsWriteRateMax() {
+        return iopsWriteRateMax;
+    }
+
+    @Override
+    public void setIopsWriteRateMax(Long iopsWriteRateMax) {
+        this.iopsWriteRateMax = iopsWriteRateMax;
+    }
+
+    @Override
+    public Long getIopsWriteRateMaxLength() {
+        return iopsWriteRateMaxLength;
+    }
+
+    @Override
+    public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) {
+        this.iopsWriteRateMaxLength = iopsWriteRateMaxLength;
+    }
+
+    @Override
+    public void setHypervisorSnapshotReserve(Integer hypervisorSnapshotReserve) {
+        this.hypervisorSnapshotReserve = hypervisorSnapshotReserve;
+    }
+
+    @Override
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    public boolean isShared() {
+        return !useLocalStorage;
+    }
+}
diff --git a/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java b/engine/schema/src/main/java/com/cloud/storage/GuestOSCategoryVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java
rename to engine/schema/src/main/java/com/cloud/storage/GuestOSCategoryVO.java
diff --git a/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java b/engine/schema/src/main/java/com/cloud/storage/GuestOSHypervisorVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java
rename to engine/schema/src/main/java/com/cloud/storage/GuestOSHypervisorVO.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/GuestOSVO.java b/engine/schema/src/main/java/com/cloud/storage/GuestOSVO.java
new file mode 100644
index 0000000..1afea4e
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/GuestOSVO.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "guest_os")
+public class GuestOSVO implements GuestOS {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "category_id")
+    private long categoryId;
+
+    @Column(name = "name")
+    String name;
+
+    @Column(name = "display_name")
+    String displayName;
+
+    @Column(name = "uuid")
+    String uuid = UUID.randomUUID().toString();
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name = "is_user_defined")
+    private boolean isUserDefined;
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public long getCategoryId() {
+        return categoryId;
+    }
+
+    public void setCategoryId(long categoryId) {
+        this.categoryId = categoryId;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    @Override
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public boolean isUserDefined() {
+        return isUserDefined;
+    }
+
+    public void setIsUserDefined(boolean isUserDefined) {
+        this.isUserDefined = isUserDefined;
+    }
+}
diff --git a/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java b/engine/schema/src/main/java/com/cloud/storage/LaunchPermissionVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/LaunchPermissionVO.java
rename to engine/schema/src/main/java/com/cloud/storage/LaunchPermissionVO.java
diff --git a/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java b/engine/schema/src/main/java/com/cloud/storage/SnapshotPolicyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java
rename to engine/schema/src/main/java/com/cloud/storage/SnapshotPolicyVO.java
diff --git a/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java b/engine/schema/src/main/java/com/cloud/storage/SnapshotScheduleVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java
rename to engine/schema/src/main/java/com/cloud/storage/SnapshotScheduleVO.java
diff --git a/engine/schema/src/com/cloud/storage/SnapshotVO.java b/engine/schema/src/main/java/com/cloud/storage/SnapshotVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/SnapshotVO.java
rename to engine/schema/src/main/java/com/cloud/storage/SnapshotVO.java
diff --git a/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java b/engine/schema/src/main/java/com/cloud/storage/StoragePoolHostAssoc.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java
rename to engine/schema/src/main/java/com/cloud/storage/StoragePoolHostAssoc.java
diff --git a/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java b/engine/schema/src/main/java/com/cloud/storage/StoragePoolHostVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/StoragePoolHostVO.java
rename to engine/schema/src/main/java/com/cloud/storage/StoragePoolHostVO.java
diff --git a/engine/schema/src/com/cloud/storage/StoragePoolTagVO.java b/engine/schema/src/main/java/com/cloud/storage/StoragePoolTagVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/StoragePoolTagVO.java
rename to engine/schema/src/main/java/com/cloud/storage/StoragePoolTagVO.java
diff --git a/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java b/engine/schema/src/main/java/com/cloud/storage/StoragePoolWorkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java
rename to engine/schema/src/main/java/com/cloud/storage/StoragePoolWorkVO.java
diff --git a/engine/schema/src/com/cloud/storage/UploadVO.java b/engine/schema/src/main/java/com/cloud/storage/UploadVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/UploadVO.java
rename to engine/schema/src/main/java/com/cloud/storage/UploadVO.java
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateHostVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VMTemplateHostVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VMTemplateHostVO.java
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java
new file mode 100644
index 0000000..30440d3
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java
@@ -0,0 +1,633 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "vm_template")
+public class VMTemplateVO implements VirtualMachineTemplate {
+    @Id
+    @TableGenerator(name = "vm_template_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_template_seq", allocationSize = 1)
+    @Column(name = "id", nullable = false)
+    private long id;
+
+    @Column(name = "format")
+    private Storage.ImageFormat format;
+
+    @Column(name = "unique_name")
+    private String uniqueName;
+
+    @Column(name = "name")
+    private String name = null;
+
+    @Column(name = "public")
+    private boolean publicTemplate = true;
+
+    @Column(name = "featured")
+    private boolean featured;
+
+    @Column(name = "type")
+    private Storage.TemplateType templateType;
+
+    @Column(name = "url", length = 2048)
+    private String url = null;
+
+    @Column(name = "hvm")
+    private boolean requiresHvm;
+
+    @Column(name = "bits")
+    private int bits;
+
+    @Temporal(value = TemporalType.TIMESTAMP)
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created = null;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date removed;
+
+    @Column(name = "account_id")
+    private long accountId;
+
+    @Column(name = "checksum")
+    private String checksum;
+
+    @Column(name = "display_text", length = 4096)
+    private String displayText;
+
+    @Column(name = "enable_password")
+    private boolean enablePassword;
+
+    @Column(name = "guest_os_id")
+    private long guestOSId;
+
+    @Column(name = "bootable")
+    private boolean bootable = true;
+
+    @Column(name = "prepopulate")
+    private boolean prepopulate = false;
+
+    @Column(name = "cross_zones")
+    private boolean crossZones = false;
+
+    @Column(name = "hypervisor_type")
+    @Enumerated(value = EnumType.STRING)
+    private HypervisorType hypervisorType;
+
+    @Column(name = "extractable")
+    private boolean extractable = true;
+
+    @Column(name = "source_template_id")
+    private Long sourceTemplateId;
+
+    @Column(name = "state")
+    @Enumerated(EnumType.STRING)
+    private State state;
+
+    @Column(name = "template_tag")
+    private String templateTag;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "sort_key")
+    private int sortKey;
+
+    @Column(name = "enable_sshkey")
+    private boolean enableSshKey;
+
+    @Column(name = "size")
+    private Long size;
+
+    @Column(name = "update_count", updatable = true)
+    protected long updatedCount;
+
+    @Column(name = "updated")
+    @Temporal(value = TemporalType.TIMESTAMP)
+    Date updated;
+
+    @Transient
+    Map<String, String> details;
+
+    @Column(name = "dynamically_scalable")
+    protected boolean dynamicallyScalable;
+
+    @Column(name = "direct_download")
+    private boolean directDownload;
+
+    @Column(name = "parent_template_id")
+    private Long parentTemplateId;
+
+    @Override
+    public String getUniqueName() {
+        return uniqueName;
+    }
+
+    public void setUniqueName(String uniqueName) {
+        this.uniqueName = uniqueName;
+    }
+
+    public VMTemplateVO() {
+        uuid = UUID.randomUUID().toString();
+    }
+
+    //FIXME - Remove unwanted constructors.
+    private VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url,
+            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
+            HypervisorType hyperType, Map<String, String> details) {
+        this(id,
+            generateUniqueName(id, accountId, name),
+            name,
+            format,
+            isPublic,
+            featured,
+            isExtractable,
+            type,
+            url,
+            null,
+            requiresHvm,
+            bits,
+            accountId,
+            cksum,
+            displayText,
+            enablePassword,
+            guestOSId,
+            bootable,
+            hyperType,
+            details);
+        uuid = UUID.randomUUID().toString();
+    }
+
+    public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url,
+            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
+            HypervisorType hyperType, String templateTag, Map<String, String> details, boolean sshKeyEnabled, boolean isDynamicallyScalable, boolean directDownload) {
+        this(id,
+            name,
+            format,
+            isPublic,
+            featured,
+            isExtractable,
+            type,
+            url,
+            requiresHvm,
+            bits,
+            accountId,
+            cksum,
+            displayText,
+            enablePassword,
+            guestOSId,
+            bootable,
+            hyperType,
+            details);
+        this.templateTag = templateTag;
+        uuid = UUID.randomUUID().toString();
+        enableSshKey = sshKeyEnabled;
+        dynamicallyScalable = isDynamicallyScalable;
+        state = State.Active;
+        this.directDownload = directDownload;
+    }
+
+    public static VMTemplateVO createPreHostIso(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type,
+        String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId,
+        boolean bootable, HypervisorType hyperType) {
+        VMTemplateVO template =
+            new VMTemplateVO(id, uniqueName, name, format, isPublic, featured, type, url, created, requiresHvm, bits, accountId, cksum, displayText, enablePassword,
+                guestOSId, bootable, hyperType);
+        return template;
+    }
+
+    public VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type, String url, Date created,
+            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
+            HypervisorType hyperType) {
+        this.id = id;
+        this.name = name;
+        publicTemplate = isPublic;
+        this.featured = featured;
+        templateType = type;
+        this.url = url;
+        this.requiresHvm = requiresHvm;
+        this.bits = bits;
+        this.accountId = accountId;
+        checksum = cksum;
+        this.uniqueName = uniqueName;
+        this.displayText = displayText;
+        this.enablePassword = enablePassword;
+        this.format = format;
+        this.created = created;
+        this.guestOSId = guestOSId;
+        this.bootable = bootable;
+        hypervisorType = hyperType;
+        uuid = UUID.randomUUID().toString();
+        state = State.Active;
+    }
+
+    //FIXME - Remove unwanted constructors. Made them private for now
+    private VMTemplateVO(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type,
+            String url, Date created, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId,
+            boolean bootable, HypervisorType hyperType, Map<String, String> details) {
+        this(id,
+            uniqueName,
+            name,
+            format,
+            isPublic,
+            featured,
+            type,
+            url,
+            created,
+            requiresHvm,
+            bits,
+            accountId,
+            cksum,
+            displayText,
+            enablePassword,
+            guestOSId,
+            bootable,
+            hyperType);
+        extractable = isExtractable;
+        uuid = UUID.randomUUID().toString();
+        this.details = details;
+        state = State.Active;
+    }
+
+    @Override
+    public boolean isEnablePassword() {
+        return enablePassword;
+    }
+
+    @Override
+    public Storage.ImageFormat getFormat() {
+        return format;
+    }
+
+    public void setEnablePassword(boolean enablePassword) {
+        this.enablePassword = enablePassword;
+    }
+
+    public void setFormat(ImageFormat format) {
+        this.format = format;
+    }
+
+    private static String generateUniqueName(long id, long userId, String displayName) {
+        StringBuilder name = new StringBuilder();
+        name.append(id);
+        name.append("-");
+        name.append(userId);
+        name.append("-");
+        name.append(UUID.nameUUIDFromBytes((displayName + System.currentTimeMillis()).getBytes()).toString());
+        return name.toString();
+    }
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public TemplateType getTemplateType() {
+        return templateType;
+    }
+
+    public void setTemplateType(TemplateType type) {
+        templateType = type;
+    }
+
+    public boolean requiresHvm() {
+        return requiresHvm;
+    }
+
+    @Override
+    public int getBits() {
+        return bits;
+    }
+
+    public void setBits(int bits) {
+        this.bits = bits;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public boolean isPublicTemplate() {
+        return publicTemplate;
+    }
+
+    public void setPublicTemplate(boolean publicTemplate) {
+        this.publicTemplate = publicTemplate;
+    }
+
+    @Override
+    public boolean isFeatured() {
+        return featured;
+    }
+
+    public void setFeatured(boolean featured) {
+        this.featured = featured;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @Override
+    public boolean isRequiresHvm() {
+        return requiresHvm;
+    }
+
+    public void setRequiresHvm(boolean value) {
+        requiresHvm = value;
+    }
+
+    @Override
+    public long getAccountId() {
+        return accountId;
+    }
+
+    @Override
+    public String getChecksum() {
+        return checksum;
+    }
+
+    public void setChecksum(String checksum) {
+        this.checksum = checksum;
+    }
+
+    @Override
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String displayText) {
+        this.displayText = displayText;
+    }
+
+    @Override
+    public long getGuestOSId() {
+        return guestOSId;
+    }
+
+    public void setGuestOSId(long guestOSId) {
+        this.guestOSId = guestOSId;
+    }
+
+    @Override
+    public boolean isBootable() {
+        return bootable;
+    }
+
+    public void setBootable(boolean bootable) {
+        this.bootable = bootable;
+    }
+
+    public void setPrepopulate(boolean prepopulate) {
+        this.prepopulate = prepopulate;
+    }
+
+    public boolean isPrepopulate() {
+        return prepopulate;
+    }
+
+    public void setCrossZones(boolean crossZones) {
+        this.crossZones = crossZones;
+    }
+
+    @Override
+    public boolean isCrossZones() {
+        return crossZones;
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return hypervisorType;
+    }
+
+    public void setHypervisorType(HypervisorType hyperType) {
+        hypervisorType = hyperType;
+    }
+
+    @Override
+    public boolean isExtractable() {
+        return extractable;
+    }
+
+    public void setExtractable(boolean extractable) {
+        this.extractable = extractable;
+    }
+
+    @Override
+    public Long getSourceTemplateId() {
+        return sourceTemplateId;
+    }
+
+    public void setSourceTemplateId(Long sourceTemplateId) {
+        this.sourceTemplateId = sourceTemplateId;
+    }
+
+    @Override
+    public String getTemplateTag() {
+        return templateTag;
+    }
+
+    public void setTemplateTag(String templateTag) {
+        this.templateTag = templateTag;
+    }
+
+    @Override
+    public long getDomainId() {
+        return -1;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (!(that instanceof VMTemplateVO)) {
+            return false;
+        }
+        VMTemplateVO other = (VMTemplateVO)that;
+
+        return ((getUniqueName().equals(other.getUniqueName())));
+    }
+
+    @Override
+    public int hashCode() {
+        return uniqueName.hashCode();
+    }
+
+    @Transient
+    String toString;
+
+    @Override
+    public String toString() {
+        if (toString == null) {
+            toString = new StringBuilder("Tmpl[").append(id).append("-").append(format).append("-").append(uniqueName).toString();
+        }
+        return toString;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    public void setSortKey(int key) {
+        sortKey = key;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public void setDynamicallyScalable(boolean dynamicallyScalable) {
+        this.dynamicallyScalable = dynamicallyScalable;
+    }
+
+    @Override
+    public boolean isDynamicallyScalable() {
+        return dynamicallyScalable;
+    }
+
+    @Override
+    public boolean isEnableSshKey() {
+        return enableSshKey;
+    }
+
+    public void setEnableSshKey(boolean enable) {
+        enableSshKey = enable;
+    }
+
+    public void setSize(Long size) {
+        this.size = size;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        return updatedCount;
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        updatedCount++;
+    }
+
+    public void decrUpdatedCount() {
+        updatedCount--;
+    }
+
+    @Override
+    public Date getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(Date updated) {
+        this.updated = updated;
+    }
+
+    public boolean isDirectDownload() {
+        return directDownload;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return VirtualMachineTemplate.class;
+    }
+
+    @Override
+    public Long getParentTemplateId() {
+        return parentTemplateId;
+    }
+
+    public void setParentTemplateId(Long parentTemplateId) {
+        this.parentTemplateId = parentTemplateId;
+    }
+
+}
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateZoneVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateZoneVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VMTemplateZoneVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VMTemplateZoneVO.java
diff --git a/engine/schema/src/com/cloud/storage/VolumeDetailVO.java b/engine/schema/src/main/java/com/cloud/storage/VolumeDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VolumeDetailVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VolumeDetailVO.java
diff --git a/engine/schema/src/com/cloud/storage/VolumeHostVO.java b/engine/schema/src/main/java/com/cloud/storage/VolumeHostVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VolumeHostVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VolumeHostVO.java
diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/main/java/com/cloud/storage/VolumeVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/VolumeVO.java
rename to engine/schema/src/main/java/com/cloud/storage/VolumeVO.java
diff --git a/engine/schema/src/com/cloud/storage/dao/DiskOfferingDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/DiskOfferingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/DiskOfferingDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/DiskOfferingDao.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/DiskOfferingDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/DiskOfferingDaoImpl.java
new file mode 100644
index 0000000..2957b68
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/DiskOfferingDaoImpl.java
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.EntityExistsException;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.offering.DiskOffering.Type;
+import com.cloud.utils.db.Attribute;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> implements DiskOfferingDao {
+    private final SearchBuilder<DiskOfferingVO> DomainIdSearch;
+    private final SearchBuilder<DiskOfferingVO> PrivateDiskOfferingSearch;
+    private final SearchBuilder<DiskOfferingVO> PublicDiskOfferingSearch;
+    protected final SearchBuilder<DiskOfferingVO> UniqueNameSearch;
+    private final Attribute _typeAttr;
+
+    protected DiskOfferingDaoImpl() {
+        DomainIdSearch = createSearchBuilder();
+        DomainIdSearch.and("domainId", DomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
+        DomainIdSearch.and("removed", DomainIdSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        DomainIdSearch.done();
+
+        PrivateDiskOfferingSearch = createSearchBuilder();
+        PrivateDiskOfferingSearch.and("diskSize", PrivateDiskOfferingSearch.entity().getDiskSize(), SearchCriteria.Op.EQ);
+        PrivateDiskOfferingSearch.done();
+
+        PublicDiskOfferingSearch = createSearchBuilder();
+        PublicDiskOfferingSearch.and("domainId", PublicDiskOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL);
+        PublicDiskOfferingSearch.and("system", PublicDiskOfferingSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
+        PublicDiskOfferingSearch.and("removed", PublicDiskOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        PublicDiskOfferingSearch.done();
+
+        UniqueNameSearch = createSearchBuilder();
+        UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
+        UniqueNameSearch.done();
+
+        _typeAttr = _allAttributes.get("type");
+    }
+
+    @Override
+    public List<DiskOfferingVO> listByDomainId(long domainId) {
+        SearchCriteria<DiskOfferingVO> sc = DomainIdSearch.create();
+        sc.setParameters("domainId", domainId);
+        // FIXME: this should not be exact match, but instead should find all
+        // available disk offerings from parent domains
+        return listBy(sc);
+    }
+
+    @Override
+    public List<DiskOfferingVO> findPrivateDiskOffering() {
+        SearchCriteria<DiskOfferingVO> sc = PrivateDiskOfferingSearch.create();
+        sc.setParameters("diskSize", 0);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<DiskOfferingVO> searchIncludingRemoved(SearchCriteria<DiskOfferingVO> sc, final Filter filter, final Boolean lock, final boolean cache) {
+        sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
+        return super.searchIncludingRemoved(sc, filter, lock, cache);
+    }
+
+    @Override
+    public <K> List<K> customSearchIncludingRemoved(SearchCriteria<K> sc, final Filter filter) {
+        sc.addAnd(_typeAttr, Op.EQ, Type.Disk);
+        return super.customSearchIncludingRemoved(sc, filter);
+    }
+
+    @Override
+    protected List<DiskOfferingVO> executeList(final String sql, final Object... params) {
+        StringBuilder builder = new StringBuilder(sql);
+        int index = builder.indexOf("WHERE");
+        if (index == -1) {
+            builder.append(" WHERE type=?");
+        } else {
+            builder.insert(index + 6, "type=? ");
+        }
+
+        return super.executeList(sql, Type.Disk, params);
+    }
+
+    @Override
+    public List<DiskOfferingVO> findPublicDiskOfferings() {
+        SearchCriteria<DiskOfferingVO> sc = PublicDiskOfferingSearch.create();
+        sc.setParameters("system", false);
+        return listBy(sc);
+    }
+
+    @Override
+    public DiskOfferingVO findByUniqueName(String uniqueName) {
+        SearchCriteria<DiskOfferingVO> sc = UniqueNameSearch.create();
+        sc.setParameters("name", uniqueName);
+        List<DiskOfferingVO> vos = search(sc, null, null, false);
+        if (vos.size() == 0) {
+            return null;
+        }
+
+        return vos.get(0);
+    }
+
+    @Override
+    public DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering) {
+        assert offering.getUniqueName() != null : "unique name shouldn't be null for the disk offering";
+        DiskOfferingVO vo = findByUniqueName(offering.getUniqueName());
+        if (vo != null) {
+            return vo;
+        }
+        try {
+            return persist(offering);
+        } catch (EntityExistsException e) {
+            // Assume it's conflict on unique name
+            return findByUniqueName(offering.getUniqueName());
+        }
+    }
+
+    @Override
+    public boolean remove(Long id) {
+        DiskOfferingVO diskOffering = createForUpdate();
+        diskOffering.setRemoved(new Date());
+
+        return update(id, diskOffering);
+    }
+}
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/LaunchPermissionDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/LaunchPermissionDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/LaunchPermissionDaoImpl.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDao.java
new file mode 100755
index 0000000..93ba720
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDao.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 com.cloud.storage.dao;
+
+import java.util.List;
+
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Type;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+public interface SnapshotDao extends GenericDao<SnapshotVO, Long>, StateDao<Snapshot.State, Snapshot.Event, SnapshotVO> {
+    List<SnapshotVO> listByVolumeId(long volumeId);
+
+    List<SnapshotVO> listByVolumeId(Filter filter, long volumeId);
+
+    long getLastSnapshot(long volumeId, DataStoreRole role);
+
+    List<SnapshotVO> listByVolumeIdTypeNotDestroyed(long volumeId, Type type);
+
+    List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId);
+
+    List<SnapshotVO> listByVolumeIdVersion(long volumeId, String version);
+
+    public Long countSnapshotsForAccount(long accountId);
+
+    List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status);
+
+    List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status);
+
+    List<SnapshotVO> listAllByStatus(Snapshot.State... status);
+
+    void updateVolumeIds(long oldVolId, long newVolId);
+
+    List<SnapshotVO> listByStatusNotIn(long volumeId, Snapshot.State... status);
+
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDaoImpl.java
new file mode 100755
index 0000000..5a3998a
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDaoImpl.java
@@ -0,0 +1,279 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Event;
+import com.cloud.storage.Snapshot.State;
+import com.cloud.storage.Snapshot.Type;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao {
+    public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName());
+    // TODO: we should remove these direct sqls
+    private static final String GET_LAST_SNAPSHOT =
+        "SELECT snapshots.id FROM snapshot_store_ref, snapshots where snapshots.id = snapshot_store_ref.snapshot_id AND snapshosts.volume_id = ? AND snapshot_store_ref.role = ? ORDER BY created DESC";
+
+    private SearchBuilder<SnapshotVO> VolumeIdSearch;
+    private SearchBuilder<SnapshotVO> VolumeIdTypeSearch;
+    private SearchBuilder<SnapshotVO> VolumeIdTypeNotDestroyedSearch;
+    private SearchBuilder<SnapshotVO> VolumeIdVersionSearch;
+    private SearchBuilder<SnapshotVO> AccountIdSearch;
+    private SearchBuilder<SnapshotVO> InstanceIdSearch;
+    private SearchBuilder<SnapshotVO> StatusSearch;
+    private SearchBuilder<SnapshotVO> notInStatusSearch;
+    private GenericSearchBuilder<SnapshotVO, Long> CountSnapshotsByAccount;
+    @Inject
+    ResourceTagDao _tagsDao;
+    @Inject
+    protected VMInstanceDao _instanceDao;
+    @Inject
+    protected VolumeDao _volumeDao;
+
+    @Override
+    public List<SnapshotVO> listByVolumeIdTypeNotDestroyed(long volumeId, Type type) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdTypeNotDestroyedSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        sc.setParameters("type", type.ordinal());
+        sc.setParameters("status", State.Destroyed);
+        return listBy(sc, null);
+    }
+
+    @Override
+    public List<SnapshotVO> listByVolumeIdVersion(long volumeId, String version) {
+        return listByVolumeIdVersion(null, volumeId, version);
+    }
+
+    @Override
+    public List<SnapshotVO> listByVolumeId(long volumeId) {
+        return listByVolumeId(null, volumeId);
+    }
+
+    @Override
+    public List<SnapshotVO> listByVolumeId(Filter filter, long volumeId) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        return listBy(sc, filter);
+    }
+
+    @Override
+    public List<SnapshotVO> listByVolumeIdIncludingRemoved(long volumeId) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        return listIncludingRemovedBy(sc, null);
+    }
+
+    public List<SnapshotVO> listByVolumeIdType(Filter filter, long volumeId, Type type) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdTypeSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        sc.setParameters("type", type.ordinal());
+        return listBy(sc, filter);
+    }
+
+    public List<SnapshotVO> listByVolumeIdVersion(Filter filter, long volumeId, String version) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdVersionSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        sc.setParameters("version", version);
+        return listBy(sc, filter);
+    }
+
+    public SnapshotDaoImpl() {
+    }
+
+    @PostConstruct
+    protected void init() {
+        VolumeIdSearch = createSearchBuilder();
+        VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        VolumeIdSearch.done();
+
+        VolumeIdTypeSearch = createSearchBuilder();
+        VolumeIdTypeSearch.and("volumeId", VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ);
+        VolumeIdTypeSearch.done();
+
+        VolumeIdTypeNotDestroyedSearch = createSearchBuilder();
+        VolumeIdTypeNotDestroyedSearch.and("volumeId", VolumeIdTypeNotDestroyedSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        VolumeIdTypeNotDestroyedSearch.and("type", VolumeIdTypeNotDestroyedSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ);
+        VolumeIdTypeNotDestroyedSearch.and("status", VolumeIdTypeNotDestroyedSearch.entity().getState(), SearchCriteria.Op.NEQ);
+        VolumeIdTypeNotDestroyedSearch.done();
+
+        VolumeIdVersionSearch = createSearchBuilder();
+        VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ);
+        VolumeIdVersionSearch.done();
+
+        AccountIdSearch = createSearchBuilder();
+        AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountIdSearch.done();
+
+        StatusSearch = createSearchBuilder();
+        StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN);
+        StatusSearch.done();
+
+        notInStatusSearch  = createSearchBuilder();
+        notInStatusSearch.and("volumeId", notInStatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        notInStatusSearch.and("status", notInStatusSearch.entity().getState(), SearchCriteria.Op.NOTIN);
+        notInStatusSearch.done();
+
+        CountSnapshotsByAccount = createSearchBuilder(Long.class);
+        CountSnapshotsByAccount.select(null, Func.COUNT, null);
+        CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
+        CountSnapshotsByAccount.and("status", CountSnapshotsByAccount.entity().getState(), SearchCriteria.Op.NIN);
+        CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
+        CountSnapshotsByAccount.done();
+
+        InstanceIdSearch = createSearchBuilder();
+        InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
+
+        SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
+        instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
+
+        SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
+        volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
+        volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER);
+
+        InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER);
+        InstanceIdSearch.done();
+    }
+
+    @Override
+    public long getLastSnapshot(long volumeId, DataStoreRole role) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = GET_LAST_SNAPSHOT;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, volumeId);
+            pstmt.setString(2, role.toString());
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                return rs.getLong(1);
+            }
+        } catch (Exception ex) {
+            s_logger.error("error getting last snapshot", ex);
+        }
+        return 0;
+    }
+
+    @Override
+    public Long countSnapshotsForAccount(long accountId) {
+        SearchCriteria<Long> sc = CountSnapshotsByAccount.create();
+        sc.setParameters("account", accountId);
+        sc.setParameters("status", State.Error, State.Destroyed);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status) {
+        SearchCriteria<SnapshotVO> sc = InstanceIdSearch.create();
+
+        if (status != null && status.length != 0) {
+            sc.setParameters("status", (Object[])status);
+        }
+
+        sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready);
+        sc.setJoinParameters("instanceVolumes", "instanceId", instanceId);
+        return listBy(sc, null);
+    }
+
+    @Override
+    public List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status) {
+        SearchCriteria<SnapshotVO> sc = StatusSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        sc.setParameters("status", (Object[])status);
+        return listBy(sc, null);
+    }
+
+    @Override
+    @DB
+    public boolean remove(Long id) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        SnapshotVO entry = findById(id);
+        if (entry != null) {
+            _tagsDao.removeByIdAndType(id, ResourceObjectType.Snapshot);
+        }
+        boolean result = super.remove(id);
+        txn.commit();
+        return result;
+    }
+
+    @Override
+    public List<SnapshotVO> listAllByStatus(Snapshot.State... status) {
+        SearchCriteria<SnapshotVO> sc = StatusSearch.create();
+        sc.setParameters("status", (Object[])status);
+        return listBy(sc, null);
+    }
+
+    @Override
+    public boolean updateState(State currentState, Event event, State nextState, SnapshotVO snapshot, Object data) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        SnapshotVO snapshotVO = snapshot;
+        snapshotVO.setState(nextState);
+        super.update(snapshotVO.getId(), snapshotVO);
+        txn.commit();
+        return true;
+    }
+
+    @Override
+    public void updateVolumeIds(long oldVolId, long newVolId) {
+        SearchCriteria<SnapshotVO> sc = VolumeIdSearch.create();
+        sc.setParameters("volumeId", oldVolId);
+        SnapshotVO snapshot = createForUpdate();
+        snapshot.setVolumeId(newVolId);
+        UpdateBuilder ub = getUpdateBuilder(snapshot);
+        update(ub, sc, null);
+    }
+
+    @Override
+    public List<SnapshotVO> listByStatusNotIn(long volumeId, Snapshot.State... status) {
+        SearchCriteria<SnapshotVO> sc = this.notInStatusSearch.create();
+        sc.setParameters("volumeId", volumeId);
+        sc.setParameters("status", (Object[]) status);
+        return listBy(sc, null);
+    }
+}
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotDetailsVO.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotPolicyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotPolicyDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotScheduleDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotScheduleDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolHostDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolHostDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolHostDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolHostDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolHostDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolTagsDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolTagsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolTagsDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolTagsDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolTagsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolTagsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolTagsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolTagsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolWorkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolWorkDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/UploadDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/UploadDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/UploadDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/UploadDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/UploadDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/UploadDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateHostDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateHostDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateHostDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateHostDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateZoneDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateZoneDao.java
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
new file mode 100644
index 0000000..21b3150
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.dao;
+
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+
+@Component
+public class VMTemplateZoneDaoImpl extends GenericDaoBase<VMTemplateZoneVO, Long> implements VMTemplateZoneDao {
+    public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName());
+
+    protected final SearchBuilder<VMTemplateZoneVO> ZoneSearch;
+    protected final SearchBuilder<VMTemplateZoneVO> TemplateSearch;
+    protected final SearchBuilder<VMTemplateZoneVO> ZoneTemplateSearch;
+
+    public VMTemplateZoneDaoImpl() {
+        ZoneSearch = createSearchBuilder();
+        ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
+        ZoneSearch.done();
+
+        TemplateSearch = createSearchBuilder();
+        TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        TemplateSearch.done();
+
+        ZoneTemplateSearch = createSearchBuilder();
+        ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
+        ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        ZoneTemplateSearch.done();
+    }
+
+    @Override
+    public List<VMTemplateZoneVO> listByZoneId(long id) {
+        SearchCriteria<VMTemplateZoneVO> sc = ZoneSearch.create();
+        sc.setParameters("zone_id", id);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VMTemplateZoneVO> listByTemplateId(long templateId) {
+        SearchCriteria<VMTemplateZoneVO> sc = TemplateSearch.create();
+        sc.setParameters("template_id", templateId);
+        return listBy(sc);
+    }
+
+    @Override
+    public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId) {
+        SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
+        sc.setParameters("zone_id", zoneId);
+        sc.setParameters("template_id", templateId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId) {
+        SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
+        if (zoneId != null) {
+            sc.setParameters("zone_id", zoneId);
+        }
+        sc.setParameters("template_id", templateId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void deletePrimaryRecordsForTemplate(long templateId) {
+        SearchCriteria<VMTemplateZoneVO> sc = TemplateSearch.create();
+        sc.setParameters("template_id", templateId);
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        remove(sc);
+        txn.commit();
+    }
+
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java
new file mode 100644
index 0000000..51d46a0
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java
@@ -0,0 +1,124 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.State, Volume.Event, Volume> {
+
+    List<VolumeVO> findDetachedByAccount(long accountId);
+
+    List<VolumeVO> findByAccount(long accountId);
+
+    List<VolumeVO> findIncludingRemovedByAccount(long accountId);
+
+    Pair<Long, Long> getCountAndTotalByPool(long poolId);
+
+    Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId);
+
+    long getVMSnapshotSizeByPool(long poolId);
+
+    List<VolumeVO> findByInstance(long id);
+
+    List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
+
+    List<VolumeVO> findByInstanceIdDestroyed(long vmId);
+
+    List<VolumeVO> findByPod(long podId);
+
+    List<VolumeVO> findByDc(long dcId);
+
+    List<VolumeVO> findByAccountAndPod(long accountId, long podId);
+
+    List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId);
+
+    void deleteVolumesByInstance(long instanceId);
+
+    void attachVolume(long volumeId, long vmId, long deviceId);
+
+    void detachVolume(long volumeId);
+
+    boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId);
+
+    List<VolumeVO> findCreatedByInstance(long id);
+
+    List<VolumeVO> findByPoolId(long poolId);
+
+    VolumeVO findByPoolIdName(long poolId, String name);
+
+    List<VolumeVO> findByPoolId(long poolId, Volume.Type volumeType);
+
+    List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId);
+
+    List<VolumeVO> findUsableVolumesForInstance(long instanceId);
+
+    Long countAllocatedVolumesForAccount(long accountId);
+
+    HypervisorType getHypervisorType(long volumeId);
+
+    List<VolumeVO> listVolumesToBeDestroyed();
+
+    List<VolumeVO> listVolumesToBeDestroyed(Date date);
+
+    ImageFormat getImageFormat(Long volumeId);
+
+    List<VolumeVO> findReadyRootVolumesByInstance(long instanceId);
+
+    List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId);
+
+    List<Long> listZoneWidePoolIdsByVolumeCount(long dcId, long accountId);
+
+    /**
+     * Gets the Total Primary Storage space allocated for an account
+     *
+     * @param list of ids of virtual router VMs under this account
+     * @return total Primary Storage space (in bytes) used
+     */
+    long primaryStorageUsedForAccount(long accountId, List<Long> virtualRouters);
+
+    /**
+     * Gets the Total Secondary Storage space used by volumes allocated for an account
+     * @return total Secondary Storage space (in bytes) used
+     */
+    long secondaryStorageUsedForAccount(long accountId);
+
+    /***
+     * @return the scope of the storage pool where the volume is present (ZONE/CLUSTER)
+     */
+    ScopeType getVolumeStoragePoolScope(long volumeId);
+
+    /***
+     * Updates the destVol uuid with srcVol uuid and sets the srcVol uuid as null.
+     * @return returns true if transaction is successful.
+     */
+    boolean updateUuid(long srcVolId, long destVolId);
+
+    /**
+     *  Updates the disk offering for the given volume.
+     */
+    void updateDiskOffering(long volumeId, long diskOfferingId);
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java
new file mode 100644
index 0000000..663a5f5
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java
@@ -0,0 +1,686 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Event;
+import com.cloud.storage.Volume.State;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements VolumeDao {
+    private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
+    protected final SearchBuilder<VolumeVO> DetachedAccountIdSearch;
+    protected final SearchBuilder<VolumeVO> TemplateZoneSearch;
+    protected final GenericSearchBuilder<VolumeVO, SumCount> TotalSizeByPoolSearch;
+    protected final GenericSearchBuilder<VolumeVO, SumCount> TotalVMSnapshotSizeByPoolSearch;
+    protected final GenericSearchBuilder<VolumeVO, Long> ActiveTemplateSearch;
+    protected final SearchBuilder<VolumeVO> InstanceStatesSearch;
+    protected final SearchBuilder<VolumeVO> AllFieldsSearch;
+    protected GenericSearchBuilder<VolumeVO, Long> CountByAccount;
+    protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch;
+    protected GenericSearchBuilder<VolumeVO, SumCount> primaryStorageSearch2;
+    protected GenericSearchBuilder<VolumeVO, SumCount> secondaryStorageSearch;
+    @Inject
+    ResourceTagDao _tagsDao;
+
+    protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?";
+    // need to account for zone-wide primary storage where storage_pool has
+    // null-value pod and cluster, where hypervisor information is stored in
+    // storage_pool
+    protected static final String SELECT_HYPERTYPE_FROM_CLUSTER_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?";
+    protected static final String SELECT_HYPERTYPE_FROM_ZONE_VOLUME = "SELECT s.hypervisor from volumes v, storage_pool s where v.pool_id = s.id and v.id = ?";
+    protected static final String SELECT_POOLSCOPE = "SELECT s.scope from storage_pool s, volumes v where s.id = v.pool_id and v.id = ?";
+
+    private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? "
+            + " AND pool.pod_id = ? AND pool.cluster_id = ? " + " GROUP BY pool.id ORDER BY 2 ASC ";
+    private static final String ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? "
+            + " AND pool.scope = 'ZONE' AND pool.status='Up' " + " GROUP BY pool.id ORDER BY 2 ASC ";
+
+    @Override
+    public List<VolumeVO> findDetachedByAccount(long accountId) {
+        SearchCriteria<VolumeVO> sc = DetachedAccountIdSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("destroyed", Volume.State.Destroy);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByAccount(long accountId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findIncludingRemovedByAccount(long accountId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByInstance(long id) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByInstanceAndDeviceId(long instanceId, long deviceId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        sc.setParameters("deviceId", deviceId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByPoolId(long poolId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("notDestroyed", Volume.State.Destroy);
+        sc.setParameters("vType", Volume.Type.ROOT.toString());
+        return listBy(sc);
+    }
+
+    @Override
+    public VolumeVO findByPoolIdName(long poolId, String name) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("name", name);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByPoolId(long poolId, Volume.Type volumeType) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("notDestroyed", Volume.State.Destroy);
+
+        if (volumeType != null) {
+            sc.setParameters("vType", volumeType.toString());
+        }
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findCreatedByInstance(long id) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        sc.setParameters("state", Volume.State.Ready);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findUsableVolumesForInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = InstanceStatesSearch.create();
+        sc.setParameters("instance", instanceId);
+        sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByInstanceAndType(long id, Type vType) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        sc.setParameters("vType", vType.toString());
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByInstanceIdDestroyed(long vmId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", vmId);
+        sc.setParameters("destroyed", Volume.State.Destroy);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findReadyRootVolumesByInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        sc.setParameters("state", Volume.State.Ready);
+        sc.setParameters("vType", Volume.Type.ROOT);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByPod(long podId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("pod", podId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByDc(long dcId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("dcId", dcId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByAccountAndPod(long accountId, long podId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("pod", podId);
+        sc.setParameters("state", Volume.State.Ready);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> findByTemplateAndZone(long templateId, long zoneId) {
+        SearchCriteria<VolumeVO> sc = TemplateZoneSearch.create();
+        sc.setParameters("template", templateId);
+        sc.setParameters("zone", zoneId);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) {
+        SearchCriteria<Long> sc = ActiveTemplateSearch.create();
+        sc.setParameters("template", templateId);
+        sc.setParameters("pool", poolId);
+
+        List<Long> results = customSearchIncludingRemoved(sc, null);
+        assert results.size() > 0 : "How can this return a size of " + results.size();
+
+        return results.get(0) > 0;
+    }
+
+    @Override
+    public void deleteVolumesByInstance(long instanceId) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        expunge(sc);
+    }
+
+    @Override
+    public void attachVolume(long volumeId, long vmId, long deviceId) {
+        VolumeVO volume = createForUpdate(volumeId);
+        volume.setInstanceId(vmId);
+        volume.setDeviceId(deviceId);
+        volume.setUpdated(new Date());
+        volume.setAttached(new Date());
+        if (deviceId == 0L) {
+            volume.setVolumeType(Type.ROOT);
+        }
+        update(volumeId, volume);
+    }
+
+    @Override
+    public void detachVolume(long volumeId) {
+        VolumeVO volume = createForUpdate(volumeId);
+        volume.setInstanceId(null);
+        volume.setDeviceId(null);
+        volume.setUpdated(new Date());
+        volume.setAttached(null);
+        if (findById(volumeId).getVolumeType() == Type.ROOT) {
+            volume.setVolumeType(Type.DATADISK);
+        }
+        update(volumeId, volume);
+    }
+
+    @Override
+    @DB
+    public HypervisorType getHypervisorType(long volumeId) {
+        /* lookup from cluster of pool */
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = null;
+        try {
+            ScopeType scope = getVolumeStoragePoolScope(volumeId);
+            if (scope != null) {
+                if (scope == ScopeType.CLUSTER || scope == ScopeType.HOST) {
+                    sql = SELECT_HYPERTYPE_FROM_CLUSTER_VOLUME;
+                } else if (scope == ScopeType.ZONE) {
+                    sql = SELECT_HYPERTYPE_FROM_ZONE_VOLUME;
+                } else {
+                    s_logger.error("Unhandled scope type '" + scope + "' when running getHypervisorType on volume id " + volumeId);
+                }
+
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setLong(1, volumeId);
+                ResultSet rs = pstmt.executeQuery();
+                if (rs.next()) {
+                    if (rs.getString(1) != null) {
+                        return HypervisorType.getType(rs.getString(1));
+                    }
+                }
+            }
+            return HypervisorType.None;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + sql, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + sql, e);
+        }
+    }
+
+    @Override
+    public ImageFormat getImageFormat(Long volumeId) {
+        HypervisorType type = getHypervisorType(volumeId);
+        if (type.equals(HypervisorType.KVM)) {
+            return ImageFormat.QCOW2;
+        } else if (type.equals(HypervisorType.XenServer)) {
+            return ImageFormat.VHD;
+        } else if (type.equals(HypervisorType.VMware)) {
+            return ImageFormat.OVA;
+        } else {
+            s_logger.warn("Do not support hypervisor " + type.toString());
+            return null;
+        }
+    }
+
+    public VolumeDaoImpl() {
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
+        AllFieldsSearch.and("dcId", AllFieldsSearch.entity().getDataCenterId(), Op.EQ);
+        AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ);
+        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ);
+        AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
+        AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ);
+        AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ);
+        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
+        AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ);
+        AllFieldsSearch.and("updateTime", AllFieldsSearch.entity().getUpdated(), SearchCriteria.Op.LT);
+        AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ);
+        AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ);
+        AllFieldsSearch.done();
+
+        DetachedAccountIdSearch = createSearchBuilder();
+        DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ);
+        DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ);
+        DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL);
+        DetachedAccountIdSearch.done();
+
+        TemplateZoneSearch = createSearchBuilder();
+        TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ);
+        TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ);
+        TemplateZoneSearch.done();
+
+        TotalSizeByPoolSearch = createSearchBuilder(SumCount.class);
+        TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize());
+        TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null);
+        TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ);
+        TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL);
+        TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ);
+        TotalSizeByPoolSearch.done();
+
+        TotalVMSnapshotSizeByPoolSearch = createSearchBuilder(SumCount.class);
+        TotalVMSnapshotSizeByPoolSearch.select("sum", Func.SUM, TotalVMSnapshotSizeByPoolSearch.entity().getVmSnapshotChainSize());
+        TotalVMSnapshotSizeByPoolSearch.and("poolId", TotalVMSnapshotSizeByPoolSearch.entity().getPoolId(), Op.EQ);
+        TotalVMSnapshotSizeByPoolSearch.and("removed", TotalVMSnapshotSizeByPoolSearch.entity().getRemoved(), Op.NULL);
+        TotalVMSnapshotSizeByPoolSearch.and("state", TotalVMSnapshotSizeByPoolSearch.entity().getState(), Op.NEQ);
+        TotalVMSnapshotSizeByPoolSearch.and("vType", TotalVMSnapshotSizeByPoolSearch.entity().getVolumeType(), Op.EQ);
+        TotalVMSnapshotSizeByPoolSearch.and("instanceId", TotalVMSnapshotSizeByPoolSearch.entity().getInstanceId(), Op.NNULL);
+        TotalVMSnapshotSizeByPoolSearch.done();
+
+        ActiveTemplateSearch = createSearchBuilder(Long.class);
+        ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ);
+        ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ);
+        ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL);
+        ActiveTemplateSearch.select(null, Func.COUNT, null);
+        ActiveTemplateSearch.done();
+
+        InstanceStatesSearch = createSearchBuilder();
+        InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ);
+        InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN);
+        InstanceStatesSearch.done();
+
+        CountByAccount = createSearchBuilder(Long.class);
+        CountByAccount.select(null, Func.COUNT, null);
+        CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
+        CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
+        CountByAccount.and("displayVolume", CountByAccount.entity().isDisplayVolume(), Op.EQ);
+        CountByAccount.done();
+
+        primaryStorageSearch = createSearchBuilder(SumCount.class);
+        primaryStorageSearch.select("sum", Func.SUM, primaryStorageSearch.entity().getSize());
+        primaryStorageSearch.and("accountId", primaryStorageSearch.entity().getAccountId(), Op.EQ);
+        primaryStorageSearch.and().op("path", primaryStorageSearch.entity().getPath(), Op.NNULL);
+        primaryStorageSearch.or("states", primaryStorageSearch.entity().getState(), Op.IN);
+        primaryStorageSearch.cp();
+        primaryStorageSearch.and("displayVolume", primaryStorageSearch.entity().isDisplayVolume(), Op.EQ);
+        primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL);
+        primaryStorageSearch.done();
+
+        primaryStorageSearch2 = createSearchBuilder(SumCount.class);
+        primaryStorageSearch2.select("sum", Func.SUM, primaryStorageSearch2.entity().getSize());
+        primaryStorageSearch2.and("accountId", primaryStorageSearch2.entity().getAccountId(), Op.EQ);
+        primaryStorageSearch2.and().op("instanceId", primaryStorageSearch2.entity().getInstanceId(), Op.NULL);
+        primaryStorageSearch2.or("virtualRouterVmIds", primaryStorageSearch2.entity().getInstanceId(), Op.NIN);
+        primaryStorageSearch2.cp();
+        primaryStorageSearch2.and().op("path", primaryStorageSearch2.entity().getPath(), Op.NNULL);
+        primaryStorageSearch2.or("states", primaryStorageSearch2.entity().getState(), Op.IN);
+        primaryStorageSearch2.cp();
+        primaryStorageSearch2.and("displayVolume", primaryStorageSearch2.entity().isDisplayVolume(), Op.EQ);
+        primaryStorageSearch2.and("isRemoved", primaryStorageSearch2.entity().getRemoved(), Op.NULL);
+        primaryStorageSearch2.done();
+
+        secondaryStorageSearch = createSearchBuilder(SumCount.class);
+        secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize());
+        secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ);
+        secondaryStorageSearch.and("path", secondaryStorageSearch.entity().getPath(), Op.NULL);
+        secondaryStorageSearch.and("states", secondaryStorageSearch.entity().getState(), Op.NIN);
+        secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL);
+        secondaryStorageSearch.done();
+    }
+
+    @Override
+    @DB()
+    public Pair<Long, Long> getCountAndTotalByPool(long poolId) {
+        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
+        sc.setParameters("poolId", poolId);
+        List<SumCount> results = customSearch(sc, null);
+        SumCount sumCount = results.get(0);
+        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
+    }
+
+    @Override
+    public Long countAllocatedVolumesForAccount(long accountId) {
+        SearchCriteria<Long> sc = CountByAccount.create();
+        sc.setParameters("account", accountId);
+        sc.setParameters("state", Volume.State.Destroy);
+        sc.setParameters("displayVolume", 1);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public long primaryStorageUsedForAccount(long accountId, List<Long> virtualRouters) {
+        SearchCriteria<SumCount> sc;
+        if (!virtualRouters.isEmpty()) {
+            sc = primaryStorageSearch2.create();
+            sc.setParameters("virtualRouterVmIds", virtualRouters.toArray(new Object[virtualRouters.size()]));
+        } else {
+            sc = primaryStorageSearch.create();
+        }
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("states", State.Allocated);
+        sc.setParameters("displayVolume", 1);
+        List<SumCount> storageSpace = customSearch(sc, null);
+        if (storageSpace != null) {
+            return storageSpace.get(0).sum;
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public long secondaryStorageUsedForAccount(long accountId) {
+        SearchCriteria<SumCount> sc = secondaryStorageSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("states", State.Allocated);
+        List<SumCount> storageSpace = customSearch(sc, null);
+        if (storageSpace != null) {
+            return storageSpace.get(0).sum;
+        } else {
+            return 0;
+        }
+    }
+
+    public static class SumCount {
+        public long sum;
+        public long count;
+
+        public SumCount() {
+        }
+    }
+
+    @Override
+    public List<VolumeVO> listVolumesToBeDestroyed() {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("state", Volume.State.Destroy);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<VolumeVO> listVolumesToBeDestroyed(Date date) {
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("state", Volume.State.Destroy);
+        sc.setParameters("updateTime", date);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public boolean updateState(com.cloud.storage.Volume.State currentState, Event event, com.cloud.storage.Volume.State nextState, Volume vo, Object data) {
+
+        Long oldUpdated = vo.getUpdatedCount();
+        Date oldUpdatedTime = vo.getUpdated();
+
+        SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
+        sc.setParameters("id", vo.getId());
+        sc.setParameters("state", currentState);
+        sc.setParameters("updatedCount", vo.getUpdatedCount());
+
+        vo.incrUpdatedCount();
+
+        UpdateBuilder builder = getUpdateBuilder(vo);
+        builder.set(vo, "state", nextState);
+        builder.set(vo, "updated", new Date());
+
+        int rows = update((VolumeVO)vo, sc);
+        if (rows == 0 && s_logger.isDebugEnabled()) {
+            VolumeVO dbVol = findByIdIncludingRemoved(vo.getId());
+            if (dbVol != null) {
+                StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
+                str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=")
+                .append(dbVol.getUpdated());
+                str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount())
+                .append("; updatedTime=").append(vo.getUpdated());
+                str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated)
+                .append("; updatedTime=").append(oldUpdatedTime);
+            } else {
+                s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore");
+            }
+        }
+        return rows > 0;
+    }
+
+    @Override
+    public List<Long> listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        List<Long> result = new ArrayList<Long>();
+        try {
+            String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, accountId);
+            pstmt.setLong(2, dcId);
+            pstmt.setLong(3, podId);
+            pstmt.setLong(4, clusterId);
+
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(rs.getLong(1));
+            }
+            return result;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        }
+    }
+
+    @Override
+    public List<Long> listZoneWidePoolIdsByVolumeCount(long dcId, long accountId) {
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        List<Long> result = new ArrayList<Long>();
+        try {
+            String sql = ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, accountId);
+            pstmt.setLong(2, dcId);
+
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(rs.getLong(1));
+            }
+            return result;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + ORDER_ZONE_WIDE_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e);
+        }
+    }
+
+    @Override
+    @DB()
+    public Pair<Long, Long> getNonDestroyedCountAndTotalByPool(long poolId) {
+        SearchCriteria<SumCount> sc = TotalSizeByPoolSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("state", State.Destroy);
+        List<SumCount> results = customSearch(sc, null);
+        SumCount sumCount = results.get(0);
+        return new Pair<Long, Long>(sumCount.count, sumCount.sum);
+    }
+
+    @Override
+    public long getVMSnapshotSizeByPool(long poolId) {
+        SearchCriteria<SumCount> sc = TotalVMSnapshotSizeByPoolSearch.create();
+        sc.setParameters("poolId", poolId);
+        sc.setParameters("state", State.Destroy);
+        sc.setParameters("vType", Volume.Type.ROOT.toString());
+        List<SumCount> results = customSearch(sc, null);
+        if (results != null) {
+            return results.get(0).sum;
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    @DB
+    public boolean remove(Long id) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        VolumeVO entry = findById(id);
+        if (entry != null) {
+            _tagsDao.removeByIdAndType(id, ResourceObjectType.Volume);
+        }
+        boolean result = super.remove(id);
+        txn.commit();
+        return result;
+    }
+
+    @Override
+    @DB
+    public boolean updateUuid(long srcVolId, long destVolId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        try {
+            VolumeVO srcVol = findById(srcVolId);
+            VolumeVO destVol = findById(destVolId);
+            String uuid = srcVol.getUuid();
+            Long instanceId = srcVol.getInstanceId();
+            srcVol.setUuid(null);
+            destVol.setUuid(uuid);
+            destVol.setInstanceId(instanceId);
+            update(srcVolId, srcVol);
+            update(destVolId, destVol);
+            _tagsDao.updateResourceId(srcVolId, destVolId, ResourceObjectType.Volume);
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Unable to persist the sequence number for this host");
+        }
+        txn.commit();
+        return true;
+    }
+
+    @Override
+    public ScopeType getVolumeStoragePoolScope(long volumeId) {
+        // finding the storage scope where the volume is present
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+
+        try {
+            String sql = SELECT_POOLSCOPE;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, volumeId);
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                String scope = rs.getString(1);
+                if (scope != null) {
+                    try {
+                        return Enum.valueOf(ScopeType.class, scope.toUpperCase());
+                    } catch (Exception e) {
+                        throw new InvalidParameterValueException("invalid scope for pool " + scope);
+                    }
+                }
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + SELECT_POOLSCOPE, e);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Caught: " + SELECT_POOLSCOPE, e);
+        }
+        return null;
+    }
+
+    private String sqlUpdateDiskOffering = "UPDATE volumes SET disk_offering_id = ? where id =?";
+
+    @Override
+    public void updateDiskOffering(long volumeId, long diskOfferingId) {
+        try (TransactionLegacy txn = TransactionLegacy.currentTxn();
+                PreparedStatement pstmt = txn.prepareAutoCloseStatement(sqlUpdateDiskOffering)) {
+            pstmt.setLong(1, diskOfferingId);
+            pstmt.setLong(2, volumeId);
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException(e);
+        }
+    }
+}
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VolumeDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VolumeDetailsDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VolumeDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VolumeDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeHostDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VolumeHostDao.java
diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeHostDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/VolumeHostDaoImpl.java
diff --git a/engine/schema/src/com/cloud/tags/ResourceTagVO.java b/engine/schema/src/main/java/com/cloud/tags/ResourceTagVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/tags/ResourceTagVO.java
rename to engine/schema/src/main/java/com/cloud/tags/ResourceTagVO.java
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
rename to engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagDao.java
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/tags/dao/ResourceTagsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/DatabaseCreator.java
rename to engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java
new file mode 100644
index 0000000..bb75aac
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseIntegrityChecker.java
@@ -0,0 +1,306 @@
+// 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.upgrade;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.utils.CloudStackVersion;
+
+import com.cloud.upgrade.dao.VersionDao;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.SystemIntegrityChecker;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class DatabaseIntegrityChecker extends AdapterBase implements SystemIntegrityChecker {
+    private static final Logger s_logger = Logger.getLogger(DatabaseIntegrityChecker.class);
+
+    @Inject
+    VersionDao _dao;
+
+    public DatabaseIntegrityChecker() {
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP);
+    }
+
+    /*
+     * Check if there were multiple hosts connect to the same local storage. This is from a 2.1.x bug,
+     * we didn't prevent adding host with the same IP.
+     */
+    private String formatDuplicateHostToReadText(Long poolId, ResultSet rs) throws SQLException {
+        boolean has = false;
+        StringBuffer buf = new StringBuffer();
+        String fmt = "|%1$-8s|%2$-16s|%3$-16s|%4$-24s|%5$-8s|\n";
+        String head = String.format(fmt, "id", "status", "removed", "private_ip_address", "pool_id");
+        buf.append(head);
+        while (rs.next()) {
+            String h = String.format(fmt, rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(4), poolId);
+            buf.append(h);
+            has = true;
+        }
+
+        if (!has) {
+            throw new CloudRuntimeException(
+                "Local storage with Id " +
+                    poolId +
+                    " shows there are multiple hosts connect to it, but 'select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)' returns nothing");
+        } else {
+            return buf.toString();
+        }
+    }
+
+    private Boolean checkDuplicateHostWithTheSameLocalStorage() {
+
+        TransactionLegacy txn = TransactionLegacy.open("Integrity");
+        try {
+            txn.start();
+            Connection conn = txn.getConnection();
+            try (PreparedStatement pstmt =
+                             conn.prepareStatement("SELECT pool_id FROM host INNER JOIN storage_pool_host_ref INNER JOIN storage_pool WHERE storage_pool.id = storage_pool_host_ref.pool_id and storage_pool.pool_type='LVM' AND host.id=storage_pool_host_ref.host_id AND host.removed IS NULL group by pool_id having count(*) > 1");
+                 ResultSet rs = pstmt.executeQuery();)
+            {
+                    boolean noDuplicate = true;
+                    StringBuffer helpInfo = new StringBuffer();
+                    String note =
+                        "DATABASE INTEGRITY ERROR\nManagement server detected there are some hosts connect to the same loacal storage, please contact CloudStack support team for solution. Below are detialed info, please attach all of them to CloudStack support. Thank you\n";
+                    helpInfo.append(note);
+                    while (rs.next()) {
+                        try ( PreparedStatement sel_pstmt =
+                                conn.prepareStatement("select id, status, removed, private_ip_address from host where id in (select host_id from storage_pool_host_ref where pool_id=?)");
+                        ){
+                                long poolId = rs.getLong(1);
+                                pstmt.setLong(1, poolId);
+                                try(ResultSet dhrs = sel_pstmt.executeQuery();) {
+                                    String help = formatDuplicateHostToReadText(poolId, dhrs);
+                                    helpInfo.append(help);
+                                    helpInfo.append("\n");
+                                    noDuplicate = false;
+                                }
+                                catch (Exception e)
+                                {
+                                    s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
+                                    throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
+                                }
+                        }
+                        catch (Exception e)
+                        {
+                                s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
+                                throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
+                        }
+                    }
+                    if (noDuplicate) {
+                        s_logger.debug("No duplicate hosts with the same local storage found in database");
+                    } else {
+                        s_logger.error(helpInfo.toString());
+                    }
+                    txn.commit();
+                    return noDuplicate;
+            }catch (Exception e)
+            {
+                  s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
+                  throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
+            }
+        }
+        catch (Exception e)
+        {
+            s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage());
+            throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage: Exception :" + e.getMessage(),e);
+        }
+        finally
+        {
+            try {
+                if (txn != null) {
+                    txn.close();
+                }
+            }catch(Exception e)
+            {
+                s_logger.error("checkDuplicateHostWithTheSameLocalStorage: Exception:"+ e.getMessage());
+            }
+        }
+    }
+
+    private boolean check21to22PremiumUprage(Connection conn) throws SQLException {
+        try (PreparedStatement pstmt = conn.prepareStatement("show tables in cloud_usage");
+             ResultSet rs = pstmt.executeQuery();) {
+            int num = 0;
+            while (rs.next()) {
+                String tableName = rs.getString(1);
+                if (tableName.equalsIgnoreCase("usage_event") || tableName.equalsIgnoreCase("usage_port_forwarding") || tableName.equalsIgnoreCase("usage_network_offering")) {
+                    num++;
+                    s_logger.debug("Checking 21to22PremiumUprage table " + tableName + " found");
+                }
+                if (num == 3) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private boolean isColumnExisted(Connection conn, String dbName, String tableName, String column) throws SQLException {
+        try (PreparedStatement pstmt = conn.prepareStatement(String.format("describe %1$s.%2$s", dbName, tableName));
+             ResultSet rs = pstmt.executeQuery();) {
+            boolean found = false;
+            while (rs.next()) {
+                if (column.equalsIgnoreCase(rs.getString(1))) {
+                    s_logger.debug(String.format("Column %1$s.%2$s.%3$s found", dbName, tableName, column));
+                    found = true;
+                    break;
+                }
+            }
+            return found;
+        }
+    }
+
+    private boolean check221to222PremiumUprage(Connection conn) throws SQLException {
+        if (!isColumnExisted(conn, "cloud_usage", "cloud_usage", "network_id")) {
+            return false;
+        }
+
+        if (!isColumnExisted(conn, "cloud_usage", "usage_network", "network_id")) {
+            return false;
+        }
+
+        return isColumnExisted(conn, "cloud_usage", "user_statistics", "network_id");
+    }
+
+    private boolean check222to224PremiumUpgrade(Connection conn) throws SQLException {
+        if (!isColumnExisted(conn, "cloud_usage", "usage_vm_instance", "hypervisor_type")) {
+            return false;
+        }
+
+        return isColumnExisted(conn, "cloud_usage", "usage_event", "resource_type");
+    }
+
+    private boolean checkMissedPremiumUpgradeFor228() {
+        TransactionLegacy txn = TransactionLegacy.open("Integrity");
+        try {
+            txn.start();
+            Connection conn = txn.getConnection();
+            try (
+                PreparedStatement pstmt = conn.prepareStatement("show databases");
+                ResultSet rs = pstmt.executeQuery();) {
+                String dbVersion = _dao.getCurrentVersion();
+
+                if (dbVersion == null) {
+                    txn.commit();
+                    return false;
+                }
+
+                if (CloudStackVersion.compare(dbVersion, "2.2.8") != 0) {
+                    txn.commit();
+                    return true;
+                }
+                boolean hasUsage = false;
+                while (rs.next()) {
+                    String dbName = rs.getString(1);
+                    if (dbName.equalsIgnoreCase("cloud_usage")) {
+                        hasUsage = true;
+                        break;
+                    }
+                }
+                if (!hasUsage) {
+                    s_logger.debug("No cloud_usage found in database, no need to check missed premium upgrade");
+                    txn.commit();
+                    return true;
+                }
+                if (!check21to22PremiumUprage(conn)) {
+                    s_logger.error("21to22 premium upgrade missed");
+                    txn.commit();
+                    return false;
+                }
+                if (!check221to222PremiumUprage(conn)) {
+                    s_logger.error("221to222 premium upgrade missed");
+                    txn.commit();
+                    return false;
+                }
+                if (!check222to224PremiumUpgrade(conn)) {
+                    s_logger.error("222to224 premium upgrade missed");
+                    txn.commit();
+                    return false;
+                }
+                txn.commit();
+                return true;
+            } catch (Exception e) {
+                s_logger.error("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage());
+                throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(), e);
+            }
+        }catch (Exception e) {
+            s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage());
+            throw new CloudRuntimeException("checkMissedPremiumUpgradeFor228: Exception:" + e.getMessage(),e);
+        }
+        finally
+        {
+            try {
+                if (txn != null) {
+                    txn.close();
+                }
+            }catch(Exception e)
+            {
+                s_logger.error("checkMissedPremiumUpgradeFor228: Exception:"+ e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void check() {
+        GlobalLock lock = GlobalLock.getInternLock("DatabaseIntegrity");
+        try {
+            s_logger.info("Grabbing lock to check for database integrity.");
+            if (!lock.lock(20 * 60)) {
+                throw new CloudRuntimeException("Unable to acquire lock to check for database integrity.");
+            }
+
+            try {
+                s_logger.info("Performing database integrity check");
+                if (!checkDuplicateHostWithTheSameLocalStorage()) {
+                    throw new CloudRuntimeException("checkDuplicateHostWithTheSameLocalStorage detected error");
+                }
+
+                if (!checkMissedPremiumUpgradeFor228()) {
+                    s_logger.error("Your current database version is 2.2.8, management server detected some missed premium upgrade, please contact CloudStack support and attach log file. Thank you!");
+                    throw new CloudRuntimeException("Detected missed premium upgrade");
+                }
+            } finally {
+                lock.unlock();
+            }
+        } finally {
+            lock.releaseRef();
+        }
+    }
+
+    @Override
+    public boolean start() {
+        try {
+            check();
+        } catch (Exception e) {
+            s_logger.error("System integrity check exception", e);
+            System.exit(1);
+        }
+        return true;
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java
new file mode 100644
index 0000000..8d24ab9
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java
@@ -0,0 +1,389 @@
+// 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.upgrade;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ObjectArrays.concat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.utils.CloudStackVersion;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.upgrade.dao.DbUpgrade;
+import com.cloud.upgrade.dao.Upgrade217to218;
+import com.cloud.upgrade.dao.Upgrade218to22;
+import com.cloud.upgrade.dao.Upgrade218to224DomainVlans;
+import com.cloud.upgrade.dao.Upgrade2210to2211;
+import com.cloud.upgrade.dao.Upgrade2211to2212;
+import com.cloud.upgrade.dao.Upgrade2212to2213;
+import com.cloud.upgrade.dao.Upgrade2213to2214;
+import com.cloud.upgrade.dao.Upgrade2214to30;
+import com.cloud.upgrade.dao.Upgrade221to222;
+import com.cloud.upgrade.dao.Upgrade222to224;
+import com.cloud.upgrade.dao.Upgrade224to225;
+import com.cloud.upgrade.dao.Upgrade225to226;
+import com.cloud.upgrade.dao.Upgrade227to228;
+import com.cloud.upgrade.dao.Upgrade228to229;
+import com.cloud.upgrade.dao.Upgrade229to2210;
+import com.cloud.upgrade.dao.Upgrade301to302;
+import com.cloud.upgrade.dao.Upgrade302to303;
+import com.cloud.upgrade.dao.Upgrade302to40;
+import com.cloud.upgrade.dao.Upgrade303to304;
+import com.cloud.upgrade.dao.Upgrade304to305;
+import com.cloud.upgrade.dao.Upgrade305to306;
+import com.cloud.upgrade.dao.Upgrade306to307;
+import com.cloud.upgrade.dao.Upgrade307to410;
+import com.cloud.upgrade.dao.Upgrade30to301;
+import com.cloud.upgrade.dao.Upgrade40to41;
+import com.cloud.upgrade.dao.Upgrade41000to41100;
+import com.cloud.upgrade.dao.Upgrade410to420;
+import com.cloud.upgrade.dao.Upgrade41100to41110;
+import com.cloud.upgrade.dao.Upgrade41110to41120;
+import com.cloud.upgrade.dao.Upgrade41120to41130;
+import com.cloud.upgrade.dao.Upgrade41120to41200;
+import com.cloud.upgrade.dao.Upgrade420to421;
+import com.cloud.upgrade.dao.Upgrade421to430;
+import com.cloud.upgrade.dao.Upgrade430to440;
+import com.cloud.upgrade.dao.Upgrade431to440;
+import com.cloud.upgrade.dao.Upgrade432to440;
+import com.cloud.upgrade.dao.Upgrade440to441;
+import com.cloud.upgrade.dao.Upgrade441to442;
+import com.cloud.upgrade.dao.Upgrade442to450;
+import com.cloud.upgrade.dao.Upgrade443to444;
+import com.cloud.upgrade.dao.Upgrade444to450;
+import com.cloud.upgrade.dao.Upgrade450to451;
+import com.cloud.upgrade.dao.Upgrade451to452;
+import com.cloud.upgrade.dao.Upgrade452to453;
+import com.cloud.upgrade.dao.Upgrade453to460;
+import com.cloud.upgrade.dao.Upgrade460to461;
+import com.cloud.upgrade.dao.Upgrade461to470;
+import com.cloud.upgrade.dao.Upgrade470to471;
+import com.cloud.upgrade.dao.Upgrade471to480;
+import com.cloud.upgrade.dao.Upgrade480to481;
+import com.cloud.upgrade.dao.Upgrade481to490;
+import com.cloud.upgrade.dao.Upgrade490to4910;
+import com.cloud.upgrade.dao.Upgrade4910to4920;
+import com.cloud.upgrade.dao.Upgrade4920to4930;
+import com.cloud.upgrade.dao.Upgrade4930to41000;
+import com.cloud.upgrade.dao.UpgradeSnapshot217to224;
+import com.cloud.upgrade.dao.UpgradeSnapshot223to224;
+import com.cloud.upgrade.dao.VersionDao;
+import com.cloud.upgrade.dao.VersionDaoImpl;
+import com.cloud.upgrade.dao.VersionVO;
+import com.cloud.upgrade.dao.VersionVO.Step;
+import com.cloud.utils.component.SystemIntegrityChecker;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.ScriptRunner;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.annotations.VisibleForTesting;
+
+public class DatabaseUpgradeChecker implements SystemIntegrityChecker {
+    private static final Logger s_logger = Logger.getLogger(DatabaseUpgradeChecker.class);
+    private final DatabaseVersionHierarchy hierarchy;
+
+    @Inject
+    VersionDao _dao;
+
+    public DatabaseUpgradeChecker() {
+        _dao = new VersionDaoImpl();
+
+        hierarchy = DatabaseVersionHierarchy.builder()
+                // legacy
+                .next("2.1.7"   , new Upgrade217to218())
+                .next("2.1.7.1" , new UpgradeSnapshot217to224())
+                .next("2.1.8"   , new Upgrade218to22())
+                .next("2.1.8.1" , new Upgrade218to224DomainVlans())
+                .next("2.1.9"   , new Upgrade218to22())
+                .next("2.2.1"   , new Upgrade221to222())
+                .next("2.2.2"   , new Upgrade222to224())
+                .next("2.2.3"   , new Upgrade222to224())
+                .next("2.2.3.1" , new UpgradeSnapshot223to224())
+                .next("2.2.4"   , new Upgrade224to225())
+                .next("2.2.5"   , new Upgrade225to226())
+                .next("2.2.6"   , new Upgrade227to228())
+                .next("2.2.7"   , new Upgrade227to228())
+                .next("2.2.8"   , new Upgrade228to229())
+                .next("2.2.9"   , new Upgrade229to2210())
+                .next("2.2.10"  , new Upgrade2210to2211())
+                .next("2.2.11"  , new Upgrade2211to2212())
+                .next("2.2.12"  , new Upgrade2212to2213())
+                .next("2.2.13"  , new Upgrade2213to2214())
+                .next("2.2.14"  , new Upgrade2214to30())
+                .next("2.2.15"  , new Upgrade2214to30())
+                .next("2.2.16"  , new Upgrade2214to30())
+                .next("3.0.0"   , new Upgrade30to301())
+                .next("3.0.1"   , new Upgrade301to302())
+                .next("3.0.2"   , new Upgrade302to303())
+                .next("3.0.2.1" , new Upgrade302to40())
+                .next("3.0.3"   , new Upgrade303to304())
+                .next("3.0.4"   , new Upgrade304to305())
+                .next("3.0.5"   , new Upgrade305to306())
+                .next("3.0.6"   , new Upgrade306to307())
+                .next("3.0.7"   , new Upgrade307to410())
+
+                // recent
+                .next("4.0.0"   , new Upgrade40to41())
+                .next("4.0.1"   , new Upgrade40to41())
+                .next("4.0.2"   , new Upgrade40to41())
+                .next("4.1.0"   , new Upgrade410to420())
+                .next("4.1.1"   , new Upgrade410to420())
+                .next("4.2.0"   , new Upgrade420to421())
+                .next("4.2.1"   , new Upgrade421to430())
+                .next("4.3.0"   , new Upgrade430to440())
+                .next("4.3.1"   , new Upgrade431to440())
+                .next("4.3.2"   , new Upgrade432to440())
+                .next("4.4.0"   , new Upgrade440to441())
+                .next("4.4.1"   , new Upgrade441to442())
+                .next("4.4.2"   , new Upgrade442to450())
+                .next("4.4.3"   , new Upgrade443to444())
+                .next("4.4.4"   , new Upgrade444to450())
+                .next("4.5.0"   , new Upgrade450to451())
+                .next("4.5.1"   , new Upgrade451to452())
+                .next("4.5.2"   , new Upgrade452to453())
+                .next("4.5.3"   , new Upgrade453to460())
+                .next("4.6.0"   , new Upgrade460to461())
+                .next("4.6.1"   , new Upgrade461to470())
+                .next("4.6.2"   , new Upgrade461to470())
+                .next("4.7.0"   , new Upgrade470to471())
+                .next("4.7.1"   , new Upgrade471to480())
+                .next("4.7.2"   , new Upgrade471to480())
+                .next("4.8.0"   , new Upgrade480to481())
+                .next("4.8.1"   , new Upgrade481to490())
+                .next("4.8.2.0" , new Upgrade481to490())
+                .next("4.9.0"   , new Upgrade490to4910())
+                .next("4.9.1.0" , new Upgrade4910to4920())
+                .next("4.9.2.0" , new Upgrade4920to4930())
+                .next("4.9.3.0" , new Upgrade4930to41000())
+                .next("4.9.3.1" , new Upgrade4930to41000())
+                .next("4.10.0.0", new Upgrade41000to41100())
+                .next("4.11.0.0", new Upgrade41100to41110())
+                .next("4.11.1.0", new Upgrade41110to41120())
+                .next("4.11.2.0", new Upgrade41120to41130())
+                .next("4.11.3.0", new Upgrade41120to41200())
+                .build();
+    }
+
+    protected void runScript(Connection conn, InputStream file) {
+
+        try (InputStreamReader reader = new InputStreamReader(file)) {
+            ScriptRunner runner = new ScriptRunner(conn, false, true);
+            runner.runScript(reader);
+        } catch (IOException e) {
+            s_logger.error("Unable to read upgrade script", e);
+            throw new CloudRuntimeException("Unable to read upgrade script", e);
+        } catch (SQLException e) {
+            s_logger.error("Unable to execute upgrade script", e);
+            throw new CloudRuntimeException("Unable to execute upgrade script", e);
+        }
+
+    }
+
+    @VisibleForTesting
+    DbUpgrade[] calculateUpgradePath(final CloudStackVersion dbVersion, final CloudStackVersion currentVersion) {
+
+        checkArgument(dbVersion != null);
+        checkArgument(currentVersion != null);
+        checkArgument(currentVersion.compareTo(dbVersion) > 0);
+
+        final DbUpgrade[] upgrades = hierarchy.getPath(dbVersion, currentVersion);
+
+        // When there is no upgrade defined for the target version, we assume that there were no schema changes or
+        // data migrations required.  Based on that assumption, we add a noop DbUpgrade to the end of the list ...
+        final CloudStackVersion tailVersion = upgrades.length > 0 ? CloudStackVersion.parse(upgrades[upgrades.length - 1].getUpgradedVersion()) : dbVersion;
+
+        if (currentVersion.compareTo(tailVersion) != 0) {
+            return concat(upgrades, new NoopDbUpgrade(tailVersion, currentVersion));
+        }
+
+        return upgrades;
+
+    }
+
+    protected void upgrade(CloudStackVersion dbVersion, CloudStackVersion currentVersion) {
+        s_logger.info("Database upgrade must be performed from " + dbVersion + " to " + currentVersion);
+
+        final DbUpgrade[] upgrades = calculateUpgradePath(dbVersion, currentVersion);
+
+        for (DbUpgrade upgrade : upgrades) {
+            VersionVO version;
+            s_logger.debug("Running upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade
+                .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion());
+            TransactionLegacy txn = TransactionLegacy.open("Upgrade");
+            txn.start();
+            try {
+                Connection conn;
+                try {
+                    conn = txn.getConnection();
+                } catch (SQLException e) {
+                    String errorMessage = "Unable to upgrade the database";
+                    s_logger.error(errorMessage, e);
+                    throw new CloudRuntimeException(errorMessage, e);
+                }
+                InputStream[] scripts = upgrade.getPrepareScripts();
+                if (scripts != null) {
+                    for (InputStream script : scripts) {
+                        runScript(conn, script);
+                    }
+                }
+
+                upgrade.performDataMigration(conn);
+
+                version = new VersionVO(upgrade.getUpgradedVersion());
+                version = _dao.persist(version);
+
+                txn.commit();
+            } catch (CloudRuntimeException e) {
+                String errorMessage = "Unable to upgrade the database";
+                s_logger.error(errorMessage, e);
+                throw new CloudRuntimeException(errorMessage, e);
+            } finally {
+                txn.close();
+            }
+
+            // Run the corresponding '-cleanup.sql' script
+            txn = TransactionLegacy.open("Cleanup");
+            try {
+                s_logger.info("Cleanup upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade
+                    .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion());
+
+                txn.start();
+                Connection conn;
+                try {
+                    conn = txn.getConnection();
+                } catch (SQLException e) {
+                    s_logger.error("Unable to cleanup the database", e);
+                    throw new CloudRuntimeException("Unable to cleanup the database", e);
+                }
+
+                InputStream[] scripts = upgrade.getCleanupScripts();
+                if (scripts != null) {
+                    for (InputStream script : scripts) {
+                        runScript(conn, script);
+                        s_logger.debug("Cleanup script " + upgrade.getClass().getSimpleName() + " is executed successfully");
+                    }
+                }
+                txn.commit();
+
+                txn.start();
+                version.setStep(Step.Complete);
+                version.setUpdated(new Date());
+                _dao.update(version.getId(), version);
+                txn.commit();
+                s_logger.debug("Upgrade completed for version " + version.getVersion());
+            } finally {
+                txn.close();
+            }
+        }
+    }
+
+    @Override
+    public void check() {
+        GlobalLock lock = GlobalLock.getInternLock("DatabaseUpgrade");
+        try {
+            s_logger.info("Grabbing lock to check for database upgrade.");
+            if (!lock.lock(20 * 60)) {
+                throw new CloudRuntimeException("Unable to acquire lock to check for database integrity.");
+            }
+
+            try {
+
+                final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
+                final String currentVersionValue = this.getClass().getPackage().getImplementationVersion();
+
+                if (StringUtils.isBlank(currentVersionValue)) {
+                    return;
+                }
+
+                final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
+                s_logger.info("DB version = " + dbVersion + " Code Version = " + currentVersion);
+
+                if (dbVersion.compareTo(currentVersion) > 0) {
+                    throw new CloudRuntimeException("Database version " + dbVersion + " is higher than management software version " + currentVersionValue);
+                }
+
+                if (dbVersion.compareTo(currentVersion) == 0) {
+                    s_logger.info("DB version and code version matches so no upgrade needed.");
+                    return;
+                }
+
+                upgrade(dbVersion, currentVersion);
+            } finally {
+                lock.unlock();
+            }
+        } finally {
+            lock.releaseRef();
+        }
+    }
+
+    @VisibleForTesting
+    protected static final class NoopDbUpgrade implements DbUpgrade {
+
+        private final String upgradedVersion;
+        private final String[] upgradeRange;
+
+        private NoopDbUpgrade(final CloudStackVersion fromVersion, final CloudStackVersion toVersion) {
+
+            super();
+
+            upgradedVersion = toVersion.toString();
+            upgradeRange = new String[] {fromVersion.toString(), toVersion.toString()};
+
+        }
+
+        @Override
+        public String[] getUpgradableVersionRange() {
+            return Arrays.copyOf(upgradeRange, upgradeRange.length);
+        }
+
+        @Override
+        public String getUpgradedVersion() {
+            return upgradedVersion;
+        }
+
+        @Override
+        public boolean supportsRollingUpgrade() {
+            return false;
+        }
+
+        @Override
+        public InputStream[] getPrepareScripts() {
+            return new InputStream[0];
+        }
+
+        @Override
+        public void performDataMigration(Connection conn) {
+
+        }
+
+        @Override
+        public InputStream[] getCleanupScripts() {
+            return new InputStream[0];
+        }
+
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java
new file mode 100644
index 0000000..35b2faa
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseVersionHierarchy.java
@@ -0,0 +1,186 @@
+// 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.upgrade;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.ImmutableList;
+
+import org.apache.cloudstack.utils.CloudStackVersion;
+
+import com.cloud.upgrade.dao.DbUpgrade;
+
+/**
+ * @since 4.12.0.0
+ */
+public final class DatabaseVersionHierarchy {
+    private final ImmutableList<VersionNode> hierarchy;
+
+    private DatabaseVersionHierarchy(ImmutableList<VersionNode> hierarchy) {
+        this.hierarchy = hierarchy;
+    }
+
+    public static DatabaseVersionHierarchyBuilder builder() {
+        return new DatabaseVersionHierarchyBuilder();
+    }
+
+    /**
+     * Check if current hierarchy of Database Versions contains <code>version</code>.
+     *
+     * @param version The version to check if hierarchy contains it
+     *
+     * @return true if hierarchy contains the version, false if not
+     */
+    public boolean contains(final CloudStackVersion version) {
+        return toList().contains(version);
+    }
+
+    /**
+     * Calculates an  upgrade path for the  passed <code>fromVersion</code>.  If the  <code>fromVersion</code>
+     * doesn't exist in list  of  available <code>VersionNode</code> hierarchy,  then calculation assumes that
+     * the <code>fromVersion</code> required no schema migrations or data conversions and no  upgrade path was
+     * defined  for it.  Therefore,  we  find  the most  recent  version  with  database migrations before the
+     * <code>fromVersion</code> and adopt that upgrade path list.
+     *
+     * @param fromVersion The version from which the upgrade will occur
+     *
+     * @return The upgrade path from <code>fromVersion</code> to <code>LATEST</code> version.
+     */
+    public DbUpgrade[] getPath(final CloudStackVersion fromVersion) {
+        return getPath(fromVersion, null);
+    }
+
+    /**
+     * Calculates an  upgrade path for the  passed <code>fromVersion</code> and <code>toVersion</code>. If the
+     * <code>fromVersion</code> doesn't exist in list  of available <code>VersionNode</code> hierarchy,   then
+     * calculation assumes that the <code>fromVersion</code> required no schema migrations or data conversions
+     * and no  upgrade path was defined  for it.  Therefore, we find  the most recent  version  with  database
+     * migrations before the <code>fromVersion</code> and adopt that upgrade path list up to <code>toVersion</code>.
+     * If <code>toVersion</code> is null, we're going to find the upgrade path up to the latest available version.
+     *
+     * @param fromVersion The version from which the upgrade will occur
+     * @param toVersion The version up to which the upgrade will occur (can be null)
+     *
+     * @return The upgrade path from <code>fromVersion</code> to <code>toVersion</code>
+     */
+    public DbUpgrade[] getPath(final CloudStackVersion fromVersion, final CloudStackVersion toVersion) {
+        if (fromVersion == null) {
+            return new DbUpgrade[0];
+        }
+
+        // we cannot find the version specified, so get the
+        // most recent one immediately before this version
+        if (!contains(fromVersion)) {
+            return getPath(getRecentVersion(fromVersion), toVersion);
+        }
+
+        final Predicate<? super VersionNode> predicate;
+
+        if (toVersion == null) {
+            // all the available versions greater than or equal to fromVersion
+            predicate = node -> node.version.compareTo(fromVersion) > -1;
+        } else {
+            // all the available versions greater than or equal to fromVersion AND less than toVersion
+            predicate = node -> node.version.compareTo(fromVersion) > -1 && node.version.compareTo(toVersion) < 0;
+        }
+
+        // get upgrade path from version forward (include version itself in the path)
+        return hierarchy
+                    .stream()
+                    .filter(predicate)
+                    .filter(distinct(node -> node.upgrader.getUpgradedVersion()))
+                    .map(node -> node.upgrader)
+                    .toArray(DbUpgrade[]::new);
+    }
+
+    /**
+     * Find the most recent <code>CloudStackVersion</code> immediately before <code>fromVersion</code>
+     *
+     * @param fromVersion The version to look up its immediate previous available version
+     *
+     * @return The <code>CloudStackVersion</code> or null
+     *
+     * @since 4.8.2.0 (refactored in 4.11.1.0)
+     */
+    private CloudStackVersion getRecentVersion(final CloudStackVersion fromVersion) {
+        if (fromVersion == null) {
+            return null;
+        }
+
+        // find the most recent version immediately before fromVersion
+        return toList()
+                 .reverse()
+                 .stream()
+                 .filter(version -> fromVersion.compareTo(version) < 0)
+                 .findFirst()
+                 .orElse(null);
+    }
+
+    /**
+     * Generate immutable list of available <code>CloudstackVersion</code> in the hierarchy
+     *
+     * @return list of available versions
+     */
+    public ImmutableList<CloudStackVersion> toList() {
+        List<CloudStackVersion> versions = hierarchy
+                                                .stream()
+                                                .map(node -> node.version)
+                                                .collect(Collectors.toList());
+
+        return ImmutableList.copyOf(versions);
+    }
+
+    /**
+     * Find the distinct <code>VersionNode</code> based on the provided <code>getUpgradedVersion()</code>
+     */
+    private Predicate<VersionNode> distinct(Function<VersionNode, String> keyExtractor) {
+        Map<String, Boolean> seen = new ConcurrentHashMap<>();
+        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
+    }
+
+    private static class VersionNode {
+        final CloudStackVersion version;
+        final DbUpgrade upgrader;
+
+        private VersionNode(final CloudStackVersion version, final DbUpgrade upgrader) {
+            this.version = version;
+            this.upgrader = upgrader;
+        }
+    }
+
+    public static final class DatabaseVersionHierarchyBuilder {
+        private final List<VersionNode> hierarchyBuilder = new LinkedList<>();
+
+        private DatabaseVersionHierarchyBuilder() {
+        }
+
+        public DatabaseVersionHierarchyBuilder next(final String version, final DbUpgrade upgrader) {
+            hierarchyBuilder.add(new VersionNode(CloudStackVersion.parse(version), upgrader));
+            return this;
+        }
+
+        public DatabaseVersionHierarchy build() {
+            return new DatabaseVersionHierarchy(ImmutableList.copyOf(hierarchyBuilder));
+        }
+    }
+}
\ No newline at end of file
diff --git a/engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/DatabaseAccessObject.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/DatabaseAccessObject.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/DbUpgrade.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgrade.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/DbUpgrade.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgrade.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/DbUpgradeUtils.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/DbUpgradeUtils.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/DbUpgradeUtils.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/LegacyDbUpgrade.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/LegacyDbUpgrade.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/LegacyDbUpgrade.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/LegacyDbUpgrade.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade217to218.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade217to218.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade217to218.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade217to218.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to22.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to22.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to224DomainVlans.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to22Premium.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade218to22Premium.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade218to22Premium.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2210to2211.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2210to2211.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade2210to2211.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2210to2211.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2211to2212.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2211to2212.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2211to2212Premium.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2212to2213.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2212to2213.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade2212to2213.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2212to2213.java
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2213to2214.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2213to2214.java
new file mode 100644
index 0000000..9dc3f5b
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2213to2214.java
@@ -0,0 +1,276 @@
+// 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.upgrade.dao;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class Upgrade2213to2214 implements DbUpgrade {
+    final static Logger s_logger = Logger.getLogger(Upgrade2213to2214.class);
+
+    @Override
+    public String[] getUpgradableVersionRange() {
+        return new String[] {"2.2.13", "2.2.14"};
+    }
+
+    @Override
+    public String getUpgradedVersion() {
+        return "2.2.14";
+    }
+
+    @Override
+    public boolean supportsRollingUpgrade() {
+        return true;
+    }
+
+    @Override
+    public InputStream[] getPrepareScripts() {
+        final String scriptFile = "META-INF/db/schema-2213to2214.sql";
+        final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
+        if (script == null) {
+            throw new CloudRuntimeException("Unable to find " + scriptFile);
+        }
+
+        return new InputStream[] {script};
+    }
+
+    @Override
+    public void performDataMigration(Connection conn) {
+        fixIndexes(conn);
+    }
+
+    @Override
+    public InputStream[] getCleanupScripts() {
+        return null;
+    }
+
+    private void fixIndexes(Connection conn) {
+        //Drop i_usage_event__created key (if exists) and re-add it again
+        List<String> keys = new ArrayList<String>();
+        keys.add("i_usage_event__created");
+        DbUpgradeUtils.dropKeysIfExist(conn, "usage_event", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`usage_event` ADD INDEX `i_usage_event__created`(`created`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute usage_event table update", e);
+        }
+
+        //In cloud_usage DB, drop i_usage_event__created key (if exists) and re-add it again
+        keys = new ArrayList<String>();
+        keys.add("i_usage_event__created");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud_usage.usage_event", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud_usage`.`usage_event` ADD INDEX `i_usage_event__created`(`created`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute cloud_usage usage_event table update", e);
+        }
+
+        //Drop i_snapshots__removed key (if exists) and re-add it again
+        keys = new ArrayList<String>();
+        keys.add("i_snapshots__removed");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.snapshots", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`snapshots` ADD INDEX `i_snapshots__removed`(`removed`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert index for removed column in snapshots", e);
+        }
+        //Drop i_op_vm_ruleset_log__instance_id, u_op_vm_ruleset_log__instance_id key (if exists) and re-add u_op_vm_ruleset_log__instance_id again
+        keys = new ArrayList<String>();
+        keys.add("i_op_vm_ruleset_log__instance_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.op_vm_ruleset_log", keys, false);
+
+        keys = new ArrayList<String>();
+        keys.add("u_op_vm_ruleset_log__instance_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.op_vm_ruleset_log", keys, false);
+        try {
+            PreparedStatement pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`op_vm_ruleset_log` ADD CONSTRAINT `u_op_vm_ruleset_log__instance_id` UNIQUE (`instance_id`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute changes for op_vm_ruleset_log", e);
+        }
+
+        //Drop i_async__removed, i_async_job__removed  (if exists) and add i_async_job__removed
+        keys = new ArrayList<String>();
+        keys.add("i_async__removed");
+        keys.add("i_async_job__removed");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.async_job", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`async_job` ADD INDEX `i_async_job__removed`(`removed`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e);
+        }
+
+        keys = new ArrayList<String>();
+        keys.add("fk_ssh_keypair__account_id");
+        keys.add("fk_ssh_keypair__domain_id");
+        keys.add("fk_ssh_keypairs__account_id");
+        keys.add("fk_ssh_keypairs__domain_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, true);
+
+        keys = new ArrayList<String>();
+        keys.add("fk_ssh_keypair__account_id");
+        keys.add("fk_ssh_keypair__domain_id");
+        keys.add("fk_ssh_keypairs__account_id");
+        keys.add("fk_ssh_keypairs__domain_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "ssh_keypairs", keys, false);
+
+        try {
+            PreparedStatement pstmt;
+            pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__account_id` FOREIGN KEY `fk_ssh_keypairs__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding account_id foreign key", e);
+        }
+
+        try {
+            PreparedStatement pstmt;
+            pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__domain_id` FOREIGN KEY `fk_ssh_keypairs__domain_id` (`domain_id`) REFERENCES `domain` (`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding domain_id foreign key", e);
+        }
+
+        //Drop i_async__removed, i_async_job__removed  (if exists) and add i_async_job__removed
+        keys = new ArrayList<String>();
+        keys.add("i_async__removed");
+        keys.add("i_async_job__removed");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.async_job", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`async_job` ADD INDEX `i_async_job__removed`(`removed`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert index for removed column in async_job", e);
+        }
+
+        //Drop storage pool details keys (if exists) and insert one with correct name
+        keys = new ArrayList<String>();
+        keys.add("fk_storage_pool__pool_id");
+        keys.add("fk_storage_pool_details__pool_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.storage_pool_details", keys, true);
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.storage_pool_details", keys, false);
+        try {
+            PreparedStatement pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`storage_pool_details` ADD CONSTRAINT `fk_storage_pool_details__pool_id` FOREIGN KEY `fk_storage_pool_details__pool_id`(`pool_id`) REFERENCES `storage_pool`(`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert foreign key in storage_pool_details ", e);
+        }
+
+        //Drop securityGroup keys (if exists) and insert one with correct name
+        keys = new ArrayList<String>();
+        keys.add("fk_security_group___account_id");
+        keys.add("fk_security_group__account_id");
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.security_group", keys, true);
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.security_group", keys, false);
+        try {
+            PreparedStatement pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`security_group` ADD CONSTRAINT `fk_security_group__account_id` FOREIGN KEY `fk_security_group__account_id` (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert foreign key in security_group table ", e);
+        }
+
+        //Drop vmInstance keys (if exists) and insert one with correct name
+        keys = new ArrayList<String>();
+        keys.add("i_vm_instance__host_id");
+        keys.add("fk_vm_instance__host_id");
+
+        keys.add("fk_vm_instance__last_host_id");
+        keys.add("i_vm_instance__last_host_id");
+
+        keys.add("fk_vm_instance__service_offering_id");
+        keys.add("i_vm_instance__service_offering_id");
+
+        keys.add("fk_vm_instance__account_id");
+        keys.add("i_vm_instance__account_id");
+
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, true);
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.vm_instance", keys, false);
+        try {
+            PreparedStatement pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY (`host_id`) REFERENCES `host` (`id`)");
+            pstmt.executeUpdate();
+            pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__last_host_id` FOREIGN KEY (`last_host_id`) REFERENCES `host` (`id`)");
+            pstmt.executeUpdate();
+            pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`)");
+            pstmt.executeUpdate();
+            pstmt =
+                conn.prepareStatement("ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY (`service_offering_id`) REFERENCES `service_offering` (`id`)");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert foreign key in vm_instance table ", e);
+        }
+
+        //Drop user_ip_address keys (if exists) and insert one with correct name
+        keys = new ArrayList<String>();
+        keys.add("fk_user_ip_address__account_id");
+        keys.add("i_user_ip_address__account_id");
+
+        keys.add("fk_user_ip_address__vlan_db_id");
+        keys.add("i_user_ip_address__vlan_db_id");
+
+        keys.add("fk_user_ip_address__data_center_id");
+        keys.add("i_user_ip_address__data_center_id");
+
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, true);
+        DbUpgradeUtils.dropKeysIfExist(conn, "cloud.user_ip_address", keys, false);
+        try {
+            PreparedStatement pstmt = conn.prepareStatement(
+                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`)");
+            pstmt.executeUpdate();
+            pstmt = conn.prepareStatement(
+                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__vlan_db_id` FOREIGN KEY (`vlan_db_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt = conn.prepareStatement(
+                "ALTER TABLE `cloud`.`user_ip_address` ADD CONSTRAINT `fk_user_ip_address__data_center_id`" +
+                    " FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE");
+            pstmt.executeUpdate();
+            pstmt.close();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to insert foreign key in vm_instance table ", e);
+        }
+
+    }
+}
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade2214to30.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2214to30.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade2214to30.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2214to30.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade221to222.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade221to222.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade221to222Premium.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade221to222Premium.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade221to222Premium.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade222to224.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade222to224.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade222to224Premium.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade222to224Premium.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade222to224Premium.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade224to225.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade224to225.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade224to225.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade224to225.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade225to226.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade225to226.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade225to226.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade225to226.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade227to228.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade227to228.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade227to228Premium.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade227to228Premium.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade227to228Premium.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade228to229.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade228to229.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade228to229.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade228to229.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade229to2210.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade229to2210.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade229to2210.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade229to2210.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade301to302.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade301to302.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade301to302.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade301to302.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to303.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade302to303.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade302to303.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade302to303.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade302to40.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade302to40.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade302to40.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade303to304.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade303to304.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade303to304.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade303to304.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade304to305.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade304to305.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade304to305.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade304to305.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade305to306.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade305to306.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade305to306.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade305to306.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade306to307.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade306to307.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade306to307.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade306to307.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade307to410.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade307to410.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade307to410.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade30to301.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade30to301.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade30to301.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade30to301.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade30xBase.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade30xBase.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade30xBase.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade30xBase.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade40to41.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade40to41.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade40to41.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade40to41.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41000to41100.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41000to41100.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade410to420.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade410to420.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41100to41110.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41100to41110.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade41100to41110.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41100to41110.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41110to41120.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41110to41120.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade41110to41120.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41110to41120.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41120to41130.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41120to41130.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade41120to41130.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41120to41130.java
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41120to41200.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41120to41200.java
new file mode 100644
index 0000000..f68f04a
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41120to41200.java
@@ -0,0 +1,81 @@
+// 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.upgrade.dao;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.log4j.Logger;
+
+public class Upgrade41120to41200 implements DbUpgrade {
+
+    final static Logger LOG = Logger.getLogger(Upgrade41120to41200.class);
+
+    @Override
+    public String[] getUpgradableVersionRange() {
+        return new String[] {"4.11.2.0", "4.12.0.0"};
+    }
+
+    @Override
+    public String getUpgradedVersion() {
+        return "4.12.0.0";
+    }
+
+    @Override
+    public boolean supportsRollingUpgrade() {
+        return false;
+    }
+
+    @Override
+    public InputStream[] getPrepareScripts() {
+        final String scriptFile = "META-INF/db/schema-41120to41200.sql";
+        final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
+        if (script == null) {
+            throw new CloudRuntimeException("Unable to find " + scriptFile);
+        }
+
+        return new InputStream[] {script};
+    }
+
+    @Override
+    public void performDataMigration(Connection conn) {
+        updateManagementServerHostUuid(conn);
+    }
+
+    private void updateManagementServerHostUuid(Connection conn) {
+        try (final PreparedStatement updateStatement = conn.prepareStatement("UPDATE cloud.mshost SET uuid=UUID()")) {
+            updateStatement.executeUpdate();
+        } catch (SQLException e) {
+            LOG.error("Failed to add an UUID to each management server.", e);
+        }
+    }
+
+    @Override
+    public InputStream[] getCleanupScripts() {
+        final String scriptFile = "META-INF/db/schema-41120to41200-cleanup.sql";
+        final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
+        if (script == null) {
+            throw new CloudRuntimeException("Unable to find " + scriptFile);
+        }
+
+        return new InputStream[] {script};
+    }
+}
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade420to421.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade420to421.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade420to421.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade421to430.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade421to430.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade430to440.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade430to440.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade431to440.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade431to440.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade431to440.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade431to440.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade432to440.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade432to440.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade432to440.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade432to440.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade440to441.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade440to441.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade440to441.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade440to441.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade441to442.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade441to442.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade441to442.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade441to442.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade442to450.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade442to450.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade442to450.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade442to450.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade443to444.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade443to444.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade443to444.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade443to444.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade443to450.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade443to450.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade443to450.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade443to450.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade444to450.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade444to450.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade444to450.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade444to450.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade450to451.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade450to451.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade450to451.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade450to451.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade451to452.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade451to452.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade451to452.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade451to452.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade452to453.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade452to453.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade452to453.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade452to453.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade452to460.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade452to460.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade452to460.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade452to460.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade453to460.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade453to460.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade453to460.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade453to460.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade460to461.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade460to461.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade460to461.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade460to461.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade461to470.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade461to470.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade461to470.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade461to470.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade470to471.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade470to471.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade470to471.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade470to471.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade471to480.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade471to480.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade471to480.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade471to480.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade480to481.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade480to481.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade480to481.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade480to481.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade481to490.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade481to490.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade481to490.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade481to490.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade490to4910.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade490to4910.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade490to4910.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade490to4910.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade4910to4920.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4910to4920.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade4910to4920.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4910to4920.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade4920to4930.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4920to4930.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade4920to4930.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4920to4930.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade4930to41000.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4930to41000.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade4930to41000.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade4930to41000.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/UpgradeSnapshot217to224.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/UpgradeSnapshot223to224.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/VersionDao.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/VersionDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/VersionDao.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/VersionDao.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/VersionDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/VersionDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/VersionDaoImpl.java
diff --git a/engine/schema/src/com/cloud/upgrade/dao/VersionVO.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/VersionVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/upgrade/dao/VersionVO.java
rename to engine/schema/src/main/java/com/cloud/upgrade/dao/VersionVO.java
diff --git a/engine/schema/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java b/engine/schema/src/main/java/com/cloud/usage/ExternalPublicIpStatisticsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/ExternalPublicIpStatisticsVO.java
rename to engine/schema/src/main/java/com/cloud/usage/ExternalPublicIpStatisticsVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageIPAddressVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageIPAddressVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageIPAddressVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageIPAddressVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageJobVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageJobVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageJobVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageJobVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageLoadBalancerPolicyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageLoadBalancerPolicyVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageLoadBalancerPolicyVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageNetworkOfferingVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworkOfferingVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageNetworkOfferingVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageNetworkOfferingVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageNetworkVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageNetworkVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageNetworkVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsagePortForwardingRuleVO.java b/engine/schema/src/main/java/com/cloud/usage/UsagePortForwardingRuleVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsagePortForwardingRuleVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsagePortForwardingRuleVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageSecurityGroupVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageSecurityGroupVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageSecurityGroupVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageSecurityGroupVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageSnapshotOnPrimaryVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageStorageVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageStorageVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageStorageVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageStorageVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVMInstanceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVMInstanceVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVMInstanceVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVPNUserVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVPNUserVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVPNUserVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVPNUserVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVmDiskVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVmDiskVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVmDiskVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVmDiskVO.java
diff --git a/engine/schema/src/com/cloud/usage/UsageVolumeVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/UsageVolumeVO.java
rename to engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java
diff --git a/engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/ExternalPublicIpStatisticsDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/ExternalPublicIpStatisticsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageDao.java
diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageDaoImpl.java
new file mode 100644
index 0000000..3bdf79a
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageDaoImpl.java
@@ -0,0 +1,515 @@
+// 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.usage.dao;
+
+import com.cloud.usage.UsageVO;
+import com.cloud.user.AccountVO;
+import com.cloud.user.UserStatisticsVO;
+import com.cloud.user.VmDiskStatisticsVO;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+@Component
+public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements UsageDao {
+    public static final Logger s_logger = Logger.getLogger(UsageDaoImpl.class.getName());
+    private static final String DELETE_ALL = "DELETE FROM cloud_usage";
+    private static final String DELETE_ALL_BY_ACCOUNTID = "DELETE FROM cloud_usage WHERE account_id = ?";
+    private static final String DELETE_ALL_BY_INTERVAL = "DELETE FROM cloud_usage WHERE end_date < DATE_SUB(CURRENT_DATE(), INTERVAL ? DAY)";
+    private static final String INSERT_ACCOUNT = "INSERT INTO cloud_usage.account (id, account_name, type, role_id, domain_id, removed, cleanup_needed) VALUES (?,?,?,?,?,?,?)";
+    private static final String INSERT_USER_STATS = "INSERT INTO cloud_usage.user_statistics (id, data_center_id, account_id, public_ip_address, device_id, device_type, network_id, net_bytes_received,"
+            + " net_bytes_sent, current_bytes_received, current_bytes_sent, agg_bytes_received, agg_bytes_sent) VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?)";
+
+    private static final String UPDATE_ACCOUNT = "UPDATE cloud_usage.account SET account_name=?, removed=? WHERE id=?";
+    private static final String UPDATE_USER_STATS = "UPDATE cloud_usage.user_statistics SET net_bytes_received=?, net_bytes_sent=?, current_bytes_received=?, current_bytes_sent=?, agg_bytes_received=?, agg_bytes_sent=? WHERE id=?";
+
+    private static final String GET_LAST_ACCOUNT = "SELECT id FROM cloud_usage.account ORDER BY id DESC LIMIT 1";
+    private static final String GET_LAST_USER_STATS = "SELECT id FROM cloud_usage.user_statistics ORDER BY id DESC LIMIT 1";
+    private static final String GET_PUBLIC_TEMPLATES_BY_ACCOUNTID = "SELECT id FROM cloud.vm_template WHERE account_id = ? AND public = '1' AND removed IS NULL";
+
+    private static final String GET_LAST_VM_DISK_STATS = "SELECT id FROM cloud_usage.vm_disk_statistics ORDER BY id DESC LIMIT 1";
+    private static final String INSERT_VM_DISK_STATS = "INSERT INTO cloud_usage.vm_disk_statistics (id, data_center_id, account_id, vm_id, volume_id, net_io_read, net_io_write, current_io_read, "
+            + "current_io_write, agg_io_read, agg_io_write, net_bytes_read, net_bytes_write, current_bytes_read, current_bytes_write, agg_bytes_read, agg_bytes_write) "
+            + " VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)";
+    private static final String UPDATE_VM_DISK_STATS = "UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, "
+            + "net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=?  WHERE id=?";
+    private static final String INSERT_USAGE_RECORDS = "INSERT INTO cloud_usage.cloud_usage (zone_id, account_id, domain_id, description, usage_display, "
+            + "usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, "
+            + "usage_id, type, size, network_id, start_date, end_date, virtual_size) VALUES (?,?,?,?,?,?,?,?,?, ?, ?, ?,?,?,?,?,?,?)";
+
+    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
+
+    public UsageDaoImpl() {
+    }
+
+    @Override
+    public void deleteRecordsForAccount(Long accountId) {
+        String sql = ((accountId == null) ? DELETE_ALL : DELETE_ALL_BY_ACCOUNTID);
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            if (accountId != null) {
+                pstmt.setLong(1, accountId.longValue());
+            }
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error retrieving usage vm instances for account id: " + accountId, ex);
+        } finally {
+            txn.close();
+        }
+    }
+
+    @Override
+    public Pair<List<UsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<UsageVO> sc, Filter filter) {
+        return listAndCountIncludingRemovedBy(sc, filter);
+    }
+
+    @Override
+    public void saveAccounts(List<AccountVO> accounts) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = INSERT_ACCOUNT;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (AccountVO acct : accounts) {
+                pstmt.setLong(1, acct.getId());
+                pstmt.setString(2, acct.getAccountName());
+                pstmt.setShort(3, acct.getType());
+
+                //prevent autoboxing NPE by defaulting to User role
+                if(acct.getRoleId() == null){
+                    pstmt.setLong(4, RoleType.User.getId());
+                }else{
+                    pstmt.setLong(4, acct.getRoleId());
+                }
+
+                pstmt.setLong(5, acct.getDomainId());
+
+                Date removed = acct.getRemoved();
+                if (removed == null) {
+                    pstmt.setString(6, null);
+                } else {
+                    pstmt.setString(6, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), acct.getRemoved()));
+                }
+
+                pstmt.setBoolean(7, acct.getNeedsCleanup());
+
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error saving account to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    @Override
+    public void updateAccounts(List<AccountVO> accounts) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = UPDATE_ACCOUNT;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (AccountVO acct : accounts) {
+                pstmt.setString(1, acct.getAccountName());
+
+                Date removed = acct.getRemoved();
+                if (removed == null) {
+                    pstmt.setString(2, null);
+                } else {
+                    pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), acct.getRemoved()));
+                }
+
+                pstmt.setLong(3, acct.getId());
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error updating account to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    @Override
+    public void saveUserStats(List<UserStatisticsVO> userStats) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = INSERT_USER_STATS;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (UserStatisticsVO userStat : userStats) {
+                pstmt.setLong(1, userStat.getId());
+                pstmt.setLong(2, userStat.getDataCenterId());
+                pstmt.setLong(3, userStat.getAccountId());
+                pstmt.setString(4, userStat.getPublicIpAddress());
+                if (userStat.getDeviceId() != null) {
+                    pstmt.setLong(5, userStat.getDeviceId());
+                } else {
+                    pstmt.setNull(5, Types.BIGINT);
+                }
+                pstmt.setString(6, userStat.getDeviceType());
+                if (userStat.getNetworkId() != null) {
+                    pstmt.setLong(7, userStat.getNetworkId());
+                } else {
+                    pstmt.setNull(7, Types.BIGINT);
+                }
+                pstmt.setLong(8, userStat.getNetBytesReceived());
+                pstmt.setLong(9, userStat.getNetBytesSent());
+                pstmt.setLong(10, userStat.getCurrentBytesReceived());
+                pstmt.setLong(11, userStat.getCurrentBytesSent());
+                pstmt.setLong(12, userStat.getAggBytesReceived());
+                pstmt.setLong(13, userStat.getAggBytesSent());
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error saving user stats to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    @Override
+    public void updateUserStats(List<UserStatisticsVO> userStats) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = UPDATE_USER_STATS;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (UserStatisticsVO userStat : userStats) {
+                pstmt.setLong(1, userStat.getNetBytesReceived());
+                pstmt.setLong(2, userStat.getNetBytesSent());
+                pstmt.setLong(3, userStat.getCurrentBytesReceived());
+                pstmt.setLong(4, userStat.getCurrentBytesSent());
+                pstmt.setLong(5, userStat.getAggBytesReceived());
+                pstmt.setLong(6, userStat.getAggBytesSent());
+                pstmt.setLong(7, userStat.getId());
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error updating user stats to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    @Override
+    public Long getLastAccountId() {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = GET_LAST_ACCOUNT;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                return Long.valueOf(rs.getLong(1));
+            }
+        } catch (Exception ex) {
+            s_logger.error("error getting last account id", ex);
+        }
+        return null;
+    }
+
+    @Override
+    public Long getLastUserStatsId() {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = GET_LAST_USER_STATS;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                return Long.valueOf(rs.getLong(1));
+            }
+        } catch (Exception ex) {
+            s_logger.error("error getting last user stats id", ex);
+        }
+        return null;
+    }
+
+    @Override
+    public List<Long> listPublicTemplatesByAccount(long accountId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = GET_PUBLIC_TEMPLATES_BY_ACCOUNTID;
+        List<Long> templateList = new ArrayList<Long>();
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, accountId);
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                templateList.add(Long.valueOf(rs.getLong(1)));
+            }
+        } catch (Exception ex) {
+            s_logger.error("error listing public templates", ex);
+        }
+        return templateList;
+    }
+
+    @Override
+    public Long getLastVmDiskStatsId() {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = GET_LAST_VM_DISK_STATS;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            ResultSet rs = pstmt.executeQuery();
+            if (rs.next()) {
+                return Long.valueOf(rs.getLong(1));
+            }
+        } catch (Exception ex) {
+            s_logger.error("error getting last vm disk stats id", ex);
+        }
+        return null;
+    }
+
+    @Override
+    public void updateVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = UPDATE_VM_DISK_STATS;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
+                pstmt.setLong(1, vmDiskStat.getNetIORead());
+                pstmt.setLong(2, vmDiskStat.getNetIOWrite());
+                pstmt.setLong(3, vmDiskStat.getCurrentIORead());
+                pstmt.setLong(4, vmDiskStat.getCurrentIOWrite());
+                pstmt.setLong(5, vmDiskStat.getAggIORead());
+                pstmt.setLong(6, vmDiskStat.getAggIOWrite());
+                pstmt.setLong(7, vmDiskStat.getNetBytesRead());
+                pstmt.setLong(8, vmDiskStat.getNetBytesWrite());
+                pstmt.setLong(9, vmDiskStat.getCurrentBytesRead());
+                pstmt.setLong(10, vmDiskStat.getCurrentBytesWrite());
+                pstmt.setLong(11, vmDiskStat.getAggBytesRead());
+                pstmt.setLong(12, vmDiskStat.getAggBytesWrite());
+                pstmt.setLong(13, vmDiskStat.getId());
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error updating vm disk stats to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+
+    }
+
+    @Override
+    public void saveVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = INSERT_VM_DISK_STATS;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
+                pstmt.setLong(1, vmDiskStat.getId());
+                pstmt.setLong(2, vmDiskStat.getDataCenterId());
+                pstmt.setLong(3, vmDiskStat.getAccountId());
+                if (vmDiskStat.getVmId() != null) {
+                    pstmt.setLong(4, vmDiskStat.getVmId());
+                } else {
+                    pstmt.setNull(4, Types.BIGINT);
+                }
+                if (vmDiskStat.getVolumeId() != null) {
+                    pstmt.setLong(5, vmDiskStat.getVolumeId());
+                } else {
+                    pstmt.setNull(5, Types.BIGINT);
+                }
+                pstmt.setLong(6, vmDiskStat.getNetIORead());
+                pstmt.setLong(7, vmDiskStat.getNetIOWrite());
+                pstmt.setLong(8, vmDiskStat.getCurrentIORead());
+                pstmt.setLong(9, vmDiskStat.getCurrentIOWrite());
+                pstmt.setLong(10, vmDiskStat.getAggIORead());
+                pstmt.setLong(11, vmDiskStat.getAggIOWrite());
+                pstmt.setLong(12, vmDiskStat.getNetBytesRead());
+                pstmt.setLong(13, vmDiskStat.getNetBytesWrite());
+                pstmt.setLong(14, vmDiskStat.getCurrentBytesRead());
+                pstmt.setLong(15, vmDiskStat.getCurrentBytesWrite());
+                pstmt.setLong(16, vmDiskStat.getAggBytesRead());
+                pstmt.setLong(17, vmDiskStat.getAggBytesWrite());
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error saving vm disk stats to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+
+    }
+
+    @Override
+    public void saveUsageRecords(List<UsageVO> usageRecords) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+            String sql = INSERT_USAGE_RECORDS;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
+            for (UsageVO usageRecord : usageRecords) {
+                pstmt.setLong(1, usageRecord.getZoneId());
+                pstmt.setLong(2, usageRecord.getAccountId());
+                pstmt.setLong(3, usageRecord.getDomainId());
+                pstmt.setString(4, usageRecord.getDescription());
+                pstmt.setString(5, usageRecord.getUsageDisplay());
+                pstmt.setInt(6, usageRecord.getUsageType());
+                pstmt.setDouble(7, usageRecord.getRawUsage());
+                if (usageRecord.getVmInstanceId() != null) {
+                    pstmt.setLong(8, usageRecord.getVmInstanceId());
+                } else {
+                    pstmt.setNull(8, Types.BIGINT);
+                }
+                pstmt.setString(9, usageRecord.getVmName());
+                if (usageRecord.getOfferingId() != null) {
+                    pstmt.setLong(10, usageRecord.getOfferingId());
+                } else {
+                    pstmt.setNull(10, Types.BIGINT);
+                }
+                if (usageRecord.getTemplateId() != null) {
+                    pstmt.setLong(11, usageRecord.getTemplateId());
+                } else {
+                    pstmt.setNull(11, Types.BIGINT);
+                }
+                if (usageRecord.getUsageId() != null) {
+                    pstmt.setLong(12, usageRecord.getUsageId());
+                } else {
+                    pstmt.setNull(12, Types.BIGINT);
+                }
+                pstmt.setString(13, usageRecord.getType());
+                if (usageRecord.getSize() != null) {
+                    pstmt.setLong(14, usageRecord.getSize());
+                } else {
+                    pstmt.setNull(14, Types.BIGINT);
+                }
+                if (usageRecord.getNetworkId() != null) {
+                    pstmt.setLong(15, usageRecord.getNetworkId());
+                } else {
+                    pstmt.setNull(15, Types.BIGINT);
+                }
+                pstmt.setString(16, DateUtil.getDateDisplayString(s_gmtTimeZone, usageRecord.getStartDate()));
+                pstmt.setString(17, DateUtil.getDateDisplayString(s_gmtTimeZone, usageRecord.getEndDate()));
+                if (usageRecord.getVirtualSize() != null) {
+                    pstmt.setLong(18, usageRecord.getVirtualSize());
+                } else {
+                    pstmt.setNull(18, Types.BIGINT);
+                }
+                pstmt.addBatch();
+            }
+            pstmt.executeBatch();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error saving usage records to cloud_usage db", ex);
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    @Override
+    public void removeOldUsageRecords(int days) {
+        String sql = DELETE_ALL_BY_INTERVAL;
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, days);
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception ex) {
+            txn.rollback();
+            s_logger.error("error removing old cloud_usage records for interval: " + days);
+        } finally {
+            txn.close();
+        }
+    }
+
+    public UsageVO persistUsage(final UsageVO usage) {
+        return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<UsageVO>() {
+            @Override
+            public UsageVO doInTransaction(final TransactionStatus status) {
+                return persist(usage);
+            }
+        });
+    }
+
+    public Pair<List<? extends UsageVO>, Integer> getUsageRecordsPendingQuotaAggregation(final long accountId, final long domainId) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Getting usage records for account: " + accountId + ", domainId: " + domainId);
+        }
+        return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Pair<List<? extends UsageVO>, Integer>>() {
+            @Override
+            public Pair<List<? extends UsageVO>, Integer> doInTransaction(final TransactionStatus status) {
+                Pair<List<UsageVO>, Integer> usageRecords = new Pair<List<UsageVO>, Integer>(new ArrayList<UsageVO>(), 0);
+                Filter usageFilter = new Filter(UsageVO.class, "startDate", true, 0L, Long.MAX_VALUE);
+                QueryBuilder<UsageVO> qb = QueryBuilder.create(UsageVO.class);
+                if (accountId != -1) {
+                    qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId);
+                }
+                if (domainId != -1) {
+                    qb.and(qb.entity().getDomainId(), SearchCriteria.Op.EQ, domainId);
+                }
+                qb.and(qb.entity().getQuotaCalculated(), SearchCriteria.Op.NEQ, 1);
+                qb.and(qb.entity().getRawUsage(), SearchCriteria.Op.GT, 0);
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Getting usage records" + usageFilter.getOrderBy());
+                }
+                usageRecords = searchAndCountAllRecords(qb.create(), usageFilter);
+                return new Pair<List<? extends UsageVO>, Integer>(usageRecords.first(), usageRecords.second());
+            }
+        });
+    }
+}
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageIPAddressDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageIPAddressDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageIPAddressDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageIPAddressDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageIPAddressDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageIPAddressDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageJobDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageJobDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageJobDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageJobDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageJobDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageJobDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageJobDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageJobDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageLoadBalancerPolicyDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageLoadBalancerPolicyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageNetworkDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageNetworkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkOfferingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkOfferingDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworkOfferingDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsagePortForwardingRuleDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsagePortForwardingRuleDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsagePortForwardingRuleDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageSecurityGroupDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageSecurityGroupDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageSecurityGroupDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageStorageDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageStorageDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageStorageDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMInstanceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMInstanceDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMInstanceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVPNUserDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVPNUserDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVPNUserDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVPNUserDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVPNUserDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVPNUserDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVmDiskDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVmDiskDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVmDiskDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVmDiskDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVmDiskDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVmDiskDaoImpl.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVolumeDao.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java
diff --git a/engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/usage/dao/UsageVolumeDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/AccountDetailVO.java b/engine/schema/src/main/java/com/cloud/user/AccountDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/AccountDetailVO.java
rename to engine/schema/src/main/java/com/cloud/user/AccountDetailVO.java
diff --git a/engine/schema/src/com/cloud/user/AccountDetailsDao.java b/engine/schema/src/main/java/com/cloud/user/AccountDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/AccountDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/user/AccountDetailsDao.java
diff --git a/engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/AccountDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/AccountDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/AccountDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/AccountVO.java b/engine/schema/src/main/java/com/cloud/user/AccountVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/AccountVO.java
rename to engine/schema/src/main/java/com/cloud/user/AccountVO.java
diff --git a/engine/schema/src/com/cloud/user/SSHKeyPairVO.java b/engine/schema/src/main/java/com/cloud/user/SSHKeyPairVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/SSHKeyPairVO.java
rename to engine/schema/src/main/java/com/cloud/user/SSHKeyPairVO.java
diff --git a/engine/schema/src/com/cloud/user/UserAccountVO.java b/engine/schema/src/main/java/com/cloud/user/UserAccountVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/UserAccountVO.java
rename to engine/schema/src/main/java/com/cloud/user/UserAccountVO.java
diff --git a/engine/schema/src/com/cloud/user/UserStatisticsVO.java b/engine/schema/src/main/java/com/cloud/user/UserStatisticsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/UserStatisticsVO.java
rename to engine/schema/src/main/java/com/cloud/user/UserStatisticsVO.java
diff --git a/engine/schema/src/com/cloud/user/UserStatsLogVO.java b/engine/schema/src/main/java/com/cloud/user/UserStatsLogVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/UserStatsLogVO.java
rename to engine/schema/src/main/java/com/cloud/user/UserStatsLogVO.java
diff --git a/engine/schema/src/com/cloud/user/UserVO.java b/engine/schema/src/main/java/com/cloud/user/UserVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/UserVO.java
rename to engine/schema/src/main/java/com/cloud/user/UserVO.java
diff --git a/engine/schema/src/com/cloud/user/VmDiskStatisticsVO.java b/engine/schema/src/main/java/com/cloud/user/VmDiskStatisticsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/VmDiskStatisticsVO.java
rename to engine/schema/src/main/java/com/cloud/user/VmDiskStatisticsVO.java
diff --git a/engine/schema/src/com/cloud/user/dao/AccountDao.java b/engine/schema/src/main/java/com/cloud/user/dao/AccountDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/AccountDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/AccountDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/AccountDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/AccountDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/SSHKeyPairDao.java b/engine/schema/src/main/java/com/cloud/user/dao/SSHKeyPairDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/SSHKeyPairDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/SSHKeyPairDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/SSHKeyPairDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/SSHKeyPairDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/SSHKeyPairDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserAccountDao.java b/engine/schema/src/main/java/com/cloud/user/dao/UserAccountDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserAccountDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserAccountDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserAccountDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/UserAccountDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserAccountDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserAccountDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserDao.java b/engine/schema/src/main/java/com/cloud/user/dao/UserDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/UserDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserStatisticsDao.java b/engine/schema/src/main/java/com/cloud/user/dao/UserStatisticsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserStatisticsDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserStatisticsDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/UserStatisticsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserStatisticsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserStatisticsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserStatsLogDao.java b/engine/schema/src/main/java/com/cloud/user/dao/UserStatsLogDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserStatsLogDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserStatsLogDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/UserStatsLogDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/UserStatsLogDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/UserStatsLogDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/UserStatsLogDaoImpl.java
diff --git a/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDao.java b/engine/schema/src/main/java/com/cloud/user/dao/VmDiskStatisticsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDao.java
rename to engine/schema/src/main/java/com/cloud/user/dao/VmDiskStatisticsDao.java
diff --git a/engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/user/dao/VmDiskStatisticsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/ConsoleProxyVO.java b/engine/schema/src/main/java/com/cloud/vm/ConsoleProxyVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/ConsoleProxyVO.java
rename to engine/schema/src/main/java/com/cloud/vm/ConsoleProxyVO.java
diff --git a/engine/schema/src/com/cloud/vm/DomainRouterVO.java b/engine/schema/src/main/java/com/cloud/vm/DomainRouterVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/DomainRouterVO.java
rename to engine/schema/src/main/java/com/cloud/vm/DomainRouterVO.java
diff --git a/engine/schema/src/com/cloud/vm/InstanceGroupVMMapVO.java b/engine/schema/src/main/java/com/cloud/vm/InstanceGroupVMMapVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/InstanceGroupVMMapVO.java
rename to engine/schema/src/main/java/com/cloud/vm/InstanceGroupVMMapVO.java
diff --git a/engine/schema/src/com/cloud/vm/InstanceGroupVO.java b/engine/schema/src/main/java/com/cloud/vm/InstanceGroupVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/InstanceGroupVO.java
rename to engine/schema/src/main/java/com/cloud/vm/InstanceGroupVO.java
diff --git a/engine/schema/src/com/cloud/vm/ItWorkDao.java b/engine/schema/src/main/java/com/cloud/vm/ItWorkDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/ItWorkDao.java
rename to engine/schema/src/main/java/com/cloud/vm/ItWorkDao.java
diff --git a/engine/schema/src/com/cloud/vm/ItWorkDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/ItWorkDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/ItWorkDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/ItWorkDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/ItWorkVO.java b/engine/schema/src/main/java/com/cloud/vm/ItWorkVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/ItWorkVO.java
rename to engine/schema/src/main/java/com/cloud/vm/ItWorkVO.java
diff --git a/engine/schema/src/com/cloud/vm/NicDetailVO.java b/engine/schema/src/main/java/com/cloud/vm/NicDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/NicDetailVO.java
rename to engine/schema/src/main/java/com/cloud/vm/NicDetailVO.java
diff --git a/engine/schema/src/com/cloud/vm/NicExtraDhcpOptionVO.java b/engine/schema/src/main/java/com/cloud/vm/NicExtraDhcpOptionVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/NicExtraDhcpOptionVO.java
rename to engine/schema/src/main/java/com/cloud/vm/NicExtraDhcpOptionVO.java
diff --git a/engine/schema/src/com/cloud/vm/NicVO.java b/engine/schema/src/main/java/com/cloud/vm/NicVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/NicVO.java
rename to engine/schema/src/main/java/com/cloud/vm/NicVO.java
diff --git a/engine/schema/src/com/cloud/vm/SecondaryStorageVmVO.java b/engine/schema/src/main/java/com/cloud/vm/SecondaryStorageVmVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/SecondaryStorageVmVO.java
rename to engine/schema/src/main/java/com/cloud/vm/SecondaryStorageVmVO.java
diff --git a/engine/schema/src/com/cloud/vm/UserVmCloneSettingVO.java b/engine/schema/src/main/java/com/cloud/vm/UserVmCloneSettingVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/UserVmCloneSettingVO.java
rename to engine/schema/src/main/java/com/cloud/vm/UserVmCloneSettingVO.java
diff --git a/engine/schema/src/com/cloud/vm/UserVmDetailVO.java b/engine/schema/src/main/java/com/cloud/vm/UserVmDetailVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/UserVmDetailVO.java
rename to engine/schema/src/main/java/com/cloud/vm/UserVmDetailVO.java
diff --git a/engine/schema/src/com/cloud/vm/UserVmVO.java b/engine/schema/src/main/java/com/cloud/vm/UserVmVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/UserVmVO.java
rename to engine/schema/src/main/java/com/cloud/vm/UserVmVO.java
diff --git a/engine/schema/src/com/cloud/vm/VMInstanceVO.java b/engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/VMInstanceVO.java
rename to engine/schema/src/main/java/com/cloud/vm/VMInstanceVO.java
diff --git a/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleProxyDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/ConsoleProxyDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/ConsoleProxyDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/ConsoleProxyDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/ConsoleProxyDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/DomainRouterDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/InstanceGroupDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/InstanceGroupDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/InstanceGroupDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupVMMapDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupVMMapDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/InstanceGroupVMMapDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDetailsDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicExtraDhcpOptionDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicExtraDhcpOptionDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicExtraDhcpOptionDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicExtraDhcpOptionDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicExtraDhcpOptionDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicExtraDhcpOptionDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicExtraDhcpOptionDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicExtraDhcpOptionDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/NicIpAliasDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicIpAliasDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDao.java
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDaoImpl.java
new file mode 100644
index 0000000..887b3d7
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasDaoImpl.java
@@ -0,0 +1,186 @@
+// 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.vm.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.NicIpAlias;
+
+@Component
+public class NicIpAliasDaoImpl extends GenericDaoBase<NicIpAliasVO, Long> implements NicIpAliasDao {
+    private final SearchBuilder<NicIpAliasVO> AllFieldsSearch;
+    private final GenericSearchBuilder<NicIpAliasVO, String> IpSearch;
+
+    protected NicIpAliasDaoImpl() {
+        super();
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
+        AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
+        AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ);
+        AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
+        AllFieldsSearch.and("gateway", AllFieldsSearch.entity().getGateway(), Op.EQ);
+        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.done();
+
+        IpSearch = createSearchBuilder(String.class);
+        IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
+        IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
+        IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL);
+        IpSearch.done();
+    }
+
+    @Override
+    public List<NicIpAliasVO> listByVmId(long instanceId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicIpAliasVO> listByNicId(long nicId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<String> listAliasIpAddressInNetwork(long networkId) {
+        SearchCriteria<String> sc = IpSearch.create();
+        sc.setParameters("network", networkId);
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public List<NicIpAliasVO> listByNetworkId(long networkId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicIpAliasVO> listByNetworkIdAndState(long networkId, NicIpAlias.State state) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("state", state);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicIpAliasVO> listByNicIdAndVmid(long nicId, long vmId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        sc.setParameters("instanceId", vmId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicIpAliasVO> getAliasIpForVm(long vmId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", vmId);
+        sc.setParameters("state", NicIpAlias.State.active);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<String> getAliasIpAddressesForNic(long nicId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        List<NicIpAliasVO> results = search(sc, null);
+        List<String> ips = new ArrayList<String>(results.size());
+        for (NicIpAliasVO result : results) {
+            ips.add(result.getIp4Address());
+            ips.add(result.getIp6Address());
+        }
+        return ips;
+    }
+
+    @Override
+    public NicIpAliasVO findByInstanceIdAndNetworkId(long networkId, long instanceId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("instanceId", instanceId);
+        sc.setParameters("state", NicIpAlias.State.active);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicIpAliasVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public NicIpAliasVO findByGatewayAndNetworkIdAndState(String gateway, long networkId, NicIpAlias.State state) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("gateway", gateway);
+        sc.setParameters("network", networkId);
+        sc.setParameters("state", state);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicIpAliasVO findByIp4AddressAndVmId(String ip4Address, long vmId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("address", ip4Address);
+        sc.setParameters("instanceId", vmId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicIpAliasVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("address", ip4Address);
+        sc.setParameters("nicId", nicId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicIpAliasVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("instanceId", vmId);
+        sc.setParameters("address", vmIp);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public Integer countAliasIps(long id) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", id);
+        List<NicIpAliasVO> list = listBy(sc);
+        return list.size();
+    }
+
+    @Override
+    public int moveIpAliases(long fromNicId, long toNicId) {
+        SearchCriteria<NicIpAliasVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", fromNicId);
+
+        NicIpAliasVO update = createForUpdate();
+        update.setNicId(toNicId);
+        return update(update, sc);
+    }
+}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicIpAliasVO.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicIpAliasVO.java
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDao.java
new file mode 100644
index 0000000..cbb52e5
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDao.java
@@ -0,0 +1,58 @@
+// 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.vm.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
+    List<NicSecondaryIpVO> listByVmId(long instanceId);
+
+    List<String> listSecondaryIpAddressInNetwork(long networkConfigId);
+
+    List<NicSecondaryIpVO> listByNetworkId(long networkId);
+
+    NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId);
+
+    //    void removeNicsForInstance(long instanceId);
+    //    void removeSecondaryIpForNic(long nicId);
+
+    NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId);
+
+    NicSecondaryIpVO findByIp6AddressAndNetworkId(String ip6Address, long networkId);
+
+    List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId);
+
+    List<NicSecondaryIpVO> listByNicId(long nicId);
+
+    List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId);
+
+    NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId);
+
+    NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp);
+
+    NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp);
+
+    List<String> getSecondaryIpAddressesForNic(long nicId);
+
+    Long countByNicId(long nicId);
+
+    List<NicSecondaryIpVO> listSecondaryIpUsingKeyword(long nicId, String keyword);
+
+    int moveSecondaryIps(long fromNicId, long toNicId);
+}
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java
new file mode 100644
index 0000000..ba3a5c7
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java
@@ -0,0 +1,195 @@
+// 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.vm.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long> implements NicSecondaryIpDao {
+
+    private final SearchBuilder<NicSecondaryIpVO> AllFieldsSearch;
+    private final GenericSearchBuilder<NicSecondaryIpVO, String> IpSearch;
+    protected GenericSearchBuilder<NicSecondaryIpVO, Long> CountByNicId;
+
+    public NicSecondaryIpDaoImpl() {
+        super();
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
+        AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
+        AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.LIKE);
+        AllFieldsSearch.and("ip6address", AllFieldsSearch.entity().getIp6Address(), Op.LIKE);
+        AllFieldsSearch.and("nicId", AllFieldsSearch.entity().getNicId(), Op.EQ);
+        AllFieldsSearch.done();
+
+        IpSearch = createSearchBuilder(String.class);
+        IpSearch.select(null, Func.DISTINCT, IpSearch.entity().getIp4Address());
+        IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ);
+        IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL);
+        IpSearch.done();
+
+        CountByNicId = createSearchBuilder(Long.class);
+        CountByNicId.select(null, Func.COUNT, null);
+        CountByNicId.and("nic", CountByNicId.entity().getNicId(), SearchCriteria.Op.EQ);
+        CountByNicId.done();
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> listByVmId(long instanceId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", instanceId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> listByNicId(long nicId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<String> listSecondaryIpAddressInNetwork(long networkId) {
+        SearchCriteria<String> sc = IpSearch.create();
+        sc.setParameters("network", networkId);
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> listByNetworkId(long networkId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> listByNicIdAndVmid(long nicId, long vmId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        sc.setParameters("instanceId", vmId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> getSecondaryIpAddressesForVm(long vmId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", vmId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<String> getSecondaryIpAddressesForNic(long nicId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        List<NicSecondaryIpVO> results = search(sc, null);
+        List<String> ips = new ArrayList<String>(results.size());
+        for (NicSecondaryIpVO result : results) {
+            if (StringUtils.isNotBlank(result.getIp4Address())) {
+                ips.add(result.getIp4Address());
+            }
+
+            if (StringUtils.isNotBlank(result.getIp6Address())) {
+                ips.add(result.getIp6Address());
+            }
+        }
+        return ips;
+    }
+
+    @Override
+    public NicSecondaryIpVO findByInstanceIdAndNetworkId(long networkId, long instanceId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("address", ip4Address);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicSecondaryIpVO findByIp6AddressAndNetworkId(String ip6Address, long networkId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("ip6address", ip6Address);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("address", ip4Address);
+        sc.setParameters("nicId", nicId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("instanceId", vmId);
+        sc.setParameters("address", vmIp);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("network", networkId);
+        sc.setParameters("instanceId", vmId);
+        sc.setParameters("address", vmIp);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public Long countByNicId(long nicId) {
+        SearchCriteria<Long> sc = CountByNicId.create();
+        sc.setParameters("nic", nicId);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public List<NicSecondaryIpVO> listSecondaryIpUsingKeyword(long nicId, String keyword)
+    {
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", nicId);
+        sc.setParameters("address", "%" + keyword + "%");
+        return listBy(sc);
+    }
+
+    @Override
+    public int moveSecondaryIps(long fromNicId, long toNicId) {
+        NicSecondaryIpVO update = createForUpdate();
+        update.setNicId(toNicId);
+
+        SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
+        sc.setParameters("nicId", fromNicId);
+
+        return update(update, sc);
+    }
+}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/NicSecondaryIpVO.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/NicSecondaryIpVO.java
diff --git a/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/SecondaryStorageVmDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/SecondaryStorageVmDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/SecondaryStorageVmDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmCloneSettingDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmCloneSettingDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmCloneSettingDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmDao.java
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java
new file mode 100644
index 0000000..5e22eb5
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java
@@ -0,0 +1,683 @@
+// 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.vm.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.network.Network;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Attribute;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.UserVmDetailVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmData.NicData;
+import com.cloud.vm.dao.UserVmData.SecurityGroupData;
+
+public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements UserVmDao {
+    public static final Logger s_logger = Logger.getLogger(UserVmDaoImpl.class);
+
+    protected SearchBuilder<UserVmVO> AccountPodSearch;
+    protected SearchBuilder<UserVmVO> AccountDataCenterSearch;
+    protected SearchBuilder<UserVmVO> AccountSearch;
+    protected SearchBuilder<UserVmVO> HostSearch;
+    protected SearchBuilder<UserVmVO> LastHostSearch;
+    protected SearchBuilder<UserVmVO> HostUpSearch;
+    protected SearchBuilder<UserVmVO> HostRunningSearch;
+    protected SearchBuilder<UserVmVO> StateChangeSearch;
+    protected SearchBuilder<UserVmVO> AccountHostSearch;
+
+    protected SearchBuilder<UserVmVO> DestroySearch;
+    protected SearchBuilder<UserVmVO> AccountDataCenterVirtualSearch;
+    protected GenericSearchBuilder<UserVmVO, Long> CountByAccountPod;
+    protected GenericSearchBuilder<UserVmVO, Long> CountByAccount;
+    protected GenericSearchBuilder<UserVmVO, Long> PodsHavingVmsForAccount;
+
+    protected SearchBuilder<UserVmVO> UserVmSearch;
+    protected SearchBuilder<UserVmVO> UserVmByIsoSearch;
+    protected Attribute _updateTimeAttr;
+    // ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class);
+    @Inject
+    ResourceTagDao _tagsDao;
+    @Inject
+    NetworkDao networkDao;
+
+    private static final String LIST_PODS_HAVING_VMS_FOR_ACCOUNT =
+            "SELECT pod_id FROM cloud.vm_instance WHERE data_center_id = ? AND account_id = ? AND pod_id IS NOT NULL AND (state = 'Running' OR state = 'Stopped') "
+                    + "GROUP BY pod_id HAVING count(id) > 0 ORDER BY count(id) DESC";
+
+    private static final String VM_DETAILS = "select vm_instance.id, "
+            + "account.id, account.account_name, account.type, domain.name, instance_group.id, instance_group.name,"
+            + "data_center.id, data_center.name, data_center.is_security_group_enabled, host.id, host.name, "
+            + "vm_template.id, vm_template.name, vm_template.display_text, iso.id, iso.name, "
+            + "vm_template.enable_password, service_offering.id, disk_offering.name, storage_pool.id, storage_pool.pool_type, "
+            + "service_offering.cpu, service_offering.speed, service_offering.ram_size, volumes.id, volumes.device_id, volumes.volume_type, security_group.id, security_group.name, "
+            + "security_group.description, nics.id, nics.ip4_address, nics.default_nic, nics.gateway, nics.network_id, nics.netmask, nics.mac_address, nics.broadcast_uri, " +
+            "nics.isolation_uri, "
+            + "networks.traffic_type, networks.guest_type, user_ip_address.id, user_ip_address.public_ip_address from vm_instance "
+            + "left join account on vm_instance.account_id=account.id  " + "left join domain on vm_instance.domain_id=domain.id "
+            + "left join instance_group_vm_map on vm_instance.id=instance_group_vm_map.instance_id "
+            + "left join instance_group on instance_group_vm_map.group_id=instance_group.id " + "left join data_center on vm_instance.data_center_id=data_center.id "
+            + "left join host on vm_instance.host_id=host.id " + "left join vm_template on vm_instance.vm_template_id=vm_template.id "
+            + "left join user_vm on vm_instance.id=user_vm.id " + "left join vm_template iso on iso.id=user_vm.iso_id "
+            + "left join service_offering on vm_instance.service_offering_id=service_offering.id "
+            + "left join disk_offering  on vm_instance.service_offering_id=disk_offering.id " + "left join volumes on vm_instance.id=volumes.instance_id "
+            + "left join storage_pool on volumes.pool_id=storage_pool.id " + "left join security_group_vm_map on vm_instance.id=security_group_vm_map.instance_id "
+            + "left join security_group on security_group_vm_map.security_group_id=security_group.id " + "left join nics on vm_instance.id=nics.instance_id "
+            + "left join networks on nics.network_id=networks.id " + "left join user_ip_address on user_ip_address.vm_id=vm_instance.id " + "where vm_instance.id in (";
+
+    private static final String VMS_DETAIL_BY_NAME = "select vm_instance.instance_name, vm_instance.vm_type, vm_instance.id , user_vm_details.value, user_vm_details.name from vm_instance "
+            + "left join user_vm_details on vm_instance.id = user_vm_details.vm_id where (user_vm_details.name is null or user_vm_details.name = ? ) and vm_instance.instance_name in (";
+
+    private static final int VM_DETAILS_BATCH_SIZE = 100;
+
+    @Inject
+    protected UserVmDetailsDao _detailsDao;
+    @Inject
+    protected NicDao _nicDao;
+
+    public UserVmDaoImpl() {
+    }
+
+    @PostConstruct
+    void init() {
+        AccountSearch = createSearchBuilder();
+        AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountSearch.done();
+
+        HostSearch = createSearchBuilder();
+        HostSearch.and("host", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        HostSearch.done();
+
+        LastHostSearch = createSearchBuilder();
+        LastHostSearch.and("lastHost", LastHostSearch.entity().getLastHostId(), SearchCriteria.Op.EQ);
+        LastHostSearch.and("state", LastHostSearch.entity().getState(), SearchCriteria.Op.EQ);
+        LastHostSearch.done();
+
+        HostUpSearch = createSearchBuilder();
+        HostUpSearch.and("host", HostUpSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        HostUpSearch.and("states", HostUpSearch.entity().getState(), SearchCriteria.Op.NIN);
+        HostUpSearch.done();
+
+        HostRunningSearch = createSearchBuilder();
+        HostRunningSearch.and("host", HostRunningSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        HostRunningSearch.and("state", HostRunningSearch.entity().getState(), SearchCriteria.Op.EQ);
+        HostRunningSearch.done();
+
+        AccountPodSearch = createSearchBuilder();
+        AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountPodSearch.and("pod", AccountPodSearch.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
+        AccountPodSearch.done();
+
+        AccountDataCenterSearch = createSearchBuilder();
+        AccountDataCenterSearch.and("account", AccountDataCenterSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountDataCenterSearch.and("dc", AccountDataCenterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AccountDataCenterSearch.done();
+
+        StateChangeSearch = createSearchBuilder();
+        StateChangeSearch.and("id", StateChangeSearch.entity().getId(), SearchCriteria.Op.EQ);
+        StateChangeSearch.and("states", StateChangeSearch.entity().getState(), SearchCriteria.Op.EQ);
+        StateChangeSearch.and("host", StateChangeSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        StateChangeSearch.and("update", StateChangeSearch.entity().getUpdated(), SearchCriteria.Op.EQ);
+        StateChangeSearch.done();
+
+        DestroySearch = createSearchBuilder();
+        DestroySearch.and("state", DestroySearch.entity().getState(), SearchCriteria.Op.IN);
+        DestroySearch.and("updateTime", DestroySearch.entity().getUpdateTime(), SearchCriteria.Op.LT);
+        DestroySearch.done();
+
+        AccountHostSearch = createSearchBuilder();
+        AccountHostSearch.and("accountId", AccountHostSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountHostSearch.and("hostId", AccountHostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        AccountHostSearch.done();
+
+        CountByAccountPod = createSearchBuilder(Long.class);
+        CountByAccountPod.select(null, Func.COUNT, null);
+        CountByAccountPod.and("account", CountByAccountPod.entity().getAccountId(), SearchCriteria.Op.EQ);
+        CountByAccountPod.and("pod", CountByAccountPod.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
+        CountByAccountPod.done();
+
+        CountByAccount = createSearchBuilder(Long.class);
+        CountByAccount.select(null, Func.COUNT, null);
+        CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
+        CountByAccount.and("type", CountByAccount.entity().getType(), SearchCriteria.Op.EQ);
+        CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
+        CountByAccount.and("displayVm", CountByAccount.entity().isDisplayVm(), SearchCriteria.Op.EQ);
+        CountByAccount.done();
+
+        SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
+        nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        nicSearch.and("ip4Address", nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
+
+        AccountDataCenterVirtualSearch = createSearchBuilder();
+        AccountDataCenterVirtualSearch.and("account", AccountDataCenterVirtualSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        AccountDataCenterVirtualSearch.and("dc", AccountDataCenterVirtualSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(),
+                JoinBuilder.JoinType.INNER);
+        AccountDataCenterVirtualSearch.done();
+
+        UserVmByIsoSearch = createSearchBuilder();
+        UserVmByIsoSearch.and("isoId", UserVmByIsoSearch.entity().getIsoId(), SearchCriteria.Op.EQ);
+        UserVmByIsoSearch.done();
+
+        _updateTimeAttr = _allAttributes.get("updateTime");
+        assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
+    }
+
+    @Override
+    public List<UserVmVO> listByAccountAndPod(long accountId, long podId) {
+        SearchCriteria<UserVmVO> sc = AccountPodSearch.create();
+        sc.setParameters("account", accountId);
+        sc.setParameters("pod", podId);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByAccountAndDataCenter(long accountId, long dcId) {
+        SearchCriteria<UserVmVO> sc = AccountDataCenterSearch.create();
+        sc.setParameters("account", accountId);
+        sc.setParameters("dc", dcId);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public void updateVM(long id, String displayName, boolean enable, Long osTypeId, String userData, boolean displayVm,
+            boolean isDynamicallyScalable, String customId, String hostName, String instanceName) {
+        UserVmVO vo = createForUpdate();
+        vo.setDisplayName(displayName);
+        vo.setHaEnabled(enable);
+        vo.setGuestOSId(osTypeId);
+        vo.setUserData(userData);
+        vo.setDisplayVm(displayVm);
+        vo.setDynamicallyScalable(isDynamicallyScalable);
+        if (hostName != null) {
+            vo.setHostName(hostName);
+        }
+        if (customId != null) {
+            vo.setUuid(customId);
+        }
+        if(instanceName != null){
+            vo.setInstanceName(instanceName);
+        }
+
+        update(id, vo);
+    }
+
+    @Override
+    public List<UserVmVO> findDestroyedVms(Date date) {
+        SearchCriteria<UserVmVO> sc = DestroySearch.create();
+        sc.setParameters("state", State.Destroyed, State.Expunging, State.Error);
+        sc.setParameters("updateTime", date);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByAccountId(long id) {
+        SearchCriteria<UserVmVO> sc = AccountSearch.create();
+        sc.setParameters("account", id);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByHostId(Long id) {
+        SearchCriteria<UserVmVO> sc = HostSearch.create();
+        sc.setParameters("host", id);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByIsoId(Long isoId) {
+        SearchCriteria<UserVmVO> sc = UserVmByIsoSearch.create();
+        sc.setParameters("isoId", isoId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listUpByHostId(Long hostId) {
+        SearchCriteria<UserVmVO> sc = HostUpSearch.create();
+        sc.setParameters("host", hostId);
+        sc.setParameters("states", new Object[] {State.Destroyed, State.Stopped, State.Expunging});
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listRunningByHostId(long hostId) {
+        SearchCriteria<UserVmVO> sc = HostRunningSearch.create();
+        sc.setParameters("host", hostId);
+        sc.setParameters("state", State.Running);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId) {
+
+        SearchCriteria<UserVmVO> sc = AccountDataCenterVirtualSearch.create();
+        sc.setParameters("account", accountId);
+        sc.setJoinParameters("nicSearch", "networkId", networkId);
+
+        return listBy(sc);
+    }
+
+    /**
+     * Recreates UserVmSearch depending on network type, as nics on L2 networks have no ip addresses
+     * @param network network
+     */
+    private void recreateUserVmSeach(NetworkVO network) {
+        if (network != null) {
+            SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
+            nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
+            nicSearch.and("removed", nicSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+            if (!Network.GuestType.L2.equals(network.getGuestType())) {
+                nicSearch.and().op("ip4Address", nicSearch.entity().getIPv4Address(), SearchCriteria.Op.NNULL);
+                nicSearch.or("ip6Address", nicSearch.entity().getIPv6Address(), SearchCriteria.Op.NNULL);
+                nicSearch.cp();
+            }
+
+            UserVmSearch = createSearchBuilder();
+            UserVmSearch.and("states", UserVmSearch.entity().getState(), SearchCriteria.Op.IN);
+            UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
+            UserVmSearch.done();
+        }
+    }
+
+    @Override
+    public List<UserVmVO> listByNetworkIdAndStates(long networkId, State... states) {
+        NetworkVO network = networkDao.findById(networkId);
+        recreateUserVmSeach(network);
+
+        SearchCriteria<UserVmVO> sc = UserVmSearch.create();
+        if (states != null && states.length != 0) {
+            sc.setParameters("states", (Object[])states);
+        }
+        sc.setJoinParameters("nicSearch", "networkId", networkId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByLastHostId(Long hostId) {
+        SearchCriteria<UserVmVO> sc = LastHostSearch.create();
+        sc.setParameters("lastHost", hostId);
+        sc.setParameters("state", State.Stopped);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<UserVmVO> listByAccountIdAndHostId(long accountId, long hostId) {
+        SearchCriteria<UserVmVO> sc = AccountHostSearch.create();
+        sc.setParameters("hostId", hostId);
+        sc.setParameters("accountId", accountId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void loadDetails(UserVmVO vm) {
+        Map<String, String> details = _detailsDao.listDetailsKeyPairs(vm.getId());
+        vm.setDetails(details);
+    }
+
+    @Override
+    public void saveDetails(UserVmVO vm) {
+        Map<String, String> detailsStr = vm.getDetails();
+        if (detailsStr == null) {
+            return;
+        }
+
+        final Map<String, Boolean> visibilityMap = _detailsDao.listDetailsVisibility(vm.getId());
+
+        List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>();
+        for (Map.Entry<String, String> entry : detailsStr.entrySet()) {
+            boolean display = visibilityMap.getOrDefault(entry.getKey(), true);
+            details.add(new UserVmDetailVO(vm.getId(), entry.getKey(), entry.getValue(), display));
+        }
+
+        _detailsDao.saveDetails(details);
+    }
+
+    @Override
+    public List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        List<Long> result = new ArrayList<Long>();
+        String sql = LIST_PODS_HAVING_VMS_FOR_ACCOUNT;
+
+        try(PreparedStatement pstmt = txn.prepareStatement(sql)) {
+            pstmt.setLong(1, zoneId);
+            pstmt.setLong(2, accountId);
+            try(ResultSet rs = pstmt.executeQuery();)
+            {
+                while (rs.next()) {
+                    result.add(rs.getLong(1));
+                }
+            }
+            catch (Exception e) {
+                s_logger.error("listPodIdsHavingVmsforAccount:Exception: " +  e.getMessage());
+                throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e);
+            }
+            txn.commit();
+            return result;
+        } catch (Exception e) {
+            s_logger.error("listPodIdsHavingVmsforAccount:Exception : " +  e.getMessage());
+            throw new CloudRuntimeException("listPodIdsHavingVmsforAccount:Exception: " + e.getMessage(), e);
+        }
+        finally {
+            try{
+                if (txn != null)
+                {
+                    txn.close();
+                }
+            }
+            catch (Exception e)
+            {
+                s_logger.error("listPodIdsHavingVmsforAccount:Exception:" + e.getMessage());
+            }
+        }
+
+    }
+
+    @Override
+    public Hashtable<Long, UserVmData> listVmDetails(Hashtable<Long, UserVmData> userVmDataHash) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            int curr_index = 0;
+            List<UserVmData> userVmDataList = new ArrayList(userVmDataHash.values());
+            if (userVmDataList.size() > VM_DETAILS_BATCH_SIZE)
+            {
+                try (PreparedStatement pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(VM_DETAILS_BATCH_SIZE));)
+                {
+                    while ((curr_index + VM_DETAILS_BATCH_SIZE) <= userVmDataList.size()) {
+                        // set the vars value
+                        for (int k = 1, j = curr_index; j < curr_index + VM_DETAILS_BATCH_SIZE; j++, k++) {
+                            pstmt.setLong(k, userVmDataList.get(j).getId());
+                        }
+                        try(ResultSet rs = pstmt.executeQuery();)
+                        {
+                            while (rs.next()) {
+                                long vm_id = rs.getLong("vm_instance.id");
+                                //check if the entry is already there
+                                UserVmData uvm = userVmDataHash.get(vm_id);
+                                if (uvm == null) {
+                                    uvm = new UserVmData();
+                                    uvm.setId(vm_id);
+                                }
+                                // initialize the data with this row
+                                setUserVmData(uvm, rs);
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            s_logger.error("listVmDetails:Exception:" + e.getMessage());
+                            throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
+                        }
+                        curr_index += VM_DETAILS_BATCH_SIZE;
+                    }
+                }
+                catch (Exception e)
+                {
+                    s_logger.error("listVmDetails:Exception:" + e.getMessage());
+                    throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
+                }
+            }
+
+            if (curr_index < userVmDataList.size()) {
+                int batch_size = (userVmDataList.size() - curr_index);
+                try (PreparedStatement vm_details_pstmt = txn.prepareStatement(VM_DETAILS + getQueryBatchAppender(batch_size)))
+                {
+                    // set the vars value
+                    for (int k = 1, j = curr_index; j < curr_index + batch_size; j++, k++) {
+                        vm_details_pstmt.setLong(k, userVmDataList.get(j).getId());
+                    }
+                    try(ResultSet rs = vm_details_pstmt.executeQuery();) {
+                        while (rs.next()) {
+                            long vm_id = rs.getLong("vm_instance.id");
+                            //check if the entry is already there
+                            UserVmData uvm = userVmDataHash.get(vm_id);
+                            if (uvm == null) {
+                                uvm = new UserVmData();
+                                uvm.setId(vm_id);
+                            }
+                            // initialize the data with this row
+                            setUserVmData(uvm, rs);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        s_logger.error("listVmDetails: Exception:" + e.getMessage());
+                        throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
+                    }
+                }
+                catch (Exception e)
+                {
+                    s_logger.error("listVmDetails:Exception:" + e.getMessage());
+                    throw new CloudRuntimeException("listVmDetails: Exception:" + e.getMessage(),e);
+                }
+            }
+            txn.commit();
+            return userVmDataHash;
+        } catch (Exception e) {
+            s_logger.error("listVmDetails:Exception:" + e.getMessage());
+            throw new CloudRuntimeException("listVmDetails:Exception : ", e);
+        }
+        finally {
+            try{
+                if (txn != null)
+                {
+                    txn.close();
+                }
+            }
+            catch (Exception e)
+            {
+                s_logger.error("listVmDetails:Exception:" + e.getMessage());
+            }
+        }
+
+    }
+
+    public static UserVmData setUserVmData(UserVmData userVmData, ResultSet rs) throws SQLException {
+
+        if (!userVmData.isInitialized()) {
+
+            //account.account_name, account.type, domain.name,  instance_group.id, instance_group.name,"
+            userVmData.setAccountId(rs.getLong("account.id"));
+            userVmData.setAccountName(rs.getString("account.account_name"));
+            userVmData.setDomainName(rs.getString("domain.name"));
+
+            long grp_id = rs.getLong("instance_group.id");
+            if (grp_id > 0) {
+                userVmData.setGroupId(grp_id);
+                userVmData.setGroup(rs.getString("instance_group.name"));
+            }
+
+            //"data_center.id, data_center.name, host.id, host.name, vm_template.id, vm_template.name, vm_template.display_text, vm_template.enable_password,
+            userVmData.setZoneId(rs.getLong("data_center.id"));
+            userVmData.setZoneName(rs.getString("data_center.name"));
+
+            userVmData.setHostId(rs.getLong("host.id"));
+            userVmData.setHostName(rs.getString("host.name"));
+
+            long template_id = rs.getLong("vm_template.id");
+            if (template_id > 0) {
+                userVmData.setTemplateId(template_id);
+                userVmData.setTemplateName(rs.getString("vm_template.name"));
+                userVmData.setTemplateDisplayText(rs.getString("vm_template.display_text"));
+                userVmData.setPasswordEnabled(rs.getBoolean("vm_template.enable_password"));
+            } else {
+                userVmData.setTemplateId(-1L);
+                userVmData.setTemplateName("ISO Boot");
+                userVmData.setTemplateDisplayText("ISO Boot");
+                userVmData.setPasswordEnabled(false);
+            }
+
+            long iso_id = rs.getLong("iso.id");
+            if (iso_id > 0) {
+                userVmData.setIsoId(iso_id);
+                userVmData.setIsoName(rs.getString("iso.name"));
+            }
+
+            //service_offering.id, disk_offering.name, "
+            //"service_offering.cpu, service_offering.speed, service_offering.ram_size,
+            userVmData.setServiceOfferingId(rs.getLong("service_offering.id"));
+            userVmData.setServiceOfferingName(rs.getString("disk_offering.name"));
+            userVmData.setCpuNumber(rs.getInt("service_offering.cpu"));
+            userVmData.setCpuSpeed(rs.getInt("service_offering.speed"));
+            userVmData.setMemory(rs.getInt("service_offering.ram_size"));
+
+            // volumes.device_id, volumes.volume_type,
+            long vol_id = rs.getLong("volumes.id");
+            if (vol_id > 0) {
+                userVmData.setRootDeviceId(rs.getLong("volumes.device_id"));
+                userVmData.setRootDeviceType(rs.getString("volumes.volume_type"));
+                // storage pool
+                long pool_id = rs.getLong("storage_pool.id");
+                if (pool_id > 0) {
+                    userVmData.setRootDeviceType(rs.getString("storage_pool.pool_type"));
+                } else {
+                    userVmData.setRootDeviceType("Not created");
+                }
+            }
+            userVmData.setInitialized();
+        }
+
+        Long securityGroupId = rs.getLong("security_group.id");
+        if (securityGroupId != null && securityGroupId.longValue() != 0) {
+            SecurityGroupData resp = userVmData.newSecurityGroupData();
+            resp.setId(rs.getLong("security_group.id"));
+            resp.setName(rs.getString("security_group.name"));
+            resp.setDescription(rs.getString("security_group.description"));
+            resp.setObjectName("securitygroup");
+            userVmData.addSecurityGroup(resp);
+        }
+
+        long nic_id = rs.getLong("nics.id");
+        if (nic_id > 0) {
+            NicData nicResponse = userVmData.newNicData();
+            nicResponse.setId(nic_id);
+            nicResponse.setIpaddress(rs.getString("nics.ip4_address"));
+            nicResponse.setGateway(rs.getString("nics.gateway"));
+            nicResponse.setNetmask(rs.getString("nics.netmask"));
+            nicResponse.setNetworkid(rs.getLong("nics.network_id"));
+            nicResponse.setMacAddress(rs.getString("nics.mac_address"));
+
+            int account_type = rs.getInt("account.type");
+            if (account_type == Account.ACCOUNT_TYPE_ADMIN) {
+                nicResponse.setBroadcastUri(rs.getString("nics.broadcast_uri"));
+                nicResponse.setIsolationUri(rs.getString("nics.isolation_uri"));
+            }
+
+            nicResponse.setTrafficType(rs.getString("networks.traffic_type"));
+            nicResponse.setType(rs.getString("networks.guest_type"));
+            nicResponse.setIsDefault(rs.getBoolean("nics.default_nic"));
+            nicResponse.setObjectName("nic");
+            userVmData.addNic(nicResponse);
+        }
+
+        long publicIpId = rs.getLong("user_ip_address.id");
+        if (publicIpId > 0) {
+            userVmData.setPublicIpId(publicIpId);
+            userVmData.setPublicIp(rs.getString("user_ip_address.public_ip_address"));
+        }
+
+        return userVmData;
+    }
+
+    public String getQueryBatchAppender(int count) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < count; i++) {
+            sb.append(" ?,");
+        }
+        sb.deleteCharAt(sb.length() - 1).append(")");
+        return sb.toString();
+    }
+
+    @Override
+    public Long countAllocatedVMsForAccount(long accountId) {
+        SearchCriteria<Long> sc = CountByAccount.create();
+        sc.setParameters("account", accountId);
+        sc.setParameters("type", VirtualMachine.Type.User);
+        sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
+        sc.setParameters("displayVm", 1);
+        return customSearch(sc, null).get(0);
+    }
+
+    @Override
+    public boolean remove(Long id) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        _tagsDao.removeByIdAndType(id, ResourceObjectType.UserVm);
+        boolean result = super.remove(id);
+        txn.commit();
+        return result;
+    }
+
+    @Override
+    public List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> getVmsDetailByNames(Set<String> vmNames, String detail) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        List<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>> vmsDetailByNames = new ArrayList<Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>>();
+
+        try (PreparedStatement pstmt = txn.prepareStatement(VMS_DETAIL_BY_NAME + getQueryBatchAppender(vmNames.size()));) {
+            pstmt.setString(1, detail);
+            int i = 2;
+            for(String name : vmNames) {
+                pstmt.setString(i, name);
+                i++;
+            }
+            try (ResultSet rs = pstmt.executeQuery();) {
+                while (rs.next()) {
+                    vmsDetailByNames.add(new Pair<Pair<String, VirtualMachine.Type>, Pair<Long, String>>(new Pair<String, VirtualMachine.Type>(
+                            rs.getString("vm_instance.instance_name"), VirtualMachine.Type.valueOf(rs.getString("vm_type"))),
+                            new Pair<Long, String>(rs.getLong("vm_instance.id"), rs.getString("user_vm_details.value"))));
+                }
+            }
+        } catch (SQLException e) {
+            s_logger.error("GetVmsDetailsByNames: Exception in sql: " + e.getMessage());
+            throw new CloudRuntimeException("GetVmsDetailsByNames: Exception: " + e.getMessage());
+        }
+
+        return vmsDetailByNames;
+    }
+}
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmData.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmData.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmData.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmData.java
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmDetailsDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/UserVmDetailsDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java
diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/VMSnapshotDetailsVO.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/VMSnapshotVO.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/VMSnapshotVO.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/VMSnapshotVO.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDao.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDao.java
diff --git a/engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
rename to engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/RolePermissionVO.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/RolePermissionVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/RolePermissionVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/RolePermissionVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/RoleVO.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/RoleVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/RoleVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/RoleVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RoleDao.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/dao/RoleDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RoleDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RolePermissionsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RolePermissionsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RolePermissionsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupDomainMapVO.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupDomainMapVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupDomainMapVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupDomainMapVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupVMMapVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/AffinityGroupVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/AffinityGroupVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDao.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupDomainMapDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/affinity/dao/AffinityGroupVMMapDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/annotation/AnnotationVO.java b/engine/schema/src/main/java/org/apache/cloudstack/annotation/AnnotationVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/annotation/AnnotationVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/annotation/AnnotationVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/annotation/dao/AnnotationDao.java b/engine/schema/src/main/java/org/apache/cloudstack/annotation/dao/AnnotationDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/annotation/dao/AnnotationDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/annotation/dao/AnnotationDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/annotation/dao/AnnotationDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/annotation/dao/AnnotationDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/annotation/dao/AnnotationDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/annotation/dao/AnnotationDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMComputeTagVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMEntityVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMNetworkMapVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMReservationVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VMRootDiskTagVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/VolumeReservationVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMComputeTagDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMEntityDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMNetworkMapDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMReservationDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VMRootDiskTagDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDao.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/engine/cloud/entity/api/db/dao/VolumeReservationDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/ha/HAConfigVO.java b/engine/schema/src/main/java/org/apache/cloudstack/ha/HAConfigVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/ha/HAConfigVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/ha/HAConfigVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/ha/dao/HAConfigDao.java b/engine/schema/src/main/java/org/apache/cloudstack/ha/dao/HAConfigDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/ha/dao/HAConfigDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/ha/dao/HAConfigDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/ha/dao/HAConfigDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/ha/dao/HAConfigDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/ha/dao/HAConfigDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/ha/dao/HAConfigDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/lb/ApplicationLoadBalancerRuleVO.java b/engine/schema/src/main/java/org/apache/cloudstack/lb/ApplicationLoadBalancerRuleVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/lb/ApplicationLoadBalancerRuleVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/lb/ApplicationLoadBalancerRuleVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java b/engine/schema/src/main/java/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementVO.java b/engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDao.java b/engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpDao.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpRangeDao.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpRangeDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpRangeVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpRangeVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpRangeVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/PortableIpVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/PortableIpVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/PortableIpVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/RegionSyncVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/RegionSyncVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/RegionSyncVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/RegionSyncVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/RegionVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/RegionVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/RegionVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/RegionVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/dao/RegionDao.java b/engine/schema/src/main/java/org/apache/cloudstack/region/dao/RegionDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/dao/RegionDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/dao/RegionDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/region/dao/RegionDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/dao/RegionDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/dao/RegionDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/FirewallRuleDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/FirewallRuleDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/FirewallRuleDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/FirewallRuleDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/GuestOsDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/GuestOsDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/GuestOsDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/GuestOsDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/LBHealthCheckPolicyDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/LBStickinessPolicyDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/NetworkACLItemDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/NetworkACLListDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/RemoteAccessVpnDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/RemoteAccessVpnDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/RemoteAccessVpnDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/RemoteAccessVpnDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/ResourceDetailsDaoBase.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteCustomerGatewayDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteCustomerGatewayDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteCustomerGatewayDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteCustomerGatewayDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteVpnConnectionDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteVpnConnectionDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteVpnConnectionDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteVpnConnectionDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteVpnGatewayDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteVpnGatewayDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/Site2SiteVpnGatewayDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/Site2SiteVpnGatewayDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/SnapshotPolicyDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/UserDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/UserDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/UserIpAddressDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserIpAddressDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/UserIpAddressDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/UserIpAddressDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/VpcDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/VpcDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/VpcDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/VpcGatewayDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/FirewallRuleDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/GuestOsDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBHealthCheckPolicyDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/LBStickinessPolicyDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLItemDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/NetworkACLListDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/RemoteAccessVpnDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteCustomerGatewayDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnConnectionDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/Site2SiteVpnGatewayDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/SnapshotPolicyDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/UserIpAddressDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/VpcGatewayDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
new file mode 100644
index 0000000..fee9dc2
--- /dev/null
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -0,0 +1,555 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.datastore.db;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.collections.CollectionUtils;
+
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.StoragePoolTagVO;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.StoragePoolTagsDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@DB()
+public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long> implements PrimaryDataStoreDao {
+    private final SearchBuilder<StoragePoolVO> AllFieldSearch;
+    private final SearchBuilder<StoragePoolVO> DcPodSearch;
+    private final SearchBuilder<StoragePoolVO> DcPodAnyClusterSearch;
+    private final SearchBuilder<StoragePoolVO> DeleteLvmSearch;
+    private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
+    private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
+
+    @Inject
+    private StoragePoolDetailsDao _detailsDao;
+    @Inject
+    private StoragePoolHostDao _hostDao;
+    @Inject
+    private StoragePoolTagsDao _tagsDao;
+
+    protected final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
+    protected final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
+    private final String ZoneWideTagsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_tags ON storage_pool.id = storage_pool_tags.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and (";
+    private final String ZoneWideTagsSqlSuffix = ") GROUP BY storage_pool_tags.pool_id HAVING COUNT(storage_pool_tags.tag) >= ?";
+
+    // Storage tags are now separate from storage_pool_details, leaving only details on that table
+    protected final String TagsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_tags ON storage_pool.id = storage_pool_tags.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
+    protected final String TagsSqlSuffix = ") GROUP BY storage_pool_tags.pool_id HAVING COUNT(storage_pool_tags.tag) >= ?";
+
+    /**
+     * Used in method findPoolsByDetailsOrTagsInternal
+     */
+    protected enum ValueType {
+        DETAILS, TAGS;
+    }
+
+    public PrimaryDataStoreDaoImpl() {
+        AllFieldSearch = createSearchBuilder();
+        AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("status", AllFieldSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("scope", AllFieldSearch.entity().getScope(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ);
+        AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ);
+        AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ);
+        AllFieldSearch.and("storage_provider_name", AllFieldSearch.entity().getStorageProviderName(), Op.EQ);
+        AllFieldSearch.done();
+
+        DcPodSearch = createSearchBuilder();
+        DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ);
+        DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL);
+        DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        DcPodSearch.cp();
+        DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL);
+        DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        DcPodSearch.cp();
+        DcPodSearch.done();
+
+        DcPodAnyClusterSearch = createSearchBuilder();
+        DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL);
+        DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+        DcPodAnyClusterSearch.cp();
+        DcPodAnyClusterSearch.done();
+
+        DeleteLvmSearch = createSearchBuilder();
+        DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN);
+        DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
+        DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
+        DeleteLvmSearch.cp();
+        DeleteLvmSearch.done();
+
+        StatusCountSearch = createSearchBuilder(Long.class);
+        StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        StatusCountSearch.select(null, Func.COUNT, null);
+        StatusCountSearch.done();
+
+        DcLocalStorageSearch = createSearchBuilder();
+        DcLocalStorageSearch.and("datacenterId", DcLocalStorageSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        DcLocalStorageSearch.and("path", DcLocalStorageSearch.entity().getPath(), SearchCriteria.Op.EQ);
+        DcLocalStorageSearch.and("scope", DcLocalStorageSearch.entity().getScope(), SearchCriteria.Op.EQ);
+        DcLocalStorageSearch.done();
+    }
+
+    @Override
+    public List<StoragePoolVO> findPoolByName(String name) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("name", name);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> findPoolsByProvider(String provider) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("storage_provider_name", provider);
+        return listBy(sc);
+    }
+
+    @Override
+    public StoragePoolVO findPoolByUUID(String uuid) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("uuid", uuid);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> findIfDuplicatePoolsExistByUUID(String uuid) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("uuid", uuid);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listByDataCenterId(long datacenterId) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("datacenterId", datacenterId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void updateCapacityBytes(long id, long capacityBytes) {
+        StoragePoolVO pool = createForUpdate(id);
+        pool.setCapacityBytes(capacityBytes);
+        update(id, pool);
+    }
+
+    @Override
+    public void updateCapacityIops(long id, long capacityIops) {
+        StoragePoolVO pool = createForUpdate(id);
+        pool.setCapacityIops(capacityIops);
+        update(id, pool);
+    }
+
+    @Override
+    public List<StoragePoolVO> listByStorageHost(String hostFqdnOrIp) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", hostFqdnOrIp);
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listByStatus(StoragePoolStatus status) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("status", status);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listByStatusInZone(long dcId, StoragePoolStatus status) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("status", status);
+        sc.setParameters("datacenterId", dcId);
+        return listBy(sc);
+    }
+
+    @Override
+    public StoragePoolVO findPoolByHostPath(long datacenterId, Long podId, String host, String path, String uuid) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", host);
+        if (path != null) {
+            sc.setParameters("path", path);
+        }
+        sc.setParameters("datacenterId", datacenterId);
+        sc.setParameters("podId", podId);
+        sc.setParameters("uuid", uuid);
+
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String path) {
+        SearchCriteria<StoragePoolVO> sc = DcLocalStorageSearch.create();
+        sc.setParameters("path", path);
+        sc.setParameters("datacenterId", datacenterId);
+        sc.setParameters("scope", ScopeType.HOST);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope) {
+        SearchCriteria<StoragePoolVO> sc = null;
+        if (clusterId != null) {
+            sc = DcPodSearch.create();
+            sc.setParameters("cluster", clusterId);
+        } else {
+            sc = DcPodAnyClusterSearch.create();
+
+        }
+        sc.setParameters("datacenterId", datacenterId);
+        sc.setParameters("podId", podId);
+        sc.setParameters("status", Status.Up);
+        if (scope != null) {
+            sc.setParameters("scope", scope);
+        }
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> listPoolByHostPath(String host, String path) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("hostAddress", host);
+        sc.setParameters("path", path);
+
+        return listBy(sc);
+    }
+
+    public StoragePoolVO listById(Integer id) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("id", id);
+
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    @DB
+    public StoragePoolVO persist(StoragePoolVO pool, Map<String, String> details, List<String> tags) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        pool = super.persist(pool);
+        if (details != null) {
+            for (Map.Entry<String, String> detail : details.entrySet()) {
+                StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue(), true);
+                _detailsDao.persist(vo);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(tags)) {
+            _tagsDao.persist(pool.getId(), tags);
+        }
+        txn.commit();
+        return pool;
+    }
+
+    /**
+     * Internal helper method to retrieve storage pools by given details or storage tags.
+     * @param dcId data center id
+     * @param podId pod id
+     * @param clusterId cluster id
+     * @param scope score
+     * @param sqlValues sql string containing details or storage tags values required to query
+     * @param valuesType enumerate to indicate if values are related to details or storage tags
+     * @param valuesLength values length
+     * @return list of storage pools matching conditions
+     */
+    protected List<StoragePoolVO> findPoolsByDetailsOrTagsInternal(long dcId, long podId, Long clusterId, ScopeType scope, String sqlValues, ValueType valuesType,
+            int valuesLength) {
+        String sqlPrefix = valuesType.equals(ValueType.DETAILS) ? DetailsSqlPrefix : TagsSqlPrefix;
+        String sqlSuffix = valuesType.equals(ValueType.DETAILS) ? DetailsSqlSuffix : TagsSqlSuffix;
+        String sql = getSqlPreparedStatement(sqlPrefix, sqlSuffix, sqlValues, clusterId);
+        return searchStoragePoolsPreparedStatement(sql, dcId, podId, clusterId, scope, valuesLength);
+    }
+
+    /**
+     * Search storage pools in a transaction
+     * @param sql prepared statement sql
+     * @param dcId data center id
+     * @param podId pod id
+     * @param clusterId cluster id
+     * @param scope scope
+     * @param valuesLength values length
+     * @return storage pools matching criteria
+     */
+    @DB
+    protected List<StoragePoolVO> searchStoragePoolsPreparedStatement(String sql, long dcId, Long podId, Long clusterId, ScopeType scope, int valuesLength) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
+        try (PreparedStatement pstmt = txn.prepareStatement(sql);) {
+            if (pstmt != null) {
+                int i = 1;
+                pstmt.setLong(i++, dcId);
+                if (podId != null) {
+                    pstmt.setLong(i++, podId);
+                }
+                pstmt.setString(i++, scope.toString());
+                if (clusterId != null) {
+                    pstmt.setLong(i++, clusterId);
+                }
+                pstmt.setInt(i++, valuesLength);
+                try (ResultSet rs = pstmt.executeQuery();) {
+                    while (rs.next()) {
+                        pools.add(toEntityBean(rs, false));
+                    }
+                } catch (SQLException e) {
+                    throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e);
+                }
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e);
+        }
+        return pools;
+    }
+
+    protected String getSqlPreparedStatement(String sqlPrefix, String sqlSuffix, String sqlValues, Long clusterId) {
+        StringBuilder sql = new StringBuilder(sqlPrefix);
+        if (clusterId != null) {
+            sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND (");
+        }
+        sql.append(sqlValues);
+        sql.append(sqlSuffix);
+        return sql.toString();
+    }
+
+    /**
+     * Return SQL string from details, to be placed between SQL Prefix and SQL Suffix when creating storage tags PreparedStatement.
+     * @param details storage pool details
+     * @return SQL string containing storage tag values to be Prefix and Suffix when creating PreparedStatement.
+     * @throws NullPointerException if details is null
+     * @throws IndexOutOfBoundsException if details is not null, but empty
+     */
+    protected String getSqlValuesFromDetails(Map<String, String> details) {
+        StringBuilder sqlValues = new StringBuilder();
+        for (Map.Entry<String, String> detail : details.entrySet()) {
+            sqlValues.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR ");
+        }
+        sqlValues.delete(sqlValues.length() - 4, sqlValues.length());
+        return sqlValues.toString();
+    }
+
+    /**
+     * Return SQL string from storage tags, to be placed between SQL Prefix and SQL Suffix when creating storage tags PreparedStatement.
+     * @param tags storage tags array
+     * @return SQL string containing storage tag values to be placed between Prefix and Suffix when creating PreparedStatement.
+     * @throws NullPointerException if tags is null
+     * @throws IndexOutOfBoundsException if tags is not null, but empty
+     */
+    protected String getSqlValuesFromStorageTags(String[] tags) throws NullPointerException, IndexOutOfBoundsException {
+        StringBuilder sqlValues = new StringBuilder();
+        for (String tag : tags) {
+            sqlValues.append("(storage_pool_tags.tag='").append(tag).append("') OR ");
+        }
+        sqlValues.delete(sqlValues.length() - 4, sqlValues.length());
+        return sqlValues.toString();
+    }
+
+    @DB
+    @Override
+    public List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details, ScopeType scope) {
+        String sqlValues = getSqlValuesFromDetails(details);
+        return findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, scope, sqlValues, ValueType.DETAILS, details.size());
+    }
+
+    @Override
+    public List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
+        List<StoragePoolVO> storagePools = null;
+        if (tags == null || tags.length == 0) {
+            storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER);
+        } else {
+            String sqlValues = getSqlValuesFromStorageTags(tags);
+            storagePools = findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, ScopeType.CLUSTER, sqlValues, ValueType.TAGS, tags.length);
+        }
+
+        return storagePools;
+    }
+
+    @Override
+    public List<StoragePoolVO> findDisabledPoolsByScope(long dcId, Long podId, Long clusterId, ScopeType scope) {
+        List<StoragePoolVO> storagePools = null;
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("status", StoragePoolStatus.Disabled);
+        sc.setParameters("scope", scope);
+
+        if (scope == ScopeType.ZONE) {
+            sc.setParameters("datacenterId", dcId);
+            storagePools = listBy(sc);
+        } else if ((scope == ScopeType.CLUSTER || scope == ScopeType.HOST) && podId != null && clusterId != null) {
+            sc.setParameters("datacenterId", dcId);
+            sc.setParameters("podId", podId);
+            sc.setParameters("clusterId", clusterId);
+            storagePools = listBy(sc);
+        }
+
+        return storagePools;
+    }
+
+    @Override
+    public List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
+        List<StoragePoolVO> storagePools = null;
+        if (tags == null || tags.length == 0) {
+            storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST);
+        } else {
+            String sqlValues = getSqlValuesFromStorageTags(tags);
+            storagePools = findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, ScopeType.HOST, sqlValues, ValueType.TAGS, tags.length);
+        }
+
+        return storagePools;
+    }
+
+    @Override
+    public List<StoragePoolVO> findLocalStoragePoolsByHostAndTags(long hostId, String[] tags) {
+        SearchBuilder<StoragePoolVO> hostSearch = createSearchBuilder();
+        SearchBuilder<StoragePoolHostVO> hostPoolSearch = _hostDao.createSearchBuilder();
+        SearchBuilder<StoragePoolTagVO> tagPoolSearch = _tagsDao.createSearchBuilder();
+        ;
+
+        // Search for pools on the host
+        hostPoolSearch.and("hostId", hostPoolSearch.entity().getHostId(), Op.EQ);
+        // Set criteria for pools
+        hostSearch.and("scope", hostSearch.entity().getScope(), Op.EQ);
+        hostSearch.and("removed", hostSearch.entity().getRemoved(), Op.NULL);
+        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
+        hostSearch.join("hostJoin", hostPoolSearch, hostSearch.entity().getId(), hostPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER);
+
+        if (!(tags == null || tags.length == 0)) {
+            tagPoolSearch.and("tag", tagPoolSearch.entity().getTag(), Op.EQ);
+            hostSearch.join("tagJoin", tagPoolSearch, hostSearch.entity().getId(), tagPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<StoragePoolVO> sc = hostSearch.create();
+        sc.setJoinParameters("hostJoin", "hostId", hostId);
+        sc.setParameters("scope", ScopeType.HOST.toString());
+        sc.setParameters("status", Status.Up.toString());
+
+        if (!(tags == null || tags.length == 0)) {
+            for (String tag : tags) {
+                sc.setJoinParameters("tagJoin", "tag", tag);
+            }
+        }
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> findZoneWideStoragePoolsByTags(long dcId, String[] tags) {
+        if (tags == null || tags.length == 0) {
+            QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
+            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+            sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+            sc.and(sc.entity().getScope(), Op.EQ, ScopeType.ZONE);
+            return sc.list();
+        } else {
+            String sqlValues = getSqlValuesFromStorageTags(tags);
+            String sql = getSqlPreparedStatement(ZoneWideTagsSqlPrefix, ZoneWideTagsSqlSuffix, sqlValues, null);
+            return searchStoragePoolsPreparedStatement(sql, dcId, null, null, ScopeType.ZONE, tags.length);
+        }
+    }
+
+    @Override
+    public List<String> searchForStoragePoolTags(long poolId) {
+        return _tagsDao.getStoragePoolTags(poolId);
+    }
+
+    @Override
+    public void updateDetails(long poolId, Map<String, String> details) {
+        if (details != null) {
+            List<StoragePoolDetailVO> detailsVO = new ArrayList<StoragePoolDetailVO>();
+            for (String key : details.keySet()) {
+                detailsVO.add(new StoragePoolDetailVO(poolId, key, details.get(key), true));
+            }
+            _detailsDao.saveDetails(detailsVO);
+            if (details.size() == 0) {
+                _detailsDao.removeDetails(poolId);
+            }
+        }
+    }
+
+    @Override
+    public Map<String, String> getDetails(long poolId) {
+        return _detailsDao.listDetailsKeyPairs(poolId);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        _detailsDao.configure("DetailsDao", params);
+        return true;
+    }
+
+    @Override
+    public long countPoolsByStatus(StoragePoolStatus... statuses) {
+        SearchCriteria<Long> sc = StatusCountSearch.create();
+
+        sc.setParameters("status", (Object[])statuses);
+
+        List<Long> rs = customSearchIncludingRemoved(sc, null);
+        if (rs.size() == 0) {
+            return 0;
+        }
+
+        return rs.get(0);
+    }
+
+    @Override
+    public List<StoragePoolVO> listPoolsByCluster(long clusterId) {
+        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
+        sc.setParameters("clusterId", clusterId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType) {
+        QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dataCenterId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getScope(), Op.EQ, ScopeType.ZONE);
+        sc.and(sc.entity().getHypervisor(), Op.EQ, hypervisorType);
+        return sc.list();
+    }
+
+    @Override
+    public void deletePoolTags(long poolId) {
+        _tagsDao.deleteTags(poolId);
+    }
+}
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
new file mode 100644
index 0000000..50f311a
--- /dev/null
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.datastore.db;
+
+import java.util.List;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+
+import com.cloud.storage.DataStoreRole;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
+
+public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Long>,
+StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
+
+    List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role);
+
+    List<SnapshotDataStoreVO> listActiveOnCache(long id);
+
+    void deletePrimaryRecordsForStore(long id, DataStoreRole role);
+
+    SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId);
+
+    SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId);
+
+    SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role);
+
+    List<SnapshotDataStoreVO> listDestroyed(long storeId);
+
+    List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId);
+
+    void duplicateCacheRecordsOnRegionStore(long storeId);
+
+    // delete the snapshot entry on primary data store to make sure that next snapshot will be full snapshot
+    void deleteSnapshotRecordsOnPrimary();
+
+    SnapshotDataStoreVO findReadyOnCache(long snapshotId);
+
+    List<SnapshotDataStoreVO> listOnCache(long snapshotId);
+
+    void updateStoreRoleToCache(long storeId);
+
+    SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role);
+
+    SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role);
+
+    void updateVolumeIds(long oldVolId, long newVolId);
+
+    SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role);
+
+    /**
+     * List all snapshots in 'snapshot_store_ref' by volume and data store role. Therefore, it is possible to list all snapshots that are in the primary storage or in the secondary storage.
+     */
+    List<SnapshotDataStoreVO> listAllByVolumeAndDataStore(long volumeId, DataStoreRole role);
+
+    List<SnapshotDataStoreVO> listByState(ObjectInDataStoreStateMachine.State... states);
+}
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolDetailsDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
similarity index 100%
rename from engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
rename to engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
similarity index 100%
rename from engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
rename to engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
diff --git a/engine/schema/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml
similarity index 100%
rename from engine/schema/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml
rename to engine/schema/src/main/resources/META-INF/cloudstack/system/spring-engine-schema-system-checkers-context.xml
diff --git a/engine/schema/resources/META-INF/db/create-default-role-api-mappings.sql b/engine/schema/src/main/resources/META-INF/db/create-default-role-api-mappings.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/create-default-role-api-mappings.sql
rename to engine/schema/src/main/resources/META-INF/db/create-default-role-api-mappings.sql
diff --git a/engine/schema/resources/META-INF/db/data-217to218.sql b/engine/schema/src/main/resources/META-INF/db/data-217to218.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/data-217to218.sql
rename to engine/schema/src/main/resources/META-INF/db/data-217to218.sql
diff --git a/engine/schema/resources/META-INF/db/schema-20to21.sql b/engine/schema/src/main/resources/META-INF/db/schema-20to21.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-20to21.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-20to21.sql
diff --git a/engine/schema/resources/META-INF/db/schema-217to218.sql b/engine/schema/src/main/resources/META-INF/db/schema-217to218.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-217to218.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-217to218.sql
diff --git a/engine/schema/resources/META-INF/db/schema-21to22-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-21to22-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-21to22-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-21to22-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-21to22-premium.sql b/engine/schema/src/main/resources/META-INF/db/schema-21to22-premium.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-21to22-premium.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-21to22-premium.sql
diff --git a/engine/schema/resources/META-INF/db/schema-21to22.sql b/engine/schema/src/main/resources/META-INF/db/schema-21to22.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-21to22.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-21to22.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2210to2211.sql b/engine/schema/src/main/resources/META-INF/db/schema-2210to2211.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2210to2211.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2210to2211.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2211to2212-premium.sql b/engine/schema/src/main/resources/META-INF/db/schema-2211to2212-premium.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2211to2212-premium.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2211to2212-premium.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2211to2212.sql b/engine/schema/src/main/resources/META-INF/db/schema-2211to2212.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2211to2212.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2211to2212.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2212to2213.sql b/engine/schema/src/main/resources/META-INF/db/schema-2212to2213.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2212to2213.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2212to2213.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2213to2214.sql b/engine/schema/src/main/resources/META-INF/db/schema-2213to2214.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2213to2214.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2213to2214.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2214to30-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-2214to30-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2214to30-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2214to30-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-2214to30.sql b/engine/schema/src/main/resources/META-INF/db/schema-2214to30.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-2214to30.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-2214to30.sql
diff --git a/engine/schema/resources/META-INF/db/schema-221to222-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-221to222-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-221to222-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-221to222-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-221to222-premium.sql b/engine/schema/src/main/resources/META-INF/db/schema-221to222-premium.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-221to222-premium.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-221to222-premium.sql
diff --git a/engine/schema/resources/META-INF/db/schema-221to222.sql b/engine/schema/src/main/resources/META-INF/db/schema-221to222.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-221to222.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-221to222.sql
diff --git a/engine/schema/resources/META-INF/db/schema-222to224-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-222to224-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-222to224-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-222to224-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-222to224-premium.sql b/engine/schema/src/main/resources/META-INF/db/schema-222to224-premium.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-222to224-premium.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-222to224-premium.sql
diff --git a/engine/schema/resources/META-INF/db/schema-222to224.sql b/engine/schema/src/main/resources/META-INF/db/schema-222to224.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-222to224.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-222to224.sql
diff --git a/engine/schema/resources/META-INF/db/schema-224to225-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-224to225-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-224to225-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-224to225-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-224to225.sql b/engine/schema/src/main/resources/META-INF/db/schema-224to225.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-224to225.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-224to225.sql
diff --git a/engine/schema/resources/META-INF/db/schema-225to226.sql b/engine/schema/src/main/resources/META-INF/db/schema-225to226.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-225to226.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-225to226.sql
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-227to228-premium.sql b/engine/schema/src/main/resources/META-INF/db/schema-227to228-premium.sql
new file mode 100755
index 0000000..26d555e
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-227to228-premium.sql
@@ -0,0 +1,37 @@
+-- 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.
+
+--;
+-- Schema upgrade from 2.2.7 to 2.2.8;
+--;
+
+--;
+-- Cleanup usage records for bug # 10727;
+--;
+
+
+create table `cloud_usage`.`temp_usage` (  `vol_id` bigint unsigned, `created` DATETIME);
+
+insert into `cloud_usage`.`temp_usage` (vol_id, created) select id, max(created) from `cloud_usage`.`usage_volume` where deleted is null group by id having count(id) > 1;
+
+delete `cloud_usage`.`usage_volume` from `cloud_usage`.`usage_volume` inner join `cloud_usage`.`temp_usage` where `cloud_usage`.`usage_volume`.created = `cloud_usage`.`temp_usage`.created and `cloud_usage`.`usage_volume`.id = `cloud_usage`.`temp_usage`.vol_id and `cloud_usage`.`usage_volume`.deleted is null;
+
+drop table `cloud_usage`.`temp_usage`;
+
+update `cloud_usage`.`cloud_usage` set raw_usage = (raw_usage % 24) where usage_type =6 and raw_usage > 24 and (raw_usage % 24) <> 0;
+update `cloud_usage`.`cloud_usage` set raw_usage = 24 where usage_type =6 and raw_usage > 24 and (raw_usage % 24) = 0;
+
diff --git a/engine/schema/resources/META-INF/db/schema-227to228.sql b/engine/schema/src/main/resources/META-INF/db/schema-227to228.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-227to228.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-227to228.sql
diff --git a/engine/schema/resources/META-INF/db/schema-228to229.sql b/engine/schema/src/main/resources/META-INF/db/schema-228to229.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-228to229.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-228to229.sql
diff --git a/engine/schema/resources/META-INF/db/schema-229to2210.sql b/engine/schema/src/main/resources/META-INF/db/schema-229to2210.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-229to2210.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-229to2210.sql
diff --git a/engine/schema/resources/META-INF/db/schema-22beta1to22beta2.sql b/engine/schema/src/main/resources/META-INF/db/schema-22beta1to22beta2.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-22beta1to22beta2.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-22beta1to22beta2.sql
diff --git a/engine/schema/resources/META-INF/db/schema-22beta3to22beta4.sql b/engine/schema/src/main/resources/META-INF/db/schema-22beta3to22beta4.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-22beta3to22beta4.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-22beta3to22beta4.sql
diff --git a/engine/schema/resources/META-INF/db/schema-301to302-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-301to302-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-301to302-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-301to302-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-301to302.sql b/engine/schema/src/main/resources/META-INF/db/schema-301to302.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-301to302.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-301to302.sql
diff --git a/engine/schema/resources/META-INF/db/schema-302to303.sql b/engine/schema/src/main/resources/META-INF/db/schema-302to303.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-302to303.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-302to303.sql
diff --git a/engine/schema/resources/META-INF/db/schema-302to40-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-302to40-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-302to40-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-302to40-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-302to40.sql b/engine/schema/src/main/resources/META-INF/db/schema-302to40.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-302to40.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-302to40.sql
diff --git a/engine/schema/resources/META-INF/db/schema-304to305-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-304to305-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-304to305-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-304to305-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-304to305.sql b/engine/schema/src/main/resources/META-INF/db/schema-304to305.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-304to305.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-304to305.sql
diff --git a/engine/schema/resources/META-INF/db/schema-305to306-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-305to306-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-305to306-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-305to306-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-305to306.sql b/engine/schema/src/main/resources/META-INF/db/schema-305to306.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-305to306.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-305to306.sql
diff --git a/engine/schema/resources/META-INF/db/schema-306to307.sql b/engine/schema/src/main/resources/META-INF/db/schema-306to307.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-306to307.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-306to307.sql
diff --git a/engine/schema/resources/META-INF/db/schema-307to410-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-307to410-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-307to410-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-307to410-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-307to410.sql b/engine/schema/src/main/resources/META-INF/db/schema-307to410.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-307to410.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-307to410.sql
diff --git a/engine/schema/resources/META-INF/db/schema-30to301.sql b/engine/schema/src/main/resources/META-INF/db/schema-30to301.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-30to301.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-30to301.sql
diff --git a/engine/schema/resources/META-INF/db/schema-40to410-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-40to410-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-40to410-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-40to410-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-40to410.sql b/engine/schema/src/main/resources/META-INF/db/schema-40to410.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-40to410.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-40to410.sql
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41000to41100-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-41000to41100-cleanup.sql
new file mode 100644
index 0000000..f8d9ce9
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41000to41100-cleanup.sql
@@ -0,0 +1,69 @@
+-- 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.
+
+--;
+-- Schema upgrade cleanup from 4.10.0.0 to 4.11.0.0
+--;
+
+DELETE FROM `cloud`.`configuration` WHERE name='snapshot.backup.rightafter';
+-- CLOUDSTACK-9914: Alter quota_tariff to support currency values up to 5 decimal places
+ALTER TABLE `cloud_usage`.`quota_tariff` MODIFY `currency_value` DECIMAL(15,5) not null;
+
+DROP VIEW IF EXISTS `cloud`.`user_view`;
+CREATE VIEW `cloud`.`user_view` AS
+    select
+        user.id,
+        user.uuid,
+        user.username,
+        user.password,
+        user.firstname,
+        user.lastname,
+        user.email,
+        user.state,
+        user.api_key,
+        user.secret_key,
+        user.created,
+        user.removed,
+        user.timezone,
+        user.registration_token,
+        user.is_registered,
+        user.incorrect_login_attempts,
+        user.source,
+        user.default,
+        account.id account_id,
+        account.uuid account_uuid,
+        account.account_name account_name,
+        account.type account_type,
+        account.role_id account_role_id,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path,
+        async_job.id job_id,
+        async_job.uuid job_uuid,
+        async_job.job_status job_status,
+        async_job.account_id job_account_id
+    from
+        `cloud`.`user`
+            inner join
+        `cloud`.`account` ON user.account_id = account.id
+            inner join
+        `cloud`.`domain` ON account.domain_id = domain.id
+            left join
+        `cloud`.`async_job` ON async_job.instance_id = user.id
+            and async_job.instance_type = 'User'
+            and async_job.job_status = 0;
\ No newline at end of file
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41000to41100.sql b/engine/schema/src/main/resources/META-INF/db/schema-41000to41100.sql
new file mode 100644
index 0000000..2db644f
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41000to41100.sql
@@ -0,0 +1,610 @@
+-- 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.
+
+--;
+-- Schema upgrade from 4.10.0.0 to 4.11.0.0
+--;
+
+--;
+-- Stored procedure to do idempotent column add;
+--;
+DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_ADD_COLUMN`;
+
+CREATE PROCEDURE `cloud`.`IDEMPOTENT_ADD_COLUMN` (
+		IN in_table_name VARCHAR(200)
+    , IN in_column_name VARCHAR(200)
+    , IN in_column_definition VARCHAR(1000)
+)
+BEGIN
+
+    DECLARE CONTINUE HANDLER FOR 1060 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', 'ADD COLUMN') ; SET @ddl = CONCAT(@ddl, ' ', in_column_name); SET @ddl = CONCAT(@ddl, ' ', in_column_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
+
+DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`;
+
+CREATE PROCEDURE `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY` (
+		IN in_table_name VARCHAR(200)
+    , IN in_foreign_key_name VARCHAR(200)
+)
+BEGIN
+
+    DECLARE CONTINUE HANDLER FOR 1091 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', ' DROP FOREIGN KEY '); SET @ddl = CONCAT(@ddl, ' ', in_foreign_key_name); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
+
+DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_DROP_INDEX`;
+
+CREATE PROCEDURE `cloud`.`IDEMPOTENT_DROP_INDEX` (
+		IN in_index_name VARCHAR(200)
+    , IN in_table_name VARCHAR(200)
+)
+BEGIN
+
+    DECLARE CONTINUE HANDLER FOR 1091 BEGIN END; SET @ddl = CONCAT('DROP INDEX ', in_index_name); SET @ddl = CONCAT(@ddl, ' ', ' ON ') ; SET @ddl = CONCAT(@ddl, ' ', in_table_name); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
+
+DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX`;
+
+CREATE PROCEDURE `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX` (
+		IN in_index_name VARCHAR(200)
+    , IN in_table_name VARCHAR(200)
+    , IN in_index_definition VARCHAR(1000)
+)
+BEGIN
+
+    DECLARE CONTINUE HANDLER FOR 1061 BEGIN END; SET @ddl = CONCAT('CREATE UNIQUE INDEX ', in_index_name); SET @ddl = CONCAT(@ddl, ' ', ' ON ') ; SET @ddl = CONCAT(@ddl, ' ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', in_index_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
+
+-- Add For VPC flag
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','for_vpc', 'INT(1) NOT NULL DEFAULT 0');
+
+UPDATE cloud.network_offerings o
+SET for_vpc = 1
+where
+  o.conserve_mode = 0
+  and o.guest_type = 'Isolated'
+  and exists(
+    SELECT id
+    from cloud.ntwk_offering_service_map
+    where network_offering_id = o.id and (
+      provider in ('VpcVirtualRouter', 'InternalLbVm', 'JuniperContrailVpcRouter')
+      or service in ('NetworkACL')
+    )
+  );
+
+UPDATE `cloud`.`configuration` SET value = '600', default_value = '600' WHERE category = 'Advanced' AND name = 'router.aggregation.command.each.timeout';
+
+-- CA framework changes
+DELETE from `cloud`.`configuration` where name='ssl.keystore';
+
+-- Certificate Revocation List
+CREATE TABLE IF NOT EXISTS `cloud`.`crl` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `serial` varchar(255) UNIQUE NOT NULL COMMENT 'certificate\'s serial number as hex string',
+  `cn` varchar(255) COMMENT 'certificate\'s common name',
+  `revoker_uuid` varchar(40) COMMENT 'revoker user account uuid',
+  `revoked` datetime COMMENT 'date of revocation',
+  PRIMARY KEY (`id`),
+  KEY (`serial`),
+  UNIQUE KEY (`serial`, `cn`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- Host HA feature
+CREATE TABLE IF NOT EXISTS `cloud`.`ha_config` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `resource_id` bigint(20) unsigned DEFAULT NULL COMMENT 'id of the resource',
+  `resource_type` varchar(255) NOT NULL COMMENT 'the type of the resource',
+  `enabled` int(1) unsigned DEFAULT '0' COMMENT 'is HA enabled for the resource',
+  `ha_state` varchar(255) DEFAULT 'Disabled' COMMENT 'HA state',
+  `provider` varchar(255) DEFAULT NULL COMMENT 'HA provider',
+  `update_count` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'state based incr-only counter for atomic ha_state updates',
+  `update_time` datetime COMMENT 'last ha_state update datetime',
+  `mgmt_server_id` bigint(20) unsigned DEFAULT NULL COMMENT 'management server id that is responsible for the HA for the resource',
+  PRIMARY KEY (`id`),
+  KEY `i_ha_config__enabled` (`enabled`),
+  KEY `i_ha_config__ha_state` (`ha_state`),
+  KEY `i_ha_config__mgmt_server_id` (`mgmt_server_id`),
+  UNIQUE KEY (`resource_id`, `resource_type`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DELETE from `cloud`.`configuration` where name='outofbandmanagement.sync.interval';
+
+-- Annotations specifc changes following
+CREATE TABLE IF NOT EXISTS `cloud`.`annotations` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `uuid` varchar(40) UNIQUE,
+  `annotation` text,
+  `entity_uuid` varchar(40),
+  `entity_type` varchar(32),
+  `user_uuid` varchar(40),
+  `created` datetime COMMENT 'date of creation',
+  `removed` datetime COMMENT 'date of removal',
+  PRIMARY KEY (`id`),
+  KEY (`uuid`),
+  KEY `i_entity` (`entity_uuid`, `entity_type`, `created`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP VIEW IF EXISTS `cloud`.`last_annotation_view`;
+CREATE VIEW `cloud`.`last_annotation_view` AS
+    SELECT
+        `annotations`.`uuid` AS `uuid`,
+        `annotations`.`annotation` AS `annotation`,
+        `annotations`.`entity_uuid` AS `entity_uuid`,
+        `annotations`.`entity_type` AS `entity_type`,
+        `annotations`.`user_uuid` AS `user_uuid`,
+        `annotations`.`created` AS `created`,
+        `annotations`.`removed` AS `removed`
+    FROM
+        `annotations`
+    WHERE
+        `annotations`.`created` IN (SELECT
+                                        MAX(`annotations`.`created`)
+                                    FROM
+                                        `annotations`
+                                    WHERE
+                                        `annotations`.`removed` IS NULL
+                                    GROUP BY `annotations`.`entity_uuid`);
+
+-- Host HA changes:
+DROP VIEW IF EXISTS `cloud`.`host_view`;
+CREATE VIEW `cloud`.`host_view` AS
+    SELECT
+        host.id,
+        host.uuid,
+        host.name,
+        host.status,
+        host.disconnected,
+        host.type,
+        host.private_ip_address,
+        host.version,
+        host.hypervisor_type,
+        host.hypervisor_version,
+        host.capabilities,
+        host.last_ping,
+        host.created,
+        host.removed,
+        host.resource_state,
+        host.mgmt_server_id,
+        host.cpu_sockets,
+        host.cpus,
+        host.speed,
+        host.ram,
+        cluster.id cluster_id,
+        cluster.uuid cluster_uuid,
+        cluster.name cluster_name,
+        cluster.cluster_type,
+        data_center.id data_center_id,
+        data_center.uuid data_center_uuid,
+        data_center.name data_center_name,
+        data_center.networktype data_center_type,
+        host_pod_ref.id pod_id,
+        host_pod_ref.uuid pod_uuid,
+        host_pod_ref.name pod_name,
+        host_tags.tag,
+        guest_os_category.id guest_os_category_id,
+        guest_os_category.uuid guest_os_category_uuid,
+        guest_os_category.name guest_os_category_name,
+        mem_caps.used_capacity memory_used_capacity,
+        mem_caps.reserved_capacity memory_reserved_capacity,
+        cpu_caps.used_capacity cpu_used_capacity,
+        cpu_caps.reserved_capacity cpu_reserved_capacity,
+        async_job.id job_id,
+        async_job.uuid job_uuid,
+        async_job.job_status job_status,
+        async_job.account_id job_account_id,
+        oobm.enabled AS `oobm_enabled`,
+        oobm.power_state AS `oobm_power_state`,
+        ha_config.enabled AS `ha_enabled`,
+        ha_config.ha_state AS `ha_state`,
+        ha_config.provider AS `ha_provider`,
+        `last_annotation_view`.`annotation` AS `annotation`,
+        `last_annotation_view`.`created` AS `last_annotated`,
+        `user`.`username` AS `username`
+    FROM
+        `cloud`.`host`
+            LEFT JOIN
+        `cloud`.`cluster` ON host.cluster_id = cluster.id
+            LEFT JOIN
+        `cloud`.`data_center` ON host.data_center_id = data_center.id
+            LEFT JOIN
+        `cloud`.`host_pod_ref` ON host.pod_id = host_pod_ref.id
+            LEFT JOIN
+        `cloud`.`host_details` ON host.id = host_details.host_id
+            AND host_details.name = 'guest.os.category.id'
+            LEFT JOIN
+        `cloud`.`guest_os_category` ON guest_os_category.id = CONVERT ( host_details.value, UNSIGNED )
+            LEFT JOIN
+        `cloud`.`host_tags` ON host_tags.host_id = host.id
+            LEFT JOIN
+        `cloud`.`op_host_capacity` mem_caps ON host.id = mem_caps.host_id
+            AND mem_caps.capacity_type = 0
+            LEFT JOIN
+        `cloud`.`op_host_capacity` cpu_caps ON host.id = cpu_caps.host_id
+            AND cpu_caps.capacity_type = 1
+            LEFT JOIN
+        `cloud`.`async_job` ON async_job.instance_id = host.id
+            AND async_job.instance_type = 'Host'
+            AND async_job.job_status = 0
+            LEFT JOIN
+        `cloud`.`oobm` ON oobm.host_id = host.id
+            left join
+        `cloud`.`ha_config` ON ha_config.resource_id=host.id
+            and ha_config.resource_type='Host'
+            LEFT JOIN
+        `cloud`.`last_annotation_view` ON `last_annotation_view`.`entity_uuid` = `host`.`uuid`
+            LEFT JOIN
+        `cloud`.`user` ON `user`.`uuid` = `last_annotation_view`.`user_uuid`;
+-- End Of Annotations specific changes
+
+-- Out-of-band management driver for nested-cloudstack
+ALTER TABLE `cloud`.`oobm` MODIFY COLUMN port VARCHAR(255);
+
+-- CLOUDSTACK-9902: Console proxy SSL toggle
+INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `description`, `default_value`, `is_dynamic`) VALUES ('Console Proxy', 'DEFAULT', 'AgentManager', 'consoleproxy.sslEnabled', 'false', 'Enable SSL for console proxy', 'false', 0);
+
+-- CLOUDSTACK-9859: Retirement of midonet plugin (final removal)
+delete from `cloud`.`configuration` where name in ('midonet.apiserver.address', 'midonet.providerrouter.id');
+
+-- CLOUDSTACK-9972: Enhance listVolumes API
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Premium', 'DEFAULT', 'management-server', 'volume.stats.interval', '600000', 'Interval (in seconds) to report volume statistics', '600000', now(), NULL, NULL);
+
+DROP VIEW IF EXISTS `cloud`.`volume_view`;
+CREATE VIEW `cloud`.`volume_view` AS
+    SELECT
+        volumes.id,
+        volumes.uuid,
+        volumes.name,
+        volumes.device_id,
+        volumes.volume_type,
+        volumes.provisioning_type,
+        volumes.size,
+        volumes.min_iops,
+        volumes.max_iops,
+        volumes.created,
+        volumes.state,
+        volumes.attached,
+        volumes.removed,
+        volumes.display_volume,
+        volumes.format,
+        volumes.path,
+        volumes.chain_info,
+        account.id account_id,
+        account.uuid account_uuid,
+        account.account_name account_name,
+        account.type account_type,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path,
+        projects.id project_id,
+        projects.uuid project_uuid,
+        projects.name project_name,
+        data_center.id data_center_id,
+        data_center.uuid data_center_uuid,
+        data_center.name data_center_name,
+        data_center.networktype data_center_type,
+        vm_instance.id vm_id,
+        vm_instance.uuid vm_uuid,
+        vm_instance.name vm_name,
+        vm_instance.state vm_state,
+        vm_instance.vm_type,
+        user_vm.display_name vm_display_name,
+        volume_store_ref.size volume_store_size,
+        volume_store_ref.download_pct,
+        volume_store_ref.download_state,
+        volume_store_ref.error_str,
+        volume_store_ref.created created_on_store,
+        disk_offering.id disk_offering_id,
+        disk_offering.uuid disk_offering_uuid,
+        disk_offering.name disk_offering_name,
+        disk_offering.display_text disk_offering_display_text,
+        disk_offering.use_local_storage,
+        disk_offering.system_use,
+        disk_offering.bytes_read_rate,
+        disk_offering.bytes_write_rate,
+        disk_offering.iops_read_rate,
+        disk_offering.iops_write_rate,
+        disk_offering.cache_mode,
+        storage_pool.id pool_id,
+        storage_pool.uuid pool_uuid,
+        storage_pool.name pool_name,
+        cluster.id cluster_id,
+        cluster.name cluster_name,
+        cluster.uuid cluster_uuid,
+        cluster.hypervisor_type,
+        vm_template.id template_id,
+        vm_template.uuid template_uuid,
+        vm_template.extractable,
+        vm_template.type template_type,
+        vm_template.name template_name,
+        vm_template.display_text template_display_text,
+        iso.id iso_id,
+        iso.uuid iso_uuid,
+        iso.name iso_name,
+        iso.display_text iso_display_text,
+        resource_tags.id tag_id,
+        resource_tags.uuid tag_uuid,
+        resource_tags.key tag_key,
+        resource_tags.value tag_value,
+        resource_tags.domain_id tag_domain_id,
+        resource_tags.account_id tag_account_id,
+        resource_tags.resource_id tag_resource_id,
+        resource_tags.resource_uuid tag_resource_uuid,
+        resource_tags.resource_type tag_resource_type,
+        resource_tags.customer tag_customer,
+        async_job.id job_id,
+        async_job.uuid job_uuid,
+        async_job.job_status job_status,
+        async_job.account_id job_account_id,
+        host_pod_ref.id pod_id,
+        host_pod_ref.uuid pod_uuid,
+        host_pod_ref.name pod_name,
+        resource_tag_account.account_name tag_account_name,
+        resource_tag_domain.uuid tag_domain_uuid,
+        resource_tag_domain.name tag_domain_name
+    from
+        `cloud`.`volumes`
+            inner join
+        `cloud`.`account` ON volumes.account_id = account.id
+            inner join
+        `cloud`.`domain` ON volumes.domain_id = domain.id
+            left join
+        `cloud`.`projects` ON projects.project_account_id = account.id
+            left join
+        `cloud`.`data_center` ON volumes.data_center_id = data_center.id
+            left join
+        `cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id
+            left join
+        `cloud`.`user_vm` ON user_vm.id = vm_instance.id
+            left join
+        `cloud`.`volume_store_ref` ON volumes.id = volume_store_ref.volume_id
+            left join
+        `cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id
+            left join
+        `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id
+            left join
+        `cloud`.`host_pod_ref` ON storage_pool.pod_id = host_pod_ref.id
+            left join
+        `cloud`.`cluster` ON storage_pool.cluster_id = cluster.id
+            left join
+        `cloud`.`vm_template` ON volumes.template_id = vm_template.id
+            left join
+        `cloud`.`vm_template` iso ON iso.id = volumes.iso_id
+            left join
+        `cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id
+            and resource_tags.resource_type = 'Volume'
+            left join
+        `cloud`.`async_job` ON async_job.instance_id = volumes.id
+            and async_job.instance_type = 'Volume'
+            and async_job.job_status = 0
+            left join
+        `cloud`.`account` resource_tag_account ON resource_tag_account.id = resource_tags.account_id
+            left join
+        `cloud`.`domain` resource_tag_domain ON resource_tag_domain.id = resource_tags.domain_id;
+
+-- Extra Dhcp Options
+CREATE TABLE IF NOT EXISTS `cloud`.`nic_extra_dhcp_options` (
+  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `uuid` varchar(255) UNIQUE,
+  `nic_id` bigint unsigned NOT NULL COMMENT ' nic id where dhcp options are applied',
+  `code` int(32),
+  `value` text,
+  PRIMARY KEY (`id`),
+  CONSTRAINT `fk_nic_extra_dhcp_options_nic_id` FOREIGN KEY (`nic_id`) REFERENCES `nics`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- Add new OS versions
+
+-- Add XenServer 7.1 and 7.2 hypervisor capabilities
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, storage_motion_supported) values (UUID(), 'XenServer', '7.1.0', 500, 13, 1);
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, storage_motion_supported) values (UUID(), 'XenServer', '7.2.0', 500, 13, 1);
+
+-- Add XenServer 7.0 support for windows 10
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.0.0', 'Windows 10 (64-bit)', 258, now(), 0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.0.0', 'Windows 10 (32-bit)', 257, now(), 0);
+
+-- Add XenServer 7.1 hypervisor guest OS mappings (copy 7.0.0)
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '7.1.0', guest_os_name, guest_os_id, utc_timestamp(), 0  FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='7.0.0';
+
+-- Add XenServer 7.1 hypervisor guest OS (see https://docs.citrix.com/content/dam/docs/en-us/xenserver/7-1/downloads/xenserver-7-1-release-notes.pdf)
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Windows Server 2016 (64-bit)', 259, now(), 0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'SUSE Linux Enterprise Server 11 SP4', 187, now(),  0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Red Hat Enterprise Linux 6 (64-bit)', 240, now(),  0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Red Hat Enterprise Linux 7', 245, now(),  0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Oracle Enterprise Linux 6 (64-bit)', 251, now(),  0);
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'Xenserver', '7.1.0', 'Oracle Linux 7', 247, now(),  0);
+
+-- Add XenServer 7.2 hypervisor guest OS mappings (copy 7.1.0 & remove Windows Vista, Windows XP, Windows 2003, CentOS 4.x, RHEL 4.xS, LES 10 (all versions) as per XenServer 7.2 Release Notes)
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '7.2.0', guest_os_name, guest_os_id, utc_timestamp(), 0  FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='7.1.0' AND guest_os_id not in (1,2,3,4,56,101,56,58,93,94,50,51,87,88,89,90,91,92,26,27,28,29,40,41,42,43,44,45,96,97,107,108,109,110,151,152,153);
+
+-- Add table to track primary storage in use for snapshots
+CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_snapshot_on_primary` (
+  `id` bigint(20) unsigned NOT NULL,
+  `zone_id` bigint(20) unsigned NOT NULL,
+  `account_id` bigint(20) unsigned NOT NULL,
+  `domain_id` bigint(20) unsigned NOT NULL,
+  `vm_id` bigint(20) unsigned NOT NULL,
+  `name` varchar(128),
+  `type` int(1) unsigned NOT NULL,
+  `physicalsize` bigint(20),
+  `virtualsize` bigint(20),
+  `created` datetime NOT NULL,
+  `deleted` datetime,
+  INDEX `i_usage_snapshot_on_primary` (`account_id`,`id`,`vm_id`,`created`)
+) ENGINE=InnoDB CHARSET=utf8;
+
+-- Change monitor patch for apache2 in systemvm
+UPDATE `cloud`.`monitoring_services` SET pidfile="/var/run/apache2/apache2.pid" WHERE process_name="apache2" AND service_name="apache2";
+
+-- Use 'Other Linux 64-bit' as guest os for the default systemvmtemplate for VMware
+-- This fixes a memory allocation issue to systemvms on VMware/ESXi
+UPDATE `cloud`.`vm_template` SET guest_os_id=99 WHERE id=8;
+
+-- Network External Ids
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.networks','external_id', 'varchar(255)');
+
+-- Separate Subnet for CPVM and SSVM (system vms)
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.op_dc_ip_address_alloc','forsystemvms', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''Indicates if IP is dedicated for CPVM or SSVM'' ');
+
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.op_dc_ip_address_alloc','vlan', 'INT(10) UNSIGNED NULL COMMENT ''Vlan the management network range is on'' ');
+
+-- CLOUDSTACK-4757: Support multidisk OVA
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_template','parent_template_id', 'bigint(20) unsigned DEFAULT NULL COMMENT ''If datadisk template, then id of the root template this template belongs to'' ');
+
+-- CLOUDSTACK-10146: Bypass Secondary Storage for KVM templates
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_template','direct_download', 'TINYINT(1) DEFAULT 0 COMMENT ''Indicates if Secondary Storage is bypassed and template is downloaded to Primary Storage'' ');
+
+-- Changes to template_view for both multidisk OVA and bypass secondary storage for KVM templates
+DROP VIEW IF EXISTS `cloud`.`template_view`;
+CREATE VIEW `cloud`.`template_view` AS
+     SELECT
+         `vm_template`.`id` AS `id`,
+         `vm_template`.`uuid` AS `uuid`,
+         `vm_template`.`unique_name` AS `unique_name`,
+         `vm_template`.`name` AS `name`,
+         `vm_template`.`public` AS `public`,
+         `vm_template`.`featured` AS `featured`,
+         `vm_template`.`type` AS `type`,
+         `vm_template`.`hvm` AS `hvm`,
+         `vm_template`.`bits` AS `bits`,
+         `vm_template`.`url` AS `url`,
+         `vm_template`.`format` AS `format`,
+         `vm_template`.`created` AS `created`,
+         `vm_template`.`checksum` AS `checksum`,
+         `vm_template`.`display_text` AS `display_text`,
+         `vm_template`.`enable_password` AS `enable_password`,
+         `vm_template`.`dynamically_scalable` AS `dynamically_scalable`,
+         `vm_template`.`state` AS `template_state`,
+         `vm_template`.`guest_os_id` AS `guest_os_id`,
+         `guest_os`.`uuid` AS `guest_os_uuid`,
+         `guest_os`.`display_name` AS `guest_os_name`,
+         `vm_template`.`bootable` AS `bootable`,
+         `vm_template`.`prepopulate` AS `prepopulate`,
+         `vm_template`.`cross_zones` AS `cross_zones`,
+         `vm_template`.`hypervisor_type` AS `hypervisor_type`,
+         `vm_template`.`extractable` AS `extractable`,
+         `vm_template`.`template_tag` AS `template_tag`,
+         `vm_template`.`sort_key` AS `sort_key`,
+         `vm_template`.`removed` AS `removed`,
+         `vm_template`.`enable_sshkey` AS `enable_sshkey`,
+         `parent_template`.`id` AS `parent_template_id`,
+         `parent_template`.`uuid` AS `parent_template_uuid`,
+         `source_template`.`id` AS `source_template_id`,
+         `source_template`.`uuid` AS `source_template_uuid`,
+         `account`.`id` AS `account_id`,
+         `account`.`uuid` AS `account_uuid`,
+         `account`.`account_name` AS `account_name`,
+         `account`.`type` AS `account_type`,
+         `domain`.`id` AS `domain_id`,
+         `domain`.`uuid` AS `domain_uuid`,
+         `domain`.`name` AS `domain_name`,
+         `domain`.`path` AS `domain_path`,
+         `projects`.`id` AS `project_id`,
+         `projects`.`uuid` AS `project_uuid`,
+         `projects`.`name` AS `project_name`,
+         `data_center`.`id` AS `data_center_id`,
+         `data_center`.`uuid` AS `data_center_uuid`,
+         `data_center`.`name` AS `data_center_name`,
+         `launch_permission`.`account_id` AS `lp_account_id`,
+         `template_store_ref`.`store_id` AS `store_id`,
+         `image_store`.`scope` AS `store_scope`,
+         `template_store_ref`.`state` AS `state`,
+         `template_store_ref`.`download_state` AS `download_state`,
+         `template_store_ref`.`download_pct` AS `download_pct`,
+         `template_store_ref`.`error_str` AS `error_str`,
+         `template_store_ref`.`size` AS `size`,
+         `template_store_ref`.physical_size AS `physical_size`,
+         `template_store_ref`.`destroyed` AS `destroyed`,
+         `template_store_ref`.`created` AS `created_on_store`,
+         `vm_template_details`.`name` AS `detail_name`,
+         `vm_template_details`.`value` AS `detail_value`,
+         `resource_tags`.`id` AS `tag_id`,
+         `resource_tags`.`uuid` AS `tag_uuid`,
+         `resource_tags`.`key` AS `tag_key`,
+         `resource_tags`.`value` AS `tag_value`,
+         `resource_tags`.`domain_id` AS `tag_domain_id`,
+         `domain`.`uuid` AS `tag_domain_uuid`,
+         `domain`.`name` AS `tag_domain_name`,
+         `resource_tags`.`account_id` AS `tag_account_id`,
+         `account`.`account_name` AS `tag_account_name`,
+         `resource_tags`.`resource_id` AS `tag_resource_id`,
+         `resource_tags`.`resource_uuid` AS `tag_resource_uuid`,
+         `resource_tags`.`resource_type` AS `tag_resource_type`,
+         `resource_tags`.`customer` AS `tag_customer`,
+          CONCAT(`vm_template`.`id`,
+                 '_',
+                 IFNULL(`data_center`.`id`, 0)) AS `temp_zone_pair`,
+          `vm_template`.`direct_download` AS `direct_download`
+     FROM
+         (((((((((((((`vm_template`
+         JOIN `guest_os` ON ((`guest_os`.`id` = `vm_template`.`guest_os_id`)))
+         JOIN `account` ON ((`account`.`id` = `vm_template`.`account_id`)))
+         JOIN `domain` ON ((`domain`.`id` = `account`.`domain_id`)))
+         LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`)))
+         LEFT JOIN `vm_template_details` ON ((`vm_template_details`.`template_id` = `vm_template`.`id`)))
+         LEFT JOIN `vm_template` `source_template` ON ((`source_template`.`id` = `vm_template`.`source_template_id`)))
+         LEFT JOIN `template_store_ref` ON (((`template_store_ref`.`template_id` = `vm_template`.`id`)
+             AND (`template_store_ref`.`store_role` = 'Image')
+             AND (`template_store_ref`.`destroyed` = 0))))
+         LEFT JOIN `vm_template` `parent_template` ON ((`parent_template`.`id` = `vm_template`.`parent_template_id`)))
+         LEFT JOIN `image_store` ON ((ISNULL(`image_store`.`removed`)
+             AND (`template_store_ref`.`store_id` IS NOT NULL)
+             AND (`image_store`.`id` = `template_store_ref`.`store_id`))))
+         LEFT JOIN `template_zone_ref` ON (((`template_zone_ref`.`template_id` = `vm_template`.`id`)
+             AND ISNULL(`template_store_ref`.`store_id`)
+             AND ISNULL(`template_zone_ref`.`removed`))))
+         LEFT JOIN `data_center` ON (((`image_store`.`data_center_id` = `data_center`.`id`)
+             OR (`template_zone_ref`.`zone_id` = `data_center`.`id`))))
+         LEFT JOIN `launch_permission` ON ((`launch_permission`.`template_id` = `vm_template`.`id`)))
+         LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_template`.`id`)
+             AND ((`resource_tags`.`resource_type` = 'Template')
+             OR (`resource_tags`.`resource_type` = 'ISO')))));
+
+-- CLOUDSTACK-10109: Enable dedication of public IPs to SSVM and CPVM
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user_ip_address','forsystemvms', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''true if IP is set to system vms, false if not'' ');
+
+-- ldap binding on domain level
+CREATE TABLE IF NOT EXISTS `cloud`.`domain_details` (
+    `id` bigint unsigned NOT NULL auto_increment,
+    `domain_id` bigint unsigned NOT NULL COMMENT 'account id',
+    `name` varchar(255) NOT NULL,
+    `value` varchar(255) NULL,
+    PRIMARY KEY (`id`),
+    CONSTRAINT `fk_domain_details__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE
+)ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.ldap_configuration','domain_id', 'BIGINT(20) DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.ldap_trust_map','account_id', 'BIGINT(20) DEFAULT 0');
+CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.ldap_trust_map','fk_ldap_trust_map__domain_id');
+CALL `cloud`.`IDEMPOTENT_DROP_INDEX`('uk_ldap_trust_map__domain_id','cloud.ldap_trust_map');
+CALL `cloud`.`IDEMPOTENT_CREATE_UNIQUE_INDEX`('uk_ldap_trust_map__bind_location','cloud.ldap_trust_map', '(domain_id, account_id)');
+
+CREATE TABLE IF NOT EXISTS `cloud`.`netscaler_servicepackages` (
+  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `uuid` varchar(255) UNIQUE,
+  `name` varchar(255) UNIQUE COMMENT 'name of the service package',
+  `description` varchar(255) COMMENT 'description of the service package',
+  PRIMARY KEY  (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `cloud`.`external_netscaler_controlcenter` (
+  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `uuid` varchar(255) UNIQUE,
+  `username` varchar(255) COMMENT 'username of the NCC',
+  `password` varchar(255) COMMENT 'password of NCC',
+  `ncc_ip` varchar(255) COMMENT 'IP of NCC Manager',
+  `num_retries` bigint unsigned NOT NULL default 2 COMMENT 'Number of retries in ncc for command failure',
+  PRIMARY KEY  (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.sslcerts','name', 'varchar(255) NULL default NULL COMMENT ''Name of the Certificate'' ');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','service_package_id', 'varchar(255) NULL default NULL COMMENT ''Netscaler ControlCenter Service Package'' ');
diff --git a/engine/schema/resources/META-INF/db/schema-410to420-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-410to420-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-410to420-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-410to420-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-410to420.sql b/engine/schema/src/main/resources/META-INF/db/schema-410to420.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-410to420.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-410to420.sql
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41100to41110-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-41100to41110-cleanup.sql
new file mode 100644
index 0000000..e6a5b3d
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41100to41110-cleanup.sql
@@ -0,0 +1,22 @@
+-- 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.
+
+--;
+-- Schema cleanup after 4.11.0.0 to 4.11.1.0 upgrade
+--;
+
+DELETE FROM `cloud`.`configuration` WHERE `name`='vmware.ports.per.dvportgroup';
diff --git a/engine/schema/resources/META-INF/db/schema-41100to41110.sql b/engine/schema/src/main/resources/META-INF/db/schema-41100to41110.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-41100to41110.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-41100to41110.sql
diff --git a/engine/schema/resources/META-INF/db/schema-41110to41120-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-41110to41120-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-41110to41120-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-41110to41120-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-41110to41120.sql b/engine/schema/src/main/resources/META-INF/db/schema-41110to41120.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-41110to41120.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-41110to41120.sql
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41120to41200-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200-cleanup.sql
new file mode 100644
index 0000000..82cbfad
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200-cleanup.sql
@@ -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.
+
+--;
+-- Schema upgrade cleanup from 4.11.2.0 to 4.12.0.0
+--;
+
+DROP TABLE IF EXISTS `cloud`.`iam_account_policy_map`;
+DROP TABLE IF EXISTS `cloud`.`iam_group_account_map`;
+DROP TABLE IF EXISTS `cloud`.`iam_group_policy_map`;
+DROP TABLE IF EXISTS `cloud`.`iam_group`;
+DROP TABLE IF EXISTS `cloud`.`iam_policy_permission`;
+DROP TABLE IF EXISTS `cloud`.`iam_policy`;
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql
new file mode 100644
index 0000000..3a99c54
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41120to41200.sql
@@ -0,0 +1,162 @@
+-- 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.
+
+--;
+-- Schema upgrade from 4.11.2.0 to 4.12.0.0
+--;
+
+-- [CLOUDSTACK-10314] Add reason column to ACL rule table
+ALTER TABLE `cloud`.`network_acl_item` ADD COLUMN `reason` VARCHAR(2500) AFTER `display`;
+
+-- [CLOUDSTACK-9846] Make provision to store content and subject for Alerts in separate columns.
+ALTER TABLE `cloud`.`alert` ADD COLUMN `content` VARCHAR(5000);
+
+-- Fix the name of the column used to hold IPv4 range in 'vlan' table.
+ALTER TABLE `vlan` CHANGE `description` `ip4_range` varchar(255);
+
+-- [CLOUDSTACK-10344] bug when moving ACL rules (change order with drag and drop)
+-- We are only adding the permission to the default rules. Any custom rule must be configured by the root admin.
+INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 2, 'moveNetworkAclItem', 'ALLOW', 100) ON DUPLICATE KEY UPDATE rule=rule;
+INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 3, 'moveNetworkAclItem', 'ALLOW', 302) ON DUPLICATE KEY UPDATE rule=rule;
+INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 4, 'moveNetworkAclItem', 'ALLOW', 260) ON DUPLICATE KEY UPDATE rule=rule;
+
+UPDATE `cloud`.`async_job` SET `removed` = now() WHERE `removed` IS NULL;
+
+-- PR#1448 update description of 'execute.in.sequence.network.element.commands' parameter to reflect an unused command that has been removed. The removed class command is 'UserDataCommand'.
+update `cloud`.`configuration` set description = 'If set to true, DhcpEntryCommand, SavePasswordCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.' where name = 'execute.in.sequence.network.element.commands';
+
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Storage', 'DEFAULT', 'StorageManager', 'kvm.storage.offline.migration.wait', '10800', 'Timeout in seconds for offline (non-live) storage migration to complete on KVM', '10800', null, 'Global', 0);
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Storage', 'DEFAULT', 'StorageManager', 'kvm.storage.online.migration.wait', '10800', 'Timeout in seconds for online (live) storage migration to complete on KVM (migrateVirtualMachineWithVolume)', '10800', null, 'Global', 0);
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Storage', 'DEFAULT', 'StorageManager', 'max.number.managed.clustered.file.systems', '200', 'XenServer and VMware only: Maximum number of managed SRs or datastores per compute cluster', '200', null, 'Cluster', 0);
+
+-- add KVM Guest OS mapping for Windows Server 2019
+INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (276, UUID(), 6, 'Windows Server 2019 (64-bit)', now());
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'KVM', 'default', 'Windows Server 2019', 276, now(), 0);
+
+-- changed fingerprint type to TEXT, it avoids db exception when creating the certificate issue #3123
+ALTER TABLE `cloud`.`sslcerts` MODIFY `fingerprint` TEXT;
+
+-- add KVM / qemu io bursting options PR 3133
+alter table `cloud`.`disk_offering` add `bytes_read_rate_max` bigint(20) default null after `bytes_read_rate`;
+alter table `cloud`.`disk_offering` add `bytes_read_rate_max_length` bigint(20) default null after `bytes_read_rate_max`;
+alter table `cloud`.`disk_offering` add `bytes_write_rate_max` bigint(20) default null after `bytes_write_rate`;
+alter table `cloud`.`disk_offering` add `bytes_write_rate_max_length` bigint(20) default null after `bytes_write_rate_max`;
+alter table `cloud`.`disk_offering` add `iops_read_rate_max` bigint(20) default null after `iops_read_rate`;
+alter table `cloud`.`disk_offering` add `iops_read_rate_max_length` bigint(20) default null after `iops_read_rate_max`;
+alter table `cloud`.`disk_offering` add `iops_write_rate_max` bigint(20) default null after `iops_write_rate`;
+alter table `cloud`.`disk_offering` add `iops_write_rate_max_length` bigint(20) default null after `iops_write_rate_max`;
+
+ALTER VIEW `cloud`.`disk_offering_view` AS
+    SELECT
+        `disk_offering`.`id` AS `id`,
+        `disk_offering`.`uuid` AS `uuid`,
+        `disk_offering`.`name` AS `name`,
+        `disk_offering`.`display_text` AS `display_text`,
+        `disk_offering`.`provisioning_type` AS `provisioning_type`,
+        `disk_offering`.`disk_size` AS `disk_size`,
+        `disk_offering`.`min_iops` AS `min_iops`,
+        `disk_offering`.`max_iops` AS `max_iops`,
+        `disk_offering`.`created` AS `created`,
+        `disk_offering`.`tags` AS `tags`,
+        `disk_offering`.`customized` AS `customized`,
+        `disk_offering`.`customized_iops` AS `customized_iops`,
+        `disk_offering`.`removed` AS `removed`,
+        `disk_offering`.`use_local_storage` AS `use_local_storage`,
+        `disk_offering`.`system_use` AS `system_use`,
+        `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
+        `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
+        `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
+        `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
+        `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
+        `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
+        `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
+        `disk_offering`.`iops_read_rate` AS `iops_read_rate`,
+        `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
+        `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
+        `disk_offering`.`iops_write_rate` AS `iops_write_rate`,
+        `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
+        `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
+        `disk_offering`.`cache_mode` AS `cache_mode`,
+        `disk_offering`.`sort_key` AS `sort_key`,
+        `disk_offering`.`type` AS `type`,
+        `disk_offering`.`display_offering` AS `display_offering`,
+        `domain`.`id` AS `domain_id`,
+        `domain`.`uuid` AS `domain_uuid`,
+        `domain`.`name` AS `domain_name`,
+        `domain`.`path` AS `domain_path`
+    FROM
+        (`disk_offering`
+        LEFT JOIN `domain` ON ((`disk_offering`.`domain_id` = `domain`.`id`)))
+    WHERE
+        (`disk_offering`.`state` = 'ACTIVE');
+
+
+ALTER VIEW `cloud`.`service_offering_view` AS
+    SELECT
+        `service_offering`.`id` AS `id`,
+        `disk_offering`.`uuid` AS `uuid`,
+        `disk_offering`.`name` AS `name`,
+        `disk_offering`.`display_text` AS `display_text`,
+        `disk_offering`.`provisioning_type` AS `provisioning_type`,
+        `disk_offering`.`created` AS `created`,
+        `disk_offering`.`tags` AS `tags`,
+        `disk_offering`.`removed` AS `removed`,
+        `disk_offering`.`use_local_storage` AS `use_local_storage`,
+        `disk_offering`.`system_use` AS `system_use`,
+        `disk_offering`.`customized_iops` AS `customized_iops`,
+        `disk_offering`.`min_iops` AS `min_iops`,
+        `disk_offering`.`max_iops` AS `max_iops`,
+        `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
+        `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
+        `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
+        `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
+        `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
+        `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
+        `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
+        `disk_offering`.`iops_read_rate` AS `iops_read_rate`,
+        `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
+        `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
+        `disk_offering`.`iops_write_rate` AS `iops_write_rate`,
+        `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
+        `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
+        `disk_offering`.`cache_mode` AS `cache_mode`,
+        `service_offering`.`cpu` AS `cpu`,
+        `service_offering`.`speed` AS `speed`,
+        `service_offering`.`ram_size` AS `ram_size`,
+        `service_offering`.`nw_rate` AS `nw_rate`,
+        `service_offering`.`mc_rate` AS `mc_rate`,
+        `service_offering`.`ha_enabled` AS `ha_enabled`,
+        `service_offering`.`limit_cpu_use` AS `limit_cpu_use`,
+        `service_offering`.`host_tag` AS `host_tag`,
+        `service_offering`.`default_use` AS `default_use`,
+        `service_offering`.`vm_type` AS `vm_type`,
+        `service_offering`.`sort_key` AS `sort_key`,
+        `service_offering`.`is_volatile` AS `is_volatile`,
+        `service_offering`.`deployment_planner` AS `deployment_planner`,
+        `domain`.`id` AS `domain_id`,
+        `domain`.`uuid` AS `domain_uuid`,
+        `domain`.`name` AS `domain_name`,
+        `domain`.`path` AS `domain_path`
+    FROM
+        ((`service_offering`
+        JOIN `disk_offering` ON ((`service_offering`.`id` = `disk_offering`.`id`)))
+        LEFT JOIN `domain` ON ((`disk_offering`.`domain_id` = `domain`.`id`)))
+    WHERE
+        (`disk_offering`.`state` = 'Active');
+
+-- PR#2578 New column for listManagementServers API call
+ALTER TABLE `mshost` ADD COLUMN `uuid` varchar(40) AFTER `name`;
\ No newline at end of file
diff --git a/engine/schema/resources/META-INF/db/schema-420to421.sql b/engine/schema/src/main/resources/META-INF/db/schema-420to421.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-420to421.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-420to421.sql
diff --git a/engine/schema/resources/META-INF/db/schema-421to430-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-421to430-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-421to430-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-421to430-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-421to430.sql b/engine/schema/src/main/resources/META-INF/db/schema-421to430.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-421to430.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-421to430.sql
diff --git a/engine/schema/resources/META-INF/db/schema-430to440-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-430to440-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-430to440-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-430to440-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-430to440.sql b/engine/schema/src/main/resources/META-INF/db/schema-430to440.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-430to440.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-430to440.sql
diff --git a/engine/schema/resources/META-INF/db/schema-440to441-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-440to441-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-440to441-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-440to441-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-440to441.sql b/engine/schema/src/main/resources/META-INF/db/schema-440to441.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-440to441.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-440to441.sql
diff --git a/engine/schema/resources/META-INF/db/schema-441to442.sql b/engine/schema/src/main/resources/META-INF/db/schema-441to442.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-441to442.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-441to442.sql
diff --git a/engine/schema/resources/META-INF/db/schema-442to450-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-442to450-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-442to450-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-442to450-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-442to450.sql b/engine/schema/src/main/resources/META-INF/db/schema-442to450.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-442to450.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-442to450.sql
diff --git a/engine/schema/resources/META-INF/db/schema-443to444.sql b/engine/schema/src/main/resources/META-INF/db/schema-443to444.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-443to444.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-443to444.sql
diff --git a/engine/schema/resources/META-INF/db/schema-450to451-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-450to451-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-450to451-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-450to451-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-450to451.sql b/engine/schema/src/main/resources/META-INF/db/schema-450to451.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-450to451.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-450to451.sql
diff --git a/engine/schema/resources/META-INF/db/schema-451to452-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-451to452-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-451to452-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-451to452-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-451to452.sql b/engine/schema/src/main/resources/META-INF/db/schema-451to452.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-451to452.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-451to452.sql
diff --git a/engine/schema/resources/META-INF/db/schema-452to453-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-452to453-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-452to453-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-452to453-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-452to453.sql b/engine/schema/src/main/resources/META-INF/db/schema-452to453.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-452to453.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-452to453.sql
diff --git a/engine/schema/resources/META-INF/db/schema-452to460-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-452to460-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-452to460-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-452to460-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-452to460.sql b/engine/schema/src/main/resources/META-INF/db/schema-452to460.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-452to460.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-452to460.sql
diff --git a/engine/schema/resources/META-INF/db/schema-460to461-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-460to461-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-460to461-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-460to461-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-460to461.sql b/engine/schema/src/main/resources/META-INF/db/schema-460to461.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-460to461.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-460to461.sql
diff --git a/engine/schema/resources/META-INF/db/schema-461to470-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-461to470-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-461to470-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-461to470-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-461to470.sql b/engine/schema/src/main/resources/META-INF/db/schema-461to470.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-461to470.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-461to470.sql
diff --git a/engine/schema/resources/META-INF/db/schema-470to471-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-470to471-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-470to471-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-470to471-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-470to471.sql b/engine/schema/src/main/resources/META-INF/db/schema-470to471.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-470to471.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-470to471.sql
diff --git a/engine/schema/resources/META-INF/db/schema-471to480-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-471to480-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-471to480-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-471to480-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-471to480.sql b/engine/schema/src/main/resources/META-INF/db/schema-471to480.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-471to480.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-471to480.sql
diff --git a/engine/schema/resources/META-INF/db/schema-480to481-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-480to481-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-480to481-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-480to481-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-480to481.sql b/engine/schema/src/main/resources/META-INF/db/schema-480to481.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-480to481.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-480to481.sql
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-481to490-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-481to490-cleanup.sql
new file mode 100644
index 0000000..0b426dc
--- /dev/null
+++ b/engine/schema/src/main/resources/META-INF/db/schema-481to490-cleanup.sql
@@ -0,0 +1,271 @@
+-- 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.
+
+--;
+-- Schema cleanup from 4.8.1 to 4.9.0;
+--;
+
+-- Added in CLOUDSTACK-9340: General DB optimization, 4 cases:
+
+----- 1) Incorrect PRIMARY key
+ALTER TABLE `cloud`.`ovs_tunnel_network` 
+DROP PRIMARY KEY,
+ADD PRIMARY KEY (`id`),
+DROP INDEX `id` ,
+ADD UNIQUE INDEX `i_to_from_network_id` (`to` ASC, `from` ASC, `network_id` ASC);
+
+----- 2) Duplicate PRIMARY KEY
+ALTER TABLE `cloud`.`user_vm` DROP INDEX `id_2` ,DROP INDEX `id` ;
+ALTER TABLE `cloud`.`domain_router` DROP INDEX `id_2` ,DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vm_instance` DROP INDEX `id_2` ,DROP INDEX `id` ;
+ALTER TABLE `cloud`.`account_vlan_map` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`account_vnet_map` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`baremetal_rct` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`cluster` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`conditions` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`counter` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`data_center` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`dc_storage_network_ip_range` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`dedicated_resources` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`host_pod_ref` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`iam_group` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`iam_policy` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`iam_policy_permission` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`image_store_details` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`instance_group` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`network_acl_item_cidrs` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`network_offerings` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`nic_secondary_ips` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`nics` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_ha_work` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_host` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_host_transfer` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_networks` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_nwgrp_work` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_vm_ruleset_log` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`op_vpc_distributed_router_sequence_no` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`pod_vlan_map` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`portable_ip_address` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`portable_ip_range` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`region` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`remote_access_vpn` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`snapshot_details` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`snapshots` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`storage_pool` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`storage_pool_details` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`storage_pool_work` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`user_ip_address` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`user_ipv6_address` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`user_statistics` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`version` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vlan` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vm_disk_statistics` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vm_snapshot_details` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vm_work_job` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vpc_gateways` DROP INDEX `id` ;
+ALTER TABLE `cloud`.`vpn_users` DROP INDEX `id` ;
+
+-- Dynamic roles changes
+DROP VIEW IF EXISTS `cloud`.`account_view`;
+CREATE VIEW `cloud`.`account_view` AS
+    select
+        account.id,
+        account.uuid,
+        account.account_name,
+        account.type,
+        account.role_id,
+        account.state,
+        account.removed,
+        account.cleanup_needed,
+        account.network_domain,
+        account.default,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path,
+        data_center.id data_center_id,
+        data_center.uuid data_center_uuid,
+        data_center.name data_center_name,
+        account_netstats_view.bytesReceived,
+        account_netstats_view.bytesSent,
+        vmlimit.max vmLimit,
+        vmcount.count vmTotal,
+        runningvm.vmcount runningVms,
+        stoppedvm.vmcount stoppedVms,
+        iplimit.max ipLimit,
+        ipcount.count ipTotal,
+        free_ip_view.free_ip ipFree,
+        volumelimit.max volumeLimit,
+        volumecount.count volumeTotal,
+        snapshotlimit.max snapshotLimit,
+        snapshotcount.count snapshotTotal,
+        templatelimit.max templateLimit,
+        templatecount.count templateTotal,
+        vpclimit.max vpcLimit,
+        vpccount.count vpcTotal,
+        projectlimit.max projectLimit,
+        projectcount.count projectTotal,
+        networklimit.max networkLimit,
+        networkcount.count networkTotal,
+        cpulimit.max cpuLimit,
+        cpucount.count cpuTotal,
+        memorylimit.max memoryLimit,
+        memorycount.count memoryTotal,
+        primary_storage_limit.max primaryStorageLimit,
+        primary_storage_count.count primaryStorageTotal,
+        secondary_storage_limit.max secondaryStorageLimit,
+        secondary_storage_count.count secondaryStorageTotal,
+        async_job.id job_id,
+        async_job.uuid job_uuid,
+        async_job.job_status job_status,
+        async_job.account_id job_account_id
+    from
+        `cloud`.`free_ip_view`,
+        `cloud`.`account`
+            inner join
+        `cloud`.`domain` ON account.domain_id = domain.id
+            left join
+        `cloud`.`data_center` ON account.default_zone_id = data_center.id
+            left join
+        `cloud`.`account_netstats_view` ON account.id = account_netstats_view.account_id
+            left join
+        `cloud`.`resource_limit` vmlimit ON account.id = vmlimit.account_id
+            and vmlimit.type = 'user_vm'
+            left join
+        `cloud`.`resource_count` vmcount ON account.id = vmcount.account_id
+            and vmcount.type = 'user_vm'
+            left join
+        `cloud`.`account_vmstats_view` runningvm ON account.id = runningvm.account_id
+            and runningvm.state = 'Running'
+            left join
+        `cloud`.`account_vmstats_view` stoppedvm ON account.id = stoppedvm.account_id
+           and stoppedvm.state = 'Stopped'
+            left join
+        `cloud`.`resource_limit` iplimit ON account.id = iplimit.account_id
+            and iplimit.type = 'public_ip'
+            left join
+        `cloud`.`resource_count` ipcount ON account.id = ipcount.account_id
+            and ipcount.type = 'public_ip'
+            left join
+        `cloud`.`resource_limit` volumelimit ON account.id = volumelimit.account_id
+            and volumelimit.type = 'volume'
+            left join
+        `cloud`.`resource_count` volumecount ON account.id = volumecount.account_id
+            and volumecount.type = 'volume'
+            left join
+        `cloud`.`resource_limit` snapshotlimit ON account.id = snapshotlimit.account_id
+            and snapshotlimit.type = 'snapshot'
+            left join
+        `cloud`.`resource_count` snapshotcount ON account.id = snapshotcount.account_id
+            and snapshotcount.type = 'snapshot'
+            left join
+        `cloud`.`resource_limit` templatelimit ON account.id = templatelimit.account_id
+            and templatelimit.type = 'template'
+            left join
+        `cloud`.`resource_count` templatecount ON account.id = templatecount.account_id
+            and templatecount.type = 'template'
+            left join
+        `cloud`.`resource_limit` vpclimit ON account.id = vpclimit.account_id
+            and vpclimit.type = 'vpc'
+            left join
+        `cloud`.`resource_count` vpccount ON account.id = vpccount.account_id
+            and vpccount.type = 'vpc'
+            left join
+        `cloud`.`resource_limit` projectlimit ON account.id = projectlimit.account_id
+            and projectlimit.type = 'project'
+            left join
+        `cloud`.`resource_count` projectcount ON account.id = projectcount.account_id
+            and projectcount.type = 'project'
+            left join
+        `cloud`.`resource_limit` networklimit ON account.id = networklimit.account_id
+            and networklimit.type = 'network'
+            left join
+        `cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
+            and networkcount.type = 'network'
+            left join
+        `cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
+            and cpulimit.type = 'cpu'
+            left join
+        `cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
+            and cpucount.type = 'cpu'
+            left join
+        `cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
+            and memorylimit.type = 'memory'
+            left join
+        `cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
+            and memorycount.type = 'memory'
+            left join
+        `cloud`.`resource_limit` primary_storage_limit ON account.id = primary_storage_limit.account_id
+            and primary_storage_limit.type = 'primary_storage'
+            left join
+        `cloud`.`resource_count` primary_storage_count ON account.id = primary_storage_count.account_id
+            and primary_storage_count.type = 'primary_storage'
+            left join
+        `cloud`.`resource_limit` secondary_storage_limit ON account.id = secondary_storage_limit.account_id
+            and secondary_storage_limit.type = 'secondary_storage'
+            left join
+        `cloud`.`resource_count` secondary_storage_count ON account.id = secondary_storage_count.account_id
+            and secondary_storage_count.type = 'secondary_storage'
+            left join
+        `cloud`.`async_job` ON async_job.instance_id = account.id
+            and async_job.instance_type = 'Account'
+            and async_job.job_status = 0;
+
+DROP VIEW IF EXISTS `cloud`.`user_view`;
+CREATE VIEW `cloud`.`user_view` AS
+    select
+        user.id,
+        user.uuid,
+        user.username,
+        user.password,
+        user.firstname,
+        user.lastname,
+        user.email,
+        user.state,
+        user.api_key,
+        user.secret_key,
+        user.created,
+        user.removed,
+        user.timezone,
+        user.registration_token,
+        user.is_registered,
+        user.incorrect_login_attempts,
+        user.default,
+        account.id account_id,
+        account.uuid account_uuid,
+        account.account_name account_name,
+        account.type account_type,
+        account.role_id account_role_id,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path,
+        async_job.id job_id,
+        async_job.uuid job_uuid,
+        async_job.job_status job_status,
+        async_job.account_id job_account_id
+    from
+        `cloud`.`user`
+            inner join
+        `cloud`.`account` ON user.account_id = account.id
+            inner join
+        `cloud`.`domain` ON account.domain_id = domain.id
+            left join
+        `cloud`.`async_job` ON async_job.instance_id = user.id
+            and async_job.instance_type = 'User'
+            and async_job.job_status = 0;
+
diff --git a/engine/schema/resources/META-INF/db/schema-481to490.sql b/engine/schema/src/main/resources/META-INF/db/schema-481to490.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-481to490.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-481to490.sql
diff --git a/engine/schema/resources/META-INF/db/schema-490to4910-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-490to4910-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-490to4910-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-490to4910-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-490to4910.sql b/engine/schema/src/main/resources/META-INF/db/schema-490to4910.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-490to4910.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-490to4910.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4910to4920-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-4910to4920-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4910to4920-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4910to4920-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4910to4920.sql b/engine/schema/src/main/resources/META-INF/db/schema-4910to4920.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4910to4920.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4910to4920.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4920to4930-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-4920to4930-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4920to4930-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4920to4930-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4920to4930.sql b/engine/schema/src/main/resources/META-INF/db/schema-4920to4930.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4920to4930.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4920to4930.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4930to41000-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-4930to41000-cleanup.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4930to41000-cleanup.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4930to41000-cleanup.sql
diff --git a/engine/schema/resources/META-INF/db/schema-4930to41000.sql b/engine/schema/src/main/resources/META-INF/db/schema-4930to41000.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-4930to41000.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-4930to41000.sql
diff --git a/engine/schema/resources/META-INF/db/schema-level.sql b/engine/schema/src/main/resources/META-INF/db/schema-level.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-level.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-level.sql
diff --git a/engine/schema/resources/META-INF/db/schema-snapshot-217to224.sql b/engine/schema/src/main/resources/META-INF/db/schema-snapshot-217to224.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-snapshot-217to224.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-snapshot-217to224.sql
diff --git a/engine/schema/resources/META-INF/db/schema-snapshot-223to224.sql b/engine/schema/src/main/resources/META-INF/db/schema-snapshot-223to224.sql
similarity index 100%
rename from engine/schema/resources/META-INF/db/schema-snapshot-223to224.sql
rename to engine/schema/src/main/resources/META-INF/db/schema-snapshot-223to224.sql
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
deleted file mode 100644
index 3cd5905..0000000
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++ /dev/null
@@ -1,557 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.datastore.db;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.collections.CollectionUtils;
-
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.StoragePoolTagVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolTagsDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@DB()
-public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long> implements PrimaryDataStoreDao {
-    private final SearchBuilder<StoragePoolVO> AllFieldSearch;
-    private final SearchBuilder<StoragePoolVO> DcPodSearch;
-    private final SearchBuilder<StoragePoolVO> DcPodAnyClusterSearch;
-    private final SearchBuilder<StoragePoolVO> DeleteLvmSearch;
-    private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
-    private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
-
-    @Inject
-    private StoragePoolDetailsDao _detailsDao;
-    @Inject
-    private StoragePoolHostDao _hostDao;
-    @Inject
-    private StoragePoolTagsDao _tagsDao;
-
-    protected final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
-    protected final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
-    private final String ZoneWideTagsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_tags ON storage_pool.id = storage_pool_tags.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and (";
-    private final String ZoneWideTagsSqlSuffix = ") GROUP BY storage_pool_tags.pool_id HAVING COUNT(storage_pool_tags.tag) >= ?";
-
-    // Storage tags are now separate from storage_pool_details, leaving only details on that table
-    protected final String TagsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_tags ON storage_pool.id = storage_pool_tags.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
-    protected final String TagsSqlSuffix = ") GROUP BY storage_pool_tags.pool_id HAVING COUNT(storage_pool_tags.tag) >= ?";
-
-    /**
-     * Used in method findPoolsByDetailsOrTagsInternal
-     */
-    protected enum ValueType {
-        DETAILS, TAGS;
-    }
-
-    public PrimaryDataStoreDaoImpl() {
-        AllFieldSearch = createSearchBuilder();
-        AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("status", AllFieldSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("scope", AllFieldSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ);
-        AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ);
-        AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ);
-        AllFieldSearch.and("storage_provider_name", AllFieldSearch.entity().getStorageProviderName(), Op.EQ);
-        AllFieldSearch.done();
-
-        DcPodSearch = createSearchBuilder();
-        DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL);
-        DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
-        DcPodSearch.cp();
-        DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL);
-        DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
-        DcPodSearch.cp();
-        DcPodSearch.done();
-
-        DcPodAnyClusterSearch = createSearchBuilder();
-        DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL);
-        DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ);
-        DcPodAnyClusterSearch.cp();
-        DcPodAnyClusterSearch.done();
-
-        DeleteLvmSearch = createSearchBuilder();
-        DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN);
-        DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
-        DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ);
-        DeleteLvmSearch.cp();
-        DeleteLvmSearch.done();
-
-        StatusCountSearch = createSearchBuilder(Long.class);
-        StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN);
-        StatusCountSearch.select(null, Func.COUNT, null);
-        StatusCountSearch.done();
-
-        DcLocalStorageSearch = createSearchBuilder();
-        DcLocalStorageSearch.and("datacenterId", DcLocalStorageSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        DcLocalStorageSearch.and("path", DcLocalStorageSearch.entity().getPath(), SearchCriteria.Op.EQ);
-        DcLocalStorageSearch.and("scope", DcLocalStorageSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        DcLocalStorageSearch.done();
-    }
-
-    @Override
-    public List<StoragePoolVO> findPoolByName(String name) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("name", name);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> findPoolsByProvider(String provider) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("storage_provider_name", provider);
-        return listBy(sc);
-    }
-
-    @Override
-    public StoragePoolVO findPoolByUUID(String uuid) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("uuid", uuid);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> findIfDuplicatePoolsExistByUUID(String uuid) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("uuid", uuid);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> listByDataCenterId(long datacenterId) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("datacenterId", datacenterId);
-        return listBy(sc);
-    }
-
-    @Override
-    public void updateCapacityBytes(long id, long capacityBytes) {
-        StoragePoolVO pool = createForUpdate(id);
-        pool.setCapacityBytes(capacityBytes);
-        update(id, pool);
-    }
-
-    @Override
-    public void updateCapacityIops(long id, long capacityIops) {
-        StoragePoolVO pool = createForUpdate(id);
-        pool.setCapacityIops(capacityIops);
-        update(id, pool);
-    }
-
-    @Override
-    public List<StoragePoolVO> listByStorageHost(String hostFqdnOrIp) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("hostAddress", hostFqdnOrIp);
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> listByStatus(StoragePoolStatus status) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("status", status);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> listByStatusInZone(long dcId, StoragePoolStatus status) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("status", status);
-        sc.setParameters("datacenterId", dcId);
-        return listBy(sc);
-    }
-
-    @Override
-    public StoragePoolVO findPoolByHostPath(long datacenterId, Long podId, String host, String path, String uuid) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("hostAddress", host);
-        if (path != null) {
-            sc.setParameters("path", path);
-        }
-        sc.setParameters("datacenterId", datacenterId);
-        sc.setParameters("podId", podId);
-        sc.setParameters("uuid", uuid);
-
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String path) {
-        SearchCriteria<StoragePoolVO> sc = DcLocalStorageSearch.create();
-        sc.setParameters("path", path);
-        sc.setParameters("datacenterId", datacenterId);
-        sc.setParameters("scope", ScopeType.HOST);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> listBy(long datacenterId, Long podId, Long clusterId, ScopeType scope) {
-        if (clusterId != null) {
-            SearchCriteria<StoragePoolVO> sc = DcPodSearch.create();
-            sc.setParameters("datacenterId", datacenterId);
-            sc.setParameters("podId", podId);
-            sc.setParameters("status", Status.Up);
-            sc.setParameters("scope", scope);
-
-            sc.setParameters("cluster", clusterId);
-            return listBy(sc);
-        } else {
-            SearchCriteria<StoragePoolVO> sc = DcPodAnyClusterSearch.create();
-            sc.setParameters("datacenterId", datacenterId);
-            sc.setParameters("podId", podId);
-            sc.setParameters("status", Status.Up);
-            sc.setParameters("scope", scope);
-            return listBy(sc);
-        }
-    }
-
-    @Override
-    public List<StoragePoolVO> listPoolByHostPath(String host, String path) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("hostAddress", host);
-        sc.setParameters("path", path);
-
-        return listBy(sc);
-    }
-
-    public StoragePoolVO listById(Integer id) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("id", id);
-
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    @DB
-    public StoragePoolVO persist(StoragePoolVO pool, Map<String, String> details, List<String> tags) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        pool = super.persist(pool);
-        if (details != null) {
-            for (Map.Entry<String, String> detail : details.entrySet()) {
-                StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue(), true);
-                _detailsDao.persist(vo);
-            }
-        }
-        if (CollectionUtils.isNotEmpty(tags)) {
-            _tagsDao.persist(pool.getId(), tags);
-        }
-        txn.commit();
-        return pool;
-    }
-
-    /**
-     * Internal helper method to retrieve storage pools by given details or storage tags.
-     * @param dcId data center id
-     * @param podId pod id
-     * @param clusterId cluster id
-     * @param scope score
-     * @param sqlValues sql string containing details or storage tags values required to query
-     * @param valuesType enumerate to indicate if values are related to details or storage tags
-     * @param valuesLength values length
-     * @return list of storage pools matching conditions
-     */
-    protected List<StoragePoolVO> findPoolsByDetailsOrTagsInternal(long dcId, long podId, Long clusterId, ScopeType scope, String sqlValues, ValueType valuesType,
-            int valuesLength) {
-        String sqlPrefix = valuesType.equals(ValueType.DETAILS) ? DetailsSqlPrefix : TagsSqlPrefix;
-        String sqlSuffix = valuesType.equals(ValueType.DETAILS) ? DetailsSqlSuffix : TagsSqlSuffix;
-        String sql = getSqlPreparedStatement(sqlPrefix, sqlSuffix, sqlValues, clusterId);
-        return searchStoragePoolsPreparedStatement(sql, dcId, podId, clusterId, scope, valuesLength);
-    }
-
-    /**
-     * Search storage pools in a transaction
-     * @param sql prepared statement sql
-     * @param dcId data center id
-     * @param podId pod id
-     * @param clusterId cluster id
-     * @param scope scope
-     * @param valuesLength values length
-     * @return storage pools matching criteria
-     */
-    @DB
-    protected List<StoragePoolVO> searchStoragePoolsPreparedStatement(String sql, long dcId, Long podId, Long clusterId, ScopeType scope, int valuesLength) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
-        try (PreparedStatement pstmt = txn.prepareStatement(sql);) {
-            if (pstmt != null) {
-                int i = 1;
-                pstmt.setLong(i++, dcId);
-                if (podId != null) {
-                    pstmt.setLong(i++, podId);
-                }
-                pstmt.setString(i++, scope.toString());
-                if (clusterId != null) {
-                    pstmt.setLong(i++, clusterId);
-                }
-                pstmt.setInt(i++, valuesLength);
-                try (ResultSet rs = pstmt.executeQuery();) {
-                    while (rs.next()) {
-                        pools.add(toEntityBean(rs, false));
-                    }
-                } catch (SQLException e) {
-                    throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e);
-                }
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to execute :" + e.getMessage(), e);
-        }
-        return pools;
-    }
-
-    protected String getSqlPreparedStatement(String sqlPrefix, String sqlSuffix, String sqlValues, Long clusterId) {
-        StringBuilder sql = new StringBuilder(sqlPrefix);
-        if (clusterId != null) {
-            sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND (");
-        }
-        sql.append(sqlValues);
-        sql.append(sqlSuffix);
-        return sql.toString();
-    }
-
-    /**
-     * Return SQL string from details, to be placed between SQL Prefix and SQL Suffix when creating storage tags PreparedStatement.
-     * @param details storage pool details
-     * @return SQL string containing storage tag values to be Prefix and Suffix when creating PreparedStatement.
-     * @throws NullPointerException if details is null
-     * @throws IndexOutOfBoundsException if details is not null, but empty
-     */
-    protected String getSqlValuesFromDetails(Map<String, String> details) {
-        StringBuilder sqlValues = new StringBuilder();
-        for (Map.Entry<String, String> detail : details.entrySet()) {
-            sqlValues.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR ");
-        }
-        sqlValues.delete(sqlValues.length() - 4, sqlValues.length());
-        return sqlValues.toString();
-    }
-
-    /**
-     * Return SQL string from storage tags, to be placed between SQL Prefix and SQL Suffix when creating storage tags PreparedStatement.
-     * @param tags storage tags array
-     * @return SQL string containing storage tag values to be placed between Prefix and Suffix when creating PreparedStatement.
-     * @throws NullPointerException if tags is null
-     * @throws IndexOutOfBoundsException if tags is not null, but empty
-     */
-    protected String getSqlValuesFromStorageTags(String[] tags) throws NullPointerException, IndexOutOfBoundsException {
-        StringBuilder sqlValues = new StringBuilder();
-        for (String tag : tags) {
-            sqlValues.append("(storage_pool_tags.tag='").append(tag).append("') OR ");
-        }
-        sqlValues.delete(sqlValues.length() - 4, sqlValues.length());
-        return sqlValues.toString();
-    }
-
-    @DB
-    @Override
-    public List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details, ScopeType scope) {
-        String sqlValues = getSqlValuesFromDetails(details);
-        return findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, scope, sqlValues, ValueType.DETAILS, details.size());
-    }
-
-    @Override
-    public List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
-        List<StoragePoolVO> storagePools = null;
-        if (tags == null || tags.length == 0) {
-            storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER);
-        } else {
-            String sqlValues = getSqlValuesFromStorageTags(tags);
-            storagePools = findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, ScopeType.CLUSTER, sqlValues, ValueType.TAGS, tags.length);
-        }
-
-        return storagePools;
-    }
-
-    @Override
-    public List<StoragePoolVO> findDisabledPoolsByScope(long dcId, Long podId, Long clusterId, ScopeType scope) {
-        List<StoragePoolVO> storagePools = null;
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("status", StoragePoolStatus.Disabled);
-        sc.setParameters("scope", scope);
-
-        if (scope == ScopeType.ZONE) {
-            sc.setParameters("datacenterId", dcId);
-            storagePools = listBy(sc);
-        } else if ((scope == ScopeType.CLUSTER || scope == ScopeType.HOST) && podId != null && clusterId != null) {
-            sc.setParameters("datacenterId", dcId);
-            sc.setParameters("podId", podId);
-            sc.setParameters("clusterId", clusterId);
-            storagePools = listBy(sc);
-        }
-
-        return storagePools;
-    }
-
-    @Override
-    public List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
-        List<StoragePoolVO> storagePools = null;
-        if (tags == null || tags.length == 0) {
-            storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST);
-        } else {
-            String sqlValues = getSqlValuesFromStorageTags(tags);
-            storagePools = findPoolsByDetailsOrTagsInternal(dcId, podId, clusterId, ScopeType.HOST, sqlValues, ValueType.TAGS, tags.length);
-        }
-
-        return storagePools;
-    }
-
-    @Override
-    public List<StoragePoolVO> findLocalStoragePoolsByHostAndTags(long hostId, String[] tags) {
-        SearchBuilder<StoragePoolVO> hostSearch = createSearchBuilder();
-        SearchBuilder<StoragePoolHostVO> hostPoolSearch = _hostDao.createSearchBuilder();
-        SearchBuilder<StoragePoolTagVO> tagPoolSearch = _tagsDao.createSearchBuilder();
-        ;
-
-        // Search for pools on the host
-        hostPoolSearch.and("hostId", hostPoolSearch.entity().getHostId(), Op.EQ);
-        // Set criteria for pools
-        hostSearch.and("scope", hostSearch.entity().getScope(), Op.EQ);
-        hostSearch.and("removed", hostSearch.entity().getRemoved(), Op.NULL);
-        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
-        hostSearch.join("hostJoin", hostPoolSearch, hostSearch.entity().getId(), hostPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER);
-
-        if (!(tags == null || tags.length == 0)) {
-            tagPoolSearch.and("tag", tagPoolSearch.entity().getTag(), Op.EQ);
-            hostSearch.join("tagJoin", tagPoolSearch, hostSearch.entity().getId(), tagPoolSearch.entity().getPoolId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<StoragePoolVO> sc = hostSearch.create();
-        sc.setJoinParameters("hostJoin", "hostId", hostId);
-        sc.setParameters("scope", ScopeType.HOST.toString());
-        sc.setParameters("status", Status.Up.toString());
-
-        if (!(tags == null || tags.length == 0)) {
-            for (String tag : tags) {
-                sc.setJoinParameters("tagJoin", "tag", tag);
-            }
-        }
-        return listBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> findZoneWideStoragePoolsByTags(long dcId, String[] tags) {
-        if (tags == null || tags.length == 0) {
-            QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
-            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-            sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-            sc.and(sc.entity().getScope(), Op.EQ, ScopeType.ZONE);
-            return sc.list();
-        } else {
-            String sqlValues = getSqlValuesFromStorageTags(tags);
-            String sql = getSqlPreparedStatement(ZoneWideTagsSqlPrefix, ZoneWideTagsSqlSuffix, sqlValues, null);
-            return searchStoragePoolsPreparedStatement(sql, dcId, null, null, ScopeType.ZONE, tags.length);
-        }
-    }
-
-    @Override
-    public List<String> searchForStoragePoolTags(long poolId) {
-        return _tagsDao.getStoragePoolTags(poolId);
-    }
-
-    @Override
-    public void updateDetails(long poolId, Map<String, String> details) {
-        if (details != null) {
-            List<StoragePoolDetailVO> detailsVO = new ArrayList<StoragePoolDetailVO>();
-            for (String key : details.keySet()) {
-                detailsVO.add(new StoragePoolDetailVO(poolId, key, details.get(key), true));
-            }
-            _detailsDao.saveDetails(detailsVO);
-            if (details.size() == 0) {
-                _detailsDao.removeDetails(poolId);
-            }
-        }
-    }
-
-    @Override
-    public Map<String, String> getDetails(long poolId) {
-        return _detailsDao.listDetailsKeyPairs(poolId);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        _detailsDao.configure("DetailsDao", params);
-        return true;
-    }
-
-    @Override
-    public long countPoolsByStatus(StoragePoolStatus... statuses) {
-        SearchCriteria<Long> sc = StatusCountSearch.create();
-
-        sc.setParameters("status", (Object[])statuses);
-
-        List<Long> rs = customSearchIncludingRemoved(sc, null);
-        if (rs.size() == 0) {
-            return 0;
-        }
-
-        return rs.get(0);
-    }
-
-    @Override
-    public List<StoragePoolVO> listPoolsByCluster(long clusterId) {
-        SearchCriteria<StoragePoolVO> sc = AllFieldSearch.create();
-        sc.setParameters("clusterId", clusterId);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<StoragePoolVO> findZoneWideStoragePoolsByHypervisor(long dataCenterId, HypervisorType hypervisorType) {
-        QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dataCenterId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getScope(), Op.EQ, ScopeType.ZONE);
-        sc.and(sc.entity().getHypervisor(), Op.EQ, hypervisorType);
-        return sc.list();
-    }
-
-    @Override
-    public void deletePoolTags(long poolId) {
-        _tagsDao.deleteTags(poolId);
-    }
-}
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
deleted file mode 100644
index 20cff56..0000000
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.datastore.db;
-
-import java.util.List;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-
-import com.cloud.storage.DataStoreRole;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.fsm.StateDao;
-
-public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Long>,
-        StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
-
-    List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role);
-
-    List<SnapshotDataStoreVO> listActiveOnCache(long id);
-
-    void deletePrimaryRecordsForStore(long id, DataStoreRole role);
-
-    SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId);
-
-    SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId);
-
-    SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role);
-
-    List<SnapshotDataStoreVO> listDestroyed(long storeId);
-
-    List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId);
-
-    void duplicateCacheRecordsOnRegionStore(long storeId);
-
-    // delete the snapshot entry on primary data store to make sure that next snapshot will be full snapshot
-    void deleteSnapshotRecordsOnPrimary();
-
-    SnapshotDataStoreVO findReadyOnCache(long snapshotId);
-
-    List<SnapshotDataStoreVO> listOnCache(long snapshotId);
-
-    void updateStoreRoleToCache(long storeId);
-
-    SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role);
-
-    SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role);
-
-    void updateVolumeIds(long oldVolId, long newVolId);
-
-    SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role);
-
-    List<SnapshotDataStoreVO> listByState(ObjectInDataStoreStateMachine.State... states);
-}
diff --git a/engine/schema/test/com/cloud/storage/dao/StoragePoolTagsDaoImplTest.java b/engine/schema/src/test/java/com/cloud/storage/dao/StoragePoolTagsDaoImplTest.java
similarity index 100%
rename from engine/schema/test/com/cloud/storage/dao/StoragePoolTagsDaoImplTest.java
rename to engine/schema/src/test/java/com/cloud/storage/dao/StoragePoolTagsDaoImplTest.java
diff --git a/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java b/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
new file mode 100644
index 0000000..982a386
--- /dev/null
+++ b/engine/schema/src/test/java/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
@@ -0,0 +1,173 @@
+// 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.upgrade;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.apache.cloudstack.utils.CloudStackVersion;
+import org.junit.Test;
+
+import com.cloud.upgrade.DatabaseUpgradeChecker.NoopDbUpgrade;
+import com.cloud.upgrade.dao.DbUpgrade;
+import com.cloud.upgrade.dao.Upgrade41000to41100;
+import com.cloud.upgrade.dao.Upgrade41100to41110;
+import com.cloud.upgrade.dao.Upgrade41110to41120;
+import com.cloud.upgrade.dao.Upgrade41120to41130;
+import com.cloud.upgrade.dao.Upgrade41120to41200;
+import com.cloud.upgrade.dao.Upgrade452to453;
+import com.cloud.upgrade.dao.Upgrade453to460;
+import com.cloud.upgrade.dao.Upgrade460to461;
+import com.cloud.upgrade.dao.Upgrade461to470;
+import com.cloud.upgrade.dao.Upgrade470to471;
+import com.cloud.upgrade.dao.Upgrade471to480;
+import com.cloud.upgrade.dao.Upgrade480to481;
+import com.cloud.upgrade.dao.Upgrade490to4910;
+
+public class DatabaseUpgradeCheckerTest {
+
+    @Test
+    public void testCalculateUpgradePath480to481() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.8.0");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+
+        assertNotNull(upgrades);
+        assertTrue(upgrades.length >= 1);
+        assertTrue(upgrades[0] instanceof Upgrade480to481);
+
+    }
+
+    @Test
+    public void testCalculateUpgradePath490to4910() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.9.0");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.1.0");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+
+        assertNotNull(upgrades);
+        assertTrue(upgrades.length >= 1);
+        assertTrue(upgrades[0] instanceof Upgrade490to4910);
+
+        assertTrue(Arrays.equals(new String[] {"4.9.0", currentVersion.toString()}, upgrades[0].getUpgradableVersionRange()));
+        assertEquals(currentVersion.toString(), upgrades[0].getUpgradedVersion());
+
+    }
+
+    @Test
+    public void testCalculateUpgradePath410to412() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.10.0.0");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.12.0.0");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+
+        assertNotNull(upgrades);
+        assertTrue(upgrades.length >= 1);
+        assertTrue(upgrades[0] instanceof Upgrade41000to41100);
+        assertTrue(upgrades[1] instanceof Upgrade41100to41110);
+        assertTrue(upgrades[2] instanceof Upgrade41110to41120);
+        assertTrue(upgrades[3] instanceof Upgrade41120to41130);
+        assertTrue(upgrades[4] instanceof Upgrade41120to41200);
+
+        assertTrue(Arrays.equals(new String[] {"4.11.0.0", "4.11.1.0"}, upgrades[1].getUpgradableVersionRange()));
+        assertEquals(currentVersion.toString(), upgrades[4].getUpgradedVersion());
+
+    }
+
+    @Test
+    public void testFindUpgradePath470to481() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.7.0");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+
+        assertNotNull(upgrades);
+
+        assertTrue(upgrades[0] instanceof Upgrade470to471);
+        assertTrue(upgrades[1] instanceof Upgrade471to480);
+        assertTrue(upgrades[2] instanceof Upgrade480to481);
+
+    }
+
+    @Test
+    public void testFindUpgradePath452to490() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.5.2");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.0");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+
+        assertNotNull(upgrades);
+
+        assertTrue(upgrades[0] instanceof Upgrade452to453);
+        assertTrue(upgrades[1] instanceof Upgrade453to460);
+        assertTrue(upgrades[2] instanceof Upgrade460to461);
+        assertTrue(upgrades[3] instanceof Upgrade461to470);
+        assertTrue(upgrades[4] instanceof Upgrade470to471);
+        assertTrue(upgrades[5] instanceof Upgrade471to480);
+        assertTrue(upgrades[6] instanceof Upgrade480to481);
+
+        assertTrue(Arrays.equals(new String[] {"4.8.1", currentVersion.toString()}, upgrades[upgrades.length - 1].getUpgradableVersionRange()));
+        assertEquals(currentVersion.toString(), upgrades[upgrades.length - 1].getUpgradedVersion());
+    }
+
+    @Test
+    public void testCalculateUpgradePathUnkownDbVersion() {
+
+        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.99.0.0");
+        assertNotNull(dbVersion);
+
+        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.99.1.0");
+        assertNotNull(currentVersion);
+
+        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
+        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
+        assertNotNull(upgrades);
+        assertTrue(upgrades.length == 1);
+        assertTrue(upgrades[0] instanceof NoopDbUpgrade);
+
+     }
+
+}
diff --git a/engine/schema/test/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java b/engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
similarity index 100%
rename from engine/schema/test/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
rename to engine/schema/src/test/java/com/cloud/upgrade/dao/DatabaseAccessObjectTest.java
diff --git a/engine/schema/test/com/cloud/upgrade/dao/DbUpgradeUtilsTest.java b/engine/schema/src/test/java/com/cloud/upgrade/dao/DbUpgradeUtilsTest.java
similarity index 100%
rename from engine/schema/test/com/cloud/upgrade/dao/DbUpgradeUtilsTest.java
rename to engine/schema/src/test/java/com/cloud/upgrade/dao/DbUpgradeUtilsTest.java
diff --git a/engine/schema/test/com/cloud/usage/dao/UsageStorageDaoImplTest.java b/engine/schema/src/test/java/com/cloud/usage/dao/UsageStorageDaoImplTest.java
similarity index 100%
rename from engine/schema/test/com/cloud/usage/dao/UsageStorageDaoImplTest.java
rename to engine/schema/src/test/java/com/cloud/usage/dao/UsageStorageDaoImplTest.java
diff --git a/engine/schema/test/com/cloud/vm/dao/VMInstanceDaoImplTest.java b/engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDaoImplTest.java
similarity index 100%
rename from engine/schema/test/com/cloud/vm/dao/VMInstanceDaoImplTest.java
rename to engine/schema/src/test/java/com/cloud/vm/dao/VMInstanceDaoImplTest.java
diff --git a/engine/schema/test/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImplTest.java b/engine/schema/src/test/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImplTest.java
similarity index 100%
rename from engine/schema/test/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImplTest.java
rename to engine/schema/src/test/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImplTest.java
diff --git a/engine/schema/test/resources/db.properties b/engine/schema/src/test/resources/db.properties
similarity index 100%
rename from engine/schema/test/resources/db.properties
rename to engine/schema/src/test/resources/db.properties
diff --git a/engine/schema/test/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java b/engine/schema/test/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
deleted file mode 100644
index 15bfd8a..0000000
--- a/engine/schema/test/com/cloud/upgrade/DatabaseUpgradeCheckerTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.upgrade;
-
-import com.cloud.upgrade.dao.DbUpgrade;
-import com.cloud.upgrade.dao.Upgrade452to460;
-import com.cloud.upgrade.dao.Upgrade460to461;
-import com.cloud.upgrade.dao.Upgrade461to470;
-import com.cloud.upgrade.dao.Upgrade470to471;
-import com.cloud.upgrade.dao.Upgrade471to480;
-import com.cloud.upgrade.dao.Upgrade480to481;
-import com.cloud.upgrade.dao.Upgrade490to4910;
-import com.cloud.upgrade.dao.Upgrade41100to41110;
-import org.apache.cloudstack.utils.CloudStackVersion;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class DatabaseUpgradeCheckerTest {
-
-    @Test
-    public void testCalculateUpgradePath480to481() {
-
-        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.8.0");
-        assertNotNull(dbVersion);
-
-        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
-        assertNotNull(currentVersion);
-
-        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
-        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
-
-        assertNotNull(upgrades);
-        assertTrue(upgrades.length >= 1);
-        assertTrue(upgrades[0] instanceof Upgrade480to481);
-
-    }
-
-    @Test
-    public void testCalculateUpgradePath490to4910() {
-
-        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.9.0");
-        assertNotNull(dbVersion);
-
-        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.1.0");
-        assertNotNull(currentVersion);
-
-        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
-        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
-
-        assertNotNull(upgrades);
-        assertTrue(upgrades.length >= 1);
-        assertTrue(upgrades[0] instanceof Upgrade490to4910);
-
-        assertTrue(Arrays.equals(new String[] { "4.9.0", currentVersion.toString()}, upgrades[0].getUpgradableVersionRange()));
-        assertEquals(currentVersion.toString(), upgrades[0].getUpgradedVersion());
-
-    }
-
-    @Test
-    public void testCalculateUpgradePath4110to4111() {
-
-        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.11.0.0");
-        assertNotNull(dbVersion);
-
-        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.11.1.0");
-        assertNotNull(currentVersion);
-
-        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
-        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
-
-        assertNotNull(upgrades);
-        assertTrue(upgrades.length >= 1);
-        assertTrue(upgrades[0] instanceof Upgrade41100to41110);
-
-        assertTrue(Arrays.equals(new String[] { "4.11.0.0", currentVersion.toString()},
-                upgrades[0].getUpgradableVersionRange()));
-        assertEquals(currentVersion.toString(), upgrades[0].getUpgradedVersion());
-
-    }
-
-    @Test
-    public void testFindUpgradePath470to481() {
-
-        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.7.0");
-        assertNotNull(dbVersion);
-
-        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.8.1");
-        assertNotNull(currentVersion);
-
-        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
-        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
-
-        assertNotNull(upgrades);
-
-        assertTrue(upgrades[0] instanceof Upgrade470to471);
-        assertTrue(upgrades[1] instanceof Upgrade471to480);
-        assertTrue(upgrades[2] instanceof Upgrade480to481);
-
-    }
-
-    @Test
-    public void testFindUpgradePath452to490() {
-
-        final CloudStackVersion dbVersion = CloudStackVersion.parse("4.5.2");
-        assertNotNull(dbVersion);
-
-        final CloudStackVersion currentVersion = CloudStackVersion.parse("4.9.0");
-        assertNotNull(currentVersion);
-
-        final DatabaseUpgradeChecker checker = new DatabaseUpgradeChecker();
-        final DbUpgrade[] upgrades = checker.calculateUpgradePath(dbVersion, currentVersion);
-
-        assertNotNull(upgrades);
-
-        assertTrue(upgrades[0] instanceof Upgrade452to460);
-        assertTrue(upgrades[1] instanceof Upgrade460to461);
-        assertTrue(upgrades[2] instanceof Upgrade461to470);
-        assertTrue(upgrades[3] instanceof Upgrade470to471);
-        assertTrue(upgrades[4] instanceof Upgrade471to480);
-        assertTrue(upgrades[5] instanceof Upgrade480to481);
-
-        assertTrue(Arrays.equals(new String[] { "4.8.1", currentVersion.toString()}, upgrades[6].getUpgradableVersionRange()));
-        assertEquals(currentVersion.toString(), upgrades[6].getUpgradedVersion());
-
-    }
-}
diff --git a/engine/service/pom.xml b/engine/service/pom.xml
index 84d504c..ba91ba0 100644
--- a/engine/service/pom.xml
+++ b/engine/service/pom.xml
@@ -1,95 +1,93 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
 -->
-<project
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>cloud-engine-service</artifactId>
-  <packaging>war</packaging>
-  <name>Apache CloudStack Cloud Engine Service</name>
-  <url>http://www.cloudstack.org</url>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-orchestration</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-network</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-web</artifactId>
-    </dependency>
-  </dependencies>
-  <build>
-    <finalName>engine</finalName>
-    <plugins>
-      <plugin>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-maven-plugin</artifactId>
-        <version>${cs.jetty.version}</version>
-        <configuration>
-          <scanIntervalSeconds>10</scanIntervalSeconds>
-          <webApp>
-            <contextPath>/engine</contextPath>
-          </webApp>
-          <connectors>
-            <connector
-              implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
-              <port>1736</port>
-              <maxIdleTime>60000</maxIdleTime>
-            </connector>
-          </connectors>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <artifactId>cloud-engine-service</artifactId>
+    <packaging>war</packaging>
+    <name>Apache CloudStack Cloud Engine Service</name>
+    <url>http://www.cloudstack.org</url>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-orchestration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-network</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>engine</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${cs.jetty.version}</version>
+                <configuration>
+                    <scanIntervalSeconds>10</scanIntervalSeconds>
+                    <webApp>
+                        <contextPath>/engine</contextPath>
+                    </webApp>
+                    <connectors>
+                        <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
+                            <port>1736</port>
+                            <maxIdleTime>60000</maxIdleTime>
+                        </connector>
+                    </connectors>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml
index 3b20d0a..b50d5cd 100644
--- a/engine/storage/cache/pom.xml
+++ b/engine/storage/cache/pom.xml
@@ -1,33 +1,42 @@
-<!-- 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. -->
+<!--
+  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-engine-storage-cache</artifactId>
-  <name>Apache CloudStack Engine Storage Cache Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-storage-cache</artifactId>
+    <name>Apache CloudStack Engine Storage Cache Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
similarity index 100%
rename from engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
rename to engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
similarity index 100%
rename from engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
rename to engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
similarity index 100%
rename from engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
rename to engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java
similarity index 100%
rename from engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java
rename to engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java
diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java
similarity index 100%
rename from engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java
rename to engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java
diff --git a/engine/storage/cache/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml b/engine/storage/cache/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml
similarity index 100%
rename from engine/storage/cache/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml
rename to engine/storage/cache/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-cache-core-context.xml
diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml
index a965484..4fa5bea 100644
--- a/engine/storage/configdrive/pom.xml
+++ b/engine/storage/configdrive/pom.xml
@@ -1,43 +1,42 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-engine-storage-configdrive</artifactId>
-  <name>Apache CloudStack Framework - Storage Config Drive Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.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-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
+<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-engine-storage-configdrive</artifactId>
+    <name>Apache CloudStack Framework - Storage Config Drive Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</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-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java b/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
similarity index 100%
rename from engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
rename to engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
diff --git a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java b/engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
similarity index 100%
rename from engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
rename to engine/storage/configdrive/src/main/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
diff --git a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java b/engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
similarity index 100%
rename from engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
rename to engine/storage/configdrive/src/test/java/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml
index f62d14d..ef70394 100644
--- a/engine/storage/datamotion/pom.xml
+++ b/engine/storage/datamotion/pom.xml
@@ -1,41 +1,49 @@
-<!-- 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. -->
+<!--
+  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-engine-storage-datamotion</artifactId>
-  <name>Apache CloudStack Engine Storage Data Motion Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-      <scope>runtime</scope>
-    </dependency>
-  </dependencies>
+    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-engine-storage-datamotion</artifactId>
+    <name>Apache CloudStack Engine Storage Data Motion Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml b/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml
deleted file mode 100644
index 1cefc51..0000000
--- a/engine/storage/datamotion/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context.xsd"
-                      >
-    <bean id="ancientDataMotionStrategy"
-        class="org.apache.cloudstack.storage.motion.AncientDataMotionStrategy" />
-    <bean id="xenserverStorageMotionStrategy"
-        class="org.apache.cloudstack.storage.motion.XenServerStorageMotionStrategy" />
-    <bean id="hypervStorageMotionStrategy"
-        class="org.apache.cloudstack.storage.motion.HypervStorageMotionStrategy" />
-    <bean id="storageSystemDataMotionStrategy"
-        class="org.apache.cloudstack.storage.motion.StorageSystemDataMotionStrategy" />
-</beans>
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
new file mode 100644
index 0000000..7b52645
--- /dev/null
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -0,0 +1,582 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.configuration.Config;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachineManager;
+
+@Component
+public class AncientDataMotionStrategy implements DataMotionStrategy {
+    private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class);
+    @Inject
+    EndPointSelector selector;
+    @Inject
+    ConfigurationDao configDao;
+    @Inject
+    VolumeDao volDao;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    StorageCacheManager cacheMgr;
+
+    @Override
+    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
+        return StrategyPriority.DEFAULT;
+    }
+
+    @Override
+    public StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    protected boolean needCacheStorage(DataObject srcData, DataObject destData) {
+        DataTO srcTO = srcData.getTO();
+        DataStoreTO srcStoreTO = srcTO.getDataStore();
+
+        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) {
+            return false;
+        }
+        DataTO destTO = destData.getTO();
+        DataStoreTO destStoreTO = destTO.getDataStore();
+
+        if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) {
+            return false;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("needCacheStorage true, dest at " + destTO.getPath() + " dest role " + destStoreTO.getRole().toString() + srcTO.getPath() + " src role " +
+                srcStoreTO.getRole().toString());
+        }
+        return true;
+    }
+
+    private Scope getZoneScope(Scope destScope) {
+        ZoneScope zoneScope = null;
+        if (destScope instanceof ClusterScope) {
+            ClusterScope clusterScope = (ClusterScope)destScope;
+            zoneScope = new ZoneScope(clusterScope.getZoneId());
+        } else if (destScope instanceof HostScope) {
+            HostScope hostScope = (HostScope)destScope;
+            zoneScope = new ZoneScope(hostScope.getZoneId());
+        } else {
+            zoneScope = (ZoneScope)destScope;
+        }
+        return zoneScope;
+    }
+
+    private Scope pickCacheScopeForCopy(DataObject srcData, DataObject destData) {
+        Scope srcScope = srcData.getDataStore().getScope();
+        Scope destScope = destData.getDataStore().getScope();
+
+        Scope selectedScope = null;
+        if (srcScope.getScopeId() != null) {
+            selectedScope = getZoneScope(srcScope);
+        } else if (destScope.getScopeId() != null) {
+            selectedScope = getZoneScope(destScope);
+        } else {
+            s_logger.warn("Cannot find a zone-wide scope for movement that needs a cache storage");
+        }
+        return selectedScope;
+    }
+
+    protected Answer copyObject(DataObject srcData, DataObject destData, Host destHost) {
+        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+        Answer answer = null;
+        DataObject cacheData = null;
+        DataObject srcForCopy = srcData;
+        try {
+            if (needCacheStorage(srcData, destData)) {
+                Scope destScope = pickCacheScopeForCopy(srcData, destData);
+                srcForCopy = cacheData = cacheMgr.createCacheObject(srcData, destScope);
+            }
+
+            CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), primaryStorageDownloadWait,
+                    VirtualMachineManager.ExecuteInSequence.value());
+            EndPoint ep = destHost != null ? RemoteHostEndPoint.getHypervisorHostEndPoint(destHost) : selector.select(srcForCopy, destData);
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+
+            if (cacheData != null) {
+                final Long cacheId = cacheData.getId();
+                final String cacheType = cacheData.getType().toString();
+                final String cacheUuid = cacheData.getUuid().toString();
+
+                if (srcData.getType() == DataObjectType.VOLUME &&
+                    (destData.getType() == DataObjectType.VOLUME ||
+                     destData.getType() == DataObjectType.TEMPLATE)) {
+                    // volume transfer from primary to secondary. Volume transfer between primary pools are already handled by copyVolumeBetweenPools
+                    // Delete cache in order to certainly transfer a latest image.
+                    s_logger.debug("Delete " + cacheType + " cache(id: " + cacheId +
+                                   ", uuid: " + cacheUuid + ")");
+                    cacheMgr.deleteCacheObject(srcForCopy);
+                } else {
+                    // for template, we want to leave it on cache for performance reason
+                    if ((answer == null || !answer.getResult()) && srcForCopy.getRefCount() < 2) {
+                        // cache object created by this copy, not already there
+                        s_logger.warn("Copy may not be handled correctly by agent(id: " + (ep != null ? ep.getId() : "\"unspecified\"") + ")." +
+                                      " Delete " + cacheType + " cache(id: " + cacheId +
+                                      ", uuid: " + cacheUuid + ")");
+                        cacheMgr.deleteCacheObject(srcForCopy);
+                    } else {
+                        s_logger.debug("Decrease reference count of " + cacheType +
+                                       " cache(id: " + cacheId + ", uuid: " + cacheUuid + ")");
+                        cacheMgr.releaseCacheObject(srcForCopy);
+                    }
+                }
+            }
+            return answer;
+        } catch (Exception e) {
+            s_logger.debug("copy object failed: ", e);
+            if (cacheData != null) {
+                cacheMgr.deleteCacheObject(cacheData);
+            }
+            throw new CloudRuntimeException(e.toString());
+        }
+    }
+
+    /**
+     * Adds {@code 'vmware.create.full.clone'} value for a given primary storage, whose HV is VMware, on datastore's {@code fullCloneFlag} field
+     * @param dataTO Dest data store TO
+     * @return dataTO including fullCloneFlag, if provided
+     */
+    protected DataTO addFullCloneFlagOnVMwareDest(DataTO dataTO) {
+        if (dataTO != null && dataTO.getHypervisorType().equals(Hypervisor.HypervisorType.VMware)){
+            DataStoreTO dataStoreTO = dataTO.getDataStore();
+            if (dataStoreTO != null && dataStoreTO instanceof PrimaryDataStoreTO){
+                PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) dataStoreTO;
+                Boolean value = CapacityManager.VmwareCreateCloneFull.valueIn(primaryDataStoreTO.getId());
+                primaryDataStoreTO.setFullCloneFlag(value);
+            }
+        }
+        return dataTO;
+    }
+
+    protected Answer copyObject(DataObject srcData, DataObject destData) {
+        return copyObject(srcData, destData, null);
+    }
+
+    protected DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) {
+        DataObject leafData = null;
+        DataStore store = cacheMgr.getCacheStorage(snapshot, scope);
+        while (snapshot != null) {
+            DataObject cacheData = cacheMgr.createCacheObject(snapshot, store);
+            if (leafData == null) {
+                leafData = cacheData;
+            }
+            snapshot = snapshot.getParent();
+        }
+        return leafData;
+    }
+
+
+    protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) {
+        while (snapshot != null) {
+            cacheMgr.deleteCacheObject(snapshot);
+            snapshot = snapshot.getParent();
+        }
+    }
+
+    protected void releaseSnapshotCacheChain(SnapshotInfo snapshot) {
+        while (snapshot != null) {
+            cacheMgr.releaseCacheObject(snapshot);
+            snapshot = snapshot.getParent();
+        }
+    }
+
+    protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) {
+        SnapshotInfo snapshot = (SnapshotInfo)snapObj;
+        StoragePool pool = (StoragePool)volObj.getDataStore();
+
+        String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool;
+        DataStore store = snapObj.getDataStore();
+        DataStoreTO storTO = store.getTO();
+        DataObject srcData = snapObj;
+        try {
+            if (!(storTO instanceof NfsTO)) {
+                // cache snapshot to zone-wide staging store for the volume to be created
+                srcData = cacheSnapshotChain(snapshot, new ZoneScope(pool.getDataCenterId()));
+            }
+
+            String value = configDao.getValue(Config.CreateVolumeFromSnapshotWait.toString());
+            int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreateVolumeFromSnapshotWait.getDefaultValue()));
+
+            EndPoint ep = null;
+            if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+                ep = selector.select(volObj);
+            } else {
+                ep = selector.select(srcData, volObj);
+            }
+
+            CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(volObj.getTO()), _createVolumeFromSnapshotWait, VirtualMachineManager.ExecuteInSequence.value());
+            Answer answer = null;
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+
+            return answer;
+        } catch (Exception e) {
+            s_logger.error(basicErrMsg, e);
+            throw new CloudRuntimeException(basicErrMsg);
+        } finally {
+            if (!(storTO instanceof NfsTO)) {
+                // still keep snapshot on cache which may be migrated from previous secondary storage
+                releaseSnapshotCacheChain((SnapshotInfo)srcData);
+            }
+        }
+    }
+
+    protected Answer cloneVolume(DataObject template, DataObject volume) {
+        CopyCommand cmd = new CopyCommand(template.getTO(), addFullCloneFlagOnVMwareDest(volume.getTO()), 0, VirtualMachineManager.ExecuteInSequence.value());
+        try {
+            EndPoint ep = selector.select(volume.getDataStore());
+            Answer answer = null;
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+            return answer;
+        } catch (Exception e) {
+            s_logger.debug("Failed to send to storage pool", e);
+            throw new CloudRuntimeException("Failed to send to storage pool", e);
+        }
+    }
+
+    protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
+        String value = configDao.getValue(Config.CopyVolumeWait.key());
+        int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+
+        Scope destScope = getZoneScope(destData.getDataStore().getScope());
+        DataStore cacheStore = cacheMgr.getCacheStorage(destScope);
+        if (cacheStore == null) {
+            // need to find a nfs or cifs image store, assuming that can't copy volume
+            // directly to s3
+            ImageStoreEntity imageStore = (ImageStoreEntity)dataStoreMgr.getImageStore(destScope.getScopeId());
+            if (!imageStore.getProtocol().equalsIgnoreCase("nfs") && !imageStore.getProtocol().equalsIgnoreCase("cifs")) {
+                s_logger.debug("can't find a nfs (or cifs) image store to satisfy the need for a staging store");
+                return null;
+            }
+
+            DataObject objOnImageStore = imageStore.create(srcData);
+            objOnImageStore.processEvent(Event.CreateOnlyRequested);
+
+            Answer answer = copyObject(srcData, objOnImageStore);
+            if (answer == null || !answer.getResult()) {
+                if (answer != null) {
+                    s_logger.debug("copy to image store failed: " + answer.getDetails());
+                }
+                objOnImageStore.processEvent(Event.OperationFailed);
+                imageStore.delete(objOnImageStore);
+                return answer;
+            }
+
+            objOnImageStore.processEvent(Event.OperationSuccessed, answer);
+
+            objOnImageStore.processEvent(Event.CopyingRequested);
+
+            CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
+            EndPoint ep = selector.select(objOnImageStore, destData);
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+
+            if (answer == null || !answer.getResult()) {
+                if (answer != null) {
+                    s_logger.debug("copy to primary store failed: " + answer.getDetails());
+                }
+                objOnImageStore.processEvent(Event.OperationFailed);
+                imageStore.delete(objOnImageStore);
+                return answer;
+            }
+
+            objOnImageStore.processEvent(Event.OperationSuccessed);
+            imageStore.delete(objOnImageStore);
+            return answer;
+        } else {
+            DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope);
+            CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
+            EndPoint ep = selector.select(cacheData, destData);
+            Answer answer = null;
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+            // delete volume on cache store
+            if (cacheData != null) {
+                cacheMgr.deleteCacheObject(cacheData);
+            }
+            return answer;
+        }
+
+    }
+
+    protected Answer migrateVolumeToPool(DataObject srcData, DataObject destData) {
+        String value = configDao.getValue(Config.MigrateWait.key());
+        int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue()));
+
+        VolumeInfo volume = (VolumeInfo)srcData;
+        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
+        MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), volume.getVolumeType(), waitInterval);
+        EndPoint ep = selector.select(srcData, StorageAction.MIGRATEVOLUME);
+        Answer answer = null;
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            answer = new Answer(command, false, errMsg);
+        } else {
+            answer = ep.sendMessage(command);
+        }
+
+        if (answer == null || !answer.getResult()) {
+            throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool);
+        } else {
+            // Update the volume details after migration.
+            VolumeVO volumeVo = volDao.findById(volume.getId());
+            Long oldPoolId = volume.getPoolId();
+            volumeVo.setPath(((MigrateVolumeAnswer)answer).getVolumePath());
+            String chainInfo = ((MigrateVolumeAnswer)answer).getVolumeChainInfo();
+            if (chainInfo != null) {
+                volumeVo.setChainInfo(chainInfo);
+            }
+            volumeVo.setPodId(destPool.getPodId());
+            volumeVo.setPoolId(destPool.getId());
+            volumeVo.setLastPoolId(oldPoolId);
+            // For SMB, pool credentials are also stored in the uri query string.  We trim the query string
+            // part  here to make sure the credentials do not get stored in the db unencrypted.
+            String folder = destPool.getPath();
+            if (destPool.getPoolType() == StoragePoolType.SMB && folder != null && folder.contains("?")) {
+                folder = folder.substring(0, folder.indexOf("?"));
+            }
+            volumeVo.setFolder(folder);
+            volDao.update(volume.getId(), volumeVo);
+        }
+
+        return answer;
+    }
+
+    // Note: destHost is currently only used if the copyObject method is invoked
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        Answer answer = null;
+        String errMsg = null;
+        try {
+            s_logger.debug("copyAsync inspecting src type " + srcData.getType().toString() + " copyAsync inspecting dest type " + destData.getType().toString());
+            if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) {
+                answer = copyVolumeFromSnapshot(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) {
+                answer = createTemplateFromSnapshot(srcData, destData);
+            } else if (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
+                answer = cloneVolume(srcData, destData);
+            } else if (destData.getType() == DataObjectType.VOLUME && srcData.getType() == DataObjectType.VOLUME &&
+                srcData.getDataStore().getRole() == DataStoreRole.Primary && destData.getDataStore().getRole() == DataStoreRole.Primary) {
+                if (srcData.getId() == destData.getId()) {
+                    // The volume has to be migrated across storage pools.
+                    answer = migrateVolumeToPool(srcData, destData);
+                } else {
+                    answer = copyVolumeBetweenPools(srcData, destData);
+                }
+            } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) {
+                answer = copySnapshot(srcData, destData);
+            } else {
+                answer = copyObject(srcData, destData, destHost);
+            }
+
+            if (answer != null && !answer.getResult()) {
+                errMsg = answer.getDetails();
+            }
+        } catch (Exception e) {
+            s_logger.debug("copy failed", e);
+            errMsg = e.toString();
+        }
+        CopyCommandResult result = new CopyCommandResult(null, answer);
+        result.setResult(errMsg);
+        callback.complete(result);
+    }
+
+    @DB
+    protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) {
+
+        String value = configDao.getValue(Config.CreatePrivateTemplateFromSnapshotWait.toString());
+        int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreatePrivateTemplateFromSnapshotWait.getDefaultValue()));
+
+        boolean needCache = false;
+        if (needCacheStorage(srcData, destData)) {
+            needCache = true;
+            SnapshotInfo snapshot = (SnapshotInfo) srcData;
+            srcData = cacheSnapshotChain(snapshot, snapshot.getDataStore().getScope());
+        }
+
+        EndPoint ep = null;
+        if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
+            ep = selector.select(destData);
+        } else {
+            ep = selector.select(srcData, destData);
+        }
+
+        CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _createprivatetemplatefromsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
+        Answer answer = null;
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            answer = new Answer(cmd, false, errMsg);
+        } else {
+            answer = ep.sendMessage(cmd);
+        }
+
+        // clean up snapshot copied to staging
+        if (needCache && srcData != null) {
+            cacheMgr.releaseCacheObject(srcData);  // reduce ref count, but keep it there on cache which is converted from previous secondary storage
+        }
+        return answer;
+    }
+
+    protected Answer copySnapshot(DataObject srcData, DataObject destData) {
+        String value = configDao.getValue(Config.BackupSnapshotWait.toString());
+        int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
+
+        DataObject cacheData = null;
+        SnapshotInfo snapshotInfo = (SnapshotInfo)srcData;
+        Boolean snapshotFullBackup = snapshotInfo.getFullBackup();
+        Boolean fullSnapshot = true;
+        if (snapshotFullBackup != null) {
+            fullSnapshot = snapshotFullBackup;
+        }
+        Map<String, String> options = new HashMap<String, String>();
+        options.put("fullSnapshot", fullSnapshot.toString());
+        Answer answer = null;
+        try {
+            if (needCacheStorage(srcData, destData)) {
+                Scope selectedScope = pickCacheScopeForCopy(srcData, destData);
+                cacheData = cacheMgr.getCacheObject(srcData, selectedScope);
+
+                CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
+                cmd.setCacheTO(cacheData.getTO());
+                cmd.setOptions(options);
+                EndPoint ep = selector.select(srcData, destData);
+                if (ep == null) {
+                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                    s_logger.error(errMsg);
+                    answer = new Answer(cmd, false, errMsg);
+                } else {
+                    answer = ep.sendMessage(cmd);
+                }
+            } else {
+                addFullCloneFlagOnVMwareDest(destData.getTO());
+                CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
+                cmd.setOptions(options);
+                EndPoint ep = selector.select(srcData, destData, StorageAction.BACKUPSNAPSHOT);
+                if (ep == null) {
+                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                    s_logger.error(errMsg);
+                    answer = new Answer(cmd, false, errMsg);
+                } else {
+                    answer = ep.sendMessage(cmd);
+                }
+
+            }
+            // clean up cache entry
+            if (cacheData != null) {
+                cacheMgr.deleteCacheObject(cacheData);
+            }
+            return answer;
+        } catch (Exception e) {
+            s_logger.debug("copy snasphot failed: " + e.toString());
+            if (cacheData != null) {
+                cacheMgr.deleteCacheObject(cacheData);
+            }
+            throw new CloudRuntimeException(e.toString());
+        }
+
+    }
+
+    @Override
+    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        CopyCommandResult result = new CopyCommandResult(null, null);
+        result.setResult("Unsupported operation requested for copying data.");
+        callback.complete(result);
+    }
+}
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
new file mode 100644
index 0000000..c2724e6
--- /dev/null
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.Host;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+
+@Component
+public class DataMotionServiceImpl implements DataMotionService {
+    private static final Logger LOGGER = Logger.getLogger(DataMotionServiceImpl.class);
+
+    @Inject
+    StorageStrategyFactory storageStrategyFactory;
+    @Inject
+    VolumeDao volDao;
+
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (srcData.getDataStore() == null || destData.getDataStore() == null) {
+            throw new CloudRuntimeException("can't find data store");
+        }
+
+        if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) {
+            srcData.getDataStore().getDriver().copyAsync(srcData, destData, callback);
+            return;
+        } else if (destData.getDataStore().getDriver().canCopy(srcData, destData)) {
+            destData.getDataStore().getDriver().copyAsync(srcData, destData, callback);
+            return;
+        }
+
+        DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(srcData, destData);
+        if (strategy == null) {
+            // OfflineVmware volume migration
+            // Cleanup volumes from target and reset the state of volume at source
+            cleanUpVolumesForFailedMigrations(srcData, destData);
+            throw new CloudRuntimeException("Can't find strategy to move data. " + "Source: " + srcData.getType().name() + " '" + srcData.getUuid() + ", Destination: " +
+                    destData.getType().name() + " '" + destData.getUuid() + "'");
+        }
+
+        strategy.copyAsync(srcData, destData, destHost, callback);
+    }
+
+    /**
+     * Offline Vmware volume migration
+     * Cleanup volumes after failed migrations and reset state of source volume
+     *
+     * @param srcData
+     * @param destData
+     */
+    private void cleanUpVolumesForFailedMigrations(DataObject srcData, DataObject destData) {
+        VolumeVO destinationVO = volDao.findById(destData.getId());
+        VolumeVO sourceVO = volDao.findById(srcData.getId());
+        sourceVO.setState(Volume.State.Ready);
+        volDao.update(sourceVO.getId(), sourceVO);
+        destinationVO.setState(Volume.State.Expunged);
+        destinationVO.setRemoved(new Date());
+        volDao.update(destinationVO.getId(), destinationVO);
+    }
+
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        copyAsync(srcData, destData, null, callback);
+    }
+
+    @Override
+    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+
+        DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(volumeMap, srcHost, destHost);
+        if (strategy == null) {
+            List<String> volumeIds = new LinkedList<String>();
+            for (final VolumeInfo volumeInfo : volumeMap.keySet()) {
+                volumeIds.add(volumeInfo.getUuid());
+            }
+
+            throw new CloudRuntimeException("Can't find strategy to move data. " + "Source Host: " + srcHost.getName() + ", Destination Host: " + destHost.getName() +
+                    ", Volume UUIDs: " + StringUtils.join(volumeIds, ","));
+        }
+
+        strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback);
+    }
+}
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
new file mode 100644
index 0000000..2cf236d
--- /dev/null
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+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.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.datastore.DataStoreManagerImpl;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineManager;
+
+/**
+ * Extends {@link StorageSystemDataMotionStrategy}, allowing KVM hosts to migrate VMs with the ROOT volume on a non managed local storage pool.
+ * As {@link StorageSystemDataMotionStrategy} is considering KVM, this implementation also migrates only from/to KVM hosts.
+ */
+public class KvmNonManagedStorageDataMotionStrategy extends StorageSystemDataMotionStrategy {
+
+    @Inject
+    private TemplateDataFactory templateDataFactory;
+    @Inject
+    private VMTemplatePoolDao vmTemplatePoolDao;
+    @Inject
+    private DataStoreManagerImpl dataStoreManagerImpl;
+    @Inject
+    private VirtualMachineManager virtualMachineManager;
+
+    private static final Logger LOGGER = Logger.getLogger(KvmNonManagedStorageDataMotionStrategy.class);
+
+    /**
+     * Uses the canHandle from the Super class {@link StorageSystemDataMotionStrategy}. If the storage pool is of file and the internalCanHandle from {@link StorageSystemDataMotionStrategy} CANT_HANDLE, returns the StrategyPriority.HYPERVISOR strategy priority. otherwise returns CANT_HANDLE.
+     * Note that the super implementation (override) is called by {@link #canHandle(Map, Host, Host)} which ensures that {@link #internalCanHandle(Map)} will be executed only if the source host is KVM.
+     */
+    @Override
+    protected StrategyPriority internalCanHandle(Map<VolumeInfo, DataStore> volumeMap) {
+        if (super.internalCanHandle(volumeMap) == StrategyPriority.CANT_HANDLE) {
+            Set<VolumeInfo> volumeInfoSet = volumeMap.keySet();
+
+            for (VolumeInfo volumeInfo : volumeInfoSet) {
+                StoragePoolVO storagePoolVO = _storagePoolDao.findById(volumeInfo.getPoolId());
+                if (storagePoolVO.getPoolType() != StoragePoolType.Filesystem && storagePoolVO.getPoolType() != StoragePoolType.NetworkFilesystem) {
+                    return StrategyPriority.CANT_HANDLE;
+                }
+            }
+            return StrategyPriority.HYPERVISOR;
+        }
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    /**
+     * Configures a {@link MigrateDiskInfo} object configured for migrating a File System volume and calls rootImageProvisioning.
+     */
+    @Override
+    protected MigrateCommand.MigrateDiskInfo configureMigrateDiskInfo(VolumeInfo srcVolumeInfo, String destPath) {
+        return new MigrateCommand.MigrateDiskInfo(srcVolumeInfo.getPath(), MigrateCommand.MigrateDiskInfo.DiskType.FILE, MigrateCommand.MigrateDiskInfo.DriverType.QCOW2,
+                MigrateCommand.MigrateDiskInfo.Source.FILE, destPath);
+    }
+
+    /**
+     * Generates the volume path by appending the Volume UUID to the Libvirt destiny images path.</br>
+     * Example: /var/lib/libvirt/images/f3d49ecc-870c-475a-89fa-fd0124420a9b
+     */
+    @Override
+    protected String generateDestPath(VirtualMachineTO vmTO, VolumeVO srcVolume, Host destHost, StoragePoolVO destStoragePool, VolumeInfo destVolumeInfo) {
+        DiskOfferingVO diskOffering = _diskOfferingDao.findById(srcVolume.getDiskOfferingId());
+        DiskProfile diskProfile = new DiskProfile(destVolumeInfo, diskOffering, HypervisorType.KVM);
+        String templateUuid = getTemplateUuid(destVolumeInfo.getTemplateId());
+        CreateCommand rootImageProvisioningCommand = new CreateCommand(diskProfile, templateUuid, destStoragePool, true);
+
+        Answer rootImageProvisioningAnswer = agentManager.easySend(destHost.getId(), rootImageProvisioningCommand);
+
+        if (rootImageProvisioningAnswer == null) {
+            throw new CloudRuntimeException(String.format("Migration with storage of vm [%s] failed while provisioning root image", vmTO.getName()));
+        }
+
+        if (!rootImageProvisioningAnswer.getResult()) {
+            throw new CloudRuntimeException(String.format("Unable to modify target volume on the host [host id:%s, name:%s]", destHost.getId(), destHost.getName()));
+        }
+
+        String libvirtDestImgsPath = null;
+        if (rootImageProvisioningAnswer instanceof CreateAnswer) {
+            libvirtDestImgsPath = ((CreateAnswer)rootImageProvisioningAnswer).getVolume().getName();
+        }
+        // File.getAbsolutePath is used to keep the file separator as it should be and eliminate a verification to check if exists a file separator in the last character of libvirtDestImgsPath.
+        return new File(libvirtDestImgsPath, destVolumeInfo.getUuid()).getAbsolutePath();
+    }
+
+    /**
+     * Returns the template UUID with the given id. If the template ID is null, it returns null.
+     */
+    protected String getTemplateUuid(Long templateId) {
+        if (templateId == null) {
+            return null;
+        }
+        TemplateInfo templateImage = templateDataFactory.getTemplate(templateId, DataStoreRole.Image);
+        return templateImage.getUuid();
+    }
+
+    /**
+     * Sets the volume path as the volume UUID.
+     */
+    @Override
+    protected void setVolumePath(VolumeVO volume) {
+        volume.setPath(volume.getUuid());
+    }
+
+    /**
+     * Return true if the volume should be migrated. Currently only supports migrating volumes on storage pool of the type StoragePoolType.Filesystem.
+     * This ensures that volumes on shared storage are not migrated and those on local storage pools are migrated.
+     */
+    @Override
+    protected boolean shouldMigrateVolume(StoragePoolVO sourceStoragePool, Host destHost, StoragePoolVO destStoragePool) {
+        return sourceStoragePool.getPoolType() == StoragePoolType.Filesystem;
+    }
+
+    /**
+     * If the template is not on the target primary storage then it copies the template.
+     */
+    @Override
+    protected void copyTemplateToTargetFilesystemStorageIfNeeded(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, DataStore destDataStore, StoragePool destStoragePool,
+            Host destHost) {
+        VMTemplateStoragePoolVO sourceVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(destStoragePool.getId(), srcVolumeInfo.getTemplateId());
+        if (sourceVolumeTemplateStoragePoolVO == null && destStoragePool.getPoolType() == StoragePoolType.Filesystem) {
+            DataStore sourceTemplateDataStore = dataStoreManagerImpl.getImageStore(srcVolumeInfo.getDataCenterId());
+            TemplateInfo sourceTemplateInfo = templateDataFactory.getTemplate(srcVolumeInfo.getTemplateId(), sourceTemplateDataStore);
+            TemplateObjectTO sourceTemplate = new TemplateObjectTO(sourceTemplateInfo);
+
+            LOGGER.debug(String.format("Could not find template [id=%s, name=%s] on the storage pool [id=%s]; copying the template to the target storage pool.",
+                    srcVolumeInfo.getTemplateId(), sourceTemplateInfo.getName(), destDataStore.getId()));
+
+            TemplateInfo destTemplateInfo = templateDataFactory.getTemplate(srcVolumeInfo.getTemplateId(), destDataStore);
+            final TemplateObjectTO destTemplate = new TemplateObjectTO(destTemplateInfo);
+            Answer copyCommandAnswer = sendCopyCommand(destHost, sourceTemplate, destTemplate, destDataStore);
+
+            if (copyCommandAnswer != null && copyCommandAnswer.getResult()) {
+                updateTemplateReferenceIfSuccessfulCopy(srcVolumeInfo, srcStoragePool, destTemplateInfo, destDataStore);
+            }
+        }
+    }
+
+    /**
+     *  Update the template reference on table "template_spool_ref" (VMTemplateStoragePoolVO).
+     */
+    protected void updateTemplateReferenceIfSuccessfulCopy(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, TemplateInfo destTemplateInfo, DataStore destDataStore) {
+        VMTemplateStoragePoolVO srcVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(srcStoragePool.getId(), srcVolumeInfo.getTemplateId());
+        VMTemplateStoragePoolVO destVolumeTemplateStoragePoolVO = new VMTemplateStoragePoolVO(destDataStore.getId(), srcVolumeInfo.getTemplateId());
+        destVolumeTemplateStoragePoolVO.setDownloadPercent(100);
+        destVolumeTemplateStoragePoolVO.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        destVolumeTemplateStoragePoolVO.setState(ObjectInDataStoreStateMachine.State.Ready);
+        destVolumeTemplateStoragePoolVO.setTemplateSize(srcVolumeTemplateStoragePoolVO.getTemplateSize());
+        destVolumeTemplateStoragePoolVO.setLocalDownloadPath(destTemplateInfo.getUuid());
+        destVolumeTemplateStoragePoolVO.setInstallPath(destTemplateInfo.getUuid());
+        vmTemplatePoolDao.persist(destVolumeTemplateStoragePoolVO);
+    }
+
+    /**
+     * Sends the CopyCommand to migrate the template to the dest host.
+     */
+    protected Answer sendCopyCommand(Host destHost, TemplateObjectTO sourceTemplate, TemplateObjectTO destTemplate, DataStore destDataStore) {
+        boolean executeInSequence = virtualMachineManager.getExecuteInSequence(HypervisorType.KVM);
+        CopyCommand copyCommand = new CopyCommand(sourceTemplate, destTemplate, StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value(), executeInSequence);
+        try {
+            Answer copyCommandAnswer = agentManager.send(destHost.getId(), copyCommand);
+            logInCaseOfTemplateCopyFailure(copyCommandAnswer, sourceTemplate, destDataStore);
+            return copyCommandAnswer;
+        } catch (AgentUnavailableException | OperationTimedoutException e) {
+            throw new CloudRuntimeException(generateFailToCopyTemplateMessage(sourceTemplate, destDataStore), e);
+        }
+    }
+
+    private String generateFailToCopyTemplateMessage(TemplateObjectTO sourceTemplate, DataStore destDataStore) {
+        return String.format("Failed to copy template [id=%s, name=%s] to the primary storage pool [id=%s].", sourceTemplate.getId(),
+                sourceTemplate.getName(), destDataStore.getId());
+    }
+
+    /**
+     * Logs in debug mode the copy command failure if the CopyCommand Answer has result as false.
+     */
+    protected void logInCaseOfTemplateCopyFailure(Answer copyCommandAnswer, TemplateObjectTO sourceTemplate, DataStore destDataStore) {
+        if (copyCommandAnswer != null && !copyCommandAnswer.getResult()) {
+            String failureDetails = StringUtils.EMPTY;
+            if (copyCommandAnswer.getDetails() != null) {
+                failureDetails = " Details: " + copyCommandAnswer.getDetails();
+            }
+            LOGGER.error(generateFailToCopyTemplateMessage(sourceTemplate, destDataStore) + failureDetails);
+        }
+    }
+}
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
new file mode 100644
index 0000000..6bcaebe
--- /dev/null
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@ -0,0 +1,2671 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo;
+import com.cloud.agent.api.ModifyTargetsAnswer;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.configuration.Config;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeDetailVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotDetailsDao;
+import com.cloud.storage.dao.SnapshotDetailsVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+
+import com.google.common.base.Preconditions;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.ResignatureAnswer;
+import org.apache.cloudstack.storage.command.ResignatureCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
+    private static final Logger LOGGER = Logger.getLogger(StorageSystemDataMotionStrategy.class);
+    private static final Random RANDOM = new Random(System.nanoTime());
+    private static final int LOCK_TIME_IN_SECONDS = 300;
+    private static final String OPERATION_NOT_SUPPORTED = "This operation is not supported.";
+
+    @Inject
+    protected AgentManager agentManager;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private DataStoreManager dataStoreMgr;
+    @Inject
+    protected DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private GuestOSCategoryDao _guestOsCategoryDao;
+    @Inject
+    private GuestOSDao _guestOsDao;
+    @Inject
+    private ClusterDao clusterDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    protected PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private SnapshotDao _snapshotDao;
+    @Inject
+    private SnapshotDataStoreDao _snapshotDataStoreDao;
+    @Inject
+    private SnapshotDetailsDao _snapshotDetailsDao;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private VMTemplateDao _vmTemplateDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private VolumeDataFactory _volumeDataFactory;
+    @Inject
+    private VolumeDetailsDao volumeDetailsDao;
+    @Inject
+    private VolumeService _volumeService;
+    @Inject
+    private StorageCacheManager cacheMgr;
+    @Inject
+    private EndPointSelector selector;
+
+    @Override
+    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
+        if (srcData instanceof SnapshotInfo) {
+            if (canHandle(srcData) || canHandle(destData)) {
+                return StrategyPriority.HIGHEST;
+            }
+        }
+
+        if (srcData instanceof TemplateInfo && destData instanceof VolumeInfo &&
+                (srcData.getDataStore().getId() == destData.getDataStore().getId()) &&
+                (canHandle(srcData) || canHandle(destData))) {
+            // Both source and dest are on the same storage, so just clone them.
+            return StrategyPriority.HIGHEST;
+        }
+
+        if (srcData instanceof VolumeInfo && destData instanceof VolumeInfo) {
+            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
+
+            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
+                return StrategyPriority.HIGHEST;
+            }
+
+            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
+
+            if (isVolumeOnManagedStorage(destVolumeInfo)) {
+                return StrategyPriority.HIGHEST;
+            }
+        }
+
+        if (srcData instanceof VolumeInfo && destData instanceof TemplateInfo) {
+            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
+
+            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
+                return StrategyPriority.HIGHEST;
+            }
+        }
+
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    private boolean isVolumeOnManagedStorage(VolumeInfo volumeInfo) {
+        DataStore dataStore = volumeInfo.getDataStore();
+
+        if (dataStore.getRole() == DataStoreRole.Primary) {
+            long storagePooldId = dataStore.getId();
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePooldId);
+
+            return storagePoolVO.isManaged();
+        }
+
+        return false;
+    }
+
+    // canHandle returns true if the storage driver for the DataObject that's passed in can support certain features (what features we
+    // care about during a particular invocation of this method depend on what type of DataObject was passed in (ex. VolumeInfo versus SnapshotInfo)).
+    private boolean canHandle(DataObject dataObject) {
+        Preconditions.checkArgument(dataObject != null, "Passing 'null' to dataObject of canHandle(DataObject) is not supported.");
+
+        DataStore dataStore = dataObject.getDataStore();
+
+        if (dataStore.getRole() == DataStoreRole.Primary) {
+            Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
+
+            if (mapCapabilities == null) {
+                return false;
+            }
+
+            if (dataObject instanceof VolumeInfo || dataObject instanceof SnapshotInfo) {
+                String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
+                Boolean supportsStorageSystemSnapshots = Boolean.valueOf(value);
+
+                if (supportsStorageSystemSnapshots) {
+                    LOGGER.info("Using 'StorageSystemDataMotionStrategy' (dataObject is a volume or snapshot and the storage system supports snapshots)");
+
+                    return true;
+                }
+            } else if (dataObject instanceof TemplateInfo) {
+                // If the storage system can clone volumes, we can cache templates on it.
+                String value = mapCapabilities.get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString());
+                Boolean canCloneVolume = Boolean.valueOf(value);
+
+                if (canCloneVolume) {
+                    LOGGER.info("Using 'StorageSystemDataMotionStrategy' (dataObject is a template and the storage system can create a volume from a volume)");
+
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public final StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
+        if (HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
+            return internalCanHandle(volumeMap);
+        }
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    /**
+     * Handles migrating volumes on managed Storage.
+     */
+    protected StrategyPriority internalCanHandle(Map<VolumeInfo, DataStore> volumeMap) {
+        Set<VolumeInfo> volumeInfoSet = volumeMap.keySet();
+
+        for (VolumeInfo volumeInfo : volumeInfoSet) {
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(volumeInfo.getPoolId());
+
+            if (storagePoolVO.isManaged()) {
+                return StrategyPriority.HIGHEST;
+            }
+        }
+
+        Collection<DataStore> dataStores = volumeMap.values();
+
+        for (DataStore dataStore : dataStores) {
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(dataStore.getId());
+
+            if (storagePoolVO.isManaged()) {
+                return StrategyPriority.HIGHEST;
+            }
+        }
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (srcData instanceof SnapshotInfo) {
+            SnapshotInfo srcSnapshotInfo = (SnapshotInfo)srcData;
+
+            handleCopyAsyncForSnapshot(srcSnapshotInfo, destData, callback);
+        } else if (srcData instanceof TemplateInfo && destData instanceof VolumeInfo) {
+            TemplateInfo srcTemplateInfo = (TemplateInfo)srcData;
+            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
+
+            handleCopyAsyncForTemplateAndVolume(srcTemplateInfo, destVolumeInfo, callback);
+        } else if (srcData instanceof VolumeInfo && destData instanceof VolumeInfo) {
+            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
+            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
+
+            handleCopyAsyncForVolumes(srcVolumeInfo, destVolumeInfo, callback);
+        } else if (srcData instanceof VolumeInfo && destData instanceof TemplateInfo &&
+                (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) {
+            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
+            TemplateInfo destTemplateInfo = (TemplateInfo)destData;
+
+            handleCreateTemplateFromManagedVolume(srcVolumeInfo, destTemplateInfo, callback);
+        }
+        else {
+            handleError(OPERATION_NOT_SUPPORTED, callback);
+        }
+    }
+
+    private void handleCopyAsyncForSnapshot(SnapshotInfo srcSnapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        verifyFormat(srcSnapshotInfo);
+
+        boolean canHandleSrc = canHandle(srcSnapshotInfo);
+
+        if (canHandleSrc && (destData instanceof TemplateInfo || destData instanceof SnapshotInfo) &&
+                (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) {
+            handleCopyAsyncToSecondaryStorage(srcSnapshotInfo, destData, callback);
+        } else if (destData instanceof VolumeInfo) {
+            handleCopyAsyncForSnapshotToVolume(srcSnapshotInfo, (VolumeInfo)destData, callback);
+        } else {
+            handleError(OPERATION_NOT_SUPPORTED, callback);
+        }
+    }
+
+    private void handleCopyAsyncForSnapshotToVolume(SnapshotInfo srcSnapshotInfo, VolumeInfo destVolumeInfo,
+                                                    AsyncCompletionCallback<CopyCommandResult> callback) {
+        boolean canHandleSrc = canHandle(srcSnapshotInfo);
+        boolean canHandleDest = canHandle(destVolumeInfo);
+
+        if (canHandleSrc && canHandleDest) {
+            if (srcSnapshotInfo.getDataStore().getId() == destVolumeInfo.getDataStore().getId()) {
+                handleCreateManagedVolumeFromManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback);
+            } else {
+                String errMsg = "To perform this operation, the source and destination primary storages must be the same.";
+
+                handleError(errMsg, callback);
+            }
+        }
+        else if (!canHandleSrc && !canHandleDest) {
+            handleError(OPERATION_NOT_SUPPORTED, callback);
+        }
+        else if (canHandleSrc) {
+            handleCreateNonManagedVolumeFromManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback);
+        }
+        else {
+            handleCreateManagedVolumeFromNonManagedSnapshot(srcSnapshotInfo, destVolumeInfo, callback);
+        }
+    }
+
+    private void handleCopyAsyncForTemplateAndVolume(TemplateInfo srcTemplateInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
+        boolean canHandleSrc = canHandle(srcTemplateInfo);
+
+        if (!canHandleSrc) {
+            handleError(OPERATION_NOT_SUPPORTED, callback);
+        }
+
+        handleCreateVolumeFromTemplateBothOnStorageSystem(srcTemplateInfo, destVolumeInfo, callback);
+    }
+
+    private void handleCopyAsyncForVolumes(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (srcVolumeInfo.getState() == Volume.State.Migrating) {
+            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
+                if (destVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || destVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) {
+                    handleVolumeCopyFromManagedStorageToSecondaryStorage(srcVolumeInfo, destVolumeInfo, callback);
+                } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
+                    handleVolumeMigrationFromManagedStorageToNonManagedStorage(srcVolumeInfo, destVolumeInfo, callback);
+                } else {
+                    String errMsg = "The source volume to migrate and the destination volume are both on managed storage. " +
+                            "Migration in this case is not yet supported.";
+
+                    handleError(errMsg, callback);
+                }
+            } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
+                String errMsg = "The 'StorageSystemDataMotionStrategy' does not support this migration use case.";
+
+                handleError(errMsg, callback);
+            } else {
+                handleVolumeMigrationFromNonManagedStorageToManagedStorage(srcVolumeInfo, destVolumeInfo, callback);
+            }
+        } else if (srcVolumeInfo.getState() == Volume.State.Uploaded &&
+                (srcVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || srcVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) &&
+                destVolumeInfo.getDataStore().getRole() == DataStoreRole.Primary) {
+            ImageFormat imageFormat = destVolumeInfo.getFormat();
+
+            if (!ImageFormat.QCOW2.equals(imageFormat)) {
+                String errMsg = "The 'StorageSystemDataMotionStrategy' does not support this upload use case (non KVM).";
+
+                handleError(errMsg, callback);
+            }
+
+            handleCreateVolumeFromVolumeOnSecondaryStorage(srcVolumeInfo, destVolumeInfo, destVolumeInfo.getDataCenterId(), HypervisorType.KVM, callback);
+        } else {
+            handleError(OPERATION_NOT_SUPPORTED, callback);
+        }
+    }
+
+    private void handleError(String errMsg, AsyncCompletionCallback<CopyCommandResult> callback) {
+        LOGGER.warn(errMsg);
+
+        invokeCallback(errMsg, callback);
+
+        throw new UnsupportedOperationException(errMsg);
+    }
+
+    private void invokeCallback(String errMsg, AsyncCompletionCallback<CopyCommandResult> callback) {
+        CopyCmdAnswer copyCmdAnswer = new CopyCmdAnswer(errMsg);
+
+        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+        result.setResult(errMsg);
+
+        callback.complete(result);
+    }
+
+    private void handleVolumeCopyFromManagedStorageToSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                      AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        String volumePath = null;
+
+        try {
+            if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
+                throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " +
+                        "from managed storage to non-managed storage.");
+            }
+
+            HypervisorType hypervisorType = HypervisorType.KVM;
+            VirtualMachine vm = srcVolumeInfo.getAttachedVM();
+
+            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
+                throw new CloudRuntimeException("Currently, if a volume to copy from managed storage to secondary storage is attached to " +
+                        "a VM, the VM must be in the Stopped state.");
+            }
+
+            long srcStoragePoolId = srcVolumeInfo.getPoolId();
+            StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(srcStoragePoolId);
+
+            HostVO hostVO;
+
+            if (srcStoragePoolVO.getClusterId() != null) {
+                hostVO = getHostInCluster(srcStoragePoolVO.getClusterId());
+            }
+            else {
+                hostVO = getHost(srcVolumeInfo.getDataCenterId(), hypervisorType, false);
+            }
+
+            volumePath = copyManagedVolumeToSecondaryStorage(srcVolumeInfo, destVolumeInfo, hostVO,
+                    "Unable to copy the volume from managed storage to secondary storage");
+        }
+        catch (Exception ex) {
+            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeCopyFromManagedStorageToSecondaryStorage': " +
+                    ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            CopyCmdAnswer copyCmdAnswer;
+
+            if (errMsg != null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+            else if (volumePath == null) {
+                copyCmdAnswer = new CopyCmdAnswer("Unable to acquire a volume path");
+            }
+            else {
+                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)destVolumeInfo.getTO();
+
+                volumeObjectTO.setPath(volumePath);
+
+                copyCmdAnswer = new CopyCmdAnswer(volumeObjectTO);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void handleVolumeMigrationFromManagedStorageToNonManagedStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                            AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+
+        try {
+            if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
+                throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " +
+                        "from managed storage to non-managed storage.");
+            }
+
+            HypervisorType hypervisorType = HypervisorType.KVM;
+            VirtualMachine vm = srcVolumeInfo.getAttachedVM();
+
+            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
+                throw new CloudRuntimeException("Currently, if a volume to migrate from managed storage to non-managed storage is attached to " +
+                        "a VM, the VM must be in the Stopped state.");
+            }
+
+            long destStoragePoolId = destVolumeInfo.getPoolId();
+            StoragePoolVO destStoragePoolVO = _storagePoolDao.findById(destStoragePoolId);
+
+            HostVO hostVO;
+
+            if (destStoragePoolVO.getClusterId() != null) {
+                hostVO = getHostInCluster(destStoragePoolVO.getClusterId());
+            }
+            else {
+                hostVO = getHost(destVolumeInfo.getDataCenterId(), hypervisorType, false);
+            }
+
+            setCertainVolumeValuesNull(destVolumeInfo.getId());
+
+            // migrate the volume via the hypervisor
+            String path = migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from managed storage to non-managed storage");
+
+            updateVolumePath(destVolumeInfo.getId(), path);
+        }
+        catch (Exception ex) {
+            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeMigrationFromManagedStorageToNonManagedStorage': " +
+                    ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            CopyCmdAnswer copyCmdAnswer;
+
+            if (errMsg != null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+            else {
+                destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+
+                DataTO dataTO = destVolumeInfo.getTO();
+
+                copyCmdAnswer = new CopyCmdAnswer(dataTO);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void verifyFormat(ImageFormat imageFormat) {
+        if (imageFormat != ImageFormat.VHD && imageFormat != ImageFormat.OVA && imageFormat != ImageFormat.QCOW2) {
+            throw new CloudRuntimeException("Only the following image types are currently supported: " +
+                    ImageFormat.VHD.toString() + ", " + ImageFormat.OVA.toString() + ", and " + ImageFormat.QCOW2);
+        }
+    }
+
+    private void verifyFormat(SnapshotInfo snapshotInfo) {
+        long volumeId = snapshotInfo.getVolumeId();
+
+        VolumeVO volumeVO = _volumeDao.findByIdIncludingRemoved(volumeId);
+
+        verifyFormat(volumeVO.getFormat());
+    }
+
+    private boolean usingBackendSnapshotFor(SnapshotInfo snapshotInfo) {
+        String property = getSnapshotProperty(snapshotInfo.getId(), "takeSnapshot");
+
+        return Boolean.parseBoolean(property);
+    }
+
+    private boolean needCacheStorage(DataObject srcData, DataObject destData) {
+        DataTO srcTO = srcData.getTO();
+        DataStoreTO srcStoreTO = srcTO.getDataStore();
+        DataTO destTO = destData.getTO();
+        DataStoreTO destStoreTO = destTO.getDataStore();
+
+        // both snapshot and volume are on primary datastore - no need for a cache storage as hypervisor will copy directly
+        if (srcStoreTO instanceof PrimaryDataStoreTO && destStoreTO instanceof PrimaryDataStoreTO) {
+            return false;
+        }
+
+        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) {
+            return false;
+        }
+
+        if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) {
+            return false;
+        }
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("needCacheStorage true; dest at " + destTO.getPath() + ", dest role " + destStoreTO.getRole().toString() + "; src at " +
+                    srcTO.getPath() + ", src role " + srcStoreTO.getRole().toString());
+        }
+
+        return true;
+    }
+
+    private Scope pickCacheScopeForCopy(DataObject srcData, DataObject destData) {
+        Scope srcScope = srcData.getDataStore().getScope();
+        Scope destScope = destData.getDataStore().getScope();
+
+        Scope selectedScope = null;
+
+        if (srcScope.getScopeId() != null) {
+            selectedScope = getZoneScope(srcScope);
+        } else if (destScope.getScopeId() != null) {
+            selectedScope = getZoneScope(destScope);
+        } else {
+            LOGGER.warn("Cannot find a zone-wide scope for movement that needs a cache storage");
+        }
+
+        return selectedScope;
+    }
+
+    private Scope getZoneScope(Scope scope) {
+        ZoneScope zoneScope;
+
+        if (scope instanceof ClusterScope) {
+            ClusterScope clusterScope = (ClusterScope)scope;
+
+            zoneScope = new ZoneScope(clusterScope.getZoneId());
+        } else if (scope instanceof HostScope) {
+            HostScope hostScope = (HostScope)scope;
+
+            zoneScope = new ZoneScope(hostScope.getZoneId());
+        } else {
+            zoneScope = (ZoneScope)scope;
+        }
+
+        return zoneScope;
+    }
+
+    private void handleVolumeMigrationFromNonManagedStorageToManagedStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                            AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+
+        try {
+            HypervisorType hypervisorType = srcVolumeInfo.getHypervisorType();
+
+            if (!HypervisorType.XenServer.equals(hypervisorType) && !HypervisorType.KVM.equals(hypervisorType)) {
+                throw new CloudRuntimeException("Currently, only the XenServer and KVM hypervisor types are supported for the migration of a volume " +
+                        "from non-managed storage to managed storage.");
+            }
+
+            if (HypervisorType.XenServer.equals(hypervisorType)) {
+                handleVolumeMigrationForXenServer(srcVolumeInfo, destVolumeInfo);
+            }
+            else {
+                handleVolumeMigrationForKVM(srcVolumeInfo, destVolumeInfo);
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeMigrationFromNonManagedStorageToManagedStorage': " +
+                    ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            CopyCmdAnswer copyCmdAnswer;
+
+            if (errMsg != null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+            else {
+                destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+
+                DataTO dataTO = destVolumeInfo.getTO();
+
+                copyCmdAnswer = new CopyCmdAnswer(dataTO);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void handleVolumeMigrationForXenServer(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) {
+        VirtualMachine vm = srcVolumeInfo.getAttachedVM();
+
+        if (vm == null || vm.getState() != VirtualMachine.State.Running) {
+            throw new CloudRuntimeException("Currently, a volume to migrate from non-managed storage to managed storage on XenServer must be attached to " +
+                    "a VM in the Running state.");
+        }
+
+        destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
+
+        destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+
+        handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+        HostVO hostVO = _hostDao.findById(vm.getHostId());
+
+        _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+
+        String value = _configDao.getValue(Config.MigrateWait.key());
+        int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue()));
+
+        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destVolumeInfo.getDataStore().getId(), DataStoreRole.Primary);
+
+        MigrateVolumeCommand command = new MigrateVolumeCommand(srcVolumeInfo.getId(), srcVolumeInfo.getPath(), destPool, srcVolumeInfo.getAttachedVmName(),
+                srcVolumeInfo.getVolumeType(), waitInterval);
+
+        Map<String, String> details = new HashMap<>();
+
+        details.put(DiskTO.MANAGED, Boolean.TRUE.toString());
+        details.put(DiskTO.IQN, destVolumeInfo.get_iScsiName());
+        details.put(DiskTO.STORAGE_HOST, destPool.getHostAddress());
+
+        command.setDestDetails(details);
+
+        EndPoint ep = selector.select(srcVolumeInfo, StorageAction.MIGRATEVOLUME);
+
+        Answer answer;
+
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command to; check if host or SSVM is down";
+
+            LOGGER.error(errMsg);
+
+            answer = new Answer(command, false, errMsg);
+        } else {
+            answer = ep.sendMessage(command);
+        }
+
+        handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+
+        if (answer == null || !answer.getResult()) {
+            handleFailedVolumeMigration(srcVolumeInfo, destVolumeInfo, hostVO);
+
+            throw new CloudRuntimeException("Failed to migrate volume with ID " + srcVolumeInfo.getId() + " to storage pool with ID " + destPool.getId());
+        } else {
+            handleSuccessfulVolumeMigration(srcVolumeInfo, destPool, (MigrateVolumeAnswer)answer);
+        }
+    }
+
+    private void handleSuccessfulVolumeMigration(VolumeInfo srcVolumeInfo, StoragePool destPool, MigrateVolumeAnswer migrateVolumeAnswer) {
+        VolumeVO volumeVO = _volumeDao.findById(srcVolumeInfo.getId());
+
+        volumeVO.setPath(migrateVolumeAnswer.getVolumePath());
+
+        String chainInfo = migrateVolumeAnswer.getVolumeChainInfo();
+
+        if (chainInfo != null) {
+            volumeVO.setChainInfo(chainInfo);
+        }
+
+        volumeVO.setPodId(destPool.getPodId());
+        volumeVO.setPoolId(destPool.getId());
+        volumeVO.setLastPoolId(srcVolumeInfo.getPoolId());
+
+        _volumeDao.update(srcVolumeInfo.getId(), volumeVO);
+    }
+
+    private void handleFailedVolumeMigration(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO) {
+        try {
+            _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+        }
+        catch (Exception ex) {
+            LOGGER.warn("Failed to revoke access to the volume with the following ID: " + destVolumeInfo.getId());
+        }
+
+        try {
+            VolumeDetailVO volumeDetailVO = new VolumeDetailVO(destVolumeInfo.getId(), PrimaryDataStoreDriver.BASIC_DELETE_BY_FOLDER,
+                    Boolean.TRUE.toString(), false);
+
+            volumeDetailsDao.persist(volumeDetailVO);
+
+            destVolumeInfo.getDataStore().getDriver().deleteAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
+
+            volumeDetailsDao.removeDetails(srcVolumeInfo.getId());
+        }
+        catch (Exception ex) {
+            LOGGER.warn(ex.getMessage());
+        }
+
+        VolumeVO volumeVO = _volumeDao.findById(srcVolumeInfo.getId());
+
+        volumeVO.setPoolId(srcVolumeInfo.getPoolId());
+        volumeVO.setLastPoolId(srcVolumeInfo.getLastPoolId());
+        volumeVO.setFolder(srcVolumeInfo.getFolder());
+        volumeVO.set_iScsiName(srcVolumeInfo.get_iScsiName());
+
+        _volumeDao.update(srcVolumeInfo.getId(), volumeVO);
+    }
+
+    private void handleVolumeMigrationForKVM(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) {
+        VirtualMachine vm = srcVolumeInfo.getAttachedVM();
+
+        if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
+            throw new CloudRuntimeException("Currently, if a volume to migrate from non-managed storage to managed storage on KVM is attached to " +
+                    "a VM, the VM must be in the Stopped state.");
+        }
+
+        destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
+
+        VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+
+        volumeVO.setPath(volumeVO.get_iScsiName());
+
+        _volumeDao.update(volumeVO.getId(), volumeVO);
+
+        destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+
+        long srcStoragePoolId = srcVolumeInfo.getPoolId();
+        StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(srcStoragePoolId);
+
+        HostVO hostVO;
+
+        if (srcStoragePoolVO.getClusterId() != null) {
+            hostVO = getHostInCluster(srcStoragePoolVO.getClusterId());
+        }
+        else {
+            hostVO = getHost(destVolumeInfo.getDataCenterId(), HypervisorType.KVM, false);
+        }
+
+        // migrate the volume via the hypervisor
+        migrateVolumeForKVM(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from non-managed storage to managed storage");
+
+        volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+
+        volumeVO.setFormat(ImageFormat.QCOW2);
+
+        _volumeDao.update(volumeVO.getId(), volumeVO);
+    }
+
+    /**
+     * This function is responsible for copying a snapshot from managed storage to secondary storage. This is used in the following two cases:
+     * 1) When creating a template from a snapshot
+     * 2) When createSnapshot is called with location=SECONDARY
+     *
+     * @param snapshotInfo source snapshot
+     * @param destData destination (can be template or snapshot)
+     * @param callback callback for async
+     */
+    private void handleCopyAsyncToSecondaryStorage(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+        boolean usingBackendSnapshot = false;
+
+        try {
+            snapshotInfo.processEvent(Event.CopyingRequested);
+
+            HostVO hostVO = getHost(snapshotInfo);
+
+            boolean needCache = needCacheStorage(snapshotInfo, destData);
+
+            DataObject destOnStore = destData;
+
+            if (needCache) {
+                // creates an object in the DB for data to be cached
+                Scope selectedScope = pickCacheScopeForCopy(snapshotInfo, destData);
+
+                destOnStore = cacheMgr.getCacheObject(snapshotInfo, selectedScope);
+
+                destOnStore.processEvent(Event.CreateOnlyRequested);
+            }
+
+            usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
+
+            if (usingBackendSnapshot) {
+                final boolean computeClusterSupportsVolumeClone;
+
+                // only XenServer, VMware, and KVM are currently supported
+                if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
+                    computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
+                }
+                else if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType()) || HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
+                    computeClusterSupportsVolumeClone = true;
+                }
+                else {
+                    throw new CloudRuntimeException("Unsupported hypervisor type");
+                }
+
+                if (!computeClusterSupportsVolumeClone) {
+                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
+                            hostVO.getClusterId();
+
+                    LOGGER.warn(noSupportForResignErrMsg);
+
+                    throw new CloudRuntimeException(noSupportForResignErrMsg);
+                }
+            }
+
+            String vmdk = null;
+            String uuid = null;
+            boolean keepGrantedAccess = false;
+
+            DataStore srcDataStore = snapshotInfo.getDataStore();
+
+            if (usingBackendSnapshot) {
+                createVolumeFromSnapshot(snapshotInfo);
+
+                if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                    keepGrantedAccess = HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType());
+
+                    Map<String, String> extraDetails = null;
+
+                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                        extraDetails = new HashMap<>();
+
+                        String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
+
+                        extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
+                        extraDetails.put(DiskTO.TEMPLATE_RESIGN, Boolean.TRUE.toString());
+                    }
+
+                    copyCmdAnswer = performResignature(snapshotInfo, hostVO, extraDetails, keepGrantedAccess);
+
+                    // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
+                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                        String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
+
+                        disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
+                    }
+
+                    verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
+
+                    vmdk = copyCmdAnswer.getNewData().getPath();
+                    uuid = UUID.randomUUID().toString();
+                }
+            }
+
+            int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+            CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait,
+                    VirtualMachineManager.ExecuteInSequence.value());
+
+            try {
+                if (!keepGrantedAccess) {
+                    _volumeService.grantAccess(snapshotInfo, hostVO, srcDataStore);
+                }
+
+                Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
+
+                if (isForVMware(destData)) {
+                    srcDetails.put(DiskTO.VMDK, vmdk);
+                    srcDetails.put(DiskTO.UUID, uuid);
+
+                    if (destData instanceof TemplateInfo) {
+                        VMTemplateVO templateDataStoreVO = _vmTemplateDao.findById(destData.getId());
+
+                        templateDataStoreVO.setUniqueName(uuid);
+
+                        _vmTemplateDao.update(destData.getId(), templateDataStoreVO);
+                    }
+                }
+
+                copyCommand.setOptions(srcDetails);
+
+                copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+
+                if (!copyCmdAnswer.getResult()) {
+                    errMsg = copyCmdAnswer.getDetails();
+
+                    LOGGER.warn(errMsg);
+
+                    throw new CloudRuntimeException(errMsg);
+                }
+
+                if (needCache) {
+                    // If cached storage was needed (in case of object store as secondary
+                    // storage), at this point, the data has been copied from the primary
+                    // to the NFS cache by the hypervisor. We now invoke another copy
+                    // command to copy this data from cache to secondary storage. We
+                    // then clean up the cache.
+
+                    destOnStore.processEvent(Event.OperationSuccessed, copyCmdAnswer);
+
+                    CopyCommand cmd = new CopyCommand(destOnStore.getTO(), destData.getTO(), primaryStorageDownloadWait,
+                            VirtualMachineManager.ExecuteInSequence.value());
+                    EndPoint ep = selector.select(destOnStore, destData);
+
+                    if (ep == null) {
+                        errMsg = "No remote endpoint to send command, check if host or SSVM is down";
+
+                        LOGGER.error(errMsg);
+
+                        copyCmdAnswer = new CopyCmdAnswer(errMsg);
+                    } else {
+                        copyCmdAnswer = (CopyCmdAnswer)ep.sendMessage(cmd);
+                    }
+
+                    // clean up snapshot copied to staging
+                    cacheMgr.deleteCacheObject(destOnStore);
+                }
+            } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
+                String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : ";
+
+                LOGGER.warn(msg, ex);
+
+                throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+            } finally {
+                _volumeService.revokeAccess(snapshotInfo, hostVO, srcDataStore);
+
+                // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
+                if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                    String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
+
+                    disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
+                }
+
+                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
+                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
+                        errMsg = copyCmdAnswer.getDetails();
+
+                        if (needCache) {
+                            cacheMgr.deleteCacheObject(destOnStore);
+                        }
+                    }
+                    else {
+                        errMsg = "Unable to create template from snapshot";
+                    }
+                }
+
+                try {
+                    if (StringUtils.isEmpty(errMsg)) {
+                        snapshotInfo.processEvent(Event.OperationSuccessed);
+                    }
+                    else {
+                        snapshotInfo.processEvent(Event.OperationFailed);
+                    }
+                }
+                catch (Exception ex) {
+                    LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
+                }
+            }
+        }
+        catch (Exception ex) {
+            errMsg = ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            if (usingBackendSnapshot) {
+                deleteVolumeFromSnapshot(snapshotInfo);
+            }
+
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void handleCreateNonManagedVolumeFromManagedSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo,
+                                                                 AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (!HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
+            String errMsg = "Creating a volume on non-managed storage from a snapshot on managed storage is currently only supported with XenServer.";
+
+            handleError(errMsg, callback);
+        }
+
+        long volumeStoragePoolId = volumeInfo.getDataStore().getId();
+        StoragePoolVO volumeStoragePoolVO = _storagePoolDao.findById(volumeStoragePoolId);
+
+        if (volumeStoragePoolVO.getClusterId() == null) {
+            String errMsg = "To create a non-managed volume from a managed snapshot, the destination storage pool must be cluster scoped.";
+
+            handleError(errMsg, callback);
+        }
+
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        boolean usingBackendSnapshot = false;
+
+        try {
+            snapshotInfo.processEvent(Event.CopyingRequested);
+
+            usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
+
+            if (usingBackendSnapshot) {
+                boolean computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(volumeStoragePoolVO.getClusterId());
+
+                if (!computeClusterSupportsVolumeClone) {
+                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
+                            volumeStoragePoolVO.getClusterId();
+
+                    LOGGER.warn(noSupportForResignErrMsg);
+
+                    throw new CloudRuntimeException(noSupportForResignErrMsg);
+                }
+
+                createVolumeFromSnapshot(snapshotInfo);
+
+                HostVO hostVO = getHost(snapshotInfo.getDataCenterId(), HypervisorType.XenServer, true);
+
+                copyCmdAnswer = performResignature(snapshotInfo, hostVO, null, true);
+
+                verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
+            }
+
+            int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+
+            CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait,
+                    VirtualMachineManager.ExecuteInSequence.value());
+
+            HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId());
+
+            if (!usingBackendSnapshot) {
+                long snapshotStoragePoolId = snapshotInfo.getDataStore().getId();
+                DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary);
+
+                _volumeService.grantAccess(snapshotInfo, hostVO, snapshotDataStore);
+            }
+
+            Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
+
+            copyCommand.setOptions(srcDetails);
+
+            copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+
+            if (!copyCmdAnswer.getResult()) {
+                errMsg = copyCmdAnswer.getDetails();
+
+                LOGGER.warn(errMsg);
+
+                throw new CloudRuntimeException(errMsg);
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateNonManagedVolumeFromManagedSnapshot': " + ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            try {
+                HostVO hostVO = getHostInCluster(volumeStoragePoolVO.getClusterId());
+
+                long snapshotStoragePoolId = snapshotInfo.getDataStore().getId();
+                DataStore snapshotDataStore = dataStoreMgr.getDataStore(snapshotStoragePoolId, DataStoreRole.Primary);
+
+                _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotDataStore);
+            }
+            catch (Exception e) {
+                LOGGER.debug("Failed to revoke access from dest volume", e);
+            }
+
+            if (usingBackendSnapshot) {
+                deleteVolumeFromSnapshot(snapshotInfo);
+            }
+
+            try {
+                if (StringUtils.isEmpty(errMsg)) {
+                    snapshotInfo.processEvent(Event.OperationSuccessed);
+                }
+                else {
+                    snapshotInfo.processEvent(Event.OperationFailed);
+                }
+            }
+            catch (Exception ex) {
+                LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
+            }
+
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void verifyCopyCmdAnswer(CopyCmdAnswer copyCmdAnswer, DataObject dataObject) {
+        if (copyCmdAnswer == null) {
+            throw new CloudRuntimeException("Unable to create a volume from a " + dataObject.getType().toString().toLowerCase() + " (copyCmdAnswer == null)");
+        }
+
+        if (copyCmdAnswer.getResult()) {
+            return;
+        }
+
+        String details = copyCmdAnswer.getDetails();
+
+        if (StringUtils.isEmpty(details)) {
+            throw new CloudRuntimeException("Unable to create a volume from a " + dataObject.getType().toString().toLowerCase() + " (no error details specified)");
+        }
+
+        throw new CloudRuntimeException(details);
+    }
+
+    /**
+     * Creates a managed volume on the storage from a snapshot that resides on the secondary storage (archived snapshot).
+     * @param snapshotInfo snapshot on secondary
+     * @param volumeInfo volume to be created on the storage
+     * @param callback for async
+     */
+    private void handleCreateManagedVolumeFromNonManagedSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo,
+                                                                 AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        try {
+            // at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance)
+            DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId());
+            SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId());
+
+            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+            _volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType());
+
+            HostVO hostVO;
+
+            // create a volume on the storage
+            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
+            VolumeApiResult result = future.get();
+
+            if (result.isFailed()) {
+                LOGGER.error("Failed to create a volume: " + result.getResult());
+
+                throw new CloudRuntimeException(result.getResult());
+            }
+
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+            volumeInfo.processEvent(Event.MigrationRequested);
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+
+            handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+            hostVO = getHost(snapshotInfo.getDataCenterId(), snapshotInfo.getHypervisorType(), false);
+
+            // copy the volume from secondary via the hypervisor
+            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
+                copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO);
+            }
+            else {
+                copyCmdAnswer = copyImageToVolume(snapshotInfo, volumeInfo, hostVO);
+            }
+
+            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
+                if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
+                    throw new CloudRuntimeException(copyCmdAnswer.getDetails());
+                }
+                else {
+                    throw new CloudRuntimeException("Unable to create volume from snapshot");
+                }
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateManagedVolumeFromNonManagedSnapshot': " + ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    /**
+     * Clones a template present on the storage to a new volume and resignatures it.
+     *
+     * @param templateInfo source template
+     * @param volumeInfo destination ROOT volume
+     * @param callback for async
+     */
+    private void handleCreateVolumeFromTemplateBothOnStorageSystem(TemplateInfo templateInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        try {
+            Preconditions.checkArgument(templateInfo != null, "Passing 'null' to templateInfo of " +
+                            "handleCreateVolumeFromTemplateBothOnStorageSystem is not supported.");
+            Preconditions.checkArgument(volumeInfo != null, "Passing 'null' to volumeInfo of " +
+                            "handleCreateVolumeFromTemplateBothOnStorageSystem is not supported.");
+
+            verifyFormat(templateInfo.getFormat());
+
+            HostVO hostVO = null;
+
+            final boolean computeClusterSupportsVolumeClone;
+
+            // only XenServer, VMware, and KVM are currently supported
+            // Leave host equal to null for KVM since we don't need to perform a resignature when using that hypervisor type.
+            if (volumeInfo.getFormat() == ImageFormat.VHD) {
+                hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.XenServer, true);
+
+                if (hostVO == null) {
+                    throw new CloudRuntimeException("Unable to locate a host capable of resigning in the zone with the following ID: " +
+                            volumeInfo.getDataCenterId());
+                }
+
+                computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
+
+                if (!computeClusterSupportsVolumeClone) {
+                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
+                            hostVO.getClusterId();
+
+                    LOGGER.warn(noSupportForResignErrMsg);
+
+                    throw new CloudRuntimeException(noSupportForResignErrMsg);
+                }
+            }
+            else if (volumeInfo.getFormat() == ImageFormat.OVA) {
+                // all VMware hosts support resigning
+                hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.VMware, false);
+
+                if (hostVO == null) {
+                    throw new CloudRuntimeException("Unable to locate a host capable of resigning in the zone with the following ID: " +
+                            volumeInfo.getDataCenterId());
+                }
+            }
+
+            VolumeDetailVO volumeDetail = new VolumeDetailVO(volumeInfo.getId(),
+                    "cloneOfTemplate",
+                    String.valueOf(templateInfo.getId()),
+                    false);
+
+            volumeDetail = volumeDetailsDao.persist(volumeDetail);
+
+            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
+
+            int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
+
+            VolumeApiResult result = future.get(storagePoolMaxWaitSeconds, TimeUnit.SECONDS);
+
+            if (volumeDetail != null) {
+                volumeDetailsDao.remove(volumeDetail.getId());
+            }
+
+            if (result.isFailed()) {
+                LOGGER.warn("Failed to create a volume: " + result.getResult());
+
+                throw new CloudRuntimeException(result.getResult());
+            }
+
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+            volumeInfo.processEvent(Event.MigrationRequested);
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+
+            if (hostVO != null) {
+                Map<String, String> extraDetails = null;
+
+                if (HypervisorType.VMware.equals(templateInfo.getHypervisorType())) {
+                    extraDetails = new HashMap<>();
+
+                    String extraDetailsVmdk = templateInfo.getUniqueName() + ".vmdk";
+
+                    extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
+                    extraDetails.put(DiskTO.EXPAND_DATASTORE, Boolean.TRUE.toString());
+                }
+
+                copyCmdAnswer = performResignature(volumeInfo, hostVO, extraDetails);
+
+                verifyCopyCmdAnswer(copyCmdAnswer, templateInfo);
+
+                // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
+                if (HypervisorType.VMware.equals(templateInfo.getHypervisorType())) {
+                    disconnectHostFromVolume(hostVO, volumeInfo.getPoolId(), volumeInfo.get_iScsiName());
+                }
+            }
+            else {
+                VolumeObjectTO newVolume = new VolumeObjectTO();
+
+                newVolume.setSize(volumeInfo.getSize());
+                newVolume.setPath(volumeInfo.getPath());
+                newVolume.setFormat(volumeInfo.getFormat());
+
+                copyCmdAnswer = new CopyCmdAnswer(newVolume);
+            }
+        } catch (Exception ex) {
+            try {
+                volumeInfo.getDataStore().getDriver().deleteAsync(volumeInfo.getDataStore(), volumeInfo, null);
+            }
+            catch (Exception exc) {
+                LOGGER.warn("Failed to delete volume", exc);
+            }
+
+            if (templateInfo != null) {
+                errMsg = "Create volume from template (ID = " + templateInfo.getId() + ") failed: " + ex.getMessage();
+            }
+            else {
+                errMsg = "Create volume from template failed: " + ex.getMessage();
+            }
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void handleCreateManagedVolumeFromManagedSnapshot(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo,
+                                                              AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        boolean useCloning = true;
+
+        try {
+            verifyFormat(snapshotInfo);
+
+            HostVO hostVO = getHost(snapshotInfo);
+
+            boolean usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
+            boolean computeClusterSupportsVolumeClone = true;
+
+            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
+                computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
+
+                if (usingBackendSnapshot && !computeClusterSupportsVolumeClone) {
+                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
+                            hostVO.getClusterId();
+
+                    LOGGER.warn(noSupportForResignErrMsg);
+
+                    throw new CloudRuntimeException(noSupportForResignErrMsg);
+                }
+            }
+
+            boolean canStorageSystemCreateVolumeFromVolume = canStorageSystemCreateVolumeFromVolume(snapshotInfo.getDataStore().getId());
+
+            useCloning = usingBackendSnapshot || (canStorageSystemCreateVolumeFromVolume && computeClusterSupportsVolumeClone);
+
+            VolumeDetailVO volumeDetail = null;
+
+            if (useCloning) {
+                volumeDetail = new VolumeDetailVO(volumeInfo.getId(),
+                    "cloneOfSnapshot",
+                    String.valueOf(snapshotInfo.getId()),
+                    false);
+
+                volumeDetail = volumeDetailsDao.persist(volumeDetail);
+            }
+
+            // at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance)
+            DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId());
+            SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId());
+
+            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+            _volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType());
+
+            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
+            VolumeApiResult result = future.get();
+
+            if (volumeDetail != null) {
+                volumeDetailsDao.remove(volumeDetail.getId());
+            }
+
+            if (result.isFailed()) {
+                LOGGER.warn("Failed to create a volume: " + result.getResult());
+
+                throw new CloudRuntimeException(result.getResult());
+            }
+
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+            volumeInfo.processEvent(Event.MigrationRequested);
+            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
+
+            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                if (useCloning) {
+                    Map<String, String> extraDetails = null;
+
+                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                        extraDetails = new HashMap<>();
+
+                        String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
+
+                        extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
+                    }
+
+                    copyCmdAnswer = performResignature(volumeInfo, hostVO, extraDetails);
+
+                    // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
+                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
+                        disconnectHostFromVolume(hostVO, volumeInfo.getPoolId(), volumeInfo.get_iScsiName());
+                    }
+                } else {
+                    // asking for a XenServer host here so we don't always prefer to use XenServer hosts that support resigning
+                    // even when we don't need those hosts to do this kind of copy work
+                    hostVO = getHost(snapshotInfo.getDataCenterId(), snapshotInfo.getHypervisorType(), false);
+
+                    handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+                    copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO);
+                }
+
+                verifyCopyCmdAnswer(copyCmdAnswer, snapshotInfo);
+            }
+            else if (HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
+                VolumeObjectTO newVolume = new VolumeObjectTO();
+
+                newVolume.setSize(volumeInfo.getSize());
+                newVolume.setPath(volumeInfo.get_iScsiName());
+                newVolume.setFormat(volumeInfo.getFormat());
+
+                copyCmdAnswer = new CopyCmdAnswer(newVolume);
+            }
+            else {
+                throw new CloudRuntimeException("Unsupported hypervisor type");
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateManagedVolumeFromManagedSnapshot': " +
+                    ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            if (useCloning) {
+                handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+            }
+
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private void handleCreateVolumeFromVolumeOnSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
+                                                                long dataCenterId, HypervisorType hypervisorType,
+                                                                AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        try {
+            // create a volume on the storage
+            destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
+
+            destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
+
+            HostVO hostVO = getHost(dataCenterId, hypervisorType, false);
+
+            handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+            // copy the volume from secondary via the hypervisor
+            copyCmdAnswer = copyImageToVolume(srcVolumeInfo, destVolumeInfo, hostVO);
+
+            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
+                if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
+                    throw new CloudRuntimeException(copyCmdAnswer.getDetails());
+                }
+                else {
+                    throw new CloudRuntimeException("Unable to create volume from volume");
+                }
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromVolumeOnSecondaryStorage': " +
+                    ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private CopyCmdAnswer copyImageToVolume(DataObject srcDataObject, VolumeInfo destVolumeInfo, HostVO hostVO) {
+        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+
+        CopyCommand copyCommand = new CopyCommand(srcDataObject.getTO(), destVolumeInfo.getTO(), primaryStorageDownloadWait,
+                VirtualMachineManager.ExecuteInSequence.value());
+
+        CopyCmdAnswer copyCmdAnswer;
+
+        try {
+            _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+
+            Map<String, String> destDetails = getVolumeDetails(destVolumeInfo);
+
+            copyCommand.setOptions2(destDetails);
+
+            copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+        }
+        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
+            String msg = "Failed to copy image : ";
+
+            LOGGER.warn(msg, ex);
+
+            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+        }
+        finally {
+            _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+        }
+
+        VolumeObjectTO volumeObjectTO = (VolumeObjectTO)copyCmdAnswer.getNewData();
+
+        volumeObjectTO.setFormat(ImageFormat.QCOW2);
+
+        return copyCmdAnswer;
+    }
+
+    /**
+     * If the underlying storage system is making use of read-only snapshots, this gives the storage system the opportunity to
+     * create a volume from the snapshot so that we can copy the VHD file that should be inside of the snapshot to secondary storage.
+     *
+     * The resultant volume must be writable because we need to resign the SR and the VDI that should be inside of it before we copy
+     * the VHD file to secondary storage.
+     *
+     * If the storage system is using writable snapshots, then nothing need be done by that storage system here because we can just
+     * resign the SR and the VDI that should be inside of the snapshot before copying the VHD file to secondary storage.
+     */
+    private void createVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
+        SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "create");
+
+        try {
+            snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
+        }
+        finally {
+            _snapshotDetailsDao.remove(snapshotDetails.getId());
+        }
+    }
+
+    /**
+     * If the underlying storage system needed to create a volume from a snapshot for createVolumeFromSnapshot(SnapshotInfo), then
+     * this is its opportunity to delete that temporary volume and restore properties in snapshot_details to the way they were before the
+     * invocation of createVolumeFromSnapshot(SnapshotInfo).
+     */
+    private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
+        SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete");
+
+        try {
+            snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
+        }
+        finally {
+            _snapshotDetailsDao.remove(snapshotDetails.getId());
+        }
+    }
+
+    private void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState qualityOfServiceState) {
+        try {
+            ((PrimaryDataStoreDriver)volumeInfo.getDataStore().getDriver()).handleQualityOfServiceForVolumeMigration(volumeInfo, qualityOfServiceState);
+        }
+        catch (Exception ex) {
+            LOGGER.warn(ex);
+        }
+    }
+
+    private SnapshotDetailsVO handleSnapshotDetails(long csSnapshotId, String value) {
+        String name = "tempVolume";
+
+        _snapshotDetailsDao.removeDetail(csSnapshotId, name);
+
+        SnapshotDetailsVO snapshotDetails = new SnapshotDetailsVO(csSnapshotId, name, value, false);
+
+        return _snapshotDetailsDao.persist(snapshotDetails);
+    }
+
+    /**
+     * For each disk to migrate:
+     * <ul>
+     *  <li>Create a volume on the target storage system.</li>
+     *  <li>Make the newly created volume accessible to the target KVM host.</li>
+     *  <li>Send a command to the target KVM host to connect to the newly created volume.</li>
+     *  <li>Send a command to the source KVM host to migrate the VM and its storage.</li>
+     * </ul>
+     */
+    @Override
+    public void copyAsync(Map<VolumeInfo, DataStore> volumeDataStoreMap, VirtualMachineTO vmTO, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        String errMsg = null;
+
+        try {
+            if (srcHost.getHypervisorType() != HypervisorType.KVM) {
+                throw new CloudRuntimeException("Invalid hypervisor type (only KVM supported for this operation at the time being)");
+            }
+
+            verifyLiveMigrationMapForKVM(volumeDataStoreMap);
+
+            VMInstanceVO vmInstance = _vmDao.findById(vmTO.getId());
+            vmTO.setState(vmInstance.getState());
+            List<MigrateDiskInfo> migrateDiskInfoList = new ArrayList<MigrateDiskInfo>();
+
+            Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage = new HashMap<>();
+            Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo = new HashMap<>();
+
+            for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) {
+                VolumeInfo srcVolumeInfo = entry.getKey();
+                DataStore destDataStore = entry.getValue();
+
+                VolumeVO srcVolume = _volumeDao.findById(srcVolumeInfo.getId());
+                StoragePoolVO destStoragePool = _storagePoolDao.findById(destDataStore.getId());
+                StoragePoolVO sourceStoragePool = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
+
+                if (!shouldMigrateVolume(sourceStoragePool, destHost, destStoragePool)) {
+                    continue;
+                }
+
+                copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, sourceStoragePool, destDataStore, destStoragePool, destHost);
+
+                VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool);
+                VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
+
+                // move the volume from Allocated to Creating
+                destVolumeInfo.processEvent(Event.MigrationCopyRequested);
+                // move the volume from Creating to Ready
+                destVolumeInfo.processEvent(Event.MigrationCopySucceeded);
+                // move the volume from Ready to Migrating
+                destVolumeInfo.processEvent(Event.MigrationRequested);
+
+                // create a volume on the destination storage
+                destDataStore.getDriver().createAsync(destDataStore, destVolumeInfo, null);
+
+                destVolume = _volumeDao.findById(destVolume.getId());
+
+                setVolumePath(destVolume);
+
+                _volumeDao.update(destVolume.getId(), destVolume);
+
+                destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
+
+                handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+                _volumeService.grantAccess(destVolumeInfo, destHost, destDataStore);
+
+                String destPath = generateDestPath(vmTO, srcVolume, destHost, destStoragePool, destVolumeInfo);
+
+                MigrateCommand.MigrateDiskInfo migrateDiskInfo = configureMigrateDiskInfo(srcVolumeInfo, destPath);
+                migrateDiskInfo.setSourceDiskOnStorageFileSystem(isStoragePoolTypeOfFile(sourceStoragePool));
+                migrateDiskInfoList.add(migrateDiskInfo);
+
+                migrateStorage.put(srcVolumeInfo.getPath(), migrateDiskInfo);
+
+                srcVolumeInfoToDestVolumeInfo.put(srcVolumeInfo, destVolumeInfo);
+            }
+
+            PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO);
+
+            try {
+                Answer pfma = agentManager.send(destHost.getId(), pfmc);
+
+                if (pfma == null || !pfma.getResult()) {
+                    String details = pfma != null ? pfma.getDetails() : "null answer returned";
+                    String msg = "Unable to prepare for migration due to the following: " + details;
+
+                    throw new AgentUnavailableException(msg, destHost.getId());
+                }
+            }
+            catch (final OperationTimedoutException e) {
+                throw new AgentUnavailableException("Operation timed out", destHost.getId());
+            }
+
+            VMInstanceVO vm = _vmDao.findById(vmTO.getId());
+            boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+
+            MigrateCommand migrateCommand = new MigrateCommand(vmTO.getName(), destHost.getPrivateIpAddress(), isWindows, vmTO, true);
+
+            migrateCommand.setWait(StorageManager.KvmStorageOnlineMigrationWait.value());
+
+            migrateCommand.setMigrateStorage(migrateStorage);
+            migrateCommand.setMigrateDiskInfoList(migrateDiskInfoList);
+
+            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
+            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
+
+            migrateCommand.setAutoConvergence(kvmAutoConvergence);
+
+            MigrateAnswer migrateAnswer = (MigrateAnswer)agentManager.send(srcHost.getId(), migrateCommand);
+
+            boolean success = migrateAnswer != null && migrateAnswer.getResult();
+
+            handlePostMigration(success, srcVolumeInfoToDestVolumeInfo, vmTO, destHost);
+
+            if (migrateAnswer == null) {
+                throw new CloudRuntimeException("Unable to get an answer to the migrate command");
+            }
+
+            if (!migrateAnswer.getResult()) {
+                errMsg = migrateAnswer.getDetails();
+
+                throw new CloudRuntimeException(errMsg);
+            }
+        }
+        catch (Exception ex) {
+            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.copyAsync': " + ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            CopyCmdAnswer copyCmdAnswer = new CopyCmdAnswer(errMsg);
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    /**
+     * Returns true. This method was implemented considering the classes that extend this {@link StorageSystemDataMotionStrategy} and cannot migrate volumes from certain types of source storage pools and/or to a different kind of destiny storage pool.
+     */
+    protected boolean shouldMigrateVolume(StoragePoolVO sourceStoragePool, Host destHost, StoragePoolVO destStoragePool) {
+        return true;
+    }
+
+    /**
+     * Returns true if the storage pool type is {@link StoragePoolType.Filesystem}.
+     */
+    protected boolean isStoragePoolTypeOfFile(StoragePoolVO sourceStoragePool) {
+        return sourceStoragePool.getPoolType() == StoragePoolType.Filesystem;
+    }
+
+    /**
+     * Returns the iScsi connection path.
+     */
+    protected String generateDestPath(VirtualMachineTO vmTO, VolumeVO srcVolume, Host destHost, StoragePoolVO destStoragePool, VolumeInfo destVolumeInfo) {
+        return connectHostToVolume(destHost, destVolumeInfo.getPoolId(), destVolumeInfo.get_iScsiName());
+    }
+
+    /**
+     * Configures a {@link MigrateDiskInfo} object with disk type of BLOCK, Driver type RAW and Source DEV
+     */
+    protected MigrateCommand.MigrateDiskInfo configureMigrateDiskInfo(VolumeInfo srcVolumeInfo, String destPath) {
+        return new MigrateCommand.MigrateDiskInfo(srcVolumeInfo.getPath(), MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, MigrateCommand.MigrateDiskInfo.DriverType.RAW,
+                MigrateCommand.MigrateDiskInfo.Source.DEV, destPath);
+    }
+
+    /**
+     * Sets the volume path as the iScsi name in case of a configured iScsi.
+     */
+    protected void setVolumePath(VolumeVO volume) {
+        volume.setPath(volume.get_iScsiName());
+    }
+
+    /**
+     * For this strategy it is not necessary to copy the template before migrating the VM.
+     * However, classes that extend this one may need to copy the template to the target storage pool before migrating the VM.
+     */
+    protected void copyTemplateToTargetFilesystemStorageIfNeeded(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, DataStore destDataStore, StoragePool destStoragePool,
+            Host destHost) {
+        // This method is used by classes that extend this one
+    }
+
+    private void handlePostMigration(boolean success, Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo, VirtualMachineTO vmTO, Host destHost) {
+        if (!success) {
+            try {
+                PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO);
+
+                pfmc.setRollback(true);
+
+                Answer pfma = agentManager.send(destHost.getId(), pfmc);
+
+                if (pfma == null || !pfma.getResult()) {
+                    String details = pfma != null ? pfma.getDetails() : "null answer returned";
+                    String msg = "Unable to rollback prepare for migration due to the following: " + details;
+
+                    throw new AgentUnavailableException(msg, destHost.getId());
+                }
+            }
+            catch (Exception e) {
+                LOGGER.debug("Failed to disconnect one or more (original) dest volumes", e);
+            }
+        }
+
+        for (Map.Entry<VolumeInfo, VolumeInfo> entry : srcVolumeInfoToDestVolumeInfo.entrySet()) {
+            VolumeInfo srcVolumeInfo = entry.getKey();
+            VolumeInfo destVolumeInfo = entry.getValue();
+
+            handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+
+            if (success) {
+                srcVolumeInfo.processEvent(Event.OperationSuccessed);
+                destVolumeInfo.processEvent(Event.OperationSuccessed);
+
+                _volumeDao.updateUuid(srcVolumeInfo.getId(), destVolumeInfo.getId());
+
+                VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
+
+                volumeVO.setFormat(ImageFormat.QCOW2);
+
+                _volumeDao.update(volumeVO.getId(), volumeVO);
+
+                try {
+                    _volumeService.destroyVolume(srcVolumeInfo.getId());
+
+                    srcVolumeInfo = _volumeDataFactory.getVolume(srcVolumeInfo.getId());
+
+                    AsyncCallFuture<VolumeApiResult> destroyFuture = _volumeService.expungeVolumeAsync(srcVolumeInfo);
+
+                    if (destroyFuture.get().isFailed()) {
+                        LOGGER.debug("Failed to clean up source volume on storage");
+                    }
+                } catch (Exception e) {
+                    LOGGER.debug("Failed to clean up source volume on storage", e);
+                }
+
+                // Update the volume ID for snapshots on secondary storage
+                if (!_snapshotDao.listByVolumeId(srcVolumeInfo.getId()).isEmpty()) {
+                    _snapshotDao.updateVolumeIds(srcVolumeInfo.getId(), destVolumeInfo.getId());
+                    _snapshotDataStoreDao.updateVolumeIds(srcVolumeInfo.getId(), destVolumeInfo.getId());
+                }
+            }
+            else {
+                try {
+                    disconnectHostFromVolume(destHost, destVolumeInfo.getPoolId(), destVolumeInfo.get_iScsiName());
+                }
+                catch (Exception e) {
+                    LOGGER.debug("Failed to disconnect (new) dest volume", e);
+                }
+
+                try {
+                    _volumeService.revokeAccess(destVolumeInfo, destHost, destVolumeInfo.getDataStore());
+                }
+                catch (Exception e) {
+                    LOGGER.debug("Failed to revoke access from dest volume", e);
+                }
+
+                destVolumeInfo.processEvent(Event.OperationFailed);
+                srcVolumeInfo.processEvent(Event.OperationFailed);
+
+                try {
+                    _volumeService.destroyVolume(destVolumeInfo.getId());
+
+                    destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId());
+
+                    AsyncCallFuture<VolumeApiResult> destroyFuture = _volumeService.expungeVolumeAsync(destVolumeInfo);
+
+                    if (destroyFuture.get().isFailed()) {
+                        LOGGER.debug("Failed to clean up dest volume on storage");
+                    }
+                } catch (Exception e) {
+                    LOGGER.debug("Failed to clean up dest volume on storage", e);
+                }
+            }
+        }
+    }
+
+    private VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePoolVO storagePoolVO) {
+        Long lastPoolId = volume.getPoolId();
+
+        VolumeVO newVol = new VolumeVO(volume);
+
+        newVol.setInstanceId(null);
+        newVol.setChainInfo(null);
+        newVol.setPath(null);
+        newVol.setFolder(null);
+        newVol.setPodId(storagePoolVO.getPodId());
+        newVol.setPoolId(storagePoolVO.getId());
+        newVol.setLastPoolId(lastPoolId);
+
+        return _volumeDao.persist(newVol);
+    }
+
+    protected String connectHostToVolume(Host host, long storagePoolId, String iqn) {
+        ModifyTargetsCommand modifyTargetsCommand = getModifyTargetsCommand(storagePoolId, iqn, true);
+
+        return sendModifyTargetsCommand(modifyTargetsCommand, host.getId()).get(0);
+    }
+
+    private void disconnectHostFromVolume(Host host, long storagePoolId, String iqn) {
+        ModifyTargetsCommand modifyTargetsCommand = getModifyTargetsCommand(storagePoolId, iqn, false);
+
+        sendModifyTargetsCommand(modifyTargetsCommand, host.getId());
+    }
+
+    private ModifyTargetsCommand getModifyTargetsCommand(long storagePoolId, String iqn, boolean add) {
+        StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
+
+        Map<String, String> details = new HashMap<>();
+
+        details.put(ModifyTargetsCommand.IQN, iqn);
+        details.put(ModifyTargetsCommand.STORAGE_TYPE, storagePool.getPoolType().name());
+        details.put(ModifyTargetsCommand.STORAGE_UUID, storagePool.getUuid());
+        details.put(ModifyTargetsCommand.STORAGE_HOST, storagePool.getHostAddress());
+        details.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
+
+        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+        List<Map<String, String>> targets = new ArrayList<>();
+
+        targets.add(details);
+
+        cmd.setTargets(targets);
+        cmd.setApplyToAllHostsInCluster(true);
+        cmd.setAdd(add);
+        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+
+        return cmd;
+    }
+
+    private List<String> sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        ModifyTargetsAnswer modifyTargetsAnswer = (ModifyTargetsAnswer)agentManager.easySend(hostId, cmd);
+
+        if (modifyTargetsAnswer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
+        }
+
+        if (!modifyTargetsAnswer.getResult()) {
+            String msg = "Unable to modify targets on the following host: " + hostId;
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        return modifyTargetsAnswer.getConnectedPaths();
+    }
+
+    /*
+    * At a high level: The source storage cannot be managed and the destination storage must be managed.
+    */
+    private void verifyLiveMigrationMapForKVM(Map<VolumeInfo, DataStore> volumeDataStoreMap) {
+        for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) {
+            VolumeInfo volumeInfo = entry.getKey();
+
+            Long storagePoolId = volumeInfo.getPoolId();
+            StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(storagePoolId);
+
+            if (srcStoragePoolVO == null) {
+                throw new CloudRuntimeException("Volume with ID " + volumeInfo.getId() + " is not associated with a storage pool.");
+            }
+
+            if (srcStoragePoolVO.isManaged()) {
+                throw new CloudRuntimeException("Migrating a volume online with KVM from managed storage is not currently supported.");
+            }
+
+            DataStore dataStore = entry.getValue();
+            StoragePoolVO destStoragePoolVO = _storagePoolDao.findById(dataStore.getId());
+
+            if (destStoragePoolVO == null) {
+                throw new CloudRuntimeException("Destination storage pool with ID " + dataStore.getId() + " was not located.");
+            }
+        }
+    }
+
+    private boolean canStorageSystemCreateVolumeFromVolume(long storagePoolId) {
+        return storageSystemSupportsCapability(storagePoolId, DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString());
+    }
+
+    private boolean canStorageSystemCreateVolumeFromSnapshot(long storagePoolId) {
+        return storageSystemSupportsCapability(storagePoolId, DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_SNAPSHOT.toString());
+    }
+
+    private boolean storageSystemSupportsCapability(long storagePoolId, String capability) {
+        boolean supportsCapability = false;
+
+        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
+
+        if (mapCapabilities != null) {
+            String value = mapCapabilities.get(capability);
+
+            supportsCapability = Boolean.valueOf(value);
+        }
+
+        return supportsCapability;
+    }
+
+    private String getVolumeProperty(long volumeId, String property) {
+        VolumeDetailVO volumeDetails = volumeDetailsDao.findDetail(volumeId, property);
+
+        if (volumeDetails != null) {
+            return volumeDetails.getValue();
+        }
+
+        return null;
+    }
+
+    private String getSnapshotProperty(long snapshotId, String property) {
+        SnapshotDetailsVO snapshotDetails = _snapshotDetailsDao.findDetail(snapshotId, property);
+
+        if (snapshotDetails != null) {
+            return snapshotDetails.getValue();
+        }
+
+        return null;
+    }
+
+    private void handleCreateTemplateFromManagedVolume(VolumeInfo volumeInfo, TemplateInfo templateInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
+        boolean srcVolumeDetached = volumeInfo.getAttachedVM() == null;
+
+        String errMsg = null;
+        CopyCmdAnswer copyCmdAnswer = null;
+
+        try {
+            if (!ImageFormat.QCOW2.equals(volumeInfo.getFormat())) {
+                throw new CloudRuntimeException("When using managed storage, you can only create a template from a volume on KVM currently.");
+            }
+
+            volumeInfo.processEvent(Event.MigrationRequested);
+
+            HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false);
+            DataStore srcDataStore = volumeInfo.getDataStore();
+
+            int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+
+            CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
+
+            try {
+                handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+                if (srcVolumeDetached) {
+                    _volumeService.grantAccess(volumeInfo, hostVO, srcDataStore);
+                }
+
+                Map<String, String> srcDetails = getVolumeDetails(volumeInfo);
+
+                copyCommand.setOptions(srcDetails);
+
+                copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+
+                if (!copyCmdAnswer.getResult()) {
+                    errMsg = copyCmdAnswer.getDetails();
+
+                    LOGGER.warn(errMsg);
+
+                    throw new CloudRuntimeException(errMsg);
+                }
+
+                VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(templateInfo.getId());
+
+                vmTemplateVO.setHypervisorType(HypervisorType.KVM);
+
+                _vmTemplateDao.update(vmTemplateVO.getId(), vmTemplateVO);
+            }
+            catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
+                String msg = "Failed to create template from volume (Volume ID = " + volumeInfo.getId() + ") : ";
+
+                LOGGER.warn(msg, ex);
+
+                throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+            }
+            finally {
+                if (srcVolumeDetached) {
+                    try {
+                        _volumeService.revokeAccess(volumeInfo, hostVO, srcDataStore);
+                    }
+                    catch (Exception ex) {
+                        LOGGER.warn("Error revoking access to volume (Volume ID = " + volumeInfo.getId() + "): " + ex.getMessage(), ex);
+                    }
+                }
+
+                handleQualityOfServiceForVolumeMigration(volumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+
+                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
+                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
+                        errMsg = copyCmdAnswer.getDetails();
+                    }
+                    else {
+                        errMsg = "Unable to create template from volume";
+                    }
+                }
+
+                try {
+                    if (StringUtils.isEmpty(errMsg)) {
+                        volumeInfo.processEvent(Event.OperationSuccessed);
+                    }
+                    else {
+                        volumeInfo.processEvent(Event.OperationFailed);
+                    }
+                }
+                catch (Exception ex) {
+                    LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
+                }
+            }
+        }
+        catch (Exception ex) {
+            errMsg = ex.getMessage();
+
+            throw new CloudRuntimeException(errMsg);
+        }
+        finally {
+            if (copyCmdAnswer == null) {
+                copyCmdAnswer = new CopyCmdAnswer(errMsg);
+            }
+
+            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo) {
+        long storagePoolId = volumeInfo.getPoolId();
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
+
+        if (!storagePoolVO.isManaged()) {
+            return null;
+        }
+
+        Map<String, String> volumeDetails = new HashMap<>();
+
+        VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId());
+
+        volumeDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress());
+        volumeDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
+        volumeDetails.put(DiskTO.IQN, volumeVO.get_iScsiName());
+
+        volumeDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeVO.getSize()));
+        volumeDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getVolumeProperty(volumeInfo.getId(), DiskTO.SCSI_NAA_DEVICE_ID));
+
+        ChapInfo chapInfo = _volumeService.getChapInfo(volumeInfo, volumeInfo.getDataStore());
+
+        if (chapInfo != null) {
+            volumeDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+            volumeDetails.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+            volumeDetails.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+            volumeDetails.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
+        }
+
+        return volumeDetails;
+    }
+
+    private Map<String, String> getSnapshotDetails(SnapshotInfo snapshotInfo) {
+        Map<String, String> snapshotDetails = new HashMap<>();
+
+        long storagePoolId = snapshotInfo.getDataStore().getId();
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
+
+        snapshotDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress());
+        snapshotDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
+
+        long snapshotId = snapshotInfo.getId();
+
+        snapshotDetails.put(DiskTO.IQN, getSnapshotProperty(snapshotId, DiskTO.IQN));
+        snapshotDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(snapshotInfo.getSize()));
+        snapshotDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getSnapshotProperty(snapshotId, DiskTO.SCSI_NAA_DEVICE_ID));
+
+        snapshotDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_USERNAME));
+        snapshotDetails.put(DiskTO.CHAP_INITIATOR_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_SECRET));
+        snapshotDetails.put(DiskTO.CHAP_TARGET_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_USERNAME));
+        snapshotDetails.put(DiskTO.CHAP_TARGET_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_SECRET));
+
+        return snapshotDetails;
+    }
+
+    private HostVO getHost(SnapshotInfo snapshotInfo) {
+        HypervisorType hypervisorType = snapshotInfo.getHypervisorType();
+
+        if (HypervisorType.XenServer.equals(hypervisorType)) {
+            HostVO hostVO = getHost(snapshotInfo.getDataCenterId(), hypervisorType, true);
+
+            if (hostVO == null) {
+                hostVO = getHost(snapshotInfo.getDataCenterId(), hypervisorType, false);
+
+                if (hostVO == null) {
+                    throw new CloudRuntimeException("Unable to locate an applicable host in data center with ID = " + snapshotInfo.getDataCenterId());
+                }
+            }
+
+            return hostVO;
+        }
+
+        if (HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
+            return getHost(snapshotInfo.getDataCenterId(), hypervisorType, false);
+        }
+
+        throw new CloudRuntimeException("Unsupported hypervisor type");
+    }
+
+    private HostVO getHostInCluster(long clusterId) {
+        List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
+
+        if (hosts != null && hosts.size() > 0) {
+            Collections.shuffle(hosts, RANDOM);
+
+            for (HostVO host : hosts) {
+                if (ResourceState.Enabled.equals(host.getResourceState())) {
+                    return host;
+                }
+            }
+        }
+
+        throw new CloudRuntimeException("Unable to locate a host");
+    }
+
+    private HostVO getHost(Long zoneId, HypervisorType hypervisorType, boolean computeClusterMustSupportResign) {
+        Preconditions.checkArgument(zoneId != null, "Zone ID cannot be null.");
+        Preconditions.checkArgument(hypervisorType != null, "Hypervisor type cannot be null.");
+
+        List<HostVO> hosts = _hostDao.listByDataCenterIdAndHypervisorType(zoneId, hypervisorType);
+
+        if (hosts == null) {
+            return null;
+        }
+
+        List<Long> clustersToSkip = new ArrayList<>();
+
+        Collections.shuffle(hosts, RANDOM);
+
+        for (HostVO host : hosts) {
+            if (!ResourceState.Enabled.equals(host.getResourceState())) {
+                continue;
+            }
+
+            if (computeClusterMustSupportResign) {
+                long clusterId = host.getClusterId();
+
+                if (clustersToSkip.contains(clusterId)) {
+                    continue;
+                }
+
+                if (clusterDao.getSupportsResigning(clusterId)) {
+                    return host;
+                }
+                else {
+                    clustersToSkip.add(clusterId);
+                }
+            }
+            else {
+                return host;
+            }
+        }
+
+        return null;
+    }
+
+    private Map<String, String> getDetails(DataObject dataObj) {
+        if (dataObj instanceof VolumeInfo) {
+            return getVolumeDetails((VolumeInfo)dataObj);
+        }
+        else if (dataObj instanceof SnapshotInfo) {
+            return getSnapshotDetails((SnapshotInfo)dataObj);
+        }
+
+        throw new CloudRuntimeException("'dataObj' must be of type 'VolumeInfo' or 'SnapshotInfo'.");
+    }
+
+    private boolean isForVMware(DataObject dataObj) {
+        if (dataObj instanceof VolumeInfo) {
+            return ImageFormat.OVA.equals(((VolumeInfo)dataObj).getFormat());
+        }
+
+        if (dataObj instanceof SnapshotInfo) {
+            return ImageFormat.OVA.equals(((SnapshotInfo)dataObj).getBaseVolume().getFormat());
+        }
+
+        return dataObj instanceof TemplateInfo && HypervisorType.VMware.equals(((TemplateInfo)dataObj).getHypervisorType());
+    }
+
+    private CopyCmdAnswer performResignature(DataObject dataObj, HostVO hostVO, Map<String, String> extraDetails) {
+        return performResignature(dataObj, hostVO, extraDetails, false);
+    }
+
+    private CopyCmdAnswer performResignature(DataObject dataObj, HostVO hostVO, Map<String, String> extraDetails, boolean keepGrantedAccess) {
+        long storagePoolId = dataObj.getDataStore().getId();
+        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        Map<String, String> details = getDetails(dataObj);
+
+        if (extraDetails != null) {
+            details.putAll(extraDetails);
+        }
+
+        ResignatureCommand command = new ResignatureCommand(details);
+
+        ResignatureAnswer answer;
+
+        GlobalLock lock = GlobalLock.getInternLock(dataStore.getUuid());
+
+        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB (in performResignature) on the following string: " + dataStore.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            _volumeService.grantAccess(dataObj, hostVO, dataStore);
+
+            answer = (ResignatureAnswer)agentManager.send(hostVO.getId(), command);
+        }
+        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
+            keepGrantedAccess = false;
+
+            String msg = "Failed to resign the DataObject with the following ID: " + dataObj.getId();
+
+            LOGGER.warn(msg, ex);
+
+            throw new CloudRuntimeException(msg + ex.getMessage());
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+
+            if (!keepGrantedAccess) {
+                _volumeService.revokeAccess(dataObj, hostVO, dataStore);
+            }
+        }
+
+        if (answer == null || !answer.getResult()) {
+            final String errMsg;
+
+            if (answer != null && answer.getDetails() != null && !answer.getDetails().isEmpty()) {
+                errMsg = answer.getDetails();
+            }
+            else {
+                errMsg = "Unable to perform resignature operation in 'StorageSystemDataMotionStrategy.performResignature'";
+            }
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        VolumeObjectTO newVolume = new VolumeObjectTO();
+
+        newVolume.setSize(answer.getSize());
+        newVolume.setPath(answer.getPath());
+        newVolume.setFormat(answer.getFormat());
+
+        return new CopyCmdAnswer(newVolume);
+    }
+
+    private DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) {
+        DataObject leafData = null;
+        DataStore store = cacheMgr.getCacheStorage(snapshot, scope);
+
+        while (snapshot != null) {
+            DataObject cacheData = cacheMgr.createCacheObject(snapshot, store);
+
+            if (leafData == null) {
+                leafData = cacheData;
+            }
+
+            snapshot = snapshot.getParent();
+        }
+
+        return leafData;
+    }
+
+    private String migrateVolumeForKVM(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO, String errMsg) {
+        boolean srcVolumeDetached = srcVolumeInfo.getAttachedVM() == null;
+
+        try {
+            Map<String, String> srcDetails = getVolumeDetails(srcVolumeInfo);
+            Map<String, String> destDetails = getVolumeDetails(destVolumeInfo);
+
+            MigrateVolumeCommand migrateVolumeCommand = new MigrateVolumeCommand(srcVolumeInfo.getTO(), destVolumeInfo.getTO(),
+                    srcDetails, destDetails, StorageManager.KvmStorageOfflineMigrationWait.value());
+
+            if (srcVolumeDetached) {
+                _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
+            }
+
+            handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+            _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+
+            MigrateVolumeAnswer migrateVolumeAnswer = (MigrateVolumeAnswer)agentManager.send(hostVO.getId(), migrateVolumeCommand);
+
+            if (migrateVolumeAnswer == null || !migrateVolumeAnswer.getResult()) {
+                if (migrateVolumeAnswer != null && !StringUtils.isEmpty(migrateVolumeAnswer.getDetails())) {
+                    throw new CloudRuntimeException(migrateVolumeAnswer.getDetails());
+                }
+                else {
+                    throw new CloudRuntimeException(errMsg);
+                }
+            }
+
+            if (srcVolumeDetached) {
+                _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+            }
+
+            try {
+                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
+            }
+            catch (Exception e) {
+                // This volume should be deleted soon, so just log a warning here.
+                LOGGER.warn(e.getMessage(), e);
+            }
+
+            return migrateVolumeAnswer.getVolumePath();
+        }
+        catch (Exception ex) {
+            try {
+                _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
+            }
+            catch (Exception e) {
+                // This volume should be deleted soon, so just log a warning here.
+                LOGGER.warn(e.getMessage(), e);
+            }
+
+            if (srcVolumeDetached) {
+                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
+            }
+
+            String msg = "Failed to perform volume migration : ";
+
+            LOGGER.warn(msg, ex);
+
+            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+        }
+        finally {
+            handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+        }
+    }
+
+    private String copyManagedVolumeToSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO, String errMsg) {
+        boolean srcVolumeDetached = srcVolumeInfo.getAttachedVM() == null;
+
+        try {
+            StoragePoolVO storagePoolVO = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
+            Map<String, String> srcDetails = getVolumeDetails(srcVolumeInfo);
+
+            CopyVolumeCommand copyVolumeCommand = new CopyVolumeCommand(srcVolumeInfo.getId(), destVolumeInfo.getPath(), storagePoolVO,
+                    destVolumeInfo.getDataStore().getUri(), true, StorageManager.KvmStorageOfflineMigrationWait.value(), true);
+
+            copyVolumeCommand.setSrcData(srcVolumeInfo.getTO());
+            copyVolumeCommand.setSrcDetails(srcDetails);
+
+            handleQualityOfServiceForVolumeMigration(srcVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
+
+            if (srcVolumeDetached) {
+                _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
+            }
+
+            CopyVolumeAnswer copyVolumeAnswer = (CopyVolumeAnswer)agentManager.send(hostVO.getId(), copyVolumeCommand);
+
+            if (copyVolumeAnswer == null || !copyVolumeAnswer.getResult()) {
+                if (copyVolumeAnswer != null && !StringUtils.isEmpty(copyVolumeAnswer.getDetails())) {
+                    throw new CloudRuntimeException(copyVolumeAnswer.getDetails());
+                }
+                else {
+                    throw new CloudRuntimeException(errMsg);
+                }
+            }
+
+            return copyVolumeAnswer.getVolumePath();
+        }
+        catch (Exception ex) {
+            String msg = "Failed to perform volume copy to secondary storage : ";
+
+            LOGGER.warn(msg, ex);
+
+            throw new CloudRuntimeException(msg + ex.getMessage());
+        }
+        finally {
+            if (srcVolumeDetached) {
+                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
+            }
+
+            handleQualityOfServiceForVolumeMigration(srcVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.NO_MIGRATION);
+        }
+    }
+
+    private void setCertainVolumeValuesNull(long volumeId) {
+        VolumeVO volumeVO = _volumeDao.findById(volumeId);
+
+        volumeVO.set_iScsiName(null);
+        volumeVO.setMinIops(null);
+        volumeVO.setMaxIops(null);
+        volumeVO.setHypervisorSnapshotReserve(null);
+
+        _volumeDao.update(volumeId, volumeVO);
+    }
+
+    private void updateVolumePath(long volumeId, String path) {
+        VolumeVO volumeVO = _volumeDao.findById(volumeId);
+
+        volumeVO.setPath(path);
+
+        _volumeDao.update(volumeId, volumeVO);
+    }
+
+    /**
+     * Copies data from secondary storage to a primary volume
+     * @param volumeInfo The primary volume
+     * @param snapshotInfo  destination of the copy
+     * @param hostVO the host used to copy the data
+     * @return result of the copy
+     */
+    private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) {
+        Snapshot.LocationType locationType = snapshotInfo.getLocationType();
+
+        int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+
+        DataObject srcData = snapshotInfo;
+        CopyCmdAnswer copyCmdAnswer = null;
+        DataObject cacheData = null;
+
+        boolean needCacheStorage = needCacheStorage(snapshotInfo, volumeInfo);
+
+        if (needCacheStorage) {
+            cacheData = cacheSnapshotChain(snapshotInfo, new ZoneScope(volumeInfo.getDataCenterId()));
+            srcData = cacheData;
+        }
+
+        CopyCommand copyCommand = new CopyCommand(srcData.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
+
+        try {
+            if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
+                _volumeService.grantAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
+
+                Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
+
+                copyCommand.setOptions(srcDetails);
+            }
+
+            _volumeService.grantAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
+
+            Map<String, String> destDetails = getVolumeDetails(volumeInfo);
+
+            copyCommand.setOptions2(destDetails);
+
+            copyCmdAnswer = (CopyCmdAnswer)agentManager.send(hostVO.getId(), copyCommand);
+        }
+        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
+            String msg = "Failed to perform VDI copy : ";
+
+            LOGGER.warn(msg, ex);
+
+            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
+        }
+        finally {
+            if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
+                _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
+            }
+
+            _volumeService.revokeAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
+
+            if (needCacheStorage && copyCmdAnswer != null && copyCmdAnswer.getResult()) {
+                cacheMgr.deleteCacheObject(cacheData);
+            }
+        }
+
+        return copyCmdAnswer;
+    }
+}
diff --git a/engine/storage/datamotion/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml b/engine/storage/datamotion/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml
similarity index 100%
rename from engine/storage/datamotion/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml
rename to engine/storage/datamotion/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-datamotion-core-context.xml
diff --git a/engine/storage/datamotion/src/main/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml b/engine/storage/datamotion/src/main/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml
new file mode 100644
index 0000000..5292419
--- /dev/null
+++ b/engine/storage/datamotion/src/main/resources/META-INF/cloudstack/storage/spring-engine-storage-datamotion-storage-context.xml
@@ -0,0 +1,39 @@
+<!--
+  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"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context.xsd"
+                      >
+    <bean id="ancientDataMotionStrategy"
+        class="org.apache.cloudstack.storage.motion.AncientDataMotionStrategy" />
+    <bean id="xenserverStorageMotionStrategy"
+        class="org.apache.cloudstack.storage.motion.XenServerStorageMotionStrategy" />
+    <bean id="hypervStorageMotionStrategy"
+        class="org.apache.cloudstack.storage.motion.HypervStorageMotionStrategy" />
+    <bean id="storageSystemDataMotionStrategy"
+        class="org.apache.cloudstack.storage.motion.StorageSystemDataMotionStrategy" />
+    <bean id="kvmNonManagedStorageSystemDataMotionStrategy"
+        class="org.apache.cloudstack.storage.motion.KvmNonManagedStorageDataMotionStrategy" />
+</beans>
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
deleted file mode 100644
index 9471fad..0000000
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.motion;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.MigrateVolumeAnswer;
-import com.cloud.agent.api.storage.MigrateVolumeCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.configuration.Config;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachineManager;
-
-@Component
-public class AncientDataMotionStrategy implements DataMotionStrategy {
-    private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class);
-    @Inject
-    EndPointSelector selector;
-    @Inject
-    ConfigurationDao configDao;
-    @Inject
-    VolumeDao volDao;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    StorageCacheManager cacheMgr;
-
-    @Override
-    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
-        return StrategyPriority.DEFAULT;
-    }
-
-    @Override
-    public StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
-        return StrategyPriority.CANT_HANDLE;
-    }
-
-    protected boolean needCacheStorage(DataObject srcData, DataObject destData) {
-        DataTO srcTO = srcData.getTO();
-        DataStoreTO srcStoreTO = srcTO.getDataStore();
-
-        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) {
-            return false;
-        }
-        DataTO destTO = destData.getTO();
-        DataStoreTO destStoreTO = destTO.getDataStore();
-
-        if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) {
-            return false;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("needCacheStorage true, dest at " + destTO.getPath() + " dest role " + destStoreTO.getRole().toString() + srcTO.getPath() + " src role " +
-                srcStoreTO.getRole().toString());
-        }
-        return true;
-    }
-
-    private Scope getZoneScope(Scope destScope) {
-        ZoneScope zoneScope = null;
-        if (destScope instanceof ClusterScope) {
-            ClusterScope clusterScope = (ClusterScope)destScope;
-            zoneScope = new ZoneScope(clusterScope.getZoneId());
-        } else if (destScope instanceof HostScope) {
-            HostScope hostScope = (HostScope)destScope;
-            zoneScope = new ZoneScope(hostScope.getZoneId());
-        } else {
-            zoneScope = (ZoneScope)destScope;
-        }
-        return zoneScope;
-    }
-
-    private Scope pickCacheScopeForCopy(DataObject srcData, DataObject destData) {
-        Scope srcScope = srcData.getDataStore().getScope();
-        Scope destScope = destData.getDataStore().getScope();
-
-        Scope selectedScope = null;
-        if (srcScope.getScopeId() != null) {
-            selectedScope = getZoneScope(srcScope);
-        } else if (destScope.getScopeId() != null) {
-            selectedScope = getZoneScope(destScope);
-        } else {
-            s_logger.warn("Cannot find a zone-wide scope for movement that needs a cache storage");
-        }
-        return selectedScope;
-    }
-
-    protected Answer copyObject(DataObject srcData, DataObject destData, Host destHost) {
-        String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-        int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-        Answer answer = null;
-        DataObject cacheData = null;
-        DataObject srcForCopy = srcData;
-        try {
-            if (needCacheStorage(srcData, destData)) {
-                Scope destScope = pickCacheScopeForCopy(srcData, destData);
-                srcForCopy = cacheData = cacheMgr.createCacheObject(srcData, destScope);
-            }
-
-            CopyCommand cmd = new CopyCommand(srcForCopy.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
-            EndPoint ep = destHost != null ? RemoteHostEndPoint.getHypervisorHostEndPoint(destHost) : selector.select(srcForCopy, destData);
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-
-            if (cacheData != null) {
-                final Long cacheId = cacheData.getId();
-                final String cacheType = cacheData.getType().toString();
-                final String cacheUuid = cacheData.getUuid().toString();
-
-                if (srcData.getType() == DataObjectType.VOLUME &&
-                    (destData.getType() == DataObjectType.VOLUME ||
-                     destData.getType() == DataObjectType.TEMPLATE)) {
-                    // volume transfer from primary to secondary. Volume transfer between primary pools are already handled by copyVolumeBetweenPools
-                    // Delete cache in order to certainly transfer a latest image.
-                    s_logger.debug("Delete " + cacheType + " cache(id: " + cacheId +
-                                   ", uuid: " + cacheUuid + ")");
-                    cacheMgr.deleteCacheObject(srcForCopy);
-                } else {
-                    // for template, we want to leave it on cache for performance reason
-                    if ((answer == null || !answer.getResult()) && srcForCopy.getRefCount() < 2) {
-                        // cache object created by this copy, not already there
-                        s_logger.warn("Copy may not be handled correctly by agent(id: " + (ep != null ? ep.getId() : "\"unspecified\"") + ")." +
-                                      " Delete " + cacheType + " cache(id: " + cacheId +
-                                      ", uuid: " + cacheUuid + ")");
-                        cacheMgr.deleteCacheObject(srcForCopy);
-                    } else {
-                        s_logger.debug("Decrease reference count of " + cacheType +
-                                       " cache(id: " + cacheId + ", uuid: " + cacheUuid + ")");
-                        cacheMgr.releaseCacheObject(srcForCopy);
-                    }
-                }
-            }
-            return answer;
-        } catch (Exception e) {
-            s_logger.debug("copy object failed: ", e);
-            if (cacheData != null) {
-                cacheMgr.deleteCacheObject(cacheData);
-            }
-            throw new CloudRuntimeException(e.toString());
-        }
-    }
-
-    /**
-     * Adds {@code 'vmware.create.full.clone'} value for a given primary storage, whose HV is VMware, on datastore's {@code fullCloneFlag} field
-     * @param dataTO Dest data store TO
-     * @return dataTO including fullCloneFlag, if provided
-     */
-    protected DataTO addFullCloneFlagOnVMwareDest(DataTO dataTO) {
-        if (dataTO != null && dataTO.getHypervisorType().equals(Hypervisor.HypervisorType.VMware)){
-            DataStoreTO dataStoreTO = dataTO.getDataStore();
-            if (dataStoreTO != null && dataStoreTO instanceof PrimaryDataStoreTO){
-                PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO) dataStoreTO;
-                Boolean value = CapacityManager.VmwareCreateCloneFull.valueIn(primaryDataStoreTO.getId());
-                primaryDataStoreTO.setFullCloneFlag(value);
-            }
-        }
-        return dataTO;
-    }
-
-    protected Answer copyObject(DataObject srcData, DataObject destData) {
-        return copyObject(srcData, destData, null);
-    }
-
-    protected DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) {
-        DataObject leafData = null;
-        DataStore store = cacheMgr.getCacheStorage(snapshot, scope);
-        while (snapshot != null) {
-            DataObject cacheData = cacheMgr.createCacheObject(snapshot, store);
-            if (leafData == null) {
-                leafData = cacheData;
-            }
-            snapshot = snapshot.getParent();
-        }
-        return leafData;
-    }
-
-
-    protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) {
-        while (snapshot != null) {
-            cacheMgr.deleteCacheObject(snapshot);
-            snapshot = snapshot.getParent();
-        }
-    }
-
-    protected void releaseSnapshotCacheChain(SnapshotInfo snapshot) {
-        while (snapshot != null) {
-            cacheMgr.releaseCacheObject(snapshot);
-            snapshot = snapshot.getParent();
-        }
-    }
-
-    protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) {
-        SnapshotInfo snapshot = (SnapshotInfo)snapObj;
-        StoragePool pool = (StoragePool)volObj.getDataStore();
-
-        String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool;
-        DataStore store = snapObj.getDataStore();
-        DataStoreTO storTO = store.getTO();
-        DataObject srcData = snapObj;
-        try {
-            if (!(storTO instanceof NfsTO)) {
-                // cache snapshot to zone-wide staging store for the volume to be created
-                srcData = cacheSnapshotChain(snapshot, new ZoneScope(pool.getDataCenterId()));
-            }
-
-            String value = configDao.getValue(Config.CreateVolumeFromSnapshotWait.toString());
-            int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreateVolumeFromSnapshotWait.getDefaultValue()));
-
-            EndPoint ep = null;
-            if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
-                ep = selector.select(volObj);
-            } else {
-                ep = selector.select(srcData, volObj);
-            }
-
-            CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(volObj.getTO()), _createVolumeFromSnapshotWait, VirtualMachineManager.ExecuteInSequence.value());
-            Answer answer = null;
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-
-            return answer;
-        } catch (Exception e) {
-            s_logger.error(basicErrMsg, e);
-            throw new CloudRuntimeException(basicErrMsg);
-        } finally {
-            if (!(storTO instanceof NfsTO)) {
-                // still keep snapshot on cache which may be migrated from previous secondary storage
-                releaseSnapshotCacheChain((SnapshotInfo)srcData);
-            }
-        }
-    }
-
-    protected Answer cloneVolume(DataObject template, DataObject volume) {
-        CopyCommand cmd = new CopyCommand(template.getTO(), addFullCloneFlagOnVMwareDest(volume.getTO()), 0, VirtualMachineManager.ExecuteInSequence.value());
-        try {
-            EndPoint ep = selector.select(volume.getDataStore());
-            Answer answer = null;
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-            return answer;
-        } catch (Exception e) {
-            s_logger.debug("Failed to send to storage pool", e);
-            throw new CloudRuntimeException("Failed to send to storage pool", e);
-        }
-    }
-
-    protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) {
-        String value = configDao.getValue(Config.CopyVolumeWait.key());
-        int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
-
-        Scope destScope = getZoneScope(destData.getDataStore().getScope());
-        DataStore cacheStore = cacheMgr.getCacheStorage(destScope);
-        if (cacheStore == null) {
-            // need to find a nfs or cifs image store, assuming that can't copy volume
-            // directly to s3
-            ImageStoreEntity imageStore = (ImageStoreEntity)dataStoreMgr.getImageStore(destScope.getScopeId());
-            if (!imageStore.getProtocol().equalsIgnoreCase("nfs") && !imageStore.getProtocol().equalsIgnoreCase("cifs")) {
-                s_logger.debug("can't find a nfs (or cifs) image store to satisfy the need for a staging store");
-                return null;
-            }
-
-            DataObject objOnImageStore = imageStore.create(srcData);
-            objOnImageStore.processEvent(Event.CreateOnlyRequested);
-
-            Answer answer = copyObject(srcData, objOnImageStore);
-            if (answer == null || !answer.getResult()) {
-                if (answer != null) {
-                    s_logger.debug("copy to image store failed: " + answer.getDetails());
-                }
-                objOnImageStore.processEvent(Event.OperationFailed);
-                imageStore.delete(objOnImageStore);
-                return answer;
-            }
-
-            objOnImageStore.processEvent(Event.OperationSuccessed, answer);
-
-            objOnImageStore.processEvent(Event.CopyingRequested);
-
-            CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
-            EndPoint ep = selector.select(objOnImageStore, destData);
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-
-            if (answer == null || !answer.getResult()) {
-                if (answer != null) {
-                    s_logger.debug("copy to primary store failed: " + answer.getDetails());
-                }
-                objOnImageStore.processEvent(Event.OperationFailed);
-                imageStore.delete(objOnImageStore);
-                return answer;
-            }
-
-            objOnImageStore.processEvent(Event.OperationSuccessed);
-            imageStore.delete(objOnImageStore);
-            return answer;
-        } else {
-            DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope);
-            CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
-            EndPoint ep = selector.select(cacheData, destData);
-            Answer answer = null;
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-            // delete volume on cache store
-            if (cacheData != null) {
-                cacheMgr.deleteCacheObject(cacheData);
-            }
-            return answer;
-        }
-
-    }
-
-    protected Answer migrateVolumeToPool(DataObject srcData, DataObject destData) {
-        String value = configDao.getValue(Config.MigrateWait.key());
-        int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue()));
-
-        VolumeInfo volume = (VolumeInfo)srcData;
-        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
-        MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), volume.getVolumeType(), waitInterval);
-        EndPoint ep = selector.select(srcData, StorageAction.MIGRATEVOLUME);
-        Answer answer = null;
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            answer = new Answer(command, false, errMsg);
-        } else {
-            answer = ep.sendMessage(command);
-        }
-
-        if (answer == null || !answer.getResult()) {
-            throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool);
-        } else {
-            // Update the volume details after migration.
-            VolumeVO volumeVo = volDao.findById(volume.getId());
-            Long oldPoolId = volume.getPoolId();
-            volumeVo.setPath(((MigrateVolumeAnswer)answer).getVolumePath());
-            String chainInfo = ((MigrateVolumeAnswer)answer).getVolumeChainInfo();
-            if (chainInfo != null) {
-                volumeVo.setChainInfo(chainInfo);
-            }
-            volumeVo.setPodId(destPool.getPodId());
-            volumeVo.setPoolId(destPool.getId());
-            volumeVo.setLastPoolId(oldPoolId);
-            // For SMB, pool credentials are also stored in the uri query string.  We trim the query string
-            // part  here to make sure the credentials do not get stored in the db unencrypted.
-            String folder = destPool.getPath();
-            if (destPool.getPoolType() == StoragePoolType.SMB && folder != null && folder.contains("?")) {
-                folder = folder.substring(0, folder.indexOf("?"));
-            }
-            volumeVo.setFolder(folder);
-            volDao.update(volume.getId(), volumeVo);
-        }
-
-        return answer;
-    }
-
-    // Note: destHost is currently only used if the copyObject method is invoked
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        Answer answer = null;
-        String errMsg = null;
-        try {
-            s_logger.debug("copyAsync inspecting src type " + srcData.getType().toString() + " copyAsync inspecting dest type " + destData.getType().toString());
-            if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) {
-                answer = copyVolumeFromSnapshot(srcData, destData);
-            } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) {
-                answer = createTemplateFromSnapshot(srcData, destData);
-            } else if (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
-                answer = cloneVolume(srcData, destData);
-            } else if (destData.getType() == DataObjectType.VOLUME && srcData.getType() == DataObjectType.VOLUME &&
-                srcData.getDataStore().getRole() == DataStoreRole.Primary && destData.getDataStore().getRole() == DataStoreRole.Primary) {
-                if (srcData.getId() == destData.getId()) {
-                    // The volume has to be migrated across storage pools.
-                    answer = migrateVolumeToPool(srcData, destData);
-                } else {
-                    answer = copyVolumeBetweenPools(srcData, destData);
-                }
-            } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) {
-                answer = copySnapshot(srcData, destData);
-            } else {
-                answer = copyObject(srcData, destData, destHost);
-            }
-
-            if (answer != null && !answer.getResult()) {
-                errMsg = answer.getDetails();
-            }
-        } catch (Exception e) {
-            s_logger.debug("copy failed", e);
-            errMsg = e.toString();
-        }
-        CopyCommandResult result = new CopyCommandResult(null, answer);
-        result.setResult(errMsg);
-        callback.complete(result);
-    }
-
-    @DB
-    protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) {
-
-        String value = configDao.getValue(Config.CreatePrivateTemplateFromSnapshotWait.toString());
-        int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreatePrivateTemplateFromSnapshotWait.getDefaultValue()));
-
-        boolean needCache = false;
-        if (needCacheStorage(srcData, destData)) {
-            needCache = true;
-            SnapshotInfo snapshot = (SnapshotInfo) srcData;
-            srcData = cacheSnapshotChain(snapshot, snapshot.getDataStore().getScope());
-        }
-
-        EndPoint ep = null;
-        if (srcData.getDataStore().getRole() == DataStoreRole.Primary) {
-            ep = selector.select(destData);
-        } else {
-            ep = selector.select(srcData, destData);
-        }
-
-        CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _createprivatetemplatefromsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
-        Answer answer = null;
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            answer = new Answer(cmd, false, errMsg);
-        } else {
-            answer = ep.sendMessage(cmd);
-        }
-
-        // clean up snapshot copied to staging
-        if (needCache && srcData != null) {
-            cacheMgr.releaseCacheObject(srcData);  // reduce ref count, but keep it there on cache which is converted from previous secondary storage
-        }
-        return answer;
-    }
-
-    protected Answer copySnapshot(DataObject srcData, DataObject destData) {
-        String value = configDao.getValue(Config.BackupSnapshotWait.toString());
-        int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
-
-        DataObject cacheData = null;
-        SnapshotInfo snapshotInfo = (SnapshotInfo)srcData;
-        Boolean snapshotFullBackup = snapshotInfo.getFullBackup();
-        Boolean fullSnapshot = true;
-        if (snapshotFullBackup != null) {
-            fullSnapshot = snapshotFullBackup;
-        }
-        Map<String, String> options = new HashMap<String, String>();
-        options.put("fullSnapshot", fullSnapshot.toString());
-        Answer answer = null;
-        try {
-            if (needCacheStorage(srcData, destData)) {
-                Scope selectedScope = pickCacheScopeForCopy(srcData, destData);
-                cacheData = cacheMgr.getCacheObject(srcData, selectedScope);
-
-                CopyCommand cmd = new CopyCommand(srcData.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
-                cmd.setCacheTO(cacheData.getTO());
-                cmd.setOptions(options);
-                EndPoint ep = selector.select(srcData, destData);
-                if (ep == null) {
-                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                    s_logger.error(errMsg);
-                    answer = new Answer(cmd, false, errMsg);
-                } else {
-                    answer = ep.sendMessage(cmd);
-                }
-            } else {
-                addFullCloneFlagOnVMwareDest(destData.getTO());
-                CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait, VirtualMachineManager.ExecuteInSequence.value());
-                cmd.setOptions(options);
-                EndPoint ep = selector.select(srcData, destData, StorageAction.BACKUPSNAPSHOT);
-                if (ep == null) {
-                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                    s_logger.error(errMsg);
-                    answer = new Answer(cmd, false, errMsg);
-                } else {
-                    answer = ep.sendMessage(cmd);
-                }
-
-            }
-            // clean up cache entry
-            if (cacheData != null) {
-                cacheMgr.deleteCacheObject(cacheData);
-            }
-            return answer;
-        } catch (Exception e) {
-            s_logger.debug("copy snasphot failed: " + e.toString());
-            if (cacheData != null) {
-                cacheMgr.deleteCacheObject(cacheData);
-            }
-            throw new CloudRuntimeException(e.toString());
-        }
-
-    }
-
-    @Override
-    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        CopyCommandResult result = new CopyCommandResult(null, null);
-        result.setResult("Unsupported operation requested for copying data.");
-        callback.complete(result);
-    }
-}
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
deleted file mode 100644
index eed1e08..0000000
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.motion;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.host.Host;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class DataMotionServiceImpl implements DataMotionService {
-    @Inject
-    StorageStrategyFactory storageStrategyFactory;
-
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        if (srcData.getDataStore() == null || destData.getDataStore() == null) {
-            throw new CloudRuntimeException("can't find data store");
-        }
-
-        if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) {
-            srcData.getDataStore().getDriver().copyAsync(srcData, destData, callback);
-            return;
-        } else if (destData.getDataStore().getDriver().canCopy(srcData, destData)) {
-            destData.getDataStore().getDriver().copyAsync(srcData, destData, callback);
-            return;
-        }
-
-        DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(srcData, destData);
-        if (strategy == null) {
-            throw new CloudRuntimeException("Can't find strategy to move data. " + "Source: " + srcData.getType().name() + " '" + srcData.getUuid() + ", Destination: " +
-                destData.getType().name() + " '" + destData.getUuid() + "'");
-        }
-
-        strategy.copyAsync(srcData, destData, destHost, callback);
-    }
-
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        copyAsync(srcData, destData, null, callback);
-    }
-
-    @Override
-    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-
-        DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(volumeMap, srcHost, destHost);
-        if (strategy == null) {
-            List<String> volumeIds = new LinkedList<String>();
-            for (final VolumeInfo volumeInfo : volumeMap.keySet()) {
-                volumeIds.add(volumeInfo.getUuid());
-            }
-
-            throw new CloudRuntimeException("Can't find strategy to move data. " + "Source Host: " + srcHost.getName() + ", Destination Host: " + destHost.getName() +
-                ", Volume UUIDs: " + StringUtils.join(volumeIds, ","));
-        }
-
-        strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback);
-    }
-}
diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
deleted file mode 100644
index fc445cf..0000000
--- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++ /dev/null
@@ -1,2296 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.motion;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.MigrateAnswer;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.agent.api.ModifyTargetsAnswer;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.storage.MigrateVolumeAnswer;
-import com.cloud.agent.api.storage.MigrateVolumeCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.configuration.Config;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotDetailsDao;
-import com.cloud.storage.dao.SnapshotDetailsVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-import com.google.common.base.Preconditions;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.ResignatureAnswer;
-import org.apache.cloudstack.storage.command.ResignatureCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.NumberUtils;
-import org.apache.log4j.Logger;
-
-import org.springframework.stereotype.Component;
-
-import javax.inject.Inject;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-@Component
-public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
-    private static final Logger LOGGER = Logger.getLogger(StorageSystemDataMotionStrategy.class);
-    private static final Random RANDOM = new Random(System.nanoTime());
-    private static final int LOCK_TIME_IN_SECONDS = 300;
-    private static final String OPERATION_NOT_SUPPORTED = "This operation is not supported.";
-
-    @Inject private AgentManager _agentMgr;
-    @Inject private ConfigurationDao _configDao;
-    @Inject private DataStoreManager dataStoreMgr;
-    @Inject private DiskOfferingDao _diskOfferingDao;
-    @Inject private GuestOSCategoryDao _guestOsCategoryDao;
-    @Inject private GuestOSDao _guestOsDao;
-    @Inject private ClusterDao clusterDao;
-    @Inject private HostDao _hostDao;
-    @Inject private HostDetailsDao hostDetailsDao;
-    @Inject private PrimaryDataStoreDao _storagePoolDao;
-    @Inject private SnapshotDao _snapshotDao;
-    @Inject private SnapshotDataStoreDao _snapshotDataStoreDao;
-    @Inject private SnapshotDetailsDao _snapshotDetailsDao;
-    @Inject private VMInstanceDao _vmDao;
-    @Inject private VMTemplateDao _vmTemplateDao;
-    @Inject private VolumeDao _volumeDao;
-    @Inject private VolumeDataFactory _volumeDataFactory;
-    @Inject private VolumeDetailsDao volumeDetailsDao;
-    @Inject private VolumeService _volumeService;
-    @Inject private StorageCacheManager cacheMgr;
-    @Inject private EndPointSelector selector;
-
-    @Override
-    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
-        if (srcData instanceof SnapshotInfo) {
-            if (canHandle(srcData) || canHandle(destData)) {
-                return StrategyPriority.HIGHEST;
-            }
-        }
-
-        if (srcData instanceof TemplateInfo && destData instanceof VolumeInfo &&
-                (srcData.getDataStore().getId() == destData.getDataStore().getId()) &&
-                (canHandle(srcData) || canHandle(destData))) {
-            // Both source and dest are on the same storage, so just clone them.
-            return StrategyPriority.HIGHEST;
-        }
-
-        if (srcData instanceof VolumeInfo && destData instanceof VolumeInfo) {
-            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
-
-            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
-                return StrategyPriority.HIGHEST;
-            }
-
-            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
-
-            if (isVolumeOnManagedStorage(destVolumeInfo)) {
-                return StrategyPriority.HIGHEST;
-            }
-        }
-
-        if (srcData instanceof VolumeInfo && destData instanceof TemplateInfo) {
-            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
-
-            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
-                return StrategyPriority.HIGHEST;
-            }
-        }
-
-        return StrategyPriority.CANT_HANDLE;
-    }
-
-    private boolean isVolumeOnManagedStorage(VolumeInfo volumeInfo) {
-        DataStore dataStore = volumeInfo.getDataStore();
-
-        if (dataStore.getRole() == DataStoreRole.Primary) {
-            long storagePooldId = dataStore.getId();
-            StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePooldId);
-
-            return storagePoolVO.isManaged();
-        }
-
-        return false;
-    }
-
-    // canHandle returns true if the storage driver for the DataObject that's passed in can support certain features (what features we
-    // care about during a particular invocation of this method depend on what type of DataObject was passed in (ex. VolumeInfo versus SnapshotInfo)).
-    private boolean canHandle(DataObject dataObject) {
-        Preconditions.checkArgument(dataObject != null, "Passing 'null' to dataObject of canHandle(DataObject) is not supported.");
-
-        DataStore dataStore = dataObject.getDataStore();
-
-        if (dataStore.getRole() == DataStoreRole.Primary) {
-            Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
-
-            if (mapCapabilities == null) {
-                return false;
-            }
-
-            if (dataObject instanceof VolumeInfo || dataObject instanceof SnapshotInfo) {
-                String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
-                Boolean supportsStorageSystemSnapshots = Boolean.valueOf(value);
-
-                if (supportsStorageSystemSnapshots) {
-                    LOGGER.info("Using 'StorageSystemDataMotionStrategy' (dataObject is a volume or snapshot and the storage system supports snapshots)");
-
-                    return true;
-                }
-            } else if (dataObject instanceof TemplateInfo) {
-                // If the storage system can clone volumes, we can cache templates on it.
-                String value = mapCapabilities.get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString());
-                Boolean canCloneVolume = Boolean.valueOf(value);
-
-                if (canCloneVolume) {
-                    LOGGER.info("Using 'StorageSystemDataMotionStrategy' (dataObject is a template and the storage system can create a volume from a volume)");
-
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
-        if (HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
-            Set<VolumeInfo> volumeInfoSet = volumeMap.keySet();
-
-            for (VolumeInfo volumeInfo : volumeInfoSet) {
-                StoragePoolVO storagePoolVO = _storagePoolDao.findById(volumeInfo.getPoolId());
-
-                if (storagePoolVO.isManaged()) {
-                    return StrategyPriority.HIGHEST;
-                }
-            }
-
-            Collection<DataStore> dataStores = volumeMap.values();
-
-            for (DataStore dataStore : dataStores) {
-                StoragePoolVO storagePoolVO = _storagePoolDao.findById(dataStore.getId());
-
-                if (storagePoolVO.isManaged()) {
-                    return StrategyPriority.HIGHEST;
-                }
-            }
-        }
-
-        return StrategyPriority.CANT_HANDLE;
-    }
-
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        if (srcData instanceof SnapshotInfo) {
-            SnapshotInfo srcSnapshotInfo = (SnapshotInfo)srcData;
-
-            handleCopyAsyncForSnapshot(srcSnapshotInfo, destData, callback);
-        } else if (srcData instanceof TemplateInfo && destData instanceof VolumeInfo) {
-            TemplateInfo srcTemplateInfo = (TemplateInfo)srcData;
-            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
-
-            handleCopyAsyncForTemplateAndVolume(srcTemplateInfo, destVolumeInfo, callback);
-        } else if (srcData instanceof VolumeInfo && destData instanceof VolumeInfo) {
-            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
-            VolumeInfo destVolumeInfo = (VolumeInfo)destData;
-
-            handleCopyAsyncForVolumes(srcVolumeInfo, destVolumeInfo, callback);
-        } else if (srcData instanceof VolumeInfo && destData instanceof TemplateInfo &&
-                (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) {
-            VolumeInfo srcVolumeInfo = (VolumeInfo)srcData;
-            TemplateInfo destTemplateInfo = (TemplateInfo)destData;
-
-            handleCreateTemplateFromVolume(srcVolumeInfo, destTemplateInfo, callback);
-        }
-        else {
-            handleError(OPERATION_NOT_SUPPORTED, callback);
-        }
-    }
-
-    private void handleCopyAsyncForSnapshot(SnapshotInfo srcSnapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        verifyFormat(srcSnapshotInfo);
-
-        boolean canHandleSrc = canHandle(srcSnapshotInfo);
-
-        if (canHandleSrc && (destData instanceof TemplateInfo || destData instanceof SnapshotInfo) &&
-                (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) {
-            handleCopyDataToSecondaryStorage(srcSnapshotInfo, destData, callback);
-        } else if (destData instanceof VolumeInfo) {
-            handleCopyAsyncForSnapshotToVolume(srcSnapshotInfo, (VolumeInfo)destData, callback);
-        } else {
-            handleError(OPERATION_NOT_SUPPORTED, callback);
-        }
-    }
-
-    private void handleCopyAsyncForSnapshotToVolume(SnapshotInfo srcSnapshotInfo, VolumeInfo destVolumeInfo,
-                                                    AsyncCompletionCallback<CopyCommandResult> callback) {
-        boolean canHandleDest = canHandle(destVolumeInfo);
-
-        if (!canHandleDest) {
-            handleError(OPERATION_NOT_SUPPORTED, callback);
-        }
-
-        boolean canHandleSrc = canHandle(srcSnapshotInfo);
-
-        if (!canHandleSrc) {
-            handleCreateVolumeFromSnapshotOnSecondaryStorage(srcSnapshotInfo, destVolumeInfo, callback);
-        }
-
-        if (srcSnapshotInfo.getDataStore().getId() == destVolumeInfo.getDataStore().getId()) {
-            handleCreateVolumeFromSnapshotBothOnStorageSystem(srcSnapshotInfo, destVolumeInfo, callback);
-        } else {
-            String errMsg = "To perform this operation, the source and destination primary storages must be the same.";
-
-            handleError(errMsg, callback);
-        }
-    }
-
-    private void handleCopyAsyncForTemplateAndVolume(TemplateInfo srcTemplateInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
-        boolean canHandleSrc = canHandle(srcTemplateInfo);
-
-        if (!canHandleSrc) {
-            handleError(OPERATION_NOT_SUPPORTED, callback);
-        }
-
-        handleCreateVolumeFromTemplateBothOnStorageSystem(srcTemplateInfo, destVolumeInfo, callback);
-    }
-
-    private void handleCopyAsyncForVolumes(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
-        if (srcVolumeInfo.getState() == Volume.State.Migrating) {
-            if (isVolumeOnManagedStorage(srcVolumeInfo)) {
-                if (destVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || destVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) {
-                    handleVolumeCopyFromManagedStorageToSecondaryStorage(srcVolumeInfo, destVolumeInfo, callback);
-                } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
-                    handleVolumeMigrationFromManagedStorageToNonManagedStorage(srcVolumeInfo, destVolumeInfo, callback);
-                } else {
-                    String errMsg = "The source volume to migrate and the destination volume are both on managed storage. " +
-                            "Migration in this case is not yet supported.";
-
-                    handleError(errMsg, callback);
-                }
-            } else if (!isVolumeOnManagedStorage(destVolumeInfo)) {
-                String errMsg = "The 'StorageSystemDataMotionStrategy' does not support this migration use case.";
-
-                handleError(errMsg, callback);
-            } else {
-                handleVolumeMigrationFromNonManagedStorageToManagedStorage(srcVolumeInfo, destVolumeInfo, callback);
-            }
-        } else if (srcVolumeInfo.getState() == Volume.State.Uploaded &&
-                (srcVolumeInfo.getDataStore().getRole() == DataStoreRole.Image || srcVolumeInfo.getDataStore().getRole() == DataStoreRole.ImageCache) &&
-                destVolumeInfo.getDataStore().getRole() == DataStoreRole.Primary) {
-            ImageFormat imageFormat = destVolumeInfo.getFormat();
-
-            if (!ImageFormat.QCOW2.equals(imageFormat)) {
-                String errMsg = "The 'StorageSystemDataMotionStrategy' does not support this upload use case (non KVM).";
-
-                handleError(errMsg, callback);
-            }
-
-            handleCreateVolumeFromVolumeOnSecondaryStorage(srcVolumeInfo, destVolumeInfo, destVolumeInfo.getDataCenterId(), HypervisorType.KVM, callback);
-        } else {
-            handleError(OPERATION_NOT_SUPPORTED, callback);
-        }
-    }
-
-    private void handleError(String errMsg, AsyncCompletionCallback<CopyCommandResult> callback) {
-        LOGGER.warn(errMsg);
-
-        invokeCallback(errMsg, callback);
-
-        throw new UnsupportedOperationException(errMsg);
-    }
-
-    private void invokeCallback(String errMsg, AsyncCompletionCallback<CopyCommandResult> callback) {
-        CopyCmdAnswer copyCmdAnswer = new CopyCmdAnswer(errMsg);
-
-        CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-        result.setResult(errMsg);
-
-        callback.complete(result);
-    }
-
-    private void handleVolumeCopyFromManagedStorageToSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
-                                                                      AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        String volumePath = null;
-
-        try {
-            if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
-                throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " +
-                        "from managed storage to non-managed storage.");
-            }
-
-            HypervisorType hypervisorType = HypervisorType.KVM;
-            VirtualMachine vm = srcVolumeInfo.getAttachedVM();
-
-            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
-                throw new CloudRuntimeException("Currently, if a volume to copy from managed storage to secondary storage is attached to " +
-                        "a VM, the VM must be in the Stopped state.");
-            }
-
-            long srcStoragePoolId = srcVolumeInfo.getPoolId();
-            StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(srcStoragePoolId);
-
-            HostVO hostVO;
-
-            if (srcStoragePoolVO.getClusterId() != null) {
-                hostVO = getHostInCluster(srcStoragePoolVO.getClusterId());
-            }
-            else {
-                hostVO = getHost(srcVolumeInfo.getDataCenterId(), hypervisorType, false);
-            }
-
-            volumePath = copyVolumeToSecondaryStorage(srcVolumeInfo, destVolumeInfo, hostVO,
-                    "Unable to copy the volume from managed storage to secondary storage");
-        }
-        catch (Exception ex) {
-            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeCopyFromManagedStorageToSecondaryStorage': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            CopyCmdAnswer copyCmdAnswer;
-
-            if (errMsg != null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-            else if (volumePath == null) {
-                copyCmdAnswer = new CopyCmdAnswer("Unable to acquire a volume path");
-            }
-            else {
-                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)destVolumeInfo.getTO();
-
-                volumeObjectTO.setPath(volumePath);
-
-                copyCmdAnswer = new CopyCmdAnswer(volumeObjectTO);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void handleVolumeMigrationFromManagedStorageToNonManagedStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
-                                                                            AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-
-        try {
-            if (!ImageFormat.QCOW2.equals(srcVolumeInfo.getFormat())) {
-                throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " +
-                        "from managed storage to non-managed storage.");
-            }
-
-            HypervisorType hypervisorType = HypervisorType.KVM;
-            VirtualMachine vm = srcVolumeInfo.getAttachedVM();
-
-            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
-                throw new CloudRuntimeException("Currently, if a volume to migrate from managed storage to non-managed storage is attached to " +
-                        "a VM, the VM must be in the Stopped state.");
-            }
-
-            long destStoragePoolId = destVolumeInfo.getPoolId();
-            StoragePoolVO destStoragePoolVO = _storagePoolDao.findById(destStoragePoolId);
-
-            HostVO hostVO;
-
-            if (destStoragePoolVO.getClusterId() != null) {
-                hostVO = getHostInCluster(destStoragePoolVO.getClusterId());
-            }
-            else {
-                hostVO = getHost(destVolumeInfo.getDataCenterId(), hypervisorType, false);
-            }
-
-            setCertainVolumeValuesNull(destVolumeInfo.getId());
-
-            // migrate the volume via the hypervisor
-            String path = migrateVolume(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from managed storage to non-managed storage");
-
-            updateVolumePath(destVolumeInfo.getId(), path);
-        }
-        catch (Exception ex) {
-            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeMigrationFromManagedStorageToNonManagedStorage': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            CopyCmdAnswer copyCmdAnswer;
-
-            if (errMsg != null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-            else {
-                destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
-
-                DataTO dataTO = destVolumeInfo.getTO();
-
-                copyCmdAnswer = new CopyCmdAnswer(dataTO);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void verifyFormat(ImageFormat imageFormat) {
-        if (imageFormat != ImageFormat.VHD && imageFormat != ImageFormat.OVA && imageFormat != ImageFormat.QCOW2) {
-            throw new CloudRuntimeException("Only the following image types are currently supported: " +
-                    ImageFormat.VHD.toString() + ", " + ImageFormat.OVA.toString() + ", and " + ImageFormat.QCOW2);
-        }
-    }
-
-    private void verifyFormat(SnapshotInfo snapshotInfo) {
-        long volumeId = snapshotInfo.getVolumeId();
-
-        VolumeVO volumeVO = _volumeDao.findByIdIncludingRemoved(volumeId);
-
-        verifyFormat(volumeVO.getFormat());
-    }
-
-    private boolean usingBackendSnapshotFor(SnapshotInfo snapshotInfo) {
-        String property = getSnapshotProperty(snapshotInfo.getId(), "takeSnapshot");
-
-        return Boolean.parseBoolean(property);
-    }
-
-    private boolean needCacheStorage(DataObject srcData, DataObject destData) {
-        DataTO srcTO = srcData.getTO();
-        DataStoreTO srcStoreTO = srcTO.getDataStore();
-        DataTO destTO = destData.getTO();
-        DataStoreTO destStoreTO = destTO.getDataStore();
-
-        // both snapshot and volume are on primary datastore - no need for a cache storage as hypervisor will copy directly
-        if (srcStoreTO instanceof PrimaryDataStoreTO && destStoreTO instanceof PrimaryDataStoreTO) {
-            return false;
-        }
-
-        if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) {
-            return false;
-        }
-
-        if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) {
-            return false;
-        }
-
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("needCacheStorage true; dest at " + destTO.getPath() + ", dest role " + destStoreTO.getRole().toString() + "; src at " +
-                    srcTO.getPath() + ", src role " + srcStoreTO.getRole().toString());
-        }
-
-        return true;
-    }
-
-    private Scope pickCacheScopeForCopy(DataObject srcData, DataObject destData) {
-        Scope srcScope = srcData.getDataStore().getScope();
-        Scope destScope = destData.getDataStore().getScope();
-
-        Scope selectedScope = null;
-
-        if (srcScope.getScopeId() != null) {
-            selectedScope = getZoneScope(srcScope);
-        } else if (destScope.getScopeId() != null) {
-            selectedScope = getZoneScope(destScope);
-        } else {
-            LOGGER.warn("Cannot find a zone-wide scope for movement that needs a cache storage");
-        }
-
-        return selectedScope;
-    }
-
-    private Scope getZoneScope(Scope scope) {
-        ZoneScope zoneScope;
-
-        if (scope instanceof ClusterScope) {
-            ClusterScope clusterScope = (ClusterScope)scope;
-
-            zoneScope = new ZoneScope(clusterScope.getZoneId());
-        } else if (scope instanceof HostScope) {
-            HostScope hostScope = (HostScope)scope;
-
-            zoneScope = new ZoneScope(hostScope.getZoneId());
-        } else {
-            zoneScope = (ZoneScope)scope;
-        }
-
-        return zoneScope;
-    }
-
-    private void handleVolumeMigrationFromNonManagedStorageToManagedStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
-                                                                            AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-
-        try {
-            HypervisorType hypervisorType = srcVolumeInfo.getHypervisorType();
-
-            if (!HypervisorType.KVM.equals(hypervisorType)) {
-                throw new CloudRuntimeException("Currently, only the KVM hypervisor type is supported for the migration of a volume " +
-                        "from non-managed storage to managed storage.");
-            }
-
-            VirtualMachine vm = srcVolumeInfo.getAttachedVM();
-
-            if (vm != null && vm.getState() != VirtualMachine.State.Stopped) {
-                throw new CloudRuntimeException("Currently, if a volume to migrate from non-managed storage to managed storage is attached to " +
-                        "a VM, the VM must be in the Stopped state.");
-            }
-
-            destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
-
-            VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
-
-            volumeVO.setPath(volumeVO.get_iScsiName());
-
-            _volumeDao.update(volumeVO.getId(), volumeVO);
-
-            destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
-
-            long srcStoragePoolId = srcVolumeInfo.getPoolId();
-            StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(srcStoragePoolId);
-
-            HostVO hostVO;
-
-            if (srcStoragePoolVO.getClusterId() != null) {
-                hostVO = getHostInCluster(srcStoragePoolVO.getClusterId());
-            }
-            else {
-                hostVO = getHost(destVolumeInfo.getDataCenterId(), hypervisorType, false);
-            }
-
-            // migrate the volume via the hypervisor
-            migrateVolume(srcVolumeInfo, destVolumeInfo, hostVO, "Unable to migrate the volume from non-managed storage to managed storage");
-
-            volumeVO = _volumeDao.findById(destVolumeInfo.getId());
-
-            volumeVO.setFormat(ImageFormat.QCOW2);
-
-            _volumeDao.update(volumeVO.getId(), volumeVO);
-        }
-        catch (Exception ex) {
-            errMsg = "Migration operation failed in 'StorageSystemDataMotionStrategy.handleVolumeMigrationFromNonManagedStorageToManagedStorage': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            CopyCmdAnswer copyCmdAnswer;
-
-            if (errMsg != null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-            else {
-                destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
-
-                DataTO dataTO = destVolumeInfo.getTO();
-
-                copyCmdAnswer = new CopyCmdAnswer(dataTO);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    /**
-     * This function is responsible for copying a snapshot from managed storage to secondary storage. This is used in the following two cases:
-     * 1) When creating a template from a snapshot
-     * 2) When createSnapshot is called with location=SECONDARY
-     *
-     * @param snapshotInfo source snapshot
-     * @param destData destination (can be template or snapshot)
-     * @param callback callback for async
-     */
-    private void handleCopyDataToSecondaryStorage(SnapshotInfo snapshotInfo, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-        boolean usingBackendSnapshot = false;
-
-        try {
-            snapshotInfo.processEvent(Event.CopyingRequested);
-
-            HostVO hostVO = getHost(snapshotInfo);
-
-            boolean needCache = needCacheStorage(snapshotInfo, destData);
-
-            DataObject destOnStore = destData;
-
-            if (needCache) {
-                // creates an object in the DB for data to be cached
-                Scope selectedScope = pickCacheScopeForCopy(snapshotInfo, destData);
-
-                destOnStore = cacheMgr.getCacheObject(snapshotInfo, selectedScope);
-
-                destOnStore.processEvent(Event.CreateOnlyRequested);
-            }
-
-            usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
-
-            if (usingBackendSnapshot) {
-                final boolean computeClusterSupportsVolumeClone;
-
-                // only XenServer, VMware, and KVM are currently supported
-                if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
-                    computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
-                }
-                else if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType()) || HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
-                    computeClusterSupportsVolumeClone = true;
-                }
-                else {
-                    throw new CloudRuntimeException("Unsupported hypervisor type");
-                }
-
-                if (!computeClusterSupportsVolumeClone) {
-                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
-                            hostVO.getClusterId();
-
-                    LOGGER.warn(noSupportForResignErrMsg);
-
-                    throw new CloudRuntimeException(noSupportForResignErrMsg);
-                }
-            }
-
-            String vmdk = null;
-            String uuid = null;
-            boolean keepGrantedAccess = false;
-
-            DataStore srcDataStore = snapshotInfo.getDataStore();
-
-            if (usingBackendSnapshot) {
-                createVolumeFromSnapshot(snapshotInfo);
-
-                if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                    keepGrantedAccess = HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType());
-
-                    Map<String, String> extraDetails = null;
-
-                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                        extraDetails = new HashMap<>();
-
-                        String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
-
-                        extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
-                        extraDetails.put(DiskTO.TEMPLATE_RESIGN, Boolean.TRUE.toString());
-                    }
-
-                    copyCmdAnswer = performResignature(snapshotInfo, hostVO, extraDetails, keepGrantedAccess);
-
-                    // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
-                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                        String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
-
-                        disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
-                    }
-
-                    if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                        if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                            throw new CloudRuntimeException(copyCmdAnswer.getDetails());
-                        } else {
-                            throw new CloudRuntimeException("Unable to create volume from snapshot");
-                        }
-                    }
-
-                    vmdk = copyCmdAnswer.getNewData().getPath();
-                    uuid = UUID.randomUUID().toString();
-                }
-            }
-
-            String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-            int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-            CopyCommand copyCommand = new CopyCommand(snapshotInfo.getTO(), destOnStore.getTO(), primaryStorageDownloadWait,
-                    VirtualMachineManager.ExecuteInSequence.value());
-
-            try {
-                if (!keepGrantedAccess) {
-                    _volumeService.grantAccess(snapshotInfo, hostVO, srcDataStore);
-                }
-
-                Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
-
-                if (isForVMware(destData)) {
-                    srcDetails.put(DiskTO.VMDK, vmdk);
-                    srcDetails.put(DiskTO.UUID, uuid);
-
-                    if (destData instanceof TemplateInfo) {
-                        VMTemplateVO templateDataStoreVO = _vmTemplateDao.findById(destData.getId());
-
-                        templateDataStoreVO.setUniqueName(uuid);
-
-                        _vmTemplateDao.update(destData.getId(), templateDataStoreVO);
-                    }
-                }
-
-                copyCommand.setOptions(srcDetails);
-
-                copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand);
-
-                if (!copyCmdAnswer.getResult()) {
-                    // We were not able to copy. Handle it.
-                    errMsg = copyCmdAnswer.getDetails();
-
-                    throw new CloudRuntimeException(errMsg);
-                }
-
-                if (needCache) {
-                    // If cached storage was needed (in case of object store as secondary
-                    // storage), at this point, the data has been copied from the primary
-                    // to the NFS cache by the hypervisor. We now invoke another copy
-                    // command to copy this data from cache to secondary storage. We
-                    // then clean up the cache.
-
-                    destOnStore.processEvent(Event.OperationSuccessed, copyCmdAnswer);
-
-                    CopyCommand cmd = new CopyCommand(destOnStore.getTO(), destData.getTO(), primaryStorageDownloadWait,
-                            VirtualMachineManager.ExecuteInSequence.value());
-                    EndPoint ep = selector.select(destOnStore, destData);
-
-                    if (ep == null) {
-                        errMsg = "No remote endpoint to send command, check if host or SSVM is down";
-
-                        LOGGER.error(errMsg);
-
-                        copyCmdAnswer = new CopyCmdAnswer(errMsg);
-                    } else {
-                        copyCmdAnswer = (CopyCmdAnswer)ep.sendMessage(cmd);
-                    }
-
-                    // clean up snapshot copied to staging
-                    cacheMgr.deleteCacheObject(destOnStore);
-                }
-            } catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
-                String msg = "Failed to create template from snapshot (Snapshot ID = " + snapshotInfo.getId() + ") : ";
-
-                LOGGER.warn(msg, ex);
-
-                throw new CloudRuntimeException(msg + ex.getMessage(), ex);
-            } finally {
-                _volumeService.revokeAccess(snapshotInfo, hostVO, srcDataStore);
-
-                // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
-                if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                    String iqn = getSnapshotProperty(snapshotInfo.getId(), DiskTO.IQN);
-
-                    disconnectHostFromVolume(hostVO, srcDataStore.getId(), iqn);
-                }
-
-                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                        errMsg = copyCmdAnswer.getDetails();
-
-                        if (needCache) {
-                            cacheMgr.deleteCacheObject(destOnStore);
-                        }
-                    }
-                    else {
-                        errMsg = "Unable to create template from snapshot";
-                    }
-                }
-
-                try {
-                    if (StringUtils.isEmpty(errMsg)) {
-                        snapshotInfo.processEvent(Event.OperationSuccessed);
-                    }
-                    else {
-                        snapshotInfo.processEvent(Event.OperationFailed);
-                    }
-                }
-                catch (Exception ex) {
-                    LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
-                }
-            }
-        }
-        catch (Exception ex) {
-            errMsg = ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (usingBackendSnapshot) {
-                deleteVolumeFromSnapshot(snapshotInfo);
-            }
-
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    /**
-     * Creates a volume on the storage from a snapshot that resides on the secondary storage (archived snapshot).
-     * @param snapshotInfo snapshot on secondary
-     * @param volumeInfo volume to be created on the storage
-     * @param callback for async
-     */
-    private void handleCreateVolumeFromSnapshotOnSecondaryStorage(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo,
-                                                                  AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-
-        try {
-            // at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance)
-            DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId());
-            SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId());
-
-            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-            _volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType());
-
-            HostVO hostVO;
-
-            // create a volume on the storage
-            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
-            VolumeApiResult result = future.get();
-
-            if (result.isFailed()) {
-                LOGGER.error("Failed to create a volume: " + result.getResult());
-
-                throw new CloudRuntimeException(result.getResult());
-            }
-
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-            volumeInfo.processEvent(Event.MigrationRequested);
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-
-            hostVO = getHost(snapshotInfo.getDataCenterId(), snapshotInfo.getHypervisorType(), false);
-
-            // copy the volume from secondary via the hypervisor
-            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
-                copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO);
-            }
-            else {
-                copyCmdAnswer = copyImageToVolume(snapshotInfo, volumeInfo, hostVO);
-            }
-
-            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                    throw new CloudRuntimeException(copyCmdAnswer.getDetails());
-                }
-                else {
-                    throw new CloudRuntimeException("Unable to create volume from snapshot");
-                }
-            }
-        }
-        catch (Exception ex) {
-            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromSnapshotOnSecondaryStorage': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    /**
-     * Clones a template present on the storage to a new volume and resignatures it.
-     *
-     * @param templateInfo source template
-     * @param volumeInfo destination ROOT volume
-     * @param callback for async
-     */
-    private void handleCreateVolumeFromTemplateBothOnStorageSystem(TemplateInfo templateInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-
-        try {
-            Preconditions.checkArgument(templateInfo != null, "Passing 'null' to templateInfo of " +
-                            "handleCreateVolumeFromTemplateBothOnStorageSystem is not supported.");
-            Preconditions.checkArgument(volumeInfo != null, "Passing 'null' to volumeInfo of " +
-                            "handleCreateVolumeFromTemplateBothOnStorageSystem is not supported.");
-
-            verifyFormat(templateInfo.getFormat());
-
-            HostVO hostVO = null;
-
-            final boolean computeClusterSupportsVolumeClone;
-
-            // only XenServer, VMware, and KVM are currently supported
-            // Leave host equal to null for KVM since we don't need to perform a resignature when using that hypervisor type.
-            if (volumeInfo.getFormat() == ImageFormat.VHD) {
-                hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.XenServer, true);
-
-                if (hostVO == null) {
-                    throw new CloudRuntimeException("Unable to locate a host capable of resigning in the zone with the following ID: " +
-                            volumeInfo.getDataCenterId());
-                }
-
-                computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
-
-                if (!computeClusterSupportsVolumeClone) {
-                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
-                            hostVO.getClusterId();
-
-                    LOGGER.warn(noSupportForResignErrMsg);
-
-                    throw new CloudRuntimeException(noSupportForResignErrMsg);
-                }
-            }
-            else if (volumeInfo.getFormat() == ImageFormat.OVA) {
-                // all VMware hosts support resigning
-                hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.VMware, false);
-
-                if (hostVO == null) {
-                    throw new CloudRuntimeException("Unable to locate a host capable of resigning in the zone with the following ID: " +
-                            volumeInfo.getDataCenterId());
-                }
-            }
-
-            VolumeDetailVO volumeDetail = new VolumeDetailVO(volumeInfo.getId(),
-                    "cloneOfTemplate",
-                    String.valueOf(templateInfo.getId()),
-                    false);
-
-            volumeDetail = volumeDetailsDao.persist(volumeDetail);
-
-            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
-
-            int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
-
-            VolumeApiResult result = future.get(storagePoolMaxWaitSeconds, TimeUnit.SECONDS);
-
-            if (volumeDetail != null) {
-                volumeDetailsDao.remove(volumeDetail.getId());
-            }
-
-            if (result.isFailed()) {
-                LOGGER.warn("Failed to create a volume: " + result.getResult());
-
-                throw new CloudRuntimeException(result.getResult());
-            }
-
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-            volumeInfo.processEvent(Event.MigrationRequested);
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-
-            if (hostVO != null) {
-                Map<String, String> extraDetails = null;
-
-                if (HypervisorType.VMware.equals(templateInfo.getHypervisorType())) {
-                    extraDetails = new HashMap<>();
-
-                    String extraDetailsVmdk = templateInfo.getUniqueName() + ".vmdk";
-
-                    extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
-                    extraDetails.put(DiskTO.EXPAND_DATASTORE, Boolean.TRUE.toString());
-                }
-
-                copyCmdAnswer = performResignature(volumeInfo, hostVO, extraDetails);
-
-                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                        throw new CloudRuntimeException(copyCmdAnswer.getDetails());
-                    } else {
-                        throw new CloudRuntimeException("Unable to create a volume from a template");
-                    }
-                }
-
-                // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
-                if (HypervisorType.VMware.equals(templateInfo.getHypervisorType())) {
-                    disconnectHostFromVolume(hostVO, volumeInfo.getPoolId(), volumeInfo.get_iScsiName());
-                }
-            }
-            else {
-                VolumeObjectTO newVolume = new VolumeObjectTO();
-
-                newVolume.setSize(volumeInfo.getSize());
-                newVolume.setPath(volumeInfo.getPath());
-                newVolume.setFormat(volumeInfo.getFormat());
-
-                copyCmdAnswer = new CopyCmdAnswer(newVolume);
-            }
-        } catch (Exception ex) {
-            try {
-                volumeInfo.getDataStore().getDriver().deleteAsync(volumeInfo.getDataStore(), volumeInfo, null);
-            }
-            catch (Exception exc) {
-                LOGGER.warn("Failed to delete volume", exc);
-            }
-
-            if (templateInfo != null) {
-                errMsg = "Create volume from template (ID = " + templateInfo.getId() + ") failed: " + ex.getMessage();
-            }
-            else {
-                errMsg = "Create volume from template failed: " + ex.getMessage();
-            }
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void handleCreateVolumeFromSnapshotBothOnStorageSystem(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo,
-                                                                   AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-
-        try {
-            verifyFormat(snapshotInfo);
-
-            HostVO hostVO = getHost(snapshotInfo);
-
-            boolean usingBackendSnapshot = usingBackendSnapshotFor(snapshotInfo);
-            boolean computeClusterSupportsVolumeClone = true;
-
-            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType())) {
-                computeClusterSupportsVolumeClone = clusterDao.getSupportsResigning(hostVO.getClusterId());
-
-                if (usingBackendSnapshot && !computeClusterSupportsVolumeClone) {
-                    String noSupportForResignErrMsg = "Unable to locate an applicable host with which to perform a resignature operation : Cluster ID = " +
-                            hostVO.getClusterId();
-
-                    LOGGER.warn(noSupportForResignErrMsg);
-
-                    throw new CloudRuntimeException(noSupportForResignErrMsg);
-                }
-            }
-
-            boolean canStorageSystemCreateVolumeFromVolume = canStorageSystemCreateVolumeFromVolume(snapshotInfo);
-            boolean useCloning = usingBackendSnapshot || (canStorageSystemCreateVolumeFromVolume && computeClusterSupportsVolumeClone);
-
-            VolumeDetailVO volumeDetail = null;
-
-            if (useCloning) {
-                volumeDetail = new VolumeDetailVO(volumeInfo.getId(),
-                    "cloneOfSnapshot",
-                    String.valueOf(snapshotInfo.getId()),
-                    false);
-
-                volumeDetail = volumeDetailsDao.persist(volumeDetail);
-            }
-
-            // at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance)
-            DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId());
-            SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId());
-
-            // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-            _volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType());
-
-            AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
-            VolumeApiResult result = future.get();
-
-            if (volumeDetail != null) {
-                volumeDetailsDao.remove(volumeDetail.getId());
-            }
-
-            if (result.isFailed()) {
-                LOGGER.warn("Failed to create a volume: " + result.getResult());
-
-                throw new CloudRuntimeException(result.getResult());
-            }
-
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-            volumeInfo.processEvent(Event.MigrationRequested);
-            volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
-
-            if (HypervisorType.XenServer.equals(snapshotInfo.getHypervisorType()) || HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                if (useCloning) {
-                    Map<String, String> extraDetails = null;
-
-                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                        extraDetails = new HashMap<>();
-
-                        String extraDetailsVmdk = getSnapshotProperty(snapshotInfo.getId(), DiskTO.VMDK);
-
-                        extraDetails.put(DiskTO.VMDK, extraDetailsVmdk);
-                    }
-
-                    copyCmdAnswer = performResignature(volumeInfo, hostVO, extraDetails);
-
-                    // If using VMware, have the host rescan its software HBA if dynamic discovery is in use.
-                    if (HypervisorType.VMware.equals(snapshotInfo.getHypervisorType())) {
-                        disconnectHostFromVolume(hostVO, volumeInfo.getPoolId(), volumeInfo.get_iScsiName());
-                    }
-                } else {
-                    // asking for a XenServer host here so we don't always prefer to use XenServer hosts that support resigning
-                    // even when we don't need those hosts to do this kind of copy work
-                    hostVO = getHost(snapshotInfo.getDataCenterId(), snapshotInfo.getHypervisorType(), false);
-
-                    copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO);
-                }
-
-                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                        throw new CloudRuntimeException(copyCmdAnswer.getDetails());
-                    } else {
-                        throw new CloudRuntimeException("Unable to create volume from snapshot");
-                    }
-                }
-            }
-            else if (HypervisorType.KVM.equals(snapshotInfo.getHypervisorType())) {
-                VolumeObjectTO newVolume = new VolumeObjectTO();
-
-                newVolume.setSize(volumeInfo.getSize());
-                newVolume.setPath(volumeInfo.get_iScsiName());
-                newVolume.setFormat(volumeInfo.getFormat());
-
-                copyCmdAnswer = new CopyCmdAnswer(newVolume);
-            }
-            else {
-                throw new CloudRuntimeException("Unsupported hypervisor type");
-            }
-        }
-        catch (Exception ex) {
-            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromSnapshotBothOnStorageSystem': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void handleCreateVolumeFromVolumeOnSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo,
-                                                                long dataCenterId, HypervisorType hypervisorType,
-                                                                AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-
-        try {
-            // create a volume on the storage
-            destVolumeInfo.getDataStore().getDriver().createAsync(destVolumeInfo.getDataStore(), destVolumeInfo, null);
-
-            destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId(), destVolumeInfo.getDataStore());
-
-            HostVO hostVO = getHost(dataCenterId, hypervisorType, false);
-
-            // copy the volume from secondary via the hypervisor
-            copyCmdAnswer = copyImageToVolume(srcVolumeInfo, destVolumeInfo, hostVO);
-
-            if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                    throw new CloudRuntimeException(copyCmdAnswer.getDetails());
-                }
-                else {
-                    throw new CloudRuntimeException("Unable to create volume from volume");
-                }
-            }
-        }
-        catch (Exception ex) {
-            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromVolumeOnSecondaryStorage': " +
-                    ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private CopyCmdAnswer copyImageToVolume(DataObject srcDataObject, VolumeInfo destVolumeInfo, HostVO hostVO) {
-        String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-        int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-
-        CopyCommand copyCommand = new CopyCommand(srcDataObject.getTO(), destVolumeInfo.getTO(), primaryStorageDownloadWait,
-                VirtualMachineManager.ExecuteInSequence.value());
-
-        CopyCmdAnswer copyCmdAnswer;
-
-        try {
-            _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
-
-            Map<String, String> destDetails = getVolumeDetails(destVolumeInfo);
-
-            copyCommand.setOptions2(destDetails);
-
-            copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand);
-        }
-        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
-            String msg = "Failed to copy image : ";
-
-            LOGGER.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
-        }
-        finally {
-            _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
-        }
-
-        VolumeObjectTO volumeObjectTO = (VolumeObjectTO)copyCmdAnswer.getNewData();
-
-        volumeObjectTO.setFormat(ImageFormat.QCOW2);
-
-        return copyCmdAnswer;
-    }
-
-    /**
-     * If the underlying storage system is making use of read-only snapshots, this gives the storage system the opportunity to
-     * create a volume from the snapshot so that we can copy the VHD file that should be inside of the snapshot to secondary storage.
-     *
-     * The resultant volume must be writable because we need to resign the SR and the VDI that should be inside of it before we copy
-     * the VHD file to secondary storage.
-     *
-     * If the storage system is using writable snapshots, then nothing need be done by that storage system here because we can just
-     * resign the SR and the VDI that should be inside of the snapshot before copying the VHD file to secondary storage.
-     */
-    private void createVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
-        SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "create");
-
-        try {
-            snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
-        }
-        finally {
-            _snapshotDetailsDao.remove(snapshotDetails.getId());
-        }
-    }
-
-    /**
-     * If the underlying storage system needed to create a volume from a snapshot for createVolumeFromSnapshot(SnapshotInfo), then
-     * this is its opportunity to delete that temporary volume and restore properties in snapshot_details to the way they were before the
-     * invocation of createVolumeFromSnapshot(SnapshotInfo).
-     */
-    private void deleteVolumeFromSnapshot(SnapshotInfo snapshotInfo) {
-        SnapshotDetailsVO snapshotDetails = handleSnapshotDetails(snapshotInfo.getId(), "delete");
-
-        try {
-            snapshotInfo.getDataStore().getDriver().createAsync(snapshotInfo.getDataStore(), snapshotInfo, null);
-        }
-        finally {
-            _snapshotDetailsDao.remove(snapshotDetails.getId());
-        }
-    }
-
-    private SnapshotDetailsVO handleSnapshotDetails(long csSnapshotId, String value) {
-        String name = "tempVolume";
-
-        _snapshotDetailsDao.removeDetail(csSnapshotId, name);
-
-        SnapshotDetailsVO snapshotDetails = new SnapshotDetailsVO(csSnapshotId, name, value, false);
-
-        return _snapshotDetailsDao.persist(snapshotDetails);
-    }
-
-    /**
-     * For each disk to migrate:
-     *   Create a volume on the target storage system.
-     *   Make the newly created volume accessible to the target KVM host.
-     *   Send a command to the target KVM host to connect to the newly created volume.
-     * Send a command to the source KVM host to migrate the VM and its storage.
-     */
-    @Override
-    public void copyAsync(Map<VolumeInfo, DataStore> volumeDataStoreMap, VirtualMachineTO vmTO, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        String errMsg = null;
-
-        try {
-            if (srcHost.getHypervisorType() != HypervisorType.KVM) {
-                throw new CloudRuntimeException("Invalid hypervisor type (only KVM supported for this operation at the time being)");
-            }
-
-            verifyLiveMigrationMapForKVM(volumeDataStoreMap);
-
-            Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage = new HashMap<>();
-            Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo = new HashMap<>();
-
-            for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) {
-                VolumeInfo srcVolumeInfo = entry.getKey();
-                DataStore destDataStore = entry.getValue();
-
-                VolumeVO srcVolume = _volumeDao.findById(srcVolumeInfo.getId());
-                StoragePoolVO destStoragePool = _storagePoolDao.findById(destDataStore.getId());
-
-                VolumeVO destVolume = duplicateVolumeOnAnotherStorage(srcVolume, destStoragePool);
-                VolumeInfo destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
-
-                // move the volume from Allocated to Creating
-                destVolumeInfo.processEvent(Event.MigrationCopyRequested);
-                // move the volume from Creating to Ready
-                destVolumeInfo.processEvent(Event.MigrationCopySucceeded);
-                // move the volume from Ready to Migrating
-                destVolumeInfo.processEvent(Event.MigrationRequested);
-
-                // create a volume on the destination storage
-                destDataStore.getDriver().createAsync(destDataStore, destVolumeInfo, null);
-
-                destVolume = _volumeDao.findById(destVolume.getId());
-
-                destVolume.setPath(destVolume.get_iScsiName());
-
-                _volumeDao.update(destVolume.getId(), destVolume);
-
-                destVolumeInfo = _volumeDataFactory.getVolume(destVolume.getId(), destDataStore);
-
-                _volumeService.grantAccess(destVolumeInfo, destHost, destDataStore);
-
-                String connectedPath = connectHostToVolume(destHost, destVolumeInfo.getPoolId(), destVolumeInfo.get_iScsiName());
-
-                MigrateCommand.MigrateDiskInfo migrateDiskInfo = new MigrateCommand.MigrateDiskInfo(srcVolumeInfo.getPath(),
-                        MigrateCommand.MigrateDiskInfo.DiskType.BLOCK,
-                        MigrateCommand.MigrateDiskInfo.DriverType.RAW,
-                        MigrateCommand.MigrateDiskInfo.Source.DEV,
-                        connectedPath);
-
-                migrateStorage.put(srcVolumeInfo.getPath(), migrateDiskInfo);
-
-                srcVolumeInfoToDestVolumeInfo.put(srcVolumeInfo, destVolumeInfo);
-            }
-
-            PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO);
-
-            try {
-                Answer pfma = _agentMgr.send(destHost.getId(), pfmc);
-
-                if (pfma == null || !pfma.getResult()) {
-                    String details = pfma != null ? pfma.getDetails() : "null answer returned";
-                    String msg = "Unable to prepare for migration due to the following: " + details;
-
-                    throw new AgentUnavailableException(msg, destHost.getId());
-                }
-            }
-            catch (final OperationTimedoutException e) {
-                throw new AgentUnavailableException("Operation timed out", destHost.getId());
-            }
-
-            VMInstanceVO vm = _vmDao.findById(vmTO.getId());
-            boolean isWindows = _guestOsCategoryDao.findById(_guestOsDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-
-            MigrateCommand migrateCommand = new MigrateCommand(vmTO.getName(), destHost.getPrivateIpAddress(), isWindows, vmTO, true);
-
-            migrateCommand.setWait(StorageManager.KvmStorageOnlineMigrationWait.value());
-
-            migrateCommand.setMigrateStorage(migrateStorage);
-
-            String autoConvergence = _configDao.getValue(Config.KvmAutoConvergence.toString());
-            boolean kvmAutoConvergence = Boolean.parseBoolean(autoConvergence);
-
-            migrateCommand.setAutoConvergence(kvmAutoConvergence);
-
-            MigrateAnswer migrateAnswer = (MigrateAnswer)_agentMgr.send(srcHost.getId(), migrateCommand);
-
-            boolean success = migrateAnswer != null && migrateAnswer.getResult();
-
-            handlePostMigration(success, srcVolumeInfoToDestVolumeInfo, vmTO, destHost);
-
-            if (migrateAnswer == null) {
-                throw new CloudRuntimeException("Unable to get an answer to the migrate command");
-            }
-
-            if (!migrateAnswer.getResult()) {
-                errMsg = migrateAnswer.getDetails();
-
-                throw new CloudRuntimeException(errMsg);
-            }
-        }
-        catch (Exception ex) {
-            errMsg = "Copy operation failed in 'StorageSystemDataMotionStrategy.copyAsync': " + ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            CopyCmdAnswer copyCmdAnswer = new CopyCmdAnswer(errMsg);
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void handlePostMigration(boolean success, Map<VolumeInfo, VolumeInfo> srcVolumeInfoToDestVolumeInfo, VirtualMachineTO vmTO, Host destHost) {
-        if (!success) {
-            try {
-                PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(vmTO);
-
-                pfmc.setRollback(true);
-
-                Answer pfma = _agentMgr.send(destHost.getId(), pfmc);
-
-                if (pfma == null || !pfma.getResult()) {
-                    String details = pfma != null ? pfma.getDetails() : "null answer returned";
-                    String msg = "Unable to rollback prepare for migration due to the following: " + details;
-
-                    throw new AgentUnavailableException(msg, destHost.getId());
-                }
-            }
-            catch (Exception e) {
-                LOGGER.debug("Failed to disconnect one or more (original) dest volumes", e);
-            }
-        }
-
-        for (Map.Entry<VolumeInfo, VolumeInfo> entry : srcVolumeInfoToDestVolumeInfo.entrySet()) {
-            VolumeInfo srcVolumeInfo = entry.getKey();
-            VolumeInfo destVolumeInfo = entry.getValue();
-
-            if (success) {
-                srcVolumeInfo.processEvent(Event.OperationSuccessed);
-                destVolumeInfo.processEvent(Event.OperationSuccessed);
-
-                _volumeDao.updateUuid(srcVolumeInfo.getId(), destVolumeInfo.getId());
-
-                VolumeVO volumeVO = _volumeDao.findById(destVolumeInfo.getId());
-
-                volumeVO.setFormat(ImageFormat.QCOW2);
-
-                _volumeDao.update(volumeVO.getId(), volumeVO);
-
-                try {
-                    _volumeService.destroyVolume(srcVolumeInfo.getId());
-
-                    srcVolumeInfo = _volumeDataFactory.getVolume(srcVolumeInfo.getId());
-
-                    AsyncCallFuture<VolumeApiResult> destroyFuture = _volumeService.expungeVolumeAsync(srcVolumeInfo);
-
-                    if (destroyFuture.get().isFailed()) {
-                        LOGGER.debug("Failed to clean up source volume on storage");
-                    }
-                } catch (Exception e) {
-                    LOGGER.debug("Failed to clean up source volume on storage", e);
-                }
-
-                // Update the volume ID for snapshots on secondary storage
-                if (!_snapshotDao.listByVolumeId(srcVolumeInfo.getId()).isEmpty()) {
-                    _snapshotDao.updateVolumeIds(srcVolumeInfo.getId(), destVolumeInfo.getId());
-                    _snapshotDataStoreDao.updateVolumeIds(srcVolumeInfo.getId(), destVolumeInfo.getId());
-                }
-            }
-            else {
-                try {
-                    disconnectHostFromVolume(destHost, destVolumeInfo.getPoolId(), destVolumeInfo.get_iScsiName());
-                }
-                catch (Exception e) {
-                    LOGGER.debug("Failed to disconnect (new) dest volume", e);
-                }
-
-                try {
-                    _volumeService.revokeAccess(destVolumeInfo, destHost, destVolumeInfo.getDataStore());
-                }
-                catch (Exception e) {
-                    LOGGER.debug("Failed to revoke access from dest volume", e);
-                }
-
-                destVolumeInfo.processEvent(Event.OperationFailed);
-                srcVolumeInfo.processEvent(Event.OperationFailed);
-
-                try {
-                    _volumeService.destroyVolume(destVolumeInfo.getId());
-
-                    destVolumeInfo = _volumeDataFactory.getVolume(destVolumeInfo.getId());
-
-                    AsyncCallFuture<VolumeApiResult> destroyFuture = _volumeService.expungeVolumeAsync(destVolumeInfo);
-
-                    if (destroyFuture.get().isFailed()) {
-                        LOGGER.debug("Failed to clean up dest volume on storage");
-                    }
-                } catch (Exception e) {
-                    LOGGER.debug("Failed to clean up dest volume on storage", e);
-                }
-            }
-        }
-    }
-
-    private VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePoolVO storagePoolVO) {
-        Long lastPoolId = volume.getPoolId();
-
-        VolumeVO newVol = new VolumeVO(volume);
-
-        newVol.setInstanceId(null);
-        newVol.setChainInfo(null);
-        newVol.setPath(null);
-        newVol.setFolder(null);
-        newVol.setPodId(storagePoolVO.getPodId());
-        newVol.setPoolId(storagePoolVO.getId());
-        newVol.setLastPoolId(lastPoolId);
-
-        return _volumeDao.persist(newVol);
-    }
-
-    private String connectHostToVolume(Host host, long storagePoolId, String iqn) {
-        ModifyTargetsCommand modifyTargetsCommand = getModifyTargetsCommand(storagePoolId, iqn, true);
-
-        return sendModifyTargetsCommand(modifyTargetsCommand, host.getId()).get(0);
-    }
-
-    private void disconnectHostFromVolume(Host host, long storagePoolId, String iqn) {
-        ModifyTargetsCommand modifyTargetsCommand = getModifyTargetsCommand(storagePoolId, iqn, false);
-
-        sendModifyTargetsCommand(modifyTargetsCommand, host.getId());
-    }
-
-    private ModifyTargetsCommand getModifyTargetsCommand(long storagePoolId, String iqn, boolean add) {
-        StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
-
-        Map<String, String> details = new HashMap<>();
-
-        details.put(ModifyTargetsCommand.IQN, iqn);
-        details.put(ModifyTargetsCommand.STORAGE_TYPE, storagePool.getPoolType().name());
-        details.put(ModifyTargetsCommand.STORAGE_UUID, storagePool.getUuid());
-        details.put(ModifyTargetsCommand.STORAGE_HOST, storagePool.getHostAddress());
-        details.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
-
-        ModifyTargetsCommand modifyTargetsCommand = new ModifyTargetsCommand();
-
-        List<Map<String, String>> targets = new ArrayList<>();
-
-        targets.add(details);
-
-        modifyTargetsCommand.setTargets(targets);
-        modifyTargetsCommand.setApplyToAllHostsInCluster(true);
-        modifyTargetsCommand.setAdd(add);
-        modifyTargetsCommand.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-
-        return modifyTargetsCommand;
-    }
-
-    private List<String> sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        ModifyTargetsAnswer modifyTargetsAnswer = (ModifyTargetsAnswer)_agentMgr.easySend(hostId, cmd);
-
-        if (modifyTargetsAnswer == null) {
-            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
-        }
-
-        if (!modifyTargetsAnswer.getResult()) {
-            String msg = "Unable to modify targets on the following host: " + hostId;
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        return modifyTargetsAnswer.getConnectedPaths();
-    }
-
-    /*
-    * At a high level: The source storage cannot be managed and the destination storage must be managed.
-    */
-    private void verifyLiveMigrationMapForKVM(Map<VolumeInfo, DataStore> volumeDataStoreMap) {
-        for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) {
-            VolumeInfo volumeInfo = entry.getKey();
-
-            Long storagePoolId = volumeInfo.getPoolId();
-            StoragePoolVO srcStoragePoolVO = _storagePoolDao.findById(storagePoolId);
-
-            if (srcStoragePoolVO == null) {
-                throw new CloudRuntimeException("Volume with ID " + volumeInfo.getId() + " is not associated with a storage pool.");
-            }
-
-            if (srcStoragePoolVO.isManaged()) {
-                throw new CloudRuntimeException("Migrating a volume online with KVM from managed storage is not currently supported.");
-            }
-
-            DataStore dataStore = entry.getValue();
-            StoragePoolVO destStoragePoolVO = _storagePoolDao.findById(dataStore.getId());
-
-            if (destStoragePoolVO == null) {
-                throw new CloudRuntimeException("Destination storage pool with ID " + dataStore.getId() + " was not located.");
-            }
-
-            if (!destStoragePoolVO.isManaged()) {
-                throw new CloudRuntimeException("Migrating a volume online with KVM can currently only be done when moving to managed storage.");
-            }
-        }
-    }
-
-    private boolean canStorageSystemCreateVolumeFromVolume(SnapshotInfo snapshotInfo) {
-        boolean supportsCloningVolumeFromVolume = false;
-
-        DataStore dataStore = dataStoreMgr.getDataStore(snapshotInfo.getDataStore().getId(), DataStoreRole.Primary);
-
-        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
-
-        if (mapCapabilities != null) {
-            String value = mapCapabilities.get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString());
-
-            supportsCloningVolumeFromVolume = Boolean.valueOf(value);
-        }
-
-        return supportsCloningVolumeFromVolume;
-    }
-
-    private String getVolumeProperty(long volumeId, String property) {
-        VolumeDetailVO volumeDetails = volumeDetailsDao.findDetail(volumeId, property);
-
-        if (volumeDetails != null) {
-            return volumeDetails.getValue();
-        }
-
-        return null;
-    }
-
-    private String getSnapshotProperty(long snapshotId, String property) {
-        SnapshotDetailsVO snapshotDetails = _snapshotDetailsDao.findDetail(snapshotId, property);
-
-        if (snapshotDetails != null) {
-            return snapshotDetails.getValue();
-        }
-
-        return null;
-    }
-
-    private void handleCreateTemplateFromVolume(VolumeInfo volumeInfo, TemplateInfo templateInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
-        boolean srcVolumeDetached = volumeInfo.getAttachedVM() == null;
-
-        String errMsg = null;
-        CopyCmdAnswer copyCmdAnswer = null;
-
-        try {
-            if (!ImageFormat.QCOW2.equals(volumeInfo.getFormat())) {
-                throw new CloudRuntimeException("When using managed storage, you can only create a template from a volume on KVM currently.");
-            }
-
-            volumeInfo.processEvent(Event.MigrationRequested);
-
-            HostVO hostVO = getHost(volumeInfo.getDataCenterId(), HypervisorType.KVM, false);
-            DataStore srcDataStore = volumeInfo.getDataStore();
-
-            String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-            int primaryStorageDownloadWait = NumberUtils.toInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-            CopyCommand copyCommand = new CopyCommand(volumeInfo.getTO(), templateInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
-
-            try {
-                if (srcVolumeDetached) {
-                    _volumeService.grantAccess(volumeInfo, hostVO, srcDataStore);
-                }
-
-                Map<String, String> srcDetails = getVolumeDetails(volumeInfo);
-
-                copyCommand.setOptions(srcDetails);
-
-                copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand);
-
-                if (!copyCmdAnswer.getResult()) {
-                    // We were not able to copy. Handle it.
-                    errMsg = copyCmdAnswer.getDetails();
-                    throw new CloudRuntimeException(errMsg);
-                }
-
-                VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(templateInfo.getId());
-
-                vmTemplateVO.setHypervisorType(HypervisorType.KVM);
-
-                _vmTemplateDao.update(vmTemplateVO.getId(), vmTemplateVO);
-            }
-            catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
-                String msg = "Failed to create template from volume (Volume ID = " + volumeInfo.getId() + ") : ";
-
-                LOGGER.warn(msg, ex);
-
-                throw new CloudRuntimeException(msg + ex.getMessage(), ex);
-            }
-            finally {
-                try {
-                    if (srcVolumeDetached) {
-                        _volumeService.revokeAccess(volumeInfo, hostVO, srcDataStore);
-                    }
-                }
-                catch (Exception ex) {
-                    LOGGER.warn("Error revoking access to volume (Volume ID = " + volumeInfo.getId() + "): " + ex.getMessage(), ex);
-                }
-                if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
-                    if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
-                        errMsg = copyCmdAnswer.getDetails();
-                    }
-                    else {
-                        errMsg = "Unable to create template from volume";
-                    }
-                }
-
-                try {
-                    if (StringUtils.isEmpty(errMsg)) {
-                        volumeInfo.processEvent(Event.OperationSuccessed);
-                    }
-                    else {
-                        volumeInfo.processEvent(Event.OperationFailed);
-                    }
-                }
-                catch (Exception ex) {
-                    LOGGER.warn("Error processing snapshot event: " + ex.getMessage(), ex);
-                }
-            }
-        }
-        catch (Exception ex) {
-            errMsg = ex.getMessage();
-
-            throw new CloudRuntimeException(errMsg);
-        }
-        finally {
-            if (copyCmdAnswer == null) {
-                copyCmdAnswer = new CopyCmdAnswer(errMsg);
-            }
-
-            CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo) {
-        long storagePoolId = volumeInfo.getPoolId();
-        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
-
-        if (!storagePoolVO.isManaged()) {
-            return null;
-        }
-
-        Map<String, String> volumeDetails = new HashMap<>();
-
-        VolumeVO volumeVO = _volumeDao.findById(volumeInfo.getId());
-
-        volumeDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress());
-        volumeDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
-        volumeDetails.put(DiskTO.IQN, volumeVO.get_iScsiName());
-
-        volumeDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeVO.getSize()));
-        volumeDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getVolumeProperty(volumeInfo.getId(), DiskTO.SCSI_NAA_DEVICE_ID));
-
-        ChapInfo chapInfo = _volumeService.getChapInfo(volumeInfo, volumeInfo.getDataStore());
-
-        if (chapInfo != null) {
-            volumeDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
-            volumeDetails.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
-            volumeDetails.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
-            volumeDetails.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
-        }
-
-        return volumeDetails;
-    }
-
-    private Map<String, String> getSnapshotDetails(SnapshotInfo snapshotInfo) {
-        Map<String, String> snapshotDetails = new HashMap<>();
-
-        long storagePoolId = snapshotInfo.getDataStore().getId();
-        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
-
-        snapshotDetails.put(DiskTO.STORAGE_HOST, storagePoolVO.getHostAddress());
-        snapshotDetails.put(DiskTO.STORAGE_PORT, String.valueOf(storagePoolVO.getPort()));
-
-        long snapshotId = snapshotInfo.getId();
-
-        snapshotDetails.put(DiskTO.IQN, getSnapshotProperty(snapshotId, DiskTO.IQN));
-        snapshotDetails.put(DiskTO.VOLUME_SIZE, String.valueOf(snapshotInfo.getSize()));
-        snapshotDetails.put(DiskTO.SCSI_NAA_DEVICE_ID, getSnapshotProperty(snapshotId, DiskTO.SCSI_NAA_DEVICE_ID));
-
-        snapshotDetails.put(DiskTO.CHAP_INITIATOR_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_USERNAME));
-        snapshotDetails.put(DiskTO.CHAP_INITIATOR_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_INITIATOR_SECRET));
-        snapshotDetails.put(DiskTO.CHAP_TARGET_USERNAME, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_USERNAME));
-        snapshotDetails.put(DiskTO.CHAP_TARGET_SECRET, getSnapshotProperty(snapshotId, DiskTO.CHAP_TARGET_SECRET));
-
-        return snapshotDetails;
-    }
-
-    private HostVO getHost(SnapshotInfo snapshotInfo) {
-        HypervisorType hypervisorType = snapshotInfo.getHypervisorType();
-
-        if (HypervisorType.XenServer.equals(hypervisorType)) {
-            HostVO hostVO = getHost(snapshotInfo.getDataCenterId(), hypervisorType, true);
-
-            if (hostVO == null) {
-                hostVO = getHost(snapshotInfo.getDataCenterId(), hypervisorType, false);
-
-                if (hostVO == null) {
-                    throw new CloudRuntimeException("Unable to locate an applicable host in data center with ID = " + snapshotInfo.getDataCenterId());
-                }
-            }
-
-            return hostVO;
-        }
-
-        if (HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
-            return getHost(snapshotInfo.getDataCenterId(), hypervisorType, false);
-        }
-
-        throw new CloudRuntimeException("Unsupported hypervisor type");
-    }
-
-    private HostVO getHostInCluster(long clusterId) {
-        List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
-
-        if (hosts != null && hosts.size() > 0) {
-            Collections.shuffle(hosts, RANDOM);
-
-            for (HostVO host : hosts) {
-                if (ResourceState.Enabled.equals(host.getResourceState())) {
-                    return host;
-                }
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate a host");
-    }
-
-    private HostVO getHost(Long zoneId, HypervisorType hypervisorType, boolean computeClusterMustSupportResign) {
-        Preconditions.checkArgument(zoneId != null, "Zone ID cannot be null.");
-        Preconditions.checkArgument(hypervisorType != null, "Hypervisor type cannot be null.");
-
-        List<HostVO> hosts = _hostDao.listByDataCenterIdAndHypervisorType(zoneId, hypervisorType);
-
-        if (hosts == null) {
-            return null;
-        }
-
-        List<Long> clustersToSkip = new ArrayList<>();
-
-        Collections.shuffle(hosts, RANDOM);
-
-        for (HostVO host : hosts) {
-            if (!ResourceState.Enabled.equals(host.getResourceState())) {
-                continue;
-            }
-
-            if (computeClusterMustSupportResign) {
-                long clusterId = host.getClusterId();
-
-                if (clustersToSkip.contains(clusterId)) {
-                    continue;
-                }
-
-                if (clusterDao.getSupportsResigning(clusterId)) {
-                    return host;
-                }
-                else {
-                    clustersToSkip.add(clusterId);
-                }
-            }
-            else {
-                return host;
-            }
-        }
-
-        return null;
-    }
-
-    private Map<String, String> getDetails(DataObject dataObj) {
-        if (dataObj instanceof VolumeInfo) {
-            return getVolumeDetails((VolumeInfo)dataObj);
-        }
-        else if (dataObj instanceof SnapshotInfo) {
-            return getSnapshotDetails((SnapshotInfo)dataObj);
-        }
-
-        throw new CloudRuntimeException("'dataObj' must be of type 'VolumeInfo' or 'SnapshotInfo'.");
-    }
-
-    private boolean isForVMware(DataObject dataObj) {
-        if (dataObj instanceof VolumeInfo) {
-            return ImageFormat.OVA.equals(((VolumeInfo)dataObj).getFormat());
-        }
-
-        if (dataObj instanceof SnapshotInfo) {
-            return ImageFormat.OVA.equals(((SnapshotInfo)dataObj).getBaseVolume().getFormat());
-        }
-
-        return dataObj instanceof TemplateInfo && HypervisorType.VMware.equals(((TemplateInfo)dataObj).getHypervisorType());
-    }
-
-    private CopyCmdAnswer performResignature(DataObject dataObj, HostVO hostVO, Map<String, String> extraDetails) {
-        return performResignature(dataObj, hostVO, extraDetails, false);
-    }
-
-    private CopyCmdAnswer performResignature(DataObject dataObj, HostVO hostVO, Map<String, String> extraDetails, boolean keepGrantedAccess) {
-        long storagePoolId = dataObj.getDataStore().getId();
-        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-
-        Map<String, String> details = getDetails(dataObj);
-
-        if (extraDetails != null) {
-            details.putAll(extraDetails);
-        }
-
-        ResignatureCommand command = new ResignatureCommand(details);
-
-        ResignatureAnswer answer;
-
-        GlobalLock lock = GlobalLock.getInternLock(dataStore.getUuid());
-
-        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
-            String errMsg = "Couldn't lock the DB (in performResignature) on the following string: " + dataStore.getUuid();
-
-            LOGGER.warn(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        try {
-            _volumeService.grantAccess(dataObj, hostVO, dataStore);
-
-            answer = (ResignatureAnswer)_agentMgr.send(hostVO.getId(), command);
-        }
-        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
-            keepGrantedAccess = false;
-
-            String msg = "Failed to resign the DataObject with the following ID: " + dataObj.getId();
-
-            LOGGER.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg + ex.getMessage());
-        }
-        finally {
-            lock.unlock();
-            lock.releaseRef();
-
-            if (!keepGrantedAccess) {
-                _volumeService.revokeAccess(dataObj, hostVO, dataStore);
-            }
-        }
-
-        if (answer == null || !answer.getResult()) {
-            final String errMsg;
-
-            if (answer != null && answer.getDetails() != null && !answer.getDetails().isEmpty()) {
-                errMsg = answer.getDetails();
-            }
-            else {
-                errMsg = "Unable to perform resignature operation in 'StorageSystemDataMotionStrategy.performResignature'";
-            }
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        VolumeObjectTO newVolume = new VolumeObjectTO();
-
-        newVolume.setSize(answer.getSize());
-        newVolume.setPath(answer.getPath());
-        newVolume.setFormat(answer.getFormat());
-
-        return new CopyCmdAnswer(newVolume);
-    }
-
-    private DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) {
-        DataObject leafData = null;
-        DataStore store = cacheMgr.getCacheStorage(snapshot, scope);
-
-        while (snapshot != null) {
-            DataObject cacheData = cacheMgr.createCacheObject(snapshot, store);
-
-            if (leafData == null) {
-                leafData = cacheData;
-            }
-
-            snapshot = snapshot.getParent();
-        }
-
-        return leafData;
-    }
-
-    private String migrateVolume(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO, String errMsg) {
-        boolean srcVolumeDetached = srcVolumeInfo.getAttachedVM() == null;
-
-        try {
-            Map<String, String> srcDetails = getVolumeDetails(srcVolumeInfo);
-            Map<String, String> destDetails = getVolumeDetails(destVolumeInfo);
-
-            MigrateVolumeCommand migrateVolumeCommand = new MigrateVolumeCommand(srcVolumeInfo.getTO(), destVolumeInfo.getTO(),
-                    srcDetails, destDetails, StorageManager.KvmStorageOfflineMigrationWait.value());
-
-            if (srcVolumeDetached) {
-                _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
-            }
-
-            _volumeService.grantAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
-
-            MigrateVolumeAnswer migrateVolumeAnswer = (MigrateVolumeAnswer)_agentMgr.send(hostVO.getId(), migrateVolumeCommand);
-
-            if (migrateVolumeAnswer == null || !migrateVolumeAnswer.getResult()) {
-                if (migrateVolumeAnswer != null && !StringUtils.isEmpty(migrateVolumeAnswer.getDetails())) {
-                    throw new CloudRuntimeException(migrateVolumeAnswer.getDetails());
-                }
-                else {
-                    throw new CloudRuntimeException(errMsg);
-                }
-            }
-
-            if (srcVolumeDetached) {
-                _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
-            }
-
-            try {
-                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
-            }
-            catch (Exception e) {
-                // This volume should be deleted soon, so just log a warning here.
-                LOGGER.warn(e.getMessage(), e);
-            }
-
-            return migrateVolumeAnswer.getVolumePath();
-        }
-        catch (Exception ex) {
-            try {
-                _volumeService.revokeAccess(destVolumeInfo, hostVO, destVolumeInfo.getDataStore());
-            }
-            catch (Exception e) {
-                // This volume should be deleted soon, so just log a warning here.
-                LOGGER.warn(e.getMessage(), e);
-            }
-
-            if (srcVolumeDetached) {
-                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
-            }
-
-            String msg = "Failed to perform volume migration : ";
-
-            LOGGER.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
-        }
-    }
-
-    private String copyVolumeToSecondaryStorage(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, HostVO hostVO, String errMsg) {
-        boolean srcVolumeDetached = srcVolumeInfo.getAttachedVM() == null;
-
-        try {
-            StoragePoolVO storagePoolVO = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
-            Map<String, String> srcDetails = getVolumeDetails(srcVolumeInfo);
-
-            CopyVolumeCommand copyVolumeCommand = new CopyVolumeCommand(srcVolumeInfo.getId(), destVolumeInfo.getPath(), storagePoolVO,
-                    destVolumeInfo.getDataStore().getUri(), true, StorageManager.KvmStorageOfflineMigrationWait.value(), true);
-
-            copyVolumeCommand.setSrcData(srcVolumeInfo.getTO());
-            copyVolumeCommand.setSrcDetails(srcDetails);
-
-            if (srcVolumeDetached) {
-                _volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
-            }
-
-            CopyVolumeAnswer copyVolumeAnswer = (CopyVolumeAnswer)_agentMgr.send(hostVO.getId(), copyVolumeCommand);
-
-            if (copyVolumeAnswer == null || !copyVolumeAnswer.getResult()) {
-                if (copyVolumeAnswer != null && !StringUtils.isEmpty(copyVolumeAnswer.getDetails())) {
-                    throw new CloudRuntimeException(copyVolumeAnswer.getDetails());
-                }
-                else {
-                    throw new CloudRuntimeException(errMsg);
-                }
-            }
-
-            return copyVolumeAnswer.getVolumePath();
-        }
-        catch (Exception ex) {
-            String msg = "Failed to perform volume copy to secondary storage : ";
-
-            LOGGER.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg + ex.getMessage());
-        }
-        finally {
-            if (srcVolumeDetached) {
-                _volumeService.revokeAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
-            }
-        }
-    }
-
-    private void setCertainVolumeValuesNull(long volumeId) {
-        VolumeVO volumeVO = _volumeDao.findById(volumeId);
-
-        volumeVO.set_iScsiName(null);
-        volumeVO.setMinIops(null);
-        volumeVO.setMaxIops(null);
-        volumeVO.setHypervisorSnapshotReserve(null);
-
-        _volumeDao.update(volumeId, volumeVO);
-    }
-
-    private void updateVolumePath(long volumeId, String path) {
-        VolumeVO volumeVO = _volumeDao.findById(volumeId);
-
-        volumeVO.setPath(path);
-
-        _volumeDao.update(volumeId, volumeVO);
-    }
-
-    /**
-     * Copies data from secondary storage to a primary volume
-     * @param volumeInfo The primary volume
-     * @param snapshotInfo  destination of the copy
-     * @param hostVO the host used to copy the data
-     * @return result of the copy
-     */
-    private CopyCmdAnswer performCopyOfVdi(VolumeInfo volumeInfo, SnapshotInfo snapshotInfo, HostVO hostVO) {
-        Snapshot.LocationType locationType = snapshotInfo.getLocationType();
-
-        String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-        int primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-
-        DataObject srcData = snapshotInfo;
-        CopyCmdAnswer copyCmdAnswer = null;
-        DataObject cacheData = null;
-
-        boolean needCacheStorage = needCacheStorage(snapshotInfo, volumeInfo);
-
-        if (needCacheStorage) {
-            cacheData = cacheSnapshotChain(snapshotInfo, new ZoneScope(volumeInfo.getDataCenterId()));
-            srcData = cacheData;
-        }
-
-        CopyCommand copyCommand = new CopyCommand(srcData.getTO(), volumeInfo.getTO(), primaryStorageDownloadWait, VirtualMachineManager.ExecuteInSequence.value());
-
-        try {
-            if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
-                _volumeService.grantAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
-
-                Map<String, String> srcDetails = getSnapshotDetails(snapshotInfo);
-
-                copyCommand.setOptions(srcDetails);
-            }
-
-            _volumeService.grantAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
-
-            Map<String, String> destDetails = getVolumeDetails(volumeInfo);
-
-            copyCommand.setOptions2(destDetails);
-
-            copyCmdAnswer = (CopyCmdAnswer)_agentMgr.send(hostVO.getId(), copyCommand);
-        }
-        catch (CloudRuntimeException | AgentUnavailableException | OperationTimedoutException ex) {
-            String msg = "Failed to perform VDI copy : ";
-
-            LOGGER.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg + ex.getMessage(), ex);
-        }
-        finally {
-            if (Snapshot.LocationType.PRIMARY.equals(locationType)) {
-                _volumeService.revokeAccess(snapshotInfo, hostVO, snapshotInfo.getDataStore());
-            }
-
-            _volumeService.revokeAccess(volumeInfo, hostVO, volumeInfo.getDataStore());
-
-            if (needCacheStorage && copyCmdAnswer != null && copyCmdAnswer.getResult()) {
-                cacheMgr.deleteCacheObject(cacheData);
-            }
-        }
-
-        return copyCmdAnswer;
-    }
-}
diff --git a/engine/storage/datamotion/test/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java
similarity index 100%
rename from engine/storage/datamotion/test/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java
rename to engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java
diff --git a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java
new file mode 100644
index 0000000..c0d8ad3
--- /dev/null
+++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java
@@ -0,0 +1,400 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+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;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.datastore.DataStoreManagerImpl;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.CloudException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineManager;
+
+@RunWith(MockitoJUnitRunner.class)
+public class KvmNonManagedStorageSystemDataMotionTest {
+
+    @Mock
+    private PrimaryDataStoreDao primaryDataStoreDao;
+    @Mock
+    private TemplateDataFactory templateDataFactory;
+    @Mock
+    private AgentManager agentManager;
+    @Mock
+    private DiskOfferingDao diskOfferingDao;
+    @Mock
+    private VirtualMachineManager virtualMachineManager;
+    @Mock
+    private VMTemplatePoolDao vmTemplatePoolDao;
+    @Mock
+    private DataStoreManagerImpl dataStoreManagerImpl;
+    @Mock
+    private VolumeDataFactory volumeDataFactory;
+
+    @Spy
+    @InjectMocks
+    private KvmNonManagedStorageDataMotionStrategy kvmNonManagedStorageDataMotionStrategy;
+
+    @Test
+    public void canHandleTestExpectHypervisorStrategyForKvm() {
+        canHandleExpectCannotHandle(HypervisorType.KVM, 1, StrategyPriority.HYPERVISOR);
+    }
+
+    @Test
+    public void canHandleTestExpectCannotHandle() {
+        HypervisorType[] hypervisorTypeArray = HypervisorType.values();
+        for (int i = 0; i < hypervisorTypeArray.length; i++) {
+            HypervisorType ht = hypervisorTypeArray[i];
+            if (ht.equals(HypervisorType.KVM)) {
+                continue;
+            }
+            canHandleExpectCannotHandle(ht, 0, StrategyPriority.CANT_HANDLE);
+        }
+    }
+
+    private void canHandleExpectCannotHandle(HypervisorType hypervisorType, int times, StrategyPriority expectedStrategyPriority) {
+        HostVO srcHost = new HostVO("sourceHostUuid");
+        srcHost.setHypervisorType(hypervisorType);
+        Mockito.doReturn(StrategyPriority.HYPERVISOR).when(kvmNonManagedStorageDataMotionStrategy).internalCanHandle(new HashMap<>());
+
+        StrategyPriority strategyPriority = kvmNonManagedStorageDataMotionStrategy.canHandle(new HashMap<>(), srcHost, new HostVO("destHostUuid"));
+
+        Mockito.verify(kvmNonManagedStorageDataMotionStrategy, Mockito.times(times)).internalCanHandle(new HashMap<>());
+        Assert.assertEquals(expectedStrategyPriority, strategyPriority);
+    }
+
+    @Test
+    public void internalCanHandleTestNonManaged() {
+        StoragePoolType[] storagePoolTypeArray = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypeArray.length; i++) {
+            Map<VolumeInfo, DataStore> volumeMap = configureTestInternalCanHandle(false, storagePoolTypeArray[i]);
+            StrategyPriority strategyPriority = kvmNonManagedStorageDataMotionStrategy.internalCanHandle(volumeMap);
+            if (storagePoolTypeArray[i] == StoragePoolType.Filesystem || storagePoolTypeArray[i] == StoragePoolType.NetworkFilesystem) {
+                Assert.assertEquals(StrategyPriority.HYPERVISOR, strategyPriority);
+            } else {
+                Assert.assertEquals(StrategyPriority.CANT_HANDLE, strategyPriority);
+            }
+        }
+    }
+
+    @Test
+    public void internalCanHandleTestIsManaged() {
+        StoragePoolType[] storagePoolTypeArray = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypeArray.length; i++) {
+            Map<VolumeInfo, DataStore> volumeMap = configureTestInternalCanHandle(true, storagePoolTypeArray[i]);
+            StrategyPriority strategyPriority = kvmNonManagedStorageDataMotionStrategy.internalCanHandle(volumeMap);
+            Assert.assertEquals(StrategyPriority.CANT_HANDLE, strategyPriority);
+        }
+    }
+
+    private Map<VolumeInfo, DataStore> configureTestInternalCanHandle(boolean isManagedStorage, StoragePoolType storagePoolType) {
+        VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
+        Mockito.doReturn(0l).when(volumeInfo).getPoolId();
+        DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
+        Mockito.doReturn(0l).when(ds).getId();
+
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
+        volumeMap.put(volumeInfo, ds);
+
+        StoragePoolVO storagePool = Mockito.spy(new StoragePoolVO());
+        Mockito.doReturn(storagePoolType).when(storagePool).getPoolType();
+
+        Mockito.doReturn(storagePool).when(primaryDataStoreDao).findById(0l);
+        Mockito.doReturn(isManagedStorage).when(storagePool).isManaged();
+        return volumeMap;
+    }
+
+    @Test
+    public void getTemplateUuidTestTemplateIdNotNull() {
+        String expectedTemplateUuid = prepareTestGetTemplateUuid();
+        String templateUuid = kvmNonManagedStorageDataMotionStrategy.getTemplateUuid(0l);
+        Assert.assertEquals(expectedTemplateUuid, templateUuid);
+    }
+
+    @Test
+    public void getTemplateUuidTestTemplateIdNull() {
+        prepareTestGetTemplateUuid();
+        String templateUuid = kvmNonManagedStorageDataMotionStrategy.getTemplateUuid(null);
+        Assert.assertEquals(null, templateUuid);
+    }
+
+    private String prepareTestGetTemplateUuid() {
+        TemplateInfo templateImage = Mockito.mock(TemplateInfo.class);
+        String expectedTemplateUuid = "template uuid";
+        Mockito.when(templateImage.getUuid()).thenReturn(expectedTemplateUuid);
+        Mockito.doReturn(templateImage).when(templateDataFactory).getTemplate(0l, DataStoreRole.Image);
+        return expectedTemplateUuid;
+    }
+
+    @Test
+    public void configureMigrateDiskInfoTest() {
+        VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject());
+        Mockito.doReturn("volume path").when(srcVolumeInfo).getPath();
+        MigrateCommand.MigrateDiskInfo migrateDiskInfo = kvmNonManagedStorageDataMotionStrategy.configureMigrateDiskInfo(srcVolumeInfo, "destPath");
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.FILE, migrateDiskInfo.getDiskType());
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.QCOW2, migrateDiskInfo.getDriverType());
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.FILE, migrateDiskInfo.getSource());
+        Assert.assertEquals("destPath", migrateDiskInfo.getSourceText());
+        Assert.assertEquals("volume path", migrateDiskInfo.getSerialNumber());
+    }
+
+    @Test
+    public void generateDestPathTest() {
+        configureAndVerifygenerateDestPathTest(true, false);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void generateDestPathTestExpectCloudRuntimeException() {
+        configureAndVerifygenerateDestPathTest(false, false);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void generateDestPathTestExpectCloudRuntimeException2() {
+        configureAndVerifygenerateDestPathTest(false, true);
+    }
+
+    private void configureAndVerifygenerateDestPathTest(boolean answerResult, boolean answerIsNull) {
+        String uuid = "f3d49ecc-870c-475a-89fa-fd0124420a9b";
+        String destPath = "/var/lib/libvirt/images/";
+
+        VirtualMachineTO vmTO = Mockito.mock(VirtualMachineTO.class);
+        Mockito.when(vmTO.getName()).thenReturn("vmName");
+
+        VolumeVO srcVolume = Mockito.spy(new VolumeVO("name", 0l, 0l, 0l, 0l, 0l, "folder", "path", Storage.ProvisioningType.THIN, 0l, Volume.Type.ROOT));
+        StoragePoolVO destStoragePool = Mockito.spy(new StoragePoolVO());
+
+        VolumeInfo destVolumeInfo = Mockito.spy(new VolumeObject());
+        Mockito.doReturn(0l).when(destVolumeInfo).getTemplateId();
+        Mockito.doReturn(0l).when(destVolumeInfo).getId();
+        Mockito.doReturn(Volume.Type.ROOT).when(destVolumeInfo).getVolumeType();
+        Mockito.doReturn("name").when(destVolumeInfo).getName();
+        Mockito.doReturn(0l).when(destVolumeInfo).getSize();
+        Mockito.doReturn(uuid).when(destVolumeInfo).getUuid();
+
+        DiskOfferingVO diskOffering = Mockito.spy(new DiskOfferingVO());
+        Mockito.doReturn(0l).when(diskOffering).getId();
+        Mockito.doReturn(diskOffering).when(diskOfferingDao).findById(0l);
+        DiskProfile diskProfile = Mockito.spy(new DiskProfile(destVolumeInfo, diskOffering, HypervisorType.KVM));
+
+        String templateUuid = Mockito.doReturn("templateUuid").when(kvmNonManagedStorageDataMotionStrategy).getTemplateUuid(0l);
+        CreateCommand rootImageProvisioningCommand = new CreateCommand(diskProfile, templateUuid, destStoragePool, true);
+        CreateAnswer createAnswer = Mockito.spy(new CreateAnswer(rootImageProvisioningCommand, "details"));
+        Mockito.doReturn(answerResult).when(createAnswer).getResult();
+
+        VolumeTO volumeTo = Mockito.mock(VolumeTO.class);
+        Mockito.doReturn(destPath).when(volumeTo).getName();
+        Mockito.doReturn(volumeTo).when(createAnswer).getVolume();
+
+        if (answerIsNull) {
+            Mockito.doReturn(null).when(agentManager).easySend(0l, rootImageProvisioningCommand);
+        } else {
+            Mockito.doReturn(createAnswer).when(agentManager).easySend(0l, rootImageProvisioningCommand);
+        }
+
+        String generatedDestPath = kvmNonManagedStorageDataMotionStrategy.generateDestPath(vmTO, srcVolume, new HostVO("sourceHostUuid"), destStoragePool, destVolumeInfo);
+
+        Assert.assertEquals(destPath + uuid, generatedDestPath);
+    }
+
+    @Test
+    public void shouldMigrateVolumeTest() {
+        StoragePoolVO sourceStoragePool = Mockito.spy(new StoragePoolVO());
+        HostVO destHost = new HostVO("guid");
+        StoragePoolVO destStoragePool = new StoragePoolVO();
+        StoragePoolType[] storagePoolTypes = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypes.length; i++) {
+            Mockito.doReturn(storagePoolTypes[i]).when(sourceStoragePool).getPoolType();
+            boolean result = kvmNonManagedStorageDataMotionStrategy.shouldMigrateVolume(sourceStoragePool, destHost, destStoragePool);
+            if (storagePoolTypes[i] == StoragePoolType.Filesystem) {
+                Assert.assertTrue(result);
+            } else {
+                Assert.assertFalse(result);
+            }
+        }
+    }
+
+    @Test
+    public void sendCopyCommandTest() throws AgentUnavailableException, OperationTimedoutException {
+        configureAndTestSendCommandTest(null);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void sendCopyCommandTestThrowAgentUnavailableException() throws AgentUnavailableException, OperationTimedoutException {
+        configureAndTestSendCommandTest(AgentUnavailableException.class);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void sendCopyCommandTestThrowOperationTimedoutException() throws AgentUnavailableException, OperationTimedoutException {
+        configureAndTestSendCommandTest(OperationTimedoutException.class);
+    }
+
+    private void configureAndTestSendCommandTest(Class<? extends CloudException> exception) throws AgentUnavailableException, OperationTimedoutException {
+        Host destHost = new HostVO("guid");
+        TemplateObjectTO sourceTemplate = new TemplateObjectTO();
+        sourceTemplate.setName("name");
+        sourceTemplate.setId(0l);
+        TemplateObjectTO destTemplate = new TemplateObjectTO();
+        ImageStoreVO dataStoreVO = Mockito.mock(ImageStoreVO.class);
+        Mockito.when(dataStoreVO.getId()).thenReturn(0l);
+
+        ImageStoreEntity destDataStore = Mockito.mock(ImageStoreImpl.class);
+        Mockito.doReturn(0l).when(destDataStore).getId();
+
+        Answer copyCommandAnswer = Mockito.mock(Answer.class);
+
+        if (exception == null) {
+            Mockito.doReturn(copyCommandAnswer).when(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
+        } else {
+            Mockito.doThrow(exception).when(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
+        }
+
+        Mockito.doNothing().when(kvmNonManagedStorageDataMotionStrategy).logInCaseOfTemplateCopyFailure(Mockito.any(Answer.class), Mockito.any(TemplateObjectTO.class),
+                Mockito.any(DataStore.class));
+
+        kvmNonManagedStorageDataMotionStrategy.sendCopyCommand(destHost, sourceTemplate, destTemplate, destDataStore);
+
+        InOrder verifyInOrder = Mockito.inOrder(virtualMachineManager, agentManager, kvmNonManagedStorageDataMotionStrategy);
+
+        verifyInOrder.verify(virtualMachineManager).getExecuteInSequence(HypervisorType.KVM);
+        verifyInOrder.verify(agentManager).send(Mockito.anyLong(), Mockito.any(CopyCommand.class));
+        verifyInOrder.verify(kvmNonManagedStorageDataMotionStrategy).logInCaseOfTemplateCopyFailure(Mockito.any(Answer.class), Mockito.any(TemplateObjectTO.class),
+                Mockito.any(DataStore.class));
+    }
+
+    @Test
+    public void copyTemplateToTargetStorageIfNeededTestTemplateAlreadyOnTargetHost() throws AgentUnavailableException, OperationTimedoutException {
+        Answer copyCommandAnswer = Mockito.mock(Answer.class);
+        Mockito.when(copyCommandAnswer.getResult()).thenReturn(true);
+        configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), StoragePoolType.Filesystem, 0);
+    }
+
+    @Test
+    public void migrateTemplateToTargetStorageIfNeededTestTemplateNotOnTargetHost() throws AgentUnavailableException, OperationTimedoutException {
+        configureAndTestcopyTemplateToTargetStorageIfNeeded(null, StoragePoolType.Filesystem, 1);
+    }
+
+    @Test
+    public void migrateTemplateToTargetStorageIfNeededTestNonDesiredStoragePoolType() throws AgentUnavailableException, OperationTimedoutException {
+        StoragePoolType[] storagePoolTypeArray = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypeArray.length; i++) {
+            if (storagePoolTypeArray[i] == StoragePoolType.Filesystem) {
+                continue;
+            }
+            configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), storagePoolTypeArray[i], 0);
+        }
+    }
+
+    private void configureAndTestcopyTemplateToTargetStorageIfNeeded(VMTemplateStoragePoolVO vmTemplateStoragePoolVO, StoragePoolType storagePoolType, int times) {
+        DataStore destDataStore = Mockito.mock(DataStore.class);
+        Host destHost = Mockito.mock(Host.class);
+
+        VolumeInfo srcVolumeInfo = Mockito.mock(VolumeInfo.class);
+        Mockito.when(srcVolumeInfo.getTemplateId()).thenReturn(0l);
+
+        StoragePool srcStoragePool = Mockito.mock(StoragePool.class);
+
+        VolumeInfo destVolumeInfo = Mockito.mock(VolumeInfo.class);
+        Mockito.when(volumeDataFactory.getVolume(Mockito.anyLong(), Mockito.any(DataStore.class))).thenReturn(destVolumeInfo);
+
+        StoragePool destStoragePool = Mockito.mock(StoragePool.class);
+        Mockito.when(destStoragePool.getId()).thenReturn(0l);
+        Mockito.when(destStoragePool.getPoolType()).thenReturn(storagePoolType);
+
+        DataStore sourceTemplateDataStore = Mockito.mock(DataStore.class);
+        Mockito.when(sourceTemplateDataStore.getName()).thenReturn("sourceTemplateName");
+
+        TemplateInfo sourceTemplateInfo = Mockito.mock(TemplateInfo.class);
+        Mockito.when(sourceTemplateInfo.getInstallPath()).thenReturn("installPath");
+        Mockito.when(sourceTemplateInfo.getUuid()).thenReturn("uuid");
+        Mockito.when(sourceTemplateInfo.getId()).thenReturn(0l);
+        Mockito.when(sourceTemplateInfo.getUrl()).thenReturn("url");
+        Mockito.when(sourceTemplateInfo.getDisplayText()).thenReturn("display text");
+        Mockito.when(sourceTemplateInfo.getChecksum()).thenReturn("checksum");
+        Mockito.when(sourceTemplateInfo.isRequiresHvm()).thenReturn(true);
+        Mockito.when(sourceTemplateInfo.getAccountId()).thenReturn(0l);
+        Mockito.when(sourceTemplateInfo.getUniqueName()).thenReturn("unique name");
+        Mockito.when(sourceTemplateInfo.getFormat()).thenReturn(ImageFormat.QCOW2);
+        Mockito.when(sourceTemplateInfo.getSize()).thenReturn(0l);
+        Mockito.when(sourceTemplateInfo.getHypervisorType()).thenReturn(HypervisorType.KVM);
+
+        Mockito.when(vmTemplatePoolDao.findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong())).thenReturn(vmTemplateStoragePoolVO);
+        Mockito.when(dataStoreManagerImpl.getImageStore(Mockito.anyLong())).thenReturn(sourceTemplateDataStore);
+        Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore))).thenReturn(sourceTemplateInfo);
+        Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore))).thenReturn(sourceTemplateInfo);
+        kvmNonManagedStorageDataMotionStrategy.copyTemplateToTargetFilesystemStorageIfNeeded(srcVolumeInfo, srcStoragePool, destDataStore, destStoragePool, destHost);
+        Mockito.doNothing().when(kvmNonManagedStorageDataMotionStrategy).updateTemplateReferenceIfSuccessfulCopy(Mockito.any(VolumeInfo.class), Mockito.any(StoragePool.class),
+                Mockito.any(TemplateInfo.class), Mockito.any(DataStore.class));
+
+        InOrder verifyInOrder = Mockito.inOrder(vmTemplatePoolDao, dataStoreManagerImpl, templateDataFactory, kvmNonManagedStorageDataMotionStrategy);
+        verifyInOrder.verify(vmTemplatePoolDao, Mockito.times(1)).findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong());
+        verifyInOrder.verify(dataStoreManagerImpl, Mockito.times(times)).getImageStore(Mockito.anyLong());
+        verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore));
+        verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore));
+        verifyInOrder.verify(kvmNonManagedStorageDataMotionStrategy, Mockito.times(times)).sendCopyCommand(Mockito.eq(destHost), Mockito.any(TemplateObjectTO.class),
+                Mockito.any(TemplateObjectTO.class), Mockito.eq(destDataStore));
+    }
+}
diff --git a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
new file mode 100644
index 0000000..d76ff27
--- /dev/null
+++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.motion;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.HostVO;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ImageStore;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.VolumeVO;
+
+@RunWith(MockitoJUnitRunner.class)
+public class StorageSystemDataMotionStrategyTest {
+
+    @Spy
+    @InjectMocks
+    private StorageSystemDataMotionStrategy storageSystemDataMotionStrategy;
+
+    @Mock
+    private VolumeObject volumeObjectSource;
+    @Mock
+    private DataObject dataObjectDestination;
+    @Mock
+    private PrimaryDataStore primaryDataStoreSourceStore;
+    @Mock
+    private ImageStore destinationStore;
+    @Mock
+    private PrimaryDataStoreDao primaryDataStoreDao;
+
+    @Before
+    public void setUp() throws Exception {
+        primaryDataStoreSourceStore = mock(PrimaryDataStoreImpl.class);
+        destinationStore = mock(ImageStoreImpl.class);
+        volumeObjectSource = mock(VolumeObject.class);
+        dataObjectDestination = mock(VolumeObject.class);
+
+        initMocks(storageSystemDataMotionStrategy);
+    }
+
+    @Test
+    public void cantHandleSecondary() {
+        doReturn(primaryDataStoreSourceStore).when(volumeObjectSource).getDataStore();
+        doReturn(DataStoreRole.Primary).when(primaryDataStoreSourceStore).getRole();
+        doReturn(destinationStore).when(dataObjectDestination).getDataStore();
+        doReturn(DataStoreRole.Image).when((DataStore)destinationStore).getRole();
+        doReturn(primaryDataStoreSourceStore).when(volumeObjectSource).getDataStore();
+        doReturn(destinationStore).when(dataObjectDestination).getDataStore();
+        StoragePoolVO storeVO = new StoragePoolVO();
+        doReturn(storeVO).when(primaryDataStoreDao).findById(0l);
+
+        assertTrue(storageSystemDataMotionStrategy.canHandle(volumeObjectSource, dataObjectDestination) == StrategyPriority.CANT_HANDLE);
+    }
+
+    @Test
+    public void internalCanHandleTestAllStoragePoolsAreManaged() {
+        configureAndTestInternalCanHandle(true, true, StrategyPriority.HIGHEST);
+    }
+
+    @Test
+    public void internalCanHandleTestFirstStoragePoolsIsManaged() {
+        configureAndTestInternalCanHandle(false, true, StrategyPriority.HIGHEST);
+    }
+
+    @Test
+    public void internalCanHandleTestSecondStoragePoolsIsManaged() {
+        configureAndTestInternalCanHandle(true, false, StrategyPriority.HIGHEST);
+    }
+
+    @Test
+    public void internalCanHandleTestNoStoragePoolsIsManaged() {
+        configureAndTestInternalCanHandle(false, false, StrategyPriority.CANT_HANDLE);
+    }
+
+    private void configureAndTestInternalCanHandle(boolean sPool0IsManaged, boolean sPool1IsManaged, StrategyPriority expectedStrategyPriority) {
+        VolumeObject volumeInfo = Mockito.spy(new VolumeObject());
+        Mockito.doReturn(0l).when(volumeInfo).getPoolId();
+
+        DataStore ds = Mockito.spy(new PrimaryDataStoreImpl());
+        Mockito.doReturn(1l).when(ds).getId();
+
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<>();
+        volumeMap.put(volumeInfo, ds);
+
+        StoragePoolVO storagePool0 = Mockito.spy(new StoragePoolVO());
+        Mockito.doReturn(sPool0IsManaged).when(storagePool0).isManaged();
+        StoragePoolVO storagePool1 = Mockito.spy(new StoragePoolVO());
+        Mockito.doReturn(sPool1IsManaged).when(storagePool1).isManaged();
+
+        Mockito.doReturn(storagePool0).when(primaryDataStoreDao).findById(0l);
+        Mockito.doReturn(storagePool1).when(primaryDataStoreDao).findById(1l);
+
+        StrategyPriority strategyPriority = storageSystemDataMotionStrategy.internalCanHandle(volumeMap);
+
+        Assert.assertEquals(expectedStrategyPriority, strategyPriority);
+    }
+
+    @Test
+    public void isStoragePoolTypeOfFileTest() {
+        StoragePoolVO sourceStoragePool = Mockito.spy(new StoragePoolVO());
+        StoragePoolType[] storagePoolTypeArray = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypeArray.length; i++) {
+            Mockito.doReturn(storagePoolTypeArray[i]).when(sourceStoragePool).getPoolType();
+            boolean result = storageSystemDataMotionStrategy.isStoragePoolTypeOfFile(sourceStoragePool);
+            if (sourceStoragePool.getPoolType() == StoragePoolType.Filesystem) {
+                Assert.assertTrue(result);
+            } else {
+                Assert.assertFalse(result);
+            }
+        }
+    }
+
+    @Test
+    public void generateDestPathTest() {
+        VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject());
+        HostVO destHost = new HostVO("guid");
+        Mockito.doReturn("iScsiName").when(destVolumeInfo).get_iScsiName();
+        Mockito.doReturn(0l).when(destVolumeInfo).getPoolId();
+        Mockito.doReturn("expected").when(storageSystemDataMotionStrategy).connectHostToVolume(destHost, 0l, "iScsiName");
+
+        String expected = storageSystemDataMotionStrategy.generateDestPath(Mockito.mock(VirtualMachineTO.class), Mockito.mock(VolumeVO.class), destHost,
+                Mockito.mock(StoragePoolVO.class), destVolumeInfo);
+
+        Assert.assertEquals(expected, "expected");
+        Mockito.verify(storageSystemDataMotionStrategy).connectHostToVolume(destHost, 0l, "iScsiName");
+    }
+
+    @Test
+    public void configureMigrateDiskInfoTest() {
+        VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject());
+        Mockito.doReturn("volume path").when(srcVolumeInfo).getPath();
+        MigrateCommand.MigrateDiskInfo migrateDiskInfo = storageSystemDataMotionStrategy.configureMigrateDiskInfo(srcVolumeInfo, "destPath");
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DiskType.BLOCK, migrateDiskInfo.getDiskType());
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.DriverType.RAW, migrateDiskInfo.getDriverType());
+        Assert.assertEquals(MigrateCommand.MigrateDiskInfo.Source.DEV, migrateDiskInfo.getSource());
+        Assert.assertEquals("destPath", migrateDiskInfo.getSourceText());
+        Assert.assertEquals("volume path", migrateDiskInfo.getSerialNumber());
+    }
+
+    @Test
+    public void setVolumePathTest() {
+        VolumeVO volume = new VolumeVO("name", 0l, 0l, 0l, 0l, 0l, "folder", "path", Storage.ProvisioningType.THIN, 0l, Volume.Type.ROOT);
+        String volumePath = "iScsiName";
+        volume.set_iScsiName(volumePath);
+
+        storageSystemDataMotionStrategy.setVolumePath(volume);
+
+        Assert.assertEquals(volumePath, volume.getPath());
+    }
+
+    @Test
+    public void shouldMigrateVolumeTest() {
+        StoragePoolVO sourceStoragePool = Mockito.spy(new StoragePoolVO());
+        HostVO destHost = new HostVO("guid");
+        StoragePoolVO destStoragePool = new StoragePoolVO();
+        StoragePoolType[] storagePoolTypes = StoragePoolType.values();
+        for (int i = 0; i < storagePoolTypes.length; i++) {
+            Mockito.doReturn(storagePoolTypes[i]).when(sourceStoragePool).getPoolType();
+            boolean result = storageSystemDataMotionStrategy.shouldMigrateVolume(sourceStoragePool, destHost, destStoragePool);
+            Assert.assertTrue(result);
+        }
+    }
+}
diff --git a/engine/storage/datamotion/test/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java b/engine/storage/datamotion/test/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
deleted file mode 100644
index ec85f7d..0000000
--- a/engine/storage/datamotion/test/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategyTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.motion;
-
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ImageStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-@RunWith(MockitoJUnitRunner.class)
-public class StorageSystemDataMotionStrategyTest {
-
-    @Mock
-    VolumeObject source;
-    @Mock
-    DataObject destination;
-    @Mock
-    PrimaryDataStore sourceStore;
-    @Mock
-    ImageStore destinationStore;
-
-    @InjectMocks
-    DataMotionStrategy strategy = new StorageSystemDataMotionStrategy();
-    @Mock
-    PrimaryDataStoreDao _storagePoolDao;
-
-    @Before public void setUp() throws Exception {
-        sourceStore = mock(PrimaryDataStoreImpl.class);
-        destinationStore = mock(ImageStoreImpl.class);
-        source = mock(VolumeObject.class);
-        destination = mock(VolumeObject.class);
-
-                initMocks(strategy);
-    }
-
-    @Test
-    public void cantHandleSecondary() {
-        doReturn(sourceStore).when(source).getDataStore();
-        doReturn(DataStoreRole.Primary).when(sourceStore).getRole();
-        doReturn(destinationStore).when(destination).getDataStore();
-        doReturn(DataStoreRole.Image).when((DataStore)destinationStore).getRole();
-        doReturn(sourceStore).when(source).getDataStore();
-        doReturn(destinationStore).when(destination).getDataStore();
-        StoragePoolVO storeVO = new StoragePoolVO();
-        doReturn(storeVO).when(_storagePoolDao).findById(0l);
-
-        assertTrue(strategy.canHandle(source,destination) == StrategyPriority.CANT_HANDLE);
-    }
-}
\ No newline at end of file
diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml
index 420a3db5..deb5fb0 100644
--- a/engine/storage/image/pom.xml
+++ b/engine/storage/image/pom.xml
@@ -1,29 +1,37 @@
-<!-- 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. -->
+<!--
+  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-engine-storage-image</artifactId>
-  <name>Apache CloudStack Engine Storage Image Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-storage-image</artifactId>
+    <name>Apache CloudStack Engine Storage Image Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
rename to engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
rename to engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
rename to engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
rename to engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java
new file mode 100644
index 0000000..25f27a2
--- /dev/null
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java
@@ -0,0 +1,526 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.image.store;
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import com.cloud.agent.api.storage.CreateDatadiskTemplateAnswer;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+
+import com.google.common.base.Strings;
+
+@SuppressWarnings("serial")
+public class TemplateObject implements TemplateInfo {
+    private static final Logger s_logger = Logger.getLogger(TemplateObject.class);
+    private VMTemplateVO imageVO;
+    private DataStore dataStore;
+    private String url;
+    private String installPath; // temporarily set installPath before passing to resource for entries with empty installPath for object store migration case
+    @Inject
+    VMTemplateDao imageDao;
+    @Inject
+    ObjectInDataStoreManager objectInStoreMgr;
+    @Inject
+    VMTemplatePoolDao templatePoolDao;
+    @Inject
+    TemplateDataStoreDao templateStoreDao;
+
+    public TemplateObject() {
+    }
+
+    protected void configure(VMTemplateVO template, DataStore dataStore) {
+        imageVO = template;
+        this.dataStore = dataStore;
+    }
+
+    public static TemplateObject getTemplate(VMTemplateVO vo, DataStore store) {
+        TemplateObject to = ComponentContext.inject(TemplateObject.class);
+        to.configure(vo, store);
+        return to;
+    }
+
+    public void setSize(Long size) {
+        imageVO.setSize(size);
+    }
+
+    public VMTemplateVO getImage() {
+        return imageVO;
+    }
+
+    @Override
+    public DataStore getDataStore() {
+        return dataStore;
+    }
+
+    @Override
+    public String getUniqueName() {
+        return imageVO.getUniqueName();
+    }
+
+    @Override
+    public long getId() {
+        return imageVO.getId();
+    }
+
+    @Override
+    public State getState() {
+        return imageVO.getState();
+    }
+
+    @Override
+    public String getUuid() {
+        return imageVO.getUuid();
+    }
+
+    @Override
+    public String getUri() {
+        if (url != null) {
+            return url;
+        }
+        VMTemplateVO image = imageDao.findById(imageVO.getId());
+
+        return image.getUrl();
+
+    }
+
+    @Override
+    public Long getSize() {
+        if (dataStore == null) {
+            return imageVO.getSize();
+        }
+
+        /*
+         *
+         * // If the template that was passed into this allocator is not
+         * installed in the storage pool, // add 3 * (template size on secondary
+         * storage) to the running total VMTemplateHostVO templateHostVO =
+         * _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null);
+         *
+         * if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO =
+         * _swiftMgr.findByTmpltId(templateForVmCreation.getId()); if
+         * (templateSwiftVO != null) { long templateSize =
+         * templateSwiftVO.getPhysicalSize(); if (templateSize == 0) {
+         * templateSize = templateSwiftVO.getSize(); } totalAllocatedSize +=
+         * (templateSize + _extraBytesPerVolume); } } else { long templateSize =
+         * templateHostVO.getPhysicalSize(); if ( templateSize == 0 ){
+         * templateSize = templateHostVO.getSize(); } totalAllocatedSize +=
+         * (templateSize + _extraBytesPerVolume); }
+         */
+        VMTemplateVO image = imageDao.findById(imageVO.getId());
+        return image.getSize();
+    }
+
+    @Override
+    public DataObjectType getType() {
+        return DataObjectType.TEMPLATE;
+    }
+
+    @Override
+    public ImageFormat getFormat() {
+        return imageVO.getFormat();
+    }
+
+    @Override
+    public void processEvent(ObjectInDataStoreStateMachine.Event event) {
+        try {
+            objectInStoreMgr.update(this, event);
+        } catch (NoTransitionException e) {
+            throw new CloudRuntimeException("Failed to update state", e);
+        } catch (ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Failed to update state", e);
+        } finally {
+            // in case of OperationFailed, expunge the entry
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+        }
+    }
+
+    @Override
+    public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
+        try {
+            if (getDataStore().getRole() == DataStoreRole.Primary) {
+                if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
+                    VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(getDataStore().getId(), getId());
+                    templatePoolRef.setDownloadPercent(100);
+
+                    setTemplateSizeIfNeeded(newTemplate, templatePoolRef);
+
+                    templatePoolRef.setDownloadState(Status.DOWNLOADED);
+
+                    setDownloadPathIfNeeded(newTemplate, templatePoolRef);
+
+                    setInstallPathIfNeeded(newTemplate, templatePoolRef);
+
+                    templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
+                }
+            } else if (getDataStore().getRole() == DataStoreRole.Image || getDataStore().getRole() == DataStoreRole.ImageCache) {
+                if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
+                    TemplateDataStoreVO templateStoreRef = templateStoreDao.findByStoreTemplate(getDataStore().getId(), getId());
+                    templateStoreRef.setInstallPath(newTemplate.getPath());
+                    templateStoreRef.setDownloadPercent(100);
+                    templateStoreRef.setDownloadState(Status.DOWNLOADED);
+                    templateStoreRef.setSize(newTemplate.getSize());
+                    if (newTemplate.getPhysicalSize() != null) {
+                        templateStoreRef.setPhysicalSize(newTemplate.getPhysicalSize());
+                    }
+                    templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
+                    if (getDataStore().getRole() == DataStoreRole.Image) {
+                        VMTemplateVO templateVO = imageDao.findById(getId());
+                        if (newTemplate.getFormat() != null) {
+                            templateVO.setFormat(newTemplate.getFormat());
+                        }
+                        if (newTemplate.getName() != null) {
+                            // For template created from snapshot, template name is determine by resource code.
+                            templateVO.setUniqueName(newTemplate.getName());
+                        }
+                        if (newTemplate.getHypervisorType() != null) {
+                            templateVO.setHypervisorType(newTemplate.getHypervisorType());
+                        }
+                        templateVO.setSize(newTemplate.getSize());
+                        imageDao.update(templateVO.getId(), templateVO);
+                    }
+                } else if (answer instanceof CreateDatadiskTemplateAnswer) {
+                    CreateDatadiskTemplateAnswer createAnswer = (CreateDatadiskTemplateAnswer)answer;
+                    TemplateObjectTO dataDiskTemplate = createAnswer.getDataDiskTemplate();
+                    TemplateDataStoreVO templateStoreRef = templateStoreDao.findByStoreTemplate(getDataStore().getId(), dataDiskTemplate.getId());
+                    templateStoreRef.setInstallPath(dataDiskTemplate.getPath());
+                    templateStoreRef.setDownloadPercent(100);
+                    templateStoreRef.setDownloadState(Status.DOWNLOADED);
+                    templateStoreRef.setSize(dataDiskTemplate.getSize());
+                    templateStoreRef.setPhysicalSize(dataDiskTemplate.getPhysicalSize());
+                    templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
+                }
+            }
+            objectInStoreMgr.update(this, event);
+        } catch (NoTransitionException e) {
+            s_logger.debug("failed to update state", e);
+            throw new CloudRuntimeException("Failed to update state" + e.toString());
+        } catch (Exception ex) {
+            s_logger.debug("failed to process event and answer", ex);
+            objectInStoreMgr.delete(this);
+            throw new CloudRuntimeException("Failed to process event", ex);
+        } finally {
+            // in case of OperationFailed, expunge the entry
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+        }
+    }
+
+    /**
+     * In the case of managed storage, the install path may already be specified (by the storage plug-in), so do not overwrite it.
+     */
+    private void setInstallPathIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
+        if (Strings.isNullOrEmpty(templatePoolRef.getInstallPath())) {
+            templatePoolRef.setInstallPath(template.getPath());
+        }
+    }
+
+    /**
+     * In the case of managed storage, the local download path may already be specified (by the storage plug-in), so do not overwrite it.
+     */
+    private void setDownloadPathIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
+        if (Strings.isNullOrEmpty(templatePoolRef.getLocalDownloadPath())) {
+            templatePoolRef.setLocalDownloadPath(template.getPath());
+        }
+    }
+
+    /**
+     *  In the case of managed storage, the template size may already be specified (by the storage plug-in), so do not overwrite it.
+     */
+    private void setTemplateSizeIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
+        if (templatePoolRef.getTemplateSize() == 0 && template.getSize() != null) {
+            templatePoolRef.setTemplateSize(template.getSize());
+        }
+    }
+
+    @Override
+    public void incRefCount() {
+        if (dataStore == null) {
+            return;
+        }
+
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
+            store.incrRefCnt();
+            store.setLastUpdated(new Date());
+            templateStoreDao.update(store.getId(), store);
+        }
+    }
+
+    @Override
+    public void decRefCount() {
+        if (dataStore == null) {
+            return;
+        }
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
+            store.decrRefCnt();
+            store.setLastUpdated(new Date());
+            templateStoreDao.update(store.getId(), store);
+        }
+    }
+
+    @Override
+    public Long getRefCount() {
+        if (dataStore == null) {
+            return null;
+        }
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
+            return store.getRefCnt();
+        }
+        return null;
+    }
+
+    @Override
+    public DataTO getTO() {
+        DataTO to = null;
+        if (dataStore == null) {
+            to = new TemplateObjectTO(this);
+        } else {
+            to = dataStore.getDriver().getTO(this);
+            if (to == null) {
+                to = new TemplateObjectTO(this);
+            }
+        }
+
+        return to;
+    }
+
+    @Override
+    public String getInstallPath() {
+        if (installPath != null) {
+            return installPath;
+        }
+
+        if (dataStore == null) {
+            return null;
+        }
+
+        DataObjectInStore obj = objectInStoreMgr.findObject(this, dataStore);
+
+        return obj != null ? obj.getInstallPath() : null;
+    }
+
+    @Override
+    public boolean isDirectDownload() {
+        if (this.imageVO == null) {
+            return false;
+        }
+        return this.imageVO.isDirectDownload();
+    }
+
+    public void setInstallPath(String installPath) {
+        this.installPath = installPath;
+    }
+
+    @Override
+    public long getAccountId() {
+        return imageVO.getAccountId();
+    }
+
+    @Override
+    public boolean isFeatured() {
+        return imageVO.isFeatured();
+    }
+
+    @Override
+    public boolean isPublicTemplate() {
+        return imageVO.isPublicTemplate();
+    }
+
+    @Override
+    public boolean isExtractable() {
+        return imageVO.isExtractable();
+    }
+
+    @Override
+    public String getName() {
+        return imageVO.getName();
+    }
+
+    @Override
+    public boolean isRequiresHvm() {
+        return imageVO.isRequiresHvm();
+    }
+
+    @Override
+    public String getDisplayText() {
+        return imageVO.getDisplayText();
+    }
+
+    @Override
+    public boolean isEnablePassword() {
+        return imageVO.isEnablePassword();
+    }
+
+    @Override
+    public boolean isEnableSshKey() {
+        return imageVO.isEnableSshKey();
+    }
+
+    @Override
+    public boolean isCrossZones() {
+        return imageVO.isCrossZones();
+    }
+
+    @Override
+    public Date getCreated() {
+        return imageVO.getCreated();
+    }
+
+    @Override
+    public long getGuestOSId() {
+        return imageVO.getGuestOSId();
+    }
+
+    @Override
+    public boolean isBootable() {
+        return imageVO.isBootable();
+    }
+
+    @Override
+    public TemplateType getTemplateType() {
+        return imageVO.getTemplateType();
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return imageVO.getHypervisorType();
+    }
+
+    @Override
+    public int getBits() {
+        return imageVO.getBits();
+    }
+
+    @Override
+    public String getUrl() {
+        if (url != null) {
+            return url;
+        }
+        return imageVO.getUrl();
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @Override
+    public String getChecksum() {
+        return imageVO.getChecksum();
+    }
+
+    @Override
+    public Long getSourceTemplateId() {
+        return imageVO.getSourceTemplateId();
+    }
+
+    @Override
+    public Long getParentTemplateId() {
+        return imageVO.getParentTemplateId();
+    }
+
+    @Override
+    public String getTemplateTag() {
+        return imageVO.getTemplateTag();
+    }
+
+    @Override
+    public Map<String, String> getDetails() {
+        return imageVO.getDetails();
+    }
+
+    @Override
+    public boolean isDynamicallyScalable() {
+        return false;
+    }
+
+    @Override
+    public long getDomainId() {
+        return imageVO.getDomainId();
+    }
+
+    @Override
+    public boolean delete() {
+        if (dataStore != null) {
+            return dataStore.delete(this);
+        }
+        return true;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return VirtualMachineTemplate.class;
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Date getUpdated() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java
similarity index 100%
rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java
rename to engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java
diff --git a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml b/engine/storage/image/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
similarity index 100%
rename from engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
rename to engine/storage/image/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
deleted file mode 100644
index 9b9b711..0000000
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.image.store;
-
-import java.util.Date;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import com.cloud.agent.api.storage.CreateDatadiskTemplateAnswer;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-
-import com.google.common.base.Strings;
-
-@SuppressWarnings("serial")
-public class TemplateObject implements TemplateInfo {
-    private static final Logger s_logger = Logger.getLogger(TemplateObject.class);
-    private VMTemplateVO imageVO;
-    private DataStore dataStore;
-    private String url;
-    private String installPath; // temporarily set installPath before passing to resource for entries with empty installPath for object store migration case
-    @Inject
-    VMTemplateDao imageDao;
-    @Inject
-    ObjectInDataStoreManager objectInStoreMgr;
-    @Inject
-    VMTemplatePoolDao templatePoolDao;
-    @Inject
-    TemplateDataStoreDao templateStoreDao;
-
-    public TemplateObject() {
-    }
-
-    protected void configure(VMTemplateVO template, DataStore dataStore) {
-        imageVO = template;
-        this.dataStore = dataStore;
-    }
-
-    public static TemplateObject getTemplate(VMTemplateVO vo, DataStore store) {
-        TemplateObject to = ComponentContext.inject(TemplateObject.class);
-        to.configure(vo, store);
-        return to;
-    }
-
-    public void setSize(Long size) {
-        imageVO.setSize(size);
-    }
-
-    public VMTemplateVO getImage() {
-        return imageVO;
-    }
-
-    @Override
-    public DataStore getDataStore() {
-        return dataStore;
-    }
-
-    @Override
-    public String getUniqueName() {
-        return imageVO.getUniqueName();
-    }
-
-    @Override
-    public long getId() {
-        return imageVO.getId();
-    }
-
-    @Override
-    public State getState() {
-        return imageVO.getState();
-    }
-
-    @Override
-    public String getUuid() {
-        return imageVO.getUuid();
-    }
-
-    @Override
-    public String getUri() {
-        if (url != null) {
-            return url;
-        }
-        VMTemplateVO image = imageDao.findById(imageVO.getId());
-
-        return image.getUrl();
-
-    }
-
-    @Override
-    public Long getSize() {
-        if (dataStore == null) {
-            return imageVO.getSize();
-        }
-
-        /*
-         *
-         * // If the template that was passed into this allocator is not
-         * installed in the storage pool, // add 3 * (template size on secondary
-         * storage) to the running total VMTemplateHostVO templateHostVO =
-         * _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null);
-         *
-         * if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO =
-         * _swiftMgr.findByTmpltId(templateForVmCreation.getId()); if
-         * (templateSwiftVO != null) { long templateSize =
-         * templateSwiftVO.getPhysicalSize(); if (templateSize == 0) {
-         * templateSize = templateSwiftVO.getSize(); } totalAllocatedSize +=
-         * (templateSize + _extraBytesPerVolume); } } else { long templateSize =
-         * templateHostVO.getPhysicalSize(); if ( templateSize == 0 ){
-         * templateSize = templateHostVO.getSize(); } totalAllocatedSize +=
-         * (templateSize + _extraBytesPerVolume); }
-         */
-        VMTemplateVO image = imageDao.findById(imageVO.getId());
-        return image.getSize();
-    }
-
-    @Override
-    public DataObjectType getType() {
-        return DataObjectType.TEMPLATE;
-    }
-
-    @Override
-    public ImageFormat getFormat() {
-        return imageVO.getFormat();
-    }
-
-    @Override
-    public void processEvent(ObjectInDataStoreStateMachine.Event event) {
-        try {
-            objectInStoreMgr.update(this, event);
-        } catch (NoTransitionException e) {
-            throw new CloudRuntimeException("Failed to update state", e);
-        } catch (ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Failed to update state", e);
-        } finally {
-            // in case of OperationFailed, expunge the entry
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-        }
-    }
-
-    @Override
-    public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
-        try {
-            if (getDataStore().getRole() == DataStoreRole.Primary) {
-                if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
-                    VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(getDataStore().getId(), getId());
-                    templatePoolRef.setDownloadPercent(100);
-
-                    setTemplateSizeIfNeeded(newTemplate, templatePoolRef);
-
-                    templatePoolRef.setDownloadState(Status.DOWNLOADED);
-
-                    setDownloadPathIfNeeded(newTemplate, templatePoolRef);
-
-                    setInstallPathIfNeeded(newTemplate, templatePoolRef);
-
-                    templatePoolDao.update(templatePoolRef.getId(), templatePoolRef);
-                }
-            } else if (getDataStore().getRole() == DataStoreRole.Image || getDataStore().getRole() == DataStoreRole.ImageCache) {
-                if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
-                    TemplateDataStoreVO templateStoreRef = templateStoreDao.findByStoreTemplate(getDataStore().getId(), getId());
-                    templateStoreRef.setInstallPath(newTemplate.getPath());
-                    templateStoreRef.setDownloadPercent(100);
-                    templateStoreRef.setDownloadState(Status.DOWNLOADED);
-                    templateStoreRef.setSize(newTemplate.getSize());
-                    if (newTemplate.getPhysicalSize() != null) {
-                        templateStoreRef.setPhysicalSize(newTemplate.getPhysicalSize());
-                    }
-                    templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
-                    if (getDataStore().getRole() == DataStoreRole.Image) {
-                        VMTemplateVO templateVO = imageDao.findById(getId());
-                        if (newTemplate.getFormat() != null) {
-                            templateVO.setFormat(newTemplate.getFormat());
-                        }
-                        if (newTemplate.getName() != null) {
-                            // For template created from snapshot, template name is determine by resource code.
-                            templateVO.setUniqueName(newTemplate.getName());
-                        }
-                        if (newTemplate.getHypervisorType() != null) {
-                            templateVO.setHypervisorType(newTemplate.getHypervisorType());
-                        }
-                        templateVO.setSize(newTemplate.getSize());
-                        imageDao.update(templateVO.getId(), templateVO);
-                    }
-                } else if (answer instanceof CreateDatadiskTemplateAnswer) {
-                    CreateDatadiskTemplateAnswer createAnswer = (CreateDatadiskTemplateAnswer)answer;
-                    TemplateObjectTO dataDiskTemplate = createAnswer.getDataDiskTemplate();
-                    TemplateDataStoreVO templateStoreRef = templateStoreDao.findByStoreTemplate(getDataStore().getId(), dataDiskTemplate.getId());
-                    templateStoreRef.setInstallPath(dataDiskTemplate.getPath());
-                    templateStoreRef.setDownloadPercent(100);
-                    templateStoreRef.setDownloadState(Status.DOWNLOADED);
-                    templateStoreRef.setSize(dataDiskTemplate.getSize());
-                    templateStoreRef.setPhysicalSize(dataDiskTemplate.getPhysicalSize());
-                    templateStoreDao.update(templateStoreRef.getId(), templateStoreRef);
-                }
-            }
-            objectInStoreMgr.update(this, event);
-        } catch (NoTransitionException e) {
-            s_logger.debug("failed to update state", e);
-            throw new CloudRuntimeException("Failed to update state" + e.toString());
-        } catch (Exception ex) {
-            s_logger.debug("failed to process event and answer", ex);
-            objectInStoreMgr.delete(this);
-            throw new CloudRuntimeException("Failed to process event", ex);
-        } finally {
-            // in case of OperationFailed, expunge the entry
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-        }
-    }
-
-    /**
-     * In the case of managed storage, the install path may already be specified (by the storage plug-in), so do not overwrite it.
-     */
-    private void setInstallPathIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
-        if (Strings.isNullOrEmpty(templatePoolRef.getInstallPath())) {
-            templatePoolRef.setInstallPath(template.getPath());
-        }
-    }
-
-    /**
-     * In the case of managed storage, the local download path may already be specified (by the storage plug-in), so do not overwrite it.
-     */
-    private void setDownloadPathIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
-        if (Strings.isNullOrEmpty(templatePoolRef.getLocalDownloadPath())) {
-            templatePoolRef.setLocalDownloadPath(template.getPath());
-        }
-    }
-
-    /**
-     *  In the case of managed storage, the template size may already be specified (by the storage plug-in), so do not overwrite it.
-     */
-    private void setTemplateSizeIfNeeded(TemplateObjectTO template, VMTemplateStoragePoolVO templatePoolRef) {
-        if (templatePoolRef.getTemplateSize() == 0 && template.getSize() != null) {
-            templatePoolRef.setTemplateSize(template.getSize());
-        }
-    }
-
-    @Override
-    public void incRefCount() {
-        if (dataStore == null) {
-            return;
-        }
-
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
-            store.incrRefCnt();
-            store.setLastUpdated(new Date());
-            templateStoreDao.update(store.getId(), store);
-        }
-    }
-
-    @Override
-    public void decRefCount() {
-        if (dataStore == null) {
-            return;
-        }
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
-            store.decrRefCnt();
-            store.setLastUpdated(new Date());
-            templateStoreDao.update(store.getId(), store);
-        }
-    }
-
-    @Override
-    public Long getRefCount() {
-        if (dataStore == null) {
-            return null;
-        }
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), getId());
-            return store.getRefCnt();
-        }
-        return null;
-    }
-
-    @Override
-    public DataTO getTO() {
-        DataTO to = null;
-        if (dataStore == null) {
-            to = new TemplateObjectTO(this);
-        } else {
-            to = dataStore.getDriver().getTO(this);
-            if (to == null) {
-                to = new TemplateObjectTO(this);
-            }
-        }
-
-        return to;
-    }
-
-    @Override
-    public String getInstallPath() {
-        if (installPath != null) {
-            return installPath;
-        }
-
-        if (dataStore == null) {
-            return null;
-        }
-
-        DataObjectInStore obj = objectInStoreMgr.findObject(this, dataStore);
-
-        return obj != null ? obj.getInstallPath() : null;
-    }
-
-    @Override
-    public boolean isDirectDownload() {
-        if (this.imageVO == null) {
-            return false;
-        }
-        return this.imageVO.isDirectDownload();
-    }
-
-    public void setInstallPath(String installPath) {
-        this.installPath = installPath;
-    }
-
-    @Override
-    public long getAccountId() {
-        return imageVO.getAccountId();
-    }
-
-    @Override
-    public boolean isFeatured() {
-        return imageVO.isFeatured();
-    }
-
-    @Override
-    public boolean isPublicTemplate() {
-        return imageVO.isPublicTemplate();
-    }
-
-    @Override
-    public boolean isExtractable() {
-        return imageVO.isExtractable();
-    }
-
-    @Override
-    public String getName() {
-        return imageVO.getName();
-    }
-
-    @Override
-    public boolean isRequiresHvm() {
-        return imageVO.isRequiresHvm();
-    }
-
-    @Override
-    public String getDisplayText() {
-        return imageVO.getDisplayText();
-    }
-
-    @Override
-    public boolean getEnablePassword() {
-        return imageVO.getEnablePassword();
-    }
-
-    @Override
-    public boolean getEnableSshKey() {
-        return imageVO.getEnableSshKey();
-    }
-
-    @Override
-    public boolean isCrossZones() {
-        return imageVO.isCrossZones();
-    }
-
-    @Override
-    public Date getCreated() {
-        return imageVO.getCreated();
-    }
-
-    @Override
-    public long getGuestOSId() {
-        return imageVO.getGuestOSId();
-    }
-
-    @Override
-    public boolean isBootable() {
-        return imageVO.isBootable();
-    }
-
-    @Override
-    public TemplateType getTemplateType() {
-        return imageVO.getTemplateType();
-    }
-
-    @Override
-    public HypervisorType getHypervisorType() {
-        return imageVO.getHypervisorType();
-    }
-
-    @Override
-    public int getBits() {
-        return imageVO.getBits();
-    }
-
-    @Override
-    public String getUrl() {
-        if (url != null) {
-            return url;
-        }
-        return imageVO.getUrl();
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    @Override
-    public String getChecksum() {
-        return imageVO.getChecksum();
-    }
-
-    @Override
-    public Long getSourceTemplateId() {
-        return imageVO.getSourceTemplateId();
-    }
-
-    @Override
-    public Long getParentTemplateId() {
-        return imageVO.getParentTemplateId();
-    }
-
-    @Override
-    public String getTemplateTag() {
-        return imageVO.getTemplateTag();
-    }
-
-    @Override
-    public Map<String, String> getDetails() {
-        return imageVO.getDetails();
-    }
-
-    @Override
-    public boolean isDynamicallyScalable() {
-        return false;
-    }
-
-    @Override
-    public long getDomainId() {
-        return imageVO.getDomainId();
-    }
-
-    @Override
-    public boolean delete() {
-        if (dataStore != null) {
-            return dataStore.delete(this);
-        }
-        return true;
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return VirtualMachineTemplate.class;
-    }
-
-    @Override
-    public long getUpdatedCount() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void incrUpdatedCount() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Date getUpdated() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-}
diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml
index 692e6e9..c9e65d0 100644
--- a/engine/storage/integration-test/pom.xml
+++ b/engine/storage/integration-test/pom.xml
@@ -1,182 +1,186 @@
-<!-- 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-engine-storage-integration-test</artifactId>
-  <name>Apache CloudStack Engine Storage integration test Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-datamotion</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-     <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-cache</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.aspectj</groupId>
-      <artifactId>aspectjrt</artifactId>
-      <version>1.7.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-kvm</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-     <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-default</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-secondary-storage</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-default</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-      <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-s3</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-image-swift</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.testng</groupId>
-      <artifactId>testng</artifactId>
-      <version>6.1.1</version>
-      <scope>test</scope>
-    </dependency>
+<!--
+  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
 
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-      </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
-                  todir="${basedir}/target/test-classes/">
-                  <fileset dir="${basedir}/../../../utils/conf/">
-                    <include name="db.properties" />
-                  </fileset>
-                </copy>
-              </target>
-            </configuration>  
-            </execution>
-          </executions>  
-          </plugin>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-engine-storage-integration-test</artifactId>
+    <name>Apache CloudStack Engine Storage integration test Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-datamotion</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-cache</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-kvm</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-default</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-secondary-storage</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-default</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-s3</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-image-swift</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </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 todir="${basedir}/target/test-classes/">
+                                    <fileset dir="${basedir}/../../../utils/conf/">
+                                        <include name="db.properties" />
+                                    </fileset>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/engine/storage/integration-test/src/test/java/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java b/engine/storage/integration-test/src/test/java/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
new file mode 100644
index 0000000..be8d04a
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.vm.snapshot.dao;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.storage.test.CloudStackTestNGBase;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = "classpath:/storageContext.xml")
+public class VmSnapshotDaoTest extends CloudStackTestNGBase {
+    @Inject
+    VMSnapshotDetailsDao vmsnapshotDetailsDao;
+
+    @Test
+    public void testVmSnapshotDetails() {
+        VMSnapshotDetailsVO detailsVO = new VMSnapshotDetailsVO(1L, "test", "foo", true);
+        vmsnapshotDetailsDao.persist(detailsVO);
+        Map<String, String> details = vmsnapshotDetailsDao.listDetailsKeyPairs(1L);
+        Assert.assertTrue(details.containsKey("test"));
+    }
+
+}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java
new file mode 100644
index 0000000..0d2ebf5
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java
@@ -0,0 +1,486 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.allocator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.DB;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+import junit.framework.Assert;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = "classpath:/storageContext.xml")
+public class StorageAllocatorTest {
+    @Inject
+    PrimaryDataStoreDao storagePoolDao;
+    @Inject
+    StorageManager storageMgr;
+    @Inject
+    DiskOfferingDao diskOfferingDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    HostPodDao podDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    DataCenterDao dcDao;
+    @Inject
+    StoragePoolDetailsDao poolDetailsDao;
+    @Inject
+    DataStoreProviderManager providerMgr;
+    @Inject
+    ConfigurationDao configDao;
+    Long dcId = 1l;
+    Long podId = 1l;
+    Long clusterId = 1l;
+    Long volumeId = null;
+    Long diskOfferingId = null;
+    Long storagePoolId = null;
+    VolumeVO volume = null;
+    DiskOfferingVO diskOffering = null;
+    StoragePoolVO storage = null;
+
+    @Before
+    @DB
+    public void setup() throws Exception {
+        ConfigurationVO cfg = configDao.findByName(Config.VmAllocationAlgorithm.key());
+        if (cfg == null) {
+            ConfigurationVO configVO = new ConfigurationVO("test", "DEFAULT", "test", Config.VmAllocationAlgorithm.key(), "userdispersing", null);
+            configDao.persist(configVO);
+        }
+        ComponentContext.initComponentsLifeCycle();
+
+    }
+
+    protected void createDb() {
+        DataCenterVO dc =
+                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                        true, null, null);
+        dc = dcDao.persist(dc);
+        dcId = dc.getId();
+
+        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "255.255.255.255", "", 8, "test");
+        pod = podDao.persist(pod);
+        podId = pod.getId();
+
+        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+        cluster.setHypervisorType(HypervisorType.XenServer.toString());
+        cluster.setClusterType(ClusterType.CloudManaged);
+        cluster.setManagedState(ManagedState.Managed);
+        cluster = clusterDao.persist(cluster);
+        clusterId = cluster.getId();
+
+        DataStoreProvider provider = providerMgr.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY);
+        storage = new StoragePoolVO();
+        storage.setDataCenterId(dcId);
+        storage.setPodId(podId);
+        storage.setPoolType(StoragePoolType.NetworkFilesystem);
+        storage.setClusterId(clusterId);
+        storage.setStatus(StoragePoolStatus.Up);
+        storage.setScope(ScopeType.CLUSTER);
+        storage.setUsedBytes(1000);
+        storage.setCapacityBytes(20000);
+        storage.setHostAddress(UUID.randomUUID().toString());
+        storage.setPath(UUID.randomUUID().toString());
+        storage.setStorageProviderName(provider.getName());
+        storage = storagePoolDao.persist(storage);
+        storagePoolId = storage.getId();
+
+        storageMgr.createCapacityEntry(storage.getId());
+
+        diskOffering = new DiskOfferingVO();
+        diskOffering.setDiskSize(500);
+        diskOffering.setName("test-disk");
+        diskOffering.setSystemUse(false);
+        diskOffering.setUseLocalStorage(false);
+        diskOffering.setCustomized(false);
+        diskOffering.setRecreatable(false);
+        diskOffering = diskOfferingDao.persist(diskOffering);
+        diskOfferingId = diskOffering.getId();
+
+        volume =
+                new VolumeVO(Volume.Type.ROOT, "volume", dcId, 1, 1, diskOffering.getId(), Storage.ProvisioningType.THIN, diskOffering.getDiskSize(), diskOffering.getMinIops(),
+                        diskOffering.getMaxIops(), "");
+        volume = volumeDao.persist(volume);
+        volumeId = volume.getId();
+    }
+
+    @Inject
+    List<StoragePoolAllocator> allocators;
+
+    @Test
+    public void testClusterAllocatorMultiplePools() {
+        Long newStorageId = null;
+        try {
+            createDb();
+
+            DataStoreProvider provider = providerMgr.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY);
+            storage = new StoragePoolVO();
+            storage.setDataCenterId(dcId);
+            storage.setPodId(podId);
+            storage.setPoolType(StoragePoolType.NetworkFilesystem);
+            storage.setClusterId(clusterId);
+            storage.setStatus(StoragePoolStatus.Up);
+            storage.setScope(ScopeType.CLUSTER);
+            storage.setUsedBytes(1000);
+            storage.setCapacityBytes(20000);
+            storage.setHostAddress(UUID.randomUUID().toString());
+            storage.setPath(UUID.randomUUID().toString());
+            storage.setStorageProviderName(provider.getName());
+            StoragePoolVO newStorage = storagePoolDao.persist(storage);
+            newStorageId = newStorage.getId();
+
+            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.size(), 1);
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+
+            if (newStorageId != null) {
+                storagePoolDao.remove(newStorageId);
+            }
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testClusterAllocator() {
+        try {
+            createDb();
+            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testClusterAllocatorWithTags() {
+        try {
+            createDb();
+            StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true", true);
+            poolDetailsDao.persist(detailVO);
+            DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
+            List<String> tags = new ArrayList<String>();
+            tags.add("high");
+            diskOff.setTagsArray(tags);
+            diskOfferingDao.update(diskOff.getId(), diskOff);
+
+            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testClusterAllocatorWithWrongTag() {
+        try {
+            createDb();
+            StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true", true);
+            poolDetailsDao.persist(detailVO);
+            DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
+            List<String> tags = new ArrayList<String>();
+            tags.add("low");
+            diskOff.setTagsArray(tags);
+            diskOfferingDao.update(diskOff.getId(), diskOff);
+
+            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct != 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testZoneWideStorageAllocator() {
+        try {
+            createDb();
+
+            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
+            pool.setHypervisor(HypervisorType.KVM);
+            pool.setScope(ScopeType.ZONE);
+            pool.setClusterId(null);
+            pool.setPodId(null);
+            storagePoolDao.update(pool.getId(), pool);
+
+            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            Mockito.when(storageMgr.storagePoolHasEnoughIops(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testCLOUDSTACK3481() {
+        try {
+            createDb();
+
+            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
+            pool.setHypervisor(HypervisorType.KVM);
+            pool.setScope(ScopeType.ZONE);
+            pool.setClusterId(null);
+            pool.setPodId(null);
+            storagePoolDao.update(pool.getId(), pool);
+
+            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Account account = Mockito.mock(Account.class);
+            Mockito.when(account.getAccountId()).thenReturn(1L);
+            Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
+            Mockito.when(vmProfile.getOwner()).thenReturn(account);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            Mockito.when(storageMgr.storagePoolHasEnoughIops(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testPoolStateIsNotUp() {
+        try {
+            createDb();
+
+            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
+            pool.setScope(ScopeType.ZONE);
+            pool.setStatus(StoragePoolStatus.Maintenance);
+            storagePoolDao.update(pool.getId(), pool);
+
+            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct == 1) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testLocalStorageAllocator() {
+        try {
+            createDb();
+
+            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
+            pool.setScope(ScopeType.HOST);
+            storagePoolDao.update(pool.getId(), pool);
+
+            DiskOfferingVO diskOff = diskOfferingDao.findById(diskOfferingId);
+            diskOff.setUseLocalStorage(true);
+            diskOfferingDao.update(diskOfferingId, diskOff);
+
+            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
+            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
+            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
+            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
+            int foundAcct = 0;
+            for (StoragePoolAllocator allocator : allocators) {
+                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
+                if (!pools.isEmpty()) {
+                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
+                    foundAcct++;
+                }
+            }
+
+            if (foundAcct > 1 || foundAcct == 0) {
+                Assert.fail();
+            }
+        } catch (Exception e) {
+            cleanDb();
+            Assert.fail();
+        }
+    }
+
+    protected void cleanDb() {
+        if (volumeId != null) {
+            volumeDao.remove(volumeId);
+            volumeId = null;
+        }
+        if (diskOfferingId != null) {
+            diskOfferingDao.remove(diskOfferingId);
+            diskOfferingId = null;
+        }
+        if (storagePoolId != null) {
+            storagePoolDao.remove(storagePoolId);
+            storagePoolId = null;
+        }
+        if (clusterId != null) {
+            clusterDao.remove(clusterId);
+            clusterId = null;
+        }
+        if (podId != null) {
+            podDao.remove(podId);
+            podId = null;
+        }
+        if (dcId != null) {
+            dcDao.remove(dcId);
+            dcId = null;
+        }
+    }
+
+}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AllTests.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AllTests.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AllTests.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AllTests.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AopTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AopTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AopTestAdvice.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/AopTestAdvice.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
new file mode 100644
index 0000000..c6003af
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.StartupCommandProcessor;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.SetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.manager.Commands;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostEnvironment;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.Status.Event;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.vmware.VmwareServerDiscoverer;
+import com.cloud.hypervisor.xenserver.resource.XcpOssResource;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentManager {
+    private static final Logger logger = Logger.getLogger(DirectAgentManagerSimpleImpl.class);
+    private final Map<Long, ServerResource> hostResourcesMap = new HashMap<Long, ServerResource>();
+    @Inject
+    HostDao hostDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    ClusterDetailsDao clusterDetailsDao;
+    @Inject
+    HostDao _hostDao;
+    protected StateMachine2<Status, Event, Host> _statusStateMachine = Status.getStateMachine();
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void rescan() {
+    }
+
+    @Override
+    public boolean start() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Answer easySend(Long hostId, Command cmd) {
+        try {
+            return this.send(hostId, cmd);
+        } catch (AgentUnavailableException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (OperationTimedoutException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    protected void loadResource(Long hostId) {
+        HostVO host = hostDao.findById(hostId);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("guid", host.getGuid());
+        params.put("ipaddress", host.getPrivateIpAddress());
+        params.put("username", "root");
+        params.put("password", "password");
+        params.put("zone", String.valueOf(host.getDataCenterId()));
+        params.put("pod", String.valueOf(host.getPodId()));
+
+        ServerResource resource = null;
+        if (host.getHypervisorType() == HypervisorType.XenServer) {
+            resource = new XcpOssResource();
+            try {
+                resource.configure(host.getName(), params);
+
+            } catch (ConfigurationException e) {
+                logger.debug("Failed to load resource:" + e.toString());
+            }
+        } else if (host.getHypervisorType() == HypervisorType.KVM) {
+            resource = new LibvirtComputingResource();
+            try {
+                params.put("public.network.device", "cloudbr0");
+                params.put("private.network.device", "cloudbr0");
+                resource.configure(host.getName(), params);
+            } catch (ConfigurationException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        } else if (host.getHypervisorType() == HypervisorType.VMware) {
+            ClusterVO cluster = clusterDao.findById(host.getClusterId());
+            String url = clusterDetailsDao.findDetail(cluster.getId(), "url").getValue();
+            URI uri;
+            try {
+                uri = new URI(url);
+                String userName = clusterDetailsDao.findDetail(cluster.getId(), "username").getValue();
+                String password = clusterDetailsDao.findDetail(cluster.getId(), "password").getValue();
+                VmwareServerDiscoverer discover = new VmwareServerDiscoverer();
+
+                Map<? extends ServerResource, Map<String, String>> resources =
+                        discover.find(host.getDataCenterId(), host.getPodId(), host.getClusterId(), uri, userName, password, null);
+                for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
+                    resource = entry.getKey();
+                }
+                if (resource == null) {
+                    throw new CloudRuntimeException("can't find resource");
+                }
+            } catch (DiscoveryException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (URISyntaxException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        hostResourcesMap.put(hostId, resource);
+        HostEnvironment env = new HostEnvironment();
+        SetupCommand cmd = new SetupCommand(env);
+        cmd.setNeedSetup(true);
+
+        resource.executeRequest(cmd);
+    }
+
+    @Override
+    public synchronized Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
+        ServerResource resource = hostResourcesMap.get(hostId);
+        if (resource == null) {
+            loadResource(hostId);
+            resource = hostResourcesMap.get(hostId);
+        }
+
+        if (resource == null) {
+            return null;
+        }
+
+        Answer answer = resource.executeRequest(cmd);
+        return answer;
+    }
+
+    @Override
+    public Answer[] send(Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, OperationTimedoutException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long send(Long hostId, Commands cmds, Listener listener) throws AgentUnavailableException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int registerForHostEvents(Listener listener, boolean connections, boolean commands, boolean priority) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int registerForInitialConnects(StartupCommandProcessor creator, boolean priority) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void unregisterForHostEvents(int id) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Answer sendTo(Long dcId, HypervisorType type, Command cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean agentStatusTransitTo(HostVO host, Event e, long msId) {
+        try {
+            return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
+        } catch (NoTransitionException e1) {
+            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        }
+        return true;
+
+    }
+
+    @Override
+    public void disconnectWithoutInvestigation(long hostId, Event event) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void pullAgentToMaintenance(long hostId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void pullAgentOutMaintenance(long hostId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void reconnect(long hostId) {
+    }
+
+    @Override
+    public boolean isAgentAttached(long hostId) {
+        return false;
+    }
+
+    @Override
+    public boolean handleDirectConnectAgent(Host host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance, boolean newHost) throws ConnectionException {
+        return false;
+    }
+
+    @Override
+    public void notifyMonitorsOfHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void notifyMonitorsOfRemovedHost(long hostId, long clusterId) {
+    }
+
+    @Override
+    public void disconnectWithInvestigation(long hostId, Event event) {
+
+    }
+
+    @Override
+    public void notifyMonitorsOfNewlyAddedHost(long hostId) {
+    }
+}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/DirectAgentTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/DirectAgentTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/EndpointSelectorTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/FakeDriverTestConfiguration.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/FakePrimaryDataStoreDriver.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockRpcCallBack.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockRpcCallBack.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/S3TemplateTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/S3TemplateTest.java
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java
new file mode 100644
index 0000000..0185c0d
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTest.java
@@ -0,0 +1,499 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+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.StorageStrategyFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.LocalHostEndpoint;
+import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.LocationType;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+
+import junit.framework.Assert;
+
+@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
+public class SnapshotTest extends CloudStackTestNGBase {
+    @Inject
+    ImageStoreDao imageStoreDao;
+    ImageStoreVO imageStore;
+    Long dcId;
+    Long clusterId;
+    Long podId;
+    HostVO host;
+    String primaryName = "my primary data store";
+    DataStore primaryStore;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    TemplateService imageService;
+    @Inject
+    VolumeService volumeService;
+    @Inject
+    VMTemplateDao imageDataDao;
+    @Inject
+    HostPodDao podDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    DataCenterDao dcDao;
+    @Inject
+    PrimaryDataStoreDao primaryStoreDao;
+    @Inject
+    DataStoreProviderManager dataStoreProviderMgr;
+    @Inject
+    TemplateDataStoreDao templateStoreDao;
+    @Inject
+    TemplateDataFactory templateFactory;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    HypervisorGuruManager hyGuruMgr;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    ResourceManager resourceMgr;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    SnapshotDataFactory snapshotFactory;
+    @Inject
+    StorageStrategyFactory storageStrategyFactory;
+    @Inject
+    List<SnapshotStrategy> snapshotStrategies;
+    @Inject
+    SnapshotService snapshotSvr;
+    @Inject
+    SnapshotDao snapshotDao;
+    @Inject
+    EndPointSelector epSelector;
+    @Inject
+    VolumeDao volumeDao;
+
+    long primaryStoreId;
+    VMTemplateVO image;
+    String imageStoreName = "testImageStore";
+    RemoteHostEndPoint remoteEp;
+
+    @Test(priority = -1)
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+
+        host = hostDao.findByGuid(this.getHostGuid());
+        if (host != null) {
+            dcId = host.getDataCenterId();
+            clusterId = host.getClusterId();
+            podId = host.getPodId();
+            imageStore = this.imageStoreDao.findByName(imageStoreName);
+        } else {
+            // create data center
+            DataCenterVO dc =
+                    new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                            true, null, null);
+            dc = dcDao.persist(dc);
+            dcId = dc.getId();
+            // create pod
+
+            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
+            pod = podDao.persist(pod);
+            podId = pod.getId();
+            // create xenserver cluster
+            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+            cluster.setHypervisorType(this.getHypervisor().toString());
+            cluster.setClusterType(ClusterType.CloudManaged);
+            cluster.setManagedState(ManagedState.Managed);
+            cluster = clusterDao.persist(cluster);
+            clusterId = cluster.getId();
+            // create xenserver host
+
+            host = new HostVO(this.getHostGuid());
+            host.setName("devcloud xenserver host");
+            host.setType(Host.Type.Routing);
+            host.setPrivateIpAddress(this.getHostIp());
+            host.setDataCenterId(dc.getId());
+            host.setVersion("6.0.1");
+            host.setAvailable(true);
+            host.setSetup(true);
+            host.setPodId(podId);
+            host.setLastPinged(0);
+            host.setResourceState(ResourceState.Enabled);
+            host.setHypervisorType(this.getHypervisor());
+            host.setClusterId(cluster.getId());
+
+            host = hostDao.persist(host);
+
+            imageStore = new ImageStoreVO();
+            imageStore.setName(imageStoreName);
+            imageStore.setDataCenterId(dcId);
+            imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
+            imageStore.setRole(DataStoreRole.Image);
+            imageStore.setUrl(this.getSecondaryStorage());
+            imageStore.setUuid(UUID.randomUUID().toString());
+            imageStore.setProtocol("nfs");
+            imageStore = imageStoreDao.persist(imageStore);
+        }
+
+        image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+        image.setUrl(this.getTemplateUrl());
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+
+        image = imageDataDao.persist(image);
+
+        /*
+         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
+         *
+         * templateStore.setDataStoreId(imageStore.getId());
+         * templateStore.setDownloadPercent(100);
+         * templateStore.setDownloadState(Status.DOWNLOADED);
+         * templateStore.setDownloadUrl(imageStore.getUrl());
+         * templateStore.setInstallPath(this.getImageInstallPath());
+         * templateStore.setTemplateId(image.getId());
+         * templateStoreDao.persist(templateStore);
+         */
+
+        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
+        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
+        DataObject templateOnStore = store.create(template);
+        TemplateObjectTO to = new TemplateObjectTO();
+        to.setPath(this.getImageInstallPath());
+        to.setFormat(ImageFormat.VHD);
+        to.setSize(1000L);
+        CopyCmdAnswer answer = new CopyCmdAnswer(to);
+        templateOnStore.processEvent(Event.CreateOnlyRequested);
+        templateOnStore.processEvent(Event.OperationSuccessed, answer);
+
+    }
+
+    @Override
+    protected void injectMockito() {
+        List<HostVO> hosts = new ArrayList<HostVO>();
+        hosts.add(this.host);
+        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
+        remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(remoteEp);
+        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);
+        Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(this.host.getId());
+
+    }
+
+    public DataStore createPrimaryDataStore() {
+        try {
+            String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
+            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
+            if (pools.size() > 0) {
+                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
+            }
+
+            /*
+             * DataStoreProvider provider =
+             * dataStoreProviderMgr.getDataStoreProvider
+             * ("cloudstack primary data store provider"); Map<String, Object>
+             * params = new HashMap<String, Object>(); URI uri = new
+             * URI(this.getPrimaryStorageUrl()); params.put("url",
+             * this.getPrimaryStorageUrl()); params.put("server",
+             * uri.getHost()); params.put("path", uri.getPath());
+             * params.put("protocol",
+             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
+             * dcId); params.put("clusterId", clusterId); params.put("name",
+             * this.primaryName); params.put("port", 1); params.put("podId",
+             * this.podId); params.put("roles",
+             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
+             * params.put("providerName", String.valueOf(provider.getName()));
+             *
+             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+             * DataStore store = lifeCycle.initialize(params); ClusterScope
+             * scope = new ClusterScope(clusterId, podId, dcId);
+             * lifeCycle.attachCluster(store, scope);
+             */
+
+            StoragePoolVO pool = new StoragePoolVO();
+            pool.setClusterId(clusterId);
+            pool.setDataCenterId(dcId);
+            URI uri = new URI(this.getPrimaryStorageUrl());
+            pool.setHostAddress(uri.getHost());
+            pool.setPath(uri.getPath());
+            pool.setPort(0);
+            pool.setName(this.primaryName);
+            pool.setUuid(this.getPrimaryStorageUuid());
+            pool.setStatus(StoragePoolStatus.Up);
+            pool.setPoolType(StoragePoolType.NetworkFilesystem);
+            pool.setPodId(podId);
+            pool.setScope(ScopeType.CLUSTER);
+            pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
+            pool = this.primaryStoreDao.persist(pool);
+            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+            return store;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private SnapshotVO createSnapshotInDb(VolumeInfo volume) {
+        Snapshot.Type snapshotType = Snapshot.Type.MANUAL;
+        SnapshotVO snapshotVO =
+                new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(),
+                        volume.getSize(), 1L, 100L, HypervisorType.XenServer, LocationType.PRIMARY);
+        return this.snapshotDao.persist(snapshotVO);
+    }
+
+    private VolumeVO createVolume(Long templateId, long dataStoreId) {
+        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, Storage.ProvisioningType.THIN, 1000, 0L, 0L, "");
+        volume.setDataCenterId(this.dcId);
+        volume.setPoolId(dataStoreId);
+        volume = volumeDao.persist(volume);
+        return volume;
+    }
+
+    public VolumeInfo createCopyBaseImage() throws InterruptedException, ExecutionException {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future =
+                this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
+
+        VolumeApiResult result;
+        result = future.get();
+        Assert.assertTrue(result.isSuccess());
+        return result.getVolume();
+
+    }
+
+    private VMTemplateVO createTemplateInDb() {
+        VMTemplateVO image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+        image = imageDataDao.persist(image);
+        return image;
+    }
+
+    @Test
+    public void createVolumeFromSnapshot() throws InterruptedException, ExecutionException {
+        VolumeInfo vol = createCopyBaseImage();
+        SnapshotVO snapshotVO = createSnapshotInDb(vol);
+        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
+        boolean result = false;
+
+        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+        if (snapshotStrategy != null) {
+            snapshot = snapshotStrategy.takeSnapshot(snapshot);
+            result = true;
+        }
+
+        AssertJUnit.assertTrue(result);
+
+        VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId());
+        VolumeInfo newVol = this.volFactory.getVolume(volVO.getId());
+        AsyncCallFuture<VolumeApiResult> volFuture = this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot);
+        VolumeApiResult apiResult = volFuture.get();
+        Assert.assertTrue(apiResult.isSuccess());
+    }
+
+    @Test
+    public void deleteSnapshot() throws InterruptedException, ExecutionException {
+        VolumeInfo vol = createCopyBaseImage();
+        SnapshotVO snapshotVO = createSnapshotInDb(vol);
+        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
+        SnapshotInfo newSnapshot = null;
+
+        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+        if (snapshotStrategy != null) {
+            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
+
+        }
+        AssertJUnit.assertNotNull(newSnapshot);
+
+        // create another snapshot
+        for (SnapshotStrategy strategy : this.snapshotStrategies) {
+            if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) {
+                strategy.deleteSnapshot(newSnapshot.getId());
+            }
+        }
+
+    }
+
+    @Test
+    public void createTemplateFromSnapshot() throws InterruptedException, ExecutionException {
+        VolumeInfo vol = createCopyBaseImage();
+        SnapshotVO snapshotVO = createSnapshotInDb(vol);
+        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
+        boolean result = false;
+
+        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+        if (snapshotStrategy != null) {
+            snapshot = snapshotStrategy.takeSnapshot(snapshot);
+            result = true;
+        }
+
+        AssertJUnit.assertTrue(result);
+        LocalHostEndpoint ep = new LocalHostEndpoint();
+        ep.setResource(new MockLocalNfsSecondaryStorageResource());
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
+
+        try {
+            VMTemplateVO templateVO = createTemplateInDb();
+            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
+            DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
+            AsyncCallFuture<TemplateApiResult> templateFuture = this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
+            TemplateApiResult apiResult = templateFuture.get();
+            Assert.assertTrue(apiResult.isSuccess());
+        } finally {
+            Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
+        }
+    }
+
+    @Test
+    public void createSnapshot() throws InterruptedException, ExecutionException {
+        VolumeInfo vol = createCopyBaseImage();
+        SnapshotVO snapshotVO = createSnapshotInDb(vol);
+        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
+        SnapshotInfo newSnapshot = null;
+
+        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+        if (snapshotStrategy != null) {
+            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
+        }
+
+        AssertJUnit.assertNotNull(newSnapshot);
+
+        LocalHostEndpoint ep = new MockLocalHostEndPoint();
+        ep.setResource(new MockLocalNfsSecondaryStorageResource());
+        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
+
+        try {
+            for (SnapshotStrategy strategy : this.snapshotStrategies) {
+                if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) {
+                    boolean res = strategy.deleteSnapshot(newSnapshot.getId());
+                    Assert.assertTrue(res);
+                }
+            }
+        } finally {
+            Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);
+        }
+    }
+
+}
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
new file mode 100644
index 0000000..a3961ac
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
@@ -0,0 +1,359 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
+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.SnapshotResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.org.Cluster;
+import com.cloud.org.Managed;
+import com.cloud.server.LockMasterListener;
+import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.LocationType;
+import com.cloud.storage.SnapshotPolicyVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotPolicyDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.Merovingian2;
+
+import junit.framework.Assert;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:/fakeDriverTestContext.xml"})
+public class SnapshotTestWithFakeData {
+    @Inject
+    SnapshotService snapshotService;
+    @Inject
+    SnapshotDao snapshotDao;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject
+    DataStoreManager dataStoreManager;
+    @Inject
+    SnapshotDataFactory snapshotDataFactory;
+    @Inject
+    PrimaryDataStoreProvider primaryDataStoreProvider;
+    @Inject
+    SnapshotDataStoreDao snapshotDataStoreDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    VolumeService volumeService;
+    @Inject
+    VolumeDataFactory volumeDataFactory;
+    @Inject
+    DataCenterDao dcDao;
+    Long dcId;
+    @Inject
+    HostPodDao podDao;
+    Long podId;
+    @Inject
+    ClusterDao clusterDao;
+    Long clusterId;
+    @Inject
+    ImageStoreDao imageStoreDao;
+    ImageStoreVO imageStore;
+    @Inject
+    AccountManager accountManager;
+    LockMasterListener lockMasterListener;
+    VolumeInfo vol = null;
+    FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
+    @Inject
+    MockStorageMotionStrategy mockStorageMotionStrategy;
+    Merovingian2 _lockMaster;
+    @Inject
+    SnapshotPolicyDao snapshotPolicyDao;
+
+    @Before
+    public void setUp() {
+        // create data center
+
+        DataCenterVO dc =
+                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, DataCenter.NetworkType.Basic, null,
+                        null, true, true, null, null);
+        dc = dcDao.persist(dc);
+        dcId = dc.getId();
+        // create pod
+
+        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "10.223.0.1", "10.233.2.2/25", 8, "test");
+        pod = podDao.persist(pod);
+        podId = pod.getId();
+        // create xenserver cluster
+        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+        cluster.setHypervisorType(Hypervisor.HypervisorType.XenServer.toString());
+        cluster.setClusterType(Cluster.ClusterType.CloudManaged);
+        cluster.setManagedState(Managed.ManagedState.Managed);
+        cluster = clusterDao.persist(cluster);
+        clusterId = cluster.getId();
+
+        imageStore = new ImageStoreVO();
+        imageStore.setName(UUID.randomUUID().toString());
+        imageStore.setDataCenterId(dcId);
+        imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
+        imageStore.setRole(DataStoreRole.Image);
+        imageStore.setUrl(UUID.randomUUID().toString());
+        imageStore.setUuid(UUID.randomUUID().toString());
+        imageStore.setProtocol("nfs");
+        imageStore = imageStoreDao.persist(imageStore);
+
+        when(primaryDataStoreProvider.configure(Matchers.anyMap())).thenReturn(true);
+        Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
+        types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
+
+        when(primaryDataStoreProvider.getTypes()).thenReturn(types);
+        when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
+        when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
+        User user = mock(User.class);
+        when(user.getId()).thenReturn(1L);
+        Account account = mock(Account.class);
+        when(account.getId()).thenReturn(1L);
+        when(accountManager.getSystemAccount()).thenReturn(account);
+        when(accountManager.getSystemUser()).thenReturn(user);
+
+        if (Merovingian2.getLockMaster() == null) {
+            _lockMaster = Merovingian2.createLockMaster(1234);
+        } else {
+            _lockMaster = Merovingian2.getLockMaster();
+        }
+        _lockMaster.cleanupThisServer();
+        ComponentContext.initComponentsLifeCycle();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        _lockMaster.cleanupThisServer();
+    }
+
+    private SnapshotVO createSnapshotInDb() {
+        Snapshot.Type snapshotType = Snapshot.Type.RECURRING;
+        SnapshotVO snapshotVO =
+                new SnapshotVO(dcId, 2, 1, 1L, 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(), 100, 1L, 100L, Hypervisor.HypervisorType.XenServer,
+                        LocationType.PRIMARY);
+        return snapshotDao.persist(snapshotVO);
+    }
+
+    private SnapshotVO createSnapshotInDb(Long volumeId) {
+        Snapshot.Type snapshotType = Snapshot.Type.DAILY;
+        SnapshotVO snapshotVO =
+                new SnapshotVO(dcId, 2, 1, 1L, 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(), 100, 1L, 100L, Hypervisor.HypervisorType.XenServer,
+                        LocationType.PRIMARY);
+        return snapshotDao.persist(snapshotVO);
+    }
+
+    private VolumeInfo createVolume(Long templateId, DataStore store) {
+        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), dcId, 1L, 1L, 1L, Storage.ProvisioningType.THIN, 1000, 0L, 0L, "");
+        volume.setPoolId(store.getId());
+
+        volume = volumeDao.persist(volume);
+        VolumeInfo volumeInfo = volumeDataFactory.getVolume(volume.getId(), store);
+        volumeInfo.stateTransit(Volume.Event.CreateRequested);
+        volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
+        return volumeInfo;
+    }
+
+    private DataStore createDataStore() throws URISyntaxException {
+        StoragePoolVO pool = new StoragePoolVO();
+        pool.setClusterId(clusterId);
+        pool.setDataCenterId(dcId);
+        URI uri = new URI("nfs://jfkdkf/fjdkfj");
+        pool.setHostAddress(uri.getHost());
+        pool.setPath(uri.getPath());
+        pool.setPort(0);
+        pool.setName(UUID.randomUUID().toString());
+        pool.setUuid(UUID.randomUUID().toString());
+        pool.setStatus(StoragePoolStatus.Up);
+        pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
+        pool.setPodId(podId);
+        pool.setScope(ScopeType.CLUSTER);
+        pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
+        pool = primaryDataStoreDao.persist(pool);
+        DataStore store = dataStoreManager.getPrimaryDataStore(pool.getId());
+        return store;
+    }
+
+    //@Test
+    public void testTakeSnapshot() throws URISyntaxException {
+        SnapshotVO snapshotVO = createSnapshotInDb();
+        DataStore store = createDataStore();
+        try {
+            SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
+            SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
+            Assert.assertTrue(result.isSuccess());
+            SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
+            Assert.assertTrue(storeRef != null);
+            Assert.assertTrue(storeRef.getState() == ObjectInDataStoreStateMachine.State.Ready);
+            snapshotInfo = result.getSnapshot();
+            boolean deletResult = snapshotService.deleteSnapshot(snapshotInfo);
+            Assert.assertTrue(deletResult);
+            snapshotDataStoreDao.expunge(storeRef.getId());
+        } finally {
+            snapshotDao.expunge(snapshotVO.getId());
+            primaryDataStoreDao.remove(store.getId());
+        }
+    }
+
+    //@Test
+    public void testTakeSnapshotWithFailed() throws URISyntaxException {
+        SnapshotVO snapshotVO = createSnapshotInDb();
+        DataStore store = null;
+        try {
+            store = createDataStore();
+            FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
+            dataStoreDriver.makeTakeSnapshotSucceed(false);
+            SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
+            SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
+            Assert.assertFalse(result.isSuccess());
+            SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
+            Assert.assertTrue(storeRef == null);
+        } finally {
+            snapshotDao.expunge(snapshotVO.getId());
+            if (store != null) {
+                primaryDataStoreDao.remove(store.getId());
+            }
+        }
+    }
+
+    //@Test
+    public void testTakeSnapshotFromVolume() throws URISyntaxException {
+        DataStore store = createDataStore();
+        FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
+        dataStoreDriver.makeTakeSnapshotSucceed(false);
+        VolumeInfo volumeInfo = createVolume(1L, store);
+        Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
+        SnapshotInfo result = volumeService.takeSnapshot(volumeInfo);
+        Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
+        Assert.assertTrue(result == null);
+    }
+
+    protected SnapshotPolicyVO createSnapshotPolicy(Long volId) {
+        SnapshotPolicyVO policyVO = new SnapshotPolicyVO(volId, "jfkd", "fdfd", DateUtil.IntervalType.DAILY, 8, true);
+            policyVO = snapshotPolicyDao.persist(policyVO);
+            return policyVO;
+        }
+
+        @Test
+        public void testConcurrentSnapshot() throws URISyntaxException, InterruptedException, ExecutionException {
+            DataStore store = createDataStore();
+            final FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
+            dataStoreDriver.makeTakeSnapshotSucceed(true);
+            final VolumeInfo volumeInfo = createVolume(1L, store);
+            Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
+            vol = volumeInfo;
+            // final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
+
+            ExecutorService pool = Executors.newFixedThreadPool(2);
+            boolean result = false;
+            List<Future<Boolean>> future = new ArrayList<Future<Boolean>>();
+            for (int i = 0; i < 12; i++) {
+                final int cnt = i;
+                Future<Boolean> task = pool.submit(new Callable<Boolean>() {
+                    @Override
+                    public Boolean call() throws Exception {
+                        boolean r = true;
+                        try {
+                            SnapshotVO snapshotVO = createSnapshotInDb(vol.getId());
+                            VolumeObject volumeObject = (VolumeObject)vol;
+                            Account account = mock(Account.class);
+                            when(account.getId()).thenReturn(1L);
+                            CreateSnapshotPayload createSnapshotPayload = mock(CreateSnapshotPayload.class);
+                            when(createSnapshotPayload.getAccount()).thenReturn(account);
+                            when(createSnapshotPayload.getSnapshotId()).thenReturn(snapshotVO.getId());
+                            when(createSnapshotPayload.getSnapshotPolicyId()).thenReturn(0L);
+                            volumeObject.addPayload(createSnapshotPayload);
+                            if (cnt > 8) {
+                                mockStorageMotionStrategy.makeBackupSnapshotSucceed(false);
+                            }
+                            SnapshotInfo newSnapshot = volumeService.takeSnapshot(vol);
+                            if (newSnapshot == null) {
+                                r = false;
+                            }
+                        } catch (Exception e) {
+                            r = false;
+                        }
+                        return r;
+                    }
+                });
+                Assert.assertTrue(task.get());
+            }
+
+        }
+    }
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/StorageFactoryBean.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/StorageFactoryBean.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/StorageTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/StorageTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TemplateTest.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TemplateTest.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestConfiguration.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestConfiguration.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestConfiguration.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestConfiguration.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestHttp.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestHttp.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestNG.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestNG.java
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestNGAop.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/TestNGAop.java
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeServiceTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeServiceTest.java
new file mode 100644
index 0000000..9a680ed
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeServiceTest.java
@@ -0,0 +1,470 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+
+@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
+public class VolumeServiceTest extends CloudStackTestNGBase {
+    // @Inject
+    // ImageDataStoreProviderManager imageProviderMgr;
+    @Inject
+    TemplateService imageService;
+    @Inject
+    VolumeService volumeService;
+    @Inject
+    VMTemplateDao imageDataDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    HostPodDao podDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    DataCenterDao dcDao;
+    @Inject
+    PrimaryDataStoreDao primaryStoreDao;
+    @Inject
+    DataStoreProviderManager dataStoreProviderMgr;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    EndPointSelector selector;
+    @Inject
+    TemplateDataFactory imageDataFactory;
+    @Inject
+    VolumeDataFactory volumeFactory;
+    @Inject
+    ImageStoreDao imageStoreDao;
+    ImageStoreVO imageStore;
+    Long dcId;
+    Long clusterId;
+    Long podId;
+    HostVO host;
+    String primaryName = "my primary data store";
+    DataStore primaryStore;
+
+    @Test(priority = -1)
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+
+        host = hostDao.findByGuid(this.getHostGuid());
+        if (host != null) {
+            dcId = host.getDataCenterId();
+            clusterId = host.getClusterId();
+            podId = host.getPodId();
+            return;
+        }
+        // create data center
+        DataCenterVO dc =
+                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                        true, null, null);
+        dc = dcDao.persist(dc);
+        dcId = dc.getId();
+        // create pod
+
+        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
+        pod = podDao.persist(pod);
+        podId = pod.getId();
+        // create xenserver cluster
+        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+        cluster.setHypervisorType(HypervisorType.XenServer.toString());
+        cluster.setClusterType(ClusterType.CloudManaged);
+        cluster.setManagedState(ManagedState.Managed);
+        cluster = clusterDao.persist(cluster);
+        clusterId = cluster.getId();
+        // create xenserver host
+
+        host = new HostVO(this.getHostGuid());
+        host.setName("devcloud xenserver host");
+        host.setType(Host.Type.Routing);
+        host.setPrivateIpAddress(this.getHostIp());
+        host.setDataCenterId(dc.getId());
+        host.setVersion("6.0.1");
+        host.setAvailable(true);
+        host.setSetup(true);
+        host.setPodId(podId);
+        host.setLastPinged(0);
+        host.setResourceState(ResourceState.Enabled);
+        host.setHypervisorType(HypervisorType.XenServer);
+        host.setClusterId(cluster.getId());
+
+        host = hostDao.persist(host);
+
+        imageStore = new ImageStoreVO();
+        imageStore.setName("test");
+        imageStore.setDataCenterId(dcId);
+        imageStore.setProviderName("CloudStack ImageStore Provider");
+        imageStore.setRole(DataStoreRole.Image);
+        imageStore.setUrl(this.getSecondaryStorage());
+        imageStore.setUuid(UUID.randomUUID().toString());
+        imageStore = imageStoreDao.persist(imageStore);
+
+    }
+
+    @Override
+    protected void injectMockito() {
+        if (host == null) {
+            return;
+        }
+        List<HostVO> results = new ArrayList<HostVO>();
+        results.add(host);
+        Mockito.when(hostDao.listAll()).thenReturn(results);
+        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(host);
+        Mockito.when(hostDao.findHypervisorHostInCluster(Matchers.anyLong())).thenReturn(results);
+        List<EndPoint> eps = new ArrayList<EndPoint>();
+        eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
+        Mockito.when(selector.selectAll(Matchers.any(DataStore.class))).thenReturn(eps);
+        Mockito.when(selector.select(Matchers.any(DataObject.class))).thenReturn(eps.get(0));
+        Mockito.when(selector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(eps.get(0));
+    }
+
+    private VMTemplateVO createImageData() {
+        VMTemplateVO image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+        image.setUrl(this.getTemplateUrl());
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+
+        // image.setImageDataStoreId(storeId);
+        image = imageDataDao.persist(image);
+
+        return image;
+    }
+
+    private TemplateInfo createTemplate() {
+        try {
+            DataStore store = createImageStore();
+            VMTemplateVO image = createImageData();
+            TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store);
+            // AsyncCallFuture<TemplateApiResult> future =
+            // imageService.createTemplateAsync(template, store);
+            // future.get();
+            template = imageDataFactory.getTemplate(image.getId(), store);
+            /*
+             * imageProviderMgr.configure("image Provider", new HashMap<String,
+             * Object>()); VMTemplateVO image = createImageData();
+             * ImageDataStoreProvider defaultProvider =
+             * imageProviderMgr.getProvider("DefaultProvider");
+             * ImageDataStoreLifeCycle lifeCycle =
+             * defaultProvider.getLifeCycle(); ImageDataStore store =
+             * lifeCycle.registerDataStore("defaultHttpStore", new
+             * HashMap<String, String>());
+             * imageService.registerTemplate(image.getId(),
+             * store.getImageDataStoreId()); TemplateEntity te =
+             * imageService.getTemplateEntity(image.getId()); return te;
+             */
+            return template;
+        } catch (Exception e) {
+            Assert.fail("failed", e);
+            return null;
+        }
+    }
+
+    // @Test
+    public void createTemplateTest() {
+        createTemplate();
+    }
+
+    @Test
+    public void testCreatePrimaryStorage() {
+        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
+        Map<String, Object> params = new HashMap<String, Object>();
+        URI uri = null;
+        try {
+            uri = new URI(this.getPrimaryStorageUrl());
+        } catch (URISyntaxException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        params.put("url", this.getPrimaryStorageUrl());
+        params.put("server", uri.getHost());
+        params.put("path", uri.getPath());
+        params.put("protocol", StoragePoolType.NetworkFilesystem);
+        params.put("dcId", dcId.toString());
+        params.put("clusterId", clusterId.toString());
+        params.put("name", this.primaryName);
+        params.put("port", "1");
+        params.put("roles", DataStoreRole.Primary.toString());
+        params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
+        params.put("providerName", String.valueOf(provider.getName()));
+
+        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+        this.primaryStore = lifeCycle.initialize(params);
+        ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
+        lifeCycle.attachCluster(this.primaryStore, scope);
+    }
+
+    private DataStore createImageStore() {
+        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider");
+        Map<String, Object> params = new HashMap<String, Object>();
+        String name = UUID.randomUUID().toString();
+        params.put("name", name);
+        params.put("uuid", name);
+        params.put("protocol", "http");
+        params.put("scope", ScopeType.GLOBAL.toString());
+        params.put("providerName", name);
+        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+        DataStore store = lifeCycle.initialize(params);
+        return store;
+    }
+
+    // @Test
+    public void testcreateImageStore() {
+        createImageStore();
+    }
+
+    public DataStore createPrimaryDataStore() {
+        try {
+            DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
+            Map<String, Object> params = new HashMap<String, Object>();
+            URI uri = new URI(this.getPrimaryStorageUrl());
+            params.put("url", this.getPrimaryStorageUrl());
+            params.put("server", uri.getHost());
+            params.put("path", uri.getPath());
+            params.put("protocol", Storage.StoragePoolType.NetworkFilesystem);
+            params.put("dcId", dcId.toString());
+            params.put("clusterId", clusterId.toString());
+            params.put("name", this.primaryName);
+            params.put("port", "1");
+            params.put("roles", DataStoreRole.Primary.toString());
+            params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
+            params.put("providerName", String.valueOf(provider.getName()));
+
+            DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+            DataStore store = lifeCycle.initialize(params);
+            ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
+            lifeCycle.attachCluster(store, scope);
+
+            /*
+             * PrimaryDataStoreProvider provider =
+             * primaryDataStoreProviderMgr.getDataStoreProvider
+             * ("sample primary data store provider");
+             * primaryDataStoreProviderMgr.configure("primary data store mgr",
+             * new HashMap<String, Object>());
+             *
+             * List<PrimaryDataStoreVO> ds =
+             * primaryStoreDao.findPoolByName(this.primaryName); if (ds.size()
+             * >= 1) { PrimaryDataStoreVO store = ds.get(0); if
+             * (store.getRemoved() == null) { return
+             * provider.getDataStore(store.getId()); } }
+             *
+             *
+             * Map<String, String> params = new HashMap<String, String>();
+             * params.put("url", this.getPrimaryStorageUrl());
+             * params.put("dcId", dcId.toString()); params.put("clusterId",
+             * clusterId.toString()); params.put("name", this.primaryName);
+             * PrimaryDataStoreInfo primaryDataStoreInfo =
+             * provider.registerDataStore(params); PrimaryDataStoreLifeCycle lc
+             * = primaryDataStoreInfo.getLifeCycle(); ClusterScope scope = new
+             * ClusterScope(clusterId, podId, dcId); lc.attachCluster(scope);
+             * return primaryDataStoreInfo;
+             */
+            return store;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private VolumeVO createVolume(Long templateId, long dataStoreId) {
+        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, ProvisioningType.THIN, 1000, 0L, 0L, "");
+        volume.setPoolId(dataStoreId);
+        volume = volumeDao.persist(volume);
+        return volume;
+    }
+
+    @Test(priority = 2)
+    public void createVolumeFromTemplate() {
+        DataStore primaryStore = this.primaryStore;
+        TemplateInfo te = createTemplate();
+        VolumeVO volume = createVolume(te.getId(), primaryStore.getId());
+        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
+        // ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te);
+        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeFromTemplateAsync(vol, primaryStore.getId(), te);
+        try {
+            future.get();
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    // @Test(priority=3)
+    public void createDataDisk() {
+        DataStore primaryStore = this.primaryStore;
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
+        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeAsync(vol, primaryStore);
+        try {
+            future.get();
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    // @Test(priority=3)
+    public void createAndDeleteDataDisk() {
+        DataStore primaryStore = this.primaryStore;
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
+        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeAsync(vol, primaryStore);
+        try {
+            future.get();
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        // delete the volume
+        vol = volumeFactory.getVolume(volume.getId(), primaryStore);
+        future = volumeService.expungeVolumeAsync(vol);
+        try {
+            future.get();
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    // @Test(priority=3)
+    public void tearDown() {
+        List<StoragePoolVO> ds = primaryStoreDao.findPoolByName(this.primaryName);
+        for (int i = 0; i < ds.size(); i++) {
+            StoragePoolVO store = ds.get(i);
+            store.setUuid(null);
+            primaryStoreDao.remove(ds.get(i).getId());
+            primaryStoreDao.expunge(ds.get(i).getId());
+        }
+    }
+
+    // @Test
+    // @Test
+    public void test1() {
+        /*
+         * System.out.println(VolumeTypeHelper.getType("Root"));
+         * System.out.println(VolumeDiskTypeHelper.getDiskType("vmdk"));
+         * System.out.println(ImageFormatHelper.getFormat("ova"));
+         * AssertJUnit.assertFalse(new VMDK().equals(new VHD())); VMDK vmdk =
+         * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(vmdk)); VMDK newvmdk =
+         * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(newvmdk));
+         *
+         * ImageFormat ova = new OVA(); ImageFormat iso = new ISO();
+         * AssertJUnit.assertTrue(ova.equals(new OVA()));
+         * AssertJUnit.assertFalse(ova.equals(iso));
+         * AssertJUnit.assertTrue(ImageFormatHelper.getFormat("test").equals(new
+         * Unknown()));
+         *
+         * VolumeDiskType qcow2 = new QCOW2(); ImageFormat qcow2format = new
+         * org.apache.cloudstack.storage.image.format.QCOW2();
+         * AssertJUnit.assertFalse(qcow2.equals(qcow2format));
+         */
+    }
+
+}
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java
new file mode 100644
index 0000000..8642174
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+
+import junit.framework.Assert;
+
+@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
+public class VolumeTest extends CloudStackTestNGBase {
+    @Inject
+    ImageStoreDao imageStoreDao;
+    ImageStoreVO imageStore;
+    Long dcId;
+    Long clusterId;
+    Long podId;
+    HostVO host;
+    String primaryName = "my primary data store";
+    DataStore primaryStore;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    TemplateService imageService;
+    @Inject
+    VolumeService volumeService;
+    @Inject
+    VMTemplateDao imageDataDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    HostPodDao podDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    DataCenterDao dcDao;
+    @Inject
+    PrimaryDataStoreDao primaryStoreDao;
+    @Inject
+    DataStoreProviderManager dataStoreProviderMgr;
+    @Inject
+    TemplateDataStoreDao templateStoreDao;
+    @Inject
+    TemplateDataFactory templateFactory;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    ResourceManager resourceMgr;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    EndPointSelector epSelector;
+    @Inject
+    HypervisorGuruManager hyGuruMgr;
+    long primaryStoreId;
+    VMTemplateVO image;
+    String imageStoreName = "testImageStore";
+
+    @Test(priority = -1)
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+
+        host = hostDao.findByGuid(this.getHostGuid());
+        if (host != null) {
+            dcId = host.getDataCenterId();
+            clusterId = host.getClusterId();
+            podId = host.getPodId();
+            imageStore = this.imageStoreDao.findByName(imageStoreName);
+        } else {
+            // create data center
+            DataCenterVO dc =
+                    new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                            true, null, null);
+            dc = dcDao.persist(dc);
+            dcId = dc.getId();
+            // create pod
+
+            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
+            pod = podDao.persist(pod);
+            podId = pod.getId();
+            // create xenserver cluster
+            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+            cluster.setHypervisorType(this.getHypervisor().toString());
+            cluster.setClusterType(ClusterType.CloudManaged);
+            cluster.setManagedState(ManagedState.Managed);
+            cluster = clusterDao.persist(cluster);
+            clusterId = cluster.getId();
+            // create xenserver host
+
+            host = new HostVO(this.getHostGuid());
+            host.setName("devcloud xenserver host");
+            host.setType(Host.Type.Routing);
+            host.setPrivateIpAddress(this.getHostIp());
+            host.setDataCenterId(dc.getId());
+            host.setVersion("6.0.1");
+            host.setAvailable(true);
+            host.setSetup(true);
+            host.setPodId(podId);
+            host.setLastPinged(0);
+            host.setResourceState(ResourceState.Enabled);
+            host.setHypervisorType(this.getHypervisor());
+            host.setClusterId(cluster.getId());
+
+            host = hostDao.persist(host);
+
+            imageStore = new ImageStoreVO();
+            imageStore.setName(imageStoreName);
+            imageStore.setDataCenterId(dcId);
+            imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
+            imageStore.setRole(DataStoreRole.Image);
+            imageStore.setUrl(this.getSecondaryStorage());
+            imageStore.setUuid(UUID.randomUUID().toString());
+            imageStore.setProtocol("nfs");
+            imageStore = imageStoreDao.persist(imageStore);
+        }
+
+        image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+        image.setUrl(this.getTemplateUrl());
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+
+        image = imageDataDao.persist(image);
+
+        /*
+         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
+         *
+         * templateStore.setDataStoreId(imageStore.getId());
+         * templateStore.setDownloadPercent(100);
+         * templateStore.setDownloadState(Status.DOWNLOADED);
+         * templateStore.setDownloadUrl(imageStore.getUrl());
+         * templateStore.setInstallPath(this.getImageInstallPath());
+         * templateStore.setTemplateId(image.getId());
+         * templateStoreDao.persist(templateStore);
+         */
+
+        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
+        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
+        DataObject templateOnStore = store.create(template);
+        TemplateObjectTO to = new TemplateObjectTO();
+        to.setPath(this.getImageInstallPath());
+        to.setFormat(ImageFormat.VHD);
+        to.setSize(100L);
+        CopyCmdAnswer answer = new CopyCmdAnswer(to);
+        templateOnStore.processEvent(Event.CreateOnlyRequested);
+        templateOnStore.processEvent(Event.OperationSuccessed, answer);
+
+    }
+
+    @Override
+    protected void injectMockito() {
+        List<HostVO> hosts = new ArrayList<HostVO>();
+        hosts.add(this.host);
+        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
+
+        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
+        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
+        Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(this.host.getId());
+    }
+
+    public DataStore createPrimaryDataStore() {
+        try {
+            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
+            if (pools.size() > 0) {
+                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
+            }
+
+            /*
+             * DataStoreProvider provider =
+             * dataStoreProviderMgr.getDataStoreProvider
+             * ("cloudstack primary data store provider"); Map<String, Object>
+             * params = new HashMap<String, Object>(); URI uri = new
+             * URI(this.getPrimaryStorageUrl()); params.put("url",
+             * this.getPrimaryStorageUrl()); params.put("server",
+             * uri.getHost()); params.put("path", uri.getPath());
+             * params.put("protocol",
+             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
+             * dcId); params.put("clusterId", clusterId); params.put("name",
+             * this.primaryName); params.put("port", 1); params.put("podId",
+             * this.podId); params.put("roles",
+             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
+             * params.put("providerName", String.valueOf(provider.getName()));
+             *
+             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+             * DataStore store = lifeCycle.initialize(params); ClusterScope
+             * scope = new ClusterScope(clusterId, podId, dcId);
+             * lifeCycle.attachCluster(store, scope);
+             */
+
+            StoragePoolVO pool = new StoragePoolVO();
+            pool.setClusterId(clusterId);
+            pool.setDataCenterId(dcId);
+            URI uri = new URI(this.getPrimaryStorageUrl());
+            pool.setHostAddress(uri.getHost());
+            pool.setPath(uri.getPath());
+            pool.setPort(0);
+            pool.setName(this.primaryName);
+            pool.setUuid(this.getPrimaryStorageUuid());
+            pool.setStatus(StoragePoolStatus.Up);
+            pool.setPoolType(StoragePoolType.NetworkFilesystem);
+            pool.setPodId(podId);
+            pool.setScope(ScopeType.CLUSTER);
+            pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
+            pool = this.primaryStoreDao.persist(pool);
+            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+            return store;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private VolumeVO createVolume(Long templateId, long dataStoreId) {
+        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, ProvisioningType.THIN, 1000, 0L, 0L, "");
+        volume.setPoolId(dataStoreId);
+        volume = volumeDao.persist(volume);
+        return volume;
+    }
+
+    @Test
+    public void testCopyBaseImage() {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future =
+                this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
+        try {
+            VolumeApiResult result = future.get();
+
+            AssertJUnit.assertTrue(result.isSuccess());
+
+            VolumeInfo newVol = result.getVolume();
+            boolean res = this.volumeService.destroyVolume(newVol.getId());
+            Assert.assertTrue(res);
+            VolumeInfo vol = this.volFactory.getVolume(volume.getId());
+            future = this.volumeService.expungeVolumeAsync(vol);
+            result = future.get();
+            Assert.assertTrue(result.isSuccess());
+        } catch (InterruptedException e) {
+            Assert.fail(e.toString());
+        } catch (ExecutionException e) {
+            Assert.fail(e.toString());
+        } catch (ConcurrentOperationException e) {
+            Assert.fail(e.toString());
+        }
+    }
+
+    @Test
+    public void testCreateDataDisk() throws InterruptedException, ExecutionException {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
+        VolumeApiResult result = future.get();
+        Assert.assertTrue(result.isSuccess());
+    }
+
+    @Test
+    public void testDeleteDisk() throws InterruptedException, ExecutionException, ConcurrentOperationException {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
+
+        VolumeApiResult result = future.get();
+        Assert.assertTrue(result.isSuccess());
+        VolumeInfo vol = result.getVolume();
+
+        boolean res = this.volumeService.destroyVolume(volInfo.getId());
+        Assert.assertTrue(res);
+        volInfo = this.volFactory.getVolume(vol.getId());
+        future = this.volumeService.expungeVolumeAsync(volInfo);
+        result = future.get();
+        Assert.assertTrue(result.isSuccess());
+    }
+
+    private VMTemplateVO createTemplateInDb() {
+        image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+        image = imageDataDao.persist(image);
+        return image;
+    }
+
+    @Test
+    public void testCreateTemplateFromVolume() throws InterruptedException, ExecutionException {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
+
+        VolumeApiResult result = future.get();
+
+        AssertJUnit.assertTrue(result.isSuccess());
+        volInfo = result.getVolume();
+        VMTemplateVO templateVO = createTemplateInDb();
+        TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
+        DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
+
+        AsyncCallFuture<TemplateApiResult> templateResult = this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
+        TemplateApiResult templateApiResult = templateResult.get();
+        Assert.assertTrue(templateApiResult.isSuccess());
+    }
+}
diff --git a/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java
new file mode 100644
index 0000000..98af170
--- /dev/null
+++ b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/VolumeTestVmware.java
@@ -0,0 +1,441 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.test.context.ContextConfiguration;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+
+@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
+public class VolumeTestVmware extends CloudStackTestNGBase {
+    @Inject
+    ImageStoreDao imageStoreDao;
+    ImageStoreVO imageStore;
+    Long dcId;
+    Long clusterId;
+    Long podId;
+    HostVO host;
+    String primaryName = "my primary data store";
+    DataStore primaryStore;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    TemplateService imageService;
+    @Inject
+    VolumeService volumeService;
+    @Inject
+    VMTemplateDao imageDataDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    HostPodDao podDao;
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    ClusterDetailsDao clusterDetailsDao;
+    @Inject
+    DataCenterDao dcDao;
+    @Inject
+    PrimaryDataStoreDao primaryStoreDao;
+    @Inject
+    DataStoreProviderManager dataStoreProviderMgr;
+    @Inject
+    TemplateDataStoreDao templateStoreDao;
+    @Inject
+    TemplateDataFactory templateFactory;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    ResourceManager resourceMgr;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    EndPointSelector epSelector;
+    long primaryStoreId;
+    VMTemplateVO image;
+    String imageStoreName = "testImageStore";
+
+    @Test(priority = -1)
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+
+        host = hostDao.findByGuid(this.getHostGuid());
+        if (host != null) {
+            dcId = host.getDataCenterId();
+            clusterId = host.getClusterId();
+            podId = host.getPodId();
+            imageStore = this.imageStoreDao.findByName(imageStoreName);
+        } else {
+            // create data center
+            DataCenterVO dc =
+                    new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                            true, null, null);
+            dc = dcDao.persist(dc);
+            dcId = dc.getId();
+            // create pod
+
+            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
+            pod = podDao.persist(pod);
+            podId = pod.getId();
+            // create xen cluster
+            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
+            cluster.setHypervisorType(HypervisorType.VMware.toString());
+            cluster.setClusterType(ClusterType.ExternalManaged);
+            cluster.setManagedState(ManagedState.Managed);
+            cluster = clusterDao.persist(cluster);
+            clusterId = cluster.getId();
+
+            // setup vcenter
+            ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null);
+            this.clusterDetailsDao.persist(clusterDetailVO);
+            clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "username", null);
+            this.clusterDetailsDao.persist(clusterDetailVO);
+            clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "password", null);
+            this.clusterDetailsDao.persist(clusterDetailVO);
+            // create xen host
+
+            host = new HostVO(this.getHostGuid());
+            host.setName("devcloud vmware host");
+            host.setType(Host.Type.Routing);
+            host.setPrivateIpAddress(this.getHostIp());
+            host.setDataCenterId(dc.getId());
+            host.setVersion("6.0.1");
+            host.setAvailable(true);
+            host.setSetup(true);
+            host.setPodId(podId);
+            host.setLastPinged(0);
+            host.setResourceState(ResourceState.Enabled);
+            host.setHypervisorType(HypervisorType.VMware);
+            host.setClusterId(cluster.getId());
+
+            host = hostDao.persist(host);
+
+            imageStore = new ImageStoreVO();
+            imageStore.setName(imageStoreName);
+            imageStore.setDataCenterId(dcId);
+            imageStore.setProviderName("CloudStack ImageStore Provider");
+            imageStore.setRole(DataStoreRole.Image);
+            imageStore.setUrl(this.getSecondaryStorage());
+            imageStore.setUuid(UUID.randomUUID().toString());
+            imageStore.setProtocol("nfs");
+            imageStore = imageStoreDao.persist(imageStore);
+        }
+
+        image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+        image.setUrl(this.getTemplateUrl());
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+
+        image = imageDataDao.persist(image);
+
+        /*
+         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
+         *
+         * templateStore.setDataStoreId(imageStore.getId());
+         * templateStore.setDownloadPercent(100);
+         * templateStore.setDownloadState(Status.DOWNLOADED);
+         * templateStore.setDownloadUrl(imageStore.getUrl());
+         * templateStore.setInstallPath(this.getImageInstallPath());
+         * templateStore.setTemplateId(image.getId());
+         * templateStoreDao.persist(templateStore);
+         */
+
+        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
+        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
+        DataObject templateOnStore = store.create(template);
+        TemplateObjectTO to = new TemplateObjectTO();
+        to.setPath(this.getImageInstallPath());
+        CopyCmdAnswer answer = new CopyCmdAnswer(to);
+        templateOnStore.processEvent(Event.CreateOnlyRequested);
+        templateOnStore.processEvent(Event.OperationSuccessed, answer);
+
+    }
+
+    @Override
+    protected void injectMockito() {
+        List<HostVO> hosts = new ArrayList<HostVO>();
+        hosts.add(this.host);
+        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
+
+        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
+        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
+        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
+    }
+
+    public DataStore createPrimaryDataStore() {
+        try {
+            String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
+            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
+            if (pools.size() > 0) {
+                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
+            }
+
+            /*
+             * DataStoreProvider provider =
+             * dataStoreProviderMgr.getDataStoreProvider
+             * ("cloudstack primary data store provider"); Map<String, Object>
+             * params = new HashMap<String, Object>(); URI uri = new
+             * URI(this.getPrimaryStorageUrl()); params.put("url",
+             * this.getPrimaryStorageUrl()); params.put("server",
+             * uri.getHost()); params.put("path", uri.getPath());
+             * params.put("protocol",
+             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
+             * dcId); params.put("clusterId", clusterId); params.put("name",
+             * this.primaryName); params.put("port", 1); params.put("podId",
+             * this.podId); params.put("roles",
+             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
+             * params.put("providerName", String.valueOf(provider.getName()));
+             *
+             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+             * DataStore store = lifeCycle.initialize(params); ClusterScope
+             * scope = new ClusterScope(clusterId, podId, dcId);
+             * lifeCycle.attachCluster(store, scope);
+             */
+
+            StoragePoolVO pool = new StoragePoolVO();
+            pool.setClusterId(clusterId);
+            pool.setDataCenterId(dcId);
+            URI uri = new URI(this.getPrimaryStorageUrl());
+            pool.setHostAddress(uri.getHost());
+            pool.setPath(uri.getPath());
+            pool.setPort(0);
+            pool.setName(this.primaryName);
+            pool.setUuid(this.getPrimaryStorageUuid());
+            pool.setStatus(StoragePoolStatus.Up);
+            pool.setPoolType(StoragePoolType.VMFS);
+            pool.setPodId(podId);
+            pool.setScope(ScopeType.CLUSTER);
+            pool.setStorageProviderName("cloudstack primary data store provider");
+            pool = this.primaryStoreDao.persist(pool);
+            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+            return store;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private VolumeVO createVolume(Long templateId, long dataStoreId) {
+        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, ProvisioningType.THIN, 1000, 0L, 0L, "");
+        volume.setPoolId(dataStoreId);
+        volume = volumeDao.persist(volume);
+        return volume;
+    }
+
+    // @Test
+    public void testCopyBaseImage() {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future =
+                this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
+        try {
+            VolumeApiResult result = future.get();
+
+            AssertJUnit.assertTrue(result.isSuccess());
+
+            VolumeInfo newVol = result.getVolume();
+            this.volumeService.destroyVolume(newVol.getId());
+            VolumeInfo vol = this.volFactory.getVolume(volume.getId());
+            this.volumeService.expungeVolumeAsync(vol);
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ConcurrentOperationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testCreateDataDisk() {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        this.volumeService.createVolumeAsync(volInfo, primaryStore);
+    }
+
+    @Test
+    public void testDeleteDisk() {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
+        try {
+            VolumeApiResult result = future.get();
+            VolumeInfo vol = result.getVolume();
+
+            this.volumeService.destroyVolume(volInfo.getId());
+            volInfo = this.volFactory.getVolume(vol.getId());
+            this.volumeService.expungeVolumeAsync(volInfo);
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ConcurrentOperationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+
+    private VMTemplateVO createTemplateInDb() {
+        image = new VMTemplateVO();
+        image.setTemplateType(TemplateType.USER);
+
+        image.setUniqueName(UUID.randomUUID().toString());
+        image.setName(UUID.randomUUID().toString());
+        image.setPublicTemplate(true);
+        image.setFeatured(true);
+        image.setRequiresHvm(true);
+        image.setBits(64);
+        image.setFormat(Storage.ImageFormat.VHD);
+        image.setEnablePassword(true);
+        image.setEnableSshKey(true);
+        image.setGuestOSId(1);
+        image.setBootable(true);
+        image.setPrepopulate(true);
+        image.setCrossZones(true);
+        image.setExtractable(true);
+        image = imageDataDao.persist(image);
+        return image;
+    }
+
+    @Test
+    public void testCreateTemplateFromVolume() {
+        DataStore primaryStore = createPrimaryDataStore();
+        primaryStoreId = primaryStore.getId();
+        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
+        VolumeVO volume = createVolume(null, primaryStore.getId());
+        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
+        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
+        try {
+            VolumeApiResult result = future.get();
+
+            AssertJUnit.assertTrue(result.isSuccess());
+            volInfo = result.getVolume();
+            VMTemplateVO templateVO = createTemplateInDb();
+            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
+            DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
+
+            this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
+        } catch (InterruptedException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/XenEndpoint.java b/engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/XenEndpoint.java
similarity index 100%
rename from engine/storage/integration-test/test/org/apache/cloudstack/storage/test/XenEndpoint.java
rename to engine/storage/integration-test/src/test/java/org/apache/cloudstack/storage/test/XenEndpoint.java
diff --git a/engine/storage/integration-test/test/resources/StorageAllocatorTestContext.xml b/engine/storage/integration-test/src/test/resources/StorageAllocatorTestContext.xml
similarity index 100%
rename from engine/storage/integration-test/test/resources/StorageAllocatorTestContext.xml
rename to engine/storage/integration-test/src/test/resources/StorageAllocatorTestContext.xml
diff --git a/engine/storage/integration-test/test/resources/component.xml b/engine/storage/integration-test/src/test/resources/component.xml
similarity index 100%
rename from engine/storage/integration-test/test/resources/component.xml
rename to engine/storage/integration-test/src/test/resources/component.xml
diff --git a/engine/storage/integration-test/test/resource/fakeDriverTestContext.xml b/engine/storage/integration-test/src/test/resources/fakeDriverTestContext.xml
similarity index 100%
rename from engine/storage/integration-test/test/resource/fakeDriverTestContext.xml
rename to engine/storage/integration-test/src/test/resources/fakeDriverTestContext.xml
diff --git a/engine/storage/integration-test/test/resources/s3_testng.xml b/engine/storage/integration-test/src/test/resources/s3_testng.xml
similarity index 100%
rename from engine/storage/integration-test/test/resources/s3_testng.xml
rename to engine/storage/integration-test/src/test/resources/s3_testng.xml
diff --git a/engine/storage/integration-test/test/resources/storageContext.xml b/engine/storage/integration-test/src/test/resources/storageContext.xml
similarity index 100%
rename from engine/storage/integration-test/test/resources/storageContext.xml
rename to engine/storage/integration-test/src/test/resources/storageContext.xml
diff --git a/engine/storage/integration-test/test/resources/testng.xml b/engine/storage/integration-test/src/test/resources/testng.xml
similarity index 100%
rename from engine/storage/integration-test/test/resources/testng.xml
rename to engine/storage/integration-test/src/test/resources/testng.xml
diff --git a/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java b/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
deleted file mode 100644
index 38b4f29..0000000
--- a/engine/storage/integration-test/test/com/cloud/vm/snapshot/dao/VmSnapshotDaoTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.vm.snapshot.dao;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import org.apache.cloudstack.storage.test.CloudStackTestNGBase;
-
-import com.cloud.vm.snapshot.VMSnapshotDetailsVO;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = "classpath:/storageContext.xml")
-public class VmSnapshotDaoTest extends CloudStackTestNGBase {
-    @Inject
-    VMSnapshotDetailsDao vmsnapshotDetailsDao;
-
-    @Test
-    public void testVmSnapshotDetails() {
-        VMSnapshotDetailsVO detailsVO = new VMSnapshotDetailsVO(1L, "test", "foo", display);
-        vmsnapshotDetailsDao.persist(detailsVO);
-        Map<String, String> details = vmsnapshotDetailsDao.listDetailsKeyPairs(1L);
-        Assert.assertTrue(details.containsKey("test"));
-    }
-
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java
deleted file mode 100644
index 3c4caee..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java
+++ /dev/null
@@ -1,486 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.allocator;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.DB;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = "classpath:/storageContext.xml")
-public class StorageAllocatorTest {
-    @Inject
-    PrimaryDataStoreDao storagePoolDao;
-    @Inject
-    StorageManager storageMgr;
-    @Inject
-    DiskOfferingDao diskOfferingDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    HostPodDao podDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    DataCenterDao dcDao;
-    @Inject
-    StoragePoolDetailsDao poolDetailsDao;
-    @Inject
-    DataStoreProviderManager providerMgr;
-    @Inject
-    ConfigurationDao configDao;
-    Long dcId = 1l;
-    Long podId = 1l;
-    Long clusterId = 1l;
-    Long volumeId = null;
-    Long diskOfferingId = null;
-    Long storagePoolId = null;
-    VolumeVO volume = null;
-    DiskOfferingVO diskOffering = null;
-    StoragePoolVO storage = null;
-
-    @Before
-    @DB
-    public void setup() throws Exception {
-        ConfigurationVO cfg = configDao.findByName(Config.VmAllocationAlgorithm.key());
-        if (cfg == null) {
-            ConfigurationVO configVO = new ConfigurationVO("test", "DEFAULT", "test", Config.VmAllocationAlgorithm.key(), "userdispersing", null);
-            configDao.persist(configVO);
-        }
-        ComponentContext.initComponentsLifeCycle();
-
-    }
-
-    protected void createDb() {
-        DataCenterVO dc =
-            new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                true, null, null);
-        dc = dcDao.persist(dc);
-        dcId = dc.getId();
-
-        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "255.255.255.255", "", 8, "test");
-        pod = podDao.persist(pod);
-        podId = pod.getId();
-
-        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-        cluster.setHypervisorType(HypervisorType.XenServer.toString());
-        cluster.setClusterType(ClusterType.CloudManaged);
-        cluster.setManagedState(ManagedState.Managed);
-        cluster = clusterDao.persist(cluster);
-        clusterId = cluster.getId();
-
-        DataStoreProvider provider = providerMgr.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY);
-        storage = new StoragePoolVO();
-        storage.setDataCenterId(dcId);
-        storage.setPodId(podId);
-        storage.setPoolType(StoragePoolType.NetworkFilesystem);
-        storage.setClusterId(clusterId);
-        storage.setStatus(StoragePoolStatus.Up);
-        storage.setScope(ScopeType.CLUSTER);
-        storage.setUsedBytes(1000);
-        storage.setCapacityBytes(20000);
-        storage.setHostAddress(UUID.randomUUID().toString());
-        storage.setPath(UUID.randomUUID().toString());
-        storage.setStorageProviderName(provider.getName());
-        storage = storagePoolDao.persist(storage);
-        storagePoolId = storage.getId();
-
-        storageMgr.createCapacityEntry(storage.getId());
-
-        diskOffering = new DiskOfferingVO();
-        diskOffering.setDiskSize(500);
-        diskOffering.setName("test-disk");
-        diskOffering.setSystemUse(false);
-        diskOffering.setUseLocalStorage(false);
-        diskOffering.setCustomized(false);
-        diskOffering.setRecreatable(false);
-        diskOffering = diskOfferingDao.persist(diskOffering);
-        diskOfferingId = diskOffering.getId();
-
-        volume =
-            new VolumeVO(Volume.Type.ROOT, "volume", dcId, 1, 1, diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getMinIops(), diskOffering.getMaxIops(),
-                "");
-        volume = volumeDao.persist(volume);
-        volumeId = volume.getId();
-    }
-
-    @Inject
-    List<StoragePoolAllocator> allocators;
-
-    @Test
-    public void testClusterAllocatorMultiplePools() {
-        Long newStorageId = null;
-        try {
-            createDb();
-
-            DataStoreProvider provider = providerMgr.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY);
-            storage = new StoragePoolVO();
-            storage.setDataCenterId(dcId);
-            storage.setPodId(podId);
-            storage.setPoolType(StoragePoolType.NetworkFilesystem);
-            storage.setClusterId(clusterId);
-            storage.setStatus(StoragePoolStatus.Up);
-            storage.setScope(ScopeType.CLUSTER);
-            storage.setUsedBytes(1000);
-            storage.setCapacityBytes(20000);
-            storage.setHostAddress(UUID.randomUUID().toString());
-            storage.setPath(UUID.randomUUID().toString());
-            storage.setStorageProviderName(provider.getName());
-            StoragePoolVO newStorage = storagePoolDao.persist(storage);
-            newStorageId = newStorage.getId();
-
-            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.size(), 1);
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-
-            if (newStorageId != null) {
-                storagePoolDao.remove(newStorageId);
-            }
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testClusterAllocator() {
-        try {
-            createDb();
-            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testClusterAllocatorWithTags() {
-        try {
-            createDb();
-            StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true", true);
-            poolDetailsDao.persist(detailVO);
-            DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
-            List<String> tags = new ArrayList<String>();
-            tags.add("high");
-            diskOff.setTagsArray(tags);
-            diskOfferingDao.update(diskOff.getId(), diskOff);
-
-            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testClusterAllocatorWithWrongTag() {
-        try {
-            createDb();
-            StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true", true);
-            poolDetailsDao.persist(detailVO);
-            DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
-            List<String> tags = new ArrayList<String>();
-            tags.add("low");
-            diskOff.setTagsArray(tags);
-            diskOfferingDao.update(diskOff.getId(), diskOff);
-
-            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct != 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testZoneWideStorageAllocator() {
-        try {
-            createDb();
-
-            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
-            pool.setHypervisor(HypervisorType.KVM);
-            pool.setScope(ScopeType.ZONE);
-            pool.setClusterId(null);
-            pool.setPodId(null);
-            storagePoolDao.update(pool.getId(), pool);
-
-            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            Mockito.when(storageMgr.storagePoolHasEnoughIops(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testCLOUDSTACK3481() {
-        try {
-            createDb();
-
-            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
-            pool.setHypervisor(HypervisorType.KVM);
-            pool.setScope(ScopeType.ZONE);
-            pool.setClusterId(null);
-            pool.setPodId(null);
-            storagePoolDao.update(pool.getId(), pool);
-
-            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Account account = Mockito.mock(Account.class);
-            Mockito.when(account.getAccountId()).thenReturn(1L);
-            Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
-            Mockito.when(vmProfile.getOwner()).thenReturn(account);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            Mockito.when(storageMgr.storagePoolHasEnoughIops(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testPoolStateIsNotUp() {
-        try {
-            createDb();
-
-            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
-            pool.setScope(ScopeType.ZONE);
-            pool.setStatus(StoragePoolStatus.Maintenance);
-            storagePoolDao.update(pool.getId(), pool);
-
-            DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct == 1) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    @Test
-    public void testLocalStorageAllocator() {
-        try {
-            createDb();
-
-            StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
-            pool.setScope(ScopeType.HOST);
-            storagePoolDao.update(pool.getId(), pool);
-
-            DiskOfferingVO diskOff = diskOfferingDao.findById(diskOfferingId);
-            diskOff.setUseLocalStorage(true);
-            diskOfferingDao.update(diskOfferingId, diskOff);
-
-            DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
-            VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
-            Mockito.when(storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), Matchers.any(StoragePool.class))).thenReturn(true);
-            DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
-            int foundAcct = 0;
-            for (StoragePoolAllocator allocator : allocators) {
-                List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
-                if (!pools.isEmpty()) {
-                    Assert.assertEquals(pools.get(0).getId(), storage.getId());
-                    foundAcct++;
-                }
-            }
-
-            if (foundAcct > 1 || foundAcct == 0) {
-                Assert.fail();
-            }
-        } catch (Exception e) {
-            cleanDb();
-            Assert.fail();
-        }
-    }
-
-    protected void cleanDb() {
-        if (volumeId != null) {
-            volumeDao.remove(volumeId);
-            volumeId = null;
-        }
-        if (diskOfferingId != null) {
-            diskOfferingDao.remove(diskOfferingId);
-            diskOfferingId = null;
-        }
-        if (storagePoolId != null) {
-            storagePoolDao.remove(storagePoolId);
-            storagePoolId = null;
-        }
-        if (clusterId != null) {
-            clusterDao.remove(clusterId);
-            clusterId = null;
-        }
-        if (podId != null) {
-            podDao.remove(podId);
-            podId = null;
-        }
-        if (dcId != null) {
-            dcDao.remove(dcId);
-            dcId = null;
-        }
-    }
-
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
deleted file mode 100644
index 0e4755e..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.StartupCommandProcessor;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.SetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.manager.Commands;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostEnvironment;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Status.Event;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.vmware.VmwareServerDiscoverer;
-import com.cloud.hypervisor.xenserver.resource.XcpOssResource;
-import com.cloud.resource.ServerResource;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-
-public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentManager {
-    private static final Logger logger = Logger.getLogger(DirectAgentManagerSimpleImpl.class);
-    private final Map<Long, ServerResource> hostResourcesMap = new HashMap<Long, ServerResource>();
-    @Inject
-    HostDao hostDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    ClusterDetailsDao clusterDetailsDao;
-    @Inject
-    HostDao _hostDao;
-    protected StateMachine2<Status, Event, Host> _statusStateMachine = Status.getStateMachine();
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void rescan() {
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Answer easySend(Long hostId, Command cmd) {
-        try {
-            return this.send(hostId, cmd);
-        } catch (AgentUnavailableException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (OperationTimedoutException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    protected void loadResource(Long hostId) {
-        HostVO host = hostDao.findById(hostId);
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.put("guid", host.getGuid());
-        params.put("ipaddress", host.getPrivateIpAddress());
-        params.put("username", "root");
-        params.put("password", "password");
-        params.put("zone", String.valueOf(host.getDataCenterId()));
-        params.put("pod", String.valueOf(host.getPodId()));
-
-        ServerResource resource = null;
-        if (host.getHypervisorType() == HypervisorType.XenServer) {
-            resource = new XcpOssResource();
-            try {
-                resource.configure(host.getName(), params);
-
-            } catch (ConfigurationException e) {
-                logger.debug("Failed to load resource:" + e.toString());
-            }
-        } else if (host.getHypervisorType() == HypervisorType.KVM) {
-            resource = new LibvirtComputingResource();
-            try {
-                params.put("public.network.device", "cloudbr0");
-                params.put("private.network.device", "cloudbr0");
-                resource.configure(host.getName(), params);
-            } catch (ConfigurationException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } else if (host.getHypervisorType() == HypervisorType.VMware) {
-            ClusterVO cluster = clusterDao.findById(host.getClusterId());
-            String url = clusterDetailsDao.findDetail(cluster.getId(), "url").getValue();
-            URI uri;
-            try {
-                uri = new URI(url);
-                String userName = clusterDetailsDao.findDetail(cluster.getId(), "username").getValue();
-                String password = clusterDetailsDao.findDetail(cluster.getId(), "password").getValue();
-                VmwareServerDiscoverer discover = new VmwareServerDiscoverer();
-
-                Map<? extends ServerResource, Map<String, String>> resources =
-                    discover.find(host.getDataCenterId(), host.getPodId(), host.getClusterId(), uri, userName, password, null);
-                for (Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
-                    resource = entry.getKey();
-                }
-                if (resource == null) {
-                    throw new CloudRuntimeException("can't find resource");
-                }
-            } catch (DiscoveryException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            } catch (URISyntaxException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        }
-
-        hostResourcesMap.put(hostId, resource);
-        HostEnvironment env = new HostEnvironment();
-        SetupCommand cmd = new SetupCommand(env);
-        cmd.setNeedSetup(true);
-
-        resource.executeRequest(cmd);
-    }
-
-    @Override
-    public synchronized Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
-        ServerResource resource = hostResourcesMap.get(hostId);
-        if (resource == null) {
-            loadResource(hostId);
-            resource = hostResourcesMap.get(hostId);
-        }
-
-        if (resource == null) {
-            return null;
-        }
-
-        Answer answer = resource.executeRequest(cmd);
-        return answer;
-    }
-
-    @Override
-    public Answer[] send(Long hostId, Commands cmds) throws AgentUnavailableException, OperationTimedoutException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, OperationTimedoutException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public long send(Long hostId, Commands cmds, Listener listener) throws AgentUnavailableException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int registerForHostEvents(Listener listener, boolean connections, boolean commands, boolean priority) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int registerForInitialConnects(StartupCommandProcessor creator, boolean priority) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void unregisterForHostEvents(int id) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Answer sendTo(Long dcId, HypervisorType type, Command cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean agentStatusTransitTo(HostVO host, Event e, long msId) {
-        try {
-            return _statusStateMachine.transitTo(host, e, host.getId(), _hostDao);
-        } catch (NoTransitionException e1) {
-            e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-        }
-        return true;
-
-    }
-
-    @Override
-    public void disconnectWithoutInvestigation(long hostId, Event event) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void pullAgentToMaintenance(long hostId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void pullAgentOutMaintenance(long hostId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean reconnect(long hostId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isAgentAttached(long hostId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean handleDirectConnectAgent(Host host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance, boolean newHost) throws ConnectionException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void notifyMonitorsOfHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void notifyMonitorsOfRemovedHost(long hostId, long clusterId) {
-    }
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
deleted file mode 100644
index 1b5746d..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.testng.AssertJUnit;
-import org.testng.annotations.Test;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-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.StorageStrategyFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.storage.LocalHostEndpoint;
-import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Command;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-
-@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
-public class SnapshotTest extends CloudStackTestNGBase {
-    @Inject
-    ImageStoreDao imageStoreDao;
-    ImageStoreVO imageStore;
-    Long dcId;
-    Long clusterId;
-    Long podId;
-    HostVO host;
-    String primaryName = "my primary data store";
-    DataStore primaryStore;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    TemplateService imageService;
-    @Inject
-    VolumeService volumeService;
-    @Inject
-    VMTemplateDao imageDataDao;
-    @Inject
-    HostPodDao podDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    DataCenterDao dcDao;
-    @Inject
-    PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    TemplateDataStoreDao templateStoreDao;
-    @Inject
-    TemplateDataFactory templateFactory;
-    @Inject
-    PrimaryDataStoreDao primaryDataStoreDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    HypervisorGuruManager hyGuruMgr;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    ResourceManager resourceMgr;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    StorageStrategyFactory storageStrategyFactory;
-    @Inject
-    List<SnapshotStrategy> snapshotStrategies;
-    @Inject
-    SnapshotService snapshotSvr;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    EndPointSelector epSelector;
-    @Inject
-    VolumeDao volumeDao;
-
-    long primaryStoreId;
-    VMTemplateVO image;
-    String imageStoreName = "testImageStore";
-    RemoteHostEndPoint remoteEp;
-
-    @Test(priority = -1)
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-
-        host = hostDao.findByGuid(this.getHostGuid());
-        if (host != null) {
-            dcId = host.getDataCenterId();
-            clusterId = host.getClusterId();
-            podId = host.getPodId();
-            imageStore = this.imageStoreDao.findByName(imageStoreName);
-        } else {
-            // create data center
-            DataCenterVO dc =
-                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                    true, null, null);
-            dc = dcDao.persist(dc);
-            dcId = dc.getId();
-            // create pod
-
-            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
-            pod = podDao.persist(pod);
-            podId = pod.getId();
-            // create xenserver cluster
-            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-            cluster.setHypervisorType(this.getHypervisor().toString());
-            cluster.setClusterType(ClusterType.CloudManaged);
-            cluster.setManagedState(ManagedState.Managed);
-            cluster = clusterDao.persist(cluster);
-            clusterId = cluster.getId();
-            // create xenserver host
-
-            host = new HostVO(this.getHostGuid());
-            host.setName("devcloud xenserver host");
-            host.setType(Host.Type.Routing);
-            host.setPrivateIpAddress(this.getHostIp());
-            host.setDataCenterId(dc.getId());
-            host.setVersion("6.0.1");
-            host.setAvailable(true);
-            host.setSetup(true);
-            host.setPodId(podId);
-            host.setLastPinged(0);
-            host.setResourceState(ResourceState.Enabled);
-            host.setHypervisorType(this.getHypervisor());
-            host.setClusterId(cluster.getId());
-
-            host = hostDao.persist(host);
-
-            imageStore = new ImageStoreVO();
-            imageStore.setName(imageStoreName);
-            imageStore.setDataCenterId(dcId);
-            imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
-            imageStore.setRole(DataStoreRole.Image);
-            imageStore.setUrl(this.getSecondaryStorage());
-            imageStore.setUuid(UUID.randomUUID().toString());
-            imageStore.setProtocol("nfs");
-            imageStore = imageStoreDao.persist(imageStore);
-        }
-
-        image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-        image.setUrl(this.getTemplateUrl());
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-
-        image = imageDataDao.persist(image);
-
-        /*
-         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
-         *
-         * templateStore.setDataStoreId(imageStore.getId());
-         * templateStore.setDownloadPercent(100);
-         * templateStore.setDownloadState(Status.DOWNLOADED);
-         * templateStore.setDownloadUrl(imageStore.getUrl());
-         * templateStore.setInstallPath(this.getImageInstallPath());
-         * templateStore.setTemplateId(image.getId());
-         * templateStoreDao.persist(templateStore);
-         */
-
-        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
-        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
-        DataObject templateOnStore = store.create(template);
-        TemplateObjectTO to = new TemplateObjectTO();
-        to.setPath(this.getImageInstallPath());
-        to.setFormat(ImageFormat.VHD);
-        to.setSize(1000L);
-        CopyCmdAnswer answer = new CopyCmdAnswer(to);
-        templateOnStore.processEvent(Event.CreateOnlyRequested);
-        templateOnStore.processEvent(Event.OperationSuccessed, answer);
-
-    }
-
-    @Override
-    protected void injectMockito() {
-        List<HostVO> hosts = new ArrayList<HostVO>();
-        hosts.add(this.host);
-        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
-        remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(remoteEp);
-        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);
-        Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(this.host.getId());
-
-    }
-
-    public DataStore createPrimaryDataStore() {
-        try {
-            String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
-            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
-            if (pools.size() > 0) {
-                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
-            }
-
-            /*
-             * DataStoreProvider provider =
-             * dataStoreProviderMgr.getDataStoreProvider
-             * ("cloudstack primary data store provider"); Map<String, Object>
-             * params = new HashMap<String, Object>(); URI uri = new
-             * URI(this.getPrimaryStorageUrl()); params.put("url",
-             * this.getPrimaryStorageUrl()); params.put("server",
-             * uri.getHost()); params.put("path", uri.getPath());
-             * params.put("protocol",
-             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
-             * dcId); params.put("clusterId", clusterId); params.put("name",
-             * this.primaryName); params.put("port", 1); params.put("podId",
-             * this.podId); params.put("roles",
-             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
-             * params.put("providerName", String.valueOf(provider.getName()));
-             *
-             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-             * DataStore store = lifeCycle.initialize(params); ClusterScope
-             * scope = new ClusterScope(clusterId, podId, dcId);
-             * lifeCycle.attachCluster(store, scope);
-             */
-
-            StoragePoolVO pool = new StoragePoolVO();
-            pool.setClusterId(clusterId);
-            pool.setDataCenterId(dcId);
-            URI uri = new URI(this.getPrimaryStorageUrl());
-            pool.setHostAddress(uri.getHost());
-            pool.setPath(uri.getPath());
-            pool.setPort(0);
-            pool.setName(this.primaryName);
-            pool.setUuid(this.getPrimaryStorageUuid());
-            pool.setStatus(StoragePoolStatus.Up);
-            pool.setPoolType(StoragePoolType.NetworkFilesystem);
-            pool.setPodId(podId);
-            pool.setScope(ScopeType.CLUSTER);
-            pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
-            pool = this.primaryStoreDao.persist(pool);
-            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-            return store;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private SnapshotVO createSnapshotInDb(VolumeInfo volume) {
-        Snapshot.Type snapshotType = Snapshot.Type.MANUAL;
-        SnapshotVO snapshotVO =
-            new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(),
-                volume.getSize(), HypervisorType.XenServer);
-        return this.snapshotDao.persist(snapshotVO);
-    }
-
-    private VolumeVO createVolume(Long templateId, long dataStoreId) {
-
-        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
-        volume.setDataCenterId(this.dcId);
-        volume.setPoolId(dataStoreId);
-        volume = volumeDao.persist(volume);
-        return volume;
-    }
-
-    public VolumeInfo createCopyBaseImage() throws InterruptedException, ExecutionException {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future =
-            this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
-
-        VolumeApiResult result;
-        result = future.get();
-        Assert.assertTrue(result.isSuccess());
-        return result.getVolume();
-
-    }
-
-    private VMTemplateVO createTemplateInDb() {
-        VMTemplateVO image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-        image = imageDataDao.persist(image);
-        return image;
-    }
-
-    @Test
-    public void createVolumeFromSnapshot() throws InterruptedException, ExecutionException {
-        VolumeInfo vol = createCopyBaseImage();
-        SnapshotVO snapshotVO = createSnapshotInDb(vol);
-        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
-        boolean result = false;
-
-        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
-        if (snapshotStrategy != null) {
-            snapshot = snapshotStrategy.takeSnapshot(snapshot);
-            result = true;
-        }
-
-        AssertJUnit.assertTrue(result);
-
-        VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId());
-        VolumeInfo newVol = this.volFactory.getVolume(volVO.getId());
-        AsyncCallFuture<VolumeApiResult> volFuture = this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot);
-        VolumeApiResult apiResult = volFuture.get();
-        Assert.assertTrue(apiResult.isSuccess());
-    }
-
-    @Test
-    public void deleteSnapshot() throws InterruptedException, ExecutionException {
-        VolumeInfo vol = createCopyBaseImage();
-        SnapshotVO snapshotVO = createSnapshotInDb(vol);
-        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
-        SnapshotInfo newSnapshot = null;
-
-        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
-        if (snapshotStrategy != null) {
-            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
-
-        }
-        AssertJUnit.assertNotNull(newSnapshot);
-
-        // create another snapshot
-        for (SnapshotStrategy strategy : this.snapshotStrategies) {
-            if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) {
-                strategy.deleteSnapshot(newSnapshot.getId());
-            }
-        }
-
-    }
-
-    @Test
-    public void createTemplateFromSnapshot() throws InterruptedException, ExecutionException {
-        VolumeInfo vol = createCopyBaseImage();
-        SnapshotVO snapshotVO = createSnapshotInDb(vol);
-        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
-        boolean result = false;
-
-        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
-        if (snapshotStrategy != null) {
-            snapshot = snapshotStrategy.takeSnapshot(snapshot);
-            result = true;
-        }
-
-        AssertJUnit.assertTrue(result);
-        LocalHostEndpoint ep = new LocalHostEndpoint();
-        ep.setResource(new MockLocalNfsSecondaryStorageResource());
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
-
-        try {
-            VMTemplateVO templateVO = createTemplateInDb();
-            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
-            DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
-            AsyncCallFuture<TemplateApiResult> templateFuture = this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
-            TemplateApiResult apiResult = templateFuture.get();
-            Assert.assertTrue(apiResult.isSuccess());
-        } finally {
-            Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp);
-        }
-    }
-
-    @Test
-    public void createSnapshot() throws InterruptedException, ExecutionException {
-        VolumeInfo vol = createCopyBaseImage();
-        SnapshotVO snapshotVO = createSnapshotInDb(vol);
-        SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
-        SnapshotInfo newSnapshot = null;
-
-        SnapshotStrategy snapshotStrategy = storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
-        if (snapshotStrategy != null) {
-            newSnapshot = snapshotStrategy.takeSnapshot(snapshot);
-        }
-
-        AssertJUnit.assertNotNull(newSnapshot);
-
-        LocalHostEndpoint ep = new MockLocalHostEndPoint();
-        ep.setResource(new MockLocalNfsSecondaryStorageResource());
-        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
-
-        try {
-            for (SnapshotStrategy strategy : this.snapshotStrategies) {
-                if (strategy.canHandle(snapshot, SnapshotOperation.DELETE) != StrategyPriority.CANT_HANDLE) {
-                    boolean res = strategy.deleteSnapshot(newSnapshot.getId());
-                    Assert.assertTrue(res);
-                }
-            }
-        } finally {
-            Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp);
-        }
-    }
-
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
deleted file mode 100644
index 8c7b06d..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTestWithFakeData.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider;
-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.SnapshotResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.org.Cluster;
-import com.cloud.org.Managed;
-import com.cloud.server.LockMasterListener;
-import com.cloud.storage.CreateSnapshotPayload;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotPolicyVO;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotPolicyDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.Merovingian2;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath:/fakeDriverTestContext.xml"})
-public class SnapshotTestWithFakeData {
-    @Inject
-    SnapshotService snapshotService;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    PrimaryDataStoreDao primaryDataStoreDao;
-    @Inject
-    DataStoreManager dataStoreManager;
-    @Inject
-    SnapshotDataFactory snapshotDataFactory;
-    @Inject
-    PrimaryDataStoreProvider primaryDataStoreProvider;
-    @Inject
-    SnapshotDataStoreDao snapshotDataStoreDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    VolumeService volumeService;
-    @Inject
-    VolumeDataFactory volumeDataFactory;
-    @Inject
-    DataCenterDao dcDao;
-    Long dcId;
-    @Inject
-    HostPodDao podDao;
-    Long podId;
-    @Inject
-    ClusterDao clusterDao;
-    Long clusterId;
-    @Inject
-    ImageStoreDao imageStoreDao;
-    ImageStoreVO imageStore;
-    @Inject
-    AccountManager accountManager;
-    LockMasterListener lockMasterListener;
-    VolumeInfo vol = null;
-    FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
-    @Inject
-    MockStorageMotionStrategy mockStorageMotionStrategy;
-    Merovingian2 _lockMaster;
-    @Inject
-    SnapshotPolicyDao snapshotPolicyDao;
-
-    @Before
-    public void setUp() {
-        // create data center
-
-        DataCenterVO dc =
-            new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, DataCenter.NetworkType.Basic, null,
-                null, true, true, null, null);
-        dc = dcDao.persist(dc);
-        dcId = dc.getId();
-        // create pod
-
-        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "10.223.0.1", "10.233.2.2/25", 8, "test");
-        pod = podDao.persist(pod);
-        podId = pod.getId();
-        // create xenserver cluster
-        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-        cluster.setHypervisorType(Hypervisor.HypervisorType.XenServer.toString());
-        cluster.setClusterType(Cluster.ClusterType.CloudManaged);
-        cluster.setManagedState(Managed.ManagedState.Managed);
-        cluster = clusterDao.persist(cluster);
-        clusterId = cluster.getId();
-
-        imageStore = new ImageStoreVO();
-        imageStore.setName(UUID.randomUUID().toString());
-        imageStore.setDataCenterId(dcId);
-        imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
-        imageStore.setRole(DataStoreRole.Image);
-        imageStore.setUrl(UUID.randomUUID().toString());
-        imageStore.setUuid(UUID.randomUUID().toString());
-        imageStore.setProtocol("nfs");
-        imageStore = imageStoreDao.persist(imageStore);
-
-        when(primaryDataStoreProvider.configure(Matchers.anyMap())).thenReturn(true);
-        Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
-        types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
-
-        when(primaryDataStoreProvider.getTypes()).thenReturn(types);
-        when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
-        when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
-        User user = mock(User.class);
-        when(user.getId()).thenReturn(1L);
-        Account account = mock(Account.class);
-        when(account.getId()).thenReturn(1L);
-        when(accountManager.getSystemAccount()).thenReturn(account);
-        when(accountManager.getSystemUser()).thenReturn(user);
-
-        if (Merovingian2.getLockMaster() == null) {
-            _lockMaster = Merovingian2.createLockMaster(1234);
-        } else {
-            _lockMaster = Merovingian2.getLockMaster();
-        }
-        _lockMaster.cleanupThisServer();
-        ComponentContext.initComponentsLifeCycle();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        _lockMaster.cleanupThisServer();
-    }
-
-    private SnapshotVO createSnapshotInDb() {
-        Snapshot.Type snapshotType = Snapshot.Type.RECURRING;
-        SnapshotVO snapshotVO =
-            new SnapshotVO(dcId, 2, 1, 1L, 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(), 100, Hypervisor.HypervisorType.XenServer);
-        return snapshotDao.persist(snapshotVO);
-    }
-
-    private SnapshotVO createSnapshotInDb(Long volumeId) {
-        Snapshot.Type snapshotType = Snapshot.Type.DAILY;
-        SnapshotVO snapshotVO =
-            new SnapshotVO(dcId, 2, 1, volumeId, 1L, UUID.randomUUID().toString(), (short)snapshotType.ordinal(), snapshotType.name(), 100,
-                Hypervisor.HypervisorType.XenServer);
-        return snapshotDao.persist(snapshotVO);
-    }
-
-    private VolumeInfo createVolume(Long templateId, DataStore store) {
-        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
-        ;
-        volume.setPoolId(store.getId());
-
-        volume = volumeDao.persist(volume);
-        VolumeInfo volumeInfo = volumeDataFactory.getVolume(volume.getId(), store);
-        volumeInfo.stateTransit(Volume.Event.CreateRequested);
-        volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
-        return volumeInfo;
-    }
-
-    private DataStore createDataStore() throws URISyntaxException {
-        StoragePoolVO pool = new StoragePoolVO();
-        pool.setClusterId(clusterId);
-        pool.setDataCenterId(dcId);
-        URI uri = new URI("nfs://jfkdkf/fjdkfj");
-        pool.setHostAddress(uri.getHost());
-        pool.setPath(uri.getPath());
-        pool.setPort(0);
-        pool.setName(UUID.randomUUID().toString());
-        pool.setUuid(UUID.randomUUID().toString());
-        pool.setStatus(StoragePoolStatus.Up);
-        pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
-        pool.setPodId(podId);
-        pool.setScope(ScopeType.CLUSTER);
-        pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
-        pool = primaryDataStoreDao.persist(pool);
-        DataStore store = dataStoreManager.getPrimaryDataStore(pool.getId());
-        return store;
-    }
-
-    //@Test
-    public void testTakeSnapshot() throws URISyntaxException {
-        SnapshotVO snapshotVO = createSnapshotInDb();
-        DataStore store = createDataStore();
-        try {
-            SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
-            SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
-            Assert.assertTrue(result.isSuccess());
-            SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
-            Assert.assertTrue(storeRef != null);
-            Assert.assertTrue(storeRef.getState() == ObjectInDataStoreStateMachine.State.Ready);
-            snapshotInfo = result.getSnashot();
-            boolean deletResult = snapshotService.deleteSnapshot(snapshotInfo);
-            Assert.assertTrue(deletResult);
-            snapshotDataStoreDao.expunge(storeRef.getId());
-        } finally {
-            snapshotDao.expunge(snapshotVO.getId());
-            primaryDataStoreDao.remove(store.getId());
-        }
-    }
-
-    //@Test
-    public void testTakeSnapshotWithFailed() throws URISyntaxException {
-        SnapshotVO snapshotVO = createSnapshotInDb();
-        DataStore store = null;
-        try {
-            store = createDataStore();
-            FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
-            dataStoreDriver.makeTakeSnapshotSucceed(false);
-            SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
-            SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
-            Assert.assertFalse(result.isSuccess());
-            SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
-            Assert.assertTrue(storeRef == null);
-        } finally {
-            snapshotDao.expunge(snapshotVO.getId());
-            if (store != null) {
-                primaryDataStoreDao.remove(store.getId());
-            }
-        }
-    }
-
-    //@Test
-    public void testTakeSnapshotFromVolume() throws URISyntaxException {
-        DataStore store = createDataStore();
-        FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
-        dataStoreDriver.makeTakeSnapshotSucceed(false);
-        VolumeInfo volumeInfo = createVolume(1L, store);
-        Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
-        SnapshotInfo result = volumeService.takeSnapshot(volumeInfo);
-        Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
-        Assert.assertTrue(result == null);
-    }
-
-    protected SnapshotPolicyVO createSnapshotPolicy(Long volId) {
-        SnapshotPolicyVO policyVO = new SnapshotPolicyVO(volId, "jfkd", "fdfd", DateUtil.IntervalType.DAILY, 8);
-        policyVO = snapshotPolicyDao.persist(policyVO);
-        return policyVO;
-    }
-
-    @Test
-    public void testConcurrentSnapshot() throws URISyntaxException, InterruptedException, ExecutionException {
-        DataStore store = createDataStore();
-        final FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
-        dataStoreDriver.makeTakeSnapshotSucceed(true);
-        final VolumeInfo volumeInfo = createVolume(1L, store);
-        Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
-        vol = volumeInfo;
-        // final SnapshotPolicyVO policyVO = createSnapshotPolicy(vol.getId());
-
-        ExecutorService pool = Executors.newFixedThreadPool(2);
-        boolean result = false;
-        List<Future<Boolean>> future = new ArrayList<Future<Boolean>>();
-        for (int i = 0; i < 12; i++) {
-            final int cnt = i;
-            Future<Boolean> task = pool.submit(new Callable<Boolean>() {
-                @Override
-                public Boolean call() throws Exception {
-                    boolean r = true;
-                    try {
-                        SnapshotVO snapshotVO = createSnapshotInDb(vol.getId());
-                        VolumeObject volumeObject = (VolumeObject)vol;
-                        Account account = mock(Account.class);
-                        when(account.getId()).thenReturn(1L);
-                        CreateSnapshotPayload createSnapshotPayload = mock(CreateSnapshotPayload.class);
-                        when(createSnapshotPayload.getAccount()).thenReturn(account);
-                        when(createSnapshotPayload.getSnapshotId()).thenReturn(snapshotVO.getId());
-                        when(createSnapshotPayload.getSnapshotPolicyId()).thenReturn(0L);
-                        volumeObject.addPayload(createSnapshotPayload);
-                        if (cnt > 8) {
-                            mockStorageMotionStrategy.makeBackupSnapshotSucceed(false);
-                        }
-                        SnapshotInfo newSnapshot = volumeService.takeSnapshot(vol);
-                        if (newSnapshot == null) {
-                            r = false;
-                        }
-                    } catch (Exception e) {
-                        r = false;
-                    }
-                    return r;
-                }
-            });
-            Assert.assertTrue(task.get());
-        }
-
-    }
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
deleted file mode 100644
index 0fc6f59..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeServiceTest.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-
-@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
-public class VolumeServiceTest extends CloudStackTestNGBase {
-    // @Inject
-    // ImageDataStoreProviderManager imageProviderMgr;
-    @Inject
-    TemplateService imageService;
-    @Inject
-    VolumeService volumeService;
-    @Inject
-    VMTemplateDao imageDataDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    HostPodDao podDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    DataCenterDao dcDao;
-    @Inject
-    PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    EndPointSelector selector;
-    @Inject
-    TemplateDataFactory imageDataFactory;
-    @Inject
-    VolumeDataFactory volumeFactory;
-    @Inject
-    ImageStoreDao imageStoreDao;
-    ImageStoreVO imageStore;
-    Long dcId;
-    Long clusterId;
-    Long podId;
-    HostVO host;
-    String primaryName = "my primary data store";
-    DataStore primaryStore;
-
-    @Test(priority = -1)
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-
-        host = hostDao.findByGuid(this.getHostGuid());
-        if (host != null) {
-            dcId = host.getDataCenterId();
-            clusterId = host.getClusterId();
-            podId = host.getPodId();
-            return;
-        }
-        // create data center
-        DataCenterVO dc =
-            new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                true, null, null);
-        dc = dcDao.persist(dc);
-        dcId = dc.getId();
-        // create pod
-
-        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
-        pod = podDao.persist(pod);
-        podId = pod.getId();
-        // create xenserver cluster
-        ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-        cluster.setHypervisorType(HypervisorType.XenServer.toString());
-        cluster.setClusterType(ClusterType.CloudManaged);
-        cluster.setManagedState(ManagedState.Managed);
-        cluster = clusterDao.persist(cluster);
-        clusterId = cluster.getId();
-        // create xenserver host
-
-        host = new HostVO(this.getHostGuid());
-        host.setName("devcloud xenserver host");
-        host.setType(Host.Type.Routing);
-        host.setPrivateIpAddress(this.getHostIp());
-        host.setDataCenterId(dc.getId());
-        host.setVersion("6.0.1");
-        host.setAvailable(true);
-        host.setSetup(true);
-        host.setPodId(podId);
-        host.setLastPinged(0);
-        host.setResourceState(ResourceState.Enabled);
-        host.setHypervisorType(HypervisorType.XenServer);
-        host.setClusterId(cluster.getId());
-
-        host = hostDao.persist(host);
-
-        imageStore = new ImageStoreVO();
-        imageStore.setName("test");
-        imageStore.setDataCenterId(dcId);
-        imageStore.setProviderName("CloudStack ImageStore Provider");
-        imageStore.setRole(DataStoreRole.Image);
-        imageStore.setUrl(this.getSecondaryStorage());
-        imageStore.setUuid(UUID.randomUUID().toString());
-        imageStore = imageStoreDao.persist(imageStore);
-
-    }
-
-    @Override
-    protected void injectMockito() {
-        if (host == null) {
-            return;
-        }
-        List<HostVO> results = new ArrayList<HostVO>();
-        results.add(host);
-        Mockito.when(hostDao.listAll()).thenReturn(results);
-        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(host);
-        Mockito.when(hostDao.findHypervisorHostInCluster(Matchers.anyLong())).thenReturn(results);
-        List<EndPoint> eps = new ArrayList<EndPoint>();
-        eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
-        Mockito.when(selector.selectAll(Matchers.any(DataStore.class))).thenReturn(eps);
-        Mockito.when(selector.select(Matchers.any(DataObject.class))).thenReturn(eps.get(0));
-        Mockito.when(selector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(eps.get(0));
-    }
-
-    private VMTemplateVO createImageData() {
-        VMTemplateVO image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-        image.setUrl(this.getTemplateUrl());
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-
-        // image.setImageDataStoreId(storeId);
-        image = imageDataDao.persist(image);
-
-        return image;
-    }
-
-    private TemplateInfo createTemplate() {
-        try {
-            DataStore store = createImageStore();
-            VMTemplateVO image = createImageData();
-            TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store);
-            // AsyncCallFuture<TemplateApiResult> future =
-            // imageService.createTemplateAsync(template, store);
-            // future.get();
-            template = imageDataFactory.getTemplate(image.getId(), store);
-            /*
-             * imageProviderMgr.configure("image Provider", new HashMap<String,
-             * Object>()); VMTemplateVO image = createImageData();
-             * ImageDataStoreProvider defaultProvider =
-             * imageProviderMgr.getProvider("DefaultProvider");
-             * ImageDataStoreLifeCycle lifeCycle =
-             * defaultProvider.getLifeCycle(); ImageDataStore store =
-             * lifeCycle.registerDataStore("defaultHttpStore", new
-             * HashMap<String, String>());
-             * imageService.registerTemplate(image.getId(),
-             * store.getImageDataStoreId()); TemplateEntity te =
-             * imageService.getTemplateEntity(image.getId()); return te;
-             */
-            return template;
-        } catch (Exception e) {
-            Assert.fail("failed", e);
-            return null;
-        }
-    }
-
-    // @Test
-    public void createTemplateTest() {
-        createTemplate();
-    }
-
-    @Test
-    public void testCreatePrimaryStorage() {
-        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
-        Map<String, Object> params = new HashMap<String, Object>();
-        URI uri = null;
-        try {
-            uri = new URI(this.getPrimaryStorageUrl());
-        } catch (URISyntaxException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        params.put("url", this.getPrimaryStorageUrl());
-        params.put("server", uri.getHost());
-        params.put("path", uri.getPath());
-        params.put("protocol", StoragePoolType.NetworkFilesystem);
-        params.put("dcId", dcId.toString());
-        params.put("clusterId", clusterId.toString());
-        params.put("name", this.primaryName);
-        params.put("port", "1");
-        params.put("roles", DataStoreRole.Primary.toString());
-        params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
-        params.put("providerName", String.valueOf(provider.getName()));
-
-        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        this.primaryStore = lifeCycle.initialize(params);
-        ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
-        lifeCycle.attachCluster(this.primaryStore, scope);
-    }
-
-    private DataStore createImageStore() {
-        DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider");
-        Map<String, Object> params = new HashMap<String, Object>();
-        String name = UUID.randomUUID().toString();
-        params.put("name", name);
-        params.put("uuid", name);
-        params.put("protocol", "http");
-        params.put("scope", ScopeType.GLOBAL.toString());
-        params.put("providerName", name);
-        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = lifeCycle.initialize(params);
-        return store;
-    }
-
-    // @Test
-    public void testcreateImageStore() {
-        createImageStore();
-    }
-
-    public DataStore createPrimaryDataStore() {
-        try {
-            DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider");
-            Map<String, Object> params = new HashMap<String, Object>();
-            URI uri = new URI(this.getPrimaryStorageUrl());
-            params.put("url", this.getPrimaryStorageUrl());
-            params.put("server", uri.getHost());
-            params.put("path", uri.getPath());
-            params.put("protocol", Storage.StoragePoolType.NetworkFilesystem);
-            params.put("dcId", dcId.toString());
-            params.put("clusterId", clusterId.toString());
-            params.put("name", this.primaryName);
-            params.put("port", "1");
-            params.put("roles", DataStoreRole.Primary.toString());
-            params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString());
-            params.put("providerName", String.valueOf(provider.getName()));
-
-            DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-            DataStore store = lifeCycle.initialize(params);
-            ClusterScope scope = new ClusterScope(clusterId, podId, dcId);
-            lifeCycle.attachCluster(store, scope);
-
-            /*
-             * PrimaryDataStoreProvider provider =
-             * primaryDataStoreProviderMgr.getDataStoreProvider
-             * ("sample primary data store provider");
-             * primaryDataStoreProviderMgr.configure("primary data store mgr",
-             * new HashMap<String, Object>());
-             *
-             * List<PrimaryDataStoreVO> ds =
-             * primaryStoreDao.findPoolByName(this.primaryName); if (ds.size()
-             * >= 1) { PrimaryDataStoreVO store = ds.get(0); if
-             * (store.getRemoved() == null) { return
-             * provider.getDataStore(store.getId()); } }
-             *
-             *
-             * Map<String, String> params = new HashMap<String, String>();
-             * params.put("url", this.getPrimaryStorageUrl());
-             * params.put("dcId", dcId.toString()); params.put("clusterId",
-             * clusterId.toString()); params.put("name", this.primaryName);
-             * PrimaryDataStoreInfo primaryDataStoreInfo =
-             * provider.registerDataStore(params); PrimaryDataStoreLifeCycle lc
-             * = primaryDataStoreInfo.getLifeCycle(); ClusterScope scope = new
-             * ClusterScope(clusterId, podId, dcId); lc.attachCluster(scope);
-             * return primaryDataStoreInfo;
-             */
-            return store;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private VolumeVO createVolume(Long templateId, long dataStoreId) {
-        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
-        volume.setPoolId(dataStoreId);
-        volume = volumeDao.persist(volume);
-        return volume;
-    }
-
-    @Test(priority = 2)
-    public void createVolumeFromTemplate() {
-        DataStore primaryStore = this.primaryStore;
-        TemplateInfo te = createTemplate();
-        VolumeVO volume = createVolume(te.getId(), primaryStore.getId());
-        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
-        // ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te);
-        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeFromTemplateAsync(vol, primaryStore.getId(), te);
-        try {
-            future.get();
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    // @Test(priority=3)
-    public void createDataDisk() {
-        DataStore primaryStore = this.primaryStore;
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
-        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeAsync(vol, primaryStore);
-        try {
-            future.get();
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    // @Test(priority=3)
-    public void createAndDeleteDataDisk() {
-        DataStore primaryStore = this.primaryStore;
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore);
-        AsyncCallFuture<VolumeApiResult> future = volumeService.createVolumeAsync(vol, primaryStore);
-        try {
-            future.get();
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
-        // delete the volume
-        vol = volumeFactory.getVolume(volume.getId(), primaryStore);
-        future = volumeService.expungeVolumeAsync(vol);
-        try {
-            future.get();
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    // @Test(priority=3)
-    public void tearDown() {
-        List<StoragePoolVO> ds = primaryStoreDao.findPoolByName(this.primaryName);
-        for (int i = 0; i < ds.size(); i++) {
-            StoragePoolVO store = ds.get(i);
-            store.setUuid(null);
-            primaryStoreDao.remove(ds.get(i).getId());
-            primaryStoreDao.expunge(ds.get(i).getId());
-        }
-    }
-
-    // @Test
-    // @Test
-    public void test1() {
-        /*
-         * System.out.println(VolumeTypeHelper.getType("Root"));
-         * System.out.println(VolumeDiskTypeHelper.getDiskType("vmdk"));
-         * System.out.println(ImageFormatHelper.getFormat("ova"));
-         * AssertJUnit.assertFalse(new VMDK().equals(new VHD())); VMDK vmdk =
-         * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(vmdk)); VMDK newvmdk =
-         * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(newvmdk));
-         *
-         * ImageFormat ova = new OVA(); ImageFormat iso = new ISO();
-         * AssertJUnit.assertTrue(ova.equals(new OVA()));
-         * AssertJUnit.assertFalse(ova.equals(iso));
-         * AssertJUnit.assertTrue(ImageFormatHelper.getFormat("test").equals(new
-         * Unknown()));
-         *
-         * VolumeDiskType qcow2 = new QCOW2(); ImageFormat qcow2format = new
-         * org.apache.cloudstack.storage.image.format.QCOW2();
-         * AssertJUnit.assertFalse(qcow2.equals(qcow2format));
-         */
-    }
-
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
deleted file mode 100644
index c274d76..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import junit.framework.Assert;
-
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.testng.AssertJUnit;
-import org.testng.annotations.Test;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Command;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-
-@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
-public class VolumeTest extends CloudStackTestNGBase {
-    @Inject
-    ImageStoreDao imageStoreDao;
-    ImageStoreVO imageStore;
-    Long dcId;
-    Long clusterId;
-    Long podId;
-    HostVO host;
-    String primaryName = "my primary data store";
-    DataStore primaryStore;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    TemplateService imageService;
-    @Inject
-    VolumeService volumeService;
-    @Inject
-    VMTemplateDao imageDataDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    HostPodDao podDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    DataCenterDao dcDao;
-    @Inject
-    PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    TemplateDataStoreDao templateStoreDao;
-    @Inject
-    TemplateDataFactory templateFactory;
-    @Inject
-    PrimaryDataStoreDao primaryDataStoreDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    ResourceManager resourceMgr;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    EndPointSelector epSelector;
-    @Inject
-    HypervisorGuruManager hyGuruMgr;
-    long primaryStoreId;
-    VMTemplateVO image;
-    String imageStoreName = "testImageStore";
-
-    @Test(priority = -1)
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-
-        host = hostDao.findByGuid(this.getHostGuid());
-        if (host != null) {
-            dcId = host.getDataCenterId();
-            clusterId = host.getClusterId();
-            podId = host.getPodId();
-            imageStore = this.imageStoreDao.findByName(imageStoreName);
-        } else {
-            // create data center
-            DataCenterVO dc =
-                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                    true, null, null);
-            dc = dcDao.persist(dc);
-            dcId = dc.getId();
-            // create pod
-
-            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
-            pod = podDao.persist(pod);
-            podId = pod.getId();
-            // create xenserver cluster
-            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-            cluster.setHypervisorType(this.getHypervisor().toString());
-            cluster.setClusterType(ClusterType.CloudManaged);
-            cluster.setManagedState(ManagedState.Managed);
-            cluster = clusterDao.persist(cluster);
-            clusterId = cluster.getId();
-            // create xenserver host
-
-            host = new HostVO(this.getHostGuid());
-            host.setName("devcloud xenserver host");
-            host.setType(Host.Type.Routing);
-            host.setPrivateIpAddress(this.getHostIp());
-            host.setDataCenterId(dc.getId());
-            host.setVersion("6.0.1");
-            host.setAvailable(true);
-            host.setSetup(true);
-            host.setPodId(podId);
-            host.setLastPinged(0);
-            host.setResourceState(ResourceState.Enabled);
-            host.setHypervisorType(this.getHypervisor());
-            host.setClusterId(cluster.getId());
-
-            host = hostDao.persist(host);
-
-            imageStore = new ImageStoreVO();
-            imageStore.setName(imageStoreName);
-            imageStore.setDataCenterId(dcId);
-            imageStore.setProviderName(DataStoreProvider.NFS_IMAGE);
-            imageStore.setRole(DataStoreRole.Image);
-            imageStore.setUrl(this.getSecondaryStorage());
-            imageStore.setUuid(UUID.randomUUID().toString());
-            imageStore.setProtocol("nfs");
-            imageStore = imageStoreDao.persist(imageStore);
-        }
-
-        image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-        image.setUrl(this.getTemplateUrl());
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-
-        image = imageDataDao.persist(image);
-
-        /*
-         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
-         *
-         * templateStore.setDataStoreId(imageStore.getId());
-         * templateStore.setDownloadPercent(100);
-         * templateStore.setDownloadState(Status.DOWNLOADED);
-         * templateStore.setDownloadUrl(imageStore.getUrl());
-         * templateStore.setInstallPath(this.getImageInstallPath());
-         * templateStore.setTemplateId(image.getId());
-         * templateStoreDao.persist(templateStore);
-         */
-
-        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
-        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
-        DataObject templateOnStore = store.create(template);
-        TemplateObjectTO to = new TemplateObjectTO();
-        to.setPath(this.getImageInstallPath());
-        to.setFormat(ImageFormat.VHD);
-        to.setSize(100L);
-        CopyCmdAnswer answer = new CopyCmdAnswer(to);
-        templateOnStore.processEvent(Event.CreateOnlyRequested);
-        templateOnStore.processEvent(Event.OperationSuccessed, answer);
-
-    }
-
-    @Override
-    protected void injectMockito() {
-        List<HostVO> hosts = new ArrayList<HostVO>();
-        hosts.add(this.host);
-        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
-
-        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
-        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
-        Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(this.host.getId());
-    }
-
-    public DataStore createPrimaryDataStore() {
-        try {
-            String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
-            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
-            if (pools.size() > 0) {
-                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
-            }
-
-            /*
-             * DataStoreProvider provider =
-             * dataStoreProviderMgr.getDataStoreProvider
-             * ("cloudstack primary data store provider"); Map<String, Object>
-             * params = new HashMap<String, Object>(); URI uri = new
-             * URI(this.getPrimaryStorageUrl()); params.put("url",
-             * this.getPrimaryStorageUrl()); params.put("server",
-             * uri.getHost()); params.put("path", uri.getPath());
-             * params.put("protocol",
-             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
-             * dcId); params.put("clusterId", clusterId); params.put("name",
-             * this.primaryName); params.put("port", 1); params.put("podId",
-             * this.podId); params.put("roles",
-             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
-             * params.put("providerName", String.valueOf(provider.getName()));
-             *
-             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-             * DataStore store = lifeCycle.initialize(params); ClusterScope
-             * scope = new ClusterScope(clusterId, podId, dcId);
-             * lifeCycle.attachCluster(store, scope);
-             */
-
-            StoragePoolVO pool = new StoragePoolVO();
-            pool.setClusterId(clusterId);
-            pool.setDataCenterId(dcId);
-            URI uri = new URI(this.getPrimaryStorageUrl());
-            pool.setHostAddress(uri.getHost());
-            pool.setPath(uri.getPath());
-            pool.setPort(0);
-            pool.setName(this.primaryName);
-            pool.setUuid(this.getPrimaryStorageUuid());
-            pool.setStatus(StoragePoolStatus.Up);
-            pool.setPoolType(StoragePoolType.NetworkFilesystem);
-            pool.setPodId(podId);
-            pool.setScope(ScopeType.CLUSTER);
-            pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
-            pool = this.primaryStoreDao.persist(pool);
-            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-            return store;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private VolumeVO createVolume(Long templateId, long dataStoreId) {
-        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
-        ;
-        volume.setPoolId(dataStoreId);
-        volume = volumeDao.persist(volume);
-        return volume;
-    }
-
-    @Test
-    public void testCopyBaseImage() {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future =
-            this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
-        try {
-            VolumeApiResult result = future.get();
-
-            AssertJUnit.assertTrue(result.isSuccess());
-
-            VolumeInfo newVol = result.getVolume();
-            boolean res = this.volumeService.destroyVolume(newVol.getId());
-            Assert.assertTrue(res);
-            VolumeInfo vol = this.volFactory.getVolume(volume.getId());
-            future = this.volumeService.expungeVolumeAsync(vol);
-            result = future.get();
-            Assert.assertTrue(result.isSuccess());
-        } catch (InterruptedException e) {
-            Assert.fail(e.toString());
-        } catch (ExecutionException e) {
-            Assert.fail(e.toString());
-        } catch (ConcurrentOperationException e) {
-            Assert.fail(e.toString());
-        }
-    }
-
-    @Test
-    public void testCreateDataDisk() throws InterruptedException, ExecutionException {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
-        VolumeApiResult result = future.get();
-        Assert.assertTrue(result.isSuccess());
-    }
-
-    @Test
-    public void testDeleteDisk() throws InterruptedException, ExecutionException, ConcurrentOperationException {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
-
-        VolumeApiResult result = future.get();
-        Assert.assertTrue(result.isSuccess());
-        VolumeInfo vol = result.getVolume();
-
-        boolean res = this.volumeService.destroyVolume(volInfo.getId());
-        Assert.assertTrue(res);
-        volInfo = this.volFactory.getVolume(vol.getId());
-        future = this.volumeService.expungeVolumeAsync(volInfo);
-        result = future.get();
-        Assert.assertTrue(result.isSuccess());
-    }
-
-    private VMTemplateVO createTemplateInDb() {
-        image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-        image = imageDataDao.persist(image);
-        return image;
-    }
-
-    @Test
-    public void testCreateTemplateFromVolume() throws InterruptedException, ExecutionException {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
-
-        VolumeApiResult result = future.get();
-
-        AssertJUnit.assertTrue(result.isSuccess());
-        volInfo = result.getVolume();
-        VMTemplateVO templateVO = createTemplateInDb();
-        TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
-        DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
-
-        AsyncCallFuture<TemplateApiResult> templateResult = this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
-        TemplateApiResult templateApiResult = templateResult.get();
-        Assert.assertTrue(templateApiResult.isSuccess());
-    }
-}
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
deleted file mode 100644
index 1f3aff0..0000000
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.test;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.test.context.ContextConfiguration;
-import org.testng.AssertJUnit;
-import org.testng.annotations.Test;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-
-@ContextConfiguration(locations = {"classpath:/storageContext.xml"})
-public class VolumeTestVmware extends CloudStackTestNGBase {
-    @Inject
-    ImageStoreDao imageStoreDao;
-    ImageStoreVO imageStore;
-    Long dcId;
-    Long clusterId;
-    Long podId;
-    HostVO host;
-    String primaryName = "my primary data store";
-    DataStore primaryStore;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    TemplateService imageService;
-    @Inject
-    VolumeService volumeService;
-    @Inject
-    VMTemplateDao imageDataDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    HostPodDao podDao;
-    @Inject
-    ClusterDao clusterDao;
-    @Inject
-    ClusterDetailsDao clusterDetailsDao;
-    @Inject
-    DataCenterDao dcDao;
-    @Inject
-    PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    TemplateDataStoreDao templateStoreDao;
-    @Inject
-    TemplateDataFactory templateFactory;
-    @Inject
-    PrimaryDataStoreDao primaryDataStoreDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    ResourceManager resourceMgr;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    EndPointSelector epSelector;
-    long primaryStoreId;
-    VMTemplateVO image;
-    String imageStoreName = "testImageStore";
-
-    @Test(priority = -1)
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-
-        host = hostDao.findByGuid(this.getHostGuid());
-        if (host != null) {
-            dcId = host.getDataCenterId();
-            clusterId = host.getClusterId();
-            podId = host.getPodId();
-            imageStore = this.imageStoreDao.findByName(imageStoreName);
-        } else {
-            // create data center
-            DataCenterVO dc =
-                new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                    true, null, null);
-            dc = dcDao.persist(dc);
-            dcId = dc.getId();
-            // create pod
-
-            HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test");
-            pod = podDao.persist(pod);
-            podId = pod.getId();
-            // create xen cluster
-            ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
-            cluster.setHypervisorType(HypervisorType.VMware.toString());
-            cluster.setClusterType(ClusterType.ExternalManaged);
-            cluster.setManagedState(ManagedState.Managed);
-            cluster = clusterDao.persist(cluster);
-            clusterId = cluster.getId();
-
-            // setup vcenter
-            ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null);
-            this.clusterDetailsDao.persist(clusterDetailVO);
-            clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "username", null);
-            this.clusterDetailsDao.persist(clusterDetailVO);
-            clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "password", null);
-            this.clusterDetailsDao.persist(clusterDetailVO);
-            // create xen host
-
-            host = new HostVO(this.getHostGuid());
-            host.setName("devcloud vmware host");
-            host.setType(Host.Type.Routing);
-            host.setPrivateIpAddress(this.getHostIp());
-            host.setDataCenterId(dc.getId());
-            host.setVersion("6.0.1");
-            host.setAvailable(true);
-            host.setSetup(true);
-            host.setPodId(podId);
-            host.setLastPinged(0);
-            host.setResourceState(ResourceState.Enabled);
-            host.setHypervisorType(HypervisorType.VMware);
-            host.setClusterId(cluster.getId());
-
-            host = hostDao.persist(host);
-
-            imageStore = new ImageStoreVO();
-            imageStore.setName(imageStoreName);
-            imageStore.setDataCenterId(dcId);
-            imageStore.setProviderName("CloudStack ImageStore Provider");
-            imageStore.setRole(DataStoreRole.Image);
-            imageStore.setUrl(this.getSecondaryStorage());
-            imageStore.setUuid(UUID.randomUUID().toString());
-            imageStore.setProtocol("nfs");
-            imageStore = imageStoreDao.persist(imageStore);
-        }
-
-        image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-        image.setUrl(this.getTemplateUrl());
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-
-        image = imageDataDao.persist(image);
-
-        /*
-         * TemplateDataStoreVO templateStore = new TemplateDataStoreVO();
-         *
-         * templateStore.setDataStoreId(imageStore.getId());
-         * templateStore.setDownloadPercent(100);
-         * templateStore.setDownloadState(Status.DOWNLOADED);
-         * templateStore.setDownloadUrl(imageStore.getUrl());
-         * templateStore.setInstallPath(this.getImageInstallPath());
-         * templateStore.setTemplateId(image.getId());
-         * templateStoreDao.persist(templateStore);
-         */
-
-        DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image);
-        TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image);
-        DataObject templateOnStore = store.create(template);
-        TemplateObjectTO to = new TemplateObjectTO();
-        to.setPath(this.getImageInstallPath());
-        CopyCmdAnswer answer = new CopyCmdAnswer(to);
-        templateOnStore.processEvent(Event.CreateOnlyRequested);
-        templateOnStore.processEvent(Event.OperationSuccessed, answer);
-
-    }
-
-    @Override
-    protected void injectMockito() {
-        List<HostVO> hosts = new ArrayList<HostVO>();
-        hosts.add(this.host);
-        Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type)Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), Matchers.anyLong())).thenReturn(hosts);
-
-        RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep);
-        Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep);
-        Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep);
-    }
-
-    public DataStore createPrimaryDataStore() {
-        try {
-            String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString();
-            List<StoragePoolVO> pools = primaryDataStoreDao.findPoolByName(this.primaryName);
-            if (pools.size() > 0) {
-                return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId());
-            }
-
-            /*
-             * DataStoreProvider provider =
-             * dataStoreProviderMgr.getDataStoreProvider
-             * ("cloudstack primary data store provider"); Map<String, Object>
-             * params = new HashMap<String, Object>(); URI uri = new
-             * URI(this.getPrimaryStorageUrl()); params.put("url",
-             * this.getPrimaryStorageUrl()); params.put("server",
-             * uri.getHost()); params.put("path", uri.getPath());
-             * params.put("protocol",
-             * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId",
-             * dcId); params.put("clusterId", clusterId); params.put("name",
-             * this.primaryName); params.put("port", 1); params.put("podId",
-             * this.podId); params.put("roles",
-             * DataStoreRole.Primary.toString()); params.put("uuid", uuid);
-             * params.put("providerName", String.valueOf(provider.getName()));
-             *
-             * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-             * DataStore store = lifeCycle.initialize(params); ClusterScope
-             * scope = new ClusterScope(clusterId, podId, dcId);
-             * lifeCycle.attachCluster(store, scope);
-             */
-
-            StoragePoolVO pool = new StoragePoolVO();
-            pool.setClusterId(clusterId);
-            pool.setDataCenterId(dcId);
-            URI uri = new URI(this.getPrimaryStorageUrl());
-            pool.setHostAddress(uri.getHost());
-            pool.setPath(uri.getPath());
-            pool.setPort(0);
-            pool.setName(this.primaryName);
-            pool.setUuid(this.getPrimaryStorageUuid());
-            pool.setStatus(StoragePoolStatus.Up);
-            pool.setPoolType(StoragePoolType.VMFS);
-            pool.setPodId(podId);
-            pool.setScope(ScopeType.CLUSTER);
-            pool.setStorageProviderName("cloudstack primary data store provider");
-            pool = this.primaryStoreDao.persist(pool);
-            DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-            return store;
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private VolumeVO createVolume(Long templateId, long dataStoreId) {
-        VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000, 0L, 0L, "");
-        ;
-        volume.setPoolId(dataStoreId);
-        volume = volumeDao.persist(volume);
-        return volume;
-    }
-
-    // @Test
-    public void testCopyBaseImage() {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(image.getId(), primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future =
-            this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image));
-        try {
-            VolumeApiResult result = future.get();
-
-            AssertJUnit.assertTrue(result.isSuccess());
-
-            VolumeInfo newVol = result.getVolume();
-            this.volumeService.destroyVolume(newVol.getId());
-            VolumeInfo vol = this.volFactory.getVolume(volume.getId());
-            this.volumeService.expungeVolumeAsync(vol);
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ConcurrentOperationException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    @Test
-    public void testCreateDataDisk() {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        this.volumeService.createVolumeAsync(volInfo, primaryStore);
-    }
-
-    @Test
-    public void testDeleteDisk() {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
-        try {
-            VolumeApiResult result = future.get();
-            VolumeInfo vol = result.getVolume();
-
-            this.volumeService.destroyVolume(volInfo.getId());
-            volInfo = this.volFactory.getVolume(vol.getId());
-            this.volumeService.expungeVolumeAsync(volInfo);
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ConcurrentOperationException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
-    }
-
-    private VMTemplateVO createTemplateInDb() {
-        image = new VMTemplateVO();
-        image.setTemplateType(TemplateType.USER);
-
-        image.setUniqueName(UUID.randomUUID().toString());
-        image.setName(UUID.randomUUID().toString());
-        image.setPublicTemplate(true);
-        image.setFeatured(true);
-        image.setRequiresHvm(true);
-        image.setBits(64);
-        image.setFormat(Storage.ImageFormat.VHD);
-        image.setEnablePassword(true);
-        image.setEnableSshKey(true);
-        image.setGuestOSId(1);
-        image.setBootable(true);
-        image.setPrepopulate(true);
-        image.setCrossZones(true);
-        image.setExtractable(true);
-        image = imageDataDao.persist(image);
-        return image;
-    }
-
-    @Test
-    public void testCreateTemplateFromVolume() {
-        DataStore primaryStore = createPrimaryDataStore();
-        primaryStoreId = primaryStore.getId();
-        primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
-        VolumeVO volume = createVolume(null, primaryStore.getId());
-        VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
-        try {
-            VolumeApiResult result = future.get();
-
-            AssertJUnit.assertTrue(result.isSuccess());
-            volInfo = result.getVolume();
-            VMTemplateVO templateVO = createTemplateInDb();
-            TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image);
-            DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
-
-            this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore);
-        } catch (InterruptedException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (ExecutionException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-
-    }
-}
diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml
index 1df2146..9f19a51 100644
--- a/engine/storage/pom.xml
+++ b/engine/storage/pom.xml
@@ -1,61 +1,69 @@
-<!-- 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. -->
+<!--
+  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-engine-storage</artifactId>
-  <name>Apache CloudStack Engine Storage Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.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-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <!-- 
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    -->
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-secondary-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-engine-storage</artifactId>
+    <name>Apache CloudStack Engine Storage Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</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-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+<!--
+         <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+ -->
+         <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-secondary-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index 9e17abc..4556454 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -1,48 +1,56 @@
-<!-- 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. -->
+<!--
+  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-engine-storage-snapshot</artifactId>
-  <name>Apache CloudStack Engine Storage Snapshot Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-      <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-api</artifactId>
-          <version>${project.version}</version>
-          <type>test-jar</type>
-          <scope>test</scope>
-      </dependency>
-      <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-engine-storage-volume</artifactId>
-          <version>${project.version}</version>
-      </dependency>
-  </dependencies>
+    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-engine-storage-snapshot</artifactId>
+    <name>Apache CloudStack Engine Storage Snapshot Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
     <build>
         <plugins>
             <plugin>
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotBackupException.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotBackupException.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotBackupException.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotBackupException.java
diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
new file mode 100644
index 0000000..11d61df
--- /dev/null
+++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.snapshot;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.commons.collections.CollectionUtils;
+
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
+
+    @Inject
+    private SnapshotDao snapshotDao;
+    @Inject
+    private SnapshotDataStoreDao snapshotStoreDao;
+    @Inject
+    private DataStoreManager storeMgr;
+
+    @Override
+    public SnapshotInfo getSnapshot(long snapshotId, DataStore store) {
+        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
+        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
+        return so;
+    }
+
+    @Override
+    public SnapshotInfo getSnapshot(DataObject obj, DataStore store) {
+        SnapshotVO snapshot = snapshotDao.findById(obj.getId());
+        if (snapshot == null) {
+            throw new CloudRuntimeException("Can't find snapshot: " + obj.getId());
+        }
+        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
+        return so;
+    }
+
+    @Override
+    public List<SnapshotInfo> getSnapshots(long volumeId, DataStoreRole role) {
+        List<SnapshotDataStoreVO> allSnapshotsFromVolumeAndDataStore = snapshotStoreDao.listAllByVolumeAndDataStore(volumeId, role);
+        if (CollectionUtils.isEmpty(allSnapshotsFromVolumeAndDataStore)) {
+            return new ArrayList<>();
+        }
+        List<SnapshotInfo> infos = new ArrayList<>();
+        for (SnapshotDataStoreVO snapshotDataStoreVO : allSnapshotsFromVolumeAndDataStore) {
+            DataStore store = storeMgr.getDataStore(snapshotDataStoreVO.getDataStoreId(), role);
+            SnapshotVO snapshot = snapshotDao.findById(snapshotDataStoreVO.getSnapshotId());
+            SnapshotObject info = SnapshotObject.getSnapshotObject(snapshot, store);
+
+            infos.add(info);
+        }
+        return infos;
+    }
+
+
+    @Override
+    public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role) {
+        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
+        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId, role);
+        if (snapshotStore == null) {
+            snapshotStore = snapshotStoreDao.findByVolume(snapshot.getVolumeId(), role);
+            if (snapshotStore == null) {
+                return null;
+            }
+        }
+        DataStore store = storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
+        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
+        return so;
+    }
+
+    @Override
+    public SnapshotInfo getReadySnapshotOnCache(long snapshotId) {
+        SnapshotDataStoreVO snapStore = snapshotStoreDao.findReadyOnCache(snapshotId);
+        if (snapStore != null) {
+            DataStore store = storeMgr.getDataStore(snapStore.getDataStoreId(), DataStoreRole.ImageCache);
+            return getSnapshot(snapshotId, store);
+        } else {
+            return null;
+        }
+
+    }
+
+    @Override
+    public List<SnapshotInfo> listSnapshotOnCache(long snapshotId) {
+        List<SnapshotDataStoreVO> cacheSnapshots = snapshotStoreDao.listOnCache(snapshotId);
+        List<SnapshotInfo> snapObjs = new ArrayList<SnapshotInfo>();
+        for (SnapshotDataStoreVO cacheSnap : cacheSnapshots) {
+            long storeId = cacheSnap.getDataStoreId();
+            DataStore store = storeMgr.getDataStore(storeId, DataStoreRole.ImageCache);
+            SnapshotInfo tmplObj = getSnapshot(snapshotId, store);
+            snapObjs.add(tmplObj);
+        }
+        return snapObjs;
+    }
+
+}
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotObject.java
diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
new file mode 100644
index 0000000..9c51370
--- /dev/null
+++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -0,0 +1,603 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.storage.snapshot;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+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.SnapshotResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcContext;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.log4j.Logger;
+
+import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotDetailsDao;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+
+public class SnapshotServiceImpl implements SnapshotService {
+    private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class);
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    @Inject
+    protected SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    SnapshotDataFactory _snapshotFactory;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    DataMotionService motionSrv;
+    @Inject
+    StorageCacheManager _cacheMgr;
+    @Inject
+    private SnapshotDetailsDao _snapshotDetailsDao;
+
+    static private class CreateSnapshotContext<T> extends AsyncRpcContext<T> {
+        final SnapshotInfo snapshot;
+        final AsyncCallFuture<SnapshotResult> future;
+
+        public CreateSnapshotContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
+            super(callback);
+            this.snapshot = snapshot;
+            this.future = future;
+        }
+    }
+
+    static private class DeleteSnapshotContext<T> extends AsyncRpcContext<T> {
+        final SnapshotInfo snapshot;
+        final AsyncCallFuture<SnapshotResult> future;
+
+        public DeleteSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
+            super(callback);
+            this.snapshot = snapshot;
+            this.future = future;
+        }
+
+    }
+
+    static private class CopySnapshotContext<T> extends AsyncRpcContext<T> {
+        final SnapshotInfo srcSnapshot;
+        final SnapshotInfo destSnapshot;
+        final AsyncCallFuture<SnapshotResult> future;
+
+        public CopySnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo srcSnapshot, SnapshotInfo destSnapshot, AsyncCallFuture<SnapshotResult> future) {
+            super(callback);
+            this.srcSnapshot = srcSnapshot;
+            this.destSnapshot = destSnapshot;
+            this.future = future;
+        }
+
+    }
+
+    static private class RevertSnapshotContext<T> extends AsyncRpcContext<T> {
+        final SnapshotInfo snapshot;
+        final AsyncCallFuture<SnapshotResult> future;
+
+        public RevertSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
+            super(callback);
+            this.snapshot = snapshot;
+            this.future = future;
+        }
+
+    }
+
+    protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> callback, CreateSnapshotContext<CreateCmdResult> context) {
+        CreateCmdResult result = callback.getResult();
+        SnapshotObject snapshot = (SnapshotObject)context.snapshot;
+        AsyncCallFuture<SnapshotResult> future = context.future;
+        SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer());
+        if (result.isFailed()) {
+            s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult());
+            try {
+                snapshot.processEvent(Snapshot.Event.OperationFailed);
+                snapshot.processEvent(Event.OperationFailed);
+            } catch (Exception e) {
+                s_logger.debug("Failed to update snapshot state due to " + e.getMessage());
+            }
+
+            snapResult.setResult(result.getResult());
+            future.complete(snapResult);
+            return null;
+        }
+
+        try {
+            snapshot.processEvent(Event.OperationSuccessed, result.getAnswer());
+            snapshot.processEvent(Snapshot.Event.OperationSucceeded);
+        } catch (Exception e) {
+            s_logger.debug("Failed to create snapshot: ", e);
+            snapResult.setResult(e.toString());
+            try {
+                snapshot.processEvent(Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change snapshot state: " + e1.toString());
+            }
+        }
+
+        future.complete(snapResult);
+        return null;
+    }
+
+    @Override
+    public SnapshotResult takeSnapshot(SnapshotInfo snap) {
+        SnapshotObject snapshot = (SnapshotObject)snap;
+
+        SnapshotObject snapshotOnPrimary = null;
+        try {
+            snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot);
+        } catch (Exception e) {
+            s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage());
+            throw new CloudRuntimeException(e);
+        }
+
+        try {
+            snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested);
+        } catch (NoTransitionException e) {
+            s_logger.debug("Failed to change snapshot state: " + e.toString());
+            throw new CloudRuntimeException(e);
+        }
+
+        try {
+            snapshotOnPrimary.processEvent(Event.CreateOnlyRequested);
+        } catch (Exception e) {
+            s_logger.debug("Failed to change snapshot state: " + e.toString());
+            try {
+                snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change snapshot state: " + e1.toString());
+            }
+            throw new CloudRuntimeException(e);
+        }
+
+        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+        try {
+            CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(null, snap.getBaseVolume(), snapshotOnPrimary, future);
+            AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createSnapshotAsyncCallback(null, null)).setContext(context);
+            PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)snapshotOnPrimary.getDataStore().getDriver();
+            primaryStore.takeSnapshot(snapshot, caller);
+        } catch (Exception e) {
+            s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
+            try {
+                snapshot.processEvent(Snapshot.Event.OperationFailed);
+                snapshot.processEvent(Event.OperationFailed);
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change state for event: OperationFailed", e);
+            }
+            throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId());
+        }
+
+        SnapshotResult result;
+
+        try {
+            result = future.get();
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_ON_PRIMARY, snap.getAccountId(), snap.getDataCenterId(), snap.getId(),
+                    snap.getName(), null, null, snapshotOnPrimary.getSize(), snapshotOnPrimary.getSize(), snap.getClass().getName(), snap.getUuid());
+            return result;
+        } catch (InterruptedException e) {
+            s_logger.debug("Failed to create snapshot", e);
+            throw new CloudRuntimeException("Failed to create snapshot", e);
+        } catch (ExecutionException e) {
+            s_logger.debug("Failed to create snapshot", e);
+            throw new CloudRuntimeException("Failed to create snapshot", e);
+        }
+    }
+
+    // if a snapshot has parent snapshot, the new snapshot should be stored in
+    // the same store as its parent since
+    // we are taking delta snapshot
+    private DataStore findSnapshotImageStore(SnapshotInfo snapshot) {
+        Boolean fullSnapshot = true;
+        Boolean snapshotFullBackup = snapshot.getFullBackup();
+        if (snapshotFullBackup != null) {
+            fullSnapshot = snapshotFullBackup;
+        }
+        if (fullSnapshot) {
+            return dataStoreMgr.getImageStore(snapshot.getDataCenterId());
+        } else {
+            SnapshotInfo parentSnapshot = snapshot.getParent();
+            // Note that DataStore information in parentSnapshot is for primary
+            // data store here, we need to
+            // find the image store where the parent snapshot backup is located
+            SnapshotDataStoreVO parentSnapshotOnBackupStore = null;
+            if (parentSnapshot != null) {
+                parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
+            }
+            if (parentSnapshotOnBackupStore == null) {
+                return dataStoreMgr.getImageStore(snapshot.getDataCenterId());
+            }
+            return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole());
+        }
+    }
+
+    @Override
+    public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
+        SnapshotObject snapObj = (SnapshotObject)snapshot;
+        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+        SnapshotResult result = new SnapshotResult(snapshot, null);
+        Snapshot.State origState = snapObj.getState();
+        try {
+            snapObj.processEvent(Snapshot.Event.BackupToSecondary);
+
+            DataStore imageStore = findSnapshotImageStore(snapshot);
+            if (imageStore == null) {
+                throw new CloudRuntimeException("can not find an image stores");
+            }
+
+            SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot);
+
+            snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
+            CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot, snapshotOnImageStore, future);
+            AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().copySnapshotAsyncCallback(null, null)).setContext(context);
+            motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller);
+        } catch (Exception e) {
+            s_logger.debug("Failed to copy snapshot", e);
+            result.setResult("Failed to copy snapshot:" + e.toString());
+            try {
+                // When error archiving an already existing snapshot, emit OperationNotPerformed.
+                // This will ensure that the original snapshot does not get deleted
+                if (origState.equals(Snapshot.State.BackedUp)) {
+                    snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
+                } else {
+                    snapObj.processEvent(Snapshot.Event.OperationFailed);
+                }
+            } catch (NoTransitionException e1) {
+                s_logger.debug("Failed to change state: " + e1.toString());
+            }
+            future.complete(result);
+        }
+
+        try {
+            SnapshotResult res = future.get();
+            if (res.isFailed()) {
+                throw new CloudRuntimeException(res.getResult());
+            }
+            SnapshotInfo destSnapshot = res.getSnapshot();
+            return destSnapshot;
+        } catch (InterruptedException e) {
+            s_logger.debug("failed copy snapshot", e);
+            throw new CloudRuntimeException("Failed to copy snapshot", e);
+        } catch (ExecutionException e) {
+            s_logger.debug("Failed to copy snapshot", e);
+            throw new CloudRuntimeException("Failed to copy snapshot", e);
+        }
+
+    }
+
+    protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> callback, CopySnapshotContext<CommandResult> context) {
+        CopyCommandResult result = callback.getResult();
+        SnapshotInfo destSnapshot = context.destSnapshot;
+        SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot;
+        Object payload = srcSnapshot.getPayload();
+        CreateSnapshotPayload createSnapshotPayload = (CreateSnapshotPayload)payload;
+        AsyncCallFuture<SnapshotResult> future = context.future;
+        SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer());
+        if (result.isFailed()) {
+            try {
+                if (createSnapshotPayload.getAsyncBackup()) {
+                    destSnapshot.processEvent(Event.OperationFailed);
+                    throw new SnapshotBackupException("Failed in creating backup of snapshot with ID "+srcSnapshot.getId());
+                } else {
+                    destSnapshot.processEvent(Event.OperationFailed);
+                    //if backup snapshot failed, mark srcSnapshot in snapshot_store_ref as failed also
+                    cleanupOnSnapshotBackupFailure(context.srcSnapshot);
+                }
+            } catch (SnapshotBackupException e) {
+                s_logger.debug("Failed to create backup: " + e.toString());
+            }
+            snapResult.setResult(result.getResult());
+            future.complete(snapResult);
+            return null;
+        }
+
+        try {
+            CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)result.getAnswer();
+            destSnapshot.processEvent(Event.OperationSuccessed, copyCmdAnswer);
+            srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded);
+            snapResult = new SnapshotResult(_snapshotFactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), copyCmdAnswer);
+            future.complete(snapResult);
+        } catch (Exception e) {
+            s_logger.debug("Failed to update snapshot state", e);
+            snapResult.setResult(e.toString());
+            future.complete(snapResult);
+        }
+        return null;
+    }
+
+    protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback, DeleteSnapshotContext<CommandResult> context) {
+
+        CommandResult result = callback.getResult();
+        AsyncCallFuture<SnapshotResult> future = context.future;
+        SnapshotInfo snapshot = context.snapshot;
+        SnapshotResult res = null;
+        try {
+            if (result.isFailed()) {
+                s_logger.debug("delete snapshot failed" + result.getResult());
+                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+                res = new SnapshotResult(context.snapshot, null);
+                res.setResult(result.getResult());
+            } else {
+                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
+                res = new SnapshotResult(context.snapshot, null);
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to in deleteSnapshotCallback", e);
+            res.setResult(e.toString());
+        }
+        future.complete(res);
+        return null;
+    }
+
+    protected Void revertSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback, RevertSnapshotContext<CommandResult> context) {
+
+        CommandResult result = callback.getResult();
+        AsyncCallFuture<SnapshotResult> future = context.future;
+        SnapshotResult res = null;
+        try {
+            if (result.isFailed()) {
+                s_logger.debug("revert snapshot failed" + result.getResult());
+                res = new SnapshotResult(context.snapshot, null);
+                res.setResult(result.getResult());
+            } else {
+                res = new SnapshotResult(context.snapshot, null);
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to in revertSnapshotCallback", e);
+            res.setResult(e.toString());
+        }
+        future.complete(res);
+        return null;
+    }
+
+    @Override
+    public boolean deleteSnapshot(SnapshotInfo snapInfo) {
+        snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
+
+        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+        DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null, snapInfo, future);
+        AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context);
+        DataStore store = snapInfo.getDataStore();
+        store.getDriver().deleteAsync(store, snapInfo, caller);
+
+        SnapshotResult result = null;
+        try {
+            result = future.get();
+            if (result.isFailed()) {
+                throw new CloudRuntimeException(result.getResult());
+            }
+            return true;
+        } catch (InterruptedException e) {
+            s_logger.debug("delete snapshot is failed: " + e.toString());
+        } catch (ExecutionException e) {
+            s_logger.debug("delete snapshot is failed: " + e.toString());
+        }
+
+        return false;
+
+    }
+
+    @Override
+    public boolean revertSnapshot(SnapshotInfo snapshot) {
+        SnapshotInfo snapshotOnPrimaryStore = _snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
+        if (snapshotOnPrimaryStore == null) {
+            throw new CloudRuntimeException("Cannot find an entry for snapshot " + snapshot.getId() + " on primary storage pools");
+        }
+        PrimaryDataStore store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore();
+
+        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+        RevertSnapshotContext<CommandResult> context = new RevertSnapshotContext<CommandResult>(null, snapshot, future);
+        AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().revertSnapshotCallback(null, null)).setContext(context);
+
+        ((PrimaryDataStoreDriver)store.getDriver()).revertSnapshot(snapshot, snapshotOnPrimaryStore, caller);
+
+        SnapshotResult result = null;
+        try {
+            result = future.get();
+            if (result.isFailed()) {
+                throw new CloudRuntimeException(result.getResult());
+            }
+            return true;
+        } catch (InterruptedException e) {
+            s_logger.debug("revert snapshot is failed: " + e.toString());
+        } catch (ExecutionException e) {
+            s_logger.debug("revert snapshot is failed: " + e.toString());
+        }
+
+        return false;
+    }
+
+    // This routine is used to push snapshots currently on cache store, but not in region store to region store.
+    // used in migrating existing NFS secondary storage to S3. We chose to push all volume related snapshots to handle delta snapshots smoothly.
+    @Override
+    public void syncVolumeSnapshotsToRegionStore(long volumeId, DataStore store) {
+        if (dataStoreMgr.isRegionStore(store)) {
+            // list all backed up snapshots for the given volume
+            List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volumeId, Snapshot.State.BackedUp);
+            if (snapshots != null) {
+                for (SnapshotVO snapshot : snapshots) {
+                    syncSnapshotToRegionStore(snapshot.getId(), store);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void cleanupVolumeDuringSnapshotFailure(Long volumeId, Long snapshotId) {
+        SnapshotVO snaphsot = _snapshotDao.findById(snapshotId);
+
+        if (snaphsot != null) {
+            if (snaphsot.getState() != Snapshot.State.BackedUp) {
+                List<SnapshotDataStoreVO> snapshotDataStoreVOs = _snapshotStoreDao.findBySnapshotId(snapshotId);
+                for (SnapshotDataStoreVO snapshotDataStoreVO : snapshotDataStoreVOs) {
+                    s_logger.debug("Remove snapshot " + snapshotId + ", status " + snapshotDataStoreVO.getState() +
+                            " on snapshot_store_ref table with id: " + snapshotDataStoreVO.getId());
+
+                    _snapshotStoreDao.remove(snapshotDataStoreVO.getId());
+                }
+
+                s_logger.debug("Remove snapshot " + snapshotId + " status " + snaphsot.getState() + " from snapshot table");
+                _snapshotDao.remove(snapshotId);
+            }
+        }
+
+
+    }
+
+    // push one individual snapshots currently on cache store to region store if it is not there already
+    private void syncSnapshotToRegionStore(long snapshotId, DataStore store){
+        // if snapshot is already on region wide object store, check if it is really downloaded there (by checking install_path). Sync snapshot to region
+        // wide store if it is not there physically.
+        SnapshotInfo snapOnStore = _snapshotFactory.getSnapshot(snapshotId, store);
+        if (snapOnStore == null) {
+            throw new CloudRuntimeException("Cannot find an entry in snapshot_store_ref for snapshot " + snapshotId + " on region store: " + store.getName());
+        }
+        if (snapOnStore.getPath() == null || snapOnStore.getPath().length() == 0) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("sync snapshot " + snapshotId + " from cache to object store...");
+            }
+            // snapshot is not on region store yet, sync to region store
+            SnapshotInfo srcSnapshot = _snapshotFactory.getReadySnapshotOnCache(snapshotId);
+            if (srcSnapshot == null) {
+                throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + "  on cache store");
+            }
+            AsyncCallFuture<SnapshotResult> future = syncToRegionStoreAsync(srcSnapshot, store);
+            try {
+                SnapshotResult result = future.get();
+                if (result.isFailed()) {
+                    throw new CloudRuntimeException("sync snapshot from cache to region wide store failed for image store " + store.getName() + ":"
+                            + result.getResult());
+                }
+                _cacheMgr.releaseCacheObject(srcSnapshot); // reduce reference count for template on cache, so it can recycled by schedule
+            } catch (Exception ex) {
+                throw new CloudRuntimeException("sync snapshot from cache to region wide store failed for image store " + store.getName());
+            }
+        }
+
+    }
+
+    private AsyncCallFuture<SnapshotResult> syncToRegionStoreAsync(SnapshotInfo snapshot, DataStore store) {
+        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
+        // no need to create entry on snapshot_store_ref here, since entries are already created when updateCloudToUseObjectStore is invoked.
+        // But we need to set default install path so that sync can be done in the right s3 path
+        SnapshotInfo snapshotOnStore = _snapshotFactory.getSnapshot(snapshot, store);
+        String installPath = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/"
+                + snapshot.getAccountId() + "/" + snapshot.getVolumeId();
+        ((SnapshotObject)snapshotOnStore).setPath(installPath);
+        CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot,
+                snapshotOnStore, future);
+        AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher
+                .create(this);
+        caller.setCallback(caller.getTarget().syncSnapshotCallBack(null, null)).setContext(context);
+        motionSrv.copyAsync(snapshot, snapshotOnStore, caller);
+        return future;
+    }
+
+    protected Void syncSnapshotCallBack(AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> callback,
+            CopySnapshotContext<CommandResult> context) {
+        CopyCommandResult result = callback.getResult();
+        SnapshotInfo destSnapshot = context.destSnapshot;
+        SnapshotResult res = new SnapshotResult(destSnapshot, null);
+
+        AsyncCallFuture<SnapshotResult> future = context.future;
+        try {
+            if (result.isFailed()) {
+                res.setResult(result.getResult());
+                // no change to existing snapshot_store_ref, will try to re-sync later if other call triggers this sync operation
+            } else {
+                // this will update install path properly, next time it will not sync anymore.
+                destSnapshot.processEvent(Event.OperationSuccessed, result.getAnswer());
+            }
+            future.complete(res);
+        } catch (Exception e) {
+            s_logger.debug("Failed to process sync snapshot callback", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void processEventOnSnapshotObject(SnapshotInfo snapshot, Snapshot.Event event) {
+        SnapshotObject object = (SnapshotObject)snapshot;
+        try {
+            object.processEvent(event);
+        } catch (NoTransitionException e) {
+            s_logger.debug("Unable to update the state " + e.toString());
+        }
+    }
+
+    @Override
+    public void cleanupOnSnapshotBackupFailure(SnapshotInfo snapshot) {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                try {
+                    SnapshotObject srcSnapshot = (SnapshotObject)snapshot;
+                    srcSnapshot.processEvent(Event.DestroyRequested);
+                    srcSnapshot.processEvent(Event.OperationSuccessed);
+
+                    srcSnapshot.processEvent(Snapshot.Event.OperationFailed);
+
+                    _snapshotDetailsDao.removeDetail(srcSnapshot.getId(), AsyncJob.Constants.MS_ID);
+                    _snapshotDao.remove(srcSnapshot.getId());
+                } catch (NoTransitionException ex) {
+                    s_logger.debug("Failed to create backup " + ex.toString());
+                    throw new CloudRuntimeException("Failed to backup snapshot" + snapshot.getId());
+                }
+            }
+        });
+
+    }
+
+}
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java
diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
new file mode 100644
index 0000000..57f8938
--- /dev/null
+++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.storage.snapshot;
+
+import javax.inject.Inject;
+
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Event;
+import com.cloud.storage.Snapshot.State;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.listener.SnapshotStateListener;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+
+public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineManager {
+    private StateMachine2<State, Event, SnapshotVO> stateMachine = new StateMachine2<State, Event, SnapshotVO>();
+    @Inject
+    protected SnapshotDao snapshotDao;
+
+    public SnapshotStateMachineManagerImpl() {
+        stateMachine.addTransition(Snapshot.State.Allocated, Event.CreateRequested, Snapshot.State.Creating);
+        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationSucceeded, Snapshot.State.CreatedOnPrimary);
+        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp);
+        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error);
+        stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp);
+        stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.OperationNotPerformed, Snapshot.State.BackedUp);
+        stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp);
+        stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.Error);
+        stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationNotPerformed, State.BackedUp);
+        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);
+        stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, State.BackedUp);
+        stateMachine.addTransition(Snapshot.State.Destroying, Event.DestroyRequested, Snapshot.State.Destroying);
+        stateMachine.addTransition(Snapshot.State.BackingUp, Event.BackupToSecondary, Snapshot.State.BackingUp);
+
+        stateMachine.registerListener(new SnapshotStateListener());
+    }
+
+    @Override
+    public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException {
+        stateMachine.transitTo(snapshot, event, null, snapshotDao);
+    }
+}
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
similarity index 100%
rename from engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
rename to engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
diff --git a/engine/storage/snapshot/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml b/engine/storage/snapshot/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml
similarity index 100%
rename from engine/storage/snapshot/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml
rename to engine/storage/snapshot/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-snapshot-core-context.xml
diff --git a/engine/storage/snapshot/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml b/engine/storage/snapshot/src/main/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml
similarity index 100%
rename from engine/storage/snapshot/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml
rename to engine/storage/snapshot/src/main/resources/META-INF/cloudstack/storage/spring-engine-storage-snapshot-storage-context.xml
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
deleted file mode 100644
index ad58f42..0000000
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.snapshot;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    SnapshotDataStoreDao snapshotStoreDao;
-    @Inject
-    DataStoreManager storeMgr;
-    @Inject
-    VolumeDataFactory volumeFactory;
-
-    @Override
-    public SnapshotInfo getSnapshot(long snapshotId, DataStore store) {
-        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
-        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
-        return so;
-    }
-
-    @Override
-    public SnapshotInfo getSnapshot(DataObject obj, DataStore store) {
-        SnapshotVO snapshot = snapshotDao.findById(obj.getId());
-        if (snapshot == null) {
-            throw new CloudRuntimeException("Can't find snapshot: " + obj.getId());
-        }
-        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
-        return so;
-    }
-
-    @Override
-    public List<SnapshotInfo> getSnapshots(long volumeId, DataStoreRole role) {
-
-        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findByVolume(volumeId, role);
-        if (snapshotStore == null) {
-            return new ArrayList<>();
-        }
-        DataStore store = storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
-        List<SnapshotVO> volSnapShots = snapshotDao.listByVolumeId(volumeId);
-        List<SnapshotInfo> infos = new ArrayList<>();
-        for(SnapshotVO snapshot: volSnapShots) {
-            SnapshotObject info = SnapshotObject.getSnapshotObject(snapshot, store);
-            infos.add(info);
-        }
-        return infos;
-    }
-
-
-    @Override
-    public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role) {
-        SnapshotVO snapshot = snapshotDao.findById(snapshotId);
-        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId, role);
-        if (snapshotStore == null) {
-            snapshotStore = snapshotStoreDao.findByVolume(snapshot.getVolumeId(), role);
-            if (snapshotStore == null) {
-                return null;
-            }
-        }
-        DataStore store = storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
-        SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);
-        return so;
-    }
-
-    @Override
-    public SnapshotInfo getReadySnapshotOnCache(long snapshotId) {
-        SnapshotDataStoreVO snapStore = snapshotStoreDao.findReadyOnCache(snapshotId);
-        if (snapStore != null) {
-            DataStore store = storeMgr.getDataStore(snapStore.getDataStoreId(), DataStoreRole.ImageCache);
-            return getSnapshot(snapshotId, store);
-        } else {
-            return null;
-        }
-
-    }
-
-    @Override
-    public List<SnapshotInfo> listSnapshotOnCache(long snapshotId) {
-        List<SnapshotDataStoreVO> cacheSnapshots = snapshotStoreDao.listOnCache(snapshotId);
-        List<SnapshotInfo> snapObjs = new ArrayList<SnapshotInfo>();
-        for (SnapshotDataStoreVO cacheSnap : cacheSnapshots) {
-            long storeId = cacheSnap.getDataStoreId();
-            DataStore store = storeMgr.getDataStore(storeId, DataStoreRole.ImageCache);
-            SnapshotInfo tmplObj = getSnapshot(snapshotId, store);
-            snapObjs.add(tmplObj);
-        }
-        return snapObjs;
-    }
-
-}
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
deleted file mode 100644
index 601959b..0000000
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ /dev/null
@@ -1,596 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.storage.snapshot;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-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.SnapshotResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.async.AsyncRpcContext;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.log4j.Logger;
-
-import com.cloud.storage.CreateSnapshotPayload;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotDetailsDao;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-
-public class SnapshotServiceImpl implements SnapshotService {
-    private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class);
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected SnapshotDataStoreDao _snapshotStoreDao;
-    @Inject
-    SnapshotDataFactory _snapshotFactory;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    DataMotionService motionSrv;
-    @Inject
-    StorageCacheManager _cacheMgr;
-    @Inject
-    private SnapshotDetailsDao _snapshotDetailsDao;
-
-    static private class CreateSnapshotContext<T> extends AsyncRpcContext<T> {
-        final SnapshotInfo snapshot;
-        final AsyncCallFuture<SnapshotResult> future;
-
-        public CreateSnapshotContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
-            super(callback);
-            this.snapshot = snapshot;
-            this.future = future;
-        }
-    }
-
-    static private class DeleteSnapshotContext<T> extends AsyncRpcContext<T> {
-        final SnapshotInfo snapshot;
-        final AsyncCallFuture<SnapshotResult> future;
-
-        public DeleteSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
-            super(callback);
-            this.snapshot = snapshot;
-            this.future = future;
-        }
-
-    }
-
-    static private class CopySnapshotContext<T> extends AsyncRpcContext<T> {
-        final SnapshotInfo srcSnapshot;
-        final SnapshotInfo destSnapshot;
-        final AsyncCallFuture<SnapshotResult> future;
-
-        public CopySnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo srcSnapshot, SnapshotInfo destSnapshot, AsyncCallFuture<SnapshotResult> future) {
-            super(callback);
-            this.srcSnapshot = srcSnapshot;
-            this.destSnapshot = destSnapshot;
-            this.future = future;
-        }
-
-    }
-
-    static private class RevertSnapshotContext<T> extends AsyncRpcContext<T> {
-        final SnapshotInfo snapshot;
-        final AsyncCallFuture<SnapshotResult> future;
-
-        public RevertSnapshotContext(AsyncCompletionCallback<T> callback, SnapshotInfo snapshot, AsyncCallFuture<SnapshotResult> future) {
-            super(callback);
-            this.snapshot = snapshot;
-            this.future = future;
-        }
-
-    }
-
-    protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> callback, CreateSnapshotContext<CreateCmdResult> context) {
-        CreateCmdResult result = callback.getResult();
-        SnapshotObject snapshot = (SnapshotObject)context.snapshot;
-        AsyncCallFuture<SnapshotResult> future = context.future;
-        SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer());
-        if (result.isFailed()) {
-            s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult());
-            try {
-                snapshot.processEvent(Snapshot.Event.OperationFailed);
-                snapshot.processEvent(Event.OperationFailed);
-            } catch (Exception e) {
-                s_logger.debug("Failed to update snapshot state due to " + e.getMessage());
-            }
-
-            snapResult.setResult(result.getResult());
-            future.complete(snapResult);
-            return null;
-        }
-
-        try {
-            snapshot.processEvent(Event.OperationSuccessed, result.getAnswer());
-            snapshot.processEvent(Snapshot.Event.OperationSucceeded);
-        } catch (Exception e) {
-            s_logger.debug("Failed to create snapshot: ", e);
-            snapResult.setResult(e.toString());
-            try {
-                snapshot.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change snapshot state: " + e1.toString());
-            }
-        }
-
-        future.complete(snapResult);
-        return null;
-    }
-
-    @Override
-    public SnapshotResult takeSnapshot(SnapshotInfo snap) {
-        SnapshotObject snapshot = (SnapshotObject)snap;
-
-        SnapshotObject snapshotOnPrimary = null;
-        try {
-            snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot);
-        } catch (Exception e) {
-            s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage());
-            throw new CloudRuntimeException(e);
-        }
-
-        try {
-            snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Failed to change snapshot state: " + e.toString());
-            throw new CloudRuntimeException(e);
-        }
-
-        try {
-            snapshotOnPrimary.processEvent(Event.CreateOnlyRequested);
-        } catch (Exception e) {
-            s_logger.debug("Failed to change snapshot state: " + e.toString());
-            try {
-                snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change snapshot state: " + e1.toString());
-            }
-            throw new CloudRuntimeException(e);
-        }
-
-        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-        try {
-            CreateSnapshotContext<CommandResult> context = new CreateSnapshotContext<CommandResult>(null, snap.getBaseVolume(), snapshotOnPrimary, future);
-            AsyncCallbackDispatcher<SnapshotServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().createSnapshotAsyncCallback(null, null)).setContext(context);
-            PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)snapshotOnPrimary.getDataStore().getDriver();
-            primaryStore.takeSnapshot(snapshot, caller);
-        } catch (Exception e) {
-            s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
-            try {
-                snapshot.processEvent(Snapshot.Event.OperationFailed);
-                snapshot.processEvent(Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change state for event: OperationFailed", e);
-            }
-            throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId());
-        }
-
-        SnapshotResult result;
-
-        try {
-            result = future.get();
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_ON_PRIMARY, snap.getAccountId(), snap.getDataCenterId(), snap.getId(),
-                    snap.getName(), null, null, snapshotOnPrimary.getSize(), snapshotOnPrimary.getSize(), snap.getClass().getName(), snap.getUuid());
-            return result;
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to create snapshot", e);
-            throw new CloudRuntimeException("Failed to create snapshot", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to create snapshot", e);
-            throw new CloudRuntimeException("Failed to create snapshot", e);
-        }
-    }
-
-    // if a snapshot has parent snapshot, the new snapshot should be stored in
-    // the same store as its parent since
-    // we are taking delta snapshot
-    private DataStore findSnapshotImageStore(SnapshotInfo snapshot) {
-        Boolean fullSnapshot = true;
-        Boolean snapshotFullBackup = snapshot.getFullBackup();
-        if (snapshotFullBackup != null) {
-            fullSnapshot = snapshotFullBackup;
-        }
-        if (fullSnapshot) {
-            return dataStoreMgr.getImageStore(snapshot.getDataCenterId());
-        } else {
-            SnapshotInfo parentSnapshot = snapshot.getParent();
-            // Note that DataStore information in parentSnapshot is for primary
-            // data store here, we need to
-            // find the image store where the parent snapshot backup is located
-            SnapshotDataStoreVO parentSnapshotOnBackupStore = null;
-            if (parentSnapshot != null) {
-                parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
-            }
-            if (parentSnapshotOnBackupStore == null) {
-                return dataStoreMgr.getImageStore(snapshot.getDataCenterId());
-            }
-            return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), parentSnapshotOnBackupStore.getRole());
-        }
-    }
-
-    @Override
-    public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
-        SnapshotObject snapObj = (SnapshotObject)snapshot;
-        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-        SnapshotResult result = new SnapshotResult(snapshot, null);
-        try {
-            snapObj.processEvent(Snapshot.Event.BackupToSecondary);
-
-            DataStore imageStore = findSnapshotImageStore(snapshot);
-            if (imageStore == null) {
-                throw new CloudRuntimeException("can not find an image stores");
-            }
-
-            SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot);
-
-            snapshotOnImageStore.processEvent(Event.CreateOnlyRequested);
-            CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot, snapshotOnImageStore, future);
-            AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().copySnapshotAsyncCallback(null, null)).setContext(context);
-            motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller);
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy snapshot", e);
-            result.setResult("Failed to copy snapshot:" + e.toString());
-            try {
-                snapObj.processEvent(Snapshot.Event.OperationFailed);
-            } catch (NoTransitionException e1) {
-                s_logger.debug("Failed to change state: " + e1.toString());
-            }
-            future.complete(result);
-        }
-
-        try {
-            SnapshotResult res = future.get();
-            if (res.isFailed()) {
-                throw new CloudRuntimeException(res.getResult());
-            }
-            SnapshotInfo destSnapshot = res.getSnapshot();
-            return destSnapshot;
-        } catch (InterruptedException e) {
-            s_logger.debug("failed copy snapshot", e);
-            throw new CloudRuntimeException("Failed to copy snapshot", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to copy snapshot", e);
-            throw new CloudRuntimeException("Failed to copy snapshot", e);
-        }
-
-    }
-
-    protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> callback, CopySnapshotContext<CommandResult> context) {
-        CopyCommandResult result = callback.getResult();
-        SnapshotInfo destSnapshot = context.destSnapshot;
-        SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot;
-        Object payload = srcSnapshot.getPayload();
-        CreateSnapshotPayload createSnapshotPayload = (CreateSnapshotPayload)payload;
-        AsyncCallFuture<SnapshotResult> future = context.future;
-        SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer());
-        if (result.isFailed()) {
-            try {
-                if (createSnapshotPayload.getAsyncBackup()) {
-                    destSnapshot.processEvent(Event.OperationFailed);
-                    throw new SnapshotBackupException("Failed in creating backup of snapshot with ID "+srcSnapshot.getId());
-                } else {
-                    destSnapshot.processEvent(Event.OperationFailed);
-                    //if backup snapshot failed, mark srcSnapshot in snapshot_store_ref as failed also
-                    cleanupOnSnapshotBackupFailure(context.srcSnapshot);
-                }
-            } catch (SnapshotBackupException e) {
-                s_logger.debug("Failed to create backup: " + e.toString());
-            }
-            snapResult.setResult(result.getResult());
-            future.complete(snapResult);
-            return null;
-        }
-
-        try {
-            CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)result.getAnswer();
-            destSnapshot.processEvent(Event.OperationSuccessed, copyCmdAnswer);
-            srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded);
-            snapResult = new SnapshotResult(_snapshotFactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), copyCmdAnswer);
-            future.complete(snapResult);
-        } catch (Exception e) {
-            s_logger.debug("Failed to update snapshot state", e);
-            snapResult.setResult(e.toString());
-            future.complete(snapResult);
-        }
-        return null;
-    }
-
-    protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback, DeleteSnapshotContext<CommandResult> context) {
-
-        CommandResult result = callback.getResult();
-        AsyncCallFuture<SnapshotResult> future = context.future;
-        SnapshotInfo snapshot = context.snapshot;
-        SnapshotResult res = null;
-        try {
-            if (result.isFailed()) {
-                s_logger.debug("delete snapshot failed" + result.getResult());
-                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-                res = new SnapshotResult(context.snapshot, null);
-                res.setResult(result.getResult());
-            } else {
-                snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
-                res = new SnapshotResult(context.snapshot, null);
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to in deleteSnapshotCallback", e);
-            res.setResult(e.toString());
-        }
-        future.complete(res);
-        return null;
-    }
-
-    protected Void revertSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback, RevertSnapshotContext<CommandResult> context) {
-
-        CommandResult result = callback.getResult();
-        AsyncCallFuture<SnapshotResult> future = context.future;
-        SnapshotResult res = null;
-        try {
-            if (result.isFailed()) {
-                s_logger.debug("revert snapshot failed" + result.getResult());
-                res = new SnapshotResult(context.snapshot, null);
-                res.setResult(result.getResult());
-            } else {
-                res = new SnapshotResult(context.snapshot, null);
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to in revertSnapshotCallback", e);
-            res.setResult(e.toString());
-        }
-        future.complete(res);
-        return null;
-    }
-
-    @Override
-    public boolean deleteSnapshot(SnapshotInfo snapInfo) {
-        snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
-
-        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-        DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null, snapInfo, future);
-        AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context);
-        DataStore store = snapInfo.getDataStore();
-        store.getDriver().deleteAsync(store, snapInfo, caller);
-
-        SnapshotResult result = null;
-        try {
-            result = future.get();
-            if (result.isFailed()) {
-                throw new CloudRuntimeException(result.getResult());
-            }
-            return true;
-        } catch (InterruptedException e) {
-            s_logger.debug("delete snapshot is failed: " + e.toString());
-        } catch (ExecutionException e) {
-            s_logger.debug("delete snapshot is failed: " + e.toString());
-        }
-
-        return false;
-
-    }
-
-    @Override
-    public boolean revertSnapshot(SnapshotInfo snapshot) {
-        SnapshotInfo snapshotOnPrimaryStore = _snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
-        if (snapshotOnPrimaryStore == null) {
-            throw new CloudRuntimeException("Cannot find an entry for snapshot " + snapshot.getId() + " on primary storage pools");
-        }
-        PrimaryDataStore store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore();
-
-        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-        RevertSnapshotContext<CommandResult> context = new RevertSnapshotContext<CommandResult>(null, snapshot, future);
-        AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().revertSnapshotCallback(null, null)).setContext(context);
-
-        ((PrimaryDataStoreDriver)store.getDriver()).revertSnapshot(snapshot, snapshotOnPrimaryStore, caller);
-
-        SnapshotResult result = null;
-        try {
-            result = future.get();
-            if (result.isFailed()) {
-                throw new CloudRuntimeException(result.getResult());
-            }
-            return true;
-        } catch (InterruptedException e) {
-            s_logger.debug("revert snapshot is failed: " + e.toString());
-        } catch (ExecutionException e) {
-            s_logger.debug("revert snapshot is failed: " + e.toString());
-        }
-
-        return false;
-    }
-
-    // This routine is used to push snapshots currently on cache store, but not in region store to region store.
-    // used in migrating existing NFS secondary storage to S3. We chose to push all volume related snapshots to handle delta snapshots smoothly.
-    @Override
-    public void syncVolumeSnapshotsToRegionStore(long volumeId, DataStore store) {
-        if (dataStoreMgr.isRegionStore(store)) {
-            // list all backed up snapshots for the given volume
-            List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volumeId, Snapshot.State.BackedUp);
-            if (snapshots != null) {
-                for (SnapshotVO snapshot : snapshots) {
-                    syncSnapshotToRegionStore(snapshot.getId(), store);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void cleanupVolumeDuringSnapshotFailure(Long volumeId, Long snapshotId) {
-        SnapshotVO snaphsot = _snapshotDao.findById(snapshotId);
-
-        if (snaphsot != null) {
-            if (snaphsot.getState() != Snapshot.State.BackedUp) {
-                List<SnapshotDataStoreVO> snapshotDataStoreVOs = _snapshotStoreDao.findBySnapshotId(snapshotId);
-                for (SnapshotDataStoreVO snapshotDataStoreVO : snapshotDataStoreVOs) {
-                    s_logger.debug("Remove snapshot " + snapshotId + ", status " + snapshotDataStoreVO.getState() +
-                            " on snapshot_store_ref table with id: " + snapshotDataStoreVO.getId());
-
-                    _snapshotStoreDao.remove(snapshotDataStoreVO.getId());
-                }
-
-                s_logger.debug("Remove snapshot " + snapshotId + " status " + snaphsot.getState() + " from snapshot table");
-                _snapshotDao.remove(snapshotId);
-            }
-        }
-
-
-    }
-
-    // push one individual snapshots currently on cache store to region store if it is not there already
-    private void syncSnapshotToRegionStore(long snapshotId, DataStore store){
-        // if snapshot is already on region wide object store, check if it is really downloaded there (by checking install_path). Sync snapshot to region
-        // wide store if it is not there physically.
-        SnapshotInfo snapOnStore = _snapshotFactory.getSnapshot(snapshotId, store);
-        if (snapOnStore == null) {
-            throw new CloudRuntimeException("Cannot find an entry in snapshot_store_ref for snapshot " + snapshotId + " on region store: " + store.getName());
-        }
-        if (snapOnStore.getPath() == null || snapOnStore.getPath().length() == 0) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("sync snapshot " + snapshotId + " from cache to object store...");
-            }
-            // snapshot is not on region store yet, sync to region store
-            SnapshotInfo srcSnapshot = _snapshotFactory.getReadySnapshotOnCache(snapshotId);
-            if (srcSnapshot == null) {
-                throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + "  on cache store");
-            }
-            AsyncCallFuture<SnapshotResult> future = syncToRegionStoreAsync(srcSnapshot, store);
-            try {
-                SnapshotResult result = future.get();
-                if (result.isFailed()) {
-                    throw new CloudRuntimeException("sync snapshot from cache to region wide store failed for image store " + store.getName() + ":"
-                            + result.getResult());
-                }
-                _cacheMgr.releaseCacheObject(srcSnapshot); // reduce reference count for template on cache, so it can recycled by schedule
-            } catch (Exception ex) {
-                throw new CloudRuntimeException("sync snapshot from cache to region wide store failed for image store " + store.getName());
-            }
-        }
-
-    }
-
-    private AsyncCallFuture<SnapshotResult> syncToRegionStoreAsync(SnapshotInfo snapshot, DataStore store) {
-        AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
-        // no need to create entry on snapshot_store_ref here, since entries are already created when updateCloudToUseObjectStore is invoked.
-        // But we need to set default install path so that sync can be done in the right s3 path
-        SnapshotInfo snapshotOnStore = _snapshotFactory.getSnapshot(snapshot, store);
-        String installPath = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/"
-                + snapshot.getAccountId() + "/" + snapshot.getVolumeId();
-        ((SnapshotObject)snapshotOnStore).setPath(installPath);
-        CopySnapshotContext<CommandResult> context = new CopySnapshotContext<CommandResult>(null, snapshot,
-                snapshotOnStore, future);
-        AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher
-                .create(this);
-        caller.setCallback(caller.getTarget().syncSnapshotCallBack(null, null)).setContext(context);
-        motionSrv.copyAsync(snapshot, snapshotOnStore, caller);
-        return future;
-    }
-
-    protected Void syncSnapshotCallBack(AsyncCallbackDispatcher<SnapshotServiceImpl, CopyCommandResult> callback,
-            CopySnapshotContext<CommandResult> context) {
-        CopyCommandResult result = callback.getResult();
-        SnapshotInfo destSnapshot = context.destSnapshot;
-        SnapshotResult res = new SnapshotResult(destSnapshot, null);
-
-        AsyncCallFuture<SnapshotResult> future = context.future;
-        try {
-            if (result.isFailed()) {
-                res.setResult(result.getResult());
-                // no change to existing snapshot_store_ref, will try to re-sync later if other call triggers this sync operation
-            } else {
-                // this will update install path properly, next time it will not sync anymore.
-                destSnapshot.processEvent(Event.OperationSuccessed, result.getAnswer());
-            }
-            future.complete(res);
-        } catch (Exception e) {
-            s_logger.debug("Failed to process sync snapshot callback", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-
-        return null;
-    }
-
-    @Override
-    public void processEventOnSnapshotObject(SnapshotInfo snapshot, Snapshot.Event event) {
-        SnapshotObject object = (SnapshotObject)snapshot;
-        try {
-            object.processEvent(event);
-        } catch (NoTransitionException e) {
-            s_logger.debug("Unable to update the state " + e.toString());
-        }
-    }
-
-    @Override
-    public void cleanupOnSnapshotBackupFailure(SnapshotInfo snapshot) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                try {
-                    SnapshotObject srcSnapshot = (SnapshotObject)snapshot;
-                    srcSnapshot.processEvent(Event.DestroyRequested);
-                    srcSnapshot.processEvent(Event.OperationSuccessed);
-
-                    srcSnapshot.processEvent(Snapshot.Event.OperationFailed);
-
-                    _snapshotDetailsDao.removeDetail(srcSnapshot.getId(), AsyncJob.Constants.MS_ID);
-                    _snapshotDao.remove(srcSnapshot.getId());
-                } catch (NoTransitionException ex) {
-                    s_logger.debug("Failed to create backup " + ex.toString());
-                    throw new CloudRuntimeException("Failed to backup snapshot" + snapshot.getId());
-                }
-            }
-        });
-
-    }
-
-}
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
deleted file mode 100644
index 287c378..0000000
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.storage.snapshot;
-
-import javax.inject.Inject;
-
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Event;
-import com.cloud.storage.Snapshot.State;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.listener.SnapshotStateListener;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-
-public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineManager {
-    private StateMachine2<State, Event, SnapshotVO> stateMachine = new StateMachine2<State, Event, SnapshotVO>();
-    @Inject
-    protected SnapshotDao snapshotDao;
-
-    public SnapshotStateMachineManagerImpl() {
-        stateMachine.addTransition(Snapshot.State.Allocated, Event.CreateRequested, Snapshot.State.Creating);
-        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationSucceeded, Snapshot.State.CreatedOnPrimary);
-        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp);
-        stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error);
-        stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp);
-        stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.OperationNotPerformed, Snapshot.State.BackedUp);
-        stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp);
-        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);
-        stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, State.BackedUp);
-        stateMachine.addTransition(Snapshot.State.Destroying, Event.DestroyRequested, Snapshot.State.Destroying);
-        stateMachine.addTransition(Snapshot.State.BackingUp, Event.BackupToSecondary, Snapshot.State.BackingUp);
-
-        stateMachine.registerListener(new SnapshotStateListener());
-    }
-
-    @Override
-    public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException {
-        stateMachine.transitTo(snapshot, event, null, snapshotDao);
-    }
-}
diff --git a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java
new file mode 100644
index 0000000..aad339b
--- /dev/null
+++ b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImplTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.snapshot;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(PowerMockRunner.class)
+public class SnapshotDataFactoryImplTest {
+
+    @Spy
+    @InjectMocks
+    private SnapshotDataFactoryImpl snapshotDataFactoryImpl = new SnapshotDataFactoryImpl();
+
+    @Mock
+    private SnapshotDataStoreDao snapshotStoreDaoMock;
+    @Mock
+    private DataStoreManager dataStoreManagerMock;
+    @Mock
+    private SnapshotDao snapshotDaoMock;
+
+    private long volumeMockId = 1;
+
+    @Test
+    public void getSnapshotsByVolumeAndDataStoreTestNoSnapshotDataStoreVOFound() {
+        Mockito.doReturn(new ArrayList<>()).when(snapshotStoreDaoMock).listAllByVolumeAndDataStore(volumeMockId, DataStoreRole.Primary);
+
+        List<SnapshotInfo> snapshots = snapshotDataFactoryImpl.getSnapshots(volumeMockId, DataStoreRole.Primary);
+
+        Assert.assertTrue(snapshots.isEmpty());
+    }
+
+    @Test
+    @PrepareForTest({ComponentContext.class})
+    public void getSnapshotsByVolumeAndDataStoreTest() {
+        PowerMockito.mockStatic(ComponentContext.class);
+        PowerMockito.when(ComponentContext.inject(SnapshotObject.class)).thenReturn(new SnapshotObject());
+
+        SnapshotDataStoreVO snapshotDataStoreVoMock = Mockito.mock(SnapshotDataStoreVO.class);
+        Mockito.doReturn(volumeMockId).when(snapshotDataStoreVoMock).getVolumeId();
+
+        long snapshotId = 1223;
+        long dataStoreId = 34567;
+        Mockito.doReturn(snapshotId).when(snapshotDataStoreVoMock).getSnapshotId();
+        Mockito.doReturn(dataStoreId).when(snapshotDataStoreVoMock).getDataStoreId();
+
+        SnapshotVO snapshotVoMock  = Mockito.mock(SnapshotVO.class);
+        Mockito.doReturn(snapshotId).when(snapshotVoMock).getId();
+
+        DataStoreRole dataStoreRole = DataStoreRole.Primary;
+        DataStore dataStoreMock = Mockito.mock(DataStore.class);
+        Mockito.doReturn(dataStoreId).when(dataStoreMock).getId();
+        Mockito.doReturn(dataStoreRole).when(dataStoreMock).getRole();
+
+        List<SnapshotDataStoreVO> snapshotDataStoreVOs = new ArrayList<>();
+        snapshotDataStoreVOs.add(snapshotDataStoreVoMock);
+
+        Mockito.doReturn(snapshotDataStoreVOs).when(snapshotStoreDaoMock).listAllByVolumeAndDataStore(volumeMockId, dataStoreRole);
+        Mockito.doReturn(dataStoreMock).when(dataStoreManagerMock).getDataStore(dataStoreId, dataStoreRole);
+        Mockito.doReturn(snapshotVoMock).when(snapshotDaoMock).findById(snapshotId);
+
+        List<SnapshotInfo> snapshots = snapshotDataFactoryImpl.getSnapshots(volumeMockId, dataStoreRole);
+
+        Assert.assertEquals(1, snapshots.size());
+
+        SnapshotInfo snapshotInfo = snapshots.get(0);
+        Assert.assertEquals(dataStoreMock, snapshotInfo.getDataStore());
+        Assert.assertEquals(snapshotVoMock, ((SnapshotObject)snapshotInfo).getSnapshotVO());
+
+        PowerMockito.verifyStatic();
+        ComponentContext.inject(SnapshotObject.class);
+    }
+}
diff --git a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
new file mode 100644
index 0000000..4420c19
--- /dev/null
+++ b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.vmsnapshot;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateVMSnapshotAnswer;
+import com.cloud.agent.api.DeleteVMSnapshotAnswer;
+import com.cloud.agent.api.RevertToVMSnapshotAnswer;
+import com.cloud.agent.api.VMSnapshotTO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.GuestOSHypervisorVO;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.GuestOSHypervisorDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+import junit.framework.TestCase;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class VMSnapshotStrategyTest extends TestCase {
+    @Inject
+    VMSnapshotStrategy vmSnapshotStrategy;
+    @Inject
+    VMSnapshotHelper vmSnapshotHelper;
+    @Inject
+    UserVmDao userVmDao;
+    @Inject
+    GuestOSDao guestOSDao;
+    @Inject
+    GuestOSHypervisorDao guestOsHypervisorDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    VMSnapshotDao vmSnapshotDao;
+    @Inject
+    HostDao hostDao;
+
+    @Override
+    @Before
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+    }
+
+    @Test
+    public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        HypervisorType hypervisorType = HypervisorType.Any;
+        String hypervisorVersion = "default";
+        String guestOsName = "Other";
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
+        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
+        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
+        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
+        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
+        HostVO hostVO = Mockito.mock(HostVO.class);
+        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
+        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
+        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+        CreateVMSnapshotAnswer answer = Mockito.mock(CreateVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(true);
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
+        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
+        VMSnapshot snapshot = null;
+        snapshot = vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
+        assertNotNull(snapshot);
+    }
+
+    @Test
+    public void testRevertSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        HypervisorType hypervisorType = HypervisorType.Any;
+        String hypervisorVersion = "default";
+        String guestOsName = "Other";
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
+        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
+        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
+        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
+        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
+        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
+        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
+        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
+        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
+        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
+        HostVO hostVO = Mockito.mock(HostVO.class);
+        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
+        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
+        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+
+        RevertToVMSnapshotAnswer answer = Mockito.mock(RevertToVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(Boolean.TRUE);
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
+        boolean result = vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
+        assertTrue(result);
+    }
+
+    @Test
+    public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
+        Long hostId = 1L;
+        Long vmId = 1L;
+        Long guestOsId = 1L;
+        HypervisorType hypervisorType = HypervisorType.Any;
+        String hypervisorVersion = "default";
+        String guestOsName = "Other";
+        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
+        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
+        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
+        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
+        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
+        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
+        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
+        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
+        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
+        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
+        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
+        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
+        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
+        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
+        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
+        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
+        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
+        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
+        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
+        HostVO hostVO = Mockito.mock(HostVO.class);
+        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
+        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
+        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
+
+        Exception e = null;
+        try {
+            vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
+        } catch (CloudRuntimeException e1) {
+            e = e1;
+        }
+
+        assertNotNull(e);
+
+        DeleteVMSnapshotAnswer answer = Mockito.mock(DeleteVMSnapshotAnswer.class);
+        Mockito.when(answer.getResult()).thenReturn(true);
+        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
+
+        boolean result = vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
+        assertTrue(result);
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {NetUtils.class, DefaultVMSnapshotStrategy.class}, includeFilters = {
+            @ComponentScan.Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        public static class Library implements TypeFilter {
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                mdr.getClassMetadata().getClassName();
+                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+
+        @Bean
+        public VMSnapshotHelper vmSnapshotHelper() {
+            return Mockito.mock(VMSnapshotHelper.class);
+        }
+
+        @Bean
+        public GuestOSDao guestOSDao() {
+            return Mockito.mock(GuestOSDao.class);
+        }
+
+        @Bean
+        public GuestOSHypervisorDao guestOsHypervisorDao() {
+            return Mockito.mock(GuestOSHypervisorDao.class);
+        }
+
+        @Bean
+        public UserVmDao userVmDao() {
+            return Mockito.mock(UserVmDao.class);
+        }
+
+        @Bean
+        public VMSnapshotDao vmSnapshotDao() {
+            return Mockito.mock(VMSnapshotDao.class);
+        }
+
+        @Bean
+        public ConfigurationDao configurationDao() {
+            return Mockito.mock(ConfigurationDao.class);
+        }
+
+        @Bean
+        public AgentManager agentManager() {
+            return Mockito.mock(AgentManager.class);
+        }
+
+        @Bean
+        public VolumeDao volumeDao() {
+            return Mockito.mock(VolumeDao.class);
+        }
+
+        @Bean
+        public DiskOfferingDao diskOfferingDao() {
+            return Mockito.mock(DiskOfferingDao.class);
+        }
+
+        @Bean
+        public HostDao hostDao() {
+            return Mockito.mock(HostDao.class);
+        }
+    }
+}
diff --git a/engine/storage/snapshot/test/resources/SnapshotManagerTestContext.xml b/engine/storage/snapshot/src/test/resources/SnapshotManagerTestContext.xml
similarity index 100%
rename from engine/storage/snapshot/test/resources/SnapshotManagerTestContext.xml
rename to engine/storage/snapshot/src/test/resources/SnapshotManagerTestContext.xml
diff --git a/engine/storage/snapshot/test/resources/db.properties b/engine/storage/snapshot/src/test/resources/db.properties
similarity index 100%
rename from engine/storage/snapshot/test/resources/db.properties
rename to engine/storage/snapshot/src/test/resources/db.properties
diff --git a/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java b/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java
deleted file mode 100644
index 6edaff1..0000000
--- a/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package src;
-
-import junit.framework.TestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-
-//@RunWith(SpringJUnit4ClassRunner.class)
-//@ContextConfiguration(locations = "classpath:/SnapshotManagerTestContext.xml")
-public class SnapshotDataFactoryTest extends TestCase {
-    // @Inject SnapshotDataFactory snapshotFactory;
-
-    @Before
-    public void setup() throws Exception {
-        // ComponentContext.initComponentsLifeCycle();
-
-    }
-
-    @Test
-    public void testGestSnapshot() {
-        // snapshotFactory.getSnapshot(snapshotId);
-    }
-
-}
diff --git a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java b/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java
deleted file mode 100644
index 22cf9c1..0000000
--- a/engine/storage/snapshot/test/src/VMSnapshotStrategyTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package src;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import junit.framework.TestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.storage.vmsnapshot.DefaultVMSnapshotStrategy;
-import org.apache.cloudstack.storage.vmsnapshot.VMSnapshotHelper;
-import org.apache.cloudstack.test.utils.SpringUtils;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreateVMSnapshotAnswer;
-import com.cloud.agent.api.DeleteVMSnapshotAnswer;
-import com.cloud.agent.api.RevertToVMSnapshotAnswer;
-import com.cloud.agent.api.VMSnapshotTO;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.GuestOSHypervisorVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.GuestOSHypervisorDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.snapshot.VMSnapshot;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class VMSnapshotStrategyTest extends TestCase {
-    @Inject
-    VMSnapshotStrategy vmSnapshotStrategy;
-    @Inject
-    VMSnapshotHelper vmSnapshotHelper;
-    @Inject
-    UserVmDao userVmDao;
-    @Inject
-    GuestOSDao guestOSDao;
-    @Inject
-    GuestOSHypervisorDao guestOsHypervisorDao;
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    VMSnapshotDao vmSnapshotDao;
-    @Inject
-    HostDao hostDao;
-
-    @Override
-    @Before
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-    }
-
-    @Test
-    public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
-        Long hostId = 1L;
-        Long vmId = 1L;
-        Long guestOsId = 1L;
-        HypervisorType hypervisorType = HypervisorType.Any;
-        String hypervisorVersion = "default";
-        String guestOsName = "Other";
-        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
-        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
-        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
-        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
-        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
-        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
-        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
-        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
-        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
-        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
-        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
-        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
-        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
-        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
-        HostVO hostVO = Mockito.mock(HostVO.class);
-        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
-        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
-        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
-        Exception e = null;
-        try {
-            vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
-        } catch (CloudRuntimeException e1) {
-            e = e1;
-        }
-
-        assertNotNull(e);
-        CreateVMSnapshotAnswer answer = Mockito.mock(CreateVMSnapshotAnswer.class);
-        Mockito.when(answer.getResult()).thenReturn(true);
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
-        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
-        VMSnapshot snapshot = null;
-        snapshot = vmSnapshotStrategy.takeVMSnapshot(vmSnapshot);
-        assertNotNull(snapshot);
-    }
-
-    @Test
-    public void testRevertSnapshot() throws AgentUnavailableException, OperationTimedoutException {
-        Long hostId = 1L;
-        Long vmId = 1L;
-        Long guestOsId = 1L;
-        HypervisorType hypervisorType = HypervisorType.Any;
-        String hypervisorVersion = "default";
-        String guestOsName = "Other";
-        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
-        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
-        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
-        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
-        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
-        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
-        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
-        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
-        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
-        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
-        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
-        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
-        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
-        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
-        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
-        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
-        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
-        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
-        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
-        HostVO hostVO = Mockito.mock(HostVO.class);
-        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
-        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
-        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
-        Exception e = null;
-        try {
-            vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
-        } catch (CloudRuntimeException e1) {
-            e = e1;
-        }
-
-        assertNotNull(e);
-
-        RevertToVMSnapshotAnswer answer = Mockito.mock(RevertToVMSnapshotAnswer.class);
-        Mockito.when(answer.getResult()).thenReturn(Boolean.TRUE);
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
-        boolean result = vmSnapshotStrategy.revertVMSnapshot(vmSnapshot);
-        assertTrue(result);
-    }
-
-    @Test
-    public void testDeleteVMSnapshot() throws AgentUnavailableException, OperationTimedoutException {
-        Long hostId = 1L;
-        Long vmId = 1L;
-        Long guestOsId = 1L;
-        HypervisorType hypervisorType = HypervisorType.Any;
-        String hypervisorVersion = "default";
-        String guestOsName = "Other";
-        List<VolumeObjectTO> volumeObjectTOs = new ArrayList<VolumeObjectTO>();
-        VMSnapshotVO vmSnapshot = Mockito.mock(VMSnapshotVO.class);
-        UserVmVO userVmVO = Mockito.mock(UserVmVO.class);
-        Mockito.when(userVmVO.getGuestOSId()).thenReturn(guestOsId);
-        Mockito.when(vmSnapshot.getVmId()).thenReturn(vmId);
-        Mockito.when(vmSnapshotHelper.pickRunningHost(Matchers.anyLong())).thenReturn(hostId);
-        Mockito.when(vmSnapshotHelper.getVolumeTOList(Matchers.anyLong())).thenReturn(volumeObjectTOs);
-        Mockito.when(userVmDao.findById(Matchers.anyLong())).thenReturn(userVmVO);
-        GuestOSVO guestOSVO = Mockito.mock(GuestOSVO.class);
-        Mockito.when(guestOSDao.findById(Matchers.anyLong())).thenReturn(guestOSVO);
-        GuestOSHypervisorVO guestOSHypervisorVO = Mockito.mock(GuestOSHypervisorVO.class);
-        Mockito.when(guestOSHypervisorVO.getGuestOsName()).thenReturn(guestOsName);
-        Mockito.when(guestOsHypervisorDao.findById(Matchers.anyLong())).thenReturn(guestOSHypervisorVO);
-        Mockito.when(guestOsHypervisorDao.findByOsIdAndHypervisor(Matchers.anyLong(), Matchers.anyString(), Matchers.anyString())).thenReturn(guestOSHypervisorVO);
-        VMSnapshotTO vmSnapshotTO = Mockito.mock(VMSnapshotTO.class);
-        Mockito.when(vmSnapshotHelper.getSnapshotWithParents(Matchers.any(VMSnapshotVO.class))).thenReturn(vmSnapshotTO);
-        Mockito.when(vmSnapshotDao.findById(Matchers.anyLong())).thenReturn(vmSnapshot);
-        Mockito.when(vmSnapshot.getId()).thenReturn(1L);
-        Mockito.when(vmSnapshot.getCreated()).thenReturn(new Date());
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(null);
-        HostVO hostVO = Mockito.mock(HostVO.class);
-        Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(hostVO);
-        Mockito.when(hostVO.getHypervisorType()).thenReturn(hypervisorType);
-        Mockito.when(hostVO.getHypervisorVersion()).thenReturn(hypervisorVersion);
-
-        Exception e = null;
-        try {
-            vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
-        } catch (CloudRuntimeException e1) {
-            e = e1;
-        }
-
-        assertNotNull(e);
-
-        DeleteVMSnapshotAnswer answer = Mockito.mock(DeleteVMSnapshotAnswer.class);
-        Mockito.when(answer.getResult()).thenReturn(true);
-        Mockito.when(agentMgr.send(Matchers.anyLong(), Matchers.any(Command.class))).thenReturn(answer);
-
-        boolean result = vmSnapshotStrategy.deleteVMSnapshot(vmSnapshot);
-        assertTrue(result);
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {NetUtils.class, DefaultVMSnapshotStrategy.class},
-                   includeFilters = {@ComponentScan.Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
-                   useDefaultFilters = false)
-    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        public static class Library implements TypeFilter {
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                mdr.getClassMetadata().getClassName();
-                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-
-        @Bean
-        public VMSnapshotHelper vmSnapshotHelper() {
-            return Mockito.mock(VMSnapshotHelper.class);
-        }
-
-        @Bean
-        public GuestOSDao guestOSDao() {
-            return Mockito.mock(GuestOSDao.class);
-        }
-
-        @Bean
-        public GuestOSHypervisorDao guestOsHypervisorDao() {
-            return Mockito.mock(GuestOSHypervisorDao.class);
-        }
-
-        @Bean
-        public UserVmDao userVmDao() {
-            return Mockito.mock(UserVmDao.class);
-        }
-
-        @Bean
-        public VMSnapshotDao vmSnapshotDao() {
-            return Mockito.mock(VMSnapshotDao.class);
-        }
-
-        @Bean
-        public ConfigurationDao configurationDao() {
-            return Mockito.mock(ConfigurationDao.class);
-        }
-
-        @Bean
-        public AgentManager agentManager() {
-            return Mockito.mock(AgentManager.class);
-        }
-
-        @Bean
-        public VolumeDao volumeDao() {
-            return Mockito.mock(VolumeDao.class);
-        }
-
-        @Bean
-        public DiskOfferingDao diskOfferingDao() {
-            return Mockito.mock(DiskOfferingDao.class);
-        }
-
-        @Bean
-        public HostDao hostDao() {
-            return Mockito.mock(HostDao.class);
-        }
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/BaseType.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/BaseType.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/BaseType.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/BaseType.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/LocalHostEndpoint.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/LocalHostEndpoint.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/RemoteHostEndPoint.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/RemoteHostEndPoint.java
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
new file mode 100644
index 0000000..ef5e21d
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
@@ -0,0 +1,242 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.allocator;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StorageUtil;
+import com.cloud.storage.Volume;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator {
+    private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class);
+
+    protected BigDecimal storageOverprovisioningFactor = new BigDecimal(1);
+    protected String allocationAlgorithm = "random";
+    protected long extraBytesPerVolume = 0;
+    @Inject protected DataStoreManager dataStoreMgr;
+    @Inject protected PrimaryDataStoreDao storagePoolDao;
+    @Inject protected VolumeDao volumeDao;
+    @Inject protected ConfigurationDao configDao;
+    @Inject private CapacityDao capacityDao;
+    @Inject private ClusterDao clusterDao;
+    @Inject private StorageManager storageMgr;
+    @Inject private StorageUtil storageUtil;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        if(configDao != null) {
+            Map<String, String> configs = configDao.getConfiguration(null, params);
+            String globalStorageOverprovisioningFactor = configs.get("storage.overprovisioning.factor");
+            storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, 2.0f));
+            extraBytesPerVolume = 0;
+            String allocationAlgorithm = configs.get("vm.allocation.algorithm");
+            if (allocationAlgorithm != null) {
+                this.allocationAlgorithm = allocationAlgorithm;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    protected abstract List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
+
+    @Override
+    public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+        List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo);
+        return reOrder(pools, vmProfile, plan);
+    }
+
+    protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan,
+        List<StoragePool> pools) {
+        Long clusterId = plan.getClusterId();
+        short capacityType;
+        if(pools != null && pools.size() != 0){
+            capacityType = pools.get(0).getPoolType().isShared() ? Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED : Capacity.CAPACITY_TYPE_LOCAL_STORAGE;
+        } else{
+            return null;
+        }
+
+        List<Long> poolIdsByCapacity = capacityDao.orderHostsByFreeCapacity(clusterId, capacityType);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("List of pools in descending order of free capacity: "+ poolIdsByCapacity);
+        }
+
+      //now filter the given list of Pools by this ordered list
+      Map<Long, StoragePool> poolMap = new HashMap<>();
+      for (StoragePool pool : pools) {
+          poolMap.put(pool.getId(), pool);
+      }
+      List<Long> matchingPoolIds = new ArrayList<>(poolMap.keySet());
+
+      poolIdsByCapacity.retainAll(matchingPoolIds);
+
+      List<StoragePool> reorderedPools = new ArrayList<>();
+      for(Long id: poolIdsByCapacity){
+          reorderedPools.add(poolMap.get(id));
+      }
+
+      return reorderedPools;
+    }
+
+    protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, Account account) {
+        if (account == null) {
+            return pools;
+        }
+        long dcId = plan.getDataCenterId();
+        Long podId = plan.getPodId();
+        Long clusterId = plan.getClusterId();
+
+        List<Long> poolIdsByVolCount = volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, account.getAccountId());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("List of pools in ascending order of number of volumes for account id: " + account.getAccountId() + " is: " + poolIdsByVolCount);
+        }
+
+        // now filter the given list of Pools by this ordered list
+        Map<Long, StoragePool> poolMap = new HashMap<>();
+        for (StoragePool pool : pools) {
+            poolMap.put(pool.getId(), pool);
+        }
+        List<Long> matchingPoolIds = new ArrayList<>(poolMap.keySet());
+
+        poolIdsByVolCount.retainAll(matchingPoolIds);
+
+        List<StoragePool> reorderedPools = new ArrayList<>();
+        for (Long id : poolIdsByVolCount) {
+            reorderedPools.add(poolMap.get(id));
+        }
+
+        return reorderedPools;
+    }
+
+    protected List<StoragePool> reOrder(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) {
+        if (pools == null) {
+            return null;
+        }
+        Account account = null;
+        if (vmProfile.getVirtualMachine() != null) {
+            account = vmProfile.getOwner();
+        }
+
+        if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
+            // Shuffle this so that we don't check the pools in the same order.
+            Collections.shuffle(pools);
+        } else if (allocationAlgorithm.equals("userdispersing")) {
+            pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
+        } else if(allocationAlgorithm.equals("firstfitleastconsumed")){
+            pools = reorderPoolsByCapacity(plan, pools);
+        }
+        return pools;
+    }
+
+    protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, DeploymentPlan plan) {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName() + " ,poolId: " + pool.getId());
+        }
+        if (avoid.shouldAvoid(pool)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("StoragePool is in avoid set, skipping this pool");
+            }
+            return false;
+        }
+
+        Long clusterId = pool.getClusterId();
+        if (clusterId != null) {
+            ClusterVO cluster = clusterDao.findById(clusterId);
+            if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool");
+                }
+                return false;
+            }
+        } else if (pool.getHypervisor() != null && !pool.getHypervisor().equals(HypervisorType.Any) && !(pool.getHypervisor() == dskCh.getHypervisorType())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("StoragePool does not have required hypervisorType, skipping this pool");
+            }
+            return false;
+        }
+
+        if(!checkHypervisorCompatibility(dskCh.getHypervisorType(), dskCh.getType(), pool.getPoolType())){
+            return false;
+        }
+
+        if (pool.isManaged() && !storageUtil.managedStoragePoolCanScale(pool, plan.getClusterId(), plan.getHostId())) {
+            return false;
+        }
+
+        // check capacity
+        Volume volume = volumeDao.findById(dskCh.getVolumeId());
+        List<Volume> requestVolumes = new ArrayList<>();
+        requestVolumes.add(volume);
+        return storageMgr.storagePoolHasEnoughIops(requestVolumes, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool, plan.getClusterId());
+    }
+
+    /*
+    Check StoragePool and Volume type compatibility for the hypervisor
+     */
+    private boolean checkHypervisorCompatibility(HypervisorType hyperType, Volume.Type volType, Storage.StoragePoolType poolType){
+        if(HypervisorType.LXC.equals(hyperType)){
+            if(Volume.Type.ROOT.equals(volType)){
+                //LXC ROOT disks supports NFS and local storage pools only
+                if(!(Storage.StoragePoolType.NetworkFilesystem.equals(poolType) ||
+                        Storage.StoragePoolType.Filesystem.equals(poolType)) ){
+                    s_logger.debug("StoragePool does not support LXC ROOT disk, skipping this pool");
+                    return false;
+                }
+            } else if (Volume.Type.DATADISK.equals(volType)){
+                //LXC DATA disks supports RBD storage pool only
+                if(!Storage.StoragePoolType.RBD.equals(poolType)){
+                    s_logger.debug("StoragePool does not support LXC DATA disk, skipping this pool");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
new file mode 100644
index 0000000..12884d5
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.allocator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Component
+public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocator {
+    private static final Logger s_logger = Logger.getLogger(ClusterScopeStoragePoolAllocator.class);
+
+    @Inject
+    DiskOfferingDao _diskOfferingDao;
+
+    @Override
+    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+        s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool");
+
+        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
+
+        long dcId = plan.getDataCenterId();
+        Long podId = plan.getPodId();
+        Long clusterId = plan.getClusterId();
+
+        if (podId == null) {
+            // for zone wide storage, podId should be null. We cannot check
+            // clusterId == null here because it will break ClusterWide primary
+            // storage volume operation where
+            // only podId is passed into this call.
+            return null;
+        }
+        if (dskCh.getTags() != null && dskCh.getTags().length != 0) {
+            s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + " having tags:" + Arrays.toString(dskCh.getTags()) +
+                    ". Disabled pools will be ignored.");
+        } else {
+            s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + ". Disabled pools will be ignored.");
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            // Log the pools details that are ignored because they are in disabled state
+            List<StoragePoolVO> disabledPools = storagePoolDao.findDisabledPoolsByScope(dcId, podId, clusterId, ScopeType.CLUSTER);
+            if (disabledPools != null && !disabledPools.isEmpty()) {
+                for (StoragePoolVO pool : disabledPools) {
+                    s_logger.trace("Ignoring pool " + pool + " as it is in disabled state.");
+                }
+            }
+        }
+
+        List<StoragePoolVO> pools = storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags());
+        s_logger.debug("Found pools matching tags: " + pools);
+
+        // add remaining pools in cluster, that did not match tags, to avoid set
+        List<StoragePoolVO> allPools = storagePoolDao.findPoolsByTags(dcId, podId, clusterId, null);
+        allPools.removeAll(pools);
+        for (StoragePoolVO pool : allPools) {
+            s_logger.debug("Adding pool " + pool + " to avoid set since it did not match tags");
+            avoid.addPool(pool.getId());
+        }
+
+        if (pools.size() == 0) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("No storage pools available for " + ServiceOffering.StorageType.shared.toString() + " volume allocation, returning");
+            }
+            return suitablePools;
+        }
+
+        for (StoragePoolVO pool : pools) {
+            if (suitablePools.size() == returnUpTo) {
+                break;
+            }
+            StoragePool storagePool = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
+            if (filter(avoid, storagePool, dskCh, plan)) {
+                suitablePools.add(storagePool);
+            } else {
+                avoid.addPool(pool.getId());
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("ClusterScopeStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
+        }
+
+        return suitablePools;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        if (configDao != null) {
+            Map<String, String> configs = configDao.getConfiguration(params);
+            String allocationAlgorithm = configs.get("vm.allocation.algorithm");
+            if (allocationAlgorithm != null) {
+                this.allocationAlgorithm = allocationAlgorithm;
+            }
+        }
+        return true;
+    }
+}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
new file mode 100644
index 0000000..390272e
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
@@ -0,0 +1,147 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.allocator;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
+    private static final Logger s_logger = Logger.getLogger(LocalStoragePoolAllocator.class);
+
+    @Inject
+    StoragePoolHostDao _poolHostDao;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    UserVmDao _vmDao;
+    @Inject
+    ServiceOfferingDao _offeringDao;
+    @Inject
+    CapacityDao _capacityDao;
+    @Inject
+    ConfigurationDao _configDao;
+
+    @Override
+    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+        s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm");
+
+        if (!dskCh.useLocalStorage()) {
+            return null;
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            // Log the pools details that are ignored because they are in disabled state
+            List<StoragePoolVO> disabledPools = storagePoolDao.findDisabledPoolsByScope(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), ScopeType.HOST);
+            if (disabledPools != null && !disabledPools.isEmpty()) {
+                for (StoragePoolVO pool : disabledPools) {
+                    s_logger.trace("Ignoring pool " + pool + " as it is in disabled state.");
+                }
+            }
+        }
+
+        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
+
+        // data disk and host identified from deploying vm (attach volume case)
+        if (plan.getHostId() != null) {
+            List<StoragePoolVO> hostTagsPools = storagePoolDao.findLocalStoragePoolsByHostAndTags(plan.getHostId(), dskCh.getTags());
+            for (StoragePoolVO pool : hostTagsPools) {
+                if (pool != null && pool.isLocal()) {
+                    StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+                    if (filter(avoid, storagePool, dskCh, plan)) {
+                        s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
+                        suitablePools.add(storagePool);
+                    } else {
+                        avoid.addPool(pool.getId());
+                    }
+                }
+
+                if (suitablePools.size() == returnUpTo) {
+                    break;
+                }
+            }
+        } else {
+            if (plan.getPodId() == null) {
+                // zone wide primary storage deployment
+                return null;
+            }
+            List<StoragePoolVO> availablePools =
+                storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags());
+            for (StoragePoolVO pool : availablePools) {
+                if (suitablePools.size() == returnUpTo) {
+                    break;
+                }
+                StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+                if (filter(avoid, storagePool, dskCh, plan)) {
+                    suitablePools.add(storagePool);
+                } else {
+                    avoid.addPool(pool.getId());
+                }
+            }
+
+            // add remaining pools in cluster, that did not match tags, to avoid
+            // set
+            List<StoragePoolVO> allPools = storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), null);
+            allPools.removeAll(availablePools);
+            for (StoragePoolVO pool : allPools) {
+                avoid.addPool(pool.getId());
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("LocalStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
+        }
+
+        return suitablePools;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        storageOverprovisioningFactor = new BigDecimal(1);
+        extraBytesPerVolume = NumbersUtil.parseLong((String)params.get("extra.bytes.per.volume"), 50 * 1024L * 1024L);
+
+        return true;
+    }
+
+    public LocalStoragePoolAllocator() {
+    }
+}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
new file mode 100644
index 0000000..aa077f3
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
@@ -0,0 +1,141 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.allocator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.user.Account;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Component
+public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
+    private static final Logger LOGGER = Logger.getLogger(ZoneWideStoragePoolAllocator.class);
+    @Inject
+    private DataStoreManager dataStoreMgr;
+
+
+    @Override
+    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+        LOGGER.debug("ZoneWideStoragePoolAllocator to find storage pool");
+
+        if (dskCh.useLocalStorage()) {
+            return null;
+        }
+
+        if (LOGGER.isTraceEnabled()) {
+            // Log the pools details that are ignored because they are in disabled state
+            List<StoragePoolVO> disabledPools = storagePoolDao.findDisabledPoolsByScope(plan.getDataCenterId(), null, null, ScopeType.ZONE);
+            if (disabledPools != null && !disabledPools.isEmpty()) {
+                for (StoragePoolVO pool : disabledPools) {
+                    LOGGER.trace("Ignoring pool " + pool + " as it is in disabled state.");
+                }
+            }
+        }
+
+        List<StoragePool> suitablePools = new ArrayList<>();
+
+        List<StoragePoolVO> storagePools = storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
+        if (storagePools == null) {
+            storagePools = new ArrayList<>();
+        }
+
+        List<StoragePoolVO> anyHypervisorStoragePools = new ArrayList<>();
+        for (StoragePoolVO storagePool : storagePools) {
+            if (HypervisorType.Any.equals(storagePool.getHypervisor())) {
+                anyHypervisorStoragePools.add(storagePool);
+            }
+        }
+
+        List<StoragePoolVO> storagePoolsByHypervisor = storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType());
+        storagePools.retainAll(storagePoolsByHypervisor);
+        storagePools.addAll(anyHypervisorStoragePools);
+
+        // add remaining pools in zone, that did not match tags, to avoid set
+        List<StoragePoolVO> allPools = storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), null);
+        allPools.removeAll(storagePools);
+        for (StoragePoolVO pool : allPools) {
+            avoid.addPool(pool.getId());
+        }
+
+
+        for (StoragePoolVO storage : storagePools) {
+            if (suitablePools.size() == returnUpTo) {
+                break;
+            }
+            StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
+            if (filter(avoid, storagePool, dskCh, plan)) {
+                suitablePools.add(storagePool);
+            } else {
+                if (canAddStoragePoolToAvoidSet(storage)) {
+                    avoid.addPool(storagePool.getId());
+                }
+            }
+        }
+        return suitablePools;
+    }
+
+    // Don't add zone-wide, managed storage to the avoid list because it may be usable for another cluster.
+    private boolean canAddStoragePoolToAvoidSet(StoragePoolVO storagePoolVO) {
+        return !ScopeType.ZONE.equals(storagePoolVO.getScope()) || !storagePoolVO.isManaged();
+    }
+
+    @Override
+    protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, Account account) {
+        if (account == null) {
+            return pools;
+        }
+        long dcId = plan.getDataCenterId();
+
+        List<Long> poolIdsByVolCount = volumeDao.listZoneWidePoolIdsByVolumeCount(dcId, account.getAccountId());
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("List of pools in ascending order of number of volumes for account id: " + account.getAccountId() + " is: " + poolIdsByVolCount);
+        }
+
+        // now filter the given list of Pools by this ordered list
+        Map<Long, StoragePool> poolMap = new HashMap<>();
+        for (StoragePool pool : pools) {
+            poolMap.put(pool.getId(), pool);
+        }
+        List<Long> matchingPoolIds = new ArrayList<>(poolMap.keySet());
+
+        poolIdsByVolCount.retainAll(matchingPoolIds);
+
+        List<StoragePool> reorderedPools = new ArrayList<>();
+        for (Long id : poolIdsByVolCount) {
+            reorderedPools.add(poolMap.get(id));
+        }
+
+        return reorderedPools;
+    }
+}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManager.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManager.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/helper/HypervisorHelper.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelper.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/helper/HypervisorHelper.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/helper/HypervisorHelperImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/helper/StorageStrategyFactoryImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/helper/VMSnapshotHelperImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/helper/VMSnapshotHelperImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/helper/VMSnapshotHelperImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/helper/VMSnapshotHelperImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/NfsImageStoreDriverImpl.java
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
new file mode 100644
index 0000000..b027c42
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.image;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.template.VirtualMachineTemplate;
+
+public class TemplateEntityImpl implements TemplateEntity {
+    protected TemplateInfo templateInfo;
+
+    @Override
+    public State getState() {
+        return templateInfo.getState();
+    }
+
+    public TemplateEntityImpl(TemplateInfo templateInfo) {
+        this.templateInfo = templateInfo;
+    }
+
+    public ImageStoreInfo getImageDataStore() {
+        return (ImageStoreInfo)templateInfo.getDataStore();
+    }
+
+    public long getImageDataStoreId() {
+        return getImageDataStore().getImageStoreId();
+    }
+
+    public TemplateInfo getTemplateInfo() {
+        return templateInfo;
+    }
+
+    @Override
+    public String getUuid() {
+        return templateInfo.getUuid();
+    }
+
+    @Override
+    public long getId() {
+        return templateInfo.getId();
+    }
+
+    public String getExternalId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getCurrentState() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getDesiredState() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getCreatedTime() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getLastUpdatedTime() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getOwner() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getDetails() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isDynamicallyScalable() {
+        return false;
+    }
+
+    @Override
+    public void addDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void delDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public List<Method> getApplicableActions() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isFeatured() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isPublicTemplate() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isExtractable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ImageFormat getFormat() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isRequiresHvm() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getDisplayText() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isEnablePassword() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isEnableSshKey() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isCrossZones() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Date getCreated() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long getGuestOSId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean isBootable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public TemplateType getTemplateType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getBits() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getUniqueName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getUrl() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getChecksum() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Long getSourceTemplateId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getTemplateTag() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long getAccountId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getDomainId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getPhysicalSize() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getVirtualSize() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return VirtualMachineTemplate.class;
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Date getUpdated() {
+        return null;
+    }
+
+    @Override
+    public Long getParentTemplateId() {
+        return null;
+    }
+}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
new file mode 100644
index 0000000..6ca6b23
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
@@ -0,0 +1,466 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.image.db;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
+
+@Component
+public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO, Long> implements SnapshotDataStoreDao {
+    private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
+    private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
+    private SearchBuilder<SnapshotDataStoreVO> storeSearch;
+    private SearchBuilder<SnapshotDataStoreVO> destroyedSearch;
+    private SearchBuilder<SnapshotDataStoreVO> cacheSearch;
+    private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
+    private SearchBuilder<SnapshotDataStoreVO> storeSnapshotSearch;
+    private SearchBuilder<SnapshotDataStoreVO> snapshotIdSearch;
+    private SearchBuilder<SnapshotDataStoreVO> volumeIdSearch;
+    private SearchBuilder<SnapshotDataStoreVO> volumeSearch;
+    private SearchBuilder<SnapshotDataStoreVO> stateSearch;
+    private SearchBuilder<SnapshotDataStoreVO> parentSnapshotSearch;
+    private SearchBuilder<SnapshotVO> snapshotVOSearch;
+
+    public static ArrayList<Hypervisor.HypervisorType> hypervisorsSupportingSnapshotsChaining = new ArrayList<Hypervisor.HypervisorType>();
+
+    @Inject
+    private SnapshotDao _snapshotDao;
+
+    private final String findLatestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " +
+            " store_role = ? and volume_id = ? and state = 'Ready'" +
+            " order by created DESC " +
+            " limit 1";
+    private final String findOldestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " +
+            " store_role = ? and volume_id = ? and state = 'Ready'" +
+            " order by created ASC " +
+            " limit 1";
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        // Note that snapshot_store_ref stores snapshots on primary as well as
+        // those on secondary, so we need to
+        // use (store_id, store_role) to search
+        storeSearch = createSearchBuilder();
+        storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ);
+        storeSearch.done();
+
+        destroyedSearch = createSearchBuilder();
+        destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ);
+        destroyedSearch.done();
+
+        cacheSearch = createSearchBuilder();
+        cacheSearch.and("store_id", cacheSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        cacheSearch.and("store_role", cacheSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        cacheSearch.and("state", cacheSearch.entity().getState(), SearchCriteria.Op.NEQ);
+        cacheSearch.and("ref_cnt", cacheSearch.entity().getRefCnt(), SearchCriteria.Op.NEQ);
+        cacheSearch.done();
+
+        updateStateSearch = this.createSearchBuilder();
+        updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
+        updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
+        updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
+        updateStateSearch.done();
+
+        snapshotSearch = createSearchBuilder();
+        snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
+        snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        snapshotSearch.and("state", snapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
+        snapshotSearch.done();
+
+        storeSnapshotSearch = createSearchBuilder();
+        storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
+        storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        storeSnapshotSearch.and("state", storeSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
+        storeSnapshotSearch.done();
+
+        snapshotIdSearch = createSearchBuilder();
+        snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
+        snapshotIdSearch.done();
+
+        volumeIdSearch = createSearchBuilder();
+        volumeIdSearch.and("volume_id", volumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        volumeIdSearch.done();
+
+        volumeSearch = createSearchBuilder();
+        volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        volumeSearch.and("store_role", volumeSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        volumeSearch.done();
+
+        stateSearch = createSearchBuilder();
+        stateSearch.and("state", stateSearch.entity().getState(), SearchCriteria.Op.IN);
+        stateSearch.done();
+
+        parentSnapshotSearch = createSearchBuilder();
+        parentSnapshotSearch.and("volume_id", parentSnapshotSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        parentSnapshotSearch.and("store_id", parentSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        parentSnapshotSearch.and("store_role", parentSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
+        parentSnapshotSearch.and("state", parentSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
+        parentSnapshotSearch.done();
+
+        snapshotVOSearch = _snapshotDao.createSearchBuilder();
+        snapshotVOSearch.and("volume_id", snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        snapshotVOSearch.done();
+
+        return true;
+    }
+
+    @Override
+    public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) {
+        SnapshotDataStoreVO dataObj = (SnapshotDataStoreVO)vo;
+        Long oldUpdated = dataObj.getUpdatedCount();
+        Date oldUpdatedTime = dataObj.getUpdated();
+
+        SearchCriteria<SnapshotDataStoreVO> sc = updateStateSearch.create();
+        sc.setParameters("id", dataObj.getId());
+        sc.setParameters("state", currentState);
+        sc.setParameters("updatedCount", dataObj.getUpdatedCount());
+
+        dataObj.incrUpdatedCount();
+
+        UpdateBuilder builder = getUpdateBuilder(dataObj);
+        builder.set(dataObj, "state", nextState);
+        builder.set(dataObj, "updated", new Date());
+
+        int rows = update(dataObj, sc);
+        if (rows == 0 && s_logger.isDebugEnabled()) {
+            SnapshotDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId());
+            if (dbVol != null) {
+                StringBuilder str = new StringBuilder("Unable to update ").append(dataObj.toString());
+                str.append(": DB Data={id=")
+                .append(dbVol.getId())
+                .append("; state=")
+                .append(dbVol.getState())
+                .append("; updatecount=")
+                .append(dbVol.getUpdatedCount())
+                .append(";updatedTime=")
+                .append(dbVol.getUpdated());
+                str.append(": New Data={id=")
+                .append(dataObj.getId())
+                .append("; state=")
+                .append(nextState)
+                .append("; event=")
+                .append(event)
+                .append("; updatecount=")
+                .append(dataObj.getUpdatedCount())
+                .append("; updatedTime=")
+                .append(dataObj.getUpdated());
+                str.append(": stale Data={id=")
+                .append(dataObj.getId())
+                .append("; state=")
+                .append(currentState)
+                .append("; event=")
+                .append(event)
+                .append("; updatecount=")
+                .append(oldUpdated)
+                .append("; updatedTime=")
+                .append(oldUpdatedTime);
+            } else {
+                s_logger.debug("Unable to update objectIndatastore: id=" + dataObj.getId() + ", as there is no such object exists in the database anymore");
+            }
+        }
+        return rows > 0;
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
+        sc.setParameters("store_id", id);
+        sc.setParameters("store_role", role);
+        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
+        return listBy(sc);
+    }
+
+    @Override
+    public void deletePrimaryRecordsForStore(long id, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
+        sc.setParameters("store_id", id);
+        sc.setParameters("store_role", role);
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        remove(sc);
+        txn.commit();
+    }
+
+    @Override
+    public void deleteSnapshotRecordsOnPrimary() {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
+        sc.setParameters("store_role", DataStoreRole.Primary);
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        remove(sc);
+        txn.commit();
+    }
+
+    @Override
+    public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("snapshot_id", snapshotId);
+        sc.setParameters("store_role", role);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try (
+                PreparedStatement pstmt = txn.prepareStatement(findLatestSnapshot);
+                ){
+            pstmt.setString(1, role.toString());
+            pstmt.setLong(2, volumeId);
+            try (ResultSet rs = pstmt.executeQuery();) {
+                while (rs.next()) {
+                    long sid = rs.getLong(1);
+                    long snid = rs.getLong(3);
+                    return findByStoreSnapshot(role, sid, snid);
+                }
+            }
+        } catch (SQLException e) {
+            s_logger.debug("Failed to find latest snapshot for volume: " + volumeId + " due to: "  + e.toString());
+        }
+        return null;
+    }
+
+    @Override
+    public SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try (
+                PreparedStatement pstmt = txn.prepareStatement(findOldestSnapshot);
+                ){
+            pstmt.setString(1, role.toString());
+            pstmt.setLong(2, volumeId);
+            try (ResultSet rs = pstmt.executeQuery();) {
+                while (rs.next()) {
+                    long sid = rs.getLong(1);
+                    long snid = rs.getLong(3);
+                    return findByStoreSnapshot(role, sid, snid);
+                }
+            }
+        } catch (SQLException e) {
+            s_logger.debug("Failed to find oldest snapshot for volume: " + volumeId + " due to: "  + e.toString());
+        }
+        return null;
+    }
+
+    @Override
+    @DB
+    public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
+        if(isSnapshotChainingRequired(volumeId)) {
+            SearchCriteria<SnapshotDataStoreVO> sc = parentSnapshotSearch.create();
+            sc.setParameters("volume_id", volumeId);
+            sc.setParameters("store_role", role.toString());
+            sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready.name());
+            sc.setParameters("store_id", storeId);
+
+            List<SnapshotDataStoreVO> snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, "created", false, null, null));
+            if (snapshotList != null && snapshotList.size() != 0) {
+                return snapshotList.get(0);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = snapshotSearch.create();
+        sc.setParameters("snapshot_id", snapshotId);
+        sc.setParameters("store_role", role);
+        sc.setParameters("state", State.Ready);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listAllByVolumeAndDataStore(long volumeId, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("store_role", role);
+        return listBy(sc);
+    }
+
+    @Override
+    public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) {
+        SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();
+        sc.setParameters("volume_id", volumeId);
+        sc.setParameters("store_role", role);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = snapshotIdSearch.create();
+        sc.setParameters("snapshot_id", snapshotId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listDestroyed(long id) {
+        SearchCriteria<SnapshotDataStoreVO> sc = destroyedSearch.create();
+        sc.setParameters("store_id", id);
+        sc.setParameters("store_role", DataStoreRole.Image);
+        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listActiveOnCache(long id) {
+        SearchCriteria<SnapshotDataStoreVO> sc = cacheSearch.create();
+        sc.setParameters("store_id", id);
+        sc.setParameters("store_role", DataStoreRole.ImageCache);
+        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
+        sc.setParameters("ref_cnt", 0);
+        return listBy(sc);
+    }
+
+    @Override
+    public void duplicateCacheRecordsOnRegionStore(long storeId) {
+        // find all records on image cache
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
+        sc.setParameters("store_role", DataStoreRole.ImageCache);
+        sc.setParameters("destroyed", false);
+        List<SnapshotDataStoreVO> snapshots = listBy(sc);
+        // create an entry for each record, but with empty install path since the content is not yet on region-wide store yet
+        if (snapshots != null) {
+            s_logger.info("Duplicate " + snapshots.size() + " snapshot cache store records to region store");
+            for (SnapshotDataStoreVO snap : snapshots) {
+                SnapshotDataStoreVO snapStore = findByStoreSnapshot(DataStoreRole.Image, storeId, snap.getSnapshotId());
+                if (snapStore != null) {
+                    s_logger.info("There is already entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId);
+                    continue;
+                }
+                s_logger.info("Persisting an entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId);
+                SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
+                ss.setSnapshotId(snap.getSnapshotId());
+                ss.setDataStoreId(storeId);
+                ss.setRole(DataStoreRole.Image);
+                ss.setVolumeId(snap.getVolumeId());
+                ss.setParentSnapshotId(snap.getParentSnapshotId());
+                ss.setState(snap.getState());
+                ss.setSize(snap.getSize());
+                ss.setPhysicalSize(snap.getPhysicalSize());
+                ss.setRefCnt(snap.getRefCnt());
+                persist(ss);
+                // increase ref_cnt so that this will not be recycled before the content is pushed to region-wide store
+                snap.incrRefCnt();
+                update(snap.getId(), snap);
+            }
+        }
+
+    }
+
+    @Override
+    public SnapshotDataStoreVO findReadyOnCache(long snapshotId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
+        sc.setParameters("snapshot_id", snapshotId);
+        sc.setParameters("store_role", DataStoreRole.ImageCache);
+        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listOnCache(long snapshotId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
+        sc.setParameters("snapshot_id", snapshotId);
+        sc.setParameters("store_role", DataStoreRole.ImageCache);
+        return search(sc, null);
+    }
+
+    @Override
+    public void updateStoreRoleToCache(long storeId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("destroyed", false);
+        List<SnapshotDataStoreVO> snaps = listBy(sc);
+        if (snaps != null) {
+            s_logger.info("Update to cache store role for " + snaps.size() + " entries in snapshot_store_ref");
+            for (SnapshotDataStoreVO snap : snaps) {
+                snap.setRole(DataStoreRole.ImageCache);
+                update(snap.getId(), snap);
+            }
+        }
+    }
+
+    @Override
+    public void updateVolumeIds(long oldVolId, long newVolId) {
+        SearchCriteria<SnapshotDataStoreVO> sc = volumeIdSearch.create();
+        sc.setParameters("volume_id", oldVolId);
+        SnapshotDataStoreVO snapshot = createForUpdate();
+        snapshot.setVolumeId(newVolId);
+        UpdateBuilder ub = getUpdateBuilder(snapshot);
+        update(ub, sc, null);
+    }
+
+    @Override
+    public List<SnapshotDataStoreVO> listByState(ObjectInDataStoreStateMachine.State... states) {
+        SearchCriteria<SnapshotDataStoreVO> sc = stateSearch.create();
+        sc.setParameters("state", (Object[])states);
+        return listBy(sc, null);
+    }
+
+    private boolean isSnapshotChainingRequired(long volumeId) {
+
+        hypervisorsSupportingSnapshotsChaining.add(Hypervisor.HypervisorType.XenServer);
+
+        SearchCriteria<SnapshotVO> sc = snapshotVOSearch.create();
+        sc.setParameters("volume_id", volumeId);
+
+        SnapshotVO volSnapshot = _snapshotDao.findOneBy(sc);
+
+        if (volSnapshot != null && hypervisorsSupportingSnapshotsChaining.contains(volSnapshot.getHypervisorType())) {
+            return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/BAREMETAL.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/BAREMETAL.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/BAREMETAL.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/BAREMETAL.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/ISO.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ISO.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/ISO.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ISO.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/ImageFormat.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ImageFormat.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/ImageFormat.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ImageFormat.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/ImageFormatHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ImageFormatHelper.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/ImageFormatHelper.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/ImageFormatHelper.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/OVA.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/OVA.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/OVA.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/OVA.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/QCOW2.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/QCOW2.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/QCOW2.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/QCOW2.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/RAW.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/RAW.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/Unknown.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/Unknown.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/Unknown.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/Unknown.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/VHD.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/VHD.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/VHD.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/VHD.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/VHDX.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/VHDX.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/format/VHDX.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/format/VHDX.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/image/motion/ImageMotionService.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotHelper.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreInfo.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreInfo.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreInfo.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/volume/TemplateOnPrimaryDataStoreInfo.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/VolumeEvent.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/volume/VolumeEvent.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/volume/VolumeEvent.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java
similarity index 100%
rename from engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java
rename to engine/storage/src/main/java/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java
diff --git a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
similarity index 100%
rename from engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
rename to engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
diff --git a/engine/storage/resources/META-INF/cloudstack/storage-allocator/module.properties b/engine/storage/src/main/resources/META-INF/cloudstack/storage-allocator/module.properties
similarity index 100%
rename from engine/storage/resources/META-INF/cloudstack/storage-allocator/module.properties
rename to engine/storage/src/main/resources/META-INF/cloudstack/storage-allocator/module.properties
diff --git a/engine/storage/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml b/engine/storage/src/main/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml
similarity index 100%
rename from engine/storage/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml
rename to engine/storage/src/main/resources/META-INF/cloudstack/storage-allocator/spring-engine-storage-storage-allocator-context.xml
diff --git a/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java
deleted file mode 100644
index b248758..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/EndPoint.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
deleted file mode 100644
index 194f7bd..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
+++ /dev/null
@@ -1,251 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.allocator;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.storage.Storage;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator {
-    private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class);
-    @Inject
-    StorageManager storageMgr;
-    protected @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    VolumeDao _volumeDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ClusterDao _clusterDao;
-    protected @Inject
-    DataStoreManager dataStoreMgr;
-    protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1);
-    long _extraBytesPerVolume = 0;
-    Random _rand;
-    boolean _dontMatter;
-    protected String _allocationAlgorithm = "random";
-    @Inject
-    DiskOfferingDao _diskOfferingDao;
-    @Inject
-    CapacityDao _capacityDao;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        if(_configDao != null) {
-            Map<String, String> configs = _configDao.getConfiguration(null, params);
-            String globalStorageOverprovisioningFactor = configs.get("storage.overprovisioning.factor");
-            _storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, 2.0f));
-            _extraBytesPerVolume = 0;
-            _rand = new Random(System.currentTimeMillis());
-            _dontMatter = Boolean.parseBoolean(configs.get("storage.overwrite.provisioning"));
-            String allocationAlgorithm = configs.get("vm.allocation.algorithm");
-            if (allocationAlgorithm != null) {
-                _allocationAlgorithm = allocationAlgorithm;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    protected abstract List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
-
-    @Override
-    public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-        List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo);
-        return reOrder(pools, vmProfile, plan);
-    }
-
-    protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan,
-        List<StoragePool> pools) {
-        Long clusterId = plan.getClusterId();
-        short capacityType;
-        if(pools != null && pools.size() != 0){
-            capacityType = pools.get(0).getPoolType().isShared() == true ?
-                    Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED : Capacity.CAPACITY_TYPE_LOCAL_STORAGE;
-        } else{
-            return null;
-        }
-
-        List<Long> poolIdsByCapacity = _capacityDao.orderHostsByFreeCapacity(clusterId, capacityType);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("List of pools in descending order of free capacity: "+ poolIdsByCapacity);
-        }
-
-      //now filter the given list of Pools by this ordered list
-      Map<Long, StoragePool> poolMap = new HashMap<Long, StoragePool>();
-      for (StoragePool pool : pools) {
-          poolMap.put(pool.getId(), pool);
-      }
-      List<Long> matchingPoolIds = new ArrayList<Long>(poolMap.keySet());
-
-      poolIdsByCapacity.retainAll(matchingPoolIds);
-
-      List<StoragePool> reorderedPools = new ArrayList<StoragePool>();
-      for(Long id: poolIdsByCapacity){
-          reorderedPools.add(poolMap.get(id));
-      }
-
-      return reorderedPools;
-    }
-
-    protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, Account account) {
-        if (account == null) {
-            return pools;
-        }
-        long dcId = plan.getDataCenterId();
-        Long podId = plan.getPodId();
-        Long clusterId = plan.getClusterId();
-
-        List<Long> poolIdsByVolCount = _volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, account.getAccountId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("List of pools in ascending order of number of volumes for account id: " + account.getAccountId() + " is: " + poolIdsByVolCount);
-        }
-
-        // now filter the given list of Pools by this ordered list
-        Map<Long, StoragePool> poolMap = new HashMap<Long, StoragePool>();
-        for (StoragePool pool : pools) {
-            poolMap.put(pool.getId(), pool);
-        }
-        List<Long> matchingPoolIds = new ArrayList<Long>(poolMap.keySet());
-
-        poolIdsByVolCount.retainAll(matchingPoolIds);
-
-        List<StoragePool> reorderedPools = new ArrayList<StoragePool>();
-        for (Long id : poolIdsByVolCount) {
-            reorderedPools.add(poolMap.get(id));
-        }
-
-        return reorderedPools;
-    }
-
-    protected List<StoragePool> reOrder(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) {
-        if (pools == null) {
-            return null;
-        }
-        Account account = null;
-        if (vmProfile.getVirtualMachine() != null) {
-            account = vmProfile.getOwner();
-        }
-
-        if (_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
-            // Shuffle this so that we don't check the pools in the same order.
-            Collections.shuffle(pools);
-        } else if (_allocationAlgorithm.equals("userdispersing")) {
-            pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
-        } else if(_allocationAlgorithm.equals("firstfitleastconsumed")){
-            pools = reorderPoolsByCapacity(plan, pools);
-        }
-        return pools;
-    }
-
-    protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, DeploymentPlan plan) {
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName() + " ,poolId: " + pool.getId());
-        }
-        if (avoid.shouldAvoid(pool)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("StoragePool is in avoid set, skipping this pool");
-            }
-            return false;
-        }
-
-        Long clusterId = pool.getClusterId();
-        if (clusterId != null) {
-            ClusterVO cluster = _clusterDao.findById(clusterId);
-            if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool");
-                }
-                return false;
-            }
-        } else if (pool.getHypervisor() != null && !pool.getHypervisor().equals(HypervisorType.Any) && !(pool.getHypervisor() == dskCh.getHypervisorType())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("StoragePool does not have required hypervisorType, skipping this pool");
-            }
-            return false;
-        }
-
-        if(!checkHypervisorCompatibility(dskCh.getHypervisorType(), dskCh.getType(), pool.getPoolType())){
-            return false;
-        }
-
-        // check capacity
-        Volume volume = _volumeDao.findById(dskCh.getVolumeId());
-        List<Volume> requestVolumes = new ArrayList<Volume>();
-        requestVolumes.add(volume);
-        return storageMgr.storagePoolHasEnoughIops(requestVolumes, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool, plan.getClusterId());
-    }
-
-    /*
-    Check StoragePool and Volume type compatibility for the hypervisor
-     */
-    private boolean checkHypervisorCompatibility(HypervisorType hyperType, Volume.Type volType, Storage.StoragePoolType poolType){
-        if(HypervisorType.LXC.equals(hyperType)){
-            if(Volume.Type.ROOT.equals(volType)){
-                //LXC ROOT disks supports NFS and local storage pools only
-                if(!(Storage.StoragePoolType.NetworkFilesystem.equals(poolType) ||
-                        Storage.StoragePoolType.Filesystem.equals(poolType)) ){
-                    s_logger.debug("StoragePool does not support LXC ROOT disk, skipping this pool");
-                    return false;
-                }
-            } else if (Volume.Type.DATADISK.equals(volType)){
-                //LXC DATA disks supports RBD storage pool only
-                if(!Storage.StoragePoolType.RBD.equals(poolType)){
-                    s_logger.debug("StoragePool does not support LXC DATA disk, skipping this pool");
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
deleted file mode 100644
index b040c74..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.allocator;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-@Component
-public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocator {
-    private static final Logger s_logger = Logger.getLogger(ClusterScopeStoragePoolAllocator.class);
-
-    @Inject
-    DiskOfferingDao _diskOfferingDao;
-
-    @Override
-    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-        s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool");
-
-        if (dskCh.useLocalStorage()) {
-            // cluster wide allocator should bail out in case of local disk
-            return null;
-        }
-
-        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        long dcId = plan.getDataCenterId();
-        Long podId = plan.getPodId();
-        Long clusterId = plan.getClusterId();
-
-        if (podId == null) {
-            // for zone wide storage, podId should be null. We cannot check
-            // clusterId == null here because it will break ClusterWide primary
-            // storage volume operation where
-            // only podId is passed into this call.
-            return null;
-        }
-        if (dskCh.getTags() != null && dskCh.getTags().length != 0) {
-            s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + " having tags:" + Arrays.toString(dskCh.getTags()) +
-                    ". Disabled pools will be ignored.");
-        } else {
-            s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId + ". Disabled pools will be ignored.");
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            // Log the pools details that are ignored because they are in disabled state
-            List<StoragePoolVO> disabledPools = _storagePoolDao.findDisabledPoolsByScope(dcId, podId, clusterId, ScopeType.CLUSTER);
-            if (disabledPools != null && !disabledPools.isEmpty()) {
-                for (StoragePoolVO pool : disabledPools) {
-                    s_logger.trace("Ignoring pool " + pool + " as it is in disabled state.");
-                }
-            }
-        }
-
-        List<StoragePoolVO> pools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags());
-        s_logger.debug("Found pools matching tags: " + pools);
-
-        // add remaining pools in cluster, that did not match tags, to avoid set
-        List<StoragePoolVO> allPools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, null);
-        allPools.removeAll(pools);
-        for (StoragePoolVO pool : allPools) {
-            s_logger.debug("Adding pool " + pool + " to avoid set since it did not match tags");
-            avoid.addPool(pool.getId());
-        }
-
-        if (pools.size() == 0) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("No storage pools available for " + ServiceOffering.StorageType.shared.toString() + " volume allocation, returning");
-            }
-            return suitablePools;
-        }
-
-        for (StoragePoolVO pool : pools) {
-            if (suitablePools.size() == returnUpTo) {
-                break;
-            }
-            StoragePool storagePool = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
-            if (filter(avoid, storagePool, dskCh, plan)) {
-                suitablePools.add(storagePool);
-            } else {
-                avoid.addPool(pool.getId());
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("ClusterScopeStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
-        }
-
-        return suitablePools;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        if (_configDao != null) {
-            Map<String, String> configs = _configDao.getConfiguration(params);
-            String allocationAlgorithm = configs.get("vm.allocation.algorithm");
-            if (allocationAlgorithm != null) {
-                _allocationAlgorithm = allocationAlgorithm;
-            }
-        }
-        return true;
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
deleted file mode 100644
index 0949036..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.allocator;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
-    private static final Logger s_logger = Logger.getLogger(LocalStoragePoolAllocator.class);
-
-    @Inject
-    StoragePoolHostDao _poolHostDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    UserVmDao _vmDao;
-    @Inject
-    ServiceOfferingDao _offeringDao;
-    @Inject
-    CapacityDao _capacityDao;
-    @Inject
-    ConfigurationDao _configDao;
-
-    @Override
-    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-        s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm");
-
-        if (!dskCh.useLocalStorage()) {
-            return null;
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            // Log the pools details that are ignored because they are in disabled state
-            List<StoragePoolVO> disabledPools = _storagePoolDao.findDisabledPoolsByScope(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), ScopeType.HOST);
-            if (disabledPools != null && !disabledPools.isEmpty()) {
-                for (StoragePoolVO pool : disabledPools) {
-                    s_logger.trace("Ignoring pool " + pool + " as it is in disabled state.");
-                }
-            }
-        }
-
-        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        // data disk and host identified from deploying vm (attach volume case)
-        if (plan.getHostId() != null) {
-            List<StoragePoolVO> hostTagsPools = _storagePoolDao.findLocalStoragePoolsByHostAndTags(plan.getHostId(), dskCh.getTags());
-            for (StoragePoolVO pool : hostTagsPools) {
-                if (pool != null && pool.isLocal()) {
-                    StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-                    if (filter(avoid, storagePool, dskCh, plan)) {
-                        s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
-                        suitablePools.add(storagePool);
-                    } else {
-                        avoid.addPool(pool.getId());
-                    }
-                }
-
-                if (suitablePools.size() == returnUpTo) {
-                    break;
-                }
-            }
-        } else {
-            if (plan.getPodId() == null) {
-                // zone wide primary storage deployment
-                return null;
-            }
-            List<StoragePoolVO> availablePools =
-                _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags());
-            for (StoragePoolVO pool : availablePools) {
-                if (suitablePools.size() == returnUpTo) {
-                    break;
-                }
-                StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-                if (filter(avoid, storagePool, dskCh, plan)) {
-                    suitablePools.add(storagePool);
-                } else {
-                    avoid.addPool(pool.getId());
-                }
-            }
-
-            // add remaining pools in cluster, that did not match tags, to avoid
-            // set
-            List<StoragePoolVO> allPools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), null);
-            allPools.removeAll(availablePools);
-            for (StoragePoolVO pool : allPools) {
-                avoid.addPool(pool.getId());
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("LocalStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
-        }
-
-        return suitablePools;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        _storageOverprovisioningFactor = new BigDecimal(1);
-        _extraBytesPerVolume = NumbersUtil.parseLong((String)params.get("extra.bytes.per.volume"), 50 * 1024L * 1024L);
-
-        return true;
-    }
-
-    public LocalStoragePoolAllocator() {
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
deleted file mode 100644
index 7a10966..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
+++ /dev/null
@@ -1,137 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.allocator;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePool;
-import com.cloud.user.Account;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-@Component
-public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
-    private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class);
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    DataStoreManager dataStoreMgr;
-
-
-    @Override
-    protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-        s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool");
-
-        if (dskCh.useLocalStorage()) {
-            return null;
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            // Log the pools details that are ignored because they are in disabled state
-            List<StoragePoolVO> disabledPools = _storagePoolDao.findDisabledPoolsByScope(plan.getDataCenterId(), null, null, ScopeType.ZONE);
-            if (disabledPools != null && !disabledPools.isEmpty()) {
-                for (StoragePoolVO pool : disabledPools) {
-                    s_logger.trace("Ignoring pool " + pool + " as it is in disabled state.");
-                }
-            }
-        }
-
-        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        List<StoragePoolVO> storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
-        if (storagePools == null) {
-            storagePools = new ArrayList<StoragePoolVO>();
-        }
-
-        List<StoragePoolVO> anyHypervisorStoragePools = new ArrayList<StoragePoolVO>();
-        for (StoragePoolVO storagePool : storagePools) {
-            if (HypervisorType.Any.equals(storagePool.getHypervisor())) {
-                anyHypervisorStoragePools.add(storagePool);
-            }
-        }
-
-        List<StoragePoolVO> storagePoolsByHypervisor = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType());
-        storagePools.retainAll(storagePoolsByHypervisor);
-        storagePools.addAll(anyHypervisorStoragePools);
-
-        // add remaining pools in zone, that did not match tags, to avoid set
-        List<StoragePoolVO> allPools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), null);
-        allPools.removeAll(storagePools);
-        for (StoragePoolVO pool : allPools) {
-            avoid.addPool(pool.getId());
-        }
-
-
-        for (StoragePoolVO storage : storagePools) {
-            if (suitablePools.size() == returnUpTo) {
-                break;
-            }
-            StoragePool storagePool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
-            if (filter(avoid, storagePool, dskCh, plan)) {
-                suitablePools.add(storagePool);
-            } else {
-                avoid.addPool(storagePool.getId());
-            }
-        }
-        return suitablePools;
-    }
-
-    @Override
-    protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, Account account) {
-        if (account == null) {
-            return pools;
-        }
-        long dcId = plan.getDataCenterId();
-
-        List<Long> poolIdsByVolCount = _volumeDao.listZoneWidePoolIdsByVolumeCount(dcId, account.getAccountId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("List of pools in ascending order of number of volumes for account id: " + account.getAccountId() + " is: " + poolIdsByVolCount);
-        }
-
-        // now filter the given list of Pools by this ordered list
-        Map<Long, StoragePool> poolMap = new HashMap<Long, StoragePool>();
-        for (StoragePool pool : pools) {
-            poolMap.put(pool.getId(), pool);
-        }
-        List<Long> matchingPoolIds = new ArrayList<Long>(poolMap.keySet());
-
-        poolIdsByVolCount.retainAll(matchingPoolIds);
-
-        List<StoragePool> reorderedPools = new ArrayList<StoragePool>();
-        for (Long id : poolIdsByVolCount) {
-            reorderedPools.add(poolMap.get(id));
-        }
-
-        return reorderedPools;
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStore.java
deleted file mode 100644
index b248758..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStore.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java
deleted file mode 100644
index b248758..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/datastore/TemplateInDataStore.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
deleted file mode 100644
index d3c1eff..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.image;
-
-import java.lang.reflect.Method;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.template.VirtualMachineTemplate;
-
-public class TemplateEntityImpl implements TemplateEntity {
-    protected TemplateInfo templateInfo;
-
-    @Override
-    public State getState() {
-        return templateInfo.getState();
-    }
-
-    public TemplateEntityImpl(TemplateInfo templateInfo) {
-        this.templateInfo = templateInfo;
-    }
-
-    public ImageStoreInfo getImageDataStore() {
-        return (ImageStoreInfo)templateInfo.getDataStore();
-    }
-
-    public long getImageDataStoreId() {
-        return getImageDataStore().getImageStoreId();
-    }
-
-    public TemplateInfo getTemplateInfo() {
-        return templateInfo;
-    }
-
-    @Override
-    public String getUuid() {
-        return templateInfo.getUuid();
-    }
-
-    @Override
-    public long getId() {
-        return templateInfo.getId();
-    }
-
-    public String getExternalId() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getCurrentState() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getDesiredState() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Date getCreatedTime() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Date getLastUpdatedTime() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getOwner() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<String, String> getDetails() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isDynamicallyScalable() {
-        return false;
-    }
-
-    @Override
-    public void addDetail(String name, String value) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void delDetail(String name, String value) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void updateDetail(String name, String value) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public List<Method> getApplicableActions() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isFeatured() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isPublicTemplate() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isExtractable() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ImageFormat getFormat() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isRequiresHvm() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public String getDisplayText() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean getEnablePassword() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean getEnableSshKey() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isCrossZones() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Date getCreated() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public long getGuestOSId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean isBootable() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public TemplateType getTemplateType() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public HypervisorType getHypervisorType() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getBits() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public String getUniqueName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getUrl() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getChecksum() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Long getSourceTemplateId() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getTemplateTag() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public long getAccountId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public long getDomainId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public long getPhysicalSize() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public long getVirtualSize() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return VirtualMachineTemplate.class;
-    }
-
-    @Override
-    public long getUpdatedCount() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void incrUpdatedCount() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Date getUpdated() {
-        return null;
-    }
-
-    @Override
-    public Long getParentTemplateId() {
-        return null;
-    }
-}
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
deleted file mode 100644
index c3e48b9..0000000
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java
+++ /dev/null
@@ -1,456 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.image.db;
-
-import com.cloud.storage.DataStoreRole;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UpdateBuilder;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.dao.SnapshotDao;
-import javax.inject.Inject;
-import com.cloud.hypervisor.Hypervisor;
-import java.util.ArrayList;
-import com.cloud.utils.db.Filter;
-import javax.naming.ConfigurationException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-@Component
-public class SnapshotDataStoreDaoImpl extends GenericDaoBase<SnapshotDataStoreVO, Long> implements SnapshotDataStoreDao {
-    private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class);
-    private SearchBuilder<SnapshotDataStoreVO> updateStateSearch;
-    private SearchBuilder<SnapshotDataStoreVO> storeSearch;
-    private SearchBuilder<SnapshotDataStoreVO> destroyedSearch;
-    private SearchBuilder<SnapshotDataStoreVO> cacheSearch;
-    private SearchBuilder<SnapshotDataStoreVO> snapshotSearch;
-    private SearchBuilder<SnapshotDataStoreVO> storeSnapshotSearch;
-    private SearchBuilder<SnapshotDataStoreVO> snapshotIdSearch;
-    private SearchBuilder<SnapshotDataStoreVO> volumeIdSearch;
-    private SearchBuilder<SnapshotDataStoreVO> volumeSearch;
-    private SearchBuilder<SnapshotDataStoreVO> stateSearch;
-    private SearchBuilder<SnapshotDataStoreVO> parentSnapshotSearch;
-    private SearchBuilder<SnapshotVO> snapshotVOSearch;
-
-    public static ArrayList<Hypervisor.HypervisorType> hypervisorsSupportingSnapshotsChaining = new ArrayList<Hypervisor.HypervisorType>();
-
-    @Inject
-    private SnapshotDao _snapshotDao;
-
-    private final String findLatestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " +
-            " store_role = ? and volume_id = ? and state = 'Ready'" +
-            " order by created DESC " +
-            " limit 1";
-    private final String findOldestSnapshot = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where " +
-            " store_role = ? and volume_id = ? and state = 'Ready'" +
-            " order by created ASC " +
-            " limit 1";
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        // Note that snapshot_store_ref stores snapshots on primary as well as
-        // those on secondary, so we need to
-        // use (store_id, store_role) to search
-        storeSearch = createSearchBuilder();
-        storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        storeSearch.and("store_role", storeSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        storeSearch.and("state", storeSearch.entity().getState(), SearchCriteria.Op.NEQ);
-        storeSearch.done();
-
-        destroyedSearch = createSearchBuilder();
-        destroyedSearch.and("store_id", destroyedSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        destroyedSearch.and("store_role", destroyedSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        destroyedSearch.and("state", destroyedSearch.entity().getState(), SearchCriteria.Op.EQ);
-        destroyedSearch.done();
-
-        cacheSearch = createSearchBuilder();
-        cacheSearch.and("store_id", cacheSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        cacheSearch.and("store_role", cacheSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        cacheSearch.and("state", cacheSearch.entity().getState(), SearchCriteria.Op.NEQ);
-        cacheSearch.and("ref_cnt", cacheSearch.entity().getRefCnt(), SearchCriteria.Op.NEQ);
-        cacheSearch.done();
-
-        updateStateSearch = this.createSearchBuilder();
-        updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
-        updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
-        updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
-        updateStateSearch.done();
-
-        snapshotSearch = createSearchBuilder();
-        snapshotSearch.and("snapshot_id", snapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
-        snapshotSearch.and("store_role", snapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        snapshotSearch.and("state", snapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
-        snapshotSearch.done();
-
-        storeSnapshotSearch = createSearchBuilder();
-        storeSnapshotSearch.and("snapshot_id", storeSnapshotSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
-        storeSnapshotSearch.and("store_id", storeSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        storeSnapshotSearch.and("store_role", storeSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        storeSnapshotSearch.and("state", storeSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
-        storeSnapshotSearch.done();
-
-        snapshotIdSearch = createSearchBuilder();
-        snapshotIdSearch.and("snapshot_id", snapshotIdSearch.entity().getSnapshotId(), SearchCriteria.Op.EQ);
-        snapshotIdSearch.done();
-
-        volumeIdSearch = createSearchBuilder();
-        volumeIdSearch.and("volume_id", volumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        volumeIdSearch.done();
-
-        volumeSearch = createSearchBuilder();
-        volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        volumeSearch.and("store_role", volumeSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        volumeSearch.done();
-
-        stateSearch = createSearchBuilder();
-        stateSearch.and("state", stateSearch.entity().getState(), SearchCriteria.Op.IN);
-        stateSearch.done();
-
-        parentSnapshotSearch = createSearchBuilder();
-        parentSnapshotSearch.and("volume_id", parentSnapshotSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        parentSnapshotSearch.and("store_id", parentSnapshotSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        parentSnapshotSearch.and("store_role", parentSnapshotSearch.entity().getRole(), SearchCriteria.Op.EQ);
-        parentSnapshotSearch.and("state", parentSnapshotSearch.entity().getState(), SearchCriteria.Op.EQ);
-        parentSnapshotSearch.done();
-
-        snapshotVOSearch = _snapshotDao.createSearchBuilder();
-        snapshotVOSearch.and("volume_id", snapshotVOSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        snapshotVOSearch.done();
-
-        return true;
-    }
-
-    @Override
-    public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) {
-        SnapshotDataStoreVO dataObj = (SnapshotDataStoreVO)vo;
-        Long oldUpdated = dataObj.getUpdatedCount();
-        Date oldUpdatedTime = dataObj.getUpdated();
-
-        SearchCriteria<SnapshotDataStoreVO> sc = updateStateSearch.create();
-        sc.setParameters("id", dataObj.getId());
-        sc.setParameters("state", currentState);
-        sc.setParameters("updatedCount", dataObj.getUpdatedCount());
-
-        dataObj.incrUpdatedCount();
-
-        UpdateBuilder builder = getUpdateBuilder(dataObj);
-        builder.set(dataObj, "state", nextState);
-        builder.set(dataObj, "updated", new Date());
-
-        int rows = update(dataObj, sc);
-        if (rows == 0 && s_logger.isDebugEnabled()) {
-            SnapshotDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId());
-            if (dbVol != null) {
-                StringBuilder str = new StringBuilder("Unable to update ").append(dataObj.toString());
-                str.append(": DB Data={id=")
-                    .append(dbVol.getId())
-                    .append("; state=")
-                    .append(dbVol.getState())
-                    .append("; updatecount=")
-                    .append(dbVol.getUpdatedCount())
-                    .append(";updatedTime=")
-                    .append(dbVol.getUpdated());
-                str.append(": New Data={id=")
-                    .append(dataObj.getId())
-                    .append("; state=")
-                    .append(nextState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(dataObj.getUpdatedCount())
-                    .append("; updatedTime=")
-                    .append(dataObj.getUpdated());
-                str.append(": stale Data={id=")
-                    .append(dataObj.getId())
-                    .append("; state=")
-                    .append(currentState)
-                    .append("; event=")
-                    .append(event)
-                    .append("; updatecount=")
-                    .append(oldUpdated)
-                    .append("; updatedTime=")
-                    .append(oldUpdatedTime);
-            } else {
-                s_logger.debug("Unable to update objectIndatastore: id=" + dataObj.getId() + ", as there is no such object exists in the database anymore");
-            }
-        }
-        return rows > 0;
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listByStoreId(long id, DataStoreRole role) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
-        sc.setParameters("store_id", id);
-        sc.setParameters("store_role", role);
-        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
-        return listBy(sc);
-    }
-
-    @Override
-    public void deletePrimaryRecordsForStore(long id, DataStoreRole role) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
-        sc.setParameters("store_id", id);
-        sc.setParameters("store_role", role);
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        remove(sc);
-        txn.commit();
-    }
-
-    @Override
-    public void deleteSnapshotRecordsOnPrimary() {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
-        sc.setParameters("store_role", DataStoreRole.Primary);
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        remove(sc);
-        txn.commit();
-    }
-
-    @Override
-    public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
-        sc.setParameters("store_id", storeId);
-        sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("store_role", role);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public SnapshotDataStoreVO findLatestSnapshotForVolume(Long volumeId, DataStoreRole role) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try (
-                PreparedStatement pstmt = txn.prepareStatement(findLatestSnapshot);
-            ){
-            pstmt.setString(1, role.toString());
-            pstmt.setLong(2, volumeId);
-            try (ResultSet rs = pstmt.executeQuery();) {
-                while (rs.next()) {
-                    long sid = rs.getLong(1);
-                    long snid = rs.getLong(3);
-                    return findByStoreSnapshot(role, sid, snid);
-                }
-            }
-        } catch (SQLException e) {
-            s_logger.debug("Failed to find latest snapshot for volume: " + volumeId + " due to: "  + e.toString());
-        }
-        return null;
-    }
-
-    @Override
-    public SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try (
-                PreparedStatement pstmt = txn.prepareStatement(findOldestSnapshot);
-            ){
-            pstmt.setString(1, role.toString());
-            pstmt.setLong(2, volumeId);
-            try (ResultSet rs = pstmt.executeQuery();) {
-                while (rs.next()) {
-                    long sid = rs.getLong(1);
-                    long snid = rs.getLong(3);
-                    return findByStoreSnapshot(role, sid, snid);
-                }
-            }
-        } catch (SQLException e) {
-            s_logger.debug("Failed to find oldest snapshot for volume: " + volumeId + " due to: "  + e.toString());
-        }
-        return null;
-    }
-
-    @Override
-    @DB
-    public SnapshotDataStoreVO findParent(DataStoreRole role, Long storeId, Long volumeId) {
-        if(isSnapshotChainingRequired(volumeId)) {
-            SearchCriteria<SnapshotDataStoreVO> sc = parentSnapshotSearch.create();
-            sc.setParameters("volume_id", volumeId);
-            sc.setParameters("store_role", role.toString());
-            sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready.name());
-            sc.setParameters("store_id", storeId);
-
-            List<SnapshotDataStoreVO> snapshotList = listBy(sc, new Filter(SnapshotDataStoreVO.class, "created", false, null, null));
-            if (snapshotList != null && snapshotList.size() != 0) {
-                return snapshotList.get(0);
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) {
-        SearchCriteria<SnapshotDataStoreVO> sc = snapshotSearch.create();
-        sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("store_role", role);
-        sc.setParameters("state", State.Ready);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role) {
-        SearchCriteria<SnapshotDataStoreVO> sc = volumeSearch.create();
-        sc.setParameters("volume_id", volumeId);
-        sc.setParameters("store_role", role);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> findBySnapshotId(long snapshotId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = snapshotIdSearch.create();
-        sc.setParameters("snapshot_id", snapshotId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listDestroyed(long id) {
-        SearchCriteria<SnapshotDataStoreVO> sc = destroyedSearch.create();
-        sc.setParameters("store_id", id);
-        sc.setParameters("store_role", DataStoreRole.Image);
-        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listActiveOnCache(long id) {
-        SearchCriteria<SnapshotDataStoreVO> sc = cacheSearch.create();
-        sc.setParameters("store_id", id);
-        sc.setParameters("store_role", DataStoreRole.ImageCache);
-        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed);
-        sc.setParameters("ref_cnt", 0);
-        return listBy(sc);
-    }
-
-    @Override
-    public void duplicateCacheRecordsOnRegionStore(long storeId) {
-        // find all records on image cache
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
-        sc.setParameters("store_role", DataStoreRole.ImageCache);
-        sc.setParameters("destroyed", false);
-        List<SnapshotDataStoreVO> snapshots = listBy(sc);
-        // create an entry for each record, but with empty install path since the content is not yet on region-wide store yet
-        if (snapshots != null) {
-            s_logger.info("Duplicate " + snapshots.size() + " snapshot cache store records to region store");
-            for (SnapshotDataStoreVO snap : snapshots) {
-                SnapshotDataStoreVO snapStore = findByStoreSnapshot(DataStoreRole.Image, storeId, snap.getSnapshotId());
-                if (snapStore != null) {
-                    s_logger.info("There is already entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId);
-                    continue;
-                }
-                s_logger.info("Persisting an entry for snapshot " + snap.getSnapshotId() + " on region store " + storeId);
-                SnapshotDataStoreVO ss = new SnapshotDataStoreVO();
-                ss.setSnapshotId(snap.getSnapshotId());
-                ss.setDataStoreId(storeId);
-                ss.setRole(DataStoreRole.Image);
-                ss.setVolumeId(snap.getVolumeId());
-                ss.setParentSnapshotId(snap.getParentSnapshotId());
-                ss.setState(snap.getState());
-                ss.setSize(snap.getSize());
-                ss.setPhysicalSize(snap.getPhysicalSize());
-                ss.setRefCnt(snap.getRefCnt());
-                persist(ss);
-                // increase ref_cnt so that this will not be recycled before the content is pushed to region-wide store
-                snap.incrRefCnt();
-                update(snap.getId(), snap);
-            }
-        }
-
-    }
-
-    @Override
-    public SnapshotDataStoreVO findReadyOnCache(long snapshotId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
-        sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("store_role", DataStoreRole.ImageCache);
-        sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listOnCache(long snapshotId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSnapshotSearch.create();
-        sc.setParameters("snapshot_id", snapshotId);
-        sc.setParameters("store_role", DataStoreRole.ImageCache);
-        return search(sc, null);
-    }
-
-    @Override
-    public void updateStoreRoleToCache(long storeId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = storeSearch.create();
-        sc.setParameters("store_id", storeId);
-        sc.setParameters("destroyed", false);
-        List<SnapshotDataStoreVO> snaps = listBy(sc);
-        if (snaps != null) {
-            s_logger.info("Update to cache store role for " + snaps.size() + " entries in snapshot_store_ref");
-            for (SnapshotDataStoreVO snap : snaps) {
-                snap.setRole(DataStoreRole.ImageCache);
-                update(snap.getId(), snap);
-            }
-        }
-    }
-
-    @Override
-    public void updateVolumeIds(long oldVolId, long newVolId) {
-        SearchCriteria<SnapshotDataStoreVO> sc = volumeIdSearch.create();
-        sc.setParameters("volume_id", oldVolId);
-        SnapshotDataStoreVO snapshot = createForUpdate();
-        snapshot.setVolumeId(newVolId);
-        UpdateBuilder ub = getUpdateBuilder(snapshot);
-        update(ub, sc, null);
-    }
-
-    @Override
-    public List<SnapshotDataStoreVO> listByState(ObjectInDataStoreStateMachine.State... states) {
-        SearchCriteria<SnapshotDataStoreVO> sc = stateSearch.create();
-        sc.setParameters("state", (Object[])states);
-        return listBy(sc, null);
-    }
-
-    private boolean isSnapshotChainingRequired(long volumeId) {
-
-        hypervisorsSupportingSnapshotsChaining.add(Hypervisor.HypervisorType.XenServer);
-
-        SearchCriteria<SnapshotVO> sc = snapshotVOSearch.create();
-        sc.setParameters("volume_id", volumeId);
-
-        SnapshotVO volSnapshot = _snapshotDao.findOneBy(sc);
-
-        if (volSnapshot != null && hypervisorsSupportingSnapshotsChaining.contains(volSnapshot.getHypervisorType())) {
-            return true;
-        }
-
-        return false;
-    }
-
-}
diff --git a/engine/storage/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java b/engine/storage/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java
new file mode 100644
index 0000000..bddd5a2
--- /dev/null
+++ b/engine/storage/src/test/java/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java
@@ -0,0 +1,143 @@
+// 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.engine.subsystem.api.storage;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
+import org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl;
+
+import com.cloud.host.Host;
+import com.cloud.storage.Snapshot;
+
+public class StrategyPriorityTest {
+
+    @Test
+    public void testSortSnapshotStrategies() {
+        SnapshotStrategy cantHandleStrategy = mock(SnapshotStrategy.class);
+        SnapshotStrategy defaultStrategy = mock(SnapshotStrategy.class);
+        SnapshotStrategy hyperStrategy = mock(SnapshotStrategy.class);
+        SnapshotStrategy highestStrategy = mock(SnapshotStrategy.class);
+
+        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
+        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
+        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
+        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
+
+        List<SnapshotStrategy> strategies = new ArrayList<SnapshotStrategy>(5);
+        SnapshotStrategy strategy = null;
+
+        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
+        factory.setSnapshotStrategies(strategies);
+
+        strategies.add(cantHandleStrategy);
+        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
+        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
+
+        strategies.add(defaultStrategy);
+        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
+        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
+
+        strategies.add(hyperStrategy);
+        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
+        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
+
+        strategies.add(highestStrategy);
+        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
+        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
+    }
+
+    @Test
+    public void testSortDataMotionStrategies() {
+        DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class);
+
+        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(DataObject.class), any(DataObject.class));
+        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(DataObject.class), any(DataObject.class));
+        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(DataObject.class), any(DataObject.class));
+        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(DataObject.class), any(DataObject.class));
+
+        List<DataMotionStrategy> strategies = new ArrayList<DataMotionStrategy>(5);
+        DataMotionStrategy strategy = null;
+
+        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
+        factory.setDataMotionStrategies(strategies);
+
+        strategies.add(cantHandleStrategy);
+        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
+        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
+
+        strategies.add(defaultStrategy);
+        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
+        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
+
+        strategies.add(hyperStrategy);
+        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
+        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
+
+        strategies.add(highestStrategy);
+        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
+        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testSortDataMotionStrategies2() {
+        DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class);
+        DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class);
+
+        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
+        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
+        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
+        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
+
+        List<DataMotionStrategy> strategies = new ArrayList<DataMotionStrategy>(5);
+        DataMotionStrategy strategy = null;
+
+        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
+        factory.setDataMotionStrategies(strategies);
+
+        strategies.add(cantHandleStrategy);
+        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
+        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
+
+        strategies.add(defaultStrategy);
+        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
+        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
+
+        strategies.add(hyperStrategy);
+        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
+        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
+
+        strategies.add(highestStrategy);
+        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
+        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
+    }
+}
diff --git a/engine/storage/test/org/apache/cloudstack/storage/BaseTypeTest.java b/engine/storage/src/test/java/org/apache/cloudstack/storage/BaseTypeTest.java
similarity index 100%
rename from engine/storage/test/org/apache/cloudstack/storage/BaseTypeTest.java
rename to engine/storage/src/test/java/org/apache/cloudstack/storage/BaseTypeTest.java
diff --git a/engine/storage/storage.ucls b/engine/storage/storage.ucls
index 197432e..7f3c9fb 100644
--- a/engine/storage/storage.ucls
+++ b/engine/storage/storage.ucls
@@ -20,7 +20,7 @@
   generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true">    
   <class id="1" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore" project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java" 
     binary="false">    
     <position height="-1" width="-1" x="418" y="554"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -30,7 +30,7 @@
   </class>  
   <interface id="2" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java" 
     binary="false">    
     <position height="-1" width="-1" x="727" y="1011"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -40,7 +40,7 @@
   </interface>  
   <interface id="3" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.driver.PrimaryDataStoreDriver" project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java" 
     binary="false">    
     <position height="-1" width="-1" x="1494" y="1138"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -51,7 +51,7 @@
   <interface id="4" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.validator.StorageProtocolTransformer" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/StorageProtocolTransformer.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/validator/StorageProtocolTransformer.java" 
     binary="false">    
     <position height="-1" width="-1" x="1584" y="606"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -61,7 +61,7 @@
   </interface>  
   <interface id="5" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreProvider.java" 
     binary="false">    
     <position height="-1" width="-1" x="189" y="87"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -72,7 +72,7 @@
   <class id="6" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.xenserver.XenNfsConfigurator"
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/xenserver/XenNfsConfigurator.java"
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/xenserver/XenNfsConfigurator.java"
     binary="false">    
     <position height="-1" width="-1" x="1482" y="448"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -83,7 +83,7 @@
   <class id="7" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.xenserver.AbstractXenConfigurator"
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/xenserver/AbstractXenConfigurator.java"
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/xenserver/AbstractXenConfigurator.java"
     binary="false">    
     <position height="-1" width="-1" x="1536" y="278"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -94,7 +94,7 @@
   <class id="8" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.AbstractPrimaryDataStoreConfigurator" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/AbstractPrimaryDataStoreConfigurator.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/AbstractPrimaryDataStoreConfigurator.java" 
     binary="false">    
     <position height="-1" width="-1" x="1386" y="104"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -104,7 +104,7 @@
   </class>  
   <interface id="9" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore" project="cloud-engine-storage"
-    file="/cloud-engine-storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java" binary="false">    
+    file="/cloud-engine-storage/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java" binary="false">    
     <position height="-1" width="-1" x="770" y="-4"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
       <attributes public="false" package="true" protected="true" private="true"/>      
@@ -114,7 +114,7 @@
   <interface id="10" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.PrimaryDataStoreConfigurator" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/PrimaryDataStoreConfigurator.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/PrimaryDataStoreConfigurator.java" 
     binary="false">    
     <position height="-1" width="-1" x="1394" y="-75"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -125,7 +125,7 @@
   <class id="11" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.validator.NfsProtocolTransformer" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/NfsProtocolTransformer.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/validator/NfsProtocolTransformer.java" 
     binary="false">    
     <position height="-1" width="-1" x="1557" y="830"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -136,7 +136,7 @@
   <class id="12" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.lifecycle.DefaultXenServerPrimaryDataStoreLifeCycle"
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenServerPrimaryDataStoreLifeCycle.java"
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/DefaultXenServerPrimaryDataStoreLifeCycle.java"
     binary="false">    
     <position height="-1" width="-1" x="724" y="1502"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -147,7 +147,7 @@
   <class id="13" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.lifecycle.DefaultPrimaryDataStoreLifeCycleImpl" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java" 
     binary="false">    
     <position height="-1" width="-1" x="487" y="1290"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -158,7 +158,7 @@
   <class id="14" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.xenserver.XenServerIscsiConfigurator"
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/xenserver/XenServerIscsiConfigurator.java"
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/xenserver/XenServerIscsiConfigurator.java"
     binary="false">    
     <position height="-1" width="-1" x="1817" y="450"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -169,7 +169,7 @@
   <class id="15" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.kvm.AbstractKvmConfigurator" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/kvm/AbstractKvmConfigurator.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/kvm/AbstractKvmConfigurator.java" 
     binary="false">    
     <position height="-1" width="-1" x="2255" y="278"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -180,7 +180,7 @@
   <class id="16" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.kvm.KvmNfsConfigurator" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/kvm/KvmNfsConfigurator.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/kvm/KvmNfsConfigurator.java" 
     binary="false">    
     <position height="-1" width="-1" x="2155" y="459"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -191,7 +191,7 @@
   <class id="17" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.kvm.KvmCLVMConfigurator" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/kvm/KvmCLVMConfigurator.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/kvm/KvmCLVMConfigurator.java" 
     binary="false">    
     <position height="-1" width="-1" x="2515" y="453"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -202,7 +202,7 @@
   <class id="18" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.validator.ISCSIProtocolTransformer" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/ISCSIProtocolTransformer.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/validator/ISCSIProtocolTransformer.java" 
     binary="false">    
     <position height="-1" width="-1" x="1935" y="823"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
@@ -213,7 +213,7 @@
   <class id="19" corner="BOTTOM_RIGHT" language="java" 
     name="org.apache.cloudstack.storage.datastore.configurator.validator.CLVMProtocolTransformer" 
     project="cloud-engine-storage-volume" 
-    file="/cloud-engine-storage-volume/src/org/apache/cloudstack/storage/datastore/configurator/validator/CLVMProtocolTransformer.java" 
+    file="/cloud-engine-storage-volume/src/main/java/org/apache/cloudstack/storage/datastore/configurator/validator/CLVMProtocolTransformer.java" 
     binary="false">    
     <position height="-1" width="-1" x="2319" y="824"/>    
     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
diff --git a/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java b/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java
deleted file mode 100644
index af44b4a..0000000
--- a/engine/storage/test/org/apache/cloudstack/engine/subsystem/api/storage/StrategyPriorityTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.engine.subsystem.api.storage;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
-import org.apache.cloudstack.storage.helper.StorageStrategyFactoryImpl;
-
-import com.cloud.host.Host;
-import com.cloud.storage.Snapshot;
-
-public class StrategyPriorityTest {
-
-    @Test
-    public void testSortSnapshotStrategies() {
-        SnapshotStrategy cantHandleStrategy = mock(SnapshotStrategy.class);
-        SnapshotStrategy defaultStrategy = mock(SnapshotStrategy.class);
-        SnapshotStrategy hyperStrategy = mock(SnapshotStrategy.class);
-        SnapshotStrategy pluginStrategy = mock(SnapshotStrategy.class);
-        SnapshotStrategy highestStrategy = mock(SnapshotStrategy.class);
-
-        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
-        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
-        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
-        doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
-        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Snapshot.class), any(SnapshotOperation.class));
-
-        List<SnapshotStrategy> strategies = new ArrayList<SnapshotStrategy>(5);
-        SnapshotStrategy strategy = null;
-
-        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
-        factory.setSnapshotStrategies(strategies);
-
-        strategies.add(cantHandleStrategy);
-        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
-        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
-
-        strategies.add(defaultStrategy);
-        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
-        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
-
-        strategies.add(hyperStrategy);
-        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
-        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
-
-        strategies.add(pluginStrategy);
-        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
-        assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy);
-
-        strategies.add(highestStrategy);
-        strategy = factory.getSnapshotStrategy(mock(Snapshot.class), SnapshotOperation.TAKE);
-        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
-    }
-
-    @Test
-    public void testSortDataMotionStrategies() {
-        DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class);
-
-        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(DataObject.class), any(DataObject.class));
-        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(DataObject.class), any(DataObject.class));
-        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(DataObject.class), any(DataObject.class));
-        doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(DataObject.class), any(DataObject.class));
-        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(DataObject.class), any(DataObject.class));
-
-        List<DataMotionStrategy> strategies = new ArrayList<DataMotionStrategy>(5);
-        DataMotionStrategy strategy = null;
-
-        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
-        factory.setDataMotionStrategies(strategies);
-
-        strategies.add(cantHandleStrategy);
-        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
-        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
-
-        strategies.add(defaultStrategy);
-        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
-        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
-
-        strategies.add(hyperStrategy);
-        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
-        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
-
-        strategies.add(pluginStrategy);
-        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
-        assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy);
-
-        strategies.add(highestStrategy);
-        strategy = factory.getDataMotionStrategy(mock(DataObject.class), mock(DataObject.class));
-        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testSortDataMotionStrategies2() {
-        DataMotionStrategy cantHandleStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy defaultStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy hyperStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy pluginStrategy = mock(DataMotionStrategy.class);
-        DataMotionStrategy highestStrategy = mock(DataMotionStrategy.class);
-
-        doReturn(StrategyPriority.CANT_HANDLE).when(cantHandleStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
-        doReturn(StrategyPriority.DEFAULT).when(defaultStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
-        doReturn(StrategyPriority.HYPERVISOR).when(hyperStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
-        doReturn(StrategyPriority.PLUGIN).when(pluginStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
-        doReturn(StrategyPriority.HIGHEST).when(highestStrategy).canHandle(any(Map.class), any(Host.class), any(Host.class));
-
-        List<DataMotionStrategy> strategies = new ArrayList<DataMotionStrategy>(5);
-        DataMotionStrategy strategy = null;
-
-        StorageStrategyFactoryImpl factory = new StorageStrategyFactoryImpl();
-        factory.setDataMotionStrategies(strategies);
-
-        strategies.add(cantHandleStrategy);
-        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
-        assertEquals("A strategy was found when it shouldn't have been.", null, strategy);
-
-        strategies.add(defaultStrategy);
-        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
-        assertEquals("Default strategy was not picked.", defaultStrategy, strategy);
-
-        strategies.add(hyperStrategy);
-        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
-        assertEquals("Hypervisor strategy was not picked.", hyperStrategy, strategy);
-
-        strategies.add(pluginStrategy);
-        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
-        assertEquals("Plugin strategy was not picked.", pluginStrategy, strategy);
-
-        strategies.add(highestStrategy);
-        strategy = factory.getDataMotionStrategy(mock(Map.class), mock(Host.class), mock(Host.class));
-        assertEquals("Highest strategy was not picked.", highestStrategy, strategy);
-    }
-}
diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml
index 3c968fb..e4514b9 100644
--- a/engine/storage/volume/pom.xml
+++ b/engine/storage/volume/pom.xml
@@ -1,52 +1,60 @@
-<!-- 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. -->
+<!--
+  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-engine-storage-volume</artifactId>
-  <name>Apache CloudStack Engine Storage Volume Component</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-engine</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-engine-storage-volume</artifactId>
+    <name>Apache CloudStack Engine Storage Volume Component</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-engine</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/manager/data model.ucls b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/manager/data model.ucls
new file mode 100644
index 0000000..b28a5cc
--- /dev/null
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/manager/data model.ucls
@@ -0,0 +1,75 @@
+<!--
+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.
+-->
+<class-diagram version="1.0.11" icons="true" always-add-relationships="false" generalizations="true" realizations="true" 
+  associations="true" dependencies="false" nesting-relationships="true">  
+  <interface id="1" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.DataObject" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java" binary="false">    
+    <position height="-1" width="-1" x="311" y="101"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="2" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java" binary="false">    
+    <position height="-1" width="-1" x="146" y="279"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="3" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java" binary="false">    
+    <position height="-1" width="-1" x="361" y="282"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <interface id="4" corner="BOTTOM_RIGHT" language="java" 
+    name="org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo" project="cloud-engine-api" 
+    file="/cloud-engine-api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java" binary="false">    
+    <position height="-1" width="-1" x="573" y="292"/>    
+    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
+      <attributes public="true" package="true" protected="true" private="true"/>      
+      <operations public="true" package="true" protected="true" private="true"/>    
+    </display>  
+  </interface>  
+  <generalization id="5">    
+    <end type="SOURCE" refId="3"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <generalization id="6">    
+    <end type="SOURCE" refId="4"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <generalization id="7">    
+    <end type="SOURCE" refId="2"/>    
+    <end type="TARGET" refId="1"/>  
+  </generalization>  
+  <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
+    visibility="true">    
+    <attributes public="true" package="true" protected="true" private="true"/>    
+    <operations public="true" package="true" protected="true" private="true"/>  
+  </classifier-display>  
+  <association-display labels="true" multiplicity="true"/>
+</class-diagram>
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/DataStoreType.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/DataStoreType.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/DataStoreType.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/DataStoreType.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/ISCSI.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/ISCSI.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/ISCSI.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/ISCSI.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/NetworkFileSystem.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/NetworkFileSystem.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/NetworkFileSystem.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/NetworkFileSystem.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/SharedMount.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/SharedMount.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/type/SharedMount.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/type/SharedMount.java
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
similarity index 100%
rename from engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
rename to engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java
new file mode 100644
index 0000000..85d9524
--- /dev/null
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -0,0 +1,766 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.volume;
+
+import java.util.Date;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering.DiskCacheMode;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.storage.encoding.EncodingType;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class VolumeObject implements VolumeInfo {
+    private static final Logger s_logger = Logger.getLogger(VolumeObject.class);
+    protected VolumeVO volumeVO;
+    private StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
+    protected DataStore dataStore;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    VolumeDataStoreDao volumeStoreDao;
+    @Inject
+    ObjectInDataStoreManager objectInStoreMgr;
+    @Inject
+    VMInstanceDao vmInstanceDao;
+    @Inject
+    DiskOfferingDao diskOfferingDao;
+    private Object payload;
+
+    public VolumeObject() {
+        _volStateMachine = Volume.State.getStateMachine();
+    }
+
+    protected void configure(DataStore dataStore, VolumeVO volumeVO) {
+        this.volumeVO = volumeVO;
+        this.dataStore = dataStore;
+    }
+
+    public static VolumeObject getVolumeObject(DataStore dataStore, VolumeVO volumeVO) {
+        VolumeObject vo = ComponentContext.inject(VolumeObject.class);
+        vo.configure(dataStore, volumeVO);
+        return vo;
+    }
+
+    @Override
+    public String getAttachedVmName() {
+        Long vmId = volumeVO.getInstanceId();
+        if (vmId != null) {
+            VMInstanceVO vm = vmInstanceDao.findById(vmId);
+
+            if (vm == null) {
+                return null;
+            }
+            return vm.getInstanceName();
+        }
+        return null;
+    }
+
+    @Override
+    public VirtualMachine getAttachedVM() {
+        Long vmId = volumeVO.getInstanceId();
+        if (vmId != null) {
+            VMInstanceVO vm = vmInstanceDao.findById(vmId);
+            return vm;
+        }
+        return null;
+    }
+    @Override
+    public String getUuid() {
+        return volumeVO.getUuid();
+    }
+
+    public void setUuid(String uuid) {
+        volumeVO.setUuid(uuid);
+    }
+
+    @Override
+    public String get_iScsiName() {
+        return volumeVO.get_iScsiName();
+    }
+
+    public void setSize(Long size) {
+        volumeVO.setSize(size);
+    }
+
+    @Override
+    public Volume.State getState() {
+        return volumeVO.getState();
+    }
+
+    @Override
+    public DataStore getDataStore() {
+        return dataStore;
+    }
+
+    @Override
+    public Long getSize() {
+        return volumeVO.getSize();
+    }
+
+    @Override
+    public Long getMinIops() {
+        return volumeVO.getMinIops();
+    }
+
+    @Override
+    public Long getMaxIops() {
+        return volumeVO.getMaxIops();
+    }
+
+    @Override
+    public Integer getHypervisorSnapshotReserve() {
+        return volumeVO.getHypervisorSnapshotReserve();
+    }
+
+    @Override
+    public boolean isDisplayVolume() {
+        return volumeVO.isDisplayVolume();
+    }
+
+    @Override
+    public boolean isDisplay() {
+        return volumeVO.isDisplay();
+    }
+
+    public long getVolumeId() {
+        return volumeVO.getId();
+    }
+
+    @Override
+    public boolean stateTransit(Volume.Event event) {
+        boolean result = false;
+        try {
+            volumeVO = volumeDao.findById(volumeVO.getId());
+            if (volumeVO != null) {
+                result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
+                volumeVO = volumeDao.findById(volumeVO.getId());
+            }
+        } catch (NoTransitionException e) {
+            String errorMessage = "Failed to transit volume: " + getVolumeId() + ", due to: " + e.toString();
+            s_logger.debug(errorMessage);
+            throw new CloudRuntimeException(errorMessage);
+        }
+        return result;
+    }
+
+    private DiskOfferingVO getDiskOfferingVO() {
+        if (getDiskOfferingId() != null) {
+            DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(getDiskOfferingId());
+            return diskOfferingVO;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesReadRate() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesReadRate();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesReadRateMax() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesReadRateMax();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesReadRateMaxLength() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesReadRateMaxLength();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesWriteRate() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesWriteRate();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesWriteRateMax() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesWriteRateMax();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getBytesWriteRateMaxLength() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getBytesWriteRateMaxLength();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsReadRate() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsReadRate();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsReadRateMax() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsReadRateMax();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsReadRateMaxLength() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsReadRateMaxLength();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsWriteRate() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsWriteRate();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsWriteRateMax() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsWriteRateMax();
+        }
+        return null;
+    }
+
+    @Override
+    public Long getIopsWriteRateMaxLength() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getIopsWriteRateMaxLength();
+        }
+        return null;
+    }
+
+    @Override
+    public DiskCacheMode getCacheMode() {
+        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
+        if (diskOfferingVO != null) {
+            return diskOfferingVO.getCacheMode();
+        }
+        return null;
+    }
+
+    public void update() {
+        volumeDao.update(volumeVO.getId(), volumeVO);
+        volumeVO = volumeDao.findById(volumeVO.getId());
+    }
+
+    @Override
+    public long getId() {
+        return volumeVO.getId();
+    }
+
+    @Override
+    public boolean isAttachedVM() {
+        return (volumeVO.getInstanceId() == null) ? false : true;
+    }
+
+    @Override
+    public String getUri() {
+        if (dataStore == null) {
+            throw new CloudRuntimeException("datastore must be set before using this object");
+        }
+        DataObjectInStore obj = objectInStoreMgr.findObject(volumeVO.getId(), DataObjectType.VOLUME, dataStore.getId(), dataStore.getRole());
+        if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
+            return dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + EncodingType.SIZE + "=" + volumeVO.getSize() + "&" +
+                EncodingType.NAME + "=" + volumeVO.getName();
+        } else {
+            return dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + EncodingType.PATH + "=" + obj.getInstallPath();
+        }
+    }
+
+    @Override
+    public DataObjectType getType() {
+        return DataObjectType.VOLUME;
+    }
+
+    @Override
+    public void processEvent(ObjectInDataStoreStateMachine.Event event) {
+        if (dataStore == null) {
+            return;
+        }
+        try {
+            Volume.Event volEvent = null;
+            if (dataStore.getRole() == DataStoreRole.ImageCache) {
+                objectInStoreMgr.update(this, event);
+                return;
+            }
+            if (dataStore.getRole() == DataStoreRole.Image) {
+                objectInStoreMgr.update(this, event);
+                if (volumeVO.getState() == Volume.State.Migrating || volumeVO.getState() == Volume.State.Copying ||
+                    volumeVO.getState() == Volume.State.Uploaded || volumeVO.getState() == Volume.State.Expunged) {
+                    return;
+                }
+                if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
+                    volEvent = Volume.Event.UploadRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) {
+                    volEvent = Volume.Event.CopyRequested;
+                }
+            } else {
+                if (event == ObjectInDataStoreStateMachine.Event.CreateRequested || event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
+                    volEvent = Volume.Event.CreateRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.CopyingRequested) {
+                    volEvent = Volume.Event.CopyRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) {
+                    volEvent = Volume.Event.MigrationRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopyRequested) {
+                    volEvent = Event.MigrationCopyRequested;
+                }
+            }
+
+            if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) {
+                volEvent = Volume.Event.DestroyRequested;
+            } else if (event == ObjectInDataStoreStateMachine.Event.ExpungeRequested) {
+                volEvent = Volume.Event.ExpungingRequested;
+            } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) {
+                volEvent = Volume.Event.OperationSucceeded;
+            } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopySucceeded) {
+              volEvent = Event.MigrationCopySucceeded;
+            } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                volEvent = Volume.Event.OperationFailed;
+            } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopyFailed) {
+              volEvent = Event.MigrationCopyFailed;
+            } else if (event == ObjectInDataStoreStateMachine.Event.ResizeRequested) {
+                volEvent = Volume.Event.ResizeRequested;
+            }
+            stateTransit(volEvent);
+        } catch (Exception e) {
+            s_logger.debug("Failed to update state", e);
+            throw new CloudRuntimeException("Failed to update state:" + e.toString());
+        } finally {
+            // in case of OperationFailed, expunge the entry
+            // state transit call reloads the volume from DB and so check for null as well
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed &&
+                (volumeVO != null && volumeVO.getState() != Volume.State.Copying && volumeVO.getState() != Volume.State.Uploaded && volumeVO.getState() != Volume.State.UploadError)) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+        }
+    }
+
+    @Override
+    public void processEventOnly(ObjectInDataStoreStateMachine.Event event) {
+        try {
+            objectInStoreMgr.update(this, event);
+        } catch (Exception e) {
+            s_logger.debug("Failed to update state", e);
+            throw new CloudRuntimeException("Failed to update state:" + e.toString());
+        } finally {
+            // in case of OperationFailed, expunge the entry
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return volumeVO.getName();
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return volumeVO.getInstanceId();
+    }
+
+    @Override
+    public String getFolder() {
+        return volumeVO.getFolder();
+    }
+
+    @Override
+    public String getPath() {
+        if (dataStore.getRole() == DataStoreRole.Primary) {
+            return volumeVO.getPath();
+        } else {
+            DataObjectInStore objInStore = objectInStoreMgr.findObject(this, dataStore);
+            if (objInStore != null) {
+                return objInStore.getInstallPath();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    @Override
+    public Long getPodId() {
+        return volumeVO.getPodId();
+    }
+
+    @Override
+    public long getDataCenterId() {
+        return volumeVO.getDataCenterId();
+    }
+
+    @Override
+    public Type getVolumeType() {
+        return volumeVO.getVolumeType();
+    }
+
+    @Override
+    public Long getPoolId() {
+        return volumeVO.getPoolId();
+    }
+
+    @Override
+    public Date getAttached() {
+        return volumeVO.getAttached();
+    }
+
+    @Override
+    public Long getDeviceId() {
+        return volumeVO.getDeviceId();
+    }
+
+    @Override
+    public Date getCreated() {
+        return volumeVO.getCreated();
+    }
+
+    @Override
+    public Long getDiskOfferingId() {
+        return volumeVO.getDiskOfferingId();
+    }
+
+    @Override
+    public String getChainInfo() {
+        return volumeVO.getChainInfo();
+    }
+
+    @Override
+    public boolean isRecreatable() {
+        return volumeVO.isRecreatable();
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        return volumeVO.getUpdatedCount();
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        volumeVO.incrUpdatedCount();
+    }
+
+    @Override
+    public Date getUpdated() {
+        return volumeVO.getUpdated();
+    }
+
+    @Override
+    public String getReservationId() {
+        return volumeVO.getReservationId();
+    }
+
+    @Override
+    public void setReservationId(String reserv) {
+        volumeVO.setReservationId(reserv);
+    }
+
+    @Override
+    public long getAccountId() {
+        return volumeVO.getAccountId();
+    }
+
+    @Override
+    public long getDomainId() {
+        return volumeVO.getDomainId();
+    }
+
+    @Override
+    public Long getTemplateId() {
+        return volumeVO.getTemplateId();
+    }
+
+    @Override
+    public void addPayload(Object data) {
+        payload = data;
+    }
+
+    @Override
+    public Object getpayload() {
+        return payload;
+    }
+
+    public VolumeVO getVolume() {
+        return volumeVO;
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return volumeDao.getHypervisorType(volumeVO.getId());
+    }
+
+    @Override
+    public Long getLastPoolId() {
+        return volumeVO.getLastPoolId();
+    }
+
+    @Override
+    public DataTO getTO() {
+        DataTO to = getDataStore().getDriver().getTO(this);
+        if (to == null) {
+            to = new VolumeObjectTO(this);
+        }
+        return to;
+    }
+
+    @Override
+    public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
+        try {
+            if (dataStore.getRole() == DataStoreRole.Primary) {
+                if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    VolumeVO vol = volumeDao.findById(getId());
+                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
+                    vol.setPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        // Root disk resize may be requested where the original
+                        // template size is less than the requested root disk size
+                        if (vol.getSize() == null || vol.getSize() < newVol.getSize()) {
+                            vol.setSize(newVol.getSize());
+                        }
+                    }
+                    if (newVol.getFormat() != null) {
+                        vol.setFormat(newVol.getFormat());
+                    }
+                    vol.setPoolId(getDataStore().getId());
+                    volumeDao.update(vol.getId(), vol);
+                } else if (answer instanceof CreateObjectAnswer) {
+                    CreateObjectAnswer createAnswer = (CreateObjectAnswer)answer;
+                    VolumeObjectTO newVol = (VolumeObjectTO)createAnswer.getData();
+                    VolumeVO vol = volumeDao.findById(getId());
+                    vol.setPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        vol.setSize(newVol.getSize());
+                    }
+                    vol.setPoolId(getDataStore().getId());
+                    if (newVol.getFormat() != null) {
+                        vol.setFormat(newVol.getFormat());
+                    }
+                    volumeDao.update(vol.getId(), vol);
+                }
+            } else {
+                // image store or imageCache store
+                if (answer instanceof DownloadAnswer) {
+                    DownloadAnswer dwdAnswer = (DownloadAnswer)answer;
+                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+                    volStore.setInstallPath(dwdAnswer.getInstallPath());
+                    volStore.setChecksum(dwdAnswer.getCheckSum());
+                    volumeStoreDao.update(volStore.getId(), volStore);
+                } else if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
+                    volStore.setInstallPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        volStore.setSize(newVol.getSize());
+                    }
+                    volumeStoreDao.update(volStore.getId(), volStore);
+                }
+            }
+        } catch (RuntimeException ex) {
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+            throw ex;
+        }
+        this.processEvent(event);
+
+    }
+
+    @Override
+    public void incRefCount() {
+        if (dataStore == null) {
+            return;
+        }
+
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+            store.incrRefCnt();
+            store.setLastUpdated(new Date());
+            volumeStoreDao.update(store.getId(), store);
+        }
+    }
+
+    @Override
+    public void decRefCount() {
+        if (dataStore == null) {
+            return;
+        }
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+            store.decrRefCnt();
+            store.setLastUpdated(new Date());
+            volumeStoreDao.update(store.getId(), store);
+        }
+    }
+
+    @Override
+    public Long getRefCount() {
+        if (dataStore == null) {
+            return null;
+        }
+        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
+            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+            return store.getRefCnt();
+        }
+        return null;
+    }
+
+    @Override
+    public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer) {
+        try {
+            if (dataStore.getRole() == DataStoreRole.Primary) {
+                if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    VolumeVO vol = volumeDao.findById(getId());
+                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
+                    vol.setPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        vol.setSize(newVol.getSize());
+                    }
+                    vol.setPoolId(getDataStore().getId());
+                    volumeDao.update(vol.getId(), vol);
+                } else if (answer instanceof CreateObjectAnswer) {
+                    CreateObjectAnswer createAnswer = (CreateObjectAnswer)answer;
+                    VolumeObjectTO newVol = (VolumeObjectTO)createAnswer.getData();
+                    VolumeVO vol = volumeDao.findById(getId());
+                    vol.setPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        vol.setSize(newVol.getSize());
+                    }
+                    vol.setPoolId(getDataStore().getId());
+                    volumeDao.update(vol.getId(), vol);
+                }
+            } else {
+                // image store or imageCache store
+                if (answer instanceof DownloadAnswer) {
+                    DownloadAnswer dwdAnswer = (DownloadAnswer)answer;
+                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+                    volStore.setInstallPath(dwdAnswer.getInstallPath());
+                    volStore.setChecksum(dwdAnswer.getCheckSum());
+                    volumeStoreDao.update(volStore.getId(), volStore);
+                } else if (answer instanceof CopyCmdAnswer) {
+                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
+                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
+                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
+                    volStore.setInstallPath(newVol.getPath());
+                    if (newVol.getSize() != null) {
+                        volStore.setSize(newVol.getSize());
+                    }
+                    volumeStoreDao.update(volStore.getId(), volStore);
+                }
+            }
+        } catch (RuntimeException ex) {
+            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
+                objectInStoreMgr.deleteIfNotReady(this);
+            }
+            throw ex;
+        }
+        this.processEventOnly(event);
+
+    }
+
+    @Override
+    public ImageFormat getFormat() {
+        return volumeVO.getFormat();
+    }
+
+    @Override
+    public ProvisioningType getProvisioningType(){
+        return this.volumeVO.getProvisioningType();
+    }
+
+    @Override
+    public boolean delete() {
+        if (dataStore != null) {
+            return dataStore.delete(this);
+        }
+        return true;
+    }
+
+    @Override
+    public Long getVmSnapshotChainSize() {
+        return volumeVO.getVmSnapshotChainSize();
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return Volume.class;
+    }
+}
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
new file mode 100644
index 0000000..2a642f0
--- /dev/null
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -0,0 +1,2101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.volume;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.RemoteHostEndPoint;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.apache.cloudstack.storage.image.store.TemplateObject;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.storage.ListVolumeAnswer;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.ResizeVolumeCommand;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.resource.ResourceState;
+import com.cloud.server.ManagementService;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.RegisterVolumePayload;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.State;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class VolumeServiceImpl implements VolumeService {
+    private static final Logger s_logger = Logger.getLogger(VolumeServiceImpl.class);
+    @Inject
+    protected AgentManager agentMgr;
+    @Inject
+    VolumeDao volDao;
+    @Inject
+    PrimaryDataStoreProviderManager dataStoreMgr;
+    @Inject
+    DataMotionService motionSrv;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    SnapshotManager snapshotMgr;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    ConfigurationDao configDao;
+    @Inject
+    VolumeDataStoreDao _volumeStoreDao;
+    @Inject
+    VMTemplatePoolDao _tmpltPoolDao;
+    @Inject
+    SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    VolumeDao _volumeDao;
+    @Inject
+    EndPointSelector _epSelector;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    private PrimaryDataStoreDao storagePoolDao;
+    @Inject
+    private HostDetailsDao hostDetailsDao;
+    @Inject
+    private ManagementService mgr;
+    @Inject
+    private ClusterDao clusterDao;
+    @Inject
+    private VolumeDetailsDao _volumeDetailsDao;
+
+    private final static String SNAPSHOT_ID = "SNAPSHOT_ID";
+
+    public VolumeServiceImpl() {
+    }
+
+    private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
+
+        private final DataObject volume;
+        private final AsyncCallFuture<VolumeApiResult> future;
+
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume, AsyncCallFuture<VolumeApiResult> future) {
+            super(callback);
+            this.volume = volume;
+            this.future = future;
+        }
+
+        public DataObject getVolume() {
+            return this.volume;
+        }
+
+        public AsyncCallFuture<VolumeApiResult> getFuture() {
+            return this.future;
+        }
+
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject, DataStore dataStore) {
+        DataStoreDriver dataStoreDriver = dataStore.getDriver();
+
+        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
+            return ((PrimaryDataStoreDriver)dataStoreDriver).getChapInfo(dataObject);
+        }
+
+        return null;
+    }
+
+    @Override
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
+
+        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
+            return ((PrimaryDataStoreDriver)dataStoreDriver).grantAccess(dataObject, host, dataStore);
+        }
+
+        return false;
+    }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
+        if (dataStoreDriver == null) {
+            return;
+        }
+
+        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
+            ((PrimaryDataStoreDriver)dataStoreDriver).revokeAccess(dataObject, host, dataStore);
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore dataStore) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        DataObject volumeOnStore = dataStore.create(volume);
+        volumeOnStore.processEvent(Event.CreateOnlyRequested);
+
+        try {
+            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
+
+            dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
+            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(dataStore.getId(), volume.getId());
+            if (volStoreVO != null) {
+                VolumeInfo volObj = volFactory.getVolume(volume, dataStore);
+                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            VolumeApiResult volResult = new VolumeApiResult((VolumeObject)volumeOnStore);
+            volResult.setResult(ex.getMessage());
+            future.complete(volResult);
+        }
+        return future;
+    }
+
+    protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
+        CreateCmdResult result = callback.getResult();
+        DataObject vo = context.getVolume();
+        String errMsg = null;
+        if (result.isSuccess()) {
+            vo.processEvent(Event.OperationSuccessed, result.getAnswer());
+        } else {
+            vo.processEvent(Event.OperationFailed);
+            errMsg = result.getResult();
+        }
+        VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
+        if (errMsg != null) {
+            volResult.setResult(errMsg);
+        }
+        context.getFuture().complete(volResult);
+        return null;
+    }
+
+    private class DeleteVolumeContext<T> extends AsyncRpcContext<T> {
+        private final VolumeObject volume;
+        private final AsyncCallFuture<VolumeApiResult> future;
+
+        public DeleteVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume, AsyncCallFuture<VolumeApiResult> future) {
+            super(callback);
+            this.volume = volume;
+            this.future = future;
+        }
+
+        public VolumeObject getVolume() {
+            return this.volume;
+        }
+
+        public AsyncCallFuture<VolumeApiResult> getFuture() {
+            return this.future;
+        }
+    }
+
+    // check if a volume is expunged on both primary and secondary
+    private boolean canVolumeBeRemoved(long volumeId) {
+        VolumeVO vol = volDao.findById(volumeId);
+        if (vol == null) {
+            // already removed from volumes table
+            return false;
+        }
+        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volumeId);
+        if ((vol.getState() == State.Expunged || (vol.getPodId() == null && vol.getState() == State.Destroy)) && volumeStore == null) {
+            // volume is expunged from primary, as well as on secondary
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+    @DB
+    @Override
+    public AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult result = new VolumeApiResult(volume);
+        if (volume.getDataStore() == null) {
+            s_logger.info("Expunge volume with no data store specified");
+            if (canVolumeBeRemoved(volume.getId())) {
+                s_logger.info("Volume " + volume.getId() + " is not referred anywhere, remove it from volumes table");
+                volDao.remove(volume.getId());
+            }
+            future.complete(result);
+            return future;
+        }
+
+        // Find out if the volume is at state of download_in_progress on secondary storage
+        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
+        if (volumeStore != null) {
+            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
+                s_logger.debug("Volume: " + volume.getName() + " is currently being uploaded; cant' delete it.");
+                future.complete(result);
+                return future;
+            }
+        }
+
+        VolumeVO vol = volDao.findById(volume.getId());
+        if (vol == null) {
+            s_logger.debug("Volume " + volume.getId() + " is not found");
+            future.complete(result);
+            return future;
+        }
+
+        if (!volumeExistsOnPrimary(vol)) {
+            // not created on primary store
+            if (volumeStore == null) {
+                // also not created on secondary store
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Marking volume that was never created as destroyed: " + vol);
+                }
+                volDao.remove(vol.getId());
+                future.complete(result);
+                return future;
+            }
+        }
+        VolumeObject vo = (VolumeObject)volume;
+
+        if (volume.getDataStore().getRole() == DataStoreRole.Image) {
+            // no need to change state in volumes table
+            volume.processEventOnly(Event.DestroyRequested);
+        } else if (volume.getDataStore().getRole() == DataStoreRole.Primary) {
+            volume.processEvent(Event.ExpungeRequested);
+        }
+
+        DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)).setContext(context);
+
+        volume.getDataStore().getDriver().deleteAsync(volume.getDataStore(), volume, caller);
+        return future;
+    }
+
+    private boolean volumeExistsOnPrimary(VolumeVO vol) {
+        Long poolId = vol.getPoolId();
+
+        if (poolId == null) {
+            return false;
+        }
+
+        PrimaryDataStore primaryStore = dataStoreMgr.getPrimaryDataStore(poolId);
+
+        if (primaryStore == null) {
+            return false;
+        }
+
+        if (primaryStore.isManaged()) {
+            return true;
+        }
+
+        String volumePath = vol.getPath();
+
+        if (volumePath == null || volumePath.trim().isEmpty()) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public Void deleteVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, DeleteVolumeContext<VolumeApiResult> context) {
+        CommandResult result = callback.getResult();
+        VolumeObject vo = context.getVolume();
+        VolumeApiResult apiResult = new VolumeApiResult(vo);
+        try {
+            if (result.isSuccess()) {
+                vo.processEvent(Event.OperationSuccessed);
+                if (canVolumeBeRemoved(vo.getId())) {
+                    s_logger.info("Volume " + vo.getId() + " is not referred anywhere, remove it from volumes table");
+                    volDao.remove(vo.getId());
+                }
+
+                SnapshotDataStoreVO snapStoreVo = _snapshotStoreDao.findByVolume(vo.getId(), DataStoreRole.Primary);
+
+                if (snapStoreVo != null) {
+                    long storagePoolId = snapStoreVo.getDataStoreId();
+                    StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId);
+
+                    if (storagePoolVO.isManaged()) {
+                        DataStore primaryDataStore = dataStoreMgr.getPrimaryDataStore(storagePoolId);
+                        Map<String, String> mapCapabilities = primaryDataStore.getDriver().getCapabilities();
+
+                        String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
+                        Boolean supportsStorageSystemSnapshots = new Boolean(value);
+
+                        if (!supportsStorageSystemSnapshots) {
+                            _snapshotStoreDao.remove(snapStoreVo.getId());
+                        }
+                    } else {
+                        _snapshotStoreDao.remove(snapStoreVo.getId());
+                    }
+                }
+            } else {
+                vo.processEvent(Event.OperationFailed);
+                apiResult.setResult(result.getResult());
+            }
+        } catch (Exception e) {
+            s_logger.debug("ignore delete volume status update failure, it will be picked up by storage clean up thread later", e);
+        }
+        context.getFuture().complete(apiResult);
+        return null;
+    }
+
+    @Override
+    public boolean cloneVolume(long volumeId, long baseVolId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public VolumeEntity getVolumeEntity(long volumeId) {
+        return null;
+    }
+
+    private class ManagedCreateBaseImageContext<T> extends AsyncRpcContext<T> {
+        private final VolumeInfo _volumeInfo;
+        private final PrimaryDataStore _primaryDataStore;
+        private final TemplateInfo _templateInfo;
+        private final AsyncCallFuture<VolumeApiResult> _future;
+
+        public ManagedCreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volumeInfo, PrimaryDataStore primaryDatastore, TemplateInfo templateInfo,
+                AsyncCallFuture<VolumeApiResult> future) {
+            super(callback);
+
+            _volumeInfo = volumeInfo;
+            _primaryDataStore = primaryDatastore;
+            _templateInfo = templateInfo;
+            _future = future;
+        }
+
+        public VolumeInfo getVolumeInfo() {
+            return _volumeInfo;
+        }
+
+        public PrimaryDataStore getPrimaryDataStore() {
+            return _primaryDataStore;
+        }
+
+        public TemplateInfo getTemplateInfo() {
+            return _templateInfo;
+        }
+
+        public AsyncCallFuture<VolumeApiResult> getFuture() {
+            return _future;
+        }
+    }
+
+    class CreateBaseImageContext<T> extends AsyncRpcContext<T> {
+        private final VolumeInfo volume;
+        private final PrimaryDataStore dataStore;
+        private final TemplateInfo srcTemplate;
+        private final AsyncCallFuture<VolumeApiResult> future;
+        final DataObject destObj;
+        long templatePoolId;
+
+        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture<VolumeApiResult> future,
+                DataObject destObj, long templatePoolId) {
+            super(callback);
+            this.volume = volume;
+            this.dataStore = datastore;
+            this.future = future;
+            this.srcTemplate = srcTemplate;
+            this.destObj = destObj;
+            this.templatePoolId = templatePoolId;
+        }
+
+        public VolumeInfo getVolume() {
+            return this.volume;
+        }
+
+        public PrimaryDataStore getDataStore() {
+            return this.dataStore;
+        }
+
+        public TemplateInfo getSrcTemplate() {
+            return this.srcTemplate;
+        }
+
+        public AsyncCallFuture<VolumeApiResult> getFuture() {
+            return this.future;
+        }
+
+        public long getTemplatePoolId() {
+            return templatePoolId;
+        }
+
+    }
+
+    private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) {
+        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
+        int sleepTime = 120;
+        int tries = storagePoolMaxWaitSeconds / sleepTime;
+        while (tries > 0) {
+            TemplateInfo tmpl = store.getTemplate(template.getId());
+            if (tmpl != null) {
+                return tmpl;
+            }
+            try {
+                Thread.sleep(sleepTime * 1000);
+            } catch (InterruptedException e) {
+                s_logger.debug("waiting for template download been interrupted: " + e.toString());
+            }
+            tries--;
+        }
+        return null;
+    }
+
+    @DB
+    protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
+        DataObject templateOnPrimaryStoreObj = dataStore.create(template);
+
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
+        if (templatePoolRef == null) {
+            throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + templatePoolRef.getId());
+            }
+        }
+        long templatePoolRefId = templatePoolRef.getId();
+        CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context);
+
+        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Acquire lock on VMTemplateStoragePool " + templatePoolRefId + " with timeout " + storagePoolMaxWaitSeconds + " seconds");
+        }
+        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
+
+        if (templatePoolRef == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId);
+            }
+            templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
+            if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
+                s_logger.info(
+                        "Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
+                createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
+                return;
+            }
+            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.info("lock is acquired for VMTemplateStoragePool " + templatePoolRefId);
+        }
+        try {
+            if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
+                s_logger.info("Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
+                createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
+                return;
+            }
+            templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
+            motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
+        } catch (Throwable e) {
+            s_logger.debug("failed to create template on storage", e);
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
+            dataStore.create(template);  // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
+            VolumeApiResult result = new VolumeApiResult(volume);
+            result.setResult(e.toString());
+            future.complete(result);
+        } finally {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.info("releasing lock for VMTemplateStoragePool " + templatePoolRefId);
+            }
+            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
+        }
+        return;
+    }
+
+    protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, ManagedCreateBaseImageContext<VolumeApiResult> context) {
+        CopyCommandResult result = callback.getResult();
+        VolumeInfo volumeInfo = context.getVolumeInfo();
+        VolumeApiResult res = new VolumeApiResult(volumeInfo);
+
+        if (result.isSuccess()) {
+            // volumeInfo.processEvent(Event.OperationSuccessed, result.getAnswer());
+
+            VolumeVO volume = volDao.findById(volumeInfo.getId());
+            CopyCmdAnswer answer = (CopyCmdAnswer)result.getAnswer();
+            TemplateObjectTO templateObjectTo = (TemplateObjectTO)answer.getNewData();
+
+            volume.setPath(templateObjectTo.getPath());
+
+            if (templateObjectTo.getFormat() != null) {
+                volume.setFormat(templateObjectTo.getFormat());
+            }
+
+            volDao.update(volume.getId(), volume);
+        } else {
+            volumeInfo.processEvent(Event.DestroyRequested);
+
+            res.setResult(result.getResult());
+        }
+
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+
+        future.complete(res);
+
+        return null;
+    }
+
+    protected Void createManagedTemplateImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<CreateCmdResult> context) {
+        CreateCmdResult result = callback.getResult();
+        VolumeApiResult res = new VolumeApiResult(null);
+
+        res.setResult(result.getResult());
+
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+        DataObject templateOnPrimaryStoreObj = context.getVolume();
+
+        if (result.isSuccess()) {
+            ((TemplateObject)templateOnPrimaryStoreObj).setInstallPath(result.getPath());
+            templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
+        } else {
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
+        }
+
+        future.complete(res);
+
+        return null;
+    }
+
+    protected Void copyManagedTemplateCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
+        CopyCommandResult result = callback.getResult();
+        VolumeApiResult res = new VolumeApiResult(context.getVolume());
+
+        res.setResult(result.getResult());
+
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+        DataObject templateOnPrimaryStoreObj = context.destObj;
+
+        if (result.isSuccess()) {
+            templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
+        } else {
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
+        }
+
+        future.complete(res);
+
+        return null;
+    }
+
+    @DB
+    protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
+        CopyCommandResult result = callback.getResult();
+        VolumeApiResult res = new VolumeApiResult(context.getVolume());
+
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+        DataObject templateOnPrimaryStoreObj = context.destObj;
+        if (!result.isSuccess()) {
+            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
+            res.setResult(result.getResult());
+            future.complete(res);
+            return null;
+        }
+
+        templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
+        createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
+        return null;
+    }
+
+    private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcContext<T> {
+        private final DataObject vo;
+        private final AsyncCallFuture<VolumeApiResult> future;
+        private final DataObject templateOnStore;
+        private final SnapshotInfo snapshot;
+
+        public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture<VolumeApiResult> future,
+                SnapshotInfo snapshot) {
+            super(callback);
+            this.vo = vo;
+            this.future = future;
+            this.templateOnStore = templateOnStore;
+            this.snapshot = snapshot;
+        }
+
+        public AsyncCallFuture<VolumeApiResult> getFuture() {
+            return this.future;
+        }
+    }
+
+    @DB
+    protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
+        DataObject volumeOnPrimaryStorage = pd.create(volume);
+        volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested);
+
+        CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
+        caller.setContext(context);
+
+        motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
+        return;
+    }
+
+    @DB
+    protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
+        DataObject vo = context.vo;
+        DataObject tmplOnPrimary = context.templateOnStore;
+        CopyCommandResult result = callback.getResult();
+        VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
+
+        if (result.isSuccess()) {
+            vo.processEvent(Event.OperationSuccessed, result.getAnswer());
+        } else {
+
+            vo.processEvent(Event.OperationFailed);
+            volResult.setResult(result.getResult());
+            // hack for Vmware: host is down, previously download template to the host needs to be re-downloaded, so we need to reset
+            // template_spool_ref entry here to NOT_DOWNLOADED and Allocated state
+            Answer ans = result.getAnswer();
+            if (ans != null && ans instanceof CopyCmdAnswer && ans.getDetails().contains("request template reload")) {
+                if (tmplOnPrimary != null) {
+                    s_logger.info("Reset template_spool_ref entry so that vmware template can be reloaded in next try");
+                    VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(tmplOnPrimary.getDataStore().getId(), tmplOnPrimary.getId());
+                    if (templatePoolRef != null) {
+                        long templatePoolRefId = templatePoolRef.getId();
+                        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, 1200);
+                        try {
+                            if (templatePoolRef == null) {
+                                s_logger.warn("Reset Template State On Pool failed - unable to lock TemplatePoolRef " + templatePoolRefId);
+                            } else {
+                                templatePoolRef.setTemplateSize(0);
+                                templatePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
+                                templatePoolRef.setState(ObjectInDataStoreStateMachine.State.Allocated);
+
+                                _tmpltPoolDao.update(templatePoolRefId, templatePoolRef);
+                            }
+                        } finally {
+                            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
+                        }
+                    }
+                }
+            }
+        }
+
+        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
+        future.complete(volResult);
+        return null;
+    }
+
+    /**
+     * Creates a template volume on managed storage, which will be used for creating ROOT volumes by cloning.
+     *
+     * @param srcTemplateInfo Source template on secondary storage
+     * @param destPrimaryDataStore Managed storage on which we need to create the volume
+     */
+    private TemplateInfo createManagedTemplateVolume(TemplateInfo srcTemplateInfo, PrimaryDataStore destPrimaryDataStore) {
+        // create a template volume on primary storage
+        AsyncCallFuture<VolumeApiResult> createTemplateFuture = new AsyncCallFuture<>();
+        TemplateInfo templateOnPrimary = (TemplateInfo)destPrimaryDataStore.create(srcTemplateInfo);
+
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
+
+        if (templatePoolRef == null) {
+            throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
+        }
+
+        // At this point, we have an entry in the DB that points to our cached template.
+        // We need to lock it as there may be other VMs that may get started using the same template.
+        // We want to avoid having to create multiple cache copies of the same template.
+
+        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
+        long templatePoolRefId = templatePoolRef.getId();
+
+        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
+
+        if (templatePoolRef == null) {
+            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
+        }
+
+        // Template already exists
+        if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
+            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
+
+            return templateOnPrimary;
+        }
+
+        try {
+            // create a cache volume on the back-end
+
+            templateOnPrimary.processEvent(Event.CreateOnlyRequested);
+
+            CreateVolumeContext<CreateCmdResult> createContext = new CreateVolumeContext<>(null, templateOnPrimary, createTemplateFuture);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> createCaller = AsyncCallbackDispatcher.create(this);
+
+            createCaller.setCallback(createCaller.getTarget().createManagedTemplateImageCallback(null, null)).setContext(createContext);
+
+            destPrimaryDataStore.getDriver().createAsync(destPrimaryDataStore, templateOnPrimary, createCaller);
+
+            VolumeApiResult result = createTemplateFuture.get();
+
+            if (result.isFailed()) {
+                String errMesg = result.getResult();
+
+                throw new CloudRuntimeException("Unable to create template " + templateOnPrimary.getId() + " on primary storage " + destPrimaryDataStore.getId() + ":" + errMesg);
+            }
+        } catch (Throwable e) {
+            s_logger.debug("Failed to create template volume on storage", e);
+
+            templateOnPrimary.processEvent(Event.OperationFailed);
+
+            throw new CloudRuntimeException(e.getMessage());
+        } finally {
+            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
+        }
+
+        return templateOnPrimary;
+    }
+
+    /**
+     * This function copies a template from secondary storage to a template volume
+     * created on managed storage. This template volume will be used as a cache.
+     * Instead of copying the template to a ROOT volume every time, a clone is performed instead.
+     *
+     * @param srcTemplateInfo Source from which to copy the template
+     * @param templateOnPrimary Dest to copy to
+     * @param templatePoolRef Template reference on primary storage (entry in the template_spool_ref)
+     * @param destPrimaryDataStore The managed primary storage
+     * @param destHost The host that we will use for the copy
+     */
+    private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore,
+            Host destHost) {
+        AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
+        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
+        long templatePoolRefId = templatePoolRef.getId();
+
+        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
+
+        if (templatePoolRef == null) {
+            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
+        }
+
+        if (templatePoolRef.getDownloadState() == Status.DOWNLOADED) {
+            // There can be cases where we acquired the lock, but the template
+            // was already copied by a previous thread. Just return in that case.
+
+            s_logger.debug("Template already downloaded, nothing to do");
+
+            return;
+        }
+
+        try {
+            // copy the template from sec storage to the created volume
+            CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(null, null, destPrimaryDataStore, srcTemplateInfo, copyTemplateFuture, templateOnPrimary,
+                    templatePoolRefId);
+
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
+            copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
+
+            // Populate details which will be later read by the storage subsystem.
+            Map<String, String> details = new HashMap<>();
+
+            details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
+            details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
+            details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
+            details.put(PrimaryDataStore.MANAGED_STORE_TARGET, templateOnPrimary.getInstallPath());
+            details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, srcTemplateInfo.getUniqueName());
+            details.put(PrimaryDataStore.REMOVE_AFTER_COPY, Boolean.TRUE.toString());
+            details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(templateOnPrimary.getSize()));
+
+            ChapInfo chapInfo = getChapInfo(templateOnPrimary, destPrimaryDataStore);
+
+            if (chapInfo != null) {
+                details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+                details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+                details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+                details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
+            }
+
+            templateOnPrimary.processEvent(Event.CopyingRequested);
+
+            destPrimaryDataStore.setDetails(details);
+
+            grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
+
+            VolumeApiResult result;
+
+            try {
+                motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
+
+                result = copyTemplateFuture.get();
+            } finally {
+                revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
+
+                if (HypervisorType.VMware.equals(destHost.getHypervisorType())) {
+                    details.put(ModifyTargetsCommand.IQN, templateOnPrimary.getInstallPath());
+
+                    List<Map<String, String>> targets = new ArrayList<>();
+
+                    targets.add(details);
+
+                    removeDynamicTargets(destHost.getId(), targets);
+                }
+            }
+
+            if (result.isFailed()) {
+                throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() + " to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
+                // XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
+                // something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
+                // For now, I just retry the copy.
+            }
+        } catch (Throwable e) {
+            s_logger.debug("Failed to create a template on primary storage", e);
+
+            templateOnPrimary.processEvent(Event.OperationFailed);
+
+            throw new CloudRuntimeException(e.getMessage());
+        } finally {
+            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
+        }
+    }
+
+    private void removeDynamicTargets(long hostId, List<Map<String, String>> targets) {
+        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+        cmd.setTargets(targets);
+        cmd.setApplyToAllHostsInCluster(true);
+        cmd.setAdd(false);
+        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+
+        sendModifyTargetsCommand(cmd, hostId);
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            String msg = "Unable to get an answer to the modify targets command";
+
+            s_logger.warn(msg);
+        } else if (!answer.getResult()) {
+            String msg = "Unable to modify target on the following host: " + hostId;
+
+            s_logger.warn(msg);
+        }
+    }
+
+    /**
+     * Clones the template volume on managed storage to the ROOT volume
+     *
+     * @param volumeInfo ROOT volume to create
+     * @param templateOnPrimary Template from which to clone the ROOT volume
+     * @param destPrimaryDataStore Primary storage of the volume
+     * @param future For async
+     */
+    private void createManagedVolumeCloneTemplateAsync(VolumeInfo volumeInfo, TemplateInfo templateOnPrimary, PrimaryDataStore destPrimaryDataStore, AsyncCallFuture<VolumeApiResult> future) {
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
+
+        if (templatePoolRef == null) {
+            throw new CloudRuntimeException("Failed to find template " + templateOnPrimary.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
+        }
+
+        //XXX: not sure if this the right thing to do here. We can always fallback to the "copy from sec storage"
+        if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
+            throw new CloudRuntimeException("Template " + templateOnPrimary.getUniqueName() + " has not been downloaded to primary storage.");
+        }
+
+        try {
+            volumeInfo.processEvent(Event.CreateOnlyRequested);
+
+            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null);
+
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+
+            caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
+            caller.setContext(context);
+
+            motionSrv.copyAsync(templateOnPrimary, volumeInfo, caller);
+        } catch (Throwable e) {
+            s_logger.debug("Failed to clone template on primary storage", e);
+
+            volumeInfo.processEvent(Event.OperationFailed);
+
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, PrimaryDataStore primaryDataStore, TemplateInfo srcTemplateInfo, Host destHost, AsyncCallFuture<VolumeApiResult> future) {
+        try {
+            // Create a volume on managed storage.
+
+            TemplateInfo destTemplateInfo = (TemplateInfo)primaryDataStore.create(srcTemplateInfo, false);
+
+            AsyncCallFuture<VolumeApiResult> createVolumeFuture = createVolumeAsync(volumeInfo, primaryDataStore);
+            VolumeApiResult createVolumeResult = createVolumeFuture.get();
+
+            if (createVolumeResult.isFailed()) {
+                throw new CloudRuntimeException("Creation of a volume failed: " + createVolumeResult.getResult());
+            }
+
+            // Refresh the volume info from the DB.
+            volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore);
+
+            ManagedCreateBaseImageContext<CreateCmdResult> context = new ManagedCreateBaseImageContext<CreateCmdResult>(null, volumeInfo, primaryDataStore, srcTemplateInfo, future);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+
+            caller.setCallback(caller.getTarget().managedCopyBaseImageCallback(null, null)).setContext(context);
+
+            Map<String, String> details = new HashMap<String, String>();
+
+            details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
+            details.put(PrimaryDataStore.STORAGE_HOST, primaryDataStore.getHostAddress());
+            details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(primaryDataStore.getPort()));
+            // for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume
+            details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName());
+            details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName());
+            details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(volumeInfo.getSize()));
+
+            ChapInfo chapInfo = getChapInfo(volumeInfo, primaryDataStore);
+
+            if (chapInfo != null) {
+                details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+                details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+                details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+                details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
+            }
+
+            primaryDataStore.setDetails(details);
+
+            grantAccess(volumeInfo, destHost, primaryDataStore);
+
+            try {
+                motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller);
+            } finally {
+                revokeAccess(volumeInfo, destHost, primaryDataStore);
+            }
+        } catch (Throwable t) {
+            String errMsg = t.toString();
+
+            volumeInfo.processEvent(Event.DestroyRequested);
+
+            try {
+                AsyncCallFuture<VolumeApiResult> expungeVolumeFuture = expungeVolumeAsync(volumeInfo);
+
+                VolumeApiResult expungeVolumeResult = expungeVolumeFuture.get();
+
+                if (expungeVolumeResult.isFailed()) {
+                    errMsg += " : Failed to expunge a volume that was created";
+                }
+            } catch (Exception ex) {
+                errMsg += " : " + ex.getMessage();
+            }
+
+            VolumeApiResult result = new VolumeApiResult(volumeInfo);
+
+            result.setResult(errMsg);
+
+            future.complete(result);
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId, TemplateInfo srcTemplateInfo, long destHostId) {
+        PrimaryDataStore destPrimaryDataStore = dataStoreMgr.getPrimaryDataStore(destDataStoreId);
+        Host destHost = _hostDao.findById(destHostId);
+
+        if (destHost == null) {
+            throw new CloudRuntimeException("Destination host should not be null.");
+        }
+
+        Boolean storageCanCloneVolume = new Boolean(destPrimaryDataStore.getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString()));
+
+        boolean computeSupportsVolumeClone = computeSupportsVolumeClone(destHost.getDataCenterId(), destHost.getHypervisorType());
+
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<>();
+
+        if (storageCanCloneVolume && computeSupportsVolumeClone) {
+            s_logger.debug("Storage " + destDataStoreId + " can support cloning using a cached template and compute side is OK with volume cloning.");
+
+            TemplateInfo templateOnPrimary = destPrimaryDataStore.getTemplate(srcTemplateInfo.getId());
+
+            if (templateOnPrimary == null) {
+                templateOnPrimary = createManagedTemplateVolume(srcTemplateInfo, destPrimaryDataStore);
+
+                if (templateOnPrimary == null) {
+                    throw new CloudRuntimeException("Failed to create template " + srcTemplateInfo.getUniqueName() + " on primary storage: " + destDataStoreId);
+                }
+            }
+
+            // Copy the template to the template volume.
+            VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
+
+            if (templatePoolRef == null) {
+                throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
+            }
+
+            if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
+                copyTemplateToManagedTemplateVolume(srcTemplateInfo, templateOnPrimary, templatePoolRef, destPrimaryDataStore, destHost);
+            }
+
+            // We have a template on primary storage. Clone it to new volume.
+            s_logger.debug("Creating a clone from template on primary storage " + destDataStoreId);
+
+            createManagedVolumeCloneTemplateAsync(volumeInfo, templateOnPrimary, destPrimaryDataStore, future);
+        } else {
+            s_logger.debug("Primary storage does not support cloning or no support for UUID resigning on the host side; copying the template normally");
+
+            createManagedVolumeCopyTemplateAsync(volumeInfo, destPrimaryDataStore, srcTemplateInfo, destHost, future);
+        }
+
+        return future;
+    }
+
+    private boolean computeSupportsVolumeClone(long zoneId, HypervisorType hypervisorType) {
+        if (HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
+            return true;
+        }
+
+        return getHost(zoneId, hypervisorType, true) != null;
+    }
+
+    private HostVO getHost(Long zoneId, HypervisorType hypervisorType, boolean computeClusterMustSupportResign) {
+        if (zoneId == null) {
+            throw new CloudRuntimeException("Zone ID cannot be null.");
+        }
+
+        List<? extends Cluster> clusters = mgr.searchForClusters(zoneId, new Long(0), Long.MAX_VALUE, hypervisorType.toString());
+
+        if (clusters == null) {
+            clusters = new ArrayList<>();
+        }
+
+        Collections.shuffle(clusters, new Random(System.nanoTime()));
+
+        clusters: for (Cluster cluster : clusters) {
+            if (cluster.getAllocationState() == AllocationState.Enabled) {
+                List<HostVO> hosts = _hostDao.findByClusterId(cluster.getId());
+
+                if (hosts != null) {
+                    Collections.shuffle(hosts, new Random(System.nanoTime()));
+
+                    for (HostVO host : hosts) {
+                        if (host.getResourceState() == ResourceState.Enabled) {
+                            if (computeClusterMustSupportResign) {
+                                if (clusterDao.getSupportsResigning(cluster.getId())) {
+                                    return host;
+                                } else {
+                                    // no other host in the cluster in question should be able to satisfy our requirements here, so move on to the next cluster
+                                    continue clusters;
+                                }
+                            } else {
+                                return host;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @DB
+    @Override
+    public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template) {
+        PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
+        TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+
+        if (templateOnPrimaryStore == null) {
+            createBaseImageAsync(volume, pd, template, future);
+            return future;
+        }
+
+        createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
+        return future;
+    }
+
+    @DB
+    @Override
+    public void destroyVolume(long volumeId) {
+        // mark volume entry in volumes table as destroy state
+        VolumeInfo vol = volFactory.getVolume(volumeId);
+        vol.stateTransit(Volume.Event.DestroyRequested);
+        snapshotMgr.deletePoliciesForVolume(volumeId);
+
+        vol.stateTransit(Volume.Event.OperationSucceeded);
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+
+        try {
+            DataObject volumeOnStore = store.create(volume);
+            volumeOnStore.processEvent(Event.CreateOnlyRequested);
+            _volumeDetailsDao.addDetail(volume.getId(), SNAPSHOT_ID, Long.toString(snapshot.getId()), false);
+
+            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context);
+            motionSrv.copyAsync(snapshot, volumeOnStore, caller);
+        } catch (Exception e) {
+            s_logger.debug("create volume from snapshot failed", e);
+            VolumeApiResult result = new VolumeApiResult(volume);
+            result.setResult(e.toString());
+            future.complete(result);
+        }
+
+        return future;
+    }
+
+    protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
+        CopyCommandResult result = callback.getResult();
+        VolumeInfo volume = (VolumeInfo)context.templateOnStore;
+        SnapshotInfo snapshot = context.snapshot;
+        VolumeApiResult apiResult = new VolumeApiResult(volume);
+        Event event = null;
+        if (result.isFailed()) {
+            apiResult.setResult(result.getResult());
+            event = Event.OperationFailed;
+        } else {
+            event = Event.OperationSuccessed;
+        }
+
+        try {
+            if (result.isSuccess()) {
+                volume.processEvent(event, result.getAnswer());
+            } else {
+                volume.processEvent(event);
+            }
+            _volumeDetailsDao.removeDetail(volume.getId(), SNAPSHOT_ID);
+
+        } catch (Exception e) {
+            s_logger.debug("create volume from snapshot failed", e);
+            apiResult.setResult(e.toString());
+        }
+
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        future.complete(apiResult);
+        return null;
+    }
+
+    protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) {
+        Long lastPoolId = volume.getPoolId();
+        String folder = pool.getPath();
+        // For SMB, pool credentials are also stored in the uri query string.  We trim the query string
+        // part  here to make sure the credentials do not get stored in the db unencrypted.
+        if (pool.getPoolType() == StoragePoolType.SMB && folder != null && folder.contains("?")) {
+            folder = folder.substring(0, folder.indexOf("?"));
+        }
+
+        VolumeVO newVol = new VolumeVO(volume);
+        newVol.setInstanceId(null);
+        newVol.setChainInfo(null);
+        newVol.setPath(null);
+        newVol.setFolder(folder);
+        newVol.setPodId(pool.getPodId());
+        newVol.setPoolId(pool.getId());
+        newVol.setLastPoolId(lastPoolId);
+        newVol.setPodId(pool.getPodId());
+        return volDao.persist(newVol);
+    }
+
+    private class CopyVolumeContext<T> extends AsyncRpcContext<T> {
+        final VolumeInfo srcVolume;
+        final VolumeInfo destVolume;
+        final AsyncCallFuture<VolumeApiResult> future;
+
+        public CopyVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
+            super(callback);
+            this.srcVolume = srcVolume;
+            this.destVolume = destVolume;
+            this.future = future;
+        }
+
+    }
+
+    protected AsyncCallFuture<VolumeApiResult> copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult res = new VolumeApiResult(srcVolume);
+        VolumeInfo destVolume = null;
+        try {
+            destVolume = (VolumeInfo)destStore.create(srcVolume);
+            destVolume.processEvent(Event.CopyingRequested);
+            srcVolume.processEvent(Event.CopyingRequested);
+
+            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)).setContext(context);
+
+            motionSrv.copyAsync(srcVolume, destVolume, caller);
+            return future;
+        } catch (Exception e) {
+            s_logger.error("failed to copy volume from image store", e);
+            if (destVolume != null) {
+                destVolume.processEvent(Event.OperationFailed);
+            }
+
+            srcVolume.processEvent(Event.OperationFailed);
+            res.setResult(e.toString());
+            future.complete(res);
+            return future;
+        }
+    }
+
+    protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
+        VolumeInfo srcVolume = context.srcVolume;
+        VolumeInfo destVolume = context.destVolume;
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        VolumeApiResult res = new VolumeApiResult(destVolume);
+        try {
+            if (result.isFailed()) {
+                destVolume.processEvent(Event.OperationFailed);
+                srcVolume.processEvent(Event.OperationFailed);
+                res.setResult(result.getResult());
+                future.complete(res);
+                return null;
+            }
+
+            srcVolume.processEvent(Event.OperationSuccessed);
+            destVolume.processEvent(Event.OperationSuccessed, result.getAnswer());
+            srcVolume.getDataStore().delete(srcVolume);
+            future.complete(res);
+        } catch (Exception e) {
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+        return null;
+    }
+
+    protected AsyncCallFuture<VolumeApiResult> copyVolumeFromPrimaryToImage(VolumeInfo srcVolume, DataStore destStore) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult res = new VolumeApiResult(srcVolume);
+        VolumeInfo destVolume = null;
+        try {
+            destVolume = (VolumeInfo)destStore.create(srcVolume);
+            srcVolume.processEvent(Event.MigrationRequested);    // this is just used for locking that src volume record in DB to avoid using lock
+            destVolume.processEventOnly(Event.CreateOnlyRequested);
+
+            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().copyVolumeFromPrimaryToImageCallback(null, null)).setContext(context);
+
+            motionSrv.copyAsync(srcVolume, destVolume, caller);
+            return future;
+        } catch (Exception e) {
+            s_logger.error("failed to copy volume to image store", e);
+            if (destVolume != null) {
+                destVolume.getDataStore().delete(destVolume);
+            }
+            srcVolume.processEvent(Event.OperationFailed); // unlock source volume record
+            res.setResult(e.toString());
+            future.complete(res);
+            return future;
+        }
+    }
+
+    protected Void copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
+        VolumeInfo srcVolume = context.srcVolume;
+        VolumeInfo destVolume = context.destVolume;
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        VolumeApiResult res = new VolumeApiResult(destVolume);
+        try {
+            if (result.isFailed()) {
+                srcVolume.processEvent(Event.OperationFailed); // back to Ready state in Volume table
+                destVolume.processEventOnly(Event.OperationFailed);
+                res.setResult(result.getResult());
+                future.complete(res);
+            } else {
+                srcVolume.processEvent(Event.OperationSuccessed); // back to Ready state in Volume table
+                destVolume.processEventOnly(Event.OperationSuccessed, result.getAnswer());
+                future.complete(res);
+            }
+        } catch (Exception e) {
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume, DataStore destStore) {
+        if (s_logger.isDebugEnabled()) {
+            DataStore srcStore = srcVolume.getDataStore();
+            String srcRole = (srcStore != null && srcStore.getRole() != null ? srcVolume.getDataStore().getRole().toString() : "<unknown role>");
+
+            String msg = String.format("copying %s(id=%d, role=%s) to %s (id=%d, role=%s)"
+                    , srcVolume.getName()
+                    , srcVolume.getId()
+                    , srcRole
+                    , destStore.getName()
+                    , destStore.getId()
+                    , destStore.getRole());
+            s_logger.debug(msg);
+        }
+
+        if (srcVolume.getState() == Volume.State.Uploaded) {
+            return copyVolumeFromImageToPrimary(srcVolume, destStore);
+        }
+
+        if (destStore.getRole() == DataStoreRole.Image) {
+            return copyVolumeFromPrimaryToImage(srcVolume, destStore);
+        }
+
+        // OfflineVmwareMigration: aren't we missing secondary to secondary in this logic?
+
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult res = new VolumeApiResult(srcVolume);
+        try {
+            if (!snapshotMgr.canOperateOnVolume(srcVolume)) {
+                s_logger.debug("There are snapshots creating on this volume, can not move this volume");
+
+                res.setResult("There are snapshots creating on this volume, can not move this volume");
+                future.complete(res);
+                return future;
+            }
+
+            VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool)destStore);
+            VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), destStore);
+            destVolume.processEvent(Event.MigrationCopyRequested);
+            srcVolume.processEvent(Event.MigrationRequested);
+
+            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)).setContext(context);
+            motionSrv.copyAsync(srcVolume, destVolume, caller);
+        } catch (Exception e) {
+            s_logger.error("Failed to copy volume:" + e);
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to copy volume.", e);
+            }
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+        return future;
+    }
+
+    protected Void copyVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
+        VolumeInfo srcVolume = context.srcVolume;
+        VolumeInfo destVolume = context.destVolume;
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        VolumeApiResult res = new VolumeApiResult(destVolume);
+        try {
+            if (result.isFailed()) {
+                res.setResult(result.getResult());
+                destVolume.processEvent(Event.MigrationCopyFailed);
+                srcVolume.processEvent(Event.OperationFailed);
+                destroyVolume(destVolume.getId());
+                destVolume = volFactory.getVolume(destVolume.getId());
+                AsyncCallFuture<VolumeApiResult> destroyFuture = expungeVolumeAsync(destVolume);
+                destroyFuture.get();
+                future.complete(res);
+            } else {
+                srcVolume.processEvent(Event.OperationSuccessed);
+                destVolume.processEvent(Event.MigrationCopySucceeded, result.getAnswer());
+                volDao.updateUuid(srcVolume.getId(), destVolume.getId());
+                try {
+                    destroyVolume(srcVolume.getId());
+                    srcVolume = volFactory.getVolume(srcVolume.getId());
+                    AsyncCallFuture<VolumeApiResult> destroyFuture = expungeVolumeAsync(srcVolume);
+                    // If volume destroy fails, this could be because of vdi is still in use state, so wait and retry.
+                    if (destroyFuture.get().isFailed()) {
+                        Thread.sleep(5 * 1000);
+                        destroyFuture = expungeVolumeAsync(srcVolume);
+                        destroyFuture.get();
+                    }
+                    future.complete(res);
+                } catch (Exception e) {
+                    s_logger.debug("failed to clean up volume on storage", e);
+                }
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to process copy volume callback", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return null;
+    }
+
+    private class MigrateVolumeContext<T> extends AsyncRpcContext<T> {
+        final VolumeInfo srcVolume;
+        final VolumeInfo destVolume;
+        final AsyncCallFuture<VolumeApiResult> future;
+
+        /**
+         * @param callback
+         */
+        public MigrateVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
+            super(callback);
+            this.srcVolume = srcVolume;
+            this.destVolume = destVolume;
+            this.future = future;
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> migrateVolume(VolumeInfo srcVolume, DataStore destStore) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult res = new VolumeApiResult(srcVolume);
+        try {
+            if (!snapshotMgr.canOperateOnVolume(srcVolume)) {
+                s_logger.debug("Snapshots are being created on this volume. This volume cannot be migrated now.");
+                res.setResult("Snapshots are being created on this volume. This volume cannot be migrated now.");
+                future.complete(res);
+                return future;
+            }
+
+            VolumeInfo destVolume = volFactory.getVolume(srcVolume.getId(), destStore);
+            srcVolume.processEvent(Event.MigrationRequested);
+            MigrateVolumeContext<VolumeApiResult> context = new MigrateVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().migrateVolumeCallBack(null, null)).setContext(context);
+            motionSrv.copyAsync(srcVolume, destVolume, caller);
+        } catch (Exception e) {
+            s_logger.debug("Failed to copy volume", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+        return future;
+    }
+
+    protected Void migrateVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVolumeContext<VolumeApiResult> context) {
+        VolumeInfo srcVolume = context.srcVolume;
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        VolumeApiResult res = new VolumeApiResult(srcVolume);
+        try {
+            if (result.isFailed()) {
+                res.setResult(result.getResult());
+                srcVolume.processEvent(Event.OperationFailed);
+                future.complete(res);
+            } else {
+                srcVolume.processEvent(Event.OperationSuccessed);
+                snapshotMgr.cleanupSnapshotsByVolume(srcVolume.getId());
+                future.complete(res);
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to process migrate volume callback", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return null;
+    }
+
+    private class MigrateVmWithVolumesContext<T> extends AsyncRpcContext<T> {
+        final Map<VolumeInfo, DataStore> volumeToPool;
+        final AsyncCallFuture<CommandResult> future;
+
+        public MigrateVmWithVolumesContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future, Map<VolumeInfo, DataStore> volumeToPool) {
+            super(callback);
+            this.volumeToPool = volumeToPool;
+            this.future = future;
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<CommandResult> migrateVolumes(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost) {
+        AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
+        CommandResult res = new CommandResult();
+        try {
+            // Check to make sure there are no snapshot operations on a volume
+            // and
+            // put it in the migrating state.
+            List<VolumeInfo> volumesMigrating = new ArrayList<VolumeInfo>();
+            for (Map.Entry<VolumeInfo, DataStore> entry : volumeMap.entrySet()) {
+                VolumeInfo volume = entry.getKey();
+                if (!snapshotMgr.canOperateOnVolume(volume)) {
+                    s_logger.debug("Snapshots are being created on a volume. Volumes cannot be migrated now.");
+                    res.setResult("Snapshots are being created on a volume. Volumes cannot be migrated now.");
+                    future.complete(res);
+
+                    // All the volumes that are already in migrating state need
+                    // to be put back in ready state.
+                    for (VolumeInfo volumeMigrating : volumesMigrating) {
+                        volumeMigrating.processEvent(Event.OperationFailed);
+                    }
+                    return future;
+                } else {
+                    volume.processEvent(Event.MigrationRequested);
+                    volumesMigrating.add(volume);
+                }
+            }
+
+            MigrateVmWithVolumesContext<CommandResult> context = new MigrateVmWithVolumesContext<CommandResult>(null, future, volumeMap);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().migrateVmWithVolumesCallBack(null, null)).setContext(context);
+            motionSrv.copyAsync(volumeMap, vmTo, srcHost, destHost, caller);
+
+        } catch (Exception e) {
+            s_logger.debug("Failed to copy volume", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return future;
+    }
+
+    protected Void migrateVmWithVolumesCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVmWithVolumesContext<CommandResult> context) {
+        Map<VolumeInfo, DataStore> volumeToPool = context.volumeToPool;
+        CopyCommandResult result = callback.getResult();
+        AsyncCallFuture<CommandResult> future = context.future;
+        CommandResult res = new CommandResult();
+        try {
+            if (result.isFailed()) {
+                res.setResult(result.getResult());
+                for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
+                    VolumeInfo volume = entry.getKey();
+                    volume.processEvent(Event.OperationFailed);
+                }
+                future.complete(res);
+            } else {
+                for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
+                    VolumeInfo volume = entry.getKey();
+                    snapshotMgr.cleanupSnapshotsByVolume(volume.getId());
+                    volume.processEvent(Event.OperationSuccessed);
+                }
+                future.complete(res);
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to process copy volume callback", e);
+            res.setResult(e.toString());
+            future.complete(res);
+        }
+
+        return null;
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) {
+
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        DataObject volumeOnStore = store.create(volume);
+
+        volumeOnStore.processEvent(Event.CreateOnlyRequested);
+
+        try {
+            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future);
+            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+            caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
+            caller.setContext(context);
+
+            store.getDriver().createAsync(store, volumeOnStore, caller);
+        } catch (CloudRuntimeException ex) {
+            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
+            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
+            if (volStoreVO != null) {
+                VolumeInfo volObj = volFactory.getVolume(volume, store);
+                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+            }
+            VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore);
+            res.setResult(ex.getMessage());
+            future.complete(res);
+        }
+        return future;
+    }
+
+    @Override
+    public Pair<EndPoint, DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store) {
+
+        EndPoint ep = _epSelector.select(store);
+        if (ep == null) {
+            String errorMessage = "There is no secondary storage VM for image store " + store.getName();
+            s_logger.warn(errorMessage);
+            throw new CloudRuntimeException(errorMessage);
+        }
+        DataObject volumeOnStore = store.create(volume);
+        return new Pair<>(ep, volumeOnStore);
+    }
+
+    protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
+        CreateCmdResult result = callback.getResult();
+        VolumeObject vo = (VolumeObject)context.volume;
+        try {
+            if (result.isFailed()) {
+                vo.processEvent(Event.OperationFailed);
+                // delete the volume entry from volumes table in case of failure
+                VolumeVO vol = volDao.findById(vo.getId());
+                if (vol != null) {
+                    volDao.remove(vo.getId());
+                }
+
+            } else {
+                vo.processEvent(Event.OperationSuccessed, result.getAnswer());
+
+                if (vo.getSize() != null) {
+                    // publish usage events
+                    // get physical size from volume_store_ref table
+                    long physicalSize = 0;
+                    DataStore ds = vo.getDataStore();
+                    VolumeDataStoreVO volStore = _volumeStoreDao.findByStoreVolume(ds.getId(), vo.getId());
+                    if (volStore != null) {
+                        physicalSize = volStore.getPhysicalSize();
+                    } else {
+                        s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() + " at the end of uploading volume!");
+                    }
+                    Scope dsScope = ds.getScope();
+                    if (dsScope.getScopeType() == ScopeType.ZONE) {
+                        if (dsScope.getScopeId() != null) {
+                            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
+                                    Volume.class.getName(), vo.getUuid());
+                        } else {
+                            s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id");
+                        }
+                    } else if (dsScope.getScopeType() == ScopeType.REGION) {
+                        // publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2
+                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
+                                Volume.class.getName(), vo.getUuid());
+
+                        _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize());
+                    }
+                }
+            }
+            VolumeApiResult res = new VolumeApiResult(vo);
+            context.future.complete(res);
+            return null;
+
+        } catch (Exception e) {
+            s_logger.error("register volume failed: ", e);
+            // delete the volume entry from volumes table in case of failure
+            VolumeVO vol = volDao.findById(vo.getId());
+            if (vol != null) {
+                volDao.remove(vo.getId());
+            }
+            VolumeApiResult res = new VolumeApiResult(null);
+            context.future.complete(res);
+            return null;
+        }
+    }
+
+    @Override
+    public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
+        VolumeApiResult result = new VolumeApiResult(volume);
+        try {
+            volume.processEvent(Event.ResizeRequested);
+        } catch (Exception e) {
+            s_logger.debug("Failed to change state to resize", e);
+            result.setResult(e.toString());
+            future.complete(result);
+            return future;
+        }
+        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volume, future);
+        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().resizeVolumeCallback(caller, context)).setContext(context);
+
+        try {
+            volume.getDataStore().getDriver().resize(volume, caller);
+        } catch (Exception e) {
+            s_logger.debug("Failed to change state to resize", e);
+
+            result.setResult(e.toString());
+
+            future.complete(result);
+        }
+
+        return future;
+    }
+
+    @Override
+    public void resizeVolumeOnHypervisor(long volumeId, long newSize, long destHostId, String instanceName) {
+        final String errMsg = "Resize command failed";
+
+        try {
+            Answer answer = null;
+            Host destHost = _hostDao.findById(destHostId);
+            EndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(destHost);
+
+            if (ep != null) {
+                VolumeVO volume = volDao.findById(volumeId);
+                PrimaryDataStore primaryDataStore = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
+                ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(volume.getPath(), new StorageFilerTO(primaryDataStore), volume.getSize(), newSize, true, instanceName,
+                        primaryDataStore.isManaged(), volume.get_iScsiName());
+
+                answer = ep.sendMessage(resizeCmd);
+            } else {
+                throw new CloudRuntimeException("Could not find a remote endpoint to send command to. Check if host or SSVM is down.");
+            }
+
+            if (answer == null || !answer.getResult()) {
+                throw new CloudRuntimeException(answer != null ? answer.getDetails() : errMsg);
+            }
+        } catch (Exception e) {
+            throw new CloudRuntimeException(errMsg, e);
+        }
+    }
+
+    protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
+        CreateCmdResult result = callback.getResult();
+        AsyncCallFuture<VolumeApiResult> future = context.future;
+        VolumeInfo volume = (VolumeInfo)context.volume;
+
+        if (result.isFailed()) {
+            try {
+                volume.processEvent(Event.OperationFailed);
+            } catch (Exception e) {
+                s_logger.debug("Failed to change state", e);
+            }
+            VolumeApiResult res = new VolumeApiResult(volume);
+            res.setResult(result.getResult());
+            future.complete(res);
+            return null;
+        }
+
+        try {
+            volume.processEvent(Event.OperationSuccessed);
+        } catch (Exception e) {
+            s_logger.debug("Failed to change state", e);
+            VolumeApiResult res = new VolumeApiResult(volume);
+            res.setResult(result.getResult());
+            future.complete(res);
+            return null;
+        }
+
+        VolumeApiResult res = new VolumeApiResult(volume);
+        future.complete(res);
+
+        return null;
+    }
+
+    @Override
+    public void handleVolumeSync(DataStore store) {
+        if (store == null) {
+            s_logger.warn("Huh? image store is null");
+            return;
+        }
+        long storeId = store.getId();
+
+        // add lock to make template sync for a data store only be done once
+        String lockString = "volumesync.storeId:" + storeId;
+        GlobalLock syncLock = GlobalLock.getInternLock(lockString);
+        try {
+            if (syncLock.lock(3)) {
+                try {
+                    Map<Long, TemplateProp> volumeInfos = listVolume(store);
+                    if (volumeInfos == null) {
+                        return;
+                    }
+
+                    // find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
+                    List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
+                    List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
+                    for (VolumeDataStoreVO volumeStore : dbVolumes) {
+                        VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
+                        if (volume == null) {
+                            s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId
+                                    + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
+                            volumeStore.setDestroyed(true);
+                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+                            continue;
+                        }
+                        // Exists then don't download
+                        if (volumeInfos.containsKey(volume.getId())) {
+                            TemplateProp volInfo = volumeInfos.remove(volume.getId());
+                            toBeDownloaded.remove(volumeStore);
+                            s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
+                            if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
+                                volumeStore.setErrorString("");
+                            }
+                            if (volInfo.isCorrupted()) {
+                                volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                                String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
+                                volumeStore.setErrorString(msg);
+                                s_logger.info(msg);
+                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
+                                    s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as failed");
+                                    _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+                                    // mark volume as failed, so that storage GC will clean it up
+                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                                    volObj.processEvent(Event.OperationFailed);
+                                } else if (volumeStore.getDownloadUrl() == null) {
+                                    msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: "
+                                            + volumeStore.getDataStoreId();
+                                    s_logger.warn(msg);
+                                } else {
+                                    s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
+                                    _volumeStoreDao.remove(volumeStore.getId());
+                                    toBeDownloaded.add(volumeStore);
+                                }
+                            } else { // Put them in right status
+                                volumeStore.setDownloadPercent(100);
+                                volumeStore.setDownloadState(Status.DOWNLOADED);
+                                volumeStore.setState(ObjectInDataStoreStateMachine.State.Ready);
+                                volumeStore.setInstallPath(volInfo.getInstallPath());
+                                volumeStore.setSize(volInfo.getSize());
+                                volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
+                                volumeStore.setLastUpdated(new Date());
+                                _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+
+                                if (volume.getSize() == 0) {
+                                    // Set volume size in volumes table
+                                    volume.setSize(volInfo.getSize());
+                                    volDao.update(volumeStore.getVolumeId(), volume);
+                                }
+
+                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
+                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                                    volObj.processEvent(Event.OperationSuccessed);
+                                }
+
+                                if (volInfo.getSize() > 0) {
+                                    try {
+                                        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage,
+                                                volInfo.getSize() - volInfo.getPhysicalSize());
+                                    } catch (ResourceAllocationException e) {
+                                        s_logger.warn(e.getMessage());
+                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
+                                    } finally {
+                                        _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
+                                                com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
+                                    }
+                                }
+                            }
+                            continue;
+                        } else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) { // failed uploads through SSVM
+                            s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
+                            toBeDownloaded.remove(volumeStore);
+                            volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
+                            String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
+                            volumeStore.setErrorString(msg);
+                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
+                            // mark volume as failed, so that storage GC will clean it up
+                            VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
+                            volObj.processEvent(Event.OperationFailed);
+                            continue;
+                        }
+                        // Volume is not on secondary but we should download.
+                        if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
+                            s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
+                        }
+                    }
+
+                    // Download volumes which haven't been downloaded yet.
+                    if (toBeDownloaded.size() > 0) {
+                        for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
+                            if (volumeHost.getDownloadUrl() == null) { // If url is null, skip downloading
+                                s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
+                                continue;
+                            }
+
+                            // if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which
+                            // means that this is a duplicate entry from migration of previous NFS to staging.
+                            if (store.getScope().getScopeType() == ScopeType.REGION) {
+                                if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED && volumeHost.getInstallPath() == null) {
+                                    s_logger.info("Skip sync volume for migration of previous NFS to object store");
+                                    continue;
+                                }
+                            }
+
+                            s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
+                            // reset volume status back to Allocated
+                            VolumeObject vol = (VolumeObject)volFactory.getVolume(volumeHost.getVolumeId());
+                            vol.processEvent(Event.OperationFailed); // reset back volume status
+                            // remove leftover volume_store_ref entry since re-download will create it again
+                            _volumeStoreDao.remove(volumeHost.getId());
+                            // get an updated volumeVO
+                            vol = (VolumeObject)volFactory.getVolume(volumeHost.getVolumeId());
+                            RegisterVolumePayload payload = new RegisterVolumePayload(volumeHost.getDownloadUrl(), volumeHost.getChecksum(), vol.getFormat().toString());
+                            vol.addPayload(payload);
+                            createVolumeAsync(vol, store);
+                        }
+                    }
+
+                    // Delete volumes which are not present on DB.
+                    for (Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
+                        Long uniqueName = entry.getKey();
+                        TemplateProp tInfo = entry.getValue();
+
+                        // we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
+                        VolumeObjectTO tmplTO = new VolumeObjectTO();
+                        tmplTO.setDataStore(store.getTO());
+                        tmplTO.setPath(tInfo.getInstallPath());
+                        tmplTO.setId(tInfo.getId());
+                        DeleteCommand dtCommand = new DeleteCommand(tmplTO);
+                        EndPoint ep = _epSelector.select(store);
+                        Answer answer = null;
+                        if (ep == null) {
+                            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                            s_logger.error(errMsg);
+                            answer = new Answer(dtCommand, false, errMsg);
+                        } else {
+                            answer = ep.sendMessage(dtCommand);
+                        }
+                        if (answer == null || !answer.getResult()) {
+                            s_logger.info("Failed to deleted volume at store: " + store.getName());
+
+                        } else {
+                            String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId;
+                            s_logger.info(description);
+                        }
+                    }
+                } finally {
+                    syncLock.unlock();
+                }
+            } else {
+                s_logger.info("Couldn't get global lock on " + lockString + ", another thread may be doing volume sync on data store " + storeId + " now.");
+            }
+        } finally {
+            syncLock.releaseRef();
+        }
+    }
+
+    private Map<Long, TemplateProp> listVolume(DataStore store) {
+        ListVolumeCommand cmd = new ListVolumeCommand(store.getTO(), store.getUri());
+        EndPoint ep = _epSelector.select(store);
+        Answer answer = null;
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            answer = new Answer(cmd, false, errMsg);
+        } else {
+            answer = ep.sendMessage(cmd);
+        }
+        if (answer != null && answer.getResult()) {
+            ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
+            return tanswer.getTemplateInfo();
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Can not list volumes for image store " + store.getId());
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public SnapshotInfo takeSnapshot(VolumeInfo volume) {
+        SnapshotInfo snapshot = null;
+        try {
+            snapshot = snapshotMgr.takeSnapshot(volume);
+        } catch (CloudRuntimeException cre) {
+            s_logger.error("Take snapshot: " + volume.getId() + " failed", cre);
+            throw cre;
+        } catch (Exception e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("unknown exception while taking snapshot for volume " + volume.getId() + " was caught", e);
+            }
+            throw new CloudRuntimeException("Failed to take snapshot", e);
+        }
+
+        return snapshot;
+    }
+
+    // For managed storage on Xen and VMware, we need to potentially make space for hypervisor snapshots.
+    // The disk offering can collect this information and pass it on to the volume that's about to be created.
+    // Ex. if you want a 10 GB CloudStack volume to reside on managed storage on Xen, this leads to an SR
+    // that is a total size of (10 GB * (hypervisorSnapshotReserveSpace / 100) + 10 GB).
+    @Override
+    public VolumeInfo updateHypervisorSnapshotReserveForVolume(DiskOffering diskOffering, long volumeId, HypervisorType hyperType) {
+        if (diskOffering != null && hyperType != null) {
+            Integer hypervisorSnapshotReserve = diskOffering.getHypervisorSnapshotReserve();
+
+            if (hyperType == HypervisorType.KVM) {
+                hypervisorSnapshotReserve = null;
+            } else if (hypervisorSnapshotReserve == null || hypervisorSnapshotReserve < 0) {
+                hypervisorSnapshotReserve = 0;
+            }
+
+            VolumeVO volume = volDao.findById(volumeId);
+
+            volume.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
+
+            volDao.update(volume.getId(), volume);
+        }
+
+        return volFactory.getVolume(volumeId);
+    }
+}
diff --git a/engine/storage/volume/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml b/engine/storage/volume/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml
similarity index 100%
rename from engine/storage/volume/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml
rename to engine/storage/volume/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-volume-core-context.xml
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls
deleted file mode 100644
index 8d7a696..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/data model.ucls
+++ /dev/null
@@ -1,75 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<class-diagram version="1.0.11" icons="true" always-add-relationships="false" generalizations="true" realizations="true" 
-  associations="true" dependencies="false" nesting-relationships="true">  
-  <interface id="1" corner="BOTTOM_RIGHT" language="java" 
-    name="org.apache.cloudstack.engine.subsystem.api.storage.DataObject" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java" binary="false">    
-    <position height="-1" width="-1" x="311" y="101"/>    
-    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true"/>      
-      <operations public="true" package="true" protected="true" private="true"/>    
-    </display>  
-  </interface>  
-  <interface id="2" corner="BOTTOM_RIGHT" language="java" 
-    name="org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java" binary="false">    
-    <position height="-1" width="-1" x="146" y="279"/>    
-    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true"/>      
-      <operations public="true" package="true" protected="true" private="true"/>    
-    </display>  
-  </interface>  
-  <interface id="3" corner="BOTTOM_RIGHT" language="java" 
-    name="org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java" binary="false">    
-    <position height="-1" width="-1" x="361" y="282"/>    
-    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true"/>      
-      <operations public="true" package="true" protected="true" private="true"/>    
-    </display>  
-  </interface>  
-  <interface id="4" corner="BOTTOM_RIGHT" language="java" 
-    name="org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo" project="cloud-engine-api" 
-    file="/cloud-engine-api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java" binary="false">    
-    <position height="-1" width="-1" x="573" y="292"/>    
-    <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" visibility="true">      
-      <attributes public="true" package="true" protected="true" private="true"/>      
-      <operations public="true" package="true" protected="true" private="true"/>    
-    </display>  
-  </interface>  
-  <generalization id="5">    
-    <end type="SOURCE" refId="3"/>    
-    <end type="TARGET" refId="1"/>  
-  </generalization>  
-  <generalization id="6">    
-    <end type="SOURCE" refId="4"/>    
-    <end type="TARGET" refId="1"/>  
-  </generalization>  
-  <generalization id="7">    
-    <end type="SOURCE" refId="2"/>    
-    <end type="TARGET" refId="1"/>  
-  </generalization>  
-  <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" 
-    visibility="true">    
-    <attributes public="true" package="true" protected="true" private="true"/>    
-    <operations public="true" package="true" protected="true" private="true"/>  
-  </classifier-display>  
-  <association-display labels="true" multiplicity="true"/>
-</class-diagram>
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
deleted file mode 100644
index ed9b398..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ /dev/null
@@ -1,694 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.volume;
-
-import java.util.Date;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering.DiskCacheMode;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.storage.encoding.EncodingType;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class VolumeObject implements VolumeInfo {
-    private static final Logger s_logger = Logger.getLogger(VolumeObject.class);
-    protected VolumeVO volumeVO;
-    private StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
-    protected DataStore dataStore;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    VolumeDataStoreDao volumeStoreDao;
-    @Inject
-    ObjectInDataStoreManager objectInStoreMgr;
-    @Inject
-    VMInstanceDao vmInstanceDao;
-    @Inject
-    DiskOfferingDao diskOfferingDao;
-    private Object payload;
-
-    public VolumeObject() {
-        _volStateMachine = Volume.State.getStateMachine();
-    }
-
-    protected void configure(DataStore dataStore, VolumeVO volumeVO) {
-        this.volumeVO = volumeVO;
-        this.dataStore = dataStore;
-    }
-
-    public static VolumeObject getVolumeObject(DataStore dataStore, VolumeVO volumeVO) {
-        VolumeObject vo = ComponentContext.inject(VolumeObject.class);
-        vo.configure(dataStore, volumeVO);
-        return vo;
-    }
-
-    @Override
-    public String getAttachedVmName() {
-        Long vmId = volumeVO.getInstanceId();
-        if (vmId != null) {
-            VMInstanceVO vm = vmInstanceDao.findById(vmId);
-
-            if (vm == null) {
-                return null;
-            }
-            return vm.getInstanceName();
-        }
-        return null;
-    }
-
-    @Override
-    public VirtualMachine getAttachedVM() {
-        Long vmId = volumeVO.getInstanceId();
-        if (vmId != null) {
-            VMInstanceVO vm = vmInstanceDao.findById(vmId);
-            return vm;
-        }
-        return null;
-    }
-    @Override
-    public String getUuid() {
-        return volumeVO.getUuid();
-    }
-
-    public void setUuid(String uuid) {
-        volumeVO.setUuid(uuid);
-    }
-
-    @Override
-    public String get_iScsiName() {
-        return volumeVO.get_iScsiName();
-    }
-
-    public void setSize(Long size) {
-        volumeVO.setSize(size);
-    }
-
-    @Override
-    public Volume.State getState() {
-        return volumeVO.getState();
-    }
-
-    @Override
-    public DataStore getDataStore() {
-        return dataStore;
-    }
-
-    @Override
-    public Long getSize() {
-        return volumeVO.getSize();
-    }
-
-    @Override
-    public Long getMinIops() {
-        return volumeVO.getMinIops();
-    }
-
-    @Override
-    public Long getMaxIops() {
-        return volumeVO.getMaxIops();
-    }
-
-    @Override
-    public Integer getHypervisorSnapshotReserve() {
-        return volumeVO.getHypervisorSnapshotReserve();
-    }
-
-    @Override
-    public boolean isDisplayVolume() {
-        return volumeVO.isDisplayVolume();
-    }
-
-    @Override
-    public boolean isDisplay() {
-        return volumeVO.isDisplay();
-    }
-
-    public long getVolumeId() {
-        return volumeVO.getId();
-    }
-
-    @Override
-    public boolean stateTransit(Volume.Event event) {
-        boolean result = false;
-        try {
-            volumeVO = volumeDao.findById(volumeVO.getId());
-            if (volumeVO != null) {
-                result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao);
-                volumeVO = volumeDao.findById(volumeVO.getId());
-            }
-        } catch (NoTransitionException e) {
-            String errorMessage = "Failed to transit volume: " + getVolumeId() + ", due to: " + e.toString();
-            s_logger.debug(errorMessage);
-            throw new CloudRuntimeException(errorMessage);
-        }
-        return result;
-    }
-
-    private DiskOfferingVO getDiskOfferingVO() {
-        if (getDiskOfferingId() != null) {
-            DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(getDiskOfferingId());
-            return diskOfferingVO;
-        }
-        return null;
-    }
-
-    @Override
-    public Long getBytesReadRate() {
-        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
-        if (diskOfferingVO != null) {
-            return diskOfferingVO.getBytesReadRate();
-        }
-        return null;
-    }
-
-    @Override
-    public Long getBytesWriteRate() {
-        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
-        if (diskOfferingVO != null) {
-            return diskOfferingVO.getBytesWriteRate();
-        }
-        return null;
-    }
-
-    @Override
-    public Long getIopsReadRate() {
-        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
-        if (diskOfferingVO != null) {
-            return diskOfferingVO.getIopsReadRate();
-        }
-        return null;
-    }
-
-    @Override
-    public Long getIopsWriteRate() {
-        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
-        if (diskOfferingVO != null) {
-            return diskOfferingVO.getIopsWriteRate();
-        }
-        return null;
-    }
-
-    @Override
-    public DiskCacheMode getCacheMode() {
-        DiskOfferingVO diskOfferingVO = getDiskOfferingVO();
-        if (diskOfferingVO != null) {
-            return diskOfferingVO.getCacheMode();
-        }
-        return null;
-    }
-
-    public void update() {
-        volumeDao.update(volumeVO.getId(), volumeVO);
-        volumeVO = volumeDao.findById(volumeVO.getId());
-    }
-
-    @Override
-    public long getId() {
-        return volumeVO.getId();
-    }
-
-    @Override
-    public boolean isAttachedVM() {
-        return (volumeVO.getInstanceId() == null) ? false : true;
-    }
-
-    @Override
-    public String getUri() {
-        if (dataStore == null) {
-            throw new CloudRuntimeException("datastore must be set before using this object");
-        }
-        DataObjectInStore obj = objectInStoreMgr.findObject(volumeVO.getId(), DataObjectType.VOLUME, dataStore.getId(), dataStore.getRole());
-        if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
-            return dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + EncodingType.SIZE + "=" + volumeVO.getSize() + "&" +
-                EncodingType.NAME + "=" + volumeVO.getName();
-        } else {
-            return dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + EncodingType.PATH + "=" + obj.getInstallPath();
-        }
-    }
-
-    @Override
-    public DataObjectType getType() {
-        return DataObjectType.VOLUME;
-    }
-
-    @Override
-    public void processEvent(ObjectInDataStoreStateMachine.Event event) {
-        if (dataStore == null) {
-            return;
-        }
-        try {
-            Volume.Event volEvent = null;
-            if (dataStore.getRole() == DataStoreRole.ImageCache) {
-                objectInStoreMgr.update(this, event);
-                return;
-            }
-            if (dataStore.getRole() == DataStoreRole.Image) {
-                objectInStoreMgr.update(this, event);
-                if (volumeVO.getState() == Volume.State.Migrating || volumeVO.getState() == Volume.State.Copying ||
-                    volumeVO.getState() == Volume.State.Uploaded || volumeVO.getState() == Volume.State.Expunged) {
-                    return;
-                }
-                if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
-                    volEvent = Volume.Event.UploadRequested;
-                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) {
-                    volEvent = Volume.Event.CopyRequested;
-                }
-            } else {
-                if (event == ObjectInDataStoreStateMachine.Event.CreateRequested || event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
-                    volEvent = Volume.Event.CreateRequested;
-                } else if (event == ObjectInDataStoreStateMachine.Event.CopyingRequested) {
-                    volEvent = Volume.Event.CopyRequested;
-                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) {
-                    volEvent = Volume.Event.MigrationRequested;
-                } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopyRequested) {
-                    volEvent = Event.MigrationCopyRequested;
-                }
-            }
-
-            if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) {
-                volEvent = Volume.Event.DestroyRequested;
-            } else if (event == ObjectInDataStoreStateMachine.Event.ExpungeRequested) {
-                volEvent = Volume.Event.ExpungingRequested;
-            } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) {
-                volEvent = Volume.Event.OperationSucceeded;
-            } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopySucceeded) {
-              volEvent = Event.MigrationCopySucceeded;
-            } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                volEvent = Volume.Event.OperationFailed;
-            } else if (event == ObjectInDataStoreStateMachine.Event.MigrationCopyFailed) {
-              volEvent = Event.MigrationCopyFailed;
-            } else if (event == ObjectInDataStoreStateMachine.Event.ResizeRequested) {
-                volEvent = Volume.Event.ResizeRequested;
-            }
-            stateTransit(volEvent);
-        } catch (Exception e) {
-            s_logger.debug("Failed to update state", e);
-            throw new CloudRuntimeException("Failed to update state:" + e.toString());
-        } finally {
-            // in case of OperationFailed, expunge the entry
-            // state transit call reloads the volume from DB and so check for null as well
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed &&
-                (volumeVO != null && volumeVO.getState() != Volume.State.Copying && volumeVO.getState() != Volume.State.Uploaded && volumeVO.getState() != Volume.State.UploadError)) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-        }
-    }
-
-    @Override
-    public void processEventOnly(ObjectInDataStoreStateMachine.Event event) {
-        try {
-            objectInStoreMgr.update(this, event);
-        } catch (Exception e) {
-            s_logger.debug("Failed to update state", e);
-            throw new CloudRuntimeException("Failed to update state:" + e.toString());
-        } finally {
-            // in case of OperationFailed, expunge the entry
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-        }
-    }
-
-    @Override
-    public String getName() {
-        return volumeVO.getName();
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return volumeVO.getInstanceId();
-    }
-
-    @Override
-    public String getFolder() {
-        return volumeVO.getFolder();
-    }
-
-    @Override
-    public String getPath() {
-        if (dataStore.getRole() == DataStoreRole.Primary) {
-            return volumeVO.getPath();
-        } else {
-            DataObjectInStore objInStore = objectInStoreMgr.findObject(this, dataStore);
-            if (objInStore != null) {
-                return objInStore.getInstallPath();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    @Override
-    public Long getPodId() {
-        return volumeVO.getPodId();
-    }
-
-    @Override
-    public long getDataCenterId() {
-        return volumeVO.getDataCenterId();
-    }
-
-    @Override
-    public Type getVolumeType() {
-        return volumeVO.getVolumeType();
-    }
-
-    @Override
-    public Long getPoolId() {
-        return volumeVO.getPoolId();
-    }
-
-    @Override
-    public Date getAttached() {
-        return volumeVO.getAttached();
-    }
-
-    @Override
-    public Long getDeviceId() {
-        return volumeVO.getDeviceId();
-    }
-
-    @Override
-    public Date getCreated() {
-        return volumeVO.getCreated();
-    }
-
-    @Override
-    public Long getDiskOfferingId() {
-        return volumeVO.getDiskOfferingId();
-    }
-
-    @Override
-    public String getChainInfo() {
-        return volumeVO.getChainInfo();
-    }
-
-    @Override
-    public boolean isRecreatable() {
-        return volumeVO.isRecreatable();
-    }
-
-    @Override
-    public long getUpdatedCount() {
-        return volumeVO.getUpdatedCount();
-    }
-
-    @Override
-    public void incrUpdatedCount() {
-        volumeVO.incrUpdatedCount();
-    }
-
-    @Override
-    public Date getUpdated() {
-        return volumeVO.getUpdated();
-    }
-
-    @Override
-    public String getReservationId() {
-        return volumeVO.getReservationId();
-    }
-
-    @Override
-    public void setReservationId(String reserv) {
-        volumeVO.setReservationId(reserv);
-    }
-
-    @Override
-    public long getAccountId() {
-        return volumeVO.getAccountId();
-    }
-
-    @Override
-    public long getDomainId() {
-        return volumeVO.getDomainId();
-    }
-
-    @Override
-    public Long getTemplateId() {
-        return volumeVO.getTemplateId();
-    }
-
-    @Override
-    public void addPayload(Object data) {
-        payload = data;
-    }
-
-    @Override
-    public Object getpayload() {
-        return payload;
-    }
-
-    public VolumeVO getVolume() {
-        return volumeVO;
-    }
-
-    @Override
-    public HypervisorType getHypervisorType() {
-        return volumeDao.getHypervisorType(volumeVO.getId());
-    }
-
-    @Override
-    public Long getLastPoolId() {
-        return volumeVO.getLastPoolId();
-    }
-
-    @Override
-    public DataTO getTO() {
-        DataTO to = getDataStore().getDriver().getTO(this);
-        if (to == null) {
-            to = new VolumeObjectTO(this);
-        }
-        return to;
-    }
-
-    @Override
-    public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
-        try {
-            if (dataStore.getRole() == DataStoreRole.Primary) {
-                if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    VolumeVO vol = volumeDao.findById(getId());
-                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
-                    vol.setPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        // Root disk resize may be requested where the original
-                        // template size is less than the requested root disk size
-                        if (vol.getSize() == null || vol.getSize() < newVol.getSize()) {
-                            vol.setSize(newVol.getSize());
-                        }
-                    }
-                    if (newVol.getFormat() != null) {
-                        vol.setFormat(newVol.getFormat());
-                    }
-                    vol.setPoolId(getDataStore().getId());
-                    volumeDao.update(vol.getId(), vol);
-                } else if (answer instanceof CreateObjectAnswer) {
-                    CreateObjectAnswer createAnswer = (CreateObjectAnswer)answer;
-                    VolumeObjectTO newVol = (VolumeObjectTO)createAnswer.getData();
-                    VolumeVO vol = volumeDao.findById(getId());
-                    vol.setPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        vol.setSize(newVol.getSize());
-                    }
-                    vol.setPoolId(getDataStore().getId());
-                    if (newVol.getFormat() != null) {
-                        vol.setFormat(newVol.getFormat());
-                    }
-                    volumeDao.update(vol.getId(), vol);
-                }
-            } else {
-                // image store or imageCache store
-                if (answer instanceof DownloadAnswer) {
-                    DownloadAnswer dwdAnswer = (DownloadAnswer)answer;
-                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-                    volStore.setInstallPath(dwdAnswer.getInstallPath());
-                    volStore.setChecksum(dwdAnswer.getCheckSum());
-                    volumeStoreDao.update(volStore.getId(), volStore);
-                } else if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
-                    volStore.setInstallPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        volStore.setSize(newVol.getSize());
-                    }
-                    volumeStoreDao.update(volStore.getId(), volStore);
-                }
-            }
-        } catch (RuntimeException ex) {
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-            throw ex;
-        }
-        this.processEvent(event);
-
-    }
-
-    @Override
-    public void incRefCount() {
-        if (dataStore == null) {
-            return;
-        }
-
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-            store.incrRefCnt();
-            store.setLastUpdated(new Date());
-            volumeStoreDao.update(store.getId(), store);
-        }
-    }
-
-    @Override
-    public void decRefCount() {
-        if (dataStore == null) {
-            return;
-        }
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-            store.decrRefCnt();
-            store.setLastUpdated(new Date());
-            volumeStoreDao.update(store.getId(), store);
-        }
-    }
-
-    @Override
-    public Long getRefCount() {
-        if (dataStore == null) {
-            return null;
-        }
-        if (dataStore.getRole() == DataStoreRole.Image || dataStore.getRole() == DataStoreRole.ImageCache) {
-            VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-            return store.getRefCnt();
-        }
-        return null;
-    }
-
-    @Override
-    public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer) {
-        try {
-            if (dataStore.getRole() == DataStoreRole.Primary) {
-                if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    VolumeVO vol = volumeDao.findById(getId());
-                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
-                    vol.setPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        vol.setSize(newVol.getSize());
-                    }
-                    vol.setPoolId(getDataStore().getId());
-                    volumeDao.update(vol.getId(), vol);
-                } else if (answer instanceof CreateObjectAnswer) {
-                    CreateObjectAnswer createAnswer = (CreateObjectAnswer)answer;
-                    VolumeObjectTO newVol = (VolumeObjectTO)createAnswer.getData();
-                    VolumeVO vol = volumeDao.findById(getId());
-                    vol.setPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        vol.setSize(newVol.getSize());
-                    }
-                    vol.setPoolId(getDataStore().getId());
-                    volumeDao.update(vol.getId(), vol);
-                }
-            } else {
-                // image store or imageCache store
-                if (answer instanceof DownloadAnswer) {
-                    DownloadAnswer dwdAnswer = (DownloadAnswer)answer;
-                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-                    volStore.setInstallPath(dwdAnswer.getInstallPath());
-                    volStore.setChecksum(dwdAnswer.getCheckSum());
-                    volumeStoreDao.update(volStore.getId(), volStore);
-                } else if (answer instanceof CopyCmdAnswer) {
-                    CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
-                    VolumeDataStoreVO volStore = volumeStoreDao.findByStoreVolume(dataStore.getId(), getId());
-                    VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData();
-                    volStore.setInstallPath(newVol.getPath());
-                    if (newVol.getSize() != null) {
-                        volStore.setSize(newVol.getSize());
-                    }
-                    volumeStoreDao.update(volStore.getId(), volStore);
-                }
-            }
-        } catch (RuntimeException ex) {
-            if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
-                objectInStoreMgr.deleteIfNotReady(this);
-            }
-            throw ex;
-        }
-        this.processEventOnly(event);
-
-    }
-
-    @Override
-    public ImageFormat getFormat() {
-        return volumeVO.getFormat();
-    }
-
-    @Override
-    public ProvisioningType getProvisioningType(){
-        return this.volumeVO.getProvisioningType();
-    }
-
-    @Override
-    public boolean delete() {
-        if (dataStore != null) {
-            return dataStore.delete(this);
-        }
-        return true;
-    }
-
-    @Override
-    public Long getVmSnapshotChainSize() {
-        return volumeVO.getVmSnapshotChainSize();
-    }
-
-    @Override
-    public Class<?> getEntityType() {
-        return Volume.class;
-    }
-}
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
deleted file mode 100644
index 4abb190..0000000
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ /dev/null
@@ -1,2085 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.volume;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.async.AsyncRpcContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.RemoteHostEndPoint;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.store.TemplateObject;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.storage.ResizeVolumeCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.DiskOffering;
-import com.cloud.org.Cluster;
-import com.cloud.org.Grouping.AllocationState;
-import com.cloud.resource.ResourceState;
-import com.cloud.server.ManagementService;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.RegisterVolumePayload;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.Volume;
-import com.cloud.storage.Volume.State;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class VolumeServiceImpl implements VolumeService {
-    private static final Logger s_logger = Logger.getLogger(VolumeServiceImpl.class);
-    @Inject
-    protected AgentManager agentMgr;
-    @Inject
-    VolumeDao volDao;
-    @Inject
-    PrimaryDataStoreProviderManager dataStoreMgr;
-    @Inject
-    DataMotionService motionSrv;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    SnapshotManager snapshotMgr;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    AlertManager _alertMgr;
-    @Inject
-    ConfigurationDao configDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    VMTemplatePoolDao _tmpltPoolDao;
-    @Inject
-    SnapshotDataStoreDao _snapshotStoreDao;
-    @Inject
-    VolumeDao _volumeDao;
-    @Inject
-    EndPointSelector _epSelector;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    private PrimaryDataStoreDao storagePoolDao;
-    @Inject
-    private HostDetailsDao hostDetailsDao;
-    @Inject
-    private ManagementService mgr;
-    @Inject
-    private ClusterDao clusterDao;
-    @Inject
-    private VolumeDetailsDao _volumeDetailsDao;
-
-    private final static String SNAPSHOT_ID = "SNAPSHOT_ID";
-
-    public VolumeServiceImpl() {
-    }
-
-    private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
-
-        private final DataObject volume;
-        private final AsyncCallFuture<VolumeApiResult> future;
-
-        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume, AsyncCallFuture<VolumeApiResult> future) {
-            super(callback);
-            this.volume = volume;
-            this.future = future;
-        }
-
-        public DataObject getVolume() {
-            return this.volume;
-        }
-
-        public AsyncCallFuture<VolumeApiResult> getFuture() {
-            return this.future;
-        }
-
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject, DataStore dataStore) {
-        DataStoreDriver dataStoreDriver = dataStore.getDriver();
-
-        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
-            return ((PrimaryDataStoreDriver)dataStoreDriver).getChapInfo(dataObject);
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
-
-        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
-            return ((PrimaryDataStoreDriver)dataStoreDriver).grantAccess(dataObject, host, dataStore);
-        }
-
-        return false;
-    }
-
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
-        if (dataStoreDriver == null) {
-            return;
-        }
-
-        if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
-            ((PrimaryDataStoreDriver)dataStoreDriver).revokeAccess(dataObject, host, dataStore);
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore dataStore) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        DataObject volumeOnStore = dataStore.create(volume);
-        volumeOnStore.processEvent(Event.CreateOnlyRequested);
-
-        try {
-            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context);
-
-            dataStore.getDriver().createAsync(dataStore, volumeOnStore, caller);
-        } catch (CloudRuntimeException ex) {
-            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
-            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(dataStore.getId(), volume.getId());
-            if (volStoreVO != null) {
-                VolumeInfo volObj = volFactory.getVolume(volume, dataStore);
-                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-            }
-            VolumeApiResult volResult = new VolumeApiResult((VolumeObject)volumeOnStore);
-            volResult.setResult(ex.getMessage());
-            future.complete(volResult);
-        }
-        return future;
-    }
-
-    protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
-        CreateCmdResult result = callback.getResult();
-        DataObject vo = context.getVolume();
-        String errMsg = null;
-        if (result.isSuccess()) {
-            vo.processEvent(Event.OperationSuccessed, result.getAnswer());
-        } else {
-            vo.processEvent(Event.OperationFailed);
-            errMsg = result.getResult();
-        }
-        VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
-        if (errMsg != null) {
-            volResult.setResult(errMsg);
-        }
-        context.getFuture().complete(volResult);
-        return null;
-    }
-
-    private class DeleteVolumeContext<T> extends AsyncRpcContext<T> {
-        private final VolumeObject volume;
-        private final AsyncCallFuture<VolumeApiResult> future;
-
-        public DeleteVolumeContext(AsyncCompletionCallback<T> callback, VolumeObject volume, AsyncCallFuture<VolumeApiResult> future) {
-            super(callback);
-            this.volume = volume;
-            this.future = future;
-        }
-
-        public VolumeObject getVolume() {
-            return this.volume;
-        }
-
-        public AsyncCallFuture<VolumeApiResult> getFuture() {
-            return this.future;
-        }
-    }
-
-    // check if a volume is expunged on both primary and secondary
-    private boolean canVolumeBeRemoved(long volumeId) {
-        VolumeVO vol = volDao.findById(volumeId);
-        if (vol == null) {
-            // already removed from volumes table
-            return false;
-        }
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volumeId);
-        if ((vol.getState() == State.Expunged || (vol.getPodId() == null && vol.getState() == State.Destroy)) && volumeStore == null) {
-            // volume is expunged from primary, as well as on secondary
-            return true;
-        } else {
-            return false;
-        }
-
-    }
-
-    @DB
-    @Override
-    public AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult result = new VolumeApiResult(volume);
-        if (volume.getDataStore() == null) {
-            s_logger.info("Expunge volume with no data store specified");
-            if (canVolumeBeRemoved(volume.getId())) {
-                s_logger.info("Volume " + volume.getId() + " is not referred anywhere, remove it from volumes table");
-                volDao.remove(volume.getId());
-            }
-            future.complete(result);
-            return future;
-        }
-
-        // Find out if the volume is at state of download_in_progress on secondary storage
-        VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
-        if (volumeStore != null) {
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                s_logger.debug("Volume: " + volume.getName() + " is currently being uploaded; cant' delete it.");
-                future.complete(result);
-                return future;
-            }
-        }
-
-        VolumeVO vol = volDao.findById(volume.getId());
-        if (vol == null) {
-            s_logger.debug("Volume " + volume.getId() + " is not found");
-            future.complete(result);
-            return future;
-        }
-
-        if (!volumeExistsOnPrimary(vol)) {
-            // not created on primary store
-            if (volumeStore == null) {
-                // also not created on secondary store
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Marking volume that was never created as destroyed: " + vol);
-                }
-                volDao.remove(vol.getId());
-                future.complete(result);
-                return future;
-            }
-        }
-        VolumeObject vo = (VolumeObject)volume;
-
-        if (volume.getDataStore().getRole() == DataStoreRole.Image) {
-            // no need to change state in volumes table
-            volume.processEventOnly(Event.DestroyRequested);
-        } else if (volume.getDataStore().getRole() == DataStoreRole.Primary) {
-            volume.processEvent(Event.ExpungeRequested);
-        }
-
-        DeleteVolumeContext<VolumeApiResult> context = new DeleteVolumeContext<VolumeApiResult>(null, vo, future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)).setContext(context);
-
-        volume.getDataStore().getDriver().deleteAsync(volume.getDataStore(), volume, caller);
-        return future;
-    }
-
-    private boolean volumeExistsOnPrimary(VolumeVO vol) {
-        Long poolId = vol.getPoolId();
-
-        if (poolId == null) {
-            return false;
-        }
-
-        PrimaryDataStore primaryStore = dataStoreMgr.getPrimaryDataStore(poolId);
-
-        if (primaryStore == null) {
-            return false;
-        }
-
-        if (primaryStore.isManaged()) {
-            return true;
-        }
-
-        String volumePath = vol.getPath();
-
-        if (volumePath == null || volumePath.trim().isEmpty()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public Void deleteVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CommandResult> callback, DeleteVolumeContext<VolumeApiResult> context) {
-        CommandResult result = callback.getResult();
-        VolumeObject vo = context.getVolume();
-        VolumeApiResult apiResult = new VolumeApiResult(vo);
-        try {
-            if (result.isSuccess()) {
-                vo.processEvent(Event.OperationSuccessed);
-                if (canVolumeBeRemoved(vo.getId())) {
-                    s_logger.info("Volume " + vo.getId() + " is not referred anywhere, remove it from volumes table");
-                    volDao.remove(vo.getId());
-                }
-
-                SnapshotDataStoreVO snapStoreVo = _snapshotStoreDao.findByVolume(vo.getId(), DataStoreRole.Primary);
-
-                if (snapStoreVo != null) {
-                    long storagePoolId = snapStoreVo.getDataStoreId();
-                    StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId);
-
-                    if (storagePoolVO.isManaged()) {
-                        DataStore primaryDataStore = dataStoreMgr.getPrimaryDataStore(storagePoolId);
-                        Map<String, String> mapCapabilities = primaryDataStore.getDriver().getCapabilities();
-
-                        String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
-                        Boolean supportsStorageSystemSnapshots = new Boolean(value);
-
-                        if (!supportsStorageSystemSnapshots) {
-                            _snapshotStoreDao.remove(snapStoreVo.getId());
-                        }
-                    } else {
-                        _snapshotStoreDao.remove(snapStoreVo.getId());
-                    }
-                }
-            } else {
-                vo.processEvent(Event.OperationFailed);
-                apiResult.setResult(result.getResult());
-            }
-        } catch (Exception e) {
-            s_logger.debug("ignore delete volume status update failure, it will be picked up by storage clean up thread later", e);
-        }
-        context.getFuture().complete(apiResult);
-        return null;
-    }
-
-    @Override
-    public boolean cloneVolume(long volumeId, long baseVolId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public VolumeEntity getVolumeEntity(long volumeId) {
-        return null;
-    }
-
-    private class ManagedCreateBaseImageContext<T> extends AsyncRpcContext<T> {
-        private final VolumeInfo _volumeInfo;
-        private final PrimaryDataStore _primaryDataStore;
-        private final TemplateInfo _templateInfo;
-        private final AsyncCallFuture<VolumeApiResult> _future;
-
-        public ManagedCreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volumeInfo, PrimaryDataStore primaryDatastore, TemplateInfo templateInfo,
-                AsyncCallFuture<VolumeApiResult> future) {
-            super(callback);
-
-            _volumeInfo = volumeInfo;
-            _primaryDataStore = primaryDatastore;
-            _templateInfo = templateInfo;
-            _future = future;
-        }
-
-        public VolumeInfo getVolumeInfo() {
-            return _volumeInfo;
-        }
-
-        public PrimaryDataStore getPrimaryDataStore() {
-            return _primaryDataStore;
-        }
-
-        public TemplateInfo getTemplateInfo() {
-            return _templateInfo;
-        }
-
-        public AsyncCallFuture<VolumeApiResult> getFuture() {
-            return _future;
-        }
-    }
-
-    class CreateBaseImageContext<T> extends AsyncRpcContext<T> {
-        private final VolumeInfo volume;
-        private final PrimaryDataStore dataStore;
-        private final TemplateInfo srcTemplate;
-        private final AsyncCallFuture<VolumeApiResult> future;
-        final DataObject destObj;
-        long templatePoolId;
-
-        public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture<VolumeApiResult> future,
-                DataObject destObj, long templatePoolId) {
-            super(callback);
-            this.volume = volume;
-            this.dataStore = datastore;
-            this.future = future;
-            this.srcTemplate = srcTemplate;
-            this.destObj = destObj;
-            this.templatePoolId = templatePoolId;
-        }
-
-        public VolumeInfo getVolume() {
-            return this.volume;
-        }
-
-        public PrimaryDataStore getDataStore() {
-            return this.dataStore;
-        }
-
-        public TemplateInfo getSrcTemplate() {
-            return this.srcTemplate;
-        }
-
-        public AsyncCallFuture<VolumeApiResult> getFuture() {
-            return this.future;
-        }
-
-        public long getTemplatePoolId() {
-            return templatePoolId;
-        }
-
-    }
-
-    private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) {
-        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
-        int sleepTime = 120;
-        int tries = storagePoolMaxWaitSeconds / sleepTime;
-        while (tries > 0) {
-            TemplateInfo tmpl = store.getTemplate(template.getId());
-            if (tmpl != null) {
-                return tmpl;
-            }
-            try {
-                Thread.sleep(sleepTime * 1000);
-            } catch (InterruptedException e) {
-                s_logger.debug("waiting for template download been interrupted: " + e.toString());
-            }
-            tries--;
-        }
-        return null;
-    }
-
-    @DB
-    protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
-        DataObject templateOnPrimaryStoreObj = dataStore.create(template);
-
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
-        if (templatePoolRef == null) {
-            throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + templatePoolRef.getId());
-            }
-        }
-        long templatePoolRefId = templatePoolRef.getId();
-        CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context);
-
-        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Acquire lock on VMTemplateStoragePool " + templatePoolRefId + " with timeout " + storagePoolMaxWaitSeconds + " seconds");
-        }
-        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
-
-        if (templatePoolRef == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId);
-            }
-            templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
-            if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
-                s_logger.info(
-                        "Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
-                createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
-                return;
-            }
-            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.info("lock is acquired for VMTemplateStoragePool " + templatePoolRefId);
-        }
-        try {
-            if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
-                s_logger.info("Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
-                createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
-                return;
-            }
-            templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
-            motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);
-        } catch (Throwable e) {
-            s_logger.debug("failed to create template on storage", e);
-            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
-            dataStore.create(template);  // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
-            VolumeApiResult result = new VolumeApiResult(volume);
-            result.setResult(e.toString());
-            future.complete(result);
-        } finally {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.info("releasing lock for VMTemplateStoragePool " + templatePoolRefId);
-            }
-            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
-        }
-        return;
-    }
-
-    protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, ManagedCreateBaseImageContext<VolumeApiResult> context) {
-        CopyCommandResult result = callback.getResult();
-        VolumeInfo volumeInfo = context.getVolumeInfo();
-        VolumeApiResult res = new VolumeApiResult(volumeInfo);
-
-        if (result.isSuccess()) {
-            // volumeInfo.processEvent(Event.OperationSuccessed, result.getAnswer());
-
-            VolumeVO volume = volDao.findById(volumeInfo.getId());
-            CopyCmdAnswer answer = (CopyCmdAnswer)result.getAnswer();
-            TemplateObjectTO templateObjectTo = (TemplateObjectTO)answer.getNewData();
-
-            volume.setPath(templateObjectTo.getPath());
-
-            if (templateObjectTo.getFormat() != null) {
-                volume.setFormat(templateObjectTo.getFormat());
-            }
-
-            volDao.update(volume.getId(), volume);
-        } else {
-            volumeInfo.processEvent(Event.DestroyRequested);
-
-            res.setResult(result.getResult());
-        }
-
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-
-        future.complete(res);
-
-        return null;
-    }
-
-    protected Void createManagedTemplateImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<CreateCmdResult> context) {
-        CreateCmdResult result = callback.getResult();
-        VolumeApiResult res = new VolumeApiResult(null);
-
-        res.setResult(result.getResult());
-
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-        DataObject templateOnPrimaryStoreObj = context.getVolume();
-
-        if (result.isSuccess()) {
-            ((TemplateObject)templateOnPrimaryStoreObj).setInstallPath(result.getPath());
-            templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
-        } else {
-            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
-        }
-
-        future.complete(res);
-
-        return null;
-    }
-
-    protected Void copyManagedTemplateCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
-        CopyCommandResult result = callback.getResult();
-        VolumeApiResult res = new VolumeApiResult(context.getVolume());
-
-        res.setResult(result.getResult());
-
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-        DataObject templateOnPrimaryStoreObj = context.destObj;
-
-        if (result.isSuccess()) {
-            templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
-        } else {
-            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
-        }
-
-        future.complete(res);
-
-        return null;
-    }
-
-    @DB
-    protected Void copyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateBaseImageContext<VolumeApiResult> context) {
-        CopyCommandResult result = callback.getResult();
-        VolumeApiResult res = new VolumeApiResult(context.getVolume());
-
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-        DataObject templateOnPrimaryStoreObj = context.destObj;
-        if (!result.isSuccess()) {
-            templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
-            res.setResult(result.getResult());
-            future.complete(res);
-            return null;
-        }
-
-        templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
-        createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future);
-        return null;
-    }
-
-    private class CreateVolumeFromBaseImageContext<T> extends AsyncRpcContext<T> {
-        private final DataObject vo;
-        private final AsyncCallFuture<VolumeApiResult> future;
-        private final DataObject templateOnStore;
-        private final SnapshotInfo snapshot;
-
-        public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture<VolumeApiResult> future,
-                SnapshotInfo snapshot) {
-            super(callback);
-            this.vo = vo;
-            this.future = future;
-            this.templateOnStore = templateOnStore;
-            this.snapshot = snapshot;
-        }
-
-        public AsyncCallFuture<VolumeApiResult> getFuture() {
-            return this.future;
-        }
-    }
-
-    @DB
-    protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
-        DataObject volumeOnPrimaryStorage = pd.create(volume);
-        volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested);
-
-        CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
-        caller.setContext(context);
-
-        motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
-        return;
-    }
-
-    @DB
-    protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
-        DataObject vo = context.vo;
-        DataObject tmplOnPrimary = context.templateOnStore;
-        CopyCommandResult result = callback.getResult();
-        VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
-
-        if (result.isSuccess()) {
-            vo.processEvent(Event.OperationSuccessed, result.getAnswer());
-        } else {
-
-            vo.processEvent(Event.OperationFailed);
-            volResult.setResult(result.getResult());
-            // hack for Vmware: host is down, previously download template to the host needs to be re-downloaded, so we need to reset
-            // template_spool_ref entry here to NOT_DOWNLOADED and Allocated state
-            Answer ans = result.getAnswer();
-            if (ans != null && ans instanceof CopyCmdAnswer && ans.getDetails().contains("request template reload")) {
-                if (tmplOnPrimary != null) {
-                    s_logger.info("Reset template_spool_ref entry so that vmware template can be reloaded in next try");
-                    VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(tmplOnPrimary.getDataStore().getId(), tmplOnPrimary.getId());
-                    if (templatePoolRef != null) {
-                        long templatePoolRefId = templatePoolRef.getId();
-                        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, 1200);
-                        try {
-                            if (templatePoolRef == null) {
-                                s_logger.warn("Reset Template State On Pool failed - unable to lock TemplatePoolRef " + templatePoolRefId);
-                            } else {
-                                templatePoolRef.setTemplateSize(0);
-                                templatePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
-                                templatePoolRef.setState(ObjectInDataStoreStateMachine.State.Allocated);
-
-                                _tmpltPoolDao.update(templatePoolRefId, templatePoolRef);
-                            }
-                        } finally {
-                            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
-                        }
-                    }
-                }
-            }
-        }
-
-        AsyncCallFuture<VolumeApiResult> future = context.getFuture();
-        future.complete(volResult);
-        return null;
-    }
-
-    /**
-     * Creates a template volume on managed storage, which will be used for creating ROOT volumes by cloning.
-     *
-     * @param srcTemplateInfo Source template on secondary storage
-     * @param destPrimaryDataStore Managed storage on which we need to create the volume
-     */
-    private TemplateInfo createManagedTemplateVolume(TemplateInfo srcTemplateInfo, PrimaryDataStore destPrimaryDataStore) {
-        // create a template volume on primary storage
-        AsyncCallFuture<VolumeApiResult> createTemplateFuture = new AsyncCallFuture<>();
-        TemplateInfo templateOnPrimary = (TemplateInfo)destPrimaryDataStore.create(srcTemplateInfo);
-
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
-
-        if (templatePoolRef == null) {
-            throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
-        }
-
-        // At this point, we have an entry in the DB that points to our cached template.
-        // We need to lock it as there may be other VMs that may get started using the same template.
-        // We want to avoid having to create multiple cache copies of the same template.
-
-        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
-        long templatePoolRefId = templatePoolRef.getId();
-
-        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
-
-        if (templatePoolRef == null) {
-            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
-        }
-
-        // Template already exists
-        if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
-            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
-
-            return templateOnPrimary;
-        }
-
-        try {
-            // create a cache volume on the back-end
-
-            templateOnPrimary.processEvent(Event.CreateOnlyRequested);
-
-            CreateVolumeContext<CreateCmdResult> createContext = new CreateVolumeContext<>(null, templateOnPrimary, createTemplateFuture);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> createCaller = AsyncCallbackDispatcher.create(this);
-
-            createCaller.setCallback(createCaller.getTarget().createManagedTemplateImageCallback(null, null)).setContext(createContext);
-
-            destPrimaryDataStore.getDriver().createAsync(destPrimaryDataStore, templateOnPrimary, createCaller);
-
-            VolumeApiResult result = createTemplateFuture.get();
-
-            if (result.isFailed()) {
-                String errMesg = result.getResult();
-
-                throw new CloudRuntimeException("Unable to create template " + templateOnPrimary.getId() + " on primary storage " + destPrimaryDataStore.getId() + ":" + errMesg);
-            }
-        } catch (Throwable e) {
-            s_logger.debug("Failed to create template volume on storage", e);
-
-            templateOnPrimary.processEvent(Event.OperationFailed);
-
-            throw new CloudRuntimeException(e.getMessage());
-        } finally {
-            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
-        }
-
-        return templateOnPrimary;
-    }
-
-    /**
-     * This function copies a template from secondary storage to a template volume
-     * created on managed storage. This template volume will be used as a cache.
-     * Instead of copying the template to a ROOT volume every time, a clone is performed instead.
-     *
-     * @param srcTemplateInfo Source from which to copy the template
-     * @param templateOnPrimary Dest to copy to
-     * @param templatePoolRef Template reference on primary storage (entry in the template_spool_ref)
-     * @param destPrimaryDataStore The managed primary storage
-     * @param destHost The host that we will use for the copy
-     */
-    private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore,
-            Host destHost) {
-        AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
-        int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
-        long templatePoolRefId = templatePoolRef.getId();
-
-        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
-
-        if (templatePoolRef == null) {
-            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
-        }
-
-        if (templatePoolRef.getDownloadState() == Status.DOWNLOADED) {
-            // There can be cases where we acquired the lock, but the template
-            // was already copied by a previous thread. Just return in that case.
-
-            s_logger.debug("Template already downloaded, nothing to do");
-
-            return;
-        }
-
-        try {
-            // copy the template from sec storage to the created volume
-            CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(null, null, destPrimaryDataStore, srcTemplateInfo, copyTemplateFuture, templateOnPrimary,
-                    templatePoolRefId);
-
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
-            copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
-
-            // Populate details which will be later read by the storage subsystem.
-            Map<String, String> details = new HashMap<>();
-
-            details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
-            details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
-            details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
-            details.put(PrimaryDataStore.MANAGED_STORE_TARGET, templateOnPrimary.getInstallPath());
-            details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, srcTemplateInfo.getUniqueName());
-            details.put(PrimaryDataStore.REMOVE_AFTER_COPY, Boolean.TRUE.toString());
-            details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(templateOnPrimary.getSize()));
-
-            ChapInfo chapInfo = getChapInfo(templateOnPrimary, destPrimaryDataStore);
-
-            if (chapInfo != null) {
-                details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
-                details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
-                details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
-                details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
-            }
-
-            templateOnPrimary.processEvent(Event.CopyingRequested);
-
-            destPrimaryDataStore.setDetails(details);
-
-            grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
-
-            VolumeApiResult result;
-
-            try {
-                motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
-
-                result = copyTemplateFuture.get();
-            } finally {
-                revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
-
-                if (HypervisorType.VMware.equals(destHost.getHypervisorType())) {
-                    details.put(ModifyTargetsCommand.IQN, templateOnPrimary.getInstallPath());
-
-                    List<Map<String, String>> targets = new ArrayList<>();
-
-                    targets.add(details);
-
-                    removeDynamicTargets(destHost.getId(), targets);
-                }
-            }
-
-            if (result.isFailed()) {
-                throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() + " to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
-                // XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
-                // something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
-                // For now, I just retry the copy.
-            }
-        } catch (Throwable e) {
-            s_logger.debug("Failed to create a template on primary storage", e);
-
-            templateOnPrimary.processEvent(Event.OperationFailed);
-
-            throw new CloudRuntimeException(e.getMessage());
-        } finally {
-            _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
-        }
-    }
-
-    private void removeDynamicTargets(long hostId, List<Map<String, String>> targets) {
-        ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-        cmd.setTargets(targets);
-        cmd.setApplyToAllHostsInCluster(true);
-        cmd.setAdd(false);
-        cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-
-        sendModifyTargetsCommand(cmd, hostId);
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            String msg = "Unable to get an answer to the modify targets command";
-
-            s_logger.warn(msg);
-        } else if (!answer.getResult()) {
-            String msg = "Unable to modify target on the following host: " + hostId;
-
-            s_logger.warn(msg);
-        }
-    }
-
-    /**
-     * Clones the template volume on managed storage to the ROOT volume
-     *
-     * @param volumeInfo ROOT volume to create
-     * @param templateOnPrimary Template from which to clone the ROOT volume
-     * @param destPrimaryDataStore Primary storage of the volume
-     * @param future For async
-     */
-    private void createManagedVolumeCloneTemplateAsync(VolumeInfo volumeInfo, TemplateInfo templateOnPrimary, PrimaryDataStore destPrimaryDataStore, AsyncCallFuture<VolumeApiResult> future) {
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
-
-        if (templatePoolRef == null) {
-            throw new CloudRuntimeException("Failed to find template " + templateOnPrimary.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
-        }
-
-        //XXX: not sure if this the right thing to do here. We can always fallback to the "copy from sec storage"
-        if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
-            throw new CloudRuntimeException("Template " + templateOnPrimary.getUniqueName() + " has not been downloaded to primary storage.");
-        }
-
-        try {
-            volumeInfo.processEvent(Event.CreateOnlyRequested);
-
-            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null);
-
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-
-            caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
-            caller.setContext(context);
-
-            motionSrv.copyAsync(templateOnPrimary, volumeInfo, caller);
-        } catch (Throwable e) {
-            s_logger.debug("Failed to clone template on primary storage", e);
-
-            volumeInfo.processEvent(Event.OperationFailed);
-
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, PrimaryDataStore primaryDataStore, TemplateInfo srcTemplateInfo, Host destHost, AsyncCallFuture<VolumeApiResult> future) {
-        try {
-            // Create a volume on managed storage.
-
-            TemplateInfo destTemplateInfo = (TemplateInfo)primaryDataStore.create(srcTemplateInfo, false);
-
-            AsyncCallFuture<VolumeApiResult> createVolumeFuture = createVolumeAsync(volumeInfo, primaryDataStore);
-            VolumeApiResult createVolumeResult = createVolumeFuture.get();
-
-            if (createVolumeResult.isFailed()) {
-                throw new CloudRuntimeException("Creation of a volume failed: " + createVolumeResult.getResult());
-            }
-
-            // Refresh the volume info from the DB.
-            volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore);
-
-            ManagedCreateBaseImageContext<CreateCmdResult> context = new ManagedCreateBaseImageContext<CreateCmdResult>(null, volumeInfo, primaryDataStore, srcTemplateInfo, future);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-
-            caller.setCallback(caller.getTarget().managedCopyBaseImageCallback(null, null)).setContext(context);
-
-            Map<String, String> details = new HashMap<String, String>();
-
-            details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
-            details.put(PrimaryDataStore.STORAGE_HOST, primaryDataStore.getHostAddress());
-            details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(primaryDataStore.getPort()));
-            // for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume
-            details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName());
-            details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName());
-            details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(volumeInfo.getSize()));
-
-            ChapInfo chapInfo = getChapInfo(volumeInfo, primaryDataStore);
-
-            if (chapInfo != null) {
-                details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
-                details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
-                details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
-                details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
-            }
-
-            primaryDataStore.setDetails(details);
-
-            grantAccess(volumeInfo, destHost, primaryDataStore);
-
-            try {
-                motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller);
-            } finally {
-                revokeAccess(volumeInfo, destHost, primaryDataStore);
-            }
-        } catch (Throwable t) {
-            String errMsg = t.toString();
-
-            volumeInfo.processEvent(Event.DestroyRequested);
-
-            try {
-                AsyncCallFuture<VolumeApiResult> expungeVolumeFuture = expungeVolumeAsync(volumeInfo);
-
-                VolumeApiResult expungeVolumeResult = expungeVolumeFuture.get();
-
-                if (expungeVolumeResult.isFailed()) {
-                    errMsg += " : Failed to expunge a volume that was created";
-                }
-            } catch (Exception ex) {
-                errMsg += " : " + ex.getMessage();
-            }
-
-            VolumeApiResult result = new VolumeApiResult(volumeInfo);
-
-            result.setResult(errMsg);
-
-            future.complete(result);
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId, TemplateInfo srcTemplateInfo, long destHostId) {
-        PrimaryDataStore destPrimaryDataStore = dataStoreMgr.getPrimaryDataStore(destDataStoreId);
-        Host destHost = _hostDao.findById(destHostId);
-
-        if (destHost == null) {
-            throw new CloudRuntimeException("Destination host should not be null.");
-        }
-
-        Boolean storageCanCloneVolume = new Boolean(destPrimaryDataStore.getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString()));
-
-        boolean computeSupportsVolumeClone = computeSupportsVolumeClone(destHost.getDataCenterId(), destHost.getHypervisorType());
-
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<>();
-
-        if (storageCanCloneVolume && computeSupportsVolumeClone) {
-            s_logger.debug("Storage " + destDataStoreId + " can support cloning using a cached template and compute side is OK with volume cloning.");
-
-            TemplateInfo templateOnPrimary = destPrimaryDataStore.getTemplate(srcTemplateInfo.getId());
-
-            if (templateOnPrimary == null) {
-                templateOnPrimary = createManagedTemplateVolume(srcTemplateInfo, destPrimaryDataStore);
-
-                if (templateOnPrimary == null) {
-                    throw new CloudRuntimeException("Failed to create template " + srcTemplateInfo.getUniqueName() + " on primary storage: " + destDataStoreId);
-                }
-            }
-
-            // Copy the template to the template volume.
-            VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
-
-            if (templatePoolRef == null) {
-                throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
-            }
-
-            if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
-                copyTemplateToManagedTemplateVolume(srcTemplateInfo, templateOnPrimary, templatePoolRef, destPrimaryDataStore, destHost);
-            }
-
-            // We have a template on primary storage. Clone it to new volume.
-            s_logger.debug("Creating a clone from template on primary storage " + destDataStoreId);
-
-            createManagedVolumeCloneTemplateAsync(volumeInfo, templateOnPrimary, destPrimaryDataStore, future);
-        } else {
-            s_logger.debug("Primary storage does not support cloning or no support for UUID resigning on the host side; copying the template normally");
-
-            createManagedVolumeCopyTemplateAsync(volumeInfo, destPrimaryDataStore, srcTemplateInfo, destHost, future);
-        }
-
-        return future;
-    }
-
-    private boolean computeSupportsVolumeClone(long zoneId, HypervisorType hypervisorType) {
-        if (HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
-            return true;
-        }
-
-        return getHost(zoneId, hypervisorType, true) != null;
-    }
-
-    private HostVO getHost(Long zoneId, HypervisorType hypervisorType, boolean computeClusterMustSupportResign) {
-        if (zoneId == null) {
-            throw new CloudRuntimeException("Zone ID cannot be null.");
-        }
-
-        List<? extends Cluster> clusters = mgr.searchForClusters(zoneId, new Long(0), Long.MAX_VALUE, hypervisorType.toString());
-
-        if (clusters == null) {
-            clusters = new ArrayList<>();
-        }
-
-        Collections.shuffle(clusters, new Random(System.nanoTime()));
-
-        clusters: for (Cluster cluster : clusters) {
-            if (cluster.getAllocationState() == AllocationState.Enabled) {
-                List<HostVO> hosts = _hostDao.findByClusterId(cluster.getId());
-
-                if (hosts != null) {
-                    Collections.shuffle(hosts, new Random(System.nanoTime()));
-
-                    for (HostVO host : hosts) {
-                        if (host.getResourceState() == ResourceState.Enabled) {
-                            if (computeClusterMustSupportResign) {
-                                if (clusterDao.getSupportsResigning(cluster.getId())) {
-                                    return host;
-                                } else {
-                                    // no other host in the cluster in question should be able to satisfy our requirements here, so move on to the next cluster
-                                    continue clusters;
-                                }
-                            } else {
-                                return host;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @DB
-    @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template) {
-        PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
-        TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-
-        if (templateOnPrimaryStore == null) {
-            createBaseImageAsync(volume, pd, template, future);
-            return future;
-        }
-
-        createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future);
-        return future;
-    }
-
-    @DB
-    @Override
-    public void destroyVolume(long volumeId) {
-        // mark volume entry in volumes table as destroy state
-        VolumeInfo vol = volFactory.getVolume(volumeId);
-        vol.stateTransit(Volume.Event.DestroyRequested);
-        snapshotMgr.deletePoliciesForVolume(volumeId);
-
-        vol.stateTransit(Volume.Event.OperationSucceeded);
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-
-        try {
-            DataObject volumeOnStore = store.create(volume);
-            volumeOnStore.processEvent(Event.CreateOnlyRequested);
-            _volumeDetailsDao.addDetail(volume.getId(), SNAPSHOT_ID, Long.toString(snapshot.getId()), false);
-
-            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context);
-            motionSrv.copyAsync(snapshot, volumeOnStore, caller);
-        } catch (Exception e) {
-            s_logger.debug("create volume from snapshot failed", e);
-            VolumeApiResult result = new VolumeApiResult(volume);
-            result.setResult(e.toString());
-            future.complete(result);
-        }
-
-        return future;
-    }
-
-    protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
-        CopyCommandResult result = callback.getResult();
-        VolumeInfo volume = (VolumeInfo)context.templateOnStore;
-        SnapshotInfo snapshot = context.snapshot;
-        VolumeApiResult apiResult = new VolumeApiResult(volume);
-        Event event = null;
-        if (result.isFailed()) {
-            apiResult.setResult(result.getResult());
-            event = Event.OperationFailed;
-        } else {
-            event = Event.OperationSuccessed;
-        }
-
-        try {
-            if (result.isSuccess()) {
-                volume.processEvent(event, result.getAnswer());
-            } else {
-                volume.processEvent(event);
-            }
-            _volumeDetailsDao.removeDetail(volume.getId(), SNAPSHOT_ID);
-
-        } catch (Exception e) {
-            s_logger.debug("create volume from snapshot failed", e);
-            apiResult.setResult(e.toString());
-        }
-
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        future.complete(apiResult);
-        return null;
-    }
-
-    protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) {
-        Long lastPoolId = volume.getPoolId();
-        String folder = pool.getPath();
-        // For SMB, pool credentials are also stored in the uri query string.  We trim the query string
-        // part  here to make sure the credentials do not get stored in the db unencrypted.
-        if (pool.getPoolType() == StoragePoolType.SMB && folder != null && folder.contains("?")) {
-            folder = folder.substring(0, folder.indexOf("?"));
-        }
-
-        VolumeVO newVol = new VolumeVO(volume);
-        newVol.setInstanceId(null);
-        newVol.setChainInfo(null);
-        newVol.setPath(null);
-        newVol.setFolder(folder);
-        newVol.setPodId(pool.getPodId());
-        newVol.setPoolId(pool.getId());
-        newVol.setLastPoolId(lastPoolId);
-        newVol.setPodId(pool.getPodId());
-        return volDao.persist(newVol);
-    }
-
-    private class CopyVolumeContext<T> extends AsyncRpcContext<T> {
-        final VolumeInfo srcVolume;
-        final VolumeInfo destVolume;
-        final AsyncCallFuture<VolumeApiResult> future;
-
-        public CopyVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
-            super(callback);
-            this.srcVolume = srcVolume;
-            this.destVolume = destVolume;
-            this.future = future;
-        }
-
-    }
-
-    protected AsyncCallFuture<VolumeApiResult> copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult res = new VolumeApiResult(srcVolume);
-        VolumeInfo destVolume = null;
-        try {
-            destVolume = (VolumeInfo)destStore.create(srcVolume);
-            destVolume.processEvent(Event.CopyingRequested);
-            srcVolume.processEvent(Event.CopyingRequested);
-
-            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)).setContext(context);
-
-            motionSrv.copyAsync(srcVolume, destVolume, caller);
-            return future;
-        } catch (Exception e) {
-            s_logger.error("failed to copy volume from image store", e);
-            if (destVolume != null) {
-                destVolume.processEvent(Event.OperationFailed);
-            }
-
-            srcVolume.processEvent(Event.OperationFailed);
-            res.setResult(e.toString());
-            future.complete(res);
-            return future;
-        }
-    }
-
-    protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
-        VolumeInfo srcVolume = context.srcVolume;
-        VolumeInfo destVolume = context.destVolume;
-        CopyCommandResult result = callback.getResult();
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        VolumeApiResult res = new VolumeApiResult(destVolume);
-        try {
-            if (result.isFailed()) {
-                destVolume.processEvent(Event.OperationFailed);
-                srcVolume.processEvent(Event.OperationFailed);
-                res.setResult(result.getResult());
-                future.complete(res);
-                return null;
-            }
-
-            srcVolume.processEvent(Event.OperationSuccessed);
-            destVolume.processEvent(Event.OperationSuccessed, result.getAnswer());
-            srcVolume.getDataStore().delete(srcVolume);
-            future.complete(res);
-        } catch (Exception e) {
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-        return null;
-    }
-
-    protected AsyncCallFuture<VolumeApiResult> copyVolumeFromPrimaryToImage(VolumeInfo srcVolume, DataStore destStore) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult res = new VolumeApiResult(srcVolume);
-        VolumeInfo destVolume = null;
-        try {
-            destVolume = (VolumeInfo)destStore.create(srcVolume);
-            srcVolume.processEvent(Event.MigrationRequested);    // this is just used for locking that src volume record in DB to avoid using lock
-            destVolume.processEventOnly(Event.CreateOnlyRequested);
-
-            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().copyVolumeFromPrimaryToImageCallback(null, null)).setContext(context);
-
-            motionSrv.copyAsync(srcVolume, destVolume, caller);
-            return future;
-        } catch (Exception e) {
-            s_logger.error("failed to copy volume to image store", e);
-            if (destVolume != null) {
-                destVolume.getDataStore().delete(destVolume);
-            }
-            srcVolume.processEvent(Event.OperationFailed); // unlock source volume record
-            res.setResult(e.toString());
-            future.complete(res);
-            return future;
-        }
-    }
-
-    protected Void copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
-        VolumeInfo srcVolume = context.srcVolume;
-        VolumeInfo destVolume = context.destVolume;
-        CopyCommandResult result = callback.getResult();
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        VolumeApiResult res = new VolumeApiResult(destVolume);
-        try {
-            if (result.isFailed()) {
-                srcVolume.processEvent(Event.OperationFailed); // back to Ready state in Volume table
-                destVolume.processEventOnly(Event.OperationFailed);
-                res.setResult(result.getResult());
-                future.complete(res);
-            } else {
-                srcVolume.processEvent(Event.OperationSuccessed); // back to Ready state in Volume table
-                destVolume.processEventOnly(Event.OperationSuccessed, result.getAnswer());
-                future.complete(res);
-            }
-        } catch (Exception e) {
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-        return null;
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume, DataStore destStore) {
-
-        if (srcVolume.getState() == Volume.State.Uploaded) {
-            return copyVolumeFromImageToPrimary(srcVolume, destStore);
-        }
-
-        if (destStore.getRole() == DataStoreRole.Image) {
-            return copyVolumeFromPrimaryToImage(srcVolume, destStore);
-        }
-
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult res = new VolumeApiResult(srcVolume);
-        try {
-            if (!snapshotMgr.canOperateOnVolume(srcVolume)) {
-                s_logger.debug("There are snapshots creating on this volume, can not move this volume");
-
-                res.setResult("There are snapshots creating on this volume, can not move this volume");
-                future.complete(res);
-                return future;
-            }
-
-            VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool)destStore);
-            VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), destStore);
-            destVolume.processEvent(Event.MigrationCopyRequested);
-            srcVolume.processEvent(Event.MigrationRequested);
-
-            CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)).setContext(context);
-            motionSrv.copyAsync(srcVolume, destVolume, caller);
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy volume" + e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-        return future;
-    }
-
-    protected Void copyVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
-        VolumeInfo srcVolume = context.srcVolume;
-        VolumeInfo destVolume = context.destVolume;
-        CopyCommandResult result = callback.getResult();
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        VolumeApiResult res = new VolumeApiResult(destVolume);
-        try {
-            if (result.isFailed()) {
-                res.setResult(result.getResult());
-                destVolume.processEvent(Event.MigrationCopyFailed);
-                srcVolume.processEvent(Event.OperationFailed);
-                destroyVolume(destVolume.getId());
-                destVolume = volFactory.getVolume(destVolume.getId());
-                AsyncCallFuture<VolumeApiResult> destroyFuture = expungeVolumeAsync(destVolume);
-                destroyFuture.get();
-                future.complete(res);
-                return null;
-            }
-            srcVolume.processEvent(Event.OperationSuccessed);
-            destVolume.processEvent(Event.MigrationCopySucceeded, result.getAnswer());
-            volDao.updateUuid(srcVolume.getId(), destVolume.getId());
-            _volumeStoreDao.updateVolumeId(srcVolume.getId(), destVolume.getId());
-            try {
-                destroyVolume(srcVolume.getId());
-                srcVolume = volFactory.getVolume(srcVolume.getId());
-                AsyncCallFuture<VolumeApiResult> destroyFuture = expungeVolumeAsync(srcVolume);
-                // If volume destroy fails, this could be because of vdi is still in use state, so wait and retry.
-                if (destroyFuture.get().isFailed()) {
-                    Thread.sleep(5 * 1000);
-                    destroyFuture = expungeVolumeAsync(srcVolume);
-                    destroyFuture.get();
-                }
-                future.complete(res);
-            } catch (Exception e) {
-                s_logger.debug("failed to clean up volume on storage", e);
-            }
-            return null;
-        } catch (Exception e) {
-            s_logger.debug("Failed to process copy volume callback", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-
-        return null;
-    }
-
-    private class MigrateVolumeContext<T> extends AsyncRpcContext<T> {
-        final VolumeInfo srcVolume;
-        final VolumeInfo destVolume;
-        final AsyncCallFuture<VolumeApiResult> future;
-
-        /**
-         * @param callback
-         */
-        public MigrateVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
-            super(callback);
-            this.srcVolume = srcVolume;
-            this.destVolume = destVolume;
-            this.future = future;
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> migrateVolume(VolumeInfo srcVolume, DataStore destStore) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult res = new VolumeApiResult(srcVolume);
-        try {
-            if (!snapshotMgr.canOperateOnVolume(srcVolume)) {
-                s_logger.debug("Snapshots are being created on this volume. This volume cannot be migrated now.");
-                res.setResult("Snapshots are being created on this volume. This volume cannot be migrated now.");
-                future.complete(res);
-                return future;
-            }
-
-            VolumeInfo destVolume = volFactory.getVolume(srcVolume.getId(), destStore);
-            srcVolume.processEvent(Event.MigrationRequested);
-            MigrateVolumeContext<VolumeApiResult> context = new MigrateVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, destStore);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().migrateVolumeCallBack(null, null)).setContext(context);
-            motionSrv.copyAsync(srcVolume, destVolume, caller);
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy volume", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-        return future;
-    }
-
-    protected Void migrateVolumeCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVolumeContext<VolumeApiResult> context) {
-        VolumeInfo srcVolume = context.srcVolume;
-        CopyCommandResult result = callback.getResult();
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        VolumeApiResult res = new VolumeApiResult(srcVolume);
-        try {
-            if (result.isFailed()) {
-                res.setResult(result.getResult());
-                srcVolume.processEvent(Event.OperationFailed);
-                future.complete(res);
-            } else {
-                srcVolume.processEvent(Event.OperationSuccessed);
-                snapshotMgr.cleanupSnapshotsByVolume(srcVolume.getId());
-                future.complete(res);
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to process migrate volume callback", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-
-        return null;
-    }
-
-    private class MigrateVmWithVolumesContext<T> extends AsyncRpcContext<T> {
-        final Map<VolumeInfo, DataStore> volumeToPool;
-        final AsyncCallFuture<CommandResult> future;
-
-        public MigrateVmWithVolumesContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future, Map<VolumeInfo, DataStore> volumeToPool) {
-            super(callback);
-            this.volumeToPool = volumeToPool;
-            this.future = future;
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<CommandResult> migrateVolumes(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost) {
-        AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
-        CommandResult res = new CommandResult();
-        try {
-            // Check to make sure there are no snapshot operations on a volume
-            // and
-            // put it in the migrating state.
-            List<VolumeInfo> volumesMigrating = new ArrayList<VolumeInfo>();
-            for (Map.Entry<VolumeInfo, DataStore> entry : volumeMap.entrySet()) {
-                VolumeInfo volume = entry.getKey();
-                if (!snapshotMgr.canOperateOnVolume(volume)) {
-                    s_logger.debug("Snapshots are being created on a volume. Volumes cannot be migrated now.");
-                    res.setResult("Snapshots are being created on a volume. Volumes cannot be migrated now.");
-                    future.complete(res);
-
-                    // All the volumes that are already in migrating state need
-                    // to be put back in ready state.
-                    for (VolumeInfo volumeMigrating : volumesMigrating) {
-                        volumeMigrating.processEvent(Event.OperationFailed);
-                    }
-                    return future;
-                } else {
-                    volume.processEvent(Event.MigrationRequested);
-                    volumesMigrating.add(volume);
-                }
-            }
-
-            MigrateVmWithVolumesContext<CommandResult> context = new MigrateVmWithVolumesContext<CommandResult>(null, future, volumeMap);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().migrateVmWithVolumesCallBack(null, null)).setContext(context);
-            motionSrv.copyAsync(volumeMap, vmTo, srcHost, destHost, caller);
-
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy volume", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-
-        return future;
-    }
-
-    protected Void migrateVmWithVolumesCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVmWithVolumesContext<CommandResult> context) {
-        Map<VolumeInfo, DataStore> volumeToPool = context.volumeToPool;
-        CopyCommandResult result = callback.getResult();
-        AsyncCallFuture<CommandResult> future = context.future;
-        CommandResult res = new CommandResult();
-        try {
-            if (result.isFailed()) {
-                res.setResult(result.getResult());
-                for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
-                    VolumeInfo volume = entry.getKey();
-                    volume.processEvent(Event.OperationFailed);
-                }
-                future.complete(res);
-            } else {
-                for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
-                    VolumeInfo volume = entry.getKey();
-                    snapshotMgr.cleanupSnapshotsByVolume(volume.getId());
-                    volume.processEvent(Event.OperationSuccessed);
-                }
-                future.complete(res);
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to process copy volume callback", e);
-            res.setResult(e.toString());
-            future.complete(res);
-        }
-
-        return null;
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store) {
-
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        DataObject volumeOnStore = store.create(volume);
-
-        volumeOnStore.processEvent(Event.CreateOnlyRequested);
-
-        try {
-            CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volumeOnStore, future);
-            AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-            caller.setCallback(caller.getTarget().registerVolumeCallback(null, null));
-            caller.setContext(context);
-
-            store.getDriver().createAsync(store, volumeOnStore, caller);
-        } catch (CloudRuntimeException ex) {
-            // clean up already persisted volume_store_ref entry in case of createVolumeCallback is never called
-            VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId());
-            if (volStoreVO != null) {
-                VolumeInfo volObj = volFactory.getVolume(volume, store);
-                volObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
-            }
-            VolumeApiResult res = new VolumeApiResult((VolumeObject)volumeOnStore);
-            res.setResult(ex.getMessage());
-            future.complete(res);
-        }
-        return future;
-    }
-
-    @Override
-    public Pair<EndPoint, DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store) {
-
-        EndPoint ep = _epSelector.select(store);
-        if (ep == null) {
-            String errorMessage = "There is no secondary storage VM for image store " + store.getName();
-            s_logger.warn(errorMessage);
-            throw new CloudRuntimeException(errorMessage);
-        }
-        DataObject volumeOnStore = store.create(volume);
-        return new Pair<>(ep, volumeOnStore);
-    }
-
-    protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
-        CreateCmdResult result = callback.getResult();
-        VolumeObject vo = (VolumeObject)context.volume;
-        try {
-            if (result.isFailed()) {
-                vo.processEvent(Event.OperationFailed);
-                // delete the volume entry from volumes table in case of failure
-                VolumeVO vol = volDao.findById(vo.getId());
-                if (vol != null) {
-                    volDao.remove(vo.getId());
-                }
-
-            } else {
-                vo.processEvent(Event.OperationSuccessed, result.getAnswer());
-
-                if (vo.getSize() != null) {
-                    // publish usage events
-                    // get physical size from volume_store_ref table
-                    long physicalSize = 0;
-                    DataStore ds = vo.getDataStore();
-                    VolumeDataStoreVO volStore = _volumeStoreDao.findByStoreVolume(ds.getId(), vo.getId());
-                    if (volStore != null) {
-                        physicalSize = volStore.getPhysicalSize();
-                    } else {
-                        s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() + " at the end of uploading volume!");
-                    }
-                    Scope dsScope = ds.getScope();
-                    if (dsScope.getScopeType() == ScopeType.ZONE) {
-                        if (dsScope.getScopeId() != null) {
-                            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
-                                    Volume.class.getName(), vo.getUuid());
-                        } else {
-                            s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id");
-                        }
-                    } else if (dsScope.getScopeType() == ScopeType.REGION) {
-                        // publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
-                                Volume.class.getName(), vo.getUuid());
-
-                        _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize());
-                    }
-                }
-            }
-            VolumeApiResult res = new VolumeApiResult(vo);
-            context.future.complete(res);
-            return null;
-
-        } catch (Exception e) {
-            s_logger.error("register volume failed: ", e);
-            // delete the volume entry from volumes table in case of failure
-            VolumeVO vol = volDao.findById(vo.getId());
-            if (vol != null) {
-                volDao.remove(vo.getId());
-            }
-            VolumeApiResult res = new VolumeApiResult(null);
-            context.future.complete(res);
-            return null;
-        }
-    }
-
-    @Override
-    public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
-        VolumeApiResult result = new VolumeApiResult(volume);
-        try {
-            volume.processEvent(Event.ResizeRequested);
-        } catch (Exception e) {
-            s_logger.debug("Failed to change state to resize", e);
-            result.setResult(e.toString());
-            future.complete(result);
-            return future;
-        }
-        CreateVolumeContext<VolumeApiResult> context = new CreateVolumeContext<VolumeApiResult>(null, volume, future);
-        AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().resizeVolumeCallback(caller, context)).setContext(context);
-
-        try {
-            volume.getDataStore().getDriver().resize(volume, caller);
-        } catch (Exception e) {
-            s_logger.debug("Failed to change state to resize", e);
-
-            result.setResult(e.toString());
-
-            future.complete(result);
-        }
-
-        return future;
-    }
-
-    @Override
-    public void resizeVolumeOnHypervisor(long volumeId, long newSize, long destHostId, String instanceName) {
-        final String errMsg = "Resize command failed";
-
-        try {
-            Answer answer = null;
-            Host destHost = _hostDao.findById(destHostId);
-            EndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(destHost);
-
-            if (ep != null) {
-                VolumeVO volume = volDao.findById(volumeId);
-                PrimaryDataStore primaryDataStore = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
-                ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(volume.getPath(), new StorageFilerTO(primaryDataStore), volume.getSize(), newSize, true, instanceName,
-                        primaryDataStore.isManaged(), volume.get_iScsiName());
-
-                answer = ep.sendMessage(resizeCmd);
-            } else {
-                throw new CloudRuntimeException("Could not find a remote endpoint to send command to. Check if host or SSVM is down.");
-            }
-
-            if (answer == null || !answer.getResult()) {
-                throw new CloudRuntimeException(answer != null ? answer.getDetails() : errMsg);
-            }
-        } catch (Exception e) {
-            throw new CloudRuntimeException(errMsg, e);
-        }
-    }
-
-    protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
-        CreateCmdResult result = callback.getResult();
-        AsyncCallFuture<VolumeApiResult> future = context.future;
-        VolumeInfo volume = (VolumeInfo)context.volume;
-
-        if (result.isFailed()) {
-            try {
-                volume.processEvent(Event.OperationFailed);
-            } catch (Exception e) {
-                s_logger.debug("Failed to change state", e);
-            }
-            VolumeApiResult res = new VolumeApiResult(volume);
-            res.setResult(result.getResult());
-            future.complete(res);
-            return null;
-        }
-
-        try {
-            volume.processEvent(Event.OperationSuccessed);
-        } catch (Exception e) {
-            s_logger.debug("Failed to change state", e);
-            VolumeApiResult res = new VolumeApiResult(volume);
-            res.setResult(result.getResult());
-            future.complete(res);
-            return null;
-        }
-
-        VolumeApiResult res = new VolumeApiResult(volume);
-        future.complete(res);
-
-        return null;
-    }
-
-    @Override
-    public void handleVolumeSync(DataStore store) {
-        if (store == null) {
-            s_logger.warn("Huh? image store is null");
-            return;
-        }
-        long storeId = store.getId();
-
-        // add lock to make template sync for a data store only be done once
-        String lockString = "volumesync.storeId:" + storeId;
-        GlobalLock syncLock = GlobalLock.getInternLock(lockString);
-        try {
-            if (syncLock.lock(3)) {
-                try {
-                    Map<Long, TemplateProp> volumeInfos = listVolume(store);
-                    if (volumeInfos == null) {
-                        return;
-                    }
-
-                    // find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
-                    List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
-                    List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<VolumeDataStoreVO>(dbVolumes);
-                    for (VolumeDataStoreVO volumeStore : dbVolumes) {
-                        VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
-                        if (volume == null) {
-                            s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId
-                                    + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
-                            volumeStore.setDestroyed(true);
-                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
-                            continue;
-                        }
-                        // Exists then don't download
-                        if (volumeInfos.containsKey(volume.getId())) {
-                            TemplateProp volInfo = volumeInfos.remove(volume.getId());
-                            toBeDownloaded.remove(volumeStore);
-                            s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
-                            if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
-                                volumeStore.setErrorString("");
-                            }
-                            if (volInfo.isCorrupted()) {
-                                volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
-                                String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
-                                volumeStore.setErrorString(msg);
-                                s_logger.info(msg);
-                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
-                                    s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as failed");
-                                    _volumeStoreDao.update(volumeStore.getId(), volumeStore);
-                                    // mark volume as failed, so that storage GC will clean it up
-                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
-                                    volObj.processEvent(Event.OperationFailed);
-                                } else if (volumeStore.getDownloadUrl() == null) {
-                                    msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: "
-                                            + volumeStore.getDataStoreId();
-                                    s_logger.warn(msg);
-                                } else {
-                                    s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
-                                    _volumeStoreDao.remove(volumeStore.getId());
-                                    toBeDownloaded.add(volumeStore);
-                                }
-                            } else { // Put them in right status
-                                volumeStore.setDownloadPercent(100);
-                                volumeStore.setDownloadState(Status.DOWNLOADED);
-                                volumeStore.setState(ObjectInDataStoreStateMachine.State.Ready);
-                                volumeStore.setInstallPath(volInfo.getInstallPath());
-                                volumeStore.setSize(volInfo.getSize());
-                                volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
-                                volumeStore.setLastUpdated(new Date());
-                                _volumeStoreDao.update(volumeStore.getId(), volumeStore);
-
-                                if (volume.getSize() == 0) {
-                                    // Set volume size in volumes table
-                                    volume.setSize(volInfo.getSize());
-                                    volDao.update(volumeStore.getVolumeId(), volume);
-                                }
-
-                                if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
-                                    VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
-                                    volObj.processEvent(Event.OperationSuccessed);
-                                }
-
-                                if (volInfo.getSize() > 0) {
-                                    try {
-                                        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage,
-                                                volInfo.getSize() - volInfo.getPhysicalSize());
-                                    } catch (ResourceAllocationException e) {
-                                        s_logger.warn(e.getMessage());
-                                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
-                                    } finally {
-                                        _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
-                                                com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal());
-                                    }
-                                }
-                            }
-                            continue;
-                        } else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) { // failed uploads through SSVM
-                            s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
-                            toBeDownloaded.remove(volumeStore);
-                            volumeStore.setDownloadState(Status.DOWNLOAD_ERROR);
-                            String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
-                            volumeStore.setErrorString(msg);
-                            _volumeStoreDao.update(volumeStore.getId(), volumeStore);
-                            // mark volume as failed, so that storage GC will clean it up
-                            VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
-                            volObj.processEvent(Event.OperationFailed);
-                            continue;
-                        }
-                        // Volume is not on secondary but we should download.
-                        if (volumeStore.getDownloadState() != Status.DOWNLOADED) {
-                            s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
-                        }
-                    }
-
-                    // Download volumes which haven't been downloaded yet.
-                    if (toBeDownloaded.size() > 0) {
-                        for (VolumeDataStoreVO volumeHost : toBeDownloaded) {
-                            if (volumeHost.getDownloadUrl() == null) { // If url is null, skip downloading
-                                s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
-                                continue;
-                            }
-
-                            // if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which
-                            // means that this is a duplicate entry from migration of previous NFS to staging.
-                            if (store.getScope().getScopeType() == ScopeType.REGION) {
-                                if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED && volumeHost.getInstallPath() == null) {
-                                    s_logger.info("Skip sync volume for migration of previous NFS to object store");
-                                    continue;
-                                }
-                            }
-
-                            s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
-                            // reset volume status back to Allocated
-                            VolumeObject vol = (VolumeObject)volFactory.getVolume(volumeHost.getVolumeId());
-                            vol.processEvent(Event.OperationFailed); // reset back volume status
-                            // remove leftover volume_store_ref entry since re-download will create it again
-                            _volumeStoreDao.remove(volumeHost.getId());
-                            // get an updated volumeVO
-                            vol = (VolumeObject)volFactory.getVolume(volumeHost.getVolumeId());
-                            RegisterVolumePayload payload = new RegisterVolumePayload(volumeHost.getDownloadUrl(), volumeHost.getChecksum(), vol.getFormat().toString());
-                            vol.addPayload(payload);
-                            createVolumeAsync(vol, store);
-                        }
-                    }
-
-                    // Delete volumes which are not present on DB.
-                    for (Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
-                        Long uniqueName = entry.getKey();
-                        TemplateProp tInfo = entry.getValue();
-
-                        // we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
-                        VolumeObjectTO tmplTO = new VolumeObjectTO();
-                        tmplTO.setDataStore(store.getTO());
-                        tmplTO.setPath(tInfo.getInstallPath());
-                        tmplTO.setId(tInfo.getId());
-                        DeleteCommand dtCommand = new DeleteCommand(tmplTO);
-                        EndPoint ep = _epSelector.select(store);
-                        Answer answer = null;
-                        if (ep == null) {
-                            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                            s_logger.error(errMsg);
-                            answer = new Answer(dtCommand, false, errMsg);
-                        } else {
-                            answer = ep.sendMessage(dtCommand);
-                        }
-                        if (answer == null || !answer.getResult()) {
-                            s_logger.info("Failed to deleted volume at store: " + store.getName());
-
-                        } else {
-                            String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId;
-                            s_logger.info(description);
-                        }
-                    }
-                } finally {
-                    syncLock.unlock();
-                }
-            } else {
-                s_logger.info("Couldn't get global lock on " + lockString + ", another thread may be doing volume sync on data store " + storeId + " now.");
-            }
-        } finally {
-            syncLock.releaseRef();
-        }
-    }
-
-    private Map<Long, TemplateProp> listVolume(DataStore store) {
-        ListVolumeCommand cmd = new ListVolumeCommand(store.getTO(), store.getUri());
-        EndPoint ep = _epSelector.select(store);
-        Answer answer = null;
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            answer = new Answer(cmd, false, errMsg);
-        } else {
-            answer = ep.sendMessage(cmd);
-        }
-        if (answer != null && answer.getResult()) {
-            ListVolumeAnswer tanswer = (ListVolumeAnswer)answer;
-            return tanswer.getTemplateInfo();
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Can not list volumes for image store " + store.getId());
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public SnapshotInfo takeSnapshot(VolumeInfo volume) {
-        SnapshotInfo snapshot = null;
-        try {
-            snapshot = snapshotMgr.takeSnapshot(volume);
-        } catch (CloudRuntimeException cre) {
-            s_logger.error("Take snapshot: " + volume.getId() + " failed", cre);
-            throw cre;
-        } catch (Exception e) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("unknown exception while taking snapshot for volume " + volume.getId() + " was caught", e);
-            }
-            throw new CloudRuntimeException("Failed to take snapshot", e);
-        }
-
-        return snapshot;
-    }
-
-    // For managed storage on Xen and VMware, we need to potentially make space for hypervisor snapshots.
-    // The disk offering can collect this information and pass it on to the volume that's about to be created.
-    // Ex. if you want a 10 GB CloudStack volume to reside on managed storage on Xen, this leads to an SR
-    // that is a total size of (10 GB * (hypervisorSnapshotReserveSpace / 100) + 10 GB).
-    @Override
-    public VolumeInfo updateHypervisorSnapshotReserveForVolume(DiskOffering diskOffering, long volumeId, HypervisorType hyperType) {
-        if (diskOffering != null && hyperType != null) {
-            Integer hypervisorSnapshotReserve = diskOffering.getHypervisorSnapshotReserve();
-
-            if (hyperType == HypervisorType.KVM) {
-                hypervisorSnapshotReserve = null;
-            } else if (hypervisorSnapshotReserve == null || hypervisorSnapshotReserve < 0) {
-                hypervisorSnapshotReserve = 0;
-            }
-
-            VolumeVO volume = volDao.findById(volumeId);
-
-            volume.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
-
-            volDao.update(volume.getId(), volume);
-        }
-
-        return volFactory.getVolume(volumeId);
-    }
-}
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/VolumeObjectTest.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeObjectTest.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/VolumeObjectTest.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeObjectTest.java
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/Server.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/Server.java
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/Server1.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server1.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/Server1.java
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/TestConfiguration.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/TestConfiguration.java
diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
similarity index 100%
rename from engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
rename to engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java
diff --git a/engine/storage/volume/test/resource/testContext.xml b/engine/storage/volume/src/test/resource/testContext.xml
similarity index 100%
rename from engine/storage/volume/test/resource/testContext.xml
rename to engine/storage/volume/src/test/resource/testContext.xml
diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml
index 13b8af2..b729c32 100644
--- a/framework/agent-lb/pom.xml
+++ b/framework/agent-lb/pom.xml
@@ -1,32 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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">
+<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>
     <name>Apache CloudStack Agent Management Servers Load Balancer</name>
     <artifactId>cloud-framework-agent-lb</artifactId>
     <parent>
         <artifactId>cloudstack-framework</artifactId>
         <groupId>org.apache.cloudstack</groupId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
-
 </project>
diff --git a/framework/agent-lb/src/org/apache/cloudstack/agent/lb/IndirectAgentLB.java b/framework/agent-lb/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLB.java
similarity index 100%
rename from framework/agent-lb/src/org/apache/cloudstack/agent/lb/IndirectAgentLB.java
rename to framework/agent-lb/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLB.java
diff --git a/framework/agent-lb/src/org/apache/cloudstack/agent/lb/IndirectAgentLBAlgorithm.java b/framework/agent-lb/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBAlgorithm.java
similarity index 100%
rename from framework/agent-lb/src/org/apache/cloudstack/agent/lb/IndirectAgentLBAlgorithm.java
rename to framework/agent-lb/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBAlgorithm.java
diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml
index 96f78d4..97b2dad 100644
--- a/framework/ca/pom.xml
+++ b/framework/ca/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-framework-ca</artifactId>
-  <name>Apache CloudStack Framework - Certificate Authority</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+<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-framework-ca</artifactId>
+    <name>Apache CloudStack Framework - Certificate Authority</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/framework/ca/src/org/apache/cloudstack/framework/ca/CAProvider.java b/framework/ca/src/main/java/org/apache/cloudstack/framework/ca/CAProvider.java
similarity index 100%
rename from framework/ca/src/org/apache/cloudstack/framework/ca/CAProvider.java
rename to framework/ca/src/main/java/org/apache/cloudstack/framework/ca/CAProvider.java
diff --git a/framework/ca/src/org/apache/cloudstack/framework/ca/CAService.java b/framework/ca/src/main/java/org/apache/cloudstack/framework/ca/CAService.java
similarity index 100%
rename from framework/ca/src/org/apache/cloudstack/framework/ca/CAService.java
rename to framework/ca/src/main/java/org/apache/cloudstack/framework/ca/CAService.java
diff --git a/framework/ca/src/org/apache/cloudstack/framework/ca/Certificate.java b/framework/ca/src/main/java/org/apache/cloudstack/framework/ca/Certificate.java
similarity index 100%
rename from framework/ca/src/org/apache/cloudstack/framework/ca/Certificate.java
rename to framework/ca/src/main/java/org/apache/cloudstack/framework/ca/Certificate.java
diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml
index 5b955c4..119fae8 100644
--- a/framework/cluster/pom.xml
+++ b/framework/cluster/pom.xml
@@ -1,45 +1,53 @@
-<!-- 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. -->
+<!--
+  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-framework-cluster</artifactId>
-  <name>Apache CloudStack Framework - Clustering</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+    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-framework-cluster</artifactId>
+    <name>Apache CloudStack Framework - Clustering</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
 </project>
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterFenceManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterFenceManagerImpl.java
deleted file mode 100644
index 0b14be8..0000000
--- a/framework/cluster/src/com/cloud/cluster/ClusterFenceManagerImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.component.ManagerBase;
-
-@Component
-public class ClusterFenceManagerImpl extends ManagerBase implements ClusterFenceManager, ClusterManagerListener {
-    private static final Logger s_logger = Logger.getLogger(ClusterFenceManagerImpl.class);
-
-    @Inject
-    ClusterManager _clusterMgr;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _clusterMgr.registerListener(this);
-        return true;
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-        s_logger.error("Received node isolation notification, will perform self-fencing and shut myself down");
-        System.exit(SELF_FENCING_EXIT_CODE);
-    }
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManager.java b/framework/cluster/src/com/cloud/cluster/ClusterManager.java
deleted file mode 100644
index 86d6fb3..0000000
--- a/framework/cluster/src/com/cloud/cluster/ClusterManager.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-import com.cloud.utils.component.Manager;
-
-public interface ClusterManager extends Manager {
-    static final String ALERT_SUBJECT = "cluster-alert";
-    final ConfigKey<Integer> HeartbeatInterval = new ConfigKey<Integer>(Integer.class, "cluster.heartbeat.interval", "management-server", "1500",
-        "Interval to check for the heart beat between management server nodes", false);
-    final ConfigKey<Integer> HeartbeatThreshold = new ConfigKey<Integer>(Integer.class, "cluster.heartbeat.threshold", "management-server", "150000",
-        "Threshold before self-fence the management server", true);
-
-    void OnReceiveClusterServicePdu(ClusterServicePdu pdu);
-
-    /**
-     * This executes
-     * @param strPeer
-     * @param agentId
-     * @param cmds
-     * @param stopOnError
-     * @return
-     */
-    String execute(String strPeer, long agentId, String cmds, boolean stopOnError);
-
-    /**
-     * Broadcast the command to all of the  management server nodes.
-     * @param agentId agent id this broadcast is regarding
-     * @param cmds commands to broadcast
-     */
-    void broadcast(long agentId, String cmds);
-
-    void registerListener(ClusterManagerListener listener);
-
-    void unregisterListener(ClusterManagerListener listener);
-
-    void registerDispatcher(Dispatcher dispatcher);
-
-    ManagementServerHost getPeer(String peerName);
-
-    String getSelfPeerName();
-
-    long getManagementNodeId();
-
-    long getCurrentRunId();
-
-    public long getManagementRunId(long msId);
-
-    public interface Dispatcher {
-        String getName();
-
-        String dispatch(ClusterServicePdu pdu);
-    }
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
deleted file mode 100644
index d4717ca..0000000
--- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
+++ /dev/null
@@ -1,1201 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.nio.channels.SocketChannel;
-import java.rmi.RemoteException;
-import java.sql.Connection;
-import java.sql.SQLNonTransientException;
-import java.sql.SQLRecoverableException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import com.cloud.cluster.dao.ManagementServerHostDao;
-import com.cloud.cluster.dao.ManagementServerHostPeerDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Profiler;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.ConnectionConcierge;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.DbProperties;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.events.SubscriptionMgr;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.mgmt.JmxUtil;
-import com.cloud.utils.net.NetUtils;
-
-public class ClusterManagerImpl extends ManagerBase implements ClusterManager, Configurable {
-    private static final Logger s_logger = Logger.getLogger(ClusterManagerImpl.class);
-
-    private static final int EXECUTOR_SHUTDOWN_TIMEOUT = 1000; // 1 second
-    private static final int DEFAULT_OUTGOING_WORKERS = 5;
-
-    private final List<ClusterManagerListener> _listeners = new ArrayList<ClusterManagerListener>();
-    private final Map<Long, ManagementServerHostVO> _activePeers = new HashMap<Long, ManagementServerHostVO>();
-
-    private final Map<String, ClusterService> _clusterPeers;
-
-    @Inject
-    protected ConfigDepot _configDepot;
-
-    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Cluster-Heartbeat"));
-    private final ExecutorService _notificationExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("Cluster-Notification"));
-    private final List<ClusterManagerMessage> _notificationMsgs = new ArrayList<ClusterManagerMessage>();
-    private ConnectionConcierge _heartbeatConnection = null;
-
-    private final ExecutorService _executor;
-
-    private ClusterServiceAdapter _currentServiceAdapter;
-
-    @Inject
-    private List<ClusterServiceAdapter> _serviceAdapters;
-
-    @Inject
-    private ManagementServerHostDao _mshostDao;
-    @Inject
-    private ManagementServerHostPeerDao _mshostPeerDao;
-
-    protected Dispatcher _dispatcher;
-
-    //
-    // pay attention to _mshostId and _msid
-    // _mshostId is the primary key of management host table
-    // _msid is the unique persistent identifier that peer name is based upon
-    //
-    private Long _mshostId = null;
-    protected long _msId = ManagementServerNode.getManagementServerId();
-    protected long _runId = System.currentTimeMillis();
-
-    private boolean _peerScanInited = false;
-
-    private String _clusterNodeIP = "127.0.0.1";
-
-    private final List<ClusterServicePdu> _clusterPduOutgoingQueue = new ArrayList<ClusterServicePdu>();
-    private final List<ClusterServicePdu> _clusterPduIncomingQueue = new ArrayList<ClusterServicePdu>();
-    private final Map<Long, ClusterServiceRequestPdu> _outgoingPdusWaitingForAck = new HashMap<Long, ClusterServiceRequestPdu>();
-
-    public ClusterManagerImpl() {
-        _clusterPeers = new HashMap<String, ClusterService>();
-
-        // executor to perform remote-calls in another thread context, to avoid potential
-        // recursive remote calls between nodes
-        //
-        _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Cluster-Worker"));
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK);
-    }
-
-    private void registerRequestPdu(final ClusterServiceRequestPdu pdu) {
-        synchronized (_outgoingPdusWaitingForAck) {
-            _outgoingPdusWaitingForAck.put(pdu.getSequenceId(), pdu);
-        }
-    }
-
-    @Override
-    public void registerDispatcher(final Dispatcher dispatcher) {
-        _dispatcher = dispatcher;
-    }
-
-    private ClusterServiceRequestPdu popRequestPdu(final long ackSequenceId) {
-        synchronized (_outgoingPdusWaitingForAck) {
-            if (_outgoingPdusWaitingForAck.get(ackSequenceId) != null) {
-                final ClusterServiceRequestPdu pdu = _outgoingPdusWaitingForAck.get(ackSequenceId);
-                _outgoingPdusWaitingForAck.remove(ackSequenceId);
-                return pdu;
-            }
-        }
-
-        return null;
-    }
-
-    private void cancelClusterRequestToPeer(final String strPeer) {
-        final List<ClusterServiceRequestPdu> candidates = new ArrayList<ClusterServiceRequestPdu>();
-        synchronized (_outgoingPdusWaitingForAck) {
-            for (final Map.Entry<Long, ClusterServiceRequestPdu> entry : _outgoingPdusWaitingForAck.entrySet()) {
-                if (entry.getValue().getDestPeer().equalsIgnoreCase(strPeer)) {
-                    candidates.add(entry.getValue());
-                }
-            }
-
-            for (final ClusterServiceRequestPdu pdu : candidates) {
-                _outgoingPdusWaitingForAck.remove(pdu.getSequenceId());
-            }
-        }
-
-        for (final ClusterServiceRequestPdu pdu : candidates) {
-            s_logger.warn("Cancel cluster request PDU to peer: " + strPeer + ", pdu: " + pdu.getJsonPackage());
-            synchronized (pdu) {
-                pdu.notifyAll();
-            }
-        }
-    }
-
-    private void addOutgoingClusterPdu(final ClusterServicePdu pdu) {
-        synchronized (_clusterPduOutgoingQueue) {
-            _clusterPduOutgoingQueue.add(pdu);
-            _clusterPduOutgoingQueue.notifyAll();
-        }
-    }
-
-    private ClusterServicePdu popOutgoingClusterPdu(final long timeoutMs) {
-        synchronized (_clusterPduOutgoingQueue) {
-            try {
-                _clusterPduOutgoingQueue.wait(timeoutMs);
-            } catch (final InterruptedException e) {
-            }
-
-            if (_clusterPduOutgoingQueue.size() > 0) {
-                final ClusterServicePdu pdu = _clusterPduOutgoingQueue.get(0);
-                _clusterPduOutgoingQueue.remove(0);
-                return pdu;
-            }
-        }
-        return null;
-    }
-
-    private void addIncomingClusterPdu(final ClusterServicePdu pdu) {
-        synchronized (_clusterPduIncomingQueue) {
-            _clusterPduIncomingQueue.add(pdu);
-            _clusterPduIncomingQueue.notifyAll();
-        }
-    }
-
-    private ClusterServicePdu popIncomingClusterPdu(final long timeoutMs) {
-        synchronized (_clusterPduIncomingQueue) {
-            try {
-                _clusterPduIncomingQueue.wait(timeoutMs);
-            } catch (final InterruptedException e) {
-            }
-
-            if (_clusterPduIncomingQueue.size() > 0) {
-                final ClusterServicePdu pdu = _clusterPduIncomingQueue.get(0);
-                _clusterPduIncomingQueue.remove(0);
-                return pdu;
-            }
-        }
-        return null;
-    }
-
-    private Runnable getClusterPduSendingTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                onSendingClusterPdu();
-            }
-        };
-    }
-
-    private Runnable getClusterPduNotificationTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                onNotifyingClusterPdu();
-            }
-        };
-    }
-
-    private void onSendingClusterPdu() {
-        while (true) {
-            try {
-                final ClusterServicePdu pdu = popOutgoingClusterPdu(1000);
-                if (pdu == null) {
-                    continue;
-                }
-
-                ClusterService peerService = null;
-                for (int i = 0; i < 2; i++) {
-                    try {
-                        peerService = getPeerService(pdu.getDestPeer());
-                    } catch (final RemoteException e) {
-                        s_logger.error("Unable to get cluster service on peer : " + pdu.getDestPeer());
-                    }
-
-                    if (peerService != null) {
-                        try {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + ". agent: " + pdu.getAgentId() + ", pdu seq: " +
-                                        pdu.getSequenceId() + ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage());
-                            }
-
-                            final Profiler profiler = new Profiler();
-                            profiler.start();
-
-                            final String strResult = peerService.execute(pdu);
-                            profiler.stop();
-
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + " completed. time: " +
-                                        profiler.getDurationInMillis() + "ms. agent: " + pdu.getAgentId() + ", pdu seq: " + pdu.getSequenceId() +
-                                        ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage());
-                            }
-
-                            if ("true".equals(strResult)) {
-                                break;
-                            }
-
-                        } catch (final RemoteException e) {
-                            invalidatePeerService(pdu.getDestPeer());
-                            if (s_logger.isInfoEnabled()) {
-                                s_logger.info("Exception on remote execution, peer: " + pdu.getDestPeer() + ", iteration: " + i + ", exception message :" +
-                                        e.getMessage());
-                            }
-                        }
-                    }
-                }
-            } catch (final Throwable e) {
-                s_logger.error("Unexcpeted exception: ", e);
-            }
-        }
-    }
-
-    private void onNotifyingClusterPdu() {
-        while (true) {
-            try {
-                final ClusterServicePdu pdu = popIncomingClusterPdu(1000);
-                if (pdu == null) {
-                    continue;
-                }
-
-                _executor.execute(new ManagedContextRunnable() {
-                    @Override
-                    protected void runInContext() {
-                        if (pdu.getPduType() == ClusterServicePdu.PDU_TYPE_RESPONSE) {
-                            final ClusterServiceRequestPdu requestPdu = popRequestPdu(pdu.getAckSequenceId());
-                            if (requestPdu != null) {
-                                requestPdu.setResponseResult(pdu.getJsonPackage());
-                                synchronized (requestPdu) {
-                                    requestPdu.notifyAll();
-                                }
-                            } else {
-                                s_logger.warn("Original request has already been cancelled. pdu: " + pdu.getJsonPackage());
-                            }
-                        } else {
-                            String result = _dispatcher.dispatch(pdu);
-                            if (result == null) {
-                                result = "";
-                            }
-
-                            if (pdu.getPduType() == ClusterServicePdu.PDU_TYPE_REQUEST) {
-                                final ClusterServicePdu responsePdu = new ClusterServicePdu();
-                                responsePdu.setPduType(ClusterServicePdu.PDU_TYPE_RESPONSE);
-                                responsePdu.setSourcePeer(pdu.getDestPeer());
-                                responsePdu.setDestPeer(pdu.getSourcePeer());
-                                responsePdu.setAckSequenceId(pdu.getSequenceId());
-                                responsePdu.setJsonPackage(result);
-
-                                addOutgoingClusterPdu(responsePdu);
-                            }
-                        }
-                    }
-                });
-            } catch (final Throwable e) {
-                s_logger.error("Unexcpeted exception: ", e);
-            }
-        }
-    }
-
-    @Override
-    public void OnReceiveClusterServicePdu(final ClusterServicePdu pdu) {
-        addIncomingClusterPdu(pdu);
-    }
-
-    /**
-     * called by DatabaseUpgradeChecker to see if there are other peers running.
-     *
-     * @param notVersion
-     *            If version is passed in, the peers CANNOT be running at this version. If version is null, return true if any
-     *            peer is running regardless of version.
-     * @return true if there are peers running and false if not.
-     */
-    public static final boolean arePeersRunning(final String notVersion) {
-        return false; // TODO: Leaving this for Kelven to take care of.
-    }
-
-    @Override
-    public void broadcast(final long agentId, final String cmds) {
-        final Date cutTime = DateUtil.currentGMTTime();
-
-        final List<ManagementServerHostVO> peers = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
-        for (final ManagementServerHostVO peer : peers) {
-            final String peerName = Long.toString(peer.getMsid());
-            if (getSelfPeerName().equals(peerName)) {
-                continue; // Skip myself.
-            }
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Forwarding " + cmds + " to " + peer.getMsid());
-                }
-                executeAsync(peerName, agentId, cmds, true);
-            } catch (final Exception e) {
-                s_logger.warn("Caught exception while talkign to " + peer.getMsid());
-            }
-        }
-    }
-
-    public void executeAsync(final String strPeer, final long agentId, final String cmds, final boolean stopOnError) {
-        final ClusterServicePdu pdu = new ClusterServicePdu();
-        pdu.setSourcePeer(getSelfPeerName());
-        pdu.setDestPeer(strPeer);
-        pdu.setAgentId(agentId);
-        pdu.setJsonPackage(cmds);
-        pdu.setStopOnError(true);
-        addOutgoingClusterPdu(pdu);
-    }
-
-    @Override
-    public String execute(final String strPeer, final long agentId, final String cmds, final boolean stopOnError) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(getSelfPeerName() + " -> " + strPeer + "." + agentId + " " + cmds);
-        }
-
-        final ClusterServiceRequestPdu pdu = new ClusterServiceRequestPdu();
-        pdu.setSourcePeer(getSelfPeerName());
-        pdu.setDestPeer(strPeer);
-        pdu.setAgentId(agentId);
-        pdu.setJsonPackage(cmds);
-        pdu.setStopOnError(stopOnError);
-        registerRequestPdu(pdu);
-        addOutgoingClusterPdu(pdu);
-
-        synchronized (pdu) {
-            try {
-                pdu.wait();
-            } catch (final InterruptedException e) {
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(getSelfPeerName() + " -> " + strPeer + "." + agentId + " completed. result: " + pdu.getResponseResult());
-        }
-
-        if (pdu.getResponseResult() != null && pdu.getResponseResult().length() > 0) {
-            return pdu.getResponseResult();
-        }
-
-        return null;
-    }
-
-    @Override
-    public ManagementServerHostVO getPeer(final String mgmtServerId) {
-        return _mshostDao.findByMsid(Long.parseLong(mgmtServerId));
-    }
-
-    @Override
-    public String getSelfPeerName() {
-        return Long.toString(_msId);
-    }
-
-    public String getSelfNodeIP() {
-        return _clusterNodeIP;
-    }
-
-    @Override
-    public void registerListener(final ClusterManagerListener listener) {
-        // Note : we don't check duplicates
-        synchronized (_listeners) {
-
-            s_logger.info("register cluster listener " + listener.getClass());
-
-            _listeners.add(listener);
-        }
-    }
-
-    @Override
-    public void unregisterListener(final ClusterManagerListener listener) {
-        synchronized (_listeners) {
-            s_logger.info("unregister cluster listener " + listener.getClass());
-
-            _listeners.remove(listener);
-        }
-    }
-
-    public void notifyNodeJoined(final List<ManagementServerHostVO> nodeList) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Notify management server node join to listeners.");
-
-            for (final ManagementServerHostVO mshost : nodeList) {
-                s_logger.debug("Joining node, IP: " + mshost.getServiceIP() + ", msid: " + mshost.getMsid());
-            }
-        }
-
-        synchronized (_listeners) {
-            for (final ClusterManagerListener listener : _listeners) {
-                listener.onManagementNodeJoined(nodeList, _mshostId);
-            }
-        }
-
-        SubscriptionMgr.getInstance().notifySubscribers(ClusterManager.ALERT_SUBJECT, this, new ClusterNodeJoinEventArgs(_mshostId, nodeList));
-    }
-
-    public void notifyNodeLeft(final List<ManagementServerHostVO> nodeList) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Notify management server node left to listeners.");
-        }
-
-        for (final ManagementServerHostVO mshost : nodeList) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Leaving node, IP: " + mshost.getServiceIP() + ", msid: " + mshost.getMsid());
-            }
-            cancelClusterRequestToPeer(String.valueOf(mshost.getMsid()));
-        }
-
-        synchronized (_listeners) {
-            for (final ClusterManagerListener listener : _listeners) {
-                listener.onManagementNodeLeft(nodeList, _mshostId);
-            }
-        }
-
-        SubscriptionMgr.getInstance().notifySubscribers(ClusterManager.ALERT_SUBJECT, this, new ClusterNodeLeftEventArgs(_mshostId, nodeList));
-    }
-
-    public void notifyNodeIsolated() {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Notify management server node isolation to listeners");
-        }
-
-        synchronized (_listeners) {
-            for (final ClusterManagerListener listener : _listeners) {
-                listener.onManagementNodeIsolated();
-            }
-        }
-    }
-
-    public ClusterService getPeerService(final String strPeer) throws RemoteException {
-        synchronized (_clusterPeers) {
-            if (_clusterPeers.containsKey(strPeer)) {
-                return _clusterPeers.get(strPeer);
-            }
-        }
-
-        final ClusterService service = _currentServiceAdapter.getPeerService(strPeer);
-
-        if (service != null) {
-            synchronized (_clusterPeers) {
-                // re-check the peer map again to deal with the
-                // race conditions
-                if (!_clusterPeers.containsKey(strPeer)) {
-                    _clusterPeers.put(strPeer, service);
-                }
-            }
-        }
-
-        return service;
-    }
-
-    public void invalidatePeerService(final String strPeer) {
-        synchronized (_clusterPeers) {
-            if (_clusterPeers.containsKey(strPeer)) {
-                _clusterPeers.remove(strPeer);
-            }
-        }
-    }
-
-    private Runnable getHeartbeatTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                final TransactionLegacy txn = TransactionLegacy.open("ClusterHeartbeat");
-                try {
-                    final Profiler profiler = new Profiler();
-                    final Profiler profilerHeartbeatUpdate = new Profiler();
-                    final Profiler profilerPeerScan = new Profiler();
-
-                    try {
-                        profiler.start();
-
-                        profilerHeartbeatUpdate.start();
-                        txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB);
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("Cluster manager heartbeat update, id:" + _mshostId);
-                        }
-
-                        _mshostDao.update(_mshostId, _runId, DateUtil.currentGMTTime());
-                        profilerHeartbeatUpdate.stop();
-
-                        profilerPeerScan.start();
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("Cluster manager peer-scan, id:" + _mshostId);
-                        }
-
-                        if (!_peerScanInited) {
-                            _peerScanInited = true;
-                            initPeerScan();
-                        }
-
-                        peerScan();
-                        profilerPeerScan.stop();
-
-                    } finally {
-                        profiler.stop();
-
-                        if (profiler.getDurationInMillis() >= HeartbeatInterval.value()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Management server heartbeat takes too long to finish. profiler: " + profiler.toString() + ", profilerHeartbeatUpdate: " +
-                                        profilerHeartbeatUpdate.toString() + ", profilerPeerScan: " + profilerPeerScan.toString());
-                            }
-                        }
-                    }
-
-                } catch (final CloudRuntimeException e) {
-                    s_logger.error("Runtime DB exception ", e.getCause());
-
-                    if (e.getCause() instanceof ClusterInvalidSessionException) {
-                        s_logger.error("Invalid cluster session found, fence it");
-                        queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
-                    }
-
-                    if (isRootCauseConnectionRelated(e.getCause())) {
-                        invalidHeartbeatConnection();
-                    }
-                } catch (final ActiveFencingException e) {
-                    queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
-                } catch (final Throwable e) {
-                    s_logger.error("Unexpected exception in cluster heartbeat", e);
-                    if (isRootCauseConnectionRelated(e.getCause())) {
-                        invalidHeartbeatConnection();
-                    }
-                } finally {
-                    txn.close("ClusterHeartbeat");
-                }
-            }
-        };
-    }
-
-    private boolean isRootCauseConnectionRelated(Throwable e) {
-        while (e != null) {
-            if (e instanceof SQLRecoverableException || e instanceof SQLNonTransientException) {
-                return true;
-            }
-
-            e = e.getCause();
-        }
-
-        return false;
-    }
-
-    private void invalidHeartbeatConnection() {
-        if (_heartbeatConnection != null) {
-            final Connection conn = TransactionLegacy.getStandaloneConnection();
-            if (conn != null) {
-                _heartbeatConnection.reset(conn);
-            } else {
-                s_logger.error("DB communication problem detected, fence it");
-                queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
-            }
-            // The stand-alone connection does not have to be closed here because there will be another reference to it.
-            // As a matter of fact, it will be assigned to the connection instance variable in the ConnectionConcierge class.
-        }
-    }
-
-    private Runnable getNotificationTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                while (true) {
-                    synchronized (_notificationMsgs) {
-                        try {
-                            _notificationMsgs.wait(1000);
-                        } catch (final InterruptedException e) {
-                        }
-                    }
-
-                    ClusterManagerMessage msg = null;
-                    while ((msg = getNextNotificationMessage()) != null) {
-                        try {
-                            switch (msg.getMessageType()) {
-                            case nodeAdded:
-                                if (msg.getNodes() != null && msg.getNodes().size() > 0) {
-                                    final Profiler profiler = new Profiler();
-                                    profiler.start();
-
-                                    notifyNodeJoined(msg.getNodes());
-
-                                    profiler.stop();
-                                    if (profiler.getDurationInMillis() > 1000) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Notifying management server join event took " + profiler.getDurationInMillis() + " ms");
-                                        }
-                                    } else {
-                                        s_logger.warn("Notifying management server join event took " + profiler.getDurationInMillis() + " ms");
-                                    }
-                                }
-                                break;
-
-                            case nodeRemoved:
-                                if (msg.getNodes() != null && msg.getNodes().size() > 0) {
-                                    final Profiler profiler = new Profiler();
-                                    profiler.start();
-
-                                    notifyNodeLeft(msg.getNodes());
-
-                                    profiler.stop();
-                                    if (profiler.getDurationInMillis() > 1000) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Notifying management server leave event took " + profiler.getDurationInMillis() + " ms");
-                                        }
-                                    } else {
-                                        s_logger.warn("Notifying management server leave event took " + profiler.getDurationInMillis() + " ms");
-                                    }
-                                }
-                                break;
-
-                            case nodeIsolated:
-                                notifyNodeIsolated();
-                                break;
-
-                            default:
-                                assert false;
-                                break;
-                            }
-
-                        } catch (final Throwable e) {
-                            s_logger.warn("Unexpected exception during cluster notification. ", e);
-                        }
-                    }
-
-                    try {
-                        Thread.sleep(1000);
-                    } catch (final InterruptedException e) {
-                    }
-                }
-            }
-        };
-    }
-
-    private void queueNotification(final ClusterManagerMessage msg) {
-        synchronized (_notificationMsgs) {
-            _notificationMsgs.add(msg);
-            _notificationMsgs.notifyAll();
-        }
-
-        switch (msg.getMessageType()) {
-        case nodeAdded: {
-            final List<ManagementServerHostVO> l = msg.getNodes();
-            if (l != null && l.size() > 0) {
-                for (final ManagementServerHostVO mshost : l) {
-                    _mshostPeerDao.updatePeerInfo(_mshostId, mshost.getId(), mshost.getRunid(), ManagementServerHost.State.Up);
-                }
-            }
-        }
-        break;
-
-        case nodeRemoved: {
-            final List<ManagementServerHostVO> l = msg.getNodes();
-            if (l != null && l.size() > 0) {
-                for (final ManagementServerHostVO mshost : l) {
-                    _mshostPeerDao.updatePeerInfo(_mshostId, mshost.getId(), mshost.getRunid(), ManagementServerHost.State.Down);
-                }
-            }
-        }
-        break;
-
-        default:
-            break;
-        }
-    }
-
-    private ClusterManagerMessage getNextNotificationMessage() {
-        synchronized (_notificationMsgs) {
-            if (_notificationMsgs.size() > 0) {
-                return _notificationMsgs.remove(0);
-            }
-        }
-
-        return null;
-    }
-
-    private void initPeerScan() {
-        // upon startup, for all inactive management server nodes that we see at startup time, we will send notification also to help upper layer perform
-        // missed cleanup
-        final Date cutTime = DateUtil.currentGMTTime();
-        final List<ManagementServerHostVO> inactiveList = _mshostDao.getInactiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
-
-        // We don't have foreign key constraints to enforce the mgmt_server_id integrity in host table, when user manually
-        // remove records from mshost table, this will leave orphan mgmt_serve_id reference in host table.
-        final List<Long> orphanList = _mshostDao.listOrphanMsids();
-        if (orphanList.size() > 0) {
-            for (final Long orphanMsid : orphanList) {
-                // construct fake ManagementServerHostVO based on orphan MSID
-                s_logger.info("Add orphan management server msid found in host table to initial clustering notification, orphan msid: " + orphanMsid);
-                inactiveList.add(new ManagementServerHostVO(orphanMsid, 0, "orphan", 0, new Date()));
-            }
-        } else {
-            s_logger.info("We are good, no orphan management server msid in host table is found");
-        }
-
-        if (inactiveList.size() > 0) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Found " + inactiveList.size() + " inactive management server node based on timestamp");
-                for (final ManagementServerHostVO host : inactiveList) {
-                    s_logger.info("management server node msid: " + host.getMsid() + ", name: " + host.getName() + ", service ip: " + host.getServiceIP() +
-                            ", version: " + host.getVersion());
-                }
-            }
-
-            final List<ManagementServerHostVO> downHostList = new ArrayList<ManagementServerHostVO>();
-            for (final ManagementServerHostVO host : inactiveList) {
-                if (!pingManagementNode(host)) {
-                    s_logger.warn("Management node " + host.getId() + " is detected inactive by timestamp and also not pingable");
-                    downHostList.add(host);
-                }
-            }
-
-            if (downHostList.size() > 0) {
-                queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, downHostList));
-            }
-        } else {
-            s_logger.info("No inactive management server node found");
-        }
-    }
-
-    private void peerScan() throws ActiveFencingException {
-        final Date cutTime = DateUtil.currentGMTTime();
-
-        final Profiler profiler = new Profiler();
-        profiler.start();
-
-        final Profiler profilerQueryActiveList = new Profiler();
-        profilerQueryActiveList.start();
-        final List<ManagementServerHostVO> currentList = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
-        profilerQueryActiveList.stop();
-
-        final Profiler profilerSyncClusterInfo = new Profiler();
-        profilerSyncClusterInfo.start();
-        final List<ManagementServerHostVO> removedNodeList = new ArrayList<ManagementServerHostVO>();
-        final List<ManagementServerHostVO> invalidatedNodeList = new ArrayList<ManagementServerHostVO>();
-
-        if (_mshostId != null) {
-
-            if (_mshostPeerDao.countStateSeenInPeers(_mshostId, _runId, ManagementServerHost.State.Down) > 0) {
-                final String msg =
-                        "We have detected that at least one management server peer reports that this management server is down, perform active fencing to avoid split-brain situation";
-                s_logger.error(msg);
-                throw new ActiveFencingException(msg);
-            }
-
-            // only if we have already attached to cluster, will we start to check leaving nodes
-            for (final Map.Entry<Long, ManagementServerHostVO> entry : _activePeers.entrySet()) {
-
-                final ManagementServerHostVO current = getInListById(entry.getKey(), currentList);
-                if (current == null) {
-                    if (entry.getKey().longValue() != _mshostId.longValue()) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Detected management node left, id:" + entry.getKey() + ", nodeIP:" + entry.getValue().getServiceIP());
-                        }
-                        removedNodeList.add(entry.getValue());
-                    }
-                } else {
-                    if (current.getRunid() == 0) {
-                        if (entry.getKey().longValue() != _mshostId.longValue()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Detected management node left because of invalidated session, id:" + entry.getKey() + ", nodeIP:" +
-                                        entry.getValue().getServiceIP());
-                            }
-                            invalidatedNodeList.add(entry.getValue());
-                        }
-                    } else {
-                        if (entry.getValue().getRunid() != current.getRunid()) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Detected management node left and rejoined quickly, id:" + entry.getKey() + ", nodeIP:" + entry.getValue().getServiceIP());
-                            }
-
-                            entry.getValue().setRunid(current.getRunid());
-                        }
-                    }
-                }
-            }
-        }
-        profilerSyncClusterInfo.stop();
-
-        final Profiler profilerInvalidatedNodeList = new Profiler();
-        profilerInvalidatedNodeList.start();
-        // process invalidated node list
-        if (invalidatedNodeList.size() > 0) {
-            for (final ManagementServerHostVO mshost : invalidatedNodeList) {
-                _activePeers.remove(mshost.getId());
-                try {
-                    JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
-                }
-            }
-
-            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, invalidatedNodeList));
-        }
-        profilerInvalidatedNodeList.stop();
-
-        final Profiler profilerRemovedList = new Profiler();
-        profilerRemovedList.start();
-        // process removed node list
-        final Iterator<ManagementServerHostVO> it = removedNodeList.iterator();
-        while (it.hasNext()) {
-            final ManagementServerHostVO mshost = it.next();
-            if (!pingManagementNode(mshost)) {
-                s_logger.warn("Management node " + mshost.getId() + " is detected inactive by timestamp and also not pingable");
-                _activePeers.remove(mshost.getId());
-                try {
-                    JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
-                }
-            } else {
-                s_logger.info("Management node " + mshost.getId() + " is detected inactive by timestamp but is pingable");
-                it.remove();
-            }
-        }
-
-        if (removedNodeList.size() > 0) {
-            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, removedNodeList));
-        }
-        profilerRemovedList.stop();
-
-        final List<ManagementServerHostVO> newNodeList = new ArrayList<ManagementServerHostVO>();
-        for (final ManagementServerHostVO mshost : currentList) {
-            if (!_activePeers.containsKey(mshost.getId())) {
-                _activePeers.put(mshost.getId(), mshost);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Detected management node joined, id:" + mshost.getId() + ", nodeIP:" + mshost.getServiceIP());
-                }
-                newNodeList.add(mshost);
-
-                try {
-                    JmxUtil.registerMBean("ClusterManager", "Node " + mshost.getId(), new ClusterManagerMBeanImpl(this, mshost));
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to regiester cluster node into JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                }
-            }
-        }
-
-        if (newNodeList.size() > 0) {
-            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeAdded, newNodeList));
-        }
-
-        profiler.stop();
-
-        if (profiler.getDurationInMillis() >= HeartbeatInterval.value()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Peer scan takes too long to finish. profiler: " + profiler.toString() + ", profilerQueryActiveList: " +
-                        profilerQueryActiveList.toString() + ", profilerSyncClusterInfo: " + profilerSyncClusterInfo.toString() + ", profilerInvalidatedNodeList: " +
-                        profilerInvalidatedNodeList.toString() + ", profilerRemovedList: " + profilerRemovedList.toString());
-            }
-        }
-    }
-
-    private static ManagementServerHostVO getInListById(final Long id, final List<ManagementServerHostVO> l) {
-        for (final ManagementServerHostVO mshost : l) {
-            if (mshost.getId() == id) {
-                return mshost;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    @DB
-    public boolean start() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Starting Cluster manager, msid : " + _msId);
-        }
-
-        final ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback<ManagementServerHostVO>() {
-            @Override
-            public ManagementServerHostVO doInTransaction(final TransactionStatus status) {
-
-                final Class<?> c = this.getClass();
-                final String version = c.getPackage().getImplementationVersion();
-
-                ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
-                if (mshost == null) {
-                    mshost = new ManagementServerHostVO();
-                    mshost.setMsid(_msId);
-                    mshost.setRunid(_runId);
-                    mshost.setName(NetUtils.getHostName());
-                    mshost.setVersion(version);
-                    mshost.setServiceIP(_clusterNodeIP);
-                    mshost.setServicePort(_currentServiceAdapter.getServicePort());
-                    mshost.setLastUpdateTime(DateUtil.currentGMTTime());
-                    mshost.setRemoved(null);
-                    mshost.setAlertCount(0);
-                    mshost.setState(ManagementServerHost.State.Up);
-                    _mshostDao.persist(mshost);
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("New instance of management server msid " + _msId + ", runId " + _runId + " is being started");
-                    }
-                } else {
-                    _mshostDao.update(mshost.getId(), _runId, NetUtils.getHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(),
-                            DateUtil.currentGMTTime());
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Management server " + _msId + ", runId " + _runId + " is being started");
-                    }
-                }
-
-                return mshost;
-            }
-        });
-
-        _mshostId = mshost.getId();
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort());
-        }
-
-        _mshostPeerDao.clearPeerInfo(_mshostId);
-
-        // use seperate thread for heartbeat updates
-        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS);
-        _notificationExecutor.submit(getNotificationTask());
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Cluster manager was started successfully");
-        }
-
-        return true;
-    }
-
-    @Override
-    @DB
-    public boolean stop() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Stopping Cluster manager, msid : " + _msId);
-        }
-
-        if (_mshostId != null) {
-            final ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
-            mshost.setState(ManagementServerHost.State.Down);
-            _mshostDao.update(_mshostId, mshost);
-        }
-
-        _heartbeatScheduler.shutdownNow();
-        _executor.shutdownNow();
-
-        try {
-            _heartbeatScheduler.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
-            _executor.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
-        } catch (final InterruptedException e) {
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Cluster manager is stopped");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start configuring cluster manager : " + name);
-        }
-
-        final Properties dbProps = DbProperties.getDbProperties();
-        _clusterNodeIP = dbProps.getProperty("cluster.node.IP");
-        if (_clusterNodeIP == null) {
-            _clusterNodeIP = "127.0.0.1";
-        }
-        _clusterNodeIP = _clusterNodeIP.trim();
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Cluster node IP : " + _clusterNodeIP);
-        }
-
-        if (!NetUtils.isLocalAddress(_clusterNodeIP)) {
-            throw new ConfigurationException("cluster node IP should be valid local address where the server is running, please check your configuration");
-        }
-
-        for (int i = 0; i < DEFAULT_OUTGOING_WORKERS; i++) {
-            _executor.execute(getClusterPduSendingTask());
-        }
-
-        // notification task itself in turn works as a task dispatcher
-        _executor.execute(getClusterPduNotificationTask());
-
-        if (_serviceAdapters == null) {
-            throw new ConfigurationException("Unable to get cluster service adapters");
-        }
-        _currentServiceAdapter = _serviceAdapters.get(0);
-
-        if (_currentServiceAdapter == null) {
-            throw new ConfigurationException("Unable to set current cluster service adapter");
-        }
-
-        checkConflicts();
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Cluster manager is configured.");
-        }
-        return true;
-    }
-
-    @Override
-    public long getManagementNodeId() {
-        return _msId;
-    }
-
-    @Override
-    public long getCurrentRunId() {
-        return _runId;
-    }
-
-    @Override
-    public long getManagementRunId(final long msId) {
-        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msId);
-        if (mshost != null) {
-            return mshost.getRunid();
-        }
-        return -1;
-    }
-
-    public boolean isManagementNodeAlive(final long msid) {
-        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msid);
-        if (mshost != null) {
-            if (mshost.getLastUpdateTime().getTime() >= DateUtil.currentGMTTime().getTime() - HeartbeatThreshold.value()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public boolean pingManagementNode(final long msid) {
-        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msid);
-        if (mshost == null) {
-            return false;
-        }
-
-        return pingManagementNode(mshost);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ClusterManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {HeartbeatInterval, HeartbeatThreshold};
-    }
-
-    private boolean pingManagementNode(final ManagementServerHostVO mshost) {
-
-        final String targetIp = mshost.getServiceIP();
-        if ("127.0.0.1".equals(targetIp) || "0.0.0.0".equals(targetIp)) {
-            s_logger.info("ping management node cluster service can not be performed on self");
-            return false;
-        }
-
-        int retry = 10;
-        while (--retry > 0) {
-            SocketChannel sch = null;
-            try {
-                s_logger.info("Trying to connect to " + targetIp);
-                sch = SocketChannel.open();
-                sch.configureBlocking(true);
-                sch.socket().setSoTimeout(5000);
-
-                final InetSocketAddress addr = new InetSocketAddress(targetIp, mshost.getServicePort());
-                sch.connect(addr);
-                return true;
-            } catch (final IOException e) {
-                if (e instanceof ConnectException) {
-                    s_logger.error("Unable to ping management server at " + targetIp + ":" + mshost.getServicePort() + " due to ConnectException", e);
-                    return false;
-                }
-            } finally {
-                if (sch != null) {
-                    try {
-                        sch.close();
-                    } catch (final IOException e) {
-                    }
-                }
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (final InterruptedException ex) {
-            }
-        }
-
-        s_logger.error("Unable to ping management server at " + targetIp + ":" + mshost.getServicePort() + " after retries");
-        return false;
-    }
-
-    public int getHeartbeatInterval() {
-        return HeartbeatInterval.value();
-    }
-
-    private void checkConflicts() throws ConfigurationException {
-        final Date cutTime = DateUtil.currentGMTTime();
-        final List<ManagementServerHostVO> peers = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
-        for (final ManagementServerHostVO peer : peers) {
-            final String peerIP = peer.getServiceIP().trim();
-            if (_clusterNodeIP.equals(peerIP)) {
-                if ("127.0.0.1".equals(_clusterNodeIP)) {
-                    if (pingManagementNode(peer.getMsid())) {
-                        final String msg = "Detected another management node with localhost IP is already running, please check your cluster configuration";
-                        s_logger.error(msg);
-                        throw new ConfigurationException(msg);
-                    } else {
-                        final String msg =
-                                "Detected another management node with localhost IP is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node";
-                        s_logger.info(msg);
-                    }
-                } else {
-                    if (pingManagementNode(peer.getMsid())) {
-                        final String msg =
-                                "Detected that another management node with the same IP " + peer.getServiceIP() +
-                                " is already running, please check your cluster configuration";
-                        s_logger.error(msg);
-                        throw new ConfigurationException(msg);
-                    } else {
-                        final String msg =
-                                "Detected that another management node with the same IP " + peer.getServiceIP() +
-                                " is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node";
-                        s_logger.info(msg);
-                    }
-                }
-            }
-        }
-    }
-
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerListener.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerListener.java
deleted file mode 100644
index 2fe1f24..0000000
--- a/framework/cluster/src/com/cloud/cluster/ClusterManagerListener.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import java.util.List;
-
-public interface ClusterManagerListener {
-    void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId);
-
-    void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId);
-
-    void onManagementNodeIsolated();
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ManagementServerHost.java b/framework/cluster/src/com/cloud/cluster/ManagementServerHost.java
deleted file mode 100644
index 7fc57b7..0000000
--- a/framework/cluster/src/com/cloud/cluster/ManagementServerHost.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-public interface ManagementServerHost {
-    long getId();
-
-    public static enum State {
-        Up, Starting, Down
-    };
-
-    long getMsid();
-
-    State getState();
-
-    String getVersion();
-
-    String getServiceIP();
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ManagementServerHostPeerVO.java b/framework/cluster/src/com/cloud/cluster/ManagementServerHostPeerVO.java
deleted file mode 100644
index 5b7e988..0000000
--- a/framework/cluster/src/com/cloud/cluster/ManagementServerHostPeerVO.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import com.cloud.utils.DateUtil;
-
-@Entity
-@Table(name = "mshost_peer")
-public class ManagementServerHostPeerVO {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "owner_mshost", updatable = true, nullable = false)
-    private long ownerMshost;
-
-    @Column(name = "peer_mshost", updatable = true, nullable = false)
-    private long peerMshost;
-
-    @Column(name = "peer_runid", updatable = true, nullable = false)
-    private long peerRunid;
-
-    @Column(name = "peer_state", updatable = true, nullable = false)
-    @Enumerated(value = EnumType.STRING)
-    private ManagementServerHost.State peerState;
-
-    @Temporal(TemporalType.TIMESTAMP)
-    @Column(name = "last_update", updatable = true, nullable = true)
-    private Date lastUpdateTime;
-
-    public ManagementServerHostPeerVO() {
-    }
-
-    public ManagementServerHostPeerVO(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState) {
-        this.ownerMshost = ownerMshost;
-        this.peerMshost = peerMshost;
-        this.peerRunid = peerRunid;
-        this.peerState = peerState;
-
-        lastUpdateTime = DateUtil.currentGMTTime();
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public long getOwnerMshost() {
-        return ownerMshost;
-    }
-
-    public void setOwnerMshost(long ownerMshost) {
-        this.ownerMshost = ownerMshost;
-    }
-
-    public long getPeerMshost() {
-        return peerMshost;
-    }
-
-    public void setPeerMshost(long peerMshost) {
-        this.peerMshost = peerMshost;
-    }
-
-    public long getPeerRunid() {
-        return peerRunid;
-    }
-
-    public void setPeerRunid(long peerRunid) {
-        this.peerRunid = peerRunid;
-    }
-
-    public ManagementServerHost.State getPeerState() {
-        return peerState;
-    }
-
-    public void setPeerState(ManagementServerHost.State peerState) {
-        this.peerState = peerState;
-    }
-
-    public Date getLastUpdateTime() {
-        return lastUpdateTime;
-    }
-
-    public void setLastUpdateTime(Date lastUpdateTime) {
-        this.lastUpdateTime = lastUpdateTime;
-    }
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ManagementServerHostVO.java b/framework/cluster/src/com/cloud/cluster/ManagementServerHostVO.java
deleted file mode 100644
index f93c2ac..0000000
--- a/framework/cluster/src/com/cloud/cluster/ManagementServerHostVO.java
+++ /dev/null
@@ -1,183 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "mshost")
-public class ManagementServerHostVO implements ManagementServerHost {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "msid", updatable = true, nullable = false)
-    private long msid;
-
-    @Column(name = "runid", updatable = true, nullable = false)
-    private long runid;
-
-    @Column(name = "name", updatable = true, nullable = true)
-    private String name;
-
-    @Column(name = "state", updatable = true, nullable = false)
-    @Enumerated(value = EnumType.STRING)
-    private ManagementServerHost.State state;
-
-    @Column(name = "version", updatable = true, nullable = true)
-    private String version;
-
-    @Column(name = "service_ip", updatable = true, nullable = false)
-    private String serviceIP;
-
-    @Column(name = "service_port", updatable = true, nullable = false)
-    private int servicePort;
-
-    @Temporal(TemporalType.TIMESTAMP)
-    @Column(name = "last_update", updatable = true, nullable = true)
-    private Date lastUpdateTime;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = "alert_count", updatable = true, nullable = false)
-    private int alertCount;
-
-    public ManagementServerHostVO() {
-    }
-
-    public ManagementServerHostVO(long msid, long runid, String serviceIP, int servicePort, Date updateTime) {
-        this.msid = msid;
-        this.runid = runid;
-        this.serviceIP = serviceIP;
-        this.servicePort = servicePort;
-        lastUpdateTime = updateTime;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public long getRunid() {
-        return runid;
-    }
-
-    public void setRunid(long runid) {
-        this.runid = runid;
-    }
-
-    @Override
-    public long getMsid() {
-        return msid;
-    }
-
-    public void setMsid(long msid) {
-        this.msid = msid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public ManagementServerHost.State getState() {
-        return state;
-    }
-
-    public void setState(ManagementServerHost.State state) {
-        this.state = state;
-    }
-
-    @Override
-    public String getVersion() {
-        return version;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    @Override
-    public String getServiceIP() {
-        return serviceIP;
-    }
-
-    public void setServiceIP(String serviceIP) {
-        this.serviceIP = serviceIP;
-    }
-
-    public int getServicePort() {
-        return servicePort;
-    }
-
-    public void setServicePort(int servicePort) {
-        this.servicePort = servicePort;
-    }
-
-    public Date getLastUpdateTime() {
-        return lastUpdateTime;
-    }
-
-    public void setLastUpdateTime(Date lastUpdateTime) {
-        this.lastUpdateTime = lastUpdateTime;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public void setRemoved(Date removedTime) {
-        removed = removedTime;
-    }
-
-    public int getAlertCount() {
-        return alertCount;
-    }
-
-    public void setAlertCount(int count) {
-        alertCount = count;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("ManagementServer[").append("-").append(id).append("-").append(msid).append("-").append(state).append("]").toString();
-    }
-}
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDao.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDao.java
deleted file mode 100644
index d6b25c1..0000000
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDao.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerHost.State;
-import com.cloud.cluster.ManagementServerHostVO;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDao;
-
-public interface ManagementServerHostDao extends GenericDao<ManagementServerHostVO, Long> {
-    @Override
-    boolean remove(Long id);
-
-    ManagementServerHostVO findByMsid(long msid);
-
-    int increaseAlertCount(long id);
-
-    void update(long id, long runid, String name, String version, String serviceIP, int servicePort, Date lastUpdate);
-
-    void update(long id, long runid, Date lastUpdate);
-
-    List<ManagementServerHostVO> getActiveList(Date cutTime);
-
-    List<ManagementServerHostVO> getInactiveList(Date cutTime);
-
-    void invalidateRunSession(long id, long runid);
-
-    void update(long id, long runId, State state, Date lastUpdate);
-
-    List<ManagementServerHostVO> listBy(ManagementServerHost.State... states);
-
-    public List<Long> listOrphanMsids();
-
-    ManagementServerHostVO findOneInUpState(Filter filter);
-}
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
deleted file mode 100644
index 3ab4d97..0000000
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
+++ /dev/null
@@ -1,275 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.TimeZone;
-
-
-import org.apache.log4j.Logger;
-
-import com.cloud.cluster.ClusterInvalidSessionException;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerHost.State;
-import com.cloud.cluster.ManagementServerHostVO;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServerHostVO, Long> implements ManagementServerHostDao {
-    private static final Logger s_logger = Logger.getLogger(ManagementServerHostDaoImpl.class);
-
-    private final SearchBuilder<ManagementServerHostVO> MsIdSearch;
-    private final SearchBuilder<ManagementServerHostVO> ActiveSearch;
-    private final SearchBuilder<ManagementServerHostVO> InactiveSearch;
-    private final SearchBuilder<ManagementServerHostVO> StateSearch;
-
-    @Override
-    public void invalidateRunSession(long id, long runid) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement("update mshost set runid=0, state='Down' where id=? and runid=?");
-            pstmt.setLong(1, id);
-            pstmt.setLong(2, runid);
-
-            pstmt.executeUpdate();
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB exception: ", e);
-        }
-    }
-
-    @Override
-    public ManagementServerHostVO findByMsid(long msid) {
-        SearchCriteria<ManagementServerHostVO> sc = MsIdSearch.create();
-        sc.setParameters("msid", msid);
-
-        List<ManagementServerHostVO> l = listIncludingRemovedBy(sc);
-        if (l != null && l.size() > 0) {
-            return l.get(0);
-        }
-
-        return null;
-    }
-
-    @Override
-    @DB
-    public void update(long id, long runid, String name, String version, String serviceIP, int servicePort, Date lastUpdate) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-
-            pstmt =
-                txn.prepareAutoCloseStatement("update mshost set name=?, version=?, service_ip=?, service_port=?, last_update=?, removed=null, alert_count=0, runid=?, state=? where id=?");
-            pstmt.setString(1, name);
-            pstmt.setString(2, version);
-            pstmt.setString(3, serviceIP);
-            pstmt.setInt(4, servicePort);
-            pstmt.setString(5, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
-            pstmt.setLong(6, runid);
-            pstmt.setString(7, ManagementServerHost.State.Up.toString());
-            pstmt.setLong(8, id);
-
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception e) {
-            s_logger.warn("Unexpected exception, ", e);
-            throw new RuntimeException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    @DB
-    public boolean remove(Long id) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-
-        try {
-            txn.start();
-
-            ManagementServerHostVO msHost = findById(id);
-            msHost.setState(ManagementServerHost.State.Down);
-            super.remove(id);
-
-            txn.commit();
-            return true;
-        } catch (Exception e) {
-            s_logger.warn("Unexpected exception, ", e);
-            throw new RuntimeException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    @DB
-    public void update(long id, long runid, Date lastUpdate) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-
-            pstmt = txn.prepareAutoCloseStatement("update mshost set last_update=?, removed=null, alert_count=0 where id=? and runid=?");
-            pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
-            pstmt.setLong(2, id);
-            pstmt.setLong(3, runid);
-
-            int count = pstmt.executeUpdate();
-            txn.commit();
-
-            if (count < 1) {
-                s_logger.info("Invalid cluster session detected, runId " + runid + " is no longer valid");
-                throw new CloudRuntimeException("Invalid cluster session detected, runId " + runid + " is no longer valid", new ClusterInvalidSessionException("runId " + runid + " is no longer valid"));
-            }
-        } catch (Exception e) {
-            s_logger.warn("Unexpected exception, ", e);
-            throw new RuntimeException(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public List<ManagementServerHostVO> getActiveList(Date cutTime) {
-        SearchCriteria<ManagementServerHostVO> sc = ActiveSearch.create();
-        sc.setParameters("lastUpdateTime", cutTime);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    public List<ManagementServerHostVO> getInactiveList(Date cutTime) {
-        SearchCriteria<ManagementServerHostVO> sc = InactiveSearch.create();
-        sc.setParameters("lastUpdateTime", cutTime);
-
-        return listIncludingRemovedBy(sc);
-    }
-
-    @Override
-    @DB
-    public int increaseAlertCount(long id) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        int changedRows = 0;
-        try {
-            txn.start();
-
-            pstmt = txn.prepareAutoCloseStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0");
-            pstmt.setLong(1, id);
-
-            changedRows = pstmt.executeUpdate();
-            txn.commit();
-        } catch (Exception e) {
-            s_logger.warn("Unexpected exception, ", e);
-            throw new RuntimeException(e.getMessage(), e);
-        }
-
-        return changedRows;
-    }
-
-    protected ManagementServerHostDaoImpl() {
-        MsIdSearch = createSearchBuilder();
-        MsIdSearch.and("msid", MsIdSearch.entity().getMsid(), SearchCriteria.Op.EQ);
-        MsIdSearch.done();
-
-        ActiveSearch = createSearchBuilder();
-        ActiveSearch.and("lastUpdateTime", ActiveSearch.entity().getLastUpdateTime(), SearchCriteria.Op.GT);
-        ActiveSearch.and("removed", ActiveSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-        ActiveSearch.done();
-
-        InactiveSearch = createSearchBuilder();
-        InactiveSearch.and("lastUpdateTime", InactiveSearch.entity().getLastUpdateTime(), SearchCriteria.Op.LTEQ);
-        InactiveSearch.and("removed", InactiveSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
-        InactiveSearch.done();
-
-        StateSearch = createSearchBuilder();
-        StateSearch.and("state", StateSearch.entity().getState(), SearchCriteria.Op.IN);
-        StateSearch.done();
-    }
-
-    @Override
-    public void update(long id, long runId, State state, Date lastUpdate) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement("update mshost set state=?, last_update=? where id=? and runid=?");
-            pstmt.setString(1, state.toString());
-            pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
-            pstmt.setLong(3, id);
-            pstmt.setLong(4, runId);
-
-            int count = pstmt.executeUpdate();
-
-            if (count < 1) {
-                s_logger.info("Invalid cluster session detected, runId " + runId + " is no longer valid");
-                throw new CloudRuntimeException("Invalid cluster session detected, runId " + runId + " is no longer valid", new ClusterInvalidSessionException("runId " + runId + " is no longer valid"));
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB exception: ", e);
-        }
-    }
-
-    @Override
-    public List<ManagementServerHostVO> listBy(ManagementServerHost.State... states) {
-        SearchCriteria<ManagementServerHostVO> sc = StateSearch.create();
-
-        sc.setParameters("state", (Object[])states);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public List<Long> listOrphanMsids() {
-        List<Long> orphanList = new ArrayList<Long>();
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt =
-                txn.prepareAutoCloseStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)");
-
-            ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                orphanList.add(rs.getLong(1));
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB exception: ", e);
-        }
-
-        return orphanList;
-    }
-
-    @Override
-    public ManagementServerHostVO findOneInUpState(Filter filter) {
-        SearchCriteria<ManagementServerHostVO> sc = StateSearch.create();
-
-        sc.setParameters("state", ManagementServerHost.State.Up);
-
-        List<ManagementServerHostVO> mshosts = listBy(sc, filter);
-        if (mshosts != null && mshosts.size() > 0) {
-            return mshosts.get(0);
-        }
-        return null;
-    }
-
-}
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java
deleted file mode 100644
index 6d21049..0000000
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDao.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster.dao;
-
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerHostPeerVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface ManagementServerHostPeerDao extends GenericDao<ManagementServerHostPeerVO, Long> {
-    void clearPeerInfo(long ownerMshost);
-
-    void updatePeerInfo(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState);
-
-    int countStateSeenInPeers(long mshost, long runid, ManagementServerHost.State state);
-}
diff --git a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java b/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
deleted file mode 100644
index a43fcfc..0000000
--- a/framework/cluster/src/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.cluster.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.ManagementServerHostPeerVO;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-
-public class ManagementServerHostPeerDaoImpl extends GenericDaoBase<ManagementServerHostPeerVO, Long> implements ManagementServerHostPeerDao {
-    private static final Logger s_logger = Logger.getLogger(ManagementServerHostPeerDaoImpl.class);
-
-    private final SearchBuilder<ManagementServerHostPeerVO> ClearPeerSearch;
-    private final SearchBuilder<ManagementServerHostPeerVO> FindForUpdateSearch;
-    private final SearchBuilder<ManagementServerHostPeerVO> CountSearch;
-
-    public ManagementServerHostPeerDaoImpl() {
-        ClearPeerSearch = createSearchBuilder();
-        ClearPeerSearch.and("ownerMshost", ClearPeerSearch.entity().getOwnerMshost(), SearchCriteria.Op.EQ);
-        ClearPeerSearch.done();
-
-        FindForUpdateSearch = createSearchBuilder();
-        FindForUpdateSearch.and("ownerMshost", FindForUpdateSearch.entity().getOwnerMshost(), SearchCriteria.Op.EQ);
-        FindForUpdateSearch.and("peerMshost", FindForUpdateSearch.entity().getPeerMshost(), SearchCriteria.Op.EQ);
-        FindForUpdateSearch.and("peerRunid", FindForUpdateSearch.entity().getPeerRunid(), SearchCriteria.Op.EQ);
-        FindForUpdateSearch.done();
-
-        CountSearch = createSearchBuilder();
-        CountSearch.and("peerMshost", CountSearch.entity().getPeerMshost(), SearchCriteria.Op.EQ);
-        CountSearch.and("peerRunid", CountSearch.entity().getPeerRunid(), SearchCriteria.Op.EQ);
-        CountSearch.and("peerState", CountSearch.entity().getPeerState(), SearchCriteria.Op.EQ);
-        CountSearch.done();
-    }
-
-    @Override
-    @DB
-    public void clearPeerInfo(long ownerMshost) {
-        SearchCriteria<ManagementServerHostPeerVO> sc = ClearPeerSearch.create();
-        sc.setParameters("ownerMshost", ownerMshost);
-
-        expunge(sc);
-    }
-
-    @Override
-    @DB
-    public void updatePeerInfo(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            txn.start();
-
-            SearchCriteria<ManagementServerHostPeerVO> sc = FindForUpdateSearch.create();
-            sc.setParameters("ownerMshost", ownerMshost);
-            sc.setParameters("peerMshost", peerMshost);
-            sc.setParameters("peerRunid", peerRunid);
-            List<ManagementServerHostPeerVO> l = listBy(sc);
-            if (l.size() == 1) {
-                ManagementServerHostPeerVO peer = l.get(0);
-                peer.setPeerState(peerState);
-                update(peer.getId(), peer);
-            } else {
-                ManagementServerHostPeerVO peer = new ManagementServerHostPeerVO(ownerMshost, peerMshost, peerRunid, peerState);
-                persist(peer);
-            }
-            txn.commit();
-        } catch (Exception e) {
-            s_logger.warn("Unexpected exception, ", e);
-            txn.rollback();
-        }
-    }
-
-    @Override
-    @DB
-    public int countStateSeenInPeers(long mshost, long runid, ManagementServerHost.State state) {
-        SearchCriteria<ManagementServerHostPeerVO> sc = CountSearch.create();
-        sc.setParameters("peerMshost", mshost);
-        sc.setParameters("peerRunid", runid);
-        sc.setParameters("peerState", state);
-
-        List<ManagementServerHostPeerVO> l = listBy(sc);
-        return l.size();
-    }
-}
diff --git a/framework/cluster/src/com/cloud/cluster/ActiveFencingException.java b/framework/cluster/src/main/java/com/cloud/cluster/ActiveFencingException.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ActiveFencingException.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ActiveFencingException.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterFenceManager.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterFenceManager.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterFenceManager.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterFenceManager.java
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterFenceManagerImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterFenceManagerImpl.java
new file mode 100644
index 0000000..4f5e034
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterFenceManagerImpl.java
@@ -0,0 +1,57 @@
+// 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.cluster;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.component.ManagerBase;
+
+@Component
+public class ClusterFenceManagerImpl extends ManagerBase implements ClusterFenceManager, ClusterManagerListener {
+    private static final Logger s_logger = Logger.getLogger(ClusterFenceManagerImpl.class);
+
+    @Inject
+    ClusterManager _clusterMgr;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _clusterMgr.registerListener(this);
+        return true;
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+        s_logger.error("Received node isolation notification, will perform self-fencing and shut myself down");
+        System.exit(SELF_FENCING_EXIT_CODE);
+    }
+}
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterInvalidSessionException.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterInvalidSessionException.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterInvalidSessionException.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterInvalidSessionException.java
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManager.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManager.java
new file mode 100644
index 0000000..c4a800c
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManager.java
@@ -0,0 +1,71 @@
+// 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.cluster;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.utils.component.Manager;
+
+public interface ClusterManager extends Manager {
+    static final String ALERT_SUBJECT = "cluster-alert";
+    final ConfigKey<Integer> HeartbeatInterval = new ConfigKey<Integer>(Integer.class, "cluster.heartbeat.interval", "management-server", "1500",
+        "Interval to check for the heart beat between management server nodes", false);
+    final ConfigKey<Integer> HeartbeatThreshold = new ConfigKey<Integer>(Integer.class, "cluster.heartbeat.threshold", "management-server", "150000",
+        "Threshold before self-fence the management server", true);
+
+    void OnReceiveClusterServicePdu(ClusterServicePdu pdu);
+
+    /**
+     * This executes
+     * @param strPeer
+     * @param agentId
+     * @param cmds
+     * @param stopOnError
+     * @return
+     */
+    String execute(String strPeer, long agentId, String cmds, boolean stopOnError);
+
+    /**
+     * Broadcast the command to all of the  management server nodes.
+     * @param agentId agent id this broadcast is regarding
+     * @param cmds commands to broadcast
+     */
+    void broadcast(long agentId, String cmds);
+
+    void registerListener(ClusterManagerListener listener);
+
+    void unregisterListener(ClusterManagerListener listener);
+
+    void registerDispatcher(Dispatcher dispatcher);
+
+    ManagementServerHost getPeer(String peerName);
+
+    String getSelfPeerName();
+
+    long getManagementNodeId();
+
+    long getCurrentRunId();
+
+    public long getManagementRunId(long msId);
+
+    public interface Dispatcher {
+        String getName();
+
+        String dispatch(ClusterServicePdu pdu);
+    }
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
new file mode 100644
index 0000000..8786bfd
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerImpl.java
@@ -0,0 +1,1204 @@
+// 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.cluster;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SocketChannel;
+import java.rmi.RemoteException;
+import java.sql.Connection;
+import java.sql.SQLNonTransientException;
+import java.sql.SQLRecoverableException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import com.cloud.cluster.dao.ManagementServerHostPeerDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Profiler;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.ConnectionConcierge;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.DbProperties;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.events.SubscriptionMgr;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.mgmt.JmxUtil;
+import com.cloud.utils.net.NetUtils;
+
+public class ClusterManagerImpl extends ManagerBase implements ClusterManager, Configurable {
+    private static final Logger s_logger = Logger.getLogger(ClusterManagerImpl.class);
+
+    private static final int EXECUTOR_SHUTDOWN_TIMEOUT = 1000; // 1 second
+    private static final int DEFAULT_OUTGOING_WORKERS = 5;
+
+    private final List<ClusterManagerListener> _listeners = new ArrayList<ClusterManagerListener>();
+    private final Map<Long, ManagementServerHostVO> _activePeers = new HashMap<Long, ManagementServerHostVO>();
+
+    private final Map<String, ClusterService> _clusterPeers;
+
+    @Inject
+    protected ConfigDepot _configDepot;
+
+    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Cluster-Heartbeat"));
+    private final ExecutorService _notificationExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("Cluster-Notification"));
+    private final List<ClusterManagerMessage> _notificationMsgs = new ArrayList<ClusterManagerMessage>();
+    private ConnectionConcierge _heartbeatConnection = null;
+
+    private final ExecutorService _executor;
+
+    private ClusterServiceAdapter _currentServiceAdapter;
+
+    @Inject
+    private List<ClusterServiceAdapter> _serviceAdapters;
+
+    @Inject
+    private ManagementServerHostDao _mshostDao;
+    @Inject
+    private ManagementServerHostPeerDao _mshostPeerDao;
+
+    protected Dispatcher _dispatcher;
+
+    //
+    // pay attention to _mshostId and _msid
+    // _mshostId is the primary key of management host table
+    // _msid is the unique persistent identifier that peer name is based upon
+    //
+    private Long _mshostId = null;
+    protected long _msId = ManagementServerNode.getManagementServerId();
+    protected long _runId = System.currentTimeMillis();
+
+    private boolean _peerScanInited = false;
+
+    private String _clusterNodeIP = "127.0.0.1";
+
+    private final List<ClusterServicePdu> _clusterPduOutgoingQueue = new ArrayList<ClusterServicePdu>();
+    private final List<ClusterServicePdu> _clusterPduIncomingQueue = new ArrayList<ClusterServicePdu>();
+    private final Map<Long, ClusterServiceRequestPdu> _outgoingPdusWaitingForAck = new HashMap<Long, ClusterServiceRequestPdu>();
+
+    public ClusterManagerImpl() {
+        _clusterPeers = new HashMap<String, ClusterService>();
+
+        // executor to perform remote-calls in another thread context, to avoid potential
+        // recursive remote calls between nodes
+        //
+        _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Cluster-Worker"));
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK);
+    }
+
+    private void registerRequestPdu(final ClusterServiceRequestPdu pdu) {
+        synchronized (_outgoingPdusWaitingForAck) {
+            _outgoingPdusWaitingForAck.put(pdu.getSequenceId(), pdu);
+        }
+    }
+
+    @Override
+    public void registerDispatcher(final Dispatcher dispatcher) {
+        _dispatcher = dispatcher;
+    }
+
+    private ClusterServiceRequestPdu popRequestPdu(final long ackSequenceId) {
+        synchronized (_outgoingPdusWaitingForAck) {
+            if (_outgoingPdusWaitingForAck.get(ackSequenceId) != null) {
+                final ClusterServiceRequestPdu pdu = _outgoingPdusWaitingForAck.get(ackSequenceId);
+                _outgoingPdusWaitingForAck.remove(ackSequenceId);
+                return pdu;
+            }
+        }
+
+        return null;
+    }
+
+    private void cancelClusterRequestToPeer(final String strPeer) {
+        final List<ClusterServiceRequestPdu> candidates = new ArrayList<ClusterServiceRequestPdu>();
+        synchronized (_outgoingPdusWaitingForAck) {
+            for (final Map.Entry<Long, ClusterServiceRequestPdu> entry : _outgoingPdusWaitingForAck.entrySet()) {
+                if (entry.getValue().getDestPeer().equalsIgnoreCase(strPeer)) {
+                    candidates.add(entry.getValue());
+                }
+            }
+
+            for (final ClusterServiceRequestPdu pdu : candidates) {
+                _outgoingPdusWaitingForAck.remove(pdu.getSequenceId());
+            }
+        }
+
+        for (final ClusterServiceRequestPdu pdu : candidates) {
+            s_logger.warn("Cancel cluster request PDU to peer: " + strPeer + ", pdu: " + pdu.getJsonPackage());
+            synchronized (pdu) {
+                pdu.notifyAll();
+            }
+        }
+    }
+
+    private void addOutgoingClusterPdu(final ClusterServicePdu pdu) {
+        synchronized (_clusterPduOutgoingQueue) {
+            _clusterPduOutgoingQueue.add(pdu);
+            _clusterPduOutgoingQueue.notifyAll();
+        }
+    }
+
+    private ClusterServicePdu popOutgoingClusterPdu(final long timeoutMs) {
+        synchronized (_clusterPduOutgoingQueue) {
+            try {
+                _clusterPduOutgoingQueue.wait(timeoutMs);
+            } catch (final InterruptedException e) {
+            }
+
+            if (_clusterPduOutgoingQueue.size() > 0) {
+                final ClusterServicePdu pdu = _clusterPduOutgoingQueue.get(0);
+                _clusterPduOutgoingQueue.remove(0);
+                return pdu;
+            }
+        }
+        return null;
+    }
+
+    private void addIncomingClusterPdu(final ClusterServicePdu pdu) {
+        synchronized (_clusterPduIncomingQueue) {
+            _clusterPduIncomingQueue.add(pdu);
+            _clusterPduIncomingQueue.notifyAll();
+        }
+    }
+
+    private ClusterServicePdu popIncomingClusterPdu(final long timeoutMs) {
+        synchronized (_clusterPduIncomingQueue) {
+            try {
+                _clusterPduIncomingQueue.wait(timeoutMs);
+            } catch (final InterruptedException e) {
+            }
+
+            if (_clusterPduIncomingQueue.size() > 0) {
+                final ClusterServicePdu pdu = _clusterPduIncomingQueue.get(0);
+                _clusterPduIncomingQueue.remove(0);
+                return pdu;
+            }
+        }
+        return null;
+    }
+
+    private Runnable getClusterPduSendingTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                onSendingClusterPdu();
+            }
+        };
+    }
+
+    private Runnable getClusterPduNotificationTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                onNotifyingClusterPdu();
+            }
+        };
+    }
+
+    private void onSendingClusterPdu() {
+        while (true) {
+            try {
+                final ClusterServicePdu pdu = popOutgoingClusterPdu(1000);
+                if (pdu == null) {
+                    continue;
+                }
+
+                ClusterService peerService = null;
+                for (int i = 0; i < 2; i++) {
+                    try {
+                        peerService = getPeerService(pdu.getDestPeer());
+                    } catch (final RemoteException e) {
+                        s_logger.error("Unable to get cluster service on peer : " + pdu.getDestPeer());
+                    }
+
+                    if (peerService != null) {
+                        try {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + ". agent: " + pdu.getAgentId() + ", pdu seq: " +
+                                        pdu.getSequenceId() + ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage());
+                            }
+
+                            final Profiler profiler = new Profiler();
+                            profiler.start();
+
+                            final String strResult = peerService.execute(pdu);
+                            profiler.stop();
+
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Cluster PDU " + getSelfPeerName() + " -> " + pdu.getDestPeer() + " completed. time: " +
+                                        profiler.getDurationInMillis() + "ms. agent: " + pdu.getAgentId() + ", pdu seq: " + pdu.getSequenceId() +
+                                        ", pdu ack seq: " + pdu.getAckSequenceId() + ", json: " + pdu.getJsonPackage());
+                            }
+
+                            if ("true".equals(strResult)) {
+                                break;
+                            }
+
+                        } catch (final RemoteException e) {
+                            invalidatePeerService(pdu.getDestPeer());
+                            if (s_logger.isInfoEnabled()) {
+                                s_logger.info("Exception on remote execution, peer: " + pdu.getDestPeer() + ", iteration: " + i + ", exception message :" +
+                                        e.getMessage());
+                            }
+                        }
+                    }
+                }
+            } catch (final Throwable e) {
+                s_logger.error("Unexcpeted exception: ", e);
+            }
+        }
+    }
+
+    private void onNotifyingClusterPdu() {
+        while (true) {
+            try {
+                final ClusterServicePdu pdu = popIncomingClusterPdu(1000);
+                if (pdu == null) {
+                    continue;
+                }
+
+                _executor.execute(new ManagedContextRunnable() {
+                    @Override
+                    protected void runInContext() {
+                        if (pdu.getPduType() == ClusterServicePdu.PDU_TYPE_RESPONSE) {
+                            final ClusterServiceRequestPdu requestPdu = popRequestPdu(pdu.getAckSequenceId());
+                            if (requestPdu != null) {
+                                requestPdu.setResponseResult(pdu.getJsonPackage());
+                                synchronized (requestPdu) {
+                                    requestPdu.notifyAll();
+                                }
+                            } else {
+                                s_logger.warn("Original request has already been cancelled. pdu: " + pdu.getJsonPackage());
+                            }
+                        } else {
+                            String result = _dispatcher.dispatch(pdu);
+                            if (result == null) {
+                                result = "";
+                            }
+
+                            if (pdu.getPduType() == ClusterServicePdu.PDU_TYPE_REQUEST) {
+                                final ClusterServicePdu responsePdu = new ClusterServicePdu();
+                                responsePdu.setPduType(ClusterServicePdu.PDU_TYPE_RESPONSE);
+                                responsePdu.setSourcePeer(pdu.getDestPeer());
+                                responsePdu.setDestPeer(pdu.getSourcePeer());
+                                responsePdu.setAckSequenceId(pdu.getSequenceId());
+                                responsePdu.setJsonPackage(result);
+
+                                addOutgoingClusterPdu(responsePdu);
+                            }
+                        }
+                    }
+                });
+            } catch (final Throwable e) {
+                s_logger.error("Unexcpeted exception: ", e);
+            }
+        }
+    }
+
+    @Override
+    public void OnReceiveClusterServicePdu(final ClusterServicePdu pdu) {
+        addIncomingClusterPdu(pdu);
+    }
+
+    /**
+     * called by DatabaseUpgradeChecker to see if there are other peers running.
+     *
+     * @param notVersion
+     *            If version is passed in, the peers CANNOT be running at this version. If version is null, return true if any
+     *            peer is running regardless of version.
+     * @return true if there are peers running and false if not.
+     */
+    public static final boolean arePeersRunning(final String notVersion) {
+        return false; // TODO: Leaving this for Kelven to take care of.
+    }
+
+    @Override
+    public void broadcast(final long agentId, final String cmds) {
+        final Date cutTime = DateUtil.currentGMTTime();
+
+        final List<ManagementServerHostVO> peers = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
+        for (final ManagementServerHostVO peer : peers) {
+            final String peerName = Long.toString(peer.getMsid());
+            if (getSelfPeerName().equals(peerName)) {
+                continue; // Skip myself.
+            }
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Forwarding " + cmds + " to " + peer.getMsid());
+                }
+                executeAsync(peerName, agentId, cmds, true);
+            } catch (final Exception e) {
+                s_logger.warn("Caught exception while talkign to " + peer.getMsid());
+            }
+        }
+    }
+
+    public void executeAsync(final String strPeer, final long agentId, final String cmds, final boolean stopOnError) {
+        final ClusterServicePdu pdu = new ClusterServicePdu();
+        pdu.setSourcePeer(getSelfPeerName());
+        pdu.setDestPeer(strPeer);
+        pdu.setAgentId(agentId);
+        pdu.setJsonPackage(cmds);
+        pdu.setStopOnError(true);
+        addOutgoingClusterPdu(pdu);
+    }
+
+    @Override
+    public String execute(final String strPeer, final long agentId, final String cmds, final boolean stopOnError) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(getSelfPeerName() + " -> " + strPeer + "." + agentId + " " + cmds);
+        }
+
+        final ClusterServiceRequestPdu pdu = new ClusterServiceRequestPdu();
+        pdu.setSourcePeer(getSelfPeerName());
+        pdu.setDestPeer(strPeer);
+        pdu.setAgentId(agentId);
+        pdu.setJsonPackage(cmds);
+        pdu.setStopOnError(stopOnError);
+        registerRequestPdu(pdu);
+        addOutgoingClusterPdu(pdu);
+
+        synchronized (pdu) {
+            try {
+                pdu.wait();
+            } catch (final InterruptedException e) {
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(getSelfPeerName() + " -> " + strPeer + "." + agentId + " completed. result: " + pdu.getResponseResult());
+        }
+
+        if (pdu.getResponseResult() != null && pdu.getResponseResult().length() > 0) {
+            return pdu.getResponseResult();
+        }
+
+        return null;
+    }
+
+    @Override
+    public ManagementServerHostVO getPeer(final String mgmtServerId) {
+        return _mshostDao.findByMsid(Long.parseLong(mgmtServerId));
+    }
+
+    @Override
+    public String getSelfPeerName() {
+        return Long.toString(_msId);
+    }
+
+    public String getSelfNodeIP() {
+        return _clusterNodeIP;
+    }
+
+    @Override
+    public void registerListener(final ClusterManagerListener listener) {
+        // Note : we don't check duplicates
+        synchronized (_listeners) {
+
+            s_logger.info("register cluster listener " + listener.getClass());
+
+            _listeners.add(listener);
+        }
+    }
+
+    @Override
+    public void unregisterListener(final ClusterManagerListener listener) {
+        synchronized (_listeners) {
+            s_logger.info("unregister cluster listener " + listener.getClass());
+
+            _listeners.remove(listener);
+        }
+    }
+
+    public void notifyNodeJoined(final List<ManagementServerHostVO> nodeList) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Notify management server node join to listeners.");
+
+            for (final ManagementServerHostVO mshost : nodeList) {
+                s_logger.debug("Joining node, IP: " + mshost.getServiceIP() + ", msid: " + mshost.getMsid());
+            }
+        }
+
+        synchronized (_listeners) {
+            for (final ClusterManagerListener listener : _listeners) {
+                listener.onManagementNodeJoined(nodeList, _mshostId);
+            }
+        }
+
+        SubscriptionMgr.getInstance().notifySubscribers(ClusterManager.ALERT_SUBJECT, this, new ClusterNodeJoinEventArgs(_mshostId, nodeList));
+    }
+
+    public void notifyNodeLeft(final List<ManagementServerHostVO> nodeList) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Notify management server node left to listeners.");
+        }
+
+        for (final ManagementServerHostVO mshost : nodeList) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Leaving node, IP: " + mshost.getServiceIP() + ", msid: " + mshost.getMsid());
+            }
+            cancelClusterRequestToPeer(String.valueOf(mshost.getMsid()));
+        }
+
+        synchronized (_listeners) {
+            for (final ClusterManagerListener listener : _listeners) {
+                listener.onManagementNodeLeft(nodeList, _mshostId);
+            }
+        }
+
+        SubscriptionMgr.getInstance().notifySubscribers(ClusterManager.ALERT_SUBJECT, this, new ClusterNodeLeftEventArgs(_mshostId, nodeList));
+    }
+
+    public void notifyNodeIsolated() {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Notify management server node isolation to listeners");
+        }
+
+        synchronized (_listeners) {
+            for (final ClusterManagerListener listener : _listeners) {
+                listener.onManagementNodeIsolated();
+            }
+        }
+    }
+
+    public ClusterService getPeerService(final String strPeer) throws RemoteException {
+        synchronized (_clusterPeers) {
+            if (_clusterPeers.containsKey(strPeer)) {
+                return _clusterPeers.get(strPeer);
+            }
+        }
+
+        final ClusterService service = _currentServiceAdapter.getPeerService(strPeer);
+
+        if (service != null) {
+            synchronized (_clusterPeers) {
+                // re-check the peer map again to deal with the
+                // race conditions
+                if (!_clusterPeers.containsKey(strPeer)) {
+                    _clusterPeers.put(strPeer, service);
+                }
+            }
+        }
+
+        return service;
+    }
+
+    public void invalidatePeerService(final String strPeer) {
+        synchronized (_clusterPeers) {
+            if (_clusterPeers.containsKey(strPeer)) {
+                _clusterPeers.remove(strPeer);
+            }
+        }
+    }
+
+    private Runnable getHeartbeatTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                final TransactionLegacy txn = TransactionLegacy.open("ClusterHeartbeat");
+                try {
+                    final Profiler profiler = new Profiler();
+                    final Profiler profilerHeartbeatUpdate = new Profiler();
+                    final Profiler profilerPeerScan = new Profiler();
+
+                    try {
+                        profiler.start();
+
+                        profilerHeartbeatUpdate.start();
+                        txn.transitToAutoManagedConnection(TransactionLegacy.CLOUD_DB);
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("Cluster manager heartbeat update, id:" + _mshostId);
+                        }
+
+                        _mshostDao.update(_mshostId, _runId, DateUtil.currentGMTTime());
+                        profilerHeartbeatUpdate.stop();
+
+                        profilerPeerScan.start();
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("Cluster manager peer-scan, id:" + _mshostId);
+                        }
+
+                        if (!_peerScanInited) {
+                            _peerScanInited = true;
+                            initPeerScan();
+                        }
+
+                        peerScan();
+                        profilerPeerScan.stop();
+
+                    } finally {
+                        profiler.stop();
+
+                        if (profiler.getDurationInMillis() >= HeartbeatInterval.value()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Management server heartbeat takes too long to finish. profiler: " + profiler.toString() + ", profilerHeartbeatUpdate: " +
+                                        profilerHeartbeatUpdate.toString() + ", profilerPeerScan: " + profilerPeerScan.toString());
+                            }
+                        }
+                    }
+
+                } catch (final CloudRuntimeException e) {
+                    s_logger.error("Runtime DB exception ", e.getCause());
+
+                    if (e.getCause() instanceof ClusterInvalidSessionException) {
+                        s_logger.error("Invalid cluster session found, fence it");
+                        queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
+                    }
+
+                    if (isRootCauseConnectionRelated(e.getCause())) {
+                        invalidHeartbeatConnection();
+                    }
+                } catch (final ActiveFencingException e) {
+                    queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
+                } catch (final Throwable e) {
+                    s_logger.error("Unexpected exception in cluster heartbeat", e);
+                    if (isRootCauseConnectionRelated(e.getCause())) {
+                        invalidHeartbeatConnection();
+                    }
+                } finally {
+                    txn.close("ClusterHeartbeat");
+                }
+            }
+        };
+    }
+
+    private boolean isRootCauseConnectionRelated(Throwable e) {
+        while (e != null) {
+            if (e instanceof SQLRecoverableException || e instanceof SQLNonTransientException) {
+                return true;
+            }
+
+            e = e.getCause();
+        }
+
+        return false;
+    }
+
+    private void invalidHeartbeatConnection() {
+        if (_heartbeatConnection != null) {
+            final Connection conn = TransactionLegacy.getStandaloneConnection();
+            if (conn != null) {
+                _heartbeatConnection.reset(conn);
+            } else {
+                s_logger.error("DB communication problem detected, fence it");
+                queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeIsolated));
+            }
+            // The stand-alone connection does not have to be closed here because there will be another reference to it.
+            // As a matter of fact, it will be assigned to the connection instance variable in the ConnectionConcierge class.
+        }
+    }
+
+    private Runnable getNotificationTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                while (true) {
+                    synchronized (_notificationMsgs) {
+                        try {
+                            _notificationMsgs.wait(1000);
+                        } catch (final InterruptedException e) {
+                        }
+                    }
+
+                    ClusterManagerMessage msg = null;
+                    while ((msg = getNextNotificationMessage()) != null) {
+                        try {
+                            switch (msg.getMessageType()) {
+                            case nodeAdded:
+                                if (msg.getNodes() != null && msg.getNodes().size() > 0) {
+                                    final Profiler profiler = new Profiler();
+                                    profiler.start();
+
+                                    notifyNodeJoined(msg.getNodes());
+
+                                    profiler.stop();
+                                    if (profiler.getDurationInMillis() > 1000) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Notifying management server join event took " + profiler.getDurationInMillis() + " ms");
+                                        }
+                                    } else {
+                                        s_logger.warn("Notifying management server join event took " + profiler.getDurationInMillis() + " ms");
+                                    }
+                                }
+                                break;
+
+                            case nodeRemoved:
+                                if (msg.getNodes() != null && msg.getNodes().size() > 0) {
+                                    final Profiler profiler = new Profiler();
+                                    profiler.start();
+
+                                    notifyNodeLeft(msg.getNodes());
+
+                                    profiler.stop();
+                                    if (profiler.getDurationInMillis() > 1000) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Notifying management server leave event took " + profiler.getDurationInMillis() + " ms");
+                                        }
+                                    } else {
+                                        s_logger.warn("Notifying management server leave event took " + profiler.getDurationInMillis() + " ms");
+                                    }
+                                }
+                                break;
+
+                            case nodeIsolated:
+                                notifyNodeIsolated();
+                                break;
+
+                            default:
+                                assert false;
+                                break;
+                            }
+
+                        } catch (final Throwable e) {
+                            s_logger.warn("Unexpected exception during cluster notification. ", e);
+                        }
+                    }
+
+                    try {
+                        Thread.sleep(1000);
+                    } catch (final InterruptedException e) {
+                    }
+                }
+            }
+        };
+    }
+
+    private void queueNotification(final ClusterManagerMessage msg) {
+        synchronized (_notificationMsgs) {
+            _notificationMsgs.add(msg);
+            _notificationMsgs.notifyAll();
+        }
+
+        switch (msg.getMessageType()) {
+        case nodeAdded: {
+            final List<ManagementServerHostVO> l = msg.getNodes();
+            if (l != null && l.size() > 0) {
+                for (final ManagementServerHostVO mshost : l) {
+                    _mshostPeerDao.updatePeerInfo(_mshostId, mshost.getId(), mshost.getRunid(), ManagementServerHost.State.Up);
+                }
+            }
+        }
+        break;
+
+        case nodeRemoved: {
+            final List<ManagementServerHostVO> l = msg.getNodes();
+            if (l != null && l.size() > 0) {
+                for (final ManagementServerHostVO mshost : l) {
+                    _mshostPeerDao.updatePeerInfo(_mshostId, mshost.getId(), mshost.getRunid(), ManagementServerHost.State.Down);
+                }
+            }
+        }
+        break;
+
+        default:
+            break;
+        }
+    }
+
+    private ClusterManagerMessage getNextNotificationMessage() {
+        synchronized (_notificationMsgs) {
+            if (_notificationMsgs.size() > 0) {
+                return _notificationMsgs.remove(0);
+            }
+        }
+
+        return null;
+    }
+
+    private void initPeerScan() {
+        // upon startup, for all inactive management server nodes that we see at startup time, we will send notification also to help upper layer perform
+        // missed cleanup
+        final Date cutTime = DateUtil.currentGMTTime();
+        final List<ManagementServerHostVO> inactiveList = _mshostDao.getInactiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
+
+        // We don't have foreign key constraints to enforce the mgmt_server_id integrity in host table, when user manually
+        // remove records from mshost table, this will leave orphan mgmt_serve_id reference in host table.
+        final List<Long> orphanList = _mshostDao.listOrphanMsids();
+        if (orphanList.size() > 0) {
+            for (final Long orphanMsid : orphanList) {
+                // construct fake ManagementServerHostVO based on orphan MSID
+                s_logger.info("Add orphan management server msid found in host table to initial clustering notification, orphan msid: " + orphanMsid);
+                inactiveList.add(new ManagementServerHostVO(orphanMsid, 0, "orphan", 0, new Date()));
+            }
+        } else {
+            s_logger.info("We are good, no orphan management server msid in host table is found");
+        }
+
+        if (inactiveList.size() > 0) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Found " + inactiveList.size() + " inactive management server node based on timestamp");
+                for (final ManagementServerHostVO host : inactiveList) {
+                    s_logger.info("management server node msid: " + host.getMsid() + ", name: " + host.getName() + ", service ip: " + host.getServiceIP() +
+                            ", version: " + host.getVersion());
+                }
+            }
+
+            final List<ManagementServerHostVO> downHostList = new ArrayList<ManagementServerHostVO>();
+            for (final ManagementServerHostVO host : inactiveList) {
+                if (!pingManagementNode(host)) {
+                    s_logger.warn("Management node " + host.getId() + " is detected inactive by timestamp and also not pingable");
+                    downHostList.add(host);
+                }
+            }
+
+            if (downHostList.size() > 0) {
+                queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, downHostList));
+            }
+        } else {
+            s_logger.info("No inactive management server node found");
+        }
+    }
+
+    private void peerScan() throws ActiveFencingException {
+        final Date cutTime = DateUtil.currentGMTTime();
+
+        final Profiler profiler = new Profiler();
+        profiler.start();
+
+        final Profiler profilerQueryActiveList = new Profiler();
+        profilerQueryActiveList.start();
+        final List<ManagementServerHostVO> currentList = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
+        profilerQueryActiveList.stop();
+
+        final Profiler profilerSyncClusterInfo = new Profiler();
+        profilerSyncClusterInfo.start();
+        final List<ManagementServerHostVO> removedNodeList = new ArrayList<ManagementServerHostVO>();
+        final List<ManagementServerHostVO> invalidatedNodeList = new ArrayList<ManagementServerHostVO>();
+
+        if (_mshostId != null) {
+
+            if (_mshostPeerDao.countStateSeenInPeers(_mshostId, _runId, ManagementServerHost.State.Down) > 0) {
+                final String msg =
+                        "We have detected that at least one management server peer reports that this management server is down, perform active fencing to avoid split-brain situation";
+                s_logger.error(msg);
+                throw new ActiveFencingException(msg);
+            }
+
+            // only if we have already attached to cluster, will we start to check leaving nodes
+            for (final Map.Entry<Long, ManagementServerHostVO> entry : _activePeers.entrySet()) {
+
+                final ManagementServerHostVO current = getInListById(entry.getKey(), currentList);
+                if (current == null) {
+                    if (entry.getKey().longValue() != _mshostId.longValue()) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Detected management node left, id:" + entry.getKey() + ", nodeIP:" + entry.getValue().getServiceIP());
+                        }
+                        removedNodeList.add(entry.getValue());
+                    }
+                } else {
+                    if (current.getRunid() == 0) {
+                        if (entry.getKey().longValue() != _mshostId.longValue()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Detected management node left because of invalidated session, id:" + entry.getKey() + ", nodeIP:" +
+                                        entry.getValue().getServiceIP());
+                            }
+                            invalidatedNodeList.add(entry.getValue());
+                        }
+                    } else {
+                        if (entry.getValue().getRunid() != current.getRunid()) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Detected management node left and rejoined quickly, id:" + entry.getKey() + ", nodeIP:" + entry.getValue().getServiceIP());
+                            }
+
+                            entry.getValue().setRunid(current.getRunid());
+                        }
+                    }
+                }
+            }
+        }
+        profilerSyncClusterInfo.stop();
+
+        final Profiler profilerInvalidatedNodeList = new Profiler();
+        profilerInvalidatedNodeList.start();
+        // process invalidated node list
+        if (invalidatedNodeList.size() > 0) {
+            for (final ManagementServerHostVO mshost : invalidatedNodeList) {
+                _activePeers.remove(mshost.getId());
+                try {
+                    JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
+                }
+            }
+
+            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, invalidatedNodeList));
+        }
+        profilerInvalidatedNodeList.stop();
+
+        final Profiler profilerRemovedList = new Profiler();
+        profilerRemovedList.start();
+        // process removed node list
+        final Iterator<ManagementServerHostVO> it = removedNodeList.iterator();
+        while (it.hasNext()) {
+            final ManagementServerHostVO mshost = it.next();
+            if (!pingManagementNode(mshost)) {
+                s_logger.warn("Management node " + mshost.getId() + " is detected inactive by timestamp and also not pingable");
+                _activePeers.remove(mshost.getId());
+                try {
+                    JmxUtil.unregisterMBean("ClusterManager", "Node " + mshost.getId());
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to deregiester cluster node from JMX monitoring due to exception " + e.toString());
+                }
+            } else {
+                s_logger.info("Management node " + mshost.getId() + " is detected inactive by timestamp but is pingable");
+                it.remove();
+            }
+        }
+
+        if (removedNodeList.size() > 0) {
+            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeRemoved, removedNodeList));
+        }
+        profilerRemovedList.stop();
+
+        final List<ManagementServerHostVO> newNodeList = new ArrayList<ManagementServerHostVO>();
+        for (final ManagementServerHostVO mshost : currentList) {
+            if (!_activePeers.containsKey(mshost.getId())) {
+                _activePeers.put(mshost.getId(), mshost);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Detected management node joined, id:" + mshost.getId() + ", nodeIP:" + mshost.getServiceIP());
+                }
+                newNodeList.add(mshost);
+
+                try {
+                    JmxUtil.registerMBean("ClusterManager", "Node " + mshost.getId(), new ClusterManagerMBeanImpl(this, mshost));
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to regiester cluster node into JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                }
+            }
+        }
+
+        if (newNodeList.size() > 0) {
+            queueNotification(new ClusterManagerMessage(ClusterManagerMessage.MessageType.nodeAdded, newNodeList));
+        }
+
+        profiler.stop();
+
+        if (profiler.getDurationInMillis() >= HeartbeatInterval.value()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Peer scan takes too long to finish. profiler: " + profiler.toString() + ", profilerQueryActiveList: " +
+                        profilerQueryActiveList.toString() + ", profilerSyncClusterInfo: " + profilerSyncClusterInfo.toString() + ", profilerInvalidatedNodeList: " +
+                        profilerInvalidatedNodeList.toString() + ", profilerRemovedList: " + profilerRemovedList.toString());
+            }
+        }
+    }
+
+    private static ManagementServerHostVO getInListById(final Long id, final List<ManagementServerHostVO> l) {
+        for (final ManagementServerHostVO mshost : l) {
+            if (mshost.getId() == id) {
+                return mshost;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    @DB
+    public boolean start() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Starting Cluster manager, msid : " + _msId);
+        }
+
+        final ManagementServerHostVO mshost = Transaction.execute(new TransactionCallback<ManagementServerHostVO>() {
+            @Override
+            public ManagementServerHostVO doInTransaction(final TransactionStatus status) {
+
+                final Class<?> c = this.getClass();
+                final String version = c.getPackage().getImplementationVersion();
+
+                ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
+                if (mshost == null) {
+                    mshost = new ManagementServerHostVO();
+                    mshost.setMsid(_msId);
+                    mshost.setRunid(_runId);
+                    mshost.setName(NetUtils.getCanonicalHostName());
+                    mshost.setVersion(version);
+                    mshost.setServiceIP(_clusterNodeIP);
+                    mshost.setServicePort(_currentServiceAdapter.getServicePort());
+                    mshost.setLastUpdateTime(DateUtil.currentGMTTime());
+                    mshost.setRemoved(null);
+                    mshost.setAlertCount(0);
+                    mshost.setState(ManagementServerHost.State.Up);
+                    mshost.setUuid(UUID.randomUUID().toString());
+                    _mshostDao.persist(mshost);
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("New instance of management server msid " + _msId + ", runId " + _runId + " is being started");
+                    }
+                } else {
+                    _mshostDao.update(mshost.getId(), _runId, NetUtils.getCanonicalHostName(), version, _clusterNodeIP, _currentServiceAdapter.getServicePort(),
+                            DateUtil.currentGMTTime());
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Management server " + _msId + ", runId " + _runId + " is being started");
+                    }
+                }
+
+                return mshost;
+            }
+        });
+
+        _mshostId = mshost.getId();
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Management server (host id : " + _mshostId + ") is being started at " + _clusterNodeIP + ":" + _currentServiceAdapter.getServicePort());
+        }
+
+        _mshostPeerDao.clearPeerInfo(_mshostId);
+
+        // use seperate thread for heartbeat updates
+        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS);
+        _notificationExecutor.submit(getNotificationTask());
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Cluster manager was started successfully");
+        }
+
+        return true;
+    }
+
+    @Override
+    @DB
+    public boolean stop() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Stopping Cluster manager, msid : " + _msId);
+        }
+
+        if (_mshostId != null) {
+            final ManagementServerHostVO mshost = _mshostDao.findByMsid(_msId);
+            mshost.setState(ManagementServerHost.State.Down);
+            _mshostDao.update(_mshostId, mshost);
+        }
+
+        _heartbeatScheduler.shutdownNow();
+        _executor.shutdownNow();
+
+        try {
+            _heartbeatScheduler.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
+            _executor.awaitTermination(EXECUTOR_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (final InterruptedException e) {
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Cluster manager is stopped");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start configuring cluster manager : " + name);
+        }
+
+        final Properties dbProps = DbProperties.getDbProperties();
+        _clusterNodeIP = dbProps.getProperty("cluster.node.IP");
+        if (_clusterNodeIP == null) {
+            _clusterNodeIP = "127.0.0.1";
+        }
+        _clusterNodeIP = _clusterNodeIP.trim();
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Cluster node IP : " + _clusterNodeIP);
+        }
+
+        if (!NetUtils.isLocalAddress(_clusterNodeIP)) {
+            throw new ConfigurationException("cluster node IP should be valid local address where the server is running, please check your configuration");
+        }
+
+        for (int i = 0; i < DEFAULT_OUTGOING_WORKERS; i++) {
+            _executor.execute(getClusterPduSendingTask());
+        }
+
+        // notification task itself in turn works as a task dispatcher
+        _executor.execute(getClusterPduNotificationTask());
+
+        if (_serviceAdapters == null) {
+            throw new ConfigurationException("Unable to get cluster service adapters");
+        }
+        _currentServiceAdapter = _serviceAdapters.get(0);
+
+        if (_currentServiceAdapter == null) {
+            throw new ConfigurationException("Unable to set current cluster service adapter");
+        }
+
+        checkConflicts();
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Cluster manager is configured.");
+        }
+        return true;
+    }
+
+    @Override
+    public long getManagementNodeId() {
+        return _msId;
+    }
+
+    @Override
+    public long getCurrentRunId() {
+        return _runId;
+    }
+
+    @Override
+    public long getManagementRunId(final long msId) {
+        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msId);
+        if (mshost != null) {
+            return mshost.getRunid();
+        }
+        return -1;
+    }
+
+    public boolean isManagementNodeAlive(final long msid) {
+        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msid);
+        if (mshost != null) {
+            if (mshost.getLastUpdateTime().getTime() >= DateUtil.currentGMTTime().getTime() - HeartbeatThreshold.value()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean pingManagementNode(final long msid) {
+        final ManagementServerHostVO mshost = _mshostDao.findByMsid(msid);
+        if (mshost == null) {
+            return false;
+        }
+
+        return pingManagementNode(mshost);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ClusterManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {HeartbeatInterval, HeartbeatThreshold};
+    }
+
+    private boolean pingManagementNode(final ManagementServerHostVO mshost) {
+
+        final String targetIp = mshost.getServiceIP();
+        if ("127.0.0.1".equals(targetIp) || "0.0.0.0".equals(targetIp)) {
+            s_logger.info("ping management node cluster service can not be performed on self");
+            return false;
+        }
+
+        int retry = 10;
+        while (--retry > 0) {
+            SocketChannel sch = null;
+            try {
+                s_logger.info("Trying to connect to " + targetIp);
+                sch = SocketChannel.open();
+                sch.configureBlocking(true);
+                sch.socket().setSoTimeout(5000);
+
+                final InetSocketAddress addr = new InetSocketAddress(targetIp, mshost.getServicePort());
+                sch.connect(addr);
+                return true;
+            } catch (final IOException e) {
+                if (e instanceof ConnectException) {
+                    s_logger.error("Unable to ping management server at " + targetIp + ":" + mshost.getServicePort() + " due to ConnectException", e);
+                    return false;
+                }
+            } finally {
+                if (sch != null) {
+                    try {
+                        sch.close();
+                    } catch (final IOException e) {
+                    }
+                }
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (final InterruptedException ex) {
+            }
+        }
+
+        s_logger.error("Unable to ping management server at " + targetIp + ":" + mshost.getServicePort() + " after retries");
+        return false;
+    }
+
+    public int getHeartbeatInterval() {
+        return HeartbeatInterval.value();
+    }
+
+    private void checkConflicts() throws ConfigurationException {
+        final Date cutTime = DateUtil.currentGMTTime();
+        final List<ManagementServerHostVO> peers = _mshostDao.getActiveList(new Date(cutTime.getTime() - HeartbeatThreshold.value()));
+        for (final ManagementServerHostVO peer : peers) {
+            final String peerIP = peer.getServiceIP().trim();
+            if (_clusterNodeIP.equals(peerIP)) {
+                if ("127.0.0.1".equals(_clusterNodeIP)) {
+                    if (pingManagementNode(peer.getMsid())) {
+                        final String msg = "Detected another management node with localhost IP is already running, please check your cluster configuration";
+                        s_logger.error(msg);
+                        throw new ConfigurationException(msg);
+                    } else {
+                        final String msg =
+                                "Detected another management node with localhost IP is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node";
+                        s_logger.info(msg);
+                    }
+                } else {
+                    if (pingManagementNode(peer.getMsid())) {
+                        final String msg =
+                                "Detected that another management node with the same IP " + peer.getServiceIP() +
+                                " is already running, please check your cluster configuration";
+                        s_logger.error(msg);
+                        throw new ConfigurationException(msg);
+                    } else {
+                        final String msg =
+                                "Detected that another management node with the same IP " + peer.getServiceIP() +
+                                " is considered as running in DB, however it is not pingable, we will continue cluster initialization with this management server node";
+                        s_logger.info(msg);
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerListener.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerListener.java
new file mode 100644
index 0000000..61af3ef
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerListener.java
@@ -0,0 +1,29 @@
+// 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.cluster;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+
+import java.util.List;
+
+public interface ClusterManagerListener {
+    void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId);
+
+    void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId);
+
+    void onManagementNodeIsolated();
+}
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerMBean.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMBean.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterManagerMBean.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMBean.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerMBeanImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMBeanImpl.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterManagerMBeanImpl.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMBeanImpl.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerMessage.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMessage.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterManagerMessage.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterManagerMessage.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterNodeJoinEventArgs.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterNodeJoinEventArgs.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterNodeJoinEventArgs.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterNodeJoinEventArgs.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterNodeLeftEventArgs.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterNodeLeftEventArgs.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterNodeLeftEventArgs.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterNodeLeftEventArgs.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterService.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterService.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterService.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterService.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceAdapter.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceAdapter.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceAdapter.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceAdapter.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServicePdu.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServicePdu.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServicePdu.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServicePdu.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceRequestPdu.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceRequestPdu.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceRequestPdu.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceRequestPdu.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletAdapter.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletAdapter.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletContainer.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceServletContainer.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletContainer.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletHttpHandler.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletHttpHandler.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceServletHttpHandler.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletHttpHandler.java
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletImpl.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/ClusterServiceServletImpl.java
rename to framework/cluster/src/main/java/com/cloud/cluster/ClusterServiceServletImpl.java
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostPeerVO.java b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostPeerVO.java
new file mode 100644
index 0000000..a381bb4
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostPeerVO.java
@@ -0,0 +1,126 @@
+// 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.cluster;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.management.ManagementServerHostPeer;
+import com.cloud.utils.DateUtil;
+
+@Entity
+@Table(name = "mshost_peer")
+public class ManagementServerHostPeerVO implements ManagementServerHostPeer {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "owner_mshost", updatable = true, nullable = false)
+    private long ownerMshost;
+
+    @Column(name = "peer_mshost", updatable = true, nullable = false)
+    private long peerMshost;
+
+    @Column(name = "peer_runid", updatable = true, nullable = false)
+    private long peerRunid;
+
+    @Column(name = "peer_state", updatable = true, nullable = false)
+    @Enumerated(value = EnumType.STRING)
+    private ManagementServerHost.State peerState;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "last_update", updatable = true, nullable = true)
+    private Date lastUpdateTime;
+
+    public ManagementServerHostPeerVO() {
+    }
+
+    public ManagementServerHostPeerVO(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState) {
+        this.ownerMshost = ownerMshost;
+        this.peerMshost = peerMshost;
+        this.peerRunid = peerRunid;
+        this.peerState = peerState;
+
+        lastUpdateTime = DateUtil.currentGMTTime();
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Override
+    public long getOwnerMshost() {
+        return ownerMshost;
+    }
+
+    public void setOwnerMshost(long ownerMshost) {
+        this.ownerMshost = ownerMshost;
+    }
+
+    @Override
+    public long getPeerMshost() {
+        return peerMshost;
+    }
+
+    public void setPeerMshost(long peerMshost) {
+        this.peerMshost = peerMshost;
+    }
+
+    @Override
+    public long getPeerRunid() {
+        return peerRunid;
+    }
+
+    public void setPeerRunid(long peerRunid) {
+        this.peerRunid = peerRunid;
+    }
+
+    @Override
+    public ManagementServerHost.State getPeerState() {
+        return peerState;
+    }
+
+    public void setPeerState(ManagementServerHost.State peerState) {
+        this.peerState = peerState;
+    }
+
+    @Override
+    public Date getLastUpdateTime() {
+        return lastUpdateTime;
+    }
+
+    public void setLastUpdateTime(Date lastUpdateTime) {
+        this.lastUpdateTime = lastUpdateTime;
+    }
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostVO.java b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostVO.java
new file mode 100644
index 0000000..121b939
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/ManagementServerHostVO.java
@@ -0,0 +1,199 @@
+// 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.cluster;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "mshost")
+public class ManagementServerHostVO implements ManagementServerHost {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "msid", updatable = true, nullable = false)
+    private long msid;
+
+    @Column(name = "runid", updatable = true, nullable = false)
+    private long runid;
+
+    @Column(name = "name", updatable = true, nullable = true)
+    private String name;
+
+    @Column(name = "state", updatable = true, nullable = false)
+    @Enumerated(value = EnumType.STRING)
+    private ManagementServerHost.State state;
+
+    @Column(name = "version", updatable = true, nullable = true)
+    private String version;
+
+    @Column(name = "service_ip", updatable = true, nullable = false)
+    private String serviceIP;
+
+    @Column(name = "service_port", updatable = true, nullable = false)
+    private int servicePort;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "last_update", updatable = true, nullable = true)
+    private Date lastUpdateTime;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = "alert_count", updatable = true, nullable = false)
+    private int alertCount;
+
+    public ManagementServerHostVO() {
+    }
+
+    public ManagementServerHostVO(long msid, long runid, String serviceIP, int servicePort, Date updateTime) {
+        this.msid = msid;
+        this.runid = runid;
+        this.serviceIP = serviceIP;
+        this.servicePort = servicePort;
+        lastUpdateTime = updateTime;
+        this.uuid = UUID.randomUUID().toString();
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public long getRunid() {
+        return runid;
+    }
+
+    public void setRunid(long runid) {
+        this.runid = runid;
+    }
+
+    @Override
+    public long getMsid() {
+        return msid;
+    }
+
+    public void setMsid(long msid) {
+        this.msid = msid;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public ManagementServerHost.State getState() {
+        return state;
+    }
+
+    public void setState(ManagementServerHost.State state) {
+        this.state = state;
+    }
+
+    @Override
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    @Override
+    public String getServiceIP() {
+        return serviceIP;
+    }
+
+    public void setServiceIP(String serviceIP) {
+        this.serviceIP = serviceIP;
+    }
+
+    public int getServicePort() {
+        return servicePort;
+    }
+
+    public void setServicePort(int servicePort) {
+        this.servicePort = servicePort;
+    }
+
+    public Date getLastUpdateTime() {
+        return lastUpdateTime;
+    }
+
+    public void setLastUpdateTime(Date lastUpdateTime) {
+        this.lastUpdateTime = lastUpdateTime;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public void setRemoved(Date removedTime) {
+        removed = removedTime;
+    }
+
+    public int getAlertCount() {
+        return alertCount;
+    }
+
+    public void setAlertCount(int count) {
+        alertCount = count;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("ManagementServer[").append("-").append(id).append("-").append(msid).append("-").append(state).append("]").toString();
+    }
+}
diff --git a/framework/cluster/src/com/cloud/cluster/RemoteMethodConstants.java b/framework/cluster/src/main/java/com/cloud/cluster/RemoteMethodConstants.java
similarity index 100%
rename from framework/cluster/src/com/cloud/cluster/RemoteMethodConstants.java
rename to framework/cluster/src/main/java/com/cloud/cluster/RemoteMethodConstants.java
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
new file mode 100644
index 0000000..6108269
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDao.java
@@ -0,0 +1,53 @@
+// 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.cluster.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.management.ManagementServerHost.State;
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDao;
+
+public interface ManagementServerHostDao extends GenericDao<ManagementServerHostVO, Long> {
+    @Override
+    boolean remove(Long id);
+
+    ManagementServerHostVO findByMsid(long msid);
+
+    int increaseAlertCount(long id);
+
+    void update(long id, long runid, String name, String version, String serviceIP, int servicePort, Date lastUpdate);
+
+    void update(long id, long runid, Date lastUpdate);
+
+    List<ManagementServerHostVO> getActiveList(Date cutTime);
+
+    List<ManagementServerHostVO> getInactiveList(Date cutTime);
+
+    void invalidateRunSession(long id, long runid);
+
+    void update(long id, long runId, State state, Date lastUpdate);
+
+    List<ManagementServerHostVO> listBy(ManagementServerHost.State... states);
+
+    public List<Long> listOrphanMsids();
+
+    ManagementServerHostVO findOneInUpState(Filter filter);
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
new file mode 100644
index 0000000..74f8481
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostDaoImpl.java
@@ -0,0 +1,275 @@
+// 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.cluster.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+
+import org.apache.log4j.Logger;
+
+import com.cloud.cluster.ClusterInvalidSessionException;
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.management.ManagementServerHost.State;
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class ManagementServerHostDaoImpl extends GenericDaoBase<ManagementServerHostVO, Long> implements ManagementServerHostDao {
+    private static final Logger s_logger = Logger.getLogger(ManagementServerHostDaoImpl.class);
+
+    private final SearchBuilder<ManagementServerHostVO> MsIdSearch;
+    private final SearchBuilder<ManagementServerHostVO> ActiveSearch;
+    private final SearchBuilder<ManagementServerHostVO> InactiveSearch;
+    private final SearchBuilder<ManagementServerHostVO> StateSearch;
+
+    @Override
+    public void invalidateRunSession(long id, long runid) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement("update mshost set runid=0, state='Down' where id=? and runid=?");
+            pstmt.setLong(1, id);
+            pstmt.setLong(2, runid);
+
+            pstmt.executeUpdate();
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB exception: ", e);
+        }
+    }
+
+    @Override
+    public ManagementServerHostVO findByMsid(long msid) {
+        SearchCriteria<ManagementServerHostVO> sc = MsIdSearch.create();
+        sc.setParameters("msid", msid);
+
+        List<ManagementServerHostVO> l = listIncludingRemovedBy(sc);
+        if (l != null && l.size() > 0) {
+            return l.get(0);
+        }
+
+        return null;
+    }
+
+    @Override
+    @DB
+    public void update(long id, long runid, String name, String version, String serviceIP, int servicePort, Date lastUpdate) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+
+            pstmt =
+                txn.prepareAutoCloseStatement("update mshost set name=?, version=?, service_ip=?, service_port=?, last_update=?, removed=null, alert_count=0, runid=?, state=? where id=?");
+            pstmt.setString(1, name);
+            pstmt.setString(2, version);
+            pstmt.setString(3, serviceIP);
+            pstmt.setInt(4, servicePort);
+            pstmt.setString(5, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
+            pstmt.setLong(6, runid);
+            pstmt.setString(7, ManagementServerHost.State.Up.toString());
+            pstmt.setLong(8, id);
+
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception e) {
+            s_logger.warn("Unexpected exception, ", e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    @DB
+    public boolean remove(Long id) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+
+        try {
+            txn.start();
+
+            ManagementServerHostVO msHost = findById(id);
+            msHost.setState(ManagementServerHost.State.Down);
+            super.remove(id);
+
+            txn.commit();
+            return true;
+        } catch (Exception e) {
+            s_logger.warn("Unexpected exception, ", e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    @DB
+    public void update(long id, long runid, Date lastUpdate) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+
+            pstmt = txn.prepareAutoCloseStatement("update mshost set last_update=?, removed=null, alert_count=0 where id=? and runid=?");
+            pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
+            pstmt.setLong(2, id);
+            pstmt.setLong(3, runid);
+
+            int count = pstmt.executeUpdate();
+            txn.commit();
+
+            if (count < 1) {
+                s_logger.info("Invalid cluster session detected, runId " + runid + " is no longer valid");
+                throw new CloudRuntimeException("Invalid cluster session detected, runId " + runid + " is no longer valid", new ClusterInvalidSessionException("runId " + runid + " is no longer valid"));
+            }
+        } catch (Exception e) {
+            s_logger.warn("Unexpected exception, ", e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public List<ManagementServerHostVO> getActiveList(Date cutTime) {
+        SearchCriteria<ManagementServerHostVO> sc = ActiveSearch.create();
+        sc.setParameters("lastUpdateTime", cutTime);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    public List<ManagementServerHostVO> getInactiveList(Date cutTime) {
+        SearchCriteria<ManagementServerHostVO> sc = InactiveSearch.create();
+        sc.setParameters("lastUpdateTime", cutTime);
+
+        return listIncludingRemovedBy(sc);
+    }
+
+    @Override
+    @DB
+    public int increaseAlertCount(long id) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        int changedRows = 0;
+        try {
+            txn.start();
+
+            pstmt = txn.prepareAutoCloseStatement("update mshost set alert_count=alert_count+1 where id=? and alert_count=0");
+            pstmt.setLong(1, id);
+
+            changedRows = pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception e) {
+            s_logger.warn("Unexpected exception, ", e);
+            throw new RuntimeException(e.getMessage(), e);
+        }
+
+        return changedRows;
+    }
+
+    protected ManagementServerHostDaoImpl() {
+        MsIdSearch = createSearchBuilder();
+        MsIdSearch.and("msid", MsIdSearch.entity().getMsid(), SearchCriteria.Op.EQ);
+        MsIdSearch.done();
+
+        ActiveSearch = createSearchBuilder();
+        ActiveSearch.and("lastUpdateTime", ActiveSearch.entity().getLastUpdateTime(), SearchCriteria.Op.GT);
+        ActiveSearch.and("removed", ActiveSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        ActiveSearch.done();
+
+        InactiveSearch = createSearchBuilder();
+        InactiveSearch.and("lastUpdateTime", InactiveSearch.entity().getLastUpdateTime(), SearchCriteria.Op.LTEQ);
+        InactiveSearch.and("removed", InactiveSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+        InactiveSearch.done();
+
+        StateSearch = createSearchBuilder();
+        StateSearch.and("state", StateSearch.entity().getState(), SearchCriteria.Op.IN);
+        StateSearch.done();
+    }
+
+    @Override
+    public void update(long id, long runId, State state, Date lastUpdate) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement("update mshost set state=?, last_update=? where id=? and runid=?");
+            pstmt.setString(1, state.toString());
+            pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), lastUpdate));
+            pstmt.setLong(3, id);
+            pstmt.setLong(4, runId);
+
+            int count = pstmt.executeUpdate();
+
+            if (count < 1) {
+                s_logger.info("Invalid cluster session detected, runId " + runId + " is no longer valid");
+                throw new CloudRuntimeException("Invalid cluster session detected, runId " + runId + " is no longer valid", new ClusterInvalidSessionException("runId " + runId + " is no longer valid"));
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB exception: ", e);
+        }
+    }
+
+    @Override
+    public List<ManagementServerHostVO> listBy(ManagementServerHost.State... states) {
+        SearchCriteria<ManagementServerHostVO> sc = StateSearch.create();
+
+        sc.setParameters("state", (Object[])states);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<Long> listOrphanMsids() {
+        List<Long> orphanList = new ArrayList<Long>();
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt =
+                txn.prepareAutoCloseStatement("select t.mgmt_server_id from (select mgmt_server_id, count(*) as count from host group by mgmt_server_id) as t WHERE t.count > 0 AND t.mgmt_server_id NOT IN (select msid from mshost)");
+
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                orphanList.add(rs.getLong(1));
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB exception: ", e);
+        }
+
+        return orphanList;
+    }
+
+    @Override
+    public ManagementServerHostVO findOneInUpState(Filter filter) {
+        SearchCriteria<ManagementServerHostVO> sc = StateSearch.create();
+
+        sc.setParameters("state", ManagementServerHost.State.Up);
+
+        List<ManagementServerHostVO> mshosts = listBy(sc, filter);
+        if (mshosts != null && mshosts.size() > 0) {
+            return mshosts.get(0);
+        }
+        return null;
+    }
+
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDao.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDao.java
new file mode 100644
index 0000000..f799116
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDao.java
@@ -0,0 +1,29 @@
+// 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.cluster.dao;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.cluster.ManagementServerHostPeerVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface ManagementServerHostPeerDao extends GenericDao<ManagementServerHostPeerVO, Long> {
+    void clearPeerInfo(long ownerMshost);
+
+    void updatePeerInfo(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState);
+
+    int countStateSeenInPeers(long mshost, long runid, ManagementServerHost.State state);
+}
diff --git a/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
new file mode 100644
index 0000000..a7a56c7
--- /dev/null
+++ b/framework/cluster/src/main/java/com/cloud/cluster/dao/ManagementServerHostPeerDaoImpl.java
@@ -0,0 +1,104 @@
+// 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.cluster.dao;
+
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.cluster.ManagementServerHostPeerVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+
+public class ManagementServerHostPeerDaoImpl extends GenericDaoBase<ManagementServerHostPeerVO, Long> implements ManagementServerHostPeerDao {
+    private static final Logger s_logger = Logger.getLogger(ManagementServerHostPeerDaoImpl.class);
+
+    private final SearchBuilder<ManagementServerHostPeerVO> ClearPeerSearch;
+    private final SearchBuilder<ManagementServerHostPeerVO> FindForUpdateSearch;
+    private final SearchBuilder<ManagementServerHostPeerVO> CountSearch;
+
+    public ManagementServerHostPeerDaoImpl() {
+        ClearPeerSearch = createSearchBuilder();
+        ClearPeerSearch.and("ownerMshost", ClearPeerSearch.entity().getOwnerMshost(), SearchCriteria.Op.EQ);
+        ClearPeerSearch.done();
+
+        FindForUpdateSearch = createSearchBuilder();
+        FindForUpdateSearch.and("ownerMshost", FindForUpdateSearch.entity().getOwnerMshost(), SearchCriteria.Op.EQ);
+        FindForUpdateSearch.and("peerMshost", FindForUpdateSearch.entity().getPeerMshost(), SearchCriteria.Op.EQ);
+        FindForUpdateSearch.and("peerRunid", FindForUpdateSearch.entity().getPeerRunid(), SearchCriteria.Op.EQ);
+        FindForUpdateSearch.done();
+
+        CountSearch = createSearchBuilder();
+        CountSearch.and("peerMshost", CountSearch.entity().getPeerMshost(), SearchCriteria.Op.EQ);
+        CountSearch.and("peerRunid", CountSearch.entity().getPeerRunid(), SearchCriteria.Op.EQ);
+        CountSearch.and("peerState", CountSearch.entity().getPeerState(), SearchCriteria.Op.EQ);
+        CountSearch.done();
+    }
+
+    @Override
+    @DB
+    public void clearPeerInfo(long ownerMshost) {
+        SearchCriteria<ManagementServerHostPeerVO> sc = ClearPeerSearch.create();
+        sc.setParameters("ownerMshost", ownerMshost);
+
+        expunge(sc);
+    }
+
+    @Override
+    @DB
+    public void updatePeerInfo(long ownerMshost, long peerMshost, long peerRunid, ManagementServerHost.State peerState) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            txn.start();
+
+            SearchCriteria<ManagementServerHostPeerVO> sc = FindForUpdateSearch.create();
+            sc.setParameters("ownerMshost", ownerMshost);
+            sc.setParameters("peerMshost", peerMshost);
+            sc.setParameters("peerRunid", peerRunid);
+            List<ManagementServerHostPeerVO> l = listBy(sc);
+            if (l.size() == 1) {
+                ManagementServerHostPeerVO peer = l.get(0);
+                peer.setPeerState(peerState);
+                update(peer.getId(), peer);
+            } else {
+                ManagementServerHostPeerVO peer = new ManagementServerHostPeerVO(ownerMshost, peerMshost, peerRunid, peerState);
+                persist(peer);
+            }
+            txn.commit();
+        } catch (Exception e) {
+            s_logger.warn("Unexpected exception, ", e);
+            txn.rollback();
+        }
+    }
+
+    @Override
+    @DB
+    public int countStateSeenInPeers(long mshost, long runid, ManagementServerHost.State state) {
+        SearchCriteria<ManagementServerHostPeerVO> sc = CountSearch.create();
+        sc.setParameters("peerMshost", mshost);
+        sc.setParameters("peerRunid", runid);
+        sc.setParameters("peerState", state);
+
+        List<ManagementServerHostPeerVO> l = listBy(sc);
+        return l.size();
+    }
+}
diff --git a/framework/cluster/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml b/framework/cluster/src/main/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml
similarity index 100%
rename from framework/cluster/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml
rename to framework/cluster/src/main/resources/META-INF/cloudstack/core/spring-framework-cluster-core-context.xml
diff --git a/framework/cluster/test/com/cloud/cluster/ClusterServiceServletAdapterTest.java b/framework/cluster/src/test/java/com/cloud/cluster/ClusterServiceServletAdapterTest.java
similarity index 100%
rename from framework/cluster/test/com/cloud/cluster/ClusterServiceServletAdapterTest.java
rename to framework/cluster/src/test/java/com/cloud/cluster/ClusterServiceServletAdapterTest.java
diff --git a/framework/config/pom.xml b/framework/config/pom.xml
index 03655d9..c006c3a 100644
--- a/framework/config/pom.xml
+++ b/framework/config/pom.xml
@@ -1,33 +1,42 @@
-<!-- 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. -->
+<!--
+  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-framework-config</artifactId>
-  <name>Apache CloudStack Framework - Configuration</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-framework-config</artifactId>
+    <name>Apache CloudStack Framework - Configuration</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/config/src/org/apache/cloudstack/config/Configuration.java b/framework/config/src/main/java/org/apache/cloudstack/config/Configuration.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/config/Configuration.java
rename to framework/config/src/main/java/org/apache/cloudstack/config/Configuration.java
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigDepot.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigDepot.java
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
diff --git a/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKey.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKey.java
new file mode 100644
index 0000000..2ace24d
--- /dev/null
+++ b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKey.java
@@ -0,0 +1,195 @@
+// 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.framework.config;
+
+import java.sql.Date;
+
+import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
+import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * ConfigKey supplants the original Config.java.  It is just a class
+ * declaration where others can declare their config variables.
+ *
+ */
+public class ConfigKey<T> {
+
+    public static enum Scope {
+        Global, Zone, Cluster, StoragePool, Account, ManagementServer, ImageStore, Domain
+    }
+
+    private final String _category;
+
+    public String category() {
+        return _category;
+    }
+
+    public Class<T> type() {
+        return _type;
+    }
+
+    public final String key() {
+        return _name;
+    }
+
+    public String defaultValue() {
+        return _defaultValue;
+    }
+
+    public String description() {
+        return _description;
+    }
+
+    public Scope scope() {
+        return _scope;
+    }
+
+    public boolean isDynamic() {
+        return _isDynamic;
+    }
+
+    @Override
+    public String toString() {
+        return _name;
+    }
+
+    private final Class<T> _type;
+    private final String _name;
+    private final String _defaultValue;
+    private final String _description;
+    private final Scope _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
+    private final boolean _isDynamic;
+    private final T _multiplier;
+    T _value = null;
+
+    static ConfigDepotImpl s_depot = null;
+
+    static public void init(ConfigDepotImpl depot) {
+        s_depot = depot;
+    }
+
+    public ConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean isDynamic, Scope scope) {
+        this(type, name, category, defaultValue, description, isDynamic, scope, null);
+    }
+
+    public ConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean isDynamic) {
+        this(type, name, category, defaultValue, description, isDynamic, Scope.Global, null);
+    }
+
+    public ConfigKey(Class<T> type, String name, String category, String defaultValue, String description, boolean isDynamic, Scope scope, T multiplier) {
+        _category = category;
+        _type = type;
+        _name = name;
+        _defaultValue = defaultValue;
+        _description = description;
+        _scope = scope;
+        _isDynamic = isDynamic;
+        _multiplier = multiplier;
+    }
+
+    @Deprecated
+    public ConfigKey(Class<T> type, String name, String category, String defaultValue, String description, boolean isDynamic) {
+        this(type, name, category, defaultValue, description, isDynamic, Scope.Global, null);
+    }
+
+    public T multiplier() {
+        return _multiplier;
+    }
+
+    @Override
+    public int hashCode() {
+        return _name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ConfigKey) {
+            ConfigKey<?> that = (ConfigKey<?>)obj;
+            return this._name.equals(that._name);
+        }
+        return false;
+    }
+
+    public boolean isSameKeyAs(Object obj) {
+        if(this.equals(obj)) {
+            return true;
+        } else if (obj instanceof String) {
+            String key = (String)obj;
+            return key.equals(_name);
+        }
+
+        throw new CloudRuntimeException("Comparing ConfigKey to " + obj.toString());
+    }
+
+    public T value() {
+        if (_value == null || isDynamic()) {
+            ConfigurationVO vo = s_depot != null ? s_depot.global().findById(key()) : null;
+            final String value = (vo != null && vo.getValue() != null) ? vo.getValue() : defaultValue();
+            _value = ((value == null) ? (T)defaultValue() : valueOf(value));
+        }
+
+        return _value;
+    }
+
+    public T valueIn(Long id) {
+        if (id == null) {
+            return value();
+        }
+
+        String value = s_depot != null ? s_depot.findScopedConfigStorage(this).getConfigValue(id, this) : null;
+        if (value == null) {
+            return value();
+        } else {
+            return valueOf(value);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected T valueOf(String value) {
+        Number multiplier = 1;
+        if (multiplier() != null) {
+            multiplier = (Number)multiplier();
+        }
+        Class<T> type = type();
+        if (type.isAssignableFrom(Boolean.class)) {
+            return (T)Boolean.valueOf(value);
+        } else if (type.isAssignableFrom(Integer.class)) {
+            return (T)new Integer(Integer.parseInt(value) * multiplier.intValue());
+        } else if (type.isAssignableFrom(Long.class)) {
+            return (T)new Long(Long.parseLong(value) * multiplier.longValue());
+        } else if (type.isAssignableFrom(Short.class)) {
+            return (T)new Short(Short.parseShort(value));
+        } else if (type.isAssignableFrom(String.class)) {
+            return (T)value;
+        } else if (type.isAssignableFrom(Float.class)) {
+            return (T)new Float(Float.parseFloat(value) * multiplier.floatValue());
+        } else if (type.isAssignableFrom(Double.class)) {
+            return (T)new Double(Double.parseDouble(value) * multiplier.doubleValue());
+        } else if (type.isAssignableFrom(String.class)) {
+            return (T)value;
+        } else if (type.isAssignableFrom(Date.class)) {
+            return (T)Date.valueOf(value);
+        } else if (type.isAssignableFrom(Character.class)) {
+            return (T)new Character(value.charAt(0));
+        } else {
+            throw new CloudRuntimeException("Unsupported data type for config values: " + type);
+        }
+    }
+
+}
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/Configurable.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/Configurable.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/Configurable.java
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigStorage.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/ScopedConfigStorage.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigStorage.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/ScopedConfigStorage.java
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/dao/ConfigurationDao.java
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/dao/ConfigurationDaoImpl.java
diff --git a/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java
new file mode 100644
index 0000000..ddc06b6
--- /dev/null
+++ b/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java
@@ -0,0 +1,222 @@
+// 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.framework.config.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.ScopedConfigStorage;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * ConfigDepotImpl implements the ConfigDepot and ConfigDepotAdmin interface.
+ * Its functionalities include:
+ *   - Control how dynamic config values are cached and refreshed.
+ *   - Control how scoped config values are stored.
+ *   - Gather all of the Configurable interfaces and insert their config
+ *     variables into the config table.
+ *   - Hide the data source where configs are stored and retrieved.
+ *
+ * When dealing with this class, we must be very careful on cluster situations.
+ *
+ * TODO:
+ *   - Move the rest of the changes to the config table to here.
+ *   - Add the code to mark the rows in configuration table without
+ *     the corresponding keys to be null.
+ *   - Move all of the configurations to using ConfigDepot
+ *   - Completely eliminate Config.java
+ *   - Figure out the correct categories.
+ *   - Add a scope for management server, where if the scope is management server
+ *     then the override is retrieved from a properties file.  Imagine adding a
+ *     new management server node and it is much more capable system than previous
+ *     management servers, you want the adjustments to thread pools etc to be
+ *     very different than other management serves.
+ *   - Add validation methods to ConfigKey<?>.  If a validation class is declared
+ *     when constructing a ConfigKey then configuration server should use the
+ *     validation class to validate the value the admin input for the key.
+ */
+public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
+    private final static Logger s_logger = Logger.getLogger(ConfigDepotImpl.class);
+    @Inject
+    ConfigurationDao _configDao;
+    List<Configurable> _configurables;
+    List<ScopedConfigStorage> _scopedStorages;
+    Set<Configurable> _configured = Collections.synchronizedSet(new HashSet<Configurable>());
+
+    private HashMap<String, Pair<String, ConfigKey<?>>> _allKeys = new HashMap<String, Pair<String, ConfigKey<?>>>(1007);
+
+    HashMap<ConfigKey.Scope, Set<ConfigKey<?>>> _scopeLevelConfigsMap = new HashMap<ConfigKey.Scope, Set<ConfigKey<?>>>();
+
+    public ConfigDepotImpl() {
+        ConfigKey.init(this);
+        createEmptyScopeLevelMappings();
+    }
+
+    /**
+     * Create an empty map of ConfigKey.Scope values, setting the _scopeLevelConfigsMap with the created map
+     * This map must contain all ConfigKey.Scope values, except the ConfigKey.Scope.Global.
+     */
+    protected void createEmptyScopeLevelMappings() {
+        _scopeLevelConfigsMap = new HashMap<ConfigKey.Scope, Set<ConfigKey<?>>>();
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.Zone, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.Account, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.ImageStore, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.Domain, new HashSet<ConfigKey<?>>());
+        _scopeLevelConfigsMap.put(ConfigKey.Scope.ManagementServer, new HashSet<ConfigKey<?>>());
+    }
+
+    @Override
+    public ConfigKey<?> get(String key) {
+        Pair<String, ConfigKey<?>> value = _allKeys.get(key);
+        return value != null ? value.second() : null;
+    }
+
+    @PostConstruct
+    @Override
+    public void populateConfigurations() {
+        Date date = new Date();
+        for (Configurable configurable : _configurables) {
+            populateConfiguration(date, configurable);
+        }
+    }
+
+    protected void populateConfiguration(Date date, Configurable configurable) {
+        if (_configured.contains(configurable))
+            return;
+
+        s_logger.debug("Retrieving keys from " + configurable.getClass().getSimpleName());
+
+        for (ConfigKey<?> key : configurable.getConfigKeys()) {
+            Pair<String, ConfigKey<?>> previous = _allKeys.get(key.key());
+            if (previous != null && !previous.first().equals(configurable.getConfigComponentName())) {
+                throw new CloudRuntimeException("Configurable " + configurable.getConfigComponentName() + " is adding a key that has been added before by " +
+                    previous.first() + ": " + key.toString());
+            }
+            _allKeys.put(key.key(), new Pair<String, ConfigKey<?>>(configurable.getConfigComponentName(), key));
+
+            createOrupdateConfigObject(date, configurable.getConfigComponentName(), key, null);
+
+            if ((key.scope() != null) && (key.scope() != ConfigKey.Scope.Global)) {
+                Set<ConfigKey<?>> currentConfigs = _scopeLevelConfigsMap.get(key.scope());
+                currentConfigs.add(key);
+            }
+        }
+
+        _configured.add(configurable);
+    }
+
+    private void createOrupdateConfigObject(Date date, String componentName, ConfigKey<?> key, String value) {
+        ConfigurationVO vo = _configDao.findById(key.key());
+        if (vo == null) {
+            vo = new ConfigurationVO(componentName, key);
+            vo.setUpdated(date);
+            if (value != null) {
+                vo.setValue(value);
+            }
+            _configDao.persist(vo);
+        } else {
+            if (vo.isDynamic() != key.isDynamic() || !ObjectUtils.equals(vo.getDescription(), key.description()) || !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue()) ||
+                !ObjectUtils.equals(vo.getScope(), key.scope().toString()) ||
+                !ObjectUtils.equals(vo.getComponent(), componentName)) {
+                vo.setDynamic(key.isDynamic());
+                vo.setDescription(key.description());
+                vo.setDefaultValue(key.defaultValue());
+                vo.setScope(key.scope().toString());
+                vo.setComponent(componentName);
+                vo.setUpdated(date);
+                _configDao.persist(vo);
+            }
+        }
+    }
+
+    @Override
+    public void populateConfiguration(Configurable configurable) {
+        populateConfiguration(new Date(), configurable);
+    }
+
+    @Override
+    public List<String> getComponentsInDepot() {
+        return new ArrayList<String>();
+    }
+
+    public ConfigurationDao global() {
+        return _configDao;
+    }
+
+    public ScopedConfigStorage findScopedConfigStorage(ConfigKey<?> config) {
+        for (ScopedConfigStorage storage : _scopedStorages) {
+            if (storage.getScope() == config.scope()) {
+                return storage;
+            }
+        }
+
+        throw new CloudRuntimeException("Unable to find config storage for this scope: " + config.scope() + " for " + config.key());
+    }
+
+    public List<ScopedConfigStorage> getScopedStorages() {
+        return _scopedStorages;
+    }
+
+    @Inject
+    public void setScopedStorages(List<ScopedConfigStorage> scopedStorages) {
+        _scopedStorages = scopedStorages;
+    }
+
+    public List<Configurable> getConfigurables() {
+        return _configurables;
+    }
+
+    @Inject
+    public void setConfigurables(List<Configurable> configurables) {
+        _configurables = configurables;
+    }
+
+    @Override
+    public Set<ConfigKey<?>> getConfigListByScope(String scope) {
+        return _scopeLevelConfigsMap.get(ConfigKey.Scope.valueOf(scope));
+    }
+
+    @Override
+    public <T> void set(ConfigKey<T> key, T value) {
+        _configDao.update(key.key(), value.toString());
+    }
+
+    @Override
+    public <T> void createOrUpdateConfigObject(String componentName, ConfigKey<T> key, String value) {
+        createOrupdateConfigObject(new Date(), componentName, key, value);
+
+    }
+}
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java
similarity index 100%
rename from framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java
rename to framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java
diff --git a/framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context-inheritable.xml b/framework/config/src/main/resources/META-INF/cloudstack/system/spring-framework-config-system-context-inheritable.xml
similarity index 100%
rename from framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context-inheritable.xml
rename to framework/config/src/main/resources/META-INF/cloudstack/system/spring-framework-config-system-context-inheritable.xml
diff --git a/framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml b/framework/config/src/main/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml
similarity index 100%
rename from framework/config/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml
rename to framework/config/src/main/resources/META-INF/cloudstack/system/spring-framework-config-system-context.xml
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java b/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
deleted file mode 100644
index 1734b98..0000000
--- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
+++ /dev/null
@@ -1,195 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.config;
-
-import java.sql.Date;
-
-import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * ConfigKey supplants the original Config.java.  It is just a class
- * declaration where others can declare their config variables.
- *
- */
-public class ConfigKey<T> {
-
-    public static enum Scope {
-        Global, Zone, Cluster, StoragePool, Account, ManagementServer, ImageStore, Domain
-    }
-
-    private final String _category;
-
-    public String category() {
-        return _category;
-    }
-
-    public Class<T> type() {
-        return _type;
-    }
-
-    public final String key() {
-        return _name;
-    }
-
-    public String defaultValue() {
-        return _defaultValue;
-    }
-
-    public String description() {
-        return _description;
-    }
-
-    public Scope scope() {
-        return _scope;
-    }
-
-    public boolean isDynamic() {
-        return _isDynamic;
-    }
-
-    @Override
-    public String toString() {
-        return _name;
-    }
-
-    private final Class<T> _type;
-    private final String _name;
-    private final String _defaultValue;
-    private final String _description;
-    private final Scope _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
-    private final boolean _isDynamic;
-    private final T _multiplier;
-    T _value = null;
-
-    static ConfigDepotImpl s_depot = null;
-
-    static public void init(ConfigDepotImpl depot) {
-        s_depot = depot;
-    }
-
-    public ConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean isDynamic, Scope scope) {
-        this(type, name, category, defaultValue, description, isDynamic, scope, null);
-    }
-
-    public ConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean isDynamic) {
-        this(type, name, category, defaultValue, description, isDynamic, Scope.Global, null);
-    }
-
-    public ConfigKey(Class<T> type, String name, String category, String defaultValue, String description, boolean isDynamic, Scope scope, T multiplier) {
-        _category = category;
-        _type = type;
-        _name = name;
-        _defaultValue = defaultValue;
-        _description = description;
-        _scope = scope;
-        _isDynamic = isDynamic;
-        _multiplier = multiplier;
-    }
-
-    @Deprecated
-    public ConfigKey(Class<T> type, String name, String category, String defaultValue, String description, boolean isDynamic) {
-        this(type, name, category, defaultValue, description, isDynamic, Scope.Global, null);
-    }
-
-    public T multiplier() {
-        return _multiplier;
-    }
-
-    @Override
-    public int hashCode() {
-        return _name.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ConfigKey) {
-            ConfigKey<?> that = (ConfigKey<?>)obj;
-            return this._name.equals(that._name);
-        }
-        return false;
-    }
-
-    public boolean isSameKeyAs(Object obj) {
-        if(this.equals(obj)) {
-            return true;
-        } else if (obj instanceof String) {
-            String key = (String)obj;
-            return key.equals(_name);
-        }
-
-        throw new CloudRuntimeException("Comparing ConfigKey to " + obj.toString());
-    }
-
-    public T value() {
-        if (_value == null || isDynamic()) {
-            ConfigurationVO vo = s_depot != null ? s_depot.global().findById(key()) : null;
-            final String value = (vo != null && vo.getValue() != null) ? vo.getValue() : defaultValue();
-            _value = ((value == null) ? (T)defaultValue() : valueOf(value));
-        }
-
-        return _value;
-    }
-
-    public T valueIn(Long id) {
-        if (id == null) {
-            return value();
-        }
-
-        String value = s_depot != null ? s_depot.scoped(this).getConfigValue(id, this) : null;
-        if (value == null) {
-            return value();
-        } else {
-            return valueOf(value);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected T valueOf(String value) {
-        Number multiplier = 1;
-        if (multiplier() != null) {
-            multiplier = (Number)multiplier();
-        }
-        Class<T> type = type();
-        if (type.isAssignableFrom(Boolean.class)) {
-            return (T)Boolean.valueOf(value);
-        } else if (type.isAssignableFrom(Integer.class)) {
-            return (T)new Integer(Integer.parseInt(value) * multiplier.intValue());
-        } else if (type.isAssignableFrom(Long.class)) {
-            return (T)new Long(Long.parseLong(value) * multiplier.longValue());
-        } else if (type.isAssignableFrom(Short.class)) {
-            return (T)new Short(Short.parseShort(value));
-        } else if (type.isAssignableFrom(String.class)) {
-            return (T)value;
-        } else if (type.isAssignableFrom(Float.class)) {
-            return (T)new Float(Float.parseFloat(value) * multiplier.floatValue());
-        } else if (type.isAssignableFrom(Double.class)) {
-            return (T)new Double(Double.parseDouble(value) * multiplier.doubleValue());
-        } else if (type.isAssignableFrom(String.class)) {
-            return (T)value;
-        } else if (type.isAssignableFrom(Date.class)) {
-            return (T)Date.valueOf(value);
-        } else if (type.isAssignableFrom(Character.class)) {
-            return (T)new Character(value.charAt(0));
-        } else {
-            throw new CloudRuntimeException("Unsupported data type for config values: " + type);
-        }
-    }
-
-}
diff --git a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java b/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java
deleted file mode 100644
index 6a85b90..0000000
--- a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.config.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.ScopedConfigStorage;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.Pair;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * ConfigDepotImpl implements the ConfigDepot and ConfigDepotAdmin interface.
- * Its functionalities include:
- *   - Control how dynamic config values are cached and refreshed.
- *   - Control how scoped config values are stored.
- *   - Gather all of the Configurable interfaces and insert their config
- *     variables into the config table.
- *   - Hide the data source where configs are stored and retrieved.
- *
- * When dealing with this class, we must be very careful on cluster situations.
- *
- * TODO:
- *   - Move the rest of the changes to the config table to here.
- *   - Add the code to mark the rows in configuration table without
- *     the corresponding keys to be null.
- *   - Move all of the configurations to using ConfigDepot
- *   - Completely eliminate Config.java
- *   - Figure out the correct categories.
- *   - Add a scope for management server, where if the scope is management server
- *     then the override is retrieved from a properties file.  Imagine adding a
- *     new management server node and it is much more capable system than previous
- *     management servers, you want the adjustments to thread pools etc to be
- *     very different than other management serves.
- *   - Add validation methods to ConfigKey<?>.  If a validation class is declared
- *     when constructing a ConfigKey then configuration server should use the
- *     validation class to validate the value the admin input for the key.
- */
-public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
-    private final static Logger s_logger = Logger.getLogger(ConfigDepotImpl.class);
-    @Inject
-    ConfigurationDao _configDao;
-    List<Configurable> _configurables;
-    List<ScopedConfigStorage> _scopedStorages;
-    Set<Configurable> _configured = Collections.synchronizedSet(new HashSet<Configurable>());
-
-    HashMap<String, Pair<String, ConfigKey<?>>> _allKeys = new HashMap<String, Pair<String, ConfigKey<?>>>(1007);
-
-    HashMap<ConfigKey.Scope, Set<ConfigKey<?>>> _scopeLevelConfigsMap = new HashMap<ConfigKey.Scope, Set<ConfigKey<?>>>();
-
-    public ConfigDepotImpl() {
-        ConfigKey.init(this);
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.Zone, new HashSet<ConfigKey<?>>());
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster, new HashSet<ConfigKey<?>>());
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool, new HashSet<ConfigKey<?>>());
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.Account, new HashSet<ConfigKey<?>>());
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.ImageStore, new HashSet<ConfigKey<?>>());
-        _scopeLevelConfigsMap.put(ConfigKey.Scope.Domain, new HashSet<ConfigKey<?>>());
-    }
-
-    @Override
-    public ConfigKey<?> get(String key) {
-        Pair<String, ConfigKey<?>> value = _allKeys.get(key);
-        return value != null ? value.second() : null;
-    }
-
-    @PostConstruct
-    @Override
-    public void populateConfigurations() {
-        Date date = new Date();
-        for (Configurable configurable : _configurables) {
-            populateConfiguration(date, configurable);
-        }
-    }
-
-    protected void populateConfiguration(Date date, Configurable configurable) {
-        if (_configured.contains(configurable))
-            return;
-
-        s_logger.debug("Retrieving keys from " + configurable.getClass().getSimpleName());
-
-        for (ConfigKey<?> key : configurable.getConfigKeys()) {
-            Pair<String, ConfigKey<?>> previous = _allKeys.get(key.key());
-            if (previous != null && !previous.first().equals(configurable.getConfigComponentName())) {
-                throw new CloudRuntimeException("Configurable " + configurable.getConfigComponentName() + " is adding a key that has been added before by " +
-                    previous.first() + ": " + key.toString());
-            }
-            _allKeys.put(key.key(), new Pair<String, ConfigKey<?>>(configurable.getConfigComponentName(), key));
-
-            createOrupdateConfigObject(date, configurable.getConfigComponentName(), key, null);
-
-            if ((key.scope() != null) && (key.scope() != ConfigKey.Scope.Global)) {
-                Set<ConfigKey<?>> currentConfigs = _scopeLevelConfigsMap.get(key.scope());
-                currentConfigs.add(key);
-            }
-        }
-
-        _configured.add(configurable);
-    }
-
-    private void createOrupdateConfigObject(Date date, String componentName, ConfigKey<?> key, String value) {
-        ConfigurationVO vo = _configDao.findById(key.key());
-        if (vo == null) {
-            vo = new ConfigurationVO(componentName, key);
-            vo.setUpdated(date);
-            if (value != null) {
-                vo.setValue(value);
-            }
-            _configDao.persist(vo);
-        } else {
-            if (vo.isDynamic() != key.isDynamic() || !ObjectUtils.equals(vo.getDescription(), key.description()) || !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue()) ||
-                !ObjectUtils.equals(vo.getScope(), key.scope().toString()) ||
-                !ObjectUtils.equals(vo.getComponent(), componentName)) {
-                vo.setDynamic(key.isDynamic());
-                vo.setDescription(key.description());
-                vo.setDefaultValue(key.defaultValue());
-                vo.setScope(key.scope().toString());
-                vo.setComponent(componentName);
-                vo.setUpdated(date);
-                _configDao.persist(vo);
-            }
-        }
-    }
-
-    @Override
-    public void populateConfiguration(Configurable configurable) {
-        populateConfiguration(new Date(), configurable);
-    }
-
-    @Override
-    public List<String> getComponentsInDepot() {
-        return new ArrayList<String>();
-    }
-
-    public ConfigurationDao global() {
-        return _configDao;
-    }
-
-    public ScopedConfigStorage scoped(ConfigKey<?> config) {
-        for (ScopedConfigStorage storage : _scopedStorages) {
-            if (storage.getScope() == config.scope()) {
-                return storage;
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to find config storage for this scope: " + config.scope() + " for " + config.key());
-    }
-
-    public List<ScopedConfigStorage> getScopedStorages() {
-        return _scopedStorages;
-    }
-
-    @Inject
-    public void setScopedStorages(List<ScopedConfigStorage> scopedStorages) {
-        _scopedStorages = scopedStorages;
-    }
-
-    public List<Configurable> getConfigurables() {
-        return _configurables;
-    }
-
-    @Inject
-    public void setConfigurables(List<Configurable> configurables) {
-        _configurables = configurables;
-    }
-
-    @Override
-    public Set<ConfigKey<?>> getConfigListByScope(String scope) {
-        return _scopeLevelConfigsMap.get(ConfigKey.Scope.valueOf(scope));
-    }
-
-    @Override
-    public <T> void set(ConfigKey<T> key, T value) {
-        _configDao.update(key.key(), value.toString());
-    }
-
-    @Override
-    public <T> void createOrUpdateConfigObject(String componentName, ConfigKey<T> key, String value) {
-        createOrupdateConfigObject(new Date(), componentName, key, value);
-
-    }
-}
diff --git a/framework/config/test/org/apache/cloudstack/framework/config/ConfigKeyTest.java b/framework/config/src/test/java/org/apache/cloudstack/framework/config/ConfigKeyTest.java
similarity index 100%
rename from framework/config/test/org/apache/cloudstack/framework/config/ConfigKeyTest.java
rename to framework/config/src/test/java/org/apache/cloudstack/framework/config/ConfigKeyTest.java
diff --git a/framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java b/framework/config/src/test/java/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java
similarity index 100%
rename from framework/config/test/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java
rename to framework/config/src/test/java/org/apache/cloudstack/framework/config/impl/ConfigDepotAdminTest.java
diff --git a/framework/config/src/test/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImplTest.java b/framework/config/src/test/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImplTest.java
new file mode 100644
index 0000000..fed784c
--- /dev/null
+++ b/framework/config/src/test/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImplTest.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 org.apache.cloudstack.framework.config.impl;
+
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ConfigDepotImplTest {
+
+    private ConfigDepotImpl configDepotImpl = new ConfigDepotImpl();
+
+    @Test
+    public void createEmptyScopeLevelMappingsTest() {
+        configDepotImpl.createEmptyScopeLevelMappings();
+        ConfigKey.Scope[] configKeyScopeArray = ConfigKey.Scope.values();
+
+        for (int i = 0; i < configKeyScopeArray.length; i++) {
+            if (configKeyScopeArray[i] == ConfigKey.Scope.Global) {
+                Assert.assertFalse(configDepotImpl._scopeLevelConfigsMap.containsKey(configKeyScopeArray[i]));
+            } else {
+                Assert.assertTrue(configDepotImpl._scopeLevelConfigsMap.containsKey(configKeyScopeArray[i]));
+            }
+        }
+    }
+
+}
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index d6674d8..defedd7 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -1,63 +1,71 @@
-<!-- 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. -->
+<!--
+  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-framework-db</artifactId>
-  <name>Apache CloudStack Framework - Database</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>net.sf.ehcache</groupId>
-      <artifactId>ehcache-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>javax.persistence</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-dbcp2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-pool2</artifactId>
-    </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>
-          <excludes>
-            <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
-            <exclude>com/cloud/utils/db/*Test*</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    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-framework-db</artifactId>
+    <name>Apache CloudStack Framework - Database</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>javax.persistence</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-dbcp2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </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>
+                    <excludes>
+                        <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
+                        <exclude>com/cloud/utils/db/*Test*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
deleted file mode 100644
index 304a122..0000000
--- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java
+++ /dev/null
@@ -1,2084 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// the License.  You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.utils.db;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import com.google.common.base.Strings;
-import javax.naming.ConfigurationException;
-import javax.persistence.AttributeOverride;
-import javax.persistence.Column;
-import javax.persistence.EmbeddedId;
-import javax.persistence.EntityExistsException;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-
-import net.sf.cglib.proxy.Callback;
-import net.sf.cglib.proxy.CallbackFilter;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.NoOp;
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ComponentLifecycleBase;
-import com.cloud.utils.component.ComponentMethodInterceptable;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.SearchCriteria.SelectType;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-
-/**
- *  GenericDaoBase is a simple way to implement DAOs.  It DOES NOT
- *  support the full EJB3 spec.  It borrows some of the annotations from
- *  the EJB3 spec to produce a set of SQLs so developers don't have to
- *  copy and paste the same code over and over again.  Of course,
- *  GenericDaoBase is completely at the mercy of the annotations you add
- *  to your entity bean.  If GenericDaoBase does not fit your needs, then
- *  don't extend from it.
- *
- *  GenericDaoBase attempts to achieve the following:
- *    1. If you use _allFieldsStr in your SQL statement and use to() to convert
- *       the result to the entity bean, you don't ever have to worry about
- *       missing fields because its automatically taken from the entity bean's
- *       annotations.
- *    2. You don't have to rewrite the same insert and select query strings
- *       in all of your DAOs.
- *    3. You don't have to match the '?' (you know what I'm talking about) to
- *       the fields in the insert statement as that's taken care of for you.
- *
- *  GenericDaoBase looks at the following annotations:
- *    1. Table - just name
- *    2. Column - just name
- *    3. GeneratedValue - any field with this annotation is not inserted.
- *    4. SequenceGenerator - sequence generator
- *    5. Id
- *    6. SecondaryTable
- *
- *  Sometime later, I might look into injecting the SQLs as needed but right
- *  now we have to construct them at construction time.  The good thing is that
- *  the DAOs are suppose to be one per jvm so the time is all during the
- *  initial load.
- *
- **/
-@DB
-public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID>, ComponentMethodInterceptable {
-    private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
-
-    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
-
-    protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
-
-    protected Class<T> _entityBeanType;
-    protected String _table;
-
-    protected String _tables;
-
-    protected Field[] _embeddedFields;
-
-    // This is private on purpose.  Everyone should use createPartialSelectSql()
-    private final Pair<StringBuilder, Attribute[]> _partialSelectSql;
-    private final Pair<StringBuilder, Attribute[]> _partialQueryCacheSelectSql;
-    protected StringBuilder _discriminatorClause;
-    protected Map<String, Object> _discriminatorValues;
-    protected String _selectByIdSql;
-    protected String _count;
-    protected String _distinctIdSql;
-
-    protected Field _idField;
-
-    protected List<Pair<String, Attribute[]>> _insertSqls;
-    protected Pair<String, Attribute> _removed;
-    protected Pair<String, Attribute[]> _removeSql;
-    protected List<Pair<String, Attribute[]>> _deleteSqls;
-    protected Map<String, Attribute[]> _idAttributes;
-    protected Map<String, TableGenerator> _tgs;
-    protected Map<String, Attribute> _allAttributes;
-    protected List<Attribute> _ecAttributes;
-    protected Map<Pair<String, String>, Attribute> _allColumns;
-    protected Enhancer _enhancer;
-    protected Factory _factory;
-    protected Enhancer _searchEnhancer;
-    protected int _timeoutSeconds;
-
-    protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
-
-    protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
-    protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE";
-    protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
-    public static final Date DATE_TO_NULL = new Date(Long.MIN_VALUE);
-
-    protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
-
-    public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
-        @SuppressWarnings("unchecked")
-        GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
-        assert dao != null : "Unable to find DAO for " + entityType + ".  Are you sure you waited for the DAO to be initialized before asking for it?";
-        return dao;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    @DB()
-    public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) {
-        return new GenericSearchBuilder<T, J>(_entityBeanType, resultType);
-    }
-
-    @Override
-    public Map<String, Attribute> getAllAttributes() {
-        return _allAttributes;
-    }
-
-    @SuppressWarnings("unchecked")
-    public T createSearchEntity(MethodInterceptor interceptor) {
-        T entity = (T)_searchEnhancer.create();
-        final Factory factory = (Factory)entity;
-        factory.setCallback(0, interceptor);
-        return entity;
-    }
-
-    @SuppressWarnings("unchecked")
-    protected GenericDaoBase() {
-        super();
-        Type t = getClass().getGenericSuperclass();
-        if (t instanceof ParameterizedType) {
-            _entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0];
-        } else if (((Class<?>)t).getGenericSuperclass() instanceof ParameterizedType) {
-            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
-        } else {
-            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)((Class<?>)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0];
-        }
-
-        s_daoMaps.put(_entityBeanType, this);
-        Class<?>[] interphaces = _entityBeanType.getInterfaces();
-        if (interphaces != null) {
-            for (Class<?> interphace : interphaces) {
-                s_daoMaps.put(interphace, this);
-            }
-        }
-
-        _table = DbUtil.getTableName(_entityBeanType);
-
-        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
-        _partialSelectSql = generator.buildSelectSql(false);
-        _count = generator.buildCountSql();
-        _distinctIdSql= generator.buildDistinctIdSql();
-        _partialQueryCacheSelectSql = generator.buildSelectSql(true);
-        _embeddedFields = generator.getEmbeddedFields();
-        _insertSqls = generator.buildInsertSqls();
-        final Pair<StringBuilder, Map<String, Object>> dc = generator.buildDiscriminatorClause();
-        _discriminatorClause = dc.first().length() == 0 ? null : dc.first();
-        _discriminatorValues = dc.second();
-
-        _idAttributes = generator.getIdAttributes();
-        _idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
-
-        _tables = generator.buildTableReferences();
-
-        _allAttributes = generator.getAllAttributes();
-        _allColumns = generator.getAllColumns();
-
-        _selectByIdSql = buildSelectByIdSql(createPartialSelectSql(null, true));
-        _removeSql = generator.buildRemoveSql();
-        _deleteSqls = generator.buildDeleteSqls();
-        _removed = generator.getRemovedAttribute();
-        _tgs = generator.getTableGenerators();
-        _ecAttributes = generator.getElementCollectionAttributes();
-
-        TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
-        if (tg != null) {
-            _tgs.put(tg.name(), tg);
-        }
-        tg = this.getClass().getSuperclass().getAnnotation(TableGenerator.class);
-        if (tg != null) {
-            _tgs.put(tg.name(), tg);
-        }
-
-        Callback[] callbacks = new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)};
-
-        _enhancer = new Enhancer();
-        _enhancer.setSuperclass(_entityBeanType);
-        _enhancer.setCallbackFilter(s_callbackFilter);
-        _enhancer.setCallbacks(callbacks);
-        _factory = (Factory)_enhancer.create();
-
-        _searchEnhancer = new Enhancer();
-        _searchEnhancer.setSuperclass(_entityBeanType);
-        _searchEnhancer.setCallback(new UpdateBuilder(this));
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
-            s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql"));
-            s_logger.trace("Select by Id SQL: " + _selectByIdSql);
-            s_logger.trace("Table References: " + _tables);
-            s_logger.trace("Insert SQLs:");
-            for (final Pair<String, Attribute[]> insertSql : _insertSqls) {
-                s_logger.trace(insertSql.first());
-            }
-
-            s_logger.trace("Delete SQLs");
-            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
-                s_logger.trace(deletSql.first());
-            }
-
-            s_logger.trace("Collection SQLs");
-            for (Attribute attr : _ecAttributes) {
-                EcInfo info = (EcInfo)attr.attache;
-                s_logger.trace(info.insertSql);
-                s_logger.trace(info.selectSql);
-            }
-        }
-
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_SYSTEM);
-    }
-
-    @Override
-    @DB()
-    @SuppressWarnings("unchecked")
-    public T createForUpdate(final ID id) {
-        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
-        if (id != null) {
-            try {
-                _idField.set(entity, id);
-            } catch (final IllegalArgumentException e) {
-            } catch (final IllegalAccessException e) {
-            }
-        }
-        return entity;
-    }
-
-    @Override
-    @DB()
-    public T createForUpdate() {
-        return createForUpdate(null);
-    }
-
-    @Override
-    @DB()
-    public <K> K getNextInSequence(final Class<K> clazz, final String name) {
-        final TableGenerator tg = _tgs.get(name);
-        assert (tg != null) : "Couldn't find Table generator using " + name;
-
-        return s_seqFetcher.getNextSequence(clazz, tg);
-    }
-
-    @Override
-    @DB()
-    public <K> K getRandomlyIncreasingNextInSequence(final Class<K> clazz, final String name) {
-        final TableGenerator tg = _tgs.get(name);
-        assert (tg != null) : "Couldn't find Table generator using " + name;
-
-        return s_seqFetcher.getRandomNextSequence(clazz, tg);
-    }
-
-    @Override
-    @DB()
-    public List<T> lockRows(final SearchCriteria<T> sc, final Filter filter, final boolean exclusive) {
-        return search(sc, filter, exclusive, false);
-    }
-
-    @Override
-    @DB()
-    public T lockOneRandomRow(final SearchCriteria<T> sc, final boolean exclusive) {
-        final Filter filter = new Filter(1);
-        final List<T> beans = search(sc, filter, exclusive, true);
-        return beans.isEmpty() ? null : beans.get(0);
-    }
-
-    @DB()
-    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
-        if (_removed != null) {
-            if (sc == null) {
-                sc = createSearchCriteria();
-            }
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return searchIncludingRemoved(sc, filter, lock, cache);
-    }
-
-    @DB()
-    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enableQueryCache) {
-        if (_removed != null) {
-            if (sc == null) {
-                sc = createSearchCriteria();
-            }
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return searchIncludingRemoved(sc, filter, lock, cache, enableQueryCache);
-    }
-
-    @Override
-    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
-        return searchIncludingRemoved(sc, filter, lock, cache, false);
-    }
-
-    @Override
-    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enableQueryCache) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createPartialSelectSql(sc, clause != null, enableQueryCache);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        List<Object> groupByValues = addGroupBy(str, sc);
-        addFilter(str, filter);
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        if (lock != null) {
-            assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction?  Review your db 101 course from college.";
-            str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
-        }
-
-        final String sql = str.toString();
-
-        PreparedStatement pstmt = null;
-        final List<T> result = new ArrayList<T>();
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 1;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(i++, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-
-            if (s_logger.isDebugEnabled() && lock != null) {
-                txn.registerLock(pstmt.toString());
-            }
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(toEntityBean(rs, cache));
-            }
-            return result;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
-        if (sc == null) {
-            throw new CloudRuntimeException("Call to customSearchIncludingRemoved with null search Criteria");
-        }
-        if (sc.isSelectAll()) {
-            return (List<M>)searchIncludingRemoved((SearchCriteria<T>)sc, filter, null, false);
-        }
-        String clause = sc.getWhereClause();
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createPartialSelectSql(sc, clause != null);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        joins = sc.getJoins();
-        if (joins != null) {
-            addJoins(str, joins);
-        }
-
-        List<Object> groupByValues = addGroupBy(str, sc);
-        addFilter(str, filter);
-
-        final String sql = str.toString();
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 1;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(i++, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-
-            ResultSet rs = pstmt.executeQuery();
-            SelectType st = sc.getSelectType();
-            ArrayList<M> results = new ArrayList<M>();
-            List<Field> fields = sc.getSelectFields();
-            while (rs.next()) {
-                if (st == SelectType.Entity) {
-                    results.add((M)toEntityBean(rs, false));
-                } else if (st == SelectType.Fields || st == SelectType.Result) {
-                    M m = sc.getResultType().newInstance();
-                    for (int j = 1; j <= fields.size(); j++) {
-                        setField(m, fields.get(j - 1), rs, j);
-                    }
-                    results.add(m);
-                } else if (st == SelectType.Single) {
-                    results.add(getObject(sc.getResultType(), rs, 1));
-                }
-            }
-
-            return results;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override
-    @DB()
-    public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-
-        return customSearchIncludingRemoved(sc, filter);
-    }
-
-    @DB()
-    protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
-        try {
-            final Class<?> type = field.getType();
-            if (type == String.class) {
-                byte[] bytes = rs.getBytes(index);
-                if (bytes != null) {
-                    try {
-                        Encrypt encrypt = field.getAnnotation(Encrypt.class);
-                        if (encrypt != null && encrypt.encrypt()) {
-                            field.set(entity, DBEncryptionUtil.decrypt(new String(bytes, "UTF-8")));
-                        } else {
-                            field.set(entity, new String(bytes, "UTF-8"));
-                        }
-                    } catch (IllegalArgumentException e) {
-                        assert (false);
-                        throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
-                    } catch (UnsupportedEncodingException e) {
-                        assert (false);
-                        throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
-                    }
-                } else {
-                    field.set(entity, null);
-                }
-            } else if (type == long.class) {
-                field.setLong(entity, rs.getLong(index));
-            } else if (type == Long.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getLong(index));
-                }
-            } else if (type.isEnum()) {
-                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
-                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
-
-                final Enum<?>[] enums = (Enum<?>[])field.getType().getEnumConstants();
-                for (final Enum<?> e : enums) {
-                    if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) ||
-                            (enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) {
-                        field.set(entity, e);
-                        return;
-                    }
-                }
-            } else if (type == int.class) {
-                field.set(entity, rs.getInt(index));
-            } else if (type == Integer.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getInt(index));
-                }
-            } else if (type == Date.class) {
-                final Object data = rs.getDate(index);
-                if (data == null) {
-                    field.set(entity, null);
-                    return;
-                }
-                field.set(entity, DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-            } else if (type == Calendar.class) {
-                final Object data = rs.getDate(index);
-                if (data == null) {
-                    field.set(entity, null);
-                    return;
-                }
-                final Calendar cal = Calendar.getInstance();
-                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-                field.set(entity, cal);
-            } else if (type == boolean.class) {
-                field.setBoolean(entity, rs.getBoolean(index));
-            } else if (type == Boolean.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getBoolean(index));
-                }
-            } else if (type == URI.class) {
-                try {
-                    String str = rs.getString(index);
-                    field.set(entity, str == null ? null : new URI(str));
-                } catch (URISyntaxException e) {
-                    throw new CloudRuntimeException("Invalid URI: " + rs.getString(index), e);
-                }
-            } else if (type == URL.class) {
-                try {
-                    String str = rs.getString(index);
-                    field.set(entity, str != null ? new URL(str) : null);
-                } catch (MalformedURLException e) {
-                    throw new CloudRuntimeException("Invalid URL: " + rs.getString(index), e);
-                }
-            } else if (type == Ip.class) {
-                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
-                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
-
-                Ip ip = null;
-                if (enumType == EnumType.STRING) {
-                    String s = rs.getString(index);
-                    ip = s == null ? null : new Ip(NetUtils.ip2Long(s));
-                } else {
-                    ip = new Ip(rs.getLong(index));
-                }
-                field.set(entity, ip);
-            } else if (type == short.class) {
-                field.setShort(entity, rs.getShort(index));
-            } else if (type == Short.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getShort(index));
-                }
-            } else if (type == float.class) {
-                field.setFloat(entity, rs.getFloat(index));
-            } else if (type == Float.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getFloat(index));
-                }
-            } else if (type == double.class) {
-                field.setDouble(entity, rs.getDouble(index));
-            } else if (type == Double.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getDouble(index));
-                }
-            } else if (type == byte.class) {
-                field.setByte(entity, rs.getByte(index));
-            } else if (type == Byte.class) {
-                if (rs.getObject(index) == null) {
-                    field.set(entity, null);
-                } else {
-                    field.set(entity, rs.getByte(index));
-                }
-            } else if (type == byte[].class) {
-                field.set(entity, rs.getBytes(index));
-            } else {
-                field.set(entity, rs.getObject(index));
-            }
-        } catch (final IllegalAccessException e) {
-            throw new CloudRuntimeException("Yikes! ", e);
-        }
-    }
-
-    /**
-     * Get a value from a result set.
-     *
-     * @param type
-     *            the expected type of the result
-     * @param rs
-     *            the result set
-     * @param index
-     *            the index of the column
-     * @return the result in the requested type
-     * @throws SQLException
-     */
-    @DB()
-    @SuppressWarnings("unchecked")
-    protected static <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
-        if (type == String.class) {
-            byte[] bytes = rs.getBytes(index);
-            if (bytes != null) {
-                try {
-                    return (M)new String(bytes, "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                    throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
-                }
-            } else {
-                return null;
-            }
-        } else if (type == int.class) {
-            return (M) (Integer) rs.getInt(index);
-        } else if (type == Integer.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Integer) rs.getInt(index);
-            }
-        } else if (type == long.class) {
-            return (M) (Long) rs.getLong(index);
-        } else if (type == Long.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Long) rs.getLong(index);
-            }
-        } else if (type == Date.class) {
-            final Object data = rs.getDate(index);
-            if (data == null) {
-                return null;
-            } else {
-                return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index));
-            }
-        } else if (type == short.class) {
-            return (M) (Short) rs.getShort(index);
-        } else if (type == Short.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Short) rs.getShort(index);
-            }
-        } else if (type == boolean.class) {
-            return (M) (Boolean) rs.getBoolean(index);
-        } else if (type == Boolean.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Boolean) rs.getBoolean(index);
-            }
-        } else if (type == float.class) {
-            return (M) (Float) rs.getFloat(index);
-        } else if (type == Float.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Float) rs.getFloat(index);
-            }
-        } else if (type == double.class) {
-            return (M) (Double) rs.getDouble(index);
-        } else if (type == Double.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Double) rs.getDouble(index);
-            }
-        } else if (type == byte.class) {
-            return (M) (Byte) rs.getByte(index);
-        } else if (type == Byte.class) {
-            if (rs.getObject(index) == null) {
-                return null;
-            } else {
-                return (M) (Byte) rs.getByte(index);
-            }
-        } else if (type == Calendar.class) {
-            final Object data = rs.getDate(index);
-            if (data == null) {
-                return null;
-            } else {
-                final Calendar cal = Calendar.getInstance();
-                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
-                return (M)cal;
-            }
-        } else if (type == byte[].class) {
-            return (M)rs.getBytes(index);
-        } else {
-            return (M)rs.getObject(index);
-        }
-    }
-
-    @DB()
-    protected int addJoinAttributes(int count, PreparedStatement pstmt, Collection<JoinBuilder<SearchCriteria<?>>> joins) throws SQLException {
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            for (final Pair<Attribute, Object> value : join.getT().getValues()) {
-                prepareAttribute(count++, pstmt, value.first(), value.second());
-            }
-        }
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            if (join.getT().getJoins() != null) {
-                count = addJoinAttributes(count, pstmt, join.getT().getJoins());
-            }
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("join search statement is " + pstmt);
-        }
-        return count;
-    }
-
-    protected int update(ID id, UpdateBuilder ub, T entity) {
-        if (_cache != null) {
-            _cache.remove(id);
-        }
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        try {
-            if (ub.getCollectionChanges() != null) {
-                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ub.getCollectionChanges());
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("Unable to persist element collection", e);
-        }
-
-        int rowsUpdated = update(ub, sc, null);
-
-        txn.commit();
-
-        return rowsUpdated;
-    }
-
-    public int update(UpdateBuilder ub, final SearchCriteria<?> sc, Integer rows) {
-        StringBuilder sql = null;
-        PreparedStatement pstmt = null;
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            final String searchClause = sc.getWhereClause();
-
-            sql = ub.toSql(_tables);
-            if (sql == null) {
-                return 0;
-            }
-
-            sql.append(searchClause);
-
-            if (rows != null) {
-                sql.append(" LIMIT ").append(rows);
-            }
-
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
-
-            int i = 1;
-            for (final Ternary<Attribute, Boolean, Object> value : changes) {
-                prepareAttribute(i++, pstmt, value.first(), value.third());
-            }
-
-            for (Pair<Attribute, Object> value : sc.getValues()) {
-                prepareAttribute(i++, pstmt, value.first(), value.second());
-            }
-
-            int result = pstmt.executeUpdate();
-            txn.commit();
-            ub.clear();
-            return result;
-        } catch (final SQLException e) {
-            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
-                throw new EntityExistsException("Entity already exists ", e);
-            }
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @DB()
-    protected Attribute findAttributeByFieldName(String name) {
-        return _allAttributes.get(name);
-    }
-
-    @DB()
-    protected String buildSelectByIdSql(final StringBuilder sql) {
-        if (_idField == null) {
-            return null;
-        }
-
-        if (_idField.getAnnotation(EmbeddedId.class) == null) {
-            sql.append(_table).append(".").append(DbUtil.getColumnName(_idField, null)).append(" = ? ");
-        } else {
-            final Class<?> clazz = _idField.getClass();
-            final AttributeOverride[] overrides = DbUtil.getAttributeOverrides(_idField);
-            for (final Field field : clazz.getDeclaredFields()) {
-                sql.append(_table).append(".").append(DbUtil.getColumnName(field, overrides)).append(" = ? AND ");
-            }
-            sql.delete(sql.length() - 4, sql.length());
-        }
-
-        return sql.toString();
-    }
-
-    @DB()
-    @Override
-    public Class<T> getEntityBeanType() {
-        return _entityBeanType;
-    }
-
-    @DB()
-    protected T findOneIncludingRemovedBy(final SearchCriteria<T> sc) {
-        Filter filter = new Filter(1);
-        List<T> results = searchIncludingRemoved(sc, filter, null, false);
-        assert results.size() <= 1 : "Didn't the limiting worked?";
-        return results.size() == 0 ? null : results.get(0);
-    }
-
-    @Override
-    @DB()
-    public T findOneBy(final SearchCriteria<T> sc) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @DB()
-    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return listIncludingRemovedBy(sc, filter);
-    }
-
-    @DB()
-    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
-        if (_removed != null) {
-            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
-        }
-        return listIncludingRemovedBy(sc, filter, enableQueryCache);
-    }
-
-    @DB()
-    protected List<T> listBy(final SearchCriteria<T> sc) {
-        return listBy(sc, null);
-    }
-
-    @DB()
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
-        return searchIncludingRemoved(sc, filter, null, false, enableQueryCache);
-    }
-
-    @DB()
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
-        return searchIncludingRemoved(sc, filter, null, false);
-    }
-
-    @DB()
-    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc) {
-        return listIncludingRemovedBy(sc, null);
-    }
-
-    @Override
-    @DB()
-    @SuppressWarnings("unchecked")
-    public T findById(final ID id) {
-        T result = null;
-        if (_cache != null) {
-            final Element element = _cache.get(id);
-            if (element == null) {
-                result = lockRow(id, null);
-            } else {
-                result = (T)element.getObjectValue();
-            }
-        } else {
-            result = lockRow(id, null);
-        }
-        return result;
-    }
-
-    @Override
-    @DB()
-    public T findByUuid(final String uuid) {
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
-        return findOneBy(sc);
-    }
-
-    @Override
-    @DB()
-    public T findByUuidIncludingRemoved(final String uuid) {
-        SearchCriteria<T> sc = createSearchCriteria();
-        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
-        return findOneIncludingRemovedBy(sc);
-    }
-
-    @Override
-    @DB()
-    public T findByIdIncludingRemoved(final ID id) {
-        T result = null;
-        if (_cache != null) {
-            final Element element = _cache.get(id);
-            if (element == null) {
-                result = findById(id, true, null);
-            } else {
-                result = (T)element.getObjectValue();
-            }
-        } else {
-            result = findById(id, true, null);
-        }
-        return result;
-    }
-
-    @Override
-    @DB()
-    public T findById(final ID id, boolean fresh) {
-        if (!fresh) {
-            return findById(id);
-        }
-
-        if (_cache != null) {
-            _cache.remove(id);
-        }
-        return lockRow(id, null);
-    }
-
-    @Override
-    @DB()
-    public T lockRow(ID id, Boolean lock) {
-        return findById(id, false, lock);
-    }
-
-    protected T findById(ID id, boolean removed, Boolean lock) {
-        StringBuilder sql = new StringBuilder(_selectByIdSql);
-        if (!removed && _removed != null) {
-            sql.append(" AND ").append(_removed.first());
-        }
-        if (lock != null) {
-            sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
-        }
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            if (_idField.getAnnotation(EmbeddedId.class) == null) {
-                prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id);
-            }
-
-            ResultSet rs = pstmt.executeQuery();
-            return rs.next() ? toEntityBean(rs, true) : null;
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @Override
-    @DB()
-    public T acquireInLockTable(ID id) {
-        return acquireInLockTable(id, _timeoutSeconds);
-    }
-
-    @Override
-    public T acquireInLockTable(final ID id, int seconds) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        T t = null;
-        boolean locked = false;
-        try {
-            if (!txn.lock(_table + id.toString(), seconds)) {
-                return null;
-            }
-
-            locked = true;
-            t = findById(id);
-            return t;
-        } finally {
-            if (t == null && locked) {
-                txn.release(_table + id.toString());
-            }
-        }
-    }
-
-    @Override
-    public boolean releaseFromLockTable(final ID id) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        return txn.release(_table + id);
-    }
-
-    @Override
-    @DB()
-    public boolean lockInLockTable(final String id) {
-        return lockInLockTable(id, _timeoutSeconds);
-    }
-
-    @Override
-    public boolean lockInLockTable(final String id, int seconds) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        return txn.lock(_table + id, seconds);
-    }
-
-    @Override
-    public boolean unlockFromLockTable(final String id) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        return txn.release(_table + id);
-    }
-
-    @Override
-    @DB()
-    public List<T> listAllIncludingRemoved() {
-        return listAllIncludingRemoved(null);
-    }
-
-    @DB()
-    protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
-        if (sc == null)
-            return null;
-        Pair<GroupBy<?, ?, ?>, List<Object>> groupBys = sc.getGroupBy();
-        if (groupBys != null) {
-            groupBys.first().toSql(sql);
-            return groupBys.second();
-        } else {
-            return null;
-        }
-    }
-
-    @DB()
-    protected void addFilter(final StringBuilder sql, final Filter filter) {
-        if (filter != null) {
-            if (filter.getOrderBy() != null) {
-                sql.append(filter.getOrderBy());
-            }
-            if (filter.getOffset() != null) {
-                sql.append(" LIMIT ");
-                sql.append(filter.getOffset());
-                if (filter.getLimit() != null) {
-                    sql.append(", ").append(filter.getLimit());
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB()
-    public List<T> listAllIncludingRemoved(final Filter filter) {
-        final StringBuilder sql = createPartialSelectSql(null, false);
-        addFilter(sql, filter);
-
-        return executeList(sql.toString());
-    }
-
-    protected List<T> executeList(final String sql, final Object... params) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        final List<T> result = new ArrayList<T>();
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            for (final Object param : params) {
-                pstmt.setObject(++i, param);
-            }
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                result.add(toEntityBean(rs, true));
-            }
-            return result;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @Override
-    @DB()
-    public List<T> listAll() {
-        return listAll(null);
-    }
-
-    @Override
-    @DB()
-    public List<T> listAll(final Filter filter) {
-        if (_removed == null) {
-            return listAllIncludingRemoved(filter);
-        }
-
-        final StringBuilder sql = createPartialSelectSql(null, true);
-        sql.append(_removed.first());
-        addFilter(sql, filter);
-
-        return executeList(sql.toString());
-    }
-
-    @Override
-    public boolean expunge(final ID id) {
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = null;
-        try {
-            txn.start();
-            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
-                sql = deletSql.first();
-                final Attribute[] attrs = deletSql.second();
-
-                pstmt = txn.prepareAutoCloseStatement(sql);
-
-                for (int i = 0; i < attrs.length; i++) {
-                    prepareAttribute(i + 1, pstmt, attrs[i], id);
-                }
-                pstmt.executeUpdate();
-            }
-
-            txn.commit();
-            if (_cache != null) {
-                _cache.remove(id);
-            }
-            return true;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    // FIXME: Does not work for joins.
-    @Override
-    public int expunge(final SearchCriteria<T> sc) {
-        if (sc == null) {
-            throw new CloudRuntimeException("Call to throw new expunge with null search Criteria");
-        }
-
-        final StringBuilder str = new StringBuilder("DELETE FROM ");
-        str.append(_table);
-        str.append(" WHERE ");
-
-        if (sc != null && sc.getWhereClause().length() > 0) {
-            str.append(sc.getWhereClause());
-        }
-
-        final String sql = str.toString();
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 0;
-            for (final Pair<Attribute, Object> value : sc.getValues()) {
-                prepareAttribute(++i, pstmt, value.first(), value.second());
-            }
-            return pstmt.executeUpdate();
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @DB()
-    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause, final boolean enableQueryCache) {
-        StringBuilder sql = new StringBuilder(enableQueryCache ? _partialQueryCacheSelectSql.first() : _partialSelectSql.first());
-        if (sc != null && !sc.isSelectAll()) {
-            sql.delete(7, sql.indexOf(" FROM"));
-            sc.getSelect(sql, 7);
-        }
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-    @DB()
-    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause) {
-        StringBuilder sql = new StringBuilder(_partialSelectSql.first());
-        if (sc != null && !sc.isSelectAll()) {
-            sql.delete(7, sql.indexOf(" FROM"));
-            sc.getSelect(sql, 7);
-        }
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-    @DB()
-    protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
-        int fromIndex = str.lastIndexOf("WHERE");
-        if (fromIndex == -1) {
-            fromIndex = str.length();
-            str.append(" WHERE ");
-        } else {
-            str.append(" AND ");
-        }
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            StringBuilder onClause = new StringBuilder();
-            onClause.append(" ")
-            .append(join.getType().getName())
-            .append(" ")
-            .append(join.getSecondAttribute().table)
-            .append(" ON ")
-            .append(join.getFirstAttribute().table)
-            .append(".")
-            .append(join.getFirstAttribute().columnName)
-            .append("=")
-            .append(join.getSecondAttribute().table)
-            .append(".")
-            .append(join.getSecondAttribute().columnName)
-            .append(" ");
-            str.insert(fromIndex, onClause);
-            String whereClause = join.getT().getWhereClause();
-            if ((whereClause != null) && !"".equals(whereClause)) {
-                str.append(" (").append(whereClause).append(") AND");
-            }
-            fromIndex += onClause.length();
-        }
-
-        str.delete(str.length() - 4, str.length());
-
-        for (JoinBuilder<SearchCriteria<?>> join : joins) {
-            if (join.getT().getJoins() != null) {
-                addJoins(str, join.getT().getJoins());
-            }
-        }
-    }
-
-    @Override
-    @DB()
-    public List<T> search(final SearchCriteria<T> sc, final Filter filter) {
-        return search(sc, filter, null, false);
-    }
-
-    @Override
-    @DB()
-    public Pair<List<T>, Integer> searchAndCount(final SearchCriteria<T> sc, final Filter filter) {
-        List<T> objects = search(sc, filter, null, false);
-        Integer count = getCount(sc);
-        return new Pair<List<T>, Integer>(objects, count);
-    }
-
-    @Override
-    @DB()
-    public Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter) {
-        List<T> objects = search(sc, filter, null, false);
-        Integer count = getDistinctCount(sc);
-        return new Pair<List<T>, Integer>(objects, count);
-    }
-
-    @Override
-    @DB()
-    public Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter, final String[] distinctColumns) {
-        List<T> objects = search(sc, filter, null, false);
-        Integer count = getDistinctCount(sc, distinctColumns);
-        return new Pair<List<T>, Integer>(objects, count);
-    }
-
-    @Override
-    @DB()
-    public List<T> search(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
-        return search(sc, filter, null, false, enableQueryCache);
-    }
-
-    @Override
-    @DB()
-    public boolean update(ID id, T entity) {
-        assert Enhancer.isEnhanced(entity.getClass()) : "Entity is not generated by this dao";
-
-        UpdateBuilder ub = getUpdateBuilder(entity);
-        boolean result = update(id, ub, entity) != 0;
-        return result;
-    }
-
-    @DB()
-    public int update(final T entity, final SearchCriteria<T> sc, Integer rows) {
-        final UpdateBuilder ub = getUpdateBuilder(entity);
-        return update(ub, sc, rows);
-    }
-
-    @Override
-    @DB()
-    public int update(final T entity, final SearchCriteria<T> sc) {
-        final UpdateBuilder ub = getUpdateBuilder(entity);
-        return update(ub, sc, null);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T persist(final T entity) {
-        if (Enhancer.isEnhanced(entity.getClass())) {
-            if (_idField != null) {
-                ID id;
-                try {
-                    id = (ID)_idField.get(entity);
-                } catch (IllegalAccessException e) {
-                    throw new CloudRuntimeException("How can it be illegal access...come on", e);
-                }
-                update(id, entity);
-                return entity;
-            }
-
-            assert false : "Can't call persit if you don't have primary key";
-        }
-
-        ID id = null;
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        String sql = null;
-        try {
-            txn.start();
-            for (final Pair<String, Attribute[]> pair : _insertSqls) {
-                sql = pair.first();
-                final Attribute[] attrs = pair.second();
-
-                pstmt = txn.prepareAutoCloseStatement(sql, Statement.RETURN_GENERATED_KEYS);
-
-                int index = 1;
-                index = prepareAttributes(pstmt, entity, attrs, index);
-
-                pstmt.executeUpdate();
-
-                final ResultSet rs = pstmt.getGeneratedKeys();
-                if (id == null) {
-                    if (rs != null && rs.next()) {
-                        id = (ID)rs.getObject(1);
-                    }
-                    try {
-                        if (_idField != null) {
-                            if (id != null) {
-                                _idField.set(entity, id);
-                            } else {
-                                id = (ID)_idField.get(entity);
-                            }
-                        }
-                    } catch (final IllegalAccessException e) {
-                        throw new CloudRuntimeException("Yikes! ", e);
-                    }
-                }
-            }
-
-            if (_ecAttributes != null && _ecAttributes.size() > 0) {
-                HashMap<Attribute, Object> ecAttributes = new HashMap<Attribute, Object>();
-                for (Attribute attr : _ecAttributes) {
-                    Object ec = attr.field.get(entity);
-                    if (ec != null) {
-                        ecAttributes.put(attr, ec);
-                    }
-                }
-
-                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ecAttributes);
-            }
-            txn.commit();
-        } catch (final SQLException e) {
-            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
-                throw new EntityExistsException("Entity already exists: ", e);
-            } else {
-                throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-            }
-        } catch (IllegalArgumentException e) {
-            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
-        } catch (IllegalAccessException e) {
-            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
-        }
-
-        return _idField != null ? findByIdIncludingRemoved(id) : null;
-    }
-
-    protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map<Attribute, Object> ecAttributes) throws SQLException {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        for (Map.Entry<Attribute, Object> entry : ecAttributes.entrySet()) {
-            Attribute attr = entry.getKey();
-            Object obj = entry.getValue();
-
-            EcInfo ec = (EcInfo)attr.attache;
-            Enumeration<?> en = null;
-            if (ec.rawClass == null) {
-                en = Collections.enumeration(Arrays.asList((Object[])obj));
-            } else {
-                en = Collections.enumeration((Collection)obj);
-            }
-            PreparedStatement pstmt = txn.prepareAutoCloseStatement(ec.clearSql);
-            prepareAttribute(1, pstmt, idAttribute, id);
-            pstmt.executeUpdate();
-
-            while (en.hasMoreElements()) {
-                pstmt = txn.prepareAutoCloseStatement(ec.insertSql);
-                if (ec.targetClass == Date.class) {
-                    pstmt.setString(1, DateUtil.getDateDisplayString(s_gmtTimeZone, (Date)en.nextElement()));
-                } else {
-                    pstmt.setObject(1, en.nextElement());
-                }
-                prepareAttribute(2, pstmt, idAttribute, id);
-                pstmt.executeUpdate();
-            }
-        }
-        txn.commit();
-    }
-
-    @DB()
-    protected Object generateValue(final Attribute attr) {
-        if (attr.is(Attribute.Flag.Created) || attr.is(Attribute.Flag.Removed)) {
-            return new Date();
-        } else if (attr.is(Attribute.Flag.TableGV)) {
-            return null;
-            // Not sure what to do here.
-        } else if (attr.is(Attribute.Flag.AutoGV)) {
-            if (attr.columnName.equals(GenericDao.XID_COLUMN)) {
-                return UUID.randomUUID().toString();
-            }
-            assert (false) : "Auto generation is not supported.";
-            return null;
-        } else if (attr.is(Attribute.Flag.SequenceGV)) {
-            assert (false) : "Sequence generation is not supported.";
-            return null;
-        } else if (attr.is(Attribute.Flag.DC)) {
-            return _discriminatorValues.get(attr.columnName);
-        } else {
-            assert (false) : "Attribute can't be auto generated: " + attr.columnName;
-            return null;
-        }
-    }
-
-    @DB()
-    protected void prepareAttribute(final int j, final PreparedStatement pstmt, final Attribute attr, Object value) throws SQLException {
-        if (attr.is(Attribute.Flag.DaoGenerated) && value == null) {
-            value = generateValue(attr);
-            if (attr.field == null) {
-                pstmt.setObject(j, value);
-                return;
-            }
-        }
-        if (attr.field.getType() == String.class) {
-            final String str = (String)value;
-            if (str == null) {
-                pstmt.setString(j, null);
-                return;
-            }
-            final Column column = attr.field.getAnnotation(Column.class);
-            final int length = column != null ? column.length() : 255;
-
-            // to support generic localization, utilize MySql UTF-8 support
-            if (length < str.length()) {
-                try {
-                    if (attr.is(Attribute.Flag.Encrypted)) {
-                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, length)).getBytes("UTF-8"));
-                    } else {
-                        pstmt.setBytes(j, str.substring(0, length).getBytes("UTF-8"));
-                    }
-                } catch (UnsupportedEncodingException e) {
-                    // no-way it can't support UTF-8 encoding
-                    assert (false);
-                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
-                }
-            } else {
-                try {
-                    if (attr.is(Attribute.Flag.Encrypted)) {
-                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str).getBytes("UTF-8"));
-                    } else {
-                        pstmt.setBytes(j, str.getBytes("UTF-8"));
-                    }
-                } catch (UnsupportedEncodingException e) {
-                    // no-way it can't support UTF-8 encoding
-                    assert (false);
-                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
-                }
-            }
-        } else if (attr.field.getType() == Date.class) {
-            final Date date = (Date)value;
-            if (date == null || date.equals(DATE_TO_NULL)) {
-                pstmt.setObject(j, null);
-                return;
-            }
-            if (attr.is(Attribute.Flag.Date)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            } else if (attr.is(Attribute.Flag.TimeStamp)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            } else if (attr.is(Attribute.Flag.Time)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
-            }
-        } else if (attr.field.getType() == Calendar.class) {
-            final Calendar cal = (Calendar)value;
-            if (cal == null) {
-                pstmt.setObject(j, null);
-                return;
-            }
-            if (attr.is(Attribute.Flag.Date)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            } else if (attr.is(Attribute.Flag.TimeStamp)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            } else if (attr.is(Attribute.Flag.Time)) {
-                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
-            }
-        } else if (attr.field.getType().isEnum()) {
-            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
-            final EnumType type = (enumerated == null) ? EnumType.STRING : enumerated.value();
-            if (type == EnumType.STRING) {
-                pstmt.setString(j, value == null ? null : value.toString());
-            } else if (type == EnumType.ORDINAL) {
-                if (value == null) {
-                    pstmt.setObject(j, null);
-                } else {
-                    pstmt.setInt(j, ((Enum<?>)value).ordinal());
-                }
-            }
-        } else if (attr.field.getType() == URI.class) {
-            pstmt.setString(j, value == null ? null : value.toString());
-        } else if (attr.field.getType() == URL.class) {
-            pstmt.setURL(j, (URL)value);
-        } else if (attr.field.getType() == byte[].class) {
-            pstmt.setBytes(j, (byte[])value);
-        } else if (attr.field.getType() == Ip.class) {
-            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
-            final EnumType type = (enumerated == null) ? EnumType.ORDINAL : enumerated.value();
-            if (type == EnumType.STRING) {
-                pstmt.setString(j, value == null ? null : value.toString());
-            } else if (type == EnumType.ORDINAL) {
-                if (value == null) {
-                    pstmt.setObject(j, null);
-                } else {
-                    pstmt.setLong(j, (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
-                }
-            }
-        } else {
-            pstmt.setObject(j, value);
-        }
-    }
-
-    @DB()
-    protected int prepareAttributes(final PreparedStatement pstmt, final Object entity, final Attribute[] attrs, final int index) throws SQLException {
-        int j = 0;
-        for (int i = 0; i < attrs.length; i++) {
-            j = i + index;
-            try {
-                prepareAttribute(j, pstmt, attrs[i], attrs[i].field != null ? attrs[i].field.get(entity) : null);
-            } catch (final IllegalArgumentException e) {
-                throw new CloudRuntimeException("IllegalArgumentException", e);
-            } catch (final IllegalAccessException e) {
-                throw new CloudRuntimeException("IllegalArgumentException", e);
-            }
-        }
-
-        return j;
-    }
-
-    @SuppressWarnings("unchecked")
-    @DB()
-    protected T toEntityBean(final ResultSet result, final boolean cache) throws SQLException {
-        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
-
-        toEntityBean(result, entity);
-
-        if (cache && _cache != null) {
-            try {
-                _cache.put(new Element(_idField.get(entity), entity));
-            } catch (final Exception e) {
-                s_logger.debug("Can't put it in the cache", e);
-            }
-        }
-
-        return entity;
-    }
-
-    @DB()
-    protected T toVO(ResultSet result, boolean cache) throws SQLException {
-        T entity;
-        try {
-            entity = _entityBeanType.newInstance();
-        } catch (InstantiationException e1) {
-            throw new CloudRuntimeException("Unable to instantiate entity", e1);
-        } catch (IllegalAccessException e1) {
-            throw new CloudRuntimeException("Illegal Access", e1);
-        }
-        toEntityBean(result, entity);
-        if (cache && _cache != null) {
-            try {
-                _cache.put(new Element(_idField.get(entity), entity));
-            } catch (final Exception e) {
-                s_logger.debug("Can't put it in the cache", e);
-            }
-        }
-
-        return entity;
-    }
-
-    @DB()
-    protected void toEntityBean(final ResultSet result, final T entity) throws SQLException {
-        ResultSetMetaData meta = result.getMetaData();
-        for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
-            setField(entity, result, meta, index);
-        }
-        for (Attribute attr : _ecAttributes) {
-            loadCollection(entity, attr);
-        }
-    }
-
-    @DB()
-    @SuppressWarnings("unchecked")
-    protected void loadCollection(T entity, Attribute attr) {
-        EcInfo ec = (EcInfo)attr.attache;
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try(PreparedStatement pstmt = txn.prepareStatement(ec.selectSql);)
-        {
-            pstmt.setObject(1, _idField.get(entity));
-            try(ResultSet rs = pstmt.executeQuery();)
-            {
-                ArrayList lst = new ArrayList();
-                if (ec.targetClass == Integer.class) {
-                    while (rs.next()) {
-                        lst.add(rs.getInt(1));
-                    }
-                } else if (ec.targetClass == Long.class) {
-                    while (rs.next()) {
-                        lst.add(rs.getLong(1));
-                    }
-                } else if (ec.targetClass == String.class) {
-                    while (rs.next()) {
-                        lst.add(rs.getString(1));
-                    }
-                } else if (ec.targetClass == Short.class) {
-                    while (rs.next()) {
-                        lst.add(rs.getShort(1));
-                    }
-                } else if (ec.targetClass == Date.class) {
-                    while (rs.next()) {
-                        lst.add(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(1)));
-                    }
-                } else if (ec.targetClass == Boolean.class) {
-                    while (rs.next()) {
-                        lst.add(rs.getBoolean(1));
-                    }
-                } else {
-                    assert (false) : "You'll need to add more classeses";
-                }
-                if (ec.rawClass == null) {
-                    Object[] array = (Object[]) Array.newInstance(ec.targetClass);
-                    lst.toArray(array);
-                    try {
-                        attr.field.set(entity, array);
-                    } catch (IllegalArgumentException e) {
-                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                    } catch (IllegalAccessException e) {
-                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                    }
-                } else {
-                    try {
-                        Collection coll = (Collection) ec.rawClass.newInstance();
-                        coll.addAll(lst);
-                        attr.field.set(entity, coll);
-                    } catch (IllegalAccessException e) {
-                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
-                    } catch (InstantiationException e) {
-                        throw new CloudRuntimeException("Never should happen", e);
-                    }
-                }
-            }
-            catch (SQLException e) {
-                throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
-            }
-        } catch (SQLException e) {
-            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
-        } catch (IllegalArgumentException e) {
-            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
-        } catch (IllegalAccessException e) {
-            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void expunge() {
-        if (_removed == null) {
-            return;
-        }
-        final StringBuilder sql = new StringBuilder("DELETE FROM ");
-        sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL");
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(sql.toString());
-
-            pstmt.executeUpdate();
-            txn.commit();
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on " + pstmt, e);
-        }
-    }
-
-    @DB()
-    protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
-        Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
-        if (attr == null) {
-            // work around for mysql bug to return original table name instead of view name in db view case
-            Table tbl = entity.getClass().getSuperclass().getAnnotation(Table.class);
-            if (tbl != null) {
-                attr = _allColumns.get(new Pair<String, String>(tbl.name(), meta.getColumnLabel(index)));
-            }
-        }
-        assert (attr != null) : "How come I can't find " + meta.getCatalogName(index) + "." + meta.getColumnName(index);
-        setField(entity, attr.field, rs, index);
-    }
-
-    @Override
-    public boolean remove(final ID id) {
-        if (_removeSql == null) {
-            return expunge(id);
-        }
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-
-            txn.start();
-            pstmt = txn.prepareAutoCloseStatement(_removeSql.first());
-            final Attribute[] attrs = _removeSql.second();
-            prepareAttribute(1, pstmt, attrs[attrs.length - 1], null);
-            for (int i = 0; i < attrs.length - 1; i++) {
-                prepareAttribute(i + 2, pstmt, attrs[i], id);
-            }
-
-            final int result = pstmt.executeUpdate();
-            txn.commit();
-            if (_cache != null) {
-                _cache.remove(id);
-            }
-            return result > 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        }
-    }
-
-    @Override
-    public int remove(SearchCriteria<T> sc) {
-        if (_removeSql == null) {
-            return expunge(sc);
-        }
-
-        T vo = createForUpdate();
-        UpdateBuilder ub = getUpdateBuilder(vo);
-
-        ub.set(vo, _removed.second(), new Date());
-        return update(ub, sc, null);
-    }
-
-    protected Cache _cache;
-
-    @DB()
-    protected void createCache(final Map<String, ? extends Object> params) {
-        final String value = (String)params.get("cache.size");
-
-        if (value != null) {
-            final CacheManager cm = CacheManager.create();
-            final int maxElements = NumbersUtil.parseInt(value, 0);
-            final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
-            final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
-            _cache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
-            cm.addCache(_cache);
-            s_logger.info("Cache created: " + _cache.toString());
-        } else {
-            _cache = null;
-        }
-    }
-
-    @Override
-    @DB()
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        final String value = (String)params.get("lock.timeout");
-        _timeoutSeconds = NumbersUtil.parseInt(value, 300);
-
-        createCache(params);
-        final boolean load = Boolean.parseBoolean((String)params.get("cache.preload"));
-        if (load) {
-            listAll();
-        }
-
-        return true;
-    }
-
-    @DB()
-    public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
-        final Factory factory = (Factory)entityObject;
-        assert (factory != null);
-        return (UpdateBuilder)factory.getCallback(1);
-    }
-
-    @Override
-    @DB()
-    public SearchBuilder<T> createSearchBuilder() {
-        return new SearchBuilder<T>(_entityBeanType);
-    }
-
-    @Override
-    @DB()
-    public SearchCriteria<T> createSearchCriteria() {
-        SearchBuilder<T> builder = createSearchBuilder();
-        return builder.create();
-    }
-
-    public Integer getDistinctCount(SearchCriteria<T> sc) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createDistinctIdSelect(sc, clause != null);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        // we have to disable group by in getting count, since count for groupBy clause will be different.
-        //List<Object> groupByValues = addGroupBy(str, sc);
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        final String sql = "SELECT COUNT(*) FROM (" + str.toString() + ") AS tmp";
-
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 1;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(i++, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            /*
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-             */
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                return rs.getInt(1);
-            }
-            return 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    public Integer getDistinctCount(SearchCriteria<T> sc, String[] distinctColumns) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (Strings.isNullOrEmpty(clause)) {
-            clause = null;
-        }
-
-        final StringBuilder str = createDistinctSelect(sc, clause != null, distinctColumns);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        final String sql = "SELECT COUNT(*) FROM (" + str.toString() + ") AS tmp";
-
-        try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql)) {
-            int i = 1;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(i++, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                return rs.getInt(1);
-            }
-            return 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception in executing: " + sql, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught exception in : " + sql, e);
-        }
-    }
-
-    public Integer getCount(SearchCriteria<T> sc) {
-        String clause = sc != null ? sc.getWhereClause() : null;
-        if (clause != null && clause.length() == 0) {
-            clause = null;
-        }
-
-        final StringBuilder str = createCountSelect(sc, clause != null);
-        if (clause != null) {
-            str.append(clause);
-        }
-
-        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
-        if (sc != null) {
-            joins = sc.getJoins();
-            if (joins != null) {
-                addJoins(str, joins);
-            }
-        }
-
-        // we have to disable group by in getting count, since count for groupBy clause will be different.
-        //List<Object> groupByValues = addGroupBy(str, sc);
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        final String sql = str.toString();
-
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            int i = 1;
-            if (clause != null) {
-                for (final Pair<Attribute, Object> value : sc.getValues()) {
-                    prepareAttribute(i++, pstmt, value.first(), value.second());
-                }
-            }
-
-            if (joins != null) {
-                i = addJoinAttributes(i, pstmt, joins);
-            }
-
-            /*
-            if (groupByValues != null) {
-                for (Object value : groupByValues) {
-                    pstmt.setObject(i++, value);
-                }
-            }
-             */
-
-            final ResultSet rs = pstmt.executeQuery();
-            while (rs.next()) {
-                return rs.getInt(1);
-            }
-            return 0;
-        } catch (final SQLException e) {
-            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
-        } catch (final Throwable e) {
-            throw new CloudRuntimeException("Caught: " + pstmt, e);
-        }
-    }
-
-    @DB()
-    protected StringBuilder createCountSelect(SearchCriteria<?> sc, final boolean whereClause) {
-        StringBuilder sql = new StringBuilder(_count);
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-    @DB()
-    protected StringBuilder createDistinctIdSelect(SearchCriteria<?> sc, final boolean whereClause) {
-        StringBuilder sql = new StringBuilder(_distinctIdSql);
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-
-    @DB()
-    protected Pair<List<T>, Integer> listAndCountIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
-        List<T> objects = searchIncludingRemoved(sc, filter, null, false);
-        Integer count = getCount(sc);
-        return new Pair<List<T>, Integer>(objects, count);
-    }
-
-    @DB()
-    protected StringBuilder createDistinctSelect(SearchCriteria<?> sc, final boolean whereClause, String[] distinctColumns) {
-        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
-        String distinctSql = generator.buildDistinctSql(distinctColumns);
-
-        StringBuilder sql = new StringBuilder(distinctSql);
-
-        if (!whereClause) {
-            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
-        }
-
-        return sql;
-    }
-}
diff --git a/framework/db/src/com/cloud/dao/EntityManagerImpl.java b/framework/db/src/main/java/com/cloud/dao/EntityManagerImpl.java
similarity index 100%
rename from framework/db/src/com/cloud/dao/EntityManagerImpl.java
rename to framework/db/src/main/java/com/cloud/dao/EntityManagerImpl.java
diff --git a/framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
rename to framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java
diff --git a/framework/db/src/com/cloud/utils/db/Attribute.java b/framework/db/src/main/java/com/cloud/utils/db/Attribute.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/Attribute.java
rename to framework/db/src/main/java/com/cloud/utils/db/Attribute.java
diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConcierge.java b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/ConnectionConcierge.java
rename to framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
diff --git a/framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConciergeMBean.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/ConnectionConciergeMBean.java
rename to framework/db/src/main/java/com/cloud/utils/db/ConnectionConciergeMBean.java
diff --git a/framework/db/src/com/cloud/utils/db/DB.java b/framework/db/src/main/java/com/cloud/utils/db/DB.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/DB.java
rename to framework/db/src/main/java/com/cloud/utils/db/DB.java
diff --git a/framework/db/src/com/cloud/utils/db/DbUtil.java b/framework/db/src/main/java/com/cloud/utils/db/DbUtil.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/DbUtil.java
rename to framework/db/src/main/java/com/cloud/utils/db/DbUtil.java
diff --git a/framework/db/src/com/cloud/utils/db/DriverLoader.java b/framework/db/src/main/java/com/cloud/utils/db/DriverLoader.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/DriverLoader.java
rename to framework/db/src/main/java/com/cloud/utils/db/DriverLoader.java
diff --git a/framework/db/src/com/cloud/utils/db/EcInfo.java b/framework/db/src/main/java/com/cloud/utils/db/EcInfo.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/EcInfo.java
rename to framework/db/src/main/java/com/cloud/utils/db/EcInfo.java
diff --git a/framework/db/src/com/cloud/utils/db/Encrypt.java b/framework/db/src/main/java/com/cloud/utils/db/Encrypt.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/Encrypt.java
rename to framework/db/src/main/java/com/cloud/utils/db/Encrypt.java
diff --git a/framework/db/src/com/cloud/utils/db/Filter.java b/framework/db/src/main/java/com/cloud/utils/db/Filter.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/Filter.java
rename to framework/db/src/main/java/com/cloud/utils/db/Filter.java
diff --git a/framework/db/src/com/cloud/utils/db/GenericDao.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/GenericDao.java
rename to framework/db/src/main/java/com/cloud/utils/db/GenericDao.java
diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
new file mode 100644
index 0000000..442d3cc
--- /dev/null
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
@@ -0,0 +1,2098 @@
+// 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
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.db;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import com.google.common.base.Strings;
+import javax.naming.ConfigurationException;
+import javax.persistence.AttributeOverride;
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.NoOp;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ComponentLifecycleBase;
+import com.cloud.utils.component.ComponentMethodInterceptable;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.SearchCriteria.SelectType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+
+/**
+ *  GenericDaoBase is a simple way to implement DAOs.  It DOES NOT
+ *  support the full EJB3 spec.  It borrows some of the annotations from
+ *  the EJB3 spec to produce a set of SQLs so developers don't have to
+ *  copy and paste the same code over and over again.  Of course,
+ *  GenericDaoBase is completely at the mercy of the annotations you add
+ *  to your entity bean.  If GenericDaoBase does not fit your needs, then
+ *  don't extend from it.
+ *
+ *  GenericDaoBase attempts to achieve the following:
+ *    1. If you use _allFieldsStr in your SQL statement and use to() to convert
+ *       the result to the entity bean, you don't ever have to worry about
+ *       missing fields because its automatically taken from the entity bean's
+ *       annotations.
+ *    2. You don't have to rewrite the same insert and select query strings
+ *       in all of your DAOs.
+ *    3. You don't have to match the '?' (you know what I'm talking about) to
+ *       the fields in the insert statement as that's taken care of for you.
+ *
+ *  GenericDaoBase looks at the following annotations:
+ *    1. Table - just name
+ *    2. Column - just name
+ *    3. GeneratedValue - any field with this annotation is not inserted.
+ *    4. SequenceGenerator - sequence generator
+ *    5. Id
+ *    6. SecondaryTable
+ *
+ *  Sometime later, I might look into injecting the SQLs as needed but right
+ *  now we have to construct them at construction time.  The good thing is that
+ *  the DAOs are suppose to be one per jvm so the time is all during the
+ *  initial load.
+ *
+ **/
+@DB
+public abstract class GenericDaoBase<T, ID extends Serializable> extends ComponentLifecycleBase implements GenericDao<T, ID>, ComponentMethodInterceptable {
+    private final static Logger s_logger = Logger.getLogger(GenericDaoBase.class);
+
+    protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
+
+    protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
+
+    protected Class<T> _entityBeanType;
+    protected String _table;
+
+    protected String _tables;
+
+    protected Field[] _embeddedFields;
+
+    // This is private on purpose.  Everyone should use createPartialSelectSql()
+    private final Pair<StringBuilder, Attribute[]> _partialSelectSql;
+    private final Pair<StringBuilder, Attribute[]> _partialQueryCacheSelectSql;
+    protected StringBuilder _discriminatorClause;
+    protected Map<String, Object> _discriminatorValues;
+    protected String _selectByIdSql;
+    protected String _count;
+    protected String _distinctIdSql;
+
+    protected Field _idField;
+
+    protected List<Pair<String, Attribute[]>> _insertSqls;
+    protected Pair<String, Attribute> _removed;
+    protected Pair<String, Attribute[]> _removeSql;
+    protected List<Pair<String, Attribute[]>> _deleteSqls;
+    protected Map<String, Attribute[]> _idAttributes;
+    protected Map<String, TableGenerator> _tgs;
+    protected Map<String, Attribute> _allAttributes;
+    protected List<Attribute> _ecAttributes;
+    protected Map<Pair<String, String>, Attribute> _allColumns;
+    protected Enhancer _enhancer;
+    protected Factory _factory;
+    protected Enhancer _searchEnhancer;
+    protected int _timeoutSeconds;
+
+    protected final static CallbackFilter s_callbackFilter = new UpdateFilter();
+
+    protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE ";
+    protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE";
+    protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
+    public static final Date DATE_TO_NULL = new Date(Long.MIN_VALUE);
+
+    protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
+
+    public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
+        @SuppressWarnings("unchecked")
+        GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
+        assert dao != null : "Unable to find DAO for " + entityType + ".  Are you sure you waited for the DAO to be initialized before asking for it?";
+        return dao;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    @DB()
+    public <J> GenericSearchBuilder<T, J> createSearchBuilder(Class<J> resultType) {
+        return new GenericSearchBuilder<T, J>(_entityBeanType, resultType);
+    }
+
+    @Override
+    public Map<String, Attribute> getAllAttributes() {
+        return _allAttributes;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T createSearchEntity(MethodInterceptor interceptor) {
+        T entity = (T)_searchEnhancer.create();
+        final Factory factory = (Factory)entity;
+        factory.setCallback(0, interceptor);
+        return entity;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected GenericDaoBase() {
+        super();
+        Type t = getClass().getGenericSuperclass();
+        if (t instanceof ParameterizedType) {
+            _entityBeanType = (Class<T>)((ParameterizedType)t).getActualTypeArguments()[0];
+        } else if (((Class<?>)t).getGenericSuperclass() instanceof ParameterizedType) {
+            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)t).getGenericSuperclass()).getActualTypeArguments()[0];
+        } else {
+            _entityBeanType = (Class<T>)((ParameterizedType)((Class<?>)((Class<?>)t).getGenericSuperclass()).getGenericSuperclass()).getActualTypeArguments()[0];
+        }
+
+        s_daoMaps.put(_entityBeanType, this);
+        Class<?>[] interphaces = _entityBeanType.getInterfaces();
+        if (interphaces != null) {
+            for (Class<?> interphace : interphaces) {
+                s_daoMaps.put(interphace, this);
+            }
+        }
+
+        _table = DbUtil.getTableName(_entityBeanType);
+
+        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
+        _partialSelectSql = generator.buildSelectSql(false);
+        _count = generator.buildCountSql();
+        _distinctIdSql= generator.buildDistinctIdSql();
+        _partialQueryCacheSelectSql = generator.buildSelectSql(true);
+        _embeddedFields = generator.getEmbeddedFields();
+        _insertSqls = generator.buildInsertSqls();
+        final Pair<StringBuilder, Map<String, Object>> dc = generator.buildDiscriminatorClause();
+        _discriminatorClause = dc.first().length() == 0 ? null : dc.first();
+        _discriminatorValues = dc.second();
+
+        _idAttributes = generator.getIdAttributes();
+        _idField = _idAttributes.get(_table).length > 0 ? _idAttributes.get(_table)[0].field : null;
+
+        _tables = generator.buildTableReferences();
+
+        _allAttributes = generator.getAllAttributes();
+        _allColumns = generator.getAllColumns();
+
+        _selectByIdSql = buildSelectByIdSql(createPartialSelectSql(null, true));
+        _removeSql = generator.buildRemoveSql();
+        _deleteSqls = generator.buildDeleteSqls();
+        _removed = generator.getRemovedAttribute();
+        _tgs = generator.getTableGenerators();
+        _ecAttributes = generator.getElementCollectionAttributes();
+
+        TableGenerator tg = this.getClass().getAnnotation(TableGenerator.class);
+        if (tg != null) {
+            _tgs.put(tg.name(), tg);
+        }
+        tg = this.getClass().getSuperclass().getAnnotation(TableGenerator.class);
+        if (tg != null) {
+            _tgs.put(tg.name(), tg);
+        }
+
+        Callback[] callbacks = new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)};
+
+        _enhancer = new Enhancer();
+        _enhancer.setSuperclass(_entityBeanType);
+        _enhancer.setCallbackFilter(s_callbackFilter);
+        _enhancer.setCallbacks(callbacks);
+        _factory = (Factory)_enhancer.create();
+
+        _searchEnhancer = new Enhancer();
+        _searchEnhancer.setSuperclass(_entityBeanType);
+        _searchEnhancer.setCallback(new UpdateBuilder(this));
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Select SQL: " + _partialSelectSql.first().toString());
+            s_logger.trace("Remove SQL: " + (_removeSql != null ? _removeSql.first() : "No remove sql"));
+            s_logger.trace("Select by Id SQL: " + _selectByIdSql);
+            s_logger.trace("Table References: " + _tables);
+            s_logger.trace("Insert SQLs:");
+            for (final Pair<String, Attribute[]> insertSql : _insertSqls) {
+                s_logger.trace(insertSql.first());
+            }
+
+            s_logger.trace("Delete SQLs");
+            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
+                s_logger.trace(deletSql.first());
+            }
+
+            s_logger.trace("Collection SQLs");
+            for (Attribute attr : _ecAttributes) {
+                EcInfo info = (EcInfo)attr.attache;
+                s_logger.trace(info.insertSql);
+                s_logger.trace(info.selectSql);
+            }
+        }
+
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_SYSTEM);
+    }
+
+    @Override
+    @DB()
+    @SuppressWarnings("unchecked")
+    public T createForUpdate(final ID id) {
+        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
+        if (id != null) {
+            try {
+                _idField.set(entity, id);
+            } catch (final IllegalArgumentException e) {
+            } catch (final IllegalAccessException e) {
+            }
+        }
+        return entity;
+    }
+
+    @Override
+    @DB()
+    public T createForUpdate() {
+        return createForUpdate(null);
+    }
+
+    @Override
+    @DB()
+    public <K> K getNextInSequence(final Class<K> clazz, final String name) {
+        final TableGenerator tg = _tgs.get(name);
+        assert (tg != null) : "Couldn't find Table generator using " + name;
+
+        return s_seqFetcher.getNextSequence(clazz, tg);
+    }
+
+    @Override
+    @DB()
+    public <K> K getRandomlyIncreasingNextInSequence(final Class<K> clazz, final String name) {
+        final TableGenerator tg = _tgs.get(name);
+        assert (tg != null) : "Couldn't find Table generator using " + name;
+
+        return s_seqFetcher.getRandomNextSequence(clazz, tg);
+    }
+
+    @Override
+    @DB()
+    public List<T> lockRows(final SearchCriteria<T> sc, final Filter filter, final boolean exclusive) {
+        return search(sc, filter, exclusive, false);
+    }
+
+    @Override
+    @DB()
+    public T lockOneRandomRow(final SearchCriteria<T> sc, final boolean exclusive) {
+        final Filter filter = new Filter(1);
+        final List<T> beans = search(sc, filter, exclusive, true);
+        return beans.isEmpty() ? null : beans.get(0);
+    }
+
+    @DB()
+    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
+        if (_removed != null) {
+            if (sc == null) {
+                sc = createSearchCriteria();
+            }
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return searchIncludingRemoved(sc, filter, lock, cache);
+    }
+
+    @DB()
+    protected List<T> search(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enableQueryCache) {
+        if (_removed != null) {
+            if (sc == null) {
+                sc = createSearchCriteria();
+            }
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return searchIncludingRemoved(sc, filter, lock, cache, enableQueryCache);
+    }
+
+    @Override
+    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache) {
+        return searchIncludingRemoved(sc, filter, lock, cache, false);
+    }
+
+    @Override
+    public List<T> searchIncludingRemoved(SearchCriteria<T> sc, final Filter filter, final Boolean lock, final boolean cache, final boolean enableQueryCache) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createPartialSelectSql(sc, clause != null, enableQueryCache);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        List<Object> groupByValues = addGroupBy(str, sc);
+        addFilter(str, filter);
+
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        if (lock != null) {
+            assert (txn.dbTxnStarted() == true) : "As nice as I can here now....how do you lock when there's no DB transaction?  Review your db 101 course from college.";
+            str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
+        }
+
+        final String sql = str.toString();
+
+        PreparedStatement pstmt = null;
+        final List<T> result = new ArrayList<T>();
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 1;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(i++, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+
+            if (s_logger.isDebugEnabled() && lock != null) {
+                txn.registerLock(pstmt.toString());
+            }
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(toEntityBean(rs, cache));
+            }
+            return result;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <M> List<M> customSearchIncludingRemoved(SearchCriteria<M> sc, final Filter filter) {
+        if (sc == null) {
+            throw new CloudRuntimeException("Call to customSearchIncludingRemoved with null search Criteria");
+        }
+        if (sc.isSelectAll()) {
+            return (List<M>)searchIncludingRemoved((SearchCriteria<T>)sc, filter, null, false);
+        }
+        String clause = sc.getWhereClause();
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createPartialSelectSql(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        joins = sc.getJoins();
+        if (joins != null) {
+            addJoins(str, joins);
+        }
+
+        List<Object> groupByValues = addGroupBy(str, sc);
+        addFilter(str, filter);
+
+        final String sql = str.toString();
+
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 1;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(i++, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+
+            ResultSet rs = pstmt.executeQuery();
+            SelectType st = sc.getSelectType();
+            ArrayList<M> results = new ArrayList<M>();
+            List<Field> fields = sc.getSelectFields();
+            while (rs.next()) {
+                if (st == SelectType.Entity) {
+                    results.add((M)toEntityBean(rs, false));
+                } else if (st == SelectType.Fields || st == SelectType.Result) {
+                    M m = sc.getResultType().newInstance();
+                    for (int j = 1; j <= fields.size(); j++) {
+                        setField(m, fields.get(j - 1), rs, j);
+                    }
+                    results.add(m);
+                } else if (st == SelectType.Single) {
+                    results.add(getObject(sc.getResultType(), rs, 1));
+                }
+            }
+
+            return results;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override
+    @DB()
+    public <M> List<M> customSearch(SearchCriteria<M> sc, final Filter filter) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+
+        return customSearchIncludingRemoved(sc, filter);
+    }
+
+    @DB()
+    protected void setField(Object entity, Field field, ResultSet rs, int index) throws SQLException {
+        try {
+            final Class<?> type = field.getType();
+            if (type == String.class) {
+                byte[] bytes = rs.getBytes(index);
+                if (bytes != null) {
+                    try {
+                        Encrypt encrypt = field.getAnnotation(Encrypt.class);
+                        if (encrypt != null && encrypt.encrypt()) {
+                            field.set(entity, DBEncryptionUtil.decrypt(new String(bytes, "UTF-8")));
+                        } else {
+                            field.set(entity, new String(bytes, "UTF-8"));
+                        }
+                    } catch (IllegalArgumentException e) {
+                        assert (false);
+                        throw new CloudRuntimeException("IllegalArgumentException when converting UTF-8 data");
+                    } catch (UnsupportedEncodingException e) {
+                        assert (false);
+                        throw new CloudRuntimeException("UnsupportedEncodingException when converting UTF-8 data");
+                    }
+                } else {
+                    field.set(entity, null);
+                }
+            } else if (type == long.class) {
+                field.setLong(entity, rs.getLong(index));
+            } else if (type == Long.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getLong(index));
+                }
+            } else if (type.isEnum()) {
+                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
+                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
+
+                final Enum<?>[] enums = (Enum<?>[])field.getType().getEnumConstants();
+                for (final Enum<?> e : enums) {
+                    if ((enumType == EnumType.STRING && e.name().equalsIgnoreCase(rs.getString(index))) ||
+                            (enumType == EnumType.ORDINAL && e.ordinal() == rs.getInt(index))) {
+                        field.set(entity, e);
+                        return;
+                    }
+                }
+            } else if (type == int.class) {
+                field.set(entity, rs.getInt(index));
+            } else if (type == Integer.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getInt(index));
+                }
+            } else if (type == Date.class) {
+                final Object data = rs.getDate(index);
+                if (data == null) {
+                    field.set(entity, null);
+                    return;
+                }
+                field.set(entity, DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+            } else if (type == Calendar.class) {
+                final Object data = rs.getDate(index);
+                if (data == null) {
+                    field.set(entity, null);
+                    return;
+                }
+                final Calendar cal = Calendar.getInstance();
+                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+                field.set(entity, cal);
+            } else if (type == boolean.class) {
+                field.setBoolean(entity, rs.getBoolean(index));
+            } else if (type == Boolean.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getBoolean(index));
+                }
+            } else if (type == URI.class) {
+                try {
+                    String str = rs.getString(index);
+                    field.set(entity, str == null ? null : new URI(str));
+                } catch (URISyntaxException e) {
+                    throw new CloudRuntimeException("Invalid URI: " + rs.getString(index), e);
+                }
+            } else if (type == URL.class) {
+                try {
+                    String str = rs.getString(index);
+                    field.set(entity, str != null ? new URL(str) : null);
+                } catch (MalformedURLException e) {
+                    throw new CloudRuntimeException("Invalid URL: " + rs.getString(index), e);
+                }
+            } else if (type == Ip.class) {
+                final Enumerated enumerated = field.getAnnotation(Enumerated.class);
+                final EnumType enumType = (enumerated == null) ? EnumType.STRING : enumerated.value();
+
+                Ip ip = null;
+                if (enumType == EnumType.STRING) {
+                    String s = rs.getString(index);
+                    ip = s == null ? null : new Ip(NetUtils.ip2Long(s));
+                } else {
+                    ip = new Ip(rs.getLong(index));
+                }
+                field.set(entity, ip);
+            } else if (type == short.class) {
+                field.setShort(entity, rs.getShort(index));
+            } else if (type == Short.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getShort(index));
+                }
+            } else if (type == float.class) {
+                field.setFloat(entity, rs.getFloat(index));
+            } else if (type == Float.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getFloat(index));
+                }
+            } else if (type == double.class) {
+                field.setDouble(entity, rs.getDouble(index));
+            } else if (type == Double.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getDouble(index));
+                }
+            } else if (type == byte.class) {
+                field.setByte(entity, rs.getByte(index));
+            } else if (type == Byte.class) {
+                if (rs.getObject(index) == null) {
+                    field.set(entity, null);
+                } else {
+                    field.set(entity, rs.getByte(index));
+                }
+            } else if (type == byte[].class) {
+                field.set(entity, rs.getBytes(index));
+            } else {
+                field.set(entity, rs.getObject(index));
+            }
+        } catch (final IllegalAccessException e) {
+            throw new CloudRuntimeException("Yikes! ", e);
+        }
+    }
+
+    /**
+     * Get a value from a result set.
+     *
+     * @param type
+     *            the expected type of the result
+     * @param rs
+     *            the result set
+     * @param index
+     *            the index of the column
+     * @return the result in the requested type
+     * @throws SQLException
+     */
+    @DB()
+    @SuppressWarnings("unchecked")
+    protected static <M> M getObject(Class<M> type, ResultSet rs, int index) throws SQLException {
+        if (type == String.class) {
+            byte[] bytes = rs.getBytes(index);
+            if (bytes != null) {
+                try {
+                    return (M)new String(bytes, "UTF-8");
+                } catch (UnsupportedEncodingException e) {
+                    throw new CloudRuntimeException("UnsupportedEncodingException exception while converting UTF-8 data");
+                }
+            } else {
+                return null;
+            }
+        } else if (type == int.class) {
+            return (M) (Integer) rs.getInt(index);
+        } else if (type == Integer.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Integer) rs.getInt(index);
+            }
+        } else if (type == long.class) {
+            return (M) (Long) rs.getLong(index);
+        } else if (type == Long.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Long) rs.getLong(index);
+            }
+        } else if (type == Date.class) {
+            final Object data = rs.getDate(index);
+            if (data == null) {
+                return null;
+            } else {
+                return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index));
+            }
+        } else if (type == short.class) {
+            return (M) (Short) rs.getShort(index);
+        } else if (type == Short.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Short) rs.getShort(index);
+            }
+        } else if (type == boolean.class) {
+            return (M) (Boolean) rs.getBoolean(index);
+        } else if (type == Boolean.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Boolean) rs.getBoolean(index);
+            }
+        } else if (type == float.class) {
+            return (M) (Float) rs.getFloat(index);
+        } else if (type == Float.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Float) rs.getFloat(index);
+            }
+        } else if (type == double.class) {
+            return (M) (Double) rs.getDouble(index);
+        } else if (type == Double.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Double) rs.getDouble(index);
+            }
+        } else if (type == byte.class) {
+            return (M) (Byte) rs.getByte(index);
+        } else if (type == Byte.class) {
+            if (rs.getObject(index) == null) {
+                return null;
+            } else {
+                return (M) (Byte) rs.getByte(index);
+            }
+        } else if (type == Calendar.class) {
+            final Object data = rs.getDate(index);
+            if (data == null) {
+                return null;
+            } else {
+                final Calendar cal = Calendar.getInstance();
+                cal.setTime(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)));
+                return (M)cal;
+            }
+        } else if (type == byte[].class) {
+            return (M)rs.getBytes(index);
+        } else {
+            return (M)rs.getObject(index);
+        }
+    }
+
+    @DB()
+    protected int addJoinAttributes(int count, PreparedStatement pstmt, Collection<JoinBuilder<SearchCriteria<?>>> joins) throws SQLException {
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            for (final Pair<Attribute, Object> value : join.getT().getValues()) {
+                prepareAttribute(count++, pstmt, value.first(), value.second());
+            }
+        }
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            if (join.getT().getJoins() != null) {
+                count = addJoinAttributes(count, pstmt, join.getT().getJoins());
+            }
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("join search statement is " + pstmt);
+        }
+        return count;
+    }
+
+    protected int update(ID id, UpdateBuilder ub, T entity) {
+        if (_cache != null) {
+            _cache.remove(id);
+        }
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd(_idAttributes.get(_table)[0], SearchCriteria.Op.EQ, id);
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        try {
+            if (ub.getCollectionChanges() != null) {
+                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ub.getCollectionChanges());
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to persist element collection", e);
+        }
+
+        int rowsUpdated = update(ub, sc, null);
+
+        txn.commit();
+
+        return rowsUpdated;
+    }
+
+    public int update(UpdateBuilder ub, final SearchCriteria<?> sc, Integer rows) {
+        StringBuilder sql = null;
+        PreparedStatement pstmt = null;
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            final String searchClause = sc.getWhereClause();
+
+            sql = ub.toSql(_tables);
+            if (sql == null) {
+                return 0;
+            }
+
+            sql.append(searchClause);
+
+            if (rows != null) {
+                sql.append(" LIMIT ").append(rows);
+            }
+
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            Collection<Ternary<Attribute, Boolean, Object>> changes = ub.getChanges();
+
+            int i = 1;
+            for (final Ternary<Attribute, Boolean, Object> value : changes) {
+                prepareAttribute(i++, pstmt, value.first(), value.third());
+            }
+
+            for (Pair<Attribute, Object> value : sc.getValues()) {
+                prepareAttribute(i++, pstmt, value.first(), value.second());
+            }
+
+            int result = pstmt.executeUpdate();
+            txn.commit();
+            ub.clear();
+            return result;
+        } catch (final SQLException e) {
+            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
+                throw new EntityExistsException("Entity already exists ", e);
+            }
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @DB()
+    protected Attribute findAttributeByFieldName(String name) {
+        return _allAttributes.get(name);
+    }
+
+    @DB()
+    protected String buildSelectByIdSql(final StringBuilder sql) {
+        if (_idField == null) {
+            return null;
+        }
+
+        if (_idField.getAnnotation(EmbeddedId.class) == null) {
+            sql.append(_table).append(".").append(DbUtil.getColumnName(_idField, null)).append(" = ? ");
+        } else {
+            final Class<?> clazz = _idField.getClass();
+            final AttributeOverride[] overrides = DbUtil.getAttributeOverrides(_idField);
+            for (final Field field : clazz.getDeclaredFields()) {
+                sql.append(_table).append(".").append(DbUtil.getColumnName(field, overrides)).append(" = ? AND ");
+            }
+            sql.delete(sql.length() - 4, sql.length());
+        }
+
+        return sql.toString();
+    }
+
+    @DB()
+    @Override
+    public Class<T> getEntityBeanType() {
+        return _entityBeanType;
+    }
+
+    @DB()
+    protected T findOneIncludingRemovedBy(final SearchCriteria<T> sc) {
+        Filter filter = new Filter(1);
+        List<T> results = searchIncludingRemoved(sc, filter, null, false);
+        assert results.size() <= 1 : "Didn't the limiting worked?";
+        return results.size() == 0 ? null : results.get(0);
+    }
+
+    @Override
+    @DB()
+    public T findOneBy(final SearchCriteria<T> sc) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @DB()
+    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return listIncludingRemovedBy(sc, filter);
+    }
+
+    @DB()
+    protected List<T> listBy(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
+        if (_removed != null) {
+            sc.addAnd(_removed.second().field.getName(), SearchCriteria.Op.NULL);
+        }
+        return listIncludingRemovedBy(sc, filter, enableQueryCache);
+    }
+
+    @DB()
+    protected List<T> listBy(final SearchCriteria<T> sc) {
+        return listBy(sc, null);
+    }
+
+    @DB()
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
+        return searchIncludingRemoved(sc, filter, null, false, enableQueryCache);
+    }
+
+    @DB()
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
+        return searchIncludingRemoved(sc, filter, null, false);
+    }
+
+    @DB()
+    protected List<T> listIncludingRemovedBy(final SearchCriteria<T> sc) {
+        return listIncludingRemovedBy(sc, null);
+    }
+
+    @Override
+    @DB()
+    @SuppressWarnings("unchecked")
+    public T findById(final ID id) {
+        T result = null;
+        if (_cache != null) {
+            final Element element = _cache.get(id);
+            if (element == null) {
+                result = lockRow(id, null);
+            } else {
+                result = (T)element.getObjectValue();
+            }
+        } else {
+            result = lockRow(id, null);
+        }
+        return result;
+    }
+
+    @Override
+    @DB()
+    public T findByUuid(final String uuid) {
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
+        return findOneBy(sc);
+    }
+
+    @Override
+    @DB()
+    public T findByUuidIncludingRemoved(final String uuid) {
+        SearchCriteria<T> sc = createSearchCriteria();
+        sc.addAnd("uuid", SearchCriteria.Op.EQ, uuid);
+        return findOneIncludingRemovedBy(sc);
+    }
+
+    @Override
+    @DB()
+    public T findByIdIncludingRemoved(final ID id) {
+        T result = null;
+        if (_cache != null) {
+            final Element element = _cache.get(id);
+            if (element == null) {
+                result = findById(id, true, null);
+            } else {
+                result = (T)element.getObjectValue();
+            }
+        } else {
+            result = findById(id, true, null);
+        }
+        return result;
+    }
+
+    @Override
+    @DB()
+    public T findById(final ID id, boolean fresh) {
+        if (!fresh) {
+            return findById(id);
+        }
+
+        if (_cache != null) {
+            _cache.remove(id);
+        }
+        return lockRow(id, null);
+    }
+
+    @Override
+    @DB()
+    public T lockRow(ID id, Boolean lock) {
+        return findById(id, false, lock);
+    }
+
+    protected T findById(ID id, boolean removed, Boolean lock) {
+        StringBuilder sql = new StringBuilder(_selectByIdSql);
+        if (!removed && _removed != null) {
+            sql.append(" AND ").append(_removed.first());
+        }
+        if (lock != null) {
+            sql.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
+        }
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            if (_idField.getAnnotation(EmbeddedId.class) == null) {
+                prepareAttribute(1, pstmt, _idAttributes.get(_table)[0], id);
+            }
+
+            ResultSet rs = pstmt.executeQuery();
+            return rs.next() ? toEntityBean(rs, true) : null;
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @Override
+    @DB()
+    public T acquireInLockTable(ID id) {
+        return acquireInLockTable(id, _timeoutSeconds);
+    }
+
+    @Override
+    public T acquireInLockTable(final ID id, int seconds) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        T t = null;
+        boolean locked = false;
+        try {
+            if (!txn.lock(_table + id.toString(), seconds)) {
+                return null;
+            }
+
+            locked = true;
+            t = findById(id);
+            return t;
+        } finally {
+            if (t == null && locked) {
+                txn.release(_table + id.toString());
+            }
+        }
+    }
+
+    @Override
+    public boolean releaseFromLockTable(final ID id) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        return txn.release(_table + id);
+    }
+
+    @Override
+    @DB()
+    public boolean lockInLockTable(final String id) {
+        return lockInLockTable(id, _timeoutSeconds);
+    }
+
+    @Override
+    public boolean lockInLockTable(final String id, int seconds) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        return txn.lock(_table + id, seconds);
+    }
+
+    @Override
+    public boolean unlockFromLockTable(final String id) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        return txn.release(_table + id);
+    }
+
+    @Override
+    @DB()
+    public List<T> listAllIncludingRemoved() {
+        return listAllIncludingRemoved(null);
+    }
+
+    @DB()
+    protected List<Object> addGroupBy(final StringBuilder sql, SearchCriteria<?> sc) {
+        if (sc == null)
+            return null;
+        Pair<GroupBy<?, ?, ?>, List<Object>> groupBys = sc.getGroupBy();
+        if (groupBys != null) {
+            groupBys.first().toSql(sql);
+            return groupBys.second();
+        } else {
+            return null;
+        }
+    }
+
+    @DB()
+    protected void addFilter(final StringBuilder sql, final Filter filter) {
+        if (filter != null) {
+            if (filter.getOrderBy() != null) {
+                sql.append(filter.getOrderBy());
+            }
+            if (filter.getOffset() != null) {
+                sql.append(" LIMIT ");
+                sql.append(filter.getOffset());
+                if (filter.getLimit() != null) {
+                    sql.append(", ").append(filter.getLimit());
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB()
+    public List<T> listAllIncludingRemoved(final Filter filter) {
+        final StringBuilder sql = createPartialSelectSql(null, false);
+        addFilter(sql, filter);
+
+        return executeList(sql.toString());
+    }
+
+    protected List<T> executeList(final String sql, final Object... params) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        final List<T> result = new ArrayList<T>();
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            for (final Object param : params) {
+                pstmt.setObject(++i, param);
+            }
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                result.add(toEntityBean(rs, true));
+            }
+            return result;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @Override
+    @DB()
+    public List<T> listAll() {
+        return listAll(null);
+    }
+
+    @Override
+    @DB()
+    public List<T> listAll(final Filter filter) {
+        if (_removed == null) {
+            return listAllIncludingRemoved(filter);
+        }
+
+        final StringBuilder sql = createPartialSelectSql(null, true);
+        sql.append(_removed.first());
+        addFilter(sql, filter);
+
+        return executeList(sql.toString());
+    }
+
+    @Override
+    public boolean expunge(final ID id) {
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = null;
+        try {
+            txn.start();
+            for (final Pair<String, Attribute[]> deletSql : _deleteSqls) {
+                sql = deletSql.first();
+                final Attribute[] attrs = deletSql.second();
+
+                pstmt = txn.prepareAutoCloseStatement(sql);
+
+                for (int i = 0; i < attrs.length; i++) {
+                    prepareAttribute(i + 1, pstmt, attrs[i], id);
+                }
+                pstmt.executeUpdate();
+            }
+
+            txn.commit();
+            if (_cache != null) {
+                _cache.remove(id);
+            }
+            return true;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    // FIXME: Does not work for joins.
+    @Override
+    public int expunge(final SearchCriteria<T> sc) {
+        if (sc == null) {
+            throw new CloudRuntimeException("Call to throw new expunge with null search Criteria");
+        }
+
+        final StringBuilder str = new StringBuilder("DELETE FROM ");
+        str.append(_table);
+        str.append(" WHERE ");
+
+        if (sc != null && sc.getWhereClause().length() > 0) {
+            str.append(sc.getWhereClause());
+        }
+
+        final String sql = str.toString();
+
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            for (final Pair<Attribute, Object> value : sc.getValues()) {
+                prepareAttribute(++i, pstmt, value.first(), value.second());
+            }
+            return pstmt.executeUpdate();
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @DB()
+    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause, final boolean enableQueryCache) {
+        StringBuilder sql = new StringBuilder(enableQueryCache ? _partialQueryCacheSelectSql.first() : _partialSelectSql.first());
+        if (sc != null && !sc.isSelectAll()) {
+            sql.delete(7, sql.indexOf(" FROM"));
+            sc.getSelect(sql, 7);
+        }
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+    @DB()
+    protected StringBuilder createPartialSelectSql(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_partialSelectSql.first());
+        if (sc != null && !sc.isSelectAll()) {
+            sql.delete(7, sql.indexOf(" FROM"));
+            sc.getSelect(sql, 7);
+        }
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+    @DB()
+    protected void addJoins(StringBuilder str, Collection<JoinBuilder<SearchCriteria<?>>> joins) {
+        int fromIndex = str.lastIndexOf("WHERE");
+        if (fromIndex == -1) {
+            fromIndex = str.length();
+            str.append(" WHERE ");
+        } else {
+            str.append(" AND ");
+        }
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            StringBuilder onClause = new StringBuilder();
+            onClause.append(" ")
+            .append(join.getType().getName())
+            .append(" ")
+            .append(join.getSecondAttribute().table)
+            .append(" ON ")
+            .append(join.getFirstAttribute().table)
+            .append(".")
+            .append(join.getFirstAttribute().columnName)
+            .append("=")
+            .append(join.getSecondAttribute().table)
+            .append(".")
+            .append(join.getSecondAttribute().columnName)
+            .append(" ");
+            str.insert(fromIndex, onClause);
+            String whereClause = join.getT().getWhereClause();
+            if ((whereClause != null) && !"".equals(whereClause)) {
+                str.append(" (").append(whereClause).append(") AND");
+            }
+            fromIndex += onClause.length();
+        }
+
+        str.delete(str.length() - 4, str.length());
+
+        for (JoinBuilder<SearchCriteria<?>> join : joins) {
+            if (join.getT().getJoins() != null) {
+                addJoins(str, join.getT().getJoins());
+            }
+        }
+    }
+
+    @Override
+    @DB()
+    public List<T> search(final SearchCriteria<T> sc, final Filter filter) {
+        return search(sc, filter, null, false);
+    }
+
+    @Override
+    @DB()
+    public Pair<List<T>, Integer> searchAndCount(final SearchCriteria<T> sc, final Filter filter) {
+        List<T> objects = search(sc, filter, null, false);
+        Integer count = getCount(sc);
+        // Count cannot be less than the result set but can be higher due to pagination, see CLOUDSTACK-10320
+        if (count < objects.size()) {
+            count = objects.size();
+        }
+        return new Pair<List<T>, Integer>(objects, count);
+    }
+
+    @Override
+    @DB()
+    public Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter) {
+        List<T> objects = search(sc, filter, null, false);
+        Integer count = getDistinctCount(sc);
+        // Count cannot be 0 if there is at least a result in the list, see CLOUDSTACK-10320
+        if (count == 0 && !objects.isEmpty()) {
+            // Cannot assume if it's more than one since the count is distinct vs search
+            count = 1;
+        }
+        return new Pair<List<T>, Integer>(objects, count);
+    }
+
+    @Override
+    @DB()
+    public Pair<List<T>, Integer> searchAndDistinctCount(final SearchCriteria<T> sc, final Filter filter, final String[] distinctColumns) {
+        List<T> objects = search(sc, filter, null, false);
+        Integer count = getDistinctCount(sc, distinctColumns);
+        // Count cannot be 0 if there is at least a result in the list, see CLOUDSTACK-10320
+        if (count == 0 && !objects.isEmpty()) {
+            // Cannot assume if it's more than one since the count is distinct vs search
+            count = 1;
+        }
+        return new Pair<List<T>, Integer>(objects, count);
+    }
+
+    @Override
+    @DB()
+    public List<T> search(final SearchCriteria<T> sc, final Filter filter, final boolean enableQueryCache) {
+        return search(sc, filter, null, false, enableQueryCache);
+    }
+
+    @Override
+    @DB()
+    public boolean update(ID id, T entity) {
+        assert Enhancer.isEnhanced(entity.getClass()) : "Entity is not generated by this dao";
+
+        UpdateBuilder ub = getUpdateBuilder(entity);
+        boolean result = update(id, ub, entity) != 0;
+        return result;
+    }
+
+    @DB()
+    public int update(final T entity, final SearchCriteria<T> sc, Integer rows) {
+        final UpdateBuilder ub = getUpdateBuilder(entity);
+        return update(ub, sc, rows);
+    }
+
+    @Override
+    @DB()
+    public int update(final T entity, final SearchCriteria<T> sc) {
+        final UpdateBuilder ub = getUpdateBuilder(entity);
+        return update(ub, sc, null);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T persist(final T entity) {
+        if (Enhancer.isEnhanced(entity.getClass())) {
+            if (_idField != null) {
+                ID id;
+                try {
+                    id = (ID)_idField.get(entity);
+                } catch (IllegalAccessException e) {
+                    throw new CloudRuntimeException("How can it be illegal access...come on", e);
+                }
+                update(id, entity);
+                return entity;
+            }
+
+            assert false : "Can't call persit if you don't have primary key";
+        }
+
+        ID id = null;
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        String sql = null;
+        try {
+            txn.start();
+            for (final Pair<String, Attribute[]> pair : _insertSqls) {
+                sql = pair.first();
+                final Attribute[] attrs = pair.second();
+
+                pstmt = txn.prepareAutoCloseStatement(sql, Statement.RETURN_GENERATED_KEYS);
+
+                int index = 1;
+                index = prepareAttributes(pstmt, entity, attrs, index);
+
+                pstmt.executeUpdate();
+
+                final ResultSet rs = pstmt.getGeneratedKeys();
+                if (id == null) {
+                    if (rs != null && rs.next()) {
+                        id = (ID)rs.getObject(1);
+                    }
+                    try {
+                        if (_idField != null) {
+                            if (id != null) {
+                                _idField.set(entity, id);
+                            } else {
+                                id = (ID)_idField.get(entity);
+                            }
+                        }
+                    } catch (final IllegalAccessException e) {
+                        throw new CloudRuntimeException("Yikes! ", e);
+                    }
+                }
+            }
+
+            if (_ecAttributes != null && _ecAttributes.size() > 0) {
+                HashMap<Attribute, Object> ecAttributes = new HashMap<Attribute, Object>();
+                for (Attribute attr : _ecAttributes) {
+                    Object ec = attr.field.get(entity);
+                    if (ec != null) {
+                        ecAttributes.put(attr, ec);
+                    }
+                }
+
+                insertElementCollection(entity, _idAttributes.get(_table)[0], id, ecAttributes);
+            }
+            txn.commit();
+        } catch (final SQLException e) {
+            if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) {
+                throw new EntityExistsException("Entity already exists: ", e);
+            } else {
+                throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+            }
+        } catch (IllegalArgumentException e) {
+            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
+        } catch (IllegalAccessException e) {
+            throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
+        }
+
+        return _idField != null ? findByIdIncludingRemoved(id) : null;
+    }
+
+    protected void insertElementCollection(T entity, Attribute idAttribute, ID id, Map<Attribute, Object> ecAttributes) throws SQLException {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        for (Map.Entry<Attribute, Object> entry : ecAttributes.entrySet()) {
+            Attribute attr = entry.getKey();
+            Object obj = entry.getValue();
+
+            EcInfo ec = (EcInfo)attr.attache;
+            Enumeration<?> en = null;
+            if (ec.rawClass == null) {
+                en = Collections.enumeration(Arrays.asList((Object[])obj));
+            } else {
+                en = Collections.enumeration((Collection)obj);
+            }
+            PreparedStatement pstmt = txn.prepareAutoCloseStatement(ec.clearSql);
+            prepareAttribute(1, pstmt, idAttribute, id);
+            pstmt.executeUpdate();
+
+            while (en.hasMoreElements()) {
+                pstmt = txn.prepareAutoCloseStatement(ec.insertSql);
+                if (ec.targetClass == Date.class) {
+                    pstmt.setString(1, DateUtil.getDateDisplayString(s_gmtTimeZone, (Date)en.nextElement()));
+                } else {
+                    pstmt.setObject(1, en.nextElement());
+                }
+                prepareAttribute(2, pstmt, idAttribute, id);
+                pstmt.executeUpdate();
+            }
+        }
+        txn.commit();
+    }
+
+    @DB()
+    protected Object generateValue(final Attribute attr) {
+        if (attr.is(Attribute.Flag.Created) || attr.is(Attribute.Flag.Removed)) {
+            return new Date();
+        } else if (attr.is(Attribute.Flag.TableGV)) {
+            return null;
+            // Not sure what to do here.
+        } else if (attr.is(Attribute.Flag.AutoGV)) {
+            if (attr.columnName.equals(GenericDao.XID_COLUMN)) {
+                return UUID.randomUUID().toString();
+            }
+            assert (false) : "Auto generation is not supported.";
+            return null;
+        } else if (attr.is(Attribute.Flag.SequenceGV)) {
+            assert (false) : "Sequence generation is not supported.";
+            return null;
+        } else if (attr.is(Attribute.Flag.DC)) {
+            return _discriminatorValues.get(attr.columnName);
+        } else {
+            assert (false) : "Attribute can't be auto generated: " + attr.columnName;
+            return null;
+        }
+    }
+
+    @DB()
+    protected void prepareAttribute(final int j, final PreparedStatement pstmt, final Attribute attr, Object value) throws SQLException {
+        if (attr.is(Attribute.Flag.DaoGenerated) && value == null) {
+            value = generateValue(attr);
+            if (attr.field == null) {
+                pstmt.setObject(j, value);
+                return;
+            }
+        }
+        if (attr.field.getType() == String.class) {
+            final String str = (String)value;
+            if (str == null) {
+                pstmt.setString(j, null);
+                return;
+            }
+            final Column column = attr.field.getAnnotation(Column.class);
+            final int length = column != null ? column.length() : 255;
+
+            // to support generic localization, utilize MySql UTF-8 support
+            if (length < str.length()) {
+                try {
+                    if (attr.is(Attribute.Flag.Encrypted)) {
+                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str.substring(0, length)).getBytes("UTF-8"));
+                    } else {
+                        pstmt.setBytes(j, str.substring(0, length).getBytes("UTF-8"));
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    // no-way it can't support UTF-8 encoding
+                    assert (false);
+                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
+                }
+            } else {
+                try {
+                    if (attr.is(Attribute.Flag.Encrypted)) {
+                        pstmt.setBytes(j, DBEncryptionUtil.encrypt(str).getBytes("UTF-8"));
+                    } else {
+                        pstmt.setBytes(j, str.getBytes("UTF-8"));
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    // no-way it can't support UTF-8 encoding
+                    assert (false);
+                    throw new CloudRuntimeException("UnsupportedEncodingException when saving string as UTF-8 data");
+                }
+            }
+        } else if (attr.field.getType() == Date.class) {
+            final Date date = (Date)value;
+            if (date == null || date.equals(DATE_TO_NULL)) {
+                pstmt.setObject(j, null);
+                return;
+            }
+            if (attr.is(Attribute.Flag.Date)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            } else if (attr.is(Attribute.Flag.TimeStamp)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            } else if (attr.is(Attribute.Flag.Time)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, date));
+            }
+        } else if (attr.field.getType() == Calendar.class) {
+            final Calendar cal = (Calendar)value;
+            if (cal == null) {
+                pstmt.setObject(j, null);
+                return;
+            }
+            if (attr.is(Attribute.Flag.Date)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            } else if (attr.is(Attribute.Flag.TimeStamp)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            } else if (attr.is(Attribute.Flag.Time)) {
+                pstmt.setString(j, DateUtil.getDateDisplayString(s_gmtTimeZone, cal.getTime()));
+            }
+        } else if (attr.field.getType().isEnum()) {
+            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
+            final EnumType type = (enumerated == null) ? EnumType.STRING : enumerated.value();
+            if (type == EnumType.STRING) {
+                pstmt.setString(j, value == null ? null : value.toString());
+            } else if (type == EnumType.ORDINAL) {
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setInt(j, ((Enum<?>)value).ordinal());
+                }
+            }
+        } else if (attr.field.getType() == URI.class) {
+            pstmt.setString(j, value == null ? null : value.toString());
+        } else if (attr.field.getType() == URL.class) {
+            pstmt.setURL(j, (URL)value);
+        } else if (attr.field.getType() == byte[].class) {
+            pstmt.setBytes(j, (byte[])value);
+        } else if (attr.field.getType() == Ip.class) {
+            final Enumerated enumerated = attr.field.getAnnotation(Enumerated.class);
+            final EnumType type = (enumerated == null) ? EnumType.ORDINAL : enumerated.value();
+            if (type == EnumType.STRING) {
+                pstmt.setString(j, value == null ? null : value.toString());
+            } else if (type == EnumType.ORDINAL) {
+                if (value == null) {
+                    pstmt.setObject(j, null);
+                } else {
+                    pstmt.setLong(j, (value instanceof Ip) ? ((Ip)value).longValue() : NetUtils.ip2Long((String)value));
+                }
+            }
+        } else {
+            pstmt.setObject(j, value);
+        }
+    }
+
+    @DB()
+    protected int prepareAttributes(final PreparedStatement pstmt, final Object entity, final Attribute[] attrs, final int index) throws SQLException {
+        int j = 0;
+        for (int i = 0; i < attrs.length; i++) {
+            j = i + index;
+            try {
+                prepareAttribute(j, pstmt, attrs[i], attrs[i].field != null ? attrs[i].field.get(entity) : null);
+            } catch (final IllegalArgumentException e) {
+                throw new CloudRuntimeException("IllegalArgumentException", e);
+            } catch (final IllegalAccessException e) {
+                throw new CloudRuntimeException("IllegalArgumentException", e);
+            }
+        }
+
+        return j;
+    }
+
+    @SuppressWarnings("unchecked")
+    @DB()
+    protected T toEntityBean(final ResultSet result, final boolean cache) throws SQLException {
+        final T entity = (T)_factory.newInstance(new Callback[] {NoOp.INSTANCE, new UpdateBuilder(this)});
+
+        toEntityBean(result, entity);
+
+        if (cache && _cache != null) {
+            try {
+                _cache.put(new Element(_idField.get(entity), entity));
+            } catch (final Exception e) {
+                s_logger.debug("Can't put it in the cache", e);
+            }
+        }
+
+        return entity;
+    }
+
+    @DB()
+    protected T toVO(ResultSet result, boolean cache) throws SQLException {
+        T entity;
+        try {
+            entity = _entityBeanType.newInstance();
+        } catch (InstantiationException e1) {
+            throw new CloudRuntimeException("Unable to instantiate entity", e1);
+        } catch (IllegalAccessException e1) {
+            throw new CloudRuntimeException("Illegal Access", e1);
+        }
+        toEntityBean(result, entity);
+        if (cache && _cache != null) {
+            try {
+                _cache.put(new Element(_idField.get(entity), entity));
+            } catch (final Exception e) {
+                s_logger.debug("Can't put it in the cache", e);
+            }
+        }
+
+        return entity;
+    }
+
+    @DB()
+    protected void toEntityBean(final ResultSet result, final T entity) throws SQLException {
+        ResultSetMetaData meta = result.getMetaData();
+        for (int index = 1, max = meta.getColumnCount(); index <= max; index++) {
+            setField(entity, result, meta, index);
+        }
+        for (Attribute attr : _ecAttributes) {
+            loadCollection(entity, attr);
+        }
+    }
+
+    @DB()
+    @SuppressWarnings("unchecked")
+    protected void loadCollection(T entity, Attribute attr) {
+        EcInfo ec = (EcInfo)attr.attache;
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try(PreparedStatement pstmt = txn.prepareStatement(ec.selectSql);)
+        {
+            pstmt.setObject(1, _idField.get(entity));
+            try(ResultSet rs = pstmt.executeQuery();)
+            {
+                ArrayList lst = new ArrayList();
+                if (ec.targetClass == Integer.class) {
+                    while (rs.next()) {
+                        lst.add(rs.getInt(1));
+                    }
+                } else if (ec.targetClass == Long.class) {
+                    while (rs.next()) {
+                        lst.add(rs.getLong(1));
+                    }
+                } else if (ec.targetClass == String.class) {
+                    while (rs.next()) {
+                        lst.add(rs.getString(1));
+                    }
+                } else if (ec.targetClass == Short.class) {
+                    while (rs.next()) {
+                        lst.add(rs.getShort(1));
+                    }
+                } else if (ec.targetClass == Date.class) {
+                    while (rs.next()) {
+                        lst.add(DateUtil.parseDateString(s_gmtTimeZone, rs.getString(1)));
+                    }
+                } else if (ec.targetClass == Boolean.class) {
+                    while (rs.next()) {
+                        lst.add(rs.getBoolean(1));
+                    }
+                } else {
+                    assert (false) : "You'll need to add more classeses";
+                }
+                if (ec.rawClass == null) {
+                    Object[] array = (Object[]) Array.newInstance(ec.targetClass);
+                    lst.toArray(array);
+                    try {
+                        attr.field.set(entity, array);
+                    } catch (IllegalArgumentException e) {
+                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                    } catch (IllegalAccessException e) {
+                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                    }
+                } else {
+                    try {
+                        Collection coll = (Collection) ec.rawClass.newInstance();
+                        coll.addAll(lst);
+                        attr.field.set(entity, coll);
+                    } catch (IllegalAccessException e) {
+                        throw new CloudRuntimeException("Come on we screen for this stuff, don't we?", e);
+                    } catch (InstantiationException e) {
+                        throw new CloudRuntimeException("Never should happen", e);
+                    }
+                }
+            }
+            catch (SQLException e) {
+                throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
+        } catch (IllegalArgumentException e) {
+            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
+        } catch (IllegalAccessException e) {
+            throw new CloudRuntimeException("loadCollection: Exception : " +e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void expunge() {
+        if (_removed == null) {
+            return;
+        }
+        final StringBuilder sql = new StringBuilder("DELETE FROM ");
+        sql.append(_table).append(" WHERE ").append(_removed.first()).append(" IS NOT NULL");
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(sql.toString());
+
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on " + pstmt, e);
+        }
+    }
+
+    @DB()
+    protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
+        Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
+        if (attr == null) {
+            // work around for mysql bug to return original table name instead of view name in db view case
+            Table tbl = entity.getClass().getSuperclass().getAnnotation(Table.class);
+            if (tbl != null) {
+                attr = _allColumns.get(new Pair<String, String>(tbl.name(), meta.getColumnLabel(index)));
+            }
+        }
+        assert (attr != null) : "How come I can't find " + meta.getCatalogName(index) + "." + meta.getColumnName(index);
+        setField(entity, attr.field, rs, index);
+    }
+
+    @Override
+    public boolean remove(final ID id) {
+        if (_removeSql == null) {
+            return expunge(id);
+        }
+
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(_removeSql.first());
+            final Attribute[] attrs = _removeSql.second();
+            prepareAttribute(1, pstmt, attrs[attrs.length - 1], null);
+            for (int i = 0; i < attrs.length - 1; i++) {
+                prepareAttribute(i + 2, pstmt, attrs[i], id);
+            }
+
+            final int result = pstmt.executeUpdate();
+            txn.commit();
+            if (_cache != null) {
+                _cache.remove(id);
+            }
+            return result > 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        }
+    }
+
+    @Override
+    public int remove(SearchCriteria<T> sc) {
+        if (_removeSql == null) {
+            return expunge(sc);
+        }
+
+        T vo = createForUpdate();
+        UpdateBuilder ub = getUpdateBuilder(vo);
+
+        ub.set(vo, _removed.second(), new Date());
+        return update(ub, sc, null);
+    }
+
+    protected Cache _cache;
+
+    @DB()
+    protected void createCache(final Map<String, ? extends Object> params) {
+        final String value = (String)params.get("cache.size");
+
+        if (value != null) {
+            final CacheManager cm = CacheManager.create();
+            final int maxElements = NumbersUtil.parseInt(value, 0);
+            final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
+            final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
+            _cache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
+            cm.addCache(_cache);
+            s_logger.info("Cache created: " + _cache.toString());
+        } else {
+            _cache = null;
+        }
+    }
+
+    @Override
+    @DB()
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+
+        final String value = (String)params.get("lock.timeout");
+        _timeoutSeconds = NumbersUtil.parseInt(value, 300);
+
+        createCache(params);
+        final boolean load = Boolean.parseBoolean((String)params.get("cache.preload"));
+        if (load) {
+            listAll();
+        }
+
+        return true;
+    }
+
+    @DB()
+    public static <T> UpdateBuilder getUpdateBuilder(final T entityObject) {
+        final Factory factory = (Factory)entityObject;
+        assert (factory != null);
+        return (UpdateBuilder)factory.getCallback(1);
+    }
+
+    @Override
+    @DB()
+    public SearchBuilder<T> createSearchBuilder() {
+        return new SearchBuilder<T>(_entityBeanType);
+    }
+
+    @Override
+    @DB()
+    public SearchCriteria<T> createSearchCriteria() {
+        SearchBuilder<T> builder = createSearchBuilder();
+        return builder.create();
+    }
+
+    public Integer getDistinctCount(SearchCriteria<T> sc) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createDistinctIdSelect(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        // we have to disable group by in getting count, since count for groupBy clause will be different.
+        //List<Object> groupByValues = addGroupBy(str, sc);
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        final String sql = "SELECT COUNT(*) FROM (" + str.toString() + ") AS tmp";
+
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 1;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(i++, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            /*
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+             */
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getInt(1);
+            }
+            return 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    public Integer getDistinctCount(SearchCriteria<T> sc, String[] distinctColumns) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (Strings.isNullOrEmpty(clause)) {
+            clause = null;
+        }
+
+        final StringBuilder str = createDistinctSelect(sc, clause != null, distinctColumns);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        final String sql = "SELECT COUNT(*) FROM (" + str.toString() + ") AS tmp";
+
+        try (PreparedStatement pstmt = txn.prepareAutoCloseStatement(sql)) {
+            int i = 1;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(i++, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getInt(1);
+            }
+            return 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception in executing: " + sql, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught exception in : " + sql, e);
+        }
+    }
+
+    public Integer getCount(SearchCriteria<T> sc) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createCountSelect(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        // we have to disable group by in getting count, since count for groupBy clause will be different.
+        //List<Object> groupByValues = addGroupBy(str, sc);
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        final String sql = str.toString();
+
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 1;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(i++, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+
+            /*
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+             */
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getInt(1);
+            }
+            return 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @DB()
+    protected StringBuilder createCountSelect(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_count);
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+    @DB()
+    protected StringBuilder createDistinctIdSelect(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_distinctIdSql);
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+
+    @DB()
+    protected Pair<List<T>, Integer> listAndCountIncludingRemovedBy(final SearchCriteria<T> sc, final Filter filter) {
+        List<T> objects = searchIncludingRemoved(sc, filter, null, false);
+        Integer count = getCount(sc);
+        return new Pair<List<T>, Integer>(objects, count);
+    }
+
+    @DB()
+    protected StringBuilder createDistinctSelect(SearchCriteria<?> sc, final boolean whereClause, String[] distinctColumns) {
+        final SqlGenerator generator = new SqlGenerator(_entityBeanType);
+        String distinctSql = generator.buildDistinctSql(distinctColumns);
+
+        StringBuilder sql = new StringBuilder(distinctSql);
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+}
diff --git a/framework/db/src/com/cloud/utils/db/GenericQueryBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericQueryBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/GenericQueryBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/GenericQueryBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/GenericSearchBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/GenericSearchBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/GlobalLock.java b/framework/db/src/main/java/com/cloud/utils/db/GlobalLock.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/GlobalLock.java
rename to framework/db/src/main/java/com/cloud/utils/db/GlobalLock.java
diff --git a/framework/db/src/com/cloud/utils/db/GroupBy.java b/framework/db/src/main/java/com/cloud/utils/db/GroupBy.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/GroupBy.java
rename to framework/db/src/main/java/com/cloud/utils/db/GroupBy.java
diff --git a/framework/db/src/com/cloud/utils/db/JoinBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/JoinBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/JoinBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/JoinType.java b/framework/db/src/main/java/com/cloud/utils/db/JoinType.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/JoinType.java
rename to framework/db/src/main/java/com/cloud/utils/db/JoinType.java
diff --git a/framework/db/src/com/cloud/utils/db/Merovingian2.java b/framework/db/src/main/java/com/cloud/utils/db/Merovingian2.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/Merovingian2.java
rename to framework/db/src/main/java/com/cloud/utils/db/Merovingian2.java
diff --git a/framework/db/src/com/cloud/utils/db/MerovingianMBean.java b/framework/db/src/main/java/com/cloud/utils/db/MerovingianMBean.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/MerovingianMBean.java
rename to framework/db/src/main/java/com/cloud/utils/db/MerovingianMBean.java
diff --git a/framework/db/src/com/cloud/utils/db/QueryBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/QueryBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/QueryBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/QueryBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/ScriptRunner.java b/framework/db/src/main/java/com/cloud/utils/db/ScriptRunner.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/ScriptRunner.java
rename to framework/db/src/main/java/com/cloud/utils/db/ScriptRunner.java
diff --git a/framework/db/src/com/cloud/utils/db/SearchBase.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/SearchBase.java
rename to framework/db/src/main/java/com/cloud/utils/db/SearchBase.java
diff --git a/framework/db/src/com/cloud/utils/db/SearchBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/SearchBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/SearchBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/SearchBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/SearchCriteria.java b/framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/SearchCriteria.java
rename to framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java
diff --git a/framework/db/src/com/cloud/utils/db/SequenceFetcher.java b/framework/db/src/main/java/com/cloud/utils/db/SequenceFetcher.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/SequenceFetcher.java
rename to framework/db/src/main/java/com/cloud/utils/db/SequenceFetcher.java
diff --git a/framework/db/src/com/cloud/utils/db/SqlGenerator.java b/framework/db/src/main/java/com/cloud/utils/db/SqlGenerator.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/SqlGenerator.java
rename to framework/db/src/main/java/com/cloud/utils/db/SqlGenerator.java
diff --git a/framework/db/src/com/cloud/utils/db/StateMachine.java b/framework/db/src/main/java/com/cloud/utils/db/StateMachine.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/StateMachine.java
rename to framework/db/src/main/java/com/cloud/utils/db/StateMachine.java
diff --git a/framework/db/src/com/cloud/utils/db/Transaction.java b/framework/db/src/main/java/com/cloud/utils/db/Transaction.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/Transaction.java
rename to framework/db/src/main/java/com/cloud/utils/db/Transaction.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionAttachment.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionAttachment.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionAttachment.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionAttachment.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallback.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionCallback.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionCallback.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionCallback.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackNoReturn.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionCallbackNoReturn.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackNoReturn.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackWithException.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionCallbackWithException.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackWithException.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionCallbackWithExceptionNoReturn.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionContextBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionContextBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionContextBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextInterceptor.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionContextInterceptor.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionContextInterceptor.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionContextInterceptor.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionContextListener.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionContextListener.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionContextListener.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionContextListener.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionLegacy.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionLegacy.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionMBean.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionMBean.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionMBean.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionMBean.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionMBeanImpl.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionMBeanImpl.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionMBeanImpl.java
diff --git a/framework/db/src/com/cloud/utils/db/TransactionStatus.java b/framework/db/src/main/java/com/cloud/utils/db/TransactionStatus.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/TransactionStatus.java
rename to framework/db/src/main/java/com/cloud/utils/db/TransactionStatus.java
diff --git a/framework/db/src/com/cloud/utils/db/UpdateBuilder.java b/framework/db/src/main/java/com/cloud/utils/db/UpdateBuilder.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/UpdateBuilder.java
rename to framework/db/src/main/java/com/cloud/utils/db/UpdateBuilder.java
diff --git a/framework/db/src/com/cloud/utils/db/UpdateFilter.java b/framework/db/src/main/java/com/cloud/utils/db/UpdateFilter.java
similarity index 100%
rename from framework/db/src/com/cloud/utils/db/UpdateFilter.java
rename to framework/db/src/main/java/com/cloud/utils/db/UpdateFilter.java
diff --git a/framework/db/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml b/framework/db/src/main/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml
similarity index 100%
rename from framework/db/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml
rename to framework/db/src/main/resources/META-INF/cloudstack/system/spring-framework-db-system-context.xml
diff --git a/framework/db/test/db.properties b/framework/db/src/test/db.properties
similarity index 100%
rename from framework/db/test/db.properties
rename to framework/db/src/test/db.properties
diff --git a/framework/db/test/com/cloud/utils/DbUtilTest.java b/framework/db/src/test/java/com/cloud/utils/DbUtilTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/DbUtilTest.java
rename to framework/db/src/test/java/com/cloud/utils/DbUtilTest.java
diff --git a/framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java b/framework/db/src/test/java/com/cloud/utils/db/DbAnnotatedBase.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DbAnnotatedBase.java
rename to framework/db/src/test/java/com/cloud/utils/db/DbAnnotatedBase.java
diff --git a/framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java b/framework/db/src/test/java/com/cloud/utils/db/DbAnnotatedBaseDerived.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DbAnnotatedBaseDerived.java
rename to framework/db/src/test/java/com/cloud/utils/db/DbAnnotatedBaseDerived.java
diff --git a/framework/db/test/com/cloud/utils/db/DbTestDao.java b/framework/db/src/test/java/com/cloud/utils/db/DbTestDao.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DbTestDao.java
rename to framework/db/src/test/java/com/cloud/utils/db/DbTestDao.java
diff --git a/framework/db/test/com/cloud/utils/db/DbTestUtils.java b/framework/db/src/test/java/com/cloud/utils/db/DbTestUtils.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DbTestUtils.java
rename to framework/db/src/test/java/com/cloud/utils/db/DbTestUtils.java
diff --git a/framework/db/test/com/cloud/utils/db/DbTestVO.java b/framework/db/src/test/java/com/cloud/utils/db/DbTestVO.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DbTestVO.java
rename to framework/db/src/test/java/com/cloud/utils/db/DbTestVO.java
diff --git a/framework/db/test/com/cloud/utils/db/DummyComponent.java b/framework/db/src/test/java/com/cloud/utils/db/DummyComponent.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/DummyComponent.java
rename to framework/db/src/test/java/com/cloud/utils/db/DummyComponent.java
diff --git a/framework/db/test/com/cloud/utils/db/ElementCollectionTest.java b/framework/db/src/test/java/com/cloud/utils/db/ElementCollectionTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/ElementCollectionTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/ElementCollectionTest.java
diff --git a/framework/db/test/com/cloud/utils/db/FilterTest.java b/framework/db/src/test/java/com/cloud/utils/db/FilterTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/FilterTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/FilterTest.java
diff --git a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/GenericDaoBaseTest.java
diff --git a/framework/db/test/com/cloud/utils/db/GlobalLockTest.java b/framework/db/src/test/java/com/cloud/utils/db/GlobalLockTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/GlobalLockTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/GlobalLockTest.java
diff --git a/framework/db/test/com/cloud/utils/db/GroupByTest.java b/framework/db/src/test/java/com/cloud/utils/db/GroupByTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/GroupByTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/GroupByTest.java
diff --git a/framework/db/test/com/cloud/utils/db/Merovingian2Test.java b/framework/db/src/test/java/com/cloud/utils/db/Merovingian2Test.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/Merovingian2Test.java
rename to framework/db/src/test/java/com/cloud/utils/db/Merovingian2Test.java
diff --git a/framework/db/test/com/cloud/utils/db/TestTransaction.java b/framework/db/src/test/java/com/cloud/utils/db/TestTransaction.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/TestTransaction.java
rename to framework/db/src/test/java/com/cloud/utils/db/TestTransaction.java
diff --git a/framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java b/framework/db/src/test/java/com/cloud/utils/db/TransactionContextBuilderTest.java
similarity index 100%
rename from framework/db/test/com/cloud/utils/db/TransactionContextBuilderTest.java
rename to framework/db/src/test/java/com/cloud/utils/db/TransactionContextBuilderTest.java
diff --git a/framework/db/test/resources/db.properties b/framework/db/src/test/resources/db.properties
similarity index 100%
rename from framework/db/test/resources/db.properties
rename to framework/db/src/test/resources/db.properties
diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml
index 7f5c4cb..f08c24d 100644
--- a/framework/direct-download/pom.xml
+++ b/framework/direct-download/pom.xml
@@ -1,31 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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">
+<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-framework-direct-download</artifactId>
     <name>Apache CloudStack Framework - Direct Download to Primary Storage</name>
     <parent>
         <artifactId>cloudstack-framework</artifactId>
         <groupId>org.apache.cloudstack</groupId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 </project>
\ No newline at end of file
diff --git a/framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java b/framework/direct-download/src/main/java/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java
similarity index 100%
rename from framework/direct-download/src/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java
rename to framework/direct-download/src/main/java/org/apache/cloudstack/framework/agent/direct/download/DirectDownloadService.java
diff --git a/framework/events/pom.xml b/framework/events/pom.xml
index 7f054d8..8e30eb8 100644
--- a/framework/events/pom.xml
+++ b/framework/events/pom.xml
@@ -1,36 +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. -->
+<!--
+  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-framework-events</artifactId>
-  <name>Apache CloudStack Framework - Event Notification</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-  </dependencies>
+    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-framework-events</artifactId>
+    <name>Apache CloudStack Framework - Event Notification</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/events/src/org/apache/cloudstack/framework/events/Event.java b/framework/events/src/main/java/org/apache/cloudstack/framework/events/Event.java
similarity index 100%
rename from framework/events/src/org/apache/cloudstack/framework/events/Event.java
rename to framework/events/src/main/java/org/apache/cloudstack/framework/events/Event.java
diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventBus.java b/framework/events/src/main/java/org/apache/cloudstack/framework/events/EventBus.java
similarity index 100%
rename from framework/events/src/org/apache/cloudstack/framework/events/EventBus.java
rename to framework/events/src/main/java/org/apache/cloudstack/framework/events/EventBus.java
diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventBusException.java b/framework/events/src/main/java/org/apache/cloudstack/framework/events/EventBusException.java
similarity index 100%
rename from framework/events/src/org/apache/cloudstack/framework/events/EventBusException.java
rename to framework/events/src/main/java/org/apache/cloudstack/framework/events/EventBusException.java
diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventSubscriber.java b/framework/events/src/main/java/org/apache/cloudstack/framework/events/EventSubscriber.java
similarity index 100%
rename from framework/events/src/org/apache/cloudstack/framework/events/EventSubscriber.java
rename to framework/events/src/main/java/org/apache/cloudstack/framework/events/EventSubscriber.java
diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventTopic.java b/framework/events/src/main/java/org/apache/cloudstack/framework/events/EventTopic.java
similarity index 100%
rename from framework/events/src/org/apache/cloudstack/framework/events/EventTopic.java
rename to framework/events/src/main/java/org/apache/cloudstack/framework/events/EventTopic.java
diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml
index 9ed44f5..64204ac 100644
--- a/framework/ipc/pom.xml
+++ b/framework/ipc/pom.xml
@@ -1,60 +1,68 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-  license agreements. See the NOTICE file distributed with this work for additional 
-  information regarding copyright ownership. The ASF licenses this file to 
-  you under the Apache License, Version 2.0 (the "License"); you may not use 
-  this file except in compliance with the License. You may obtain a copy of 
-  the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
-  by applicable law or agreed to in writing, software distributed under the 
-  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
-  OF ANY KIND, either express or implied. See the License for the specific 
-  language governing permissions and limitations under the License. -->
+<!--
+  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-framework-ipc</artifactId>
-  <name>Apache CloudStack Framework - IPC</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>cglib</groupId>
-      <artifactId>cglib-nodep</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>  
+    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-framework-ipc</artifactId>
+    <name>Apache CloudStack Framework - IPC</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/framework/ipc/src/com/cloud/agent/manager/Commands.java b/framework/ipc/src/main/java/com/cloud/agent/manager/Commands.java
similarity index 100%
rename from framework/ipc/src/com/cloud/agent/manager/Commands.java
rename to framework/ipc/src/main/java/com/cloud/agent/manager/Commands.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallFuture.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallFuture.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallFuture.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDriver.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallbackDriver.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDriver.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCallbackDriver.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncCompletionCallback.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncRpcContext.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncRpcContext.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/AsyncRpcContext.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/AsyncRpcContext.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/InplaceAsyncCallbackDriver.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/async/InplaceAsyncCallbackDriver.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/async/InplaceAsyncCallbackDriver.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/async/InplaceAsyncCallbackDriver.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientMessageBus.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientMessageBus.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/client/ClientMessageBus.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientMessageBus.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportConnection.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportConnection.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportConnection.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportConnection.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportEndpoint.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportEndpoint.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportEndpoint.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportEndpoint.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportEndpointSite.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportEndpointSite.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportEndpointSite.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportEndpointSite.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportProvider.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/client/ClientTransportProvider.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/client/ClientTransportProvider.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBus.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBus.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBus.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBus.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBusBase.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusBase.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBusBase.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusEndpoint.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBusEndpoint.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageBusEndpoint.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageBusEndpoint.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageDetector.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDetector.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageDetector.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageHandler.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageHandler.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageHandler.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageHandler.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageSubscriber.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageSubscriber.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageSubscriber.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/MessageSubscriber.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/PublishScope.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/PublishScope.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/messagebus/PublishScope.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/messagebus/PublishScope.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallRequestPdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallRequestPdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallRequestPdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallRequestPdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallResponsePdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallResponsePdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallResponsePdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallResponsePdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallbackDispatcher.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackListener.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallbackListener.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcCallbackListener.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcCallbackListener.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcClientCall.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCall.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcClientCall.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcClientCallImpl.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcException.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcException.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcException.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcException.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcIOException.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcIOException.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcIOException.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcIOException.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcProvider.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcProvider.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcProvider.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcProvider.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcProviderImpl.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcProviderImpl.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcProviderImpl.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcProviderImpl.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServerCall.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServerCall.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServerCall.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServerCall.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServerCallImpl.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServerCallImpl.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServerCallImpl.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServerCallImpl.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceDispatcher.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceDispatcher.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceDispatcher.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceDispatcher.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceEndpoint.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceEndpoint.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceEndpoint.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceEndpoint.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceHandler.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceHandler.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcServiceHandler.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcServiceHandler.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcTimeoutException.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcTimeoutException.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/rpc/RpcTimeoutException.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/rpc/RpcTimeoutException.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/serializer/JsonMessageSerializer.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/JsonMessageSerializer.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/serializer/JsonMessageSerializer.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/JsonMessageSerializer.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/serializer/MessageSerializer.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/MessageSerializer.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/serializer/MessageSerializer.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/MessageSerializer.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/OnwireClassRegistry.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireName.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/OnwireName.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/serializer/OnwireName.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/serializer/OnwireName.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/server/ServerMessageBus.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/server/ServerMessageBus.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/server/ServerMessageBus.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/server/ServerMessageBus.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/server/ServerTransportProvider.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/server/ServerTransportProvider.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/server/ServerTransportProvider.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/server/ServerTransportProvider.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAddress.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAddress.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAddress.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAddress.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAddressMapper.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAddressMapper.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAddressMapper.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAddressMapper.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAttachRequestPdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAttachRequestPdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAttachRequestPdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAttachRequestPdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAttachResponsePdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAttachResponsePdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportAttachResponsePdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportAttachResponsePdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportConnectRequestPdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportConnectRequestPdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportConnectRequestPdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportConnectRequestPdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportConnectResponsePdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportConnectResponsePdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportConnectResponsePdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportConnectResponsePdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportDataPdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportDataPdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportDataPdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportDataPdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportEndpoint.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportEndpoint.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportEndpoint.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportEndpoint.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportEndpointSite.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportEndpointSite.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportEndpointSite.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportEndpointSite.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportMultiplexier.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportMultiplexier.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportMultiplexier.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportMultiplexier.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportPdu.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportPdu.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportPdu.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportPdu.java
diff --git a/framework/ipc/src/org/apache/cloudstack/framework/transport/TransportProvider.java b/framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportProvider.java
similarity index 100%
rename from framework/ipc/src/org/apache/cloudstack/framework/transport/TransportProvider.java
rename to framework/ipc/src/main/java/org/apache/cloudstack/framework/transport/TransportProvider.java
diff --git a/framework/ipc/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml b/framework/ipc/src/main/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml
similarity index 100%
rename from framework/ipc/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml
rename to framework/ipc/src/main/resources/META-INF/cloudstack/core/spring-framework-ipc-core-context.xml
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleCallee.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleEventDrivenStyleCaller.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/codestyle/AsyncSampleListenerStyleCaller.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagementServer.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagementServer.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagementServer.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagementServer.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagementServerApp.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagementServerApp.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagementServerApp.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagementServerApp.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleManagerComponent2.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareAnswer.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareAnswer.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareAnswer.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareAnswer.java
diff --git a/framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareCommand.java b/framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareCommand.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareCommand.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/framework/sampleserver/SampleStoragePrepareCommand.java
diff --git a/framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java b/framework/ipc/src/test/java/org/apache/cloudstack/messagebus/TestMessageBus.java
similarity index 100%
rename from framework/ipc/test/org/apache/cloudstack/messagebus/TestMessageBus.java
rename to framework/ipc/src/test/java/org/apache/cloudstack/messagebus/TestMessageBus.java
diff --git a/framework/ipc/test/resources/MessageBusTestContext.xml b/framework/ipc/src/test/resources/MessageBusTestContext.xml
similarity index 100%
rename from framework/ipc/test/resources/MessageBusTestContext.xml
rename to framework/ipc/src/test/resources/MessageBusTestContext.xml
diff --git a/framework/ipc/test/resources/SampleManagementServerAppContext.xml b/framework/ipc/src/test/resources/SampleManagementServerAppContext.xml
similarity index 100%
rename from framework/ipc/test/resources/SampleManagementServerAppContext.xml
rename to framework/ipc/src/test/resources/SampleManagementServerAppContext.xml
diff --git a/framework/ipc/test/resources/log4j-cloud.xml b/framework/ipc/src/test/resources/log4j-cloud.xml
similarity index 100%
rename from framework/ipc/test/resources/log4j-cloud.xml
rename to framework/ipc/src/test/resources/log4j-cloud.xml
diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml
index d4d4def..40a9bdb 100644
--- a/framework/jobs/pom.xml
+++ b/framework/jobs/pom.xml
@@ -1,77 +1,77 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-framework-jobs</artifactId>
-  <name>Apache CloudStack Framework - Jobs</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>  
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-cluster</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+<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-framework-jobs</artifactId>
+    <name>Apache CloudStack Framework - Jobs</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-cluster</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJob.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJob.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJob.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobDispatcher.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobDispatcher.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobDispatcher.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobDispatcher.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobMBean.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobMBean.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobMBean.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobMBean.java
diff --git a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobManager.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
new file mode 100644
index 0000000..8542407
--- /dev/null
+++ b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
@@ -0,0 +1,136 @@
+// Licensed to the Apache Software Foundation (ASF) under ones
+// 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.framework.jobs;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.jobs.JobInfo;
+
+import com.cloud.utils.Predicate;
+import com.cloud.utils.component.Manager;
+
+public interface AsyncJobManager extends Manager {
+
+    public static final String API_JOB_POOL_THREAD_PREFIX = "API-Job-Executor";
+    public static final String WORK_JOB_POOL_THREAD_PREFIX = "Work-Job-Executor";
+
+    AsyncJobVO getAsyncJob(long jobId);
+
+    List<? extends AsyncJob> findInstancePendingAsyncJobs(String instanceType, Long accountId);
+
+    long submitAsyncJob(AsyncJob job);
+
+    long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId);
+
+    void completeAsyncJob(long jobId, JobInfo.Status jobStatus, int resultCode, String result);
+
+    void updateAsyncJobStatus(long jobId, int processStatus, String resultObject);
+
+    void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
+    void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
+            journalText, String journalObjJson);
+
+    /**
+     * A running thread inside management server can have a 1:1 linked pseudo job.
+     * This is to help make some legacy code work without too dramatic changes.
+     *
+     * All pseudo jobs should be expunged upon management start event
+     *
+     * @return pseudo job for the thread
+     */
+    AsyncJob getPseudoJob(long accountId, long userId);
+
+    /**
+     * Used by upper level job to wait for completion of a down-level job (usually VmWork jobs)
+     * in synchronous way. Caller needs to use waitAndCheck() to check the completion status
+     * of the down-level job
+     *
+     * Due to the amount of legacy code that relies on synchronous-call semantics, this form of joinJob
+     * is used mostly
+     *
+     *
+     * @param jobId upper job that is going to wait the completion of a down-level job
+     * @param joinJobId down-level job
+     */
+    void joinJob(long jobId, long joinJobId);
+
+    /**
+     * Used by upper level job to wait for completion of a down-level job (usually VmWork jobs)
+     * in asynchronous way, it will cause upper job to cease current execution, upper job will be
+     * rescheduled to execute periodically or on wakeup events detected from message bus
+     *
+     * @param jobId upper job that is going to wait the completion of a down-level job
+     * @param joinJobId down-level job
+     * @Param wakeupHandler    wake-up handler
+     * @Param wakeupDispatcher wake-up dispatcher
+     * @param wakeupTopicsOnMessageBus
+     * @param wakeupIntervalInMilliSeconds
+     * @param timeoutInMilliSeconds
+     */
+    void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakupDispatcher,
+            String[] wakeupTopicsOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds);
+
+    /**
+     * Dis-join two related jobs
+     *
+     * @param jobId
+     * @param joinedJobId
+     */
+    void disjoinJob(long jobId, long joinedJobId);
+
+    /**
+     * Used by down-level job to notify its completion to upper level jobs
+     *
+     * @param joinJobId down-level job for upper level job to join with
+     * @param joinStatus AsyncJobConstants status code to indicate success or failure of the
+     *                     down-level job
+     * @param joinResult object-stream serialized result object
+     *                     this is primarily used by down-level job to pass error exception objects
+     *                     for legacy code to work. To help pass exception object easier, we use
+     *                     object-stream based serialization instead of GSON
+     */
+    void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult);
+
+    void releaseSyncSource();
+
+    void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit);
+
+    /**
+     * This method will be deprecated after all code has been migrated to fully-asynchronous mode
+     * that uses async-feature of joinJob/disjoinJob
+     *
+     * @param wakupTopicsOnMessageBus topic on message bus to wakeup the wait
+     * @param checkIntervalInMilliSeconds time to break out wait for checking predicate condition
+     * @param timeoutInMiliseconds time out to break out the whole wait process
+     * @param predicate
+     * @return true, predicate condition is satisfied
+     *             false, wait is timed out
+     */
+    boolean waitAndCheck(AsyncJob job, String[] wakupTopicsOnMessageBus, long checkIntervalInMilliSeconds, long timeoutInMiliseconds, Predicate predicate);
+
+    AsyncJob queryJob(long jobId, boolean updatePollTime);
+
+    String marshallResultObject(Serializable obj);
+
+    Object unmarshallResultObject(AsyncJob job);
+
+    List<AsyncJobVO> findFailureAsyncJobs(String... cmds);
+
+    long countPendingJobs(String havingInfo, String... cmds);
+}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/Outcome.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/Outcome.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/Outcome.java
diff --git a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java
new file mode 100644
index 0000000..2696e10
--- /dev/null
+++ b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java
@@ -0,0 +1,49 @@
+// 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.framework.jobs.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface AsyncJobDao extends GenericDao<AsyncJobVO, Long> {
+
+    AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
+
+    List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId);
+
+    AsyncJobVO findPseudoJob(long threadId, long msid);
+
+    void cleanupPseduoJobs(long msid);
+
+    List<AsyncJobVO> getExpiredJobs(Date cutTime, int limit);
+
+    List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit);
+
+    void resetJobProcess(long msid, int jobResultCode, String jobResultMessage);
+
+    List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit);
+
+    List<AsyncJobVO> getResetJobs(long msid);
+
+    List<AsyncJobVO> getFailureJobsSinceLastMsStart(long msId, String... cmds);
+
+    long countPendingJobs(String havingInfo, String... cmds);
+}
diff --git a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
new file mode 100644
index 0000000..6ca698b
--- /dev/null
+++ b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
@@ -0,0 +1,249 @@
+// 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.framework.jobs.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.jobs.JobInfo;
+
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+
+public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements AsyncJobDao {
+    private static final Logger s_logger = Logger.getLogger(AsyncJobDaoImpl.class.getName());
+
+    private final SearchBuilder<AsyncJobVO> pendingAsyncJobSearch;
+    private final SearchBuilder<AsyncJobVO> pendingAsyncJobsSearch;
+    private final SearchBuilder<AsyncJobVO> expiringAsyncJobSearch;
+    private final SearchBuilder<AsyncJobVO> pseudoJobSearch;
+    private final SearchBuilder<AsyncJobVO> pseudoJobCleanupSearch;
+    private final SearchBuilder<AsyncJobVO> expiringUnfinishedAsyncJobSearch;
+    private final SearchBuilder<AsyncJobVO> expiringCompletedAsyncJobSearch;
+    private final SearchBuilder<AsyncJobVO> failureMsidAsyncJobSearch;
+    private final GenericSearchBuilder<AsyncJobVO, Long> asyncJobTypeSearch;
+
+    public AsyncJobDaoImpl() {
+        pendingAsyncJobSearch = createSearchBuilder();
+        pendingAsyncJobSearch.and("instanceType", pendingAsyncJobSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
+        pendingAsyncJobSearch.and("instanceId", pendingAsyncJobSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
+        pendingAsyncJobSearch.and("status", pendingAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        pendingAsyncJobSearch.done();
+
+        expiringAsyncJobSearch = createSearchBuilder();
+        expiringAsyncJobSearch.and("created", expiringAsyncJobSearch.entity().getCreated(), SearchCriteria.Op.LTEQ);
+        expiringAsyncJobSearch.done();
+
+        pendingAsyncJobsSearch = createSearchBuilder();
+        pendingAsyncJobsSearch.and("instanceType", pendingAsyncJobsSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
+        pendingAsyncJobsSearch.and("accountId", pendingAsyncJobsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        pendingAsyncJobsSearch.and("status", pendingAsyncJobsSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        pendingAsyncJobsSearch.done();
+
+        expiringUnfinishedAsyncJobSearch = createSearchBuilder();
+        expiringUnfinishedAsyncJobSearch.and("jobDispatcher", expiringUnfinishedAsyncJobSearch.entity().getDispatcher(), SearchCriteria.Op.NEQ);
+        expiringUnfinishedAsyncJobSearch.and("created", expiringUnfinishedAsyncJobSearch.entity().getCreated(), SearchCriteria.Op.LTEQ);
+        expiringUnfinishedAsyncJobSearch.and("completeMsId", expiringUnfinishedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NULL);
+        expiringUnfinishedAsyncJobSearch.and("jobStatus", expiringUnfinishedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        expiringUnfinishedAsyncJobSearch.done();
+
+        expiringCompletedAsyncJobSearch = createSearchBuilder();
+        expiringCompletedAsyncJobSearch.and(ApiConstants.REMOVED, expiringCompletedAsyncJobSearch.entity().getRemoved(), SearchCriteria.Op.LTEQ);
+        expiringCompletedAsyncJobSearch.and("completeMsId", expiringCompletedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NNULL);
+        expiringCompletedAsyncJobSearch.and("jobStatus", expiringCompletedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.NEQ);
+        expiringCompletedAsyncJobSearch.done();
+
+        pseudoJobSearch = createSearchBuilder();
+        pseudoJobSearch.and("jobDispatcher", pseudoJobSearch.entity().getDispatcher(), Op.EQ);
+        pseudoJobSearch.and("instanceType", pseudoJobSearch.entity().getInstanceType(), Op.EQ);
+        pseudoJobSearch.and("instanceId", pseudoJobSearch.entity().getInstanceId(), Op.EQ);
+        pseudoJobSearch.done();
+
+        pseudoJobCleanupSearch = createSearchBuilder();
+        pseudoJobCleanupSearch.and("initMsid", pseudoJobCleanupSearch.entity().getInitMsid(), Op.EQ);
+        pseudoJobCleanupSearch.done();
+
+        failureMsidAsyncJobSearch = createSearchBuilder();
+        failureMsidAsyncJobSearch.and("initMsid", failureMsidAsyncJobSearch.entity().getInitMsid(), Op.EQ);
+        failureMsidAsyncJobSearch.and("instanceType", failureMsidAsyncJobSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
+        failureMsidAsyncJobSearch.and("status", failureMsidAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        failureMsidAsyncJobSearch.and("job_cmd", failureMsidAsyncJobSearch.entity().getCmd(), Op.IN);
+        failureMsidAsyncJobSearch.done();
+
+        asyncJobTypeSearch = createSearchBuilder(Long.class);
+        asyncJobTypeSearch.select(null, SearchCriteria.Func.COUNT, asyncJobTypeSearch.entity().getId());
+        asyncJobTypeSearch.and("job_info", asyncJobTypeSearch.entity().getCmdInfo(),Op.LIKE);
+        asyncJobTypeSearch.and("job_cmd", asyncJobTypeSearch.entity().getCmd(), Op.IN);
+        asyncJobTypeSearch.and("status", asyncJobTypeSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        asyncJobTypeSearch.done();
+
+    }
+
+    @Override
+    public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
+        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
+        sc.setParameters("instanceType", instanceType);
+        sc.setParameters("instanceId", instanceId);
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
+
+        List<AsyncJobVO> l = listIncludingRemovedBy(sc);
+        if (l != null && l.size() > 0) {
+            if (l.size() > 1) {
+                s_logger.warn("Instance " + instanceType + "-" + instanceId + " has multiple pending async-job");
+            }
+
+            return l.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
+        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobsSearch.create();
+        sc.setParameters("instanceType", instanceType);
+
+        if (accountId != null) {
+            sc.setParameters("accountId", accountId);
+        }
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public AsyncJobVO findPseudoJob(long threadId, long msid) {
+        SearchCriteria<AsyncJobVO> sc = pseudoJobSearch.create();
+        sc.setParameters("jobDispatcher", AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+        sc.setParameters("instanceType", AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
+        sc.setParameters("instanceId", threadId);
+
+        List<AsyncJobVO> result = listBy(sc);
+        if (result != null && result.size() > 0) {
+            assert (result.size() == 1);
+            return result.get(0);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void cleanupPseduoJobs(long msid) {
+        SearchCriteria<AsyncJobVO> sc = pseudoJobCleanupSearch.create();
+        sc.setParameters("initMsid", msid);
+        this.expunge(sc);
+    }
+
+    @Override
+    public List<AsyncJobVO> getExpiredJobs(Date cutTime, int limit) {
+        SearchCriteria<AsyncJobVO> sc = expiringAsyncJobSearch.create();
+        sc.setParameters("created", cutTime);
+        Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
+        return listIncludingRemovedBy(sc, filter);
+    }
+
+    @Override
+    public List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit) {
+        SearchCriteria<AsyncJobVO> sc = expiringUnfinishedAsyncJobSearch.create();
+        sc.setParameters("jobDispatcher", AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+        sc.setParameters("created", cutTime);
+        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
+        Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
+        return listIncludingRemovedBy(sc, filter);
+    }
+
+    @Override
+    public List<AsyncJobVO> getExpiredCompletedJobs(final Date cutTime, final int limit) {
+        final SearchCriteria<AsyncJobVO> sc = expiringCompletedAsyncJobSearch.create();
+        sc.setParameters(ApiConstants.REMOVED, cutTime);
+        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
+        final Filter filter = new Filter(AsyncJobVO.class, ApiConstants.REMOVED, true, 0L, (long)limit);
+        return listIncludingRemovedBy(sc, filter);
+    }
+
+    @Override
+    @DB
+    public void resetJobProcess(long msid, int jobResultCode, String jobResultMessage) {
+        String sql = "UPDATE async_job SET job_status=?, job_result_code=?, job_result=? where job_status=? AND (job_executing_msid=? OR (job_executing_msid IS NULL AND job_init_msid=?))";
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setInt(1, JobInfo.Status.FAILED.ordinal());
+            pstmt.setInt(2, jobResultCode);
+            pstmt.setString(3, jobResultMessage);
+            pstmt.setInt(4, JobInfo.Status.IN_PROGRESS.ordinal());
+            pstmt.setLong(5, msid);
+            pstmt.setLong(6, msid);
+            pstmt.execute();
+        } catch (SQLException e) {
+            s_logger.warn("Unable to reset job status for management server " + msid, e);
+        } catch (Throwable e) {
+            s_logger.warn("Unable to reset job status for management server " + msid, e);
+        }
+    }
+
+    @Override
+    public List<AsyncJobVO> getResetJobs(long msid) {
+        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
+
+        // construct query: (job_executing_msid=msid OR (job_executing_msid IS NULL AND job_init_msid=msid))
+        SearchCriteria<AsyncJobVO> msQuery = createSearchCriteria();
+        msQuery.addOr("executingMsid", SearchCriteria.Op.EQ, msid);
+        SearchCriteria<AsyncJobVO> initMsQuery = createSearchCriteria();
+        initMsQuery.addAnd("executingMsid", SearchCriteria.Op.NULL);
+        initMsQuery.addAnd("initMsid", SearchCriteria.Op.EQ, msid);
+        msQuery.addOr("initMsid", SearchCriteria.Op.SC, initMsQuery);
+
+        sc.addAnd("executingMsid", SearchCriteria.Op.SC, msQuery);
+
+        Filter filter = new Filter(AsyncJobVO.class, "created", true, null, null);
+        return listIncludingRemovedBy(sc, filter);
+
+    }
+
+    @Override
+    public List<AsyncJobVO> getFailureJobsSinceLastMsStart(long msId, String... cmds) {
+        SearchCriteria<AsyncJobVO> sc = failureMsidAsyncJobSearch.create();
+        sc.setParameters("initMsid", msId);
+        sc.setParameters("status", AsyncJobVO.Status.FAILED);
+        sc.setParameters("job_cmd", (Object[])cmds);
+        return listBy(sc);
+    }
+
+    @Override
+    public long countPendingJobs(String havingInfo, String... cmds) {
+        SearchCriteria<Long> sc = asyncJobTypeSearch.create();
+        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
+        sc.setParameters("job_cmd", (Object[])cmds);
+        sc.setParameters("job_info", "%" + havingInfo + "%");
+        List<Long> results = customSearch(sc, null);
+        return results.get(0);
+    }
+}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDao.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJoinMapDaoImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDao.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDao.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDao.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDaoImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDaoImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/AsyncJobJournalDaoImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueDao.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDao.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueDao.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueDaoImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDao.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDao.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDao.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/SyncQueueItemDaoImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobJoinMapVO.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJournalVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobJournalVO.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobJournalVO.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobJournalVO.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobMBeanImpl.java
diff --git a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
new file mode 100644
index 0000000..378e2f5
--- /dev/null
+++ b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
@@ -0,0 +1,1130 @@
+// 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.framework.jobs.impl;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.storage.dao.VolumeDetailsDao;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.context.CallContext;
+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.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDao;
+import org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageDetector;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.jobs.JobInfo;
+import org.apache.cloudstack.jobs.JobInfo.Status;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.slf4j.MDC;
+
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotDetailsDao;
+import com.cloud.storage.dao.SnapshotDetailsVO;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Predicate;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.DbProperties;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.mgmt.JmxUtil;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.storage.dao.VolumeDao;
+
+public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
+    // Advanced
+    public static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.expire.minutes", "1440",
+        "Time (in minutes) for async-jobs to be kept in system", true, ConfigKey.Scope.Global);
+    public static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.cancel.threshold.minutes", "60",
+        "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, ConfigKey.Scope.Global);
+    private static final ConfigKey<Integer> VmJobLockTimeout = new ConfigKey<Integer>("Advanced",
+            Integer.class, "vm.job.lock.timeout", "1800",
+            "Time in seconds to wait in acquiring lock to submit a vm worker job", false);
+
+    private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
+
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3;     // 3 seconds
+
+    private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
+    private static final int HEARTBEAT_INTERVAL = 2000;
+    private static final int GC_INTERVAL = 10000;                // 10 seconds
+
+    @Inject
+    private SyncQueueItemDao _queueItemDao;
+    @Inject
+    private SyncQueueManager _queueMgr;
+    @Inject
+    private AsyncJobDao _jobDao;
+    @Inject
+    private AsyncJobJournalDao _journalDao;
+    @Inject
+    private AsyncJobJoinMapDao _joinMapDao;
+    @Inject
+    private List<AsyncJobDispatcher> _jobDispatchers;
+    @Inject
+    private MessageBus _messageBus;
+    @Inject
+    private AsyncJobMonitor _jobMonitor;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+    @Inject
+    private VolumeDetailsDao _volumeDetailsDao;
+    @Inject
+    private VolumeDao _volsDao;
+    @Inject
+    private SnapshotDao _snapshotDao;
+    @Inject
+    private SnapshotService snapshotSrv;
+    @Inject
+    private SnapshotDataFactory snapshotFactory;
+    @Inject
+    private SnapshotDetailsDao _snapshotDetailsDao;
+
+    private volatile long _executionRunNumber = 1;
+
+    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
+    private ExecutorService _apiJobExecutor;
+    private ExecutorService _workerJobExecutor;
+
+    @Override
+    public String getConfigComponentName() {
+        return AsyncJobManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes, VmJobLockTimeout};
+    }
+
+    @Override
+    public AsyncJobVO getAsyncJob(long jobId) {
+        return _jobDao.findByIdIncludingRemoved(jobId);
+    }
+
+    @Override
+    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
+        return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
+    }
+
+    @Override
+    @DB
+    public AsyncJob getPseudoJob(long accountId, long userId) {
+        AsyncJobVO job = _jobDao.findPseudoJob(Thread.currentThread().getId(), getMsid());
+        if (job == null) {
+            job = new AsyncJobVO();
+            job.setAccountId(accountId);
+            job.setUserId(userId);
+            job.setInitMsid(getMsid());
+            job.setDispatcher(AsyncJobVO.JOB_DISPATCHER_PSEUDO);
+            job.setInstanceType(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
+            job.setInstanceId(Thread.currentThread().getId());
+            _jobDao.persist(job);
+        }
+        return job;
+    }
+
+    @Override
+    public long submitAsyncJob(AsyncJob job) {
+        return submitAsyncJob(job, false);
+    }
+
+    @SuppressWarnings("unchecked")
+    @DB
+    public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) {
+        @SuppressWarnings("rawtypes")
+        GenericDao dao = GenericDaoBase.getDao(job.getClass());
+        job.setInitMsid(getMsid());
+        job.setSyncSource(null);        // no sync source originally
+        dao.persist(job);
+
+        publishOnEventBus(job, "submit");
+        scheduleExecution(job, scheduleJobExecutionInContext);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("submit async job-" + job.getId() + ", details: " + StringUtils.cleanString(job.toString()));
+        }
+        return job.getId();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    @DB
+    public long submitAsyncJob(final AsyncJob job, final String syncObjType, final long syncObjId) {
+        try {
+            @SuppressWarnings("rawtypes")
+            final GenericDao dao = GenericDaoBase.getDao(job.getClass());
+
+            if (dao == null) {
+                throw new CloudRuntimeException(String.format("Failed to get dao from job's class=%s, for job id=%d, cmd=%s", job.getClass(), job.getId(), job.getCmd()));
+            }
+
+            publishOnEventBus(job, "submit");
+
+            if (!_vmInstanceDao.lockInLockTable(String.valueOf(syncObjId), VmJobLockTimeout.value())){
+                throw new CloudRuntimeException("Failed to acquire lock in submitting async job: " + job.getCmd() + " with timeout value = " + VmJobLockTimeout.value());
+            }
+
+            try {
+                // lock is acquired
+                return Transaction.execute(new TransactionCallback<Long>() {
+                    @Override
+                    public Long doInTransaction(TransactionStatus status) {
+                        job.setInitMsid(getMsid());
+                        dao.persist(job);
+
+                        syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
+                        return job.getId();
+                    }
+                });
+            } finally {
+                _vmInstanceDao.unlockFromLockTable(String.valueOf(syncObjId));
+            }
+        } catch (Exception e) {
+            String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
+            s_logger.warn(errMsg, e);
+            throw new CloudRuntimeException(errMsg);
+        }
+    }
+
+    @Override
+    @DB
+    public void completeAsyncJob(final long jobId, final Status jobStatus, final int resultCode, final String resultObject) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus + ", resultCode: " + resultCode + ", result: " + resultObject);
+        }
+
+        final AsyncJobVO job = _jobDao.findById(jobId);
+        if (job == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus + ", resultCode: " + resultCode + ", result: " +
+                    resultObject);
+            }
+            // still purge item from queue to avoid any blocking
+            _queueMgr.purgeAsyncJobQueueItemId(jobId);
+            return;
+        }
+
+        if (job.getStatus() != JobInfo.Status.IN_PROGRESS) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("job-" + jobId + " is already completed.");
+            }
+            // still purge item from queue to avoid any blocking
+            _queueMgr.purgeAsyncJobQueueItemId(jobId);
+            return;
+        }
+
+        if (resultObject != null) {
+            job.setResult(resultObject);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Publish async job-" + jobId + " complete on message bus");
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Wake up jobs related to job-" + jobId);
+        }
+        final List<Long> wakeupList = Transaction.execute(new TransactionCallback<List<Long>>() {
+            @Override
+            public List<Long> doInTransaction(final TransactionStatus status) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Update db status for job-" + jobId);
+                }
+                job.setCompleteMsid(getMsid());
+                job.setStatus(jobStatus);
+                job.setResultCode(resultCode);
+
+                if (resultObject != null) {
+                    job.setResult(resultObject);
+                } else {
+                    job.setResult(null);
+                }
+
+                final Date currentGMTTime = DateUtil.currentGMTTime();
+                job.setLastUpdated(currentGMTTime);
+                job.setRemoved(currentGMTTime);
+                job.setExecutingMsid(null);
+                _jobDao.update(jobId, job);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Wake up jobs joined with job-" + jobId + " and disjoin all subjobs created from job- " + jobId);
+                }
+                final List<Long> wakeupList = wakeupByJoinedJobCompletion(jobId);
+                _joinMapDao.disjoinAllJobs(jobId);
+
+                // purge the job sync item from queue
+                _queueMgr.purgeAsyncJobQueueItemId(jobId);
+
+                return wakeupList;
+            }
+        });
+
+        publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out
+
+        //
+        // disable wakeup scheduling now, since all API jobs are currently using block-waiting for sub-jobs
+        //
+        /*
+                for (Long id : wakeupList) {
+                    // TODO, we assume that all jobs in this category is API job only
+                    AsyncJobVO jobToWakeup = _jobDao.findById(id);
+                    if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0)
+                        scheduleExecution(jobToWakeup, false);
+                }
+        */
+        _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId);
+    }
+
+    @Override
+    @DB
+    public void updateAsyncJobStatus(final long jobId, final int processStatus, final String resultObject) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus + ", result: " + resultObject);
+        }
+
+        final AsyncJobVO job = _jobDao.findById(jobId);
+        if (job == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus);
+            }
+
+            return;
+        }
+
+        publishOnEventBus(job, "update");
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                job.setProcessStatus(processStatus);
+                if (resultObject != null) {
+                    job.setResult(resultObject);
+                }
+                job.setLastUpdated(DateUtil.currentGMTTime());
+                _jobDao.update(jobId, job);
+            }
+        });
+    }
+
+    @Override
+    @DB
+    public void updateAsyncJobAttachment(final long jobId, final String instanceType, final Long instanceId) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + ", instanceId: " + instanceId);
+        }
+
+        final AsyncJobVO job = _jobDao.findById(jobId);
+        publishOnEventBus(job, "update");
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                AsyncJobVO job = _jobDao.createForUpdate();
+                job.setInstanceType(instanceType);
+                job.setInstanceId(instanceId);
+                job.setLastUpdated(DateUtil.currentGMTTime());
+                _jobDao.update(jobId, job);
+            }
+        });
+    }
+
+    @Override
+    @DB
+    public void logJobJournal(long jobId, AsyncJob.JournalType journalType, String journalText, String journalObjJson) {
+        AsyncJobJournalVO journal = new AsyncJobJournalVO();
+        journal.setJobId(jobId);
+        journal.setJournalType(journalType);
+        journal.setJournalText(journalText);
+        journal.setJournalObjJsonString(journalObjJson);
+
+        _journalDao.persist(journal);
+    }
+
+    @Override
+    @DB
+    public void joinJob(long jobId, long joinJobId) {
+        _joinMapDao.joinJob(jobId, joinJobId, getMsid(), 0, 0, null, null, null);
+    }
+
+    @Override
+    @DB
+    public void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakeupDispatcher, String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds,
+        long timeoutInMilliSeconds) {
+
+        Long syncSourceId = null;
+        AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrentExecutionContext();
+        assert (context.getJob() != null);
+        if (context.getJob().getSyncSource() != null) {
+            syncSourceId = context.getJob().getSyncSource().getQueueId();
+        }
+
+        _joinMapDao.joinJob(jobId, joinJobId, getMsid(), wakeupIntervalInMilliSeconds, timeoutInMilliSeconds, syncSourceId, wakeupHandler, wakeupDispatcher);
+    }
+
+    @Override
+    @DB
+    public void disjoinJob(long jobId, long joinedJobId) {
+        _joinMapDao.disjoinJob(jobId, joinedJobId);
+    }
+
+    @Override
+    @DB
+    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult) {
+        _joinMapDao.completeJoin(joinJobId, joinStatus, joinResult, getMsid());
+    }
+
+    @Override
+    public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Sync job-" + job.getId() + " execution on object " + syncObjType + "." + syncObjId);
+        }
+
+        SyncQueueVO queue = null;
+        queue = _queueMgr.queue(syncObjType, syncObjId, SyncQueueItem.AsyncJobContentType, job.getId(), queueSizeLimit);
+        if (queue == null)
+            throw new CloudRuntimeException("Unable to insert queue item into database, DB is full?");
+    }
+
+    @Override
+    public AsyncJob queryJob(final long jobId, final boolean updatePollTime) {
+        final AsyncJobVO job = _jobDao.findByIdIncludingRemoved(jobId);
+
+        if (updatePollTime) {
+            job.setLastPolled(DateUtil.currentGMTTime());
+            _jobDao.update(jobId, job);
+        }
+        return job;
+    }
+
+    private void scheduleExecution(final AsyncJobVO job) {
+        scheduleExecution(job, false);
+    }
+
+    private void scheduleExecution(final AsyncJob job, boolean executeInContext) {
+        Runnable runnable = getExecutorRunnable(job);
+        if (executeInContext) {
+            runnable.run();
+        } else {
+            if (job.getDispatcher() == null || job.getDispatcher().equalsIgnoreCase("ApiAsyncJobDispatcher"))
+                _apiJobExecutor.submit(runnable);
+            else
+                _workerJobExecutor.submit(runnable);
+        }
+    }
+
+    private AsyncJobDispatcher getDispatcher(String dispatcherName) {
+        assert (dispatcherName != null && !dispatcherName.isEmpty()) : "Who's not setting the dispatcher when submitting a job?  Who am I suppose to call if you do that!";
+
+        for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
+            if (dispatcherName.equals(dispatcher.getName()))
+                return dispatcher;
+        }
+
+        throw new CloudRuntimeException("Unable to find dispatcher name: " + dispatcherName);
+    }
+
+    private AsyncJobDispatcher findWakeupDispatcher(AsyncJob job) {
+        if (_jobDispatchers != null) {
+            List<AsyncJobJoinMapVO> joinRecords = _joinMapDao.listJoinRecords(job.getId());
+            if (joinRecords.size() > 0) {
+                AsyncJobJoinMapVO joinRecord = joinRecords.get(0);
+                for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
+                    if (dispatcher.getName().equals(joinRecord.getWakeupDispatcher()))
+                        return dispatcher;
+                }
+            } else {
+                s_logger.warn("job-" + job.getId() + " is scheduled for wakeup run, but there is no joining info anymore");
+            }
+        }
+        return null;
+    }
+
+    private long getJobRunNumber() {
+        synchronized (this) {
+            return _executionRunNumber++;
+        }
+    }
+
+    private Runnable getExecutorRunnable(final AsyncJob job) {
+        return new ManagedContextRunnable() {
+
+            @Override
+            public void run() {
+                // register place-holder context to avoid installing system account call context
+                if (CallContext.current() == null)
+                    CallContext.registerPlaceHolderContext();
+
+                String related = job.getRelated();
+                String logContext = job.getShortUuid();
+                if (related != null && !related.isEmpty()) {
+                    NDC.push("job-" + related + "/" + "job-" + job.getId());
+                    AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
+                    if (relatedJob != null) {
+                        logContext = relatedJob.getShortUuid();
+                    }
+                } else {
+                    NDC.push("job-" + job.getId());
+                }
+                MDC.put("logcontextid", logContext);
+                try {
+                    super.run();
+                } finally {
+                    NDC.pop();
+                }
+            }
+
+            @Override
+            protected void runInContext() {
+                long runNumber = getJobRunNumber();
+
+                try {
+                    //
+                    // setup execution environment
+                    //
+                    try {
+                        JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
+                    } catch (Exception e) {
+                        // Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean register() call
+                        // is expected to fail under situations
+                        if (s_logger.isTraceEnabled())
+                            s_logger.trace("Unable to register active job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                    }
+
+                    _jobMonitor.registerActiveTask(runNumber, job.getId());
+                    AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
+                    String related = job.getRelated();
+                    String logContext = job.getShortUuid();
+                    if (related != null && !related.isEmpty()) {
+                        AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
+                        if (relatedJob != null) {
+                            logContext = relatedJob.getShortUuid();
+                        }
+                    }
+                    MDC.put("logcontextid", logContext);
+
+                    // execute the job
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Executing " + StringUtils.cleanString(job.toString()));
+                    }
+
+                    if ((getAndResetPendingSignals(job) & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) {
+                        AsyncJobDispatcher jobDispatcher = findWakeupDispatcher(job);
+                        if (jobDispatcher != null) {
+                            jobDispatcher.runJob(job);
+                        } else {
+                            // TODO, job wakeup is not in use yet
+                            if (s_logger.isTraceEnabled())
+                                s_logger.trace("Unable to find a wakeup dispatcher from the joined job: " + job);
+                        }
+                    } else {
+                        AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
+                        if (jobDispatcher != null) {
+                            jobDispatcher.runJob(job);
+                        } else {
+                            s_logger.error("Unable to find job dispatcher, job will be cancelled");
+                            completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+                        }
+                    }
+
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId());
+                    }
+
+                } catch (Throwable e) {
+                    s_logger.error("Unexpected exception", e);
+                    completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
+                } finally {
+                    // guard final clause as well
+                    try {
+                        if (job.getSyncSource() != null) {
+                            // here check queue item one more time to double make sure that queue item is removed in case of any uncaught exception
+                            _queueMgr.purgeItem(job.getSyncSource().getId());
+                        }
+
+                        try {
+                            JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
+                        } catch (Exception e) {
+                            // Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean unregister() call
+                            // is expected to fail under situations
+                            if (s_logger.isTraceEnabled())
+                                s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                        }
+
+                        //
+                        // clean execution environment
+                        //
+                        AsyncJobExecutionContext.unregister();
+                        _jobMonitor.unregisterActiveTask(runNumber);
+
+                    } catch (Throwable e) {
+                        s_logger.error("Double exception", e);
+                    }
+                }
+            }
+        };
+    }
+
+    private int getAndResetPendingSignals(AsyncJob job) {
+        int signals = job.getPendingSignals();
+        if (signals != 0) {
+            AsyncJobVO jobRecord = _jobDao.findById(job.getId());
+            jobRecord.setPendingSignals(0);
+            _jobDao.update(job.getId(), jobRecord);
+        }
+        return signals;
+    }
+
+    private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) {
+        AsyncJobVO job = _jobDao.findById(item.getContentId());
+        if (job != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Schedule queued job-" + job.getId());
+            }
+
+            job.setSyncSource(item);
+
+            //
+            // TODO: a temporary solution to work-around DB deadlock situation
+            //
+            // to live with DB deadlocks, we will give a chance for job to be rescheduled
+            // in case of exceptions (most-likely DB deadlock exceptions)
+            try {
+                job.setExecutingMsid(getMsid());
+                _jobDao.update(job.getId(), job);
+            } catch (Exception e) {
+                s_logger.warn("Unexpected exception while dispatching job-" + item.getContentId(), e);
+
+                try {
+                    _queueMgr.returnItem(item.getId());
+                } catch (Throwable thr) {
+                    s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", thr);
+                }
+            }
+
+            try {
+                scheduleExecution(job);
+            } catch (RejectedExecutionException e) {
+                s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn");
+
+                try {
+                    _queueMgr.returnItem(item.getId());
+                } catch (Exception e2) {
+                    s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", e2);
+                }
+
+                try {
+                    job.setExecutingMsid(null);
+                    _jobDao.update(job.getId(), job);
+                } catch (Exception e3) {
+                    s_logger.warn("Unexpected exception while update job-" + item.getContentId() + " msid for bookkeeping");
+                }
+            }
+
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find related job for queue item: " + item.toString());
+            }
+
+            _queueMgr.purgeItem(item.getId());
+        }
+    }
+
+    @Override
+    public void releaseSyncSource() {
+        AsyncJobExecutionContext executionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        assert (executionContext != null);
+
+        if (executionContext.getSyncSource() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Release sync source for job-" + executionContext.getJob().getId() + " sync source: " + executionContext.getSyncSource().getContentType() +
+                    "-" + executionContext.getSyncSource().getContentId());
+            }
+
+            _queueMgr.purgeItem(executionContext.getSyncSource().getId());
+            checkQueue(executionContext.getSyncSource().getQueueId());
+        }
+    }
+
+    @Override
+    public boolean waitAndCheck(AsyncJob job, String[] wakeupTopicsOnMessageBus, long checkIntervalInMilliSeconds, long timeoutInMiliseconds, Predicate predicate) {
+
+        MessageDetector msgDetector = new MessageDetector();
+        String[] topics = Arrays.copyOf(wakeupTopicsOnMessageBus, wakeupTopicsOnMessageBus.length + 1);
+        topics[topics.length - 1] = AsyncJob.Topics.JOB_STATE;
+
+        msgDetector.open(_messageBus, topics);
+        try {
+            long startTick = System.currentTimeMillis();
+            while (timeoutInMiliseconds < 0 || System.currentTimeMillis() - startTick < timeoutInMiliseconds) {
+                msgDetector.waitAny(checkIntervalInMilliSeconds);
+                job = _jobDao.findById(job.getId());
+                if (job != null && job.getStatus().done()) {
+                    return true;
+                }
+
+                if (predicate.checkCondition()) {
+                    return true;
+                }
+            }
+        } finally {
+            msgDetector.close();
+        }
+
+        return false;
+    }
+
+    @Override
+    public String marshallResultObject(Serializable obj) {
+        if (obj != null)
+            return JobSerializerHelper.toObjectSerializedString(obj);
+
+        return null;
+    }
+
+    @Override
+    public Object unmarshallResultObject(AsyncJob job) {
+        if(job != null && job.getResult() != null)
+            return JobSerializerHelper.fromObjectSerializedString(job.getResult());
+        return null;
+    }
+
+    private void checkQueue(long queueId) {
+        while (true) {
+            try {
+                SyncQueueItemVO item = _queueMgr.dequeueFromOne(queueId, getMsid());
+                if (item != null) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Executing sync queue item: " + item.toString());
+                    }
+
+                    executeQueueItem(item, false);
+                } else {
+                    break;
+                }
+            } catch (Throwable e) {
+                s_logger.error("Unexpected exception when kicking sync queue-" + queueId, e);
+                break;
+            }
+        }
+    }
+
+    private Runnable getHeartbeatTask() {
+        return new ManagedContextRunnable() {
+
+            @Override
+            protected void runInContext() {
+                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerHeartbeat");
+                try {
+                    if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                        try {
+                            reallyRun();
+                        } finally {
+                            scanLock.unlock();
+                        }
+                    }
+                } finally {
+                    scanLock.releaseRef();
+                }
+            }
+
+            protected void reallyRun() {
+                try {
+                    List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
+                    if (l != null && l.size() > 0) {
+                        for (SyncQueueItemVO item : l) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Execute sync-queue item: " + item.toString());
+                            }
+                            executeQueueItem(item, false);
+                        }
+                    }
+
+                    List<Long> standaloneWakeupJobs = wakeupScan();
+                    for (Long jobId : standaloneWakeupJobs) {
+                        // TODO, we assume that all jobs in this category is API job only
+                        AsyncJobVO job = _jobDao.findById(jobId);
+                        if (job != null && (job.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0)
+                            scheduleExecution(job, false);
+                    }
+                } catch (Throwable e) {
+                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
+                }
+            }
+        };
+    }
+
+    @DB
+    private Runnable getGCTask() {
+        return new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC");
+                try {
+                    if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                        try {
+                            reallyRun();
+                        } finally {
+                            scanLock.unlock();
+                        }
+                    }
+                } finally {
+                    scanLock.releaseRef();
+                }
+            }
+
+            public void reallyRun() {
+                try {
+                    s_logger.info("Begin cleanup expired async-jobs");
+
+                    // forcefully cancel blocking queue items if they've been staying there for too long
+                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(JobCancelThresholdMinutes.value() * 60000, false);
+                    if (blockItems != null && blockItems.size() > 0) {
+                        for (SyncQueueItemVO item : blockItems) {
+                            try {
+                                if (item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
+                                    s_logger.info("Remove Job-" + item.getContentId() + " from Queue-" + item.getId() + " since it has been blocked for too long");
+                                    completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long");
+
+                                    _jobMonitor.unregisterByJobId(item.getContentId());
+                                }
+
+                                // purge the item and resume queue processing
+                                _queueMgr.purgeItem(item.getId());
+                            } catch (Throwable e) {
+                                s_logger.error("Unexpected exception when trying to remove job from sync queue, ", e);
+                            }
+                        }
+                    }
+
+                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - JobExpireMinutes.value() * 60000);
+                    // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
+                    // hopefully this will be fast enough to balance potential growth of job table
+                    // 1) Expire unfinished jobs that weren't processed yet
+                    List<AsyncJobVO> unfinishedJobs = _jobDao.getExpiredUnfinishedJobs(cutTime, 100);
+                    for (AsyncJobVO job : unfinishedJobs) {
+                        try {
+                            s_logger.info("Expunging unfinished job-" + job.getId());
+
+                            _jobMonitor.unregisterByJobId(job.getId());
+                            expungeAsyncJob(job);
+                        } catch (Throwable e) {
+                            s_logger.error("Unexpected exception when trying to expunge job-" + job.getId(), e);
+                        }
+                    }
+
+                    // 2) Expunge finished jobs
+                    List<AsyncJobVO> completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100);
+                    for (AsyncJobVO job : completedJobs) {
+                        try {
+                            s_logger.info("Expunging completed job-" + job.getId());
+
+                            expungeAsyncJob(job);
+                        } catch (Throwable e) {
+                            s_logger.error("Unexpected exception when trying to expunge job-" + job.getId(), e);
+                        }
+                    }
+
+                    s_logger.info("End cleanup expired async-jobs");
+                } catch (Throwable e) {
+                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
+                }
+            }
+        };
+    }
+
+    @DB
+    protected void expungeAsyncJob(final AsyncJobVO job) {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                _jobDao.expunge(job.getId());
+                // purge corresponding sync queue item
+                _queueMgr.purgeAsyncJobQueueItemId(job.getId());
+            }
+        });
+    }
+
+    private long getMsid() {
+        return ManagementServerNode.getManagementServerId();
+    }
+
+    @DB
+    protected List<Long> wakeupByJoinedJobCompletion(long joinedJobId) {
+        SearchCriteria<Long> joinJobSC = JoinJobSearch.create("joinJobId", joinedJobId);
+
+        List<Long> result = _joinMapDao.customSearch(joinJobSC, null);
+        if (result.size() > 0) {
+            Collections.sort(result);
+            Long[] ids = result.toArray(new Long[result.size()]);
+
+            final SearchCriteria<AsyncJobVO> jobsSC = JobIdsSearch.create("ids", ids);
+            final SearchCriteria<SyncQueueItemVO> queueItemsSC = QueueJobIdsSearch.create("contentIds", ids);
+
+            AsyncJobVO job = _jobDao.createForUpdate();
+            job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
+            _jobDao.update(job, jobsSC);
+
+            SyncQueueItemVO item = _queueItemDao.createForUpdate();
+            item.setLastProcessNumber(null);
+            item.setLastProcessMsid(null);
+            _queueItemDao.update(item, queueItemsSC);
+        }
+
+        return _joinMapDao.findJobsToWake(joinedJobId);
+    }
+
+    @DB
+    protected List<Long> wakeupScan() {
+        final Date cutDate = DateUtil.currentGMTTime();
+
+        SearchCriteria<Long> sc = JoinJobTimeSearch.create();
+        sc.setParameters("beginTime", cutDate);
+        sc.setParameters("endTime", cutDate);
+
+        final List<Long> result = _joinMapDao.customSearch(sc, null);
+
+        return Transaction.execute(new TransactionCallback<List<Long>>() {
+            @Override
+            public List<Long> doInTransaction(TransactionStatus status) {
+                if (result.size() > 0) {
+                    Collections.sort(result);
+                    Long[] ids = result.toArray(new Long[result.size()]);
+
+                    AsyncJobVO job = _jobDao.createForUpdate();
+                    job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
+
+                    SearchCriteria<AsyncJobVO> sc2 = JobIdsSearch.create("ids", ids);
+                    SearchCriteria<SyncQueueItemVO> queueItemsSC = QueueJobIdsSearch.create("contentIds", ids);
+
+                    _jobDao.update(job, sc2);
+
+                    SyncQueueItemVO item = _queueItemDao.createForUpdate();
+                    item.setLastProcessNumber(null);
+                    item.setLastProcessMsid(null);
+                    _queueItemDao.update(item, queueItemsSC);
+                }
+
+                return _joinMapDao.findJobsToWakeBetween(cutDate);
+            }
+        });
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        try {
+            final Properties dbProps = DbProperties.getDbProperties();
+            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
+
+            int apiPoolSize = cloudMaxActive / 2;
+            int workPoolSize = (cloudMaxActive * 2) / 3;
+
+            s_logger.info("Start AsyncJobManager API executor thread pool in size " + apiPoolSize);
+            _apiJobExecutor = Executors.newFixedThreadPool(apiPoolSize, new NamedThreadFactory(AsyncJobManager.API_JOB_POOL_THREAD_PREFIX));
+
+            s_logger.info("Start AsyncJobManager Work executor thread pool in size " + workPoolSize);
+            _workerJobExecutor = Executors.newFixedThreadPool(workPoolSize, new NamedThreadFactory(AsyncJobManager.WORK_JOB_POOL_THREAD_PREFIX));
+        } catch (final Exception e) {
+            throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
+        }
+
+        JoinJobSearch = _joinMapDao.createSearchBuilder(Long.class);
+        JoinJobSearch.and(JoinJobSearch.entity().getJoinJobId(), Op.EQ, "joinJobId");
+        JoinJobSearch.selectFields(JoinJobSearch.entity().getJobId());
+        JoinJobSearch.done();
+
+        JoinJobTimeSearch = _joinMapDao.createSearchBuilder(Long.class);
+        JoinJobTimeSearch.and(JoinJobTimeSearch.entity().getNextWakeupTime(), Op.LT, "beginTime");
+        JoinJobTimeSearch.and(JoinJobTimeSearch.entity().getExpiration(), Op.GT, "endTime");
+        JoinJobTimeSearch.selectFields(JoinJobTimeSearch.entity().getJobId()).done();
+
+        JobIdsSearch = _jobDao.createSearchBuilder();
+        JobIdsSearch.and(JobIdsSearch.entity().getId(), Op.IN, "ids").done();
+
+        QueueJobIdsSearch = _queueItemDao.createSearchBuilder();
+        QueueJobIdsSearch.and(QueueJobIdsSearch.entity().getContentId(), Op.IN, "contentIds").done();
+
+        JoinJobIdsSearch = _joinMapDao.createSearchBuilder(Long.class);
+        JoinJobIdsSearch.selectFields(JoinJobIdsSearch.entity().getJobId());
+        JoinJobIdsSearch.and(JoinJobIdsSearch.entity().getJoinJobId(), Op.EQ, "joinJobId");
+        JoinJobIdsSearch.and(JoinJobIdsSearch.entity().getJobId(), Op.NIN, "jobIds");
+        JoinJobIdsSearch.done();
+
+        ContentIdsSearch = _queueItemDao.createSearchBuilder(Long.class);
+        ContentIdsSearch.selectFields(ContentIdsSearch.entity().getContentId()).done();
+
+        AsyncJobExecutionContext.init(this, _joinMapDao);
+        OutcomeImpl.init(this);
+
+        return true;
+    }
+
+    private void cleanupLeftOverJobs(final long msid) {
+        try {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    // purge sync queue item running on this ms node
+                    _queueMgr.cleanupActiveQueueItems(msid, true);
+                    // reset job status for all jobs running on this ms node
+                    final List<AsyncJobVO> jobs = _jobDao.getResetJobs(msid);
+                    for (final AsyncJobVO job : jobs) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cancel left-over job-" + job.getId());
+                        }
+                        job.setStatus(JobInfo.Status.FAILED);
+                        job.setResultCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
+                        job.setResult("job cancelled because of management server restart or shutdown");
+                        job.setCompleteMsid(msid);
+                        final Date currentGMTTime = DateUtil.currentGMTTime();
+                        job.setLastUpdated(currentGMTTime);
+                        job.setRemoved(currentGMTTime);
+                        _jobDao.update(job.getId(), job);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Purge queue item for cancelled job-" + job.getId());
+                        }
+                        _queueMgr.purgeAsyncJobQueueItemId(job.getId());
+                        if (ApiCommandJobType.Volume.toString().equals(job.getInstanceType())) {
+
+                            try {
+                                _volumeDetailsDao.removeDetail(job.getInstanceId(), "SNAPSHOT_ID");
+                                _volsDao.remove(job.getInstanceId());
+                            } catch (Exception e) {
+                                s_logger.error("Unexpected exception while removing concurrent request meta data :" + e.getLocalizedMessage());
+                            }
+                        }
+                    }
+                    final List<SnapshotDetailsVO> snapshotList = _snapshotDetailsDao.findDetails(AsyncJob.Constants.MS_ID, Long.toString(msid), false);
+                    for (final SnapshotDetailsVO snapshotDetailsVO : snapshotList) {
+                        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotDetailsVO.getResourceId(), DataStoreRole.Primary);
+                        snapshotSrv.processEventOnSnapshotObject(snapshot, Snapshot.Event.OperationFailed);
+                        _snapshotDetailsDao.removeDetail(snapshotDetailsVO.getResourceId(), AsyncJob.Constants.MS_ID);
+                    }
+                }
+            });
+        } catch (Throwable e) {
+            s_logger.warn("Unexpected exception in cleaning up left over jobs for mamagement server node " + msid, e);
+        }
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (final ManagementServerHost msHost : nodeList) {
+            cleanupLeftOverJobs(msHost.getId());
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public boolean start() {
+        cleanupLeftOverJobs(getMsid());
+
+        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
+        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, GC_INTERVAL, TimeUnit.MILLISECONDS);
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _heartbeatScheduler.shutdown();
+        _apiJobExecutor.shutdown();
+        _workerJobExecutor.shutdown();
+        return true;
+    }
+
+    private GenericSearchBuilder<SyncQueueItemVO, Long> ContentIdsSearch;
+    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobSearch;
+    private SearchBuilder<AsyncJobVO> JobIdsSearch;
+    private SearchBuilder<SyncQueueItemVO> QueueJobIdsSearch;
+    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobIdsSearch;
+    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobTimeSearch;
+
+    protected AsyncJobManagerImpl() {
+        // override default run level for manager components to start this early, otherwise, VirtualMachineManagerImpl will
+        // get stuck in non-initializing job queue
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK);
+    }
+
+    private void publishOnEventBus(AsyncJob job, String jobEvent) {
+        _messageBus.publish(null, AsyncJob.Topics.JOB_EVENT_PUBLISH, PublishScope.LOCAL,
+            new Pair<AsyncJob, String>(job, jobEvent));
+    }
+
+    @Override
+    public List<AsyncJobVO> findFailureAsyncJobs(String... cmds) {
+        return _jobDao.getFailureJobsSinceLastMsStart(getMsid(), cmds);
+    }
+
+    @Override
+    public long countPendingJobs(String havingInfo, String... cmds) {
+        return _jobDao.countPendingJobs(havingInfo, cmds);
+    }
+}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobMonitor.java
diff --git a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
new file mode 100644
index 0000000..9d30c2c
--- /dev/null
+++ b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
@@ -0,0 +1,408 @@
+// 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.framework.jobs.impl;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.jobs.JobInfo;
+
+import com.cloud.utils.UuidUtils;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "async_job")
+@Inheritance(strategy = InheritanceType.JOINED)
+@DiscriminatorColumn(name = "job_type", discriminatorType = DiscriminatorType.STRING, length = 32)
+public class AsyncJobVO implements AsyncJob, JobInfo {
+
+    public static final String JOB_DISPATCHER_PSEUDO = "pseudoJobDispatcher";
+    public static final String PSEUDO_JOB_INSTANCE_TYPE = "Thread";
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "job_type", length = 32)
+    protected String type;
+
+    @Column(name = "job_dispatcher", length = 64)
+    protected String dispatcher;
+
+    @Column(name = "job_pending_signals")
+    protected int pendingSignals;
+
+    @Column(name = "user_id")
+    private long userId;
+
+    @Column(name = "account_id")
+    private long accountId;
+
+    @Column(name = "job_cmd")
+    private String cmd;
+
+    @Column(name = "job_cmd_ver")
+    private int cmdVersion;
+
+    @Column(name = "related")
+    private String related;
+
+    @Column(name = "job_cmd_info", length = 65535)
+    private String cmdInfo;
+
+    @Column(name = "job_status")
+    @Enumerated(value = EnumType.ORDINAL)
+    private Status status;
+
+    @Column(name = "job_process_status")
+    private int processStatus;
+
+    @Column(name = "job_result_code")
+    private int resultCode;
+
+    @Column(name = "job_result", length = 65535)
+    private String result;
+
+    @Column(name = "instance_type", length = 64)
+    private String instanceType;
+
+    @Column(name = "instance_id", length = 64)
+    private Long instanceId;
+
+    @Column(name = "job_init_msid")
+    private Long initMsid;
+
+    @Column(name = "job_complete_msid")
+    private Long completeMsid;
+
+    @Column(name = "job_executing_msid")
+    private Long executingMsid;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name = "last_updated")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date lastUpdated;
+
+    @Column(name = "last_polled")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date lastPolled;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Transient
+    private SyncQueueItem syncSource = null;
+
+    public AsyncJobVO() {
+        uuid = UUID.randomUUID().toString();
+        related = "";
+        status = Status.IN_PROGRESS;
+    }
+
+    public AsyncJobVO(String related, long userId, long accountId, String cmd, String cmdInfo, Long instanceId, String instanceType, String injectedUuid) {
+        this.userId = userId;
+        this.accountId = accountId;
+        this.cmd = cmd;
+        this.cmdInfo = cmdInfo;
+        uuid = ( injectedUuid == null ? UUID.randomUUID().toString() : injectedUuid );
+        this.related = related;
+        this.instanceId = instanceId;
+        this.instanceType = instanceType;
+        status = Status.IN_PROGRESS;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getShortUuid() {
+        return UuidUtils.first(uuid);
+    }
+
+    public void setRelated(String related) {
+        this.related = related;
+    }
+
+    @Override
+    public String getRelated() {
+        return related;
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getDispatcher() {
+        return dispatcher;
+    }
+
+    public void setDispatcher(String dispatcher) {
+        this.dispatcher = dispatcher;
+    }
+
+    @Override
+    public int getPendingSignals() {
+        return pendingSignals;
+    }
+
+    public void setPendingSignals(int signals) {
+        pendingSignals = signals;
+    }
+
+    @Override
+    public long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(long userId) {
+        this.userId = userId;
+    }
+
+    @Override
+    public long getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(long accountId) {
+        this.accountId = accountId;
+    }
+
+    @Override
+    public String getCmd() {
+        return cmd;
+    }
+
+    public void setCmd(String cmd) {
+        this.cmd = cmd;
+    }
+
+    @Override
+    public int getCmdVersion() {
+        return cmdVersion;
+    }
+
+    public void setCmdVersion(int version) {
+        cmdVersion = version;
+    }
+
+    @Override
+    public String getCmdInfo() {
+        return cmdInfo;
+    }
+
+    public void setCmdInfo(String cmdInfo) {
+        this.cmdInfo = cmdInfo;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    @Override
+    public int getProcessStatus() {
+        return processStatus;
+    }
+
+    public void setProcessStatus(int status) {
+        processStatus = status;
+    }
+
+    @Override
+    public int getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(int resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    @Override
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    @Override
+    public Long getInitMsid() {
+        return initMsid;
+    }
+
+    @Override
+    public void setInitMsid(Long initMsid) {
+        this.initMsid = initMsid;
+    }
+
+    @Override
+    public Long getExecutingMsid() {
+        return executingMsid;
+    }
+
+    public void setExecutingMsid(Long executingMsid) {
+        this.executingMsid = executingMsid;
+    }
+
+    @Override
+    public Long getCompleteMsid() {
+        return completeMsid;
+    }
+
+    @Override
+    public void setCompleteMsid(Long completeMsid) {
+        this.completeMsid = completeMsid;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    @Override
+    public Date getLastUpdated() {
+        return lastUpdated;
+    }
+
+    public void setLastUpdated(Date lastUpdated) {
+        this.lastUpdated = lastUpdated;
+    }
+
+    @Override
+    public Date getLastPolled() {
+        return lastPolled;
+    }
+
+    public void setLastPolled(Date lastPolled) {
+        this.lastPolled = lastPolled;
+    }
+
+    @Override
+    public String getInstanceType() {
+        return instanceType;
+    }
+
+    public void setInstanceType(String instanceType) {
+        this.instanceType = instanceType;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return instanceId;
+    }
+
+    public void setInstanceId(Long instanceId) {
+        this.instanceId = instanceId;
+    }
+
+    @Override
+    public SyncQueueItem getSyncSource() {
+        return syncSource;
+    }
+
+    @Override
+    public void setSyncSource(SyncQueueItem syncSource) {
+        this.syncSource = syncSource;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public void setRemoved(final Date removed) {
+        this.removed = removed;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("AsyncJobVO {id:").append(getId());
+        sb.append(", userId: ").append(getUserId());
+        sb.append(", accountId: ").append(getAccountId());
+        sb.append(", instanceType: ").append(getInstanceType());
+        sb.append(", instanceId: ").append(getInstanceId());
+        sb.append(", cmd: ").append(getCmd());
+        sb.append(", cmdInfo: ").append(getCmdInfo());
+        sb.append(", cmdVersion: ").append(getCmdVersion());
+        sb.append(", status: ").append(getStatus());
+        sb.append(", processStatus: ").append(getProcessStatus());
+        sb.append(", resultCode: ").append(getResultCode());
+        sb.append(", result: ").append(getResult());
+        sb.append(", initMsid: ").append(getInitMsid());
+        sb.append(", completeMsid: ").append(getCompleteMsid());
+        sb.append(", lastUpdated: ").append(getLastUpdated());
+        sb.append(", lastPolled: ").append(getLastPolled());
+        sb.append(", created: ").append(getCreated());
+        sb.append(", removed: ").append(getRemoved());
+        sb.append("}");
+        return sb.toString();
+    }
+}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/JobSerializerHelper.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/OutcomeImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueItem.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueItem.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueItem.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueItem.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueItemVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueItemVO.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueItemVO.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueItemVO.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManager.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueManager.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManager.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueManager.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueManagerImpl.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueVO.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/SyncQueueVO.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/SyncQueueVO.java
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/VmWorkJobVO.java b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/VmWorkJobVO.java
similarity index 100%
rename from framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/VmWorkJobVO.java
rename to framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/impl/VmWorkJobVO.java
diff --git a/framework/jobs/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml b/framework/jobs/src/main/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml
similarity index 100%
rename from framework/jobs/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml
rename to framework/jobs/src/main/resources/META-INF/cloudstack/core/spring-framework-jobs-core-context.xml
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
deleted file mode 100644
index bce99d0..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobManager.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under ones
-// 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.framework.jobs;
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.jobs.JobInfo;
-
-import com.cloud.utils.Predicate;
-import com.cloud.utils.component.Manager;
-
-public interface AsyncJobManager extends Manager {
-
-    public static final String API_JOB_POOL_THREAD_PREFIX = "API-Job-Executor";
-    public static final String WORK_JOB_POOL_THREAD_PREFIX = "Work-Job-Executor";
-
-    AsyncJobVO getAsyncJob(long jobId);
-
-    List<? extends AsyncJob> findInstancePendingAsyncJobs(String instanceType, Long accountId);
-
-    long submitAsyncJob(AsyncJob job);
-
-    long submitAsyncJob(AsyncJob job, String syncObjType, long syncObjId);
-
-    void completeAsyncJob(long jobId, JobInfo.Status jobStatus, int resultCode, String result);
-
-    void updateAsyncJobStatus(long jobId, int processStatus, String resultObject);
-
-    void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId);
-    void logJobJournal(long jobId, AsyncJob.JournalType journalType, String
-            journalText, String journalObjJson);
-
-    /**
-     * A running thread inside management server can have a 1:1 linked pseudo job.
-     * This is to help make some legacy code work without too dramatic changes.
-     *
-     * All pseudo jobs should be expunged upon management start event
-     *
-     * @return pseudo job for the thread
-     */
-    AsyncJob getPseudoJob(long accountId, long userId);
-
-    /**
-     * Used by upper level job to wait for completion of a down-level job (usually VmWork jobs)
-     * in synchronous way. Caller needs to use waitAndCheck() to check the completion status
-     * of the down-level job
-     *
-     * Due to the amount of legacy code that relies on synchronous-call semantics, this form of joinJob
-     * is used mostly
-     *
-     *
-     * @param jobId upper job that is going to wait the completion of a down-level job
-     * @param joinJobId down-level job
-     */
-    void joinJob(long jobId, long joinJobId);
-
-    /**
-     * Used by upper level job to wait for completion of a down-level job (usually VmWork jobs)
-     * in asynchronous way, it will cause upper job to cease current execution, upper job will be
-     * rescheduled to execute periodically or on wakeup events detected from message bus
-     *
-     * @param jobId upper job that is going to wait the completion of a down-level job
-     * @param joinJobId down-level job
-     * @Param wakeupHandler    wake-up handler
-     * @Param wakeupDispatcher wake-up dispatcher
-     * @param wakeupTopicsOnMessageBus
-     * @param wakeupIntervalInMilliSeconds
-     * @param timeoutInMilliSeconds
-     */
-    void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakupDispatcher,
-            String[] wakeupTopicsOnMessageBus, long wakeupIntervalInMilliSeconds, long timeoutInMilliSeconds);
-
-    /**
-     * Dis-join two related jobs
-     *
-     * @param jobId
-     * @param joinedJobId
-     */
-    void disjoinJob(long jobId, long joinedJobId);
-
-    /**
-     * Used by down-level job to notify its completion to upper level jobs
-     *
-     * @param joinJobId down-level job for upper level job to join with
-     * @param joinStatus AsyncJobConstants status code to indicate success or failure of the
-     *                     down-level job
-     * @param joinResult object-stream serialized result object
-     *                     this is primarily used by down-level job to pass error exception objects
-     *                     for legacy code to work. To help pass exception object easier, we use
-     *                     object-stream based serialization instead of GSON
-     */
-    void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult);
-
-    void releaseSyncSource();
-
-    void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit);
-
-    /**
-     * This method will be deprecated after all code has been migrated to fully-asynchronous mode
-     * that uses async-feature of joinJob/disjoinJob
-     *
-     * @param wakupTopicsOnMessageBus topic on message bus to wakeup the wait
-     * @param checkIntervalInMilliSeconds time to break out wait for checking predicate condition
-     * @param timeoutInMiliseconds time out to break out the whole wait process
-     * @param predicate
-     * @return true, predicate condition is satisfied
-     *             false, wait is timed out
-     */
-    boolean waitAndCheck(AsyncJob job, String[] wakupTopicsOnMessageBus, long checkIntervalInMilliSeconds, long timeoutInMiliseconds, Predicate predicate);
-
-    AsyncJob queryJob(long jobId, boolean updatePollTime);
-
-    String marshallResultObject(Serializable obj);
-
-    Object unmarshallResultObject(AsyncJob job);
-
-    List<AsyncJobVO> findFailureAsyncJobs(String... cmds);
-}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java
deleted file mode 100644
index 8778bef..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDao.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.jobs.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface AsyncJobDao extends GenericDao<AsyncJobVO, Long> {
-    AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
-
-    List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId);
-
-    AsyncJobVO findPseudoJob(long threadId, long msid);
-
-    void cleanupPseduoJobs(long msid);
-
-    List<AsyncJobVO> getExpiredJobs(Date cutTime, int limit);
-
-    List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit);
-
-    void resetJobProcess(long msid, int jobResultCode, String jobResultMessage);
-
-    List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit);
-
-    List<AsyncJobVO> getResetJobs(long msid);
-
-    List<AsyncJobVO> getFailureJobsSinceLastMsStart(long msId, String... cmds);
-}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
deleted file mode 100644
index 0ccd4ad..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/AsyncJobDaoImpl.java
+++ /dev/null
@@ -1,229 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.jobs.dao;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.jobs.JobInfo;
-
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.TransactionLegacy;
-
-public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements AsyncJobDao {
-    private static final Logger s_logger = Logger.getLogger(AsyncJobDaoImpl.class.getName());
-
-    private final SearchBuilder<AsyncJobVO> pendingAsyncJobSearch;
-    private final SearchBuilder<AsyncJobVO> pendingAsyncJobsSearch;
-    private final SearchBuilder<AsyncJobVO> expiringAsyncJobSearch;
-    private final SearchBuilder<AsyncJobVO> pseudoJobSearch;
-    private final SearchBuilder<AsyncJobVO> pseudoJobCleanupSearch;
-    private final SearchBuilder<AsyncJobVO> expiringUnfinishedAsyncJobSearch;
-    private final SearchBuilder<AsyncJobVO> expiringCompletedAsyncJobSearch;
-    private final SearchBuilder<AsyncJobVO> failureMsidAsyncJobSearch;
-
-    public AsyncJobDaoImpl() {
-        pendingAsyncJobSearch = createSearchBuilder();
-        pendingAsyncJobSearch.and("instanceType", pendingAsyncJobSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
-        pendingAsyncJobSearch.and("instanceId", pendingAsyncJobSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
-        pendingAsyncJobSearch.and("status", pendingAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        pendingAsyncJobSearch.done();
-
-        expiringAsyncJobSearch = createSearchBuilder();
-        expiringAsyncJobSearch.and("created", expiringAsyncJobSearch.entity().getCreated(), SearchCriteria.Op.LTEQ);
-        expiringAsyncJobSearch.done();
-
-        pendingAsyncJobsSearch = createSearchBuilder();
-        pendingAsyncJobsSearch.and("instanceType", pendingAsyncJobsSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
-        pendingAsyncJobsSearch.and("accountId", pendingAsyncJobsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        pendingAsyncJobsSearch.and("status", pendingAsyncJobsSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        pendingAsyncJobsSearch.done();
-
-        expiringUnfinishedAsyncJobSearch = createSearchBuilder();
-        expiringUnfinishedAsyncJobSearch.and("jobDispatcher", expiringUnfinishedAsyncJobSearch.entity().getDispatcher(), SearchCriteria.Op.NEQ);
-        expiringUnfinishedAsyncJobSearch.and("created", expiringUnfinishedAsyncJobSearch.entity().getCreated(), SearchCriteria.Op.LTEQ);
-        expiringUnfinishedAsyncJobSearch.and("completeMsId", expiringUnfinishedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NULL);
-        expiringUnfinishedAsyncJobSearch.and("jobStatus", expiringUnfinishedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        expiringUnfinishedAsyncJobSearch.done();
-
-        expiringCompletedAsyncJobSearch = createSearchBuilder();
-        expiringCompletedAsyncJobSearch.and("created", expiringCompletedAsyncJobSearch.entity().getCreated(), SearchCriteria.Op.LTEQ);
-        expiringCompletedAsyncJobSearch.and("completeMsId", expiringCompletedAsyncJobSearch.entity().getCompleteMsid(), SearchCriteria.Op.NNULL);
-        expiringCompletedAsyncJobSearch.and("jobStatus", expiringCompletedAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.NEQ);
-        expiringCompletedAsyncJobSearch.done();
-
-        pseudoJobSearch = createSearchBuilder();
-        pseudoJobSearch.and("jobDispatcher", pseudoJobSearch.entity().getDispatcher(), Op.EQ);
-        pseudoJobSearch.and("instanceType", pseudoJobSearch.entity().getInstanceType(), Op.EQ);
-        pseudoJobSearch.and("instanceId", pseudoJobSearch.entity().getInstanceId(), Op.EQ);
-        pseudoJobSearch.done();
-
-        pseudoJobCleanupSearch = createSearchBuilder();
-        pseudoJobCleanupSearch.and("initMsid", pseudoJobCleanupSearch.entity().getInitMsid(), Op.EQ);
-        pseudoJobCleanupSearch.done();
-
-        failureMsidAsyncJobSearch = createSearchBuilder();
-        failureMsidAsyncJobSearch.and("initMsid", failureMsidAsyncJobSearch.entity().getInitMsid(), Op.EQ);
-        failureMsidAsyncJobSearch.and("instanceType", failureMsidAsyncJobSearch.entity().getInstanceType(), SearchCriteria.Op.EQ);
-        failureMsidAsyncJobSearch.and("status", failureMsidAsyncJobSearch.entity().getStatus(), SearchCriteria.Op.EQ);
-        failureMsidAsyncJobSearch.and("job_cmd", failureMsidAsyncJobSearch.entity().getCmd(), Op.IN);
-        failureMsidAsyncJobSearch.done();
-
-    }
-
-    @Override
-    public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
-        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
-        sc.setParameters("instanceType", instanceType);
-        sc.setParameters("instanceId", instanceId);
-        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
-
-        List<AsyncJobVO> l = listIncludingRemovedBy(sc);
-        if (l != null && l.size() > 0) {
-            if (l.size() > 1) {
-                s_logger.warn("Instance " + instanceType + "-" + instanceId + " has multiple pending async-job");
-            }
-
-            return l.get(0);
-        }
-        return null;
-    }
-
-    @Override
-    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
-        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobsSearch.create();
-        sc.setParameters("instanceType", instanceType);
-
-        if (accountId != null) {
-            sc.setParameters("accountId", accountId);
-        }
-        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
-
-        return listBy(sc);
-    }
-
-    @Override
-    public AsyncJobVO findPseudoJob(long threadId, long msid) {
-        SearchCriteria<AsyncJobVO> sc = pseudoJobSearch.create();
-        sc.setParameters("jobDispatcher", AsyncJobVO.JOB_DISPATCHER_PSEUDO);
-        sc.setParameters("instanceType", AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
-        sc.setParameters("instanceId", threadId);
-
-        List<AsyncJobVO> result = listBy(sc);
-        if (result != null && result.size() > 0) {
-            assert (result.size() == 1);
-            return result.get(0);
-        }
-
-        return null;
-    }
-
-    @Override
-    public void cleanupPseduoJobs(long msid) {
-        SearchCriteria<AsyncJobVO> sc = pseudoJobCleanupSearch.create();
-        sc.setParameters("initMsid", msid);
-        this.expunge(sc);
-    }
-
-    @Override
-    public List<AsyncJobVO> getExpiredJobs(Date cutTime, int limit) {
-        SearchCriteria<AsyncJobVO> sc = expiringAsyncJobSearch.create();
-        sc.setParameters("created", cutTime);
-        Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
-        return listIncludingRemovedBy(sc, filter);
-    }
-
-    @Override
-    public List<AsyncJobVO> getExpiredUnfinishedJobs(Date cutTime, int limit) {
-        SearchCriteria<AsyncJobVO> sc = expiringUnfinishedAsyncJobSearch.create();
-        sc.setParameters("jobDispatcher", AsyncJobVO.JOB_DISPATCHER_PSEUDO);
-        sc.setParameters("created", cutTime);
-        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
-        Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
-        return listIncludingRemovedBy(sc, filter);
-    }
-
-    @Override
-    public List<AsyncJobVO> getExpiredCompletedJobs(Date cutTime, int limit) {
-        SearchCriteria<AsyncJobVO> sc = expiringCompletedAsyncJobSearch.create();
-        sc.setParameters("created", cutTime);
-        sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
-        Filter filter = new Filter(AsyncJobVO.class, "created", true, 0L, (long)limit);
-        return listIncludingRemovedBy(sc, filter);
-    }
-
-    @Override
-    @DB
-    public void resetJobProcess(long msid, int jobResultCode, String jobResultMessage) {
-        String sql = "UPDATE async_job SET job_status=?, job_result_code=?, job_result=? where job_status=? AND (job_executing_msid=? OR (job_executing_msid IS NULL AND job_init_msid=?))";
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement pstmt = null;
-        try {
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setInt(1, JobInfo.Status.FAILED.ordinal());
-            pstmt.setInt(2, jobResultCode);
-            pstmt.setString(3, jobResultMessage);
-            pstmt.setInt(4, JobInfo.Status.IN_PROGRESS.ordinal());
-            pstmt.setLong(5, msid);
-            pstmt.setLong(6, msid);
-            pstmt.execute();
-        } catch (SQLException e) {
-            s_logger.warn("Unable to reset job status for management server " + msid, e);
-        } catch (Throwable e) {
-            s_logger.warn("Unable to reset job status for management server " + msid, e);
-        }
-    }
-
-    @Override
-    public List<AsyncJobVO> getResetJobs(long msid) {
-        SearchCriteria<AsyncJobVO> sc = pendingAsyncJobSearch.create();
-        sc.setParameters("status", JobInfo.Status.IN_PROGRESS);
-
-        // construct query: (job_executing_msid=msid OR (job_executing_msid IS NULL AND job_init_msid=msid))
-        SearchCriteria<AsyncJobVO> msQuery = createSearchCriteria();
-        msQuery.addOr("executingMsid", SearchCriteria.Op.EQ, msid);
-        SearchCriteria<AsyncJobVO> initMsQuery = createSearchCriteria();
-        initMsQuery.addAnd("executingMsid", SearchCriteria.Op.NULL);
-        initMsQuery.addAnd("initMsid", SearchCriteria.Op.EQ, msid);
-        msQuery.addOr("initMsid", SearchCriteria.Op.SC, initMsQuery);
-
-        sc.addAnd("executingMsid", SearchCriteria.Op.SC, msQuery);
-
-        Filter filter = new Filter(AsyncJobVO.class, "created", true, null, null);
-        return listIncludingRemovedBy(sc, filter);
-
-    }
-
-    @Override
-    public List<AsyncJobVO> getFailureJobsSinceLastMsStart(long msId, String... cmds) {
-        SearchCriteria<AsyncJobVO> sc = failureMsidAsyncJobSearch.create();
-        sc.setParameters("initMsid", msId);
-        sc.setParameters("status", AsyncJobVO.Status.FAILED);
-        sc.setParameters("job_cmd", (Object[])cmds);
-        return listBy(sc);
-    }
-}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
deleted file mode 100644
index 3ce96a6..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java
+++ /dev/null
@@ -1,1120 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.framework.jobs.impl;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.storage.dao.VolumeDetailsDao;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.context.CallContext;
-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.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDao;
-import org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageDetector;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.jobs.JobInfo;
-import org.apache.cloudstack.jobs.JobInfo.Status;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.slf4j.MDC;
-
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotDetailsDao;
-import com.cloud.storage.dao.SnapshotDetailsVO;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Predicate;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.DbProperties;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.mgmt.JmxUtil;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.storage.dao.VolumeDao;
-
-public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
-    // Advanced
-    public static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.expire.minutes", "1440",
-        "Time (in minutes) for async-jobs to be kept in system", true, ConfigKey.Scope.Global);
-    public static final ConfigKey<Long> JobCancelThresholdMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.cancel.threshold.minutes", "60",
-        "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", true, ConfigKey.Scope.Global);
-    private static final ConfigKey<Integer> VmJobLockTimeout = new ConfigKey<Integer>("Advanced",
-            Integer.class, "vm.job.lock.timeout", "1800",
-            "Time in seconds to wait in acquiring lock to submit a vm worker job", false);
-
-    private static final Logger s_logger = Logger.getLogger(AsyncJobManagerImpl.class);
-
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3;     // 3 seconds
-
-    private static final int MAX_ONETIME_SCHEDULE_SIZE = 50;
-    private static final int HEARTBEAT_INTERVAL = 2000;
-    private static final int GC_INTERVAL = 10000;                // 10 seconds
-
-    @Inject
-    private SyncQueueItemDao _queueItemDao;
-    @Inject
-    private SyncQueueManager _queueMgr;
-    @Inject
-    private AsyncJobDao _jobDao;
-    @Inject
-    private AsyncJobJournalDao _journalDao;
-    @Inject
-    private AsyncJobJoinMapDao _joinMapDao;
-    @Inject
-    private List<AsyncJobDispatcher> _jobDispatchers;
-    @Inject
-    private MessageBus _messageBus;
-    @Inject
-    private AsyncJobMonitor _jobMonitor;
-    @Inject
-    private VMInstanceDao _vmInstanceDao;
-    @Inject
-    private VolumeDetailsDao _volumeDetailsDao;
-    @Inject
-    private VolumeDao _volsDao;
-    @Inject
-    private SnapshotDao _snapshotDao;
-    @Inject
-    private SnapshotService snapshotSrv;
-    @Inject
-    private SnapshotDataFactory snapshotFactory;
-    @Inject
-    private SnapshotDetailsDao _snapshotDetailsDao;
-
-    private volatile long _executionRunNumber = 1;
-
-    private final ScheduledExecutorService _heartbeatScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat"));
-    private ExecutorService _apiJobExecutor;
-    private ExecutorService _workerJobExecutor;
-
-    @Override
-    public String getConfigComponentName() {
-        return AsyncJobManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {JobExpireMinutes, JobCancelThresholdMinutes, VmJobLockTimeout};
-    }
-
-    @Override
-    public AsyncJobVO getAsyncJob(long jobId) {
-        return _jobDao.findById(jobId);
-    }
-
-    @Override
-    public List<AsyncJobVO> findInstancePendingAsyncJobs(String instanceType, Long accountId) {
-        return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
-    }
-
-    @Override
-    @DB
-    public AsyncJob getPseudoJob(long accountId, long userId) {
-        AsyncJobVO job = _jobDao.findPseudoJob(Thread.currentThread().getId(), getMsid());
-        if (job == null) {
-            job = new AsyncJobVO();
-            job.setAccountId(accountId);
-            job.setUserId(userId);
-            job.setInitMsid(getMsid());
-            job.setDispatcher(AsyncJobVO.JOB_DISPATCHER_PSEUDO);
-            job.setInstanceType(AsyncJobVO.PSEUDO_JOB_INSTANCE_TYPE);
-            job.setInstanceId(Thread.currentThread().getId());
-            _jobDao.persist(job);
-        }
-        return job;
-    }
-
-    @Override
-    public long submitAsyncJob(AsyncJob job) {
-        return submitAsyncJob(job, false);
-    }
-
-    @SuppressWarnings("unchecked")
-    @DB
-    public long submitAsyncJob(AsyncJob job, boolean scheduleJobExecutionInContext) {
-        @SuppressWarnings("rawtypes")
-        GenericDao dao = GenericDaoBase.getDao(job.getClass());
-        job.setInitMsid(getMsid());
-        job.setSyncSource(null);        // no sync source originally
-        dao.persist(job);
-
-        publishOnEventBus(job, "submit");
-        scheduleExecution(job, scheduleJobExecutionInContext);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("submit async job-" + job.getId() + ", details: " + StringUtils.cleanString(job.toString()));
-        }
-        return job.getId();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    @DB
-    public long submitAsyncJob(final AsyncJob job, final String syncObjType, final long syncObjId) {
-        try {
-            @SuppressWarnings("rawtypes")
-            final GenericDao dao = GenericDaoBase.getDao(job.getClass());
-
-            if (dao == null) {
-                throw new CloudRuntimeException(String.format("Failed to get dao from job's class=%s, for job id=%d, cmd=%s", job.getClass(), job.getId(), job.getCmd()));
-            }
-
-            publishOnEventBus(job, "submit");
-
-            if (!_vmInstanceDao.lockInLockTable(String.valueOf(syncObjId), VmJobLockTimeout.value())){
-                throw new CloudRuntimeException("Failed to acquire lock in submitting async job: " + job.getCmd() + " with timeout value = " + VmJobLockTimeout.value());
-            }
-
-            try {
-                // lock is acquired
-                return Transaction.execute(new TransactionCallback<Long>() {
-                    @Override
-                    public Long doInTransaction(TransactionStatus status) {
-                        job.setInitMsid(getMsid());
-                        dao.persist(job);
-
-                        syncAsyncJobExecution(job, syncObjType, syncObjId, 1);
-                        return job.getId();
-                    }
-                });
-            } finally {
-                _vmInstanceDao.unlockFromLockTable(String.valueOf(syncObjId));
-            }
-        } catch (Exception e) {
-            String errMsg = "Unable to schedule async job for command " + job.getCmd() + ", unexpected exception.";
-            s_logger.warn(errMsg, e);
-            throw new CloudRuntimeException(errMsg);
-        }
-    }
-
-    @Override
-    @DB
-    public void completeAsyncJob(final long jobId, final Status jobStatus, final int resultCode, final String resultObject) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Complete async job-" + jobId + ", jobStatus: " + jobStatus + ", resultCode: " + resultCode + ", result: " + resultObject);
-        }
-
-        final AsyncJobVO job = _jobDao.findById(jobId);
-        if (job == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("job-" + jobId + " no longer exists, we just log completion info here. " + jobStatus + ", resultCode: " + resultCode + ", result: " +
-                    resultObject);
-            }
-            // still purge item from queue to avoid any blocking
-            _queueMgr.purgeAsyncJobQueueItemId(jobId);
-            return;
-        }
-
-        if (job.getStatus() != JobInfo.Status.IN_PROGRESS) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("job-" + jobId + " is already completed.");
-            }
-            // still purge item from queue to avoid any blocking
-            _queueMgr.purgeAsyncJobQueueItemId(jobId);
-            return;
-        }
-
-        if (resultObject != null) {
-            job.setResult(resultObject);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Publish async job-" + jobId + " complete on message bus");
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Wake up jobs related to job-" + jobId);
-        }
-        List<Long> wakeupList = Transaction.execute(new TransactionCallback<List<Long>>() {
-            @Override
-            public List<Long> doInTransaction(TransactionStatus status) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Update db status for job-" + jobId);
-                }
-                job.setCompleteMsid(getMsid());
-                job.setStatus(jobStatus);
-                job.setResultCode(resultCode);
-
-                if (resultObject != null) {
-                    job.setResult(resultObject);
-                } else {
-                    job.setResult(null);
-                }
-
-                job.setLastUpdated(DateUtil.currentGMTTime());
-                job.setExecutingMsid(null);
-                _jobDao.update(jobId, job);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Wake up jobs joined with job-" + jobId + " and disjoin all subjobs created from job- " + jobId);
-                }
-                List<Long> wakeupList = wakeupByJoinedJobCompletion(jobId);
-                _joinMapDao.disjoinAllJobs(jobId);
-
-                // purge the job sync item from queue
-                _queueMgr.purgeAsyncJobQueueItemId(jobId);
-
-                return wakeupList;
-            }
-        });
-
-        publishOnEventBus(job, "complete"); // publish before the instance type and ID are wiped out
-
-        //
-        // disable wakeup scheduling now, since all API jobs are currently using block-waiting for sub-jobs
-        //
-        /*
-                for (Long id : wakeupList) {
-                    // TODO, we assume that all jobs in this category is API job only
-                    AsyncJobVO jobToWakeup = _jobDao.findById(id);
-                    if (jobToWakeup != null && (jobToWakeup.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0)
-                        scheduleExecution(jobToWakeup, false);
-                }
-        */
-        _messageBus.publish(null, AsyncJob.Topics.JOB_STATE, PublishScope.GLOBAL, jobId);
-    }
-
-    @Override
-    @DB
-    public void updateAsyncJobStatus(final long jobId, final int processStatus, final String resultObject) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Update async-job progress, job-" + jobId + ", processStatus: " + processStatus + ", result: " + resultObject);
-        }
-
-        final AsyncJobVO job = _jobDao.findById(jobId);
-        if (job == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("job-" + jobId + " no longer exists, we just log progress info here. progress status: " + processStatus);
-            }
-
-            return;
-        }
-
-        publishOnEventBus(job, "update");
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                job.setProcessStatus(processStatus);
-                if (resultObject != null) {
-                    job.setResult(resultObject);
-                }
-                job.setLastUpdated(DateUtil.currentGMTTime());
-                _jobDao.update(jobId, job);
-            }
-        });
-    }
-
-    @Override
-    @DB
-    public void updateAsyncJobAttachment(final long jobId, final String instanceType, final Long instanceId) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + ", instanceId: " + instanceId);
-        }
-
-        final AsyncJobVO job = _jobDao.findById(jobId);
-        publishOnEventBus(job, "update");
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                AsyncJobVO job = _jobDao.createForUpdate();
-                job.setInstanceType(instanceType);
-                job.setInstanceId(instanceId);
-                job.setLastUpdated(DateUtil.currentGMTTime());
-                _jobDao.update(jobId, job);
-            }
-        });
-    }
-
-    @Override
-    @DB
-    public void logJobJournal(long jobId, AsyncJob.JournalType journalType, String journalText, String journalObjJson) {
-        AsyncJobJournalVO journal = new AsyncJobJournalVO();
-        journal.setJobId(jobId);
-        journal.setJournalType(journalType);
-        journal.setJournalText(journalText);
-        journal.setJournalObjJsonString(journalObjJson);
-
-        _journalDao.persist(journal);
-    }
-
-    @Override
-    @DB
-    public void joinJob(long jobId, long joinJobId) {
-        _joinMapDao.joinJob(jobId, joinJobId, getMsid(), 0, 0, null, null, null);
-    }
-
-    @Override
-    @DB
-    public void joinJob(long jobId, long joinJobId, String wakeupHandler, String wakeupDispatcher, String[] wakeupTopcisOnMessageBus, long wakeupIntervalInMilliSeconds,
-        long timeoutInMilliSeconds) {
-
-        Long syncSourceId = null;
-        AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrentExecutionContext();
-        assert (context.getJob() != null);
-        if (context.getJob().getSyncSource() != null) {
-            syncSourceId = context.getJob().getSyncSource().getQueueId();
-        }
-
-        _joinMapDao.joinJob(jobId, joinJobId, getMsid(), wakeupIntervalInMilliSeconds, timeoutInMilliSeconds, syncSourceId, wakeupHandler, wakeupDispatcher);
-    }
-
-    @Override
-    @DB
-    public void disjoinJob(long jobId, long joinedJobId) {
-        _joinMapDao.disjoinJob(jobId, joinedJobId);
-    }
-
-    @Override
-    @DB
-    public void completeJoin(long joinJobId, JobInfo.Status joinStatus, String joinResult) {
-        _joinMapDao.completeJoin(joinJobId, joinStatus, joinResult, getMsid());
-    }
-
-    @Override
-    public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Sync job-" + job.getId() + " execution on object " + syncObjType + "." + syncObjId);
-        }
-
-        SyncQueueVO queue = null;
-        queue = _queueMgr.queue(syncObjType, syncObjId, SyncQueueItem.AsyncJobContentType, job.getId(), queueSizeLimit);
-        if (queue == null)
-            throw new CloudRuntimeException("Unable to insert queue item into database, DB is full?");
-    }
-
-    @Override
-    public AsyncJob queryJob(long jobId, boolean updatePollTime) {
-        AsyncJobVO job = _jobDao.findById(jobId);
-
-        if (updatePollTime) {
-            job.setLastPolled(DateUtil.currentGMTTime());
-            _jobDao.update(jobId, job);
-        }
-        return job;
-    }
-
-    private void scheduleExecution(final AsyncJobVO job) {
-        scheduleExecution(job, false);
-    }
-
-    private void scheduleExecution(final AsyncJob job, boolean executeInContext) {
-        Runnable runnable = getExecutorRunnable(job);
-        if (executeInContext) {
-            runnable.run();
-        } else {
-            if (job.getDispatcher() == null || job.getDispatcher().equalsIgnoreCase("ApiAsyncJobDispatcher"))
-                _apiJobExecutor.submit(runnable);
-            else
-                _workerJobExecutor.submit(runnable);
-        }
-    }
-
-    private AsyncJobDispatcher getDispatcher(String dispatcherName) {
-        assert (dispatcherName != null && !dispatcherName.isEmpty()) : "Who's not setting the dispatcher when submitting a job?  Who am I suppose to call if you do that!";
-
-        for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
-            if (dispatcherName.equals(dispatcher.getName()))
-                return dispatcher;
-        }
-
-        throw new CloudRuntimeException("Unable to find dispatcher name: " + dispatcherName);
-    }
-
-    private AsyncJobDispatcher getWakeupDispatcher(AsyncJob job) {
-        if (_jobDispatchers != null) {
-            List<AsyncJobJoinMapVO> joinRecords = _joinMapDao.listJoinRecords(job.getId());
-            if (joinRecords.size() > 0) {
-                AsyncJobJoinMapVO joinRecord = joinRecords.get(0);
-                for (AsyncJobDispatcher dispatcher : _jobDispatchers) {
-                    if (dispatcher.getName().equals(joinRecord.getWakeupDispatcher()))
-                        return dispatcher;
-                }
-            } else {
-                s_logger.warn("job-" + job.getId() + " is scheduled for wakeup run, but there is no joining info anymore");
-            }
-        }
-        return null;
-    }
-
-    private long getJobRunNumber() {
-        synchronized (this) {
-            return _executionRunNumber++;
-        }
-    }
-
-    private Runnable getExecutorRunnable(final AsyncJob job) {
-        return new ManagedContextRunnable() {
-
-            @Override
-            public void run() {
-                // register place-holder context to avoid installing system account call context
-                if (CallContext.current() == null)
-                    CallContext.registerPlaceHolderContext();
-
-                String related = job.getRelated();
-                String logContext = job.getShortUuid();
-                if (related != null && !related.isEmpty()) {
-                    NDC.push("job-" + related + "/" + "job-" + job.getId());
-                    AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
-                    if (relatedJob != null) {
-                        logContext = relatedJob.getShortUuid();
-                    }
-                } else {
-                    NDC.push("job-" + job.getId());
-                }
-                MDC.put("logcontextid", logContext);
-                try {
-                    super.run();
-                } finally {
-                    NDC.pop();
-                }
-            }
-
-            @Override
-            protected void runInContext() {
-                long runNumber = getJobRunNumber();
-
-                try {
-                    //
-                    // setup execution environment
-                    //
-                    try {
-                        JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
-                    } catch (Exception e) {
-                        // Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean register() call
-                        // is expected to fail under situations
-                        if (s_logger.isTraceEnabled())
-                            s_logger.trace("Unable to register active job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                    }
-
-                    _jobMonitor.registerActiveTask(runNumber, job.getId());
-                    AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
-                    String related = job.getRelated();
-                    String logContext = job.getShortUuid();
-                    if (related != null && !related.isEmpty()) {
-                        AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
-                        if (relatedJob != null) {
-                            logContext = relatedJob.getShortUuid();
-                        }
-                    }
-                    MDC.put("logcontextid", logContext);
-
-                    // execute the job
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Executing " + StringUtils.cleanString(job.toString()));
-                    }
-
-                    if ((getAndResetPendingSignals(job) & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) {
-                        AsyncJobDispatcher jobDispatcher = getWakeupDispatcher(job);
-                        if (jobDispatcher != null) {
-                            jobDispatcher.runJob(job);
-                        } else {
-                            // TODO, job wakeup is not in use yet
-                            if (s_logger.isTraceEnabled())
-                                s_logger.trace("Unable to find a wakeup dispatcher from the joined job: " + job);
-                        }
-                    } else {
-                        AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
-                        if (jobDispatcher != null) {
-                            jobDispatcher.runJob(job);
-                        } else {
-                            s_logger.error("Unable to find job dispatcher, job will be cancelled");
-                            completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
-                        }
-                    }
-
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId());
-                    }
-
-                } catch (Throwable e) {
-                    s_logger.error("Unexpected exception", e);
-                    completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), null);
-                } finally {
-                    // guard final clause as well
-                    try {
-                        if (job.getSyncSource() != null) {
-                            // here check queue item one more time to double make sure that queue item is removed in case of any uncaught exception
-                            _queueMgr.purgeItem(job.getSyncSource().getId());
-                        }
-
-                        try {
-                            JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
-                        } catch (Exception e) {
-                            // Due to co-existence of normal-dispatched-job/wakeup-dispatched-job, MBean unregister() call
-                            // is expected to fail under situations
-                            if (s_logger.isTraceEnabled())
-                                s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                        }
-
-                        //
-                        // clean execution environment
-                        //
-                        AsyncJobExecutionContext.unregister();
-                        _jobMonitor.unregisterActiveTask(runNumber);
-
-                    } catch (Throwable e) {
-                        s_logger.error("Double exception", e);
-                    }
-                }
-            }
-        };
-    }
-
-    private int getAndResetPendingSignals(AsyncJob job) {
-        int signals = job.getPendingSignals();
-        if (signals != 0) {
-            AsyncJobVO jobRecord = _jobDao.findById(job.getId());
-            jobRecord.setPendingSignals(0);
-            _jobDao.update(job.getId(), jobRecord);
-        }
-        return signals;
-    }
-
-    private void executeQueueItem(SyncQueueItemVO item, boolean fromPreviousSession) {
-        AsyncJobVO job = _jobDao.findById(item.getContentId());
-        if (job != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Schedule queued job-" + job.getId());
-            }
-
-            job.setSyncSource(item);
-
-            //
-            // TODO: a temporary solution to work-around DB deadlock situation
-            //
-            // to live with DB deadlocks, we will give a chance for job to be rescheduled
-            // in case of exceptions (most-likely DB deadlock exceptions)
-            try {
-                job.setExecutingMsid(getMsid());
-                _jobDao.update(job.getId(), job);
-            } catch (Exception e) {
-                s_logger.warn("Unexpected exception while dispatching job-" + item.getContentId(), e);
-
-                try {
-                    _queueMgr.returnItem(item.getId());
-                } catch (Throwable thr) {
-                    s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", thr);
-                }
-            }
-
-            try {
-                scheduleExecution(job);
-            } catch (RejectedExecutionException e) {
-                s_logger.warn("Execution for job-" + job.getId() + " is rejected, return it to the queue for next turn");
-
-                try {
-                    _queueMgr.returnItem(item.getId());
-                } catch (Exception e2) {
-                    s_logger.error("Unexpected exception while returning job-" + item.getContentId() + " to queue", e2);
-                }
-
-                try {
-                    job.setExecutingMsid(null);
-                    _jobDao.update(job.getId(), job);
-                } catch (Exception e3) {
-                    s_logger.warn("Unexpected exception while update job-" + item.getContentId() + " msid for bookkeeping");
-                }
-            }
-
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find related job for queue item: " + item.toString());
-            }
-
-            _queueMgr.purgeItem(item.getId());
-        }
-    }
-
-    @Override
-    public void releaseSyncSource() {
-        AsyncJobExecutionContext executionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        assert (executionContext != null);
-
-        if (executionContext.getSyncSource() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Release sync source for job-" + executionContext.getJob().getId() + " sync source: " + executionContext.getSyncSource().getContentType() +
-                    "-" + executionContext.getSyncSource().getContentId());
-            }
-
-            _queueMgr.purgeItem(executionContext.getSyncSource().getId());
-            checkQueue(executionContext.getSyncSource().getQueueId());
-        }
-    }
-
-    @Override
-    public boolean waitAndCheck(AsyncJob job, String[] wakeupTopicsOnMessageBus, long checkIntervalInMilliSeconds, long timeoutInMiliseconds, Predicate predicate) {
-
-        MessageDetector msgDetector = new MessageDetector();
-        String[] topics = Arrays.copyOf(wakeupTopicsOnMessageBus, wakeupTopicsOnMessageBus.length + 1);
-        topics[topics.length - 1] = AsyncJob.Topics.JOB_STATE;
-
-        msgDetector.open(_messageBus, topics);
-        try {
-            long startTick = System.currentTimeMillis();
-            while (timeoutInMiliseconds < 0 || System.currentTimeMillis() - startTick < timeoutInMiliseconds) {
-                msgDetector.waitAny(checkIntervalInMilliSeconds);
-                job = _jobDao.findById(job.getId());
-                if (job != null && job.getStatus().done()) {
-                    return true;
-                }
-
-                if (predicate.checkCondition()) {
-                    return true;
-                }
-            }
-        } finally {
-            msgDetector.close();
-        }
-
-        return false;
-    }
-
-    @Override
-    public String marshallResultObject(Serializable obj) {
-        if (obj != null)
-            return JobSerializerHelper.toObjectSerializedString(obj);
-
-        return null;
-    }
-
-    @Override
-    public Object unmarshallResultObject(AsyncJob job) {
-        if(job != null && job.getResult() != null)
-            return JobSerializerHelper.fromObjectSerializedString(job.getResult());
-        return null;
-    }
-
-    private void checkQueue(long queueId) {
-        while (true) {
-            try {
-                SyncQueueItemVO item = _queueMgr.dequeueFromOne(queueId, getMsid());
-                if (item != null) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Executing sync queue item: " + item.toString());
-                    }
-
-                    executeQueueItem(item, false);
-                } else {
-                    break;
-                }
-            } catch (Throwable e) {
-                s_logger.error("Unexpected exception when kicking sync queue-" + queueId, e);
-                break;
-            }
-        }
-    }
-
-    private Runnable getHeartbeatTask() {
-        return new ManagedContextRunnable() {
-
-            @Override
-            protected void runInContext() {
-                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerHeartbeat");
-                try {
-                    if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                        try {
-                            reallyRun();
-                        } finally {
-                            scanLock.unlock();
-                        }
-                    }
-                } finally {
-                    scanLock.releaseRef();
-                }
-            }
-
-            protected void reallyRun() {
-                try {
-                    List<SyncQueueItemVO> l = _queueMgr.dequeueFromAny(getMsid(), MAX_ONETIME_SCHEDULE_SIZE);
-                    if (l != null && l.size() > 0) {
-                        for (SyncQueueItemVO item : l) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Execute sync-queue item: " + item.toString());
-                            }
-                            executeQueueItem(item, false);
-                        }
-                    }
-
-                    List<Long> standaloneWakeupJobs = wakeupScan();
-                    for (Long jobId : standaloneWakeupJobs) {
-                        // TODO, we assume that all jobs in this category is API job only
-                        AsyncJobVO job = _jobDao.findById(jobId);
-                        if (job != null && (job.getPendingSignals() & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0)
-                            scheduleExecution(job, false);
-                    }
-                } catch (Throwable e) {
-                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
-                }
-            }
-        };
-    }
-
-    @DB
-    private Runnable getGCTask() {
-        return new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                GlobalLock scanLock = GlobalLock.getInternLock("AsyncJobManagerGC");
-                try {
-                    if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                        try {
-                            reallyRun();
-                        } finally {
-                            scanLock.unlock();
-                        }
-                    }
-                } finally {
-                    scanLock.releaseRef();
-                }
-            }
-
-            public void reallyRun() {
-                try {
-                    s_logger.info("Begin cleanup expired async-jobs");
-
-                    // forcefully cancel blocking queue items if they've been staying there for too long
-                    List<SyncQueueItemVO> blockItems = _queueMgr.getBlockedQueueItems(JobCancelThresholdMinutes.value() * 60000, false);
-                    if (blockItems != null && blockItems.size() > 0) {
-                        for (SyncQueueItemVO item : blockItems) {
-                            try {
-                                if (item.getContentType().equalsIgnoreCase(SyncQueueItem.AsyncJobContentType)) {
-                                    s_logger.info("Remove Job-" + item.getContentId() + " from Queue-" + item.getId() + " since it has been blocked for too long");
-                                    completeAsyncJob(item.getContentId(), JobInfo.Status.FAILED, 0, "Job is cancelled as it has been blocking others for too long");
-
-                                    _jobMonitor.unregisterByJobId(item.getContentId());
-                                }
-
-                                // purge the item and resume queue processing
-                                _queueMgr.purgeItem(item.getId());
-                            } catch (Throwable e) {
-                                s_logger.error("Unexpected exception when trying to remove job from sync queue, ", e);
-                            }
-                        }
-                    }
-
-                    Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - JobExpireMinutes.value() * 60000);
-                    // limit to 100 jobs per turn, this gives cleanup throughput as 600 jobs per minute
-                    // hopefully this will be fast enough to balance potential growth of job table
-                    // 1) Expire unfinished jobs that weren't processed yet
-                    List<AsyncJobVO> unfinishedJobs = _jobDao.getExpiredUnfinishedJobs(cutTime, 100);
-                    for (AsyncJobVO job : unfinishedJobs) {
-                        try {
-                            s_logger.info("Expunging unfinished job-" + job.getId());
-
-                            _jobMonitor.unregisterByJobId(job.getId());
-                            expungeAsyncJob(job);
-                        } catch (Throwable e) {
-                            s_logger.error("Unexpected exception when trying to expunge job-" + job.getId(), e);
-                        }
-                    }
-
-                    // 2) Expunge finished jobs
-                    List<AsyncJobVO> completedJobs = _jobDao.getExpiredCompletedJobs(cutTime, 100);
-                    for (AsyncJobVO job : completedJobs) {
-                        try {
-                            s_logger.info("Expunging completed job-" + job.getId());
-
-                            expungeAsyncJob(job);
-                        } catch (Throwable e) {
-                            s_logger.error("Unexpected exception when trying to expunge job-" + job.getId(), e);
-                        }
-                    }
-
-                    s_logger.info("End cleanup expired async-jobs");
-                } catch (Throwable e) {
-                    s_logger.error("Unexpected exception when trying to execute queue item, ", e);
-                }
-            }
-        };
-    }
-
-    @DB
-    protected void expungeAsyncJob(final AsyncJobVO job) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                _jobDao.expunge(job.getId());
-                // purge corresponding sync queue item
-                _queueMgr.purgeAsyncJobQueueItemId(job.getId());
-            }
-        });
-    }
-
-    private long getMsid() {
-        return ManagementServerNode.getManagementServerId();
-    }
-
-    @DB
-    protected List<Long> wakeupByJoinedJobCompletion(long joinedJobId) {
-        SearchCriteria<Long> joinJobSC = JoinJobSearch.create("joinJobId", joinedJobId);
-
-        List<Long> result = _joinMapDao.customSearch(joinJobSC, null);
-        if (result.size() > 0) {
-            Collections.sort(result);
-            Long[] ids = result.toArray(new Long[result.size()]);
-
-            final SearchCriteria<AsyncJobVO> jobsSC = JobIdsSearch.create("ids", ids);
-            final SearchCriteria<SyncQueueItemVO> queueItemsSC = QueueJobIdsSearch.create("contentIds", ids);
-
-            AsyncJobVO job = _jobDao.createForUpdate();
-            job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
-            _jobDao.update(job, jobsSC);
-
-            SyncQueueItemVO item = _queueItemDao.createForUpdate();
-            item.setLastProcessNumber(null);
-            item.setLastProcessMsid(null);
-            _queueItemDao.update(item, queueItemsSC);
-        }
-
-        return _joinMapDao.findJobsToWake(joinedJobId);
-    }
-
-    @DB
-    protected List<Long> wakeupScan() {
-        final Date cutDate = DateUtil.currentGMTTime();
-
-        SearchCriteria<Long> sc = JoinJobTimeSearch.create();
-        sc.setParameters("beginTime", cutDate);
-        sc.setParameters("endTime", cutDate);
-
-        final List<Long> result = _joinMapDao.customSearch(sc, null);
-
-        return Transaction.execute(new TransactionCallback<List<Long>>() {
-            @Override
-            public List<Long> doInTransaction(TransactionStatus status) {
-                if (result.size() > 0) {
-                    Collections.sort(result);
-                    Long[] ids = result.toArray(new Long[result.size()]);
-
-                    AsyncJobVO job = _jobDao.createForUpdate();
-                    job.setPendingSignals(AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
-
-                    SearchCriteria<AsyncJobVO> sc2 = JobIdsSearch.create("ids", ids);
-                    SearchCriteria<SyncQueueItemVO> queueItemsSC = QueueJobIdsSearch.create("contentIds", ids);
-
-                    _jobDao.update(job, sc2);
-
-                    SyncQueueItemVO item = _queueItemDao.createForUpdate();
-                    item.setLastProcessNumber(null);
-                    item.setLastProcessMsid(null);
-                    _queueItemDao.update(item, queueItemsSC);
-                }
-
-                return _joinMapDao.findJobsToWakeBetween(cutDate);
-            }
-        });
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        try {
-            final Properties dbProps = DbProperties.getDbProperties();
-            final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
-
-            int apiPoolSize = cloudMaxActive / 2;
-            int workPoolSize = (cloudMaxActive * 2) / 3;
-
-            s_logger.info("Start AsyncJobManager API executor thread pool in size " + apiPoolSize);
-            _apiJobExecutor = Executors.newFixedThreadPool(apiPoolSize, new NamedThreadFactory(AsyncJobManager.API_JOB_POOL_THREAD_PREFIX));
-
-            s_logger.info("Start AsyncJobManager Work executor thread pool in size " + workPoolSize);
-            _workerJobExecutor = Executors.newFixedThreadPool(workPoolSize, new NamedThreadFactory(AsyncJobManager.WORK_JOB_POOL_THREAD_PREFIX));
-        } catch (final Exception e) {
-            throw new ConfigurationException("Unable to load db.properties to configure AsyncJobManagerImpl");
-        }
-
-        JoinJobSearch = _joinMapDao.createSearchBuilder(Long.class);
-        JoinJobSearch.and(JoinJobSearch.entity().getJoinJobId(), Op.EQ, "joinJobId");
-        JoinJobSearch.selectFields(JoinJobSearch.entity().getJobId());
-        JoinJobSearch.done();
-
-        JoinJobTimeSearch = _joinMapDao.createSearchBuilder(Long.class);
-        JoinJobTimeSearch.and(JoinJobTimeSearch.entity().getNextWakeupTime(), Op.LT, "beginTime");
-        JoinJobTimeSearch.and(JoinJobTimeSearch.entity().getExpiration(), Op.GT, "endTime");
-        JoinJobTimeSearch.selectFields(JoinJobTimeSearch.entity().getJobId()).done();
-
-        JobIdsSearch = _jobDao.createSearchBuilder();
-        JobIdsSearch.and(JobIdsSearch.entity().getId(), Op.IN, "ids").done();
-
-        QueueJobIdsSearch = _queueItemDao.createSearchBuilder();
-        QueueJobIdsSearch.and(QueueJobIdsSearch.entity().getContentId(), Op.IN, "contentIds").done();
-
-        JoinJobIdsSearch = _joinMapDao.createSearchBuilder(Long.class);
-        JoinJobIdsSearch.selectFields(JoinJobIdsSearch.entity().getJobId());
-        JoinJobIdsSearch.and(JoinJobIdsSearch.entity().getJoinJobId(), Op.EQ, "joinJobId");
-        JoinJobIdsSearch.and(JoinJobIdsSearch.entity().getJobId(), Op.NIN, "jobIds");
-        JoinJobIdsSearch.done();
-
-        ContentIdsSearch = _queueItemDao.createSearchBuilder(Long.class);
-        ContentIdsSearch.selectFields(ContentIdsSearch.entity().getContentId()).done();
-
-        AsyncJobExecutionContext.init(this, _joinMapDao);
-        OutcomeImpl.init(this);
-
-        return true;
-    }
-
-    private void cleanupLeftOverJobs(final long msid) {
-        try {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    // purge sync queue item running on this ms node
-                    _queueMgr.cleanupActiveQueueItems(msid, true);
-                    // reset job status for all jobs running on this ms node
-                    List<AsyncJobVO> jobs = _jobDao.getResetJobs(msid);
-                    for (AsyncJobVO job : jobs) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Cancel left-over job-" + job.getId());
-                        }
-                        job.setStatus(JobInfo.Status.FAILED);
-                        job.setResultCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
-                        job.setResult("job cancelled because of management server restart or shutdown");
-                        job.setCompleteMsid(msid);
-                        _jobDao.update(job.getId(), job);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Purge queue item for cancelled job-" + job.getId());
-                        }
-                        _queueMgr.purgeAsyncJobQueueItemId(job.getId());
-                        if (job.getInstanceType().equals(ApiCommandJobType.Volume.toString())) {
-
-                            try {
-                                _volumeDetailsDao.removeDetail(job.getInstanceId(), "SNAPSHOT_ID");
-                                _volsDao.remove(job.getInstanceId());
-                            } catch (Exception e) {
-                                s_logger.error("Unexpected exception while removing concurrent request meta data :" + e.getLocalizedMessage());
-                            }
-                        }
-                    }
-                    List<SnapshotDetailsVO> snapshotList = _snapshotDetailsDao.findDetails(AsyncJob.Constants.MS_ID, Long.toString(msid), false);
-                    for (SnapshotDetailsVO snapshotDetailsVO : snapshotList) {
-                        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotDetailsVO.getResourceId(), DataStoreRole.Primary);
-                        snapshotSrv.processEventOnSnapshotObject(snapshot, Snapshot.Event.OperationFailed);
-                        _snapshotDetailsDao.removeDetail(snapshotDetailsVO.getResourceId(), AsyncJob.Constants.MS_ID);
-                    }
-                }
-            });
-        } catch (Throwable e) {
-            s_logger.warn("Unexpected exception in cleaning up left over jobs for mamagement server node " + msid, e);
-        }
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (final ManagementServerHost msHost : nodeList) {
-            cleanupLeftOverJobs(msHost.getId());
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public boolean start() {
-        cleanupLeftOverJobs(getMsid());
-
-        _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
-        _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, GC_INTERVAL, TimeUnit.MILLISECONDS);
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _heartbeatScheduler.shutdown();
-        _apiJobExecutor.shutdown();
-        _workerJobExecutor.shutdown();
-        return true;
-    }
-
-    private GenericSearchBuilder<SyncQueueItemVO, Long> ContentIdsSearch;
-    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobSearch;
-    private SearchBuilder<AsyncJobVO> JobIdsSearch;
-    private SearchBuilder<SyncQueueItemVO> QueueJobIdsSearch;
-    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobIdsSearch;
-    private GenericSearchBuilder<AsyncJobJoinMapVO, Long> JoinJobTimeSearch;
-
-    protected AsyncJobManagerImpl() {
-        // override default run level for manager components to start this early, otherwise, VirtualMachineManagerImpl will
-        // get stuck in non-initializing job queue
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK);
-    }
-
-    private void publishOnEventBus(AsyncJob job, String jobEvent) {
-        _messageBus.publish(null, AsyncJob.Topics.JOB_EVENT_PUBLISH, PublishScope.LOCAL,
-            new Pair<AsyncJob, String>(job, jobEvent));
-    }
-
-    @Override
-    public List<AsyncJobVO> findFailureAsyncJobs(String... cmds) {
-        return _jobDao.getFailureJobsSinceLastMsStart(getMsid(), cmds);
-    }
-}
diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
deleted file mode 100644
index 0ca9ed5..0000000
--- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobVO.java
+++ /dev/null
@@ -1,398 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.framework.jobs.impl;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.jobs.JobInfo;
-
-import com.cloud.utils.UuidUtils;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "async_job")
-@Inheritance(strategy = InheritanceType.JOINED)
-@DiscriminatorColumn(name = "job_type", discriminatorType = DiscriminatorType.STRING, length = 32)
-public class AsyncJobVO implements AsyncJob, JobInfo {
-
-    public static final String JOB_DISPATCHER_PSEUDO = "pseudoJobDispatcher";
-    public static final String PSEUDO_JOB_INSTANCE_TYPE = "Thread";
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "job_type", length = 32)
-    protected String type;
-
-    @Column(name = "job_dispatcher", length = 64)
-    protected String dispatcher;
-
-    @Column(name = "job_pending_signals")
-    protected int pendingSignals;
-
-    @Column(name = "user_id")
-    private long userId;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = "job_cmd")
-    private String cmd;
-
-    @Column(name = "job_cmd_ver")
-    private int cmdVersion;
-
-    @Column(name = "related")
-    private String related;
-
-    @Column(name = "job_cmd_info", length = 65535)
-    private String cmdInfo;
-
-    @Column(name = "job_status")
-    @Enumerated(value = EnumType.ORDINAL)
-    private Status status;
-
-    @Column(name = "job_process_status")
-    private int processStatus;
-
-    @Column(name = "job_result_code")
-    private int resultCode;
-
-    @Column(name = "job_result", length = 65535)
-    private String result;
-
-    @Column(name = "instance_type", length = 64)
-    private String instanceType;
-
-    @Column(name = "instance_id", length = 64)
-    private Long instanceId;
-
-    @Column(name = "job_init_msid")
-    private Long initMsid;
-
-    @Column(name = "job_complete_msid")
-    private Long completeMsid;
-
-    @Column(name = "job_executing_msid")
-    private Long executingMsid;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = "last_updated")
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date lastUpdated;
-
-    @Column(name = "last_polled")
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date lastPolled;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Transient
-    private SyncQueueItem syncSource = null;
-
-    public AsyncJobVO() {
-        uuid = UUID.randomUUID().toString();
-        related = "";
-        status = Status.IN_PROGRESS;
-    }
-
-    public AsyncJobVO(String related, long userId, long accountId, String cmd, String cmdInfo, Long instanceId, String instanceType, String injectedUuid) {
-        this.userId = userId;
-        this.accountId = accountId;
-        this.cmd = cmd;
-        this.cmdInfo = cmdInfo;
-        uuid = ( injectedUuid == null ? UUID.randomUUID().toString() : injectedUuid );
-        this.related = related;
-        this.instanceId = instanceId;
-        this.instanceType = instanceType;
-        status = Status.IN_PROGRESS;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    @Override
-    public String getShortUuid() {
-        return UuidUtils.first(uuid);
-    }
-
-    public void setRelated(String related) {
-        this.related = related;
-    }
-
-    @Override
-    public String getRelated() {
-        return related;
-    }
-
-    @Override
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    @Override
-    public String getDispatcher() {
-        return dispatcher;
-    }
-
-    public void setDispatcher(String dispatcher) {
-        this.dispatcher = dispatcher;
-    }
-
-    @Override
-    public int getPendingSignals() {
-        return pendingSignals;
-    }
-
-    public void setPendingSignals(int signals) {
-        pendingSignals = signals;
-    }
-
-    @Override
-    public long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(long userId) {
-        this.userId = userId;
-    }
-
-    @Override
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(long accountId) {
-        this.accountId = accountId;
-    }
-
-    @Override
-    public String getCmd() {
-        return cmd;
-    }
-
-    public void setCmd(String cmd) {
-        this.cmd = cmd;
-    }
-
-    @Override
-    public int getCmdVersion() {
-        return cmdVersion;
-    }
-
-    public void setCmdVersion(int version) {
-        cmdVersion = version;
-    }
-
-    @Override
-    public String getCmdInfo() {
-        return cmdInfo;
-    }
-
-    public void setCmdInfo(String cmdInfo) {
-        this.cmdInfo = cmdInfo;
-    }
-
-    @Override
-    public Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(Status status) {
-        this.status = status;
-    }
-
-    @Override
-    public int getProcessStatus() {
-        return processStatus;
-    }
-
-    public void setProcessStatus(int status) {
-        processStatus = status;
-    }
-
-    @Override
-    public int getResultCode() {
-        return resultCode;
-    }
-
-    public void setResultCode(int resultCode) {
-        this.resultCode = resultCode;
-    }
-
-    @Override
-    public String getResult() {
-        return result;
-    }
-
-    public void setResult(String result) {
-        this.result = result;
-    }
-
-    @Override
-    public Long getInitMsid() {
-        return initMsid;
-    }
-
-    @Override
-    public void setInitMsid(Long initMsid) {
-        this.initMsid = initMsid;
-    }
-
-    @Override
-    public Long getExecutingMsid() {
-        return executingMsid;
-    }
-
-    public void setExecutingMsid(Long executingMsid) {
-        this.executingMsid = executingMsid;
-    }
-
-    @Override
-    public Long getCompleteMsid() {
-        return completeMsid;
-    }
-
-    @Override
-    public void setCompleteMsid(Long completeMsid) {
-        this.completeMsid = completeMsid;
-    }
-
-    @Override
-    public Date getCreated() {
-        return created;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    @Override
-    public Date getLastUpdated() {
-        return lastUpdated;
-    }
-
-    public void setLastUpdated(Date lastUpdated) {
-        this.lastUpdated = lastUpdated;
-    }
-
-    @Override
-    public Date getLastPolled() {
-        return lastPolled;
-    }
-
-    public void setLastPolled(Date lastPolled) {
-        this.lastPolled = lastPolled;
-    }
-
-    @Override
-    public String getInstanceType() {
-        return instanceType;
-    }
-
-    public void setInstanceType(String instanceType) {
-        this.instanceType = instanceType;
-    }
-
-    @Override
-    public Long getInstanceId() {
-        return instanceId;
-    }
-
-    public void setInstanceId(Long instanceId) {
-        this.instanceId = instanceId;
-    }
-
-    @Override
-    public SyncQueueItem getSyncSource() {
-        return syncSource;
-    }
-
-    @Override
-    public void setSyncSource(SyncQueueItem syncSource) {
-        this.syncSource = syncSource;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append("AsyncJobVO {id:").append(getId());
-        sb.append(", userId: ").append(getUserId());
-        sb.append(", accountId: ").append(getAccountId());
-        sb.append(", instanceType: ").append(getInstanceType());
-        sb.append(", instanceId: ").append(getInstanceId());
-        sb.append(", cmd: ").append(getCmd());
-        sb.append(", cmdInfo: ").append(getCmdInfo());
-        sb.append(", cmdVersion: ").append(getCmdVersion());
-        sb.append(", status: ").append(getStatus());
-        sb.append(", processStatus: ").append(getProcessStatus());
-        sb.append(", resultCode: ").append(getResultCode());
-        sb.append(", result: ").append(getResult());
-        sb.append(", initMsid: ").append(getInitMsid());
-        sb.append(", completeMsid: ").append(getCompleteMsid());
-        sb.append(", lastUpdated: ").append(getLastUpdated());
-        sb.append(", lastPolled: ").append(getLastPolled());
-        sb.append(", created: ").append(getCreated());
-        sb.append("}");
-        return sb.toString();
-    }
-}
diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java b/framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java
similarity index 100%
rename from framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java
rename to framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobManagerTest.java
diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java b/framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java
similarity index 100%
rename from framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java
rename to framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobManagerTestConfiguration.java
diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java b/framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java
similarity index 100%
rename from framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java
rename to framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobTestDashboard.java
diff --git a/framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java b/framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java
similarity index 100%
rename from framework/jobs/test/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java
rename to framework/jobs/src/test/java/org/apache/cloudstack/framework/jobs/AsyncJobTestDispatcher.java
diff --git a/framework/jobs/test/resources/AsyncJobManagerTestContext.xml b/framework/jobs/src/test/resources/AsyncJobManagerTestContext.xml
similarity index 100%
rename from framework/jobs/test/resources/AsyncJobManagerTestContext.xml
rename to framework/jobs/src/test/resources/AsyncJobManagerTestContext.xml
diff --git a/framework/jobs/test/resources/commonContext.xml b/framework/jobs/src/test/resources/commonContext.xml
similarity index 100%
rename from framework/jobs/test/resources/commonContext.xml
rename to framework/jobs/src/test/resources/commonContext.xml
diff --git a/framework/jobs/test/resources/db.properties b/framework/jobs/src/test/resources/db.properties
similarity index 100%
rename from framework/jobs/test/resources/db.properties
rename to framework/jobs/src/test/resources/db.properties
diff --git a/framework/jobs/test/resources/log4j.properties b/framework/jobs/src/test/resources/log4j.properties
similarity index 100%
rename from framework/jobs/test/resources/log4j.properties
rename to framework/jobs/src/test/resources/log4j.properties
diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml
index c07c6ab..c059d15 100644
--- a/framework/managed-context/pom.xml
+++ b/framework/managed-context/pom.xml
@@ -1,36 +1,36 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-framework-managed-context</artifactId>
-  <name>Apache CloudStack Framework - Managed Context</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-maven-standard</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../maven-standard/pom.xml</relativePath>
-  </parent>
-  <dependencies>
-      <dependency>
-          <groupId>org.slf4j</groupId>
-          <artifactId>slf4j-api</artifactId>
-      </dependency>
-  </dependencies>
+    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-framework-managed-context</artifactId>
+    <name>Apache CloudStack Framework - Managed Context</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/pom.xml b/framework/pom.xml
index 169c34d..f5b358f 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -1,62 +1,63 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>cloudstack-framework</artifactId>
-  <name>Apache CloudStack Framework</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>none</phase>
-              <inherited>false</inherited>
-            </execution>
-          </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <modules>
-    <module>ipc</module>
-    <module>ca</module>
-    <module>rest</module>
-    <module>events</module>
-    <module>jobs</module>
-    <module>quota</module>
-    <module>cluster</module>
-    <module>db</module>
-    <module>config</module>
-    <module>managed-context</module>
-    <module>spring/lifecycle</module>
-    <module>spring/module</module>
-    <module>security</module>
-    <module>agent-lb</module>
-    <module>direct-download</module>
-  </modules>
+<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>cloudstack-framework</artifactId>
+    <name>Apache CloudStack Framework</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <!-- keep in alphabetic order -->
+        <module>agent-lb</module>
+        <module>ca</module>
+        <module>cluster</module>
+        <module>config</module>
+        <module>db</module>
+        <module>direct-download</module>
+        <module>events</module>
+        <module>ipc</module>
+        <module>jobs</module>
+        <module>managed-context</module>
+        <module>quota</module>
+        <module>rest</module>
+        <module>security</module>
+        <module>spring/lifecycle</module>
+        <module>spring/module</module>
+    </modules>
 </project>
diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml
index d0d105d..9ccf1b4 100644
--- a/framework/quota/pom.xml
+++ b/framework/quota/pom.xml
@@ -1,73 +1,50 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-framework-quota</artifactId>
-  <name>Apache CloudStack Framework - Quota</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-        <groupId>junit</groupId>
-        <artifactId>junit</artifactId>
-        <version>${cs.junit.version}</version>
-        <scope>test</scope>
-    </dependency>
-    <dependency>
-        <groupId>org.mockito</groupId>
-        <artifactId>mockito-all</artifactId>
-        <version>${cs.mockito.version}</version>
-        <scope>test</scope>
-    </dependency>
-    <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-module-junit4</artifactId>
-        <version>${cs.powermock.version}</version>
-    </dependency>
-    <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-api-mockito</artifactId>
-        <version>${cs.powermock.version}</version>
-        <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-      <version>${cs.commons-lang3.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.mail</groupId>
-      <artifactId>mail</artifactId>
-    </dependency>
-  </dependencies>
+<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-framework-quota</artifactId>
+    <name>Apache CloudStack Framework - Quota</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaAlertManager.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManager.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaAlertManager.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManager.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaManager.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManager.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaManager.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManager.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManagerImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManagerImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaStatement.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaStatement.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaStatement.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaStatement.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaStatementImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaStatementImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/QuotaStatementImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaStatementImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaConfig.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaConfig.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/constant/QuotaConfig.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaConfig.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaAccountDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaAccountDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaAccountDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaAccountDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaAccountDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaAccountDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaAccountDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaAccountDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaCreditsDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaCreditsDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaCreditsDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaCreditsDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaCreditsDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaEmailTemplatesDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaTariffDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaTariffDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaUsageDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaUsageDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/ServiceOfferingDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/ServiceOfferingDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/ServiceOfferingDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/ServiceOfferingDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/ServiceOfferingDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/ServiceOfferingDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/ServiceOfferingDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/ServiceOfferingDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/UserVmDetailsDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/UserVmDetailsDao.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/UserVmDetailsDao.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/UserVmDetailsDao.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/UserVmDetailsDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/UserVmDetailsDaoImpl.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/dao/UserVmDetailsDaoImpl.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/dao/UserVmDetailsDaoImpl.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaAccountVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaAccountVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaAccountVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaAccountVO.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaBalanceVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaBalanceVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaBalanceVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaBalanceVO.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaCreditsVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaCreditsVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaCreditsVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaCreditsVO.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaEmailTemplatesVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaEmailTemplatesVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaEmailTemplatesVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaEmailTemplatesVO.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaTariffVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaTariffVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/QuotaUsageVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaUsageVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/QuotaUsageVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaUsageVO.java
diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java
new file mode 100644
index 0000000..00bdb82
--- /dev/null
+++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java
@@ -0,0 +1,287 @@
+//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.quota.vo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.vm.VirtualMachine;
+
+@Entity
+@Table(name = "service_offering")
+@DiscriminatorValue(value = "Service")
+@PrimaryKeyJoinColumn(name = "id")
+public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
+    @Column(name = "cpu")
+    private Integer cpu;
+
+    @Column(name = "speed")
+    private Integer speed;
+
+    @Column(name = "ram_size")
+    private Integer ramSize;
+
+    @Column(name = "nw_rate")
+    private Integer rateMbps;
+
+    @Column(name = "mc_rate")
+    private Integer multicastRateMbps;
+
+    @Column(name = "ha_enabled")
+    private boolean offerHA;
+
+    @Column(name = "limit_cpu_use")
+    private boolean limitCpuUse;
+
+    @Column(name = "is_volatile")
+    private boolean volatileVm;
+
+    @Column(name = "host_tag")
+    private String hostTag;
+
+    @Column(name = "default_use")
+    private boolean defaultUse;
+
+    @Column(name = "vm_type")
+    private String vmType;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "deployment_planner")
+    private String deploymentPlanner = null;
+
+    @Transient
+    Map<String, String> details = new HashMap<String, String>();
+
+    @Transient
+    boolean isDynamic;
+
+    protected ServiceOfferingVO() {
+        super();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
+            ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
+        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
+        this.cpu = cpu;
+        this.ramSize = ramSize;
+        this.speed = speed;
+        this.rateMbps = rateMbps;
+        this.multicastRateMbps = multicastRateMbps;
+        this.offerHA = offerHA;
+        limitCpuUse = false;
+        volatileVm = false;
+        this.defaultUse = defaultUse;
+        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
+            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
+            VirtualMachine.Type vmType, Long domainId) {
+        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
+        this.cpu = cpu;
+        this.ramSize = ramSize;
+        this.speed = speed;
+        this.rateMbps = rateMbps;
+        this.multicastRateMbps = multicastRateMbps;
+        this.offerHA = offerHA;
+        this.limitCpuUse = limitCpuUse;
+        this.volatileVm = volatileVm;
+        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
+            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
+            VirtualMachine.Type vmType, Long domainId, String hostTag) {
+        this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
+                systemUse, vmType, domainId);
+        this.hostTag = hostTag;
+    }
+
+    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
+            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
+            VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
+        this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
+                systemUse, vmType, domainId, hostTag);
+        this.deploymentPlanner = deploymentPlanner;
+    }
+
+    public ServiceOfferingVO(ServiceOfferingVO offering) {
+        super(offering.getId(), offering.getName(), offering.getDisplayText(), offering.getProvisioningType(), false, offering.getTags(), offering.isRecreatable(),
+                offering.isUseLocalStorage(), offering.isSystemUse(), true, offering.isCustomizedIops() == null ? false : offering.isCustomizedIops(), offering.getDomainId(),
+                offering.getMinIops(), offering.getMaxIops());
+        cpu = offering.getCpu();
+        ramSize = offering.getRamSize();
+        speed = offering.getSpeed();
+        rateMbps = offering.getRateMbps();
+        multicastRateMbps = offering.getMulticastRateMbps();
+        offerHA = offering.isOfferHA();
+        limitCpuUse = offering.getLimitCpuUse();
+        volatileVm = offering.isVolatileVm();
+        hostTag = offering.getHostTag();
+        vmType = offering.getSystemVmType();
+    }
+
+    @Override
+    public boolean isOfferHA() {
+        return offerHA;
+    }
+
+    public void setOfferHA(boolean offerHA) {
+        this.offerHA = offerHA;
+    }
+
+    @Override
+    public boolean getLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public void setLimitResourceUse(boolean limitCpuUse) {
+        this.limitCpuUse = limitCpuUse;
+    }
+
+    @Override
+    public boolean getDefaultUse() {
+        return defaultUse;
+    }
+
+    @Override
+    @Transient
+    public String[] getTagsArray() {
+        String tags = getTags();
+        if (tags == null || tags.length() == 0) {
+            return new String[0];
+        }
+
+        return tags.split(",");
+    }
+
+    @Override
+    public Integer getCpu() {
+        return cpu;
+    }
+
+    public void setCpu(int cpu) {
+        this.cpu = cpu;
+    }
+
+    public void setSpeed(int speed) {
+        this.speed = speed;
+    }
+
+    public void setRamSize(int ramSize) {
+        this.ramSize = ramSize;
+    }
+
+    @Override
+    public Integer getSpeed() {
+        return speed;
+    }
+
+    @Override
+    public Integer getRamSize() {
+        return ramSize;
+    }
+
+    public void setRateMbps(Integer rateMbps) {
+        this.rateMbps = rateMbps;
+    }
+
+    @Override
+    public Integer getRateMbps() {
+        return rateMbps;
+    }
+
+    public void setMulticastRateMbps(Integer multicastRateMbps) {
+        this.multicastRateMbps = multicastRateMbps;
+    }
+
+    @Override
+    public Integer getMulticastRateMbps() {
+        return multicastRateMbps;
+    }
+
+    public void setHostTag(String hostTag) {
+        this.hostTag = hostTag;
+    }
+
+    @Override
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    @Override
+    public String getSystemVmType() {
+        return vmType;
+    }
+
+    @Override
+    public void setSortKey(int key) {
+        sortKey = key;
+    }
+
+    @Override
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    @Override
+    public boolean isVolatileVm() {
+        return volatileVm;
+    }
+
+    @Override
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public Map<String, String> getDetails() {
+        return details;
+    }
+
+    public String getDetail(String name) {
+        return details.get(name);
+    }
+
+    public void addDetail(String name, String value) {
+        details.put(name, value);
+    }
+
+    public void setDetails(Map<String, String> details) {
+        this.details = details;
+    }
+
+    @Override
+    public boolean isDynamic() {
+        return cpu == null || speed == null || ramSize == null || isDynamic;
+    }
+
+    public void setDynamicFlag(boolean isdynamic) {
+        isDynamic = isdynamic;
+    }
+}
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/UserVmDetailVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/UserVmDetailVO.java
similarity index 100%
rename from framework/quota/src/org/apache/cloudstack/quota/vo/UserVmDetailVO.java
rename to framework/quota/src/main/java/org/apache/cloudstack/quota/vo/UserVmDetailVO.java
diff --git a/framework/quota/resources/META-INF/cloudstack/quota/spring-framework-quota-context.xml b/framework/quota/src/main/resources/META-INF/cloudstack/quota/spring-framework-quota-context.xml
similarity index 100%
rename from framework/quota/resources/META-INF/cloudstack/quota/spring-framework-quota-context.xml
rename to framework/quota/src/main/resources/META-INF/cloudstack/quota/spring-framework-quota-context.xml
diff --git a/framework/quota/src/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java b/framework/quota/src/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java
deleted file mode 100644
index 795a178..0000000
--- a/framework/quota/src/org/apache/cloudstack/quota/vo/ServiceOfferingVO.java
+++ /dev/null
@@ -1,287 +0,0 @@
-//Licensed to the Apache Software Foundation (ASF) under one
-//or more contributor license agreements.  See the NOTICE file
-//distributed with this work for additional information
-//regarding copyright ownership.  The ASF licenses this file
-//to you under the Apache License, Version 2.0 (the
-//"License"); you may not use this file except in compliance
-//with the License.  You may obtain a copy of the License at
-//
-//http://www.apache.org/licenses/LICENSE-2.0
-//
-//Unless required by applicable law or agreed to in writing,
-//software distributed under the License is distributed on an
-//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-//KIND, either express or implied.  See the License for the
-//specific language governing permissions and limitations
-//under the License.
-package org.apache.cloudstack.quota.vo;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-import com.cloud.offering.ServiceOffering;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.vm.VirtualMachine;
-
-@Entity
-@Table(name = "service_offering")
-@DiscriminatorValue(value = "Service")
-@PrimaryKeyJoinColumn(name = "id")
-public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
-    @Column(name = "cpu")
-    private Integer cpu;
-
-    @Column(name = "speed")
-    private Integer speed;
-
-    @Column(name = "ram_size")
-    private Integer ramSize;
-
-    @Column(name = "nw_rate")
-    private Integer rateMbps;
-
-    @Column(name = "mc_rate")
-    private Integer multicastRateMbps;
-
-    @Column(name = "ha_enabled")
-    private boolean offerHA;
-
-    @Column(name = "limit_cpu_use")
-    private boolean limitCpuUse;
-
-    @Column(name = "is_volatile")
-    private boolean volatileVm;
-
-    @Column(name = "host_tag")
-    private String hostTag;
-
-    @Column(name = "default_use")
-    private boolean defaultUse;
-
-    @Column(name = "vm_type")
-    private String vmType;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "deployment_planner")
-    private String deploymentPlanner = null;
-
-    @Transient
-    Map<String, String> details = new HashMap<String, String>();
-
-    @Transient
-    boolean isDynamic;
-
-    protected ServiceOfferingVO() {
-        super();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
-            ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
-        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
-        this.cpu = cpu;
-        this.ramSize = ramSize;
-        this.speed = speed;
-        this.rateMbps = rateMbps;
-        this.multicastRateMbps = multicastRateMbps;
-        this.offerHA = offerHA;
-        limitCpuUse = false;
-        volatileVm = false;
-        this.defaultUse = defaultUse;
-        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
-            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
-            VirtualMachine.Type vmType, Long domainId) {
-        super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
-        this.cpu = cpu;
-        this.ramSize = ramSize;
-        this.speed = speed;
-        this.rateMbps = rateMbps;
-        this.multicastRateMbps = multicastRateMbps;
-        this.offerHA = offerHA;
-        this.limitCpuUse = limitCpuUse;
-        this.volatileVm = volatileVm;
-        this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
-            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
-            VirtualMachine.Type vmType, Long domainId, String hostTag) {
-        this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
-                systemUse, vmType, domainId);
-        this.hostTag = hostTag;
-    }
-
-    public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse,
-            boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
-            VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
-        this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags,
-                systemUse, vmType, domainId, hostTag);
-        this.deploymentPlanner = deploymentPlanner;
-    }
-
-    public ServiceOfferingVO(ServiceOfferingVO offering) {
-        super(offering.getId(), offering.getName(), offering.getDisplayText(), offering.getProvisioningType(), false, offering.getTags(), offering.isRecreatable(),
-                offering.getUseLocalStorage(), offering.getSystemUse(), true, offering.isCustomizedIops() == null ? false : offering.isCustomizedIops(), offering.getDomainId(),
-                offering.getMinIops(), offering.getMaxIops());
-        cpu = offering.getCpu();
-        ramSize = offering.getRamSize();
-        speed = offering.getSpeed();
-        rateMbps = offering.getRateMbps();
-        multicastRateMbps = offering.getMulticastRateMbps();
-        offerHA = offering.getOfferHA();
-        limitCpuUse = offering.getLimitCpuUse();
-        volatileVm = offering.getVolatileVm();
-        hostTag = offering.getHostTag();
-        vmType = offering.getSystemVmType();
-    }
-
-    @Override
-    public boolean getOfferHA() {
-        return offerHA;
-    }
-
-    public void setOfferHA(boolean offerHA) {
-        this.offerHA = offerHA;
-    }
-
-    @Override
-    public boolean getLimitCpuUse() {
-        return limitCpuUse;
-    }
-
-    public void setLimitResourceUse(boolean limitCpuUse) {
-        this.limitCpuUse = limitCpuUse;
-    }
-
-    @Override
-    public boolean getDefaultUse() {
-        return defaultUse;
-    }
-
-    @Override
-    @Transient
-    public String[] getTagsArray() {
-        String tags = getTags();
-        if (tags == null || tags.length() == 0) {
-            return new String[0];
-        }
-
-        return tags.split(",");
-    }
-
-    @Override
-    public Integer getCpu() {
-        return cpu;
-    }
-
-    public void setCpu(int cpu) {
-        this.cpu = cpu;
-    }
-
-    public void setSpeed(int speed) {
-        this.speed = speed;
-    }
-
-    public void setRamSize(int ramSize) {
-        this.ramSize = ramSize;
-    }
-
-    @Override
-    public Integer getSpeed() {
-        return speed;
-    }
-
-    @Override
-    public Integer getRamSize() {
-        return ramSize;
-    }
-
-    public void setRateMbps(Integer rateMbps) {
-        this.rateMbps = rateMbps;
-    }
-
-    @Override
-    public Integer getRateMbps() {
-        return rateMbps;
-    }
-
-    public void setMulticastRateMbps(Integer multicastRateMbps) {
-        this.multicastRateMbps = multicastRateMbps;
-    }
-
-    @Override
-    public Integer getMulticastRateMbps() {
-        return multicastRateMbps;
-    }
-
-    public void setHostTag(String hostTag) {
-        this.hostTag = hostTag;
-    }
-
-    @Override
-    public String getHostTag() {
-        return hostTag;
-    }
-
-    @Override
-    public String getSystemVmType() {
-        return vmType;
-    }
-
-    @Override
-    public void setSortKey(int key) {
-        sortKey = key;
-    }
-
-    @Override
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    @Override
-    public boolean getVolatileVm() {
-        return volatileVm;
-    }
-
-    @Override
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public Map<String, String> getDetails() {
-        return details;
-    }
-
-    public String getDetail(String name) {
-        return details.get(name);
-    }
-
-    public void addDetail(String name, String value) {
-        details.put(name, value);
-    }
-
-    public void setDetails(Map<String, String> details) {
-        this.details = details;
-    }
-
-    @Override
-    public boolean isDynamic() {
-        return cpu == null || speed == null || ramSize == null || isDynamic;
-    }
-
-    public void setDynamicFlag(boolean isdynamic) {
-        isDynamic = isdynamic;
-    }
-}
diff --git a/framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
similarity index 100%
rename from framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
rename to framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
diff --git a/framework/quota/test/org/apache/cloudstack/quota/QuotaManagerImplTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaManagerImplTest.java
similarity index 100%
rename from framework/quota/test/org/apache/cloudstack/quota/QuotaManagerImplTest.java
rename to framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaManagerImplTest.java
diff --git a/framework/quota/test/org/apache/cloudstack/quota/QuotaStatementTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaStatementTest.java
similarity index 100%
rename from framework/quota/test/org/apache/cloudstack/quota/QuotaStatementTest.java
rename to framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaStatementTest.java
diff --git a/framework/quota/test/org/apache/cloudstack/quota/constant/QuotaTypesTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/constant/QuotaTypesTest.java
similarity index 100%
rename from framework/quota/test/org/apache/cloudstack/quota/constant/QuotaTypesTest.java
rename to framework/quota/src/test/java/org/apache/cloudstack/quota/constant/QuotaTypesTest.java
diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml
index a654155..afdccb2 100644
--- a/framework/rest/pom.xml
+++ b/framework/rest/pom.xml
@@ -1,78 +1,78 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <artifactId>cloud-framework-rest</artifactId>
-  <name>Apache CloudStack Framework - REST</name>
-  <build>
-  </build>
-  <dependencies>
-    <dependency>
-      <groupId>com.fasterxml.jackson.module</groupId>
-      <artifactId>jackson-module-jaxb-annotations</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.jaxrs</groupId>
-      <artifactId>jackson-jaxrs-json-provider</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cxf</groupId>
-      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
-      <version>${cs.cxf.version}</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.eclipse.jetty</groupId>
-          <artifactId>jetty-server</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>org.apache.geronimo.specs</groupId>
-          <artifactId>geronimo-servlet_3.0_spec</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>com.sun.xml.bind</groupId>
-          <artifactId>jaxb-impl</artifactId>
-        </exclusion>        
-      </exclusions>
-    </dependency>
-  </dependencies>
+    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>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>cloud-framework-rest</artifactId>
+    <name>Apache CloudStack Framework - REST</name>
+    <build>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-jaxb-annotations</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+            <version>${cs.cxf.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-server</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.geronimo.specs</groupId>
+                    <artifactId>geronimo-servlet_3.0_spec</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.xml.bind</groupId>
+                    <artifactId>jaxb-impl</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/rest/src/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationIntrospector.java b/framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationIntrospector.java
similarity index 100%
rename from framework/rest/src/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationIntrospector.java
rename to framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationIntrospector.java
diff --git a/framework/rest/src/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationModule.java b/framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationModule.java
similarity index 100%
rename from framework/rest/src/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationModule.java
rename to framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationModule.java
diff --git a/framework/rest/src/org/apache/cloudstack/framework/ws/jackson/UriSerializer.java b/framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/UriSerializer.java
similarity index 100%
rename from framework/rest/src/org/apache/cloudstack/framework/ws/jackson/UriSerializer.java
rename to framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/UriSerializer.java
diff --git a/framework/rest/src/org/apache/cloudstack/framework/ws/jackson/UrisSerializer.java b/framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/UrisSerializer.java
similarity index 100%
rename from framework/rest/src/org/apache/cloudstack/framework/ws/jackson/UrisSerializer.java
rename to framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/UrisSerializer.java
diff --git a/framework/rest/src/org/apache/cloudstack/framework/ws/jackson/Url.java b/framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/Url.java
similarity index 100%
rename from framework/rest/src/org/apache/cloudstack/framework/ws/jackson/Url.java
rename to framework/rest/src/main/java/org/apache/cloudstack/framework/ws/jackson/Url.java
diff --git a/framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java b/framework/rest/src/test/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
similarity index 100%
rename from framework/rest/test/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
rename to framework/rest/src/test/java/org/apache/cloudstack/framework/ws/jackson/CSJacksonAnnotationTest.java
diff --git a/framework/security/pom.xml b/framework/security/pom.xml
index 51b2235..05fec6c 100644
--- a/framework/security/pom.xml
+++ b/framework/security/pom.xml
@@ -1,60 +1,61 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-framework-security</artifactId>
-  <name>Apache CloudStack Framework - Security</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-framework</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+<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-framework-security</artifactId>
+    <name>Apache CloudStack Framework - Security</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-framework</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keys/KeysManager.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keys/KeysManager.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreDao.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreDaoImpl.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java
diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreVO.java b/framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreVO.java
similarity index 100%
rename from framework/security/src/org/apache/cloudstack/framework/security/keystore/KeystoreVO.java
rename to framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreVO.java
diff --git a/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml b/framework/security/src/main/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml
similarity index 100%
rename from framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml
rename to framework/security/src/main/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml
diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml
index 48f7d73..96eedfc 100644
--- a/framework/spring/lifecycle/pom.xml
+++ b/framework/spring/lifecycle/pom.xml
@@ -1,13 +1,21 @@
-<!-- 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. -->
+<!--
+  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>
@@ -15,9 +23,9 @@
     <name>Apache CloudStack Framework - Spring Life Cycle</name>
     <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-maven-standard</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
-        <relativePath>../../../maven-standard/pom.xml</relativePath>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
     </parent>
     <dependencies>
         <dependency>
diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml
index 5ceff79..e708a94 100644
--- a/framework/spring/module/pom.xml
+++ b/framework/spring/module/pom.xml
@@ -1,18 +1,18 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
 -->
@@ -23,9 +23,9 @@
     <name>Apache CloudStack Framework - Spring Module</name>
     <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-maven-standard</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
-        <relativePath>../../../maven-standard/pom.xml</relativePath>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
     </parent>
     <dependencies>
         <dependency>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <version>${cs.commons-io.version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
diff --git a/maven-standard/pom.xml b/maven-standard/pom.xml
deleted file mode 100644
index a215756..0000000
--- a/maven-standard/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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-maven-standard</artifactId>
-  <name>Apache CloudStack Maven Conventions Parent</name>
-  <description>Historically ACS was built with a custom build system mixing ant and wscript.  When the conversion to maven was done the existing directory structure in git was kept.  So the src, testing, and resources folders in ACS don't follow the standard maven conventions.  This parent pom forces the folders back to the standard conventions</description>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <build>
-    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
-    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
-    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
-    <outputDirectory>${basedir}/target/classes</outputDirectory>
-    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>${basedir}/src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${basedir}/src/test/resources</directory>
-      </testResource>
-    </testResources>
-  </build>
-</project>
diff --git a/packaging/build-deb.sh b/packaging/build-deb.sh
index d8f2f8f..c13fb60 100755
--- a/packaging/build-deb.sh
+++ b/packaging/build-deb.sh
@@ -16,18 +16,12 @@
 # specific language governing permissions and limitations
 # under the License.
 
-#set -e
+set -e
 
 #
 # This script builds Debian packages for CloudStack and does
 # so by altering the debian/changelog file and add the Ubuntu
-# version as a suffix, for example: 4.9.0~xenial
-#
-# To build packages for Ubuntu 14.04 run this script on a
-# 14.04 system. The same goes for Ubuntu 16.04
-#
-# The biggest difference between those two versions is the
-# sysvinit vs systemd and Java 7 vs Java 8
+# version as a suffix, for example: 4.10.0~xenial
 #
 # These packages can be build using Docker for example:
 #
@@ -36,22 +30,115 @@
 # Ubuntu 16.04
 # docker run -ti -v /tmp:/src ubuntu:16.04 /bin/bash -c "apt-get update && apt-get install -y dpkg-dev python debhelper openjdk-8-jdk genisoimage python-mysql.connector maven lsb-release devscripts dh-systemd python-setuptools && /src/cloudstack/packaging/build-deb.sh"
 #
-# Ubuntu 14.04
-# docker run -ti -v /tmp:/src ubuntu:14.04 /bin/bash -c "apt-get update && apt-get install -y dpkg-dev python debhelper openjdk-8-jdk genisoimage python-mysql.connector maven lsb-release devscripts dh-systemd python-setuptools && /src/cloudstack/packaging/build-deb.sh"
-#
 
-cd `dirname $0`
-cd ..
+function usage() {
+    cat << USAGE
+Usage: ./build-deb.sh [OPTIONS]...
+Package CloudStack for Debian based distribution.
 
-DCH=$(which dch)
-if [ -z "$DCH" ] ; then
+If there's a "branding" string in the POM version (e.g. x.y.z.a-NAME[-SNAPSHOT]), the branding name will
+be used in the final generated package like: cloudstack-management_x.y.z.a-NAME-SNAPSHOT~xenial_all.deb
+note that you can override/provide "branding" string with "-b, --brand" flag as well.
+
+Optional arguments:
+   -b, --brand string                      Set branding to be used in package name (it will override any branding string in POM version)
+   -T, --use-timestamp                     Use epoch timestamp instead of SNAPSHOT in the package name (if not provided, use "SNAPSHOT")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   build-deb.sh --use-timestamp
+   build-deb.sh --brand foo
+
+USAGE
+    exit 0
+}
+
+BRANDING=""
+USE_TIMESTAMP="false"
+
+while [ -n "$1" ]; do
+    case "$1" in
+        -h | --help)
+            usage
+            ;;
+
+        -b | --brand)
+            if [ -n "$BRANDING" ]; then
+                echo "ERROR: you have already entered value for -b, --brand"
+                exit 1
+            else
+                BRANDING=$2
+                shift 2
+            fi
+            ;;
+
+        -T | --use-timestamp)
+            if [ "$USE_TIMESTAMP" == "true" ]; then
+                echo "ERROR: you have already entered value for -T, --use-timestamp"
+                exit 1
+            else
+                USE_TIMESTAMP="true"
+                shift 1
+            fi
+            ;;
+
+        -*|*)
+            echo "ERROR: no such option $1. -h or --help for help"
+            exit 1
+            ;;
+    esac
+done
+
+if [ -z "$(which dch)" ] ; then
     echo -e "dch not found, please install devscripts at first. \nDEB Build Failed"
-    exit
+    exit 1
+fi
+
+NOW="$(date +%s)"
+PWD=$(cd $(dirname "$0") && pwd -P)
+cd $PWD/../
+
+# Fail early if working directory is NOT clean and --use-timestamp was provided
+if [ "$USE_TIMESTAMP" == "true" ]; then
+    if [ -n "$(cd $PWD; git status -s)" ]; then
+        echo "Erro: You have uncommitted changes and asked for --use-timestamp to be used."
+        echo "      --use-timestamp flag is going to temporarily change  POM versions  and"
+        echo "      revert them at the end of build, and there's no  way we can do partial"
+        echo "      revert. Please commit your changes first or omit --use-timestamp flag."
+        exit 1
+    fi
 fi
 
 VERSION=$(head -n1 debian/changelog  |awk -F [\(\)] '{print $2}')
 DISTCODE=$(lsb_release -sc)
 
+if [ "$USE_TIMESTAMP" == "true" ]; then
+    # use timestamp instead of SNAPSHOT
+    if echo "$VERSION" | grep -q SNAPSHOT ; then
+        # apply/override branding, if provided
+        if [ "$BRANDING" != "" ]; then
+            VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+            VERSION="$VERSION-$BRANDING-$NOW"
+        else
+            VERSION=`echo $VERSION | sed 's/-SNAPSHOT/-'$NOW'/g'`
+        fi
+
+        branch=$(cd $PWD; git rev-parse --abbrev-ref HEAD)
+        (cd $PWD; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+    fi
+else
+    # apply/override branding, if provided
+    if [ "$BRANDING" != "" ]; then
+        VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+        VERSION="$VERSION-$BRANDING"
+
+        branch=$(cd $PWD; git rev-parse --abbrev-ref HEAD)
+        (cd $PWD; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+    fi
+fi
+
 /bin/cp debian/changelog /tmp/changelog.orig
 
 dch -b -v "${VERSION}~${DISTCODE}" -u low -m "Apache CloudStack Release ${VERSION}"
@@ -61,3 +148,7 @@
 dpkg-buildpackage -uc -us -b
 
 /bin/mv /tmp/changelog.orig debian/changelog
+
+if [ "$USE_TIMESTAMP" == "true" ]; then
+    (cd $PWD; git reset --hard)
+fi
diff --git a/packaging/centos63/cloud-management.rc b/packaging/centos63/cloud-management.rc
index df7a583..8dcd7aa 100755
--- a/packaging/centos63/cloud-management.rc
+++ b/packaging/centos63/cloud-management.rc
@@ -88,7 +88,7 @@
 
     echo -n "Starting $PROGNAME" "$SHORTNAME"
 
-    if daemon --pidfile $PIDFILE $DAEMON -home "$JAVA_HOME" -cp "$CLASSPATH" -pidfile "$PIDFILE" -user "$USER" \
+    if daemon --pidfile $PIDFILE $DAEMON $JAVA_DEBUG -home "$JAVA_HOME" -cp "$CLASSPATH" -pidfile "$PIDFILE" -user "$USER" \
       -errfile $LOGDIR/cloudstack-management.err $JAVA_OPTS $CLASS
         RETVAL=$?
     then
diff --git a/packaging/centos63/cloud-usage.rc b/packaging/centos63/cloud-usage.rc
index 7741137..15e9ee5 100755
--- a/packaging/centos63/cloud-usage.rc
+++ b/packaging/centos63/cloud-usage.rc
@@ -96,7 +96,7 @@
 
     echo -n "Starting $PROGNAME" "$SHORTNAME"
 
-    if daemon --pidfile $PIDFILE $DAEMON -home "$JAVA_HOME" -cp "$CLASSPATH" -pidfile "$PIDFILE" -user "$USER" \
+    if daemon --pidfile $PIDFILE $DAEMON $JAVA_DEBUG -home "$JAVA_HOME" -cp "$CLASSPATH" -pidfile "$PIDFILE" -user "$USER" \
       -errfile $LOGDIR/cloudstack-usage.err -outfile $LOGDIR/cloudstack-usage.out -Dpid=$$ $CLASS
         RETVAL=$?
     then
diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec
index a957380..05575e0 100644
--- a/packaging/centos63/cloud.spec
+++ b/packaging/centos63/cloud.spec
@@ -24,13 +24,8 @@
 Name:      cloudstack
 Summary:   CloudStack IaaS Platform
 #http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages
-%if "%{?_prerelease}" != ""
-%define _maventag %{_ver}-SNAPSHOT
+%define _maventag %{_fullver}
 Release:   %{_rel}%{dist}
-%else
-%define _maventag %{_ver}
-Release:   %{_rel}%{dist}
-%endif
 
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 
@@ -260,7 +255,7 @@
 cp packaging/centos63/cloudstack-sccs ${RPM_BUILD_ROOT}/usr/bin
  
 mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
-cp -r plugins/network-elements/cisco-vnmc/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
+cp -r plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
 
 # Management
 mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/
diff --git a/packaging/centos7/cloud.spec b/packaging/centos7/cloud.spec
index cb07e2b..34fab72 100644
--- a/packaging/centos7/cloud.spec
+++ b/packaging/centos7/cloud.spec
@@ -24,13 +24,8 @@
 Name:      cloudstack
 Summary:   CloudStack IaaS Platform
 #http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages
-%if "%{?_prerelease}" != ""
-%define _maventag %{_ver}-SNAPSHOT
+%define _maventag %{_fullver}
 Release:   %{_rel}%{dist}
-%else
-%define _maventag %{_ver}
-Release:   %{_rel}%{dist}
-%endif
 
 %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 
@@ -226,7 +221,7 @@
 cp packaging/centos7/cloudstack-sccs ${RPM_BUILD_ROOT}/usr/bin
 
 mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
-cp -r plugins/network-elements/cisco-vnmc/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
+cp -r plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts/network/cisco
 
 # Management
 mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/
diff --git a/packaging/debian/cloudstack-agent.init b/packaging/debian/cloudstack-agent.init
deleted file mode 100755
index 2610779..0000000
--- a/packaging/debian/cloudstack-agent.init
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/bin/bash
-
-### BEGIN INIT INFO
-# Provides:          cloudstack-agent
-# Required-Start:    $network $local_fs
-# Required-Stop:     $network $local_fs
-# Default-Start:     3 4 5
-# Default-Stop:      0 1 2 6
-# Short-Description: Start/stop Apache CloudStack Agent
-# Description: This scripts Starts/Stops the Apache CloudStack agent
-##  The CloudStack Agent is a part of the Apache CloudStack project and is used
-##  for managing KVM-based Hypervisors and performing secondary storage tasks inside
-##  the Secondary Storage System Virtual Machine.
-## JSVC (Java daemonizing) is used for starting and stopping the agent
-### END INIT INFO
-
-# 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.
-
-. /lib/lsb/init-functions
-
-TMP=/usr/share/cloudstack-agent/tmp
-SHORTNAME="cloudstack-agent"
-PIDFILE=/var/run/"$SHORTNAME".pid
-LOCKFILE=/var/lock/subsys/"$SHORTNAME"
-PROGNAME="CloudStack Agent"
-CLASS="com.cloud.agent.AgentShell"
-PROG="jsvc"
-DAEMON="/usr/bin/jsvc"
-SHUTDOWN_WAIT="30"
-
-unset OPTIONS
-[ -r /etc/default/"$SHORTNAME" ] && source /etc/default/"$SHORTNAME"
-
-# create java tmp dir if not found
-mkdir -m 0755 -p "$TMP"
-
-# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined in $DEFAULT)
-JDK_DIRS="/usr/lib/jvm/java-8-openjdk-amd64 /usr/lib/jvm/java-8-openjdk-i386 /usr/lib/jvm/java-8-oracle"
-
-for jdir in $JDK_DIRS; do
-    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
-        JAVA_HOME="$jdir"
-    fi
-done
-export JAVA_HOME
-
-ACP=`ls /usr/share/cloudstack-agent/lib/*.jar | tr '\n' ':' | sed s'/.$//'`
-PCP=`ls /usr/share/cloudstack-agent/plugins/*.jar 2>/dev/null | tr '\n' ':' | sed s'/.$//'`
-
-# We need to append the JSVC daemon JAR to the classpath
-# AgentShell implements the JSVC daemon methods
-export CLASSPATH="/usr/share/java/commons-daemon.jar:$ACP:$PCP:/etc/cloudstack/agent"
-
-wait_for_network() {
-    i=1
-    while [ $i -lt 10 ]
-    do
-        # Under Ubuntu and Debian libvirt by default creates a bridge called virbr0.
-        # That's why we want more then 3 lines back from brctl, so that there is a manually created bridge
-        if [ "$(brctl show|wc -l)" -gt 2 ]; then
-            break
-        else
-            sleep 1
-            let i=$i+1
-            continue
-        fi
-    done
-}
-
-start() {
-    if [ -s "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
-        log_daemon_msg "$PROGNAME apparently already running"
-        log_end_msg 0
-        exit 0
-    fi
-
-    log_daemon_msg "Starting $PROGNAME" "$SHORTNAME"
-    if hostname --fqdn >/dev/null 2>&1 ; then
-        true
-    else
-        log_failure_msg "The host name does not resolve properly to an IP address. Cannot start $PROGNAME"
-        log_end_msg 1
-        exit 1
-    fi
-
-    wait_for_network
-
-    if start_daemon -p $PIDFILE $DAEMON -Djava.io.tmpdir="$TMP" -Xms256m -Xmx2048m -cp "$CLASSPATH" -Djna.nosys=true -pidfile "$PIDFILE" -errfile SYSLOG $CLASS
-        RETVAL=$?
-    then
-        rc=0
-        sleep 1
-        if ! kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
-            log_failure_msg "$PROG failed to start"
-            rc=1
-        fi
-    else
-        rc=1
-    fi
-
-    if [ $rc -eq 0 ]; then
-        log_end_msg 0
-    else
-        log_end_msg 1
-        rm -f "$PIDFILE"
-    fi
-}
-
-stop() {
-    count="0"
-
-    log_daemon_msg "Stopping $PROGNAME" "$SHORTNAME"
-    killproc -p $PIDFILE $DAEMON
-
-    until [ "$count" -gt "$SHUTDOWN_WAIT" ]
-    do
-        agentPid=$(ps aux|grep [j]svc|grep $SHORTNAME)
-        if [ "$?" -gt "0" ];then
-            break
-        fi
-        sleep 1
-        let count="${count}+1"
-    done
-
-    agentPid=$(ps aux|grep [j]svc|grep $SHORTNAME)
-    if [ "$?" -eq "0" ]; then
-        agentPid=$(ps aux|grep [j]svc|awk '{print $2}')
-        if [ "$agentPid" != "" ]; then
-            log_warning_msg "$PROG still running, forcing kill"
-            kill -9 $agentPid
-        fi
-    fi
-
-    log_end_msg $?
-    rm -f "$PIDFILE"
-}
-
-case "$1" in
-    start)
-        start
-        ;;
-    stop)
-        stop
-        ;;
-    status)
-        status_of_proc -p "$PIDFILE" "$PROG" "$SHORTNAME"
-        RETVAL=$?
-        ;;
-    restart | force-reload)
-        stop
-        sleep 3
-        start
-        ;;
-    *)
-    echo "Usage: $0 {start|stop|restart|force-reload|status}"
-    RETVAL=3
-esac
-
-exit $RETVAL
diff --git a/packaging/debian/cloudstack-usage.init b/packaging/debian/cloudstack-usage.init
deleted file mode 100755
index 0517450..0000000
--- a/packaging/debian/cloudstack-usage.init
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/bin/bash
-
-### BEGIN INIT INFO
-# Provides:          cloudstack-usage
-# Required-Start:    $network $local_fs
-# Required-Stop:     $network $local_fs
-# Default-Start:     3 4 5
-# Default-Stop:      0 1 2 6
-# Short-Description: Start/stop Apache CloudStack Usage Monitor
-# Description: This scripts Starts/Stops the Apache CloudStack Usage Monitor
-##  The CloudStack Usage Monitor is a part of the Apache CloudStack project and is used
-##  for storing usage statistics from instances.
-## JSVC (Java daemonizing) is used for starting and stopping the usage monitor.
-### END INIT INFO
-
-# 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.
-
-. /lib/lsb/init-functions
-
-SHORTNAME="cloudstack-usage"
-PIDFILE=/var/run/"$SHORTNAME".pid
-PROGNAME="CloudStack Usage Monitor"
-CLASS="com.cloud.usage.UsageServer"
-PROG="jsvc"
-DAEMON="/usr/bin/jsvc"
-
-unset OPTIONS
-[ -r /etc/default/"$SHORTNAME" ] && source /etc/default/"$SHORTNAME"
-
-setJavaHome() {
-  # use $JAVA_HOME if defined
-  if [ -n "$JAVA_HOME" ] ; then
-    return
-  fi
-
-  # try java first
-  java=$(which java 2>/dev/null || :)
-
-  # try javac if java is not found
-  if [ -z "$java" ] ; then
-    java=$(which javac 2>/dev/null || :)
-  fi
-
-  if [ -n "$java" ] ; then
-    JAVA_HOME=$(dirname $(dirname $(readlink -e $java)))
-    export JAVA_HOME
-    return
-  fi
-
-  # If everything has failed, try hardcoded paths
-  # The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined in $DEFAULT)
-  JDK_DIRS="/usr/lib/jvm/java-8-openjdk-amd64 /usr/lib/jvm/java-8-openjdk-i386 /usr/lib/jvm/java-8-oracle /usr/lib/jvm/java-8-openjdk"
-  for jdir in $JDK_DIRS; do
-    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
-      JAVA_HOME="$jdir"
-      export JAVA_HOME
-      return
-    fi
-  done
-
-  # didnt find java home. exiting with error
-  exit 1
-}
-
-setJavaHome
-
-UCP=`ls /usr/share/cloudstack-usage/lib/*.jar | tr '\n' ':' | sed s'/.$//'`
-PCP=`ls /usr/share/cloudstack-usage/plugins/*.jar 2>/dev/null | tr '\n' ':' | sed s'/.$//'`
-
-# We need to append the JSVC daemon JAR to the classpath
-# AgentShell implements the JSVC daemon methods
-export CLASSPATH="/usr/share/java/commons-daemon.jar:/usr/share/java/mysql-connector-java.jar:$UCP:$PCP:/etc/cloudstack/usage"
-
-start() {
-    if [ -s "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
-        log_daemon_msg "$PROGNAME apparently already running"
-        log_end_msg 0
-        exit 0
-    fi
-
-    log_daemon_msg "Starting $PROGNAME" "$SHORTNAME"
-    if hostname --fqdn >/dev/null 2>&1 ; then
-        true
-    else
-        log_failure_msg "The host name does not resolve properly to an IP address. Cannot start $PROGNAME"
-        log_end_msg 1
-        exit 1
-    fi
-
-    if start_daemon -p $PIDFILE $DAEMON -home "$JAVA_HOME" -cp "$CLASSPATH" -pidfile "$PIDFILE" -outfile SYSLOG -errfile SYSLOG -Dpid=$$ $CLASS
-        RETVAL=$?
-    then
-        rc=0
-        sleep 1
-        if ! kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
-            log_failure_msg "$PROG failed to start"
-            rc=1
-        fi
-    else
-        rc=1
-    fi
-
-    if [ $rc -eq 0 ]; then
-        log_end_msg 0
-    else
-        log_end_msg 1
-        rm -f "$PIDFILE"
-    fi
-}
-
-stop() {
-    log_daemon_msg "Stopping $PROGNAME" "$SHORTNAME"
-    killproc -p $PIDFILE $DAEMON
-    log_end_msg $?
-    rm -f "$PIDFILE"
-}
-
-case "$1" in
-    start)
-        start
-        ;;
-    stop)
-        stop
-        ;;
-    status)
-        status_of_proc -p "$PIDFILE" "$PROG" "$SHORTNAME"
-        RETVAL=$?
-        ;;
-    restart | force-reload)
-        stop
-        sleep 3
-        start
-        ;;
-    *)
-    echo "Usage: $0 {start|stop|restart|force-reload|status}"
-    RETVAL=3
-esac
-
-exit $RETVAL
diff --git a/packaging/debian/init/cloud-management b/packaging/debian/init/cloud-management
deleted file mode 100755
index 5ccef70..0000000
--- a/packaging/debian/init/cloud-management
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/sh
-#
-# /etc/init.d/cloudstack-management -- startup script for CloudStack
-
-# 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.
-### BEGIN INIT INFO
-# Provides:          cloudstack-management
-# Required-Start:    $local_fs $remote_fs $network
-# Required-Stop:     $local_fs $remote_fs $network
-# Should-Start:      $named
-# Should-Stop:       $named
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: Start CloudStack.
-# Description:       Start the CloudStack Management Server.
-### END INIT INFO
-
-PATH=/bin:/usr/bin:/sbin:/usr/sbin
-NAME=cloudstack-management
-DESC="CloudStack Management Server"
-DAEMON=/usr/bin/jsvc
-DEFAULT=/etc/default/$NAME
-USER="cloud"
-GROUP="cloud"
-CLOUDSTACK_PID="/var/run/$NAME.pid"
-
-# We have to explicitly set the HOME variable to the homedir from the user "cloud"
-# This is because various scripts run by the management server read the HOME variable
-# and fail when this init script is run manually.
-HOME=$(echo ~cloud)
-
-if [ `id -u` -ne 0 ]; then
-	echo "You need root privileges to run this script"
-	exit 1
-fi
-
-if [ -r /etc/default/locale ]; then
-	. /etc/default/locale
-	export LANG
-fi
-
-. /lib/lsb/init-functions
-. /etc/default/rcS
-
-# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not
-# defined in $DEFAULT)
-JDK_DIRS="/usr/lib/jvm/java-8-openjdk-amd64 /usr/lib/jvm/java-8-openjdk-i386 /usr/lib/jvm/java-8-oracle /usr/lib/jvm/java-8-openjdk"
-
-# Look for the right JVM to use
-for jdir in $JDK_DIRS; do
-    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
-    JAVA_HOME="$jdir"
-    fi
-done
-export JAVA_HOME
-
-# overwrite settings from default file
-if [ -f "$DEFAULT" ]; then
-	. "$DEFAULT"
-fi
-
-JARS=$(ls /usr/share/cloudstack-management/lib/*.jar | tr '\n' ':' | sed s'/.$//')
-CLASSPATH="$JARS:$CLASSPATH:/usr/share/java/commons-daemon.jar"
-
-[ -f "$DAEMON" ] || exit 0
-
-# Look for Java Secure Sockets Extension (JSSE) JARs
-if [ -z "${JSSE_HOME}" -a -r "${JAVA_HOME}/jre/lib/jsse.jar" ]; then
-    JSSE_HOME="${JAVA_HOME}/jre/"
-fi
-export JSSE_HOME
-
-case "$1" in
-  start)
-	if [ -z "$JAVA_HOME" ]; then
-		log_failure_msg "no JDK found - please set JAVA_HOME"
-		exit 1
-	fi
-
-	log_daemon_msg "Starting $DESC" "$NAME"
-	if start-stop-daemon --test --start --quiet --pidfile "$CLOUDSTACK_PID" \
-		--user $USER --startas "$JAVA_HOME/bin/java"; then
-
-		# fix storage issues on nfs mounts
-		umask 000
-		start-stop-daemon --start --quiet --pidfile "$CLOUDSTACK_PID" \
-		--user $USER --group $GROUP --exec $DAEMON -- -user "$USER" -server \
-		-home "$JAVA_HOME" -cp "$CLASSPATH" \
-		-outfile SYSLOG -errfile $LOGDIR/$NAME.err \
-		-pidfile "$CLOUDSTACK_PID" $JAVA_OPTS "$BOOTSTRAP_CLASS"
-		log_end_msg $?
-	else
-		log_progress_msg "(already running)"
-		log_end_msg 0
-	fi
-	;;
-  stop)
-	log_daemon_msg "Stopping $DESC" "$NAME"
-	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$CLOUDSTACK_PID"
-	RETVAL="$?"
-	[ "$RETVAL" = 2 ] && return 2
-	log_end_msg 0
-	;;
-   status)
-        if start-stop-daemon --test --start --pidfile "$CLOUDSTACK_PID" \
-		--user $USER --startas "$JAVA_HOME/bin/java" \
-		>/dev/null; then
-
-		if [ -f "$CLOUDSTACK_PID" ]; then
-		    log_success_msg "$DESC is not running, but pid file exists."
-			exit 1
-		else
-		    log_success_msg "$DESC is not running."
-			exit 3
-		fi
-	else
-		log_success_msg "$DESC is running with pid `cat $CLOUDSTACK_PID`"
-	fi
-        ;;
-  restart|force-reload)
-        if start-stop-daemon --test --stop --pidfile "$CLOUDSTACK_PID" \
-		--user $USER --startas "$JAVA_HOME/bin/java" \
-		>/dev/null; then
-		$0 stop
-		sleep 1
-	fi
-	$0 start
-	;;
-  *)
-	log_success_msg "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
-	exit 1
-	;;
-esac
-
-exit 0
diff --git a/packaging/package.sh b/packaging/package.sh
index 8a87661..fe96eac8 100755
--- a/packaging/package.sh
+++ b/packaging/package.sh
@@ -17,48 +17,68 @@
 # under the License.
 
 function usage() {
-    echo ""
-    echo "usage: ./package.sh [-h|--help] -d|--distribution <name> [-r|--release <version>] [-p|--pack oss|OSS|noredist|NOREDIST] [-s|--simulator default|DEFAULT|simulator|SIMULATOR]"
-    echo ""
-    echo "The supported arguments are:"
-    echo "  To package with only redistributable libraries (default)"
-    echo "    -p|--pack oss|OSS"
-    echo "  To package with non-redistributable libraries"
-    echo "    -p|--pack noredist|NOREDIST"
-    echo "  To build a package for a distribution (mandatory)"
-    echo "    -d|--distribution centos7|centos63|fedora20|fedora21"
-    echo "  To set the package release version (optional)"
-    echo "  (default is 1 for normal and prereleases, empty for SNAPSHOT)"
-    echo "    -r|--release version(integer)"
-    echo "  To build for Simulator (optional)"
-    echo "    -s|--simulator default|DEFAULT|simulator|SIMULATOR"
-    echo "  To display this information"
-    echo "    -h|--help"
-    echo ""
-    echo "Examples: ./package.sh --pack oss"
-    echo "          ./package.sh --pack noredist"
-    echo "          ./package.sh --pack oss --distribution centos7 --release 42"
-    echo "          ./package.sh --distribution centos7 --release 42"
-    echo "          ./package.sh --distribution centos7"
+    cat << USAGE
+Usage: ./package.sh -d DISTRO [OPTIONS]...
+Package CloudStack for specific distribution and provided options.
+
+If there's a "branding" string in the POM version (e.g. x.y.z.a-NAME[-SNAPSHOT]), the branding name will
+be used in the final generated package like: cloudstack-management-x.y.z.a-NAME.NUMBER.el7.centos.x86_64
+note that you can override/provide "branding" string with "-b, --brand" flag as well.
+
+Mandatory arguments:
+   -d, --distribution string               Build package for specified distribution ("centos7"|"centos63")
+
+Optional arguments:
+   -p, --pack string                       Define which type of libraries to package ("oss"|"OSS"|"noredist"|"NOREDIST") (default "oss")
+                                             - oss|OSS to package with only redistributable libraries
+                                             - noredist|NOREDIST to package with non-redistributable libraries
+   -r, --release integer                   Set the package release version (default is 1 for normal and prereleases, empty for SNAPSHOT)
+   -s, --simulator string                  Build package for Simulator ("default"|"DEFAULT"|"simulator"|"SIMULATOR") (default "default")
+   -b, --brand string                      Set branding to be used in package name (it will override any branding string in POM version)
+   -T, --use-timestamp                     Use epoch timestamp instead of SNAPSHOT in the package name (if not provided, use "SNAPSHOT")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   package.sh --distribution centos7
+   package.sh --distribution centos7 --pack oss
+   package.sh --distribution centos7 --pack noredist
+   package.sh --distribution centos7 --release 42
+   package.sh --distribution centos7 --pack noredist --release 42
+
+USAGE
+    exit 0
 }
 
+PWD=$(cd $(dirname "$0") && pwd -P)
+NOW="$(date +%s)"
+
 # packaging
 #   $1 redist flag
 #   $2 simulator flag
 #   $3 distribution name
 #   $4 package release version
+#   $5 brand string to apply/override
+#   $6 use timestamp flag
 function packaging() {
-    CWD=$(pwd)
-    RPMDIR=$CWD/../dist/rpmbuild
+    RPMDIR=$PWD/../dist/rpmbuild
     PACK_PROJECT=cloudstack
+
     if [ -n "$1" ] ; then
         DEFOSSNOSS="-D_ossnoss $1"
     fi
     if [ -n "$2" ] ; then
         DEFSIM="-D_sim $2"
     fi
+    if [ "$6" == "true" ]; then
+        INDICATOR="$NOW"
+    else
+        INDICATOR="SNAPSHOT"
+    fi
 
     DISTRO=$3
+
     MVN=$(which mvn)
     if [ -z "$MVN" ] ; then
         MVN=$(locate bin/mvn | grep -e mvn$ | tail -1)
@@ -67,24 +87,63 @@
             exit 2
         fi
     fi
-    VERSION=$(cd ../; $MVN org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep --color=none '^[0-9]\.')
-    if echo "$VERSION" | grep -q SNAPSHOT ; then
-        REALVER=$(echo "$VERSION" | cut -d '-' -f 1)
-        if [ -n "$4" ] ; then
-            DEFPRE="-D_prerelease $4"
-            DEFREL="-D_rel SNAPSHOT$4"
-        else
-            DEFPRE="-D_prerelease 1"
-            DEFREL="-D_rel SNAPSHOT"
-        fi
+
+    VERSION=$(cd $PWD/../; $MVN org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep --color=none '^[0-9]\.')
+    REALVER=$(echo "$VERSION" | cut -d '-' -f 1)
+
+    if [ -n "$5" ]; then
+        BRAND="${5}."
     else
-        REALVER="$VERSION"
-        if [ -n "$4" ] ; then
-            DEFREL="-D_rel $4"
+        BASEVER=$(echo "$VERSION" | sed 's/-SNAPSHOT//g')
+        BRAND=$(echo "$BASEVER" | cut -d '-' -f 2)
+
+        if [ "$REALVER" != "$BRAND" ]; then
+            BRAND="${BRAND}."
         else
-            DEFREL="-D_rel 1"
+            BRAND=""
         fi
     fi
+
+    if echo "$VERSION" | grep -q SNAPSHOT ; then
+        if [ -n "$4" ] ; then
+            DEFREL="-D_rel ${BRAND}${INDICATOR}.$4"
+        else
+            DEFREL="-D_rel ${BRAND}${INDICATOR}"
+        fi
+    else
+        if [ -n "$4" ] ; then
+            DEFREL="-D_rel ${BRAND}$4"
+        else
+            DEFREL="-D_rel ${BRAND}1"
+        fi
+    fi
+
+    if [ "$USE_TIMESTAMP" == "true" ]; then
+        # use timestamp instead of SNAPSHOT
+        if echo "$VERSION" | grep -q SNAPSHOT ; then
+            # apply/override branding, if provided
+            if [ "$BRANDING" != "" ]; then
+                VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+                VERSION="$VERSION-$BRANDING-$NOW"
+            else
+                VERSION=`echo $VERSION | sed 's/-SNAPSHOT/-'$NOW'/g'`
+            fi
+
+            branch=$(cd $PWD/../; git rev-parse --abbrev-ref HEAD)
+            (cd $PWD/../; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+        fi
+    else
+        # apply/override branding, if provided
+        if [ "$BRANDING" != "" ]; then
+            VERSION=$(echo "$VERSION" | cut -d '-' -f 1) # remove any existing branding from POM version to be overriden
+            VERSION="$VERSION-$BRANDING"
+
+            branch=$(cd $PWD/../; git rev-parse --abbrev-ref HEAD)
+            (cd $PWD/../; ./tools/build/setnextversion.sh --version $VERSION --sourcedir . --branch $branch --no-commit)
+        fi
+    fi
+
+    DEFFULLVER="-D_fullver $VERSION"
     DEFVER="-D_ver $REALVER"
 
     echo "Preparing to package Apache CloudStack $VERSION"
@@ -96,17 +155,23 @@
     mkdir -p "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION"
 
     echo ". preparing source tarball"
-    (cd ../; tar -c --exclude .git --exclude dist . | tar -C "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION" -x )
+    (cd $PWD/../; tar -c --exclude .git --exclude dist . | tar -C "$RPMDIR/SOURCES/$PACK_PROJECT-$VERSION" -x )
     (cd "$RPMDIR/SOURCES/"; tar -czf "$PACK_PROJECT-$VERSION.tgz" "$PACK_PROJECT-$VERSION")
 
     echo ". executing rpmbuild"
-    cp "$DISTRO/cloud.spec" "$RPMDIR/SPECS"
+    cp "$PWD/$DISTRO/cloud.spec" "$RPMDIR/SPECS"
 
-    (cd "$RPMDIR"; rpmbuild --define "_topdir ${RPMDIR}" "${DEFVER}" "${DEFREL}" ${DEFPRE+"$DEFPRE"} ${DEFOSSNOSS+"$DEFOSSNOSS"} ${DEFSIM+"$DEFSIM"} -bb SPECS/cloud.spec)
+    (cd "$RPMDIR"; rpmbuild --define "_topdir ${RPMDIR}" "${DEFVER}" "${DEFFULLVER}" "${DEFREL}" ${DEFPRE+"$DEFPRE"} ${DEFOSSNOSS+"$DEFOSSNOSS"} ${DEFSIM+"$DEFSIM"} -bb SPECS/cloud.spec)
     if [ $? -ne 0 ]; then
+        if [ "$USE_TIMESTAMP" == "true" ]; then
+            (cd $PWD/../; git reset --hard)
+        fi
         echo "RPM Build Failed "
         exit 3
     else
+        if [ "$USE_TIMESTAMP" == "true" ]; then
+            (cd $PWD/../; git reset --hard)
+        fi
         echo "RPM Build Done"
     fi
     exit
@@ -116,22 +181,20 @@
 SIM=""
 PACKAGEVAL=""
 RELEASE=""
+BRANDING=""
+USE_TIMESTAMP="false"
 
-SHORTOPTS="hp:s:d:r:"
-LONGOPTS="help,pack:simulator:distribution:release:"
-ARGS=$(getopt -s bash -u -a --options "$SHORTOPTS"  --longoptions "$LONGOPTS" --name "$0" -- "$@")
-eval set -- "$ARGS"
-echo "$ARGS"
-while [ $# -gt 0 ] ; do
+unrecognized_flags=""
+
+while [ -n "$1" ]; do
     case "$1" in
         -h | --help)
             usage
             exit 0
             ;;
+
         -p | --pack)
-            echo "Packaging CloudStack..."
             PACKAGEVAL=$2
-            echo "$PACKAGEVAL"
             if [ "$PACKAGEVAL" == "oss" -o "$PACKAGEVAL" == "OSS" ] ; then
                 PACKAGEVAL=""
             elif [ "$PACKAGEVAL" == "noredist" -o "$PACKAGEVAL" == "NOREDIST" ] ; then
@@ -141,11 +204,11 @@
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -s | --simulator)
             SIM=$2
-            echo "$SIM"
             if [ "$SIM" == "default" -o "$SIM" == "DEFAULT" ] ; then
                 SIM="false"
             elif [ "$SIM" == "simulator" -o "$SIM" == "SIMULATOR" ] ; then
@@ -155,8 +218,9 @@
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -d | --distribution)
             TARGETDISTRO=$2
             if [ -z "$TARGETDISTRO" ] ; then
@@ -164,22 +228,52 @@
                 usage
                 exit 1
             fi
-            shift
+            shift 2
             ;;
+
         -r | --release)
             RELEASE=$2
-            shift
+            shift 2
             ;;
-        -)
-            echo "Error: Unrecognized option"
-            usage
-            exit 1
+
+        -b | --brand)
+            BRANDING=$2
+            shift 2
             ;;
+
+        -T | --use-timestamp)
+            USE_TIMESTAMP="true"
+            shift 1
+            ;;
+
+        -*)
+            unrecognized_flags="${unrecognized_flags}$1 "
+            shift 1
+            ;;
+
         *)
-            shift
+            shift 1
             ;;
     esac
 done
 
-packaging "$PACKAGEVAL" "$SIM" "$TARGETDISTRO" "$RELEASE"
+if [ -n "$unrecognized_flags" ]; then
+    echo "Warning: Unrecognized option(s) found \" ${unrecognized_flags}\""
+    echo "         You're advised to fix your build job scripts and prevent using these"
+    echo "         flags, as in the future release(s) they will break packaging script."
+    echo ""
+fi
 
+# Fail early if working directory is NOT clean and --use-timestamp was provided
+if [ "$USE_TIMESTAMP" == "true" ]; then
+    if [ -n "$(cd $PWD/../; git status -s)" ]; then
+        echo "Erro: You have uncommitted changes and asked for --use-timestamp to be used."
+        echo "      --use-timestamp flag is going to temporarily change  POM versions  and"
+        echo "      revert them at the end of build, and there's no  way we can do partial"
+        echo "      revert. Please commit your changes first or omit --use-timestamp flag."
+        exit 1
+    fi
+fi
+
+echo "Packaging CloudStack..."
+packaging "$PACKAGEVAL" "$SIM" "$TARGETDISTRO" "$RELEASE" "$BRANDING" "$USE_TIMESTAMP"
diff --git a/packaging/systemd/cloudstack-agent.default b/packaging/systemd/cloudstack-agent.default
index 36f0562..dba2c0c 100644
--- a/packaging/systemd/cloudstack-agent.default
+++ b/packaging/systemd/cloudstack-agent.default
@@ -20,3 +20,7 @@
 CLASSPATH="/usr/share/cloudstack-agent/lib/*:/usr/share/cloudstack-agent/plugins/*:/etc/cloudstack/agent:/usr/share/cloudstack-common/scripts"
 
 JAVA_CLASS=com.cloud.agent.AgentShell
+
+#You can uncomment this if you want to enable Java remote debugging.
+#Feel free to change the parameters at your will. The 'address' field defines the port to be used.
+#JAVA_DEBUG="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
diff --git a/packaging/systemd/cloudstack-agent.service b/packaging/systemd/cloudstack-agent.service
index 9bdbdf8..72e99fe 100644
--- a/packaging/systemd/cloudstack-agent.service
+++ b/packaging/systemd/cloudstack-agent.service
@@ -24,7 +24,7 @@
 [Service]
 Type=simple
 EnvironmentFile=/etc/default/cloudstack-agent
-ExecStart=/usr/bin/java $JAVA_OPTS -cp $CLASSPATH $JAVA_CLASS
+ExecStart=/usr/bin/java $JAVA_OPTS $JAVA_DEBUG -cp $CLASSPATH $JAVA_CLASS
 Restart=always
 RestartSec=10s
 
diff --git a/packaging/systemd/cloudstack-management.default b/packaging/systemd/cloudstack-management.default
index 00b8ec1..d59ebad 100644
--- a/packaging/systemd/cloudstack-management.default
+++ b/packaging/systemd/cloudstack-management.default
@@ -20,3 +20,13 @@
 CLASSPATH="/usr/share/cloudstack-management/lib/*:/etc/cloudstack/management:/usr/share/cloudstack-common:/usr/share/cloudstack-management/setup:/usr/share/cloudstack-management:/usr/share/java/mysql-connector-java.jar"
 
 BOOTSTRAP_CLASS=org.apache.cloudstack.ServerDaemon
+
+################################################################################################
+#You can uncomment one of these options if you want to enable Java remote debugging.           #
+#You can change the parameters at your will. The 'address' field defines the port to be used.  #
+################################################################################################ 
+# This option here should be used with 'systemmd' based operating systems such as CentOS7, Ubuntu 16, and so on.
+#JAVA_DEBUG="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
+
+# On the other hand, this option is used by CentOS6.
+#JAVA_DEBUG="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
\ No newline at end of file
diff --git a/packaging/systemd/cloudstack-management.service b/packaging/systemd/cloudstack-management.service
index f1be34e..1f4ded3 100644
--- a/packaging/systemd/cloudstack-management.service
+++ b/packaging/systemd/cloudstack-management.service
@@ -28,7 +28,7 @@
 EnvironmentFile=/etc/default/cloudstack-management
 WorkingDirectory=/var/log/cloudstack/management
 PIDFile=/var/run/cloudstack-management.pid
-ExecStart=/usr/bin/java $JAVA_OPTS -cp $CLASSPATH $BOOTSTRAP_CLASS
+ExecStart=/usr/bin/java $JAVA_DEBUG $JAVA_OPTS -cp $CLASSPATH $BOOTSTRAP_CLASS
 
 [Install]
 WantedBy=multi-user.target
diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml
index bb796e1..9edc21e 100644
--- a/plugins/acl/dynamic-role-based/pom.xml
+++ b/plugins/acl/dynamic-role-based/pom.xml
@@ -1,32 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-acl-dynamic-role-based</artifactId>
-  <name>Apache CloudStack Plugin - ACL Dynamic Role Based</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-acl-dynamic-role-based</artifactId>
+    <name>Apache CloudStack Plugin - ACL Dynamic Role Based</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/acl/dynamic-role-based/src/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
similarity index 100%
rename from plugins/acl/dynamic-role-based/src/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
rename to plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java
diff --git a/plugins/acl/dynamic-role-based/resources/META-INF/cloudstack/acl-dynamic-role-based/module.properties b/plugins/acl/dynamic-role-based/src/main/resources/META-INF/cloudstack/acl-dynamic-role-based/module.properties
similarity index 100%
rename from plugins/acl/dynamic-role-based/resources/META-INF/cloudstack/acl-dynamic-role-based/module.properties
rename to plugins/acl/dynamic-role-based/src/main/resources/META-INF/cloudstack/acl-dynamic-role-based/module.properties
diff --git a/plugins/acl/dynamic-role-based/resources/META-INF/cloudstack/acl-dynamic-role-based/spring-acl-dynamic-role-based-context.xml b/plugins/acl/dynamic-role-based/src/main/resources/META-INF/cloudstack/acl-dynamic-role-based/spring-acl-dynamic-role-based-context.xml
similarity index 100%
rename from plugins/acl/dynamic-role-based/resources/META-INF/cloudstack/acl-dynamic-role-based/spring-acl-dynamic-role-based-context.xml
rename to plugins/acl/dynamic-role-based/src/main/resources/META-INF/cloudstack/acl-dynamic-role-based/spring-acl-dynamic-role-based-context.xml
diff --git a/plugins/acl/dynamic-role-based/test/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessCheckerTest.java b/plugins/acl/dynamic-role-based/src/test/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessCheckerTest.java
similarity index 100%
rename from plugins/acl/dynamic-role-based/test/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessCheckerTest.java
rename to plugins/acl/dynamic-role-based/src/test/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessCheckerTest.java
diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml
index 5a03d9a..dcbaeae 100644
--- a/plugins/acl/static-role-based/pom.xml
+++ b/plugins/acl/static-role-based/pom.xml
@@ -1,32 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-acl-static-role-based</artifactId>
-  <name>Apache CloudStack Plugin - ACL Static Role Based</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-acl-static-role-based</artifactId>
+    <name>Apache CloudStack Plugin - ACL Static Role Based</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java b/plugins/acl/static-role-based/src/main/java/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
similarity index 100%
rename from plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
rename to plugins/acl/static-role-based/src/main/java/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java
diff --git a/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/module.properties b/plugins/acl/static-role-based/src/main/resources/META-INF/cloudstack/acl-static-role-based/module.properties
similarity index 100%
rename from plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/module.properties
rename to plugins/acl/static-role-based/src/main/resources/META-INF/cloudstack/acl-static-role-based/module.properties
diff --git a/plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml b/plugins/acl/static-role-based/src/main/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml
similarity index 100%
rename from plugins/acl/static-role-based/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml
rename to plugins/acl/static-role-based/src/main/resources/META-INF/cloudstack/acl-static-role-based/spring-acl-static-role-based-context.xml
diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml
index 578691b..d011cae 100644
--- a/plugins/affinity-group-processors/explicit-dedication/pom.xml
+++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml
@@ -1,33 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-explicit-dedication</artifactId>
-  <name>Apache CloudStack Plugin - Explicit Dedication Processor</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-  </build>
+<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-explicit-dedication</artifactId>
+    <name>Apache CloudStack Plugin - Explicit Dedication Processor</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java b/plugins/affinity-group-processors/explicit-dedication/src/main/java/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
similarity index 100%
rename from plugins/affinity-group-processors/explicit-dedication/src/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
rename to plugins/affinity-group-processors/explicit-dedication/src/main/java/org/apache/cloudstack/affinity/ExplicitDedicationProcessor.java
diff --git a/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/module.properties b/plugins/affinity-group-processors/explicit-dedication/src/main/resources/META-INF/cloudstack/explicit-dedication/module.properties
similarity index 100%
rename from plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/module.properties
rename to plugins/affinity-group-processors/explicit-dedication/src/main/resources/META-INF/cloudstack/explicit-dedication/module.properties
diff --git a/plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml b/plugins/affinity-group-processors/explicit-dedication/src/main/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml
similarity index 100%
rename from plugins/affinity-group-processors/explicit-dedication/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml
rename to plugins/affinity-group-processors/explicit-dedication/src/main/resources/META-INF/cloudstack/explicit-dedication/spring-explicit-dedication-context.xml
diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml
index 38d11e0..d52748f 100644
--- a/plugins/affinity-group-processors/host-affinity/pom.xml
+++ b/plugins/affinity-group-processors/host-affinity/pom.xml
@@ -1,33 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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">
+<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>
-    <name>Apache CloudStack Plugin - Host Affinity Processor</name>
     <artifactId>cloud-plugin-host-affinity</artifactId>
+    <name>Apache CloudStack Plugin - Host Affinity Processor</name>
     <parent>
-        <artifactId>cloudstack-plugins</artifactId>
         <groupId>org.apache.cloudstack</groupId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
-    <build>
-        <defaultGoal>install</defaultGoal>
-        <sourceDirectory>src</sourceDirectory>
-    </build>
-</project>
\ No newline at end of file
+</project>
diff --git a/plugins/affinity-group-processors/host-affinity/src/org/apache/cloudstack/affinity/HostAffinityProcessor.java b/plugins/affinity-group-processors/host-affinity/src/main/java/org/apache/cloudstack/affinity/HostAffinityProcessor.java
similarity index 100%
rename from plugins/affinity-group-processors/host-affinity/src/org/apache/cloudstack/affinity/HostAffinityProcessor.java
rename to plugins/affinity-group-processors/host-affinity/src/main/java/org/apache/cloudstack/affinity/HostAffinityProcessor.java
diff --git a/plugins/affinity-group-processors/host-affinity/resources/META-INF/cloudstack/host-affinity/module.properties b/plugins/affinity-group-processors/host-affinity/src/main/resources/META-INF/cloudstack/host-affinity/module.properties
similarity index 100%
rename from plugins/affinity-group-processors/host-affinity/resources/META-INF/cloudstack/host-affinity/module.properties
rename to plugins/affinity-group-processors/host-affinity/src/main/resources/META-INF/cloudstack/host-affinity/module.properties
diff --git a/plugins/affinity-group-processors/host-affinity/resources/META-INF/cloudstack/host-affinity/spring-host-affinity-context.xml b/plugins/affinity-group-processors/host-affinity/src/main/resources/META-INF/cloudstack/host-affinity/spring-host-affinity-context.xml
similarity index 100%
rename from plugins/affinity-group-processors/host-affinity/resources/META-INF/cloudstack/host-affinity/spring-host-affinity-context.xml
rename to plugins/affinity-group-processors/host-affinity/src/main/resources/META-INF/cloudstack/host-affinity/spring-host-affinity-context.xml
diff --git a/plugins/affinity-group-processors/host-affinity/test/org/apache/cloudstack/affinity/HostAffinityProcessorTest.java b/plugins/affinity-group-processors/host-affinity/src/test/java/org/apache/cloudstack/affinity/HostAffinityProcessorTest.java
similarity index 100%
rename from plugins/affinity-group-processors/host-affinity/test/org/apache/cloudstack/affinity/HostAffinityProcessorTest.java
rename to plugins/affinity-group-processors/host-affinity/src/test/java/org/apache/cloudstack/affinity/HostAffinityProcessorTest.java
diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml
index de4c665..edbbe55 100644
--- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml
+++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml
@@ -1,33 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-host-anti-affinity</artifactId>
-  <name>Apache CloudStack Plugin - Host Anti-Affinity Processor</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>    
-  </build>  
+<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-host-anti-affinity</artifactId>
+    <name>Apache CloudStack Plugin - Host Anti-Affinity Processor</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java b/plugins/affinity-group-processors/host-anti-affinity/src/main/java/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java
similarity index 100%
rename from plugins/affinity-group-processors/host-anti-affinity/src/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java
rename to plugins/affinity-group-processors/host-anti-affinity/src/main/java/org/apache/cloudstack/affinity/HostAntiAffinityProcessor.java
diff --git a/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/module.properties b/plugins/affinity-group-processors/host-anti-affinity/src/main/resources/META-INF/cloudstack/host-anti-affinity/module.properties
similarity index 100%
rename from plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/module.properties
rename to plugins/affinity-group-processors/host-anti-affinity/src/main/resources/META-INF/cloudstack/host-anti-affinity/module.properties
diff --git a/plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml b/plugins/affinity-group-processors/host-anti-affinity/src/main/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml
similarity index 100%
rename from plugins/affinity-group-processors/host-anti-affinity/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml
rename to plugins/affinity-group-processors/host-anti-affinity/src/main/resources/META-INF/cloudstack/host-anti-affinity/spring-host-anti-affinity-context.xml
diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml
index 0b570ae..17fb92e 100644
--- a/plugins/alert-handlers/snmp-alerts/pom.xml
+++ b/plugins/alert-handlers/snmp-alerts/pom.xml
@@ -1,43 +1,40 @@
 <!--
-  ~ 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">
-  <parent>
-    <artifactId>cloudstack-plugins</artifactId>
-    <groupId>org.apache.cloudstack</groupId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <name>Apache CloudStack Plugin - SNMP Alerts</name>
-  <artifactId>cloud-plugin-snmp-alerts</artifactId>
+  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
 
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicemix.bundles</groupId>
-      <artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-  </dependencies>
+    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>
+    <name>Apache CloudStack Plugin - SNMP Alerts</name>
+    <artifactId>cloud-plugin-snmp-alerts</artifactId>
+    <parent>
+        <artifactId>cloudstack-plugins</artifactId>
+        <groupId>org.apache.cloudstack</groupId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java b/plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java
rename to plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java b/plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java
rename to plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpHelper.java b/plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpHelper.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpHelper.java
rename to plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpHelper.java
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java b/plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java
rename to plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java b/plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java
rename to plugins/alert-handlers/snmp-alerts/src/main/java/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java
diff --git a/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java b/plugins/alert-handlers/snmp-alerts/src/test/java/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java
rename to plugins/alert-handlers/snmp-alerts/src/test/java/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java
diff --git a/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java b/plugins/alert-handlers/snmp-alerts/src/test/java/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java
similarity index 100%
rename from plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java
rename to plugins/alert-handlers/snmp-alerts/src/test/java/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java
diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml
index 6a230bb..bcad5a7 100644
--- a/plugins/alert-handlers/syslog-alerts/pom.xml
+++ b/plugins/alert-handlers/syslog-alerts/pom.xml
@@ -1,39 +1,36 @@
 <!--
-  ~ 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">
-  <parent>
-    <artifactId>cloudstack-plugins</artifactId>
-    <groupId>org.apache.cloudstack</groupId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <name>Apache CloudStack Plugin - Syslog Alerts</name>
-  <artifactId>cloud-plugin-syslog-alerts</artifactId>
+  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
 
-  <dependencies>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-  </dependencies>
+    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>
+    <name>Apache CloudStack Plugin - Syslog Alerts</name>
+    <artifactId>cloud-plugin-syslog-alerts</artifactId>
+    <parent>
+        <artifactId>cloudstack-plugins</artifactId>
+        <groupId>org.apache.cloudstack</groupId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java b/plugins/alert-handlers/syslog-alerts/src/main/java/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
similarity index 100%
rename from plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
rename to plugins/alert-handlers/syslog-alerts/src/main/java/org/apache/cloudstack/syslog/AlertsSyslogAppender.java
diff --git a/plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java b/plugins/alert-handlers/syslog-alerts/src/test/java/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
similarity index 100%
rename from plugins/alert-handlers/syslog-alerts/test/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
rename to plugins/alert-handlers/syslog-alerts/src/test/java/org/apache/cloudstack/syslog/AlertsSyslogAppenderTest.java
diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml
index 0422755..a8b084b 100644
--- a/plugins/api/discovery/pom.xml
+++ b/plugins/api/discovery/pom.xml
@@ -1,58 +1,57 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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
+<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-api-discovery</artifactId>
-  <name>Apache CloudStack Plugin - API Discovery</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.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>
-          <excludes>
-            <exclude>org/apache/cloudstack/discovery/integration/*</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>cloud-plugin-api-discovery</artifactId>
+    <name>Apache CloudStack Plugin - API Discovery</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</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>
+                    <excludes>
+                        <exclude>org/apache/cloudstack/discovery/integration/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/api/command/user/discovery/ListApisCmd.java
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiDiscoveryResponse.java
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiParameterResponse.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiParameterResponse.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiParameterResponse.java
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiResponseResponse.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/api/response/ApiResponseResponse.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/api/response/ApiResponseResponse.java
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryService.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryService.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryService.java
diff --git a/plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java b/plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
similarity index 100%
rename from plugins/api/discovery/src/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
rename to plugins/api/discovery/src/main/java/org/apache/cloudstack/discovery/ApiDiscoveryServiceImpl.java
diff --git a/plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java b/plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java
similarity index 100%
rename from plugins/api/discovery/test/org/apache/cloudstack/discovery/ApiDiscoveryTest.java
rename to plugins/api/discovery/src/test/java/org/apache/cloudstack/discovery/ApiDiscoveryTest.java
diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml
index 88283b3..21d9925 100644
--- a/plugins/api/rate-limit/pom.xml
+++ b/plugins/api/rate-limit/pom.xml
@@ -1,44 +1,45 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-api-limit-account-based</artifactId>
-  <name>Apache CloudStack Plugin - API Rate Limit</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <forkMode>always</forkMode>
-          <argLine>-Xmx2048m -XX:MaxPermSize=1024m</argLine>
-          <excludes>
-            <exclude>org/apache/cloudstack/ratelimit/integration/*</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>  
+<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-api-limit-account-based</artifactId>
+    <name>Apache CloudStack Plugin - API Rate Limit</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkMode>always</forkMode>
+                    <argLine>-Xmx2048m -XX:MaxPermSize=1024m</argLine>
+                    <excludes>
+                        <exclude>org/apache/cloudstack/ratelimit/integration/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/admin/ratelimit/ResetApiLimitCmd.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/api/response/ApiLimitResponse.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/response/ApiLimitResponse.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/api/response/ApiLimitResponse.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/api/response/ApiLimitResponse.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitService.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitService.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitService.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitService.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/ApiRateLimitServiceImpl.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/EhcacheLimitStore.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/LimitStore.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/LimitStore.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/LimitStore.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/LimitStore.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/StoreEntry.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntry.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/StoreEntry.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntry.java
diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/StoreEntryImpl.java b/plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntryImpl.java
similarity index 100%
rename from plugins/api/rate-limit/src/org/apache/cloudstack/ratelimit/StoreEntryImpl.java
rename to plugins/api/rate-limit/src/main/java/org/apache/cloudstack/ratelimit/StoreEntryImpl.java
diff --git a/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/module.properties b/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/module.properties
similarity index 100%
rename from plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/module.properties
rename to plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/module.properties
diff --git a/plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml b/plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml
similarity index 100%
rename from plugins/api/rate-limit/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml
rename to plugins/api/rate-limit/src/main/resources/META-INF/cloudstack/rate-limit/spring-rate-limit-context.xml
diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java
similarity index 100%
rename from plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java
rename to plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/ApiRateLimitTest.java
diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/APITest.java
similarity index 100%
rename from plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java
rename to plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/APITest.java
diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/LoginResponse.java
similarity index 100%
rename from plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java
rename to plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/LoginResponse.java
diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java b/plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java
similarity index 100%
rename from plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java
rename to plugins/api/rate-limit/src/test/java/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java
diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml
index 47de6b3..0c9cc2e 100644
--- a/plugins/api/solidfire-intg-test/pom.xml
+++ b/plugins/api/solidfire-intg-test/pom.xml
@@ -1,50 +1,51 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-api-solidfire-intg-test</artifactId>
-  <name>Apache CloudStack Plugin - API SolidFire Integration Testing</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-      <dependency>
-          <groupId>org.apache.cloudstack</groupId>
-          <artifactId>cloud-plugin-storage-volume-solidfire</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>
-          <excludes>
-            <exclude>org/apache/cloudstack/solidfire/integration/*</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+<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-api-solidfire-intg-test</artifactId>
+    <name>Apache CloudStack Plugin - API SolidFire Integration Testing</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-solidfire</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>
+                    <excludes>
+                        <exclude>org/apache/cloudstack/solidfire/integration/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetPathForVolumeCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetPathForVolumeCmd.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetPathForVolumeCmd.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetPathForVolumeCmd.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireAccountIdCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireAccountIdCmd.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireAccountIdCmd.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireAccountIdCmd.java
diff --git a/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdsCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdsCmd.java
new file mode 100644
index 0000000..0516b8e
--- /dev/null
+++ b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdsCmd.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.solidfire;
+
+import com.cloud.user.Account;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.solidfire.ApiSolidFireVolumeAccessGroupIdsResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.solidfire.SolidFireIntegrationTestManager;
+import org.apache.cloudstack.util.solidfire.SolidFireIntegrationTestUtil;
+
+@APICommand(name = "getSolidFireVolumeAccessGroupIds", responseObject = ApiSolidFireVolumeAccessGroupIdsResponse.class, description = "Get the SF Volume Access Group IDs",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class GetSolidFireVolumeAccessGroupIdsCmd extends BaseCmd {
+    private static final Logger LOGGER = Logger.getLogger(GetSolidFireVolumeAccessGroupIdsCmd.class.getName());
+    private static final String NAME = "getsolidfirevolumeaccessgroupidsresponse";
+
+    @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.STRING, description = "Cluster UUID", required = true)
+    private String clusterUuid;
+    @Parameter(name = ApiConstants.STORAGE_ID, type = CommandType.STRING, description = "Storage Pool UUID", required = true)
+    private String storagePoolUuid;
+
+    @Inject private SolidFireIntegrationTestManager manager;
+    @Inject private SolidFireIntegrationTestUtil util;
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return NAME;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Account account = CallContext.current().getCallingAccount();
+
+        if (account != null) {
+            return account.getId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() {
+        LOGGER.info("'GetSolidFireVolumeAccessGroupIdsCmd.execute' method invoked");
+
+        long[] sfVagIds = manager.getSolidFireVolumeAccessGroupIds(clusterUuid, storagePoolUuid);
+
+        ApiSolidFireVolumeAccessGroupIdsResponse response = new ApiSolidFireVolumeAccessGroupIdsResponse(sfVagIds);
+
+        response.setResponseName(getCommandName());
+        response.setObjectName("apisolidfirevolumeaccessgroupids");
+
+        this.setResponseObject(response);
+    }
+}
\ No newline at end of file
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeSizeCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeSizeCmd.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeSizeCmd.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeSizeCmd.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeSnapshotDetailsCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeSnapshotDetailsCmd.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeSnapshotDetailsCmd.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeSnapshotDetailsCmd.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeiScsiNameCmd.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeiScsiNameCmd.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeiScsiNameCmd.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/command/admin/solidfire/GetVolumeiScsiNameCmd.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiPathForVolumeResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiPathForVolumeResponse.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiPathForVolumeResponse.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiPathForVolumeResponse.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireAccountIdResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireAccountIdResponse.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireAccountIdResponse.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireAccountIdResponse.java
diff --git a/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdsResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdsResponse.java
new file mode 100644
index 0000000..a37da40
--- /dev/null
+++ b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdsResponse.java
@@ -0,0 +1,33 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.response.solidfire;
+
+import com.cloud.serializer.Param;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.BaseResponse;
+
+public class ApiSolidFireVolumeAccessGroupIdsResponse extends BaseResponse {
+    @SerializedName("solidFireVolumeAccessGroupIds")
+    @Param(description = "SolidFire Volume Access Group Ids")
+    private long[] solidFireVolumeAccessGroupIds;
+
+    public ApiSolidFireVolumeAccessGroupIdsResponse(long[] sfVolumeAccessGroupIds) {
+        solidFireVolumeAccessGroupIds = sfVolumeAccessGroupIds;
+    }
+}
\ No newline at end of file
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeSizeResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeSizeResponse.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeSizeResponse.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeSizeResponse.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiVolumeSnapshotDetailsResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiVolumeSnapshotDetailsResponse.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiVolumeSnapshotDetailsResponse.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiVolumeSnapshotDetailsResponse.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiVolumeiScsiNameResponse.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiVolumeiScsiNameResponse.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiVolumeiScsiNameResponse.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/response/solidfire/ApiVolumeiScsiNameResponse.java
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestService.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestService.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestService.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestService.java
diff --git a/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java
new file mode 100644
index 0000000..4adcbbe
--- /dev/null
+++ b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java
@@ -0,0 +1,48 @@
+// 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.solidfire;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.cloudstack.api.command.admin.solidfire.GetPathForVolumeCmd;
+// import org.apache.log4j.Logger;
+import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireAccountIdCmd;
+import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireVolumeAccessGroupIdsCmd;
+import org.apache.cloudstack.api.command.admin.solidfire.GetVolumeSnapshotDetailsCmd;
+import org.apache.cloudstack.api.command.admin.solidfire.GetVolumeiScsiNameCmd;
+import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireVolumeSizeCmd;
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.component.AdapterBase;
+
+@Component
+public class ApiSolidFireIntegrationTestServiceImpl extends AdapterBase implements ApiSolidFireIntegrationTestService {
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+
+        cmdList.add(GetPathForVolumeCmd.class);
+        cmdList.add(GetSolidFireAccountIdCmd.class);
+        cmdList.add(GetSolidFireVolumeAccessGroupIdsCmd.class);
+        cmdList.add(GetVolumeiScsiNameCmd.class);
+        cmdList.add(GetSolidFireVolumeSizeCmd.class);
+        cmdList.add(GetVolumeSnapshotDetailsCmd.class);
+
+        return cmdList;
+    }
+}
diff --git a/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java
new file mode 100644
index 0000000..302a034
--- /dev/null
+++ b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java
@@ -0,0 +1,23 @@
+// 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.solidfire;
+
+public interface SolidFireIntegrationTestManager {
+    long getSolidFireAccountId(String csAccountUuid, String storagePoolUuid);
+    long[] getSolidFireVolumeAccessGroupIds(String csClusterUuid, String storagePoolUuid);
+    long getSolidFireVolumeSize(String volumeUuid);
+}
diff --git a/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java
new file mode 100644
index 0000000..0339379
--- /dev/null
+++ b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java
@@ -0,0 +1,107 @@
+// 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.solidfire;
+
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.storage.VolumeDetailVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.user.AccountDetailVO;
+import com.cloud.user.AccountDetailsDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
+import org.apache.cloudstack.util.solidfire.SolidFireIntegrationTestUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.inject.Inject;
+
+@Component
+public class SolidFireIntegrationTestManagerImpl implements SolidFireIntegrationTestManager {
+    @Inject private AccountDetailsDao accountDetailsDao;
+    @Inject private HostDao hostDao;
+    @Inject private SolidFireIntegrationTestUtil util;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject private VolumeDao volumeDao;
+    @Inject private VolumeDetailsDao volumeDetailsDao;
+
+    @Override
+    public long getSolidFireAccountId(String csAccountUuid, String storagePoolUuid) {
+        long csAccountId = util.getAccountIdForAccountUuid(csAccountUuid);
+        long storagePoolId = util.getStoragePoolIdForStoragePoolUuid(storagePoolUuid);
+
+        AccountDetailVO accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId));
+
+        if (accountDetail == null) {
+            throw new CloudRuntimeException("Unable to find SF account for storage " + storagePoolUuid + " for CS account " + csAccountUuid);
+        }
+
+        String sfAccountId = accountDetail.getValue();
+
+        return Long.parseLong(sfAccountId);
+    }
+
+    @Override
+    public long[] getSolidFireVolumeAccessGroupIds(String csClusterUuid, String storagePoolUuid) {
+        long storagePoolId = util.getStoragePoolIdForStoragePoolUuid(storagePoolUuid);
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+        long csClusterId = util.getClusterIdForClusterUuid(csClusterUuid);
+        List<HostVO> hosts = hostDao.findByClusterId(csClusterId);
+
+        if (hosts == null) {
+            return new long[0];
+        }
+
+        List<Long> vagIds = new ArrayList<>(hosts.size());
+
+        for (HostVO host : hosts) {
+            String iqn = host.getStorageUrl();
+
+            SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVolumeAccessGroup(iqn, sfVags);
+
+            if (sfVag != null) {
+                if (!vagIds.contains(sfVag.getId())) {
+                    vagIds.add(sfVag.getId());
+                }
+            }
+        }
+
+        return vagIds.stream().mapToLong(l -> l).toArray();
+    }
+
+    @Override
+    public long getSolidFireVolumeSize(String volumeUuid) {
+        VolumeVO volume = volumeDao.findByUuid(volumeUuid);
+
+        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volume.getId(), SolidFireUtil.VOLUME_SIZE);
+
+        if (volumeDetail != null && volumeDetail.getValue() != null) {
+            return Long.parseLong(volumeDetail.getValue());
+        }
+
+        throw new CloudRuntimeException("Unable to determine the size of the SolidFire volume");
+    }
+}
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/util/solidfire/SolidFireIntegrationTestUtil.java b/plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/util/solidfire/SolidFireIntegrationTestUtil.java
similarity index 100%
rename from plugins/api/solidfire-intg-test/src/org/apache/cloudstack/util/solidfire/SolidFireIntegrationTestUtil.java
rename to plugins/api/solidfire-intg-test/src/main/java/org/apache/cloudstack/util/solidfire/SolidFireIntegrationTestUtil.java
diff --git a/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties b/plugins/api/solidfire-intg-test/src/main/resources/META-INF/cloudstack/solidfire-intg-test/module.properties
similarity index 100%
rename from plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/module.properties
rename to plugins/api/solidfire-intg-test/src/main/resources/META-INF/cloudstack/solidfire-intg-test/module.properties
diff --git a/plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml b/plugins/api/solidfire-intg-test/src/main/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml
similarity index 100%
rename from plugins/api/solidfire-intg-test/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml
rename to plugins/api/solidfire-intg-test/src/main/resources/META-INF/cloudstack/solidfire-intg-test/spring-solidfire-intg-test-context.xml
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdCmd.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdCmd.java
deleted file mode 100644
index 5c15e01..0000000
--- a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/command/admin/solidfire/GetSolidFireVolumeAccessGroupIdCmd.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.solidfire;
-
-import com.cloud.user.Account;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.solidfire.ApiSolidFireVolumeAccessGroupIdResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.solidfire.SolidFireIntegrationTestManager;
-import org.apache.cloudstack.util.solidfire.SolidFireIntegrationTestUtil;
-
-@APICommand(name = "getSolidFireVolumeAccessGroupId", responseObject = ApiSolidFireVolumeAccessGroupIdResponse.class, description = "Get the SF Volume Access Group ID",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class GetSolidFireVolumeAccessGroupIdCmd extends BaseCmd {
-    private static final Logger LOGGER = Logger.getLogger(GetSolidFireVolumeAccessGroupIdCmd.class.getName());
-    private static final String NAME = "getsolidfirevolumeaccessgroupidresponse";
-
-    @Parameter(name = ApiConstants.CLUSTER_ID, type = CommandType.STRING, description = "Cluster UUID", required = true)
-    private String clusterUuid;
-    @Parameter(name = ApiConstants.STORAGE_ID, type = CommandType.STRING, description = "Storage Pool UUID", required = true)
-    private String storagePoolUuid;
-
-    @Inject private SolidFireIntegrationTestManager manager;
-    @Inject private SolidFireIntegrationTestUtil util;
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return NAME;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() {
-        LOGGER.info("'GetSolidFireVolumeAccessGroupIdCmd.execute' method invoked");
-
-        long sfVagId = manager.getSolidFireVolumeAccessGroupId(clusterUuid, storagePoolUuid);
-
-        ApiSolidFireVolumeAccessGroupIdResponse response = new ApiSolidFireVolumeAccessGroupIdResponse(sfVagId);
-
-        response.setResponseName(getCommandName());
-        response.setObjectName("apisolidfirevolumeaccessgroupid");
-
-        this.setResponseObject(response);
-    }
-}
\ No newline at end of file
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdResponse.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdResponse.java
deleted file mode 100644
index 202a7e9..0000000
--- a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/response/solidfire/ApiSolidFireVolumeAccessGroupIdResponse.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response.solidfire;
-
-import com.cloud.serializer.Param;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class ApiSolidFireVolumeAccessGroupIdResponse extends BaseResponse {
-    @SerializedName("solidFireVolumeAccessGroupId")
-    @Param(description = "SolidFire Volume Access Group Id")
-    private long solidFireVolumeAccessGroupId;
-
-    public ApiSolidFireVolumeAccessGroupIdResponse(long sfVolumeAccessGroupId) {
-        solidFireVolumeAccessGroupId = sfVolumeAccessGroupId;
-    }
-}
\ No newline at end of file
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java
deleted file mode 100644
index 0458903..0000000
--- a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/api/solidfire/ApiSolidFireIntegrationTestServiceImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.solidfire;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.cloudstack.api.command.admin.solidfire.GetPathForVolumeCmd;
-// import org.apache.log4j.Logger;
-import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireAccountIdCmd;
-import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireVolumeAccessGroupIdCmd;
-import org.apache.cloudstack.api.command.admin.solidfire.GetVolumeSnapshotDetailsCmd;
-import org.apache.cloudstack.api.command.admin.solidfire.GetVolumeiScsiNameCmd;
-import org.apache.cloudstack.api.command.admin.solidfire.GetSolidFireVolumeSizeCmd;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.component.AdapterBase;
-
-@Component
-public class ApiSolidFireIntegrationTestServiceImpl extends AdapterBase implements ApiSolidFireIntegrationTestService {
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-
-        cmdList.add(GetPathForVolumeCmd.class);
-        cmdList.add(GetSolidFireAccountIdCmd.class);
-        cmdList.add(GetSolidFireVolumeAccessGroupIdCmd.class);
-        cmdList.add(GetVolumeiScsiNameCmd.class);
-        cmdList.add(GetSolidFireVolumeSizeCmd.class);
-        cmdList.add(GetVolumeSnapshotDetailsCmd.class);
-
-        return cmdList;
-    }
-}
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java
deleted file mode 100644
index bdc1180..0000000
--- a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManager.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.solidfire;
-
-public interface SolidFireIntegrationTestManager {
-    long getSolidFireAccountId(String csAccountUuid, String storagePoolUuid);
-    long getSolidFireVolumeAccessGroupId(String csClusterUuid, String storagePoolUuid);
-    long getSolidFireVolumeSize(String volumeUuid);
-}
diff --git a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java b/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java
deleted file mode 100644
index 66b9228..0000000
--- a/plugins/api/solidfire-intg-test/src/org/apache/cloudstack/solidfire/SolidFireIntegrationTestManagerImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.solidfire;
-
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.user.AccountDetailVO;
-import com.cloud.user.AccountDetailsDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
-import org.apache.cloudstack.util.solidfire.SolidFireIntegrationTestUtil;
-import org.springframework.stereotype.Component;
-
-import javax.inject.Inject;
-
-@Component
-public class SolidFireIntegrationTestManagerImpl implements SolidFireIntegrationTestManager {
-
-    @Inject private AccountDetailsDao accountDetailsDao;
-    @Inject private ClusterDetailsDao clusterDetailsDao;
-    @Inject private SolidFireIntegrationTestUtil util;
-    @Inject private VolumeDao volumeDao;
-    @Inject private VolumeDetailsDao volumeDetailsDao;
-
-    @Override
-    public long getSolidFireAccountId(String csAccountUuid, String storagePoolUuid) {
-        long csAccountId = util.getAccountIdForAccountUuid(csAccountUuid);
-        long storagePoolId = util.getStoragePoolIdForStoragePoolUuid(storagePoolUuid);
-
-        AccountDetailVO accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId));
-
-        if (accountDetail == null){
-            throw new CloudRuntimeException("Unable to find SF account for storage " + storagePoolUuid + " for CS account " + csAccountUuid);
-        }
-
-        String sfAccountId = accountDetail.getValue();
-
-        return Long.parseLong(sfAccountId);
-    }
-
-    @Override
-    public long getSolidFireVolumeAccessGroupId(String csClusterUuid, String storagePoolUuid) {
-        long csClusterId = util.getClusterIdForClusterUuid(csClusterUuid);
-        long storagePoolId = util.getStoragePoolIdForStoragePoolUuid(storagePoolUuid);
-
-        ClusterDetailsVO clusterDetails = clusterDetailsDao.findDetail(csClusterId, SolidFireUtil.getVagKey(storagePoolId));
-        String sfVagId = clusterDetails.getValue();
-
-        return Long.parseLong(sfVagId);
-    }
-
-    @Override
-    public long getSolidFireVolumeSize(String volumeUuid) {
-        VolumeVO volume = volumeDao.findByUuid(volumeUuid);
-
-        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volume.getId(), SolidFireUtil.VOLUME_SIZE);
-
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return Long.parseLong(volumeDetail.getValue());
-        }
-
-        throw new CloudRuntimeException("Unable to determine the size of the SolidFire volume");
-    }
-}
diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml
index cc61d24..4d15e29 100644
--- a/plugins/api/vmware-sioc/pom.xml
+++ b/plugins/api/vmware-sioc/pom.xml
@@ -1,47 +1,48 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-api-vmware-sioc</artifactId>
-  <name>Apache CloudStack Plugin - API VMware SIOC</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-       <artifactId>cloud-plugin-hypervisor-vmware</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 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-api-vmware-sioc</artifactId>
+    <name>Apache CloudStack Plugin - API VMware SIOC</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-vmware</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/api/vmware-sioc/src/org/apache/cloudstack/api/command/admin/sioc/UpdateSiocInfoCmd.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/command/admin/sioc/UpdateSiocInfoCmd.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/api/command/admin/sioc/UpdateSiocInfoCmd.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/command/admin/sioc/UpdateSiocInfoCmd.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/api/response/sioc/ApiUpdateSiocInfoResponse.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/response/sioc/ApiUpdateSiocInfoResponse.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/api/response/sioc/ApiUpdateSiocInfoResponse.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/response/sioc/ApiUpdateSiocInfoResponse.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/api/sioc/ApiSiocService.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/sioc/ApiSiocService.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/api/sioc/ApiSiocService.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/sioc/ApiSiocService.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/api/sioc/ApiSiocServiceImpl.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/sioc/ApiSiocServiceImpl.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/api/sioc/ApiSiocServiceImpl.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/api/sioc/ApiSiocServiceImpl.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/sioc/SiocManager.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/sioc/SiocManager.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/sioc/SiocManager.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/sioc/SiocManager.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/sioc/SiocManagerImpl.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/sioc/SiocManagerImpl.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/sioc/SiocManagerImpl.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/sioc/SiocManagerImpl.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/util/LoginInfo.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/util/LoginInfo.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/util/LoginInfo.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/util/LoginInfo.java
diff --git a/plugins/api/vmware-sioc/src/org/apache/cloudstack/util/vmware/VMwareUtil.java b/plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/util/vmware/VMwareUtil.java
similarity index 100%
rename from plugins/api/vmware-sioc/src/org/apache/cloudstack/util/vmware/VMwareUtil.java
rename to plugins/api/vmware-sioc/src/main/java/org/apache/cloudstack/util/vmware/VMwareUtil.java
diff --git a/plugins/api/vmware-sioc/resources/META-INF/cloudstack/vmware-sioc/module.properties b/plugins/api/vmware-sioc/src/main/resources/META-INF/cloudstack/vmware-sioc/module.properties
similarity index 100%
rename from plugins/api/vmware-sioc/resources/META-INF/cloudstack/vmware-sioc/module.properties
rename to plugins/api/vmware-sioc/src/main/resources/META-INF/cloudstack/vmware-sioc/module.properties
diff --git a/plugins/api/vmware-sioc/resources/META-INF/cloudstack/vmware-sioc/spring-sioc-context.xml b/plugins/api/vmware-sioc/src/main/resources/META-INF/cloudstack/vmware-sioc/spring-sioc-context.xml
similarity index 100%
rename from plugins/api/vmware-sioc/resources/META-INF/cloudstack/vmware-sioc/spring-sioc-context.xml
rename to plugins/api/vmware-sioc/src/main/resources/META-INF/cloudstack/vmware-sioc/spring-sioc-context.xml
diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml
index 645632e..736f69b 100644
--- a/plugins/ca/root-ca/pom.xml
+++ b/plugins/ca/root-ca/pom.xml
@@ -1,46 +1,47 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-ca-rootca</artifactId>
-  <name>Apache CloudStack Plugin - Inbuilt Root Certificate Authority</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+<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-ca-rootca</artifactId>
+    <name>Apache CloudStack Plugin - Inbuilt Root Certificate Authority</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCACustomTrustManager.java b/plugins/ca/root-ca/src/main/java/org/apache/cloudstack/ca/provider/RootCACustomTrustManager.java
similarity index 100%
rename from plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCACustomTrustManager.java
rename to plugins/ca/root-ca/src/main/java/org/apache/cloudstack/ca/provider/RootCACustomTrustManager.java
diff --git a/plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java b/plugins/ca/root-ca/src/main/java/org/apache/cloudstack/ca/provider/RootCAProvider.java
similarity index 100%
rename from plugins/ca/root-ca/src/org/apache/cloudstack/ca/provider/RootCAProvider.java
rename to plugins/ca/root-ca/src/main/java/org/apache/cloudstack/ca/provider/RootCAProvider.java
diff --git a/plugins/ca/root-ca/resources/META-INF/cloudstack/root-ca/module.properties b/plugins/ca/root-ca/src/main/resources/META-INF/cloudstack/root-ca/module.properties
similarity index 100%
rename from plugins/ca/root-ca/resources/META-INF/cloudstack/root-ca/module.properties
rename to plugins/ca/root-ca/src/main/resources/META-INF/cloudstack/root-ca/module.properties
diff --git a/plugins/ca/root-ca/resources/META-INF/cloudstack/root-ca/spring-root-ca-context.xml b/plugins/ca/root-ca/src/main/resources/META-INF/cloudstack/root-ca/spring-root-ca-context.xml
similarity index 100%
rename from plugins/ca/root-ca/resources/META-INF/cloudstack/root-ca/spring-root-ca-context.xml
rename to plugins/ca/root-ca/src/main/resources/META-INF/cloudstack/root-ca/spring-root-ca-context.xml
diff --git a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java b/plugins/ca/root-ca/src/test/java/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
similarity index 100%
rename from plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
rename to plugins/ca/root-ca/src/test/java/org/apache/cloudstack/ca/provider/RootCACustomTrustManagerTest.java
diff --git a/plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java b/plugins/ca/root-ca/src/test/java/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
similarity index 100%
rename from plugins/ca/root-ca/test/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
rename to plugins/ca/root-ca/src/test/java/org/apache/cloudstack/ca/provider/RootCAProviderTest.java
diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml
index d68b64c..f1cc846 100644
--- a/plugins/database/mysql-ha/pom.xml
+++ b/plugins/database/mysql-ha/pom.xml
@@ -1,28 +1,37 @@
-<!-- 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. -->
+<!--
+  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-database-mysqlha</artifactId>
-  <name>Apache CloudStack Plugin - MySQL HA Strategy</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
-    </dependency>
-  </dependencies>
+    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-database-mysqlha</artifactId>
+    <name>Apache CloudStack Plugin - MySQL HA Strategy</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/database/mysql-ha/src/com/cloud/utils/db/StaticStrategy.java b/plugins/database/mysql-ha/src/main/java/com/cloud/utils/db/StaticStrategy.java
similarity index 100%
rename from plugins/database/mysql-ha/src/com/cloud/utils/db/StaticStrategy.java
rename to plugins/database/mysql-ha/src/main/java/com/cloud/utils/db/StaticStrategy.java
diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml
index 17b1feb..df69c79 100644
--- a/plugins/database/quota/pom.xml
+++ b/plugins/database/quota/pom.xml
@@ -1,99 +1,66 @@
-<!-- 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. -->
+<!--
+  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-database-quota</artifactId>
-  <name>Apache CloudStack Plugin - Quota Service</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.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-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-quota</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-      <version>${cs.commons-lang3.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>joda-time</groupId>
-      <artifactId>joda-time</artifactId>
-      <version>${cs.joda-time.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${cs.junit.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-library</artifactId>
-      <version>${cs.hamcrest.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <version>${cs.mockito.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <version>${cs.powermock.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito</artifactId>
-      <version>${cs.powermock.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-      <version>${org.springframework.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-    </dependency>
-  </dependencies>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>cloud-plugin-database-quota</artifactId>
+    <name>Apache CloudStack Plugin - Quota Service</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</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-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-quota</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>${cs.joda-time.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaBalanceCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaBalanceCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaCreditsCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaCreditsCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEnabledCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaEnabledCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaEnabledCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java
diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java
new file mode 100644
index 0000000..21441ef
--- /dev/null
+++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaSummaryCmd.java
@@ -0,0 +1,110 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements.  See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership.  The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//with the License.  You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied.  See the License for the
+//specific language governing permissions and limitations
+//under the License.
+package org.apache.cloudstack.api.command;
+
+import com.cloud.user.Account;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.QuotaResponseBuilder;
+import org.apache.cloudstack.api.response.QuotaSummaryResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+@APICommand(name = "quotaSummary", responseObject = QuotaSummaryResponse.class, description = "Lists balance and quota usage for all accounts", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class QuotaSummaryCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(QuotaSummaryCmd.class);
+    private static final String s_name = "quotasummaryresponse";
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = false, description = "Optional, Account Id for which statement needs to be generated")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = false, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, required = false, description = "Optional, to list all accounts irrespective of the quota activity")
+    private Boolean listAll;
+
+    @Inject
+    QuotaResponseBuilder _responseBuilder;
+
+    public QuotaSummaryCmd() {
+        super();
+    }
+
+    @Override
+    public void execute() {
+        Account caller = CallContext.current().getCallingAccount();
+        List<QuotaSummaryResponse> responses;
+        if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { //admin account
+            if (getAccountName() != null && getDomainId() != null)
+                responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
+            else
+                responses = _responseBuilder.createQuotaSummaryResponse(isListAll());
+        } else {
+            responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
+        }
+        final ListResponse<QuotaSummaryResponse> response = new ListResponse<QuotaSummaryResponse>();
+        response.setResponses(responses);
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(Long domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public Boolean isListAll() {
+        return listAll == null ? false: listAll;
+    }
+
+    public void setListAll(Boolean listAll) {
+        this.listAll = listAll;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+}
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaTariffListCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaTariffListCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffListCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaUpdateCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaUpdateCmd.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaUpdateCmd.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaUpdateCmd.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaBalanceResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaBalanceResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaCreditsResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaCreditsResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaCreditsResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaCreditsResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaEmailTemplateResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaEmailTemplateResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaEmailTemplateResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaEmailTemplateResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaEnabledResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaEnabledResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaEnabledResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaEnabledResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilder.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilder.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilder.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilder.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaStatementResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaStatementResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaSummaryResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaSummaryResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaTariffResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaTariffResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaTypeResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaTypeResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaUpdateResponse.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaUpdateResponse.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/quota/QuotaService.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/quota/QuotaService.java
diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/quota/QuotaServiceImpl.java
similarity index 100%
rename from plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java
rename to plugins/database/quota/src/main/java/org/apache/cloudstack/quota/QuotaServiceImpl.java
diff --git a/plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties b/plugins/database/quota/src/main/resources/META-INF/cloudstack/quota/module.properties
similarity index 100%
rename from plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties
rename to plugins/database/quota/src/main/resources/META-INF/cloudstack/quota/module.properties
diff --git a/plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml b/plugins/database/quota/src/main/resources/META-INF/cloudstack/quota/spring-quota-context.xml
similarity index 100%
rename from plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml
rename to plugins/database/quota/src/main/resources/META-INF/cloudstack/quota/spring-quota-context.xml
diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaSummaryCmd.java b/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaSummaryCmd.java
deleted file mode 100644
index 88466e0..0000000
--- a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaSummaryCmd.java
+++ /dev/null
@@ -1,110 +0,0 @@
-//Licensed to the Apache Software Foundation (ASF) under one
-//or more contributor license agreements.  See the NOTICE file
-//distributed with this work for additional information
-//regarding copyright ownership.  The ASF licenses this file
-//to you under the Apache License, Version 2.0 (the
-//"License"); you may not use this file except in compliance
-//with the License.  You may obtain a copy of the License at
-//
-//http://www.apache.org/licenses/LICENSE-2.0
-//
-//Unless required by applicable law or agreed to in writing,
-//software distributed under the License is distributed on an
-//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-//KIND, either express or implied.  See the License for the
-//specific language governing permissions and limitations
-//under the License.
-package org.apache.cloudstack.api.command;
-
-import com.cloud.user.Account;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.BaseCmd.CommandType;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.QuotaResponseBuilder;
-import org.apache.cloudstack.api.response.QuotaSummaryResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-@APICommand(name = "quotaSummary", responseObject = QuotaSummaryResponse.class, description = "Lists balance and quota usage for all accounts", since = "4.7.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class QuotaSummaryCmd extends BaseListCmd {
-    public static final Logger s_logger = Logger.getLogger(QuotaSummaryCmd.class);
-    private static final String s_name = "quotasummaryresponse";
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = false, description = "Optional, Account Id for which statement needs to be generated")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = false, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, required = false, description = "Optional, to list all accounts irrespective of the quota activity")
-    private Boolean listAll;
-
-    @Inject
-    QuotaResponseBuilder _responseBuilder;
-
-    public QuotaSummaryCmd() {
-        super();
-    }
-
-    @Override
-    public void execute() {
-        Account caller = CallContext.current().getCallingAccount();
-        List<QuotaSummaryResponse> responses;
-        if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { //admin account
-            if (getAccountName() != null && getDomainId() != null)
-                responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
-            else
-                responses = _responseBuilder.createQuotaSummaryResponse(getListAll());
-        } else {
-            responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
-        }
-        final ListResponse<QuotaSummaryResponse> response = new ListResponse<QuotaSummaryResponse>();
-        response.setResponses(responses);
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public void setAccountName(String accountName) {
-        this.accountName = accountName;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public void setDomainId(Long domainId) {
-        this.domainId = domainId;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    public Boolean getListAll() {
-        return listAll == null ? false: listAll;
-    }
-
-    public void setListAll(Boolean listAll) {
-        this.listAll = listAll;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-}
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java
diff --git a/plugins/database/quota/test/org/apache/cloudstack/quota/QuotaServiceImplTest.java b/plugins/database/quota/src/test/java/org/apache/cloudstack/quota/QuotaServiceImplTest.java
similarity index 100%
rename from plugins/database/quota/test/org/apache/cloudstack/quota/QuotaServiceImplTest.java
rename to plugins/database/quota/src/test/java/org/apache/cloudstack/quota/QuotaServiceImplTest.java
diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml
index 3e8aa56..27be61c 100644
--- a/plugins/dedicated-resources/pom.xml
+++ b/plugins/dedicated-resources/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-dedicated-resources</artifactId>
-  <name>Apache CloudStack Plugin - Dedicated Resources</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+<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-dedicated-resources</artifactId>
+    <name>Apache CloudStack Plugin - Dedicated Resources</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateClusterCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateClusterCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateClusterCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateHostCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateHostCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateHostCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicatePodCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicatePodCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicatePodCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateZoneCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/DedicateZoneCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/DedicateZoneCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedClustersCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedHostsCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedPodsCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ListDedicatedZonesCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedClusterCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedHostCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedPodCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/commands/ReleaseDedicatedZoneCmd.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateClusterResponse.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateClusterResponse.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateClusterResponse.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateHostResponse.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateHostResponse.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateHostResponse.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicatePodResponse.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicatePodResponse.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicatePodResponse.java
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateZoneResponse.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/api/response/DedicateZoneResponse.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/api/response/DedicateZoneResponse.java
diff --git a/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
new file mode 100644
index 0000000..cd6d8cf
--- /dev/null
+++ b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
@@ -0,0 +1,966 @@
+// 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.dedicated;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.AffinityGroupService;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.api.commands.DedicateClusterCmd;
+import org.apache.cloudstack.api.commands.DedicateHostCmd;
+import org.apache.cloudstack.api.commands.DedicatePodCmd;
+import org.apache.cloudstack.api.commands.DedicateZoneCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedClustersCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedHostsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedPodsCmd;
+import org.apache.cloudstack.api.commands.ListDedicatedZonesCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedClusterCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedHostCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedPodCmd;
+import org.apache.cloudstack.api.commands.ReleaseDedicatedZoneCmd;
+import org.apache.cloudstack.api.response.DedicateClusterResponse;
+import org.apache.cloudstack.api.response.DedicateHostResponse;
+import org.apache.cloudstack.api.response.DedicatePodResponse;
+import org.apache.cloudstack.api.response.DedicateZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DedicatedResources;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+
+@Component
+public class DedicatedResourceManagerImpl implements DedicatedService {
+    private static final Logger s_logger = Logger.getLogger(DedicatedResourceManagerImpl.class);
+
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    HostPodDao _podDao;
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    DedicatedResourceDao _dedicatedDao;
+    @Inject
+    DataCenterDao _zoneDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    AffinityGroupDao _affinityGroupDao;
+
+    @Inject
+    AffinityGroupService _affinityGroupService;
+
+    private int capacityReleaseInterval;
+
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone")
+    public List<DedicatedResourceVO> dedicateZone(final Long zoneId, final Long domainId, final String accountName) {
+        Long accountId = null;
+        List<HostVO> hosts = null;
+        if (accountName != null) {
+            Account caller = CallContext.current().getCallingAccount();
+            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+            accountId = owner.getId();
+        }
+        List<Long> childDomainIds = getDomainChildIds(domainId);
+        childDomainIds.add(domainId);
+        checkAccountAndDomain(accountId, domainId);
+        final DataCenterVO dc = _zoneDao.findById(zoneId);
+        if (dc == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+        } else {
+            DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zoneId);
+            //check if zone is dedicated
+            if (dedicatedZone != null) {
+                s_logger.error("Zone " + dc.getName() + " is already dedicated");
+                throw new CloudRuntimeException("Zone  " + dc.getName() + " is already dedicated");
+            }
+
+            //check if any resource under this zone is dedicated to different account or sub-domain
+            List<HostPodVO> pods = _podDao.listByDataCenterId(dc.getId());
+            List<DedicatedResourceVO> podsToRelease = new ArrayList<DedicatedResourceVO>();
+            List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
+            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
+            for (HostPodVO pod : pods) {
+                DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
+                if (dPod != null) {
+                    if (!(childDomainIds.contains(dPod.getDomainId()))) {
+                        throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                    }
+                    if (accountId != null) {
+                        if (dPod.getAccountId().equals(accountId)) {
+                            podsToRelease.add(dPod);
+                        } else {
+                            s_logger.error("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                            throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                        }
+                    } else {
+                        if (dPod.getAccountId() == null && dPod.getDomainId().equals(domainId)) {
+                            podsToRelease.add(dPod);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : podsToRelease) {
+                releaseDedicatedResource(null, dr.getPodId(), null, null);
+            }
+
+            List<ClusterVO> clusters = _clusterDao.listClustersByDcId(dc.getId());
+            for (ClusterVO cluster : clusters) {
+                DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
+                if (dCluster != null) {
+                    if (!(childDomainIds.contains(dCluster.getDomainId()))) {
+                        throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                    }
+                    if (accountId != null) {
+                        if (dCluster.getAccountId().equals(accountId)) {
+                            clustersToRelease.add(dCluster);
+                        } else {
+                            s_logger.error("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                            throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() +
+                                " is dedicated to different account/domain");
+                        }
+                    } else {
+                        if (dCluster.getAccountId() == null && dCluster.getDomainId().equals(domainId)) {
+                            clustersToRelease.add(dCluster);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : clustersToRelease) {
+                releaseDedicatedResource(null, null, dr.getClusterId(), null);
+            }
+
+            hosts = _hostDao.listByDataCenterId(dc.getId());
+            for (HostVO host : hosts) {
+                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+                if (dHost != null) {
+                    if (!(childDomainIds.contains(dHost.getDomainId()))) {
+                        throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                    }
+                    if (accountId != null) {
+                        if (dHost.getAccountId().equals(accountId)) {
+                            hostsToRelease.add(dHost);
+                        } else {
+                            s_logger.error("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                            throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
+                        }
+                    } else {
+                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
+                            hostsToRelease.add(dHost);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : hostsToRelease) {
+                releaseDedicatedResource(null, null, null, dr.getHostId());
+            }
+        }
+
+        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+        final Long accountIdFinal = accountId;
+        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
+            @Override
+            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
+                // find or create the affinity group by name under this account/domain
+                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
+                if (group == null) {
+                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
+                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+                }
+
+                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null, group.getId());
+                try {
+                    dedicatedResource.setDomainId(domainId);
+                    if (accountIdFinal != null) {
+                        dedicatedResource.setAccountId(accountIdFinal);
+                    }
+                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+
+                    // save the domainId in the zone
+                    dc.setDomainId(domainId);
+                    if (!_zoneDao.update(zoneId, dc)) {
+                        throw new CloudRuntimeException("Failed to dedicate zone, could not set domainId. Please contact Cloud Support.");
+                    }
+
+                } catch (Exception e) {
+                    s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e);
+                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+                }
+
+                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
+                result.add(dedicatedResource);
+                return result;
+
+            }
+        });
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Pod")
+    public List<DedicatedResourceVO> dedicatePod(final Long podId, final Long domainId, final String accountName) {
+        Long accountId = null;
+        if (accountName != null) {
+            Account caller = CallContext.current().getCallingAccount();
+            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+            accountId = owner.getId();
+        }
+        List<Long> childDomainIds = getDomainChildIds(domainId);
+        childDomainIds.add(domainId);
+        checkAccountAndDomain(accountId, domainId);
+        HostPodVO pod = _podDao.findById(podId);
+        List<HostVO> hosts = null;
+        if (pod == null) {
+            throw new InvalidParameterValueException("Unable to find pod by id " + podId);
+        } else {
+            DedicatedResourceVO dedicatedPod = _dedicatedDao.findByPodId(podId);
+            DedicatedResourceVO dedicatedZoneOfPod = _dedicatedDao.findByZoneId(pod.getDataCenterId());
+            //check if pod is dedicated
+            if (dedicatedPod != null) {
+                s_logger.error("Pod " + pod.getName() + " is already dedicated");
+                throw new CloudRuntimeException("Pod " + pod.getName() + " is already dedicated");
+            }
+
+            if (dedicatedZoneOfPod != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfPod.getDomainId()).contains(domainId);
+                //can dedicate a pod to an account/domain if zone is dedicated to parent-domain
+                if (dedicatedZoneOfPod.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedZoneOfPod.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId());
+                    s_logger.error("Cannot dedicate Pod. Its zone is already dedicated");
+                    throw new CloudRuntimeException("Pod's Zone " + zone.getName() + " is already dedicated");
+                }
+            }
+
+            //check if any resource under this pod is dedicated to different account or sub-domain
+            List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
+            List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
+            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
+            for (ClusterVO cluster : clusters) {
+                DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
+                if (dCluster != null) {
+                    if (!(childDomainIds.contains(dCluster.getDomainId()))) {
+                        throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+                    }
+                    /*if all dedicated resources belongs to same account and domain then we should release dedication
+                    and make new entry for this Pod*/
+                    if (accountId != null) {
+                        if (dCluster.getAccountId().equals(accountId)) {
+                            clustersToRelease.add(dCluster);
+                        } else {
+                            s_logger.error("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+                            throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() +
+                                " is dedicated to different account/domain");
+                        }
+                    } else {
+                        if (dCluster.getAccountId() == null && dCluster.getDomainId().equals(domainId)) {
+                            clustersToRelease.add(dCluster);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : clustersToRelease) {
+                releaseDedicatedResource(null, null, dr.getClusterId(), null);
+            }
+
+            hosts = _hostDao.findByPodId(pod.getId());
+            for (HostVO host : hosts) {
+                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+                if (dHost != null) {
+                    if (!(getDomainChildIds(domainId).contains(dHost.getDomainId()))) {
+                        throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+                    }
+                    if (accountId != null) {
+                        if (dHost.getAccountId().equals(accountId)) {
+                            hostsToRelease.add(dHost);
+                        } else {
+                            s_logger.error("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+                            throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
+                        }
+                    } else {
+                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
+                            hostsToRelease.add(dHost);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : hostsToRelease) {
+                releaseDedicatedResource(null, null, null, dr.getHostId());
+            }
+        }
+
+        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+        final Long accountIdFinal = accountId;
+        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
+            @Override
+            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
+                // find or create the affinity group by name under this account/domain
+                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
+                if (group == null) {
+                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
+                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+                }
+                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null, group.getId());
+                try {
+                    dedicatedResource.setDomainId(domainId);
+                    if (accountIdFinal != null) {
+                        dedicatedResource.setAccountId(accountIdFinal);
+                    }
+                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+                } catch (Exception e) {
+                    s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e);
+                    throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support.");
+                }
+
+                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
+                result.add(dedicatedResource);
+                return result;
+            }
+        });
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Cluster")
+    public List<DedicatedResourceVO> dedicateCluster(final Long clusterId, final Long domainId, final String accountName) {
+        Long accountId = null;
+        List<HostVO> hosts = null;
+        if (accountName != null) {
+            Account caller = CallContext.current().getCallingAccount();
+            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+            accountId = owner.getId();
+        }
+        List<Long> childDomainIds = getDomainChildIds(domainId);
+        childDomainIds.add(domainId);
+        checkAccountAndDomain(accountId, domainId);
+        ClusterVO cluster = _clusterDao.findById(clusterId);
+        if (cluster == null) {
+            throw new InvalidParameterValueException("Unable to find cluster by id " + clusterId);
+        } else {
+            DedicatedResourceVO dedicatedCluster = _dedicatedDao.findByClusterId(clusterId);
+            DedicatedResourceVO dedicatedPodOfCluster = _dedicatedDao.findByPodId(cluster.getPodId());
+            DedicatedResourceVO dedicatedZoneOfCluster = _dedicatedDao.findByZoneId(cluster.getDataCenterId());
+
+            //check if cluster is dedicated
+            if (dedicatedCluster != null) {
+                s_logger.error("Cluster " + cluster.getName() + " is already dedicated");
+                throw new CloudRuntimeException("Cluster " + cluster.getName() + " is already dedicated");
+            }
+
+            if (dedicatedPodOfCluster != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfCluster.getDomainId()).contains(domainId);
+                //can dedicate a cluster to an account/domain if pod is dedicated to parent-domain
+                if (dedicatedPodOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedPodOfCluster.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    s_logger.error("Cannot dedicate Cluster. Its Pod is already dedicated");
+                    HostPodVO pod = _podDao.findById(cluster.getPodId());
+                    throw new CloudRuntimeException("Cluster's Pod " + pod.getName() + " is already dedicated");
+                }
+            }
+
+            if (dedicatedZoneOfCluster != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfCluster.getDomainId()).contains(domainId);
+                //can dedicate a cluster to an account/domain if zone is dedicated to parent-domain
+                if (dedicatedZoneOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedZoneOfCluster.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    s_logger.error("Cannot dedicate Cluster. Its zone is already dedicated");
+                    DataCenterVO zone = _zoneDao.findById(cluster.getDataCenterId());
+                    throw new CloudRuntimeException("Cluster's Zone " + zone.getName() + " is already dedicated");
+                }
+            }
+
+            //check if any resource under this cluster is dedicated to different account or sub-domain
+            hosts = _hostDao.findByClusterId(cluster.getId());
+            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
+            for (HostVO host : hosts) {
+                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
+                if (dHost != null) {
+                    if (!(childDomainIds.contains(dHost.getDomainId()))) {
+                        throw new CloudRuntimeException("Host " + host.getName() + " under this Cluster " + cluster.getName() +
+                            " is dedicated to different account/domain");
+                    }
+                    /*if all dedicated resources belongs to same account and domain then we should release dedication
+                    and make new entry for this cluster */
+                    if (accountId != null) {
+                        if (dHost.getAccountId().equals(accountId)) {
+                            hostsToRelease.add(dHost);
+                        } else {
+                            s_logger.error("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
+                            throw new CloudRuntimeException("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
+                        }
+                    } else {
+                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
+                            hostsToRelease.add(dHost);
+                        }
+                    }
+                }
+            }
+
+            for (DedicatedResourceVO dr : hostsToRelease) {
+                releaseDedicatedResource(null, null, null, dr.getHostId());
+            }
+        }
+
+        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
+
+        final Long accountIdFinal = accountId;
+        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
+            @Override
+            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
+                // find or create the affinity group by name under this account/domain
+                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
+                if (group == null) {
+                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
+                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+                }
+                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null, group.getId());
+                try {
+                    dedicatedResource.setDomainId(domainId);
+                    if (accountIdFinal != null) {
+                        dedicatedResource.setAccountId(accountIdFinal);
+                    }
+                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+                } catch (Exception e) {
+                    s_logger.error("Unable to dedicate cluster due to " + e.getMessage(), e);
+                    throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support.", e);
+                }
+
+                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
+                result.add(dedicatedResource);
+                return result;
+            }
+        });
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Host")
+    public List<DedicatedResourceVO> dedicateHost(final Long hostId, final Long domainId, final String accountName) {
+        Long accountId = null;
+        if (accountName != null) {
+            Account caller = CallContext.current().getCallingAccount();
+            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+            accountId = owner.getId();
+        }
+        checkAccountAndDomain(accountId, domainId);
+        HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new InvalidParameterValueException("Unable to find host by id " + hostId);
+        } else {
+            //check if host is of routing type
+            if (host.getType() != Host.Type.Routing) {
+                throw new CloudRuntimeException("Invalid host type for host " + host.getName());
+            }
+
+            DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+            DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+            DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+            DedicatedResourceVO dedicatedZoneOfHost = _dedicatedDao.findByZoneId(host.getDataCenterId());
+
+            if (dedicatedHost != null) {
+                s_logger.error("Host " + host.getName() + " is already dedicated");
+                throw new CloudRuntimeException("Host " + host.getName() + " is already dedicated");
+            }
+
+            if (dedicatedClusterOfHost != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedClusterOfHost.getDomainId()).contains(domainId);
+                //can dedicate a host to an account/domain if cluster is dedicated to parent-domain
+                if (dedicatedClusterOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedClusterOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+                    s_logger.error("Host's Cluster " + cluster.getName() + " is already dedicated");
+                    throw new CloudRuntimeException("Host's Cluster " + cluster.getName() + " is already dedicated");
+                }
+            }
+
+            if (dedicatedPodOfHost != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfHost.getDomainId()).contains(domainId);
+                //can dedicate a host to an account/domain if pod is dedicated to parent-domain
+                if (dedicatedPodOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedPodOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    HostPodVO pod = _podDao.findById(host.getPodId());
+                    s_logger.error("Host's Pod " + pod.getName() + " is already dedicated");
+                    throw new CloudRuntimeException("Host's Pod " + pod.getName() + " is already dedicated");
+                }
+            }
+
+            if (dedicatedZoneOfHost != null) {
+                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfHost.getDomainId()).contains(domainId);
+                //can dedicate a host to an account/domain if zone is dedicated to parent-domain
+                if (dedicatedZoneOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
+                    (accountId != null && !(dedicatedZoneOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
+                    DataCenterVO zone = _zoneDao.findById(host.getDataCenterId());
+                    s_logger.error("Host's Data Center " + zone.getName() + " is already dedicated");
+                    throw new CloudRuntimeException("Host's Data Center " + zone.getName() + " is already dedicated");
+                }
+            }
+        }
+
+        List<Long> childDomainIds = getDomainChildIds(domainId);
+        childDomainIds.add(domainId);
+        checkHostSuitabilityForExplicitDedication(accountId, childDomainIds, hostId);
+
+        final Long accountIdFinal = accountId;
+        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
+            @Override
+            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
+                // find or create the affinity group by name under this account/domain
+                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
+                if (group == null) {
+                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
+                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
+                }
+                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null, group.getId());
+                try {
+                    dedicatedResource.setDomainId(domainId);
+                    if (accountIdFinal != null) {
+                        dedicatedResource.setAccountId(accountIdFinal);
+                    }
+                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
+                } catch (Exception e) {
+                    s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
+                    throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support.", e);
+                }
+
+                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
+                result.add(dedicatedResource);
+                return result;
+            }
+        });
+
+    }
+
+    private AffinityGroup findOrCreateDedicatedAffinityGroup(Long domainId, Long accountId) {
+        if (domainId == null) {
+            return null;
+        }
+
+        AffinityGroup group = null;
+        String accountName = null;
+        String affinityGroupName = null;
+
+        if (accountId != null) {
+            AccountVO account = _accountDao.findById(accountId);
+            accountName = account.getAccountName();
+
+            group = _affinityGroupDao.findByAccountAndType(accountId, "ExplicitDedication");
+            if (group != null) {
+                return group;
+            }
+            // default to a groupname with account/domain information
+            affinityGroupName = "DedicatedGrp-" + accountName;
+
+        } else {
+            // domain level group
+            group = _affinityGroupDao.findDomainLevelGroupByType(domainId, "ExplicitDedication");
+            if (group != null) {
+                return group;
+            }
+            // default to a groupname with account/domain information
+            String domainName = _domainDao.findById(domainId).getName();
+            affinityGroupName = "DedicatedGrp-domain-" + domainName;
+        }
+
+        group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
+
+        return group;
+
+    }
+
+    private List<UserVmVO> getVmsOnHost(long hostId) {
+        List<UserVmVO> vms = _userVmDao.listUpByHostId(hostId);
+        List<UserVmVO> vmsByLastHostId = _userVmDao.listByLastHostId(hostId);
+        if (vmsByLastHostId.size() > 0) {
+            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
+            for (UserVmVO stoppedVM : vmsByLastHostId) {
+                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
+                if (secondsSinceLastUpdate < capacityReleaseInterval) {
+                    vms.add(stoppedVM);
+                }
+            }
+        }
+
+        return vms;
+    }
+
+    private boolean checkHostSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, long hostId) {
+        boolean suitable = true;
+        List<UserVmVO> allVmsOnHost = getVmsOnHost(hostId);
+        if (accountId != null) {
+            for (UserVmVO vm : allVmsOnHost) {
+                if (vm.getAccountId() != accountId) {
+                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " + "running instances of another account");
+                    throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
+                        "running instances of another account");
+                }
+            }
+        } else {
+            for (UserVmVO vm : allVmsOnHost) {
+                if (!domainIds.contains(vm.getDomainId())) {
+                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " + "running instances of another domain");
+                    throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
+                        "running instances of another domain");
+                }
+            }
+        }
+        return suitable;
+    }
+
+    private boolean checkHostsSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, List<HostVO> hosts) {
+        boolean suitable = true;
+        for (HostVO host : hosts) {
+            checkHostSuitabilityForExplicitDedication(accountId, domainIds, host.getId());
+        }
+        return suitable;
+    }
+
+    private void checkAccountAndDomain(Long accountId, Long domainId) {
+        DomainVO domain = _domainDao.findById(domainId);
+        if (domain == null) {
+            throw new InvalidParameterValueException("Unable to find the domain by id " + domainId + ", please specify valid domainId");
+        }
+        //check if account belongs to the domain id
+        if (accountId != null) {
+            AccountVO account = _accountDao.findById(accountId);
+            if (account == null || domainId != account.getDomainId()) {
+                throw new InvalidParameterValueException("Please specify the domain id of the account id " + accountId);
+            }
+        }
+    }
+
+    private List<Long> getDomainChildIds(long domainId) {
+        DomainVO domainRecord = _domainDao.findById(domainId);
+        List<Long> domainIds = new ArrayList<Long>();
+        domainIds.add(domainRecord.getId());
+        // find all domain Ids till leaf
+        List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
+        for (DomainVO domain : allChildDomains) {
+            domainIds.add(domain.getId());
+        }
+        return domainIds;
+    }
+
+    @Override
+    public DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource) {
+        DedicateZoneResponse dedicateZoneResponse = new DedicateZoneResponse();
+        DataCenterVO dc = _zoneDao.findById(resource.getDataCenterId());
+        DomainVO domain = _domainDao.findById(resource.getDomainId());
+        AccountVO account = _accountDao.findById(resource.getAccountId());
+        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
+        dedicateZoneResponse.setId(resource.getUuid());
+        dedicateZoneResponse.setZoneId(dc.getUuid());
+        dedicateZoneResponse.setZoneName(dc.getName());
+        dedicateZoneResponse.setDomainId(domain.getUuid());
+        dedicateZoneResponse.setAffinityGroupId(group.getUuid());
+        if (account != null) {
+            dedicateZoneResponse.setAccountId(account.getUuid());
+        }
+        dedicateZoneResponse.setObjectName("dedicatedzone");
+        return dedicateZoneResponse;
+    }
+
+    @Override
+    public DedicatePodResponse createDedicatePodResponse(DedicatedResources resource) {
+        DedicatePodResponse dedicatePodResponse = new DedicatePodResponse();
+        HostPodVO pod = _podDao.findById(resource.getPodId());
+        DomainVO domain = _domainDao.findById(resource.getDomainId());
+        AccountVO account = _accountDao.findById(resource.getAccountId());
+        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
+        dedicatePodResponse.setId(resource.getUuid());
+        dedicatePodResponse.setPodId(pod.getUuid());
+        dedicatePodResponse.setPodName(pod.getName());
+        dedicatePodResponse.setDomainId(domain.getUuid());
+        dedicatePodResponse.setAffinityGroupId(group.getUuid());
+        if (account != null) {
+            dedicatePodResponse.setAccountId(account.getUuid());
+        }
+        dedicatePodResponse.setObjectName("dedicatedpod");
+        return dedicatePodResponse;
+    }
+
+    @Override
+    public DedicateClusterResponse createDedicateClusterResponse(DedicatedResources resource) {
+        DedicateClusterResponse dedicateClusterResponse = new DedicateClusterResponse();
+        ClusterVO cluster = _clusterDao.findById(resource.getClusterId());
+        DomainVO domain = _domainDao.findById(resource.getDomainId());
+        AccountVO account = _accountDao.findById(resource.getAccountId());
+        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
+        dedicateClusterResponse.setId(resource.getUuid());
+        dedicateClusterResponse.setClusterId(cluster.getUuid());
+        dedicateClusterResponse.setClusterName(cluster.getName());
+        dedicateClusterResponse.setDomainId(domain.getUuid());
+        dedicateClusterResponse.setAffinityGroupId(group.getUuid());
+        if (account != null) {
+            dedicateClusterResponse.setAccountId(account.getUuid());
+        }
+        dedicateClusterResponse.setObjectName("dedicatedcluster");
+        return dedicateClusterResponse;
+    }
+
+    @Override
+    public DedicateHostResponse createDedicateHostResponse(DedicatedResources resource) {
+        DedicateHostResponse dedicateHostResponse = new DedicateHostResponse();
+        HostVO host = _hostDao.findById(resource.getHostId());
+        DomainVO domain = _domainDao.findById(resource.getDomainId());
+        AccountVO account = _accountDao.findById(resource.getAccountId());
+        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
+        dedicateHostResponse.setId(resource.getUuid());
+        dedicateHostResponse.setHostId(host.getUuid());
+        dedicateHostResponse.setHostName(host.getName());
+        dedicateHostResponse.setDomainId(domain.getUuid());
+        dedicateHostResponse.setAffinityGroupId(group.getUuid());
+        if (account != null) {
+            dedicateHostResponse.setAccountId(account.getUuid());
+        }
+        dedicateHostResponse.setObjectName("dedicatedhost");
+        return dedicateHostResponse;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(DedicateZoneCmd.class);
+        cmdList.add(DedicatePodCmd.class);
+        cmdList.add(DedicateClusterCmd.class);
+        cmdList.add(DedicateHostCmd.class);
+        cmdList.add(ListDedicatedZonesCmd.class);
+        cmdList.add(ListDedicatedPodsCmd.class);
+        cmdList.add(ListDedicatedClustersCmd.class);
+        cmdList.add(ListDedicatedHostsCmd.class);
+        cmdList.add(ReleaseDedicatedClusterCmd.class);
+        cmdList.add(ReleaseDedicatedHostCmd.class);
+        cmdList.add(ReleaseDedicatedPodCmd.class);
+        cmdList.add(ReleaseDedicatedZoneCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd) {
+        Long zoneId = cmd.getZoneId();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        Long accountId = null;
+        Long affinityGroupId = cmd.getAffinityGroupId();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        if (accountName != null) {
+            if (domainId != null) {
+                Account account = _accountDao.findActiveAccount(accountName, domainId);
+                if (account != null) {
+                    accountId = account.getId();
+                }
+            } else {
+                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+            }
+        }
+        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
+        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId, accountId, affinityGroupId, searchFilter);
+        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd) {
+        Long podId = cmd.getPodId();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        Long accountId = null;
+        Long affinityGroupId = cmd.getAffinityGroupId();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        if (accountName != null) {
+            if (domainId != null) {
+                Account account = _accountDao.findActiveAccount(accountName, domainId);
+                if (account != null) {
+                    accountId = account.getId();
+                }
+            } else {
+                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+            }
+        }
+        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
+        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId, affinityGroupId, searchFilter);
+        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd) {
+        Long clusterId = cmd.getClusterId();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        Long accountId = null;
+        Long affinityGroupId = cmd.getAffinityGroupId();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        if (accountName != null) {
+            if (domainId != null) {
+                Account account = _accountDao.findActiveAccount(accountName, domainId);
+                if (account != null) {
+                    accountId = account.getId();
+                }
+            } else {
+                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+            }
+        }
+        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
+        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId, accountId, affinityGroupId, searchFilter);
+        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd) {
+        Long hostId = cmd.getHostId();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        Long affinityGroupId = cmd.getAffinityGroupId();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        Long accountId = null;
+        if (accountName != null) {
+            if (domainId != null) {
+                Account account = _accountDao.findActiveAccount(accountName, domainId);
+                if (account != null) {
+                    accountId = account.getId();
+                }
+            } else {
+                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
+            }
+        }
+        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
+        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId, affinityGroupId, searchFilter);
+        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE, eventDescription = "Releasing dedicated resource")
+    public boolean releaseDedicatedResource(final Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException {
+        DedicatedResourceVO resource = null;
+        if (zoneId != null) {
+            resource = _dedicatedDao.findByZoneId(zoneId);
+        }
+        if (podId != null) {
+            resource = _dedicatedDao.findByPodId(podId);
+        }
+        if (clusterId != null) {
+            resource = _dedicatedDao.findByClusterId(clusterId);
+        }
+        if (hostId != null) {
+            resource = _dedicatedDao.findByHostId(hostId);
+        }
+        if (resource == null) {
+            throw new InvalidParameterValueException("No Dedicated Resource available to release");
+        } else {
+            final DedicatedResourceVO resourceFinal = resource;
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    Long resourceId = resourceFinal.getId();
+                    if (!_dedicatedDao.remove(resourceId)) {
+                        throw new CloudRuntimeException("Failed to delete Resource " + resourceId);
+                    }
+                    if (zoneId != null) {
+                        // remove the domainId set in zone
+                        DataCenterVO dc = _zoneDao.findById(zoneId);
+                        if (dc != null) {
+                            dc.setDomainId(null);
+                            dc.setDomain(null);
+                            if (!_zoneDao.update(zoneId, dc)) {
+                                throw new CloudRuntimeException("Failed to release dedicated zone, could not clear domainId. Please contact Cloud Support.");
+                            }
+                        }
+                    }
+                }
+            });
+
+            // find the group associated and check if there are any more
+            // resources under that group
+            List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
+            if (resourcesInGroup.isEmpty()) {
+                // delete the group
+                _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
+            }
+
+        }
+        return true;
+    }
+}
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedService.java b/plugins/dedicated-resources/src/main/java/org/apache/cloudstack/dedicated/DedicatedService.java
similarity index 100%
rename from plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedService.java
rename to plugins/dedicated-resources/src/main/java/org/apache/cloudstack/dedicated/DedicatedService.java
diff --git a/plugins/dedicated-resources/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml b/plugins/dedicated-resources/src/main/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml
similarity index 100%
rename from plugins/dedicated-resources/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml
rename to plugins/dedicated-resources/src/main/resources/META-INF/cloudstack/core/spring-dedicated-resources-core-context.xml
diff --git a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java b/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
deleted file mode 100644
index 7cf193d..0000000
--- a/plugins/dedicated-resources/src/org/apache/cloudstack/dedicated/DedicatedResourceManagerImpl.java
+++ /dev/null
@@ -1,966 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.dedicated;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.AffinityGroupService;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.api.commands.DedicateClusterCmd;
-import org.apache.cloudstack.api.commands.DedicateHostCmd;
-import org.apache.cloudstack.api.commands.DedicatePodCmd;
-import org.apache.cloudstack.api.commands.DedicateZoneCmd;
-import org.apache.cloudstack.api.commands.ListDedicatedClustersCmd;
-import org.apache.cloudstack.api.commands.ListDedicatedHostsCmd;
-import org.apache.cloudstack.api.commands.ListDedicatedPodsCmd;
-import org.apache.cloudstack.api.commands.ListDedicatedZonesCmd;
-import org.apache.cloudstack.api.commands.ReleaseDedicatedClusterCmd;
-import org.apache.cloudstack.api.commands.ReleaseDedicatedHostCmd;
-import org.apache.cloudstack.api.commands.ReleaseDedicatedPodCmd;
-import org.apache.cloudstack.api.commands.ReleaseDedicatedZoneCmd;
-import org.apache.cloudstack.api.response.DedicateClusterResponse;
-import org.apache.cloudstack.api.response.DedicateHostResponse;
-import org.apache.cloudstack.api.response.DedicatePodResponse;
-import org.apache.cloudstack.api.response.DedicateZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.DedicatedResources;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.dao.UserVmDao;
-
-@Component
-public class DedicatedResourceManagerImpl implements DedicatedService {
-    private static final Logger s_logger = Logger.getLogger(DedicatedResourceManagerImpl.class);
-
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    HostPodDao _podDao;
-    @Inject
-    ClusterDao _clusterDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    DedicatedResourceDao _dedicatedDao;
-    @Inject
-    DataCenterDao _zoneDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    AffinityGroupDao _affinityGroupDao;
-
-    @Inject
-    AffinityGroupService _affinityGroupService;
-
-    private int capacityReleaseInterval;
-
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Zone")
-    public List<DedicatedResourceVO> dedicateZone(final Long zoneId, final Long domainId, final String accountName) {
-        Long accountId = null;
-        List<HostVO> hosts = null;
-        if (accountName != null) {
-            Account caller = CallContext.current().getCallingAccount();
-            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
-            accountId = owner.getId();
-        }
-        List<Long> childDomainIds = getDomainChildIds(domainId);
-        childDomainIds.add(domainId);
-        checkAccountAndDomain(accountId, domainId);
-        final DataCenterVO dc = _zoneDao.findById(zoneId);
-        if (dc == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        } else {
-            DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zoneId);
-            //check if zone is dedicated
-            if (dedicatedZone != null) {
-                s_logger.error("Zone " + dc.getName() + " is already dedicated");
-                throw new CloudRuntimeException("Zone  " + dc.getName() + " is already dedicated");
-            }
-
-            //check if any resource under this zone is dedicated to different account or sub-domain
-            List<HostPodVO> pods = _podDao.listByDataCenterId(dc.getId());
-            List<DedicatedResourceVO> podsToRelease = new ArrayList<DedicatedResourceVO>();
-            List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
-            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
-            for (HostPodVO pod : pods) {
-                DedicatedResourceVO dPod = _dedicatedDao.findByPodId(pod.getId());
-                if (dPod != null) {
-                    if (!(childDomainIds.contains(dPod.getDomainId()))) {
-                        throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                    }
-                    if (accountId != null) {
-                        if (dPod.getAccountId().equals(accountId)) {
-                            podsToRelease.add(dPod);
-                        } else {
-                            s_logger.error("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                            throw new CloudRuntimeException("Pod " + pod.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                        }
-                    } else {
-                        if (dPod.getAccountId() == null && dPod.getDomainId().equals(domainId)) {
-                            podsToRelease.add(dPod);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : podsToRelease) {
-                releaseDedicatedResource(null, dr.getPodId(), null, null);
-            }
-
-            List<ClusterVO> clusters = _clusterDao.listClustersByDcId(dc.getId());
-            for (ClusterVO cluster : clusters) {
-                DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
-                if (dCluster != null) {
-                    if (!(childDomainIds.contains(dCluster.getDomainId()))) {
-                        throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                    }
-                    if (accountId != null) {
-                        if (dCluster.getAccountId().equals(accountId)) {
-                            clustersToRelease.add(dCluster);
-                        } else {
-                            s_logger.error("Cluster " + cluster.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                            throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Zone " + dc.getName() +
-                                " is dedicated to different account/domain");
-                        }
-                    } else {
-                        if (dCluster.getAccountId() == null && dCluster.getDomainId().equals(domainId)) {
-                            clustersToRelease.add(dCluster);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : clustersToRelease) {
-                releaseDedicatedResource(null, null, dr.getClusterId(), null);
-            }
-
-            hosts = _hostDao.listByDataCenterId(dc.getId());
-            for (HostVO host : hosts) {
-                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
-                if (dHost != null) {
-                    if (!(childDomainIds.contains(dHost.getDomainId()))) {
-                        throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                    }
-                    if (accountId != null) {
-                        if (dHost.getAccountId().equals(accountId)) {
-                            hostsToRelease.add(dHost);
-                        } else {
-                            s_logger.error("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                            throw new CloudRuntimeException("Host " + host.getName() + " under this Zone " + dc.getName() + " is dedicated to different account/domain");
-                        }
-                    } else {
-                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
-                            hostsToRelease.add(dHost);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : hostsToRelease) {
-                releaseDedicatedResource(null, null, null, dr.getHostId());
-            }
-        }
-
-        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
-
-        final Long accountIdFinal = accountId;
-        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
-            @Override
-            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
-                // find or create the affinity group by name under this account/domain
-                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
-                if (group == null) {
-                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
-                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
-                }
-
-                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zoneId, null, null, null, null, null, group.getId());
-                try {
-                    dedicatedResource.setDomainId(domainId);
-                    if (accountIdFinal != null) {
-                        dedicatedResource.setAccountId(accountIdFinal);
-                    }
-                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
-
-                    // save the domainId in the zone
-                    dc.setDomainId(domainId);
-                    if (!_zoneDao.update(zoneId, dc)) {
-                        throw new CloudRuntimeException("Failed to dedicate zone, could not set domainId. Please contact Cloud Support.");
-                    }
-
-                } catch (Exception e) {
-                    s_logger.error("Unable to dedicate zone due to " + e.getMessage(), e);
-                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
-                }
-
-                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
-                result.add(dedicatedResource);
-                return result;
-
-            }
-        });
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Pod")
-    public List<DedicatedResourceVO> dedicatePod(final Long podId, final Long domainId, final String accountName) {
-        Long accountId = null;
-        if (accountName != null) {
-            Account caller = CallContext.current().getCallingAccount();
-            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
-            accountId = owner.getId();
-        }
-        List<Long> childDomainIds = getDomainChildIds(domainId);
-        childDomainIds.add(domainId);
-        checkAccountAndDomain(accountId, domainId);
-        HostPodVO pod = _podDao.findById(podId);
-        List<HostVO> hosts = null;
-        if (pod == null) {
-            throw new InvalidParameterValueException("Unable to find pod by id " + podId);
-        } else {
-            DedicatedResourceVO dedicatedPod = _dedicatedDao.findByPodId(podId);
-            DedicatedResourceVO dedicatedZoneOfPod = _dedicatedDao.findByZoneId(pod.getDataCenterId());
-            //check if pod is dedicated
-            if (dedicatedPod != null) {
-                s_logger.error("Pod " + pod.getName() + " is already dedicated");
-                throw new CloudRuntimeException("Pod " + pod.getName() + " is already dedicated");
-            }
-
-            if (dedicatedZoneOfPod != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfPod.getDomainId()).contains(domainId);
-                //can dedicate a pod to an account/domain if zone is dedicated to parent-domain
-                if (dedicatedZoneOfPod.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedZoneOfPod.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId());
-                    s_logger.error("Cannot dedicate Pod. Its zone is already dedicated");
-                    throw new CloudRuntimeException("Pod's Zone " + zone.getName() + " is already dedicated");
-                }
-            }
-
-            //check if any resource under this pod is dedicated to different account or sub-domain
-            List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
-            List<DedicatedResourceVO> clustersToRelease = new ArrayList<DedicatedResourceVO>();
-            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
-            for (ClusterVO cluster : clusters) {
-                DedicatedResourceVO dCluster = _dedicatedDao.findByClusterId(cluster.getId());
-                if (dCluster != null) {
-                    if (!(childDomainIds.contains(dCluster.getDomainId()))) {
-                        throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
-                    }
-                    /*if all dedicated resources belongs to same account and domain then we should release dedication
-                    and make new entry for this Pod*/
-                    if (accountId != null) {
-                        if (dCluster.getAccountId().equals(accountId)) {
-                            clustersToRelease.add(dCluster);
-                        } else {
-                            s_logger.error("Cluster " + cluster.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
-                            throw new CloudRuntimeException("Cluster " + cluster.getName() + " under this Pod " + pod.getName() +
-                                " is dedicated to different account/domain");
-                        }
-                    } else {
-                        if (dCluster.getAccountId() == null && dCluster.getDomainId().equals(domainId)) {
-                            clustersToRelease.add(dCluster);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : clustersToRelease) {
-                releaseDedicatedResource(null, null, dr.getClusterId(), null);
-            }
-
-            hosts = _hostDao.findByPodId(pod.getId());
-            for (HostVO host : hosts) {
-                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
-                if (dHost != null) {
-                    if (!(getDomainChildIds(domainId).contains(dHost.getDomainId()))) {
-                        throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
-                    }
-                    if (accountId != null) {
-                        if (dHost.getAccountId().equals(accountId)) {
-                            hostsToRelease.add(dHost);
-                        } else {
-                            s_logger.error("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
-                            throw new CloudRuntimeException("Host " + host.getName() + " under this Pod " + pod.getName() + " is dedicated to different account/domain");
-                        }
-                    } else {
-                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
-                            hostsToRelease.add(dHost);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : hostsToRelease) {
-                releaseDedicatedResource(null, null, null, dr.getHostId());
-            }
-        }
-
-        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
-
-        final Long accountIdFinal = accountId;
-        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
-            @Override
-            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
-                // find or create the affinity group by name under this account/domain
-                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
-                if (group == null) {
-                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
-                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
-                }
-                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, podId, null, null, null, null, group.getId());
-                try {
-                    dedicatedResource.setDomainId(domainId);
-                    if (accountIdFinal != null) {
-                        dedicatedResource.setAccountId(accountIdFinal);
-                    }
-                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
-                } catch (Exception e) {
-                    s_logger.error("Unable to dedicate pod due to " + e.getMessage(), e);
-                    throw new CloudRuntimeException("Failed to dedicate pod. Please contact Cloud Support.");
-                }
-
-                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
-                result.add(dedicatedResource);
-                return result;
-            }
-        });
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Cluster")
-    public List<DedicatedResourceVO> dedicateCluster(final Long clusterId, final Long domainId, final String accountName) {
-        Long accountId = null;
-        List<HostVO> hosts = null;
-        if (accountName != null) {
-            Account caller = CallContext.current().getCallingAccount();
-            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
-            accountId = owner.getId();
-        }
-        List<Long> childDomainIds = getDomainChildIds(domainId);
-        childDomainIds.add(domainId);
-        checkAccountAndDomain(accountId, domainId);
-        ClusterVO cluster = _clusterDao.findById(clusterId);
-        if (cluster == null) {
-            throw new InvalidParameterValueException("Unable to find cluster by id " + clusterId);
-        } else {
-            DedicatedResourceVO dedicatedCluster = _dedicatedDao.findByClusterId(clusterId);
-            DedicatedResourceVO dedicatedPodOfCluster = _dedicatedDao.findByPodId(cluster.getPodId());
-            DedicatedResourceVO dedicatedZoneOfCluster = _dedicatedDao.findByZoneId(cluster.getDataCenterId());
-
-            //check if cluster is dedicated
-            if (dedicatedCluster != null) {
-                s_logger.error("Cluster " + cluster.getName() + " is already dedicated");
-                throw new CloudRuntimeException("Cluster " + cluster.getName() + " is already dedicated");
-            }
-
-            if (dedicatedPodOfCluster != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfCluster.getDomainId()).contains(domainId);
-                //can dedicate a cluster to an account/domain if pod is dedicated to parent-domain
-                if (dedicatedPodOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedPodOfCluster.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    s_logger.error("Cannot dedicate Cluster. Its Pod is already dedicated");
-                    HostPodVO pod = _podDao.findById(cluster.getPodId());
-                    throw new CloudRuntimeException("Cluster's Pod " + pod.getName() + " is already dedicated");
-                }
-            }
-
-            if (dedicatedZoneOfCluster != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfCluster.getDomainId()).contains(domainId);
-                //can dedicate a cluster to an account/domain if zone is dedicated to parent-domain
-                if (dedicatedZoneOfCluster.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedZoneOfCluster.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    s_logger.error("Cannot dedicate Cluster. Its zone is already dedicated");
-                    DataCenterVO zone = _zoneDao.findById(cluster.getDataCenterId());
-                    throw new CloudRuntimeException("Cluster's Zone " + zone.getName() + " is already dedicated");
-                }
-            }
-
-            //check if any resource under this cluster is dedicated to different account or sub-domain
-            hosts = _hostDao.findByClusterId(cluster.getId());
-            List<DedicatedResourceVO> hostsToRelease = new ArrayList<DedicatedResourceVO>();
-            for (HostVO host : hosts) {
-                DedicatedResourceVO dHost = _dedicatedDao.findByHostId(host.getId());
-                if (dHost != null) {
-                    if (!(childDomainIds.contains(dHost.getDomainId()))) {
-                        throw new CloudRuntimeException("Host " + host.getName() + " under this Cluster " + cluster.getName() +
-                            " is dedicated to different account/domain");
-                    }
-                    /*if all dedicated resources belongs to same account and domain then we should release dedication
-                    and make new entry for this cluster */
-                    if (accountId != null) {
-                        if (dHost.getAccountId().equals(accountId)) {
-                            hostsToRelease.add(dHost);
-                        } else {
-                            s_logger.error("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
-                            throw new CloudRuntimeException("Cannot dedicate Cluster " + cluster.getName() + " to account" + accountName);
-                        }
-                    } else {
-                        if (dHost.getAccountId() == null && dHost.getDomainId().equals(domainId)) {
-                            hostsToRelease.add(dHost);
-                        }
-                    }
-                }
-            }
-
-            for (DedicatedResourceVO dr : hostsToRelease) {
-                releaseDedicatedResource(null, null, null, dr.getHostId());
-            }
-        }
-
-        checkHostsSuitabilityForExplicitDedication(accountId, childDomainIds, hosts);
-
-        final Long accountIdFinal = accountId;
-        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
-            @Override
-            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
-                // find or create the affinity group by name under this account/domain
-                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
-                if (group == null) {
-                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
-                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
-                }
-                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, clusterId, null, null, null, group.getId());
-                try {
-                    dedicatedResource.setDomainId(domainId);
-                    if (accountIdFinal != null) {
-                        dedicatedResource.setAccountId(accountIdFinal);
-                    }
-                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
-                } catch (Exception e) {
-                    s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
-                    throw new CloudRuntimeException("Failed to dedicate cluster. Please contact Cloud Support.");
-                }
-
-                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
-                result.add(dedicatedResource);
-                return result;
-            }
-        });
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE, eventDescription = "dedicating a Host")
-    public List<DedicatedResourceVO> dedicateHost(final Long hostId, final Long domainId, final String accountName) {
-        Long accountId = null;
-        if (accountName != null) {
-            Account caller = CallContext.current().getCallingAccount();
-            Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
-            accountId = owner.getId();
-        }
-        checkAccountAndDomain(accountId, domainId);
-        HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Unable to find host by id " + hostId);
-        } else {
-            //check if host is of routing type
-            if (host.getType() != Host.Type.Routing) {
-                throw new CloudRuntimeException("Invalid host type for host " + host.getName());
-            }
-
-            DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
-            DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
-            DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
-            DedicatedResourceVO dedicatedZoneOfHost = _dedicatedDao.findByZoneId(host.getDataCenterId());
-
-            if (dedicatedHost != null) {
-                s_logger.error("Host " + host.getName() + " is already dedicated");
-                throw new CloudRuntimeException("Host " + host.getName() + " is already dedicated");
-            }
-
-            if (dedicatedClusterOfHost != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedClusterOfHost.getDomainId()).contains(domainId);
-                //can dedicate a host to an account/domain if cluster is dedicated to parent-domain
-                if (dedicatedClusterOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedClusterOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-                    s_logger.error("Host's Cluster " + cluster.getName() + " is already dedicated");
-                    throw new CloudRuntimeException("Host's Cluster " + cluster.getName() + " is already dedicated");
-                }
-            }
-
-            if (dedicatedPodOfHost != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedPodOfHost.getDomainId()).contains(domainId);
-                //can dedicate a host to an account/domain if pod is dedicated to parent-domain
-                if (dedicatedPodOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedPodOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    HostPodVO pod = _podDao.findById(host.getPodId());
-                    s_logger.error("Host's Pod " + pod.getName() + " is already dedicated");
-                    throw new CloudRuntimeException("Host's Pod " + pod.getName() + " is already dedicated");
-                }
-            }
-
-            if (dedicatedZoneOfHost != null) {
-                boolean domainIdInChildreanList = getDomainChildIds(dedicatedZoneOfHost.getDomainId()).contains(domainId);
-                //can dedicate a host to an account/domain if zone is dedicated to parent-domain
-                if (dedicatedZoneOfHost.getAccountId() != null || (accountId == null && !domainIdInChildreanList) ||
-                    (accountId != null && !(dedicatedZoneOfHost.getDomainId().equals(domainId) || domainIdInChildreanList))) {
-                    DataCenterVO zone = _zoneDao.findById(host.getDataCenterId());
-                    s_logger.error("Host's Data Center " + zone.getName() + " is already dedicated");
-                    throw new CloudRuntimeException("Host's Data Center " + zone.getName() + " is already dedicated");
-                }
-            }
-        }
-
-        List<Long> childDomainIds = getDomainChildIds(domainId);
-        childDomainIds.add(domainId);
-        checkHostSuitabilityForExplicitDedication(accountId, childDomainIds, hostId);
-
-        final Long accountIdFinal = accountId;
-        return Transaction.execute(new TransactionCallback<List<DedicatedResourceVO>>() {
-            @Override
-            public List<DedicatedResourceVO> doInTransaction(TransactionStatus status) {
-                // find or create the affinity group by name under this account/domain
-                AffinityGroup group = findOrCreateDedicatedAffinityGroup(domainId, accountIdFinal);
-                if (group == null) {
-                    s_logger.error("Unable to dedicate zone due to, failed to create dedication affinity group");
-                    throw new CloudRuntimeException("Failed to dedicate zone. Please contact Cloud Support.");
-                }
-                DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(null, null, null, hostId, null, null, group.getId());
-                try {
-                    dedicatedResource.setDomainId(domainId);
-                    if (accountIdFinal != null) {
-                        dedicatedResource.setAccountId(accountIdFinal);
-                    }
-                    dedicatedResource = _dedicatedDao.persist(dedicatedResource);
-                } catch (Exception e) {
-                    s_logger.error("Unable to dedicate host due to " + e.getMessage(), e);
-                    throw new CloudRuntimeException("Failed to dedicate host. Please contact Cloud Support.");
-                }
-
-                List<DedicatedResourceVO> result = new ArrayList<DedicatedResourceVO>();
-                result.add(dedicatedResource);
-                return result;
-            }
-        });
-
-    }
-
-    private AffinityGroup findOrCreateDedicatedAffinityGroup(Long domainId, Long accountId) {
-        if (domainId == null) {
-            return null;
-        }
-
-        AffinityGroup group = null;
-        String accountName = null;
-        String affinityGroupName = null;
-
-        if (accountId != null) {
-            AccountVO account = _accountDao.findById(accountId);
-            accountName = account.getAccountName();
-
-            group = _affinityGroupDao.findByAccountAndType(accountId, "ExplicitDedication");
-            if (group != null) {
-                return group;
-            }
-            // default to a groupname with account/domain information
-            affinityGroupName = "DedicatedGrp-" + accountName;
-
-        } else {
-            // domain level group
-            group = _affinityGroupDao.findDomainLevelGroupByType(domainId, "ExplicitDedication");
-            if (group != null) {
-                return group;
-            }
-            // default to a groupname with account/domain information
-            String domainName = _domainDao.findById(domainId).getName();
-            affinityGroupName = "DedicatedGrp-domain-" + domainName;
-        }
-
-        group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
-
-        return group;
-
-    }
-
-    private List<UserVmVO> getVmsOnHost(long hostId) {
-        List<UserVmVO> vms = _userVmDao.listUpByHostId(hostId);
-        List<UserVmVO> vmsByLastHostId = _userVmDao.listByLastHostId(hostId);
-        if (vmsByLastHostId.size() > 0) {
-            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
-            for (UserVmVO stoppedVM : vmsByLastHostId) {
-                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
-                if (secondsSinceLastUpdate < capacityReleaseInterval) {
-                    vms.add(stoppedVM);
-                }
-            }
-        }
-
-        return vms;
-    }
-
-    private boolean checkHostSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, long hostId) {
-        boolean suitable = true;
-        List<UserVmVO> allVmsOnHost = getVmsOnHost(hostId);
-        if (accountId != null) {
-            for (UserVmVO vm : allVmsOnHost) {
-                if (vm.getAccountId() != accountId) {
-                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " + "running instances of another account");
-                    throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
-                        "running instances of another account");
-                }
-            }
-        } else {
-            for (UserVmVO vm : allVmsOnHost) {
-                if (!domainIds.contains(vm.getDomainId())) {
-                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for explicit dedication as it is " + "running instances of another domain");
-                    throw new CloudRuntimeException("Host " + hostId + " found to be unsuitable for explicit dedication as it is " +
-                        "running instances of another domain");
-                }
-            }
-        }
-        return suitable;
-    }
-
-    private boolean checkHostsSuitabilityForExplicitDedication(Long accountId, List<Long> domainIds, List<HostVO> hosts) {
-        boolean suitable = true;
-        for (HostVO host : hosts) {
-            checkHostSuitabilityForExplicitDedication(accountId, domainIds, host.getId());
-        }
-        return suitable;
-    }
-
-    private void checkAccountAndDomain(Long accountId, Long domainId) {
-        DomainVO domain = _domainDao.findById(domainId);
-        if (domain == null) {
-            throw new InvalidParameterValueException("Unable to find the domain by id " + domainId + ", please specify valid domainId");
-        }
-        //check if account belongs to the domain id
-        if (accountId != null) {
-            AccountVO account = _accountDao.findById(accountId);
-            if (account == null || domainId != account.getDomainId()) {
-                throw new InvalidParameterValueException("Please specify the domain id of the account id " + accountId);
-            }
-        }
-    }
-
-    private List<Long> getDomainChildIds(long domainId) {
-        DomainVO domainRecord = _domainDao.findById(domainId);
-        List<Long> domainIds = new ArrayList<Long>();
-        domainIds.add(domainRecord.getId());
-        // find all domain Ids till leaf
-        List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
-        for (DomainVO domain : allChildDomains) {
-            domainIds.add(domain.getId());
-        }
-        return domainIds;
-    }
-
-    @Override
-    public DedicateZoneResponse createDedicateZoneResponse(DedicatedResources resource) {
-        DedicateZoneResponse dedicateZoneResponse = new DedicateZoneResponse();
-        DataCenterVO dc = _zoneDao.findById(resource.getDataCenterId());
-        DomainVO domain = _domainDao.findById(resource.getDomainId());
-        AccountVO account = _accountDao.findById(resource.getAccountId());
-        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
-        dedicateZoneResponse.setId(resource.getUuid());
-        dedicateZoneResponse.setZoneId(dc.getUuid());
-        dedicateZoneResponse.setZoneName(dc.getName());
-        dedicateZoneResponse.setDomainId(domain.getUuid());
-        dedicateZoneResponse.setAffinityGroupId(group.getUuid());
-        if (account != null) {
-            dedicateZoneResponse.setAccountId(account.getUuid());
-        }
-        dedicateZoneResponse.setObjectName("dedicatedzone");
-        return dedicateZoneResponse;
-    }
-
-    @Override
-    public DedicatePodResponse createDedicatePodResponse(DedicatedResources resource) {
-        DedicatePodResponse dedicatePodResponse = new DedicatePodResponse();
-        HostPodVO pod = _podDao.findById(resource.getPodId());
-        DomainVO domain = _domainDao.findById(resource.getDomainId());
-        AccountVO account = _accountDao.findById(resource.getAccountId());
-        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
-        dedicatePodResponse.setId(resource.getUuid());
-        dedicatePodResponse.setPodId(pod.getUuid());
-        dedicatePodResponse.setPodName(pod.getName());
-        dedicatePodResponse.setDomainId(domain.getUuid());
-        dedicatePodResponse.setAffinityGroupId(group.getUuid());
-        if (account != null) {
-            dedicatePodResponse.setAccountId(account.getUuid());
-        }
-        dedicatePodResponse.setObjectName("dedicatedpod");
-        return dedicatePodResponse;
-    }
-
-    @Override
-    public DedicateClusterResponse createDedicateClusterResponse(DedicatedResources resource) {
-        DedicateClusterResponse dedicateClusterResponse = new DedicateClusterResponse();
-        ClusterVO cluster = _clusterDao.findById(resource.getClusterId());
-        DomainVO domain = _domainDao.findById(resource.getDomainId());
-        AccountVO account = _accountDao.findById(resource.getAccountId());
-        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
-        dedicateClusterResponse.setId(resource.getUuid());
-        dedicateClusterResponse.setClusterId(cluster.getUuid());
-        dedicateClusterResponse.setClusterName(cluster.getName());
-        dedicateClusterResponse.setDomainId(domain.getUuid());
-        dedicateClusterResponse.setAffinityGroupId(group.getUuid());
-        if (account != null) {
-            dedicateClusterResponse.setAccountId(account.getUuid());
-        }
-        dedicateClusterResponse.setObjectName("dedicatedcluster");
-        return dedicateClusterResponse;
-    }
-
-    @Override
-    public DedicateHostResponse createDedicateHostResponse(DedicatedResources resource) {
-        DedicateHostResponse dedicateHostResponse = new DedicateHostResponse();
-        HostVO host = _hostDao.findById(resource.getHostId());
-        DomainVO domain = _domainDao.findById(resource.getDomainId());
-        AccountVO account = _accountDao.findById(resource.getAccountId());
-        AffinityGroup group = _affinityGroupDao.findById(resource.getAffinityGroupId());
-        dedicateHostResponse.setId(resource.getUuid());
-        dedicateHostResponse.setHostId(host.getUuid());
-        dedicateHostResponse.setHostName(host.getName());
-        dedicateHostResponse.setDomainId(domain.getUuid());
-        dedicateHostResponse.setAffinityGroupId(group.getUuid());
-        if (account != null) {
-            dedicateHostResponse.setAccountId(account.getUuid());
-        }
-        dedicateHostResponse.setObjectName("dedicatedhost");
-        return dedicateHostResponse;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(DedicateZoneCmd.class);
-        cmdList.add(DedicatePodCmd.class);
-        cmdList.add(DedicateClusterCmd.class);
-        cmdList.add(DedicateHostCmd.class);
-        cmdList.add(ListDedicatedZonesCmd.class);
-        cmdList.add(ListDedicatedPodsCmd.class);
-        cmdList.add(ListDedicatedClustersCmd.class);
-        cmdList.add(ListDedicatedHostsCmd.class);
-        cmdList.add(ReleaseDedicatedClusterCmd.class);
-        cmdList.add(ReleaseDedicatedHostCmd.class);
-        cmdList.add(ReleaseDedicatedPodCmd.class);
-        cmdList.add(ReleaseDedicatedZoneCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedZones(ListDedicatedZonesCmd cmd) {
-        Long zoneId = cmd.getZoneId();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        Long accountId = null;
-        Long affinityGroupId = cmd.getAffinityGroupId();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        if (accountName != null) {
-            if (domainId != null) {
-                Account account = _accountDao.findActiveAccount(accountName, domainId);
-                if (account != null) {
-                    accountId = account.getId();
-                }
-            } else {
-                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
-            }
-        }
-        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
-        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedZones(zoneId, domainId, accountId, affinityGroupId, searchFilter);
-        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedPods(ListDedicatedPodsCmd cmd) {
-        Long podId = cmd.getPodId();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        Long accountId = null;
-        Long affinityGroupId = cmd.getAffinityGroupId();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        if (accountName != null) {
-            if (domainId != null) {
-                Account account = _accountDao.findActiveAccount(accountName, domainId);
-                if (account != null) {
-                    accountId = account.getId();
-                }
-            } else {
-                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
-            }
-        }
-        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
-        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedPods(podId, domainId, accountId, affinityGroupId, searchFilter);
-        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedClusters(ListDedicatedClustersCmd cmd) {
-        Long clusterId = cmd.getClusterId();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        Long accountId = null;
-        Long affinityGroupId = cmd.getAffinityGroupId();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        if (accountName != null) {
-            if (domainId != null) {
-                Account account = _accountDao.findActiveAccount(accountName, domainId);
-                if (account != null) {
-                    accountId = account.getId();
-                }
-            } else {
-                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
-            }
-        }
-        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
-        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedClusters(clusterId, domainId, accountId, affinityGroupId, searchFilter);
-        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends DedicatedResourceVO>, Integer> listDedicatedHosts(ListDedicatedHostsCmd cmd) {
-        Long hostId = cmd.getHostId();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        Long affinityGroupId = cmd.getAffinityGroupId();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        Long accountId = null;
-        if (accountName != null) {
-            if (domainId != null) {
-                Account account = _accountDao.findActiveAccount(accountName, domainId);
-                if (account != null) {
-                    accountId = account.getId();
-                }
-            } else {
-                throw new InvalidParameterValueException("Please specify the domain id of the account: " + accountName);
-            }
-        }
-        Filter searchFilter = new Filter(DedicatedResourceVO.class, "id", true, startIndex, pageSize);
-        Pair<List<DedicatedResourceVO>, Integer> result = _dedicatedDao.searchDedicatedHosts(hostId, domainId, accountId, affinityGroupId, searchFilter);
-        return new Pair<List<? extends DedicatedResourceVO>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATE_RESOURCE_RELEASE, eventDescription = "Releasing dedicated resource")
-    public boolean releaseDedicatedResource(final Long zoneId, Long podId, Long clusterId, Long hostId) throws InvalidParameterValueException {
-        DedicatedResourceVO resource = null;
-        if (zoneId != null) {
-            resource = _dedicatedDao.findByZoneId(zoneId);
-        }
-        if (podId != null) {
-            resource = _dedicatedDao.findByPodId(podId);
-        }
-        if (clusterId != null) {
-            resource = _dedicatedDao.findByClusterId(clusterId);
-        }
-        if (hostId != null) {
-            resource = _dedicatedDao.findByHostId(hostId);
-        }
-        if (resource == null) {
-            throw new InvalidParameterValueException("No Dedicated Resource available to release");
-        } else {
-            final DedicatedResourceVO resourceFinal = resource;
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    Long resourceId = resourceFinal.getId();
-                    if (!_dedicatedDao.remove(resourceId)) {
-                        throw new CloudRuntimeException("Failed to delete Resource " + resourceId);
-                    }
-                    if (zoneId != null) {
-                        // remove the domainId set in zone
-                        DataCenterVO dc = _zoneDao.findById(zoneId);
-                        if (dc != null) {
-                            dc.setDomainId(null);
-                            dc.setDomain(null);
-                            if (!_zoneDao.update(zoneId, dc)) {
-                                throw new CloudRuntimeException("Failed to release dedicated zone, could not clear domainId. Please contact Cloud Support.");
-                            }
-                        }
-                    }
-                }
-            });
-
-            // find the group associated and check if there are any more
-            // resources under that group
-            List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
-            if (resourcesInGroup.isEmpty()) {
-                // delete the group
-                _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
-            }
-
-        }
-        return true;
-    }
-}
diff --git a/plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java b/plugins/dedicated-resources/src/test/java/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
similarity index 100%
rename from plugins/dedicated-resources/test/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
rename to plugins/dedicated-resources/src/test/java/org/apache/cloudstack/dedicated/manager/DedicatedApiUnitTest.java
diff --git a/plugins/dedicated-resources/test/resource/dedicatedContext.xml b/plugins/dedicated-resources/src/test/resources/dedicatedContext.xml
similarity index 100%
rename from plugins/dedicated-resources/test/resource/dedicatedContext.xml
rename to plugins/dedicated-resources/src/test/resources/dedicatedContext.xml
diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml
index 13b2251..07d19d6 100644
--- a/plugins/deployment-planners/implicit-dedication/pom.xml
+++ b/plugins/deployment-planners/implicit-dedication/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-planner-implicit-dedication</artifactId>
-  <name>Apache CloudStack Plugin - Implicit Dedication Planner</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-planner-implicit-dedication</artifactId>
+    <name>Apache CloudStack Plugin - Implicit Dedication Planner</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/deployment-planners/implicit-dedication/src/com/cloud/deploy/ImplicitDedicationPlanner.java b/plugins/deployment-planners/implicit-dedication/src/com/cloud/deploy/ImplicitDedicationPlanner.java
deleted file mode 100644
index 5bad922..0000000
--- a/plugins/deployment-planners/implicit-dedication/src/com/cloud/deploy/ImplicitDedicationPlanner.java
+++ /dev/null
@@ -1,317 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deploy;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.Config;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.host.HostVO;
-import com.cloud.resource.ResourceManager;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.user.Account;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class ImplicitDedicationPlanner extends FirstFitPlanner implements DeploymentClusterPlanner {
-
-    private static final Logger s_logger = Logger.getLogger(ImplicitDedicationPlanner.class);
-
-    @Inject
-    private ServiceOfferingDao serviceOfferingDao;
-    @Inject
-    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
-    @Inject
-    private ResourceManager resourceMgr;
-
-    private int capacityReleaseInterval;
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        capacityReleaseInterval = NumbersUtil.parseInt(configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
-        return true;
-    }
-
-    @Override
-    public List<Long> orderClusters(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException {
-        List<Long> clusterList = super.orderClusters(vmProfile, plan, avoid);
-        Set<Long> hostsToAvoid = avoid.getHostsToAvoid();
-        Account account = vmProfile.getOwner();
-
-        if (clusterList == null || clusterList.isEmpty()) {
-            return clusterList;
-        }
-
-        // Check if strict or preferred mode should be used.
-        boolean preferred = isServiceOfferingUsingPlannerInPreferredMode(vmProfile.getServiceOfferingId());
-
-        // Get the list of all the hosts in the given clusters
-        List<Long> allHosts = new ArrayList<Long>();
-        for (Long cluster : clusterList) {
-            List<HostVO> hostsInCluster = resourceMgr.listAllHostsInCluster(cluster);
-            for (HostVO hostVO : hostsInCluster) {
-                allHosts.add(hostVO.getId());
-            }
-        }
-
-        // Go over all the hosts in the cluster and get a list of
-        // 1. All empty hosts, not running any vms.
-        // 2. Hosts running vms for this account and created by a service offering which uses an
-        //    implicit dedication planner.
-        // 3. Hosts running vms created by implicit planner and in strict mode of other accounts.
-        // 4. Hosts running vms from other account or from this account but created by a service offering which uses
-        //    any planner besides implicit.
-        Set<Long> emptyHosts = new HashSet<Long>();
-        Set<Long> hostRunningVmsOfAccount = new HashSet<Long>();
-        Set<Long> hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet<Long>();
-        Set<Long> allOtherHosts = new HashSet<Long>();
-        for (Long host : allHosts) {
-            List<VMInstanceVO> vms = getVmsOnHost(host);
-            if (vms == null || vms.isEmpty()) {
-                emptyHosts.add(host);
-            } else if (checkHostSuitabilityForImplicitDedication(account.getAccountId(), vms)) {
-                hostRunningVmsOfAccount.add(host);
-            } else if (checkIfAllVmsCreatedInStrictMode(account.getAccountId(), vms)) {
-                hostRunningStrictImplicitVmsOfOtherAccounts.add(host);
-            } else {
-                allOtherHosts.add(host);
-            }
-        }
-
-        // Hosts running vms of other accounts created by ab implicit planner in strict mode should always be avoided.
-        avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts);
-
-        if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {
-            // Check if any of hosts that are running implicit dedicated vms are available (not in avoid list).
-            // If so, we'll try and use these hosts.
-            avoid.addHostList(emptyHosts);
-            avoid.addHostList(allOtherHosts);
-            clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
-        } else if (!emptyHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(emptyHosts))) {
-            // If there aren't implicit resources try on empty hosts
-            avoid.addHostList(allOtherHosts);
-            clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
-        } else if (!preferred) {
-            // If in strict mode, there is nothing else to try.
-            clusterList = null;
-        } else {
-            // If in preferred mode, check if hosts are available to try, otherwise return an empty cluster list.
-            if (!allOtherHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(allOtherHosts))) {
-                clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
-            } else {
-                clusterList = null;
-            }
-        }
-
-        return clusterList;
-    }
-
-    private List<VMInstanceVO> getVmsOnHost(long hostId) {
-        List<VMInstanceVO> vms = vmInstanceDao.listUpByHostId(hostId);
-        List<VMInstanceVO> vmsByLastHostId = vmInstanceDao.listByLastHostId(hostId);
-        if (vmsByLastHostId.size() > 0) {
-            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
-            for (VMInstanceVO stoppedVM : vmsByLastHostId) {
-                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
-                if (secondsSinceLastUpdate < capacityReleaseInterval) {
-                    vms.add(stoppedVM);
-                }
-            }
-        }
-
-        return vms;
-    }
-
-    private boolean checkHostSuitabilityForImplicitDedication(Long accountId, List<VMInstanceVO> allVmsOnHost) {
-        boolean suitable = true;
-        if (allVmsOnHost.isEmpty())
-            return false;
-
-        for (VMInstanceVO vm : allVmsOnHost) {
-            if (vm.getAccountId() != accountId) {
-                s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for implicit dedication as it is " + "running instances of another account");
-                suitable = false;
-                break;
-            } else {
-                if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId())) {
-                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for implicit dedication as it " +
-                        "is running instances of this account which haven't been created using implicit dedication.");
-                    suitable = false;
-                    break;
-                }
-            }
-        }
-        return suitable;
-    }
-
-    private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
-        boolean createdByImplicitStrict = true;
-        if (allVmsOnHost.isEmpty())
-            return false;
-        for (VMInstanceVO vm : allVmsOnHost) {
-            if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId())) {
-                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" + " than implicit.");
-                createdByImplicitStrict = false;
-                break;
-            } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
-                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" + " in preferred mode.");
-                createdByImplicitStrict = false;
-                break;
-            }
-        }
-        return createdByImplicitStrict;
-    }
-
-    private boolean isImplicitPlannerUsedByOffering(long offeringId) {
-        boolean implicitPlannerUsed = false;
-        ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(offeringId);
-        if (offering == null) {
-            s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
-        } else {
-            String plannerName = offering.getDeploymentPlanner();
-            if (plannerName == null) {
-                plannerName = globalDeploymentPlanner;
-            }
-
-            if (plannerName != null && this.getName().equals(plannerName)) {
-                implicitPlannerUsed = true;
-            }
-        }
-
-        return implicitPlannerUsed;
-    }
-
-    private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
-        boolean preferred = false;
-        Map<String, String> details = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOfferingId);
-        if (details != null && !details.isEmpty()) {
-            String preferredAttribute = details.get("ImplicitDedicationMode");
-            if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
-                preferred = true;
-            }
-        }
-        return preferred;
-    }
-
-    private List<Long> getUpdatedClusterList(List<Long> clusterList, Set<Long> hostsSet) {
-        List<Long> updatedClusterList = new ArrayList<Long>();
-        for (Long cluster : clusterList) {
-            List<HostVO> hosts = resourceMgr.listAllHostsInCluster(cluster);
-            Set<Long> hostsInClusterSet = new HashSet<Long>();
-            for (HostVO host : hosts) {
-                hostsInClusterSet.add(host.getId());
-            }
-
-            if (!hostsSet.containsAll(hostsInClusterSet)) {
-                updatedClusterList.add(cluster);
-            }
-        }
-
-        return updatedClusterList;
-    }
-
-    @Override
-    public PlannerResourceUsage getResourceUsage(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException {
-        // Check if strict or preferred mode should be used.
-        boolean preferred = isServiceOfferingUsingPlannerInPreferredMode(vmProfile.getServiceOfferingId());
-
-        // If service offering in strict mode return resource usage as Dedicated
-        if (!preferred) {
-            return PlannerResourceUsage.Dedicated;
-        } else {
-            // service offering is in implicit mode.
-            // find is it possible to deploy in dedicated mode,
-            // if its possible return dedicated else return shared.
-            List<Long> clusterList = super.orderClusters(vmProfile, plan, avoid);
-            Set<Long> hostsToAvoid = avoid.getHostsToAvoid();
-            Account account = vmProfile.getOwner();
-
-            // Get the list of all the hosts in the given clusters
-            List<Long> allHosts = new ArrayList<Long>();
-            for (Long cluster : clusterList) {
-                List<HostVO> hostsInCluster = resourceMgr.listAllHostsInCluster(cluster);
-                for (HostVO hostVO : hostsInCluster) {
-
-                    allHosts.add(hostVO.getId());
-                }
-            }
-
-            // Go over all the hosts in the cluster and get a list of
-            // 1. All empty hosts, not running any vms.
-            // 2. Hosts running vms for this account and created by a service
-            // offering which uses an
-            // implicit dedication planner.
-            // 3. Hosts running vms created by implicit planner and in strict
-            // mode of other accounts.
-            // 4. Hosts running vms from other account or from this account but
-            // created by a service offering which uses
-            // any planner besides implicit.
-            Set<Long> emptyHosts = new HashSet<Long>();
-            Set<Long> hostRunningVmsOfAccount = new HashSet<Long>();
-            Set<Long> hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet<Long>();
-            Set<Long> allOtherHosts = new HashSet<Long>();
-            for (Long host : allHosts) {
-                List<VMInstanceVO> vms = getVmsOnHost(host);
-                // emptyHost should contain only Hosts which are not having any VM's (user/system) on it.
-                if (vms == null || vms.isEmpty()) {
-                    emptyHosts.add(host);
-                } else if (checkHostSuitabilityForImplicitDedication(account.getAccountId(), vms)) {
-                    hostRunningVmsOfAccount.add(host);
-                } else if (checkIfAllVmsCreatedInStrictMode(account.getAccountId(), vms)) {
-                    hostRunningStrictImplicitVmsOfOtherAccounts.add(host);
-                } else {
-                    allOtherHosts.add(host);
-                }
-            }
-
-            // Hosts running vms of other accounts created by ab implicit
-            // planner in strict mode should always be avoided.
-            avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts);
-
-            if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {
-                // Check if any of hosts that are running implicit dedicated vms are available (not in avoid list).
-                // If so, we'll try and use these hosts. We can deploy in Dedicated mode
-                return PlannerResourceUsage.Dedicated;
-            } else if (!emptyHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(emptyHosts))) {
-                // If there aren't implicit resources try on empty hosts, As empty hosts are available we can deploy in Dedicated mode.
-                // Empty hosts can contain hosts which are not having user vms but system vms are running.
-                // But the host where system vms are running is marked as shared and still be part of empty Hosts.
-                // The scenario will fail where actual Empty hosts and uservms not running host.
-                return PlannerResourceUsage.Dedicated;
-            } else {
-                if (!allOtherHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(allOtherHosts))) {
-                    return PlannerResourceUsage.Shared;
-                }
-            }
-            return PlannerResourceUsage.Shared;
-        }
-    }
-}
diff --git a/plugins/deployment-planners/implicit-dedication/src/main/java/com/cloud/deploy/ImplicitDedicationPlanner.java b/plugins/deployment-planners/implicit-dedication/src/main/java/com/cloud/deploy/ImplicitDedicationPlanner.java
new file mode 100644
index 0000000..45f16ab
--- /dev/null
+++ b/plugins/deployment-planners/implicit-dedication/src/main/java/com/cloud/deploy/ImplicitDedicationPlanner.java
@@ -0,0 +1,319 @@
+// 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.deploy;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.host.HostVO;
+import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.user.Account;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachineProfile;
+import org.springframework.util.CollectionUtils;
+
+public class ImplicitDedicationPlanner extends FirstFitPlanner implements DeploymentClusterPlanner {
+
+    private static final Logger s_logger = Logger.getLogger(ImplicitDedicationPlanner.class);
+
+    @Inject
+    private ServiceOfferingDao serviceOfferingDao;
+    @Inject
+    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
+    @Inject
+    private ResourceManager resourceMgr;
+
+    private int capacityReleaseInterval;
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        capacityReleaseInterval = NumbersUtil.parseInt(configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+        return true;
+    }
+
+    @Override
+    public List<Long> orderClusters(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException {
+        List<Long> clusterList = super.orderClusters(vmProfile, plan, avoid);
+        Set<Long> hostsToAvoid = avoid.getHostsToAvoid();
+        Account account = vmProfile.getOwner();
+
+        if (clusterList == null || clusterList.isEmpty()) {
+            return clusterList;
+        }
+
+        // Check if strict or preferred mode should be used.
+        boolean preferred = isServiceOfferingUsingPlannerInPreferredMode(vmProfile.getServiceOfferingId());
+
+        // Get the list of all the hosts in the given clusters
+        List<Long> allHosts = new ArrayList<Long>();
+        for (Long cluster : clusterList) {
+            List<HostVO> hostsInCluster = resourceMgr.listAllHostsInCluster(cluster);
+            for (HostVO hostVO : hostsInCluster) {
+                allHosts.add(hostVO.getId());
+            }
+        }
+
+        // Go over all the hosts in the cluster and get a list of
+        // 1. All empty hosts, not running any vms.
+        // 2. Hosts running vms for this account and created by a service offering which uses an
+        //    implicit dedication planner.
+        // 3. Hosts running vms created by implicit planner and in strict mode of other accounts.
+        // 4. Hosts running vms from other account or from this account but created by a service offering which uses
+        //    any planner besides implicit.
+        Set<Long> emptyHosts = new HashSet<Long>();
+        Set<Long> hostRunningVmsOfAccount = new HashSet<Long>();
+        Set<Long> hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet<Long>();
+        Set<Long> allOtherHosts = new HashSet<Long>();
+        for (Long host : allHosts) {
+            List<VMInstanceVO> vms = getVmsOnHost(host);
+            if (vms == null || vms.isEmpty()) {
+                emptyHosts.add(host);
+            } else if (checkHostSuitabilityForImplicitDedication(account.getAccountId(), vms)) {
+                hostRunningVmsOfAccount.add(host);
+            } else if (checkIfAllVmsCreatedInStrictMode(account.getAccountId(), vms)) {
+                hostRunningStrictImplicitVmsOfOtherAccounts.add(host);
+            } else {
+                allOtherHosts.add(host);
+            }
+        }
+
+        // Hosts running vms of other accounts created by ab implicit planner in strict mode should always be avoided.
+        avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts);
+
+        if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {
+            // Check if any of hosts that are running implicit dedicated vms are available (not in avoid list).
+            // If so, we'll try and use these hosts.
+            avoid.addHostList(emptyHosts);
+            avoid.addHostList(allOtherHosts);
+            clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
+        } else if (!emptyHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(emptyHosts))) {
+            // If there aren't implicit resources try on empty hosts
+            avoid.addHostList(allOtherHosts);
+            clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
+        } else if (!preferred) {
+            // If in strict mode, there is nothing else to try.
+            clusterList = null;
+        } else {
+            // If in preferred mode, check if hosts are available to try, otherwise return an empty cluster list.
+            if (!allOtherHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(allOtherHosts))) {
+                clusterList = getUpdatedClusterList(clusterList, avoid.getHostsToAvoid());
+            } else {
+                clusterList = null;
+            }
+        }
+
+        return clusterList;
+    }
+
+    private List<VMInstanceVO> getVmsOnHost(long hostId) {
+        List<VMInstanceVO> vms = vmInstanceDao.listUpByHostId(hostId);
+        List<VMInstanceVO> vmsByLastHostId = vmInstanceDao.listByLastHostId(hostId);
+        if (vmsByLastHostId.size() > 0) {
+            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
+            for (VMInstanceVO stoppedVM : vmsByLastHostId) {
+                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
+                if (secondsSinceLastUpdate < capacityReleaseInterval) {
+                    vms.add(stoppedVM);
+                }
+            }
+        }
+
+        return vms;
+    }
+
+    private boolean checkHostSuitabilityForImplicitDedication(Long accountId, List<VMInstanceVO> allVmsOnHost) {
+        boolean suitable = true;
+        if (allVmsOnHost.isEmpty())
+            return false;
+
+        for (VMInstanceVO vm : allVmsOnHost) {
+            if (vm.getAccountId() != accountId) {
+                s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for implicit dedication as it is " + "running instances of another account");
+                suitable = false;
+                break;
+            } else {
+                if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId())) {
+                    s_logger.info("Host " + vm.getHostId() + " found to be unsuitable for implicit dedication as it " +
+                        "is running instances of this account which haven't been created using implicit dedication.");
+                    suitable = false;
+                    break;
+                }
+            }
+        }
+        return suitable;
+    }
+
+    private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
+        boolean createdByImplicitStrict = true;
+        if (allVmsOnHost.isEmpty())
+            return false;
+        for (VMInstanceVO vm : allVmsOnHost) {
+            if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId())) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" + " than implicit.");
+                createdByImplicitStrict = false;
+                break;
+            } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" + " in preferred mode.");
+                createdByImplicitStrict = false;
+                break;
+            }
+        }
+        return createdByImplicitStrict;
+    }
+
+    private boolean isImplicitPlannerUsedByOffering(long offeringId) {
+        boolean implicitPlannerUsed = false;
+        ServiceOfferingVO offering = serviceOfferingDao.findByIdIncludingRemoved(offeringId);
+        if (offering == null) {
+            s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
+        } else {
+            String plannerName = offering.getDeploymentPlanner();
+            if (plannerName == null) {
+                plannerName = globalDeploymentPlanner;
+            }
+
+            if (plannerName != null && this.getName().equals(plannerName)) {
+                implicitPlannerUsed = true;
+            }
+        }
+
+        return implicitPlannerUsed;
+    }
+
+    private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
+        boolean preferred = false;
+        Map<String, String> details = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOfferingId);
+        if (details != null && !details.isEmpty()) {
+            String preferredAttribute = details.get("ImplicitDedicationMode");
+            if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
+                preferred = true;
+            }
+        }
+        return preferred;
+    }
+
+    private List<Long> getUpdatedClusterList(List<Long> clusterList, Set<Long> hostsSet) {
+        List<Long> updatedClusterList = new ArrayList<Long>();
+        for (Long cluster : clusterList) {
+            List<HostVO> hosts = resourceMgr.listAllHostsInCluster(cluster);
+            Set<Long> hostsInClusterSet = new HashSet<Long>();
+            for (HostVO host : hosts) {
+                hostsInClusterSet.add(host.getId());
+            }
+
+            if (!hostsSet.containsAll(hostsInClusterSet)) {
+                updatedClusterList.add(cluster);
+            }
+        }
+
+        return updatedClusterList;
+    }
+
+    @Override
+    public PlannerResourceUsage getResourceUsage(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException {
+        // Check if strict or preferred mode should be used.
+        boolean preferred = isServiceOfferingUsingPlannerInPreferredMode(vmProfile.getServiceOfferingId());
+
+        // If service offering in strict mode return resource usage as Dedicated
+        if (!preferred) {
+            return PlannerResourceUsage.Dedicated;
+        } else {
+            // service offering is in implicit mode.
+            // find is it possible to deploy in dedicated mode,
+            // if its possible return dedicated else return shared.
+            List<Long> clusterList = super.orderClusters(vmProfile, plan, avoid);
+            Set<Long> hostsToAvoid = avoid.getHostsToAvoid();
+            Account account = vmProfile.getOwner();
+
+            // Get the list of all the hosts in the given clusters
+            List<Long> allHosts = new ArrayList<Long>();
+            if (!CollectionUtils.isEmpty(clusterList)) {
+                for (Long cluster : clusterList) {
+                    List<HostVO> hostsInCluster = resourceMgr.listAllHostsInCluster(cluster);
+                    for (HostVO hostVO : hostsInCluster) {
+
+                        allHosts.add(hostVO.getId());
+                    }
+                }
+            }
+            // Go over all the hosts in the cluster and get a list of
+            // 1. All empty hosts, not running any vms.
+            // 2. Hosts running vms for this account and created by a service
+            // offering which uses an
+            // implicit dedication planner.
+            // 3. Hosts running vms created by implicit planner and in strict
+            // mode of other accounts.
+            // 4. Hosts running vms from other account or from this account but
+            // created by a service offering which uses
+            // any planner besides implicit.
+            Set<Long> emptyHosts = new HashSet<Long>();
+            Set<Long> hostRunningVmsOfAccount = new HashSet<Long>();
+            Set<Long> hostRunningStrictImplicitVmsOfOtherAccounts = new HashSet<Long>();
+            Set<Long> allOtherHosts = new HashSet<Long>();
+            for (Long host : allHosts) {
+                List<VMInstanceVO> vms = getVmsOnHost(host);
+                // emptyHost should contain only Hosts which are not having any VM's (user/system) on it.
+                if (vms == null || vms.isEmpty()) {
+                    emptyHosts.add(host);
+                } else if (checkHostSuitabilityForImplicitDedication(account.getAccountId(), vms)) {
+                    hostRunningVmsOfAccount.add(host);
+                } else if (checkIfAllVmsCreatedInStrictMode(account.getAccountId(), vms)) {
+                    hostRunningStrictImplicitVmsOfOtherAccounts.add(host);
+                } else {
+                    allOtherHosts.add(host);
+                }
+            }
+
+            // Hosts running vms of other accounts created by ab implicit
+            // planner in strict mode should always be avoided.
+            avoid.addHostList(hostRunningStrictImplicitVmsOfOtherAccounts);
+
+            if (!hostRunningVmsOfAccount.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(hostRunningVmsOfAccount))) {
+                // Check if any of hosts that are running implicit dedicated vms are available (not in avoid list).
+                // If so, we'll try and use these hosts. We can deploy in Dedicated mode
+                return PlannerResourceUsage.Dedicated;
+            } else if (!emptyHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(emptyHosts))) {
+                // If there aren't implicit resources try on empty hosts, As empty hosts are available we can deploy in Dedicated mode.
+                // Empty hosts can contain hosts which are not having user vms but system vms are running.
+                // But the host where system vms are running is marked as shared and still be part of empty Hosts.
+                // The scenario will fail where actual Empty hosts and uservms not running host.
+                return PlannerResourceUsage.Dedicated;
+            } else {
+                if (!allOtherHosts.isEmpty() && (hostsToAvoid == null || !hostsToAvoid.containsAll(allOtherHosts))) {
+                    return PlannerResourceUsage.Shared;
+                }
+            }
+            return PlannerResourceUsage.Shared;
+        }
+    }
+}
diff --git a/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/module.properties b/plugins/deployment-planners/implicit-dedication/src/main/resources/META-INF/cloudstack/implicit-dedication/module.properties
similarity index 100%
rename from plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/module.properties
rename to plugins/deployment-planners/implicit-dedication/src/main/resources/META-INF/cloudstack/implicit-dedication/module.properties
diff --git a/plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml b/plugins/deployment-planners/implicit-dedication/src/main/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml
similarity index 100%
rename from plugins/deployment-planners/implicit-dedication/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml
rename to plugins/deployment-planners/implicit-dedication/src/main/resources/META-INF/cloudstack/implicit-dedication/spring-implicit-dedication-context.xml
diff --git a/plugins/deployment-planners/implicit-dedication/test/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java b/plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java
similarity index 100%
rename from plugins/deployment-planners/implicit-dedication/test/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java
rename to plugins/deployment-planners/implicit-dedication/src/test/java/org/apache/cloudstack/implicitplanner/ImplicitPlannerTest.java
diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml
index a452913..63973c4 100644
--- a/plugins/deployment-planners/user-concentrated-pod/pom.xml
+++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-planner-user-concentrated-pod</artifactId>
-  <name>Apache CloudStack Plugin - User Concentrated Pod Deployment Planner</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-planner-user-concentrated-pod</artifactId>
+    <name>Apache CloudStack Plugin - User Concentrated Pod Deployment Planner</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/deployment-planners/user-concentrated-pod/src/com/cloud/deploy/UserConcentratedPodPlanner.java b/plugins/deployment-planners/user-concentrated-pod/src/main/java/com/cloud/deploy/UserConcentratedPodPlanner.java
similarity index 100%
rename from plugins/deployment-planners/user-concentrated-pod/src/com/cloud/deploy/UserConcentratedPodPlanner.java
rename to plugins/deployment-planners/user-concentrated-pod/src/main/java/com/cloud/deploy/UserConcentratedPodPlanner.java
diff --git a/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/module.properties b/plugins/deployment-planners/user-concentrated-pod/src/main/resources/META-INF/cloudstack/user-concentrated-pod/module.properties
similarity index 100%
rename from plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/module.properties
rename to plugins/deployment-planners/user-concentrated-pod/src/main/resources/META-INF/cloudstack/user-concentrated-pod/module.properties
diff --git a/plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml b/plugins/deployment-planners/user-concentrated-pod/src/main/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml
similarity index 100%
rename from plugins/deployment-planners/user-concentrated-pod/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml
rename to plugins/deployment-planners/user-concentrated-pod/src/main/resources/META-INF/cloudstack/user-concentrated-pod/spring-user-concentrated-pod-context.xml
diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml
index b79068e..a7f940c 100644
--- a/plugins/deployment-planners/user-dispersing/pom.xml
+++ b/plugins/deployment-planners/user-dispersing/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-planner-user-dispersing</artifactId>
-  <name>Apache CloudStack Plugin - User Dispersing Deployment Planner</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-planner-user-dispersing</artifactId>
+    <name>Apache CloudStack Plugin - User Dispersing Deployment Planner</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java b/plugins/deployment-planners/user-dispersing/src/main/java/com/cloud/deploy/UserDispersingPlanner.java
similarity index 100%
rename from plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java
rename to plugins/deployment-planners/user-dispersing/src/main/java/com/cloud/deploy/UserDispersingPlanner.java
diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml
index bc6e668..0f2c69e 100644
--- a/plugins/event-bus/inmemory/pom.xml
+++ b/plugins/event-bus/inmemory/pom.xml
@@ -1,40 +1,37 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-mom-inmemory</artifactId>
-  <name>Apache CloudStack Plugin - In Memory Event Bus</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-    <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
+    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-mom-inmemory</artifactId>
+    <name>Apache CloudStack Plugin - In Memory Event Bus</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/event-bus/inmemory/src/org/apache/cloudstack/mom/inmemory/InMemoryEventBus.java b/plugins/event-bus/inmemory/src/main/java/org/apache/cloudstack/mom/inmemory/InMemoryEventBus.java
similarity index 100%
rename from plugins/event-bus/inmemory/src/org/apache/cloudstack/mom/inmemory/InMemoryEventBus.java
rename to plugins/event-bus/inmemory/src/main/java/org/apache/cloudstack/mom/inmemory/InMemoryEventBus.java
diff --git a/plugins/event-bus/inmemory/test/org/apache/cloudstack/mom/inmemory/InMemoryEventBusTest.java b/plugins/event-bus/inmemory/src/test/java/org/apache/cloudstack/mom/inmemory/InMemoryEventBusTest.java
similarity index 100%
rename from plugins/event-bus/inmemory/test/org/apache/cloudstack/mom/inmemory/InMemoryEventBusTest.java
rename to plugins/event-bus/inmemory/src/test/java/org/apache/cloudstack/mom/inmemory/InMemoryEventBusTest.java
diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml
index f72c693..ffa9476 100644
--- a/plugins/event-bus/kafka/pom.xml
+++ b/plugins/event-bus/kafka/pom.xml
@@ -1,45 +1,41 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-mom-kafka</artifactId>
-  <name>Apache CloudStack Plugin - Kafka Event Bus</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-    <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.kafka</groupId>
-      <artifactId>kafka-clients</artifactId>
-      <version>0.11.0.1</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
+    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-mom-kafka</artifactId>
+    <name>Apache CloudStack Plugin - Kafka Event Bus</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/event-bus/kafka/src/org/apache/cloudstack/mom/kafka/KafkaEventBus.java b/plugins/event-bus/kafka/src/main/java/org/apache/cloudstack/mom/kafka/KafkaEventBus.java
similarity index 100%
rename from plugins/event-bus/kafka/src/org/apache/cloudstack/mom/kafka/KafkaEventBus.java
rename to plugins/event-bus/kafka/src/main/java/org/apache/cloudstack/mom/kafka/KafkaEventBus.java
diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml
index 4741b01..c55509d 100644
--- a/plugins/event-bus/rabbitmq/pom.xml
+++ b/plugins/event-bus/rabbitmq/pom.xml
@@ -1,45 +1,41 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-mom-rabbitmq</artifactId>
-  <name>Apache CloudStack Plugin - RabbitMQ Event Bus</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-    <groupId>com.rabbitmq</groupId>
-      <artifactId>amqp-client</artifactId>
-        <version>5.1.1</version>
-    </dependency>
-    <dependency>
-    <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
+    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-mom-rabbitmq</artifactId>
+    <name>Apache CloudStack Plugin - RabbitMQ Event Bus</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.rabbitmq</groupId>
+            <artifactId>amqp-client</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/event-bus/rabbitmq/src/main/java/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java b/plugins/event-bus/rabbitmq/src/main/java/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
new file mode 100644
index 0000000..b2f173e
--- /dev/null
+++ b/plugins/event-bus/rabbitmq/src/main/java/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
@@ -0,0 +1,626 @@
+/*
+ * 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.mom.rabbitmq;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.rabbitmq.client.BlockedListener;
+import org.apache.log4j.Logger;
+
+import com.rabbitmq.client.AMQP;
+import com.rabbitmq.client.AlreadyClosedException;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import com.rabbitmq.client.DefaultConsumer;
+import com.rabbitmq.client.Envelope;
+import com.rabbitmq.client.MessageProperties;
+import com.rabbitmq.client.ShutdownListener;
+import com.rabbitmq.client.ShutdownSignalException;
+
+import org.apache.cloudstack.framework.events.Event;
+import org.apache.cloudstack.framework.events.EventBus;
+import org.apache.cloudstack.framework.events.EventBusException;
+import org.apache.cloudstack.framework.events.EventSubscriber;
+import org.apache.cloudstack.framework.events.EventTopic;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+
+public class RabbitMQEventBus extends ManagerBase implements EventBus {
+
+    // details of AMQP server
+    private static String amqpHost;
+    private static Integer port;
+    private static String username;
+    private static String password;
+    private static String secureProtocol = "TLSv1.2";
+
+    public synchronized static void setVirtualHost(String virtualHost) {
+        RabbitMQEventBus.virtualHost = virtualHost;
+    }
+
+    private static String virtualHost;
+
+    public static void setUseSsl(String useSsl) {
+        RabbitMQEventBus.useSsl = useSsl;
+    }
+
+    private static String useSsl;
+
+    // AMQP exchange name where all CloudStack events will be published
+    private static String amqpExchangeName;
+
+    private String name;
+
+    private static Integer retryInterval;
+
+    // hashmap to book keep the registered subscribers
+    private static ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>> s_subscribers;
+
+    // connection to AMQP server,
+    private static Connection s_connection = null;
+
+    // AMQP server should consider messages acknowledged once delivered if _autoAck is true
+    private static boolean s_autoAck = true;
+
+    private ExecutorService executorService;
+    private static DisconnectHandler disconnectHandler;
+    private static BlockedConnectionHandler blockedConnectionHandler;
+    private static final Logger s_logger = Logger.getLogger(RabbitMQEventBus.class);
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+        try {
+            if (amqpHost == null || amqpHost.isEmpty()) {
+                throw new ConfigurationException("Unable to get the AMQP server details");
+            }
+
+            if (username == null || username.isEmpty()) {
+                throw new ConfigurationException("Unable to get the username details");
+            }
+
+            if (password == null || password.isEmpty()) {
+                throw new ConfigurationException("Unable to get the password details");
+            }
+
+            if (amqpExchangeName == null || amqpExchangeName.isEmpty()) {
+                throw new ConfigurationException("Unable to get the _exchange details on the AMQP server");
+            }
+
+            if (port == null) {
+                throw new ConfigurationException("Unable to get the port details of AMQP server");
+            }
+
+            if (useSsl != null && !useSsl.isEmpty()) {
+                if (!useSsl.equalsIgnoreCase("true") && !useSsl.equalsIgnoreCase("false")) {
+                    throw new ConfigurationException("Invalid configuration parameter for 'ssl'.");
+                }
+            }
+
+            if (retryInterval == null) {
+                retryInterval = 10000;// default to 10s to try out reconnect
+            }
+
+        } catch (NumberFormatException e) {
+            throw new ConfigurationException("Invalid port number/retry interval");
+        }
+
+        s_subscribers = new ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>>();
+        executorService = Executors.newCachedThreadPool();
+        disconnectHandler = new DisconnectHandler();
+        blockedConnectionHandler = new BlockedConnectionHandler();
+
+        return true;
+    }
+
+    public static void setServer(String amqpHost) {
+        RabbitMQEventBus.amqpHost = amqpHost;
+    }
+
+    public static void setUsername(String username) {
+        RabbitMQEventBus.username = username;
+    }
+
+    public static void setPassword(String password) {
+        RabbitMQEventBus.password = password;
+    }
+
+    public static void setPort(Integer port) {
+        RabbitMQEventBus.port = port;
+    }
+
+    public static void setSecureProtocol(String protocol) {
+        RabbitMQEventBus.secureProtocol = protocol;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public static void setExchange(String exchange) {
+        RabbitMQEventBus.amqpExchangeName = exchange;
+    }
+
+    public static void setRetryInterval(Integer retryInterval) {
+        RabbitMQEventBus.retryInterval = retryInterval;
+    }
+
+    /** Call to subscribe to interested set of events
+     *
+     * @param topic defines category and type of the events being subscribed to
+     * @param subscriber subscriber that intends to receive event notification
+     * @return UUID that represents the subscription with event bus
+     * @throws EventBusException
+     */
+    @Override
+    public UUID subscribe(EventTopic topic, EventSubscriber subscriber) throws EventBusException {
+
+        if (subscriber == null || topic == null) {
+            throw new EventBusException("Invalid EventSubscriber/EventTopic object passed.");
+        }
+
+        // create a UUID, that will be used for managing subscriptions and also used as queue name
+        // for on the queue used for the subscriber on the AMQP broker
+        UUID queueId = UUID.randomUUID();
+        String queueName = queueId.toString();
+
+        try {
+            String bindingKey = createBindingKey(topic);
+
+            // store the subscriber details before creating channel
+            s_subscribers.put(queueName, new Ternary(bindingKey, null, subscriber));
+
+            // create a channel dedicated for this subscription
+            Connection connection = getConnection();
+            Channel channel = createChannel(connection);
+
+            // create a queue and bind it to the exchange with binding key formed from event topic
+            createExchange(channel, amqpExchangeName);
+            channel.queueDeclare(queueName, false, false, false, null);
+            channel.queueBind(queueName, amqpExchangeName, bindingKey);
+
+            // register a callback handler to receive the events that a subscriber subscribed to
+            channel.basicConsume(queueName, s_autoAck, queueName, new DefaultConsumer(channel) {
+                @Override
+                public void handleDelivery(String queueName, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
+                    Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
+                    if (queueDetails != null) {
+                        EventSubscriber subscriber = queueDetails.third();
+                        String routingKey = envelope.getRoutingKey();
+                        String eventSource = getEventSourceFromRoutingKey(routingKey);
+                        String eventCategory = getEventCategoryFromRoutingKey(routingKey);
+                        String eventType = getEventTypeFromRoutingKey(routingKey);
+                        String resourceType = getResourceTypeFromRoutingKey(routingKey);
+                        String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
+                        Event event = new Event(eventSource, eventCategory, eventType, resourceType, resourceUUID);
+                        event.setDescription(new String(body));
+
+                        // deliver the event to call back object provided by subscriber
+                        subscriber.onEvent(event);
+                    }
+                }
+            });
+
+            // update the channel details for the subscription
+            Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
+            queueDetails.second(channel);
+            s_subscribers.put(queueName, queueDetails);
+
+        } catch (AlreadyClosedException closedException) {
+            s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + " will be active after reconnection", closedException);
+        } catch (ConnectException connectException) {
+            s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + " will be active after reconnection", connectException);
+        } catch (Exception e) {
+            throw new EventBusException("Failed to subscribe to event due to " + e.getMessage());
+        }
+
+        return queueId;
+    }
+
+    @Override
+    public void unsubscribe(UUID subscriberId, EventSubscriber subscriber) throws EventBusException {
+        try {
+            String classname = subscriber.getClass().getName();
+            String queueName = UUID.nameUUIDFromBytes(classname.getBytes()).toString();
+            Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
+            Channel channel = queueDetails.second();
+            channel.basicCancel(queueName);
+            s_subscribers.remove(queueName, queueDetails);
+        } catch (Exception e) {
+            throw new EventBusException("Failed to unsubscribe from event bus due to " + e.getMessage());
+        }
+    }
+
+    // publish event on to the exchange created on AMQP server
+    @Override
+    public void publish(Event event) throws EventBusException {
+
+        String routingKey = createRoutingKey(event);
+        String eventDescription = event.getDescription();
+
+        try {
+            Connection connection = getConnection();
+            Channel channel = createChannel(connection);
+            createExchange(channel, amqpExchangeName);
+            publishEventToExchange(channel, amqpExchangeName, routingKey, eventDescription);
+            channel.close();
+        } catch (AlreadyClosedException e) {
+            closeConnection();
+            throw new EventBusException("Failed to publish event to message broker as connection to AMQP broker in lost");
+        } catch (Exception e) {
+            throw new EventBusException("Failed to publish event to message broker due to " + e.getMessage());
+        }
+    }
+
+    /** creates a routing key from the event details.
+     *  created routing key will be used while publishing the message to exchange on AMQP server
+     */
+    private String createRoutingKey(Event event) {
+
+        StringBuilder routingKey = new StringBuilder();
+
+        String eventSource = replaceNullWithWildcard(event.getEventSource());
+        eventSource = eventSource.replace(".", "-");
+
+        String eventCategory = replaceNullWithWildcard(event.getEventCategory());
+        eventCategory = eventCategory.replace(".", "-");
+
+        String eventType = replaceNullWithWildcard(event.getEventType());
+        eventType = eventType.replace(".", "-");
+
+        String resourceType = replaceNullWithWildcard(event.getResourceType());
+        resourceType = resourceType.replace(".", "-");
+
+        String resourceUuid = replaceNullWithWildcard(event.getResourceUUID());
+        resourceUuid = resourceUuid.replace(".", "-");
+
+        // routing key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
+        routingKey.append(eventSource);
+        routingKey.append(".");
+        routingKey.append(eventCategory);
+        routingKey.append(".");
+        routingKey.append(eventType);
+        routingKey.append(".");
+        routingKey.append(resourceType);
+        routingKey.append(".");
+        routingKey.append(resourceUuid);
+
+        return routingKey.toString();
+    }
+
+    /** creates a binding key from the event topic that subscriber specified
+     *  binding key will be used to bind the queue created for subscriber to exchange on AMQP server
+     */
+    private String createBindingKey(EventTopic topic) {
+
+        StringBuilder bindingKey = new StringBuilder();
+
+        String eventSource = replaceNullWithWildcard(topic.getEventSource());
+        eventSource = eventSource.replace(".", "-");
+
+        String eventCategory = replaceNullWithWildcard(topic.getEventCategory());
+        eventCategory = eventCategory.replace(".", "-");
+
+        String eventType = replaceNullWithWildcard(topic.getEventType());
+        eventType = eventType.replace(".", "-");
+
+        String resourceType = replaceNullWithWildcard(topic.getResourceType());
+        resourceType = resourceType.replace(".", "-");
+
+        String resourceUuid = replaceNullWithWildcard(topic.getResourceUUID());
+        resourceUuid = resourceUuid.replace(".", "-");
+
+        // binding key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
+        bindingKey.append(eventSource);
+        bindingKey.append(".");
+        bindingKey.append(eventCategory);
+        bindingKey.append(".");
+        bindingKey.append(eventType);
+        bindingKey.append(".");
+        bindingKey.append(resourceType);
+        bindingKey.append(".");
+        bindingKey.append(resourceUuid);
+
+        return bindingKey.toString();
+    }
+
+    private synchronized Connection getConnection() throws Exception {
+        if (s_connection == null) {
+            try {
+                return createConnection();
+            } catch (Exception e) {
+                s_logger.error("Failed to create a connection to AMQP server due to " + e.getMessage());
+                throw e;
+            }
+        } else {
+            return s_connection;
+        }
+    }
+
+    private synchronized Connection createConnection() throws Exception {
+        try {
+            ConnectionFactory factory = new ConnectionFactory();
+            factory.setUsername(username);
+            factory.setPassword(password);
+            factory.setHost(amqpHost);
+            factory.setPort(port);
+
+            if (virtualHost != null && !virtualHost.isEmpty()) {
+                factory.setVirtualHost(virtualHost);
+            } else {
+                factory.setVirtualHost("/");
+            }
+
+            if (useSsl != null && !useSsl.isEmpty() && useSsl.equalsIgnoreCase("true")) {
+                factory.useSslProtocol(secureProtocol);
+            }
+            Connection connection = factory.newConnection();
+            connection.addShutdownListener(disconnectHandler);
+            connection.addBlockedListener(blockedConnectionHandler);
+            s_connection = connection;
+            return s_connection;
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    private synchronized void closeConnection() {
+        try {
+            if (s_connection != null) {
+                s_connection.close();
+            }
+        } catch (Exception e) {
+            s_logger.warn("Failed to close connection to AMQP server due to " + e.getMessage());
+        }
+        s_connection = null;
+    }
+
+    private synchronized void abortConnection() {
+        if (s_connection == null)
+            return;
+
+        try {
+            s_connection.abort();
+        } catch (Exception e) {
+            s_logger.warn("Failed to abort connection due to " + e.getMessage());
+        }
+        s_connection = null;
+    }
+
+    private String replaceNullWithWildcard(String key) {
+        if (key == null || key.isEmpty()) {
+            return "*";
+        } else {
+            return key;
+        }
+    }
+
+    private Channel createChannel(Connection connection) throws Exception {
+        try {
+            return connection.createChannel();
+        } catch (java.io.IOException exception) {
+            s_logger.warn("Failed to create a channel due to " + exception.getMessage());
+            throw exception;
+        }
+    }
+
+    private void createExchange(Channel channel, String exchangeName) throws Exception {
+        try {
+            channel.exchangeDeclare(exchangeName, "topic", true);
+        } catch (java.io.IOException exception) {
+            s_logger.error("Failed to create exchange" + exchangeName + " on RabbitMQ server");
+            throw exception;
+        }
+    }
+
+    private void publishEventToExchange(Channel channel, String exchangeName, String routingKey, String eventDescription) throws Exception {
+        try {
+            byte[] messageBodyBytes = eventDescription.getBytes();
+            channel.basicPublish(exchangeName, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);
+        } catch (Exception e) {
+            s_logger.error("Failed to publish event " + routingKey + " on exchange " + exchangeName + "  of message broker due to " + e.getMessage());
+            throw e;
+        }
+    }
+
+    private String getEventCategoryFromRoutingKey(String routingKey) {
+        String[] keyParts = routingKey.split("\\.");
+        return keyParts[1];
+    }
+
+    private String getEventTypeFromRoutingKey(String routingKey) {
+        String[] keyParts = routingKey.split("\\.");
+        return keyParts[2];
+    }
+
+    private String getEventSourceFromRoutingKey(String routingKey) {
+        String[] keyParts = routingKey.split("\\.");
+        return keyParts[0];
+    }
+
+    private String getResourceTypeFromRoutingKey(String routingKey) {
+        String[] keyParts = routingKey.split("\\.");
+        return keyParts[3];
+    }
+
+    private String getResourceUUIDFromRoutingKey(String routingKey) {
+        String[] keyParts = routingKey.split("\\.");
+        return keyParts[4];
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        ReconnectionTask reconnect = new ReconnectionTask(); // initiate connection to AMQP server
+        executorService.submit(reconnect);
+        return true;
+    }
+
+    @Override
+    public synchronized boolean stop() {
+        if (s_connection.isOpen()) {
+            for (String subscriberId : s_subscribers.keySet()) {
+                Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
+                Channel channel = subscriberDetails.second();
+                String queueName = subscriberId;
+                try {
+                    channel.queueDelete(queueName);
+                    channel.abort();
+                } catch (IOException ioe) {
+                    s_logger.warn("Failed to delete queue: " + queueName + " on AMQP server due to " + ioe.getMessage());
+                }
+            }
+        }
+
+        closeConnection();
+        return true;
+    }
+
+    //logic to deal with blocked connection. connections are blocked for example when the rabbitmq server is out of space. https://www.rabbitmq.com/connection-blocked.html
+    private class BlockedConnectionHandler implements BlockedListener {
+
+        @Override
+        public void handleBlocked(String reason) throws IOException {
+            s_logger.error("rabbitmq connection is blocked with reason: " + reason);
+            closeConnection();
+            throw new CloudRuntimeException("unblocking the parent thread as publishing to rabbitmq server is blocked with reason: " + reason);
+        }
+
+        @Override
+        public void handleUnblocked() throws IOException {
+            s_logger.info("rabbitmq connection in unblocked");
+        }
+    }
+    // logic to deal with loss of connection to AMQP server
+    private class DisconnectHandler implements ShutdownListener {
+
+        @Override
+        public void shutdownCompleted(ShutdownSignalException shutdownSignalException) {
+            if (!shutdownSignalException.isInitiatedByApplication()) {
+
+                for (String subscriberId : s_subscribers.keySet()) {
+                    Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
+                    subscriberDetails.second(null);
+                    s_subscribers.put(subscriberId, subscriberDetails);
+                }
+
+                abortConnection(); // disconnected to AMQP server, so abort the connection and channels
+                s_logger.warn("Connection has been shutdown by AMQP server. Attempting to reconnect.");
+
+                // initiate re-connect process
+                ReconnectionTask reconnect = new ReconnectionTask();
+                executorService.submit(reconnect);
+            }
+        }
+    }
+
+    // retry logic to connect back to AMQP server after loss of connection
+    private class ReconnectionTask extends ManagedContextRunnable {
+
+        boolean connected = false;
+        Connection connection = null;
+
+        @Override
+        protected void runInContext() {
+
+            while (!connected) {
+                try {
+                    Thread.sleep(retryInterval);
+                } catch (InterruptedException ie) {
+                    // ignore timer interrupts
+                }
+
+                try {
+                    try {
+                        connection = createConnection();
+                        connected = true;
+                    } catch (IOException ie) {
+                        continue; // can't establish connection to AMQP server yet, so continue
+                    }
+
+                    // prepare consumer on AMQP server for each of subscriber
+                    for (String subscriberId : s_subscribers.keySet()) {
+                        Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
+                        String bindingKey = subscriberDetails.first();
+                        EventSubscriber subscriber = subscriberDetails.third();
+
+                        /** create a queue with subscriber ID as queue name and bind it to the exchange
+                         *  with binding key formed from event topic
+                         */
+                        Channel channel = createChannel(connection);
+                        createExchange(channel, amqpExchangeName);
+                        channel.queueDeclare(subscriberId, false, false, false, null);
+                        channel.queueBind(subscriberId, amqpExchangeName, bindingKey);
+
+                        // register a callback handler to receive the events that a subscriber subscribed to
+                        channel.basicConsume(subscriberId, s_autoAck, subscriberId, new DefaultConsumer(channel) {
+                            @Override
+                            public void handleDelivery(String queueName, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
+
+                                Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(queueName); // queue name == subscriber ID
+
+                                if (subscriberDetails != null) {
+                                    EventSubscriber subscriber = subscriberDetails.third();
+                                    String routingKey = envelope.getRoutingKey();
+                                    String eventSource = getEventSourceFromRoutingKey(routingKey);
+                                    String eventCategory = getEventCategoryFromRoutingKey(routingKey);
+                                    String eventType = getEventTypeFromRoutingKey(routingKey);
+                                    String resourceType = getResourceTypeFromRoutingKey(routingKey);
+                                    String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
+
+                                    // create event object from the message details obtained from AMQP server
+                                    Event event = new Event(eventSource, eventCategory, eventType, resourceType, resourceUUID);
+                                    event.setDescription(new String(body));
+
+                                    // deliver the event to call back object provided by subscriber
+                                    subscriber.onEvent(event);
+                                }
+                            }
+                        });
+
+                        // update the channel details for the subscription
+                        subscriberDetails.second(channel);
+                        s_subscribers.put(subscriberId, subscriberDetails);
+                    }
+                } catch (Exception e) {
+                    s_logger.warn("Failed to recreate queues and binding for the subscribers due to " + e.getMessage());
+                }
+            }
+            return;
+        }
+    }
+}
diff --git a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
deleted file mode 100644
index 0b0b083..0000000
--- a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.cloudstack.mom.rabbitmq;
-
-import java.io.IOException;
-import java.net.ConnectException;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.naming.ConfigurationException;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.rabbitmq.client.BlockedListener;
-import org.apache.log4j.Logger;
-
-import com.rabbitmq.client.AMQP;
-import com.rabbitmq.client.AlreadyClosedException;
-import com.rabbitmq.client.Channel;
-import com.rabbitmq.client.Connection;
-import com.rabbitmq.client.ConnectionFactory;
-import com.rabbitmq.client.DefaultConsumer;
-import com.rabbitmq.client.Envelope;
-import com.rabbitmq.client.MessageProperties;
-import com.rabbitmq.client.ShutdownListener;
-import com.rabbitmq.client.ShutdownSignalException;
-
-import org.apache.cloudstack.framework.events.Event;
-import org.apache.cloudstack.framework.events.EventBus;
-import org.apache.cloudstack.framework.events.EventBusException;
-import org.apache.cloudstack.framework.events.EventSubscriber;
-import org.apache.cloudstack.framework.events.EventTopic;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-
-public class RabbitMQEventBus extends ManagerBase implements EventBus {
-
-    // details of AMQP server
-    private static String amqpHost;
-    private static Integer port;
-    private static String username;
-    private static String password;
-    private static String secureProtocol = "TLSv1.2";
-
-    public synchronized static void setVirtualHost(String virtualHost) {
-        RabbitMQEventBus.virtualHost = virtualHost;
-    }
-
-    private static String virtualHost;
-
-    public static void setUseSsl(String useSsl) {
-        RabbitMQEventBus.useSsl = useSsl;
-    }
-
-    private static String useSsl;
-
-    // AMQP exchange name where all CloudStack events will be published
-    private static String amqpExchangeName;
-
-    private String name;
-
-    private static Integer retryInterval;
-
-    // hashmap to book keep the registered subscribers
-    private static ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>> s_subscribers;
-
-    // connection to AMQP server,
-    private static Connection s_connection = null;
-
-    // AMQP server should consider messages acknowledged once delivered if _autoAck is true
-    private static boolean s_autoAck = true;
-
-    private ExecutorService executorService;
-    private static DisconnectHandler disconnectHandler;
-    private static BlockedConnectionHandler blockedConnectionHandler;
-    private static final Logger s_logger = Logger.getLogger(RabbitMQEventBus.class);
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-
-        try {
-            if (amqpHost == null || amqpHost.isEmpty()) {
-                throw new ConfigurationException("Unable to get the AMQP server details");
-            }
-
-            if (username == null || username.isEmpty()) {
-                throw new ConfigurationException("Unable to get the username details");
-            }
-
-            if (password == null || password.isEmpty()) {
-                throw new ConfigurationException("Unable to get the password details");
-            }
-
-            if (amqpExchangeName == null || amqpExchangeName.isEmpty()) {
-                throw new ConfigurationException("Unable to get the _exchange details on the AMQP server");
-            }
-
-            if (port == null) {
-                throw new ConfigurationException("Unable to get the port details of AMQP server");
-            }
-
-            if (useSsl != null && !useSsl.isEmpty()) {
-                if (!useSsl.equalsIgnoreCase("true") && !useSsl.equalsIgnoreCase("false")) {
-                    throw new ConfigurationException("Invalid configuration parameter for 'ssl'.");
-                }
-            }
-
-            if (retryInterval == null) {
-                retryInterval = 10000;// default to 10s to try out reconnect
-            }
-
-        } catch (NumberFormatException e) {
-            throw new ConfigurationException("Invalid port number/retry interval");
-        }
-
-        s_subscribers = new ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>>();
-        executorService = Executors.newCachedThreadPool();
-        disconnectHandler = new DisconnectHandler();
-        blockedConnectionHandler = new BlockedConnectionHandler();
-
-        return true;
-    }
-
-    public static void setServer(String amqpHost) {
-        RabbitMQEventBus.amqpHost = amqpHost;
-    }
-
-    public static void setUsername(String username) {
-        RabbitMQEventBus.username = username;
-    }
-
-    public static void setPassword(String password) {
-        RabbitMQEventBus.password = password;
-    }
-
-    public static void setPort(Integer port) {
-        RabbitMQEventBus.port = port;
-    }
-
-    public static void setSecureProtocol(String protocol) {
-        RabbitMQEventBus.secureProtocol = protocol;
-    }
-
-    @Override
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public static void setExchange(String exchange) {
-        RabbitMQEventBus.amqpExchangeName = exchange;
-    }
-
-    public static void setRetryInterval(Integer retryInterval) {
-        RabbitMQEventBus.retryInterval = retryInterval;
-    }
-
-    /** Call to subscribe to interested set of events
-     *
-     * @param topic defines category and type of the events being subscribed to
-     * @param subscriber subscriber that intends to receive event notification
-     * @return UUID that represents the subscription with event bus
-     * @throws EventBusException
-     */
-    @Override
-    public UUID subscribe(EventTopic topic, EventSubscriber subscriber) throws EventBusException {
-
-        if (subscriber == null || topic == null) {
-            throw new EventBusException("Invalid EventSubscriber/EventTopic object passed.");
-        }
-
-        // create a UUID, that will be used for managing subscriptions and also used as queue name
-        // for on the queue used for the subscriber on the AMQP broker
-        UUID queueId = UUID.randomUUID();
-        String queueName = queueId.toString();
-
-        try {
-            String bindingKey = createBindingKey(topic);
-
-            // store the subscriber details before creating channel
-            s_subscribers.put(queueName, new Ternary(bindingKey, null, subscriber));
-
-            // create a channel dedicated for this subscription
-            Connection connection = getConnection();
-            Channel channel = createChannel(connection);
-
-            // create a queue and bind it to the exchange with binding key formed from event topic
-            createExchange(channel, amqpExchangeName);
-            channel.queueDeclare(queueName, false, false, false, null);
-            channel.queueBind(queueName, amqpExchangeName, bindingKey);
-
-            // register a callback handler to receive the events that a subscriber subscribed to
-            channel.basicConsume(queueName, s_autoAck, queueName, new DefaultConsumer(channel) {
-                @Override
-                public void handleDelivery(String queueName, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
-                    Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
-                    if (queueDetails != null) {
-                        EventSubscriber subscriber = queueDetails.third();
-                        String routingKey = envelope.getRoutingKey();
-                        String eventSource = getEventSourceFromRoutingKey(routingKey);
-                        String eventCategory = getEventCategoryFromRoutingKey(routingKey);
-                        String eventType = getEventTypeFromRoutingKey(routingKey);
-                        String resourceType = getResourceTypeFromRoutingKey(routingKey);
-                        String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
-                        Event event = new Event(eventSource, eventCategory, eventType, resourceType, resourceUUID);
-                        event.setDescription(new String(body));
-
-                        // deliver the event to call back object provided by subscriber
-                        subscriber.onEvent(event);
-                    }
-                }
-            });
-
-            // update the channel details for the subscription
-            Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
-            queueDetails.second(channel);
-            s_subscribers.put(queueName, queueDetails);
-
-        } catch (AlreadyClosedException closedException) {
-            s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + " will be active after reconnection");
-        } catch (ConnectException connectException) {
-            s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + " will be active after reconnection");
-        } catch (Exception e) {
-            throw new EventBusException("Failed to subscribe to event due to " + e.getMessage());
-        }
-
-        return queueId;
-    }
-
-    @Override
-    public void unsubscribe(UUID subscriberId, EventSubscriber subscriber) throws EventBusException {
-        try {
-            String classname = subscriber.getClass().getName();
-            String queueName = UUID.nameUUIDFromBytes(classname.getBytes()).toString();
-            Ternary<String, Channel, EventSubscriber> queueDetails = s_subscribers.get(queueName);
-            Channel channel = queueDetails.second();
-            channel.basicCancel(queueName);
-            s_subscribers.remove(queueName, queueDetails);
-        } catch (Exception e) {
-            throw new EventBusException("Failed to unsubscribe from event bus due to " + e.getMessage());
-        }
-    }
-
-    // publish event on to the exchange created on AMQP server
-    @Override
-    public void publish(Event event) throws EventBusException {
-
-        String routingKey = createRoutingKey(event);
-        String eventDescription = event.getDescription();
-
-        try {
-            Connection connection = getConnection();
-            Channel channel = createChannel(connection);
-            createExchange(channel, amqpExchangeName);
-            publishEventToExchange(channel, amqpExchangeName, routingKey, eventDescription);
-            channel.close();
-        } catch (AlreadyClosedException e) {
-            closeConnection();
-            throw new EventBusException("Failed to publish event to message broker as connection to AMQP broker in lost");
-        } catch (Exception e) {
-            throw new EventBusException("Failed to publish event to message broker due to " + e.getMessage());
-        }
-    }
-
-    /** creates a routing key from the event details.
-     *  created routing key will be used while publishing the message to exchange on AMQP server
-     */
-    private String createRoutingKey(Event event) {
-
-        StringBuilder routingKey = new StringBuilder();
-
-        String eventSource = replaceNullWithWildcard(event.getEventSource());
-        eventSource = eventSource.replace(".", "-");
-
-        String eventCategory = replaceNullWithWildcard(event.getEventCategory());
-        eventCategory = eventCategory.replace(".", "-");
-
-        String eventType = replaceNullWithWildcard(event.getEventType());
-        eventType = eventType.replace(".", "-");
-
-        String resourceType = replaceNullWithWildcard(event.getResourceType());
-        resourceType = resourceType.replace(".", "-");
-
-        String resourceUuid = replaceNullWithWildcard(event.getResourceUUID());
-        resourceUuid = resourceUuid.replace(".", "-");
-
-        // routing key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
-        routingKey.append(eventSource);
-        routingKey.append(".");
-        routingKey.append(eventCategory);
-        routingKey.append(".");
-        routingKey.append(eventType);
-        routingKey.append(".");
-        routingKey.append(resourceType);
-        routingKey.append(".");
-        routingKey.append(resourceUuid);
-
-        return routingKey.toString();
-    }
-
-    /** creates a binding key from the event topic that subscriber specified
-     *  binding key will be used to bind the queue created for subscriber to exchange on AMQP server
-     */
-    private String createBindingKey(EventTopic topic) {
-
-        StringBuilder bindingKey = new StringBuilder();
-
-        String eventSource = replaceNullWithWildcard(topic.getEventSource());
-        eventSource = eventSource.replace(".", "-");
-
-        String eventCategory = replaceNullWithWildcard(topic.getEventCategory());
-        eventCategory = eventCategory.replace(".", "-");
-
-        String eventType = replaceNullWithWildcard(topic.getEventType());
-        eventType = eventType.replace(".", "-");
-
-        String resourceType = replaceNullWithWildcard(topic.getResourceType());
-        resourceType = resourceType.replace(".", "-");
-
-        String resourceUuid = replaceNullWithWildcard(topic.getResourceUUID());
-        resourceUuid = resourceUuid.replace(".", "-");
-
-        // binding key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
-        bindingKey.append(eventSource);
-        bindingKey.append(".");
-        bindingKey.append(eventCategory);
-        bindingKey.append(".");
-        bindingKey.append(eventType);
-        bindingKey.append(".");
-        bindingKey.append(resourceType);
-        bindingKey.append(".");
-        bindingKey.append(resourceUuid);
-
-        return bindingKey.toString();
-    }
-
-    private synchronized Connection getConnection() throws Exception {
-        if (s_connection == null) {
-            try {
-                return createConnection();
-            } catch (Exception e) {
-                s_logger.error("Failed to create a connection to AMQP server due to " + e.getMessage());
-                throw e;
-            }
-        } else {
-            return s_connection;
-        }
-    }
-
-    private synchronized Connection createConnection() throws Exception {
-        try {
-            ConnectionFactory factory = new ConnectionFactory();
-            factory.setUsername(username);
-            factory.setPassword(password);
-            factory.setHost(amqpHost);
-            factory.setPort(port);
-
-            if (virtualHost != null && !virtualHost.isEmpty()) {
-                factory.setVirtualHost(virtualHost);
-            } else {
-                factory.setVirtualHost("/");
-            }
-
-            if (useSsl != null && !useSsl.isEmpty() && useSsl.equalsIgnoreCase("true")) {
-                factory.useSslProtocol(secureProtocol);
-            }
-            Connection connection = factory.newConnection();
-            connection.addShutdownListener(disconnectHandler);
-            connection.addBlockedListener(blockedConnectionHandler);
-            s_connection = connection;
-            return s_connection;
-        } catch (Exception e) {
-            throw e;
-        }
-    }
-
-    private synchronized void closeConnection() {
-        try {
-            if (s_connection != null) {
-                s_connection.close();
-            }
-        } catch (Exception e) {
-            s_logger.warn("Failed to close connection to AMQP server due to " + e.getMessage());
-        }
-        s_connection = null;
-    }
-
-    private synchronized void abortConnection() {
-        if (s_connection == null)
-            return;
-
-        try {
-            s_connection.abort();
-        } catch (Exception e) {
-            s_logger.warn("Failed to abort connection due to " + e.getMessage());
-        }
-        s_connection = null;
-    }
-
-    private String replaceNullWithWildcard(String key) {
-        if (key == null || key.isEmpty()) {
-            return "*";
-        } else {
-            return key;
-        }
-    }
-
-    private Channel createChannel(Connection connection) throws Exception {
-        try {
-            return connection.createChannel();
-        } catch (java.io.IOException exception) {
-            s_logger.warn("Failed to create a channel due to " + exception.getMessage());
-            throw exception;
-        }
-    }
-
-    private void createExchange(Channel channel, String exchangeName) throws Exception {
-        try {
-            channel.exchangeDeclare(exchangeName, "topic", true);
-        } catch (java.io.IOException exception) {
-            s_logger.error("Failed to create exchange" + exchangeName + " on RabbitMQ server");
-            throw exception;
-        }
-    }
-
-    private void publishEventToExchange(Channel channel, String exchangeName, String routingKey, String eventDescription) throws Exception {
-        try {
-            byte[] messageBodyBytes = eventDescription.getBytes();
-            channel.basicPublish(exchangeName, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);
-        } catch (Exception e) {
-            s_logger.error("Failed to publish event " + routingKey + " on exchange " + exchangeName + "  of message broker due to " + e.getMessage());
-            throw e;
-        }
-    }
-
-    private String getEventCategoryFromRoutingKey(String routingKey) {
-        String[] keyParts = routingKey.split("\\.");
-        return keyParts[1];
-    }
-
-    private String getEventTypeFromRoutingKey(String routingKey) {
-        String[] keyParts = routingKey.split("\\.");
-        return keyParts[2];
-    }
-
-    private String getEventSourceFromRoutingKey(String routingKey) {
-        String[] keyParts = routingKey.split("\\.");
-        return keyParts[0];
-    }
-
-    private String getResourceTypeFromRoutingKey(String routingKey) {
-        String[] keyParts = routingKey.split("\\.");
-        return keyParts[3];
-    }
-
-    private String getResourceUUIDFromRoutingKey(String routingKey) {
-        String[] keyParts = routingKey.split("\\.");
-        return keyParts[4];
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        ReconnectionTask reconnect = new ReconnectionTask(); // initiate connection to AMQP server
-        executorService.submit(reconnect);
-        return true;
-    }
-
-    @Override
-    public synchronized boolean stop() {
-        if (s_connection.isOpen()) {
-            for (String subscriberId : s_subscribers.keySet()) {
-                Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
-                Channel channel = subscriberDetails.second();
-                String queueName = subscriberId;
-                try {
-                    channel.queueDelete(queueName);
-                    channel.abort();
-                } catch (IOException ioe) {
-                    s_logger.warn("Failed to delete queue: " + queueName + " on AMQP server due to " + ioe.getMessage());
-                }
-            }
-        }
-
-        closeConnection();
-        return true;
-    }
-
-    //logic to deal with blocked connection. connections are blocked for example when the rabbitmq server is out of space. https://www.rabbitmq.com/connection-blocked.html
-    private class BlockedConnectionHandler implements BlockedListener {
-
-        @Override
-        public void handleBlocked(String reason) throws IOException {
-            s_logger.error("rabbitmq connection is blocked with reason: " + reason);
-            closeConnection();
-            throw new CloudRuntimeException("unblocking the parent thread as publishing to rabbitmq server is blocked with reason: " + reason);
-        }
-
-        @Override
-        public void handleUnblocked() throws IOException {
-            s_logger.info("rabbitmq connection in unblocked");
-        }
-    }
-    // logic to deal with loss of connection to AMQP server
-    private class DisconnectHandler implements ShutdownListener {
-
-        @Override
-        public void shutdownCompleted(ShutdownSignalException shutdownSignalException) {
-            if (!shutdownSignalException.isInitiatedByApplication()) {
-
-                for (String subscriberId : s_subscribers.keySet()) {
-                    Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
-                    subscriberDetails.second(null);
-                    s_subscribers.put(subscriberId, subscriberDetails);
-                }
-
-                abortConnection(); // disconnected to AMQP server, so abort the connection and channels
-                s_logger.warn("Connection has been shutdown by AMQP server. Attempting to reconnect.");
-
-                // initiate re-connect process
-                ReconnectionTask reconnect = new ReconnectionTask();
-                executorService.submit(reconnect);
-            }
-        }
-    }
-
-    // retry logic to connect back to AMQP server after loss of connection
-    private class ReconnectionTask extends ManagedContextRunnable {
-
-        boolean connected = false;
-        Connection connection = null;
-
-        @Override
-        protected void runInContext() {
-
-            while (!connected) {
-                try {
-                    Thread.sleep(retryInterval);
-                } catch (InterruptedException ie) {
-                    // ignore timer interrupts
-                }
-
-                try {
-                    try {
-                        connection = createConnection();
-                        connected = true;
-                    } catch (IOException ie) {
-                        continue; // can't establish connection to AMQP server yet, so continue
-                    }
-
-                    // prepare consumer on AMQP server for each of subscriber
-                    for (String subscriberId : s_subscribers.keySet()) {
-                        Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
-                        String bindingKey = subscriberDetails.first();
-                        EventSubscriber subscriber = subscriberDetails.third();
-
-                        /** create a queue with subscriber ID as queue name and bind it to the exchange
-                         *  with binding key formed from event topic
-                         */
-                        Channel channel = createChannel(connection);
-                        createExchange(channel, amqpExchangeName);
-                        channel.queueDeclare(subscriberId, false, false, false, null);
-                        channel.queueBind(subscriberId, amqpExchangeName, bindingKey);
-
-                        // register a callback handler to receive the events that a subscriber subscribed to
-                        channel.basicConsume(subscriberId, s_autoAck, subscriberId, new DefaultConsumer(channel) {
-                            @Override
-                            public void handleDelivery(String queueName, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
-
-                                Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(queueName); // queue name == subscriber ID
-
-                                if (subscriberDetails != null) {
-                                    EventSubscriber subscriber = subscriberDetails.third();
-                                    String routingKey = envelope.getRoutingKey();
-                                    String eventSource = getEventSourceFromRoutingKey(routingKey);
-                                    String eventCategory = getEventCategoryFromRoutingKey(routingKey);
-                                    String eventType = getEventTypeFromRoutingKey(routingKey);
-                                    String resourceType = getResourceTypeFromRoutingKey(routingKey);
-                                    String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
-
-                                    // create event object from the message details obtained from AMQP server
-                                    Event event = new Event(eventSource, eventCategory, eventType, resourceType, resourceUUID);
-                                    event.setDescription(new String(body));
-
-                                    // deliver the event to call back object provided by subscriber
-                                    subscriber.onEvent(event);
-                                }
-                            }
-                        });
-
-                        // update the channel details for the subscription
-                        subscriberDetails.second(channel);
-                        s_subscribers.put(subscriberId, subscriberDetails);
-                    }
-                } catch (Exception e) {
-                    s_logger.warn("Failed to recreate queues and binding for the subscribers due to " + e.getMessage());
-                }
-            }
-            return;
-        }
-    }
-}
diff --git a/plugins/file-systems/netapp/pom.xml b/plugins/file-systems/netapp/pom.xml
deleted file mode 100644
index 13f8c66..0000000
--- a/plugins/file-systems/netapp/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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-netapp</artifactId>
-  <name>Apache CloudStack Plugin - NetApp File System</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>com.cloud.com.netapp</groupId>
-      <artifactId>manageontap</artifactId>
-      <version>4.0</version>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
deleted file mode 100644
index dadfe44..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/AssociateLunCmd.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.AssociateLunCmdResponse;
-
-@APICommand(name = "associateLun", description = "Associate a LUN with a guest IQN", responseObject = AssociateLunCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class AssociateLunCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(AssociateLunCmd.class.getName());
-    private static final String s_name = "associatelunresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "LUN name.")
-    private String lunName;
-
-    @Parameter(name = ApiConstants.IQN, type = CommandType.STRING, required = true, description = "Guest IQN to which the LUN associate.")
-    private String guestIqn;
-
-    ///////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getLunName() {
-        return lunName;
-    }
-
-    public String getGuestIQN() {
-        return guestIqn;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() {
-
-        try {
-            AssociateLunCmdResponse response = new AssociateLunCmdResponse();
-            String returnVals[] = null;
-            returnVals = netappMgr.associateLun(getGuestIQN(), getLunName());
-            response.setLun(returnVals[0]);
-            response.setIpAddress(returnVals[2]);
-            response.setTargetIQN(returnVals[1]);
-            response.setObjectName("lun");
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
deleted file mode 100644
index 6700479..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateLunCmd.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.CreateLunCmdResponse;
-
-@APICommand(name = "createLunOnFiler", description = "Create a LUN from a pool", responseObject = CreateLunCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateLunCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateLunCmd.class.getName());
-    private static final String s_name = "createlunresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = true, description = "LUN size.")
-    private long size;
-
-    public String getPoolName() {
-        return poolName;
-    }
-
-    public long getLunSize() {
-        return size;
-    }
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-
-        try {
-            CreateLunCmdResponse response = new CreateLunCmdResponse();
-            String returnVals[] = null;
-            returnVals = netappMgr.createLunOnFiler(getPoolName(), getLunSize());
-            response.setPath(returnVals[0]);
-            response.setIqn(returnVals[1]);
-            response.setIpAddress(returnVals[2]);
-            response.setObjectName("lun");
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
deleted file mode 100644
index b1e6a29..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumeOnFilerCmd.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.net.UnknownHostException;
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.CreateVolumeOnFilerCmdResponse;
-
-@APICommand(name = "createVolumeOnFiler", description = "Create a volume", responseObject = CreateVolumeOnFilerCmdResponse.class,
-        requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
-public class CreateVolumeOnFilerCmd extends BaseCmd {
-    private static final String s_name = "createvolumeresponse";
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true, description = "ip address.")
-    private String ipAddress;
-
-    @Parameter(name = ApiConstants.AGGREGATE_NAME, type = CommandType.STRING, required = true, description = "aggregate name.")
-    private String aggrName;
-
-    @Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Parameter(name = ApiConstants.VOLUME_NAME, type = CommandType.STRING, required = true, description = "volume name.")
-    private String volName;
-
-    @Parameter(name = ApiConstants.SIZE, type = CommandType.INTEGER, required = true, description = "volume size.")
-    private Integer volSize;
-
-    @Parameter(name = ApiConstants.SNAPSHOT_POLICY, type = CommandType.STRING, required = false, description = "snapshot policy.")
-    private String snapshotPolicy;
-
-    @Parameter(name = ApiConstants.SNAPSHOT_RESERVATION, type = CommandType.INTEGER, required = false, description = "snapshot reservation.")
-    private Integer snapshotReservation;
-
-    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "user name.")
-    private String userName;
-
-    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "password.")
-    private String password;
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public String getAggrName() {
-        return aggrName;
-    }
-
-    public String getPoolName() {
-        return poolName;
-    }
-
-    public String volName() {
-        return volName;
-    }
-
-    public Integer getVolSize() {
-        return volSize;
-    }
-
-    public String getSnapshotPolicy() {
-        return snapshotPolicy;
-    }
-
-    public Integer getSnapshotReservation() {
-        return snapshotReservation;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        //param checks
-        if (snapshotReservation != null && (snapshotReservation < 0 || snapshotReservation > 100))
-            throw new InvalidParameterValueException("Invalid snapshot reservation");
-
-        StringBuilder s = new StringBuilder(getVolSize().toString());
-        s.append("g");
-
-        try {
-            netappMgr.createVolumeOnFiler(ipAddress, aggrName, poolName, volName, s.toString(), snapshotPolicy, snapshotReservation, userName, password);
-            CreateVolumeOnFilerCmdResponse response = new CreateVolumeOnFilerCmdResponse();
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (UnknownHostException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
deleted file mode 100644
index d2eeb87..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/CreateVolumePoolCmd.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.CreateVolumePoolCmdResponse;
-
-@APICommand(name = "createPool", description = "Create a pool", responseObject = CreateVolumePoolCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateVolumePoolCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateVolumePoolCmd.class.getName());
-    private static final String s_name = "createpoolresponse";
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-    @Parameter(name = ApiConstants.ALGORITHM, type = CommandType.STRING, required = true, description = "algorithm.")
-    private String algorithm;
-
-    public String getPoolName() {
-        return poolName;
-    }
-
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-
-        try {
-            CreateVolumePoolCmdResponse response = new CreateVolumePoolCmdResponse();
-            netappMgr.createPool(getPoolName(), getAlgorithm());
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
deleted file mode 100644
index 6f51cc6..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DeleteVolumePoolCmd.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.DeleteVolumePoolCmdResponse;
-
-@APICommand(name = "deletePool", description = "Delete a pool", responseObject = DeleteVolumePoolCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DeleteVolumePoolCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteVolumePoolCmd.class.getName());
-    private static final String s_name = "deletepoolresponse";
-
-    @Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            netappMgr.deletePool(poolName);
-            DeleteVolumePoolCmdResponse response = new DeleteVolumePoolCmdResponse();
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (ResourceInUseException e) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
deleted file mode 100644
index cfdc1da..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyLunCmd.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.DeleteLUNCmdResponse;
-
-@APICommand(name = "destroyLunOnFiler", description = "Destroy a LUN", responseObject = DeleteLUNCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DestroyLunCmd extends BaseCmd {
-
-    public static final Logger s_logger = Logger.getLogger(DestroyLunCmd.class.getName());
-    private static final String s_name = "destroylunresponse";
-
-    @Parameter(name = ApiConstants.PATH, type = CommandType.STRING, required = true, description = "LUN path.")
-    private String path;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            netappMgr.destroyLunOnFiler(path);
-            DeleteLUNCmdResponse response = new DeleteLUNCmdResponse();
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
deleted file mode 100644
index 500a84c..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DestroyVolumeOnFilerCmd.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.DeleteVolumeOnFilerCmdResponse;
-
-@APICommand(name = "destroyVolumeOnFiler", description = "Destroy a Volume", responseObject = DeleteVolumeOnFilerCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DestroyVolumeOnFilerCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(DestroyVolumeOnFilerCmd.class.getName());
-    private static final String s_name = "destroyvolumeresponse";
-
-    @Parameter(name = ApiConstants.AGGREGATE_NAME, type = CommandType.STRING, required = true, description = "aggregate name.")
-    private String aggrName;
-
-    @Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true, description = "ip address.")
-    private String ipAddr;
-
-    @Parameter(name = ApiConstants.VOLUME_NAME, type = CommandType.STRING, required = true, description = "volume name.")
-    private String volumeName;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            netappMgr.destroyVolumeOnFiler(ipAddr, aggrName, volumeName);
-            DeleteVolumeOnFilerCmdResponse response = new DeleteVolumeOnFilerCmdResponse();
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (ResourceInUseException e) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
\ No newline at end of file
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
deleted file mode 100644
index d5c53a1..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/DissociateLunCmd.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.rmi.ServerException;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.DissociateLunCmdResponse;
-
-@APICommand(name = "dissociateLun", description = "Dissociate a LUN", responseObject = DissociateLunCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class DissociateLunCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(DissociateLunCmd.class.getName());
-    private static final String s_name = "dissociatelunresponse";
-
-    @Parameter(name = ApiConstants.PATH, type = CommandType.STRING, required = true, description = "LUN path.")
-    private String path;
-
-    @Parameter(name = ApiConstants.IQN, type = CommandType.STRING, required = true, description = "Guest IQN.")
-    private String guestIQN;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            netappMgr.disassociateLun(guestIQN, path);
-            DissociateLunCmdResponse response = new DissociateLunCmdResponse();
-            response.setResponseName(getCommandName());
-            this.setResponseObject(response);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        } catch (ServerException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
deleted file mode 100644
index c1e1fb8..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListLunsCmd.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ListResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.LunVO;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.ListLunsCmdResponse;
-
-@APICommand(name = "listLunsOnFiler", description = "List LUN", responseObject = ListLunsCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListLunsCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(ListLunsCmd.class.getName());
-    private static final String s_name = "listlunresponse";
-
-    @Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            List<LunVO> lunList = netappMgr.listLunsOnFiler(poolName);
-            ListResponse<ListLunsCmdResponse> listResponse = new ListResponse<ListLunsCmdResponse>();
-            List<ListLunsCmdResponse> responses = new ArrayList<ListLunsCmdResponse>();
-            for (LunVO lun : lunList) {
-                ListLunsCmdResponse response = new ListLunsCmdResponse();
-                response.setId(lun.getId());
-                response.setIqn(lun.getTargetIqn());
-                response.setName(lun.getLunName());
-                response.setVolumeId(lun.getVolumeId());
-                response.setObjectName("lun");
-                responses.add(response);
-            }
-            listResponse.setResponses(responses);
-            listResponse.setResponseName(getCommandName());
-            this.setResponseObject(listResponse);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
deleted file mode 100644
index f6d17c0..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumePoolsCmd.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ListResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.netapp.PoolVO;
-import com.cloud.server.api.response.netapp.ListVolumePoolsCmdResponse;
-
-@APICommand(name = "listPools", description = "List Pool", responseObject = ListVolumePoolsCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListVolumePoolsCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(ListVolumePoolsCmd.class.getName());
-    private static final String s_name = "listpoolresponse";
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            List<PoolVO> poolList = netappMgr.listPools();
-            ListResponse<ListVolumePoolsCmdResponse> listResponse = new ListResponse<ListVolumePoolsCmdResponse>();
-            List<ListVolumePoolsCmdResponse> responses = new ArrayList<ListVolumePoolsCmdResponse>();
-            for (PoolVO pool : poolList) {
-                ListVolumePoolsCmdResponse response = new ListVolumePoolsCmdResponse();
-                response.setId(pool.getId());
-                response.setName(pool.getName());
-                response.setAlgorithm(pool.getAlgorithm());
-                response.setObjectName("pool");
-                responses.add(response);
-            }
-            listResponse.setResponses(responses);
-            listResponse.setResponseName(getCommandName());
-            this.setResponseObject(listResponse);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
deleted file mode 100644
index bf72b3a..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ListVolumesOnFilerCmd.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ListResponse;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.netapp.NetappVolumeVO;
-import com.cloud.server.api.response.netapp.ListVolumesOnFilerCmdResponse;
-
-@APICommand(name = "listVolumesOnFiler", description = "List Volumes", responseObject = ListVolumesOnFilerCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListVolumesOnFilerCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(ListVolumesOnFilerCmd.class.getName());
-    private static final String s_name = "listvolumesresponse";
-
-    @Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        try {
-            List<NetappVolumeVO> volumes = netappMgr.listVolumesOnFiler(poolName);
-            ListResponse<ListVolumesOnFilerCmdResponse> listResponse = new ListResponse<ListVolumesOnFilerCmdResponse>();
-            List<ListVolumesOnFilerCmdResponse> responses = new ArrayList<ListVolumesOnFilerCmdResponse>();
-            for (NetappVolumeVO volume : volumes) {
-                ListVolumesOnFilerCmdResponse response = new ListVolumesOnFilerCmdResponse();
-                response.setId(volume.getId());
-                response.setIpAddress(volume.getIpAddress());
-                response.setPoolName(volume.getPoolName());
-                response.setAggrName(volume.getAggregateName());
-                response.setVolumeName(volume.getVolumeName());
-                response.setSnapshotPolicy(volume.getSnapshotPolicy());
-                response.setSnapshotReservation(volume.getSnapshotReservation());
-                response.setVolumeSize(volume.getVolumeSize());
-                response.setObjectName("volume");
-                responses.add(response);
-            }
-            listResponse.setResponses(responses);
-            listResponse.setResponseName(getCommandName());
-            this.setResponseObject(listResponse);
-        } catch (InvalidParameterValueException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
\ No newline at end of file
diff --git a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java b/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
deleted file mode 100644
index a5849df..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/api/commands/netapp/ModifyVolumePoolCmd.java
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.commands.netapp;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.netapp.NetappManager;
-import com.cloud.server.api.response.netapp.ModifyVolumePoolCmdResponse;
-
-@APICommand(name = "modifyPool", description = "Modify pool", responseObject = ModifyVolumePoolCmdResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ModifyVolumePoolCmd extends BaseCmd {
-    public static final Logger s_logger = Logger.getLogger(ModifyVolumePoolCmd.class.getName());
-    private static final String s_name = "modifypoolresponse";
-
-    @Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
-    private String poolName;
-
-    @Parameter(name = ApiConstants.ALGORITHM, type = CommandType.STRING, required = true, description = "algorithm.")
-    private String algorithm;
-
-    @Inject
-    NetappManager netappMgr;
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException {
-        netappMgr.modifyPool(poolName, algorithm);
-
-        ModifyVolumePoolCmdResponse response = new ModifyVolumePoolCmdResponse();
-        response.setResponseName(getCommandName());
-        this.setResponseObject(response);
-    }
-
-    @Override
-    public String getCommandName() {
-        // TODO Auto-generated method stub
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/LunVO.java b/plugins/file-systems/netapp/src/com/cloud/netapp/LunVO.java
deleted file mode 100644
index 8c9a802..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/LunVO.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.api.InternalIdentity;
-
-@Entity
-@Table(name = "netapp_lun")
-public class LunVO implements InternalIdentity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "lun_name")
-    private String lunName;
-
-    @Column(name = "target_iqn")
-    private String targetIqn;
-
-    @Column(name = "path")
-    private String path;
-
-    @Column(name = "volume_id")
-    private Long volumeId;
-
-    public Long getSize() {
-        return size;
-    }
-
-    public void setSize(Long size) {
-        this.size = size;
-    }
-
-    @Column(name = "size")
-    private Long size;
-
-    public LunVO() {
-
-    }
-
-    public LunVO(String path, Long volumeId, Long size, String lunName, String targetIqn) {
-        this.path = path;
-        this.volumeId = volumeId;
-        this.size = size;
-        this.lunName = lunName;
-        this.targetIqn = targetIqn;
-    }
-
-    public String getLunName() {
-        return lunName;
-    }
-
-    public void setLunName(String lunName) {
-        this.lunName = lunName;
-    }
-
-    public LunVO(Long id, String path, Long volumeId, Long size, String lunName, String targetIqn) {
-        this.id = id;
-        this.path = path;
-        this.volumeId = volumeId;
-        this.size = size;
-        this.lunName = lunName;
-        this.targetIqn = targetIqn;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public void setVolumeId(Long volumeId) {
-        this.volumeId = volumeId;
-    }
-
-    public void setTargetIqn(String iqn) {
-        this.targetIqn = iqn;
-    }
-
-    public String getTargetIqn() {
-        return targetIqn;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappAllocator.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappAllocator.java
deleted file mode 100644
index 316f008..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappAllocator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-public interface NetappAllocator {
-
-    public NetappVolumeVO chooseVolumeFromPool(String poolName, long lunSizeGb);
-
-    public NetappVolumeVO chooseLeastFullVolumeFromPool(String poolName, long lunSizeGb);
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappDefaultAllocatorImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappDefaultAllocatorImpl.java
deleted file mode 100644
index 0141825..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappDefaultAllocatorImpl.java
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import java.rmi.ServerException;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-public class NetappDefaultAllocatorImpl implements NetappAllocator {
-    private static HashMap<String, Integer> s_poolNameToLastVolumeIdAllocated = new HashMap<String, Integer>();
-    private final NetappManager _netappMgr;
-    public static final Logger s_logger = Logger.getLogger(NetappDefaultAllocatorImpl.class.getName());
-
-    public NetappDefaultAllocatorImpl(NetappManager netappMgr) {
-        _netappMgr = netappMgr;
-    }
-
-    @Override
-    public synchronized NetappVolumeVO chooseLeastFullVolumeFromPool(String poolName, long lunSizeGb) {
-        List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName);
-
-        if (volumesOnPoolAscending == null) {
-            //no pools exist in db
-            return null;
-        }
-
-        long maxAvailable = 0;
-        NetappVolumeVO selectedVol = null;
-        for (NetappVolumeVO vol : volumesOnPoolAscending) {
-            try {
-                long availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress());
-
-                if (lunSizeGb <= bytesToGb(availableBytes) && availableBytes > maxAvailable) {
-                    maxAvailable = availableBytes; //new max
-                    selectedVol = vol; //new least loaded vol
-                }
-            } catch (ServerException se) {
-                s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName());
-                continue;
-            }
-        }
-
-        return selectedVol;
-    }
-
-    /**
-     * This method does the actual round robin allocation
-     * @param poolName
-     * @param lunSizeGb
-     * @return -- the selected volume to create the lun on
-     */
-    @Override
-    public synchronized NetappVolumeVO chooseVolumeFromPool(String poolName, long lunSizeGb) {
-        int pos = 0; //0 by default
-        List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName);
-
-        if (volumesOnPoolAscending == null) {
-            //no pools exist in db
-            return null;
-        }
-
-        //get the index of the record from the map
-        if (s_poolNameToLastVolumeIdAllocated.get(poolName) == null) {
-            pos = 0;
-        } else {
-            pos = s_poolNameToLastVolumeIdAllocated.get(poolName);
-        }
-
-        //update for RR effect
-        s_poolNameToLastVolumeIdAllocated.put(poolName, (pos + 1) % volumesOnPoolAscending.size());
-
-        //now iterate over the records
-        Object[] volumesOnPoolAscendingArray = volumesOnPoolAscending.toArray();
-        int counter = 0;
-        while (counter < volumesOnPoolAscendingArray.length) {
-            NetappVolumeVO vol = (NetappVolumeVO)volumesOnPoolAscendingArray[pos];
-
-            //check if the volume fits the bill
-            long availableBytes;
-            try {
-                availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress());
-
-                if (lunSizeGb <= bytesToGb(availableBytes)) {
-                    //found one
-                    return vol;
-                }
-                pos = (pos + 1) % volumesOnPoolAscendingArray.length;
-                counter++;
-            } catch (ServerException e) {
-                s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName());
-                continue;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * This method does the byte to gb conversion
-     * @param bytes
-     * @return -- converted gb
-     */
-    private long bytesToGb(long bytes) {
-        long returnVal = (bytes / (1024 * 1024 * 1024));
-        return returnVal;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java
deleted file mode 100644
index 97c7dd5..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManager.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import java.net.UnknownHostException;
-import java.rmi.ServerException;
-import java.util.List;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.PluggableService;
-
-public interface NetappManager extends Manager, PluggableService {
-    enum AlgorithmType {
-        RoundRobin, LeastFull
-    }
-
-    void destroyVolumeOnFiler(String ipAddress, String aggrName, String volName) throws ServerException, InvalidParameterValueException, ResourceInUseException;
-
-    void createVolumeOnFiler(String ipAddress, String aggName, String poolName, String volName, String volSize, String snapshotPolicy, Integer snapshotReservation,
-        String username, String password) throws UnknownHostException, ServerException, InvalidParameterValueException;
-
-    public String[] associateLun(String guestIqn, String path) throws ServerException, InvalidParameterValueException;
-
-    void disassociateLun(String iGroup, String path) throws ServerException, InvalidParameterValueException;
-
-    List<LunVO> listLunsOnFiler(String poolName);
-
-    void destroyLunOnFiler(String path) throws ServerException, InvalidParameterValueException;
-
-    List<NetappVolumeVO> listVolumesOnFiler(String poolName);
-
-    List<NetappVolumeVO> listVolumesAscending(String poolName);
-
-    long returnAvailableVolumeSize(String volName, String userName, String password, String serverIp) throws ServerException;
-
-    void createPool(String poolName, String algorithm) throws InvalidParameterValueException;
-
-    void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException;
-
-    void deletePool(String poolName) throws InvalidParameterValueException, ResourceInUseException;
-
-    List<PoolVO> listPools();
-
-    public String[] createLunOnFiler(String poolName, Long lunSize) throws InvalidParameterValueException, ServerException, ResourceAllocationException;
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
deleted file mode 100644
index c226ffe..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappManagerImpl.java
+++ /dev/null
@@ -1,1013 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-import java.rmi.ServerException;
-import java.util.ArrayList;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import netapp.manage.NaAPIFailedException;
-import netapp.manage.NaElement;
-import netapp.manage.NaException;
-import netapp.manage.NaServer;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.api.commands.netapp.AssociateLunCmd;
-import com.cloud.api.commands.netapp.CreateLunCmd;
-import com.cloud.api.commands.netapp.CreateVolumeOnFilerCmd;
-import com.cloud.api.commands.netapp.CreateVolumePoolCmd;
-import com.cloud.api.commands.netapp.DeleteVolumePoolCmd;
-import com.cloud.api.commands.netapp.DestroyLunCmd;
-import com.cloud.api.commands.netapp.DestroyVolumeOnFilerCmd;
-import com.cloud.api.commands.netapp.DissociateLunCmd;
-import com.cloud.api.commands.netapp.ListLunsCmd;
-import com.cloud.api.commands.netapp.ListVolumePoolsCmd;
-import com.cloud.api.commands.netapp.ListVolumesOnFilerCmd;
-import com.cloud.api.commands.netapp.ModifyVolumePoolCmd;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.netapp.dao.LunDao;
-import com.cloud.netapp.dao.PoolDao;
-import com.cloud.netapp.dao.VolumeDao;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class NetappManagerImpl extends ManagerBase implements NetappManager {
-    public enum Algorithm {
-        roundrobin, leastfull
-    }
-
-    public static final Logger s_logger = Logger.getLogger(NetappManagerImpl.class.getName());
-    @Inject
-    public VolumeDao _volumeDao;
-    @Inject
-    public PoolDao _poolDao;
-    @Inject
-    public LunDao _lunDao;
-    private NetappAllocator _netappAllocator = null;
-
-    /**
-     * Default constructor
-     */
-    public NetappManagerImpl() {
-    }
-
-    @Override
-    public void createPool(String poolName, String algorithm) throws InvalidParameterValueException {
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Request --> createPool ");
-
-        PoolVO pool = null;
-        validAlgorithm(algorithm);
-        try {
-            pool = new PoolVO(poolName, algorithm);
-            _poolDao.persist(pool);
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Response --> createPool:success");
-
-        } catch (CloudRuntimeException cre) {
-            pool = _poolDao.findPool(poolName);
-            if (pool != null) {
-                throw new InvalidParameterValueException("Duplicate Pool Name");
-            } else {
-                throw cre;
-            }
-        }
-    }
-
-    /**
-     * This method validates the algorithm used for allocation of the volume
-     * @param algorithm -- algorithm type
-     * @throws InvalidParameterValueException
-     */
-    private void validAlgorithm(String algorithm) throws InvalidParameterValueException {
-        //TODO: use enum
-        if (!algorithm.equalsIgnoreCase("roundrobin") && !algorithm.equalsIgnoreCase("leastfull")) {
-            throw new InvalidParameterValueException("Unknown algorithm " + algorithm);
-        }
-    }
-
-    /**
-     * Utility method to get the netapp server object
-     * @param serverIp -- ip address of netapp box
-     * @param userName -- username
-     * @param password -- password
-     * @return
-     * @throws UnknownHostException
-     */
-    private NaServer getServer(String serverIp, String userName, String password) throws UnknownHostException {
-        //Initialize connection to server, and
-        //request version 1.3 of the API set
-        NaServer s = new NaServer(serverIp, 1, 3);
-        s.setStyle(NaServer.STYLE_LOGIN_PASSWORD);
-        s.setAdminUser(userName, password);
-
-        return s;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(CreateLunCmd.class);
-        cmdList.add(ListLunsCmd.class);
-        cmdList.add(DissociateLunCmd.class);
-        cmdList.add(CreateVolumeOnFilerCmd.class);
-        cmdList.add(ModifyVolumePoolCmd.class);
-        cmdList.add(ListVolumesOnFilerCmd.class);
-        cmdList.add(ListVolumePoolsCmd.class);
-        cmdList.add(DestroyLunCmd.class);
-        cmdList.add(CreateVolumePoolCmd.class);
-        cmdList.add(DeleteVolumePoolCmd.class);
-        cmdList.add(AssociateLunCmd.class);
-        cmdList.add(DestroyVolumeOnFilerCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException {
-        validAlgorithm(algorithm);
-        PoolVO pool = _poolDao.findPool(poolName);
-
-        if (pool == null) {
-            throw new InvalidParameterValueException("Cannot find pool " + poolName);
-        }
-
-        validAlgorithm(algorithm);
-
-        pool.setAlgorithm(algorithm);
-        pool.setName(poolName);
-
-        _poolDao.update(pool.getId(), pool);
-    }
-
-    @Override
-    public void deletePool(String poolName) throws InvalidParameterValueException, ResourceInUseException {
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Request --> deletePool ");
-
-        PoolVO pool = _poolDao.findPool(poolName);
-        if (pool == null) {
-            throw new InvalidParameterValueException("Cannot find pool " + poolName);
-        }
-        //check if pool is empty
-        int volCount = _volumeDao.listVolumes(poolName).size();
-
-        if (volCount == 0) {
-            _poolDao.remove(pool.getId());
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Request --> deletePool: Success ");
-
-        } else {
-            throw new ResourceInUseException("Cannot delete non-empty pool");
-        }
-    }
-
-    @Override
-    public List<PoolVO> listPools() {
-        return _poolDao.listAll();
-    }
-
-    /**
-     * This method destroys the volume on netapp filer
-     * @param ipAddress -- ip address of filer
-     * @param aggrName -- name of containing aggregate
-     * @param volName -- name of volume to destroy
-     * @throws ResourceInUseException
-     * @throws NaException
-     * @throws NaAPIFailedException
-     */
-    @Override
-    @DB
-    public void destroyVolumeOnFiler(String ipAddress, String aggrName, String volName) throws ServerException, InvalidParameterValueException, ResourceInUseException {
-        NaElement xi0;
-        NaElement xi1;
-        NetappVolumeVO volume = null;
-
-        volume = _volumeDao.findVolume(ipAddress, aggrName, volName);
-
-        if (volume == null) {
-            s_logger.warn("The volume does not exist in our system");
-            throw new InvalidParameterValueException("The given tuple:" + ipAddress + "," + aggrName + "," + volName + " doesn't exist in our system");
-        }
-
-        List<LunVO> lunsOnVol = _lunDao.listLunsByVolId(volume.getId());
-
-        if (lunsOnVol != null && lunsOnVol.size() > 0) {
-            s_logger.warn("There are luns on the volume");
-            throw new ResourceInUseException("There are luns on the volume");
-        }
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        PoolVO pool = _poolDao.findById(volume.getPoolId());
-        if (pool == null) {
-            throw new InvalidParameterValueException("Failed to find pool for given volume");
-            //FIXME: choose a better exception. this is a db integrity exception
-        }
-        pool = _poolDao.acquireInLockTable(pool.getId());
-        if (pool == null) {
-            throw new ConcurrentModificationException("Failed to acquire lock on pool " + volume.getPoolId());
-        }
-        NaServer s = null;
-        try {
-            s = getServer(volume.getIpAddress(), volume.getUsername(), volume.getPassword());
-            //bring the volume down
-            xi0 = new NaElement("volume-offline");
-            xi0.addNewChild("name", volName);
-            s.invokeElem(xi0);
-
-            //now destroy it
-            xi1 = new NaElement("volume-destroy");
-            xi1.addNewChild("name", volName);
-            s.invokeElem(xi1);
-
-            //now delete from our records
-            _volumeDao.remove(volume.getId());
-            txn.commit();
-
-        } catch (UnknownHostException uhe) {
-            s_logger.warn("Unable to delete volume on filer ", uhe);
-            throw new ServerException("Unable to delete volume on filer", uhe);
-        } catch (NaAPIFailedException naf) {
-            s_logger.warn("Unable to delete volume on filer ", naf);
-            if (naf.getErrno() == 13040) {
-                s_logger.info("Deleting the volume: " + volName);
-                _volumeDao.remove(volume.getId());
-                txn.commit();
-            }
-
-            throw new ServerException("Unable to delete volume on filer", naf);
-        } catch (NaException nae) {
-            txn.rollback();
-            s_logger.warn("Unable to delete volume on filer ", nae);
-            throw new ServerException("Unable to delete volume on filer", nae);
-        } catch (IOException ioe) {
-            txn.rollback();
-            s_logger.warn("Unable to delete volume on filer ", ioe);
-            throw new ServerException("Unable to delete volume on filer", ioe);
-        } finally {
-            if (pool != null) {
-                _poolDao.releaseFromLockTable(pool.getId());
-            }
-            if (s != null)
-                s.close();
-        }
-
-    }
-
-    /**
-     * This method creates a volume on netapp filer
-     * @param ipAddress -- ip address of the filer
-     * @param aggName -- name of aggregate
-     * @param poolName -- name of pool
-     * @param volName -- name of volume
-     * @param volSize -- size of volume to be created
-     * @param snapshotPolicy -- associated snapshot policy for volume
-     * @param snapshotReservation -- associated reservation for snapshots
-     * @param username -- username
-     * @param password -- password
-     * @throws UnknownHostException
-     * @throws InvalidParameterValueException
-     */
-    @Override
-    @DB
-    public void createVolumeOnFiler(String ipAddress, String aggName, String poolName, String volName, String volSize, String snapshotPolicy,
-        Integer snapshotReservation, String username, String password) throws UnknownHostException, ServerException, InvalidParameterValueException {
-
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Request --> createVolume " + "serverIp:" + ipAddress);
-
-        boolean snapPolicy = false;
-        boolean snapshotRes = false;
-        boolean volumeCreated = false;
-
-        NaServer s = getServer(ipAddress, username, password);
-
-        NaElement xi = new NaElement("volume-create");
-        xi.addNewChild("volume", volName);
-        xi.addNewChild("containing-aggr-name", aggName);
-        xi.addNewChild("size", volSize);
-
-        NaElement xi1 = new NaElement("snapshot-set-reserve");
-        if (snapshotReservation != null) {
-            snapshotRes = true;
-            xi1.addNewChild("percentage", snapshotReservation.toString());
-            xi1.addNewChild("volume", volName);
-        }
-
-        NaElement xi2 = new NaElement("snapshot-set-schedule");
-
-        if (snapshotPolicy != null) {
-            snapPolicy = true;
-
-            String weeks = null;
-            String days = null;
-            String hours = null;
-            String whichHours = null;
-            String minutes = null;
-            String whichMinutes = null;
-
-            StringTokenizer s1 = new StringTokenizer(snapshotPolicy, " ");
-
-            //count=4: weeks days hours@csi mins@csi
-            //count=3: weeks days hours@csi
-            //count=2: weeks days
-            //count=1: weeks
-
-            if (s1.hasMoreTokens()) {
-                weeks = s1.nextToken();
-            }
-            if (weeks != null && s1.hasMoreTokens()) {
-                days = s1.nextToken();
-            }
-            if (days != null && s1.hasMoreTokens()) {
-                String[] hoursArr = s1.nextToken().split("@");
-                hours = hoursArr[0];
-                whichHours = hoursArr[1];
-            }
-            if (hours != null && s1.hasMoreTokens()) {
-                String[] minsArr = s1.nextToken().split("@");
-                minutes = minsArr[0];
-                whichMinutes = minsArr[1];
-            }
-
-            if (weeks != null)
-                xi2.addNewChild("weeks", weeks);
-            if (days != null)
-                xi2.addNewChild("days", days);
-            if (hours != null)
-                xi2.addNewChild("hours", hours);
-            if (minutes != null)
-                xi2.addNewChild("minutes", minutes);
-            xi2.addNewChild("volume", volName);
-
-            if (whichHours != null)
-                xi2.addNewChild("which-hours", whichHours);
-            if (whichMinutes != null)
-                xi2.addNewChild("which-minutes", whichMinutes);
-        }
-        Long volumeId = null;
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        NetappVolumeVO volume = null;
-        volume = _volumeDao.findVolume(ipAddress, aggName, volName);
-
-        if (volume != null) {
-            throw new InvalidParameterValueException("The volume for the given ipAddress/aggregateName/volumeName tuple already exists");
-        }
-        PoolVO pool = _poolDao.findPool(poolName);
-        if (pool == null) {
-            throw new InvalidParameterValueException("Cannot find pool " + poolName);
-        }
-        pool = _poolDao.acquireInLockTable(pool.getId());
-        if (pool == null) {
-            s_logger.warn("Failed to acquire lock on pool " + poolName);
-            throw new ConcurrentModificationException("Failed to acquire lock on pool " + poolName);
-        }
-        volume = new NetappVolumeVO(ipAddress, aggName, pool.getId(), volName, volSize, "", 0, username, password, 0, pool.getName());
-        volume = _volumeDao.persist(volume);
-
-        volumeId = volume.getId();
-        try {
-            s.invokeElem(xi);
-            volumeCreated = true;
-
-            if (snapshotRes) {
-                s.invokeElem(xi1);
-                volume.setSnapshotReservation(snapshotReservation);
-                _volumeDao.update(volumeId, volume);
-            }
-
-            if (snapPolicy) {
-                s.invokeElem(xi2);
-                volume.setSnapshotPolicy(snapshotPolicy);
-                _volumeDao.update(volumeId, volume);
-            }
-            txn.commit();
-        } catch (NaException nae) {
-            //zapi call failed, log and throw e
-            s_logger.warn("Failed to create volume on the netapp filer:", nae);
-            txn.rollback();
-            if (volumeCreated) {
-                try {
-                    deleteRogueVolume(volName, s);//deletes created volume on filer
-                } catch (NaException e) {
-                    s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
-                    throw new ServerException("Unable to create volume via cloudtools."
-                        + "Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
-                } catch (IOException e) {
-                    s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
-                    throw new ServerException("Unable to create volume via cloudtools."
-                        + "Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
-                }
-            }
-            throw new ServerException("Unable to create volume", nae);
-        } catch (IOException ioe) {
-            s_logger.warn("Failed to create volume on the netapp filer:", ioe);
-            txn.rollback();
-            if (volumeCreated) {
-                try {
-                    deleteRogueVolume(volName, s);//deletes created volume on filer
-                } catch (NaException e) {
-                    s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
-                    throw new ServerException("Unable to create volume via cloudtools."
-                        + "Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
-                } catch (IOException e) {
-                    s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
-                    throw new ServerException("Unable to create volume via cloudtools."
-                        + "Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
-                }
-            }
-            throw new ServerException("Unable to create volume", ioe);
-        } finally {
-            if (s != null)
-                s.close();
-            if (pool != null)
-                _poolDao.releaseFromLockTable(pool.getId());
-
-        }
-    }
-
-    /**
-     * This method is primarily used to cleanup volume created on the netapp filer, when createVol api command fails at snapshot reservation.
-     * We roll back the db record, but the record on the netapp box still exists. We clean up that record using this helper method.
-     * @param volName
-     * @param s -- server reference
-     * @throws NaException
-     * @throws IOException
-     */
-    private void deleteRogueVolume(String volName, NaServer s) throws NaException, IOException {
-        //bring the volume down
-        NaElement xi0 = new NaElement("volume-offline");
-        xi0.addNewChild("name", volName);
-        s.invokeElem(xi0);
-
-        //now destroy it
-        NaElement xi1 = new NaElement("volume-destroy");
-        xi1.addNewChild("name", volName);
-        s.invokeElem(xi1);
-    }
-
-    /**
-     * This method lists all the volumes by pool name
-     * @param poolName
-     * @return -- volumes in that pool
-     */
-    @Override
-    public List<NetappVolumeVO> listVolumesOnFiler(String poolName) {
-
-        List<NetappVolumeVO> vols = _volumeDao.listVolumesAscending(poolName);
-
-        for (NetappVolumeVO vol : vols) {
-            try {
-                String snapScheduleOnFiler = returnSnapshotSchedule(vol);
-                vol.setSnapshotPolicy(snapScheduleOnFiler);
-
-            } catch (ServerException e) {
-                s_logger.warn("Error trying to get snapshot schedule for volume" + vol.getVolumeName());
-            }
-        }
-        return vols;
-    }
-
-    /**
-     * Utility method to return snapshot schedule for a volume
-     * @param vol -- volume for the snapshot schedule creation
-     * @return -- the snapshot schedule
-     * @throws ServerException
-     */
-    private String returnSnapshotSchedule(NetappVolumeVO vol) throws ServerException {
-
-        NaElement xi = new NaElement("snapshot-get-schedule");
-        xi.addNewChild("volume", vol.getVolumeName());
-        NaServer s = null;
-        try {
-            s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
-            NaElement xo = s.invokeElem(xi);
-            String weeks = xo.getChildContent("weeks");
-            String days = xo.getChildContent("days");
-            String hours = xo.getChildContent("hours");
-            String minutes = xo.getChildContent("minutes");
-            String whichHours = xo.getChildContent("which-hours");
-            String whichMinutes = xo.getChildContent("which-minutes");
-
-            StringBuilder sB = new StringBuilder();
-            sB.append(weeks)
-                .append(" ")
-                .append(days)
-                .append(" ")
-                .append(hours)
-                .append("@")
-                .append(whichHours)
-                .append(" ")
-                .append(minutes)
-                .append("@")
-                .append(whichMinutes);
-            return sB.toString();
-        } catch (NaException nae) {
-            s_logger.warn("Failed to get volume size ", nae);
-            throw new ServerException("Failed to get volume size", nae);
-        } catch (IOException ioe) {
-            s_logger.warn("Failed to get volume size ", ioe);
-            throw new ServerException("Failed to get volume size", ioe);
-        } finally {
-            if (s != null)
-                s.close();
-        }
-    }
-
-    /**
-     * This method returns the ascending order list of volumes based on their ids
-     * @param poolName -- name of pool
-     * @return -- ascending ordered list of volumes based on ids
-     */
-    @Override
-    public List<NetappVolumeVO> listVolumesAscending(String poolName) {
-        return _volumeDao.listVolumesAscending(poolName);
-    }
-
-    /**
-     * This method returns the available size on the volume in terms of bytes
-     * @param volName -- name of volume
-     * @param userName -- username
-     * @param password -- password
-     * @param serverIp -- ip address of filer
-     * @throws UnknownHostException
-     * @return-- available size on the volume in terms of bytes; return -1 if volume is offline
-     * @throws ServerException
-     */
-    @Override
-    public long returnAvailableVolumeSize(String volName, String userName, String password, String serverIp) throws ServerException {
-        long availableSize = 0;
-
-        NaElement xi = new NaElement("volume-list-info");
-        xi.addNewChild("volume", volName);
-        NaServer s = null;
-        String volumeState = null;
-        try {
-            s = getServer(serverIp, userName, password);
-            NaElement xo = s.invokeElem(xi);
-            List volList = xo.getChildByName("volumes").getChildren();
-            Iterator volIter = volList.iterator();
-            while (volIter.hasNext()) {
-                NaElement volInfo = (NaElement)volIter.next();
-                availableSize = volInfo.getChildLongValue("size-available", -1);
-                volumeState = volInfo.getChildContent("state");
-            }
-
-            if (volumeState != null) {
-                return volumeState.equalsIgnoreCase("online") ? availableSize : -1; //return -1 if volume is offline
-            } else {
-                //catch all
-                //volume state unreported
-                return -1; // as good as volume offline
-            }
-
-        } catch (NaException nae) {
-            s_logger.warn("Failed to get volume size ", nae);
-            throw new ServerException("Failed to get volume size", nae);
-        } catch (IOException ioe) {
-            s_logger.warn("Failed to get volume size ", ioe);
-            throw new ServerException("Failed to get volume size", ioe);
-        } finally {
-            if (s != null)
-                s.close();
-        }
-    }
-
-    /**
-     * This method creates a lun on the netapp filer
-     * @param poolName -- name of the pool
-     * @param lunSize -- size of the lun to be created
-     * @return -- lun path
-     * @throws IOException
-     * @throws ResourceAllocationException
-     * @throws NaException
-     */
-    @Override
-    @DB
-    public String[] createLunOnFiler(String poolName, Long lunSize) throws ServerException, InvalidParameterValueException, ResourceAllocationException {
-        String[] result = new String[3];
-        StringBuilder lunName = new StringBuilder("lun-");
-        LunVO lun = null;
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        PoolVO pool = _poolDao.findPool(poolName);
-
-        if (pool == null) {
-            throw new InvalidParameterValueException("Cannot find pool " + poolName);
-        }
-
-        if (lunSize <= 0) {
-            throw new InvalidParameterValueException("Please specify a valid lun size in Gb");
-        }
-
-        String algorithm = pool.getAlgorithm();
-        NetappVolumeVO selectedVol = null;
-
-        //sanity check
-        int numVolsInPool = _volumeDao.listVolumes(poolName).size();
-
-        if (numVolsInPool == 0) {
-            throw new InvalidParameterValueException("No volumes exist in the given pool");
-        }
-        pool = _poolDao.acquireInLockTable(pool.getId());
-        if (pool == null) {
-            s_logger.warn("Failed to acquire lock on the pool " + poolName);
-            return result;
-        }
-        NaServer s = null;
-
-        try {
-            if (algorithm == null || algorithm.equals(Algorithm.roundrobin.toString())) {
-                selectedVol = _netappAllocator.chooseVolumeFromPool(poolName, lunSize);
-            } else if (algorithm.equals(Algorithm.leastfull.toString())) {
-
-                selectedVol = _netappAllocator.chooseLeastFullVolumeFromPool(poolName, lunSize);
-            }
-
-            if (selectedVol == null) {
-                throw new ServerException("Could not find a suitable volume to create lun on");
-            }
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Request --> createLun " + "serverIp:" + selectedVol.getIpAddress());
-
-            StringBuilder exportPath = new StringBuilder("/vol/");
-            exportPath.append(selectedVol.getVolumeName());
-            exportPath.append("/");
-
-            lun = new LunVO(exportPath.toString(), selectedVol.getId(), lunSize, "", "");
-            lun = _lunDao.persist(lun);
-
-            //Lun id created: 6 digits right justified eg. 000045
-            String lunIdStr = String.valueOf(lun.getId());
-            String zeroStr = "000000";
-            int length = lunIdStr.length();
-            int offset = 6 - length;
-            StringBuilder lunIdOnPath = new StringBuilder();
-            lunIdOnPath.append(zeroStr.substring(0, offset));
-            lunIdOnPath.append(lunIdStr);
-            exportPath.append("lun-").append(lunIdOnPath.toString());
-
-            lunName.append(lunIdOnPath.toString());
-
-            //update lun name
-            lun.setLunName(lunName.toString());
-            _lunDao.update(lun.getId(), lun);
-
-            NaElement xi;
-            NaElement xi1;
-
-            long lSizeBytes = 1L * lunSize * 1024 * 1024 * 1024; //This prevents integer overflow
-            Long lunSizeBytes = new Long(lSizeBytes);
-
-            s = getServer(selectedVol.getIpAddress(), selectedVol.getUsername(), selectedVol.getPassword());
-
-            //create lun
-            xi = new NaElement("lun-create-by-size");
-            xi.addNewChild("ostype", "linux");
-            xi.addNewChild("path", exportPath.toString());
-            xi.addNewChild("size", (lunSizeBytes.toString()));
-
-            s.invokeElem(xi);
-
-            try {
-                //now create an igroup
-                xi1 = new NaElement("igroup-create");
-                xi1.addNewChild("initiator-group-name", lunName.toString());
-                xi1.addNewChild("initiator-group-type", "iscsi");
-                xi1.addNewChild("os-type", "linux");
-                s.invokeElem(xi1);
-            } catch (NaAPIFailedException e) {
-                if (e.getErrno() == 9004) {
-                    //igroup already exists hence no error
-                    s_logger.warn("Igroup already exists");
-                }
-            }
-
-            //get target iqn
-            NaElement xi4 = new NaElement("iscsi-node-get-name");
-            NaElement xo = s.invokeElem(xi4);
-            String iqn = xo.getChildContent("node-name");
-
-            lun.setTargetIqn(iqn);
-            _lunDao.update(lun.getId(), lun);
-
-            //create lun mapping
-            //now map the lun to the igroup
-            NaElement xi3 = new NaElement("lun-map");
-            xi3.addNewChild("force", "true");
-            xi3.addNewChild("initiator-group", lunName.toString());
-            xi3.addNewChild("path", lun.getPath() + lun.getLunName());
-
-            xi3.addNewChild("lun-id", lunIdStr);
-            s.invokeElem(xi3);
-
-            txn.commit();
-            //set the result
-            result[0] = lunName.toString();//lunname
-            result[1] = iqn;//iqn
-            result[2] = selectedVol.getIpAddress();
-
-            return result;
-
-        } catch (NaAPIFailedException naf) {
-            if (naf.getErrno() == 9023) { //lun is already mapped to this group
-                result[0] = lunName.toString();//lunname;
-                result[1] = lun.getTargetIqn();//iqn
-                result[2] = selectedVol.getIpAddress();
-                return result;
-            }
-            if (naf.getErrno() == 9024) { //another lun mapped at this group
-                result[0] = lunName.toString();//lunname;
-                result[1] = lun.getTargetIqn();//iqn
-                result[2] = selectedVol.getIpAddress();
-                return result;
-            }
-        } catch (NaException nae) {
-            txn.rollback();
-            throw new ServerException("Unable to create LUN", nae);
-        } catch (IOException ioe) {
-            txn.rollback();
-            throw new ServerException("Unable to create LUN", ioe);
-        } finally {
-            if (pool != null) {
-                _poolDao.releaseFromLockTable(pool.getId());
-            }
-            if (s != null) {
-                s.close();
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * This method destroys a lun on the netapp filer
-     * @param lunName -- name of the lun to be destroyed
-     */
-    @Override
-    @DB
-    public void destroyLunOnFiler(String lunName) throws InvalidParameterValueException, ServerException {
-
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        LunVO lun = _lunDao.findByName(lunName);
-
-        if (lun == null)
-            throw new InvalidParameterValueException("Cannot find lun");
-
-        NetappVolumeVO vol = _volumeDao.acquireInLockTable(lun.getVolumeId());
-        if (vol == null) {
-            s_logger.warn("Failed to lock volume id= " + lun.getVolumeId());
-            return;
-        }
-        NaServer s = null;
-        try {
-            s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Request --> destroyLun " + ":serverIp:" + vol.getIpAddress());
-
-            try {
-                //Unmap lun
-                NaElement xi2 = new NaElement("lun-unmap");
-                xi2.addNewChild("initiator-group", lunName);
-                xi2.addNewChild("path", lun.getPath() + lun.getLunName());
-                s.invokeElem(xi2);
-            } catch (NaAPIFailedException naf) {
-                if (naf.getErrno() == 9016)
-                    s_logger.warn("no map exists excpn 9016 caught in deletelun, continuing with delete");
-            }
-
-            //destroy lun
-            NaElement xi = new NaElement("lun-destroy");
-            xi.addNewChild("force", "true");
-            xi.addNewChild("path", lun.getPath() + lun.getLunName());
-            s.invokeElem(xi);
-
-            //destroy igroup
-            NaElement xi1 = new NaElement("igroup-destroy");
-            //xi1.addNewChild("force","true");
-            xi1.addNewChild("initiator-group-name", lunName);
-            s.invokeElem(xi1);
-
-            _lunDao.remove(lun.getId());
-            txn.commit();
-        } catch (UnknownHostException uhe) {
-            txn.rollback();
-            s_logger.warn("Failed to delete lun", uhe);
-            throw new ServerException("Failed to delete lun", uhe);
-        } catch (IOException ioe) {
-            txn.rollback();
-            s_logger.warn("Failed to delete lun", ioe);
-            throw new ServerException("Failed to delete lun", ioe);
-        } catch (NaAPIFailedException naf) {
-            if (naf.getErrno() == 9017) {//no such group exists excpn
-                s_logger.warn("no such group exists excpn 9017 caught in deletelun, continuing with delete");
-                _lunDao.remove(lun.getId());
-                txn.commit();
-            } else if (naf.getErrno() == 9029) {//LUN maps for this initiator group exist
-                s_logger.warn("LUN maps for this initiator group exist errno 9029 caught in deletelun, continuing with delete");
-                _lunDao.remove(lun.getId());
-                txn.commit();
-            } else {
-                txn.rollback();
-                s_logger.warn("Failed to delete lun", naf);
-                throw new ServerException("Failed to delete lun", naf);
-            }
-
-        } catch (NaException nae) {
-            txn.rollback();
-            s_logger.warn("Failed to delete lun", nae);
-            throw new ServerException("Failed to delete lun", nae);
-        } finally {
-            if (vol != null) {
-                _volumeDao.releaseFromLockTable(vol.getId());
-            }
-            if (s != null)
-                s.close();
-        }
-
-    }
-
-    /**
-     * This method lists the luns on the netapp filer
-     * @param volId -- id of the containing volume
-     * @return -- list of netapp luns
-     * @throws NaException
-     * @throws IOException
-     */
-    @Override
-    public List<LunVO> listLunsOnFiler(String poolName) {
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Request --> listLunsOnFiler ");
-
-        List<LunVO> luns = new ArrayList<LunVO>();
-
-        List<NetappVolumeVO> vols = _volumeDao.listVolumes(poolName);
-
-        for (NetappVolumeVO vol : vols) {
-            luns.addAll(_lunDao.listLunsByVolId(vol.getId()));
-        }
-
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Response --> listLunsOnFiler:success");
-
-        return luns;
-    }
-
-    /**
-     * This method disassociates a lun from the igroup on the filer
-     * @param iGroup -- igroup name
-     * @param lunName -- lun name
-     */
-    @Override
-    public void disassociateLun(String iGroup, String lunName) throws ServerException, InvalidParameterValueException {
-        NaElement xi;
-        LunVO lun = _lunDao.findByName(lunName);
-
-        if (lun == null)
-            throw new InvalidParameterValueException("Cannot find LUN " + lunName);
-
-        NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());
-        NaServer s = null;
-        try {
-            s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Request --> disassociateLun " + ":serverIp:" + vol.getIpAddress());
-
-            xi = new NaElement("igroup-remove");
-            xi.addNewChild("force", "true");
-            xi.addNewChild("initiator", iGroup);
-            xi.addNewChild("initiator-group-name", lunName);
-            s.invokeElem(xi);
-
-        } catch (UnknownHostException uhe) {
-            throw new ServerException("Failed to disassociate lun", uhe);
-        } catch (IOException ioe) {
-            throw new ServerException("Failed to disassociate lun", ioe);
-        } catch (NaException nae) {
-            throw new ServerException("Failed to disassociate lun", nae);
-        } finally {
-            if (s != null)
-                s.close();
-        }
-
-    }
-
-    /**
-     * This method associates a lun to a particular igroup
-     * @param iqn
-     * @param iGroup
-     * @param lunName
-     */
-    @Override
-    public String[] associateLun(String guestIqn, String lunName) throws ServerException, InvalidParameterValueException
-
-    {
-        NaElement xi2;
-
-        //get lun id from path
-        String[] splitLunName = lunName.split("-");
-        String[] returnVal = new String[3];
-        if (splitLunName.length != 2)
-            throw new InvalidParameterValueException("The lun id is malformed");
-
-        String lunIdStr = splitLunName[1];
-
-        Long lId = new Long(lunIdStr);
-
-        LunVO lun = _lunDao.findById(lId);
-
-        if (lun == null)
-            throw new InvalidParameterValueException("Cannot find LUN " + lunName);
-
-        NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());
-
-        //assert(vol != null);
-
-        returnVal[0] = lunIdStr;
-        returnVal[1] = lun.getTargetIqn();
-        returnVal[2] = vol.getIpAddress();
-
-        NaServer s = null;
-
-        try {
-            s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
-
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Request --> associateLun " + ":serverIp:" + vol.getIpAddress());
-
-            //add iqn to the group
-            xi2 = new NaElement("igroup-add");
-            xi2.addNewChild("force", "true");
-            xi2.addNewChild("initiator", guestIqn);
-            xi2.addNewChild("initiator-group-name", lunName);
-            s.invokeElem(xi2);
-
-            return returnVal;
-        } catch (UnknownHostException uhe) {
-            s_logger.warn("Unable to associate LUN ", uhe);
-            throw new ServerException("Unable to associate LUN", uhe);
-        } catch (NaAPIFailedException naf) {
-            if (naf.getErrno() == 9008) { //initiator group already contains node
-                return returnVal;
-            }
-            s_logger.warn("Unable to associate LUN ", naf);
-            throw new ServerException("Unable to associate LUN", naf);
-        } catch (NaException nae) {
-            s_logger.warn("Unable to associate LUN ", nae);
-            throw new ServerException("Unable to associate LUN", nae);
-        } catch (IOException ioe) {
-            s_logger.warn("Unable to associate LUN ", ioe);
-            throw new ServerException("Unable to associate LUN", ioe);
-        } finally {
-            if (s != null)
-                s.close();
-        }
-
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-
-        _netappAllocator = new NetappDefaultAllocatorImpl(this);
-
-        return true;
-    }
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappVolumeVO.java b/plugins/file-systems/netapp/src/com/cloud/netapp/NetappVolumeVO.java
deleted file mode 100644
index cfaced9..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/NetappVolumeVO.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.api.InternalIdentity;
-
-@Entity
-@Table(name = "netapp_volume")
-public class NetappVolumeVO implements InternalIdentity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "ip_address")
-    private String ipAddress;
-
-    @Column(name = "aggregate_name")
-    private String aggregateName;
-
-    @Column(name = "pool_id")
-    private Long poolId;
-
-    @Column(name = "pool_name")
-    private String poolName;
-
-    @Column(name = "volume_name")
-    private String volumeName;
-
-    @Column(name = "username")
-    private String username;
-
-    @Column(name = "password")
-    private String password;
-
-    @Column(name = "snapshot_policy")
-    private String snapshotPolicy;
-
-    @Column(name = "snapshot_reservation")
-    private Integer snapshotReservation;
-
-    @Column(name = "volume_size")
-    private String volumeSize;
-
-    @Column(name = "round_robin_marker")
-    private int roundRobinMarker;
-
-    public NetappVolumeVO() {
-
-    }
-
-    public NetappVolumeVO(String ipAddress, String aggName, Long poolId, String volName, String volSize, String snapshotPolicy, int snapshotReservation, String username,
-            String password, int roundRobinMarker, String poolName) {
-        this.ipAddress = ipAddress;
-        this.aggregateName = aggName;
-        this.poolId = poolId;
-        this.username = username;
-        this.password = password;
-        this.volumeName = volName;
-        this.volumeSize = volSize;
-        this.snapshotPolicy = snapshotPolicy;
-        this.snapshotReservation = snapshotReservation;
-        this.roundRobinMarker = roundRobinMarker;
-        this.poolName = poolName;
-    }
-
-    public String getPoolName() {
-        return poolName;
-    }
-
-    public void setPoolName(String poolName) {
-        this.poolName = poolName;
-    }
-
-    public int getRoundRobinMarker() {
-        return roundRobinMarker;
-    }
-
-    public void setRoundRobinMarker(int roundRobinMarker) {
-        this.roundRobinMarker = roundRobinMarker;
-    }
-
-    public String getVolumeName() {
-        return volumeName;
-    }
-
-    public void setVolumeName(String volumeName) {
-        this.volumeName = volumeName;
-    }
-
-    public String getSnapshotPolicy() {
-        return snapshotPolicy;
-    }
-
-    public void setSnapshotPolicy(String snapshotPolicy) {
-        this.snapshotPolicy = snapshotPolicy;
-    }
-
-    public Integer getSnapshotReservation() {
-        return snapshotReservation;
-    }
-
-    public void setSnapshotReservation(Integer snapshotReservation) {
-        this.snapshotReservation = snapshotReservation;
-    }
-
-    public String getVolumeSize() {
-        return volumeSize;
-    }
-
-    public void setVolumeSize(String volumeSize) {
-        this.volumeSize = volumeSize;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public void setIpAddress(String ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-
-    public String getAggregateName() {
-        return aggregateName;
-    }
-
-    public void setAggregateName(String aggregateName) {
-        this.aggregateName = aggregateName;
-    }
-
-    public Long getPoolId() {
-        return poolId;
-    }
-
-    public void setPoolId(Long poolId) {
-        this.poolId = poolId;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/PoolVO.java b/plugins/file-systems/netapp/src/com/cloud/netapp/PoolVO.java
deleted file mode 100644
index a045fec..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/PoolVO.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.api.InternalIdentity;
-
-@Entity
-@Table(name = "netapp_pool")
-public class PoolVO implements InternalIdentity {
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setAlgorithm(String algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "algorithm")
-    private String algorithm;
-
-    public PoolVO() {
-
-    }
-
-    public PoolVO(String name, String algorithm) {
-        this.name = name;
-        this.algorithm = algorithm;
-    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDao.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDao.java
deleted file mode 100644
index 2bc95cf..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDao.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-import com.cloud.netapp.LunVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface LunDao extends GenericDao<LunVO, Long> {
-
-    List<LunVO> listLunsByVolId(Long volId);
-
-    LunVO findByName(String name);
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDaoImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDaoImpl.java
deleted file mode 100644
index 58f2ea1..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/LunDaoImpl.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.netapp.LunVO;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class LunDaoImpl extends GenericDaoBase<LunVO, Long> implements LunDao {
-    private static final Logger s_logger = Logger.getLogger(PoolDaoImpl.class);
-
-    protected final SearchBuilder<LunVO> LunSearch;
-    protected final SearchBuilder<LunVO> LunNameSearch;
-
-    protected LunDaoImpl() {
-
-        LunSearch = createSearchBuilder();
-        LunSearch.and("volumeId", LunSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        LunSearch.done();
-
-        LunNameSearch = createSearchBuilder();
-        LunNameSearch.and("name", LunNameSearch.entity().getLunName(), SearchCriteria.Op.EQ);
-        LunNameSearch.done();
-
-    }
-
-    @Override
-    public List<LunVO> listLunsByVolId(Long volId) {
-        Filter searchFilter = new Filter(LunVO.class, "id", Boolean.TRUE, Long.valueOf(0), Long.valueOf(10000));
-
-        SearchCriteria sc = LunSearch.create();
-        sc.setParameters("volumeId", volId);
-        List<LunVO> lunList = listBy(sc, searchFilter);
-
-        return lunList;
-    }
-
-    @Override
-    public LunVO findByName(String name) {
-        SearchCriteria sc = LunNameSearch.create();
-        sc.setParameters("name", name);
-        return findOneBy(sc);
-    }
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDao.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDao.java
deleted file mode 100644
index 3c0191b..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDao.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-import com.cloud.netapp.PoolVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface PoolDao extends GenericDao<PoolVO, Long> {
-
-    PoolVO findPool(String poolName);
-
-    List<PoolVO> listPools();
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDaoImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDaoImpl.java
deleted file mode 100644
index 03352d2..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/PoolDaoImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.netapp.PoolVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class PoolDaoImpl extends GenericDaoBase<PoolVO, Long> implements PoolDao {
-    private static final Logger s_logger = Logger.getLogger(PoolDaoImpl.class);
-
-    protected final SearchBuilder<PoolVO> PoolSearch;
-
-    protected PoolDaoImpl() {
-
-        PoolSearch = createSearchBuilder();
-        PoolSearch.and("name", PoolSearch.entity().getName(), SearchCriteria.Op.EQ);
-        PoolSearch.done();
-
-    }
-
-    @Override
-    public PoolVO findPool(String poolName) {
-        SearchCriteria sc = PoolSearch.create();
-        sc.setParameters("name", poolName);
-        List<PoolVO> poolList = listBy(sc);
-
-        return (poolList.size() > 0 ? poolList.get(0) : null);
-    }
-
-    @Override
-    public List<PoolVO> listPools() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-//    @Override
-//    public List<NetappStoragePoolVO> listVolumes(String poolName) {
-//        SearchCriteria sc = NetappListVolumeSearch.create();
-//        sc.setParameters("poolName", poolName);
-//        return listBy(sc);
-//    }
-
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDao.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDao.java
deleted file mode 100644
index 59b9190..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDao.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-import com.cloud.netapp.NetappVolumeVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface VolumeDao extends GenericDao<NetappVolumeVO, Long> {
-
-    NetappVolumeVO findVolume(String ipAddress, String aggregateName, String volumeName);
-
-    List<NetappVolumeVO> listVolumes(String poolName);
-
-    NetappVolumeVO returnRoundRobinMarkerInPool(String poolName, int roundRobinMarker);
-
-    List<NetappVolumeVO> listVolumesAscending(String poolName);
-}
diff --git a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java b/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java
deleted file mode 100644
index 70db5bc..0000000
--- a/plugins/file-systems/netapp/src/com/cloud/netapp/dao/VolumeDaoImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.netapp.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.netapp.NetappVolumeVO;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component(value = "netappVolumeDaoImpl")
-public class VolumeDaoImpl extends GenericDaoBase<NetappVolumeVO, Long> implements VolumeDao {
-    private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
-
-    protected final SearchBuilder<NetappVolumeVO> NetappVolumeSearch;
-    protected final SearchBuilder<NetappVolumeVO> NetappListVolumeSearch;
-    protected final SearchBuilder<NetappVolumeVO> NetappRoundRobinMarkerSearch;
-
-    @Override
-    public NetappVolumeVO findVolume(String ipAddress, String aggregateName, String volumeName) {
-        SearchCriteria<NetappVolumeVO> sc = NetappVolumeSearch.create();
-        sc.setParameters("ipAddress", ipAddress);
-        sc.setParameters("aggregateName", aggregateName);
-        sc.setParameters("volumeName", volumeName);
-
-        List<NetappVolumeVO> volList = listBy(sc);
-
-        return (volList.size() == 0 ? null : volList.get(0));
-    }
-
-    protected VolumeDaoImpl() {
-        NetappVolumeSearch = createSearchBuilder();
-        NetappVolumeSearch.and("ipAddress", NetappVolumeSearch.entity().getIpAddress(), SearchCriteria.Op.EQ);
-        NetappVolumeSearch.and("aggregateName", NetappVolumeSearch.entity().getAggregateName(), SearchCriteria.Op.EQ);
-        NetappVolumeSearch.and("volumeName", NetappVolumeSearch.entity().getVolumeName(), SearchCriteria.Op.EQ);
-        NetappVolumeSearch.done();
-
-        NetappListVolumeSearch = createSearchBuilder();
-        NetappListVolumeSearch.and("poolName", NetappListVolumeSearch.entity().getPoolName(), SearchCriteria.Op.EQ);
-        NetappListVolumeSearch.done();
-
-        NetappRoundRobinMarkerSearch = createSearchBuilder();
-        NetappRoundRobinMarkerSearch.and("roundRobinMarker", NetappRoundRobinMarkerSearch.entity().getRoundRobinMarker(), SearchCriteria.Op.EQ);
-        NetappRoundRobinMarkerSearch.and("poolName", NetappRoundRobinMarkerSearch.entity().getPoolName(), SearchCriteria.Op.EQ);
-        NetappRoundRobinMarkerSearch.done();
-    }
-
-    @Override
-    public List<NetappVolumeVO> listVolumes(String poolName) {
-        SearchCriteria<NetappVolumeVO> sc = NetappListVolumeSearch.create();
-        sc.setParameters("poolName", poolName);
-        return listBy(sc);
-    }
-
-    @Override
-    public NetappVolumeVO returnRoundRobinMarkerInPool(String poolName, int roundRobinMarker) {
-        SearchCriteria<NetappVolumeVO> sc = NetappRoundRobinMarkerSearch.create();
-        sc.setParameters("roundRobinMarker", roundRobinMarker);
-        sc.setParameters("poolName", poolName);
-
-        List<NetappVolumeVO> marker = listBy(sc);
-
-        if (marker.size() > 0)
-            return marker.get(0);
-        else
-            return null;
-    }
-
-    @Override
-    public List<NetappVolumeVO> listVolumesAscending(String poolName) {
-        Filter searchFilter = new Filter(NetappVolumeVO.class, "id", Boolean.TRUE, Long.valueOf(0), Long.valueOf(10000));
-
-        SearchCriteria<NetappVolumeVO> sc = NetappListVolumeSearch.create();
-        sc.setParameters("poolName", poolName);
-
-        return listBy(sc, searchFilter);
-    }
-
-}
diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml
index 04b3a78..1e9a692 100644
--- a/plugins/ha-planners/skip-heurestics/pom.xml
+++ b/plugins/ha-planners/skip-heurestics/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-planner-skip-heurestics</artifactId>
-  <name>Apache CloudStack Plugin - Skip Heurestics Planner</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-planner-skip-heurestics</artifactId>
+    <name>Apache CloudStack Plugin - Skip Heurestics Planner</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/ha-planners/skip-heurestics/src/com/cloud/deploy/SkipHeuresticsPlanner.java b/plugins/ha-planners/skip-heurestics/src/main/java/com/cloud/deploy/SkipHeuresticsPlanner.java
similarity index 100%
rename from plugins/ha-planners/skip-heurestics/src/com/cloud/deploy/SkipHeuresticsPlanner.java
rename to plugins/ha-planners/skip-heurestics/src/main/java/com/cloud/deploy/SkipHeuresticsPlanner.java
diff --git a/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/module.properties b/plugins/ha-planners/skip-heurestics/src/main/resources/META-INF/cloudstack/skip-heurestics/module.properties
similarity index 100%
rename from plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/module.properties
rename to plugins/ha-planners/skip-heurestics/src/main/resources/META-INF/cloudstack/skip-heurestics/module.properties
diff --git a/plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml b/plugins/ha-planners/skip-heurestics/src/main/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml
similarity index 100%
rename from plugins/ha-planners/skip-heurestics/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml
rename to plugins/ha-planners/skip-heurestics/src/main/resources/META-INF/cloudstack/skip-heurestics/spring-skip-heurestics-context.xml
diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml
index 2032e02..bb6eb73 100644
--- a/plugins/host-allocators/random/pom.xml
+++ b/plugins/host-allocators/random/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-host-allocator-random</artifactId>
-  <name>Apache CloudStack Plugin - Host Allocator Random</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-host-allocator-random</artifactId>
+    <name>Apache CloudStack Plugin - Host Allocator Random</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java b/plugins/host-allocators/random/src/main/java/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
similarity index 100%
rename from plugins/host-allocators/random/src/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
rename to plugins/host-allocators/random/src/main/java/com/cloud/agent/manager/allocator/impl/RandomAllocator.java
diff --git a/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/module.properties b/plugins/host-allocators/random/src/main/resources/META-INF/cloudstack/host-allocator-random/module.properties
similarity index 100%
rename from plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/module.properties
rename to plugins/host-allocators/random/src/main/resources/META-INF/cloudstack/host-allocator-random/module.properties
diff --git a/plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml b/plugins/host-allocators/random/src/main/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml
similarity index 100%
rename from plugins/host-allocators/random/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml
rename to plugins/host-allocators/random/src/main/resources/META-INF/cloudstack/host-allocator-random/spring-host-allocator-random-context.xml
diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml
index 5c7af1b..aecb6b8 100755
--- a/plugins/hypervisors/baremetal/pom.xml
+++ b/plugins/hypervisors/baremetal/pom.xml
@@ -1,37 +1,36 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
-  <dependencies>
-      <dependency>
-        <groupId>commons-lang</groupId>
-        <artifactId>commons-lang</artifactId>
-        <version>2.6</version>
-    </dependency>
-   </dependencies>
-            
+<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>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
+    <dependencies>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpDao.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpDao.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpVO.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalDhcpVO.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeDao.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeDao.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeVO.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalPxeVO.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctDao.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDao.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctDao.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctDaoImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctDaoImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctVO.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalRctVO.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/database/BaremetalRctVO.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalDiscoverer.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalGuru.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalGuru.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalPlanner.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalPlanner.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalPlanner.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalPlanner.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalManager.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalManager.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalManagerImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalRct.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalRct.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalRct.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalVlanManager.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManager.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalVlanManager.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/manager/BaremetalVlanManagerImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeService.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeService.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalRctResponse.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalRctResponse.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalRctResponse.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalSwitchBackend.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalSwitchBackend.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalSwitchBackend.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalSwitchBackend.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVirtualRouterCommands.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalVirtualRouterCommands.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVirtualRouterCommands.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalVirtualRouterCommands.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVlanStruct.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalVlanStruct.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVlanStruct.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalVlanStruct.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/Force10BaremetalSwitchBackend.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/Force10BaremetalSwitchBackend.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/Force10BaremetalSwitchBackend.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/Force10BaremetalSwitchBackend.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/ObjectFactory.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/ObjectFactory.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/ObjectFactory.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/SecurityGroupRule.java
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java
rename to plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/schema/SecurityGroupVmRuleSet.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalDhcpCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalHostCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalHostCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalHostCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalHostCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalKickStartPxeCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxeCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxeCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxeCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalPxePingServerCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalRctCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/AddBaremetalRctCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/AddBaremetalRctCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/BaremetalProvisionDoneNotificationCmd.java
diff --git a/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java
new file mode 100644
index 0000000..8157c75
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java
@@ -0,0 +1,85 @@
+// 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.baremetal.manager.BaremetalVlanManager;
+import com.cloud.baremetal.networkservice.BaremetalRctResponse;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+
+/**
+ * Created by frank on 10/27/14.
+ */
+@APICommand(name = "deleteBaremetalRct", description = "deletes baremetal rack configuration text", responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
+public class DeleteBaremetalRctCmd extends BaseAsyncCmd {
+    private static final String s_name = "deletebaremetalrctresponse";
+    public static final Logger s_logger = Logger.getLogger(DeleteBaremetalRctCmd.class);
+
+    @Parameter(name = ApiConstants.ID,  type = BaseCmd.CommandType.UUID, description = "RCT id", required = true, entityType = BaremetalRctResponse.class)
+    private Long id;
+
+    @Inject
+    private BaremetalVlanManager vlanMgr;
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_BAREMETAL_RCT_DELETE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Deleting baremetal rct configuration";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+        try {
+            vlanMgr.deleteRct(this);
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } catch (Exception e) {
+            s_logger.warn(String.format("unable to delete baremetal RCT[%s]", getId()), e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccount().getId();
+    }
+
+    public Long getId() {
+        return id;
+    }
+}
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalDhcpCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalDhcpCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalDhcpCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalPxeServersCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalPxeServersCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalPxeServersCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalPxeServersCmd.java
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalRctCmd.java
similarity index 100%
rename from plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/ListBaremetalRctCmd.java
rename to plugins/hypervisors/baremetal/src/main/java/org/apache/cloudstack/api/ListBaremetalRctCmd.java
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/module.properties b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/module.properties
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-compute/module.properties
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-compute/spring-baremetal-compute-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/module.properties b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/module.properties
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-discoverer/module.properties
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-discoverer/spring-baremetal-discoverer-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/module.properties b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-network/module.properties
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/module.properties
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-network/module.properties
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-network/spring-baremetal-network-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/module.properties b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-planner/module.properties
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/module.properties
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-planner/module.properties
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-planner/spring-baremetal-planner-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/module.properties b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-storage/module.properties
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/module.properties
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-storage/module.properties
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/baremetal-storage/spring-baremetal-storage-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml b/plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml
rename to plugins/hypervisors/baremetal/src/main/resources/META-INF/cloudstack/core/spring-baremetal-core-context.xml
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/cs-sgagent
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/cs-sgagent
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/__init__.py
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/__init__.py
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/cs_sg_agent.py
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/cs_sg_agent.py
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/sglib.py
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/sglib.py
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/xmlobject.py
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/security_group_agent/xmlobject.py
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py b/plugins/hypervisors/baremetal/src/main/resources/security_group_agent/setup.py
similarity index 100%
rename from plugins/hypervisors/baremetal/resources/security_group_agent/setup.py
rename to plugins/hypervisors/baremetal/src/main/resources/security_group_agent/setup.py
diff --git a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java b/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java
deleted file mode 100644
index f1c8423..0000000
--- a/plugins/hypervisors/baremetal/src/org/apache/cloudstack/api/DeleteBaremetalRctCmd.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package org.apache.cloudstack.api;
-
-import com.cloud.baremetal.manager.BaremetalVlanManager;
-import com.cloud.baremetal.networkservice.BaremetalRctResponse;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-
-/**
- * Created by frank on 10/27/14.
- */
-@APICommand(name = "deleteBaremetalRct", description = "deletes baremetal rack configuration text", responseObject = SuccessResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
-public class DeleteBaremetalRctCmd extends BaseAsyncCmd {
-    private static final String s_name = "deletebaremetalrctresponse";
-    public static final Logger s_logger = Logger.getLogger(DeleteBaremetalRctCmd.class);
-
-    @Parameter(name = ApiConstants.ID,  type = BaseCmd.CommandType.UUID, description = "RCT id", required = true, entityType = BaremetalRctResponse.class)
-    private Long id;
-
-    @Inject
-    private BaremetalVlanManager vlanMgr;
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_BAREMETAL_RCT_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Deleting baremetal rct configuration";
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
-        try {
-            vlanMgr.deleteRct(this);
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } catch (Exception e) {
-            s_logger.warn(String.format("unable to add baremetal RCT[%s]", getId()), e);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
-        }
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccount().getId();
-    }
-
-    public Long getId() {
-        return id;
-    }
-}
diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml
index 02e31de..65059cc 100644
--- a/plugins/hypervisors/hyperv/pom.xml
+++ b/plugins/hypervisors/hyperv/pom.xml
@@ -1,184 +1,173 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-hypervisor-hyperv</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor Hyper-V</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <properties>
-    <skipTests>false</skipTests>
-    <skipFunctionalTests>true</skipFunctionalTests>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-      <classifier>tests</classifier>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>resources</directory>
-      </resource>
-      <resource>
-        <directory>conf</directory>
-      </resource>
-    </resources>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <configuration>
-          <executable>java</executable>
-          <mainClass>com.cloud.agent.AgentShell</mainClass>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <!-- Exclude tests that require an agent, they appear under a different profile -->
-            <excludes>
-              <exclude>**/HypervDirectConnectResourceTest.*</exclude>
-            </excludes>
-            <includes>
-              <include>none</include>
-            </includes>
-            <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>
-    <!-- Hyper-V plugin is built using mono -->
-    <profile>
-      <id>hyperv-agent</id>
-      <activation>
-        <property>
-          <name>hyperv-agent</name>
-        </property>
-      </activation>
-<!--      <dependencies>
-          <dependency>
-              <groupId>org.apache.cloudstack</groupId>
-              <artifactId>cloud-plugin-hypervisor-hyperv</artifactId>
-              <version>${project.version}</version>
-          </dependency>
-      </dependencies> --> 
-      <build>
-      <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>compile</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <executable>bash</executable>
-          <arguments>
-            <argument>./buildagent.sh</argument>
-            <argument>${skipTests}</argument>
-          </arguments>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-            <excludes>
-              <exclude>none</exclude>
-            </excludes>            
-            <includes>
-              <include>**/HypervDirectConnectResourceTest.java</include>
-            </includes>
-            <skipTests>${skipFunctionalTests}</skipTests>            
-        </configuration>
-      </plugin>
-      </plugins>
-      </build>
-    </profile>
-  </profiles>
+<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-hypervisor-hyperv</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor Hyper-V</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <properties>
+        <skipTests>false</skipTests>
+        <skipFunctionalTests>true</skipFunctionalTests>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-agent</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <configuration>
+                    <executable>java</executable>
+                    <mainClass>com.cloud.agent.AgentShell</mainClass>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <!-- Exclude tests that require an agent, they appear under a different profile -->
+                    <excludes>
+                        <exclude>**/HypervDirectConnectResourceTest.*</exclude>
+                    </excludes>
+                    <includes>
+                        <include>none</include>
+                    </includes>
+                    <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>
+        <!-- Hyper-V plugin is built using mono -->
+        <profile>
+            <id>hyperv-agent</id>
+            <activation>
+                <property>
+                    <name>hyperv-agent</name>
+                </property>
+            </activation>
+<!--
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-hypervisor-hyperv</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+-->
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <executable>bash</executable>
+                            <arguments>
+                                <argument>./buildagent.sh</argument>
+                                <argument>${skipTests}</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <excludes>
+                                <exclude>none</exclude>
+                            </excludes>
+                            <includes>
+                                <include>**/HypervDirectConnectResourceTest.java</include>
+                            </includes>
+                            <skipTests>${skipFunctionalTests}</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/ha/HypervInvestigator.java b/plugins/hypervisors/hyperv/src/com/cloud/ha/HypervInvestigator.java
deleted file mode 100644
index 222286f..0000000
--- a/plugins/hypervisors/hyperv/src/com/cloud/ha/HypervInvestigator.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.ha;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckOnHostCommand;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.AdapterBase;
-
-public class HypervInvestigator extends AdapterBase implements Investigator {
-    private final static Logger s_logger = Logger.getLogger(HypervInvestigator.class);
-    @Inject HostDao _hostDao;
-    @Inject AgentManager _agentMgr;
-    @Inject ResourceManager _resourceMgr;
-
-    @Override
-    public boolean isVmAlive(com.cloud.vm.VirtualMachine vm, Host host) throws UnknownVM {
-        Status status = isAgentAlive(host);
-        if (status == null) {
-            throw new UnknownVM();
-        }
-        return status == Status.Up ? true : null;
-    }
-
-    @Override
-    public Status isAgentAlive(Host agent) {
-        if (agent.getHypervisorType() != Hypervisor.HypervisorType.Hyperv) {
-            return null;
-        }
-        CheckOnHostCommand cmd = new CheckOnHostCommand(agent);
-        List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(agent.getClusterId(), Status.Up);
-        for (HostVO neighbor : neighbors) {
-            if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.HypervisorType.Hyperv) {
-                continue;
-            }
-
-            try {
-                Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
-                if (answer != null) {
-                    return answer.getResult() ? Status.Down : Status.Up;
-                }
-            } catch (Exception e) {
-                s_logger.debug("Failed to send command to host: " + neighbor.getId());
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
deleted file mode 100644
index 1f9ad02..0000000
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ /dev/null
@@ -1,2444 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.hyperv.resource;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.channels.SocketChannel;
-import java.nio.charset.Charset;
-import java.rmi.RemoteException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.conn.ssl.TrustStrategy;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.BasicClientConnectionManager;
-import org.apache.http.util.EntityUtils;
-import org.apache.log4j.Logger;
-import org.joda.time.Duration;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckRouterAnswer;
-import com.cloud.agent.api.CheckRouterCommand;
-import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
-import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetDomRVersionAnswer;
-import com.cloud.agent.api.GetDomRVersionCmd;
-import com.cloud.agent.api.GetVmConfigAnswer;
-import com.cloud.agent.api.GetVmConfigAnswer.NicDetails;
-import com.cloud.agent.api.GetVmConfigCommand;
-import com.cloud.agent.api.HostVmStateReportEntry;
-import com.cloud.agent.api.ModifyVmNicConfigCommand;
-import com.cloud.agent.api.NetworkUsageAnswer;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.agent.api.PlugNicAnswer;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.UnPlugNicAnswer;
-import com.cloud.agent.api.UnPlugNicCommand;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.routing.CreateIpAliasCommand;
-import com.cloud.agent.api.routing.DeleteIpAliasCommand;
-import com.cloud.agent.api.routing.DhcpEntryCommand;
-import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.api.routing.IpAssocAnswer;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SavePasswordCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetMonitorServiceCommand;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetSourceNatAnswer;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SetStaticRouteAnswer;
-import com.cloud.agent.api.routing.SetStaticRouteCommand;
-import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.VmDataCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DhcpTO;
-import com.cloud.agent.api.to.FirewallRuleTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.resource.virtualnetwork.VRScripts;
-import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.hyperv.manager.HypervManager;
-import com.cloud.network.HAProxyConfigurator;
-import com.cloud.network.LoadBalancerConfigurator;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.RouterPrivateIpStrategy;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.ssh.SshHelper;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VirtualMachineName;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
-
-/**
- * Implementation of dummy resource to be returned from discoverer.
- **/
-public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
-    public static final int DEFAULT_AGENT_PORT = 8250;
-    public static final String HOST_VM_STATE_REPORT_COMMAND = "org.apache.cloudstack.HostVmStateReportCommand";
-    private static final Logger s_logger = Logger.getLogger(HypervDirectConnectResource.class.getName());
-
-    private static final Gson s_gson = GsonHelper.getGson();
-    private String _zoneId;
-    private String _podId;
-    private String _clusterId;
-    private String _guid;
-    private String _agentIp;
-    private final int _port = DEFAULT_AGENT_PORT;
-    protected final long _opsTimeout = 900000;  // 15 minutes time out to time
-
-    protected final int _retry = 24;
-    protected final int _sleep = 10000;
-    protected static final int DEFAULT_DOMR_SSHPORT = 3922;
-    private String _clusterGuid;
-
-    // Used by initialize to assert object configured before
-    // initialize called.
-    private boolean _configureCalled = false;
-
-    private String _username;
-    private String _password;
-
-    private static HypervManager s_hypervMgr;
-    @Inject
-    HypervManager _hypervMgr;
-    protected VirtualRoutingResource _vrResource;
-
-    @PostConstruct
-    void init() {
-        s_hypervMgr = _hypervMgr;
-    }
-
-    @Override
-    public final Type getType() {
-        return Type.Routing;
-    }
-
-    @Override
-    public final StartupCommand[] initialize() {
-        // assert
-        if (!_configureCalled) {
-            final String errMsg = this.getClass().getName() + " requires configure() be called before" + " initialize()";
-            s_logger.error(errMsg);
-        }
-
-        // Create default StartupRoutingCommand, then customise
-        final StartupRoutingCommand defaultStartRoutCmd =
-                new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.Hyperv, RouterPrivateIpStrategy.HostLocal);
-
-        // Identity within the data centre is decided by CloudStack kernel,
-        // and passed via ServerResource.configure()
-        defaultStartRoutCmd.setDataCenter(_zoneId);
-        defaultStartRoutCmd.setPod(_podId);
-        defaultStartRoutCmd.setCluster(_clusterId);
-        defaultStartRoutCmd.setGuid(_guid);
-        defaultStartRoutCmd.setName(_name);
-        defaultStartRoutCmd.setPrivateIpAddress(_agentIp);
-        defaultStartRoutCmd.setStorageIpAddress(_agentIp);
-        defaultStartRoutCmd.setPool(_clusterGuid);
-
-        s_logger.debug("Generated StartupRoutingCommand for _agentIp \"" + _agentIp + "\"");
-
-        defaultStartRoutCmd.setVersion(this.getClass().getPackage().getImplementationVersion());
-
-        // Specifics of the host's resource capacity and network configuration
-        // comes from the host itself. CloudStack sanity checks network
-        // configuration
-        // and uses capacity info for resource allocation.
-        final Command[] startCmds = requestStartupCommand(new Command[] {defaultStartRoutCmd});
-
-        // TODO: may throw, is this okay?
-        final StartupRoutingCommand startCmd = (StartupRoutingCommand)startCmds[0];
-
-        // Assert that host identity is consistent with existing values.
-        if (startCmd == null) {
-            final String errMsg = String.format("Host %s (IP %s)" + "did not return a StartupRoutingCommand", _name, _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getDataCenter().equals(defaultStartRoutCmd.getDataCenter())) {
-            final String errMsg =
-                    String.format("Host %s (IP %s) changed zone/data center.  Was " + defaultStartRoutCmd.getDataCenter() + " NOW its " + startCmd.getDataCenter(), _name,
-                            _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getPod().equals(defaultStartRoutCmd.getPod())) {
-            final String errMsg = String.format("Host %s (IP %s) changed pod.  Was " + defaultStartRoutCmd.getPod() + " NOW its " + startCmd.getPod(), _name, _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getCluster().equals(defaultStartRoutCmd.getCluster())) {
-            final String errMsg =
-                    String.format("Host %s (IP %s) changed cluster.  Was " + defaultStartRoutCmd.getCluster() + " NOW its " + startCmd.getCluster(), _name, _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getGuid().equals(defaultStartRoutCmd.getGuid())) {
-            final String errMsg = String.format("Host %s (IP %s) changed guid.  Was " + defaultStartRoutCmd.getGuid() + " NOW its " + startCmd.getGuid(), _name, _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getPrivateIpAddress().equals(defaultStartRoutCmd.getPrivateIpAddress())) {
-            final String errMsg =
-                    String.format("Host %s (IP %s) IP address.  Was " + defaultStartRoutCmd.getPrivateIpAddress() + " NOW its " + startCmd.getPrivateIpAddress(), _name,
-                            _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-        if (!startCmd.getName().equals(defaultStartRoutCmd.getName())) {
-            final String errMsg = String.format("Host %s (IP %s) name.  Was " + startCmd.getName() + " NOW its " + defaultStartRoutCmd.getName(), _name, _agentIp);
-            s_logger.error(errMsg);
-            // TODO: valid to return null, or should we throw?
-            return null;
-        }
-
-        // Host will also supply details of an existing StoragePool if it has
-        // been configured with one.
-        //
-        // NB: if the host was configured
-        // with a local storage pool, CloudStack may not be able to use it
-        // unless
-        // it is has service offerings configured to recognise this storage
-        // type.
-        StartupStorageCommand storePoolCmd = null;
-        if (startCmds.length > 1) {
-            storePoolCmd = (StartupStorageCommand)startCmds[1];
-            // TODO: is this assertion required?
-            if (storePoolCmd == null) {
-                final String frmtStr = "Host %s (IP %s) sent incorrect Command, " + "second parameter should be a " + "StartupStorageCommand";
-                final String errMsg = String.format(frmtStr, _name, _agentIp);
-                s_logger.error(errMsg);
-                // TODO: valid to return null, or should we throw?
-                return null;
-            }
-            s_logger.info("Host " + _name + " (IP " + _agentIp + ") already configured with a storeage pool, details " + s_gson.toJson(startCmds[1]));
-        } else {
-            s_logger.info("Host " + _name + " (IP " + _agentIp + ") already configured with a storeage pool, details ");
-        }
-        return new StartupCommand[] {startCmd, storePoolCmd};
-    }
-
-    @Override
-    public final PingCommand getCurrentStatus(final long id) {
-        final PingCommand pingCmd = new PingRoutingCommand(getType(), id, getHostVmStateReport());
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Ping host " + _name + " (IP " + _agentIp + ")");
-        }
-
-        final Answer pingAns = executeRequest(pingCmd);
-
-        if (pingAns == null || !pingAns.getResult()) {
-            s_logger.info("Cannot ping host " + _name + " (IP " + _agentIp + "), pingAns (blank means null) is:" + pingAns);
-            return null;
-        }
-        return pingCmd;
-    }
-
-    public final ArrayList<Map<String, String>> requestHostVmStateReport() {
-        URI agentUri = null;
-        try {
-            agentUri = new URI("https", null, _agentIp, _port, "/api/HypervResource/" + HOST_VM_STATE_REPORT_COMMAND, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-            return null;
-        }
-        final String incomingCmd = postHttpRequest("{}", agentUri);
-
-        if (incomingCmd == null) {
-            return null;
-        }
-        ArrayList<Map<String, String>> result = null;
-        try {
-            result = s_gson.fromJson(incomingCmd, new TypeToken<ArrayList<HashMap<String, String>>>() {
-            }.getType());
-        } catch (final Exception ex) {
-            final String errMsg = "Failed to deserialize Command[] " + incomingCmd;
-            s_logger.error(errMsg, ex);
-        }
-        s_logger.debug("HostVmStateReportCommand received response "
-                + s_gson.toJson(result));
-        if (result != null) {
-            if (!result.isEmpty()) {
-                return result;
-            } else {
-                return new ArrayList<Map<String, String>>();
-            }
-        }
-        return null;
-    }
-
-    protected HashMap<String, HostVmStateReportEntry> getHostVmStateReport() {
-        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
-        final ArrayList<Map<String, String>> vmList = requestHostVmStateReport();
-        if (vmList == null) {
-            return null;
-        }
-
-        for (final Map<String, String> vmMap : vmList) {
-            final String name = (String)vmMap.keySet().toArray()[0];
-            vmStates.put(name, new HostVmStateReportEntry(PowerState.valueOf(vmMap.get(name)), _guid));
-        }
-        return vmStates;
-    }
-
-    // TODO: Is it valid to return NULL, or should we throw on error?
-    // Returns StartupCommand with fields revised with values known only to the
-    // host
-    public final Command[] requestStartupCommand(final Command[] cmd) {
-        // Set HTTP POST destination URI
-        // Using java.net.URI, see
-        // http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
-        URI agentUri = null;
-        try {
-            final String cmdName = StartupCommand.class.getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            // TODO add proper logging
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-            return null;
-        }
-        final String incomingCmd = postHttpRequest(s_gson.toJson(cmd), agentUri);
-
-        if (incomingCmd == null) {
-            return null;
-        }
-        Command[] result = null;
-        try {
-            result = s_gson.fromJson(incomingCmd, Command[].class);
-        } catch (final Exception ex) {
-            final String errMsg = "Failed to deserialize Command[] " + incomingCmd;
-            s_logger.error(errMsg, ex);
-        }
-        s_logger.debug("requestStartupCommand received response " + s_gson.toJson(result));
-        if (result.length > 0) {
-            return result;
-        }
-        return null;
-    }
-
-    // TODO: Is it valid to return NULL, or should we throw on error?
-    @Override
-    public final Answer executeRequest(final Command cmd) {
-        // Set HTTP POST destination URI
-        // Using java.net.URI, see
-        // http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
-        URI agentUri = null;
-        final Class<? extends Command> clazz = cmd.getClass();
-        Answer answer = null;
-        try {
-            final String cmdName = cmd.getClass().getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            // TODO add proper logging
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-            return null;
-        }
-        if (cmd instanceof NetworkElementCommand) {
-            return _vrResource.executeRequest((NetworkElementCommand)cmd);
-        }if (clazz == CheckSshCommand.class) {
-            answer = execute((CheckSshCommand)cmd);
-        } else if (clazz == GetDomRVersionCmd.class) {
-            answer = execute((GetDomRVersionCmd)cmd);
-        } else if (cmd instanceof NetworkUsageCommand) {
-            answer = execute((NetworkUsageCommand)cmd);
-        } else if (clazz == IpAssocCommand.class) {
-            answer = execute((IpAssocCommand)cmd);
-        } else if (clazz == DnsMasqConfigCommand.class) {
-            return execute((DnsMasqConfigCommand)cmd);
-        } else if (clazz == CreateIpAliasCommand.class) {
-            return execute((CreateIpAliasCommand)cmd);
-        } else if (clazz == DhcpEntryCommand.class) {
-            answer = execute((DhcpEntryCommand)cmd);
-        } else if (clazz == VmDataCommand.class) {
-            answer = execute((VmDataCommand)cmd);
-        } else if (clazz == SavePasswordCommand.class) {
-            answer = execute((SavePasswordCommand)cmd);
-        } else if (clazz == SetFirewallRulesCommand.class) {
-            answer = execute((SetFirewallRulesCommand)cmd);
-        } else if (clazz == LoadBalancerConfigCommand.class) {
-            answer = execute((LoadBalancerConfigCommand)cmd);
-        } else if (clazz == DeleteIpAliasCommand.class) {
-            return execute((DeleteIpAliasCommand)cmd);
-        } else if (clazz == PingTestCommand.class) {
-            answer = execute((PingTestCommand)cmd);
-        } else if (clazz == SetStaticNatRulesCommand.class) {
-            answer = execute((SetStaticNatRulesCommand)cmd);
-        } else if (clazz == CheckRouterCommand.class) {
-            answer = execute((CheckRouterCommand)cmd);
-        } else if (clazz == SetPortForwardingRulesCommand.class) {
-            answer = execute((SetPortForwardingRulesCommand)cmd);
-        } else if (clazz == SetSourceNatCommand.class) {
-            answer = execute((SetSourceNatCommand)cmd);
-        } else if (clazz == Site2SiteVpnCfgCommand.class) {
-            answer = execute((Site2SiteVpnCfgCommand)cmd);
-        } else if (clazz == CheckS2SVpnConnectionsCommand.class) {
-            answer = execute((CheckS2SVpnConnectionsCommand) cmd);
-        } else if (clazz == RemoteAccessVpnCfgCommand.class) {
-            answer = execute((RemoteAccessVpnCfgCommand) cmd);
-        } else if (clazz == VpnUsersCfgCommand.class) {
-            answer = execute((VpnUsersCfgCommand) cmd);
-        } else if (clazz == SetStaticRouteCommand.class) {
-            answer = execute((SetStaticRouteCommand) cmd);
-        } else if (clazz == SetMonitorServiceCommand.class) {
-            answer = execute((SetMonitorServiceCommand) cmd);
-        } else if (clazz == PlugNicCommand.class) {
-            answer = execute((PlugNicCommand)cmd);
-        } else if (clazz == UnPlugNicCommand.class) {
-            answer = execute((UnPlugNicCommand)cmd);
-        } else if (clazz == CopyCommand.class) {
-            answer = execute((CopyCommand)cmd);
-        }
-        else {
-            if (clazz == StartCommand.class) {
-                final VirtualMachineTO vmSpec = ((StartCommand)cmd).getVirtualMachine();
-                if (vmSpec.getType() != VirtualMachine.Type.User) {
-                    if (s_hypervMgr != null) {
-                        final String secondary = s_hypervMgr.prepareSecondaryStorageStore(Long.parseLong(_zoneId));
-                        if (secondary != null) {
-                            ((StartCommand)cmd).setSecondaryStorage(secondary);
-                        }
-                    } else {
-                        s_logger.error("Hyperv manager isn't available. Couldn't check and copy the systemvm iso.");
-                    }
-                }
-            }
-
-            // Send the cmd to hyperv agent.
-            final String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
-            if (ansStr == null) {
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-            // Only Answer instances are returned by remote agents.
-            // E.g. see Response.getAnswers()
-            final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-            final String logResult = cleanPassword(s_gson.toJson(result));
-            s_logger.debug("executeRequest received response " + logResult);
-            if (result.length > 0) {
-                return result[0];
-            }
-        }
-        return answer;
-    }
-
-    private Answer execute(final CopyCommand cmd) {
-        URI agentUri = null;
-        try {
-            final String cmdName = cmd.getClass().getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-            return null;
-        }
-        cleanPassword(cmd.getSrcTO().getDataStore());
-        cleanPassword(cmd.getDestTO().getDataStore());
-
-        // Send the cmd to hyperv agent.
-        final String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
-        if (ansStr == null) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-
-        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-        final String logResult = cleanPassword(s_gson.toJson(result));
-        s_logger.debug("executeRequest received response " + logResult);
-        if (result.length > 0) {
-            return result[0];
-        }
-
-        return null;
-    }
-
-    private void cleanPassword(final DataStoreTO dataStoreTO) {
-        if (dataStoreTO instanceof NfsTO) {
-            final NfsTO nfsTO = (NfsTO)dataStoreTO;
-            final String url = nfsTO.getUrl();
-            if (url.contains("cifs") && url.contains("password")) {
-                nfsTO.setUrl(url.substring(0, url.indexOf('?')));
-            }
-        }
-    }
-
-    private PlugNicAnswer execute(final PlugNicCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PlugNicCommand " + s_gson.toJson(cmd));
-        }
-
-        try {
-
-            final String vmName = cmd.getVmName();
-            final NicTO nic = cmd.getNic();
-            final URI broadcastUri = nic.getBroadcastUri();
-            if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-                throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + nic.getBroadcastUri());
-            }
-            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-            int publicNicInfo = -1;
-            publicNicInfo = getVmFreeNicIndex(vmName);
-            if (publicNicInfo > 0) {
-                modifyNicVlan(vmName, vlanId, publicNicInfo, true, cmd.getNic().getName());
-                return new PlugNicAnswer(cmd, true, "success");
-            }
-            final String msg = " Plug Nic failed for the vm as it has reached max limit of NICs to be added";
-            s_logger.warn(msg);
-            return new PlugNicAnswer(cmd, false, msg);
-
-        } catch (final Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
-        }
-    }
-
-
-    private UnPlugNicAnswer execute(final UnPlugNicCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource UnPlugNicCommand " + s_gson.toJson(cmd));
-        }
-
-        try {
-            final String vmName = cmd.getVmName();
-            final NicTO nic = cmd.getNic();
-            final URI broadcastUri = nic.getBroadcastUri();
-            if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-                throw new InternalErrorException("Unable to unassign a public IP to a VIF on network " + nic.getBroadcastUri());
-            }
-            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-            int publicNicInfo = -1;
-            publicNicInfo = getVmNics(vmName, vlanId);
-            if (publicNicInfo > 0) {
-                modifyNicVlan(vmName, "2", publicNicInfo, false, "");
-            }
-            return new UnPlugNicAnswer(cmd, true, "success");
-        } catch (final Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString());
-        }
-    }
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIP, final String script, final String args) {
-        return executeInVR(routerIP, script, args, Duration.standardSeconds(120L));
-    }
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) {
-        Pair<Boolean, String> result;
-
-        //TODO: Password should be masked, cannot output to log directly
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args);
-        }
-
-        try {
-            result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args, VRScripts.CONNECTION_TIMEOUT,
-                    VRScripts.CONNECTION_TIMEOUT, timeout);
-        } catch (final Exception e) {
-            final String msg = "Command failed due to " + e ;
-            s_logger.error(msg);
-            result = new Pair<Boolean, String>(false, msg);
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(script + " execution result: " + result.first().toString());
-        }
-        return new ExecutionResult(result.first(), result.second());
-    }
-
-    @Override
-    public ExecutionResult createFileInVR(final String routerIp, final String filePath, final String fileName, final String content) {
-        final File keyFile = getSystemVMKeyFile();
-        try {
-            SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(Charset.forName("UTF-8")), fileName, null);
-        } catch (final Exception e) {
-            s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
-        //Update IP used to access router
-        cmd.setRouterAccessIp(getRouterSshControlIp(cmd));
-        assert cmd.getRouterAccessIp() != null;
-
-        if (cmd instanceof IpAssocVpcCommand) {
-            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
-        } else if (cmd instanceof IpAssocCommand) {
-            return prepareNetworkElementCommand((IpAssocCommand)cmd);
-        } else if (cmd instanceof SetSourceNatCommand) {
-            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
-        } else if (cmd instanceof SetupGuestNetworkCommand) {
-            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
-        } else if (cmd instanceof SetNetworkACLCommand) {
-            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
-        try {
-
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-            final String controlIp = getRouterSshControlIp(cmd);
-
-            for (final IpAddressTO ip : ips) {
-                /**
-                 * TODO support other networks
-                 */
-                final URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-                    throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri());
-                }
-                final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-                int publicNicInfo = -1;
-                publicNicInfo = getVmNics(routerName, vlanId);
-
-                boolean addVif = false;
-                if (ip.isAdd() && publicNicInfo == -1) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp());
-                    }
-                    addVif = true;
-                }
-
-                if (addVif) {
-                    final Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(controlIp);
-                    publicNicInfo = nicdevice.first();
-                    if (publicNicInfo > 0) {
-                        modifyNicVlan(routerName, vlanId, nicdevice.second());
-                        // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
-                        publicNicInfo = getVmNics(routerName, vlanId);
-                        // As a new nic got activated in the VR. add the entry in the NIC's table.
-                        networkUsage(controlIp, "addVif", "eth" + publicNicInfo);
-                    }
-                    else {
-                        // we didn't find any eth device available in VR to configure the ip range with new VLAN
-                        final String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
-                        s_logger.error(msg);
-                        throw new InternalErrorException(msg);
-                    }
-                    ip.setNicDevId(publicNicInfo);
-                    ip.setNewNic(addVif);
-                } else {
-                    ip.setNicDevId(publicNicInfo);
-                }
-            }
-        } catch (final Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
-            return new ExecutionResult(false, e.toString());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
-        final NicTO nic = cmd.getNic();
-        final String domrName =
-                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            final URI broadcastUri = nic.getBroadcastUri();
-            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-            final int ethDeviceNum = getVmNics(domrName, vlanId);
-            if (ethDeviceNum > 0) {
-                nic.setDeviceId(ethDeviceNum);
-            } else {
-                return new ExecutionResult(false, "Prepare SetupGuestNetwork failed due to unable to find the nic");
-            }
-        } catch (final Exception e) {
-            final String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-
-    private ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            for (final IpAddressTO ip : ips) {
-                final URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-                    throw new InternalErrorException("Invalid Broadcast URI " + ip.getBroadcastUri());
-                }
-                final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-                int publicNicInfo = -1;
-                publicNicInfo = getVmNics(routerName, vlanId);
-                if (publicNicInfo < 0) {
-                    if (ip.isAdd()) {
-                        throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
-                    } else {
-                        s_logger.debug("VIF to deassociate IP with does not exist, return success");
-                        continue;
-                    }
-                }
-
-                ip.setNicDevId(publicNicInfo);
-            }
-        } catch (final Exception e) {
-            s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.toString());
-        }
-
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final IpAddressTO pubIp = cmd.getIpAddress();
-
-        try {
-            final String broadcastUri = pubIp.getBroadcastUri();
-            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-            final int ethDeviceNum = getVmNics(routerName, vlanId);
-            if (ethDeviceNum > 0) {
-                pubIp.setNicDevId(ethDeviceNum);
-            } else {
-                return new ExecutionResult(false, "Prepare Ip SNAT failed due to unable to find the nic");
-            }
-        } catch (final Exception e) {
-            final String msg = "Prepare Ip SNAT failure due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, e.toString());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) {
-        final NicTO nic = cmd.getNic();
-        final String routerName =
-                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            final URI broadcastUri = nic.getBroadcastUri();
-            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-            final int ethDeviceNum = getVmNics(routerName, vlanId);
-            if (ethDeviceNum > 0) {
-                nic.setDeviceId(ethDeviceNum);
-            } else {
-                return new ExecutionResult(false, "Prepare SetNetworkACL failed due to unable to find the nic");
-            }
-        } catch (final Exception e) {
-            final String msg = "Prepare SetNetworkACL failed due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
-        return new ExecutionResult(true, null);
-    }
-
-    protected Answer execute(final RemoteAccessVpnCfgCommand cmd) {
-        final String controlIp = getRouterSshControlIp(cmd);
-        final StringBuffer argsBuf = new StringBuffer();
-        if (cmd.isCreate()) {
-            argsBuf.append(" -r ").append(cmd.getIpRange()).append(" -p ").append(cmd.getPresharedKey()).append(" -s ").append(cmd.getVpnServerIp()).append(" -l ").append(cmd.getLocalIp())
-            .append(" -c ");
-
-        } else {
-            argsBuf.append(" -d ").append(" -s ").append(cmd.getVpnServerIp());
-        }
-        argsBuf.append(" -C ").append(cmd.getLocalCidr());
-        argsBuf.append(" -i ").append(cmd.getPublicInterface());
-
-        try {
-            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPN_L2TP, argsBuf.toString());
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Executing " + command);
-            }
-
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("RemoteAccessVpnCfg command on domR failed, message: " + result.second());
-
-                return new Answer(cmd, false, "RemoteAccessVpnCfg command failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("RemoteAccessVpnCfg command on domain router " + argsBuf.toString() + " completed");
-            }
-
-        } catch (final Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn(e.getMessage());
-            }
-
-            final String msg = "RemoteAccessVpnCfg command failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(final VpnUsersCfgCommand cmd) {
-
-        final String controlIp = getRouterSshControlIp(cmd);
-        for (final VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) {
-            final StringBuffer argsBuf = new StringBuffer();
-            if (!userpwd.isAdd()) {
-                argsBuf.append(" -U ").append(userpwd.getUsername());
-            } else {
-                argsBuf.append(" -u ").append(userpwd.getUsernamePassword());
-            }
-
-            try {
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh ");
-                }
-
-                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString());
-
-                if (!result.first()) {
-                    s_logger.error("VpnUserCfg command on domR failed, message: " + result.second());
-
-                    return new Answer(cmd, false, "VpnUserCfg command failed due to " + result.second());
-                }
-            } catch (final Throwable e) {
-                if (e instanceof RemoteException) {
-                    s_logger.warn(e.getMessage());
-                }
-
-                final String msg = "VpnUserCfg command failed due to " + e.getMessage();
-                s_logger.error(msg, e);
-                return new Answer(cmd, false, msg);
-            }
-        }
-
-        return new Answer(cmd);
-    }
-    private SetStaticRouteAnswer execute(final SetStaticRouteCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetStaticRouteCommand: " + s_gson.toJson(cmd));
-        }
-
-        boolean endResult = true;
-
-        final String controlIp = getRouterSshControlIp(cmd);
-        String args = "";
-        final String[] results = new String[cmd.getStaticRoutes().length];
-        int i = 0;
-
-        // Extract and build the arguments for the command to be sent to the VR.
-        final String[] rules = cmd.generateSRouteRules();
-        final StringBuilder sb = new StringBuilder();
-
-        for (int j = 0; j < rules.length; j++) {
-            sb.append(rules[j]).append(',');
-        }
-        args += " -a " + sb.toString();
-
-        final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPC_STATIC_ROUTE, args);
-
-        // Send over the command for execution, via ssh, to the VR.
-        try {
-            final Pair<Boolean, String> result =
-                    SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticroute.sh " + args);
-            }
-
-            if (!result.first()) {
-                s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args);
-                results[i++] = "Failed";
-                endResult = false;
-            } else {
-                results[i++] = null;
-            }
-        } catch (final Throwable e) {
-            s_logger.error("SetStaticRouteCommand(args: " + args + ") failed on setting one rule due to " + e);
-            results[i++] = "Failed";
-            endResult = false;
-        }
-        return new SetStaticRouteAnswer(cmd, endResult, results);
-
-    }
-
-    protected CheckS2SVpnConnectionsAnswer execute(final CheckS2SVpnConnectionsCommand cmd) {
-        final StringBuilder cmdline = new StringBuilder();
-        cmdline.append("/opt/cloud/bin/");
-        cmdline.append(VRScripts.S2SVPN_CHECK);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + s_gson.toJson(cmd));
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + cmdline.toString());
-        }
-
-        Pair<Boolean, String> result;
-        try {
-            final String controlIp = getRouterSshControlIp(cmd);
-            for (final String ip : cmd.getVpnIps()) {
-                cmdline.append(" ");
-                cmdline.append(ip);
-            }
-
-            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, cmdline.toString());
-
-            if (!result.first()) {
-                s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " +
-                        result.second());
-
-                return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second());
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "CheckS2SVpnConnectionsCommand failed due to " + e;
-            s_logger.error(msg, e);
-            return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed");
-        }
-        return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second());
-    }
-
-    protected Answer execute(final Site2SiteVpnCfgCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource Site2SiteVpnCfgCommand " + s_gson.toJson(cmd));
-        }
-
-        final String routerIp = getRouterSshControlIp(cmd);
-
-        String args = "";
-        if (cmd.isCreate()) {
-            args += " -A";
-            args += " -l ";
-            args += cmd.getLocalPublicIp();
-            args += " -n ";
-            args += cmd.getLocalGuestCidr();
-            args += " -g ";
-            args += cmd.getLocalPublicGateway();
-            args += " -r ";
-            args += cmd.getPeerGatewayIp();
-            args += " -N ";
-            args += cmd.getPeerGuestCidrList();
-            args += " -e ";
-            args += "\"" + cmd.getEspPolicy() + "\"";
-            args += " -i ";
-            args += "\"" + cmd.getIkePolicy() + "\"";
-            args += " -t ";
-            args += Long.toString(cmd.getIkeLifetime());
-            args += " -T ";
-            args += Long.toString(cmd.getEspLifetime());
-            args += " -s ";
-            args += "\"" + cmd.getIpsecPsk() + "\"";
-            args += " -d ";
-            if (cmd.getDpd()) {
-                args += "1";
-            } else {
-                args += "0";
-            }
-        } else {
-            args += " -D";
-            args += " -r ";
-            args += cmd.getPeerGatewayIp();
-            args += " -n ";
-            args += cmd.getLocalGuestCidr();
-            args += " -N ";
-            args += cmd.getPeerGuestCidrList();
-        }
-
-        Pair<Boolean, String> result;
-        try {
-            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.S2SVPN_IPSEC, args);
-            result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
-
-                return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.second());
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "Setup site2site VPN falied due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, "Setup site2site VPN failed due to " + e.getMessage());
-        }
-        return new Answer(cmd, true, result.second());
-    }
-
-    protected SetSourceNatAnswer execute(final SetSourceNatCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetSourceNatCommand " + s_gson.toJson(cmd));
-        }
-
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final String routerIp = getRouterSshControlIp(cmd);
-        final IpAddressTO pubIp = cmd.getIpAddress();
-        try {
-            final int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
-            String args = "";
-            args += " -A ";
-            args += " -l ";
-            args += pubIp.getPublicIp();
-
-            args += " -c ";
-            args += "eth" + ethDeviceNum;
-
-            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPC_SOURCE_NAT, args);
-
-            final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                final String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second();
-                s_logger.error(msg);
-
-                return new SetSourceNatAnswer(cmd, false, msg);
-            }
-
-            return new SetSourceNatAnswer(cmd, true, "success");
-        } catch (final Exception e) {
-            final String msg = "Ip SNAT failure due to " + e.toString();
-            s_logger.error(msg, e);
-            return new SetSourceNatAnswer(cmd, false, msg);
-        }
-    }
-
-    protected Answer execute(final SetPortForwardingRulesCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd));
-        }
-
-        final String controlIp = getRouterSshControlIp(cmd);
-        String args = "";
-        final String[] results = new String[cmd.getRules().length];
-        int i = 0;
-
-        boolean endResult = true;
-        for (final PortForwardingRuleTO rule : cmd.getRules()) {
-            args += rule.revoked() ? " -D " : " -A ";
-            args += " -P " + rule.getProtocol().toLowerCase();
-            args += " -l " + rule.getSrcIp();
-            args += " -p " + rule.getStringSrcPortRange();
-            args += " -r " + rule.getDstIp();
-            args += " -d " + rule.getStringDstPortRange();
-
-            try {
-                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall.sh " + args);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args);
-                }
-
-                if (!result.first()) {
-                    s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args);
-                    results[i++] = "Failed";
-                    endResult = false;
-                } else {
-                    results[i++] = null;
-                }
-            } catch (final Throwable e) {
-                s_logger.error("SetPortForwardingRulesCommand(args: " + args + ") failed on setting one rule due to " + e.getMessage());
-                results[i++] = "Failed";
-                endResult = false;
-            }
-        }
-
-        return new SetPortForwardingRulesAnswer(cmd, results, endResult);
-    }
-
-    protected Answer execute(final CheckRouterCommand cmd) {
-        final String command = String.format("%s%s", "/opt/cloud/bin/", VRScripts.RVR_CHECK);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Executing resource CheckRouterCommand: " + s_gson.toJson(cmd));
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
-        }
-
-        Pair<Boolean, String> result;
-        try {
-
-            final String controlIp = getRouterSshControlIp(cmd);
-            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("check router command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
-
-                return new CheckRouterAnswer(cmd, "CheckRouter failed due to " + result.second());
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("check router command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "CheckRouterCommand failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new CheckRouterAnswer(cmd, msg);
-        }
-        return new CheckRouterAnswer(cmd, result.second(), true);
-    }
-
-    protected Answer execute(final SetStaticNatRulesCommand cmd) {
-
-        if (cmd.getVpcId() != null) {
-            //return SetVPCStaticNatRules(cmd);
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetFirewallRuleCommand: " + s_gson.toJson(cmd));
-        }
-
-        String args = null;
-        final String[] results = new String[cmd.getRules().length];
-        int i = 0;
-        boolean endResult = true;
-        for (final StaticNatRuleTO rule : cmd.getRules()) {
-            // 1:1 NAT needs instanceip;publicip;domrip;op
-            args = rule.revoked() ? " -D " : " -A ";
-
-            args += " -l " + rule.getSrcIp();
-            args += " -r " + rule.getDstIp();
-
-            if (rule.getProtocol() != null) {
-                args += " -P " + rule.getProtocol().toLowerCase();
-            }
-
-            args += " -d " + rule.getStringSrcPortRange();
-            args += " -G ";
-
-            try {
-                final String controlIp = getRouterSshControlIp(cmd);
-                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall.sh " + args);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args);
-                }
-
-                if (!result.first()) {
-                    s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args);
-                    results[i++] = "Failed";
-                    endResult = false;
-                } else {
-                    results[i++] = null;
-                }
-            } catch (final Throwable e) {
-                s_logger.error("SetStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + e.getMessage());
-                results[i++] = "Failed";
-                endResult = false;
-            }
-        }
-        return new SetStaticNatRulesAnswer(cmd, results, endResult);
-    }
-
-    protected Answer execute(final PingTestCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PingTestCommand: " + s_gson.toJson(cmd));
-        }
-        final String controlIp = cmd.getRouterIp();
-        final String args = " -c 1 -n -q " + cmd.getPrivateIp();
-        try {
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/bin/ping" + args);
-            if (result.first()) {
-                return new Answer(cmd);
-            }
-        } catch (final Exception e) {
-            s_logger.error("Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + e.getMessage());
-        }
-        return new Answer(cmd, false, "PingTestCommand failed");
-    }
-
-    protected Answer execute(final DeleteIpAliasCommand cmd) {
-        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final List<IpAliasTO> revokedIpAliasTOs = cmd.getDeleteIpAliasTos();
-        final List<IpAliasTO> activeIpAliasTOs = cmd.getCreateIpAliasTos();
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing deleteIpAlias command: " + s_gson.toJson(cmd));
-        }
-        final StringBuilder args = new StringBuilder();
-        for (final IpAliasTO ipAliasTO : revokedIpAliasTOs) {
-            args.append(ipAliasTO.getAlias_count());
-            args.append(":");
-            args.append(ipAliasTO.getRouterip());
-            args.append(":");
-            args.append(ipAliasTO.getNetmask());
-            args.append("-");
-        }
-        args.append("- ");
-        for (final IpAliasTO ipAliasTO : activeIpAliasTOs) {
-            args.append(ipAliasTO.getAlias_count());
-            args.append(":");
-            args.append(ipAliasTO.getRouterip());
-            args.append(":");
-            args.append(ipAliasTO.getNetmask());
-            args.append("-");
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/deleteIpAlias " + args);
-        }
-
-        try {
-            final String controlIp = getRouterSshControlIp(cmd);
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/deleteIpAlias.sh " + args);
-
-            if (!result.first()) {
-                s_logger.error("deleteIpAlias command on domr " + controlIp + " failed, message: " + result.second());
-
-                return new Answer(cmd, false, "deleteIpAlias failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("deleteIpAlias command on domain router " + controlIp + " completed");
-            }
-
-        } catch (final Throwable e) {
-            final String msg = "deleteIpAlias failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(final LoadBalancerConfigCommand cmd) {
-
-        if (cmd.getVpcId() != null) {
-            //return VPCLoadBalancerConfig(cmd);
-        }
-
-        final File keyFile = getSystemVMKeyFile();
-
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final String controlIp = getRouterSshControlIp(cmd);
-
-        assert controlIp != null;
-
-        final LoadBalancerConfigurator cfgtr = new HAProxyConfigurator();
-        final String[] config = cfgtr.generateConfiguration(cmd);
-
-        final String[][] rules = cfgtr.generateFwRules(cmd);
-        final String tmpCfgFilePath = "/tmp/" + routerIp.replace('.', '_') + ".cfg";
-        final StringBuilder tmpCfgFileContents = new StringBuilder();
-        for (int i = 0; i < config.length; i++) {
-            tmpCfgFileContents.append(config[i]);
-            tmpCfgFileContents.append("\n");
-        }
-
-        try {
-            SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", keyFile, null, "/tmp/", tmpCfgFileContents.toString().getBytes(Charset.forName("UTF-8")), routerIp.replace('.', '_') +
-                    ".cfg", null);
-
-            try {
-                final String[] addRules = rules[LoadBalancerConfigurator.ADD];
-                final String[] removeRules = rules[LoadBalancerConfigurator.REMOVE];
-                final String[] statRules = rules[LoadBalancerConfigurator.STATS];
-
-                String args = "";
-                args += "-i " + routerIp;
-                args += " -f " + tmpCfgFilePath;
-
-                StringBuilder sb = new StringBuilder();
-                if (addRules.length > 0) {
-                    for (int i = 0; i < addRules.length; i++) {
-                        sb.append(addRules[i]).append(',');
-                    }
-
-                    args += " -a " + sb.toString();
-                }
-
-                sb = new StringBuilder();
-                if (removeRules.length > 0) {
-                    for (int i = 0; i < removeRules.length; i++) {
-                        sb.append(removeRules[i]).append(',');
-                    }
-
-                    args += " -d " + sb.toString();
-                }
-
-                sb = new StringBuilder();
-                if (statRules.length > 0) {
-                    for (int i = 0; i < statRules.length; i++) {
-                        sb.append(statRules[i]).append(',');
-                    }
-
-                    args += " -s " + sb.toString();
-                }
-
-                Pair<Boolean, String> result =
-                        SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "scp " + tmpCfgFilePath + " /etc/haproxy/haproxy.cfg.new");
-
-                if (!result.first()) {
-                    s_logger.error("Unable to copy haproxy configuration file");
-                    return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to unable to copy haproxy configuration file");
-                }
-
-                final String command = String.format("%s%s %s", "/root/", VRScripts.LB, args);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Run command on domain router " + routerIp + command);
-                }
-
-                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-                if (!result.first()) {
-                    final String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second();
-                    s_logger.error(msg);
-
-                    return new Answer(cmd, false, msg);
-                }
-
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed");
-                }
-            } finally {
-                SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm " + tmpCfgFilePath);
-            }
-
-            return new Answer(cmd);
-        } catch (final Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString(), e);
-            return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + e.getMessage());
-        }
-    }
-
-    protected Answer execute(final SavePasswordCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-
-            s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " +
-                    StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
-        }
-
-        final String controlIp = getRouterSshControlIp(cmd);
-        final String password = cmd.getPassword();
-        final String vmIpAddress = cmd.getVmIpAddress();
-
-        // Run save_password_to_domr.sh
-        final String command = String.format("%s%s %s %s %s %s", "/opt/cloud/bin/", VRScripts.PASSWORD, "-v", vmIpAddress, "-p", password);
-
-        if (s_logger.isDebugEnabled()) {
-            final String debugCommand = String.format("%s%s %s %s %s %s", "/opt/cloud/bin/", VRScripts.PASSWORD, "-v", vmIpAddress, "-p", StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
-            s_logger.debug("Run command on domain router " + controlIp + debugCommand);
-        }
-
-        try {
-
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second());
-
-                return new Answer(cmd, false, "SavePassword failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("savepassword command on domain router " + controlIp + " completed");
-            }
-
-        } catch (final Throwable e) {
-            final String msg = "SavePasswordCommand failed due to " + e;
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-        return new Answer(cmd);
-    }
-
-    protected SetFirewallRulesAnswer execute(final SetFirewallRulesCommand cmd) {
-        final String controlIp = getRouterSshControlIp(cmd);
-        final String[] results = new String[cmd.getRules().length];
-        final FirewallRuleTO[] allrules = cmd.getRules();
-        final FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
-        final String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT);
-
-        final String[][] rules = cmd.generateFwRules();
-        String args = "";
-        args += " -F ";
-        if (trafficType == FirewallRule.TrafficType.Egress) {
-            args += " -E ";
-            if (egressDefault.equals("true")) {
-                args += " -P 1 ";
-            } else if (egressDefault.equals("System")) {
-                args += " -P 2 ";
-            } else {
-                args += " -P 0 ";
-            }
-        }
-
-        final StringBuilder sb = new StringBuilder();
-        final String[] fwRules = rules[0];
-        if (fwRules.length > 0) {
-            for (int i = 0; i < fwRules.length; i++) {
-                sb.append(fwRules[i]).append(',');
-            }
-            args += " -a " + sb.toString();
-        }
-
-        try {
-            Pair<Boolean, String> result = null;
-
-            if (trafficType == FirewallRule.TrafficType.Egress) {
-                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewallRule_egress.sh " + args);
-            } else {
-                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall_rule.sh " + args);
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                if (trafficType == FirewallRule.TrafficType.Egress) {
-                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewallRule_egress.sh " + args);
-                } else {
-                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall_rule.sh " + args);
-                }
-            }
-
-            if (!result.first()) {
-                s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args);
-                //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails
-                for (int i = 0; i < results.length; i++) {
-                    results[i] = "Failed";
-                }
-
-                return new SetFirewallRulesAnswer(cmd, false, results);
-            }
-        } catch (final Throwable e) {
-            s_logger.error("SetFirewallRulesCommand(args: " + args + ") failed on setting one rule due to ", e);
-            //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails
-            for (int i = 0; i < results.length; i++) {
-                results[i] = "Failed";
-            }
-            return new SetFirewallRulesAnswer(cmd, false, results);
-        }
-
-        return new SetFirewallRulesAnswer(cmd, true, results);
-    }
-
-    protected Answer execute(final VmDataCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd));
-        }
-        final String controlIp = getRouterSshControlIp(cmd);
-        final Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
-        data.put(cmd.getVmIpAddress(), cmd.getVmData());
-
-        String json = new Gson().toJson(data);
-        s_logger.debug("VM data JSON IS:" + json);
-
-        json = Base64.encodeBase64String(json.getBytes(Charset.forName("UTF-8")));
-        final String command = String.format("%s%s %s %s", "/opt/cloud/bin/", VRScripts.VMDATA, "-d", json);
-
-        try {
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-            if (!result.first()) {
-                s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second());
-                return new Answer(cmd, false, "VmDataCommand failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("vm_data command on domain router " + controlIp + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "VmDataCommand failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(final DhcpEntryCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd));
-        }
-
-        // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null
-
-        String args = " -m " + cmd.getVmMac();
-        if (cmd.getVmIpAddress() != null) {
-            args += " -4 " + cmd.getVmIpAddress();
-        }
-        args += " -h " + cmd.getVmName();
-
-        if (cmd.getDefaultRouter() != null) {
-            args += " -d " + cmd.getDefaultRouter();
-        }
-
-        if (cmd.getDefaultDns() != null) {
-            args += " -n " + cmd.getDefaultDns();
-        }
-
-        if (cmd.getStaticRoutes() != null) {
-            args += " -s " + cmd.getStaticRoutes();
-        }
-
-        if (cmd.getVmIp6Address() != null) {
-            args += " -6 " + cmd.getVmIp6Address();
-            args += " -u " + cmd.getDuid();
-        }
-
-        if (!cmd.isDefault()) {
-            args += " -N";
-        }
-
-        final String command = String.format("%s%s %s", "/root/", VRScripts.DHCP, args);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
-        }
-
-        try {
-            final String controlIp = getRouterSshControlIp(cmd);
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second());
-
-                return new Answer(cmd, false, "DhcpEntry failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("dhcp_entry command on domain router " + controlIp + " completed");
-            }
-
-        } catch (final Throwable e) {
-            final String msg = "DhcpEntryCommand failed due to " + e;
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(final CreateIpAliasCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing createIpAlias command: " + s_gson.toJson(cmd));
-        }
-        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final List<IpAliasTO> ipAliasTOs = cmd.getIpAliasList();
-        final StringBuilder args = new StringBuilder();
-        for (final IpAliasTO ipaliasto : ipAliasTOs) {
-            args.append(ipaliasto.getAlias_count());
-            args.append(":");
-            args.append(ipaliasto.getRouterip());
-            args.append(":");
-            args.append(ipaliasto.getNetmask());
-            args.append("-");
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/createIpAlias " + args);
-        }
-
-        try {
-            final String controlIp = getRouterSshControlIp(cmd);
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/createIpAlias.sh " + args);
-
-            if (!result.first()) {
-                s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second());
-
-                return new Answer(cmd, false, "createipAlias failed due to " + result.second());
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("createIpAlias command on domain router " + controlIp + " completed");
-            }
-
-        } catch (final Throwable e) {
-            final String msg = "createIpAlias failed due to " + e;
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(final DnsMasqConfigCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing dnsmasqConfig command: " + s_gson.toJson(cmd));
-        }
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final String controlIp = getRouterSshControlIp(cmd);
-
-        assert controlIp != null;
-
-        final List<DhcpTO> dhcpTos = cmd.getIps();
-        final StringBuilder args = new StringBuilder();
-        for (final DhcpTO dhcpTo : dhcpTos) {
-            args.append(dhcpTo.getRouterIp());
-            args.append(":");
-            args.append(dhcpTo.getGateway());
-            args.append(":");
-            args.append(dhcpTo.getNetmask());
-            args.append(":");
-            args.append(dhcpTo.getStartIpOfSubnet());
-            args.append("-");
-        }
-
-        try {
-            final String command = String.format("%s%s %s", "/root/", VRScripts.DHCP, args);
-
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Run command on domain router " + routerIp + ",  /root/dnsmasq.sh");
-            }
-
-            if (!result.first()) {
-                s_logger.error("Unable update dnsmasq config file");
-                return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second());
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "Dnsmasqconfig command failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-
-        return new Answer(cmd);
-    }
-
-    //
-    // find mac address of a specified ethx device
-    //    ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
-    // returns
-    //      eth0:xx.xx.xx.xx
-
-    //
-    // list IP with eth devices
-    //  ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
-    //     | awk -F: '{ print $1 ": " $3 }'
-    //
-    // returns
-    //      eth0:xx.xx.xx.xx
-    //
-    //
-
-    private int findRouterEthDeviceIndex(final String domrName, final String routerIp, final String mac) throws Exception {
-
-        s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
-
-        // TODO : this is a temporary very inefficient solution, will refactor it later
-        final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
-                "ls /proc/sys/net/ipv4/conf");
-
-        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
-        // we use a waiting loop here as a workaround to synchronize activities in systems
-        final long startTick = System.currentTimeMillis();
-        while (System.currentTimeMillis() - startTick < 15000) {
-            if (result.first()) {
-                final String[] tokens = result.second().split("\\s+");
-                for (final String token : tokens) {
-                    if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
-                        final String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
-
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Run domr script " + cmd);
-                        }
-                        final Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
-                                // TODO need to find the dev index inside router based on IP address
-                                cmd);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
-                        }
-
-                        if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) {
-                            return Integer.parseInt(token.substring(3));
-                        }
-                    }
-                }
-            }
-
-            s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
-
-        }
-
-        return -1;
-    }
-
-    private Pair<Integer, String> findRouterFreeEthDeviceIndex(final String routerIp) throws Exception {
-
-        s_logger.info("findRouterFreeEthDeviceIndex. mac: ");
-
-        // TODO : this is a temporary very inefficient solution, will refactor it later
-        final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
-                "ip address | grep DOWN| cut -f2 -d :");
-
-        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
-        // we use a waiting loop here as a workaround to synchronize activities in systems
-        final long startTick = System.currentTimeMillis();
-        while (System.currentTimeMillis() - startTick < 15000) {
-            if (result.first() && !result.second().isEmpty()) {
-                final String[] tokens = result.second().split("\\n");
-                for (final String token : tokens) {
-                    if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
-                        //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
-                        //TODO: don't check for eth0,1,2, as they will be empty by default.
-                        //String cmd = String.format("ip address show %s ", token);
-                        final String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Run domr script " + cmd);
-                        }
-                        final Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
-                                // TODO need to find the dev index inside router based on IP address
-                                cmd);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
-                        }
-
-                        if (result2.first() && result2.second().trim().length() > 0) {
-                            return new Pair<Integer, String>(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ;
-                        }
-                    }
-                }
-            }
-
-            //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry...");
-
-        }
-
-        return new Pair<Integer, String>(-1, "");
-    }
-
-    protected Answer execute(final IpAssocCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd));
-        }
-
-        int i = 0;
-        final String[] results = new String[cmd.getIpAddresses().length];
-
-        try {
-
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-            final String controlIp = getRouterSshControlIp(cmd);
-            for (final IpAddressTO ip : ips) {
-                assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(),
-                        ip.getVlanNetmask(), ip.getVifMacAddress());
-                results[i++] = ip.getPublicIp() + " - success";
-            }
-
-            for (; i < cmd.getIpAddresses().length; i++) {
-                results[i++] = IpAssocAnswer.errorResult;
-            }
-        } catch (final Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
-
-            for (; i < cmd.getIpAddresses().length; i++) {
-                results[i++] = IpAssocAnswer.errorResult;
-            }
-        }
-
-        return new IpAssocAnswer(cmd, results);
-    }
-
-
-    protected int getVmFreeNicIndex(final String vmName) {
-        final GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
-        URI agentUri = null;
-        int nicposition = -1;
-        try {
-            final String cmdName = GetVmConfigCommand.class.getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-        }
-        final String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
-        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-        s_logger.debug("GetVmConfigCommand response received "
-                + s_gson.toJson(result));
-        if (result.length > 0) {
-            final GetVmConfigAnswer ans = (GetVmConfigAnswer)result[0];
-            final List<NicDetails> nics = ans.getNics();
-            for (final NicDetails nic : nics) {
-                if (nic.getState() == false) {
-                    nicposition = nics.indexOf(nic);
-                    break;
-                }
-            }
-        }
-        return nicposition;
-    }
-
-    protected int getVmNics(final String vmName, String vlanid) {
-        final GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
-        URI agentUri = null;
-        int nicposition = -1;
-        if(vlanid.equalsIgnoreCase("untagged")) {
-            vlanid = "-1";
-        }
-        try {
-            final String cmdName = GetVmConfigCommand.class.getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-        }
-        final String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
-        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-        s_logger.debug("executeRequest received response "
-                + s_gson.toJson(result));
-        if (result.length > 0) {
-            final GetVmConfigAnswer ans = (GetVmConfigAnswer)result[0];
-            final List<NicDetails> nics = ans.getNics();
-            for (final NicDetails nic : nics) {
-                nicposition++;
-                if (nicposition > 1 && nic.getVlanid().equals(vlanid)) {
-                    break;
-                }
-            }
-        }
-        return nicposition;
-    }
-
-    protected void modifyNicVlan(final String vmName, final String vlanId, final String macAddress) {
-        final ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress);
-        URI agentUri = null;
-        try {
-            final String cmdName = ModifyVmNicConfigCommand.class.getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-        }
-        final String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
-        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-        s_logger.debug("executeRequest received response "
-                + s_gson.toJson(result));
-        if (result.length > 0) {
-        }
-    }
-
-    protected void modifyNicVlan(final String vmName, final String vlanId, final int pos, final boolean enable, final String switchLabelName) {
-        final ModifyVmNicConfigCommand modifyNic = new ModifyVmNicConfigCommand(vmName, vlanId, pos, enable);
-        modifyNic.setSwitchLableName(switchLabelName);
-        URI agentUri = null;
-        try {
-            final String cmdName = ModifyVmNicConfigCommand.class.getName();
-            agentUri =
-                    new URI("https", null, _agentIp, _port,
-                            "/api/HypervResource/" + cmdName, null, null);
-        } catch (final URISyntaxException e) {
-            final String errMsg = "Could not generate URI for Hyper-V agent";
-            s_logger.error(errMsg, e);
-        }
-        final String ansStr = postHttpRequest(s_gson.toJson(modifyNic), agentUri);
-        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
-        s_logger.debug("executeRequest received response "
-                + s_gson.toJson(result));
-        if (result.length > 0) {
-        }
-    }
-
-    protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
-            final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
-
-        final URI broadcastUri = BroadcastDomainType.fromString(broadcastId);
-        if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-            throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId);
-        }
-        final String vlanId = BroadcastDomainType.getValue(broadcastUri);
-
-        int publicNicInfo = -1;
-        publicNicInfo = getVmNics(vmName, vlanId);
-
-        boolean addVif = false;
-        if (add && publicNicInfo == -1) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress);
-            }
-            addVif = true;
-        } else if (!add && firstIP) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unplug NIC " + publicNicInfo);
-            }
-        }
-
-        if (addVif) {
-            final Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress);
-            publicNicInfo = nicdevice.first();
-            if (publicNicInfo > 0) {
-                modifyNicVlan(vmName, vlanId, nicdevice.second());
-                // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
-                publicNicInfo = getVmNics(vmName, vlanId);
-                // As a new nic got activated in the VR. add the entry in the NIC's table.
-                networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo);
-            }
-            else {
-                // we didn't find any eth device available in VR to configure the ip range with new VLAN
-                final String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
-                s_logger.error(msg);
-                throw new InternalErrorException(msg);
-            }
-        }
-
-        String args = null;
-
-        if (add) {
-            args = " -A ";
-        } else {
-            args = " -D ";
-        }
-
-        if (sourceNat) {
-            args += " -s ";
-        }
-        if (firstIP) {
-            args += " -f ";
-        }
-        final String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
-        args += " -l ";
-        args += publicIpAddress + "/" + cidrSize;
-
-        args += " -c ";
-
-        args += "eth" + publicNicInfo;
-        args += " -g ";
-        args += vlanGateway;
-
-        if (addVif) {
-            args += " -n ";
-        }
-
-        final String command = String.format("%s%s %s","/opt/cloud/bin/", VRScripts.IPASSOC ,args);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on domain router " + privateIpAddress + command);
-        }
-
-        final Pair<Boolean, String> result =
-                SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-        if (!result.first()) {
-            s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second());
-            throw new Exception("ipassoc failed due to " + result.second());
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed");
-        }
-    }
-
-    protected Answer execute(final GetDomRVersionCmd cmd) {
-        final String command = String.format("%s%s", "/opt/cloud/bin/", VRScripts.VERSION);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Executing resource GetDomRVersionCmd: " + s_gson.toJson(cmd));
-            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
-        }
-
-        Pair<Boolean, String> result;
-        try {
-            final String controlIp = getRouterSshControlIp(cmd);
-            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
-
-                return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second());
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
-            }
-        } catch (final Throwable e) {
-            final String msg = "GetDomRVersionCmd failed due to " + e;
-            s_logger.error(msg, e);
-            return new GetDomRVersionAnswer(cmd, msg);
-        }
-        final String[] lines = result.second().split("&");
-        if (lines.length != 2) {
-            return new GetDomRVersionAnswer(cmd, result.second());
-        }
-        return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]);
-    }
-
-    private static String getRouterSshControlIp(final NetworkElementCommand cmd) {
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final String routerGuestIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
-        final String zoneNetworkType = cmd.getAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE);
-
-        if (routerGuestIp != null && zoneNetworkType != null && NetworkType.valueOf(zoneNetworkType) == NetworkType.Basic) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("In Basic zone mode, use router's guest IP for SSH control. guest IP : " + routerGuestIp);
-            }
-
-            return routerGuestIp;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
-        }
-        return routerIp;
-    }
-
-    protected Answer execute(final NetworkUsageCommand cmd) {
-        if (cmd.isForVpc()) {
-            //return VPCNetworkUsage(cmd);
-        }
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource NetworkUsageCommand " + s_gson.toJson(cmd));
-        }
-        if (cmd.getOption() != null && cmd.getOption().equals("create")) {
-            networkUsage(cmd.getPrivateIP(), "create", null);
-            final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "true", 0L, 0L);
-            return answer;
-        }
-        final long[] stats = getNetworkStats(cmd.getPrivateIP());
-
-        final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
-        return answer;
-    }
-
-    private long[] getNetworkStats(final String privateIP) {
-        final String result = networkUsage(privateIP, "get", null);
-        final long[] stats = new long[2];
-        if (result != null) {
-            try {
-                final String[] splitResult = result.split(":");
-                int i = 0;
-                while (i < splitResult.length - 1) {
-                    stats[0] += Long.parseLong(splitResult[i++]);
-                    stats[1] += Long.parseLong(splitResult[i++]);
-                }
-            } catch (final Throwable e) {
-                s_logger.warn("Unable to parse return from script return of network usage command: " + e.toString(), e);
-            }
-        }
-        return stats;
-    }
-
-    protected Answer execute(final SetMonitorServiceCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetMonitorServiceCommand: " + s_gson.toJson(cmd));
-        }
-
-        final String controlIp = getRouterSshControlIp(cmd);
-        final String config = cmd.getConfiguration();
-        final String args = String.format(" %s %s", "-c", config);
-
-        final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.MONITOR_SERVICE, args);
-
-        try {
-            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
-
-            if (!result.first()) {
-                final String msg=  "monitor_service.sh failed on domain router " + controlIp + " failed " + result.second();
-                s_logger.error(msg);
-                return new Answer(cmd, false, msg);
-            }
-
-            return new Answer(cmd);
-
-        } catch (final Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString(), e);
-            return new Answer(cmd, false, "SetMonitorServiceCommand failed due to " + e);
-        }
-    }
-
-    protected CheckSshAnswer execute(final CheckSshCommand cmd) {
-        final String vmName = cmd.getName();
-        final String privateIp = cmd.getIp();
-        final int cmdPort = cmd.getPort();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
-        }
-
-        try {
-            final String result = connect(cmd.getName(), privateIp, cmdPort);
-            if (result != null) {
-                s_logger.error("Can not ping System vm " + vmName + "due to:" + result);
-                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
-            }
-        } catch (final Exception e) {
-            s_logger.error("Can not ping System vm " + vmName + "due to exception");
-            return new CheckSshAnswer(cmd, e);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Ping command port succeeded for vm " + vmName);
-        }
-
-        if (VirtualMachineName.isValidRouterName(vmName)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Execute network usage setup command on " + vmName);
-            }
-            networkUsage(privateIp, "create", null);
-        }
-
-        return new CheckSshAnswer(cmd);
-    }
-
-    protected String networkUsage(final String privateIpAddress, final String option, final String ethName) {
-        String args = null;
-        if (option.equals("get")) {
-            args = "-g";
-        } else if (option.equals("create")) {
-            args = "-c";
-        } else if (option.equals("reset")) {
-            args = "-r";
-        } else if (option.equals("addVif")) {
-            args = "-a";
-            args += ethName;
-        } else if (option.equals("deleteVif")) {
-            args = "-d";
-            args += ethName;
-        }
-
-        try {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress);
-            }
-
-            final Pair<Boolean, String> result =
-                    SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args);
-
-            if (!result.first()) {
-                return null;
-            }
-
-            return result.second();
-        } catch (final Throwable e) {
-            s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to " + e);
-        }
-
-        return null;
-    }
-
-    public File getSystemVMKeyFile() {
-        final URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
-        File keyFile = null;
-        if (url != null) {
-            keyFile = new File(url.getPath());
-        }
-        if (keyFile == null || !keyFile.exists()) {
-            keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
-        }
-        assert keyFile != null;
-        if (!keyFile.exists()) {
-            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
-        }
-        return keyFile;
-    }
-
-    public static String postHttpRequest(final String jsonCmd, final URI agentUri) {
-        // Using Apache's HttpClient for HTTP POST
-        // Java-only approach discussed at on StackOverflow concludes with
-        // comment to use Apache HttpClient
-        // http://stackoverflow.com/a/2793153/939250, but final comment is to
-        // use Apache.
-        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
-        logMessage = cleanPassword(logMessage);
-        s_logger.debug("POST request to " + agentUri.toString()
-                + " with contents " + logMessage);
-
-        // Create request
-        HttpClient httpClient = null;
-        final TrustStrategy easyStrategy = new TrustStrategy() {
-            @Override
-            public boolean isTrusted(final X509Certificate[] chain, final String authType)
-                    throws CertificateException {
-                return true;
-            }
-        };
-
-        try {
-            final SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
-            final SchemeRegistry registry = new SchemeRegistry();
-            registry.register(new Scheme("https", DEFAULT_AGENT_PORT, sf));
-            final ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
-            httpClient = new DefaultHttpClient(ccm);
-        } catch (final KeyManagementException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (final UnrecoverableKeyException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (final NoSuchAlgorithmException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (final KeyStoreException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        }
-
-        String result = null;
-
-        // TODO: are there timeout settings and worker thread settings to tweak?
-        try {
-            final HttpPost request = new HttpPost(agentUri);
-
-            // JSON encode command
-            // Assumes command sits comfortably in a string, i.e. not used for
-            // large data transfers
-            final StringEntity cmdJson = new StringEntity(jsonCmd);
-            request.addHeader("content-type", "application/json");
-            request.setEntity(cmdJson);
-            s_logger.debug("Sending cmd to " + agentUri.toString()
-                    + " cmd data:" + logMessage);
-            final HttpResponse response = httpClient.execute(request);
-
-            // Unsupported commands will not route.
-            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
-                final String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode();
-                s_logger.error(errMsg);
-                final String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right type of" + " server?";
-                final Answer ans = new UnsupportedAnswer(null, unsupportMsg);
-                s_logger.error(ans);
-                result = s_gson.toJson(new Answer[] {ans});
-            } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-                final String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
-                s_logger.error(errMsg);
-                return null;
-            } else {
-                result = EntityUtils.toString(response.getEntity());
-                final String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
-                s_logger.debug("POST response is " + logResult);
-            }
-        } catch (final ClientProtocolException protocolEx) {
-            // Problem with HTTP message exchange
-            s_logger.error(protocolEx);
-        } catch (final IOException connEx) {
-            // Problem with underlying communications
-            s_logger.error(connEx);
-        } finally {
-            httpClient.getConnectionManager().shutdown();
-        }
-        return result;
-    }
-
-    @Override
-    protected final String getDefaultScriptsDir() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    // NB: 'params' can come from one of two places.
-    // For a new host, HypervServerDiscoverer.find().
-    // For an existing host, DiscovererBase.reloadResource().
-    // In the later case, the params Map is populated with predefined keys
-    // and custom keys from the database that were passed out by the find()
-    // call.
-    // the custom keys go by the variable name 'details'.
-    // Thus, in find(), you see that 'details' are added to the params Map.
-    @Override
-    public final boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        /* todo: update, make consistent with the xen server equivalent. */
-
-        if (params != null) {
-            _guid = (String)params.get("guid");
-            _zoneId = (String)params.get("zone");
-            _podId = (String)params.get("pod");
-            _clusterId = (String)params.get("cluster");
-            _agentIp = (String)params.get("ipaddress"); // was agentIp
-            _name = name;
-
-            _clusterGuid = (String)params.get("cluster.guid");
-            _username = (String)params.get("url");
-            _password = (String)params.get("password");
-            _username = (String)params.get("username");
-            _configureCalled = true;
-        }
-
-        _vrResource = new VirtualRoutingResource(this);
-        if (!_vrResource.configure(name, new HashMap<String, Object>())) {
-            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
-        }
-        return true;
-    }
-
-    @Override
-    public void setName(final String name) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setConfigParams(final Map<String, Object> params) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public final Map<String, Object> getConfigParams() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public final int getRunLevel() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(final int level) {
-        // TODO Auto-generated method stub
-    }
-
-    protected String connect(final String vmName, final String ipAddress, final int port) {
-        final long startTick = System.currentTimeMillis();
-
-        // wait until we have at least been waiting for _ops_timeout time or
-        // at least have tried _retry times, this is to coordinate with system
-        // VM patching/rebooting time that may need
-        int retry = _retry;
-        while (System.currentTimeMillis() - startTick <= _opsTimeout || --retry > 0) {
-            s_logger.info("Trying to connect to " + ipAddress);
-            try (SocketChannel sch = SocketChannel.open();) {
-                sch.configureBlocking(true);
-                sch.socket().setSoTimeout(5000);
-                // we need to connect to the control ip address to check the status of the system vm
-                final InetSocketAddress addr = new InetSocketAddress(ipAddress, port);
-                sch.connect(addr);
-                return null;
-            } catch (final IOException e) {
-                s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString());
-                if (e instanceof ConnectException) {
-                    // if connection is refused because of VM is being started,
-                    // we give it more sleep time
-                    // to avoid running out of retry quota too quickly
-                    try {
-                        Thread.sleep(5000);
-                    } catch (final InterruptedException ex) {
-                        s_logger.debug("[ignored] interupted while waiting to retry connecting to vm after exception: "+e.getLocalizedMessage());
-                    }
-                }
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (final InterruptedException ex) {
-                s_logger.debug("[ignored] interupted while connecting to vm.");
-            }
-        }
-
-        s_logger.info("Unable to logon to " + ipAddress);
-
-        return "Unable to connect";
-    }
-
-    public static String cleanPassword(final String logString) {
-        String cleanLogString = null;
-        if (logString != null) {
-            cleanLogString = logString;
-            final String[] temp = logString.split(",");
-            int i = 0;
-            if (temp != null) {
-                while (i < temp.length) {
-                    temp[i] = StringUtils.cleanString(temp[i]);
-                    i++;
-                }
-                final List<String> stringList = new ArrayList<String>();
-                Collections.addAll(stringList, temp);
-                cleanLogString = StringUtils.join(stringList, ",");
-            }
-        }
-        return cleanLogString;
-    }
-}
diff --git a/plugins/hypervisors/hyperv/src/main/java/com/cloud/ha/HypervInvestigator.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/ha/HypervInvestigator.java
new file mode 100644
index 0000000..774efc8
--- /dev/null
+++ b/plugins/hypervisors/hyperv/src/main/java/com/cloud/ha/HypervInvestigator.java
@@ -0,0 +1,77 @@
+/*
+ * 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.ha;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+
+public class HypervInvestigator extends AdapterBase implements Investigator {
+    private final static Logger s_logger = Logger.getLogger(HypervInvestigator.class);
+    @Inject HostDao _hostDao;
+    @Inject AgentManager _agentMgr;
+    @Inject ResourceManager _resourceMgr;
+
+    @Override
+    public boolean isVmAlive(com.cloud.vm.VirtualMachine vm, Host host) throws UnknownVM {
+        Status status = isAgentAlive(host);
+        if (status == null) {
+            throw new UnknownVM();
+        }
+        return status == Status.Up ? true : null;
+    }
+
+    @Override
+    public Status isAgentAlive(Host agent) {
+        if (agent.getHypervisorType() != Hypervisor.HypervisorType.Hyperv) {
+            return null;
+        }
+        CheckOnHostCommand cmd = new CheckOnHostCommand(agent);
+        List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(agent.getClusterId(), Status.Up);
+        for (HostVO neighbor : neighbors) {
+            if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.HypervisorType.Hyperv) {
+                continue;
+            }
+
+            try {
+                Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
+                if (answer != null) {
+                    return answer.getResult() ? Status.Down : Status.Up;
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to send command to host: " + neighbor.getId(), e);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java
rename to plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/discoverer/HypervServerDiscoverer.java
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
similarity index 100%
rename from plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
rename to plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/manager/HypervManager.java
similarity index 100%
rename from plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java
rename to plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/manager/HypervManager.java
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
rename to plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
diff --git a/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
new file mode 100644
index 0000000..979be73
--- /dev/null
+++ b/plugins/hypervisors/hyperv/src/main/java/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -0,0 +1,2404 @@
+// 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.hyperv.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.Charset;
+import java.rmi.RemoteException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.BasicClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+import org.apache.log4j.Logger;
+import org.joda.time.Duration;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckRouterAnswer;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetVmConfigAnswer;
+import com.cloud.agent.api.GetVmConfigAnswer.NicDetails;
+import com.cloud.agent.api.GetVmConfigCommand;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.ModifyVmNicConfigCommand;
+import com.cloud.agent.api.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.CreateIpAliasCommand;
+import com.cloud.agent.api.routing.DeleteIpAliasCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.IpAliasTO;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetMonitorServiceCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetSourceNatAnswer;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.SetStaticRouteAnswer;
+import com.cloud.agent.api.routing.SetStaticRouteCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DhcpTO;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VRScripts;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.hyperv.manager.HypervManager;
+import com.cloud.network.HAProxyConfigurator;
+import com.cloud.network.LoadBalancerConfigurator;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.RouterPrivateIpStrategy;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.ExecutionResult;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachineName;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+
+/**
+ * Implementation of dummy resource to be returned from discoverer.
+ **/
+public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
+    public static final int DEFAULT_AGENT_PORT = 8250;
+    public static final String HOST_VM_STATE_REPORT_COMMAND = "org.apache.cloudstack.HostVmStateReportCommand";
+    private static final Logger s_logger = Logger.getLogger(HypervDirectConnectResource.class.getName());
+
+    private static final Gson s_gson = GsonHelper.getGson();
+    private String _zoneId;
+    private String _podId;
+    private String _clusterId;
+    private String _guid;
+    private String _agentIp;
+    private final int _port = DEFAULT_AGENT_PORT;
+    protected final long _opsTimeout = 900000;  // 15 minutes time out to time
+
+    protected final int _retry = 24;
+    protected final int _sleep = 10000;
+    protected static final int DEFAULT_DOMR_SSHPORT = 3922;
+    private String _clusterGuid;
+
+    // Used by initialize to assert object configured before
+    // initialize called.
+    private boolean _configureCalled = false;
+
+    private String _username;
+    private String _password;
+
+    private static HypervManager s_hypervMgr;
+    @Inject
+    HypervManager _hypervMgr;
+    protected VirtualRoutingResource _vrResource;
+
+    @PostConstruct
+    void init() {
+        s_hypervMgr = _hypervMgr;
+    }
+
+    @Override
+    public final Type getType() {
+        return Type.Routing;
+    }
+
+    @Override
+    public final StartupCommand[] initialize() {
+        // assert
+        if (!_configureCalled) {
+            final String errMsg = this.getClass().getName() + " requires configure() be called before" + " initialize()";
+            s_logger.error(errMsg);
+        }
+
+        // Create default StartupRoutingCommand, then customise
+        final StartupRoutingCommand defaultStartRoutCmd =
+                new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.Hyperv, RouterPrivateIpStrategy.HostLocal);
+
+        // Identity within the data centre is decided by CloudStack kernel,
+        // and passed via ServerResource.configure()
+        defaultStartRoutCmd.setDataCenter(_zoneId);
+        defaultStartRoutCmd.setPod(_podId);
+        defaultStartRoutCmd.setCluster(_clusterId);
+        defaultStartRoutCmd.setGuid(_guid);
+        defaultStartRoutCmd.setName(_name);
+        defaultStartRoutCmd.setPrivateIpAddress(_agentIp);
+        defaultStartRoutCmd.setStorageIpAddress(_agentIp);
+        defaultStartRoutCmd.setPool(_clusterGuid);
+
+        s_logger.debug("Generated StartupRoutingCommand for _agentIp \"" + _agentIp + "\"");
+
+        defaultStartRoutCmd.setVersion(this.getClass().getPackage().getImplementationVersion());
+
+        // Specifics of the host's resource capacity and network configuration
+        // comes from the host itself. CloudStack sanity checks network
+        // configuration
+        // and uses capacity info for resource allocation.
+        final Command[] startCmds = requestStartupCommand(new Command[] {defaultStartRoutCmd});
+
+        // TODO: may throw, is this okay?
+        final StartupRoutingCommand startCmd = (StartupRoutingCommand)startCmds[0];
+
+        // Assert that host identity is consistent with existing values.
+        if (startCmd == null) {
+            final String errMsg = String.format("Host %s (IP %s)" + "did not return a StartupRoutingCommand", _name, _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getDataCenter().equals(defaultStartRoutCmd.getDataCenter())) {
+            final String errMsg =
+                    String.format("Host %s (IP %s) changed zone/data center.  Was " + defaultStartRoutCmd.getDataCenter() + " NOW its " + startCmd.getDataCenter(), _name,
+                            _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getPod().equals(defaultStartRoutCmd.getPod())) {
+            final String errMsg = String.format("Host %s (IP %s) changed pod.  Was " + defaultStartRoutCmd.getPod() + " NOW its " + startCmd.getPod(), _name, _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getCluster().equals(defaultStartRoutCmd.getCluster())) {
+            final String errMsg =
+                    String.format("Host %s (IP %s) changed cluster.  Was " + defaultStartRoutCmd.getCluster() + " NOW its " + startCmd.getCluster(), _name, _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getGuid().equals(defaultStartRoutCmd.getGuid())) {
+            final String errMsg = String.format("Host %s (IP %s) changed guid.  Was " + defaultStartRoutCmd.getGuid() + " NOW its " + startCmd.getGuid(), _name, _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getPrivateIpAddress().equals(defaultStartRoutCmd.getPrivateIpAddress())) {
+            final String errMsg =
+                    String.format("Host %s (IP %s) IP address.  Was " + defaultStartRoutCmd.getPrivateIpAddress() + " NOW its " + startCmd.getPrivateIpAddress(), _name,
+                            _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+        if (!startCmd.getName().equals(defaultStartRoutCmd.getName())) {
+            final String errMsg = String.format("Host %s (IP %s) name.  Was " + startCmd.getName() + " NOW its " + defaultStartRoutCmd.getName(), _name, _agentIp);
+            s_logger.error(errMsg);
+            // TODO: valid to return null, or should we throw?
+            return null;
+        }
+
+        // Host will also supply details of an existing StoragePool if it has
+        // been configured with one.
+        //
+        // NB: if the host was configured
+        // with a local storage pool, CloudStack may not be able to use it
+        // unless
+        // it is has service offerings configured to recognise this storage
+        // type.
+        StartupStorageCommand storePoolCmd = null;
+        if (startCmds.length > 1) {
+            storePoolCmd = (StartupStorageCommand)startCmds[1];
+            // TODO: is this assertion required?
+            if (storePoolCmd == null) {
+                final String frmtStr = "Host %s (IP %s) sent incorrect Command, " + "second parameter should be a " + "StartupStorageCommand";
+                final String errMsg = String.format(frmtStr, _name, _agentIp);
+                s_logger.error(errMsg);
+                // TODO: valid to return null, or should we throw?
+                return null;
+            }
+            s_logger.info("Host " + _name + " (IP " + _agentIp + ") already configured with a storeage pool, details " + s_gson.toJson(startCmds[1]));
+        } else {
+            s_logger.info("Host " + _name + " (IP " + _agentIp + ") already configured with a storeage pool, details ");
+        }
+        return new StartupCommand[] {startCmd, storePoolCmd};
+    }
+
+    @Override
+    public final PingCommand getCurrentStatus(final long id) {
+        final PingCommand pingCmd = new PingRoutingCommand(getType(), id, getHostVmStateReport());
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping host " + _name + " (IP " + _agentIp + ")");
+        }
+
+        final Answer pingAns = executeRequest(pingCmd);
+
+        if (pingAns == null || !pingAns.getResult()) {
+            s_logger.info("Cannot ping host " + _name + " (IP " + _agentIp + "), pingAns (blank means null) is:" + pingAns);
+            return null;
+        }
+        return pingCmd;
+    }
+
+    public final ArrayList<Map<String, String>> requestHostVmStateReport() {
+        URI agentUri = null;
+        try {
+            agentUri = new URI("https", null, _agentIp, _port, "/api/HypervResource/" + HOST_VM_STATE_REPORT_COMMAND, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        final String incomingCmd = postHttpRequest("{}", agentUri);
+
+        if (incomingCmd == null) {
+            return null;
+        }
+        ArrayList<Map<String, String>> result = null;
+        try {
+            result = s_gson.fromJson(incomingCmd, new TypeToken<ArrayList<HashMap<String, String>>>() {
+            }.getType());
+        } catch (final Exception ex) {
+            final String errMsg = "Failed to deserialize Command[] " + incomingCmd;
+            s_logger.error(errMsg, ex);
+        }
+        s_logger.debug("HostVmStateReportCommand received response "
+                + s_gson.toJson(result));
+        if (result != null) {
+            if (!result.isEmpty()) {
+                return result;
+            } else {
+                return new ArrayList<Map<String, String>>();
+            }
+        }
+        return null;
+    }
+
+    protected HashMap<String, HostVmStateReportEntry> getHostVmStateReport() {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        final ArrayList<Map<String, String>> vmList = requestHostVmStateReport();
+        if (vmList == null) {
+            return null;
+        }
+
+        for (final Map<String, String> vmMap : vmList) {
+            final String name = (String)vmMap.keySet().toArray()[0];
+            vmStates.put(name, new HostVmStateReportEntry(PowerState.valueOf(vmMap.get(name)), _guid));
+        }
+        return vmStates;
+    }
+
+    // TODO: Is it valid to return NULL, or should we throw on error?
+    // Returns StartupCommand with fields revised with values known only to the
+    // host
+    public final Command[] requestStartupCommand(final Command[] cmd) {
+        // Set HTTP POST destination URI
+        // Using java.net.URI, see
+        // http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
+        URI agentUri = null;
+        try {
+            final String cmdName = StartupCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            // TODO add proper logging
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        final String incomingCmd = postHttpRequest(s_gson.toJson(cmd), agentUri);
+
+        if (incomingCmd == null) {
+            return null;
+        }
+        Command[] result = null;
+        try {
+            result = s_gson.fromJson(incomingCmd, Command[].class);
+        } catch (final Exception ex) {
+            final String errMsg = "Failed to deserialize Command[] " + incomingCmd;
+            s_logger.error(errMsg, ex);
+        }
+        s_logger.debug("requestStartupCommand received response " + s_gson.toJson(result));
+        if (result.length > 0) {
+            return result;
+        }
+        return null;
+    }
+
+    // TODO: Is it valid to return NULL, or should we throw on error?
+    @Override
+    public final Answer executeRequest(final Command cmd) {
+        // Set HTTP POST destination URI
+        // Using java.net.URI, see
+        // http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URI.html
+        URI agentUri = null;
+        final Class<? extends Command> clazz = cmd.getClass();
+        Answer answer = null;
+        try {
+            final String cmdName = cmd.getClass().getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            // TODO add proper logging
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        if (cmd instanceof NetworkElementCommand) {
+            return _vrResource.executeRequest((NetworkElementCommand)cmd);
+        }if (clazz == CheckSshCommand.class) {
+            answer = execute((CheckSshCommand)cmd);
+        } else if (cmd instanceof NetworkUsageCommand) {
+            answer = execute((NetworkUsageCommand)cmd);
+        } else if (clazz == PingTestCommand.class) {
+            answer = execute((PingTestCommand)cmd);
+        } else if (clazz == PlugNicCommand.class) {
+            answer = execute((PlugNicCommand)cmd);
+        } else if (clazz == UnPlugNicCommand.class) {
+            answer = execute((UnPlugNicCommand)cmd);
+        } else if (clazz == CopyCommand.class) {
+            answer = execute((CopyCommand)cmd);
+        }
+        else {
+            if (clazz == StartCommand.class) {
+                final VirtualMachineTO vmSpec = ((StartCommand)cmd).getVirtualMachine();
+                if (vmSpec.getType() != VirtualMachine.Type.User) {
+                    if (s_hypervMgr != null) {
+                        final String secondary = s_hypervMgr.prepareSecondaryStorageStore(Long.parseLong(_zoneId));
+                        if (secondary != null) {
+                            ((StartCommand)cmd).setSecondaryStorage(secondary);
+                        }
+                    } else {
+                        s_logger.error("Hyperv manager isn't available. Couldn't check and copy the systemvm iso.");
+                    }
+                }
+            }
+
+            // Send the cmd to hyperv agent.
+            final String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
+            if (ansStr == null) {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+            // Only Answer instances are returned by remote agents.
+            // E.g. see Response.getAnswers()
+            final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+            final String logResult = cleanPassword(s_gson.toJson(result));
+            s_logger.debug("executeRequest received response " + logResult);
+            if (result.length > 0) {
+                return result[0];
+            }
+        }
+        return answer;
+    }
+
+    private Answer execute(final CopyCommand cmd) {
+        URI agentUri = null;
+        try {
+            final String cmdName = cmd.getClass().getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+            return null;
+        }
+        cleanPassword(cmd.getSrcTO().getDataStore());
+        cleanPassword(cmd.getDestTO().getDataStore());
+
+        // Send the cmd to hyperv agent.
+        final String ansStr = postHttpRequest(s_gson.toJson(cmd), agentUri);
+        if (ansStr == null) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        final String logResult = cleanPassword(s_gson.toJson(result));
+        s_logger.debug("executeRequest received response " + logResult);
+        if (result.length > 0) {
+            return result[0];
+        }
+
+        return null;
+    }
+
+    private void cleanPassword(final DataStoreTO dataStoreTO) {
+        if (dataStoreTO instanceof NfsTO) {
+            final NfsTO nfsTO = (NfsTO)dataStoreTO;
+            final String url = nfsTO.getUrl();
+            if (url.contains("cifs") && url.contains("password")) {
+                nfsTO.setUrl(url.substring(0, url.indexOf('?')));
+            }
+        }
+    }
+
+    private PlugNicAnswer execute(final PlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PlugNicCommand " + s_gson.toJson(cmd));
+        }
+
+        try {
+
+            final String vmName = cmd.getVmName();
+            final NicTO nic = cmd.getNic();
+            final URI broadcastUri = nic.getBroadcastUri();
+            if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + nic.getBroadcastUri());
+            }
+            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+            int publicNicInfo = -1;
+            publicNicInfo = getVmFreeNicIndex(vmName);
+            if (publicNicInfo > 0) {
+                modifyNicVlan(vmName, vlanId, publicNicInfo, true, cmd.getNic().getName());
+                return new PlugNicAnswer(cmd, true, "success");
+            }
+            final String msg = " Plug Nic failed for the vm as it has reached max limit of NICs to be added";
+            s_logger.warn(msg);
+            return new PlugNicAnswer(cmd, false, msg);
+
+        } catch (final Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
+        }
+    }
+
+
+    private UnPlugNicAnswer execute(final UnPlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource UnPlugNicCommand " + s_gson.toJson(cmd));
+        }
+
+        try {
+            final String vmName = cmd.getVmName();
+            final NicTO nic = cmd.getNic();
+            final URI broadcastUri = nic.getBroadcastUri();
+            if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                throw new InternalErrorException("Unable to unassign a public IP to a VIF on network " + nic.getBroadcastUri());
+            }
+            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+            int publicNicInfo = -1;
+            publicNicInfo = getVmNics(vmName, vlanId);
+            if (publicNicInfo > 0) {
+                modifyNicVlan(vmName, "2", publicNicInfo, false, "");
+            }
+            return new UnPlugNicAnswer(cmd, true, "success");
+        } catch (final Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString());
+        }
+    }
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIP, final String script, final String args) {
+        return executeInVR(routerIP, script, args, Duration.standardSeconds(120L));
+    }
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) {
+        Pair<Boolean, String> result;
+
+        //TODO: Password should be masked, cannot output to log directly
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args);
+        }
+
+        try {
+            result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args, VRScripts.CONNECTION_TIMEOUT,
+                    VRScripts.CONNECTION_TIMEOUT, timeout);
+        } catch (final Exception e) {
+            final String msg = "Command failed due to " + e ;
+            s_logger.error(msg);
+            result = new Pair<Boolean, String>(false, msg);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(script + " execution result: " + result.first().toString());
+        }
+        return new ExecutionResult(result.first(), result.second());
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(final String routerIp, final String filePath, final String fileName, final String content) {
+        final File keyFile = getSystemVMKeyFile();
+        try {
+            SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(Charset.forName("UTF-8")), fileName, null);
+        } catch (final Exception e) {
+            s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
+        //Update IP used to access router
+        cmd.setRouterAccessIp(getRouterSshControlIp(cmd));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
+        try {
+
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+            final String controlIp = getRouterSshControlIp(cmd);
+
+            for (final IpAddressTO ip : ips) {
+                /**
+                 * TODO support other networks
+                 */
+                final URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                    throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri());
+                }
+                final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+                int publicNicInfo = -1;
+                publicNicInfo = getVmNics(routerName, vlanId);
+
+                boolean addVif = false;
+                if (ip.isAdd() && publicNicInfo == -1) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp());
+                    }
+                    addVif = true;
+                }
+
+                if (addVif) {
+                    final Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(controlIp);
+                    publicNicInfo = nicdevice.first();
+                    if (publicNicInfo > 0) {
+                        modifyNicVlan(routerName, vlanId, nicdevice.second());
+                        // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
+                        publicNicInfo = getVmNics(routerName, vlanId);
+                        // As a new nic got activated in the VR. add the entry in the NIC's table.
+                        networkUsage(controlIp, "addVif", "eth" + publicNicInfo);
+                    }
+                    else {
+                        // we didn't find any eth device available in VR to configure the ip range with new VLAN
+                        final String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
+                        s_logger.error(msg);
+                        throw new InternalErrorException(msg);
+                    }
+                    ip.setNicDevId(publicNicInfo);
+                    ip.setNewNic(addVif);
+                } else {
+                    ip.setNicDevId(publicNicInfo);
+                }
+            }
+        } catch (final Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
+        final NicTO nic = cmd.getNic();
+        final String domrName =
+                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            final URI broadcastUri = nic.getBroadcastUri();
+            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+            final int ethDeviceNum = getVmNics(domrName, vlanId);
+            if (ethDeviceNum > 0) {
+                nic.setDeviceId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare SetupGuestNetwork failed due to unable to find the nic");
+            }
+        } catch (final Exception e) {
+            final String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+
+    private ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            for (final IpAddressTO ip : ips) {
+                final URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                    throw new InternalErrorException("Invalid Broadcast URI " + ip.getBroadcastUri());
+                }
+                final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+                int publicNicInfo = -1;
+                publicNicInfo = getVmNics(routerName, vlanId);
+                if (publicNicInfo < 0) {
+                    if (ip.isAdd()) {
+                        throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
+                    } else {
+                        s_logger.debug("VIF to deassociate IP with does not exist, return success");
+                        continue;
+                    }
+                }
+
+                ip.setNicDevId(publicNicInfo);
+            }
+        } catch (final Exception e) {
+            s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.toString());
+        }
+
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final IpAddressTO pubIp = cmd.getIpAddress();
+
+        try {
+            final String broadcastUri = pubIp.getBroadcastUri();
+            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+            final int ethDeviceNum = getVmNics(routerName, vlanId);
+            if (ethDeviceNum > 0) {
+                pubIp.setNicDevId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare Ip SNAT failed due to unable to find the nic");
+            }
+        } catch (final Exception e) {
+            final String msg = "Prepare Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) {
+        final NicTO nic = cmd.getNic();
+        final String routerName =
+                cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            final URI broadcastUri = nic.getBroadcastUri();
+            final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+            final int ethDeviceNum = getVmNics(routerName, vlanId);
+            if (ethDeviceNum > 0) {
+                nic.setDeviceId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare SetNetworkACL failed due to unable to find the nic");
+            }
+        } catch (final Exception e) {
+            final String msg = "Prepare SetNetworkACL failed due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
+    protected Answer execute(final RemoteAccessVpnCfgCommand cmd) {
+        final String controlIp = getRouterSshControlIp(cmd);
+        final StringBuffer argsBuf = new StringBuffer();
+        if (cmd.isCreate()) {
+            argsBuf.append(" -r ").append(cmd.getIpRange()).append(" -p ").append(cmd.getPresharedKey()).append(" -s ").append(cmd.getVpnServerIp()).append(" -l ").append(cmd.getLocalIp())
+            .append(" -c ");
+
+        } else {
+            argsBuf.append(" -d ").append(" -s ").append(cmd.getVpnServerIp());
+        }
+        argsBuf.append(" -C ").append(cmd.getLocalCidr());
+        argsBuf.append(" -i ").append(cmd.getPublicInterface());
+
+        try {
+            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPN_L2TP, argsBuf.toString());
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Executing " + command);
+            }
+
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("RemoteAccessVpnCfg command on domR failed, message: " + result.second());
+
+                return new Answer(cmd, false, "RemoteAccessVpnCfg command failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("RemoteAccessVpnCfg command on domain router " + argsBuf.toString() + " completed");
+            }
+
+        } catch (final Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn(e.getMessage());
+            }
+
+            final String msg = "RemoteAccessVpnCfg command failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final VpnUsersCfgCommand cmd) {
+
+        final String controlIp = getRouterSshControlIp(cmd);
+        for (final VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) {
+            final StringBuffer argsBuf = new StringBuffer();
+            if (!userpwd.isAdd()) {
+                argsBuf.append(" -U ").append(userpwd.getUsername());
+            } else {
+                argsBuf.append(" -u ").append(userpwd.getUsernamePassword());
+            }
+
+            try {
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh ");
+                }
+
+                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString());
+
+                if (!result.first()) {
+                    s_logger.error("VpnUserCfg command on domR failed, message: " + result.second());
+
+                    return new Answer(cmd, false, "VpnUserCfg command failed due to " + result.second());
+                }
+            } catch (final Throwable e) {
+                if (e instanceof RemoteException) {
+                    s_logger.warn(e.getMessage());
+                }
+
+                final String msg = "VpnUserCfg command failed due to " + e.getMessage();
+                s_logger.error(msg, e);
+                return new Answer(cmd, false, msg);
+            }
+        }
+
+        return new Answer(cmd);
+    }
+    private SetStaticRouteAnswer execute(final SetStaticRouteCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetStaticRouteCommand: " + s_gson.toJson(cmd));
+        }
+
+        boolean endResult = true;
+
+        final String controlIp = getRouterSshControlIp(cmd);
+        String args = "";
+        final String[] results = new String[cmd.getStaticRoutes().length];
+        int i = 0;
+
+        // Extract and build the arguments for the command to be sent to the VR.
+        final String[] rules = cmd.generateSRouteRules();
+        final StringBuilder sb = new StringBuilder();
+
+        for (int j = 0; j < rules.length; j++) {
+            sb.append(rules[j]).append(',');
+        }
+        args += " -a " + sb.toString();
+
+        final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPC_STATIC_ROUTE, args);
+
+        // Send over the command for execution, via ssh, to the VR.
+        try {
+            final Pair<Boolean, String> result =
+                    SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticroute.sh " + args);
+            }
+
+            if (!result.first()) {
+                s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args);
+                results[i++] = "Failed";
+                endResult = false;
+            } else {
+                results[i++] = null;
+            }
+        } catch (final Throwable e) {
+            s_logger.error("SetStaticRouteCommand(args: " + args + ") failed on setting one rule due to " + e);
+            results[i++] = "Failed";
+            endResult = false;
+        }
+        return new SetStaticRouteAnswer(cmd, endResult, results);
+
+    }
+
+    protected CheckS2SVpnConnectionsAnswer execute(final CheckS2SVpnConnectionsCommand cmd) {
+        final StringBuilder cmdline = new StringBuilder();
+        cmdline.append("/opt/cloud/bin/");
+        cmdline.append(VRScripts.S2SVPN_CHECK);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + s_gson.toJson(cmd));
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + cmdline.toString());
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            final String controlIp = getRouterSshControlIp(cmd);
+            for (final String ip : cmd.getVpnIps()) {
+                cmdline.append(" ");
+                cmdline.append(ip);
+            }
+
+            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, cmdline.toString());
+
+            if (!result.first()) {
+                s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " +
+                        result.second());
+
+                return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "CheckS2SVpnConnectionsCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed");
+        }
+        return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second());
+    }
+
+    protected Answer execute(final Site2SiteVpnCfgCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource Site2SiteVpnCfgCommand " + s_gson.toJson(cmd));
+        }
+
+        final String routerIp = getRouterSshControlIp(cmd);
+
+        String args = "";
+        if (cmd.isCreate()) {
+            args += " -A";
+            args += " -l ";
+            args += cmd.getLocalPublicIp();
+            args += " -n ";
+            args += cmd.getLocalGuestCidr();
+            args += " -g ";
+            args += cmd.getLocalPublicGateway();
+            args += " -r ";
+            args += cmd.getPeerGatewayIp();
+            args += " -N ";
+            args += cmd.getPeerGuestCidrList();
+            args += " -e ";
+            args += "\"" + cmd.getEspPolicy() + "\"";
+            args += " -i ";
+            args += "\"" + cmd.getIkePolicy() + "\"";
+            args += " -t ";
+            args += Long.toString(cmd.getIkeLifetime());
+            args += " -T ";
+            args += Long.toString(cmd.getEspLifetime());
+            args += " -s ";
+            args += "\"" + cmd.getIpsecPsk() + "\"";
+            args += " -d ";
+            if (cmd.getDpd()) {
+                args += "1";
+            } else {
+                args += "0";
+            }
+        } else {
+            args += " -D";
+            args += " -r ";
+            args += cmd.getPeerGatewayIp();
+            args += " -n ";
+            args += cmd.getLocalGuestCidr();
+            args += " -N ";
+            args += cmd.getPeerGuestCidrList();
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.S2SVPN_IPSEC, args);
+            result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "Setup site2site VPN falied due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, "Setup site2site VPN failed due to " + e.getMessage());
+        }
+        return new Answer(cmd, true, result.second());
+    }
+
+    protected SetSourceNatAnswer execute(final SetSourceNatCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetSourceNatCommand " + s_gson.toJson(cmd));
+        }
+
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String routerIp = getRouterSshControlIp(cmd);
+        final IpAddressTO pubIp = cmd.getIpAddress();
+        try {
+            final int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
+            String args = "";
+            args += " -A ";
+            args += " -l ";
+            args += pubIp.getPublicIp();
+
+            args += " -c ";
+            args += "eth" + ethDeviceNum;
+
+            final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.VPC_SOURCE_NAT, args);
+
+            final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                final String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second();
+                s_logger.error(msg);
+
+                return new SetSourceNatAnswer(cmd, false, msg);
+            }
+
+            return new SetSourceNatAnswer(cmd, true, "success");
+        } catch (final Exception e) {
+            final String msg = "Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new SetSourceNatAnswer(cmd, false, msg);
+        }
+    }
+
+    protected Answer execute(final SetPortForwardingRulesCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd));
+        }
+
+        final String controlIp = getRouterSshControlIp(cmd);
+        String args = "";
+        final String[] results = new String[cmd.getRules().length];
+        int i = 0;
+
+        boolean endResult = true;
+        for (final PortForwardingRuleTO rule : cmd.getRules()) {
+            args += rule.revoked() ? " -D " : " -A ";
+            args += " -P " + rule.getProtocol().toLowerCase();
+            args += " -l " + rule.getSrcIp();
+            args += " -p " + rule.getStringSrcPortRange();
+            args += " -r " + rule.getDstIp();
+            args += " -d " + rule.getStringDstPortRange();
+
+            try {
+                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall.sh " + args);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args);
+                }
+
+                if (!result.first()) {
+                    s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args);
+                    results[i++] = "Failed";
+                    endResult = false;
+                } else {
+                    results[i++] = null;
+                }
+            } catch (final Throwable e) {
+                s_logger.error("SetPortForwardingRulesCommand(args: " + args + ") failed on setting one rule due to " + e.getMessage());
+                results[i++] = "Failed";
+                endResult = false;
+            }
+        }
+
+        return new SetPortForwardingRulesAnswer(cmd, results, endResult);
+    }
+
+    protected Answer execute(final CheckRouterCommand cmd) {
+        final String command = String.format("%s%s", "/opt/cloud/bin/", VRScripts.RVR_CHECK);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Executing resource CheckRouterCommand: " + s_gson.toJson(cmd));
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
+        }
+
+        Pair<Boolean, String> result;
+        try {
+
+            final String controlIp = getRouterSshControlIp(cmd);
+            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("check router command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
+
+                return new CheckRouterAnswer(cmd, "CheckRouter failed due to " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("check router command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "CheckRouterCommand failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new CheckRouterAnswer(cmd, msg);
+        }
+        return new CheckRouterAnswer(cmd, result.second(), true);
+    }
+
+    protected Answer execute(final SetStaticNatRulesCommand cmd) {
+
+        if (cmd.getVpcId() != null) {
+            //return SetVPCStaticNatRules(cmd);
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetFirewallRuleCommand: " + s_gson.toJson(cmd));
+        }
+
+        String args = null;
+        final String[] results = new String[cmd.getRules().length];
+        int i = 0;
+        boolean endResult = true;
+        for (final StaticNatRuleTO rule : cmd.getRules()) {
+            // 1:1 NAT needs instanceip;publicip;domrip;op
+            args = rule.revoked() ? " -D " : " -A ";
+
+            args += " -l " + rule.getSrcIp();
+            args += " -r " + rule.getDstIp();
+
+            if (rule.getProtocol() != null) {
+                args += " -P " + rule.getProtocol().toLowerCase();
+            }
+
+            args += " -d " + rule.getStringSrcPortRange();
+            args += " -G ";
+
+            try {
+                final String controlIp = getRouterSshControlIp(cmd);
+                final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall.sh " + args);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args);
+                }
+
+                if (!result.first()) {
+                    s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args);
+                    results[i++] = "Failed";
+                    endResult = false;
+                } else {
+                    results[i++] = null;
+                }
+            } catch (final Throwable e) {
+                s_logger.error("SetStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + e.getMessage());
+                results[i++] = "Failed";
+                endResult = false;
+            }
+        }
+        return new SetStaticNatRulesAnswer(cmd, results, endResult);
+    }
+
+    protected Answer execute(final PingTestCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PingTestCommand: " + s_gson.toJson(cmd));
+        }
+        final String controlIp = cmd.getRouterIp();
+        final String args = " -c 1 -n -q " + cmd.getPrivateIp();
+        try {
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/bin/ping" + args);
+            if (result.first()) {
+                return new Answer(cmd);
+            }
+        } catch (final Exception e) {
+            s_logger.error("Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + e.getMessage());
+        }
+        return new Answer(cmd, false, "PingTestCommand failed");
+    }
+
+    protected Answer execute(final DeleteIpAliasCommand cmd) {
+        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final List<IpAliasTO> revokedIpAliasTOs = cmd.getDeleteIpAliasTos();
+        final List<IpAliasTO> activeIpAliasTOs = cmd.getCreateIpAliasTos();
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing deleteIpAlias command: " + s_gson.toJson(cmd));
+        }
+        final StringBuilder args = new StringBuilder();
+        for (final IpAliasTO ipAliasTO : revokedIpAliasTOs) {
+            args.append(ipAliasTO.getAlias_count());
+            args.append(":");
+            args.append(ipAliasTO.getRouterip());
+            args.append(":");
+            args.append(ipAliasTO.getNetmask());
+            args.append("-");
+        }
+        args.append("- ");
+        for (final IpAliasTO ipAliasTO : activeIpAliasTOs) {
+            args.append(ipAliasTO.getAlias_count());
+            args.append(":");
+            args.append(ipAliasTO.getRouterip());
+            args.append(":");
+            args.append(ipAliasTO.getNetmask());
+            args.append("-");
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/deleteIpAlias " + args);
+        }
+
+        try {
+            final String controlIp = getRouterSshControlIp(cmd);
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/deleteIpAlias.sh " + args);
+
+            if (!result.first()) {
+                s_logger.error("deleteIpAlias command on domr " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "deleteIpAlias failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("deleteIpAlias command on domain router " + controlIp + " completed");
+            }
+
+        } catch (final Throwable e) {
+            final String msg = "deleteIpAlias failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final LoadBalancerConfigCommand cmd) {
+
+        if (cmd.getVpcId() != null) {
+            //return VPCLoadBalancerConfig(cmd);
+        }
+
+        final File keyFile = getSystemVMKeyFile();
+
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String controlIp = getRouterSshControlIp(cmd);
+
+        assert controlIp != null;
+
+        final LoadBalancerConfigurator cfgtr = new HAProxyConfigurator();
+        final String[] config = cfgtr.generateConfiguration(cmd);
+
+        final String[][] rules = cfgtr.generateFwRules(cmd);
+        final String tmpCfgFilePath = "/tmp/" + routerIp.replace('.', '_') + ".cfg";
+        final StringBuilder tmpCfgFileContents = new StringBuilder();
+        for (int i = 0; i < config.length; i++) {
+            tmpCfgFileContents.append(config[i]);
+            tmpCfgFileContents.append("\n");
+        }
+
+        try {
+            SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", keyFile, null, "/tmp/", tmpCfgFileContents.toString().getBytes(Charset.forName("UTF-8")), routerIp.replace('.', '_') +
+                    ".cfg", null);
+
+            try {
+                final String[] addRules = rules[LoadBalancerConfigurator.ADD];
+                final String[] removeRules = rules[LoadBalancerConfigurator.REMOVE];
+                final String[] statRules = rules[LoadBalancerConfigurator.STATS];
+
+                String args = "";
+                args += "-i " + routerIp;
+                args += " -f " + tmpCfgFilePath;
+
+                StringBuilder sb = new StringBuilder();
+                if (addRules.length > 0) {
+                    for (int i = 0; i < addRules.length; i++) {
+                        sb.append(addRules[i]).append(',');
+                    }
+
+                    args += " -a " + sb.toString();
+                }
+
+                sb = new StringBuilder();
+                if (removeRules.length > 0) {
+                    for (int i = 0; i < removeRules.length; i++) {
+                        sb.append(removeRules[i]).append(',');
+                    }
+
+                    args += " -d " + sb.toString();
+                }
+
+                sb = new StringBuilder();
+                if (statRules.length > 0) {
+                    for (int i = 0; i < statRules.length; i++) {
+                        sb.append(statRules[i]).append(',');
+                    }
+
+                    args += " -s " + sb.toString();
+                }
+
+                Pair<Boolean, String> result =
+                        SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "scp " + tmpCfgFilePath + " /etc/haproxy/haproxy.cfg.new");
+
+                if (!result.first()) {
+                    s_logger.error("Unable to copy haproxy configuration file");
+                    return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to unable to copy haproxy configuration file");
+                }
+
+                final String command = String.format("%s%s %s", "/root/", VRScripts.LB, args);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Run command on domain router " + routerIp + command);
+                }
+
+                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+                if (!result.first()) {
+                    final String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second();
+                    s_logger.error(msg);
+
+                    return new Answer(cmd, false, msg);
+                }
+
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed");
+                }
+            } finally {
+                SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm " + tmpCfgFilePath);
+            }
+
+            return new Answer(cmd);
+        } catch (final Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString(), e);
+            return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + e.getMessage());
+        }
+    }
+
+    protected Answer execute(final SavePasswordCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+
+            s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " +
+                    StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
+        }
+
+        final String controlIp = getRouterSshControlIp(cmd);
+        final String password = cmd.getPassword();
+        final String vmIpAddress = cmd.getVmIpAddress();
+
+        // Run save_password_to_domr.sh
+        final String command = String.format("%s%s %s %s %s %s", "/opt/cloud/bin/", VRScripts.PASSWORD, "-v", vmIpAddress, "-p", password);
+
+        if (s_logger.isDebugEnabled()) {
+            final String debugCommand = String.format("%s%s %s %s %s %s", "/opt/cloud/bin/", VRScripts.PASSWORD, "-v", vmIpAddress, "-p", StringUtils.getMaskedPasswordForDisplay(cmd.getPassword()));
+            s_logger.debug("Run command on domain router " + controlIp + debugCommand);
+        }
+
+        try {
+
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "SavePassword failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("savepassword command on domain router " + controlIp + " completed");
+            }
+
+        } catch (final Throwable e) {
+            final String msg = "SavePasswordCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd);
+    }
+
+    protected SetFirewallRulesAnswer execute(final SetFirewallRulesCommand cmd) {
+        final String controlIp = getRouterSshControlIp(cmd);
+        final String[] results = new String[cmd.getRules().length];
+        final FirewallRuleTO[] allrules = cmd.getRules();
+        final FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
+        final String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT);
+
+        final String[][] rules = cmd.generateFwRules();
+        String args = "";
+        args += " -F ";
+        if (trafficType == FirewallRule.TrafficType.Egress) {
+            args += " -E ";
+            if (egressDefault.equals("true")) {
+                args += " -P 1 ";
+            } else if (egressDefault.equals("System")) {
+                args += " -P 2 ";
+            } else {
+                args += " -P 0 ";
+            }
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        final String[] fwRules = rules[0];
+        if (fwRules.length > 0) {
+            for (int i = 0; i < fwRules.length; i++) {
+                sb.append(fwRules[i]).append(',');
+            }
+            args += " -a " + sb.toString();
+        }
+
+        try {
+            Pair<Boolean, String> result = null;
+
+            if (trafficType == FirewallRule.TrafficType.Egress) {
+                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewallRule_egress.sh " + args);
+            } else {
+                result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/firewall_rule.sh " + args);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                if (trafficType == FirewallRule.TrafficType.Egress) {
+                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewallRule_egress.sh " + args);
+                } else {
+                    s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall_rule.sh " + args);
+                }
+            }
+
+            if (!result.first()) {
+                s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args);
+                //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails
+                for (int i = 0; i < results.length; i++) {
+                    results[i] = "Failed";
+                }
+
+                return new SetFirewallRulesAnswer(cmd, false, results);
+            }
+        } catch (final Throwable e) {
+            s_logger.error("SetFirewallRulesCommand(args: " + args + ") failed on setting one rule due to ", e);
+            //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails
+            for (int i = 0; i < results.length; i++) {
+                results[i] = "Failed";
+            }
+            return new SetFirewallRulesAnswer(cmd, false, results);
+        }
+
+        return new SetFirewallRulesAnswer(cmd, true, results);
+    }
+
+    protected Answer execute(final VmDataCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd));
+        }
+        final String controlIp = getRouterSshControlIp(cmd);
+        final Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
+        data.put(cmd.getVmIpAddress(), cmd.getVmData());
+
+        String json = new Gson().toJson(data);
+        s_logger.debug("VM data JSON IS:" + json);
+
+        json = Base64.encodeBase64String(json.getBytes(Charset.forName("UTF-8")));
+        final String command = String.format("%s%s %s %s", "/opt/cloud/bin/", VRScripts.VMDATA, "-d", json);
+
+        try {
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+            if (!result.first()) {
+                s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second());
+                return new Answer(cmd, false, "VmDataCommand failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("vm_data command on domain router " + controlIp + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "VmDataCommand failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final DhcpEntryCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd));
+        }
+
+        // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null
+
+        String args = " -m " + cmd.getVmMac();
+        if (cmd.getVmIpAddress() != null) {
+            args += " -4 " + cmd.getVmIpAddress();
+        }
+        args += " -h " + cmd.getVmName();
+
+        if (cmd.getDefaultRouter() != null) {
+            args += " -d " + cmd.getDefaultRouter();
+        }
+
+        if (cmd.getDefaultDns() != null) {
+            args += " -n " + cmd.getDefaultDns();
+        }
+
+        if (cmd.getStaticRoutes() != null) {
+            args += " -s " + cmd.getStaticRoutes();
+        }
+
+        if (cmd.getVmIp6Address() != null) {
+            args += " -6 " + cmd.getVmIp6Address();
+            args += " -u " + cmd.getDuid();
+        }
+
+        if (!cmd.isDefault()) {
+            args += " -N";
+        }
+
+        final String command = String.format("%s%s %s", "/root/", VRScripts.DHCP, args);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
+        }
+
+        try {
+            final String controlIp = getRouterSshControlIp(cmd);
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "DhcpEntry failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("dhcp_entry command on domain router " + controlIp + " completed");
+            }
+
+        } catch (final Throwable e) {
+            final String msg = "DhcpEntryCommand failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final CreateIpAliasCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing createIpAlias command: " + s_gson.toJson(cmd));
+        }
+        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final List<IpAliasTO> ipAliasTOs = cmd.getIpAliasList();
+        final StringBuilder args = new StringBuilder();
+        for (final IpAliasTO ipaliasto : ipAliasTOs) {
+            args.append(ipaliasto.getAlias_count());
+            args.append(":");
+            args.append(ipaliasto.getRouterip());
+            args.append(":");
+            args.append(ipaliasto.getNetmask());
+            args.append("-");
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/createIpAlias " + args);
+        }
+
+        try {
+            final String controlIp = getRouterSshControlIp(cmd);
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/createIpAlias.sh " + args);
+
+            if (!result.first()) {
+                s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second());
+
+                return new Answer(cmd, false, "createipAlias failed due to " + result.second());
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("createIpAlias command on domain router " + controlIp + " completed");
+            }
+
+        } catch (final Throwable e) {
+            final String msg = "createIpAlias failed due to " + e;
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(final DnsMasqConfigCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing dnsmasqConfig command: " + s_gson.toJson(cmd));
+        }
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String controlIp = getRouterSshControlIp(cmd);
+
+        assert controlIp != null;
+
+        final List<DhcpTO> dhcpTos = cmd.getIps();
+        final StringBuilder args = new StringBuilder();
+        for (final DhcpTO dhcpTo : dhcpTos) {
+            args.append(dhcpTo.getRouterIp());
+            args.append(":");
+            args.append(dhcpTo.getGateway());
+            args.append(":");
+            args.append(dhcpTo.getNetmask());
+            args.append(":");
+            args.append(dhcpTo.getStartIpOfSubnet());
+            args.append("-");
+        }
+
+        try {
+            final String command = String.format("%s%s %s", "/root/", VRScripts.DHCP, args);
+
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Run command on domain router " + routerIp + ",  /root/dnsmasq.sh");
+            }
+
+            if (!result.first()) {
+                s_logger.error("Unable update dnsmasq config file");
+                return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "Dnsmasqconfig command failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+
+        return new Answer(cmd);
+    }
+
+    //
+    // find mac address of a specified ethx device
+    //    ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
+    // returns
+    //      eth0:xx.xx.xx.xx
+
+    //
+    // list IP with eth devices
+    //  ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
+    //     | awk -F: '{ print $1 ": " $3 }'
+    //
+    // returns
+    //      eth0:xx.xx.xx.xx
+    //
+    //
+
+    private int findRouterEthDeviceIndex(final String domrName, final String routerIp, final String mac) throws Exception {
+
+        s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
+
+        // TODO : this is a temporary very inefficient solution, will refactor it later
+        final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                "ls /proc/sys/net/ipv4/conf");
+
+        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
+        // we use a waiting loop here as a workaround to synchronize activities in systems
+        final long startTick = System.currentTimeMillis();
+        while (System.currentTimeMillis() - startTick < 15000) {
+            if (result.first()) {
+                final String[] tokens = result.second().split("\\s+");
+                for (final String token : tokens) {
+                    if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
+                        final String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Run domr script " + cmd);
+                        }
+                        final Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                                // TODO need to find the dev index inside router based on IP address
+                                cmd);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
+                        }
+
+                        if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) {
+                            return Integer.parseInt(token.substring(3));
+                        }
+                    }
+                }
+            }
+
+            s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
+
+        }
+
+        return -1;
+    }
+
+    private Pair<Integer, String> findRouterFreeEthDeviceIndex(final String routerIp) throws Exception {
+
+        s_logger.info("findRouterFreeEthDeviceIndex. mac: ");
+
+        // TODO : this is a temporary very inefficient solution, will refactor it later
+        final Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                "ip address | grep DOWN| cut -f2 -d :");
+
+        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
+        // we use a waiting loop here as a workaround to synchronize activities in systems
+        final long startTick = System.currentTimeMillis();
+        while (System.currentTimeMillis() - startTick < 15000) {
+            if (result.first() && !result.second().isEmpty()) {
+                final String[] tokens = result.second().split("\\n");
+                for (final String token : tokens) {
+                    if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
+                        //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+                        //TODO: don't check for eth0,1,2, as they will be empty by default.
+                        //String cmd = String.format("ip address show %s ", token);
+                        final String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Run domr script " + cmd);
+                        }
+                        final Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+                                // TODO need to find the dev index inside router based on IP address
+                                cmd);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
+                        }
+
+                        if (result2.first() && result2.second().trim().length() > 0) {
+                            return new Pair<Integer, String>(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ;
+                        }
+                    }
+                }
+            }
+
+            //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry...");
+
+        }
+
+        return new Pair<Integer, String>(-1, "");
+    }
+
+    protected Answer execute(final IpAssocCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd));
+        }
+
+        int i = 0;
+        final String[] results = new String[cmd.getIpAddresses().length];
+
+        try {
+
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+            final String controlIp = getRouterSshControlIp(cmd);
+            for (final IpAddressTO ip : ips) {
+                assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(),
+                        ip.getVlanNetmask(), ip.getVifMacAddress());
+                results[i++] = ip.getPublicIp() + " - success";
+            }
+
+            for (; i < cmd.getIpAddresses().length; i++) {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+        } catch (final Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
+
+            for (; i < cmd.getIpAddresses().length; i++) {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+
+    protected int getVmFreeNicIndex(final String vmName) {
+        final GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
+        URI agentUri = null;
+        int nicposition = -1;
+        try {
+            final String cmdName = GetVmConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        final String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
+        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("GetVmConfigCommand response received "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+            final GetVmConfigAnswer ans = (GetVmConfigAnswer)result[0];
+            final List<NicDetails> nics = ans.getNics();
+            for (final NicDetails nic : nics) {
+                if (nic.getState() == false) {
+                    nicposition = nics.indexOf(nic);
+                    break;
+                }
+            }
+        }
+        return nicposition;
+    }
+
+    protected int getVmNics(final String vmName, String vlanid) {
+        final GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
+        URI agentUri = null;
+        int nicposition = -1;
+        if(vlanid.equalsIgnoreCase("untagged")) {
+            vlanid = "-1";
+        }
+        try {
+            final String cmdName = GetVmConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        final String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
+        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("executeRequest received response "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+            final GetVmConfigAnswer ans = (GetVmConfigAnswer)result[0];
+            final List<NicDetails> nics = ans.getNics();
+            for (final NicDetails nic : nics) {
+                nicposition++;
+                if (nicposition > 1 && nic.getVlanid().equals(vlanid)) {
+                    break;
+                }
+            }
+        }
+        return nicposition;
+    }
+
+    protected void modifyNicVlan(final String vmName, final String vlanId, final String macAddress) {
+        final ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress);
+        URI agentUri = null;
+        try {
+            final String cmdName = ModifyVmNicConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        final String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
+        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("executeRequest received response "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+        }
+    }
+
+    protected void modifyNicVlan(final String vmName, final String vlanId, final int pos, final boolean enable, final String switchLabelName) {
+        final ModifyVmNicConfigCommand modifyNic = new ModifyVmNicConfigCommand(vmName, vlanId, pos, enable);
+        modifyNic.setSwitchLableName(switchLabelName);
+        URI agentUri = null;
+        try {
+            final String cmdName = ModifyVmNicConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (final URISyntaxException e) {
+            final String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        final String ansStr = postHttpRequest(s_gson.toJson(modifyNic), agentUri);
+        final Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("executeRequest received response "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+        }
+    }
+
+    protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
+            final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
+
+        final URI broadcastUri = BroadcastDomainType.fromString(broadcastId);
+        if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+            throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId);
+        }
+        final String vlanId = BroadcastDomainType.getValue(broadcastUri);
+
+        int publicNicInfo = -1;
+        publicNicInfo = getVmNics(vmName, vlanId);
+
+        boolean addVif = false;
+        if (add && publicNicInfo == -1) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress);
+            }
+            addVif = true;
+        } else if (!add && firstIP) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unplug NIC " + publicNicInfo);
+            }
+        }
+
+        if (addVif) {
+            final Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress);
+            publicNicInfo = nicdevice.first();
+            if (publicNicInfo > 0) {
+                modifyNicVlan(vmName, vlanId, nicdevice.second());
+                // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
+                publicNicInfo = getVmNics(vmName, vlanId);
+                // As a new nic got activated in the VR. add the entry in the NIC's table.
+                networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo);
+            }
+            else {
+                // we didn't find any eth device available in VR to configure the ip range with new VLAN
+                final String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
+                s_logger.error(msg);
+                throw new InternalErrorException(msg);
+            }
+        }
+
+        String args = null;
+
+        if (add) {
+            args = " -A ";
+        } else {
+            args = " -D ";
+        }
+
+        if (sourceNat) {
+            args += " -s ";
+        }
+        if (firstIP) {
+            args += " -f ";
+        }
+        final String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
+        args += " -l ";
+        args += publicIpAddress + "/" + cidrSize;
+
+        args += " -c ";
+
+        args += "eth" + publicNicInfo;
+        args += " -g ";
+        args += vlanGateway;
+
+        if (addVif) {
+            args += " -n ";
+        }
+
+        final String command = String.format("%s%s %s","/opt/cloud/bin/", VRScripts.IPASSOC ,args);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on domain router " + privateIpAddress + command);
+        }
+
+        final Pair<Boolean, String> result =
+                SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+        if (!result.first()) {
+            s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second());
+            throw new Exception("ipassoc failed due to " + result.second());
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed");
+        }
+    }
+
+    protected Answer execute(final GetDomRVersionCmd cmd) {
+        final String command = String.format("%s%s", "/opt/cloud/bin/", VRScripts.VERSION);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Executing resource GetDomRVersionCmd: " + s_gson.toJson(cmd));
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + command);
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            final String controlIp = getRouterSshControlIp(cmd);
+            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
+
+                return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (final Throwable e) {
+            final String msg = "GetDomRVersionCmd failed due to " + e;
+            s_logger.error(msg, e);
+            return new GetDomRVersionAnswer(cmd, msg);
+        }
+        final String[] lines = result.second().split("&");
+        if (lines.length != 2) {
+            return new GetDomRVersionAnswer(cmd, result.second());
+        }
+        return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]);
+    }
+
+    private static String getRouterSshControlIp(final NetworkElementCommand cmd) {
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String routerGuestIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
+        final String zoneNetworkType = cmd.getAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE);
+
+        if (routerGuestIp != null && zoneNetworkType != null && NetworkType.valueOf(zoneNetworkType) == NetworkType.Basic) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("In Basic zone mode, use router's guest IP for SSH control. guest IP : " + routerGuestIp);
+            }
+
+            return routerGuestIp;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
+        }
+        return routerIp;
+    }
+
+    protected Answer execute(final NetworkUsageCommand cmd) {
+        if (cmd.isForVpc()) {
+            //return VPCNetworkUsage(cmd);
+        }
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource NetworkUsageCommand " + s_gson.toJson(cmd));
+        }
+        if (cmd.getOption() != null && cmd.getOption().equals("create")) {
+            networkUsage(cmd.getPrivateIP(), "create", null);
+            final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "true", 0L, 0L);
+            return answer;
+        }
+        final long[] stats = getNetworkStats(cmd.getPrivateIP());
+
+        final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
+        return answer;
+    }
+
+    private long[] getNetworkStats(final String privateIP) {
+        final String result = networkUsage(privateIP, "get", null);
+        final long[] stats = new long[2];
+        if (result != null) {
+            try {
+                final String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += Long.parseLong(splitResult[i++]);
+                    stats[1] += Long.parseLong(splitResult[i++]);
+                }
+            } catch (final Throwable e) {
+                s_logger.warn("Unable to parse return from script return of network usage command: " + e.toString(), e);
+            }
+        }
+        return stats;
+    }
+
+    protected Answer execute(final SetMonitorServiceCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetMonitorServiceCommand: " + s_gson.toJson(cmd));
+        }
+
+        final String controlIp = getRouterSshControlIp(cmd);
+        final String config = cmd.getConfiguration();
+        final String args = String.format(" %s %s", "-c", config);
+
+        final String command = String.format("%s%s %s", "/opt/cloud/bin/", VRScripts.MONITOR_SERVICE, args);
+
+        try {
+            final Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, command);
+
+            if (!result.first()) {
+                final String msg=  "monitor_service.sh failed on domain router " + controlIp + " failed " + result.second();
+                s_logger.error(msg);
+                return new Answer(cmd, false, msg);
+            }
+
+            return new Answer(cmd);
+
+        } catch (final Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString(), e);
+            return new Answer(cmd, false, "SetMonitorServiceCommand failed due to " + e);
+        }
+    }
+
+    protected CheckSshAnswer execute(final CheckSshCommand cmd) {
+        final String vmName = cmd.getName();
+        final String privateIp = cmd.getIp();
+        final int cmdPort = cmd.getPort();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
+        }
+
+        try {
+            final String result = connect(cmd.getName(), privateIp, cmdPort);
+            if (result != null) {
+                s_logger.error("Can not ping System vm " + vmName + "due to:" + result);
+                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
+            }
+        } catch (final Exception e) {
+            s_logger.error("Can not ping System vm " + vmName + "due to exception");
+            return new CheckSshAnswer(cmd, e);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port succeeded for vm " + vmName);
+        }
+
+        if (VirtualMachineName.isValidRouterName(vmName)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Execute network usage setup command on " + vmName);
+            }
+            networkUsage(privateIp, "create", null);
+        }
+
+        return new CheckSshAnswer(cmd);
+    }
+
+    protected String networkUsage(final String privateIpAddress, final String option, final String ethName) {
+        String args = null;
+        if (option.equals("get")) {
+            args = "-g";
+        } else if (option.equals("create")) {
+            args = "-c";
+        } else if (option.equals("reset")) {
+            args = "-r";
+        } else if (option.equals("addVif")) {
+            args = "-a";
+            args += ethName;
+        } else if (option.equals("deleteVif")) {
+            args = "-d";
+            args += ethName;
+        }
+
+        try {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress);
+            }
+
+            final Pair<Boolean, String> result =
+                    SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args);
+
+            if (!result.first()) {
+                return null;
+            }
+
+            return result.second();
+        } catch (final Throwable e) {
+            s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to " + e);
+        }
+
+        return null;
+    }
+
+    public File getSystemVMKeyFile() {
+        final URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
+        File keyFile = null;
+        if (url != null) {
+            keyFile = new File(url.getPath());
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
+        }
+        assert keyFile != null;
+        if (!keyFile.exists()) {
+            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
+        }
+        return keyFile;
+    }
+
+    public static String postHttpRequest(final String jsonCmd, final URI agentUri) {
+        // Using Apache's HttpClient for HTTP POST
+        // Java-only approach discussed at on StackOverflow concludes with
+        // comment to use Apache HttpClient
+        // http://stackoverflow.com/a/2793153/939250, but final comment is to
+        // use Apache.
+        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
+        logMessage = cleanPassword(logMessage);
+        s_logger.debug("POST request to " + agentUri.toString()
+                + " with contents " + logMessage);
+
+        // Create request
+        HttpClient httpClient = null;
+        final TrustStrategy easyStrategy = new TrustStrategy() {
+            @Override
+            public boolean isTrusted(final X509Certificate[] chain, final String authType)
+                    throws CertificateException {
+                return true;
+            }
+        };
+
+        try {
+            final SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
+            final SchemeRegistry registry = new SchemeRegistry();
+            registry.register(new Scheme("https", DEFAULT_AGENT_PORT, sf));
+            final ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
+            httpClient = new DefaultHttpClient(ccm);
+        } catch (final KeyManagementException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (final UnrecoverableKeyException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (final NoSuchAlgorithmException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (final KeyStoreException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        }
+
+        String result = null;
+
+        // TODO: are there timeout settings and worker thread settings to tweak?
+        try {
+            final HttpPost request = new HttpPost(agentUri);
+
+            // JSON encode command
+            // Assumes command sits comfortably in a string, i.e. not used for
+            // large data transfers
+            final StringEntity cmdJson = new StringEntity(jsonCmd);
+            request.addHeader("content-type", "application/json");
+            request.setEntity(cmdJson);
+            s_logger.debug("Sending cmd to " + agentUri.toString()
+                    + " cmd data:" + logMessage);
+            final HttpResponse response = httpClient.execute(request);
+
+            // Unsupported commands will not route.
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+                final String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode();
+                s_logger.error(errMsg);
+                final String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right type of" + " server?";
+                final Answer ans = new UnsupportedAnswer(null, unsupportMsg);
+                s_logger.error(ans);
+                result = s_gson.toJson(new Answer[] {ans});
+            } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+                final String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
+                s_logger.error(errMsg);
+                return null;
+            } else {
+                result = EntityUtils.toString(response.getEntity());
+                final String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
+                s_logger.debug("POST response is " + logResult);
+            }
+        } catch (final ClientProtocolException protocolEx) {
+            // Problem with HTTP message exchange
+            s_logger.error(protocolEx);
+        } catch (final IOException connEx) {
+            // Problem with underlying communications
+            s_logger.error(connEx);
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+        return result;
+    }
+
+    @Override
+    protected final String getDefaultScriptsDir() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    // NB: 'params' can come from one of two places.
+    // For a new host, HypervServerDiscoverer.find().
+    // For an existing host, DiscovererBase.reloadResource().
+    // In the later case, the params Map is populated with predefined keys
+    // and custom keys from the database that were passed out by the find()
+    // call.
+    // the custom keys go by the variable name 'details'.
+    // Thus, in find(), you see that 'details' are added to the params Map.
+    @Override
+    public final boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        /* todo: update, make consistent with the xen server equivalent. */
+
+        if (params != null) {
+            _guid = (String)params.get("guid");
+            _zoneId = (String)params.get("zone");
+            _podId = (String)params.get("pod");
+            _clusterId = (String)params.get("cluster");
+            _agentIp = (String)params.get("ipaddress"); // was agentIp
+            _name = name;
+
+            _clusterGuid = (String)params.get("cluster.guid");
+            _username = (String)params.get("url");
+            _password = (String)params.get("password");
+            _username = (String)params.get("username");
+            _configureCalled = true;
+        }
+
+        _vrResource = new VirtualRoutingResource(this);
+        if (!_vrResource.configure(name, new HashMap<String, Object>())) {
+            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
+        }
+        return true;
+    }
+
+    @Override
+    public void setName(final String name) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void setConfigParams(final Map<String, Object> params) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public final Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public final int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(final int level) {
+        // TODO Auto-generated method stub
+    }
+
+    protected String connect(final String vmName, final String ipAddress, final int port) {
+        final long startTick = System.currentTimeMillis();
+
+        // wait until we have at least been waiting for _ops_timeout time or
+        // at least have tried _retry times, this is to coordinate with system
+        // VM patching/rebooting time that may need
+        int retry = _retry;
+        while (System.currentTimeMillis() - startTick <= _opsTimeout || --retry > 0) {
+            s_logger.info("Trying to connect to " + ipAddress);
+            try (SocketChannel sch = SocketChannel.open();) {
+                sch.configureBlocking(true);
+                sch.socket().setSoTimeout(5000);
+                // we need to connect to the control ip address to check the status of the system vm
+                final InetSocketAddress addr = new InetSocketAddress(ipAddress, port);
+                sch.connect(addr);
+                return null;
+            } catch (final IOException e) {
+                s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString());
+                if (e instanceof ConnectException) {
+                    // if connection is refused because of VM is being started,
+                    // we give it more sleep time
+                    // to avoid running out of retry quota too quickly
+                    try {
+                        Thread.sleep(5000);
+                    } catch (final InterruptedException ex) {
+                        s_logger.debug("[ignored] interupted while waiting to retry connecting to vm after exception: "+e.getLocalizedMessage());
+                    }
+                }
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (final InterruptedException ex) {
+                s_logger.debug("[ignored] interupted while connecting to vm.");
+            }
+        }
+
+        s_logger.info("Unable to logon to " + ipAddress);
+
+        return "Unable to connect";
+    }
+
+    public static String cleanPassword(final String logString) {
+        String cleanLogString = null;
+        if (logString != null) {
+            cleanLogString = logString;
+            final String[] temp = logString.split(",");
+            int i = 0;
+            if (temp != null) {
+                while (i < temp.length) {
+                    temp[i] = StringUtils.cleanString(temp[i]);
+                    i++;
+                }
+                final List<String> stringList = new ArrayList<String>();
+                Collections.addAll(stringList, temp);
+                cleanLogString = StringUtils.join(stringList, ",");
+            }
+        }
+        return cleanLogString;
+    }
+}
diff --git a/plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java b/plugins/hypervisors/hyperv/src/main/java/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java
similarity index 100%
rename from plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java
rename to plugins/hypervisors/hyperv/src/main/java/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java
diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml b/plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml
similarity index 100%
rename from plugins/hypervisors/hyperv/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml
rename to plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/core/spring-hyperv-core-context.xml
diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-compute/module.properties b/plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-compute/module.properties
rename to plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-compute/module.properties
diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-compute/spring-hyperv-compute-context.xml b/plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-compute/spring-hyperv-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-compute/spring-hyperv-compute-context.xml
rename to plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-compute/spring-hyperv-compute-context.xml
diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-discoverer/module.properties b/plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-discoverer/module.properties
rename to plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-discoverer/module.properties
diff --git a/plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-discoverer/spring-hyperv-discoverer-context.xml b/plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-discoverer/spring-hyperv-discoverer-context.xml
similarity index 100%
rename from plugins/hypervisors/hyperv/resources/META-INF/cloudstack/hyperv-discoverer/spring-hyperv-discoverer-context.xml
rename to plugins/hypervisors/hyperv/src/main/resources/META-INF/cloudstack/hyperv-discoverer/spring-hyperv-discoverer-context.xml
diff --git a/plugins/hypervisors/hyperv/conf/agent.properties b/plugins/hypervisors/hyperv/src/main/resources/agent.properties
similarity index 100%
rename from plugins/hypervisors/hyperv/conf/agent.properties
rename to plugins/hypervisors/hyperv/src/main/resources/agent.properties
diff --git a/plugins/hypervisors/hyperv/test/com/cloud/hypervisor/hyperv/test/HypervDirectConnectResourceTest.java b/plugins/hypervisors/hyperv/src/test/java/com/cloud/hypervisor/hyperv/test/HypervDirectConnectResourceTest.java
similarity index 100%
rename from plugins/hypervisors/hyperv/test/com/cloud/hypervisor/hyperv/test/HypervDirectConnectResourceTest.java
rename to plugins/hypervisors/hyperv/src/test/java/com/cloud/hypervisor/hyperv/test/HypervDirectConnectResourceTest.java
diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml
index 3cf3d87..9d7e72e 100644
--- a/plugins/hypervisors/kvm/pom.xml
+++ b/plugins/hypervisors/kvm/pom.xml
@@ -1,91 +1,96 @@
-<!-- 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. -->
+<!--
+  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-hypervisor-kvm</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor KVM</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.libvirt</groupId>
-      <artifactId>libvirt</artifactId>
-      <version>${cs.libvirt-java.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-ovs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-configdrive</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.ceph</groupId>
-      <artifactId>rados</artifactId>
-      <version>${cs.rados-java.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>net.java.dev.jna</groupId>
-       <artifactId>jna</artifactId>
-       <version>${cs.jna.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy-dependencies</id>
-            <phase>package</phase>
-            <goals>
-              <goal>copy-dependencies</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
-              <includeScope>runtime</includeScope>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <excludes>
-            <exclude>**/Qemu*.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    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-hypervisor-kvm</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor KVM</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-agent</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.libvirt</groupId>
+            <artifactId>libvirt</artifactId>
+            <version>${cs.libvirt-java.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-ovs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.cloudstack</groupId>
+          <artifactId>cloud-engine-storage-configdrive</artifactId>
+          <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ceph</groupId>
+            <artifactId>rados</artifactId>
+            <version>${cs.rados-java.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>${cs.jna.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
+                            <includeScope>runtime</includeScope>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/Qemu*.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
deleted file mode 100644
index bd410df..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.libvirt.LibvirtException;
-
-import com.google.common.base.Strings;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.network.Networks;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-public class BridgeVifDriver extends VifDriverBase {
-
-    private static final Logger s_logger = Logger.getLogger(BridgeVifDriver.class);
-    private int _timeout;
-
-    private final Object _vnetBridgeMonitor = new Object();
-    private String _modifyVlanPath;
-    private String _modifyVxlanPath;
-    private String bridgeNameSchema;
-    private Long libvirtVersion;
-
-    @Override
-    public void configure(Map<String, Object> params) throws ConfigurationException {
-
-        super.configure(params);
-
-        getPifs();
-
-        // Set the domr scripts directory
-        params.put("domr.scripts.dir", "scripts/network/domr/kvm");
-
-        String networkScriptsDir = (String)params.get("network.scripts.dir");
-        if (networkScriptsDir == null) {
-            networkScriptsDir = "scripts/vm/network/vnet";
-        }
-
-        bridgeNameSchema = (String)params.get("network.bridge.name.schema");
-
-        String value = (String)params.get("scripts.timeout");
-        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
-
-        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
-        if (_modifyVlanPath == null) {
-            throw new ConfigurationException("Unable to find modifyvlan.sh");
-        }
-        _modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
-        if (_modifyVxlanPath == null) {
-            throw new ConfigurationException("Unable to find modifyvxlan.sh");
-        }
-
-        libvirtVersion = (Long) params.get("libvirtVersion");
-        if (libvirtVersion == null) {
-            libvirtVersion = 0L;
-        }
-    }
-
-    public void getPifs() {
-        final File dir = new File("/sys/devices/virtual/net");
-        final File[] netdevs = dir.listFiles();
-        final List<String> bridges = new ArrayList<String>();
-        for (File netdev : netdevs) {
-            final File isbridge = new File(netdev.getAbsolutePath() + "/bridge");
-            final String netdevName = netdev.getName();
-            s_logger.debug("looking in file " + netdev.getAbsolutePath() + "/bridge");
-            if (isbridge.exists()) {
-                s_logger.debug("Found bridge " + netdevName);
-                bridges.add(netdevName);
-            }
-        }
-
-        String guestBridgeName = _libvirtComputingResource.getGuestBridgeName();
-        String publicBridgeName = _libvirtComputingResource.getPublicBridgeName();
-
-        for (final String bridge : bridges) {
-            s_logger.debug("looking for pif for bridge " + bridge);
-            final String pif = getPif(bridge);
-            if (_libvirtComputingResource.isPublicBridge(bridge)) {
-                _pifs.put("public", pif);
-            }
-            if (guestBridgeName != null && bridge.equals(guestBridgeName)) {
-                _pifs.put("private", pif);
-            }
-            _pifs.put(bridge, pif);
-        }
-
-        // guest(private) creates bridges on a pif, if private bridge not found try pif direct
-        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
-        if (_pifs.get("private") == null) {
-            s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' not found as bridge, looking for physical interface");
-            final File dev = new File("/sys/class/net/" + guestBridgeName);
-            if (dev.exists()) {
-                s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' found as a physical device");
-                _pifs.put("private", guestBridgeName);
-            }
-        }
-
-        // public creates bridges on a pif, if private bridge not found try pif direct
-        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
-        if (_pifs.get("public") == null) {
-            s_logger.debug("public traffic label '" + publicBridgeName+ "' not found as bridge, looking for physical interface");
-            final File dev = new File("/sys/class/net/" + publicBridgeName);
-            if (dev.exists()) {
-                s_logger.debug("public traffic label '" + publicBridgeName + "' found as a physical device");
-                _pifs.put("public", publicBridgeName);
-            }
-        }
-
-        s_logger.debug("done looking for pifs, no more bridges");
-    }
-
-    private String getPif(final String bridge) {
-        String pif = matchPifFileInDirectory(bridge);
-        final File vlanfile = new File("/proc/net/vlan/" + pif);
-
-        if (vlanfile.isFile()) {
-            pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
-        }
-
-        return pif;
-    }
-
-    private String matchPifFileInDirectory(final String bridgeName) {
-        final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
-
-        if (!brif.isDirectory()) {
-            final File pif = new File("/sys/class/net/" + bridgeName);
-            if (pif.isDirectory()) {
-                // if bridgeName already refers to a pif, return it as-is
-                return bridgeName;
-            }
-            s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?");
-            return "";
-        }
-
-        final File[] interfaces = brif.listFiles();
-
-        for (File anInterface : interfaces) {
-            final String fname = anInterface.getName();
-            s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'");
-            if (isInterface(fname)) {
-                return fname;
-            }
-        }
-
-        s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath());
-        return "";
-    }
-
-    private static final String [] IF_NAME_PATTERNS = {
-            "^eth",
-            "^bond",
-            "^vlan",
-            "^vx",
-            "^em",
-            "^ens",
-            "^eno",
-            "^enp",
-            "^team",
-            "^enx",
-            "^p\\d+p\\d+"
-    };
-
-    /**
-     * @param fname
-     * @return
-     */
-    private static boolean isInterface(final String fname) {
-        StringBuilder commonPattern = new StringBuilder();
-        for (final String ifNamePattern : IF_NAME_PATTERNS) {
-            commonPattern.append("|(").append(ifNamePattern).append(".*)");
-        }
-
-        return fname.matches(commonPattern.toString());
-    }
-
-    protected boolean isBroadcastTypeVlanOrVxlan(final NicTO nic) {
-        return nic != null && (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
-                || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan);
-    }
-
-    protected boolean isValidProtocolAndVnetId(final String vNetId, final String protocol) {
-        return vNetId != null && protocol != null && !vNetId.equalsIgnoreCase("untagged");
-    }
-
-    @Override
-    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException {
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("nic=" + nic);
-            if (nicAdapter != null && !nicAdapter.isEmpty()) {
-                s_logger.debug("custom nic adapter=" + nicAdapter);
-            }
-        }
-
-        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
-
-        String vNetId = null;
-        String protocol = null;
-        if (isBroadcastTypeVlanOrVxlan(nic)) {
-            vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-            protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
-        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
-            throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver");
-        }
-        String trafficLabel = nic.getName();
-        Integer networkRateKBps = 0;
-        if (libvirtVersion > ((10 * 1000 + 10))) {
-            networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-        }
-
-        if (nic.getType() == Networks.TrafficType.Guest) {
-            if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
-                    if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                        s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel);
-                        String brName = createVnetBr(vNetId, trafficLabel, protocol);
-                        intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    } else {
-                        String brName = createVnetBr(vNetId, "private", protocol);
-                        intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    }
-            } else {
-                String brname = "";
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    brname = trafficLabel;
-                } else {
-                    brname = _bridges.get("guest");
-                }
-                intf.defBridgeNet(brname, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            }
-        } else if (nic.getType() == Networks.TrafficType.Control) {
-            /* Make sure the network is still there */
-            createControlNetwork();
-            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Public) {
-            if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
-                    String brName = createVnetBr(vNetId, trafficLabel, protocol);
-                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                } else {
-                    String brName = createVnetBr(vNetId, "public", protocol);
-                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                }
-            } else {
-                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            }
-        } else if (nic.getType() == Networks.TrafficType.Management) {
-            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Storage) {
-            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
-            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        }
-        if (nic.getPxeDisable()) {
-            intf.setPxeDisable(true);
-        }
-
-        return intf;
-    }
-
-    @Override
-    public void unplug(LibvirtVMDef.InterfaceDef iface) {
-        deleteVnetBr(iface.getBrName());
-    }
-
-    @Override
-    public void attach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("brctl addif " + iface.getBrName() + " " + iface.getDevName());
-    }
-
-    @Override
-    public void detach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("test -d /sys/class/net/" + iface.getBrName() + "/brif/" + iface.getDevName() + " && brctl delif " + iface.getBrName() + " " + iface.getDevName());
-    }
-
-    private String setVnetBrName(String pifName, String vnetId) {
-        return "br" + pifName + "-" + vnetId;
-    }
-
-    private String setVxnetBrName(String pifName, String vnetId) {
-        return "brvx-" + vnetId;
-    }
-
-    private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
-        String nic = _pifs.get(pifKey);
-        if (nic == null) {
-            // if not found in bridge map, maybe traffic label refers to pif already?
-            File pif = new File("/sys/class/net/" + pifKey);
-            if (pif.isDirectory()) {
-                nic = pifKey;
-            }
-        }
-        String brName = "";
-        if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
-            brName = setVxnetBrName(nic, vNetId);
-        } else {
-            brName = setVnetBrName(nic, vNetId);
-        }
-        createVnet(vNetId, nic, brName, protocol);
-        return brName;
-    }
-
-    private void createVnet(String vnetId, String pif, String brName, String protocol) throws InternalErrorException {
-        synchronized (_vnetBridgeMonitor) {
-            String script = _modifyVlanPath;
-            if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
-                script = _modifyVxlanPath;
-            }
-            final Script command = new Script(script, _timeout, s_logger);
-            command.add("-v", vnetId);
-            command.add("-p", pif);
-            command.add("-b", brName);
-            command.add("-o", "add");
-
-            final String result = command.execute();
-            if (result != null) {
-                throw new InternalErrorException("Failed to create vnet " + vnetId + ": " + result);
-            }
-        }
-    }
-
-    private void deleteVnetBr(String brName) {
-        synchronized (_vnetBridgeMonitor) {
-            String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName);
-            if (cmdout == null)
-                // Bridge does not exist
-                return;
-            cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
-            if (cmdout != null && cmdout.contains("vnet")) {
-                // Active VM remains on that bridge
-                return;
-            }
-
-            Pattern oldStyleBrNameRegex = Pattern.compile("^cloudVirBr(\\d+)$");
-            Pattern brNameRegex = Pattern.compile("^br(\\S+)-(\\d+)$");
-            Matcher oldStyleBrNameMatcher = oldStyleBrNameRegex.matcher(brName);
-            Matcher brNameMatcher = brNameRegex.matcher(brName);
-
-            String pName = null;
-            String vNetId = null;
-            if (oldStyleBrNameMatcher.find()) {
-                // Actually modifyvlan.sh doesn't require pif name when deleting its bridge so far.
-                pName = "undefined";
-                vNetId = oldStyleBrNameMatcher.group(1);
-            } else if (brNameMatcher.find()) {
-                if (brNameMatcher.group(1) != null || !brNameMatcher.group(1).isEmpty()) {
-                    pName = brNameMatcher.group(1);
-                } else {
-                    pName = "undefined";
-                }
-                vNetId = brNameMatcher.group(2);
-            }
-
-            if (vNetId == null || vNetId.isEmpty()) {
-                s_logger.debug("unable to get a vNet ID from name " + brName);
-                return;
-            }
-
-            String scriptPath = null;
-            if (cmdout != null && cmdout.contains("vxlan")) {
-                scriptPath = _modifyVxlanPath;
-            } else {
-                scriptPath = _modifyVlanPath;
-            }
-
-            final Script command = new Script(scriptPath, _timeout, s_logger);
-            command.add("-o", "delete");
-            command.add("-v", vNetId);
-            command.add("-p", pName);
-            command.add("-b", brName);
-
-            final String result = command.execute();
-            if (result != null) {
-                s_logger.debug("Delete bridge " + brName + " failed: " + result);
-            }
-        }
-    }
-
-    private void deleteExistingLinkLocalRouteTable(String linkLocalBr) {
-        Script command = new Script("/bin/bash", _timeout);
-        command.add("-c");
-        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        boolean foundLinkLocalBr = false;
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                String[] tokens = line.split(" ");
-                if (tokens != null && tokens.length < 2) {
-                    continue;
-                }
-                final String device = tokens[2];
-                if (!Strings.isNullOrEmpty(device) && !device.equalsIgnoreCase(linkLocalBr)) {
-                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR() + " dev " + tokens[2]);
-                } else {
-                    foundLinkLocalBr = true;
-                }
-            }
-        }
-        if (!foundLinkLocalBr) {
-            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
-                NetUtils.getLinkLocalGateway());
-        }
-    }
-
-    private void createControlNetwork() {
-        createControlNetwork(_bridges.get("linklocal"));
-    }
-
-    @Override
-    public void createControlNetwork(String privBrName)  {
-        deleteExistingLinkLocalRouteTable(privBrName);
-        if (!isExistingBridge(privBrName)) {
-            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
-        }
-    }
-
-    @Override
-    public boolean isExistingBridge(String bridgeName) {
-        File f = new File("/sys/devices/virtual/net/" + bridgeName + "/bridge");
-        if (f.exists()) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
deleted file mode 100644
index b8763fa..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import org.apache.log4j.Logger;
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.network.Networks;
-
-public class DirectVifDriver extends VifDriverBase {
-
-    private static final Logger s_logger = Logger.getLogger(DirectVifDriver.class);
-
-    /**
-     * Experimental driver to configure direct networking in libvirt. This should only
-     * be used on an LXC cluster that does not run any system VMs.
-     *
-     * @param nic
-     * @param guestOsType
-     * @return
-     * @throws InternalErrorException
-     * @throws LibvirtException
-     */
-    @Override
-    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException {
-        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
-
-        if (nic.getType() == Networks.TrafficType.Guest) {
-            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter),
-                _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps);
-
-        } else if (nic.getType() == Networks.TrafficType.Public) {
-            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter),
-                _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps);
-        }
-
-        return intf;
-    }
-
-    @Override
-    public void unplug(LibvirtVMDef.InterfaceDef iface) {
-        // not needed, libvirt will cleanup
-    }
-
-    @Override
-    public void attach(LibvirtVMDef.InterfaceDef iface) {
-
-    }
-
-    @Override
-    public void detach(LibvirtVMDef.InterfaceDef iface) {
-
-    }
-
-    @Override
-    public void createControlNetwork(String privBrName) {
-    }
-
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java
deleted file mode 100644
index 8e73d85..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.File;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.network.Networks;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-public class IvsVifDriver extends VifDriverBase {
-    private static final Logger s_logger = Logger.getLogger(IvsVifDriver.class);
-    private int _timeout;
-
-    private final Object _vnetBridgeMonitor = new Object();
-    private String _modifyVlanPath;
-    private String _modifyVxlanPath;
-    private String _ivsIfUpPath;
-    private Long libvirtVersion;
-
-    @Override
-    public void configure(Map<String, Object> params) throws ConfigurationException {
-        super.configure(params);
-        String networkScriptsDir = (String)params.get("network.scripts.dir");
-        if (networkScriptsDir == null) {
-            networkScriptsDir = "scripts/vm/network/vnet";
-        }
-        String utilScriptsDir = "scripts/util/";
-
-        String value = (String)params.get("scripts.timeout");
-        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
-
-        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
-        if (_modifyVlanPath == null) {
-            throw new ConfigurationException("Unable to find modifyvlan.sh");
-        }
-        _modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
-        if (_modifyVxlanPath == null) {
-            throw new ConfigurationException("Unable to find modifyvxlan.sh");
-        }
-        _ivsIfUpPath = Script.findScript(utilScriptsDir, "qemu-ivs-ifup");
-
-        libvirtVersion = (Long) params.get("libvirtVersion");
-        if (libvirtVersion == null) {
-            libvirtVersion = 0L;
-        }
-    }
-
-    @Override
-    public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException {
-        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
-
-        String vNetId = null;
-        String protocol = null;
-        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
-            vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-            protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
-        }
-
-        String vlanId = null;
-        String logicalSwitchUuid = null;
-        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
-            vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
-            logicalSwitchUuid = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
-            // TODO consider moving some of this functionality from NetUtils to Networks....
-            vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
-        }
-        String trafficLabel = nic.getName();
-        Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-        if (nic.getType() == Networks.TrafficType.Guest) {
-            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) &&
-                    !vlanId.equalsIgnoreCase("untagged")) {
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
-                    intf.defEthernet("ivsnet-" + nic.getUuid().substring(0, 5), nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), _ivsIfUpPath, networkRateKBps);
-                } else {
-                    throw new InternalErrorException("no traffic label ");
-                }
-            }
-        } else if (nic.getType() == Networks.TrafficType.Control) {
-            /* Make sure the network is still there */
-            createControlNetwork();
-            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Public) {
-            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) ||
-                    (nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) {
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
-                    String brName = createVnetBr(vNetId, trafficLabel, protocol);
-                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                } else {
-                    String brName = createVnetBr(vNetId, "public", protocol);
-                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                }
-            } else {
-                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            }
-        } else if (nic.getType() == Networks.TrafficType.Management) {
-            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Storage) {
-            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
-            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        }
-        if (nic.getPxeDisable() == true) {
-            intf.setPxeDisable(true);
-        }
-        return intf;
-    }
-
-    @Override
-    public void unplug(InterfaceDef iface) {
-    }
-
-    @Override
-    public void attach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("/usr/sbin/ivs-ctl add-port " + iface.getDevName());
-    }
-
-    @Override
-    public void detach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("/usr/sbin/ivs-ctl del-port " + iface.getDevName());
-    }
-
-
-    private void createControlNetwork() throws LibvirtException {
-        createControlNetwork(_bridges.get("linklocal"));
-    }
-
-    private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
-        String nic = _pifs.get(pifKey);
-        if (nic == null) {
-            // if not found in bridge map, maybe traffic label refers to pif already?
-            File pif = new File("/sys/class/net/" + pifKey);
-            if (pif.isDirectory()) {
-                nic = pifKey;
-            }
-        }
-        String brName = "";
-        brName = setVnetBrName(nic, vNetId);
-        createVnet(vNetId, nic, brName, protocol);
-        return brName;
-    }
-
-    private String setVnetBrName(String pifName, String vnetId) {
-        return "br" + pifName + "-" + vnetId;
-    }
-
-    private void createVnet(String vnetId, String pif, String brName, String protocol) throws InternalErrorException {
-        synchronized (_vnetBridgeMonitor) {
-            String script = _modifyVlanPath;
-            if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
-                script = _modifyVxlanPath;
-            }
-            final Script command = new Script(script, _timeout, s_logger);
-            command.add("-v", vnetId);
-            command.add("-p", pif);
-            command.add("-b", brName);
-            command.add("-o", "add");
-
-            final String result = command.execute();
-            if (result != null) {
-                throw new InternalErrorException("Failed to create vnet " + vnetId + ": " + result);
-            }
-        }
-    }
-
-    private void deleteVnetBr(String brName) {
-        synchronized (_vnetBridgeMonitor) {
-            String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName);
-            if (cmdout == null)
-                // Bridge does not exist
-                return;
-            cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
-            if (cmdout != null && cmdout.contains("vnet")) {
-                // Active VM remains on that bridge
-                return;
-            }
-
-            Pattern oldStyleBrNameRegex = Pattern.compile("^cloudVirBr(\\d+)$");
-            Pattern brNameRegex = Pattern.compile("^br(\\S+)-(\\d+)$");
-            Matcher oldStyleBrNameMatcher = oldStyleBrNameRegex.matcher(brName);
-            Matcher brNameMatcher = brNameRegex.matcher(brName);
-
-            String pName = null;
-            String vNetId = null;
-            if (oldStyleBrNameMatcher.find()) {
-                // Actually modifyvlan.sh doesn't require pif name when deleting its bridge so far.
-                pName = "undefined";
-                vNetId = oldStyleBrNameMatcher.group(1);
-            } else if (brNameMatcher.find()) {
-                if (brNameMatcher.group(1) != null || !brNameMatcher.group(1).isEmpty()) {
-                    pName = brNameMatcher.group(1);
-                } else {
-                    pName = "undefined";
-                }
-                vNetId = brNameMatcher.group(2);
-            }
-
-            if (vNetId == null || vNetId.isEmpty()) {
-                s_logger.debug("unable to get a vNet ID from name " + brName);
-                return;
-            }
-
-            String scriptPath = null;
-            if (cmdout != null && cmdout.contains("vxlan")) {
-                scriptPath = _modifyVxlanPath;
-            } else {
-                scriptPath = _modifyVlanPath;
-            }
-
-            final Script command = new Script(scriptPath, _timeout, s_logger);
-            command.add("-o", "delete");
-            command.add("-v", vNetId);
-            command.add("-p", pName);
-            command.add("-b", brName);
-
-            final String result = command.execute();
-            if (result != null) {
-                s_logger.debug("Delete bridge " + brName + " failed: " + result);
-            }
-        }
-    }
-
-    private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
-        Script command = new Script("/bin/bash", _timeout);
-        command.add("-c");
-        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        boolean foundLinkLocalBr = false;
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                String[] tokens = line.split(" ");
-                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
-                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
-                } else {
-                    foundLinkLocalBr = true;
-                }
-            }
-        }
-        if (!foundLinkLocalBr) {
-            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
-                NetUtils.getLinkLocalGateway());
-        }
-    }
-
-    @Override
-    public void createControlNetwork(String privBrName) {
-        deleteExitingLinkLocalRouteTable(privBrName);
-        if (!isBridgeExists(privBrName)) {
-            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
-        }
-    }
-
-    private boolean isBridgeExists(String bridgeName) {
-        File f = new File("/sys/devices/virtual/net/" + bridgeName);
-        if (f.exists()) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
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
deleted file mode 100644
index 6b4ed39..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ /dev/null
@@ -1,3811 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.naming.ConfigurationException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.hypervisor.HypervisorUtils;
-import org.apache.cloudstack.utils.linux.CPUStat;
-import org.apache.cloudstack.utils.linux.MemStat;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-import org.apache.cloudstack.utils.security.KeyStoreUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.math.NumberUtils;
-import org.apache.log4j.Logger;
-import org.joda.time.Duration;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainBlockStats;
-import org.libvirt.DomainInfo;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.DomainInterfaceStats;
-import org.libvirt.DomainSnapshot;
-import org.libvirt.LibvirtException;
-import org.libvirt.MemoryStatistic;
-import org.libvirt.NodeInfo;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.HostVmStateReportEntry;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.VmDiskStatsEntry;
-import com.cloud.agent.api.VmNetworkStatsEntry;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.resource.virtualnetwork.VRScripts;
-import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.dc.Vlan;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DeviceType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiscardType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiskProtocol;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FilesystemDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GraphicDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.GuestNetType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
-import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper;
-import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
-import com.cloud.hypervisor.kvm.storage.KVMStorageProcessor;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.RouterPrivateIpStrategy;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.resource.RequestWrapper;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.Volume;
-import com.cloud.storage.resource.StorageSubsystemCommandHandler;
-import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
-import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.OutputInterpreter.AllLinesParser;
-import com.cloud.utils.script.Script;
-import com.cloud.utils.ssh.SshHelper;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VmDetailConstants;
-import com.google.common.base.Strings;
-
-/**
- * LibvirtComputingResource execute requests on the computing/routing host using
- * the libvirt API
- *
- * @config {@table || Param Name | Description | Values | Default || ||
- *         hypervisor.type | type of local hypervisor | string | kvm || ||
- *         hypervisor.uri | local hypervisor to connect to | URI |
- *         qemu:///system || || domr.arch | instruction set for domr template |
- *         string | i686 || || private.bridge.name | private bridge where the
- *         domrs have their private interface | string | vmops0 || ||
- *         public.bridge.name | public bridge where the domrs have their public
- *         interface | string | br0 || || private.network.name | name of the
- *         network where the domrs have their private interface | string |
- *         vmops-private || || private.ipaddr.start | start of the range of
- *         private ip addresses for domrs | ip address | 192.168.166.128 || ||
- *         private.ipaddr.end | end of the range of private ip addresses for
- *         domrs | ip address | start + 126 || || private.macaddr.start | start
- *         of the range of private mac addresses for domrs | mac address |
- *         00:16:3e:77:e2:a0 || || private.macaddr.end | end of the range of
- *         private mac addresses for domrs | mac address | start + 126 || ||
- *         pool | the parent of the storage pool hierarchy * }
- **/
-public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
-    private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class);
-
-    private String _modifyVlanPath;
-    private String _versionstringpath;
-    private String _patchScriptPath;
-    private String _createvmPath;
-    private String _manageSnapshotPath;
-    private String _resizeVolumePath;
-    private String _createTmplPath;
-    private String _heartBeatPath;
-    private String _vmActivityCheckPath;
-    private String _securityGroupPath;
-    private String _ovsPvlanDhcpHostPath;
-    private String _ovsPvlanVmPath;
-    private String _routerProxyPath;
-    private String _ovsTunnelPath;
-    private String _host;
-    private String _dcId;
-    private String _pod;
-    private String _clusterId;
-
-    private long _hvVersion;
-    private Duration _timeout;
-    private static final int NUMMEMSTATS =2;
-
-    private KVMHAMonitor _monitor;
-    public static final String SSHKEYSPATH = "/root/.ssh";
-    public static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud";
-    public static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud";
-
-    public static final String BASH_SCRIPT_PATH = "/bin/bash";
-
-    private String _mountPoint = "/mnt";
-    private StorageLayer _storage;
-    private KVMStoragePoolManager _storagePoolMgr;
-
-    private VifDriver _defaultVifDriver;
-    private Map<TrafficType, VifDriver> _trafficTypeVifDrivers;
-
-    protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver";
-    protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver";
-
-    protected HypervisorType _hypervisorType;
-    protected String _hypervisorURI;
-    protected long _hypervisorLibvirtVersion;
-    protected long _hypervisorQemuVersion;
-    protected String _hypervisorPath;
-    protected String _hostDistro;
-    protected String _networkDirectSourceMode;
-    protected String _networkDirectDevice;
-    protected String _sysvmISOPath;
-    protected String _privNwName;
-    protected String _privBridgeName;
-    protected String _linkLocalBridgeName;
-    protected String _publicBridgeName;
-    protected String _guestBridgeName;
-    protected String _privateIp;
-    protected String _pool;
-    protected String _localGateway;
-    private boolean _canBridgeFirewall;
-    protected String _localStoragePath;
-    protected String _localStorageUUID;
-    protected boolean _noMemBalloon = false;
-    protected String _guestCpuMode;
-    protected String _guestCpuModel;
-    protected boolean _noKvmClock;
-    protected String _videoHw;
-    protected int _videoRam;
-    protected Pair<Integer,Integer> hostOsVersion;
-    protected int _migrateSpeed;
-    protected int _migrateDowntime;
-    protected int _migratePauseAfter;
-    protected boolean _diskActivityCheckEnabled;
-    protected long _diskActivityCheckFileSizeMin = 10485760; // 10MB
-    protected int _diskActivityCheckTimeoutSeconds = 120; // 120s
-    protected long _diskActivityInactiveThresholdMilliseconds = 30000; // 30s
-    protected boolean _rngEnable = false;
-    protected RngBackendModel _rngBackendModel = RngBackendModel.RANDOM;
-    protected String _rngPath = "/dev/random";
-    protected int _rngRatePeriod = 1000;
-    protected int _rngRateBytes = 2048;
-    private File _qemuSocketsPath;
-    private final String _qemuGuestAgentSocketName = "org.qemu.guest_agent.0";
-    private long _totalMemory;
-    protected WatchDogAction _watchDogAction = WatchDogAction.NONE;
-    protected WatchDogModel _watchDogModel = WatchDogModel.I6300ESB;
-
-    private final Map <String, String> _pifs = new HashMap<String, String>();
-    private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>();
-
-    protected static final HashMap<DomainState, PowerState> s_powerStatesTable;
-    static {
-        s_powerStatesTable = new HashMap<DomainState, PowerState>();
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff);
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn);
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn);
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn);
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown);
-        s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff);
-    }
-
-    protected List<String> _vmsKilled = new ArrayList<String>();
-
-    private VirtualRoutingResource _virtRouterResource;
-
-    private String _pingTestPath;
-
-    private String _updateHostPasswdPath;
-
-    private long _dom0MinMem;
-
-    private long _dom0OvercommitMem;
-
-    protected boolean _disconnected = true;
-    protected int _cmdsTimeout;
-    protected int _stopTimeout;
-    protected CPUStat _cpuStat = new CPUStat();
-    protected MemStat _memStat = new MemStat();
-
-    private final LibvirtUtilitiesHelper libvirtUtilitiesHelper = new LibvirtUtilitiesHelper();
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIp, final String script, final String args) {
-        return executeInVR(routerIp, script, args, _timeout);
-    }
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final Duration timeout) {
-        final Script command = new Script(_routerProxyPath, timeout, s_logger);
-        final AllLinesParser parser = new AllLinesParser();
-        command.add(script);
-        command.add(routerIp);
-        if (args != null) {
-            command.add(args);
-        }
-        String details = command.execute(parser);
-        if (details == null) {
-            details = parser.getLines();
-        }
-
-        s_logger.debug("Executing script in VR: " + script);
-
-        return new ExecutionResult(command.getExitValue() == 0, details);
-    }
-
-    @Override
-    public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) {
-        final File permKey = new File("/root/.ssh/id_rsa.cloud");
-        boolean success = true;
-        String details = "Creating file in VR, with ip: " + routerIp + ", file: " + filename;
-        s_logger.debug(details);
-
-        try {
-            SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null);
-        } catch (final Exception e) {
-            s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e);
-            details = e.getMessage();
-            success = false;
-        }
-        return new ExecutionResult(success, details);
-    }
-
-    @Override
-    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
-        //Update IP used to access router
-        cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP));
-        assert cmd.getRouterAccessIp() != null;
-
-        if (cmd instanceof IpAssocVpcCommand) {
-            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
-        } else if (cmd instanceof IpAssocCommand) {
-            return prepareNetworkElementCommand((IpAssocCommand)cmd);
-        } else if (cmd instanceof SetupGuestNetworkCommand) {
-            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
-        } else if (cmd instanceof SetSourceNatCommand) {
-            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
-        if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) {
-            return cleanupNetworkElementCommand((IpAssocCommand)cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    public LibvirtUtilitiesHelper getLibvirtUtilitiesHelper() {
-        return libvirtUtilitiesHelper;
-    }
-
-    public CPUStat getCPUStat() {
-        return _cpuStat;
-    }
-
-    public MemStat getMemStat() {
-        return _memStat;
-    }
-
-    public VirtualRoutingResource getVirtRouterResource() {
-        return _virtRouterResource;
-    }
-
-    public String getPublicBridgeName() {
-        return _publicBridgeName;
-    }
-
-    public KVMStoragePoolManager getStoragePoolMgr() {
-        return _storagePoolMgr;
-    }
-
-    public String getPrivateIp() {
-        return _privateIp;
-    }
-
-    public int getMigrateDowntime() {
-        return _migrateDowntime;
-    }
-
-    public int getMigratePauseAfter() {
-        return _migratePauseAfter;
-    }
-
-    public int getMigrateSpeed() {
-        return _migrateSpeed;
-    }
-
-    public String getPingTestPath() {
-        return _pingTestPath;
-    }
-
-    public String getUpdateHostPasswdPath() {
-        return _updateHostPasswdPath;
-    }
-
-    public Duration getTimeout() {
-        return _timeout;
-    }
-
-    public String getOvsTunnelPath() {
-        return _ovsTunnelPath;
-    }
-
-    public KVMHAMonitor getMonitor() {
-        return _monitor;
-    }
-
-    public StorageLayer getStorage() {
-        return _storage;
-    }
-
-    public String createTmplPath() {
-        return _createTmplPath;
-    }
-
-    public int getCmdsTimeout() {
-        return _cmdsTimeout;
-    }
-
-    public String manageSnapshotPath() {
-        return _manageSnapshotPath;
-    }
-
-    public String getGuestBridgeName() {
-        return _guestBridgeName;
-    }
-
-    public String getVmActivityCheckPath() {
-        return _vmActivityCheckPath;
-    }
-
-    public String getOvsPvlanDhcpHostPath() {
-        return _ovsPvlanDhcpHostPath;
-    }
-
-    public String getOvsPvlanVmPath() {
-        return _ovsPvlanVmPath;
-    }
-
-    public String getResizeVolumePath() {
-        return _resizeVolumePath;
-    }
-
-    public StorageSubsystemCommandHandler getStorageHandler() {
-        return storageHandler;
-    }
-
-    private static final class KeyValueInterpreter extends OutputInterpreter {
-        private final Map<String, String> map = new HashMap<String, String>();
-
-        @Override
-        public String interpret(final BufferedReader reader) throws IOException {
-            String line = null;
-            int numLines = 0;
-            while ((line = reader.readLine()) != null) {
-                final String[] toks = line.trim().split("=");
-                if (toks.length < 2) {
-                    s_logger.warn("Failed to parse Script output: " + line);
-                } else {
-                    map.put(toks[0].trim(), toks[1].trim());
-                }
-                numLines++;
-            }
-            if (numLines == 0) {
-                s_logger.warn("KeyValueInterpreter: no output lines?");
-            }
-            return null;
-        }
-
-        public Map<String, String> getKeyValues() {
-            return map;
-        }
-    }
-
-    @Override
-    protected String getDefaultScriptsDir() {
-        return null;
-    }
-
-    protected List<String> _cpuFeatures;
-
-    protected enum BridgeType {
-        NATIVE, OPENVSWITCH
-    }
-
-    protected BridgeType _bridgeType;
-
-    protected StorageSubsystemCommandHandler storageHandler;
-
-    private String getEndIpFromStartIp(final String startIp, final int numIps) {
-        final String[] tokens = startIp.split("[.]");
-        assert tokens.length == 4;
-        int lastbyte = Integer.parseInt(tokens[3]);
-        lastbyte = lastbyte + numIps;
-        tokens[3] = Integer.toString(lastbyte);
-        final StringBuilder end = new StringBuilder(15);
-        end.append(tokens[0]).append(".").append(tokens[1]).append(".").append(tokens[2]).append(".").append(tokens[3]);
-        return end.toString();
-    }
-
-    private Map<String, Object> getDeveloperProperties() throws ConfigurationException {
-
-        final File file = PropertiesUtil.findConfigFile("developer.properties");
-        if (file == null) {
-            throw new ConfigurationException("Unable to find developer.properties.");
-        }
-
-        s_logger.info("developer.properties found at " + file.getAbsolutePath());
-        try {
-            final Properties properties = PropertiesUtil.loadFromFile(file);
-
-            final String startMac = (String)properties.get("private.macaddr.start");
-            if (startMac == null) {
-                throw new ConfigurationException("Developers must specify start mac for private ip range");
-            }
-
-            final String startIp = (String)properties.get("private.ipaddr.start");
-            if (startIp == null) {
-                throw new ConfigurationException("Developers must specify start ip for private ip range");
-            }
-            final Map<String, Object> params = PropertiesUtil.toMap(properties);
-
-            String endIp = (String)properties.get("private.ipaddr.end");
-            if (endIp == null) {
-                endIp = getEndIpFromStartIp(startIp, 16);
-                params.put("private.ipaddr.end", endIp);
-            }
-            return params;
-        } catch (final FileNotFoundException ex) {
-            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
-        } catch (final IOException ex) {
-            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
-        }
-    }
-
-    protected String getDefaultNetworkScriptsDir() {
-        return "scripts/vm/network/vnet";
-    }
-
-    protected String getDefaultStorageScriptsDir() {
-        return "scripts/storage/qcow2";
-    }
-
-    protected String getDefaultHypervisorScriptsDir() {
-        return "scripts/vm/hypervisor";
-    }
-
-    protected String getDefaultKvmScriptsDir() {
-        return "scripts/vm/hypervisor/kvm";
-    }
-
-    protected String getDefaultDomrScriptsDir() {
-        return "scripts/network/domr";
-    }
-
-    protected String getNetworkDirectSourceMode() {
-        return _networkDirectSourceMode;
-    }
-
-    protected String getNetworkDirectDevice() {
-        return _networkDirectDevice;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        boolean success = super.configure(name, params);
-        if (!success) {
-            return false;
-        }
-
-        _storage = new JavaStorageLayer();
-        _storage.configure("StorageLayer", params);
-
-        String domrScriptsDir = (String)params.get("domr.scripts.dir");
-        if (domrScriptsDir == null) {
-            domrScriptsDir = getDefaultDomrScriptsDir();
-        }
-
-        String hypervisorScriptsDir = (String)params.get("hypervisor.scripts.dir");
-        if (hypervisorScriptsDir == null) {
-            hypervisorScriptsDir = getDefaultHypervisorScriptsDir();
-        }
-
-        String kvmScriptsDir = (String)params.get("kvm.scripts.dir");
-        if (kvmScriptsDir == null) {
-            kvmScriptsDir = getDefaultKvmScriptsDir();
-        }
-
-        String networkScriptsDir = (String)params.get("network.scripts.dir");
-        if (networkScriptsDir == null) {
-            networkScriptsDir = getDefaultNetworkScriptsDir();
-        }
-
-        String storageScriptsDir = (String)params.get("storage.scripts.dir");
-        if (storageScriptsDir == null) {
-            storageScriptsDir = getDefaultStorageScriptsDir();
-        }
-
-        final String bridgeType = (String)params.get("network.bridge.type");
-        if (bridgeType == null) {
-            _bridgeType = BridgeType.NATIVE;
-        } else {
-            _bridgeType = BridgeType.valueOf(bridgeType.toUpperCase());
-        }
-
-        params.put("domr.scripts.dir", domrScriptsDir);
-
-        _virtRouterResource = new VirtualRoutingResource(this);
-        success = _virtRouterResource.configure(name, params);
-
-        if (!success) {
-            return false;
-        }
-
-        _host = (String)params.get("host");
-        if (_host == null) {
-            _host = "localhost";
-        }
-
-        _dcId = (String)params.get("zone");
-        if (_dcId == null) {
-            _dcId = "default";
-        }
-
-        _pod = (String)params.get("pod");
-        if (_pod == null) {
-            _pod = "default";
-        }
-
-        _clusterId = (String)params.get("cluster");
-
-        _updateHostPasswdPath = Script.findScript(hypervisorScriptsDir, VRScripts.UPDATE_HOST_PASSWD);
-        if (_updateHostPasswdPath == null) {
-            throw new ConfigurationException("Unable to find update_host_passwd.sh");
-        }
-
-        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
-        if (_modifyVlanPath == null) {
-            throw new ConfigurationException("Unable to find modifyvlan.sh");
-        }
-
-        _versionstringpath = Script.findScript(kvmScriptsDir, "versions.sh");
-        if (_versionstringpath == null) {
-            throw new ConfigurationException("Unable to find versions.sh");
-        }
-
-        _patchScriptPath = Script.findScript(kvmScriptsDir, "patch.sh");
-        if (_patchScriptPath == null) {
-            throw new ConfigurationException("Unable to find patch.sh");
-        }
-
-        _heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
-        if (_heartBeatPath == null) {
-            throw new ConfigurationException("Unable to find kvmheartbeat.sh");
-        }
-
-        _createvmPath = Script.findScript(storageScriptsDir, "createvm.sh");
-        if (_createvmPath == null) {
-            throw new ConfigurationException("Unable to find the createvm.sh");
-        }
-
-        _manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh");
-        if (_manageSnapshotPath == null) {
-            throw new ConfigurationException("Unable to find the managesnapshot.sh");
-        }
-
-        _resizeVolumePath = Script.findScript(storageScriptsDir, "resizevolume.sh");
-        if (_resizeVolumePath == null) {
-            throw new ConfigurationException("Unable to find the resizevolume.sh");
-        }
-
-        _vmActivityCheckPath = Script.findScript(kvmScriptsDir, "kvmvmactivity.sh");
-        if (_vmActivityCheckPath == null) {
-            throw new ConfigurationException("Unable to find kvmvmactivity.sh");
-        }
-
-        _createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh");
-        if (_createTmplPath == null) {
-            throw new ConfigurationException("Unable to find the createtmplt.sh");
-        }
-
-        _securityGroupPath = Script.findScript(networkScriptsDir, "security_group.py");
-        if (_securityGroupPath == null) {
-            throw new ConfigurationException("Unable to find the security_group.py");
-        }
-
-        _ovsTunnelPath = Script.findScript(networkScriptsDir, "ovstunnel.py");
-        if (_ovsTunnelPath == null) {
-            throw new ConfigurationException("Unable to find the ovstunnel.py");
-        }
-
-        _routerProxyPath = Script.findScript("scripts/network/domr/", "router_proxy.sh");
-        if (_routerProxyPath == null) {
-            throw new ConfigurationException("Unable to find the router_proxy.sh");
-        }
-
-        _ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-dhcp-host.sh");
-        if (_ovsPvlanDhcpHostPath == null) {
-            throw new ConfigurationException("Unable to find the ovs-pvlan-dhcp-host.sh");
-        }
-
-        _ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-vm.sh");
-        if (_ovsPvlanVmPath == null) {
-            throw new ConfigurationException("Unable to find the ovs-pvlan-vm.sh");
-        }
-
-        String value = (String)params.get("developer");
-        final boolean isDeveloper = Boolean.parseBoolean(value);
-
-        if (isDeveloper) {
-            params.putAll(getDeveloperProperties());
-        }
-
-        _pool = (String)params.get("pool");
-        if (_pool == null) {
-            _pool = "/root";
-        }
-
-        final String instance = (String)params.get("instance");
-
-        _hypervisorType = HypervisorType.getType((String)params.get("hypervisor.type"));
-        if (_hypervisorType == HypervisorType.None) {
-            _hypervisorType = HypervisorType.KVM;
-        }
-
-        _hypervisorURI = (String)params.get("hypervisor.uri");
-        if (_hypervisorURI == null) {
-            _hypervisorURI = LibvirtConnection.getHypervisorURI(_hypervisorType.toString());
-        }
-
-        _networkDirectSourceMode = (String)params.get("network.direct.source.mode");
-        _networkDirectDevice = (String)params.get("network.direct.device");
-
-        String startMac = (String)params.get("private.macaddr.start");
-        if (startMac == null) {
-            startMac = "00:16:3e:77:e2:a0";
-        }
-
-        String startIp = (String)params.get("private.ipaddr.start");
-        if (startIp == null) {
-            startIp = "192.168.166.128";
-        }
-
-        _pingTestPath = Script.findScript(kvmScriptsDir, "pingtest.sh");
-        if (_pingTestPath == null) {
-            throw new ConfigurationException("Unable to find the pingtest.sh");
-        }
-
-        _linkLocalBridgeName = (String)params.get("private.bridge.name");
-        if (_linkLocalBridgeName == null) {
-            if (isDeveloper) {
-                _linkLocalBridgeName = "cloud-" + instance + "-0";
-            } else {
-                _linkLocalBridgeName = "cloud0";
-            }
-        }
-
-        _publicBridgeName = (String)params.get("public.network.device");
-        if (_publicBridgeName == null) {
-            _publicBridgeName = "cloudbr0";
-        }
-
-        _privBridgeName = (String)params.get("private.network.device");
-        if (_privBridgeName == null) {
-            _privBridgeName = "cloudbr1";
-        }
-
-        _guestBridgeName = (String)params.get("guest.network.device");
-        if (_guestBridgeName == null) {
-            _guestBridgeName = _privBridgeName;
-        }
-
-        _privNwName = (String)params.get("private.network.name");
-        if (_privNwName == null) {
-            if (isDeveloper) {
-                _privNwName = "cloud-" + instance + "-private";
-            } else {
-                _privNwName = "cloud-private";
-            }
-        }
-
-        _localStoragePath = (String)params.get("local.storage.path");
-        if (_localStoragePath == null) {
-            _localStoragePath = "/var/lib/libvirt/images/";
-        }
-
-        /* Directory to use for Qemu sockets like for the Qemu Guest Agent */
-        _qemuSocketsPath = new File("/var/lib/libvirt/qemu");
-        String _qemuSocketsPathVar = (String)params.get("qemu.sockets.path");
-        if (_qemuSocketsPathVar != null && StringUtils.isNotBlank(_qemuSocketsPathVar)) {
-            _qemuSocketsPath = new File(_qemuSocketsPathVar);
-        }
-
-        final File storagePath = new File(_localStoragePath);
-        _localStoragePath = storagePath.getAbsolutePath();
-
-        _localStorageUUID = (String)params.get("local.storage.uuid");
-        if (_localStorageUUID == null) {
-            _localStorageUUID = UUID.randomUUID().toString();
-        }
-
-        value = (String)params.get("scripts.timeout");
-        _timeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 30 * 60));
-
-        value = (String)params.get("stop.script.timeout");
-        _stopTimeout = NumbersUtil.parseInt(value, 120) * 1000;
-
-        value = (String)params.get("cmds.timeout");
-        _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000;
-
-        value = (String) params.get("vm.memballoon.disable");
-        if (Boolean.parseBoolean(value)) {
-            _noMemBalloon = true;
-        }
-
-        _videoHw = (String) params.get("vm.video.hardware");
-        value = (String) params.get("vm.video.ram");
-        _videoRam = NumbersUtil.parseInt(value, 0);
-
-        value = (String)params.get("host.reserved.mem.mb");
-        // Reserve 1GB unless admin overrides
-        _dom0MinMem = NumbersUtil.parseInt(value, 1024) * 1024 * 1024L;
-
-        value = (String)params.get("host.overcommit.mem.mb");
-        // Support overcommit memory for host if host uses ZSWAP, KSM and other memory
-        // compressing technologies
-        _dom0OvercommitMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024L;
-
-        value = (String) params.get("kvmclock.disable");
-        if (Boolean.parseBoolean(value)) {
-            _noKvmClock = true;
-        }
-
-        value = (String) params.get("vm.rng.enable");
-        if (Boolean.parseBoolean(value)) {
-            _rngEnable = true;
-
-            value = (String) params.get("vm.rng.model");
-            if (!Strings.isNullOrEmpty(value)) {
-                _rngBackendModel = RngBackendModel.valueOf(value.toUpperCase());
-            }
-
-            value = (String) params.get("vm.rng.path");
-            if (!Strings.isNullOrEmpty(value)) {
-                _rngPath = value;
-            }
-
-            value = (String) params.get("vm.rng.rate.bytes");
-            _rngRateBytes = NumbersUtil.parseInt(value, new Integer(_rngRateBytes));
-
-            value = (String) params.get("vm.rng.rate.period");
-            _rngRatePeriod = NumbersUtil.parseInt(value, new Integer(_rngRatePeriod));
-        }
-
-        value = (String) params.get("vm.watchdog.model");
-        if (!Strings.isNullOrEmpty(value)) {
-            _watchDogModel = WatchDogModel.valueOf(value.toUpperCase());
-        }
-
-        value = (String) params.get("vm.watchdog.action");
-        if (!Strings.isNullOrEmpty(value)) {
-            _watchDogAction = WatchDogAction.valueOf(value.toUpperCase());
-        }
-
-        LibvirtConnection.initialize(_hypervisorURI);
-        Connect conn = null;
-        try {
-            conn = LibvirtConnection.getConnection();
-
-            if (_bridgeType == BridgeType.OPENVSWITCH) {
-                if (conn.getLibVirVersion() < 10 * 1000 + 0) {
-                    throw new ConfigurationException("Libvirt version 0.10.0 required for openvswitch support, but version " + conn.getLibVirVersion() + " detected");
-                }
-            }
-        } catch (final LibvirtException e) {
-            throw new CloudRuntimeException(e.getMessage());
-        }
-
-        if (HypervisorType.KVM == _hypervisorType) {
-            /* Does node support HVM guest? If not, exit */
-            if (!IsHVMEnabled(conn)) {
-                throw new ConfigurationException("NO HVM support on this machine, please make sure: " + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
-                        + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)");
-            }
-        }
-
-        _hypervisorPath = getHypervisorPath(conn);
-        try {
-            _hvVersion = conn.getVersion();
-            _hvVersion = _hvVersion % 1000000 / 1000;
-            _hypervisorLibvirtVersion = conn.getLibVirVersion();
-            _hypervisorQemuVersion = conn.getVersion();
-        } catch (final LibvirtException e) {
-            s_logger.trace("Ignoring libvirt error.", e);
-        }
-
-        _guestCpuMode = (String)params.get("guest.cpu.mode");
-        if (_guestCpuMode != null) {
-            _guestCpuModel = (String)params.get("guest.cpu.model");
-
-            if (_hypervisorLibvirtVersion < 9 * 1000 + 10) {
-                s_logger.warn("Libvirt version 0.9.10 required for guest cpu mode, but version " + prettyVersion(_hypervisorLibvirtVersion) +
-                        " detected, so it will be disabled");
-                _guestCpuMode = "";
-                _guestCpuModel = "";
-            }
-            params.put("guest.cpu.mode", _guestCpuMode);
-            params.put("guest.cpu.model", _guestCpuModel);
-        }
-
-        final String cpuFeatures = (String)params.get("guest.cpu.features");
-        if (cpuFeatures != null) {
-            _cpuFeatures = new ArrayList<String>();
-            for (final String feature: cpuFeatures.split(" ")) {
-                if (!feature.isEmpty()) {
-                    _cpuFeatures.add(feature);
-                }
-            }
-        }
-
-        final String[] info = NetUtils.getNetworkParams(_privateNic);
-
-        _monitor = new KVMHAMonitor(null, info[0], _heartBeatPath);
-        final Thread ha = new Thread(_monitor);
-        ha.start();
-
-        _storagePoolMgr = new KVMStoragePoolManager(_storage, _monitor);
-
-        _sysvmISOPath = (String)params.get("systemvm.iso.path");
-        if (_sysvmISOPath == null) {
-            final String[] isoPaths = {"/usr/share/cloudstack-common/vms/systemvm.iso"};
-            for (final String isoPath : isoPaths) {
-                if (_storage.exists(isoPath)) {
-                    _sysvmISOPath = isoPath;
-                    break;
-                }
-            }
-            if (_sysvmISOPath == null) {
-                s_logger.debug("Can't find system vm ISO");
-            }
-        }
-
-        final Map<String, String> bridges = new HashMap<String, String>();
-
-        params.put("libvirt.host.bridges", bridges);
-        params.put("libvirt.host.pifs", _pifs);
-
-        params.put("libvirt.computing.resource", this);
-        params.put("libvirtVersion", _hypervisorLibvirtVersion);
-
-
-        configureVifDrivers(params);
-
-        /*
-        switch (_bridgeType) {
-        case OPENVSWITCH:
-            getOvsPifs();
-            break;
-        case NATIVE:
-        default:
-            getPifs();
-            break;
-        }
-        */
-
-        if (_pifs.get("private") == null) {
-            s_logger.debug("Failed to get private nic name");
-            throw new ConfigurationException("Failed to get private nic name");
-        }
-
-        if (_pifs.get("public") == null) {
-            s_logger.debug("Failed to get public nic name");
-            throw new ConfigurationException("Failed to get public nic name");
-        }
-        s_logger.debug("Found pif: " + _pifs.get("private") + " on " + _privBridgeName + ", pif: " + _pifs.get("public") + " on " + _publicBridgeName);
-
-        _canBridgeFirewall = canBridgeFirewall(_pifs.get("public"));
-
-        _localGateway = Script.runSimpleBashScript("ip route |grep default|awk '{print $3}'");
-        if (_localGateway == null) {
-            s_logger.debug("Failed to found the local gateway");
-        }
-
-        _mountPoint = (String)params.get("mount.path");
-        if (_mountPoint == null) {
-            _mountPoint = "/mnt";
-        }
-
-        value = (String) params.get("vm.migrate.downtime");
-        _migrateDowntime = NumbersUtil.parseInt(value, -1);
-
-        value = (String) params.get("vm.migrate.pauseafter");
-        _migratePauseAfter = NumbersUtil.parseInt(value, -1);
-
-        value = (String)params.get("vm.migrate.speed");
-        _migrateSpeed = NumbersUtil.parseInt(value, -1);
-        if (_migrateSpeed == -1) {
-            //get guest network device speed
-            _migrateSpeed = 0;
-            final String speed = Script.runSimpleBashScript("ethtool " + _pifs.get("public") + " |grep Speed | cut -d \\  -f 2");
-            if (speed != null) {
-                final String[] tokens = speed.split("M");
-                if (tokens.length == 2) {
-                    try {
-                        _migrateSpeed = Integer.parseInt(tokens[0]);
-                    } catch (final NumberFormatException e) {
-                        s_logger.trace("Ignoring migrateSpeed extraction error.", e);
-                    }
-                    s_logger.debug("device " + _pifs.get("public") + " has speed: " + String.valueOf(_migrateSpeed));
-                }
-            }
-            params.put("vm.migrate.speed", String.valueOf(_migrateSpeed));
-        }
-
-        bridges.put("linklocal", _linkLocalBridgeName);
-        bridges.put("public", _publicBridgeName);
-        bridges.put("private", _privBridgeName);
-        bridges.put("guest", _guestBridgeName);
-
-        getVifDriver(TrafficType.Control).createControlNetwork(_linkLocalBridgeName);
-
-        configureDiskActivityChecks(params);
-
-        final KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this);
-        storageProcessor.configure(name, params);
-        storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor);
-
-        return true;
-    }
-
-    protected void configureDiskActivityChecks(final Map<String, Object> params) {
-        _diskActivityCheckEnabled = Boolean.parseBoolean((String)params.get("vm.diskactivity.checkenabled"));
-        if (_diskActivityCheckEnabled) {
-            final int timeout = NumbersUtil.parseInt((String)params.get("vm.diskactivity.checktimeout_s"), 0);
-            if (timeout > 0) {
-                _diskActivityCheckTimeoutSeconds = timeout;
-            }
-            final long inactiveTime = NumbersUtil.parseLong((String)params.get("vm.diskactivity.inactivetime_ms"), 0L);
-            if (inactiveTime > 0) {
-                _diskActivityInactiveThresholdMilliseconds = inactiveTime;
-            }
-        }
-    }
-
-    protected void configureVifDrivers(final Map<String, Object> params) throws ConfigurationException {
-        final String LIBVIRT_VIF_DRIVER = "libvirt.vif.driver";
-
-        _trafficTypeVifDrivers = new HashMap<TrafficType, VifDriver>();
-
-        // Load the default vif driver
-        String defaultVifDriverName = (String)params.get(LIBVIRT_VIF_DRIVER);
-        if (defaultVifDriverName == null) {
-            if (_bridgeType == BridgeType.OPENVSWITCH) {
-                s_logger.info("No libvirt.vif.driver specified. Defaults to OvsVifDriver.");
-                defaultVifDriverName = DEFAULT_OVS_VIF_DRIVER_CLASS_NAME;
-            } else {
-                s_logger.info("No libvirt.vif.driver specified. Defaults to BridgeVifDriver.");
-                defaultVifDriverName = DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME;
-            }
-        }
-        _defaultVifDriver = getVifDriverClass(defaultVifDriverName, params);
-
-        // Load any per-traffic-type vif drivers
-        for (final Map.Entry<String, Object> entry : params.entrySet()) {
-            final String k = entry.getKey();
-            final String vifDriverPrefix = LIBVIRT_VIF_DRIVER + ".";
-
-            if (k.startsWith(vifDriverPrefix)) {
-                // Get trafficType
-                final String trafficTypeSuffix = k.substring(vifDriverPrefix.length());
-
-                // Does this suffix match a real traffic type?
-                final TrafficType trafficType = TrafficType.getTrafficType(trafficTypeSuffix);
-                if (!trafficType.equals(TrafficType.None)) {
-                    // Get vif driver class name
-                    final String vifDriverClassName = (String)entry.getValue();
-                    // if value is null, ignore
-                    if (vifDriverClassName != null) {
-                        // add traffic type to vif driver mapping to Map
-                        _trafficTypeVifDrivers.put(trafficType, getVifDriverClass(vifDriverClassName, params));
-                    }
-                }
-            }
-        }
-    }
-
-    protected VifDriver getVifDriverClass(final String vifDriverClassName, final Map<String, Object> params) throws ConfigurationException {
-        VifDriver vifDriver;
-
-        try {
-            final Class<?> clazz = Class.forName(vifDriverClassName);
-            vifDriver = (VifDriver)clazz.newInstance();
-            vifDriver.configure(params);
-        } catch (final ClassNotFoundException e) {
-            throw new ConfigurationException("Unable to find class for libvirt.vif.driver " + e);
-        } catch (final InstantiationException e) {
-            throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e);
-        } catch (final IllegalAccessException e) {
-            throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e);
-        }
-        return vifDriver;
-    }
-
-    public VifDriver getVifDriver(final TrafficType trafficType) {
-        VifDriver vifDriver = _trafficTypeVifDrivers.get(trafficType);
-
-        if (vifDriver == null) {
-            vifDriver = _defaultVifDriver;
-        }
-
-        return vifDriver;
-    }
-
-    public VifDriver getVifDriver(final TrafficType trafficType, final String bridgeName) {
-        VifDriver vifDriver = null;
-
-        for (VifDriver driver : getAllVifDrivers()) {
-            if (driver.isExistingBridge(bridgeName)) {
-                vifDriver = driver;
-                break;
-            }
-        }
-
-        if (vifDriver == null) {
-            vifDriver = getVifDriver(trafficType);
-        }
-
-        return vifDriver;
-    }
-
-    public List<VifDriver> getAllVifDrivers() {
-        final Set<VifDriver> vifDrivers = new HashSet<VifDriver>();
-
-        vifDrivers.add(_defaultVifDriver);
-        vifDrivers.addAll(_trafficTypeVifDrivers.values());
-
-        final ArrayList<VifDriver> vifDriverList = new ArrayList<VifDriver>(vifDrivers);
-
-        return vifDriverList;
-    }
-
-    private void getPifs() {
-        final File dir = new File("/sys/devices/virtual/net");
-        final File[] netdevs = dir.listFiles();
-        final List<String> bridges = new ArrayList<String>();
-        for (int i = 0; i < netdevs.length; i++) {
-            final File isbridge = new File(netdevs[i].getAbsolutePath() + "/bridge");
-            final String netdevName = netdevs[i].getName();
-            s_logger.debug("looking in file " + netdevs[i].getAbsolutePath() + "/bridge");
-            if (isbridge.exists()) {
-                s_logger.debug("Found bridge " + netdevName);
-                bridges.add(netdevName);
-            }
-        }
-
-        for (final String bridge : bridges) {
-            s_logger.debug("looking for pif for bridge " + bridge);
-            final String pif = getPif(bridge);
-            if (isPublicBridge(bridge)) {
-                _pifs.put("public", pif);
-            }
-            if (isGuestBridge(bridge)) {
-                _pifs.put("private", pif);
-            }
-            _pifs.put(bridge, pif);
-        }
-
-        // guest(private) creates bridges on a pif, if private bridge not found try pif direct
-        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
-        if (_pifs.get("private") == null) {
-            s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' not found as bridge, looking for physical interface");
-            final File dev = new File("/sys/class/net/" + _guestBridgeName);
-            if (dev.exists()) {
-                s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' found as a physical device");
-                _pifs.put("private", _guestBridgeName);
-            }
-        }
-
-        // public creates bridges on a pif, if private bridge not found try pif direct
-        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
-        if (_pifs.get("public") == null) {
-            s_logger.debug("public traffic label '" + _publicBridgeName+ "' not found as bridge, looking for physical interface");
-            final File dev = new File("/sys/class/net/" + _publicBridgeName);
-            if (dev.exists()) {
-                s_logger.debug("public traffic label '" + _publicBridgeName + "' found as a physical device");
-                _pifs.put("public", _publicBridgeName);
-            }
-        }
-
-        s_logger.debug("done looking for pifs, no more bridges");
-    }
-
-    boolean isGuestBridge(String bridge) {
-        return _guestBridgeName != null && bridge.equals(_guestBridgeName);
-    }
-
-    private void getOvsPifs() {
-        final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
-        s_logger.debug("cmdout was " + cmdout);
-        final List<String> bridges = Arrays.asList(cmdout.split("%"));
-        for (final String bridge : bridges) {
-            s_logger.debug("looking for pif for bridge " + bridge);
-            // String pif = getOvsPif(bridge);
-            // Not really interested in the pif name at this point for ovs
-            // bridges
-            final String pif = bridge;
-            if (isPublicBridge(bridge)) {
-                _pifs.put("public", pif);
-            }
-            if (isGuestBridge(bridge)) {
-                _pifs.put("private", pif);
-            }
-            _pifs.put(bridge, pif);
-        }
-        s_logger.debug("done looking for pifs, no more bridges");
-    }
-
-    public boolean isPublicBridge(String bridge) {
-        return _publicBridgeName != null && bridge.equals(_publicBridgeName);
-    }
-
-    private String getPif(final String bridge) {
-        String pif = matchPifFileInDirectory(bridge);
-        final File vlanfile = new File("/proc/net/vlan/" + pif);
-
-        if (vlanfile.isFile()) {
-            pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
-        }
-
-        return pif;
-    }
-
-    private String matchPifFileInDirectory(final String bridgeName) {
-        final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
-
-        if (!brif.isDirectory()) {
-            final File pif = new File("/sys/class/net/" + bridgeName);
-            if (pif.isDirectory()) {
-                // if bridgeName already refers to a pif, return it as-is
-                return bridgeName;
-            }
-            s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?");
-            return "";
-        }
-
-        final File[] interfaces = brif.listFiles();
-
-        for (int i = 0; i < interfaces.length; i++) {
-            final String fname = interfaces[i].getName();
-            s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'");
-            if (isInterface(fname)) {
-                return fname;
-            }
-        }
-
-        s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath());
-        return "";
-    }
-
-    String [] _ifNamePatterns = {
-            "^eth",
-            "^bond",
-            "^vlan",
-            "^vx",
-            "^em",
-            "^ens",
-            "^eno",
-            "^enp",
-            "^team",
-            "^enx",
-            "^p\\d+p\\d+"
-    };
-    /**
-     * @param fname
-     * @return
-     */
-    boolean isInterface(final String fname) {
-        StringBuffer commonPattern = new StringBuffer();
-        for (final String ifNamePattern : _ifNamePatterns) {
-            commonPattern.append("|(").append(ifNamePattern).append(".*)");
-        }
-        if(fname.matches(commonPattern.toString())) {
-            return true;
-        }
-        return false;
-    }
-
-    public boolean checkNetwork(final TrafficType trafficType, final String networkName) {
-        if (networkName == null) {
-            return true;
-        }
-
-        if (getVifDriver(trafficType, networkName) instanceof OvsVifDriver) {
-            return checkOvsNetwork(networkName);
-        } else {
-            return checkBridgeNetwork(networkName);
-        }
-    }
-
-    private boolean checkBridgeNetwork(final String networkName) {
-        if (networkName == null) {
-            return true;
-        }
-
-        final String name = matchPifFileInDirectory(networkName);
-
-        if (name == null || name.isEmpty()) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    private boolean checkOvsNetwork(final String networkName) {
-        s_logger.debug("Checking if network " + networkName + " exists as openvswitch bridge");
-        if (networkName == null) {
-            return true;
-        }
-
-        final Script command = new Script("/bin/sh", _timeout);
-        command.add("-c");
-        command.add("ovs-vsctl br-exists " + networkName);
-        return "0".equals(command.execute(null));
-    }
-
-    public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException {
-        final Script command = new Script(_patchScriptPath, 300 * 1000, s_logger);
-        String result;
-        command.add("-n", vmName);
-        command.add("-c", cmdLine);
-        result = command.execute();
-        if (result != null) {
-            s_logger.error("Passing cmdline failed:" + result);
-            return false;
-        }
-        return true;
-    }
-
-    boolean isDirectAttachedNetwork(final String type) {
-        if ("untagged".equalsIgnoreCase(type)) {
-            return true;
-        } else {
-            try {
-                Long.valueOf(type);
-            } catch (final NumberFormatException e) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    public String startVM(final Connect conn, final String vmName, final String domainXML) throws LibvirtException, InternalErrorException {
-        try {
-            /*
-                We create a transient domain here. When this method gets
-                called we receive a full XML specification of the guest,
-                so no need to define it persistent.
-
-                This also makes sure we never have any old "garbage" defined
-                in libvirt which might haunt us.
-             */
-
-            // check for existing inactive vm definition and remove it
-            // this can sometimes happen during crashes, etc
-            Domain dm = null;
-            try {
-                dm = conn.domainLookupByName(vmName);
-                if (dm != null && dm.isPersistent() == 1) {
-                    // this is safe because it doesn't stop running VMs
-                    dm.undefine();
-                }
-            } catch (final LibvirtException e) {
-                // this is what we want, no domain found
-            } finally {
-                if (dm != null) {
-                    dm.free();
-                }
-            }
-
-            conn.domainCreateXML(domainXML, 0);
-        } catch (final LibvirtException e) {
-            throw e;
-        }
-        return null;
-    }
-
-    @Override
-    public boolean stop() {
-        try {
-            final Connect conn = LibvirtConnection.getConnection();
-            conn.close();
-        } catch (final LibvirtException e) {
-            s_logger.trace("Ignoring libvirt error.", e);
-        }
-
-        return true;
-    }
-
-    /**
-     * This finds a command wrapper to handle the command and executes it.
-     * If no wrapper is found an {@see UnsupportedAnswer} is sent back.
-     * Any other exceptions are to be caught and wrapped in an generic {@see Answer}, marked as failed.
-     *
-     * @param cmd the instance of a {@see Command} to execute.
-     * @return the for the {@see Command} appropriate {@see Answer} or {@see UnsupportedAnswer}
-     */
-    @Override
-    public Answer executeRequest(final Command cmd) {
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        try {
-            return wrapper.execute(cmd, this);
-        } catch (final RequestWrapper.CommandNotSupported cmde) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    public synchronized boolean destroyTunnelNetwork(final String bridge) {
-        findOrCreateTunnelNetwork(bridge);
-
-        final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
-        cmd.add("destroy_ovs_bridge");
-        cmd.add("--bridge", bridge);
-
-        final String result = cmd.execute();
-
-        if (result != null) {
-            s_logger.debug("OVS Bridge could not be destroyed due to error ==> " + result);
-            return false;
-        }
-        return true;
-    }
-
-    public synchronized boolean findOrCreateTunnelNetwork(final String nwName) {
-        try {
-            if (checkNetwork(TrafficType.Guest, nwName)) {
-                return true;
-            }
-            // if not found, create a new one
-            final Map<String, String> otherConfig = new HashMap<String, String>();
-            otherConfig.put("ovs-host-setup", "");
-            Script.runSimpleBashScript("ovs-vsctl -- --may-exist add-br "
-                    + nwName + " -- set bridge " + nwName
-                    + " other_config:ovs-host-setup='-1'");
-            s_logger.debug("### KVM network for tunnels created:" + nwName);
-        } catch (final Exception e) {
-            s_logger.warn("createTunnelNetwork failed", e);
-            return false;
-        }
-        return true;
-    }
-
-    public synchronized boolean configureTunnelNetwork(final long networkId,
-            final long hostId, final String nwName) {
-        try {
-            final boolean findResult = findOrCreateTunnelNetwork(nwName);
-            if (!findResult) {
-                s_logger.warn("LibvirtComputingResource.findOrCreateTunnelNetwork() failed! Cannot proceed creating the tunnel.");
-                return false;
-            }
-            final String configuredHosts = Script
-                    .runSimpleBashScript("ovs-vsctl get bridge " + nwName
-                            + " other_config:ovs-host-setup");
-            boolean configured = false;
-            if (configuredHosts != null) {
-                final String hostIdsStr[] = configuredHosts.split(",");
-                for (final String hostIdStr : hostIdsStr) {
-                    if (hostIdStr.equals(((Long)hostId).toString())) {
-                        configured = true;
-                        break;
-                    }
-                }
-            }
-            if (!configured) {
-                final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
-                cmd.add("setup_ovs_bridge");
-                cmd.add("--key", nwName);
-                cmd.add("--cs_host_id", ((Long)hostId).toString());
-                cmd.add("--bridge", nwName);
-                final String result = cmd.execute();
-                if (result != null) {
-                    throw new CloudRuntimeException(
-                            "Unable to pre-configure OVS bridge " + nwName
-                            + " for network ID:" + networkId);
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.warn("createandConfigureTunnelNetwork failed", e);
-            return false;
-        }
-        return true;
-    }
-
-    protected Storage.StorageResourceType getStorageResourceType() {
-        return Storage.StorageResourceType.STORAGE_POOL;
-    }
-
-    // this is much like PrimaryStorageDownloadCommand, but keeping it separate
-    public KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
-        final int index = templateUrl.lastIndexOf("/");
-        final String mountpoint = templateUrl.substring(0, index);
-        String templateName = null;
-        if (index < templateUrl.length() - 1) {
-            templateName = templateUrl.substring(index + 1);
-        }
-
-        KVMPhysicalDisk templateVol = null;
-        KVMStoragePool secondaryPool = null;
-        try {
-            secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
-            /* Get template vol */
-            if (templateName == null) {
-                secondaryPool.refresh();
-                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
-                if (disks == null || disks.isEmpty()) {
-                    s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
-                    return null;
-                }
-                for (final KVMPhysicalDisk disk : disks) {
-                    if (disk.getName().endsWith("qcow2")) {
-                        templateVol = disk;
-                        break;
-                    }
-                }
-                if (templateVol == null) {
-                    s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
-                    return null;
-                }
-            } else {
-                templateVol = secondaryPool.getPhysicalDisk(templateName);
-            }
-
-            /* Copy volume to primary storage */
-
-            final KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, 0);
-            return primaryVol;
-        } catch (final CloudRuntimeException e) {
-            s_logger.error("Failed to download template to primary storage", e);
-            return null;
-        } finally {
-            if (secondaryPool != null) {
-                _storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid());
-            }
-        }
-    }
-
-    public String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) {
-        final StoragePoolType poolType = pool.getType();
-        final PhysicalDiskFormat volFormat = vol.getFormat();
-
-        if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) {
-            return "CLVM";
-        } else if ((poolType == StoragePoolType.NetworkFilesystem
-                || poolType == StoragePoolType.SharedMountPoint
-                || poolType == StoragePoolType.Filesystem
-                || poolType == StoragePoolType.Gluster)
-                && volFormat == PhysicalDiskFormat.QCOW2 ) {
-            return "QCOW2";
-        }
-        throw new CloudRuntimeException("Cannot determine resize type from pool type " + pool.getType());
-    }
-
-    private String getBroadcastUriFromBridge(final String brName) {
-        final String pif = matchPifFileInDirectory(brName);
-        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()) {
-            if (brName.startsWith("brvx")){
-                return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString();
-            }
-            else{
-                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)#.#
-                    s_logger.debug("failed to get vNet id from bridge " + brName
-                            + "attached to physical interface" + pif + ", perhaps untagged interface");
-                    return "";
-                }
-            }
-        } else {
-            s_logger.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif);
-            return "";
-        }
-    }
-
-    private void VifHotPlug(final Connect conn, final String vmName, final String broadcastUri, final String macAddr) throws InternalErrorException, LibvirtException {
-        final NicTO nicTO = new NicTO();
-        nicTO.setMac(macAddr);
-        nicTO.setType(TrafficType.Public);
-        if (broadcastUri == null) {
-            nicTO.setBroadcastType(BroadcastDomainType.Native);
-        } else {
-            final URI uri = BroadcastDomainType.fromString(broadcastUri);
-            nicTO.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
-            nicTO.setBroadcastUri(uri);
-        }
-
-        final Domain vm = getDomain(conn, vmName);
-        vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV", "").toString());
-    }
-
-
-    private void vifHotUnPlug (final Connect conn, final String vmName, final String macAddr) throws InternalErrorException, LibvirtException {
-
-        Domain vm = null;
-        vm = getDomain(conn, vmName);
-        final List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
-        for (final InterfaceDef pluggedNic : pluggedNics) {
-            if (pluggedNic.getMacAddress().equalsIgnoreCase(macAddr)) {
-                vm.detachDevice(pluggedNic.toString());
-                // We don't know which "traffic type" is associated with
-                // each interface at this point, so inform all vif drivers
-                for (final VifDriver vifDriver : getAllVifDrivers()) {
-                    vifDriver.unplug(pluggedNic);
-                }
-            }
-        }
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
-        Connect conn;
-        final NicTO nic = cmd.getNic();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            conn = LibvirtConnection.getConnectionByVmName(routerName);
-            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
-            InterfaceDef routerNic = null;
-
-            for (final InterfaceDef pluggedNic : pluggedNics) {
-                if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
-                    routerNic = pluggedNic;
-                    break;
-                }
-            }
-
-            if (routerNic == null) {
-                return new ExecutionResult(false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName);
-            }
-
-            return new ExecutionResult(true, null);
-        } catch (final LibvirtException e) {
-            final String msg = "Creating guest network failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
-        Connect conn;
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final IpAddressTO pubIP = cmd.getIpAddress();
-
-        try {
-            conn = LibvirtConnection.getConnectionByVmName(routerName);
-            Integer devNum = 0;
-            final String pubVlan = pubIP.getBroadcastUri();
-            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
-
-            for (final InterfaceDef pluggedNic : pluggedNics) {
-                final String pluggedVlanBr = pluggedNic.getBrName();
-                final String pluggedVlanId = getBroadcastUriFromBridge(pluggedVlanBr);
-                if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED) && pluggedVlanBr.equalsIgnoreCase(_publicBridgeName)) {
-                    break;
-                } else if (pluggedVlanBr.equalsIgnoreCase(_linkLocalBridgeName)) {
-                    /*skip over, no physical bridge device exists*/
-                } else if (pluggedVlanId == null) {
-                    /*this should only be true in the case of link local bridge*/
-                    return new ExecutionResult(false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan +
-                            " on router " + routerName);
-                } else if (pluggedVlanId.equals(pubVlan)) {
-                    break;
-                }
-                devNum++;
-            }
-
-            pubIP.setNicDevId(devNum);
-
-            return new ExecutionResult(true, "success");
-        } catch (final LibvirtException e) {
-            final String msg = "Ip SNAT failure due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
-        Connect conn;
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            conn = getLibvirtUtilitiesHelper().getConnectionByVmName(routerName);
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            Integer devNum = 0;
-            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
-            final Map<String, Integer> macAddressToNicNum = new HashMap<>(pluggedNics.size());
-
-            for (final InterfaceDef pluggedNic : pluggedNics) {
-                final String pluggedVlan = pluggedNic.getBrName();
-                macAddressToNicNum.put(pluggedNic.getMacAddress(), devNum);
-                devNum++;
-            }
-
-            for (final IpAddressTO ip : ips) {
-                ip.setNicDevId(macAddressToNicNum.get(ip.getVifMacAddress()));
-            }
-
-            return new ExecutionResult(true, null);
-        } catch (final LibvirtException e) {
-            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-    }
-
-    public ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        Connect conn;
-        try {
-            conn = LibvirtConnection.getConnectionByVmName(routerName);
-            final List<InterfaceDef> nics = getInterfaces(conn, routerName);
-            final Map<String, Integer> broadcastUriAllocatedToVM = new HashMap<String, Integer>();
-            Integer nicPos = 0;
-            for (final InterfaceDef nic : nics) {
-                if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
-                    broadcastUriAllocatedToVM.put("LinkLocal", nicPos);
-                } else {
-                    if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) ||
-                            nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
-                        broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos);
-                    } else {
-                        final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName());
-                        broadcastUriAllocatedToVM.put(broadcastUri, nicPos);
-                    }
-                }
-                nicPos++;
-            }
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            int nicNum = 0;
-            for (final IpAddressTO ip : ips) {
-                boolean newNic = false;
-                if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) {
-                    /* plug a vif into router */
-                    VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress());
-                    broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++);
-                    newNic = true;
-                }
-                nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
-                networkUsage(routerIp, "addVif", "eth" + nicNum);
-
-                ip.setNicDevId(nicNum);
-                ip.setNewNic(newNic);
-            }
-            return new ExecutionResult(true, null);
-        } catch (final LibvirtException e) {
-            s_logger.error("ipassoccmd failed", e);
-            return new ExecutionResult(false, e.getMessage());
-        } catch (final InternalErrorException e) {
-            s_logger.error("ipassoccmd failed", e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-    }
-
-    protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) {
-
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
-        Connect conn;
-
-
-        try{
-            conn = LibvirtConnection.getConnectionByVmName(routerName);
-            final List<InterfaceDef> nics = getInterfaces(conn, routerName);
-            final Map<String, Integer> broadcastUriAllocatedToVM = new HashMap<String, Integer>();
-
-            Integer nicPos = 0;
-            for (final InterfaceDef nic : nics) {
-                if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
-                    broadcastUriAllocatedToVM.put("LinkLocal", nicPos);
-                } else {
-                    if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) ||
-                            nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
-                        broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos);
-                    } else {
-                        final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName());
-                        broadcastUriAllocatedToVM.put(broadcastUri, nicPos);
-                    }
-                }
-                nicPos++;
-            }
-
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            int nicNum = 0;
-            for (final IpAddressTO ip : ips) {
-
-                if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) {
-                    /* plug a vif into router */
-                    VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress());
-                    broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++);
-                }
-                nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
-
-                if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(lastIp, "true") && !ip.isAdd()) {
-                    // in isolated network eth2 is the default public interface. We don't want to delete it.
-                    if (nicNum != 2) {
-                        vifHotUnPlug(conn, routerName, ip.getVifMacAddress());
-                        networkUsage(routerIp, "deleteVif", "eth" + nicNum);
-                    }
-                }
-            }
-
-        } catch (final LibvirtException e) {
-            s_logger.error("ipassoccmd failed", e);
-            return new ExecutionResult(false, e.getMessage());
-        } catch (final InternalErrorException e) {
-            s_logger.error("ipassoccmd failed", e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-
-        return new ExecutionResult(true, null);
-    }
-
-    protected PowerState convertToPowerState(final DomainState ps) {
-        final PowerState state = s_powerStatesTable.get(ps);
-        return state == null ? PowerState.PowerUnknown : state;
-    }
-
-    public PowerState getVmState(final Connect conn, final String vmName) {
-        int retry = 3;
-        Domain vms = null;
-        while (retry-- > 0) {
-            try {
-                vms = conn.domainLookupByName(vmName);
-                final PowerState s = convertToPowerState(vms.getInfo().state);
-                return s;
-            } catch (final LibvirtException e) {
-                s_logger.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry);
-            } finally {
-                try {
-                    if (vms != null) {
-                        vms.free();
-                    }
-                } catch (final LibvirtException l) {
-                    s_logger.trace("Ignoring libvirt error.", l);
-                }
-            }
-        }
-        return PowerState.PowerOff;
-    }
-
-    public String networkUsage(final String privateIpAddress, final String option, final String vif) {
-        final Script getUsage = new Script(_routerProxyPath, s_logger);
-        getUsage.add("netusage.sh");
-        getUsage.add(privateIpAddress);
-        if (option.equals("get")) {
-            getUsage.add("-g");
-        } else if (option.equals("create")) {
-            getUsage.add("-c");
-        } else if (option.equals("reset")) {
-            getUsage.add("-r");
-        } else if (option.equals("addVif")) {
-            getUsage.add("-a", vif);
-        } else if (option.equals("deleteVif")) {
-            getUsage.add("-d", vif);
-        }
-
-        final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
-        final String result = getUsage.execute(usageParser);
-        if (result != null) {
-            s_logger.debug("Failed to execute networkUsage:" + result);
-            return null;
-        }
-        return usageParser.getLine();
-    }
-
-    public long[] getNetworkStats(final String privateIP) {
-        final String result = networkUsage(privateIP, "get", null);
-        final long[] stats = new long[2];
-        if (result != null) {
-            final String[] splitResult = result.split(":");
-            int i = 0;
-            while (i < splitResult.length - 1) {
-                stats[0] += Long.parseLong(splitResult[i++]);
-                stats[1] += Long.parseLong(splitResult[i++]);
-            }
-        }
-        return stats;
-    }
-
-    public String configureVPCNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCIDR) {
-        final Script getUsage = new Script(_routerProxyPath, s_logger);
-        getUsage.add("vpc_netusage.sh");
-        getUsage.add(privateIpAddress);
-        getUsage.add("-l", publicIp);
-
-        if (option.equals("get")) {
-            getUsage.add("-g");
-        } else if (option.equals("create")) {
-            getUsage.add("-c");
-            getUsage.add("-v", vpcCIDR);
-        } else if (option.equals("reset")) {
-            getUsage.add("-r");
-        } else if (option.equals("vpn")) {
-            getUsage.add("-n");
-        } else if (option.equals("remove")) {
-            getUsage.add("-d");
-        }
-
-        final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
-        final String result = getUsage.execute(usageParser);
-        if (result != null) {
-            s_logger.debug("Failed to execute VPCNetworkUsage:" + result);
-            return null;
-        }
-        return usageParser.getLine();
-    }
-
-    public long[] getVPCNetworkStats(final String privateIP, final String publicIp, final String option) {
-        final String result = configureVPCNetworkUsage(privateIP, publicIp, option, null);
-        final long[] stats = new long[2];
-        if (result != null) {
-            final String[] splitResult = result.split(":");
-            int i = 0;
-            while (i < splitResult.length - 1) {
-                stats[0] += Long.parseLong(splitResult[i++]);
-                stats[1] += Long.parseLong(splitResult[i++]);
-            }
-        }
-        return stats;
-    }
-
-    public void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) {
-        if (vm != null && vm.getDevices() != null) {
-            cleanupVMNetworks(conn, vm.getDevices().getInterfaces());
-        }
-    }
-
-    protected String getUuid(String uuid) {
-        if (uuid == null) {
-            uuid = UUID.randomUUID().toString();
-        } else {
-            try {
-                final UUID uuid2 = UUID.fromString(uuid);
-                final String uuid3 = uuid2.toString();
-                if (!uuid3.equals(uuid)) {
-                    uuid = UUID.randomUUID().toString();
-                }
-            } catch (final IllegalArgumentException e) {
-                uuid = UUID.randomUUID().toString();
-            }
-        }
-        return uuid;
-    }
-
-    /**
-     * Set quota and period tags on 'ctd' when CPU limit use is set
-     */
-    protected void setQuotaAndPeriod(VirtualMachineTO vmTO, CpuTuneDef ctd) {
-        if (vmTO.getLimitCpuUse() && vmTO.getCpuQuotaPercentage() != null) {
-            Double cpuQuotaPercentage = vmTO.getCpuQuotaPercentage();
-            int period = CpuTuneDef.DEFAULT_PERIOD;
-            int quota = (int) (period * cpuQuotaPercentage);
-            if (quota < CpuTuneDef.MIN_QUOTA) {
-                s_logger.info("Calculated quota (" + quota + ") below the minimum (" + CpuTuneDef.MIN_QUOTA + ") for VM domain " + vmTO.getUuid() + ", setting it to minimum " +
-                        "and calculating period instead of using the default");
-                quota = CpuTuneDef.MIN_QUOTA;
-                period = (int) ((double) quota / cpuQuotaPercentage);
-                if (period > CpuTuneDef.MAX_PERIOD) {
-                    s_logger.info("Calculated period (" + period + ") exceeds the maximum (" + CpuTuneDef.MAX_PERIOD +
-                            "), setting it to the maximum");
-                    period = CpuTuneDef.MAX_PERIOD;
-                }
-            }
-            ctd.setQuota(quota);
-            ctd.setPeriod(period);
-            s_logger.info("Setting quota=" + quota + ", period=" + period + " to VM domain " + vmTO.getUuid());
-        }
-    }
-
-    public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) {
-        final LibvirtVMDef vm = new LibvirtVMDef();
-        vm.setDomainName(vmTO.getName());
-        String uuid = vmTO.getUuid();
-        uuid = getUuid(uuid);
-        vm.setDomUUID(uuid);
-        vm.setDomDescription(vmTO.getOs());
-        vm.setPlatformEmulator(vmTO.getPlatformEmulator());
-
-        final GuestDef guest = new GuestDef();
-
-        if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User == vmTO.getType()) {
-            // LXC domain is only valid for user VMs. Use KVM for system VMs.
-            guest.setGuestType(GuestDef.GuestType.LXC);
-            vm.setHvsType(HypervisorType.LXC.toString().toLowerCase());
-        } else {
-            guest.setGuestType(GuestDef.GuestType.KVM);
-            vm.setHvsType(HypervisorType.KVM.toString().toLowerCase());
-            vm.setLibvirtVersion(_hypervisorLibvirtVersion);
-            vm.setQemuVersion(_hypervisorQemuVersion);
-        }
-        guest.setGuestArch(vmTO.getArch());
-        guest.setMachineType("pc");
-        guest.setUuid(uuid);
-        guest.setBootOrder(GuestDef.BootOrder.CDROM);
-        guest.setBootOrder(GuestDef.BootOrder.HARDISK);
-
-        vm.addComp(guest);
-
-        final GuestResourceDef grd = new GuestResourceDef();
-
-        if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) {
-            grd.setMemBalloning(true);
-            grd.setCurrentMem(vmTO.getMinRam() / 1024);
-            grd.setMemorySize(vmTO.getMaxRam() / 1024);
-        } else {
-            grd.setMemorySize(vmTO.getMaxRam() / 1024);
-        }
-        final int vcpus = vmTO.getCpus();
-        grd.setVcpuNum(vcpus);
-        vm.addComp(grd);
-
-        final CpuModeDef cmd = new CpuModeDef();
-        cmd.setMode(_guestCpuMode);
-        cmd.setModel(_guestCpuModel);
-        if (vmTO.getType() == VirtualMachine.Type.User) {
-            cmd.setFeatures(_cpuFeatures);
-        }
-        // multi cores per socket, for larger core configs
-        if (vcpus % 6 == 0) {
-            final int sockets = vcpus / 6;
-            cmd.setTopology(6, sockets);
-        } else if (vcpus % 4 == 0) {
-            final int sockets = vcpus / 4;
-            cmd.setTopology(4, sockets);
-        }
-        vm.addComp(cmd);
-
-        if (_hypervisorLibvirtVersion >= 9000) {
-            final CpuTuneDef ctd = new CpuTuneDef();
-            /**
-             A 4.0.X/4.1.X management server doesn't send the correct JSON
-             command for getMinSpeed, it only sends a 'speed' field.
-
-             So if getMinSpeed() returns null we fall back to getSpeed().
-
-             This way a >4.1 agent can work communicate a <=4.1 management server
-
-             This change is due to the overcommit feature in 4.2
-             */
-            if (vmTO.getMinSpeed() != null) {
-                ctd.setShares(vmTO.getCpus() * vmTO.getMinSpeed());
-            } else {
-                ctd.setShares(vmTO.getCpus() * vmTO.getSpeed());
-            }
-
-            setQuotaAndPeriod(vmTO, ctd);
-
-            vm.addComp(ctd);
-        }
-
-        final FeaturesDef features = new FeaturesDef();
-        features.addFeatures("pae");
-        features.addFeatures("apic");
-        features.addFeatures("acpi");
-        //for rhel 6.5 and above, hyperv enlightment feature is added
-        /*
-         * if (vmTO.getOs().contains("Windows Server 2008") && hostOsVersion != null && ((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7))) {
-         *    LibvirtVMDef.HyperVEnlightenmentFeatureDef hyv = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
-         *    hyv.setRelaxed(true);
-         *    features.addHyperVFeature(hyv);
-         * }
-         */
-        vm.addComp(features);
-
-        final TermPolicy term = new TermPolicy();
-        term.setCrashPolicy("destroy");
-        term.setPowerOffPolicy("destroy");
-        term.setRebootPolicy("restart");
-        vm.addComp(term);
-
-        final ClockDef clock = new ClockDef();
-        if (vmTO.getOs().startsWith("Windows")) {
-            clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME);
-            clock.setTimer("rtc", "catchup", null);
-        } else if (vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) {
-            if (_hypervisorLibvirtVersion >= 9 * 1000 + 10) {
-                clock.setTimer("kvmclock", null, null, _noKvmClock);
-            }
-        }
-
-        vm.addComp(clock);
-
-        final DevicesDef devices = new DevicesDef();
-        devices.setEmulatorPath(_hypervisorPath);
-        devices.setGuestType(guest.getGuestType());
-
-        final SerialDef serial = new SerialDef("pty", null, (short)0);
-        devices.addDevice(serial);
-
-        if (_rngEnable) {
-            final RngDef rngDevice = new RngDef(_rngPath, _rngBackendModel, _rngRateBytes, _rngRatePeriod);
-            devices.addDevice(rngDevice);
-        }
-
-        /* Add a VirtIO channel for the Qemu Guest Agent tools */
-        devices.addDevice(new ChannelDef(_qemuGuestAgentSocketName, ChannelDef.ChannelType.UNIX,
-                          new File(_qemuSocketsPath + "/" + vmTO.getName() + "." + _qemuGuestAgentSocketName)));
-
-        devices.addDevice(new WatchDogDef(_watchDogAction, _watchDogModel));
-
-        final VideoDef videoCard = new VideoDef(_videoHw, _videoRam);
-        devices.addDevice(videoCard);
-
-        final ConsoleDef console = new ConsoleDef("pty", null, null, (short)0);
-        devices.addDevice(console);
-
-        //add the VNC port passwd here, get the passwd from the vmInstance.
-        final String passwd = vmTO.getVncPassword();
-        final GraphicDef grap = new GraphicDef("vnc", (short)0, true, vmTO.getVncAddr(), passwd, null);
-        devices.addDevice(grap);
-
-        final InputDef input = new InputDef("tablet", "usb");
-        devices.addDevice(input);
-
-
-        DiskDef.DiskBus busT = getDiskModelFromVMDetail(vmTO);
-
-        if (busT == null) {
-            busT = getGuestDiskModel(vmTO.getPlatformEmulator());
-        }
-
-        // If we're using virtio scsi, then we need to add a virtual scsi controller
-        if (busT == DiskDef.DiskBus.SCSI) {
-            final SCSIDef sd = new SCSIDef((short)0, 0, 0, 9, 0);
-            devices.addDevice(sd);
-        }
-
-        vm.addComp(devices);
-
-        return vm;
-    }
-
-    public void createVifs(final VirtualMachineTO vmSpec, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException {
-        final NicTO[] nics = vmSpec.getNics();
-        final Map <String, String> params = vmSpec.getDetails();
-        String nicAdapter = "";
-        if (params != null && params.get("nicAdapter") != null && !params.get("nicAdapter").isEmpty()) {
-            nicAdapter = params.get("nicAdapter");
-        }
-        for (int i = 0; i < nics.length; i++) {
-            for (final NicTO nic : vmSpec.getNics()) {
-                if (nic.getDeviceId() == i) {
-                    createVif(vm, nic, nicAdapter);
-                }
-            }
-        }
-    }
-
-    public String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException {
-        final DataTO data = volume.getData();
-        final DataStoreTO store = data.getDataStore();
-
-        if (volume.getType() == Volume.Type.ISO && data.getPath() != null && (store instanceof NfsTO ||
-                store instanceof PrimaryDataStoreTO && data instanceof TemplateObjectTO && !((TemplateObjectTO) data).isDirectDownload())) {
-            final String isoPath = store.getUrl().split("\\?")[0] + File.separator + data.getPath();
-            final int index = isoPath.lastIndexOf("/");
-            final String path = isoPath.substring(0, index);
-            final String name = isoPath.substring(index + 1);
-            final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path);
-            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
-            return isoVol.getPath();
-        } else {
-            return data.getPath();
-        }
-    }
-
-    public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException {
-        final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
-        Collections.sort(disks, new Comparator<DiskTO>() {
-            @Override
-            public int compare(final DiskTO arg0, final DiskTO arg1) {
-                return arg0.getDiskSeq() > arg1.getDiskSeq() ? 1 : -1;
-            }
-        });
-
-        for (final DiskTO volume : disks) {
-            KVMPhysicalDisk physicalDisk = null;
-            KVMStoragePool pool = null;
-            final DataTO data = volume.getData();
-            if (volume.getType() == Volume.Type.ISO && data.getPath() != null) {
-                DataStoreTO dataStore = data.getDataStore();
-                String dataStoreUrl = null;
-                if (dataStore instanceof NfsTO) {
-                    NfsTO nfsStore = (NfsTO)data.getDataStore();
-                    dataStoreUrl = nfsStore.getUrl();
-                } else if (dataStore instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO) dataStore).getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
-                    //In order to support directly downloaded ISOs
-                    String psHost = ((PrimaryDataStoreTO) dataStore).getHost();
-                    String psPath = ((PrimaryDataStoreTO) dataStore).getPath();
-                    dataStoreUrl = "nfs://" + psHost + File.separator + psPath;
-                }
-                final String volPath = dataStoreUrl + File.separator + data.getPath();
-                final int index = volPath.lastIndexOf("/");
-                final String volDir = volPath.substring(0, index);
-                final String volName = volPath.substring(index + 1);
-                final KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir);
-                physicalDisk = secondaryStorage.getPhysicalDisk(volName);
-            } else if (volume.getType() != Volume.Type.ISO) {
-                final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
-                physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
-                pool = physicalDisk.getPool();
-            }
-
-            String volPath = null;
-            if (physicalDisk != null) {
-                volPath = physicalDisk.getPath();
-            }
-
-            // check for disk activity, if detected we should exit because vm is running elsewhere
-            if (_diskActivityCheckEnabled && physicalDisk != null && physicalDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
-                s_logger.debug("Checking physical disk file at path " + volPath + " for disk activity to ensure vm is not running elsewhere");
-                try {
-                    HypervisorUtils.checkVolumeFileForActivity(volPath, _diskActivityCheckTimeoutSeconds, _diskActivityInactiveThresholdMilliseconds, _diskActivityCheckFileSizeMin);
-                } catch (final IOException ex) {
-                    throw new CloudRuntimeException("Unable to check physical disk file for activity", ex);
-                }
-                s_logger.debug("Disk activity check cleared");
-            }
-
-            // if params contains a rootDiskController key, use its value (this is what other HVs are doing)
-            DiskDef.DiskBus diskBusType = getDiskModelFromVMDetail(vmSpec);
-
-            if (diskBusType == null) {
-                diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator());
-            }
-
-            // I'm not sure why previously certain DATADISKs were hard-coded VIRTIO and others not, however this
-            // maintains existing functionality with the exception that SCSI will override VIRTIO.
-            DiskDef.DiskBus diskBusTypeData = (diskBusType == DiskDef.DiskBus.SCSI) ? diskBusType : DiskDef.DiskBus.VIRTIO;
-
-            final DiskDef disk = new DiskDef();
-            int devId = volume.getDiskSeq().intValue();
-            if (volume.getType() == Volume.Type.ISO) {
-                if (volPath == null) {
-                    /* Add iso as placeholder */
-                    disk.defISODisk(null, devId);
-                } else {
-                    disk.defISODisk(volPath, devId);
-                }
-            } else {
-                if (diskBusType == DiskDef.DiskBus.SCSI ) {
-                    disk.setQemuDriver(true);
-                    disk.setDiscard(DiscardType.UNMAP);
-                }
-
-                if (pool.getType() == StoragePoolType.RBD) {
-                    /*
-                            For RBD pools we use the secret mechanism in libvirt.
-                            We store the secret under the UUID of the pool, that's why
-                            we pass the pool's UUID as the authSecret
-                     */
-                    disk.defNetworkBasedDisk(physicalDisk.getPath().replace("rbd:", ""), pool.getSourceHost(), pool.getSourcePort(), pool.getAuthUserName(),
-                            pool.getUuid(), devId, diskBusType, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
-                } else if (pool.getType() == StoragePoolType.Gluster) {
-                    final String mountpoint = pool.getLocalPath();
-                    final String path = physicalDisk.getPath();
-                    final String glusterVolume = pool.getSourceDir().replace("/", "");
-                    disk.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), pool.getSourceHost(), pool.getSourcePort(), null,
-                            null, devId, diskBusType, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
-                } else if (pool.getType() == StoragePoolType.CLVM || physicalDisk.getFormat() == PhysicalDiskFormat.RAW) {
-                    disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
-                } else {
-                    if (volume.getType() == Volume.Type.DATADISK) {
-                        disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
-                    } else {
-                        disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusType, DiskDef.DiskFmtType.QCOW2);
-                    }
-
-                }
-
-            }
-
-            if (data instanceof VolumeObjectTO) {
-                final VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data;
-                disk.setSerial(diskUuidToSerial(volumeObjectTO.getUuid()));
-                if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) {
-                    disk.setBytesReadRate(volumeObjectTO.getBytesReadRate());
-                }
-                if (volumeObjectTO.getBytesWriteRate() != null && volumeObjectTO.getBytesWriteRate() > 0) {
-                    disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate());
-                }
-                if (volumeObjectTO.getIopsReadRate() != null && volumeObjectTO.getIopsReadRate() > 0) {
-                    disk.setIopsReadRate(volumeObjectTO.getIopsReadRate());
-                }
-                if (volumeObjectTO.getIopsWriteRate() != null && volumeObjectTO.getIopsWriteRate() > 0) {
-                    disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate());
-                }
-                if (volumeObjectTO.getCacheMode() != null) {
-                    disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase()));
-                }
-            }
-
-            vm.getDevices().addDevice(disk);
-        }
-
-        if (vmSpec.getType() != VirtualMachine.Type.User) {
-            if (_sysvmISOPath != null) {
-                final DiskDef iso = new DiskDef();
-                iso.defISODisk(_sysvmISOPath);
-                vm.getDevices().addDevice(iso);
-            }
-        }
-
-        // For LXC, find and add the root filesystem, rbd data disks
-        if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) {
-            for (final DiskTO volume : disks) {
-                final DataTO data = volume.getData();
-                final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
-                if (volume.getType() == Volume.Type.ROOT) {
-                    final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
-                    final FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/");
-                    vm.getDevices().addDevice(rootFs);
-                } else if (volume.getType() == Volume.Type.DATADISK) {
-                    final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
-                    final KVMStoragePool pool = physicalDisk.getPool();
-                    if(StoragePoolType.RBD.equals(pool.getType())) {
-                        final int devId = volume.getDiskSeq().intValue();
-                        final String device = mapRbdDevice(physicalDisk);
-                        if (device != null) {
-                            s_logger.debug("RBD device on host is: " + device);
-                            final DiskDef diskdef = new DiskDef();
-                            diskdef.defBlockBasedDisk(device, devId, DiskDef.DiskBus.VIRTIO);
-                            diskdef.setQemuDriver(false);
-                            vm.getDevices().addDevice(diskdef);
-                        } else {
-                            throw new InternalErrorException("Error while mapping RBD device on host");
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    private void createVif(final LibvirtVMDef vm, final NicTO nic, final String nicAdapter) throws InternalErrorException, LibvirtException {
-
-        if (nic.getType().equals(TrafficType.Guest) && nic.getBroadcastType().equals(BroadcastDomainType.Vsp)) {
-            String vrIp = nic.getBroadcastUri().getPath().substring(1);
-            vm.getMetaData().getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension(nic.getMac(), vrIp);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NIC with MAC " + nic.getMac() + " and BroadcastDomainType " + nic.getBroadcastType() + " in network(" + nic.getGateway() + "/" + nic.getNetmask()
-                        + ") is " + nic.getType() + " traffic type. So, vsp-vr-ip " + vrIp + " is set in the metadata");
-            }
-        }
-
-        vm.getDevices().addDevice(getVifDriver(nic.getType(), nic.getName()).plug(nic, vm.getPlatformEmulator(), nicAdapter));
-    }
-
-    public boolean cleanupDisk(Map<String, String> volumeToDisconnect) {
-        return _storagePoolMgr.disconnectPhysicalDisk(volumeToDisconnect);
-    }
-
-    public boolean cleanupDisk(final DiskDef disk) {
-        final String path = disk.getDiskPath();
-
-        if (path == null) {
-            s_logger.debug("Unable to clean up disk with null path (perhaps empty cdrom drive):" + disk);
-            return false;
-        }
-
-        if (path.endsWith("systemvm.iso")) {
-            // don't need to clean up system vm ISO as it's stored in local
-            return true;
-        }
-
-        return _storagePoolMgr.disconnectPhysicalDiskByPath(path);
-    }
-
-    protected KVMStoragePoolManager getPoolManager() {
-        return _storagePoolMgr;
-    }
-
-    public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException,
-    InternalErrorException {
-        final DiskDef iso = new DiskDef();
-        if (isoPath != null && isAttach) {
-            final int index = isoPath.lastIndexOf("/");
-            final String path = isoPath.substring(0, index);
-            final String name = isoPath.substring(index + 1);
-            final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path);
-            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
-            isoPath = isoVol.getPath();
-
-            iso.defISODisk(isoPath, diskSeq);
-        } else {
-            iso.defISODisk(null, diskSeq);
-        }
-
-        final String result = attachOrDetachDevice(conn, true, vmName, iso.toString());
-        if (result == null && !isAttach) {
-            final List<DiskDef> disks = getDisks(conn, vmName);
-            for (final DiskDef disk : disks) {
-                if (disk.getDeviceType() == DiskDef.DeviceType.CDROM
-                        && (diskSeq == null || disk.getDiskLabel() == iso.getDiskLabel())) {
-                    cleanupDisk(disk);
-                }
-            }
-
-        }
-        return result;
-    }
-
-    public synchronized String attachOrDetachDisk(final Connect conn,
-            final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk,
-            final int devId, final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate, final String cacheMode) throws LibvirtException, InternalErrorException {
-        List<DiskDef> disks = null;
-        Domain dm = null;
-        DiskDef diskdef = null;
-        final KVMStoragePool attachingPool = attachingDisk.getPool();
-        try {
-            dm = conn.domainLookupByName(vmName);
-            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-            final String domXml = dm.getXMLDesc(0);
-            parser.parseDomainXML(domXml);
-            disks = parser.getDisks();
-
-            if (!attach) {
-                for (final DiskDef disk : disks) {
-                    final String file = disk.getDiskPath();
-                    if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
-                        diskdef = disk;
-                        break;
-                    }
-                }
-                if (diskdef == null) {
-                    throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before");
-                }
-            } else {
-                DiskDef.DiskBus busT = DiskDef.DiskBus.VIRTIO;
-                for (final DiskDef disk : disks) {
-                    if (disk.getDeviceType() == DeviceType.DISK) {
-                        if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
-                            busT = DiskDef.DiskBus.SCSI;
-                        }
-                        break;
-                    }
-                }
-
-                diskdef = new DiskDef();
-                if (busT == DiskDef.DiskBus.SCSI) {
-                    diskdef.setQemuDriver(true);
-                    diskdef.setDiscard(DiscardType.UNMAP);
-                }
-                if (attachingPool.getType() == StoragePoolType.RBD) {
-                    diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), attachingPool.getAuthUserName(),
-                            attachingPool.getUuid(), devId, busT, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
-                } else if (attachingPool.getType() == StoragePoolType.Gluster) {
-                    diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), null,
-                            null, devId, busT, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
-                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
-                    diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
-                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
-                    diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
-                }
-                if (bytesReadRate != null && bytesReadRate > 0) {
-                    diskdef.setBytesReadRate(bytesReadRate);
-                }
-                if (bytesWriteRate != null && bytesWriteRate > 0) {
-                    diskdef.setBytesWriteRate(bytesWriteRate);
-                }
-                if (iopsReadRate != null && iopsReadRate > 0) {
-                    diskdef.setIopsReadRate(iopsReadRate);
-                }
-                if (iopsWriteRate != null && iopsWriteRate > 0) {
-                    diskdef.setIopsWriteRate(iopsWriteRate);
-                }
-
-                if (cacheMode != null) {
-                    diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
-                }
-            }
-
-            final String xml = diskdef.toString();
-            return attachOrDetachDevice(conn, attach, vmName, xml);
-        } finally {
-            if (dm != null) {
-                dm.free();
-            }
-        }
-    }
-
-    protected synchronized String attachOrDetachDevice(final Connect conn, final boolean attach, final String vmName, final String xml) throws LibvirtException, InternalErrorException {
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            if (attach) {
-                s_logger.debug("Attaching device: " + xml);
-                dm.attachDevice(xml);
-            } else {
-                s_logger.debug("Detaching device: " + xml);
-                dm.detachDevice(xml);
-            }
-        } catch (final LibvirtException e) {
-            if (attach) {
-                s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage());
-            } else {
-                s_logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage());
-            }
-            throw e;
-        } finally {
-            if (dm != null) {
-                try {
-                    dm.free();
-                } catch (final LibvirtException l) {
-                    s_logger.trace("Ignoring libvirt error.", l);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(final long id) {
-
-        if (!_canBridgeFirewall) {
-            return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, this.getHostVmStateReport());
-        } else {
-            final HashMap<String, Pair<Long, Long>> nwGrpStates = syncNetworkGroups(id);
-            return new PingRoutingWithNwGroupsCommand(getType(), id, this.getHostVmStateReport(), nwGrpStates);
-        }
-    }
-
-    @Override
-    public Type getType() {
-        return Type.Routing;
-    }
-
-    private Map<String, String> getVersionStrings() {
-        final Script command = new Script(_versionstringpath, _timeout, s_logger);
-        final KeyValueInterpreter kvi = new KeyValueInterpreter();
-        final String result = command.execute(kvi);
-        if (result == null) {
-            return kvi.getKeyValues();
-        } else {
-            return new HashMap<String, String>(1);
-        }
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-
-        final List<Object> info = getHostInfo();
-        _totalMemory = (Long)info.get(2);
-
-        final StartupRoutingCommand cmd =
-                new StartupRoutingCommand((Integer)info.get(0), (Long)info.get(1), (Long)info.get(2), (Long)info.get(4), (String)info.get(3), _hypervisorType,
-                        RouterPrivateIpStrategy.HostLocal);
-        cmd.setCpuSockets((Integer)info.get(5));
-        fillNetworkInformation(cmd);
-        _privateIp = cmd.getPrivateIpAddress();
-        cmd.getHostDetails().putAll(getVersionStrings());
-        cmd.getHostDetails().put(KeyStoreUtils.SECURED, String.valueOf(isHostSecured()).toLowerCase());
-        cmd.setPool(_pool);
-        cmd.setCluster(_clusterId);
-        cmd.setGatewayIpAddress(_localGateway);
-        cmd.setIqn(getIqn());
-
-        if (cmd.getHostDetails().containsKey("Host.OS")) {
-            _hostDistro = cmd.getHostDetails().get("Host.OS");
-        }
-
-        StartupStorageCommand sscmd = null;
-        try {
-
-            final KVMStoragePool localStoragePool = _storagePoolMgr.createStoragePool(_localStorageUUID, "localhost", -1, _localStoragePath, "", StoragePoolType.Filesystem);
-            final com.cloud.agent.api.StoragePoolInfo pi =
-                    new com.cloud.agent.api.StoragePoolInfo(localStoragePool.getUuid(), cmd.getPrivateIpAddress(), _localStoragePath, _localStoragePath,
-                            StoragePoolType.Filesystem, localStoragePool.getCapacity(), localStoragePool.getAvailable());
-
-            sscmd = new StartupStorageCommand();
-            sscmd.setPoolInfo(pi);
-            sscmd.setGuid(pi.getUuid());
-            sscmd.setDataCenter(_dcId);
-            sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Unable to initialize local storage pool: " + e);
-        }
-
-        if (sscmd != null) {
-            return new StartupCommand[] {cmd, sscmd};
-        } else {
-            return new StartupCommand[] {cmd};
-        }
-    }
-
-    public String diskUuidToSerial(String uuid) {
-        String uuidWithoutHyphen = uuid.replace("-","");
-        return uuidWithoutHyphen.substring(0, Math.min(uuidWithoutHyphen.length(), 20));
-    }
-
-    private String getIqn() {
-        try {
-            final String textToFind = "InitiatorName=";
-
-            final Script iScsiAdmCmd = new Script(true, "grep", 0, s_logger);
-
-            iScsiAdmCmd.add(textToFind);
-            iScsiAdmCmd.add("/etc/iscsi/initiatorname.iscsi");
-
-            final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
-
-            final String result = iScsiAdmCmd.execute(parser);
-
-            if (result != null) {
-                return null;
-            }
-
-            final String textFound = parser.getLine().trim();
-
-            return textFound.substring(textToFind.length());
-        }
-        catch (final Exception ex) {
-            return null;
-        }
-    }
-
-    protected List<String> getAllVmNames(final Connect conn) {
-        final ArrayList<String> la = new ArrayList<String>();
-        try {
-            final String names[] = conn.listDefinedDomains();
-            for (int i = 0; i < names.length; i++) {
-                la.add(names[i]);
-            }
-        } catch (final LibvirtException e) {
-            s_logger.warn("Failed to list Defined domains", e);
-        }
-
-        int[] ids = null;
-        try {
-            ids = conn.listDomains();
-        } catch (final LibvirtException e) {
-            s_logger.warn("Failed to list domains", e);
-            return la;
-        }
-
-        Domain dm = null;
-        for (int i = 0; i < ids.length; i++) {
-            try {
-                dm = conn.domainLookupByID(ids[i]);
-                la.add(dm.getName());
-            } catch (final LibvirtException e) {
-                s_logger.warn("Unable to get vms", e);
-            } finally {
-                try {
-                    if (dm != null) {
-                        dm.free();
-                    }
-                } catch (final LibvirtException e) {
-                    s_logger.trace("Ignoring libvirt error.", e);
-                }
-            }
-        }
-
-        return la;
-    }
-
-    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport() {
-        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
-        Connect conn = null;
-
-        if (_hypervisorType == HypervisorType.LXC) {
-            try {
-                conn = LibvirtConnection.getConnectionByType(HypervisorType.LXC.toString());
-                vmStates.putAll(getHostVmStateReport(conn));
-                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
-                vmStates.putAll(getHostVmStateReport(conn));
-            } catch (final LibvirtException e) {
-                s_logger.debug("Failed to get connection: " + e.getMessage());
-            }
-        }
-
-        if (_hypervisorType == HypervisorType.KVM) {
-            try {
-                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
-                vmStates.putAll(getHostVmStateReport(conn));
-            } catch (final LibvirtException e) {
-                s_logger.debug("Failed to get connection: " + e.getMessage());
-            }
-        }
-
-        return vmStates;
-    }
-
-    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport(final Connect conn) {
-        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
-
-        String[] vms = null;
-        int[] ids = null;
-
-        try {
-            ids = conn.listDomains();
-        } catch (final LibvirtException e) {
-            s_logger.warn("Unable to listDomains", e);
-            return null;
-        }
-        try {
-            vms = conn.listDefinedDomains();
-        } catch (final LibvirtException e) {
-            s_logger.warn("Unable to listDomains", e);
-            return null;
-        }
-
-        Domain dm = null;
-        for (int i = 0; i < ids.length; i++) {
-            try {
-                dm = conn.domainLookupByID(ids[i]);
-
-                final DomainState ps = dm.getInfo().state;
-
-                final PowerState state = convertToPowerState(ps);
-
-                s_logger.trace("VM " + dm.getName() + ": powerstate = " + ps + "; vm state=" + state.toString());
-                final String vmName = dm.getName();
-
-                // TODO : for XS/KVM (host-based resource), we require to remove
-                // VM completely from host, for some reason, KVM seems to still keep
-                // Stopped VM around, to work-around that, reporting only powered-on VM
-                //
-                if (state == PowerState.PowerOn) {
-                    vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
-                }
-            } catch (final LibvirtException e) {
-                s_logger.warn("Unable to get vms", e);
-            } finally {
-                try {
-                    if (dm != null) {
-                        dm.free();
-                    }
-                } catch (final LibvirtException e) {
-                    s_logger.trace("Ignoring libvirt error.", e);
-                }
-            }
-        }
-
-        for (int i = 0; i < vms.length; i++) {
-            try {
-
-                dm = conn.domainLookupByName(vms[i]);
-
-                final DomainState ps = dm.getInfo().state;
-                final PowerState state = convertToPowerState(ps);
-                final String vmName = dm.getName();
-                s_logger.trace("VM " + vmName + ": powerstate = " + ps + "; vm state=" + state.toString());
-
-                // TODO : for XS/KVM (host-based resource), we require to remove
-                // VM completely from host, for some reason, KVM seems to still keep
-                // Stopped VM around, to work-around that, reporting only powered-on VM
-                //
-                if (state == PowerState.PowerOn) {
-                    vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
-                }
-            } catch (final LibvirtException e) {
-                s_logger.warn("Unable to get vms", e);
-            } finally {
-                try {
-                    if (dm != null) {
-                        dm.free();
-                    }
-                } catch (final LibvirtException e) {
-                    s_logger.trace("Ignoring libvirt error.", e);
-                }
-            }
-        }
-
-        return vmStates;
-    }
-
-    protected List<Object> getHostInfo() {
-        final ArrayList<Object> info = new ArrayList<Object>();
-        long speed = 0;
-        long cpus = 0;
-        long ram = 0;
-        int cpuSockets = 0;
-        String cap = null;
-        try {
-            final Connect conn = LibvirtConnection.getConnection();
-            final NodeInfo hosts = conn.nodeInfo();
-            speed = getCpuSpeed(hosts);
-
-            /*
-            * Some CPUs report a single socket and multiple NUMA cells.
-            * We need to multiply them to get the correct socket count.
-            */
-            cpuSockets = hosts.sockets;
-            if (hosts.nodes > 0) {
-                cpuSockets = hosts.sockets * hosts.nodes;
-            }
-            cpus = hosts.cpus;
-            ram = hosts.memory * 1024L;
-            final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
-            parser.parseCapabilitiesXML(conn.getCapabilities());
-            final ArrayList<String> oss = parser.getGuestOsType();
-            for (final String s : oss) {
-                /*
-                 * Even host supports guest os type more than hvm, we only
-                 * report hvm to management server
-                 */
-                if (s.equalsIgnoreCase("hvm")) {
-                    cap = "hvm";
-                }
-            }
-        } catch (final LibvirtException e) {
-            s_logger.trace("Ignoring libvirt error.", e);
-        }
-
-        if (isSnapshotSupported()) {
-            cap = cap + ",snapshot";
-        }
-
-        info.add((int)cpus);
-        info.add(speed);
-        // Report system's RAM as actual RAM minus host OS reserved RAM
-        ram = ram - _dom0MinMem + _dom0OvercommitMem;
-        info.add(ram);
-        info.add(cap);
-        info.add(_dom0MinMem);
-        info.add(cpuSockets);
-        s_logger.debug("cpus=" + cpus + ", speed=" + speed + ", ram=" + ram + ", _dom0MinMem=" + _dom0MinMem + ", _dom0OvercommitMem=" + _dom0OvercommitMem + ", cpu sockets=" + cpuSockets);
-
-        return info;
-    }
-
-    protected static long getCpuSpeed(final NodeInfo nodeInfo) {
-        try (final Reader reader = new FileReader(
-                "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")) {
-            return Long.parseLong(IOUtils.toString(reader).trim()) / 1000;
-        } catch (IOException | NumberFormatException e) {
-            s_logger.warn("Could not read cpuinfo_max_freq");
-            return nodeInfo.mhz;
-        }
-    }
-
-    public String rebootVM(final Connect conn, final String vmName) {
-        Domain dm = null;
-        String msg = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            // Get XML Dump including the secure information such as VNC password
-            // By passing 1, or VIR_DOMAIN_XML_SECURE flag
-            // https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
-            String vmDef = dm.getXMLDesc(1);
-            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-            parser.parseDomainXML(vmDef);
-            for (final InterfaceDef nic : parser.getInterfaces()) {
-                if (nic.getNetType() == GuestNetType.BRIDGE && nic.getBrName().startsWith("cloudVirBr")) {
-                    try {
-                        final int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", ""));
-                        final String pifName = getPif(_guestBridgeName);
-                        final String newBrName = "br" + pifName + "-" + vnetId;
-                        vmDef = vmDef.replaceAll("'" + nic.getBrName() + "'", "'" + newBrName + "'");
-                        s_logger.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName);
-                    } catch (final NumberFormatException e) {
-                        continue;
-                    }
-                }
-            }
-            s_logger.debug(vmDef);
-            msg = stopVM(conn, vmName, false);
-            msg = startVM(conn, vmName, vmDef);
-            return null;
-        } catch (final LibvirtException e) {
-            s_logger.warn("Failed to create vm", e);
-            msg = e.getMessage();
-        } catch (final InternalErrorException e) {
-            s_logger.warn("Failed to create vm", e);
-            msg = e.getMessage();
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (final LibvirtException e) {
-                s_logger.trace("Ignoring libvirt error.", e);
-            }
-        }
-
-        return msg;
-    }
-
-    public String stopVM(final Connect conn, final String vmName, final boolean forceStop) {
-        DomainState state = null;
-        Domain dm = null;
-
-        // delete the metadata of vm snapshots before stopping
-        try {
-            dm = conn.domainLookupByName(vmName);
-            cleanVMSnapshotMetadata(dm);
-        } catch (LibvirtException e) {
-            s_logger.debug("Failed to get vm :" + e.getMessage());
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (LibvirtException l) {
-                s_logger.trace("Ignoring libvirt error.", l);
-            }
-        }
-
-        s_logger.debug("Try to stop the vm at first");
-        if (forceStop) {
-            return stopVMInternal(conn, vmName, true);
-        }
-        String ret = stopVMInternal(conn, vmName, false);
-        if (ret == Script.ERR_TIMEOUT) {
-            ret = stopVMInternal(conn, vmName, true);
-        } else if (ret != null) {
-            /*
-             * There is a race condition between libvirt and qemu: libvirt
-             * listens on qemu's monitor fd. If qemu is shutdown, while libvirt
-             * is reading on the fd, then libvirt will report an error.
-             */
-            /* Retry 3 times, to make sure we can get the vm's status */
-            for (int i = 0; i < 3; i++) {
-                try {
-                    dm = conn.domainLookupByName(vmName);
-                    state = dm.getInfo().state;
-                    break;
-                } catch (final LibvirtException e) {
-                    s_logger.debug("Failed to get vm status:" + e.getMessage());
-                } finally {
-                    try {
-                        if (dm != null) {
-                            dm.free();
-                        }
-                    } catch (final LibvirtException l) {
-                        s_logger.trace("Ignoring libvirt error.", l);
-                    }
-                }
-            }
-
-            if (state == null) {
-                s_logger.debug("Can't get vm's status, assume it's dead already");
-                return null;
-            }
-
-            if (state != DomainState.VIR_DOMAIN_SHUTOFF) {
-                s_logger.debug("Try to destroy the vm");
-                ret = stopVMInternal(conn, vmName, true);
-                if (ret != null) {
-                    return ret;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    protected String stopVMInternal(final Connect conn, final String vmName, final boolean force) {
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            final int persist = dm.isPersistent();
-            if (force) {
-                if (dm.isActive() == 1) {
-                    dm.destroy();
-                    if (persist == 1) {
-                        dm.undefine();
-                    }
-                }
-            } else {
-                if (dm.isActive() == 0) {
-                    return null;
-                }
-                dm.shutdown();
-                int retry = _stopTimeout / 2000;
-                /* Wait for the domain gets into shutoff state. When it does
-                   the dm object will no longer work, so we need to catch it. */
-                try {
-                    while (dm.isActive() == 1 && retry >= 0) {
-                        Thread.sleep(2000);
-                        retry--;
-                    }
-                } catch (final LibvirtException e) {
-                    final String error = e.toString();
-                    if (error.contains("Domain not found")) {
-                        s_logger.debug("successfully shut down vm " + vmName);
-                    } else {
-                        s_logger.debug("Error in waiting for vm shutdown:" + error);
-                    }
-                }
-                if (retry < 0) {
-                    s_logger.warn("Timed out waiting for domain " + vmName + " to shutdown gracefully");
-                    return Script.ERR_TIMEOUT;
-                } else {
-                    if (persist == 1) {
-                        dm.undefine();
-                    }
-                }
-            }
-        } catch (final LibvirtException e) {
-            if (e.getMessage().contains("Domain not found")) {
-                s_logger.debug("VM " + vmName + " doesn't exist, no need to stop it");
-                return null;
-            }
-            s_logger.debug("Failed to stop VM :" + vmName + " :", e);
-            return e.getMessage();
-        } catch (final InterruptedException ie) {
-            s_logger.debug("Interrupted sleep");
-            return ie.getMessage();
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (final LibvirtException e) {
-                s_logger.trace("Ignoring libvirt error.", e);
-            }
-        }
-
-        return null;
-    }
-
-    public Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException {
-        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            final String xmlDesc = dm.getXMLDesc(0);
-            parser.parseDomainXML(xmlDesc);
-            return parser.getVncPort();
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (final LibvirtException l) {
-                s_logger.trace("Ignoring libvirt error.", l);
-            }
-        }
-    }
-
-    private boolean IsHVMEnabled(final Connect conn) {
-        final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
-        try {
-            parser.parseCapabilitiesXML(conn.getCapabilities());
-            final ArrayList<String> osTypes = parser.getGuestOsType();
-            for (final String o : osTypes) {
-                if (o.equalsIgnoreCase("hvm")) {
-                    return true;
-                }
-            }
-        } catch (final LibvirtException e) {
-            s_logger.trace("Ignoring libvirt error.", e);
-        }
-        return false;
-    }
-
-    private String getHypervisorPath(final Connect conn) {
-        final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
-        try {
-            parser.parseCapabilitiesXML(conn.getCapabilities());
-        } catch (final LibvirtException e) {
-            s_logger.debug(e.getMessage());
-        }
-        return parser.getEmulator();
-    }
-
-    boolean isGuestPVEnabled(final String guestOSName) {
-        DiskDef.DiskBus db = getGuestDiskModel(guestOSName);
-        return db != DiskDef.DiskBus.IDE;
-    }
-
-    public boolean isCentosHost() {
-        if (_hvVersion <= 9) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public DiskDef.DiskBus getDiskModelFromVMDetail(final VirtualMachineTO vmTO) {
-        Map<String, String> details = vmTO.getDetails();
-        if (details == null) {
-            return null;
-        }
-
-        final String rootDiskController = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
-        if (StringUtils.isNotBlank(rootDiskController)) {
-            s_logger.debug("Passed custom disk bus " + rootDiskController);
-            for (final DiskDef.DiskBus bus : DiskDef.DiskBus.values()) {
-                if (bus.toString().equalsIgnoreCase(rootDiskController)) {
-                    s_logger.debug("Found matching enum for disk bus " + rootDiskController);
-                    return bus;
-                }
-            }
-        }
-        return null;
-    }
-
-    private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator) {
-        if (platformEmulator == null) {
-            return DiskDef.DiskBus.IDE;
-        } else if (platformEmulator.startsWith("Other PV Virtio-SCSI")) {
-            return DiskDef.DiskBus.SCSI;
-        } else if (platformEmulator.startsWith("Ubuntu") || platformEmulator.startsWith("Fedora 13") || platformEmulator.startsWith("Fedora 12") || platformEmulator.startsWith("Fedora 11") ||
-                platformEmulator.startsWith("Fedora 10") || platformEmulator.startsWith("Fedora 9") || platformEmulator.startsWith("CentOS 5.3") || platformEmulator.startsWith("CentOS 5.4") ||
-                platformEmulator.startsWith("CentOS 5.5") || platformEmulator.startsWith("CentOS") || platformEmulator.startsWith("Fedora") ||
-                platformEmulator.startsWith("Red Hat Enterprise Linux 5.3") || platformEmulator.startsWith("Red Hat Enterprise Linux 5.4") ||
-                platformEmulator.startsWith("Red Hat Enterprise Linux 5.5") || platformEmulator.startsWith("Red Hat Enterprise Linux 6") || platformEmulator.startsWith("Debian GNU/Linux") ||
-                platformEmulator.startsWith("FreeBSD 10") || platformEmulator.startsWith("Oracle") || platformEmulator.startsWith("Other PV")) {
-            return DiskDef.DiskBus.VIRTIO;
-        } else {
-            return DiskDef.DiskBus.IDE;
-        }
-
-    }
-    private void cleanupVMNetworks(final Connect conn, final List<InterfaceDef> nics) {
-        if (nics != null) {
-            for (final InterfaceDef nic : nics) {
-                for (final VifDriver vifDriver : getAllVifDrivers()) {
-                    vifDriver.unplug(nic);
-                }
-            }
-        }
-    }
-
-    public Domain getDomain(final Connect conn, final String vmName) throws LibvirtException {
-        return conn.domainLookupByName(vmName);
-    }
-
-    public List<InterfaceDef> getInterfaces(final Connect conn, final String vmName) {
-        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            parser.parseDomainXML(dm.getXMLDesc(0));
-            return parser.getInterfaces();
-
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to get dom xml: " + e.toString());
-            return new ArrayList<InterfaceDef>();
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (final LibvirtException e) {
-                s_logger.trace("Ignoring libvirt error.", e);
-            }
-        }
-    }
-
-    public List<DiskDef> getDisks(final Connect conn, final String vmName) {
-        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-            parser.parseDomainXML(dm.getXMLDesc(0));
-            return parser.getDisks();
-
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to get dom xml: " + e.toString());
-            return new ArrayList<DiskDef>();
-        } finally {
-            try {
-                if (dm != null) {
-                    dm.free();
-                }
-            } catch (final LibvirtException e) {
-                s_logger.trace("Ignoring libvirt error.", e);
-            }
-        }
-    }
-
-    private String executeBashScript(final String script) {
-        final Script command = new Script("/bin/bash", _timeout, s_logger);
-        command.add("-c");
-        command.add(script);
-        return command.execute();
-    }
-
-    public List<VmNetworkStatsEntry> getVmNetworkStat(Connect conn, String vmName) throws LibvirtException {
-        Domain dm = null;
-        try {
-            dm = getDomain(conn, vmName);
-
-            List<VmNetworkStatsEntry> stats = new ArrayList<VmNetworkStatsEntry>();
-
-            List<InterfaceDef> nics = getInterfaces(conn, vmName);
-
-            for (InterfaceDef nic : nics) {
-                DomainInterfaceStats nicStats = dm.interfaceStats(nic.getDevName());
-                String macAddress = nic.getMacAddress();
-                VmNetworkStatsEntry stat = new VmNetworkStatsEntry(vmName, macAddress, nicStats.tx_bytes, nicStats.rx_bytes);
-                stats.add(stat);
-            }
-
-            return stats;
-        } finally {
-            if (dm != null) {
-                dm.free();
-            }
-        }
-    }
-
-    public List<VmDiskStatsEntry> getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException {
-        Domain dm = null;
-        try {
-            dm = getDomain(conn, vmName);
-
-            final List<VmDiskStatsEntry> stats = new ArrayList<VmDiskStatsEntry>();
-
-            final List<DiskDef> disks = getDisks(conn, vmName);
-
-            for (final DiskDef disk : disks) {
-                if (disk.getDeviceType() != DeviceType.DISK) {
-                    break;
-                }
-                final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel());
-                final String path = disk.getDiskPath(); // for example, path = /mnt/pool_uuid/disk_path/
-                String diskPath = null;
-                if (path != null) {
-                    final String[] token = path.split("/");
-                    if (token.length > 3) {
-                        diskPath = token[3];
-                        final VmDiskStatsEntry stat = new VmDiskStatsEntry(vmName, diskPath, blockStats.wr_req, blockStats.rd_req, blockStats.wr_bytes, blockStats.rd_bytes);
-                        stats.add(stat);
-                    }
-                }
-            }
-
-            return stats;
-        } finally {
-            if (dm != null) {
-                dm.free();
-            }
-        }
-    }
-
-    private class VmStats {
-        long _usedTime;
-        long _tx;
-        long _rx;
-        long _ioRead;
-        long _ioWrote;
-        long _bytesRead;
-        long _bytesWrote;
-        Calendar _timestamp;
-    }
-
-    public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws LibvirtException {
-        Domain dm = null;
-        try {
-            dm = getDomain(conn, vmName);
-            if (dm == null) {
-                return null;
-            }
-            DomainInfo info = dm.getInfo();
-            final VmStatsEntry stats = new VmStatsEntry();
-
-            stats.setNumCPUs(info.nrVirtCpu);
-            stats.setEntityType("vm");
-
-            stats.setMemoryKBs(info.maxMem);
-            stats.setTargetMemoryKBs(info.memory);
-            stats.setIntFreeMemoryKBs(getMemoryFreeInKBs(dm));
-
-            /* get cpu utilization */
-            VmStats oldStats = null;
-
-            final Calendar now = Calendar.getInstance();
-
-            oldStats = _vmStats.get(vmName);
-
-            long elapsedTime = 0;
-            if (oldStats != null) {
-                elapsedTime = now.getTimeInMillis() - oldStats._timestamp.getTimeInMillis();
-                double utilization = (info.cpuTime - oldStats._usedTime) / ((double)elapsedTime * 1000000);
-
-                final NodeInfo node = conn.nodeInfo();
-                utilization = utilization / node.cpus;
-                if (utilization > 0) {
-                    stats.setCPUUtilization(utilization * 100);
-                }
-            }
-
-            /* get network stats */
-
-            final List<InterfaceDef> vifs = getInterfaces(conn, vmName);
-            long rx = 0;
-            long tx = 0;
-            for (final InterfaceDef vif : vifs) {
-                final DomainInterfaceStats ifStats = dm.interfaceStats(vif.getDevName());
-                rx += ifStats.rx_bytes;
-                tx += ifStats.tx_bytes;
-            }
-
-            if (oldStats != null) {
-                final double deltarx = rx - oldStats._rx;
-                if (deltarx > 0) {
-                    stats.setNetworkReadKBs(deltarx / 1024);
-                }
-                final double deltatx = tx - oldStats._tx;
-                if (deltatx > 0) {
-                    stats.setNetworkWriteKBs(deltatx / 1024);
-                }
-            }
-
-            /* get disk stats */
-            final List<DiskDef> disks = getDisks(conn, vmName);
-            long io_rd = 0;
-            long io_wr = 0;
-            long bytes_rd = 0;
-            long bytes_wr = 0;
-            for (final DiskDef disk : disks) {
-                if (disk.getDeviceType() == DeviceType.CDROM || disk.getDeviceType() == DeviceType.FLOPPY) {
-                    continue;
-                }
-                final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel());
-                io_rd += blockStats.rd_req;
-                io_wr += blockStats.wr_req;
-                bytes_rd += blockStats.rd_bytes;
-                bytes_wr += blockStats.wr_bytes;
-            }
-
-            if (oldStats != null) {
-                final long deltaiord = io_rd - oldStats._ioRead;
-                if (deltaiord > 0) {
-                    stats.setDiskReadIOs(deltaiord);
-                }
-                final long deltaiowr = io_wr - oldStats._ioWrote;
-                if (deltaiowr > 0) {
-                    stats.setDiskWriteIOs(deltaiowr);
-                }
-                final double deltabytesrd = bytes_rd - oldStats._bytesRead;
-                if (deltabytesrd > 0) {
-                    stats.setDiskReadKBs(deltabytesrd / 1024);
-                }
-                final double deltabyteswr = bytes_wr - oldStats._bytesWrote;
-                if (deltabyteswr > 0) {
-                    stats.setDiskWriteKBs(deltabyteswr / 1024);
-                }
-            }
-
-            /* save to Hashmap */
-            final VmStats newStat = new VmStats();
-            newStat._usedTime = info.cpuTime;
-            newStat._rx = rx;
-            newStat._tx = tx;
-            newStat._ioRead = io_rd;
-            newStat._ioWrote = io_wr;
-            newStat._bytesRead = bytes_rd;
-            newStat._bytesWrote = bytes_wr;
-            newStat._timestamp = now;
-            _vmStats.put(vmName, newStat);
-            return stats;
-        } finally {
-            if (dm != null) {
-                dm.free();
-            }
-        }
-    }
-
-    /**
-    * This method retrieves the memory statistics from the domain given as parameters.
-    * If no memory statistic is found, it will return {@link NumberUtils#LONG_ZERO} as the value of free memory in the domain.
-    * If it can retrieve the domain memory statistics, it will return the free memory statistic; that means, it returns the value at the first position of the array returned by {@link Domain#memoryStats(int)}.
-    *
-    * @return the amount of free memory in KBs
-    */
-    protected long getMemoryFreeInKBs(Domain dm) throws LibvirtException {
-        MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS);
-        if (ArrayUtils.isEmpty(mems)) {
-            return NumberUtils.LONG_ZERO;
-        }
-        return mems[0].getValue();
-    }
-
-    private boolean canBridgeFirewall(final String prvNic) {
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("can_bridge_firewall");
-        cmd.add(prvNic);
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean destroyNetworkRulesForVM(final Connect conn, final String vmName) {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-        String vif = null;
-        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
-        if (intfs.size() > 0) {
-            final InterfaceDef intf = intfs.get(0);
-            vif = intf.getDevName();
-        }
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("destroy_network_rules_for_vm");
-        cmd.add("--vmname", vmName);
-        if (vif != null) {
-            cmd.add("--vif", vif);
-        }
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean defaultNetworkRules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final String secIpStr) {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-
-        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
-        if (intfs.size() == 0 || intfs.size() < nic.getDeviceId()) {
-            return false;
-        }
-
-        final InterfaceDef intf = intfs.get(nic.getDeviceId());
-        final String brname = intf.getBrName();
-        final String vif = intf.getDevName();
-
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("default_network_rules");
-        cmd.add("--vmname", vmName);
-        cmd.add("--vmid", vmId.toString());
-        if (nic.getIp() != null) {
-            cmd.add("--vmip", nic.getIp());
-        }
-        if (nic.getIp6Address() != null) {
-            cmd.add("--vmip6", nic.getIp6Address());
-        }
-        cmd.add("--vmmac", nic.getMac());
-        cmd.add("--vif", vif);
-        cmd.add("--brname", brname);
-        cmd.add("--nicsecips", secIpStr);
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    protected boolean post_default_network_rules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final InetAddress dhcpServerIp, final String hostIp, final String hostMacAddr) {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-
-        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
-        if (intfs.size() < nic.getDeviceId()) {
-            return false;
-        }
-
-        final InterfaceDef intf = intfs.get(nic.getDeviceId());
-        final String brname = intf.getBrName();
-        final String vif = intf.getDevName();
-
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("post_default_network_rules");
-        cmd.add("--vmname", vmName);
-        cmd.add("--vmid", vmId.toString());
-        cmd.add("--vmip", nic.getIp());
-        cmd.add("--vmmac", nic.getMac());
-        cmd.add("--vif", vif);
-        cmd.add("--brname", brname);
-        if (dhcpServerIp != null) {
-            cmd.add("--dhcpSvr", dhcpServerIp.getHostAddress());
-        }
-
-        cmd.add("--hostIp", hostIp);
-        cmd.add("--hostMacAddr", hostMacAddr);
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean configureDefaultNetworkRulesForSystemVm(final Connect conn, final String vmName) {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("default_network_rules_systemvm");
-        cmd.add("--vmname", vmName);
-        cmd.add("--localbrname", _linkLocalBridgeName);
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean addNetworkRules(final String vmName, final String vmId, final String guestIP, final String guestIP6, final String sig, final String seq, final String mac, final String rules, final String vif, final String brname,
-            final String secIps) {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-
-        final String newRules = rules.replace(" ", ";");
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("add_network_rules");
-        cmd.add("--vmname", vmName);
-        cmd.add("--vmid", vmId);
-        cmd.add("--vmip", guestIP);
-        if (StringUtils.isNotBlank(guestIP6)) {
-            cmd.add("--vmip6", guestIP6);
-        }
-        cmd.add("--sig", sig);
-        cmd.add("--seq", seq);
-        cmd.add("--vmmac", mac);
-        cmd.add("--vif", vif);
-        cmd.add("--brname", brname);
-        cmd.add("--nicsecips", secIps);
-        if (newRules != null && !newRules.isEmpty()) {
-            cmd.add("--rules", newRules);
-        }
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean configureNetworkRulesVMSecondaryIP(final Connect conn, final String vmName, final String secIp, final String action) {
-
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("network_rules_vmSecondaryIp");
-        cmd.add("--vmname", vmName);
-        cmd.add("--nicsecips", secIp);
-        cmd.add("--action", action);
-
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean cleanupRules() {
-        if (!_canBridgeFirewall) {
-            return false;
-        }
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("cleanup_rules");
-        final String result = cmd.execute();
-        if (result != null) {
-            return false;
-        }
-        return true;
-    }
-
-    public String getRuleLogsForVms() {
-        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
-        cmd.add("get_rule_logs_for_vms");
-        final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
-        final String result = cmd.execute(parser);
-        if (result == null) {
-            return parser.getLine();
-        }
-        return null;
-    }
-
-    private HashMap<String, Pair<Long, Long>> syncNetworkGroups(final long id) {
-        final HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
-
-        final String result = getRuleLogsForVms();
-        s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result);
-        final String[] rulelogs = result != null ? result.split(";") : new String[0];
-        for (final String rulesforvm : rulelogs) {
-            final String[] log = rulesforvm.split(",");
-            if (log.length != 6) {
-                continue;
-            }
-            try {
-                states.put(log[0], new Pair<Long, Long>(Long.parseLong(log[1]), Long.parseLong(log[5])));
-            } catch (final NumberFormatException nfe) {
-                states.put(log[0], new Pair<Long, Long>(-1L, -1L));
-            }
-        }
-        return states;
-    }
-
-    /* online snapshot supported by enhanced qemu-kvm */
-    private boolean isSnapshotSupported() {
-        final String result = executeBashScript("qemu-img --help|grep convert");
-        if (result != null) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    public Pair<Double, Double> getNicStats(final String nicName) {
-        return new Pair<Double, Double>(readDouble(nicName, "rx_bytes"), readDouble(nicName, "tx_bytes"));
-    }
-
-    static double readDouble(final String nicName, final String fileName) {
-        final String path = "/sys/class/net/" + nicName + "/statistics/" + fileName;
-        try {
-            return Double.parseDouble(FileUtils.readFileToString(new File(path)));
-        } catch (final IOException ioe) {
-            s_logger.warn("Failed to read the " + fileName + " for " + nicName + " from " + path, ioe);
-            return 0.0;
-        }
-    }
-
-    private String prettyVersion(final long version) {
-        final long major = version / 1000000;
-        final long minor = version % 1000000 / 1000;
-        final long release = version % 1000000 % 1000;
-        return major + "." + minor + "." + release;
-    }
-
-    @Override
-    public void setName(final String name) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setConfigParams(final Map<String, Object> params) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getRunLevel() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(final int level) {
-        // TODO Auto-generated method stub
-    }
-
-    public HypervisorType getHypervisorType(){
-        return _hypervisorType;
-    }
-
-    public String mapRbdDevice(final KVMPhysicalDisk disk){
-        final KVMStoragePool pool = disk.getPool();
-        //Check if rbd image is already mapped
-        final String[] splitPoolImage = disk.getPath().split("/");
-        String device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
-        if(device == null) {
-            //If not mapped, map and return mapped device
-            Script.runSimpleBashScript("rbd map " + disk.getPath() + " --id " + pool.getAuthUserName());
-            device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
-        }
-        return device;
-    }
-
-    public List<Ternary<String, Boolean, String>> cleanVMSnapshotMetadata(Domain dm) throws LibvirtException {
-        s_logger.debug("Cleaning the metadata of vm snapshots of vm " + dm.getName());
-        List<Ternary<String, Boolean, String>> vmsnapshots = new ArrayList<Ternary<String, Boolean, String>>();
-        if (dm.snapshotNum() == 0) {
-            return vmsnapshots;
-        }
-        String currentSnapshotName = null;
-        try {
-            DomainSnapshot snapshotCurrent = dm.snapshotCurrent();
-            String snapshotXML = snapshotCurrent.getXMLDesc();
-            snapshotCurrent.free();
-            DocumentBuilder builder;
-            try {
-                builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-
-                InputSource is = new InputSource();
-                is.setCharacterStream(new StringReader(snapshotXML));
-                Document doc = builder.parse(is);
-                Element rootElement = doc.getDocumentElement();
-
-                currentSnapshotName = getTagValue("name", rootElement);
-            } catch (ParserConfigurationException e) {
-                s_logger.debug(e.toString());
-            } catch (SAXException e) {
-                s_logger.debug(e.toString());
-            } catch (IOException e) {
-                s_logger.debug(e.toString());
-            }
-        } catch (LibvirtException e) {
-            s_logger.debug("Fail to get the current vm snapshot for vm: " + dm.getName() + ", continue");
-        }
-        int flags = 2; // VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY = 2
-        String[] snapshotNames = dm.snapshotListNames();
-        Arrays.sort(snapshotNames);
-        for (String snapshotName: snapshotNames) {
-            DomainSnapshot snapshot = dm.snapshotLookupByName(snapshotName);
-            Boolean isCurrent = (currentSnapshotName != null && currentSnapshotName.equals(snapshotName)) ? true: false;
-            vmsnapshots.add(new Ternary<String, Boolean, String>(snapshotName, isCurrent, snapshot.getXMLDesc()));
-        }
-        for (String snapshotName: snapshotNames) {
-            DomainSnapshot snapshot = dm.snapshotLookupByName(snapshotName);
-            snapshot.delete(flags); // clean metadata of vm snapshot
-        }
-        return vmsnapshots;
-    }
-
-    private static String getTagValue(String tag, Element eElement) {
-        NodeList nlList = eElement.getElementsByTagName(tag).item(0).getChildNodes();
-        Node nValue = nlList.item(0);
-
-        return nValue.getNodeValue();
-    }
-
-    public void restoreVMSnapshotMetadata(Domain dm, String vmName, List<Ternary<String, Boolean, String>> vmsnapshots) {
-        s_logger.debug("Restoring the metadata of vm snapshots of vm " + vmName);
-        for (Ternary<String, Boolean, String> vmsnapshot: vmsnapshots) {
-            String snapshotName = vmsnapshot.first();
-            Boolean isCurrent = vmsnapshot.second();
-            String snapshotXML = vmsnapshot.third();
-            s_logger.debug("Restoring vm snapshot " + snapshotName + " on " + vmName + " with XML:\n " + snapshotXML);
-            try {
-                int flags = 1; // VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE = 1
-                if (isCurrent) {
-                    flags += 2; // VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT = 2
-                }
-                dm.snapshotCreateXML(snapshotXML, flags);
-            } catch (LibvirtException e) {
-                s_logger.debug("Failed to restore vm snapshot " + snapshotName + ", continue");
-                continue;
-            }
-        }
-    }
-
-    public long getTotalMemory() {
-        return _totalMemory;
-    }
-
-    public String getHostDistro() {
-        return _hostDistro;
-    }
-
-    public boolean isHostSecured() {
-        // Test for host certificates
-        final File confFile = PropertiesUtil.findConfigFile(KeyStoreUtils.AGENT_PROPSFILE);
-        if (confFile == null || !confFile.exists() || !new File(confFile.getParent() + "/" + KeyStoreUtils.CERT_FILENAME).exists()) {
-            return false;
-        }
-
-        // Test for libvirt TLS configuration
-        try {
-            new Connect(String.format("qemu+tls://%s/system", _privateIp));
-        } catch (final LibvirtException ignored) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
deleted file mode 100644
index 2eeff88..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
+++ /dev/null
@@ -1,332 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import com.google.common.base.Strings;
-
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.NicModel;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
-
-public class LibvirtDomainXMLParser {
-    private static final Logger s_logger = Logger.getLogger(LibvirtDomainXMLParser.class);
-    private final List<InterfaceDef> interfaces = new ArrayList<InterfaceDef>();
-    private final List<DiskDef> diskDefs = new ArrayList<DiskDef>();
-    private final List<RngDef> rngDefs = new ArrayList<RngDef>();
-    private final List<ChannelDef> channels = new ArrayList<ChannelDef>();
-    private final List<WatchDogDef> watchDogDefs = new ArrayList<WatchDogDef>();
-    private Integer vncPort;
-    private String desc;
-
-    public boolean parseDomainXML(String domXML) {
-        DocumentBuilder builder;
-        try {
-            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-
-            InputSource is = new InputSource();
-            is.setCharacterStream(new StringReader(domXML));
-            Document doc = builder.parse(is);
-
-            Element rootElement = doc.getDocumentElement();
-
-            desc = getTagValue("description", rootElement);
-
-            Element devices = (Element)rootElement.getElementsByTagName("devices").item(0);
-            NodeList disks = devices.getElementsByTagName("disk");
-            for (int i = 0; i < disks.getLength(); i++) {
-                Element disk = (Element)disks.item(i);
-                String type = disk.getAttribute("type");
-                DiskDef def = new DiskDef();
-                if (type.equalsIgnoreCase("network")) {
-                    String diskFmtType = getAttrValue("driver", "type", disk);
-                    String diskCacheMode = getAttrValue("driver", "cache", disk);
-                    String diskPath = getAttrValue("source", "name", disk);
-                    String protocol = getAttrValue("source", "protocol", disk);
-                    String authUserName = getAttrValue("auth", "username", disk);
-                    String poolUuid = getAttrValue("secret", "uuid", disk);
-                    String host = getAttrValue("host", "name", disk);
-                    int port = Integer.parseInt(getAttrValue("host", "port", disk));
-                    String diskLabel = getAttrValue("target", "dev", disk);
-                    String bus = getAttrValue("target", "bus", disk);
-
-                    DiskDef.DiskFmtType fmt = null;
-                    if (diskFmtType != null) {
-                        fmt = DiskDef.DiskFmtType.valueOf(diskFmtType.toUpperCase());
-                    }
-
-                    def.defNetworkBasedDisk(diskPath, host, port, authUserName, poolUuid, diskLabel,
-                        DiskDef.DiskBus.valueOf(bus.toUpperCase()),
-                        DiskDef.DiskProtocol.valueOf(protocol.toUpperCase()), fmt);
-                    def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
-                } else {
-                    String diskFmtType = getAttrValue("driver", "type", disk);
-                    String diskCacheMode = getAttrValue("driver", "cache", disk);
-                    String diskFile = getAttrValue("source", "file", disk);
-                    String diskDev = getAttrValue("source", "dev", disk);
-
-                    String diskLabel = getAttrValue("target", "dev", disk);
-                    String bus = getAttrValue("target", "bus", disk);
-                    String device = disk.getAttribute("device");
-
-                    if (type.equalsIgnoreCase("file")) {
-                        if (device.equalsIgnoreCase("disk")) {
-                            DiskDef.DiskFmtType fmt = null;
-                            if (diskFmtType != null) {
-                                fmt = DiskDef.DiskFmtType.valueOf(diskFmtType.toUpperCase());
-                            }
-                            def.defFileBasedDisk(diskFile, diskLabel, DiskDef.DiskBus.valueOf(bus.toUpperCase()), fmt);
-                        } else if (device.equalsIgnoreCase("cdrom")) {
-                            def.defISODisk(diskFile , i+1);
-                        }
-                    } else if (type.equalsIgnoreCase("block")) {
-                        def.defBlockBasedDisk(diskDev, diskLabel,
-                            DiskDef.DiskBus.valueOf(bus.toUpperCase()));
-                    }
-                    if (StringUtils.isNotBlank(diskCacheMode)) {
-                        def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
-                    }
-                }
-
-                NodeList iotune = disk.getElementsByTagName("iotune");
-                if ((iotune != null) && (iotune.getLength() != 0)) {
-                    String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0));
-                    if (bytesReadRateStr != null) {
-                        Long bytesReadRate = Long.parseLong(bytesReadRateStr);
-                        def.setBytesReadRate(bytesReadRate);
-                    }
-                    String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0));
-                    if (bytesWriteRateStr != null) {
-                        Long bytesWriteRate = Long.parseLong(bytesWriteRateStr);
-                        def.setBytesWriteRate(bytesWriteRate);
-                    }
-                    String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0));
-                    if (iopsReadRateStr != null) {
-                        Long iopsReadRate = Long.parseLong(iopsReadRateStr);
-                        def.setIopsReadRate(iopsReadRate);
-                    }
-                    String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0));
-                    if (iopsWriteRateStr != null) {
-                        Long iopsWriteRate = Long.parseLong(iopsWriteRateStr);
-                        def.setIopsWriteRate(iopsWriteRate);
-                    }
-                }
-
-                diskDefs.add(def);
-            }
-
-            NodeList nics = devices.getElementsByTagName("interface");
-            for (int i = 0; i < nics.getLength(); i++) {
-                Element nic = (Element)nics.item(i);
-
-                String type = nic.getAttribute("type");
-                String mac = getAttrValue("mac", "address", nic);
-                String dev = getAttrValue("target", "dev", nic);
-                String model = getAttrValue("model", "type", nic);
-                String slot = StringUtils.removeStart(getAttrValue("address", "slot", nic), "0x");
-
-                InterfaceDef def = new InterfaceDef();
-                NodeList bandwidth = nic.getElementsByTagName("bandwidth");
-                Integer networkRateKBps = 0;
-                if ((bandwidth != null) && (bandwidth.getLength() != 0)) {
-                    Integer inbound = Integer.valueOf(getAttrValue("inbound", "average", (Element)bandwidth.item(0)));
-                    Integer outbound = Integer.valueOf(getAttrValue("outbound", "average", (Element)bandwidth.item(0)));
-                    if (inbound.equals(outbound)) {
-                        networkRateKBps = inbound;
-                    }
-                }
-                if (type.equalsIgnoreCase("network")) {
-                    String network = getAttrValue("source", "network", nic);
-                    def.defPrivateNet(network, dev, mac, NicModel.valueOf(model.toUpperCase()), networkRateKBps);
-                } else if (type.equalsIgnoreCase("bridge")) {
-                    String bridge = getAttrValue("source", "bridge", nic);
-                    def.defBridgeNet(bridge, dev, mac, NicModel.valueOf(model.toUpperCase()), networkRateKBps);
-                } else if (type.equalsIgnoreCase("ethernet")) {
-                    String scriptPath = getAttrValue("script", "path", nic);
-                    def.defEthernet(dev, mac, NicModel.valueOf(model.toUpperCase()), scriptPath, networkRateKBps);
-                }
-
-                if (StringUtils.isNotBlank(slot)) {
-                    def.setSlot(Integer.parseInt(slot, 16));
-                }
-
-                interfaces.add(def);
-            }
-
-            NodeList ports = devices.getElementsByTagName("channel");
-            for (int i = 0; i < ports.getLength(); i++) {
-                Element channel = (Element)ports.item(i);
-
-                String type = channel.getAttribute("type");
-                String path = getAttrValue("source", "path", channel);
-                String name = getAttrValue("target", "name", channel);
-                String state = getAttrValue("target", "state", channel);
-
-                ChannelDef def = null;
-                if (!StringUtils.isNotBlank(state)) {
-                    def = new ChannelDef(name, ChannelDef.ChannelType.valueOf(type.toUpperCase()), new File(path));
-                } else {
-                    def = new ChannelDef(name, ChannelDef.ChannelType.valueOf(type.toUpperCase()),
-                            ChannelDef.ChannelState.valueOf(state.toUpperCase()), new File(path));
-                }
-
-                channels.add(def);
-            }
-
-            Element graphic = (Element)devices.getElementsByTagName("graphics").item(0);
-
-            if (graphic != null) {
-                String port = graphic.getAttribute("port");
-                if (port != null) {
-                    try {
-                        vncPort = Integer.parseInt(port);
-                        if (vncPort != -1) {
-                            vncPort = vncPort - 5900;
-                        } else {
-                            vncPort = null;
-                        }
-                    } catch (NumberFormatException nfe) {
-                        vncPort = null;
-                    }
-                }
-            }
-
-            NodeList rngs = devices.getElementsByTagName("rng");
-            for (int i = 0; i < rngs.getLength(); i++) {
-                RngDef def = null;
-                Element rng = (Element)rngs.item(i);
-                String backendModel = getAttrValue("backend", "model", rng);
-                String path = getTagValue("backend", rng);
-                String bytes = getAttrValue("rate", "bytes", rng);
-                String period = getAttrValue("rate", "period", rng);
-
-                if (Strings.isNullOrEmpty(backendModel)) {
-                    def = new RngDef(path, Integer.parseInt(bytes), Integer.parseInt(period));
-                } else {
-                    def = new RngDef(path, RngBackendModel.valueOf(backendModel.toUpperCase()),
-                                     Integer.parseInt(bytes), Integer.parseInt(period));
-                }
-
-                rngDefs.add(def);
-            }
-
-            NodeList watchDogs = devices.getElementsByTagName("watchdog");
-            for (int i = 0; i < watchDogs.getLength(); i++) {
-                WatchDogDef def = null;
-                Element watchDog = (Element)watchDogs.item(i);
-                String action = watchDog.getAttribute("action");
-                String model = watchDog.getAttribute("model");
-
-                if (Strings.isNullOrEmpty(model)) {
-                   continue;
-                }
-
-                if (Strings.isNullOrEmpty(action)) {
-                    def = new WatchDogDef(WatchDogModel.valueOf(model.toUpperCase()));
-                } else {
-                    def = new WatchDogDef(WatchDogAction.valueOf(action.toUpperCase()),
-                                          WatchDogModel.valueOf(model.toUpperCase()));
-                }
-
-                watchDogDefs.add(def);
-            }
-
-            return true;
-        } catch (ParserConfigurationException e) {
-            s_logger.debug(e.toString());
-        } catch (SAXException e) {
-            s_logger.debug(e.toString());
-        } catch (IOException e) {
-            s_logger.debug(e.toString());
-        }
-        return false;
-    }
-
-    private static String getTagValue(String tag, Element eElement) {
-        NodeList tagNodeList = eElement.getElementsByTagName(tag);
-        if (tagNodeList == null || tagNodeList.getLength() == 0) {
-            return null;
-        }
-
-        NodeList nlList = tagNodeList.item(0).getChildNodes();
-
-        Node nValue = nlList.item(0);
-
-        return nValue.getNodeValue();
-    }
-
-    private static String getAttrValue(String tag, String attr, Element eElement) {
-        NodeList tagNode = eElement.getElementsByTagName(tag);
-        if (tagNode.getLength() == 0) {
-            return null;
-        }
-        Element node = (Element)tagNode.item(0);
-        return node.getAttribute(attr);
-    }
-
-    public Integer getVncPort() {
-        return vncPort;
-    }
-
-    public List<InterfaceDef> getInterfaces() {
-        return interfaces;
-    }
-
-    public List<DiskDef> getDisks() {
-        return diskDefs;
-    }
-
-    public List<RngDef> getRngs() {
-        return rngDefs;
-    }
-
-    public List<ChannelDef> getChannels() {
-        return Collections.unmodifiableList(channels);
-    }
-
-    public List<WatchDogDef> getWatchDogs() {
-        return watchDogDefs;
-    }
-
-    public String getDescription() {
-        return desc;
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
deleted file mode 100644
index 08ece9a..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
+++ /dev/null
@@ -1,1837 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.log4j.Logger;
-
-import com.google.common.collect.Maps;
-
-public class LibvirtVMDef {
-    private static final Logger s_logger = Logger.getLogger(LibvirtVMDef.class);
-
-    private String _hvsType;
-    private static long s_libvirtVersion;
-    private static long s_qemuVersion;
-    private String _domName;
-    private String _domUUID;
-    private String _desc;
-    private String _platformEmulator;
-    private final Map<String, Object> components = new HashMap<String, Object>();
-
-    public static class GuestDef {
-        enum GuestType {
-            KVM, XEN, EXE, LXC
-        }
-
-        enum BootOrder {
-            HARDISK("hd"), CDROM("cdrom"), FLOPPY("fd"), NETWORK("network");
-            String _order;
-
-            BootOrder(String order) {
-                _order = order;
-            }
-
-            @Override
-            public String toString() {
-                return _order;
-            }
-        }
-
-        private GuestType _type;
-        private String _arch;
-        private String _loader;
-        private String _kernel;
-        private String _initrd;
-        private String _root;
-        private String _cmdline;
-        private String _uuid;
-        private final List<BootOrder> _bootdevs = new ArrayList<BootOrder>();
-        private String _machine;
-
-        public void setGuestType(GuestType type) {
-            _type = type;
-        }
-
-        public GuestType getGuestType() {
-            return _type;
-        }
-
-        public void setGuestArch(String arch) {
-            _arch = arch;
-        }
-
-        public void setMachineType(String machine) {
-            _machine = machine;
-        }
-
-        public void setLoader(String loader) {
-            _loader = loader;
-        }
-
-        public void setBootKernel(String kernel, String initrd, String rootdev, String cmdline) {
-            _kernel = kernel;
-            _initrd = initrd;
-            _root = rootdev;
-            _cmdline = cmdline;
-        }
-
-        public void setBootOrder(BootOrder order) {
-            _bootdevs.add(order);
-        }
-
-        public void setUuid(String uuid) {
-            _uuid = uuid;
-        }
-
-        @Override
-        public String toString() {
-            if (_type == GuestType.KVM) {
-                StringBuilder guestDef = new StringBuilder();
-
-                guestDef.append("<sysinfo type='smbios'>\n");
-                guestDef.append("<system>\n");
-                guestDef.append("<entry name='manufacturer'>Apache Software Foundation</entry>\n");
-                guestDef.append("<entry name='product'>CloudStack " + _type.toString() + " Hypervisor</entry>\n");
-                guestDef.append("<entry name='uuid'>" + _uuid + "</entry>\n");
-                guestDef.append("</system>\n");
-                guestDef.append("</sysinfo>\n");
-
-                guestDef.append("<os>\n");
-                guestDef.append("<type ");
-                if (_arch != null) {
-                    guestDef.append(" arch='" + _arch + "'");
-                }
-                if (_machine != null) {
-                    guestDef.append(" machine='" + _machine + "'");
-                }
-                guestDef.append(">hvm</type>\n");
-                if (!_bootdevs.isEmpty()) {
-                    for (BootOrder bo : _bootdevs) {
-                        guestDef.append("<boot dev='" + bo + "'/>\n");
-                    }
-                }
-                guestDef.append("<smbios mode='sysinfo'/>\n");
-                guestDef.append("</os>\n");
-                return guestDef.toString();
-            } else if (_type == GuestType.LXC) {
-                StringBuilder guestDef = new StringBuilder();
-                guestDef.append("<os>\n");
-                guestDef.append("<type>exe</type>\n");
-                guestDef.append("<init>/sbin/init</init>\n");
-                guestDef.append("</os>\n");
-                return guestDef.toString();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    public static class GuestResourceDef {
-        private long _mem;
-        private long _currentMem = -1;
-        private String _memBacking;
-        private int _vcpu = -1;
-        private boolean _memBalloning = false;
-
-        public void setMemorySize(long mem) {
-            _mem = mem;
-        }
-
-        public void setCurrentMem(long currMem) {
-            _currentMem = currMem;
-        }
-
-        public void setMemBacking(String memBacking) {
-            _memBacking = memBacking;
-        }
-
-        public void setVcpuNum(int vcpu) {
-            _vcpu = vcpu;
-        }
-
-        public void setMemBalloning(boolean turnon) {
-            _memBalloning = turnon;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder resBuidler = new StringBuilder();
-            resBuidler.append("<memory>" + _mem + "</memory>\n");
-            if (_currentMem != -1) {
-                resBuidler.append("<currentMemory>" + _currentMem + "</currentMemory>\n");
-            }
-            if (_memBacking != null) {
-                resBuidler.append("<memoryBacking>" + "<" + _memBacking + "/>" + "</memoryBacking>\n");
-            }
-            if (_memBalloning) {
-                resBuidler.append("<devices>\n" + "<memballoon model='virtio'/>\n" + "</devices>\n");
-            } else {
-                resBuidler.append("<devices>\n" + "<memballoon model='none'/>\n" + "</devices>\n");
-            }
-            if (_vcpu != -1) {
-                resBuidler.append("<vcpu>" + _vcpu + "</vcpu>\n");
-            }
-            return resBuidler.toString();
-        }
-    }
-
-    public static class HyperVEnlightenmentFeatureDef {
-        enum Enlight {
-            RELAX("relaxed"),
-            VAPIC("vapic"),
-            SPIN("spinlocks");
-
-            private final String featureName;
-            Enlight(String featureName) { this.featureName = featureName; }
-            String getFeatureName() { return featureName; }
-
-            static boolean isValidFeature(String featureName) {
-                Enlight[] enlights = Enlight.values();
-                for(Enlight e : enlights) {
-                    if(e.getFeatureName().equals(featureName))
-                        return true;
-                }
-                return false;
-            }
-        }
-
-        private final Map<String, String> features = new HashMap<String, String>();
-        private int retries = 4096; // set to sane default
-
-        public void setFeature(String feature, boolean on) {
-            if(on && Enlight.isValidFeature(feature))
-                setFeature(feature);
-        }
-
-        private void setFeature(String feature) {
-            features.put(feature, "on");
-        }
-
-        public void setRetries(int retry) {
-            if(retry>=retries)
-                retries=retry;
-        }
-
-        public int getRetries() {
-            return retries;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder feaBuilder = new StringBuilder();
-            feaBuilder.append("<hyperv>\n");
-            for (Map.Entry<String, String> e : features.entrySet()) {
-                feaBuilder.append("<");
-                feaBuilder.append(e.getKey());
-
-                if(e.getKey().equals("spinlocks"))  feaBuilder.append(" state='" + e.getValue() + "' retries='" + getRetries() + "'");
-                else                                feaBuilder.append(" state='" + e.getValue() + "'");
-
-                feaBuilder.append("/>\n");
-            }
-            feaBuilder.append("</hyperv>\n");
-            return feaBuilder.toString();
-        }
-    }
-
-    public static class FeaturesDef {
-        private final List<String> _features = new ArrayList<String>();
-
-        private HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = null;
-        public void addFeatures(String feature) {
-            _features.add(feature);
-        }
-
-        public void addHyperVFeature(HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef) {
-            this.hyperVEnlightenmentFeatureDef = hyperVEnlightenmentFeatureDef;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder feaBuilder = new StringBuilder();
-            feaBuilder.append("<features>\n");
-            for (String feature : _features) {
-                feaBuilder.append("<" + feature + "/>\n");
-            }
-            if (hyperVEnlightenmentFeatureDef != null) {
-                String hpervF = hyperVEnlightenmentFeatureDef.toString();
-                if (!hpervF.isEmpty()) {
-                    feaBuilder.append(hpervF);
-                }
-            }
-            feaBuilder.append("</features>\n");
-            return feaBuilder.toString();
-        }
-    }
-
-    public static class TermPolicy {
-        private String _reboot;
-        private String _powerOff;
-        private String _crash;
-
-        public TermPolicy() {
-            _reboot = _powerOff = _crash = "destroy";
-        }
-
-        public void setRebootPolicy(String rbPolicy) {
-            _reboot = rbPolicy;
-        }
-
-        public void setPowerOffPolicy(String poPolicy) {
-            _powerOff = poPolicy;
-        }
-
-        public void setCrashPolicy(String crashPolicy) {
-            _crash = crashPolicy;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder term = new StringBuilder();
-            term.append("<on_reboot>" + _reboot + "</on_reboot>\n");
-            term.append("<on_poweroff>" + _powerOff + "</on_poweroff>\n");
-            term.append("<on_crash>" + _powerOff + "</on_crash>\n");
-            return term.toString();
-        }
-    }
-
-    public static class ClockDef {
-        public enum ClockOffset {
-            UTC("utc"), LOCALTIME("localtime"), TIMEZONE("timezone"), VARIABLE("variable");
-
-            private String _offset;
-
-            private ClockOffset(String offset) {
-                _offset = offset;
-            }
-
-            @Override
-            public String toString() {
-                return _offset;
-            }
-        }
-
-        private ClockOffset _offset;
-        private String _timerName;
-        private String _tickPolicy;
-        private String _track;
-        private boolean _noKvmClock = false;
-
-        public ClockDef() {
-            _offset = ClockOffset.UTC;
-        }
-
-        public void setClockOffset(ClockOffset offset) {
-            _offset = offset;
-        }
-
-        public void setTimer(String timerName, String tickPolicy, String track) {
-            _timerName = timerName;
-            _tickPolicy = tickPolicy;
-            _track = track;
-        }
-
-        public void setTimer(String timerName, String tickPolicy, String track, boolean noKvmClock) {
-            _noKvmClock = noKvmClock;
-            setTimer(timerName, tickPolicy, track);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder clockBuilder = new StringBuilder();
-            clockBuilder.append("<clock offset='");
-            clockBuilder.append(_offset.toString());
-            clockBuilder.append("'>\n");
-            if (_timerName != null) {
-                clockBuilder.append("<timer name='");
-                clockBuilder.append(_timerName);
-                clockBuilder.append("' ");
-
-                if (_timerName.equals("kvmclock") && _noKvmClock) {
-                    clockBuilder.append("present='no' />");
-                } else {
-                    if (_tickPolicy != null) {
-                        clockBuilder.append("tickpolicy='");
-                        clockBuilder.append(_tickPolicy);
-                        clockBuilder.append("' ");
-                    }
-
-                    if (_track != null) {
-                        clockBuilder.append("track='");
-                        clockBuilder.append(_track);
-                        clockBuilder.append("' ");
-                    }
-
-                    clockBuilder.append(">\n");
-                    clockBuilder.append("</timer>\n");
-                }
-            }
-            clockBuilder.append("</clock>\n");
-            return clockBuilder.toString();
-        }
-    }
-
-    public static class DevicesDef {
-        private String _emulator;
-        private GuestDef.GuestType _guestType;
-        private final Map<String, List<?>> devices = new HashMap<String, List<?>>();
-
-        public boolean addDevice(Object device) {
-            Object dev = devices.get(device.getClass().toString());
-            if (dev == null) {
-                List<Object> devs = new ArrayList<Object>();
-                devs.add(device);
-                devices.put(device.getClass().toString(), devs);
-            } else {
-                List<Object> devs = (List<Object>)dev;
-                devs.add(device);
-            }
-            return true;
-        }
-
-        public void setEmulatorPath(String emulator) {
-            _emulator = emulator;
-        }
-
-        public void setGuestType(GuestDef.GuestType guestType) {
-            _guestType = guestType;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder devicesBuilder = new StringBuilder();
-            devicesBuilder.append("<devices>\n");
-            if (_emulator != null) {
-                devicesBuilder.append("<emulator>" + _emulator + "</emulator>\n");
-            }
-
-            for (List<?> devs : devices.values()) {
-                for (Object dev : devs) {
-                    if (_guestType == GuestDef.GuestType.LXC) {
-                        if (dev instanceof GraphicDef || dev instanceof InputDef) {
-                            continue;
-                        }
-                        if(dev instanceof DiskDef){
-                            DiskDef disk = (DiskDef)dev;
-                            if(!disk.getDiskType().toString().equals("block")){
-                                continue;
-                            }
-                        }
-                    }
-                    devicesBuilder.append(dev.toString());
-                }
-            }
-            devicesBuilder.append("</devices>\n");
-            return devicesBuilder.toString();
-        }
-
-        @SuppressWarnings("unchecked")
-        public List<DiskDef> getDisks() {
-            return (List<DiskDef>)devices.get(DiskDef.class.toString());
-        }
-
-        @SuppressWarnings("unchecked")
-        public List<InterfaceDef> getInterfaces() {
-            return (List<InterfaceDef>)devices.get(InterfaceDef.class.toString());
-        }
-
-    }
-
-    public static class DiskDef {
-        public enum DeviceType {
-            FLOPPY("floppy"), DISK("disk"), CDROM("cdrom"), LUN("lun");
-            String _type;
-
-            DeviceType(String type) {
-                _type = type;
-            }
-
-            @Override
-            public String toString() {
-                return _type;
-            }
-        }
-
-        enum DiskType {
-            FILE("file"), BLOCK("block"), DIRECTROY("dir"), NETWORK("network");
-            String _diskType;
-
-            DiskType(String type) {
-                _diskType = type;
-            }
-
-            @Override
-            public String toString() {
-                return _diskType;
-            }
-        }
-
-        public enum DiskProtocol {
-            RBD("rbd"), SHEEPDOG("sheepdog"), GLUSTER("gluster");
-            String _diskProtocol;
-
-            DiskProtocol(String protocol) {
-                _diskProtocol = protocol;
-            }
-
-            @Override
-            public String toString() {
-                return _diskProtocol;
-            }
-        }
-
-        public enum DiskBus {
-            IDE("ide"), SCSI("scsi"), VIRTIO("virtio"), XEN("xen"), USB("usb"), UML("uml"), FDC("fdc");
-            String _bus;
-
-            DiskBus(String bus) {
-                _bus = bus;
-            }
-
-            @Override
-            public String toString() {
-                return _bus;
-            }
-        }
-
-        public enum DiskFmtType {
-            RAW("raw"), QCOW2("qcow2");
-            String _fmtType;
-
-            DiskFmtType(String fmt) {
-                _fmtType = fmt;
-            }
-
-            @Override
-            public String toString() {
-                return _fmtType;
-            }
-        }
-
-        public enum DiskCacheMode {
-            NONE("none"), WRITEBACK("writeback"), WRITETHROUGH("writethrough");
-            String _diskCacheMode;
-
-            DiskCacheMode(String cacheMode) {
-                _diskCacheMode = cacheMode;
-            }
-
-            @Override
-            public String toString() {
-                if (_diskCacheMode == null) {
-                    return "NONE";
-                }
-                return _diskCacheMode;
-            }
-        }
-
-        public enum DiscardType {
-            IGNORE("ignore"), UNMAP("unmap");
-            String _discardType;
-            DiscardType(String discardType) {
-                _discardType = discardType;
-            }
-
-            @Override
-            public String toString() {
-                if (_discardType == null) {
-                    return "ignore";
-                }
-                return _discardType;
-            }
-
-        }
-
-        private DeviceType _deviceType; /* floppy, disk, cdrom */
-        private DiskType _diskType;
-        private DiskProtocol _diskProtocol;
-        private String _sourcePath;
-        private String _sourceHost;
-        private int _sourcePort;
-        private String _authUserName;
-        private String _authSecretUUID;
-        private String _diskLabel;
-        private DiskBus _bus;
-        private DiskFmtType _diskFmtType; /* qcow2, raw etc. */
-        private boolean _readonly = false;
-        private boolean _shareable = false;
-        private boolean _deferAttach = false;
-        private Long _bytesReadRate;
-        private Long _bytesWriteRate;
-        private Long _iopsReadRate;
-        private Long _iopsWriteRate;
-        private DiskCacheMode _diskCacheMode;
-        private String _serial;
-        private boolean qemuDriver = true;
-        private DiscardType _discard = DiscardType.IGNORE;
-
-        public DiscardType getDiscard() {
-            return _discard;
-        }
-
-        public void setDiscard(DiscardType discard) {
-            this._discard = discard;
-        }
-
-        public void setDeviceType(DeviceType deviceType) {
-            _deviceType = deviceType;
-        }
-
-        public void defFileBasedDisk(String filePath, String diskLabel, DiskBus bus, DiskFmtType diskFmtType) {
-            _diskType = DiskType.FILE;
-            _deviceType = DeviceType.DISK;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = filePath;
-            _diskLabel = diskLabel;
-            _diskFmtType = diskFmtType;
-            _bus = bus;
-
-        }
-
-        /* skip iso labels */
-        private String getDevLabel(int devId, DiskBus bus, boolean forIso) {
-            if (devId < 0) {
-                return "";
-            }
-
-            if (bus == DiskBus.SCSI) {
-                return "sd" + getDevLabelSuffix(devId);
-            } else if (bus == DiskBus.VIRTIO) {
-                return "vd" + getDevLabelSuffix(devId);
-            }
-            if (forIso) {
-                devId --;
-            } else if(devId >= 2) {
-                devId += 2;
-            }
-            return "hd" + getDevLabelSuffix(devId);
-
-        }
-
-        private String getDevLabelSuffix(int deviceIndex) {
-            if (deviceIndex < 0) {
-                return "";
-            }
-
-            int base = 'z' - 'a' + 1;
-            String labelSuffix = "";
-            do {
-                char suffix = (char)('a' + (deviceIndex % base));
-                labelSuffix = suffix + labelSuffix;
-                deviceIndex = (deviceIndex / base) - 1;
-            } while (deviceIndex >= 0);
-
-            return labelSuffix;
-        }
-
-        public void defFileBasedDisk(String filePath, int devId, DiskBus bus, DiskFmtType diskFmtType) {
-
-            _diskType = DiskType.FILE;
-            _deviceType = DeviceType.DISK;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = filePath;
-            _diskLabel = getDevLabel(devId, bus, false);
-            _diskFmtType = diskFmtType;
-            _bus = bus;
-
-        }
-
-        public void defISODisk(String volPath) {
-            _diskType = DiskType.FILE;
-            _deviceType = DeviceType.CDROM;
-            _sourcePath = volPath;
-            _diskLabel = getDevLabel(3, DiskBus.IDE, true);
-            _diskFmtType = DiskFmtType.RAW;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _bus = DiskBus.IDE;
-        }
-
-        public void defISODisk(String volPath, Integer devId) {
-            if (devId == null) {
-                defISODisk(volPath);
-            } else {
-                _diskType = DiskType.FILE;
-                _deviceType = DeviceType.CDROM;
-                _sourcePath = volPath;
-                _diskLabel = getDevLabel(devId, DiskBus.IDE, true);
-                _diskFmtType = DiskFmtType.RAW;
-                _diskCacheMode = DiskCacheMode.NONE;
-                _bus = DiskBus.IDE;
-            }
-        }
-
-        public void defBlockBasedDisk(String diskName, int devId, DiskBus bus) {
-            _diskType = DiskType.BLOCK;
-            _deviceType = DeviceType.DISK;
-            _diskFmtType = DiskFmtType.RAW;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = diskName;
-            _diskLabel = getDevLabel(devId, bus, false);
-            _bus = bus;
-        }
-
-        public void defBlockBasedDisk(String diskName, String diskLabel, DiskBus bus) {
-            _diskType = DiskType.BLOCK;
-            _deviceType = DeviceType.DISK;
-            _diskFmtType = DiskFmtType.RAW;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = diskName;
-            _diskLabel = diskLabel;
-            _bus = bus;
-        }
-
-        public void defNetworkBasedDisk(String diskName, String sourceHost, int sourcePort, String authUserName, String authSecretUUID, int devId, DiskBus bus,
-                DiskProtocol protocol, DiskFmtType diskFmtType) {
-            _diskType = DiskType.NETWORK;
-            _deviceType = DeviceType.DISK;
-            _diskFmtType = diskFmtType;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = diskName;
-            _sourceHost = sourceHost;
-            _sourcePort = sourcePort;
-            _authUserName = authUserName;
-            _authSecretUUID = authSecretUUID;
-            _diskLabel = getDevLabel(devId, bus, false);
-            _bus = bus;
-            _diskProtocol = protocol;
-        }
-
-        public void defNetworkBasedDisk(String diskName, String sourceHost, int sourcePort, String authUserName, String authSecretUUID, String diskLabel, DiskBus bus,
-                DiskProtocol protocol, DiskFmtType diskFmtType) {
-            _diskType = DiskType.NETWORK;
-            _deviceType = DeviceType.DISK;
-            _diskFmtType = diskFmtType;
-            _diskCacheMode = DiskCacheMode.NONE;
-            _sourcePath = diskName;
-            _sourceHost = sourceHost;
-            _sourcePort = sourcePort;
-            _authUserName = authUserName;
-            _authSecretUUID = authSecretUUID;
-            _diskLabel = diskLabel;
-            _bus = bus;
-            _diskProtocol = protocol;
-        }
-
-        public void setReadonly() {
-            _readonly = true;
-        }
-
-        public void setSharable() {
-            _shareable = true;
-        }
-
-        public void setAttachDeferred(boolean deferAttach) {
-            _deferAttach = deferAttach;
-        }
-
-        public boolean isAttachDeferred() {
-            return _deferAttach;
-        }
-
-        public String getDiskPath() {
-            return _sourcePath;
-        }
-
-        public String getDiskLabel() {
-            return _diskLabel;
-        }
-
-        public DiskType getDiskType() {
-            return _diskType;
-        }
-
-        public DeviceType getDeviceType() {
-            return _deviceType;
-        }
-
-        public void setDiskPath(String volPath) {
-            _sourcePath = volPath;
-        }
-
-        public DiskBus getBusType() {
-            return _bus;
-        }
-
-        public DiskFmtType getDiskFormatType() {
-            return _diskFmtType;
-        }
-
-        public void setBytesReadRate(Long bytesReadRate) {
-            _bytesReadRate = bytesReadRate;
-        }
-
-        public void setBytesWriteRate(Long bytesWriteRate) {
-            _bytesWriteRate = bytesWriteRate;
-        }
-
-        public void setIopsReadRate(Long iopsReadRate) {
-            _iopsReadRate = iopsReadRate;
-        }
-
-        public void setIopsWriteRate(Long iopsWriteRate) {
-            _iopsWriteRate = iopsWriteRate;
-        }
-
-        public void setCacheMode(DiskCacheMode cacheMode) {
-            _diskCacheMode = cacheMode;
-        }
-
-        public DiskCacheMode getCacheMode() {
-            return _diskCacheMode;
-        }
-
-        public void setQemuDriver(boolean qemuDriver){
-            this.qemuDriver = qemuDriver;
-        }
-
-        public void setSerial(String serial) {
-            this._serial = serial;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder diskBuilder = new StringBuilder();
-            diskBuilder.append("<disk ");
-            if (_deviceType != null) {
-                diskBuilder.append(" device='" + _deviceType + "'");
-            }
-            diskBuilder.append(" type='" + _diskType + "'");
-            diskBuilder.append(">\n");
-            if(qemuDriver) {
-                diskBuilder.append("<driver name='qemu'" + " type='" + _diskFmtType + "' ");
-
-                if (_deviceType != DeviceType.CDROM) {
-                    diskBuilder.append("cache='" + _diskCacheMode + "' ");
-                }
-
-                if(_discard != null && _discard != DiscardType.IGNORE) {
-                    diskBuilder.append("discard='" + _discard.toString() + "' ");
-                }
-                diskBuilder.append("/>\n");
-            }
-
-            if (_diskType == DiskType.FILE) {
-                diskBuilder.append("<source ");
-                if (_sourcePath != null) {
-                    diskBuilder.append("file='" + _sourcePath + "'");
-                } else if (_deviceType == DeviceType.CDROM) {
-                    diskBuilder.append("file=''");
-                }
-                diskBuilder.append("/>\n");
-            } else if (_diskType == DiskType.BLOCK) {
-                diskBuilder.append("<source");
-                if (_sourcePath != null) {
-                    diskBuilder.append(" dev='" + _sourcePath + "'");
-                }
-                diskBuilder.append("/>\n");
-            } else if (_diskType == DiskType.NETWORK) {
-                diskBuilder.append("<source ");
-                diskBuilder.append(" protocol='" + _diskProtocol + "'");
-                diskBuilder.append(" name='" + _sourcePath + "'");
-                diskBuilder.append(">\n");
-                diskBuilder.append("<host name='");
-                diskBuilder.append(_sourceHost);
-                if (_sourcePort != 0) {
-                    diskBuilder.append("' port='");
-                    diskBuilder.append(_sourcePort);
-                }
-                diskBuilder.append("'/>\n");
-                diskBuilder.append("</source>\n");
-                if (_authUserName != null) {
-                    diskBuilder.append("<auth username='" + _authUserName + "'>\n");
-                    diskBuilder.append("<secret type='ceph' uuid='" + _authSecretUUID + "'/>\n");
-                    diskBuilder.append("</auth>\n");
-                }
-            }
-            diskBuilder.append("<target dev='" + _diskLabel + "'");
-            if (_bus != null) {
-                diskBuilder.append(" bus='" + _bus + "'");
-            }
-            diskBuilder.append("/>\n");
-
-            if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) {
-                diskBuilder.append("<serial>" + _serial + "</serial>");
-            }
-
-            if ((_deviceType != DeviceType.CDROM) &&
-                    (s_libvirtVersion >= 9008) &&
-                    (s_qemuVersion >= 1001000) &&
-                    (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) ||
-                            ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)))) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0
-                diskBuilder.append("<iotune>\n");
-                if ((_bytesReadRate != null) && (_bytesReadRate > 0))
-                    diskBuilder.append("<read_bytes_sec>" + _bytesReadRate + "</read_bytes_sec>\n");
-                if ((_bytesWriteRate != null) && (_bytesWriteRate > 0))
-                    diskBuilder.append("<write_bytes_sec>" + _bytesWriteRate + "</write_bytes_sec>\n");
-                if ((_iopsReadRate != null) && (_iopsReadRate > 0))
-                    diskBuilder.append("<read_iops_sec>" + _iopsReadRate + "</read_iops_sec>\n");
-                if ((_iopsWriteRate != null) && (_iopsWriteRate > 0))
-                    diskBuilder.append("<write_iops_sec>" + _iopsWriteRate + "</write_iops_sec>\n");
-                diskBuilder.append("</iotune>\n");
-            }
-
-            diskBuilder.append("</disk>\n");
-            return diskBuilder.toString();
-        }
-    }
-
-    public static class InterfaceDef {
-        enum GuestNetType {
-            BRIDGE("bridge"), DIRECT("direct"), NETWORK("network"), USER("user"), ETHERNET("ethernet"), INTERNAL("internal");
-            String _type;
-
-            GuestNetType(String type) {
-                _type = type;
-            }
-
-            @Override
-            public String toString() {
-                return _type;
-            }
-        }
-
-        public enum NicModel {
-            E1000("e1000"), VIRTIO("virtio"), RTL8139("rtl8139"), NE2KPCI("ne2k_pci"), VMXNET3("vmxnet3");
-            String _model;
-
-            NicModel(String model) {
-                _model = model;
-            }
-
-            @Override
-            public String toString() {
-                return _model;
-            }
-        }
-
-        enum HostNicType {
-            DIRECT_ATTACHED_WITHOUT_DHCP, DIRECT_ATTACHED_WITH_DHCP, VNET, VLAN;
-        }
-
-        private GuestNetType _netType; /*
-         * bridge, ethernet, network, user,
-         * internal
-         */
-        private HostNicType _hostNetType; /* Only used by agent java code */
-        private String _netSourceMode;
-        private String _sourceName;
-        private String _networkName;
-        private String _macAddr;
-        private String _ipAddr;
-        private String _scriptPath;
-        private NicModel _model;
-        private Integer _networkRateKBps;
-        private String _virtualPortType;
-        private String _virtualPortInterfaceId;
-        private int _vlanTag = -1;
-        private boolean _pxeDisable = false;
-        private boolean _linkStateUp = true;
-        private Integer _slot;
-
-        public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model) {
-            defBridgeNet(brName, targetBrName, macAddr, model, 0);
-        }
-
-        public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model, Integer networkRateKBps) {
-            _netType = GuestNetType.BRIDGE;
-            _sourceName = brName;
-            _networkName = targetBrName;
-            _macAddr = macAddr;
-            _model = model;
-            _networkRateKBps = networkRateKBps;
-        }
-
-        public void defDirectNet(String sourceName, String targetName, String macAddr, NicModel model, String sourceMode) {
-            defDirectNet(sourceName, targetName, macAddr, model, sourceMode, 0);
-        }
-
-        public void defDirectNet(String sourceName, String targetName, String macAddr, NicModel model, String sourceMode, Integer networkRateKBps) {
-            _netType = GuestNetType.DIRECT;
-            _netSourceMode = sourceMode;
-            _sourceName = sourceName;
-            _networkName = targetName;
-            _macAddr = macAddr;
-            _model = model;
-            _networkRateKBps = networkRateKBps;
-        }
-
-        public void defPrivateNet(String networkName, String targetName, String macAddr, NicModel model) {
-            defPrivateNet(networkName, targetName, macAddr, model, 0);
-        }
-
-        public void defPrivateNet(String networkName, String targetName, String macAddr, NicModel model, Integer networkRateKBps) {
-            _netType = GuestNetType.NETWORK;
-            _sourceName = networkName;
-            _networkName = targetName;
-            _macAddr = macAddr;
-            _model = model;
-            _networkRateKBps = networkRateKBps;
-        }
-
-        public void defEthernet(String targetName, String macAddr, NicModel model, String scriptPath) {
-            defEthernet(targetName, macAddr, model, scriptPath, 0);
-        }
-
-        public void defEthernet(String targetName, String macAddr, NicModel model, String scriptPath, Integer networkRateKBps) {
-            _netType = GuestNetType.ETHERNET;
-            _networkName = targetName;
-            _sourceName = targetName;
-            _macAddr = macAddr;
-            _model = model;
-            _scriptPath = scriptPath;
-            _networkRateKBps = networkRateKBps;
-        }
-
-        public void defEthernet(String targetName, String macAddr, NicModel model) {
-            defEthernet(targetName, macAddr, model, null);
-        }
-
-        public void setHostNetType(HostNicType hostNetType) {
-            _hostNetType = hostNetType;
-        }
-
-        public HostNicType getHostNetType() {
-            return _hostNetType;
-        }
-
-        public void setPxeDisable(boolean pxeDisable) {
-            _pxeDisable = pxeDisable;
-        }
-
-        public String getBrName() {
-            return _sourceName;
-        }
-
-        public GuestNetType getNetType() {
-            return _netType;
-        }
-
-        public String getNetSourceMode() {
-            return _netSourceMode;
-        }
-
-        public String getDevName() {
-            return _networkName;
-        }
-
-        public void setDevName(String networkName) {
-            _networkName = networkName;
-        }
-
-        public String getMacAddress() {
-            return _macAddr;
-        }
-
-        public NicModel getModel() {
-            return _model;
-        }
-
-        public void setVirtualPortType(String virtualPortType) {
-            _virtualPortType = virtualPortType;
-        }
-
-        public String getVirtualPortType() {
-            return _virtualPortType;
-        }
-
-        public void setVirtualPortInterfaceId(String virtualPortInterfaceId) {
-            _virtualPortInterfaceId = virtualPortInterfaceId;
-        }
-
-        public String getVirtualPortInterfaceId() {
-            return _virtualPortInterfaceId;
-        }
-
-        public void setVlanTag(int vlanTag) {
-            _vlanTag = vlanTag;
-        }
-
-        public int getVlanTag() {
-            return _vlanTag;
-        }
-
-        public void setSlot(Integer slot) {
-            _slot = slot;
-        }
-
-        public Integer getSlot() {
-            return _slot;
-        }
-
-        public void setLinkStateUp(boolean linkStateUp) {
-            _linkStateUp = linkStateUp;
-        }
-
-        public boolean isLinkStateUp() {
-            return _linkStateUp;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder netBuilder = new StringBuilder();
-            netBuilder.append("<interface type='" + _netType + "'>\n");
-            if (_netType == GuestNetType.BRIDGE) {
-                netBuilder.append("<source bridge='" + _sourceName + "'/>\n");
-            } else if (_netType == GuestNetType.NETWORK) {
-                netBuilder.append("<source network='" + _sourceName + "'/>\n");
-            } else if (_netType == GuestNetType.DIRECT) {
-                netBuilder.append("<source dev='" + _sourceName + "' mode='" + _netSourceMode + "'/>\n");
-            }
-            if (_networkName != null) {
-                netBuilder.append("<target dev='" + _networkName + "'/>\n");
-            }
-            if (_macAddr != null) {
-                netBuilder.append("<mac address='" + _macAddr + "'/>\n");
-            }
-            if (_model != null) {
-                netBuilder.append("<model type='" + _model + "'/>\n");
-            }
-            if ((s_libvirtVersion >= 9004) && (_networkRateKBps > 0)) { // supported from libvirt 0.9.4
-                netBuilder.append("<bandwidth>\n");
-                netBuilder.append("<inbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
-                netBuilder.append("<outbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
-                netBuilder.append("</bandwidth>\n");
-            }
-            if (_scriptPath != null) {
-                netBuilder.append("<script path='" + _scriptPath + "'/>\n");
-            }
-            if (_pxeDisable) {
-                netBuilder.append("<rom bar='off' file=''/>");
-            }
-            if (_virtualPortType != null) {
-                netBuilder.append("<virtualport type='" + _virtualPortType + "'>\n");
-                if (_virtualPortInterfaceId != null) {
-                    netBuilder.append("<parameters interfaceid='" + _virtualPortInterfaceId + "'/>\n");
-                }
-                netBuilder.append("</virtualport>\n");
-            }
-            if (_vlanTag > 0 && _vlanTag < 4095) {
-                netBuilder.append("<vlan trunk='no'>\n<tag id='" + _vlanTag + "'/>\n</vlan>");
-            }
-
-            netBuilder.append("<link state='" + (_linkStateUp ? "up" : "down") +"'/>\n");
-
-            if (_slot  != null) {
-                netBuilder.append(String.format("<address type='pci' domain='0x0000' bus='0x00' slot='0x%02x' function='0x0'/>\n", _slot));
-            }
-            netBuilder.append("</interface>\n");
-            return netBuilder.toString();
-        }
-    }
-
-    public static class ConsoleDef {
-        private final String _ttyPath;
-        private final String _type;
-        private final String _source;
-        private short _port = -1;
-
-        public ConsoleDef(String type, String path, String source, short port) {
-            _type = type;
-            _ttyPath = path;
-            _source = source;
-            _port = port;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder consoleBuilder = new StringBuilder();
-            consoleBuilder.append("<console ");
-            consoleBuilder.append("type='" + _type + "'");
-            if (_ttyPath != null) {
-                consoleBuilder.append("tty='" + _ttyPath + "'");
-            }
-            consoleBuilder.append(">\n");
-            if (_source != null) {
-                consoleBuilder.append("<source path='" + _source + "'/>\n");
-            }
-            if (_port != -1) {
-                consoleBuilder.append("<target port='" + _port + "'/>\n");
-            }
-            consoleBuilder.append("</console>\n");
-            return consoleBuilder.toString();
-        }
-    }
-
-    public static class CpuTuneDef {
-        private int _shares = 0;
-        private int quota = 0;
-        private int period = 0;
-        static final int DEFAULT_PERIOD = 10000;
-        static final int MIN_QUOTA = 1000;
-        static final int MAX_PERIOD = 1000000;
-
-        public void setShares(int shares) {
-            _shares = shares;
-        }
-
-        public int getShares() {
-            return _shares;
-        }
-
-        public int getQuota() {
-            return quota;
-        }
-
-        public void setQuota(int quota) {
-            this.quota = quota;
-        }
-
-        public int getPeriod() {
-            return period;
-        }
-
-        public void setPeriod(int period) {
-            this.period = period;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder cpuTuneBuilder = new StringBuilder();
-            cpuTuneBuilder.append("<cputune>\n");
-            if (_shares > 0) {
-                cpuTuneBuilder.append("<shares>" + _shares + "</shares>\n");
-            }
-            if (quota > 0) {
-                cpuTuneBuilder.append("<quota>" + quota + "</quota>\n");
-            }
-            if (period > 0) {
-                cpuTuneBuilder.append("<period>" + period + "</period>\n");
-            }
-            cpuTuneBuilder.append("</cputune>\n");
-            return cpuTuneBuilder.toString();
-        }
-    }
-
-    public static class CpuModeDef {
-        private String _mode;
-        private String _model;
-        private List<String> _features;
-        private int _coresPerSocket = -1;
-        private int _sockets = -1;
-
-        public void setMode(String mode) {
-            _mode = mode;
-        }
-
-        public void setFeatures(List<String> features) {
-            if (features != null) {
-                _features = features;
-            }
-        }
-
-        public void setModel(String model) {
-            _model = model;
-        }
-
-        public void setTopology(int coresPerSocket, int sockets) {
-            _coresPerSocket = coresPerSocket;
-            _sockets = sockets;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder modeBuilder = new StringBuilder();
-
-            // start cpu def, adding mode, model
-            if ("custom".equalsIgnoreCase(_mode) && _model != null){
-                modeBuilder.append("<cpu mode='custom' match='exact'><model fallback='allow'>" + _model + "</model>");
-            } else if ("host-model".equals(_mode)) {
-                modeBuilder.append("<cpu mode='host-model'><model fallback='allow'></model>");
-            } else if ("host-passthrough".equals(_mode)) {
-                modeBuilder.append("<cpu mode='host-passthrough'>");
-            } else {
-                modeBuilder.append("<cpu>");
-            }
-
-            if (_features != null) {
-                for (String feature : _features) {
-                    modeBuilder.append("<feature policy='require' name='" + feature + "'/>");
-                }
-            }
-
-            // add topology
-            if (_sockets > 0 && _coresPerSocket > 0) {
-                modeBuilder.append("<topology sockets='" + _sockets + "' cores='" + _coresPerSocket + "' threads='1' />");
-            }
-
-            // close cpu def
-            modeBuilder.append("</cpu>");
-            return modeBuilder.toString();
-        }
-    }
-
-    public static class SerialDef {
-        private final String _type;
-        private final String _source;
-        private short _port = -1;
-
-        public SerialDef(String type, String source, short port) {
-            _type = type;
-            _source = source;
-            _port = port;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder serialBuidler = new StringBuilder();
-            serialBuidler.append("<serial type='" + _type + "'>\n");
-            if (_source != null) {
-                serialBuidler.append("<source path='" + _source + "'/>\n");
-            }
-            if (_port != -1) {
-                serialBuidler.append("<target port='" + _port + "'/>\n");
-            }
-            serialBuidler.append("</serial>\n");
-            return serialBuidler.toString();
-        }
-    }
-
-    public static class VideoDef {
-        private String _videoModel;
-        private int _videoRam;
-
-        public VideoDef(String videoModel, int videoRam) {
-            _videoModel = videoModel;
-            _videoRam = videoRam;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder videoBuilder = new StringBuilder();
-            if (_videoModel != null && !_videoModel.isEmpty() && _videoRam != 0){
-                videoBuilder.append("<video>\n");
-                videoBuilder.append("<model type='" + _videoModel + "' vram='" + _videoRam + "'/>\n");
-                videoBuilder.append("</video>\n");
-                return videoBuilder.toString();
-            }
-            return "";
-        }
-    }
-
-    public final static class ChannelDef {
-        enum ChannelType {
-            UNIX("unix"), SERIAL("serial");
-            String type;
-
-            ChannelType(String type) {
-                this.type = type;
-            }
-
-            @Override
-            public String toString() {
-                return this.type;
-            }
-        }
-
-        enum ChannelState {
-            DISCONNECTED("disconnected"), CONNECTED("connected");
-            String type;
-
-            ChannelState(String type) {
-                this.type = type;
-            }
-
-            @Override
-            public String toString() {
-                return type;
-            }
-        }
-
-        private final String name;
-        private File path = new File("");
-        private final ChannelType type;
-        private ChannelState state;
-
-        public ChannelDef(String name, ChannelType type) {
-            this.name = name;
-            this.type = type;
-        }
-
-        public ChannelDef(String name, ChannelType type, File path) {
-            this.name = name;
-            this.path = path;
-            this.type = type;
-        }
-
-        public ChannelDef(String name, ChannelType type, ChannelState state) {
-            this.name = name;
-            this.state = state;
-            this.type = type;
-        }
-
-        public ChannelDef(String name, ChannelType type, ChannelState state, File path) {
-            this.name = name;
-            this.path = path;
-            this.state = state;
-            this.type = type;
-        }
-
-        public ChannelType getChannelType() {
-            return type;
-        }
-
-        public ChannelState getChannelState() {
-            return state;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public File getPath() {
-            return path;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder virtioSerialBuilder = new StringBuilder();
-            virtioSerialBuilder.append("<channel type='" + type.toString() + "'>\n");
-            if (path == null) {
-                virtioSerialBuilder.append("<source mode='bind'/>\n");
-            } else {
-                virtioSerialBuilder.append("<source mode='bind' path='" + path.toString() + "'/>\n");
-            }
-            virtioSerialBuilder.append("<address type='virtio-serial'/>\n");
-            if (state == null) {
-                virtioSerialBuilder.append("<target type='virtio' name='" + name + "'/>\n");
-            } else {
-                virtioSerialBuilder.append("<target type='virtio' name='" + name + "' state='" + state.toString() + "'/>\n");
-            }
-            virtioSerialBuilder.append("</channel>\n");
-            return virtioSerialBuilder.toString();
-        }
-    }
-
-    public static class GraphicDef {
-        private final String _type;
-        private short _port = -2;
-        private boolean _autoPort = false;
-        private final String _listenAddr;
-        private final String _passwd;
-        private final String _keyMap;
-
-        public GraphicDef(String type, short port, boolean autoPort, String listenAddr, String passwd, String keyMap) {
-            _type = type;
-            _port = port;
-            _autoPort = autoPort;
-            _listenAddr = listenAddr;
-            _passwd = StringEscapeUtils.escapeXml(passwd);
-            _keyMap = keyMap;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder graphicBuilder = new StringBuilder();
-            graphicBuilder.append("<graphics type='" + _type + "'");
-            if (_autoPort) {
-                graphicBuilder.append(" autoport='yes'");
-            } else if (_port != -2) {
-                graphicBuilder.append(" port='" + _port + "'");
-            }
-            if (_listenAddr != null) {
-                graphicBuilder.append(" listen='" + _listenAddr + "'");
-            } else {
-                graphicBuilder.append(" listen=''");
-            }
-            if (_passwd != null) {
-                graphicBuilder.append(" passwd='" + _passwd + "'");
-            } else if (_keyMap != null) {
-                graphicBuilder.append(" _keymap='" + _keyMap + "'");
-            }
-            graphicBuilder.append("/>\n");
-            return graphicBuilder.toString();
-        }
-    }
-
-    public static class SCSIDef {
-        private short index = 0;
-        private int domain = 0;
-        private int bus = 0;
-        private int slot = 9;
-        private int function = 0;
-
-        public SCSIDef(short index, int domain, int bus, int slot, int function) {
-            this.index = index;
-            this.domain = domain;
-            this.bus = bus;
-            this.slot = slot;
-            this.function = function;
-        }
-
-        public SCSIDef() {
-
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder scsiBuilder = new StringBuilder();
-
-            scsiBuilder.append(String.format("<controller type='scsi' index='%d' model='virtio-scsi'>\n", this.index ));
-            scsiBuilder.append(String.format("<address type='pci' domain='0x%04X' bus='0x%02X' slot='0x%02X' function='0x%01X'/>\n",
-                    this.domain, this.bus, this.slot, this.function ) );
-            scsiBuilder.append("</controller>\n");
-            return scsiBuilder.toString();
-        }
-    }
-
-    public static class InputDef {
-        private final String _type; /* tablet, mouse */
-        private final String _bus; /* ps2, usb, xen */
-
-        public InputDef(String type, String bus) {
-            _type = type;
-            _bus = bus;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder inputBuilder = new StringBuilder();
-            inputBuilder.append("<input type='" + _type + "'");
-            if (_bus != null) {
-                inputBuilder.append(" bus='" + _bus + "'");
-            }
-            inputBuilder.append("/>\n");
-            return inputBuilder.toString();
-        }
-    }
-
-    public static class FilesystemDef {
-        private final String _sourcePath;
-        private final String _targetPath;
-
-        public FilesystemDef(String sourcePath, String targetPath) {
-            _sourcePath = sourcePath;
-            _targetPath = targetPath;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder fsBuilder = new StringBuilder();
-            fsBuilder.append("<filesystem type='mount'>\n");
-            fsBuilder.append("  <source dir='" + _sourcePath + "'/>\n");
-            fsBuilder.append("  <target dir='" + _targetPath + "'/>\n");
-            fsBuilder.append("</filesystem>\n");
-            return fsBuilder.toString();
-        }
-    }
-
-    public static class MetadataDef {
-        Map<String, Object> customNodes = new HashMap<>();
-
-        public <T> T getMetadataNode(Class<T> fieldClass) {
-            T field = (T) customNodes.get(fieldClass.getName());
-            if (field == null) {
-                try {
-                    field = fieldClass.newInstance();
-                    customNodes.put(field.getClass().getName(), field);
-                } catch (InstantiationException | IllegalAccessException e) {
-                    s_logger.debug("No default constructor available in class " + fieldClass.getName() + ", ignoring exception", e);
-                }
-            }
-            return field;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder fsBuilder = new StringBuilder();
-            fsBuilder.append("<metadata>\n");
-            for (Object field : customNodes.values()) {
-                fsBuilder.append(field.toString());
-            }
-            fsBuilder.append("</metadata>\n");
-            return fsBuilder.toString();
-        }
-    }
-
-    public static class NuageExtensionDef {
-        private Map<String, String> addresses = Maps.newHashMap();
-
-        public void addNuageExtension(String macAddress, String vrIp) {
-            addresses.put(macAddress, vrIp);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder fsBuilder = new StringBuilder();
-            fsBuilder.append("<nuage-extension xmlns='nuagenetworks.net/nuage/cna'>\n");
-            for (Map.Entry<String, String> address : addresses.entrySet()) {
-                fsBuilder.append("  <interface mac='")
-                         .append(address.getKey())
-                         .append("' vsp-vr-ip='")
-                         .append(address.getValue())
-                         .append("'></interface>\n");
-            }
-            return fsBuilder.append("</nuage-extension>\n").toString();
-        }
-    }
-
-    public static class RngDef {
-        enum RngModel {
-            VIRTIO("virtio");
-            String model;
-
-            RngModel(String model) {
-                this.model = model;
-            }
-
-            @Override
-            public String toString() {
-                return model;
-            }
-        }
-
-        enum RngBackendModel {
-            RANDOM("random"), EGD("egd");
-            String model;
-
-            RngBackendModel(String model) {
-                this.model = model;
-            }
-
-            @Override
-            public String toString() {
-                return model;
-            }
-        }
-
-        private String path = "/dev/random";
-        private RngModel rngModel = RngModel.VIRTIO;
-        private RngBackendModel rngBackendModel = RngBackendModel.RANDOM;
-        private int rngRateBytes = 2048;
-        private int rngRatePeriod = 1000;
-
-        public RngDef(String path) {
-            this.path = path;
-        }
-
-        public RngDef(String path, int rngRateBytes, int rngRatePeriod) {
-            this.path = path;
-            this.rngRateBytes = rngRateBytes;
-            this.rngRatePeriod = rngRatePeriod;
-        }
-
-        public RngDef(RngModel rngModel) {
-            this.rngModel = rngModel;
-        }
-
-        public RngDef(RngBackendModel rngBackendModel) {
-            this.rngBackendModel = rngBackendModel;
-        }
-
-        public RngDef(String path, RngBackendModel rngBackendModel) {
-            this.path = path;
-            this.rngBackendModel = rngBackendModel;
-        }
-
-        public RngDef(String path, RngBackendModel rngBackendModel, int rngRateBytes, int rngRatePeriod) {
-            this.path = path;
-            this.rngBackendModel = rngBackendModel;
-            this.rngRateBytes = rngRateBytes;
-            this.rngRatePeriod = rngRatePeriod;
-        }
-
-        public RngDef(String path, RngModel rngModel) {
-            this.path = path;
-            this.rngModel = rngModel;
-        }
-
-        public String getPath() {
-           return path;
-        }
-
-        public RngBackendModel getRngBackendModel() {
-            return rngBackendModel;
-        }
-
-        public RngModel getRngModel() {
-            return rngModel;
-        }
-
-        public int getRngRateBytes() {
-            return rngRateBytes;
-        }
-
-        public int getRngRatePeriod() {
-            return rngRatePeriod;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder rngBuilder = new StringBuilder();
-            rngBuilder.append("<rng model='" + rngModel + "'>\n");
-            rngBuilder.append("<rate period='" + rngRatePeriod + "' bytes='" + rngRateBytes + "' />\n");
-            rngBuilder.append("<backend model='" + rngBackendModel + "'>" + path + "</backend>");
-            rngBuilder.append("</rng>\n");
-            return rngBuilder.toString();
-        }
-    }
-
-    public static class WatchDogDef {
-        enum WatchDogModel {
-            I6300ESB("i6300esb"), IB700("ib700"), DIAG288("diag288");
-            String model;
-
-            WatchDogModel(String model) {
-                this.model = model;
-            }
-
-            @Override
-            public String toString() {
-                return model;
-            }
-        }
-
-        enum WatchDogAction {
-            RESET("reset"), SHUTDOWN("shutdown"), POWEROFF("poweroff"), PAUSE("pause"), NONE("none"), DUMP("dump");
-            String action;
-
-            WatchDogAction(String action) {
-                this.action = action;
-            }
-
-            @Override
-            public String toString() {
-                return action;
-            }
-        }
-
-        WatchDogModel model = WatchDogModel.I6300ESB;
-        WatchDogAction action = WatchDogAction.NONE;
-
-        public WatchDogDef(WatchDogAction action) {
-            this.action = action;
-        }
-
-        public WatchDogDef(WatchDogModel model) {
-            this.model = model;
-        }
-
-        public WatchDogDef(WatchDogAction action, WatchDogModel model) {
-            this.action = action;
-            this.model = model;
-        }
-
-        public WatchDogAction getAction() {
-            return action;
-        }
-
-        public WatchDogModel getModel() {
-            return model;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder wacthDogBuilder = new StringBuilder();
-            wacthDogBuilder.append("<watchdog model='" + model + "' action='" + action + "'/>\n");
-            return wacthDogBuilder.toString();
-        }
-    }
-
-    public void setHvsType(String hvs) {
-        _hvsType = hvs;
-    }
-
-    public String getHvsType() {
-        return _hvsType;
-    }
-
-    public static void setGlobalLibvirtVersion(long libvirtVersion) {
-        s_libvirtVersion = libvirtVersion;
-    }
-
-    public void setLibvirtVersion(long libvirtVersion) {
-        setGlobalLibvirtVersion(libvirtVersion);
-    }
-
-    public static void setGlobalQemuVersion(long qemuVersion) {
-        s_qemuVersion = qemuVersion;
-    }
-
-    public void setQemuVersion(long qemuVersion) {
-        setGlobalQemuVersion(qemuVersion);
-    }
-
-    public void setDomainName(String domainName) {
-        _domName = domainName;
-    }
-
-    public void setDomUUID(String uuid) {
-        _domUUID = uuid;
-    }
-
-    public void setDomDescription(String desc) {
-        _desc = desc;
-    }
-
-    public String getGuestOSType() {
-        return _desc;
-    }
-
-    public void setPlatformEmulator(String platformEmulator) {
-        _platformEmulator = platformEmulator;
-    }
-
-    public String getPlatformEmulator() {
-        return _platformEmulator;
-    }
-
-    public void addComp(Object comp) {
-        components.put(comp.getClass().toString(), comp);
-    }
-
-    public DevicesDef getDevices() {
-        Object o = components.get(DevicesDef.class.toString());
-        if (o != null) {
-            return (DevicesDef)o;
-        }
-        return null;
-    }
-
-    public MetadataDef getMetaData() {
-        MetadataDef o = (MetadataDef) components.get(MetadataDef.class.toString());
-        if (o == null) {
-            o = new MetadataDef();
-            addComp(o);
-        }
-        return o;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder vmBuilder = new StringBuilder();
-        vmBuilder.append("<domain type='" + _hvsType + "'>\n");
-        vmBuilder.append("<name>" + _domName + "</name>\n");
-        if (_domUUID != null) {
-            vmBuilder.append("<uuid>" + _domUUID + "</uuid>\n");
-        }
-        if (_desc != null) {
-            vmBuilder.append("<description>" + _desc + "</description>\n");
-        }
-        for (Object o : components.values()) {
-            vmBuilder.append(o.toString());
-        }
-        vmBuilder.append("</domain>\n");
-        return vmBuilder.toString();
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java
deleted file mode 100644
index 4b2afa6..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.hypervisor.kvm.resource;
-
-import java.util.concurrent.Callable;
-
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.LibvirtException;
-
-public class MigrateKVMAsync implements Callable<Domain> {
-
-    private final LibvirtComputingResource libvirtComputingResource;
-
-    private Domain dm = null;
-    private Connect dconn = null;
-    private String dxml = "";
-    private String vmName = "";
-    private String destIp = "";
-    private boolean migrateStorage;
-    private boolean autoConvergence;
-
-    public MigrateKVMAsync(final LibvirtComputingResource libvirtComputingResource, final Domain dm, final Connect dconn, final String dxml,
-                           final boolean migrateStorage, final boolean autoConvergence, final String vmName, final String destIp) {
-        this.libvirtComputingResource = libvirtComputingResource;
-
-        this.dm = dm;
-        this.dconn = dconn;
-        this.dxml = dxml;
-        this.migrateStorage = migrateStorage;
-        this.autoConvergence = autoConvergence;
-        this.vmName = vmName;
-        this.destIp = destIp;
-    }
-
-    @Override
-    public Domain call() throws LibvirtException {
-        long flags = 1 << 0;
-
-        // set compression flag for migration, if libvirt version supports it
-        if (dconn.getLibVirVersion() >= 1000003) {
-            flags |= 1 << 11;
-        }
-
-        if (migrateStorage) {
-            flags |= 1 << 6;
-        }
-
-        if (autoConvergence && dconn.getLibVirVersion() >= 1002003) {
-            flags |= 1 << 13;
-        }
-
-        return dm.migrate(dconn, flags, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed());
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
deleted file mode 100644
index 06cd161..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.hypervisor.kvm.resource;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.network.Networks;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-public class OvsVifDriver extends VifDriverBase {
-    private static final Logger s_logger = Logger.getLogger(OvsVifDriver.class);
-    private int _timeout;
-
-    @Override
-    public void configure(Map<String, Object> params) throws ConfigurationException {
-        super.configure(params);
-
-        getPifs();
-
-        String networkScriptsDir = (String)params.get("network.scripts.dir");
-        if (networkScriptsDir == null) {
-            networkScriptsDir = "scripts/vm/network/vnet";
-        }
-
-        String value = (String)params.get("scripts.timeout");
-        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
-    }
-
-    public void getPifs() {
-        final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
-        s_logger.debug("cmdout was " + cmdout);
-        final List<String> bridges = Arrays.asList(cmdout.split("%"));
-        for (final String bridge : bridges) {
-            s_logger.debug("looking for pif for bridge " + bridge);
-            // String pif = getOvsPif(bridge);
-            // Not really interested in the pif name at this point for ovs
-            // bridges
-            final String pif = bridge;
-            if (_libvirtComputingResource.isPublicBridge(bridge)) {
-                _pifs.put("public", pif);
-            }
-            if (_libvirtComputingResource.isGuestBridge(bridge)) {
-                _pifs.put("private", pif);
-            }
-            _pifs.put(bridge, pif);
-        }
-        s_logger.debug("done looking for pifs, no more bridges");
-    }
-
-    @Override
-    public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException {
-        s_logger.debug("plugging nic=" + nic);
-
-        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
-        intf.setVirtualPortType("openvswitch");
-
-        String vlanId = null;
-        String logicalSwitchUuid = null;
-        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
-            vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
-            logicalSwitchUuid = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
-            // TODO consider moving some of this functionality from NetUtils to Networks....
-            vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
-        }
-        String trafficLabel = nic.getName();
-        if (nic.getType() == Networks.TrafficType.Guest) {
-            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) &&
-                    !vlanId.equalsIgnoreCase("untagged")) {
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
-                    intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    intf.setVlanTag(Integer.parseInt(vlanId));
-                } else {
-                    intf.defBridgeNet(_pifs.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    intf.setVlanTag(Integer.parseInt(vlanId));
-                }
-            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch || nic.getBroadcastType() == Networks.BroadcastDomainType.OpenDaylight) {
-                s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + logicalSwitchUuid);
-                intf.setVirtualPortInterfaceId(nic.getUuid());
-                String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private");
-                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) {
-                String vnetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
-                String brName = "OVSTunnel" + vnetId;
-                s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + brName);
-                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vsp) {
-                intf.setVirtualPortInterfaceId(nic.getUuid());
-                String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private");
-                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            } else {
-                intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            }
-        } else if (nic.getType() == Networks.TrafficType.Control) {
-            /* Make sure the network is still there */
-            createControlNetwork(_bridges.get("linklocal"));
-            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Public) {
-            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
-            if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) {
-                if (trafficLabel != null && !trafficLabel.isEmpty()) {
-                    s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel);
-                    intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    intf.setVlanTag(Integer.parseInt(vlanId));
-                } else {
-                    intf.defBridgeNet(_pifs.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-                    intf.setVlanTag(Integer.parseInt(vlanId));
-                }
-            } else {
-                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
-            }
-        } else if (nic.getType() == Networks.TrafficType.Management) {
-            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        } else if (nic.getType() == Networks.TrafficType.Storage) {
-            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
-            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
-        }
-        return intf;
-    }
-
-    @Override
-    public void unplug(InterfaceDef iface) {
-        // Libvirt apparently takes care of this, see BridgeVifDriver unplug
-    }
-
-
-    @Override
-    public void attach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("ovs-vsctl add-port " + iface.getBrName() + " " + iface.getDevName());
-    }
-
-    @Override
-    public void detach(LibvirtVMDef.InterfaceDef iface) {
-        Script.runSimpleBashScript("ovs-vsctl port-to-br " + iface.getDevName() + " && ovs-vsctl del-port " + iface.getBrName() + " " + iface.getDevName());
-    }
-
-    private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
-        Script command = new Script("/bin/bash", _timeout);
-        command.add("-c");
-        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        boolean foundLinkLocalBr = false;
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                String[] tokens = line.split(" ");
-                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
-                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
-                } else {
-                    foundLinkLocalBr = true;
-                }
-            }
-        }
-        if (!foundLinkLocalBr) {
-            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
-                    NetUtils.getLinkLocalGateway());
-        }
-    }
-
-    @Override
-    public void createControlNetwork(String privBrName) {
-        deleteExitingLinkLocalRouteTable(privBrName);
-        if (!isExistingBridge(privBrName)) {
-            Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
-        }
-    }
-
-    @Override
-    public boolean isExistingBridge(String bridgeName) {
-        Script command = new Script("/bin/sh", _timeout);
-        command.add("-c");
-        command.add("ovs-vsctl br-exists " + bridgeName);
-        String result = command.execute(null);
-        if ("0".equals(result)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java
deleted file mode 100644
index 387a552..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriver.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-
-public interface VifDriver {
-
-    public void configure(Map<String, Object> params) throws ConfigurationException;
-
-    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException;
-
-    public void unplug(LibvirtVMDef.InterfaceDef iface);
-
-    void attach(LibvirtVMDef.InterfaceDef iface);
-
-    void detach(LibvirtVMDef.InterfaceDef iface);
-
-    void createControlNetwork(String privBrName);
-
-    boolean isExistingBridge(String bridgeName);
-
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
deleted file mode 100644
index dad73f2..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-
-public abstract class VifDriverBase implements VifDriver {
-
-    protected LibvirtComputingResource _libvirtComputingResource;
-    protected Map<String, String> _pifs;
-    protected Map<String, String> _bridges;
-
-    @Override
-    public void configure(Map<String, Object> params) throws ConfigurationException {
-        _libvirtComputingResource = (LibvirtComputingResource)params.get("libvirt.computing.resource");
-        _bridges = (Map<String, String>)params.get("libvirt.host.bridges");
-        _pifs = (Map<String, String>)params.get("libvirt.host.pifs");
-    }
-
-    @Override
-    public abstract LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException;
-
-    @Override
-    public abstract void unplug(LibvirtVMDef.InterfaceDef iface);
-
-    protected LibvirtVMDef.InterfaceDef.NicModel getGuestNicModel(String platformEmulator, String nicAdapter) {
-        // if nicAdapter is found in ENUM, use it. Otherwise, match guest OS type as before
-        if (nicAdapter != null && !nicAdapter.isEmpty()) {
-            for (LibvirtVMDef.InterfaceDef.NicModel model : LibvirtVMDef.InterfaceDef.NicModel.values()) {
-                if (model.toString().equalsIgnoreCase(nicAdapter)) {
-                    return model;
-                }
-            }
-        }
-
-        if (_libvirtComputingResource.isGuestPVEnabled(platformEmulator)) {
-            return LibvirtVMDef.InterfaceDef.NicModel.VIRTIO;
-        } else {
-            return LibvirtVMDef.InterfaceDef.NicModel.E1000;
-        }
-    }
-
-    public boolean isExistingBridge(String bridgeName) {
-        return false;
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java
deleted file mode 100644
index 1796dc5..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.CreateAnswer;
-import com.cloud.agent.api.storage.CreateCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DiskProfile;
-
-@ResourceWrapper(handles =  CreateCommand.class)
-public final class LibvirtCreateCommandWrapper extends CommandWrapper<CreateCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtCreateCommandWrapper.class);
-
-    @Override
-    public Answer execute(final CreateCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final StorageFilerTO pool = command.getPool();
-        final DiskProfile dskch = command.getDiskCharacteristics();
-        KVMPhysicalDisk baseVol = null;
-        KVMStoragePool primaryPool = null;
-        KVMPhysicalDisk vol = null;
-        long disksize;
-        try {
-            final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
-            primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
-            disksize = dskch.getSize();
-
-            if (command.getTemplateUrl() != null) {
-                if (primaryPool.getType() == StoragePoolType.CLVM) {
-                    vol = libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primaryPool, dskch.getPath());
-                } else {
-                    baseVol = primaryPool.getPhysicalDisk(command.getTemplateUrl());
-                    vol = storagePoolMgr.createDiskFromTemplate(baseVol, dskch.getPath(), dskch.getProvisioningType(), primaryPool, 0);
-                }
-                if (vol == null) {
-                    return new Answer(command, false, " Can't create storage volume on storage pool");
-                }
-            } else {
-                vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize());
-                if (vol == null) {
-                    return new Answer(command, false, " Can't create Physical Disk");
-                }
-            }
-            final VolumeTO volume = new VolumeTO(command.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize,
-                    null);
-
-            volume.setBytesReadRate(dskch.getBytesReadRate());
-            volume.setBytesWriteRate(dskch.getBytesWriteRate());
-            volume.setIopsReadRate(dskch.getIopsReadRate());
-            volume.setIopsWriteRate(dskch.getIopsWriteRate());
-            volume.setCacheMode(dskch.getCacheMode());
-            return new CreateAnswer(command, volume);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to create volume: " + e.toString());
-            return new CreateAnswer(command, e);
-        }
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
deleted file mode 100644
index 80bd5fa..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.HostStatsEntry;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.utils.Pair;
-import org.apache.cloudstack.utils.linux.CPUStat;
-import org.apache.cloudstack.utils.linux.MemStat;
-import org.apache.log4j.Logger;
-
-@ResourceWrapper(handles =  GetHostStatsCommand.class)
-public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetHostStatsCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtGetHostStatsCommandWrapper.class);
-
-    @Override
-    public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        CPUStat cpuStat = libvirtComputingResource.getCPUStat();
-        MemStat memStat = libvirtComputingResource.getMemStat();
-
-        final double cpuUtil = cpuStat.getCpuUsedPercent();
-        memStat.refresh();
-        double totMem = memStat.getTotal();
-        double freeMem = memStat.getAvailable();
-
-        final Pair<Double, Double> nicStats = libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName());
-
-        final HostStatsEntry hostStats = new HostStatsEntry(command.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0);
-        return new GetHostStatsAnswer(command, hostStats);
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
deleted file mode 100644
index 067e77d..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
+++ /dev/null
@@ -1,452 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.LibvirtException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.MigrateAnswer;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.MigrateKVMAsync;
-import com.cloud.hypervisor.kvm.resource.VifDriver;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.google.common.base.Strings;
-
-@ResourceWrapper(handles =  MigrateCommand.class)
-public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, LibvirtComputingResource> {
-
-    private static final String GRAPHICS_ELEM_END = "/graphics>";
-    private static final String GRAPHICS_ELEM_START = "<graphics";
-    private static final String CONTENTS_WILDCARD = "(?s).*";
-    private static final Logger s_logger = Logger.getLogger(LibvirtMigrateCommandWrapper.class);
-
-    protected String createMigrationURI(final String destinationIp, final LibvirtComputingResource libvirtComputingResource) {
-        if (Strings.isNullOrEmpty(destinationIp)) {
-            throw new CloudRuntimeException("Provided libvirt destination ip is invalid");
-        }
-        return String.format("%s://%s/system", libvirtComputingResource.isHostSecured() ? "qemu+tls" : "qemu+tcp", destinationIp);
-    }
-
-    @Override
-    public Answer execute(final MigrateCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final String vmName = command.getVmName();
-        final String destinationUri = createMigrationURI(command.getDestinationIp(), libvirtComputingResource);
-
-        String result = null;
-
-        List<InterfaceDef> ifaces = null;
-        List<DiskDef> disks;
-
-        Domain dm = null;
-        Connect dconn = null;
-        Domain destDomain = null;
-        Connect conn = null;
-        String xmlDesc = null;
-        List<Ternary<String, Boolean, String>> vmsnapshots = null;
-
-        try {
-            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-
-            conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
-            ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
-            disks = libvirtComputingResource.getDisks(conn, vmName);
-            dm = conn.domainLookupByName(vmName);
-            /*
-                We replace the private IP address with the address of the destination host.
-                This is because the VNC listens on the private IP address of the hypervisor,
-                but that address is of course different on the target host.
-
-                MigrateCommand.getDestinationIp() returns the private IP address of the target
-                hypervisor. So it's safe to use.
-
-                The Domain.migrate method from libvirt supports passing a different XML
-                description for the instance to be used on the target host.
-
-                This is supported by libvirt-java from version 0.50.0
-
-                CVE-2015-3252: Get XML with sensitive information suitable for migration by using
-                               VIR_DOMAIN_XML_MIGRATABLE flag (value = 8)
-                               https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
-
-                               Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0.
-             */
-            final int xmlFlag = conn.getLibVirVersion() >= 1000000 ? 8 : 1; // 1000000 equals v1.0.0
-
-            final String target = command.getDestinationIp();
-            xmlDesc = dm.getXMLDesc(xmlFlag);
-            xmlDesc = replaceIpForVNCInDescFile(xmlDesc, target);
-
-            // delete the metadata of vm snapshots before migration
-            vmsnapshots = libvirtComputingResource.cleanVMSnapshotMetadata(dm);
-
-            Map<String, MigrateCommand.MigrateDiskInfo> mapMigrateStorage = command.getMigrateStorage();
-            // migrateStorage is declared as final because the replaceStorage method may mutate mapMigrateStorage, but
-            // migrateStorage's value should always only be associated with the initial state of mapMigrateStorage.
-            final boolean migrateStorage = MapUtils.isNotEmpty(mapMigrateStorage);
-
-            if (migrateStorage) {
-                xmlDesc = replaceStorage(xmlDesc, mapMigrateStorage);
-            }
-
-            dconn = libvirtUtilitiesHelper.retrieveQemuConnection(destinationUri);
-
-            //run migration in thread so we can monitor it
-            s_logger.info("Live migration of instance " + vmName + " initiated to destination host: " + dconn.getURI());
-            final ExecutorService executor = Executors.newFixedThreadPool(1);
-            final Callable<Domain> worker = new MigrateKVMAsync(libvirtComputingResource, dm, dconn, xmlDesc, migrateStorage,
-                    command.isAutoConvergence(), vmName, command.getDestinationIp());
-            final Future<Domain> migrateThread = executor.submit(worker);
-            executor.shutdown();
-            long sleeptime = 0;
-            while (!executor.isTerminated()) {
-                Thread.sleep(100);
-                sleeptime += 100;
-                if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state
-                    final int migrateDowntime = libvirtComputingResource.getMigrateDowntime();
-                    if (migrateDowntime > 0 ) {
-                        try {
-                            final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime);
-                            if (setDowntime == 0 ) {
-                                s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms");
-                            }
-                        } catch (final LibvirtException e) {
-                            s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage());
-                        }
-                    }
-                }
-                if (sleeptime % 1000 == 0) {
-                    s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms");
-                }
-
-                // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused
-                final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter();
-                if (migratePauseAfter > 0 && sleeptime > migratePauseAfter) {
-                    DomainState state = null;
-                    try {
-                        state = dm.getInfo().state;
-                    } catch (final LibvirtException e) {
-                        s_logger.info("Couldn't get VM domain state after " + sleeptime + "ms: " + e.getMessage());
-                    }
-                    if (state != null && state == DomainState.VIR_DOMAIN_RUNNING) {
-                        try {
-                            s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter + "ms to complete migration");
-                            dm.suspend();
-                        } catch (final LibvirtException e) {
-                            // pause could be racy if it attempts to pause right when vm is finished, simply warn
-                            s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage());
-                        }
-                    }
-                }
-            }
-            s_logger.info("Migration thread for " + vmName + " is done");
-
-            destDomain = migrateThread.get(10, TimeUnit.SECONDS);
-
-            if (destDomain != null) {
-                for (final DiskDef disk : disks) {
-                    libvirtComputingResource.cleanupDisk(disk);
-                }
-            }
-
-        } catch (final LibvirtException e) {
-            s_logger.debug("Can't migrate domain: " + e.getMessage());
-            result = e.getMessage();
-            if (result.startsWith("unable to connect to server") && result.endsWith("refused")) {
-                result = String.format("Migration was refused connection to destination: %s. Please check libvirt configuration compatibility and firewall rules on the source and destination hosts.", destinationUri);
-            }
-        } catch (final InterruptedException e) {
-            s_logger.debug("Interrupted while migrating domain: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final ExecutionException e) {
-            s_logger.debug("Failed to execute while migrating domain: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final TimeoutException e) {
-            s_logger.debug("Timed out while migrating domain: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final IOException e) {
-            s_logger.debug("IOException: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final ParserConfigurationException e) {
-            s_logger.debug("ParserConfigurationException: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final SAXException e) {
-            s_logger.debug("SAXException: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final TransformerConfigurationException e) {
-            s_logger.debug("TransformerConfigurationException: " + e.getMessage());
-            result = e.getMessage();
-        } catch (final TransformerException e) {
-            s_logger.debug("TransformerException: " + e.getMessage());
-            result = e.getMessage();
-        } finally {
-            try {
-                if (dm != null && result != null) {
-                    // restore vm snapshots in case of failed migration
-                    if (vmsnapshots != null) {
-                        libvirtComputingResource.restoreVMSnapshotMetadata(dm, vmName, vmsnapshots);
-                    }
-                }
-                if (dm != null) {
-                    if (dm.isPersistent() == 1) {
-                        dm.undefine();
-                    }
-                    dm.free();
-                }
-                if (dconn != null) {
-                    dconn.close();
-                }
-                if (destDomain != null) {
-                    destDomain.free();
-                }
-            } catch (final LibvirtException e) {
-                s_logger.trace("Ignoring libvirt error.", e);
-            }
-        }
-
-        if (result != null) {
-        } else {
-            libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName);
-            for (final InterfaceDef iface : ifaces) {
-                // We don't know which "traffic type" is associated with
-                // each interface at this point, so inform all vif drivers
-                final List<VifDriver> allVifDrivers = libvirtComputingResource.getAllVifDrivers();
-                for (final VifDriver vifDriver : allVifDrivers) {
-                    vifDriver.unplug(iface);
-                }
-            }
-        }
-
-        return new MigrateAnswer(command, result == null, result, null);
-    }
-
-    /**
-     * This function assumes an qemu machine description containing a single graphics element like
-     *     <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>
-     *       <listen type='address' address='10.10.10.1'/>
-     *     </graphics>
-     * @param xmlDesc the qemu xml description
-     * @param target the ip address to migrate to
-     * @return the new xmlDesc
-     */
-    String replaceIpForVNCInDescFile(String xmlDesc, final String target) {
-        final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START);
-        if (begin >= 0) {
-            final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length();
-            if (end > begin) {
-                String graphElem = xmlDesc.substring(begin, end);
-                graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'");
-                graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'");
-                xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem);
-            }
-        }
-        return xmlDesc;
-    }
-
-    // Pass in a list of the disks to update in the XML (xmlDesc). Each disk passed in needs to have a serial number. If any disk's serial number in the
-    // list does not match a disk in the XML, an exception should be thrown.
-    // In addition to the serial number, each disk in the list needs the following info:
-    //   * The value of the 'type' of the disk (ex. file, block)
-    //   * The value of the 'type' of the driver of the disk (ex. qcow2, raw)
-    //   * The source of the disk needs an attribute that is either 'file' or 'dev' as well as its corresponding value.
-    private String replaceStorage(String xmlDesc, Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage)
-            throws IOException, ParserConfigurationException, SAXException, TransformerException {
-        InputStream in = IOUtils.toInputStream(xmlDesc);
-
-        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
-        Document doc = docBuilder.parse(in);
-
-        // Get the root element
-        Node domainNode = doc.getFirstChild();
-
-        NodeList domainChildNodes = domainNode.getChildNodes();
-
-        for (int i = 0; i < domainChildNodes.getLength(); i++) {
-            Node domainChildNode = domainChildNodes.item(i);
-
-            if ("devices".equals(domainChildNode.getNodeName())) {
-                NodeList devicesChildNodes = domainChildNode.getChildNodes();
-
-                for (int x = 0; x < devicesChildNodes.getLength(); x++) {
-                    Node deviceChildNode = devicesChildNodes.item(x);
-
-                    if ("disk".equals(deviceChildNode.getNodeName())) {
-                        Node diskNode = deviceChildNode;
-
-                        String sourceText = getSourceText(diskNode);
-
-                        String path = getPathFromSourceText(migrateStorage.keySet(), sourceText);
-
-                        if (path != null) {
-                            MigrateCommand.MigrateDiskInfo migrateDiskInfo = migrateStorage.remove(path);
-
-                            NamedNodeMap diskNodeAttributes = diskNode.getAttributes();
-                            Node diskNodeAttribute = diskNodeAttributes.getNamedItem("type");
-
-                            diskNodeAttribute.setTextContent(migrateDiskInfo.getDiskType().toString());
-
-                            NodeList diskChildNodes = diskNode.getChildNodes();
-
-                            for (int z = 0; z < diskChildNodes.getLength(); z++) {
-                                Node diskChildNode = diskChildNodes.item(z);
-
-                                if ("driver".equals(diskChildNode.getNodeName())) {
-                                    Node driverNode = diskChildNode;
-
-                                    NamedNodeMap driverNodeAttributes = driverNode.getAttributes();
-                                    Node driverNodeAttribute = driverNodeAttributes.getNamedItem("type");
-
-                                    driverNodeAttribute.setTextContent(migrateDiskInfo.getDriverType().toString());
-                                } else if ("source".equals(diskChildNode.getNodeName())) {
-                                    diskNode.removeChild(diskChildNode);
-
-                                    Element newChildSourceNode = doc.createElement("source");
-
-                                    newChildSourceNode.setAttribute(migrateDiskInfo.getSource().toString(), migrateDiskInfo.getSourceText());
-
-                                    diskNode.appendChild(newChildSourceNode);
-                                } else if ("auth".equals(diskChildNode.getNodeName())) {
-                                    diskNode.removeChild(diskChildNode);
-                                } else if ("iotune".equals(diskChildNode.getNodeName())) {
-                                    diskNode.removeChild(diskChildNode);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!migrateStorage.isEmpty()) {
-            throw new CloudRuntimeException("Disk info was passed into LibvirtMigrateCommandWrapper.replaceStorage that was not used.");
-        }
-
-        return getXml(doc);
-    }
-
-    private String getPathFromSourceText(Set<String> paths, String sourceText) {
-        if (paths != null && !StringUtils.isBlank(sourceText)) {
-            for (String path : paths) {
-                if (sourceText.contains(path)) {
-                    return path;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private String getSourceText(Node diskNode) {
-        NodeList diskChildNodes = diskNode.getChildNodes();
-
-        for (int i = 0; i < diskChildNodes.getLength(); i++) {
-            Node diskChildNode = diskChildNodes.item(i);
-
-            if ("source".equals(diskChildNode.getNodeName())) {
-                NamedNodeMap diskNodeAttributes = diskChildNode.getAttributes();
-
-                Node diskNodeAttribute = diskNodeAttributes.getNamedItem("file");
-
-                if (diskNodeAttribute != null) {
-                    return diskNodeAttribute.getTextContent();
-                }
-
-                diskNodeAttribute = diskNodeAttributes.getNamedItem("dev");
-
-                if (diskNodeAttribute != null) {
-                    return diskNodeAttribute.getTextContent();
-                }
-
-                diskNodeAttribute = diskNodeAttributes.getNamedItem("protocol");
-
-                if (diskNodeAttribute != null) {
-                    String textContent = diskNodeAttribute.getTextContent();
-
-                    if ("rbd".equalsIgnoreCase(textContent)) {
-                        diskNodeAttribute = diskNodeAttributes.getNamedItem("name");
-
-                        if (diskNodeAttribute != null) {
-                            return diskNodeAttribute.getTextContent();
-                        }
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private String getXml(Document doc) throws TransformerException {
-        TransformerFactory transformerFactory = TransformerFactory.newInstance();
-        Transformer transformer = transformerFactory.newTransformer();
-
-        DOMSource source = new DOMSource(doc);
-
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        StreamResult result = new StreamResult(byteArrayOutputStream);
-
-        transformer.transform(source, result);
-
-        return byteArrayOutputStream.toString();
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
deleted file mode 100644
index 2ee9b95..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.PlugNicAnswer;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.VifDriver;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.LibvirtException;
-
-import java.util.List;
-
-@ResourceWrapper(handles =  PlugNicCommand.class)
-public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtPlugNicCommandWrapper.class);
-
-    @Override
-    public Answer execute(final PlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final NicTO nic = command.getNic();
-        final String vmName = command.getVmName();
-        Domain vm = null;
-        try {
-            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
-            vm = libvirtComputingResource.getDomain(conn, vmName);
-
-            final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
-            Integer nicnum = 0;
-            for (final InterfaceDef pluggedNic : pluggedNics) {
-                if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
-                    s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum);
-                    return new PlugNicAnswer(command, true, "success");
-                }
-                nicnum++;
-            }
-            final VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
-            final InterfaceDef interfaceDef = vifDriver.plug(nic, "Other PV", "");
-            vm.attachDevice(interfaceDef.toString());
-
-            return new PlugNicAnswer(command, true, "success");
-        } catch (final LibvirtException e) {
-            final String msg = " Plug Nic failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new PlugNicAnswer(command, false, msg);
-        } catch (final InternalErrorException e) {
-            final String msg = " Plug Nic failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new PlugNicAnswer(command, false, msg);
-        } finally {
-            if (vm != null) {
-                try {
-                    vm.free();
-                } catch (final LibvirtException l) {
-                    s_logger.trace("Ignoring libvirt error.", l);
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java
deleted file mode 100644
index df89d24..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import org.apache.cloudstack.ca.PostCertificateRenewalCommand;
-import org.apache.cloudstack.ca.SetupCertificateAnswer;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.utils.script.Script;
-
-@ResourceWrapper(handles =  PostCertificateRenewalCommand.class)
-public final class LibvirtPostCertificateRenewalCommandWrapper extends CommandWrapper<PostCertificateRenewalCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtPostCertificateRenewalCommandWrapper.class);
-
-    @Override
-    public Answer execute(final PostCertificateRenewalCommand command, final LibvirtComputingResource serverResource) {
-        s_logger.info("Restarting libvirt after certificate provisioning/renewal");
-        if (command != null) {
-            final int timeout = 30000;
-            Script script = new Script(true, "service", timeout, s_logger);
-            if ("Ubuntu".equals(serverResource.getHostDistro()) || "Debian".equals(serverResource.getHostDistro())) {
-                script.add("libvirt-bin");
-            } else {
-               script.add("libvirtd");
-            }
-            script.add("restart");
-            script.execute();
-            return new SetupCertificateAnswer(true);
-       }
-        return new SetupCertificateAnswer(false);
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java
deleted file mode 100644
index ac9f884..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java
+++ /dev/null
@@ -1,108 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.PrepareForMigrationAnswer;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.storage.Volume;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.LibvirtException;
-
-import java.net.URISyntaxException;
-
-@ResourceWrapper(handles =  PrepareForMigrationCommand.class)
-public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapper<PrepareForMigrationCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtPrepareForMigrationCommandWrapper.class);
-
-    @Override
-    public Answer execute(final PrepareForMigrationCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final VirtualMachineTO vm = command.getVirtualMachine();
-
-        if (command.isRollback()) {
-            return handleRollback(command, libvirtComputingResource);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Preparing host for migrating " + vm);
-        }
-
-        final NicTO[] nics = vm.getNics();
-
-        boolean skipDisconnect = false;
-
-        final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
-        try {
-            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-
-            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vm.getName());
-            for (final NicTO nic : nics) {
-                libvirtComputingResource.getVifDriver(nic.getType(), nic.getName()).plug(nic, null, "");
-            }
-
-            /* setup disks, e.g for iso */
-            final DiskTO[] volumes = vm.getDisks();
-            for (final DiskTO volume : volumes) {
-                if (volume.getType() == Volume.Type.ISO) {
-                    libvirtComputingResource.getVolumePath(conn, volume);
-                }
-            }
-
-            skipDisconnect = true;
-
-            if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) {
-                return new PrepareForMigrationAnswer(command, "failed to connect physical disks to host");
-            }
-
-            return new PrepareForMigrationAnswer(command);
-        } catch (final LibvirtException e) {
-            return new PrepareForMigrationAnswer(command, e.toString());
-        } catch (final InternalErrorException e) {
-            return new PrepareForMigrationAnswer(command, e.toString());
-        } catch (final URISyntaxException e) {
-            return new PrepareForMigrationAnswer(command, e.toString());
-        } finally {
-            if (!skipDisconnect) {
-                storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm);
-            }
-        }
-    }
-
-    private Answer handleRollback(PrepareForMigrationCommand command, LibvirtComputingResource libvirtComputingResource) {
-        KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
-        VirtualMachineTO vmTO = command.getVirtualMachine();
-
-        if (!storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmTO)) {
-            return new PrepareForMigrationAnswer(command, "failed to disconnect physical disks from host");
-        }
-
-        return new PrepareForMigrationAnswer(command);
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java
deleted file mode 100644
index c91e719..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ReplugNicAnswer;
-import com.cloud.agent.api.ReplugNicCommand;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.VifDriver;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-
-@ResourceWrapper(handles =  ReplugNicCommand.class)
-public final class LibvirtReplugNicCommandWrapper extends CommandWrapper<ReplugNicCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtReplugNicCommandWrapper.class);
-    public enum DomainAffect {
-        CURRENT(0), LIVE(1), CONFIG(2), BOTH(3);
-
-        private int value;
-        DomainAffect(int value) {
-            this.value = value;
-        }
-
-        public int getValue() {
-            return value;
-        }
-    }
-
-    @Override
-    public Answer execute(final ReplugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final NicTO nic = command.getNic();
-        final String vmName = command.getVmName();
-        Domain vm = null;
-        try {
-            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
-            vm = libvirtComputingResource.getDomain(conn, vmName);
-
-            InterfaceDef oldPluggedNic = findPluggedNic(libvirtComputingResource, nic, vmName, conn);
-
-            final VifDriver newVifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
-            final InterfaceDef interfaceDef = newVifDriver.plug(nic, "Other PV", oldPluggedNic.getModel().toString());
-
-            interfaceDef.setSlot(oldPluggedNic.getSlot());
-            interfaceDef.setDevName(oldPluggedNic.getDevName());
-            interfaceDef.setLinkStateUp(false);
-
-            oldPluggedNic.setSlot(null);
-
-            int i = 0;
-            do {
-                i++;
-                s_logger.debug("ReplugNic: Detaching interface" + oldPluggedNic + " (Attempt: " + i + ")");
-                vm.detachDevice(oldPluggedNic.toString());
-            } while (findPluggedNic(libvirtComputingResource, nic, vmName, conn) != null && i <= 10);
-
-            s_logger.debug("ReplugNic: Attaching interface" + interfaceDef);
-            vm.attachDevice(interfaceDef.toString());
-
-            interfaceDef.setLinkStateUp(true);
-            s_logger.debug("ReplugNic: Updating interface" + interfaceDef);
-            vm.updateDeviceFlags(interfaceDef.toString(), DomainAffect.LIVE.getValue());
-
-            // We don't know which "traffic type" is associated with
-            // each interface at this point, so inform all vif drivers
-            for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
-                vifDriver.unplug(oldPluggedNic);
-            }
-
-            return new ReplugNicAnswer(command, true, "success");
-        } catch (final LibvirtException | InternalErrorException e) {
-            final String msg = " Plug Nic failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new ReplugNicAnswer(command, false, msg);
-        } finally {
-            if (vm != null) {
-                try {
-                    vm.free();
-                } catch (final LibvirtException l) {
-                    s_logger.trace("Ignoring libvirt error.", l);
-                }
-            }
-        }
-    }
-
-    private InterfaceDef findPluggedNic(LibvirtComputingResource libvirtComputingResource, NicTO nic, String vmName, Connect conn) {
-        InterfaceDef oldPluggedNic = null;
-
-        final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
-
-        for (final InterfaceDef pluggedNic : pluggedNics) {
-            if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
-                oldPluggedNic = pluggedNic;
-            }
-        }
-
-        return oldPluggedNic;
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
deleted file mode 100644
index e31401d..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
+++ /dev/null
@@ -1,187 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import java.net.URISyntaxException;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.LibvirtException;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.cloud.vm.VirtualMachine;
-
-@ResourceWrapper(handles =  StartCommand.class)
-public final class LibvirtStartCommandWrapper extends CommandWrapper<StartCommand, Answer, LibvirtComputingResource> {
-
-    private static final Logger s_logger = Logger.getLogger(LibvirtStartCommandWrapper.class);
-
-    @Override
-    public Answer execute(final StartCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final VirtualMachineTO vmSpec = command.getVirtualMachine();
-        vmSpec.setVncAddr(command.getHostIp());
-        final String vmName = vmSpec.getName();
-        LibvirtVMDef vm = null;
-
-        DomainState  state = DomainState.VIR_DOMAIN_SHUTOFF;
-        final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-        Connect conn = null;
-        try {
-
-            vm = libvirtComputingResource.createVMFromSpec(vmSpec);
-            conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
-
-            Long remainingMem = getFreeMemory(conn, libvirtComputingResource);
-            if (remainingMem == null){
-                return new StartAnswer(command, "failed to get free memory");
-            } else if (remainingMem < vmSpec.getMinRam()) {
-                return new StartAnswer(command, "Not enough memory on the host, remaining: " + remainingMem + ", asking: " + vmSpec.getMinRam());
-            }
-
-            final NicTO[] nics = vmSpec.getNics();
-
-            for (final NicTO nic : nics) {
-                if (vmSpec.getType() != VirtualMachine.Type.User) {
-                    nic.setPxeDisable(true);
-                }
-            }
-
-            libvirtComputingResource.createVbd(conn, vmSpec, vmName, vm);
-
-            if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) {
-                return new StartAnswer(command, "Failed to connect physical disks to host");
-            }
-
-            libvirtComputingResource.createVifs(vmSpec, vm);
-
-            s_logger.debug("starting " + vmName + ": " + vm.toString());
-            libvirtComputingResource.startVM(conn, vmName, vm.toString());
-
-            for (final NicTO nic : nics) {
-                if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
-                    if (vmSpec.getType() != VirtualMachine.Type.User) {
-                        libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, vmName);
-                        break;
-                    } else {
-                        final List<String> nicSecIps = nic.getNicSecIps();
-                        String secIpsStr;
-                        final StringBuilder sb = new StringBuilder();
-                        if (nicSecIps != null) {
-                            for (final String ip : nicSecIps) {
-                                sb.append(ip).append(";");
-                            }
-                            secIpsStr = sb.toString();
-                        } else {
-                            secIpsStr = "0;";
-                        }
-                        libvirtComputingResource.defaultNetworkRules(conn, vmName, nic, vmSpec.getId(), secIpsStr);
-                    }
-                }
-            }
-
-            // pass cmdline info to system vms
-            if (vmSpec.getType() != VirtualMachine.Type.User) {
-                String controlIp = null;
-                for (final NicTO nic : nics) {
-                    if (nic.getType() == TrafficType.Control) {
-                        controlIp = nic.getIp();
-                        break;
-                    }
-                }
-                // try to patch and SSH into the systemvm for up to 5 minutes
-                for (int count = 0; count < 10; count++) {
-                    // wait and try passCmdLine for 30 seconds at most for CLOUDSTACK-2823
-                    if (libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())) {
-                        break;
-                    }
-                }
-
-                final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
-                // check if the router is up?
-                for (int count = 0; count < 60; count++) {
-                    final boolean result = virtRouterResource.connect(controlIp, 1, 5000);
-                    if (result) {
-                        break;
-                    }
-                }
-            }
-
-            state = DomainState.VIR_DOMAIN_RUNNING;
-            return new StartAnswer(command);
-        } catch (final LibvirtException e) {
-            s_logger.warn("LibvirtException ", e);
-            if (conn != null) {
-                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
-            }
-            return new StartAnswer(command, e.getMessage());
-        } catch (final InternalErrorException e) {
-            s_logger.warn("InternalErrorException ", e);
-            if (conn != null) {
-                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
-            }
-            return new StartAnswer(command, e.getMessage());
-        } catch (final URISyntaxException e) {
-            s_logger.warn("URISyntaxException ", e);
-            if (conn != null) {
-                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
-            }
-            return new StartAnswer(command, e.getMessage());
-        } finally {
-            if (state != DomainState.VIR_DOMAIN_RUNNING) {
-                storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmSpec);
-            }
-        }
-    }
-
-    private Long getFreeMemory(final Connect conn, final LibvirtComputingResource libvirtComputingResource){
-        try {
-            long allocatedMem = 0;
-            int[] ids = conn.listDomains();
-            for(int id :ids) {
-                Domain dm = conn.domainLookupByID(id);
-                allocatedMem += dm.getMaxMemory() * 1024L;
-                s_logger.debug("vm: " + dm.getName() + " mem: " + dm.getMaxMemory() * 1024L);
-            }
-            Long remainingMem = libvirtComputingResource.getTotalMemory() - allocatedMem;
-            s_logger.debug("remaining mem" + remainingMem);
-            return remainingMem;
-        } catch (Exception e) {
-            s_logger.debug("failed to get free memory", e);
-            return null;
-        }
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
deleted file mode 100644
index a90c97f..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
+++ /dev/null
@@ -1,444 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.storage;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.utils.qemu.QemuImg;
-import org.apache.cloudstack.utils.qemu.QemuImgException;
-import org.apache.cloudstack.utils.qemu.QemuImgFile;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-@StorageAdaptorInfo(storagePoolType=StoragePoolType.Iscsi)
-public class IscsiAdmStorageAdaptor implements StorageAdaptor {
-    private static final Logger s_logger = Logger.getLogger(IscsiAdmStorageAdaptor.class);
-
-    private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>();
-
-    @Override
-    public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType) {
-        IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this);
-
-        MapStorageUuidToStoragePool.put(uuid, storagePool);
-
-        return storagePool;
-    }
-
-    @Override
-    public KVMStoragePool getStoragePool(String uuid) {
-        return MapStorageUuidToStoragePool.get(uuid);
-    }
-
-    @Override
-    public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
-        return MapStorageUuidToStoragePool.get(uuid);
-    }
-
-    @Override
-    public boolean deleteStoragePool(String uuid) {
-        return MapStorageUuidToStoragePool.remove(uuid) != null;
-    }
-
-    @Override
-    public boolean deleteStoragePool(KVMStoragePool pool) {
-        return deleteStoragePool(pool.getUuid());
-    }
-
-    // called from LibvirtComputingResource.execute(CreateCommand)
-    // does not apply for iScsiAdmStorageAdaptor
-    @Override
-    public KVMPhysicalDisk createPhysicalDisk(String volumeUuid, KVMStoragePool pool, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
-        throw new UnsupportedOperationException("Creating a physical disk is not supported.");
-    }
-
-    @Override
-    public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details) {
-        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new
-        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
-
-        iScsiAdmCmd.add("-m", "node");
-        iScsiAdmCmd.add("-T", getIqn(volumeUuid));
-        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
-        iScsiAdmCmd.add("-o", "new");
-
-        String result = iScsiAdmCmd.execute();
-
-        if (result != null) {
-            s_logger.debug("Failed to add iSCSI target " + volumeUuid);
-            System.out.println("Failed to add iSCSI target " + volumeUuid);
-
-            return false;
-        } else {
-            s_logger.debug("Successfully added iSCSI target " + volumeUuid);
-            System.out.println("Successfully added to iSCSI target " + volumeUuid);
-        }
-
-        String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
-        String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-        if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorSecret)) {
-            try {
-                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.authmethod -v CHAP
-                executeChapCommand(volumeUuid, pool, "node.session.auth.authmethod", "CHAP", null);
-
-                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.username -v username
-                executeChapCommand(volumeUuid, pool, "node.session.auth.username", chapInitiatorUsername, "username");
-
-                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.password -v password
-                executeChapCommand(volumeUuid, pool, "node.session.auth.password", chapInitiatorSecret, "password");
-            } catch (Exception ex) {
-                return false;
-            }
-        }
-
-        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --login
-        iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
-
-        iScsiAdmCmd.add("-m", "node");
-        iScsiAdmCmd.add("-T", getIqn(volumeUuid));
-        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
-        iScsiAdmCmd.add("--login");
-
-        result = iScsiAdmCmd.execute();
-
-        if (result != null) {
-            s_logger.debug("Failed to log in to iSCSI target " + volumeUuid);
-            System.out.println("Failed to log in to iSCSI target " + volumeUuid);
-
-            return false;
-        } else {
-            s_logger.debug("Successfully logged in to iSCSI target " + volumeUuid);
-            System.out.println("Successfully logged in to iSCSI target " + volumeUuid);
-        }
-
-        // There appears to be a race condition where logging in to the iSCSI volume via iscsiadm
-        // returns success before the device has been added to the OS.
-        // What happens is you get logged in and the device shows up, but the device may not
-        // show up before we invoke Libvirt to attach the device to a VM.
-        // waitForDiskToBecomeAvailable(String, KVMStoragePool) invokes blockdev
-        // via getPhysicalDisk(String, KVMStoragePool) and checks if the size came back greater
-        // than 0.
-        // After a certain number of tries and a certain waiting period in between tries,
-        // this method could still return (it should not block indefinitely) (the race condition
-        // isn't solved here, but made highly unlikely to be a problem).
-        waitForDiskToBecomeAvailable(volumeUuid, pool);
-
-        return true;
-    }
-
-    private void waitForDiskToBecomeAvailable(String volumeUuid, KVMStoragePool pool) {
-        int numberOfTries = 10;
-        int timeBetweenTries = 1000;
-
-        while (getPhysicalDisk(volumeUuid, pool).getSize() == 0 && numberOfTries > 0) {
-            numberOfTries--;
-
-            try {
-                Thread.sleep(timeBetweenTries);
-            } catch (Exception ex) {
-                // don't do anything
-            }
-        }
-    }
-
-    private void waitForDiskToBecomeUnavailable(String host, int port, String iqn, String lun) {
-        int numberOfTries = 10;
-        int timeBetweenTries = 1000;
-
-        String deviceByPath = getByPath(host, port, "/" + iqn + "/" + lun);
-
-        while (getDeviceSize(deviceByPath) > 0 && numberOfTries > 0) {
-            numberOfTries--;
-
-            try {
-                Thread.sleep(timeBetweenTries);
-            } catch (Exception ex) {
-                // don't do anything
-            }
-        }
-    }
-
-    private void executeChapCommand(String path, KVMStoragePool pool, String nParameter, String vParameter, String detail) throws Exception {
-        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
-
-        iScsiAdmCmd.add("-m", "node");
-        iScsiAdmCmd.add("-T", getIqn(path));
-        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
-        iScsiAdmCmd.add("--op", "update");
-        iScsiAdmCmd.add("-n", nParameter);
-        iScsiAdmCmd.add("-v", vParameter);
-
-        String result = iScsiAdmCmd.execute();
-
-        boolean useDetail = detail != null && detail.trim().length() > 0;
-
-        detail = useDetail ? detail.trim() + " " : detail;
-
-        if (result != null) {
-            s_logger.debug("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
-            System.out.println("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
-
-            throw new Exception("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
-        } else {
-            s_logger.debug("CHAP " + (useDetail ? detail : "") + "command executed successfully for iSCSI target " + path);
-            System.out.println("CHAP " + (useDetail ? detail : "") + "command executed successfully for iSCSI target " + path);
-        }
-    }
-
-    // example by-path: /dev/disk/by-path/ip-192.168.233.10:3260-iscsi-iqn.2012-03.com.solidfire:storagepool2-lun-0
-    private static String getByPath(String host, int port, String path) {
-        return "/dev/disk/by-path/ip-" + host + ":" + port + "-iscsi-" + getIqn(path) + "-lun-" + getLun(path);
-    }
-
-    @Override
-    public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
-        String deviceByPath = getByPath(pool.getSourceHost(), pool.getSourcePort(), volumeUuid);
-        KVMPhysicalDisk physicalDisk = new KVMPhysicalDisk(deviceByPath, volumeUuid, pool);
-
-        physicalDisk.setFormat(PhysicalDiskFormat.RAW);
-
-        long deviceSize = getDeviceSize(deviceByPath);
-
-        physicalDisk.setSize(deviceSize);
-        physicalDisk.setVirtualSize(deviceSize);
-
-        return physicalDisk;
-    }
-
-    private long getDeviceSize(String deviceByPath) {
-        Script iScsiAdmCmd = new Script(true, "blockdev", 0, s_logger);
-
-        iScsiAdmCmd.add("--getsize64", deviceByPath);
-
-        OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
-
-        String result = iScsiAdmCmd.execute(parser);
-
-        if (result != null) {
-            s_logger.warn("Unable to retrieve the size of device " + deviceByPath);
-
-            return 0;
-        }
-        else {
-            s_logger.info("Successfully retrieved the size of device " + deviceByPath);
-        }
-
-        return Long.parseLong(parser.getLine());
-    }
-
-    private static String getIqn(String path) {
-        return getComponent(path, 1);
-    }
-
-    private static String getLun(String path) {
-        return getComponent(path, 2);
-    }
-
-    private static String getComponent(String path, int index) {
-        String[] tmp = path.split("/");
-
-        if (tmp.length != 3) {
-            String msg = "Wrong format for iScsi path: " + path + ". It should be formatted as '/targetIQN/LUN'.";
-
-            s_logger.warn(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        return tmp[index].trim();
-    }
-
-    private boolean disconnectPhysicalDisk(String host, int port, String iqn, String lun) {
-        // use iscsiadm to log out of the iSCSI target and un-discover it
-
-        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --logout
-        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
-
-        iScsiAdmCmd.add("-m", "node");
-        iScsiAdmCmd.add("-T", iqn);
-        iScsiAdmCmd.add("-p", host + ":" + port);
-        iScsiAdmCmd.add("--logout");
-
-        String result = iScsiAdmCmd.execute();
-
-        if (result != null) {
-            s_logger.debug("Failed to log out of iSCSI target /" + iqn + "/" + lun + " : message = " + result);
-            System.out.println("Failed to log out of iSCSI target /" + iqn + "/" + lun + " : message = " + result);
-
-            return false;
-        } else {
-            s_logger.debug("Successfully logged out of iSCSI target /" + iqn + "/" + lun);
-            System.out.println("Successfully logged out of iSCSI target /" + iqn + "/" + lun);
-        }
-
-        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o delete
-        iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
-
-        iScsiAdmCmd.add("-m", "node");
-        iScsiAdmCmd.add("-T", iqn);
-        iScsiAdmCmd.add("-p", host + ":" + port);
-        iScsiAdmCmd.add("-o", "delete");
-
-        result = iScsiAdmCmd.execute();
-
-        if (result != null) {
-            s_logger.debug("Failed to remove iSCSI target /" + iqn + "/" + lun + " : message = " + result);
-            System.out.println("Failed to remove iSCSI target /" + iqn + "/" + lun + " : message = " + result);
-
-            return false;
-        } else {
-            s_logger.debug("Removed iSCSI target /" + iqn + "/" + lun);
-            System.out.println("Removed iSCSI target /" + iqn + "/" + lun);
-        }
-
-        waitForDiskToBecomeUnavailable(host, port, iqn, lun);
-
-        return true;
-    }
-
-    @Override
-    public boolean disconnectPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
-        return disconnectPhysicalDisk(pool.getSourceHost(), pool.getSourcePort(), getIqn(volumeUuid), getLun(volumeUuid));
-    }
-
-    @Override
-    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
-        String host = volumeToDisconnect.get(DiskTO.STORAGE_HOST);
-        String port = volumeToDisconnect.get(DiskTO.STORAGE_PORT);
-        String path = volumeToDisconnect.get(DiskTO.IQN);
-
-        if (host != null && port != null && path != null) {
-            return disconnectPhysicalDisk(host, Integer.parseInt(port), getIqn(path), getLun(path));
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean disconnectPhysicalDiskByPath(String localPath) {
-        String search1 = "/dev/disk/by-path/ip-";
-        String search2 = ":";
-        String search3 = "-iscsi-";
-        String search4 = "-lun-";
-
-        if (!localPath.contains(search3)) {
-            // this volume doesn't below to this adaptor, so just return true
-            return true;
-        }
-
-        int index = localPath.indexOf(search2);
-
-        String host = localPath.substring(search1.length(), index);
-
-        int index2 = localPath.indexOf(search3);
-
-        String port = localPath.substring(index + search2.length(), index2);
-
-        index = localPath.indexOf(search4);
-
-        String iqn = localPath.substring(index2 + search3.length(), index);
-
-        String lun = localPath.substring(index + search4.length());
-
-        return disconnectPhysicalDisk(host, Integer.parseInt(port), iqn, lun);
-    }
-
-    @Override
-    public boolean deletePhysicalDisk(String volumeUuid, KVMStoragePool pool, Storage.ImageFormat format) {
-        throw new UnsupportedOperationException("Deleting a physical disk is not supported.");
-    }
-
-    // does not apply for iScsiAdmStorageAdaptor
-    @Override
-    public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStoragePool pool) {
-        throw new UnsupportedOperationException("Listing disks is not supported for this configuration.");
-    }
-
-    @Override
-    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, PhysicalDiskFormat format,
-            ProvisioningType provisioningType, long size,
-            KVMStoragePool destPool, int timeout) {
-        throw new UnsupportedOperationException("Creating a disk from a template is not yet supported for this configuration.");
-    }
-
-    @Override
-    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
-        throw new UnsupportedOperationException("Creating a template from a disk is not yet supported for this configuration.");
-    }
-
-    @Override
-    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk srcDisk, String destVolumeUuid, KVMStoragePool destPool, int timeout) {
-        QemuImg q = new QemuImg(timeout);
-
-        QemuImgFile srcFile;
-
-        KVMStoragePool srcPool = srcDisk.getPool();
-
-        if (srcPool.getType() == StoragePoolType.RBD) {
-            srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(),
-                                                                       srcPool.getAuthUserName(), srcPool.getAuthSecret(),
-                                                                       srcDisk.getPath()),srcDisk.getFormat());
-        } else {
-            srcFile = new QemuImgFile(srcDisk.getPath(), srcDisk.getFormat());
-        }
-
-        KVMPhysicalDisk destDisk = destPool.getPhysicalDisk(destVolumeUuid);
-
-        QemuImgFile destFile = new QemuImgFile(destDisk.getPath(), destDisk.getFormat());
-
-        try {
-            q.convert(srcFile, destFile);
-        } catch (QemuImgException ex) {
-            String msg = "Failed to copy data from " + srcDisk.getPath() + " to " +
-                    destDisk.getPath() + ". The error was the following: " + ex.getMessage();
-
-            s_logger.error(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        return destPool.getPhysicalDisk(destVolumeUuid);
-    }
-
-    @Override
-    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
-        throw new UnsupportedOperationException("Creating a disk from a snapshot is not supported in this configuration.");
-    }
-
-    @Override
-    public boolean refresh(KVMStoragePool pool) {
-        return true;
-    }
-
-    @Override
-    public boolean createFolder(String uuid, String path) {
-        throw new UnsupportedOperationException("A folder cannot be created in this configuration.");
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
deleted file mode 100644
index 4d0523c..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
+++ /dev/null
@@ -1,395 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.storage;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.hypervisor.kvm.resource.KVMHABase;
-import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType;
-import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.Volume;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import org.reflections.Reflections;
-
-public class KVMStoragePoolManager {
-    private static final Logger s_logger = Logger.getLogger(KVMStoragePoolManager.class);
-
-    private class StoragePoolInformation {
-        String name;
-        String host;
-        int port;
-        String path;
-        String userInfo;
-        boolean type;
-        StoragePoolType poolType;
-
-        public StoragePoolInformation(String name, String host, int port, String path, String userInfo, StoragePoolType poolType, boolean type) {
-            this.name = name;
-            this.host = host;
-            this.port = port;
-            this.path = path;
-            this.userInfo = userInfo;
-            this.type = type;
-            this.poolType = poolType;
-        }
-    }
-
-    private KVMHAMonitor _haMonitor;
-    private final Map<String, StoragePoolInformation> _storagePools = new ConcurrentHashMap<String, StoragePoolInformation>();
-    private final Map<String, StorageAdaptor> _storageMapper = new HashMap<String, StorageAdaptor>();
-
-    private StorageAdaptor getStorageAdaptor(StoragePoolType type) {
-        // type can be null: LibVirtComputingResource:3238
-        if (type == null) {
-            return _storageMapper.get("libvirt");
-        }
-        StorageAdaptor adaptor = _storageMapper.get(type.toString());
-        if (adaptor == null) {
-            // LibvirtStorageAdaptor is selected by default
-            adaptor = _storageMapper.get("libvirt");
-        }
-        return adaptor;
-    }
-
-    private void addStoragePool(String uuid, StoragePoolInformation pool) {
-        synchronized (_storagePools) {
-            if (!_storagePools.containsKey(uuid)) {
-                _storagePools.put(uuid, pool);
-            }
-        }
-    }
-
-    public KVMStoragePoolManager(StorageLayer storagelayer, KVMHAMonitor monitor) {
-        this._haMonitor = monitor;
-        this._storageMapper.put("libvirt", new LibvirtStorageAdaptor(storagelayer));
-        // add other storage adaptors here
-        // this._storageMapper.put("newadaptor", new NewStorageAdaptor(storagelayer));
-        this._storageMapper.put(StoragePoolType.ManagedNFS.toString(), new ManagedNfsStorageAdaptor(storagelayer));
-
-        // add any adaptors that wish to register themselves via annotation
-        Reflections reflections = new Reflections("com.cloud.hypervisor.kvm.storage");
-        Set<Class<? extends StorageAdaptor>> storageAdaptors = reflections.getSubTypesOf(StorageAdaptor.class);
-        for (Class<? extends StorageAdaptor> storageAdaptor : storageAdaptors) {
-            StorageAdaptorInfo info = storageAdaptor.getAnnotation(StorageAdaptorInfo.class);
-            if (info != null && info.storagePoolType() != null) {
-                if (this._storageMapper.containsKey(info.storagePoolType().toString())) {
-                    s_logger.error("Duplicate StorageAdaptor type " + info.storagePoolType().toString() + ", not loading " + storageAdaptor.getName());
-                } else {
-                    try {
-                        this._storageMapper.put(info.storagePoolType().toString(), storageAdaptor.newInstance());
-                    } catch (Exception ex) {
-                       throw new CloudRuntimeException(ex.toString());
-                    }
-                }
-            }
-        }
-
-        for (Map.Entry<String, StorageAdaptor> adaptors : this._storageMapper.entrySet()) {
-            s_logger.debug("Registered a StorageAdaptor for " + adaptors.getKey());
-        }
-    }
-
-    public boolean connectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath, Map<String, String> details) {
-        StorageAdaptor adaptor = getStorageAdaptor(type);
-        KVMStoragePool pool = adaptor.getStoragePool(poolUuid);
-
-        return adaptor.connectPhysicalDisk(volPath, pool, details);
-    }
-
-    public boolean connectPhysicalDisksViaVmSpec(VirtualMachineTO vmSpec) {
-        boolean result = false;
-
-        final String vmName = vmSpec.getName();
-
-        List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
-
-        for (DiskTO disk : disks) {
-            if (disk.getType() != Volume.Type.ISO) {
-                VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
-                PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore();
-                KVMStoragePool pool = getStoragePool(store.getPoolType(), store.getUuid());
-
-                StorageAdaptor adaptor = getStorageAdaptor(pool.getType());
-
-                result = adaptor.connectPhysicalDisk(vol.getPath(), pool, disk.getDetails());
-
-                if (!result) {
-                    s_logger.error("Failed to connect disks via vm spec for vm: " + vmName + " volume:" + vol.toString());
-
-                    return result;
-                }
-            }
-        }
-
-        return result;
-    }
-
-    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
-        for (Map.Entry<String, StorageAdaptor> set : _storageMapper.entrySet()) {
-            StorageAdaptor adaptor = set.getValue();
-
-            if (adaptor.disconnectPhysicalDisk(volumeToDisconnect)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public boolean disconnectPhysicalDiskByPath(String path) {
-        for (Map.Entry<String, StorageAdaptor> set : _storageMapper.entrySet()) {
-            StorageAdaptor adaptor = set.getValue();
-
-            if (adaptor.disconnectPhysicalDiskByPath(path)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public boolean disconnectPhysicalDisksViaVmSpec(VirtualMachineTO vmSpec) {
-        if (vmSpec == null) {
-            /* CloudStack often tries to stop VMs that shouldn't be running, to ensure a known state,
-               for example if we lose communication with the agent and the VM is brought up elsewhere.
-               We may not know about these yet. This might mean that we can't use the vmspec map, because
-               when we restart the agent we lose all of the info about running VMs. */
-
-            s_logger.debug("disconnectPhysicalDiskViaVmSpec: Attempted to stop a VM that is not yet in our hash map");
-
-            return true;
-        }
-
-        boolean result = true;
-
-        final String vmName = vmSpec.getName();
-
-        List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
-
-        for (DiskTO disk : disks) {
-            if (disk.getType() != Volume.Type.ISO) {
-                s_logger.debug("Disconnecting disk " + disk.getPath());
-
-                VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
-                PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore();
-
-                KVMStoragePool pool = getStoragePool(store.getPoolType(), store.getUuid());
-
-                if (pool == null) {
-                    s_logger.error("Pool " + store.getUuid() + " of type " + store.getPoolType() + " was not found, skipping disconnect logic");
-                    continue;
-                }
-
-                StorageAdaptor adaptor = getStorageAdaptor(pool.getType());
-
-                // if a disk fails to disconnect, still try to disconnect remaining
-
-                boolean subResult = adaptor.disconnectPhysicalDisk(vol.getPath(), pool);
-
-                if (!subResult) {
-                    s_logger.error("Failed to disconnect disks via vm spec for vm: " + vmName + " volume:" + vol.toString());
-
-                    result = false;
-                }
-            }
-        }
-
-        return result;
-    }
-
-    public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
-        return this.getStoragePool(type, uuid, false);
-    }
-
-    public KVMStoragePool getStoragePool(StoragePoolType type, String uuid, boolean refreshInfo) {
-
-        StorageAdaptor adaptor = getStorageAdaptor(type);
-        KVMStoragePool pool = null;
-        try {
-            pool = adaptor.getStoragePool(uuid, refreshInfo);
-        } catch (Exception e) {
-            StoragePoolInformation info = _storagePools.get(uuid);
-            if (info != null) {
-                pool = createStoragePool(info.name, info.host, info.port, info.path, info.userInfo, info.poolType, info.type);
-            } else {
-                throw new CloudRuntimeException("Could not fetch storage pool " + uuid + " from libvirt");
-            }
-        }
-        return pool;
-    }
-
-    public KVMStoragePool getStoragePoolByURI(String uri) {
-        URI storageUri = null;
-
-        try {
-            storageUri = new URI(uri);
-        } catch (URISyntaxException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-
-        String sourcePath = null;
-        String uuid = null;
-        String sourceHost = "";
-        StoragePoolType protocol = null;
-        if (storageUri.getScheme().equalsIgnoreCase("nfs") || storageUri.getScheme().equalsIgnoreCase("NetworkFilesystem")) {
-            sourcePath = storageUri.getPath();
-            sourcePath = sourcePath.replace("//", "/");
-            sourceHost = storageUri.getHost();
-            uuid = UUID.nameUUIDFromBytes(new String(sourceHost + sourcePath).getBytes()).toString();
-            protocol = StoragePoolType.NetworkFilesystem;
-        }
-
-        // secondary storage registers itself through here
-        return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocol, false);
-    }
-
-    public KVMPhysicalDisk getPhysicalDisk(StoragePoolType type, String poolUuid, String volName) {
-        int cnt = 0;
-        int retries = 10;
-        KVMPhysicalDisk vol = null;
-        //harden get volume, try cnt times to get volume, in case volume is created on other host
-        String errMsg = "";
-        while (cnt < retries) {
-            try {
-                KVMStoragePool pool = getStoragePool(type, poolUuid);
-                vol = pool.getPhysicalDisk(volName);
-                if (vol != null) {
-                    break;
-                }
-            } catch (Exception e) {
-                s_logger.debug("Failed to find volume:" + volName + " due to" + e.toString() + ", retry:" + cnt);
-                errMsg = e.toString();
-            }
-
-            try {
-                Thread.sleep(30000);
-            } catch (InterruptedException e) {
-                s_logger.debug("[ignored] interupted while trying to get storage pool.");
-            }
-            cnt++;
-        }
-
-        if (vol == null) {
-            throw new CloudRuntimeException(errMsg);
-        } else {
-            return vol;
-        }
-
-    }
-
-    public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type) {
-        // primary storage registers itself through here
-        return createStoragePool(name, host, port, path, userInfo, type, true);
-    }
-
-    //Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced.
-    private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, boolean primaryStorage) {
-        StorageAdaptor adaptor = getStorageAdaptor(type);
-        KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type);
-
-        // LibvirtStorageAdaptor-specific statement
-        if (type == StoragePoolType.NetworkFilesystem && primaryStorage) {
-            KVMHABase.NfsStoragePool nfspool = new KVMHABase.NfsStoragePool(pool.getUuid(), host, path, pool.getLocalPath(), PoolType.PrimaryStorage);
-            _haMonitor.addStoragePool(nfspool);
-        }
-        StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, primaryStorage);
-        addStoragePool(pool.getUuid(), info);
-        return pool;
-    }
-
-    public boolean disconnectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath) {
-        StorageAdaptor adaptor = getStorageAdaptor(type);
-        KVMStoragePool pool = adaptor.getStoragePool(poolUuid);
-
-        return adaptor.disconnectPhysicalDisk(volPath, pool);
-    }
-
-    public boolean deleteStoragePool(StoragePoolType type, String uuid) {
-        StorageAdaptor adaptor = getStorageAdaptor(type);
-        _haMonitor.removeStoragePool(uuid);
-        adaptor.deleteStoragePool(uuid);
-        synchronized (_storagePools) {
-            _storagePools.remove(uuid);
-        }
-        return true;
-    }
-
-    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, Storage.ProvisioningType provisioningType,
-                                                    KVMStoragePool destPool, int timeout) {
-        return createDiskFromTemplate(template, name, provisioningType, destPool, template.getSize(), timeout);
-    }
-
-    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, Storage.ProvisioningType provisioningType,
-                                                    KVMStoragePool destPool, long size, int timeout) {
-        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
-
-        // LibvirtStorageAdaptor-specific statement
-        if (destPool.getType() == StoragePoolType.RBD) {
-            return adaptor.createDiskFromTemplate(template, name,
-                    PhysicalDiskFormat.RAW, provisioningType,
-                    size, destPool, timeout);
-        } else if (destPool.getType() == StoragePoolType.CLVM) {
-            return adaptor.createDiskFromTemplate(template, name,
-                    PhysicalDiskFormat.RAW, provisioningType,
-                    size, destPool, timeout);
-        } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
-            return adaptor.createDiskFromTemplate(template, name,
-                    PhysicalDiskFormat.DIR, provisioningType,
-                    size, destPool, timeout);
-        } else {
-            return adaptor.createDiskFromTemplate(template, name,
-                    PhysicalDiskFormat.QCOW2, provisioningType,
-                    size, destPool, timeout);
-        }
-    }
-
-    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
-        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
-        return adaptor.createTemplateFromDisk(disk, name, format, size, destPool);
-    }
-
-    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
-        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
-        return adaptor.copyPhysicalDisk(disk, name, destPool, timeout);
-    }
-
-    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
-        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
-        return adaptor.createDiskFromSnapshot(snapshot, snapshotName, name, destPool);
-    }
-
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
deleted file mode 100644
index 53a2278..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ /dev/null
@@ -1,1659 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.hypervisor.kvm.storage;
-
-import static com.cloud.utils.storage.S3.S3Utils.putFile;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.text.DateFormat;
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import com.cloud.agent.direct.download.DirectTemplateDownloader;
-import com.cloud.agent.direct.download.DirectTemplateDownloader.DirectTemplateInformation;
-import com.cloud.agent.direct.download.HttpDirectTemplateDownloader;
-import com.cloud.agent.direct.download.MetalinkDirectTemplateDownloader;
-import com.cloud.agent.direct.download.NfsDirectTemplateDownloader;
-import com.cloud.agent.direct.download.HttpsDirectTemplateDownloader;
-import com.cloud.exception.InvalidParameterValueException;
-import org.apache.cloudstack.agent.directdownload.HttpsDirectDownloadCommand;
-import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
-import org.apache.cloudstack.agent.directdownload.HttpDirectDownloadCommand;
-import org.apache.cloudstack.agent.directdownload.MetalinkDirectDownloadCommand;
-import org.apache.cloudstack.agent.directdownload.NfsDirectDownloadCommand;
-import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DettachAnswer;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.command.ForgetObjectCmd;
-import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
-import org.apache.cloudstack.storage.command.ResignatureAnswer;
-import org.apache.cloudstack.storage.command.ResignatureCommand;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.qemu.QemuImg;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-import org.apache.cloudstack.utils.qemu.QemuImgException;
-import org.apache.cloudstack.utils.qemu.QemuImgFile;
-import org.apache.commons.io.FileUtils;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainInfo;
-import org.libvirt.DomainSnapshot;
-import org.libvirt.LibvirtException;
-
-import com.ceph.rados.IoCTX;
-import com.ceph.rados.Rados;
-import com.ceph.rados.exceptions.ErrorCode;
-import com.ceph.rados.exceptions.RadosException;
-import com.ceph.rbd.Rbd;
-import com.ceph.rbd.RbdException;
-import com.ceph.rbd.RbdImage;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
-import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DeviceType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiscardType;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiskProtocol;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.resource.StorageProcessor;
-import com.cloud.storage.template.Processor;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.QCOW2Processor;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.storage.S3.S3Utils;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-public class KVMStorageProcessor implements StorageProcessor {
-    private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class);
-    private final KVMStoragePoolManager storagePoolMgr;
-    private final LibvirtComputingResource resource;
-    private StorageLayer storageLayer;
-    private String _createTmplPath;
-    private String _manageSnapshotPath;
-    private int _cmdsTimeout;
-
-    public KVMStorageProcessor(final KVMStoragePoolManager storagePoolMgr, final LibvirtComputingResource resource) {
-        this.storagePoolMgr = storagePoolMgr;
-        this.resource = resource;
-    }
-
-    protected String getDefaultStorageScriptsDir() {
-        return "scripts/storage/qcow2";
-    }
-
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        storageLayer = new JavaStorageLayer();
-        storageLayer.configure("StorageLayer", params);
-
-        String storageScriptsDir = (String)params.get("storage.scripts.dir");
-        if (storageScriptsDir == null) {
-            storageScriptsDir = getDefaultStorageScriptsDir();
-        }
-
-        _createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh");
-        if (_createTmplPath == null) {
-            throw new ConfigurationException("Unable to find the createtmplt.sh");
-        }
-
-        _manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh");
-        if (_manageSnapshotPath == null) {
-            throw new ConfigurationException("Unable to find the managesnapshot.sh");
-        }
-
-        final String value = (String)params.get("cmds.timeout");
-        _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000;
-        return true;
-    }
-
-    @Override
-    public SnapshotAndCopyAnswer snapshotAndCopy(final SnapshotAndCopyCommand cmd) {
-        s_logger.info("'SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand)' not currently used for KVMStorageProcessor");
-
-        return new SnapshotAndCopyAnswer();
-    }
-
-    @Override
-    public ResignatureAnswer resignature(final ResignatureCommand cmd) {
-        s_logger.info("'ResignatureAnswer resignature(ResignatureCommand)' not currently used for KVMStorageProcessor");
-
-        return new ResignatureAnswer();
-    }
-
-    @Override
-    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final TemplateObjectTO template = (TemplateObjectTO)srcData;
-        final DataStoreTO imageStore = template.getDataStore();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destData.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        final NfsTO nfsImageStore = (NfsTO)imageStore;
-        final String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath();
-        final int index = tmplturl.lastIndexOf("/");
-        final String mountpoint = tmplturl.substring(0, index);
-        String tmpltname = null;
-        if (index < tmplturl.length() - 1) {
-            tmpltname = tmplturl.substring(index + 1);
-        }
-
-        KVMPhysicalDisk tmplVol = null;
-        KVMStoragePool secondaryPool = null;
-        try {
-            secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
-
-            /* Get template vol */
-            if (tmpltname == null) {
-                secondaryPool.refresh();
-                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
-                if (disks == null || disks.isEmpty()) {
-                    return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid());
-                }
-                for (final KVMPhysicalDisk disk : disks) {
-                    if (disk.getName().endsWith("qcow2")) {
-                        tmplVol = disk;
-                        break;
-                    }
-                }
-            } else {
-                tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
-            }
-
-            if (tmplVol == null) {
-                return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
-            }
-
-            /* Copy volume to primary storage */
-            s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
-            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-
-            KVMPhysicalDisk primaryVol = null;
-            if (destData instanceof VolumeObjectTO) {
-                final VolumeObjectTO volume = (VolumeObjectTO)destData;
-                // pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
-                if (volume.getSize() != null && volume.getSize() > tmplVol.getVirtualSize()) {
-                    s_logger.debug("Using configured size of " + volume.getSize());
-                    tmplVol.setSize(volume.getSize());
-                    tmplVol.setVirtualSize(volume.getSize());
-                } else {
-                    s_logger.debug("Using template's size of " + tmplVol.getVirtualSize());
-                }
-                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
-            } else if (destData instanceof TemplateObjectTO) {
-                TemplateObjectTO destTempl = (TemplateObjectTO)destData;
-
-                Map<String, String> details = primaryStore.getDetails();
-
-                String path = details != null ? details.get("managedStoreTarget") : null;
-
-                storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
-
-                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
-
-                storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
-            } else {
-                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, cmd.getWaitInMillSeconds());
-            }
-
-            DataTO data = null;
-            /**
-             * Force the ImageFormat for RBD templates to RAW
-             *
-             */
-            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-                final TemplateObjectTO newTemplate = new TemplateObjectTO();
-                newTemplate.setPath(primaryVol.getName());
-                newTemplate.setSize(primaryVol.getSize());
-                if (primaryPool.getType() == StoragePoolType.RBD) {
-                    newTemplate.setFormat(ImageFormat.RAW);
-                } else {
-                    newTemplate.setFormat(ImageFormat.QCOW2);
-                }
-                data = newTemplate;
-            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
-                final VolumeObjectTO volumeObjectTO = new VolumeObjectTO();
-                volumeObjectTO.setPath(primaryVol.getName());
-                volumeObjectTO.setSize(primaryVol.getSize());
-                if (primaryVol.getFormat() == PhysicalDiskFormat.RAW) {
-                    volumeObjectTO.setFormat(ImageFormat.RAW);
-                } else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
-                    volumeObjectTO.setFormat(ImageFormat.QCOW2);
-                }
-                data = volumeObjectTO;
-            }
-            return new CopyCmdAnswer(data);
-        } catch (final CloudRuntimeException e) {
-            return new CopyCmdAnswer(e.toString());
-        } finally {
-            try {
-                if (secondaryPool != null) {
-                    secondaryPool.delete();
-                }
-            } catch(final Exception e) {
-                s_logger.debug("Failed to clean up secondary storage", e);
-            }
-        }
-    }
-
-    // this is much like PrimaryStorageDownloadCommand, but keeping it separate. copies template direct to root disk
-    private KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid, final Long size, final int timeout) {
-        final int index = templateUrl.lastIndexOf("/");
-        final String mountpoint = templateUrl.substring(0, index);
-        String templateName = null;
-        if (index < templateUrl.length() - 1) {
-            templateName = templateUrl.substring(index + 1);
-        }
-
-        KVMPhysicalDisk templateVol = null;
-        KVMStoragePool secondaryPool = null;
-        try {
-            secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
-            /* Get template vol */
-            if (templateName == null) {
-                secondaryPool.refresh();
-                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
-                if (disks == null || disks.isEmpty()) {
-                    s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
-                    return null;
-                }
-                for (final KVMPhysicalDisk disk : disks) {
-                    if (disk.getName().endsWith("qcow2")) {
-                        templateVol = disk;
-                        break;
-                    }
-                }
-                if (templateVol == null) {
-                    s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
-                    return null;
-                }
-            } else {
-                templateVol = secondaryPool.getPhysicalDisk(templateName);
-            }
-
-            /* Copy volume to primary storage */
-
-            if (size > templateVol.getSize()) {
-                s_logger.debug("Overriding provided template's size with new size " + size);
-                templateVol.setSize(size);
-                templateVol.setVirtualSize(size);
-            } else {
-                s_logger.debug("Using templates disk size of " + templateVol.getVirtualSize() + "since size passed was " + size);
-            }
-
-            final KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
-            return primaryVol;
-        } catch (final CloudRuntimeException e) {
-            s_logger.error("Failed to download template to primary storage", e);
-            return null;
-        } finally {
-            if (secondaryPool != null) {
-                secondaryPool.delete();
-            }
-        }
-    }
-
-    @Override
-    public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final TemplateObjectTO template = (TemplateObjectTO)srcData;
-        final DataStoreTO imageStore = template.getDataStore();
-        final VolumeObjectTO volume = (VolumeObjectTO)destData;
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
-        KVMPhysicalDisk BaseVol = null;
-        KVMStoragePool primaryPool = null;
-        KVMPhysicalDisk vol = null;
-
-        try {
-            primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-
-            String templatePath = template.getPath();
-
-            if (primaryPool.getType() == StoragePoolType.CLVM) {
-                templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
-                vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
-            } else {
-                if (templatePath.contains("/mnt")) {
-                    //upgrade issue, if the path contains path, need to extract the volume uuid from path
-                    templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
-                }
-                BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
-                vol = storagePoolMgr.createDiskFromTemplate(BaseVol, volume.getUuid(), volume.getProvisioningType(),
-                        BaseVol.getPool(), volume.getSize(), cmd.getWaitInMillSeconds());
-            }
-            if (vol == null) {
-                return new CopyCmdAnswer(" Can't create storage volume on storage pool");
-            }
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(vol.getName());
-            newVol.setSize(volume.getSize());
-
-            if (vol.getFormat() == PhysicalDiskFormat.RAW) {
-                newVol.setFormat(ImageFormat.RAW);
-            } else if (vol.getFormat() == PhysicalDiskFormat.QCOW2) {
-                newVol.setFormat(ImageFormat.QCOW2);
-            } else if (vol.getFormat() == PhysicalDiskFormat.DIR) {
-                newVol.setFormat(ImageFormat.DIR);
-            }
-
-            return new CopyCmdAnswer(newVol);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to create volume: ", e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final DataStoreTO srcStore = srcData.getDataStore();
-        final DataStoreTO destStore = destData.getDataStore();
-        final VolumeObjectTO srcVol = (VolumeObjectTO)srcData;
-        final ImageFormat srcFormat = srcVol.getFormat();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destStore;
-        if (!(srcStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("can only handle nfs storage");
-        }
-        final NfsTO nfsStore = (NfsTO)srcStore;
-        final String srcVolumePath = srcData.getPath();
-        final String secondaryStorageUrl = nfsStore.getUrl();
-        KVMStoragePool secondaryStoragePool = null;
-        KVMStoragePool primaryPool = null;
-        try {
-            try {
-                primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-            } catch (final CloudRuntimeException e) {
-                if (e.getMessage().contains("not found")) {
-                    primaryPool =
-                            storagePoolMgr.createStoragePool(primaryStore.getUuid(), primaryStore.getHost(), primaryStore.getPort(), primaryStore.getPath(), null,
-                                    primaryStore.getPoolType());
-                } else {
-                    return new CopyCmdAnswer(e.getMessage());
-                }
-            }
-
-            Map<String, String> details = cmd.getOptions2();
-
-            String path = details != null ? details.get(DiskTO.IQN) : null;
-
-            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
-
-            final String volumeName = UUID.randomUUID().toString();
-
-            final int index = srcVolumePath.lastIndexOf(File.separator);
-            final String volumeDir = srcVolumePath.substring(0, index);
-            String srcVolumeName = srcVolumePath.substring(index + 1);
-
-            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + File.separator + volumeDir);
-
-            if (!srcVolumeName.endsWith(".qcow2") && srcFormat == ImageFormat.QCOW2) {
-                srcVolumeName = srcVolumeName + ".qcow2";
-            }
-
-            final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(srcVolumeName);
-
-            volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
-
-            final KVMPhysicalDisk newDisk = storagePoolMgr.copyPhysicalDisk(volume, path != null ? path : volumeName, primaryPool, cmd.getWaitInMillSeconds());
-
-            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-
-            newVol.setFormat(ImageFormat.valueOf(newDisk.getFormat().toString().toUpperCase()));
-            newVol.setPath(path != null ? path : volumeName);
-
-            return new CopyCmdAnswer(newVol);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to copyVolumeFromImageCacheToPrimary: ", e);
-
-            return new CopyCmdAnswer(e.toString());
-        } finally {
-            if (secondaryStoragePool != null) {
-                storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
-            }
-        }
-    }
-
-    @Override
-    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final VolumeObjectTO srcVol = (VolumeObjectTO)srcData;
-        final VolumeObjectTO destVol = (VolumeObjectTO)destData;
-        final ImageFormat srcFormat = srcVol.getFormat();
-        final ImageFormat destFormat = destVol.getFormat();
-        final DataStoreTO srcStore = srcData.getDataStore();
-        final DataStoreTO destStore = destData.getDataStore();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcStore;
-        if (!(destStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("can only handle nfs storage");
-        }
-        final NfsTO nfsStore = (NfsTO)destStore;
-        final String srcVolumePath = srcData.getPath();
-        final String destVolumePath = destData.getPath();
-        final String secondaryStorageUrl = nfsStore.getUrl();
-        KVMStoragePool secondaryStoragePool = null;
-
-        try {
-            final String volumeName = UUID.randomUUID().toString();
-
-            final String destVolumeName = volumeName + "." + destFormat.getFileExtension();
-            final KVMPhysicalDisk volume = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), srcVolumePath);
-            volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
-
-            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl);
-            secondaryStoragePool.createFolder(destVolumePath);
-            storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
-            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + File.separator + destVolumePath);
-            storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, secondaryStoragePool, cmd.getWaitInMillSeconds());
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(destVolumePath + File.separator + destVolumeName);
-            newVol.setFormat(destFormat);
-            return new CopyCmdAnswer(newVol);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to copyVolumeFromPrimaryToSecondary: ", e);
-            return new CopyCmdAnswer(e.toString());
-        } finally {
-            if (secondaryStoragePool != null) {
-                storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
-            }
-        }
-    }
-
-    @Override
-    public Answer createTemplateFromVolume(final CopyCommand cmd) {
-        Map<String, String> details = cmd.getOptions();
-
-        if (details != null && details.get(DiskTO.IQN) != null) {
-            // use the managed-storage approach
-            return createTemplateFromVolumeOrSnapshot(cmd);
-        }
-
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWaitInMillSeconds();
-        final TemplateObjectTO template = (TemplateObjectTO)destData;
-        final DataStoreTO imageStore = template.getDataStore();
-        final VolumeObjectTO volume = (VolumeObjectTO)srcData;
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-        final NfsTO nfsImageStore = (NfsTO)imageStore;
-
-        KVMStoragePool secondaryStorage = null;
-        KVMStoragePool primary;
-
-        try {
-            final String templateFolder = template.getPath();
-
-            secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl());
-
-            primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-
-            final KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
-            final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder;
-            storageLayer.mkdirs(tmpltPath);
-            final String templateName = UUID.randomUUID().toString();
-
-            if (primary.getType() != StoragePoolType.RBD) {
-                final Script command = new Script(_createTmplPath, wait, s_logger);
-                command.add("-f", disk.getPath());
-                command.add("-t", tmpltPath);
-                command.add("-n", templateName + ".qcow2");
-
-                final String result = command.execute();
-
-                if (result != null) {
-                    s_logger.debug("failed to create template: " + result);
-                    return new CopyCmdAnswer(result);
-                }
-            } else {
-                s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + templateName);
-
-                final QemuImgFile srcFile =
-                        new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(),
-                                primary.getAuthSecret(), disk.getPath()));
-                srcFile.setFormat(PhysicalDiskFormat.RAW);
-
-                final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2");
-                destFile.setFormat(PhysicalDiskFormat.QCOW2);
-
-                final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
-                try {
-                    q.convert(srcFile, destFile);
-                } catch (final QemuImgException e) {
-                    final String message = "Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " +
-                            e.getMessage();
-
-                    throw new QemuImgException(message);
-                }
-
-                final File templateProp = new File(tmpltPath + "/template.properties");
-                if (!templateProp.exists()) {
-                    templateProp.createNewFile();
-                }
-
-                String templateContent = "filename=" + templateName + ".qcow2" + System.getProperty("line.separator");
-
-                final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
-                final Date date = new Date();
-                templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
-
-
-                try(FileOutputStream templFo = new FileOutputStream(templateProp);){
-                    templFo.write(templateContent.getBytes());
-                    templFo.flush();
-                } catch (final IOException e) {
-                    throw e;
-                }
-            }
-
-            final Map<String, Object> params = new HashMap<String, Object>();
-            params.put(StorageLayer.InstanceConfigKey, storageLayer);
-            final Processor qcow2Processor = new QCOW2Processor();
-
-            qcow2Processor.configure("QCOW2 Processor", params);
-
-            final FormatInfo info = qcow2Processor.process(tmpltPath, null, templateName);
-
-            final TemplateLocation loc = new TemplateLocation(storageLayer, tmpltPath);
-            loc.create(1, true, templateName);
-            loc.addFormat(info);
-            loc.save();
-
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
-            newTemplate.setSize(info.virtualSize);
-            newTemplate.setPhysicalSize(info.size);
-            newTemplate.setFormat(ImageFormat.QCOW2);
-            newTemplate.setName(templateName);
-            return new CopyCmdAnswer(newTemplate);
-
-        } catch (final QemuImgException e) {
-            s_logger.error(e.getMessage());
-            return new CopyCmdAnswer(e.toString());
-        } catch (final IOException e) {
-            s_logger.debug("Failed to createTemplateFromVolume: ", e);
-            return new CopyCmdAnswer(e.toString());
-        } catch (final Exception e) {
-            s_logger.debug("Failed to createTemplateFromVolume: ", e);
-            return new CopyCmdAnswer(e.toString());
-        } finally {
-            if (secondaryStorage != null) {
-                secondaryStorage.delete();
-            }
-        }
-    }
-
-    @Override
-    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
-        Map<String, String> details = cmd.getOptions();
-
-        if (details != null && details.get(DiskTO.IQN) != null) {
-            // use the managed-storage approach
-            return createTemplateFromVolumeOrSnapshot(cmd);
-        }
-
-        return new CopyCmdAnswer("operation not supported");
-    }
-
-    private Answer createTemplateFromVolumeOrSnapshot(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-
-        final boolean isVolume;
-
-        if (srcData instanceof VolumeObjectTO) {
-            isVolume = true;
-        }
-        else if (srcData instanceof SnapshotObjectTO) {
-            isVolume = false;
-        }
-        else {
-            return new CopyCmdAnswer("unsupported object type");
-        }
-
-        PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore();
-
-        DataTO destData = cmd.getDestTO();
-        TemplateObjectTO template = (TemplateObjectTO)destData;
-        DataStoreTO imageStore = template.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        NfsTO nfsImageStore = (NfsTO)imageStore;
-
-        KVMStoragePool secondaryStorage = null;
-
-        try {
-            Map<String, String> details = cmd.getOptions();
-
-            String path = details != null ? details.get(DiskTO.IQN) : null;
-
-            if (path == null) {
-                new CloudRuntimeException("The 'path' field must be specified.");
-            }
-
-            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
-
-            KVMPhysicalDisk srcDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
-
-            secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl());
-
-            String templateFolder = template.getPath();
-            String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder;
-
-            storageLayer.mkdirs(tmpltPath);
-
-            String templateName = UUID.randomUUID().toString();
-
-            s_logger.debug("Converting " + srcDisk.getFormat().toString() + " disk " + srcDisk.getPath() + " into template " + templateName);
-
-            String destName = templateFolder + "/" + templateName + ".qcow2";
-
-            storagePoolMgr.copyPhysicalDisk(srcDisk, destName, secondaryStorage, cmd.getWaitInMillSeconds());
-
-            File templateProp = new File(tmpltPath + "/template.properties");
-
-            if (!templateProp.exists()) {
-                templateProp.createNewFile();
-            }
-
-            String templateContent = "filename=" + templateName + ".qcow2" + System.getProperty("line.separator");
-
-            DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
-            Date date = new Date();
-
-            if (isVolume) {
-                templateContent += "volume.name=" + dateFormat.format(date) + System.getProperty("line.separator");
-            }
-            else {
-                templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
-            }
-
-            FileOutputStream templFo = new FileOutputStream(templateProp);
-
-            templFo.write(templateContent.getBytes());
-            templFo.flush();
-            templFo.close();
-
-            Map<String, Object> params = new HashMap<>();
-
-            params.put(StorageLayer.InstanceConfigKey, storageLayer);
-
-            Processor qcow2Processor = new QCOW2Processor();
-
-            qcow2Processor.configure("QCOW2 Processor", params);
-
-            FormatInfo info = qcow2Processor.process(tmpltPath, null, templateName);
-
-            TemplateLocation loc = new TemplateLocation(storageLayer, tmpltPath);
-
-            loc.create(1, true, templateName);
-            loc.addFormat(info);
-            loc.save();
-
-            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
-
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
-            newTemplate.setSize(info.virtualSize);
-            newTemplate.setPhysicalSize(info.size);
-            newTemplate.setFormat(ImageFormat.QCOW2);
-            newTemplate.setName(templateName);
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (Exception ex) {
-            if (isVolume) {
-                s_logger.debug("Failed to create template from volume: ", ex);
-            }
-            else {
-                s_logger.debug("Failed to create template from snapshot: ", ex);
-            }
-
-            return new CopyCmdAnswer(ex.toString());
-        } finally {
-            if (secondaryStorage != null) {
-                secondaryStorage.delete();
-            }
-        }
-    }
-
-    protected String copyToS3(final File srcFile, final S3TO destStore, final String destPath) throws InterruptedException {
-        final String key = destPath + S3Utils.SEPARATOR + srcFile.getName();
-
-        putFile(destStore, srcFile, destStore.getBucketName(), key).waitForCompletion();
-
-        return key;
-    }
-
-    protected Answer copyToObjectStore(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final DataStoreTO imageStore = destData.getDataStore();
-        final NfsTO srcStore = (NfsTO)srcData.getDataStore();
-        final String srcPath = srcData.getPath();
-        final int index = srcPath.lastIndexOf(File.separator);
-        final String srcSnapshotDir = srcPath.substring(0, index);
-        final String srcFileName = srcPath.substring(index + 1);
-        KVMStoragePool srcStorePool = null;
-        File srcFile = null;
-        try {
-            srcStorePool = storagePoolMgr.getStoragePoolByURI(srcStore.getUrl() + File.separator + srcSnapshotDir);
-            if (srcStorePool == null) {
-                return new CopyCmdAnswer("Can't get store:" + srcStore.getUrl());
-            }
-            srcFile = new File(srcStorePool.getLocalPath() + File.separator + srcFileName);
-            if (!srcFile.exists()) {
-                return new CopyCmdAnswer("Can't find src file: " + srcPath);
-            }
-            String destPath = null;
-            if (imageStore instanceof S3TO) {
-                destPath = copyToS3(srcFile, (S3TO)imageStore, destData.getPath());
-            } else {
-                return new CopyCmdAnswer("Unsupported protocol");
-            }
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            newSnapshot.setPath(destPath);
-            return new CopyCmdAnswer(newSnapshot);
-        } catch (final Exception e) {
-            s_logger.error("failed to upload" + srcPath, e);
-            return new CopyCmdAnswer("failed to upload" + srcPath + e.toString());
-        } finally {
-            try {
-                if (srcFile != null) {
-                    srcFile.delete();
-                }
-                if (srcStorePool != null) {
-                    srcStorePool.delete();
-                }
-            } catch (final Exception e) {
-                s_logger.debug("Failed to clean up:", e);
-            }
-        }
-    }
-
-    protected Answer backupSnapshotForObjectStore(final CopyCommand cmd) {
-        final DataTO destData = cmd.getDestTO();
-        final DataStoreTO imageStore = destData.getDataStore();
-        final DataTO cacheData = cmd.getCacheTO();
-        if (cacheData == null) {
-            return new CopyCmdAnswer("Failed to copy to object store without cache store");
-        }
-        final DataStoreTO cacheStore = cacheData.getDataStore();
-        ((SnapshotObjectTO)destData).setDataStore(cacheStore);
-        final CopyCmdAnswer answer = (CopyCmdAnswer)backupSnapshot(cmd);
-        if (!answer.getResult()) {
-            return answer;
-        }
-        final SnapshotObjectTO snapshotOnCacheStore = (SnapshotObjectTO)answer.getNewData();
-        snapshotOnCacheStore.setDataStore(cacheStore);
-        ((SnapshotObjectTO)destData).setDataStore(imageStore);
-        final CopyCommand newCpyCmd = new   CopyCommand(snapshotOnCacheStore, destData, cmd.getWaitInMillSeconds(), cmd.executeInSequence());
-        return copyToObjectStore(newCpyCmd);
-    }
-
-    @Override
-    public Answer backupSnapshot(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshot.getDataStore();
-        final SnapshotObjectTO destSnapshot = (SnapshotObjectTO)destData;
-        final DataStoreTO imageStore = destData.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return backupSnapshotForObjectStore(cmd);
-        }
-        final NfsTO nfsImageStore = (NfsTO)imageStore;
-
-        final String secondaryStoragePoolUrl = nfsImageStore.getUrl();
-        // NOTE: snapshot name is encoded in snapshot path
-        final int index = snapshot.getPath().lastIndexOf("/");
-        final boolean isCreatedFromVmSnapshot = (index == -1) ? true: false; // -1 means the snapshot is created from existing vm snapshot
-
-        final String snapshotName = snapshot.getPath().substring(index + 1);
-        String descName = snapshotName;
-        final String volumePath = snapshot.getVolume().getPath();
-        String snapshotDestPath = null;
-        String snapshotRelPath = null;
-        final String vmName = snapshot.getVmName();
-        KVMStoragePool secondaryStoragePool = null;
-        Connect conn = null;
-        KVMPhysicalDisk snapshotDisk = null;
-        KVMStoragePool primaryPool = null;
-        try {
-            conn = LibvirtConnection.getConnectionByVmName(vmName);
-
-            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
-
-            final String ssPmountPath = secondaryStoragePool.getLocalPath();
-            snapshotRelPath = destSnapshot.getPath();
-
-            snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
-            snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
-            primaryPool = snapshotDisk.getPool();
-
-            long size = 0;
-            /**
-             * Since Ceph version Dumpling (0.67.X) librbd / Qemu supports converting RBD
-             * snapshots to RAW/QCOW2 files directly.
-             *
-             * This reduces the amount of time and storage it takes to back up a snapshot dramatically
-             */
-            if (primaryPool.getType() == StoragePoolType.RBD) {
-                final String rbdSnapshot = snapshotDisk.getPath() +  "@" + snapshotName;
-                final String snapshotFile = snapshotDestPath + "/" + snapshotName;
-                try {
-                    s_logger.debug("Attempting to backup RBD snapshot " + rbdSnapshot);
-
-                    final File snapDir = new File(snapshotDestPath);
-                    s_logger.debug("Attempting to create " + snapDir.getAbsolutePath() + " recursively for snapshot storage");
-                    FileUtils.forceMkdir(snapDir);
-
-                    final QemuImgFile srcFile =
-                            new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool.getSourceHost(), primaryPool.getSourcePort(), primaryPool.getAuthUserName(),
-                                    primaryPool.getAuthSecret(), rbdSnapshot));
-                    srcFile.setFormat(snapshotDisk.getFormat());
-
-                    final QemuImgFile destFile = new QemuImgFile(snapshotFile);
-                    destFile.setFormat(PhysicalDiskFormat.QCOW2);
-
-                    s_logger.debug("Backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile);
-                    final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
-                    q.convert(srcFile, destFile);
-
-                    final File snapFile = new File(snapshotFile);
-                    if(snapFile.exists()) {
-                        size = snapFile.length();
-                    }
-
-                    s_logger.debug("Finished backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile + " Snapshot size: " + size);
-                } catch (final FileNotFoundException e) {
-                    s_logger.error("Failed to open " + snapshotDestPath + ". The error was: " + e.getMessage());
-                    return new CopyCmdAnswer(e.toString());
-                } catch (final IOException e) {
-                    s_logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
-                    return new CopyCmdAnswer(e.toString());
-                }  catch (final QemuImgException e) {
-                    s_logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot +
-                            " to " + snapshotFile + " the error was: " + e.getMessage());
-                    return new CopyCmdAnswer(e.toString());
-                }
-            } else {
-                final Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
-                command.add("-b", snapshotDisk.getPath());
-                command.add("-n", snapshotName);
-                command.add("-p", snapshotDestPath);
-                if (isCreatedFromVmSnapshot) {
-                    descName = UUID.randomUUID().toString();
-                }
-                command.add("-t", descName);
-                final String result = command.execute();
-                if (result != null) {
-                    s_logger.debug("Failed to backup snaptshot: " + result);
-                    return new CopyCmdAnswer(result);
-                }
-                final File snapFile = new File(snapshotDestPath + "/" + descName);
-                if(snapFile.exists()){
-                    size = snapFile.length();
-                }
-            }
-
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            newSnapshot.setPath(snapshotRelPath + File.separator + descName);
-            newSnapshot.setPhysicalSize(size);
-            return new CopyCmdAnswer(newSnapshot);
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to backup snapshot: ", e);
-            return new CopyCmdAnswer(e.toString());
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to backup snapshot: ", e);
-            return new CopyCmdAnswer(e.toString());
-        } finally {
-            if (isCreatedFromVmSnapshot) {
-                s_logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
-            } else {
-                try {
-                    /* Delete the snapshot on primary */
-                    DomainInfo.DomainState state = null;
-                    Domain vm = null;
-                    if (vmName != null) {
-                        try {
-                            vm = resource.getDomain(conn, vmName);
-                            state = vm.getInfo().state;
-                        } catch (final LibvirtException e) {
-                            s_logger.trace("Ignoring libvirt error.", e);
-                        }
-                    }
-
-                    final KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(primaryStore.getPoolType(),
-                            primaryStore.getUuid());
-                    if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
-                        final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
-                        try {
-                            vm.suspend();
-                        } catch(final Exception e) {
-                            s_logger.debug("Failed to suspend the VM: " + e);
-                            throw e;
-                        }
-                        snap.delete(0);
-
-                        /*
-                         * libvirt on RHEL6 doesn't handle resume event emitted from
-                         * qemu
-                         */
-                        vm = resource.getDomain(conn, vmName);
-                        state = vm.getInfo().state;
-                        if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
-                            vm.resume();
-                        }
-                    } else {
-                        if (primaryPool.getType() != StoragePoolType.RBD) {
-                            final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
-                            command.add("-d", snapshotDisk.getPath());
-                            command.add("-n", snapshotName);
-                            final String result = command.execute();
-                            if (result != null) {
-                                s_logger.debug("Failed to delete snapshot on primary: " + result);
-                                // return new CopyCmdAnswer("Failed to backup snapshot: " + result);
-                            }
-                        }
-                    }
-                } catch (final Exception ex) {
-                    s_logger.debug("Failed to delete snapshots on primary", ex);
-                }
-            }
-
-            try {
-                if (secondaryStoragePool != null) {
-                    secondaryStoragePool.delete();
-                }
-            } catch (final Exception ex) {
-                s_logger.debug("Failed to delete secondary storage", ex);
-            }
-        }
-    }
-
-    protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException,
-    InternalErrorException {
-        String isoXml = null;
-        if (isoPath != null && isAttach) {
-            final int index = isoPath.lastIndexOf("/");
-            final String path = isoPath.substring(0, index);
-            final String name = isoPath.substring(index + 1);
-            final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(path);
-            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
-            isoPath = isoVol.getPath();
-
-            final DiskDef iso = new DiskDef();
-            iso.defISODisk(isoPath);
-            isoXml = iso.toString();
-        } else {
-            final DiskDef iso = new DiskDef();
-            iso.defISODisk(null);
-            isoXml = iso.toString();
-        }
-
-        final List<DiskDef> disks = resource.getDisks(conn, vmName);
-        final String result = attachOrDetachDevice(conn, true, vmName, isoXml);
-        if (result == null && !isAttach) {
-            for (final DiskDef disk : disks) {
-                if (disk.getDeviceType() == DiskDef.DeviceType.CDROM) {
-                    resource.cleanupDisk(disk);
-                }
-            }
-
-        }
-        return result;
-    }
-
-    @Override
-    public Answer attachIso(final AttachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData();
-        final DataStoreTO store = isoTO.getDataStore();
-
-        try {
-            String dataStoreUrl = getDataStoreUrlFromStore(store);
-            final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
-            attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), true);
-        } catch (final LibvirtException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final URISyntaxException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final InternalErrorException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final InvalidParameterValueException e) {
-            return new Answer(cmd, false, e.toString());
-        }
-
-        return new Answer(cmd);
-    }
-
-    @Override
-    public Answer dettachIso(final DettachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData();
-        final DataStoreTO store = isoTO.getDataStore();
-
-        try {
-            String dataStoreUrl = getDataStoreUrlFromStore(store);
-            final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
-            attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), false);
-        } catch (final LibvirtException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final URISyntaxException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final InternalErrorException e) {
-            return new Answer(cmd, false, e.toString());
-        } catch (final InvalidParameterValueException e) {
-            return new Answer(cmd, false, e.toString());
-        }
-
-        return new Answer(cmd);
-    }
-
-    /**
-     * Return data store URL from store
-     */
-    private String getDataStoreUrlFromStore(DataStoreTO store) {
-        if (!(store instanceof NfsTO) && (!(store instanceof PrimaryDataStoreTO) ||
-                store instanceof PrimaryDataStoreTO && !((PrimaryDataStoreTO) store).getPoolType().equals(StoragePoolType.NetworkFilesystem))) {
-            throw new InvalidParameterValueException("unsupported protocol");
-        }
-
-        if (store instanceof NfsTO) {
-            NfsTO nfsStore = (NfsTO)store;
-            return nfsStore.getUrl();
-        } else if (store instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO) store).getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
-            //In order to support directly downloaded ISOs
-            String psHost = ((PrimaryDataStoreTO) store).getHost();
-            String psPath = ((PrimaryDataStoreTO) store).getPath();
-            return "nfs://" + psHost + File.separator + psPath;
-        }
-        return store.getUrl();
-    }
-
-    protected synchronized String attachOrDetachDevice(final Connect conn, final boolean attach, final String vmName, final String xml) throws LibvirtException, InternalErrorException {
-        Domain dm = null;
-        try {
-            dm = conn.domainLookupByName(vmName);
-
-            if (attach) {
-                s_logger.debug("Attaching device: " + xml);
-                dm.attachDevice(xml);
-            } else {
-                s_logger.debug("Detaching device: " + xml);
-                dm.detachDevice(xml);
-            }
-        } catch (final LibvirtException e) {
-            if (attach) {
-                s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage());
-            } else {
-                s_logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage());
-            }
-            throw e;
-        } finally {
-            if (dm != null) {
-                try {
-                    dm.free();
-                } catch (final LibvirtException l) {
-                    s_logger.trace("Ignoring libvirt error.", l);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    protected synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId, final String serial,
-            final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate) throws LibvirtException, InternalErrorException {
-        List<DiskDef> disks = null;
-        Domain dm = null;
-        DiskDef diskdef = null;
-        final KVMStoragePool attachingPool = attachingDisk.getPool();
-        try {
-            dm = conn.domainLookupByName(vmName);
-            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
-            final String domXml = dm.getXMLDesc(0);
-            parser.parseDomainXML(domXml);
-            disks = parser.getDisks();
-            if (!attach) {
-                if (attachingPool.getType() == StoragePoolType.RBD) {
-                    if (resource.getHypervisorType() == Hypervisor.HypervisorType.LXC) {
-                        final String device = resource.mapRbdDevice(attachingDisk);
-                        if (device != null) {
-                            s_logger.debug("RBD device on host is: "+device);
-                            attachingDisk.setPath(device);
-                        }
-                    }
-                }
-
-                for (final DiskDef disk : disks) {
-                    final String file = disk.getDiskPath();
-                    if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
-                        diskdef = disk;
-                        break;
-                    }
-                }
-                if (diskdef == null) {
-                    throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before");
-                }
-            } else {
-                DiskDef.DiskBus busT = DiskDef.DiskBus.VIRTIO;
-                for (final DiskDef disk : disks) {
-                    if (disk.getDeviceType() == DeviceType.DISK) {
-                        if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
-                            busT = DiskDef.DiskBus.SCSI;
-                        }
-                        break;
-                    }
-                }
-                diskdef = new DiskDef();
-                if (busT == DiskDef.DiskBus.SCSI) {
-                    diskdef.setQemuDriver(true);
-                    diskdef.setDiscard(DiscardType.UNMAP);
-                }
-                diskdef.setSerial(serial);
-                if (attachingPool.getType() == StoragePoolType.RBD) {
-                    if(resource.getHypervisorType() == Hypervisor.HypervisorType.LXC){
-                        // For LXC, map image to host and then attach to Vm
-                        final String device = resource.mapRbdDevice(attachingDisk);
-                        if (device != null) {
-                            s_logger.debug("RBD device on host is: "+device);
-                            diskdef.defBlockBasedDisk(device, devId, busT);
-                        } else {
-                            throw new InternalErrorException("Error while mapping disk "+attachingDisk.getPath()+" on host");
-                        }
-                    } else {
-                        diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), attachingPool.getAuthUserName(),
-                                attachingPool.getUuid(), devId, busT, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
-                    }
-                } else if (attachingPool.getType() == StoragePoolType.Gluster) {
-                    final String mountpoint = attachingPool.getLocalPath();
-                    final String path = attachingDisk.getPath();
-                    final String glusterVolume = attachingPool.getSourceDir().replace("/", "");
-                    diskdef.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), attachingPool.getSourceHost(), attachingPool.getSourcePort(), null,
-                            null, devId, busT, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
-                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
-                    diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
-                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
-                    diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
-                }
-
-                if ((bytesReadRate != null) && (bytesReadRate > 0)) {
-                    diskdef.setBytesReadRate(bytesReadRate);
-                }
-                if ((bytesWriteRate != null) && (bytesWriteRate > 0)) {
-                    diskdef.setBytesWriteRate(bytesWriteRate);
-                }
-                if ((iopsReadRate != null) && (iopsReadRate > 0)) {
-                    diskdef.setIopsReadRate(iopsReadRate);
-                }
-                if ((iopsWriteRate != null) && (iopsWriteRate > 0)) {
-                    diskdef.setIopsWriteRate(iopsWriteRate);
-                }
-            }
-
-            final String xml = diskdef.toString();
-            return attachOrDetachDevice(conn, attach, vmName, xml);
-        } finally {
-            if (dm != null) {
-                dm.free();
-            }
-        }
-    }
-
-    @Override
-    public Answer attachVolume(final AttachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
-        final String vmName = cmd.getVmName();
-        final String serial = resource.diskUuidToSerial(vol.getUuid());
-        try {
-            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
-
-            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath(), disk.getDetails());
-
-            final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
-
-            attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate());
-
-            return new AttachAnswer(disk);
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
-            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
-            return new AttachAnswer(e.toString());
-        } catch (final InternalErrorException e) {
-            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
-            return new AttachAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer dettachVolume(final DettachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
-        final String vmName = cmd.getVmName();
-        final String serial = resource.diskUuidToSerial(vol.getUuid());
-        try {
-            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
-
-            final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
-
-            attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate());
-
-            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
-
-            return new DettachAnswer(disk);
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
-            return new DettachAnswer(e.toString());
-        } catch (final InternalErrorException e) {
-            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
-            return new DettachAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer createVolume(final CreateObjectCommand cmd) {
-        final VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
-
-        KVMStoragePool primaryPool = null;
-        KVMPhysicalDisk vol = null;
-        long disksize;
-        try {
-            primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-            disksize = volume.getSize();
-            PhysicalDiskFormat format;
-            if (volume.getFormat() == null) {
-                format = primaryPool.getDefaultFormat();
-            } else {
-                format = PhysicalDiskFormat.valueOf(volume.getFormat().toString().toUpperCase());
-            }
-            vol = primaryPool.createPhysicalDisk(volume.getUuid(), format,
-                    volume.getProvisioningType(), disksize);
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            if(vol != null) {
-                newVol.setPath(vol.getName());
-            }
-            newVol.setSize(volume.getSize());
-            newVol.setFormat(ImageFormat.valueOf(format.toString().toUpperCase()));
-
-            return new CreateObjectAnswer(newVol);
-        } catch (final Exception e) {
-            s_logger.debug("Failed to create volume: ", e);
-            return new CreateObjectAnswer(e.toString());
-        }
-    }
-
-    protected static final MessageFormat SnapshotXML = new MessageFormat("   <domainsnapshot>" + "       <name>{0}</name>" + "          <domain>"
-            + "            <uuid>{1}</uuid>" + "        </domain>" + "    </domainsnapshot>");
-
-    @Override
-    public Answer createSnapshot(final CreateObjectCommand cmd) {
-        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)cmd.getData();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshotTO.getDataStore();
-        final VolumeObjectTO volume = snapshotTO.getVolume();
-        final String snapshotName = UUID.randomUUID().toString();
-        final String vmName = volume.getVmName();
-        try {
-            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
-            DomainInfo.DomainState state = null;
-            Domain vm = null;
-            if (vmName != null) {
-                try {
-                    vm = resource.getDomain(conn, vmName);
-                    state = vm.getInfo().state;
-                } catch (final LibvirtException e) {
-                    s_logger.trace("Ignoring libvirt error.", e);
-                }
-            }
-
-            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-
-            final KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
-            if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
-                final String vmUuid = vm.getUUIDString();
-                final Object[] args = new Object[] {snapshotName, vmUuid};
-                final String snapshot = SnapshotXML.format(args);
-
-                final long start = System.currentTimeMillis();
-                vm.snapshotCreateXML(snapshot);
-                final long total = (System.currentTimeMillis() - start)/1000;
-                s_logger.debug("snapshot takes " + total + " seconds to finish");
-
-                /*
-                 * libvirt on RHEL6 doesn't handle resume event emitted from
-                 * qemu
-                 */
-                vm = resource.getDomain(conn, vmName);
-                state = vm.getInfo().state;
-                if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
-                    vm.resume();
-                }
-            } else {
-                /**
-                 * For RBD we can't use libvirt to do our snapshotting or any Bash scripts.
-                 * libvirt also wants to store the memory contents of the Virtual Machine,
-                 * but that's not possible with RBD since there is no way to store the memory
-                 * contents in RBD.
-                 *
-                 * So we rely on the Java bindings for RBD to create our snapshot
-                 *
-                 * This snapshot might not be 100% consistent due to writes still being in the
-                 * memory of the Virtual Machine, but if the VM runs a kernel which supports
-                 * barriers properly (>2.6.32) this won't be any different then pulling the power
-                 * cord out of a running machine.
-                 */
-                if (primaryPool.getType() == StoragePoolType.RBD) {
-                    try {
-                        final Rados r = new Rados(primaryPool.getAuthUserName());
-                        r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
-                        r.confSet("key", primaryPool.getAuthSecret());
-                        r.confSet("client_mount_timeout", "30");
-                        r.connect();
-                        s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
-
-                        final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
-                        final Rbd rbd = new Rbd(io);
-                        final RbdImage image = rbd.open(disk.getName());
-
-                        s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName);
-                        image.snapCreate(snapshotName);
-
-                        rbd.close(image);
-                        r.ioCtxDestroy(io);
-                    } catch (final Exception e) {
-                        s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage());
-                    }
-                } else {
-                    /* VM is not running, create a snapshot by ourself */
-                    final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
-                    command.add("-c", disk.getPath());
-                    command.add("-n", snapshotName);
-                    final String result = command.execute();
-                    if (result != null) {
-                        s_logger.debug("Failed to manage snapshot: " + result);
-                        return new CreateObjectAnswer("Failed to manage snapshot: " + result);
-                    }
-                }
-            }
-
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            // NOTE: sort of hack, we'd better just put snapshtoName
-            newSnapshot.setPath(disk.getPath() + File.separator + snapshotName);
-            return new CreateObjectAnswer(newSnapshot);
-        } catch (final LibvirtException e) {
-            s_logger.debug("Failed to manage snapshot: ", e);
-            return new CreateObjectAnswer("Failed to manage snapshot: " + e.toString());
-        }
-    }
-
-    @Override
-    public Answer deleteVolume(final DeleteCommand cmd) {
-        final VolumeObjectTO vol = (VolumeObjectTO)cmd.getData();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
-        try {
-            final KVMStoragePool pool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-            try {
-                pool.getPhysicalDisk(vol.getPath());
-            } catch (final Exception e) {
-                s_logger.debug("can't find volume: " + vol.getPath() + ", return true");
-                return new Answer(null);
-            }
-            pool.deletePhysicalDisk(vol.getPath(), vol.getFormat());
-            return new Answer(null);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to delete volume: ", e);
-            return new Answer(null, false, e.toString());
-        }
-    }
-
-    @Override
-    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
-        try {
-            final DataTO srcData = cmd.getSrcTO();
-            final SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
-            final DataTO destData = cmd.getDestTO();
-            final PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
-            final DataStoreTO imageStore = srcData.getDataStore();
-            final VolumeObjectTO volume = snapshot.getVolume();
-
-            if (!(imageStore instanceof NfsTO)) {
-                return new CopyCmdAnswer("unsupported protocol");
-            }
-
-            final NfsTO nfsImageStore = (NfsTO)imageStore;
-
-            final String snapshotFullPath = snapshot.getPath();
-            final int index = snapshotFullPath.lastIndexOf("/");
-            final String snapshotPath = snapshotFullPath.substring(0, index);
-            final String snapshotName = snapshotFullPath.substring(index + 1);
-            final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl() + File.separator + snapshotPath);
-            final KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName);
-
-            if (volume.getFormat() == ImageFormat.RAW) {
-                snapshotDisk.setFormat(PhysicalDiskFormat.RAW);
-            } else if (volume.getFormat() == ImageFormat.QCOW2) {
-                snapshotDisk.setFormat(PhysicalDiskFormat.QCOW2);
-            }
-
-            final String primaryUuid = pool.getUuid();
-            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid);
-            final String volUuid = UUID.randomUUID().toString();
-
-            Map<String, String> details = cmd.getOptions2();
-
-            String path = details != null ? details.get(DiskTO.IQN) : null;
-
-            storagePoolMgr.connectPhysicalDisk(pool.getPoolType(), pool.getUuid(), path, details);
-
-            KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, path != null ? path : volUuid, primaryPool, cmd.getWaitInMillSeconds());
-
-            storagePoolMgr.disconnectPhysicalDisk(pool.getPoolType(), pool.getUuid(), path);
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(disk.getName());
-            newVol.setSize(disk.getVirtualSize());
-            newVol.setFormat(ImageFormat.valueOf(disk.getFormat().toString().toUpperCase()));
-
-            return new CopyCmdAnswer(newVol);
-        } catch (final CloudRuntimeException e) {
-            s_logger.debug("Failed to createVolumeFromSnapshot: ", e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer deleteSnapshot(final DeleteCommand cmd) {
-        String snap_full_name = "";
-        try {
-            SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData();
-            PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshotTO.getDataStore();
-            VolumeObjectTO volume = snapshotTO.getVolume();
-            KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
-            KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
-            String snapshotFullPath = snapshotTO.getPath();
-            String snapshotName = snapshotFullPath.substring(snapshotFullPath.lastIndexOf("/") + 1);
-            snap_full_name = disk.getName() + "@" + snapshotName;
-            if (primaryPool.getType() == StoragePoolType.RBD) {
-                Rados r = new Rados(primaryPool.getAuthUserName());
-                r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
-                r.confSet("key", primaryPool.getAuthSecret());
-                r.confSet("client_mount_timeout", "30");
-                r.connect();
-                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
-                IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
-                Rbd rbd = new Rbd(io);
-                RbdImage image = rbd.open(disk.getName());
-                try {
-                    s_logger.info("Attempting to remove RBD snapshot " + snap_full_name);
-                    if (image.snapIsProtected(snapshotName)) {
-                        s_logger.debug("Unprotecting RBD snapshot " + snap_full_name);
-                        image.snapUnprotect(snapshotName);
-                    }
-                    image.snapRemove(snapshotName);
-                    s_logger.info("Snapshot " + snap_full_name + " successfully removed from " +
-                            primaryPool.getType().toString() + "  pool.");
-                } catch (RbdException e) {
-                    s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
-                        ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-                } finally {
-                    rbd.close(image);
-                    r.ioCtxDestroy(io);
-                }
-            } else {
-                s_logger.warn("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
-                throw new InternalErrorException("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
-            }
-            return new Answer(cmd, true, "Snapshot " + snap_full_name + " removed successfully.");
-        } catch (RadosException e) {
-            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
-                ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
-        } catch (RbdException e) {
-            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
-                ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
-        } catch (Exception e) {
-            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString());
-            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
-        }
-    }
-
-    @Override
-    public Answer introduceObject(final IntroduceObjectCmd cmd) {
-        return new Answer(cmd, false, "not implememented yet");
-    }
-
-    @Override
-    public Answer forgetObject(final ForgetObjectCmd cmd) {
-        return new Answer(cmd, false, "not implememented yet");
-    }
-
-    /**
-     * Get direct template downloader from direct download command and destination pool
-     */
-    private DirectTemplateDownloader getDirectTemplateDownloaderFromCommand(DirectDownloadCommand cmd, KVMStoragePool destPool) {
-        if (cmd instanceof HttpDirectDownloadCommand) {
-            return new HttpDirectTemplateDownloader(cmd.getUrl(), cmd.getTemplateId(), destPool.getLocalPath(), cmd.getChecksum(), cmd.getHeaders());
-        } else if (cmd instanceof HttpsDirectDownloadCommand) {
-            return new HttpsDirectTemplateDownloader(cmd.getUrl(), cmd.getTemplateId(), destPool.getLocalPath(), cmd.getChecksum(), cmd.getHeaders());
-        } else if (cmd instanceof NfsDirectDownloadCommand) {
-            return new NfsDirectTemplateDownloader(cmd.getUrl(), destPool.getLocalPath(), cmd.getTemplateId(), cmd.getChecksum());
-        } else if (cmd instanceof MetalinkDirectDownloadCommand) {
-            return new MetalinkDirectTemplateDownloader(cmd.getUrl(), destPool.getLocalPath(), cmd.getTemplateId(), cmd.getChecksum(), cmd.getHeaders());
-        } else {
-            throw new IllegalArgumentException("Unsupported protocol, please provide HTTP(S), NFS or a metalink");
-        }
-    }
-
-    @Override
-    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
-        final PrimaryDataStoreTO pool = cmd.getDestPool();
-        if (!pool.getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
-            return new DirectDownloadAnswer(false, "Unsupported pool type " + pool.getPoolType().toString(), true);
-        }
-        KVMStoragePool destPool = storagePoolMgr.getStoragePool(pool.getPoolType(), pool.getUuid());
-        DirectTemplateDownloader downloader;
-
-        try {
-            downloader = getDirectTemplateDownloaderFromCommand(cmd, destPool);
-        } catch (IllegalArgumentException e) {
-            return new DirectDownloadAnswer(false, "Unable to create direct downloader: " + e.getMessage(), true);
-        }
-
-        try {
-            s_logger.info("Trying to download template");
-            if (!downloader.downloadTemplate()) {
-                s_logger.warn("Couldn't download template");
-                return new DirectDownloadAnswer(false, "Unable to download template", true);
-            }
-            if (!downloader.validateChecksum()) {
-                s_logger.warn("Couldn't validate template checksum");
-                return new DirectDownloadAnswer(false, "Checksum validation failed", false);
-            }
-            if (!downloader.extractAndInstallDownloadedTemplate()) {
-                s_logger.warn("Couldn't extract and install template");
-                return new DirectDownloadAnswer(false, "Extraction and installation failed", false);
-            }
-        } catch (CloudRuntimeException e) {
-            s_logger.warn("Error downloading template " + cmd.getTemplateId() + " due to: " + e.getMessage());
-            return new DirectDownloadAnswer(false, "Unable to download template: " + e.getMessage(), true);
-        }
-
-        DirectTemplateInformation info = downloader.getTemplateInformation();
-        return new DirectDownloadAnswer(true, info.getSize(), info.getInstallPath());
-    }
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
deleted file mode 100644
index 24cf031..0000000
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ /dev/null
@@ -1,1331 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.kvm.storage;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.LibvirtException;
-import org.libvirt.Secret;
-import org.libvirt.StoragePool;
-import org.libvirt.StoragePoolInfo.StoragePoolState;
-import org.libvirt.StorageVol;
-
-import com.ceph.rados.IoCTX;
-import com.ceph.rados.Rados;
-import com.ceph.rados.exceptions.ErrorCode;
-import com.ceph.rados.exceptions.RadosException;
-import com.ceph.rbd.Rbd;
-import com.ceph.rbd.RbdException;
-import com.ceph.rbd.RbdImage;
-import com.ceph.rbd.jna.RbdImageInfo;
-import com.ceph.rbd.jna.RbdSnapInfo;
-
-import org.apache.cloudstack.utils.qemu.QemuImg;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-import org.apache.cloudstack.utils.qemu.QemuImgException;
-import org.apache.cloudstack.utils.qemu.QemuImgFile;
-
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
-import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef.Usage;
-import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.AuthenticationType;
-import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.PoolType;
-import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolXMLParser;
-import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef.VolumeFormat;
-import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeXMLParser;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-public class LibvirtStorageAdaptor implements StorageAdaptor {
-    private static final Logger s_logger = Logger.getLogger(LibvirtStorageAdaptor.class);
-    private StorageLayer _storageLayer;
-    private String _mountPoint = "/mnt";
-    private String _manageSnapshotPath;
-
-    private String rbdTemplateSnapName = "cloudstack-base-snap";
-    private int rbdFeatures = (1 << 0); /* Feature 1<<0 means layering in RBD format 2 */
-    private int rbdOrder = 0; /* Order 0 means 4MB blocks (the default) */
-
-    public LibvirtStorageAdaptor(StorageLayer storage) {
-        _storageLayer = storage;
-        _manageSnapshotPath = Script.findScript("scripts/storage/qcow2/", "managesnapshot.sh");
-    }
-
-    @Override
-    public boolean createFolder(String uuid, String path) {
-        String mountPoint = _mountPoint + File.separator + uuid;
-        File f = new File(mountPoint + File.separator + path);
-        if (!f.exists()) {
-            f.mkdirs();
-        }
-        return true;
-    }
-
-    public StorageVol getVolume(StoragePool pool, String volName) {
-        StorageVol vol = null;
-
-        try {
-            vol = pool.storageVolLookupByName(volName);
-        } catch (LibvirtException e) {
-            s_logger.debug("Could not find volume " + volName + ": " + e.getMessage());
-        }
-
-        /**
-         * The volume was not found in the storage pool
-         * This can happen when a volume has just been created on a different host and
-         * since then the libvirt storage pool has not been refreshed.
-         */
-        if (vol == null) {
-            try {
-                s_logger.debug("Refreshing storage pool " + pool.getName());
-                refreshPool(pool);
-            } catch (LibvirtException e) {
-                s_logger.debug("Failed to refresh storage pool: " + e.getMessage());
-            }
-
-            try {
-                vol = pool.storageVolLookupByName(volName);
-                s_logger.debug("Found volume " + volName + " in storage pool " + pool.getName() + " after refreshing the pool");
-            } catch (LibvirtException e) {
-                throw new CloudRuntimeException("Could not find volume " + volName + ": " + e.getMessage());
-            }
-        }
-
-        return vol;
-    }
-
-    public StorageVol createVolume(Connect conn, StoragePool pool, String uuid, long size, VolumeFormat format) throws LibvirtException {
-        LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(UUID.randomUUID().toString(), size, format, null, null);
-        s_logger.debug(volDef.toString());
-
-        return pool.storageVolCreateXML(volDef.toString(), 0);
-    }
-
-    public void storagePoolRefresh(StoragePool pool) {
-        try {
-            synchronized (getStoragePool(pool.getUUIDString())) {
-                refreshPool(pool);
-            }
-        } catch (LibvirtException e) {
-            s_logger.debug("refresh storage pool failed: " + e.toString());
-        }
-    }
-
-    private StoragePool createNetfsStoragePool(PoolType fsType, Connect conn, String uuid, String host, String path) throws LibvirtException {
-        String targetPath = _mountPoint + File.separator + uuid;
-        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(fsType, uuid, uuid, host, path, targetPath);
-        _storageLayer.mkdir(targetPath);
-        StoragePool sp = null;
-        try {
-            s_logger.debug(spd.toString());
-            // check whether the pool is already mounted
-            int mountpointResult = Script.runSimpleBashScriptForExitValue("mountpoint -q " + targetPath);
-            // if the pool is mounted, try to unmount it
-            if(mountpointResult == 0) {
-                s_logger.info("Attempting to unmount old mount at " + targetPath);
-                String result = Script.runSimpleBashScript("umount -l " + targetPath);
-                if (result == null) {
-                    s_logger.info("Succeeded in unmounting " + targetPath);
-                } else {
-                    s_logger.error("Failed in unmounting storage");
-                }
-            }
-
-            sp = conn.storagePoolCreateXML(spd.toString(), 0);
-            return sp;
-        } catch (LibvirtException e) {
-            s_logger.error(e.toString());
-            throw e;
-        }
-    }
-
-    private StoragePool createSharedStoragePool(Connect conn, String uuid, String host, String path) {
-        String mountPoint = path;
-        if (!_storageLayer.exists(mountPoint)) {
-            s_logger.error(mountPoint + " does not exists. Check local.storage.path in agent.properties.");
-            return null;
-        }
-        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.DIR, uuid, uuid, host, path, path);
-        StoragePool sp = null;
-        try {
-            s_logger.debug(spd.toString());
-            sp = conn.storagePoolCreateXML(spd.toString(), 0);
-            return sp;
-        } catch (LibvirtException e) {
-            s_logger.error(e.toString());
-            if (sp != null) {
-                try {
-                    if (sp.isPersistent() == 1) {
-                        sp.destroy();
-                        sp.undefine();
-                    } else {
-                        sp.destroy();
-                    }
-                    sp.free();
-                } catch (LibvirtException l) {
-                    s_logger.debug("Failed to define shared mount point storage pool with: " + l.toString());
-                }
-            }
-            return null;
-        }
-    }
-
-    private StoragePool createCLVMStoragePool(Connect conn, String uuid, String host, String path) {
-
-        String volgroupPath = "/dev/" + path;
-        String volgroupName = path;
-        volgroupName = volgroupName.replaceFirst("/", "");
-
-        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.LOGICAL, volgroupName, uuid, host, volgroupPath, volgroupPath);
-        StoragePool sp = null;
-        try {
-            s_logger.debug(spd.toString());
-            sp = conn.storagePoolCreateXML(spd.toString(), 0);
-            return sp;
-        } catch (LibvirtException e) {
-            s_logger.error(e.toString());
-            if (sp != null) {
-                try {
-                    if (sp.isPersistent() == 1) {
-                        sp.destroy();
-                        sp.undefine();
-                    } else {
-                        sp.destroy();
-                    }
-                    sp.free();
-                } catch (LibvirtException l) {
-                    s_logger.debug("Failed to define clvm storage pool with: " + l.toString());
-                }
-            }
-            return null;
-        }
-
-    }
-
-    private StoragePool createRBDStoragePool(Connect conn, String uuid, String host, int port, String userInfo, String path) {
-
-        LibvirtStoragePoolDef spd;
-        StoragePool sp = null;
-        Secret s = null;
-
-        String[] userInfoTemp = userInfo.split(":");
-        if (userInfoTemp.length == 2) {
-            LibvirtSecretDef sd = new LibvirtSecretDef(Usage.CEPH, uuid);
-
-            sd.setCephName(userInfoTemp[0] + "@" + host + ":" + port + "/" + path);
-
-            try {
-                s_logger.debug(sd.toString());
-                s = conn.secretDefineXML(sd.toString());
-                s.setValue(Base64.decodeBase64(userInfoTemp[1]));
-            } catch (LibvirtException e) {
-                s_logger.error("Failed to define the libvirt secret: " + e.toString());
-                if (s != null) {
-                    try {
-                        s.undefine();
-                        s.free();
-                    } catch (LibvirtException l) {
-                        s_logger.error("Failed to undefine the libvirt secret: " + l.toString());
-                    }
-                }
-                return null;
-            }
-            spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, userInfoTemp[0], AuthenticationType.CEPH, uuid);
-        } else {
-            spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, "");
-        }
-
-        try {
-            s_logger.debug(spd.toString());
-            sp = conn.storagePoolCreateXML(spd.toString(), 0);
-            return sp;
-        } catch (LibvirtException e) {
-            s_logger.error("Failed to create RBD storage pool: " + e.toString());
-            if (sp != null) {
-                try {
-                    if (sp.isPersistent() == 1) {
-                        sp.destroy();
-                        sp.undefine();
-                    } else {
-                        sp.destroy();
-                    }
-                    sp.free();
-                } catch (LibvirtException l) {
-                    s_logger.error("Failed to undefine RBD storage pool: " + l.toString());
-                }
-            }
-
-            if (s != null) {
-                try {
-                    s_logger.error("Failed to create the RBD storage pool, cleaning up the libvirt secret");
-                    s.undefine();
-                    s.free();
-                } catch (LibvirtException se) {
-                    s_logger.error("Failed to remove the libvirt secret: " + se.toString());
-                }
-            }
-
-            return null;
-        }
-    }
-
-    public StorageVol copyVolume(StoragePool destPool, LibvirtStorageVolumeDef destVol, StorageVol srcVol, int timeout) throws LibvirtException {
-        StorageVol vol = destPool.storageVolCreateXML(destVol.toString(), 0);
-        String srcPath = srcVol.getKey();
-        String destPath = vol.getKey();
-        Script.runSimpleBashScript("cp " + srcPath + " " + destPath, timeout);
-        return vol;
-    }
-
-    public boolean copyVolume(String srcPath, String destPath, String volumeName, int timeout) throws InternalErrorException {
-        _storageLayer.mkdirs(destPath);
-        if (!_storageLayer.exists(srcPath)) {
-            throw new InternalErrorException("volume:" + srcPath + " is not exits");
-        }
-        String result = Script.runSimpleBashScript("cp " + srcPath + " " + destPath + File.separator + volumeName, timeout);
-        return result == null;
-    }
-
-    public LibvirtStoragePoolDef getStoragePoolDef(Connect conn, StoragePool pool) throws LibvirtException {
-        String poolDefXML = pool.getXMLDesc(0);
-        LibvirtStoragePoolXMLParser parser = new LibvirtStoragePoolXMLParser();
-        return parser.parseStoragePoolXML(poolDefXML);
-    }
-
-    public LibvirtStorageVolumeDef getStorageVolumeDef(Connect conn, StorageVol vol) throws LibvirtException {
-        String volDefXML = vol.getXMLDesc(0);
-        LibvirtStorageVolumeXMLParser parser = new LibvirtStorageVolumeXMLParser();
-        return parser.parseStorageVolumeXML(volDefXML);
-    }
-
-    @Override
-    public KVMStoragePool getStoragePool(String uuid) {
-        return this.getStoragePool(uuid, false);
-    }
-
-    @Override
-    public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
-        s_logger.info("Trying to fetch storage pool " + uuid + " from libvirt");
-        StoragePool storage = null;
-        try {
-            Connect conn = LibvirtConnection.getConnection();
-            storage = conn.storagePoolLookupByUUIDString(uuid);
-
-            if (storage.getInfo().state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
-                s_logger.warn("Storage pool " + uuid + " is not in running state. Attempting to start it.");
-                storage.create(0);
-            }
-            LibvirtStoragePoolDef spd = getStoragePoolDef(conn, storage);
-            if (spd == null) {
-                throw new CloudRuntimeException("Unable to parse the storage pool definition for storage pool " + uuid);
-            }
-            StoragePoolType type = null;
-            if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.NETFS) {
-                type = StoragePoolType.NetworkFilesystem;
-            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.DIR) {
-                type = StoragePoolType.Filesystem;
-            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.RBD) {
-                type = StoragePoolType.RBD;
-            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.LOGICAL) {
-                type = StoragePoolType.CLVM;
-            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.GLUSTERFS) {
-                type = StoragePoolType.Gluster;
-            }
-
-            LibvirtStoragePool pool = new LibvirtStoragePool(uuid, storage.getName(), type, this, storage);
-
-            if (pool.getType() != StoragePoolType.RBD)
-                pool.setLocalPath(spd.getTargetPath());
-            else
-                pool.setLocalPath("");
-
-            if (pool.getType() == StoragePoolType.RBD
-                    || pool.getType() == StoragePoolType.Gluster) {
-                pool.setSourceHost(spd.getSourceHost());
-                pool.setSourcePort(spd.getSourcePort());
-                pool.setSourceDir(spd.getSourceDir());
-                String authUsername = spd.getAuthUserName();
-                if (authUsername != null) {
-                    Secret secret = conn.secretLookupByUUIDString(spd.getSecretUUID());
-                    String secretValue = new String(Base64.encodeBase64(secret.getByteValue()), Charset.defaultCharset());
-                    pool.setAuthUsername(authUsername);
-                    pool.setAuthSecret(secretValue);
-                }
-            }
-
-            /**
-             * On large (RBD) storage pools it can take up to a couple of minutes
-             * for libvirt to refresh the pool.
-             *
-             * Refreshing a storage pool means that libvirt will have to iterate the whole pool
-             * and fetch information of each volume in there
-             *
-             * It is not always required to refresh a pool. So we can control if we want to or not
-             *
-             * By default only the getStorageStats call in the LibvirtComputingResource will ask to
-             * refresh the pool
-             */
-            if (refreshInfo) {
-                s_logger.info("Asking libvirt to refresh storage pool " + uuid);
-                pool.refresh();
-            }
-            pool.setCapacity(storage.getInfo().capacity);
-            pool.setUsed(storage.getInfo().allocation);
-            pool.setAvailable(storage.getInfo().available);
-
-            s_logger.debug("Succesfully refreshed pool " + uuid +
-                           " Capacity: " + storage.getInfo().capacity +
-                           " Used: " + storage.getInfo().allocation +
-                           " Available: " + storage.getInfo().available);
-
-            return pool;
-        } catch (LibvirtException e) {
-            s_logger.debug("Could not find storage pool " + uuid + " in libvirt");
-            throw new CloudRuntimeException(e.toString(), e);
-        }
-    }
-
-    @Override
-    public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
-        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
-
-        try {
-            StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid);
-            KVMPhysicalDisk disk;
-            LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol);
-            disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool);
-            disk.setSize(vol.getInfo().allocation);
-            disk.setVirtualSize(vol.getInfo().capacity);
-
-            /**
-             * libvirt returns format = 'unknow', so we have to force
-             * the format to RAW for RBD storage volumes
-             */
-            if (pool.getType() == StoragePoolType.RBD) {
-                disk.setFormat(PhysicalDiskFormat.RAW);
-            } else if (voldef.getFormat() == null) {
-                File diskDir = new File(disk.getPath());
-                if (diskDir.exists() && diskDir.isDirectory()) {
-                    disk.setFormat(PhysicalDiskFormat.DIR);
-                } else if (volumeUuid.endsWith("tar") || volumeUuid.endsWith(("TAR"))) {
-                    disk.setFormat(PhysicalDiskFormat.TAR);
-                } else if (volumeUuid.endsWith("raw") || volumeUuid.endsWith(("RAW"))) {
-                    disk.setFormat(PhysicalDiskFormat.RAW);
-                } else {
-                    disk.setFormat(pool.getDefaultFormat());
-                }
-            } else if (voldef.getFormat() == LibvirtStorageVolumeDef.VolumeFormat.QCOW2) {
-                disk.setFormat(PhysicalDiskFormat.QCOW2);
-            } else if (voldef.getFormat() == LibvirtStorageVolumeDef.VolumeFormat.RAW) {
-                disk.setFormat(PhysicalDiskFormat.RAW);
-            }
-            return disk;
-        } catch (LibvirtException e) {
-            s_logger.debug("Failed to get physical disk:", e);
-            throw new CloudRuntimeException(e.toString());
-        }
-
-    }
-
-    @Override
-    public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type) {
-        s_logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt");
-
-        StoragePool sp = null;
-        Connect conn = null;
-        try {
-            conn = LibvirtConnection.getConnection();
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-
-        try {
-            sp = conn.storagePoolLookupByUUIDString(name);
-            if (sp != null && sp.isActive() == 0) {
-                sp.undefine();
-                sp = null;
-                s_logger.info("Found existing defined storage pool " + name + ". It wasn't running, so we undefined it.");
-            }
-            if (sp != null) {
-                s_logger.info("Found existing defined storage pool " + name + ", using it.");
-            }
-        } catch (LibvirtException e) {
-            sp = null;
-            s_logger.warn("Storage pool " + name + " was not found running in libvirt. Need to create it.");
-        }
-
-        // libvirt strips trailing slashes off of path, we will too in order to match
-        // existing paths
-        if (path.endsWith("/")) {
-            path = path.substring(0, path.length() - 1);
-        }
-
-        if (sp == null) {
-            // see if any existing pool by another name is using our storage path.
-            // if anyone is, undefine the pool so we can define it as requested.
-            // This should be safe since a pool in use can't be removed, and no
-            // volumes are affected by unregistering the pool with libvirt.
-            s_logger.info("Didn't find an existing storage pool " + name + " by UUID, checking for pools with duplicate paths");
-
-            try {
-                String[] poolnames = conn.listStoragePools();
-                for (String poolname : poolnames) {
-                    s_logger.debug("Checking path of existing pool " + poolname + " against pool we want to create");
-                    StoragePool p = conn.storagePoolLookupByName(poolname);
-                    LibvirtStoragePoolDef pdef = getStoragePoolDef(conn, p);
-
-                    String targetPath = pdef.getTargetPath();
-                    if (targetPath != null && targetPath.equals(path)) {
-                        s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname +
-                                ", undefining so we can re-define with correct name " + name);
-                        if (p.isPersistent() == 1) {
-                            p.destroy();
-                            p.undefine();
-                        } else {
-                            p.destroy();
-                        }
-                    }
-                }
-            } catch (LibvirtException e) {
-                s_logger.error("Failure in attempting to see if an existing storage pool might be using the path of the pool to be created:" + e);
-            }
-
-            s_logger.debug("Attempting to create storage pool " + name);
-
-            if (type == StoragePoolType.NetworkFilesystem) {
-                try {
-                    sp = createNetfsStoragePool(PoolType.NETFS, conn, name, host, path);
-                } catch (LibvirtException e) {
-                    s_logger.error("Failed to create netfs mount: " + host + ":" + path , e);
-                    s_logger.error(e.getStackTrace());
-                    throw new CloudRuntimeException(e.toString());
-                }
-            } else if (type == StoragePoolType.Gluster) {
-                try {
-                    sp = createNetfsStoragePool(PoolType.GLUSTERFS, conn, name, host, path);
-                } catch (LibvirtException e) {
-                    s_logger.error("Failed to create glusterfs mount: " + host + ":" + path , e);
-                    s_logger.error(e.getStackTrace());
-                    throw new CloudRuntimeException(e.toString());
-                }
-            } else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) {
-                sp = createSharedStoragePool(conn, name, host, path);
-            } else if (type == StoragePoolType.RBD) {
-                sp = createRBDStoragePool(conn, name, host, port, userInfo, path);
-            } else if (type == StoragePoolType.CLVM) {
-                sp = createCLVMStoragePool(conn, name, host, path);
-            }
-        }
-
-        if (sp == null) {
-            throw new CloudRuntimeException("Failed to create storage pool: " + name);
-        }
-
-        try {
-            if (sp.isActive() == 0) {
-                s_logger.debug("Attempting to activate pool " + name);
-                sp.create(0);
-            }
-
-            return getStoragePool(name);
-        } catch (LibvirtException e) {
-            String error = e.toString();
-            if (error.contains("Storage source conflict")) {
-                throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " +
-                        " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " +
-                        error);
-            } else {
-                throw new CloudRuntimeException(error);
-            }
-        }
-    }
-
-    @Override
-    public boolean deleteStoragePool(String uuid) {
-        s_logger.info("Attempting to remove storage pool " + uuid + " from libvirt");
-        Connect conn = null;
-        try {
-            conn = LibvirtConnection.getConnection();
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-
-        StoragePool sp = null;
-        Secret s = null;
-
-        try {
-            sp = conn.storagePoolLookupByUUIDString(uuid);
-        } catch (LibvirtException e) {
-            s_logger.warn("Storage pool " + uuid + " doesn't exist in libvirt. Assuming it is already removed");
-            return true;
-        }
-
-        /*
-         * Some storage pools, like RBD also have 'secret' information stored in libvirt
-         * Destroy them if they exist
-         */
-        try {
-            s = conn.secretLookupByUUIDString(uuid);
-        } catch (LibvirtException e) {
-            s_logger.info("Storage pool " + uuid + " has no corresponding secret. Not removing any secret.");
-        }
-
-        try {
-            if (sp.isPersistent() == 1) {
-                sp.destroy();
-                sp.undefine();
-            } else {
-                sp.destroy();
-            }
-            sp.free();
-            if (s != null) {
-                s.undefine();
-                s.free();
-            }
-
-            s_logger.info("Storage pool " + uuid + " was succesfully removed from libvirt.");
-
-            return true;
-        } catch (LibvirtException e) {
-            // handle ebusy error when pool is quickly destroyed
-            if (e.toString().contains("exit status 16")) {
-                String targetPath = _mountPoint + File.separator + uuid;
-                s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble unmounting the pool. Trying umount location " + targetPath +
-                        "again in a few seconds");
-                String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath);
-                if (result == null) {
-                    s_logger.error("Succeeded in unmounting " + targetPath);
-                    return true;
-                }
-                s_logger.error("Failed to unmount " + targetPath);
-            }
-            throw new CloudRuntimeException(e.toString(), e);
-        }
-    }
-
-    @Override
-    public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool,
-            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
-
-        s_logger.info("Attempting to create volume " + name + " (" + pool.getType().toString() + ") in pool "
-                + pool.getUuid() + " with size " + size);
-
-        switch (pool.getType()) {
-            case RBD:
-                return createPhysicalDiskByLibVirt(name, pool, PhysicalDiskFormat.RAW, provisioningType, size);
-            case NetworkFilesystem:
-            case Filesystem:
-                switch (format) {
-                    case QCOW2:
-                        return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
-                    case RAW:
-                        return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
-                    case DIR:
-                        return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
-                    case TAR:
-                        return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
-                    default:
-                        throw new CloudRuntimeException("Unexpected disk format is specified.");
-                }
-            default:
-                return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
-        }
-    }
-
-    private KVMPhysicalDisk createPhysicalDiskByLibVirt(String name, KVMStoragePool pool,
-            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
-        LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
-        StoragePool virtPool = libvirtPool.getPool();
-        LibvirtStorageVolumeDef.VolumeFormat libvirtformat = LibvirtStorageVolumeDef.VolumeFormat.getFormat(format);
-
-        String volPath = null;
-        String volName = null;
-        long volAllocation = 0;
-        long volCapacity = 0;
-
-        LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(name,
-                size, libvirtformat, null, null);
-        s_logger.debug(volDef.toString());
-        try {
-            StorageVol vol = virtPool.storageVolCreateXML(volDef.toString(), 0);
-            volPath = vol.getPath();
-            volName = vol.getName();
-            volAllocation = vol.getInfo().allocation;
-            volCapacity = vol.getInfo().capacity;
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-
-        KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool);
-        disk.setFormat(format);
-        disk.setSize(volAllocation);
-        disk.setVirtualSize(volCapacity);
-        return disk;
-    }
-
-
-    private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool pool,
-            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
-        String volPath = pool.getLocalPath() + "/" + name;
-        String volName = name;
-        long virtualSize = 0;
-        long actualSize = 0;
-
-        final int timeout = 0;
-
-        QemuImgFile destFile = new QemuImgFile(volPath);
-        destFile.setFormat(format);
-        destFile.setSize(size);
-        QemuImg qemu = new QemuImg(timeout);
-        Map<String, String> options = new HashMap<String, String>();
-        if (pool.getType() == StoragePoolType.NetworkFilesystem){
-            options.put("preallocation", QemuImg.PreallocationType.getPreallocationType(provisioningType).toString());
-        }
-
-        try{
-            qemu.create(destFile, options);
-            Map<String, String> info = qemu.info(destFile);
-            virtualSize = Long.parseLong(info.get(new String("virtual_size")));
-            actualSize = new File(destFile.getFileName()).length();
-        } catch (QemuImgException e) {
-            s_logger.error("Failed to create " + volPath +
-                    " due to a failed executing of qemu-img: " + e.getMessage());
-        }
-
-        KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool);
-        disk.setFormat(format);
-        disk.setSize(actualSize);
-        disk.setVirtualSize(virtualSize);
-        return disk;
-    }
-
-    @Override
-    public boolean connectPhysicalDisk(String name, KVMStoragePool pool, Map<String, String> details) {
-        // this is for managed storage that needs to prep disks prior to use
-        return true;
-    }
-
-    @Override
-    public boolean disconnectPhysicalDisk(String uuid, KVMStoragePool pool) {
-        // this is for managed storage that needs to cleanup disks after use
-        return true;
-    }
-
-    @Override
-    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
-        // this is for managed storage that needs to cleanup disks after use
-        return false;
-    }
-
-    @Override
-    public boolean disconnectPhysicalDiskByPath(String localPath) {
-        // we've only ever cleaned up ISOs that are NFS mounted
-        String poolUuid = null;
-        if (localPath != null && localPath.startsWith(_mountPoint) && localPath.endsWith(".iso")) {
-            String[] token = localPath.split("/");
-
-            if (token.length > 3) {
-                poolUuid = token[2];
-            }
-        } else {
-            return false;
-        }
-
-        if (poolUuid == null) {
-            return false;
-        }
-
-        try {
-            Connect conn = LibvirtConnection.getConnection();
-
-            conn.storagePoolLookupByUUIDString(poolUuid);
-
-            deleteStoragePool(poolUuid);
-
-            return true;
-        } catch (LibvirtException ex) {
-            return false;
-        } catch (CloudRuntimeException ex) {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean deletePhysicalDisk(String uuid, KVMStoragePool pool, Storage.ImageFormat format) {
-
-        s_logger.info("Attempting to remove volume " + uuid + " from pool " + pool.getUuid());
-
-        /**
-         * RBD volume can have snapshots and while they exist libvirt
-         * can't remove the RBD volume
-         *
-         * We have to remove those snapshots first
-         */
-        if (pool.getType() == StoragePoolType.RBD) {
-            try {
-                s_logger.info("Unprotecting and Removing RBD snapshots of image " + pool.getSourceDir() + "/" + uuid + " prior to removing the image");
-
-                Rados r = new Rados(pool.getAuthUserName());
-                r.confSet("mon_host", pool.getSourceHost() + ":" + pool.getSourcePort());
-                r.confSet("key", pool.getAuthSecret());
-                r.confSet("client_mount_timeout", "30");
-                r.connect();
-                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
-
-                IoCTX io = r.ioCtxCreate(pool.getSourceDir());
-                Rbd rbd = new Rbd(io);
-                RbdImage image = rbd.open(uuid);
-                s_logger.debug("Fetching list of snapshots of RBD image " + pool.getSourceDir() + "/" + uuid);
-                List<RbdSnapInfo> snaps = image.snapList();
-                try {
-                    for (RbdSnapInfo snap : snaps) {
-                        if (image.snapIsProtected(snap.name)) {
-                            s_logger.debug("Unprotecting snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name);
-                            image.snapUnprotect(snap.name);
-                        } else {
-                            s_logger.debug("Snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name + " is not protected.");
-                        }
-                        s_logger.debug("Removing snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name);
-                        image.snapRemove(snap.name);
-                    }
-                    s_logger.info("Succesfully unprotected and removed any remaining snapshots (" + snaps.size() + ") of "
-                        + pool.getSourceDir() + "/" + uuid + " Continuing to remove the RBD image");
-                } catch (RbdException e) {
-                    s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
-                        ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-                    throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
-                } finally {
-                    s_logger.debug("Closing image and destroying context");
-                    rbd.close(image);
-                    r.ioCtxDestroy(io);
-                }
-            } catch (RadosException e) {
-                s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
-                    ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-                throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
-            } catch (RbdException e) {
-                s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
-                    ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
-                throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
-            }
-        }
-
-        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
-        try {
-            StorageVol vol = getVolume(libvirtPool.getPool(), uuid);
-            s_logger.debug("Instructing libvirt to remove volume " + uuid + " from pool " + pool.getUuid());
-            if(Storage.ImageFormat.DIR.equals(format)){
-                deleteDirVol(libvirtPool, vol);
-            } else {
-                deleteVol(libvirtPool, vol);
-            }
-            vol.free();
-            return true;
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-    }
-
-    /**
-     * This function copies a physical disk from Secondary Storage to Primary Storage
-     * or from Primary to Primary Storage
-     *
-     * The first time a template is deployed in Primary Storage it will be copied from
-     * Secondary to Primary.
-     *
-     * If it has been created on Primary Storage, it will be copied on the Primary Storage
-     */
-    @Override
-    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
-            String name, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size, KVMStoragePool destPool, int timeout) {
-
-        s_logger.info("Creating volume " + name + " from template " + template.getName() + " in pool " + destPool.getUuid() +
-                " (" + destPool.getType().toString() + ") with size " + size);
-
-        KVMPhysicalDisk disk = null;
-
-        if (destPool.getType() == StoragePoolType.RBD) {
-            disk = createDiskFromTemplateOnRBD(template, name, format, provisioningType, size, destPool, timeout);
-        } else {
-            try {
-                String newUuid = name;
-                disk = destPool.createPhysicalDisk(newUuid, format, provisioningType, template.getVirtualSize());
-                if (disk == null) {
-                    throw new CloudRuntimeException("Failed to create disk from template " + template.getName());
-                }
-                if (template.getFormat() == PhysicalDiskFormat.TAR) {
-                    Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath(), timeout); // TO BE FIXED to aware provisioningType
-                } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
-                    Script.runSimpleBashScript("mkdir -p " + disk.getPath());
-                    Script.runSimpleBashScript("chmod 755 " + disk.getPath());
-                    Script.runSimpleBashScript("tar -x -f " + template.getPath() + "/*.tar -C " + disk.getPath(), timeout);
-                } else if (format == PhysicalDiskFormat.QCOW2) {
-                    QemuImg qemu = new QemuImg(timeout);
-                    QemuImgFile destFile = new QemuImgFile(disk.getPath(), format);
-                    if (size > template.getVirtualSize()) {
-                        destFile.setSize(size);
-                    } else {
-                        destFile.setSize(template.getVirtualSize());
-                    }
-                    Map<String, String> options = new HashMap<String, String>();
-                    options.put("preallocation", QemuImg.PreallocationType.getPreallocationType(provisioningType).toString());
-                    switch(provisioningType){
-                    case THIN:
-                        QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
-                        qemu.create(destFile, backingFile, options);
-                        break;
-                    case SPARSE:
-                    case FAT:
-                        QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
-                        qemu.convert(srcFile, destFile, options);
-                        break;
-                    }
-                } else if (format == PhysicalDiskFormat.RAW) {
-                    QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
-                    QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
-                    if (size > template.getVirtualSize()) {
-                        destFile.setSize(size);
-                    } else {
-                        destFile.setSize(template.getVirtualSize());
-                    }
-                    QemuImg qemu = new QemuImg(timeout);
-                    Map<String, String> options = new HashMap<String, String>();
-                    qemu.convert(sourceFile, destFile, options);
-                }
-            } catch (QemuImgException e) {
-                s_logger.error("Failed to create " + disk.getPath() +
-                        " due to a failed executing of qemu-img: " + e.getMessage());
-            }
-        }
-
-
-        return disk;
-    }
-
-    private KVMPhysicalDisk createDiskFromTemplateOnRBD(KVMPhysicalDisk template,
-            String name, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size, KVMStoragePool destPool, int timeout){
-
-        /*
-            With RBD you can't run qemu-img convert with an existing RBD image as destination
-            qemu-img will exit with the error that the destination already exists.
-            So for RBD we don't create the image, but let qemu-img do that for us.
-
-            We then create a KVMPhysicalDisk object that we can return
-         */
-
-        KVMStoragePool srcPool = template.getPool();
-        KVMPhysicalDisk disk = null;
-        String newUuid = name;
-
-        format = PhysicalDiskFormat.RAW;
-        disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
-        disk.setFormat(format);
-        if (size > template.getVirtualSize()) {
-            disk.setSize(size);
-            disk.setVirtualSize(size);
-        } else {
-            // leave these as they were if size isn't applicable
-            disk.setSize(template.getVirtualSize());
-            disk.setVirtualSize(disk.getSize());
-        }
-
-
-        QemuImg qemu = new QemuImg(timeout);
-        QemuImgFile srcFile;
-        QemuImgFile destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                destPool.getSourcePort(),
-                destPool.getAuthUserName(),
-                destPool.getAuthSecret(),
-                disk.getPath()));
-        destFile.setFormat(format);
-
-
-        if (srcPool.getType() != StoragePoolType.RBD) {
-            srcFile = new QemuImgFile(template.getPath(), template.getFormat());
-            try{
-                qemu.convert(srcFile, destFile);
-            } catch (QemuImgException e) {
-                s_logger.error("Failed to create " + disk.getPath() +
-                        " due to a failed executing of qemu-img: " + e.getMessage());
-            }
-        } else {
-
-            /**
-             * We have to find out if the source file is in the same RBD pool and has
-             * RBD format 2 before we can do a layering/clone operation on the RBD image
-             *
-             * This will be the case when the template is already on Primary Storage and
-             * we want to copy it
-             */
-
-            try {
-                if ((srcPool.getSourceHost().equals(destPool.getSourceHost())) && (srcPool.getSourceDir().equals(destPool.getSourceDir()))) {
-                    /* We are on the same Ceph cluster, but we require RBD format 2 on the source image */
-                    s_logger.debug("Trying to perform a RBD clone (layering) since we are operating in the same storage pool");
-
-                    Rados r = new Rados(srcPool.getAuthUserName());
-                    r.confSet("mon_host", srcPool.getSourceHost() + ":" + srcPool.getSourcePort());
-                    r.confSet("key", srcPool.getAuthSecret());
-                    r.confSet("client_mount_timeout", "30");
-                    r.connect();
-                    s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
-
-                    IoCTX io = r.ioCtxCreate(srcPool.getSourceDir());
-                    Rbd rbd = new Rbd(io);
-                    RbdImage srcImage = rbd.open(template.getName());
-
-                    if (srcImage.isOldFormat()) {
-                        /* The source image is RBD format 1, we have to do a regular copy */
-                        s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() +
-                                " is RBD format 1. We have to perform a regular copy (" + disk.getVirtualSize() + " bytes)");
-
-                        rbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
-                        RbdImage destImage = rbd.open(disk.getName());
-
-                        s_logger.debug("Starting to copy " + srcImage.getName() +  " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
-                        rbd.copy(srcImage, destImage);
-
-                        s_logger.debug("Finished copying " + srcImage.getName() +  " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
-                        rbd.close(destImage);
-                    } else {
-                        s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName()
-                                + " is RBD format 2. We will perform a RBD clone using snapshot "
-                                + rbdTemplateSnapName);
-                        /* The source image is format 2, we can do a RBD snapshot+clone (layering) */
-
-
-                        s_logger.debug("Checking if RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
-                                + "@" + rbdTemplateSnapName + " exists prior to attempting a clone operation.");
-
-                        List<RbdSnapInfo> snaps = srcImage.snapList();
-                        s_logger.debug("Found " + snaps.size() +  " snapshots on RBD image " + srcPool.getSourceDir() + "/" + template.getName());
-                        boolean snapFound = false;
-                        for (RbdSnapInfo snap : snaps) {
-                            if (rbdTemplateSnapName.equals(snap.name)) {
-                                s_logger.debug("RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
-                                        + "@" + rbdTemplateSnapName + " already exists.");
-                                snapFound = true;
-                                break;
-                            }
-                        }
-
-                        if (!snapFound) {
-                            s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name);
-                            srcImage.snapCreate(rbdTemplateSnapName);
-                            s_logger.debug("Protecting RBD snapshot " + rbdTemplateSnapName + " on image " + name);
-                            srcImage.snapProtect(rbdTemplateSnapName);
-                        }
-
-                        rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder);
-                        s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName());
-                        /* We also need to resize the image if the VM was deployed with a larger root disk size */
-                        if (disk.getVirtualSize() > template.getVirtualSize()) {
-                            RbdImage diskImage = rbd.open(disk.getName());
-                            diskImage.resize(disk.getVirtualSize());
-                            rbd.close(diskImage);
-                            s_logger.debug("Resized " + disk.getName() + " to " + disk.getVirtualSize());
-                        }
-
-                    }
-
-                    rbd.close(srcImage);
-                    r.ioCtxDestroy(io);
-                } else {
-                    /* The source pool or host is not the same Ceph cluster, we do a simple copy with Qemu-Img */
-                    s_logger.debug("Both the source and destination are RBD, but not the same Ceph cluster. Performing a copy");
-
-                    Rados rSrc = new Rados(srcPool.getAuthUserName());
-                    rSrc.confSet("mon_host", srcPool.getSourceHost() + ":" + srcPool.getSourcePort());
-                    rSrc.confSet("key", srcPool.getAuthSecret());
-                    rSrc.confSet("client_mount_timeout", "30");
-                    rSrc.connect();
-                    s_logger.debug("Succesfully connected to source Ceph cluster at " + rSrc.confGet("mon_host"));
-
-                    Rados rDest = new Rados(destPool.getAuthUserName());
-                    rDest.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
-                    rDest.confSet("key", destPool.getAuthSecret());
-                    rDest.confSet("client_mount_timeout", "30");
-                    rDest.connect();
-                    s_logger.debug("Succesfully connected to source Ceph cluster at " + rDest.confGet("mon_host"));
-
-                    IoCTX sIO = rSrc.ioCtxCreate(srcPool.getSourceDir());
-                    Rbd sRbd = new Rbd(sIO);
-
-                    IoCTX dIO = rDest.ioCtxCreate(destPool.getSourceDir());
-                    Rbd dRbd = new Rbd(dIO);
-
-                    s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " +
-                            destPool.getSourceDir());
-                    dRbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
-
-                    RbdImage srcImage = sRbd.open(template.getName());
-                    RbdImage destImage = dRbd.open(disk.getName());
-
-                    s_logger.debug("Copying " + template.getName() + " from Ceph cluster " + rSrc.confGet("mon_host") + " to " + disk.getName()
-                            + " on cluster " + rDest.confGet("mon_host"));
-                    sRbd.copy(srcImage, destImage);
-
-                    sRbd.close(srcImage);
-                    dRbd.close(destImage);
-
-                    rSrc.ioCtxDestroy(sIO);
-                    rDest.ioCtxDestroy(dIO);
-                }
-            } catch (RadosException e) {
-                s_logger.error("Failed to perform a RADOS action on the Ceph cluster, the error was: " + e.getMessage());
-                disk = null;
-            } catch (RbdException e) {
-                s_logger.error("Failed to perform a RBD action on the Ceph cluster, the error was: " + e.getMessage());
-                disk = null;
-            }
-        }
-        return disk;
-    }
-
-    @Override
-    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
-        return null;
-    }
-
-    @Override
-    public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStoragePool pool) {
-        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
-        StoragePool virtPool = libvirtPool.getPool();
-        List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
-        try {
-            String[] vols = virtPool.listVolumes();
-            for (String volName : vols) {
-                KVMPhysicalDisk disk = getPhysicalDisk(volName, pool);
-                disks.add(disk);
-            }
-            return disks;
-        } catch (LibvirtException e) {
-            throw new CloudRuntimeException(e.toString());
-        }
-    }
-
-    /**
-     * This copies a volume from Primary Storage to Secondary Storage
-     *
-     * In theory it could also do it the other way around, but the current implementation
-     * in ManagementServerImpl shows that the destPool is always a Secondary Storage Pool
-     */
-    @Override
-    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
-
-        /**
-            With RBD you can't run qemu-img convert with an existing RBD image as destination
-            qemu-img will exit with the error that the destination already exists.
-            So for RBD we don't create the image, but let qemu-img do that for us.
-
-            We then create a KVMPhysicalDisk object that we can return
-
-            It is however very unlikely that the destPool will be RBD, since it isn't supported
-            for Secondary Storage
-         */
-
-        KVMStoragePool srcPool = disk.getPool();
-        PhysicalDiskFormat sourceFormat = disk.getFormat();
-        String sourcePath = disk.getPath();
-
-        KVMPhysicalDisk newDisk;
-        s_logger.debug("copyPhysicalDisk: disk size:" + disk.getSize() + ", virtualsize:" + disk.getVirtualSize()+" format:"+disk.getFormat());
-        if (destPool.getType() != StoragePoolType.RBD) {
-            if (disk.getFormat() == PhysicalDiskFormat.TAR) {
-                newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, Storage.ProvisioningType.THIN, disk.getVirtualSize());
-            } else {
-                    newDisk = destPool.createPhysicalDisk(name, Storage.ProvisioningType.THIN, disk.getVirtualSize());
-            }
-        } else {
-            newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool);
-            newDisk.setFormat(PhysicalDiskFormat.RAW);
-            newDisk.setSize(disk.getVirtualSize());
-            newDisk.setVirtualSize(disk.getSize());
-        }
-
-        String destPath = newDisk.getPath();
-        PhysicalDiskFormat destFormat = newDisk.getFormat();
-
-        QemuImg qemu = new QemuImg(timeout);
-        QemuImgFile srcFile = null;
-        QemuImgFile destFile = null;
-
-        if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
-            if(sourceFormat == PhysicalDiskFormat.TAR && destFormat == PhysicalDiskFormat.DIR) { //LXC template
-                Script.runSimpleBashScript("cp "+ sourcePath + " " + destPath);
-            } else if (sourceFormat == PhysicalDiskFormat.TAR) {
-                Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
-            } else if (sourceFormat == PhysicalDiskFormat.DIR) {
-                Script.runSimpleBashScript("mkdir -p " + destPath);
-                Script.runSimpleBashScript("chmod 755 " + destPath);
-                Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
-            } else {
-                srcFile = new QemuImgFile(sourcePath, sourceFormat);
-                try {
-                    Map<String, String> info = qemu.info(srcFile);
-                    String backingFile = info.get(new String("backing_file"));
-                    // qcow2 templates can just be copied into place
-                    if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) {
-                        String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
-                        if (result != null) {
-                            throw new CloudRuntimeException("Failed to create disk: " + result);
-                        }
-                    } else {
-                        destFile = new QemuImgFile(destPath, destFormat);
-                        try {
-                            qemu.convert(srcFile, destFile);
-                            Map<String, String> destInfo = qemu.info(destFile);
-                            Long virtualSize = Long.parseLong(destInfo.get(new String("virtual_size")));
-                            newDisk.setVirtualSize(virtualSize);
-                            newDisk.setSize(virtualSize);
-                        } catch (QemuImgException e) {
-                            s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
-                            newDisk = null;
-                        }
-                    }
-                } catch (QemuImgException e) {
-                    s_logger.error("Failed to fetch the information of file " + srcFile.getFileName() + " the error was: " + e.getMessage());
-                    newDisk = null;
-                }
-            }
-        } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) {
-            /**
-             * Using qemu-img we copy the QCOW2 disk to RAW (on RBD) directly.
-             * To do so it's mandatory that librbd on the system is at least 0.67.7 (Ceph Dumpling)
-             */
-            s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2");
-            try {
-                srcFile = new QemuImgFile(sourcePath, sourceFormat);
-                String rbdDestPath = destPool.getSourceDir() + "/" + name;
-                String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
-                        destPool.getSourcePort(),
-                        destPool.getAuthUserName(),
-                        destPool.getAuthSecret(),
-                        rbdDestPath);
-                destFile = new QemuImgFile(rbdDestFile, destFormat);
-
-                s_logger.debug("Starting copy from source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
-                qemu.convert(srcFile, destFile);
-                s_logger.debug("Succesfully converted source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
-
-                /* We have to stat the RBD image to see how big it became afterwards */
-                Rados r = new Rados(destPool.getAuthUserName());
-                r.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
-                r.confSet("key", destPool.getAuthSecret());
-                r.confSet("client_mount_timeout", "30");
-                r.connect();
-                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
-
-                IoCTX io = r.ioCtxCreate(destPool.getSourceDir());
-                Rbd rbd = new Rbd(io);
-
-                RbdImage image = rbd.open(name);
-                RbdImageInfo rbdInfo = image.stat();
-                newDisk.setSize(rbdInfo.size);
-                newDisk.setVirtualSize(rbdInfo.size);
-                s_logger.debug("After copy the resulting RBD image " + rbdDestPath + " is " + rbdInfo.size + " bytes long");
-                rbd.close(image);
-
-                r.ioCtxDestroy(io);
-            } catch (QemuImgException e) {
-                s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
-                newDisk = null;
-            } catch (RadosException e) {
-                s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
-                newDisk = null;
-            } catch (RbdException e) {
-                s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
-                newDisk = null;
-            }
-        } else {
-            /**
-                We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
-                it doesn't benefit us. It's better to keep the current code in place which works
-             */
-            srcFile =
-                    new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(),
-                            sourcePath));
-            srcFile.setFormat(sourceFormat);
-            destFile = new QemuImgFile(destPath);
-            destFile.setFormat(destFormat);
-
-            try {
-                qemu.convert(srcFile, destFile);
-            } catch (QemuImgException e) {
-                s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
-                newDisk = null;
-            }
-        }
-
-        if (newDisk == null) {
-            throw new CloudRuntimeException("Failed to copy " + disk.getPath() + " to " + name);
-        }
-
-        return newDisk;
-    }
-
-    @Override
-    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
-        return null;
-    }
-
-    @Override
-    public boolean refresh(KVMStoragePool pool) {
-        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
-        StoragePool virtPool = libvirtPool.getPool();
-        try {
-            refreshPool(virtPool);
-        } catch (LibvirtException e) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean deleteStoragePool(KVMStoragePool pool) {
-        return deleteStoragePool(pool.getUuid());
-    }
-
-    private void refreshPool(StoragePool pool) throws LibvirtException {
-        pool.refresh(0);
-        return;
-    }
-
-    private void deleteVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
-        vol.delete(0);
-    }
-
-    private void deleteDirVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
-        Script.runSimpleBashScript("rm -r --interactive=never " + vol.getPath());
-    }
-
-}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/ha/KVMInvestigator.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/ha/KVMInvestigator.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/ha/KVMInvestigator.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
new file mode 100644
index 0000000..ebaf23f
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
@@ -0,0 +1,433 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import com.google.common.base.Strings;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Networks;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+public class BridgeVifDriver extends VifDriverBase {
+
+    private static final Logger s_logger = Logger.getLogger(BridgeVifDriver.class);
+    private int _timeout;
+
+    private final Object _vnetBridgeMonitor = new Object();
+    private String _modifyVlanPath;
+    private String _modifyVxlanPath;
+    private String bridgeNameSchema;
+    private Long libvirtVersion;
+
+    @Override
+    public void configure(Map<String, Object> params) throws ConfigurationException {
+
+        super.configure(params);
+
+        getPifs();
+
+        // Set the domr scripts directory
+        params.put("domr.scripts.dir", "scripts/network/domr/kvm");
+
+        String networkScriptsDir = (String)params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = "scripts/vm/network/vnet";
+        }
+
+        bridgeNameSchema = (String)params.get("network.bridge.name.schema");
+
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
+
+        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
+        if (_modifyVlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvlan.sh");
+        }
+        _modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
+        if (_modifyVxlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvxlan.sh");
+        }
+
+        libvirtVersion = (Long) params.get("libvirtVersion");
+        if (libvirtVersion == null) {
+            libvirtVersion = 0L;
+        }
+    }
+
+    public void getPifs() {
+        final File dir = new File("/sys/devices/virtual/net");
+        final File[] netdevs = dir.listFiles();
+        final List<String> bridges = new ArrayList<String>();
+        for (File netdev : netdevs) {
+            final File isbridge = new File(netdev.getAbsolutePath() + "/bridge");
+            final String netdevName = netdev.getName();
+            s_logger.debug("looking in file " + netdev.getAbsolutePath() + "/bridge");
+            if (isbridge.exists()) {
+                s_logger.debug("Found bridge " + netdevName);
+                bridges.add(netdevName);
+            }
+        }
+
+        String guestBridgeName = _libvirtComputingResource.getGuestBridgeName();
+        String publicBridgeName = _libvirtComputingResource.getPublicBridgeName();
+
+        for (final String bridge : bridges) {
+            s_logger.debug("looking for pif for bridge " + bridge);
+            final String pif = getPif(bridge);
+            if (_libvirtComputingResource.isPublicBridge(bridge)) {
+                _pifs.put("public", pif);
+            }
+            if (guestBridgeName != null && bridge.equals(guestBridgeName)) {
+                _pifs.put("private", pif);
+            }
+            _pifs.put(bridge, pif);
+        }
+
+        // guest(private) creates bridges on a pif, if private bridge not found try pif direct
+        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
+        if (_pifs.get("private") == null) {
+            s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' not found as bridge, looking for physical interface");
+            final File dev = new File("/sys/class/net/" + guestBridgeName);
+            if (dev.exists()) {
+                s_logger.debug("guest(private) traffic label '" + guestBridgeName + "' found as a physical device");
+                _pifs.put("private", guestBridgeName);
+            }
+        }
+
+        // public creates bridges on a pif, if private bridge not found try pif direct
+        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
+        if (_pifs.get("public") == null) {
+            s_logger.debug("public traffic label '" + publicBridgeName+ "' not found as bridge, looking for physical interface");
+            final File dev = new File("/sys/class/net/" + publicBridgeName);
+            if (dev.exists()) {
+                s_logger.debug("public traffic label '" + publicBridgeName + "' found as a physical device");
+                _pifs.put("public", publicBridgeName);
+            }
+        }
+
+        s_logger.debug("done looking for pifs, no more bridges");
+    }
+
+    private String getPif(final String bridge) {
+        String pif = matchPifFileInDirectory(bridge);
+        final File vlanfile = new File("/proc/net/vlan/" + pif);
+
+        if (vlanfile.isFile()) {
+            pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
+        }
+
+        return pif;
+    }
+
+    private String matchPifFileInDirectory(final String bridgeName) {
+        final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
+
+        if (!brif.isDirectory()) {
+            final File pif = new File("/sys/class/net/" + bridgeName);
+            if (pif.isDirectory()) {
+                // if bridgeName already refers to a pif, return it as-is
+                return bridgeName;
+            }
+            s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?");
+            return "";
+        }
+
+        final File[] interfaces = brif.listFiles();
+
+        for (File anInterface : interfaces) {
+            final String fname = anInterface.getName();
+            s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'");
+            if (LibvirtComputingResource.isInterface(fname)) {
+                return fname;
+            }
+        }
+
+        s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath());
+        return "";
+    }
+
+    protected boolean isBroadcastTypeVlanOrVxlan(final NicTO nic) {
+        return nic != null && (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
+                || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan);
+    }
+
+    protected boolean isValidProtocolAndVnetId(final String vNetId, final String protocol) {
+        return vNetId != null && protocol != null && !vNetId.equalsIgnoreCase("untagged");
+    }
+
+    @Override
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("nic=" + nic);
+            if (nicAdapter != null && !nicAdapter.isEmpty()) {
+                s_logger.debug("custom nic adapter=" + nicAdapter);
+            }
+        }
+
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+
+        String vNetId = null;
+        String protocol = null;
+        if (isBroadcastTypeVlanOrVxlan(nic)) {
+            vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+            protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
+        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
+            throw new InternalErrorException("Nicira NVP Logicalswitches are not supported by the BridgeVifDriver");
+        }
+        String trafficLabel = nic.getName();
+        Integer networkRateKBps = 0;
+        if (libvirtVersion > ((10 * 1000 + 10))) {
+            networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+        }
+
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
+                    if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                        s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel);
+                        String brName = createVnetBr(vNetId, trafficLabel, protocol);
+                        intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                    } else {
+                        String brName = createVnetBr(vNetId, "private", protocol);
+                        intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                    }
+            } else {
+                String brname = "";
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    brname = trafficLabel;
+                } else {
+                    brname = _bridges.get("guest");
+                }
+                intf.defBridgeNet(brname, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            }
+        } else if (nic.getType() == Networks.TrafficType.Control) {
+            /* Make sure the network is still there */
+            createControlNetwork();
+            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
+                    String brName = createVnetBr(vNetId, trafficLabel, protocol);
+                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                } else {
+                    String brName = createVnetBr(vNetId, "public", protocol);
+                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                }
+            } else {
+                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            }
+        } else if (nic.getType() == Networks.TrafficType.Management) {
+            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Storage) {
+            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
+            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        }
+        if (nic.getPxeDisable()) {
+            intf.setPxeDisable(true);
+        }
+
+        return intf;
+    }
+
+    @Override
+    public void unplug(LibvirtVMDef.InterfaceDef iface) {
+        deleteVnetBr(iface.getBrName());
+    }
+
+    @Override
+    public void attach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("brctl addif " + iface.getBrName() + " " + iface.getDevName());
+    }
+
+    @Override
+    public void detach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("test -d /sys/class/net/" + iface.getBrName() + "/brif/" + iface.getDevName() + " && brctl delif " + iface.getBrName() + " " + iface.getDevName());
+    }
+
+    private String generateVnetBrName(String pifName, String vnetId) {
+        return "br" + pifName + "-" + vnetId;
+    }
+
+    private String generateVxnetBrName(String pifName, String vnetId) {
+        return "brvx-" + vnetId;
+    }
+
+    private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
+        String nic = _pifs.get(pifKey);
+        if (nic == null) {
+            // if not found in bridge map, maybe traffic label refers to pif already?
+            File pif = new File("/sys/class/net/" + pifKey);
+            if (pif.isDirectory()) {
+                nic = pifKey;
+            }
+        }
+        String brName = "";
+        if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+            brName = generateVxnetBrName(nic, vNetId);
+        } else {
+            brName = generateVnetBrName(nic, vNetId);
+        }
+        createVnet(vNetId, nic, brName, protocol);
+        return brName;
+    }
+
+    private void createVnet(String vnetId, String pif, String brName, String protocol) throws InternalErrorException {
+        synchronized (_vnetBridgeMonitor) {
+            String script = _modifyVlanPath;
+            if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+                script = _modifyVxlanPath;
+            }
+            final Script command = new Script(script, _timeout, s_logger);
+            command.add("-v", vnetId);
+            command.add("-p", pif);
+            command.add("-b", brName);
+            command.add("-o", "add");
+
+            final String result = command.execute();
+            if (result != null) {
+                throw new InternalErrorException("Failed to create vnet " + vnetId + ": " + result);
+            }
+        }
+    }
+
+    private void deleteVnetBr(String brName) {
+        synchronized (_vnetBridgeMonitor) {
+            String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName);
+            if (cmdout == null)
+                // Bridge does not exist
+                return;
+            cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
+            if (cmdout != null && cmdout.contains("vnet")) {
+                // Active VM remains on that bridge
+                return;
+            }
+
+            Pattern oldStyleBrNameRegex = Pattern.compile("^cloudVirBr(\\d+)$");
+            Pattern brNameRegex = Pattern.compile("^br(\\S+)-(\\d+)$");
+            Matcher oldStyleBrNameMatcher = oldStyleBrNameRegex.matcher(brName);
+            Matcher brNameMatcher = brNameRegex.matcher(brName);
+
+            String pName = null;
+            String vNetId = null;
+            if (oldStyleBrNameMatcher.find()) {
+                // Actually modifyvlan.sh doesn't require pif name when deleting its bridge so far.
+                pName = "undefined";
+                vNetId = oldStyleBrNameMatcher.group(1);
+            } else if (brNameMatcher.find()) {
+                if (brNameMatcher.group(1) != null || !brNameMatcher.group(1).isEmpty()) {
+                    pName = brNameMatcher.group(1);
+                } else {
+                    pName = "undefined";
+                }
+                vNetId = brNameMatcher.group(2);
+            }
+
+            if (vNetId == null || vNetId.isEmpty()) {
+                s_logger.debug("unable to get a vNet ID from name " + brName);
+                return;
+            }
+
+            String scriptPath = null;
+            if (cmdout != null && cmdout.contains("vxlan")) {
+                scriptPath = _modifyVxlanPath;
+            } else {
+                scriptPath = _modifyVlanPath;
+            }
+
+            final Script command = new Script(scriptPath, _timeout, s_logger);
+            command.add("-o", "delete");
+            command.add("-v", vNetId);
+            command.add("-p", pName);
+            command.add("-b", brName);
+
+            final String result = command.execute();
+            if (result != null) {
+                s_logger.debug("Delete bridge " + brName + " failed: " + result);
+            }
+        }
+    }
+
+    private void deleteExistingLinkLocalRouteTable(String linkLocalBr) {
+        Script command = new Script("/bin/bash", _timeout);
+        command.add("-c");
+        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        boolean foundLinkLocalBr = false;
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                String[] tokens = line.split(" ");
+                if (tokens != null && tokens.length < 2) {
+                    continue;
+                }
+                final String device = tokens[2];
+                if (!Strings.isNullOrEmpty(device) && !device.equalsIgnoreCase(linkLocalBr)) {
+                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR() + " dev " + tokens[2]);
+                } else {
+                    foundLinkLocalBr = true;
+                }
+            }
+        }
+        if (!foundLinkLocalBr) {
+            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
+                    NetUtils.getLinkLocalGateway());
+        }
+    }
+
+    private void createControlNetwork() {
+        createControlNetwork(_bridges.get("linklocal"));
+    }
+
+    @Override
+    public void createControlNetwork(String privBrName)  {
+        deleteExistingLinkLocalRouteTable(privBrName);
+        if (!isExistingBridge(privBrName)) {
+            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
+        }
+    }
+
+    @Override
+    public boolean isExistingBridge(String bridgeName) {
+        File f = new File("/sys/devices/virtual/net/" + bridgeName + "/bridge");
+        if (f.exists()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
new file mode 100644
index 0000000..de65a37
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
@@ -0,0 +1,83 @@
+/*
+ * 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;
+
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Networks;
+
+import java.util.Map;
+
+public class DirectVifDriver extends VifDriverBase {
+
+    private static final Logger s_logger = Logger.getLogger(DirectVifDriver.class);
+
+    /**
+     * Experimental driver to configure direct networking in libvirt. This should only
+     * be used on an LXC cluster that does not run any system VMs.
+     *
+     * @param nic
+     * @param guestOsType
+     * @param extraConfig
+     * @return
+     * @throws InternalErrorException
+     * @throws LibvirtException
+     */
+    @Override
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter),
+                _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps);
+
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter),
+                _libvirtComputingResource.getNetworkDirectSourceMode(), networkRateKBps);
+        }
+
+        return intf;
+    }
+
+    @Override
+    public void unplug(LibvirtVMDef.InterfaceDef iface) {
+        // not needed, libvirt will cleanup
+    }
+
+    @Override
+    public void attach(LibvirtVMDef.InterfaceDef iface) {
+
+    }
+
+    @Override
+    public void detach(LibvirtVMDef.InterfaceDef iface) {
+
+    }
+
+    @Override
+    public void createControlNetwork(String privBrName) {
+    }
+
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java
new file mode 100644
index 0000000..4ba0114
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/IvsVifDriver.java
@@ -0,0 +1,296 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.network.Networks;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+public class IvsVifDriver extends VifDriverBase {
+    private static final Logger s_logger = Logger.getLogger(IvsVifDriver.class);
+    private int _timeout;
+
+    private final Object _vnetBridgeMonitor = new Object();
+    private String _modifyVlanPath;
+    private String _modifyVxlanPath;
+    private String _ivsIfUpPath;
+    private Long libvirtVersion;
+
+    @Override
+    public void configure(Map<String, Object> params) throws ConfigurationException {
+        super.configure(params);
+        String networkScriptsDir = (String)params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = "scripts/vm/network/vnet";
+        }
+        String utilScriptsDir = "scripts/util/";
+
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
+
+        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
+        if (_modifyVlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvlan.sh");
+        }
+        _modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
+        if (_modifyVxlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvxlan.sh");
+        }
+        _ivsIfUpPath = Script.findScript(utilScriptsDir, "qemu-ivs-ifup");
+
+        libvirtVersion = (Long) params.get("libvirtVersion");
+        if (libvirtVersion == null) {
+            libvirtVersion = 0L;
+        }
+    }
+
+    @Override
+    public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+
+        String vNetId = null;
+        String protocol = null;
+        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
+            vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+            protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
+        }
+
+        String vlanId = null;
+        String logicalSwitchUuid = null;
+        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
+            vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
+            logicalSwitchUuid = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
+            // TODO consider moving some of this functionality from NetUtils to Networks....
+            vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
+        }
+        String trafficLabel = nic.getName();
+        Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) &&
+                    !vlanId.equalsIgnoreCase("untagged")) {
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
+                    intf.defEthernet("ivsnet-" + nic.getUuid().substring(0, 5), nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), _ivsIfUpPath, networkRateKBps);
+                } else {
+                    throw new InternalErrorException("no traffic label ");
+                }
+            }
+        } else if (nic.getType() == Networks.TrafficType.Control) {
+            /* Make sure the network is still there */
+            createControlNetwork();
+            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) ||
+                    (nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) {
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
+                    String brName = createVnetBr(vNetId, trafficLabel, protocol);
+                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                } else {
+                    String brName = createVnetBr(vNetId, "public", protocol);
+                    intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                }
+            } else {
+                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            }
+        } else if (nic.getType() == Networks.TrafficType.Management) {
+            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Storage) {
+            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
+            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        }
+        if (nic.getPxeDisable() == true) {
+            intf.setPxeDisable(true);
+        }
+        return intf;
+    }
+
+    @Override
+    public void unplug(InterfaceDef iface) {
+    }
+
+    @Override
+    public void attach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("/usr/sbin/ivs-ctl add-port " + iface.getDevName());
+    }
+
+    @Override
+    public void detach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("/usr/sbin/ivs-ctl del-port " + iface.getDevName());
+    }
+
+
+    private void createControlNetwork() throws LibvirtException {
+        createControlNetwork(_bridges.get("linklocal"));
+    }
+
+    private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
+        String nic = _pifs.get(pifKey);
+        if (nic == null) {
+            // if not found in bridge map, maybe traffic label refers to pif already?
+            File pif = new File("/sys/class/net/" + pifKey);
+            if (pif.isDirectory()) {
+                nic = pifKey;
+            }
+        }
+        String brName = "";
+        brName = generateVnetBrName(nic, vNetId);
+        createVnet(vNetId, nic, brName, protocol);
+        return brName;
+    }
+
+    private String generateVnetBrName(String pifName, String vnetId) {
+        return "br" + pifName + "-" + vnetId;
+    }
+
+    private void createVnet(String vnetId, String pif, String brName, String protocol) throws InternalErrorException {
+        synchronized (_vnetBridgeMonitor) {
+            String script = _modifyVlanPath;
+            if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+                script = _modifyVxlanPath;
+            }
+            final Script command = new Script(script, _timeout, s_logger);
+            command.add("-v", vnetId);
+            command.add("-p", pif);
+            command.add("-b", brName);
+            command.add("-o", "add");
+
+            final String result = command.execute();
+            if (result != null) {
+                throw new InternalErrorException("Failed to create vnet " + vnetId + ": " + result);
+            }
+        }
+    }
+
+    private void deleteVnetBr(String brName) {
+        synchronized (_vnetBridgeMonitor) {
+            String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName);
+            if (cmdout == null)
+                // Bridge does not exist
+                return;
+            cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
+            if (cmdout != null && cmdout.contains("vnet")) {
+                // Active VM remains on that bridge
+                return;
+            }
+
+            Pattern oldStyleBrNameRegex = Pattern.compile("^cloudVirBr(\\d+)$");
+            Pattern brNameRegex = Pattern.compile("^br(\\S+)-(\\d+)$");
+            Matcher oldStyleBrNameMatcher = oldStyleBrNameRegex.matcher(brName);
+            Matcher brNameMatcher = brNameRegex.matcher(brName);
+
+            String pName = null;
+            String vNetId = null;
+            if (oldStyleBrNameMatcher.find()) {
+                // Actually modifyvlan.sh doesn't require pif name when deleting its bridge so far.
+                pName = "undefined";
+                vNetId = oldStyleBrNameMatcher.group(1);
+            } else if (brNameMatcher.find()) {
+                if (brNameMatcher.group(1) != null || !brNameMatcher.group(1).isEmpty()) {
+                    pName = brNameMatcher.group(1);
+                } else {
+                    pName = "undefined";
+                }
+                vNetId = brNameMatcher.group(2);
+            }
+
+            if (vNetId == null || vNetId.isEmpty()) {
+                s_logger.debug("unable to get a vNet ID from name " + brName);
+                return;
+            }
+
+            String scriptPath = null;
+            if (cmdout != null && cmdout.contains("vxlan")) {
+                scriptPath = _modifyVxlanPath;
+            } else {
+                scriptPath = _modifyVlanPath;
+            }
+
+            final Script command = new Script(scriptPath, _timeout, s_logger);
+            command.add("-o", "delete");
+            command.add("-v", vNetId);
+            command.add("-p", pName);
+            command.add("-b", brName);
+
+            final String result = command.execute();
+            if (result != null) {
+                s_logger.debug("Delete bridge " + brName + " failed: " + result);
+            }
+        }
+    }
+
+    private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
+        Script command = new Script("/bin/bash", _timeout);
+        command.add("-c");
+        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        boolean foundLinkLocalBr = false;
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                String[] tokens = line.split(" ");
+                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
+                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
+                } else {
+                    foundLinkLocalBr = true;
+                }
+            }
+        }
+        if (!foundLinkLocalBr) {
+            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
+                NetUtils.getLinkLocalGateway());
+        }
+    }
+
+    @Override
+    public void createControlNetwork(String privBrName) {
+        deleteExitingLinkLocalRouteTable(privBrName);
+        if (!isBridgeExists(privBrName)) {
+            Script.runSimpleBashScript("brctl addbr " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
+        }
+    }
+
+    private boolean isBridgeExists(String bridgeName) {
+        File f = new File("/sys/devices/virtual/net/" + bridgeName);
+        if (f.exists()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHABase.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHABase.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHABase.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAChecker.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAChecker.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAChecker.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAChecker.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAMonitor.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAVMActivityChecker.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAVMActivityChecker.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMHAVMActivityChecker.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/KVMHAVMActivityChecker.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtCapXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtCapXMLParser.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtCapXMLParser.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtCapXMLParser.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
new file mode 100644
index 0000000..2436dc4
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -0,0 +1,3850 @@
+// 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;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import com.cloud.resource.RequestWrapper;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.hypervisor.HypervisorUtils;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.KVMHostInfo;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.security.KeyStoreUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.log4j.Logger;
+import org.joda.time.Duration;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainBlockStats;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.DomainInterfaceStats;
+import org.libvirt.DomainSnapshot;
+import org.libvirt.LibvirtException;
+import org.libvirt.MemoryStatistic;
+import org.libvirt.NodeInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.VmDiskStatsEntry;
+import com.cloud.agent.api.VmNetworkStatsEntry;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VRScripts;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.dc.Vlan;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DeviceType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiscardType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiskProtocol;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FilesystemDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GraphicDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.GuestNetType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
+import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper;
+import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper;
+import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.hypervisor.kvm.storage.KVMStorageProcessor;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.RouterPrivateIpStrategy;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Volume;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.utils.ExecutionResult;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.OutputInterpreter.AllLinesParser;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VmDetailConstants;
+import com.google.common.base.Strings;
+
+/**
+ * LibvirtComputingResource execute requests on the computing/routing host using
+ * the libvirt API
+ *
+ * @config {@table || Param Name | Description | Values | Default || ||
+ *         hypervisor.type | type of local hypervisor | string | kvm || ||
+ *         hypervisor.uri | local hypervisor to connect to | URI |
+ *         qemu:///system || || domr.arch | instruction set for domr template |
+ *         string | i686 || || private.bridge.name | private bridge where the
+ *         domrs have their private interface | string | vmops0 || ||
+ *         public.bridge.name | public bridge where the domrs have their public
+ *         interface | string | br0 || || private.network.name | name of the
+ *         network where the domrs have their private interface | string |
+ *         vmops-private || || private.ipaddr.start | start of the range of
+ *         private ip addresses for domrs | ip address | 192.168.166.128 || ||
+ *         private.ipaddr.end | end of the range of private ip addresses for
+ *         domrs | ip address | start + 126 || || private.macaddr.start | start
+ *         of the range of private mac addresses for domrs | mac address |
+ *         00:16:3e:77:e2:a0 || || private.macaddr.end | end of the range of
+ *         private mac addresses for domrs | mac address | start + 126 || ||
+ *         pool | the parent of the storage pool hierarchy * }
+ **/
+public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer {
+    private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class);
+
+    private String _modifyVlanPath;
+    private String _versionstringpath;
+    private String _patchScriptPath;
+    private String _createvmPath;
+    private String _manageSnapshotPath;
+    private String _resizeVolumePath;
+    private String _createTmplPath;
+    private String _heartBeatPath;
+    private String _vmActivityCheckPath;
+    private String _securityGroupPath;
+    private String _ovsPvlanDhcpHostPath;
+    private String _ovsPvlanVmPath;
+    private String _routerProxyPath;
+    private String _ovsTunnelPath;
+    private String _host;
+    private String _dcId;
+    private String _pod;
+    private String _clusterId;
+
+    private long _hvVersion;
+    private Duration _timeout;
+    private static final int NUMMEMSTATS =2;
+
+    private KVMHAMonitor _monitor;
+    public static final String SSHKEYSPATH = "/root/.ssh";
+    public static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud";
+    public static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud";
+
+    public static final String BASH_SCRIPT_PATH = "/bin/bash";
+
+    private String _mountPoint = "/mnt";
+    private StorageLayer _storage;
+    private KVMStoragePoolManager _storagePoolMgr;
+
+    private VifDriver _defaultVifDriver;
+    private Map<TrafficType, VifDriver> _trafficTypeVifDrivers;
+
+    protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver";
+    protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver";
+
+    protected HypervisorType _hypervisorType;
+    protected String _hypervisorURI;
+    protected long _hypervisorLibvirtVersion;
+    protected long _hypervisorQemuVersion;
+    protected String _hypervisorPath;
+    protected String _hostDistro;
+    protected String _networkDirectSourceMode;
+    protected String _networkDirectDevice;
+    protected String _sysvmISOPath;
+    protected String _privNwName;
+    protected String _privBridgeName;
+    protected String _linkLocalBridgeName;
+    protected String _publicBridgeName;
+    protected String _guestBridgeName;
+    protected String _privateIp;
+    protected String _pool;
+    protected String _localGateway;
+    private boolean _canBridgeFirewall;
+    protected String _localStoragePath;
+    protected String _localStorageUUID;
+    protected boolean _noMemBalloon = false;
+    protected String _guestCpuMode;
+    protected String _guestCpuModel;
+    protected boolean _noKvmClock;
+    protected String _videoHw;
+    protected int _videoRam;
+    protected Pair<Integer,Integer> hostOsVersion;
+    protected int _migrateSpeed;
+    protected int _migrateDowntime;
+    protected int _migratePauseAfter;
+    protected boolean _diskActivityCheckEnabled;
+    protected long _diskActivityCheckFileSizeMin = 10485760; // 10MB
+    protected int _diskActivityCheckTimeoutSeconds = 120; // 120s
+    protected long _diskActivityInactiveThresholdMilliseconds = 30000; // 30s
+    protected boolean _rngEnable = false;
+    protected RngBackendModel _rngBackendModel = RngBackendModel.RANDOM;
+    protected String _rngPath = "/dev/random";
+    protected int _rngRatePeriod = 1000;
+    protected int _rngRateBytes = 2048;
+    protected File _qemuSocketsPath;
+    private final String _qemuGuestAgentSocketName = "org.qemu.guest_agent.0";
+    protected WatchDogAction _watchDogAction = WatchDogAction.NONE;
+    protected WatchDogModel _watchDogModel = WatchDogModel.I6300ESB;
+
+    private final Map <String, String> _pifs = new HashMap<String, String>();
+    private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>();
+
+    protected static final HashMap<DomainState, PowerState> s_powerStatesTable;
+    static {
+        s_powerStatesTable = new HashMap<DomainState, PowerState>();
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff);
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn);
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn);
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn);
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown);
+        s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff);
+    }
+
+    private VirtualRoutingResource _virtRouterResource;
+
+    private String _pingTestPath;
+
+    private String _updateHostPasswdPath;
+
+    private long _dom0MinMem;
+
+    private long _dom0OvercommitMem;
+
+    protected int _cmdsTimeout;
+    protected int _stopTimeout;
+    protected CPUStat _cpuStat = new CPUStat();
+    protected MemStat _memStat = new MemStat(_dom0MinMem, _dom0OvercommitMem);
+    private final LibvirtUtilitiesHelper libvirtUtilitiesHelper = new LibvirtUtilitiesHelper();
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIp, final String script, final String args) {
+        return executeInVR(routerIp, script, args, _timeout);
+    }
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final Duration timeout) {
+        final Script command = new Script(_routerProxyPath, timeout, s_logger);
+        final AllLinesParser parser = new AllLinesParser();
+        command.add(script);
+        command.add(routerIp);
+        if (args != null) {
+            command.add(args);
+        }
+        String details = command.execute(parser);
+        if (details == null) {
+            details = parser.getLines();
+        }
+
+        s_logger.debug("Executing script in VR: " + script);
+
+        return new ExecutionResult(command.getExitValue() == 0, details);
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) {
+        final File permKey = new File("/root/.ssh/id_rsa.cloud");
+        boolean success = true;
+        String details = "Creating file in VR, with ip: " + routerIp + ", file: " + filename;
+        s_logger.debug(details);
+
+        try {
+            SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null);
+        } catch (final Exception e) {
+            s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e);
+            details = e.getMessage();
+            success = false;
+        }
+        return new ExecutionResult(success, details);
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
+        //Update IP used to access router
+        cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
+        if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) {
+            return cleanupNetworkElementCommand((IpAssocCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    public LibvirtUtilitiesHelper getLibvirtUtilitiesHelper() {
+        return libvirtUtilitiesHelper;
+    }
+
+    public CPUStat getCPUStat() {
+        return _cpuStat;
+    }
+
+    public MemStat getMemStat() {
+        return _memStat;
+    }
+
+    public VirtualRoutingResource getVirtRouterResource() {
+        return _virtRouterResource;
+    }
+
+    public String getPublicBridgeName() {
+        return _publicBridgeName;
+    }
+
+    public KVMStoragePoolManager getStoragePoolMgr() {
+        return _storagePoolMgr;
+    }
+
+    public String getPrivateIp() {
+        return _privateIp;
+    }
+
+    public int getMigrateDowntime() {
+        return _migrateDowntime;
+    }
+
+    public int getMigratePauseAfter() {
+        return _migratePauseAfter;
+    }
+
+    public int getMigrateSpeed() {
+        return _migrateSpeed;
+    }
+
+    public String getPingTestPath() {
+        return _pingTestPath;
+    }
+
+    public String getUpdateHostPasswdPath() {
+        return _updateHostPasswdPath;
+    }
+
+    public Duration getTimeout() {
+        return _timeout;
+    }
+
+    public String getOvsTunnelPath() {
+        return _ovsTunnelPath;
+    }
+
+    public KVMHAMonitor getMonitor() {
+        return _monitor;
+    }
+
+    public StorageLayer getStorage() {
+        return _storage;
+    }
+
+    public String createTmplPath() {
+        return _createTmplPath;
+    }
+
+    public int getCmdsTimeout() {
+        return _cmdsTimeout;
+    }
+
+    public String manageSnapshotPath() {
+        return _manageSnapshotPath;
+    }
+
+    public String getGuestBridgeName() {
+        return _guestBridgeName;
+    }
+
+    public String getVmActivityCheckPath() {
+        return _vmActivityCheckPath;
+    }
+
+    public String getOvsPvlanDhcpHostPath() {
+        return _ovsPvlanDhcpHostPath;
+    }
+
+    public String getOvsPvlanVmPath() {
+        return _ovsPvlanVmPath;
+    }
+
+    public String getResizeVolumePath() {
+        return _resizeVolumePath;
+    }
+
+    public StorageSubsystemCommandHandler getStorageHandler() {
+        return storageHandler;
+    }
+
+    private static final class KeyValueInterpreter extends OutputInterpreter {
+        private final Map<String, String> map = new HashMap<String, String>();
+
+        @Override
+        public String interpret(final BufferedReader reader) throws IOException {
+            String line = null;
+            int numLines = 0;
+            while ((line = reader.readLine()) != null) {
+                final String[] toks = line.trim().split("=");
+                if (toks.length < 2) {
+                    s_logger.warn("Failed to parse Script output: " + line);
+                } else {
+                    map.put(toks[0].trim(), toks[1].trim());
+                }
+                numLines++;
+            }
+            if (numLines == 0) {
+                s_logger.warn("KeyValueInterpreter: no output lines?");
+            }
+            return null;
+        }
+
+        public Map<String, String> getKeyValues() {
+            return map;
+        }
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return null;
+    }
+
+    protected List<String> _cpuFeatures;
+
+    protected enum BridgeType {
+        NATIVE, OPENVSWITCH
+    }
+
+    protected BridgeType _bridgeType;
+
+    protected StorageSubsystemCommandHandler storageHandler;
+
+    protected boolean dpdkSupport = false;
+    protected String dpdkOvsPath;
+    protected static final String DPDK_NUMA = ApiConstants.EXTRA_CONFIG + "-dpdk-numa";
+    protected static final String DPDK_HUGE_PAGES = ApiConstants.EXTRA_CONFIG + "-dpdk-hugepages";
+    protected static final String DPDK_INTERFACE_PREFIX = ApiConstants.EXTRA_CONFIG + "-dpdk-interface-";
+
+    private String getEndIpFromStartIp(final String startIp, final int numIps) {
+        final String[] tokens = startIp.split("[.]");
+        assert tokens.length == 4;
+        int lastbyte = Integer.parseInt(tokens[3]);
+        lastbyte = lastbyte + numIps;
+        tokens[3] = Integer.toString(lastbyte);
+        final StringBuilder end = new StringBuilder(15);
+        end.append(tokens[0]).append(".").append(tokens[1]).append(".").append(tokens[2]).append(".").append(tokens[3]);
+        return end.toString();
+    }
+
+    private Map<String, Object> getDeveloperProperties() throws ConfigurationException {
+
+        final File file = PropertiesUtil.findConfigFile("developer.properties");
+        if (file == null) {
+            throw new ConfigurationException("Unable to find developer.properties.");
+        }
+
+        s_logger.info("developer.properties found at " + file.getAbsolutePath());
+        try {
+            final Properties properties = PropertiesUtil.loadFromFile(file);
+
+            final String startMac = (String)properties.get("private.macaddr.start");
+            if (startMac == null) {
+                throw new ConfigurationException("Developers must specify start mac for private ip range");
+            }
+
+            final String startIp = (String)properties.get("private.ipaddr.start");
+            if (startIp == null) {
+                throw new ConfigurationException("Developers must specify start ip for private ip range");
+            }
+            final Map<String, Object> params = PropertiesUtil.toMap(properties);
+
+            String endIp = (String)properties.get("private.ipaddr.end");
+            if (endIp == null) {
+                endIp = getEndIpFromStartIp(startIp, 16);
+                params.put("private.ipaddr.end", endIp);
+            }
+            return params;
+        } catch (final FileNotFoundException ex) {
+            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+        } catch (final IOException ex) {
+            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+        }
+    }
+
+    protected String getDefaultNetworkScriptsDir() {
+        return "scripts/vm/network/vnet";
+    }
+
+    protected String getDefaultStorageScriptsDir() {
+        return "scripts/storage/qcow2";
+    }
+
+    protected String getDefaultHypervisorScriptsDir() {
+        return "scripts/vm/hypervisor";
+    }
+
+    protected String getDefaultKvmScriptsDir() {
+        return "scripts/vm/hypervisor/kvm";
+    }
+
+    protected String getDefaultDomrScriptsDir() {
+        return "scripts/network/domr";
+    }
+
+    protected String getNetworkDirectSourceMode() {
+        return _networkDirectSourceMode;
+    }
+
+    protected String getNetworkDirectDevice() {
+        return _networkDirectDevice;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        boolean success = super.configure(name, params);
+        if (!success) {
+            return false;
+        }
+
+        _storage = new JavaStorageLayer();
+        _storage.configure("StorageLayer", params);
+
+        String domrScriptsDir = (String)params.get("domr.scripts.dir");
+        if (domrScriptsDir == null) {
+            domrScriptsDir = getDefaultDomrScriptsDir();
+        }
+
+        String hypervisorScriptsDir = (String)params.get("hypervisor.scripts.dir");
+        if (hypervisorScriptsDir == null) {
+            hypervisorScriptsDir = getDefaultHypervisorScriptsDir();
+        }
+
+        String kvmScriptsDir = (String)params.get("kvm.scripts.dir");
+        if (kvmScriptsDir == null) {
+            kvmScriptsDir = getDefaultKvmScriptsDir();
+        }
+
+        String networkScriptsDir = (String)params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = getDefaultNetworkScriptsDir();
+        }
+
+        String storageScriptsDir = (String)params.get("storage.scripts.dir");
+        if (storageScriptsDir == null) {
+            storageScriptsDir = getDefaultStorageScriptsDir();
+        }
+
+        final String bridgeType = (String)params.get("network.bridge.type");
+        if (bridgeType == null) {
+            _bridgeType = BridgeType.NATIVE;
+        } else {
+            _bridgeType = BridgeType.valueOf(bridgeType.toUpperCase());
+        }
+
+        String dpdk = (String) params.get("openvswitch.dpdk.enabled");
+        if (_bridgeType == BridgeType.OPENVSWITCH && Boolean.parseBoolean(dpdk)) {
+            dpdkSupport = true;
+            dpdkOvsPath = (String) params.get("openvswitch.dpdk.ovs.path");
+            if (dpdkOvsPath != null && !dpdkOvsPath.endsWith("/")) {
+                dpdkOvsPath += "/";
+            }
+        }
+
+        params.put("domr.scripts.dir", domrScriptsDir);
+
+        _virtRouterResource = new VirtualRoutingResource(this);
+        success = _virtRouterResource.configure(name, params);
+
+        if (!success) {
+            return false;
+        }
+
+        _host = (String)params.get("host");
+        if (_host == null) {
+            _host = "localhost";
+        }
+
+        _dcId = (String)params.get("zone");
+        if (_dcId == null) {
+            _dcId = "default";
+        }
+
+        _pod = (String)params.get("pod");
+        if (_pod == null) {
+            _pod = "default";
+        }
+
+        _clusterId = (String)params.get("cluster");
+
+        _updateHostPasswdPath = Script.findScript(hypervisorScriptsDir, VRScripts.UPDATE_HOST_PASSWD);
+        if (_updateHostPasswdPath == null) {
+            throw new ConfigurationException("Unable to find update_host_passwd.sh");
+        }
+
+        _modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
+        if (_modifyVlanPath == null) {
+            throw new ConfigurationException("Unable to find modifyvlan.sh");
+        }
+
+        _versionstringpath = Script.findScript(kvmScriptsDir, "versions.sh");
+        if (_versionstringpath == null) {
+            throw new ConfigurationException("Unable to find versions.sh");
+        }
+
+        _patchScriptPath = Script.findScript(kvmScriptsDir, "patch.sh");
+        if (_patchScriptPath == null) {
+            throw new ConfigurationException("Unable to find patch.sh");
+        }
+
+        _heartBeatPath = Script.findScript(kvmScriptsDir, "kvmheartbeat.sh");
+        if (_heartBeatPath == null) {
+            throw new ConfigurationException("Unable to find kvmheartbeat.sh");
+        }
+
+        _createvmPath = Script.findScript(storageScriptsDir, "createvm.sh");
+        if (_createvmPath == null) {
+            throw new ConfigurationException("Unable to find the createvm.sh");
+        }
+
+        _manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh");
+        if (_manageSnapshotPath == null) {
+            throw new ConfigurationException("Unable to find the managesnapshot.sh");
+        }
+
+        _resizeVolumePath = Script.findScript(storageScriptsDir, "resizevolume.sh");
+        if (_resizeVolumePath == null) {
+            throw new ConfigurationException("Unable to find the resizevolume.sh");
+        }
+
+        _vmActivityCheckPath = Script.findScript(kvmScriptsDir, "kvmvmactivity.sh");
+        if (_vmActivityCheckPath == null) {
+            throw new ConfigurationException("Unable to find kvmvmactivity.sh");
+        }
+
+        _createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh");
+        if (_createTmplPath == null) {
+            throw new ConfigurationException("Unable to find the createtmplt.sh");
+        }
+
+        _securityGroupPath = Script.findScript(networkScriptsDir, "security_group.py");
+        if (_securityGroupPath == null) {
+            throw new ConfigurationException("Unable to find the security_group.py");
+        }
+
+        _ovsTunnelPath = Script.findScript(networkScriptsDir, "ovstunnel.py");
+        if (_ovsTunnelPath == null) {
+            throw new ConfigurationException("Unable to find the ovstunnel.py");
+        }
+
+        _routerProxyPath = Script.findScript("scripts/network/domr/", "router_proxy.sh");
+        if (_routerProxyPath == null) {
+            throw new ConfigurationException("Unable to find the router_proxy.sh");
+        }
+
+        _ovsPvlanDhcpHostPath = Script.findScript(networkScriptsDir, "ovs-pvlan-dhcp-host.sh");
+        if (_ovsPvlanDhcpHostPath == null) {
+            throw new ConfigurationException("Unable to find the ovs-pvlan-dhcp-host.sh");
+        }
+
+        _ovsPvlanVmPath = Script.findScript(networkScriptsDir, "ovs-pvlan-vm.sh");
+        if (_ovsPvlanVmPath == null) {
+            throw new ConfigurationException("Unable to find the ovs-pvlan-vm.sh");
+        }
+
+        String value = (String)params.get("developer");
+        final boolean isDeveloper = Boolean.parseBoolean(value);
+
+        if (isDeveloper) {
+            params.putAll(getDeveloperProperties());
+        }
+
+        _pool = (String)params.get("pool");
+        if (_pool == null) {
+            _pool = "/root";
+        }
+
+        final String instance = (String)params.get("instance");
+
+        _hypervisorType = HypervisorType.getType((String)params.get("hypervisor.type"));
+        if (_hypervisorType == HypervisorType.None) {
+            _hypervisorType = HypervisorType.KVM;
+        }
+
+        _hypervisorURI = (String)params.get("hypervisor.uri");
+        if (_hypervisorURI == null) {
+            _hypervisorURI = LibvirtConnection.getHypervisorURI(_hypervisorType.toString());
+        }
+
+        _networkDirectSourceMode = (String)params.get("network.direct.source.mode");
+        _networkDirectDevice = (String)params.get("network.direct.device");
+
+        String startMac = (String)params.get("private.macaddr.start");
+        if (startMac == null) {
+            startMac = "00:16:3e:77:e2:a0";
+        }
+
+        String startIp = (String)params.get("private.ipaddr.start");
+        if (startIp == null) {
+            startIp = "192.168.166.128";
+        }
+
+        _pingTestPath = Script.findScript(kvmScriptsDir, "pingtest.sh");
+        if (_pingTestPath == null) {
+            throw new ConfigurationException("Unable to find the pingtest.sh");
+        }
+
+        _linkLocalBridgeName = (String)params.get("private.bridge.name");
+        if (_linkLocalBridgeName == null) {
+            if (isDeveloper) {
+                _linkLocalBridgeName = "cloud-" + instance + "-0";
+            } else {
+                _linkLocalBridgeName = "cloud0";
+            }
+        }
+
+        _publicBridgeName = (String)params.get("public.network.device");
+        if (_publicBridgeName == null) {
+            _publicBridgeName = "cloudbr0";
+        }
+
+        _privBridgeName = (String)params.get("private.network.device");
+        if (_privBridgeName == null) {
+            _privBridgeName = "cloudbr1";
+        }
+
+        _guestBridgeName = (String)params.get("guest.network.device");
+        if (_guestBridgeName == null) {
+            _guestBridgeName = _privBridgeName;
+        }
+
+        _privNwName = (String)params.get("private.network.name");
+        if (_privNwName == null) {
+            if (isDeveloper) {
+                _privNwName = "cloud-" + instance + "-private";
+            } else {
+                _privNwName = "cloud-private";
+            }
+        }
+
+        _localStoragePath = (String)params.get("local.storage.path");
+        if (_localStoragePath == null) {
+            _localStoragePath = "/var/lib/libvirt/images/";
+        }
+
+        /* Directory to use for Qemu sockets like for the Qemu Guest Agent */
+        _qemuSocketsPath = new File("/var/lib/libvirt/qemu");
+        String _qemuSocketsPathVar = (String)params.get("qemu.sockets.path");
+        if (_qemuSocketsPathVar != null && StringUtils.isNotBlank(_qemuSocketsPathVar)) {
+            _qemuSocketsPath = new File(_qemuSocketsPathVar);
+        }
+
+        final File storagePath = new File(_localStoragePath);
+        _localStoragePath = storagePath.getAbsolutePath();
+
+        _localStorageUUID = (String)params.get("local.storage.uuid");
+        if (_localStorageUUID == null) {
+            _localStorageUUID = UUID.randomUUID().toString();
+        }
+
+        value = (String)params.get("scripts.timeout");
+        _timeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 30 * 60));
+
+        value = (String)params.get("stop.script.timeout");
+        _stopTimeout = NumbersUtil.parseInt(value, 120) * 1000;
+
+        value = (String)params.get("cmds.timeout");
+        _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000;
+
+        value = (String) params.get("vm.memballoon.disable");
+        if (Boolean.parseBoolean(value)) {
+            _noMemBalloon = true;
+        }
+
+        _videoHw = (String) params.get("vm.video.hardware");
+        value = (String) params.get("vm.video.ram");
+        _videoRam = NumbersUtil.parseInt(value, 0);
+
+        value = (String)params.get("host.reserved.mem.mb");
+        // Reserve 1GB unless admin overrides
+        _dom0MinMem = NumbersUtil.parseInt(value, 1024) * 1024* 1024L;
+
+        value = (String)params.get("host.overcommit.mem.mb");
+        // Support overcommit memory for host if host uses ZSWAP, KSM and other memory
+        // compressing technologies
+        _dom0OvercommitMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024L;
+
+        value = (String) params.get("kvmclock.disable");
+        if (Boolean.parseBoolean(value)) {
+            _noKvmClock = true;
+        }
+
+        value = (String) params.get("vm.rng.enable");
+        if (Boolean.parseBoolean(value)) {
+            _rngEnable = true;
+
+            value = (String) params.get("vm.rng.model");
+            if (!Strings.isNullOrEmpty(value)) {
+                _rngBackendModel = RngBackendModel.valueOf(value.toUpperCase());
+            }
+
+            value = (String) params.get("vm.rng.path");
+            if (!Strings.isNullOrEmpty(value)) {
+                _rngPath = value;
+            }
+
+            value = (String) params.get("vm.rng.rate.bytes");
+            _rngRateBytes = NumbersUtil.parseInt(value, new Integer(_rngRateBytes));
+
+            value = (String) params.get("vm.rng.rate.period");
+            _rngRatePeriod = NumbersUtil.parseInt(value, new Integer(_rngRatePeriod));
+        }
+
+        value = (String) params.get("vm.watchdog.model");
+        if (!Strings.isNullOrEmpty(value)) {
+            _watchDogModel = WatchDogModel.valueOf(value.toUpperCase());
+        }
+
+        value = (String) params.get("vm.watchdog.action");
+        if (!Strings.isNullOrEmpty(value)) {
+            _watchDogAction = WatchDogAction.valueOf(value.toUpperCase());
+        }
+
+        LibvirtConnection.initialize(_hypervisorURI);
+        Connect conn = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+
+            if (_bridgeType == BridgeType.OPENVSWITCH) {
+                if (conn.getLibVirVersion() < 10 * 1000 + 0) {
+                    throw new ConfigurationException("Libvirt version 0.10.0 required for openvswitch support, but version " + conn.getLibVirVersion() + " detected");
+                }
+            }
+        } catch (final LibvirtException e) {
+            throw new CloudRuntimeException(e.getMessage());
+        }
+
+        if (HypervisorType.KVM == _hypervisorType) {
+            /* Does node support HVM guest? If not, exit */
+            if (!IsHVMEnabled(conn)) {
+                throw new ConfigurationException("NO HVM support on this machine, please make sure: " + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
+                        + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)");
+            }
+        }
+
+        _hypervisorPath = getHypervisorPath(conn);
+        try {
+            _hvVersion = conn.getVersion();
+            _hvVersion = _hvVersion % 1000000 / 1000;
+            _hypervisorLibvirtVersion = conn.getLibVirVersion();
+            _hypervisorQemuVersion = conn.getVersion();
+        } catch (final LibvirtException e) {
+            s_logger.trace("Ignoring libvirt error.", e);
+        }
+
+        _guestCpuMode = (String)params.get("guest.cpu.mode");
+        if (_guestCpuMode != null) {
+            _guestCpuModel = (String)params.get("guest.cpu.model");
+
+            if (_hypervisorLibvirtVersion < 9 * 1000 + 10) {
+                s_logger.warn("Libvirt version 0.9.10 required for guest cpu mode, but version " + prettyVersion(_hypervisorLibvirtVersion) +
+                        " detected, so it will be disabled");
+                _guestCpuMode = "";
+                _guestCpuModel = "";
+            }
+            params.put("guest.cpu.mode", _guestCpuMode);
+            params.put("guest.cpu.model", _guestCpuModel);
+        }
+
+        final String cpuFeatures = (String)params.get("guest.cpu.features");
+        if (cpuFeatures != null) {
+            _cpuFeatures = new ArrayList<String>();
+            for (final String feature: cpuFeatures.split(" ")) {
+                if (!feature.isEmpty()) {
+                    _cpuFeatures.add(feature);
+                }
+            }
+        }
+
+        final String[] info = NetUtils.getNetworkParams(_privateNic);
+
+        _monitor = new KVMHAMonitor(null, info[0], _heartBeatPath);
+        final Thread ha = new Thread(_monitor);
+        ha.start();
+
+        _storagePoolMgr = new KVMStoragePoolManager(_storage, _monitor);
+
+        _sysvmISOPath = (String)params.get("systemvm.iso.path");
+        if (_sysvmISOPath == null) {
+            final String[] isoPaths = {"/usr/share/cloudstack-common/vms/systemvm.iso"};
+            for (final String isoPath : isoPaths) {
+                if (_storage.exists(isoPath)) {
+                    _sysvmISOPath = isoPath;
+                    break;
+                }
+            }
+            if (_sysvmISOPath == null) {
+                s_logger.debug("Can't find system vm ISO");
+            }
+        }
+
+        final Map<String, String> bridges = new HashMap<String, String>();
+
+        params.put("libvirt.host.bridges", bridges);
+        params.put("libvirt.host.pifs", _pifs);
+
+        params.put("libvirt.computing.resource", this);
+        params.put("libvirtVersion", _hypervisorLibvirtVersion);
+
+
+        configureVifDrivers(params);
+
+        /*
+        switch (_bridgeType) {
+        case OPENVSWITCH:
+            getOvsPifs();
+            break;
+        case NATIVE:
+        default:
+            getPifs();
+            break;
+        }
+        */
+
+        if (_pifs.get("private") == null) {
+            s_logger.error("Failed to get private nic name");
+            throw new ConfigurationException("Failed to get private nic name");
+        }
+
+        if (_pifs.get("public") == null) {
+            s_logger.error("Failed to get public nic name");
+            throw new ConfigurationException("Failed to get public nic name");
+        }
+        s_logger.debug("Found pif: " + _pifs.get("private") + " on " + _privBridgeName + ", pif: " + _pifs.get("public") + " on " + _publicBridgeName);
+
+        _canBridgeFirewall = canBridgeFirewall(_pifs.get("public"));
+
+        _localGateway = Script.runSimpleBashScript("ip route show default 0.0.0.0/0|head -1|awk '{print $3}'");
+        if (_localGateway == null) {
+            s_logger.warn("No default IPv4 gateway found");
+        }
+
+        _mountPoint = (String)params.get("mount.path");
+        if (_mountPoint == null) {
+            _mountPoint = "/mnt";
+        }
+
+        value = (String) params.get("vm.migrate.downtime");
+        _migrateDowntime = NumbersUtil.parseInt(value, -1);
+
+        value = (String) params.get("vm.migrate.pauseafter");
+        _migratePauseAfter = NumbersUtil.parseInt(value, -1);
+
+        value = (String)params.get("vm.migrate.speed");
+        _migrateSpeed = NumbersUtil.parseInt(value, -1);
+        if (_migrateSpeed == -1) {
+            //get guest network device speed
+            _migrateSpeed = 0;
+            final String speed = Script.runSimpleBashScript("ethtool " + _pifs.get("public") + " |grep Speed | cut -d \\  -f 2");
+            if (speed != null) {
+                final String[] tokens = speed.split("M");
+                if (tokens.length == 2) {
+                    try {
+                        _migrateSpeed = Integer.parseInt(tokens[0]);
+                    } catch (final NumberFormatException e) {
+                        s_logger.trace("Ignoring migrateSpeed extraction error.", e);
+                    }
+                    s_logger.debug("device " + _pifs.get("public") + " has speed: " + String.valueOf(_migrateSpeed));
+                }
+            }
+            params.put("vm.migrate.speed", String.valueOf(_migrateSpeed));
+        }
+
+        bridges.put("linklocal", _linkLocalBridgeName);
+        bridges.put("public", _publicBridgeName);
+        bridges.put("private", _privBridgeName);
+        bridges.put("guest", _guestBridgeName);
+
+        getVifDriver(TrafficType.Control).createControlNetwork(_linkLocalBridgeName);
+
+        configureDiskActivityChecks(params);
+
+        final KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this);
+        storageProcessor.configure(name, params);
+        storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor);
+
+        return true;
+    }
+
+    protected void configureDiskActivityChecks(final Map<String, Object> params) {
+        _diskActivityCheckEnabled = Boolean.parseBoolean((String)params.get("vm.diskactivity.checkenabled"));
+        if (_diskActivityCheckEnabled) {
+            final int timeout = NumbersUtil.parseInt((String)params.get("vm.diskactivity.checktimeout_s"), 0);
+            if (timeout > 0) {
+                _diskActivityCheckTimeoutSeconds = timeout;
+            }
+            final long inactiveTime = NumbersUtil.parseLong((String)params.get("vm.diskactivity.inactivetime_ms"), 0L);
+            if (inactiveTime > 0) {
+                _diskActivityInactiveThresholdMilliseconds = inactiveTime;
+            }
+        }
+    }
+
+    protected void configureVifDrivers(final Map<String, Object> params) throws ConfigurationException {
+        final String LIBVIRT_VIF_DRIVER = "libvirt.vif.driver";
+
+        _trafficTypeVifDrivers = new HashMap<TrafficType, VifDriver>();
+
+        // Load the default vif driver
+        String defaultVifDriverName = (String)params.get(LIBVIRT_VIF_DRIVER);
+        if (defaultVifDriverName == null) {
+            if (_bridgeType == BridgeType.OPENVSWITCH) {
+                s_logger.info("No libvirt.vif.driver specified. Defaults to OvsVifDriver.");
+                defaultVifDriverName = DEFAULT_OVS_VIF_DRIVER_CLASS_NAME;
+            } else {
+                s_logger.info("No libvirt.vif.driver specified. Defaults to BridgeVifDriver.");
+                defaultVifDriverName = DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME;
+            }
+        }
+        _defaultVifDriver = getVifDriverClass(defaultVifDriverName, params);
+
+        // Load any per-traffic-type vif drivers
+        for (final Map.Entry<String, Object> entry : params.entrySet()) {
+            final String k = entry.getKey();
+            final String vifDriverPrefix = LIBVIRT_VIF_DRIVER + ".";
+
+            if (k.startsWith(vifDriverPrefix)) {
+                // Get trafficType
+                final String trafficTypeSuffix = k.substring(vifDriverPrefix.length());
+
+                // Does this suffix match a real traffic type?
+                final TrafficType trafficType = TrafficType.getTrafficType(trafficTypeSuffix);
+                if (!trafficType.equals(TrafficType.None)) {
+                    // Get vif driver class name
+                    final String vifDriverClassName = (String)entry.getValue();
+                    // if value is null, ignore
+                    if (vifDriverClassName != null) {
+                        // add traffic type to vif driver mapping to Map
+                        _trafficTypeVifDrivers.put(trafficType, getVifDriverClass(vifDriverClassName, params));
+                    }
+                }
+            }
+        }
+    }
+
+    protected VifDriver getVifDriverClass(final String vifDriverClassName, final Map<String, Object> params) throws ConfigurationException {
+        VifDriver vifDriver;
+
+        try {
+            final Class<?> clazz = Class.forName(vifDriverClassName);
+            vifDriver = (VifDriver)clazz.newInstance();
+            vifDriver.configure(params);
+        } catch (final ClassNotFoundException e) {
+            throw new ConfigurationException("Unable to find class for libvirt.vif.driver " + e);
+        } catch (final InstantiationException e) {
+            throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e);
+        } catch (final IllegalAccessException e) {
+            throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e);
+        }
+        return vifDriver;
+    }
+
+    public VifDriver getVifDriver(final TrafficType trafficType) {
+        VifDriver vifDriver = _trafficTypeVifDrivers.get(trafficType);
+
+        if (vifDriver == null) {
+            vifDriver = _defaultVifDriver;
+        }
+
+        return vifDriver;
+    }
+
+    public VifDriver getVifDriver(final TrafficType trafficType, final String bridgeName) {
+        VifDriver vifDriver = null;
+
+        for (VifDriver driver : getAllVifDrivers()) {
+            if (driver.isExistingBridge(bridgeName)) {
+                vifDriver = driver;
+                break;
+            }
+        }
+
+        if (vifDriver == null) {
+            vifDriver = getVifDriver(trafficType);
+        }
+
+        return vifDriver;
+    }
+
+    public List<VifDriver> getAllVifDrivers() {
+        final Set<VifDriver> vifDrivers = new HashSet<VifDriver>();
+
+        vifDrivers.add(_defaultVifDriver);
+        vifDrivers.addAll(_trafficTypeVifDrivers.values());
+
+        final ArrayList<VifDriver> vifDriverList = new ArrayList<VifDriver>(vifDrivers);
+
+        return vifDriverList;
+    }
+
+    private void getPifs() {
+        final File dir = new File("/sys/devices/virtual/net");
+        final File[] netdevs = dir.listFiles();
+        final List<String> bridges = new ArrayList<String>();
+        for (int i = 0; i < netdevs.length; i++) {
+            final File isbridge = new File(netdevs[i].getAbsolutePath() + "/bridge");
+            final String netdevName = netdevs[i].getName();
+            s_logger.debug("looking in file " + netdevs[i].getAbsolutePath() + "/bridge");
+            if (isbridge.exists()) {
+                s_logger.debug("Found bridge " + netdevName);
+                bridges.add(netdevName);
+            }
+        }
+
+        for (final String bridge : bridges) {
+            s_logger.debug("looking for pif for bridge " + bridge);
+            final String pif = getPif(bridge);
+            if (isPublicBridge(bridge)) {
+                _pifs.put("public", pif);
+            }
+            if (isGuestBridge(bridge)) {
+                _pifs.put("private", pif);
+            }
+            _pifs.put(bridge, pif);
+        }
+
+        // guest(private) creates bridges on a pif, if private bridge not found try pif direct
+        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
+        if (_pifs.get("private") == null) {
+            s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' not found as bridge, looking for physical interface");
+            final File dev = new File("/sys/class/net/" + _guestBridgeName);
+            if (dev.exists()) {
+                s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' found as a physical device");
+                _pifs.put("private", _guestBridgeName);
+            }
+        }
+
+        // public creates bridges on a pif, if private bridge not found try pif direct
+        // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label
+        if (_pifs.get("public") == null) {
+            s_logger.debug("public traffic label '" + _publicBridgeName+ "' not found as bridge, looking for physical interface");
+            final File dev = new File("/sys/class/net/" + _publicBridgeName);
+            if (dev.exists()) {
+                s_logger.debug("public traffic label '" + _publicBridgeName + "' found as a physical device");
+                _pifs.put("public", _publicBridgeName);
+            }
+        }
+
+        s_logger.debug("done looking for pifs, no more bridges");
+    }
+
+    boolean isGuestBridge(String bridge) {
+        return _guestBridgeName != null && bridge.equals(_guestBridgeName);
+    }
+
+    private void getOvsPifs() {
+        final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
+        s_logger.debug("cmdout was " + cmdout);
+        final List<String> bridges = Arrays.asList(cmdout.split("%"));
+        for (final String bridge : bridges) {
+            s_logger.debug("looking for pif for bridge " + bridge);
+            // String pif = getOvsPif(bridge);
+            // Not really interested in the pif name at this point for ovs
+            // bridges
+            final String pif = bridge;
+            if (isPublicBridge(bridge)) {
+                _pifs.put("public", pif);
+            }
+            if (isGuestBridge(bridge)) {
+                _pifs.put("private", pif);
+            }
+            _pifs.put(bridge, pif);
+        }
+        s_logger.debug("done looking for pifs, no more bridges");
+    }
+
+    public boolean isPublicBridge(String bridge) {
+        return _publicBridgeName != null && bridge.equals(_publicBridgeName);
+    }
+
+    private String getPif(final String bridge) {
+        String pif = matchPifFileInDirectory(bridge);
+        final File vlanfile = new File("/proc/net/vlan/" + pif);
+
+        if (vlanfile.isFile()) {
+            pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}");
+        }
+
+        return pif;
+    }
+
+    private String matchPifFileInDirectory(final String bridgeName) {
+        final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif");
+
+        if (!brif.isDirectory()) {
+            final File pif = new File("/sys/class/net/" + bridgeName);
+            if (pif.isDirectory()) {
+                // if bridgeName already refers to a pif, return it as-is
+                return bridgeName;
+            }
+            s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", does " + brif.getAbsolutePath() + "exist?");
+            return "";
+        }
+
+        final File[] interfaces = brif.listFiles();
+
+        for (int i = 0; i < interfaces.length; i++) {
+            final String fname = interfaces[i].getName();
+            s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'");
+            if (isInterface(fname)) {
+                return fname;
+            }
+        }
+
+        s_logger.debug("failing to get physical interface from bridge " + bridgeName + ", did not find an eth*, bond*, team*, vlan*, em*, p*p*, ens*, eno*, enp*, or enx* in " + brif.getAbsolutePath());
+        return "";
+    }
+
+    static String [] ifNamePatterns = {
+            "^eth",
+            "^bond",
+            "^vlan",
+            "^vx",
+            "^em",
+            "^ens",
+            "^eno",
+            "^enp",
+            "^team",
+            "^enx",
+            "^dummy",
+            "^lo",
+            "^p\\d+p\\d+"
+    };
+
+    /**
+     * @param fname
+     * @return
+     */
+    protected static boolean isInterface(final String fname) {
+        StringBuffer commonPattern = new StringBuffer();
+        for (final String ifNamePattern : ifNamePatterns) {
+            commonPattern.append("|(").append(ifNamePattern).append(".*)");
+        }
+        if(fname.matches(commonPattern.toString())) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean checkNetwork(final TrafficType trafficType, final String networkName) {
+        if (networkName == null) {
+            return true;
+        }
+
+        if (getVifDriver(trafficType, networkName) instanceof OvsVifDriver) {
+            return checkOvsNetwork(networkName);
+        } else {
+            return checkBridgeNetwork(networkName);
+        }
+    }
+
+    private boolean checkBridgeNetwork(final String networkName) {
+        if (networkName == null) {
+            return true;
+        }
+
+        final String name = matchPifFileInDirectory(networkName);
+
+        if (name == null || name.isEmpty()) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private boolean checkOvsNetwork(final String networkName) {
+        s_logger.debug("Checking if network " + networkName + " exists as openvswitch bridge");
+        if (networkName == null) {
+            return true;
+        }
+
+        final Script command = new Script("/bin/sh", _timeout);
+        command.add("-c");
+        command.add("ovs-vsctl br-exists " + networkName);
+        return "0".equals(command.execute(null));
+    }
+
+    public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException {
+        final Script command = new Script(_patchScriptPath, 300 * 1000, s_logger);
+        String result;
+        command.add("-n", vmName);
+        command.add("-c", cmdLine);
+        result = command.execute();
+        if (result != null) {
+            s_logger.error("Passing cmdline failed:" + result);
+            return false;
+        }
+        return true;
+    }
+
+    boolean isDirectAttachedNetwork(final String type) {
+        if ("untagged".equalsIgnoreCase(type)) {
+            return true;
+        } else {
+            try {
+                Long.valueOf(type);
+            } catch (final NumberFormatException e) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    public String startVM(final Connect conn, final String vmName, final String domainXML) throws LibvirtException, InternalErrorException {
+        try {
+            /*
+                We create a transient domain here. When this method gets
+                called we receive a full XML specification of the guest,
+                so no need to define it persistent.
+
+                This also makes sure we never have any old "garbage" defined
+                in libvirt which might haunt us.
+             */
+
+            // check for existing inactive vm definition and remove it
+            // this can sometimes happen during crashes, etc
+            Domain dm = null;
+            try {
+                dm = conn.domainLookupByName(vmName);
+                if (dm != null && dm.isPersistent() == 1) {
+                    // this is safe because it doesn't stop running VMs
+                    dm.undefine();
+                }
+            } catch (final LibvirtException e) {
+                // this is what we want, no domain found
+            } finally {
+                if (dm != null) {
+                    dm.free();
+                }
+            }
+
+            conn.domainCreateXML(domainXML, 0);
+        } catch (final LibvirtException e) {
+            throw e;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean stop() {
+        try {
+            final Connect conn = LibvirtConnection.getConnection();
+            conn.close();
+        } catch (final LibvirtException e) {
+            s_logger.trace("Ignoring libvirt error.", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * This finds a command wrapper to handle the command and executes it.
+     * If no wrapper is found an {@see UnsupportedAnswer} is sent back.
+     * Any other exceptions are to be caught and wrapped in an generic {@see Answer}, marked as failed.
+     *
+     * @param cmd the instance of a {@see Command} to execute.
+     * @return the for the {@see Command} appropriate {@see Answer} or {@see UnsupportedAnswer}
+     */
+    @Override
+    public Answer executeRequest(final Command cmd) {
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        try {
+            return wrapper.execute(cmd, this);
+        } catch (final RequestWrapper.CommandNotSupported cmde) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    public synchronized boolean destroyTunnelNetwork(final String bridge) {
+        findOrCreateTunnelNetwork(bridge);
+
+        final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
+        cmd.add("destroy_ovs_bridge");
+        cmd.add("--bridge", bridge);
+
+        final String result = cmd.execute();
+
+        if (result != null) {
+            s_logger.debug("OVS Bridge could not be destroyed due to error ==> " + result);
+            return false;
+        }
+        return true;
+    }
+
+    public synchronized boolean findOrCreateTunnelNetwork(final String nwName) {
+        try {
+            if (checkNetwork(TrafficType.Guest, nwName)) {
+                return true;
+            }
+            // if not found, create a new one
+            final Map<String, String> otherConfig = new HashMap<String, String>();
+            otherConfig.put("ovs-host-setup", "");
+            Script.runSimpleBashScript("ovs-vsctl -- --may-exist add-br "
+                    + nwName + " -- set bridge " + nwName
+                    + " other_config:ovs-host-setup='-1'");
+            s_logger.debug("### KVM network for tunnels created:" + nwName);
+        } catch (final Exception e) {
+            s_logger.warn("createTunnelNetwork failed", e);
+            return false;
+        }
+        return true;
+    }
+
+    public synchronized boolean configureTunnelNetwork(final long networkId,
+                                                       final long hostId, final String nwName) {
+        try {
+            final boolean findResult = findOrCreateTunnelNetwork(nwName);
+            if (!findResult) {
+                s_logger.warn("LibvirtComputingResource.findOrCreateTunnelNetwork() failed! Cannot proceed creating the tunnel.");
+                return false;
+            }
+            final String configuredHosts = Script
+                    .runSimpleBashScript("ovs-vsctl get bridge " + nwName
+                            + " other_config:ovs-host-setup");
+            boolean configured = false;
+            if (configuredHosts != null) {
+                final String hostIdsStr[] = configuredHosts.split(",");
+                for (final String hostIdStr : hostIdsStr) {
+                    if (hostIdStr.equals(((Long)hostId).toString())) {
+                        configured = true;
+                        break;
+                    }
+                }
+            }
+            if (!configured) {
+                final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
+                cmd.add("setup_ovs_bridge");
+                cmd.add("--key", nwName);
+                cmd.add("--cs_host_id", ((Long)hostId).toString());
+                cmd.add("--bridge", nwName);
+                final String result = cmd.execute();
+                if (result != null) {
+                    throw new CloudRuntimeException(
+                            "Unable to pre-configure OVS bridge " + nwName
+                                    + " for network ID:" + networkId);
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.warn("createandConfigureTunnelNetwork failed", e);
+            return false;
+        }
+        return true;
+    }
+
+    protected Storage.StorageResourceType getStorageResourceType() {
+        return Storage.StorageResourceType.STORAGE_POOL;
+    }
+
+    // this is much like PrimaryStorageDownloadCommand, but keeping it separate
+    public KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
+        final int index = templateUrl.lastIndexOf("/");
+        final String mountpoint = templateUrl.substring(0, index);
+        String templateName = null;
+        if (index < templateUrl.length() - 1) {
+            templateName = templateUrl.substring(index + 1);
+        }
+
+        KVMPhysicalDisk templateVol = null;
+        KVMStoragePool secondaryPool = null;
+        try {
+            secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
+            /* Get template vol */
+            if (templateName == null) {
+                secondaryPool.refresh();
+                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
+                if (disks == null || disks.isEmpty()) {
+                    s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
+                    return null;
+                }
+                for (final KVMPhysicalDisk disk : disks) {
+                    if (disk.getName().endsWith("qcow2")) {
+                        templateVol = disk;
+                        break;
+                    }
+                }
+                if (templateVol == null) {
+                    s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
+                    return null;
+                }
+            } else {
+                templateVol = secondaryPool.getPhysicalDisk(templateName);
+            }
+
+            /* Copy volume to primary storage */
+
+            final KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, 0);
+            return primaryVol;
+        } catch (final CloudRuntimeException e) {
+            s_logger.error("Failed to download template to primary storage", e);
+            return null;
+        } finally {
+            if (secondaryPool != null) {
+                _storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid());
+            }
+        }
+    }
+
+    public String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) {
+        final StoragePoolType poolType = pool.getType();
+        final PhysicalDiskFormat volFormat = vol.getFormat();
+
+        if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) {
+            return "CLVM";
+        } else if ((poolType == StoragePoolType.NetworkFilesystem
+                || poolType == StoragePoolType.SharedMountPoint
+                || poolType == StoragePoolType.Filesystem
+                || poolType == StoragePoolType.Gluster)
+                && volFormat == PhysicalDiskFormat.QCOW2 ) {
+            return "QCOW2";
+        }
+        throw new CloudRuntimeException("Cannot determine resize type from pool type " + pool.getType());
+    }
+
+    private String getBroadcastUriFromBridge(final String brName) {
+        final String pif = matchPifFileInDirectory(brName);
+        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()) {
+            if (brName.startsWith("brvx")){
+                return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString();
+            }
+            else{
+                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)#.#
+                    s_logger.debug("failed to get vNet id from bridge " + brName
+                            + "attached to physical interface" + pif + ", perhaps untagged interface");
+                    return "";
+                }
+            }
+        } else {
+            s_logger.debug("failed to get vNet id from bridge " + brName + "attached to physical interface" + pif);
+            return "";
+        }
+    }
+
+    private void VifHotPlug(final Connect conn, final String vmName, final String broadcastUri, final String macAddr) throws InternalErrorException, LibvirtException {
+        final NicTO nicTO = new NicTO();
+        nicTO.setMac(macAddr);
+        nicTO.setType(TrafficType.Public);
+        if (broadcastUri == null) {
+            nicTO.setBroadcastType(BroadcastDomainType.Native);
+        } else {
+            final URI uri = BroadcastDomainType.fromString(broadcastUri);
+            nicTO.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
+            nicTO.setBroadcastUri(uri);
+        }
+
+        final Domain vm = getDomain(conn, vmName);
+        vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV", "", null).toString());
+    }
+
+
+    private void vifHotUnPlug (final Connect conn, final String vmName, final String macAddr) throws InternalErrorException, LibvirtException {
+
+        Domain vm = null;
+        vm = getDomain(conn, vmName);
+        final List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
+        for (final InterfaceDef pluggedNic : pluggedNics) {
+            if (pluggedNic.getMacAddress().equalsIgnoreCase(macAddr)) {
+                vm.detachDevice(pluggedNic.toString());
+                // We don't know which "traffic type" is associated with
+                // each interface at this point, so inform all vif drivers
+                for (final VifDriver vifDriver : getAllVifDrivers()) {
+                    vifDriver.unplug(pluggedNic);
+                }
+            }
+        }
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
+        Connect conn;
+        final NicTO nic = cmd.getNic();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
+            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
+            InterfaceDef routerNic = null;
+
+            for (final InterfaceDef pluggedNic : pluggedNics) {
+                if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
+                    routerNic = pluggedNic;
+                    break;
+                }
+            }
+
+            if (routerNic == null) {
+                return new ExecutionResult(false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName);
+            }
+
+            return new ExecutionResult(true, null);
+        } catch (final LibvirtException e) {
+            final String msg = "Creating guest network failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
+        Connect conn;
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final IpAddressTO pubIP = cmd.getIpAddress();
+
+        try {
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
+            Integer devNum = 0;
+            final String pubVlan = pubIP.getBroadcastUri();
+            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
+
+            for (final InterfaceDef pluggedNic : pluggedNics) {
+                final String pluggedVlanBr = pluggedNic.getBrName();
+                final String pluggedVlanId = getBroadcastUriFromBridge(pluggedVlanBr);
+                if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED) && pluggedVlanBr.equalsIgnoreCase(_publicBridgeName)) {
+                    break;
+                } else if (pluggedVlanBr.equalsIgnoreCase(_linkLocalBridgeName)) {
+                    /*skip over, no physical bridge device exists*/
+                } else if (pluggedVlanId == null) {
+                    /*this should only be true in the case of link local bridge*/
+                    return new ExecutionResult(false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan +
+                            " on router " + routerName);
+                } else if (pluggedVlanId.equals(pubVlan)) {
+                    break;
+                }
+                devNum++;
+            }
+
+            pubIP.setNicDevId(devNum);
+
+            return new ExecutionResult(true, "success");
+        } catch (final LibvirtException e) {
+            final String msg = "Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
+        Connect conn;
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            conn = getLibvirtUtilitiesHelper().getConnectionByVmName(routerName);
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            Integer devNum = 0;
+            final List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
+            final Map<String, Integer> macAddressToNicNum = new HashMap<>(pluggedNics.size());
+
+            for (final InterfaceDef pluggedNic : pluggedNics) {
+                final String pluggedVlan = pluggedNic.getBrName();
+                macAddressToNicNum.put(pluggedNic.getMacAddress(), devNum);
+                devNum++;
+            }
+
+            for (final IpAddressTO ip : ips) {
+                ip.setNicDevId(macAddressToNicNum.get(ip.getVifMacAddress()));
+            }
+
+            return new ExecutionResult(true, null);
+        } catch (final LibvirtException e) {
+            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+    }
+
+    public ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        Connect conn;
+        try {
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
+            final List<InterfaceDef> nics = getInterfaces(conn, routerName);
+            final Map<String, Integer> broadcastUriAllocatedToVM = new HashMap<String, Integer>();
+            Integer nicPos = 0;
+            for (final InterfaceDef nic : nics) {
+                if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
+                    broadcastUriAllocatedToVM.put("LinkLocal", nicPos);
+                } else {
+                    if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) ||
+                            nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
+                        broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos);
+                    } else {
+                        final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName());
+                        broadcastUriAllocatedToVM.put(broadcastUri, nicPos);
+                    }
+                }
+                nicPos++;
+            }
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            int nicNum = 0;
+            for (final IpAddressTO ip : ips) {
+                boolean newNic = false;
+                if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) {
+                    /* plug a vif into router */
+                    VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress());
+                    broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++);
+                    newNic = true;
+                }
+                nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
+                networkUsage(routerIp, "addVif", "eth" + nicNum);
+
+                ip.setNicDevId(nicNum);
+                ip.setNewNic(newNic);
+            }
+            return new ExecutionResult(true, null);
+        } catch (final LibvirtException e) {
+            s_logger.error("ipassoccmd failed", e);
+            return new ExecutionResult(false, e.getMessage());
+        } catch (final InternalErrorException e) {
+            s_logger.error("ipassoccmd failed", e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+    }
+
+    protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) {
+
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
+        Connect conn;
+
+
+        try{
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
+            final List<InterfaceDef> nics = getInterfaces(conn, routerName);
+            final Map<String, Integer> broadcastUriAllocatedToVM = new HashMap<String, Integer>();
+
+            Integer nicPos = 0;
+            for (final InterfaceDef nic : nics) {
+                if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
+                    broadcastUriAllocatedToVM.put("LinkLocal", nicPos);
+                } else {
+                    if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) ||
+                            nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
+                        broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos);
+                    } else {
+                        final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName());
+                        broadcastUriAllocatedToVM.put(broadcastUri, nicPos);
+                    }
+                }
+                nicPos++;
+            }
+
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            int nicNum = 0;
+            for (final IpAddressTO ip : ips) {
+
+                if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) {
+                    /* plug a vif into router */
+                    VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress());
+                    broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++);
+                }
+                nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
+
+                if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(lastIp, "true") && !ip.isAdd()) {
+                    // in isolated network eth2 is the default public interface. We don't want to delete it.
+                    if (nicNum != 2) {
+                        vifHotUnPlug(conn, routerName, ip.getVifMacAddress());
+                        networkUsage(routerIp, "deleteVif", "eth" + nicNum);
+                    }
+                }
+            }
+
+        } catch (final LibvirtException e) {
+            s_logger.error("ipassoccmd failed", e);
+            return new ExecutionResult(false, e.getMessage());
+        } catch (final InternalErrorException e) {
+            s_logger.error("ipassoccmd failed", e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+
+        return new ExecutionResult(true, null);
+    }
+
+    protected PowerState convertToPowerState(final DomainState ps) {
+        final PowerState state = s_powerStatesTable.get(ps);
+        return state == null ? PowerState.PowerUnknown : state;
+    }
+
+    public PowerState getVmState(final Connect conn, final String vmName) {
+        int retry = 3;
+        Domain vms = null;
+        while (retry-- > 0) {
+            try {
+                vms = conn.domainLookupByName(vmName);
+                final PowerState s = convertToPowerState(vms.getInfo().state);
+                return s;
+            } catch (final LibvirtException e) {
+                s_logger.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry);
+            } finally {
+                try {
+                    if (vms != null) {
+                        vms.free();
+                    }
+                } catch (final LibvirtException l) {
+                    s_logger.trace("Ignoring libvirt error.", l);
+                }
+            }
+        }
+        return PowerState.PowerOff;
+    }
+
+    public String networkUsage(final String privateIpAddress, final String option, final String vif) {
+        final Script getUsage = new Script(_routerProxyPath, s_logger);
+        getUsage.add("netusage.sh");
+        getUsage.add(privateIpAddress);
+        if (option.equals("get")) {
+            getUsage.add("-g");
+        } else if (option.equals("create")) {
+            getUsage.add("-c");
+        } else if (option.equals("reset")) {
+            getUsage.add("-r");
+        } else if (option.equals("addVif")) {
+            getUsage.add("-a", vif);
+        } else if (option.equals("deleteVif")) {
+            getUsage.add("-d", vif);
+        }
+
+        final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
+        final String result = getUsage.execute(usageParser);
+        if (result != null) {
+            s_logger.debug("Failed to execute networkUsage:" + result);
+            return null;
+        }
+        return usageParser.getLine();
+    }
+
+    public long[] getNetworkStats(final String privateIP) {
+        final String result = networkUsage(privateIP, "get", null);
+        final long[] stats = new long[2];
+        if (result != null) {
+            final String[] splitResult = result.split(":");
+            int i = 0;
+            while (i < splitResult.length - 1) {
+                stats[0] += Long.parseLong(splitResult[i++]);
+                stats[1] += Long.parseLong(splitResult[i++]);
+            }
+        }
+        return stats;
+    }
+
+    public String configureVPCNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCIDR) {
+        final Script getUsage = new Script(_routerProxyPath, s_logger);
+        getUsage.add("vpc_netusage.sh");
+        getUsage.add(privateIpAddress);
+        getUsage.add("-l", publicIp);
+
+        if (option.equals("get")) {
+            getUsage.add("-g");
+        } else if (option.equals("create")) {
+            getUsage.add("-c");
+            getUsage.add("-v", vpcCIDR);
+        } else if (option.equals("reset")) {
+            getUsage.add("-r");
+        } else if (option.equals("vpn")) {
+            getUsage.add("-n");
+        } else if (option.equals("remove")) {
+            getUsage.add("-d");
+        }
+
+        final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser();
+        final String result = getUsage.execute(usageParser);
+        if (result != null) {
+            s_logger.debug("Failed to execute VPCNetworkUsage:" + result);
+            return null;
+        }
+        return usageParser.getLine();
+    }
+
+    public long[] getVPCNetworkStats(final String privateIP, final String publicIp, final String option) {
+        final String result = configureVPCNetworkUsage(privateIP, publicIp, option, null);
+        final long[] stats = new long[2];
+        if (result != null) {
+            final String[] splitResult = result.split(":");
+            int i = 0;
+            while (i < splitResult.length - 1) {
+                stats[0] += Long.parseLong(splitResult[i++]);
+                stats[1] += Long.parseLong(splitResult[i++]);
+            }
+        }
+        return stats;
+    }
+
+    public void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) {
+        if (vm != null && vm.getDevices() != null) {
+            cleanupVMNetworks(conn, vm.getDevices().getInterfaces());
+        }
+    }
+
+    protected String getUuid(String uuid) {
+        if (uuid == null) {
+            uuid = UUID.randomUUID().toString();
+        } else {
+            try {
+                final UUID uuid2 = UUID.fromString(uuid);
+                final String uuid3 = uuid2.toString();
+                if (!uuid3.equals(uuid)) {
+                    uuid = UUID.randomUUID().toString();
+                }
+            } catch (final IllegalArgumentException e) {
+                uuid = UUID.randomUUID().toString();
+            }
+        }
+        return uuid;
+    }
+
+    /**
+     * Set quota and period tags on 'ctd' when CPU limit use is set
+     */
+    protected void setQuotaAndPeriod(VirtualMachineTO vmTO, CpuTuneDef ctd) {
+        if (vmTO.getLimitCpuUse() && vmTO.getCpuQuotaPercentage() != null) {
+            Double cpuQuotaPercentage = vmTO.getCpuQuotaPercentage();
+            int period = CpuTuneDef.DEFAULT_PERIOD;
+            int quota = (int) (period * cpuQuotaPercentage);
+            if (quota < CpuTuneDef.MIN_QUOTA) {
+                s_logger.info("Calculated quota (" + quota + ") below the minimum (" + CpuTuneDef.MIN_QUOTA + ") for VM domain " + vmTO.getUuid() + ", setting it to minimum " +
+                        "and calculating period instead of using the default");
+                quota = CpuTuneDef.MIN_QUOTA;
+                period = (int) ((double) quota / cpuQuotaPercentage);
+                if (period > CpuTuneDef.MAX_PERIOD) {
+                    s_logger.info("Calculated period (" + period + ") exceeds the maximum (" + CpuTuneDef.MAX_PERIOD +
+                            "), setting it to the maximum");
+                    period = CpuTuneDef.MAX_PERIOD;
+                }
+            }
+            ctd.setQuota(quota);
+            ctd.setPeriod(period);
+            s_logger.info("Setting quota=" + quota + ", period=" + period + " to VM domain " + vmTO.getUuid());
+        }
+    }
+
+    protected void enlightenWindowsVm(VirtualMachineTO vmTO, FeaturesDef features) {
+        if (vmTO.getOs().contains("Windows PV")) {
+            // If OS is Windows PV, then enable the features. Features supported on Windows 2008 and later
+            LibvirtVMDef.HyperVEnlightenmentFeatureDef hyv = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
+            hyv.setFeature("relaxed", true);
+            hyv.setFeature("vapic", true);
+            hyv.setFeature("spinlocks", true);
+            hyv.setRetries(8096);
+            features.addHyperVFeature(hyv);
+            s_logger.info("Enabling KVM Enlightment Features to VM domain " + vmTO.getUuid());
+        }
+    }
+
+    public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) {
+        final LibvirtVMDef vm = new LibvirtVMDef();
+        vm.setDomainName(vmTO.getName());
+        String uuid = vmTO.getUuid();
+        uuid = getUuid(uuid);
+        vm.setDomUUID(uuid);
+        vm.setDomDescription(vmTO.getOs());
+        vm.setPlatformEmulator(vmTO.getPlatformEmulator());
+
+        Map<String, String> extraConfig = vmTO.getExtraConfig();
+        if (dpdkSupport && (!extraConfig.containsKey(DPDK_NUMA) || !extraConfig.containsKey(DPDK_HUGE_PAGES))) {
+            s_logger.info("DPDK is enabled but it needs extra configurations for CPU NUMA and Huge Pages for VM deployment");
+        }
+
+        final GuestDef guest = new GuestDef();
+
+        if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User == vmTO.getType()) {
+            // LXC domain is only valid for user VMs. Use KVM for system VMs.
+            guest.setGuestType(GuestDef.GuestType.LXC);
+            vm.setHvsType(HypervisorType.LXC.toString().toLowerCase());
+        } else {
+            guest.setGuestType(GuestDef.GuestType.KVM);
+            vm.setHvsType(HypervisorType.KVM.toString().toLowerCase());
+            vm.setLibvirtVersion(_hypervisorLibvirtVersion);
+            vm.setQemuVersion(_hypervisorQemuVersion);
+        }
+        guest.setGuestArch(vmTO.getArch());
+        guest.setMachineType("pc");
+        guest.setUuid(uuid);
+        guest.setBootOrder(GuestDef.BootOrder.CDROM);
+        guest.setBootOrder(GuestDef.BootOrder.HARDISK);
+
+        vm.addComp(guest);
+
+        final GuestResourceDef grd = new GuestResourceDef();
+
+        if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) {
+            grd.setMemBalloning(true);
+            grd.setCurrentMem(vmTO.getMinRam() / 1024);
+            grd.setMemorySize(vmTO.getMaxRam() / 1024);
+        } else {
+            grd.setMemorySize(vmTO.getMaxRam() / 1024);
+        }
+        final int vcpus = vmTO.getCpus();
+        grd.setVcpuNum(vcpus);
+        vm.addComp(grd);
+
+        if (!extraConfig.containsKey(DPDK_NUMA)) {
+            final CpuModeDef cmd = new CpuModeDef();
+            cmd.setMode(_guestCpuMode);
+            cmd.setModel(_guestCpuModel);
+            if (vmTO.getType() == VirtualMachine.Type.User) {
+                cmd.setFeatures(_cpuFeatures);
+            }
+            // multi cores per socket, for larger core configs
+            if (vcpus % 6 == 0) {
+                final int sockets = vcpus / 6;
+                cmd.setTopology(6, sockets);
+            } else if (vcpus % 4 == 0) {
+                final int sockets = vcpus / 4;
+                cmd.setTopology(4, sockets);
+            }
+            vm.addComp(cmd);
+        }
+
+        if (_hypervisorLibvirtVersion >= 9000) {
+            final CpuTuneDef ctd = new CpuTuneDef();
+            /**
+             A 4.0.X/4.1.X management server doesn't send the correct JSON
+             command for getMinSpeed, it only sends a 'speed' field.
+
+             So if getMinSpeed() returns null we fall back to getSpeed().
+
+             This way a >4.1 agent can work communicate a <=4.1 management server
+
+             This change is due to the overcommit feature in 4.2
+             */
+            if (vmTO.getMinSpeed() != null) {
+                ctd.setShares(vmTO.getCpus() * vmTO.getMinSpeed());
+            } else {
+                ctd.setShares(vmTO.getCpus() * vmTO.getSpeed());
+            }
+
+            setQuotaAndPeriod(vmTO, ctd);
+
+            vm.addComp(ctd);
+        }
+
+        final FeaturesDef features = new FeaturesDef();
+        features.addFeatures("pae");
+        features.addFeatures("apic");
+        features.addFeatures("acpi");
+
+        //KVM hyperv enlightenment features based on OS Type
+        enlightenWindowsVm(vmTO, features);
+
+        vm.addComp(features);
+
+        final TermPolicy term = new TermPolicy();
+        term.setCrashPolicy("destroy");
+        term.setPowerOffPolicy("destroy");
+        term.setRebootPolicy("restart");
+        vm.addComp(term);
+
+        final ClockDef clock = new ClockDef();
+        if (vmTO.getOs().startsWith("Windows")) {
+            clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME);
+            clock.setTimer("hypervclock", null, null);
+        } else if (vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) {
+            if (_hypervisorLibvirtVersion >= 9 * 1000 + 10) {
+                clock.setTimer("kvmclock", null, null, _noKvmClock);
+            }
+        }
+
+        vm.addComp(clock);
+
+        final DevicesDef devices = new DevicesDef();
+        devices.setEmulatorPath(_hypervisorPath);
+        devices.setGuestType(guest.getGuestType());
+
+        final SerialDef serial = new SerialDef("pty", null, (short)0);
+        devices.addDevice(serial);
+
+        if (_rngEnable) {
+            final RngDef rngDevice = new RngDef(_rngPath, _rngBackendModel, _rngRateBytes, _rngRatePeriod);
+            devices.addDevice(rngDevice);
+        }
+
+        /* Add a VirtIO channel for the Qemu Guest Agent tools */
+        File virtIoChannel = Paths.get(_qemuSocketsPath.getPath(), vmTO.getName() + "." + _qemuGuestAgentSocketName).toFile();
+        devices.addDevice(new ChannelDef(_qemuGuestAgentSocketName, ChannelDef.ChannelType.UNIX, virtIoChannel));
+
+        devices.addDevice(new WatchDogDef(_watchDogAction, _watchDogModel));
+
+        final VideoDef videoCard = new VideoDef(_videoHw, _videoRam);
+        devices.addDevice(videoCard);
+
+        final ConsoleDef console = new ConsoleDef("pty", null, null, (short)0);
+        devices.addDevice(console);
+
+        //add the VNC port passwd here, get the passwd from the vmInstance.
+        final String passwd = vmTO.getVncPassword();
+        final GraphicDef grap = new GraphicDef("vnc", (short)0, true, vmTO.getVncAddr(), passwd, null);
+        devices.addDevice(grap);
+
+        final InputDef input = new InputDef("tablet", "usb");
+        devices.addDevice(input);
+
+
+        DiskDef.DiskBus busT = getDiskModelFromVMDetail(vmTO);
+
+        if (busT == null) {
+            busT = getGuestDiskModel(vmTO.getPlatformEmulator());
+        }
+
+        // If we're using virtio scsi, then we need to add a virtual scsi controller
+        if (busT == DiskDef.DiskBus.SCSI) {
+            final SCSIDef sd = new SCSIDef((short)0, 0, 0, 9, 0, vcpus);
+            devices.addDevice(sd);
+        }
+
+        vm.addComp(devices);
+
+        addExtraConfigComponent(extraConfig, vm);
+
+        return vm;
+    }
+
+    /**
+     * Add extra configurations (if any) as a String component to the domain XML
+     */
+    protected void addExtraConfigComponent(Map<String, String> extraConfig, LibvirtVMDef vm) {
+        if (MapUtils.isNotEmpty(extraConfig)) {
+            StringBuilder extraConfigBuilder = new StringBuilder();
+            for (String key : extraConfig.keySet()) {
+                if (!key.startsWith(DPDK_INTERFACE_PREFIX)) {
+                    extraConfigBuilder.append(extraConfig.get(key));
+                }
+            }
+            String comp = extraConfigBuilder.toString();
+            if (org.apache.commons.lang.StringUtils.isNotBlank(comp)) {
+                vm.addComp(comp);
+            }
+        }
+    }
+
+    public void createVifs(final VirtualMachineTO vmSpec, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException {
+        final NicTO[] nics = vmSpec.getNics();
+        final Map <String, String> params = vmSpec.getDetails();
+        String nicAdapter = "";
+        if (params != null && params.get("nicAdapter") != null && !params.get("nicAdapter").isEmpty()) {
+            nicAdapter = params.get("nicAdapter");
+        }
+        Map<String, String> extraConfig = vmSpec.getExtraConfig();
+        for (int i = 0; i < nics.length; i++) {
+            for (final NicTO nic : vmSpec.getNics()) {
+                if (nic.getDeviceId() == i) {
+                    createVif(vm, nic, nicAdapter, extraConfig);
+                }
+            }
+        }
+    }
+
+    public String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException {
+        final DataTO data = volume.getData();
+        final DataStoreTO store = data.getDataStore();
+
+        if (volume.getType() == Volume.Type.ISO && data.getPath() != null && (store instanceof NfsTO ||
+                store instanceof PrimaryDataStoreTO && data instanceof TemplateObjectTO && !((TemplateObjectTO) data).isDirectDownload())) {
+            final String isoPath = store.getUrl().split("\\?")[0] + File.separator + data.getPath();
+            final int index = isoPath.lastIndexOf("/");
+            final String path = isoPath.substring(0, index);
+            final String name = isoPath.substring(index + 1);
+            final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path);
+            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
+            return isoVol.getPath();
+        } else {
+            return data.getPath();
+        }
+    }
+
+    public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException {
+        final List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
+        Collections.sort(disks, new Comparator<DiskTO>() {
+            @Override
+            public int compare(final DiskTO arg0, final DiskTO arg1) {
+                return arg0.getDiskSeq() > arg1.getDiskSeq() ? 1 : -1;
+            }
+        });
+
+        for (final DiskTO volume : disks) {
+            KVMPhysicalDisk physicalDisk = null;
+            KVMStoragePool pool = null;
+            final DataTO data = volume.getData();
+            if (volume.getType() == Volume.Type.ISO && data.getPath() != null) {
+                DataStoreTO dataStore = data.getDataStore();
+                String dataStoreUrl = null;
+                if (dataStore instanceof NfsTO) {
+                    NfsTO nfsStore = (NfsTO)data.getDataStore();
+                    dataStoreUrl = nfsStore.getUrl();
+                } else if (dataStore instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO) dataStore).getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
+                    //In order to support directly downloaded ISOs
+                    String psHost = ((PrimaryDataStoreTO) dataStore).getHost();
+                    String psPath = ((PrimaryDataStoreTO) dataStore).getPath();
+                    dataStoreUrl = "nfs://" + psHost + File.separator + psPath;
+                }
+                final String volPath = dataStoreUrl + File.separator + data.getPath();
+                final int index = volPath.lastIndexOf("/");
+                final String volDir = volPath.substring(0, index);
+                final String volName = volPath.substring(index + 1);
+                final KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir);
+                physicalDisk = secondaryStorage.getPhysicalDisk(volName);
+            } else if (volume.getType() != Volume.Type.ISO) {
+                final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
+                physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
+                pool = physicalDisk.getPool();
+            }
+
+            String volPath = null;
+            if (physicalDisk != null) {
+                volPath = physicalDisk.getPath();
+            }
+
+            // check for disk activity, if detected we should exit because vm is running elsewhere
+            if (_diskActivityCheckEnabled && physicalDisk != null && physicalDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
+                s_logger.debug("Checking physical disk file at path " + volPath + " for disk activity to ensure vm is not running elsewhere");
+                try {
+                    HypervisorUtils.checkVolumeFileForActivity(volPath, _diskActivityCheckTimeoutSeconds, _diskActivityInactiveThresholdMilliseconds, _diskActivityCheckFileSizeMin);
+                } catch (final IOException ex) {
+                    throw new CloudRuntimeException("Unable to check physical disk file for activity", ex);
+                }
+                s_logger.debug("Disk activity check cleared");
+            }
+
+            // if params contains a rootDiskController key, use its value (this is what other HVs are doing)
+            DiskDef.DiskBus diskBusType = getDiskModelFromVMDetail(vmSpec);
+
+            if (diskBusType == null) {
+                diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator());
+            }
+
+            // I'm not sure why previously certain DATADISKs were hard-coded VIRTIO and others not, however this
+            // maintains existing functionality with the exception that SCSI will override VIRTIO.
+            DiskDef.DiskBus diskBusTypeData = (diskBusType == DiskDef.DiskBus.SCSI) ? diskBusType : DiskDef.DiskBus.VIRTIO;
+
+            final DiskDef disk = new DiskDef();
+            int devId = volume.getDiskSeq().intValue();
+            if (volume.getType() == Volume.Type.ISO) {
+                if (volPath == null) {
+                    /* Add iso as placeholder */
+                    disk.defISODisk(null, devId);
+                } else {
+                    disk.defISODisk(volPath, devId);
+                }
+            } else {
+                if (diskBusType == DiskDef.DiskBus.SCSI ) {
+                    disk.setQemuDriver(true);
+                    disk.setDiscard(DiscardType.UNMAP);
+                }
+
+                if (pool.getType() == StoragePoolType.RBD) {
+                    /*
+                            For RBD pools we use the secret mechanism in libvirt.
+                            We store the secret under the UUID of the pool, that's why
+                            we pass the pool's UUID as the authSecret
+                     */
+                    disk.defNetworkBasedDisk(physicalDisk.getPath().replace("rbd:", ""), pool.getSourceHost(), pool.getSourcePort(), pool.getAuthUserName(),
+                            pool.getUuid(), devId, diskBusType, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
+                } else if (pool.getType() == StoragePoolType.Gluster) {
+                    final String mountpoint = pool.getLocalPath();
+                    final String path = physicalDisk.getPath();
+                    final String glusterVolume = pool.getSourceDir().replace("/", "");
+                    disk.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), pool.getSourceHost(), pool.getSourcePort(), null,
+                            null, devId, diskBusType, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
+                } else if (pool.getType() == StoragePoolType.CLVM || physicalDisk.getFormat() == PhysicalDiskFormat.RAW) {
+                    disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
+                } else {
+                    if (volume.getType() == Volume.Type.DATADISK) {
+                        disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
+                    } else {
+                        disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusType, DiskDef.DiskFmtType.QCOW2);
+                    }
+
+                }
+
+            }
+
+            if (data instanceof VolumeObjectTO) {
+                final VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data;
+                disk.setSerial(diskUuidToSerial(volumeObjectTO.getUuid()));
+                setBurstProperties(volumeObjectTO, disk);
+
+                if (volumeObjectTO.getCacheMode() != null) {
+                    disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase()));
+                }
+            }
+            if (vm.getDevices() == null) {
+                s_logger.error("There is no devices for" + vm);
+                throw new RuntimeException("There is no devices for" + vm);
+            }
+            vm.getDevices().addDevice(disk);
+        }
+
+        if (vmSpec.getType() != VirtualMachine.Type.User) {
+            if (_sysvmISOPath != null) {
+                final DiskDef iso = new DiskDef();
+                iso.defISODisk(_sysvmISOPath);
+                vm.getDevices().addDevice(iso);
+            }
+        }
+
+        // For LXC, find and add the root filesystem, rbd data disks
+        if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) {
+            for (final DiskTO volume : disks) {
+                final DataTO data = volume.getData();
+                final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore();
+                if (volume.getType() == Volume.Type.ROOT) {
+                    final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
+                    final FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/");
+                    vm.getDevices().addDevice(rootFs);
+                } else if (volume.getType() == Volume.Type.DATADISK) {
+                    final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
+                    final KVMStoragePool pool = physicalDisk.getPool();
+                    if(StoragePoolType.RBD.equals(pool.getType())) {
+                        final int devId = volume.getDiskSeq().intValue();
+                        final String device = mapRbdDevice(physicalDisk);
+                        if (device != null) {
+                            s_logger.debug("RBD device on host is: " + device);
+                            final DiskDef diskdef = new DiskDef();
+                            diskdef.defBlockBasedDisk(device, devId, DiskDef.DiskBus.VIRTIO);
+                            diskdef.setQemuDriver(false);
+                            vm.getDevices().addDevice(diskdef);
+                        } else {
+                            throw new InternalErrorException("Error while mapping RBD device on host");
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    private void setBurstProperties(final VolumeObjectTO volumeObjectTO, final DiskDef disk ) {
+        if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) {
+            disk.setBytesReadRate(volumeObjectTO.getBytesReadRate());
+        }
+        if (volumeObjectTO.getBytesReadRateMax() != null && volumeObjectTO.getBytesReadRateMax() > 0) {
+            disk.setBytesReadRateMax(volumeObjectTO.getBytesReadRateMax());
+        }
+        if (volumeObjectTO.getBytesReadRateMaxLength() != null && volumeObjectTO.getBytesReadRateMaxLength() > 0) {
+            disk.setBytesReadRateMaxLength(volumeObjectTO.getBytesReadRateMaxLength());
+        }
+        if (volumeObjectTO.getBytesWriteRate() != null && volumeObjectTO.getBytesWriteRate() > 0) {
+            disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate());
+        }
+        if (volumeObjectTO.getBytesWriteRateMax() != null && volumeObjectTO.getBytesWriteRateMax() > 0) {
+            disk.setBytesWriteRateMax(volumeObjectTO.getBytesWriteRateMax());
+        }
+        if (volumeObjectTO.getBytesWriteRateMaxLength() != null && volumeObjectTO.getBytesWriteRateMaxLength() > 0) {
+            disk.setBytesWriteRateMaxLength(volumeObjectTO.getBytesWriteRateMaxLength());
+        }
+        if (volumeObjectTO.getIopsReadRate() != null && volumeObjectTO.getIopsReadRate() > 0) {
+            disk.setIopsReadRate(volumeObjectTO.getIopsReadRate());
+        }
+        if (volumeObjectTO.getIopsReadRateMax() != null && volumeObjectTO.getIopsReadRateMax() > 0) {
+            disk.setIopsReadRateMax(volumeObjectTO.getIopsReadRateMax());
+        }
+        if (volumeObjectTO.getIopsReadRateMaxLength() != null && volumeObjectTO.getIopsReadRateMaxLength() > 0) {
+            disk.setIopsReadRateMaxLength(volumeObjectTO.getIopsReadRateMaxLength());
+        }
+        if (volumeObjectTO.getIopsWriteRate() != null && volumeObjectTO.getIopsWriteRate() > 0) {
+            disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate());
+        }
+        if (volumeObjectTO.getIopsWriteRateMax() != null && volumeObjectTO.getIopsWriteRateMax() > 0) {
+            disk.setIopsWriteRateMax(volumeObjectTO.getIopsWriteRateMax());
+        }
+        if (volumeObjectTO.getIopsWriteRateMaxLength() != null && volumeObjectTO.getIopsWriteRateMaxLength() > 0) {
+            disk.setIopsWriteRateMaxLength(volumeObjectTO.getIopsWriteRateMaxLength());
+        }
+    }
+
+    private void createVif(final LibvirtVMDef vm, final NicTO nic, final String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
+
+        if (nic.getType().equals(TrafficType.Guest) && nic.getBroadcastType().equals(BroadcastDomainType.Vsp)) {
+            String vrIp = nic.getBroadcastUri().getPath().substring(1);
+            vm.getMetaData().getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension(nic.getMac(), vrIp);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NIC with MAC " + nic.getMac() + " and BroadcastDomainType " + nic.getBroadcastType() + " in network(" + nic.getGateway() + "/" + nic.getNetmask()
+                        + ") is " + nic.getType() + " traffic type. So, vsp-vr-ip " + vrIp + " is set in the metadata");
+            }
+        }
+        if (vm.getDevices() == null) {
+            s_logger.error("LibvirtVMDef object get devices with null result");
+            throw new InternalErrorException("LibvirtVMDef object get devices with null result");
+        }
+        vm.getDevices().addDevice(getVifDriver(nic.getType(), nic.getName()).plug(nic, vm.getPlatformEmulator(), nicAdapter, extraConfig));
+    }
+
+    public boolean cleanupDisk(Map<String, String> volumeToDisconnect) {
+        return _storagePoolMgr.disconnectPhysicalDisk(volumeToDisconnect);
+    }
+
+    public boolean cleanupDisk(final DiskDef disk) {
+        final String path = disk.getDiskPath();
+
+        if (path == null) {
+            s_logger.debug("Unable to clean up disk with null path (perhaps empty cdrom drive):" + disk);
+            return false;
+        }
+
+        if (path.endsWith("systemvm.iso")) {
+            // don't need to clean up system vm ISO as it's stored in local
+            return true;
+        }
+
+        return _storagePoolMgr.disconnectPhysicalDiskByPath(path);
+    }
+
+    protected KVMStoragePoolManager getPoolManager() {
+        return _storagePoolMgr;
+    }
+
+    public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, final Integer diskSeq) throws LibvirtException, URISyntaxException,
+            InternalErrorException {
+        final DiskDef iso = new DiskDef();
+        if (isoPath != null && isAttach) {
+            final int index = isoPath.lastIndexOf("/");
+            final String path = isoPath.substring(0, index);
+            final String name = isoPath.substring(index + 1);
+            final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path);
+            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
+            isoPath = isoVol.getPath();
+
+            iso.defISODisk(isoPath, diskSeq);
+        } else {
+            iso.defISODisk(null, diskSeq);
+        }
+
+        final String result = attachOrDetachDevice(conn, true, vmName, iso.toString());
+        if (result == null && !isAttach) {
+            final List<DiskDef> disks = getDisks(conn, vmName);
+            for (final DiskDef disk : disks) {
+                if (disk.getDeviceType() == DiskDef.DeviceType.CDROM
+                        && (diskSeq == null || disk.getDiskLabel() == iso.getDiskLabel())) {
+                    cleanupDisk(disk);
+                }
+            }
+
+        }
+        return result;
+    }
+
+    public synchronized String attachOrDetachDisk(final Connect conn,
+                                                  final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk,
+                                                  final int devId, final Long bytesReadRate, final Long bytesReadRateMax, final Long bytesReadRateMaxLength, final Long bytesWriteRate, final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength, final Long iopsReadRate, final Long iopsReadRateMax, final Long iopsReadRateMaxLength, final Long iopsWriteRate, final Long iopsWriteRateMax, final Long iopsWriteRateMaxLength, final String cacheMode) throws LibvirtException, InternalErrorException {
+        List<DiskDef> disks = null;
+        Domain dm = null;
+        DiskDef diskdef = null;
+        final KVMStoragePool attachingPool = attachingDisk.getPool();
+        try {
+            dm = conn.domainLookupByName(vmName);
+            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+            final String domXml = dm.getXMLDesc(0);
+            parser.parseDomainXML(domXml);
+            disks = parser.getDisks();
+
+            if (!attach) {
+                for (final DiskDef disk : disks) {
+                    final String file = disk.getDiskPath();
+                    if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
+                        diskdef = disk;
+                        break;
+                    }
+                }
+                if (diskdef == null) {
+                    throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before");
+                }
+            } else {
+                DiskDef.DiskBus busT = DiskDef.DiskBus.VIRTIO;
+                for (final DiskDef disk : disks) {
+                    if (disk.getDeviceType() == DeviceType.DISK) {
+                        if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
+                            busT = DiskDef.DiskBus.SCSI;
+                        }
+                        break;
+                    }
+                }
+
+                diskdef = new DiskDef();
+                if (busT == DiskDef.DiskBus.SCSI) {
+                    diskdef.setQemuDriver(true);
+                    diskdef.setDiscard(DiscardType.UNMAP);
+                }
+                if (attachingPool.getType() == StoragePoolType.RBD) {
+                    diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), attachingPool.getAuthUserName(),
+                            attachingPool.getUuid(), devId, busT, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
+                } else if (attachingPool.getType() == StoragePoolType.Gluster) {
+                    diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), null,
+                            null, devId, busT, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
+                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
+                    diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
+                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
+                    diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
+                }
+                if (bytesReadRate != null && bytesReadRate > 0) {
+                    diskdef.setBytesReadRate(bytesReadRate);
+                }
+                if (bytesReadRateMax != null && bytesReadRateMax > 0) {
+                    diskdef.setBytesReadRateMax(bytesReadRateMax);
+                }
+                if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) {
+                    diskdef.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+                }
+                if (bytesWriteRate != null && bytesWriteRate > 0) {
+                    diskdef.setBytesWriteRate(bytesWriteRate);
+                }
+                if (bytesWriteRateMax != null && bytesWriteRateMax > 0) {
+                    diskdef.setBytesWriteRateMax(bytesWriteRateMax);
+                }
+                if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) {
+                    diskdef.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+                }
+                if (iopsReadRate != null && iopsReadRate > 0) {
+                    diskdef.setIopsReadRate(iopsReadRate);
+                }
+                if (iopsReadRateMax != null && iopsReadRateMax > 0) {
+                    diskdef.setIopsReadRateMax(iopsReadRateMax);
+                }
+                if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) {
+                    diskdef.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+                }
+                if (iopsWriteRate != null && iopsWriteRate > 0) {
+                    diskdef.setIopsWriteRate(iopsWriteRate);
+                }
+                if (iopsWriteRateMax != null && iopsWriteRateMax > 0) {
+                    diskdef.setIopsWriteRateMax(iopsWriteRateMax);
+                }
+
+                if (cacheMode != null) {
+                    diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
+                }
+            }
+
+            final String xml = diskdef.toString();
+            return attachOrDetachDevice(conn, attach, vmName, xml);
+        } finally {
+            if (dm != null) {
+                dm.free();
+            }
+        }
+    }
+
+    protected synchronized String attachOrDetachDevice(final Connect conn, final boolean attach, final String vmName, final String xml) throws LibvirtException, InternalErrorException {
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            if (attach) {
+                s_logger.debug("Attaching device: " + xml);
+                dm.attachDevice(xml);
+            } else {
+                s_logger.debug("Detaching device: " + xml);
+                dm.detachDevice(xml);
+            }
+        } catch (final LibvirtException e) {
+            if (attach) {
+                s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage());
+            } else {
+                s_logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage());
+            }
+            throw e;
+        } finally {
+            if (dm != null) {
+                try {
+                    dm.free();
+                } catch (final LibvirtException l) {
+                    s_logger.trace("Ignoring libvirt error.", l);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(final long id) {
+
+        if (!_canBridgeFirewall) {
+            return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, this.getHostVmStateReport());
+        } else {
+            final HashMap<String, Pair<Long, Long>> nwGrpStates = syncNetworkGroups(id);
+            return new PingRoutingWithNwGroupsCommand(getType(), id, this.getHostVmStateReport(), nwGrpStates);
+        }
+    }
+
+    @Override
+    public Type getType() {
+        return Type.Routing;
+    }
+
+    private Map<String, String> getVersionStrings() {
+        final Script command = new Script(_versionstringpath, _timeout, s_logger);
+        final KeyValueInterpreter kvi = new KeyValueInterpreter();
+        final String result = command.execute(kvi);
+        if (result == null) {
+            return kvi.getKeyValues();
+        } else {
+            return new HashMap<String, String>(1);
+        }
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+
+        final KVMHostInfo info = new KVMHostInfo(_dom0MinMem, _dom0OvercommitMem);
+
+        final String capabilities = String.join(",", info.getCapabilities());
+
+        final StartupRoutingCommand cmd =
+                new StartupRoutingCommand(info.getCpus(), info.getCpuSpeed(), info.getTotalMemory(), info.getReservedMemory(), capabilities, _hypervisorType,
+                        RouterPrivateIpStrategy.HostLocal);
+        cmd.setCpuSockets(info.getCpuSockets());
+        fillNetworkInformation(cmd);
+        _privateIp = cmd.getPrivateIpAddress();
+        cmd.getHostDetails().putAll(getVersionStrings());
+        cmd.getHostDetails().put(KeyStoreUtils.SECURED, String.valueOf(isHostSecured()).toLowerCase());
+        cmd.setPool(_pool);
+        cmd.setCluster(_clusterId);
+        cmd.setGatewayIpAddress(_localGateway);
+        cmd.setIqn(getIqn());
+
+        if (cmd.getHostDetails().containsKey("Host.OS")) {
+            _hostDistro = cmd.getHostDetails().get("Host.OS");
+        }
+
+        StartupStorageCommand sscmd = null;
+        try {
+
+            final KVMStoragePool localStoragePool = _storagePoolMgr.createStoragePool(_localStorageUUID, "localhost", -1, _localStoragePath, "", StoragePoolType.Filesystem);
+            final com.cloud.agent.api.StoragePoolInfo pi =
+                    new com.cloud.agent.api.StoragePoolInfo(localStoragePool.getUuid(), cmd.getPrivateIpAddress(), _localStoragePath, _localStoragePath,
+                            StoragePoolType.Filesystem, localStoragePool.getCapacity(), localStoragePool.getAvailable());
+
+            sscmd = new StartupStorageCommand();
+            sscmd.setPoolInfo(pi);
+            sscmd.setGuid(pi.getUuid());
+            sscmd.setDataCenter(_dcId);
+            sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Unable to initialize local storage pool: " + e);
+        }
+
+        if (sscmd != null) {
+            return new StartupCommand[] {cmd, sscmd};
+        } else {
+            return new StartupCommand[] {cmd};
+        }
+    }
+
+    public String diskUuidToSerial(String uuid) {
+        String uuidWithoutHyphen = uuid.replace("-","");
+        return uuidWithoutHyphen.substring(0, Math.min(uuidWithoutHyphen.length(), 20));
+    }
+
+    private String getIqn() {
+        try {
+            final String textToFind = "InitiatorName=";
+
+            final Script iScsiAdmCmd = new Script(true, "grep", 0, s_logger);
+
+            iScsiAdmCmd.add(textToFind);
+            iScsiAdmCmd.add("/etc/iscsi/initiatorname.iscsi");
+
+            final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+
+            final String result = iScsiAdmCmd.execute(parser);
+
+            if (result != null) {
+                return null;
+            }
+
+            final String textFound = parser.getLine().trim();
+
+            return textFound.substring(textToFind.length());
+        }
+        catch (final Exception ex) {
+            return null;
+        }
+    }
+
+    protected List<String> getAllVmNames(final Connect conn) {
+        final ArrayList<String> la = new ArrayList<String>();
+        try {
+            final String names[] = conn.listDefinedDomains();
+            for (int i = 0; i < names.length; i++) {
+                la.add(names[i]);
+            }
+        } catch (final LibvirtException e) {
+            s_logger.warn("Failed to list Defined domains", e);
+        }
+
+        int[] ids = null;
+        try {
+            ids = conn.listDomains();
+        } catch (final LibvirtException e) {
+            s_logger.warn("Failed to list domains", e);
+            return la;
+        }
+
+        Domain dm = null;
+        for (int i = 0; i < ids.length; i++) {
+            try {
+                dm = conn.domainLookupByID(ids[i]);
+                la.add(dm.getName());
+            } catch (final LibvirtException e) {
+                s_logger.warn("Unable to get vms", e);
+            } finally {
+                try {
+                    if (dm != null) {
+                        dm.free();
+                    }
+                } catch (final LibvirtException e) {
+                    s_logger.trace("Ignoring libvirt error.", e);
+                }
+            }
+        }
+
+        return la;
+    }
+
+    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport() {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        Connect conn = null;
+
+        if (_hypervisorType == HypervisorType.LXC) {
+            try {
+                conn = LibvirtConnection.getConnectionByType(HypervisorType.LXC.toString());
+                vmStates.putAll(getHostVmStateReport(conn));
+                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
+                vmStates.putAll(getHostVmStateReport(conn));
+            } catch (final LibvirtException e) {
+                s_logger.debug("Failed to get connection: " + e.getMessage());
+            }
+        }
+
+        if (_hypervisorType == HypervisorType.KVM) {
+            try {
+                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
+                vmStates.putAll(getHostVmStateReport(conn));
+            } catch (final LibvirtException e) {
+                s_logger.debug("Failed to get connection: " + e.getMessage());
+            }
+        }
+
+        return vmStates;
+    }
+
+    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport(final Connect conn) {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+
+        String[] vms = null;
+        int[] ids = null;
+
+        try {
+            ids = conn.listDomains();
+        } catch (final LibvirtException e) {
+            s_logger.warn("Unable to listDomains", e);
+            return null;
+        }
+        try {
+            vms = conn.listDefinedDomains();
+        } catch (final LibvirtException e) {
+            s_logger.warn("Unable to listDomains", e);
+            return null;
+        }
+
+        Domain dm = null;
+        for (int i = 0; i < ids.length; i++) {
+            try {
+                dm = conn.domainLookupByID(ids[i]);
+
+                final DomainState ps = dm.getInfo().state;
+
+                final PowerState state = convertToPowerState(ps);
+
+                s_logger.trace("VM " + dm.getName() + ": powerstate = " + ps + "; vm state=" + state.toString());
+                final String vmName = dm.getName();
+
+                // TODO : for XS/KVM (host-based resource), we require to remove
+                // VM completely from host, for some reason, KVM seems to still keep
+                // Stopped VM around, to work-around that, reporting only powered-on VM
+                //
+                if (state == PowerState.PowerOn) {
+                    vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
+                }
+            } catch (final LibvirtException e) {
+                s_logger.warn("Unable to get vms", e);
+            } finally {
+                try {
+                    if (dm != null) {
+                        dm.free();
+                    }
+                } catch (final LibvirtException e) {
+                    s_logger.trace("Ignoring libvirt error.", e);
+                }
+            }
+        }
+
+        for (int i = 0; i < vms.length; i++) {
+            try {
+
+                dm = conn.domainLookupByName(vms[i]);
+
+                final DomainState ps = dm.getInfo().state;
+                final PowerState state = convertToPowerState(ps);
+                final String vmName = dm.getName();
+                s_logger.trace("VM " + vmName + ": powerstate = " + ps + "; vm state=" + state.toString());
+
+                // TODO : for XS/KVM (host-based resource), we require to remove
+                // VM completely from host, for some reason, KVM seems to still keep
+                // Stopped VM around, to work-around that, reporting only powered-on VM
+                //
+                if (state == PowerState.PowerOn) {
+                    vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName()));
+                }
+            } catch (final LibvirtException e) {
+                s_logger.warn("Unable to get vms", e);
+            } finally {
+                try {
+                    if (dm != null) {
+                        dm.free();
+                    }
+                } catch (final LibvirtException e) {
+                    s_logger.trace("Ignoring libvirt error.", e);
+                }
+            }
+        }
+
+        return vmStates;
+    }
+
+    public String rebootVM(final Connect conn, final String vmName) {
+        Domain dm = null;
+        String msg = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            // Get XML Dump including the secure information such as VNC password
+            // By passing 1, or VIR_DOMAIN_XML_SECURE flag
+            // https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
+            String vmDef = dm.getXMLDesc(1);
+            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+            parser.parseDomainXML(vmDef);
+            for (final InterfaceDef nic : parser.getInterfaces()) {
+                if (nic.getNetType() == GuestNetType.BRIDGE && nic.getBrName().startsWith("cloudVirBr")) {
+                    try {
+                        final int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", ""));
+                        final String pifName = getPif(_guestBridgeName);
+                        final String newBrName = "br" + pifName + "-" + vnetId;
+                        vmDef = vmDef.replaceAll("'" + nic.getBrName() + "'", "'" + newBrName + "'");
+                        s_logger.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName);
+                    } catch (final NumberFormatException e) {
+                        continue;
+                    }
+                }
+            }
+            s_logger.debug(vmDef);
+            msg = stopVM(conn, vmName, false);
+            msg = startVM(conn, vmName, vmDef);
+            return null;
+        } catch (final LibvirtException e) {
+            s_logger.warn("Failed to create vm", e);
+            msg = e.getMessage();
+        } catch (final InternalErrorException e) {
+            s_logger.warn("Failed to create vm", e);
+            msg = e.getMessage();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+                s_logger.trace("Ignoring libvirt error.", e);
+            }
+        }
+
+        return msg;
+    }
+
+    public String stopVM(final Connect conn, final String vmName, final boolean forceStop) {
+        DomainState state = null;
+        Domain dm = null;
+
+        // delete the metadata of vm snapshots before stopping
+        try {
+            dm = conn.domainLookupByName(vmName);
+            cleanVMSnapshotMetadata(dm);
+        } catch (LibvirtException e) {
+            s_logger.debug("Failed to get vm :" + e.getMessage());
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (LibvirtException l) {
+                s_logger.trace("Ignoring libvirt error.", l);
+            }
+        }
+
+        s_logger.debug("Try to stop the vm at first");
+        if (forceStop) {
+            return stopVMInternal(conn, vmName, true);
+        }
+        String ret = stopVMInternal(conn, vmName, false);
+        if (ret == Script.ERR_TIMEOUT) {
+            ret = stopVMInternal(conn, vmName, true);
+        } else if (ret != null) {
+            /*
+             * There is a race condition between libvirt and qemu: libvirt
+             * listens on qemu's monitor fd. If qemu is shutdown, while libvirt
+             * is reading on the fd, then libvirt will report an error.
+             */
+            /* Retry 3 times, to make sure we can get the vm's status */
+            for (int i = 0; i < 3; i++) {
+                try {
+                    dm = conn.domainLookupByName(vmName);
+                    state = dm.getInfo().state;
+                    break;
+                } catch (final LibvirtException e) {
+                    s_logger.debug("Failed to get vm status:" + e.getMessage());
+                } finally {
+                    try {
+                        if (dm != null) {
+                            dm.free();
+                        }
+                    } catch (final LibvirtException l) {
+                        s_logger.trace("Ignoring libvirt error.", l);
+                    }
+                }
+            }
+
+            if (state == null) {
+                s_logger.debug("Can't get vm's status, assume it's dead already");
+                return null;
+            }
+
+            if (state != DomainState.VIR_DOMAIN_SHUTOFF) {
+                s_logger.debug("Try to destroy the vm");
+                ret = stopVMInternal(conn, vmName, true);
+                if (ret != null) {
+                    return ret;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    protected String stopVMInternal(final Connect conn, final String vmName, final boolean force) {
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            final int persist = dm.isPersistent();
+            if (force) {
+                if (dm.isActive() == 1) {
+                    dm.destroy();
+                    if (persist == 1) {
+                        dm.undefine();
+                    }
+                }
+            } else {
+                if (dm.isActive() == 0) {
+                    return null;
+                }
+                dm.shutdown();
+                int retry = _stopTimeout / 2000;
+                /* Wait for the domain gets into shutoff state. When it does
+                   the dm object will no longer work, so we need to catch it. */
+                try {
+                    while (dm.isActive() == 1 && retry >= 0) {
+                        Thread.sleep(2000);
+                        retry--;
+                    }
+                } catch (final LibvirtException e) {
+                    final String error = e.toString();
+                    if (error.contains("Domain not found")) {
+                        s_logger.debug("successfully shut down vm " + vmName);
+                    } else {
+                        s_logger.debug("Error in waiting for vm shutdown:" + error);
+                    }
+                }
+                if (retry < 0) {
+                    s_logger.warn("Timed out waiting for domain " + vmName + " to shutdown gracefully");
+                    return Script.ERR_TIMEOUT;
+                } else {
+                    if (persist == 1) {
+                        dm.undefine();
+                    }
+                }
+            }
+        } catch (final LibvirtException e) {
+            if (e.getMessage().contains("Domain not found")) {
+                s_logger.debug("VM " + vmName + " doesn't exist, no need to stop it");
+                return null;
+            }
+            s_logger.debug("Failed to stop VM :" + vmName + " :", e);
+            return e.getMessage();
+        } catch (final InterruptedException ie) {
+            s_logger.debug("Interrupted sleep");
+            return ie.getMessage();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+                s_logger.trace("Ignoring libvirt error.", e);
+            }
+        }
+
+        return null;
+    }
+
+    public Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException {
+        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            final String xmlDesc = dm.getXMLDesc(0);
+            parser.parseDomainXML(xmlDesc);
+            return parser.getVncPort();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException l) {
+                s_logger.trace("Ignoring libvirt error.", l);
+            }
+        }
+    }
+
+    private boolean IsHVMEnabled(final Connect conn) {
+        final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
+        try {
+            parser.parseCapabilitiesXML(conn.getCapabilities());
+            final ArrayList<String> osTypes = parser.getGuestOsType();
+            for (final String o : osTypes) {
+                if (o.equalsIgnoreCase("hvm")) {
+                    return true;
+                }
+            }
+        } catch (final LibvirtException e) {
+            s_logger.trace("Ignoring libvirt error.", e);
+        }
+        return false;
+    }
+
+    private String getHypervisorPath(final Connect conn) {
+        final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
+        try {
+            parser.parseCapabilitiesXML(conn.getCapabilities());
+        } catch (final LibvirtException e) {
+            s_logger.debug(e.getMessage());
+        }
+        return parser.getEmulator();
+    }
+
+    boolean isGuestPVEnabled(final String guestOSName) {
+        DiskDef.DiskBus db = getGuestDiskModel(guestOSName);
+        return db != DiskDef.DiskBus.IDE;
+    }
+
+    public boolean isCentosHost() {
+        if (_hvVersion <= 9) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public DiskDef.DiskBus getDiskModelFromVMDetail(final VirtualMachineTO vmTO) {
+        Map<String, String> details = vmTO.getDetails();
+        if (details == null) {
+            return null;
+        }
+
+        final String rootDiskController = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
+        if (StringUtils.isNotBlank(rootDiskController)) {
+            s_logger.debug("Passed custom disk bus " + rootDiskController);
+            for (final DiskDef.DiskBus bus : DiskDef.DiskBus.values()) {
+                if (bus.toString().equalsIgnoreCase(rootDiskController)) {
+                    s_logger.debug("Found matching enum for disk bus " + rootDiskController);
+                    return bus;
+                }
+            }
+        }
+        return null;
+    }
+
+    private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator) {
+        if (platformEmulator == null) {
+            return DiskDef.DiskBus.IDE;
+        } else if (platformEmulator.startsWith("Other PV Virtio-SCSI")) {
+            return DiskDef.DiskBus.SCSI;
+        } else if (platformEmulator.startsWith("Ubuntu") || platformEmulator.startsWith("Fedora 13") || platformEmulator.startsWith("Fedora 12") || platformEmulator.startsWith("Fedora 11") ||
+                platformEmulator.startsWith("Fedora 10") || platformEmulator.startsWith("Fedora 9") || platformEmulator.startsWith("CentOS 5.3") || platformEmulator.startsWith("CentOS 5.4") ||
+                platformEmulator.startsWith("CentOS 5.5") || platformEmulator.startsWith("CentOS") || platformEmulator.startsWith("Fedora") ||
+                platformEmulator.startsWith("Red Hat Enterprise Linux 5.3") || platformEmulator.startsWith("Red Hat Enterprise Linux 5.4") ||
+                platformEmulator.startsWith("Red Hat Enterprise Linux 5.5") || platformEmulator.startsWith("Red Hat Enterprise Linux 6") || platformEmulator.startsWith("Debian GNU/Linux") ||
+                platformEmulator.startsWith("FreeBSD 10") || platformEmulator.startsWith("Oracle") || platformEmulator.startsWith("Other PV")) {
+            return DiskDef.DiskBus.VIRTIO;
+        } else {
+            return DiskDef.DiskBus.IDE;
+        }
+
+    }
+    private void cleanupVMNetworks(final Connect conn, final List<InterfaceDef> nics) {
+        if (nics != null) {
+            for (final InterfaceDef nic : nics) {
+                for (final VifDriver vifDriver : getAllVifDrivers()) {
+                    vifDriver.unplug(nic);
+                }
+            }
+        }
+    }
+
+    public Domain getDomain(final Connect conn, final String vmName) throws LibvirtException {
+        return conn.domainLookupByName(vmName);
+    }
+
+    public List<InterfaceDef> getInterfaces(final Connect conn, final String vmName) {
+        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            parser.parseDomainXML(dm.getXMLDesc(0));
+            return parser.getInterfaces();
+
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to get dom xml: " + e.toString());
+            return new ArrayList<InterfaceDef>();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+                s_logger.trace("Ignoring libvirt error.", e);
+            }
+        }
+    }
+
+    public List<DiskDef> getDisks(final Connect conn, final String vmName) {
+        final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+            parser.parseDomainXML(dm.getXMLDesc(0));
+            return parser.getDisks();
+
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to get dom xml: " + e.toString());
+            return new ArrayList<DiskDef>();
+        } finally {
+            try {
+                if (dm != null) {
+                    dm.free();
+                }
+            } catch (final LibvirtException e) {
+                s_logger.trace("Ignoring libvirt error.", e);
+            }
+        }
+    }
+
+    private String executeBashScript(final String script) {
+        final Script command = new Script("/bin/bash", _timeout, s_logger);
+        command.add("-c");
+        command.add(script);
+        return command.execute();
+    }
+
+    public List<VmNetworkStatsEntry> getVmNetworkStat(Connect conn, String vmName) throws LibvirtException {
+        Domain dm = null;
+        try {
+            dm = getDomain(conn, vmName);
+
+            List<VmNetworkStatsEntry> stats = new ArrayList<VmNetworkStatsEntry>();
+
+            List<InterfaceDef> nics = getInterfaces(conn, vmName);
+
+            for (InterfaceDef nic : nics) {
+                DomainInterfaceStats nicStats = dm.interfaceStats(nic.getDevName());
+                String macAddress = nic.getMacAddress();
+                VmNetworkStatsEntry stat = new VmNetworkStatsEntry(vmName, macAddress, nicStats.tx_bytes, nicStats.rx_bytes);
+                stats.add(stat);
+            }
+
+            return stats;
+        } finally {
+            if (dm != null) {
+                dm.free();
+            }
+        }
+    }
+
+    public List<VmDiskStatsEntry> getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException {
+        Domain dm = null;
+        try {
+            dm = getDomain(conn, vmName);
+
+            final List<VmDiskStatsEntry> stats = new ArrayList<VmDiskStatsEntry>();
+
+            final List<DiskDef> disks = getDisks(conn, vmName);
+
+            for (final DiskDef disk : disks) {
+                if (disk.getDeviceType() != DeviceType.DISK) {
+                    break;
+                }
+                final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel());
+                final String path = disk.getDiskPath(); // for example, path = /mnt/pool_uuid/disk_path/
+                String diskPath = null;
+                if (path != null) {
+                    final String[] token = path.split("/");
+                    if (token.length > 3) {
+                        diskPath = token[3];
+                        final VmDiskStatsEntry stat = new VmDiskStatsEntry(vmName, diskPath, blockStats.wr_req, blockStats.rd_req, blockStats.wr_bytes, blockStats.rd_bytes);
+                        stats.add(stat);
+                    }
+                }
+            }
+
+            return stats;
+        } finally {
+            if (dm != null) {
+                dm.free();
+            }
+        }
+    }
+
+    private class VmStats {
+        long _usedTime;
+        long _tx;
+        long _rx;
+        long _ioRead;
+        long _ioWrote;
+        long _bytesRead;
+        long _bytesWrote;
+        Calendar _timestamp;
+    }
+
+    public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws LibvirtException {
+        Domain dm = null;
+        try {
+            dm = getDomain(conn, vmName);
+            if (dm == null) {
+                return null;
+            }
+            DomainInfo info = dm.getInfo();
+            final VmStatsEntry stats = new VmStatsEntry();
+
+            stats.setNumCPUs(info.nrVirtCpu);
+            stats.setEntityType("vm");
+
+            stats.setMemoryKBs(info.maxMem);
+            stats.setTargetMemoryKBs(info.memory);
+            stats.setIntFreeMemoryKBs(getMemoryFreeInKBs(dm));
+
+            /* get cpu utilization */
+            VmStats oldStats = null;
+
+            final Calendar now = Calendar.getInstance();
+
+            oldStats = _vmStats.get(vmName);
+
+            long elapsedTime = 0;
+            if (oldStats != null) {
+                elapsedTime = now.getTimeInMillis() - oldStats._timestamp.getTimeInMillis();
+                double utilization = (info.cpuTime - oldStats._usedTime) / ((double)elapsedTime * 1000000);
+
+                final NodeInfo node = conn.nodeInfo();
+                utilization = utilization / node.cpus;
+                if (utilization > 0) {
+                    stats.setCPUUtilization(utilization * 100);
+                }
+            }
+
+            /* get network stats */
+
+            final List<InterfaceDef> vifs = getInterfaces(conn, vmName);
+            long rx = 0;
+            long tx = 0;
+            for (final InterfaceDef vif : vifs) {
+                final DomainInterfaceStats ifStats = dm.interfaceStats(vif.getDevName());
+                rx += ifStats.rx_bytes;
+                tx += ifStats.tx_bytes;
+            }
+
+            if (oldStats != null) {
+                final double deltarx = rx - oldStats._rx;
+                if (deltarx > 0) {
+                    stats.setNetworkReadKBs(deltarx / 1024);
+                }
+                final double deltatx = tx - oldStats._tx;
+                if (deltatx > 0) {
+                    stats.setNetworkWriteKBs(deltatx / 1024);
+                }
+            }
+
+            /* get disk stats */
+            final List<DiskDef> disks = getDisks(conn, vmName);
+            long io_rd = 0;
+            long io_wr = 0;
+            long bytes_rd = 0;
+            long bytes_wr = 0;
+            for (final DiskDef disk : disks) {
+                if (disk.getDeviceType() == DeviceType.CDROM || disk.getDeviceType() == DeviceType.FLOPPY) {
+                    continue;
+                }
+                final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel());
+                io_rd += blockStats.rd_req;
+                io_wr += blockStats.wr_req;
+                bytes_rd += blockStats.rd_bytes;
+                bytes_wr += blockStats.wr_bytes;
+            }
+
+            if (oldStats != null) {
+                final long deltaiord = io_rd - oldStats._ioRead;
+                if (deltaiord > 0) {
+                    stats.setDiskReadIOs(deltaiord);
+                }
+                final long deltaiowr = io_wr - oldStats._ioWrote;
+                if (deltaiowr > 0) {
+                    stats.setDiskWriteIOs(deltaiowr);
+                }
+                final double deltabytesrd = bytes_rd - oldStats._bytesRead;
+                if (deltabytesrd > 0) {
+                    stats.setDiskReadKBs(deltabytesrd / 1024);
+                }
+                final double deltabyteswr = bytes_wr - oldStats._bytesWrote;
+                if (deltabyteswr > 0) {
+                    stats.setDiskWriteKBs(deltabyteswr / 1024);
+                }
+            }
+
+            /* save to Hashmap */
+            final VmStats newStat = new VmStats();
+            newStat._usedTime = info.cpuTime;
+            newStat._rx = rx;
+            newStat._tx = tx;
+            newStat._ioRead = io_rd;
+            newStat._ioWrote = io_wr;
+            newStat._bytesRead = bytes_rd;
+            newStat._bytesWrote = bytes_wr;
+            newStat._timestamp = now;
+            _vmStats.put(vmName, newStat);
+            return stats;
+        } finally {
+            if (dm != null) {
+                dm.free();
+            }
+        }
+    }
+
+    /**
+     * This method retrieves the memory statistics from the domain given as parameters.
+     * If no memory statistic is found, it will return {@link NumberUtils#LONG_ZERO} as the value of free memory in the domain.
+     * If it can retrieve the domain memory statistics, it will return the free memory statistic; that means, it returns the value at the first position of the array returned by {@link Domain#memoryStats(int)}.
+     *
+     * @return the amount of free memory in KBs
+     */
+    protected long getMemoryFreeInKBs(Domain dm) throws LibvirtException {
+        MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS);
+        if (ArrayUtils.isEmpty(mems)) {
+            return NumberUtils.LONG_ZERO;
+        }
+        return mems[0].getValue();
+    }
+
+    private boolean canBridgeFirewall(final String prvNic) {
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("can_bridge_firewall");
+        cmd.add("--privnic", prvNic);
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean destroyNetworkRulesForVM(final Connect conn, final String vmName) {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+        String vif = null;
+        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
+        if (intfs.size() > 0) {
+            final InterfaceDef intf = intfs.get(0);
+            vif = intf.getDevName();
+        }
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("destroy_network_rules_for_vm");
+        cmd.add("--vmname", vmName);
+        if (vif != null) {
+            cmd.add("--vif", vif);
+        }
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean defaultNetworkRules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final String secIpStr) {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+
+        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
+        if (intfs.size() == 0 || intfs.size() < nic.getDeviceId()) {
+            return false;
+        }
+
+        final InterfaceDef intf = intfs.get(nic.getDeviceId());
+        final String brname = intf.getBrName();
+        final String vif = intf.getDevName();
+
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("default_network_rules");
+        cmd.add("--vmname", vmName);
+        cmd.add("--vmid", vmId.toString());
+        if (nic.getIp() != null) {
+            cmd.add("--vmip", nic.getIp());
+        }
+        if (nic.getIp6Address() != null) {
+            cmd.add("--vmip6", nic.getIp6Address());
+        }
+        cmd.add("--vmmac", nic.getMac());
+        cmd.add("--vif", vif);
+        cmd.add("--brname", brname);
+        cmd.add("--nicsecips", secIpStr);
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    protected boolean post_default_network_rules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final InetAddress dhcpServerIp, final String hostIp, final String hostMacAddr) {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+
+        final List<InterfaceDef> intfs = getInterfaces(conn, vmName);
+        if (intfs.size() < nic.getDeviceId()) {
+            return false;
+        }
+
+        final InterfaceDef intf = intfs.get(nic.getDeviceId());
+        final String brname = intf.getBrName();
+        final String vif = intf.getDevName();
+
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("post_default_network_rules");
+        cmd.add("--vmname", vmName);
+        cmd.add("--vmid", vmId.toString());
+        cmd.add("--vmip", nic.getIp());
+        cmd.add("--vmmac", nic.getMac());
+        cmd.add("--vif", vif);
+        cmd.add("--brname", brname);
+        if (dhcpServerIp != null) {
+            cmd.add("--dhcpSvr", dhcpServerIp.getHostAddress());
+        }
+
+        cmd.add("--hostIp", hostIp);
+        cmd.add("--hostMacAddr", hostMacAddr);
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean configureDefaultNetworkRulesForSystemVm(final Connect conn, final String vmName) {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("default_network_rules_systemvm");
+        cmd.add("--vmname", vmName);
+        cmd.add("--localbrname", _linkLocalBridgeName);
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean addNetworkRules(final String vmName, final String vmId, final String guestIP, final String guestIP6, final String sig, final String seq, final String mac, final String rules, final String vif, final String brname,
+                                   final String secIps) {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+
+        final String newRules = rules.replace(" ", ";");
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("add_network_rules");
+        cmd.add("--vmname", vmName);
+        cmd.add("--vmid", vmId);
+        cmd.add("--vmip", guestIP);
+        if (StringUtils.isNotBlank(guestIP6)) {
+            cmd.add("--vmip6", guestIP6);
+        }
+        cmd.add("--sig", sig);
+        cmd.add("--seq", seq);
+        cmd.add("--vmmac", mac);
+        cmd.add("--vif", vif);
+        cmd.add("--brname", brname);
+        cmd.add("--nicsecips", secIps);
+        if (newRules != null && !newRules.isEmpty()) {
+            cmd.add("--rules", newRules);
+        }
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean configureNetworkRulesVMSecondaryIP(final Connect conn, final String vmName, final String secIp, final String action) {
+
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("network_rules_vmSecondaryIp");
+        cmd.add("--vmname", vmName);
+        cmd.add("--nicsecips", secIp);
+        cmd.add("--action", action);
+
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean cleanupRules() {
+        if (!_canBridgeFirewall) {
+            return false;
+        }
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("cleanup_rules");
+        final String result = cmd.execute();
+        if (result != null) {
+            return false;
+        }
+        return true;
+    }
+
+    public String getRuleLogsForVms() {
+        final Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
+        cmd.add("get_rule_logs_for_vms");
+        final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+        final String result = cmd.execute(parser);
+        if (result == null) {
+            return parser.getLine();
+        }
+        return null;
+    }
+
+    private HashMap<String, Pair<Long, Long>> syncNetworkGroups(final long id) {
+        final HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
+
+        final String result = getRuleLogsForVms();
+        s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result);
+        final String[] rulelogs = result != null ? result.split(";") : new String[0];
+        for (final String rulesforvm : rulelogs) {
+            final String[] log = rulesforvm.split(",");
+            if (log.length != 6) {
+                continue;
+            }
+            try {
+                states.put(log[0], new Pair<Long, Long>(Long.parseLong(log[1]), Long.parseLong(log[5])));
+            } catch (final NumberFormatException nfe) {
+                states.put(log[0], new Pair<Long, Long>(-1L, -1L));
+            }
+        }
+        return states;
+    }
+
+    /* online snapshot supported by enhanced qemu-kvm */
+    private boolean isSnapshotSupported() {
+        final String result = executeBashScript("qemu-img --help|grep convert");
+        if (result != null) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public Pair<Double, Double> getNicStats(final String nicName) {
+        return new Pair<Double, Double>(readDouble(nicName, "rx_bytes"), readDouble(nicName, "tx_bytes"));
+    }
+
+    static double readDouble(final String nicName, final String fileName) {
+        final String path = "/sys/class/net/" + nicName + "/statistics/" + fileName;
+        try {
+            return Double.parseDouble(FileUtils.readFileToString(new File(path)));
+        } catch (final IOException ioe) {
+            s_logger.warn("Failed to read the " + fileName + " for " + nicName + " from " + path, ioe);
+            return 0.0;
+        }
+    }
+
+    private String prettyVersion(final long version) {
+        final long major = version / 1000000;
+        final long minor = version % 1000000 / 1000;
+        final long release = version % 1000000 % 1000;
+        return major + "." + minor + "." + release;
+    }
+
+    @Override
+    public void setName(final String name) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void setConfigParams(final Map<String, Object> params) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(final int level) {
+        // TODO Auto-generated method stub
+    }
+
+    public HypervisorType getHypervisorType(){
+        return _hypervisorType;
+    }
+
+    public String mapRbdDevice(final KVMPhysicalDisk disk){
+        final KVMStoragePool pool = disk.getPool();
+        //Check if rbd image is already mapped
+        final String[] splitPoolImage = disk.getPath().split("/");
+        String device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
+        if(device == null) {
+            //If not mapped, map and return mapped device
+            Script.runSimpleBashScript("rbd map " + disk.getPath() + " --id " + pool.getAuthUserName());
+            device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
+        }
+        return device;
+    }
+
+    public List<Ternary<String, Boolean, String>> cleanVMSnapshotMetadata(Domain dm) throws LibvirtException {
+        s_logger.debug("Cleaning the metadata of vm snapshots of vm " + dm.getName());
+        List<Ternary<String, Boolean, String>> vmsnapshots = new ArrayList<Ternary<String, Boolean, String>>();
+        if (dm.snapshotNum() == 0) {
+            return vmsnapshots;
+        }
+        String currentSnapshotName = null;
+        try {
+            DomainSnapshot snapshotCurrent = dm.snapshotCurrent();
+            String snapshotXML = snapshotCurrent.getXMLDesc();
+            snapshotCurrent.free();
+            DocumentBuilder builder;
+            try {
+                builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+
+                InputSource is = new InputSource();
+                is.setCharacterStream(new StringReader(snapshotXML));
+                Document doc = builder.parse(is);
+                Element rootElement = doc.getDocumentElement();
+
+                currentSnapshotName = getTagValue("name", rootElement);
+            } catch (ParserConfigurationException e) {
+                s_logger.debug(e.toString());
+            } catch (SAXException e) {
+                s_logger.debug(e.toString());
+            } catch (IOException e) {
+                s_logger.debug(e.toString());
+            }
+        } catch (LibvirtException e) {
+            s_logger.debug("Fail to get the current vm snapshot for vm: " + dm.getName() + ", continue");
+        }
+        int flags = 2; // VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY = 2
+        String[] snapshotNames = dm.snapshotListNames();
+        Arrays.sort(snapshotNames);
+        for (String snapshotName: snapshotNames) {
+            DomainSnapshot snapshot = dm.snapshotLookupByName(snapshotName);
+            Boolean isCurrent = (currentSnapshotName != null && currentSnapshotName.equals(snapshotName)) ? true: false;
+            vmsnapshots.add(new Ternary<String, Boolean, String>(snapshotName, isCurrent, snapshot.getXMLDesc()));
+        }
+        for (String snapshotName: snapshotNames) {
+            DomainSnapshot snapshot = dm.snapshotLookupByName(snapshotName);
+            snapshot.delete(flags); // clean metadata of vm snapshot
+        }
+        return vmsnapshots;
+    }
+
+    private static String getTagValue(String tag, Element eElement) {
+        NodeList nlList = eElement.getElementsByTagName(tag).item(0).getChildNodes();
+        Node nValue = nlList.item(0);
+
+        return nValue.getNodeValue();
+    }
+
+    public void restoreVMSnapshotMetadata(Domain dm, String vmName, List<Ternary<String, Boolean, String>> vmsnapshots) {
+        s_logger.debug("Restoring the metadata of vm snapshots of vm " + vmName);
+        for (Ternary<String, Boolean, String> vmsnapshot: vmsnapshots) {
+            String snapshotName = vmsnapshot.first();
+            Boolean isCurrent = vmsnapshot.second();
+            String snapshotXML = vmsnapshot.third();
+            s_logger.debug("Restoring vm snapshot " + snapshotName + " on " + vmName + " with XML:\n " + snapshotXML);
+            try {
+                int flags = 1; // VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE = 1
+                if (isCurrent) {
+                    flags += 2; // VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT = 2
+                }
+                dm.snapshotCreateXML(snapshotXML, flags);
+            } catch (LibvirtException e) {
+                s_logger.debug("Failed to restore vm snapshot " + snapshotName + ", continue");
+                continue;
+            }
+        }
+    }
+
+    public String getHostDistro() {
+        return _hostDistro;
+    }
+
+    public boolean isHostSecured() {
+        // Test for host certificates
+        final File confFile = PropertiesUtil.findConfigFile(KeyStoreUtils.AGENT_PROPSFILE);
+        if (confFile == null || !confFile.exists() || !Paths.get(confFile.getParent(), KeyStoreUtils.CERT_FILENAME).toFile().exists()) {
+            return false;
+        }
+
+        // Test for libvirt TLS configuration
+        try {
+            new Connect(String.format("qemu+tls://%s/system", _privateIp));
+        } catch (final LibvirtException ignored) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
new file mode 100644
index 0000000..97963fd
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
@@ -0,0 +1,377 @@
+// 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.google.common.base.Strings;
+
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.NicModel;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.RngDef.RngBackendModel;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogModel;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.WatchDogDef.WatchDogAction;
+
+public class LibvirtDomainXMLParser {
+    private static final Logger s_logger = Logger.getLogger(LibvirtDomainXMLParser.class);
+    private final List<InterfaceDef> interfaces = new ArrayList<InterfaceDef>();
+    private final List<DiskDef> diskDefs = new ArrayList<DiskDef>();
+    private final List<RngDef> rngDefs = new ArrayList<RngDef>();
+    private final List<ChannelDef> channels = new ArrayList<ChannelDef>();
+    private final List<WatchDogDef> watchDogDefs = new ArrayList<WatchDogDef>();
+    private Integer vncPort;
+    private String desc;
+
+    public boolean parseDomainXML(String domXML) {
+        DocumentBuilder builder;
+        try {
+            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+
+            InputSource is = new InputSource();
+            is.setCharacterStream(new StringReader(domXML));
+            Document doc = builder.parse(is);
+
+            Element rootElement = doc.getDocumentElement();
+
+            desc = getTagValue("description", rootElement);
+
+            Element devices = (Element)rootElement.getElementsByTagName("devices").item(0);
+            NodeList disks = devices.getElementsByTagName("disk");
+            for (int i = 0; i < disks.getLength(); i++) {
+                Element disk = (Element)disks.item(i);
+                String type = disk.getAttribute("type");
+                DiskDef def = new DiskDef();
+                if (type.equalsIgnoreCase("network")) {
+                    String diskFmtType = getAttrValue("driver", "type", disk);
+                    String diskCacheMode = getAttrValue("driver", "cache", disk);
+                    String diskPath = getAttrValue("source", "name", disk);
+                    String protocol = getAttrValue("source", "protocol", disk);
+                    String authUserName = getAttrValue("auth", "username", disk);
+                    String poolUuid = getAttrValue("secret", "uuid", disk);
+                    String host = getAttrValue("host", "name", disk);
+                    int port = Integer.parseInt(getAttrValue("host", "port", disk));
+                    String diskLabel = getAttrValue("target", "dev", disk);
+                    String bus = getAttrValue("target", "bus", disk);
+
+                    DiskDef.DiskFmtType fmt = null;
+                    if (diskFmtType != null) {
+                        fmt = DiskDef.DiskFmtType.valueOf(diskFmtType.toUpperCase());
+                    }
+
+                    def.defNetworkBasedDisk(diskPath, host, port, authUserName, poolUuid, diskLabel,
+                        DiskDef.DiskBus.valueOf(bus.toUpperCase()),
+                        DiskDef.DiskProtocol.valueOf(protocol.toUpperCase()), fmt);
+                    def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
+                } else {
+                    String diskFmtType = getAttrValue("driver", "type", disk);
+                    String diskCacheMode = getAttrValue("driver", "cache", disk);
+                    String diskFile = getAttrValue("source", "file", disk);
+                    String diskDev = getAttrValue("source", "dev", disk);
+
+                    String diskLabel = getAttrValue("target", "dev", disk);
+                    String bus = getAttrValue("target", "bus", disk);
+                    String device = disk.getAttribute("device");
+
+                    if (type.equalsIgnoreCase("file")) {
+                        if (device.equalsIgnoreCase("disk")) {
+                            DiskDef.DiskFmtType fmt = null;
+                            if (diskFmtType != null) {
+                                fmt = DiskDef.DiskFmtType.valueOf(diskFmtType.toUpperCase());
+                            }
+                            def.defFileBasedDisk(diskFile, diskLabel, DiskDef.DiskBus.valueOf(bus.toUpperCase()), fmt);
+                        } else if (device.equalsIgnoreCase("cdrom")) {
+                            def.defISODisk(diskFile , i+1);
+                        }
+                    } else if (type.equalsIgnoreCase("block")) {
+                        def.defBlockBasedDisk(diskDev, diskLabel,
+                            DiskDef.DiskBus.valueOf(bus.toUpperCase()));
+                    }
+                    if (StringUtils.isNotBlank(diskCacheMode)) {
+                        def.setCacheMode(DiskDef.DiskCacheMode.valueOf(diskCacheMode.toUpperCase()));
+                    }
+                }
+
+                NodeList iotune = disk.getElementsByTagName("iotune");
+                if ((iotune != null) && (iotune.getLength() != 0)) {
+                    String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0));
+                    if (bytesReadRateStr != null) {
+                        Long bytesReadRate = Long.parseLong(bytesReadRateStr);
+                        def.setBytesReadRate(bytesReadRate);
+                    }
+                    String bytesReadRateMaxStr = getTagValue("read_bytes_sec_max", (Element)iotune.item(0));
+                    if (bytesReadRateMaxStr != null) {
+                        Long bytesReadRateMax = Long.parseLong(bytesReadRateMaxStr);
+                        def.setBytesReadRateMax(bytesReadRateMax);
+                    }
+                    String bytesReadRateMaxLengthStr = getTagValue("read_bytes_sec_max_length", (Element)iotune.item(0));
+                    if (bytesReadRateMaxLengthStr != null) {
+                        Long bytesReadRateMaxLength = Long.parseLong(bytesReadRateMaxLengthStr);
+                        def.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+                    }
+                    String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0));
+                    if (bytesWriteRateStr != null) {
+                        Long bytesWriteRate = Long.parseLong(bytesWriteRateStr);
+                        def.setBytesWriteRate(bytesWriteRate);
+                    }
+                    String bytesWriteRateMaxStr = getTagValue("write_bytes_sec_max", (Element)iotune.item(0));
+                    if (bytesWriteRateMaxStr != null) {
+                        Long bytesWriteRateMax = Long.parseLong(bytesWriteRateMaxStr);
+                        def.setBytesWriteRateMax(bytesWriteRateMax);
+                    }
+                    String bytesWriteRateMaxLengthStr = getTagValue("write_bytes_sec_max_length", (Element)iotune.item(0));
+                    if (bytesWriteRateMaxLengthStr != null) {
+                        Long bytesWriteRateMaxLength = Long.parseLong(bytesWriteRateMaxLengthStr);
+                        def.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+                    }
+                    String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0));
+                    if (iopsReadRateStr != null) {
+                        Long iopsReadRate = Long.parseLong(iopsReadRateStr);
+                        def.setIopsReadRate(iopsReadRate);
+                    }
+                    String iopsReadRateMaxStr = getTagValue("read_iops_sec_max", (Element)iotune.item(0));
+                    if (iopsReadRateMaxStr != null) {
+                        Long iopsReadRateMax = Long.parseLong(iopsReadRateMaxStr);
+                        def.setIopsReadRateMax(iopsReadRateMax);
+                    }
+                    String iopsReadRateMaxLengthStr = getTagValue("read_iops_sec_max_length", (Element)iotune.item(0));
+                    if (iopsReadRateMaxLengthStr != null) {
+                        Long iopsReadRateMaxLength = Long.parseLong(iopsReadRateMaxLengthStr);
+                        def.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+                    }
+                    String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0));
+                    if (iopsWriteRateStr != null) {
+                        Long iopsWriteRate = Long.parseLong(iopsWriteRateStr);
+                        def.setIopsWriteRate(iopsWriteRate);
+                    }
+                    String iopsWriteRateMaxStr = getTagValue("write_iops_sec_max", (Element)iotune.item(0));
+                    if (iopsWriteRateMaxStr != null) {
+                        Long iopsWriteRateMax = Long.parseLong(iopsWriteRateMaxStr);
+                        def.setIopsWriteRateMax(iopsWriteRateMax);
+                    }
+                    String iopsWriteRateMaxLengthStr = getTagValue("write_iops_sec_max_length", (Element)iotune.item(0));
+                    if (iopsWriteRateMaxLengthStr != null) {
+                        Long iopsWriteRateMaxLength = Long.parseLong(iopsWriteRateMaxLengthStr);
+                        def.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
+                    }
+                }
+
+                diskDefs.add(def);
+            }
+
+            NodeList nics = devices.getElementsByTagName("interface");
+            for (int i = 0; i < nics.getLength(); i++) {
+                Element nic = (Element)nics.item(i);
+
+                String type = nic.getAttribute("type");
+                String mac = getAttrValue("mac", "address", nic);
+                String dev = getAttrValue("target", "dev", nic);
+                String model = getAttrValue("model", "type", nic);
+                String slot = StringUtils.removeStart(getAttrValue("address", "slot", nic), "0x");
+
+                InterfaceDef def = new InterfaceDef();
+                NodeList bandwidth = nic.getElementsByTagName("bandwidth");
+                Integer networkRateKBps = 0;
+                if ((bandwidth != null) && (bandwidth.getLength() != 0)) {
+                    Integer inbound = Integer.valueOf(getAttrValue("inbound", "average", (Element)bandwidth.item(0)));
+                    Integer outbound = Integer.valueOf(getAttrValue("outbound", "average", (Element)bandwidth.item(0)));
+                    if (inbound.equals(outbound)) {
+                        networkRateKBps = inbound;
+                    }
+                }
+                if (type.equalsIgnoreCase("network")) {
+                    String network = getAttrValue("source", "network", nic);
+                    def.defPrivateNet(network, dev, mac, NicModel.valueOf(model.toUpperCase()), networkRateKBps);
+                } else if (type.equalsIgnoreCase("bridge")) {
+                    String bridge = getAttrValue("source", "bridge", nic);
+                    def.defBridgeNet(bridge, dev, mac, NicModel.valueOf(model.toUpperCase()), networkRateKBps);
+                } else if (type.equalsIgnoreCase("ethernet")) {
+                    String scriptPath = getAttrValue("script", "path", nic);
+                    def.defEthernet(dev, mac, NicModel.valueOf(model.toUpperCase()), scriptPath, networkRateKBps);
+                } else if (type.equals("vhostuser")) {
+                    String sourcePort = getAttrValue("source", "path", nic);
+                    String[] sourcePathParts = sourcePort.split("/");
+                    String port = sourcePathParts[sourcePathParts.length - 1];
+                    def.setDpdkSourcePort(port);
+                }
+
+                if (StringUtils.isNotBlank(slot)) {
+                    def.setSlot(Integer.parseInt(slot, 16));
+                }
+
+                interfaces.add(def);
+            }
+
+            NodeList ports = devices.getElementsByTagName("channel");
+            for (int i = 0; i < ports.getLength(); i++) {
+                Element channel = (Element)ports.item(i);
+
+                String type = channel.getAttribute("type");
+                String path = getAttrValue("source", "path", channel);
+                String name = getAttrValue("target", "name", channel);
+                String state = getAttrValue("target", "state", channel);
+
+                ChannelDef def = null;
+                if (!StringUtils.isNotBlank(state)) {
+                    def = new ChannelDef(name, ChannelDef.ChannelType.valueOf(type.toUpperCase()), new File(path));
+                } else {
+                    def = new ChannelDef(name, ChannelDef.ChannelType.valueOf(type.toUpperCase()),
+                            ChannelDef.ChannelState.valueOf(state.toUpperCase()), new File(path));
+                }
+
+                channels.add(def);
+            }
+
+            Element graphic = (Element)devices.getElementsByTagName("graphics").item(0);
+
+            if (graphic != null) {
+                String port = graphic.getAttribute("port");
+                if (port != null) {
+                    try {
+                        vncPort = Integer.parseInt(port);
+                        if (vncPort != -1) {
+                            vncPort = vncPort - 5900;
+                        } else {
+                            vncPort = null;
+                        }
+                    } catch (NumberFormatException nfe) {
+                        vncPort = null;
+                    }
+                }
+            }
+
+            NodeList rngs = devices.getElementsByTagName("rng");
+            for (int i = 0; i < rngs.getLength(); i++) {
+                RngDef def = null;
+                Element rng = (Element)rngs.item(i);
+                String backendModel = getAttrValue("backend", "model", rng);
+                String path = getTagValue("backend", rng);
+                String bytes = getAttrValue("rate", "bytes", rng);
+                String period = getAttrValue("rate", "period", rng);
+
+                if (Strings.isNullOrEmpty(backendModel)) {
+                    def = new RngDef(path, Integer.parseInt(bytes), Integer.parseInt(period));
+                } else {
+                    def = new RngDef(path, RngBackendModel.valueOf(backendModel.toUpperCase()),
+                                     Integer.parseInt(bytes), Integer.parseInt(period));
+                }
+
+                rngDefs.add(def);
+            }
+
+            NodeList watchDogs = devices.getElementsByTagName("watchdog");
+            for (int i = 0; i < watchDogs.getLength(); i++) {
+                WatchDogDef def = null;
+                Element watchDog = (Element)watchDogs.item(i);
+                String action = watchDog.getAttribute("action");
+                String model = watchDog.getAttribute("model");
+
+                if (Strings.isNullOrEmpty(model)) {
+                   continue;
+                }
+
+                if (Strings.isNullOrEmpty(action)) {
+                    def = new WatchDogDef(WatchDogModel.valueOf(model.toUpperCase()));
+                } else {
+                    def = new WatchDogDef(WatchDogAction.valueOf(action.toUpperCase()),
+                                          WatchDogModel.valueOf(model.toUpperCase()));
+                }
+
+                watchDogDefs.add(def);
+            }
+
+            return true;
+        } catch (ParserConfigurationException e) {
+            s_logger.debug(e.toString());
+        } catch (SAXException e) {
+            s_logger.debug(e.toString());
+        } catch (IOException e) {
+            s_logger.debug(e.toString());
+        }
+        return false;
+    }
+
+    private static String getTagValue(String tag, Element eElement) {
+        NodeList tagNodeList = eElement.getElementsByTagName(tag);
+        if (tagNodeList == null || tagNodeList.getLength() == 0) {
+            return null;
+        }
+
+        NodeList nlList = tagNodeList.item(0).getChildNodes();
+
+        Node nValue = nlList.item(0);
+
+        return nValue.getNodeValue();
+    }
+
+    private static String getAttrValue(String tag, String attr, Element eElement) {
+        NodeList tagNode = eElement.getElementsByTagName(tag);
+        if (tagNode.getLength() == 0) {
+            return null;
+        }
+        Element node = (Element)tagNode.item(0);
+        return node.getAttribute(attr);
+    }
+
+    public Integer getVncPort() {
+        return vncPort;
+    }
+
+    public List<InterfaceDef> getInterfaces() {
+        return interfaces;
+    }
+
+    public List<DiskDef> getDisks() {
+        return diskDefs;
+    }
+
+    public List<RngDef> getRngs() {
+        return rngDefs;
+    }
+
+    public List<ChannelDef> getChannels() {
+        return Collections.unmodifiableList(channels);
+    }
+
+    public List<WatchDogDef> getWatchDogs() {
+        return watchDogDefs;
+    }
+
+    public String getDescription() {
+        return desc;
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtNetworkDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtNetworkDef.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtNetworkDef.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtNetworkDef.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtSecretDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtSecretDef.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtSecretDef.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtSecretDef.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDef.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDef.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDef.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolXMLParser.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolXMLParser.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolXMLParser.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeXMLParser.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeXMLParser.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeXMLParser.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
new file mode 100644
index 0000000..4f7732b
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
@@ -0,0 +1,1938 @@
+// 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;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.google.common.collect.Maps;
+
+public class LibvirtVMDef {
+    private static final Logger s_logger = Logger.getLogger(LibvirtVMDef.class);
+
+    private String _hvsType;
+    private static long s_libvirtVersion;
+    private static long s_qemuVersion;
+    private String _domName;
+    private String _domUUID;
+    private String _desc;
+    private String _platformEmulator;
+    private final Map<String, Object> components = new HashMap<String, Object>();
+
+    public static class GuestDef {
+        enum GuestType {
+            KVM, XEN, EXE, LXC
+        }
+
+        enum BootOrder {
+            HARDISK("hd"), CDROM("cdrom"), FLOPPY("fd"), NETWORK("network");
+            String _order;
+
+            BootOrder(String order) {
+                _order = order;
+            }
+
+            @Override
+            public String toString() {
+                return _order;
+            }
+        }
+
+        private GuestType _type;
+        private String _arch;
+        private String _loader;
+        private String _kernel;
+        private String _initrd;
+        private String _root;
+        private String _cmdline;
+        private String _uuid;
+        private final List<BootOrder> _bootdevs = new ArrayList<BootOrder>();
+        private String _machine;
+
+        public void setGuestType(GuestType type) {
+            _type = type;
+        }
+
+        public GuestType getGuestType() {
+            return _type;
+        }
+
+        public void setGuestArch(String arch) {
+            _arch = arch;
+        }
+
+        public void setMachineType(String machine) {
+            _machine = machine;
+        }
+
+        public void setLoader(String loader) {
+            _loader = loader;
+        }
+
+        public void setBootKernel(String kernel, String initrd, String rootdev, String cmdline) {
+            _kernel = kernel;
+            _initrd = initrd;
+            _root = rootdev;
+            _cmdline = cmdline;
+        }
+
+        public void setBootOrder(BootOrder order) {
+            _bootdevs.add(order);
+        }
+
+        public void setUuid(String uuid) {
+            _uuid = uuid;
+        }
+
+        @Override
+        public String toString() {
+            if (_type == GuestType.KVM) {
+                StringBuilder guestDef = new StringBuilder();
+
+                guestDef.append("<sysinfo type='smbios'>\n");
+                guestDef.append("<system>\n");
+                guestDef.append("<entry name='manufacturer'>Apache Software Foundation</entry>\n");
+                guestDef.append("<entry name='product'>CloudStack " + _type.toString() + " Hypervisor</entry>\n");
+                guestDef.append("<entry name='uuid'>" + _uuid + "</entry>\n");
+                guestDef.append("</system>\n");
+                guestDef.append("</sysinfo>\n");
+
+                guestDef.append("<os>\n");
+                guestDef.append("<type ");
+                if (_arch != null) {
+                    guestDef.append(" arch='" + _arch + "'");
+                }
+                if (_machine != null) {
+                    guestDef.append(" machine='" + _machine + "'");
+                }
+                guestDef.append(">hvm</type>\n");
+                if (!_bootdevs.isEmpty()) {
+                    for (BootOrder bo : _bootdevs) {
+                        guestDef.append("<boot dev='" + bo + "'/>\n");
+                    }
+                }
+                guestDef.append("<smbios mode='sysinfo'/>\n");
+                guestDef.append("</os>\n");
+                return guestDef.toString();
+            } else if (_type == GuestType.LXC) {
+                StringBuilder guestDef = new StringBuilder();
+                guestDef.append("<os>\n");
+                guestDef.append("<type>exe</type>\n");
+                guestDef.append("<init>/sbin/init</init>\n");
+                guestDef.append("</os>\n");
+                return guestDef.toString();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    public static class GuestResourceDef {
+        private long _mem;
+        private long _currentMem = -1;
+        private String _memBacking;
+        private int _vcpu = -1;
+        private boolean _memBalloning = false;
+
+        public void setMemorySize(long mem) {
+            _mem = mem;
+        }
+
+        public void setCurrentMem(long currMem) {
+            _currentMem = currMem;
+        }
+
+        public void setMemBacking(String memBacking) {
+            _memBacking = memBacking;
+        }
+
+        public void setVcpuNum(int vcpu) {
+            _vcpu = vcpu;
+        }
+
+        public void setMemBalloning(boolean turnon) {
+            _memBalloning = turnon;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder resBuidler = new StringBuilder();
+            resBuidler.append("<memory>" + _mem + "</memory>\n");
+            if (_currentMem != -1) {
+                resBuidler.append("<currentMemory>" + _currentMem + "</currentMemory>\n");
+            }
+            if (_memBacking != null) {
+                resBuidler.append("<memoryBacking>" + "<" + _memBacking + "/>" + "</memoryBacking>\n");
+            }
+            if (_memBalloning) {
+                resBuidler.append("<devices>\n" + "<memballoon model='virtio'/>\n" + "</devices>\n");
+            } else {
+                resBuidler.append("<devices>\n" + "<memballoon model='none'/>\n" + "</devices>\n");
+            }
+            if (_vcpu != -1) {
+                resBuidler.append("<vcpu>" + _vcpu + "</vcpu>\n");
+            }
+            return resBuidler.toString();
+        }
+    }
+
+    public static class HyperVEnlightenmentFeatureDef {
+        enum Enlight {
+            RELAX("relaxed"),
+            VAPIC("vapic"),
+            SPIN("spinlocks");
+
+            private final String featureName;
+            Enlight(String featureName) { this.featureName = featureName; }
+            String getFeatureName() { return featureName; }
+
+            static boolean isValidFeature(String featureName) {
+                Enlight[] enlights = Enlight.values();
+                for(Enlight e : enlights) {
+                    if(e.getFeatureName().equals(featureName))
+                        return true;
+                }
+                return false;
+            }
+        }
+
+        private final Map<String, String> features = new HashMap<String, String>();
+        private int retries = 4096; // set to sane default
+
+        public void setFeature(String feature, boolean on) {
+            if(on && Enlight.isValidFeature(feature))
+                setFeature(feature);
+        }
+
+        private void setFeature(String feature) {
+            features.put(feature, "on");
+        }
+
+        public void setRetries(int retry) {
+            if(retry>=retries)
+                retries=retry;
+        }
+
+        public int getRetries() {
+            return retries;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder feaBuilder = new StringBuilder();
+            feaBuilder.append("<hyperv>\n");
+            for (Map.Entry<String, String> e : features.entrySet()) {
+                feaBuilder.append("<");
+                feaBuilder.append(e.getKey());
+
+                if(e.getKey().equals("spinlocks"))  feaBuilder.append(" state='" + e.getValue() + "' retries='" + getRetries() + "'");
+                else                                feaBuilder.append(" state='" + e.getValue() + "'");
+
+                feaBuilder.append("/>\n");
+            }
+            feaBuilder.append("</hyperv>\n");
+            return feaBuilder.toString();
+        }
+    }
+
+    public static class FeaturesDef {
+        private final List<String> _features = new ArrayList<String>();
+
+        private HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = null;
+        public void addFeatures(String feature) {
+            _features.add(feature);
+        }
+
+        public void addHyperVFeature(HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef) {
+            this.hyperVEnlightenmentFeatureDef = hyperVEnlightenmentFeatureDef;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder feaBuilder = new StringBuilder();
+            feaBuilder.append("<features>\n");
+            for (String feature : _features) {
+                feaBuilder.append("<" + feature + "/>\n");
+            }
+            if (hyperVEnlightenmentFeatureDef != null) {
+                String hpervF = hyperVEnlightenmentFeatureDef.toString();
+                if (!hpervF.isEmpty()) {
+                    feaBuilder.append(hpervF);
+                }
+            }
+            feaBuilder.append("</features>\n");
+            return feaBuilder.toString();
+        }
+    }
+
+    public static class TermPolicy {
+        private String _reboot;
+        private String _powerOff;
+        private String _crash;
+
+        public TermPolicy() {
+            _reboot = _powerOff = _crash = "destroy";
+        }
+
+        public void setRebootPolicy(String rbPolicy) {
+            _reboot = rbPolicy;
+        }
+
+        public void setPowerOffPolicy(String poPolicy) {
+            _powerOff = poPolicy;
+        }
+
+        public void setCrashPolicy(String crashPolicy) {
+            _crash = crashPolicy;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder term = new StringBuilder();
+            term.append("<on_reboot>" + _reboot + "</on_reboot>\n");
+            term.append("<on_poweroff>" + _powerOff + "</on_poweroff>\n");
+            term.append("<on_crash>" + _powerOff + "</on_crash>\n");
+            return term.toString();
+        }
+    }
+
+    public static class ClockDef {
+        public enum ClockOffset {
+            UTC("utc"), LOCALTIME("localtime"), TIMEZONE("timezone"), VARIABLE("variable");
+
+            private String _offset;
+
+            private ClockOffset(String offset) {
+                _offset = offset;
+            }
+
+            @Override
+            public String toString() {
+                return _offset;
+            }
+        }
+
+        private ClockOffset _offset;
+        private String _timerName;
+        private String _tickPolicy;
+        private String _track;
+        private boolean _noKvmClock = false;
+
+        public ClockDef() {
+            _offset = ClockOffset.UTC;
+        }
+
+        public void setClockOffset(ClockOffset offset) {
+            _offset = offset;
+        }
+
+        public void setTimer(String timerName, String tickPolicy, String track) {
+            _timerName = timerName;
+            _tickPolicy = tickPolicy;
+            _track = track;
+        }
+
+        public void setTimer(String timerName, String tickPolicy, String track, boolean noKvmClock) {
+            _noKvmClock = noKvmClock;
+            setTimer(timerName, tickPolicy, track);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder clockBuilder = new StringBuilder();
+            clockBuilder.append("<clock offset='");
+            clockBuilder.append(_offset.toString());
+            clockBuilder.append("'>\n");
+            if (_timerName != null) {
+                clockBuilder.append("<timer name='");
+                clockBuilder.append(_timerName);
+                clockBuilder.append("' ");
+
+                if (_timerName.equals("kvmclock") && _noKvmClock) {
+                    clockBuilder.append("present='no' />");
+                } else if (_timerName.equals("hypervclock")) {
+                    clockBuilder.append("present='yes' />");
+                } else {
+                    if (_tickPolicy != null) {
+                        clockBuilder.append("tickpolicy='");
+                        clockBuilder.append(_tickPolicy);
+                        clockBuilder.append("' ");
+                    }
+
+                    if (_track != null) {
+                        clockBuilder.append("track='");
+                        clockBuilder.append(_track);
+                        clockBuilder.append("' ");
+                    }
+
+                    clockBuilder.append(">\n");
+                    clockBuilder.append("</timer>\n");
+                }
+            }
+            clockBuilder.append("</clock>\n");
+            return clockBuilder.toString();
+        }
+    }
+
+    public static class DevicesDef {
+        private String _emulator;
+        private GuestDef.GuestType _guestType;
+        private final Map<String, List<?>> devices = new HashMap<String, List<?>>();
+
+        public boolean addDevice(Object device) {
+            Object dev = devices.get(device.getClass().toString());
+            if (dev == null) {
+                List<Object> devs = new ArrayList<Object>();
+                devs.add(device);
+                devices.put(device.getClass().toString(), devs);
+            } else {
+                List<Object> devs = (List<Object>)dev;
+                devs.add(device);
+            }
+            return true;
+        }
+
+        public void setEmulatorPath(String emulator) {
+            _emulator = emulator;
+        }
+
+        public void setGuestType(GuestDef.GuestType guestType) {
+            _guestType = guestType;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder devicesBuilder = new StringBuilder();
+            devicesBuilder.append("<devices>\n");
+            if (_emulator != null) {
+                devicesBuilder.append("<emulator>" + _emulator + "</emulator>\n");
+            }
+
+            for (List<?> devs : devices.values()) {
+                for (Object dev : devs) {
+                    if (_guestType == GuestDef.GuestType.LXC) {
+                        if (dev instanceof GraphicDef || dev instanceof InputDef) {
+                            continue;
+                        }
+                        if(dev instanceof DiskDef){
+                            DiskDef disk = (DiskDef)dev;
+                            if(!disk.getDiskType().toString().equals("block")){
+                                continue;
+                            }
+                        }
+                    }
+                    devicesBuilder.append(dev.toString());
+                }
+            }
+            devicesBuilder.append("</devices>\n");
+            return devicesBuilder.toString();
+        }
+
+        @SuppressWarnings("unchecked")
+        public List<DiskDef> getDisks() {
+            return (List<DiskDef>)devices.get(DiskDef.class.toString());
+        }
+
+        @SuppressWarnings("unchecked")
+        public List<InterfaceDef> getInterfaces() {
+            return (List<InterfaceDef>)devices.get(InterfaceDef.class.toString());
+        }
+
+    }
+
+    public static class DiskDef {
+        public enum DeviceType {
+            FLOPPY("floppy"), DISK("disk"), CDROM("cdrom"), LUN("lun");
+            String _type;
+
+            DeviceType(String type) {
+                _type = type;
+            }
+
+            @Override
+            public String toString() {
+                return _type;
+            }
+        }
+
+        enum DiskType {
+            FILE("file"), BLOCK("block"), DIRECTROY("dir"), NETWORK("network");
+            String _diskType;
+
+            DiskType(String type) {
+                _diskType = type;
+            }
+
+            @Override
+            public String toString() {
+                return _diskType;
+            }
+        }
+
+        public enum DiskProtocol {
+            RBD("rbd"), SHEEPDOG("sheepdog"), GLUSTER("gluster");
+            String _diskProtocol;
+
+            DiskProtocol(String protocol) {
+                _diskProtocol = protocol;
+            }
+
+            @Override
+            public String toString() {
+                return _diskProtocol;
+            }
+        }
+
+        public enum DiskBus {
+            IDE("ide"), SCSI("scsi"), VIRTIO("virtio"), XEN("xen"), USB("usb"), UML("uml"), FDC("fdc");
+            String _bus;
+
+            DiskBus(String bus) {
+                _bus = bus;
+            }
+
+            @Override
+            public String toString() {
+                return _bus;
+            }
+        }
+
+        public enum DiskFmtType {
+            RAW("raw"), QCOW2("qcow2");
+            String _fmtType;
+
+            DiskFmtType(String fmt) {
+                _fmtType = fmt;
+            }
+
+            @Override
+            public String toString() {
+                return _fmtType;
+            }
+        }
+
+        public enum DiskCacheMode {
+            NONE("none"), WRITEBACK("writeback"), WRITETHROUGH("writethrough");
+            String _diskCacheMode;
+
+            DiskCacheMode(String cacheMode) {
+                _diskCacheMode = cacheMode;
+            }
+
+            @Override
+            public String toString() {
+                if (_diskCacheMode == null) {
+                    return "NONE";
+                }
+                return _diskCacheMode;
+            }
+        }
+
+        public enum DiscardType {
+            IGNORE("ignore"), UNMAP("unmap");
+            String _discardType;
+            DiscardType(String discardType) {
+                _discardType = discardType;
+            }
+
+            @Override
+            public String toString() {
+                if (_discardType == null) {
+                    return "ignore";
+                }
+                return _discardType;
+            }
+
+        }
+
+        private DeviceType _deviceType; /* floppy, disk, cdrom */
+        private DiskType _diskType;
+        private DiskProtocol _diskProtocol;
+        private String _sourcePath;
+        private String _sourceHost;
+        private int _sourcePort;
+        private String _authUserName;
+        private String _authSecretUUID;
+        private String _diskLabel;
+        private DiskBus _bus;
+        private DiskFmtType _diskFmtType; /* qcow2, raw etc. */
+        private boolean _readonly = false;
+        private boolean _shareable = false;
+        private boolean _deferAttach = false;
+        private Long _bytesReadRate;
+        private Long _bytesReadRateMax;
+        private Long _bytesReadRateMaxLength;
+        private Long _bytesWriteRate;
+        private Long _bytesWriteRateMax;
+        private Long _bytesWriteRateMaxLength;
+        private Long _iopsReadRate;
+        private Long _iopsReadRateMax;
+        private Long _iopsReadRateMaxLength;
+        private Long _iopsWriteRate;
+        private Long _iopsWriteRateMax;
+        private Long _iopsWriteRateMaxLength;
+        private DiskCacheMode _diskCacheMode;
+        private String _serial;
+        private boolean qemuDriver = true;
+        private DiscardType _discard = DiscardType.IGNORE;
+
+        public DiscardType getDiscard() {
+            return _discard;
+        }
+
+        public void setDiscard(DiscardType discard) {
+            this._discard = discard;
+        }
+
+        public void setDeviceType(DeviceType deviceType) {
+            _deviceType = deviceType;
+        }
+
+        public void defFileBasedDisk(String filePath, String diskLabel, DiskBus bus, DiskFmtType diskFmtType) {
+            _diskType = DiskType.FILE;
+            _deviceType = DeviceType.DISK;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = filePath;
+            _diskLabel = diskLabel;
+            _diskFmtType = diskFmtType;
+            _bus = bus;
+
+        }
+
+        /* skip iso labels */
+        private String getDevLabel(int devId, DiskBus bus, boolean forIso) {
+            if (devId < 0) {
+                return "";
+            }
+
+            if (bus == DiskBus.SCSI) {
+                return "sd" + getDevLabelSuffix(devId);
+            } else if (bus == DiskBus.VIRTIO) {
+                return "vd" + getDevLabelSuffix(devId);
+            }
+            if (forIso) {
+                devId --;
+            } else if(devId >= 2) {
+                devId += 2;
+            }
+            return "hd" + getDevLabelSuffix(devId);
+
+        }
+
+        private String getDevLabelSuffix(int deviceIndex) {
+            if (deviceIndex < 0) {
+                return "";
+            }
+
+            int base = 'z' - 'a' + 1;
+            String labelSuffix = "";
+            do {
+                char suffix = (char)('a' + (deviceIndex % base));
+                labelSuffix = suffix + labelSuffix;
+                deviceIndex = (deviceIndex / base) - 1;
+            } while (deviceIndex >= 0);
+
+            return labelSuffix;
+        }
+
+        public void defFileBasedDisk(String filePath, int devId, DiskBus bus, DiskFmtType diskFmtType) {
+
+            _diskType = DiskType.FILE;
+            _deviceType = DeviceType.DISK;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = filePath;
+            _diskLabel = getDevLabel(devId, bus, false);
+            _diskFmtType = diskFmtType;
+            _bus = bus;
+
+        }
+
+        public void defISODisk(String volPath) {
+            _diskType = DiskType.FILE;
+            _deviceType = DeviceType.CDROM;
+            _sourcePath = volPath;
+            _diskLabel = getDevLabel(3, DiskBus.IDE, true);
+            _diskFmtType = DiskFmtType.RAW;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _bus = DiskBus.IDE;
+        }
+
+        public void defISODisk(String volPath, Integer devId) {
+            if (devId == null) {
+                defISODisk(volPath);
+            } else {
+                _diskType = DiskType.FILE;
+                _deviceType = DeviceType.CDROM;
+                _sourcePath = volPath;
+                _diskLabel = getDevLabel(devId, DiskBus.IDE, true);
+                _diskFmtType = DiskFmtType.RAW;
+                _diskCacheMode = DiskCacheMode.NONE;
+                _bus = DiskBus.IDE;
+            }
+        }
+
+        public void defBlockBasedDisk(String diskName, int devId, DiskBus bus) {
+            _diskType = DiskType.BLOCK;
+            _deviceType = DeviceType.DISK;
+            _diskFmtType = DiskFmtType.RAW;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = diskName;
+            _diskLabel = getDevLabel(devId, bus, false);
+            _bus = bus;
+        }
+
+        public void defBlockBasedDisk(String diskName, String diskLabel, DiskBus bus) {
+            _diskType = DiskType.BLOCK;
+            _deviceType = DeviceType.DISK;
+            _diskFmtType = DiskFmtType.RAW;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = diskName;
+            _diskLabel = diskLabel;
+            _bus = bus;
+        }
+
+        public void defNetworkBasedDisk(String diskName, String sourceHost, int sourcePort, String authUserName, String authSecretUUID, int devId, DiskBus bus,
+                DiskProtocol protocol, DiskFmtType diskFmtType) {
+            _diskType = DiskType.NETWORK;
+            _deviceType = DeviceType.DISK;
+            _diskFmtType = diskFmtType;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = diskName;
+            _sourceHost = sourceHost;
+            _sourcePort = sourcePort;
+            _authUserName = authUserName;
+            _authSecretUUID = authSecretUUID;
+            _diskLabel = getDevLabel(devId, bus, false);
+            _bus = bus;
+            _diskProtocol = protocol;
+        }
+
+        public void defNetworkBasedDisk(String diskName, String sourceHost, int sourcePort, String authUserName, String authSecretUUID, String diskLabel, DiskBus bus,
+                DiskProtocol protocol, DiskFmtType diskFmtType) {
+            _diskType = DiskType.NETWORK;
+            _deviceType = DeviceType.DISK;
+            _diskFmtType = diskFmtType;
+            _diskCacheMode = DiskCacheMode.NONE;
+            _sourcePath = diskName;
+            _sourceHost = sourceHost;
+            _sourcePort = sourcePort;
+            _authUserName = authUserName;
+            _authSecretUUID = authSecretUUID;
+            _diskLabel = diskLabel;
+            _bus = bus;
+            _diskProtocol = protocol;
+        }
+
+        public void setReadonly() {
+            _readonly = true;
+        }
+
+        public void setSharable() {
+            _shareable = true;
+        }
+
+        public void setAttachDeferred(boolean deferAttach) {
+            _deferAttach = deferAttach;
+        }
+
+        public boolean isAttachDeferred() {
+            return _deferAttach;
+        }
+
+        public String getDiskPath() {
+            return _sourcePath;
+        }
+
+        public String getDiskLabel() {
+            return _diskLabel;
+        }
+
+        public DiskType getDiskType() {
+            return _diskType;
+        }
+
+        public DeviceType getDeviceType() {
+            return _deviceType;
+        }
+
+        public void setDiskPath(String volPath) {
+            _sourcePath = volPath;
+        }
+
+        public DiskBus getBusType() {
+            return _bus;
+        }
+
+        public DiskFmtType getDiskFormatType() {
+            return _diskFmtType;
+        }
+
+        public void setBytesReadRate(Long bytesReadRate) {
+            _bytesReadRate = bytesReadRate;
+        }
+
+        public void setBytesReadRateMax(Long bytesReadRateMax) {
+            _bytesReadRateMax = bytesReadRateMax;
+        }
+
+        public void  setBytesReadRateMaxLength(Long bytesReadRateLength) {
+            _bytesReadRateMaxLength = bytesReadRateLength;
+        }
+
+        public void setBytesWriteRate(Long bytesWriteRate) {
+            _bytesWriteRate = bytesWriteRate;
+        }
+
+        public void setBytesWriteRateMax(Long bytesWriteRateMax) {
+            _bytesWriteRateMax = bytesWriteRateMax;
+        }
+
+        public void setBytesWriteRateMaxLength(Long bytesWriteRateMaxLength) {
+            _bytesWriteRateMaxLength = bytesWriteRateMaxLength;
+        }
+
+        public void setIopsReadRate(Long iopsReadRate) {
+            _iopsReadRate = iopsReadRate;
+        }
+
+        public void setIopsReadRateMax(Long iopsReadRateMax) {
+            _iopsReadRateMax = iopsReadRateMax;
+        }
+
+        public void setIopsReadRateMaxLength(Long iopsReadRateMaxLength) {
+            _iopsReadRateMaxLength = iopsReadRateMaxLength;
+        }
+
+        public void setIopsWriteRate(Long iopsWriteRate) {
+            _iopsWriteRate = iopsWriteRate;
+        }
+
+        public void setIopsWriteRateMax(Long iopsWriteRateMax) {
+            _iopsWriteRateMax = iopsWriteRateMax;
+        }
+
+        public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) {
+            _iopsWriteRateMaxLength = iopsWriteRateMaxLength;
+        }
+
+        public void setCacheMode(DiskCacheMode cacheMode) {
+            _diskCacheMode = cacheMode;
+        }
+
+        public DiskCacheMode getCacheMode() {
+            return _diskCacheMode;
+        }
+
+        public void setQemuDriver(boolean qemuDriver){
+            this.qemuDriver = qemuDriver;
+        }
+
+        public void setSerial(String serial) {
+            this._serial = serial;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder diskBuilder = new StringBuilder();
+            diskBuilder.append("<disk ");
+            if (_deviceType != null) {
+                diskBuilder.append(" device='" + _deviceType + "'");
+            }
+            diskBuilder.append(" type='" + _diskType + "'");
+            diskBuilder.append(">\n");
+            if(qemuDriver) {
+                diskBuilder.append("<driver name='qemu'" + " type='" + _diskFmtType + "' ");
+
+                if (_deviceType != DeviceType.CDROM) {
+                    diskBuilder.append("cache='" + _diskCacheMode + "' ");
+                }
+
+                if(_discard != null && _discard != DiscardType.IGNORE) {
+                    diskBuilder.append("discard='" + _discard.toString() + "' ");
+                }
+                diskBuilder.append("/>\n");
+            }
+
+            if (_diskType == DiskType.FILE) {
+                diskBuilder.append("<source ");
+                if (_sourcePath != null) {
+                    diskBuilder.append("file='" + _sourcePath + "'");
+                } else if (_deviceType == DeviceType.CDROM) {
+                    diskBuilder.append("file=''");
+                }
+                diskBuilder.append("/>\n");
+            } else if (_diskType == DiskType.BLOCK) {
+                diskBuilder.append("<source");
+                if (_sourcePath != null) {
+                    diskBuilder.append(" dev='" + _sourcePath + "'");
+                }
+                diskBuilder.append("/>\n");
+            } else if (_diskType == DiskType.NETWORK) {
+                diskBuilder.append("<source ");
+                diskBuilder.append(" protocol='" + _diskProtocol + "'");
+                diskBuilder.append(" name='" + _sourcePath + "'");
+                diskBuilder.append(">\n");
+                diskBuilder.append("<host name='");
+                diskBuilder.append(_sourceHost);
+                if (_sourcePort != 0) {
+                    diskBuilder.append("' port='");
+                    diskBuilder.append(_sourcePort);
+                }
+                diskBuilder.append("'/>\n");
+                diskBuilder.append("</source>\n");
+                if (_authUserName != null) {
+                    diskBuilder.append("<auth username='" + _authUserName + "'>\n");
+                    diskBuilder.append("<secret type='ceph' uuid='" + _authSecretUUID + "'/>\n");
+                    diskBuilder.append("</auth>\n");
+                }
+            }
+            diskBuilder.append("<target dev='" + _diskLabel + "'");
+            if (_bus != null) {
+                diskBuilder.append(" bus='" + _bus + "'");
+            }
+            diskBuilder.append("/>\n");
+
+            if (_serial != null && !_serial.isEmpty() && _deviceType != DeviceType.LUN) {
+                diskBuilder.append("<serial>" + _serial + "</serial>");
+            }
+
+            if ((_deviceType != DeviceType.CDROM) &&
+                    (s_libvirtVersion >= 9008) &&
+                    (s_qemuVersion >= 1001000) &&
+                    (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) ||
+                            ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)))) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0
+                diskBuilder.append("<iotune>\n");
+                if ((_bytesReadRate != null) && (_bytesReadRate > 0))
+                    diskBuilder.append("<read_bytes_sec>" + _bytesReadRate + "</read_bytes_sec>\n");
+                if ((_bytesWriteRate != null) && (_bytesWriteRate > 0))
+                    diskBuilder.append("<write_bytes_sec>" + _bytesWriteRate + "</write_bytes_sec>\n");
+                if ((_iopsReadRate != null) && (_iopsReadRate > 0))
+                    diskBuilder.append("<read_iops_sec>" + _iopsReadRate + "</read_iops_sec>\n");
+                if ((_iopsWriteRate != null) && (_iopsWriteRate > 0))
+                    diskBuilder.append("<write_iops_sec>" + _iopsWriteRate + "</write_iops_sec>\n");
+                if (s_qemuVersion >= 2004000) {
+                    if (_bytesReadRateMax != null && _bytesReadRateMax > 0 ) {
+                        diskBuilder.append("<read_bytes_sec_max>" + _bytesReadRateMax + "</read_bytes_sec_max>\n");
+                    }
+                    if (_bytesWriteRateMax != null && _bytesWriteRateMax > 0) {
+                        diskBuilder.append("<write_bytes_sec_max>" + _bytesWriteRateMax + "</write_bytes_sec_max>\n");
+                    }
+                    if (_iopsReadRateMax != null && _iopsReadRateMax > 0)
+                        diskBuilder.append("<read_iops_sec_max>" + _iopsReadRateMax + "</read_iops_sec_max>\n");
+                    if (_iopsWriteRateMax != null && _iopsWriteRateMax > 0)
+                        diskBuilder.append("<write_iops_sec_max>" + _iopsWriteRateMax + "</write_iops_sec_max>\n");
+                }
+                if (s_qemuVersion >= 2006000) {
+                    if (_bytesReadRateMaxLength != null && _bytesReadRateMaxLength > 0) {
+                        diskBuilder.append("<read_bytes_sec_max_length>" + _bytesReadRateMaxLength + "</read_bytes_sec_max_length>\n");
+                    }
+                    if (_bytesWriteRateMaxLength != null && _bytesWriteRateMaxLength > 0) {
+                        diskBuilder.append("<write_bytes_sec_max_length>" + _bytesWriteRateMaxLength + "</write_bytes_sec_max_length>\n");
+                    }
+                    if (_iopsReadRateMaxLength != null && _iopsReadRateMaxLength > 0)
+                        diskBuilder.append("<read_iops_sec_max_length>" + _iopsReadRateMaxLength + "</read_iops_sec_max_length>\n");
+                    if (_iopsWriteRateMaxLength != null && _iopsWriteRateMaxLength > 0)
+                        diskBuilder.append("<write_iops_sec_max_length>" + _iopsWriteRateMaxLength + "</write_iops_sec_max_length>\n");
+                }
+
+                diskBuilder.append("</iotune>\n");
+            }
+
+            diskBuilder.append("</disk>\n");
+            return diskBuilder.toString();
+        }
+    }
+
+    public static class InterfaceDef {
+        enum GuestNetType {
+            BRIDGE("bridge"), DIRECT("direct"), NETWORK("network"), USER("user"), ETHERNET("ethernet"), INTERNAL("internal"), VHOSTUSER("vhostuser");
+            String _type;
+
+            GuestNetType(String type) {
+                _type = type;
+            }
+
+            @Override
+            public String toString() {
+                return _type;
+            }
+        }
+
+        public enum NicModel {
+            E1000("e1000"), VIRTIO("virtio"), RTL8139("rtl8139"), NE2KPCI("ne2k_pci"), VMXNET3("vmxnet3");
+            String _model;
+
+            NicModel(String model) {
+                _model = model;
+            }
+
+            @Override
+            public String toString() {
+                return _model;
+            }
+        }
+
+        enum HostNicType {
+            DIRECT_ATTACHED_WITHOUT_DHCP, DIRECT_ATTACHED_WITH_DHCP, VNET, VLAN;
+        }
+
+        private GuestNetType _netType; /*
+         * bridge, ethernet, network, user,
+         * internal, vhostuser
+         */
+        private HostNicType _hostNetType; /* Only used by agent java code */
+        private String _netSourceMode;
+        private String _sourceName;
+        private String _networkName;
+        private String _macAddr;
+        private String _ipAddr;
+        private String _scriptPath;
+        private NicModel _model;
+        private Integer _networkRateKBps;
+        private String _virtualPortType;
+        private String _virtualPortInterfaceId;
+        private int _vlanTag = -1;
+        private boolean _pxeDisable = false;
+        private boolean _linkStateUp = true;
+        private Integer _slot;
+        private String _dpdkSourcePath;
+        private String _dpdkSourcePort;
+        private String _dpdkExtraLines;
+
+        public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model) {
+            defBridgeNet(brName, targetBrName, macAddr, model, 0);
+        }
+
+        public void defBridgeNet(String brName, String targetBrName, String macAddr, NicModel model, Integer networkRateKBps) {
+            _netType = GuestNetType.BRIDGE;
+            _sourceName = brName;
+            _networkName = targetBrName;
+            _macAddr = macAddr;
+            _model = model;
+            _networkRateKBps = networkRateKBps;
+        }
+
+        public void defDpdkNet(String dpdkSourcePath, String dpdkPort, String macAddress, NicModel model, Integer networkRateKBps, String extra) {
+            _netType = GuestNetType.VHOSTUSER;
+            _dpdkSourcePath = dpdkSourcePath;
+            _dpdkSourcePort = dpdkPort;
+            _macAddr = macAddress;
+            _model = model;
+            _networkRateKBps = networkRateKBps;
+            _dpdkExtraLines = extra;
+        }
+
+        public void defDirectNet(String sourceName, String targetName, String macAddr, NicModel model, String sourceMode) {
+            defDirectNet(sourceName, targetName, macAddr, model, sourceMode, 0);
+        }
+
+        public void defDirectNet(String sourceName, String targetName, String macAddr, NicModel model, String sourceMode, Integer networkRateKBps) {
+            _netType = GuestNetType.DIRECT;
+            _netSourceMode = sourceMode;
+            _sourceName = sourceName;
+            _networkName = targetName;
+            _macAddr = macAddr;
+            _model = model;
+            _networkRateKBps = networkRateKBps;
+        }
+
+        public void defPrivateNet(String networkName, String targetName, String macAddr, NicModel model) {
+            defPrivateNet(networkName, targetName, macAddr, model, 0);
+        }
+
+        public void defPrivateNet(String networkName, String targetName, String macAddr, NicModel model, Integer networkRateKBps) {
+            _netType = GuestNetType.NETWORK;
+            _sourceName = networkName;
+            _networkName = targetName;
+            _macAddr = macAddr;
+            _model = model;
+            _networkRateKBps = networkRateKBps;
+        }
+
+        public void defEthernet(String targetName, String macAddr, NicModel model, String scriptPath) {
+            defEthernet(targetName, macAddr, model, scriptPath, 0);
+        }
+
+        public void defEthernet(String targetName, String macAddr, NicModel model, String scriptPath, Integer networkRateKBps) {
+            _netType = GuestNetType.ETHERNET;
+            _networkName = targetName;
+            _sourceName = targetName;
+            _macAddr = macAddr;
+            _model = model;
+            _scriptPath = scriptPath;
+            _networkRateKBps = networkRateKBps;
+        }
+
+        public void defEthernet(String targetName, String macAddr, NicModel model) {
+            defEthernet(targetName, macAddr, model, null);
+        }
+
+        public void setHostNetType(HostNicType hostNetType) {
+            _hostNetType = hostNetType;
+        }
+
+        public HostNicType getHostNetType() {
+            return _hostNetType;
+        }
+
+        public void setPxeDisable(boolean pxeDisable) {
+            _pxeDisable = pxeDisable;
+        }
+
+        public String getBrName() {
+            return _sourceName;
+        }
+
+        public GuestNetType getNetType() {
+            return _netType;
+        }
+
+        public String getNetSourceMode() {
+            return _netSourceMode;
+        }
+
+        public String getDevName() {
+            return _networkName;
+        }
+
+        public void setDevName(String networkName) {
+            _networkName = networkName;
+        }
+
+        public String getMacAddress() {
+            return _macAddr;
+        }
+
+        public NicModel getModel() {
+            return _model;
+        }
+
+        public void setVirtualPortType(String virtualPortType) {
+            _virtualPortType = virtualPortType;
+        }
+
+        public String getVirtualPortType() {
+            return _virtualPortType;
+        }
+
+        public void setVirtualPortInterfaceId(String virtualPortInterfaceId) {
+            _virtualPortInterfaceId = virtualPortInterfaceId;
+        }
+
+        public String getVirtualPortInterfaceId() {
+            return _virtualPortInterfaceId;
+        }
+
+        public void setVlanTag(int vlanTag) {
+            _vlanTag = vlanTag;
+        }
+
+        public int getVlanTag() {
+            return _vlanTag;
+        }
+
+        public void setSlot(Integer slot) {
+            _slot = slot;
+        }
+
+        public Integer getSlot() {
+            return _slot;
+        }
+
+        public void setLinkStateUp(boolean linkStateUp) {
+            _linkStateUp = linkStateUp;
+        }
+
+        public boolean isLinkStateUp() {
+            return _linkStateUp;
+        }
+
+        public String getDpdkSourcePort() {
+            return _dpdkSourcePort;
+        }
+        public void setDpdkSourcePort(String port) {
+            _dpdkSourcePort = port;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder netBuilder = new StringBuilder();
+            netBuilder.append("<interface type='" + _netType + "'>\n");
+            if (_netType == GuestNetType.BRIDGE) {
+                netBuilder.append("<source bridge='" + _sourceName + "'/>\n");
+            } else if (_netType == GuestNetType.NETWORK) {
+                netBuilder.append("<source network='" + _sourceName + "'/>\n");
+            } else if (_netType == GuestNetType.DIRECT) {
+                netBuilder.append("<source dev='" + _sourceName + "' mode='" + _netSourceMode + "'/>\n");
+            } else if (_netType == GuestNetType.VHOSTUSER) {
+                netBuilder.append("<source type='unix' path='"+ _dpdkSourcePath + _dpdkSourcePort + "' mode='client'/>\n");
+            }
+            if (_networkName != null) {
+                netBuilder.append("<target dev='" + _networkName + "'/>\n");
+            }
+            if (_macAddr != null) {
+                netBuilder.append("<mac address='" + _macAddr + "'/>\n");
+            }
+            if (_model != null) {
+                netBuilder.append("<model type='" + _model + "'/>\n");
+            }
+            if ((s_libvirtVersion >= 9004) && (_networkRateKBps > 0)) { // supported from libvirt 0.9.4
+                netBuilder.append("<bandwidth>\n");
+                netBuilder.append("<inbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
+                netBuilder.append("<outbound average='" + _networkRateKBps + "' peak='" + _networkRateKBps + "'/>\n");
+                netBuilder.append("</bandwidth>\n");
+            }
+            if (_scriptPath != null) {
+                netBuilder.append("<script path='" + _scriptPath + "'/>\n");
+            }
+            if (_pxeDisable) {
+                netBuilder.append("<rom bar='off' file=''/>");
+            }
+            if (_virtualPortType != null) {
+                netBuilder.append("<virtualport type='" + _virtualPortType + "'>\n");
+                if (_virtualPortInterfaceId != null) {
+                    netBuilder.append("<parameters interfaceid='" + _virtualPortInterfaceId + "'/>\n");
+                }
+                netBuilder.append("</virtualport>\n");
+            }
+            if (_vlanTag > 0 && _vlanTag < 4095) {
+                netBuilder.append("<vlan trunk='no'>\n<tag id='" + _vlanTag + "'/>\n</vlan>");
+            }
+
+            if (StringUtils.isNotBlank(_dpdkExtraLines)) {
+                netBuilder.append(_dpdkExtraLines);
+            }
+
+            if (_netType != GuestNetType.VHOSTUSER) {
+                netBuilder.append("<link state='" + (_linkStateUp ? "up" : "down") +"'/>\n");
+            }
+
+            if (_slot  != null) {
+                netBuilder.append(String.format("<address type='pci' domain='0x0000' bus='0x00' slot='0x%02x' function='0x0'/>\n", _slot));
+            }
+            netBuilder.append("</interface>\n");
+            return netBuilder.toString();
+        }
+    }
+
+    public static class ConsoleDef {
+        private final String _ttyPath;
+        private final String _type;
+        private final String _source;
+        private short _port = -1;
+
+        public ConsoleDef(String type, String path, String source, short port) {
+            _type = type;
+            _ttyPath = path;
+            _source = source;
+            _port = port;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder consoleBuilder = new StringBuilder();
+            consoleBuilder.append("<console ");
+            consoleBuilder.append("type='" + _type + "'");
+            if (_ttyPath != null) {
+                consoleBuilder.append("tty='" + _ttyPath + "'");
+            }
+            consoleBuilder.append(">\n");
+            if (_source != null) {
+                consoleBuilder.append("<source path='" + _source + "'/>\n");
+            }
+            if (_port != -1) {
+                consoleBuilder.append("<target port='" + _port + "'/>\n");
+            }
+            consoleBuilder.append("</console>\n");
+            return consoleBuilder.toString();
+        }
+    }
+
+    public static class CpuTuneDef {
+        private int _shares = 0;
+        private int quota = 0;
+        private int period = 0;
+        static final int DEFAULT_PERIOD = 10000;
+        static final int MIN_QUOTA = 1000;
+        static final int MAX_PERIOD = 1000000;
+
+        public void setShares(int shares) {
+            _shares = shares;
+        }
+
+        public int getShares() {
+            return _shares;
+        }
+
+        public int getQuota() {
+            return quota;
+        }
+
+        public void setQuota(int quota) {
+            this.quota = quota;
+        }
+
+        public int getPeriod() {
+            return period;
+        }
+
+        public void setPeriod(int period) {
+            this.period = period;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder cpuTuneBuilder = new StringBuilder();
+            cpuTuneBuilder.append("<cputune>\n");
+            if (_shares > 0) {
+                cpuTuneBuilder.append("<shares>" + _shares + "</shares>\n");
+            }
+            if (quota > 0) {
+                cpuTuneBuilder.append("<quota>" + quota + "</quota>\n");
+            }
+            if (period > 0) {
+                cpuTuneBuilder.append("<period>" + period + "</period>\n");
+            }
+            cpuTuneBuilder.append("</cputune>\n");
+            return cpuTuneBuilder.toString();
+        }
+    }
+
+    public static class CpuModeDef {
+        private String _mode;
+        private String _model;
+        private List<String> _features;
+        private int _coresPerSocket = -1;
+        private int _sockets = -1;
+
+        public void setMode(String mode) {
+            _mode = mode;
+        }
+
+        public void setFeatures(List<String> features) {
+            if (features != null) {
+                _features = features;
+            }
+        }
+
+        public void setModel(String model) {
+            _model = model;
+        }
+
+        public void setTopology(int coresPerSocket, int sockets) {
+            _coresPerSocket = coresPerSocket;
+            _sockets = sockets;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder modeBuilder = new StringBuilder();
+
+            // start cpu def, adding mode, model
+            if ("custom".equalsIgnoreCase(_mode) && _model != null){
+                modeBuilder.append("<cpu mode='custom' match='exact'><model fallback='allow'>" + _model + "</model>");
+            } else if ("host-model".equals(_mode)) {
+                modeBuilder.append("<cpu mode='host-model'><model fallback='allow'></model>");
+            } else if ("host-passthrough".equals(_mode)) {
+                modeBuilder.append("<cpu mode='host-passthrough'>");
+            } else {
+                modeBuilder.append("<cpu>");
+            }
+
+            if (_features != null) {
+                for (String feature : _features) {
+                    modeBuilder.append("<feature policy='require' name='" + feature + "'/>");
+                }
+            }
+
+            // add topology
+            if (_sockets > 0 && _coresPerSocket > 0) {
+                modeBuilder.append("<topology sockets='" + _sockets + "' cores='" + _coresPerSocket + "' threads='1' />");
+            }
+
+            // close cpu def
+            modeBuilder.append("</cpu>");
+            return modeBuilder.toString();
+        }
+    }
+
+    public static class SerialDef {
+        private final String _type;
+        private final String _source;
+        private short _port = -1;
+
+        public SerialDef(String type, String source, short port) {
+            _type = type;
+            _source = source;
+            _port = port;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder serialBuidler = new StringBuilder();
+            serialBuidler.append("<serial type='" + _type + "'>\n");
+            if (_source != null) {
+                serialBuidler.append("<source path='" + _source + "'/>\n");
+            }
+            if (_port != -1) {
+                serialBuidler.append("<target port='" + _port + "'/>\n");
+            }
+            serialBuidler.append("</serial>\n");
+            return serialBuidler.toString();
+        }
+    }
+
+    public static class VideoDef {
+        private String _videoModel;
+        private int _videoRam;
+
+        public VideoDef(String videoModel, int videoRam) {
+            _videoModel = videoModel;
+            _videoRam = videoRam;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder videoBuilder = new StringBuilder();
+            if (_videoModel != null && !_videoModel.isEmpty() && _videoRam != 0){
+                videoBuilder.append("<video>\n");
+                videoBuilder.append("<model type='" + _videoModel + "' vram='" + _videoRam + "'/>\n");
+                videoBuilder.append("</video>\n");
+                return videoBuilder.toString();
+            }
+            return "";
+        }
+    }
+
+    public final static class ChannelDef {
+        enum ChannelType {
+            UNIX("unix"), SERIAL("serial");
+            String type;
+
+            ChannelType(String type) {
+                this.type = type;
+            }
+
+            @Override
+            public String toString() {
+                return this.type;
+            }
+        }
+
+        enum ChannelState {
+            DISCONNECTED("disconnected"), CONNECTED("connected");
+            String type;
+
+            ChannelState(String type) {
+                this.type = type;
+            }
+
+            @Override
+            public String toString() {
+                return type;
+            }
+        }
+
+        private final String name;
+        private File path = new File("");
+        private final ChannelType type;
+        private ChannelState state;
+
+        public ChannelDef(String name, ChannelType type) {
+            this.name = name;
+            this.type = type;
+        }
+
+        public ChannelDef(String name, ChannelType type, File path) {
+            this.name = name;
+            this.path = path;
+            this.type = type;
+        }
+
+        public ChannelDef(String name, ChannelType type, ChannelState state) {
+            this.name = name;
+            this.state = state;
+            this.type = type;
+        }
+
+        public ChannelDef(String name, ChannelType type, ChannelState state, File path) {
+            this.name = name;
+            this.path = path;
+            this.state = state;
+            this.type = type;
+        }
+
+        public ChannelType getChannelType() {
+            return type;
+        }
+
+        public ChannelState getChannelState() {
+            return state;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public File getPath() {
+            return path;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder virtioSerialBuilder = new StringBuilder();
+            virtioSerialBuilder.append("<channel type='" + type.toString() + "'>\n");
+            if (path == null) {
+                virtioSerialBuilder.append("<source mode='bind'/>\n");
+            } else {
+                virtioSerialBuilder.append("<source mode='bind' path='" + path.toString() + "'/>\n");
+            }
+            virtioSerialBuilder.append("<address type='virtio-serial'/>\n");
+            if (state == null) {
+                virtioSerialBuilder.append("<target type='virtio' name='" + name + "'/>\n");
+            } else {
+                virtioSerialBuilder.append("<target type='virtio' name='" + name + "' state='" + state.toString() + "'/>\n");
+            }
+            virtioSerialBuilder.append("</channel>\n");
+            return virtioSerialBuilder.toString();
+        }
+    }
+
+    public static class GraphicDef {
+        private final String _type;
+        private short _port = -2;
+        private boolean _autoPort = false;
+        private final String _listenAddr;
+        private final String _passwd;
+        private final String _keyMap;
+
+        public GraphicDef(String type, short port, boolean autoPort, String listenAddr, String passwd, String keyMap) {
+            _type = type;
+            _port = port;
+            _autoPort = autoPort;
+            _listenAddr = listenAddr;
+            _passwd = StringEscapeUtils.escapeXml(passwd);
+            _keyMap = keyMap;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder graphicBuilder = new StringBuilder();
+            graphicBuilder.append("<graphics type='" + _type + "'");
+            if (_autoPort) {
+                graphicBuilder.append(" autoport='yes'");
+            } else if (_port != -2) {
+                graphicBuilder.append(" port='" + _port + "'");
+            }
+            if (_listenAddr != null) {
+                graphicBuilder.append(" listen='" + _listenAddr + "'");
+            } else {
+                graphicBuilder.append(" listen=''");
+            }
+            if (_passwd != null) {
+                graphicBuilder.append(" passwd='" + _passwd + "'");
+            } else if (_keyMap != null) {
+                graphicBuilder.append(" _keymap='" + _keyMap + "'");
+            }
+            graphicBuilder.append("/>\n");
+            return graphicBuilder.toString();
+        }
+    }
+
+    public static class SCSIDef {
+        private short index = 0;
+        private int domain = 0;
+        private int bus = 0;
+        private int slot = 9;
+        private int function = 0;
+        private int queues = 0;
+
+        public SCSIDef(short index, int domain, int bus, int slot, int function, int queues) {
+            this.index = index;
+            this.domain = domain;
+            this.bus = bus;
+            this.slot = slot;
+            this.function = function;
+            this.queues = queues;
+        }
+
+        public SCSIDef() {
+
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder scsiBuilder = new StringBuilder();
+
+            scsiBuilder.append(String.format("<controller type='scsi' index='%d' model='virtio-scsi'>\n", this.index));
+            scsiBuilder.append(String.format("<address type='pci' domain='0x%04X' bus='0x%02X' slot='0x%02X' function='0x%01X'/>\n",
+                    this.domain, this.bus, this.slot, this.function ) );
+            if (this.queues > 0) {
+                scsiBuilder.append(String.format("<driver queues='%d'/>\n", this.queues));
+            }
+            scsiBuilder.append("</controller>\n");
+            return scsiBuilder.toString();
+        }
+    }
+
+    public static class InputDef {
+        private final String _type; /* tablet, mouse */
+        private final String _bus; /* ps2, usb, xen */
+
+        public InputDef(String type, String bus) {
+            _type = type;
+            _bus = bus;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder inputBuilder = new StringBuilder();
+            inputBuilder.append("<input type='" + _type + "'");
+            if (_bus != null) {
+                inputBuilder.append(" bus='" + _bus + "'");
+            }
+            inputBuilder.append("/>\n");
+            return inputBuilder.toString();
+        }
+    }
+
+    public static class FilesystemDef {
+        private final String _sourcePath;
+        private final String _targetPath;
+
+        public FilesystemDef(String sourcePath, String targetPath) {
+            _sourcePath = sourcePath;
+            _targetPath = targetPath;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder fsBuilder = new StringBuilder();
+            fsBuilder.append("<filesystem type='mount'>\n");
+            fsBuilder.append("  <source dir='" + _sourcePath + "'/>\n");
+            fsBuilder.append("  <target dir='" + _targetPath + "'/>\n");
+            fsBuilder.append("</filesystem>\n");
+            return fsBuilder.toString();
+        }
+    }
+
+    public static class MetadataDef {
+        Map<String, Object> customNodes = new HashMap<>();
+
+        public <T> T getMetadataNode(Class<T> fieldClass) {
+            T field = (T) customNodes.get(fieldClass.getName());
+            if (field == null) {
+                try {
+                    field = fieldClass.newInstance();
+                    customNodes.put(field.getClass().getName(), field);
+                } catch (InstantiationException | IllegalAccessException e) {
+                    s_logger.debug("No default constructor available in class " + fieldClass.getName() + ", ignoring exception", e);
+                }
+            }
+            return field;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder fsBuilder = new StringBuilder();
+            fsBuilder.append("<metadata>\n");
+            for (Object field : customNodes.values()) {
+                fsBuilder.append(field.toString());
+            }
+            fsBuilder.append("</metadata>\n");
+            return fsBuilder.toString();
+        }
+    }
+
+    public static class NuageExtensionDef {
+        private Map<String, String> addresses = Maps.newHashMap();
+
+        public void addNuageExtension(String macAddress, String vrIp) {
+            addresses.put(macAddress, vrIp);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder fsBuilder = new StringBuilder();
+            fsBuilder.append("<nuage-extension xmlns='nuagenetworks.net/nuage/cna'>\n");
+            for (Map.Entry<String, String> address : addresses.entrySet()) {
+                fsBuilder.append("  <interface mac='")
+                         .append(address.getKey())
+                         .append("' vsp-vr-ip='")
+                         .append(address.getValue())
+                         .append("'></interface>\n");
+            }
+            return fsBuilder.append("</nuage-extension>\n").toString();
+        }
+    }
+
+    public static class RngDef {
+        enum RngModel {
+            VIRTIO("virtio");
+            String model;
+
+            RngModel(String model) {
+                this.model = model;
+            }
+
+            @Override
+            public String toString() {
+                return model;
+            }
+        }
+
+        enum RngBackendModel {
+            RANDOM("random"), EGD("egd");
+            String model;
+
+            RngBackendModel(String model) {
+                this.model = model;
+            }
+
+            @Override
+            public String toString() {
+                return model;
+            }
+        }
+
+        private String path = "/dev/random";
+        private RngModel rngModel = RngModel.VIRTIO;
+        private RngBackendModel rngBackendModel = RngBackendModel.RANDOM;
+        private int rngRateBytes = 2048;
+        private int rngRatePeriod = 1000;
+
+        public RngDef(String path) {
+            this.path = path;
+        }
+
+        public RngDef(String path, int rngRateBytes, int rngRatePeriod) {
+            this.path = path;
+            this.rngRateBytes = rngRateBytes;
+            this.rngRatePeriod = rngRatePeriod;
+        }
+
+        public RngDef(RngModel rngModel) {
+            this.rngModel = rngModel;
+        }
+
+        public RngDef(RngBackendModel rngBackendModel) {
+            this.rngBackendModel = rngBackendModel;
+        }
+
+        public RngDef(String path, RngBackendModel rngBackendModel) {
+            this.path = path;
+            this.rngBackendModel = rngBackendModel;
+        }
+
+        public RngDef(String path, RngBackendModel rngBackendModel, int rngRateBytes, int rngRatePeriod) {
+            this.path = path;
+            this.rngBackendModel = rngBackendModel;
+            this.rngRateBytes = rngRateBytes;
+            this.rngRatePeriod = rngRatePeriod;
+        }
+
+        public RngDef(String path, RngModel rngModel) {
+            this.path = path;
+            this.rngModel = rngModel;
+        }
+
+        public String getPath() {
+           return path;
+        }
+
+        public RngBackendModel getRngBackendModel() {
+            return rngBackendModel;
+        }
+
+        public RngModel getRngModel() {
+            return rngModel;
+        }
+
+        public int getRngRateBytes() {
+            return rngRateBytes;
+        }
+
+        public int getRngRatePeriod() {
+            return rngRatePeriod;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder rngBuilder = new StringBuilder();
+            rngBuilder.append("<rng model='" + rngModel + "'>\n");
+            rngBuilder.append("<rate period='" + rngRatePeriod + "' bytes='" + rngRateBytes + "' />\n");
+            rngBuilder.append("<backend model='" + rngBackendModel + "'>" + path + "</backend>");
+            rngBuilder.append("</rng>\n");
+            return rngBuilder.toString();
+        }
+    }
+
+    public static class WatchDogDef {
+        enum WatchDogModel {
+            I6300ESB("i6300esb"), IB700("ib700"), DIAG288("diag288");
+            String model;
+
+            WatchDogModel(String model) {
+                this.model = model;
+            }
+
+            @Override
+            public String toString() {
+                return model;
+            }
+        }
+
+        enum WatchDogAction {
+            RESET("reset"), SHUTDOWN("shutdown"), POWEROFF("poweroff"), PAUSE("pause"), NONE("none"), DUMP("dump");
+            String action;
+
+            WatchDogAction(String action) {
+                this.action = action;
+            }
+
+            @Override
+            public String toString() {
+                return action;
+            }
+        }
+
+        WatchDogModel model = WatchDogModel.I6300ESB;
+        WatchDogAction action = WatchDogAction.NONE;
+
+        public WatchDogDef(WatchDogAction action) {
+            this.action = action;
+        }
+
+        public WatchDogDef(WatchDogModel model) {
+            this.model = model;
+        }
+
+        public WatchDogDef(WatchDogAction action, WatchDogModel model) {
+            this.action = action;
+            this.model = model;
+        }
+
+        public WatchDogAction getAction() {
+            return action;
+        }
+
+        public WatchDogModel getModel() {
+            return model;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder wacthDogBuilder = new StringBuilder();
+            wacthDogBuilder.append("<watchdog model='" + model + "' action='" + action + "'/>\n");
+            return wacthDogBuilder.toString();
+        }
+    }
+
+    public void setHvsType(String hvs) {
+        _hvsType = hvs;
+    }
+
+    public String getHvsType() {
+        return _hvsType;
+    }
+
+    public static void setGlobalLibvirtVersion(long libvirtVersion) {
+        s_libvirtVersion = libvirtVersion;
+    }
+
+    public void setLibvirtVersion(long libvirtVersion) {
+        setGlobalLibvirtVersion(libvirtVersion);
+    }
+
+    public static void setGlobalQemuVersion(long qemuVersion) {
+        s_qemuVersion = qemuVersion;
+    }
+
+    public void setQemuVersion(long qemuVersion) {
+        setGlobalQemuVersion(qemuVersion);
+    }
+
+    public void setDomainName(String domainName) {
+        _domName = domainName;
+    }
+
+    public void setDomUUID(String uuid) {
+        _domUUID = uuid;
+    }
+
+    public void setDomDescription(String desc) {
+        _desc = desc;
+    }
+
+    public String getGuestOSType() {
+        return _desc;
+    }
+
+    public void setPlatformEmulator(String platformEmulator) {
+        _platformEmulator = platformEmulator;
+    }
+
+    public String getPlatformEmulator() {
+        return _platformEmulator;
+    }
+
+    public void addComp(Object comp) {
+        components.put(comp.getClass().toString(), comp);
+    }
+
+    public DevicesDef getDevices() {
+        Object o = components.get(DevicesDef.class.toString());
+        if (o != null) {
+            return (DevicesDef)o;
+        }
+        return null;
+    }
+
+    public MetadataDef getMetaData() {
+        MetadataDef o = (MetadataDef) components.get(MetadataDef.class.toString());
+        if (o == null) {
+            o = new MetadataDef();
+            addComp(o);
+        }
+        return o;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder vmBuilder = new StringBuilder();
+        vmBuilder.append("<domain type='" + _hvsType + "'>\n");
+        vmBuilder.append("<name>" + _domName + "</name>\n");
+        if (_domUUID != null) {
+            vmBuilder.append("<uuid>" + _domUUID + "</uuid>\n");
+        }
+        if (_desc != null) {
+            vmBuilder.append("<description>" + _desc + "</description>\n");
+        }
+        for (Object o : components.values()) {
+            vmBuilder.append(o.toString());
+        }
+        vmBuilder.append("</domain>\n");
+        return vmBuilder.toString();
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtXMLParser.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java
new file mode 100644
index 0000000..51dbd92
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import java.util.concurrent.Callable;
+
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.LibvirtException;
+
+public class MigrateKVMAsync implements Callable<Domain> {
+
+    private final LibvirtComputingResource libvirtComputingResource;
+
+    private Domain dm = null;
+    private Connect dconn = null;
+    private String dxml = "";
+    private String vmName = "";
+    private String destIp = "";
+    private boolean migrateStorage;
+    private boolean autoConvergence;
+
+    /**
+     * Do not pause the domain during migration. The domain's memory will be transferred to the destination host while the domain is running. The migration may never converge if the domain is changing its memory faster then it can be transferred. The domain can be manually paused anytime during migration using virDomainSuspend.
+     * @value 1
+     * @see Libvirt <a href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateFlags">virDomainMigrateFlags</a> documentation
+     */
+    private static final long VIR_MIGRATE_LIVE = 1L;
+    /**
+     * Migrate full disk images in addition to domain's memory. By default only non-shared non-readonly disk images are transferred. The VIR_MIGRATE_PARAM_MIGRATE_DISKS parameter can be used to specify which disks should be migrated. This flag and VIR_MIGRATE_NON_SHARED_INC are mutually exclusive.
+     * @value 64
+     * @see Libvirt <a href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateFlags">virDomainMigrateFlags</a> documentation
+     */
+    private static final long VIR_MIGRATE_NON_SHARED_DISK = 64L;
+    /**
+     * Compress migration data. The compression methods can be specified using VIR_MIGRATE_PARAM_COMPRESSION. A hypervisor default method will be used if this parameter is omitted. Individual compression methods can be tuned via their specific VIR_MIGRATE_PARAM_COMPRESSION_* parameters.
+     * @value 2048
+     * @see Libvirt <a href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateFlags">virDomainMigrateFlags</a> documentation
+     */
+    private static final long VIR_MIGRATE_COMPRESSED = 2048L;
+    /**
+     * Enable algorithms that ensure a live migration will eventually converge. This usually means the domain will be slowed down to make sure it does not change its memory faster than a hypervisor can transfer the changed memory to the destination host. VIR_MIGRATE_PARAM_AUTO_CONVERGE_* parameters can be used to tune the algorithm.
+     * @value 8192
+     * @see Libvirt <a href="https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrateFlags">virDomainMigrateFlags</a> documentation
+     */
+    private static final long VIR_MIGRATE_AUTO_CONVERGE = 8192L;
+
+    /**
+     *  Libvirt 1.0.3 supports compression flag for migration.
+     */
+    private static final int LIBVIRT_VERSION_SUPPORTS_MIGRATE_COMPRESSED = 1000003;
+
+    public MigrateKVMAsync(final LibvirtComputingResource libvirtComputingResource, final Domain dm, final Connect dconn, final String dxml,
+                           final boolean migrateStorage, final boolean autoConvergence, final String vmName, final String destIp) {
+        this.libvirtComputingResource = libvirtComputingResource;
+
+        this.dm = dm;
+        this.dconn = dconn;
+        this.dxml = dxml;
+        this.migrateStorage = migrateStorage;
+        this.autoConvergence = autoConvergence;
+        this.vmName = vmName;
+        this.destIp = destIp;
+    }
+
+    @Override
+    public Domain call() throws LibvirtException {
+        long flags = VIR_MIGRATE_LIVE;
+
+        if (dconn.getLibVirVersion() >= LIBVIRT_VERSION_SUPPORTS_MIGRATE_COMPRESSED) {
+            flags += VIR_MIGRATE_COMPRESSED;
+        }
+
+        if (migrateStorage) {
+            flags += VIR_MIGRATE_NON_SHARED_DISK;
+        }
+
+        if (autoConvergence && dconn.getLibVirVersion() >= 1002003) {
+            flags += VIR_MIGRATE_AUTO_CONVERGE;
+        }
+
+        return dm.migrate(dconn, flags, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed());
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
new file mode 100644
index 0000000..ea4fd4a
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java
@@ -0,0 +1,287 @@
+/*
+ * 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;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.network.Networks;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+public class OvsVifDriver extends VifDriverBase {
+    private static final Logger s_logger = Logger.getLogger(OvsVifDriver.class);
+    private int _timeout;
+
+    protected static final String DPDK_PORT_PREFIX = "csdpdk-";
+
+    @Override
+    public void configure(Map<String, Object> params) throws ConfigurationException {
+        super.configure(params);
+
+        getPifs();
+
+        String networkScriptsDir = (String)params.get("network.scripts.dir");
+        if (networkScriptsDir == null) {
+            networkScriptsDir = "scripts/vm/network/vnet";
+        }
+
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
+    }
+
+    public void getPifs() {
+        final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'");
+        s_logger.debug("cmdout was " + cmdout);
+        final List<String> bridges = Arrays.asList(cmdout.split("%"));
+        for (final String bridge : bridges) {
+            s_logger.debug("looking for pif for bridge " + bridge);
+            // String pif = getOvsPif(bridge);
+            // Not really interested in the pif name at this point for ovs
+            // bridges
+            final String pif = bridge;
+            if (_libvirtComputingResource.isPublicBridge(bridge)) {
+                _pifs.put("public", pif);
+            }
+            if (_libvirtComputingResource.isGuestBridge(bridge)) {
+                _pifs.put("private", pif);
+            }
+            _pifs.put(bridge, pif);
+        }
+        s_logger.debug("done looking for pifs, no more bridges");
+    }
+
+    /**
+     * Get the latest DPDK port number created on a DPDK enabled host
+     */
+    protected int getDpdkLatestPortNumberUsed() {
+        s_logger.debug("Checking the last DPDK port created");
+        String cmd = "ovs-vsctl show | grep Port | grep " + DPDK_PORT_PREFIX + " | " +
+                "awk '{ print $2 }' | sort -rV | head -1";
+        String port = Script.runSimpleBashScript(cmd);
+        int portNumber = 0;
+        if (StringUtils.isNotBlank(port)) {
+            String unquotedPort = port.replace("\"", "");
+            String dpdkPortNumber = unquotedPort.split(DPDK_PORT_PREFIX)[1];
+            portNumber = Integer.valueOf(dpdkPortNumber);
+        }
+        return portNumber;
+    }
+
+    /**
+     * Get the next DPDK port name to be created
+     */
+    protected String getNextDpdkPort() {
+        int portNumber = getDpdkLatestPortNumberUsed();
+        return DPDK_PORT_PREFIX + String.valueOf(portNumber + 1);
+    }
+
+    /**
+     * Add OVS port (if it does not exist) to bridge with DPDK support
+     */
+    protected void addDpdkPort(String bridgeName, String port, String vlan) {
+        String cmd = String.format("ovs-vsctl add-port %s %s " +
+                "vlan_mode=access tag=%s " +
+                "-- set Interface %s type=dpdkvhostuser", bridgeName, port, vlan, port);
+        s_logger.debug("DPDK property enabled, executing: " + cmd);
+        Script.runSimpleBashScript(cmd);
+    }
+
+    /**
+     * Check for additional extra 'dpdk-interface' configurations, return them appended
+     */
+    private String getExtraDpdkProperties(Map<String, String> extraConfig) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (String key : extraConfig.keySet()) {
+            if (key.startsWith(LibvirtComputingResource.DPDK_INTERFACE_PREFIX)) {
+                stringBuilder.append(extraConfig.get(key));
+            }
+        }
+        return stringBuilder.toString();
+    }
+
+    @Override
+    public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
+        s_logger.debug("plugging nic=" + nic);
+
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+        if (!_libvirtComputingResource.dpdkSupport || nic.isDpdkDisabled()) {
+            // Let libvirt handle OVS ports creation when DPDK property is disabled or when it is enabled but disabled for the nic
+            // For DPDK support, libvirt does not handle ports creation, invoke 'addDpdkPort' method
+            intf.setVirtualPortType("openvswitch");
+        }
+
+        String vlanId = null;
+        String logicalSwitchUuid = null;
+        if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
+            vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
+            logicalSwitchUuid = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+        } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
+            // TODO consider moving some of this functionality from NetUtils to Networks....
+            vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
+        }
+        String trafficLabel = nic.getName();
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+            if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) &&
+                    !vlanId.equalsIgnoreCase("untagged")) {
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    if (_libvirtComputingResource.dpdkSupport && !nic.isDpdkDisabled()) {
+                        s_logger.debug("DPDK support enabled: configuring per traffic label " + trafficLabel);
+                        if (StringUtils.isBlank(_libvirtComputingResource.dpdkOvsPath)) {
+                            throw new CloudRuntimeException("DPDK is enabled on the host but no OVS path has been provided");
+                        }
+                        String port = getNextDpdkPort();
+                        addDpdkPort(_pifs.get(trafficLabel), port, vlanId);
+                        intf.defDpdkNet(_libvirtComputingResource.dpdkOvsPath, port, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), 0, getExtraDpdkProperties(extraConfig));
+                    } else {
+                        s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
+                        intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                        intf.setVlanTag(Integer.parseInt(vlanId));
+                    }
+                } else {
+                    intf.defBridgeNet(_pifs.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                    intf.setVlanTag(Integer.parseInt(vlanId));
+                }
+            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch || nic.getBroadcastType() == Networks.BroadcastDomainType.OpenDaylight) {
+                s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + logicalSwitchUuid);
+                intf.setVirtualPortInterfaceId(nic.getUuid());
+                String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private");
+                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) {
+                String vnetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
+                String brName = "OVSTunnel" + vnetId;
+                s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + brName);
+                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vsp) {
+                intf.setVirtualPortInterfaceId(nic.getUuid());
+                String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private");
+                intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            } else {
+                intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            }
+        } else if (nic.getType() == Networks.TrafficType.Control) {
+            /* Make sure the network is still there */
+            createControlNetwork(_bridges.get("linklocal"));
+            intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
+            if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) {
+                if (trafficLabel != null && !trafficLabel.isEmpty()) {
+                    s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel);
+                    intf.defBridgeNet(_pifs.get(trafficLabel), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                    intf.setVlanTag(Integer.parseInt(vlanId));
+                } else {
+                    intf.defBridgeNet(_pifs.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+                    intf.setVlanTag(Integer.parseInt(vlanId));
+                }
+            } else {
+                intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
+            }
+        } else if (nic.getType() == Networks.TrafficType.Management) {
+            intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        } else if (nic.getType() == Networks.TrafficType.Storage) {
+            String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
+            intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
+        }
+        return intf;
+    }
+
+    @Override
+    public void unplug(InterfaceDef iface) {
+        // Libvirt apparently takes care of this, see BridgeVifDriver unplug
+        if (_libvirtComputingResource.dpdkSupport) {
+            // If DPDK is enabled, we'll need to cleanup the port as libvirt won't
+            String dpdkPort = iface.getDpdkSourcePort();
+            String cmd = String.format("ovs-vsctl del-port %s", dpdkPort);
+            s_logger.debug("Removing DPDK port: " + dpdkPort);
+            Script.runSimpleBashScript(cmd);
+        }
+    }
+
+
+    @Override
+    public void attach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("ovs-vsctl add-port " + iface.getBrName() + " " + iface.getDevName());
+    }
+
+    @Override
+    public void detach(LibvirtVMDef.InterfaceDef iface) {
+        Script.runSimpleBashScript("ovs-vsctl port-to-br " + iface.getDevName() + " && ovs-vsctl del-port " + iface.getBrName() + " " + iface.getDevName());
+    }
+
+    private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
+        Script command = new Script("/bin/bash", _timeout);
+        command.add("-c");
+        command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        boolean foundLinkLocalBr = false;
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                String[] tokens = line.split(" ");
+                if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
+                    Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
+                } else {
+                    foundLinkLocalBr = true;
+                }
+            }
+        }
+        if (!foundLinkLocalBr) {
+            Script.runSimpleBashScript("ip address add 169.254.0.1/16 dev " + linkLocalBr + ";" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
+                    NetUtils.getLinkLocalGateway());
+        }
+    }
+
+    @Override
+    public void createControlNetwork(String privBrName) {
+        deleteExitingLinkLocalRouteTable(privBrName);
+        if (!isExistingBridge(privBrName)) {
+            Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add 169.254.0.1/16 dev " + privBrName, _timeout);
+        }
+    }
+
+    @Override
+    public boolean isExistingBridge(String bridgeName) {
+        Script command = new Script("/bin/sh", _timeout);
+        command.add("-c");
+        command.add("ovs-vsctl br-exists " + bridgeName);
+        String result = command.execute(null);
+        if ("0".equals(result)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriver.java
new file mode 100644
index 0000000..1016fcc
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriver.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+
+public interface VifDriver {
+
+    public void configure(Map<String, Object> params) throws ConfigurationException;
+
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException;
+
+    public void unplug(LibvirtVMDef.InterfaceDef iface);
+
+    void attach(LibvirtVMDef.InterfaceDef iface);
+
+    void detach(LibvirtVMDef.InterfaceDef iface);
+
+    void createControlNetwork(String privBrName);
+
+    boolean isExistingBridge(String bridgeName);
+
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriverBase.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
new file mode 100644
index 0000000..95e38f0
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/VifDriverBase.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+
+public abstract class VifDriverBase implements VifDriver {
+
+    protected LibvirtComputingResource _libvirtComputingResource;
+    protected Map<String, String> _pifs;
+    protected Map<String, String> _bridges;
+
+    @Override
+    public void configure(Map<String, Object> params) throws ConfigurationException {
+        _libvirtComputingResource = (LibvirtComputingResource)params.get("libvirt.computing.resource");
+        _bridges = (Map<String, String>)params.get("libvirt.host.bridges");
+        _pifs = (Map<String, String>)params.get("libvirt.host.pifs");
+    }
+
+    @Override
+    public abstract LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException;
+
+    @Override
+    public abstract void unplug(LibvirtVMDef.InterfaceDef iface);
+
+    protected LibvirtVMDef.InterfaceDef.NicModel getGuestNicModel(String platformEmulator, String nicAdapter) {
+        // if nicAdapter is found in ENUM, use it. Otherwise, match guest OS type as before
+        if (nicAdapter != null && !nicAdapter.isEmpty()) {
+            for (LibvirtVMDef.InterfaceDef.NicModel model : LibvirtVMDef.InterfaceDef.NicModel.values()) {
+                if (model.toString().equalsIgnoreCase(nicAdapter)) {
+                    return model;
+                }
+            }
+        }
+
+        if (_libvirtComputingResource.isGuestPVEnabled(platformEmulator)) {
+            return LibvirtVMDef.InterfaceDef.NicModel.VIRTIO;
+        } else {
+            return LibvirtVMDef.InterfaceDef.NicModel.E1000;
+        }
+    }
+
+    public boolean isExistingBridge(String bridgeName) {
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckUrlCommand.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckUrlCommand.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckUrlCommand.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckUrlCommand.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVMActivityOnStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java
new file mode 100644
index 0000000..bfa5573
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java
@@ -0,0 +1,87 @@
+//
+// 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 org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+
+@ResourceWrapper(handles =  CreateCommand.class)
+public final class LibvirtCreateCommandWrapper extends CommandWrapper<CreateCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtCreateCommandWrapper.class);
+
+    @Override
+    public Answer execute(final CreateCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final StorageFilerTO pool = command.getPool();
+        final DiskProfile dskch = command.getDiskCharacteristics();
+        KVMPhysicalDisk baseVol = null;
+        KVMStoragePool primaryPool = null;
+        KVMPhysicalDisk vol = null;
+        long disksize;
+        try {
+            final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
+            primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
+            disksize = dskch.getSize();
+
+            if (command.getTemplateUrl() != null) {
+                if (primaryPool.getType() == StoragePoolType.CLVM) {
+                    vol = libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primaryPool, dskch.getPath());
+                } else {
+                    baseVol = primaryPool.getPhysicalDisk(command.getTemplateUrl());
+                    vol = storagePoolMgr.createDiskFromTemplate(baseVol, dskch.getPath(), dskch.getProvisioningType(), primaryPool, baseVol.getSize(), 0);
+                }
+                if (vol == null) {
+                    return new Answer(command, false, " Can't create storage volume on storage pool");
+                }
+            } else {
+                vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize());
+                if (vol == null) {
+                    return new Answer(command, false, " Can't create Physical Disk");
+                }
+            }
+            final VolumeTO volume = new VolumeTO(command.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize,
+                    null);
+
+            volume.setBytesReadRate(dskch.getBytesReadRate());
+            volume.setBytesWriteRate(dskch.getBytesWriteRate());
+            volume.setIopsReadRate(dskch.getIopsReadRate());
+            volume.setIopsWriteRate(dskch.getIopsWriteRate());
+            volume.setCacheMode(dskch.getCacheMode());
+            return new CreateAnswer(command, volume);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to create volume: " + e.toString());
+            return new CreateAnswer(command, e);
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVMSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteVMSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
new file mode 100644
index 0000000..b04a866
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.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 com.cloud.hypervisor.kvm.resource.wrapper;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.utils.Pair;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.log4j.Logger;
+
+@ResourceWrapper(handles =  GetHostStatsCommand.class)
+public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetHostStatsCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtGetHostStatsCommandWrapper.class);
+
+    @Override
+    public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        CPUStat cpuStat = libvirtComputingResource.getCPUStat();
+        MemStat memStat = libvirtComputingResource.getMemStat();
+
+        final double cpuUtil = cpuStat.getCpuUsedPercent();
+
+        final Pair<Double, Double> nicStats = libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName());
+
+        final HostStatsEntry hostStats = new HostStatsEntry(command.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", memStat.getTotal() / 1024, memStat.getAvailable() / 1024, 0, 0);
+        return new GetHostStatsAnswer(command, hostStats);
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumeStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumeStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumeStatsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVolumeStatsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtHandleConfigDriveCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtHandleConfigDriveCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtHandleConfigDriveCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtHandleConfigDriveCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
new file mode 100644
index 0000000..0c1370e
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java
@@ -0,0 +1,494 @@
+//
+// 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.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.LibvirtException;
+import org.libvirt.StorageVol;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.MigrateKVMAsync;
+import com.cloud.hypervisor.kvm.resource.VifDriver;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.base.Strings;
+
+@ResourceWrapper(handles =  MigrateCommand.class)
+public final class LibvirtMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, LibvirtComputingResource> {
+
+    private static final String GRAPHICS_ELEM_END = "/graphics>";
+    private static final String GRAPHICS_ELEM_START = "<graphics";
+    private static final String CONTENTS_WILDCARD = "(?s).*";
+    private static final Logger s_logger = Logger.getLogger(LibvirtMigrateCommandWrapper.class);
+
+    protected String createMigrationURI(final String destinationIp, final LibvirtComputingResource libvirtComputingResource) {
+        if (Strings.isNullOrEmpty(destinationIp)) {
+            throw new CloudRuntimeException("Provided libvirt destination ip is invalid");
+        }
+        return String.format("%s://%s/system", libvirtComputingResource.isHostSecured() ? "qemu+tls" : "qemu+tcp", destinationIp);
+    }
+
+    @Override
+    public Answer execute(final MigrateCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final String vmName = command.getVmName();
+        final String destinationUri = createMigrationURI(command.getDestinationIp(), libvirtComputingResource);
+        final List<MigrateDiskInfo> migrateDiskInfoList = command.getMigrateDiskInfoList();
+
+        String result = null;
+
+        List<InterfaceDef> ifaces = null;
+        List<DiskDef> disks;
+
+        Domain dm = null;
+        Connect dconn = null;
+        Domain destDomain = null;
+        Connect conn = null;
+        String xmlDesc = null;
+        List<Ternary<String, Boolean, String>> vmsnapshots = null;
+
+        try {
+            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
+
+            conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
+            ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
+            disks = libvirtComputingResource.getDisks(conn, vmName);
+            dm = conn.domainLookupByName(vmName);
+            /*
+                We replace the private IP address with the address of the destination host.
+                This is because the VNC listens on the private IP address of the hypervisor,
+                but that address is of course different on the target host.
+
+                MigrateCommand.getDestinationIp() returns the private IP address of the target
+                hypervisor. So it's safe to use.
+
+                The Domain.migrate method from libvirt supports passing a different XML
+                description for the instance to be used on the target host.
+
+                This is supported by libvirt-java from version 0.50.0
+
+                CVE-2015-3252: Get XML with sensitive information suitable for migration by using
+                               VIR_DOMAIN_XML_MIGRATABLE flag (value = 8)
+                               https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
+
+                               Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0.
+             */
+            final int xmlFlag = conn.getLibVirVersion() >= 1000000 ? 8 : 1; // 1000000 equals v1.0.0
+
+            final String target = command.getDestinationIp();
+            xmlDesc = dm.getXMLDesc(xmlFlag);
+            xmlDesc = replaceIpForVNCInDescFile(xmlDesc, target);
+
+            // delete the metadata of vm snapshots before migration
+            vmsnapshots = libvirtComputingResource.cleanVMSnapshotMetadata(dm);
+
+            Map<String, MigrateCommand.MigrateDiskInfo> mapMigrateStorage = command.getMigrateStorage();
+            // migrateStorage is declared as final because the replaceStorage method may mutate mapMigrateStorage, but
+            // migrateStorage's value should always only be associated with the initial state of mapMigrateStorage.
+            final boolean migrateStorage = MapUtils.isNotEmpty(mapMigrateStorage);
+
+            if (migrateStorage) {
+                xmlDesc = replaceStorage(xmlDesc, mapMigrateStorage);
+            }
+
+            dconn = libvirtUtilitiesHelper.retrieveQemuConnection(destinationUri);
+
+            //run migration in thread so we can monitor it
+            s_logger.info("Live migration of instance " + vmName + " initiated to destination host: " + dconn.getURI());
+            final ExecutorService executor = Executors.newFixedThreadPool(1);
+            final Callable<Domain> worker = new MigrateKVMAsync(libvirtComputingResource, dm, dconn, xmlDesc, migrateStorage,
+                    command.isAutoConvergence(), vmName, command.getDestinationIp());
+            final Future<Domain> migrateThread = executor.submit(worker);
+            executor.shutdown();
+            long sleeptime = 0;
+            while (!executor.isTerminated()) {
+                Thread.sleep(100);
+                sleeptime += 100;
+                if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state
+                    final int migrateDowntime = libvirtComputingResource.getMigrateDowntime();
+                    if (migrateDowntime > 0 ) {
+                        try {
+                            final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime);
+                            if (setDowntime == 0 ) {
+                                s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms");
+                            }
+                        } catch (final LibvirtException e) {
+                            s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage());
+                        }
+                    }
+                }
+                if (sleeptime % 1000 == 0) {
+                    s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms");
+                }
+
+                // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused
+                final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter();
+                if (migratePauseAfter > 0 && sleeptime > migratePauseAfter) {
+                    DomainState state = null;
+                    try {
+                        state = dm.getInfo().state;
+                    } catch (final LibvirtException e) {
+                        s_logger.info("Couldn't get VM domain state after " + sleeptime + "ms: " + e.getMessage());
+                    }
+                    if (state != null && state == DomainState.VIR_DOMAIN_RUNNING) {
+                        try {
+                            s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter + "ms to complete migration");
+                            dm.suspend();
+                        } catch (final LibvirtException e) {
+                            // pause could be racy if it attempts to pause right when vm is finished, simply warn
+                            s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage());
+                        }
+                    }
+                }
+            }
+            s_logger.info("Migration thread for " + vmName + " is done");
+
+            destDomain = migrateThread.get(10, TimeUnit.SECONDS);
+
+            if (destDomain != null) {
+                deleteOrDisconnectDisksOnSourcePool(libvirtComputingResource, migrateDiskInfoList, disks);
+            }
+
+        } catch (final LibvirtException e) {
+            s_logger.debug("Can't migrate domain: " + e.getMessage());
+            result = e.getMessage();
+            if (result.startsWith("unable to connect to server") && result.endsWith("refused")) {
+                result = String.format("Migration was refused connection to destination: %s. Please check libvirt configuration compatibility and firewall rules on the source and destination hosts.", destinationUri);
+            }
+        } catch (final InterruptedException e) {
+            s_logger.debug("Interrupted while migrating domain: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final ExecutionException e) {
+            s_logger.debug("Failed to execute while migrating domain: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final TimeoutException e) {
+            s_logger.debug("Timed out while migrating domain: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final IOException e) {
+            s_logger.debug("IOException: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final ParserConfigurationException e) {
+            s_logger.debug("ParserConfigurationException: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final SAXException e) {
+            s_logger.debug("SAXException: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final TransformerConfigurationException e) {
+            s_logger.debug("TransformerConfigurationException: " + e.getMessage());
+            result = e.getMessage();
+        } catch (final TransformerException e) {
+            s_logger.debug("TransformerException: " + e.getMessage());
+            result = e.getMessage();
+        } finally {
+            try {
+                if (dm != null && result != null) {
+                    // restore vm snapshots in case of failed migration
+                    if (vmsnapshots != null) {
+                        libvirtComputingResource.restoreVMSnapshotMetadata(dm, vmName, vmsnapshots);
+                    }
+                }
+                if (dm != null) {
+                    if (dm.isPersistent() == 1) {
+                        dm.undefine();
+                    }
+                    dm.free();
+                }
+                if (dconn != null) {
+                    dconn.close();
+                }
+                if (destDomain != null) {
+                    destDomain.free();
+                }
+            } catch (final LibvirtException e) {
+                s_logger.trace("Ignoring libvirt error.", e);
+            }
+        }
+
+        if (result != null) {
+        } else {
+            libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName);
+            for (final InterfaceDef iface : ifaces) {
+                // We don't know which "traffic type" is associated with
+                // each interface at this point, so inform all vif drivers
+                final List<VifDriver> allVifDrivers = libvirtComputingResource.getAllVifDrivers();
+                for (final VifDriver vifDriver : allVifDrivers) {
+                    vifDriver.unplug(iface);
+                }
+            }
+        }
+
+        return new MigrateAnswer(command, result == null, result, null);
+    }
+
+    /**
+     * In case of a local file, it deletes the file on the source host/storage pool. Otherwise (for instance iScsi) it disconnects the disk on the source storage pool. </br>
+     * This method must be executed after a successful migration to a target storage pool, cleaning up the source storage.
+     */
+    protected void deleteOrDisconnectDisksOnSourcePool(final LibvirtComputingResource libvirtComputingResource, final List<MigrateDiskInfo> migrateDiskInfoList,
+            List<DiskDef> disks) {
+        for (DiskDef disk : disks) {
+            MigrateDiskInfo migrateDiskInfo = searchDiskDefOnMigrateDiskInfoList(migrateDiskInfoList, disk);
+            if (migrateDiskInfo != null && migrateDiskInfo.isSourceDiskOnStorageFileSystem()) {
+                deleteLocalVolume(disk.getDiskPath());
+            } else {
+                libvirtComputingResource.cleanupDisk(disk);
+            }
+        }
+    }
+
+    /**
+     * Deletes the local volume from the storage pool.
+     */
+    protected void deleteLocalVolume(String localPath) {
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            StorageVol storageVolLookupByPath = conn.storageVolLookupByPath(localPath);
+            storageVolLookupByPath.delete(0);
+        } catch (LibvirtException e) {
+            s_logger.error(String.format("Cannot delete local volume [%s] due to: %s", localPath, e));
+        }
+    }
+
+    /**
+     * Searches for a {@link MigrateDiskInfo} with the path matching the {@link DiskDef} path.
+     */
+    protected MigrateDiskInfo searchDiskDefOnMigrateDiskInfoList(List<MigrateDiskInfo> migrateDiskInfoList, DiskDef disk) {
+        for (MigrateDiskInfo migrateDiskInfo : migrateDiskInfoList) {
+            if (StringUtils.contains(disk.getDiskPath(), migrateDiskInfo.getSerialNumber())) {
+                return migrateDiskInfo;
+            }
+        }
+        s_logger.debug(String.format("Cannot find Disk [uuid: %s] on the list of disks to be migrated", disk.getDiskPath()));
+        return null;
+    }
+
+    /**
+     * This function assumes an qemu machine description containing a single graphics element like
+     *     <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>
+     *       <listen type='address' address='10.10.10.1'/>
+     *     </graphics>
+     * @param xmlDesc the qemu xml description
+     * @param target the ip address to migrate to
+     * @return the new xmlDesc
+     */
+    String replaceIpForVNCInDescFile(String xmlDesc, final String target) {
+        final int begin = xmlDesc.indexOf(GRAPHICS_ELEM_START);
+        if (begin >= 0) {
+            final int end = xmlDesc.lastIndexOf(GRAPHICS_ELEM_END) + GRAPHICS_ELEM_END.length();
+            if (end > begin) {
+                String graphElem = xmlDesc.substring(begin, end);
+                graphElem = graphElem.replaceAll("listen='[a-zA-Z0-9\\.]*'", "listen='" + target + "'");
+                graphElem = graphElem.replaceAll("address='[a-zA-Z0-9\\.]*'", "address='" + target + "'");
+                xmlDesc = xmlDesc.replaceAll(GRAPHICS_ELEM_START + CONTENTS_WILDCARD + GRAPHICS_ELEM_END, graphElem);
+            }
+        }
+        return xmlDesc;
+    }
+
+    /**
+     * Pass in a list of the disks to update in the XML (xmlDesc). Each disk passed in needs to have a serial number. If any disk's serial number in the
+     * list does not match a disk in the XML, an exception should be thrown.
+     * In addition to the serial number, each disk in the list needs the following info:
+     * <ul>
+     *  <li>The value of the 'type' of the disk (ex. file, block)
+     *  <li>The value of the 'type' of the driver of the disk (ex. qcow2, raw)
+     *  <li>The source of the disk needs an attribute that is either 'file' or 'dev' as well as its corresponding value.
+     * </ul>
+     */
+    protected String replaceStorage(String xmlDesc, Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage)
+            throws IOException, ParserConfigurationException, SAXException, TransformerException {
+        InputStream in = IOUtils.toInputStream(xmlDesc);
+
+        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+        Document doc = docBuilder.parse(in);
+
+        // Get the root element
+        Node domainNode = doc.getFirstChild();
+
+        NodeList domainChildNodes = domainNode.getChildNodes();
+
+        for (int i = 0; i < domainChildNodes.getLength(); i++) {
+            Node domainChildNode = domainChildNodes.item(i);
+
+            if ("devices".equals(domainChildNode.getNodeName())) {
+                NodeList devicesChildNodes = domainChildNode.getChildNodes();
+
+                for (int x = 0; x < devicesChildNodes.getLength(); x++) {
+                    Node deviceChildNode = devicesChildNodes.item(x);
+
+                    if ("disk".equals(deviceChildNode.getNodeName())) {
+                        Node diskNode = deviceChildNode;
+
+                        String sourceText = getSourceText(diskNode);
+
+                        String path = getPathFromSourceText(migrateStorage.keySet(), sourceText);
+
+                        if (path != null) {
+                            MigrateCommand.MigrateDiskInfo migrateDiskInfo = migrateStorage.get(path);
+
+                            NamedNodeMap diskNodeAttributes = diskNode.getAttributes();
+                            Node diskNodeAttribute = diskNodeAttributes.getNamedItem("type");
+
+                            diskNodeAttribute.setTextContent(migrateDiskInfo.getDiskType().toString());
+
+                            NodeList diskChildNodes = diskNode.getChildNodes();
+
+                            for (int z = 0; z < diskChildNodes.getLength(); z++) {
+                                Node diskChildNode = diskChildNodes.item(z);
+
+                                if ("driver".equals(diskChildNode.getNodeName())) {
+                                    Node driverNode = diskChildNode;
+
+                                    NamedNodeMap driverNodeAttributes = driverNode.getAttributes();
+                                    Node driverNodeAttribute = driverNodeAttributes.getNamedItem("type");
+
+                                    driverNodeAttribute.setTextContent(migrateDiskInfo.getDriverType().toString());
+                                } else if ("source".equals(diskChildNode.getNodeName())) {
+                                    diskNode.removeChild(diskChildNode);
+
+                                    Element newChildSourceNode = doc.createElement("source");
+
+                                    newChildSourceNode.setAttribute(migrateDiskInfo.getSource().toString(), migrateDiskInfo.getSourceText());
+
+                                    diskNode.appendChild(newChildSourceNode);
+                                } else if ("auth".equals(diskChildNode.getNodeName())) {
+                                    diskNode.removeChild(diskChildNode);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return getXml(doc);
+    }
+
+    private String getPathFromSourceText(Set<String> paths, String sourceText) {
+        if (paths != null && !StringUtils.isBlank(sourceText)) {
+            for (String path : paths) {
+                if (sourceText.contains(path)) {
+                    return path;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private String getSourceText(Node diskNode) {
+        NodeList diskChildNodes = diskNode.getChildNodes();
+
+        for (int i = 0; i < diskChildNodes.getLength(); i++) {
+            Node diskChildNode = diskChildNodes.item(i);
+
+            if ("source".equals(diskChildNode.getNodeName())) {
+                NamedNodeMap diskNodeAttributes = diskChildNode.getAttributes();
+
+                Node diskNodeAttribute = diskNodeAttributes.getNamedItem("file");
+
+                if (diskNodeAttribute != null) {
+                    return diskNodeAttribute.getTextContent();
+                }
+
+                diskNodeAttribute = diskNodeAttributes.getNamedItem("dev");
+
+                if (diskNodeAttribute != null) {
+                    return diskNodeAttribute.getTextContent();
+                }
+
+                diskNodeAttribute = diskNodeAttributes.getNamedItem("protocol");
+
+                if (diskNodeAttribute != null) {
+                    String textContent = diskNodeAttribute.getTextContent();
+
+                    if ("rbd".equalsIgnoreCase(textContent)) {
+                        diskNodeAttribute = diskNodeAttributes.getNamedItem("name");
+
+                        if (diskNodeAttribute != null) {
+                            return diskNodeAttribute.getTextContent();
+                        }
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private String getXml(Document doc) throws TransformerException {
+        TransformerFactory transformerFactory = TransformerFactory.newInstance();
+        Transformer transformer = transformerFactory.newTransformer();
+
+        DOMSource source = new DOMSource(doc);
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        StreamResult result = new StreamResult(byteArrayOutputStream);
+
+        transformer.transform(source, result);
+
+        return byteArrayOutputStream.toString();
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyTargetsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyTargetsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyTargetsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyTargetsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
new file mode 100644
index 0000000..1ef32af
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java
@@ -0,0 +1,86 @@
+//
+// 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 com.cloud.agent.api.Answer;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.VifDriver;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.LibvirtException;
+
+import java.util.List;
+
+@ResourceWrapper(handles =  PlugNicCommand.class)
+public final class LibvirtPlugNicCommandWrapper extends CommandWrapper<PlugNicCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtPlugNicCommandWrapper.class);
+
+    @Override
+    public Answer execute(final PlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final NicTO nic = command.getNic();
+        final String vmName = command.getVmName();
+        Domain vm = null;
+        try {
+            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
+            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
+            vm = libvirtComputingResource.getDomain(conn, vmName);
+
+            final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
+            Integer nicnum = 0;
+            for (final InterfaceDef pluggedNic : pluggedNics) {
+                if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
+                    s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum);
+                    return new PlugNicAnswer(command, true, "success");
+                }
+                nicnum++;
+            }
+            final VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
+            final InterfaceDef interfaceDef = vifDriver.plug(nic, "Other PV", "", null);
+            vm.attachDevice(interfaceDef.toString());
+
+            return new PlugNicAnswer(command, true, "success");
+        } catch (final LibvirtException e) {
+            final String msg = " Plug Nic failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new PlugNicAnswer(command, false, msg);
+        } catch (final InternalErrorException e) {
+            final String msg = " Plug Nic failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new PlugNicAnswer(command, false, msg);
+        } finally {
+            if (vm != null) {
+                try {
+                    vm.free();
+                } catch (final LibvirtException l) {
+                    s_logger.trace("Ignoring libvirt error.", l);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java
new file mode 100644
index 0000000..5f8e2ca
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPostCertificateRenewalCommandWrapper.java
@@ -0,0 +1,48 @@
+// 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 org.apache.cloudstack.ca.PostCertificateRenewalCommand;
+import org.apache.cloudstack.ca.SetupCertificateAnswer;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.utils.script.Script;
+
+@ResourceWrapper(handles =  PostCertificateRenewalCommand.class)
+public final class LibvirtPostCertificateRenewalCommandWrapper extends CommandWrapper<PostCertificateRenewalCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtPostCertificateRenewalCommandWrapper.class);
+
+    @Override
+    public Answer execute(final PostCertificateRenewalCommand command, final LibvirtComputingResource serverResource) {
+        s_logger.info("Restarting libvirt after certificate provisioning/renewal");
+        if (command != null) {
+            final int timeout = 30000;
+            Script script = new Script(true, "service", timeout, s_logger);
+            script.add("libvirtd");
+            script.add("restart");
+            script.execute();
+            return new SetupCertificateAnswer(true);
+       }
+        return new SetupCertificateAnswer(false);
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java
new file mode 100644
index 0000000..5c9980b
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.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 com.cloud.hypervisor.kvm.resource.wrapper;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.storage.Volume;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.LibvirtException;
+
+import java.net.URISyntaxException;
+
+@ResourceWrapper(handles =  PrepareForMigrationCommand.class)
+public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapper<PrepareForMigrationCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtPrepareForMigrationCommandWrapper.class);
+
+    @Override
+    public Answer execute(final PrepareForMigrationCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final VirtualMachineTO vm = command.getVirtualMachine();
+
+        if (command.isRollback()) {
+            return handleRollback(command, libvirtComputingResource);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Preparing host for migrating " + vm);
+        }
+
+        final NicTO[] nics = vm.getNics();
+
+        boolean skipDisconnect = false;
+
+        final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
+        try {
+            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
+
+            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vm.getName());
+            for (final NicTO nic : nics) {
+                libvirtComputingResource.getVifDriver(nic.getType(), nic.getName()).plug(nic, null, "", null);
+            }
+
+            /* setup disks, e.g for iso */
+            final DiskTO[] volumes = vm.getDisks();
+            for (final DiskTO volume : volumes) {
+                if (volume.getType() == Volume.Type.ISO) {
+                    libvirtComputingResource.getVolumePath(conn, volume);
+                }
+            }
+
+            skipDisconnect = true;
+
+            if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) {
+                return new PrepareForMigrationAnswer(command, "failed to connect physical disks to host");
+            }
+
+            return new PrepareForMigrationAnswer(command);
+        } catch (final LibvirtException e) {
+            return new PrepareForMigrationAnswer(command, e.toString());
+        } catch (final InternalErrorException e) {
+            return new PrepareForMigrationAnswer(command, e.toString());
+        } catch (final URISyntaxException e) {
+            return new PrepareForMigrationAnswer(command, e.toString());
+        } finally {
+            if (!skipDisconnect) {
+                storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm);
+            }
+        }
+    }
+
+    private Answer handleRollback(PrepareForMigrationCommand command, LibvirtComputingResource libvirtComputingResource) {
+        KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
+        VirtualMachineTO vmTO = command.getVirtualMachine();
+
+        if (!storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmTO)) {
+            return new PrepareForMigrationAnswer(command, "failed to disconnect physical disks from host");
+        }
+
+        return new PrepareForMigrationAnswer(command);
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java
new file mode 100644
index 0000000..7ee9171
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapper.java
@@ -0,0 +1,125 @@
+// 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.List;
+
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ReplugNicAnswer;
+import com.cloud.agent.api.ReplugNicCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.VifDriver;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+
+@ResourceWrapper(handles =  ReplugNicCommand.class)
+public final class LibvirtReplugNicCommandWrapper extends CommandWrapper<ReplugNicCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtReplugNicCommandWrapper.class);
+    public enum DomainAffect {
+        CURRENT(0), LIVE(1), CONFIG(2), BOTH(3);
+
+        private int value;
+        DomainAffect(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
+    @Override
+    public Answer execute(final ReplugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final NicTO nic = command.getNic();
+        final String vmName = command.getVmName();
+        Domain vm = null;
+        try {
+            final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
+            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
+            vm = libvirtComputingResource.getDomain(conn, vmName);
+
+            InterfaceDef oldPluggedNic = findPluggedNic(libvirtComputingResource, nic, vmName, conn);
+
+            final VifDriver newVifDriver = libvirtComputingResource.getVifDriver(nic.getType(), nic.getName());
+            final InterfaceDef interfaceDef = newVifDriver.plug(nic, "Other PV", oldPluggedNic.getModel().toString(), null);
+
+            interfaceDef.setSlot(oldPluggedNic.getSlot());
+            interfaceDef.setDevName(oldPluggedNic.getDevName());
+            interfaceDef.setLinkStateUp(false);
+
+            oldPluggedNic.setSlot(null);
+
+            int i = 0;
+            do {
+                i++;
+                s_logger.debug("ReplugNic: Detaching interface" + oldPluggedNic + " (Attempt: " + i + ")");
+                vm.detachDevice(oldPluggedNic.toString());
+            } while (findPluggedNic(libvirtComputingResource, nic, vmName, conn) != null && i <= 10);
+
+            s_logger.debug("ReplugNic: Attaching interface" + interfaceDef);
+            vm.attachDevice(interfaceDef.toString());
+
+            interfaceDef.setLinkStateUp(true);
+            s_logger.debug("ReplugNic: Updating interface" + interfaceDef);
+            vm.updateDeviceFlags(interfaceDef.toString(), DomainAffect.LIVE.getValue());
+
+            // We don't know which "traffic type" is associated with
+            // each interface at this point, so inform all vif drivers
+            for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
+                vifDriver.unplug(oldPluggedNic);
+            }
+
+            return new ReplugNicAnswer(command, true, "success");
+        } catch (final LibvirtException | InternalErrorException e) {
+            final String msg = " Plug Nic failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ReplugNicAnswer(command, false, msg);
+        } finally {
+            if (vm != null) {
+                try {
+                    vm.free();
+                } catch (final LibvirtException l) {
+                    s_logger.trace("Ignoring libvirt error.", l);
+                }
+            }
+        }
+    }
+
+    private InterfaceDef findPluggedNic(LibvirtComputingResource libvirtComputingResource, NicTO nic, String vmName, Connect conn) {
+        InterfaceDef oldPluggedNic = null;
+
+        final List<InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
+
+        for (final InterfaceDef pluggedNic : pluggedNics) {
+            if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
+                oldPluggedNic = pluggedNic;
+            }
+        }
+
+        return oldPluggedNic;
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRestoreVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertToVMSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertToVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertToVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRevertToVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
new file mode 100644
index 0000000..f3839f0
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java
@@ -0,0 +1,162 @@
+//
+// 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.net.URISyntaxException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.LibvirtException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.cloud.vm.VirtualMachine;
+
+@ResourceWrapper(handles =  StartCommand.class)
+public final class LibvirtStartCommandWrapper extends CommandWrapper<StartCommand, Answer, LibvirtComputingResource> {
+
+    private static final Logger s_logger = Logger.getLogger(LibvirtStartCommandWrapper.class);
+
+    @Override
+    public Answer execute(final StartCommand command, final LibvirtComputingResource libvirtComputingResource) {
+        final VirtualMachineTO vmSpec = command.getVirtualMachine();
+        vmSpec.setVncAddr(command.getHostIp());
+        final String vmName = vmSpec.getName();
+        LibvirtVMDef vm = null;
+
+        DomainState  state = DomainState.VIR_DOMAIN_SHUTOFF;
+        final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
+        Connect conn = null;
+        try {
+
+            vm = libvirtComputingResource.createVMFromSpec(vmSpec);
+            conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
+
+            final NicTO[] nics = vmSpec.getNics();
+
+            for (final NicTO nic : nics) {
+                if (vmSpec.getType() != VirtualMachine.Type.User) {
+                    nic.setPxeDisable(true);
+                    nic.setDpdkDisabled(true);
+                }
+            }
+
+            libvirtComputingResource.createVbd(conn, vmSpec, vmName, vm);
+
+            if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) {
+                return new StartAnswer(command, "Failed to connect physical disks to host");
+            }
+
+            libvirtComputingResource.createVifs(vmSpec, vm);
+
+            s_logger.debug("starting " + vmName + ": " + vm.toString());
+            libvirtComputingResource.startVM(conn, vmName, vm.toString());
+
+            for (final NicTO nic : nics) {
+                if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
+                    if (vmSpec.getType() != VirtualMachine.Type.User) {
+                        libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, vmName);
+                        break;
+                    } else {
+                        final List<String> nicSecIps = nic.getNicSecIps();
+                        String secIpsStr;
+                        final StringBuilder sb = new StringBuilder();
+                        if (nicSecIps != null) {
+                            for (final String ip : nicSecIps) {
+                                sb.append(ip).append(";");
+                            }
+                            secIpsStr = sb.toString();
+                        } else {
+                            secIpsStr = "0;";
+                        }
+                        libvirtComputingResource.defaultNetworkRules(conn, vmName, nic, vmSpec.getId(), secIpsStr);
+                    }
+                }
+            }
+
+            // pass cmdline info to system vms
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                String controlIp = null;
+                for (final NicTO nic : nics) {
+                    if (nic.getType() == TrafficType.Control) {
+                        controlIp = nic.getIp();
+                        break;
+                    }
+                }
+                // try to patch and SSH into the systemvm for up to 5 minutes
+                for (int count = 0; count < 10; count++) {
+                    // wait and try passCmdLine for 30 seconds at most for CLOUDSTACK-2823
+                    if (libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())) {
+                        break;
+                    }
+                }
+
+                final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource();
+                // check if the router is up?
+                for (int count = 0; count < 60; count++) {
+                    final boolean result = virtRouterResource.connect(controlIp, 1, 5000);
+                    if (result) {
+                        break;
+                    }
+                }
+            }
+
+            state = DomainState.VIR_DOMAIN_RUNNING;
+            return new StartAnswer(command);
+        } catch (final LibvirtException e) {
+            s_logger.warn("LibvirtException ", e);
+            if (conn != null) {
+                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
+            }
+            return new StartAnswer(command, e.getMessage());
+        } catch (final InternalErrorException e) {
+            s_logger.warn("InternalErrorException ", e);
+            if (conn != null) {
+                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
+            }
+            return new StartAnswer(command, e.getMessage());
+        } catch (final URISyntaxException e) {
+            s_logger.warn("URISyntaxException ", e);
+            if (conn != null) {
+                libvirtComputingResource.handleVmStartFailure(conn, vmName, vm);
+            }
+            return new StartAnswer(command, e.getMessage());
+        } finally {
+            if (state != DomainState.VIR_DOMAIN_RUNNING) {
+                storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmSpec);
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpdateHostPasswordCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpdateHostPasswordCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpdateHostPasswordCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpdateHostPasswordCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
new file mode 100644
index 0000000..efb51fb
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java
@@ -0,0 +1,443 @@
+// 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.storage;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+@StorageAdaptorInfo(storagePoolType=StoragePoolType.Iscsi)
+public class IscsiAdmStorageAdaptor implements StorageAdaptor {
+    private static final Logger s_logger = Logger.getLogger(IscsiAdmStorageAdaptor.class);
+
+    private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>();
+
+    @Override
+    public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType) {
+        IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this);
+
+        MapStorageUuidToStoragePool.put(uuid, storagePool);
+
+        return storagePool;
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid) {
+        return MapStorageUuidToStoragePool.get(uuid);
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
+        return MapStorageUuidToStoragePool.get(uuid);
+    }
+
+    @Override
+    public boolean deleteStoragePool(String uuid) {
+        return MapStorageUuidToStoragePool.remove(uuid) != null;
+    }
+
+    @Override
+    public boolean deleteStoragePool(KVMStoragePool pool) {
+        return deleteStoragePool(pool.getUuid());
+    }
+
+    // called from LibvirtComputingResource.execute(CreateCommand)
+    // does not apply for iScsiAdmStorageAdaptor
+    @Override
+    public KVMPhysicalDisk createPhysicalDisk(String volumeUuid, KVMStoragePool pool, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
+        throw new UnsupportedOperationException("Creating a physical disk is not supported.");
+    }
+
+    @Override
+    public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details) {
+        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new
+        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
+
+        iScsiAdmCmd.add("-m", "node");
+        iScsiAdmCmd.add("-T", getIqn(volumeUuid));
+        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
+        iScsiAdmCmd.add("-o", "new");
+
+        String result = iScsiAdmCmd.execute();
+
+        if (result != null) {
+            s_logger.debug("Failed to add iSCSI target " + volumeUuid);
+            System.out.println("Failed to add iSCSI target " + volumeUuid);
+
+            return false;
+        } else {
+            s_logger.debug("Successfully added iSCSI target " + volumeUuid);
+            System.out.println("Successfully added to iSCSI target " + volumeUuid);
+        }
+
+        String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
+        String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+        if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorSecret)) {
+            try {
+                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.authmethod -v CHAP
+                executeChapCommand(volumeUuid, pool, "node.session.auth.authmethod", "CHAP", null);
+
+                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.username -v username
+                executeChapCommand(volumeUuid, pool, "node.session.auth.username", chapInitiatorUsername, "username");
+
+                // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --op update -n node.session.auth.password -v password
+                executeChapCommand(volumeUuid, pool, "node.session.auth.password", chapInitiatorSecret, "password");
+            } catch (Exception ex) {
+                return false;
+            }
+        }
+
+        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --login
+        iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
+
+        iScsiAdmCmd.add("-m", "node");
+        iScsiAdmCmd.add("-T", getIqn(volumeUuid));
+        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
+        iScsiAdmCmd.add("--login");
+
+        result = iScsiAdmCmd.execute();
+
+        if (result != null) {
+            s_logger.debug("Failed to log in to iSCSI target " + volumeUuid);
+            System.out.println("Failed to log in to iSCSI target " + volumeUuid);
+
+            return false;
+        } else {
+            s_logger.debug("Successfully logged in to iSCSI target " + volumeUuid);
+            System.out.println("Successfully logged in to iSCSI target " + volumeUuid);
+        }
+
+        // There appears to be a race condition where logging in to the iSCSI volume via iscsiadm
+        // returns success before the device has been added to the OS.
+        // What happens is you get logged in and the device shows up, but the device may not
+        // show up before we invoke Libvirt to attach the device to a VM.
+        // waitForDiskToBecomeAvailable(String, KVMStoragePool) invokes blockdev
+        // via getPhysicalDisk(String, KVMStoragePool) and checks if the size came back greater
+        // than 0.
+        // After a certain number of tries and a certain waiting period in between tries,
+        // this method could still return (it should not block indefinitely) (the race condition
+        // isn't solved here, but made highly unlikely to be a problem).
+        waitForDiskToBecomeAvailable(volumeUuid, pool);
+
+        return true;
+    }
+
+    private void waitForDiskToBecomeAvailable(String volumeUuid, KVMStoragePool pool) {
+        int numberOfTries = 10;
+        int timeBetweenTries = 1000;
+
+        while (getPhysicalDisk(volumeUuid, pool).getSize() == 0 && numberOfTries > 0) {
+            numberOfTries--;
+
+            try {
+                Thread.sleep(timeBetweenTries);
+            } catch (Exception ex) {
+                // don't do anything
+            }
+        }
+    }
+
+    private void waitForDiskToBecomeUnavailable(String host, int port, String iqn, String lun) {
+        int numberOfTries = 10;
+        int timeBetweenTries = 1000;
+
+        String deviceByPath = getByPath(host, port, "/" + iqn + "/" + lun);
+
+        while (getDeviceSize(deviceByPath) > 0 && numberOfTries > 0) {
+            numberOfTries--;
+
+            try {
+                Thread.sleep(timeBetweenTries);
+            } catch (Exception ex) {
+                // don't do anything
+            }
+        }
+    }
+
+    private void executeChapCommand(String path, KVMStoragePool pool, String nParameter, String vParameter, String detail) throws Exception {
+        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
+
+        iScsiAdmCmd.add("-m", "node");
+        iScsiAdmCmd.add("-T", getIqn(path));
+        iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
+        iScsiAdmCmd.add("--op", "update");
+        iScsiAdmCmd.add("-n", nParameter);
+        iScsiAdmCmd.add("-v", vParameter);
+
+        String result = iScsiAdmCmd.execute();
+
+        boolean useDetail = detail != null && detail.trim().length() > 0;
+
+        detail = useDetail ? detail.trim() + " " : detail;
+
+        if (result != null) {
+            s_logger.debug("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
+            System.out.println("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
+
+            throw new Exception("Failed to execute CHAP " + (useDetail ? detail : "") + "command for iSCSI target " + path + " : message = " + result);
+        } else {
+            s_logger.debug("CHAP " + (useDetail ? detail : "") + "command executed successfully for iSCSI target " + path);
+            System.out.println("CHAP " + (useDetail ? detail : "") + "command executed successfully for iSCSI target " + path);
+        }
+    }
+
+    // example by-path: /dev/disk/by-path/ip-192.168.233.10:3260-iscsi-iqn.2012-03.com.solidfire:storagepool2-lun-0
+    private static String getByPath(String host, int port, String path) {
+        return "/dev/disk/by-path/ip-" + host + ":" + port + "-iscsi-" + getIqn(path) + "-lun-" + getLun(path);
+    }
+
+    @Override
+    public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        String deviceByPath = getByPath(pool.getSourceHost(), pool.getSourcePort(), volumeUuid);
+        KVMPhysicalDisk physicalDisk = new KVMPhysicalDisk(deviceByPath, volumeUuid, pool);
+
+        physicalDisk.setFormat(PhysicalDiskFormat.RAW);
+
+        long deviceSize = getDeviceSize(deviceByPath);
+
+        physicalDisk.setSize(deviceSize);
+        physicalDisk.setVirtualSize(deviceSize);
+
+        return physicalDisk;
+    }
+
+    private long getDeviceSize(String deviceByPath) {
+        Script iScsiAdmCmd = new Script(true, "blockdev", 0, s_logger);
+
+        iScsiAdmCmd.add("--getsize64", deviceByPath);
+
+        OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+
+        String result = iScsiAdmCmd.execute(parser);
+
+        if (result != null) {
+            s_logger.warn("Unable to retrieve the size of device " + deviceByPath);
+
+            return 0;
+        }
+        else {
+            s_logger.info("Successfully retrieved the size of device " + deviceByPath);
+        }
+
+        return Long.parseLong(parser.getLine());
+    }
+
+    private static String getIqn(String path) {
+        return getComponent(path, 1);
+    }
+
+    private static String getLun(String path) {
+        return getComponent(path, 2);
+    }
+
+    private static String getComponent(String path, int index) {
+        String[] tmp = path.split("/");
+
+        if (tmp.length != 3) {
+            String msg = "Wrong format for iScsi path: " + path + ". It should be formatted as '/targetIQN/LUN'.";
+
+            s_logger.warn(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        return tmp[index].trim();
+    }
+
+    private boolean disconnectPhysicalDisk(String host, int port, String iqn, String lun) {
+        // use iscsiadm to log out of the iSCSI target and un-discover it
+
+        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --logout
+        Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
+
+        iScsiAdmCmd.add("-m", "node");
+        iScsiAdmCmd.add("-T", iqn);
+        iScsiAdmCmd.add("-p", host + ":" + port);
+        iScsiAdmCmd.add("--logout");
+
+        String result = iScsiAdmCmd.execute();
+
+        if (result != null) {
+            s_logger.debug("Failed to log out of iSCSI target /" + iqn + "/" + lun + " : message = " + result);
+            System.out.println("Failed to log out of iSCSI target /" + iqn + "/" + lun + " : message = " + result);
+
+            return false;
+        } else {
+            s_logger.debug("Successfully logged out of iSCSI target /" + iqn + "/" + lun);
+            System.out.println("Successfully logged out of iSCSI target /" + iqn + "/" + lun);
+        }
+
+        // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o delete
+        iScsiAdmCmd = new Script(true, "iscsiadm", 0, s_logger);
+
+        iScsiAdmCmd.add("-m", "node");
+        iScsiAdmCmd.add("-T", iqn);
+        iScsiAdmCmd.add("-p", host + ":" + port);
+        iScsiAdmCmd.add("-o", "delete");
+
+        result = iScsiAdmCmd.execute();
+
+        if (result != null) {
+            s_logger.debug("Failed to remove iSCSI target /" + iqn + "/" + lun + " : message = " + result);
+            System.out.println("Failed to remove iSCSI target /" + iqn + "/" + lun + " : message = " + result);
+
+            return false;
+        } else {
+            s_logger.debug("Removed iSCSI target /" + iqn + "/" + lun);
+            System.out.println("Removed iSCSI target /" + iqn + "/" + lun);
+        }
+
+        waitForDiskToBecomeUnavailable(host, port, iqn, lun);
+
+        return true;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        return disconnectPhysicalDisk(pool.getSourceHost(), pool.getSourcePort(), getIqn(volumeUuid), getLun(volumeUuid));
+    }
+
+    @Override
+    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
+        String host = volumeToDisconnect.get(DiskTO.STORAGE_HOST);
+        String port = volumeToDisconnect.get(DiskTO.STORAGE_PORT);
+        String path = volumeToDisconnect.get(DiskTO.IQN);
+
+        if (host != null && port != null && path != null) {
+            return disconnectPhysicalDisk(host, Integer.parseInt(port), getIqn(path), getLun(path));
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDiskByPath(String localPath) {
+        String search1 = "/dev/disk/by-path/ip-";
+        String search2 = ":";
+        String search3 = "-iscsi-";
+        String search4 = "-lun-";
+
+        if (!localPath.contains(search3)) {
+            return false;
+        }
+
+        int index = localPath.indexOf(search2);
+
+        String host = localPath.substring(search1.length(), index);
+
+        int index2 = localPath.indexOf(search3);
+
+        String port = localPath.substring(index + search2.length(), index2);
+
+        index = localPath.indexOf(search4);
+
+        String iqn = localPath.substring(index2 + search3.length(), index);
+
+        String lun = localPath.substring(index + search4.length());
+
+        return disconnectPhysicalDisk(host, Integer.parseInt(port), iqn, lun);
+    }
+
+    @Override
+    public boolean deletePhysicalDisk(String volumeUuid, KVMStoragePool pool, Storage.ImageFormat format) {
+        throw new UnsupportedOperationException("Deleting a physical disk is not supported.");
+    }
+
+    // does not apply for iScsiAdmStorageAdaptor
+    @Override
+    public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStoragePool pool) {
+        throw new UnsupportedOperationException("Listing disks is not supported for this configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, PhysicalDiskFormat format,
+            ProvisioningType provisioningType, long size,
+            KVMStoragePool destPool, int timeout) {
+        throw new UnsupportedOperationException("Creating a disk from a template is not yet supported for this configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
+        throw new UnsupportedOperationException("Creating a template from a disk is not yet supported for this configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk srcDisk, String destVolumeUuid, KVMStoragePool destPool, int timeout) {
+        QemuImg q = new QemuImg(timeout);
+
+        QemuImgFile srcFile;
+
+        KVMStoragePool srcPool = srcDisk.getPool();
+
+        if (srcPool.getType() == StoragePoolType.RBD) {
+            srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(),
+                                                                       srcPool.getAuthUserName(), srcPool.getAuthSecret(),
+                                                                       srcDisk.getPath()),srcDisk.getFormat());
+        } else {
+            srcFile = new QemuImgFile(srcDisk.getPath(), srcDisk.getFormat());
+        }
+
+        KVMPhysicalDisk destDisk = destPool.getPhysicalDisk(destVolumeUuid);
+
+        QemuImgFile destFile = new QemuImgFile(destDisk.getPath(), destDisk.getFormat());
+
+        try {
+            q.convert(srcFile, destFile);
+        } catch (QemuImgException ex) {
+            String msg = "Failed to copy data from " + srcDisk.getPath() + " to " +
+                    destDisk.getPath() + ". The error was the following: " + ex.getMessage();
+
+            s_logger.error(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        return destPool.getPhysicalDisk(destVolumeUuid);
+    }
+
+    @Override
+    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
+        throw new UnsupportedOperationException("Creating a disk from a snapshot is not supported in this configuration.");
+    }
+
+    @Override
+    public boolean refresh(KVMStoragePool pool) {
+        return true;
+    }
+
+    @Override
+    public boolean createFolder(String uuid, String path) {
+        throw new UnsupportedOperationException("A folder cannot be created in this configuration.");
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStoragePool.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStoragePool.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStoragePool.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStoragePool.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePool.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
new file mode 100644
index 0000000..91cfc4e
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
@@ -0,0 +1,402 @@
+// 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.storage;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.kvm.resource.KVMHABase;
+import com.cloud.hypervisor.kvm.resource.KVMHABase.PoolType;
+import com.cloud.hypervisor.kvm.resource.KVMHAMonitor;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Volume;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+
+import org.reflections.Reflections;
+
+public class KVMStoragePoolManager {
+    private static final Logger s_logger = Logger.getLogger(KVMStoragePoolManager.class);
+
+    private class StoragePoolInformation {
+        String name;
+        String host;
+        int port;
+        String path;
+        String userInfo;
+        boolean type;
+        StoragePoolType poolType;
+
+        public StoragePoolInformation(String name, String host, int port, String path, String userInfo, StoragePoolType poolType, boolean type) {
+            this.name = name;
+            this.host = host;
+            this.port = port;
+            this.path = path;
+            this.userInfo = userInfo;
+            this.type = type;
+            this.poolType = poolType;
+        }
+    }
+
+    private KVMHAMonitor _haMonitor;
+    private final Map<String, StoragePoolInformation> _storagePools = new ConcurrentHashMap<String, StoragePoolInformation>();
+    private final Map<String, StorageAdaptor> _storageMapper = new HashMap<String, StorageAdaptor>();
+
+    private StorageAdaptor getStorageAdaptor(StoragePoolType type) {
+        // type can be null: LibVirtComputingResource:3238
+        if (type == null) {
+            return _storageMapper.get("libvirt");
+        }
+        StorageAdaptor adaptor = _storageMapper.get(type.toString());
+        if (adaptor == null) {
+            // LibvirtStorageAdaptor is selected by default
+            adaptor = _storageMapper.get("libvirt");
+        }
+        return adaptor;
+    }
+
+    private void addStoragePool(String uuid, StoragePoolInformation pool) {
+        synchronized (_storagePools) {
+            if (!_storagePools.containsKey(uuid)) {
+                _storagePools.put(uuid, pool);
+            }
+        }
+    }
+
+    public KVMStoragePoolManager(StorageLayer storagelayer, KVMHAMonitor monitor) {
+        this._haMonitor = monitor;
+        this._storageMapper.put("libvirt", new LibvirtStorageAdaptor(storagelayer));
+        // add other storage adaptors here
+        // this._storageMapper.put("newadaptor", new NewStorageAdaptor(storagelayer));
+        this._storageMapper.put(StoragePoolType.ManagedNFS.toString(), new ManagedNfsStorageAdaptor(storagelayer));
+
+        // add any adaptors that wish to register themselves via annotation
+        Reflections reflections = new Reflections("com.cloud.hypervisor.kvm.storage");
+        Set<Class<? extends StorageAdaptor>> storageAdaptors = reflections.getSubTypesOf(StorageAdaptor.class);
+        for (Class<? extends StorageAdaptor> storageAdaptor : storageAdaptors) {
+            StorageAdaptorInfo info = storageAdaptor.getAnnotation(StorageAdaptorInfo.class);
+            if (info != null && info.storagePoolType() != null) {
+                if (this._storageMapper.containsKey(info.storagePoolType().toString())) {
+                    s_logger.error("Duplicate StorageAdaptor type " + info.storagePoolType().toString() + ", not loading " + storageAdaptor.getName());
+                } else {
+                    try {
+                        this._storageMapper.put(info.storagePoolType().toString(), storageAdaptor.newInstance());
+                    } catch (Exception ex) {
+                       throw new CloudRuntimeException(ex.toString());
+                    }
+                }
+            }
+        }
+
+        for (Map.Entry<String, StorageAdaptor> adaptors : this._storageMapper.entrySet()) {
+            s_logger.debug("Registered a StorageAdaptor for " + adaptors.getKey());
+        }
+    }
+
+    public boolean connectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath, Map<String, String> details) {
+        StorageAdaptor adaptor = getStorageAdaptor(type);
+        KVMStoragePool pool = adaptor.getStoragePool(poolUuid);
+
+        return adaptor.connectPhysicalDisk(volPath, pool, details);
+    }
+
+    public boolean connectPhysicalDisksViaVmSpec(VirtualMachineTO vmSpec) {
+        boolean result = false;
+
+        final String vmName = vmSpec.getName();
+
+        List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
+
+        for (DiskTO disk : disks) {
+            if (disk.getType() == Volume.Type.ISO) {
+                result = true;
+                continue;
+            }
+
+            VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
+            PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore();
+            if (!store.isManaged() && VirtualMachine.State.Migrating.equals(vmSpec.getState())) {
+                result = true;
+                continue;
+            }
+
+            KVMStoragePool pool = getStoragePool(store.getPoolType(), store.getUuid());
+            StorageAdaptor adaptor = getStorageAdaptor(pool.getType());
+
+            result = adaptor.connectPhysicalDisk(vol.getPath(), pool, disk.getDetails());
+
+            if (!result) {
+                s_logger.error("Failed to connect disks via vm spec for vm: " + vmName + " volume:" + vol.toString());
+                return result;
+            }
+        }
+
+        return result;
+    }
+
+    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
+        for (Map.Entry<String, StorageAdaptor> set : _storageMapper.entrySet()) {
+            StorageAdaptor adaptor = set.getValue();
+
+            if (adaptor.disconnectPhysicalDisk(volumeToDisconnect)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean disconnectPhysicalDiskByPath(String path) {
+        for (Map.Entry<String, StorageAdaptor> set : _storageMapper.entrySet()) {
+            StorageAdaptor adaptor = set.getValue();
+
+            if (adaptor.disconnectPhysicalDiskByPath(path)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean disconnectPhysicalDisksViaVmSpec(VirtualMachineTO vmSpec) {
+        if (vmSpec == null) {
+            /* CloudStack often tries to stop VMs that shouldn't be running, to ensure a known state,
+               for example if we lose communication with the agent and the VM is brought up elsewhere.
+               We may not know about these yet. This might mean that we can't use the vmspec map, because
+               when we restart the agent we lose all of the info about running VMs. */
+
+            s_logger.debug("disconnectPhysicalDiskViaVmSpec: Attempted to stop a VM that is not yet in our hash map");
+
+            return true;
+        }
+
+        boolean result = true;
+
+        final String vmName = vmSpec.getName();
+
+        List<DiskTO> disks = Arrays.asList(vmSpec.getDisks());
+
+        for (DiskTO disk : disks) {
+            if (disk.getType() != Volume.Type.ISO) {
+                s_logger.debug("Disconnecting disk " + disk.getPath());
+
+                VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
+                PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore();
+
+                KVMStoragePool pool = getStoragePool(store.getPoolType(), store.getUuid());
+
+                if (pool == null) {
+                    s_logger.error("Pool " + store.getUuid() + " of type " + store.getPoolType() + " was not found, skipping disconnect logic");
+                    continue;
+                }
+
+                StorageAdaptor adaptor = getStorageAdaptor(pool.getType());
+
+                // if a disk fails to disconnect, still try to disconnect remaining
+
+                boolean subResult = adaptor.disconnectPhysicalDisk(vol.getPath(), pool);
+
+                if (!subResult) {
+                    s_logger.error("Failed to disconnect disks via vm spec for vm: " + vmName + " volume:" + vol.toString());
+
+                    result = false;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
+        return this.getStoragePool(type, uuid, false);
+    }
+
+    public KVMStoragePool getStoragePool(StoragePoolType type, String uuid, boolean refreshInfo) {
+
+        StorageAdaptor adaptor = getStorageAdaptor(type);
+        KVMStoragePool pool = null;
+        try {
+            pool = adaptor.getStoragePool(uuid, refreshInfo);
+        } catch (Exception e) {
+            StoragePoolInformation info = _storagePools.get(uuid);
+            if (info != null) {
+                pool = createStoragePool(info.name, info.host, info.port, info.path, info.userInfo, info.poolType, info.type);
+            } else {
+                throw new CloudRuntimeException("Could not fetch storage pool " + uuid + " from libvirt");
+            }
+        }
+        return pool;
+    }
+
+    public KVMStoragePool getStoragePoolByURI(String uri) {
+        URI storageUri = null;
+
+        try {
+            storageUri = new URI(uri);
+        } catch (URISyntaxException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+
+        String sourcePath = null;
+        String uuid = null;
+        String sourceHost = "";
+        StoragePoolType protocol = null;
+        if (storageUri.getScheme().equalsIgnoreCase("nfs") || storageUri.getScheme().equalsIgnoreCase("NetworkFilesystem")) {
+            sourcePath = storageUri.getPath();
+            sourcePath = sourcePath.replace("//", "/");
+            sourceHost = storageUri.getHost();
+            uuid = UUID.nameUUIDFromBytes(new String(sourceHost + sourcePath).getBytes()).toString();
+            protocol = StoragePoolType.NetworkFilesystem;
+        }
+
+        // secondary storage registers itself through here
+        return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocol, false);
+    }
+
+    public KVMPhysicalDisk getPhysicalDisk(StoragePoolType type, String poolUuid, String volName) {
+        int cnt = 0;
+        int retries = 10;
+        KVMPhysicalDisk vol = null;
+        //harden get volume, try cnt times to get volume, in case volume is created on other host
+        String errMsg = "";
+        while (cnt < retries) {
+            try {
+                KVMStoragePool pool = getStoragePool(type, poolUuid);
+                vol = pool.getPhysicalDisk(volName);
+                if (vol != null) {
+                    break;
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to find volume:" + volName + " due to" + e.toString() + ", retry:" + cnt);
+                errMsg = e.toString();
+            }
+
+            try {
+                Thread.sleep(30000);
+            } catch (InterruptedException e) {
+                s_logger.debug("[ignored] interupted while trying to get storage pool.");
+            }
+            cnt++;
+        }
+
+        if (vol == null) {
+            throw new CloudRuntimeException(errMsg);
+        } else {
+            return vol;
+        }
+
+    }
+
+    public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type) {
+        // primary storage registers itself through here
+        return createStoragePool(name, host, port, path, userInfo, type, true);
+    }
+
+    //Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced.
+    private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, boolean primaryStorage) {
+        StorageAdaptor adaptor = getStorageAdaptor(type);
+        KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type);
+
+        // LibvirtStorageAdaptor-specific statement
+        if (type == StoragePoolType.NetworkFilesystem && primaryStorage) {
+            KVMHABase.NfsStoragePool nfspool = new KVMHABase.NfsStoragePool(pool.getUuid(), host, path, pool.getLocalPath(), PoolType.PrimaryStorage);
+            _haMonitor.addStoragePool(nfspool);
+        }
+        StoragePoolInformation info = new StoragePoolInformation(name, host, port, path, userInfo, type, primaryStorage);
+        addStoragePool(pool.getUuid(), info);
+        return pool;
+    }
+
+    public boolean disconnectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath) {
+        StorageAdaptor adaptor = getStorageAdaptor(type);
+        KVMStoragePool pool = adaptor.getStoragePool(poolUuid);
+
+        return adaptor.disconnectPhysicalDisk(volPath, pool);
+    }
+
+    public boolean deleteStoragePool(StoragePoolType type, String uuid) {
+        StorageAdaptor adaptor = getStorageAdaptor(type);
+        _haMonitor.removeStoragePool(uuid);
+        adaptor.deleteStoragePool(uuid);
+        synchronized (_storagePools) {
+            _storagePools.remove(uuid);
+        }
+        return true;
+    }
+
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, Storage.ProvisioningType provisioningType,
+                                                    KVMStoragePool destPool, int timeout) {
+        return createDiskFromTemplate(template, name, provisioningType, destPool, template.getSize(), timeout);
+    }
+
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, Storage.ProvisioningType provisioningType,
+                                                    KVMStoragePool destPool, long size, int timeout) {
+        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
+
+        // LibvirtStorageAdaptor-specific statement
+        if (destPool.getType() == StoragePoolType.RBD) {
+            return adaptor.createDiskFromTemplate(template, name,
+                    PhysicalDiskFormat.RAW, provisioningType,
+                    size, destPool, timeout);
+        } else if (destPool.getType() == StoragePoolType.CLVM) {
+            return adaptor.createDiskFromTemplate(template, name,
+                    PhysicalDiskFormat.RAW, provisioningType,
+                    size, destPool, timeout);
+        } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
+            return adaptor.createDiskFromTemplate(template, name,
+                    PhysicalDiskFormat.DIR, provisioningType,
+                    size, destPool, timeout);
+        } else {
+            return adaptor.createDiskFromTemplate(template, name,
+                    PhysicalDiskFormat.QCOW2, provisioningType,
+                    size, destPool, timeout);
+        }
+    }
+
+    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
+        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
+        return adaptor.createTemplateFromDisk(disk, name, format, size, destPool);
+    }
+
+    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
+        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
+        return adaptor.copyPhysicalDisk(disk, name, destPool, timeout);
+    }
+
+    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
+        StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
+        return adaptor.createDiskFromSnapshot(snapshot, snapshotName, name, destPool);
+    }
+
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
new file mode 100644
index 0000000..83a7a12
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -0,0 +1,1688 @@
+/*
+ * 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.storage;
+
+import static com.cloud.utils.storage.S3.S3Utils.putFile;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.direct.download.DirectTemplateDownloader;
+import com.cloud.agent.direct.download.DirectTemplateDownloader.DirectTemplateInformation;
+import com.cloud.agent.direct.download.HttpDirectTemplateDownloader;
+import com.cloud.agent.direct.download.MetalinkDirectTemplateDownloader;
+import com.cloud.agent.direct.download.NfsDirectTemplateDownloader;
+import com.cloud.agent.direct.download.HttpsDirectTemplateDownloader;
+import com.cloud.exception.InvalidParameterValueException;
+import org.apache.cloudstack.agent.directdownload.HttpsDirectDownloadCommand;
+import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
+import org.apache.cloudstack.agent.directdownload.HttpDirectDownloadCommand;
+import org.apache.cloudstack.agent.directdownload.MetalinkDirectDownloadCommand;
+import org.apache.cloudstack.agent.directdownload.NfsDirectDownloadCommand;
+import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachAnswer;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.ResignatureAnswer;
+import org.apache.cloudstack.storage.command.ResignatureCommand;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainSnapshot;
+import org.libvirt.LibvirtException;
+
+import com.ceph.rados.IoCTX;
+import com.ceph.rados.Rados;
+import com.ceph.rados.exceptions.ErrorCode;
+import com.ceph.rados.exceptions.RadosException;
+import com.ceph.rbd.Rbd;
+import com.ceph.rbd.RbdException;
+import com.ceph.rbd.RbdImage;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DeviceType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiscardType;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiskProtocol;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.resource.StorageProcessor;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.storage.S3.S3Utils;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+public class KVMStorageProcessor implements StorageProcessor {
+    private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class);
+    private final KVMStoragePoolManager storagePoolMgr;
+    private final LibvirtComputingResource resource;
+    private StorageLayer storageLayer;
+    private String _createTmplPath;
+    private String _manageSnapshotPath;
+    private int _cmdsTimeout;
+
+    public KVMStorageProcessor(final KVMStoragePoolManager storagePoolMgr, final LibvirtComputingResource resource) {
+        this.storagePoolMgr = storagePoolMgr;
+        this.resource = resource;
+    }
+
+    protected String getDefaultStorageScriptsDir() {
+        return "scripts/storage/qcow2";
+    }
+
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        storageLayer = new JavaStorageLayer();
+        storageLayer.configure("StorageLayer", params);
+
+        String storageScriptsDir = (String)params.get("storage.scripts.dir");
+        if (storageScriptsDir == null) {
+            storageScriptsDir = getDefaultStorageScriptsDir();
+        }
+
+        _createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh");
+        if (_createTmplPath == null) {
+            throw new ConfigurationException("Unable to find the createtmplt.sh");
+        }
+
+        _manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh");
+        if (_manageSnapshotPath == null) {
+            throw new ConfigurationException("Unable to find the managesnapshot.sh");
+        }
+
+        final String value = (String)params.get("cmds.timeout");
+        _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000;
+        return true;
+    }
+
+    @Override
+    public SnapshotAndCopyAnswer snapshotAndCopy(final SnapshotAndCopyCommand cmd) {
+        s_logger.info("'SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand)' not currently used for KVMStorageProcessor");
+
+        return new SnapshotAndCopyAnswer();
+    }
+
+    @Override
+    public ResignatureAnswer resignature(final ResignatureCommand cmd) {
+        s_logger.info("'ResignatureAnswer resignature(ResignatureCommand)' not currently used for KVMStorageProcessor");
+
+        return new ResignatureAnswer();
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final TemplateObjectTO template = (TemplateObjectTO)srcData;
+        final DataStoreTO imageStore = template.getDataStore();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destData.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        final NfsTO nfsImageStore = (NfsTO)imageStore;
+        final String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath();
+        final int index = tmplturl.lastIndexOf("/");
+        final String mountpoint = tmplturl.substring(0, index);
+        String tmpltname = null;
+        if (index < tmplturl.length() - 1) {
+            tmpltname = tmplturl.substring(index + 1);
+        }
+
+        KVMPhysicalDisk tmplVol = null;
+        KVMStoragePool secondaryPool = null;
+        try {
+            secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
+
+            /* Get template vol */
+            if (tmpltname == null) {
+                secondaryPool.refresh();
+                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
+                if (disks == null || disks.isEmpty()) {
+                    return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid());
+                }
+                for (final KVMPhysicalDisk disk : disks) {
+                    if (disk.getName().endsWith("qcow2")) {
+                        tmplVol = disk;
+                        break;
+                    }
+                }
+            } else {
+                tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
+            }
+
+            if (tmplVol == null) {
+                return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
+            }
+
+            /* Copy volume to primary storage */
+            s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
+            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+
+            KVMPhysicalDisk primaryVol = null;
+            if (destData instanceof VolumeObjectTO) {
+                final VolumeObjectTO volume = (VolumeObjectTO)destData;
+                // pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
+                if (volume.getSize() != null && volume.getSize() > tmplVol.getVirtualSize()) {
+                    s_logger.debug("Using configured size of " + volume.getSize());
+                    tmplVol.setSize(volume.getSize());
+                    tmplVol.setVirtualSize(volume.getSize());
+                } else {
+                    s_logger.debug("Using template's size of " + tmplVol.getVirtualSize());
+                }
+                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
+            } else if (destData instanceof TemplateObjectTO) {
+                TemplateObjectTO destTempl = (TemplateObjectTO)destData;
+
+                Map<String, String> details = primaryStore.getDetails();
+
+                String path = details != null ? details.get("managedStoreTarget") : null;
+
+                storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
+
+                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
+
+                storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
+            } else {
+                primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, cmd.getWaitInMillSeconds());
+            }
+
+            DataTO data = null;
+            /**
+             * Force the ImageFormat for RBD templates to RAW
+             *
+             */
+            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+                final TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(primaryVol.getName());
+                newTemplate.setSize(primaryVol.getSize());
+                if (primaryPool.getType() == StoragePoolType.RBD) {
+                    newTemplate.setFormat(ImageFormat.RAW);
+                } else {
+                    newTemplate.setFormat(ImageFormat.QCOW2);
+                }
+                data = newTemplate;
+            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
+                final VolumeObjectTO volumeObjectTO = new VolumeObjectTO();
+                volumeObjectTO.setPath(primaryVol.getName());
+                volumeObjectTO.setSize(primaryVol.getSize());
+                if (primaryVol.getFormat() == PhysicalDiskFormat.RAW) {
+                    volumeObjectTO.setFormat(ImageFormat.RAW);
+                } else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
+                    volumeObjectTO.setFormat(ImageFormat.QCOW2);
+                }
+                data = volumeObjectTO;
+            }
+            return new CopyCmdAnswer(data);
+        } catch (final CloudRuntimeException e) {
+            return new CopyCmdAnswer(e.toString());
+        } finally {
+            try {
+                if (secondaryPool != null) {
+                    secondaryPool.delete();
+                }
+            } catch(final Exception e) {
+                s_logger.debug("Failed to clean up secondary storage", e);
+            }
+        }
+    }
+
+    // this is much like PrimaryStorageDownloadCommand, but keeping it separate. copies template direct to root disk
+    private KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid, final Long size, final int timeout) {
+        final int index = templateUrl.lastIndexOf("/");
+        final String mountpoint = templateUrl.substring(0, index);
+        String templateName = null;
+        if (index < templateUrl.length() - 1) {
+            templateName = templateUrl.substring(index + 1);
+        }
+
+        KVMPhysicalDisk templateVol = null;
+        KVMStoragePool secondaryPool = null;
+        try {
+            secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
+            /* Get template vol */
+            if (templateName == null) {
+                secondaryPool.refresh();
+                final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
+                if (disks == null || disks.isEmpty()) {
+                    s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
+                    return null;
+                }
+                for (final KVMPhysicalDisk disk : disks) {
+                    if (disk.getName().endsWith("qcow2")) {
+                        templateVol = disk;
+                        break;
+                    }
+                }
+                if (templateVol == null) {
+                    s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
+                    return null;
+                }
+            } else {
+                templateVol = secondaryPool.getPhysicalDisk(templateName);
+            }
+
+            /* Copy volume to primary storage */
+
+            if (size > templateVol.getSize()) {
+                s_logger.debug("Overriding provided template's size with new size " + size);
+                templateVol.setSize(size);
+                templateVol.setVirtualSize(size);
+            } else {
+                s_logger.debug("Using templates disk size of " + templateVol.getVirtualSize() + "since size passed was " + size);
+            }
+
+            final KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
+            return primaryVol;
+        } catch (final CloudRuntimeException e) {
+            s_logger.error("Failed to download template to primary storage", e);
+            return null;
+        } finally {
+            if (secondaryPool != null) {
+                secondaryPool.delete();
+            }
+        }
+    }
+
+    @Override
+    public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final TemplateObjectTO template = (TemplateObjectTO)srcData;
+        final DataStoreTO imageStore = template.getDataStore();
+        final VolumeObjectTO volume = (VolumeObjectTO)destData;
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
+        KVMPhysicalDisk BaseVol = null;
+        KVMStoragePool primaryPool = null;
+        KVMPhysicalDisk vol = null;
+
+        try {
+            primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+
+            String templatePath = template.getPath();
+
+            if (primaryPool.getType() == StoragePoolType.CLVM) {
+                templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
+                vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
+            } else {
+                if (templatePath.contains("/mnt")) {
+                    //upgrade issue, if the path contains path, need to extract the volume uuid from path
+                    templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
+                }
+                BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
+                vol = storagePoolMgr.createDiskFromTemplate(BaseVol, volume.getUuid(), volume.getProvisioningType(),
+                        BaseVol.getPool(), volume.getSize(), cmd.getWaitInMillSeconds());
+            }
+            if (vol == null) {
+                return new CopyCmdAnswer(" Can't create storage volume on storage pool");
+            }
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(vol.getName());
+            newVol.setSize(volume.getSize());
+
+            if (vol.getFormat() == PhysicalDiskFormat.RAW) {
+                newVol.setFormat(ImageFormat.RAW);
+            } else if (vol.getFormat() == PhysicalDiskFormat.QCOW2) {
+                newVol.setFormat(ImageFormat.QCOW2);
+            } else if (vol.getFormat() == PhysicalDiskFormat.DIR) {
+                newVol.setFormat(ImageFormat.DIR);
+            }
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to create volume: ", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final DataStoreTO srcStore = srcData.getDataStore();
+        final DataStoreTO destStore = destData.getDataStore();
+        final VolumeObjectTO srcVol = (VolumeObjectTO)srcData;
+        final ImageFormat srcFormat = srcVol.getFormat();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destStore;
+        if (!(srcStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("can only handle nfs storage");
+        }
+        final NfsTO nfsStore = (NfsTO)srcStore;
+        final String srcVolumePath = srcData.getPath();
+        final String secondaryStorageUrl = nfsStore.getUrl();
+        KVMStoragePool secondaryStoragePool = null;
+        KVMStoragePool primaryPool = null;
+        try {
+            try {
+                primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+            } catch (final CloudRuntimeException e) {
+                if (e.getMessage().contains("not found")) {
+                    primaryPool =
+                            storagePoolMgr.createStoragePool(primaryStore.getUuid(), primaryStore.getHost(), primaryStore.getPort(), primaryStore.getPath(), null,
+                                    primaryStore.getPoolType());
+                } else {
+                    return new CopyCmdAnswer(e.getMessage());
+                }
+            }
+
+            Map<String, String> details = cmd.getOptions2();
+
+            String path = details != null ? details.get(DiskTO.IQN) : null;
+
+            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
+
+            final String volumeName = UUID.randomUUID().toString();
+
+            final int index = srcVolumePath.lastIndexOf(File.separator);
+            final String volumeDir = srcVolumePath.substring(0, index);
+            String srcVolumeName = srcVolumePath.substring(index + 1);
+
+            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + File.separator + volumeDir);
+
+            if (!srcVolumeName.endsWith(".qcow2") && srcFormat == ImageFormat.QCOW2) {
+                srcVolumeName = srcVolumeName + ".qcow2";
+            }
+
+            final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(srcVolumeName);
+
+            volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
+
+            final KVMPhysicalDisk newDisk = storagePoolMgr.copyPhysicalDisk(volume, path != null ? path : volumeName, primaryPool, cmd.getWaitInMillSeconds());
+
+            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+
+            newVol.setFormat(ImageFormat.valueOf(newDisk.getFormat().toString().toUpperCase()));
+            newVol.setPath(path != null ? path : volumeName);
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to copyVolumeFromImageCacheToPrimary: ", e);
+
+            return new CopyCmdAnswer(e.toString());
+        } finally {
+            if (secondaryStoragePool != null) {
+                storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
+            }
+        }
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final VolumeObjectTO srcVol = (VolumeObjectTO)srcData;
+        final VolumeObjectTO destVol = (VolumeObjectTO)destData;
+        final ImageFormat srcFormat = srcVol.getFormat();
+        final ImageFormat destFormat = destVol.getFormat();
+        final DataStoreTO srcStore = srcData.getDataStore();
+        final DataStoreTO destStore = destData.getDataStore();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcStore;
+        if (!(destStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("can only handle nfs storage");
+        }
+        final NfsTO nfsStore = (NfsTO)destStore;
+        final String srcVolumePath = srcData.getPath();
+        final String destVolumePath = destData.getPath();
+        final String secondaryStorageUrl = nfsStore.getUrl();
+        KVMStoragePool secondaryStoragePool = null;
+
+        try {
+            final String volumeName = UUID.randomUUID().toString();
+
+            final String destVolumeName = volumeName + "." + destFormat.getFileExtension();
+            final KVMPhysicalDisk volume = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), srcVolumePath);
+            volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
+
+            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl);
+            secondaryStoragePool.createFolder(destVolumePath);
+            storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
+            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + File.separator + destVolumePath);
+            storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, secondaryStoragePool, cmd.getWaitInMillSeconds());
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(destVolumePath + File.separator + destVolumeName);
+            newVol.setFormat(destFormat);
+            return new CopyCmdAnswer(newVol);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to copyVolumeFromPrimaryToSecondary: ", e);
+            return new CopyCmdAnswer(e.toString());
+        } finally {
+            if (secondaryStoragePool != null) {
+                storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid());
+            }
+        }
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(final CopyCommand cmd) {
+        Map<String, String> details = cmd.getOptions();
+
+        if (details != null && details.get(DiskTO.IQN) != null) {
+            // use the managed-storage approach
+            return createTemplateFromVolumeOrSnapshot(cmd);
+        }
+
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWaitInMillSeconds();
+        final TemplateObjectTO template = (TemplateObjectTO)destData;
+        final DataStoreTO imageStore = template.getDataStore();
+        final VolumeObjectTO volume = (VolumeObjectTO)srcData;
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+        final NfsTO nfsImageStore = (NfsTO)imageStore;
+
+        KVMStoragePool secondaryStorage = null;
+        KVMStoragePool primary;
+
+        try {
+            final String templateFolder = template.getPath();
+
+            secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl());
+
+            primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+
+            final KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
+            final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder;
+            storageLayer.mkdirs(tmpltPath);
+            final String templateName = UUID.randomUUID().toString();
+
+            if (primary.getType() != StoragePoolType.RBD) {
+                final Script command = new Script(_createTmplPath, wait, s_logger);
+                command.add("-f", disk.getPath());
+                command.add("-t", tmpltPath);
+                command.add("-n", templateName + ".qcow2");
+
+                final String result = command.execute();
+
+                if (result != null) {
+                    s_logger.debug("failed to create template: " + result);
+                    return new CopyCmdAnswer(result);
+                }
+            } else {
+                s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + templateName);
+
+                final QemuImgFile srcFile =
+                        new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(),
+                                primary.getAuthSecret(), disk.getPath()));
+                srcFile.setFormat(PhysicalDiskFormat.RAW);
+
+                final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2");
+                destFile.setFormat(PhysicalDiskFormat.QCOW2);
+
+                final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
+                try {
+                    q.convert(srcFile, destFile);
+                } catch (final QemuImgException e) {
+                    final String message = "Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " +
+                            e.getMessage();
+
+                    throw new QemuImgException(message);
+                }
+
+                final File templateProp = new File(tmpltPath + "/template.properties");
+                if (!templateProp.exists()) {
+                    templateProp.createNewFile();
+                }
+
+                String templateContent = "filename=" + templateName + ".qcow2" + System.getProperty("line.separator");
+
+                final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
+                final Date date = new Date();
+                templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
+
+
+                try(FileOutputStream templFo = new FileOutputStream(templateProp);){
+                    templFo.write(templateContent.getBytes());
+                    templFo.flush();
+                } catch (final IOException e) {
+                    throw e;
+                }
+            }
+
+            final Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, storageLayer);
+            final Processor qcow2Processor = new QCOW2Processor();
+
+            qcow2Processor.configure("QCOW2 Processor", params);
+
+            final FormatInfo info = qcow2Processor.process(tmpltPath, null, templateName);
+
+            final TemplateLocation loc = new TemplateLocation(storageLayer, tmpltPath);
+            loc.create(1, true, templateName);
+            loc.addFormat(info);
+            loc.save();
+
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
+            newTemplate.setSize(info.virtualSize);
+            newTemplate.setPhysicalSize(info.size);
+            newTemplate.setFormat(ImageFormat.QCOW2);
+            newTemplate.setName(templateName);
+            return new CopyCmdAnswer(newTemplate);
+
+        } catch (final QemuImgException e) {
+            s_logger.error(e.getMessage());
+            return new CopyCmdAnswer(e.toString());
+        } catch (final IOException e) {
+            s_logger.debug("Failed to createTemplateFromVolume: ", e);
+            return new CopyCmdAnswer(e.toString());
+        } catch (final Exception e) {
+            s_logger.debug("Failed to createTemplateFromVolume: ", e);
+            return new CopyCmdAnswer(e.toString());
+        } finally {
+            if (secondaryStorage != null) {
+                secondaryStorage.delete();
+            }
+        }
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        Map<String, String> details = cmd.getOptions();
+
+        if (details != null && details.get(DiskTO.IQN) != null) {
+            // use the managed-storage approach
+            return createTemplateFromVolumeOrSnapshot(cmd);
+        }
+
+        return new CopyCmdAnswer("operation not supported");
+    }
+
+    private Answer createTemplateFromVolumeOrSnapshot(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+
+        final boolean isVolume;
+
+        if (srcData instanceof VolumeObjectTO) {
+            isVolume = true;
+        }
+        else if (srcData instanceof SnapshotObjectTO) {
+            isVolume = false;
+        }
+        else {
+            return new CopyCmdAnswer("unsupported object type");
+        }
+
+        PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore();
+
+        DataTO destData = cmd.getDestTO();
+        TemplateObjectTO template = (TemplateObjectTO)destData;
+        DataStoreTO imageStore = template.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+
+        KVMStoragePool secondaryStorage = null;
+
+        try {
+            Map<String, String> details = cmd.getOptions();
+
+            String path = details != null ? details.get(DiskTO.IQN) : null;
+
+            if (path == null) {
+                new CloudRuntimeException("The 'path' field must be specified.");
+            }
+
+            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details);
+
+            KVMPhysicalDisk srcDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
+
+            secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl());
+
+            String templateFolder = template.getPath();
+            String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder;
+
+            storageLayer.mkdirs(tmpltPath);
+
+            String templateName = UUID.randomUUID().toString();
+
+            s_logger.debug("Converting " + srcDisk.getFormat().toString() + " disk " + srcDisk.getPath() + " into template " + templateName);
+
+            String destName = templateFolder + "/" + templateName + ".qcow2";
+
+            storagePoolMgr.copyPhysicalDisk(srcDisk, destName, secondaryStorage, cmd.getWaitInMillSeconds());
+
+            File templateProp = new File(tmpltPath + "/template.properties");
+
+            if (!templateProp.exists()) {
+                templateProp.createNewFile();
+            }
+
+            String templateContent = "filename=" + templateName + ".qcow2" + System.getProperty("line.separator");
+
+            DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy");
+            Date date = new Date();
+
+            if (isVolume) {
+                templateContent += "volume.name=" + dateFormat.format(date) + System.getProperty("line.separator");
+            }
+            else {
+                templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
+            }
+
+            FileOutputStream templFo = new FileOutputStream(templateProp);
+
+            templFo.write(templateContent.getBytes());
+            templFo.flush();
+            templFo.close();
+
+            Map<String, Object> params = new HashMap<>();
+
+            params.put(StorageLayer.InstanceConfigKey, storageLayer);
+
+            Processor qcow2Processor = new QCOW2Processor();
+
+            qcow2Processor.configure("QCOW2 Processor", params);
+
+            FormatInfo info = qcow2Processor.process(tmpltPath, null, templateName);
+
+            TemplateLocation loc = new TemplateLocation(storageLayer, tmpltPath);
+
+            loc.create(1, true, templateName);
+            loc.addFormat(info);
+            loc.save();
+
+            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
+            newTemplate.setSize(info.virtualSize);
+            newTemplate.setPhysicalSize(info.size);
+            newTemplate.setFormat(ImageFormat.QCOW2);
+            newTemplate.setName(templateName);
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (Exception ex) {
+            if (isVolume) {
+                s_logger.debug("Failed to create template from volume: ", ex);
+            }
+            else {
+                s_logger.debug("Failed to create template from snapshot: ", ex);
+            }
+
+            return new CopyCmdAnswer(ex.toString());
+        } finally {
+            if (secondaryStorage != null) {
+                secondaryStorage.delete();
+            }
+        }
+    }
+
+    protected String copyToS3(final File srcFile, final S3TO destStore, final String destPath) throws InterruptedException {
+        final String key = destPath + S3Utils.SEPARATOR + srcFile.getName();
+
+        putFile(destStore, srcFile, destStore.getBucketName(), key).waitForCompletion();
+
+        return key;
+    }
+
+    protected Answer copyToObjectStore(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final DataStoreTO imageStore = destData.getDataStore();
+        final NfsTO srcStore = (NfsTO)srcData.getDataStore();
+        final String srcPath = srcData.getPath();
+        final int index = srcPath.lastIndexOf(File.separator);
+        final String srcSnapshotDir = srcPath.substring(0, index);
+        final String srcFileName = srcPath.substring(index + 1);
+        KVMStoragePool srcStorePool = null;
+        File srcFile = null;
+        try {
+            srcStorePool = storagePoolMgr.getStoragePoolByURI(srcStore.getUrl() + File.separator + srcSnapshotDir);
+            if (srcStorePool == null) {
+                return new CopyCmdAnswer("Can't get store:" + srcStore.getUrl());
+            }
+            srcFile = new File(srcStorePool.getLocalPath() + File.separator + srcFileName);
+            if (!srcFile.exists()) {
+                return new CopyCmdAnswer("Can't find src file: " + srcPath);
+            }
+            String destPath = null;
+            if (imageStore instanceof S3TO) {
+                destPath = copyToS3(srcFile, (S3TO)imageStore, destData.getPath());
+            } else {
+                return new CopyCmdAnswer("Unsupported protocol");
+            }
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(destPath);
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (final Exception e) {
+            s_logger.error("failed to upload" + srcPath, e);
+            return new CopyCmdAnswer("failed to upload" + srcPath + e.toString());
+        } finally {
+            try {
+                if (srcFile != null) {
+                    srcFile.delete();
+                }
+                if (srcStorePool != null) {
+                    srcStorePool.delete();
+                }
+            } catch (final Exception e) {
+                s_logger.debug("Failed to clean up:", e);
+            }
+        }
+    }
+
+    protected Answer backupSnapshotForObjectStore(final CopyCommand cmd) {
+        final DataTO destData = cmd.getDestTO();
+        final DataStoreTO imageStore = destData.getDataStore();
+        final DataTO cacheData = cmd.getCacheTO();
+        if (cacheData == null) {
+            return new CopyCmdAnswer("Failed to copy to object store without cache store");
+        }
+        final DataStoreTO cacheStore = cacheData.getDataStore();
+        ((SnapshotObjectTO)destData).setDataStore(cacheStore);
+        final CopyCmdAnswer answer = (CopyCmdAnswer)backupSnapshot(cmd);
+        if (!answer.getResult()) {
+            return answer;
+        }
+        final SnapshotObjectTO snapshotOnCacheStore = (SnapshotObjectTO)answer.getNewData();
+        snapshotOnCacheStore.setDataStore(cacheStore);
+        ((SnapshotObjectTO)destData).setDataStore(imageStore);
+        final CopyCommand newCpyCmd = new   CopyCommand(snapshotOnCacheStore, destData, cmd.getWaitInMillSeconds(), cmd.executeInSequence());
+        return copyToObjectStore(newCpyCmd);
+    }
+
+    @Override
+    public Answer backupSnapshot(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshot.getDataStore();
+        final SnapshotObjectTO destSnapshot = (SnapshotObjectTO)destData;
+        final DataStoreTO imageStore = destData.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return backupSnapshotForObjectStore(cmd);
+        }
+        final NfsTO nfsImageStore = (NfsTO)imageStore;
+
+        final String secondaryStoragePoolUrl = nfsImageStore.getUrl();
+        // NOTE: snapshot name is encoded in snapshot path
+        final int index = snapshot.getPath().lastIndexOf("/");
+        final boolean isCreatedFromVmSnapshot = (index == -1) ? true: false; // -1 means the snapshot is created from existing vm snapshot
+
+        final String snapshotName = snapshot.getPath().substring(index + 1);
+        String descName = snapshotName;
+        final String volumePath = snapshot.getVolume().getPath();
+        String snapshotDestPath = null;
+        String snapshotRelPath = null;
+        final String vmName = snapshot.getVmName();
+        KVMStoragePool secondaryStoragePool = null;
+        Connect conn = null;
+        KVMPhysicalDisk snapshotDisk = null;
+        KVMStoragePool primaryPool = null;
+        try {
+            conn = LibvirtConnection.getConnectionByVmName(vmName);
+
+            secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
+
+            final String ssPmountPath = secondaryStoragePool.getLocalPath();
+            snapshotRelPath = destSnapshot.getPath();
+
+            snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
+            snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
+            primaryPool = snapshotDisk.getPool();
+
+            long size = 0;
+            /**
+             * Since Ceph version Dumpling (0.67.X) librbd / Qemu supports converting RBD
+             * snapshots to RAW/QCOW2 files directly.
+             *
+             * This reduces the amount of time and storage it takes to back up a snapshot dramatically
+             */
+            if (primaryPool.getType() == StoragePoolType.RBD) {
+                final String rbdSnapshot = snapshotDisk.getPath() +  "@" + snapshotName;
+                final String snapshotFile = snapshotDestPath + "/" + snapshotName;
+                try {
+                    s_logger.debug("Attempting to backup RBD snapshot " + rbdSnapshot);
+
+                    final File snapDir = new File(snapshotDestPath);
+                    s_logger.debug("Attempting to create " + snapDir.getAbsolutePath() + " recursively for snapshot storage");
+                    FileUtils.forceMkdir(snapDir);
+
+                    final QemuImgFile srcFile =
+                            new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool.getSourceHost(), primaryPool.getSourcePort(), primaryPool.getAuthUserName(),
+                                    primaryPool.getAuthSecret(), rbdSnapshot));
+                    srcFile.setFormat(snapshotDisk.getFormat());
+
+                    final QemuImgFile destFile = new QemuImgFile(snapshotFile);
+                    destFile.setFormat(PhysicalDiskFormat.QCOW2);
+
+                    s_logger.debug("Backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile);
+                    final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
+                    q.convert(srcFile, destFile);
+
+                    final File snapFile = new File(snapshotFile);
+                    if(snapFile.exists()) {
+                        size = snapFile.length();
+                    }
+
+                    s_logger.debug("Finished backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile + " Snapshot size: " + size);
+                } catch (final FileNotFoundException e) {
+                    s_logger.error("Failed to open " + snapshotDestPath + ". The error was: " + e.getMessage());
+                    return new CopyCmdAnswer(e.toString());
+                } catch (final IOException e) {
+                    s_logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
+                    return new CopyCmdAnswer(e.toString());
+                }  catch (final QemuImgException e) {
+                    s_logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot +
+                            " to " + snapshotFile + " the error was: " + e.getMessage());
+                    return new CopyCmdAnswer(e.toString());
+                }
+            } else {
+                final Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
+                command.add("-b", snapshotDisk.getPath());
+                command.add("-n", snapshotName);
+                command.add("-p", snapshotDestPath);
+                if (isCreatedFromVmSnapshot) {
+                    descName = UUID.randomUUID().toString();
+                }
+                command.add("-t", descName);
+                final String result = command.execute();
+                if (result != null) {
+                    s_logger.debug("Failed to backup snaptshot: " + result);
+                    return new CopyCmdAnswer(result);
+                }
+                final File snapFile = new File(snapshotDestPath + "/" + descName);
+                if(snapFile.exists()){
+                    size = snapFile.length();
+                }
+            }
+
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(snapshotRelPath + File.separator + descName);
+            newSnapshot.setPhysicalSize(size);
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to backup snapshot: ", e);
+            return new CopyCmdAnswer(e.toString());
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to backup snapshot: ", e);
+            return new CopyCmdAnswer(e.toString());
+        } finally {
+            if (isCreatedFromVmSnapshot) {
+                s_logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
+            } else {
+                try {
+                    /* Delete the snapshot on primary */
+                    DomainInfo.DomainState state = null;
+                    Domain vm = null;
+                    if (vmName != null) {
+                        try {
+                            vm = resource.getDomain(conn, vmName);
+                            state = vm.getInfo().state;
+                        } catch (final LibvirtException e) {
+                            s_logger.trace("Ignoring libvirt error.", e);
+                        }
+                    }
+
+                    final KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(primaryStore.getPoolType(),
+                            primaryStore.getUuid());
+                    if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
+                        final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
+                        snap.delete(0);
+
+                        /*
+                         * libvirt on RHEL6 doesn't handle resume event emitted from
+                         * qemu
+                         */
+                        vm = resource.getDomain(conn, vmName);
+                        state = vm.getInfo().state;
+                        if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
+                            vm.resume();
+                        }
+                    } else {
+                        if (primaryPool.getType() != StoragePoolType.RBD) {
+                            final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
+                            command.add("-d", snapshotDisk.getPath());
+                            command.add("-n", snapshotName);
+                            final String result = command.execute();
+                            if (result != null) {
+                                s_logger.debug("Failed to delete snapshot on primary: " + result);
+                                // return new CopyCmdAnswer("Failed to backup snapshot: " + result);
+                            }
+                        }
+                    }
+                } catch (final Exception ex) {
+                    s_logger.debug("Failed to delete snapshots on primary", ex);
+                }
+            }
+
+            try {
+                if (secondaryStoragePool != null) {
+                    secondaryStoragePool.delete();
+                }
+            } catch (final Exception ex) {
+                s_logger.debug("Failed to delete secondary storage", ex);
+            }
+        }
+    }
+
+    protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException,
+    InternalErrorException {
+        String isoXml = null;
+        if (isoPath != null && isAttach) {
+            final int index = isoPath.lastIndexOf("/");
+            final String path = isoPath.substring(0, index);
+            final String name = isoPath.substring(index + 1);
+            final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(path);
+            final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name);
+            isoPath = isoVol.getPath();
+
+            final DiskDef iso = new DiskDef();
+            iso.defISODisk(isoPath);
+            isoXml = iso.toString();
+        } else {
+            final DiskDef iso = new DiskDef();
+            iso.defISODisk(null);
+            isoXml = iso.toString();
+        }
+
+        final List<DiskDef> disks = resource.getDisks(conn, vmName);
+        final String result = attachOrDetachDevice(conn, true, vmName, isoXml);
+        if (result == null && !isAttach) {
+            for (final DiskDef disk : disks) {
+                if (disk.getDeviceType() == DiskDef.DeviceType.CDROM) {
+                    resource.cleanupDisk(disk);
+                }
+            }
+
+        }
+        return result;
+    }
+
+    @Override
+    public Answer attachIso(final AttachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData();
+        final DataStoreTO store = isoTO.getDataStore();
+
+        try {
+            String dataStoreUrl = getDataStoreUrlFromStore(store);
+            final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
+            attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), true);
+        } catch (final LibvirtException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final URISyntaxException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final InternalErrorException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final InvalidParameterValueException e) {
+            return new Answer(cmd, false, e.toString());
+        }
+
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer dettachIso(final DettachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData();
+        final DataStoreTO store = isoTO.getDataStore();
+
+        try {
+            String dataStoreUrl = getDataStoreUrlFromStore(store);
+            final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
+            attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), false);
+        } catch (final LibvirtException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final URISyntaxException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final InternalErrorException e) {
+            return new Answer(cmd, false, e.toString());
+        } catch (final InvalidParameterValueException e) {
+            return new Answer(cmd, false, e.toString());
+        }
+
+        return new Answer(cmd);
+    }
+
+    /**
+     * Return data store URL from store
+     */
+    private String getDataStoreUrlFromStore(DataStoreTO store) {
+        if (!(store instanceof NfsTO) && (!(store instanceof PrimaryDataStoreTO) ||
+                store instanceof PrimaryDataStoreTO && !((PrimaryDataStoreTO) store).getPoolType().equals(StoragePoolType.NetworkFilesystem))) {
+            throw new InvalidParameterValueException("unsupported protocol");
+        }
+
+        if (store instanceof NfsTO) {
+            NfsTO nfsStore = (NfsTO)store;
+            return nfsStore.getUrl();
+        } else if (store instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO) store).getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
+            //In order to support directly downloaded ISOs
+            String psHost = ((PrimaryDataStoreTO) store).getHost();
+            String psPath = ((PrimaryDataStoreTO) store).getPath();
+            return "nfs://" + psHost + File.separator + psPath;
+        }
+        return store.getUrl();
+    }
+
+    protected synchronized String attachOrDetachDevice(final Connect conn, final boolean attach, final String vmName, final String xml) throws LibvirtException, InternalErrorException {
+        Domain dm = null;
+        try {
+            dm = conn.domainLookupByName(vmName);
+
+            if (attach) {
+                s_logger.debug("Attaching device: " + xml);
+                dm.attachDevice(xml);
+            } else {
+                s_logger.debug("Detaching device: " + xml);
+                dm.detachDevice(xml);
+            }
+        } catch (final LibvirtException e) {
+            if (attach) {
+                s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage());
+            } else {
+                s_logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage());
+            }
+            throw e;
+        } finally {
+            if (dm != null) {
+                try {
+                    dm.free();
+                } catch (final LibvirtException l) {
+                    s_logger.trace("Ignoring libvirt error.", l);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    protected synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId, final String serial,
+            final Long bytesReadRate, final Long bytesReadRateMax, final Long bytesReadRateMaxLength,
+            final Long bytesWriteRate, final Long bytesWriteRateMax, final Long bytesWriteRateMaxLength,
+            final Long iopsReadRate, final Long iopsReadRateMax, final Long iopsReadRateMaxLength,
+            final Long iopsWriteRate, final Long iopsWriteRateMax, final Long iopsWriteRateMaxLength) throws LibvirtException, InternalErrorException {
+        List<DiskDef> disks = null;
+        Domain dm = null;
+        DiskDef diskdef = null;
+        final KVMStoragePool attachingPool = attachingDisk.getPool();
+        try {
+            dm = conn.domainLookupByName(vmName);
+            final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser();
+            final String domXml = dm.getXMLDesc(0);
+            parser.parseDomainXML(domXml);
+            disks = parser.getDisks();
+            if (!attach) {
+                if (attachingPool.getType() == StoragePoolType.RBD) {
+                    if (resource.getHypervisorType() == Hypervisor.HypervisorType.LXC) {
+                        final String device = resource.mapRbdDevice(attachingDisk);
+                        if (device != null) {
+                            s_logger.debug("RBD device on host is: "+device);
+                            attachingDisk.setPath(device);
+                        }
+                    }
+                }
+
+                for (final DiskDef disk : disks) {
+                    final String file = disk.getDiskPath();
+                    if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) {
+                        diskdef = disk;
+                        break;
+                    }
+                }
+                if (diskdef == null) {
+                    throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before");
+                }
+            } else {
+                DiskDef.DiskBus busT = DiskDef.DiskBus.VIRTIO;
+                for (final DiskDef disk : disks) {
+                    if (disk.getDeviceType() == DeviceType.DISK) {
+                        if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
+                            busT = DiskDef.DiskBus.SCSI;
+                        }
+                        break;
+                    }
+                }
+                diskdef = new DiskDef();
+                if (busT == DiskDef.DiskBus.SCSI) {
+                    diskdef.setQemuDriver(true);
+                    diskdef.setDiscard(DiscardType.UNMAP);
+                }
+                diskdef.setSerial(serial);
+                if (attachingPool.getType() == StoragePoolType.RBD) {
+                    if(resource.getHypervisorType() == Hypervisor.HypervisorType.LXC){
+                        // For LXC, map image to host and then attach to Vm
+                        final String device = resource.mapRbdDevice(attachingDisk);
+                        if (device != null) {
+                            s_logger.debug("RBD device on host is: "+device);
+                            diskdef.defBlockBasedDisk(device, devId, busT);
+                        } else {
+                            throw new InternalErrorException("Error while mapping disk "+attachingDisk.getPath()+" on host");
+                        }
+                    } else {
+                        diskdef.defNetworkBasedDisk(attachingDisk.getPath(), attachingPool.getSourceHost(), attachingPool.getSourcePort(), attachingPool.getAuthUserName(),
+                                attachingPool.getUuid(), devId, busT, DiskProtocol.RBD, DiskDef.DiskFmtType.RAW);
+                    }
+                } else if (attachingPool.getType() == StoragePoolType.Gluster) {
+                    final String mountpoint = attachingPool.getLocalPath();
+                    final String path = attachingDisk.getPath();
+                    final String glusterVolume = attachingPool.getSourceDir().replace("/", "");
+                    diskdef.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), attachingPool.getSourceHost(), attachingPool.getSourcePort(), null,
+                            null, devId, busT, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
+                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) {
+                    diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, busT, DiskDef.DiskFmtType.QCOW2);
+                } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) {
+                    diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, busT);
+                }
+
+                if ((bytesReadRate != null) && (bytesReadRate > 0)) {
+                    diskdef.setBytesReadRate(bytesReadRate);
+                }
+                if ((bytesReadRateMax != null) && (bytesReadRateMax > 0)) {
+                    diskdef.setBytesReadRateMax(bytesReadRateMax);
+                }
+                if ((bytesReadRateMaxLength != null) && (bytesReadRateMaxLength > 0)) {
+                    diskdef.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+                }
+                if ((bytesWriteRate != null) && (bytesWriteRate > 0)) {
+                    diskdef.setBytesWriteRate(bytesWriteRate);
+                }
+                if ((bytesWriteRateMax != null) && (bytesWriteRateMax > 0)) {
+                    diskdef.setBytesWriteRateMax(bytesWriteRateMax);
+                }
+                if ((bytesWriteRateMaxLength != null) && (bytesWriteRateMaxLength > 0)) {
+                    diskdef.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+                }
+                if ((iopsReadRate != null) && (iopsReadRate > 0)) {
+                    diskdef.setIopsReadRate(iopsReadRate);
+                }
+                if ((iopsReadRateMax != null) && (iopsReadRateMax > 0)) {
+                    diskdef.setIopsReadRateMax(iopsReadRateMax);
+                }
+                if ((iopsReadRateMaxLength != null) && (iopsReadRateMaxLength > 0)) {
+                    diskdef.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+                }
+                if ((iopsWriteRate != null) && (iopsWriteRate > 0)) {
+                    diskdef.setIopsWriteRate(iopsWriteRate);
+                }
+                if ((iopsWriteRateMax != null) && (iopsWriteRateMax > 0)) {
+                    diskdef.setIopsWriteRateMax(iopsWriteRateMax);
+                }
+                if ((iopsWriteRateMaxLength != null) && (iopsWriteRateMaxLength > 0)) {
+                    diskdef.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
+                }
+            }
+
+            final String xml = diskdef.toString();
+            return attachOrDetachDevice(conn, attach, vmName, xml);
+        } finally {
+            if (dm != null) {
+                dm.free();
+            }
+        }
+    }
+
+    @Override
+    public Answer attachVolume(final AttachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
+        final String vmName = cmd.getVmName();
+        final String serial = resource.diskUuidToSerial(vol.getUuid());
+        try {
+            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
+
+            storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath(), disk.getDetails());
+
+            final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
+
+            attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue(), serial,
+                    vol.getBytesReadRate(), vol.getBytesReadRateMax(), vol.getBytesReadRateMaxLength(),
+                    vol.getBytesWriteRate(), vol.getBytesWriteRateMax(), vol.getBytesWriteRateMaxLength(),
+                    vol.getIopsReadRate(), vol.getIopsReadRateMax(), vol.getIopsReadRateMaxLength(),
+                    vol.getIopsWriteRate(), vol.getIopsWriteRateMax(), vol.getIopsWriteRateMaxLength());
+
+            return new AttachAnswer(disk);
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
+            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
+            return new AttachAnswer(e.toString());
+        } catch (final InternalErrorException e) {
+            s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to ", e);
+            return new AttachAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer dettachVolume(final DettachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
+        final String vmName = cmd.getVmName();
+        final String serial = resource.diskUuidToSerial(vol.getUuid());
+        try {
+            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
+
+            final KVMPhysicalDisk phyDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
+
+            attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue(), serial,
+                    vol.getBytesReadRate(), vol.getBytesReadRateMax(), vol.getBytesReadRateMaxLength(),
+                    vol.getBytesWriteRate(), vol.getBytesWriteRateMax(), vol.getBytesWriteRateMaxLength(),
+                    vol.getIopsReadRate(), vol.getIopsReadRateMax(), vol.getIopsReadRateMaxLength(),
+                    vol.getIopsWriteRate(), vol.getIopsWriteRateMax(), vol.getIopsWriteRateMaxLength());
+
+            storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), vol.getPath());
+
+            return new DettachAnswer(disk);
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to detach volume: " + vol.getPath() + ", due to ", e);
+            return new DettachAnswer(e.toString());
+        } catch (final InternalErrorException e) {
+            s_logger.debug("Failed to detach volume: " + vol.getPath() + ", due to ", e);
+            return new DettachAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer createVolume(final CreateObjectCommand cmd) {
+        final VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
+
+        KVMStoragePool primaryPool = null;
+        KVMPhysicalDisk vol = null;
+        long disksize;
+        try {
+            primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+            disksize = volume.getSize();
+            PhysicalDiskFormat format;
+            if (volume.getFormat() == null) {
+                format = primaryPool.getDefaultFormat();
+            } else {
+                format = PhysicalDiskFormat.valueOf(volume.getFormat().toString().toUpperCase());
+            }
+            vol = primaryPool.createPhysicalDisk(volume.getUuid(), format,
+                    volume.getProvisioningType(), disksize);
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            if(vol != null) {
+                newVol.setPath(vol.getName());
+            }
+            newVol.setSize(volume.getSize());
+            newVol.setFormat(ImageFormat.valueOf(format.toString().toUpperCase()));
+
+            return new CreateObjectAnswer(newVol);
+        } catch (final Exception e) {
+            s_logger.debug("Failed to create volume: ", e);
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+
+    protected static final MessageFormat SnapshotXML = new MessageFormat("   <domainsnapshot>" + "       <name>{0}</name>" + "          <domain>"
+            + "            <uuid>{1}</uuid>" + "        </domain>" + "    </domainsnapshot>");
+
+    @Override
+    public Answer createSnapshot(final CreateObjectCommand cmd) {
+        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)cmd.getData();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshotTO.getDataStore();
+        final VolumeObjectTO volume = snapshotTO.getVolume();
+        final String snapshotName = UUID.randomUUID().toString();
+        final String vmName = volume.getVmName();
+        try {
+            final Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
+            DomainInfo.DomainState state = null;
+            Domain vm = null;
+            if (vmName != null) {
+                try {
+                    vm = resource.getDomain(conn, vmName);
+                    state = vm.getInfo().state;
+                } catch (final LibvirtException e) {
+                    s_logger.trace("Ignoring libvirt error.", e);
+                }
+            }
+
+            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+
+            final KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
+            if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {
+                final String vmUuid = vm.getUUIDString();
+                final Object[] args = new Object[] {snapshotName, vmUuid};
+                final String snapshot = SnapshotXML.format(args);
+
+                final long start = System.currentTimeMillis();
+                vm.snapshotCreateXML(snapshot);
+                final long total = (System.currentTimeMillis() - start)/1000;
+                s_logger.debug("snapshot takes " + total + " seconds to finish");
+
+                /*
+                 * libvirt on RHEL6 doesn't handle resume event emitted from
+                 * qemu
+                 */
+                vm = resource.getDomain(conn, vmName);
+                state = vm.getInfo().state;
+                if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
+                    vm.resume();
+                }
+            } else {
+                /**
+                 * For RBD we can't use libvirt to do our snapshotting or any Bash scripts.
+                 * libvirt also wants to store the memory contents of the Virtual Machine,
+                 * but that's not possible with RBD since there is no way to store the memory
+                 * contents in RBD.
+                 *
+                 * So we rely on the Java bindings for RBD to create our snapshot
+                 *
+                 * This snapshot might not be 100% consistent due to writes still being in the
+                 * memory of the Virtual Machine, but if the VM runs a kernel which supports
+                 * barriers properly (>2.6.32) this won't be any different then pulling the power
+                 * cord out of a running machine.
+                 */
+                if (primaryPool.getType() == StoragePoolType.RBD) {
+                    try {
+                        final Rados r = new Rados(primaryPool.getAuthUserName());
+                        r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
+                        r.confSet("key", primaryPool.getAuthSecret());
+                        r.confSet("client_mount_timeout", "30");
+                        r.connect();
+                        s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+
+                        final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
+                        final Rbd rbd = new Rbd(io);
+                        final RbdImage image = rbd.open(disk.getName());
+
+                        s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName);
+                        image.snapCreate(snapshotName);
+
+                        rbd.close(image);
+                        r.ioCtxDestroy(io);
+                    } catch (final Exception e) {
+                        s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage());
+                    }
+                } else {
+                    /* VM is not running, create a snapshot by ourself */
+                    final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
+                    command.add("-c", disk.getPath());
+                    command.add("-n", snapshotName);
+                    final String result = command.execute();
+                    if (result != null) {
+                        s_logger.debug("Failed to manage snapshot: " + result);
+                        return new CreateObjectAnswer("Failed to manage snapshot: " + result);
+                    }
+                }
+            }
+
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            // NOTE: sort of hack, we'd better just put snapshtoName
+            newSnapshot.setPath(disk.getPath() + File.separator + snapshotName);
+            return new CreateObjectAnswer(newSnapshot);
+        } catch (final LibvirtException e) {
+            s_logger.debug("Failed to manage snapshot: ", e);
+            return new CreateObjectAnswer("Failed to manage snapshot: " + e.toString());
+        }
+    }
+
+    @Override
+    public Answer deleteVolume(final DeleteCommand cmd) {
+        final VolumeObjectTO vol = (VolumeObjectTO)cmd.getData();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore();
+        try {
+            final KVMStoragePool pool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+            try {
+                pool.getPhysicalDisk(vol.getPath());
+            } catch (final Exception e) {
+                s_logger.debug("can't find volume: " + vol.getPath() + ", return true");
+                return new Answer(null);
+            }
+            pool.deletePhysicalDisk(vol.getPath(), vol.getFormat());
+            return new Answer(null);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to delete volume: ", e);
+            return new Answer(null, false, e.toString());
+        }
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
+        try {
+            final DataTO srcData = cmd.getSrcTO();
+            final SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+            final DataTO destData = cmd.getDestTO();
+            final PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
+            final DataStoreTO imageStore = srcData.getDataStore();
+            final VolumeObjectTO volume = snapshot.getVolume();
+
+            if (!(imageStore instanceof NfsTO)) {
+                return new CopyCmdAnswer("unsupported protocol");
+            }
+
+            final NfsTO nfsImageStore = (NfsTO)imageStore;
+
+            final String snapshotFullPath = snapshot.getPath();
+            final int index = snapshotFullPath.lastIndexOf("/");
+            final String snapshotPath = snapshotFullPath.substring(0, index);
+            final String snapshotName = snapshotFullPath.substring(index + 1);
+            final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl() + File.separator + snapshotPath);
+            final KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName);
+
+            if (volume.getFormat() == ImageFormat.RAW) {
+                snapshotDisk.setFormat(PhysicalDiskFormat.RAW);
+            } else if (volume.getFormat() == ImageFormat.QCOW2) {
+                snapshotDisk.setFormat(PhysicalDiskFormat.QCOW2);
+            }
+
+            final String primaryUuid = pool.getUuid();
+            final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid);
+            final String volUuid = UUID.randomUUID().toString();
+
+            Map<String, String> details = cmd.getOptions2();
+
+            String path = details != null ? details.get(DiskTO.IQN) : null;
+
+            storagePoolMgr.connectPhysicalDisk(pool.getPoolType(), pool.getUuid(), path, details);
+
+            KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, path != null ? path : volUuid, primaryPool, cmd.getWaitInMillSeconds());
+
+            storagePoolMgr.disconnectPhysicalDisk(pool.getPoolType(), pool.getUuid(), path);
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(disk.getName());
+            newVol.setSize(disk.getVirtualSize());
+            newVol.setFormat(ImageFormat.valueOf(disk.getFormat().toString().toUpperCase()));
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final CloudRuntimeException e) {
+            s_logger.debug("Failed to createVolumeFromSnapshot: ", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer deleteSnapshot(final DeleteCommand cmd) {
+        String snap_full_name = "";
+        try {
+            SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData();
+            PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshotTO.getDataStore();
+            VolumeObjectTO volume = snapshotTO.getVolume();
+            KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
+            KVMPhysicalDisk disk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volume.getPath());
+            String snapshotFullPath = snapshotTO.getPath();
+            String snapshotName = snapshotFullPath.substring(snapshotFullPath.lastIndexOf("/") + 1);
+            snap_full_name = disk.getName() + "@" + snapshotName;
+            if (primaryPool.getType() == StoragePoolType.RBD) {
+                Rados r = new Rados(primaryPool.getAuthUserName());
+                r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort());
+                r.confSet("key", primaryPool.getAuthSecret());
+                r.confSet("client_mount_timeout", "30");
+                r.connect();
+                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+                IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir());
+                Rbd rbd = new Rbd(io);
+                RbdImage image = rbd.open(disk.getName());
+                try {
+                    s_logger.info("Attempting to remove RBD snapshot " + snap_full_name);
+                    if (image.snapIsProtected(snapshotName)) {
+                        s_logger.debug("Unprotecting RBD snapshot " + snap_full_name);
+                        image.snapUnprotect(snapshotName);
+                    }
+                    image.snapRemove(snapshotName);
+                    s_logger.info("Snapshot " + snap_full_name + " successfully removed from " +
+                            primaryPool.getType().toString() + "  pool.");
+                } catch (RbdException e) {
+                    s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
+                        ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+                } finally {
+                    rbd.close(image);
+                    r.ioCtxDestroy(io);
+                }
+            } else {
+                s_logger.warn("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
+                throw new InternalErrorException("Operation not implemented for storage pool type of " + primaryPool.getType().toString());
+            }
+            return new Answer(cmd, true, "Snapshot " + snap_full_name + " removed successfully.");
+        } catch (RadosException e) {
+            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
+                ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
+        } catch (RbdException e) {
+            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString() +
+                ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
+        } catch (Exception e) {
+            s_logger.error("Failed to remove snapshot " + snap_full_name + ", with exception: " + e.toString());
+            return new Answer(cmd, false, "Failed to remove snapshot " + snap_full_name);
+        }
+    }
+
+    @Override
+    public Answer introduceObject(final IntroduceObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    @Override
+    public Answer forgetObject(final ForgetObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    /**
+     * Get direct template downloader from direct download command and destination pool
+     */
+    private DirectTemplateDownloader getDirectTemplateDownloaderFromCommand(DirectDownloadCommand cmd, KVMStoragePool destPool) {
+        if (cmd instanceof HttpDirectDownloadCommand) {
+            return new HttpDirectTemplateDownloader(cmd.getUrl(), cmd.getTemplateId(), destPool.getLocalPath(), cmd.getChecksum(), cmd.getHeaders());
+        } else if (cmd instanceof HttpsDirectDownloadCommand) {
+            return new HttpsDirectTemplateDownloader(cmd.getUrl(), cmd.getTemplateId(), destPool.getLocalPath(), cmd.getChecksum(), cmd.getHeaders());
+        } else if (cmd instanceof NfsDirectDownloadCommand) {
+            return new NfsDirectTemplateDownloader(cmd.getUrl(), destPool.getLocalPath(), cmd.getTemplateId(), cmd.getChecksum());
+        } else if (cmd instanceof MetalinkDirectDownloadCommand) {
+            return new MetalinkDirectTemplateDownloader(cmd.getUrl(), destPool.getLocalPath(), cmd.getTemplateId(), cmd.getChecksum(), cmd.getHeaders());
+        } else {
+            throw new IllegalArgumentException("Unsupported protocol, please provide HTTP(S), NFS or a metalink");
+        }
+    }
+
+    @Override
+    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
+        final PrimaryDataStoreTO pool = cmd.getDestPool();
+        if (!pool.getPoolType().equals(StoragePoolType.NetworkFilesystem)) {
+            return new DirectDownloadAnswer(false, "Unsupported pool type " + pool.getPoolType().toString(), true);
+        }
+        KVMStoragePool destPool = storagePoolMgr.getStoragePool(pool.getPoolType(), pool.getUuid());
+        DirectTemplateDownloader downloader;
+
+        try {
+            downloader = getDirectTemplateDownloaderFromCommand(cmd, destPool);
+        } catch (IllegalArgumentException e) {
+            return new DirectDownloadAnswer(false, "Unable to create direct downloader: " + e.getMessage(), true);
+        }
+
+        try {
+            s_logger.info("Trying to download template");
+            if (!downloader.downloadTemplate()) {
+                s_logger.warn("Couldn't download template");
+                return new DirectDownloadAnswer(false, "Unable to download template", true);
+            }
+            if (!downloader.validateChecksum()) {
+                s_logger.warn("Couldn't validate template checksum");
+                return new DirectDownloadAnswer(false, "Checksum validation failed", false);
+            }
+            if (!downloader.extractAndInstallDownloadedTemplate()) {
+                s_logger.warn("Couldn't extract and install template");
+                return new DirectDownloadAnswer(false, "Extraction and installation failed", false);
+            }
+        } catch (CloudRuntimeException e) {
+            s_logger.warn("Error downloading template " + cmd.getTemplateId() + " due to: " + e.getMessage());
+            return new DirectDownloadAnswer(false, "Unable to download template: " + e.getMessage(), true);
+        }
+
+        DirectTemplateInformation info = downloader.getTemplateInformation();
+        return new DirectDownloadAnswer(true, info.getSize(), info.getInstallPath());
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMVirtualDisk.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMVirtualDisk.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMVirtualDisk.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMVirtualDisk.java
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
new file mode 100644
index 0000000..dc8083f
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -0,0 +1,1339 @@
+// 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.storage;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.LibvirtException;
+import org.libvirt.Secret;
+import org.libvirt.StoragePool;
+import org.libvirt.StoragePoolInfo.StoragePoolState;
+import org.libvirt.StorageVol;
+
+import com.ceph.rados.IoCTX;
+import com.ceph.rados.Rados;
+import com.ceph.rados.exceptions.ErrorCode;
+import com.ceph.rados.exceptions.RadosException;
+import com.ceph.rbd.Rbd;
+import com.ceph.rbd.RbdException;
+import com.ceph.rbd.RbdImage;
+import com.ceph.rbd.jna.RbdImageInfo;
+import com.ceph.rbd.jna.RbdSnapInfo;
+
+import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.cloudstack.utils.qemu.QemuImgException;
+import org.apache.cloudstack.utils.qemu.QemuImgFile;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef.Usage;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.AuthenticationType;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.PoolType;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolXMLParser;
+import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef.VolumeFormat;
+import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeXMLParser;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+public class LibvirtStorageAdaptor implements StorageAdaptor {
+    private static final Logger s_logger = Logger.getLogger(LibvirtStorageAdaptor.class);
+    private StorageLayer _storageLayer;
+    private String _mountPoint = "/mnt";
+    private String _manageSnapshotPath;
+
+    private String rbdTemplateSnapName = "cloudstack-base-snap";
+    private static final int RBD_FEATURE_LAYERING = 1;
+    private static final int RBD_FEATURE_EXCLUSIVE_LOCK = 4;
+    private static final int RBD_FEATURE_OBJECT_MAP = 8;
+    private static final int RBD_FEATURE_FAST_DIFF = 16;
+    private static final int RBD_FEATURE_DEEP_FLATTEN = 32;
+    private int rbdFeatures = RBD_FEATURE_LAYERING + RBD_FEATURE_EXCLUSIVE_LOCK + RBD_FEATURE_OBJECT_MAP + RBD_FEATURE_FAST_DIFF + RBD_FEATURE_DEEP_FLATTEN;
+    private int rbdOrder = 0; /* Order 0 means 4MB blocks (the default) */
+
+    public LibvirtStorageAdaptor(StorageLayer storage) {
+        _storageLayer = storage;
+        _manageSnapshotPath = Script.findScript("scripts/storage/qcow2/", "managesnapshot.sh");
+    }
+
+    @Override
+    public boolean createFolder(String uuid, String path) {
+        String mountPoint = _mountPoint + File.separator + uuid;
+        File f = new File(mountPoint + File.separator + path);
+        if (!f.exists()) {
+            f.mkdirs();
+        }
+        return true;
+    }
+
+    public StorageVol getVolume(StoragePool pool, String volName) {
+        StorageVol vol = null;
+
+        try {
+            vol = pool.storageVolLookupByName(volName);
+        } catch (LibvirtException e) {
+            s_logger.debug("Could not find volume " + volName + ": " + e.getMessage());
+        }
+
+        /**
+         * The volume was not found in the storage pool
+         * This can happen when a volume has just been created on a different host and
+         * since then the libvirt storage pool has not been refreshed.
+         */
+        if (vol == null) {
+            try {
+                s_logger.debug("Refreshing storage pool " + pool.getName());
+                refreshPool(pool);
+            } catch (LibvirtException e) {
+                s_logger.debug("Failed to refresh storage pool: " + e.getMessage());
+            }
+
+            try {
+                vol = pool.storageVolLookupByName(volName);
+                s_logger.debug("Found volume " + volName + " in storage pool " + pool.getName() + " after refreshing the pool");
+            } catch (LibvirtException e) {
+                throw new CloudRuntimeException("Could not find volume " + volName + ": " + e.getMessage());
+            }
+        }
+
+        return vol;
+    }
+
+    public StorageVol createVolume(Connect conn, StoragePool pool, String uuid, long size, VolumeFormat format) throws LibvirtException {
+        LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(UUID.randomUUID().toString(), size, format, null, null);
+        s_logger.debug(volDef.toString());
+
+        return pool.storageVolCreateXML(volDef.toString(), 0);
+    }
+
+    public void storagePoolRefresh(StoragePool pool) {
+        try {
+            synchronized (getStoragePool(pool.getUUIDString())) {
+                refreshPool(pool);
+            }
+        } catch (LibvirtException e) {
+            s_logger.debug("refresh storage pool failed: " + e.toString());
+        }
+    }
+
+    private StoragePool createNetfsStoragePool(PoolType fsType, Connect conn, String uuid, String host, String path) throws LibvirtException {
+        String targetPath = _mountPoint + File.separator + uuid;
+        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(fsType, uuid, uuid, host, path, targetPath);
+        _storageLayer.mkdir(targetPath);
+        StoragePool sp = null;
+        try {
+            s_logger.debug(spd.toString());
+            // check whether the pool is already mounted
+            int mountpointResult = Script.runSimpleBashScriptForExitValue("mountpoint -q " + targetPath);
+            // if the pool is mounted, try to unmount it
+            if(mountpointResult == 0) {
+                s_logger.info("Attempting to unmount old mount at " + targetPath);
+                String result = Script.runSimpleBashScript("umount -l " + targetPath);
+                if (result == null) {
+                    s_logger.info("Succeeded in unmounting " + targetPath);
+                } else {
+                    s_logger.error("Failed in unmounting storage");
+                }
+            }
+
+            sp = conn.storagePoolCreateXML(spd.toString(), 0);
+            return sp;
+        } catch (LibvirtException e) {
+            s_logger.error(e.toString());
+            throw e;
+        }
+    }
+
+    private StoragePool createSharedStoragePool(Connect conn, String uuid, String host, String path) {
+        String mountPoint = path;
+        if (!_storageLayer.exists(mountPoint)) {
+            s_logger.error(mountPoint + " does not exists. Check local.storage.path in agent.properties.");
+            return null;
+        }
+        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.DIR, uuid, uuid, host, path, path);
+        StoragePool sp = null;
+        try {
+            s_logger.debug(spd.toString());
+            sp = conn.storagePoolCreateXML(spd.toString(), 0);
+            return sp;
+        } catch (LibvirtException e) {
+            s_logger.error(e.toString());
+            if (sp != null) {
+                try {
+                    if (sp.isPersistent() == 1) {
+                        sp.destroy();
+                        sp.undefine();
+                    } else {
+                        sp.destroy();
+                    }
+                    sp.free();
+                } catch (LibvirtException l) {
+                    s_logger.debug("Failed to define shared mount point storage pool with: " + l.toString());
+                }
+            }
+            return null;
+        }
+    }
+
+    private StoragePool createCLVMStoragePool(Connect conn, String uuid, String host, String path) {
+
+        String volgroupPath = "/dev/" + path;
+        String volgroupName = path;
+        volgroupName = volgroupName.replaceFirst("/", "");
+
+        LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(PoolType.LOGICAL, volgroupName, uuid, host, volgroupPath, volgroupPath);
+        StoragePool sp = null;
+        try {
+            s_logger.debug(spd.toString());
+            sp = conn.storagePoolCreateXML(spd.toString(), 0);
+            return sp;
+        } catch (LibvirtException e) {
+            s_logger.error(e.toString());
+            if (sp != null) {
+                try {
+                    if (sp.isPersistent() == 1) {
+                        sp.destroy();
+                        sp.undefine();
+                    } else {
+                        sp.destroy();
+                    }
+                    sp.free();
+                } catch (LibvirtException l) {
+                    s_logger.debug("Failed to define clvm storage pool with: " + l.toString());
+                }
+            }
+            return null;
+        }
+
+    }
+
+    private StoragePool createRBDStoragePool(Connect conn, String uuid, String host, int port, String userInfo, String path) {
+
+        LibvirtStoragePoolDef spd;
+        StoragePool sp = null;
+        Secret s = null;
+
+        String[] userInfoTemp = userInfo.split(":");
+        if (userInfoTemp.length == 2) {
+            LibvirtSecretDef sd = new LibvirtSecretDef(Usage.CEPH, uuid);
+
+            sd.setCephName(userInfoTemp[0] + "@" + host + ":" + port + "/" + path);
+
+            try {
+                s_logger.debug(sd.toString());
+                s = conn.secretDefineXML(sd.toString());
+                s.setValue(Base64.decodeBase64(userInfoTemp[1]));
+            } catch (LibvirtException e) {
+                s_logger.error("Failed to define the libvirt secret: " + e.toString());
+                if (s != null) {
+                    try {
+                        s.undefine();
+                        s.free();
+                    } catch (LibvirtException l) {
+                        s_logger.error("Failed to undefine the libvirt secret: " + l.toString());
+                    }
+                }
+                return null;
+            }
+            spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, userInfoTemp[0], AuthenticationType.CEPH, uuid);
+        } else {
+            spd = new LibvirtStoragePoolDef(PoolType.RBD, uuid, uuid, host, port, path, "");
+        }
+
+        try {
+            s_logger.debug(spd.toString());
+            sp = conn.storagePoolCreateXML(spd.toString(), 0);
+            return sp;
+        } catch (LibvirtException e) {
+            s_logger.error("Failed to create RBD storage pool: " + e.toString());
+            if (sp != null) {
+                try {
+                    if (sp.isPersistent() == 1) {
+                        sp.destroy();
+                        sp.undefine();
+                    } else {
+                        sp.destroy();
+                    }
+                    sp.free();
+                } catch (LibvirtException l) {
+                    s_logger.error("Failed to undefine RBD storage pool: " + l.toString());
+                }
+            }
+
+            if (s != null) {
+                try {
+                    s_logger.error("Failed to create the RBD storage pool, cleaning up the libvirt secret");
+                    s.undefine();
+                    s.free();
+                } catch (LibvirtException se) {
+                    s_logger.error("Failed to remove the libvirt secret: " + se.toString());
+                }
+            }
+
+            return null;
+        }
+    }
+
+    public StorageVol copyVolume(StoragePool destPool, LibvirtStorageVolumeDef destVol, StorageVol srcVol, int timeout) throws LibvirtException {
+        StorageVol vol = destPool.storageVolCreateXML(destVol.toString(), 0);
+        String srcPath = srcVol.getKey();
+        String destPath = vol.getKey();
+        Script.runSimpleBashScript("cp " + srcPath + " " + destPath, timeout);
+        return vol;
+    }
+
+    public boolean copyVolume(String srcPath, String destPath, String volumeName, int timeout) throws InternalErrorException {
+        _storageLayer.mkdirs(destPath);
+        if (!_storageLayer.exists(srcPath)) {
+            throw new InternalErrorException("volume:" + srcPath + " is not exits");
+        }
+        String result = Script.runSimpleBashScript("cp " + srcPath + " " + destPath + File.separator + volumeName, timeout);
+        return result == null;
+    }
+
+    public LibvirtStoragePoolDef getStoragePoolDef(Connect conn, StoragePool pool) throws LibvirtException {
+        String poolDefXML = pool.getXMLDesc(0);
+        LibvirtStoragePoolXMLParser parser = new LibvirtStoragePoolXMLParser();
+        return parser.parseStoragePoolXML(poolDefXML);
+    }
+
+    public LibvirtStorageVolumeDef getStorageVolumeDef(Connect conn, StorageVol vol) throws LibvirtException {
+        String volDefXML = vol.getXMLDesc(0);
+        LibvirtStorageVolumeXMLParser parser = new LibvirtStorageVolumeXMLParser();
+        return parser.parseStorageVolumeXML(volDefXML);
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid) {
+        return this.getStoragePool(uuid, false);
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
+        s_logger.info("Trying to fetch storage pool " + uuid + " from libvirt");
+        StoragePool storage = null;
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+            storage = conn.storagePoolLookupByUUIDString(uuid);
+
+            if (storage.getInfo().state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
+                s_logger.warn("Storage pool " + uuid + " is not in running state. Attempting to start it.");
+                storage.create(0);
+            }
+            LibvirtStoragePoolDef spd = getStoragePoolDef(conn, storage);
+            if (spd == null) {
+                throw new CloudRuntimeException("Unable to parse the storage pool definition for storage pool " + uuid);
+            }
+            StoragePoolType type = null;
+            if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.NETFS) {
+                type = StoragePoolType.NetworkFilesystem;
+            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.DIR) {
+                type = StoragePoolType.Filesystem;
+            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.RBD) {
+                type = StoragePoolType.RBD;
+            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.LOGICAL) {
+                type = StoragePoolType.CLVM;
+            } else if (spd.getPoolType() == LibvirtStoragePoolDef.PoolType.GLUSTERFS) {
+                type = StoragePoolType.Gluster;
+            }
+
+            LibvirtStoragePool pool = new LibvirtStoragePool(uuid, storage.getName(), type, this, storage);
+
+            if (pool.getType() != StoragePoolType.RBD)
+                pool.setLocalPath(spd.getTargetPath());
+            else
+                pool.setLocalPath("");
+
+            if (pool.getType() == StoragePoolType.RBD
+                    || pool.getType() == StoragePoolType.Gluster) {
+                pool.setSourceHost(spd.getSourceHost());
+                pool.setSourcePort(spd.getSourcePort());
+                pool.setSourceDir(spd.getSourceDir());
+                String authUsername = spd.getAuthUserName();
+                if (authUsername != null) {
+                    Secret secret = conn.secretLookupByUUIDString(spd.getSecretUUID());
+                    String secretValue = new String(Base64.encodeBase64(secret.getByteValue()), Charset.defaultCharset());
+                    pool.setAuthUsername(authUsername);
+                    pool.setAuthSecret(secretValue);
+                }
+            }
+
+            /**
+             * On large (RBD) storage pools it can take up to a couple of minutes
+             * for libvirt to refresh the pool.
+             *
+             * Refreshing a storage pool means that libvirt will have to iterate the whole pool
+             * and fetch information of each volume in there
+             *
+             * It is not always required to refresh a pool. So we can control if we want to or not
+             *
+             * By default only the getStorageStats call in the LibvirtComputingResource will ask to
+             * refresh the pool
+             */
+            if (refreshInfo) {
+                s_logger.info("Asking libvirt to refresh storage pool " + uuid);
+                pool.refresh();
+            }
+            pool.setCapacity(storage.getInfo().capacity);
+            pool.setUsed(storage.getInfo().allocation);
+            pool.setAvailable(storage.getInfo().available);
+
+            s_logger.debug("Succesfully refreshed pool " + uuid +
+                           " Capacity: " + storage.getInfo().capacity +
+                           " Used: " + storage.getInfo().allocation +
+                           " Available: " + storage.getInfo().available);
+
+            return pool;
+        } catch (LibvirtException e) {
+            s_logger.debug("Could not find storage pool " + uuid + " in libvirt");
+            throw new CloudRuntimeException(e.toString(), e);
+        }
+    }
+
+    @Override
+    public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
+
+        try {
+            StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid);
+            KVMPhysicalDisk disk;
+            LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol);
+            disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool);
+            disk.setSize(vol.getInfo().allocation);
+            disk.setVirtualSize(vol.getInfo().capacity);
+
+            /**
+             * libvirt returns format = 'unknow', so we have to force
+             * the format to RAW for RBD storage volumes
+             */
+            if (pool.getType() == StoragePoolType.RBD) {
+                disk.setFormat(PhysicalDiskFormat.RAW);
+            } else if (voldef.getFormat() == null) {
+                File diskDir = new File(disk.getPath());
+                if (diskDir.exists() && diskDir.isDirectory()) {
+                    disk.setFormat(PhysicalDiskFormat.DIR);
+                } else if (volumeUuid.endsWith("tar") || volumeUuid.endsWith(("TAR"))) {
+                    disk.setFormat(PhysicalDiskFormat.TAR);
+                } else if (volumeUuid.endsWith("raw") || volumeUuid.endsWith(("RAW"))) {
+                    disk.setFormat(PhysicalDiskFormat.RAW);
+                } else {
+                    disk.setFormat(pool.getDefaultFormat());
+                }
+            } else if (voldef.getFormat() == LibvirtStorageVolumeDef.VolumeFormat.QCOW2) {
+                disk.setFormat(PhysicalDiskFormat.QCOW2);
+            } else if (voldef.getFormat() == LibvirtStorageVolumeDef.VolumeFormat.RAW) {
+                disk.setFormat(PhysicalDiskFormat.RAW);
+            }
+            return disk;
+        } catch (LibvirtException e) {
+            s_logger.debug("Failed to get physical disk:", e);
+            throw new CloudRuntimeException(e.toString());
+        }
+
+    }
+
+    @Override
+    public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type) {
+        s_logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt");
+
+        StoragePool sp = null;
+        Connect conn = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+
+        try {
+            sp = conn.storagePoolLookupByUUIDString(name);
+            if (sp != null && sp.isActive() == 0) {
+                sp.undefine();
+                sp = null;
+                s_logger.info("Found existing defined storage pool " + name + ". It wasn't running, so we undefined it.");
+            }
+            if (sp != null) {
+                s_logger.info("Found existing defined storage pool " + name + ", using it.");
+            }
+        } catch (LibvirtException e) {
+            sp = null;
+            s_logger.warn("Storage pool " + name + " was not found running in libvirt. Need to create it.");
+        }
+
+        // libvirt strips trailing slashes off of path, we will too in order to match
+        // existing paths
+        if (path.endsWith("/")) {
+            path = path.substring(0, path.length() - 1);
+        }
+
+        if (sp == null) {
+            // see if any existing pool by another name is using our storage path.
+            // if anyone is, undefine the pool so we can define it as requested.
+            // This should be safe since a pool in use can't be removed, and no
+            // volumes are affected by unregistering the pool with libvirt.
+            s_logger.info("Didn't find an existing storage pool " + name + " by UUID, checking for pools with duplicate paths");
+
+            try {
+                String[] poolnames = conn.listStoragePools();
+                for (String poolname : poolnames) {
+                    s_logger.debug("Checking path of existing pool " + poolname + " against pool we want to create");
+                    StoragePool p = conn.storagePoolLookupByName(poolname);
+                    LibvirtStoragePoolDef pdef = getStoragePoolDef(conn, p);
+                    if (pdef == null) {
+                        throw new CloudRuntimeException("Unable to parse the storage pool definition for storage pool " + poolname);
+                    }
+
+                    String targetPath = pdef.getTargetPath();
+                    if (targetPath != null && targetPath.equals(path)) {
+                        s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname +
+                                ", undefining so we can re-define with correct name " + name);
+                        if (p.isPersistent() == 1) {
+                            p.destroy();
+                            p.undefine();
+                        } else {
+                            p.destroy();
+                        }
+                    }
+                }
+            } catch (LibvirtException e) {
+                s_logger.error("Failure in attempting to see if an existing storage pool might be using the path of the pool to be created:" + e);
+            }
+
+            s_logger.debug("Attempting to create storage pool " + name);
+
+            if (type == StoragePoolType.NetworkFilesystem) {
+                try {
+                    sp = createNetfsStoragePool(PoolType.NETFS, conn, name, host, path);
+                } catch (LibvirtException e) {
+                    s_logger.error("Failed to create netfs mount: " + host + ":" + path , e);
+                    s_logger.error(e.getStackTrace());
+                    throw new CloudRuntimeException(e.toString());
+                }
+            } else if (type == StoragePoolType.Gluster) {
+                try {
+                    sp = createNetfsStoragePool(PoolType.GLUSTERFS, conn, name, host, path);
+                } catch (LibvirtException e) {
+                    s_logger.error("Failed to create glusterfs mount: " + host + ":" + path , e);
+                    s_logger.error(e.getStackTrace());
+                    throw new CloudRuntimeException(e.toString());
+                }
+            } else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) {
+                sp = createSharedStoragePool(conn, name, host, path);
+            } else if (type == StoragePoolType.RBD) {
+                sp = createRBDStoragePool(conn, name, host, port, userInfo, path);
+            } else if (type == StoragePoolType.CLVM) {
+                sp = createCLVMStoragePool(conn, name, host, path);
+            }
+        }
+
+        if (sp == null) {
+            throw new CloudRuntimeException("Failed to create storage pool: " + name);
+        }
+
+        try {
+            if (sp.isActive() == 0) {
+                s_logger.debug("Attempting to activate pool " + name);
+                sp.create(0);
+            }
+
+            return getStoragePool(name);
+        } catch (LibvirtException e) {
+            String error = e.toString();
+            if (error.contains("Storage source conflict")) {
+                throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " +
+                        " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " +
+                        error);
+            } else {
+                throw new CloudRuntimeException(error);
+            }
+        }
+    }
+
+    @Override
+    public boolean deleteStoragePool(String uuid) {
+        s_logger.info("Attempting to remove storage pool " + uuid + " from libvirt");
+        Connect conn = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+
+        StoragePool sp = null;
+        Secret s = null;
+
+        try {
+            sp = conn.storagePoolLookupByUUIDString(uuid);
+        } catch (LibvirtException e) {
+            s_logger.warn("Storage pool " + uuid + " doesn't exist in libvirt. Assuming it is already removed");
+            return true;
+        }
+
+        /*
+         * Some storage pools, like RBD also have 'secret' information stored in libvirt
+         * Destroy them if they exist
+         */
+        try {
+            s = conn.secretLookupByUUIDString(uuid);
+        } catch (LibvirtException e) {
+            s_logger.info("Storage pool " + uuid + " has no corresponding secret. Not removing any secret.");
+        }
+
+        try {
+            if (sp.isPersistent() == 1) {
+                sp.destroy();
+                sp.undefine();
+            } else {
+                sp.destroy();
+            }
+            sp.free();
+            if (s != null) {
+                s.undefine();
+                s.free();
+            }
+
+            s_logger.info("Storage pool " + uuid + " was succesfully removed from libvirt.");
+
+            return true;
+        } catch (LibvirtException e) {
+            // handle ebusy error when pool is quickly destroyed
+            if (e.toString().contains("exit status 16")) {
+                String targetPath = _mountPoint + File.separator + uuid;
+                s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble unmounting the pool. Trying umount location " + targetPath +
+                        "again in a few seconds");
+                String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath);
+                if (result == null) {
+                    s_logger.error("Succeeded in unmounting " + targetPath);
+                    return true;
+                }
+                s_logger.error("Failed to unmount " + targetPath);
+            }
+            throw new CloudRuntimeException(e.toString(), e);
+        }
+    }
+
+    @Override
+    public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool,
+            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
+
+        s_logger.info("Attempting to create volume " + name + " (" + pool.getType().toString() + ") in pool "
+                + pool.getUuid() + " with size " + size);
+
+        switch (pool.getType()) {
+            case RBD:
+                return createPhysicalDiskByLibVirt(name, pool, PhysicalDiskFormat.RAW, provisioningType, size);
+            case NetworkFilesystem:
+            case Filesystem:
+                switch (format) {
+                    case QCOW2:
+                        return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
+                    case RAW:
+                        return createPhysicalDiskByQemuImg(name, pool, format, provisioningType, size);
+                    case DIR:
+                        return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
+                    case TAR:
+                        return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
+                    default:
+                        throw new CloudRuntimeException("Unexpected disk format is specified.");
+                }
+            default:
+                return createPhysicalDiskByLibVirt(name, pool, format, provisioningType, size);
+        }
+    }
+
+    private KVMPhysicalDisk createPhysicalDiskByLibVirt(String name, KVMStoragePool pool,
+            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
+        StoragePool virtPool = libvirtPool.getPool();
+        LibvirtStorageVolumeDef.VolumeFormat libvirtformat = LibvirtStorageVolumeDef.VolumeFormat.getFormat(format);
+
+        String volPath = null;
+        String volName = null;
+        long volAllocation = 0;
+        long volCapacity = 0;
+
+        LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(name,
+                size, libvirtformat, null, null);
+        s_logger.debug(volDef.toString());
+        try {
+            StorageVol vol = virtPool.storageVolCreateXML(volDef.toString(), 0);
+            volPath = vol.getPath();
+            volName = vol.getName();
+            volAllocation = vol.getInfo().allocation;
+            volCapacity = vol.getInfo().capacity;
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+
+        KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool);
+        disk.setFormat(format);
+        disk.setSize(volAllocation);
+        disk.setVirtualSize(volCapacity);
+        return disk;
+    }
+
+
+    private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool pool,
+            PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size) {
+        String volPath = pool.getLocalPath() + "/" + name;
+        String volName = name;
+        long virtualSize = 0;
+        long actualSize = 0;
+
+        final int timeout = 0;
+
+        QemuImgFile destFile = new QemuImgFile(volPath);
+        destFile.setFormat(format);
+        destFile.setSize(size);
+        QemuImg qemu = new QemuImg(timeout);
+        Map<String, String> options = new HashMap<String, String>();
+        if (pool.getType() == StoragePoolType.NetworkFilesystem){
+            options.put("preallocation", QemuImg.PreallocationType.getPreallocationType(provisioningType).toString());
+        }
+
+        try{
+            qemu.create(destFile, options);
+            Map<String, String> info = qemu.info(destFile);
+            virtualSize = Long.parseLong(info.get(new String("virtual_size")));
+            actualSize = new File(destFile.getFileName()).length();
+        } catch (QemuImgException e) {
+            s_logger.error("Failed to create " + volPath +
+                    " due to a failed executing of qemu-img: " + e.getMessage());
+        }
+
+        KVMPhysicalDisk disk = new KVMPhysicalDisk(volPath, volName, pool);
+        disk.setFormat(format);
+        disk.setSize(actualSize);
+        disk.setVirtualSize(virtualSize);
+        return disk;
+    }
+
+    @Override
+    public boolean connectPhysicalDisk(String name, KVMStoragePool pool, Map<String, String> details) {
+        // this is for managed storage that needs to prep disks prior to use
+        return true;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDisk(String uuid, KVMStoragePool pool) {
+        // this is for managed storage that needs to cleanup disks after use
+        return true;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) {
+        // this is for managed storage that needs to cleanup disks after use
+        return false;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDiskByPath(String localPath) {
+        // we've only ever cleaned up ISOs that are NFS mounted
+        String poolUuid = null;
+        if (localPath != null && localPath.startsWith(_mountPoint) && localPath.endsWith(".iso")) {
+            String[] token = localPath.split("/");
+
+            if (token.length > 3) {
+                poolUuid = token[2];
+            }
+        } else {
+            return false;
+        }
+
+        if (poolUuid == null) {
+            return false;
+        }
+
+        try {
+            Connect conn = LibvirtConnection.getConnection();
+
+            conn.storagePoolLookupByUUIDString(poolUuid);
+
+            deleteStoragePool(poolUuid);
+
+            return true;
+        } catch (LibvirtException ex) {
+            return false;
+        } catch (CloudRuntimeException ex) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean deletePhysicalDisk(String uuid, KVMStoragePool pool, Storage.ImageFormat format) {
+
+        s_logger.info("Attempting to remove volume " + uuid + " from pool " + pool.getUuid());
+
+        /**
+         * RBD volume can have snapshots and while they exist libvirt
+         * can't remove the RBD volume
+         *
+         * We have to remove those snapshots first
+         */
+        if (pool.getType() == StoragePoolType.RBD) {
+            try {
+                s_logger.info("Unprotecting and Removing RBD snapshots of image " + pool.getSourceDir() + "/" + uuid + " prior to removing the image");
+
+                Rados r = new Rados(pool.getAuthUserName());
+                r.confSet("mon_host", pool.getSourceHost() + ":" + pool.getSourcePort());
+                r.confSet("key", pool.getAuthSecret());
+                r.confSet("client_mount_timeout", "30");
+                r.connect();
+                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+
+                IoCTX io = r.ioCtxCreate(pool.getSourceDir());
+                Rbd rbd = new Rbd(io);
+                RbdImage image = rbd.open(uuid);
+                s_logger.debug("Fetching list of snapshots of RBD image " + pool.getSourceDir() + "/" + uuid);
+                List<RbdSnapInfo> snaps = image.snapList();
+                try {
+                    for (RbdSnapInfo snap : snaps) {
+                        if (image.snapIsProtected(snap.name)) {
+                            s_logger.debug("Unprotecting snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name);
+                            image.snapUnprotect(snap.name);
+                        } else {
+                            s_logger.debug("Snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name + " is not protected.");
+                        }
+                        s_logger.debug("Removing snapshot " + pool.getSourceDir() + "/" + uuid + "@" + snap.name);
+                        image.snapRemove(snap.name);
+                    }
+                    s_logger.info("Succesfully unprotected and removed any remaining snapshots (" + snaps.size() + ") of "
+                        + pool.getSourceDir() + "/" + uuid + " Continuing to remove the RBD image");
+                } catch (RbdException e) {
+                    s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
+                        ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+                    throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
+                } finally {
+                    s_logger.debug("Closing image and destroying context");
+                    rbd.close(image);
+                    r.ioCtxDestroy(io);
+                }
+            } catch (RadosException e) {
+                s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
+                    ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+                throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
+            } catch (RbdException e) {
+                s_logger.error("Failed to remove snapshot with exception: " + e.toString() +
+                    ", RBD error: " + ErrorCode.getErrorMessage(e.getReturnValue()));
+                throw new CloudRuntimeException(e.toString() + " - " + ErrorCode.getErrorMessage(e.getReturnValue()));
+            }
+        }
+
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
+        try {
+            StorageVol vol = getVolume(libvirtPool.getPool(), uuid);
+            s_logger.debug("Instructing libvirt to remove volume " + uuid + " from pool " + pool.getUuid());
+            if(Storage.ImageFormat.DIR.equals(format)){
+                deleteDirVol(libvirtPool, vol);
+            } else {
+                deleteVol(libvirtPool, vol);
+            }
+            vol.free();
+            return true;
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+    }
+
+    /**
+     * This function copies a physical disk from Secondary Storage to Primary Storage
+     * or from Primary to Primary Storage
+     *
+     * The first time a template is deployed in Primary Storage it will be copied from
+     * Secondary to Primary.
+     *
+     * If it has been created on Primary Storage, it will be copied on the Primary Storage
+     */
+    @Override
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
+            String name, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size, KVMStoragePool destPool, int timeout) {
+
+        s_logger.info("Creating volume " + name + " from template " + template.getName() + " in pool " + destPool.getUuid() +
+                " (" + destPool.getType().toString() + ") with size " + size);
+
+        KVMPhysicalDisk disk = null;
+
+        if (destPool.getType() == StoragePoolType.RBD) {
+            disk = createDiskFromTemplateOnRBD(template, name, format, provisioningType, size, destPool, timeout);
+        } else {
+            try {
+                String newUuid = name;
+                disk = destPool.createPhysicalDisk(newUuid, format, provisioningType, template.getVirtualSize());
+                if (disk == null) {
+                    throw new CloudRuntimeException("Failed to create disk from template " + template.getName());
+                }
+                if (template.getFormat() == PhysicalDiskFormat.TAR) {
+                    Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath(), timeout); // TO BE FIXED to aware provisioningType
+                } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
+                    Script.runSimpleBashScript("mkdir -p " + disk.getPath());
+                    Script.runSimpleBashScript("chmod 755 " + disk.getPath());
+                    Script.runSimpleBashScript("tar -x -f " + template.getPath() + "/*.tar -C " + disk.getPath(), timeout);
+                } else if (format == PhysicalDiskFormat.QCOW2) {
+                    QemuImg qemu = new QemuImg(timeout);
+                    QemuImgFile destFile = new QemuImgFile(disk.getPath(), format);
+                    if (size > template.getVirtualSize()) {
+                        destFile.setSize(size);
+                    } else {
+                        destFile.setSize(template.getVirtualSize());
+                    }
+                    Map<String, String> options = new HashMap<String, String>();
+                    options.put("preallocation", QemuImg.PreallocationType.getPreallocationType(provisioningType).toString());
+                    switch(provisioningType){
+                    case THIN:
+                        QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
+                        qemu.create(destFile, backingFile, options);
+                        break;
+                    case SPARSE:
+                    case FAT:
+                        QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
+                        qemu.convert(srcFile, destFile, options);
+                        break;
+                    }
+                } else if (format == PhysicalDiskFormat.RAW) {
+                    QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
+                    QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
+                    if (size > template.getVirtualSize()) {
+                        destFile.setSize(size);
+                    } else {
+                        destFile.setSize(template.getVirtualSize());
+                    }
+                    QemuImg qemu = new QemuImg(timeout);
+                    Map<String, String> options = new HashMap<String, String>();
+                    qemu.convert(sourceFile, destFile, options);
+                }
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to create " + disk.getPath() +
+                        " due to a failed executing of qemu-img: " + e.getMessage());
+            }
+        }
+
+
+        return disk;
+    }
+
+    private KVMPhysicalDisk createDiskFromTemplateOnRBD(KVMPhysicalDisk template,
+            String name, PhysicalDiskFormat format, Storage.ProvisioningType provisioningType, long size, KVMStoragePool destPool, int timeout){
+
+        /*
+            With RBD you can't run qemu-img convert with an existing RBD image as destination
+            qemu-img will exit with the error that the destination already exists.
+            So for RBD we don't create the image, but let qemu-img do that for us.
+
+            We then create a KVMPhysicalDisk object that we can return
+         */
+
+        KVMStoragePool srcPool = template.getPool();
+        KVMPhysicalDisk disk = null;
+        String newUuid = name;
+
+        format = PhysicalDiskFormat.RAW;
+        disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
+        disk.setFormat(format);
+        if (size > template.getVirtualSize()) {
+            disk.setSize(size);
+            disk.setVirtualSize(size);
+        } else {
+            // leave these as they were if size isn't applicable
+            disk.setSize(template.getVirtualSize());
+            disk.setVirtualSize(disk.getSize());
+        }
+
+
+        QemuImg qemu = new QemuImg(timeout);
+        QemuImgFile srcFile;
+        QemuImgFile destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
+                destPool.getSourcePort(),
+                destPool.getAuthUserName(),
+                destPool.getAuthSecret(),
+                disk.getPath()));
+        destFile.setFormat(format);
+
+
+        if (srcPool.getType() != StoragePoolType.RBD) {
+            srcFile = new QemuImgFile(template.getPath(), template.getFormat());
+            try{
+                qemu.convert(srcFile, destFile);
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to create " + disk.getPath() +
+                        " due to a failed executing of qemu-img: " + e.getMessage());
+            }
+        } else {
+
+            /**
+             * We have to find out if the source file is in the same RBD pool and has
+             * RBD format 2 before we can do a layering/clone operation on the RBD image
+             *
+             * This will be the case when the template is already on Primary Storage and
+             * we want to copy it
+             */
+
+            try {
+                if ((srcPool.getSourceHost().equals(destPool.getSourceHost())) && (srcPool.getSourceDir().equals(destPool.getSourceDir()))) {
+                    /* We are on the same Ceph cluster, but we require RBD format 2 on the source image */
+                    s_logger.debug("Trying to perform a RBD clone (layering) since we are operating in the same storage pool");
+
+                    Rados r = new Rados(srcPool.getAuthUserName());
+                    r.confSet("mon_host", srcPool.getSourceHost() + ":" + srcPool.getSourcePort());
+                    r.confSet("key", srcPool.getAuthSecret());
+                    r.confSet("client_mount_timeout", "30");
+                    r.connect();
+                    s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+
+                    IoCTX io = r.ioCtxCreate(srcPool.getSourceDir());
+                    Rbd rbd = new Rbd(io);
+                    RbdImage srcImage = rbd.open(template.getName());
+
+                    if (srcImage.isOldFormat()) {
+                        /* The source image is RBD format 1, we have to do a regular copy */
+                        s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() +
+                                " is RBD format 1. We have to perform a regular copy (" + disk.getVirtualSize() + " bytes)");
+
+                        rbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
+                        RbdImage destImage = rbd.open(disk.getName());
+
+                        s_logger.debug("Starting to copy " + srcImage.getName() +  " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
+                        rbd.copy(srcImage, destImage);
+
+                        s_logger.debug("Finished copying " + srcImage.getName() +  " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
+                        rbd.close(destImage);
+                    } else {
+                        s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName()
+                                + " is RBD format 2. We will perform a RBD clone using snapshot "
+                                + rbdTemplateSnapName);
+                        /* The source image is format 2, we can do a RBD snapshot+clone (layering) */
+
+
+                        s_logger.debug("Checking if RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
+                                + "@" + rbdTemplateSnapName + " exists prior to attempting a clone operation.");
+
+                        List<RbdSnapInfo> snaps = srcImage.snapList();
+                        s_logger.debug("Found " + snaps.size() +  " snapshots on RBD image " + srcPool.getSourceDir() + "/" + template.getName());
+                        boolean snapFound = false;
+                        for (RbdSnapInfo snap : snaps) {
+                            if (rbdTemplateSnapName.equals(snap.name)) {
+                                s_logger.debug("RBD snapshot " + srcPool.getSourceDir() + "/" + template.getName()
+                                        + "@" + rbdTemplateSnapName + " already exists.");
+                                snapFound = true;
+                                break;
+                            }
+                        }
+
+                        if (!snapFound) {
+                            s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name);
+                            srcImage.snapCreate(rbdTemplateSnapName);
+                            s_logger.debug("Protecting RBD snapshot " + rbdTemplateSnapName + " on image " + name);
+                            srcImage.snapProtect(rbdTemplateSnapName);
+                        }
+
+                        rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder);
+                        s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName());
+                        /* We also need to resize the image if the VM was deployed with a larger root disk size */
+                        if (disk.getVirtualSize() > template.getVirtualSize()) {
+                            RbdImage diskImage = rbd.open(disk.getName());
+                            diskImage.resize(disk.getVirtualSize());
+                            rbd.close(diskImage);
+                            s_logger.debug("Resized " + disk.getName() + " to " + disk.getVirtualSize());
+                        }
+
+                    }
+
+                    rbd.close(srcImage);
+                    r.ioCtxDestroy(io);
+                } else {
+                    /* The source pool or host is not the same Ceph cluster, we do a simple copy with Qemu-Img */
+                    s_logger.debug("Both the source and destination are RBD, but not the same Ceph cluster. Performing a copy");
+
+                    Rados rSrc = new Rados(srcPool.getAuthUserName());
+                    rSrc.confSet("mon_host", srcPool.getSourceHost() + ":" + srcPool.getSourcePort());
+                    rSrc.confSet("key", srcPool.getAuthSecret());
+                    rSrc.confSet("client_mount_timeout", "30");
+                    rSrc.connect();
+                    s_logger.debug("Succesfully connected to source Ceph cluster at " + rSrc.confGet("mon_host"));
+
+                    Rados rDest = new Rados(destPool.getAuthUserName());
+                    rDest.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
+                    rDest.confSet("key", destPool.getAuthSecret());
+                    rDest.confSet("client_mount_timeout", "30");
+                    rDest.connect();
+                    s_logger.debug("Succesfully connected to source Ceph cluster at " + rDest.confGet("mon_host"));
+
+                    IoCTX sIO = rSrc.ioCtxCreate(srcPool.getSourceDir());
+                    Rbd sRbd = new Rbd(sIO);
+
+                    IoCTX dIO = rDest.ioCtxCreate(destPool.getSourceDir());
+                    Rbd dRbd = new Rbd(dIO);
+
+                    s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " +
+                            destPool.getSourceDir());
+                    dRbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
+
+                    RbdImage srcImage = sRbd.open(template.getName());
+                    RbdImage destImage = dRbd.open(disk.getName());
+
+                    s_logger.debug("Copying " + template.getName() + " from Ceph cluster " + rSrc.confGet("mon_host") + " to " + disk.getName()
+                            + " on cluster " + rDest.confGet("mon_host"));
+                    sRbd.copy(srcImage, destImage);
+
+                    sRbd.close(srcImage);
+                    dRbd.close(destImage);
+
+                    rSrc.ioCtxDestroy(sIO);
+                    rDest.ioCtxDestroy(dIO);
+                }
+            } catch (RadosException e) {
+                s_logger.error("Failed to perform a RADOS action on the Ceph cluster, the error was: " + e.getMessage());
+                disk = null;
+            } catch (RbdException e) {
+                s_logger.error("Failed to perform a RBD action on the Ceph cluster, the error was: " + e.getMessage());
+                disk = null;
+            }
+        }
+        return disk;
+    }
+
+    @Override
+    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
+        return null;
+    }
+
+    @Override
+    public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStoragePool pool) {
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
+        StoragePool virtPool = libvirtPool.getPool();
+        List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
+        try {
+            String[] vols = virtPool.listVolumes();
+            for (String volName : vols) {
+                KVMPhysicalDisk disk = getPhysicalDisk(volName, pool);
+                disks.add(disk);
+            }
+            return disks;
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+    }
+
+    /**
+     * This copies a volume from Primary Storage to Secondary Storage
+     *
+     * In theory it could also do it the other way around, but the current implementation
+     * in ManagementServerImpl shows that the destPool is always a Secondary Storage Pool
+     */
+    @Override
+    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPool, int timeout) {
+
+        /**
+            With RBD you can't run qemu-img convert with an existing RBD image as destination
+            qemu-img will exit with the error that the destination already exists.
+            So for RBD we don't create the image, but let qemu-img do that for us.
+
+            We then create a KVMPhysicalDisk object that we can return
+
+            It is however very unlikely that the destPool will be RBD, since it isn't supported
+            for Secondary Storage
+         */
+
+        KVMStoragePool srcPool = disk.getPool();
+        PhysicalDiskFormat sourceFormat = disk.getFormat();
+        String sourcePath = disk.getPath();
+
+        KVMPhysicalDisk newDisk;
+        s_logger.debug("copyPhysicalDisk: disk size:" + disk.getSize() + ", virtualsize:" + disk.getVirtualSize()+" format:"+disk.getFormat());
+        if (destPool.getType() != StoragePoolType.RBD) {
+            if (disk.getFormat() == PhysicalDiskFormat.TAR) {
+                newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, Storage.ProvisioningType.THIN, disk.getVirtualSize());
+            } else {
+                    newDisk = destPool.createPhysicalDisk(name, Storage.ProvisioningType.THIN, disk.getVirtualSize());
+            }
+        } else {
+            newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool);
+            newDisk.setFormat(PhysicalDiskFormat.RAW);
+            newDisk.setSize(disk.getVirtualSize());
+            newDisk.setVirtualSize(disk.getSize());
+        }
+
+        String destPath = newDisk.getPath();
+        PhysicalDiskFormat destFormat = newDisk.getFormat();
+
+        QemuImg qemu = new QemuImg(timeout);
+        QemuImgFile srcFile = null;
+        QemuImgFile destFile = null;
+
+        if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
+            if(sourceFormat == PhysicalDiskFormat.TAR && destFormat == PhysicalDiskFormat.DIR) { //LXC template
+                Script.runSimpleBashScript("cp "+ sourcePath + " " + destPath);
+            } else if (sourceFormat == PhysicalDiskFormat.TAR) {
+                Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
+            } else if (sourceFormat == PhysicalDiskFormat.DIR) {
+                Script.runSimpleBashScript("mkdir -p " + destPath);
+                Script.runSimpleBashScript("chmod 755 " + destPath);
+                Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
+            } else {
+                srcFile = new QemuImgFile(sourcePath, sourceFormat);
+                try {
+                    Map<String, String> info = qemu.info(srcFile);
+                    String backingFile = info.get(new String("backing_file"));
+                    // qcow2 templates can just be copied into place
+                    if (sourceFormat.equals(destFormat) && backingFile == null && sourcePath.endsWith(".qcow2")) {
+                        String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
+                        if (result != null) {
+                            throw new CloudRuntimeException("Failed to create disk: " + result);
+                        }
+                    } else {
+                        destFile = new QemuImgFile(destPath, destFormat);
+                        try {
+                            qemu.convert(srcFile, destFile);
+                            Map<String, String> destInfo = qemu.info(destFile);
+                            Long virtualSize = Long.parseLong(destInfo.get(new String("virtual_size")));
+                            newDisk.setVirtualSize(virtualSize);
+                            newDisk.setSize(virtualSize);
+                        } catch (QemuImgException e) {
+                            s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
+                            newDisk = null;
+                        }
+                    }
+                } catch (QemuImgException e) {
+                    s_logger.error("Failed to fetch the information of file " + srcFile.getFileName() + " the error was: " + e.getMessage());
+                    newDisk = null;
+                }
+            }
+        } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) {
+            /**
+             * Using qemu-img we copy the QCOW2 disk to RAW (on RBD) directly.
+             * To do so it's mandatory that librbd on the system is at least 0.67.7 (Ceph Dumpling)
+             */
+            s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2");
+            try {
+                srcFile = new QemuImgFile(sourcePath, sourceFormat);
+                String rbdDestPath = destPool.getSourceDir() + "/" + name;
+                String rbdDestFile = KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
+                        destPool.getSourcePort(),
+                        destPool.getAuthUserName(),
+                        destPool.getAuthSecret(),
+                        rbdDestPath);
+                destFile = new QemuImgFile(rbdDestFile, destFormat);
+
+                s_logger.debug("Starting copy from source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
+                qemu.convert(srcFile, destFile);
+                s_logger.debug("Succesfully converted source image " + srcFile.getFileName() + " to RBD image " + rbdDestPath);
+
+                /* We have to stat the RBD image to see how big it became afterwards */
+                Rados r = new Rados(destPool.getAuthUserName());
+                r.confSet("mon_host", destPool.getSourceHost() + ":" + destPool.getSourcePort());
+                r.confSet("key", destPool.getAuthSecret());
+                r.confSet("client_mount_timeout", "30");
+                r.connect();
+                s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host"));
+
+                IoCTX io = r.ioCtxCreate(destPool.getSourceDir());
+                Rbd rbd = new Rbd(io);
+
+                RbdImage image = rbd.open(name);
+                RbdImageInfo rbdInfo = image.stat();
+                newDisk.setSize(rbdInfo.size);
+                newDisk.setVirtualSize(rbdInfo.size);
+                s_logger.debug("After copy the resulting RBD image " + rbdDestPath + " is " + rbdInfo.size + " bytes long");
+                rbd.close(image);
+
+                r.ioCtxDestroy(io);
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
+                newDisk = null;
+            } catch (RadosException e) {
+                s_logger.error("A Ceph RADOS operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
+                newDisk = null;
+            } catch (RbdException e) {
+                s_logger.error("A Ceph RBD operation failed (" + e.getReturnValue() + "). The error was: " + e.getMessage());
+                newDisk = null;
+            }
+        } else {
+            /**
+                We let Qemu-Img do the work here. Although we could work with librbd and have that do the cloning
+                it doesn't benefit us. It's better to keep the current code in place which works
+             */
+            srcFile =
+                    new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(),
+                            sourcePath));
+            srcFile.setFormat(sourceFormat);
+            destFile = new QemuImgFile(destPath);
+            destFile.setFormat(destFormat);
+
+            try {
+                qemu.convert(srcFile, destFile);
+            } catch (QemuImgException e) {
+                s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
+                newDisk = null;
+            }
+        }
+
+        if (newDisk == null) {
+            throw new CloudRuntimeException("Failed to copy " + disk.getPath() + " to " + name);
+        }
+
+        return newDisk;
+    }
+
+    @Override
+    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool) {
+        return null;
+    }
+
+    @Override
+    public boolean refresh(KVMStoragePool pool) {
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool;
+        StoragePool virtPool = libvirtPool.getPool();
+        try {
+            refreshPool(virtPool);
+        } catch (LibvirtException e) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean deleteStoragePool(KVMStoragePool pool) {
+        return deleteStoragePool(pool.getUuid());
+    }
+
+    private void refreshPool(StoragePool pool) throws LibvirtException {
+        pool.refresh(0);
+        return;
+    }
+
+    private void deleteVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
+        vol.delete(0);
+    }
+
+    private void deleteDirVol(LibvirtStoragePool pool, StorageVol vol) throws LibvirtException {
+        Script.runSimpleBashScript("rm -r --interactive=never " + vol.getPath());
+    }
+
+}
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptorInfo.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StorageAdaptorInfo.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptorInfo.java
rename to plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/StorageAdaptorInfo.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHAConfig.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHAConfig.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHAConfig.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHAConfig.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHAProvider.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHAProvider.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHAProvider.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHAProvider.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/kvm/ha/KVMHostActivityChecker.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/CPUStat.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/CPUStat.java
diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
new file mode 100644
index 0000000..1f28304
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
@@ -0,0 +1,132 @@
+// 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
+// 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.utils.linux;
+
+import com.cloud.hypervisor.kvm.resource.LibvirtCapXMLParser;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.LibvirtException;
+import org.libvirt.NodeInfo;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class KVMHostInfo {
+
+    private static final Logger LOGGER = Logger.getLogger(KVMHostInfo.class);
+
+    private int cpus;
+    private int cpusockets;
+    private long cpuSpeed;
+    private long totalMemory;
+    private long reservedMemory;
+    private long overCommitMemory;
+    private List<String> capabilities = new ArrayList<>();
+
+    public KVMHostInfo(long reservedMemory, long overCommitMemory) {
+        this.reservedMemory = reservedMemory;
+        this.overCommitMemory = overCommitMemory;
+        this.getHostInfoFromLibvirt();
+        this.totalMemory = new MemStat(this.getReservedMemory(), this.getOverCommitMemory()).getTotal();
+    }
+
+    public int getCpus() {
+        return this.cpus;
+    }
+
+    public int getCpuSockets() {
+        return this.cpusockets;
+    }
+
+    public long getCpuSpeed() {
+        return this.cpuSpeed;
+    }
+
+    public long getTotalMemory() {
+        return this.totalMemory;
+    }
+
+    public long getReservedMemory() {
+        return this.reservedMemory;
+    }
+
+    public long getOverCommitMemory() {
+        return this.overCommitMemory;
+    }
+
+    public List<String> getCapabilities() {
+        return this.capabilities;
+    }
+
+    protected static long getCpuSpeed(final NodeInfo nodeInfo) {
+        try (final Reader reader = new FileReader(
+                "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")) {
+            return Long.parseLong(IOUtils.toString(reader).trim()) / 1000;
+        } catch (IOException | NumberFormatException e) {
+            LOGGER.info("Could not read cpuinfo_max_freq, falling back on libvirt");
+            return nodeInfo.mhz;
+        }
+    }
+
+    private void getHostInfoFromLibvirt() {
+        try {
+            final Connect conn = LibvirtConnection.getConnection();
+            final NodeInfo hosts = conn.nodeInfo();
+            this.cpuSpeed = getCpuSpeed(hosts);
+
+            /*
+             * Some CPUs report a single socket and multiple NUMA cells.
+             * We need to multiply them to get the correct socket count.
+             */
+            this.cpusockets = hosts.sockets;
+            if (hosts.nodes > 0) {
+                this.cpusockets = hosts.sockets * hosts.nodes;
+            }
+            this.cpus = hosts.cpus;
+
+            final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
+            parser.parseCapabilitiesXML(conn.getCapabilities());
+            final ArrayList<String> oss = parser.getGuestOsType();
+            for (final String s : oss) {
+                /*
+                 * Even host supports guest os type more than hvm, we only
+                 * report hvm to management server
+                 */
+                String hvmCapability = "hvm";
+                if (s.equalsIgnoreCase(hvmCapability)) {
+                    if (!this.capabilities.contains(hvmCapability)) {
+                        this.capabilities.add(hvmCapability);
+                    }
+                }
+            }
+
+            /*
+                Any modern Qemu/KVM supports snapshots
+                We used to check if this was supported, but that is no longer required
+            */
+            this.capabilities.add("snapshot");
+            conn.close();
+        } catch (final LibvirtException e) {
+            LOGGER.error("Caught libvirt exception while fetching host information", e);
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/MemStat.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/MemStat.java
new file mode 100644
index 0000000..afcdf97
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/MemStat.java
@@ -0,0 +1,87 @@
+// 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
+// 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.utils.linux;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+
+public class MemStat {
+    /*
+        Gather Memory Statistics of the current node by opening /proc/meminfo
+        which contains the memory information in KiloBytes.
+
+        Convert this all to bytes and return Long as a type with the information
+        in bytes
+     */
+    protected final static String MEMINFO_FILE = "/proc/meminfo";
+    protected final static String FREE_KEY = "MemFree";
+    protected final static String CACHE_KEY = "Cached";
+    protected final static String TOTAL_KEY = "MemTotal";
+    long reservedMemory;
+    long overCommitMemory;
+
+    private final Map<String, Long> _memStats = new HashMap<>();
+
+    public MemStat() {
+        this(0,0);
+    }
+
+    public MemStat(long reservedMemory, long overCommitMemory) {
+        this.reservedMemory = reservedMemory;
+        this.overCommitMemory = overCommitMemory;
+        this.refresh();
+    }
+
+    public long getTotal() {
+        return _memStats.get(TOTAL_KEY) - reservedMemory + overCommitMemory;
+    }
+
+    public long getAvailable() {
+        return getFree() + getCache();
+    }
+
+    public long getFree() {
+        return _memStats.get(FREE_KEY) - reservedMemory + overCommitMemory;
+    }
+
+    public long getCache() {
+        return _memStats.get(CACHE_KEY);
+    }
+
+    public void refresh() {
+        File f = new File(MEMINFO_FILE);
+        try (Scanner scanner = new Scanner(f,"UTF-8")) {
+            parseFromScanner(scanner);
+        } catch (FileNotFoundException ex) {
+            throw new RuntimeException("File " + MEMINFO_FILE + " not found:" + ex.toString());
+        }
+    }
+
+    protected void parseFromScanner(Scanner scanner) {
+        scanner.useDelimiter("\\n");
+        while(scanner.hasNext()) {
+            String[] stats = scanner.next().split("\\:\\s+");
+            if (stats.length == 2) {
+                _memStats.put(stats[0], Long.valueOf(stats[1].replaceAll("\\s+\\w+","")) * 1024L);
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImg.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgException.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImgException.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgException.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImgException.java
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImgFile.java
similarity index 100%
rename from plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/qemu/QemuImgFile.java
rename to plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImgFile.java
diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/module.properties b/plugins/hypervisors/kvm/src/main/resources/META-INF/cloudstack/kvm-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/module.properties
rename to plugins/hypervisors/kvm/src/main/resources/META-INF/cloudstack/kvm-compute/module.properties
diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml b/plugins/hypervisors/kvm/src/main/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml
rename to plugins/hypervisors/kvm/src/main/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java
deleted file mode 100644
index 2029af3..0000000
--- a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/MemStat.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// 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.utils.linux;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-
-public class MemStat {
-    protected final static String MEMINFO_FILE = "/proc/meminfo";
-    protected final static String FREE_KEY = "MemFree";
-    protected final static String CACHE_KEY = "Cached";
-    protected final static String TOTAL_KEY = "MemTotal";
-
-    private final Map<String, Double> _memStats = new HashMap<String, Double>();
-
-    public MemStat() {
-    }
-
-    public Double getTotal() {
-        return _memStats.get(TOTAL_KEY);
-    }
-
-    public Double getAvailable() {
-        return getFree() + getCache();
-    }
-
-    public Double getFree() {
-        return _memStats.get(FREE_KEY);
-    }
-
-    public Double getCache() {
-        return _memStats.get(CACHE_KEY);
-    }
-
-    public void refresh() {
-        File f = new File(MEMINFO_FILE);
-        try (Scanner scanner = new Scanner(f,"UTF-8")) {
-            parseFromScanner(scanner);
-        } catch (FileNotFoundException ex) {
-            throw new RuntimeException("File " + MEMINFO_FILE + " not found:" + ex.toString());
-        }
-    }
-
-    protected void parseFromScanner(Scanner scanner) {
-        scanner.useDelimiter("\\n");
-        while(scanner.hasNext()) {
-            String[] stats = scanner.next().split("\\:\\s+");
-            if (stats.length == 2) {
-                _memStats.put(stats[0], Double.valueOf(stats[1].replaceAll("\\s+\\w+","")));
-            }
-        }
-    }
-}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/BridgeVifDriverTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriverTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/BridgeVifDriverTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriverTest.java
diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
new file mode 100644
index 0000000..0a5c3d6
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@ -0,0 +1,5250 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.Vector;
+
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
+import org.apache.commons.lang.SystemUtils;
+import org.joda.time.Duration;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainBlockStats;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.DomainInterfaceStats;
+import org.libvirt.LibvirtException;
+import org.libvirt.MemoryStatistic;
+import org.libvirt.NodeInfo;
+import org.libvirt.StorageVol;
+import org.libvirt.jna.virDomainMemoryStats;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckRouterAnswer;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.CleanupNetworkRulesCmd;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmDiskStatsCommand;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifySshKeysCommand;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.OvsCreateTunnelCommand;
+import com.cloud.agent.api.OvsDestroyBridgeCommand;
+import com.cloud.agent.api.OvsDestroyTunnelCommand;
+import com.cloud.agent.api.OvsFetchInterfaceCommand;
+import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Host;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Tier;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Vm;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Acl;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.RebootRouterCommand;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.UpdateHostPasswordCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.storage.ResizeVolumeCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
+import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper;
+import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper;
+import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
+import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachine.Type;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LibvirtComputingResourceTest {
+
+    @Mock
+    private LibvirtComputingResource libvirtComputingResource;
+    @Mock
+    VirtualMachineTO vmTO;
+    @Mock
+    LibvirtVMDef vmDef;
+
+    String hyperVisorType = "kvm";
+    Random random = new Random();
+
+    /**
+     This test tests if the Agent can handle a vmSpec coming
+     from a <=4.1 management server.
+
+     The overcommit feature has not been merged in there and thus
+     only 'speed' is set.
+     */
+    @Test
+    public void testCreateVMFromSpecLegacy() {
+        final int id = random.nextInt(65534);
+        final String name = "test-instance-1";
+
+        final int cpus = random.nextInt(2) + 1;
+        final int speed = 1024;
+        final int minRam = 256 * 1024;
+        final int maxRam = 512 * 1024;
+
+        final String os = "Ubuntu";
+
+        final String vncAddr = "";
+        final String vncPassword = "mySuperSecretPassword";
+
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr._qemuSocketsPath = new File("/var/run/qemu");
+
+        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
+        to.setVncAddr(vncAddr);
+        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
+
+        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
+        vm.setHvsType(hyperVisorType);
+
+        verifyVm(to, vm);
+    }
+
+    /**
+     This test verifies that CPU topology is properly set for hex-core
+     */
+    @Test
+    public void testCreateVMFromSpecWithTopology6() {
+        final int id = random.nextInt(65534);
+        final String name = "test-instance-1";
+
+        final int cpus = 12;
+        final int minSpeed = 1024;
+        final int maxSpeed = 2048;
+        final int minRam = 256 * 1024;
+        final int maxRam = 512 * 1024;
+
+        final String os = "Ubuntu";
+
+        final String vncAddr = "";
+        final String vncPassword = "mySuperSecretPassword";
+
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr._qemuSocketsPath = new File("/var/run/qemu");
+
+        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
+        to.setVncAddr(vncAddr);
+        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
+
+        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
+        vm.setHvsType(hyperVisorType);
+
+        verifyVm(to, vm);
+    }
+
+    /**
+     This test verifies that CPU topology is properly set for quad-core
+     */
+    @Test
+    public void testCreateVMFromSpecWithTopology4() {
+        final int id = random.nextInt(65534);
+        final String name = "test-instance-1";
+
+        final int cpus = 8;
+        final int minSpeed = 1024;
+        final int maxSpeed = 2048;
+        final int minRam = 256 * 1024;
+        final int maxRam = 512 * 1024;
+
+        final String os = "Ubuntu";
+
+        final String vncAddr = "";
+        final String vncPassword = "mySuperSecretPassword";
+
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr._qemuSocketsPath = new File("/var/run/qemu");
+
+        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
+        to.setVncAddr(vncAddr);
+        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
+
+        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
+        vm.setHvsType(hyperVisorType);
+
+        verifyVm(to, vm);
+    }
+
+    /**
+     This test tests if the Agent can handle a vmSpec coming
+     from a >4.1 management server.
+
+     It tests if the Agent can handle a vmSpec with overcommit
+     data like minSpeed and maxSpeed in there
+     */
+    @Test
+    public void testCreateVMFromSpec() {
+        final int id = random.nextInt(65534);
+        final String name = "test-instance-1";
+
+        final int cpus = random.nextInt(2) + 1;
+        final int minSpeed = 1024;
+        final int maxSpeed = 2048;
+        final int minRam = 256 * 1024;
+        final int maxRam = 512 * 1024;
+
+        final String os = "Ubuntu";
+
+        final String vncAddr = "";
+        final String vncPassword = "mySuperSecretPassword";
+
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr._qemuSocketsPath = new File("/var/run/qemu");
+
+        final VirtualMachineTO to =
+                new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
+        to.setVncAddr(vncAddr);
+        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
+
+        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
+        vm.setHvsType(hyperVisorType);
+
+        verifyVm(to, vm);
+    }
+
+    private void verifyVm(final VirtualMachineTO to, final LibvirtVMDef vm) {
+        final Document domainDoc = parse(vm.toString());
+        assertXpath(domainDoc, "/domain/@type", vm.getHvsType());
+        assertXpath(domainDoc, "/domain/name/text()", to.getName());
+        assertXpath(domainDoc, "/domain/uuid/text()", to.getUuid());
+        assertXpath(domainDoc, "/domain/description/text()", to.getOs());
+        assertXpath(domainDoc, "/domain/clock/@offset", "utc");
+        assertNodeExists(domainDoc, "/domain/features/pae");
+        assertNodeExists(domainDoc, "/domain/features/apic");
+        assertNodeExists(domainDoc, "/domain/features/acpi");
+        assertXpath(domainDoc, "/domain/devices/serial/@type", "pty");
+        assertXpath(domainDoc, "/domain/devices/serial/target/@port", "0");
+        assertXpath(domainDoc, "/domain/devices/graphics/@type", "vnc");
+        assertXpath(domainDoc, "/domain/devices/graphics/@listen", to.getVncAddr());
+        assertXpath(domainDoc, "/domain/devices/graphics/@autoport", "yes");
+        assertXpath(domainDoc, "/domain/devices/graphics/@passwd", to.getVncPassword());
+
+        assertXpath(domainDoc, "/domain/devices/console/@type", "pty");
+        assertXpath(domainDoc, "/domain/devices/console/target/@port", "0");
+        assertXpath(domainDoc, "/domain/devices/input/@type", "tablet");
+        assertXpath(domainDoc, "/domain/devices/input/@bus", "usb");
+
+        assertNodeExists(domainDoc, "/domain/devices/channel");
+        assertXpath(domainDoc, "/domain/devices/channel/@type", ChannelDef.ChannelType.UNIX.toString());
+
+        /*
+           The configure() method of LibvirtComputingResource has not been called, so the default path for the sockets
+           hasn't been initialized. That's why we check for 'null'
+
+           Calling configure is also not possible since that looks for certain files on the system which are not present
+           during testing
+         */
+        assertXpath(domainDoc, "/domain/devices/channel/source/@path", "/var/run/qemu/" + to.getName() + ".org.qemu.guest_agent.0");
+        assertXpath(domainDoc, "/domain/devices/channel/target/@name", "org.qemu.guest_agent.0");
+
+        assertXpath(domainDoc, "/domain/memory/text()", String.valueOf( to.getMaxRam() / 1024 ));
+        assertXpath(domainDoc, "/domain/currentMemory/text()", String.valueOf( to.getMinRam() / 1024 ));
+
+        assertXpath(domainDoc, "/domain/devices/memballoon/@model", "virtio");
+        assertXpath(domainDoc, "/domain/vcpu/text()", String.valueOf(to.getCpus()));
+
+        assertXpath(domainDoc, "/domain/os/type/@machine", "pc");
+        assertXpath(domainDoc, "/domain/os/type/text()", "hvm");
+
+        assertNodeExists(domainDoc, "/domain/cpu");
+        assertNodeExists(domainDoc, "/domain/os/boot[@dev='cdrom']");
+        assertNodeExists(domainDoc, "/domain/os/boot[@dev='hd']");
+
+        assertXpath(domainDoc, "/domain/on_reboot/text()", "restart");
+        assertXpath(domainDoc, "/domain/on_poweroff/text()", "destroy");
+        assertXpath(domainDoc, "/domain/on_crash/text()", "destroy");
+
+        assertXpath(domainDoc, "/domain/devices/watchdog/@model", "i6300esb");
+        assertXpath(domainDoc, "/domain/devices/watchdog/@action", "none");
+    }
+
+    static Document parse(final String input) {
+        try {
+            return DocumentBuilderFactory.newInstance().newDocumentBuilder()
+                    .parse(new ByteArrayInputStream(input.getBytes()));
+        } catch (SAXException | IOException | ParserConfigurationException e) {
+            throw new IllegalArgumentException("Cloud not parse: "+input, e);
+        }
+    }
+
+    static void assertNodeExists(final Document doc, final String xPathExpr) {
+        try {
+            Assert.assertNotNull(XPathFactory.newInstance().newXPath()
+                    .evaluate(xPathExpr, doc, XPathConstants.NODE));
+        } catch (final XPathExpressionException e) {
+            Assert.fail(e.getMessage());
+        }
+    }
+
+    static void assertXpath(final Document doc, final String xPathExpr,
+                            final String expected) {
+        try {
+            Assert.assertEquals(expected, XPathFactory.newInstance().newXPath()
+                    .evaluate(xPathExpr, doc));
+        } catch (final XPathExpressionException e) {
+            Assert.fail("Could not evaluate xpath" + xPathExpr + ":"
+                    + e.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetNicStats() {
+        //this test is only working on linux because of the loopback interface name
+        //also the tested code seems to work only on linux
+        Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
+        final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
+        final Pair<Double, Double> stats = libvirtComputingResource.getNicStats("lo");
+        assertNotNull(stats);
+    }
+
+    @Test
+    public void diskUuidToSerialTest() {
+        final String uuid = "38400000-8cf0-11bd-b24e-10b96e4ef00d";
+        final String expected = "384000008cf011bdb24e";
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        Assert.assertEquals(expected, lcr.diskUuidToSerial(uuid));
+    }
+
+    @Test
+    public void testUUID() {
+        String uuid = "1";
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        uuid = lcr.getUuid(uuid);
+        Assert.assertTrue(!uuid.equals("1"));
+
+        final String oldUuid = UUID.randomUUID().toString();
+        uuid = oldUuid;
+        uuid = lcr.getUuid(uuid);
+        Assert.assertTrue(uuid.equals(oldUuid));
+    }
+
+    private static final String VMNAME = "test";
+
+    @Test
+    public void testGetVmStat() throws LibvirtException {
+        final Connect connect = Mockito.mock(Connect.class);
+        final Domain domain = Mockito.mock(Domain.class);
+        final DomainInfo domainInfo = new DomainInfo();
+        final MemoryStatistic[] domainMem = new MemoryStatistic[2];
+        domainMem[0] = Mockito.mock(MemoryStatistic.class);
+        Mockito.when(domain.getInfo()).thenReturn(domainInfo);
+        Mockito.when(domain.memoryStats(2)).thenReturn(domainMem);
+        Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain);
+        final NodeInfo nodeInfo = new NodeInfo();
+        nodeInfo.cpus = 8;
+        nodeInfo.memory = 8 * 1024 * 1024;
+        nodeInfo.sockets = 2;
+        nodeInfo.threads = 2;
+        nodeInfo.model = "Foo processor";
+        Mockito.when(connect.nodeInfo()).thenReturn(nodeInfo);
+        // this is testing the interface stats, returns an increasing number of sent and received bytes
+        Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainInterfaceStats>() {
+            // increment with less than a KB, so this should be less than 1 KB
+            final static int increment = 1000;
+            int rxBytes = 1000;
+            int txBytes = 1000;
+
+            @Override
+            public DomainInterfaceStats answer(final InvocationOnMock invocation) throws Throwable {
+                final DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats();
+                domainInterfaceStats.rx_bytes = rxBytes += increment;
+                domainInterfaceStats.tx_bytes = txBytes += increment;
+                return domainInterfaceStats;
+
+            }
+
+        });
+
+        Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainBlockStats>() {
+            // a little less than a KB
+            final static int increment = 1000;
+
+            int rdBytes = 0;
+            int wrBytes = 1024;
+
+            @Override
+            public DomainBlockStats answer(final InvocationOnMock invocation) throws Throwable {
+                final DomainBlockStats domainBlockStats = new DomainBlockStats();
+
+                domainBlockStats.rd_bytes = rdBytes += increment;
+                domainBlockStats.wr_bytes = wrBytes += increment;
+                return domainBlockStats;
+            }
+
+        });
+
+        final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() {
+            @Override
+            public List<InterfaceDef> getInterfaces(final Connect conn, final String vmName) {
+                final InterfaceDef interfaceDef = new InterfaceDef();
+                return Arrays.asList(interfaceDef);
+            }
+
+            @Override
+            public List<DiskDef> getDisks(final Connect conn, final String vmName) {
+                final DiskDef diskDef = new DiskDef();
+                return Arrays.asList(diskDef);
+            }
+
+        };
+        libvirtComputingResource.getVmStat(connect, VMNAME);
+        final VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME);
+        // network traffic as generated by the logic above, must be greater than zero
+        Assert.assertTrue(vmStat.getNetworkReadKBs() > 0);
+        Assert.assertTrue(vmStat.getNetworkWriteKBs() > 0);
+        // IO traffic as generated by the logic above, must be greater than zero
+        Assert.assertTrue(vmStat.getDiskReadKBs() > 0);
+        Assert.assertTrue(vmStat.getDiskWriteKBs() > 0);
+        // Memory limit of VM must be greater than zero
+        Assert.assertTrue(vmStat.getIntFreeMemoryKBs() >= 0);
+        Assert.assertTrue(vmStat.getMemoryKBs() >= 0);
+        Assert.assertTrue(vmStat.getTargetMemoryKBs() >= vmStat.getMemoryKBs());
+    }
+
+    /*
+     * New Tests
+     */
+
+    @Test
+    public void testStopCommandNoCheck() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final StopCommand command = new StopCommand(vmName, false, false);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStopCommandCheckVmNOTRunning() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final DomainInfo info = Mockito.mock(DomainInfo.class);
+        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_SHUTDOWN;
+        info.state = state;
+
+        final String vmName = "Test";
+        final StopCommand command = new StopCommand(vmName, false, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
+
+            when(vm.getInfo()).thenReturn(info);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testStopCommandCheckException1() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final DomainInfo info = Mockito.mock(DomainInfo.class);
+        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
+        info.state = state;
+
+        final String vmName = "Test";
+        final StopCommand command = new StopCommand(vmName, false, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
+            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
+
+            when(vm.getInfo()).thenReturn(info);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStopCommandCheckVmRunning() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final DomainInfo info = Mockito.mock(DomainInfo.class);
+        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
+        info.state = state;
+
+        final String vmName = "Test";
+        final StopCommand command = new StopCommand(vmName, false, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
+
+            when(vm.getInfo()).thenReturn(info);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetVmStatsCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
+        final List<String> vms = new ArrayList<String>();
+        vms.add(vmName);
+
+        final GetVmStatsCommand command = new GetVmStatsCommand(vms, uuid, "hostname");
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetVmDiskStatsCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
+        final List<String> vms = new ArrayList<String>();
+        vms.add(vmName);
+
+        final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname");
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnection();
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testGetVmDiskStatsCommandException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
+        final List<String> vms = new ArrayList<String>();
+        vms.add(vmName);
+
+        final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname");
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnection();
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testRebootCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootCommand command = new RebootCommand(vmName, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRebootCommandException1() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootCommand command = new RebootCommand(vmName, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testRebootCommandError() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootCommand command = new RebootCommand(vmName, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenReturn("error");
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRebootCommandException2() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootCommand command = new RebootCommand(vmName, true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testRebootRouterCommand() {
+        final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootRouterCommand command = new RebootRouterCommand(vmName, "127.0.0.1");
+
+        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testRebootRouterCommandConnect() {
+        final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final RebootRouterCommand command = new RebootRouterCommand(vmName, "127.0.0.1");
+
+        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(routingResource.connect(command.getPrivateIpAddress())).thenReturn(true);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetHostStatsCommand() {
+        // A bit difficult to test due to the logger being passed and the parser itself relying on the connection.
+        // Have to spend some more time afterwards in order to refactor the wrapper itself.
+        final CPUStat cpuStat = Mockito.mock(CPUStat.class);
+        final MemStat memStat = Mockito.mock(MemStat.class);
+
+        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
+        final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l);
+
+        when(libvirtComputingResource.getCPUStat()).thenReturn(cpuStat);
+        when(libvirtComputingResource.getMemStat()).thenReturn(memStat);
+        when(libvirtComputingResource.getNicStats(Mockito.anyString())).thenReturn(new Pair<Double, Double>(1.0d, 1.0d));
+        when(cpuStat.getCpuUsedPercent()).thenReturn(0.5d);
+        when(memStat.getAvailable()).thenReturn(1500L);
+        when(memStat.getTotal()).thenReturn(15000L);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getCPUStat();
+        verify(libvirtComputingResource, times(1)).getMemStat();
+        verify(cpuStat, times(1)).getCpuUsedPercent();
+        verify(memStat, times(1)).getAvailable();
+        verify(memStat, times(1)).getTotal();
+    }
+
+    @Test
+    public void testCheckHealthCommand() {
+        final CheckHealthCommand command = new CheckHealthCommand();
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testPrepareForMigrationCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
+        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final NicTO nicTO = Mockito.mock(NicTO.class);
+        final DiskTO diskTO = Mockito.mock(DiskTO.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+
+        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
+        when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO});
+
+        when(nicTO.getType()).thenReturn(TrafficType.Guest);
+        when(diskTO.getType()).thenReturn(Volume.Type.ISO);
+
+        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(vm, times(1)).getNics();
+        verify(vm, times(1)).getDisks();
+        verify(diskTO, times(1)).getType();
+    }
+
+    @Test
+    public void testPrepareForMigrationCommandMigration() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
+        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final NicTO nicTO = Mockito.mock(NicTO.class);
+        final DiskTO diskTO = Mockito.mock(DiskTO.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+
+        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
+        when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO});
+
+        when(nicTO.getType()).thenReturn(TrafficType.Guest);
+        when(diskTO.getType()).thenReturn(Volume.Type.ISO);
+
+        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
+        when(storagePoolManager.connectPhysicalDisksViaVmSpec(vm)).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(vm, times(1)).getNics();
+        verify(vm, times(1)).getDisks();
+        verify(diskTO, times(1)).getType();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPrepareForMigrationCommandLibvirtException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
+        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final NicTO nicTO = Mockito.mock(NicTO.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+
+        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
+        when(nicTO.getType()).thenReturn(TrafficType.Guest);
+
+        when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver);
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(vm, times(1)).getNics();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPrepareForMigrationCommandURISyntaxException() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
+        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final NicTO nicTO = Mockito.mock(NicTO.class);
+        final DiskTO volume = Mockito.mock(DiskTO.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+
+        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
+        when(vm.getDisks()).thenReturn(new DiskTO[]{volume});
+
+        when(nicTO.getType()).thenReturn(TrafficType.Guest);
+        when(volume.getType()).thenReturn(Volume.Type.ISO);
+
+        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
+        try {
+            when(libvirtComputingResource.getVolumePath(conn, volume)).thenThrow(URISyntaxException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(vm, times(1)).getNics();
+        verify(vm, times(1)).getDisks();
+        verify(volume, times(1)).getType();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPrepareForMigrationCommandInternalErrorException() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
+        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final NicTO nicTO = Mockito.mock(NicTO.class);
+        final DiskTO volume = Mockito.mock(DiskTO.class);
+
+        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
+        when(nicTO.getType()).thenReturn(TrafficType.Guest);
+
+        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenThrow(InternalErrorException.class);
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
+        try {
+            when(libvirtComputingResource.getVolumePath(conn, volume)).thenReturn("/path");
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(vm, times(1)).getNics();
+    }
+
+    @Test
+    public void testMigrateCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final Connect dconn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final String destIp = "127.0.0.100";
+        final boolean isWindows = false;
+        final VirtualMachineTO vmTO = Mockito.mock(VirtualMachineTO.class);
+        final boolean executeInSequence = false;
+
+        final MigrateCommand command = new MigrateCommand(vmName, destIp, isWindows, vmTO, executeInSequence );
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(libvirtUtilitiesHelper.retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system")).thenReturn(dconn);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+        final List<InterfaceDef> ifaces = new ArrayList<InterfaceDef>();
+        ifaces.add(interfaceDef);
+
+        when(libvirtComputingResource.getInterfaces(conn, vmName)).thenReturn(ifaces);
+
+        final DiskDef diskDef = Mockito.mock(DiskDef.class);
+        final List<DiskDef> disks = new ArrayList<DiskDef>();
+        disks.add(diskDef);
+
+        when(libvirtComputingResource.getDisks(conn, vmName)).thenReturn(disks);
+        final Domain dm = Mockito.mock(Domain.class);
+        try {
+            when(conn.domainLookupByName(vmName)).thenReturn(dm);
+
+            when(libvirtComputingResource.getPrivateIp()).thenReturn("127.0.0.1");
+            when(dm.getXMLDesc(8)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
+                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
+            when(dm.getXMLDesc(1)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
+                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
+            when(dm.isPersistent()).thenReturn(1);
+            doNothing().when(dm).undefine();
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final Exception e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+            verify(libvirtUtilitiesHelper, times(1)).retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system");
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        verify(libvirtComputingResource, times(1)).getInterfaces(conn, vmName);
+        verify(libvirtComputingResource, times(1)).getDisks(conn, vmName);
+        try {
+            verify(conn, times(1)).domainLookupByName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        try {
+            verify(dm, times(1)).getXMLDesc(8);
+        } catch (final Throwable t) {
+            try {
+                verify(dm, times(1)).getXMLDesc(1);
+            }
+            catch (final LibvirtException e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void testPingTestHostIpCommand() {
+        final PingTestCommand command = new PingTestCommand("127.0.0.1");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testPingTestPvtIpCommand() {
+        final PingTestCommand command = new PingTestCommand("127.0.0.1", "127.0.0.1");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testPingOnlyOneIpCommand() {
+        final PingTestCommand command = new PingTestCommand("127.0.0.1", null);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testCheckVirtualMachineCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExceptionCheckVirtualMachineCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testReadyCommand() {
+        final ReadyCommand command = new ReadyCommand(1l);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testAttachIsoCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testAttachIsoCommandLibvirtException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testAttachIsoCommandURISyntaxException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(URISyntaxException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testAttachIsoCommandInternalErrorException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String vmName = "Test";
+        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testWatchConsoleProxyLoadCommand() {
+        final int interval = 0;
+        final long proxyVmId = 0l;
+        final String proxyVmName = "host";
+        final String proxyManagementIp = "127.0.0.1";
+        final int proxyCmdPort = 0;
+
+        final WatchConsoleProxyLoadCommand command = new WatchConsoleProxyLoadCommand(interval, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testCheckConsoleProxyLoadCommand() {
+        final long proxyVmId = 0l;
+        final String proxyVmName = "host";
+        final String proxyManagementIp = "127.0.0.1";
+        final int proxyCmdPort = 0;
+
+        final CheckConsoleProxyLoadCommand command = new CheckConsoleProxyLoadCommand(proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testGetVncPortCommand() {
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final GetVncPortCommand command = new GetVncPortCommand(1l, "host");
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetVncPortCommandLibvirtException() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final GetVncPortCommand command = new GetVncPortCommand(1l, "host");
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testModifySshKeysCommand() {
+        final ModifySshKeysCommand command = new ModifySshKeysCommand("", "");
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        when(libvirtUtilitiesHelper.retrieveSshKeysPath()).thenReturn("/path/keys");
+        when(libvirtUtilitiesHelper.retrieveSshPubKeyPath()).thenReturn("/path/pub/keys");
+        when(libvirtUtilitiesHelper.retrieveSshPrvKeyPath()).thenReturn("/path/pvt/keys");
+
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getTimeout();
+    }
+
+    @Test
+    public void testMaintainCommand() {
+        final MaintainCommand command = new MaintainCommand();
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testCreateCommandNoTemplate() {
+        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final boolean executeInSequence = false;
+
+        final CreateCommand command = new CreateCommand(diskCharacteristics, pool, executeInSequence );
+
+        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
+        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+
+        when(primary.createPhysicalDisk(diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), diskCharacteristics.getSize())).thenReturn(vol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
+    }
+
+    @Test
+    public void testCreateCommand() {
+        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final String templateUrl = "http://template";
+        final boolean executeInSequence = false;
+
+        final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
+
+        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
+        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+
+        when(primary.getType()).thenReturn(StoragePoolType.CLVM);
+        when(libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primary, diskCharacteristics.getPath())).thenReturn(vol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
+    }
+
+    @Test
+    public void testCreateCommandCLVM() {
+        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final String templateUrl = "http://template";
+        final boolean executeInSequence = false;
+
+        final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
+
+        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMPhysicalDisk baseVol = Mockito.mock(KVMPhysicalDisk.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
+        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+
+        when(primary.getPhysicalDisk(command.getTemplateUrl())).thenReturn(baseVol);
+        when(poolManager.createDiskFromTemplate(baseVol, diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), primary, baseVol.getSize(), 0)).thenReturn(vol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
+    }
+
+    @Test
+    public void testDestroyCommand() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final Volume volume = Mockito.mock(Volume.class);
+        final String vmName = "Test";
+
+        final DestroyCommand command = new DestroyCommand(pool, volume, vmName);
+
+        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final VolumeTO vol = command.getVolume();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
+        when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testDestroyCommandError() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final Volume volume = Mockito.mock(Volume.class);
+        final String vmName = "Test";
+
+        final DestroyCommand command = new DestroyCommand(pool, volume, vmName);
+
+        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final VolumeTO vol = command.getVolume();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
+        when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary);
+
+        when(primary.deletePhysicalDisk(vol.getPath(), null)).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPrimaryStorageDownloadCommandNOTemplateDisk() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+
+        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
+
+        final String name = "Test";
+        final String url = "http://template/";
+        final ImageFormat format = ImageFormat.QCOW2;
+        final long accountId = 1l;
+        final int wait = 0;
+        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
+
+        final KVMPhysicalDisk disk = new KVMPhysicalDisk("/path", "disk.qcow2", primaryPool);
+        disks.add(disk);
+
+        final int index = url.lastIndexOf("/");
+        final String mountpoint = url.substring(0, index);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
+        when(secondaryPool.listPhysicalDisks()).thenReturn(disks);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
+        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testPrimaryStorageDownloadCommandNOTemplateNODisk() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+
+        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
+
+        final String name = "Test";
+        final String url = "http://template/";
+        final ImageFormat format = ImageFormat.QCOW2;
+        final long accountId = 1l;
+        final int wait = 0;
+        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
+
+        final int index = url.lastIndexOf("/");
+        final String mountpoint = url.substring(0, index);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
+        when(secondaryPool.listPhysicalDisks()).thenReturn(disks);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
+        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testPrimaryStorageDownloadCommandNOTemplateNOQcow2() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+
+        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
+        final List<KVMPhysicalDisk> spiedDisks = Mockito.spy(disks);
+
+        final String name = "Test";
+        final String url = "http://template/";
+        final ImageFormat format = ImageFormat.QCOW2;
+        final long accountId = 1l;
+        final int wait = 0;
+        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
+
+        final int index = url.lastIndexOf("/");
+        final String mountpoint = url.substring(0, index);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
+        when(secondaryPool.listPhysicalDisks()).thenReturn(spiedDisks);
+        when(spiedDisks.isEmpty()).thenReturn(false);
+
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
+        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPrimaryStorageDownloadCommandTemplateNoDisk() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+
+        final String name = "Test";
+        final String url = "http://template/template.qcow2";
+        final ImageFormat format = ImageFormat.VHD;
+        final long accountId = 1l;
+        final int wait = 0;
+        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
+
+        final int index = url.lastIndexOf("/");
+        final String mountpoint = url.substring(0, index);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
+        when(secondaryPool.getPhysicalDisk("template.qcow2")).thenReturn(tmplVol);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
+        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPoolUuid());
+    }
+
+    @Test
+    public void testGetStorageStatsCommand() {
+        final DataStoreTO store = Mockito.mock(DataStoreTO.class);
+        final GetStorageStatsCommand command = new GetStorageStatsCommand(store );
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true)).thenReturn(secondaryPool);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePool(command.getPooltype(), command.getStorageId(), true);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetStorageStatsCommandException() {
+        final DataStoreTO store = Mockito.mock(DataStoreTO.class);
+        final GetStorageStatsCommand command = new GetStorageStatsCommand(store );
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testUpgradeSnapshotCommand() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final String secondaryStoragePoolURL = "url";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final Long templateId = 1l;
+        final Long tmpltAccountId = 1l;
+        final String volumePath = "/opt/path";
+        final String snapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
+        final String snapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
+        final String version = "1";
+
+        final UpgradeSnapshotCommand command = new UpgradeSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, templateId, tmpltAccountId, volumePath, snapshotUuid, snapshotName, version);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testDeleteStoragePoolCommand() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+
+        final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool);
+
+        final StorageFilerTO pool = command.getPool();
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testDeleteStoragePoolCommandException() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+
+        final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool);
+
+        final StorageFilerTO pool = command.getPool();
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid());
+    }
+
+    @Test
+    public void testOvsSetupBridgeCommand() {
+        final String name = "Test";
+        final Long hostId = 1l;
+        final Long networkId = 1l;
+
+        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName())).thenReturn(true);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsSetupBridgeCommandFailure1() {
+        final String name = "Test";
+        final Long hostId = 1l;
+        final Long networkId = 1l;
+
+        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName())).thenReturn(false);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsSetupBridgeCommandFailure2() {
+        final String name = "Test";
+        final Long hostId = 1l;
+        final Long networkId = 1l;
+
+        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName())).thenReturn(true);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
+                command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsDestroyBridgeCommand() {
+        final String name = "Test";
+        final Long hostId = 1l;
+        final Long networkId = 1l;
+
+        final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId);
+
+        when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(true);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsDestroyBridgeCommandFailure() {
+        final String name = "Test";
+        final Long hostId = 1l;
+        final Long networkId = 1l;
+
+        final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId);
+
+        when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(false);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsFetchInterfaceCommand() {
+        final String label = "eth0";
+
+        final OvsFetchInterfaceCommand command = new OvsFetchInterfaceCommand(label);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testOvsVpcPhysicalTopologyConfigCommand() {
+        final Host[] hosts = null;
+        final Tier[] tiers = null;
+        final Vm[] vms = null;
+        final String cidr = null;
+
+        final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr);
+
+        when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path");
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
+        verify(libvirtComputingResource, times(1)).getTimeout();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testOvsVpcPhysicalTopologyConfigCommandFailure() {
+        final Host[] hosts = null;
+        final Tier[] tiers = null;
+        final Vm[] vms = null;
+        final String cidr = null;
+
+        final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr);
+
+        when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
+    }
+
+    @Test
+    public void testOvsVpcRoutingPolicyConfigCommand() {
+        final String id = null;
+        final String cidr = null;
+        final Acl[] acls = null;
+        final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null;
+
+        final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers);
+
+        when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path");
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
+        verify(libvirtComputingResource, times(1)).getTimeout();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testOvsVpcRoutingPolicyConfigCommandFailure() {
+        final String id = null;
+        final String cidr = null;
+        final Acl[] acls = null;
+        final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null;
+
+        final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers);
+
+        when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
+    }
+
+    @Test
+    public void testCreateStoragePoolCommand() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final CreateStoragePoolCommand command = new CreateStoragePoolCommand(true, pool);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testModifyStoragePoolCommand() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool kvmStoragePool = Mockito.mock(KVMStoragePool.class);
+
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
+                .getUserInfo(), command.getPool().getType())).thenReturn(kvmStoragePool);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
+                .getUserInfo(), command.getPool().getType());
+    }
+
+    @Test
+    public void testModifyStoragePoolCommandFailure() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
+                .getUserInfo(), command.getPool().getType())).thenReturn(null);
+
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
+                .getUserInfo(), command.getPool().getType());
+    }
+
+    @Test
+    public void testCleanupNetworkRulesCmd() {
+        final CleanupNetworkRulesCmd command = new CleanupNetworkRulesCmd(1);
+
+        when(libvirtComputingResource.cleanupRules()).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).cleanupRules();
+    }
+
+    @Test
+    public void testNetworkRulesVmSecondaryIpCommand() {
+        final String vmName = "Test";
+        final String vmMac = "00:00:00:00";
+        final String secondaryIp = "127.0.0.1";
+        final boolean action = true;
+
+        final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action );
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        when(libvirtComputingResource.configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        verify(libvirtComputingResource, times(1)).configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testNetworkRulesVmSecondaryIpCommandFailure() {
+        final String vmName = "Test";
+        final String vmMac = "00:00:00:00";
+        final String secondaryIp = "127.0.0.1";
+        final boolean action = true;
+
+        final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action );
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+    }
+
+    @Test
+    public void testNetworkRulesSystemVmCommand() {
+        final String vmName = "Test";
+        final Type type = Type.SecondaryStorageVm;
+
+        final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        when(libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, command.getVmName())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        verify(libvirtComputingResource, times(1)).configureDefaultNetworkRulesForSystemVm(conn, command.getVmName());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testNetworkRulesSystemVmCommandFailure() {
+        final String vmName = "Test";
+        final Type type = Type.SecondaryStorageVm;
+
+        final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+    }
+
+    @Test
+    public void testCheckSshCommand() {
+        final String instanceName = "Test";
+        final String ip = "127.0.0.1";
+        final int port = 22;
+
+        final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port);
+
+        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
+
+        final String privateIp = command.getIp();
+        final int cmdPort = command.getPort();
+
+        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
+        when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
+        verify(virtRouterResource, times(1)).connect(privateIp, cmdPort);
+    }
+
+    @Test
+    public void testCheckSshCommandFailure() {
+        final String instanceName = "Test";
+        final String ip = "127.0.0.1";
+        final int port = 22;
+
+        final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port);
+
+        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
+
+        final String privateIp = command.getIp();
+        final int cmdPort = command.getPort();
+
+        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
+        when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
+        verify(virtRouterResource, times(1)).connect(privateIp, cmdPort);
+    }
+
+    @Test
+    public void testCheckNetworkCommand() {
+        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+
+        final PhysicalNetworkSetupInfo nic = Mockito.mock(PhysicalNetworkSetupInfo.class);
+        networkInfoList.add(nic);
+
+        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
+
+        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, nic.getGuestNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.checkNetwork(TrafficType.Management, nic.getPrivateNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.checkNetwork(TrafficType.Public, nic.getPublicNetworkName())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, nic.getGuestNetworkName());
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, nic.getPrivateNetworkName());
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Public, nic.getPublicNetworkName());
+    }
+
+    @Test
+    public void testCheckNetworkCommandFail1() {
+        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+
+        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
+        networkInfoList.add(networkSetupInfo);
+
+        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
+
+        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
+    }
+
+    @Test
+    public void testCheckNetworkCommandFail2() {
+        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+
+        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
+        networkInfoList.add(networkSetupInfo);
+
+        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
+
+        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
+    }
+
+    @Test
+    public void testCheckNetworkCommandFail3() {
+        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+
+        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
+        networkInfoList.add(networkSetupInfo);
+
+        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
+
+        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.checkNetwork(TrafficType.Public, networkSetupInfo.getPublicNetworkName())).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
+        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
+    }
+
+    @Test
+    public void testOvsDestroyTunnelCommand() {
+        final String networkName = "Test";
+        final Long networkId = 1l;
+        final String inPortName = "eth";
+
+        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+    }
+
+    @Test
+    public void testOvsDestroyTunnelCommandFailure1() {
+        final String networkName = "Test";
+        final Long networkId = 1l;
+        final String inPortName = "eth";
+
+        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testOvsDestroyTunnelCommandFailure2() {
+        final String networkName = "Test";
+        final Long networkId = 1l;
+        final String inPortName = "eth";
+
+        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenThrow(Exception.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
+    }
+
+    @Test
+    public void testCheckOnHostCommand() {
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);;
+
+        final CheckOnHostCommand command = new CheckOnHostCommand(host);
+
+        final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class);
+
+        when(libvirtComputingResource.getMonitor()).thenReturn(monitor);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getMonitor();
+    }
+
+    @Test
+    public void testOvsCreateTunnelCommand() {
+        final String remoteIp = "127.0.0.1";
+        final Integer key = 1;
+        final Long from = 1l;
+        final Long to = 2l;
+        final long networkId = 1l;
+        final String fromIp = "127.0.0.1";
+        final String networkName = "eth";
+        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
+
+        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
+
+        final String bridge = command.getNetworkName();
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName())).thenReturn(true);
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
+        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName());
+    }
+
+    @Test
+    public void testOvsCreateTunnelCommandFailure1() {
+        final String remoteIp = "127.0.0.1";
+        final Integer key = 1;
+        final Long from = 1l;
+        final Long to = 2l;
+        final long networkId = 1l;
+        final String fromIp = "127.0.0.1";
+        final String networkName = "eth";
+        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
+
+        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
+
+        final String bridge = command.getNetworkName();
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(false);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
+        verify(libvirtComputingResource, times(0)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testOvsCreateTunnelCommandFailure2() {
+        final String remoteIp = "127.0.0.1";
+        final Integer key = 1;
+        final Long from = 1l;
+        final Long to = 2l;
+        final long networkId = 1l;
+        final String fromIp = "127.0.0.1";
+        final String networkName = "eth";
+        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
+
+        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
+
+        final String bridge = command.getNetworkName();
+
+        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
+        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName())).thenThrow(Exception.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
+        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
+                command.getNetworkName());
+    }
+
+    @Test
+    public void testCreateVolumeFromSnapshotCommand() {
+        // This tests asserts to False because there will be a NPE due to UUID static method calls.
+
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "/opt/storage/";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
+        final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/";
+        final int wait = 0;
+
+        final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        final String primaryUuid = command.getPrimaryStoragePoolNameLabel();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool);
+        when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).thenReturn(primaryPool);
+
+        //when(storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0)).thenReturn(disk);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName());
+        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid);
+        //verify(storagePoolMgr, times(1)).copyPhysicalDisk(snapshot, volUuid, primaryPool, 0);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreateVolumeFromSnapshotCommandCloudException() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "/opt/storage/";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
+        final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/";
+        final int wait = 0;
+
+        final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        final String primaryUuid = command.getPrimaryStoragePoolNameLabel();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool);
+        when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName());
+        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid);
+    }
+
+    @Test
+    public void testFenceCommand() {
+        final VirtualMachine vm = Mockito.mock(VirtualMachine.class);;
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+
+        final FenceCommand command = new FenceCommand(vm, host);
+
+        final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class);
+
+        final NfsStoragePool storagePool = Mockito.mock(NfsStoragePool.class);
+        final List<NfsStoragePool> pools = new ArrayList<NfsStoragePool>();
+        pools.add(storagePool);
+
+        when(libvirtComputingResource.getMonitor()).thenReturn(monitor);
+        when(monitor.getStoragePools()).thenReturn(pools);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getMonitor();
+        verify(monitor, times(1)).getStoragePools();
+    }
+
+    @Test
+    public void testSecurityGroupRulesCmdFalse() {
+        final String guestIp = "127.0.0.1";
+        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
+        final String guestMac = "00:00:00:00";
+        final String vmName = "Test";
+        final Long vmId = 1l;
+        final String signature = "signature";
+        final Long seqNum = 1l;
+        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final List<String> secIps = new Vector<String>();
+        final List<String> cidrs = new Vector<String>();
+        cidrs.add("0.0.0.0/0");
+
+        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+        nics.add(interfaceDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(ingressRuleSet[0].getProto()).thenReturn("tcp");
+        when(ingressRuleSet[0].getStartPort()).thenReturn(22);
+        when(ingressRuleSet[0].getEndPort()).thenReturn(22);
+        when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
+
+        when(egressRuleSet[0].getProto()).thenReturn("tcp");
+        when(egressRuleSet[0].getStartPort()).thenReturn(22);
+        when(egressRuleSet[0].getEndPort()).thenReturn(22);
+        when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testSecurityGroupRulesCmdTrue() {
+        final String guestIp = "127.0.0.1";
+        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
+        final String guestMac = "00:00:00:00";
+        final String vmName = "Test";
+        final Long vmId = 1l;
+        final String signature = "signature";
+        final Long seqNum = 1l;
+        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final List<String> secIps = new Vector<String>();
+        final List<String> cidrs = new Vector<String>();
+        cidrs.add("0.0.0.0/0");
+
+        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+        nics.add(interfaceDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(interfaceDef.getDevName()).thenReturn("eth0");
+        when(interfaceDef.getBrName()).thenReturn("br0");
+
+        final String vif = nics.get(0).getDevName();
+        final String brname = nics.get(0).getBrName();
+
+        when(ingressRuleSet[0].getProto()).thenReturn("tcp");
+        when(ingressRuleSet[0].getStartPort()).thenReturn(22);
+        when(ingressRuleSet[0].getEndPort()).thenReturn(22);
+        when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
+
+        when(egressRuleSet[0].getProto()).thenReturn("tcp");
+        when(egressRuleSet[0].getStartPort()).thenReturn(22);
+        when(egressRuleSet[0].getEndPort()).thenReturn(22);
+        when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
+
+        when(libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getGuestIp6(), command.getSignature(),
+                Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString())).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testSecurityGroupRulesCmdException() {
+        final String guestIp = "127.0.0.1";
+        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
+        final String guestMac = "00:00:00:00";
+        final String vmName = "Test";
+        final Long vmId = 1l;
+        final String signature = "signature";
+        final Long seqNum = 1l;
+        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
+        final List<String> secIps = new Vector<String>();
+
+        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+        nics.add(interfaceDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPlugNicCommandMatchMack() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+        final Type vmtype = Type.DomainRouter;
+
+        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final Domain vm = Mockito.mock(Domain.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
+        nics.add(intDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+
+        when(intDef.getDevName()).thenReturn("eth0");
+        when(intDef.getBrName()).thenReturn("br0");
+        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
+
+        when(nic.getMac()).thenReturn("00:00:00:00");
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPlugNicCommandNoMatchMack() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+        final Type vmtype = Type.DomainRouter;
+
+        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
+        nics.add(intDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+
+        when(intDef.getDevName()).thenReturn("eth0");
+        when(intDef.getBrName()).thenReturn("br0");
+        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
+
+        when(nic.getMac()).thenReturn("00:00:00:01");
+        when(nic.getName()).thenReturn("br0");
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
+
+            when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
+
+            when(vifDriver.plug(nic, "Other PV", "", null)).thenReturn(interfaceDef);
+            when(interfaceDef.toString()).thenReturn("Interface");
+
+            final String interfaceDefStr = interfaceDef.toString();
+            doNothing().when(vm).attachDevice(interfaceDefStr);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
+            verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
+            verify(vifDriver, times(1)).plug(nic, "Other PV", "", null);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPlugNicCommandLibvirtException() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+        final Type vmtype = Type.DomainRouter;
+
+        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPlugNicCommandInternalError() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+        final Type vmtype = Type.DomainRouter;
+
+        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
+        nics.add(intDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+
+        when(intDef.getDevName()).thenReturn("eth0");
+        when(intDef.getBrName()).thenReturn("br0");
+        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
+
+        when(nic.getMac()).thenReturn("00:00:00:01");
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
+
+            when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
+
+            when(vifDriver.plug(nic, "Other PV", "", null)).thenThrow(InternalErrorException.class);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
+            verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
+            verify(vifDriver, times(1)).plug(nic, "Other PV", "", null);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUnPlugNicCommandMatchMack() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+
+        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
+        nics.add(intDef);
+
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+        final List<VifDriver> drivers = new ArrayList<VifDriver>();
+        drivers.add(vifDriver);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+
+        when(intDef.getDevName()).thenReturn("eth0");
+        when(intDef.getBrName()).thenReturn("br0");
+        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
+
+        when(nic.getMac()).thenReturn("00:00:00:00");
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
+
+            when(interfaceDef.toString()).thenReturn("Interface");
+
+            final String interfaceDefStr = interfaceDef.toString();
+            doNothing().when(vm).detachDevice(interfaceDefStr);
+
+            when(libvirtComputingResource.getAllVifDrivers()).thenReturn(drivers);
+
+            doNothing().when(vifDriver).unplug(intDef);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
+            verify(libvirtComputingResource, times(1)).getAllVifDrivers();
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testUnPlugNicCommandNoNics() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+
+        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final Domain vm = Mockito.mock(Domain.class);
+
+        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
+
+        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
+        final List<VifDriver> drivers = new ArrayList<VifDriver>();
+        drivers.add(vifDriver);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testUnPlugNicCommandLibvirtException() {
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final String instanceName = "Test";
+
+        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testNetworkUsageCommandNonVpc() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = false;
+        final String gatewayIP = "127.0.0.1";
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.getNetworkStats(command.getPrivateIP())).thenReturn(new long[]{10l, 10l});
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        //Being called twice, although I did not find the second place yet.
+        verify(libvirtComputingResource, times(2)).getNetworkStats(command.getPrivateIP());
+    }
+
+    @Test
+    public void testNetworkUsageCommandNonVpcCreate() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = false;
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "create", forVpc);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.networkUsage(command.getPrivateIP(), "create", null)).thenReturn("SUCCESS");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).networkUsage(command.getPrivateIP(), "create", null);
+    }
+
+    @Test
+    public void testNetworkUsageCommandVpcCreate() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = true;
+        final String gatewayIP = "127.0.0.1";
+        final String vpcCidr = "10.1.1.0/24";
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP, vpcCidr);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR())).thenReturn("SUCCESS");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR());
+    }
+
+    @Test
+    public void testNetworkUsageCommandVpcGet() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = true;
+        final String gatewayIP = "127.0.0.1";
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l});
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption());
+    }
+
+    @Test
+    public void testNetworkUsageCommandVpcVpn() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = true;
+        final String gatewayIP = "127.0.0.1";
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "vpn", forVpc, gatewayIP);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l});
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption());
+    }
+
+    @Test
+    public void testNetworkUsageCommandVpcNoOption() {
+        final String privateIP = "127.0.0.1";
+        final String domRName = "domR";
+        final boolean forVpc = true;
+        final String gatewayIP = "127.0.0.1";
+
+        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, null, forVpc, gatewayIP);
+
+        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
+
+        when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR())).thenReturn("FAILURE");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR());
+    }
+
+    @Test
+    public void testCreatePrivateTemplateFromVolumeCommand() {
+        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
+        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
+
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final String secondaryStorageUrl = "nfs:/127.0.0.1/storage/secondary";
+        final long templateId = 1l;
+        final long accountId = 1l;
+        final String userSpecifiedName = "User";
+        final String uniqueName = "Unique";
+        final String volumePath = "/123/vol";
+        final String vmName = "Test";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromVolumeCommand command = new CreatePrivateTemplateFromVolumeCommand(pool, secondaryStorageUrl, templateId, accountId, userSpecifiedName, uniqueName, volumePath, vmName, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryStorage = Mockito.mock(KVMStoragePool.class);
+        //final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl)).thenReturn(secondaryStorage);
+        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel())).thenThrow(new CloudRuntimeException("error"));
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(secondaryStorageUrl);
+        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testManageSnapshotCommandLibvirtException() {
+        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
+        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
+
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final String volumePath = "/123/vol";
+        final String vmName = "Test";
+
+        final long snapshotId = 1l;
+        final String preSnapshotPath = "/snapshot/path";
+        final String snapshotName = "snap";
+
+        final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, pool, preSnapshotPath, snapshotName, vmName);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        //final Connect conn = Mockito.mock(Connect.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testManageSnapshotCommandLibvirt() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);;
+        final String volumePath = "/123/vol";
+        final String vmName = "Test";
+        final long snapshotId = 1l;
+        final String preSnapshotPath = "/snapshot/path";
+        final String snapshotName = "snap";
+
+        final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, storagePool, preSnapshotPath, snapshotName, vmName);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
+        final Domain vm = Mockito.mock(Domain.class);
+        final DomainInfo info = Mockito.mock(DomainInfo.class);
+        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
+        info.state = state;
+
+        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
+
+        final StorageFilerTO pool = command.getPool();
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
+            when(libvirtComputingResource.getDomain(conn, command.getVmName())).thenReturn(vm);
+            when(vm.getInfo()).thenReturn(info);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primaryPool);
+        when(primaryPool.getPhysicalDisk(command.getVolumePath())).thenReturn(disk);
+        when(primaryPool.isExternalSnapshot()).thenReturn(false);
+
+        try {
+            when(vm.getUUIDString()).thenReturn("cdb18980-546d-4153-b916-70ee9edf0908");
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testBackupSnapshotCommandLibvirtException() {
+        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
+        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
+
+        final StoragePool pool = Mockito.mock(StoragePool.class);;
+        final String secondaryStorageUrl = "nfs:/127.0.0.1/storage/secondary";
+        final long accountId = 1l;
+        final String volumePath = "/123/vol";
+        final String vmName = "Test";
+        final int wait = 0;
+
+        final long snapshotId = 1l;
+        final String snapshotName = "snap";
+
+        final Long dcId = 1l;
+        final Long volumeId = 1l;
+        final Long secHostId = 1l;
+        final String snapshotUuid = "9a0afe7c-26a7-4585-bf87-abf82ae106d9";
+        final String prevBackupUuid = "003a0cc2-2e04-417a-bee0-534ef1724561";
+        final boolean isVolumeInactive = false;
+        final String prevSnapshotUuid = "1791efae-f22d-474b-87c6-92547d6c5877";
+
+        final BackupSnapshotCommand command = new BackupSnapshotCommand(secondaryStorageUrl, dcId, accountId, volumeId, snapshotId, secHostId, volumePath, pool, snapshotUuid, snapshotName, prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, wait);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        //final Connect conn = Mockito.mock(Connect.class);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreatePrivateTemplateFromSnapshotCommand() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
+        final String backedUpSnapshotName = "snap";
+        final String origTemplateInstallPath = "/install/path/";
+        final Long newTemplateId = 2l;
+        final String templateName = "templ";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
+
+        final String templatePath = "/template/path";
+        final String localPath = "/mnt/local";
+        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+        final StorageLayer storage = Mockito.mock(StorageLayer.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
+        final Processor qcow2Processor = Mockito.mock(Processor.class);
+        final FormatInfo info = Mockito.mock(FormatInfo.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
+        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(secondaryPool.getLocalPath()).thenReturn(localPath);
+        when(libvirtComputingResource.getStorage()).thenReturn(storage);
+
+        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
+        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
+
+        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
+        final String templateInstallFolder = "template/tmpl/" + templateFolder;
+        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
+
+        try {
+            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
+            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
+        } catch (final ConfigurationException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreatePrivateTemplateFromSnapshotCommandConfigurationException() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
+        final String backedUpSnapshotName = "snap";
+        final String origTemplateInstallPath = "/install/path/";
+        final Long newTemplateId = 2l;
+        final String templateName = "templ";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
+
+        final String templatePath = "/template/path";
+        final String localPath = "/mnt/local";
+        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+        final StorageLayer storage = Mockito.mock(StorageLayer.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
+        final Processor qcow2Processor = Mockito.mock(Processor.class);
+        final FormatInfo info = Mockito.mock(FormatInfo.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
+        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(secondaryPool.getLocalPath()).thenReturn(localPath);
+        when(libvirtComputingResource.getStorage()).thenReturn(storage);
+
+        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
+        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
+
+        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
+        final String templateInstallFolder = "template/tmpl/" + templateFolder;
+        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
+
+        try {
+            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class);
+            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
+        } catch (final ConfigurationException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreatePrivateTemplateFromSnapshotCommandInternalErrorException() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
+        final String backedUpSnapshotName = "snap";
+        final String origTemplateInstallPath = "/install/path/";
+        final Long newTemplateId = 2l;
+        final String templateName = "templ";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
+
+        final String templatePath = "/template/path";
+        final String localPath = "/mnt/local";
+        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+        final StorageLayer storage = Mockito.mock(StorageLayer.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
+        final Processor qcow2Processor = Mockito.mock(Processor.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
+        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(secondaryPool.getLocalPath()).thenReturn(localPath);
+        when(libvirtComputingResource.getStorage()).thenReturn(storage);
+
+        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
+        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
+
+        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
+        final String templateInstallFolder = "template/tmpl/" + templateFolder;
+        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
+
+        try {
+            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
+            when(qcow2Processor.process(tmplPath, null, tmplName)).thenThrow(InternalErrorException.class);
+        } catch (final ConfigurationException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreatePrivateTemplateFromSnapshotCommandIOException() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
+        final String backedUpSnapshotName = "snap";
+        final String origTemplateInstallPath = "/install/path/";
+        final Long newTemplateId = 2l;
+        final String templateName = "templ";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
+
+        final String templatePath = "/template/path";
+        final String localPath = "/mnt/local";
+        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
+        final StorageLayer storage = Mockito.mock(StorageLayer.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
+        final Processor qcow2Processor = Mockito.mock(Processor.class);
+        final FormatInfo info = Mockito.mock(FormatInfo.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
+        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
+        when(secondaryPool.getLocalPath()).thenReturn(localPath);
+        when(libvirtComputingResource.getStorage()).thenReturn(storage);
+
+        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
+        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
+
+        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
+        final String templateInstallFolder = "template/tmpl/" + templateFolder;
+        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
+
+        try {
+            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
+            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
+
+            when(location.create(1, true, tmplName)).thenThrow(IOException.class);
+
+        } catch (final ConfigurationException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final IOException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreatePrivateTemplateFromSnapshotCommandCloudRuntime() {
+        final StoragePool pool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long dcId = 1l;
+        final Long accountId = 1l;
+        final Long volumeId = 1l;
+        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
+        final String backedUpSnapshotName = "snap";
+        final String origTemplateInstallPath = "/install/path/";
+        final Long newTemplateId = 2l;
+        final String templateName = "templ";
+        final int wait = 0;
+
+        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+
+        String snapshotPath = command.getSnapshotUuid();
+        final int index = snapshotPath.lastIndexOf("/");
+        snapshotPath = snapshotPath.substring(0, index);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
+
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
+        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
+        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
+        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
+    }
+
+    @Test
+    public void testCopyVolumeCommand() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long volumeId = 1l;
+        final int wait = 0;
+        final String volumePath = "/vol/path";
+        final boolean toSecondaryStorage = true;
+        final boolean executeInSequence = false;
+
+        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
+
+        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final StorageFilerTO pool = command.getPool();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
+        when(primary.getPhysicalDisk(command.getVolumePath())).thenReturn(disk);
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL)).thenReturn(secondary);
+        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
+        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
+        when(secondary.createFolder(volumeDestPath)).thenReturn(true);
+        when(storagePoolMgr.deleteStoragePool(secondary.getType(), secondary.getUuid())).thenReturn(true);
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
+        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, secondary, 0)).thenReturn(disk);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testCopyVolumeCommandToSecFalse() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long volumeId = 1l;
+        final int wait = 0;
+        final String volumePath = "/vol/path";
+        final boolean toSecondaryStorage = false;
+        final boolean executeInSequence = false;
+
+        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
+
+        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final StorageFilerTO pool = command.getPool();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
+        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
+        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
+        when(primary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenReturn(disk);
+        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, primary, 0)).thenReturn(disk);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCopyVolumeCommandCloudRuntime() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long volumeId = 1l;
+        final int wait = 0;
+        final String volumePath = "/vol/path";
+        final boolean toSecondaryStorage = false;
+        final boolean executeInSequence = false;
+
+        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
+
+        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final StorageFilerTO pool = command.getPool();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
+        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
+        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
+        when(secondary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testCopyVolumeCommandCloudRuntime2() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long volumeId = 1l;
+        final int wait = 0;
+        final String volumePath = "/vol/path";
+        final boolean toSecondaryStorage = false;
+        final boolean executeInSequence = false;
+
+        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
+
+        final StorageFilerTO pool = command.getPool();
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenThrow(new CloudRuntimeException("error"));
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testCopyVolumeCommandPrimaryNotFound() {
+        final StoragePool storagePool = Mockito.mock(StoragePool.class);
+        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
+        final Long volumeId = 1l;
+        final int wait = 0;
+        final String volumePath = "/vol/path";
+        final boolean toSecondaryStorage = false;
+        final boolean executeInSequence = false;
+
+        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
+
+        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
+        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
+        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
+
+        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final StorageFilerTO pool = command.getPool();
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenThrow(new CloudRuntimeException("not found"));
+
+        when(storagePoolMgr.createStoragePool(pool.getUuid(), pool.getHost(), pool.getPort(), pool.getPath(),
+                pool.getUserInfo(), pool.getType())).thenReturn(primary);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
+        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
+        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
+        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
+        when(primary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenReturn(disk);
+        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, primary, 0)).thenReturn(disk);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testPvlanSetupCommandDhcpAdd() {
+        final String op = "add";
+        final URI uri = URI.create("http://localhost");
+        final String networkTag = "/105";
+        final String dhcpName = "dhcp";
+        final String dhcpMac = "00:00:00:00";
+        final String dhcpIp = "127.0.0.1";
+
+        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+
+        final String guestBridgeName = "br0";
+        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
+
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+        final String ovsPvlanDhcpHostPath = "/pvlan";
+        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        final List<InterfaceDef> ifaces = new ArrayList<InterfaceDef>();
+        final InterfaceDef nic = Mockito.mock(InterfaceDef.class);
+        ifaces.add(nic);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenReturn(conn);
+            when(libvirtComputingResource.getInterfaces(conn, dhcpName)).thenReturn(ifaces);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPvlanSetupCommandVm() {
+        final String op = "add";
+        final URI uri = URI.create("http://localhost");
+        final String networkTag = "/105";
+        final String vmMac = "00:00:00:00";
+
+        final PvlanSetupCommand command = PvlanSetupCommand.createVmSetup(op, uri, networkTag, vmMac);
+
+        final String guestBridgeName = "br0";
+        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+
+        final String ovsPvlanVmPath = "/pvlan";
+        when(libvirtComputingResource.getOvsPvlanVmPath()).thenReturn(ovsPvlanVmPath);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPvlanSetupCommandDhcpException() {
+        final String op = "add";
+        final URI uri = URI.create("http://localhost");
+        final String networkTag = "/105";
+        final String dhcpName = "dhcp";
+        final String dhcpMac = "00:00:00:00";
+        final String dhcpIp = "127.0.0.1";
+
+        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String guestBridgeName = "br0";
+        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
+
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+        final String ovsPvlanDhcpHostPath = "/pvlan";
+        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPvlanSetupCommandDhcpDelete() {
+        final String op = "delete";
+        final URI uri = URI.create("http://localhost");
+        final String networkTag = "/105";
+        final String dhcpName = "dhcp";
+        final String dhcpMac = "00:00:00:00";
+        final String dhcpIp = "127.0.0.1";
+
+        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
+
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        final String guestBridgeName = "br0";
+        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
+
+        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
+        final String ovsPvlanDhcpHostPath = "/pvlan";
+        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testResizeVolumeCommand() {
+        final String path = "nfs:/127.0.0.1/storage/secondary";
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final Long currentSize = 100l;
+        final Long newSize = 200l;
+        final boolean shrinkOk = true;
+        final String vmInstance = "Test";
+
+        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final StorageVol v = Mockito.mock(StorageVol.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
+        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
+        when(vol.getPath()).thenReturn(path);
+        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE");
+        when(storagePool.getType()).thenReturn(StoragePoolType.RBD);
+        when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn);
+            when(conn.storageVolLookupByPath(path)).thenReturn(v);
+
+            when(conn.getLibVirVersion()).thenReturn(10010l);
+
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnection();
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testResizeVolumeCommandSameSize() {
+        final String path = "nfs:/127.0.0.1/storage/secondary";
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final Long currentSize = 100l;
+        final Long newSize = 100l;
+        final boolean shrinkOk = false;
+        final String vmInstance = "Test";
+
+        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testResizeVolumeCommandShrink() {
+        final String path = "nfs:/127.0.0.1/storage/secondary";
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final Long currentSize = 100l;
+        final Long newSize = 200l;
+        final boolean shrinkOk = true;
+        final String vmInstance = "Test";
+
+        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
+        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
+        when(vol.getPath()).thenReturn(path);
+        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("QCOW2");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testResizeVolumeCommandException() {
+        final String path = "nfs:/127.0.0.1/storage/secondary";
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final Long currentSize = 100l;
+        final Long newSize = 200l;
+        final boolean shrinkOk = false;
+        final String vmInstance = "Test";
+
+        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
+        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
+        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
+        when(vol.getPath()).thenReturn(path);
+        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE");
+        when(storagePool.getType()).thenReturn(StoragePoolType.RBD);
+        when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnection();
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testResizeVolumeCommandException2() {
+        final String path = "nfs:/127.0.0.1/storage/secondary";
+        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
+        final Long currentSize = 100l;
+        final Long newSize = 200l;
+        final boolean shrinkOk = false;
+        final String vmInstance = "Test";
+
+        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
+        when(storagePool.getPhysicalDisk(path)).thenThrow(CloudRuntimeException.class);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+    }
+
+    @Test
+    public void testNetworkElementCommand() {
+        final CheckRouterCommand command = new CheckRouterCommand();
+
+        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
+        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
+
+        when(virtRouterResource.executeRequest(command)).thenReturn(new CheckRouterAnswer(command, "mock_resource"));
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testStorageSubSystemCommand() {
+        final DiskTO disk = Mockito.mock(DiskTO.class);
+        final String vmName = "Test";
+        final AttachCommand command = new AttachCommand(disk, vmName);
+
+        final StorageSubsystemCommandHandler handler = Mockito.mock(StorageSubsystemCommandHandler.class);
+        when(libvirtComputingResource.getStorageHandler()).thenReturn(handler);
+
+        when(handler.handleStorageCommands(command)).thenReturn(new AttachAnswer(disk));
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testStartCommandFailedConnect() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+
+        final String vmName = "Test";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(false);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testStartCommandLibvirtException() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+
+        final String vmName = "Test";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenThrow(LibvirtException.class);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStartCommandInternalError() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+
+        final String vmName = "Test";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            doThrow(InternalErrorException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStartCommandUriException() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+
+        final String vmName = "Test";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            doThrow(URISyntaxException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertFalse(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStartCommand() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+        final int[] vms = new int[0];
+
+        final String vmName = "Test";
+        final String controlIp = "127.0.0.1";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            when(conn.listDomains()).thenReturn(vms);
+            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
+        try {
+            doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef);
+
+            when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS");
+
+            when(vmSpec.getBootArgs()).thenReturn("ls -lart");
+            when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true);
+
+            when(nic.getIp()).thenReturn(controlIp);
+            when(nic.getType()).thenReturn(TrafficType.Control);
+            when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
+            when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true);
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStartCommandIsolationEc2() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+        final int[] vms = new int[0];
+
+        final String vmName = "Test";
+        final String controlIp = "127.0.0.1";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            when(conn.listDomains()).thenReturn(vms);
+            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
+        try {
+            doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef);
+
+            when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS");
+
+            when(nic.isSecurityGroupEnabled()).thenReturn(true);
+            when(nic.getIsolationUri()).thenReturn(new URI("ec2://test"));
+
+
+            when(vmSpec.getBootArgs()).thenReturn("ls -lart");
+            when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true);
+
+            when(nic.getIp()).thenReturn(controlIp);
+            when(nic.getType()).thenReturn(TrafficType.Control);
+            when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
+            when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true);
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+
+        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
+        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
+        try {
+            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testStartCommandHostMemory() {
+        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
+        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
+        final boolean executeInSequence = false;
+
+        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
+
+        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Connect conn = Mockito.mock(Connect.class);
+        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
+
+        final NicTO nic = Mockito.mock(NicTO.class);
+        final NicTO[] nics = new NicTO[]{nic};
+        int vmId = 1;
+        final int[] vms = new int[]{vmId};
+        final Domain dm = Mockito.mock(Domain.class);
+
+        final String vmName = "Test";
+
+        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
+        when(vmSpec.getNics()).thenReturn(nics);
+        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.User);
+        when(vmSpec.getName()).thenReturn(vmName);
+        when(vmSpec.getMaxRam()).thenReturn(512L);
+        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        try {
+            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
+            when(conn.listDomains()).thenReturn(vms);
+            when(conn.domainLookupByID(vmId)).thenReturn(dm);
+            when(dm.getMaxMemory()).thenReturn(1024L);
+            when(dm.getName()).thenReturn(vmName);
+            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
+        } catch (final LibvirtException e) {
+            fail(e.getMessage());
+        } catch (final InternalErrorException e) {
+            fail(e.getMessage());
+        } catch (final URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+        assertTrue(answer.getResult());
+    }
+
+
+    @Test
+    public void testUpdateHostPasswordCommand() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Script script = Mockito.mock(Script.class);
+
+        final String hostIp = "127.0.0.1";
+        final String username = "root";
+        final String newPassword = "password";
+
+        final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
+        when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
+
+        when(script.execute()).thenReturn(null);
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testUpdateHostPasswordCommandFail() {
+        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
+        final Script script = Mockito.mock(Script.class);
+
+        final String hostIp = "127.0.0.1";
+        final String username = "root";
+        final String newPassword = "password";
+
+        final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
+
+        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
+        when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
+        when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
+
+        when(script.execute()).thenReturn("#FAIL");
+
+        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(command, libvirtComputingResource);
+
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testIsInterface () {
+        final LibvirtComputingResource lvcr = new LibvirtComputingResource();
+        assertFalse(lvcr.isInterface("bla"));
+        assertTrue(lvcr.isInterface("p99p00"));
+        assertTrue(lvcr.isInterface("lo1"));
+        assertTrue(lvcr.isInterface("lo_11"));
+        assertTrue(lvcr.isInterface("lo_public_1"));
+        assertTrue(lvcr.isInterface("dummy0"));
+        assertTrue(lvcr.isInterface("dummy_0"));
+        assertTrue(lvcr.isInterface("dummy_private_0"));
+        for  (final String ifNamePattern : lvcr.ifNamePatterns) {
+            // excluding regexps as "\\\\d+" won't replace with String.replaceAll(String,String);
+            if (!ifNamePattern.contains("\\")) {
+                final String ifName = ifNamePattern.replaceFirst("\\^", "") + "0";
+                assertTrue("The pattern '" + ifNamePattern + "' is expected to be valid for interface " + ifName,lvcr.isInterface(ifName));
+            }
+        }
+    }
+
+    @Test
+    public void testMemoryFreeInKBsDomainReturningOfSomeMemoryStatistics() throws LibvirtException {
+        LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
+
+        MemoryStatistic[] mem = createMemoryStatisticFreeMemory100();
+        Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(mem);
+        long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock);
+
+        Assert.assertEquals(100, memoryFreeInKBs);
+    }
+
+    @Test
+    public void testMemoryFreeInKBsDomainReturningNoMemoryStatistics() throws LibvirtException {
+        LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
+
+        Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(null);
+        long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock);
+
+        Assert.assertEquals(0, memoryFreeInKBs);
+    }
+
+    private MemoryStatistic[] createMemoryStatisticFreeMemory100() {
+        virDomainMemoryStats stat = new virDomainMemoryStats();
+        stat.val = 100;
+
+        MemoryStatistic[] mem = new MemoryStatistic[2];
+        mem[0] = new MemoryStatistic(stat);
+        return mem;
+    }
+
+    private Domain getDomainConfiguredToReturnMemoryStatistic(MemoryStatistic[] mem) throws LibvirtException {
+        Domain domainMock = Mockito.mock(Domain.class);
+        when(domainMock.memoryStats(2)).thenReturn(mem);
+        return domainMock;
+    }
+
+    @Test
+    public void testSetQuotaAndPeriod() {
+        double pct = 0.33d;
+        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(true);
+        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
+        CpuTuneDef cpuTuneDef = new CpuTuneDef();
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
+        Assert.assertEquals((int) (CpuTuneDef.DEFAULT_PERIOD * pct), cpuTuneDef.getQuota());
+        Assert.assertEquals(CpuTuneDef.DEFAULT_PERIOD, cpuTuneDef.getPeriod());
+    }
+
+    @Test
+    public void testSetQuotaAndPeriodNoCpuLimitUse() {
+        double pct = 0.33d;
+        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(false);
+        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
+        CpuTuneDef cpuTuneDef = new CpuTuneDef();
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
+        Assert.assertEquals(0, cpuTuneDef.getQuota());
+        Assert.assertEquals(0, cpuTuneDef.getPeriod());
+    }
+
+    @Test
+    public void testSetQuotaAndPeriodMinQuota() {
+        double pct = 0.01d;
+        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(true);
+        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
+        CpuTuneDef cpuTuneDef = new CpuTuneDef();
+        final LibvirtComputingResource lcr = new LibvirtComputingResource();
+        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
+        Assert.assertEquals(CpuTuneDef.MIN_QUOTA, cpuTuneDef.getQuota());
+        Assert.assertEquals((int) (CpuTuneDef.MIN_QUOTA / pct), cpuTuneDef.getPeriod());
+    }
+
+    @Test
+    public void testUnknownCommand() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        Command cmd = new Command() {
+            @Override public boolean executeInSequence() {
+                return false;
+            }
+        };
+        Answer ans = libvirtComputingResource.executeRequest(cmd);
+        assertTrue(ans instanceof UnsupportedAnswer);
+    }
+
+    @Test
+    public void testKnownCommand() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        Command cmd = new PingTestCommand() {
+            @Override public boolean executeInSequence() {
+                throw new NullPointerException("test succeeded");
+            }
+        };
+        Answer ans = libvirtComputingResource.executeRequest(cmd);
+        assertFalse(ans instanceof UnsupportedAnswer);
+        assertTrue(ans instanceof Answer);
+    }
+
+    @Test
+    public void testAddExtraConfigComponentEmptyExtraConfig() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        libvirtComputingResource.addExtraConfigComponent(new HashMap<>(), vmDef);
+        Mockito.verify(vmDef, never()).addComp(any());
+    }
+
+    @Test
+    public void testAddExtraConfigComponentNotEmptyExtraConfig() {
+        libvirtComputingResource = new LibvirtComputingResource();
+        Map<String, String> extraConfig = new HashMap<>();
+        extraConfig.put("extraconfig-1", "value1");
+        extraConfig.put("extraconfig-2", "value2");
+        extraConfig.put("extraconfig-3", "value3");
+        libvirtComputingResource.addExtraConfigComponent(extraConfig, vmDef);
+        Mockito.verify(vmDef, times(1)).addComp(any());
+    }
+}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParserTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParserTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParserTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParserTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java
diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
new file mode 100644
index 0000000..50b6afe
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
@@ -0,0 +1,278 @@
+/*
+ * 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;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
+
+public class LibvirtVMDefTest extends TestCase {
+
+    public void testInterfaceEtehrnet() {
+        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
+        ifDef.defEthernet("targetDeviceName", "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
+
+        String expected =
+            "<interface type='ethernet'>\n"
+                    + "<target dev='targetDeviceName'/>\n"
+                    + "<mac address='00:11:22:aa:bb:dd'/>\n"
+                    + "<model type='virtio'/>\n"
+                    + "<link state='up'/>\n"
+                    + "</interface>\n";
+
+        assertEquals(expected, ifDef.toString());
+    }
+
+    public void testInterfaceDirectNet() {
+        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
+        ifDef.defDirectNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO, "private");
+
+        String expected =
+            "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.DIRECT + "'>\n"
+                    + "<source dev='targetDeviceName' mode='private'/>\n"
+                    + "<mac address='00:11:22:aa:bb:dd'/>\n"
+                    + "<model type='virtio'/>\n"
+                    + "<link state='up'/>\n"
+                    + "</interface>\n";
+
+        assertEquals(expected, ifDef.toString());
+    }
+
+    public void testInterfaceBridgeSlot() {
+        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
+        ifDef.defBridgeNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
+        ifDef.setSlot(16);
+
+        String expected =
+                "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
+                        + "<source bridge='targetDeviceName'/>\n"
+                        + "<mac address='00:11:22:aa:bb:dd'/>\n"
+                        + "<model type='virtio'/>\n"
+                        + "<link state='up'/>\n"
+                        + "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
+                        + "</interface>\n";
+
+        assertEquals(expected, ifDef.toString());
+
+        ifDef.setLinkStateUp(false);
+        ifDef.setDevName("vnet11");
+
+        expected =
+                "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
+                        + "<source bridge='targetDeviceName'/>\n"
+                        + "<target dev='vnet11'/>\n"
+                        + "<mac address='00:11:22:aa:bb:dd'/>\n"
+                        + "<model type='virtio'/>\n"
+                        + "<link state='down'/>\n"
+                        + "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
+                        + "</interface>\n";
+
+        assertEquals(expected, ifDef.toString());
+    }
+
+    public void testCpuModeDef() {
+        LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
+        cpuModeDef.setMode("custom");
+        cpuModeDef.setModel("Nehalem");
+
+        String expected1 = "<cpu mode='custom' match='exact'><model fallback='allow'>Nehalem</model></cpu>";
+
+        assertEquals(expected1, cpuModeDef.toString());
+
+        cpuModeDef.setMode("host-model");
+        String expected2 = "<cpu mode='host-model'><model fallback='allow'></model></cpu>";
+
+        assertEquals(expected2, cpuModeDef.toString());
+
+        cpuModeDef.setMode("host-passthrough");
+        String expected3 = "<cpu mode='host-passthrough'></cpu>";
+        assertEquals(expected3, cpuModeDef.toString());
+
+    }
+
+    public void testDiskDef() {
+        String filePath = "/var/lib/libvirt/images/disk.qcow2";
+        String diskLabel = "vda";
+
+        DiskDef disk = new DiskDef();
+        DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO;
+        DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2;
+        DiskDef.DiskCacheMode cacheMode = DiskDef.DiskCacheMode.WRITEBACK;
+
+        disk.defFileBasedDisk(filePath, diskLabel, bus, type);
+        disk.setCacheMode(cacheMode);
+
+        assertEquals(filePath, disk.getDiskPath());
+        assertEquals(diskLabel, disk.getDiskLabel());
+        assertEquals(bus, disk.getBusType());
+        assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType());
+
+        String xmlDef = disk.toString();
+        String expectedXml = "<disk  device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
+                             "<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n</disk>\n";
+
+        assertEquals(xmlDef, expectedXml);
+    }
+
+    public void testDiskDefWithBurst() {
+        String filePath = "/var/lib/libvirt/images/disk.qcow2";
+        String diskLabel = "vda";
+
+        DiskDef disk = new DiskDef();
+        DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO;
+        DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2;
+        disk.defFileBasedDisk(filePath, diskLabel, bus, type);
+
+
+        Long iopsReadRate = 500L;
+        Long iopsReadRateMax = 2000L;
+        Long iopsReadRateMaxLength = 120L;
+        Long iopsWriteRate = 501L;
+        Long iopsWriteRateMax = 2001L;
+        Long iopsWriteRateMaxLength = 121L;
+        Long bytesReadRate = 1000L;
+        Long bytesReadRateMax = 2500L;
+        Long bytesReadRateMaxLength = 122L;
+        Long bytesWriteRate = 1001L;
+        Long bytesWriteRateMax = 2501L;
+        Long bytesWriteRateMaxLength = 123L;
+
+
+        disk.setIopsReadRate(iopsReadRate);
+        disk.setIopsReadRateMax(iopsReadRateMax);
+        disk.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+        disk.setIopsWriteRate(iopsWriteRate);
+        disk.setIopsWriteRateMax(iopsWriteRateMax);
+        disk.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
+        disk.setBytesReadRate(bytesReadRate);
+        disk.setBytesReadRateMax(bytesReadRateMax);
+        disk.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+        disk.setBytesWriteRate(bytesWriteRate);
+        disk.setBytesWriteRateMax(bytesWriteRateMax);
+        disk.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+
+        LibvirtVMDef.setGlobalQemuVersion(2006000L);
+        LibvirtVMDef.setGlobalLibvirtVersion(9008L);
+
+        String xmlDef = disk.toString();
+        String expectedXml = "<disk  device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='none' />\n" +
+                "<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n" +
+                "<iotune>\n<read_bytes_sec>"+bytesReadRate+"</read_bytes_sec>\n<write_bytes_sec>"+bytesWriteRate+"</write_bytes_sec>\n" +
+                "<read_iops_sec>"+iopsReadRate+"</read_iops_sec>\n<write_iops_sec>"+iopsWriteRate+"</write_iops_sec>\n" +
+                "<read_bytes_sec_max>"+bytesReadRateMax+"</read_bytes_sec_max>\n<write_bytes_sec_max>"+bytesWriteRateMax+"</write_bytes_sec_max>\n" +
+                "<read_iops_sec_max>"+iopsReadRateMax+"</read_iops_sec_max>\n<write_iops_sec_max>"+iopsWriteRateMax+"</write_iops_sec_max>\n" +
+                "<read_bytes_sec_max_length>"+bytesReadRateMaxLength+"</read_bytes_sec_max_length>\n<write_bytes_sec_max_length>"+bytesWriteRateMaxLength+"</write_bytes_sec_max_length>\n" +
+                "<read_iops_sec_max_length>"+iopsReadRateMaxLength+"</read_iops_sec_max_length>\n<write_iops_sec_max_length>"+iopsWriteRateMaxLength+"</write_iops_sec_max_length>\n</iotune>\n</disk>\n";
+
+                assertEquals(xmlDef, expectedXml);
+    }
+
+    public void testHypervEnlightDef() {
+        LibvirtVMDef.FeaturesDef featuresDef = new LibvirtVMDef.FeaturesDef();
+        LibvirtVMDef.HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
+        hyperVEnlightenmentFeatureDef.setFeature("relaxed", true);
+        hyperVEnlightenmentFeatureDef.setFeature("vapic", true);
+        hyperVEnlightenmentFeatureDef.setFeature("spinlocks", true);
+        hyperVEnlightenmentFeatureDef.setRetries(8096);
+        featuresDef.addHyperVFeature(hyperVEnlightenmentFeatureDef);
+        String defs = featuresDef.toString();
+        assertTrue(defs.contains("relaxed"));
+        assertTrue(defs.contains("vapic"));
+        assertTrue(defs.contains("spinlocks"));
+
+        featuresDef = new LibvirtVMDef.FeaturesDef();
+        featuresDef.addFeatures("pae");
+        defs = featuresDef.toString();
+        assertFalse(defs.contains("relaxed"));
+        assertFalse(defs.contains("vapic"));
+        assertFalse(defs.contains("spinlocks"));
+        assertTrue("Windows PV".contains("Windows PV"));
+
+    }
+
+    public void testRngDef() {
+        LibvirtVMDef.RngDef.RngBackendModel backendModel = LibvirtVMDef.RngDef.RngBackendModel.RANDOM;
+        String path = "/dev/random";
+        int period = 2000;
+        int bytes = 2048;
+
+        LibvirtVMDef.RngDef def = new LibvirtVMDef.RngDef(path, backendModel, bytes, period);
+        assertEquals(def.getPath(), path);
+        assertEquals(def.getRngBackendModel(), backendModel);
+        assertEquals(def.getRngModel(), LibvirtVMDef.RngDef.RngModel.VIRTIO);
+        assertEquals(def.getRngRateBytes(), bytes);
+        assertEquals(def.getRngRatePeriod(), period);
+    }
+
+    public void testChannelDef() {
+        ChannelDef.ChannelType type = ChannelDef.ChannelType.UNIX;
+        ChannelDef.ChannelState state = ChannelDef.ChannelState.CONNECTED;
+        String name = "v-136-VM.org.qemu.guest_agent.0";
+        File path = new File("/var/lib/libvirt/qemu/" + name);
+
+        ChannelDef channelDef = new ChannelDef(name, type, state, path);
+
+        assertEquals(state, channelDef.getChannelState());
+        assertEquals(type, channelDef.getChannelType());
+        assertEquals(name, channelDef.getName());
+        assertEquals(path, channelDef.getPath());
+    }
+
+    public void testWatchDogDef() {
+        LibvirtVMDef.WatchDogDef.WatchDogModel model = LibvirtVMDef.WatchDogDef.WatchDogModel.I6300ESB;
+        LibvirtVMDef.WatchDogDef.WatchDogAction action = LibvirtVMDef.WatchDogDef.WatchDogAction.RESET;
+
+        LibvirtVMDef.WatchDogDef def = new LibvirtVMDef.WatchDogDef(action, model);
+        assertEquals(def.getModel(), model);
+        assertEquals(def.getAction(), action);
+    }
+
+    public void testSCSIDef() {
+        SCSIDef def = new SCSIDef((short)0, 0, 0, 9, 0, 4);
+        String str = def.toString();
+        String expected = "<controller type='scsi' index='0' model='virtio-scsi'>\n" +
+                "<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>\n" +
+                "<driver queues='4'/>\n" +
+                "</controller>\n";
+        assertEquals(str, expected);
+    }
+
+    public void testMetadataDef() {
+        LibvirtVMDef.MetadataDef metadataDef = new LibvirtVMDef.MetadataDef();
+
+        metadataDef.getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension("mac1", "ip1");
+        metadataDef.getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension("mac2", "ip2");
+
+        String xmlDef = metadataDef.toString();
+        String expectedXml = "<metadata>\n" +
+                "<nuage-extension xmlns='nuagenetworks.net/nuage/cna'>\n" +
+                "  <interface mac='mac2' vsp-vr-ip='ip2'></interface>\n" +
+                "  <interface mac='mac1' vsp-vr-ip='ip1'></interface>\n" +
+                "</nuage-extension>\n" +
+                "</metadata>\n";
+
+        assertEquals(xmlDef, expectedXml);
+    }
+
+}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/LibvirtVifDriverTest.java
diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/OvsVifDriverTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/OvsVifDriverTest.java
new file mode 100644
index 0000000..71a6353
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/OvsVifDriverTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import com.cloud.utils.script.Script;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@PrepareForTest({ Script.class })
+@RunWith(PowerMockRunner.class)
+public class OvsVifDriverTest {
+
+    private static final int dpdkPortNumber = 7;
+
+    private OvsVifDriver driver = new OvsVifDriver();
+
+    @Before
+    public void initMocks() {
+        MockitoAnnotations.initMocks(this);
+        PowerMockito.mockStatic(Script.class);
+        Mockito.when(Script.runSimpleBashScript(Matchers.anyString())).thenReturn(null);
+    }
+
+    @Test
+    public void testGetDpdkLatestPortNumberUsedNoDpdkPorts() {
+        Assert.assertEquals(0, driver.getDpdkLatestPortNumberUsed());
+    }
+
+    @Test
+    public void testGetDpdkLatestPortNumberUsedExistingDpdkPorts() {
+        Mockito.when(Script.runSimpleBashScript(Matchers.anyString())).
+                thenReturn(OvsVifDriver.DPDK_PORT_PREFIX + String.valueOf(dpdkPortNumber));
+        Assert.assertEquals(dpdkPortNumber, driver.getDpdkLatestPortNumberUsed());
+    }
+
+    @Test
+    public void testGetNextDpdkPortNoDpdkPorts() {
+        Mockito.when(Script.runSimpleBashScript(Matchers.anyString())).
+                thenReturn(null);
+        String expectedPortName = OvsVifDriver.DPDK_PORT_PREFIX + String.valueOf(1);
+        Assert.assertEquals(expectedPortName, driver.getNextDpdkPort());
+    }
+
+    @Test
+    public void testGetNextDpdkPortExistingDpdkPorts() {
+        Mockito.when(Script.runSimpleBashScript(Matchers.anyString())).
+                thenReturn(OvsVifDriver.DPDK_PORT_PREFIX + String.valueOf(dpdkPortNumber));
+        String expectedPortName = OvsVifDriver.DPDK_PORT_PREFIX + String.valueOf(dpdkPortNumber + 1);
+        Assert.assertEquals(expectedPortName, driver.getNextDpdkPort());
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
new file mode 100644
index 0000000..86bb617
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
@@ -0,0 +1,486 @@
+//
+// 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.libvirt.Connect;
+import org.libvirt.StorageVol;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo.DiskType;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo.DriverType;
+import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo.Source;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.w3c.dom.Document;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({LibvirtConnection.class, LibvirtMigrateCommandWrapper.class})
+public class LibvirtMigrateCommandWrapperTest {
+    String fullfile =
+"<domain type='kvm' id='4'>\n" +
+"  <name>i-6-6-VM</name>\n" +
+"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
+"  <description>Other PV (64-bit)</description>\n" +
+"  <memory unit='KiB'>262144</memory>\n" +
+"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
+"  <vcpu placement='static'>1</vcpu>\n" +
+"  <cputune>\n" +
+"    <shares>100</shares>\n" +
+"  </cputune>\n" +
+"  <resource>\n" +
+"    <partition>/machine</partition>\n" +
+"  </resource>\n" +
+"  <sysinfo type='smbios'>\n" +
+"    <system>\n" +
+"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
+"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
+"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
+"    </system>\n" +
+"  </sysinfo>\n" +
+"  <os>\n" +
+"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
+"    <boot dev='cdrom'/>\n" +
+"    <boot dev='hd'/>\n" +
+"    <smbios mode='sysinfo'/>\n" +
+"  </os>\n" +
+"  <features>\n" +
+"    <acpi/>\n" +
+"    <apic/>\n" +
+"    <pae/>\n" +
+"  </features>\n" +
+"  <clock offset='utc'>\n" +
+"    <timer name='kvmclock'/>\n" +
+"  </clock>\n" +
+"  <on_poweroff>destroy</on_poweroff>\n" +
+"  <on_reboot>restart</on_reboot>\n" +
+"  <on_crash>destroy</on_crash>\n" +
+"  <devices>\n" +
+"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
+"    <disk type='file' device='disk'>\n" +
+"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
+"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
+"      <backingStore type='file' index='1'>\n" +
+"        <format type='raw'/>\n" +
+"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
+"        <backingStore/>\n" +
+"      </backingStore>\n" +
+"      <target dev='vda' bus='virtio'/>\n" +
+"      <iotune>\n" +
+"        <write_iops_sec>500</write_iops_sec>\n" +
+"        <write_iops_sec_max>5000</write_iops_sec_max>\n" +
+"        <write_iops_sec_max_length>60</write_iops_sec_max_length>\n" +
+"      </iotune>\n" +
+"      <serial>4650a2f7fce548e2beaa</serial>\n" +
+"      <alias name='virtio-disk0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
+"    </disk>\n" +
+"    <disk type='file' device='cdrom'>\n" +
+"      <driver name='qemu' type='raw' cache='none'/>\n" +
+"      <backingStore/>\n" +
+"      <target dev='hdc' bus='ide'/>\n" +
+"      <readonly/>\n" +
+"      <alias name='ide0-1-0'/>\n" +
+"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
+"    </disk>\n" +
+"    <controller type='usb' index='0'>\n" +
+"      <alias name='usb'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
+"    </controller>\n" +
+"    <controller type='pci' index='0' model='pci-root'>\n" +
+"      <alias name='pci.0'/>\n" +
+"    </controller>\n" +
+"    <controller type='ide' index='0'>\n" +
+"      <alias name='ide'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
+"    </controller>\n" +
+"    <interface type='bridge'>\n" +
+"      <mac address='06:fe:b4:00:00:06'/>\n" +
+"      <source bridge='breth0-50'/>\n" +
+"      <bandwidth>\n" +
+"        <inbound average='25600' peak='25600'/>\n" +
+"        <outbound average='25600' peak='25600'/>\n" +
+"      </bandwidth>\n" +
+"      <target dev='vnet4'/>\n" +
+"      <model type='virtio'/>\n" +
+"      <alias name='net0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
+"    </interface>\n" +
+"    <serial type='pty'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </serial>\n" +
+"    <console type='pty' tty='/dev/pts/2'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target type='serial' port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </console>\n" +
+"    <input type='tablet' bus='usb'>\n" +
+"      <alias name='input0'/>\n" +
+"    </input>\n" +
+"    <input type='mouse' bus='ps2'/>\n" +
+"    <input type='keyboard' bus='ps2'/>\n" +
+"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.22'>\n" +
+"      <listen type='address' address='192.168.22.22'/>\n" +
+"    </graphics>\n" +
+"    <video>\n" +
+"      <model type='cirrus' vram='16384' heads='1'/>\n" +
+"      <alias name='video0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
+"    </video>\n" +
+"    <memballoon model='none'>\n" +
+"      <alias name='balloon0'/>\n" +
+"    </memballoon>\n" +
+"  </devices>\n" +
+"</domain>";
+    String targetfile =
+"<domain type='kvm' id='4'>\n" +
+"  <name>i-6-6-VM</name>\n" +
+"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
+"  <description>Other PV (64-bit)</description>\n" +
+"  <memory unit='KiB'>262144</memory>\n" +
+"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
+"  <vcpu placement='static'>1</vcpu>\n" +
+"  <cputune>\n" +
+"    <shares>100</shares>\n" +
+"  </cputune>\n" +
+"  <resource>\n" +
+"    <partition>/machine</partition>\n" +
+"  </resource>\n" +
+"  <sysinfo type='smbios'>\n" +
+"    <system>\n" +
+"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
+"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
+"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
+"    </system>\n" +
+"  </sysinfo>\n" +
+"  <os>\n" +
+"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
+"    <boot dev='cdrom'/>\n" +
+"    <boot dev='hd'/>\n" +
+"    <smbios mode='sysinfo'/>\n" +
+"  </os>\n" +
+"  <features>\n" +
+"    <acpi/>\n" +
+"    <apic/>\n" +
+"    <pae/>\n" +
+"  </features>\n" +
+"  <clock offset='utc'>\n" +
+"    <timer name='kvmclock'/>\n" +
+"  </clock>\n" +
+"  <on_poweroff>destroy</on_poweroff>\n" +
+"  <on_reboot>restart</on_reboot>\n" +
+"  <on_crash>destroy</on_crash>\n" +
+"  <devices>\n" +
+"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
+"    <disk type='file' device='disk'>\n" +
+"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
+"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
+"      <backingStore type='file' index='1'>\n" +
+"        <format type='raw'/>\n" +
+"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
+"        <backingStore/>\n" +
+"      </backingStore>\n" +
+"      <target dev='vda' bus='virtio'/>\n" +
+"      <iotune>\n" +
+"        <write_iops_sec>500</write_iops_sec>\n" +
+"        <write_iops_sec_max>5000</write_iops_sec_max>\n" +
+"        <write_iops_sec_max_length>60</write_iops_sec_max_length>\n" +
+"      </iotune>\n" +
+"      <serial>4650a2f7fce548e2beaa</serial>\n" +
+"      <alias name='virtio-disk0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
+"    </disk>\n" +
+"    <disk type='file' device='cdrom'>\n" +
+"      <driver name='qemu' type='raw' cache='none'/>\n" +
+"      <backingStore/>\n" +
+"      <target dev='hdc' bus='ide'/>\n" +
+"      <readonly/>\n" +
+"      <alias name='ide0-1-0'/>\n" +
+"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
+"    </disk>\n" +
+"    <controller type='usb' index='0'>\n" +
+"      <alias name='usb'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
+"    </controller>\n" +
+"    <controller type='pci' index='0' model='pci-root'>\n" +
+"      <alias name='pci.0'/>\n" +
+"    </controller>\n" +
+"    <controller type='ide' index='0'>\n" +
+"      <alias name='ide'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
+"    </controller>\n" +
+"    <interface type='bridge'>\n" +
+"      <mac address='06:fe:b4:00:00:06'/>\n" +
+"      <source bridge='breth0-50'/>\n" +
+"      <bandwidth>\n" +
+"        <inbound average='25600' peak='25600'/>\n" +
+"        <outbound average='25600' peak='25600'/>\n" +
+"      </bandwidth>\n" +
+"      <target dev='vnet4'/>\n" +
+"      <model type='virtio'/>\n" +
+"      <alias name='net0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
+"    </interface>\n" +
+"    <serial type='pty'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </serial>\n" +
+"    <console type='pty' tty='/dev/pts/2'>\n" +
+"      <source path='/dev/pts/2'/>\n" +
+"      <target type='serial' port='0'/>\n" +
+"      <alias name='serial0'/>\n" +
+"    </console>\n" +
+"    <input type='tablet' bus='usb'>\n" +
+"      <alias name='input0'/>\n" +
+"    </input>\n" +
+"    <input type='mouse' bus='ps2'/>\n" +
+"    <input type='keyboard' bus='ps2'/>\n" +
+"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.21'>\n" +
+"      <listen type='address' address='192.168.22.21'/>\n" +
+"    </graphics>\n" +
+"    <video>\n" +
+"      <model type='cirrus' vram='16384' heads='1'/>\n" +
+"      <alias name='video0'/>\n" +
+"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
+"    </video>\n" +
+"    <memballoon model='none'>\n" +
+"      <alias name='balloon0'/>\n" +
+"    </memballoon>\n" +
+"  </devices>\n" +
+"</domain>";
+
+    LibvirtMigrateCommandWrapper libvirtMigrateCmdWrapper = new LibvirtMigrateCommandWrapper();
+
+    @Test
+    public void testReplaceIpForVNCInDescFile() {
+        final String targetIp = "192.168.22.21";
+        final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(fullfile, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result));
+    }
+
+    @Test
+    public void testReplaceIpForVNCInDesc() {
+        final String xmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>" +
+                "      <listen type='address' address='10.10.10.1'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String expectedXmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10'>" +
+                "      <listen type='address' address='10.10.10.10'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String targetIp = "10.10.10.10";
+        final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
+    }
+
+    @Test
+    public void testReplaceFqdnForVNCInDesc() {
+        final String xmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local'>" +
+                "      <listen type='address' address='localhost.local'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String expectedXmlDesc =
+                "<domain type='kvm' id='3'>" +
+                "  <devices>" +
+                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain'>" +
+                "      <listen type='address' address='localhost.localdomain'/>" +
+                "    </graphics>" +
+                "  </devices>" +
+                "</domain>";
+        final String targetIp = "localhost.localdomain";
+        final String result = libvirtMigrateCmdWrapper.replaceIpForVNCInDescFile(xmlDesc, targetIp);
+        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
+    }
+
+    @Test
+    public void testMigrationUri() {
+        final String ip = "10.1.1.1";
+        LibvirtComputingResource lcr = new LibvirtComputingResource();
+        if (lcr.isHostSecured()) {
+            assertEquals(libvirtMigrateCmdWrapper.createMigrationURI(ip, lcr), String.format("qemu+tls://%s/system", ip));
+        } else {
+            assertEquals(libvirtMigrateCmdWrapper.createMigrationURI(ip, lcr), String.format("qemu+tcp://%s/system", ip));
+        }
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testMigrationUriException() {
+        libvirtMigrateCmdWrapper.createMigrationURI(null, new LibvirtComputingResource());
+    }
+
+    @Test
+    public void deleteLocalVolumeTest() throws Exception {
+        PowerMockito.mockStatic(LibvirtConnection.class);
+        Connect conn = Mockito.mock(Connect.class);
+
+        PowerMockito.doReturn(conn).when(LibvirtConnection.class, "getConnection");
+
+        StorageVol storageVolLookupByPath = Mockito.mock(StorageVol.class);
+        Mockito.when(conn.storageVolLookupByPath("localPath")).thenReturn(storageVolLookupByPath);
+
+        libvirtMigrateCmdWrapper.deleteLocalVolume("localPath");
+
+        PowerMockito.verifyStatic(Mockito.times(1));
+        LibvirtConnection.getConnection();
+        InOrder inOrder = Mockito.inOrder(conn, storageVolLookupByPath);
+        inOrder.verify(conn, Mockito.times(1)).storageVolLookupByPath("localPath");
+        inOrder.verify(storageVolLookupByPath, Mockito.times(1)).delete(0);
+    }
+
+    @Test
+    public void searchDiskDefOnMigrateDiskInfoListTest() {
+        configureAndVerifyTestSearchDiskDefOnMigrateDiskInfoList("f3d49ecc-870c-475a-89fa-fd0124420a9b", "/var/lib/libvirt/images/f3d49ecc-870c-475a-89fa-fd0124420a9b", false);
+    }
+
+    @Test
+    public void searchDiskDefOnMigrateDiskInfoListTestExpectNull() {
+        configureAndVerifyTestSearchDiskDefOnMigrateDiskInfoList("f3d49ecc-870c-475a-89fa-fd0124420a9b", "/var/lib/libvirt/images/f3d49ecc-870c-89fa-fd0124420a9b", true);
+    }
+
+    private void configureAndVerifyTestSearchDiskDefOnMigrateDiskInfoList(String serialNumber, String diskPath, boolean isExpectedDiskInfoNull) {
+        MigrateDiskInfo migrateDiskInfo = new MigrateDiskInfo(serialNumber, DiskType.FILE, DriverType.QCOW2, Source.FILE, "sourceText");
+        List<MigrateDiskInfo> migrateDiskInfoList = new ArrayList<>();
+        migrateDiskInfoList.add(migrateDiskInfo);
+
+        DiskDef disk = new DiskDef();
+        disk.setDiskPath(diskPath);
+
+        MigrateDiskInfo returnedMigrateDiskInfo = libvirtMigrateCmdWrapper.searchDiskDefOnMigrateDiskInfoList(migrateDiskInfoList, disk);
+
+        if (isExpectedDiskInfoNull)
+            Assert.assertEquals(null, returnedMigrateDiskInfo);
+        else
+            Assert.assertEquals(migrateDiskInfo, returnedMigrateDiskInfo);
+    }
+
+    @Test
+    public void deleteOrDisconnectDisksOnSourcePoolTest() {
+        LibvirtMigrateCommandWrapper spyLibvirtMigrateCmdWrapper = PowerMockito.spy(libvirtMigrateCmdWrapper);
+        Mockito.doNothing().when(spyLibvirtMigrateCmdWrapper).deleteLocalVolume("volPath");
+
+        List<MigrateDiskInfo> migrateDiskInfoList = new ArrayList<>();
+        MigrateDiskInfo migrateDiskInfo0 = createMigrateDiskInfo(true);
+        MigrateDiskInfo migrateDiskInfo2 = createMigrateDiskInfo(false);
+
+        List<DiskDef> disks = new ArrayList<>();
+        DiskDef diskDef0 = new DiskDef();
+        DiskDef diskDef1 = new DiskDef();
+        DiskDef diskDef2 = new DiskDef();
+
+        diskDef0.setDiskPath("volPath");
+        disks.add(diskDef0);
+        disks.add(diskDef1);
+        disks.add(diskDef2);
+
+        LibvirtComputingResource libvirtComputingResource = Mockito.spy(new LibvirtComputingResource());
+        Mockito.doReturn(true).when(libvirtComputingResource).cleanupDisk(diskDef1);
+
+        Mockito.doReturn(migrateDiskInfo0).when(spyLibvirtMigrateCmdWrapper).searchDiskDefOnMigrateDiskInfoList(migrateDiskInfoList, diskDef0);
+        Mockito.doReturn(null).when(spyLibvirtMigrateCmdWrapper).searchDiskDefOnMigrateDiskInfoList(migrateDiskInfoList, diskDef1);
+        Mockito.doReturn(migrateDiskInfo2).when(spyLibvirtMigrateCmdWrapper).searchDiskDefOnMigrateDiskInfoList(migrateDiskInfoList, diskDef2);
+
+        spyLibvirtMigrateCmdWrapper.deleteOrDisconnectDisksOnSourcePool(libvirtComputingResource, migrateDiskInfoList, disks);
+
+        InOrder inOrder = Mockito.inOrder(spyLibvirtMigrateCmdWrapper, libvirtComputingResource);
+        inOrderVerifyDeleteOrDisconnect(inOrder, spyLibvirtMigrateCmdWrapper, libvirtComputingResource, migrateDiskInfoList, diskDef0, 1, 0);
+        inOrderVerifyDeleteOrDisconnect(inOrder, spyLibvirtMigrateCmdWrapper, libvirtComputingResource, migrateDiskInfoList, diskDef1, 0, 1);
+        inOrderVerifyDeleteOrDisconnect(inOrder, spyLibvirtMigrateCmdWrapper, libvirtComputingResource, migrateDiskInfoList, diskDef2, 0, 1);
+    }
+
+    private MigrateDiskInfo createMigrateDiskInfo(boolean isSourceDiskOnStorageFileSystem) {
+        MigrateDiskInfo migrateDiskInfo = new MigrateDiskInfo("serialNumber", DiskType.FILE, DriverType.QCOW2, Source.FILE, "sourceText");
+        migrateDiskInfo.setSourceDiskOnStorageFileSystem(isSourceDiskOnStorageFileSystem);
+        return migrateDiskInfo;
+    }
+
+    private void inOrderVerifyDeleteOrDisconnect(InOrder inOrder, LibvirtMigrateCommandWrapper lw, LibvirtComputingResource virtResource, List<MigrateDiskInfo> diskInfoList,
+            DiskDef disk, int timesDelete, int timesCleanup) {
+        inOrder.verify(lw).searchDiskDefOnMigrateDiskInfoList(diskInfoList, disk);
+        inOrder.verify(lw, Mockito.times(timesDelete)).deleteLocalVolume("volPath");
+        inOrder.verify(virtResource, Mockito.times(timesCleanup)).cleanupDisk(disk);
+    }
+
+    static void assertXpath(final Document doc, final String xPathExpr,
+                            final String expected) {
+        try {
+            Assert.assertEquals(expected, XPathFactory.newInstance().newXPath()
+                    .evaluate(xPathExpr, doc));
+        } catch (final XPathExpressionException e) {
+            Assert.fail("Could not evaluate xpath" + xPathExpr + ":"
+                    + e.getMessage());
+        }
+    }
+
+    @Test
+    public void testReplaceStorage() throws Exception {
+        Map<String, MigrateDiskInfo> mapMigrateStorage = new HashMap<String, MigrateDiskInfo>();
+
+        MigrateDiskInfo diskInfo = new MigrateDiskInfo("123456", DiskType.BLOCK, DriverType.RAW, Source.FILE, "sourctest");
+        mapMigrateStorage.put("/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6", diskInfo);
+        final String result = libvirtMigrateCmdWrapper.replaceStorage(fullfile, mapMigrateStorage);
+
+        InputStream in = IOUtils.toInputStream(result);
+        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+        Document doc = docBuilder.parse(in);
+        assertXpath(doc, "/domain/devices/disk/iotune/write_iops_sec", "500");
+        assertXpath(doc, "/domain/devices/disk/@type", "block");
+        assertXpath(doc, "/domain/devices/disk/driver/@type", "raw");
+    }
+
+}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapperTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapperTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapperTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapperTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapperTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReplugNicCommandWrapperTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMPhysicalDiskTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/LibvirtStoragePoolTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePoolTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/storage/LibvirtStoragePoolTest.java
rename to plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/LibvirtStoragePoolTest.java
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/kvm/ha/KVMHostHATest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/kvm/ha/KVMHostHATest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/org/apache/cloudstack/kvm/ha/KVMHostHATest.java
rename to plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/kvm/ha/KVMHostHATest.java
diff --git a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java
new file mode 100644
index 0000000..bc6b01c
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java
@@ -0,0 +1,37 @@
+// 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
+// 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.utils.linux;
+
+import org.apache.commons.lang.SystemUtils;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.junit.Assume;
+import org.junit.Assert;
+import org.mockito.Mockito;
+
+import org.libvirt.NodeInfo;
+
+public class KVMHostInfoTest {
+    @Test
+    public void getCpuSpeed() {
+        Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
+        NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
+        nodeInfo.mhz = 1000;
+        Assert.assertThat(KVMHostInfo.getCpuSpeed(nodeInfo), Matchers.greaterThan(0l));
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/MemStatTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/MemStatTest.java
new file mode 100644
index 0000000..476dc76
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/MemStatTest.java
@@ -0,0 +1,70 @@
+// 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
+// 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.utils.linux;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Scanner;
+
+public class MemStatTest {
+    final String memInfo = "MemTotal:        5830236 kB\n" +
+                           "MemFree:          156752 kB\n" +
+                           "Buffers:          326836 kB\n" +
+                           "Cached:          2606764 kB\n" +
+                           "SwapCached:            0 kB\n" +
+                           "Active:          4260808 kB\n" +
+                           "Inactive:         949392 kB\n";
+
+    @Test
+    public void getMemInfoParseTest() {
+        MemStat memStat = null;
+        try {
+            memStat = new MemStat();
+        } catch (RuntimeException ex) {
+            // If test isn't run on linux we'll fail creation of linux-specific MemStat class due
+            // to dependency on /proc/meminfo if we don't catch here.
+            // We are really only interested in testing the parsing algorithm and getters.
+            if (memStat == null) {
+                throw ex;
+            }
+        }
+        Scanner scanner = new Scanner(memInfo);
+        memStat.parseFromScanner(scanner);
+
+        Assert.assertEquals(memStat.getTotal(), 5970161664L);
+        Assert.assertEquals(memStat.getAvailable(), 2829840384L);
+        Assert.assertEquals(memStat.getFree(), 160514048L);
+        Assert.assertEquals(memStat.getCache(), 2669326336L);
+    }
+
+    @Test
+    public void reservedMemoryTest() {
+        MemStat memStat = null;
+        try {
+            memStat = new MemStat(1024, 2048);
+        } catch (RuntimeException ex) {
+            if (memStat == null) {
+                throw ex;
+            }
+        }
+        Scanner scanner = new Scanner(memInfo);
+        memStat.parseFromScanner(scanner);
+
+        Assert.assertEquals(memStat.getTotal(), 5970162688L);
+    }
+}
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
rename to plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgFileTest.java
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java
similarity index 100%
rename from plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/qemu/QemuImgTest.java
rename to plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
deleted file mode 100644
index be191f5..0000000
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ /dev/null
@@ -1,5221 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.Vector;
-
-import javax.naming.ConfigurationException;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuTuneDef;
-import org.apache.commons.lang.SystemUtils;
-import org.joda.time.Duration;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainBlockStats;
-import org.libvirt.DomainInfo;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.DomainInterfaceStats;
-import org.libvirt.LibvirtException;
-import org.libvirt.MemoryStatistic;
-import org.libvirt.NodeInfo;
-import org.libvirt.StorageVol;
-import org.libvirt.jna.virDomainMemoryStats;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.utils.linux.CPUStat;
-import org.apache.cloudstack.utils.linux.MemStat;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.AttachIsoCommand;
-import com.cloud.agent.api.BackupSnapshotCommand;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.CheckOnHostCommand;
-import com.cloud.agent.api.CheckRouterAnswer;
-import com.cloud.agent.api.CheckRouterCommand;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.CleanupNetworkRulesCmd;
-import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
-import com.cloud.agent.api.CreateStoragePoolCommand;
-import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.GetVmDiskStatsCommand;
-import com.cloud.agent.api.GetVmStatsCommand;
-import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.ManageSnapshotCommand;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.agent.api.ModifySshKeysCommand;
-import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.NetworkRulesSystemVmCommand;
-import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.OvsCreateTunnelCommand;
-import com.cloud.agent.api.OvsDestroyBridgeCommand;
-import com.cloud.agent.api.OvsDestroyTunnelCommand;
-import com.cloud.agent.api.OvsFetchInterfaceCommand;
-import com.cloud.agent.api.OvsSetupBridgeCommand;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Host;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Tier;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Vm;
-import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
-import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Acl;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.PvlanSetupCommand;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.RebootRouterCommand;
-import com.cloud.agent.api.SecurityGroupRulesCmd;
-import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.agent.api.UnPlugNicCommand;
-import com.cloud.agent.api.UpdateHostPasswordCommand;
-import com.cloud.agent.api.UpgradeSnapshotCommand;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
-import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.CreateCommand;
-import com.cloud.agent.api.storage.DestroyCommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
-import com.cloud.agent.api.storage.ResizeVolumeCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
-import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper;
-import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper;
-import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
-import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetworkSetupInfo;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.storage.resource.StorageSubsystemCommandHandler;
-import com.cloud.storage.template.Processor;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
-import com.cloud.utils.Pair;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VirtualMachine.Type;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class LibvirtComputingResourceTest {
-
-    @Mock
-    private LibvirtComputingResource libvirtComputingResource;
-    @Mock
-    VirtualMachineTO vmTO;
-
-    String hyperVisorType = "kvm";
-    Random random = new Random();
-
-    /**
-        This test tests if the Agent can handle a vmSpec coming
-        from a <=4.1 management server.
-
-        The overcommit feature has not been merged in there and thus
-        only 'speed' is set.
-     */
-    @Test
-    public void testCreateVMFromSpecLegacy() {
-        final int id = random.nextInt(65534);
-        final String name = "test-instance-1";
-
-        final int cpus = random.nextInt(2) + 1;
-        final int speed = 1024;
-        final int minRam = 256 * 1024;
-        final int maxRam = 512 * 1024;
-
-        final String os = "Ubuntu";
-
-        final String vncAddr = "";
-        final String vncPassword = "mySuperSecretPassword";
-
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
-        to.setVncAddr(vncAddr);
-        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
-
-        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
-        vm.setHvsType(hyperVisorType);
-
-        verifyVm(to, vm);
-    }
-
-    /**
-        This test verifies that CPU topology is properly set for hex-core
-     */
-    @Test
-    public void testCreateVMFromSpecWithTopology6() {
-        final int id = random.nextInt(65534);
-        final String name = "test-instance-1";
-
-        final int cpus = 12;
-        final int minSpeed = 1024;
-        final int maxSpeed = 2048;
-        final int minRam = 256 * 1024;
-        final int maxRam = 512 * 1024;
-
-        final String os = "Ubuntu";
-
-        final String vncAddr = "";
-        final String vncPassword = "mySuperSecretPassword";
-
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
-        to.setVncAddr(vncAddr);
-        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
-
-        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
-        vm.setHvsType(hyperVisorType);
-
-        verifyVm(to, vm);
-    }
-
-    /**
-        This test verifies that CPU topology is properly set for quad-core
-     */
-    @Test
-    public void testCreateVMFromSpecWithTopology4() {
-        final int id = random.nextInt(65534);
-        final String name = "test-instance-1";
-
-        final int cpus = 8;
-        final int minSpeed = 1024;
-        final int maxSpeed = 2048;
-        final int minRam = 256 * 1024;
-        final int maxRam = 512 * 1024;
-
-        final String os = "Ubuntu";
-
-        final String vncAddr = "";
-        final String vncPassword = "mySuperSecretPassword";
-
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
-        to.setVncAddr(vncAddr);
-        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
-
-        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
-        vm.setHvsType(hyperVisorType);
-
-        verifyVm(to, vm);
-    }
-
-    /**
-        This test tests if the Agent can handle a vmSpec coming
-        from a >4.1 management server.
-
-        It tests if the Agent can handle a vmSpec with overcommit
-        data like minSpeed and maxSpeed in there
-     */
-    @Test
-    public void testCreateVMFromSpec() {
-        final int id = random.nextInt(65534);
-        final String name = "test-instance-1";
-
-        final int cpus = random.nextInt(2) + 1;
-        final int minSpeed = 1024;
-        final int maxSpeed = 2048;
-        final int minRam = 256 * 1024;
-        final int maxRam = 512 * 1024;
-
-        final String os = "Ubuntu";
-
-        final String vncAddr = "";
-        final String vncPassword = "mySuperSecretPassword";
-
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        final VirtualMachineTO to =
-                new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword);
-        to.setVncAddr(vncAddr);
-        to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9");
-
-        final LibvirtVMDef vm = lcr.createVMFromSpec(to);
-        vm.setHvsType(hyperVisorType);
-
-        verifyVm(to, vm);
-    }
-
-    private void verifyVm(final VirtualMachineTO to, final LibvirtVMDef vm) {
-        final Document domainDoc = parse(vm.toString());
-        assertXpath(domainDoc, "/domain/@type", vm.getHvsType());
-        assertXpath(domainDoc, "/domain/name/text()", to.getName());
-        assertXpath(domainDoc, "/domain/uuid/text()", to.getUuid());
-        assertXpath(domainDoc, "/domain/description/text()", to.getOs());
-        assertXpath(domainDoc, "/domain/clock/@offset", "utc");
-        assertNodeExists(domainDoc, "/domain/features/pae");
-        assertNodeExists(domainDoc, "/domain/features/apic");
-        assertNodeExists(domainDoc, "/domain/features/acpi");
-        assertXpath(domainDoc, "/domain/devices/serial/@type", "pty");
-        assertXpath(domainDoc, "/domain/devices/serial/target/@port", "0");
-        assertXpath(domainDoc, "/domain/devices/graphics/@type", "vnc");
-        assertXpath(domainDoc, "/domain/devices/graphics/@listen", to.getVncAddr());
-        assertXpath(domainDoc, "/domain/devices/graphics/@autoport", "yes");
-        assertXpath(domainDoc, "/domain/devices/graphics/@passwd", to.getVncPassword());
-
-        assertXpath(domainDoc, "/domain/devices/console/@type", "pty");
-        assertXpath(domainDoc, "/domain/devices/console/target/@port", "0");
-        assertXpath(domainDoc, "/domain/devices/input/@type", "tablet");
-        assertXpath(domainDoc, "/domain/devices/input/@bus", "usb");
-
-        assertNodeExists(domainDoc, "/domain/devices/channel");
-        assertXpath(domainDoc, "/domain/devices/channel/@type", ChannelDef.ChannelType.UNIX.toString());
-
-        /*
-           The configure() method of LibvirtComputingResource has not been called, so the default path for the sockets
-           hasn't been initialized. That's why we check for 'null'
-
-           Calling configure is also not possible since that looks for certain files on the system which are not present
-           during testing
-         */
-        assertXpath(domainDoc, "/domain/devices/channel/source/@path", "null/" + to.getName() + ".org.qemu.guest_agent.0");
-        assertXpath(domainDoc, "/domain/devices/channel/target/@name", "org.qemu.guest_agent.0");
-
-        assertXpath(domainDoc, "/domain/memory/text()", String.valueOf( to.getMaxRam() / 1024 ));
-        assertXpath(domainDoc, "/domain/currentMemory/text()", String.valueOf( to.getMinRam() / 1024 ));
-
-        assertXpath(domainDoc, "/domain/devices/memballoon/@model", "virtio");
-        assertXpath(domainDoc, "/domain/vcpu/text()", String.valueOf(to.getCpus()));
-
-        assertXpath(domainDoc, "/domain/os/type/@machine", "pc");
-        assertXpath(domainDoc, "/domain/os/type/text()", "hvm");
-
-        assertNodeExists(domainDoc, "/domain/cpu");
-        assertNodeExists(domainDoc, "/domain/os/boot[@dev='cdrom']");
-        assertNodeExists(domainDoc, "/domain/os/boot[@dev='hd']");
-
-        assertXpath(domainDoc, "/domain/on_reboot/text()", "restart");
-        assertXpath(domainDoc, "/domain/on_poweroff/text()", "destroy");
-        assertXpath(domainDoc, "/domain/on_crash/text()", "destroy");
-
-        assertXpath(domainDoc, "/domain/devices/watchdog/@model", "i6300esb");
-        assertXpath(domainDoc, "/domain/devices/watchdog/@action", "none");
-    }
-
-    static Document parse(final String input) {
-        try {
-            return DocumentBuilderFactory.newInstance().newDocumentBuilder()
-                    .parse(new ByteArrayInputStream(input.getBytes()));
-        } catch (SAXException | IOException | ParserConfigurationException e) {
-            throw new IllegalArgumentException("Cloud not parse: "+input, e);
-        }
-    }
-
-    static void assertNodeExists(final Document doc, final String xPathExpr) {
-        try {
-            Assert.assertNotNull(XPathFactory.newInstance().newXPath()
-                    .evaluate(xPathExpr, doc, XPathConstants.NODE));
-        } catch (final XPathExpressionException e) {
-            Assert.fail(e.getMessage());
-        }
-    }
-
-    static void assertXpath(final Document doc, final String xPathExpr,
-            final String expected) {
-        try {
-            Assert.assertEquals(expected, XPathFactory.newInstance().newXPath()
-                    .evaluate(xPathExpr, doc));
-        } catch (final XPathExpressionException e) {
-            Assert.fail("Could not evaluate xpath" + xPathExpr + ":"
-                    + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetNicStats() {
-        //this test is only working on linux because of the loopback interface name
-        //also the tested code seems to work only on linux
-        Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
-        final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
-        final Pair<Double, Double> stats = libvirtComputingResource.getNicStats("lo");
-        assertNotNull(stats);
-    }
-
-    @Test
-    public void diskUuidToSerialTest() {
-        final String uuid = "38400000-8cf0-11bd-b24e-10b96e4ef00d";
-        final String expected = "384000008cf011bdb24e";
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        Assert.assertEquals(expected, lcr.diskUuidToSerial(uuid));
-    }
-
-    @Test
-    public void testUUID() {
-        String uuid = "1";
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        uuid = lcr.getUuid(uuid);
-        Assert.assertTrue(!uuid.equals("1"));
-
-        final String oldUuid = UUID.randomUUID().toString();
-        uuid = oldUuid;
-        uuid = lcr.getUuid(uuid);
-        Assert.assertTrue(uuid.equals(oldUuid));
-    }
-
-    private static final String VMNAME = "test";
-
-    @Test
-    public void testGetVmStat() throws LibvirtException {
-        final Connect connect = Mockito.mock(Connect.class);
-        final Domain domain = Mockito.mock(Domain.class);
-        final DomainInfo domainInfo = new DomainInfo();
-        final MemoryStatistic[] domainMem = new MemoryStatistic[2];
-        domainMem[0] = Mockito.mock(MemoryStatistic.class);
-        Mockito.when(domain.getInfo()).thenReturn(domainInfo);
-        Mockito.when(domain.memoryStats(2)).thenReturn(domainMem);
-        Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain);
-        final NodeInfo nodeInfo = new NodeInfo();
-        nodeInfo.cpus = 8;
-        nodeInfo.memory = 8 * 1024 * 1024;
-        nodeInfo.sockets = 2;
-        nodeInfo.threads = 2;
-        nodeInfo.model = "Foo processor";
-        Mockito.when(connect.nodeInfo()).thenReturn(nodeInfo);
-        // this is testing the interface stats, returns an increasing number of sent and received bytes
-        Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainInterfaceStats>() {
-            // increment with less than a KB, so this should be less than 1 KB
-            final static int increment = 1000;
-            int rxBytes = 1000;
-            int txBytes = 1000;
-
-            @Override
-            public DomainInterfaceStats answer(final InvocationOnMock invocation) throws Throwable {
-                final DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats();
-                domainInterfaceStats.rx_bytes = rxBytes += increment;
-                domainInterfaceStats.tx_bytes = txBytes += increment;
-                return domainInterfaceStats;
-
-            }
-
-        });
-
-        Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer<DomainBlockStats>() {
-            // a little less than a KB
-            final static int increment = 1000;
-
-            int rdBytes = 0;
-            int wrBytes = 1024;
-
-            @Override
-            public DomainBlockStats answer(final InvocationOnMock invocation) throws Throwable {
-                final DomainBlockStats domainBlockStats = new DomainBlockStats();
-
-                domainBlockStats.rd_bytes = rdBytes += increment;
-                domainBlockStats.wr_bytes = wrBytes += increment;
-                return domainBlockStats;
-            }
-
-        });
-
-        final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() {
-            @Override
-            public List<InterfaceDef> getInterfaces(final Connect conn, final String vmName) {
-                final InterfaceDef interfaceDef = new InterfaceDef();
-                return Arrays.asList(interfaceDef);
-            }
-
-            @Override
-            public List<DiskDef> getDisks(final Connect conn, final String vmName) {
-                final DiskDef diskDef = new DiskDef();
-                return Arrays.asList(diskDef);
-            }
-
-        };
-        libvirtComputingResource.getVmStat(connect, VMNAME);
-        final VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME);
-        // network traffic as generated by the logic above, must be greater than zero
-        Assert.assertTrue(vmStat.getNetworkReadKBs() > 0);
-        Assert.assertTrue(vmStat.getNetworkWriteKBs() > 0);
-        // IO traffic as generated by the logic above, must be greater than zero
-        Assert.assertTrue(vmStat.getDiskReadKBs() > 0);
-        Assert.assertTrue(vmStat.getDiskWriteKBs() > 0);
-        // Memory limit of VM must be greater than zero
-        Assert.assertTrue(vmStat.getIntFreeMemoryKBs() >= 0);
-        Assert.assertTrue(vmStat.getMemoryKBs() >= 0);
-        Assert.assertTrue(vmStat.getTargetMemoryKBs() >= vmStat.getMemoryKBs());
-    }
-
-    @Test
-    public void getCpuSpeed() {
-        Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
-        final NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
-        LibvirtComputingResource.getCpuSpeed(nodeInfo);
-    }
-
-    /*
-     * New Tests
-     */
-
-    @Test
-    public void testStopCommandNoCheck() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final StopCommand command = new StopCommand(vmName, false, false);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStopCommandCheckVmNOTRunning() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final DomainInfo info = Mockito.mock(DomainInfo.class);
-        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_SHUTDOWN;
-        info.state = state;
-
-        final String vmName = "Test";
-        final StopCommand command = new StopCommand(vmName, false, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
-
-            when(vm.getInfo()).thenReturn(info);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testStopCommandCheckException1() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final DomainInfo info = Mockito.mock(DomainInfo.class);
-        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
-        info.state = state;
-
-        final String vmName = "Test";
-        final StopCommand command = new StopCommand(vmName, false, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
-            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
-
-            when(vm.getInfo()).thenReturn(info);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStopCommandCheckVmRunning() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final DomainInfo info = Mockito.mock(DomainInfo.class);
-        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
-        info.state = state;
-
-        final String vmName = "Test";
-        final StopCommand command = new StopCommand(vmName, false, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(conn.domainLookupByName(command.getVmName())).thenReturn(vm);
-
-            when(vm.getInfo()).thenReturn(info);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetVmStatsCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
-        final List<String> vms = new ArrayList<String>();
-        vms.add(vmName);
-
-        final GetVmStatsCommand command = new GetVmStatsCommand(vms, uuid, "hostname");
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetVmDiskStatsCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
-        final List<String> vms = new ArrayList<String>();
-        vms.add(vmName);
-
-        final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname");
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnection();
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testGetVmDiskStatsCommandException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
-        final List<String> vms = new ArrayList<String>();
-        vms.add(vmName);
-
-        final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname");
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnection();
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testRebootCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootCommand command = new RebootCommand(vmName, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRebootCommandException1() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootCommand command = new RebootCommand(vmName, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testRebootCommandError() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootCommand command = new RebootCommand(vmName, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenReturn("error");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRebootCommandException2() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootCommand command = new RebootCommand(vmName, true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testRebootRouterCommand() {
-        final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootRouterCommand command = new RebootRouterCommand(vmName, "127.0.0.1");
-
-        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testRebootRouterCommandConnect() {
-        final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final RebootRouterCommand command = new RebootRouterCommand(vmName, "127.0.0.1");
-
-        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(routingResource.connect(command.getPrivateIpAddress())).thenReturn(true);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetHostStatsCommand() {
-        // A bit difficult to test due to the logger being passed and the parser itself relying on the connection.
-        // Have to spend some more time afterwards in order to refactor the wrapper itself.
-        final CPUStat cpuStat = Mockito.mock(CPUStat.class);
-        final MemStat memStat = Mockito.mock(MemStat.class);
-
-        final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
-        final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l);
-
-        when(libvirtComputingResource.getCPUStat()).thenReturn(cpuStat);
-        when(libvirtComputingResource.getMemStat()).thenReturn(memStat);
-        when(libvirtComputingResource.getNicStats(Mockito.anyString())).thenReturn(new Pair<Double, Double>(1.0d, 1.0d));
-        when(cpuStat.getCpuUsedPercent()).thenReturn(0.5d);
-        when(memStat.getAvailable()).thenReturn(1500.5d);
-        when(memStat.getTotal()).thenReturn(15000d);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getCPUStat();
-        verify(libvirtComputingResource, times(1)).getMemStat();
-        verify(cpuStat, times(1)).getCpuUsedPercent();
-        verify(memStat, times(1)).getAvailable();
-        verify(memStat, times(1)).getTotal();
-    }
-
-    @Test
-    public void testCheckHealthCommand() {
-        final CheckHealthCommand command = new CheckHealthCommand();
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testPrepareForMigrationCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
-        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final NicTO nicTO = Mockito.mock(NicTO.class);
-        final DiskTO diskTO = Mockito.mock(DiskTO.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-
-        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
-        when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO});
-
-        when(nicTO.getType()).thenReturn(TrafficType.Guest);
-        when(diskTO.getType()).thenReturn(Volume.Type.ISO);
-
-        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(vm, times(1)).getNics();
-        verify(vm, times(1)).getDisks();
-        verify(diskTO, times(1)).getType();
-    }
-
-    @Test
-    public void testPrepareForMigrationCommandMigration() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
-        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final NicTO nicTO = Mockito.mock(NicTO.class);
-        final DiskTO diskTO = Mockito.mock(DiskTO.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-
-        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
-        when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO});
-
-        when(nicTO.getType()).thenReturn(TrafficType.Guest);
-        when(diskTO.getType()).thenReturn(Volume.Type.ISO);
-
-        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
-        when(storagePoolManager.connectPhysicalDisksViaVmSpec(vm)).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(vm, times(1)).getNics();
-        verify(vm, times(1)).getDisks();
-        verify(diskTO, times(1)).getType();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPrepareForMigrationCommandLibvirtException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
-        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final NicTO nicTO = Mockito.mock(NicTO.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-
-        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
-        when(nicTO.getType()).thenReturn(TrafficType.Guest);
-
-        when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver);
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(vm, times(1)).getNics();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPrepareForMigrationCommandURISyntaxException() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
-        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final NicTO nicTO = Mockito.mock(NicTO.class);
-        final DiskTO volume = Mockito.mock(DiskTO.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-
-        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
-        when(vm.getDisks()).thenReturn(new DiskTO[]{volume});
-
-        when(nicTO.getType()).thenReturn(TrafficType.Guest);
-        when(volume.getType()).thenReturn(Volume.Type.ISO);
-
-        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenReturn(vifDriver);
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
-        try {
-            when(libvirtComputingResource.getVolumePath(conn, volume)).thenThrow(URISyntaxException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(vm, times(1)).getNics();
-        verify(vm, times(1)).getDisks();
-        verify(volume, times(1)).getType();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPrepareForMigrationCommandInternalErrorException() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class);
-        final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final NicTO nicTO = Mockito.mock(NicTO.class);
-        final DiskTO volume = Mockito.mock(DiskTO.class);
-
-        final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(vm.getNics()).thenReturn(new NicTO[]{nicTO});
-        when(nicTO.getType()).thenReturn(TrafficType.Guest);
-
-        when(libvirtComputingResource.getVifDriver(nicTO.getType(), nicTO.getName())).thenThrow(InternalErrorException.class);
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager);
-        try {
-            when(libvirtComputingResource.getVolumePath(conn, volume)).thenReturn("/path");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(vm, times(1)).getNics();
-    }
-
-    @Test
-    public void testMigrateCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final Connect dconn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final String destIp = "127.0.0.100";
-        final boolean isWindows = false;
-        final VirtualMachineTO vmTO = Mockito.mock(VirtualMachineTO.class);
-        final boolean executeInSequence = false;
-
-        final MigrateCommand command = new MigrateCommand(vmName, destIp, isWindows, vmTO, executeInSequence );
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(libvirtUtilitiesHelper.retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system")).thenReturn(dconn);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-        final List<InterfaceDef> ifaces = new ArrayList<InterfaceDef>();
-        ifaces.add(interfaceDef);
-
-        when(libvirtComputingResource.getInterfaces(conn, vmName)).thenReturn(ifaces);
-
-        final DiskDef diskDef = Mockito.mock(DiskDef.class);
-        final List<DiskDef> disks = new ArrayList<DiskDef>();
-        disks.add(diskDef);
-
-        when(libvirtComputingResource.getDisks(conn, vmName)).thenReturn(disks);
-        final Domain dm = Mockito.mock(Domain.class);
-        try {
-            when(conn.domainLookupByName(vmName)).thenReturn(dm);
-
-            when(libvirtComputingResource.getPrivateIp()).thenReturn("127.0.0.1");
-            when(dm.getXMLDesc(8)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
-                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
-            when(dm.getXMLDesc(1)).thenReturn("<domain type='kvm' id='3'>" + "  <devices>" + "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>"
-                    + "      <listen type='address' address='10.10.10.1'/>" + "    </graphics>" + "  </devices>" + "</domain>");
-            when(dm.isPersistent()).thenReturn(1);
-            doNothing().when(dm).undefine();
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final Exception e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-            verify(libvirtUtilitiesHelper, times(1)).retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        verify(libvirtComputingResource, times(1)).getInterfaces(conn, vmName);
-        verify(libvirtComputingResource, times(1)).getDisks(conn, vmName);
-        try {
-            verify(conn, times(1)).domainLookupByName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        try {
-            verify(dm, times(1)).getXMLDesc(8);
-        } catch (final Throwable t) {
-            try {
-                verify(dm, times(1)).getXMLDesc(1);
-            }
-            catch (final LibvirtException e) {
-                fail(e.getMessage());
-            }
-        }
-    }
-
-    @Test
-    public void testPingTestHostIpCommand() {
-        final PingTestCommand command = new PingTestCommand("127.0.0.1");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testPingTestPvtIpCommand() {
-        final PingTestCommand command = new PingTestCommand("127.0.0.1", "127.0.0.1");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testPingOnlyOneIpCommand() {
-        final PingTestCommand command = new PingTestCommand("127.0.0.1", null);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testCheckVirtualMachineCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testExceptionCheckVirtualMachineCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testReadyCommand() {
-        final ReadyCommand command = new ReadyCommand(1l);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testAttachIsoCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testAttachIsoCommandLibvirtException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testAttachIsoCommandURISyntaxException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(URISyntaxException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testAttachIsoCommandInternalErrorException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String vmName = "Test";
-        final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testWatchConsoleProxyLoadCommand() {
-        final int interval = 0;
-        final long proxyVmId = 0l;
-        final String proxyVmName = "host";
-        final String proxyManagementIp = "127.0.0.1";
-        final int proxyCmdPort = 0;
-
-        final WatchConsoleProxyLoadCommand command = new WatchConsoleProxyLoadCommand(interval, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testCheckConsoleProxyLoadCommand() {
-        final long proxyVmId = 0l;
-        final String proxyVmName = "host";
-        final String proxyManagementIp = "127.0.0.1";
-        final int proxyCmdPort = 0;
-
-        final CheckConsoleProxyLoadCommand command = new CheckConsoleProxyLoadCommand(proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testGetVncPortCommand() {
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final GetVncPortCommand command = new GetVncPortCommand(1l, "host");
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testGetVncPortCommandLibvirtException() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final GetVncPortCommand command = new GetVncPortCommand(1l, "host");
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testModifySshKeysCommand() {
-        final ModifySshKeysCommand command = new ModifySshKeysCommand("", "");
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        when(libvirtUtilitiesHelper.retrieveSshKeysPath()).thenReturn("/path/keys");
-        when(libvirtUtilitiesHelper.retrieveSshPubKeyPath()).thenReturn("/path/pub/keys");
-        when(libvirtUtilitiesHelper.retrieveSshPrvKeyPath()).thenReturn("/path/pvt/keys");
-
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getTimeout();
-    }
-
-    @Test
-    public void testMaintainCommand() {
-        final MaintainCommand command = new MaintainCommand();
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testCreateCommandNoTemplate() {
-        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final boolean executeInSequence = false;
-
-        final CreateCommand command = new CreateCommand(diskCharacteristics, pool, executeInSequence );
-
-        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
-        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-
-        when(primary.createPhysicalDisk(diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), diskCharacteristics.getSize())).thenReturn(vol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
-    }
-
-    @Test
-    public void testCreateCommand() {
-        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final String templateUrl = "http://template";
-        final boolean executeInSequence = false;
-
-        final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
-
-        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
-        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-
-        when(primary.getType()).thenReturn(StoragePoolType.CLVM);
-        when(libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primary, diskCharacteristics.getPath())).thenReturn(vol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
-    }
-
-    @Test
-    public void testCreateCommandCLVM() {
-        final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final String templateUrl = "http://template";
-        final boolean executeInSequence = false;
-
-        final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
-
-        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMPhysicalDisk baseVol = Mockito.mock(KVMPhysicalDisk.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
-        when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-
-        when(primary.getPhysicalDisk(command.getTemplateUrl())).thenReturn(baseVol);
-        when(poolManager.createDiskFromTemplate(baseVol,
-                diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), primary, 0)).thenReturn(vol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
-    }
-
-    @Test
-    public void testDestroyCommand() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final Volume volume = Mockito.mock(Volume.class);
-        final String vmName = "Test";
-
-        final DestroyCommand command = new DestroyCommand(pool, volume, vmName);
-
-        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final VolumeTO vol = command.getVolume();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
-        when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testDestroyCommandError() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final Volume volume = Mockito.mock(Volume.class);
-        final String vmName = "Test";
-
-        final DestroyCommand command = new DestroyCommand(pool, volume, vmName);
-
-        final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final VolumeTO vol = command.getVolume();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
-        when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary);
-
-        when(primary.deletePhysicalDisk(vol.getPath(), null)).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid());
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void testPrimaryStorageDownloadCommandNOTemplateDisk() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-
-        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
-
-        final String name = "Test";
-        final String url = "http://template/";
-        final ImageFormat format = ImageFormat.QCOW2;
-        final long accountId = 1l;
-        final int wait = 0;
-        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
-
-        final KVMPhysicalDisk disk = new KVMPhysicalDisk("/path", "disk.qcow2", primaryPool);
-        disks.add(disk);
-
-        final int index = url.lastIndexOf("/");
-        final String mountpoint = url.substring(0, index);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
-        when(secondaryPool.listPhysicalDisks()).thenReturn(disks);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
-        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testPrimaryStorageDownloadCommandNOTemplateNODisk() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-
-        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
-
-        final String name = "Test";
-        final String url = "http://template/";
-        final ImageFormat format = ImageFormat.QCOW2;
-        final long accountId = 1l;
-        final int wait = 0;
-        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
-
-        final int index = url.lastIndexOf("/");
-        final String mountpoint = url.substring(0, index);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
-        when(secondaryPool.listPhysicalDisks()).thenReturn(disks);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
-        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testPrimaryStorageDownloadCommandNOTemplateNOQcow2() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-
-        final List<KVMPhysicalDisk> disks = new ArrayList<KVMPhysicalDisk>();
-        final List<KVMPhysicalDisk> spiedDisks = Mockito.spy(disks);
-
-        final String name = "Test";
-        final String url = "http://template/";
-        final ImageFormat format = ImageFormat.QCOW2;
-        final long accountId = 1l;
-        final int wait = 0;
-        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
-
-        final int index = url.lastIndexOf("/");
-        final String mountpoint = url.substring(0, index);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
-        when(secondaryPool.listPhysicalDisks()).thenReturn(spiedDisks);
-        when(spiedDisks.isEmpty()).thenReturn(false);
-
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
-        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void testPrimaryStorageDownloadCommandTemplateNoDisk() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-
-        final String name = "Test";
-        final String url = "http://template/template.qcow2";
-        final ImageFormat format = ImageFormat.VHD;
-        final long accountId = 1l;
-        final int wait = 0;
-        final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class);
-
-        final int index = url.lastIndexOf("/");
-        final String mountpoint = url.substring(0, index);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool);
-        when(secondaryPool.getPhysicalDisk("template.qcow2")).thenReturn(tmplVol);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool);
-        when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPoolUuid());
-    }
-
-    @Test
-    public void testGetStorageStatsCommand() {
-        final DataStoreTO store = Mockito.mock(DataStoreTO.class);
-        final GetStorageStatsCommand command = new GetStorageStatsCommand(store );
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true)).thenReturn(secondaryPool);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePool(command.getPooltype(), command.getStorageId(), true);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testGetStorageStatsCommandException() {
-        final DataStoreTO store = Mockito.mock(DataStoreTO.class);
-        final GetStorageStatsCommand command = new GetStorageStatsCommand(store );
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testUpgradeSnapshotCommand() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final String secondaryStoragePoolURL = "url";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final Long templateId = 1l;
-        final Long tmpltAccountId = 1l;
-        final String volumePath = "/opt/path";
-        final String snapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
-        final String snapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
-        final String version = "1";
-
-        final UpgradeSnapshotCommand command = new UpgradeSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, templateId, tmpltAccountId, volumePath, snapshotUuid, snapshotName, version);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testDeleteStoragePoolCommand() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-
-        final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool);
-
-        final StorageFilerTO pool = command.getPool();
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testDeleteStoragePoolCommandException() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-
-        final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool);
-
-        final StorageFilerTO pool = command.getPool();
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid());
-    }
-
-    @Test
-    public void testOvsSetupBridgeCommand() {
-        final String name = "Test";
-        final Long hostId = 1l;
-        final Long networkId = 1l;
-
-        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName())).thenReturn(true);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsSetupBridgeCommandFailure1() {
-        final String name = "Test";
-        final Long hostId = 1l;
-        final Long networkId = 1l;
-
-        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName())).thenReturn(false);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsSetupBridgeCommandFailure2() {
-        final String name = "Test";
-        final Long hostId = 1l;
-        final Long networkId = 1l;
-
-        final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName())).thenReturn(true);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(),
-                command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsDestroyBridgeCommand() {
-        final String name = "Test";
-        final Long hostId = 1l;
-        final Long networkId = 1l;
-
-        final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId);
-
-        when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(true);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsDestroyBridgeCommandFailure() {
-        final String name = "Test";
-        final Long hostId = 1l;
-        final Long networkId = 1l;
-
-        final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId);
-
-        when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(false);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsFetchInterfaceCommand() {
-        final String label = "eth0";
-
-        final OvsFetchInterfaceCommand command = new OvsFetchInterfaceCommand(label);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testOvsVpcPhysicalTopologyConfigCommand() {
-        final Host[] hosts = null;
-        final Tier[] tiers = null;
-        final Vm[] vms = null;
-        final String cidr = null;
-
-        final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr);
-
-        when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path");
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
-        verify(libvirtComputingResource, times(1)).getTimeout();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testOvsVpcPhysicalTopologyConfigCommandFailure() {
-        final Host[] hosts = null;
-        final Tier[] tiers = null;
-        final Vm[] vms = null;
-        final String cidr = null;
-
-        final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr);
-
-        when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
-    }
-
-    @Test
-    public void testOvsVpcRoutingPolicyConfigCommand() {
-        final String id = null;
-        final String cidr = null;
-        final Acl[] acls = null;
-        final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null;
-
-        final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers);
-
-        when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path");
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
-        verify(libvirtComputingResource, times(1)).getTimeout();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testOvsVpcRoutingPolicyConfigCommandFailure() {
-        final String id = null;
-        final String cidr = null;
-        final Acl[] acls = null;
-        final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null;
-
-        final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers);
-
-        when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getOvsTunnelPath();
-    }
-
-    @Test
-    public void testCreateStoragePoolCommand() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final CreateStoragePoolCommand command = new CreateStoragePoolCommand(true, pool);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testModifyStoragePoolCommand() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool kvmStoragePool = Mockito.mock(KVMStoragePool.class);
-
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
-                .getUserInfo(), command.getPool().getType())).thenReturn(kvmStoragePool);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
-                .getUserInfo(), command.getPool().getType());
-    }
-
-    @Test
-    public void testModifyStoragePoolCommandFailure() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
-                .getUserInfo(), command.getPool().getType())).thenReturn(null);
-
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool()
-                .getUserInfo(), command.getPool().getType());
-    }
-
-    @Test
-    public void testCleanupNetworkRulesCmd() {
-        final CleanupNetworkRulesCmd command = new CleanupNetworkRulesCmd(1);
-
-        when(libvirtComputingResource.cleanupRules()).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).cleanupRules();
-    }
-
-    @Test
-    public void testNetworkRulesVmSecondaryIpCommand() {
-        final String vmName = "Test";
-        final String vmMac = "00:00:00:00";
-        final String secondaryIp = "127.0.0.1";
-        final boolean action = true;
-
-        final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action );
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        when(libvirtComputingResource.configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        verify(libvirtComputingResource, times(1)).configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testNetworkRulesVmSecondaryIpCommandFailure() {
-        final String vmName = "Test";
-        final String vmMac = "00:00:00:00";
-        final String secondaryIp = "127.0.0.1";
-        final boolean action = true;
-
-        final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action );
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-    }
-
-    @Test
-    public void testNetworkRulesSystemVmCommand() {
-        final String vmName = "Test";
-        final Type type = Type.SecondaryStorageVm;
-
-        final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        when(libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, command.getVmName())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        verify(libvirtComputingResource, times(1)).configureDefaultNetworkRulesForSystemVm(conn, command.getVmName());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testNetworkRulesSystemVmCommandFailure() {
-        final String vmName = "Test";
-        final Type type = Type.SecondaryStorageVm;
-
-        final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-    }
-
-    @Test
-    public void testCheckSshCommand() {
-        final String instanceName = "Test";
-        final String ip = "127.0.0.1";
-        final int port = 22;
-
-        final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port);
-
-        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
-
-        final String privateIp = command.getIp();
-        final int cmdPort = command.getPort();
-
-        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
-        when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
-        verify(virtRouterResource, times(1)).connect(privateIp, cmdPort);
-    }
-
-    @Test
-    public void testCheckSshCommandFailure() {
-        final String instanceName = "Test";
-        final String ip = "127.0.0.1";
-        final int port = 22;
-
-        final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port);
-
-        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
-
-        final String privateIp = command.getIp();
-        final int cmdPort = command.getPort();
-
-        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
-        when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVirtRouterResource();
-        verify(virtRouterResource, times(1)).connect(privateIp, cmdPort);
-    }
-
-    @Test
-    public void testCheckNetworkCommand() {
-        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-
-        final PhysicalNetworkSetupInfo nic = Mockito.mock(PhysicalNetworkSetupInfo.class);
-        networkInfoList.add(nic);
-
-        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
-
-        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, nic.getGuestNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.checkNetwork(TrafficType.Management, nic.getPrivateNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.checkNetwork(TrafficType.Public, nic.getPublicNetworkName())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, nic.getGuestNetworkName());
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, nic.getPrivateNetworkName());
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Public, nic.getPublicNetworkName());
-    }
-
-    @Test
-    public void testCheckNetworkCommandFail1() {
-        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-
-        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
-        networkInfoList.add(networkSetupInfo);
-
-        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
-
-        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
-    }
-
-    @Test
-    public void testCheckNetworkCommandFail2() {
-        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-
-        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
-        networkInfoList.add(networkSetupInfo);
-
-        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
-
-        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
-    }
-
-    @Test
-    public void testCheckNetworkCommandFail3() {
-        final List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-
-        final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class);
-        networkInfoList.add(networkSetupInfo);
-
-        final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList);
-
-        when(libvirtComputingResource.checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.checkNetwork(TrafficType.Public, networkSetupInfo.getPublicNetworkName())).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Guest, networkSetupInfo.getGuestNetworkName());
-        verify(libvirtComputingResource, times(1)).checkNetwork(TrafficType.Management, networkSetupInfo.getPrivateNetworkName());
-    }
-
-    @Test
-    public void testOvsDestroyTunnelCommand() {
-        final String networkName = "Test";
-        final Long networkId = 1l;
-        final String inPortName = "eth";
-
-        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-    }
-
-    @Test
-    public void testOvsDestroyTunnelCommandFailure1() {
-        final String networkName = "Test";
-        final Long networkId = 1l;
-        final String inPortName = "eth";
-
-        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testOvsDestroyTunnelCommandFailure2() {
-        final String networkName = "Test";
-        final Long networkId = 1l;
-        final String inPortName = "eth";
-
-        final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName);
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenThrow(Exception.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName());
-    }
-
-    @Test
-    public void testCheckOnHostCommand() {
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);;
-
-        final CheckOnHostCommand command = new CheckOnHostCommand(host);
-
-        final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class);
-
-        when(libvirtComputingResource.getMonitor()).thenReturn(monitor);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getMonitor();
-    }
-
-    @Test
-    public void testOvsCreateTunnelCommand() {
-        final String remoteIp = "127.0.0.1";
-        final Integer key = 1;
-        final Long from = 1l;
-        final Long to = 2l;
-        final long networkId = 1l;
-        final String fromIp = "127.0.0.1";
-        final String networkName = "eth";
-        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
-
-        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
-
-        final String bridge = command.getNetworkName();
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName())).thenReturn(true);
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
-        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName());
-    }
-
-    @Test
-    public void testOvsCreateTunnelCommandFailure1() {
-        final String remoteIp = "127.0.0.1";
-        final Integer key = 1;
-        final Long from = 1l;
-        final Long to = 2l;
-        final long networkId = 1l;
-        final String fromIp = "127.0.0.1";
-        final String networkName = "eth";
-        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
-
-        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
-
-        final String bridge = command.getNetworkName();
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(false);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
-        verify(libvirtComputingResource, times(0)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testOvsCreateTunnelCommandFailure2() {
-        final String remoteIp = "127.0.0.1";
-        final Integer key = 1;
-        final Long from = 1l;
-        final Long to = 2l;
-        final long networkId = 1l;
-        final String fromIp = "127.0.0.1";
-        final String networkName = "eth";
-        final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861";
-
-        final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid);
-
-        final String bridge = command.getNetworkName();
-
-        when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true);
-        when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName())).thenThrow(Exception.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge);
-        verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(),
-                command.getNetworkName());
-    }
-
-    @Test
-    public void testCreateVolumeFromSnapshotCommand() {
-        // This tests asserts to False because there will be a NPE due to UUID static method calls.
-
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "/opt/storage/";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
-        final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/";
-        final int wait = 0;
-
-        final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        final String primaryUuid = command.getPrimaryStoragePoolNameLabel();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool);
-        when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).thenReturn(primaryPool);
-
-        //when(storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0)).thenReturn(disk);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName());
-        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid);
-        //verify(storagePoolMgr, times(1)).copyPhysicalDisk(snapshot, volUuid, primaryPool, 0);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCreateVolumeFromSnapshotCommandCloudException() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "/opt/storage/";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/";
-        final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/";
-        final int wait = 0;
-
-        final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        final String primaryUuid = command.getPrimaryStoragePoolNameLabel();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool);
-        when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName());
-        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid);
-    }
-
-    @Test
-    public void testFenceCommand() {
-        final VirtualMachine vm = Mockito.mock(VirtualMachine.class);;
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-
-        final FenceCommand command = new FenceCommand(vm, host);
-
-        final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class);
-
-        final NfsStoragePool storagePool = Mockito.mock(NfsStoragePool.class);
-        final List<NfsStoragePool> pools = new ArrayList<NfsStoragePool>();
-        pools.add(storagePool);
-
-        when(libvirtComputingResource.getMonitor()).thenReturn(monitor);
-        when(monitor.getStoragePools()).thenReturn(pools);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getMonitor();
-        verify(monitor, times(1)).getStoragePools();
-    }
-
-    @Test
-    public void testSecurityGroupRulesCmdFalse() {
-        final String guestIp = "127.0.0.1";
-        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
-        final String guestMac = "00:00:00:00";
-        final String vmName = "Test";
-        final Long vmId = 1l;
-        final String signature = "signature";
-        final Long seqNum = 1l;
-        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final List<String> secIps = new Vector<String>();
-        final List<String> cidrs = new Vector<String>();
-        cidrs.add("0.0.0.0/0");
-
-        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-        nics.add(interfaceDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(ingressRuleSet[0].getProto()).thenReturn("tcp");
-        when(ingressRuleSet[0].getStartPort()).thenReturn(22);
-        when(ingressRuleSet[0].getEndPort()).thenReturn(22);
-        when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
-
-        when(egressRuleSet[0].getProto()).thenReturn("tcp");
-        when(egressRuleSet[0].getStartPort()).thenReturn(22);
-        when(egressRuleSet[0].getEndPort()).thenReturn(22);
-        when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSecurityGroupRulesCmdTrue() {
-        final String guestIp = "127.0.0.1";
-        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
-        final String guestMac = "00:00:00:00";
-        final String vmName = "Test";
-        final Long vmId = 1l;
-        final String signature = "signature";
-        final Long seqNum = 1l;
-        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final List<String> secIps = new Vector<String>();
-        final List<String> cidrs = new Vector<String>();
-        cidrs.add("0.0.0.0/0");
-
-        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-        nics.add(interfaceDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(interfaceDef.getDevName()).thenReturn("eth0");
-        when(interfaceDef.getBrName()).thenReturn("br0");
-
-        final String vif = nics.get(0).getDevName();
-        final String brname = nics.get(0).getBrName();
-
-        when(ingressRuleSet[0].getProto()).thenReturn("tcp");
-        when(ingressRuleSet[0].getStartPort()).thenReturn(22);
-        when(ingressRuleSet[0].getEndPort()).thenReturn(22);
-        when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
-
-        when(egressRuleSet[0].getProto()).thenReturn("tcp");
-        when(egressRuleSet[0].getStartPort()).thenReturn(22);
-        when(egressRuleSet[0].getEndPort()).thenReturn(22);
-        when(egressRuleSet[0].getAllowedCidrs()).thenReturn(cidrs);
-
-        when(libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getGuestIp6(), command.getSignature(),
-                Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString())).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testSecurityGroupRulesCmdException() {
-        final String guestIp = "127.0.0.1";
-        final String guestIp6 = "2001:db8::cad:40ff:fefd:75c4";
-        final String guestMac = "00:00:00:00";
-        final String vmName = "Test";
-        final Long vmId = 1l;
-        final String signature = "signature";
-        final Long seqNum = 1l;
-        final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)};
-        final List<String> secIps = new Vector<String>();
-
-        final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestIp6, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet, secIps);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-        nics.add(interfaceDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testPlugNicCommandMatchMack() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-        final Type vmtype = Type.DomainRouter;
-
-        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final Domain vm = Mockito.mock(Domain.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
-        nics.add(intDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-
-        when(intDef.getDevName()).thenReturn("eth0");
-        when(intDef.getBrName()).thenReturn("br0");
-        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
-
-        when(nic.getMac()).thenReturn("00:00:00:00");
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testPlugNicCommandNoMatchMack() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-        final Type vmtype = Type.DomainRouter;
-
-        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
-        nics.add(intDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-
-        when(intDef.getDevName()).thenReturn("eth0");
-        when(intDef.getBrName()).thenReturn("br0");
-        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
-
-        when(nic.getMac()).thenReturn("00:00:00:01");
-        when(nic.getName()).thenReturn("br0");
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
-
-            when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
-
-            when(vifDriver.plug(nic, "Other PV", "")).thenReturn(interfaceDef);
-            when(interfaceDef.toString()).thenReturn("Interface");
-
-            final String interfaceDefStr = interfaceDef.toString();
-            doNothing().when(vm).attachDevice(interfaceDefStr);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
-            verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
-            verify(vifDriver, times(1)).plug(nic, "Other PV", "");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPlugNicCommandLibvirtException() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-        final Type vmtype = Type.DomainRouter;
-
-        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPlugNicCommandInternalError() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-        final Type vmtype = Type.DomainRouter;
-
-        final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
-        nics.add(intDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-
-        when(intDef.getDevName()).thenReturn("eth0");
-        when(intDef.getBrName()).thenReturn("br0");
-        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
-
-        when(nic.getMac()).thenReturn("00:00:00:01");
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
-
-            when(libvirtComputingResource.getVifDriver(nic.getType(), nic.getName())).thenReturn(vifDriver);
-
-            when(vifDriver.plug(nic, "Other PV", "")).thenThrow(InternalErrorException.class);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
-            verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType(), nic.getName());
-            verify(vifDriver, times(1)).plug(nic, "Other PV", "");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testUnPlugNicCommandMatchMack() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-
-        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-        final InterfaceDef intDef = Mockito.mock(InterfaceDef.class);
-        nics.add(intDef);
-
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-        final List<VifDriver> drivers = new ArrayList<VifDriver>();
-        drivers.add(vifDriver);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-
-        when(intDef.getDevName()).thenReturn("eth0");
-        when(intDef.getBrName()).thenReturn("br0");
-        when(intDef.getMacAddress()).thenReturn("00:00:00:00");
-
-        when(nic.getMac()).thenReturn("00:00:00:00");
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
-
-            when(interfaceDef.toString()).thenReturn("Interface");
-
-            final String interfaceDefStr = interfaceDef.toString();
-            doNothing().when(vm).detachDevice(interfaceDefStr);
-
-            when(libvirtComputingResource.getAllVifDrivers()).thenReturn(drivers);
-
-            doNothing().when(vifDriver).unplug(intDef);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
-            verify(libvirtComputingResource, times(1)).getAllVifDrivers();
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testUnPlugNicCommandNoNics() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-
-        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final Domain vm = Mockito.mock(Domain.class);
-
-        final List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
-
-        final VifDriver vifDriver = Mockito.mock(VifDriver.class);
-        final List<VifDriver> drivers = new ArrayList<VifDriver>();
-        drivers.add(vifDriver);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-            verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testUnPlugNicCommandLibvirtException() {
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final String instanceName = "Test";
-
-        final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testNetworkUsageCommandNonVpc() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = false;
-        final String gatewayIP = "127.0.0.1";
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.getNetworkStats(command.getPrivateIP())).thenReturn(new long[]{10l, 10l});
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        //Being called twice, although I did not find the second place yet.
-        verify(libvirtComputingResource, times(2)).getNetworkStats(command.getPrivateIP());
-    }
-
-    @Test
-    public void testNetworkUsageCommandNonVpcCreate() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = false;
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "create", forVpc);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.networkUsage(command.getPrivateIP(), "create", null)).thenReturn("SUCCESS");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).networkUsage(command.getPrivateIP(), "create", null);
-    }
-
-    @Test
-    public void testNetworkUsageCommandVpcCreate() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = true;
-        final String gatewayIP = "127.0.0.1";
-        final String vpcCidr = "10.1.1.0/24";
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP, vpcCidr);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR())).thenReturn("SUCCESS");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR());
-    }
-
-    @Test
-    public void testNetworkUsageCommandVpcGet() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = true;
-        final String gatewayIP = "127.0.0.1";
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l});
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption());
-    }
-
-    @Test
-    public void testNetworkUsageCommandVpcVpn() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = true;
-        final String gatewayIP = "127.0.0.1";
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "vpn", forVpc, gatewayIP);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l});
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption());
-    }
-
-    @Test
-    public void testNetworkUsageCommandVpcNoOption() {
-        final String privateIP = "127.0.0.1";
-        final String domRName = "domR";
-        final boolean forVpc = true;
-        final String gatewayIP = "127.0.0.1";
-
-        final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, null, forVpc, gatewayIP);
-
-        libvirtComputingResource.getNetworkStats(command.getPrivateIP());
-
-        when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR())).thenReturn("FAILURE");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR());
-    }
-
-    @Test
-    public void testCreatePrivateTemplateFromVolumeCommand() {
-        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
-        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
-
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final String secondaryStorageUrl = "nfs:/127.0.0.1/storage/secondary";
-        final long templateId = 1l;
-        final long accountId = 1l;
-        final String userSpecifiedName = "User";
-        final String uniqueName = "Unique";
-        final String volumePath = "/123/vol";
-        final String vmName = "Test";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromVolumeCommand command = new CreatePrivateTemplateFromVolumeCommand(pool, secondaryStorageUrl, templateId, accountId, userSpecifiedName, uniqueName, volumePath, vmName, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryStorage = Mockito.mock(KVMStoragePool.class);
-        //final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl)).thenReturn(secondaryStorage);
-        when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel())).thenThrow(new CloudRuntimeException("error"));
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(secondaryStorageUrl);
-        verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testManageSnapshotCommandLibvirtException() {
-        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
-        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
-
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final String volumePath = "/123/vol";
-        final String vmName = "Test";
-
-        final long snapshotId = 1l;
-        final String preSnapshotPath = "/snapshot/path";
-        final String snapshotName = "snap";
-
-        final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, pool, preSnapshotPath, snapshotName, vmName);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        //final Connect conn = Mockito.mock(Connect.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testManageSnapshotCommandLibvirt() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);;
-        final String volumePath = "/123/vol";
-        final String vmName = "Test";
-        final long snapshotId = 1l;
-        final String preSnapshotPath = "/snapshot/path";
-        final String snapshotName = "snap";
-
-        final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, storagePool, preSnapshotPath, snapshotName, vmName);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class);
-        final Domain vm = Mockito.mock(Domain.class);
-        final DomainInfo info = Mockito.mock(DomainInfo.class);
-        final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING;
-        info.state = state;
-
-        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
-
-        final StorageFilerTO pool = command.getPool();
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn);
-            when(libvirtComputingResource.getDomain(conn, command.getVmName())).thenReturn(vm);
-            when(vm.getInfo()).thenReturn(info);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primaryPool);
-        when(primaryPool.getPhysicalDisk(command.getVolumePath())).thenReturn(disk);
-        when(primaryPool.isExternalSnapshot()).thenReturn(false);
-
-        try {
-            when(vm.getUUIDString()).thenReturn("cdb18980-546d-4153-b916-70ee9edf0908");
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testBackupSnapshotCommandLibvirtException() {
-        //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working.
-        //The code is way to big and complex. Will finish the refactor and come back to this to add more cases.
-
-        final StoragePool pool = Mockito.mock(StoragePool.class);;
-        final String secondaryStorageUrl = "nfs:/127.0.0.1/storage/secondary";
-        final long accountId = 1l;
-        final String volumePath = "/123/vol";
-        final String vmName = "Test";
-        final int wait = 0;
-
-        final long snapshotId = 1l;
-        final String snapshotName = "snap";
-
-        final Long dcId = 1l;
-        final Long volumeId = 1l;
-        final Long secHostId = 1l;
-        final String snapshotUuid = "9a0afe7c-26a7-4585-bf87-abf82ae106d9";
-        final String prevBackupUuid = "003a0cc2-2e04-417a-bee0-534ef1724561";
-        final boolean isVolumeInactive = false;
-        final String prevSnapshotUuid = "1791efae-f22d-474b-87c6-92547d6c5877";
-
-        final BackupSnapshotCommand command = new BackupSnapshotCommand(secondaryStorageUrl, dcId, accountId, volumeId, snapshotId, secHostId, volumePath, pool, snapshotUuid, snapshotName, prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, wait);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        //final Connect conn = Mockito.mock(Connect.class);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testCreatePrivateTemplateFromSnapshotCommand() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
-        final String backedUpSnapshotName = "snap";
-        final String origTemplateInstallPath = "/install/path/";
-        final Long newTemplateId = 2l;
-        final String templateName = "templ";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
-
-        final String templatePath = "/template/path";
-        final String localPath = "/mnt/local";
-        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-        final StorageLayer storage = Mockito.mock(StorageLayer.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
-        final Processor qcow2Processor = Mockito.mock(Processor.class);
-        final FormatInfo info = Mockito.mock(FormatInfo.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
-        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(secondaryPool.getLocalPath()).thenReturn(localPath);
-        when(libvirtComputingResource.getStorage()).thenReturn(storage);
-
-        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
-        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
-
-        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
-        final String templateInstallFolder = "template/tmpl/" + templateFolder;
-        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
-
-        try {
-            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
-            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
-        } catch (final ConfigurationException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCreatePrivateTemplateFromSnapshotCommandConfigurationException() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
-        final String backedUpSnapshotName = "snap";
-        final String origTemplateInstallPath = "/install/path/";
-        final Long newTemplateId = 2l;
-        final String templateName = "templ";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
-
-        final String templatePath = "/template/path";
-        final String localPath = "/mnt/local";
-        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-        final StorageLayer storage = Mockito.mock(StorageLayer.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
-        final Processor qcow2Processor = Mockito.mock(Processor.class);
-        final FormatInfo info = Mockito.mock(FormatInfo.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
-        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(secondaryPool.getLocalPath()).thenReturn(localPath);
-        when(libvirtComputingResource.getStorage()).thenReturn(storage);
-
-        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
-        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
-
-        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
-        final String templateInstallFolder = "template/tmpl/" + templateFolder;
-        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
-
-        try {
-            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class);
-            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
-        } catch (final ConfigurationException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCreatePrivateTemplateFromSnapshotCommandInternalErrorException() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
-        final String backedUpSnapshotName = "snap";
-        final String origTemplateInstallPath = "/install/path/";
-        final Long newTemplateId = 2l;
-        final String templateName = "templ";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
-
-        final String templatePath = "/template/path";
-        final String localPath = "/mnt/local";
-        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-        final StorageLayer storage = Mockito.mock(StorageLayer.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
-        final Processor qcow2Processor = Mockito.mock(Processor.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
-        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(secondaryPool.getLocalPath()).thenReturn(localPath);
-        when(libvirtComputingResource.getStorage()).thenReturn(storage);
-
-        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
-        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
-
-        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
-        final String templateInstallFolder = "template/tmpl/" + templateFolder;
-        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
-
-        try {
-            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
-            when(qcow2Processor.process(tmplPath, null, tmplName)).thenThrow(InternalErrorException.class);
-        } catch (final ConfigurationException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCreatePrivateTemplateFromSnapshotCommandIOException() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
-        final String backedUpSnapshotName = "snap";
-        final String origTemplateInstallPath = "/install/path/";
-        final Long newTemplateId = 2l;
-        final String templateName = "templ";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
-
-        final String templatePath = "/template/path";
-        final String localPath = "/mnt/local";
-        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class);
-        final StorageLayer storage = Mockito.mock(StorageLayer.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final TemplateLocation location = Mockito.mock(TemplateLocation.class);
-        final Processor qcow2Processor = Mockito.mock(Processor.class);
-        final FormatInfo info = Mockito.mock(FormatInfo.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
-        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot);
-        when(secondaryPool.getLocalPath()).thenReturn(localPath);
-        when(libvirtComputingResource.getStorage()).thenReturn(storage);
-
-        when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath);
-        when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1);
-
-        final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId();
-        final String templateInstallFolder = "template/tmpl/" + templateFolder;
-        final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder;
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
-
-        try {
-            when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor);
-            when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info);
-
-            when(location.create(1, true, tmplName)).thenThrow(IOException.class);
-
-        } catch (final ConfigurationException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final IOException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCreatePrivateTemplateFromSnapshotCommandCloudRuntime() {
-        final StoragePool pool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long dcId = 1l;
-        final Long accountId = 1l;
-        final Long volumeId = 1l;
-        final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/";
-        final String backedUpSnapshotName = "snap";
-        final String origTemplateInstallPath = "/install/path/";
-        final Long newTemplateId = 2l;
-        final String templateName = "templ";
-        final int wait = 0;
-
-        final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-
-        String snapshotPath = command.getSnapshotUuid();
-        final int index = snapshotPath.lastIndexOf("/");
-        snapshotPath = snapshotPath.substring(0, index);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(tmplName);
-
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool);
-        when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool);
-        when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath);
-        verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl());
-    }
-
-    @Test
-    public void testCopyVolumeCommand() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long volumeId = 1l;
-        final int wait = 0;
-        final String volumePath = "/vol/path";
-        final boolean toSecondaryStorage = true;
-        final boolean executeInSequence = false;
-
-        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
-
-        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final StorageFilerTO pool = command.getPool();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
-        when(primary.getPhysicalDisk(command.getVolumePath())).thenReturn(disk);
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL)).thenReturn(secondary);
-        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
-        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
-        when(secondary.createFolder(volumeDestPath)).thenReturn(true);
-        when(storagePoolMgr.deleteStoragePool(secondary.getType(), secondary.getUuid())).thenReturn(true);
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
-        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, secondary, 0)).thenReturn(disk);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testCopyVolumeCommandToSecFalse() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long volumeId = 1l;
-        final int wait = 0;
-        final String volumePath = "/vol/path";
-        final boolean toSecondaryStorage = false;
-        final boolean executeInSequence = false;
-
-        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
-
-        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final StorageFilerTO pool = command.getPool();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
-        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
-        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
-        when(primary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenReturn(disk);
-        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, primary, 0)).thenReturn(disk);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testCopyVolumeCommandCloudRuntime() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long volumeId = 1l;
-        final int wait = 0;
-        final String volumePath = "/vol/path";
-        final boolean toSecondaryStorage = false;
-        final boolean executeInSequence = false;
-
-        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
-
-        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final StorageFilerTO pool = command.getPool();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
-        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
-        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
-        when(secondary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testCopyVolumeCommandCloudRuntime2() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long volumeId = 1l;
-        final int wait = 0;
-        final String volumePath = "/vol/path";
-        final boolean toSecondaryStorage = false;
-        final boolean executeInSequence = false;
-
-        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
-
-        final StorageFilerTO pool = command.getPool();
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenThrow(new CloudRuntimeException("error"));
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testCopyVolumeCommandPrimaryNotFound() {
-        final StoragePool storagePool = Mockito.mock(StoragePool.class);
-        final String secondaryStoragePoolURL = "nfs:/127.0.0.1/storage/secondary";
-        final Long volumeId = 1l;
-        final int wait = 0;
-        final String volumePath = "/vol/path";
-        final boolean toSecondaryStorage = false;
-        final boolean executeInSequence = false;
-
-        final CopyVolumeCommand command = new CopyVolumeCommand(volumeId, volumePath, storagePool, secondaryStoragePoolURL, toSecondaryStorage, wait, executeInSequence );
-
-        final String destVolumeName = "ce97bbc1-34fe-4259-9202-74bbce2562ab";
-        final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator;
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool secondary = Mockito.mock(KVMStoragePool.class);
-        final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
-
-        final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final StorageFilerTO pool = command.getPool();
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenThrow(new CloudRuntimeException("not found"));
-
-        when(storagePoolMgr.createStoragePool(pool.getUuid(), pool.getHost(), pool.getPort(), pool.getPath(),
-                pool.getUserInfo(), pool.getType())).thenReturn(primary);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.generateUUIDName()).thenReturn(destVolumeName);
-        when(secondary.getType()).thenReturn(StoragePoolType.ManagedNFS);
-        when(secondary.getUuid()).thenReturn("60d979d8-d132-4181-8eca-8dfde50d7df6");
-        when(storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolURL + volumeDestPath)).thenReturn(secondary);
-        when(primary.getPhysicalDisk(command.getVolumePath() + ".qcow2")).thenReturn(disk);
-        when(storagePoolMgr.copyPhysicalDisk(disk, destVolumeName, primary, 0)).thenReturn(disk);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testPvlanSetupCommandDhcpAdd() {
-        final String op = "add";
-        final URI uri = URI.create("http://localhost");
-        final String networkTag = "/105";
-        final String dhcpName = "dhcp";
-        final String dhcpMac = "00:00:00:00";
-        final String dhcpIp = "127.0.0.1";
-
-        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-
-        final String guestBridgeName = "br0";
-        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
-
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-        final String ovsPvlanDhcpHostPath = "/pvlan";
-        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        final List<InterfaceDef> ifaces = new ArrayList<InterfaceDef>();
-        final InterfaceDef nic = Mockito.mock(InterfaceDef.class);
-        ifaces.add(nic);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenReturn(conn);
-            when(libvirtComputingResource.getInterfaces(conn, dhcpName)).thenReturn(ifaces);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testPvlanSetupCommandVm() {
-        final String op = "add";
-        final URI uri = URI.create("http://localhost");
-        final String networkTag = "/105";
-        final String vmMac = "00:00:00:00";
-
-        final PvlanSetupCommand command = PvlanSetupCommand.createVmSetup(op, uri, networkTag, vmMac);
-
-        final String guestBridgeName = "br0";
-        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-
-        final String ovsPvlanVmPath = "/pvlan";
-        when(libvirtComputingResource.getOvsPvlanVmPath()).thenReturn(ovsPvlanVmPath);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testPvlanSetupCommandDhcpException() {
-        final String op = "add";
-        final URI uri = URI.create("http://localhost");
-        final String networkTag = "/105";
-        final String dhcpName = "dhcp";
-        final String dhcpMac = "00:00:00:00";
-        final String dhcpIp = "127.0.0.1";
-
-        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String guestBridgeName = "br0";
-        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
-
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-        final String ovsPvlanDhcpHostPath = "/pvlan";
-        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testPvlanSetupCommandDhcpDelete() {
-        final String op = "delete";
-        final URI uri = URI.create("http://localhost");
-        final String networkTag = "/105";
-        final String dhcpName = "dhcp";
-        final String dhcpMac = "00:00:00:00";
-        final String dhcpIp = "127.0.0.1";
-
-        final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp);
-
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        final String guestBridgeName = "br0";
-        when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName);
-
-        when(libvirtComputingResource.getTimeout()).thenReturn(Duration.ZERO);
-        final String ovsPvlanDhcpHostPath = "/pvlan";
-        when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath);
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testResizeVolumeCommand() {
-        final String path = "nfs:/127.0.0.1/storage/secondary";
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final Long currentSize = 100l;
-        final Long newSize = 200l;
-        final boolean shrinkOk = true;
-        final String vmInstance = "Test";
-
-        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final StorageVol v = Mockito.mock(StorageVol.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
-        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
-        when(vol.getPath()).thenReturn(path);
-        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE");
-        when(storagePool.getType()).thenReturn(StoragePoolType.RBD);
-        when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn);
-            when(conn.storageVolLookupByPath(path)).thenReturn(v);
-
-            when(conn.getLibVirVersion()).thenReturn(10010l);
-
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnection();
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testResizeVolumeCommandSameSize() {
-        final String path = "nfs:/127.0.0.1/storage/secondary";
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final Long currentSize = 100l;
-        final Long newSize = 100l;
-        final boolean shrinkOk = false;
-        final String vmInstance = "Test";
-
-        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testResizeVolumeCommandShrink() {
-        final String path = "nfs:/127.0.0.1/storage/secondary";
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final Long currentSize = 100l;
-        final Long newSize = 200l;
-        final boolean shrinkOk = true;
-        final String vmInstance = "Test";
-
-        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
-        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
-        when(vol.getPath()).thenReturn(path);
-        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("QCOW2");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testResizeVolumeCommandException() {
-        final String path = "nfs:/127.0.0.1/storage/secondary";
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final Long currentSize = 100l;
-        final Long newSize = 200l;
-        final boolean shrinkOk = false;
-        final String vmInstance = "Test";
-
-        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
-        final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
-        when(storagePool.getPhysicalDisk(path)).thenReturn(vol);
-        when(vol.getPath()).thenReturn(path);
-        when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE");
-        when(storagePool.getType()).thenReturn(StoragePoolType.RBD);
-        when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnection();
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testResizeVolumeCommandException2() {
-        final String path = "nfs:/127.0.0.1/storage/secondary";
-        final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
-        final Long currentSize = 100l;
-        final Long newSize = 200l;
-        final boolean shrinkOk = false;
-        final String vmInstance = "Test";
-
-        final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class);
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool);
-        when(storagePool.getPhysicalDisk(path)).thenThrow(CloudRuntimeException.class);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-    }
-
-    @Test
-    public void testNetworkElementCommand() {
-        final CheckRouterCommand command = new CheckRouterCommand();
-
-        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
-        when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
-
-        when(virtRouterResource.executeRequest(command)).thenReturn(new CheckRouterAnswer(command, "mock_resource"));
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testStorageSubSystemCommand() {
-        final DiskTO disk = Mockito.mock(DiskTO.class);
-        final String vmName = "Test";
-        final AttachCommand command = new AttachCommand(disk, vmName);
-
-        final StorageSubsystemCommandHandler handler = Mockito.mock(StorageSubsystemCommandHandler.class);
-        when(libvirtComputingResource.getStorageHandler()).thenReturn(handler);
-
-        when(handler.handleStorageCommands(command)).thenReturn(new AttachAnswer(disk));
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testStartCommandFailedConnect() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-
-        final String vmName = "Test";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(false);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testStartCommandLibvirtException() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-
-        final String vmName = "Test";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenThrow(LibvirtException.class);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStartCommandInternalError() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-
-        final String vmName = "Test";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            doThrow(InternalErrorException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStartCommandUriException() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-
-        final String vmName = "Test";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            doThrow(URISyntaxException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStartCommand() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-        final int[] vms = new int[0];
-
-        final String vmName = "Test";
-        final String controlIp = "127.0.0.1";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            when(conn.listDomains()).thenReturn(vms);
-            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
-        try {
-            doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef);
-
-            when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS");
-
-            when(vmSpec.getBootArgs()).thenReturn("ls -lart");
-            when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true);
-
-            when(nic.getIp()).thenReturn(controlIp);
-            when(nic.getType()).thenReturn(TrafficType.Control);
-            when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
-            when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true);
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStartCommandIsolationEc2() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-        final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-        final int[] vms = new int[0];
-
-        final String vmName = "Test";
-        final String controlIp = "127.0.0.1";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            when(conn.listDomains()).thenReturn(vms);
-            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
-        try {
-            doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef);
-
-            when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS");
-
-            when(nic.isSecurityGroupEnabled()).thenReturn(true);
-            when(nic.getIsolationUri()).thenReturn(new URI("ec2://test"));
-
-
-            when(vmSpec.getBootArgs()).thenReturn("ls -lart");
-            when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true);
-
-            when(nic.getIp()).thenReturn(controlIp);
-            when(nic.getType()).thenReturn(TrafficType.Control);
-            when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource);
-            when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true);
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-
-        verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        try {
-            verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType());
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    @Test
-    public void testStartCommandHostMemory() {
-        final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
-        final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
-        final boolean executeInSequence = false;
-
-        final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
-
-        final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Connect conn = Mockito.mock(Connect.class);
-        final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
-
-        final NicTO nic = Mockito.mock(NicTO.class);
-        final NicTO[] nics = new NicTO[]{nic};
-        int vmId = 1;
-        final int[] vms = new int[]{vmId};
-        final Domain dm = Mockito.mock(Domain.class);
-
-        final String vmName = "Test";
-
-        when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
-        when(vmSpec.getNics()).thenReturn(nics);
-        when(vmSpec.getType()).thenReturn(VirtualMachine.Type.User);
-        when(vmSpec.getName()).thenReturn(vmName);
-        when(vmSpec.getMaxRam()).thenReturn(512L);
-        when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        try {
-            when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
-            when(conn.listDomains()).thenReturn(vms);
-            when(conn.domainLookupByID(vmId)).thenReturn(dm);
-            when(dm.getMaxMemory()).thenReturn(1024L);
-            when(dm.getName()).thenReturn(vmName);
-            when(libvirtComputingResource.getTotalMemory()).thenReturn(2048*1024L);
-            doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
-        } catch (final LibvirtException e) {
-            fail(e.getMessage());
-        } catch (final InternalErrorException e) {
-            fail(e.getMessage());
-        } catch (final URISyntaxException e) {
-            fail(e.getMessage());
-        }
-
-        when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertTrue(answer.getResult());
-    }
-
-
-    @Test
-    public void testUpdateHostPasswordCommand() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Script script = Mockito.mock(Script.class);
-
-        final String hostIp = "127.0.0.1";
-        final String username = "root";
-        final String newPassword = "password";
-
-        final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
-        when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
-
-        when(script.execute()).thenReturn(null);
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertTrue(answer.getResult());
-    }
-
-    @Test
-    public void testUpdateHostPasswordCommandFail() {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final Script script = Mockito.mock(Script.class);
-
-        final String hostIp = "127.0.0.1";
-        final String username = "root";
-        final String newPassword = "password";
-
-        final UpdateHostPasswordCommand command = new UpdateHostPasswordCommand(username, newPassword, hostIp);
-
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtComputingResource.getUpdateHostPasswdPath()).thenReturn("/tmp");
-        when(libvirtUtilitiesHelper.buildScript(libvirtComputingResource.getUpdateHostPasswdPath())).thenReturn(script);
-
-        when(script.execute()).thenReturn("#FAIL");
-
-        final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
-        assertNotNull(wrapper);
-
-        final Answer answer = wrapper.execute(command, libvirtComputingResource);
-
-        assertFalse(answer.getResult());
-    }
-
-    @Test
-    public void testIsInterface () {
-        final LibvirtComputingResource lvcr = new LibvirtComputingResource();
-        assertFalse(lvcr.isInterface("bla"));
-        assertTrue(lvcr.isInterface("p99p00"));
-        for  (final String ifNamePattern : lvcr._ifNamePatterns) {
-            // excluding regexps as "\\\\d+" won't replace with String.replaceAll(String,String);
-            if (!ifNamePattern.contains("\\")) {
-                final String ifName = ifNamePattern.replaceFirst("\\^", "") + "0";
-                assertTrue("The pattern '" + ifNamePattern + "' is expected to be valid for interface " + ifName,lvcr.isInterface(ifName));
-            }
-        }
-    }
-
-    @Test
-    public void testMemoryFreeInKBsDomainReturningOfSomeMemoryStatistics() throws LibvirtException {
-        LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
-
-        MemoryStatistic[] mem = createMemoryStatisticFreeMemory100();
-        Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(mem);
-        long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock);
-
-        Assert.assertEquals(100, memoryFreeInKBs);
-    }
-
-    @Test
-    public void testMemoryFreeInKBsDomainReturningNoMemoryStatistics() throws LibvirtException {
-        LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
-
-        Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(null);
-        long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock);
-
-        Assert.assertEquals(0, memoryFreeInKBs);
-    }
-
-    private MemoryStatistic[] createMemoryStatisticFreeMemory100() {
-        virDomainMemoryStats stat = new virDomainMemoryStats();
-        stat.val = 100;
-
-        MemoryStatistic[] mem = new MemoryStatistic[2];
-        mem[0] = new MemoryStatistic(stat);
-        return mem;
-    }
-
-    private Domain getDomainConfiguredToReturnMemoryStatistic(MemoryStatistic[] mem) throws LibvirtException {
-        Domain domainMock = Mockito.mock(Domain.class);
-        when(domainMock.memoryStats(2)).thenReturn(mem);
-        return domainMock;
-    }
-
-    @Test
-    public void testSetQuotaAndPeriod() {
-        double pct = 0.33d;
-        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(true);
-        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
-        CpuTuneDef cpuTuneDef = new CpuTuneDef();
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
-        Assert.assertEquals((int) (CpuTuneDef.DEFAULT_PERIOD * pct), cpuTuneDef.getQuota());
-        Assert.assertEquals(CpuTuneDef.DEFAULT_PERIOD, cpuTuneDef.getPeriod());
-    }
-
-    @Test
-    public void testSetQuotaAndPeriodNoCpuLimitUse() {
-        double pct = 0.33d;
-        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(false);
-        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
-        CpuTuneDef cpuTuneDef = new CpuTuneDef();
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
-        Assert.assertEquals(0, cpuTuneDef.getQuota());
-        Assert.assertEquals(0, cpuTuneDef.getPeriod());
-    }
-
-    @Test
-    public void testSetQuotaAndPeriodMinQuota() {
-        double pct = 0.01d;
-        Mockito.when(vmTO.getLimitCpuUse()).thenReturn(true);
-        Mockito.when(vmTO.getCpuQuotaPercentage()).thenReturn(pct);
-        CpuTuneDef cpuTuneDef = new CpuTuneDef();
-        final LibvirtComputingResource lcr = new LibvirtComputingResource();
-        lcr.setQuotaAndPeriod(vmTO, cpuTuneDef);
-        Assert.assertEquals(CpuTuneDef.MIN_QUOTA, cpuTuneDef.getQuota());
-        Assert.assertEquals((int) (CpuTuneDef.MIN_QUOTA / pct), cpuTuneDef.getPeriod());
-    }
-
-    @Test
-    public void testUnknownCommand() {
-        libvirtComputingResource = new LibvirtComputingResource();
-        Command cmd = new Command() {
-            @Override public boolean executeInSequence() {
-                return false;
-            }
-        };
-        Answer ans = libvirtComputingResource.executeRequest(cmd);
-        assertTrue(ans instanceof UnsupportedAnswer);
-    }
-
-    @Test
-    public void testKnownCommand() {
-        libvirtComputingResource = new LibvirtComputingResource();
-        Command cmd = new PingTestCommand() {
-            @Override public boolean executeInSequence() {
-                throw new NullPointerException("test succeeded");
-            }
-        };
-        Answer ans = libvirtComputingResource.executeRequest(cmd);
-        assertFalse(ans instanceof UnsupportedAnswer);
-        assertTrue(ans instanceof Answer);
-    }
-}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
deleted file mode 100644
index 6a06c11..0000000
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.cloud.hypervisor.kvm.resource;
-
-import java.io.File;
-
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ChannelDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
-import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SCSIDef;
-import com.cloud.utils.Pair;
-
-import junit.framework.TestCase;
-
-public class LibvirtVMDefTest extends TestCase {
-
-    public void testInterfaceEtehrnet() {
-        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
-        ifDef.defEthernet("targetDeviceName", "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
-
-        String expected =
-            "<interface type='ethernet'>\n"
-                    + "<target dev='targetDeviceName'/>\n"
-                    + "<mac address='00:11:22:aa:bb:dd'/>\n"
-                    + "<model type='virtio'/>\n"
-                    + "<link state='up'/>\n"
-                    + "</interface>\n";
-
-        assertEquals(expected, ifDef.toString());
-    }
-
-    public void testInterfaceDirectNet() {
-        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
-        ifDef.defDirectNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO, "private");
-
-        String expected =
-            "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.DIRECT + "'>\n"
-                    + "<source dev='targetDeviceName' mode='private'/>\n"
-                    + "<mac address='00:11:22:aa:bb:dd'/>\n"
-                    + "<model type='virtio'/>\n"
-                    + "<link state='up'/>\n"
-                    + "</interface>\n";
-
-        assertEquals(expected, ifDef.toString());
-    }
-
-    public void testInterfaceBridgeSlot() {
-        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
-        ifDef.defBridgeNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.NicModel.VIRTIO);
-        ifDef.setSlot(16);
-
-        String expected =
-                "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
-                        + "<source bridge='targetDeviceName'/>\n"
-                        + "<mac address='00:11:22:aa:bb:dd'/>\n"
-                        + "<model type='virtio'/>\n"
-                        + "<link state='up'/>\n"
-                        + "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
-                        + "</interface>\n";
-
-        assertEquals(expected, ifDef.toString());
-
-        ifDef.setLinkStateUp(false);
-        ifDef.setDevName("vnet11");
-
-        expected =
-                "<interface type='" + LibvirtVMDef.InterfaceDef.GuestNetType.BRIDGE + "'>\n"
-                        + "<source bridge='targetDeviceName'/>\n"
-                        + "<target dev='vnet11'/>\n"
-                        + "<mac address='00:11:22:aa:bb:dd'/>\n"
-                        + "<model type='virtio'/>\n"
-                        + "<link state='down'/>\n"
-                        + "<address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/>\n"
-                        + "</interface>\n";
-
-        assertEquals(expected, ifDef.toString());
-    }
-
-    public void testCpuModeDef() {
-        LibvirtVMDef.CpuModeDef cpuModeDef = new LibvirtVMDef.CpuModeDef();
-        cpuModeDef.setMode("custom");
-        cpuModeDef.setModel("Nehalem");
-
-        String expected1 = "<cpu mode='custom' match='exact'><model fallback='allow'>Nehalem</model></cpu>";
-
-        assertEquals(expected1, cpuModeDef.toString());
-
-        cpuModeDef.setMode("host-model");
-        String expected2 = "<cpu mode='host-model'><model fallback='allow'></model></cpu>";
-
-        assertEquals(expected2, cpuModeDef.toString());
-
-        cpuModeDef.setMode("host-passthrough");
-        String expected3 = "<cpu mode='host-passthrough'></cpu>";
-        assertEquals(expected3, cpuModeDef.toString());
-
-    }
-
-    public void testDiskDef() {
-        String filePath = "/var/lib/libvirt/images/disk.qcow2";
-        String diskLabel = "vda";
-
-        DiskDef disk = new DiskDef();
-        DiskDef.DiskBus bus = DiskDef.DiskBus.VIRTIO;
-        DiskDef.DiskFmtType type = DiskDef.DiskFmtType.QCOW2;
-        DiskDef.DiskCacheMode cacheMode = DiskDef.DiskCacheMode.WRITEBACK;
-
-        disk.defFileBasedDisk(filePath, diskLabel, bus, type);
-        disk.setCacheMode(cacheMode);
-
-        assertEquals(filePath, disk.getDiskPath());
-        assertEquals(diskLabel, disk.getDiskLabel());
-        assertEquals(bus, disk.getBusType());
-        assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType());
-
-        String xmlDef = disk.toString();
-        String expectedXml = "<disk  device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
-                             "<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n</disk>\n";
-
-        assertEquals(xmlDef, expectedXml);
-    }
-
-    public void testHypervEnlightDef() {
-        LibvirtVMDef.FeaturesDef featuresDef = new LibvirtVMDef.FeaturesDef();
-        LibvirtVMDef.HyperVEnlightenmentFeatureDef hyperVEnlightenmentFeatureDef = new LibvirtVMDef.HyperVEnlightenmentFeatureDef();
-        hyperVEnlightenmentFeatureDef.setFeature("relaxed", true);
-        hyperVEnlightenmentFeatureDef.setFeature("vapic", true);
-        hyperVEnlightenmentFeatureDef.setFeature("spinlocks", true);
-        hyperVEnlightenmentFeatureDef.setRetries(8096);
-        featuresDef.addHyperVFeature(hyperVEnlightenmentFeatureDef);
-        String defs = featuresDef.toString();
-        assertTrue(defs.contains("relaxed"));
-        assertTrue(defs.contains("vapic"));
-        assertTrue(defs.contains("spinlocks"));
-
-        featuresDef = new LibvirtVMDef.FeaturesDef();
-        featuresDef.addFeatures("pae");
-        defs = featuresDef.toString();
-        assertFalse(defs.contains("relaxed"));
-        assertFalse(defs.contains("vapic"));
-        assertFalse(defs.contains("spinlocks"));
-        assertTrue("Windows Server 2008 R2".contains("Windows Server 2008"));
-
-        Pair<Integer,Integer> hostOsVersion = new Pair<Integer,Integer>(6,5);
-        assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7));
-        hostOsVersion = new Pair<Integer,Integer>(7,1);
-        assertTrue((hostOsVersion.first() == 6 && hostOsVersion.second() >= 5) || (hostOsVersion.first() >= 7));
-    }
-
-    public void testRngDef() {
-        LibvirtVMDef.RngDef.RngBackendModel backendModel = LibvirtVMDef.RngDef.RngBackendModel.RANDOM;
-        String path = "/dev/random";
-        int period = 2000;
-        int bytes = 2048;
-
-        LibvirtVMDef.RngDef def = new LibvirtVMDef.RngDef(path, backendModel, bytes, period);
-        assertEquals(def.getPath(), path);
-        assertEquals(def.getRngBackendModel(), backendModel);
-        assertEquals(def.getRngModel(), LibvirtVMDef.RngDef.RngModel.VIRTIO);
-        assertEquals(def.getRngRateBytes(), bytes);
-        assertEquals(def.getRngRatePeriod(), period);
-    }
-
-    public void testChannelDef() {
-        ChannelDef.ChannelType type = ChannelDef.ChannelType.UNIX;
-        ChannelDef.ChannelState state = ChannelDef.ChannelState.CONNECTED;
-        String name = "v-136-VM.org.qemu.guest_agent.0";
-        File path = new File("/var/lib/libvirt/qemu/" + name);
-
-        ChannelDef channelDef = new ChannelDef(name, type, state, path);
-
-        assertEquals(state, channelDef.getChannelState());
-        assertEquals(type, channelDef.getChannelType());
-        assertEquals(name, channelDef.getName());
-        assertEquals(path, channelDef.getPath());
-    }
-
-    public void testWatchDogDef() {
-        LibvirtVMDef.WatchDogDef.WatchDogModel model = LibvirtVMDef.WatchDogDef.WatchDogModel.I6300ESB;
-        LibvirtVMDef.WatchDogDef.WatchDogAction action = LibvirtVMDef.WatchDogDef.WatchDogAction.RESET;
-
-        LibvirtVMDef.WatchDogDef def = new LibvirtVMDef.WatchDogDef(action, model);
-        assertEquals(def.getModel(), model);
-        assertEquals(def.getAction(), action);
-    }
-
-    public void testSCSIDef() {
-        SCSIDef def = new SCSIDef();
-        String str = def.toString();
-        String expected = "<controller type='scsi' index='0' model='virtio-scsi'>\n" +
-                "<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>\n" +
-                "</controller>\n";
-        assertEquals(str, expected);
-    }
-
-    public void testMetadataDef() {
-        LibvirtVMDef.MetadataDef metadataDef = new LibvirtVMDef.MetadataDef();
-
-        metadataDef.getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension("mac1", "ip1");
-        metadataDef.getMetadataNode(LibvirtVMDef.NuageExtensionDef.class).addNuageExtension("mac2", "ip2");
-
-        String xmlDef = metadataDef.toString();
-        String expectedXml = "<metadata>\n" +
-                "<nuage-extension xmlns='nuagenetworks.net/nuage/cna'>\n" +
-                "  <interface mac='mac2' vsp-vr-ip='ip2'></interface>\n" +
-                "  <interface mac='mac1' vsp-vr-ip='ip1'></interface>\n" +
-                "</nuage-extension>\n" +
-                "</metadata>\n";
-
-        assertEquals(xmlDef, expectedXml);
-    }
-
-}
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
deleted file mode 100644
index da71e40..0000000
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.hypervisor.kvm.resource.wrapper;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class LibvirtMigrateCommandWrapperTest {
-    String fullfile =
-"<domain type='kvm' id='4'>\n" +
-"  <name>i-6-6-VM</name>\n" +
-"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
-"  <description>Other PV (64-bit)</description>\n" +
-"  <memory unit='KiB'>262144</memory>\n" +
-"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
-"  <vcpu placement='static'>1</vcpu>\n" +
-"  <cputune>\n" +
-"    <shares>100</shares>\n" +
-"  </cputune>\n" +
-"  <resource>\n" +
-"    <partition>/machine</partition>\n" +
-"  </resource>\n" +
-"  <sysinfo type='smbios'>\n" +
-"    <system>\n" +
-"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
-"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
-"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
-"    </system>\n" +
-"  </sysinfo>\n" +
-"  <os>\n" +
-"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
-"    <boot dev='cdrom'/>\n" +
-"    <boot dev='hd'/>\n" +
-"    <smbios mode='sysinfo'/>\n" +
-"  </os>\n" +
-"  <features>\n" +
-"    <acpi/>\n" +
-"    <apic/>\n" +
-"    <pae/>\n" +
-"  </features>\n" +
-"  <clock offset='utc'>\n" +
-"    <timer name='kvmclock'/>\n" +
-"  </clock>\n" +
-"  <on_poweroff>destroy</on_poweroff>\n" +
-"  <on_reboot>restart</on_reboot>\n" +
-"  <on_crash>destroy</on_crash>\n" +
-"  <devices>\n" +
-"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
-"    <disk type='file' device='disk'>\n" +
-"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
-"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
-"      <backingStore type='file' index='1'>\n" +
-"        <format type='raw'/>\n" +
-"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
-"        <backingStore/>\n" +
-"      </backingStore>\n" +
-"      <target dev='vda' bus='virtio'/>\n" +
-"      <serial>4650a2f7fce548e2beaa</serial>\n" +
-"      <alias name='virtio-disk0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
-"    </disk>\n" +
-"    <disk type='file' device='cdrom'>\n" +
-"      <driver name='qemu' type='raw' cache='none'/>\n" +
-"      <backingStore/>\n" +
-"      <target dev='hdc' bus='ide'/>\n" +
-"      <readonly/>\n" +
-"      <alias name='ide0-1-0'/>\n" +
-"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
-"    </disk>\n" +
-"    <controller type='usb' index='0'>\n" +
-"      <alias name='usb'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
-"    </controller>\n" +
-"    <controller type='pci' index='0' model='pci-root'>\n" +
-"      <alias name='pci.0'/>\n" +
-"    </controller>\n" +
-"    <controller type='ide' index='0'>\n" +
-"      <alias name='ide'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
-"    </controller>\n" +
-"    <interface type='bridge'>\n" +
-"      <mac address='06:fe:b4:00:00:06'/>\n" +
-"      <source bridge='breth0-50'/>\n" +
-"      <bandwidth>\n" +
-"        <inbound average='25600' peak='25600'/>\n" +
-"        <outbound average='25600' peak='25600'/>\n" +
-"      </bandwidth>\n" +
-"      <target dev='vnet4'/>\n" +
-"      <model type='virtio'/>\n" +
-"      <alias name='net0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
-"    </interface>\n" +
-"    <serial type='pty'>\n" +
-"      <source path='/dev/pts/2'/>\n" +
-"      <target port='0'/>\n" +
-"      <alias name='serial0'/>\n" +
-"    </serial>\n" +
-"    <console type='pty' tty='/dev/pts/2'>\n" +
-"      <source path='/dev/pts/2'/>\n" +
-"      <target type='serial' port='0'/>\n" +
-"      <alias name='serial0'/>\n" +
-"    </console>\n" +
-"    <input type='tablet' bus='usb'>\n" +
-"      <alias name='input0'/>\n" +
-"    </input>\n" +
-"    <input type='mouse' bus='ps2'/>\n" +
-"    <input type='keyboard' bus='ps2'/>\n" +
-"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.22'>\n" +
-"      <listen type='address' address='192.168.22.22'/>\n" +
-"    </graphics>\n" +
-"    <video>\n" +
-"      <model type='cirrus' vram='16384' heads='1'/>\n" +
-"      <alias name='video0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
-"    </video>\n" +
-"    <memballoon model='none'>\n" +
-"      <alias name='balloon0'/>\n" +
-"    </memballoon>\n" +
-"  </devices>\n" +
-"</domain>";
-    String targetfile =
-"<domain type='kvm' id='4'>\n" +
-"  <name>i-6-6-VM</name>\n" +
-"  <uuid>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</uuid>\n" +
-"  <description>Other PV (64-bit)</description>\n" +
-"  <memory unit='KiB'>262144</memory>\n" +
-"  <currentMemory unit='KiB'>262144</currentMemory>\n" +
-"  <vcpu placement='static'>1</vcpu>\n" +
-"  <cputune>\n" +
-"    <shares>100</shares>\n" +
-"  </cputune>\n" +
-"  <resource>\n" +
-"    <partition>/machine</partition>\n" +
-"  </resource>\n" +
-"  <sysinfo type='smbios'>\n" +
-"    <system>\n" +
-"      <entry name='manufacturer'>Apache Software Foundation</entry>\n" +
-"      <entry name='product'>CloudStack KVM Hypervisor</entry>\n" +
-"      <entry name='uuid'>f197b32b-8da2-4a57-bb8a-d01bacc5cd33</entry>\n" +
-"    </system>\n" +
-"  </sysinfo>\n" +
-"  <os>\n" +
-"    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>\n" +
-"    <boot dev='cdrom'/>\n" +
-"    <boot dev='hd'/>\n" +
-"    <smbios mode='sysinfo'/>\n" +
-"  </os>\n" +
-"  <features>\n" +
-"    <acpi/>\n" +
-"    <apic/>\n" +
-"    <pae/>\n" +
-"  </features>\n" +
-"  <clock offset='utc'>\n" +
-"    <timer name='kvmclock'/>\n" +
-"  </clock>\n" +
-"  <on_poweroff>destroy</on_poweroff>\n" +
-"  <on_reboot>restart</on_reboot>\n" +
-"  <on_crash>destroy</on_crash>\n" +
-"  <devices>\n" +
-"    <emulator>/usr/libexec/qemu-kvm</emulator>\n" +
-"    <disk type='file' device='disk'>\n" +
-"      <driver name='qemu' type='qcow2' cache='none'/>\n" +
-"      <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6'/>\n" +
-"      <backingStore type='file' index='1'>\n" +
-"        <format type='raw'/>\n" +
-"        <source file='/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/bb4d4df4-c004-11e5-94ed-5254001daa61'/>\n" +
-"        <backingStore/>\n" +
-"      </backingStore>\n" +
-"      <target dev='vda' bus='virtio'/>\n" +
-"      <serial>4650a2f7fce548e2beaa</serial>\n" +
-"      <alias name='virtio-disk0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
-"    </disk>\n" +
-"    <disk type='file' device='cdrom'>\n" +
-"      <driver name='qemu' type='raw' cache='none'/>\n" +
-"      <backingStore/>\n" +
-"      <target dev='hdc' bus='ide'/>\n" +
-"      <readonly/>\n" +
-"      <alias name='ide0-1-0'/>\n" +
-"      <address type='drive' controller='0' bus='1' target='0' unit='0'/>\n" +
-"    </disk>\n" +
-"    <controller type='usb' index='0'>\n" +
-"      <alias name='usb'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>\n" +
-"    </controller>\n" +
-"    <controller type='pci' index='0' model='pci-root'>\n" +
-"      <alias name='pci.0'/>\n" +
-"    </controller>\n" +
-"    <controller type='ide' index='0'>\n" +
-"      <alias name='ide'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>\n" +
-"    </controller>\n" +
-"    <interface type='bridge'>\n" +
-"      <mac address='06:fe:b4:00:00:06'/>\n" +
-"      <source bridge='breth0-50'/>\n" +
-"      <bandwidth>\n" +
-"        <inbound average='25600' peak='25600'/>\n" +
-"        <outbound average='25600' peak='25600'/>\n" +
-"      </bandwidth>\n" +
-"      <target dev='vnet4'/>\n" +
-"      <model type='virtio'/>\n" +
-"      <alias name='net0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>\n" +
-"    </interface>\n" +
-"    <serial type='pty'>\n" +
-"      <source path='/dev/pts/2'/>\n" +
-"      <target port='0'/>\n" +
-"      <alias name='serial0'/>\n" +
-"    </serial>\n" +
-"    <console type='pty' tty='/dev/pts/2'>\n" +
-"      <source path='/dev/pts/2'/>\n" +
-"      <target type='serial' port='0'/>\n" +
-"      <alias name='serial0'/>\n" +
-"    </console>\n" +
-"    <input type='tablet' bus='usb'>\n" +
-"      <alias name='input0'/>\n" +
-"    </input>\n" +
-"    <input type='mouse' bus='ps2'/>\n" +
-"    <input type='keyboard' bus='ps2'/>\n" +
-"    <graphics type='vnc' port='5902' autoport='yes' listen='192.168.22.21'>\n" +
-"      <listen type='address' address='192.168.22.21'/>\n" +
-"    </graphics>\n" +
-"    <video>\n" +
-"      <model type='cirrus' vram='16384' heads='1'/>\n" +
-"      <alias name='video0'/>\n" +
-"      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>\n" +
-"    </video>\n" +
-"    <memballoon model='none'>\n" +
-"      <alias name='balloon0'/>\n" +
-"    </memballoon>\n" +
-"  </devices>\n" +
-"</domain>";
-
-    @Test
-    public void testReplaceIpForVNCInDescFile() {
-        final String targetIp = "192.168.22.21";
-        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
-        final String result = lw.replaceIpForVNCInDescFile(fullfile, targetIp);
-        assertTrue("transformation does not live up to expectation:\n" + result, targetfile.equals(result));
-    }
-
-    @Test
-    public void testReplaceIpForVNCInDesc() {
-        final String xmlDesc =
-                "<domain type='kvm' id='3'>" +
-                "  <devices>" +
-                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.1'>" +
-                "      <listen type='address' address='10.10.10.1'/>" +
-                "    </graphics>" +
-                "  </devices>" +
-                "</domain>";
-        final String expectedXmlDesc =
-                "<domain type='kvm' id='3'>" +
-                "  <devices>" +
-                "    <graphics type='vnc' port='5900' autoport='yes' listen='10.10.10.10'>" +
-                "      <listen type='address' address='10.10.10.10'/>" +
-                "    </graphics>" +
-                "  </devices>" +
-                "</domain>";
-        final String targetIp = "10.10.10.10";
-        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
-        final String result = lw.replaceIpForVNCInDescFile(xmlDesc, targetIp);
-        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
-    }
-
-    @Test
-    public void testReplaceFqdnForVNCInDesc() {
-        final String xmlDesc =
-                "<domain type='kvm' id='3'>" +
-                "  <devices>" +
-                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.local'>" +
-                "      <listen type='address' address='localhost.local'/>" +
-                "    </graphics>" +
-                "  </devices>" +
-                "</domain>";
-        final String expectedXmlDesc =
-                "<domain type='kvm' id='3'>" +
-                "  <devices>" +
-                "    <graphics type='vnc' port='5900' autoport='yes' listen='localhost.localdomain'>" +
-                "      <listen type='address' address='localhost.localdomain'/>" +
-                "    </graphics>" +
-                "  </devices>" +
-                "</domain>";
-        final String targetIp = "localhost.localdomain";
-        final LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
-        final String result = lw.replaceIpForVNCInDescFile(xmlDesc, targetIp);
-        assertTrue("transformation does not live up to expectation:\n" + result, expectedXmlDesc.equals(result));
-    }
-
-    @Test
-    public void testMigrationUri() {
-        final String ip = "10.1.1.1";
-        LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
-        LibvirtComputingResource lcr = new LibvirtComputingResource();
-        if (lcr.isHostSecured()) {
-            assertEquals(lw.createMigrationURI(ip, lcr), String.format("qemu+tls://%s/system", ip));
-        } else {
-            assertEquals(lw.createMigrationURI(ip, lcr), String.format("qemu+tcp://%s/system", ip));
-        }
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    public void testMigrationUriException() {
-        LibvirtMigrateCommandWrapper lw = new LibvirtMigrateCommandWrapper();
-        lw.createMigrationURI(null, new LibvirtComputingResource());
-    }
-}
diff --git a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java b/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
deleted file mode 100644
index 5e77606..0000000
--- a/plugins/hypervisors/kvm/test/org/apache/cloudstack/utils/linux/MemStatTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// 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.utils.linux;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.Scanner;
-
-public class MemStatTest {
-    @Test
-    public void getMemInfoParseTest() {
-        String memInfo = "MemTotal:        5830236 kB\n" +
-                         "MemFree:          156752 kB\n" +
-                         "Buffers:          326836 kB\n" +
-                         "Cached:          2606764 kB\n" +
-                         "SwapCached:            0 kB\n" +
-                         "Active:          4260808 kB\n" +
-                         "Inactive:         949392 kB\n";
-
-        MemStat memStat = null;
-        try {
-            memStat = new MemStat();
-        } catch (RuntimeException ex) {
-            // If test isn't run on linux we'll fail creation of linux-specific MemStat class due
-            // to dependency on /proc/meminfo if we don't catch here.
-            // We are really only interested in testing the parsing algorithm and getters.
-            if (memStat == null) {
-                throw ex;
-            }
-        }
-        Scanner scanner = new Scanner(memInfo);
-        memStat.parseFromScanner(scanner);
-
-        Assert.assertEquals(memStat.getTotal(), Double.valueOf(5830236));
-        Assert.assertEquals(memStat.getAvailable(), Double.valueOf(2763516));
-        Assert.assertEquals(memStat.getFree(), Double.valueOf(156752));
-        Assert.assertEquals(memStat.getCache(), Double.valueOf(2606764));
-    }
-}
diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml
index b73e473..65c228d 100644
--- a/plugins/hypervisors/ovm/pom.xml
+++ b/plugins/hypervisors/ovm/pom.xml
@@ -1,36 +1,37 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-hypervisor-ovm</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor OracleVM</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>net.java.dev.vcc.thirdparty</groupId>
-      <artifactId>xen-api</artifactId>
-      <version>${cs.xapi.version}</version>
-    </dependency>    
-  </dependencies>  
+<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-hypervisor-ovm</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor OracleVM</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>net.java.dev.vcc.thirdparty</groupId>
+            <artifactId>xen-api</artifactId>
+            <version>${cs.xapi.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmFencer.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmFencer.java
deleted file mode 100644
index e671a36..0000000
--- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmFencer.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.ovm.hypervisor;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.FenceAnswer;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.ha.FenceBuilder;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.VirtualMachine;
-
-public class OvmFencer extends AdapterBase implements FenceBuilder {
-    private static final Logger s_logger = Logger.getLogger(OvmFencer.class);
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public OvmFencer() {
-        super();
-    }
-
-    @Override
-    public Boolean fenceOff(VirtualMachine vm, Host host) {
-        if (host.getHypervisorType() != HypervisorType.Ovm) {
-            s_logger.debug("Don't know how to fence non Ovm hosts " + host.getHypervisorType());
-            return null;
-        }
-
-        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
-        FenceCommand fence = new FenceCommand(vm, host);
-
-        for (HostVO h : hosts) {
-            if (h.getHypervisorType() != HypervisorType.Ovm) {
-                continue;
-            }
-
-            if (h.getStatus() != Status.Up) {
-                continue;
-            }
-
-            if (h.getId() == host.getId()) {
-                continue;
-            }
-
-            FenceAnswer answer;
-            try {
-                answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
-            } catch (AgentUnavailableException e) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                }
-                continue;
-            } catch (OperationTimedoutException e) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                }
-                continue;
-            }
-
-            if (answer != null && answer.getResult()) {
-                return true;
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
-        }
-
-        return false;
-    }
-
-}
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmDiscoverer.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmDiscoverer.java
diff --git a/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmFencer.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmFencer.java
new file mode 100644
index 0000000..6a247d9
--- /dev/null
+++ b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmFencer.java
@@ -0,0 +1,119 @@
+// 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.ovm.hypervisor;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.ha.FenceBuilder;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+public class OvmFencer extends AdapterBase implements FenceBuilder {
+    private static final Logger s_logger = Logger.getLogger(OvmFencer.class);
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public OvmFencer() {
+        super();
+    }
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.Ovm) {
+            s_logger.debug("Don't know how to fence non Ovm hosts " + host.getHypervisorType());
+            return null;
+        }
+
+        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() != HypervisorType.Ovm) {
+                continue;
+            }
+
+            if (h.getStatus() != Status.Up) {
+                continue;
+            }
+
+            if (h.getId() == host.getId()) {
+                continue;
+            }
+
+            FenceAnswer answer;
+            try {
+                answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
+            } catch (AgentUnavailableException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                }
+                continue;
+            } catch (OperationTimedoutException e) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                }
+                continue;
+            }
+
+            if (answer != null && answer.getResult()) {
+                return true;
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
+        }
+
+        return false;
+    }
+
+}
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmGuru.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmGuru.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmGuru.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmGuru.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmHelper.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmHelper.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmHelper.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmHelper.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmResourceBase.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/hypervisor/OvmResourceBase.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/Coder.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Coder.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/Coder.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Coder.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/Connection.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Connection.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/Connection.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Connection.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmBridge.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmBridge.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmBridge.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmBridge.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmDisk.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmDisk.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmDisk.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmDisk.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmHost.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmHost.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmHost.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmHost.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmObject.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmObject.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmObject.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmObject.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmSecurityGroup.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmSecurityGroup.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmSecurityGroup.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmSecurityGroup.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmStoragePool.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmStoragePool.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmStoragePool.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmStoragePool.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVif.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVif.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVif.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVif.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVlan.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVlan.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVlan.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVlan.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVm.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVm.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVm.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVm.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVolume.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVolume.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/OvmVolume.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/OvmVolume.java
diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/object/Test.java b/plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Test.java
similarity index 100%
rename from plugins/hypervisors/ovm/src/com/cloud/ovm/object/Test.java
rename to plugins/hypervisors/ovm/src/main/java/com/cloud/ovm/object/Test.java
diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/module.properties b/plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/module.properties
rename to plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-compute/module.properties
diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml b/plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml
rename to plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-compute/spring-ovm-compute-context.xml
diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/module.properties b/plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/module.properties
rename to plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-discoverer/module.properties
diff --git a/plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml b/plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml
similarity index 100%
rename from plugins/hypervisors/ovm/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml
rename to plugins/hypervisors/ovm/src/main/resources/META-INF/cloudstack/ovm-discoverer/spring-ovm-discoverer-context.xml
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/ConfigFileOps.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/ConfigFileOps.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/ConfigFileOps.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/ConfigFileOps.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmCommonModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmCommonModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmCommonModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmDiskModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmDiskModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmDiskModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmDiskModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmDispatcher.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmDispatcher.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmDispatcher.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmDispatcher.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmFaultConstants.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmFaultConstants.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmFaultConstants.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmFaultConstants.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmHaHeartBeatModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmHaHeartBeatModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmHaHeartBeatModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmHaHeartBeatModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmHostModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmHostModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmHostModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmLoggerModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmLoggerModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmLoggerModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmLoggerModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmNetworkModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmNetworkModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmNetworkModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmNetworkModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmOCFS2Module.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmOCFS2Module.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmOCFS2Module.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmOCFS2Module.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmObjectModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmObjectModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmObjectModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmObjectModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmSecurityGroupModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmSecurityGroupModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmSecurityGroupModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmSecurityGroupModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmStoragePoolModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmStoragePoolModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmStoragePoolModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmStoragePoolModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVifModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVifModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVifModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVifModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVmModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVmModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVmModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVolumeModule.py b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVolumeModule.py
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/OvmVolumeModule.py
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/OvmVolumeModule.py
diff --git a/plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/configureOvm.sh b/plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/configureOvm.sh
similarity index 100%
rename from plugins/hypervisors/ovm/scripts/vm/hypervisor/ovm/configureOvm.sh
rename to plugins/hypervisors/ovm/src/main/scripts/vm/hypervisor/ovm/configureOvm.sh
diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml
index 667f663..b55540a 100644
--- a/plugins/hypervisors/ovm3/pom.xml
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -1,89 +1,84 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-hypervisor-ovm3</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor OracleVM3</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.xmlrpc</groupId>
-      <artifactId>xmlrpc-client</artifactId>
-      <version>${cs.xmlrpc.version}</version>
-    </dependency>
-    <dependency>
-	<groupId>org.apache.xmlrpc</groupId>
-	<artifactId>xmlrpc-common</artifactId>
-	<version>${cs.xmlrpc.version}</version>
-    </dependency>
-    <dependency>
-	<groupId>org.apache.commons</groupId>
-	<artifactId>commons-lang3</artifactId>
-	<version>${cs.commons-lang3.version}</version>
-    </dependency>
-    <dependency>
-	<groupId>log4j</groupId>
-	<artifactId>log4j</artifactId>
-	<version>${cs.log4j.version}</version>
-    </dependency>
-  </dependencies>
-   <build>
-    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
-    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
-    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
-    <outputDirectory>${basedir}/target/classes</outputDirectory>
-    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>${basedir}/src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${basedir}/src/test/resources</directory>
-      </testResource>
-    </testResources>
-  </build>
-  <profiles>
-    <profile>
-      <id>integration</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+<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-hypervisor-ovm3</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor OracleVM3</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.xmlrpc</groupId>
+            <artifactId>xmlrpc-client</artifactId>
+            <version>${cs.xmlrpc.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.xmlrpc</groupId>
+            <artifactId>xmlrpc-common</artifactId>
+            <version>${cs.xmlrpc.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${cs.commons-lang3.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <configuration>
+                        <skipTests>true</skipTests>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    <profiles>
+        <profile>
+            <id>integration</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
index cfe249e..102478c 100644
--- a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
@@ -172,7 +172,7 @@
                     if (nodeListFor2.getLength() > 1) {
                         /* Do we need to figure out all the sub elements here and put them in a map? */
                     } else {
-                        String element = nodeListFor.item(index).getTextContent();
+                        String element = nodeListFor.item(index).getNodeValue();
                         myMap.put(rnode, (E) element);
                     }
                 }
@@ -193,8 +193,8 @@
             NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
                     XPathConstants.NODESET);
             for (int ind = 0; ind < nodeList.getLength(); ind++) {
-                if (!nodeList.item(ind).getTextContent().isEmpty()) {
-                    list.add("" + nodeList.item(ind).getTextContent());
+                if (!nodeList.item(ind).getNodeValue().isEmpty()) {
+                    list.add("" + nodeList.item(ind).getNodeValue());
                 } else {
                     list.add("" + nodeList.item(ind).getNodeValue());
                 }
@@ -213,7 +213,7 @@
             XPathExpression xPathExpression = xPath.compile(path);
             NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
                     XPathConstants.NODESET);
-            return nodeList.item(0).getTextContent();
+            return nodeList.item(0).getNodeValue();
         } catch (NullPointerException e) {
             LOGGER.info("Got no items back from parsing, returning null: " + e);
             return null;
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
index 6a255ba..d3bf4f0 100644
--- a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
@@ -27,8 +27,6 @@
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DettachCommand;
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.log4j.Logger;
 
@@ -195,18 +193,12 @@
             return storageprocessor.execute((CopyCommand)cmd);
         } else if (cmd instanceof StorageSubSystemCommand) {
             return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
-        } else if (clazz == DeleteCommand.class) {
-            return storageprocessor.execute((DeleteCommand)cmd);
         } else if (clazz == CreateCommand.class) {
             return storageprocessor.execute((CreateCommand)cmd);
         } else if (clazz == CreateObjectCommand.class) {
             return storageprocessor.execute((CreateObjectCommand)cmd);
         } else if (clazz == AttachIsoCommand.class) {
             return storageprocessor.attachIso((AttachCommand)cmd);
-        } else if (clazz == DettachCommand.class) {
-            return storageprocessor.execute((DettachCommand)cmd);
-        } else if (clazz == AttachCommand.class) {
-            return storageprocessor.execute((AttachCommand)cmd);
         } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
             return storageprocessor.execute((CreatePrivateTemplateFromVolumeCommand)cmd);
         } else if (clazz == DestroyCommand.class) {
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
index cb02a23..f668cc6 100644
--- a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
@@ -313,9 +313,6 @@
         boolean enableHA = true;
         boolean limitCpuUse = false;
         String vncPassword = "gobbeldygoo";
-        // public StartCommand(VirtualMachineTO vm, Host host, boolean
-        // executeInSequence) {
-        // ./api/src/com/cloud/agent/api/to/VirtualMachineTO.java
         VirtualMachineTO vmspec = new VirtualMachineTO(id, instanceName, type,
                 cpus, speed, minRam, maxRam, bootloader, os, enableHA,
                 limitCpuUse, vncPassword);
diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml
index ff79e7d..c9ea690 100644
--- a/plugins/hypervisors/simulator/pom.xml
+++ b/plugins/hypervisors/simulator/pom.xml
@@ -1,37 +1,33 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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">
+    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>
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack-plugins</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <artifactId>cloud-plugin-hypervisor-simulator</artifactId>
     <name>Apache CloudStack Plugin - Hypervisor Simulator</name>
     <description>Simulator Hypervisor for Cloudstack</description>
-    <build>
-        <defaultGoal>install</defaultGoal>
-        <sourceDirectory>src</sourceDirectory>
-    </build>
     <dependencies>
         <dependency>
             <groupId>org.apache.cloudstack</groupId>
@@ -66,7 +62,6 @@
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
-            <version>${cs.guava.version}</version>
         </dependency>
     </dependencies>
 </project>
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java
deleted file mode 100644
index 3a31550..0000000
--- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.manager;
-
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.ca.SetupCertificateCommand;
-import org.apache.cloudstack.ca.SetupKeyStoreCommand;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.resource.AgentResourceBase;
-import com.cloud.simulator.MockHost;
-import com.cloud.utils.component.Manager;
-
-public interface MockAgentManager extends Manager {
-    public static final long DEFAULT_HOST_MEM_SIZE = 8 * 1024 * 1024 * 1024L; // 8G, unit of Mbytes
-    public static final int DEFAULT_HOST_CPU_CORES = 4; // 2 dual core CPUs (2 x 2)
-    public static final int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs
-
-    @Override
-    boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
-
-    Map<AgentResourceBase, Map<String, String>> createServerResources(Map<String, Object> params);
-
-    boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType,
-        String url);
-
-    boolean handleSystemVMStop(long vmId);
-
-    GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd);
-
-    Answer checkHealth(CheckHealthCommand cmd);
-
-    Answer pingTest(PingTestCommand cmd);
-
-    Answer setupKeyStore(SetupKeyStoreCommand cmd);
-
-    Answer setupCertificate(SetupCertificateCommand cmd);
-
-    MockHost getHost(String guid);
-
-    Answer maintain(MaintainCommand cmd);
-
-    Answer checkNetworkCommand(CheckNetworkCommand cmd);
-}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java
deleted file mode 100644
index 9d1e407..0000000
--- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java
+++ /dev/null
@@ -1,531 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.manager;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.PatternSyntaxException;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.ca.SetupCertificateAnswer;
-import org.apache.cloudstack.ca.SetupCertificateCommand;
-import org.apache.cloudstack.ca.SetupKeyStoreCommand;
-import org.apache.cloudstack.ca.SetupKeystoreAnswer;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CheckNetworkAnswer;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.HostStatsEntry;
-import com.cloud.agent.api.MaintainAnswer;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.api.commands.SimulatorAddSecondaryAgent;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.resource.AgentResourceBase;
-import com.cloud.resource.AgentRoutingResource;
-import com.cloud.resource.AgentStorageResource;
-import com.cloud.resource.Discoverer;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.SimulatorSecondaryDiscoverer;
-import com.cloud.simulator.MockHost;
-import com.cloud.simulator.MockHostVO;
-import com.cloud.simulator.MockVMVO;
-import com.cloud.simulator.dao.MockHostDao;
-import com.cloud.simulator.dao.MockVMDao;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-
-@Component
-public class MockAgentManagerImpl extends ManagerBase implements MockAgentManager {
-    private static final Logger s_logger = Logger.getLogger(MockAgentManagerImpl.class);
-    @Inject
-    HostPodDao _podDao = null;
-    @Inject
-    MockHostDao _mockHostDao = null;
-    @Inject
-    MockVMDao _mockVmDao = null;
-    @Inject
-    SimulatorManager _simulatorMgr = null;
-    @Inject
-    AgentManager _agentMgr = null;
-    @Inject
-    MockStorageManager _storageMgr = null;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject private AccountManager _accountMgr;
-
-    SimulatorSecondaryDiscoverer discoverer;
-    @Inject
-    HostDao hostDao;
-
-    List<Discoverer> discoverers;
-
-    private SecureRandom random;
-    private final Map<String, AgentResourceBase> _resources = new ConcurrentHashMap<String, AgentResourceBase>();
-    private ThreadPoolExecutor _executor;
-
-    private Pair<String, Long> getPodCidr(long podId, long dcId) {
-        try {
-
-            HashMap<Long, List<Object>> podMap = _podDao.getCurrentPodCidrSubnets(dcId, 0);
-            List<Object> cidrPair = podMap.get(podId);
-            String cidrAddress = (String)cidrPair.get(0);
-            Long cidrSize = (Long)cidrPair.get(1);
-            return new Pair<String, Long>(cidrAddress, cidrSize);
-        } catch (PatternSyntaxException e) {
-            s_logger.error("Exception while splitting pod cidr");
-            return null;
-        } catch (IndexOutOfBoundsException e) {
-            s_logger.error("Invalid pod cidr. Please check");
-            return null;
-        }
-    }
-
-    private String getIpAddress(long instanceId, long dcId, long podId) {
-        Pair<String, Long> cidr = this.getPodCidr(podId, dcId);
-        return NetUtils.long2Ip(NetUtils.ip2Long(cidr.first()) + instanceId);
-    }
-
-    private String getMacAddress(long dcId, long podId, long clusterId, int instanceId) {
-        return NetUtils.long2Mac((dcId << 40 + podId << 32 + clusterId << 24 + instanceId));
-    }
-
-    public synchronized int getNextAgentId(long cidrSize) {
-        return random.nextInt((int)cidrSize);
-    }
-
-    @Override
-    @DB
-    public Map<AgentResourceBase, Map<String, String>> createServerResources(Map<String, Object> params) {
-
-        Map<String, String> args = new HashMap<String, String>();
-        Map<AgentResourceBase, Map<String, String>> newResources = new HashMap<AgentResourceBase, Map<String, String>>();
-        AgentResourceBase agentResource;
-        long cpuCore = Long.parseLong((String)params.get("cpucore"));
-        long cpuSpeed = Long.parseLong((String)params.get("cpuspeed"));
-        long memory = Long.parseLong((String)params.get("memory"));
-        long localStorageSize = Long.parseLong((String)params.get("localstorage"));
-        synchronized (this) {
-            long dataCenterId = Long.parseLong((String)params.get("zone"));
-            long podId = Long.parseLong((String)params.get("pod"));
-            long clusterId = Long.parseLong((String)params.get("cluster"));
-            long cidrSize = getPodCidr(podId, dataCenterId).second();
-
-            int agentId = getNextAgentId(cidrSize);
-            String ipAddress = getIpAddress(agentId, dataCenterId, podId);
-            String macAddress = getMacAddress(dataCenterId, podId, clusterId, agentId);
-            MockHostVO mockHost = new MockHostVO();
-            mockHost.setDataCenterId(dataCenterId);
-            mockHost.setPodId(podId);
-            mockHost.setClusterId(clusterId);
-            mockHost.setCapabilities("hvm");
-            mockHost.setCpuCount(cpuCore);
-            mockHost.setCpuSpeed(cpuSpeed);
-            mockHost.setMemorySize(memory);
-            String guid = UUID.randomUUID().toString();
-            mockHost.setGuid(guid);
-            mockHost.setName("SimulatedAgent." + guid);
-            mockHost.setPrivateIpAddress(ipAddress);
-            mockHost.setPublicIpAddress(ipAddress);
-            mockHost.setStorageIpAddress(ipAddress);
-            mockHost.setPrivateMacAddress(macAddress);
-            mockHost.setPublicMacAddress(macAddress);
-            mockHost.setStorageMacAddress(macAddress);
-            mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
-            mockHost.setResource("com.cloud.agent.AgentRoutingResource");
-
-            TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-            try {
-                txn.start();
-                mockHost = _mockHostDao.persist(mockHost);
-                txn.commit();
-            } catch (Exception ex) {
-                txn.rollback();
-                s_logger.error("Error while configuring mock agent " + ex.getMessage());
-                throw new CloudRuntimeException("Error configuring agent", ex);
-            } finally {
-                txn.close();
-                txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-                txn.close();
-            }
-
-            _storageMgr.getLocalStorage(guid, localStorageSize);
-
-            agentResource = new AgentRoutingResource();
-            if (agentResource != null) {
-                try {
-                    params.put("guid", mockHost.getGuid());
-                    agentResource.start();
-                    agentResource.configure(mockHost.getName(), params);
-
-                    newResources.put(agentResource, args);
-                } catch (ConfigurationException e) {
-                    s_logger.error("error while configuring server resource" + e.getMessage());
-                }
-            }
-        }
-        return newResources;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        try {
-            random = SecureRandom.getInstance("SHA1PRNG");
-            _executor = new ThreadPoolExecutor(1, 5, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("Simulator-Agent-Mgr"));
-        } catch (NoSuchAlgorithmException e) {
-            s_logger.debug("Failed to initialize random:" + e.toString());
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name,
-        String vmType, String url) {
-        _executor.execute(new SystemVMHandler(vmId, privateIpAddress, privateMacAddress, privateNetMask, dcId, podId, name, vmType, _simulatorMgr, url));
-        return true;
-    }
-
-    @Override
-    public boolean handleSystemVMStop(long vmId) {
-        _executor.execute(new SystemVMHandler(vmId));
-        return true;
-    }
-
-    private class SystemVMHandler implements Runnable {
-        private final long vmId;
-        private String privateIpAddress;
-        private String privateMacAddress;
-        private String privateNetMask;
-        private long dcId;
-        private long podId;
-        private String guid;
-        private String name;
-        private String vmType;
-        private SimulatorManager mgr;
-        private final String mode;
-        private String url;
-
-        public SystemVMHandler(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType,
-                SimulatorManager mgr, String url) {
-            this.vmId = vmId;
-            this.privateIpAddress = privateIpAddress;
-            this.privateMacAddress = privateMacAddress;
-            this.privateNetMask = privateNetMask;
-            this.dcId = dcId;
-            this.guid = "SystemVM-" + UUID.randomUUID().toString();
-            this.name = name;
-            this.vmType = vmType;
-            this.mgr = mgr;
-            this.mode = "Start";
-            this.url = url;
-            this.podId = podId;
-        }
-
-        public SystemVMHandler(long vmId) {
-            this.vmId = vmId;
-            this.mode = "Stop";
-        }
-
-        private void handleSystemVMStop() {
-            TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-            try {
-                if (this.mode.equalsIgnoreCase("Stop")) {
-                    txn.start();
-                    MockHost host = _mockHostDao.findByVmId(this.vmId);
-                    if (host != null) {
-                        String guid = host.getGuid();
-                        if (guid != null) {
-                            AgentResourceBase res = _resources.get(guid);
-                            if (res != null) {
-                                res.stop();
-                                _resources.remove(guid);
-                            }
-                        }
-                    }
-                    txn.commit();
-                    return;
-                }
-            } catch (Exception ex) {
-                txn.rollback();
-                throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
-            } finally {
-                txn.close();
-                txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-                txn.close();
-            }
-
-            //stop ssvm agent
-            HostVO host = hostDao.findByGuid(this.guid);
-            if (host != null) {
-                try {
-                    _resourceMgr.deleteHost(host.getId(), true, true);
-                } catch (Exception e) {
-                    s_logger.debug("Failed to delete host: ", e);
-                }
-            }
-        }
-
-        @Override
-        @DB
-        public void run() {
-            CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
-            if (this.mode.equalsIgnoreCase("Stop")) {
-                handleSystemVMStop();
-                CallContext.unregister();
-                return;
-            }
-
-            String resource = null;
-            if (vmType.equalsIgnoreCase("secstorage")) {
-                resource = "com.cloud.agent.AgentStorageResource";
-            }
-            MockHostVO mockHost = new MockHostVO();
-            mockHost.setDataCenterId(this.dcId);
-            mockHost.setPodId(this.podId);
-            mockHost.setCpuCount(DEFAULT_HOST_CPU_CORES);
-            mockHost.setCpuSpeed(DEFAULT_HOST_SPEED_MHZ);
-            mockHost.setMemorySize(DEFAULT_HOST_MEM_SIZE);
-            mockHost.setGuid(this.guid);
-            mockHost.setName(name);
-            mockHost.setPrivateIpAddress(this.privateIpAddress);
-            mockHost.setPublicIpAddress(this.privateIpAddress);
-            mockHost.setStorageIpAddress(this.privateIpAddress);
-            mockHost.setPrivateMacAddress(this.privateMacAddress);
-            mockHost.setPublicMacAddress(this.privateMacAddress);
-            mockHost.setStorageMacAddress(this.privateMacAddress);
-            mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
-            mockHost.setResource(resource);
-            mockHost.setVmId(vmId);
-            TransactionLegacy simtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-            try {
-                simtxn.start();
-                mockHost = _mockHostDao.persist(mockHost);
-                simtxn.commit();
-            } catch (Exception ex) {
-                simtxn.rollback();
-                throw new CloudRuntimeException("Unable to persist host " + mockHost.getGuid() + " due to " + ex.getMessage(), ex);
-            } finally {
-                simtxn.close();
-                simtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-                simtxn.close();
-            }
-
-            if (vmType.equalsIgnoreCase("secstorage")) {
-                AgentStorageResource storageResource = new AgentStorageResource();
-                try {
-                    Map<String, Object> params = new HashMap<String, Object>();
-                    Map<String, String> details = new HashMap<String, String>();
-                    params.put("guid", this.guid);
-                    details.put("guid", this.guid);
-                    storageResource.configure("secondaryStorage", params);
-                    storageResource.start();
-                    _resources.put(this.guid, storageResource);
-                    discoverer.setResource(storageResource);
-                    SimulatorAddSecondaryAgent cmd = new SimulatorAddSecondaryAgent("sim://" + this.guid, this.dcId);
-                    try {
-                        _resourceMgr.discoverHosts(cmd);
-                    } catch (DiscoveryException e) {
-                        s_logger.debug("Failed to discover host: " + e.toString());
-                        CallContext.unregister();
-                        return;
-                    }
-                } catch (ConfigurationException e) {
-                    s_logger.debug("Failed to load secondary storage resource: " + e.toString());
-                    CallContext.unregister();
-                    return;
-                }
-            }
-        }
-    }
-
-    @Override
-    public MockHost getHost(String guid) {
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            txn.start();
-            MockHost _host = _mockHostDao.findByGuid(guid);
-            txn.commit();
-            if (_host != null) {
-                return _host;
-            } else {
-                s_logger.error("Host with guid " + guid + " was not found");
-                return null;
-            }
-        } catch (Exception ex) {
-            txn.rollback();
-            throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-    }
-
-    @Override
-    public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) {
-        String hostGuid = cmd.getHostGuid();
-        MockHost host = null;
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            txn.start();
-            host = _mockHostDao.findByGuid(hostGuid);
-            txn.commit();
-            if (host == null) {
-                return null;
-            }
-        } catch (Exception ex) {
-            txn.rollback();
-            throw new CloudRuntimeException("Unable to get host " + hostGuid + " due to " + ex.getMessage(), ex);
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-
-        TransactionLegacy vmtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            vmtxn.start();
-            List<MockVMVO> vms = _mockVmDao.findByHostId(host.getId());
-            vmtxn.commit();
-            double usedMem = 0.0;
-            double usedCpu = 0.0;
-            for (MockVMVO vm : vms) {
-                usedMem += vm.getMemory();
-                usedCpu += vm.getCpu();
-            }
-
-            HostStatsEntry hostStats = new HostStatsEntry();
-            hostStats.setTotalMemoryKBs(host.getMemorySize());
-            hostStats.setFreeMemoryKBs(host.getMemorySize() - usedMem);
-            hostStats.setNetworkReadKBs(32768);
-            hostStats.setNetworkWriteKBs(16384);
-            hostStats.setCpuUtilization(usedCpu / (host.getCpuCount() * host.getCpuSpeed()));
-            hostStats.setEntityType("simulator-host");
-            hostStats.setHostId(cmd.getHostId());
-            return new GetHostStatsAnswer(cmd, hostStats);
-        } catch (Exception ex) {
-            vmtxn.rollback();
-            throw new CloudRuntimeException("Unable to get Vms on host " + host.getGuid() + " due to " + ex.getMessage(), ex);
-        } finally {
-            vmtxn.close();
-            vmtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            vmtxn.close();
-        }
-    }
-
-    @Override
-    public Answer checkHealth(CheckHealthCommand cmd) {
-        return new Answer(cmd);
-    }
-
-    @Override
-    public Answer pingTest(PingTestCommand cmd) {
-        return new Answer(cmd);
-    }
-
-    @Override
-    public Answer setupKeyStore(SetupKeyStoreCommand cmd) {
-        return new SetupKeystoreAnswer(
-                "-----BEGIN CERTIFICATE REQUEST-----\n" +
-                "MIIBHjCByQIBADBkMQswCQYDVQQGEwJJTjELMAkGA1UECAwCSFIxETAPBgNVBAcM\n" +
-                "CEd1cnVncmFtMQ8wDQYDVQQKDAZBcGFjaGUxEzARBgNVBAsMCkNsb3VkU3RhY2sx\n" +
-                "DzANBgNVBAMMBnYtMS1WTTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQD46KFWKYrJ\n" +
-                "F43Y1oqWUfrl4mj4Qm05Bgsi6nuigZv7ufiAKK0nO4iJKdRa2hFMUvBi2/bU3IyY\n" +
-                "Nvg7cdJsn4K9AgMBAAGgADANBgkqhkiG9w0BAQUFAANBAIta9glu/ZSjA/ncyXix\n" +
-                "yDOyAKmXXxsRIsdrEuIzakUuJS7C8IG0FjUbDyIaiwWQa5x+Lt4oMqCmpNqRzaGP\n" +
-                "fOo=\n" + "-----END CERTIFICATE REQUEST-----");
-    }
-
-    @Override
-    public Answer setupCertificate(SetupCertificateCommand cmd) {
-        return new SetupCertificateAnswer(true);
-    }
-
-    @Override
-    public boolean start() {
-        for (Discoverer discoverer : discoverers) {
-            if (discoverer instanceof SimulatorSecondaryDiscoverer) {
-                this.discoverer = (SimulatorSecondaryDiscoverer)discoverer;
-                break;
-            }
-        }
-
-        if (this.discoverer == null) {
-            throw new IllegalStateException("Failed to find SimulatorSecondaryDiscoverer");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return this.getClass().getSimpleName();
-    }
-
-    @Override
-    public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) {
-        return new MaintainAnswer(cmd);
-    }
-
-    @Override
-    public Answer checkNetworkCommand(CheckNetworkCommand cmd) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Checking if network name setup is done on the resource");
-        }
-        return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done");
-    }
-
-    public List<Discoverer> getDiscoverers() {
-        return discoverers;
-    }
-
-    @Inject
-    public void setDiscoverers(List<Discoverer> discoverers) {
-        this.discoverers = discoverers;
-    }
-}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
deleted file mode 100644
index 7297773..0000000
--- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java
+++ /dev/null
@@ -1,579 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.manager;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.google.gson.Gson;
-import com.google.gson.stream.JsonReader;
-
-import org.apache.cloudstack.ca.SetupCertificateCommand;
-import org.apache.cloudstack.ca.SetupKeyStoreCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
-import org.apache.cloudstack.storage.command.UploadStatusCommand;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.AttachIsoCommand;
-import com.cloud.agent.api.BackupSnapshotCommand;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.CheckRouterCommand;
-import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.CleanupNetworkRulesCmd;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ComputeChecksumCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
-import com.cloud.agent.api.CreateStoragePoolCommand;
-import com.cloud.agent.api.CreateVMSnapshotCommand;
-import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
-import com.cloud.agent.api.DeleteVMSnapshotCommand;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.agent.api.GetDomRVersionCmd;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.GetVmStatsCommand;
-import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.GetVolumeStatsCommand;
-import com.cloud.agent.api.HandleConfigDriveIsoCommand;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.ManageSnapshotCommand;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.PvlanSetupCommand;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.ReplugNicCommand;
-import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.ScaleVmCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.SecurityGroupRulesCmd;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.UnPlugNicCommand;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
-import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand;
-import com.cloud.agent.api.routing.DhcpEntryCommand;
-import com.cloud.agent.api.routing.GetRouterAlertsCommand;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SavePasswordCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetMonitorServiceCommand;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SetStaticRouteCommand;
-import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.VmDataCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.CreateCommand;
-import com.cloud.agent.api.storage.DestroyCommand;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
-import com.cloud.api.commands.CleanupSimulatorMockCmd;
-import com.cloud.api.commands.ConfigureSimulatorCmd;
-import com.cloud.api.commands.ConfigureSimulatorHAProviderState;
-import com.cloud.api.commands.ListSimulatorHAStateTransitions;
-import com.cloud.api.commands.QuerySimulatorMockCmd;
-import com.cloud.resource.SimulatorStorageProcessor;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.simulator.MockConfigurationVO;
-import com.cloud.simulator.MockHost;
-import com.cloud.simulator.MockVMVO;
-import com.cloud.simulator.dao.MockConfigurationDao;
-import com.cloud.simulator.dao.MockHostDao;
-import com.cloud.storage.resource.StorageSubsystemCommandHandler;
-import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachine.PowerState;
-
-@Component
-public class SimulatorManagerImpl extends ManagerBase implements SimulatorManager, PluggableService {
-    private static final Logger s_logger = Logger.getLogger(SimulatorManagerImpl.class);
-    private static final Gson s_gson = GsonHelper.getGson();
-    @Inject
-    MockVmManager _mockVmMgr;
-    @Inject
-    MockStorageManager _mockStorageMgr;
-    @Inject
-    MockAgentManager _mockAgentMgr;
-    @Inject
-    MockNetworkManager _mockNetworkMgr;
-    @Inject
-    MockConfigurationDao _mockConfigDao;
-    @Inject
-    MockHostDao _mockHost = null;
-    protected StorageSubsystemCommandHandler storageHandler;
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        final SimulatorStorageProcessor processor = new SimulatorStorageProcessor(this);
-        storageHandler = new StorageSubsystemCommandHandlerBase(processor);
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return this.getClass().getSimpleName();
-    }
-
-    @Override
-    public MockVmManager getVmMgr() {
-        return _mockVmMgr;
-    }
-
-    @Override
-    public MockStorageManager getStorageMgr() {
-        return _mockStorageMgr;
-    }
-
-    @Override
-    public MockAgentManager getAgentMgr() {
-        return _mockAgentMgr;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(ConfigureSimulatorCmd.class);
-        cmdList.add(QuerySimulatorMockCmd.class);
-        cmdList.add(CleanupSimulatorMockCmd.class);
-        cmdList.add(ConfigureSimulatorHAProviderState.class);
-        cmdList.add(ListSimulatorHAStateTransitions.class);
-        return cmdList;
-    }
-
-    @DB
-    @Override
-    public Answer simulate(final Command cmd, final String hostGuid) {
-        s_logger.debug("Simulate command " + cmd);
-        Answer answer = null;
-        Exception exception = null;
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            final MockHost host = _mockHost.findByGuid(hostGuid);
-            String cmdName = cmd.toString();
-            final int index = cmdName.lastIndexOf(".");
-            if (index != -1) {
-                cmdName = cmdName.substring(index + 1);
-            }
-
-            final SimulatorInfo info = new SimulatorInfo();
-            info.setHostUuid(hostGuid);
-
-            final MockConfigurationVO config = _mockConfigDao.findByNameBottomUP(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), cmdName);
-            if (config != null && (config.getCount() == null || config.getCount().intValue() > 0)) {
-                final Map<String, String> configParameters = config.getParameters();
-                for (final Map.Entry<String, String> entry : configParameters.entrySet()) {
-                    if (entry.getKey().equalsIgnoreCase("enabled")) {
-                        info.setEnabled(Boolean.parseBoolean(entry.getValue()));
-                    } else if (entry.getKey().equalsIgnoreCase("timeout")) {
-                        try {
-                            info.setTimeout(Integer.valueOf(entry.getValue()));
-                        } catch (final NumberFormatException e) {
-                            s_logger.debug("invalid timeout parameter: " + e.toString());
-                        }
-                    }
-
-                    if (entry.getKey().equalsIgnoreCase("wait")) {
-                        try {
-                            final int wait = Integer.valueOf(entry.getValue());
-                            Thread.sleep(wait);
-                        } catch (final NumberFormatException e) {
-                            s_logger.debug("invalid wait parameter: " + e.toString());
-                        } catch (final InterruptedException e) {
-                            s_logger.debug("thread is interrupted: " + e.toString());
-                        }
-                    }
-
-                    if (entry.getKey().equalsIgnoreCase("result")) {
-                        final String value = entry.getValue();
-                        if (value.equalsIgnoreCase("fail")) {
-                            answer = new Answer(cmd, false, "Simulated failure");
-                        } else if (value.equalsIgnoreCase("fault")) {
-                            exception = new Exception("Simulated fault");
-                        }
-                    }
-                }
-
-                if (exception != null) {
-                    throw exception;
-                }
-
-                if (answer == null) {
-                    final String message = config.getJsonResponse();
-                    if (message != null) {
-                        // json response looks like {"<Type>":....}
-                        final String objectType = message.split(":")[0].substring(2).replace("\"", "");
-                        final String objectData = message.substring(message.indexOf(':') + 1, message.length() - 1);
-                        if (objectType != null) {
-                            Class<?> clz = null;
-                            try {
-                                clz = Class.forName(objectType);
-                            } catch (final ClassNotFoundException e) {
-                            }
-                            if (clz != null) {
-                                final StringReader reader = new StringReader(objectData);
-                                final JsonReader jsonReader = new JsonReader(reader);
-                                jsonReader.setLenient(true);
-                                answer = (Answer)s_gson.fromJson(jsonReader, clz);
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (answer == null) {
-                if (cmd instanceof GetHostStatsCommand) {
-                    answer = _mockAgentMgr.getHostStatistic((GetHostStatsCommand)cmd);
-                } else if (cmd instanceof CheckHealthCommand) {
-                    answer = _mockAgentMgr.checkHealth((CheckHealthCommand)cmd);
-                } else if (cmd instanceof PingTestCommand) {
-                    answer = _mockAgentMgr.pingTest((PingTestCommand)cmd);
-                } else if (cmd instanceof SetupKeyStoreCommand) {
-                    answer = _mockAgentMgr.setupKeyStore((SetupKeyStoreCommand)cmd);
-                } else if (cmd instanceof SetupCertificateCommand) {
-                    answer = _mockAgentMgr.setupCertificate((SetupCertificateCommand)cmd);
-                } else if (cmd instanceof PrepareForMigrationCommand) {
-                    answer = _mockVmMgr.prepareForMigrate((PrepareForMigrationCommand)cmd);
-                } else if (cmd instanceof MigrateCommand) {
-                    answer = _mockVmMgr.migrate((MigrateCommand)cmd, info);
-                } else if (cmd instanceof StartCommand) {
-                    answer = _mockVmMgr.startVM((StartCommand)cmd, info);
-                } else if (cmd instanceof CheckSshCommand) {
-                    answer = _mockVmMgr.checkSshCommand((CheckSshCommand)cmd);
-                } else if (cmd instanceof CheckVirtualMachineCommand) {
-                    answer = _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd);
-                } else if (cmd instanceof SetStaticNatRulesCommand) {
-                    answer = _mockNetworkMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd);
-                } else if (cmd instanceof SetFirewallRulesCommand) {
-                    answer = _mockNetworkMgr.SetFirewallRules((SetFirewallRulesCommand)cmd);
-                } else if (cmd instanceof SetPortForwardingRulesCommand) {
-                    answer = _mockNetworkMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd);
-                } else if (cmd instanceof NetworkUsageCommand) {
-                    answer = _mockNetworkMgr.getNetworkUsage((NetworkUsageCommand)cmd);
-                } else if (cmd instanceof IpAssocCommand) {
-                    answer = _mockNetworkMgr.IpAssoc((IpAssocCommand)cmd);
-                } else if (cmd instanceof LoadBalancerConfigCommand) {
-                    answer = _mockNetworkMgr.LoadBalancerConfig((LoadBalancerConfigCommand)cmd);
-                } else if (cmd instanceof DhcpEntryCommand) {
-                    answer = _mockNetworkMgr.AddDhcpEntry((DhcpEntryCommand)cmd);
-                } else if (cmd instanceof VmDataCommand) {
-                    answer = _mockVmMgr.setVmData((VmDataCommand)cmd);
-                } else if (cmd instanceof CleanupNetworkRulesCmd) {
-                    answer = _mockVmMgr.cleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info);
-                } else if (cmd instanceof CheckNetworkCommand) {
-                    answer = _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand)cmd);
-                } else if (cmd instanceof StopCommand) {
-                    answer = _mockVmMgr.stopVM((StopCommand)cmd);
-                } else if (cmd instanceof RebootCommand) {
-                    answer = _mockVmMgr.rebootVM((RebootCommand)cmd);
-                } else if (cmd instanceof GetVncPortCommand) {
-                    answer = _mockVmMgr.getVncPort((GetVncPortCommand)cmd);
-                } else if (cmd instanceof CheckConsoleProxyLoadCommand) {
-                    answer = _mockVmMgr.checkConsoleProxyLoad((CheckConsoleProxyLoadCommand)cmd);
-                } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
-                    answer = _mockVmMgr.watchConsoleProxyLoad((WatchConsoleProxyLoadCommand)cmd);
-                } else if (cmd instanceof SecurityGroupRulesCmd) {
-                    answer = _mockVmMgr.addSecurityGroupRules((SecurityGroupRulesCmd)cmd, info);
-                } else if (cmd instanceof SavePasswordCommand) {
-                    answer = _mockVmMgr.savePassword((SavePasswordCommand)cmd);
-                } else if (cmd instanceof PrimaryStorageDownloadCommand) {
-                    answer = _mockStorageMgr.primaryStorageDownload((PrimaryStorageDownloadCommand)cmd);
-                } else if (cmd instanceof CreateCommand) {
-                    answer = _mockStorageMgr.createVolume((CreateCommand)cmd);
-                } else if (cmd instanceof AttachIsoCommand) {
-                    answer = _mockStorageMgr.AttachIso((AttachIsoCommand)cmd);
-                } else if (cmd instanceof DeleteStoragePoolCommand) {
-                    answer = _mockStorageMgr.DeleteStoragePool((DeleteStoragePoolCommand)cmd);
-                } else if (cmd instanceof ModifyStoragePoolCommand) {
-                    answer = _mockStorageMgr.ModifyStoragePool((ModifyStoragePoolCommand)cmd);
-                } else if (cmd instanceof CreateStoragePoolCommand) {
-                    answer = _mockStorageMgr.CreateStoragePool((CreateStoragePoolCommand)cmd);
-                } else if (cmd instanceof SecStorageSetupCommand) {
-                    answer = _mockStorageMgr.SecStorageSetup((SecStorageSetupCommand)cmd);
-                } else if (cmd instanceof ListTemplateCommand) {
-                    answer = _mockStorageMgr.ListTemplates((ListTemplateCommand)cmd);
-                } else if (cmd instanceof ListVolumeCommand) {
-                    answer = _mockStorageMgr.ListVolumes((ListVolumeCommand)cmd);
-                } else if (cmd instanceof DestroyCommand) {
-                    answer = _mockStorageMgr.Destroy((DestroyCommand)cmd);
-                } else if (cmd instanceof DownloadProgressCommand) {
-                    answer = _mockStorageMgr.DownloadProcess((DownloadProgressCommand)cmd);
-                } else if (cmd instanceof DownloadCommand) {
-                    answer = _mockStorageMgr.Download((DownloadCommand)cmd);
-                } else if (cmd instanceof GetStorageStatsCommand) {
-                    answer = _mockStorageMgr.GetStorageStats((GetStorageStatsCommand)cmd);
-                } else if (cmd instanceof GetVolumeStatsCommand) {
-                    answer = _mockStorageMgr.getVolumeStats((GetVolumeStatsCommand)cmd);
-                } else if (cmd instanceof ManageSnapshotCommand) {
-                    answer = _mockStorageMgr.ManageSnapshot((ManageSnapshotCommand)cmd);
-                } else if (cmd instanceof BackupSnapshotCommand) {
-                    answer = _mockStorageMgr.BackupSnapshot((BackupSnapshotCommand)cmd, info);
-                } else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
-                    answer = _mockStorageMgr.CreateVolumeFromSnapshot((CreateVolumeFromSnapshotCommand)cmd);
-                } else if (cmd instanceof DeleteCommand) {
-                    answer = _mockStorageMgr.Delete((DeleteCommand)cmd);
-                } else if (cmd instanceof SecStorageVMSetupCommand) {
-                    answer = _mockStorageMgr.SecStorageVMSetup((SecStorageVMSetupCommand)cmd);
-                } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
-                    answer = _mockStorageMgr.CreatePrivateTemplateFromSnapshot((CreatePrivateTemplateFromSnapshotCommand)cmd);
-                } else if (cmd instanceof ComputeChecksumCommand) {
-                    answer = _mockStorageMgr.ComputeChecksum((ComputeChecksumCommand)cmd);
-                } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
-                    answer = _mockStorageMgr.CreatePrivateTemplateFromVolume((CreatePrivateTemplateFromVolumeCommand)cmd);
-                } else if (cmd instanceof UploadStatusCommand) {
-                    answer = _mockStorageMgr.getUploadStatus((UploadStatusCommand)cmd);
-                } else if (cmd instanceof MaintainCommand) {
-                    answer = _mockAgentMgr.maintain((MaintainCommand)cmd);
-                } else if (cmd instanceof GetVmStatsCommand) {
-                    answer = _mockVmMgr.getVmStats((GetVmStatsCommand)cmd);
-                } else if (cmd instanceof CheckRouterCommand) {
-                    answer = _mockVmMgr.checkRouter((CheckRouterCommand)cmd);
-                } else if (cmd instanceof GetDomRVersionCmd) {
-                    answer = _mockVmMgr.getDomRVersion((GetDomRVersionCmd)cmd);
-                } else if (cmd instanceof CopyVolumeCommand) {
-                    answer = _mockStorageMgr.CopyVolume((CopyVolumeCommand)cmd);
-                } else if (cmd instanceof PlugNicCommand) {
-                    answer = _mockNetworkMgr.plugNic((PlugNicCommand)cmd);
-                } else if (cmd instanceof UnPlugNicCommand) {
-                    answer = _mockNetworkMgr.unplugNic((UnPlugNicCommand)cmd);
-                } else if (cmd instanceof ReplugNicCommand) {
-                    answer = _mockNetworkMgr.replugNic((ReplugNicCommand)cmd);
-                } else if (cmd instanceof IpAssocVpcCommand) {
-                    answer = _mockNetworkMgr.ipAssoc((IpAssocVpcCommand)cmd);
-                } else if (cmd instanceof SetSourceNatCommand) {
-                    answer = _mockNetworkMgr.setSourceNat((SetSourceNatCommand)cmd);
-                } else if (cmd instanceof SetNetworkACLCommand) {
-                    answer = _mockNetworkMgr.setNetworkAcl((SetNetworkACLCommand)cmd);
-                } else if (cmd instanceof SetupGuestNetworkCommand) {
-                    answer = _mockNetworkMgr.setUpGuestNetwork((SetupGuestNetworkCommand)cmd);
-                } else if (cmd instanceof SetPortForwardingRulesVpcCommand) {
-                    answer = _mockNetworkMgr.setVpcPortForwards((SetPortForwardingRulesVpcCommand)cmd);
-                } else if (cmd instanceof SetStaticNatRulesCommand) {
-                    answer = _mockNetworkMgr.setVPCStaticNatRules((SetStaticNatRulesCommand)cmd);
-                } else if (cmd instanceof SetStaticRouteCommand) {
-                    answer = _mockNetworkMgr.setStaticRoute((SetStaticRouteCommand)cmd);
-                } else if (cmd instanceof Site2SiteVpnCfgCommand) {
-                    answer = _mockNetworkMgr.siteToSiteVpn((Site2SiteVpnCfgCommand)cmd);
-                } else if (cmd instanceof CheckS2SVpnConnectionsCommand) {
-                    answer = _mockNetworkMgr.checkSiteToSiteVpnConnection((CheckS2SVpnConnectionsCommand)cmd);
-                } else if (cmd instanceof CreateVMSnapshotCommand) {
-                    answer = _mockVmMgr.createVmSnapshot((CreateVMSnapshotCommand)cmd);
-                } else if (cmd instanceof DeleteVMSnapshotCommand) {
-                    answer = _mockVmMgr.deleteVmSnapshot((DeleteVMSnapshotCommand)cmd);
-                } else if (cmd instanceof RevertToVMSnapshotCommand) {
-                    answer = _mockVmMgr.revertVmSnapshot((RevertToVMSnapshotCommand)cmd);
-                } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) {
-                    answer = _mockVmMgr.plugSecondaryIp((NetworkRulesVmSecondaryIpCommand)cmd);
-                } else if (cmd instanceof ScaleVmCommand) {
-                    answer = _mockVmMgr.scaleVm((ScaleVmCommand)cmd);
-                } else if (cmd instanceof PvlanSetupCommand) {
-                    answer = _mockNetworkMgr.setupPVLAN((PvlanSetupCommand)cmd);
-                } else if (cmd instanceof StorageSubSystemCommand) {
-                    answer = storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
-                } else if (cmd instanceof FenceCommand) {
-                    answer = _mockVmMgr.fence((FenceCommand)cmd);
-                } else if (cmd instanceof HandleConfigDriveIsoCommand) {
-                    answer = _mockStorageMgr.handleConfigDriveIso((HandleConfigDriveIsoCommand)cmd);
-                } else if (cmd instanceof GetRouterAlertsCommand
-                        || cmd instanceof VpnUsersCfgCommand
-                        || cmd instanceof RemoteAccessVpnCfgCommand
-                        || cmd instanceof SetMonitorServiceCommand
-                        || cmd instanceof AggregationControlCommand
-                        || cmd instanceof SecStorageFirewallCfgCommand) {
-                    answer = new Answer(cmd);
-                } else {
-                    s_logger.error("Simulator does not implement command of type " + cmd.toString());
-                    answer = Answer.createUnsupportedCommandAnswer(cmd);
-                }
-            }
-
-            if (config != null && config.getCount() != null && config.getCount().intValue() > 0) {
-                if (answer != null) {
-                    config.setCount(config.getCount().intValue() - 1);
-                    _mockConfigDao.update(config.getId(), config);
-                }
-            }
-
-            s_logger.debug("Finished simulate command " + cmd);
-
-            return answer;
-        } catch (final Exception e) {
-            s_logger.error("Failed execute cmd: ", e);
-            txn.rollback();
-            return new Answer(cmd, false, e.toString());
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-    }
-
-    @Override
-    public StoragePoolInfo getLocalStorage(final String hostGuid) {
-        return _mockStorageMgr.getLocalStorage(hostGuid);
-    }
-
-    @Override
-    public Map<String, PowerState> getVmStates(final String hostGuid) {
-        return _mockVmMgr.getVmStates(hostGuid);
-    }
-
-    @Override
-    public Map<String, MockVMVO> getVms(final String hostGuid) {
-        return _mockVmMgr.getVms(hostGuid);
-    }
-
-    @Override
-    public HashMap<String, Pair<Long, Long>> syncNetworkGroups(final String hostGuid) {
-        final SimulatorInfo info = new SimulatorInfo();
-        info.setHostUuid(hostGuid);
-        return _mockVmMgr.syncNetworkGroups(info);
-    }
-
-    @Override
-    public Long configureSimulator(final Long zoneId, final Long podId, final Long clusterId, final Long hostId, final String command, final String values, final Integer count, final String jsonResponse) {
-        Long id = null;
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            txn.start();
-            MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command);
-            if (config == null) {
-                config = new MockConfigurationVO();
-                config.setClusterId(clusterId);
-                config.setDataCenterId(zoneId);
-                config.setPodId(podId);
-                config.setHostId(hostId);
-                config.setName(command);
-                config.setValues(values);
-                config.setCount(count);
-                config.setJsonResponse(jsonResponse);
-                config = _mockConfigDao.persist(config);
-                txn.commit();
-            } else {
-                config.setValues(values);
-                config.setCount(count);
-                config.setJsonResponse(jsonResponse);
-                _mockConfigDao.update(config.getId(), config);
-                txn.commit();
-            }
-            id = config.getId();
-        } catch (final Exception ex) {
-            txn.rollback();
-            throw new CloudRuntimeException("Unable to configure simulator mock because of " + ex.getMessage(), ex);
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-        return id;
-    }
-
-    @Override
-    public MockConfigurationVO querySimulatorMock(final Long id) {
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            txn.start();
-            return _mockConfigDao.findById(id);
-        } catch (final Exception ex) {
-            txn.rollback();
-            throw new CloudRuntimeException("Unable to query simulator mock because of " + ex.getMessage(), ex);
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-    }
-
-    @Override
-    public boolean clearSimulatorMock(final Long id) {
-        boolean status = false;
-        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
-        try {
-            txn.start();
-            final MockConfigurationVO config = _mockConfigDao.findById(id);
-            if (config != null) {
-                config.setRemoved(new Date());
-                _mockConfigDao.update(config.getId(), config);
-                status = true;
-                txn.commit();
-            }
-        } catch (final Exception ex) {
-            txn.rollback();
-            throw new CloudRuntimeException("Unable to cleanup simulator mock because of " + ex.getMessage(), ex);
-        } finally {
-            txn.close();
-            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-        }
-        return status;
-    }
-
-    @Override
-    public MockConfigurationDao getMockConfigurationDao() {
-        return _mockConfigDao;
-    }
-}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/ha/SimulatorFencer.java b/plugins/hypervisors/simulator/src/com/cloud/ha/SimulatorFencer.java
deleted file mode 100644
index 86c2871..0000000
--- a/plugins/hypervisors/simulator/src/com/cloud/ha/SimulatorFencer.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.ha;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.FenceAnswer;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.VirtualMachine;
-
-public class SimulatorFencer extends AdapterBase implements FenceBuilder {
-    private static final Logger s_logger = Logger.getLogger(SimulatorFencer.class);
-
-    @Inject HostDao _hostDao;
-    @Inject AgentManager _agentMgr;
-    @Inject ResourceManager _resourceMgr;
-    @Override
-    public boolean configure(String name, Map<String, Object> params)
-            throws ConfigurationException {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public SimulatorFencer() {
-        super();
-    }
-
-    @Override
-    public Boolean fenceOff(VirtualMachine vm, Host host) {
-        if (host.getHypervisorType() != HypervisorType.Simulator) {
-            s_logger.debug("Don't know how to fence non simulator hosts " + host.getHypervisorType());
-            return null;
-        }
-
-        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
-        FenceCommand fence = new FenceCommand(vm, host);
-
-        for (HostVO h : hosts) {
-            if (h.getHypervisorType() == HypervisorType.Simulator) {
-                if( h.getStatus() != Status.Up ) {
-                    continue;
-                }
-                if( h.getId() == host.getId() ) {
-                    continue;
-                }
-                FenceAnswer answer = null;
-                try {
-                    answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
-                } catch (AgentUnavailableException e) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                    }
-                    continue;
-                } catch (OperationTimedoutException e) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                    }
-                    continue;
-                }
-                if (answer != null && answer.getResult()) {
-                    return true;
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
-        }
-
-        return false;
-    }
-}
diff --git a/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManager.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManager.java
new file mode 100644
index 0000000..6a9e707
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManager.java
@@ -0,0 +1,70 @@
+// 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.manager;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.ca.SetupCertificateCommand;
+import org.apache.cloudstack.ca.SetupKeyStoreCommand;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.resource.AgentResourceBase;
+import com.cloud.simulator.MockHost;
+import com.cloud.utils.component.Manager;
+import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
+
+public interface MockAgentManager extends Manager {
+    public static final long DEFAULT_HOST_MEM_SIZE = 8 * 1024 * 1024 * 1024L; // 8G, unit of Mbytes
+    public static final int DEFAULT_HOST_CPU_CORES = 4; // 2 dual core CPUs (2 x 2)
+    public static final int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs
+
+    @Override
+    boolean configure(String name, Map<String, Object> params) throws ConfigurationException;
+
+    Map<AgentResourceBase, Map<String, String>> createServerResources(Map<String, Object> params);
+
+    boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType,
+        String url);
+
+    boolean handleSystemVMStop(long vmId);
+
+    GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd);
+
+    Answer checkHealth(CheckHealthCommand cmd);
+
+    Answer pingTest(PingTestCommand cmd);
+
+    Answer setupKeyStore(SetupKeyStoreCommand cmd);
+
+    Answer setupCertificate(SetupCertificateCommand cmd);
+
+    MockHost getHost(String guid);
+
+    Answer maintain(MaintainCommand cmd);
+
+    Answer checkNetworkCommand(CheckNetworkCommand cmd);
+
+    Answer runDiagnostics(DiagnosticsCommand cmd);
+}
diff --git a/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManagerImpl.java
new file mode 100644
index 0000000..7af2827
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockAgentManagerImpl.java
@@ -0,0 +1,541 @@
+// 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.manager;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.api.commands.SimulatorAddSecondaryAgent;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.resource.AgentResourceBase;
+import com.cloud.resource.AgentRoutingResource;
+import com.cloud.resource.AgentStorageResource;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.SimulatorSecondaryDiscoverer;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockHostVO;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.simulator.dao.MockVMDao;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import org.apache.cloudstack.ca.SetupCertificateAnswer;
+import org.apache.cloudstack.ca.SetupCertificateCommand;
+import org.apache.cloudstack.ca.SetupKeyStoreCommand;
+import org.apache.cloudstack.ca.SetupKeystoreAnswer;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.diagnostics.DiagnosticsAnswer;
+import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.PatternSyntaxException;
+
+@Component
+public class MockAgentManagerImpl extends ManagerBase implements MockAgentManager {
+    private static final Logger s_logger = Logger.getLogger(MockAgentManagerImpl.class);
+    @Inject
+    HostPodDao _podDao = null;
+    @Inject
+    MockHostDao _mockHostDao = null;
+    @Inject
+    MockVMDao _mockVmDao = null;
+    @Inject
+    SimulatorManager _simulatorMgr = null;
+    @Inject
+    AgentManager _agentMgr = null;
+    @Inject
+    MockStorageManager _storageMgr = null;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject private AccountManager _accountMgr;
+
+    SimulatorSecondaryDiscoverer discoverer;
+    @Inject
+    HostDao hostDao;
+
+    List<Discoverer> discoverers;
+
+    private SecureRandom random;
+    private final Map<String, AgentResourceBase> _resources = new ConcurrentHashMap<String, AgentResourceBase>();
+    private ThreadPoolExecutor _executor;
+
+    private Pair<String, Long> getPodCidr(long podId, long dcId) {
+        try {
+
+            HashMap<Long, List<Object>> podMap = _podDao.getCurrentPodCidrSubnets(dcId, 0);
+            List<Object> cidrPair = podMap.get(podId);
+            String cidrAddress = (String)cidrPair.get(0);
+            Long cidrSize = (Long)cidrPair.get(1);
+            return new Pair<String, Long>(cidrAddress, cidrSize);
+        } catch (PatternSyntaxException e) {
+            s_logger.error("Exception while splitting pod cidr");
+            return null;
+        } catch (IndexOutOfBoundsException e) {
+            s_logger.error("Invalid pod cidr. Please check");
+            return null;
+        }
+    }
+
+    private String getIpAddress(long instanceId, long dcId, long podId) {
+        Pair<String, Long> cidr = this.getPodCidr(podId, dcId);
+        return NetUtils.long2Ip(NetUtils.ip2Long(cidr.first()) + instanceId);
+    }
+
+    private String getMacAddress(long dcId, long podId, long clusterId, int instanceId) {
+        return NetUtils.long2Mac((dcId << 40 + podId << 32 + clusterId << 24 + instanceId));
+    }
+
+    public synchronized int getNextAgentId(long cidrSize) {
+        return random.nextInt((int)cidrSize);
+    }
+
+    @Override
+    @DB
+    public Map<AgentResourceBase, Map<String, String>> createServerResources(Map<String, Object> params) {
+
+        Map<String, String> args = new HashMap<String, String>();
+        Map<AgentResourceBase, Map<String, String>> newResources = new HashMap<AgentResourceBase, Map<String, String>>();
+        AgentResourceBase agentResource;
+        long cpuCore = Long.parseLong((String)params.get("cpucore"));
+        long cpuSpeed = Long.parseLong((String)params.get("cpuspeed"));
+        long memory = Long.parseLong((String)params.get("memory"));
+        long localStorageSize = Long.parseLong((String)params.get("localstorage"));
+        synchronized (this) {
+            long dataCenterId = Long.parseLong((String)params.get("zone"));
+            long podId = Long.parseLong((String)params.get("pod"));
+            long clusterId = Long.parseLong((String)params.get("cluster"));
+            long cidrSize = getPodCidr(podId, dataCenterId).second();
+
+            int agentId = getNextAgentId(cidrSize);
+            String ipAddress = getIpAddress(agentId, dataCenterId, podId);
+            String macAddress = getMacAddress(dataCenterId, podId, clusterId, agentId);
+            MockHostVO mockHost = new MockHostVO();
+            mockHost.setDataCenterId(dataCenterId);
+            mockHost.setPodId(podId);
+            mockHost.setClusterId(clusterId);
+            mockHost.setCapabilities("hvm");
+            mockHost.setCpuCount(cpuCore);
+            mockHost.setCpuSpeed(cpuSpeed);
+            mockHost.setMemorySize(memory);
+            String guid = UUID.randomUUID().toString();
+            mockHost.setGuid(guid);
+            mockHost.setName("SimulatedAgent." + guid);
+            mockHost.setPrivateIpAddress(ipAddress);
+            mockHost.setPublicIpAddress(ipAddress);
+            mockHost.setStorageIpAddress(ipAddress);
+            mockHost.setPrivateMacAddress(macAddress);
+            mockHost.setPublicMacAddress(macAddress);
+            mockHost.setStorageMacAddress(macAddress);
+            mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
+            mockHost.setResource("com.cloud.agent.AgentRoutingResource");
+
+            TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+            try {
+                txn.start();
+                mockHost = _mockHostDao.persist(mockHost);
+                txn.commit();
+            } catch (Exception ex) {
+                txn.rollback();
+                s_logger.error("Error while configuring mock agent " + ex.getMessage());
+                throw new CloudRuntimeException("Error configuring agent", ex);
+            } finally {
+                txn.close();
+                txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+                txn.close();
+            }
+
+            _storageMgr.getLocalStorage(guid, localStorageSize);
+
+            agentResource = new AgentRoutingResource();
+            if (agentResource != null) {
+                try {
+                    params.put("guid", mockHost.getGuid());
+                    agentResource.start();
+                    agentResource.configure(mockHost.getName(), params);
+
+                    newResources.put(agentResource, args);
+                } catch (ConfigurationException e) {
+                    s_logger.error("error while configuring server resource" + e.getMessage());
+                }
+            }
+        }
+        return newResources;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        try {
+            random = SecureRandom.getInstance("SHA1PRNG");
+            _executor = new ThreadPoolExecutor(1, 5, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("Simulator-Agent-Mgr"));
+        } catch (NoSuchAlgorithmException e) {
+            s_logger.debug("Failed to initialize random:" + e.toString());
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name,
+        String vmType, String url) {
+        _executor.execute(new SystemVMHandler(vmId, privateIpAddress, privateMacAddress, privateNetMask, dcId, podId, name, vmType, _simulatorMgr, url));
+        return true;
+    }
+
+    @Override
+    public boolean handleSystemVMStop(long vmId) {
+        _executor.execute(new SystemVMHandler(vmId));
+        return true;
+    }
+
+    private class SystemVMHandler implements Runnable {
+        private final long vmId;
+        private String privateIpAddress;
+        private String privateMacAddress;
+        private String privateNetMask;
+        private long dcId;
+        private long podId;
+        private String guid;
+        private String name;
+        private String vmType;
+        private SimulatorManager mgr;
+        private final String mode;
+        private String url;
+
+        public SystemVMHandler(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType,
+                SimulatorManager mgr, String url) {
+            this.vmId = vmId;
+            this.privateIpAddress = privateIpAddress;
+            this.privateMacAddress = privateMacAddress;
+            this.privateNetMask = privateNetMask;
+            this.dcId = dcId;
+            this.guid = "SystemVM-" + UUID.randomUUID().toString();
+            this.name = name;
+            this.vmType = vmType;
+            this.mgr = mgr;
+            this.mode = "Start";
+            this.url = url;
+            this.podId = podId;
+        }
+
+        public SystemVMHandler(long vmId) {
+            this.vmId = vmId;
+            this.mode = "Stop";
+        }
+
+        private void handleSystemVMStop() {
+            TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+            try {
+                if (this.mode.equalsIgnoreCase("Stop")) {
+                    txn.start();
+                    MockHost host = _mockHostDao.findByVmId(this.vmId);
+                    if (host != null) {
+                        String guid = host.getGuid();
+                        if (guid != null) {
+                            AgentResourceBase res = _resources.get(guid);
+                            if (res != null) {
+                                res.stop();
+                                _resources.remove(guid);
+                            }
+                        }
+                    }
+                    txn.commit();
+                    return;
+                }
+            } catch (Exception ex) {
+                txn.rollback();
+                throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
+            } finally {
+                txn.close();
+                txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+                txn.close();
+            }
+
+            //stop ssvm agent
+            HostVO host = hostDao.findByGuid(this.guid);
+            if (host != null) {
+                try {
+                    _resourceMgr.deleteHost(host.getId(), true, true);
+                } catch (Exception e) {
+                    s_logger.debug("Failed to delete host: ", e);
+                }
+            }
+        }
+
+        @Override
+        @DB
+        public void run() {
+            CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount());
+            if (this.mode.equalsIgnoreCase("Stop")) {
+                handleSystemVMStop();
+                CallContext.unregister();
+                return;
+            }
+
+            String resource = null;
+            if (vmType.equalsIgnoreCase("secstorage")) {
+                resource = "com.cloud.agent.AgentStorageResource";
+            }
+            MockHostVO mockHost = new MockHostVO();
+            mockHost.setDataCenterId(this.dcId);
+            mockHost.setPodId(this.podId);
+            mockHost.setCpuCount(DEFAULT_HOST_CPU_CORES);
+            mockHost.setCpuSpeed(DEFAULT_HOST_SPEED_MHZ);
+            mockHost.setMemorySize(DEFAULT_HOST_MEM_SIZE);
+            mockHost.setGuid(this.guid);
+            mockHost.setName(name);
+            mockHost.setPrivateIpAddress(this.privateIpAddress);
+            mockHost.setPublicIpAddress(this.privateIpAddress);
+            mockHost.setStorageIpAddress(this.privateIpAddress);
+            mockHost.setPrivateMacAddress(this.privateMacAddress);
+            mockHost.setPublicMacAddress(this.privateMacAddress);
+            mockHost.setStorageMacAddress(this.privateMacAddress);
+            mockHost.setVersion(this.getClass().getPackage().getImplementationVersion());
+            mockHost.setResource(resource);
+            mockHost.setVmId(vmId);
+            TransactionLegacy simtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+            try {
+                simtxn.start();
+                mockHost = _mockHostDao.persist(mockHost);
+                simtxn.commit();
+            } catch (Exception ex) {
+                simtxn.rollback();
+                throw new CloudRuntimeException("Unable to persist host " + mockHost.getGuid() + " due to " + ex.getMessage(), ex);
+            } finally {
+                simtxn.close();
+                simtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+                simtxn.close();
+            }
+
+            if (vmType.equalsIgnoreCase("secstorage")) {
+                AgentStorageResource storageResource = new AgentStorageResource();
+                try {
+                    Map<String, Object> params = new HashMap<String, Object>();
+                    Map<String, String> details = new HashMap<String, String>();
+                    params.put("guid", this.guid);
+                    details.put("guid", this.guid);
+                    storageResource.configure("secondaryStorage", params);
+                    storageResource.start();
+                    _resources.put(this.guid, storageResource);
+                    discoverer.setResource(storageResource);
+                    SimulatorAddSecondaryAgent cmd = new SimulatorAddSecondaryAgent("sim://" + this.guid, this.dcId);
+                    try {
+                        _resourceMgr.discoverHosts(cmd);
+                    } catch (DiscoveryException e) {
+                        s_logger.debug("Failed to discover host: " + e.toString());
+                        CallContext.unregister();
+                        return;
+                    }
+                } catch (ConfigurationException e) {
+                    s_logger.debug("Failed to load secondary storage resource: " + e.toString());
+                    CallContext.unregister();
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public MockHost getHost(String guid) {
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            txn.start();
+            MockHost _host = _mockHostDao.findByGuid(guid);
+            txn.commit();
+            if (_host != null) {
+                return _host;
+            } else {
+                s_logger.error("Host with guid " + guid + " was not found");
+                return null;
+            }
+        } catch (Exception ex) {
+            txn.rollback();
+            throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex);
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+    }
+
+    @Override
+    public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) {
+        String hostGuid = cmd.getHostGuid();
+        MockHost host = null;
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            txn.start();
+            host = _mockHostDao.findByGuid(hostGuid);
+            txn.commit();
+            if (host == null) {
+                return null;
+            }
+        } catch (Exception ex) {
+            txn.rollback();
+            throw new CloudRuntimeException("Unable to get host " + hostGuid + " due to " + ex.getMessage(), ex);
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+
+        TransactionLegacy vmtxn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            vmtxn.start();
+            List<MockVMVO> vms = _mockVmDao.findByHostId(host.getId());
+            vmtxn.commit();
+            double usedMem = 0.0;
+            double usedCpu = 0.0;
+            for (MockVMVO vm : vms) {
+                usedMem += vm.getMemory();
+                usedCpu += vm.getCpu();
+            }
+
+            HostStatsEntry hostStats = new HostStatsEntry();
+            hostStats.setTotalMemoryKBs(host.getMemorySize());
+            hostStats.setFreeMemoryKBs(host.getMemorySize() - usedMem);
+            hostStats.setNetworkReadKBs(32768);
+            hostStats.setNetworkWriteKBs(16384);
+            hostStats.setCpuUtilization(usedCpu / (host.getCpuCount() * host.getCpuSpeed()));
+            hostStats.setEntityType("simulator-host");
+            hostStats.setHostId(cmd.getHostId());
+            return new GetHostStatsAnswer(cmd, hostStats);
+        } catch (Exception ex) {
+            vmtxn.rollback();
+            throw new CloudRuntimeException("Unable to get Vms on host " + host.getGuid() + " due to " + ex.getMessage(), ex);
+        } finally {
+            vmtxn.close();
+            vmtxn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            vmtxn.close();
+        }
+    }
+
+    @Override
+    public Answer checkHealth(CheckHealthCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer pingTest(PingTestCommand cmd) {
+        return new Answer(cmd);
+    }
+
+    @Override
+    public Answer setupKeyStore(SetupKeyStoreCommand cmd) {
+        return new SetupKeystoreAnswer(
+                "-----BEGIN CERTIFICATE REQUEST-----\n" +
+                "MIIBHjCByQIBADBkMQswCQYDVQQGEwJJTjELMAkGA1UECAwCSFIxETAPBgNVBAcM\n" +
+                "CEd1cnVncmFtMQ8wDQYDVQQKDAZBcGFjaGUxEzARBgNVBAsMCkNsb3VkU3RhY2sx\n" +
+                "DzANBgNVBAMMBnYtMS1WTTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQD46KFWKYrJ\n" +
+                "F43Y1oqWUfrl4mj4Qm05Bgsi6nuigZv7ufiAKK0nO4iJKdRa2hFMUvBi2/bU3IyY\n" +
+                "Nvg7cdJsn4K9AgMBAAGgADANBgkqhkiG9w0BAQUFAANBAIta9glu/ZSjA/ncyXix\n" +
+                "yDOyAKmXXxsRIsdrEuIzakUuJS7C8IG0FjUbDyIaiwWQa5x+Lt4oMqCmpNqRzaGP\n" +
+                "fOo=\n" + "-----END CERTIFICATE REQUEST-----");
+    }
+
+    @Override
+    public Answer setupCertificate(SetupCertificateCommand cmd) {
+        return new SetupCertificateAnswer(true);
+    }
+
+
+    @Override
+    public boolean start() {
+        for (Discoverer discoverer : discoverers) {
+            if (discoverer instanceof SimulatorSecondaryDiscoverer) {
+                this.discoverer = (SimulatorSecondaryDiscoverer)discoverer;
+                break;
+            }
+        }
+
+        if (this.discoverer == null) {
+            throw new IllegalStateException("Failed to find SimulatorSecondaryDiscoverer");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return this.getClass().getSimpleName();
+    }
+
+    @Override
+    public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) {
+        return new MaintainAnswer(cmd);
+    }
+
+    @Override
+    public Answer checkNetworkCommand(CheckNetworkCommand cmd) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking if network name setup is done on the resource");
+        }
+        return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done");
+    }
+
+    @Override
+    public Answer runDiagnostics(final DiagnosticsCommand cmd) {
+        final String vmInstance = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String[] args = cmd.getSrciptArguments().split(" ");
+        final String mockAnswer = String.format("%s %s executed in %s &&  && 0", args[0].toUpperCase(), args[1], vmInstance);
+        return new DiagnosticsAnswer(cmd, true, mockAnswer);
+    }
+
+    public List<Discoverer> getDiscoverers() {
+        return discoverers;
+    }
+
+    @Inject
+    public void setDiscoverers(List<Discoverer> discoverers) {
+        this.discoverers = discoverers;
+    }
+}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockNetworkManager.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockNetworkManager.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockNetworkManager.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockNetworkManager.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockNetworkManagerImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockNetworkManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockNetworkManagerImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockNetworkManagerImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockStorageManager.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockStorageManager.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockStorageManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockStorageManagerImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockVmManager.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockVmManager.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockVmManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/MockVmManagerImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorInfo.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorInfo.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorManager.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorManager.java
diff --git a/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorManagerImpl.java
new file mode 100644
index 0000000..29ad3cc
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/main/java/com/cloud/agent/manager/SimulatorManagerImpl.java
@@ -0,0 +1,582 @@
+// 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.manager;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.google.gson.Gson;
+import com.google.gson.stream.JsonReader;
+
+import org.apache.cloudstack.ca.SetupCertificateCommand;
+import org.apache.cloudstack.ca.SetupKeyStoreCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.cloudstack.storage.command.UploadStatusCommand;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.CleanupNetworkRulesCmd;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVMSnapshotCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.DeleteVMSnapshotCommand;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.GetVolumeStatsCommand;
+import com.cloud.agent.api.HandleConfigDriveIsoCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.ReplugNicCommand;
+import com.cloud.agent.api.RevertToVMSnapshotCommand;
+import com.cloud.agent.api.ScaleVmCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
+import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.GetRouterAlertsCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetMonitorServiceCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.SetStaticRouteCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.api.commands.CleanupSimulatorMockCmd;
+import com.cloud.api.commands.ConfigureSimulatorCmd;
+import com.cloud.api.commands.ConfigureSimulatorHAProviderState;
+import com.cloud.api.commands.ListSimulatorHAStateTransitions;
+import com.cloud.api.commands.QuerySimulatorMockCmd;
+import com.cloud.resource.SimulatorStorageProcessor;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.simulator.MockConfigurationVO;
+import com.cloud.simulator.MockHost;
+import com.cloud.simulator.MockVMVO;
+import com.cloud.simulator.dao.MockConfigurationDao;
+import com.cloud.simulator.dao.MockHostDao;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine.PowerState;
+
+@Component
+public class SimulatorManagerImpl extends ManagerBase implements SimulatorManager, PluggableService {
+    private static final Logger s_logger = Logger.getLogger(SimulatorManagerImpl.class);
+    private static final Gson s_gson = GsonHelper.getGson();
+    @Inject
+    MockVmManager _mockVmMgr;
+    @Inject
+    MockStorageManager _mockStorageMgr;
+    @Inject
+    MockAgentManager _mockAgentMgr;
+    @Inject
+    MockNetworkManager _mockNetworkMgr;
+    @Inject
+    MockConfigurationDao _mockConfigDao;
+    @Inject
+    MockHostDao _mockHost = null;
+    protected StorageSubsystemCommandHandler storageHandler;
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        final SimulatorStorageProcessor processor = new SimulatorStorageProcessor(this);
+        storageHandler = new StorageSubsystemCommandHandlerBase(processor);
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return this.getClass().getSimpleName();
+    }
+
+    @Override
+    public MockVmManager getVmMgr() {
+        return _mockVmMgr;
+    }
+
+    @Override
+    public MockStorageManager getStorageMgr() {
+        return _mockStorageMgr;
+    }
+
+    @Override
+    public MockAgentManager getAgentMgr() {
+        return _mockAgentMgr;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(ConfigureSimulatorCmd.class);
+        cmdList.add(QuerySimulatorMockCmd.class);
+        cmdList.add(CleanupSimulatorMockCmd.class);
+        cmdList.add(ConfigureSimulatorHAProviderState.class);
+        cmdList.add(ListSimulatorHAStateTransitions.class);
+        return cmdList;
+    }
+
+    @DB
+    @Override
+    public Answer simulate(final Command cmd, final String hostGuid) {
+        s_logger.debug("Simulate command " + cmd);
+        Answer answer = null;
+        Exception exception = null;
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            final MockHost host = _mockHost.findByGuid(hostGuid);
+            String cmdName = cmd.toString();
+            final int index = cmdName.lastIndexOf(".");
+            if (index != -1) {
+                cmdName = cmdName.substring(index + 1);
+            }
+
+            final SimulatorInfo info = new SimulatorInfo();
+            info.setHostUuid(hostGuid);
+
+            final MockConfigurationVO config = _mockConfigDao.findByNameBottomUP(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), cmdName);
+            if (config != null && (config.getCount() == null || config.getCount().intValue() > 0)) {
+                final Map<String, String> configParameters = config.getParameters();
+                for (final Map.Entry<String, String> entry : configParameters.entrySet()) {
+                    if (entry.getKey().equalsIgnoreCase("enabled")) {
+                        info.setEnabled(Boolean.parseBoolean(entry.getValue()));
+                    } else if (entry.getKey().equalsIgnoreCase("timeout")) {
+                        try {
+                            info.setTimeout(Integer.valueOf(entry.getValue()));
+                        } catch (final NumberFormatException e) {
+                            s_logger.debug("invalid timeout parameter: " + e.toString());
+                        }
+                    }
+
+                    if (entry.getKey().equalsIgnoreCase("wait")) {
+                        try {
+                            final int wait = Integer.valueOf(entry.getValue());
+                            Thread.sleep(wait);
+                        } catch (final NumberFormatException e) {
+                            s_logger.debug("invalid wait parameter: " + e.toString());
+                        } catch (final InterruptedException e) {
+                            s_logger.debug("thread is interrupted: " + e.toString());
+                        }
+                    }
+
+                    if (entry.getKey().equalsIgnoreCase("result")) {
+                        final String value = entry.getValue();
+                        if (value.equalsIgnoreCase("fail")) {
+                            answer = new Answer(cmd, false, "Simulated failure");
+                        } else if (value.equalsIgnoreCase("fault")) {
+                            exception = new Exception("Simulated fault");
+                        }
+                    }
+                }
+
+                if (exception != null) {
+                    throw exception;
+                }
+
+                if (answer == null) {
+                    final String message = config.getJsonResponse();
+                    if (message != null) {
+                        // json response looks like {"<Type>":....}
+                        final String objectType = message.split(":")[0].substring(2).replace("\"", "");
+                        final String objectData = message.substring(message.indexOf(':') + 1, message.length() - 1);
+                        if (objectType != null) {
+                            Class<?> clz = null;
+                            try {
+                                clz = Class.forName(objectType);
+                            } catch (final ClassNotFoundException e) {
+                            }
+                            if (clz != null) {
+                                final StringReader reader = new StringReader(objectData);
+                                final JsonReader jsonReader = new JsonReader(reader);
+                                jsonReader.setLenient(true);
+                                answer = (Answer)s_gson.fromJson(jsonReader, clz);
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (answer == null) {
+                if (cmd instanceof GetHostStatsCommand) {
+                    answer = _mockAgentMgr.getHostStatistic((GetHostStatsCommand)cmd);
+                } else if (cmd instanceof CheckHealthCommand) {
+                    answer = _mockAgentMgr.checkHealth((CheckHealthCommand)cmd);
+                } else if (cmd instanceof PingTestCommand) {
+                    answer = _mockAgentMgr.pingTest((PingTestCommand)cmd);
+                } else if (cmd instanceof SetupKeyStoreCommand) {
+                    answer = _mockAgentMgr.setupKeyStore((SetupKeyStoreCommand) cmd);
+                }else if (cmd instanceof DiagnosticsCommand) {
+                    answer = _mockAgentMgr.runDiagnostics((DiagnosticsCommand)cmd);
+                } else if (cmd instanceof SetupCertificateCommand) {
+                    answer = _mockAgentMgr.setupCertificate((SetupCertificateCommand)cmd);
+                } else if (cmd instanceof PrepareForMigrationCommand) {
+                    answer = _mockVmMgr.prepareForMigrate((PrepareForMigrationCommand)cmd);
+                } else if (cmd instanceof MigrateCommand) {
+                    answer = _mockVmMgr.migrate((MigrateCommand)cmd, info);
+                } else if (cmd instanceof StartCommand) {
+                    answer = _mockVmMgr.startVM((StartCommand)cmd, info);
+                } else if (cmd instanceof CheckSshCommand) {
+                    answer = _mockVmMgr.checkSshCommand((CheckSshCommand)cmd);
+                } else if (cmd instanceof CheckVirtualMachineCommand) {
+                    answer = _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd);
+                } else if (cmd instanceof SetStaticNatRulesCommand) {
+                    answer = _mockNetworkMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd);
+                } else if (cmd instanceof SetFirewallRulesCommand) {
+                    answer = _mockNetworkMgr.SetFirewallRules((SetFirewallRulesCommand)cmd);
+                } else if (cmd instanceof SetPortForwardingRulesCommand) {
+                    answer = _mockNetworkMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd);
+                } else if (cmd instanceof NetworkUsageCommand) {
+                    answer = _mockNetworkMgr.getNetworkUsage((NetworkUsageCommand)cmd);
+                } else if (cmd instanceof IpAssocCommand) {
+                    answer = _mockNetworkMgr.IpAssoc((IpAssocCommand)cmd);
+                } else if (cmd instanceof LoadBalancerConfigCommand) {
+                    answer = _mockNetworkMgr.LoadBalancerConfig((LoadBalancerConfigCommand)cmd);
+                } else if (cmd instanceof DhcpEntryCommand) {
+                    answer = _mockNetworkMgr.AddDhcpEntry((DhcpEntryCommand)cmd);
+                } else if (cmd instanceof VmDataCommand) {
+                    answer = _mockVmMgr.setVmData((VmDataCommand)cmd);
+                } else if (cmd instanceof CleanupNetworkRulesCmd) {
+                    answer = _mockVmMgr.cleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info);
+                } else if (cmd instanceof CheckNetworkCommand) {
+                    answer = _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand)cmd);
+                } else if (cmd instanceof StopCommand) {
+                    answer = _mockVmMgr.stopVM((StopCommand)cmd);
+                } else if (cmd instanceof RebootCommand) {
+                    answer = _mockVmMgr.rebootVM((RebootCommand)cmd);
+                } else if (cmd instanceof GetVncPortCommand) {
+                    answer = _mockVmMgr.getVncPort((GetVncPortCommand)cmd);
+                } else if (cmd instanceof CheckConsoleProxyLoadCommand) {
+                    answer = _mockVmMgr.checkConsoleProxyLoad((CheckConsoleProxyLoadCommand)cmd);
+                } else if (cmd instanceof WatchConsoleProxyLoadCommand) {
+                    answer = _mockVmMgr.watchConsoleProxyLoad((WatchConsoleProxyLoadCommand)cmd);
+                } else if (cmd instanceof SecurityGroupRulesCmd) {
+                    answer = _mockVmMgr.addSecurityGroupRules((SecurityGroupRulesCmd)cmd, info);
+                } else if (cmd instanceof SavePasswordCommand) {
+                    answer = _mockVmMgr.savePassword((SavePasswordCommand)cmd);
+                } else if (cmd instanceof PrimaryStorageDownloadCommand) {
+                    answer = _mockStorageMgr.primaryStorageDownload((PrimaryStorageDownloadCommand)cmd);
+                } else if (cmd instanceof CreateCommand) {
+                    answer = _mockStorageMgr.createVolume((CreateCommand)cmd);
+                } else if (cmd instanceof AttachIsoCommand) {
+                    answer = _mockStorageMgr.AttachIso((AttachIsoCommand)cmd);
+                } else if (cmd instanceof DeleteStoragePoolCommand) {
+                    answer = _mockStorageMgr.DeleteStoragePool((DeleteStoragePoolCommand)cmd);
+                } else if (cmd instanceof ModifyStoragePoolCommand) {
+                    answer = _mockStorageMgr.ModifyStoragePool((ModifyStoragePoolCommand)cmd);
+                } else if (cmd instanceof CreateStoragePoolCommand) {
+                    answer = _mockStorageMgr.CreateStoragePool((CreateStoragePoolCommand)cmd);
+                } else if (cmd instanceof SecStorageSetupCommand) {
+                    answer = _mockStorageMgr.SecStorageSetup((SecStorageSetupCommand)cmd);
+                } else if (cmd instanceof ListTemplateCommand) {
+                    answer = _mockStorageMgr.ListTemplates((ListTemplateCommand)cmd);
+                } else if (cmd instanceof ListVolumeCommand) {
+                    answer = _mockStorageMgr.ListVolumes((ListVolumeCommand)cmd);
+                } else if (cmd instanceof DestroyCommand) {
+                    answer = _mockStorageMgr.Destroy((DestroyCommand)cmd);
+                } else if (cmd instanceof DownloadProgressCommand) {
+                    answer = _mockStorageMgr.DownloadProcess((DownloadProgressCommand)cmd);
+                } else if (cmd instanceof DownloadCommand) {
+                    answer = _mockStorageMgr.Download((DownloadCommand)cmd);
+                } else if (cmd instanceof GetStorageStatsCommand) {
+                    answer = _mockStorageMgr.GetStorageStats((GetStorageStatsCommand)cmd);
+                } else if (cmd instanceof GetVolumeStatsCommand) {
+                    answer = _mockStorageMgr.getVolumeStats((GetVolumeStatsCommand)cmd);
+                } else if (cmd instanceof ManageSnapshotCommand) {
+                    answer = _mockStorageMgr.ManageSnapshot((ManageSnapshotCommand)cmd);
+                } else if (cmd instanceof BackupSnapshotCommand) {
+                    answer = _mockStorageMgr.BackupSnapshot((BackupSnapshotCommand)cmd, info);
+                } else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
+                    answer = _mockStorageMgr.CreateVolumeFromSnapshot((CreateVolumeFromSnapshotCommand)cmd);
+                } else if (cmd instanceof DeleteCommand) {
+                    answer = _mockStorageMgr.Delete((DeleteCommand)cmd);
+                } else if (cmd instanceof SecStorageVMSetupCommand) {
+                    answer = _mockStorageMgr.SecStorageVMSetup((SecStorageVMSetupCommand)cmd);
+                } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
+                    answer = _mockStorageMgr.CreatePrivateTemplateFromSnapshot((CreatePrivateTemplateFromSnapshotCommand)cmd);
+                } else if (cmd instanceof ComputeChecksumCommand) {
+                    answer = _mockStorageMgr.ComputeChecksum((ComputeChecksumCommand)cmd);
+                } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
+                    answer = _mockStorageMgr.CreatePrivateTemplateFromVolume((CreatePrivateTemplateFromVolumeCommand)cmd);
+                } else if (cmd instanceof UploadStatusCommand) {
+                    answer = _mockStorageMgr.getUploadStatus((UploadStatusCommand)cmd);
+                } else if (cmd instanceof MaintainCommand) {
+                    answer = _mockAgentMgr.maintain((MaintainCommand)cmd);
+                } else if (cmd instanceof GetVmStatsCommand) {
+                    answer = _mockVmMgr.getVmStats((GetVmStatsCommand)cmd);
+                } else if (cmd instanceof CheckRouterCommand) {
+                    answer = _mockVmMgr.checkRouter((CheckRouterCommand)cmd);
+                } else if (cmd instanceof GetDomRVersionCmd) {
+                    answer = _mockVmMgr.getDomRVersion((GetDomRVersionCmd)cmd);
+                } else if (cmd instanceof CopyVolumeCommand) {
+                    answer = _mockStorageMgr.CopyVolume((CopyVolumeCommand)cmd);
+                } else if (cmd instanceof PlugNicCommand) {
+                    answer = _mockNetworkMgr.plugNic((PlugNicCommand)cmd);
+                } else if (cmd instanceof UnPlugNicCommand) {
+                    answer = _mockNetworkMgr.unplugNic((UnPlugNicCommand)cmd);
+                } else if (cmd instanceof ReplugNicCommand) {
+                    answer = _mockNetworkMgr.replugNic((ReplugNicCommand)cmd);
+                } else if (cmd instanceof IpAssocVpcCommand) {
+                    answer = _mockNetworkMgr.ipAssoc((IpAssocVpcCommand)cmd);
+                } else if (cmd instanceof SetSourceNatCommand) {
+                    answer = _mockNetworkMgr.setSourceNat((SetSourceNatCommand)cmd);
+                } else if (cmd instanceof SetNetworkACLCommand) {
+                    answer = _mockNetworkMgr.setNetworkAcl((SetNetworkACLCommand)cmd);
+                } else if (cmd instanceof SetupGuestNetworkCommand) {
+                    answer = _mockNetworkMgr.setUpGuestNetwork((SetupGuestNetworkCommand)cmd);
+                } else if (cmd instanceof SetPortForwardingRulesVpcCommand) {
+                    answer = _mockNetworkMgr.setVpcPortForwards((SetPortForwardingRulesVpcCommand)cmd);
+                } else if (cmd instanceof SetStaticNatRulesCommand) {
+                    answer = _mockNetworkMgr.setVPCStaticNatRules((SetStaticNatRulesCommand)cmd);
+                } else if (cmd instanceof SetStaticRouteCommand) {
+                    answer = _mockNetworkMgr.setStaticRoute((SetStaticRouteCommand)cmd);
+                } else if (cmd instanceof Site2SiteVpnCfgCommand) {
+                    answer = _mockNetworkMgr.siteToSiteVpn((Site2SiteVpnCfgCommand)cmd);
+                } else if (cmd instanceof CheckS2SVpnConnectionsCommand) {
+                    answer = _mockNetworkMgr.checkSiteToSiteVpnConnection((CheckS2SVpnConnectionsCommand)cmd);
+                } else if (cmd instanceof CreateVMSnapshotCommand) {
+                    answer = _mockVmMgr.createVmSnapshot((CreateVMSnapshotCommand)cmd);
+                } else if (cmd instanceof DeleteVMSnapshotCommand) {
+                    answer = _mockVmMgr.deleteVmSnapshot((DeleteVMSnapshotCommand)cmd);
+                } else if (cmd instanceof RevertToVMSnapshotCommand) {
+                    answer = _mockVmMgr.revertVmSnapshot((RevertToVMSnapshotCommand)cmd);
+                } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) {
+                    answer = _mockVmMgr.plugSecondaryIp((NetworkRulesVmSecondaryIpCommand)cmd);
+                } else if (cmd instanceof ScaleVmCommand) {
+                    answer = _mockVmMgr.scaleVm((ScaleVmCommand)cmd);
+                } else if (cmd instanceof PvlanSetupCommand) {
+                    answer = _mockNetworkMgr.setupPVLAN((PvlanSetupCommand)cmd);
+                } else if (cmd instanceof StorageSubSystemCommand) {
+                    answer = storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
+                } else if (cmd instanceof FenceCommand) {
+                    answer = _mockVmMgr.fence((FenceCommand)cmd);
+                } else if (cmd instanceof HandleConfigDriveIsoCommand) {
+                    answer = _mockStorageMgr.handleConfigDriveIso((HandleConfigDriveIsoCommand)cmd);
+                } else if (cmd instanceof GetRouterAlertsCommand
+                        || cmd instanceof VpnUsersCfgCommand
+                        || cmd instanceof RemoteAccessVpnCfgCommand
+                        || cmd instanceof SetMonitorServiceCommand
+                        || cmd instanceof AggregationControlCommand
+                        || cmd instanceof SecStorageFirewallCfgCommand) {
+                    answer = new Answer(cmd);
+                } else {
+                    s_logger.error("Simulator does not implement command of type " + cmd.toString());
+                    answer = Answer.createUnsupportedCommandAnswer(cmd);
+                }
+            }
+
+            if (config != null && config.getCount() != null && config.getCount().intValue() > 0) {
+                if (answer != null) {
+                    config.setCount(config.getCount().intValue() - 1);
+                    _mockConfigDao.update(config.getId(), config);
+                }
+            }
+
+            s_logger.debug("Finished simulate command " + cmd);
+
+            return answer;
+        } catch (final Exception e) {
+            s_logger.error("Failed execute cmd: ", e);
+            txn.rollback();
+            return new Answer(cmd, false, e.toString());
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+    }
+
+    @Override
+    public StoragePoolInfo getLocalStorage(final String hostGuid) {
+        return _mockStorageMgr.getLocalStorage(hostGuid);
+    }
+
+    @Override
+    public Map<String, PowerState> getVmStates(final String hostGuid) {
+        return _mockVmMgr.getVmStates(hostGuid);
+    }
+
+    @Override
+    public Map<String, MockVMVO> getVms(final String hostGuid) {
+        return _mockVmMgr.getVms(hostGuid);
+    }
+
+    @Override
+    public HashMap<String, Pair<Long, Long>> syncNetworkGroups(final String hostGuid) {
+        final SimulatorInfo info = new SimulatorInfo();
+        info.setHostUuid(hostGuid);
+        return _mockVmMgr.syncNetworkGroups(info);
+    }
+
+    @Override
+    public Long configureSimulator(final Long zoneId, final Long podId, final Long clusterId, final Long hostId, final String command, final String values, final Integer count, final String jsonResponse) {
+        Long id = null;
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            txn.start();
+            MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command);
+            if (config == null) {
+                config = new MockConfigurationVO();
+                config.setClusterId(clusterId);
+                config.setDataCenterId(zoneId);
+                config.setPodId(podId);
+                config.setHostId(hostId);
+                config.setName(command);
+                config.setValues(values);
+                config.setCount(count);
+                config.setJsonResponse(jsonResponse);
+                config = _mockConfigDao.persist(config);
+                txn.commit();
+            } else {
+                config.setValues(values);
+                config.setCount(count);
+                config.setJsonResponse(jsonResponse);
+                _mockConfigDao.update(config.getId(), config);
+                txn.commit();
+            }
+            id = config.getId();
+        } catch (final Exception ex) {
+            txn.rollback();
+            throw new CloudRuntimeException("Unable to configure simulator mock because of " + ex.getMessage(), ex);
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+        return id;
+    }
+
+    @Override
+    public MockConfigurationVO querySimulatorMock(final Long id) {
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            txn.start();
+            return _mockConfigDao.findById(id);
+        } catch (final Exception ex) {
+            txn.rollback();
+            throw new CloudRuntimeException("Unable to query simulator mock because of " + ex.getMessage(), ex);
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+    }
+
+    @Override
+    public boolean clearSimulatorMock(final Long id) {
+        boolean status = false;
+        TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.SIMULATOR_DB);
+        try {
+            txn.start();
+            final MockConfigurationVO config = _mockConfigDao.findById(id);
+            if (config != null) {
+                config.setRemoved(new Date());
+                _mockConfigDao.update(config.getId(), config);
+                status = true;
+                txn.commit();
+            }
+        } catch (final Exception ex) {
+            txn.rollback();
+            throw new CloudRuntimeException("Unable to cleanup simulator mock because of " + ex.getMessage(), ex);
+        } finally {
+            txn.close();
+            txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+        }
+        return status;
+    }
+
+    @Override
+    public MockConfigurationDao getMockConfigurationDao() {
+        return _mockConfigDao;
+    }
+}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/CleanupSimulatorMockCmd.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/CleanupSimulatorMockCmd.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/CleanupSimulatorMockCmd.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/CleanupSimulatorMockCmd.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ConfigureSimulatorCmd.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorCmd.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ConfigureSimulatorCmd.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorHAProviderState.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ConfigureSimulatorHAProviderState.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulatorHAProviderState.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ConfigureSimulatorHAProviderState.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/ListSimulatorHAStateTransitions.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ListSimulatorHAStateTransitions.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/ListSimulatorHAStateTransitions.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/ListSimulatorHAStateTransitions.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/QuerySimulatorMockCmd.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/QuerySimulatorMockCmd.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/QuerySimulatorMockCmd.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/QuerySimulatorMockCmd.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/commands/SimulatorAddSecondaryAgent.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/SimulatorAddSecondaryAgent.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/commands/SimulatorAddSecondaryAgent.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/commands/SimulatorAddSecondaryAgent.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/response/MockResponse.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/response/MockResponse.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/response/MockResponse.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/response/MockResponse.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/api/response/SimulatorHAStateResponse.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/api/response/SimulatorHAStateResponse.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/api/response/SimulatorHAStateResponse.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/api/response/SimulatorHAStateResponse.java
diff --git a/plugins/hypervisors/simulator/src/main/java/com/cloud/ha/SimulatorFencer.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/ha/SimulatorFencer.java
new file mode 100644
index 0000000..c776edf
--- /dev/null
+++ b/plugins/hypervisors/simulator/src/main/java/com/cloud/ha/SimulatorFencer.java
@@ -0,0 +1,114 @@
+// 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.ha;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+public class SimulatorFencer extends AdapterBase implements FenceBuilder {
+    private static final Logger s_logger = Logger.getLogger(SimulatorFencer.class);
+
+    @Inject HostDao _hostDao;
+    @Inject AgentManager _agentMgr;
+    @Inject ResourceManager _resourceMgr;
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public SimulatorFencer() {
+        super();
+    }
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.Simulator) {
+            s_logger.debug("Don't know how to fence non simulator hosts " + host.getHypervisorType());
+            return null;
+        }
+
+        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() == HypervisorType.Simulator) {
+                if( h.getStatus() != Status.Up ) {
+                    continue;
+                }
+                if( h.getId() == host.getId() ) {
+                    continue;
+                }
+                FenceAnswer answer = null;
+                try {
+                    answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
+                } catch (AgentUnavailableException e) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    }
+                    continue;
+                } catch (OperationTimedoutException e) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    }
+                    continue;
+                }
+                if (answer != null && answer.getResult()) {
+                    return true;
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
+        }
+
+        return false;
+    }
+}
diff --git a/plugins/hypervisors/simulator/src/com/cloud/ha/SimulatorInvestigator.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/ha/SimulatorInvestigator.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/ha/SimulatorInvestigator.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/ha/SimulatorInvestigator.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentResourceBase.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentResourceBase.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentRoutingResource.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentRoutingResource.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentStorageResource.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/AgentStorageResource.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorDiscoverer.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorSecondaryDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorSecondaryDiscoverer.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorStorageProcessor.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockConfigurationVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockConfigurationVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHost.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockHost.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockHost.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockHost.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHostVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockHostVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockHostVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockHostVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockSecStorageVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockSecStorageVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecurityRulesVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockSecurityRulesVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecurityRulesVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockSecurityRulesVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockStoragePoolVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockStoragePoolVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVMVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVMVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVm.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVm.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVolumeVO.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/MockVolumeVO.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorGuru.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/SimulatorGuru.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorGuru.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/SimulatorGuru.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorRuntimeException.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/SimulatorRuntimeException.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorRuntimeException.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/SimulatorRuntimeException.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockConfigurationDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockConfigurationDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockConfigurationDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockConfigurationDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockHostDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockHostDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockHostDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockHostDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockHostDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockHostDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockHostDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockHostDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecStorageDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecStorageDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecStorageDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecStorageDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecurityRulesDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecurityRulesDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockStoragePoolDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockStoragePoolDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVMDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVMDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVMDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVMDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVMDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVMDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVMDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVMDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDao.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVolumeDao.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDao.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVolumeDao.java
diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVolumeDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java
rename to plugins/hypervisors/simulator/src/main/java/com/cloud/simulator/dao/MockVolumeDaoImpl.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/ha/SimulatorHAProvider.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/ha/SimulatorHAProvider.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/ha/SimulatorHAProvider.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/ha/SimulatorHAProvider.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/ha/SimulatorHAState.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/ha/SimulatorHAState.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/ha/SimulatorHAState.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/ha/SimulatorHAState.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/driver/SimulatorImageStoreDriverImpl.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/lifecycle/SimulatorImageStoreLifeCycleImpl.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SimulatorImageStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/lifecycle/SimulatorImageStoreLifeCycleImpl.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SimulatorImageStoreLifeCycleImpl.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/provider/SimulatorImageStoreProviderImpl.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/provider/SimulatorImageStoreProviderImpl.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/datastore/provider/SimulatorImageStoreProviderImpl.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/datastore/provider/SimulatorImageStoreProviderImpl.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java
diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/resource/SimulatorSecondaryStorageResource.java b/plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/resource/SimulatorSecondaryStorageResource.java
similarity index 100%
rename from plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/resource/SimulatorSecondaryStorageResource.java
rename to plugins/hypervisors/simulator/src/main/java/org/apache/cloudstack/storage/resource/SimulatorSecondaryStorageResource.java
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/core/spring-simulator-core-context.xml
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/module.properties b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/module.properties
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-compute/module.properties
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-compute/spring-simulator-compute-context.xml
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/module.properties b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/module.properties
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-discoverer/module.properties
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-discoverer/spring-simulator-discover-context.xml
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/module.properties b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-storage/module.properties
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/module.properties
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-storage/module.properties
diff --git a/plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml b/plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml
similarity index 100%
rename from plugins/hypervisors/simulator/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml
rename to plugins/hypervisors/simulator/src/main/resources/META-INF/cloudstack/simulator-storage/spring-simulator-storage-context.xml
diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml
old mode 100755
new mode 100644
index 4f1f136..166abd6
--- a/plugins/hypervisors/ucs/pom.xml
+++ b/plugins/hypervisors/ucs/pom.xml
@@ -1,39 +1,44 @@
-<!-- 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
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
     http://maven.apache.org/xsd/maven-4.0.0.xsd"
-  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <artifactId>cloud-plugin-hypervisor-ucs</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor UCS</name>
-  <url>http://maven.apache.org</url>
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <artifactId>cloud-plugin-hypervisor-ucs</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor UCS</name>
+    <url>http://maven.apache.org</url>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDao.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeDao.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDao.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeDao.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeDaoImpl.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeDaoImpl.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeVO.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeVO.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsBladeVO.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsBladeVO.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerDao.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDao.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerDao.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerDaoImpl.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerDaoImpl.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerVO.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerVO.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/database/UcsManagerVO.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/database/UcsManagerVO.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/StringTemplate.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/StringTemplate.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/manager/StringTemplate.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/StringTemplate.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsCommands.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsCommands.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsHttpClient.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsHttpClient.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsManager.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsManager.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/manager/UcsManagerImpl.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/ComputeBlade.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/ComputeBlade.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/structure/ComputeBlade.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/ComputeBlade.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsCookie.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/UcsCookie.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsCookie.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/UcsCookie.java
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsProfile.java b/plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/UcsProfile.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsProfile.java
rename to plugins/hypervisors/ucs/src/main/java/com/cloud/ucs/structure/UcsProfile.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/AddUcsManagerCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/AddUcsManagerCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/AddUcsManagerCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/AddUcsManagerCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/AssociateUcsProfileToBladeCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/AssociateUcsProfileToBladeCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/AssociateUcsProfileToBladeCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/AssociateUcsProfileToBladeCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DeleteUcsManagerCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/DeleteUcsManagerCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DeleteUcsManagerCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/DeleteUcsManagerCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsBladeCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsBladeCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsBladeCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsBladeCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsManagerCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsManagerCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsManagerCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsManagerCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsProfileCmd.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsProfileCmd.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsProfileCmd.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/ListUcsProfileCmd.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsBladeResponse.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsBladeResponse.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsBladeResponse.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsBladeResponse.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsManagerResponse.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsManagerResponse.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsManagerResponse.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsManagerResponse.java
diff --git a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsProfileResponse.java b/plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsProfileResponse.java
similarity index 100%
rename from plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsProfileResponse.java
rename to plugins/hypervisors/ucs/src/main/java/org/apache/cloudstack/api/response/UcsProfileResponse.java
diff --git a/plugins/hypervisors/ucs/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml b/plugins/hypervisors/ucs/src/main/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml
similarity index 100%
rename from plugins/hypervisors/ucs/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml
rename to plugins/hypervisors/ucs/src/main/resources/META-INF/cloudstack/core/spring-ucs-core-context.xml
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index 571720f..13bdc91 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -1,70 +1,71 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-hypervisor-vmware</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor VMware</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-vmware-base</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-secondary-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-orchestration</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.cloud.com.vmware</groupId>
-      <artifactId>vmware-vim25</artifactId>
-      <version>${cs.vmware.api.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis-jaxrpc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>wsdl4j</groupId>
-      <artifactId>wsdl4j</artifactId>
-    </dependency>
-  </dependencies>
+<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-hypervisor-vmware</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor VMware</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-vmware-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-secondary-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-orchestration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.cloud.com.vmware</groupId>
+            <artifactId>vmware-vim25</artifactId>
+            <version>${cs.vmware.api.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis-jaxrpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>wsdl4j</groupId>
+            <artifactId>wsdl4j</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
deleted file mode 100644
index 81dfc33..0000000
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ /dev/null
@@ -1,643 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.guru;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.commons.lang.BooleanUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.BackupSnapshotCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
-import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
-import com.cloud.agent.api.UnregisterNicCommand;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.CreateVolumeOVACommand;
-import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuru;
-import com.cloud.hypervisor.HypervisorGuruBase;
-import com.cloud.hypervisor.vmware.manager.VmwareManager;
-import com.cloud.hypervisor.vmware.mo.DiskControllerType;
-import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
-import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.secstorage.CommandExecLogVO;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.GuestOSHypervisorVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.GuestOSHypervisorDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.VmDetailConstants;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
-    private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
-
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private GuestOSDao _guestOsDao;
-    @Inject
-    GuestOSHypervisorDao _guestOsHypervisorDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private HostDetailsDao _hostDetailsDao;
-    @Inject
-    private CommandExecLogDao _cmdExecLogDao;
-    @Inject
-    private VmwareManager _vmwareMgr;
-    @Inject
-    private SecondaryStorageVmManager _secStorageMgr;
-    @Inject
-    private NetworkModel _networkMgr;
-    @Inject
-    private NicDao _nicDao;
-    @Inject
-    private DomainRouterDao _domainRouterDao;
-    @Inject
-    private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
-    @Inject
-    private VMInstanceDao _vmDao;
-    @Inject
-    private ClusterManager _clusterMgr;
-    @Inject
-    VolumeDao _volumeDao;
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    VolumeDataFactory _volFactory;
-
-    protected VMwareGuru() {
-        super();
-    }
-
-    public static final ConfigKey<Boolean> VmwareReserveCpu = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.cpu", "Advanced", "false",
-        "Specify whether or not to reserve CPU when not overprovisioning, In case of cpu overprovisioning we will always reserve cpu.", true, ConfigKey.Scope.Cluster,
-        null);
-
-    public static final ConfigKey<Boolean> VmwareReserveMemory = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.mem", "Advanced", "false",
-        "Specify whether or not to reserve memory when not overprovisioning, In case of memory overprovisioning we will always reserve memory.", true,
-        ConfigKey.Scope.Cluster, null);
-
-    protected ConfigKey<Boolean> VmwareEnableNestedVirtualization = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization", "Advanced", "false",
-            "When set to true this will enable nested virtualization when this is supported by the hypervisor", true, ConfigKey.Scope.Global, null);
-
-    protected ConfigKey<Boolean> VmwareEnableNestedVirtualizationPerVM = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization.perVM", "Advanced", "false",
-            "When set to true this will enable nested virtualization per vm", true, ConfigKey.Scope.Global, null);
-
-    @Override
-    public HypervisorType getHypervisorType() {
-        return HypervisorType.VMware;
-    }
-
-    @Override
-    public VirtualMachineTO implement(VirtualMachineProfile vm) {
-        VirtualMachineTO to = toVirtualMachineTO(vm);
-        to.setBootloader(BootloaderType.HVM);
-
-        Map<String, String> details = to.getDetails();
-        if (details == null)
-            details = new HashMap<String, String>();
-
-        Type vmType = vm.getType();
-        boolean userVm = !(vmType.equals(VirtualMachine.Type.DomainRouter) || vmType.equals(VirtualMachine.Type.ConsoleProxy)
-                || vmType.equals(VirtualMachine.Type.SecondaryStorageVm));
-
-        String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER);
-        if (!userVm) {
-
-            if (nicDeviceType == null) {
-                details.put(VmDetailConstants.NIC_ADAPTER, _vmwareMgr.getSystemVMDefaultNicAdapterType());
-            } else {
-                try {
-                    VirtualEthernetCardType.valueOf(nicDeviceType);
-                } catch (Exception e) {
-                    s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
-                    details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
-                }
-            }
-        } else {
-            // for user-VM, use E1000 as default
-            if (nicDeviceType == null) {
-                details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
-            } else {
-                try {
-                    VirtualEthernetCardType.valueOf(nicDeviceType);
-                } catch (Exception e) {
-                    s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
-                    details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
-                }
-            }
-        }
-
-        String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
-        if (userVm) {
-            if (diskDeviceType == null) {
-                details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
-            }
-        }
-        String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER);
-        if (userVm) {
-            if (diskController == null) {
-                details.put(VmDetailConstants.DATA_DISK_CONTROLLER, DiskControllerType.lsilogic.toString());
-            }
-        }
-
-        if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
-            details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
-        }
-
-        List<NicProfile> nicProfiles = vm.getNics();
-
-        for (NicProfile nicProfile : nicProfiles) {
-            if (nicProfile.getTrafficType() == TrafficType.Guest) {
-                if (_networkMgr.isProviderSupportServiceInNetwork(nicProfile.getNetworkId(), Service.Firewall, Provider.CiscoVnmc)) {
-                    details.put("ConfigureVServiceInNexus", Boolean.TRUE.toString());
-                }
-                break;
-            }
-        }
-
-        long clusterId = getClusterId(vm.getId());
-        details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
-        details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
-        to.setDetails(details);
-
-        if (vmType.equals(VirtualMachine.Type.DomainRouter)) {
-
-            NicProfile publicNicProfile = null;
-            for (NicProfile nicProfile : nicProfiles) {
-                if (nicProfile.getTrafficType() == TrafficType.Public) {
-                    publicNicProfile = nicProfile;
-                    break;
-                }
-            }
-
-            if (publicNicProfile != null) {
-                NicTO[] nics = to.getNics();
-
-                // reserve extra NICs
-                NicTO[] expandedNics = new NicTO[nics.length + _vmwareMgr.getRouterExtraPublicNics()];
-                int i = 0;
-                int deviceId = -1;
-                for (i = 0; i < nics.length; i++) {
-                    expandedNics[i] = nics[i];
-                    if (nics[i].getDeviceId() > deviceId)
-                        deviceId = nics[i].getDeviceId();
-                }
-                deviceId++;
-
-                long networkId = publicNicProfile.getNetworkId();
-                NetworkVO network = _networkDao.findById(networkId);
-
-                for (; i < nics.length + _vmwareMgr.getRouterExtraPublicNics(); i++) {
-                    NicTO nicTo = new NicTO();
-
-                    nicTo.setDeviceId(deviceId++);
-                    nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
-                    nicTo.setType(publicNicProfile.getTrafficType());
-                    nicTo.setIp("0.0.0.0");
-                    nicTo.setNetmask("255.255.255.255");
-
-                    try {
-                        String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
-                        nicTo.setMac(mac);
-                    } catch (InsufficientAddressCapacityException e) {
-                        throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
-                    }
-                    nicTo.setDns1(publicNicProfile.getIPv4Dns1());
-                    nicTo.setDns2(publicNicProfile.getIPv4Dns2());
-                    if (publicNicProfile.getIPv4Gateway() != null) {
-                        nicTo.setGateway(publicNicProfile.getIPv4Gateway());
-                    } else {
-                        nicTo.setGateway(network.getGateway());
-                    }
-                    nicTo.setDefaultNic(false);
-                    nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
-                    nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
-
-                    Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
-                    nicTo.setNetworkRateMbps(networkRate);
-
-                    expandedNics[i] = nicTo;
-                }
-
-                to.setNics(expandedNics);
-
-                VirtualMachine router = vm.getVirtualMachine();
-                DomainRouterVO routerVO = _domainRouterDao.findById(router.getId());
-                if (routerVO != null && routerVO.getIsRedundantRouter()) {
-                    Long peerRouterId = _nicDao.getPeerRouterId(publicNicProfile.getMacAddress(), router.getId());
-                    DomainRouterVO peerRouterVO = null;
-                    if (peerRouterId != null) {
-                        peerRouterVO = _domainRouterDao.findById(peerRouterId);
-                        if (peerRouterVO != null) {
-                            details.put("PeerRouterInstanceName", peerRouterVO.getInstanceName());
-                        }
-                    }
-                }
-            }
-
-            StringBuffer sbMacSequence = new StringBuffer();
-            for (NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
-                sbMacSequence.append(nicTo.getMac()).append("|");
-            }
-            if (!sbMacSequence.toString().isEmpty()) {
-                sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
-                String bootArgs = to.getBootArgs();
-                to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
-            }
-
-        }
-
-        // Don't do this if the virtual machine is one of the special types
-        // Should only be done on user machines
-        if (userVm) {
-            configureNestedVirtualization(details, to);
-        }
-        // Determine the VM's OS description
-        GuestOSVO guestOS = _guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
-        to.setOs(guestOS.getDisplayName());
-        to.setHostName(vm.getHostName());
-        HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
-        GuestOSHypervisorVO guestOsMapping = null;
-        if (host != null) {
-            guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion());
-        }
-        if (guestOsMapping == null || host == null) {
-            to.setPlatformEmulator(null);
-        } else {
-            to.setPlatformEmulator(guestOsMapping.getGuestOsName());
-        }
-        return to;
-    }
-
-    /**
-     * Decide in which cases nested virtualization should be enabled based on (1){@code globalNestedV}, (2){@code globalNestedVPerVM}, (3){@code localNestedV}<br/>
-     * Nested virtualization should be enabled when one of this cases:
-     * <ul>
-     * <li>(1)=TRUE, (2)=TRUE, (3) is NULL (missing)</li>
-     * <li>(1)=TRUE, (2)=TRUE, (3)=TRUE</li>
-     * <li>(1)=TRUE, (2)=FALSE</li>
-     * <li>(1)=FALSE, (2)=TRUE, (3)=TRUE</li>
-     * </ul>
-     * In any other case, it shouldn't be enabled
-     * @param globalNestedV value of {@code 'vmware.nested.virtualization'} global config
-     * @param globalNestedVPerVM value of {@code 'vmware.nested.virtualization.perVM'} global config
-     * @param localNestedV value of {@code 'nestedVirtualizationFlag'} key in vm details if present, null if not present
-     * @return "true" for cases in which nested virtualization is enabled, "false" if not
-     */
-    protected Boolean shouldEnableNestedVirtualization(Boolean globalNestedV, Boolean globalNestedVPerVM, String localNestedV){
-        if (globalNestedV == null || globalNestedVPerVM == null) {
-            return false;
-        }
-        boolean globalNV = globalNestedV.booleanValue();
-        boolean globalNVPVM = globalNestedVPerVM.booleanValue();
-
-        if (globalNVPVM){
-            return (localNestedV == null && globalNV) || BooleanUtils.toBoolean(localNestedV);
-        }
-        return globalNV;
-    }
-
-    /**
-     * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
-     * @param details vm details
-     * @param to vm to
-     */
-    protected void configureNestedVirtualization(Map<String, String> details, VirtualMachineTO to) {
-        Boolean globalNestedV = VmwareEnableNestedVirtualization.value();
-        Boolean globalNestedVPerVM = VmwareEnableNestedVirtualizationPerVM.value();
-        String localNestedV = details.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG);
-
-        Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedV, globalNestedVPerVM, localNestedV);
-        s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
-        details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Boolean.toString(shouldEnableNestedVirtualization));
-        to.setDetails(details);
-    }
-
-    private long getClusterId(long vmId) {
-        long clusterId;
-        Long hostId;
-
-        hostId = _vmDao.findById(vmId).getHostId();
-        if (hostId == null) {
-            // If VM is in stopped state then hostId would be undefined. Hence read last host's Id instead.
-            hostId = _vmDao.findById(vmId).getLastHostId();
-        }
-        clusterId = _hostDao.findById(hostId).getClusterId();
-
-        return clusterId;
-    }
-
-    private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
-
-        List<NicTO> listForSort = new ArrayList<NicTO>();
-        for (NicTO nic : nics) {
-            listForSort.add(nic);
-        }
-        Collections.sort(listForSort, new Comparator<NicTO>() {
-
-            @Override
-            public int compare(NicTO arg0, NicTO arg1) {
-                if (arg0.getDeviceId() < arg1.getDeviceId()) {
-                    return -1;
-                } else if (arg0.getDeviceId() == arg1.getDeviceId()) {
-                    return 0;
-                }
-
-                return 1;
-            }
-        });
-
-        return listForSort.toArray(new NicTO[0]);
-    }
-
-    @Override
-    @DB
-    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
-        boolean needDelegation = false;
-        if (cmd instanceof StorageSubSystemCommand) {
-            Boolean fullCloneEnabled = VmwareFullClone.value();
-            StorageSubSystemCommand c = (StorageSubSystemCommand)cmd;
-            c.setExecuteInSequence(fullCloneEnabled);
-        }
-        if (cmd instanceof DownloadCommand) {
-          cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
-        }
-        //NOTE: the hostid can be a hypervisor host, or a ssvm agent. For copycommand, if it's for volume upload, the hypervisor
-        //type is empty, so we need to check the format of volume at first.
-        if (cmd instanceof CopyCommand) {
-            CopyCommand cpyCommand = (CopyCommand) cmd;
-            DataTO srcData = cpyCommand.getSrcTO();
-            DataStoreTO srcStoreTO = srcData.getDataStore();
-            DataTO destData = cpyCommand.getDestTO();
-            DataStoreTO destStoreTO = destData.getDataStore();
-
-            boolean inSeq = true;
-            if ((srcData.getObjectType() == DataObjectType.SNAPSHOT) || (destData.getObjectType() == DataObjectType.SNAPSHOT)) {
-                inSeq = false;
-            } else if ((destStoreTO.getRole() == DataStoreRole.Image) || (destStoreTO.getRole() == DataStoreRole.ImageCache)) {
-                inSeq = false;
-            } else if (!VmwareFullClone.value()) {
-                inSeq = false;
-            }
-            cpyCommand.setExecuteInSequence(inSeq);
-
-            if (srcData.getObjectType() == DataObjectType.VOLUME) {
-                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)srcData;
-                if (Storage.ImageFormat.OVA == volumeObjectTO.getFormat()) {
-                    needDelegation = true;
-                }
-            }
-
-            if (!needDelegation && !(HypervisorType.VMware == srcData.getHypervisorType() || HypervisorType.VMware == destData.getHypervisorType())) {
-                return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
-            }
-
-            if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
-                srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
-                needDelegation = false;
-            } else {
-                needDelegation = true;
-            }
-        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
-            DataTO srcData = ((CreateEntityDownloadURLCommand)cmd).getData();
-            if ((HypervisorType.VMware == srcData.getHypervisorType())) {
-                needDelegation = true;
-            }
-            if (srcData.getObjectType() == DataObjectType.VOLUME) {
-                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)srcData;
-                if (Storage.ImageFormat.OVA == volumeObjectTO.getFormat()) {
-                    needDelegation = true;
-                }
-            }
-        }
-
-        if (!needDelegation) {
-            return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
-        }
-        HostVO host = _hostDao.findById(hostId);
-        long dcId = host.getDataCenterId();
-        Pair<HostVO, SecondaryStorageVmVO> cmdTarget = _secStorageMgr.assignSecStorageVm(dcId, cmd);
-        if (cmdTarget != null) {
-            // TODO, we need to make sure agent is actually connected too
-
-            cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
-            if (host.getType() == Host.Type.Routing) {
-                Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
-                cmd.setContextParam("guid", resolveNameInGuid(hostDetails.get("guid")));
-                cmd.setContextParam("username", hostDetails.get("username"));
-                cmd.setContextParam("password", hostDetails.get("password"));
-                cmd.setContextParam("serviceconsole", _vmwareMgr.getServiceConsolePortGroupName());
-                cmd.setContextParam("manageportgroup", _vmwareMgr.getManagementPortGroupName());
-            }
-
-            CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
-            _cmdExecLogDao.persist(execLog);
-            cmd.setContextParam("execid", String.valueOf(execLog.getId()));
-            cmd.setContextParam("noderuninfo", String.format("%d-%d", _clusterMgr.getManagementNodeId(), _clusterMgr.getCurrentRunId()));
-            cmd.setContextParam("vCenterSessionTimeout", String.valueOf(_vmwareMgr.getVcenterSessionTimeout()));
-            cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
-
-            if (cmd instanceof BackupSnapshotCommand || cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
-                cmd instanceof CreatePrivateTemplateFromSnapshotCommand || cmd instanceof CopyVolumeCommand || cmd instanceof CopyCommand ||
-                cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand || cmd instanceof CreateVolumeFromSnapshotCommand) {
-                String workerName = _vmwareMgr.composeWorkerName();
-                long checkPointId = 1;
-                // FIXME: Fix                    long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
-                cmd.setContextParam("worker", workerName);
-                cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
-
-                // some commands use 2 workers
-                String workerName2 = _vmwareMgr.composeWorkerName();
-                long checkPointId2 = 1;
-                // FIXME: Fix                    long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
-                cmd.setContextParam("worker2", workerName2);
-                cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
-                cmd.setContextParam("searchexludefolders", _vmwareMgr.s_vmwareSearchExcludeFolder.value());
-            }
-
-            return new Pair<Boolean, Long>(Boolean.TRUE, cmdTarget.first().getId());
-
-        }
-        return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
-    }
-
-    @Override
-    public boolean trackVmHostChange() {
-        return true;
-    }
-
-    private static String resolveNameInGuid(String guid) {
-        String tokens[] = guid.split("@");
-        assert (tokens.length == 2);
-
-        String vCenterIp = NetUtils.resolveToIp(tokens[1]);
-        if (vCenterIp == null) {
-            s_logger.error("Fatal : unable to resolve vCenter address " + tokens[1] + ", please check your DNS configuration");
-            return guid;
-        }
-
-        if (vCenterIp.equals(tokens[1]))
-            return guid;
-
-        return tokens[0] + "@" + vCenterIp;
-    }
-
-    @Override
-    public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
-        List<Command> commands = new ArrayList<Command>();
-        List<NicVO> nicVOs = _nicDao.listByVmId(vm.getId());
-        for (NicVO nic : nicVOs) {
-            NetworkVO network = _networkDao.findById(nic.getNetworkId());
-            if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch) {
-                s_logger.debug("Nic " + nic.toString() + " is connected to an lswitch, cleanup required");
-                NetworkVO networkVO = _networkDao.findById(nic.getNetworkId());
-                // We need the traffic label to figure out which vSwitch has the
-                // portgroup
-                PhysicalNetworkTrafficTypeVO trafficTypeVO = _physicalNetworkTrafficTypeDao.findBy(networkVO.getPhysicalNetworkId(), networkVO.getTrafficType());
-                UnregisterNicCommand unregisterNicCommand =
-                    new UnregisterNicCommand(vm.getInstanceName(), trafficTypeVO.getVmwareNetworkLabel(), UUID.fromString(nic.getUuid()));
-                commands.add(unregisterNicCommand);
-            }
-        }
-        return commands;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return VMwareGuru.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {VmwareReserveCpu, VmwareReserveMemory, VmwareEnableNestedVirtualization, VmwareEnableNestedVirtualizationPerVM};
-    }
-
-    @Override
-    public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
-        List<Command> commands = new ArrayList<Command>();
-
-        List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
-
-        if (volumes != null) {
-            for (VolumeVO volume : volumes) {
-                StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
-
-                // storagePool should be null if we are expunging a volume that was never
-                // attached to a VM that was started (the "trick" for storagePool to be null
-                // is that none of the VMs this volume may have been attached to were ever started,
-                // so the volume was never assigned to a storage pool)
-                if (storagePool != null && storagePool.isManaged() && volume.getVolumeType() == Volume.Type.ROOT) {
-                    VolumeInfo volumeInfo = _volFactory.getVolume(volume.getId());
-                    PrimaryDataStore primaryDataStore = (PrimaryDataStore)volumeInfo.getDataStore();
-                    Map<String, String> details = primaryDataStore.getDetails();
-
-                    if (details == null) {
-                        details = new HashMap<String, String>();
-
-                        primaryDataStore.setDetails(details);
-                    }
-
-                    details.put(DiskTO.MANAGED, Boolean.TRUE.toString());
-
-                    DeleteCommand cmd = new DeleteCommand(volumeInfo.getTO());
-
-                    commands.add(cmd);
-
-                    break;
-                }
-            }
-        }
-
-        return commands;
-    }
-
-    @Override
-    public Map<String, String> getClusterSettings(long vmId) {
-        Map<String, String> details = new HashMap<String, String>();
-        long clusterId = getClusterId(vmId);
-        details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
-        details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
-        return details;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
deleted file mode 100644
index d74c123..0000000
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.hypervisor.vmware;
-
-import java.util.List;
-
-import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
-import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
-
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public interface VmwareDatacenterService extends PluggableService {
-
-    public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException;
-
-    public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws IllegalArgumentException, ResourceInUseException;
-
-    public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws IllegalArgumentException, CloudRuntimeException;
-}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
deleted file mode 100644
index f586f39..0000000
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ /dev/null
@@ -1,1344 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.manager;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.api.query.dao.TemplateJoinDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.cluster.dao.ManagementServerHostPeerDao;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.ClusterVSMMapVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.ClusterVSMMapDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.exception.DiscoveredWithErrorException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.host.Host;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.hypervisor.vmware.LegacyZoneVO;
-import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
-import com.cloud.hypervisor.vmware.VmwareDatacenter;
-import com.cloud.hypervisor.vmware.VmwareDatacenterService;
-import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
-import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
-import com.cloud.hypervisor.vmware.dao.LegacyZoneDao;
-import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
-import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
-import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
-import com.cloud.hypervisor.vmware.mo.DatacenterMO;
-import com.cloud.hypervisor.vmware.mo.DiskControllerType;
-import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
-import com.cloud.hypervisor.vmware.mo.HostMO;
-import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
-import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
-import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
-import com.cloud.hypervisor.vmware.mo.VmwareHostType;
-import com.cloud.hypervisor.vmware.resource.VmwareContextFactory;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.network.CiscoNexusVSMDeviceVO;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.VmwareTrafficLabel;
-import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.storage.ImageStoreDetailsUtil;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.utils.FileUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-import com.cloud.utils.ssh.SshHelper;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.dao.UserVmCloneSettingDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.vmware.vim25.AboutInfo;
-import com.vmware.vim25.ManagedObjectReference;
-import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
-import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.rmi.RemoteException;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
-    private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
-
-    private static final long SECONDS_PER_MINUTE = 60;
-    private static final int DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x = 256;
-    private static final int DEFAULT_PORTS_PER_DV_PORT_GROUP = 8;
-
-    private int _timeout;
-
-    private String _instance;
-
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private NetworkModel _netMgr;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    private CommandExecLogDao _cmdExecLogDao;
-    @Inject
-    private DataStoreManager _dataStoreMgr;
-    @Inject
-    private CiscoNexusVSMDeviceDao _nexusDao;
-    @Inject
-    private ClusterVSMMapDao _vsmMapDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private ConfigurationServer _configServer;
-    @Inject
-    private HypervisorCapabilitiesDao _hvCapabilitiesDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private VmwareDatacenterDao _vmwareDcDao;
-    @Inject
-    private VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
-    @Inject
-    private LegacyZoneDao _legacyZoneDao;
-    @Inject
-    private ManagementServerHostPeerDao _mshostPeerDao;
-    @Inject
-    private ClusterManager _clusterMgr;
-    @Inject
-    private ImageStoreDetailsUtil imageStoreDetailsUtil;
-    @Inject
-    private PrimaryDataStoreDao primaryStorageDao;
-    @Inject
-    private VMTemplatePoolDao templateDataStoreDao;
-    @Inject
-    private TemplateJoinDao templateDao;
-    @Inject
-    private VMInstanceDao vmInstanceDao;
-    @Inject
-    private UserVmCloneSettingDao cloneSettingDao;
-    @Inject
-    private TemplateManager templateManager;
-
-    private String _mountParent;
-    private StorageLayer _storage;
-    private final String _privateNetworkVSwitchName = "vSwitch0";
-
-    private int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
-    private boolean _fullCloneFlag;
-    private boolean _instanceNameFlag;
-    private String _serviceConsoleName;
-    private String _managemetPortGroupName;
-    private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
-    private String _recycleHungWorker = "false";
-    private int _additionalPortRangeStart;
-    private int _additionalPortRangeSize;
-    private int _routerExtraPublicNics = 2;
-    private int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
-    private String _rootDiskController = DiskControllerType.ide.toString();
-
-    private final String _dataDiskController = DiskControllerType.osdefault.toString();
-
-    private final Map<String, String> _storageMounts = new HashMap<>();
-
-    private final Random _rand = new Random(System.currentTimeMillis());
-
-    private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
-
-    private final VmwareStorageManager _storageMgr;
-    private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
-
-    public VmwareManagerImpl() {
-        _storageMgr = new VmwareStorageManagerImpl(this);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return VmwareManagerImpl.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout};
-    }
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        s_logger.info("Configure VmwareManagerImpl, manager name: " + name);
-
-        if (!_configDao.isPremium()) {
-            s_logger.error("Vmware component can only run under premium distribution");
-            throw new ConfigurationException("Vmware component can only run under premium distribution");
-        }
-
-        _instance = _configDao.getValue(Config.InstanceName.key());
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-        s_logger.info("VmwareManagerImpl config - instance.name: " + _instance);
-
-        _mountParent = _configDao.getValue(Config.MountParent.key());
-        if (_mountParent == null) {
-            _mountParent = File.separator + "mnt";
-        }
-
-        if (_instance != null) {
-            _mountParent = _mountParent + File.separator + _instance;
-        }
-        s_logger.info("VmwareManagerImpl config - _mountParent: " + _mountParent);
-
-        String value = (String)params.get("scripts.timeout");
-        _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
-
-        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
-        if (_storage == null) {
-            _storage = new JavaStorageLayer();
-            _storage.configure("StorageLayer", params);
-        }
-
-        value = _configDao.getValue(Config.VmwareCreateFullClone.key());
-        if (value == null) {
-            _fullCloneFlag = false;
-        } else {
-            _fullCloneFlag = Boolean.parseBoolean(value);
-        }
-
-        value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
-        if (value == null) {
-            _instanceNameFlag = false;
-        } else {
-            _instanceNameFlag = Boolean.parseBoolean(value);
-        }
-
-        _serviceConsoleName = _configDao.getValue(Config.VmwareServiceConsole.key());
-        if (_serviceConsoleName == null) {
-            _serviceConsoleName = "Service Console";
-        }
-
-        _managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
-        if (_managemetPortGroupName == null) {
-            _managemetPortGroupName = "Management Network";
-        }
-
-        _defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
-        if (_defaultSystemVmNicAdapterType == null) {
-            _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
-        }
-
-        _additionalPortRangeStart = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000);
-        if (_additionalPortRangeStart > 65535) {
-            s_logger.warn("Invalid port range start port (" + _additionalPortRangeStart + ") for additional VNC port allocation, reset it to default start port 59000");
-            _additionalPortRangeStart = 59000;
-        }
-
-        _additionalPortRangeSize = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareAdditionalVncPortRangeSize.key()), 1000);
-        if (_additionalPortRangeSize < 0 || _additionalPortRangeStart + _additionalPortRangeSize > 65535) {
-            s_logger.warn("Invalid port range size (" + _additionalPortRangeSize + " for range starts at " + _additionalPortRangeStart);
-            _additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart);
-        }
-
-        _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
-
-        _vCenterSessionTimeout = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareVcenterSessionTimeout.key()), 1200) * 1000;
-        s_logger.info("VmwareManagerImpl config - vmware.vcenter.session.timeout: " + _vCenterSessionTimeout);
-
-        _recycleHungWorker = _configDao.getValue(Config.VmwareRecycleHungWorker.key());
-        if (_recycleHungWorker == null || _recycleHungWorker.isEmpty()) {
-            _recycleHungWorker = "false";
-        }
-
-        _rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
-        if (_rootDiskController == null || _rootDiskController.isEmpty()) {
-            _rootDiskController = DiskControllerType.ide.toString();
-        }
-
-        s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize));
-
-        ((VmwareStorageManagerImpl)_storageMgr).configure(params);
-
-        _agentMgr.registerForHostEvents(this, true, true, true);
-
-        s_logger.info("VmwareManagerImpl has been successfully configured");
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-// Do not run empty task        _hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS);
-// but implement it first!
-
-        startTemplateCleanJobSchedule();
-        startupCleanup(_mountParent);
-
-        s_logger.info("start done");
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        s_logger.info("shutting down scheduled tasks");
-        templateCleanupScheduler.shutdown();
-        shutdownCleanup();
-        return true;
-    }
-
-    @Override
-    public boolean getFullCloneFlag() {
-        return _fullCloneFlag;
-    }
-
-    @Override
-    public String composeWorkerName() {
-        return UUID.randomUUID().toString().replace("-", "");
-    }
-
-    @Override
-    public String getPrivateVSwitchName(long dcId, HypervisorType hypervisorType) {
-        return _netMgr.getDefaultManagementTrafficLabel(dcId, hypervisorType);
-    }
-
-    private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Exception {
-        // For ESX host, we need to enable host firewall to allow VNC access
-        HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO();
-        if (firewallMo != null) {
-            if (hostMo.getHostType() == VmwareHostType.ESX) {
-                firewallMo.enableRuleset("vncServer");
-                firewallMo.refreshFirewall();
-            }
-        }
-
-        // prepare at least one network on the vswitch to enable OVF importing
-        String vSwitchName;
-        String vlanId;
-        String vSwitchType;
-        VmwareTrafficLabel mgmtTrafficLabelObj = new VmwareTrafficLabel(privateTrafficLabel, TrafficType.Management);
-        vSwitchName = mgmtTrafficLabelObj.getVirtualSwitchName();
-        vlanId = mgmtTrafficLabelObj.getVlanId();
-        vSwitchType = mgmtTrafficLabelObj.getVirtualSwitchType().toString();
-
-        s_logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
-        VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
-        //The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
-        if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
-            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
-        }
-        else {
-            int portsPerDvPortGroup = _portsPerDvPortGroup;
-            AboutInfo about = hostMo.getHostAboutInfo();
-            if (about != null) {
-                String version = about.getApiVersion();
-                if (version != null && (version.equals("4.0") || version.equals("4.1")) && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x) {
-                    portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
-                }
-            }
-            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, null, 180000,
-                    vsType, portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null);
-        }
-    }
-
-    @Override
-    public List<ManagedObjectReference> addHostToPodCluster(VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath)
-            throws Exception {
-        if (serviceContext == null) {
-            throw new CloudRuntimeException("Invalid serviceContext");
-        }
-        ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
-        String privateTrafficLabel = null;
-        privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
-        if (privateTrafficLabel == null) {
-            privateTrafficLabel = _privateNetworkVSwitchName;
-        }
-
-        if (mor != null) {
-            List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
-
-            if (mor.getType().equals("ComputeResource")) {
-                List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
-                assert (hosts != null && hosts.size() > 0);
-
-                // For ESX host, we need to enable host firewall to allow VNC access
-                HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
-
-                prepareHost(hostMo, privateTrafficLabel);
-                returnedHostList.add(hosts.get(0));
-                return returnedHostList;
-            } else if (mor.getType().equals("ClusterComputeResource")) {
-                List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
-                assert (hosts != null);
-
-                if (hosts.size() > 0) {
-                    AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
-                    String version = about.getApiVersion();
-                    int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
-                    if (hosts.size() > maxHostsPerCluster) {
-                        String msg = "Failed to add VMware cluster as size is too big, current size: " + hosts.size() + ", max. size: " + maxHostsPerCluster;
-                        s_logger.error(msg);
-                        throw new DiscoveredWithErrorException(msg);
-                    }
-                }
-
-                for (ManagedObjectReference morHost : hosts) {
-                    // For ESX host, we need to enable host firewall to allow VNC access
-                    HostMO hostMo = new HostMO(serviceContext, morHost);
-                    prepareHost(hostMo, privateTrafficLabel);
-                    returnedHostList.add(morHost);
-                }
-                return returnedHostList;
-            } else if (mor.getType().equals("HostSystem")) {
-                // For ESX host, we need to enable host firewall to allow VNC access
-                HostMO hostMo = new HostMO(serviceContext, mor);
-                prepareHost(hostMo, privateTrafficLabel);
-                returnedHostList.add(mor);
-                return returnedHostList;
-            } else {
-                s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath);
-                return null;
-            }
-        }
-
-        s_logger.error("Unable to find host from inventory path: " + hostInventoryPath);
-        return null;
-    }
-
-    @Override
-    public Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId) {
-
-        String secUrl = null;
-        Long secId = null;
-        DataStore secStore = _dataStoreMgr.getImageStore(dcId);
-        if (secStore != null) {
-            secUrl = secStore.getUri();
-            secId = secStore.getId();
-        }
-
-        if (secUrl == null) {
-            // we are using non-NFS image store, then use cache storage instead
-            s_logger.info("Secondary storage is not NFS, we need to use staging storage");
-            DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
-            if (cacheStore != null) {
-                secUrl = cacheStore.getUri();
-                secId = cacheStore.getId();
-            } else {
-                s_logger.warn("No staging storage is found when non-NFS secondary storage is used");
-            }
-        }
-
-        return new Pair<String, Long>(secUrl, secId);
-    }
-
-    @Override
-    public String getServiceConsolePortGroupName() {
-        return _serviceConsoleName;
-    }
-
-    @Override
-    public String getManagementPortGroupName() {
-        return _managemetPortGroupName;
-    }
-
-    @Override
-    public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
-        if (hostMo.getHostType() == VmwareHostType.ESXi) {
-            return _managemetPortGroupName;
-        }
-        return _serviceConsoleName;
-    }
-
-    @Override
-    public void setupResourceStartupParams(Map<String, Object> params) {
-        params.put("vmware.create.full.clone", _fullCloneFlag);
-        params.put("vm.instancename.flag", _instanceNameFlag);
-        params.put("service.console.name", _serviceConsoleName);
-        params.put("management.portgroup.name", _managemetPortGroupName);
-        params.put("vmware.root.disk.controller", _rootDiskController);
-        params.put("vmware.data.disk.controller", _dataDiskController);
-        params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
-        params.put("ports.per.dvportgroup", _portsPerDvPortGroup);
-    }
-
-    @Override
-    public VmwareStorageManager getStorageManager() {
-        return _storageMgr;
-    }
-
-    @Override
-    public void gcLeftOverVMs(VmwareContext context) {
-        VmwareCleanupMaid.gcLeftOverVMs(context);
-    }
-
-    @Override
-    public boolean needRecycle(String workerTag) {
-        if (s_logger.isInfoEnabled())
-            s_logger.info("Check to see if a worker VM with tag " + workerTag + " needs to be recycled");
-
-        if (workerTag == null || workerTag.isEmpty()) {
-            s_logger.error("Invalid worker VM tag " + workerTag);
-            return false;
-        }
-
-        String tokens[] = workerTag.split("-");
-        if (tokens.length != 3) {
-            s_logger.error("Invalid worker VM tag " + workerTag);
-            return false;
-        }
-
-        long startTick = Long.parseLong(tokens[0]);
-        long msid = Long.parseLong(tokens[1]);
-        long runid = Long.parseLong(tokens[2]);
-
-        if (_mshostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
-            if (s_logger.isInfoEnabled())
-                s_logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
-            return true;
-        }
-
-        if (runid != _clusterMgr.getManagementRunId(msid)) {
-            if (s_logger.isInfoEnabled())
-                s_logger.info("Worker VM's owner management server has changed runid, recycle it");
-            return true;
-        }
-
-        // this time-out check was disabled
-        // "until we have found out a VMware API that can check if there are pending tasks on the subject VM"
-        // but as we expire jobs and those stale worker VMs stay around untill an MS reboot we opt in to have them removed anyway
-        Instant start = Instant.ofEpochMilli(startTick);
-        Instant end = start.plusSeconds(2 * (AsyncJobManagerImpl.JobExpireMinutes.value() + AsyncJobManagerImpl.JobCancelThresholdMinutes.value()) * SECONDS_PER_MINUTE);
-        Instant now = Instant.now();
-        if(s_vmwareCleanOldWorderVMs.value() && now.isAfter(end)) {
-            if(s_logger.isInfoEnabled()) {
-                s_logger.info("Worker VM expired, seconds elapsed: " + Duration.between(start,now).getSeconds());
-            }
-            return true;
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Worker VM with tag '" + workerTag + "' does not need recycling, yet." +
-                    "But in " + Duration.between(now,end).getSeconds() + " seconds, though");
-        }
-        return false;
-    }
-
-    @Override
-    public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
-        Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(storeId);
-        String mountPoint = getMountPoint(storageUrl, nfsVersion);
-
-        GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
-        try {
-            if (lock.lock(3600)) {
-                try {
-                    File patchFolder = new File(mountPoint + "/systemvm");
-                    if (!patchFolder.exists()) {
-                        if (!patchFolder.mkdirs()) {
-                            String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString();
-                            s_logger.error(msg);
-                            throw new CloudRuntimeException(msg);
-                        }
-                    }
-
-                    File srcIso = getSystemVMPatchIsoFile();
-                    File destIso = new File(mountPoint + "/systemvm/" + getSystemVMIsoFileNameOnDatastore());
-                    if (!destIso.exists()) {
-                        s_logger.info("Inject SSH key pairs before copying systemvm.iso into secondary storage");
-                        _configServer.updateKeyPairs();
-
-                        s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: " + srcIso.getAbsolutePath() + ", destination: " +
-                                destIso.getAbsolutePath());
-                        try {
-                            FileUtil.copyfile(srcIso, destIso);
-                        } catch (IOException e) {
-                            s_logger.error("Unexpected exception ", e);
-
-                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso;
-                            s_logger.error(msg);
-                            throw new CloudRuntimeException(msg);
-                        }
-                    } else {
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("SystemVM ISO file " + destIso.getPath() + " already exists");
-                        }
-                    }
-                } finally {
-                    lock.unlock();
-                }
-            }
-        } finally {
-            lock.releaseRef();
-        }
-    }
-
-    @Override
-    public String getSystemVMIsoFileNameOnDatastore() {
-        String version = this.getClass().getPackage().getImplementationVersion();
-        String fileName = "systemvm-" + version + ".iso";
-        return fileName.replace(':', '-');
-    }
-
-    @Override
-    public String getSystemVMDefaultNicAdapterType() {
-        return _defaultSystemVmNicAdapterType;
-    }
-
-    private File getSystemVMPatchIsoFile() {
-        // locate systemvm.iso
-        URL url = this.getClass().getClassLoader().getResource("vms/systemvm.iso");
-        File isoFile = null;
-        if (url != null) {
-            isoFile = new File(url.getPath());
-        }
-
-        if (isoFile == null || !isoFile.exists()) {
-            isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
-        }
-
-        assert (isoFile != null);
-        if (!isoFile.exists()) {
-            s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString());
-        }
-        return isoFile;
-    }
-
-    @Override
-    public File getSystemVMKeyFile() {
-        URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
-        File keyFile = null;
-        if (url != null) {
-            keyFile = new File(url.getPath());
-        }
-        if (keyFile == null || !keyFile.exists()) {
-            keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
-        }
-        assert (keyFile != null);
-        if (!keyFile.exists()) {
-            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
-        }
-        return keyFile;
-    }
-
-    @Override
-    public String getMountPoint(String storageUrl, Integer nfsVersion) {
-        String mountPoint = null;
-        synchronized (_storageMounts) {
-            mountPoint = _storageMounts.get(storageUrl);
-            if (mountPoint != null) {
-                return mountPoint;
-            }
-
-            URI uri;
-            try {
-                uri = new URI(storageUrl);
-            } catch (URISyntaxException e) {
-                s_logger.error("Invalid storage URL format ", e);
-                throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl);
-            }
-
-            mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent, nfsVersion);
-            if (mountPoint == null) {
-                s_logger.error("Unable to create mount point for " + storageUrl);
-                return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl);
-            }
-
-            _storageMounts.put(storageUrl, mountPoint);
-            return mountPoint;
-        }
-    }
-
-    private String setupMountPoint(String parent) {
-        String mountPoint = null;
-        long mshostId = ManagementServerNode.getManagementServerId();
-        for (int i = 0; i < 10; i++) {
-            String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
-            File file = new File(mntPt);
-            if (!file.exists()) {
-                if (_storage.mkdir(mntPt)) {
-                    mountPoint = mntPt;
-                    break;
-                }
-            }
-            s_logger.error("Unable to create mount: " + mntPt);
-        }
-
-        return mountPoint;
-    }
-
-    private void startupCleanup(String parent) {
-        s_logger.info("Cleanup mounted NFS mount points used in previous session");
-
-        long mshostId = ManagementServerNode.getManagementServerId();
-
-        // cleanup left-over NFS mounts from previous session
-        List<String> mounts = _storage.listMountPointsByMsHost(parent, mshostId);
-        if (mounts != null && !mounts.isEmpty()) {
-            for (String mountPoint : mounts) {
-                s_logger.info("umount NFS mount from previous session: " + mountPoint);
-
-                String result = null;
-                Script command = new Script(true, "umount", _timeout, s_logger);
-                command.add(mountPoint);
-                result = command.execute();
-                if (result != null) {
-                    s_logger.warn("Unable to umount " + mountPoint + " due to " + result);
-                }
-                File file = new File(mountPoint);
-                if (file.exists()) {
-                    file.delete();
-                }
-            }
-        }
-    }
-
-    private void shutdownCleanup() {
-        s_logger.info("Cleanup mounted NFS mount points used in current session");
-
-        for (String mountPoint : _storageMounts.values()) {
-            s_logger.info("umount NFS mount: " + mountPoint);
-
-            String result = null;
-            Script command = new Script(true, "umount", _timeout, s_logger);
-            command.add(mountPoint);
-            result = command.execute();
-            if (result != null) {
-                s_logger.warn("Unable to umount " + mountPoint + " due to " + result);
-            }
-            File file = new File(mountPoint);
-            if (file.exists()) {
-                file.delete();
-            }
-        }
-    }
-
-    protected String mount(String path, String parent, Integer nfsVersion) {
-        String mountPoint = setupMountPoint(parent);
-        if (mountPoint == null) {
-            s_logger.warn("Unable to create a mount point");
-            return null;
-        }
-
-        Script script = null;
-        String result = null;
-        Script command = new Script(true, "mount", _timeout, s_logger);
-        command.add("-t", "nfs");
-        if (nfsVersion != null){
-            command.add("-o", "vers=" + nfsVersion);
-        }
-        // command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
-        if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
-            command.add("-o", "resvport");
-        }
-        command.add(path);
-        command.add(mountPoint);
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to mount " + path + " due to " + result);
-            File file = new File(mountPoint);
-            if (file.exists()) {
-                file.delete();
-            }
-            return null;
-        }
-
-        // Change permissions for the mountpoint
-        script = new Script(true, "chmod", _timeout, s_logger);
-        script.add("1777", mountPoint);
-        result = script.execute();
-        if (result != null) {
-            s_logger.warn("Unable to set permissions for " + mountPoint + " due to " + result);
-        }
-        return mountPoint;
-    }
-
-    @DB
-    private void updateClusterNativeHAState(Host host, StartupCommand cmd) {
-        ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-        if (cluster.getClusterType() == ClusterType.ExternalManaged) {
-            if (cmd instanceof StartupRoutingCommand) {
-                StartupRoutingCommand hostStartupCmd = (StartupRoutingCommand)cmd;
-                Map<String, String> details = hostStartupCmd.getHostDetails();
-
-                if (details.get("NativeHA") != null && details.get("NativeHA").equalsIgnoreCase("true")) {
-                    _clusterDetailsDao.persist(host.getClusterId(), "NativeHA", "true");
-                } else {
-                    _clusterDetailsDao.persist(host.getClusterId(), "NativeHA", "false");
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
-        if (answers != null) {
-            for (Answer answer : answers) {
-                String execIdStr = answer.getContextParam("execid");
-                if (execIdStr != null) {
-                    long execId = 0;
-                    try {
-                        execId = Long.parseLong(execIdStr);
-                    } catch (NumberFormatException e) {
-                        assert (false);
-                    }
-
-                    _cmdExecLogDao.expunge(execId);
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean processCommands(long agentId, long seq, Command[] commands) {
-        return false;
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
-        return null;
-    }
-
-    @Override
-    public void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
-        if (cmd instanceof StartupCommand) {
-            if (host.getHypervisorType() == HypervisorType.VMware) {
-                updateClusterNativeHAState(host, cmd);
-            } else {
-                return;
-            }
-        }
-    }
-
-    protected final static int DEFAULT_DOMR_SSHPORT = 3922;
-
-    protected boolean shutdownRouterVM(DomainRouterVO router) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Try to shutdown router VM " + router.getInstanceName() + " directly.");
-        }
-
-        Pair<Boolean, String> result;
-        try {
-            result = SshHelper.sshExecute(router.getPrivateIpAddress(), DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "poweroff -f");
-
-            if (!result.first()) {
-                s_logger.debug("Unable to shutdown " + router.getInstanceName() + " directly");
-                return false;
-            }
-        } catch (Throwable e) {
-            s_logger.warn("Unable to shutdown router " + router.getInstanceName() + " directly.");
-            return false;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Shutdown router " + router.getInstanceName() + " successful.");
-        }
-        return true;
-    }
-
-    @Override
-    public boolean processDisconnect(long agentId, Status state) {
-        return false;
-    }
-
-    @Override
-    public void processHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void processHostRemoved(long hostId, long clusterId) {
-    }
-
-    @Override
-    public boolean isRecurring() {
-        return false;
-    }
-
-    @Override
-    public int getTimeout() {
-        return 0;
-    }
-
-    @Override
-    public boolean processTimeout(long agentId, long seq) {
-        return false;
-    }
-
-    @Override
-    public boolean beginExclusiveOperation(int timeOutSeconds) {
-        return _exclusiveOpLock.lock(timeOutSeconds);
-    }
-
-    @Override
-    public void endExclusiveOperation() {
-        _exclusiveOpLock.unlock();
-    }
-
-    @Override
-    public Pair<Integer, Integer> getAddiionalVncPortRange() {
-        return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
-    }
-
-    @Override
-    public int getRouterExtraPublicNics() {
-        return _routerExtraPublicNics;
-    }
-
-    @Override
-    public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
-        CiscoNexusVSMDeviceVO nexusVSM = null;
-        ClusterVSMMapVO vsmMapVO = null;
-
-        vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
-        long vsmId = 0;
-        if (vsmMapVO != null) {
-            vsmId = vsmMapVO.getVsmId();
-            s_logger.info("vsmId is " + vsmId);
-            nexusVSM = _nexusDao.findById(vsmId);
-            s_logger.info("Fetching nexus vsm credentials from database.");
-        } else {
-            s_logger.info("Found empty vsmMapVO.");
-            return null;
-        }
-
-        Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
-        if (nexusVSM != null) {
-            nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
-            nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
-            nexusVSMCredentials.put("vsmpassword", nexusVSM.getPassword());
-            s_logger.info("Successfully fetched the credentials of Nexus VSM.");
-        }
-        return nexusVSMCredentials;
-    }
-
-    @Override
-    public String getRootDiskController() {
-        return _rootDiskController;
-    }
-
-    @Override
-    public String getDataDiskController() {
-        return _dataDiskController;
-    }
-
-    @Override
-    public int getVcenterSessionTimeout() {
-        return _vCenterSessionTimeout;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(AddVmwareDcCmd.class);
-        cmdList.add(RemoveVmwareDcCmd.class);
-        cmdList.add(ListVmwareDcsCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    @DB
-    public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
-        VmwareDatacenterVO vmwareDc = null;
-        Long zoneId = cmd.getZoneId();
-        String userName = cmd.getUsername();
-        String password = cmd.getPassword();
-        String vCenterHost = cmd.getVcenter();
-        String vmwareDcName = cmd.getName();
-
-        // Validate username, password, VMware DC name and vCenter
-        if (userName == null) {
-            throw new InvalidParameterValueException("Missing or invalid parameter username.");
-        }
-
-        if (password == null) {
-            throw new InvalidParameterValueException("Missing or invalid parameter username.");
-        }
-
-        if (vmwareDcName == null) {
-            throw new InvalidParameterValueException("Missing or invalid parameter name. Please provide valid VMware datacenter name.");
-        }
-
-        if (vCenterHost == null) {
-            throw new InvalidParameterValueException("Missing or invalid parameter name. "
-                    + "Please provide valid VMware vCenter server's IP address or fully qualified domain name.");
-        }
-
-        if (zoneId == null) {
-            throw new InvalidParameterValueException("Missing or invalid parameter name. " + "Please provide valid zone id.");
-        }
-
-        // Zone validation
-        validateZone(zoneId);
-
-        VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
-        // Check if zone is associated with VMware DC
-        if (vmwareDcZoneMap != null) {
-            // Check if the associated VMware DC matches the one specified in API params
-            // This check would yield success as the association exists between same entities (zone and VMware DC)
-            // This scenario would result in if the API addVmwareDc is called more than once with same parameters.
-            Long associatedVmwareDcId = vmwareDcZoneMap.getVmwareDcId();
-            VmwareDatacenterVO associatedVmwareDc = _vmwareDcDao.findById(associatedVmwareDcId);
-            if (associatedVmwareDc.getVcenterHost().equalsIgnoreCase(vCenterHost) && associatedVmwareDc.getVmwareDatacenterName().equalsIgnoreCase(vmwareDcName)) {
-                s_logger.info("Ignoring API call addVmwareDc, because VMware DC " + vCenterHost + "/" + vmwareDcName +
-                        " is already associated with specified zone with id " + zoneId);
-                return associatedVmwareDc;
-            } else {
-                throw new CloudRuntimeException("Zone " + zoneId + " is already associated with a VMware datacenter. " +
-                        "Only 1 VMware DC can be associated with a zone.");
-            }
-        }
-        // Zone validation to check if the zone already has resources.
-        // Association of VMware DC to zone is not allowed if zone already has resources added.
-        validateZoneWithResources(zoneId, "add VMware datacenter to zone");
-
-        // Check if DC is already part of zone
-        // In that case vmware_data_center table should have the DC
-        vmwareDc = _vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
-        if (vmwareDc != null) {
-            throw new ResourceInUseException("This DC is already part of other CloudStack zone(s). Cannot add this DC to more zones.");
-        }
-
-        VmwareContext context = null;
-        DatacenterMO dcMo = null;
-        String dcCustomFieldValue;
-        boolean addDcCustomFieldDef = false;
-        boolean dcInUse = false;
-        String guid;
-        ManagedObjectReference dcMor;
-        try {
-            context = VmwareContextFactory.create(vCenterHost, userName, password);
-
-            // Check if DC exists on vCenter
-            dcMo = new DatacenterMO(context, vmwareDcName);
-            dcMor = dcMo.getMor();
-            if (dcMor == null) {
-                String msg = "Unable to find VMware DC " + vmwareDcName + " in vCenter " + vCenterHost + ". ";
-                s_logger.error(msg);
-                throw new InvalidParameterValueException(msg);
-            }
-
-            // Check if DC is already associated with another cloudstack deployment
-            // Get custom field property cloud.zone over this DC
-            guid = vmwareDcName + "@" + vCenterHost;
-
-            dcCustomFieldValue = dcMo.getCustomFieldValue(CustomFieldConstants.CLOUD_ZONE);
-            if (dcCustomFieldValue == null) {
-                addDcCustomFieldDef = true;
-            }
-            dcInUse = Boolean.parseBoolean(dcCustomFieldValue);
-            if (dcInUse) {
-                throw new ResourceInUseException("This DC is being managed by other CloudStack deployment. Cannot add this DC to zone.");
-            }
-
-            // Add DC to database into vmware_data_center table
-            vmwareDc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, userName, password);
-            vmwareDc = _vmwareDcDao.persist(vmwareDc);
-
-            // Map zone with vmware datacenter
-            vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
-
-            vmwareDcZoneMap = _vmwareDcZoneMapDao.persist(vmwareDcZoneMap);
-
-            // Set custom field for this DC
-            if (addDcCustomFieldDef) {
-                dcMo.ensureCustomFieldDef(CustomFieldConstants.CLOUD_ZONE);
-            }
-            dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "true");
-
-        } catch (Throwable e) {
-            String msg = "Failed to add VMware DC to zone ";
-            if (e instanceof RemoteException) {
-                msg = "Encountered remote exception at vCenter. " + VmwareHelper.getExceptionMessage(e);
-            } else {
-                msg += "due to : " + e.getMessage();
-            }
-            throw new CloudRuntimeException(msg);
-        } finally {
-            if (context != null) {
-                context.close();
-            }
-            context = null;
-        }
-        return vmwareDc;
-    }
-
-    @Override
-    public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUseException {
-        Long zoneId = cmd.getZoneId();
-        // Validate Id of zone
-        doesZoneExist(zoneId);
-        // Zone validation to check if the zone already has resources.
-        // Association of VMware DC to zone is not allowed if zone already has resources added.
-        validateZoneWithResources(zoneId, "remove VMware datacenter to zone");
-
-        // Get DC associated with this zone
-        VmwareDatacenterVO vmwareDatacenter;
-        String vmwareDcName;
-        String vCenterHost;
-        String userName;
-        String password;
-        DatacenterMO dcMo = null;
-        final VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
-        // Check if zone is associated with VMware DC
-        if (vmwareDcZoneMap == null) {
-            throw new CloudRuntimeException("Zone " + zoneId + " is not associated with any VMware datacenter.");
-        }
-
-        final long vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
-        vmwareDatacenter = _vmwareDcDao.findById(vmwareDcId);
-        vmwareDcName = vmwareDatacenter.getVmwareDatacenterName();
-        vCenterHost = vmwareDatacenter.getVcenterHost();
-        userName = vmwareDatacenter.getUser();
-        password = vmwareDatacenter.getPassword();
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // Remove the VMware datacenter entry in table vmware_data_center
-                _vmwareDcDao.remove(vmwareDcId);
-                // Remove the map entry in table vmware_data_center_zone_map
-                _vmwareDcZoneMapDao.remove(vmwareDcZoneMap.getId());
-            }
-        });
-
-        // Construct context
-        VmwareContext context = null;
-        try {
-            context = VmwareContextFactory.create(vCenterHost, userName, password);
-
-            // Check if DC exists on vCenter
-            try {
-                dcMo = new DatacenterMO(context, vmwareDcName);
-            } catch (Throwable t) {
-                String msg = "Unable to find DC " + vmwareDcName + " in vCenter " + vCenterHost;
-                s_logger.error(msg);
-                throw new DiscoveryException(msg);
-            }
-
-            assert (dcMo != null);
-
-            // Reset custom field property cloud.zone over this DC
-            dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
-            s_logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName);
-        } catch (Exception e) {
-            String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        } finally {
-            if (context != null) {
-                context.close();
-            }
-            context = null;
-        }
-        return true;
-    }
-
-    private void validateZone(Long zoneId) throws InvalidParameterValueException {
-        // Check if zone with specified id exists
-        doesZoneExist(zoneId);
-        // Check if zone is legacy zone
-        if (isLegacyZone(zoneId)) {
-            throw new InvalidParameterValueException("The specified zone is legacy zone. Adding VMware datacenter to legacy zone is not supported.");
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("The specified zone is not legacy zone.");
-            }
-        }
-    }
-
-    private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
-        // Check if zone has resources? - For now look for clusters
-        List<ClusterVO> clusters = _clusterDao.listByZoneId(zoneId);
-        if (clusters != null && clusters.size() > 0) {
-            // Look for VMware hypervisor.
-            for (ClusterVO cluster : clusters) {
-                if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
-                    throw new ResourceInUseException("Zone has one or more clusters." + " Can't " + errStr + " which already has clusters.");
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isLegacyZone(long dcId) {
-        boolean isLegacyZone = false;
-        LegacyZoneVO legacyZoneVo = _legacyZoneDao.findByZoneId(dcId);
-        if (legacyZoneVo != null) {
-            isLegacyZone = true;
-        }
-        return isLegacyZone;
-    }
-
-    @Override
-    public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
-        Long zoneId = cmd.getZoneId();
-        List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
-        VmwareDatacenterZoneMapVO vmwareDcZoneMap;
-        VmwareDatacenterVO vmwareDatacenter;
-        long vmwareDcId;
-
-        // Validate if zone id parameter passed to API is valid
-        doesZoneExist(zoneId);
-
-        // Check if zone is associated with VMware DC
-        vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
-        if (vmwareDcZoneMap == null) {
-            return null;
-        }
-        // Retrieve details of VMware DC associated with zone.
-        vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
-        vmwareDatacenter = _vmwareDcDao.findById(vmwareDcId);
-        vmwareDcList.add(vmwareDatacenter);
-
-        // Currently a zone can have only 1 VMware DC associated with.
-        // Returning list of VmwareDatacenterVO objects, in-line with future requirements, if any, like participation of multiple VMware DCs in a zone.
-        return vmwareDcList;
-    }
-
-    private void doesZoneExist(Long zoneId) throws InvalidParameterValueException {
-        // Check if zone with specified id exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by the id specified.");
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Zone with id:[" + zoneId + "] exists.");
-        }
-    }
-
-    @Override
-    public boolean hasNexusVSM(Long clusterId) {
-        ClusterVSMMapVO vsmMapVo = null;
-
-        vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
-        if (vsmMapVo == null) {
-            s_logger.info("There is no instance of Nexus 1000v VSM associated with this cluster [Id:" + clusterId + "] yet.");
-            return false;
-        }
-        else {
-            s_logger.info("An instance of Nexus 1000v VSM [Id:" + vsmMapVo.getVsmId() + "] associated with this cluster [Id:" + clusterId + "]");
-            return true;
-        }
-    }
-
-    private void startTemplateCleanJobSchedule() {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("checking to see if we should schedule a job to search for fully cloned templates to clean-up");
-        }
-        if(StorageManager.StorageCleanupEnabled.value() &&
-                StorageManager.TemplateCleanupEnabled.value() &&
-                templateCleanupInterval.value() > 0) {
-            try {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("scheduling job to search for fully cloned templates to clean-up once per " + templateCleanupInterval.value() + " minutes.");
-                }
-//                    futureTemplateCleanup =
-                Runnable task = getCleanupFullyClonedTemplatesTask();
-                templateCleanupScheduler.scheduleAtFixedRate(task,
-                        templateCleanupInterval.value(),
-                        templateCleanupInterval.value(),
-                        TimeUnit.MINUTES);
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("scheduled job to search for fully cloned templates to clean-up.");
-                }
-            } catch (RejectedExecutionException ree) {
-                s_logger.error("job to search for fully cloned templates cannot be scheduled");
-                s_logger.debug("job to search for fully cloned templates cannot be scheduled;", ree);
-            } catch (NullPointerException npe) {
-                s_logger.error("job to search for fully cloned templates is invalid");
-                s_logger.debug("job to search for fully cloned templates is invalid;", npe);
-            } catch (IllegalArgumentException iae) {
-                s_logger.error("job to search for fully cloned templates is scheduled at invalid intervals");
-                s_logger.debug("job to search for fully cloned templates is scheduled at invalid intervals;", iae);
-            } catch (Exception e) {
-                s_logger.error("job to search for fully cloned templates failed for unknown reasons");
-                s_logger.debug("job to search for fully cloned templates failed for unknown reasons;", e);
-            }
-        }
-    }
-
-    /**
-     * This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
-     * it is called at regular intervals when storage.template.cleanup.enabled == true
-     * It collect all templates that
-     * - are deleted from cloudstack
-     * - when vmware.create.full.clone == true and the entries for VMs having volumes on the primary storage in db table “user_vm_clone_setting” reads 'full'
-     */
-    private Runnable getCleanupFullyClonedTemplatesTask() {
-        return new CleanupFullyClonedTemplatesTask(primaryStorageDao,
-                templateDataStoreDao,
-                templateDao,
-                vmInstanceDao,
-                cloneSettingDao,
-                templateManager);
-    }
-}
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
deleted file mode 100644
index ee14077..0000000
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ /dev/null
@@ -1,6201 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.resource;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URL;
-import java.nio.channels.SocketChannel;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.NumberUtils;
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-import org.joda.time.Duration;
-
-import com.google.gson.Gson;
-import com.vmware.vim25.AboutInfo;
-import com.vmware.vim25.BoolPolicy;
-import com.vmware.vim25.ComputeResourceSummary;
-import com.vmware.vim25.CustomFieldStringValue;
-import com.vmware.vim25.DVPortConfigInfo;
-import com.vmware.vim25.DVPortConfigSpec;
-import com.vmware.vim25.DasVmPriority;
-import com.vmware.vim25.DatastoreSummary;
-import com.vmware.vim25.DistributedVirtualPort;
-import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
-import com.vmware.vim25.DistributedVirtualSwitchPortCriteria;
-import com.vmware.vim25.DynamicProperty;
-import com.vmware.vim25.GuestInfo;
-import com.vmware.vim25.HostCapability;
-import com.vmware.vim25.HostHostBusAdapter;
-import com.vmware.vim25.HostInternetScsiHba;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.ObjectContent;
-import com.vmware.vim25.OptionValue;
-import com.vmware.vim25.PerfCounterInfo;
-import com.vmware.vim25.PerfEntityMetric;
-import com.vmware.vim25.PerfEntityMetricBase;
-import com.vmware.vim25.PerfMetricId;
-import com.vmware.vim25.PerfMetricIntSeries;
-import com.vmware.vim25.PerfMetricSeries;
-import com.vmware.vim25.PerfQuerySpec;
-import com.vmware.vim25.PerfSampleInfo;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.ToolsUnavailableFaultMsg;
-import com.vmware.vim25.VMwareDVSPortSetting;
-import com.vmware.vim25.VimPortType;
-import com.vmware.vim25.VirtualDevice;
-import com.vmware.vim25.VirtualDeviceBackingInfo;
-import com.vmware.vim25.VirtualDeviceConfigSpec;
-import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
-import com.vmware.vim25.VirtualDisk;
-import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
-import com.vmware.vim25.VirtualEthernetCard;
-import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
-import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
-import com.vmware.vim25.VirtualEthernetCardOpaqueNetworkBackingInfo;
-import com.vmware.vim25.VirtualMachineConfigSpec;
-import com.vmware.vim25.VirtualMachineFileInfo;
-import com.vmware.vim25.VirtualMachineFileLayoutEx;
-import com.vmware.vim25.VirtualMachineFileLayoutExFileInfo;
-import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
-import com.vmware.vim25.VirtualMachinePowerState;
-import com.vmware.vim25.VirtualMachineRelocateSpec;
-import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
-import com.vmware.vim25.VirtualMachineRuntimeInfo;
-import com.vmware.vim25.VirtualMachineToolsStatus;
-import com.vmware.vim25.VirtualMachineVideoCard;
-import com.vmware.vim25.VirtualUSBController;
-import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
-import org.apache.cloudstack.storage.configdrive.ConfigDrive;
-import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
-
-import com.cloud.agent.IAgentControl;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.AttachIsoAnswer;
-import com.cloud.agent.api.AttachIsoCommand;
-import com.cloud.agent.api.BackupSnapshotAnswer;
-import com.cloud.agent.api.BackupSnapshotCommand;
-import com.cloud.agent.api.CheckHealthAnswer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.CheckNetworkAnswer;
-import com.cloud.agent.api.CheckNetworkCommand;
-import com.cloud.agent.api.CheckOnHostAnswer;
-import com.cloud.agent.api.CheckOnHostCommand;
-import com.cloud.agent.api.CheckVirtualMachineAnswer;
-import com.cloud.agent.api.CheckVirtualMachineCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
-import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
-import com.cloud.agent.api.CreateStoragePoolCommand;
-import com.cloud.agent.api.CreateVMSnapshotAnswer;
-import com.cloud.agent.api.CreateVMSnapshotCommand;
-import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
-import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
-import com.cloud.agent.api.DeleteVMSnapshotAnswer;
-import com.cloud.agent.api.DeleteVMSnapshotCommand;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.GetStorageStatsAnswer;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.GetVmDiskStatsAnswer;
-import com.cloud.agent.api.GetVmDiskStatsCommand;
-import com.cloud.agent.api.GetVmIpAddressCommand;
-import com.cloud.agent.api.GetVmNetworkStatsAnswer;
-import com.cloud.agent.api.GetVmNetworkStatsCommand;
-import com.cloud.agent.api.GetVmStatsAnswer;
-import com.cloud.agent.api.GetVmStatsCommand;
-import com.cloud.agent.api.GetVncPortAnswer;
-import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.GetVolumeStatsAnswer;
-import com.cloud.agent.api.GetVolumeStatsCommand;
-import com.cloud.agent.api.HostStatsEntry;
-import com.cloud.agent.api.HostVmStateReportEntry;
-import com.cloud.agent.api.MaintainAnswer;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.ManageSnapshotAnswer;
-import com.cloud.agent.api.ManageSnapshotCommand;
-import com.cloud.agent.api.MigrateAnswer;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.agent.api.MigrateWithStorageAnswer;
-import com.cloud.agent.api.MigrateWithStorageCommand;
-import com.cloud.agent.api.ModifySshKeysCommand;
-import com.cloud.agent.api.ModifyStoragePoolAnswer;
-import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.ModifyTargetsAnswer;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.NetworkUsageAnswer;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PingTestCommand;
-import com.cloud.agent.api.PlugNicAnswer;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.PrepareForMigrationAnswer;
-import com.cloud.agent.api.PrepareForMigrationCommand;
-import com.cloud.agent.api.PvlanSetupCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.RebootAnswer;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.RebootRouterCommand;
-import com.cloud.agent.api.ReplugNicAnswer;
-import com.cloud.agent.api.ReplugNicCommand;
-import com.cloud.agent.api.RevertToVMSnapshotAnswer;
-import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.ScaleVmAnswer;
-import com.cloud.agent.api.ScaleVmCommand;
-import com.cloud.agent.api.SetupAnswer;
-import com.cloud.agent.api.SetupCommand;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.UnPlugNicAnswer;
-import com.cloud.agent.api.UnPlugNicCommand;
-import com.cloud.agent.api.UnregisterNicCommand;
-import com.cloud.agent.api.UnregisterVMCommand;
-import com.cloud.agent.api.UpgradeSnapshotCommand;
-import com.cloud.agent.api.ValidateSnapshotAnswer;
-import com.cloud.agent.api.ValidateSnapshotCommand;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.VolumeStatsEntry;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.storage.CopyVolumeAnswer;
-import com.cloud.agent.api.storage.CopyVolumeCommand;
-import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
-import com.cloud.agent.api.storage.DestroyCommand;
-import com.cloud.agent.api.storage.MigrateVolumeAnswer;
-import com.cloud.agent.api.storage.MigrateVolumeCommand;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
-import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
-import com.cloud.agent.api.storage.ResizeVolumeAnswer;
-import com.cloud.agent.api.storage.ResizeVolumeCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.agent.resource.virtualnetwork.VRScripts;
-import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.Vlan;
-import com.cloud.exception.CloudException;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.guru.VMwareGuru;
-import com.cloud.hypervisor.vmware.manager.VmwareHostService;
-import com.cloud.hypervisor.vmware.manager.VmwareManager;
-import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
-import com.cloud.hypervisor.vmware.mo.ClusterMO;
-import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
-import com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO;
-import com.cloud.hypervisor.vmware.mo.DatacenterMO;
-import com.cloud.hypervisor.vmware.mo.DatastoreFile;
-import com.cloud.hypervisor.vmware.mo.DatastoreMO;
-import com.cloud.hypervisor.vmware.mo.DiskControllerType;
-import com.cloud.hypervisor.vmware.mo.FeatureKeyConstants;
-import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
-import com.cloud.hypervisor.vmware.mo.HostMO;
-import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
-import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
-import com.cloud.hypervisor.vmware.mo.NetworkDetails;
-import com.cloud.hypervisor.vmware.mo.TaskMO;
-import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
-import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
-import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
-import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
-import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
-import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostNetworkSummary;
-import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareContextPool;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.network.Networks;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.VmwareTrafficLabel;
-import com.cloud.resource.ServerResource;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Volume;
-import com.cloud.storage.resource.StoragePoolResource;
-import com.cloud.storage.resource.StorageSubsystemCommandHandler;
-import com.cloud.storage.resource.VmwareStorageLayoutHelper;
-import com.cloud.storage.resource.VmwareStorageProcessor;
-import com.cloud.storage.resource.VmwareStorageProcessor.VmwareStorageProcessorConfigurableFields;
-import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.mgmt.JmxUtil;
-import com.cloud.utils.mgmt.PropertyMapDynamicBean;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.nicira.nvp.plugin.NiciraNvpApiVersion;
-import com.cloud.utils.script.Script;
-import com.cloud.utils.ssh.SshHelper;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VmDetailConstants;
-
-public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer {
-    private static final Logger s_logger = Logger.getLogger(VmwareResource.class);
-
-    private static final Random RANDOM = new Random(System.nanoTime());
-
-    protected String _name;
-
-    protected final long _opsTimeout = 900000;   // 15 minutes time out to time
-
-    protected final int _shutdownWaitMs = 300000;  // wait up to 5 minutes for shutdown
-
-    // out an operation
-    protected final int _retry = 24;
-    protected final int _sleep = 10000;
-    protected final int DefaultDomRSshPort = 3922;
-    protected final int MazCmdMBean = 100;
-
-    protected String _url;
-    protected String _dcId;
-    protected String _pod;
-    protected String _cluster;
-    protected String _username;
-    protected String _password;
-    protected String _guid;
-    protected String _vCenterAddress;
-    protected Integer storageNfsVersion;
-
-    protected String _privateNetworkVSwitchName;
-    protected VmwareTrafficLabel _guestTrafficInfo = new VmwareTrafficLabel(TrafficType.Guest);
-    protected VmwareTrafficLabel _publicTrafficInfo = new VmwareTrafficLabel(TrafficType.Public);
-    protected Map<String, String> _vsmCredentials = null;
-    protected int _portsPerDvPortGroup;
-    protected boolean _fullCloneFlag = false;
-    protected boolean _instanceNameFlag = false;
-
-    protected boolean _recycleHungWorker = false;
-    protected DiskControllerType _rootDiskController = DiskControllerType.ide;
-
-    protected ManagedObjectReference _morHyperHost;
-    protected final static ThreadLocal<VmwareContext> s_serviceContext = new ThreadLocal<VmwareContext>();
-    protected String _hostName;
-
-    protected List<PropertyMapDynamicBean> _cmdMBeans = new ArrayList<PropertyMapDynamicBean>();
-
-    protected Gson _gson;
-
-    protected volatile long _cmdSequence = 1;
-
-    protected StorageSubsystemCommandHandler storageHandler;
-    private VmwareStorageProcessor _storageProcessor;
-
-    protected VirtualRoutingResource _vrResource;
-
-    protected final static HashMap<VirtualMachinePowerState, PowerState> s_powerStatesTable = new HashMap<VirtualMachinePowerState, PowerState>();
-    static {
-        s_powerStatesTable.put(VirtualMachinePowerState.POWERED_ON, PowerState.PowerOn);
-        s_powerStatesTable.put(VirtualMachinePowerState.POWERED_OFF, PowerState.PowerOff);
-        s_powerStatesTable.put(VirtualMachinePowerState.SUSPENDED, PowerState.PowerOn);
-    }
-
-    protected static File s_systemVmKeyFile = null;
-    private static final Object s_syncLockObjectFetchKeyFile = new Object();
-    protected static final String s_relativePathSystemVmKeyFileInstallDir = "scripts/vm/systemvm/id_rsa.cloud";
-    protected static final String s_defaultPathSystemVmKeyFile = "/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud";
-
-    public Gson getGson() {
-        return _gson;
-    }
-
-    public VmwareResource() {
-        _gson = GsonHelper.getGsonLogger();
-    }
-
-    private String getCommandLogTitle(Command cmd) {
-        StringBuffer sb = new StringBuffer();
-        if (_hostName != null) {
-            sb.append(_hostName);
-        }
-
-        if (cmd.getContextParam("job") != null) {
-            sb.append(", ").append(cmd.getContextParam("job"));
-        }
-        sb.append(", cmd: ").append(cmd.getClass().getSimpleName());
-
-        return sb.toString();
-    }
-
-    @Override
-    public Answer executeRequest(Command cmd) {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("Begin executeRequest(), cmd: " + cmd.getClass().getSimpleName());
-
-        Answer answer = null;
-        NDC.push(getCommandLogTitle(cmd));
-        try {
-            long cmdSequence = _cmdSequence++;
-            Date startTime = DateUtil.currentGMTTime();
-            PropertyMapDynamicBean mbean = new PropertyMapDynamicBean();
-            mbean.addProp("StartTime", DateUtil.getDateDisplayString(TimeZone.getDefault(), startTime));
-            mbean.addProp("Command", _gson.toJson(cmd));
-            mbean.addProp("Sequence", String.valueOf(cmdSequence));
-            mbean.addProp("Name", cmd.getClass().getSimpleName());
-
-            Class<? extends Command> clz = cmd.getClass();
-            if (cmd instanceof NetworkElementCommand) {
-                return _vrResource.executeRequest((NetworkElementCommand)cmd);
-            } else if (clz == ReadyCommand.class) {
-                answer = execute((ReadyCommand)cmd);
-            } else if (clz == GetHostStatsCommand.class) {
-                answer = execute((GetHostStatsCommand)cmd);
-            } else if (clz == GetVmStatsCommand.class) {
-                answer = execute((GetVmStatsCommand)cmd);
-            } else if (clz == GetVmNetworkStatsCommand.class) {
-                answer = execute((GetVmNetworkStatsCommand) cmd);
-            } else if (clz == GetVmDiskStatsCommand.class) {
-                answer = execute((GetVmDiskStatsCommand)cmd);
-            } else if (cmd instanceof GetVolumeStatsCommand) {
-                return execute((GetVolumeStatsCommand)cmd);
-            } else if (clz == CheckHealthCommand.class) {
-                answer = execute((CheckHealthCommand)cmd);
-            } else if (clz == StopCommand.class) {
-                answer = execute((StopCommand)cmd);
-            } else if (clz == RebootRouterCommand.class) {
-                answer = execute((RebootRouterCommand)cmd);
-            } else if (clz == RebootCommand.class) {
-                answer = execute((RebootCommand)cmd);
-            } else if (clz == CheckVirtualMachineCommand.class) {
-                answer = execute((CheckVirtualMachineCommand)cmd);
-            } else if (clz == PrepareForMigrationCommand.class) {
-                answer = execute((PrepareForMigrationCommand)cmd);
-            } else if (clz == MigrateCommand.class) {
-                answer = execute((MigrateCommand)cmd);
-            } else if (clz == MigrateWithStorageCommand.class) {
-                answer = execute((MigrateWithStorageCommand)cmd);
-            } else if (clz == MigrateVolumeCommand.class) {
-                answer = execute((MigrateVolumeCommand)cmd);
-            } else if (clz == DestroyCommand.class) {
-                answer = execute((DestroyCommand)cmd);
-            } else if (clz == CreateStoragePoolCommand.class) {
-                return execute((CreateStoragePoolCommand)cmd);
-            } else if (clz == ModifyTargetsCommand.class) {
-                answer = execute((ModifyTargetsCommand)cmd);
-            } else if (clz == ModifyStoragePoolCommand.class) {
-                answer = execute((ModifyStoragePoolCommand)cmd);
-            } else if (clz == DeleteStoragePoolCommand.class) {
-                answer = execute((DeleteStoragePoolCommand)cmd);
-            } else if (clz == CopyVolumeCommand.class) {
-                answer = execute((CopyVolumeCommand)cmd);
-            } else if (clz == AttachIsoCommand.class) {
-                answer = execute((AttachIsoCommand)cmd);
-            } else if (clz == ValidateSnapshotCommand.class) {
-                answer = execute((ValidateSnapshotCommand)cmd);
-            } else if (clz == ManageSnapshotCommand.class) {
-                answer = execute((ManageSnapshotCommand)cmd);
-            } else if (clz == BackupSnapshotCommand.class) {
-                answer = execute((BackupSnapshotCommand)cmd);
-            } else if (clz == CreateVolumeFromSnapshotCommand.class) {
-                answer = execute((CreateVolumeFromSnapshotCommand)cmd);
-            } else if (clz == CreatePrivateTemplateFromVolumeCommand.class) {
-                answer = execute((CreatePrivateTemplateFromVolumeCommand)cmd);
-            } else if (clz == CreatePrivateTemplateFromSnapshotCommand.class) {
-                answer = execute((CreatePrivateTemplateFromSnapshotCommand)cmd);
-            } else if (clz == UpgradeSnapshotCommand.class) {
-                answer = execute((UpgradeSnapshotCommand)cmd);
-            } else if (clz == GetStorageStatsCommand.class) {
-                answer = execute((GetStorageStatsCommand)cmd);
-            } else if (clz == PrimaryStorageDownloadCommand.class) {
-                answer = execute((PrimaryStorageDownloadCommand)cmd);
-            } else if (clz == GetVncPortCommand.class) {
-                answer = execute((GetVncPortCommand)cmd);
-            } else if (clz == SetupCommand.class) {
-                answer = execute((SetupCommand)cmd);
-            } else if (clz == MaintainCommand.class) {
-                answer = execute((MaintainCommand)cmd);
-            } else if (clz == PingTestCommand.class) {
-                answer = execute((PingTestCommand)cmd);
-            } else if (clz == CheckOnHostCommand.class) {
-                answer = execute((CheckOnHostCommand)cmd);
-            } else if (clz == ModifySshKeysCommand.class) {
-                answer = execute((ModifySshKeysCommand)cmd);
-            } else if (clz == NetworkUsageCommand.class) {
-                answer = execute((NetworkUsageCommand)cmd);
-            } else if (clz == StartCommand.class) {
-                answer = execute((StartCommand)cmd);
-            } else if (clz == CheckSshCommand.class) {
-                answer = execute((CheckSshCommand)cmd);
-            } else if (clz == CheckNetworkCommand.class) {
-                answer = execute((CheckNetworkCommand)cmd);
-            } else if (clz == PlugNicCommand.class) {
-                answer = execute((PlugNicCommand)cmd);
-            } else if (clz == ReplugNicCommand.class) {
-                answer = execute((ReplugNicCommand)cmd);
-            } else if (clz == UnPlugNicCommand.class) {
-                answer = execute((UnPlugNicCommand)cmd);
-            } else if (cmd instanceof CreateVMSnapshotCommand) {
-                return execute((CreateVMSnapshotCommand)cmd);
-            } else if (cmd instanceof DeleteVMSnapshotCommand) {
-                return execute((DeleteVMSnapshotCommand)cmd);
-            } else if (cmd instanceof RevertToVMSnapshotCommand) {
-                return execute((RevertToVMSnapshotCommand)cmd);
-            } else if (clz == ResizeVolumeCommand.class) {
-                return execute((ResizeVolumeCommand)cmd);
-            } else if (clz == UnregisterVMCommand.class) {
-                return execute((UnregisterVMCommand)cmd);
-            } else if (cmd instanceof StorageSubSystemCommand) {
-                checkStorageProcessorAndHandlerNfsVersionAttribute((StorageSubSystemCommand)cmd);
-                return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
-            } else if (clz == ScaleVmCommand.class) {
-                return execute((ScaleVmCommand)cmd);
-            } else if (clz == PvlanSetupCommand.class) {
-                return execute((PvlanSetupCommand)cmd);
-            } else if (clz == GetVmIpAddressCommand.class) {
-                return execute((GetVmIpAddressCommand)cmd);
-            } else if (clz == UnregisterNicCommand.class) {
-                answer = execute((UnregisterNicCommand)cmd);
-            } else {
-                answer = Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
-            if (cmd.getContextParam("checkpoint") != null) {
-                answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint"));
-            }
-
-            Date doneTime = DateUtil.currentGMTTime();
-            mbean.addProp("DoneTime", DateUtil.getDateDisplayString(TimeZone.getDefault(), doneTime));
-            mbean.addProp("Answer", _gson.toJson(answer));
-
-            synchronized (this) {
-                try {
-                    JmxUtil.registerMBean("VMware " + _morHyperHost.getValue(), "Command " + cmdSequence + "-" + cmd.getClass().getSimpleName(), mbean);
-                    _cmdMBeans.add(mbean);
-
-                    if (_cmdMBeans.size() >= MazCmdMBean) {
-                        PropertyMapDynamicBean mbeanToRemove = _cmdMBeans.get(0);
-                        _cmdMBeans.remove(0);
-
-                        JmxUtil.unregisterMBean("VMware " + _morHyperHost.getValue(), "Command " + mbeanToRemove.getProp("Sequence") + "-" + mbeanToRemove.getProp("Name"));
-                    }
-                } catch (Exception e) {
-                    if (s_logger.isTraceEnabled())
-                        s_logger.trace("Unable to register JMX monitoring due to exception " + ExceptionUtil.toString(e));
-                }
-            }
-
-        } finally {
-            recycleServiceContext();
-            NDC.pop();
-        }
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("End executeRequest(), cmd: " + cmd.getClass().getSimpleName());
-
-        return answer;
-    }
-
-    /**
-     * Check if storage NFS version is already set or needs to be reconfigured.<br>
-     * If _storageNfsVersion is not null -> nothing to do, version already set.<br>
-     * If _storageNfsVersion is null -> examine StorageSubSystemCommand to get NFS version and set it
-     * to the storage processor and storage handler.
-     * @param cmd command to execute
-     */
-    protected void checkStorageProcessorAndHandlerNfsVersionAttribute(StorageSubSystemCommand cmd) {
-        if (storageNfsVersion != null)
-            return;
-        if (cmd instanceof CopyCommand) {
-            EnumMap<VmwareStorageProcessorConfigurableFields, Object> params = new EnumMap<VmwareStorageProcessorConfigurableFields, Object>(
-                    VmwareStorageProcessorConfigurableFields.class);
-            examineStorageSubSystemCommandNfsVersion((CopyCommand)cmd, params);
-            params = examineStorageSubSystemCommandFullCloneFlagForVmware((CopyCommand)cmd, params);
-            reconfigureProcessorByHandler(params);
-        }
-    }
-
-    /**
-     * Reconfigure processor by handler
-     * @param params params
-     */
-    protected void reconfigureProcessorByHandler(EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
-        VmwareStorageSubsystemCommandHandler handler = (VmwareStorageSubsystemCommandHandler)storageHandler;
-        boolean success = handler.reconfigureStorageProcessor(params);
-        if (success) {
-            s_logger.info("VmwareStorageProcessor and VmwareStorageSubsystemCommandHandler successfully reconfigured");
-        } else {
-            s_logger.error("Error while reconfiguring VmwareStorageProcessor and VmwareStorageSubsystemCommandHandler, params=" + _gson.toJson(params));
-        }
-    }
-
-    /**
-     * Examine StorageSubSystem command to get full clone flag, if provided
-     * @param cmd command to execute
-     * @param params params
-     * @return copy of params including new values, if suitable
-     */
-    protected EnumMap<VmwareStorageProcessorConfigurableFields, Object> examineStorageSubSystemCommandFullCloneFlagForVmware(CopyCommand cmd,
-            EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
-        EnumMap<VmwareStorageProcessorConfigurableFields, Object> paramsCopy = new EnumMap<VmwareStorageProcessorConfigurableFields, Object>(params);
-        HypervisorType hypervisor = cmd.getDestTO().getHypervisorType();
-        if (hypervisor != null && hypervisor.equals(HypervisorType.VMware)) {
-            DataStoreTO destDataStore = cmd.getDestTO().getDataStore();
-            if (destDataStore instanceof PrimaryDataStoreTO) {
-                PrimaryDataStoreTO dest = (PrimaryDataStoreTO)destDataStore;
-                if (dest.isFullCloneFlag() != null) {
-                    paramsCopy.put(VmwareStorageProcessorConfigurableFields.FULL_CLONE_FLAG, dest.isFullCloneFlag().booleanValue());
-                }
-            }
-        }
-        return paramsCopy;
-    }
-
-    /**
-     * Examine StorageSubSystem command to get storage NFS version, if provided
-     * @param cmd command to execute
-     * @param params params
-     */
-    protected void examineStorageSubSystemCommandNfsVersion(CopyCommand cmd, EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
-        DataStoreTO srcDataStore = cmd.getSrcTO().getDataStore();
-        boolean nfsVersionFound = false;
-
-        if (srcDataStore instanceof NfsTO) {
-            nfsVersionFound = getStorageNfsVersionFromNfsTO((NfsTO)srcDataStore);
-        }
-
-        if (nfsVersionFound) {
-            params.put(VmwareStorageProcessorConfigurableFields.NFS_VERSION, storageNfsVersion);
-        }
-    }
-
-    /**
-     * Get storage NFS version from NfsTO
-     * @param nfsTO nfsTO
-     * @return true if NFS version was found and not null, false in other case
-     */
-    protected boolean getStorageNfsVersionFromNfsTO(NfsTO nfsTO) {
-        if (nfsTO != null && nfsTO.getNfsVersion() != null) {
-            storageNfsVersion = nfsTO.getNfsVersion();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Registers the vm to the inventory given the vmx file.
-     */
-    private void registerVm(String vmName, DatastoreMO dsMo) throws Exception {
-
-        //1st param
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-        DatacenterMO dataCenterMo = new DatacenterMO(getServiceContext(), dcMor);
-        ManagedObjectReference vmFolderMor = dataCenterMo.getVmFolder();
-
-        //2nd param
-        String vmxFilePath = dsMo.searchFileInSubFolders(vmName + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
-
-        // 5th param
-        ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-
-        ManagedObjectReference morTask = getServiceContext().getService().registerVMTask(vmFolderMor, vmxFilePath, vmName, false, morPool, hyperHost.getMor());
-        boolean result = getServiceContext().getVimClient().waitForTask(morTask);
-        if (!result) {
-            throw new Exception("Unable to register vm due to " + TaskMO.getTaskFailureInfo(getServiceContext(), morTask));
-        } else {
-            getServiceContext().waitForTaskProgressDone(morTask);
-        }
-
-    }
-
-    private Answer execute(ResizeVolumeCommand cmd) {
-        String path = cmd.getPath();
-        String vmName = cmd.getInstanceName();
-        long newSize = cmd.getNewSize() / ResourceType.bytesToKiB;
-        long oldSize = cmd.getCurrentSize() / ResourceType.bytesToKiB;
-        boolean useWorkerVm = false;
-
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        VirtualMachineMO vmMo = null;
-
-        String vmdkDataStorePath = null;
-
-        try {
-            if (newSize < oldSize) {
-                throw new Exception(
-                        "VMware doesn't support shrinking volume from larger size: " + oldSize / ResourceType.bytesToMiB + " GB to a smaller size: " + newSize / ResourceType.bytesToMiB + " GB");
-            } else if (newSize == oldSize) {
-                return new ResizeVolumeAnswer(cmd, true, "success", newSize * ResourceType.bytesToKiB);
-            }
-
-            if (vmName.equalsIgnoreCase("none")) {
-                // we need to spawn a worker VM to attach the volume to and resize the volume.
-                useWorkerVm = true;
-                vmName = getWorkerName(getServiceContext(), cmd, 0);
-
-                String poolId = cmd.getPoolUuid();
-
-                ManagedObjectReference morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
-                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDS);
-
-                s_logger.info("Create worker VM " + vmName);
-
-                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName);
-
-                if (vmMo == null) {
-                    throw new Exception("Unable to create a worker VM for volume resize");
-                }
-
-                synchronized (this) {
-                    vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, path + ".vmdk");
-
-                    vmMo.attachDisk(new String[] { vmdkDataStorePath }, morDS);
-                }
-            }
-
-            // find VM through datacenter (VM is not at the target host yet)
-            vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-
-            if (vmMo == null) {
-                String msg = "VM " + vmName + " does not exist in VMware datacenter";
-
-                s_logger.error(msg);
-
-                throw new Exception(msg);
-            }
-
-            Pair<VirtualDisk, String> vdisk = vmMo.getDiskDevice(path);
-
-            if (vdisk == null) {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("resize volume done (failed)");
-                }
-
-                throw new Exception("No such disk device: " + path);
-            }
-
-            // IDE virtual disk cannot be re-sized if VM is running
-            if (vdisk.second() != null && vdisk.second().contains("ide")) {
-                throw new Exception("Re-sizing a virtual disk over an IDE controller is not supported in the VMware hypervisor. " +
-                            "Please re-try when virtual disk is attached to a VM using a SCSI controller.");
-            }
-
-            if (cmd.isManaged()) {
-                VmwareContext context = getServiceContext();
-
-                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-                ClusterMO clusterMO = new ClusterMO(context, morCluster);
-
-                List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
-
-                Collections.shuffle(lstHosts, RANDOM);
-
-                Pair<ManagedObjectReference, String> host = lstHosts.get(0);
-
-                HostMO hostMO = new HostMO(context, host.first());
-                HostDatastoreSystemMO hostDatastoreSystem = hostMO.getHostDatastoreSystemMO();
-
-                String iScsiName = cmd.get_iScsiName();
-
-                ManagedObjectReference morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, VmwareResource.getDatastoreName(iScsiName));
-                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDS);
-
-                _storageProcessor.expandDatastore(hostDatastoreSystem, dsMo);
-            }
-
-            if (vdisk.second() != null && !vdisk.second().toLowerCase().startsWith("scsi"))
-            {
-                s_logger.error("Unsupported disk device bus "+ vdisk.second());
-                throw new Exception("Unsupported disk device bus "+ vdisk.second());
-            }
-            VirtualDisk disk = vdisk.first();
-            if ((VirtualDiskFlatVer2BackingInfo)disk.getBacking() != null && ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent() != null)
-            {
-                s_logger.error("Resize is not supported because Disk device has Parent "+ ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent().getUuid());
-                throw new Exception("Resize is not supported because Disk device has Parent "+ ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent().getUuid());
-            }
-            String vmdkAbsFile = getAbsoluteVmdkFile(disk);
-
-            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
-                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
-            }
-
-            disk.setCapacityInKB(newSize);
-
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            deviceConfigSpec.setDevice(disk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure VM to resize disk. vmName: " + vmName);
-            }
-
-            return new ResizeVolumeAnswer(cmd, true, "success", newSize * 1024);
-        } catch (Exception e) {
-            s_logger.error("Unable to resize volume", e);
-
-            String error = "Failed to resize volume: " + e.getMessage();
-
-            return new ResizeVolumeAnswer(cmd, false, error);
-        } finally {
-            try {
-                if (useWorkerVm) {
-                    s_logger.info("Destroy worker VM after volume resize");
-
-                    vmMo.detachDisk(vmdkDataStorePath, false);
-                    vmMo.destroy();
-                }
-            } catch (Throwable e) {
-                s_logger.info("Failed to destroy worker VM: " + vmName);
-            }
-        }
-    }
-
-    protected Answer execute(CheckNetworkCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CheckNetworkCommand " + _gson.toJson(cmd));
-        }
-
-        // TODO setup portgroup for private network needs to be done here now
-        return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done");
-    }
-
-    protected Answer execute(NetworkUsageCommand cmd) {
-        if (cmd.isForVpc()) {
-            return VPCNetworkUsage(cmd);
-        }
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource NetworkUsageCommand " + _gson.toJson(cmd));
-        }
-        if (cmd.getOption() != null && cmd.getOption().equals("create")) {
-            String result = networkUsage(cmd.getPrivateIP(), "create", null);
-            NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L);
-            return answer;
-        }
-        long[] stats = getNetworkStats(cmd.getPrivateIP());
-
-        NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
-        return answer;
-    }
-
-    protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) {
-        String privateIp = cmd.getPrivateIP();
-        String option = cmd.getOption();
-        String publicIp = cmd.getGatewayIP();
-
-        String args = "-l " + publicIp + " ";
-        if (option.equals("get")) {
-            args += "-g";
-        } else if (option.equals("create")) {
-            args += "-c";
-            String vpcCIDR = cmd.getVpcCIDR();
-            args += " -v " + vpcCIDR;
-        } else if (option.equals("reset")) {
-            args += "-r";
-        } else if (option.equals("vpn")) {
-            args += "-n";
-        } else if (option.equals("remove")) {
-            args += "-d";
-        } else {
-            return new NetworkUsageAnswer(cmd, "success", 0L, 0L);
-        }
-
-        ExecutionResult callResult = executeInVR(privateIp, "vpc_netusage.sh", args);
-
-        if (!callResult.isSuccess()) {
-            s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + callResult.getDetails());
-        }
-
-        if (option.equals("get") || option.equals("vpn")) {
-            String result = callResult.getDetails();
-            if (result == null || result.isEmpty()) {
-                s_logger.error(" vpc network usage get returns empty ");
-            }
-            long[] stats = new long[2];
-            if (result != null) {
-                String[] splitResult = result.split(":");
-                int i = 0;
-                while (i < splitResult.length - 1) {
-                    stats[0] += Long.parseLong(splitResult[i++]);
-                    stats[1] += Long.parseLong(splitResult[i++]);
-                }
-                return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]);
-            }
-        }
-        return new NetworkUsageAnswer(cmd, "success", 0L, 0L);
-    }
-
-    @Override
-    public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) {
-        File keyFile = getSystemVmKeyFile();
-        try {
-            SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes("UTF-8"), fileName, null);
-        } catch (Exception e) {
-            s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
-        //Update IP used to access router
-        cmd.setRouterAccessIp(getRouterSshControlIp(cmd));
-        assert cmd.getRouterAccessIp() != null;
-
-        if (cmd instanceof IpAssocVpcCommand) {
-            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
-        } else if (cmd instanceof IpAssocCommand) {
-            return prepareNetworkElementCommand((IpAssocCommand)cmd);
-        } else if (cmd instanceof SetSourceNatCommand) {
-            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
-        } else if (cmd instanceof SetupGuestNetworkCommand) {
-            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
-        } else if (cmd instanceof SetNetworkACLCommand) {
-            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
-        return new ExecutionResult(true, null);
-    }
-
-    //
-    // list IP with eth devices
-    //  ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
-    //     | awk -F: '{ print $1 ": " $3 }'
-    //
-    // returns
-    //      eth0:xx.xx.xx.xx
-    //
-    //
-    private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception {
-        File keyFile = getSystemVmKeyFile();
-        s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
-        ArrayList<String> skipInterfaces = new ArrayList<String>(Arrays.asList("all", "default", "lo"));
-
-        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
-        // we use a waiting loop here as a workaround to synchronize activities in systems
-        long startTick = System.currentTimeMillis();
-        long waitTimeoutMillis = VmwareManager.s_vmwareNicHotplugWaitTimeout.value();
-        while (System.currentTimeMillis() - startTick < waitTimeoutMillis) {
-
-            // TODO : this is a temporary very inefficient solution, will refactor it later
-            Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", keyFile, null, "ls /proc/sys/net/ipv4/conf");
-            if (result.first()) {
-                String[] tokens = result.second().split("\\s+");
-                for (String token : tokens) {
-                    if (!(skipInterfaces.contains(token))) {
-                        String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
-
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("Run domr script " + cmd);
-                        Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", keyFile, null,
-                                // TODO need to find the dev index inside router based on IP address
-                                cmd);
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
-
-                        if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) {
-                            return Integer.parseInt(token.substring(3));
-                        } else {
-                            skipInterfaces.add(token);
-                        }
-                    }
-                }
-            }
-
-            s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
-
-            try {
-                Thread.currentThread();
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-                s_logger.debug("[ignored] interupted while trying to get mac.");
-            }
-        }
-
-        return -1;
-    }
-
-    private VirtualDevice findVirtualNicDevice(VirtualMachineMO vmMo, String mac) throws Exception {
-
-        VirtualDevice[] nics = vmMo.getNicDevices();
-        for (VirtualDevice nic : nics) {
-            if (nic instanceof VirtualEthernetCard) {
-                if (((VirtualEthernetCard)nic).getMacAddress().equals(mac))
-                    return nic;
-            }
-        }
-        return null;
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
-        NicTO nic = cmd.getNic();
-        String routerIp = getRouterSshControlIp(cmd);
-        String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac());
-            nic.setDeviceId(ethDeviceNum);
-        } catch (Exception e) {
-            String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
-
-        try {
-            IpAddressTO[] ips = cmd.getIpAddresses();
-            for (IpAddressTO ip : ips) {
-
-                int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress());
-                if (ethDeviceNum < 0) {
-                    if (ip.isAdd()) {
-                        throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
-                    } else {
-                        s_logger.debug("VIF to deassociate IP with does not exist, return success");
-                        continue;
-                    }
-                }
-
-                ip.setNicDevId(ethDeviceNum);
-            }
-        } catch (Exception e) {
-            s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.toString());
-        }
-
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
-        IpAddressTO pubIp = cmd.getIpAddress();
-
-        try {
-            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
-            pubIp.setNicDevId(ethDeviceNum);
-        } catch (Exception e) {
-            String msg = "Prepare Ip SNAT failure due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, e.toString());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) {
-        NicTO nic = cmd.getNic();
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
-
-        try {
-            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac());
-            nic.setDeviceId(ethDeviceNum);
-        } catch (Exception e) {
-            String msg = "Prepare SetNetworkACL failed due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    private PlugNicAnswer execute(PlugNicCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PlugNicCommand " + _gson.toJson(cmd));
-        }
-
-        getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-        VmwareContext context = getServiceContext();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-            String vmName = cmd.getVmName();
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-
-            if (vmMo == null) {
-                if (hyperHost instanceof HostMO) {
-                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
-                    vmMo = clusterMo.findVmOnHyperHost(vmName);
-                }
-            }
-
-            if (vmMo == null) {
-                String msg = "Router " + vmName + " no longer exists to execute PlugNic command";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            /*
-            if(!isVMWareToolsInstalled(vmMo)){
-                String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName;
-                s_logger.debug(errMsg);
-                return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg);
-            }
-             */
-            // Fallback to E1000 if no specific nicAdapter is passed
-            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000;
-            Map<String, String> details = cmd.getDetails();
-            if (details != null) {
-                nicDeviceType = VirtualEthernetCardType.valueOf((String)details.get("nicAdapter"));
-            }
-
-            // find a usable device number in VMware environment
-            VirtualDevice[] nicDevices = vmMo.getNicDevices();
-            int deviceNumber = -1;
-            for (VirtualDevice device : nicDevices) {
-                if (device.getUnitNumber() > deviceNumber)
-                    deviceNumber = device.getUnitNumber();
-            }
-            deviceNumber++;
-
-            NicTO nicTo = cmd.getNic();
-            VirtualDevice nic;
-            Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
-            String dvSwitchUuid = null;
-            if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
-                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-                DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
-                ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
-                dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
-                s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
-                nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid,
-                        nicTo.getMac(), deviceNumber + 1, true, true);
-            } else {
-                s_logger.info("Preparing NIC device on network " + networkInfo.second());
-                nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(),
-                        nicTo.getMac(), deviceNumber + 1, true, true);
-            }
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(nic);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when running PlugNicCommand");
-            }
-
-            return new PlugNicAnswer(cmd, true, "success");
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
-        }
-    }
-
-    private ReplugNicAnswer execute(ReplugNicCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ReplugNicCommand " + _gson.toJson(cmd));
-        }
-
-        getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-        VmwareContext context = getServiceContext();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-            String vmName = cmd.getVmName();
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-
-            if (vmMo == null) {
-                if (hyperHost instanceof HostMO) {
-                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
-                    vmMo = clusterMo.findVmOnHyperHost(vmName);
-                }
-            }
-
-            if (vmMo == null) {
-                String msg = "Router " + vmName + " no longer exists to execute ReplugNic command";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            /*
-            if(!isVMWareToolsInstalled(vmMo)){
-                String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName;
-                s_logger.debug(errMsg);
-                return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg);
-            }
-             */
-            // Fallback to E1000 if no specific nicAdapter is passed
-            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000;
-            Map<String, String> details = cmd.getDetails();
-            if (details != null) {
-                nicDeviceType = VirtualEthernetCardType.valueOf((String) details.get("nicAdapter"));
-            }
-
-            NicTO nicTo = cmd.getNic();
-
-            VirtualDevice nic = findVirtualNicDevice(vmMo, nicTo.getMac());
-            if (nic == null) {
-                return new ReplugNicAnswer(cmd, false, "Nic to replug not found");
-            }
-
-            Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
-            String dvSwitchUuid = null;
-            if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
-                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-                DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
-                ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
-                dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
-                s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
-                VmwareHelper.updateDvNicDevice(nic, networkInfo.first(), dvSwitchUuid);
-            } else {
-                s_logger.info("Preparing NIC device on network " + networkInfo.second());
-
-                VmwareHelper.updateNicDevice(nic, networkInfo.first(), networkInfo.second());
-            }
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(nic);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when running ReplugNicCommand");
-            }
-
-            return new ReplugNicAnswer(cmd, true, "success");
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new ReplugNicAnswer(cmd, false, "Unable to execute ReplugNicCommand due to " + e.toString());
-        }
-    }
-
-    private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource UnPlugNicCommand " + _gson.toJson(cmd));
-        }
-
-        VmwareContext context = getServiceContext();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-            String vmName = cmd.getVmName();
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-
-            if (vmMo == null) {
-                if (hyperHost instanceof HostMO) {
-                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
-                    vmMo = clusterMo.findVmOnHyperHost(vmName);
-                }
-            }
-
-            if (vmMo == null) {
-                String msg = "VM " + vmName + " no longer exists to execute UnPlugNic command";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            /*
-            if(!isVMWareToolsInstalled(vmMo)){
-                String errMsg = "vmware tools not installed or not running, cannot remove nic from vm " + vmName;
-                s_logger.debug(errMsg);
-                return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + errMsg);
-            }
-             */
-            VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac());
-            if (nic == null) {
-                return new UnPlugNicAnswer(cmd, true, "success");
-            }
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(nic);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when running unplugNicCommand");
-            }
-
-            return new UnPlugNicAnswer(cmd, true, "success");
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString());
-        }
-    }
-
-    private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final IpAddressTO ipAddressTO) throws Exception {
-        // TODO : probably need to set traffic shaping
-        Pair<ManagedObjectReference, String> networkInfo = null;
-        VirtualSwitchType vSwitchType = VirtualSwitchType.StandardVirtualSwitch;
-        if (_publicTrafficInfo != null) {
-            vSwitchType = _publicTrafficInfo.getVirtualSwitchType();
-        }
-        /** FIXME We have no clue which network this nic is on and that means that we can't figure out the BroadcastDomainType
-         *  so we assume that it's VLAN for now
-         */
-        if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
-            networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(),
-                    "cloud.public", vmMo.getRunningHost(), vlanId, ipAddressTO.getNetworkRate(), null,
-                    _opsTimeout, true, BroadcastDomainType.Vlan, null, null);
-        } else {
-            networkInfo =
-                    HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, ipAddressTO.getNetworkRate(), null,
-                            _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null);
-        }
-
-        int nicIndex = allocPublicNicIndex(vmMo);
-
-        try {
-            VirtualDevice[] nicDevices = vmMo.getNicDevices();
-
-            VirtualEthernetCard device = (VirtualEthernetCard)nicDevices[nicIndex];
-
-            if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
-                VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
-                nicBacking.setDeviceName(networkInfo.second());
-                nicBacking.setNetwork(networkInfo.first());
-                device.setBacking(nicBacking);
-            } else {
-                HostMO hostMo = vmMo.getRunningHost();
-                DatacenterMO dataCenterMo = new DatacenterMO(hostMo.getContext(), hostMo.getHyperHostDatacenter());
-                device.setBacking(dataCenterMo.getDvPortBackingInfo(networkInfo));
-            }
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(device);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when plugPublicNic");
-            }
-        } catch (Exception e) {
-
-            // restore allocation mask in case of exceptions
-            String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
-            int nicMasks = Integer.parseInt(nicMasksStr);
-            nicMasks &= ~(1 << nicIndex);
-            vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
-
-            throw e;
-        }
-    }
-
-    private int allocPublicNicIndex(VirtualMachineMO vmMo) throws Exception {
-        String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
-        if (nicMasksStr == null || nicMasksStr.isEmpty()) {
-            throw new Exception("Could not find NIC allocation info");
-        }
-
-        int nicMasks = Integer.parseInt(nicMasksStr);
-        VirtualDevice[] nicDevices = vmMo.getNicDevices();
-        for (int i = 3; i < nicDevices.length; i++) {
-            if ((nicMasks & (1 << i)) == 0) {
-                nicMasks |= (1 << i);
-                vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
-                return i;
-            }
-        }
-
-        throw new Exception("Could not allocate a free public NIC");
-    }
-
-    private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
-        VmwareContext context = getServiceContext();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-            IpAddressTO[] ips = cmd.getIpAddresses();
-            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-            String controlIp = VmwareResource.getRouterSshControlIp(cmd);
-
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName);
-
-            // command may sometimes be redirect to a wrong host, we relax
-            // the check and will try to find it within cluster
-            if (vmMo == null) {
-                if (hyperHost instanceof HostMO) {
-                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
-                    vmMo = clusterMo.findVmOnHyperHost(routerName);
-                }
-            }
-
-            if (vmMo == null) {
-                String msg = "Router " + routerName + " no longer exists to execute IPAssoc command";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            for (IpAddressTO ip : ips) {
-                /**
-                 * TODO support other networks
-                 */
-                URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
-                    throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri());
-                }
-                String vlanId = BroadcastDomainType.getValue(broadcastUri);
-
-                String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
-                Pair<Integer, VirtualDevice> publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first());
-                }
-
-                boolean addVif = false;
-                if (ip.isAdd() && publicNicInfo.first().intValue() == -1) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp());
-                    }
-                    addVif = true;
-                }
-
-                if (addVif) {
-                    plugPublicNic(vmMo, vlanId, ip);
-                    publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
-                    if (publicNicInfo.first().intValue() >= 0) {
-                        networkUsage(controlIp, "addVif", "eth" + publicNicInfo.first());
-                    }
-                }
-
-                if (publicNicInfo.first().intValue() < 0) {
-                    String msg = "Failed to find DomR VIF to associate/disassociate IP with.";
-                    s_logger.error(msg);
-                    throw new InternalErrorException(msg);
-                }
-                ip.setNicDevId(publicNicInfo.first().intValue());
-                ip.setNewNic(addVif);
-            }
-        } catch (Throwable e) {
-            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
-            return new ExecutionResult(false, e.toString());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    @Override
-    public ExecutionResult executeInVR(String routerIP, String script, String args) {
-        return executeInVR(routerIP, script, args, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
-    }
-
-    @Override
-    public ExecutionResult executeInVR(String routerIP, String script, String args, Duration timeout) {
-        Pair<Boolean, String> result;
-
-        //TODO: Password should be masked, cannot output to log directly
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args);
-        }
-
-        try {
-            result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", getSystemVmKeyFile(), null, "/opt/cloud/bin/" + script + " " + args,
-                    VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout);
-        } catch (Exception e) {
-            String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            result = new Pair<Boolean, String>(false, msg);
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(script + " execution result: " + result.first().toString());
-        }
-        return new ExecutionResult(result.first(), result.second());
-    }
-
-    protected CheckSshAnswer execute(CheckSshCommand cmd) {
-        String vmName = cmd.getName();
-        String privateIp = cmd.getIp();
-        int cmdPort = cmd.getPort();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
-        }
-
-        try {
-            String result = connect(cmd.getName(), privateIp, cmdPort);
-            if (result != null) {
-                s_logger.error("Can not ping System vm " + vmName + "due to:" + result);
-                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
-            }
-        } catch (Exception e) {
-            s_logger.error("Can not ping System vm " + vmName + "due to exception");
-            return new CheckSshAnswer(cmd, e);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Ping command port succeeded for vm " + vmName);
-        }
-
-        if (VirtualMachineName.isValidRouterName(vmName)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Execute network usage setup command on " + vmName);
-            }
-            networkUsage(privateIp, "create", null);
-        }
-
-        return new CheckSshAnswer(cmd);
-    }
-
-    private DiskTO[] validateDisks(DiskTO[] disks) {
-        List<DiskTO> validatedDisks = new ArrayList<DiskTO>();
-
-        for (DiskTO vol : disks) {
-            if (vol.getType() != Volume.Type.ISO) {
-                VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-                DataStoreTO primaryStore = volumeTO.getDataStore();
-                if (primaryStore.getUuid() != null && !primaryStore.getUuid().isEmpty()) {
-                    validatedDisks.add(vol);
-                }
-            } else if (vol.getType() == Volume.Type.ISO) {
-                TemplateObjectTO templateTO = (TemplateObjectTO)vol.getData();
-                if (templateTO.getPath() != null && !templateTO.getPath().isEmpty()) {
-                    validatedDisks.add(vol);
-                }
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Drop invalid disk option, volumeTO: " + _gson.toJson(vol));
-                }
-            }
-        }
-        Collections.sort(validatedDisks, (d1, d2) -> d1.getDiskSeq().compareTo(d2.getDiskSeq()));
-        return validatedDisks.toArray(new DiskTO[0]);
-    }
-
-    private static DiskTO getIsoDiskTO(DiskTO[] disks) {
-        for (DiskTO vol : disks) {
-            if (vol.getType() == Volume.Type.ISO) {
-                return vol;
-            }
-        }
-        return null;
-    }
-
-    protected ScaleVmAnswer execute(ScaleVmCommand cmd) {
-
-        VmwareContext context = getServiceContext();
-        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            int ramMb = getReservedMemoryMb(vmSpec);
-            long hotaddIncrementSizeInMb;
-            long hotaddMemoryLimitInMb;
-            long requestedMaxMemoryInMb = vmSpec.getMaxRam() / (1024 * 1024);
-
-            // Check if VM is really running on hypervisor host
-            if (getVmPowerState(vmMo) != PowerState.PowerOn) {
-                throw new CloudRuntimeException("Found that the VM " + vmMo.getVmName() + " is not running. Unable to scale-up this VM");
-            }
-
-            // Check max hot add limit
-            hotaddIncrementSizeInMb = vmMo.getHotAddMemoryIncrementSizeInMb();
-            hotaddMemoryLimitInMb = vmMo.getHotAddMemoryLimitInMb();
-            if (requestedMaxMemoryInMb > hotaddMemoryLimitInMb) {
-                throw new CloudRuntimeException("Memory of VM " + vmMo.getVmName() + " cannot be scaled to " + requestedMaxMemoryInMb + "MB."
-                        + " Requested memory limit is beyond the hotadd memory limit for this VM at the moment is " + hotaddMemoryLimitInMb + "MB.");
-            }
-
-            // Check increment is multiple of increment size
-            long reminder = requestedMaxMemoryInMb % hotaddIncrementSizeInMb;
-            if (reminder != 0) {
-                requestedMaxMemoryInMb = requestedMaxMemoryInMb + hotaddIncrementSizeInMb - reminder;
-            }
-
-            // Check if license supports the feature
-            VmwareHelper.isFeatureLicensed(hyperHost, FeatureKeyConstants.HOTPLUG);
-            VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(), (int)requestedMaxMemoryInMb, ramMb,
-                    vmSpec.getLimitCpuUse());
-
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Unable to execute ScaleVmCommand");
-            }
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new ScaleVmAnswer(cmd, false, "Unable to execute ScaleVmCommand due to " + e.toString());
-        }
-        return new ScaleVmAnswer(cmd, true, null);
-    }
-
-    protected void ensureDiskControllers(VirtualMachineMO vmMo, Pair<String, String> controllerInfo) throws Exception {
-        if (vmMo == null) {
-            return;
-        }
-
-        String msg;
-        String rootDiskController = controllerInfo.first();
-        String dataDiskController = controllerInfo.second();
-        String scsiDiskController;
-        String recommendedDiskController = null;
-
-        if (VmwareHelper.isControllerOsRecommended(dataDiskController) || VmwareHelper.isControllerOsRecommended(rootDiskController)) {
-            recommendedDiskController = vmMo.getRecommendedDiskController(null);
-        }
-        scsiDiskController = HypervisorHostHelper.getScsiController(new Pair<String, String>(rootDiskController, dataDiskController), recommendedDiskController);
-        if (scsiDiskController == null) {
-            return;
-        }
-
-        vmMo.getScsiDeviceControllerKeyNoException();
-        // This VM needs SCSI controllers.
-        // Get count of existing scsi controllers. Helps not to attempt to create more than the maximum allowed 4
-        // Get maximum among the bus numbers in use by scsi controllers. Safe to pick maximum, because we always go sequential allocating bus numbers.
-        Ternary<Integer, Integer, DiskControllerType> scsiControllerInfo = vmMo.getScsiControllerInfo();
-        int requiredNumScsiControllers = VmwareHelper.MAX_SCSI_CONTROLLER_COUNT - scsiControllerInfo.first();
-        int availableBusNum = scsiControllerInfo.second() + 1; // method returned current max. bus number
-
-        if (requiredNumScsiControllers == 0) {
-            return;
-        }
-        if (scsiControllerInfo.first() > 0) {
-            // For VMs which already have a SCSI controller, do NOT attempt to add any more SCSI controllers & return the sub type.
-            // For Legacy VMs would have only 1 LsiLogic Parallel SCSI controller, and doesn't require more.
-            // For VMs created post device ordering support, 4 SCSI subtype controllers are ensured during deployment itself. No need to add more.
-            // For fresh VM deployment only, all required controllers should be ensured.
-            return;
-        }
-        ensureScsiDiskControllers(vmMo, scsiDiskController, requiredNumScsiControllers, availableBusNum);
-    }
-
-    private void ensureScsiDiskControllers(VirtualMachineMO vmMo, String scsiDiskController, int requiredNumScsiControllers, int availableBusNum) throws Exception {
-        // Pick the sub type of scsi
-        if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.pvscsi) {
-            if (!vmMo.isPvScsiSupported()) {
-                String msg = "This VM doesn't support Vmware Paravirtual SCSI controller for virtual disks, because the virtual hardware version is less than 7.";
-                throw new Exception(msg);
-            }
-            vmMo.ensurePvScsiDeviceController(requiredNumScsiControllers, availableBusNum);
-        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.lsisas1068) {
-            vmMo.ensureLsiLogicSasDeviceControllers(requiredNumScsiControllers, availableBusNum);
-        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.buslogic) {
-            vmMo.ensureBusLogicDeviceControllers(requiredNumScsiControllers, availableBusNum);
-        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.lsilogic) {
-            vmMo.ensureLsiLogicDeviceControllers(requiredNumScsiControllers, availableBusNum);
-        }
-    }
-
-    protected StartAnswer execute(StartCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
-        }
-
-        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
-        boolean vmAlreadyExistsInVcenter = false;
-
-        String existingVmName = null;
-        VirtualMachineFileInfo existingVmFileInfo = null;
-        VirtualMachineFileLayoutEx existingVmFileLayout = null;
-        List<DatastoreMO> existingDatastores = new ArrayList<DatastoreMO>();
-
-        Pair<String, String> names = composeVmNames(vmSpec);
-        String vmInternalCSName = names.first();
-        String vmNameOnVcenter = names.second();
-        String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
-        String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
-        DiskTO rootDiskTO = null;
-        // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
-        // This helps avoid mix of different scsi subtype controllers in instance.
-        if (DiskControllerType.osdefault == DiskControllerType.getType(dataDiskController) && DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
-            dataDiskController = DiskControllerType.scsi.toString();
-        }
-
-        // Validate the controller types
-        dataDiskController = DiskControllerType.getType(dataDiskController).toString();
-        rootDiskController = DiskControllerType.getType(rootDiskController).toString();
-
-        if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
-            throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
-        }
-        if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
-            throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
-        }
-
-        Pair<String, String> controllerInfo = new Pair<String, String>(rootDiskController, dataDiskController);
-
-        Boolean systemVm = vmSpec.getType().isUsedBySystem();
-        // Thus, vmInternalCSName always holds i-x-y, the cloudstack generated internal VM name.
-        VmwareContext context = getServiceContext();
-        DatacenterMO dcMo = null;
-        try {
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            dcMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter());
-
-            // Validate VM name is unique in Datacenter
-            VirtualMachineMO vmInVcenter = dcMo.checkIfVmAlreadyExistsInVcenter(vmNameOnVcenter, vmInternalCSName);
-            if (vmInVcenter != null) {
-                vmAlreadyExistsInVcenter = true;
-                String msg = "VM with name: " + vmNameOnVcenter + " already exists in vCenter.";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-            String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
-            DiskTO[] disks = validateDisks(vmSpec.getDisks());
-            assert (disks.length > 0);
-            NicTO[] nics = vmSpec.getNics();
-
-            HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks, cmd);
-            if ((dataStoresDetails == null) || (dataStoresDetails.isEmpty())) {
-                String msg = "Unable to locate datastore details of the volumes to be attached";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
-            if (dsRootVolumeIsOn == null) {
-                String msg = "Unable to locate datastore details of root volume";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
-            DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
-            int firstScsiControllerBusNum = 0;
-            int numScsiControllerForSystemVm = 1;
-            boolean hasSnapshot = false;
-            if (vmMo != null) {
-                s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
-                if (getVmPowerState(vmMo) != PowerState.PowerOff)
-                    vmMo.safePowerOff(_shutdownWaitMs);
-
-                // retrieve disk information before we tear down
-                diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                hasSnapshot = vmMo.hasSnapshot();
-                if (!hasSnapshot)
-                    vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
-                else
-                    vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
-                if (systemVm) {
-                    ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
-                } else {
-                    ensureDiskControllers(vmMo, controllerInfo);
-                }
-            } else {
-                ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
-                assert (morDc != null);
-
-                vmMo = hyperHost.findVmOnPeerHyperHost(vmInternalCSName);
-                if (vmMo != null) {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Found vm " + vmInternalCSName + " at other host, relocate to " + hyperHost.getHyperHostName());
-                    }
-
-                    takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
-
-                    if (getVmPowerState(vmMo) != PowerState.PowerOff)
-                        vmMo.safePowerOff(_shutdownWaitMs);
-
-                    diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                    hasSnapshot = vmMo.hasSnapshot();
-                    if (!hasSnapshot)
-                        vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
-                    else
-                        vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
-
-                    if (systemVm) {
-                        // System volumes doesn't require more than 1 SCSI controller as there is no requirement for data volumes.
-                        ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
-                    } else {
-                        ensureDiskControllers(vmMo, controllerInfo);
-                    }
-                } else {
-                    // If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
-                    VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
-                    if (existingVmInDc != null) {
-                        s_logger.debug("Found VM: " + vmInternalCSName + " on a host in a different cluster. Unregistering the exisitng VM.");
-                        existingVmName = existingVmInDc.getName();
-                        existingVmFileInfo = existingVmInDc.getFileInfo();
-                        existingVmFileLayout = existingVmInDc.getFileLayout();
-                        existingDatastores = existingVmInDc.getAllDatastores();
-                        existingVmInDc.unregisterVm();
-                    }
-                    Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
-                    for (DiskTO vol : disks) {
-                        if (vol.getType() == Volume.Type.ROOT) {
-                            Map<String, String> details = vol.getDetails();
-                            boolean managed = false;
-
-                            if (details != null) {
-                                managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-                            }
-
-                            if (managed) {
-                                String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
-
-                                rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
-                            } else {
-                                DataStoreTO primaryStore = vol.getData().getDataStore();
-
-                                rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
-                            }
-                        }
-                    }
-
-                    assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
-
-                    boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
-                    String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                    if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present.
-                        registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
-                        vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
-                        if (vmMo != null) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
-                            }
-                        }
-                        tearDownVm(vmMo);
-                    } else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec),
-                            vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / ResourceType.bytesToMiB), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false,
-                            controllerInfo, systemVm)) {
-                        throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
-                    }
-                }
-
-                vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
-                if (vmMo == null) {
-                    throw new Exception("Failed to find the newly create or relocated VM. vmName: " + vmInternalCSName);
-                }
-            }
-
-            int totalChangeDevices = disks.length + nics.length;
-
-            DiskTO volIso = null;
-            if (vmSpec.getType() != VirtualMachine.Type.User) {
-                // system VM needs a patch ISO
-                totalChangeDevices++;
-            } else {
-                volIso = getIsoDiskTO(disks);
-                if (volIso == null)
-                    totalChangeDevices++;
-            }
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-
-            VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)),
-                    getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse());
-
-            // Check for multi-cores per socket settings
-            int numCoresPerSocket = 1;
-            String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket");
-            if (coresPerSocket != null) {
-                String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext());
-                // Property 'numCoresPerSocket' is supported since vSphere API 5.0
-                if (apiVersion.compareTo("5.0") >= 0) {
-                    numCoresPerSocket = NumbersUtil.parseInt(coresPerSocket, 1);
-                    vmConfigSpec.setNumCoresPerSocket(numCoresPerSocket);
-                }
-            }
-
-            // Check for hotadd settings
-            vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId));
-
-            String hostApiVersion = ((HostMO)hyperHost).getHostAboutInfo().getApiVersion();
-            if (numCoresPerSocket > 1 && hostApiVersion.compareTo("5.0") < 0) {
-                s_logger.warn("Dynamic scaling of CPU is not supported for Virtual Machines with multi-core vCPUs in case of ESXi hosts 4.1 and prior. Hence CpuHotAdd will not be"
-                        + " enabled for Virtual Machine: " + vmInternalCSName);
-                vmConfigSpec.setCpuHotAddEnabled(false);
-            } else {
-                vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId));
-            }
-
-            configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
-
-            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
-            int i = 0;
-            int ideUnitNumber = 0;
-            int scsiUnitNumber = 0;
-            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
-            int scsiControllerKey = vmMo.getGenericScsiDeviceControllerKeyNoException();
-            int controllerKey;
-
-            //
-            // Setup ISO device
-            //
-
-            // prepare systemvm patch ISO
-            if (vmSpec.getType() != VirtualMachine.Type.User) {
-                // attach ISO (for patching of system VM)
-                Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
-                String secStoreUrl = secStoreUrlAndId.first();
-                Long secStoreId = secStoreUrlAndId.second();
-                if (secStoreUrl == null) {
-                    String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
-                    throw new Exception(msg);
-                }
-                mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
-
-                ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
-                if (morSecDs == null) {
-                    String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
-                    throw new Exception(msg);
-                }
-                DatastoreMO secDsMo = new DatastoreMO(hyperHost.getContext(), morSecDs);
-
-                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo,
-                        String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), true, true, ideUnitNumber++, i + 1);
-                deviceConfigSpecArray[i].setDevice(isoInfo.first());
-                if (isoInfo.second()) {
-                    if (s_logger.isDebugEnabled())
-                        s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
-                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-                } else {
-                    if (s_logger.isDebugEnabled())
-                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
-                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-                }
-                i++;
-            } else {
-                // Note: we will always plug a CDROM device
-                if (volIso != null) {
-                    for (DiskTO vol : disks) {
-                        if (vol.getType() == Volume.Type.ISO) {
-
-                            TemplateObjectTO iso = (TemplateObjectTO) vol.getData();
-
-                            if (iso.getPath() != null && !iso.getPath().isEmpty()) {
-                                DataStoreTO imageStore = iso.getDataStore();
-                                if (!(imageStore instanceof NfsTO)) {
-                                    s_logger.debug("unsupported protocol");
-                                    throw new Exception("unsupported protocol");
-                                }
-                                NfsTO nfsImageStore = (NfsTO) imageStore;
-                                String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
-                                Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath);
-                                assert (isoDatastoreInfo != null);
-                                assert (isoDatastoreInfo.second() != null);
-
-                                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                                Pair<VirtualDevice, Boolean> isoInfo =
-                                        VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1);
-                                deviceConfigSpecArray[i].setDevice(isoInfo.first());
-                                if (isoInfo.second()) {
-                                    if (s_logger.isDebugEnabled())
-                                        s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
-                                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-                                } else {
-                                    if (s_logger.isDebugEnabled())
-                                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
-                                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-                                }
-                            }
-                            i++;
-                        }
-                    }
-                } else {
-                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                    Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, null, null, true, true, ideUnitNumber++, i + 1);
-                    deviceConfigSpecArray[i].setDevice(isoInfo.first());
-                    if (isoInfo.second()) {
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
-
-                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-                    } else {
-                        if (s_logger.isDebugEnabled())
-                            s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
-
-                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-                    }
-                    i++;
-                }
-            }
-
-
-
-            //
-            // Setup ROOT/DATA disk devices
-            //
-            DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
-            for (DiskTO vol : sortedDisks) {
-                if (vol.getType() == Volume.Type.ISO)
-                    continue;
-
-                VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
-                controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey);
-                String diskController = getDiskController(vmMo, matchingExistingDisk, vol, new Pair<String, String>(rootDiskController, dataDiskController));
-
-                if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
-                    diskController = vmMo.getRecommendedDiskController(null);
-                }
-                if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
-                    controllerKey = vmMo.getIDEControllerKey(ideUnitNumber);
-                    if (vol.getType() == Volume.Type.DATADISK) {
-                        // Could be result of flip due to user configured setting or "osdefault" for data disks
-                        // Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
-                        if (vmMo.getNumberOfVirtualDisks() > 3) {
-                            throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over "
-                                    + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device.");
-                        }
-                    }
-                } else {
-                    controllerKey = vmMo.getScsiDiskControllerKeyNoException(diskController);
-                    if (controllerKey == -1) {
-                        // This may happen for ROOT legacy VMs which doesn't have recommended disk controller when global configuration parameter 'vmware.root.disk.controller' is set to "osdefault"
-                        // Retrieve existing controller and use.
-                        Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
-                        DiskControllerType existingControllerType = vmScsiControllerInfo.third();
-                        controllerKey = vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString());
-                    }
-                }
-                if (!hasSnapshot) {
-                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-
-                    VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-                    DataStoreTO primaryStore = volumeTO.getDataStore();
-                    Map<String, String> details = vol.getDetails();
-                    boolean managed = false;
-                    String iScsiName = null;
-
-                    if (details != null) {
-                        managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-                        iScsiName = details.get(DiskTO.IQN);
-                    }
-
-                    // if the storage is managed, iScsiName should not be null
-                    String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
-                    Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
-
-                    assert (volumeDsDetails != null);
-
-                    String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
-                    if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
-                        scsiUnitNumber++;
-                    VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(),
-                            (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) ? ((ideUnitNumber++) % VmwareHelper.MAX_IDE_CONTROLLER_COUNT) : scsiUnitNumber++, i + 1);
-
-                    if (vol.getType() == Volume.Type.ROOT)
-                        rootDiskTO = vol;
-                    deviceConfigSpecArray[i].setDevice(device);
-                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                    if (s_logger.isDebugEnabled())
-                        s_logger.debug("Prepare volume at new device " + _gson.toJson(device));
-
-                    i++;
-                } else {
-                    if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
-                        scsiUnitNumber++;
-                    if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber))
-                        ideUnitNumber++;
-                    else
-                        scsiUnitNumber++;
-                }
-            }
-
-            //
-            // Setup USB devices
-            //
-            if (guestOsId.startsWith("darwin")) { //Mac OS
-                VirtualDevice[] devices = vmMo.getMatchedDevices(new Class<?>[] {VirtualUSBController.class});
-                if (devices.length == 0) {
-                    s_logger.debug("No USB Controller device on VM Start. Add USB Controller device for Mac OS VM " + vmInternalCSName);
-
-                    //For Mac OS X systems, the EHCI+UHCI controller is enabled by default and is required for USB mouse and keyboard access.
-                    VirtualDevice usbControllerDevice = VmwareHelper.prepareUSBControllerDevice();
-                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                    deviceConfigSpecArray[i].setDevice(usbControllerDevice);
-                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                    if (s_logger.isDebugEnabled())
-                        s_logger.debug("Prepare USB controller at new device " + _gson.toJson(deviceConfigSpecArray[i]));
-
-                    i++;
-                } else {
-                    s_logger.debug("USB Controller device exists on VM Start for Mac OS VM " + vmInternalCSName);
-                }
-            }
-
-            //
-            // Setup NIC devices
-            //
-            VirtualDevice nic;
-            int nicMask = 0;
-            int nicCount = 0;
-
-            if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
-                int extraPublicNics = mgr.getRouterExtraPublicNics();
-                if (extraPublicNics > 0 && vmSpec.getDetails().containsKey("PeerRouterInstanceName")) {
-                    //Set identical MAC address for RvR on extra public interfaces
-                    String peerRouterInstanceName = vmSpec.getDetails().get("PeerRouterInstanceName");
-
-                    VirtualMachineMO peerVmMo = hyperHost.findVmOnHyperHost(peerRouterInstanceName);
-                    if (peerVmMo == null) {
-                        peerVmMo = hyperHost.findVmOnPeerHyperHost(peerRouterInstanceName);
-                    }
-
-                    if (peerVmMo != null) {
-                        String oldMacSequence = generateMacSequence(nics);
-
-                        for (int nicIndex = nics.length - extraPublicNics; nicIndex < nics.length; nicIndex++) {
-                            VirtualDevice nicDevice = peerVmMo.getNicDeviceByIndex(nics[nicIndex].getDeviceId());
-                            if (nicDevice != null) {
-                                String mac = ((VirtualEthernetCard)nicDevice).getMacAddress();
-                                if (mac != null) {
-                                    s_logger.info("Use same MAC as previous RvR, the MAC is " + mac + " for extra NIC with device id: " + nics[nicIndex].getDeviceId());
-                                    nics[nicIndex].setMac(mac);
-                                }
-                            }
-                        }
-
-                        if (!StringUtils.isBlank(vmSpec.getBootArgs())) {
-                            String newMacSequence = generateMacSequence(nics);
-                            vmSpec.setBootArgs(replaceNicsMacSequenceInBootArgs(oldMacSequence, newMacSequence, vmSpec));
-                        }
-                    }
-                }
-            }
-
-            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType);
-
-            NiciraNvpApiVersion.logNiciraApiVersion();
-
-            Map<String, String> nicUuidToDvSwitchUuid = new HashMap<String, String>();
-            for (NicTO nicTo : sortNicsByDeviceId(nics)) {
-                s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
-
-                boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
-                VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
-                Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
-                if ((nicTo.getBroadcastType() != BroadcastDomainType.Lswitch)
-                        || (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch && NiciraNvpApiVersion.isApiVersionLowerThan("4.2"))) {
-                    if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
-                        String dvSwitchUuid;
-                        ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-                        DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
-                        ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
-                        dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
-                        s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
-                        nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid,
-                                nicTo.getMac(), i + 1, true, true);
-                        if (nicTo.getUuid() != null) {
-                            nicUuidToDvSwitchUuid.put(nicTo.getUuid(), dvSwitchUuid);
-                        }
-                    } else {
-                        s_logger.info("Preparing NIC device on network " + networkInfo.second());
-                        nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(),
-                                nicTo.getMac(), i + 1, true, true);
-                    }
-                } else {
-                    //if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
-                    nic = VmwareHelper.prepareNicOpaque(vmMo, nicDeviceType, networkInfo.second(),
-                            nicTo.getMac(), i + 1, true, true);
-                }
-
-                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                deviceConfigSpecArray[i].setDevice(nic);
-                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i]));
-
-                // this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3
-                if (nicCount < 3)
-                    nicMask |= (1 << nicCount);
-
-                i++;
-                nicCount++;
-            }
-
-            for (int j = 0; j < i; j++)
-                vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[j]);
-
-            //
-            // Setup VM options
-            //
-
-            // pass boot arguments through machine.id & perform customized options to VMX
-            ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
-            configBasicExtraOption(extraOptions, vmSpec);
-            configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
-            configCustomExtraOption(extraOptions, vmSpec);
-
-            // config for NCC
-            VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
-            if (vmType.equals(VirtualMachine.Type.NetScalerVm)) {
-                NicTO mgmtNic = vmSpec.getNics()[0];
-                OptionValue option = new OptionValue();
-                option.setKey("machine.id");
-                option.setValue("ip=" + mgmtNic.getIp() + "&netmask=" + mgmtNic.getNetmask() + "&gateway=" + mgmtNic.getGateway());
-                extraOptions.add(option);
-            }
-
-            // config VNC
-            String keyboardLayout = null;
-            if (vmSpec.getDetails() != null)
-                keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
-            vmConfigSpec.getExtraConfig()
-                    .addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
-
-            // config video card
-            configureVideoCard(vmMo, vmSpec, vmConfigSpec);
-
-            //
-            // Configure VM
-            //
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName);
-            }
-
-            if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
-                hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value());
-            }
-
-            // Resizing root disk only when explicit requested by user
-            final Map<String, String> vmDetails = cmd.getVirtualMachine().getDetails();
-            if (rootDiskTO != null && !hasSnapshot && (vmDetails != null && vmDetails.containsKey(ApiConstants.ROOT_DISK_SIZE))) {
-                resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context);
-            }
-
-            //
-            // Post Configuration
-            //
-
-            vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
-            postNvpConfigBeforeStart(vmMo, vmSpec);
-
-            Map<String, Map<String, String>> iqnToData = new HashMap<>();
-
-            postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToData, hyperHost, context);
-
-            //
-            // Power-on VM
-            //
-            if (!vmMo.powerOn()) {
-                throw new Exception("Failed to start VM. vmName: " + vmInternalCSName + " with hostname " + vmNameOnVcenter);
-            }
-
-            StartAnswer startAnswer = new StartAnswer(cmd);
-
-            startAnswer.setIqnToData(iqnToData);
-
-            // Since VM was successfully powered-on, if there was an existing VM in a different cluster that was unregistered, delete all the files associated with it.
-            if (existingVmName != null && existingVmFileLayout != null) {
-                List<String> vmDatastoreNames = new ArrayList<String>();
-                for (DatastoreMO vmDatastore : vmMo.getAllDatastores()) {
-                    vmDatastoreNames.add(vmDatastore.getName());
-                }
-                // Don't delete files that are in a datastore that is being used by the new VM as well (zone-wide datastore).
-                List<String> skipDatastores = new ArrayList<String>();
-                for (DatastoreMO existingDatastore : existingDatastores) {
-                    if (vmDatastoreNames.contains(existingDatastore.getName())) {
-                        skipDatastores.add(existingDatastore.getName());
-                    }
-                }
-                deleteUnregisteredVmFiles(existingVmFileLayout, dcMo, true, skipDatastores);
-            }
-
-            return startAnswer;
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "StartCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.warn(msg, e);
-            StartAnswer startAnswer = new StartAnswer(cmd, msg);
-            if (vmAlreadyExistsInVcenter) {
-                startAnswer.setContextParam("stopRetry", "true");
-            }
-
-            // Since VM start failed, if there was an existing VM in a different cluster that was unregistered, register it back.
-            if (existingVmName != null && existingVmFileInfo != null) {
-                s_logger.debug("Since VM start failed, registering back an existing VM: " + existingVmName + " that was unregistered");
-                try {
-                    DatastoreFile fileInDatastore = new DatastoreFile(existingVmFileInfo.getVmPathName());
-                    DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
-                    registerVm(existingVmName, existingVmDsMo);
-                } catch (Exception ex) {
-                    String message = "Failed to register an existing VM: " + existingVmName + " due to " + VmwareHelper.getExceptionMessage(ex);
-                    s_logger.warn(message, ex);
-                }
-            }
-
-            return startAnswer;
-        } finally {
-        }
-    }
-
-    private String appendFileType(String path, String fileType) {
-        if (path.toLowerCase().endsWith(fileType.toLowerCase())) {
-            return path;
-        }
-
-        return path + fileType;
-    }
-
-    private void resizeRootDiskOnVMStart(VirtualMachineMO vmMo, DiskTO rootDiskTO, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
-        final Pair<VirtualDisk, String> vdisk = getVirtualDiskInfo(vmMo, appendFileType(rootDiskTO.getPath(), ".vmdk"));
-        assert(vdisk != null);
-
-        Long reqSize = 0L;
-        final VolumeObjectTO volumeTO = ((VolumeObjectTO)rootDiskTO.getData());
-        if (volumeTO != null) {
-            reqSize = volumeTO.getSize() / 1024;
-        }
-        final VirtualDisk disk = vdisk.first();
-        if (reqSize > disk.getCapacityInKB()) {
-            final VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(vmMo.getDiskInfoBuilder(), rootDiskTO, hyperHost, context);
-            assert (diskInfo != null);
-            final String[] diskChain = diskInfo.getDiskChain();
-
-            if (diskChain != null && diskChain.length > 1) {
-                s_logger.warn("Disk chain length for the VM is greater than one, this is not supported");
-                throw new CloudRuntimeException("Unsupported VM disk chain length: "+ diskChain.length);
-            }
-
-            boolean resizingSupported = false;
-            String deviceBusName = diskInfo.getDiskDeviceBusName();
-            if (deviceBusName != null && (deviceBusName.toLowerCase().contains("scsi") || deviceBusName.toLowerCase().contains("lsi"))) {
-                resizingSupported = true;
-            }
-            if (!resizingSupported) {
-                s_logger.warn("Resizing of root disk is only support for scsi device/bus, the provide VM's disk device bus name is " + diskInfo.getDiskDeviceBusName());
-                throw new CloudRuntimeException("Unsupported VM root disk device bus: "+ diskInfo.getDiskDeviceBusName());
-            }
-
-            disk.setCapacityInKB(reqSize);
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(disk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure VM for given root disk size. vmName: " + vmMo.getName());
-            }
-        }
-    }
-
-
-    /**
-     * Generate the mac sequence from the nics.
-     */
-    protected String generateMacSequence(NicTO[] nics) {
-        if (nics.length == 0) {
-            return "";
-        }
-
-        StringBuffer sbMacSequence = new StringBuffer();
-        for (NicTO nicTo : sortNicsByDeviceId(nics)) {
-            sbMacSequence.append(nicTo.getMac()).append("|");
-        }
-        if (!sbMacSequence.toString().isEmpty()) {
-            sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); //Remove extra '|' char appended at the end
-        }
-
-        return sbMacSequence.toString();
-    }
-
-    /**
-     * Update boot args with the new nic mac addresses.
-     */
-    protected String replaceNicsMacSequenceInBootArgs(String oldMacSequence, String newMacSequence, VirtualMachineTO vmSpec) {
-        String bootArgs = vmSpec.getBootArgs();
-        if (!StringUtils.isBlank(bootArgs) && !StringUtils.isBlank(oldMacSequence) && !StringUtils.isBlank(newMacSequence)) {
-            return bootArgs.replace(oldMacSequence, newMacSequence);
-        }
-        return "";
-    }
-
-    /**
-     * Sets video card memory to the one provided in detail svga.vramSize (if provided) on {@code vmConfigSpec}.
-     * 64MB was always set before.
-     * Size must be in KB.
-     * @param vmMo virtual machine mo
-     * @param vmSpec virtual machine specs
-     * @param vmConfigSpec virtual machine config spec
-     * @throws Exception exception
-     */
-    protected void configureVideoCard(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
-        if (vmSpec.getDetails().containsKey(VmDetailConstants.SVGA_VRAM_SIZE)) {
-            String value = vmSpec.getDetails().get(VmDetailConstants.SVGA_VRAM_SIZE);
-            try {
-                long svgaVmramSize = Long.parseLong(value);
-                setNewVRamSizeVmVideoCard(vmMo, svgaVmramSize, vmConfigSpec);
-            } catch (NumberFormatException e) {
-                s_logger.error("Unexpected value, cannot parse " + value + " to long due to: " + e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * Search for vm video card iterating through vm device list
-     * @param vmMo virtual machine mo
-     * @param svgaVmramSize new svga vram size (in KB)
-     * @param vmConfigSpec virtual machine config spec
-     */
-    protected void setNewVRamSizeVmVideoCard(VirtualMachineMO vmMo, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
-        for (VirtualDevice device : vmMo.getAllDeviceList()) {
-            if (device instanceof VirtualMachineVideoCard) {
-                VirtualMachineVideoCard videoCard = (VirtualMachineVideoCard)device;
-                modifyVmVideoCardVRamSize(videoCard, vmMo, svgaVmramSize, vmConfigSpec);
-            }
-        }
-    }
-
-    /**
-     * Modifies vm vram size if it was set to a different size to the one provided in svga.vramSize (user_vm_details or template_vm_details) on {@code vmConfigSpec}
-     * @param videoCard vm's video card device
-     * @param vmMo virtual machine mo
-     * @param svgaVmramSize new svga vram size (in KB)
-     * @param vmConfigSpec virtual machine config spec
-     */
-    protected void modifyVmVideoCardVRamSize(VirtualMachineVideoCard videoCard, VirtualMachineMO vmMo, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) {
-        if (videoCard.getVideoRamSizeInKB().longValue() != svgaVmramSize) {
-            s_logger.info("Video card memory was set " + videoCard.getVideoRamSizeInKB().longValue() + "kb instead of " + svgaVmramSize + "kb");
-            configureSpecVideoCardNewVRamSize(videoCard, svgaVmramSize, vmConfigSpec);
-        }
-    }
-
-    /**
-     * Add edit spec on {@code vmConfigSpec} to modify svga vram size
-     * @param videoCard video card device to edit providing the svga vram size
-     * @param svgaVmramSize new svga vram size (in KB)
-     * @param vmConfigSpec virtual machine spec
-     */
-    protected void configureSpecVideoCardNewVRamSize(VirtualMachineVideoCard videoCard, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) {
-        videoCard.setVideoRamSizeInKB(svgaVmramSize);
-        videoCard.setUseAutoDetect(false);
-
-        VirtualDeviceConfigSpec arrayVideoCardConfigSpecs = new VirtualDeviceConfigSpec();
-        arrayVideoCardConfigSpecs.setDevice(videoCard);
-        arrayVideoCardConfigSpecs.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-        vmConfigSpec.getDeviceChange().add(arrayVideoCardConfigSpecs);
-    }
-
-    private void tearDownVm(VirtualMachineMO vmMo) throws Exception {
-
-        if (vmMo == null)
-            return;
-
-        boolean hasSnapshot = false;
-        hasSnapshot = vmMo.hasSnapshot();
-        if (!hasSnapshot)
-            vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
-        else
-            vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
-        vmMo.ensureScsiDeviceController();
-    }
-
-    int getReservedMemoryMb(VirtualMachineTO vmSpec) {
-        if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveMemory.key()).equalsIgnoreCase("true")) {
-            return (int)(vmSpec.getMinRam() / ResourceType.bytesToMiB);
-        }
-        return 0;
-    }
-
-    int getReservedCpuMHZ(VirtualMachineTO vmSpec) {
-        if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveCpu.key()).equalsIgnoreCase("true")) {
-            return vmSpec.getMinSpeed() * vmSpec.getCpus();
-        }
-        return 0;
-    }
-
-    // return the finalized disk chain for startup, from top to bottom
-    private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO vol, VirtualMachineDiskInfo diskInfo,
-            HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
-
-        VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-        DataStoreTO primaryStore = volumeTO.getDataStore();
-        Map<String, String> details = vol.getDetails();
-        boolean isManaged = false;
-        String iScsiName = null;
-
-        if (details != null) {
-            isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-            iScsiName = details.get(DiskTO.IQN);
-        }
-
-        // if the storage is managed, iScsiName should not be null
-        String datastoreName = isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
-        Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
-
-        if (volumeDsDetails == null) {
-            throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
-        }
-
-        DatastoreMO dsMo = volumeDsDetails.second();
-
-        // we will honor vCenter's meta if it exists
-        if (diskInfo != null) {
-            // to deal with run-time upgrade to maintain the new datastore folder structure
-            String disks[] = diskInfo.getDiskChain();
-            for (int i = 0; i < disks.length; i++) {
-                DatastoreFile file = new DatastoreFile(disks[i]);
-                if (!isManaged && file.getDir() != null && file.getDir().isEmpty()) {
-                    s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder");
-                    disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, file.getFileBaseName(), VmwareManager.s_vmwareSearchExcludeFolder.value());
-                }
-            }
-            return disks;
-        }
-
-        final String datastoreDiskPath;
-
-        if (isManaged) {
-            String vmdkPath = new DatastoreFile(volumeTO.getPath()).getFileBaseName();
-
-            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
-                if (vmdkPath == null) {
-                    vmdkPath = volumeTO.getName();
-                }
-
-                datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, vmdkPath);
-            }
-            else {
-                if (vmdkPath == null) {
-                    vmdkPath = dsMo.getName();
-                }
-
-                datastoreDiskPath = dsMo.getDatastorePath(vmdkPath + ".vmdk");
-            }
-        } else {
-            datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
-        }
-
-        if (!dsMo.fileExists(datastoreDiskPath)) {
-            s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath);
-        }
-
-        return new String[] {datastoreDiskPath};
-    }
-
-    // Pair<internal CS name, vCenter display name>
-    private Pair<String, String> composeVmNames(VirtualMachineTO vmSpec) {
-        String vmInternalCSName = vmSpec.getName();
-        String vmNameOnVcenter = vmSpec.getName();
-        if (_instanceNameFlag && vmSpec.getHostName() != null) {
-            vmNameOnVcenter = vmSpec.getHostName();
-        }
-        return new Pair<String, String>(vmInternalCSName, vmNameOnVcenter);
-    }
-
-    protected void configNestedHVSupport(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
-
-        VmwareContext context = vmMo.getContext();
-        if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) {
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability");
-
-            ManagedObjectReference hostMor = vmMo.getRunningHost().getMor();
-            ManagedObjectReference computeMor = context.getVimClient().getMoRefProp(hostMor, "parent");
-            ManagedObjectReference environmentBrowser = context.getVimClient().getMoRefProp(computeMor, "environmentBrowser");
-            HostCapability hostCapability = context.getService().queryTargetCapabilities(environmentBrowser, hostMor);
-            Boolean nestedHvSupported = hostCapability.isNestedHVSupported();
-            if (nestedHvSupported == null) {
-                // nestedHvEnabled property is supported only since VMware 5.1. It's not defined for earlier versions.
-                s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " + vmSpec.getName());
-            } else if (nestedHvSupported.booleanValue()) {
-                s_logger.debug("Hypervisor supports nested virtualization, enabling for VM " + vmSpec.getName());
-                vmConfigSpec.setNestedHVEnabled(true);
-            } else {
-                s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " + vmSpec.getName());
-                vmConfigSpec.setNestedHVEnabled(false);
-            }
-        }
-    }
-
-    private static void configBasicExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
-        OptionValue newVal = new OptionValue();
-        newVal.setKey("machine.id");
-        newVal.setValue(vmSpec.getBootArgs());
-        extraOptions.add(newVal);
-
-        newVal = new OptionValue();
-        newVal.setKey("devices.hotplug");
-        newVal.setValue("true");
-        extraOptions.add(newVal);
-    }
-
-    private static void configNvpExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec, Map<String, String> nicUuidToDvSwitchUuid) {
-        /**
-         * Extra Config : nvp.vm-uuid = uuid
-         *  - Required for Nicira NVP integration
-         */
-        OptionValue newVal = new OptionValue();
-        newVal.setKey("nvp.vm-uuid");
-        newVal.setValue(vmSpec.getUuid());
-        extraOptions.add(newVal);
-
-        /**
-         * Extra Config : nvp.iface-id.<num> = uuid
-         *  - Required for Nicira NVP integration
-         */
-        int nicNum = 0;
-        for (NicTO nicTo : sortNicsByDeviceId(vmSpec.getNics())) {
-            if (nicTo.getUuid() != null) {
-                newVal = new OptionValue();
-                newVal.setKey("nvp.iface-id." + nicNum);
-                newVal.setValue(nicTo.getUuid());
-                extraOptions.add(newVal);
-                setNuageVspVrIpInExtraConfig(extraOptions, nicTo, nicUuidToDvSwitchUuid.get(nicTo.getUuid()));
-            }
-            nicNum++;
-        }
-    }
-
-    private static void setNuageVspVrIpInExtraConfig(List<OptionValue> extraOptions, NicTO nicTo, String dvSwitchUuid) {
-        if (nicTo.getBroadcastType() != BroadcastDomainType.Vsp) {
-            return;
-        }
-
-        OptionValue newVal;
-        if (nicTo.getType().equals(TrafficType.Guest) && dvSwitchUuid != null && nicTo.getGateway() != null && nicTo.getNetmask() != null) {
-            String vrIp = nicTo.getBroadcastUri().getPath().substring(1);
-            newVal = new OptionValue();
-            newVal.setKey("vsp.vr-ip." + nicTo.getMac());
-            newVal.setValue(vrIp);
-            extraOptions.add(newVal);
-            newVal = new OptionValue();
-            newVal.setKey("vsp.dvswitch." + nicTo.getMac());
-            newVal.setValue(dvSwitchUuid);
-            extraOptions.add(newVal);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NIC with MAC " + nicTo.getMac() + " and BroadcastDomainType " + nicTo.getBroadcastType() + " in network(" + nicTo.getGateway() + "/"
-                        + nicTo.getNetmask() + ") is " + nicTo.getType() + " traffic type. So, vsp-vr-ip is set in the extraconfig");
-            }
-        }
-    }
-
-    private static void configCustomExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
-        // we no longer to validation anymore
-        for (Map.Entry<String, String> entry : vmSpec.getDetails().entrySet()) {
-            OptionValue newVal = new OptionValue();
-            newVal.setKey(entry.getKey());
-            newVal.setValue(entry.getValue());
-            extraOptions.add(newVal);
-        }
-    }
-
-    private static void postNvpConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec) throws Exception {
-        /**
-         * We need to configure the port on the DV switch after the host is
-         * connected. So make this happen between the configure and start of
-         * the VM
-         */
-        int nicIndex = 0;
-        for (NicTO nicTo : sortNicsByDeviceId(vmSpec.getNics())) {
-            if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
-                // We need to create a port with a unique vlan and pass the key to the nic device
-                s_logger.trace("Nic " + nicTo.toString() + " is connected to an NVP logicalswitch");
-                VirtualDevice nicVirtualDevice = vmMo.getNicDeviceByIndex(nicIndex);
-                if (nicVirtualDevice == null) {
-                    throw new Exception("Failed to find a VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
-                }
-                VirtualDeviceBackingInfo backing = nicVirtualDevice.getBacking();
-                if (backing instanceof VirtualEthernetCardDistributedVirtualPortBackingInfo) {
-                    // This NIC is connected to a Distributed Virtual Switch
-                    VirtualEthernetCardDistributedVirtualPortBackingInfo portInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo)backing;
-                    DistributedVirtualSwitchPortConnection port = portInfo.getPort();
-                    String portKey = port.getPortKey();
-                    String portGroupKey = port.getPortgroupKey();
-                    String dvSwitchUuid = port.getSwitchUuid();
-
-                    s_logger.debug("NIC " + nicTo.toString() + " is connected to dvSwitch " + dvSwitchUuid + " pg " + portGroupKey + " port " + portKey);
-
-                    ManagedObjectReference dvSwitchManager = vmMo.getContext().getVimClient().getServiceContent().getDvSwitchManager();
-                    ManagedObjectReference dvSwitch = vmMo.getContext().getVimClient().getService().queryDvsByUuid(dvSwitchManager, dvSwitchUuid);
-
-                    // Get all ports
-                    DistributedVirtualSwitchPortCriteria criteria = new DistributedVirtualSwitchPortCriteria();
-                    criteria.setInside(true);
-                    criteria.getPortgroupKey().add(portGroupKey);
-                    List<DistributedVirtualPort> dvPorts = vmMo.getContext().getVimClient().getService().fetchDVPorts(dvSwitch, criteria);
-
-                    DistributedVirtualPort vmDvPort = null;
-                    List<Integer> usedVlans = new ArrayList<Integer>();
-                    for (DistributedVirtualPort dvPort : dvPorts) {
-                        // Find the port for this NIC by portkey
-                        if (portKey.equals(dvPort.getKey())) {
-                            vmDvPort = dvPort;
-                        }
-                        VMwareDVSPortSetting settings = (VMwareDVSPortSetting)dvPort.getConfig().getSetting();
-                        VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec)settings.getVlan();
-                        s_logger.trace("Found port " + dvPort.getKey() + " with vlan " + vlanId.getVlanId());
-                        if (vlanId.getVlanId() > 0 && vlanId.getVlanId() < 4095) {
-                            usedVlans.add(vlanId.getVlanId());
-                        }
-                    }
-
-                    if (vmDvPort == null) {
-                        throw new Exception("Empty port list from dvSwitch for nic " + nicTo.toString());
-                    }
-
-                    DVPortConfigInfo dvPortConfigInfo = vmDvPort.getConfig();
-                    VMwareDVSPortSetting settings = (VMwareDVSPortSetting)dvPortConfigInfo.getSetting();
-
-                    VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec)settings.getVlan();
-                    BoolPolicy blocked = settings.getBlocked();
-                    if (blocked.isValue() == Boolean.TRUE) {
-                        s_logger.trace("Port is blocked, set a vlanid and unblock");
-                        DVPortConfigSpec dvPortConfigSpec = new DVPortConfigSpec();
-                        VMwareDVSPortSetting edittedSettings = new VMwareDVSPortSetting();
-                        // Unblock
-                        blocked.setValue(Boolean.FALSE);
-                        blocked.setInherited(Boolean.FALSE);
-                        edittedSettings.setBlocked(blocked);
-                        // Set vlan
-                        int i;
-                        for (i = 1; i < 4095; i++) {
-                            if (!usedVlans.contains(i))
-                                break;
-                        }
-                        vlanId.setVlanId(i); // FIXME should be a determined
-                        // based on usage
-                        vlanId.setInherited(false);
-                        edittedSettings.setVlan(vlanId);
-
-                        dvPortConfigSpec.setSetting(edittedSettings);
-                        dvPortConfigSpec.setOperation("edit");
-                        dvPortConfigSpec.setKey(portKey);
-                        List<DVPortConfigSpec> dvPortConfigSpecs = new ArrayList<DVPortConfigSpec>();
-                        dvPortConfigSpecs.add(dvPortConfigSpec);
-                        ManagedObjectReference task = vmMo.getContext().getVimClient().getService().reconfigureDVPortTask(dvSwitch, dvPortConfigSpecs);
-                        if (!vmMo.getContext().getVimClient().waitForTask(task)) {
-                            throw new Exception("Failed to configure the dvSwitch port for nic " + nicTo.toString());
-                        }
-                        s_logger.debug("NIC " + nicTo.toString() + " connected to vlan " + i);
-                    } else {
-                        s_logger.trace("Port already configured and set to vlan " + vlanId.getVlanId());
-                    }
-                } else if (backing instanceof VirtualEthernetCardNetworkBackingInfo) {
-                    // This NIC is connected to a Virtual Switch
-                    // Nothing to do
-                } else if (backing instanceof VirtualEthernetCardOpaqueNetworkBackingInfo) {
-                    //if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
-                    //OK, connected to OpaqueNetwork
-                } else {
-                    s_logger.error("nic device backing is of type " + backing.getClass().getName());
-                    throw new Exception("Incompatible backing for a VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
-                }
-            }
-            nicIndex++;
-        }
-    }
-
-    private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol, VmwareHypervisorHost hyperHost, VmwareContext context)
-            throws Exception {
-        if (diskInfoBuilder != null) {
-            VolumeObjectTO volume = (VolumeObjectTO)vol.getData();
-
-            String dsName = null;
-            String diskBackingFileBaseName = null;
-
-            Map<String, String> details = vol.getDetails();
-            boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-
-            if (isManaged) {
-                String iScsiName = details.get(DiskTO.IQN);
-
-                // if the storage is managed, iScsiName should not be null
-                dsName = VmwareResource.getDatastoreName(iScsiName);
-
-                diskBackingFileBaseName = new DatastoreFile(volume.getPath()).getFileBaseName();
-            } else {
-                ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid());
-                DatastoreMO dsMo = new DatastoreMO(context, morDs);
-
-                dsName = dsMo.getName();
-
-                diskBackingFileBaseName = volume.getPath();
-            }
-
-            VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
-            if (diskInfo != null) {
-                s_logger.info("Found existing disk info from volume path: " + volume.getPath());
-                return diskInfo;
-            } else {
-                String chainInfo = volume.getChainInfo();
-                if (chainInfo != null) {
-                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
-                    if (infoInChain != null) {
-                        String[] disks = infoInChain.getDiskChain();
-                        if (disks.length > 0) {
-                            for (String diskPath : disks) {
-                                DatastoreFile file = new DatastoreFile(diskPath);
-                                diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
-                                if (diskInfo != null) {
-                                    s_logger.info("Found existing disk from chain info: " + diskPath);
-                                    return diskInfo;
-                                }
-                            }
-                        }
-
-                        if (diskInfo == null) {
-                            diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(infoInChain.getDiskDeviceBusName());
-                            if (diskInfo != null) {
-                                s_logger.info("Found existing disk from from chain device bus information: " + infoInChain.getDiskDeviceBusName());
-                                return diskInfo;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private int getDiskController(VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, VirtualMachineTO vmSpec, int ideControllerKey, int scsiControllerKey) {
-
-        int controllerKey;
-        if (matchingExistingDisk != null) {
-            s_logger.info("Chose disk controller based on existing information: " + matchingExistingDisk.getDiskDeviceBusName());
-            if (matchingExistingDisk.getDiskDeviceBusName().startsWith("ide"))
-                return ideControllerKey;
-            else
-                return scsiControllerKey;
-        }
-
-        if (vol.getType() == Volume.Type.ROOT) {
-            Map<String, String> vmDetails = vmSpec.getDetails();
-            if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER) != null) {
-                if (vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER).equalsIgnoreCase("scsi")) {
-                    s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: "
-                            + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
-                    controllerKey = scsiControllerKey;
-                } else {
-                    s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: "
-                            + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
-                    controllerKey = ideControllerKey;
-                }
-            } else {
-                s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi. due to null root disk controller setting");
-                controllerKey = scsiControllerKey;
-            }
-
-        } else {
-            // DATA volume always use SCSI device
-            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi");
-            controllerKey = scsiControllerKey;
-        }
-
-        return controllerKey;
-    }
-
-    private String getDiskController(VirtualMachineMO vmMo, VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, Pair<String, String> controllerInfo) throws Exception {
-        int controllerKey;
-        DiskControllerType controllerType = DiskControllerType.none;
-        if (matchingExistingDisk != null) {
-            String currentBusName = matchingExistingDisk.getDiskDeviceBusName();
-            if (currentBusName != null) {
-                s_logger.info("Chose disk controller based on existing information: " + currentBusName);
-                if (currentBusName.startsWith("ide")) {
-                    controllerType = DiskControllerType.ide;
-                } else if (currentBusName.startsWith("scsi")) {
-                    controllerType = DiskControllerType.scsi;
-                }
-            }
-            if (controllerType == DiskControllerType.scsi || controllerType == DiskControllerType.none) {
-                Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
-                controllerType = vmScsiControllerInfo.third();
-            }
-            return controllerType.toString();
-        }
-
-        if (vol.getType() == Volume.Type.ROOT) {
-            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.first()
-                    + ", based on root disk controller settings at global configuration setting.");
-            return controllerInfo.first();
-        } else {
-            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.second()
-                    + ", based on default data disk controller setting i.e. Operating system recommended."); // Need to bring in global configuration setting & template level setting.
-            return controllerInfo.second();
-        }
-    }
-
-    private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey,
-            int scsiControllerKey, Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
-        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-
-        for (DiskTO vol : sortedDisks) {
-            if (vol.getType() == Volume.Type.ISO)
-                continue;
-
-            VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-
-            VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
-            assert (diskInfo != null);
-
-            String[] diskChain = diskInfo.getDiskChain();
-            assert (diskChain.length > 0);
-
-            Map<String, String> details = vol.getDetails();
-            boolean managed = false;
-
-            if (details != null) {
-                managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-            }
-
-            DatastoreFile file = new DatastoreFile(diskChain[0]);
-
-            if (managed) {
-                DatastoreFile originalFile = new DatastoreFile(volumeTO.getPath());
-
-                if (!file.getFileBaseName().equalsIgnoreCase(originalFile.getFileBaseName())) {
-                    if (s_logger.isInfoEnabled())
-                        s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + diskChain[0]);
-                }
-            } else {
-                if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) {
-                    if (s_logger.isInfoEnabled())
-                        s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName());
-                }
-            }
-
-            VolumeObjectTO volInSpec = getVolumeInSpec(vmSpec, volumeTO);
-
-            if (volInSpec != null) {
-                if (managed) {
-                    Map<String, String> data = new HashMap<>();
-
-                    String datastoreVolumePath = diskChain[0];
-
-                    data.put(StartAnswer.PATH, datastoreVolumePath);
-                    data.put(StartAnswer.IMAGE_FORMAT, Storage.ImageFormat.OVA.toString());
-
-                    iqnToData.put(details.get(DiskTO.IQN), data);
-
-                    vol.setPath(datastoreVolumePath);
-                    volumeTO.setPath(datastoreVolumePath);
-                    volInSpec.setPath(datastoreVolumePath);
-                } else {
-                    volInSpec.setPath(file.getFileBaseName());
-                }
-                volInSpec.setChainInfo(_gson.toJson(diskInfo));
-            }
-        }
-    }
-
-    private void checkAndDeleteDatastoreFile(String filePath, List<String> skipDatastores, DatastoreMO dsMo, DatacenterMO dcMo) throws Exception {
-        if (dsMo != null && dcMo != null && (skipDatastores == null || !skipDatastores.contains(dsMo.getName()))) {
-            s_logger.debug("Deleting file: " + filePath);
-            dsMo.deleteFile(filePath, dcMo.getMor(), true);
-        }
-    }
-
-    private void deleteUnregisteredVmFiles(VirtualMachineFileLayoutEx vmFileLayout, DatacenterMO dcMo, boolean deleteDisks, List<String> skipDatastores) throws Exception {
-        s_logger.debug("Deleting files associated with an existing VM that was unregistered");
-        DatastoreFile vmFolder = null;
-        try {
-            List<VirtualMachineFileLayoutExFileInfo> fileInfo = vmFileLayout.getFile();
-            for (VirtualMachineFileLayoutExFileInfo file : fileInfo) {
-                DatastoreFile fileInDatastore = new DatastoreFile(file.getName());
-                // In case of linked clones, VM file layout includes the base disk so don't delete all disk files.
-                if (file.getType().startsWith("disk") || file.getType().startsWith("digest"))
-                    continue;
-                else if (file.getType().equals("config"))
-                    vmFolder = new DatastoreFile(fileInDatastore.getDatastoreName(), fileInDatastore.getDir());
-                DatastoreMO dsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
-                checkAndDeleteDatastoreFile(file.getName(), skipDatastores, dsMo, dcMo);
-            }
-            // Delete files that are present in the VM folder - this will take care of the VM disks as well.
-            DatastoreMO vmFolderDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(vmFolder.getDatastoreName()));
-            String[] files = vmFolderDsMo.listDirContent(vmFolder.getPath());
-            if (deleteDisks) {
-                for (String file : files) {
-                    String vmDiskFileFullPath = String.format("%s/%s", vmFolder.getPath(), file);
-                    checkAndDeleteDatastoreFile(vmDiskFileFullPath, skipDatastores, vmFolderDsMo, dcMo);
-                }
-            }
-            // Delete VM folder
-            if (deleteDisks || files.length == 0) {
-                checkAndDeleteDatastoreFile(vmFolder.getPath(), skipDatastores, vmFolderDsMo, dcMo);
-            }
-        } catch (Exception e) {
-            String message = "Failed to delete files associated with an existing VM that was unregistered due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.warn(message, e);
-        }
-    }
-
-    private static VolumeObjectTO getVolumeInSpec(VirtualMachineTO vmSpec, VolumeObjectTO srcVol) {
-        for (DiskTO disk : vmSpec.getDisks()) {
-            if (disk.getData() instanceof VolumeObjectTO) {
-                VolumeObjectTO vol = (VolumeObjectTO) disk.getData();
-                if (vol.getId() == srcVol.getId())
-                    return vol;
-            }
-        }
-
-        return null;
-    }
-
-    private static NicTO[] sortNicsByDeviceId(NicTO[] nics) {
-
-        List<NicTO> listForSort = new ArrayList<NicTO>();
-        for (NicTO nic : nics) {
-            listForSort.add(nic);
-        }
-        Collections.sort(listForSort, new Comparator<NicTO>() {
-
-            @Override
-            public int compare(NicTO arg0, NicTO arg1) {
-                if (arg0.getDeviceId() < arg1.getDeviceId()) {
-                    return -1;
-                } else if (arg0.getDeviceId() == arg1.getDeviceId()) {
-                    return 0;
-                }
-
-                return 1;
-            }
-        });
-
-        return listForSort.toArray(new NicTO[0]);
-    }
-
-    private static DiskTO[] sortVolumesByDeviceId(DiskTO[] volumes) {
-
-        List<DiskTO> listForSort = new ArrayList<DiskTO>();
-        for (DiskTO vol : volumes) {
-            listForSort.add(vol);
-        }
-        Collections.sort(listForSort, new Comparator<DiskTO>() {
-
-            @Override
-            public int compare(DiskTO arg0, DiskTO arg1) {
-                if (arg0.getDiskSeq() < arg1.getDiskSeq()) {
-                    return -1;
-                } else if (arg0.getDiskSeq().equals(arg1.getDiskSeq())) {
-                    return 0;
-                }
-
-                return 1;
-            }
-        });
-
-        return listForSort.toArray(new DiskTO[0]);
-    }
-
-    /**
-     * Only call this for managed storage.
-     * Ex. "[-iqn.2010-01.com.solidfire:4nhe.vol-1.27-0] i-2-18-VM/ROOT-18.vmdk" should return "i-2-18-VM/ROOT-18"
-     */
-    public String getVmdkPath(String path) {
-        if (!com.cloud.utils.StringUtils.isNotBlank(path)) {
-            return null;
-        }
-
-        final String search = "]";
-
-        int startIndex = path.indexOf(search);
-
-        if (startIndex == -1) {
-            return null;
-        }
-
-        path = path.substring(startIndex + search.length());
-
-        final String search2 = ".vmdk";
-
-        int endIndex = path.indexOf(search2);
-
-        if (endIndex == -1) {
-            return null;
-        }
-
-        return path.substring(0, endIndex).trim();
-    }
-
-    private HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context,
-            DiskTO[] disks, Command cmd) throws Exception {
-        HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> mapIdToMors = new HashMap<>();
-
-        assert (hyperHost != null) && (context != null);
-
-        for (DiskTO vol : disks) {
-            if (vol.getType() != Volume.Type.ISO) {
-                VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
-                DataStoreTO primaryStore = volumeTO.getDataStore();
-                String poolUuid = primaryStore.getUuid();
-
-                if (mapIdToMors.get(poolUuid) == null) {
-                    boolean isManaged = false;
-                    Map<String, String> details = vol.getDetails();
-
-                    if (details != null) {
-                        isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-                    }
-
-                    if (isManaged) {
-                        String iScsiName = details.get(DiskTO.IQN); // details should not be null for managed storage (it may or may not be null for non-managed storage)
-                        String datastoreName = VmwareResource.getDatastoreName(iScsiName);
-                        ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
-
-                        // if the datastore is not present, we need to discover the iSCSI device that will support it,
-                        // create the datastore, and create a VMDK file in the datastore
-                        if (morDatastore == null) {
-                            final String vmdkPath = getVmdkPath(volumeTO.getPath());
-
-                            morDatastore = _storageProcessor.prepareManagedStorage(context, hyperHost, null, iScsiName,
-                                    details.get(DiskTO.STORAGE_HOST), Integer.parseInt(details.get(DiskTO.STORAGE_PORT)),
-                                    vmdkPath,
-                                    details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
-                                    details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
-                                    Long.parseLong(details.get(DiskTO.VOLUME_SIZE)), cmd);
-
-                            DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDatastore);
-
-                            final String datastoreVolumePath;
-
-                            if (vmdkPath != null) {
-                                datastoreVolumePath = dsMo.getDatastorePath(vmdkPath + ".vmdk");
-                            }
-                            else {
-                                datastoreVolumePath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");
-                            }
-
-                            volumeTO.setPath(datastoreVolumePath);
-                            vol.setPath(datastoreVolumePath);
-                        }
-
-                        mapIdToMors.put(datastoreName, new Pair<>(morDatastore, new DatastoreMO(context, morDatastore)));
-                    }
-                    else {
-                        ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid);
-
-                        if (morDatastore == null) {
-                            String msg = "Failed to get the mounted datastore for the volume's pool " + poolUuid;
-
-                            s_logger.error(msg);
-
-                            throw new Exception(msg);
-                        }
-
-                        mapIdToMors.put(poolUuid, new Pair<>(morDatastore, new DatastoreMO(context, morDatastore)));
-                    }
-                }
-            }
-        }
-
-        return mapIdToMors;
-    }
-
-    private DatastoreMO getDatastoreThatRootDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO disks[]) {
-        Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
-
-        for (DiskTO vol : disks) {
-            if (vol.getType() == Volume.Type.ROOT) {
-                Map<String, String> details = vol.getDetails();
-                boolean managed = false;
-
-                if (details != null) {
-                    managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-                }
-
-                if (managed) {
-                    String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
-
-                    rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
-
-                    break;
-                } else {
-                    DataStoreTO primaryStore = vol.getData().getDataStore();
-
-                    rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
-
-                    break;
-                }
-            }
-        }
-
-        if (rootDiskDataStoreDetails != null) {
-            return rootDiskDataStoreDetails.second();
-        }
-
-        return null;
-    }
-
-    private String getPvlanInfo(NicTO nicTo) {
-        if (nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
-            return NetUtils.getIsolatedPvlanFromUri(nicTo.getBroadcastUri());
-        }
-        return null;
-    }
-
-    private String getVlanInfo(NicTO nicTo, String defaultVlan) {
-        if (nicTo.getBroadcastType() == BroadcastDomainType.Native) {
-            return defaultVlan;
-        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan || nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
-            if (nicTo.getBroadcastUri() != null) {
-                if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan)
-                    // For vlan, the broadcast uri is of the form vlan://<vlanid>
-                    // BroadcastDomainType recogniizes and handles this.
-                    return BroadcastDomainType.getValue(nicTo.getBroadcastUri());
-                else
-                    // for pvlan, the broacast uri will be of the form pvlan://<vlanid>-i<pvlanid>
-                    // TODO consider the spread of functionality between BroadcastDomainType and NetUtils
-                    return NetUtils.getPrimaryPvlanFromUri(nicTo.getBroadcastUri());
-            } else {
-                s_logger.warn("BroadcastType is not claimed as VLAN or PVLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan);
-                return defaultVlan;
-            }
-        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
-            // We don't need to set any VLAN id for an NVP logical switch
-            return null;
-        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Storage) {
-            URI broadcastUri = nicTo.getBroadcastUri();
-            if (broadcastUri != null) {
-                String vlanId = BroadcastDomainType.getValue(broadcastUri);
-                s_logger.debug("Using VLAN [" + vlanId + "] from broadcast uri [" + broadcastUri + "]");
-                return vlanId;
-            }
-        }
-
-        s_logger.warn("Unrecognized broadcast type in VmwareResource, type: " + nicTo.getBroadcastType().toString() + ". Use vlan info from labeling: " + defaultVlan);
-        return defaultVlan;
-    }
-
-    private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType)
-            throws Exception {
-
-        Ternary<String, String, String> switchDetails = getTargetSwitch(nicTo);
-        VirtualSwitchType switchType = VirtualSwitchType.getType(switchDetails.second());
-        String switchName = switchDetails.first();
-        String vlanToken = switchDetails.third();
-
-        String namePrefix = getNetworkNamePrefix(nicTo);
-        Pair<ManagedObjectReference, String> networkInfo = null;
-
-        s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix);
-
-        if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
-            networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo,
-                    getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(),
-                    _opsTimeout, true, nicTo.getBroadcastType(), nicTo.getUuid(), nicTo.getDetails());
-        }
-        else {
-            String vlanId = getVlanInfo(nicTo, vlanToken);
-            String svlanId = null;
-            boolean pvlannetwork = (getPvlanInfo(nicTo) == null) ? false : true;
-            if (vmType != null && vmType.equals(VirtualMachine.Type.DomainRouter) && pvlannetwork) {
-                // plumb this network to the promiscuous vlan.
-                svlanId = vlanId;
-            } else {
-                // plumb this network to the isolated vlan.
-                svlanId = getPvlanInfo(nicTo);
-            }
-            networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId,
-                    nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType,
-                    _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails());
-        }
-
-        return networkInfo;
-    }
-
-    // return Ternary <switch name, switch tyep, vlan tagging>
-    private Ternary<String, String, String> getTargetSwitch(NicTO nicTo) throws CloudException {
-        TrafficType[] supportedTrafficTypes = new TrafficType[] {TrafficType.Guest, TrafficType.Public, TrafficType.Control, TrafficType.Management, TrafficType.Storage};
-
-        TrafficType trafficType = nicTo.getType();
-        if (!Arrays.asList(supportedTrafficTypes).contains(trafficType)) {
-            throw new CloudException("Traffic type " + trafficType.toString() + " for nic " + nicTo.toString() + " is not supported.");
-        }
-
-        String switchName = null;
-        VirtualSwitchType switchType = VirtualSwitchType.StandardVirtualSwitch;
-        String vlanId = Vlan.UNTAGGED;
-
-        if (StringUtils.isNotBlank(nicTo.getName())) {
-            // Format of network traffic label is <VSWITCH>,<VLANID>,<VSWITCHTYPE>
-            // If all 3 fields are mentioned then number of tokens would be 3.
-            // If only <VSWITCH>,<VLANID> are mentioned then number of tokens would be 2.
-            // Get switch details from the nicTO object
-            String networkName = nicTo.getName();
-            VmwareTrafficLabel mgmtTrafficLabelObj = new VmwareTrafficLabel(networkName, trafficType);
-            switchName = mgmtTrafficLabelObj.getVirtualSwitchName();
-            vlanId = mgmtTrafficLabelObj.getVlanId();
-            switchType = mgmtTrafficLabelObj.getVirtualSwitchType();
-        } else {
-            if (trafficType == TrafficType.Guest && _guestTrafficInfo != null) {
-                switchType = _guestTrafficInfo.getVirtualSwitchType();
-                switchName = _guestTrafficInfo.getVirtualSwitchName();
-            } else if (trafficType == TrafficType.Public && _publicTrafficInfo != null) {
-                switchType = _publicTrafficInfo.getVirtualSwitchType();
-                switchName = _publicTrafficInfo.getVirtualSwitchName();
-            }
-        }
-
-        if (switchName == null
-                && (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management || nicTo.getType() == Networks.TrafficType.Storage)) {
-            switchName = _privateNetworkVSwitchName;
-        }
-
-        if (switchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
-            if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) {
-                throw new CloudException(
-                        "Unable to configure NIC " + nicTo.toString() + " as traffic type " + trafficType.toString() + " is not supported over virtual switch type " + switchType
-                                + ". Please specify only supported type of virtual switches i.e. {vmwaresvs, vmwaredvs} in physical network traffic label.");
-            }
-        }
-
-        return new Ternary<String, String, String>(switchName, switchType.toString(), vlanId);
-    }
-
-    private String getNetworkNamePrefix(NicTO nicTo) throws Exception {
-        if (nicTo.getType() == Networks.TrafficType.Guest) {
-            return "cloud.guest";
-        } else if (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management) {
-            return "cloud.private";
-        } else if (nicTo.getType() == Networks.TrafficType.Public) {
-            return "cloud.public";
-        } else if (nicTo.getType() == Networks.TrafficType.Storage) {
-            return "cloud.storage";
-        } else if (nicTo.getType() == Networks.TrafficType.Vpn) {
-            throw new Exception("Unsupported traffic type: " + nicTo.getType().toString());
-        } else {
-            throw new Exception("Unsupported traffic type: " + nicTo.getType().toString());
-        }
-    }
-
-    private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost hyperHost, String vmName) throws Exception {
-
-        VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-        if (vmMo != null) {
-            ManagedObjectReference morTargetPhysicalHost = hyperHost.findMigrationTarget(vmMo);
-            if (morTargetPhysicalHost == null) {
-                String msg = "VM " + vmName + " is on other host and we have no resource available to migrate and start it here";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            if (!vmMo.relocate(morTargetPhysicalHost)) {
-                String msg = "VM " + vmName + " is on other host and we failed to relocate it here";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            return vmMo;
-        }
-        return null;
-    }
-
-    // isoUrl sample content :
-    // nfs://192.168.10.231/export/home/kelven/vmware-test/secondary/template/tmpl/2/200//200-2-80f7ee58-6eff-3a2d-bcb0-59663edf6d26.iso
-    private Pair<String, ManagedObjectReference> getIsoDatastoreInfo(VmwareHypervisorHost hyperHost, String isoUrl) throws Exception {
-
-        assert (isoUrl != null);
-        int isoFileNameStartPos = isoUrl.lastIndexOf("/");
-        if (isoFileNameStartPos < 0) {
-            throw new Exception("Invalid ISO path info");
-        }
-
-        String isoFileName = isoUrl.substring(isoFileNameStartPos);
-
-        int templateRootPos = isoUrl.indexOf("template/tmpl");
-        templateRootPos = (templateRootPos < 0 ? isoUrl.indexOf(ConfigDrive.CONFIGDRIVEDIR) : templateRootPos);
-        if (templateRootPos < 0 ) {
-            throw new Exception("Invalid ISO path info");
-        }
-
-        String storeUrl = isoUrl.substring(0, templateRootPos - 1);
-        String isoPath = isoUrl.substring(templateRootPos, isoFileNameStartPos);
-
-        ManagedObjectReference morDs = prepareSecondaryDatastoreOnHost(storeUrl);
-        DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs);
-
-        return new Pair<String, ManagedObjectReference>(String.format("[%s] %s%s", dsMo.getName(), isoPath, isoFileName), morDs);
-    }
-
-    protected Answer execute(ReadyCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ReadyCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            if (hyperHost.isHyperHostConnected()) {
-                return new ReadyAnswer(cmd);
-            } else {
-                return new ReadyAnswer(cmd, "Host is not in connect state");
-            }
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception: ", e);
-            return new ReadyAnswer(cmd, VmwareHelper.getExceptionMessage(e));
-        }
-    }
-
-    protected Answer execute(GetHostStatsCommand cmd) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Executing resource GetHostStatsCommand: " + _gson.toJson(cmd));
-        }
-
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-        HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 0, 0, "host", 0, 0, 0, 0);
-        Answer answer = new GetHostStatsAnswer(cmd, hostStats);
-        try {
-            HostStatsEntry entry = getHyperHostStats(hyperHost);
-            if (entry != null) {
-                entry.setHostId(cmd.getHostId());
-                answer = new GetHostStatsAnswer(cmd, entry);
-            }
-        } catch (Exception e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "Unable to execute GetHostStatsCommand due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("GetHostStats Answer: " + _gson.toJson(answer));
-        }
-
-        return answer;
-    }
-
-    protected Answer execute(GetVmStatsCommand cmd) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Executing resource GetVmStatsCommand: " + _gson.toJson(cmd));
-        }
-
-        HashMap<String, VmStatsEntry> vmStatsMap = null;
-
-        try {
-            HashMap<String, PowerState> vmPowerStates = getVmStates();
-
-            // getVmNames should return all i-x-y values.
-            List<String> requestedVmNames = cmd.getVmNames();
-            List<String> vmNames = new ArrayList<String>();
-
-            if (requestedVmNames != null) {
-                for (String vmName : requestedVmNames) {
-                    if (vmPowerStates.get(vmName) != null) {
-                        vmNames.add(vmName);
-                    }
-                }
-            }
-
-            if (vmNames != null) {
-                vmStatsMap = getVmStats(vmNames);
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            s_logger.error("Unable to execute GetVmStatsCommand due to : " + VmwareHelper.getExceptionMessage(e), e);
-        }
-
-        Answer answer = new GetVmStatsAnswer(cmd, vmStatsMap);
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Report GetVmStatsAnswer: " + _gson.toJson(answer));
-        }
-        return answer;
-    }
-
-    protected Answer execute(GetVmDiskStatsCommand cmd) {
-        return new GetVmDiskStatsAnswer(cmd, null, null, null);
-    }
-
-    protected Answer execute(GetVmNetworkStatsCommand cmd) {
-        return new GetVmNetworkStatsAnswer(cmd, null, null, null);
-    }
-
-    protected GetVolumeStatsAnswer execute(GetVolumeStatsCommand cmd) {
-        try {
-            VmwareHypervisorHost srcHyperHost = getHyperHost(getServiceContext());
-            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, cmd.getPoolUuid());
-            assert (morDs != null);
-            DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(getServiceContext(), morDs);
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-            DatacenterMO dcMo = new DatacenterMO(getServiceContext(), dcMor);
-            HashMap<String, VolumeStatsEntry> statEntry = new HashMap<String, VolumeStatsEntry>();
-
-            for (String chainInfo : cmd.getVolumeUuids()){
-                if (chainInfo != null) {
-                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
-                    if (infoInChain != null) {
-                        String[] disks = infoInChain.getDiskChain();
-                        if (disks.length > 0) {
-                            for (String diskPath : disks) {
-                                DatastoreFile file = new DatastoreFile(diskPath);
-                                VirtualMachineMO vmMo = dcMo.findVm(file.getDir());
-                                Pair<VirtualDisk, String> vds = vmMo.getDiskDevice(file.getFileName(), true);
-                                long virtualsize = vds.first().getCapacityInKB() * 1024;
-                                long physicalsize = primaryStorageDatastoreMo.fileDiskSize(file.getPath());
-                                VolumeStatsEntry vse = new VolumeStatsEntry(chainInfo, physicalsize, virtualsize);
-                                statEntry.put(chainInfo, vse);
-                            }
-                        }
-                    }
-                }
-            }
-            return new GetVolumeStatsAnswer(cmd, "", statEntry);
-        } catch (Exception e) {
-            s_logger.info("VOLSTAT GetVolumeStatsCommand failed " + e.getMessage());
-        }
-
-        return new GetVolumeStatsAnswer(cmd, "", null);
-    }
-
-    protected Answer execute(CheckHealthCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CheckHealthCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            if (hyperHost.isHyperHostConnected()) {
-                return new CheckHealthAnswer(cmd, true);
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            s_logger.error("Unable to execute CheckHealthCommand due to " + VmwareHelper.getExceptionMessage(e), e);
-        }
-        return new CheckHealthAnswer(cmd, false);
-    }
-
-    protected Answer execute(StopCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource StopCommand: " + _gson.toJson(cmd));
-        }
-
-        // In the stop command, we're passed in the name of the VM as seen by cloudstack,
-        // i.e., i-x-y. This is the internal VM name.
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-        try {
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
-            if (vmMo != null) {
-                if (cmd.checkBeforeCleanup()) {
-                    if (getVmPowerState(vmMo) != PowerState.PowerOff) {
-                        String msg = "StopCommand is sent for cleanup and VM " + cmd.getVmName() + " is current running. ignore it.";
-                        s_logger.warn(msg);
-                        return new StopAnswer(cmd, msg, false);
-                    } else {
-                        String msg = "StopCommand is sent for cleanup and VM " + cmd.getVmName() + " is indeed stopped already.";
-                        s_logger.info(msg);
-                        return new StopAnswer(cmd, msg, true);
-                    }
-                }
-
-                try {
-                    vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, "0");
-                    vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_VM_INTERNAL_NAME, cmd.getVmName());
-
-                    if (getVmPowerState(vmMo) != PowerState.PowerOff) {
-                        String msg = "Stop VM " + cmd.getVmName() + " Succeed";
-                        boolean success = false;
-                        if (cmd.isForceStop()) {
-                            success = vmMo.powerOff();
-                        } else {
-                            success = vmMo.safePowerOff(_shutdownWaitMs);
-                        }
-                        if (!success) {
-                            msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue";
-                            s_logger.warn(msg);
-                        }
-                        return new StopAnswer(cmd, msg, true);
-                    }
-
-                    String msg = "VM " + cmd.getVmName() + " is already in stopped state";
-                    s_logger.info(msg);
-                    return new StopAnswer(cmd, msg, true);
-                } finally {
-                }
-            } else {
-
-                String msg = "VM " + cmd.getVmName() + " is no longer in vSphere";
-                s_logger.info(msg);
-                return new StopAnswer(cmd, msg, true);
-            }
-        } catch (Exception e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "StopCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            return new StopAnswer(cmd, msg, false);
-        }
-    }
-
-    protected Answer execute(RebootRouterCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource RebootRouterCommand: " + _gson.toJson(cmd));
-        }
-
-        RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd);
-
-        if (answer.getResult()) {
-            String connectResult = connect(cmd.getVmName(), cmd.getPrivateIpAddress());
-            networkUsage(cmd.getPrivateIpAddress(), "create", null);
-            if (connectResult == null) {
-                return answer;
-            } else {
-                return new Answer(cmd, false, connectResult);
-            }
-        }
-        return answer;
-    }
-
-    protected Answer execute(RebootCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource RebootCommand: " + _gson.toJson(cmd));
-        }
-
-        boolean toolsInstallerMounted = false;
-        VirtualMachineMO vmMo = null;
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-        try {
-            vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
-            if (vmMo != null) {
-                if (vmMo.isToolsInstallerMounted()) {
-                    toolsInstallerMounted = true;
-                    s_logger.trace("Detected mounted vmware tools installer for :[" + cmd.getVmName() + "]");
-                }
-                try {
-                    vmMo.rebootGuest();
-                    return new RebootAnswer(cmd, "reboot succeeded", true);
-                } catch (ToolsUnavailableFaultMsg e) {
-                    s_logger.warn("VMware tools is not installed at guest OS, we will perform hard reset for reboot");
-                } catch (Exception e) {
-                    s_logger.warn("We are not able to perform gracefull guest reboot due to " + VmwareHelper.getExceptionMessage(e));
-                }
-
-                // continue to try with hard-reset
-                if (vmMo.reset()) {
-                    return new RebootAnswer(cmd, "reboot succeeded", true);
-                }
-
-                String msg = "Reboot failed in vSphere. vm: " + cmd.getVmName();
-                s_logger.warn(msg);
-                return new RebootAnswer(cmd, msg, false);
-            } else {
-                String msg = "Unable to find the VM in vSphere to reboot. vm: " + cmd.getVmName();
-                s_logger.warn(msg);
-                return new RebootAnswer(cmd, msg, false);
-            }
-        } catch (Exception e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "RebootCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            return new RebootAnswer(cmd, msg, false);
-        } finally {
-            if (toolsInstallerMounted) {
-                try {
-                    vmMo.mountToolsInstaller();
-                    s_logger.debug("Successfully re-mounted vmware tools installer for :[" + cmd.getVmName() + "]");
-                } catch (Exception e) {
-                    s_logger.warn("Unabled to re-mount vmware tools installer for :[" + cmd.getVmName() + "]");
-                }
-            }
-        }
-    }
-
-    protected Answer execute(CheckVirtualMachineCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CheckVirtualMachineCommand: " + _gson.toJson(cmd));
-        }
-
-        final String vmName = cmd.getVmName();
-        PowerState powerState = PowerState.PowerUnknown;
-        Integer vncPort = null;
-
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-        try {
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if (vmMo != null) {
-                powerState = getVmPowerState(vmMo);
-                return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
-            } else {
-                s_logger.warn("Can not find vm " + vmName + " to execute CheckVirtualMachineCommand");
-                return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
-            }
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-            s_logger.error("Unexpected exception: " + VmwareHelper.getExceptionMessage(e), e);
-
-            return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
-        }
-    }
-
-    protected Answer execute(PrepareForMigrationCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PrepareForMigrationCommand: " + _gson.toJson(cmd));
-        }
-
-        VirtualMachineTO vm = cmd.getVirtualMachine();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Preparing host for migrating " + vm);
-        }
-
-        final String vmName = vm.getName();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            // find VM through datacenter (VM is not at the target host yet)
-            VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-            if (vmMo == null) {
-                s_logger.info("VM " + vmName + " was not found in the cluster of host " + hyperHost.getHyperHostName() + ". Looking for the VM in datacenter.");
-                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-                DatacenterMO dcMo = new DatacenterMO(hyperHost.getContext(), dcMor);
-                vmMo = dcMo.findVm(vmName);
-                if (vmMo == null) {
-                    String msg = "VM " + vmName + " does not exist in VMware datacenter";
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-            }
-
-            NicTO[] nics = vm.getNics();
-            for (NicTO nic : nics) {
-                // prepare network on the host
-                prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
-            }
-
-            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
-            String secStoreUrl = secStoreUrlAndId.first();
-            Long secStoreId = secStoreUrlAndId.second();
-            if (secStoreUrl == null) {
-                String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
-                throw new Exception(msg);
-            }
-            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
-
-            ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
-            if (morSecDs == null) {
-                String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
-                throw new Exception(msg);
-            }
-            return new PrepareForMigrationAnswer(cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "Unexcpeted exception " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new PrepareForMigrationAnswer(cmd, msg);
-        }
-    }
-
-    protected Answer execute(MigrateCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource MigrateCommand: " + _gson.toJson(cmd));
-        }
-
-        final String vmName = cmd.getVmName();
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
-
-            // find VM through datacenter (VM is not at the target host yet)
-            VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-            if (vmMo == null) {
-                String msg = "VM " + vmName + " does not exist in VMware datacenter";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            VmwareHypervisorHost destHyperHost = getTargetHyperHost(new DatacenterMO(hyperHost.getContext(), morDc), cmd.getDestinationIp());
-
-            ManagedObjectReference morTargetPhysicalHost = destHyperHost.findMigrationTarget(vmMo);
-            if (morTargetPhysicalHost == null) {
-                throw new Exception("Unable to find a target capable physical host");
-            }
-
-            if (!vmMo.migrate(destHyperHost.getHyperHostOwnerResourcePool(), morTargetPhysicalHost)) {
-                throw new Exception("Migration failed");
-            }
-
-            return new MigrateAnswer(cmd, true, "migration succeeded", null);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.warn(msg, e);
-            return new MigrateAnswer(cmd, false, msg, null);
-        }
-    }
-
-    protected Answer execute(MigrateWithStorageCommand cmd) {
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource MigrateWithStorageCommand: " + _gson.toJson(cmd));
-        }
-
-        VirtualMachineTO vmTo = cmd.getVirtualMachine();
-        String vmName = vmTo.getName();
-
-        VmwareHypervisorHost srcHyperHost = null;
-        VmwareHypervisorHost tgtHyperHost = null;
-        VirtualMachineMO vmMo = null;
-
-        ManagedObjectReference morDsAtTarget = null;
-        ManagedObjectReference morDsAtSource = null;
-        ManagedObjectReference morDc = null;
-        ManagedObjectReference morDcOfTargetHost = null;
-        ManagedObjectReference morTgtHost = new ManagedObjectReference();
-        ManagedObjectReference morTgtDatastore = new ManagedObjectReference();
-        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
-        List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
-        VirtualMachineRelocateSpecDiskLocator diskLocator = null;
-
-        String tgtDsName = "";
-        String tgtDsHost;
-        String tgtDsPath;
-        int tgtDsPort;
-        VolumeTO volume;
-        StorageFilerTO filerTo;
-        Set<String> mountedDatastoresAtSource = new HashSet<String>();
-        List<VolumeObjectTO> volumeToList = new ArrayList<VolumeObjectTO>();
-        Map<Long, Integer> volumeDeviceKey = new HashMap<Long, Integer>();
-
-        List<Pair<VolumeTO, StorageFilerTO>> volToFiler = cmd.getVolumeToFilerAsList();
-        String tgtHost = cmd.getTargetHost();
-        String tgtHostMorInfo = tgtHost.split("@")[0];
-        morTgtHost.setType(tgtHostMorInfo.split(":")[0]);
-        morTgtHost.setValue(tgtHostMorInfo.split(":")[1]);
-
-        try {
-            srcHyperHost = getHyperHost(getServiceContext());
-            tgtHyperHost = new HostMO(getServiceContext(), morTgtHost);
-            morDc = srcHyperHost.getHyperHostDatacenter();
-            morDcOfTargetHost = tgtHyperHost.getHyperHostDatacenter();
-            if (!morDc.getValue().equalsIgnoreCase(morDcOfTargetHost.getValue())) {
-                String msg = "Source host & target host are in different datacentesr";
-                throw new CloudRuntimeException(msg);
-            }
-            VmwareManager mgr = tgtHyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            String srcHostApiVersion = ((HostMO)srcHyperHost).getHostAboutInfo().getApiVersion();
-
-            // find VM through datacenter (VM is not at the target host yet)
-            vmMo = srcHyperHost.findVmOnPeerHyperHost(vmName);
-            if (vmMo == null) {
-                String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-            vmName = vmMo.getName();
-
-            // Specify destination datastore location for each volume
-            for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
-                volume = entry.first();
-                filerTo = entry.second();
-
-                s_logger.debug("Preparing spec for volume : " + volume.getName());
-                morDsAtTarget = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, filerTo.getUuid());
-                morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, filerTo.getUuid());
-                if (morDsAtTarget == null) {
-                    String msg = "Unable to find the target datastore: " + filerTo.getUuid() + " on target host: " + tgtHyperHost.getHyperHostName()
-                            + " to execute MigrateWithStorageCommand";
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-                morTgtDatastore = morDsAtTarget;
-
-                // If host version is below 5.1 then simultaneous change of VM's datastore and host is not supported.
-                // So since only the datastore will be changed first, ensure the target datastore is mounted on source host.
-                if (srcHostApiVersion.compareTo("5.1") < 0) {
-                    tgtDsName = filerTo.getUuid().replace("-", "");
-                    tgtDsHost = filerTo.getHost();
-                    tgtDsPath = filerTo.getPath();
-                    tgtDsPort = filerTo.getPort();
-
-                    // If datastore is NFS and target datastore is not already mounted on source host then mount the datastore.
-                    if (filerTo.getType().equals(StoragePoolType.NetworkFilesystem)) {
-                        if (morDsAtSource == null) {
-                            morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName);
-                            if (morDsAtSource == null) {
-                                throw new Exception("Unable to mount NFS datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
-                            }
-                            mountedDatastoresAtSource.add(tgtDsName);
-                            s_logger.debug("Mounted datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
-                        }
-                    }
-
-                    // If datastore is VMFS and target datastore is not mounted or accessible to source host then fail migration.
-                    if (filerTo.getType().equals(StoragePoolType.VMFS)) {
-                        if (morDsAtSource == null) {
-                            s_logger.warn(
-                                    "If host version is below 5.1, then target VMFS datastore(s) need to manually mounted on source host for a successful live storage migration.");
-                            throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not mounted on source host: " + _hostName);
-                        }
-                        DatastoreMO dsAtSourceMo = new DatastoreMO(getServiceContext(), morDsAtSource);
-                        String srcHostValue = srcHyperHost.getMor().getValue();
-                        if (!dsAtSourceMo.isAccessibleToHost(srcHostValue)) {
-                            s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to accessible to source host for a successful live storage migration.");
-                            throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not accessible on source host: " + _hostName);
-                        }
-                    }
-                    morTgtDatastore = morDsAtSource;
-                }
-
-                if (volume.getType() == Volume.Type.ROOT) {
-                    relocateSpec.setDatastore(morTgtDatastore);
-                }
-                diskLocator = new VirtualMachineRelocateSpecDiskLocator();
-                diskLocator.setDatastore(morDsAtSource);
-                Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volume.getPath(), ".vmdk"));
-                String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
-                if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
-                    vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
-                }
-                int diskId = diskInfo.first().getKey();
-                diskLocator.setDiskId(diskId);
-
-                diskLocators.add(diskLocator);
-                volumeDeviceKey.put(volume.getId(), diskId);
-            }
-            // If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
-            // Hence set the existing datastore as target datastore for volumes that are not to be migrated.
-            List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
-            for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
-                if (!volumeDeviceKey.containsValue(diskDatastore.first().intValue())) {
-                    diskLocator = new VirtualMachineRelocateSpecDiskLocator();
-                    diskLocator.setDiskId(diskDatastore.first().intValue());
-                    diskLocator.setDatastore(diskDatastore.second());
-                    diskLocators.add(diskLocator);
-                }
-            }
-
-            relocateSpec.getDisk().addAll(diskLocators);
-
-            // Prepare network at target before migration
-            NicTO[] nics = vmTo.getNics();
-            for (NicTO nic : nics) {
-                // prepare network on the host
-                prepareNetworkFromNicInfo(new HostMO(getServiceContext(), morTgtHost), nic, false, vmTo.getType());
-            }
-
-            // Ensure secondary storage mounted on target host
-            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
-            String secStoreUrl = secStoreUrlAndId.first();
-            Long secStoreId = secStoreUrlAndId.second();
-            if (secStoreUrl == null) {
-                String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
-                throw new Exception(msg);
-            }
-            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
-            ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
-            if (morSecDs == null) {
-                String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
-                throw new Exception(msg);
-            }
-
-            if (srcHostApiVersion.compareTo("5.1") < 0) {
-                // Migrate VM's volumes to target datastore(s).
-                if (!vmMo.changeDatastore(relocateSpec)) {
-                    throw new Exception("Change datastore operation failed during storage migration");
-                } else {
-                    s_logger.debug("Successfully migrated storage of VM " + vmName + " to target datastore(s)");
-                }
-
-                // Migrate VM to target host.
-                ManagedObjectReference morPool = tgtHyperHost.getHyperHostOwnerResourcePool();
-                if (!vmMo.migrate(morPool, tgtHyperHost.getMor())) {
-                    throw new Exception("VM migration to target host failed during storage migration");
-                } else {
-                    s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName());
-                }
-            } else {
-                // Simultaneously migrate VM's volumes to target datastore and VM to target host.
-                relocateSpec.setHost(tgtHyperHost.getMor());
-                relocateSpec.setPool(tgtHyperHost.getHyperHostOwnerResourcePool());
-                if (!vmMo.changeDatastore(relocateSpec)) {
-                    throw new Exception("Change datastore operation failed during storage migration");
-                } else {
-                    s_logger.debug(
-                            "Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName() + " and its storage to target datastore(s)");
-                }
-            }
-
-            // Consolidate VM disks.
-            // In case of a linked clone VM, if VM's disks are not consolidated, further VM operations such as volume snapshot, VM snapshot etc. will result in DB inconsistencies.
-            if (!vmMo.consolidateVmDisks()) {
-                s_logger.warn("VM disk consolidation failed after storage migration. Yet proceeding with VM migration.");
-            } else {
-                s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
-            }
-
-            // Update and return volume path and chain info for every disk because that could have changed after migration
-            VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-            for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
-                volume = entry.first();
-                long volumeId = volume.getId();
-                VirtualDisk[] disks = vmMo.getAllDiskDevice();
-                for (VirtualDisk disk : disks) {
-                    if (volumeDeviceKey.get(volumeId) == disk.getKey()) {
-                        VolumeObjectTO newVol = new VolumeObjectTO();
-                        String newPath = vmMo.getVmdkFileBaseName(disk);
-                        String poolName = entry.second().getUuid().replace("-", "");
-                        VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolName);
-                        newVol.setId(volumeId);
-                        newVol.setPath(newPath);
-                        newVol.setChainInfo(_gson.toJson(diskInfo));
-                        volumeToList.add(newVol);
-                        break;
-                    }
-                }
-            }
-
-            return new MigrateWithStorageAnswer(cmd, volumeToList);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encountered remote exception at vCenter, invalidating VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.warn(msg, e);
-            return new MigrateWithStorageAnswer(cmd, (Exception)e);
-        } finally {
-            // Cleanup datastores mounted on source host
-            for (String mountedDatastore : mountedDatastoresAtSource) {
-                s_logger.debug("Attempting to unmount datastore " + mountedDatastore + " at " + _hostName);
-                try {
-                    srcHyperHost.unmountDatastore(mountedDatastore);
-                } catch (Exception unmountEx) {
-                    s_logger.debug("Failed to unmount datastore " + mountedDatastore + " at " + _hostName + ". Seems the datastore is still being used by " + _hostName
-                            + ". Please unmount manually to cleanup.");
-                }
-                s_logger.debug("Successfully unmounted datastore " + mountedDatastore + " at " + _hostName);
-            }
-        }
-    }
-
-    private Answer execute(MigrateVolumeCommand cmd) {
-        String volumePath = cmd.getVolumePath();
-        StorageFilerTO poolTo = cmd.getPool();
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource MigrateVolumeCommand: " + _gson.toJson(cmd));
-        }
-
-        String vmName = cmd.getAttachedVmName();
-
-        VirtualMachineMO vmMo = null;
-        VmwareHypervisorHost srcHyperHost = null;
-
-        ManagedObjectReference morDs = null;
-        ManagedObjectReference morDc = null;
-        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
-        List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
-        VirtualMachineRelocateSpecDiskLocator diskLocator = null;
-
-        String tgtDsName = "";
-
-        try {
-            srcHyperHost = getHyperHost(getServiceContext());
-            morDc = srcHyperHost.getHyperHostDatacenter();
-            tgtDsName = poolTo.getUuid();
-
-            // find VM in this datacenter not just in this cluster.
-            DatacenterMO dcMo = new DatacenterMO(getServiceContext(), morDc);
-            vmMo = dcMo.findVm(vmName);
-
-            if (vmMo == null) {
-                String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-            vmName = vmMo.getName();
-            morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, tgtDsName);
-            if (morDs == null) {
-                String msg = "Unable to find the mounted datastore with name: " + tgtDsName + " on source host: " + srcHyperHost.getHyperHostName()
-                        + " to execute MigrateVolumeCommand";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            DatastoreMO targetDsMo = new DatastoreMO(srcHyperHost.getContext(), morDs);
-            String fullVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(targetDsMo, vmName, volumePath + ".vmdk");
-            Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volumePath, ".vmdk"));
-            String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
-            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
-                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
-            }
-            int diskId = diskInfo.first().getKey();
-
-            diskLocator = new VirtualMachineRelocateSpecDiskLocator();
-            diskLocator.setDatastore(morDs);
-            diskLocator.setDiskId(diskId);
-            diskLocators.add(diskLocator);
-            if (cmd.getVolumeType() == Volume.Type.ROOT) {
-                relocateSpec.setDatastore(morDs);
-                // If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
-                // Hence set the existing datastore as target datastore for volumes that are not to be migrated.
-                List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
-                for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
-                    if (diskDatastore.first().intValue() != diskId) {
-                        diskLocator = new VirtualMachineRelocateSpecDiskLocator();
-                        diskLocator.setDiskId(diskDatastore.first().intValue());
-                        diskLocator.setDatastore(diskDatastore.second());
-                        diskLocators.add(diskLocator);
-                    }
-                }
-            }
-
-            relocateSpec.getDisk().addAll(diskLocators);
-
-            // Change datastore
-            if (!vmMo.changeDatastore(relocateSpec)) {
-                throw new Exception("Change datastore operation failed during volume migration");
-            } else {
-                s_logger.debug("Successfully migrated volume " + volumePath + " to target datastore " + tgtDsName);
-            }
-
-            // Consolidate VM disks.
-            // In case of a linked clone VM, if VM's disks are not consolidated,
-            // further volume operations on the ROOT volume such as volume snapshot etc. will result in DB inconsistencies.
-            if (!vmMo.consolidateVmDisks()) {
-                s_logger.warn("VM disk consolidation failed after storage migration.");
-            } else {
-                s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
-            }
-
-            // Update and return volume path and chain info because that could have changed after migration
-            if (!targetDsMo.fileExists(fullVolumePath)) {
-                VirtualDisk[] disks = vmMo.getAllDiskDevice();
-                for (VirtualDisk disk : disks)
-                    if (disk.getKey() == diskId) {
-                        volumePath = vmMo.getVmdkFileBaseName(disk);
-                    }
-            }
-            VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-            String chainInfo = _gson.toJson(diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, poolTo.getUuid().replace("-", "")));
-            MigrateVolumeAnswer answer = new MigrateVolumeAnswer(cmd, true, null, volumePath);
-            answer.setVolumeChainInfo(chainInfo);
-            return answer;
-        } catch (Exception e) {
-            String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
-            s_logger.error(msg, e);
-            return new MigrateVolumeAnswer(cmd, false, msg, null);
-        }
-    }
-
-    private Pair<VirtualDisk, String> getVirtualDiskInfo(VirtualMachineMO vmMo, String srcDiskName) throws Exception {
-        Pair<VirtualDisk, String> deviceInfo = vmMo.getDiskDevice(srcDiskName);
-        if (deviceInfo == null) {
-            throw new Exception("No such disk device: " + srcDiskName);
-        }
-        return deviceInfo;
-    }
-
-    private VmwareHypervisorHost getTargetHyperHost(DatacenterMO dcMo, String destIp) throws Exception {
-
-        VmwareManager mgr = dcMo.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-        List<ObjectContent> ocs = dcMo.getHostPropertiesOnDatacenterHostFolder(new String[] {"name", "parent"});
-        if (ocs != null && ocs.size() > 0) {
-            for (ObjectContent oc : ocs) {
-                HostMO hostMo = new HostMO(dcMo.getContext(), oc.getObj());
-                VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary(mgr.getManagementPortGroupByHost(hostMo));
-                if (destIp.equalsIgnoreCase(netSummary.getHostIp())) {
-                    return new HostMO(dcMo.getContext(), oc.getObj());
-                }
-            }
-        }
-
-        throw new Exception("Unable to locate dest host by " + destIp);
-    }
-
-    protected Answer execute(CreateStoragePoolCommand cmd) {
-        if (cmd.getCreateDatastore()) {
-            try {
-                VmwareContext context = getServiceContext();
-
-                _storageProcessor.prepareManagedDatastore(context, getHyperHost(context), cmd.getDetails().get(CreateStoragePoolCommand.DATASTORE_NAME),
-                        cmd.getDetails().get(CreateStoragePoolCommand.IQN), cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_HOST),
-                        Integer.parseInt(cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_PORT)));
-            } catch (Exception ex) {
-                return new Answer(cmd, false, "Issue creating datastore");
-            }
-        }
-
-        return new Answer(cmd, true, "success");
-    }
-
-    protected Answer execute(ModifyTargetsCommand cmd) {
-        VmwareContext context = getServiceContext(cmd);
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-        List<HostMO> hostMOs = new ArrayList<>();
-
-        if (cmd.getApplyToAllHostsInCluster()) {
-            try {
-                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-                ClusterMO clusterMO = new ClusterMO(context, morCluster);
-
-                List<Pair<ManagedObjectReference, String>> hosts = clusterMO.getClusterHosts();
-
-                for (Pair<ManagedObjectReference, String> host : hosts) {
-                    HostMO hostMO = new HostMO(context, host.first());
-
-                    hostMOs.add(hostMO);
-                }
-            }
-            catch (Exception ex) {
-                s_logger.error(ex.getMessage(), ex);
-
-                throw new CloudRuntimeException(ex.getMessage(), ex);
-            }
-        }
-        else {
-            hostMOs.add((HostMO)hyperHost);
-        }
-
-        handleTargets(cmd.getAdd(), cmd.getTargetTypeToRemove(), cmd.isRemoveAsync(), cmd.getTargets(), hostMOs);
-
-        return new ModifyTargetsAnswer();
-    }
-
-    protected Answer execute(ModifyStoragePoolCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ModifyStoragePoolCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            StorageFilerTO pool = cmd.getPool();
-
-            if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS) {
-                throw new Exception("Unsupported storage pool type " + pool.getType());
-            }
-
-            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid());
-
-            if (morDatastore == null) {
-                morDatastore = hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", ""));
-            }
-
-            assert (morDatastore != null);
-
-            DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
-
-            long capacity = summary.getCapacity();
-            long available = summary.getFreeSpace();
-
-            Map<String, TemplateProp> tInfo = new HashMap<>();
-            ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
-
-            if (cmd.getAdd() && pool.getType() == StoragePoolType.VMFS) {
-                answer.setLocalDatastoreName(morDatastore.getValue());
-            }
-
-            return answer;
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-
-                invalidateServiceContext();
-            }
-
-            String msg = "ModifyStoragePoolCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-
-            s_logger.error(msg, e);
-
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    private void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove, boolean isRemoveAsync,
-                               List<Map<String, String>> targets, List<HostMO> hosts) {
-        if (targets != null && targets.size() > 0) {
-            try {
-                _storageProcessor.handleTargets(add, targetTypeToRemove, isRemoveAsync, targets, hosts);
-            }
-            catch (Exception ex) {
-                s_logger.warn(ex.getMessage());
-            }
-        }
-    }
-
-    protected Answer execute(DeleteStoragePoolCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource DeleteStoragePoolCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            if (cmd.getRemoveDatastore()) {
-                _storageProcessor.handleDatastoreAndVmdkDetach(cmd, cmd.getDetails().get(DeleteStoragePoolCommand.DATASTORE_NAME),
-                        cmd.getDetails().get(DeleteStoragePoolCommand.IQN), cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_HOST),
-                        Integer.parseInt(cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_PORT)));
-
-                return new Answer(cmd, true, "success");
-            } else {
-                // We will leave datastore cleanup management to vCenter. Since for cluster VMFS datastore, it will always
-                // be mounted by vCenter.
-
-                // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext());
-                // hyperHost.unmountDatastore(pool.getUuid());
-
-                return new Answer(cmd, true, "success");
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-
-                invalidateServiceContext();
-            }
-
-            StorageFilerTO pool = cmd.getPool();
-            String msg = "DeleteStoragePoolCommand (pool: " + pool.getHost() + ", path: " + pool.getPath() + ") failed due to " + VmwareHelper.getExceptionMessage(e);
-
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    public static String getDatastoreName(String str) {
-        return str.replace('/', '-');
-    }
-
-    public static String createDatastoreNameFromIqn(String iqn) {
-        return "-" + iqn + "-0";
-    }
-
-    protected AttachIsoAnswer execute(AttachIsoCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource AttachIsoCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
-            if (vmMo == null) {
-                String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + cmd.getVmName();
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            String storeUrl = cmd.getStoreUrl();
-            if (storeUrl == null) {
-                if (!cmd.getIsoPath().equalsIgnoreCase("vmware-tools.iso")) {
-                    String msg = "ISO store root url is not found in AttachIsoCommand";
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                } else {
-                    if (cmd.isAttach()) {
-                        vmMo.mountToolsInstaller();
-                    } else {
-                        try {
-                            if (!vmMo.unmountToolsInstaller()) {
-                                return new AttachIsoAnswer(cmd, false,
-                                        "Failed to unmount vmware-tools installer ISO as the corresponding CDROM device is locked by VM. Please unmount the CDROM device inside the VM and ret-try.");
-                            }
-                        } catch (Throwable e) {
-                            vmMo.detachIso(null);
-                        }
-                    }
-
-                    return new AttachIsoAnswer(cmd);
-                }
-            }
-
-            ManagedObjectReference morSecondaryDs = prepareSecondaryDatastoreOnHost(storeUrl);
-            String isoPath = cmd.getIsoPath();
-            if (!isoPath.startsWith(storeUrl)) {
-                assert (false);
-                String msg = "ISO path does not start with the secondary storage root";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            int isoNameStartPos = isoPath.lastIndexOf('/');
-            String isoFileName = isoPath.substring(isoNameStartPos + 1);
-            String isoStorePathFromRoot = isoPath.substring(storeUrl.length() + 1, isoNameStartPos + 1);
-
-
-            // TODO, check if iso is already attached, or if there is a previous
-            // attachment
-            DatastoreMO secondaryDsMo = new DatastoreMO(getServiceContext(), morSecondaryDs);
-            String storeName = secondaryDsMo.getName();
-            String isoDatastorePath = String.format("[%s] %s%s", storeName, isoStorePathFromRoot, isoFileName);
-
-            if (cmd.isAttach()) {
-                vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false, cmd.getDeviceKey());
-                return new AttachIsoAnswer(cmd);
-            } else {
-                int key = vmMo.detachIso(isoDatastorePath, cmd.isForce());
-                return new AttachIsoAnswer(cmd, key);
-            }
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            if (cmd.isAttach()) {
-                String msg = "AttachIsoCommand(attach) failed due to " + VmwareHelper.getExceptionMessage(e);
-                s_logger.error(msg, e);
-                return new AttachIsoAnswer(cmd, false, msg);
-            } else {
-                String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e);
-                s_logger.warn(msg, e);
-                return new AttachIsoAnswer(cmd, false, msg);
-            }
-        }
-    }
-
-    public synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception {
-        String storeName = getSecondaryDatastoreUUID(storeUrl);
-        URI uri = new URI(storeUrl);
-
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
-
-        if (morDatastore == null)
-            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
-
-        return morDatastore;
-    }
-
-    public synchronized ManagedObjectReference prepareSecondaryDatastoreOnSpecificHost(String storeUrl, VmwareHypervisorHost hyperHost) throws Exception {
-        String storeName = getSecondaryDatastoreUUID(storeUrl);
-        URI uri = new URI(storeUrl);
-
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
-
-        if (morDatastore == null)
-            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
-
-        return morDatastore;
-    }
-
-    private static String getSecondaryDatastoreUUID(String storeUrl) {
-        String uuid = null;
-        try {
-            uuid = UUID.nameUUIDFromBytes(storeUrl.getBytes("UTF-8")).toString();
-        } catch (UnsupportedEncodingException e) {
-            s_logger.warn("Failed to create UUID from string " + storeUrl + ". Bad storeUrl or UTF-8 encoding error.");
-        }
-        return uuid;
-    }
-
-    protected Answer execute(ValidateSnapshotCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ValidateSnapshotCommand: " + _gson.toJson(cmd));
-        }
-
-        // the command is no longer available
-        String expectedSnapshotBackupUuid = null;
-        String actualSnapshotBackupUuid = null;
-        String actualSnapshotUuid = null;
-        return new ValidateSnapshotAnswer(cmd, false, "ValidateSnapshotCommand is not supported for vmware yet", expectedSnapshotBackupUuid, actualSnapshotBackupUuid,
-                actualSnapshotUuid);
-    }
-
-    protected Answer execute(ManageSnapshotCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ManageSnapshotCommand: " + _gson.toJson(cmd));
-        }
-
-        long snapshotId = cmd.getSnapshotId();
-
-        /*
-         * "ManageSnapshotCommand",
-         * "{\"_commandSwitch\":\"-c\",\"_volumePath\":\"i-2-3-KY-ROOT\",\"_snapshotName\":\"i-2-3-KY_i-2-3-KY-ROOT_20101102203827\",\"_snapshotId\":1,\"_vmName\":\"i-2-3-KY\"}"
-         */
-        boolean success = false;
-        String cmdSwitch = cmd.getCommandSwitch();
-        String snapshotOp = "Unsupported snapshot command." + cmdSwitch;
-        if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
-            snapshotOp = "create";
-        } else if (cmdSwitch.equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) {
-            snapshotOp = "destroy";
-        }
-
-        String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId;
-        String snapshotUUID = null;
-
-        // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake
-        // a success return here
-        snapshotUUID = UUID.randomUUID().toString();
-        success = true;
-        details = null;
-
-        return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details);
-    }
-
-    protected Answer execute(BackupSnapshotCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource BackupSnapshotCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String details = "BackupSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details, e);
-            return new BackupSnapshotAnswer(cmd, false, details, null, true);
-        }
-    }
-
-    protected Answer execute(CreateVMSnapshotCommand cmd) {
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return new CreateVMSnapshotAnswer(cmd, false, "");
-        }
-    }
-
-    protected Answer execute(DeleteVMSnapshotCommand cmd) {
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return new DeleteVMSnapshotAnswer(cmd, false, "");
-        }
-    }
-
-    protected Answer execute(RevertToVMSnapshotCommand cmd) {
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return new RevertToVMSnapshotAnswer(cmd, false, "");
-        }
-    }
-
-    protected Answer execute(CreateVolumeFromSnapshotCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd));
-        }
-
-        String details = null;
-        boolean success = false;
-        String newVolumeName = UUID.randomUUID().toString();
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            details = "CreateVolumeFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details, e);
-        }
-
-        return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
-    }
-
-    protected Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            return mgr.getStorageManager().execute(this, cmd);
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String details = "CreatePrivateTemplateFromVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details, e);
-            return new CreatePrivateTemplateAnswer(cmd, false, details);
-        }
-    }
-
-    protected Answer execute(final UpgradeSnapshotCommand cmd) {
-        return new Answer(cmd, true, "success");
-    }
-
-    protected Answer execute(CreatePrivateTemplateFromSnapshotCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CreatePrivateTemplateFromSnapshotCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return mgr.getStorageManager().execute(this, cmd);
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String details = "CreatePrivateTemplateFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details, e);
-            return new CreatePrivateTemplateAnswer(cmd, false, details);
-        }
-    }
-
-    protected Answer execute(GetStorageStatsCommand cmd) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Executing resource GetStorageStatsCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId());
-
-            if (morDs != null) {
-                DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
-                DatastoreSummary summary = datastoreMo.getSummary();
-                assert (summary != null);
-
-                long capacity = summary.getCapacity();
-                long free = summary.getFreeSpace();
-                long used = capacity - free;
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Datastore summary info, storageId: " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype()
-                            + ", capacity: " + capacity + ", free: " + free + ", used: " + used);
-                }
-
-                if (summary.getCapacity() <= 0) {
-                    s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help");
-                }
-
-                return new GetStorageStatsAnswer(cmd, capacity, used);
-            } else {
-                String msg = "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: "
-                        + cmd.getPooltype();
-
-                s_logger.error(msg);
-                return new GetStorageStatsAnswer(cmd, msg);
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype()
-                    + ") due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new GetStorageStatsAnswer(cmd, msg);
-        }
-    }
-
-    protected Answer execute(GetVncPortCommand cmd) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Executing resource GetVncPortCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            assert (hyperHost instanceof HostMO);
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getName());
-            if (vmMo == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to find the owner VM for GetVncPortCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter");
-                }
-
-                vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getName());
-
-                if (vmMo == null) {
-                    throw new Exception("Unable to find VM in vSphere, vm: " + cmd.getName());
-                }
-            }
-
-            Pair<String, Integer> portInfo = vmMo.getVncPort(mgr.getManagementPortGroupByHost((HostMO)hyperHost));
-
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Found vnc port info. vm: " + cmd.getName() + " host: " + portInfo.first() + ", vnc port: " + portInfo.second());
-            }
-            return new GetVncPortAnswer(cmd, portInfo.first(), portInfo.second());
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "GetVncPortCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new GetVncPortAnswer(cmd, msg);
-        }
-    }
-
-    protected Answer execute(SetupCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource SetupCommand: " + _gson.toJson(cmd));
-        }
-
-        return new SetupAnswer(cmd, false);
-    }
-
-    protected Answer execute(MaintainCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource MaintainCommand: " + _gson.toJson(cmd));
-        }
-
-        return new MaintainAnswer(cmd, "Put host in maintaince");
-    }
-
-    protected Answer execute(PingTestCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PingTestCommand: " + _gson.toJson(cmd));
-        }
-
-        String controlIp = cmd.getRouterIp();
-        if (controlIp != null) {
-            String args = " -c 1 -n -q " + cmd.getPrivateIp();
-            try {
-                Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", getSystemVmKeyFile(), null, "/bin/ping" + args);
-                if (result.first())
-                    return new Answer(cmd);
-            } catch (Exception e) {
-                s_logger.error("Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e);
-            }
-            return new Answer(cmd, false, "PingTestCommand failed");
-        } else {
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-            try {
-                HostMO hostMo = (HostMO)hyperHost;
-                ClusterMO clusterMo = new ClusterMO(context, hostMo.getHyperHostCluster());
-                VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-                List<Pair<ManagedObjectReference, String>> hosts = clusterMo.getClusterHosts();
-                for (Pair<ManagedObjectReference, String> entry : hosts) {
-                    HostMO hostInCluster = new HostMO(context, entry.first());
-                    String hostIp = hostInCluster.getHostManagementIp(mgr.getManagementPortGroupName());
-                    if (hostIp != null && hostIp.equals(cmd.getComputingHostIp())) {
-                        if (hostInCluster.isHyperHostConnected())
-                            return new Answer(cmd);
-                        else
-                            return new Answer(cmd, false, "PingTestCommand failed");
-                    }
-                }
-            } catch (Exception e) {
-                s_logger.error("Unable to execute ping command on host (" + cmd.getComputingHostIp() + "). failure due to " + VmwareHelper.getExceptionMessage(e), e);
-            }
-
-            return new Answer(cmd, false, "PingTestCommand failed");
-        }
-    }
-
-    protected Answer execute(CheckOnHostCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CheckOnHostCommand: " + _gson.toJson(cmd));
-        }
-
-        return new CheckOnHostAnswer(cmd, null, "Not Implmeneted");
-    }
-
-    protected Answer execute(ModifySshKeysCommand cmd) {
-        //do not log the command contents for this command. do NOT log the ssh keys
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ModifySshKeysCommand.");
-        }
-
-        return new Answer(cmd);
-    }
-
-    protected Answer execute(GetVmIpAddressCommand cmd) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Executing resource command GetVmIpAddressCommand: " + _gson.toJson(cmd));
-        }
-
-        String details = "Unable to find IP Address of VM. ";
-        String vmName = cmd.getVmName();
-        boolean result = false;
-        String ip = null;
-        Answer answer = null;
-
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-
-        if (vmName == null || vmName.isEmpty()) {
-            details += "Name of instance provided is NULL or empty.";
-            return new Answer(cmd, result, details);
-        }
-
-        try {
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if (vmMo != null) {
-                GuestInfo guestInfo = vmMo.getGuestInfo();
-                VirtualMachineToolsStatus toolsStatus = guestInfo.getToolsStatus();
-                if (toolsStatus == VirtualMachineToolsStatus.TOOLS_NOT_INSTALLED) {
-                    details += "Vmware tools not installed.";
-                } else {
-                    ip = guestInfo.getIpAddress();
-                    if (ip != null) {
-                        result = true;
-                    }
-                    details = ip;
-                }
-            } else {
-                details += "VM " + vmName + " no longer exists on vSphere host: " + hyperHost.getHyperHostName();
-                s_logger.info(details);
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-            details += "Encountered exception : " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(details);
-        }
-
-        answer = new Answer(cmd, result, details);
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Returning GetVmIpAddressAnswer: " + _gson.toJson(answer));
-        }
-        return answer;
-    }
-
-    @Override
-    public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return (PrimaryStorageDownloadAnswer)mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "PrimaryStorageDownloadCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new PrimaryStorageDownloadAnswer(msg);
-        }
-    }
-
-    protected Answer execute(PvlanSetupCommand cmd) {
-        // Pvlan related operations are performed in the start/stop command paths
-        // for vmware. This function is implemented to support mgmt layer code
-        // that issue this command. Note that pvlan operations are supported only
-        // in Distributed Virtual Switch environments for vmware deployments.
-        return new Answer(cmd, true, "success");
-    }
-
-    protected Answer execute(UnregisterVMCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource UnregisterVMCommand: " + _gson.toJson(cmd));
-        }
-
-        VmwareContext context = getServiceContext();
-        VmwareHypervisorHost hyperHost = getHyperHost(context);
-        try {
-            DatacenterMO dataCenterMo = new DatacenterMO(getServiceContext(), hyperHost.getHyperHostDatacenter());
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
-            if (vmMo != null) {
-                try {
-                    VirtualMachineFileLayoutEx vmFileLayout = vmMo.getFileLayout();
-                    context.getService().unregisterVM(vmMo.getMor());
-                    if (cmd.getCleanupVmFiles()) {
-                        deleteUnregisteredVmFiles(vmFileLayout, dataCenterMo, false, null);
-                    }
-                    return new Answer(cmd, true, "unregister succeeded");
-                } catch (Exception e) {
-                    s_logger.warn("We are not able to unregister VM " + VmwareHelper.getExceptionMessage(e));
-                }
-
-                String msg = "Expunge failed in vSphere. vm: " + cmd.getVmName();
-                s_logger.warn(msg);
-                return new Answer(cmd, false, msg);
-            } else {
-                String msg = "Unable to find the VM in vSphere to unregister, assume it is already removed. VM: " + cmd.getVmName();
-                s_logger.warn(msg);
-                return new Answer(cmd, true, msg);
-            }
-        } catch (Exception e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    /**
-     * UnregisterNicCommand is used to remove a portgroup created for this
-     * specific nic. The portgroup will have the name set to the UUID of the
-     * nic. Introduced to cleanup the portgroups created for each nic that is
-     * plugged into an lswitch (Nicira NVP plugin)
-     *
-     * @param cmd
-     * @return
-     */
-    protected Answer execute(UnregisterNicCommand cmd) {
-        s_logger.info("Executing resource UnregisterNicCommand: " + _gson.toJson(cmd));
-
-        if (_guestTrafficInfo == null) {
-            return new Answer(cmd, false, "No Guest Traffic Info found, unable to determine where to clean up");
-        }
-
-        try {
-            if (_guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
-                // For now we only need to cleanup the nvp specific portgroups
-                // on the standard switches
-                return new Answer(cmd, true, "Nothing to do");
-            }
-
-            s_logger.debug("Cleaning up portgroup " + cmd.getNicUuid() + " on switch " + _guestTrafficInfo.getVirtualSwitchName());
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost host = getHyperHost(context);
-            ManagedObjectReference clusterMO = host.getHyperHostCluster();
-
-            // Get a list of all the hosts in this cluster
-            @SuppressWarnings("unchecked")
-            List<ManagedObjectReference> hosts = (List<ManagedObjectReference>)context.getVimClient().getDynamicProperty(clusterMO, "host");
-            if (hosts == null) {
-                return new Answer(cmd, false, "No hosts in cluster, which is pretty weird");
-            }
-
-            for (ManagedObjectReference hostMOR : hosts) {
-                HostMO hostMo = new HostMO(context, hostMOR);
-                hostMo.deletePortGroup(cmd.getNicUuid().toString());
-                s_logger.debug("Removed portgroup " + cmd.getNicUuid() + " from host " + hostMo.getHostName());
-            }
-            return new Answer(cmd, true, "Unregistered resources for NIC " + cmd.getNicUuid());
-        } catch (Exception e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) {
-        // we will no longer cleanup VLAN networks in order to support native VMware HA
-        /*
-         * assert(netDetails.getName() != null); try { synchronized(this) { NetworkMO networkMo = new
-         * NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); ManagedObjectReference[] vms =
-         * networkMo.getVMsOnNetwork(); if(vms == null || vms.length == 0) { if(s_logger.isInfoEnabled()) {
-         * s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); }
-         *
-         * hostMo.deletePortGroup(netDetails.getName()); } } } catch(Throwable e) {
-         * s_logger.warn("Unable to cleanup network due to exception, skip for next time"); }
-         */
-    }
-
-    @Override
-    public CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource CopyVolumeCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            return (CopyVolumeAnswer)mgr.getStorageManager().execute(this, cmd);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-
-            String msg = "CopyVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new CopyVolumeAnswer(cmd, false, msg, null, null);
-        }
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    @Override
-    public IAgentControl getAgentControl() {
-        return null;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(long id) {
-        try {
-            gcAndKillHungWorkerVMs();
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            try {
-                if (!hyperHost.isHyperHostConnected()) {
-                    return null;
-                }
-            } catch (Exception e) {
-                s_logger.error("Unexpected exception", e);
-                return null;
-            }
-            return new PingRoutingCommand(getType(), id, syncHostVmStates());
-        } finally {
-            recycleServiceContext();
-        }
-    }
-
-    private void gcAndKillHungWorkerVMs() {
-        try {
-            // take the chance to do left-over dummy VM cleanup from previous run
-            VmwareContext context = getServiceContext();
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            if (hyperHost.isHyperHostConnected()) {
-                mgr.gcLeftOverVMs(context);
-
-                s_logger.info("Scan hung worker VM to recycle");
-
-                int workerKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
-                int workerTagKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
-                String workerPropName = String.format("value[%d]", workerKey);
-                String workerTagPropName = String.format("value[%d]", workerTagKey);
-
-                // GC worker that has been running for too long
-                ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "config.template", workerPropName, workerTagPropName,});
-                if (ocs != null) {
-                    for (ObjectContent oc : ocs) {
-                        List<DynamicProperty> props = oc.getPropSet();
-                        if (props != null) {
-                            boolean template = false;
-                            boolean isWorker = false;
-                            String workerTag = null;
-
-                            for (DynamicProperty prop : props) {
-                                if (prop.getName().equals("config.template")) {
-                                    template = (Boolean)prop.getVal();
-                                } else if (prop.getName().equals(workerPropName)) {
-                                    CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
-                                    if (val != null && val.getValue() != null && val.getValue().equalsIgnoreCase("true"))
-                                        isWorker = true;
-                                } else if (prop.getName().equals(workerTagPropName)) {
-                                    CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
-                                    workerTag = val.getValue();
-                                }
-                            }
-
-                            VirtualMachineMO vmMo = new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
-                            if (!template && isWorker) {
-                                boolean recycle = false;
-                                recycle = mgr.needRecycle(workerTag);
-
-                                if (recycle) {
-                                    s_logger.info("Recycle pending worker VM: " + vmMo.getName());
-
-                                    vmMo.powerOff();
-                                    vmMo.detachAllDisks();
-                                    vmMo.destroy();
-                                }
-                            }
-                        }
-                    }
-                }
-            } else {
-                s_logger.error("Host is no longer connected.");
-            }
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext();
-            }
-        }
-    }
-
-    @Override
-    public Type getType() {
-        return com.cloud.host.Host.Type.Routing;
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-        try {
-            String hostApiVersion = "4.1";
-            VmwareContext context = getServiceContext();
-            try {
-                VmwareHypervisorHost hyperHost = getHyperHost(context);
-                assert (hyperHost instanceof HostMO);
-                if (!((HostMO)hyperHost).isHyperHostConnected()) {
-                    s_logger.info("Host " + hyperHost.getHyperHostName() + " is not in connected state");
-                    return null;
-                }
-
-                ((HostMO)hyperHost).enableVncOnHostFirewall();
-
-                AboutInfo aboutInfo = ((HostMO)hyperHost).getHostAboutInfo();
-                hostApiVersion = aboutInfo.getApiVersion();
-
-            } catch (Exception e) {
-                String msg = "VmwareResource intialize() failed due to : " + VmwareHelper.getExceptionMessage(e);
-                s_logger.error(msg);
-                invalidateServiceContext();
-                return null;
-            }
-
-            StartupRoutingCommand cmd = new StartupRoutingCommand();
-            fillHostInfo(cmd);
-            cmd.setHypervisorType(HypervisorType.VMware);
-            cmd.setCluster(_cluster);
-            cmd.setHypervisorVersion(hostApiVersion);
-
-            List<StartupStorageCommand> storageCmds = initializeLocalStorage();
-            StartupCommand[] answerCmds = new StartupCommand[1 + storageCmds.size()];
-            answerCmds[0] = cmd;
-            for (int i = 0; i < storageCmds.size(); i++) {
-                answerCmds[i + 1] = storageCmds.get(i);
-            }
-
-            return answerCmds;
-        } finally {
-            recycleServiceContext();
-        }
-    }
-
-    private List<StartupStorageCommand> initializeLocalStorage() {
-        List<StartupStorageCommand> storageCmds = new ArrayList<StartupStorageCommand>();
-        VmwareContext context = getServiceContext();
-
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(context);
-            if (hyperHost instanceof HostMO) {
-                HostMO hostMo = (HostMO)hyperHost;
-
-                List<Pair<ManagedObjectReference, String>> dsList = hostMo.getLocalDatastoreOnHost();
-                for (Pair<ManagedObjectReference, String> dsPair : dsList) {
-                    DatastoreMO dsMo = new DatastoreMO(context, dsPair.first());
-
-                    String poolUuid = dsMo.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                    if (poolUuid == null || poolUuid.isEmpty()) {
-                        poolUuid = UUID.randomUUID().toString();
-                        dsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, poolUuid);
-                    }
-
-                    DatastoreSummary dsSummary = dsMo.getSummary();
-                    String address = hostMo.getHostName();
-                    StoragePoolInfo pInfo = new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.VMFS, dsSummary.getCapacity(),
-                            dsSummary.getFreeSpace());
-                    StartupStorageCommand cmd = new StartupStorageCommand();
-                    cmd.setName(poolUuid);
-                    cmd.setPoolInfo(pInfo);
-                    cmd.setGuid(poolUuid); // give storage host the same UUID as the local storage pool itself
-                    cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
-                    cmd.setDataCenter(_dcId);
-                    cmd.setPod(_pod);
-                    cmd.setCluster(_cluster);
-
-                    s_logger.info("Add local storage startup command: " + _gson.toJson(cmd));
-                    storageCmds.add(cmd);
-                }
-
-            } else {
-                s_logger.info("Cluster host does not support local storage, skip it");
-            }
-        } catch (Exception e) {
-            String msg = "initializing local storage failed due to : " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg);
-            invalidateServiceContext();
-            throw new CloudRuntimeException(msg);
-        }
-
-        return storageCmds;
-    }
-
-    protected void fillHostInfo(StartupRoutingCommand cmd) {
-        VmwareContext serviceContext = getServiceContext();
-        Map<String, String> details = cmd.getHostDetails();
-        if (details == null) {
-            details = new HashMap<String, String>();
-        }
-
-        try {
-            fillHostHardwareInfo(serviceContext, cmd);
-            fillHostNetworkInfo(serviceContext, cmd);
-            fillHostDetailsInfo(serviceContext, details);
-        } catch (RuntimeFaultFaultMsg e) {
-            s_logger.error("RuntimeFault while retrieving host info: " + e.toString(), e);
-            throw new CloudRuntimeException("RuntimeFault while retrieving host info");
-        } catch (RemoteException e) {
-            s_logger.error("RemoteException while retrieving host info: " + e.toString(), e);
-            invalidateServiceContext();
-            throw new CloudRuntimeException("RemoteException while retrieving host info");
-        } catch (Exception e) {
-            s_logger.error("Exception while retrieving host info: " + e.toString(), e);
-            invalidateServiceContext();
-            throw new CloudRuntimeException("Exception while retrieving host info: " + e.toString());
-        }
-
-        cmd.setHostDetails(details);
-        cmd.setName(_url);
-        cmd.setGuid(_guid);
-        cmd.setDataCenter(_dcId);
-        cmd.setIqn(getIqn());
-        cmd.setPod(_pod);
-        cmd.setCluster(_cluster);
-        cmd.setVersion(VmwareResource.class.getPackage().getImplementationVersion());
-    }
-
-    private String getIqn() {
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-
-            if (hyperHost instanceof HostMO) {
-                HostMO host = (HostMO)hyperHost;
-                HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
-
-                for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-                    if (hba instanceof HostInternetScsiHba) {
-                        HostInternetScsiHba hostInternetScsiHba = (HostInternetScsiHba)hba;
-
-                        if (hostInternetScsiHba.isIsSoftwareBased()) {
-                            return ((HostInternetScsiHba)hba).getIScsiName();
-                        }
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            s_logger.info("Could not locate an IQN for this host.");
-        }
-
-        return null;
-    }
-
-    private void fillHostHardwareInfo(VmwareContext serviceContext, StartupRoutingCommand cmd) throws RuntimeFaultFaultMsg, RemoteException, Exception {
-
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        VmwareHypervisorHostResourceSummary summary = hyperHost.getHyperHostResourceSummary();
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Startup report on host hardware info. " + _gson.toJson(summary));
-        }
-
-        cmd.setCaps("hvm");
-        cmd.setDom0MinMemory(0);
-        cmd.setSpeed(summary.getCpuSpeed());
-        cmd.setCpuSockets(summary.getCpuSockets());
-        cmd.setCpus((int)summary.getCpuCount());
-        cmd.setMemory(summary.getMemoryBytes());
-    }
-
-    private void fillHostNetworkInfo(VmwareContext serviceContext, StartupRoutingCommand cmd) throws RuntimeFaultFaultMsg, RemoteException {
-
-        try {
-            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-
-            assert (hyperHost instanceof HostMO);
-            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-
-            VmwareHypervisorHostNetworkSummary summary = hyperHost.getHyperHostNetworkSummary(mgr.getManagementPortGroupByHost((HostMO)hyperHost));
-            if (summary == null) {
-                throw new Exception("No ESX(i) host found");
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Startup report on host network info. " + _gson.toJson(summary));
-            }
-
-            cmd.setPrivateIpAddress(summary.getHostIp());
-            cmd.setPrivateNetmask(summary.getHostNetmask());
-            cmd.setPrivateMacAddress(summary.getHostMacAddress());
-
-            cmd.setStorageIpAddress(summary.getHostIp());
-            cmd.setStorageNetmask(summary.getHostNetmask());
-            cmd.setStorageMacAddress(summary.getHostMacAddress());
-
-        } catch (Throwable e) {
-            String msg = "querying host network info failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    private void fillHostDetailsInfo(VmwareContext serviceContext, Map<String, String> details) throws Exception {
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-
-        if (hyperHost.isHAEnabled()) {
-            details.put("NativeHA", "true");
-        }
-    }
-
-    protected HashMap<String, HostVmStateReportEntry> syncHostVmStates() {
-        try {
-            return getHostVmStateReport();
-        } catch (Exception e) {
-            return new HashMap<String, HostVmStateReportEntry>();
-        }
-    }
-
-    protected OptionValue[] configureVnc(OptionValue[] optionsToMerge, VmwareHypervisorHost hyperHost, String vmName, String vncPassword, String keyboardLayout) throws Exception {
-
-        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-
-        VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-        if (!mgr.beginExclusiveOperation(600))
-            throw new Exception("Unable to begin exclusive operation, lock time out");
-
-        try {
-            int maxVncPorts = 64;
-            int vncPort = 0;
-            Random random = new Random();
-
-            HostMO vmOwnerHost = vmMo.getRunningHost();
-
-            ManagedObjectReference morParent = vmOwnerHost.getParentMor();
-            HashMap<String, Integer> portInfo;
-            if (morParent.getType().equalsIgnoreCase("ClusterComputeResource")) {
-                ClusterMO clusterMo = new ClusterMO(vmOwnerHost.getContext(), morParent);
-                portInfo = clusterMo.getVmVncPortsOnCluster();
-            } else {
-                portInfo = vmOwnerHost.getVmVncPortsOnHost();
-            }
-
-            // allocate first at 5900 - 5964 range
-            Collection<Integer> existingPorts = portInfo.values();
-            int val = random.nextInt(maxVncPorts);
-            int startVal = val;
-            do {
-                if (!existingPorts.contains(5900 + val)) {
-                    vncPort = 5900 + val;
-                    break;
-                }
-
-                val = (++val) % maxVncPorts;
-            } while (val != startVal);
-
-            if (vncPort == 0) {
-                s_logger.info("we've run out of range for ports between 5900-5964 for the cluster, we will try port range at 59000-60000");
-
-                Pair<Integer, Integer> additionalRange = mgr.getAddiionalVncPortRange();
-                maxVncPorts = additionalRange.second();
-                val = random.nextInt(maxVncPorts);
-                startVal = val;
-                do {
-                    if (!existingPorts.contains(additionalRange.first() + val)) {
-                        vncPort = additionalRange.first() + val;
-                        break;
-                    }
-
-                    val = (++val) % maxVncPorts;
-                } while (val != startVal);
-            }
-
-            if (vncPort == 0) {
-                throw new Exception("Unable to find an available VNC port on host");
-            }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Configure VNC port for VM " + vmName + ", port: " + vncPort + ", host: " + vmOwnerHost.getHyperHostName());
-            }
-
-            return VmwareHelper.composeVncOptions(optionsToMerge, true, vncPassword, vncPort, keyboardLayout);
-        } finally {
-            try {
-                mgr.endExclusiveOperation();
-            } catch (Throwable e) {
-                assert (false);
-                s_logger.error("Unexpected exception ", e);
-            }
-        }
-    }
-
-    private VirtualMachineGuestOsIdentifier translateGuestOsIdentifier(String cpuArchitecture, String guestOs, String cloudGuestOs) {
-        if (cpuArchitecture == null) {
-            s_logger.warn("CPU arch is not set, default to i386. guest os: " + guestOs);
-            cpuArchitecture = "i386";
-        }
-
-        if (cloudGuestOs == null) {
-            s_logger.warn("Guest OS mapping name is not set for guest os: " + guestOs);
-        }
-
-        VirtualMachineGuestOsIdentifier identifier = null;
-        try {
-            if (cloudGuestOs != null) {
-                identifier = VirtualMachineGuestOsIdentifier.fromValue(cloudGuestOs);
-                s_logger.debug("Using mapping name : " + identifier.toString());
-            }
-        } catch (IllegalArgumentException e) {
-            s_logger.warn("Unable to find Guest OS Identifier in VMware for mapping name: " + cloudGuestOs + ". Continuing with defaults.");
-        }
-        if (identifier != null) {
-            return identifier;
-        }
-
-        if (cpuArchitecture.equalsIgnoreCase("x86_64")) {
-            return VirtualMachineGuestOsIdentifier.OTHER_GUEST_64;
-        }
-        return VirtualMachineGuestOsIdentifier.OTHER_GUEST;
-    }
-
-    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport() throws Exception {
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-
-        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
-        if (key == 0) {
-            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
-        }
-        String instanceNameCustomField = "value[" + key + "]";
-
-        // CLOUD_VM_INTERNAL_NAME stores the internal CS generated vm name. This was earlier stored in name. Now, name can be either the hostname or
-        // the internal CS name, but the custom field CLOUD_VM_INTERNAL_NAME always stores the internal CS name.
-        ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "runtime.powerState", "config.template", instanceNameCustomField});
-
-        HashMap<String, HostVmStateReportEntry> newStates = new HashMap<String, HostVmStateReportEntry>();
-        if (ocs != null && ocs.length > 0) {
-            for (ObjectContent oc : ocs) {
-                List<DynamicProperty> objProps = oc.getPropSet();
-                if (objProps != null) {
-
-                    boolean isTemplate = false;
-                    String name = null;
-                    String VMInternalCSName = null;
-                    VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
-                    for (DynamicProperty objProp : objProps) {
-                        if (objProp.getName().equals("config.template")) {
-                            if (objProp.getVal().toString().equalsIgnoreCase("true")) {
-                                isTemplate = true;
-                            }
-                        } else if (objProp.getName().equals("runtime.powerState")) {
-                            powerState = (VirtualMachinePowerState)objProp.getVal();
-                        } else if (objProp.getName().equals("name")) {
-                            name = (String)objProp.getVal();
-                        } else if (objProp.getName().contains(instanceNameCustomField)) {
-                            if (objProp.getVal() != null)
-                                VMInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
-                        } else {
-                            assert (false);
-                        }
-                    }
-
-                    if (VMInternalCSName != null)
-                        name = VMInternalCSName;
-
-                    if (!isTemplate) {
-                        newStates.put(name, new HostVmStateReportEntry(convertPowerState(powerState), hyperHost.getHyperHostName()));
-                    }
-                }
-            }
-        }
-        return newStates;
-    }
-
-    private HashMap<String, PowerState> getVmStates() throws Exception {
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-
-        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
-        if (key == 0) {
-            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
-        }
-        String instanceNameCustomField = "value[" + key + "]";
-
-        // CLOUD_VM_INTERNAL_NAME stores the internal CS generated vm name. This was earlier stored in name. Now, name can be either the hostname or
-        // the internal CS name, but the custom field CLOUD_VM_INTERNAL_NAME always stores the internal CS name.
-        ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "runtime.powerState", "config.template", instanceNameCustomField});
-
-        HashMap<String, PowerState> newStates = new HashMap<String, PowerState>();
-        if (ocs != null && ocs.length > 0) {
-            for (ObjectContent oc : ocs) {
-                List<DynamicProperty> objProps = oc.getPropSet();
-                if (objProps != null) {
-
-                    boolean isTemplate = false;
-                    String name = null;
-                    String VMInternalCSName = null;
-                    VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
-                    for (DynamicProperty objProp : objProps) {
-                        if (objProp.getName().equals("config.template")) {
-                            if (objProp.getVal().toString().equalsIgnoreCase("true")) {
-                                isTemplate = true;
-                            }
-                        } else if (objProp.getName().equals("runtime.powerState")) {
-                            powerState = (VirtualMachinePowerState)objProp.getVal();
-                        } else if (objProp.getName().equals("name")) {
-                            name = (String)objProp.getVal();
-                        } else if (objProp.getName().contains(instanceNameCustomField)) {
-                            if (objProp.getVal() != null)
-                                VMInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
-                        } else {
-                            assert (false);
-                        }
-                    }
-
-                    if (VMInternalCSName != null)
-                        name = VMInternalCSName;
-
-                    if (!isTemplate) {
-                        newStates.put(name, convertPowerState(powerState));
-                    }
-                }
-            }
-        }
-        return newStates;
-    }
-
-    private HashMap<String, VmStatsEntry> getVmStats(List<String> vmNames) throws Exception {
-        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
-        ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager();
-        VimPortType service = getServiceContext().getService();
-        PerfCounterInfo rxPerfCounterInfo = null;
-        PerfCounterInfo txPerfCounterInfo = null;
-
-        List<PerfCounterInfo> cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter");
-        for (PerfCounterInfo info : cInfo) {
-            if ("net".equalsIgnoreCase(info.getGroupInfo().getKey())) {
-                if ("transmitted".equalsIgnoreCase(info.getNameInfo().getKey())) {
-                    txPerfCounterInfo = info;
-                }
-                if ("received".equalsIgnoreCase(info.getNameInfo().getKey())) {
-                    rxPerfCounterInfo = info;
-                }
-            }
-        }
-
-        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
-        if (key == 0) {
-            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
-        }
-        String instanceNameCustomField = "value[" + key + "]";
-
-        final String numCpuStr = "summary.config.numCpu";
-        final String cpuUseStr = "summary.quickStats.overallCpuUsage";
-        final String guestMemUseStr = "summary.quickStats.guestMemoryUsage";
-        final String memLimitStr = "resourceConfig.memoryAllocation.limit";
-        final String memMbStr = "config.hardware.memoryMB";
-        final String allocatedCpuStr = "summary.runtime.maxCpuUsage";
-
-        ObjectContent[] ocs =
-                hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr ,guestMemUseStr ,memLimitStr ,memMbStr,allocatedCpuStr ,instanceNameCustomField});
-
-        if (ocs != null && ocs.length > 0) {
-            for (ObjectContent oc : ocs) {
-                List<DynamicProperty> objProps = oc.getPropSet();
-                if (objProps != null) {
-                    String name = null;
-                    String numberCPUs = null;
-                    double maxCpuUsage = 0;
-                    String memlimit = null;
-                    String memkb = null;
-                    String guestMemusage = null;
-                    String vmNameOnVcenter = null;
-                    String vmInternalCSName = null;
-                    double allocatedCpu = 0;
-                    for (DynamicProperty objProp : objProps) {
-                        if (objProp.getName().equals("name")) {
-                            vmNameOnVcenter = objProp.getVal().toString();
-                        } else if (objProp.getName().contains(instanceNameCustomField)) {
-                            if (objProp.getVal() != null)
-                                vmInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
-                        } else if (objProp.getName().equals(guestMemusage)) {
-                            guestMemusage = objProp.getVal().toString();
-                        } else if (objProp.getName().equals(numCpuStr)) {
-                            numberCPUs = objProp.getVal().toString();
-                        } else if (objProp.getName().equals(cpuUseStr)) {
-                            maxCpuUsage = NumberUtils.toDouble(objProp.getVal().toString());
-                        } else if (objProp.getName().equals(memLimitStr)) {
-                            memlimit = objProp.getVal().toString();
-                        } else if (objProp.getName().equals(memMbStr)) {
-                            memkb = objProp.getVal().toString();
-                        } else if (objProp.getName().equals(allocatedCpuStr)){
-                            allocatedCpu  = NumberUtils.toDouble(objProp.getVal().toString());
-                        }
-                    }
-
-                    maxCpuUsage = (maxCpuUsage/allocatedCpu)*100;
-                    new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
-                    if (vmInternalCSName != null) {
-                        name = vmInternalCSName;
-                    } else {
-                        name = vmNameOnVcenter;
-                    }
-
-                    if (!vmNames.contains(name)) {
-                        continue;
-                    }
-
-                    ManagedObjectReference vmMor = hyperHost.findVmOnHyperHost(name).getMor();
-                    assert (vmMor != null);
-
-                    ArrayList<PerfMetricId> vmNetworkMetrics = new ArrayList<PerfMetricId>();
-                    // get all the metrics from the available sample period
-                    List<PerfMetricId> perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMor, null, null, null);
-                    if (perfMetrics != null) {
-                        for (int index = 0; index < perfMetrics.size(); ++index) {
-                            if (((rxPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rxPerfCounterInfo.getKey()))
-                                    || ((txPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == txPerfCounterInfo.getKey()))) {
-                                vmNetworkMetrics.add(perfMetrics.get(index));
-                            }
-                        }
-                    }
-
-                    double networkReadKBs = 0;
-                    double networkWriteKBs = 0;
-                    long sampleDuration = 0;
-
-                    if (vmNetworkMetrics.size() != 0) {
-                        PerfQuerySpec qSpec = new PerfQuerySpec();
-                        qSpec.setEntity(vmMor);
-                        PerfMetricId[] availableMetricIds = vmNetworkMetrics.toArray(new PerfMetricId[0]);
-                        qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds));
-                        List<PerfQuerySpec> qSpecs = new ArrayList<PerfQuerySpec>();
-                        qSpecs.add(qSpec);
-                        List<PerfEntityMetricBase> values = service.queryPerf(perfMgr, qSpecs);
-
-                        for (int i = 0; i < values.size(); ++i) {
-                            List<PerfSampleInfo> infos = ((PerfEntityMetric)values.get(i)).getSampleInfo();
-                            if (infos != null && infos.size() > 0) {
-                                int endMs = infos.get(infos.size() - 1).getTimestamp().getSecond() * 1000 + infos.get(infos.size() - 1).getTimestamp().getMillisecond();
-                                int beginMs = infos.get(0).getTimestamp().getSecond() * 1000 + infos.get(0).getTimestamp().getMillisecond();
-                                sampleDuration = (endMs - beginMs) / 1000;
-                                List<PerfMetricSeries> vals = ((PerfEntityMetric)values.get(i)).getValue();
-                                for (int vi = 0; ((vals != null) && (vi < vals.size())); ++vi) {
-                                    if (vals.get(vi) instanceof PerfMetricIntSeries) {
-                                        PerfMetricIntSeries val = (PerfMetricIntSeries)vals.get(vi);
-                                        List<Long> perfValues = val.getValue();
-                                        Long sumRate = 0L;
-                                        for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo
-                                            sumRate += perfValues.get(j);
-                                        }
-                                        Long averageRate = sumRate / infos.size();
-                                        if (vals.get(vi).getId().getCounterId() == rxPerfCounterInfo.getKey()) {
-                                            networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration
-                                        }
-                                        if (vals.get(vi).getId().getCounterId() == txPerfCounterInfo.getKey()) {
-                                            networkWriteKBs = sampleDuration * averageRate;//get the average TX rate multiplied by sampled duration
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    vmResponseMap.put(name, new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024,
-                            maxCpuUsage, networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm"));
-
-                }
-            }
-        }
-        return vmResponseMap;
-    }
-
-    protected String networkUsage(final String privateIpAddress, final String option, final String ethName) {
-        String args = null;
-        if (option.equals("get")) {
-            args = "-g";
-        } else if (option.equals("create")) {
-            args = "-c";
-        } else if (option.equals("reset")) {
-            args = "-r";
-        } else if (option.equals("addVif")) {
-            args = "-a";
-            args += ethName;
-        } else if (option.equals("deleteVif")) {
-            args = "-d";
-            args += ethName;
-        }
-
-        ExecutionResult result = executeInVR(privateIpAddress, "netusage.sh", args);
-
-        if (!result.isSuccess()) {
-            return null;
-        }
-
-        return result.getDetails();
-    }
-
-    private long[] getNetworkStats(String privateIP) {
-        String result = networkUsage(privateIP, "get", null);
-        long[] stats = new long[2];
-        if (result != null) {
-            try {
-                String[] splitResult = result.split(":");
-                int i = 0;
-                while (i < splitResult.length - 1) {
-                    stats[0] += Long.parseLong(splitResult[i++]);
-                    stats[1] += Long.parseLong(splitResult[i++]);
-                }
-            } catch (Throwable e) {
-                s_logger.warn("Unable to parse return from script return of network usage command: " + e.toString(), e);
-            }
-        }
-        return stats;
-    }
-
-    protected String connect(final String vmName, final String ipAddress, final int port) {
-        long startTick = System.currentTimeMillis();
-
-        // wait until we have at least been waiting for _ops_timeout time or
-        // at least have tried _retry times, this is to coordinate with system
-        // VM patching/rebooting time that may need
-        int retry = _retry;
-        while (System.currentTimeMillis() - startTick <= _opsTimeout || --retry > 0) {
-            s_logger.info("Trying to connect to " + ipAddress);
-            try (SocketChannel sch = SocketChannel.open();) {
-                sch.configureBlocking(true);
-                sch.socket().setSoTimeout(5000);
-
-                InetSocketAddress addr = new InetSocketAddress(ipAddress, port);
-                sch.connect(addr);
-                return null;
-            } catch (IOException e) {
-                s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString());
-                if (e instanceof ConnectException) {
-                    // if connection is refused because of VM is being started,
-                    // we give it more sleep time
-                    // to avoid running out of retry quota too quickly
-                    try {
-                        Thread.sleep(5000);
-                    } catch (InterruptedException ex) {
-                        s_logger.debug("[ignored] interupted while waiting to retry connect after failure.", e);
-                    }
-                }
-            }
-
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ex) {
-                s_logger.debug("[ignored] interupted while waiting to retry connect.");
-            }
-        }
-
-        s_logger.info("Unable to logon to " + ipAddress);
-
-        return "Unable to connect";
-    }
-
-    protected String connect(final String vmname, final String ipAddress) {
-        return connect(vmname, ipAddress, 3922);
-    }
-
-    public static PowerState getVmState(VirtualMachineMO vmMo) throws Exception {
-        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
-        return convertPowerState(runtimeInfo.getPowerState());
-    }
-
-    private static PowerState convertPowerState(VirtualMachinePowerState powerState) {
-        return s_powerStatesTable.get(powerState);
-    }
-
-    public static PowerState getVmPowerState(VirtualMachineMO vmMo) throws Exception {
-        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
-        return convertPowerState(runtimeInfo.getPowerState());
-    }
-
-    private static HostStatsEntry getHyperHostStats(VmwareHypervisorHost hyperHost) throws Exception {
-        ComputeResourceSummary hardwareSummary = hyperHost.getHyperHostHardwareSummary();
-        if (hardwareSummary == null)
-            return null;
-
-        HostStatsEntry entry = new HostStatsEntry();
-
-        entry.setEntityType("host");
-        double cpuUtilization = ((double)(hardwareSummary.getTotalCpu() - hardwareSummary.getEffectiveCpu()) / (double)hardwareSummary.getTotalCpu() * 100);
-        entry.setCpuUtilization(cpuUtilization);
-        entry.setTotalMemoryKBs(hardwareSummary.getTotalMemory() / 1024);
-        entry.setFreeMemoryKBs(hardwareSummary.getEffectiveMemory() * 1024);
-
-        return entry;
-    }
-
-    private static String getRouterSshControlIp(NetworkElementCommand cmd) {
-        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        String routerGuestIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
-        String zoneNetworkType = cmd.getAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE);
-
-        if (routerGuestIp != null && zoneNetworkType != null && NetworkType.valueOf(zoneNetworkType) == NetworkType.Basic) {
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("In Basic zone mode, use router's guest IP for SSH control. guest IP : " + routerGuestIp);
-
-            return routerGuestIp;
-        }
-
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
-        return routerIp;
-    }
-
-    @Override
-    public void setAgentControl(IAgentControl agentControl) {
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        try {
-            _name = name;
-
-            _url = (String)params.get("url");
-            _username = (String)params.get("username");
-            _password = (String)params.get("password");
-            _dcId = (String)params.get("zone");
-            _pod = (String)params.get("pod");
-            _cluster = (String)params.get("cluster");
-
-            _guid = (String)params.get("guid");
-            String[] tokens = _guid.split("@");
-            _vCenterAddress = tokens[1];
-            _morHyperHost = new ManagedObjectReference();
-            String[] hostTokens = tokens[0].split(":");
-            _morHyperHost.setType(hostTokens[0]);
-            _morHyperHost.setValue(hostTokens[1]);
-
-            _guestTrafficInfo = (VmwareTrafficLabel)params.get("guestTrafficInfo");
-            _publicTrafficInfo = (VmwareTrafficLabel)params.get("publicTrafficInfo");
-            VmwareContext context = getServiceContext();
-            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-            if (mgr == null) {
-                throw new ConfigurationException("Invalid vmwareContext:  vmwareMgr stock object is not set or cleared.");
-            }
-            mgr.setupResourceStartupParams(params);
-
-            CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
-            cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
-            if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch
-                    || _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
-                cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
-            }
-            cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
-            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
-            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
-            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
-            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
-            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
-
-            VmwareHypervisorHost hostMo = this.getHyperHost(context);
-            _hostName = hostMo.getHyperHostName();
-
-            if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch
-                    || _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) {
-                _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware);
-                _vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster));
-            }
-
-            if (_privateNetworkVSwitchName == null) {
-                _privateNetworkVSwitchName = (String)params.get("private.network.vswitch.name");
-            }
-
-            String value = (String)params.get("vmware.recycle.hung.wokervm");
-            if (value != null && value.equalsIgnoreCase("true"))
-                _recycleHungWorker = true;
-
-            value = (String)params.get("vmware.root.disk.controller");
-            if (value != null && value.equalsIgnoreCase("scsi"))
-                _rootDiskController = DiskControllerType.scsi;
-            else if (value != null && value.equalsIgnoreCase("ide"))
-                _rootDiskController = DiskControllerType.ide;
-            else
-                _rootDiskController = DiskControllerType.osdefault;
-
-            Integer intObj = (Integer)params.get("ports.per.dvportgroup");
-            if (intObj != null)
-                _portsPerDvPortGroup = intObj.intValue();
-
-            s_logger.info("VmwareResource network configuration info." + " private traffic over vSwitch: " + _privateNetworkVSwitchName + ", public traffic over "
-                    + _publicTrafficInfo.getVirtualSwitchType() + " : " + _publicTrafficInfo.getVirtualSwitchName() + ", guest traffic over "
-                    + _guestTrafficInfo.getVirtualSwitchType() + " : " + _guestTrafficInfo.getVirtualSwitchName());
-
-            Boolean boolObj = (Boolean)params.get("vmware.create.full.clone");
-            if (boolObj != null && boolObj.booleanValue()) {
-                _fullCloneFlag = true;
-            } else {
-                _fullCloneFlag = false;
-            }
-
-            boolObj = (Boolean)params.get("vm.instancename.flag");
-            if (boolObj != null && boolObj.booleanValue()) {
-                _instanceNameFlag = true;
-            } else {
-                _instanceNameFlag = false;
-            }
-
-            value = (String)params.get("scripts.timeout");
-            int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
-
-            storageNfsVersion = NfsSecondaryStorageResource.retrieveNfsVersionFromParams(params);
-            _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null,
-                    storageNfsVersion);
-            storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, storageNfsVersion);
-
-            _vrResource = new VirtualRoutingResource(this);
-            if (!_vrResource.configure(name, params)) {
-                throw new ConfigurationException("Unable to configure VirtualRoutingResource");
-            }
-
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Successfully configured VmwareResource.");
-            }
-            return true;
-        } catch (Exception e) {
-            s_logger.error("Unexpected Exception ", e);
-            throw new ConfigurationException("Failed to configure VmwareResource due to unexpect exception.");
-        } finally {
-            recycleServiceContext();
-        }
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    public VmwareContext getServiceContext() {
-        return getServiceContext(null);
-    }
-
-    public void invalidateServiceContext() {
-        invalidateServiceContext(null);
-    }
-
-    public VmwareHypervisorHost getHyperHost(VmwareContext context) {
-        return getHyperHost(context, null);
-    }
-
-    @Override
-    public VmwareContext getServiceContext(Command cmd) {
-        VmwareContext context = null;
-        if (s_serviceContext.get() != null) {
-            context = s_serviceContext.get();
-            String poolKey = VmwareContextPool.composePoolKey(_vCenterAddress, _username);
-            // Before re-using the thread local context, ensure it corresponds to the right vCenter API session and that it is valid to make calls.
-            if (context.getPoolKey().equals(poolKey)) {
-                if (context.validate()) {
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("ThreadLocal context is still valid, just reuse");
-                    }
-                    return context;
-                } else {
-                    s_logger.info("Validation of the context failed, dispose and use a new one");
-                    invalidateServiceContext(context);
-                }
-            } else {
-                // Exisitng ThreadLocal context corresponds to a different vCenter API session. Why has it not been recycled?
-                s_logger.warn("ThreadLocal VMware context: " + poolKey + " doesn't correspond to the right vCenter. Expected VMware context: " + context.getPoolKey());
-            }
-        }
-        try {
-            context = VmwareContextFactory.getContext(_vCenterAddress, _username, _password);
-            s_serviceContext.set(context);
-        } catch (Exception e) {
-            s_logger.error("Unable to connect to vSphere server: " + _vCenterAddress, e);
-            throw new CloudRuntimeException("Unable to connect to vSphere server: " + _vCenterAddress);
-        }
-        return context;
-    }
-
-    @Override
-    public void invalidateServiceContext(VmwareContext context) {
-        assert (s_serviceContext.get() == context);
-
-        s_serviceContext.set(null);
-        if (context != null)
-            context.close();
-    }
-
-    private static void recycleServiceContext() {
-        VmwareContext context = s_serviceContext.get();
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Reset threadlocal context to null");
-        }
-        s_serviceContext.set(null);
-
-        if (context != null) {
-            assert (context.getPool() != null);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Recycling threadlocal context to pool");
-            }
-            context.getPool().registerContext(context);
-        }
-    }
-
-    @Override
-    public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) {
-        if (_morHyperHost.getType().equalsIgnoreCase("HostSystem")) {
-            return new HostMO(context, _morHyperHost);
-        }
-        return new ClusterMO(context, _morHyperHost);
-    }
-
-    @Override
-    @DB
-    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
-        VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-        String vmName = mgr.composeWorkerName();
-
-        assert (cmd != null);
-        context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
-        // TODO: Fix this? long checkPointId = vmwareMgr.pushCleanupCheckpoint(this._guid, vmName);
-        // TODO: Fix this? cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
-        return vmName;
-    }
-
-    @Override
-    public void setName(String name) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setConfigParams(Map<String, Object> params) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getRunLevel() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(int level) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Answer execute(DestroyCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource DestroyCommand to evict template from storage pool: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = getServiceContext(null);
-            VmwareHypervisorHost hyperHost = getHyperHost(context, null);
-            VolumeTO vol = cmd.getVolume();
-
-            VirtualMachineMO vmMo = findVmOnDatacenter(context, hyperHost, vol);
-
-            if (vmMo != null && vmMo.isTemplate()) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Destroy template volume " + vol.getPath());
-                }
-                vmMo.destroy();
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Template volume " + vol.getPath() + " is not found, no need to delete.");
-                }
-            }
-            return new Answer(cmd, true, "Success");
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                invalidateServiceContext(null);
-            }
-
-            String msg = "DestroyCommand failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    /**
-     * Use data center to look for vm, instead of randomly picking up a cluster<br/>
-     * (in multiple cluster environments vm could not be found if wrong cluster was chosen)
-     * @param context vmware context
-     * @param hyperHost vmware hv host
-     * @param vol volume
-     * @return a virtualmachinemo if could be found on datacenter.
-     * @throws Exception if there is an error while finding vm
-     * @throws CloudRuntimeException if datacenter cannot be found
-     */
-    protected VirtualMachineMO findVmOnDatacenter(VmwareContext context, VmwareHypervisorHost hyperHost, VolumeTO vol) throws Exception {
-        DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-        if (dcMo.getMor() == null) {
-            String msg = "Unable to find VMware DC";
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        return dcMo.findVm(vol.getPath());
-    }
-
-    public String getAbsoluteVmdkFile(VirtualDisk disk) {
-        String vmdkAbsFile = null;
-        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
-        if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-            VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-            vmdkAbsFile = diskBackingInfo.getFileName();
-        }
-        return vmdkAbsFile;
-    }
-
-    protected File getSystemVmKeyFile() {
-        if (s_systemVmKeyFile == null) {
-            syncFetchSystemVmKeyFile();
-        }
-        return s_systemVmKeyFile;
-    }
-
-    private static void syncFetchSystemVmKeyFile() {
-        synchronized (s_syncLockObjectFetchKeyFile) {
-            if (s_systemVmKeyFile == null) {
-                s_systemVmKeyFile = fetchSystemVmKeyFile();
-            }
-        }
-    }
-
-    private static File fetchSystemVmKeyFile() {
-        String filePath = s_relativePathSystemVmKeyFileInstallDir;
-        s_logger.debug("Looking for file [" + filePath + "] in the classpath.");
-        URL url = Script.class.getClassLoader().getResource(filePath);
-        File keyFile = null;
-        if (url != null) {
-            keyFile = new File(url.getPath());
-        }
-        if (keyFile == null || !keyFile.exists()) {
-            filePath = s_defaultPathSystemVmKeyFile;
-            keyFile = new File(filePath);
-            s_logger.debug("Looking for file [" + filePath + "] in the classpath.");
-        }
-        if (!keyFile.exists()) {
-            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
-        }
-        return keyFile;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
deleted file mode 100644
index 0cea62f..0000000
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ /dev/null
@@ -1,3435 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.resource;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.vmware.vim25.DatastoreHostMount;
-import com.vmware.vim25.HostHostBusAdapter;
-import com.vmware.vim25.HostInternetScsiHba;
-import com.vmware.vim25.HostInternetScsiHbaAuthenticationProperties;
-import com.vmware.vim25.HostInternetScsiHbaSendTarget;
-import com.vmware.vim25.HostInternetScsiHbaStaticTarget;
-import com.vmware.vim25.HostInternetScsiTargetTransport;
-import com.vmware.vim25.HostResignatureRescanResult;
-import com.vmware.vim25.HostUnresolvedVmfsResignatureSpec;
-import com.vmware.vim25.HostScsiDisk;
-import com.vmware.vim25.HostScsiTopology;
-import com.vmware.vim25.HostScsiTopologyInterface;
-import com.vmware.vim25.HostScsiTopologyLun;
-import com.vmware.vim25.HostScsiTopologyTarget;
-import com.vmware.vim25.HostUnresolvedVmfsExtent;
-import com.vmware.vim25.HostUnresolvedVmfsVolume;
-import com.vmware.vim25.InvalidStateFaultMsg;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.VirtualDeviceBackingInfo;
-import com.vmware.vim25.VirtualDeviceConfigSpec;
-import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
-import com.vmware.vim25.VirtualMachineConfigSpec;
-import com.vmware.vim25.VirtualDisk;
-import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
-import com.vmware.vim25.VmfsDatastoreExpandSpec;
-import com.vmware.vim25.VmfsDatastoreOption;
-
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.command.ForgetObjectCmd;
-import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
-import org.apache.cloudstack.storage.command.ResignatureAnswer;
-import org.apache.cloudstack.storage.command.ResignatureCommand;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.hypervisor.vmware.manager.VmwareHostService;
-import com.cloud.hypervisor.vmware.manager.VmwareManager;
-import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
-import com.cloud.hypervisor.vmware.mo.ClusterMO;
-import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
-import com.cloud.hypervisor.vmware.mo.DatacenterMO;
-import com.cloud.hypervisor.vmware.mo.DatastoreFile;
-import com.cloud.hypervisor.vmware.mo.DatastoreMO;
-import com.cloud.hypervisor.vmware.mo.DiskControllerType;
-import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
-import com.cloud.hypervisor.vmware.mo.HostMO;
-import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
-import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
-import com.cloud.hypervisor.vmware.mo.NetworkDetails;
-import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
-import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
-import com.cloud.hypervisor.vmware.resource.VmwareResource;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.Volume;
-import com.cloud.storage.template.OVAProcessor;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.cloud.vm.VmDetailConstants;
-
-public class VmwareStorageProcessor implements StorageProcessor {
-
-    public enum VmwareStorageProcessorConfigurableFields {
-        NFS_VERSION("nfsVersion"), FULL_CLONE_FLAG("fullCloneFlag");
-
-        private String name;
-
-        VmwareStorageProcessorConfigurableFields(String name){
-            this.name = name;
-        }
-
-        public String getName() {
-            return name;
-        }
-    }
-
-    private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
-    private static final int DEFAULT_NFS_PORT = 2049;
-
-    private final VmwareHostService hostService;
-    private boolean _fullCloneFlag;
-    private final VmwareStorageMount mountService;
-    private final VmwareResource resource;
-    private final Integer _timeout;
-    protected Integer _shutdownWaitMs;
-    private final Gson _gson;
-    private final StorageLayer _storage = new JavaStorageLayer();
-    private Integer _nfsVersion;
-    private static final Random RANDOM = new Random(System.nanoTime());
-
-    public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, Integer timeout, VmwareResource resource,
-                                  Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource, Integer nfsVersion) {
-        this.hostService = hostService;
-        _fullCloneFlag = fullCloneFlag;
-        this.mountService = mountService;
-        _timeout = timeout;
-        this.resource = resource;
-        _shutdownWaitMs = shutdownWaitMs;
-        _gson = GsonHelper.getGsonLogger();
-        _nfsVersion = nfsVersion;
-    }
-
-    @Override
-    public SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand cmd) {
-        s_logger.info("'SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand)' not currently used for VmwareStorageProcessor");
-
-        return new SnapshotAndCopyAnswer();
-    }
-
-    @Override
-    public ResignatureAnswer resignature(ResignatureCommand cmd) {
-        final Map<String, String> details = cmd.getDetails();
-
-        String scsiNaaDeviceId = details.get(DiskTO.SCSI_NAA_DEVICE_ID);
-
-        if (scsiNaaDeviceId == null || scsiNaaDeviceId.trim().length() == 0) {
-            throw new CloudRuntimeException("The 'scsiNaaDeviceId' needs to be specified when resignaturing a VMware datastore.");
-        }
-
-        final String iScsiName = details.get(DiskTO.IQN);
-        final String datastoreName = getMaximumDatastoreName(VmwareResource.getDatastoreName(iScsiName));
-
-        String vmdk = null;
-
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-
-            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-            ClusterMO clusterMO = new ClusterMO(context, morCluster);
-
-            List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
-
-            // add iSCSI connection to host
-
-            final String storageHost = details.get(DiskTO.STORAGE_HOST);
-            final int storagePortNumber = Integer.parseInt(details.get(DiskTO.STORAGE_PORT));
-            final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
-            final String chapTargetUsername = details.get(DiskTO.CHAP_TARGET_USERNAME);
-            final String chapTargetSecret = details.get(DiskTO.CHAP_TARGET_SECRET);
-
-            HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
-            List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-            if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-                List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
-                        chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-
-                addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
-            }
-
-            rescanAllHosts(context, lstHosts, true, true);
-
-            // perform resignature operation
-
-            HostMO hostMO = new HostMO(context, lstHosts.get(0).first());
-
-            HostDatastoreSystemMO hostDatastoreSystem = hostMO.getHostDatastoreSystemMO();
-
-            List<HostUnresolvedVmfsVolume> hostUnresolvedVmfsVolumes = hostDatastoreSystem.queryUnresolvedVmfsVolumes();
-
-            if (hostUnresolvedVmfsVolumes == null || hostUnresolvedVmfsVolumes.size() == 0) {
-                throw new CloudRuntimeException("Unable to locate any snapshot datastores");
-            }
-
-            boolean foundExtent = false;
-
-            for (HostUnresolvedVmfsVolume hostUnresolvedVmfsVolume : hostUnresolvedVmfsVolumes) {
-                List<HostUnresolvedVmfsExtent> extents = hostUnresolvedVmfsVolume.getExtent();
-                List<HostUnresolvedVmfsExtent> matchingExtents = getExtentsMatching(extents, scsiNaaDeviceId);
-
-                if (matchingExtents.size() >= 1) {
-                    String extentDevicePath = matchingExtents.get(0).getDevicePath();
-                    HostResignatureRescanResult hostResignatureRescanResult = resignatureDatastore(hostDatastoreSystem, extentDevicePath);
-
-                    if (hostResignatureRescanResult == null) {
-                        throw new CloudRuntimeException("'hostResignatureRescanResult' should not be 'null'.");
-                    }
-
-                    ManagedObjectReference morDs = hostResignatureRescanResult.getResult();
-
-                    if (morDs == null) {
-                        throw new CloudRuntimeException("'morDs' should not be 'null'.");
-                    }
-
-                    DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
-
-                    boolean isOnlyForTemplate = Boolean.parseBoolean(details.get(DiskTO.TEMPLATE_RESIGN));
-
-                    // If this is only for a template, all we really want to do is resignature the datastore (done at this point),
-                    // then rename the datastore.
-                    if (isOnlyForTemplate) {
-                        vmdk = details.get(DiskTO.VMDK);
-                    }
-                    else {
-                        vmdk = cleanUpDatastore(cmd, hostDatastoreSystem, datastoreMO, details);
-                    }
-
-                    if (renameDatastore(context, morDs, datastoreName, lstHosts)) {
-                        foundExtent = true;
-
-                        break;
-                    }
-                }
-            }
-
-            removeVmfsDatastore(cmd, hyperHost, datastoreName, storageHost, storagePortNumber, trimIqn(iScsiName), lstHosts);
-
-            if (!foundExtent) {
-                throw new CloudRuntimeException("Unable to locate the applicable extent");
-            }
-
-            final ResignatureAnswer answer = new ResignatureAnswer();
-
-            final long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
-
-            answer.setSize(volumeSize);
-
-            answer.setPath("[" + datastoreName + "] " + vmdk);
-
-            answer.setFormat(ImageFormat.OVA);
-
-            return answer;
-        }
-        catch (Exception ex) {
-            s_logger.debug(ex.getMessage());
-
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-    }
-
-    private List<HostUnresolvedVmfsExtent> getExtentsMatching(List<HostUnresolvedVmfsExtent> extents, String naa) {
-        List<HostUnresolvedVmfsExtent> matchingExtents = new ArrayList<>();
-
-        if (extents != null) {
-            for (HostUnresolvedVmfsExtent extent : extents) {
-                s_logger.debug("extent devicePath=" + extent.getDevicePath() + ", ordinal=" + extent.getOrdinal()
-                        + ", reason=" + extent.getReason() + ", isHeadExtent=" + extent.isIsHeadExtent());
-
-                String extentDevicePath = extent.getDevicePath();
-
-                if (extentDevicePath.contains(naa)) {
-                    matchingExtents.add(extent);
-                }
-            }
-        }
-
-        return matchingExtents;
-    }
-
-    private class HostUnresolvedVmfsResignatureSpecCustom extends HostUnresolvedVmfsResignatureSpec {
-        private HostUnresolvedVmfsResignatureSpecCustom(String extentDevicePath) {
-            this.extentDevicePath = new ArrayList<>(1);
-
-            this.extentDevicePath.add(extentDevicePath);
-        }
-    }
-
-    private HostResignatureRescanResult resignatureDatastore(HostDatastoreSystemMO hostDatastoreSystemMO, String extentDevicePath) throws Exception {
-        HostUnresolvedVmfsResignatureSpecCustom resignatureSpec = new HostUnresolvedVmfsResignatureSpecCustom(extentDevicePath);
-
-        return hostDatastoreSystemMO.resignatureUnresolvedVmfsVolume(resignatureSpec);
-    }
-
-    private boolean renameDatastore(VmwareContext context, ManagedObjectReference morDs, String newName, List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
-        if (morDs != null) {
-            DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
-
-            datastoreMO.renameDatastore(newName);
-
-            waitForAllHostsToMountDatastore(lstHosts, datastoreMO);
-
-            return true;
-        }
-
-        s_logger.debug("Unable to locate datastore to rename");
-
-        return false;
-    }
-
-    private String getMaximumDatastoreName(String datastoreName) {
-        final int maxDatastoreNameLength = 80;
-
-        return datastoreName.length() > maxDatastoreNameLength ? datastoreName.substring(0, maxDatastoreNameLength) : datastoreName;
-    }
-
-    /**
-     * 1) Possibly expand the datastore.
-     * 2) Possibly consolidate all relevant VMDK files into one VMDK file.
-     * 3) Possibly move the VMDK file to the root folder (may already be there).
-     * 4) If the VMDK file wasn't already in the root folder, then delete the folder the VMDK file was in.
-     * 5) Possibly rename the VMDK file (this will lead to there being a delta file with the new name and the
-     *    original file with the original name).
-     *
-     * Note: If the underlying VMDK file was for a root disk, the 'vmdk' parameter's value might look, for example,
-     *  like "i-2-32-VM/ROOT-32.vmdk".
-     *
-     * Note: If the underlying VMDK file was for a data disk, the 'vmdk' parameter's value might look, for example,
-     *  like "-iqn.2010-01.com.solidfire:4nhe.data-32.79-0.vmdk".
-     *
-     * Returns the (potentially new) name of the VMDK file.
-     */
-    private String cleanUpDatastore(Command cmd, HostDatastoreSystemMO hostDatastoreSystem, DatastoreMO dsMo, Map<String, String> details) throws Exception {
-        boolean expandDatastore = Boolean.parseBoolean(details.get(DiskTO.EXPAND_DATASTORE));
-
-        // A volume on the storage system holding a template uses a minimum hypervisor snapshot reserve value.
-        // When this volume is cloned to a new volume, the new volume can be expanded (to take a new hypervisor snapshot reserve value
-        // into consideration). If expandDatastore is true, we want to expand the datastore in the new volume to the size of the cloned volume.
-        // It's possible that expandDatastore might be true and there isn't any extra space in the cloned volume (if the hypervisor snapshot
-        // reserve value in use is set to the minimum for the cloned volume), but that's fine.
-        if (expandDatastore) {
-            expandDatastore(hostDatastoreSystem, dsMo);
-        }
-
-        String vmdk = details.get(DiskTO.VMDK);
-        String fullVmdkPath = new DatastoreFile(dsMo.getName(), vmdk).getPath();
-
-        VmwareContext context = hostService.getServiceContext(null);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-
-        DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-
-        String vmName = getVmName(vmdk);
-
-        // If vmName is not null, then move all VMDK files out of this folder to the root folder and then delete the folder named vmName.
-        if (vmName != null) {
-            String workerVmName = hostService.getWorkerName(context, cmd, 0);
-
-            VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
-
-            if (vmMo == null) {
-                throw new Exception("Unable to create a worker VM for volume creation");
-            }
-
-            vmMo.attachDisk(new String[] { fullVmdkPath }, dsMo.getMor());
-
-            List<String> backingFiles = new ArrayList<>(1);
-
-            List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
-
-            VirtualDisk virtualDisk = virtualDisks.get(0);
-
-            VirtualDeviceBackingInfo virtualDeviceBackingInfo = virtualDisk.getBacking();
-
-            while (virtualDeviceBackingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDeviceBackingInfo;
-
-                backingFiles.add(backingInfo.getFileName());
-
-                virtualDeviceBackingInfo = backingInfo.getParent();
-            }
-
-            vmMo.detachAllDisks();
-            vmMo.destroy();
-
-            VmwareStorageLayoutHelper.moveVolumeToRootFolder(dcMo, backingFiles);
-
-            vmdk = new DatastoreFile(vmdk).getFileName();
-
-            // Delete the folder the VMDK file was in.
-
-            DatastoreFile folderToDelete = new DatastoreFile(dsMo.getName(), vmName);
-
-            dsMo.deleteFolder(folderToDelete.getPath(), dcMo.getMor());
-        }
-
-        return vmdk;
-    }
-
-    /**
-     * Example input for the 'vmdk' parameter:
-     *  i-2-32-VM/ROOT-32.vmdk
-     *  -iqn.2010-01.com.solidfire:4nhe.data-32.79-0.vmdk
-     */
-    private String getVmName(String vmdk) {
-        int indexOf = vmdk.indexOf("/");
-
-        if (indexOf == -1) {
-            return null;
-        }
-
-        return vmdk.substring(0, indexOf).trim();
-    }
-
-    public void expandDatastore(HostDatastoreSystemMO hostDatastoreSystem, DatastoreMO datastoreMO) throws Exception {
-        List<VmfsDatastoreOption> vmfsDatastoreOptions = hostDatastoreSystem.queryVmfsDatastoreExpandOptions(datastoreMO);
-
-        if (vmfsDatastoreOptions != null && vmfsDatastoreOptions.size() > 0) {
-            VmfsDatastoreExpandSpec vmfsDatastoreExpandSpec = (VmfsDatastoreExpandSpec)vmfsDatastoreOptions.get(0).getSpec();
-
-            hostDatastoreSystem.expandVmfsDatastore(datastoreMO, vmfsDatastoreExpandSpec);
-        }
-    }
-
-    private String getOVFFilePath(String srcOVAFileName) {
-        File file = new File(srcOVAFileName);
-        assert (_storage != null);
-        String[] files = _storage.listFiles(file.getParent());
-        if (files != null) {
-            for (String fileName : files) {
-                if (fileName.toLowerCase().endsWith(".ovf")) {
-                    File ovfFile = new File(fileName);
-                    return file.getParent() + File.separator + ovfFile.getName();
-                }
-            }
-        }
-        return null;
-    }
-
-    private Pair<VirtualMachineMO, Long> copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
-                                                                            String templatePathAtSecondaryStorage, String templateName, String templateUuid,
-                                                                            boolean createSnapshot, Integer nfsVersion) throws Exception {
-        s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
-                templatePathAtSecondaryStorage + ", templateName: " + templateName);
-
-        String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
-        s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
-
-        String srcOVAFileName =
-                VmwareStorageLayoutHelper.getTemplateOnSecStorageFilePath(secondaryMountPoint, templatePathAtSecondaryStorage, templateName,
-                        ImageFormat.OVA.getFileExtension());
-
-        String srcFileName = getOVFFilePath(srcOVAFileName);
-        if (srcFileName == null) {
-            Script command = new Script("tar", 0, s_logger);
-            command.add("--no-same-owner");
-            command.add("-xf", srcOVAFileName);
-            command.setWorkDir(secondaryMountPoint + "/" + templatePathAtSecondaryStorage);
-            s_logger.info("Executing command: " + command.toString());
-            String result = command.execute();
-            if (result != null) {
-                String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-        }
-
-        srcFileName = getOVFFilePath(srcOVAFileName);
-        if (srcFileName == null) {
-            String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
-            s_logger.error(msg);
-            throw new Exception(msg);
-        }
-
-        String vmName = templateUuid;
-        hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin");
-
-        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-        if (vmMo == null) {
-            String msg =
-                    "Failed to import OVA template. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage +
-                            ", templateName: " + templateName + ", templateUuid: " + templateUuid;
-            s_logger.error(msg);
-            throw new Exception(msg);
-        }
-
-        OVAProcessor processor = new OVAProcessor();
-        Map<String, Object> params = new HashMap<>();
-        params.put(StorageLayer.InstanceConfigKey, _storage);
-        processor.configure("OVA Processor", params);
-        long virtualSize = processor.getTemplateVirtualSize(secondaryMountPoint + "/" + templatePathAtSecondaryStorage, templateName);
-
-        if (createSnapshot) {
-            if (vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
-                // the same template may be deployed with multiple copies at per-datastore per-host basis,
-                // save the original template name from CloudStack DB as the UUID to associate them.
-                vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateName);
-                vmMo.markAsTemplate();
-            } else {
-                vmMo.destroy();
-
-                String msg = "Unable to create base snapshot for template, templateName: " + templateName + ", templateUuid: " + templateUuid;
-
-                s_logger.error(msg);
-
-                throw new Exception(msg);
-            }
-        }
-
-        return new Pair<>(vmMo, virtualSize);
-    }
-
-    @Override
-    public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        TemplateObjectTO template = (TemplateObjectTO)srcData;
-        DataStoreTO srcStore = srcData.getDataStore();
-
-        if (!(srcStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        NfsTO nfsImageStore = (NfsTO)srcStore;
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO destStore = destData.getDataStore();
-        DataStoreTO primaryStore = destStore;
-
-        String secondaryStorageUrl = nfsImageStore.getUrl();
-
-        assert secondaryStorageUrl != null;
-
-        boolean managed = false;
-        String storageHost = null;
-        int storagePort = Integer.MIN_VALUE;
-        String managedStoragePoolName = null;
-        String managedStoragePoolRootVolumeName = null;
-        String chapInitiatorUsername = null;
-        String chapInitiatorSecret = null;
-        String chapTargetUsername = null;
-        String chapTargetSecret = null;
-
-        if (destStore instanceof PrimaryDataStoreTO) {
-            PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destStore;
-
-            Map<String, String> details = destPrimaryDataStoreTo.getDetails();
-
-            if (details != null) {
-                managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
-
-                if (managed) {
-                    storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
-
-                    try {
-                        storagePort = Integer.parseInt(details.get(PrimaryDataStoreTO.STORAGE_PORT));
-                    }
-                    catch (Exception ex) {
-                        storagePort = 3260;
-                    }
-
-                    managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
-                    managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
-                    chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
-                    chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
-                    chapTargetUsername = details.get(PrimaryDataStoreTO.CHAP_TARGET_USERNAME);
-                    chapTargetSecret = details.get(PrimaryDataStoreTO.CHAP_TARGET_SECRET);
-                }
-            }
-        }
-
-        String templateUrl = secondaryStorageUrl + "/" + srcData.getPath();
-        Pair<String, String> templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-
-        if (context == null) {
-            return new CopyCmdAnswer("Failed to create a VMware context, check the management server logs or the SSVM log for details");
-        }
-
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-        DatastoreMO dsMo = null;
-
-        try {
-            String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
-            String templateUuidName = deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
-            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-            VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
-            Pair<VirtualMachineMO, Long> vmInfo = null;
-
-            if (templateMo == null) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
-                }
-
-                final ManagedObjectReference morDs;
-
-                if (managed) {
-                    morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort,
-                                chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-                }
-                else {
-                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
-                }
-
-                assert (morDs != null);
-
-                dsMo = new DatastoreMO(context, morDs);
-
-                if (managed) {
-                    vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
-                            managedStoragePoolRootVolumeName, false, _nfsVersion);
-
-                    VirtualMachineMO vmMo = vmInfo.first();
-                    vmMo.unregisterVm();
-
-                    String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName,
-                            managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false);
-                    String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null,
-                            managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
-
-                    dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
-                    dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
-
-                    String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
-                    dsMo.deleteFolder(folderToDelete, dcMo.getMor());
-                }
-                else {
-                    vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
-                            templateUuidName, true, _nfsVersion);
-                }
-            } else {
-                s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
-            }
-
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            if (managed) {
-                if (dsMo != null) {
-                    String path = dsMo.getDatastorePath(managedStoragePoolRootVolumeName + ".vmdk");
-
-                    newTemplate.setPath(path);
-                }
-            }
-            else {
-                newTemplate.setPath(templateUuidName);
-            }
-
-            newTemplate.setSize((vmInfo != null)? vmInfo.second() : new Long(0));
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            String msg = "Unable to copy template to primary storage due to exception:" + VmwareHelper.getExceptionMessage(e);
-
-            s_logger.error(msg, e);
-
-            return new CopyCmdAnswer(msg);
-        }
-        finally {
-            if (dsMo != null && managedStoragePoolName != null) {
-                try {
-                    removeVmfsDatastore(cmd, hyperHost, VmwareResource.getDatastoreName(managedStoragePoolName), storageHost, storagePort, trimIqn(managedStoragePoolName));
-                }
-                catch (Exception ex) {
-                    s_logger.error("Unable to remove the following datastore: " + VmwareResource.getDatastoreName(managedStoragePoolName), ex);
-                }
-            }
-        }
-    }
-
-    private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, String vmdkName, ManagedObjectReference morDatastore,
-                                        ManagedObjectReference morPool) throws Exception {
-        return createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool, null);
-    }
-
-    private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, String vmdkName, ManagedObjectReference morDatastore,
-                                        ManagedObjectReference morPool, ManagedObjectReference morBaseSnapshot) throws Exception {
-        if (morBaseSnapshot == null) {
-            morBaseSnapshot = vmTemplate.getSnapshotMor("cloud.template.base");
-        }
-
-        if (morBaseSnapshot == null) {
-            String msg = "Unable to find template base snapshot, invalid template";
-
-            s_logger.error(msg);
-
-            throw new Exception(msg);
-        }
-
-        s_logger.info("creating linked clone from template");
-
-        if (!vmTemplate.createLinkedClone(vmdkName, morBaseSnapshot, dcMo.getVmFolder(), morPool, morDatastore)) {
-            String msg = "Unable to clone from the template";
-
-            s_logger.error(msg);
-
-            throw new Exception(msg);
-        }
-
-        return true;
-    }
-
-    private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, String vmdkName, ManagedObjectReference morDatastore,
-                                      ManagedObjectReference morPool) throws Exception {
-        s_logger.info("creating full clone from template");
-
-        if (!vmTemplate.createFullClone(vmdkName, dcMo.getVmFolder(), morPool, morDatastore)) {
-            String msg = "Unable to create full clone from the template";
-
-            s_logger.error(msg);
-
-            throw new Exception(msg);
-        }
-
-        return true;
-    }
-
-    @Override
-    public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        TemplateObjectTO template = (TemplateObjectTO)srcData;
-        DataTO destData = cmd.getDestTO();
-        VolumeObjectTO volume = (VolumeObjectTO)destData;
-        DataStoreTO primaryStore = volume.getDataStore();
-        DataStoreTO srcStore = template.getDataStore();
-        String searchExcludedFolders = cmd.getContextParam("searchexludefolders");
-
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-            VirtualMachineMO vmMo = null;
-            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
-            if (morDatastore == null) {
-                throw new Exception("Unable to find datastore in vSphere");
-            }
-
-            DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
-
-            String vmdkName = volume.getName();
-            String vmdkFileBaseName;
-            if (srcStore == null) {
-                // create a root volume for blank VM (created from ISO)
-                String dummyVmName = hostService.getWorkerName(context, cmd, 0);
-
-                try {
-                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
-                    if (vmMo == null) {
-                        throw new Exception("Unable to create a dummy VM for volume creation");
-                    }
-
-                    vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
-                    // we only use the first file in the pair, linked or not will not matter
-                    String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
-                    String volumeDatastorePath = vmdkFilePair[0];
-                    synchronized (this) {
-                        s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
-                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo, searchExcludedFolders);
-                        vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, -1);
-                        vmMo.detachDisk(volumeDatastorePath, false);
-                    }
-                } finally {
-                    s_logger.info("Destroy dummy VM after volume creation");
-                    if (vmMo != null) {
-                        s_logger.warn("Unable to destroy a null VM ManagedObjectReference");
-                        vmMo.detachAllDisks();
-                        vmMo.destroy();
-                    }
-                }
-            } else {
-                String templatePath = template.getPath();
-                VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true);
-                if (vmTemplate == null) {
-                    s_logger.warn("Template host in vSphere is not in connected state, request template reload");
-                    return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload");
-                }
-
-                ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-                if (template.getSize() != null){
-                    _fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
-                }
-                if (!_fullCloneFlag) {
-                    createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool);
-                } else {
-                    createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
-                }
-
-                vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName);
-                assert (vmMo != null);
-
-                vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
-                s_logger.info("Move volume out of volume-wrapper VM " + vmdkFileBaseName);
-                String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag);
-                String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
-
-                dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
-                dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
-
-                s_logger.info("detach disks from volume-wrapper VM " + vmdkName);
-                vmMo.detachAllDisks();
-
-                s_logger.info("destroy volume-wrapper VM " + vmdkName);
-                vmMo.destroy();
-
-                String srcFile = dsMo.getDatastorePath(vmdkName, true);
-
-                dsMo.deleteFile(srcFile, dcMo.getMor(), true, searchExcludedFolders);
-
-                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) {
-                    dsMo.deleteFolder(srcFile, dcMo.getMor());
-                }
-            }
-            // restoreVM - move the new ROOT disk into corresponding VM folder
-            VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
-            if (restoreVmMo != null) {
-                String vmNameInVcenter = restoreVmMo.getName(); // VM folder name in datastore will be VM's name in vCenter.
-                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
-                    VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName, searchExcludedFolders);
-                }
-            }
-
-            VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(vmdkFileBaseName);
-            if (template.getSize() != null){
-                newVol.setSize(template.getSize());
-            }
-            else {
-                newVol.setSize(volume.getSize());
-            }
-            return new CopyCmdAnswer(newVol);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                hostService.invalidateServiceContext(null);
-            }
-
-            String msg = "clone volume from base image failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl,
-                                                          long wait, Integer nfsVersion) throws Exception {
-        String volumeFolder;
-        String volumeName;
-        String sufix = ".ova";
-        int index = srcVolumePath.lastIndexOf(File.separator);
-        if (srcVolumePath.endsWith(sufix)) {
-            volumeFolder = srcVolumePath.substring(0, index);
-            volumeName = srcVolumePath.substring(index + 1).replace(sufix, "");
-        } else {
-            volumeFolder = srcVolumePath;
-            volumeName = srcVolumePath.substring(index + 1);
-        }
-
-        String newVolume = VmwareHelper.getVCenterSafeUuid();
-        restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion);
-
-        return new Pair<>(volumeFolder, newVolume);
-    }
-
-    private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl, Integer nfsVersion) throws Exception {
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
-        String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
-
-        return deleteDir(volumeMountRoot);
-    }
-
-    private String deleteDir(String dir) {
-        synchronized (dir.intern()) {
-            Script command = new Script(false, "rm", _timeout, s_logger);
-            command.add("-rf");
-            command.add(dir);
-            return command.execute();
-        }
-    }
-
-    @Override
-    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
-        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
-        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
-        VmwareContext context = hostService.getServiceContext(cmd);
-        try {
-
-            NfsTO srcStore = (NfsTO)srcVolume.getDataStore();
-            DataStoreTO destStore = destVolume.getDataStore();
-
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-            String uuid = destStore.getUuid();
-
-            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, uuid);
-            if (morDatastore == null) {
-                URI uri = new URI(destStore.getUrl());
-
-                morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), destStore.getUuid().replace("-", ""));
-
-                if (morDatastore == null) {
-                    throw new Exception("Unable to mount storage pool on host. storeUrl: " + uri.getHost() + ":/" + uri.getPath());
-                }
-            }
-
-            Pair<String, String> result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000, _nfsVersion);
-            deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl(), _nfsVersion);
-            VolumeObjectTO newVolume = new VolumeObjectTO();
-            newVolume.setPath(result.second());
-            return new CopyCmdAnswer(newVolume);
-        } catch (Throwable t) {
-            if (t instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            String msg = "Unable to execute CopyVolumeCommand due to exception";
-            s_logger.error(msg, t);
-            return new CopyCmdAnswer("copy volume secondary to primary failed due to exception: " + VmwareHelper.getExceptionMessage(t));
-        }
-
-    }
-
-    private String getVolumePathInDatastore(DatastoreMO dsMo, String volumeFileName, String searchExcludedFolders) throws Exception {
-        String datastoreVolumePath = dsMo.searchFileInSubFolders(volumeFileName, true, searchExcludedFolders);
-        assert (datastoreVolumePath != null) : "Virtual disk file missing from datastore.";
-        return datastoreVolumePath;
-    }
-
-    private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyCommand cmd, String vmName, String poolId,
-                                                        String volumePath, String destVolumePath, String secStorageUrl, String workerVmName) throws Exception {
-        VirtualMachineMO workerVm = null;
-        VirtualMachineMO vmMo = null;
-        String exportName = UUID.randomUUID().toString().replace("-", "");
-        String searchExcludedFolders = cmd.getContextParam("searchexludefolders");
-
-        try {
-            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
-
-            if (morDs == null) {
-                String msg = "Unable to find volumes's storage pool for copy volume operation";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if (vmMo == null || VmwareResource.getVmState(vmMo) == PowerState.PowerOff) {
-                // create a dummy worker vm for attaching the volume
-                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
-                workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
-
-                if (workerVm == null) {
-                    String msg = "Unable to create worker VM to execute CopyVolumeCommand";
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-
-                // attach volume to worker VM
-                String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk", searchExcludedFolders);
-                workerVm.attachDisk(new String[] {datastoreVolumePath}, morDs);
-                vmMo = workerVm;
-            }
-
-            vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
-
-            exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion);
-            return new Pair<>(destVolumePath, exportName);
-
-        } finally {
-            vmMo.removeSnapshot(exportName, false);
-            if (workerVm != null) {
-                //detach volume and destroy worker vm
-                workerVm.detachAllDisks();
-                workerVm.destroy();
-            }
-        }
-    }
-
-    @Override
-    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
-        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
-        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
-        String vmName = srcVolume.getVmName();
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-        try {
-            DataStoreTO primaryStorage = srcVolume.getDataStore();
-            NfsTO destStore = (NfsTO)destVolume.getDataStore();
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-
-            Pair<String, String> result;
-
-            result =
-                    copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, primaryStorage.getUuid(), srcVolume.getPath(), destVolume.getPath(), destStore.getUrl(),
-                            hostService.getWorkerName(context, cmd, 0));
-            VolumeObjectTO newVolume = new VolumeObjectTO();
-            newVolume.setPath(result.first() + File.separator + result.second());
-            return new CopyCmdAnswer(newVolume);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            String msg = "Unable to execute CopyVolumeCommand due to exception";
-            s_logger.error(msg, e);
-            return new CopyCmdAnswer("copy volume from primary to secondary failed due to exception: " + VmwareHelper.getExceptionMessage(e));
-        }
-    }
-
-    private void postCreatePrivateTemplate(String installFullPath, long templateId, String templateName, long size, long virtualSize) throws Exception {
-
-        // TODO a bit ugly here
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/template.properties"),"UTF-8"));
-            out.write("filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("description=");
-            out.newLine();
-            out.write("checksum=");
-            out.newLine();
-            out.write("hvm=false");
-            out.newLine();
-            out.write("size=" + size);
-            out.newLine();
-            out.write("ova=true");
-            out.newLine();
-            out.write("id=" + templateId);
-            out.newLine();
-            out.write("public=false");
-            out.newLine();
-            out.write("ova.filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("uniquename=" + templateName);
-            out.newLine();
-            out.write("ova.virtualsize=" + virtualSize);
-            out.newLine();
-            out.write("virtualsize=" + virtualSize);
-            out.newLine();
-            out.write("ova.size=" + size);
-            out.newLine();
-        } finally {
-            if (out != null) {
-                out.close();
-            }
-        }
-    }
-
-    private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
-                                                                 String secStorageUrl, String volumePath, String workerVmName, Integer nfsVersion) throws Exception {
-
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
-        String installFullPath = secondaryMountPoint + "/" + installPath;
-        synchronized (installPath.intern()) {
-            Script command = new Script(false, "mkdir", _timeout, s_logger);
-            command.add("-p");
-            command.add(installFullPath);
-
-            String result = command.execute();
-            if (result != null) {
-                String msg = "unable to prepare template directory: " + installPath + ", storage: " + secStorageUrl + ", error msg: " + result;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-        }
-
-        VirtualMachineMO clonedVm = null;
-        try {
-            Pair<VirtualDisk, String> volumeDeviceInfo = vmMo.getDiskDevice(volumePath);
-            if (volumeDeviceInfo == null) {
-                String msg = "Unable to find related disk device for volume. volume path: " + volumePath;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            if (!vmMo.createSnapshot(templateUniqueName, "Temporary snapshot for template creation", false, false)) {
-                String msg = "Unable to take snapshot for creating template from volume. volume path: " + volumePath;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            // 4 MB is the minimum requirement for VM memory in VMware
-            Pair<VirtualMachineMO, String[]> cloneResult =
-                    vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
-            clonedVm = cloneResult.first();
-
-            clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false);
-
-            // Get VMDK filename
-            String templateVMDKName = "";
-            File[] files = new File(installFullPath).listFiles();
-            if(files != null) {
-                for(File file : files) {
-                    String fileName = file.getName();
-                    if(fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
-                        templateVMDKName += fileName;
-                        break;
-                    }
-                }
-            }
-
-            long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
-            OVAProcessor processor = new OVAProcessor();
-
-            Map<String, Object> params = new HashMap<>();
-            params.put(StorageLayer.InstanceConfigKey, _storage);
-            processor.configure("OVA Processor", params);
-            long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
-
-            postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
-            writeMetaOvaForTemplate(installFullPath, templateUniqueName + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
-            return new Ternary<String, Long, Long>(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize);
-
-        } finally {
-            if (clonedVm != null) {
-                clonedVm.detachAllDisks();
-                clonedVm.destroy();
-            }
-
-            vmMo.removeSnapshot(templateUniqueName, false);
-        }
-    }
-
-    @Override
-    public Answer createTemplateFromVolume(CopyCommand cmd) {
-        VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
-        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
-        DataStoreTO imageStore = template.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-        NfsTO nfsImageStore = (NfsTO)imageStore;
-        String secondaryStoragePoolURL = nfsImageStore.getUrl();
-        String volumePath = volume.getPath();
-
-        String details = null;
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-        try {
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName());
-            if (vmMo == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() +
-                            ", try within datacenter");
-                }
-                vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName());
-
-                if (vmMo == null) {
-                    // This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
-                    // Look for the VM in the datacenter.
-                    ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
-                    DatacenterMO dcMo = new DatacenterMO(context, dcMor);
-                    vmMo = dcMo.findVm(volume.getVmName());
-                }
-
-                if (vmMo == null) {
-                    String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-            }
-
-            Ternary<String, Long, Long> result =
-                    createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
-                            hostService.getWorkerName(context, cmd, 0), _nfsVersion);
-
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(result.first());
-            newTemplate.setFormat(ImageFormat.OVA);
-            newTemplate.setSize(result.third());
-            newTemplate.setPhysicalSize(result.second());
-            return new CopyCmdAnswer(newTemplate);
-
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            s_logger.error("Unexpecpted exception ", e);
-
-            details = "create template from volume exception: " + VmwareHelper.getExceptionMessage(e);
-            return new CopyCmdAnswer(details);
-        }
-    }
-
-    private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename, String templateName, long diskSize) throws Exception {
-
-        // TODO a bit ugly here
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName + ".ova.meta"),"UTF-8"));
-            out.write("ova.filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("version=1.0");
-            out.newLine();
-            out.write("ovf=" + ovfFilename);
-            out.newLine();
-            out.write("numDisks=1");
-            out.newLine();
-            out.write("disk1.name=" + vmdkFilename);
-            out.newLine();
-            out.write("disk1.size=" + diskSize);
-            out.newLine();
-        } finally {
-            if (out != null) {
-                out.close();
-            }
-        }
-    }
-
-    private Ternary<String, Long, Long> createTemplateFromSnapshot(String installPath, String templateUniqueName, String secStorageUrl, String snapshotPath,
-                                                                   Long templateId, long wait, Integer nfsVersion) throws Exception {
-        //Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid
-        String backupSSUuid;
-        String snapshotFolder;
-        if (snapshotPath.endsWith(".ova")) {
-            int index = snapshotPath.lastIndexOf(File.separator);
-            backupSSUuid = snapshotPath.substring(index + 1).replace(".ova", "");
-            snapshotFolder = snapshotPath.substring(0, index);
-        } else {
-            String[] tokens = snapshotPath.split(File.separatorChar == '\\' ? "\\\\" : File.separator);
-            backupSSUuid = tokens[tokens.length - 1];
-            snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1);
-        }
-
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
-        String installFullPath = secondaryMountPoint + "/" + installPath;
-        String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova";  //Note: volss for tmpl
-        String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
-        String snapshotFullOVAName = snapshotRoot + "/" + backupSSUuid + ".ova";
-        String snapshotFullOvfName = snapshotRoot + "/" + backupSSUuid + ".ovf";
-        String result;
-        Script command;
-        String templateVMDKName = "";
-        String snapshotFullVMDKName = snapshotRoot + "/" + backupSSUuid + "/";
-
-        synchronized (installPath.intern()) {
-            command = new Script(false, "mkdir", _timeout, s_logger);
-            command.add("-p");
-            command.add(installFullPath);
-
-            result = command.execute();
-            if (result != null) {
-                String msg = "unable to prepare template directory: " + installPath + ", storage: " + secStorageUrl + ", error msg: " + result;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-        }
-
-        try {
-            if (new File(snapshotFullOVAName).exists()) {
-                command = new Script(false, "cp", wait, s_logger);
-                command.add(snapshotFullOVAName);
-                command.add(installFullOVAName);
-                result = command.execute();
-                if (result != null) {
-                    String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-
-                // untar OVA file at template directory
-                command = new Script("tar", wait, s_logger);
-                command.add("--no-same-owner");
-                command.add("-xf", installFullOVAName);
-                command.setWorkDir(installFullPath);
-                s_logger.info("Executing command: " + command.toString());
-                result = command.execute();
-                if (result != null) {
-                    String msg = "unable to untar snapshot " + snapshotFullOVAName + " to " + installFullPath;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-
-            } else {  // there is no ova file, only ovf originally;
-                if (new File(snapshotFullOvfName).exists()) {
-                    command = new Script(false, "cp", wait, s_logger);
-                    command.add(snapshotFullOvfName);
-                    //command.add(installFullOvfName);
-                    command.add(installFullPath);
-                    result = command.execute();
-                    if (result != null) {
-                        String msg = "unable to copy snapshot " + snapshotFullOvfName + " to " + installFullPath;
-                        s_logger.error(msg);
-                        throw new Exception(msg);
-                    }
-
-                    s_logger.info("vmdkfile parent dir: " + snapshotRoot);
-                    File snapshotdir = new File(snapshotRoot);
-                    File[] ssfiles = snapshotdir.listFiles();
-                    if (ssfiles == null) {
-                        String msg = "unable to find snapshot vmdk files in " + snapshotRoot;
-                        s_logger.error(msg);
-                        throw new Exception(msg);
-                    }
-                    // List<String> filenames = new ArrayList<String>();
-                    for (int i = 0; i < ssfiles.length; i++) {
-                        String vmdkfile = ssfiles[i].getName();
-                        s_logger.info("vmdk file name: " + vmdkfile);
-                        if (vmdkfile.toLowerCase().startsWith(backupSSUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) {
-                            snapshotFullVMDKName = snapshotRoot + File.separator + vmdkfile;
-                            templateVMDKName += vmdkfile;
-                            break;
-                        }
-                    }
-                    if (snapshotFullVMDKName != null) {
-                        command = new Script(false, "cp", wait, s_logger);
-                        command.add(snapshotFullVMDKName);
-                        command.add(installFullPath);
-                        result = command.execute();
-                        s_logger.info("Copy VMDK file: " + snapshotFullVMDKName);
-                        if (result != null) {
-                            String msg = "unable to copy snapshot vmdk file " + snapshotFullVMDKName + " to " + installFullPath;
-                            s_logger.error(msg);
-                            throw new Exception(msg);
-                        }
-                    }
-                } else {
-                    String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-            }
-
-            Size size = handleMetadataCreateTemplateFromSnapshot(installFullPath, templateVMDKName, templateId, templateUniqueName, backupSSUuid);
-
-            return new Ternary<>(installPath + "/" + templateUniqueName + ".ova", size.getPhysicalSize(), size.getVirtualSize());
-        } finally {
-            // TODO, clean up left over files
-        }
-    }
-
-    private class Size {
-        private final long _physicalSize;
-        private final long _virtualSize;
-
-        Size(long physicalSize, long virtualSize) {
-            _physicalSize = physicalSize;
-            _virtualSize = virtualSize;
-        }
-
-        long getPhysicalSize() {
-            return _physicalSize;
-        }
-
-        long getVirtualSize() {
-            return _virtualSize;
-        }
-    }
-
-    private Size handleMetadataCreateTemplateFromSnapshot(String installFullPath, String templateVMDKName, long templateId, String templateUniqueName,
-                                                          String ovfFilename) throws Exception {
-        long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
-
-        OVAProcessor processor = new OVAProcessor();
-
-        Map<String, Object> params = new HashMap<>();
-
-        params.put(StorageLayer.InstanceConfigKey, _storage);
-
-        processor.configure("OVA Processor", params);
-
-        long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
-
-        postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
-
-        writeMetaOvaForTemplate(installFullPath, ovfFilename + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
-
-        return new Size(physicalSize, virtualSize);
-    }
-
-    private void setUpManagedStorageCopyTemplateFromSnapshot(CopyCommand cmd) throws Exception {
-        VmwareContext context = hostService.getServiceContext(cmd);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO clusterMO = new ClusterMO(context, morCluster);
-
-        List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
-
-        final Map<String, String> options = cmd.getOptions();
-
-        final String storageHost = options.get(DiskTO.STORAGE_HOST);
-        final int storagePortNumber = Integer.parseInt(options.get(DiskTO.STORAGE_PORT));
-        final String iScsiName = options.get(DiskTO.IQN);
-        final String snapshotPath = options.get(DiskTO.VMDK);
-        final String chapInitiatorUsername = options.get(DiskTO.CHAP_INITIATOR_USERNAME);
-        final String chapInitiatorSecret = options.get(DiskTO.CHAP_INITIATOR_SECRET);
-        final String chapTargetUsername = options.get(DiskTO.CHAP_TARGET_USERNAME);
-        final String chapTargetSecret = options.get(DiskTO.CHAP_TARGET_SECRET);
-
-        String datastoreName = getManagedDatastoreNameFromPath(snapshotPath);
-
-        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
-        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-            final List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
-                    chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-
-            addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
-        }
-
-        rescanAllHosts(context, lstHosts, true, true);
-
-        Pair<ManagedObjectReference, String> firstHost = lstHosts.get(0);
-        HostMO firstHostMO = new HostMO(context, firstHost.first());
-        HostDatastoreSystemMO firstHostDatastoreSystemMO = firstHostMO.getHostDatastoreSystemMO();
-        ManagedObjectReference morDs = firstHostDatastoreSystemMO.findDatastoreByName(datastoreName);
-        DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
-
-        mountVmfsDatastore(datastoreMO, lstHosts);
-    }
-
-    private void takeDownManagedStorageCopyTemplateFromSnapshot(CopyCommand cmd) throws Exception {
-        VmwareContext context = hostService.getServiceContext(cmd);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO clusterMO = new ClusterMO(context, morCluster);
-
-        List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
-
-        final Map<String, String> options = cmd.getOptions();
-
-        final String storageHost = options.get(DiskTO.STORAGE_HOST);
-        final int storagePortNumber = Integer.parseInt(options.get(DiskTO.STORAGE_PORT));
-        final String iScsiName = options.get(DiskTO.IQN);
-        final String snapshotPath = options.get(DiskTO.VMDK);
-
-        String datastoreName = getManagedDatastoreNameFromPath(snapshotPath);
-
-        unmountVmfsDatastore(context, hyperHost, datastoreName, lstHosts);
-
-        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
-        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-            final List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
-                    null, null, null, null);
-
-            addRemoveInternetScsiTargetsToAllHosts(false, lstTargets, hostsUsingStaticDiscovery);
-
-            rescanAllHosts(context, lstHosts, true, false);
-        }
-    }
-
-    private void createTemplateFolder(String installPath, String installFullPath, NfsTO nfsSvr) {
-        synchronized (installPath.intern()) {
-            Script command = new Script(false, "mkdir", _timeout, s_logger);
-
-            command.add("-p");
-            command.add(installFullPath);
-
-            String result = command.execute();
-
-            if (result != null) {
-                String secStorageUrl = nfsSvr.getUrl();
-                String msg = "unable to prepare template directory: " + installPath + "; storage: " + secStorageUrl + "; error msg: " + result;
-
-                s_logger.error(msg);
-
-                throw new CloudRuntimeException(msg);
-            }
-        }
-    }
-
-    private void exportManagedStorageSnapshotToTemplate(CopyCommand cmd, String installFullPath, String snapshotPath, String exportName) throws Exception {
-        DatastoreFile dsFile = new DatastoreFile(snapshotPath);
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-
-        String workerVMName = hostService.getWorkerName(context, cmd, 0);
-
-        ManagedObjectReference dsMor = hyperHost.findDatastoreByName(dsFile.getDatastoreName());
-        DatastoreMO dsMo = new DatastoreMO(context, dsMor);
-
-        VirtualMachineMO workerVM = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
-
-        if (workerVM == null) {
-            throw new CloudRuntimeException("Failed to find the newly created worker VM: " + workerVMName);
-        }
-
-        workerVM.attachDisk(new String[]{snapshotPath}, dsMor);
-
-        workerVM.exportVm(installFullPath, exportName, false, false);
-
-        workerVM.detachAllDisks();
-        workerVM.destroy();
-    }
-
-    private String getTemplateVmdkName(String installFullPath, String exportName) {
-        File templateDir = new File(installFullPath);
-        File[] templateFiles = templateDir.listFiles();
-
-        if (templateFiles == null) {
-            String msg = "Unable to find template files in " + installFullPath;
-
-            s_logger.error(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        for (int i = 0; i < templateFiles.length; i++) {
-            String templateFile = templateFiles[i].getName();
-
-            if (templateFile.toLowerCase().startsWith(exportName) && templateFile.toLowerCase().endsWith(".vmdk")) {
-                return templateFile;
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate the template VMDK file");
-    }
-
-    private Answer handleManagedStorageCreateTemplateFromSnapshot(CopyCommand cmd, TemplateObjectTO template, NfsTO nfsSvr) {
-        try {
-            setUpManagedStorageCopyTemplateFromSnapshot(cmd);
-
-            final Map<String, String> options = cmd.getOptions();
-
-            String snapshotPath = options.get(DiskTO.VMDK);
-
-            String secondaryMountPoint = mountService.getMountPoint(nfsSvr.getUrl(), _nfsVersion);
-            String installPath = template.getPath();
-            String installFullPath = secondaryMountPoint + "/" + installPath;
-
-            createTemplateFolder(installPath, installFullPath, nfsSvr);
-
-            String exportName = UUID.randomUUID().toString();
-
-            exportManagedStorageSnapshotToTemplate(cmd, installFullPath, snapshotPath, exportName);
-
-            String templateVmdkName = getTemplateVmdkName(installFullPath, exportName);
-
-            String uniqueName = options.get(DiskTO.UUID);
-
-            Size size = handleMetadataCreateTemplateFromSnapshot(installFullPath, templateVmdkName, template.getId(), uniqueName, exportName);
-
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(installPath + "/" + uniqueName + ".ova");
-            newTemplate.setPhysicalSize(size.getPhysicalSize());
-            newTemplate.setSize(size.getVirtualSize());
-            newTemplate.setFormat(ImageFormat.OVA);
-            newTemplate.setName(uniqueName);
-
-            return new CopyCmdAnswer(newTemplate);
-        }
-        catch (Exception ex) {
-            String errMsg = "Problem creating a template from a snapshot for managed storage: " + ex.getMessage();
-
-            s_logger.error(errMsg);
-
-            throw new CloudRuntimeException(errMsg, ex);
-        }
-        finally {
-            try {
-                takeDownManagedStorageCopyTemplateFromSnapshot(cmd);
-            }
-            catch (Exception ex) {
-                s_logger.warn("Unable to remove one or more static targets");
-            }
-        }
-    }
-
-    @Override
-    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
-        String details;
-
-        SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getSrcTO();
-        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
-
-        DataStoreTO imageStore = template.getDataStore();
-
-        String uniqueName = UUID.randomUUID().toString();
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-
-        try {
-            if (!(imageStore instanceof NfsTO)) {
-                return new CopyCmdAnswer("Creating a template from a snapshot is only supported when the destination store is NFS.");
-            }
-
-            NfsTO nfsSvr = (NfsTO)imageStore;
-
-            if (snapshot.getDataStore() instanceof PrimaryDataStoreTO && template.getDataStore() instanceof NfsTO) {
-                return handleManagedStorageCreateTemplateFromSnapshot(cmd, template, nfsSvr);
-            }
-
-            Ternary<String, Long, Long> result = createTemplateFromSnapshot(template.getPath(), uniqueName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(),
-                    cmd.getWait() * 1000, _nfsVersion);
-
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(result.first());
-            newTemplate.setPhysicalSize(result.second());
-            newTemplate.setSize(result.third());
-            newTemplate.setFormat(ImageFormat.OVA);
-            newTemplate.setName(uniqueName);
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            s_logger.error("Unexpected exception ", e);
-
-            details = "create template from snapshot exception: " + VmwareHelper.getExceptionMessage(e);
-
-            return new CopyCmdAnswer(details);
-        }
-    }
-
-    // return Pair<String(divice bus name), String[](disk chain)>
-    private Pair<String, String[]> exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
-                                                                  String exportName, String workerVmName, Integer nfsVersion) throws Exception {
-
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
-        String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
-
-        synchronized (exportPath.intern()) {
-            if (!new File(exportPath).exists()) {
-                Script command = new Script(false, "mkdir", _timeout, s_logger);
-                command.add("-p");
-                command.add(exportPath);
-                if (command.execute() != null) {
-                    throw new Exception("unable to prepare snapshot backup directory");
-                }
-            }
-        }
-
-        VirtualMachineMO clonedVm = null;
-        try {
-
-            Pair<VirtualDisk, String> volumeDeviceInfo = vmMo.getDiskDevice(volumePath);
-            if (volumeDeviceInfo == null) {
-                String msg = "Unable to find related disk device for volume. volume path: " + volumePath;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            // 4 MB is the minimum requirement for VM memory in VMware
-            Pair<VirtualMachineMO, String[]> cloneResult =
-                    vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
-            clonedVm = cloneResult.first();
-            String disks[] = cloneResult.second();
-
-            clonedVm.exportVm(exportPath, exportName, false, false);
-            return new Pair<>(volumeDeviceInfo.second(), disks);
-        } finally {
-            if (clonedVm != null) {
-                clonedVm.detachAllDisks();
-                clonedVm.destroy();
-            }
-        }
-    }
-
-    // Ternary<String(backup uuid in secondary storage), String(device bus name), String[](original disk chain in the snapshot)>
-    private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid,
-                                                                               String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName,
-                                                                               Integer nfsVersion) throws Exception {
-
-        String backupUuid = UUID.randomUUID().toString();
-        Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion);
-        return new Ternary<>(backupUuid, snapshotInfo.first(), snapshotInfo.second());
-    }
-
-    @Override
-    public Answer backupSnapshot(CopyCommand cmd) {
-        SnapshotObjectTO srcSnapshot = (SnapshotObjectTO)cmd.getSrcTO();
-        DataStoreTO primaryStore = srcSnapshot.getDataStore();
-        SnapshotObjectTO destSnapshot = (SnapshotObjectTO)cmd.getDestTO();
-        DataStoreTO destStore = destSnapshot.getDataStore();
-        if (!(destStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        NfsTO destNfsStore = (NfsTO)destStore;
-
-        String secondaryStorageUrl = destNfsStore.getUrl();
-        String snapshotUuid = srcSnapshot.getPath();
-        String prevSnapshotUuid = srcSnapshot.getParentSnapshotPath();
-        String prevBackupUuid = destSnapshot.getParentSnapshotPath();
-        VirtualMachineMO workerVm = null;
-        String workerVMName = null;
-        String volumePath = srcSnapshot.getVolume().getPath();
-        ManagedObjectReference morDs;
-        DatastoreMO dsMo;
-
-        // By default assume failure
-        String details;
-        boolean success;
-        String snapshotBackupUuid;
-
-        boolean hasOwnerVm = false;
-        Ternary<String, String, String[]> backupResult = null;
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-        VirtualMachineMO vmMo = null;
-        String vmName = srcSnapshot.getVmName();
-        try {
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-            morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
-
-            CopyCmdAnswer answer = null;
-
-            try {
-                if(vmName != null) {
-                    vmMo = hyperHost.findVmOnHyperHost(vmName);
-                    if (vmMo == null) {
-                        if(s_logger.isDebugEnabled()) {
-                            s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
-                        }
-                        vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-                    }
-                }
-                if(vmMo == null) {
-                    dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
-                    workerVMName = hostService.getWorkerName(context, cmd, 0);
-                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
-                    if (vmMo == null) {
-                        throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
-                    }
-                    workerVm = vmMo;
-                    // attach volume to worker VM
-                    String datastoreVolumePath = dsMo.getDatastorePath(volumePath + ".vmdk");
-                    vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
-                } else {
-                    s_logger.info("Using owner VM " + vmName + " for snapshot operation");
-                    hasOwnerVm = true;
-                }
-
-                if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) {
-                    throw new Exception("Failed to take snapshot " + srcSnapshot.getName() + " on vm: " + vmName);
-                }
-
-                backupResult =
-                        backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
-                                prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
-                snapshotBackupUuid = backupResult.first();
-
-                success = (snapshotBackupUuid != null);
-                if (!success) {
-                    details = "Failed to backUp the snapshot with uuid: " + snapshotUuid + " to secondary storage.";
-                    answer = new CopyCmdAnswer(details);
-                } else {
-                    details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage.";
-
-                    // Get snapshot physical size
-                    long physicalSize = 0;
-                    String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
-                    String snapshotDir =  destSnapshot.getPath() + "/" + snapshotBackupUuid;
-                    File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
-                    if(files != null) {
-                        for(File file : files) {
-                            String fileName = file.getName();
-                            if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
-                                physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
-                                break;
-                            }
-                        }
-                    }
-
-                    SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-                    newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid);
-                    newSnapshot.setPhysicalSize(physicalSize);
-                    answer = new CopyCmdAnswer(newSnapshot);
-                }
-            } finally {
-                if (vmMo != null) {
-                    ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid);
-                    if (snapshotMor != null) {
-                        vmMo.removeSnapshot(snapshotUuid, false);
-
-                        // Snapshot operation may cause disk consolidation in VMware, when this happens
-                        // we need to update CloudStack DB
-                        //
-                        // TODO: this post operation fixup is not atomic and not safe when management server stops
-                        // in the middle
-                        if (backupResult != null && hasOwnerVm) {
-                            s_logger.info("Check if we have disk consolidation after snapshot operation");
-
-                            boolean chainConsolidated = false;
-                            for (String vmdkDsFilePath : backupResult.third()) {
-                                s_logger.info("Validate disk chain file:" + vmdkDsFilePath);
-
-                                if (vmMo.getDiskDevice(vmdkDsFilePath) == null) {
-                                    s_logger.info("" + vmdkDsFilePath + " no longer exists, consolidation detected");
-                                    chainConsolidated = true;
-                                    break;
-                                } else {
-                                    s_logger.info("" + vmdkDsFilePath + " is found still in chain");
-                                }
-                            }
-
-                            if (chainConsolidated) {
-                                String topVmdkFilePath = null;
-                                try {
-                                    topVmdkFilePath = vmMo.getDiskCurrentTopBackingFileInChain(backupResult.second());
-                                } catch (Exception e) {
-                                    s_logger.error("Unexpected exception", e);
-                                }
-
-                                s_logger.info("Disk has been consolidated, top VMDK is now: " + topVmdkFilePath);
-                                if (topVmdkFilePath != null) {
-                                    DatastoreFile file = new DatastoreFile(topVmdkFilePath);
-
-                                    SnapshotObjectTO snapshotInfo = (SnapshotObjectTO)answer.getNewData();
-                                    VolumeObjectTO vol = new VolumeObjectTO();
-                                    vol.setUuid(srcSnapshot.getVolume().getUuid());
-                                    vol.setPath(file.getFileBaseName());
-                                    snapshotInfo.setVolume(vol);
-                                } else {
-                                    s_logger.error("Disk has been consolidated, but top VMDK is not found ?!");
-                                }
-                            }
-                        }
-                    } else {
-                        s_logger.error("Can not find the snapshot we just used ?!");
-                    }
-                }
-
-                try {
-                    if (workerVm != null) {
-                        // detach volume and destroy worker vm
-                        workerVm.detachAllDisks();
-                        workerVm.destroy();
-                    }
-                } catch (Throwable e) {
-                    s_logger.warn("Failed to destroy worker VM: " + workerVMName);
-                }
-            }
-
-            return answer;
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            s_logger.error("Unexpecpted exception ", e);
-
-            details = "backup snapshot exception: " + VmwareHelper.getExceptionMessage(e);
-            return new CopyCmdAnswer(details);
-        }
-    }
-
-    @Override
-    public Answer attachIso(AttachCommand cmd) {
-        return this.attachIso(cmd.getDisk(), true, cmd.getVmName());
-    }
-
-    @Override
-    public Answer attachVolume(AttachCommand cmd) {
-        Map<String, String> details = cmd.getDisk().getDetails();
-        boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-        String iScsiName = details.get(DiskTO.IQN);
-        String storageHost = details.get(DiskTO.STORAGE_HOST);
-        int storagePort = Integer.parseInt(details.get(DiskTO.STORAGE_PORT));
-
-        return this.attachVolume(cmd, cmd.getDisk(), true, isManaged, cmd.getVmName(), iScsiName, storageHost, storagePort, cmd.getControllerInfo());
-    }
-
-    private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean isManaged, String vmName, String iScsiName,
-                                String storageHost, int storagePort, Map<String, String> controllerInfo) {
-        VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData();
-        DataStoreTO primaryStore = volumeTO.getDataStore();
-
-        String vmdkPath = isManaged ? resource.getVmdkPath(volumeTO.getPath()) : null;
-
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-
-            if (vmMo == null) {
-                vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
-
-                if (vmMo == null) {
-                    String msg = "Unable to find the VM to execute AttachCommand, vmName: " + vmName;
-
-                    s_logger.error(msg);
-
-                    throw new Exception(msg);
-                }
-            }
-
-            vmName = vmMo.getName();
-
-            ManagedObjectReference morDs;
-            String diskUuid =  volumeTO.getUuid().replace("-", "");
-
-            if (isAttach && isManaged) {
-                Map<String, String> details = disk.getDetails();
-
-                morDs = prepareManagedStorage(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort, vmdkPath,
-                            details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
-                            details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
-                            volumeTO.getSize(), cmd);
-            }
-            else {
-                if (storagePort == DEFAULT_NFS_PORT) {
-                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(diskUuid) : primaryStore.getUuid());
-                } else {
-                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
-                }
-            }
-
-            if (morDs == null) {
-                String msg = "Unable to find the mounted datastore to execute AttachCommand, vmName: " + vmName;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            DatastoreMO dsMo = new DatastoreMO(context, morDs);
-            String datastoreVolumePath;
-
-            if (isAttach) {
-                if (isManaged) {
-                    datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
-                } else {
-                    datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName, dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
-                }
-            } else {
-                if (isManaged) {
-                    datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
-                } else {
-                    datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
-
-                    if (!dsMo.fileExists(datastoreVolumePath)) {
-                        datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
-                    }
-                }
-            }
-
-            disk.setPath(datastoreVolumePath);
-
-            AttachAnswer answer = new AttachAnswer(disk);
-
-            if (isAttach) {
-                String diskController = getLegacyVmDataDiskController();
-
-                if (controllerInfo != null && !Strings.isNullOrEmpty(controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER))) {
-                    diskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
-                }
-
-                if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
-                    diskController = vmMo.getRecommendedDiskController(null);
-                }
-
-                vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController);
-
-                if (isManaged) {
-                    expandVirtualDisk(vmMo, datastoreVolumePath, volumeTO.getSize());
-                }
-            } else {
-                vmMo.removeAllSnapshots();
-                vmMo.detachDisk(datastoreVolumePath, false);
-
-                if (isManaged) {
-                    handleDatastoreAndVmdkDetachManaged(cmd, diskUuid, iScsiName, storageHost, storagePort);
-                } else {
-                    VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath(), vmName, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                }
-            }
-
-            return answer;
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-
-                hostService.invalidateServiceContext(null);
-            }
-
-            String msg = "";
-
-            if (isAttach) {
-                msg += "Failed to attach volume: " + e.getMessage();
-            }
-            else {
-                msg += "Failed to detach volume: " + e.getMessage();
-            }
-
-            s_logger.error(msg, e);
-
-            return new AttachAnswer(msg);
-        }
-    }
-
-    private boolean expandVirtualDisk(VirtualMachineMO vmMo, String datastoreVolumePath, long currentSizeInBytes) throws Exception {
-        long currentSizeInKB = currentSizeInBytes / 1024;
-
-        Pair<VirtualDisk, String> vDiskPair = vmMo.getDiskDevice(datastoreVolumePath);
-
-        VirtualDisk vDisk = vDiskPair.first();
-
-        if (vDisk.getCapacityInKB() < currentSizeInKB) {
-            // IDE virtual disk cannot be re-sized if VM is running
-            if (vDiskPair.second() != null && vDiskPair.second().contains("ide")) {
-                throw new Exception("Re-sizing a virtual disk over an IDE controller is not supported in VMware hypervisor. " +
-                        "Please re-try when virtual disk is attached to a VM using a SCSI controller.");
-            }
-
-            String vmdkAbsFile = resource.getAbsoluteVmdkFile(vDisk);
-
-            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
-                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
-            }
-
-            vDisk.setCapacityInKB(currentSizeInKB);
-
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            deviceConfigSpec.setDevice(vDisk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure VM to resize disk. vmName: " + vmMo.getName());
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    private static String getSecondaryDatastoreUUID(String storeUrl) {
-        String uuid = null;
-        try{
-            uuid=UUID.nameUUIDFromBytes(storeUrl.getBytes("UTF-8")).toString();
-        }catch(UnsupportedEncodingException e){
-            s_logger.warn("Failed to create UUID from string " + storeUrl + ". Bad storeUrl or UTF-8 encoding error." );
-        }
-        return uuid;
-    }
-
-    private synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception {
-        String storeName = getSecondaryDatastoreUUID(storeUrl);
-        URI uri = new URI(storeUrl);
-
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(hostService.getServiceContext(null), null);
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
-
-        if (morDatastore == null) {
-            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
-        }
-
-        return morDatastore;
-    }
-
-    private Answer attachIso(DiskTO disk, boolean isAttach, String vmName) {
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if (vmMo == null) {
-                String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + vmName;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-            TemplateObjectTO iso = (TemplateObjectTO)disk.getData();
-            NfsTO nfsImageStore = (NfsTO)iso.getDataStore();
-            String storeUrl = null;
-            if (nfsImageStore != null) {
-                storeUrl = nfsImageStore.getUrl();
-            }
-            if (storeUrl == null) {
-                if (!iso.getName().equalsIgnoreCase("vmware-tools.iso")) {
-                    String msg = "ISO store root url is not found in AttachIsoCommand";
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                } else {
-                    if (isAttach) {
-                        vmMo.mountToolsInstaller();
-                    } else {
-                        try{
-                            if (!vmMo.unmountToolsInstaller()) {
-                                return new AttachAnswer("Failed to unmount vmware-tools installer ISO as the corresponding CDROM device is locked by VM. Please unmount the CDROM device inside the VM and ret-try.");
-                            }
-                        } catch(Throwable e){
-                            vmMo.detachIso(null);
-                        }
-                    }
-
-                    return new AttachAnswer(disk);
-                }
-            }
-
-            ManagedObjectReference morSecondaryDs = prepareSecondaryDatastoreOnHost(storeUrl);
-            String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
-            if (!isoPath.startsWith(storeUrl)) {
-                assert (false);
-                String msg = "ISO path does not start with the secondary storage root";
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            int isoNameStartPos = isoPath.lastIndexOf('/');
-            String isoFileName = isoPath.substring(isoNameStartPos + 1);
-            String isoStorePathFromRoot = isoPath.substring(storeUrl.length() + 1, isoNameStartPos);
-
-            // TODO, check if iso is already attached, or if there is a previous
-            // attachment
-            DatastoreMO secondaryDsMo = new DatastoreMO(context, morSecondaryDs);
-            String storeName = secondaryDsMo.getName();
-            String isoDatastorePath = String.format("[%s] %s/%s", storeName, isoStorePathFromRoot, isoFileName);
-
-            if (isAttach) {
-                vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false);
-            } else {
-                vmMo.detachIso(isoDatastorePath);
-            }
-
-            return new AttachAnswer(disk);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                hostService.invalidateServiceContext(null);
-            }
-
-            if (isAttach) {
-                String msg = "AttachIsoCommand(attach) failed due to " + VmwareHelper.getExceptionMessage(e);
-                msg = msg + " Also check if your guest os is a supported version";
-                s_logger.error(msg, e);
-                return new AttachAnswer(msg);
-            } else {
-                String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e);
-                msg = msg + " Also check if your guest os is a supported version";
-                s_logger.warn(msg, e);
-                return new AttachAnswer(msg);
-            }
-        }
-    }
-
-    @Override
-    public Answer dettachIso(DettachCommand cmd) {
-        return this.attachIso(cmd.getDisk(), false, cmd.getVmName());
-    }
-
-    @Override
-    public Answer dettachVolume(DettachCommand cmd) {
-        return this.attachVolume(cmd, cmd.getDisk(), false, cmd.isManaged(), cmd.getVmName(), cmd.get_iScsiName(), cmd.getStorageHost(), cmd.getStoragePort(), null);
-    }
-
-    @Override
-    public Answer createVolume(CreateObjectCommand cmd) {
-
-        VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
-        DataStoreTO primaryStore = volume.getDataStore();
-
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-
-            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
-            if (morDatastore == null) {
-                throw new Exception("Unable to find datastore in vSphere");
-            }
-
-            DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
-            // create data volume
-            VirtualMachineMO vmMo = null;
-            String volumeUuid = UUID.randomUUID().toString().replace("-", "");
-
-            String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk");
-            String dummyVmName = hostService.getWorkerName(context, cmd, 0);
-            try {
-                s_logger.info("Create worker VM " + dummyVmName);
-                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
-                if (vmMo == null) {
-                    throw new Exception("Unable to create a dummy VM for volume creation");
-                }
-
-                synchronized (this) {
-                    try {
-                        vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey());
-                        vmMo.detachDisk(volumeDatastorePath, false);
-                    }
-                    catch (Exception e) {
-                        s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage());
-                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                        throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage());
-                    }
-                }
-
-                VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(volumeUuid);
-                newVol.setSize(volume.getSize());
-                return new CreateObjectAnswer(newVol);
-            } finally {
-                s_logger.info("Destroy dummy VM after volume creation");
-                if (vmMo != null) {
-                    vmMo.detachAllDisks();
-                    vmMo.destroy();
-                }
-            }
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                hostService.invalidateServiceContext(null);
-            }
-
-            String msg = "create volume failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new CreateObjectAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer createSnapshot(CreateObjectCommand cmd) {
-        // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake
-        // a success return here
-        String snapshotUUID = UUID.randomUUID().toString();
-        SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-        newSnapshot.setPath(snapshotUUID);
-        return new CreateObjectAnswer(newSnapshot);
-    }
-
-    // format: [datastore_name] file_name.vmdk (the '[' and ']' chars should only be used to denote the datastore)
-    private String getManagedDatastoreNameFromPath(String path) {
-        int lastIndexOf = path.lastIndexOf("]");
-
-        return path.substring(1, lastIndexOf);
-    }
-
-    @Override
-    public Answer deleteVolume(DeleteCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource DeleteCommand: " + _gson.toJson(cmd));
-        }
-
-        try {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            VolumeObjectTO vol = (VolumeObjectTO)cmd.getData();
-            DataStoreTO store = vol.getDataStore();
-            PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO)store;
-
-            Map<String, String> details = primaryDataStoreTO.getDetails();
-            boolean isManaged = false;
-            String managedDatastoreName = null;
-
-            if (details != null) {
-                isManaged = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
-
-                if (isManaged) {
-                    managedDatastoreName = getManagedDatastoreNameFromPath(vol.getPath());
-                }
-            }
-
-            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost,
-                    isManaged ? managedDatastoreName : store.getUuid());
-
-            if (morDs == null) {
-                String msg = "Unable to find datastore based on volume mount point " + store.getUuid();
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            DatastoreMO dsMo = new DatastoreMO(context, morDs);
-
-            ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
-            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-            ClusterMO clusterMo = new ClusterMO(context, morCluster);
-
-            if (vol.getVolumeType() == Volume.Type.ROOT) {
-
-                String vmName = vol.getVmName();
-                if (vmName != null) {
-                    VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName);
-                    if (vmMo == null) {
-                        // Volume might be on a zone-wide storage pool, look for VM in datacenter
-                        DatacenterMO dcMo = new DatacenterMO(context, morDc);
-                        vmMo = dcMo.findVm(vmName);
-                    }
-
-                    List<Map<String, String>> dynamicTargetsToRemove = null;
-
-                    if (vmMo != null) {
-                        if (s_logger.isInfoEnabled()) {
-                            s_logger.info("Destroy root volume and VM itself. vmName " + vmName);
-                        }
-
-                        VirtualMachineDiskInfo diskInfo = null;
-                        if (vol.getChainInfo() != null)
-                            diskInfo = _gson.fromJson(vol.getChainInfo(), VirtualMachineDiskInfo.class);
-
-                        HostMO hostMo = vmMo.getRunningHost();
-                        List<NetworkDetails> networks = vmMo.getNetworksWithDetails();
-
-                        // tear down all devices first before we destroy the VM to avoid accidently delete disk backing files
-                        if (VmwareResource.getVmState(vmMo) != PowerState.PowerOff) {
-                            vmMo.safePowerOff(_shutdownWaitMs);
-                        }
-
-                        // call this before calling detachAllDisksExcept
-                        // when expunging a VM, we need to see if any of its disks are serviced by managed storage
-                        // if there is one or more disk serviced by managed storage, remove the iSCSI connection(s)
-                        // don't remove the iSCSI connection(s) until the supported disk(s) is/are removed from the VM
-                        // (removeManagedTargetsFromCluster should be called after detachAllDisksExcept and vm.destroy)
-                        List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
-                        List<String> managedDatastoreNames = getManagedDatastoreNamesFromVirtualDisks(virtualDisks);
-
-                        List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
-                        VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
-
-                        // let vmMo.destroy to delete volume for us
-                        // vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
-
-                        if (isManaged) {
-                            vmMo.unregisterVm();
-                        }
-                        else {
-                            vmMo.destroy();
-                        }
-
-                        // this.hostService.handleDatastoreAndVmdkDetach(iScsiName, storageHost, storagePort);
-                        if (managedDatastoreNames != null && !managedDatastoreNames.isEmpty()) {
-                            removeManagedTargetsFromCluster(managedDatastoreNames);
-                        }
-
-                        for (NetworkDetails netDetails : networks) {
-                            if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) {
-                                if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) {
-                                    resource.cleanupNetwork(hostMo, netDetails);
-                                }
-                            }
-                        }
-                    }
-
-                    /*
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk");
-                    }
-
-                    VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
-                     */
-
-                    return new Answer(cmd, true, "");
-                }
-
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Destroy root volume directly from datastore");
-                }
-            }
-
-            if (!isManaged) {
-                VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc), VmwareManager.s_vmwareSearchExcludeFolder.value());
-            }
-
-            return new Answer(cmd, true, "Success");
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
-                hostService.invalidateServiceContext(null);
-            }
-
-            String msg = "delete volume failed due to " + VmwareHelper.getExceptionMessage(e);
-            s_logger.error(msg, e);
-            return new Answer(cmd, false, msg);
-        }
-    }
-
-    public ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
-                                                          String iScsiName, String storageHost, int storagePort) throws Exception {
-        return getVmfsDatastore(context, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iScsiName), null, null, null, null);
-    }
-
-    private ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
-                                                           String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
-                                                           String chapTargetUsername, String chapTargetSecret) throws Exception {
-        if (storagePort == DEFAULT_NFS_PORT) {
-            s_logger.info("creating the NFS datastore with the following configuration - storageHost: " + storageHost + ", storagePort: " + storagePort +
-                    ", exportpath: " + iScsiName + "and diskUuid : " + diskUuid);
-            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-            ClusterMO cluster = new ClusterMO(context, morCluster);
-            List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
-
-            HostMO host = new HostMO(context, lstHosts.get(0).first());
-            HostDatastoreSystemMO hostDatastoreSystem = host.getHostDatastoreSystemMO();
-
-            return hostDatastoreSystem.createNfsDatastore(storageHost, storagePort, iScsiName, diskUuid);
-        } else {
-            return getVmfsDatastore(context, hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
-                    trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-        }
-    }
-
-    private List<HostInternetScsiHbaStaticTarget> getTargets(String storageIpAddress, int storagePortNumber, String iqn,
-                                                             String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) {
-        HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
-
-        target.setAddress(storageIpAddress);
-        target.setPort(storagePortNumber);
-        target.setIScsiName(iqn);
-
-        if (StringUtils.isNotBlank(chapName) && StringUtils.isNotBlank(chapSecret)) {
-            HostInternetScsiHbaAuthenticationProperties auth = new HostInternetScsiHbaAuthenticationProperties();
-
-            String strAuthType = "chapRequired";
-
-            auth.setChapAuthEnabled(true);
-            auth.setChapInherited(false);
-            auth.setChapAuthenticationType(strAuthType);
-            auth.setChapName(chapName);
-            auth.setChapSecret(chapSecret);
-
-            if (StringUtils.isNotBlank(mutualChapName) && StringUtils.isNotBlank(mutualChapSecret)) {
-                auth.setMutualChapInherited(false);
-                auth.setMutualChapAuthenticationType(strAuthType);
-                auth.setMutualChapName(mutualChapName);
-                auth.setMutualChapSecret(mutualChapSecret);
-            }
-
-            target.setAuthenticationProperties(auth);
-        }
-
-        final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<>();
-
-        lstTargets.add(target);
-
-        return lstTargets;
-    }
-
-    private class HostDiscoveryMethod {
-        private final List<HostMO> hostsUsingDynamicDiscovery;
-        private final List<HostMO> hostsUsingStaticDiscovery;
-
-        HostDiscoveryMethod(List<HostMO> hostsUsingDynamicDiscovery, List<HostMO> hostsUsingStaticDiscovery) {
-            this.hostsUsingDynamicDiscovery = hostsUsingDynamicDiscovery;
-            this.hostsUsingStaticDiscovery = hostsUsingStaticDiscovery;
-        }
-
-        List<HostMO> getHostsUsingDynamicDiscovery() {
-            return hostsUsingDynamicDiscovery;
-        }
-
-        List<HostMO> getHostsUsingStaticDiscovery() {
-            return hostsUsingStaticDiscovery;
-        }
-    }
-
-    private HostDiscoveryMethod getHostDiscoveryMethod(VmwareContext context, String address,
-                                                       List<Pair<ManagedObjectReference, String>> hostPairs) throws Exception {
-        List<HostMO> hosts = new ArrayList<>();
-
-        for (Pair<ManagedObjectReference, String> hostPair : hostPairs) {
-            HostMO host = new HostMO(context, hostPair.first());
-
-            hosts.add(host);
-        }
-
-        return getHostDiscoveryMethod(address, hosts);
-    }
-
-    private HostDiscoveryMethod getHostDiscoveryMethod(String address, List<HostMO> lstHosts) throws Exception {
-        List<HostMO> hostsUsingDynamicDiscovery = new ArrayList<>();
-        List<HostMO> hostsUsingStaticDiscovery = new ArrayList<>();
-
-        for (HostMO host : lstHosts) {
-            boolean usingDynamicDiscovery = false;
-
-            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
-
-            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-                if (hba instanceof HostInternetScsiHba) {
-                    HostInternetScsiHba hostInternetScsiHba = (HostInternetScsiHba)hba;
-
-                    if (hostInternetScsiHba.isIsSoftwareBased()) {
-                        List<HostInternetScsiHbaSendTarget> sendTargets = hostInternetScsiHba.getConfiguredSendTarget();
-
-                        if (sendTargets != null) {
-                            for (HostInternetScsiHbaSendTarget sendTarget : sendTargets) {
-                                String sendTargetAddress = sendTarget.getAddress();
-
-                                if (sendTargetAddress.contains(address)) {
-                                    usingDynamicDiscovery = true;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (usingDynamicDiscovery) {
-                hostsUsingDynamicDiscovery.add(host);
-            }
-            else {
-                hostsUsingStaticDiscovery.add(host);
-            }
-        }
-
-        return new HostDiscoveryMethod(hostsUsingDynamicDiscovery, hostsUsingStaticDiscovery);
-    }
-
-    private ManagedObjectReference getVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
-                                                    String iqn, String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception {
-        ManagedObjectReference morDs;
-
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO cluster = new ClusterMO(context, morCluster);
-        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
-
-        Pair<ManagedObjectReference, String> firstHost = lstHosts.get(0);
-        HostMO firstHostMO = new HostMO(context, firstHost.first());
-        HostDatastoreSystemMO firstHostDatastoreSystemMO = firstHostMO.getHostDatastoreSystemMO();
-
-        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageIpAddress, lstHosts);
-        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-            List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageIpAddress, storagePortNumber, iqn,
-                    chapName, chapSecret, mutualChapName, mutualChapSecret);
-
-            addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
-        }
-
-        rescanAllHosts(context, lstHosts, true, false);
-
-        HostStorageSystemMO firstHostStorageSystem = firstHostMO.getHostStorageSystemMO();
-        List<HostScsiDisk> lstHostScsiDisks = firstHostDatastoreSystemMO.queryAvailableDisksForVmfs();
-
-        HostScsiDisk hostScsiDisk = getHostScsiDisk(firstHostStorageSystem.getStorageDeviceInfo().getScsiTopology(), lstHostScsiDisks, iqn);
-
-        if (hostScsiDisk == null) {
-            rescanAllHosts(context, lstHosts, false, true);
-
-            morDs = firstHostDatastoreSystemMO.findDatastoreByName(datastoreName);
-
-            if (morDs != null) {
-                waitForAllHostsToSeeDatastore(lstHosts, new DatastoreMO(context, morDs));
-
-                mountVmfsDatastore(new DatastoreMO(context, morDs), lstHosts);
-
-                expandDatastore(firstHostDatastoreSystemMO, new DatastoreMO(context, morDs));
-
-                return morDs;
-            }
-
-            throw new Exception("A relevant SCSI disk could not be located to use to create a datastore.");
-        }
-
-        morDs = firstHostDatastoreSystemMO.createVmfsDatastore(datastoreName, hostScsiDisk);
-
-        if (morDs != null) {
-            waitForAllHostsToMountDatastore(lstHosts, new DatastoreMO(context, morDs));
-
-            expandDatastore(firstHostDatastoreSystemMO, new DatastoreMO(context, morDs));
-
-            return morDs;
-        }
-
-        throw new Exception("Unable to create a datastore");
-    }
-
-    private void waitForAllHostsToSeeDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
-        long secondsToWait = 120;
-        long endWaitTime = System.currentTimeMillis() + secondsToWait * 1000;
-
-        boolean isConditionMet = false;
-
-        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
-            Thread.sleep(5000);
-
-            isConditionMet = verifyAllHostsSeeDatastore(lstHosts, dsMO);
-        }
-
-        if (!isConditionMet) {
-            throw new CloudRuntimeException("Not all hosts mounted the datastore");
-        }
-    }
-
-    private boolean verifyAllHostsSeeDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
-        int numHostsChecked = 0;
-
-        for (Pair<ManagedObjectReference, String> host: lstHosts) {
-            ManagedObjectReference morHostToMatch = host.first();
-            HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
-
-            List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
-
-            for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
-                ManagedObjectReference morHost = datastoreHostMount.getKey();
-                HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
-
-                if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
-                    numHostsChecked++;
-                }
-            }
-        }
-
-        return lstHosts.size() == numHostsChecked;
-    }
-
-    private void waitForAllHostsToMountDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
-        long secondsToWait = 120;
-        long endWaitTime = System.currentTimeMillis() + secondsToWait * 1000;
-
-        boolean isConditionMet = false;
-
-        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
-            Thread.sleep(5000);
-
-            isConditionMet = verifyAllHostsMountedDatastore(lstHosts, dsMO);
-        }
-
-        if (!isConditionMet) {
-            throw new CloudRuntimeException("Not all hosts mounted the datastore");
-        }
-    }
-
-    private boolean verifyAllHostsMountedDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
-        int numHostsChecked = 0;
-
-        for (Pair<ManagedObjectReference, String> host: lstHosts) {
-            ManagedObjectReference morHostToMatch = host.first();
-            HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
-
-            List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
-
-            for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
-                ManagedObjectReference morHost = datastoreHostMount.getKey();
-                HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
-
-                if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
-                    if (datastoreHostMount.getMountInfo().isMounted() && datastoreHostMount.getMountInfo().isAccessible()) {
-                        numHostsChecked++;
-                    }
-                    else {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return lstHosts.size() == numHostsChecked;
-    }
-
-    // the purpose of this method is to find the HostScsiDisk in the passed-in array that exists (if any) because
-    // we added the static iqn to an iSCSI HBA
-    private static HostScsiDisk getHostScsiDisk(HostScsiTopology hst, List<HostScsiDisk> lstHostScsiDisks, String iqn) {
-        for (HostScsiTopologyInterface adapter : hst.getAdapter()) {
-            if (adapter.getTarget() != null) {
-                for (HostScsiTopologyTarget target : adapter.getTarget()) {
-                    if (target.getTransport() instanceof HostInternetScsiTargetTransport) {
-                        String iScsiName = ((HostInternetScsiTargetTransport)target.getTransport()).getIScsiName();
-
-                        if (iqn.equals(iScsiName)) {
-                            for (HostScsiDisk hostScsiDisk : lstHostScsiDisks) {
-                                for (HostScsiTopologyLun hstl : target.getLun()) {
-                                    if (hstl.getScsiLun().contains(hostScsiDisk.getUuid())) {
-                                        return hostScsiDisk;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private boolean isDatastoreMounted(DatastoreMO dsMO, HostMO hostToMatchMO) throws Exception {
-        List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
-
-        for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
-            ManagedObjectReference morHost = datastoreHostMount.getKey();
-            HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
-
-            if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
-                return datastoreHostMount.getMountInfo().isMounted();
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate the applicable host");
-    }
-
-    private String getDatastoreUuid(DatastoreMO dsMO, HostMO hostToMatchMO) throws Exception {
-        List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
-
-        for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
-            ManagedObjectReference morHost = datastoreHostMount.getKey();
-            HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
-
-            if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
-                String path = datastoreHostMount.getMountInfo().getPath();
-
-                String searchStr = "/vmfs/volumes/";
-                int index = path.indexOf(searchStr);
-
-                if (index == -1) {
-                    throw new CloudRuntimeException("Unable to find the following search string: " + searchStr);
-                }
-
-                return path.substring(index + searchStr.length());
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate the UUID of the datastore");
-    }
-
-    private void mountVmfsDatastore(DatastoreMO dsMO, List<Pair<ManagedObjectReference, String>> hosts) throws Exception {
-        for (Pair<ManagedObjectReference, String> host : hosts) {
-            HostMO hostMO = new HostMO(dsMO.getContext(), host.first());
-
-            if (!isDatastoreMounted(dsMO, hostMO)) {
-                HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
-
-                try {
-                    hostStorageSystemMO.mountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
-                }
-                catch (InvalidStateFaultMsg ex) {
-                    List<Pair<ManagedObjectReference, String>> currentHosts = new ArrayList<>(1);
-
-                    currentHosts.add(host);
-
-                    waitForAllHostsToMountDatastore(currentHosts, dsMO);
-                }
-            }
-        }
-    }
-
-    private void unmountVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
-                                      List<Pair<ManagedObjectReference, String>> hosts) throws Exception {
-        ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
-        DatastoreMO dsMO = new DatastoreMO(context, morDs);
-
-        for (Pair<ManagedObjectReference, String> host : hosts) {
-            HostMO hostMO = new HostMO(context, host.first());
-
-            HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
-
-            hostStorageSystemMO.unmountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
-        }
-    }
-
-    private List<HostInternetScsiHbaStaticTarget> getTargets(List<Map<String, String>> targets) {
-        List<HostInternetScsiHbaStaticTarget> iScsiTargets = new ArrayList<>();
-
-        for (Map<String, String> target : targets) {
-            HostInternetScsiHbaStaticTarget iScsiTarget = new HostInternetScsiHbaStaticTarget();
-
-            iScsiTarget.setAddress(target.get(ModifyTargetsCommand.STORAGE_HOST));
-            iScsiTarget.setPort(Integer.parseInt(target.get(ModifyTargetsCommand.STORAGE_PORT)));
-            iScsiTarget.setIScsiName(trimIqn(target.get(ModifyTargetsCommand.IQN)));
-
-            iScsiTargets.add(iScsiTarget);
-        }
-
-        return iScsiTargets;
-    }
-
-    private void removeVmfsDatastore(Command cmd, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
-                                     String iqn) throws Exception {
-        VmwareContext context = hostService.getServiceContext(cmd);
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO cluster = new ClusterMO(context, morCluster);
-        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
-
-        removeVmfsDatastore(cmd, hyperHost, datastoreName, storageIpAddress, storagePortNumber, iqn, lstHosts);
-    }
-
-    private void removeVmfsDatastore(Command cmd, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
-                                     String iqn, List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
-        VmwareContext context = hostService.getServiceContext(cmd);
-
-        unmountVmfsDatastore(context, hyperHost, datastoreName, lstHosts);
-
-        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageIpAddress, lstHosts);
-        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-            HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
-
-            target.setAddress(storageIpAddress);
-            target.setPort(storagePortNumber);
-            target.setIScsiName(iqn);
-
-            final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<>();
-
-            lstTargets.add(target);
-
-            addRemoveInternetScsiTargetsToAllHosts(false, lstTargets, hostsUsingStaticDiscovery);
-
-            rescanAllHosts(hostsUsingStaticDiscovery, true, false);
-        }
-    }
-
-    private void createVmdk(Command cmd, DatastoreMO dsMo, String vmdkDatastorePath, Long volumeSize) throws Exception {
-        VmwareContext context = hostService.getServiceContext(null);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-
-        String dummyVmName = hostService.getWorkerName(context, cmd, 0);
-
-        VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
-
-        if (vmMo == null) {
-            throw new Exception("Unable to create a dummy VM for volume creation");
-        }
-
-        Long volumeSizeToUse = volumeSize < dsMo.getSummary().getFreeSpace() ? volumeSize : dsMo.getSummary().getFreeSpace();
-
-        vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey());
-        vmMo.detachDisk(vmdkDatastorePath, false);
-        vmMo.destroy();
-    }
-
-    private static int getMBsFromBytes(long bytes) {
-        return (int)(bytes / (1024L * 1024L));
-    }
-
-    public void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove, boolean isRemoveAsync,
-                              List<Map<String, String>> targets, List<HostMO> lstHosts) throws Exception {
-        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
-
-        for (HostMO host : lstHosts) {
-            List<HostMO> hosts = new ArrayList<>();
-
-            hosts.add(host);
-
-            List<Map<String, String>> dynamicTargetsForHost = new ArrayList<>();
-            List<Map<String, String>> staticTargetsForHost = new ArrayList<>();
-
-            for (Map<String, String> target : targets) {
-                String storageAddress = target.get(ModifyTargetsCommand.STORAGE_HOST);
-
-                HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(storageAddress, hosts);
-                List<HostMO> hostsUsingDynamicDiscovery = hostDiscoveryMethod.getHostsUsingDynamicDiscovery();
-
-                if (hostsUsingDynamicDiscovery != null && hostsUsingDynamicDiscovery.size() > 0) {
-                    dynamicTargetsForHost.add(target);
-                }
-                else {
-                    staticTargetsForHost.add(target);
-                }
-            }
-
-            if (add) {
-                executorService.submit(new Thread(() -> {
-                    try {
-                        boolean rescan = false;
-
-                        if (staticTargetsForHost.size() > 0) {
-                            addRemoveInternetScsiTargetsToAllHosts(true, getTargets(staticTargetsForHost), hosts);
-
-                            rescan = true;
-                        }
-
-                        if (dynamicTargetsForHost.size() > 0) {
-                            rescan = true;
-                        }
-
-                        if (rescan) {
-                            rescanAllHosts(hosts, true, false);
-                        }
-                    }
-                    catch (Exception ex) {
-                        s_logger.warn(ex.getMessage());
-                    }
-                }));
-            }
-            else {
-                List<HostInternetScsiHbaStaticTarget> targetsToRemove = new ArrayList<>();
-
-                if (staticTargetsForHost.size() > 0 &&
-                        (ModifyTargetsCommand.TargetTypeToRemove.STATIC.equals(targetTypeToRemove) || ModifyTargetsCommand.TargetTypeToRemove.BOTH.equals(targetTypeToRemove))) {
-                    targetsToRemove.addAll(getTargets(staticTargetsForHost));
-                }
-
-                if (dynamicTargetsForHost.size() > 0 &&
-                        (ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC.equals(targetTypeToRemove) || ModifyTargetsCommand.TargetTypeToRemove.BOTH.equals(targetTypeToRemove))) {
-                    targetsToRemove.addAll(getTargets(dynamicTargetsForHost));
-                }
-
-                if (targetsToRemove.size() > 0) {
-                    if (isRemoveAsync) {
-                        new Thread(() -> {
-                            try {
-                                addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
-
-                                rescanAllHosts(hosts, true, false);
-                            } catch (Exception ex) {
-                                s_logger.warn(ex.getMessage());
-                            }
-                        }).start();
-                    } else {
-                        executorService.submit(new Thread(() -> {
-                            try {
-                                addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
-
-                                rescanAllHosts(hosts, true, false);
-                            }
-                            catch (Exception ex) {
-                                s_logger.warn(ex.getMessage());
-                            }
-                        }));
-                    }
-                }
-            }
-        }
-
-        executorService.shutdown();
-
-        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
-            throw new Exception("The system timed out before completing the task 'handleTargets'.");
-        }
-    }
-
-    private void addRemoveInternetScsiTargetsToAllHosts(VmwareContext context, final boolean add, final List<HostInternetScsiHbaStaticTarget> targets,
-                                                        List<Pair<ManagedObjectReference, String>> hostPairs) throws Exception {
-        List<HostMO> hosts = new ArrayList<>();
-
-        for (Pair<ManagedObjectReference, String> hostPair : hostPairs) {
-            HostMO host = new HostMO(context, hostPair.first());
-
-            hosts.add(host);
-        }
-
-        addRemoveInternetScsiTargetsToAllHosts(add, targets, hosts);
-    }
-
-    private void addRemoveInternetScsiTargetsToAllHosts(boolean add, List<HostInternetScsiHbaStaticTarget> targets,
-                                                        List<HostMO> hosts) throws Exception {
-        ExecutorService executorService = Executors.newFixedThreadPool(hosts.size());
-
-        final List<Exception> exceptions = new ArrayList<>();
-
-        for (HostMO host : hosts) {
-            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
-
-            boolean iScsiHbaConfigured = false;
-
-            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-                if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
-                    iScsiHbaConfigured = true;
-
-                    final String iScsiHbaDevice = hba.getDevice();
-
-                    final HostStorageSystemMO hss = hostStorageSystem;
-
-                    executorService.submit(new Thread(() -> {
-                        try {
-                            if (add) {
-                                hss.addInternetScsiStaticTargets(iScsiHbaDevice, targets);
-                            } else {
-                                hss.removeInternetScsiStaticTargets(iScsiHbaDevice, targets);
-                            }
-                        } catch (Exception ex) {
-                            synchronized (exceptions) {
-                                exceptions.add(ex);
-                            }
-                        }
-                    }));
-                }
-            }
-
-            if (!iScsiHbaConfigured) {
-                throw new Exception("An iSCSI HBA must be configured before a host can use iSCSI storage.");
-            }
-        }
-
-        executorService.shutdown();
-
-        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
-            throw new Exception("The system timed out before completing the task 'addRemoveInternetScsiTargetsToAllHosts'.");
-        }
-
-        if (exceptions.size() > 0) {
-            throw new Exception(exceptions.get(0).getMessage());
-        }
-    }
-
-    private void rescanAllHosts(VmwareContext context, List<Pair<ManagedObjectReference, String>> lstHostPairs, boolean rescanHba, boolean rescanVmfs) throws Exception {
-        List<HostMO> hosts = new ArrayList<>(lstHostPairs.size());
-
-        for (Pair<ManagedObjectReference, String> hostPair : lstHostPairs) {
-            HostMO host = new HostMO(context, hostPair.first());
-
-            hosts.add(host);
-        }
-
-        rescanAllHosts(hosts, rescanHba, rescanVmfs);
-    }
-
-    private void rescanAllHosts(List<HostMO> lstHosts, boolean rescanHba, boolean rescanVmfs) throws Exception {
-        if (!rescanHba && !rescanVmfs) {
-            // nothing to do
-            return;
-        }
-
-        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
-
-        final List<Exception> exceptions = new ArrayList<>();
-
-        for (HostMO host : lstHosts) {
-            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
-
-            boolean iScsiHbaConfigured = false;
-
-            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-                if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
-                    iScsiHbaConfigured = true;
-
-                    final String iScsiHbaDevice = hba.getDevice();
-
-                    final HostStorageSystemMO hss = hostStorageSystem;
-
-                    executorService.submit(new Thread(() -> {
-                        try {
-                            if (rescanHba) {
-                                hss.rescanHba(iScsiHbaDevice);
-                            }
-
-                            if (rescanVmfs) {
-                                hss.rescanVmfs();
-                            }
-                        } catch (Exception ex) {
-                            synchronized (exceptions) {
-                                exceptions.add(ex);
-                            }
-                        }
-                    }));
-                }
-            }
-
-            if (!iScsiHbaConfigured) {
-                throw new Exception("An iSCSI HBA must be configured before a host can use iSCSI storage.");
-            }
-        }
-
-        executorService.shutdown();
-
-        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
-            throw new Exception("The system timed out before completing the task 'rescanAllHosts'.");
-        }
-
-        if (exceptions.size() > 0) {
-            throw new Exception(exceptions.get(0).getMessage());
-        }
-    }
-
-    private static String trimIqn(String iqn) {
-        String[] tmp = iqn.split("/");
-
-        if (tmp.length != 3) {
-            String msg = "Wrong format for iSCSI path: " + iqn + ". It should be formatted as '/targetIQN/LUN'.";
-
-            s_logger.warn(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        return tmp[1].trim();
-    }
-
-    public ManagedObjectReference prepareManagedStorage(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
-                                                        String storageHost, int storagePort, String volumeName, String chapInitiatorUsername, String chapInitiatorSecret,
-                                                        String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception {
-
-        ManagedObjectReference morDs = prepareManagedDatastore(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort,
-                chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-
-        DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs);
-
-        String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeName != null ? volumeName : dsMo.getName());
-
-        if (!dsMo.fileExists(volumeDatastorePath)) {
-            createVmdk(cmd, dsMo, volumeDatastorePath, size);
-        }
-
-        return morDs;
-    }
-
-    public void handleDatastoreAndVmdkDetach(Command cmd, String datastoreName, String iqn, String storageHost, int storagePort) throws Exception {
-        VmwareContext context = hostService.getServiceContext(null);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-
-        removeVmfsDatastore(cmd, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iqn));
-    }
-
-    private void handleDatastoreAndVmdkDetachManaged(Command cmd, String diskUuid, String iqn, String storageHost, int storagePort) throws Exception {
-        if (storagePort == DEFAULT_NFS_PORT) {
-            VmwareContext context = hostService.getServiceContext(null);
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-            // for managed NFS datastore
-            hyperHost.unmountDatastore(diskUuid);
-        } else {
-            handleDatastoreAndVmdkDetach(cmd, VmwareResource.getDatastoreName(iqn), iqn, storageHost, storagePort);
-        }
-    }
-
-    private class ManagedTarget {
-        private final String storageAddress;
-        private final int storagePort;
-        private final String iqn;
-
-        ManagedTarget(String storageAddress, int storagePort, String iqn) {
-            this.storageAddress = storageAddress;
-            this.storagePort = storagePort;
-            this.iqn = iqn;
-        }
-
-        public String toString() {
-            return storageAddress + storagePort + iqn;
-        }
-    }
-
-    private void removeManagedTargetsFromCluster(List<String> managedDatastoreNames) throws Exception {
-        List<HostInternetScsiHbaStaticTarget> lstManagedTargets = new ArrayList<>();
-
-        VmwareContext context = hostService.getServiceContext(null);
-        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        ClusterMO cluster = new ClusterMO(context, morCluster);
-        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
-        HostMO hostMO = new HostMO(context, lstHosts.get(0).first());
-        HostStorageSystemMO hostStorageSystem = hostMO.getHostStorageSystemMO();
-
-        for (String managedDatastoreName : managedDatastoreNames) {
-            unmountVmfsDatastore(context, hyperHost, managedDatastoreName, lstHosts);
-        }
-
-        for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
-            if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
-                List<HostInternetScsiHbaStaticTarget> lstTargets = ((HostInternetScsiHba)hba).getConfiguredStaticTarget();
-
-                if (lstTargets != null) {
-                    for (HostInternetScsiHbaStaticTarget target : lstTargets) {
-                        if (managedDatastoreNames.contains(VmwareResource.createDatastoreNameFromIqn(target.getIScsiName()))) {
-                            lstManagedTargets.add(target);
-                        }
-                    }
-                }
-            }
-        }
-
-        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
-
-        for (Pair<ManagedObjectReference, String> host : lstHosts) {
-            List<Pair<ManagedObjectReference, String>> hosts = new ArrayList<>();
-
-            hosts.add(host);
-
-            List<HostInternetScsiHbaStaticTarget> staticTargetsForHost = new ArrayList<>();
-
-            for (HostInternetScsiHbaStaticTarget iScsiManagedTarget : lstManagedTargets) {
-                String storageAddress = iScsiManagedTarget.getAddress();
-
-                HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageAddress, hosts);
-                List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
-
-                if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
-                    staticTargetsForHost.add(iScsiManagedTarget);
-                }
-            }
-
-            if (staticTargetsForHost.size() > 0) {
-                executorService.submit(new Thread(() -> {
-                    try {
-                        addRemoveInternetScsiTargetsToAllHosts(context, false, staticTargetsForHost, hosts);
-
-                        rescanAllHosts(context, hosts, true, false);
-                    }
-                    catch (Exception ex) {
-                        s_logger.warn(ex.getMessage());
-                    }
-                }));
-            }
-        }
-
-        executorService.shutdown();
-
-        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
-            throw new Exception("The system timed out before completing the task 'removeManagedTargetsFromCluster'.");
-        }
-    }
-
-    private List<String> getManagedDatastoreNamesFromVirtualDisks(List<VirtualDisk> virtualDisks) {
-        List<String> managedDatastoreNames = new ArrayList<>();
-
-        if (virtualDisks != null) {
-            for (VirtualDisk virtualDisk : virtualDisks) {
-                if (virtualDisk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
-                    VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
-                    String path = backingInfo.getFileName();
-
-                    String search = "[-";
-                    int index = path.indexOf(search);
-
-                    if (index > -1) {
-                        path = path.substring(index + search.length());
-
-                        String search2 = "-0]";
-
-                        index = path.lastIndexOf(search2);
-
-                        if (index > -1) {
-                            path = path.substring(0, index);
-
-                            if (path.startsWith("iqn.")) {
-                                managedDatastoreNames.add("-" + path + "-0");
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return managedDatastoreNames;
-    }
-
-    private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
-                                             String backupName, long wait, Integer nfsVersion) throws Exception {
-
-        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
-        String srcOVAFileName;
-        String srcOVFFileName;
-
-        srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension();
-        srcOVFFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + ".ovf";
-
-        String snapshotDir = "";
-        if (backupName.contains("/")) {
-            snapshotDir = backupName.split("/")[0];
-        }
-
-        File ovafile = new File(srcOVAFileName);
-
-        File ovfFile = new File(srcOVFFileName);
-        // String srcFileName = getOVFFilePath(srcOVAFileName);
-        if (!ovfFile.exists()) {
-            srcOVFFileName = getOVFFilePath(srcOVAFileName);
-            if (srcOVFFileName == null && ovafile.exists()) {  // volss: ova file exists; o/w can't do tar
-                Script command = new Script("tar", wait, s_logger);
-                command.add("--no-same-owner");
-                command.add("-xf", srcOVAFileName);
-                command.setWorkDir(secondaryMountPoint + "/" + secStorageDir + "/" + snapshotDir);
-                s_logger.info("Executing command: " + command.toString());
-                String result = command.execute();
-                if (result != null) {
-                    String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-                srcOVFFileName = getOVFFilePath(srcOVAFileName);
-            } else if (srcOVFFileName == null) {
-                String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-        }
-        if (srcOVFFileName == null) {
-            String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
-            s_logger.error(msg);
-            throw new Exception(msg);
-        }
-
-        VirtualMachineMO clonedVm = null;
-        try {
-            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin");
-            clonedVm = hyperHost.findVmOnHyperHost(newVolumeName);
-            if (clonedVm == null) {
-                throw new Exception("Unable to create container VM for volume creation");
-            }
-
-            clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false);
-            clonedVm.detachAllDisks();
-            return _storage.getSize(srcOVFFileName);
-        } finally {
-            if (clonedVm != null) {
-                clonedVm.detachAllDisks();
-                clonedVm.destroy();
-            }
-        }
-    }
-
-    @Override
-    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO pool = destData.getDataStore();
-        DataStoreTO imageStore = srcData.getDataStore();
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        NfsTO nfsImageStore = (NfsTO)imageStore;
-        String primaryStorageNameLabel = pool.getUuid();
-
-        String secondaryStorageUrl = nfsImageStore.getUrl();
-        String backedUpSnapshotUuid = snapshot.getPath();
-        int index = backedUpSnapshotUuid.lastIndexOf(File.separator);
-        String backupPath = backedUpSnapshotUuid.substring(0, index);
-        backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 1);
-        String details;
-        String newVolumeName = VmwareHelper.getVCenterSafeUuid();
-
-        VmwareContext context = hostService.getServiceContext(cmd);
-        try {
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-            ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStorageNameLabel);
-            if (morPrimaryDs == null) {
-                String msg = "Unable to find datastore: " + primaryStorageNameLabel;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            // strip off the extension since restoreVolumeFromSecStorage internally will append suffix there.
-            if (backedUpSnapshotUuid.endsWith(".ova")){
-                backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ova", "");
-            } else if (backedUpSnapshotUuid.endsWith(".ovf")){
-                backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
-            }
-            DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
-            restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion);
-
-            VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(newVolumeName);
-            return new CopyCmdAnswer(newVol);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-
-            s_logger.error("Unexpecpted exception ", e);
-            details = "create volume from snapshot exception: " + VmwareHelper.getExceptionMessage(e);
-        }
-        return new CopyCmdAnswer(details);
-    }
-
-    @Override
-    public Answer deleteSnapshot(DeleteCommand cmd) {
-        SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData();
-        DataStoreTO store = snapshot.getDataStore();
-        if (store.getRole() == DataStoreRole.Primary) {
-            return new Answer(cmd);
-        } else {
-            return new Answer(cmd, false, "unsupported command");
-        }
-    }
-
-    @Override
-    public Answer introduceObject(IntroduceObjectCmd cmd) {
-        return new Answer(cmd, false, "not implememented yet");
-    }
-
-    @Override
-    public Answer forgetObject(ForgetObjectCmd cmd) {
-        return new Answer(cmd, false, "not implememented yet");
-    }
-
-    private static String deriveTemplateUuidOnHost(VmwareHypervisorHost hyperHost, String storeIdentifier, String templateName) {
-        String templateUuid;
-        try{
-            templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes("UTF-8")).toString();
-        }catch(UnsupportedEncodingException e){
-            s_logger.warn("unexpected encoding error, using default Charset: " + e.getLocalizedMessage());
-            templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes(Charset.defaultCharset()))
-                    .toString();
-        }
-        templateUuid = templateUuid.replaceAll("-", "");
-        return templateUuid;
-    }
-
-    private String getLegacyVmDataDiskController() throws Exception {
-        return DiskControllerType.lsilogic.toString();
-    }
-
-    void setNfsVersion(Integer nfsVersion){
-        this._nfsVersion = nfsVersion;
-        s_logger.debug("VmwareProcessor instance now using NFS version: " + nfsVersion);
-    }
-
-    void setFullCloneFlag(boolean value){
-        this._fullCloneFlag = value;
-        s_logger.debug("VmwareProcessor instance - create full clone = " + (value ? "TRUE" : "FALSE"));
-    }
-
-    @Override
-    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
-        return null;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/api/commands/DeleteCiscoNexusVSMCmd.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/DeleteCiscoNexusVSMCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/api/commands/DeleteCiscoNexusVSMCmd.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/DeleteCiscoNexusVSMCmd.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/api/commands/DisableCiscoNexusVSMCmd.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/DisableCiscoNexusVSMCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/api/commands/DisableCiscoNexusVSMCmd.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/DisableCiscoNexusVSMCmd.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/api/commands/EnableCiscoNexusVSMCmd.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/EnableCiscoNexusVSMCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/api/commands/EnableCiscoNexusVSMCmd.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/EnableCiscoNexusVSMCmd.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/api/commands/ListCiscoNexusVSMsCmd.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/ListCiscoNexusVSMsCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/api/commands/ListCiscoNexusVSMsCmd.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/api/commands/ListCiscoNexusVSMsCmd.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/api/response/CiscoNexusVSMResponse.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/api/response/CiscoNexusVSMResponse.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/api/response/CiscoNexusVSMResponse.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/api/response/CiscoNexusVSMResponse.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/ha/VmwareFencer.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/ha/VmwareFencer.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/ha/VmwareFencer.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/ha/VmwareFencer.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/ha/VmwareInvestigator.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/ha/VmwareInvestigator.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/ha/VmwareInvestigator.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/ha/VmwareInvestigator.java
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
new file mode 100644
index 0000000..10c3feb
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -0,0 +1,681 @@
+// 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.guru;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import com.cloud.agent.api.MigrateVmToPoolCommand;
+import com.cloud.agent.api.UnregisterVMCommand;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.storage.StoragePool;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.UnregisterNicCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.CreateVolumeOVACommand;
+import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruBase;
+import com.cloud.hypervisor.vmware.manager.VmwareManager;
+import com.cloud.hypervisor.vmware.mo.DiskControllerType;
+import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.secstorage.CommandExecLogVO;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.GuestOSHypervisorVO;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.GuestOSHypervisorDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VmDetailConstants;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
+    private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
+
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private GuestOSDao _guestOsDao;
+    @Inject
+    private GuestOSHypervisorDao _guestOsHypervisorDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private HostDetailsDao _hostDetailsDao;
+    @Inject
+    private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private CommandExecLogDao _cmdExecLogDao;
+    @Inject
+    private VmwareManager _vmwareMgr;
+    @Inject
+    private SecondaryStorageVmManager _secStorageMgr;
+    @Inject
+    private NetworkModel _networkMgr;
+    @Inject
+    private NicDao _nicDao;
+    @Inject
+    private DomainRouterDao _domainRouterDao;
+    @Inject
+    private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private ClusterManager _clusterMgr;
+    @Inject
+    VolumeDao _volumeDao;
+    @Inject
+    PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    VolumeDataFactory _volFactory;
+
+    protected VMwareGuru() {
+        super();
+    }
+
+    public static final ConfigKey<Boolean> VmwareReserveCpu = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.cpu", "Advanced", "false",
+        "Specify whether or not to reserve CPU when not overprovisioning, In case of cpu overprovisioning we will always reserve cpu.", true, ConfigKey.Scope.Cluster,
+        null);
+
+    public static final ConfigKey<Boolean> VmwareReserveMemory = new ConfigKey<Boolean>(Boolean.class, "vmware.reserve.mem", "Advanced", "false",
+        "Specify whether or not to reserve memory when not overprovisioning, In case of memory overprovisioning we will always reserve memory.", true,
+        ConfigKey.Scope.Cluster, null);
+
+    protected ConfigKey<Boolean> VmwareEnableNestedVirtualization = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization", "Advanced", "false",
+            "When set to true this will enable nested virtualization when this is supported by the hypervisor", true, ConfigKey.Scope.Global, null);
+
+    protected ConfigKey<Boolean> VmwareEnableNestedVirtualizationPerVM = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization.perVM", "Advanced", "false",
+            "When set to true this will enable nested virtualization per vm", true, ConfigKey.Scope.Global, null);
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.VMware;
+    }
+
+    @Override
+    public VirtualMachineTO implement(VirtualMachineProfile vm) {
+        VirtualMachineTO to = toVirtualMachineTO(vm);
+        to.setBootloader(BootloaderType.HVM);
+
+        Map<String, String> details = to.getDetails();
+        if (details == null)
+            details = new HashMap<String, String>();
+
+        Type vmType = vm.getType();
+        boolean userVm = !(vmType.equals(VirtualMachine.Type.DomainRouter) || vmType.equals(VirtualMachine.Type.ConsoleProxy)
+                || vmType.equals(VirtualMachine.Type.SecondaryStorageVm));
+
+        String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER);
+        if (!userVm) {
+
+            if (nicDeviceType == null) {
+                details.put(VmDetailConstants.NIC_ADAPTER, _vmwareMgr.getSystemVMDefaultNicAdapterType());
+            } else {
+                try {
+                    VirtualEthernetCardType.valueOf(nicDeviceType);
+                } catch (Exception e) {
+                    s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
+                    details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
+                }
+            }
+        } else {
+            // for user-VM, use E1000 as default
+            if (nicDeviceType == null) {
+                details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
+            } else {
+                try {
+                    VirtualEthernetCardType.valueOf(nicDeviceType);
+                } catch (Exception e) {
+                    s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
+                    details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
+                }
+            }
+        }
+
+        String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
+        if (userVm) {
+            if (diskDeviceType == null) {
+                details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
+            }
+        }
+        String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER);
+        if (userVm) {
+            if (diskController == null) {
+                details.put(VmDetailConstants.DATA_DISK_CONTROLLER, DiskControllerType.lsilogic.toString());
+            }
+        }
+
+        if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
+            details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
+        }
+
+        List<NicProfile> nicProfiles = vm.getNics();
+
+        for (NicProfile nicProfile : nicProfiles) {
+            if (nicProfile.getTrafficType() == TrafficType.Guest) {
+                if (_networkMgr.isProviderSupportServiceInNetwork(nicProfile.getNetworkId(), Service.Firewall, Provider.CiscoVnmc)) {
+                    details.put("ConfigureVServiceInNexus", Boolean.TRUE.toString());
+                }
+                break;
+            }
+        }
+
+        long clusterId = getClusterId(vm.getId());
+        details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
+        details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
+        to.setDetails(details);
+
+        if (vmType.equals(VirtualMachine.Type.DomainRouter)) {
+
+            NicProfile publicNicProfile = null;
+            for (NicProfile nicProfile : nicProfiles) {
+                if (nicProfile.getTrafficType() == TrafficType.Public) {
+                    publicNicProfile = nicProfile;
+                    break;
+                }
+            }
+
+            if (publicNicProfile != null) {
+                NicTO[] nics = to.getNics();
+
+                // reserve extra NICs
+                NicTO[] expandedNics = new NicTO[nics.length + _vmwareMgr.getRouterExtraPublicNics()];
+                int i = 0;
+                int deviceId = -1;
+                for (i = 0; i < nics.length; i++) {
+                    expandedNics[i] = nics[i];
+                    if (nics[i].getDeviceId() > deviceId)
+                        deviceId = nics[i].getDeviceId();
+                }
+                deviceId++;
+
+                long networkId = publicNicProfile.getNetworkId();
+                NetworkVO network = _networkDao.findById(networkId);
+
+                for (; i < nics.length + _vmwareMgr.getRouterExtraPublicNics(); i++) {
+                    NicTO nicTo = new NicTO();
+
+                    nicTo.setDeviceId(deviceId++);
+                    nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
+                    nicTo.setType(publicNicProfile.getTrafficType());
+                    nicTo.setIp("0.0.0.0");
+                    nicTo.setNetmask("255.255.255.255");
+
+                    try {
+                        String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
+                        nicTo.setMac(mac);
+                    } catch (InsufficientAddressCapacityException e) {
+                        throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
+                    }
+                    nicTo.setDns1(publicNicProfile.getIPv4Dns1());
+                    nicTo.setDns2(publicNicProfile.getIPv4Dns2());
+                    if (publicNicProfile.getIPv4Gateway() != null) {
+                        nicTo.setGateway(publicNicProfile.getIPv4Gateway());
+                    } else {
+                        nicTo.setGateway(network.getGateway());
+                    }
+                    nicTo.setDefaultNic(false);
+                    nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
+                    nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
+
+                    Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
+                    nicTo.setNetworkRateMbps(networkRate);
+
+                    expandedNics[i] = nicTo;
+                }
+
+                to.setNics(expandedNics);
+
+                VirtualMachine router = vm.getVirtualMachine();
+                DomainRouterVO routerVO = _domainRouterDao.findById(router.getId());
+                if (routerVO != null && routerVO.getIsRedundantRouter()) {
+                    Long peerRouterId = _nicDao.getPeerRouterId(publicNicProfile.getMacAddress(), router.getId());
+                    DomainRouterVO peerRouterVO = null;
+                    if (peerRouterId != null) {
+                        peerRouterVO = _domainRouterDao.findById(peerRouterId);
+                        if (peerRouterVO != null) {
+                            details.put("PeerRouterInstanceName", peerRouterVO.getInstanceName());
+                        }
+                    }
+                }
+            }
+
+            StringBuffer sbMacSequence = new StringBuffer();
+            for (NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
+                sbMacSequence.append(nicTo.getMac()).append("|");
+            }
+            if (!sbMacSequence.toString().isEmpty()) {
+                sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
+                String bootArgs = to.getBootArgs();
+                to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
+            }
+
+        }
+
+        // Don't do this if the virtual machine is one of the special types
+        // Should only be done on user machines
+        if (userVm) {
+            configureNestedVirtualization(details, to);
+        }
+        // Determine the VM's OS description
+        GuestOSVO guestOS = _guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
+        to.setOs(guestOS.getDisplayName());
+        to.setHostName(vm.getHostName());
+        HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
+        GuestOSHypervisorVO guestOsMapping = null;
+        if (host != null) {
+            guestOsMapping = _guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), getHypervisorType().toString(), host.getHypervisorVersion());
+        }
+        if (guestOsMapping == null || host == null) {
+            to.setPlatformEmulator(null);
+        } else {
+            to.setPlatformEmulator(guestOsMapping.getGuestOsName());
+        }
+        return to;
+    }
+
+    /**
+     * Decide in which cases nested virtualization should be enabled based on (1){@code globalNestedV}, (2){@code globalNestedVPerVM}, (3){@code localNestedV}<br/>
+     * Nested virtualization should be enabled when one of this cases:
+     * <ul>
+     * <li>(1)=TRUE, (2)=TRUE, (3) is NULL (missing)</li>
+     * <li>(1)=TRUE, (2)=TRUE, (3)=TRUE</li>
+     * <li>(1)=TRUE, (2)=FALSE</li>
+     * <li>(1)=FALSE, (2)=TRUE, (3)=TRUE</li>
+     * </ul>
+     * In any other case, it shouldn't be enabled
+     * @param globalNestedV value of {@code 'vmware.nested.virtualization'} global config
+     * @param globalNestedVPerVM value of {@code 'vmware.nested.virtualization.perVM'} global config
+     * @param localNestedV value of {@code 'nestedVirtualizationFlag'} key in vm details if present, null if not present
+     * @return "true" for cases in which nested virtualization is enabled, "false" if not
+     */
+    protected Boolean shouldEnableNestedVirtualization(Boolean globalNestedV, Boolean globalNestedVPerVM, String localNestedV){
+        if (globalNestedV == null || globalNestedVPerVM == null) {
+            return false;
+        }
+        boolean globalNV = globalNestedV.booleanValue();
+        boolean globalNVPVM = globalNestedVPerVM.booleanValue();
+
+        if (globalNVPVM){
+            return (localNestedV == null && globalNV) || BooleanUtils.toBoolean(localNestedV);
+        }
+        return globalNV;
+    }
+
+    /**
+     * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
+     * @param details vm details
+     * @param to vm to
+     */
+    protected void configureNestedVirtualization(Map<String, String> details, VirtualMachineTO to) {
+        Boolean globalNestedV = VmwareEnableNestedVirtualization.value();
+        Boolean globalNestedVPerVM = VmwareEnableNestedVirtualizationPerVM.value();
+        String localNestedV = details.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG);
+
+        Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedV, globalNestedVPerVM, localNestedV);
+        s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
+        details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Boolean.toString(shouldEnableNestedVirtualization));
+        to.setDetails(details);
+    }
+
+    private long getClusterId(long vmId) {
+        long clusterId;
+        Long hostId;
+
+        hostId = _vmDao.findById(vmId).getHostId();
+        if (hostId == null) {
+            // If VM is in stopped state then hostId would be undefined. Hence read last host's Id instead.
+            hostId = _vmDao.findById(vmId).getLastHostId();
+        }
+        clusterId = _hostDao.findById(hostId).getClusterId();
+
+        return clusterId;
+    }
+
+    private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
+
+        List<NicTO> listForSort = new ArrayList<NicTO>();
+        for (NicTO nic : nics) {
+            listForSort.add(nic);
+        }
+        Collections.sort(listForSort, new Comparator<NicTO>() {
+
+            @Override
+            public int compare(NicTO arg0, NicTO arg1) {
+                if (arg0.getDeviceId() < arg1.getDeviceId()) {
+                    return -1;
+                } else if (arg0.getDeviceId() == arg1.getDeviceId()) {
+                    return 0;
+                }
+
+                return 1;
+            }
+        });
+
+        return listForSort.toArray(new NicTO[0]);
+    }
+
+    @Override
+    @DB
+    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
+        boolean needDelegation = false;
+        if (cmd instanceof StorageSubSystemCommand) {
+            Boolean fullCloneEnabled = VmwareFullClone.value();
+            StorageSubSystemCommand c = (StorageSubSystemCommand)cmd;
+            c.setExecuteInSequence(fullCloneEnabled);
+        }
+        if (cmd instanceof DownloadCommand) {
+          cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
+        }
+        //NOTE: the hostid can be a hypervisor host, or a ssvm agent. For copycommand, if it's for volume upload, the hypervisor
+        //type is empty, so we need to check the format of volume at first.
+        if (cmd instanceof CopyCommand) {
+            CopyCommand cpyCommand = (CopyCommand) cmd;
+            DataTO srcData = cpyCommand.getSrcTO();
+            DataStoreTO srcStoreTO = srcData.getDataStore();
+            DataTO destData = cpyCommand.getDestTO();
+            DataStoreTO destStoreTO = destData.getDataStore();
+
+            boolean inSeq = true;
+            if ((srcData.getObjectType() == DataObjectType.SNAPSHOT) || (destData.getObjectType() == DataObjectType.SNAPSHOT)) {
+                inSeq = false;
+            } else if ((destStoreTO.getRole() == DataStoreRole.Image) || (destStoreTO.getRole() == DataStoreRole.ImageCache)) {
+                inSeq = false;
+            } else if (!VmwareFullClone.value()) {
+                inSeq = false;
+            }
+            cpyCommand.setExecuteInSequence(inSeq);
+
+            if (srcData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)srcData;
+                if (Storage.ImageFormat.OVA == volumeObjectTO.getFormat()) {
+                    needDelegation = true;
+                }
+            }
+
+            if (!needDelegation && !(HypervisorType.VMware == srcData.getHypervisorType() || HypervisorType.VMware == destData.getHypervisorType())) {
+                return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
+            }
+
+            if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary &&
+                srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) {
+                needDelegation = false;
+            } else {
+                needDelegation = true;
+            }
+        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
+            DataTO srcData = ((CreateEntityDownloadURLCommand)cmd).getData();
+            if ((HypervisorType.VMware == srcData.getHypervisorType())) {
+                needDelegation = true;
+            }
+            if (srcData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO volumeObjectTO = (VolumeObjectTO)srcData;
+                if (Storage.ImageFormat.OVA == volumeObjectTO.getFormat()) {
+                    needDelegation = true;
+                }
+            }
+        }
+
+        if (!needDelegation) {
+            return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
+        }
+        HostVO host = _hostDao.findById(hostId);
+        long dcId = host.getDataCenterId();
+        Pair<HostVO, SecondaryStorageVmVO> cmdTarget = _secStorageMgr.assignSecStorageVm(dcId, cmd);
+        if (cmdTarget != null) {
+            // TODO, we need to make sure agent is actually connected too
+
+            cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
+            if (host.getType() == Host.Type.Routing) {
+                Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
+                cmd.setContextParam("guid", resolveNameInGuid(hostDetails.get("guid")));
+                cmd.setContextParam("username", hostDetails.get("username"));
+                cmd.setContextParam("password", hostDetails.get("password"));
+                cmd.setContextParam("serviceconsole", _vmwareMgr.getServiceConsolePortGroupName());
+                cmd.setContextParam("manageportgroup", _vmwareMgr.getManagementPortGroupName());
+            }
+
+            CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
+            _cmdExecLogDao.persist(execLog);
+            cmd.setContextParam("execid", String.valueOf(execLog.getId()));
+            cmd.setContextParam("noderuninfo", String.format("%d-%d", _clusterMgr.getManagementNodeId(), _clusterMgr.getCurrentRunId()));
+            cmd.setContextParam("vCenterSessionTimeout", String.valueOf(_vmwareMgr.getVcenterSessionTimeout()));
+            cmd.setContextParam(VmwareManager.s_vmwareOVAPackageTimeout.key(), String.valueOf(VmwareManager.s_vmwareOVAPackageTimeout.value()));
+
+            if (cmd instanceof BackupSnapshotCommand || cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
+                cmd instanceof CreatePrivateTemplateFromSnapshotCommand || cmd instanceof CopyVolumeCommand || cmd instanceof CopyCommand ||
+                cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand || cmd instanceof CreateVolumeFromSnapshotCommand) {
+                String workerName = _vmwareMgr.composeWorkerName();
+                long checkPointId = 1;
+                // FIXME: Fix                    long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
+                cmd.setContextParam("worker", workerName);
+                cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
+
+                // some commands use 2 workers
+                String workerName2 = _vmwareMgr.composeWorkerName();
+                long checkPointId2 = 1;
+                // FIXME: Fix                    long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
+                cmd.setContextParam("worker2", workerName2);
+                cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
+                cmd.setContextParam("searchexludefolders", _vmwareMgr.s_vmwareSearchExcludeFolder.value());
+            }
+
+            return new Pair<Boolean, Long>(Boolean.TRUE, cmdTarget.first().getId());
+
+        }
+        return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
+    }
+
+    @Override
+    public boolean trackVmHostChange() {
+        return true;
+    }
+
+    private static String resolveNameInGuid(String guid) {
+        String tokens[] = guid.split("@");
+        assert (tokens.length == 2);
+
+        String vCenterIp = NetUtils.resolveToIp(tokens[1]);
+        if (vCenterIp == null) {
+            s_logger.error("Fatal : unable to resolve vCenter address " + tokens[1] + ", please check your DNS configuration");
+            return guid;
+        }
+
+        if (vCenterIp.equals(tokens[1]))
+            return guid;
+
+        return tokens[0] + "@" + vCenterIp;
+    }
+
+    @Override
+    public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
+        List<Command> commands = new ArrayList<Command>();
+        List<NicVO> nicVOs = _nicDao.listByVmId(vm.getId());
+        for (NicVO nic : nicVOs) {
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch) {
+                s_logger.debug("Nic " + nic.toString() + " is connected to an lswitch, cleanup required");
+                NetworkVO networkVO = _networkDao.findById(nic.getNetworkId());
+                // We need the traffic label to figure out which vSwitch has the
+                // portgroup
+                PhysicalNetworkTrafficTypeVO trafficTypeVO = _physicalNetworkTrafficTypeDao.findBy(networkVO.getPhysicalNetworkId(), networkVO.getTrafficType());
+                UnregisterNicCommand unregisterNicCommand =
+                    new UnregisterNicCommand(vm.getInstanceName(), trafficTypeVO.getVmwareNetworkLabel(), UUID.fromString(nic.getUuid()));
+                commands.add(unregisterNicCommand);
+            }
+        }
+        return commands;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VMwareGuru.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {VmwareReserveCpu, VmwareReserveMemory, VmwareEnableNestedVirtualization, VmwareEnableNestedVirtualizationPerVM};
+    }
+
+    @Override
+    public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
+        List<Command> commands = new ArrayList<Command>();
+
+        List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
+
+        if (volumes != null) {
+            for (VolumeVO volume : volumes) {
+                StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+
+                // storagePool should be null if we are expunging a volume that was never
+                // attached to a VM that was started (the "trick" for storagePool to be null
+                // is that none of the VMs this volume may have been attached to were ever started,
+                // so the volume was never assigned to a storage pool)
+                if (storagePool != null && storagePool.isManaged() && volume.getVolumeType() == Volume.Type.ROOT) {
+                    VolumeInfo volumeInfo = _volFactory.getVolume(volume.getId());
+                    PrimaryDataStore primaryDataStore = (PrimaryDataStore)volumeInfo.getDataStore();
+                    Map<String, String> details = primaryDataStore.getDetails();
+
+                    if (details == null) {
+                        details = new HashMap<String, String>();
+
+                        primaryDataStore.setDetails(details);
+                    }
+
+                    details.put(DiskTO.MANAGED, Boolean.TRUE.toString());
+
+                    DeleteCommand cmd = new DeleteCommand(volumeInfo.getTO());
+
+                    commands.add(cmd);
+
+                    break;
+                }
+            }
+        }
+
+        return commands;
+    }
+
+    @Override
+    public Map<String, String> getClusterSettings(long vmId) {
+        Map<String, String> details = new HashMap<String, String>();
+        long clusterId = getClusterId(vmId);
+        details.put(VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
+        details.put(VmwareReserveMemory.key(), VmwareReserveMemory.valueIn(clusterId).toString());
+        return details;
+    }
+
+    @Override
+    public List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination) {
+        List<Command> commands = new ArrayList<Command>();
+
+        // OfflineVmwareMigration: specialised migration command
+        List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
+        List<VolumeTO> vols = new ArrayList<>();
+        for (Volume volume : volumes) {
+            VolumeTO vol = new VolumeTO(volume,destination);
+            vols.add(vol);
+        }
+        MigrateVmToPoolCommand migrateVmToPoolCommand = new MigrateVmToPoolCommand(vm.getInstanceName(), vols, destination.getUuid(), true);
+        commands.add(migrateVmToPoolCommand);
+
+        // OfflineVmwareMigration: cleanup if needed
+        final Long destClusterId = destination.getClusterId();
+        final Long srcClusterId = getClusterId(vm.getId());
+
+        if (srcClusterId != null && destClusterId != null && ! srcClusterId.equals(destClusterId)) {
+            final String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
+            final String destDcName = _clusterDetailsDao.getVmwareDcName(destClusterId);
+            if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
+                final UnregisterVMCommand unregisterVMCommand = new UnregisterVMCommand(vm.getInstanceName(), true);
+                unregisterVMCommand.setCleanupVmFiles(true);
+
+                commands.add(unregisterVMCommand);
+            }
+        }
+        return commands;
+    }
+}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZone.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/LegacyZone.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZone.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/LegacyZone.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/LegacyZoneVO.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/LegacyZoneVO.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenter.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenter.java
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
new file mode 100644
index 0000000..5379253
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.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 com.cloud.hypervisor.vmware;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
+import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
+
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public interface VmwareDatacenterService extends PluggableService {
+
+    VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException;
+
+    VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd updateVmwareDcCmd);
+
+    boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws IllegalArgumentException, ResourceInUseException;
+
+    List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws IllegalArgumentException, CloudRuntimeException;
+}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/LegacyZoneDao.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/LegacyZoneDao.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/LegacyZoneDao.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/LegacyZoneDao.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/LegacyZoneDaoImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/LegacyZoneDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/LegacyZoneDaoImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/LegacyZoneDaoImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/CleanupFullyClonedTemplatesTask.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
new file mode 100644
index 0000000..23758d5
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -0,0 +1,1425 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.manager;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.rmi.RemoteException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
+import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.api.query.dao.TemplateJoinDao;
+import com.cloud.cluster.ClusterManager;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.cluster.dao.ManagementServerHostPeerDao;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.ClusterVSMMapVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.ClusterVSMMapDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.DiscoveredWithErrorException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.hypervisor.vmware.LegacyZoneVO;
+import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
+import com.cloud.hypervisor.vmware.VmwareDatacenter;
+import com.cloud.hypervisor.vmware.VmwareDatacenterService;
+import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
+import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
+import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
+import com.cloud.hypervisor.vmware.dao.LegacyZoneDao;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
+import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
+import com.cloud.hypervisor.vmware.mo.DatacenterMO;
+import com.cloud.hypervisor.vmware.mo.DiskControllerType;
+import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
+import com.cloud.hypervisor.vmware.mo.HostMO;
+import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
+import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
+import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
+import com.cloud.hypervisor.vmware.mo.VmwareHostType;
+import com.cloud.hypervisor.vmware.resource.VmwareContextFactory;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.network.CiscoNexusVSMDeviceVO;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.VmwareTrafficLabel;
+import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
+import com.cloud.org.Cluster;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.storage.ImageStoreDetailsUtil;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.template.TemplateManager;
+import com.cloud.utils.FileUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.dao.UserVmCloneSettingDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.common.base.Strings;
+import com.vmware.vim25.AboutInfo;
+import com.vmware.vim25.ManagedObjectReference;
+
+public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
+    private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
+
+    private static final long SECONDS_PER_MINUTE = 60;
+    private static final int DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x = 256;
+    private static final int DEFAULT_PORTS_PER_DV_PORT_GROUP = 8;
+
+    private int _timeout;
+
+    private String _instance;
+
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private NetworkModel _netMgr;
+    @Inject
+    private ClusterDao clusterDao;
+    @Inject
+    private ClusterDetailsDao clusterDetailsDao;
+    @Inject
+    private HostDao hostDao;
+    @Inject
+    private HostDetailsDao hostDetailsDao;
+    @Inject
+    private CommandExecLogDao _cmdExecLogDao;
+    @Inject
+    private DataStoreManager _dataStoreMgr;
+    @Inject
+    private CiscoNexusVSMDeviceDao _nexusDao;
+    @Inject
+    private ClusterVSMMapDao _vsmMapDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ConfigurationServer _configServer;
+    @Inject
+    private HypervisorCapabilitiesDao _hvCapabilitiesDao;
+    @Inject
+    private DataCenterDao datacenterDao;
+    @Inject
+    private VmwareDatacenterDao vmwareDcDao;
+    @Inject
+    private VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao;
+    @Inject
+    private LegacyZoneDao legacyZoneDao;
+    @Inject
+    private ManagementServerHostPeerDao msHostPeerDao;
+    @Inject
+    private ClusterManager clusterManager;
+    @Inject
+    private ImageStoreDetailsUtil imageStoreDetailsUtil;
+    @Inject
+    private PrimaryDataStoreDao primaryStorageDao;
+    @Inject
+    private VMTemplatePoolDao templateDataStoreDao;
+    @Inject
+    private TemplateJoinDao templateDao;
+    @Inject
+    private VMInstanceDao vmInstanceDao;
+    @Inject
+    private UserVmCloneSettingDao cloneSettingDao;
+    @Inject
+    private TemplateManager templateManager;
+
+    private String _mountParent;
+    private StorageLayer _storage;
+    private final String _privateNetworkVSwitchName = "vSwitch0";
+
+    private int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
+    private boolean _fullCloneFlag;
+    private boolean _instanceNameFlag;
+    private String _serviceConsoleName;
+    private String _managemetPortGroupName;
+    private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
+    private String _recycleHungWorker = "false";
+    private int _additionalPortRangeStart;
+    private int _additionalPortRangeSize;
+    private int _routerExtraPublicNics = 2;
+    private int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
+    private String _rootDiskController = DiskControllerType.ide.toString();
+
+    private final String _dataDiskController = DiskControllerType.osdefault.toString();
+
+    private final Map<String, String> _storageMounts = new HashMap<>();
+
+    private final Random _rand = new Random(System.currentTimeMillis());
+
+    private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
+
+    private final VmwareStorageManager _storageMgr;
+    private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
+
+    public VmwareManagerImpl() {
+        _storageMgr = new VmwareStorageManagerImpl(this);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VmwareManagerImpl.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout};
+    }
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        s_logger.info("Configure VmwareManagerImpl, manager name: " + name);
+
+        if (!_configDao.isPremium()) {
+            s_logger.error("Vmware component can only run under premium distribution");
+            throw new ConfigurationException("Vmware component can only run under premium distribution");
+        }
+
+        _instance = _configDao.getValue(Config.InstanceName.key());
+        if (_instance == null) {
+            _instance = "DEFAULT";
+        }
+        s_logger.info("VmwareManagerImpl config - instance.name: " + _instance);
+
+        _mountParent = _configDao.getValue(Config.MountParent.key());
+        if (_mountParent == null) {
+            _mountParent = File.separator + "mnt";
+        }
+
+        if (_instance != null) {
+            _mountParent = _mountParent + File.separator + _instance;
+        }
+        s_logger.info("VmwareManagerImpl config - _mountParent: " + _mountParent);
+
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
+
+        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+        if (_storage == null) {
+            _storage = new JavaStorageLayer();
+            _storage.configure("StorageLayer", params);
+        }
+
+        value = _configDao.getValue(Config.VmwareCreateFullClone.key());
+        if (value == null) {
+            _fullCloneFlag = false;
+        } else {
+            _fullCloneFlag = Boolean.parseBoolean(value);
+        }
+
+        value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
+        if (value == null) {
+            _instanceNameFlag = false;
+        } else {
+            _instanceNameFlag = Boolean.parseBoolean(value);
+        }
+
+        _serviceConsoleName = _configDao.getValue(Config.VmwareServiceConsole.key());
+        if (_serviceConsoleName == null) {
+            _serviceConsoleName = "Service Console";
+        }
+
+        _managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
+        if (_managemetPortGroupName == null) {
+            _managemetPortGroupName = "Management Network";
+        }
+
+        _defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
+        if (_defaultSystemVmNicAdapterType == null) {
+            _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
+        }
+
+        _additionalPortRangeStart = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareAdditionalVncPortRangeStart.key()), 59000);
+        if (_additionalPortRangeStart > 65535) {
+            s_logger.warn("Invalid port range start port (" + _additionalPortRangeStart + ") for additional VNC port allocation, reset it to default start port 59000");
+            _additionalPortRangeStart = 59000;
+        }
+
+        _additionalPortRangeSize = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareAdditionalVncPortRangeSize.key()), 1000);
+        if (_additionalPortRangeSize < 0 || _additionalPortRangeStart + _additionalPortRangeSize > 65535) {
+            s_logger.warn("Invalid port range size (" + _additionalPortRangeSize + " for range starts at " + _additionalPortRangeStart);
+            _additionalPortRangeSize = Math.min(1000, 65535 - _additionalPortRangeStart);
+        }
+
+        _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
+
+        _vCenterSessionTimeout = NumbersUtil.parseInt(_configDao.getValue(Config.VmwareVcenterSessionTimeout.key()), 1200) * 1000;
+        s_logger.info("VmwareManagerImpl config - vmware.vcenter.session.timeout: " + _vCenterSessionTimeout);
+
+        _recycleHungWorker = _configDao.getValue(Config.VmwareRecycleHungWorker.key());
+        if (_recycleHungWorker == null || _recycleHungWorker.isEmpty()) {
+            _recycleHungWorker = "false";
+        }
+
+        _rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
+        if (_rootDiskController == null || _rootDiskController.isEmpty()) {
+            _rootDiskController = DiskControllerType.ide.toString();
+        }
+
+        s_logger.info("Additional VNC port allocation range is settled at " + _additionalPortRangeStart + " to " + (_additionalPortRangeStart + _additionalPortRangeSize));
+
+        ((VmwareStorageManagerImpl)_storageMgr).configure(params);
+
+        _agentMgr.registerForHostEvents(this, true, true, true);
+
+        s_logger.info("VmwareManagerImpl has been successfully configured");
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+// Do not run empty task        _hostScanScheduler.scheduleAtFixedRate(getHostScanTask(), STARTUP_DELAY, _hostScanInterval, TimeUnit.MILLISECONDS);
+// but implement it first!
+
+        startTemplateCleanJobSchedule();
+        startupCleanup(_mountParent);
+
+        s_logger.info("start done");
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        s_logger.info("shutting down scheduled tasks");
+        templateCleanupScheduler.shutdown();
+        shutdownCleanup();
+        return true;
+    }
+
+    @Override
+    public boolean getFullCloneFlag() {
+        return _fullCloneFlag;
+    }
+
+    @Override
+    public String composeWorkerName() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    @Override
+    public String getPrivateVSwitchName(long dcId, HypervisorType hypervisorType) {
+        return _netMgr.getDefaultManagementTrafficLabel(dcId, hypervisorType);
+    }
+
+    private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Exception {
+        // For ESX host, we need to enable host firewall to allow VNC access
+        HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO();
+        if (firewallMo != null) {
+            if (hostMo.getHostType() == VmwareHostType.ESX) {
+                firewallMo.enableRuleset("vncServer");
+                firewallMo.refreshFirewall();
+            }
+        }
+
+        // prepare at least one network on the vswitch to enable OVF importing
+        String vSwitchName;
+        String vlanId;
+        String vSwitchType;
+        VmwareTrafficLabel mgmtTrafficLabelObj = new VmwareTrafficLabel(privateTrafficLabel, TrafficType.Management);
+        vSwitchName = mgmtTrafficLabelObj.getVirtualSwitchName();
+        vlanId = mgmtTrafficLabelObj.getVlanId();
+        vSwitchType = mgmtTrafficLabelObj.getVirtualSwitchType().toString();
+
+        s_logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
+        VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
+        //The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
+        if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
+            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
+        }
+        else {
+            int portsPerDvPortGroup = _portsPerDvPortGroup;
+            AboutInfo about = hostMo.getHostAboutInfo();
+            if (about != null) {
+                String version = about.getApiVersion();
+                if (version != null && (version.equals("4.0") || version.equals("4.1")) && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x) {
+                    portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
+                }
+            }
+            HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, null, 180000,
+                    vsType, portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null);
+        }
+    }
+
+    @Override
+    public List<ManagedObjectReference> addHostToPodCluster(VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath)
+            throws Exception {
+        if (serviceContext == null) {
+            throw new CloudRuntimeException("Invalid serviceContext");
+        }
+        ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
+        String privateTrafficLabel = null;
+        privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
+        if (privateTrafficLabel == null) {
+            privateTrafficLabel = _privateNetworkVSwitchName;
+        }
+
+        if (mor != null) {
+            List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
+
+            if (mor.getType().equals("ComputeResource")) {
+                List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
+                assert (hosts != null && hosts.size() > 0);
+
+                // For ESX host, we need to enable host firewall to allow VNC access
+                HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
+
+                prepareHost(hostMo, privateTrafficLabel);
+                returnedHostList.add(hosts.get(0));
+                return returnedHostList;
+            } else if (mor.getType().equals("ClusterComputeResource")) {
+                List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
+                assert (hosts != null);
+
+                if (hosts.size() > 0) {
+                    AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
+                    String version = about.getApiVersion();
+                    int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
+                    if (hosts.size() > maxHostsPerCluster) {
+                        String msg = "Failed to add VMware cluster as size is too big, current size: " + hosts.size() + ", max. size: " + maxHostsPerCluster;
+                        s_logger.error(msg);
+                        throw new DiscoveredWithErrorException(msg);
+                    }
+                }
+
+                for (ManagedObjectReference morHost : hosts) {
+                    // For ESX host, we need to enable host firewall to allow VNC access
+                    HostMO hostMo = new HostMO(serviceContext, morHost);
+                    prepareHost(hostMo, privateTrafficLabel);
+                    returnedHostList.add(morHost);
+                }
+                return returnedHostList;
+            } else if (mor.getType().equals("HostSystem")) {
+                // For ESX host, we need to enable host firewall to allow VNC access
+                HostMO hostMo = new HostMO(serviceContext, mor);
+                prepareHost(hostMo, privateTrafficLabel);
+                returnedHostList.add(mor);
+                return returnedHostList;
+            } else {
+                s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath);
+                return null;
+            }
+        }
+
+        s_logger.error("Unable to find host from inventory path: " + hostInventoryPath);
+        return null;
+    }
+
+    @Override
+    public Pair<String, Long> getSecondaryStorageStoreUrlAndId(long dcId) {
+
+        String secUrl = null;
+        Long secId = null;
+        DataStore secStore = _dataStoreMgr.getImageStore(dcId);
+        if (secStore != null) {
+            secUrl = secStore.getUri();
+            secId = secStore.getId();
+        }
+
+        if (secUrl == null) {
+            // we are using non-NFS image store, then use cache storage instead
+            s_logger.info("Secondary storage is not NFS, we need to use staging storage");
+            DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId);
+            if (cacheStore != null) {
+                secUrl = cacheStore.getUri();
+                secId = cacheStore.getId();
+            } else {
+                s_logger.warn("No staging storage is found when non-NFS secondary storage is used");
+            }
+        }
+
+        return new Pair<String, Long>(secUrl, secId);
+    }
+
+    @Override
+    public String getServiceConsolePortGroupName() {
+        return _serviceConsoleName;
+    }
+
+    @Override
+    public String getManagementPortGroupName() {
+        return _managemetPortGroupName;
+    }
+
+    @Override
+    public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
+        if (hostMo.getHostType() == VmwareHostType.ESXi) {
+            return _managemetPortGroupName;
+        }
+        return _serviceConsoleName;
+    }
+
+    @Override
+    public void setupResourceStartupParams(Map<String, Object> params) {
+        params.put("vmware.create.full.clone", _fullCloneFlag);
+        params.put("vm.instancename.flag", _instanceNameFlag);
+        params.put("service.console.name", _serviceConsoleName);
+        params.put("management.portgroup.name", _managemetPortGroupName);
+        params.put("vmware.root.disk.controller", _rootDiskController);
+        params.put("vmware.data.disk.controller", _dataDiskController);
+        params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
+        params.put("ports.per.dvportgroup", _portsPerDvPortGroup);
+    }
+
+    @Override
+    public VmwareStorageManager getStorageManager() {
+        return _storageMgr;
+    }
+
+    @Override
+    public void gcLeftOverVMs(VmwareContext context) {
+        VmwareCleanupMaid.gcLeftOverVMs(context);
+    }
+
+    @Override
+    public boolean needRecycle(String workerTag) {
+        if (s_logger.isInfoEnabled())
+            s_logger.info("Check to see if a worker VM with tag " + workerTag + " needs to be recycled");
+
+        if (workerTag == null || workerTag.isEmpty()) {
+            s_logger.error("Invalid worker VM tag " + workerTag);
+            return false;
+        }
+
+        String tokens[] = workerTag.split("-");
+        if (tokens.length != 3) {
+            s_logger.error("Invalid worker VM tag " + workerTag);
+            return false;
+        }
+
+        long startTick = Long.parseLong(tokens[0]);
+        long msid = Long.parseLong(tokens[1]);
+        long runid = Long.parseLong(tokens[2]);
+
+        if (msHostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
+            if (s_logger.isInfoEnabled())
+                s_logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
+            return true;
+        }
+
+        if (runid != clusterManager.getManagementRunId(msid)) {
+            if (s_logger.isInfoEnabled())
+                s_logger.info("Worker VM's owner management server has changed runid, recycle it");
+            return true;
+        }
+
+        // this time-out check was disabled
+        // "until we have found out a VMware API that can check if there are pending tasks on the subject VM"
+        // but as we expire jobs and those stale worker VMs stay around untill an MS reboot we opt in to have them removed anyway
+        Instant start = Instant.ofEpochMilli(startTick);
+        Instant end = start.plusSeconds(2 * (AsyncJobManagerImpl.JobExpireMinutes.value() + AsyncJobManagerImpl.JobCancelThresholdMinutes.value()) * SECONDS_PER_MINUTE);
+        Instant now = Instant.now();
+        if(s_vmwareCleanOldWorderVMs.value() && now.isAfter(end)) {
+            if(s_logger.isInfoEnabled()) {
+                s_logger.info("Worker VM expired, seconds elapsed: " + Duration.between(start,now).getSeconds());
+            }
+            return true;
+        }
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Worker VM with tag '" + workerTag + "' does not need recycling, yet." +
+                    "But in " + Duration.between(now,end).getSeconds() + " seconds, though");
+        }
+        return false;
+    }
+
+    @Override
+    public void prepareSecondaryStorageStore(String storageUrl, Long storeId) {
+        Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(storeId);
+        String mountPoint = getMountPoint(storageUrl, nfsVersion);
+
+        GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
+        try {
+            if (lock.lock(3600)) {
+                try {
+                    File patchFolder = new File(mountPoint + "/systemvm");
+                    if (!patchFolder.exists()) {
+                        if (!patchFolder.mkdirs()) {
+                            String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString();
+                            s_logger.error(msg);
+                            throw new CloudRuntimeException(msg);
+                        }
+                    }
+
+                    File srcIso = getSystemVMPatchIsoFile();
+                    File destIso = new File(mountPoint + "/systemvm/" + getSystemVMIsoFileNameOnDatastore());
+                    if (!destIso.exists()) {
+                        s_logger.info("Inject SSH key pairs before copying systemvm.iso into secondary storage");
+                        _configServer.updateKeyPairs();
+
+                        s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: " + srcIso.getAbsolutePath() + ", destination: " +
+                                destIso.getAbsolutePath());
+                        try {
+                            FileUtil.copyfile(srcIso, destIso);
+                        } catch (IOException e) {
+                            s_logger.error("Unexpected exception ", e);
+
+                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso;
+                            s_logger.error(msg);
+                            throw new CloudRuntimeException(msg);
+                        }
+                    } else {
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("SystemVM ISO file " + destIso.getPath() + " already exists");
+                        }
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
+        } finally {
+            lock.releaseRef();
+        }
+    }
+
+    @Override
+    public String getSystemVMIsoFileNameOnDatastore() {
+        String version = this.getClass().getPackage().getImplementationVersion();
+        String fileName = "systemvm-" + version + ".iso";
+        return fileName.replace(':', '-');
+    }
+
+    @Override
+    public String getSystemVMDefaultNicAdapterType() {
+        return _defaultSystemVmNicAdapterType;
+    }
+
+    private File getSystemVMPatchIsoFile() {
+        // locate systemvm.iso
+        URL url = this.getClass().getClassLoader().getResource("vms/systemvm.iso");
+        File isoFile = null;
+        if (url != null) {
+            isoFile = new File(url.getPath());
+        }
+
+        if (isoFile == null || !isoFile.exists()) {
+            isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
+        }
+
+        assert (isoFile != null);
+        if (!isoFile.exists()) {
+            s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString());
+        }
+        return isoFile;
+    }
+
+    @Override
+    public File getSystemVMKeyFile() {
+        URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
+        File keyFile = null;
+        if (url != null) {
+            keyFile = new File(url.getPath());
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
+        }
+        assert (keyFile != null);
+        if (!keyFile.exists()) {
+            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
+        }
+        return keyFile;
+    }
+
+    @Override
+    public String getMountPoint(String storageUrl, Integer nfsVersion) {
+        String mountPoint = null;
+        synchronized (_storageMounts) {
+            mountPoint = _storageMounts.get(storageUrl);
+            if (mountPoint != null) {
+                return mountPoint;
+            }
+
+            URI uri;
+            try {
+                uri = new URI(storageUrl);
+            } catch (URISyntaxException e) {
+                s_logger.error("Invalid storage URL format ", e);
+                throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl);
+            }
+
+            mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent, nfsVersion);
+            if (mountPoint == null) {
+                s_logger.error("Unable to create mount point for " + storageUrl);
+                return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl);
+            }
+
+            _storageMounts.put(storageUrl, mountPoint);
+            return mountPoint;
+        }
+    }
+
+    private String setupMountPoint(String parent) {
+        String mountPoint = null;
+        long mshostId = ManagementServerNode.getManagementServerId();
+        for (int i = 0; i < 10; i++) {
+            String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
+            File file = new File(mntPt);
+            if (!file.exists()) {
+                if (_storage.mkdir(mntPt)) {
+                    mountPoint = mntPt;
+                    break;
+                }
+            }
+            s_logger.error("Unable to create mount: " + mntPt);
+        }
+
+        return mountPoint;
+    }
+
+    private void startupCleanup(String parent) {
+        s_logger.info("Cleanup mounted NFS mount points used in previous session");
+
+        long mshostId = ManagementServerNode.getManagementServerId();
+
+        // cleanup left-over NFS mounts from previous session
+        List<String> mounts = _storage.listMountPointsByMsHost(parent, mshostId);
+        if (mounts != null && !mounts.isEmpty()) {
+            for (String mountPoint : mounts) {
+                s_logger.info("umount NFS mount from previous session: " + mountPoint);
+
+                String result = null;
+                Script command = new Script(true, "umount", _timeout, s_logger);
+                command.add(mountPoint);
+                result = command.execute();
+                if (result != null) {
+                    s_logger.warn("Unable to umount " + mountPoint + " due to " + result);
+                }
+                File file = new File(mountPoint);
+                if (file.exists()) {
+                    file.delete();
+                }
+            }
+        }
+    }
+
+    private void shutdownCleanup() {
+        s_logger.info("Cleanup mounted NFS mount points used in current session");
+
+        for (String mountPoint : _storageMounts.values()) {
+            s_logger.info("umount NFS mount: " + mountPoint);
+
+            String result = null;
+            Script command = new Script(true, "umount", _timeout, s_logger);
+            command.add(mountPoint);
+            result = command.execute();
+            if (result != null) {
+                s_logger.warn("Unable to umount " + mountPoint + " due to " + result);
+            }
+            File file = new File(mountPoint);
+            if (file.exists()) {
+                file.delete();
+            }
+        }
+    }
+
+    protected String mount(String path, String parent, Integer nfsVersion) {
+        String mountPoint = setupMountPoint(parent);
+        if (mountPoint == null) {
+            s_logger.warn("Unable to create a mount point");
+            return null;
+        }
+
+        Script script = null;
+        String result = null;
+        Script command = new Script(true, "mount", _timeout, s_logger);
+        command.add("-t", "nfs");
+        if (nfsVersion != null){
+            command.add("-o", "vers=" + nfsVersion);
+        }
+        // command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
+        if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
+            command.add("-o", "resvport");
+        }
+        command.add(path);
+        command.add(mountPoint);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to mount " + path + " due to " + result);
+            File file = new File(mountPoint);
+            if (file.exists()) {
+                file.delete();
+            }
+            return null;
+        }
+
+        // Change permissions for the mountpoint
+        script = new Script(true, "chmod", _timeout, s_logger);
+        script.add("1777", mountPoint);
+        result = script.execute();
+        if (result != null) {
+            s_logger.warn("Unable to set permissions for " + mountPoint + " due to " + result);
+        }
+        return mountPoint;
+    }
+
+    @DB
+    private void updateClusterNativeHAState(Host host, StartupCommand cmd) {
+        ClusterVO cluster = clusterDao.findById(host.getClusterId());
+        if (cluster.getClusterType() == ClusterType.ExternalManaged) {
+            if (cmd instanceof StartupRoutingCommand) {
+                StartupRoutingCommand hostStartupCmd = (StartupRoutingCommand)cmd;
+                Map<String, String> details = hostStartupCmd.getHostDetails();
+
+                if (details.get("NativeHA") != null && details.get("NativeHA").equalsIgnoreCase("true")) {
+                    clusterDetailsDao.persist(host.getClusterId(), "NativeHA", "true");
+                } else {
+                    clusterDetailsDao.persist(host.getClusterId(), "NativeHA", "false");
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        if (answers != null) {
+            for (Answer answer : answers) {
+                String execIdStr = answer.getContextParam("execid");
+                if (execIdStr != null) {
+                    long execId = 0;
+                    try {
+                        execId = Long.parseLong(execIdStr);
+                    } catch (NumberFormatException e) {
+                        assert (false);
+                    }
+
+                    _cmdExecLogDao.expunge(execId);
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
+        return null;
+    }
+
+    @Override
+    public void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
+        if (cmd instanceof StartupCommand) {
+            if (host.getHypervisorType() == HypervisorType.VMware) {
+                updateClusterNativeHAState(host, cmd);
+            } else {
+                return;
+            }
+        }
+    }
+
+    protected final static int DEFAULT_DOMR_SSHPORT = 3922;
+
+    protected boolean shutdownRouterVM(DomainRouterVO router) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Try to shutdown router VM " + router.getInstanceName() + " directly.");
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            result = SshHelper.sshExecute(router.getPrivateIpAddress(), DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "poweroff -f");
+
+            if (!result.first()) {
+                s_logger.debug("Unable to shutdown " + router.getInstanceName() + " directly");
+                return false;
+            }
+        } catch (Throwable e) {
+            s_logger.warn("Unable to shutdown router " + router.getInstanceName() + " directly.");
+            return false;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Shutdown router " + router.getInstanceName() + " successful.");
+        }
+        return true;
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        return false;
+    }
+
+    @Override
+    public void processHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void processHostRemoved(long hostId, long clusterId) {
+    }
+
+    @Override
+    public boolean isRecurring() {
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        return false;
+    }
+
+    @Override
+    public boolean beginExclusiveOperation(int timeOutSeconds) {
+        return _exclusiveOpLock.lock(timeOutSeconds);
+    }
+
+    @Override
+    public void endExclusiveOperation() {
+        _exclusiveOpLock.unlock();
+    }
+
+    @Override
+    public Pair<Integer, Integer> getAddiionalVncPortRange() {
+        return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
+    }
+
+    @Override
+    public int getRouterExtraPublicNics() {
+        return _routerExtraPublicNics;
+    }
+
+    @Override
+    public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
+        CiscoNexusVSMDeviceVO nexusVSM = null;
+        ClusterVSMMapVO vsmMapVO = null;
+
+        vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
+        long vsmId = 0;
+        if (vsmMapVO != null) {
+            vsmId = vsmMapVO.getVsmId();
+            s_logger.info("vsmId is " + vsmId);
+            nexusVSM = _nexusDao.findById(vsmId);
+            s_logger.info("Fetching nexus vsm credentials from database.");
+        } else {
+            s_logger.info("Found empty vsmMapVO.");
+            return null;
+        }
+
+        Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
+        if (nexusVSM != null) {
+            nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
+            nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
+            nexusVSMCredentials.put("vsmpassword", nexusVSM.getPassword());
+            s_logger.info("Successfully fetched the credentials of Nexus VSM.");
+        }
+        return nexusVSMCredentials;
+    }
+
+    @Override
+    public String getRootDiskController() {
+        return _rootDiskController;
+    }
+
+    @Override
+    public String getDataDiskController() {
+        return _dataDiskController;
+    }
+
+    @Override
+    public int getVcenterSessionTimeout() {
+        return _vCenterSessionTimeout;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(AddVmwareDcCmd.class);
+        cmdList.add(UpdateVmwareDcCmd.class);
+        cmdList.add(RemoveVmwareDcCmd.class);
+        cmdList.add(ListVmwareDcsCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    @DB
+    public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
+        VmwareDatacenterVO vmwareDc = null;
+        Long zoneId = cmd.getZoneId();
+        String userName = cmd.getUsername();
+        String password = cmd.getPassword();
+        String vCenterHost = cmd.getVcenter();
+        String vmwareDcName = cmd.getName();
+
+        // Validate username, password, VMware DC name and vCenter
+        if (userName == null) {
+            throw new InvalidParameterValueException("Missing or invalid parameter username.");
+        }
+
+        if (password == null) {
+            throw new InvalidParameterValueException("Missing or invalid parameter username.");
+        }
+
+        if (vmwareDcName == null) {
+            throw new InvalidParameterValueException("Missing or invalid parameter name. Please provide valid VMware datacenter name.");
+        }
+
+        if (vCenterHost == null) {
+            throw new InvalidParameterValueException("Missing or invalid parameter name. "
+                    + "Please provide valid VMware vCenter server's IP address or fully qualified domain name.");
+        }
+
+        if (zoneId == null) {
+            throw new InvalidParameterValueException("Missing or invalid parameter name. " + "Please provide valid zone id.");
+        }
+
+        // Zone validation
+        validateZone(zoneId);
+
+        VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
+        // Check if zone is associated with VMware DC
+        if (vmwareDcZoneMap != null) {
+            // Check if the associated VMware DC matches the one specified in API params
+            // This check would yield success as the association exists between same entities (zone and VMware DC)
+            // This scenario would result in if the API addVmwareDc is called more than once with same parameters.
+            Long associatedVmwareDcId = vmwareDcZoneMap.getVmwareDcId();
+            VmwareDatacenterVO associatedVmwareDc = vmwareDcDao.findById(associatedVmwareDcId);
+            if (associatedVmwareDc.getVcenterHost().equalsIgnoreCase(vCenterHost) && associatedVmwareDc.getVmwareDatacenterName().equalsIgnoreCase(vmwareDcName)) {
+                s_logger.info("Ignoring API call addVmwareDc, because VMware DC " + vCenterHost + "/" + vmwareDcName +
+                        " is already associated with specified zone with id " + zoneId);
+                return associatedVmwareDc;
+            } else {
+                throw new CloudRuntimeException("Zone " + zoneId + " is already associated with a VMware datacenter. " +
+                        "Only 1 VMware DC can be associated with a zone.");
+            }
+        }
+        // Zone validation to check if the zone already has resources.
+        // Association of VMware DC to zone is not allowed if zone already has resources added.
+        validateZoneWithResources(zoneId, "add VMware datacenter to zone");
+
+        // Check if DC is already part of zone
+        // In that case vmware_data_center table should have the DC
+        vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
+        if (vmwareDc != null) {
+            throw new ResourceInUseException("This DC is already part of other CloudStack zone(s). Cannot add this DC to more zones.");
+        }
+
+        VmwareContext context = null;
+        DatacenterMO dcMo = null;
+        String dcCustomFieldValue;
+        boolean addDcCustomFieldDef = false;
+        boolean dcInUse = false;
+        String guid;
+        ManagedObjectReference dcMor;
+        try {
+            context = VmwareContextFactory.create(vCenterHost, userName, password);
+
+            // Check if DC exists on vCenter
+            dcMo = new DatacenterMO(context, vmwareDcName);
+            dcMor = dcMo.getMor();
+            if (dcMor == null) {
+                String msg = "Unable to find VMware DC " + vmwareDcName + " in vCenter " + vCenterHost + ". ";
+                s_logger.error(msg);
+                throw new InvalidParameterValueException(msg);
+            }
+
+            // Check if DC is already associated with another cloudstack deployment
+            // Get custom field property cloud.zone over this DC
+            guid = vmwareDcName + "@" + vCenterHost;
+
+            dcCustomFieldValue = dcMo.getCustomFieldValue(CustomFieldConstants.CLOUD_ZONE);
+            if (dcCustomFieldValue == null) {
+                addDcCustomFieldDef = true;
+            }
+            dcInUse = Boolean.parseBoolean(dcCustomFieldValue);
+            if (dcInUse) {
+                throw new ResourceInUseException("This DC is being managed by other CloudStack deployment. Cannot add this DC to zone.");
+            }
+
+            // Add DC to database into vmware_data_center table
+            vmwareDc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, userName, password);
+            vmwareDc = vmwareDcDao.persist(vmwareDc);
+
+            // Map zone with vmware datacenter
+            vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
+
+            vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
+
+            // Set custom field for this DC
+            if (addDcCustomFieldDef) {
+                dcMo.ensureCustomFieldDef(CustomFieldConstants.CLOUD_ZONE);
+            }
+            dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "true");
+
+        } catch (Throwable e) {
+            String msg = "Failed to add VMware DC to zone ";
+            if (e instanceof RemoteException) {
+                msg = "Encountered remote exception at vCenter. " + VmwareHelper.getExceptionMessage(e);
+            } else {
+                msg += "due to : " + e.getMessage();
+            }
+            throw new CloudRuntimeException(msg);
+        } finally {
+            if (context != null) {
+                context.close();
+            }
+            context = null;
+        }
+        return vmwareDc;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
+    public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
+        final Long zoneId = cmd.getZoneId();
+        final String userName = cmd.getUsername();
+        final String password = cmd.getPassword();
+        final String vCenterHost = cmd.getVcenter();
+        final String vmwareDcName = cmd.getName();
+        final Boolean isRecursive = cmd.isRecursive();
+
+        final VmwareDatacenterZoneMap vdcMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
+        final VmwareDatacenterVO vmwareDc = vmwareDcDao.findById(vdcMap.getVmwareDcId());
+        if (vmwareDc == null) {
+            throw new CloudRuntimeException("VMWare datacenter does not exist by provided ID");
+        }
+        final String oldVCenterHost = vmwareDc.getVcenterHost();
+
+        if (!Strings.isNullOrEmpty(userName)) {
+            vmwareDc.setUser(userName);
+        }
+        if (!Strings.isNullOrEmpty(password)) {
+            vmwareDc.setPassword(password);
+        }
+        if (!Strings.isNullOrEmpty(vCenterHost)) {
+            vmwareDc.setVcenterHost(vCenterHost);
+        }
+        if (!Strings.isNullOrEmpty(vmwareDcName)) {
+            vmwareDc.setVmwareDatacenterName(vmwareDcName);
+        }
+        vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
+
+        return Transaction.execute(new TransactionCallback<VmwareDatacenter>() {
+            @Override
+            public VmwareDatacenter doInTransaction(TransactionStatus status) {
+                if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
+                    if (isRecursive) {
+                        for (final Cluster cluster : clusterDao.listByDcHyType(zoneId, Hypervisor.HypervisorType.VMware.toString())) {
+                            final Map<String, String> clusterDetails = clusterDetailsDao.findDetails(cluster.getId());
+                            clusterDetails.put("username", vmwareDc.getUser());
+                            clusterDetails.put("password", vmwareDc.getPassword());
+                            final String clusterUrl = clusterDetails.get("url");
+                            if (!oldVCenterHost.equals(vmwareDc.getVcenterHost()) && !Strings.isNullOrEmpty(clusterUrl)) {
+                                clusterDetails.put("url", clusterUrl.replace(oldVCenterHost, vmwareDc.getVcenterHost()));
+                            }
+                            clusterDetailsDao.persist(cluster.getId(), clusterDetails);
+                        }
+                        for (final Host host : hostDao.listAllHostsByZoneAndHypervisorType(zoneId, HypervisorType.VMware)) {
+                            final Map<String, String> hostDetails = hostDetailsDao.findDetails(host.getId());
+                            hostDetails.put("username", vmwareDc.getUser());
+                            hostDetails.put("password", vmwareDc.getPassword());
+                            final String hostGuid = hostDetails.get("guid");
+                            if (!Strings.isNullOrEmpty(hostGuid)) {
+                                hostDetails.put("guid", hostGuid.replace(oldVCenterHost, vmwareDc.getVcenterHost()));
+                            }
+                            hostDetailsDao.persist(host.getId(), hostDetails);
+                        }
+                    }
+                    return vmwareDc;
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUseException {
+        Long zoneId = cmd.getZoneId();
+        // Validate Id of zone
+        doesZoneExist(zoneId);
+        // Zone validation to check if the zone already has resources.
+        // Association of VMware DC to zone is not allowed if zone already has resources added.
+        validateZoneWithResources(zoneId, "remove VMware datacenter to zone");
+
+        // Get DC associated with this zone
+        VmwareDatacenterVO vmwareDatacenter;
+        String vmwareDcName;
+        String vCenterHost;
+        String userName;
+        String password;
+        DatacenterMO dcMo = null;
+        final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
+        // Check if zone is associated with VMware DC
+        if (vmwareDcZoneMap == null) {
+            throw new CloudRuntimeException("Zone " + zoneId + " is not associated with any VMware datacenter.");
+        }
+
+        final long vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
+        vmwareDatacenter = vmwareDcDao.findById(vmwareDcId);
+        vmwareDcName = vmwareDatacenter.getVmwareDatacenterName();
+        vCenterHost = vmwareDatacenter.getVcenterHost();
+        userName = vmwareDatacenter.getUser();
+        password = vmwareDatacenter.getPassword();
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // Remove the VMware datacenter entry in table vmware_data_center
+                vmwareDcDao.remove(vmwareDcId);
+                // Remove the map entry in table vmware_data_center_zone_map
+                vmwareDatacenterZoneMapDao.remove(vmwareDcZoneMap.getId());
+            }
+        });
+
+        // Construct context
+        VmwareContext context = null;
+        try {
+            context = VmwareContextFactory.create(vCenterHost, userName, password);
+
+            // Check if DC exists on vCenter
+            try {
+                dcMo = new DatacenterMO(context, vmwareDcName);
+            } catch (Throwable t) {
+                String msg = "Unable to find DC " + vmwareDcName + " in vCenter " + vCenterHost;
+                s_logger.error(msg);
+                throw new DiscoveryException(msg);
+            }
+
+            assert (dcMo != null);
+
+            // Reset custom field property cloud.zone over this DC
+            dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
+            s_logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName);
+        } catch (Exception e) {
+            String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        } finally {
+            if (context != null) {
+                context.close();
+            }
+            context = null;
+        }
+        return true;
+    }
+
+    private void validateZone(Long zoneId) throws InvalidParameterValueException {
+        // Check if zone with specified id exists
+        doesZoneExist(zoneId);
+        // Check if zone is legacy zone
+        if (isLegacyZone(zoneId)) {
+            throw new InvalidParameterValueException("The specified zone is legacy zone. Adding VMware datacenter to legacy zone is not supported.");
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("The specified zone is not legacy zone.");
+            }
+        }
+    }
+
+    private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
+        // Check if zone has resources? - For now look for clusters
+        List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
+        if (clusters != null && clusters.size() > 0) {
+            // Look for VMware hypervisor.
+            for (ClusterVO cluster : clusters) {
+                if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
+                    throw new ResourceInUseException("Zone has one or more clusters." + " Can't " + errStr + " which already has clusters.");
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean isLegacyZone(long dcId) {
+        boolean isLegacyZone = false;
+        LegacyZoneVO legacyZoneVo = legacyZoneDao.findByZoneId(dcId);
+        if (legacyZoneVo != null) {
+            isLegacyZone = true;
+        }
+        return isLegacyZone;
+    }
+
+    @Override
+    public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
+        Long zoneId = cmd.getZoneId();
+        List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
+        VmwareDatacenterZoneMapVO vmwareDcZoneMap;
+        VmwareDatacenterVO vmwareDatacenter;
+        long vmwareDcId;
+
+        // Validate if zone id parameter passed to API is valid
+        doesZoneExist(zoneId);
+
+        // Check if zone is associated with VMware DC
+        vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
+        if (vmwareDcZoneMap == null) {
+            return null;
+        }
+        // Retrieve details of VMware DC associated with zone.
+        vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
+        vmwareDatacenter = vmwareDcDao.findById(vmwareDcId);
+        vmwareDcList.add(vmwareDatacenter);
+
+        // Currently a zone can have only 1 VMware DC associated with.
+        // Returning list of VmwareDatacenterVO objects, in-line with future requirements, if any, like participation of multiple VMware DCs in a zone.
+        return vmwareDcList;
+    }
+
+    private void doesZoneExist(Long zoneId) throws InvalidParameterValueException {
+        // Check if zone with specified id exists
+        DataCenterVO zone = datacenterDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by the id specified.");
+        }
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Zone with id:[" + zoneId + "] exists.");
+        }
+    }
+
+    @Override
+    public boolean hasNexusVSM(Long clusterId) {
+        ClusterVSMMapVO vsmMapVo = null;
+
+        vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
+        if (vsmMapVo == null) {
+            s_logger.info("There is no instance of Nexus 1000v VSM associated with this cluster [Id:" + clusterId + "] yet.");
+            return false;
+        }
+        else {
+            s_logger.info("An instance of Nexus 1000v VSM [Id:" + vsmMapVo.getVsmId() + "] associated with this cluster [Id:" + clusterId + "]");
+            return true;
+        }
+    }
+
+    private void startTemplateCleanJobSchedule() {
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("checking to see if we should schedule a job to search for fully cloned templates to clean-up");
+        }
+        if(StorageManager.StorageCleanupEnabled.value() &&
+                StorageManager.TemplateCleanupEnabled.value() &&
+                templateCleanupInterval.value() > 0) {
+            try {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("scheduling job to search for fully cloned templates to clean-up once per " + templateCleanupInterval.value() + " minutes.");
+                }
+//                    futureTemplateCleanup =
+                Runnable task = getCleanupFullyClonedTemplatesTask();
+                templateCleanupScheduler.scheduleAtFixedRate(task,
+                        templateCleanupInterval.value(),
+                        templateCleanupInterval.value(),
+                        TimeUnit.MINUTES);
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("scheduled job to search for fully cloned templates to clean-up.");
+                }
+            } catch (RejectedExecutionException ree) {
+                s_logger.error("job to search for fully cloned templates cannot be scheduled");
+                s_logger.debug("job to search for fully cloned templates cannot be scheduled;", ree);
+            } catch (NullPointerException npe) {
+                s_logger.error("job to search for fully cloned templates is invalid");
+                s_logger.debug("job to search for fully cloned templates is invalid;", npe);
+            } catch (IllegalArgumentException iae) {
+                s_logger.error("job to search for fully cloned templates is scheduled at invalid intervals");
+                s_logger.debug("job to search for fully cloned templates is scheduled at invalid intervals;", iae);
+            } catch (Exception e) {
+                s_logger.error("job to search for fully cloned templates failed for unknown reasons");
+                s_logger.debug("job to search for fully cloned templates failed for unknown reasons;", e);
+            }
+        }
+    }
+
+    /**
+     * This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
+     * it is called at regular intervals when storage.template.cleanup.enabled == true
+     * It collect all templates that
+     * - are deleted from cloudstack
+     * - when vmware.create.full.clone == true and the entries for VMs having volumes on the primary storage in db table “user_vm_clone_setting” reads 'full'
+     */
+    private Runnable getCleanupFullyClonedTemplatesTask() {
+        return new CleanupFullyClonedTemplatesTask(primaryStorageDao,
+                templateDataStoreDao,
+                templateDao,
+                vmInstanceDao,
+                cloneSettingDao,
+                templateManager);
+    }
+}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManager.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareContextFactory.java
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
new file mode 100644
index 0000000..37d27c8
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -0,0 +1,6515 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.nio.channels.SocketChannel;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+import org.joda.time.Duration;
+
+import com.google.gson.Gson;
+import com.vmware.vim25.AboutInfo;
+import com.vmware.vim25.BoolPolicy;
+import com.vmware.vim25.ComputeResourceSummary;
+import com.vmware.vim25.CustomFieldStringValue;
+import com.vmware.vim25.DVPortConfigInfo;
+import com.vmware.vim25.DVPortConfigSpec;
+import com.vmware.vim25.DasVmPriority;
+import com.vmware.vim25.DatastoreSummary;
+import com.vmware.vim25.DistributedVirtualPort;
+import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
+import com.vmware.vim25.DistributedVirtualSwitchPortCriteria;
+import com.vmware.vim25.DynamicProperty;
+import com.vmware.vim25.GuestInfo;
+import com.vmware.vim25.HostCapability;
+import com.vmware.vim25.HostHostBusAdapter;
+import com.vmware.vim25.HostInternetScsiHba;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.ObjectContent;
+import com.vmware.vim25.OptionValue;
+import com.vmware.vim25.PerfCounterInfo;
+import com.vmware.vim25.PerfEntityMetric;
+import com.vmware.vim25.PerfEntityMetricBase;
+import com.vmware.vim25.PerfMetricId;
+import com.vmware.vim25.PerfMetricIntSeries;
+import com.vmware.vim25.PerfMetricSeries;
+import com.vmware.vim25.PerfQuerySpec;
+import com.vmware.vim25.PerfSampleInfo;
+import com.vmware.vim25.RuntimeFaultFaultMsg;
+import com.vmware.vim25.ToolsUnavailableFaultMsg;
+import com.vmware.vim25.VMwareDVSPortSetting;
+import com.vmware.vim25.VimPortType;
+import com.vmware.vim25.VirtualDevice;
+import com.vmware.vim25.VirtualDeviceBackingInfo;
+import com.vmware.vim25.VirtualDeviceConfigSpec;
+import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
+import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
+import com.vmware.vim25.VirtualEthernetCard;
+import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
+import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
+import com.vmware.vim25.VirtualEthernetCardOpaqueNetworkBackingInfo;
+import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.VirtualMachineFileInfo;
+import com.vmware.vim25.VirtualMachineFileLayoutEx;
+import com.vmware.vim25.VirtualMachineFileLayoutExFileInfo;
+import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
+import com.vmware.vim25.VirtualMachinePowerState;
+import com.vmware.vim25.VirtualMachineRelocateSpec;
+import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
+import com.vmware.vim25.VirtualMachineRuntimeInfo;
+import com.vmware.vim25.VirtualMachineToolsStatus;
+import com.vmware.vim25.VirtualMachineVideoCard;
+import com.vmware.vim25.VirtualUSBController;
+import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.cloudstack.storage.configdrive.ConfigDrive;
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoAnswer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.BackupSnapshotAnswer;
+import com.cloud.agent.api.BackupSnapshotCommand;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckOnHostAnswer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVMSnapshotAnswer;
+import com.cloud.agent.api.CreateVMSnapshotCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
+import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.DeleteVMSnapshotAnswer;
+import com.cloud.agent.api.DeleteVMSnapshotCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmDiskStatsAnswer;
+import com.cloud.agent.api.GetVmDiskStatsCommand;
+import com.cloud.agent.api.GetVmIpAddressCommand;
+import com.cloud.agent.api.GetVmNetworkStatsAnswer;
+import com.cloud.agent.api.GetVmNetworkStatsCommand;
+import com.cloud.agent.api.GetVmStatsAnswer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.GetVolumeStatsAnswer;
+import com.cloud.agent.api.GetVolumeStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.ManageSnapshotAnswer;
+import com.cloud.agent.api.ManageSnapshotCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.MigrateVmToPoolAnswer;
+import com.cloud.agent.api.MigrateVmToPoolCommand;
+import com.cloud.agent.api.MigrateWithStorageAnswer;
+import com.cloud.agent.api.MigrateWithStorageCommand;
+import com.cloud.agent.api.ModifySshKeysCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.ModifyTargetsAnswer;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.RebootRouterCommand;
+import com.cloud.agent.api.ReplugNicAnswer;
+import com.cloud.agent.api.ReplugNicCommand;
+import com.cloud.agent.api.RevertToVMSnapshotAnswer;
+import com.cloud.agent.api.RevertToVMSnapshotCommand;
+import com.cloud.agent.api.ScaleVmAnswer;
+import com.cloud.agent.api.ScaleVmCommand;
+import com.cloud.agent.api.SetupAnswer;
+import com.cloud.agent.api.SetupCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.UnregisterNicCommand;
+import com.cloud.agent.api.UnregisterVMCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.ValidateSnapshotAnswer;
+import com.cloud.agent.api.ValidateSnapshotCommand;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.VolumeStatsEntry;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.storage.ResizeVolumeAnswer;
+import com.cloud.agent.api.storage.ResizeVolumeCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.agent.resource.virtualnetwork.VRScripts;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.Vlan;
+import com.cloud.exception.CloudException;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.guru.VMwareGuru;
+import com.cloud.hypervisor.vmware.manager.VmwareHostService;
+import com.cloud.hypervisor.vmware.manager.VmwareManager;
+import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
+import com.cloud.hypervisor.vmware.mo.ClusterMO;
+import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
+import com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO;
+import com.cloud.hypervisor.vmware.mo.DatacenterMO;
+import com.cloud.hypervisor.vmware.mo.DatastoreFile;
+import com.cloud.hypervisor.vmware.mo.DatastoreMO;
+import com.cloud.hypervisor.vmware.mo.DiskControllerType;
+import com.cloud.hypervisor.vmware.mo.FeatureKeyConstants;
+import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
+import com.cloud.hypervisor.vmware.mo.HostMO;
+import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
+import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
+import com.cloud.hypervisor.vmware.mo.NetworkDetails;
+import com.cloud.hypervisor.vmware.mo.TaskMO;
+import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
+import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
+import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
+import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
+import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
+import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostNetworkSummary;
+import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareContextPool;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.VmwareTrafficLabel;
+import com.cloud.resource.ServerResource;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.resource.StoragePoolResource;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.VmwareStorageLayoutHelper;
+import com.cloud.storage.resource.VmwareStorageProcessor;
+import com.cloud.storage.resource.VmwareStorageProcessor.VmwareStorageProcessorConfigurableFields;
+import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.ExecutionResult;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.mgmt.JmxUtil;
+import com.cloud.utils.mgmt.PropertyMapDynamicBean;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.nicira.nvp.plugin.NiciraNvpApiVersion;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VmDetailConstants;
+
+public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer {
+    private static final Logger s_logger = Logger.getLogger(VmwareResource.class);
+    public static final String VMDK_EXTENSION = ".vmdk";
+
+    private static final Random RANDOM = new Random(System.nanoTime());
+
+    protected String _name;
+
+    protected final long _opsTimeout = 900000;   // 15 minutes time out to time
+
+    protected final int _shutdownWaitMs = 300000;  // wait up to 5 minutes for shutdown
+
+    // out an operation
+    protected final int _retry = 24;
+    protected final int _sleep = 10000;
+    protected final int DefaultDomRSshPort = 3922;
+    protected final int MazCmdMBean = 100;
+
+    protected String _url;
+    protected String _dcId;
+    protected String _pod;
+    protected String _cluster;
+    protected String _username;
+    protected String _password;
+    protected String _guid;
+    protected String _vCenterAddress;
+    protected Integer storageNfsVersion;
+
+    protected String _privateNetworkVSwitchName;
+    protected VmwareTrafficLabel _guestTrafficInfo = new VmwareTrafficLabel(TrafficType.Guest);
+    protected VmwareTrafficLabel _publicTrafficInfo = new VmwareTrafficLabel(TrafficType.Public);
+    protected Map<String, String> _vsmCredentials = null;
+    protected int _portsPerDvPortGroup;
+    protected boolean _fullCloneFlag = false;
+    protected boolean _instanceNameFlag = false;
+
+    protected boolean _recycleHungWorker = false;
+    protected DiskControllerType _rootDiskController = DiskControllerType.ide;
+
+    protected ManagedObjectReference _morHyperHost;
+    protected final static ThreadLocal<VmwareContext> s_serviceContext = new ThreadLocal<VmwareContext>();
+    protected String _hostName;
+
+    protected List<PropertyMapDynamicBean> _cmdMBeans = new ArrayList<PropertyMapDynamicBean>();
+
+    protected Gson _gson;
+
+    protected volatile long _cmdSequence = 1;
+
+    protected StorageSubsystemCommandHandler storageHandler;
+    private VmwareStorageProcessor _storageProcessor;
+
+    protected VirtualRoutingResource _vrResource;
+
+    protected final static HashMap<VirtualMachinePowerState, PowerState> s_powerStatesTable = new HashMap<VirtualMachinePowerState, PowerState>();
+    static {
+        s_powerStatesTable.put(VirtualMachinePowerState.POWERED_ON, PowerState.PowerOn);
+        s_powerStatesTable.put(VirtualMachinePowerState.POWERED_OFF, PowerState.PowerOff);
+        s_powerStatesTable.put(VirtualMachinePowerState.SUSPENDED, PowerState.PowerOn);
+    }
+
+    protected static File s_systemVmKeyFile = null;
+    private static final Object s_syncLockObjectFetchKeyFile = new Object();
+    protected static final String s_relativePathSystemVmKeyFileInstallDir = "scripts/vm/systemvm/id_rsa.cloud";
+    protected static final String s_defaultPathSystemVmKeyFile = "/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud";
+
+    public Gson getGson() {
+        return _gson;
+    }
+
+    public VmwareResource() {
+        _gson = GsonHelper.getGsonLogger();
+    }
+
+    private String getCommandLogTitle(Command cmd) {
+        StringBuffer sb = new StringBuffer();
+        if (_hostName != null) {
+            sb.append(_hostName);
+        }
+
+        if (cmd.getContextParam("job") != null) {
+            sb.append(", ").append(cmd.getContextParam("job"));
+        }
+        sb.append(", cmd: ").append(cmd.getClass().getSimpleName());
+
+        return sb.toString();
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("Begin executeRequest(), cmd: " + cmd.getClass().getSimpleName());
+
+        Answer answer = null;
+        NDC.push(getCommandLogTitle(cmd));
+        try {
+            long cmdSequence = _cmdSequence++;
+            Date startTime = DateUtil.currentGMTTime();
+            PropertyMapDynamicBean mbean = new PropertyMapDynamicBean();
+            mbean.addProp("StartTime", DateUtil.getDateDisplayString(TimeZone.getDefault(), startTime));
+            mbean.addProp("Command", _gson.toJson(cmd));
+            mbean.addProp("Sequence", String.valueOf(cmdSequence));
+            mbean.addProp("Name", cmd.getClass().getSimpleName());
+
+            Class<? extends Command> clz = cmd.getClass();
+            if (cmd instanceof NetworkElementCommand) {
+                return _vrResource.executeRequest((NetworkElementCommand)cmd);
+            } else if (clz == ReadyCommand.class) {
+                answer = execute((ReadyCommand)cmd);
+            } else if (clz == GetHostStatsCommand.class) {
+                answer = execute((GetHostStatsCommand)cmd);
+            } else if (clz == GetVmStatsCommand.class) {
+                answer = execute((GetVmStatsCommand)cmd);
+            } else if (clz == GetVmNetworkStatsCommand.class) {
+                answer = execute((GetVmNetworkStatsCommand) cmd);
+            } else if (clz == GetVmDiskStatsCommand.class) {
+                answer = execute((GetVmDiskStatsCommand)cmd);
+            } else if (cmd instanceof GetVolumeStatsCommand) {
+                return execute((GetVolumeStatsCommand)cmd);
+            } else if (clz == CheckHealthCommand.class) {
+                answer = execute((CheckHealthCommand)cmd);
+            } else if (clz == StopCommand.class) {
+                answer = execute((StopCommand)cmd);
+            } else if (clz == RebootRouterCommand.class) {
+                answer = execute((RebootRouterCommand)cmd);
+            } else if (clz == RebootCommand.class) {
+                answer = execute((RebootCommand)cmd);
+            } else if (clz == CheckVirtualMachineCommand.class) {
+                answer = execute((CheckVirtualMachineCommand)cmd);
+            } else if (clz == PrepareForMigrationCommand.class) {
+                answer = execute((PrepareForMigrationCommand)cmd);
+            } else if (clz == MigrateCommand.class) {
+                answer = execute((MigrateCommand)cmd);
+            } else if (clz == MigrateVmToPoolCommand.class) {
+                answer = execute((MigrateVmToPoolCommand)cmd);
+            } else if (clz == MigrateWithStorageCommand.class) {
+                answer = execute((MigrateWithStorageCommand)cmd);
+            } else if (clz == MigrateVolumeCommand.class) {
+                answer = execute((MigrateVolumeCommand)cmd);
+            } else if (clz == DestroyCommand.class) {
+                answer = execute((DestroyCommand)cmd);
+            } else if (clz == CreateStoragePoolCommand.class) {
+                return execute((CreateStoragePoolCommand)cmd);
+            } else if (clz == ModifyTargetsCommand.class) {
+                answer = execute((ModifyTargetsCommand)cmd);
+            } else if (clz == ModifyStoragePoolCommand.class) {
+                answer = execute((ModifyStoragePoolCommand)cmd);
+            } else if (clz == DeleteStoragePoolCommand.class) {
+                answer = execute((DeleteStoragePoolCommand)cmd);
+            } else if (clz == CopyVolumeCommand.class) {
+                answer = execute((CopyVolumeCommand)cmd);
+            } else if (clz == AttachIsoCommand.class) {
+                answer = execute((AttachIsoCommand)cmd);
+            } else if (clz == ValidateSnapshotCommand.class) {
+                answer = execute((ValidateSnapshotCommand)cmd);
+            } else if (clz == ManageSnapshotCommand.class) {
+                answer = execute((ManageSnapshotCommand)cmd);
+            } else if (clz == BackupSnapshotCommand.class) {
+                answer = execute((BackupSnapshotCommand)cmd);
+            } else if (clz == CreateVolumeFromSnapshotCommand.class) {
+                answer = execute((CreateVolumeFromSnapshotCommand)cmd);
+            } else if (clz == CreatePrivateTemplateFromVolumeCommand.class) {
+                answer = execute((CreatePrivateTemplateFromVolumeCommand)cmd);
+            } else if (clz == CreatePrivateTemplateFromSnapshotCommand.class) {
+                answer = execute((CreatePrivateTemplateFromSnapshotCommand)cmd);
+            } else if (clz == UpgradeSnapshotCommand.class) {
+                answer = execute((UpgradeSnapshotCommand)cmd);
+            } else if (clz == GetStorageStatsCommand.class) {
+                answer = execute((GetStorageStatsCommand)cmd);
+            } else if (clz == PrimaryStorageDownloadCommand.class) {
+                answer = execute((PrimaryStorageDownloadCommand)cmd);
+            } else if (clz == GetVncPortCommand.class) {
+                answer = execute((GetVncPortCommand)cmd);
+            } else if (clz == SetupCommand.class) {
+                answer = execute((SetupCommand)cmd);
+            } else if (clz == MaintainCommand.class) {
+                answer = execute((MaintainCommand)cmd);
+            } else if (clz == PingTestCommand.class) {
+                answer = execute((PingTestCommand)cmd);
+            } else if (clz == CheckOnHostCommand.class) {
+                answer = execute((CheckOnHostCommand)cmd);
+            } else if (clz == ModifySshKeysCommand.class) {
+                answer = execute((ModifySshKeysCommand)cmd);
+            } else if (clz == NetworkUsageCommand.class) {
+                answer = execute((NetworkUsageCommand)cmd);
+            } else if (clz == StartCommand.class) {
+                answer = execute((StartCommand)cmd);
+            } else if (clz == CheckSshCommand.class) {
+                answer = execute((CheckSshCommand)cmd);
+            } else if (clz == CheckNetworkCommand.class) {
+                answer = execute((CheckNetworkCommand)cmd);
+            } else if (clz == PlugNicCommand.class) {
+                answer = execute((PlugNicCommand)cmd);
+            } else if (clz == ReplugNicCommand.class) {
+                answer = execute((ReplugNicCommand)cmd);
+            } else if (clz == UnPlugNicCommand.class) {
+                answer = execute((UnPlugNicCommand)cmd);
+            } else if (cmd instanceof CreateVMSnapshotCommand) {
+                return execute((CreateVMSnapshotCommand)cmd);
+            } else if (cmd instanceof DeleteVMSnapshotCommand) {
+                return execute((DeleteVMSnapshotCommand)cmd);
+            } else if (cmd instanceof RevertToVMSnapshotCommand) {
+                return execute((RevertToVMSnapshotCommand)cmd);
+            } else if (clz == ResizeVolumeCommand.class) {
+                return execute((ResizeVolumeCommand)cmd);
+            } else if (clz == UnregisterVMCommand.class) {
+                return execute((UnregisterVMCommand)cmd);
+            } else if (cmd instanceof StorageSubSystemCommand) {
+                checkStorageProcessorAndHandlerNfsVersionAttribute((StorageSubSystemCommand)cmd);
+                return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd);
+            } else if (clz == ScaleVmCommand.class) {
+                return execute((ScaleVmCommand)cmd);
+            } else if (clz == PvlanSetupCommand.class) {
+                return execute((PvlanSetupCommand)cmd);
+            } else if (clz == GetVmIpAddressCommand.class) {
+                return execute((GetVmIpAddressCommand)cmd);
+            } else if (clz == UnregisterNicCommand.class) {
+                answer = execute((UnregisterNicCommand)cmd);
+            } else {
+                answer = Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            if (cmd.getContextParam("checkpoint") != null) {
+                answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint"));
+            }
+
+            Date doneTime = DateUtil.currentGMTTime();
+            mbean.addProp("DoneTime", DateUtil.getDateDisplayString(TimeZone.getDefault(), doneTime));
+            mbean.addProp("Answer", _gson.toJson(answer));
+
+            synchronized (this) {
+                try {
+                    JmxUtil.registerMBean("VMware " + _morHyperHost.getValue(), "Command " + cmdSequence + "-" + cmd.getClass().getSimpleName(), mbean);
+                    _cmdMBeans.add(mbean);
+
+                    if (_cmdMBeans.size() >= MazCmdMBean) {
+                        PropertyMapDynamicBean mbeanToRemove = _cmdMBeans.get(0);
+                        _cmdMBeans.remove(0);
+
+                        JmxUtil.unregisterMBean("VMware " + _morHyperHost.getValue(), "Command " + mbeanToRemove.getProp("Sequence") + "-" + mbeanToRemove.getProp("Name"));
+                    }
+                } catch (Exception e) {
+                    if (s_logger.isTraceEnabled())
+                        s_logger.trace("Unable to register JMX monitoring due to exception " + ExceptionUtil.toString(e));
+                }
+            }
+
+        } finally {
+            recycleServiceContext();
+            NDC.pop();
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("End executeRequest(), cmd: " + cmd.getClass().getSimpleName());
+
+        return answer;
+    }
+
+    /**
+     * Check if storage NFS version is already set or needs to be reconfigured.<br>
+     * If _storageNfsVersion is not null -> nothing to do, version already set.<br>
+     * If _storageNfsVersion is null -> examine StorageSubSystemCommand to get NFS version and set it
+     * to the storage processor and storage handler.
+     * @param cmd command to execute
+     */
+    protected void checkStorageProcessorAndHandlerNfsVersionAttribute(StorageSubSystemCommand cmd) {
+        if (storageNfsVersion != null)
+            return;
+        if (cmd instanceof CopyCommand) {
+            EnumMap<VmwareStorageProcessorConfigurableFields, Object> params = new EnumMap<VmwareStorageProcessorConfigurableFields, Object>(
+                    VmwareStorageProcessorConfigurableFields.class);
+            examineStorageSubSystemCommandNfsVersion((CopyCommand)cmd, params);
+            params = examineStorageSubSystemCommandFullCloneFlagForVmware((CopyCommand)cmd, params);
+            reconfigureProcessorByHandler(params);
+        }
+    }
+
+    /**
+     * Reconfigure processor by handler
+     * @param params params
+     */
+    protected void reconfigureProcessorByHandler(EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
+        VmwareStorageSubsystemCommandHandler handler = (VmwareStorageSubsystemCommandHandler)storageHandler;
+        boolean success = handler.reconfigureStorageProcessor(params);
+        if (success) {
+            s_logger.info("VmwareStorageProcessor and VmwareStorageSubsystemCommandHandler successfully reconfigured");
+        } else {
+            s_logger.error("Error while reconfiguring VmwareStorageProcessor and VmwareStorageSubsystemCommandHandler, params=" + _gson.toJson(params));
+        }
+    }
+
+    /**
+     * Examine StorageSubSystem command to get full clone flag, if provided
+     * @param cmd command to execute
+     * @param params params
+     * @return copy of params including new values, if suitable
+     */
+    protected EnumMap<VmwareStorageProcessorConfigurableFields, Object> examineStorageSubSystemCommandFullCloneFlagForVmware(CopyCommand cmd,
+            EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
+        EnumMap<VmwareStorageProcessorConfigurableFields, Object> paramsCopy = new EnumMap<VmwareStorageProcessorConfigurableFields, Object>(params);
+        HypervisorType hypervisor = cmd.getDestTO().getHypervisorType();
+        if (hypervisor != null && hypervisor.equals(HypervisorType.VMware)) {
+            DataStoreTO destDataStore = cmd.getDestTO().getDataStore();
+            if (destDataStore instanceof PrimaryDataStoreTO) {
+                PrimaryDataStoreTO dest = (PrimaryDataStoreTO)destDataStore;
+                if (dest.isFullCloneFlag() != null) {
+                    paramsCopy.put(VmwareStorageProcessorConfigurableFields.FULL_CLONE_FLAG, dest.isFullCloneFlag().booleanValue());
+                }
+            }
+        }
+        return paramsCopy;
+    }
+
+    /**
+     * Examine StorageSubSystem command to get storage NFS version, if provided
+     * @param cmd command to execute
+     * @param params params
+     */
+    protected void examineStorageSubSystemCommandNfsVersion(CopyCommand cmd, EnumMap<VmwareStorageProcessorConfigurableFields, Object> params) {
+        DataStoreTO srcDataStore = cmd.getSrcTO().getDataStore();
+        boolean nfsVersionFound = false;
+
+        if (srcDataStore instanceof NfsTO) {
+            nfsVersionFound = getStorageNfsVersionFromNfsTO((NfsTO)srcDataStore);
+        }
+
+        if (nfsVersionFound) {
+            params.put(VmwareStorageProcessorConfigurableFields.NFS_VERSION, storageNfsVersion);
+        }
+    }
+
+    /**
+     * Get storage NFS version from NfsTO
+     * @param nfsTO nfsTO
+     * @return true if NFS version was found and not null, false in other case
+     */
+    protected boolean getStorageNfsVersionFromNfsTO(NfsTO nfsTO) {
+        if (nfsTO != null && nfsTO.getNfsVersion() != null) {
+            storageNfsVersion = nfsTO.getNfsVersion();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Registers the vm to the inventory given the vmx file.
+     */
+    private void registerVm(String vmName, DatastoreMO dsMo) throws Exception {
+
+        //1st param
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+        DatacenterMO dataCenterMo = new DatacenterMO(getServiceContext(), dcMor);
+        ManagedObjectReference vmFolderMor = dataCenterMo.getVmFolder();
+
+        //2nd param
+        String vmxFilePath = dsMo.searchFileInSubFolders(vmName + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
+
+        // 5th param
+        ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
+
+        ManagedObjectReference morTask = getServiceContext().getService().registerVMTask(vmFolderMor, vmxFilePath, vmName, false, morPool, hyperHost.getMor());
+        boolean result = getServiceContext().getVimClient().waitForTask(morTask);
+        if (!result) {
+            throw new Exception("Unable to register vm due to " + TaskMO.getTaskFailureInfo(getServiceContext(), morTask));
+        } else {
+            getServiceContext().waitForTaskProgressDone(morTask);
+        }
+
+    }
+
+    private Answer execute(ResizeVolumeCommand cmd) {
+        String path = cmd.getPath();
+        String vmName = cmd.getInstanceName();
+        long newSize = cmd.getNewSize() / ResourceType.bytesToKiB;
+        long oldSize = cmd.getCurrentSize() / ResourceType.bytesToKiB;
+        boolean useWorkerVm = false;
+
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        VirtualMachineMO vmMo = null;
+
+        String vmdkDataStorePath = null;
+
+        try {
+            if (newSize < oldSize) {
+                throw new Exception(
+                        "VMware doesn't support shrinking volume from larger size: " + oldSize / ResourceType.bytesToMiB + " GB to a smaller size: " + newSize / ResourceType.bytesToMiB + " GB");
+            } else if (newSize == oldSize) {
+                return new ResizeVolumeAnswer(cmd, true, "success", newSize * ResourceType.bytesToKiB);
+            }
+
+            if (vmName.equalsIgnoreCase("none")) {
+                // OfflineVmwareMigration: we need to refactor the worker vm creation out for use in migration methods as well as here
+                // OfflineVmwareMigration: this method is 100 lines and needs refactorring anyway
+                // we need to spawn a worker VM to attach the volume to and resize the volume.
+                useWorkerVm = true;
+                vmName = getWorkerName(getServiceContext(), cmd, 0);
+
+                String poolId = cmd.getPoolUuid();
+
+                // OfflineVmwareMigration: refactor for re-use
+                // OfflineVmwareMigration: 1. find data(store)
+                ManagedObjectReference morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
+                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDS);
+
+                s_logger.info("Create worker VM " + vmName);
+
+                // OfflineVmwareMigration: 2. create the worker with access to the data(store)
+                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName);
+
+                if (vmMo == null) {
+                    // OfflineVmwareMigration: don't throw a general Exception but think of a specific one
+                    throw new Exception("Unable to create a worker VM for volume resize");
+                }
+
+                synchronized (this) {
+                    // OfflineVmwareMigration: 3. attach the disk to the worker
+                    vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, path + VMDK_EXTENSION);
+
+                    vmMo.attachDisk(new String[] { vmdkDataStorePath }, morDS);
+                }
+            }
+
+            // OfflineVmwareMigration: 4. find the (worker-) VM
+            // find VM through datacenter (VM is not at the target host yet)
+            vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter";
+
+                s_logger.error(msg);
+
+                throw new Exception(msg);
+            }
+
+            // OfflineVmwareMigration: 5. ignore/replace the rest of the try-block; It is the functional bit
+            Pair<VirtualDisk, String> vdisk = vmMo.getDiskDevice(path);
+
+            if (vdisk == null) {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("resize volume done (failed)");
+                }
+
+                throw new Exception("No such disk device: " + path);
+            }
+
+            // IDE virtual disk cannot be re-sized if VM is running
+            if (vdisk.second() != null && vdisk.second().contains("ide")) {
+                throw new Exception("Re-sizing a virtual disk over an IDE controller is not supported in the VMware hypervisor. " +
+                            "Please re-try when virtual disk is attached to a VM using a SCSI controller.");
+            }
+
+            if (cmd.isManaged()) {
+                VmwareContext context = getServiceContext();
+
+                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+                ClusterMO clusterMO = new ClusterMO(context, morCluster);
+
+                List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
+
+                Collections.shuffle(lstHosts, RANDOM);
+
+                Pair<ManagedObjectReference, String> host = lstHosts.get(0);
+
+                HostMO hostMO = new HostMO(context, host.first());
+                HostDatastoreSystemMO hostDatastoreSystem = hostMO.getHostDatastoreSystemMO();
+
+                String iScsiName = cmd.get_iScsiName();
+
+                ManagedObjectReference morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, VmwareResource.getDatastoreName(iScsiName));
+                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDS);
+
+                _storageProcessor.expandDatastore(hostDatastoreSystem, dsMo);
+            }
+
+            if (vdisk.second() != null && !vdisk.second().toLowerCase().startsWith("scsi"))
+            {
+                s_logger.error("Unsupported disk device bus "+ vdisk.second());
+                throw new Exception("Unsupported disk device bus "+ vdisk.second());
+            }
+            VirtualDisk disk = vdisk.first();
+            if ((VirtualDiskFlatVer2BackingInfo)disk.getBacking() != null && ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent() != null)
+            {
+                s_logger.error("Resize is not supported because Disk device has Parent "+ ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent().getUuid());
+                throw new Exception("Resize is not supported because Disk device has Parent "+ ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getParent().getUuid());
+            }
+            String vmdkAbsFile = getAbsoluteVmdkFile(disk);
+
+            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+            }
+
+            disk.setCapacityInKB(newSize);
+
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(disk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure VM to resize disk. vmName: " + vmName);
+            }
+
+            return new ResizeVolumeAnswer(cmd, true, "success", newSize * 1024);
+        } catch (Exception e) {
+            s_logger.error("Unable to resize volume", e);
+
+            String error = "Failed to resize volume: " + e.getMessage();
+
+            return new ResizeVolumeAnswer(cmd, false, error);
+        } finally {
+            // OfflineVmwareMigration: 6. check if a worker was used and destroy it if needed
+            try {
+                if (useWorkerVm) {
+                    s_logger.info("Destroy worker VM after volume resize");
+
+                    vmMo.detachDisk(vmdkDataStorePath, false);
+                    vmMo.destroy();
+                }
+            } catch (Throwable e) {
+                s_logger.info("Failed to destroy worker VM: " + vmName);
+            }
+        }
+    }
+
+    protected Answer execute(CheckNetworkCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CheckNetworkCommand " + _gson.toJson(cmd));
+        }
+
+        // TODO setup portgroup for private network needs to be done here now
+        return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done");
+    }
+
+    protected Answer execute(NetworkUsageCommand cmd) {
+        if (cmd.isForVpc()) {
+            return VPCNetworkUsage(cmd);
+        }
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource NetworkUsageCommand " + _gson.toJson(cmd));
+        }
+        if (cmd.getOption() != null && cmd.getOption().equals("create")) {
+            String result = networkUsage(cmd.getPrivateIP(), "create", null);
+            NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L);
+            return answer;
+        }
+        long[] stats = getNetworkStats(cmd.getPrivateIP());
+
+        NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
+        return answer;
+    }
+
+    protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) {
+        String privateIp = cmd.getPrivateIP();
+        String option = cmd.getOption();
+        String publicIp = cmd.getGatewayIP();
+
+        String args = "-l " + publicIp + " ";
+        if (option.equals("get")) {
+            args += "-g";
+        } else if (option.equals("create")) {
+            args += "-c";
+            String vpcCIDR = cmd.getVpcCIDR();
+            args += " -v " + vpcCIDR;
+        } else if (option.equals("reset")) {
+            args += "-r";
+        } else if (option.equals("vpn")) {
+            args += "-n";
+        } else if (option.equals("remove")) {
+            args += "-d";
+        } else {
+            return new NetworkUsageAnswer(cmd, "success", 0L, 0L);
+        }
+
+        ExecutionResult callResult = executeInVR(privateIp, "vpc_netusage.sh", args);
+
+        if (!callResult.isSuccess()) {
+            s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + callResult.getDetails());
+        }
+
+        if (option.equals("get") || option.equals("vpn")) {
+            String result = callResult.getDetails();
+            if (result == null || result.isEmpty()) {
+                s_logger.error(" vpc network usage get returns empty ");
+            }
+            long[] stats = new long[2];
+            if (result != null) {
+                String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += Long.parseLong(splitResult[i++]);
+                    stats[1] += Long.parseLong(splitResult[i++]);
+                }
+                return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]);
+            }
+        }
+        return new NetworkUsageAnswer(cmd, "success", 0L, 0L);
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) {
+        File keyFile = getSystemVmKeyFile();
+        try {
+            SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes("UTF-8"), fileName, null);
+        } catch (Exception e) {
+            s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
+        //Update IP used to access router
+        cmd.setRouterAccessIp(getRouterSshControlIp(cmd));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
+    //
+    // list IP with eth devices
+    //  ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
+    //     | awk -F: '{ print $1 ": " $3 }'
+    //
+    // returns
+    //      eth0:xx.xx.xx.xx
+    //
+    //
+    private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception {
+        File keyFile = getSystemVmKeyFile();
+        s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
+        ArrayList<String> skipInterfaces = new ArrayList<String>(Arrays.asList("all", "default", "lo"));
+
+        // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
+        // we use a waiting loop here as a workaround to synchronize activities in systems
+        long startTick = System.currentTimeMillis();
+        long waitTimeoutMillis = VmwareManager.s_vmwareNicHotplugWaitTimeout.value();
+        while (System.currentTimeMillis() - startTick < waitTimeoutMillis) {
+
+            // TODO : this is a temporary very inefficient solution, will refactor it later
+            Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", keyFile, null, "ls /proc/sys/net/ipv4/conf");
+            if (result.first()) {
+                String[] tokens = result.second().split("\\s+");
+                for (String token : tokens) {
+                    if (!(skipInterfaces.contains(token))) {
+                        String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("Run domr script " + cmd);
+                        Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", keyFile, null,
+                                // TODO need to find the dev index inside router based on IP address
+                                cmd);
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
+
+                        if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) {
+                            return Integer.parseInt(token.substring(3));
+                        } else {
+                            skipInterfaces.add(token);
+                        }
+                    }
+                }
+            }
+
+            s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
+
+            try {
+                Thread.currentThread();
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                s_logger.debug("[ignored] interupted while trying to get mac.");
+            }
+        }
+
+        return -1;
+    }
+
+    private VirtualDevice findVirtualNicDevice(VirtualMachineMO vmMo, String mac) throws Exception {
+
+        VirtualDevice[] nics = vmMo.getNicDevices();
+        for (VirtualDevice nic : nics) {
+            if (nic instanceof VirtualEthernetCard) {
+                if (((VirtualEthernetCard)nic).getMacAddress().equals(mac))
+                    return nic;
+            }
+        }
+        return null;
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
+        NicTO nic = cmd.getNic();
+        String routerIp = getRouterSshControlIp(cmd);
+        String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac());
+            nic.setDeviceId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare SetupGuestNetwork failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+
+        try {
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            for (IpAddressTO ip : ips) {
+
+                int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress());
+                if (ethDeviceNum < 0) {
+                    if (ip.isAdd()) {
+                        throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
+                    } else {
+                        s_logger.debug("VIF to deassociate IP with does not exist, return success");
+                        continue;
+                    }
+                }
+
+                ip.setNicDevId(ethDeviceNum);
+            }
+        } catch (Exception e) {
+            s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.toString());
+        }
+
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+        IpAddressTO pubIp = cmd.getIpAddress();
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress());
+            pubIp.setNicDevId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) {
+        NicTO nic = cmd.getNic();
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        String routerIp = getRouterSshControlIp(cmd);
+
+        try {
+            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac());
+            nic.setDeviceId(ethDeviceNum);
+        } catch (Exception e) {
+            String msg = "Prepare SetNetworkACL failed due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private PlugNicAnswer execute(PlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PlugNicCommand " + _gson.toJson(cmd));
+        }
+
+        getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        VmwareContext context = getServiceContext();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+            String vmName = cmd.getVmName();
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+
+            if (vmMo == null) {
+                if (hyperHost instanceof HostMO) {
+                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
+                    vmMo = clusterMo.findVmOnHyperHost(vmName);
+                }
+            }
+
+            if (vmMo == null) {
+                String msg = "Router " + vmName + " no longer exists to execute PlugNic command";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            /*
+            if(!isVMWareToolsInstalled(vmMo)){
+                String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName;
+                s_logger.debug(errMsg);
+                return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg);
+            }
+             */
+            // Fallback to E1000 if no specific nicAdapter is passed
+            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000;
+            Map<String, String> details = cmd.getDetails();
+            if (details != null) {
+                nicDeviceType = VirtualEthernetCardType.valueOf((String)details.get("nicAdapter"));
+            }
+
+            // find a usable device number in VMware environment
+            VirtualDevice[] nicDevices = vmMo.getNicDevices();
+            int deviceNumber = -1;
+            for (VirtualDevice device : nicDevices) {
+                if (device.getUnitNumber() > deviceNumber)
+                    deviceNumber = device.getUnitNumber();
+            }
+            deviceNumber++;
+
+            NicTO nicTo = cmd.getNic();
+            VirtualDevice nic;
+            Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
+            String dvSwitchUuid = null;
+            if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
+                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+                DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
+                ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
+                dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
+                s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
+                nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid,
+                        nicTo.getMac(), deviceNumber + 1, true, true);
+            } else {
+                s_logger.info("Preparing NIC device on network " + networkInfo.second());
+                nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(),
+                        nicTo.getMac(), deviceNumber + 1, true, true);
+            }
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(nic);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure devices when running PlugNicCommand");
+            }
+
+            return new PlugNicAnswer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
+        }
+    }
+
+    private ReplugNicAnswer execute(ReplugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ReplugNicCommand " + _gson.toJson(cmd));
+        }
+
+        getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        VmwareContext context = getServiceContext();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+            String vmName = cmd.getVmName();
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+
+            if (vmMo == null) {
+                if (hyperHost instanceof HostMO) {
+                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
+                    vmMo = clusterMo.findVmOnHyperHost(vmName);
+                }
+            }
+
+            if (vmMo == null) {
+                String msg = "Router " + vmName + " no longer exists to execute ReplugNic command";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            /*
+            if(!isVMWareToolsInstalled(vmMo)){
+                String errMsg = "vmware tools is not installed or not running, cannot add nic to vm " + vmName;
+                s_logger.debug(errMsg);
+                return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg);
+            }
+             */
+            // Fallback to E1000 if no specific nicAdapter is passed
+            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000;
+            Map<String, String> details = cmd.getDetails();
+            if (details != null) {
+                nicDeviceType = VirtualEthernetCardType.valueOf((String) details.get("nicAdapter"));
+            }
+
+            NicTO nicTo = cmd.getNic();
+
+            VirtualDevice nic = findVirtualNicDevice(vmMo, nicTo.getMac());
+            if (nic == null) {
+                return new ReplugNicAnswer(cmd, false, "Nic to replug not found");
+            }
+
+            Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
+            String dvSwitchUuid = null;
+            if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
+                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+                DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
+                ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
+                dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
+                s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
+                VmwareHelper.updateDvNicDevice(nic, networkInfo.first(), dvSwitchUuid);
+            } else {
+                s_logger.info("Preparing NIC device on network " + networkInfo.second());
+
+                VmwareHelper.updateNicDevice(nic, networkInfo.first(), networkInfo.second());
+            }
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(nic);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo, dvSwitchUuid);
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure devices when running ReplugNicCommand");
+            }
+
+            return new ReplugNicAnswer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new ReplugNicAnswer(cmd, false, "Unable to execute ReplugNicCommand due to " + e.toString());
+        }
+    }
+
+    private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource UnPlugNicCommand " + _gson.toJson(cmd));
+        }
+
+        VmwareContext context = getServiceContext();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+            String vmName = cmd.getVmName();
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+
+            if (vmMo == null) {
+                if (hyperHost instanceof HostMO) {
+                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
+                    vmMo = clusterMo.findVmOnHyperHost(vmName);
+                }
+            }
+
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " no longer exists to execute UnPlugNic command";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            /*
+            if(!isVMWareToolsInstalled(vmMo)){
+                String errMsg = "vmware tools not installed or not running, cannot remove nic from vm " + vmName;
+                s_logger.debug(errMsg);
+                return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + errMsg);
+            }
+             */
+            VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac());
+            if (nic == null) {
+                return new UnPlugNicAnswer(cmd, true, "success");
+            }
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(nic);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure devices when running unplugNicCommand");
+            }
+
+            return new UnPlugNicAnswer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString());
+        }
+    }
+
+    private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final IpAddressTO ipAddressTO) throws Exception {
+        // TODO : probably need to set traffic shaping
+        Pair<ManagedObjectReference, String> networkInfo = null;
+        VirtualSwitchType vSwitchType = VirtualSwitchType.StandardVirtualSwitch;
+        if (_publicTrafficInfo != null) {
+            vSwitchType = _publicTrafficInfo.getVirtualSwitchType();
+        }
+        /** FIXME We have no clue which network this nic is on and that means that we can't figure out the BroadcastDomainType
+         *  so we assume that it's VLAN for now
+         */
+        if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
+            networkInfo = HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(),
+                    "cloud.public", vmMo.getRunningHost(), vlanId, ipAddressTO.getNetworkRate(), null,
+                    _opsTimeout, true, BroadcastDomainType.Vlan, null, null);
+        } else {
+            networkInfo =
+                    HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, ipAddressTO.getNetworkRate(), null,
+                            _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null);
+        }
+
+        int nicIndex = allocPublicNicIndex(vmMo);
+
+        try {
+            VirtualDevice[] nicDevices = vmMo.getNicDevices();
+
+            VirtualEthernetCard device = (VirtualEthernetCard)nicDevices[nicIndex];
+
+            if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
+                VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
+                nicBacking.setDeviceName(networkInfo.second());
+                nicBacking.setNetwork(networkInfo.first());
+                device.setBacking(nicBacking);
+            } else {
+                HostMO hostMo = vmMo.getRunningHost();
+                DatacenterMO dataCenterMo = new DatacenterMO(hostMo.getContext(), hostMo.getHyperHostDatacenter());
+                device.setBacking(dataCenterMo.getDvPortBackingInfo(networkInfo));
+            }
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+
+            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(device);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure devices when plugPublicNic");
+            }
+        } catch (Exception e) {
+
+            // restore allocation mask in case of exceptions
+            String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
+            int nicMasks = Integer.parseInt(nicMasksStr);
+            nicMasks &= ~(1 << nicIndex);
+            vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
+
+            throw e;
+        }
+    }
+
+    private int allocPublicNicIndex(VirtualMachineMO vmMo) throws Exception {
+        String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK);
+        if (nicMasksStr == null || nicMasksStr.isEmpty()) {
+            throw new Exception("Could not find NIC allocation info");
+        }
+
+        int nicMasks = Integer.parseInt(nicMasksStr);
+        VirtualDevice[] nicDevices = vmMo.getNicDevices();
+        for (int i = 3; i < nicDevices.length; i++) {
+            if ((nicMasks & (1 << i)) == 0) {
+                nicMasks |= (1 << i);
+                vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks));
+                return i;
+            }
+        }
+
+        throw new Exception("Could not allocate a free public NIC");
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
+        VmwareContext context = getServiceContext();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+            String controlIp = VmwareResource.getRouterSshControlIp(cmd);
+
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName);
+
+            // command may sometimes be redirect to a wrong host, we relax
+            // the check and will try to find it within cluster
+            if (vmMo == null) {
+                if (hyperHost instanceof HostMO) {
+                    ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor());
+                    vmMo = clusterMo.findVmOnHyperHost(routerName);
+                }
+            }
+
+            if (vmMo == null) {
+                String msg = "Router " + routerName + " no longer exists to execute IPAssoc command";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            for (IpAddressTO ip : ips) {
+                /**
+                 * TODO support other networks
+                 */
+                URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+                    throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri());
+                }
+                String vlanId = BroadcastDomainType.getValue(broadcastUri);
+
+                String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
+                Pair<Integer, VirtualDevice> publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first());
+                }
+
+                boolean addVif = false;
+                if (ip.isAdd() && publicNicInfo.first().intValue() == -1) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp());
+                    }
+                    addVif = true;
+                }
+
+                if (addVif) {
+                    plugPublicNic(vmMo, vlanId, ip);
+                    publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
+                    if (publicNicInfo.first().intValue() >= 0) {
+                        networkUsage(controlIp, "addVif", "eth" + publicNicInfo.first());
+                    }
+                }
+
+                if (publicNicInfo.first().intValue() < 0) {
+                    String msg = "Failed to find DomR VIF to associate/disassociate IP with.";
+                    s_logger.error(msg);
+                    throw new InternalErrorException(msg);
+                }
+                ip.setNicDevId(publicNicInfo.first().intValue());
+                ip.setNewNic(addVif);
+            }
+        } catch (Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult executeInVR(String routerIP, String script, String args) {
+        return executeInVR(routerIP, script, args, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
+    }
+
+    @Override
+    public ExecutionResult executeInVR(String routerIP, String script, String args, Duration timeout) {
+        Pair<Boolean, String> result;
+
+        //TODO: Password should be masked, cannot output to log directly
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args);
+        }
+
+        try {
+            result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", getSystemVmKeyFile(), null, "/opt/cloud/bin/" + script + " " + args,
+                    VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout);
+        } catch (Exception e) {
+            String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            result = new Pair<Boolean, String>(false, msg);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(script + " execution result: " + result.first().toString());
+        }
+        return new ExecutionResult(result.first(), result.second());
+    }
+
+    protected CheckSshAnswer execute(CheckSshCommand cmd) {
+        String vmName = cmd.getName();
+        String privateIp = cmd.getIp();
+        int cmdPort = cmd.getPort();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
+        }
+
+        try {
+            String result = connect(cmd.getName(), privateIp, cmdPort);
+            if (result != null) {
+                s_logger.error("Can not ping System vm " + vmName + "due to:" + result);
+                return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
+            }
+        } catch (Exception e) {
+            s_logger.error("Can not ping System vm " + vmName + "due to exception");
+            return new CheckSshAnswer(cmd, e);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Ping command port succeeded for vm " + vmName);
+        }
+
+        if (VirtualMachineName.isValidRouterName(vmName)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Execute network usage setup command on " + vmName);
+            }
+            networkUsage(privateIp, "create", null);
+        }
+
+        return new CheckSshAnswer(cmd);
+    }
+
+    private DiskTO[] validateDisks(DiskTO[] disks) {
+        List<DiskTO> validatedDisks = new ArrayList<DiskTO>();
+
+        for (DiskTO vol : disks) {
+            if (vol.getType() != Volume.Type.ISO) {
+                VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+                DataStoreTO primaryStore = volumeTO.getDataStore();
+                if (primaryStore.getUuid() != null && !primaryStore.getUuid().isEmpty()) {
+                    validatedDisks.add(vol);
+                }
+            } else if (vol.getType() == Volume.Type.ISO) {
+                TemplateObjectTO templateTO = (TemplateObjectTO)vol.getData();
+                if (templateTO.getPath() != null && !templateTO.getPath().isEmpty()) {
+                    validatedDisks.add(vol);
+                }
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Drop invalid disk option, volumeTO: " + _gson.toJson(vol));
+                }
+            }
+        }
+        Collections.sort(validatedDisks, (d1, d2) -> d1.getDiskSeq().compareTo(d2.getDiskSeq()));
+        return validatedDisks.toArray(new DiskTO[0]);
+    }
+
+    private static DiskTO getIsoDiskTO(DiskTO[] disks) {
+        for (DiskTO vol : disks) {
+            if (vol.getType() == Volume.Type.ISO) {
+                return vol;
+            }
+        }
+        return null;
+    }
+
+    protected ScaleVmAnswer execute(ScaleVmCommand cmd) {
+
+        VmwareContext context = getServiceContext();
+        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            int ramMb = getReservedMemoryMb(vmSpec);
+            long hotaddIncrementSizeInMb;
+            long hotaddMemoryLimitInMb;
+            long requestedMaxMemoryInMb = vmSpec.getMaxRam() / (1024 * 1024);
+
+            // Check if VM is really running on hypervisor host
+            if (getVmPowerState(vmMo) != PowerState.PowerOn) {
+                throw new CloudRuntimeException("Found that the VM " + vmMo.getVmName() + " is not running. Unable to scale-up this VM");
+            }
+
+            // Check max hot add limit
+            hotaddIncrementSizeInMb = vmMo.getHotAddMemoryIncrementSizeInMb();
+            hotaddMemoryLimitInMb = vmMo.getHotAddMemoryLimitInMb();
+            if (requestedMaxMemoryInMb > hotaddMemoryLimitInMb) {
+                throw new CloudRuntimeException("Memory of VM " + vmMo.getVmName() + " cannot be scaled to " + requestedMaxMemoryInMb + "MB."
+                        + " Requested memory limit is beyond the hotadd memory limit for this VM at the moment is " + hotaddMemoryLimitInMb + "MB.");
+            }
+
+            // Check increment is multiple of increment size
+            long reminder = requestedMaxMemoryInMb % hotaddIncrementSizeInMb;
+            if (reminder != 0) {
+                requestedMaxMemoryInMb = requestedMaxMemoryInMb + hotaddIncrementSizeInMb - reminder;
+            }
+
+            // Check if license supports the feature
+            VmwareHelper.isFeatureLicensed(hyperHost, FeatureKeyConstants.HOTPLUG);
+            VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(), (int)requestedMaxMemoryInMb, ramMb,
+                    vmSpec.getLimitCpuUse());
+
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Unable to execute ScaleVmCommand");
+            }
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new ScaleVmAnswer(cmd, false, "Unable to execute ScaleVmCommand due to " + e.toString());
+        }
+        return new ScaleVmAnswer(cmd, true, null);
+    }
+
+    protected void ensureDiskControllers(VirtualMachineMO vmMo, Pair<String, String> controllerInfo) throws Exception {
+        if (vmMo == null) {
+            return;
+        }
+
+        String msg;
+        String rootDiskController = controllerInfo.first();
+        String dataDiskController = controllerInfo.second();
+        String scsiDiskController;
+        String recommendedDiskController = null;
+
+        if (VmwareHelper.isControllerOsRecommended(dataDiskController) || VmwareHelper.isControllerOsRecommended(rootDiskController)) {
+            recommendedDiskController = vmMo.getRecommendedDiskController(null);
+        }
+        scsiDiskController = HypervisorHostHelper.getScsiController(new Pair<String, String>(rootDiskController, dataDiskController), recommendedDiskController);
+        if (scsiDiskController == null) {
+            return;
+        }
+
+        vmMo.getScsiDeviceControllerKeyNoException();
+        // This VM needs SCSI controllers.
+        // Get count of existing scsi controllers. Helps not to attempt to create more than the maximum allowed 4
+        // Get maximum among the bus numbers in use by scsi controllers. Safe to pick maximum, because we always go sequential allocating bus numbers.
+        Ternary<Integer, Integer, DiskControllerType> scsiControllerInfo = vmMo.getScsiControllerInfo();
+        int requiredNumScsiControllers = VmwareHelper.MAX_SCSI_CONTROLLER_COUNT - scsiControllerInfo.first();
+        int availableBusNum = scsiControllerInfo.second() + 1; // method returned current max. bus number
+
+        if (requiredNumScsiControllers == 0) {
+            return;
+        }
+        if (scsiControllerInfo.first() > 0) {
+            // For VMs which already have a SCSI controller, do NOT attempt to add any more SCSI controllers & return the sub type.
+            // For Legacy VMs would have only 1 LsiLogic Parallel SCSI controller, and doesn't require more.
+            // For VMs created post device ordering support, 4 SCSI subtype controllers are ensured during deployment itself. No need to add more.
+            // For fresh VM deployment only, all required controllers should be ensured.
+            return;
+        }
+        ensureScsiDiskControllers(vmMo, scsiDiskController, requiredNumScsiControllers, availableBusNum);
+    }
+
+    private void ensureScsiDiskControllers(VirtualMachineMO vmMo, String scsiDiskController, int requiredNumScsiControllers, int availableBusNum) throws Exception {
+        // Pick the sub type of scsi
+        if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.pvscsi) {
+            if (!vmMo.isPvScsiSupported()) {
+                String msg = "This VM doesn't support Vmware Paravirtual SCSI controller for virtual disks, because the virtual hardware version is less than 7.";
+                throw new Exception(msg);
+            }
+            vmMo.ensurePvScsiDeviceController(requiredNumScsiControllers, availableBusNum);
+        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.lsisas1068) {
+            vmMo.ensureLsiLogicSasDeviceControllers(requiredNumScsiControllers, availableBusNum);
+        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.buslogic) {
+            vmMo.ensureBusLogicDeviceControllers(requiredNumScsiControllers, availableBusNum);
+        } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.lsilogic) {
+            vmMo.ensureLsiLogicDeviceControllers(requiredNumScsiControllers, availableBusNum);
+        }
+    }
+
+    protected StartAnswer execute(StartCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
+        }
+
+        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+        boolean vmAlreadyExistsInVcenter = false;
+
+        String existingVmName = null;
+        VirtualMachineFileInfo existingVmFileInfo = null;
+        VirtualMachineFileLayoutEx existingVmFileLayout = null;
+        List<DatastoreMO> existingDatastores = new ArrayList<DatastoreMO>();
+
+        Pair<String, String> names = composeVmNames(vmSpec);
+        String vmInternalCSName = names.first();
+        String vmNameOnVcenter = names.second();
+        String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
+        String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
+        DiskTO rootDiskTO = null;
+        // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
+        // This helps avoid mix of different scsi subtype controllers in instance.
+        if (DiskControllerType.osdefault == DiskControllerType.getType(dataDiskController) && DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
+            dataDiskController = DiskControllerType.scsi.toString();
+        }
+
+        // Validate the controller types
+        dataDiskController = DiskControllerType.getType(dataDiskController).toString();
+        rootDiskController = DiskControllerType.getType(rootDiskController).toString();
+
+        if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
+            throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
+        }
+        if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
+            throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
+        }
+
+        Pair<String, String> controllerInfo = new Pair<String, String>(rootDiskController, dataDiskController);
+
+        Boolean systemVm = vmSpec.getType().isUsedBySystem();
+        // Thus, vmInternalCSName always holds i-x-y, the cloudstack generated internal VM name.
+        VmwareContext context = getServiceContext();
+        DatacenterMO dcMo = null;
+        try {
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            dcMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter());
+
+            // Validate VM name is unique in Datacenter
+            VirtualMachineMO vmInVcenter = dcMo.checkIfVmAlreadyExistsInVcenter(vmNameOnVcenter, vmInternalCSName);
+            if (vmInVcenter != null) {
+                vmAlreadyExistsInVcenter = true;
+                String msg = "VM with name: " + vmNameOnVcenter + " already exists in vCenter.";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+            String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
+            DiskTO[] disks = validateDisks(vmSpec.getDisks());
+            assert (disks.length > 0);
+            NicTO[] nics = vmSpec.getNics();
+
+            HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks, cmd);
+            if ((dataStoresDetails == null) || (dataStoresDetails.isEmpty())) {
+                String msg = "Unable to locate datastore details of the volumes to be attached";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
+            if (dsRootVolumeIsOn == null) {
+                String msg = "Unable to locate datastore details of root volume";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
+            DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
+            int firstScsiControllerBusNum = 0;
+            int numScsiControllerForSystemVm = 1;
+            boolean hasSnapshot = false;
+            if (vmMo != null) {
+                s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
+                if (getVmPowerState(vmMo) != PowerState.PowerOff)
+                    vmMo.safePowerOff(_shutdownWaitMs);
+
+                // retrieve disk information before we tear down
+                diskInfoBuilder = vmMo.getDiskInfoBuilder();
+                hasSnapshot = vmMo.hasSnapshot();
+                if (!hasSnapshot)
+                    vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
+                else
+                    vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
+                if (systemVm) {
+                    ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
+                } else {
+                    ensureDiskControllers(vmMo, controllerInfo);
+                }
+            } else {
+                ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
+                assert (morDc != null);
+
+                vmMo = hyperHost.findVmOnPeerHyperHost(vmInternalCSName);
+                if (vmMo != null) {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Found vm " + vmInternalCSName + " at other host, relocate to " + hyperHost.getHyperHostName());
+                    }
+
+                    takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
+
+                    if (getVmPowerState(vmMo) != PowerState.PowerOff)
+                        vmMo.safePowerOff(_shutdownWaitMs);
+
+                    diskInfoBuilder = vmMo.getDiskInfoBuilder();
+                    hasSnapshot = vmMo.hasSnapshot();
+                    if (!hasSnapshot)
+                        vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
+                    else
+                        vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
+
+                    if (systemVm) {
+                        // System volumes doesn't require more than 1 SCSI controller as there is no requirement for data volumes.
+                        ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
+                    } else {
+                        ensureDiskControllers(vmMo, controllerInfo);
+                    }
+                } else {
+                    // If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
+                    VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
+                    if (existingVmInDc != null) {
+                        s_logger.debug("Found VM: " + vmInternalCSName + " on a host in a different cluster. Unregistering the exisitng VM.");
+                        existingVmName = existingVmInDc.getName();
+                        existingVmFileInfo = existingVmInDc.getFileInfo();
+                        existingVmFileLayout = existingVmInDc.getFileLayout();
+                        existingDatastores = existingVmInDc.getAllDatastores();
+                        existingVmInDc.unregisterVm();
+                    }
+                    Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
+                    for (DiskTO vol : disks) {
+                        if (vol.getType() == Volume.Type.ROOT) {
+                            Map<String, String> details = vol.getDetails();
+                            boolean managed = false;
+
+                            if (details != null) {
+                                managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                            }
+
+                            if (managed) {
+                                String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
+
+                                rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
+                            } else {
+                                DataStoreTO primaryStore = vol.getData().getDataStore();
+
+                                rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
+                            }
+                        }
+                    }
+
+                    assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
+
+                    boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
+                    String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
+                    if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present.
+                        registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
+                        vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
+                        if (vmMo != null) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
+                            }
+                        }
+                        tearDownVm(vmMo);
+                    } else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec),
+                            vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / ResourceType.bytesToMiB), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false,
+                            controllerInfo, systemVm)) {
+                        throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
+                    }
+                }
+
+                vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
+                if (vmMo == null) {
+                    throw new Exception("Failed to find the newly create or relocated VM. vmName: " + vmInternalCSName);
+                }
+            }
+
+            int totalChangeDevices = disks.length + nics.length;
+
+            DiskTO volIso = null;
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                // system VM needs a patch ISO
+                totalChangeDevices++;
+            } else {
+                volIso = getIsoDiskTO(disks);
+                if (volIso == null)
+                    totalChangeDevices++;
+            }
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+
+            VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)),
+                    getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse());
+
+            // Check for multi-cores per socket settings
+            int numCoresPerSocket = 1;
+            String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket");
+            if (coresPerSocket != null) {
+                String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext());
+                // Property 'numCoresPerSocket' is supported since vSphere API 5.0
+                if (apiVersion.compareTo("5.0") >= 0) {
+                    numCoresPerSocket = NumbersUtil.parseInt(coresPerSocket, 1);
+                    vmConfigSpec.setNumCoresPerSocket(numCoresPerSocket);
+                }
+            }
+
+            // Check for hotadd settings
+            vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId));
+
+            String hostApiVersion = ((HostMO)hyperHost).getHostAboutInfo().getApiVersion();
+            if (numCoresPerSocket > 1 && hostApiVersion.compareTo("5.0") < 0) {
+                s_logger.warn("Dynamic scaling of CPU is not supported for Virtual Machines with multi-core vCPUs in case of ESXi hosts 4.1 and prior. Hence CpuHotAdd will not be"
+                        + " enabled for Virtual Machine: " + vmInternalCSName);
+                vmConfigSpec.setCpuHotAddEnabled(false);
+            } else {
+                vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId));
+            }
+
+            configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
+
+            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
+            int i = 0;
+            int ideUnitNumber = 0;
+            int scsiUnitNumber = 0;
+            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
+            int scsiControllerKey = vmMo.getGenericScsiDeviceControllerKeyNoException();
+            int controllerKey;
+
+            //
+            // Setup ISO device
+            //
+
+            // prepare systemvm patch ISO
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                // attach ISO (for patching of system VM)
+                Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+                String secStoreUrl = secStoreUrlAndId.first();
+                Long secStoreId = secStoreUrlAndId.second();
+                if (secStoreUrl == null) {
+                    String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
+                    throw new Exception(msg);
+                }
+                mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
+
+                ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
+                if (morSecDs == null) {
+                    String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
+                    throw new Exception(msg);
+                }
+                DatastoreMO secDsMo = new DatastoreMO(hyperHost.getContext(), morSecDs);
+
+                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo,
+                        String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), true, true, ideUnitNumber++, i + 1);
+                deviceConfigSpecArray[i].setDevice(isoInfo.first());
+                if (isoInfo.second()) {
+                    if (s_logger.isDebugEnabled())
+                        s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
+                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+                } else {
+                    if (s_logger.isDebugEnabled())
+                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
+                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+                }
+                i++;
+            } else {
+                // Note: we will always plug a CDROM device
+                if (volIso != null) {
+                    for (DiskTO vol : disks) {
+                        if (vol.getType() == Volume.Type.ISO) {
+
+                            TemplateObjectTO iso = (TemplateObjectTO) vol.getData();
+
+                            if (iso.getPath() != null && !iso.getPath().isEmpty()) {
+                                DataStoreTO imageStore = iso.getDataStore();
+                                if (!(imageStore instanceof NfsTO)) {
+                                    s_logger.debug("unsupported protocol");
+                                    throw new Exception("unsupported protocol");
+                                }
+                                NfsTO nfsImageStore = (NfsTO) imageStore;
+                                String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
+                                Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath);
+                                assert (isoDatastoreInfo != null);
+                                assert (isoDatastoreInfo.second() != null);
+
+                                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                                Pair<VirtualDevice, Boolean> isoInfo =
+                                        VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1);
+                                deviceConfigSpecArray[i].setDevice(isoInfo.first());
+                                if (isoInfo.second()) {
+                                    if (s_logger.isDebugEnabled())
+                                        s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
+                                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+                                } else {
+                                    if (s_logger.isDebugEnabled())
+                                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
+                                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+                                }
+                            }
+                            i++;
+                        }
+                    }
+                } else {
+                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                    Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, null, null, true, true, ideUnitNumber++, i + 1);
+                    deviceConfigSpecArray[i].setDevice(isoInfo.first());
+                    if (isoInfo.second()) {
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
+
+                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+                    } else {
+                        if (s_logger.isDebugEnabled())
+                            s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
+
+                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+                    }
+                    i++;
+                }
+            }
+
+
+
+            //
+            // Setup ROOT/DATA disk devices
+            //
+            DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
+            for (DiskTO vol : sortedDisks) {
+                if (vol.getType() == Volume.Type.ISO)
+                    continue;
+
+                VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
+                controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey);
+                String diskController = getDiskController(vmMo, matchingExistingDisk, vol, new Pair<String, String>(rootDiskController, dataDiskController));
+
+                if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
+                    diskController = vmMo.getRecommendedDiskController(null);
+                }
+                if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
+                    controllerKey = vmMo.getIDEControllerKey(ideUnitNumber);
+                    if (vol.getType() == Volume.Type.DATADISK) {
+                        // Could be result of flip due to user configured setting or "osdefault" for data disks
+                        // Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
+                        if (vmMo.getNumberOfVirtualDisks() > 3) {
+                            throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over "
+                                    + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device.");
+                        }
+                    }
+                } else {
+                    controllerKey = vmMo.getScsiDiskControllerKeyNoException(diskController);
+                    if (controllerKey == -1) {
+                        // This may happen for ROOT legacy VMs which doesn't have recommended disk controller when global configuration parameter 'vmware.root.disk.controller' is set to "osdefault"
+                        // Retrieve existing controller and use.
+                        Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
+                        DiskControllerType existingControllerType = vmScsiControllerInfo.third();
+                        controllerKey = vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString());
+                    }
+                }
+                if (!hasSnapshot) {
+                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+
+                    VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+                    DataStoreTO primaryStore = volumeTO.getDataStore();
+                    Map<String, String> details = vol.getDetails();
+                    boolean managed = false;
+                    String iScsiName = null;
+
+                    if (details != null) {
+                        managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                        iScsiName = details.get(DiskTO.IQN);
+                    }
+
+                    // if the storage is managed, iScsiName should not be null
+                    String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
+                    Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
+
+                    assert (volumeDsDetails != null);
+
+                    String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
+                    if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
+                        scsiUnitNumber++;
+                    VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(),
+                            (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) ? ((ideUnitNumber++) % VmwareHelper.MAX_IDE_CONTROLLER_COUNT) : scsiUnitNumber++, i + 1);
+
+                    if (vol.getType() == Volume.Type.ROOT)
+                        rootDiskTO = vol;
+                    deviceConfigSpecArray[i].setDevice(device);
+                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                    if (s_logger.isDebugEnabled())
+                        s_logger.debug("Prepare volume at new device " + _gson.toJson(device));
+
+                    i++;
+                } else {
+                    if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
+                        scsiUnitNumber++;
+                    if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber))
+                        ideUnitNumber++;
+                    else
+                        scsiUnitNumber++;
+                }
+            }
+
+            //
+            // Setup USB devices
+            //
+            if (guestOsId.startsWith("darwin")) { //Mac OS
+                VirtualDevice[] devices = vmMo.getMatchedDevices(new Class<?>[] {VirtualUSBController.class});
+                if (devices.length == 0) {
+                    s_logger.debug("No USB Controller device on VM Start. Add USB Controller device for Mac OS VM " + vmInternalCSName);
+
+                    //For Mac OS X systems, the EHCI+UHCI controller is enabled by default and is required for USB mouse and keyboard access.
+                    VirtualDevice usbControllerDevice = VmwareHelper.prepareUSBControllerDevice();
+                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                    deviceConfigSpecArray[i].setDevice(usbControllerDevice);
+                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                    if (s_logger.isDebugEnabled())
+                        s_logger.debug("Prepare USB controller at new device " + _gson.toJson(deviceConfigSpecArray[i]));
+
+                    i++;
+                } else {
+                    s_logger.debug("USB Controller device exists on VM Start for Mac OS VM " + vmInternalCSName);
+                }
+            }
+
+            //
+            // Setup NIC devices
+            //
+            VirtualDevice nic;
+            int nicMask = 0;
+            int nicCount = 0;
+
+            if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
+                int extraPublicNics = mgr.getRouterExtraPublicNics();
+                if (extraPublicNics > 0 && vmSpec.getDetails().containsKey("PeerRouterInstanceName")) {
+                    //Set identical MAC address for RvR on extra public interfaces
+                    String peerRouterInstanceName = vmSpec.getDetails().get("PeerRouterInstanceName");
+
+                    VirtualMachineMO peerVmMo = hyperHost.findVmOnHyperHost(peerRouterInstanceName);
+                    if (peerVmMo == null) {
+                        peerVmMo = hyperHost.findVmOnPeerHyperHost(peerRouterInstanceName);
+                    }
+
+                    if (peerVmMo != null) {
+                        String oldMacSequence = generateMacSequence(nics);
+
+                        for (int nicIndex = nics.length - extraPublicNics; nicIndex < nics.length; nicIndex++) {
+                            VirtualDevice nicDevice = peerVmMo.getNicDeviceByIndex(nics[nicIndex].getDeviceId());
+                            if (nicDevice != null) {
+                                String mac = ((VirtualEthernetCard)nicDevice).getMacAddress();
+                                if (mac != null) {
+                                    s_logger.info("Use same MAC as previous RvR, the MAC is " + mac + " for extra NIC with device id: " + nics[nicIndex].getDeviceId());
+                                    nics[nicIndex].setMac(mac);
+                                }
+                            }
+                        }
+
+                        if (!StringUtils.isBlank(vmSpec.getBootArgs())) {
+                            String newMacSequence = generateMacSequence(nics);
+                            vmSpec.setBootArgs(replaceNicsMacSequenceInBootArgs(oldMacSequence, newMacSequence, vmSpec));
+                        }
+                    }
+                }
+            }
+
+            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType);
+
+            NiciraNvpApiVersion.logNiciraApiVersion();
+
+            Map<String, String> nicUuidToDvSwitchUuid = new HashMap<String, String>();
+            for (NicTO nicTo : sortNicsByDeviceId(nics)) {
+                s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
+
+                boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
+                VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
+                Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
+                if ((nicTo.getBroadcastType() != BroadcastDomainType.Lswitch)
+                        || (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch && NiciraNvpApiVersion.isApiVersionLowerThan("4.2"))) {
+                    if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
+                        String dvSwitchUuid;
+                        ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+                        DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
+                        ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
+                        dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
+                        s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
+                        nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid,
+                                nicTo.getMac(), i + 1, true, true);
+                        if (nicTo.getUuid() != null) {
+                            nicUuidToDvSwitchUuid.put(nicTo.getUuid(), dvSwitchUuid);
+                        }
+                    } else {
+                        s_logger.info("Preparing NIC device on network " + networkInfo.second());
+                        nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(),
+                                nicTo.getMac(), i + 1, true, true);
+                    }
+                } else {
+                    //if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
+                    nic = VmwareHelper.prepareNicOpaque(vmMo, nicDeviceType, networkInfo.second(),
+                            nicTo.getMac(), i + 1, true, true);
+                }
+
+                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                deviceConfigSpecArray[i].setDevice(nic);
+                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i]));
+
+                // this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3
+                if (nicCount < 3)
+                    nicMask |= (1 << nicCount);
+
+                i++;
+                nicCount++;
+            }
+
+            for (int j = 0; j < i; j++)
+                vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[j]);
+
+            //
+            // Setup VM options
+            //
+
+            // pass boot arguments through machine.id & perform customized options to VMX
+            ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
+            configBasicExtraOption(extraOptions, vmSpec);
+            configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
+            configCustomExtraOption(extraOptions, vmSpec);
+
+            // config for NCC
+            VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
+            if (vmType.equals(VirtualMachine.Type.NetScalerVm)) {
+                NicTO mgmtNic = vmSpec.getNics()[0];
+                OptionValue option = new OptionValue();
+                option.setKey("machine.id");
+                option.setValue("ip=" + mgmtNic.getIp() + "&netmask=" + mgmtNic.getNetmask() + "&gateway=" + mgmtNic.getGateway());
+                extraOptions.add(option);
+            }
+
+            // config VNC
+            String keyboardLayout = null;
+            if (vmSpec.getDetails() != null)
+                keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
+            vmConfigSpec.getExtraConfig()
+                    .addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
+
+            // config video card
+            configureVideoCard(vmMo, vmSpec, vmConfigSpec);
+
+            //
+            // Configure VM
+            //
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName);
+            }
+
+            if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
+                hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value());
+            }
+
+            // Resizing root disk only when explicit requested by user
+            final Map<String, String> vmDetails = cmd.getVirtualMachine().getDetails();
+            if (rootDiskTO != null && !hasSnapshot && (vmDetails != null && vmDetails.containsKey(ApiConstants.ROOT_DISK_SIZE))) {
+                resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context);
+            }
+
+            //
+            // Post Configuration
+            //
+
+            vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
+            postNvpConfigBeforeStart(vmMo, vmSpec);
+
+            Map<String, Map<String, String>> iqnToData = new HashMap<>();
+
+            postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToData, hyperHost, context);
+
+            //
+            // Power-on VM
+            //
+            if (!vmMo.powerOn()) {
+                throw new Exception("Failed to start VM. vmName: " + vmInternalCSName + " with hostname " + vmNameOnVcenter);
+            }
+
+            StartAnswer startAnswer = new StartAnswer(cmd);
+
+            startAnswer.setIqnToData(iqnToData);
+
+            // Since VM was successfully powered-on, if there was an existing VM in a different cluster that was unregistered, delete all the files associated with it.
+            if (existingVmName != null && existingVmFileLayout != null) {
+                List<String> vmDatastoreNames = new ArrayList<String>();
+                for (DatastoreMO vmDatastore : vmMo.getAllDatastores()) {
+                    vmDatastoreNames.add(vmDatastore.getName());
+                }
+                // Don't delete files that are in a datastore that is being used by the new VM as well (zone-wide datastore).
+                List<String> skipDatastores = new ArrayList<String>();
+                for (DatastoreMO existingDatastore : existingDatastores) {
+                    if (vmDatastoreNames.contains(existingDatastore.getName())) {
+                        skipDatastores.add(existingDatastore.getName());
+                    }
+                }
+                deleteUnregisteredVmFiles(existingVmFileLayout, dcMo, true, skipDatastores);
+            }
+
+            return startAnswer;
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "StartCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.warn(msg, e);
+            StartAnswer startAnswer = new StartAnswer(cmd, msg);
+            if (vmAlreadyExistsInVcenter) {
+                startAnswer.setContextParam("stopRetry", "true");
+            }
+
+            // Since VM start failed, if there was an existing VM in a different cluster that was unregistered, register it back.
+            if (existingVmName != null && existingVmFileInfo != null) {
+                s_logger.debug("Since VM start failed, registering back an existing VM: " + existingVmName + " that was unregistered");
+                try {
+                    DatastoreFile fileInDatastore = new DatastoreFile(existingVmFileInfo.getVmPathName());
+                    DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
+                    registerVm(existingVmName, existingVmDsMo);
+                } catch (Exception ex) {
+                    String message = "Failed to register an existing VM: " + existingVmName + " due to " + VmwareHelper.getExceptionMessage(ex);
+                    s_logger.warn(message, ex);
+                }
+            }
+
+            return startAnswer;
+        } finally {
+        }
+    }
+
+    private String appendFileType(String path, String fileType) {
+        if (path.toLowerCase().endsWith(fileType.toLowerCase())) {
+            return path;
+        }
+
+        return path + fileType;
+    }
+
+    private void resizeRootDiskOnVMStart(VirtualMachineMO vmMo, DiskTO rootDiskTO, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
+        final Pair<VirtualDisk, String> vdisk = getVirtualDiskInfo(vmMo, appendFileType(rootDiskTO.getPath(), VMDK_EXTENSION));
+        assert(vdisk != null);
+
+        Long reqSize = 0L;
+        final VolumeObjectTO volumeTO = ((VolumeObjectTO)rootDiskTO.getData());
+        if (volumeTO != null) {
+            reqSize = volumeTO.getSize() / 1024;
+        }
+        final VirtualDisk disk = vdisk.first();
+        if (reqSize > disk.getCapacityInKB()) {
+            final VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(vmMo.getDiskInfoBuilder(), rootDiskTO, hyperHost, context);
+            assert (diskInfo != null);
+            final String[] diskChain = diskInfo.getDiskChain();
+
+            if (diskChain != null && diskChain.length > 1) {
+                s_logger.warn("Disk chain length for the VM is greater than one, this is not supported");
+                throw new CloudRuntimeException("Unsupported VM disk chain length: "+ diskChain.length);
+            }
+
+            boolean resizingSupported = false;
+            String deviceBusName = diskInfo.getDiskDeviceBusName();
+            if (deviceBusName != null && (deviceBusName.toLowerCase().contains("scsi") || deviceBusName.toLowerCase().contains("lsi"))) {
+                resizingSupported = true;
+            }
+            if (!resizingSupported) {
+                s_logger.warn("Resizing of root disk is only support for scsi device/bus, the provide VM's disk device bus name is " + diskInfo.getDiskDeviceBusName());
+                throw new CloudRuntimeException("Unsupported VM root disk device bus: "+ diskInfo.getDiskDeviceBusName());
+            }
+
+            disk.setCapacityInKB(reqSize);
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(disk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure VM for given root disk size. vmName: " + vmMo.getName());
+            }
+        }
+    }
+
+
+    /**
+     * Generate the mac sequence from the nics.
+     */
+    protected String generateMacSequence(NicTO[] nics) {
+        if (nics.length == 0) {
+            return "";
+        }
+
+        StringBuffer sbMacSequence = new StringBuffer();
+        for (NicTO nicTo : sortNicsByDeviceId(nics)) {
+            sbMacSequence.append(nicTo.getMac()).append("|");
+        }
+        if (!sbMacSequence.toString().isEmpty()) {
+            sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); //Remove extra '|' char appended at the end
+        }
+
+        return sbMacSequence.toString();
+    }
+
+    /**
+     * Update boot args with the new nic mac addresses.
+     */
+    protected String replaceNicsMacSequenceInBootArgs(String oldMacSequence, String newMacSequence, VirtualMachineTO vmSpec) {
+        String bootArgs = vmSpec.getBootArgs();
+        if (!StringUtils.isBlank(bootArgs) && !StringUtils.isBlank(oldMacSequence) && !StringUtils.isBlank(newMacSequence)) {
+            return bootArgs.replace(oldMacSequence, newMacSequence);
+        }
+        return "";
+    }
+
+    /**
+     * Sets video card memory to the one provided in detail svga.vramSize (if provided) on {@code vmConfigSpec}.
+     * 64MB was always set before.
+     * Size must be in KB.
+     * @param vmMo virtual machine mo
+     * @param vmSpec virtual machine specs
+     * @param vmConfigSpec virtual machine config spec
+     * @throws Exception exception
+     */
+    protected void configureVideoCard(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
+        if (vmSpec.getDetails().containsKey(VmDetailConstants.SVGA_VRAM_SIZE)) {
+            String value = vmSpec.getDetails().get(VmDetailConstants.SVGA_VRAM_SIZE);
+            try {
+                long svgaVmramSize = Long.parseLong(value);
+                setNewVRamSizeVmVideoCard(vmMo, svgaVmramSize, vmConfigSpec);
+            } catch (NumberFormatException e) {
+                s_logger.error("Unexpected value, cannot parse " + value + " to long due to: " + e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Search for vm video card iterating through vm device list
+     * @param vmMo virtual machine mo
+     * @param svgaVmramSize new svga vram size (in KB)
+     * @param vmConfigSpec virtual machine config spec
+     */
+    protected void setNewVRamSizeVmVideoCard(VirtualMachineMO vmMo, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
+        for (VirtualDevice device : vmMo.getAllDeviceList()) {
+            if (device instanceof VirtualMachineVideoCard) {
+                VirtualMachineVideoCard videoCard = (VirtualMachineVideoCard)device;
+                modifyVmVideoCardVRamSize(videoCard, vmMo, svgaVmramSize, vmConfigSpec);
+            }
+        }
+    }
+
+    /**
+     * Modifies vm vram size if it was set to a different size to the one provided in svga.vramSize (user_vm_details or template_vm_details) on {@code vmConfigSpec}
+     * @param videoCard vm's video card device
+     * @param vmMo virtual machine mo
+     * @param svgaVmramSize new svga vram size (in KB)
+     * @param vmConfigSpec virtual machine config spec
+     */
+    protected void modifyVmVideoCardVRamSize(VirtualMachineVideoCard videoCard, VirtualMachineMO vmMo, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) {
+        if (videoCard.getVideoRamSizeInKB().longValue() != svgaVmramSize) {
+            s_logger.info("Video card memory was set " + videoCard.getVideoRamSizeInKB().longValue() + "kb instead of " + svgaVmramSize + "kb");
+            configureSpecVideoCardNewVRamSize(videoCard, svgaVmramSize, vmConfigSpec);
+        }
+    }
+
+    /**
+     * Add edit spec on {@code vmConfigSpec} to modify svga vram size
+     * @param videoCard video card device to edit providing the svga vram size
+     * @param svgaVmramSize new svga vram size (in KB)
+     * @param vmConfigSpec virtual machine spec
+     */
+    protected void configureSpecVideoCardNewVRamSize(VirtualMachineVideoCard videoCard, long svgaVmramSize, VirtualMachineConfigSpec vmConfigSpec) {
+        videoCard.setVideoRamSizeInKB(svgaVmramSize);
+        videoCard.setUseAutoDetect(false);
+
+        VirtualDeviceConfigSpec arrayVideoCardConfigSpecs = new VirtualDeviceConfigSpec();
+        arrayVideoCardConfigSpecs.setDevice(videoCard);
+        arrayVideoCardConfigSpecs.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+        vmConfigSpec.getDeviceChange().add(arrayVideoCardConfigSpecs);
+    }
+
+    private void tearDownVm(VirtualMachineMO vmMo) throws Exception {
+
+        if (vmMo == null)
+            return;
+
+        boolean hasSnapshot = false;
+        hasSnapshot = vmMo.hasSnapshot();
+        if (!hasSnapshot)
+            vmMo.tearDownDevices(new Class<?>[] {VirtualDisk.class, VirtualEthernetCard.class});
+        else
+            vmMo.tearDownDevices(new Class<?>[] {VirtualEthernetCard.class});
+        vmMo.ensureScsiDeviceController();
+    }
+
+    int getReservedMemoryMb(VirtualMachineTO vmSpec) {
+        if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveMemory.key()).equalsIgnoreCase("true")) {
+            return (int)(vmSpec.getMinRam() / ResourceType.bytesToMiB);
+        }
+        return 0;
+    }
+
+    int getReservedCpuMHZ(VirtualMachineTO vmSpec) {
+        if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveCpu.key()).equalsIgnoreCase("true")) {
+            return vmSpec.getMinSpeed() * vmSpec.getCpus();
+        }
+        return 0;
+    }
+
+    // return the finalized disk chain for startup, from top to bottom
+    private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO vol, VirtualMachineDiskInfo diskInfo,
+            HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
+
+        VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+        DataStoreTO primaryStore = volumeTO.getDataStore();
+        Map<String, String> details = vol.getDetails();
+        boolean isManaged = false;
+        String iScsiName = null;
+
+        if (details != null) {
+            isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+            iScsiName = details.get(DiskTO.IQN);
+        }
+
+        // if the storage is managed, iScsiName should not be null
+        String datastoreName = isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
+        Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
+
+        if (volumeDsDetails == null) {
+            throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
+        }
+
+        DatastoreMO dsMo = volumeDsDetails.second();
+
+        // we will honor vCenter's meta if it exists
+        if (diskInfo != null) {
+            // to deal with run-time upgrade to maintain the new datastore folder structure
+            String disks[] = diskInfo.getDiskChain();
+            for (int i = 0; i < disks.length; i++) {
+                DatastoreFile file = new DatastoreFile(disks[i]);
+                if (!isManaged && file.getDir() != null && file.getDir().isEmpty()) {
+                    s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder");
+                    disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, file.getFileBaseName(), VmwareManager.s_vmwareSearchExcludeFolder.value());
+                }
+            }
+            return disks;
+        }
+
+        final String datastoreDiskPath;
+
+        if (isManaged) {
+            String vmdkPath = new DatastoreFile(volumeTO.getPath()).getFileBaseName();
+
+            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
+                if (vmdkPath == null) {
+                    vmdkPath = volumeTO.getName();
+                }
+
+                datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, vmdkPath);
+            }
+            else {
+                if (vmdkPath == null) {
+                    vmdkPath = dsMo.getName();
+                }
+
+                datastoreDiskPath = dsMo.getDatastorePath(vmdkPath + VMDK_EXTENSION);
+            }
+        } else {
+            datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
+        }
+
+        if (!dsMo.fileExists(datastoreDiskPath)) {
+            s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath);
+        }
+
+        return new String[] {datastoreDiskPath};
+    }
+
+    // Pair<internal CS name, vCenter display name>
+    private Pair<String, String> composeVmNames(VirtualMachineTO vmSpec) {
+        String vmInternalCSName = vmSpec.getName();
+        String vmNameOnVcenter = vmSpec.getName();
+        if (_instanceNameFlag && vmSpec.getHostName() != null) {
+            vmNameOnVcenter = vmSpec.getHostName();
+        }
+        return new Pair<String, String>(vmInternalCSName, vmNameOnVcenter);
+    }
+
+    protected void configNestedHVSupport(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
+
+        VmwareContext context = vmMo.getContext();
+        if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) {
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability");
+
+            ManagedObjectReference hostMor = vmMo.getRunningHost().getMor();
+            ManagedObjectReference computeMor = context.getVimClient().getMoRefProp(hostMor, "parent");
+            ManagedObjectReference environmentBrowser = context.getVimClient().getMoRefProp(computeMor, "environmentBrowser");
+            HostCapability hostCapability = context.getService().queryTargetCapabilities(environmentBrowser, hostMor);
+            Boolean nestedHvSupported = hostCapability.isNestedHVSupported();
+            if (nestedHvSupported == null) {
+                // nestedHvEnabled property is supported only since VMware 5.1. It's not defined for earlier versions.
+                s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " + vmSpec.getName());
+            } else if (nestedHvSupported.booleanValue()) {
+                s_logger.debug("Hypervisor supports nested virtualization, enabling for VM " + vmSpec.getName());
+                vmConfigSpec.setNestedHVEnabled(true);
+            } else {
+                s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " + vmSpec.getName());
+                vmConfigSpec.setNestedHVEnabled(false);
+            }
+        }
+    }
+
+    private static void configBasicExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
+        OptionValue newVal = new OptionValue();
+        newVal.setKey("machine.id");
+        newVal.setValue(vmSpec.getBootArgs());
+        extraOptions.add(newVal);
+
+        newVal = new OptionValue();
+        newVal.setKey("devices.hotplug");
+        newVal.setValue("true");
+        extraOptions.add(newVal);
+    }
+
+    private static void configNvpExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec, Map<String, String> nicUuidToDvSwitchUuid) {
+        /**
+         * Extra Config : nvp.vm-uuid = uuid
+         *  - Required for Nicira NVP integration
+         */
+        OptionValue newVal = new OptionValue();
+        newVal.setKey("nvp.vm-uuid");
+        newVal.setValue(vmSpec.getUuid());
+        extraOptions.add(newVal);
+
+        /**
+         * Extra Config : nvp.iface-id.<num> = uuid
+         *  - Required for Nicira NVP integration
+         */
+        int nicNum = 0;
+        for (NicTO nicTo : sortNicsByDeviceId(vmSpec.getNics())) {
+            if (nicTo.getUuid() != null) {
+                newVal = new OptionValue();
+                newVal.setKey("nvp.iface-id." + nicNum);
+                newVal.setValue(nicTo.getUuid());
+                extraOptions.add(newVal);
+                setNuageVspVrIpInExtraConfig(extraOptions, nicTo, nicUuidToDvSwitchUuid.get(nicTo.getUuid()));
+            }
+            nicNum++;
+        }
+    }
+
+    private static void setNuageVspVrIpInExtraConfig(List<OptionValue> extraOptions, NicTO nicTo, String dvSwitchUuid) {
+        if (nicTo.getBroadcastType() != BroadcastDomainType.Vsp) {
+            return;
+        }
+
+        OptionValue newVal;
+        if (nicTo.getType().equals(TrafficType.Guest) && dvSwitchUuid != null && nicTo.getGateway() != null && nicTo.getNetmask() != null) {
+            String vrIp = nicTo.getBroadcastUri().getPath().substring(1);
+            newVal = new OptionValue();
+            newVal.setKey("vsp.vr-ip." + nicTo.getMac());
+            newVal.setValue(vrIp);
+            extraOptions.add(newVal);
+            newVal = new OptionValue();
+            newVal.setKey("vsp.dvswitch." + nicTo.getMac());
+            newVal.setValue(dvSwitchUuid);
+            extraOptions.add(newVal);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NIC with MAC " + nicTo.getMac() + " and BroadcastDomainType " + nicTo.getBroadcastType() + " in network(" + nicTo.getGateway() + "/"
+                        + nicTo.getNetmask() + ") is " + nicTo.getType() + " traffic type. So, vsp-vr-ip is set in the extraconfig");
+            }
+        }
+    }
+
+    private static void configCustomExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) {
+        // we no longer to validation anymore
+        for (Map.Entry<String, String> entry : vmSpec.getDetails().entrySet()) {
+            OptionValue newVal = new OptionValue();
+            newVal.setKey(entry.getKey());
+            newVal.setValue(entry.getValue());
+            extraOptions.add(newVal);
+        }
+    }
+
+    private static void postNvpConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec) throws Exception {
+        /**
+         * We need to configure the port on the DV switch after the host is
+         * connected. So make this happen between the configure and start of
+         * the VM
+         */
+        int nicIndex = 0;
+        for (NicTO nicTo : sortNicsByDeviceId(vmSpec.getNics())) {
+            if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
+                // We need to create a port with a unique vlan and pass the key to the nic device
+                s_logger.trace("Nic " + nicTo.toString() + " is connected to an NVP logicalswitch");
+                VirtualDevice nicVirtualDevice = vmMo.getNicDeviceByIndex(nicIndex);
+                if (nicVirtualDevice == null) {
+                    throw new Exception("Failed to find a VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
+                }
+                VirtualDeviceBackingInfo backing = nicVirtualDevice.getBacking();
+                if (backing instanceof VirtualEthernetCardDistributedVirtualPortBackingInfo) {
+                    // This NIC is connected to a Distributed Virtual Switch
+                    VirtualEthernetCardDistributedVirtualPortBackingInfo portInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo)backing;
+                    DistributedVirtualSwitchPortConnection port = portInfo.getPort();
+                    String portKey = port.getPortKey();
+                    String portGroupKey = port.getPortgroupKey();
+                    String dvSwitchUuid = port.getSwitchUuid();
+
+                    s_logger.debug("NIC " + nicTo.toString() + " is connected to dvSwitch " + dvSwitchUuid + " pg " + portGroupKey + " port " + portKey);
+
+                    ManagedObjectReference dvSwitchManager = vmMo.getContext().getVimClient().getServiceContent().getDvSwitchManager();
+                    ManagedObjectReference dvSwitch = vmMo.getContext().getVimClient().getService().queryDvsByUuid(dvSwitchManager, dvSwitchUuid);
+
+                    // Get all ports
+                    DistributedVirtualSwitchPortCriteria criteria = new DistributedVirtualSwitchPortCriteria();
+                    criteria.setInside(true);
+                    criteria.getPortgroupKey().add(portGroupKey);
+                    List<DistributedVirtualPort> dvPorts = vmMo.getContext().getVimClient().getService().fetchDVPorts(dvSwitch, criteria);
+
+                    DistributedVirtualPort vmDvPort = null;
+                    List<Integer> usedVlans = new ArrayList<Integer>();
+                    for (DistributedVirtualPort dvPort : dvPorts) {
+                        // Find the port for this NIC by portkey
+                        if (portKey.equals(dvPort.getKey())) {
+                            vmDvPort = dvPort;
+                        }
+                        VMwareDVSPortSetting settings = (VMwareDVSPortSetting)dvPort.getConfig().getSetting();
+                        VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec)settings.getVlan();
+                        s_logger.trace("Found port " + dvPort.getKey() + " with vlan " + vlanId.getVlanId());
+                        if (vlanId.getVlanId() > 0 && vlanId.getVlanId() < 4095) {
+                            usedVlans.add(vlanId.getVlanId());
+                        }
+                    }
+
+                    if (vmDvPort == null) {
+                        throw new Exception("Empty port list from dvSwitch for nic " + nicTo.toString());
+                    }
+
+                    DVPortConfigInfo dvPortConfigInfo = vmDvPort.getConfig();
+                    VMwareDVSPortSetting settings = (VMwareDVSPortSetting)dvPortConfigInfo.getSetting();
+
+                    VmwareDistributedVirtualSwitchVlanIdSpec vlanId = (VmwareDistributedVirtualSwitchVlanIdSpec)settings.getVlan();
+                    BoolPolicy blocked = settings.getBlocked();
+                    if (blocked.isValue() == Boolean.TRUE) {
+                        s_logger.trace("Port is blocked, set a vlanid and unblock");
+                        DVPortConfigSpec dvPortConfigSpec = new DVPortConfigSpec();
+                        VMwareDVSPortSetting edittedSettings = new VMwareDVSPortSetting();
+                        // Unblock
+                        blocked.setValue(Boolean.FALSE);
+                        blocked.setInherited(Boolean.FALSE);
+                        edittedSettings.setBlocked(blocked);
+                        // Set vlan
+                        int i;
+                        for (i = 1; i < 4095; i++) {
+                            if (!usedVlans.contains(i))
+                                break;
+                        }
+                        vlanId.setVlanId(i); // FIXME should be a determined
+                        // based on usage
+                        vlanId.setInherited(false);
+                        edittedSettings.setVlan(vlanId);
+
+                        dvPortConfigSpec.setSetting(edittedSettings);
+                        dvPortConfigSpec.setOperation("edit");
+                        dvPortConfigSpec.setKey(portKey);
+                        List<DVPortConfigSpec> dvPortConfigSpecs = new ArrayList<DVPortConfigSpec>();
+                        dvPortConfigSpecs.add(dvPortConfigSpec);
+                        ManagedObjectReference task = vmMo.getContext().getVimClient().getService().reconfigureDVPortTask(dvSwitch, dvPortConfigSpecs);
+                        if (!vmMo.getContext().getVimClient().waitForTask(task)) {
+                            throw new Exception("Failed to configure the dvSwitch port for nic " + nicTo.toString());
+                        }
+                        s_logger.debug("NIC " + nicTo.toString() + " connected to vlan " + i);
+                    } else {
+                        s_logger.trace("Port already configured and set to vlan " + vlanId.getVlanId());
+                    }
+                } else if (backing instanceof VirtualEthernetCardNetworkBackingInfo) {
+                    // This NIC is connected to a Virtual Switch
+                    // Nothing to do
+                } else if (backing instanceof VirtualEthernetCardOpaqueNetworkBackingInfo) {
+                    //if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
+                    //OK, connected to OpaqueNetwork
+                } else {
+                    s_logger.error("nic device backing is of type " + backing.getClass().getName());
+                    throw new Exception("Incompatible backing for a VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
+                }
+            }
+            nicIndex++;
+        }
+    }
+
+    private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol, VmwareHypervisorHost hyperHost, VmwareContext context)
+            throws Exception {
+        if (diskInfoBuilder != null) {
+            VolumeObjectTO volume = (VolumeObjectTO)vol.getData();
+
+            String dsName = null;
+            String diskBackingFileBaseName = null;
+
+            Map<String, String> details = vol.getDetails();
+            boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+            if (isManaged) {
+                String iScsiName = details.get(DiskTO.IQN);
+
+                // if the storage is managed, iScsiName should not be null
+                dsName = VmwareResource.getDatastoreName(iScsiName);
+
+                diskBackingFileBaseName = new DatastoreFile(volume.getPath()).getFileBaseName();
+            } else {
+                ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid());
+                DatastoreMO dsMo = new DatastoreMO(context, morDs);
+
+                dsName = dsMo.getName();
+
+                diskBackingFileBaseName = volume.getPath();
+            }
+
+            VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
+            if (diskInfo != null) {
+                s_logger.info("Found existing disk info from volume path: " + volume.getPath());
+                return diskInfo;
+            } else {
+                String chainInfo = volume.getChainInfo();
+                if (chainInfo != null) {
+                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
+                    if (infoInChain != null) {
+                        String[] disks = infoInChain.getDiskChain();
+                        if (disks.length > 0) {
+                            for (String diskPath : disks) {
+                                DatastoreFile file = new DatastoreFile(diskPath);
+                                diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
+                                if (diskInfo != null) {
+                                    s_logger.info("Found existing disk from chain info: " + diskPath);
+                                    return diskInfo;
+                                }
+                            }
+                        }
+
+                        if (diskInfo == null) {
+                            diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(infoInChain.getDiskDeviceBusName());
+                            if (diskInfo != null) {
+                                s_logger.info("Found existing disk from from chain device bus information: " + infoInChain.getDiskDeviceBusName());
+                                return diskInfo;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private int getDiskController(VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, VirtualMachineTO vmSpec, int ideControllerKey, int scsiControllerKey) {
+
+        int controllerKey;
+        if (matchingExistingDisk != null) {
+            s_logger.info("Chose disk controller based on existing information: " + matchingExistingDisk.getDiskDeviceBusName());
+            if (matchingExistingDisk.getDiskDeviceBusName().startsWith("ide"))
+                return ideControllerKey;
+            else
+                return scsiControllerKey;
+        }
+
+        if (vol.getType() == Volume.Type.ROOT) {
+            Map<String, String> vmDetails = vmSpec.getDetails();
+            if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER) != null) {
+                if (vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER).equalsIgnoreCase("scsi")) {
+                    s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: "
+                            + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
+                    controllerKey = scsiControllerKey;
+                } else {
+                    s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: "
+                            + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
+                    controllerKey = ideControllerKey;
+                }
+            } else {
+                s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi. due to null root disk controller setting");
+                controllerKey = scsiControllerKey;
+            }
+
+        } else {
+            // DATA volume always use SCSI device
+            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi");
+            controllerKey = scsiControllerKey;
+        }
+
+        return controllerKey;
+    }
+
+    private String getDiskController(VirtualMachineMO vmMo, VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, Pair<String, String> controllerInfo) throws Exception {
+        int controllerKey;
+        DiskControllerType controllerType = DiskControllerType.none;
+        if (matchingExistingDisk != null) {
+            String currentBusName = matchingExistingDisk.getDiskDeviceBusName();
+            if (currentBusName != null) {
+                s_logger.info("Chose disk controller based on existing information: " + currentBusName);
+                if (currentBusName.startsWith("ide")) {
+                    controllerType = DiskControllerType.ide;
+                } else if (currentBusName.startsWith("scsi")) {
+                    controllerType = DiskControllerType.scsi;
+                }
+            }
+            if (controllerType == DiskControllerType.scsi || controllerType == DiskControllerType.none) {
+                Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
+                controllerType = vmScsiControllerInfo.third();
+            }
+            return controllerType.toString();
+        }
+
+        if (vol.getType() == Volume.Type.ROOT) {
+            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.first()
+                    + ", based on root disk controller settings at global configuration setting.");
+            return controllerInfo.first();
+        } else {
+            s_logger.info("Chose disk controller for vol " + vol.getType() + " -> " + controllerInfo.second()
+                    + ", based on default data disk controller setting i.e. Operating system recommended."); // Need to bring in global configuration setting & template level setting.
+            return controllerInfo.second();
+        }
+    }
+
+    private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey,
+            int scsiControllerKey, Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
+        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
+
+        for (DiskTO vol : sortedDisks) {
+            if (vol.getType() == Volume.Type.ISO)
+                continue;
+
+            VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+
+            VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
+            assert (diskInfo != null);
+
+            String[] diskChain = diskInfo.getDiskChain();
+            assert (diskChain.length > 0);
+
+            Map<String, String> details = vol.getDetails();
+            boolean managed = false;
+
+            if (details != null) {
+                managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+            }
+
+            DatastoreFile file = new DatastoreFile(diskChain[0]);
+
+            if (managed) {
+                DatastoreFile originalFile = new DatastoreFile(volumeTO.getPath());
+
+                if (!file.getFileBaseName().equalsIgnoreCase(originalFile.getFileBaseName())) {
+                    if (s_logger.isInfoEnabled())
+                        s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + diskChain[0]);
+                }
+            } else {
+                if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) {
+                    if (s_logger.isInfoEnabled())
+                        s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName());
+                }
+            }
+
+            VolumeObjectTO volInSpec = getVolumeInSpec(vmSpec, volumeTO);
+
+            if (volInSpec != null) {
+                if (managed) {
+                    Map<String, String> data = new HashMap<>();
+
+                    String datastoreVolumePath = diskChain[0];
+
+                    data.put(StartAnswer.PATH, datastoreVolumePath);
+                    data.put(StartAnswer.IMAGE_FORMAT, Storage.ImageFormat.OVA.toString());
+
+                    iqnToData.put(details.get(DiskTO.IQN), data);
+
+                    vol.setPath(datastoreVolumePath);
+                    volumeTO.setPath(datastoreVolumePath);
+                    volInSpec.setPath(datastoreVolumePath);
+                } else {
+                    volInSpec.setPath(file.getFileBaseName());
+                }
+                volInSpec.setChainInfo(_gson.toJson(diskInfo));
+            }
+        }
+    }
+
+    private void checkAndDeleteDatastoreFile(String filePath, List<String> skipDatastores, DatastoreMO dsMo, DatacenterMO dcMo) throws Exception {
+        if (dsMo != null && dcMo != null && (skipDatastores == null || !skipDatastores.contains(dsMo.getName()))) {
+            s_logger.debug("Deleting file: " + filePath);
+            dsMo.deleteFile(filePath, dcMo.getMor(), true);
+        }
+    }
+
+    private void deleteUnregisteredVmFiles(VirtualMachineFileLayoutEx vmFileLayout, DatacenterMO dcMo, boolean deleteDisks, List<String> skipDatastores) throws Exception {
+        s_logger.debug("Deleting files associated with an existing VM that was unregistered");
+        DatastoreFile vmFolder = null;
+        try {
+            List<VirtualMachineFileLayoutExFileInfo> fileInfo = vmFileLayout.getFile();
+            for (VirtualMachineFileLayoutExFileInfo file : fileInfo) {
+                DatastoreFile fileInDatastore = new DatastoreFile(file.getName());
+                // In case of linked clones, VM file layout includes the base disk so don't delete all disk files.
+                if (file.getType().startsWith("disk") || file.getType().startsWith("digest"))
+                    continue;
+                else if (file.getType().equals("config"))
+                    vmFolder = new DatastoreFile(fileInDatastore.getDatastoreName(), fileInDatastore.getDir());
+                DatastoreMO dsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
+                checkAndDeleteDatastoreFile(file.getName(), skipDatastores, dsMo, dcMo);
+            }
+            // Delete files that are present in the VM folder - this will take care of the VM disks as well.
+            DatastoreMO vmFolderDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(vmFolder.getDatastoreName()));
+            String[] files = vmFolderDsMo.listDirContent(vmFolder.getPath());
+            if (deleteDisks) {
+                for (String file : files) {
+                    String vmDiskFileFullPath = String.format("%s/%s", vmFolder.getPath(), file);
+                    checkAndDeleteDatastoreFile(vmDiskFileFullPath, skipDatastores, vmFolderDsMo, dcMo);
+                }
+            }
+            // Delete VM folder
+            if (deleteDisks || files.length == 0) {
+                checkAndDeleteDatastoreFile(vmFolder.getPath(), skipDatastores, vmFolderDsMo, dcMo);
+            }
+        } catch (Exception e) {
+            String message = "Failed to delete files associated with an existing VM that was unregistered due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.warn(message, e);
+        }
+    }
+
+    private static VolumeObjectTO getVolumeInSpec(VirtualMachineTO vmSpec, VolumeObjectTO srcVol) {
+        for (DiskTO disk : vmSpec.getDisks()) {
+            if (disk.getData() instanceof VolumeObjectTO) {
+                VolumeObjectTO vol = (VolumeObjectTO) disk.getData();
+                if (vol.getId() == srcVol.getId())
+                    return vol;
+            }
+        }
+
+        return null;
+    }
+
+    private static NicTO[] sortNicsByDeviceId(NicTO[] nics) {
+
+        List<NicTO> listForSort = new ArrayList<NicTO>();
+        for (NicTO nic : nics) {
+            listForSort.add(nic);
+        }
+        Collections.sort(listForSort, new Comparator<NicTO>() {
+
+            @Override
+            public int compare(NicTO arg0, NicTO arg1) {
+                if (arg0.getDeviceId() < arg1.getDeviceId()) {
+                    return -1;
+                } else if (arg0.getDeviceId() == arg1.getDeviceId()) {
+                    return 0;
+                }
+
+                return 1;
+            }
+        });
+
+        return listForSort.toArray(new NicTO[0]);
+    }
+
+    private static DiskTO[] sortVolumesByDeviceId(DiskTO[] volumes) {
+
+        List<DiskTO> listForSort = new ArrayList<DiskTO>();
+        for (DiskTO vol : volumes) {
+            listForSort.add(vol);
+        }
+        Collections.sort(listForSort, new Comparator<DiskTO>() {
+
+            @Override
+            public int compare(DiskTO arg0, DiskTO arg1) {
+                if (arg0.getDiskSeq() < arg1.getDiskSeq()) {
+                    return -1;
+                } else if (arg0.getDiskSeq().equals(arg1.getDiskSeq())) {
+                    return 0;
+                }
+
+                return 1;
+            }
+        });
+
+        return listForSort.toArray(new DiskTO[0]);
+    }
+
+    /**
+     * Only call this for managed storage.
+     * Ex. "[-iqn.2010-01.com.solidfire:4nhe.vol-1.27-0] i-2-18-VM/ROOT-18.vmdk" should return "i-2-18-VM/ROOT-18"
+     */
+    public String getVmdkPath(String path) {
+        if (!StringUtils.isNotBlank(path)) {
+            return null;
+        }
+
+        final String search = "]";
+
+        int startIndex = path.indexOf(search);
+
+        if (startIndex == -1) {
+            return null;
+        }
+
+        path = path.substring(startIndex + search.length());
+
+        final String search2 = VMDK_EXTENSION;
+
+        int endIndex = path.indexOf(search2);
+
+        if (endIndex == -1) {
+            return null;
+        }
+
+        return path.substring(0, endIndex).trim();
+    }
+
+    private HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context,
+            DiskTO[] disks, Command cmd) throws Exception {
+        HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> mapIdToMors = new HashMap<>();
+
+        assert (hyperHost != null) && (context != null);
+
+        for (DiskTO vol : disks) {
+            if (vol.getType() != Volume.Type.ISO) {
+                VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData();
+                DataStoreTO primaryStore = volumeTO.getDataStore();
+                String poolUuid = primaryStore.getUuid();
+
+                if (mapIdToMors.get(poolUuid) == null) {
+                    boolean isManaged = false;
+                    Map<String, String> details = vol.getDetails();
+
+                    if (details != null) {
+                        isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                    }
+
+                    if (isManaged) {
+                        String iScsiName = details.get(DiskTO.IQN); // details should not be null for managed storage (it may or may not be null for non-managed storage)
+                        String datastoreName = VmwareResource.getDatastoreName(iScsiName);
+                        ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
+
+                        // if the datastore is not present, we need to discover the iSCSI device that will support it,
+                        // create the datastore, and create a VMDK file in the datastore
+                        if (morDatastore == null) {
+                            final String vmdkPath = getVmdkPath(volumeTO.getPath());
+
+                            morDatastore = _storageProcessor.prepareManagedStorage(context, hyperHost, null, iScsiName,
+                                    details.get(DiskTO.STORAGE_HOST), Integer.parseInt(details.get(DiskTO.STORAGE_PORT)),
+                                    vmdkPath,
+                                    details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
+                                    details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
+                                    Long.parseLong(details.get(DiskTO.VOLUME_SIZE)), cmd);
+
+                            DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDatastore);
+
+                            final String datastoreVolumePath;
+
+                            if (vmdkPath != null) {
+                                datastoreVolumePath = dsMo.getDatastorePath(vmdkPath + VMDK_EXTENSION);
+                            }
+                            else {
+                                datastoreVolumePath = dsMo.getDatastorePath(dsMo.getName() + VMDK_EXTENSION);
+                            }
+
+                            volumeTO.setPath(datastoreVolumePath);
+                            vol.setPath(datastoreVolumePath);
+                        }
+
+                        mapIdToMors.put(datastoreName, new Pair<>(morDatastore, new DatastoreMO(context, morDatastore)));
+                    }
+                    else {
+                        ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid);
+
+                        if (morDatastore == null) {
+                            String msg = "Failed to get the mounted datastore for the volume's pool " + poolUuid;
+
+                            s_logger.error(msg);
+
+                            throw new Exception(msg);
+                        }
+
+                        mapIdToMors.put(poolUuid, new Pair<>(morDatastore, new DatastoreMO(context, morDatastore)));
+                    }
+                }
+            }
+        }
+
+        return mapIdToMors;
+    }
+
+    private DatastoreMO getDatastoreThatRootDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO disks[]) {
+        Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
+
+        for (DiskTO vol : disks) {
+            if (vol.getType() == Volume.Type.ROOT) {
+                Map<String, String> details = vol.getDetails();
+                boolean managed = false;
+
+                if (details != null) {
+                    managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                }
+
+                if (managed) {
+                    String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
+
+                    rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
+
+                    break;
+                } else {
+                    DataStoreTO primaryStore = vol.getData().getDataStore();
+
+                    rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
+
+                    break;
+                }
+            }
+        }
+
+        if (rootDiskDataStoreDetails != null) {
+            return rootDiskDataStoreDetails.second();
+        }
+
+        return null;
+    }
+
+    private String getPvlanInfo(NicTO nicTo) {
+        if (nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
+            return NetUtils.getIsolatedPvlanFromUri(nicTo.getBroadcastUri());
+        }
+        return null;
+    }
+
+    private String getVlanInfo(NicTO nicTo, String defaultVlan) {
+        if (nicTo.getBroadcastType() == BroadcastDomainType.Native) {
+            return defaultVlan;
+        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan || nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
+            if (nicTo.getBroadcastUri() != null) {
+                if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan)
+                    // For vlan, the broadcast uri is of the form vlan://<vlanid>
+                    // BroadcastDomainType recogniizes and handles this.
+                    return BroadcastDomainType.getValue(nicTo.getBroadcastUri());
+                else
+                    // for pvlan, the broacast uri will be of the form pvlan://<vlanid>-i<pvlanid>
+                    // TODO consider the spread of functionality between BroadcastDomainType and NetUtils
+                    return NetUtils.getPrimaryPvlanFromUri(nicTo.getBroadcastUri());
+            } else {
+                s_logger.warn("BroadcastType is not claimed as VLAN or PVLAN, but without vlan info in broadcast URI. Use vlan info from labeling: " + defaultVlan);
+                return defaultVlan;
+            }
+        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
+            // We don't need to set any VLAN id for an NVP logical switch
+            return null;
+        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Storage) {
+            URI broadcastUri = nicTo.getBroadcastUri();
+            if (broadcastUri != null) {
+                String vlanId = BroadcastDomainType.getValue(broadcastUri);
+                s_logger.debug("Using VLAN [" + vlanId + "] from broadcast uri [" + broadcastUri + "]");
+                return vlanId;
+            }
+        }
+
+        s_logger.warn("Unrecognized broadcast type in VmwareResource, type: " + nicTo.getBroadcastType().toString() + ". Use vlan info from labeling: " + defaultVlan);
+        return defaultVlan;
+    }
+
+    private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType)
+            throws Exception {
+
+        Ternary<String, String, String> switchDetails = getTargetSwitch(nicTo);
+        VirtualSwitchType switchType = VirtualSwitchType.getType(switchDetails.second());
+        String switchName = switchDetails.first();
+        String vlanToken = switchDetails.third();
+
+        String namePrefix = getNetworkNamePrefix(nicTo);
+        Pair<ManagedObjectReference, String> networkInfo = null;
+
+        s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix);
+
+        if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
+            networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo,
+                    getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(),
+                    _opsTimeout, true, nicTo.getBroadcastType(), nicTo.getUuid(), nicTo.getDetails());
+        }
+        else {
+            String vlanId = getVlanInfo(nicTo, vlanToken);
+            String svlanId = null;
+            boolean pvlannetwork = (getPvlanInfo(nicTo) == null) ? false : true;
+            if (vmType != null && vmType.equals(VirtualMachine.Type.DomainRouter) && pvlannetwork) {
+                // plumb this network to the promiscuous vlan.
+                svlanId = vlanId;
+            } else {
+                // plumb this network to the isolated vlan.
+                svlanId = getPvlanInfo(nicTo);
+            }
+            networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId,
+                    nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType,
+                    _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails());
+        }
+
+        return networkInfo;
+    }
+
+    // return Ternary <switch name, switch tyep, vlan tagging>
+    private Ternary<String, String, String> getTargetSwitch(NicTO nicTo) throws CloudException {
+        TrafficType[] supportedTrafficTypes = new TrafficType[] {TrafficType.Guest, TrafficType.Public, TrafficType.Control, TrafficType.Management, TrafficType.Storage};
+
+        TrafficType trafficType = nicTo.getType();
+        if (!Arrays.asList(supportedTrafficTypes).contains(trafficType)) {
+            throw new CloudException("Traffic type " + trafficType.toString() + " for nic " + nicTo.toString() + " is not supported.");
+        }
+
+        String switchName = null;
+        VirtualSwitchType switchType = VirtualSwitchType.StandardVirtualSwitch;
+        String vlanId = Vlan.UNTAGGED;
+
+        if (StringUtils.isNotBlank(nicTo.getName())) {
+            // Format of network traffic label is <VSWITCH>,<VLANID>,<VSWITCHTYPE>
+            // If all 3 fields are mentioned then number of tokens would be 3.
+            // If only <VSWITCH>,<VLANID> are mentioned then number of tokens would be 2.
+            // Get switch details from the nicTO object
+            String networkName = nicTo.getName();
+            VmwareTrafficLabel mgmtTrafficLabelObj = new VmwareTrafficLabel(networkName, trafficType);
+            switchName = mgmtTrafficLabelObj.getVirtualSwitchName();
+            vlanId = mgmtTrafficLabelObj.getVlanId();
+            switchType = mgmtTrafficLabelObj.getVirtualSwitchType();
+        } else {
+            if (trafficType == TrafficType.Guest && _guestTrafficInfo != null) {
+                switchType = _guestTrafficInfo.getVirtualSwitchType();
+                switchName = _guestTrafficInfo.getVirtualSwitchName();
+            } else if (trafficType == TrafficType.Public && _publicTrafficInfo != null) {
+                switchType = _publicTrafficInfo.getVirtualSwitchType();
+                switchName = _publicTrafficInfo.getVirtualSwitchName();
+            }
+        }
+
+        if (switchName == null
+                && (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management || nicTo.getType() == Networks.TrafficType.Storage)) {
+            switchName = _privateNetworkVSwitchName;
+        }
+
+        if (switchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
+            if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) {
+                throw new CloudException(
+                        "Unable to configure NIC " + nicTo.toString() + " as traffic type " + trafficType.toString() + " is not supported over virtual switch type " + switchType
+                                + ". Please specify only supported type of virtual switches i.e. {vmwaresvs, vmwaredvs} in physical network traffic label.");
+            }
+        }
+
+        return new Ternary<String, String, String>(switchName, switchType.toString(), vlanId);
+    }
+
+    private String getNetworkNamePrefix(NicTO nicTo) throws Exception {
+        if (nicTo.getType() == Networks.TrafficType.Guest) {
+            return "cloud.guest";
+        } else if (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management) {
+            return "cloud.private";
+        } else if (nicTo.getType() == Networks.TrafficType.Public) {
+            return "cloud.public";
+        } else if (nicTo.getType() == Networks.TrafficType.Storage) {
+            return "cloud.storage";
+        } else if (nicTo.getType() == Networks.TrafficType.Vpn) {
+            throw new Exception("Unsupported traffic type: " + nicTo.getType().toString());
+        } else {
+            throw new Exception("Unsupported traffic type: " + nicTo.getType().toString());
+        }
+    }
+
+    private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost hyperHost, String vmName) throws Exception {
+
+        VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+        if (vmMo != null) {
+            ManagedObjectReference morTargetPhysicalHost = hyperHost.findMigrationTarget(vmMo);
+            if (morTargetPhysicalHost == null) {
+                String msg = "VM " + vmName + " is on other host and we have no resource available to migrate and start it here";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            if (!vmMo.relocate(morTargetPhysicalHost)) {
+                String msg = "VM " + vmName + " is on other host and we failed to relocate it here";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            return vmMo;
+        }
+        return null;
+    }
+
+    // isoUrl sample content :
+    // nfs://192.168.10.231/export/home/kelven/vmware-test/secondary/template/tmpl/2/200//200-2-80f7ee58-6eff-3a2d-bcb0-59663edf6d26.iso
+    private Pair<String, ManagedObjectReference> getIsoDatastoreInfo(VmwareHypervisorHost hyperHost, String isoUrl) throws Exception {
+
+        assert (isoUrl != null);
+        int isoFileNameStartPos = isoUrl.lastIndexOf("/");
+        if (isoFileNameStartPos < 0) {
+            throw new Exception("Invalid ISO path info");
+        }
+
+        String isoFileName = isoUrl.substring(isoFileNameStartPos);
+
+        int templateRootPos = isoUrl.indexOf("template/tmpl");
+        templateRootPos = (templateRootPos < 0 ? isoUrl.indexOf(ConfigDrive.CONFIGDRIVEDIR) : templateRootPos);
+        if (templateRootPos < 0 ) {
+            throw new Exception("Invalid ISO path info");
+        }
+
+        String storeUrl = isoUrl.substring(0, templateRootPos - 1);
+        String isoPath = isoUrl.substring(templateRootPos, isoFileNameStartPos);
+
+        ManagedObjectReference morDs = prepareSecondaryDatastoreOnHost(storeUrl);
+        DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs);
+
+        return new Pair<String, ManagedObjectReference>(String.format("[%s] %s%s", dsMo.getName(), isoPath, isoFileName), morDs);
+    }
+
+    protected Answer execute(ReadyCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ReadyCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            if (hyperHost.isHyperHostConnected()) {
+                return new ReadyAnswer(cmd);
+            } else {
+                return new ReadyAnswer(cmd, "Host is not in connect state");
+            }
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new ReadyAnswer(cmd, VmwareHelper.getExceptionMessage(e));
+        }
+    }
+
+    protected Answer execute(GetHostStatsCommand cmd) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Executing resource GetHostStatsCommand: " + _gson.toJson(cmd));
+        }
+
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+        HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 0, 0, "host", 0, 0, 0, 0);
+        Answer answer = new GetHostStatsAnswer(cmd, hostStats);
+        try {
+            HostStatsEntry entry = getHyperHostStats(hyperHost);
+            if (entry != null) {
+                entry.setHostId(cmd.getHostId());
+                answer = new GetHostStatsAnswer(cmd, entry);
+            }
+        } catch (Exception e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "Unable to execute GetHostStatsCommand due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("GetHostStats Answer: " + _gson.toJson(answer));
+        }
+
+        return answer;
+    }
+
+    protected Answer execute(GetVmStatsCommand cmd) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Executing resource GetVmStatsCommand: " + _gson.toJson(cmd));
+        }
+
+        HashMap<String, VmStatsEntry> vmStatsMap = null;
+
+        try {
+            HashMap<String, PowerState> vmPowerStates = getVmStates();
+
+            // getVmNames should return all i-x-y values.
+            List<String> requestedVmNames = cmd.getVmNames();
+            List<String> vmNames = new ArrayList<String>();
+
+            if (requestedVmNames != null) {
+                for (String vmName : requestedVmNames) {
+                    if (vmPowerStates.get(vmName) != null) {
+                        vmNames.add(vmName);
+                    }
+                }
+            }
+
+            if (vmNames != null) {
+                vmStatsMap = getVmStats(vmNames);
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            s_logger.error("Unable to execute GetVmStatsCommand due to : " + VmwareHelper.getExceptionMessage(e), e);
+        }
+
+        Answer answer = new GetVmStatsAnswer(cmd, vmStatsMap);
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Report GetVmStatsAnswer: " + _gson.toJson(answer));
+        }
+        return answer;
+    }
+
+    protected Answer execute(GetVmDiskStatsCommand cmd) {
+        return new GetVmDiskStatsAnswer(cmd, null, null, null);
+    }
+
+    protected Answer execute(GetVmNetworkStatsCommand cmd) {
+        return new GetVmNetworkStatsAnswer(cmd, null, null, null);
+    }
+
+    protected GetVolumeStatsAnswer execute(GetVolumeStatsCommand cmd) {
+        try {
+            VmwareHypervisorHost srcHyperHost = getHyperHost(getServiceContext());
+            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, cmd.getPoolUuid());
+            assert (morDs != null);
+            DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(getServiceContext(), morDs);
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+            DatacenterMO dcMo = new DatacenterMO(getServiceContext(), dcMor);
+            HashMap<String, VolumeStatsEntry> statEntry = new HashMap<String, VolumeStatsEntry>();
+
+            for (String chainInfo : cmd.getVolumeUuids()){
+                if (chainInfo != null) {
+                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
+                    if (infoInChain != null) {
+                        String[] disks = infoInChain.getDiskChain();
+                        if (disks.length > 0) {
+                            for (String diskPath : disks) {
+                                DatastoreFile file = new DatastoreFile(diskPath);
+                                VirtualMachineMO vmMo = dcMo.findVm(file.getDir());
+                                Pair<VirtualDisk, String> vds = vmMo.getDiskDevice(file.getFileName(), true);
+                                long virtualsize = vds.first().getCapacityInKB() * 1024;
+                                long physicalsize = primaryStorageDatastoreMo.fileDiskSize(file.getPath());
+                                VolumeStatsEntry vse = new VolumeStatsEntry(chainInfo, physicalsize, virtualsize);
+                                statEntry.put(chainInfo, vse);
+                            }
+                        }
+                    }
+                }
+            }
+            return new GetVolumeStatsAnswer(cmd, "", statEntry);
+        } catch (Exception e) {
+            s_logger.info("VOLSTAT GetVolumeStatsCommand failed " + e.getMessage());
+        }
+
+        return new GetVolumeStatsAnswer(cmd, "", null);
+    }
+
+    protected Answer execute(CheckHealthCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CheckHealthCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            if (hyperHost.isHyperHostConnected()) {
+                return new CheckHealthAnswer(cmd, true);
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            s_logger.error("Unable to execute CheckHealthCommand due to " + VmwareHelper.getExceptionMessage(e), e);
+        }
+        return new CheckHealthAnswer(cmd, false);
+    }
+
+    protected Answer execute(StopCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource StopCommand: " + _gson.toJson(cmd));
+        }
+
+        // In the stop command, we're passed in the name of the VM as seen by cloudstack,
+        // i.e., i-x-y. This is the internal VM name.
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+        try {
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+            if (vmMo != null) {
+                if (cmd.checkBeforeCleanup()) {
+                    if (getVmPowerState(vmMo) != PowerState.PowerOff) {
+                        String msg = "StopCommand is sent for cleanup and VM " + cmd.getVmName() + " is current running. ignore it.";
+                        s_logger.warn(msg);
+                        return new StopAnswer(cmd, msg, false);
+                    } else {
+                        String msg = "StopCommand is sent for cleanup and VM " + cmd.getVmName() + " is indeed stopped already.";
+                        s_logger.info(msg);
+                        return new StopAnswer(cmd, msg, true);
+                    }
+                }
+
+                try {
+                    vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, "0");
+                    vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_VM_INTERNAL_NAME, cmd.getVmName());
+
+                    if (getVmPowerState(vmMo) != PowerState.PowerOff) {
+                        String msg = "Stop VM " + cmd.getVmName() + " Succeed";
+                        boolean success = false;
+                        if (cmd.isForceStop()) {
+                            success = vmMo.powerOff();
+                        } else {
+                            success = vmMo.safePowerOff(_shutdownWaitMs);
+                        }
+                        if (!success) {
+                            msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue";
+                            s_logger.warn(msg);
+                        }
+                        return new StopAnswer(cmd, msg, true);
+                    }
+
+                    String msg = "VM " + cmd.getVmName() + " is already in stopped state";
+                    s_logger.info(msg);
+                    return new StopAnswer(cmd, msg, true);
+                } finally {
+                }
+            } else {
+
+                String msg = "VM " + cmd.getVmName() + " is no longer in vSphere";
+                s_logger.info(msg);
+                return new StopAnswer(cmd, msg, true);
+            }
+        } catch (Exception e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "StopCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            return new StopAnswer(cmd, msg, false);
+        }
+    }
+
+    protected Answer execute(RebootRouterCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource RebootRouterCommand: " + _gson.toJson(cmd));
+        }
+
+        RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd);
+
+        if (answer.getResult()) {
+            String connectResult = connect(cmd.getVmName(), cmd.getPrivateIpAddress());
+            networkUsage(cmd.getPrivateIpAddress(), "create", null);
+            if (connectResult == null) {
+                return answer;
+            } else {
+                return new Answer(cmd, false, connectResult);
+            }
+        }
+        return answer;
+    }
+
+    protected Answer execute(RebootCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource RebootCommand: " + _gson.toJson(cmd));
+        }
+
+        boolean toolsInstallerMounted = false;
+        VirtualMachineMO vmMo = null;
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+        try {
+            vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+            if (vmMo != null) {
+                if (vmMo.isToolsInstallerMounted()) {
+                    toolsInstallerMounted = true;
+                    s_logger.trace("Detected mounted vmware tools installer for :[" + cmd.getVmName() + "]");
+                }
+                try {
+                    vmMo.rebootGuest();
+                    return new RebootAnswer(cmd, "reboot succeeded", true);
+                } catch (ToolsUnavailableFaultMsg e) {
+                    s_logger.warn("VMware tools is not installed at guest OS, we will perform hard reset for reboot");
+                } catch (Exception e) {
+                    s_logger.warn("We are not able to perform gracefull guest reboot due to " + VmwareHelper.getExceptionMessage(e));
+                }
+
+                // continue to try with hard-reset
+                if (vmMo.reset()) {
+                    return new RebootAnswer(cmd, "reboot succeeded", true);
+                }
+
+                String msg = "Reboot failed in vSphere. vm: " + cmd.getVmName();
+                s_logger.warn(msg);
+                return new RebootAnswer(cmd, msg, false);
+            } else {
+                String msg = "Unable to find the VM in vSphere to reboot. vm: " + cmd.getVmName();
+                s_logger.warn(msg);
+                return new RebootAnswer(cmd, msg, false);
+            }
+        } catch (Exception e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "RebootCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            return new RebootAnswer(cmd, msg, false);
+        } finally {
+            if (toolsInstallerMounted) {
+                try {
+                    vmMo.mountToolsInstaller();
+                    s_logger.debug("Successfully re-mounted vmware tools installer for :[" + cmd.getVmName() + "]");
+                } catch (Exception e) {
+                    s_logger.warn("Unabled to re-mount vmware tools installer for :[" + cmd.getVmName() + "]");
+                }
+            }
+        }
+    }
+
+    protected Answer execute(CheckVirtualMachineCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CheckVirtualMachineCommand: " + _gson.toJson(cmd));
+        }
+
+        final String vmName = cmd.getVmName();
+        PowerState powerState = PowerState.PowerUnknown;
+        Integer vncPort = null;
+
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+        try {
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+            if (vmMo != null) {
+                powerState = getVmPowerState(vmMo);
+                return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
+            } else {
+                s_logger.warn("Can not find vm " + vmName + " to execute CheckVirtualMachineCommand");
+                return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
+            }
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+            s_logger.error("Unexpected exception: " + VmwareHelper.getExceptionMessage(e), e);
+
+            return new CheckVirtualMachineAnswer(cmd, powerState, vncPort);
+        }
+    }
+
+    protected Answer execute(PrepareForMigrationCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PrepareForMigrationCommand: " + _gson.toJson(cmd));
+        }
+
+        VirtualMachineTO vm = cmd.getVirtualMachine();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Preparing host for migrating " + vm);
+        }
+
+        final String vmName = vm.getName();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            // find VM through datacenter (VM is not at the target host yet)
+            VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+            if (vmMo == null) {
+                s_logger.info("VM " + vmName + " was not found in the cluster of host " + hyperHost.getHyperHostName() + ". Looking for the VM in datacenter.");
+                ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+                DatacenterMO dcMo = new DatacenterMO(hyperHost.getContext(), dcMor);
+                vmMo = dcMo.findVm(vmName);
+                if (vmMo == null) {
+                    String msg = "VM " + vmName + " does not exist in VMware datacenter";
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+            }
+
+            NicTO[] nics = vm.getNics();
+            for (NicTO nic : nics) {
+                // prepare network on the host
+                prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
+            }
+
+            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+            String secStoreUrl = secStoreUrlAndId.first();
+            Long secStoreId = secStoreUrlAndId.second();
+            if (secStoreUrl == null) {
+                String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
+                throw new Exception(msg);
+            }
+            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
+
+            ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
+            if (morSecDs == null) {
+                String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
+                throw new Exception(msg);
+            }
+            return new PrepareForMigrationAnswer(cmd);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "Unexpected exception " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new PrepareForMigrationAnswer(cmd, msg);
+        }
+    }
+
+    protected Answer execute(MigrateVmToPoolCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info(String.format("excuting MigrateVmToPoolCommand %s -> %s", cmd.getVmName(), cmd.getDestinationPool()));
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("MigrateVmToPoolCommand: " + _gson.toJson(cmd));
+            }
+        }
+
+        final String vmName = cmd.getVmName();
+
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        try {
+            VirtualMachineMO vmMo = getVirtualMachineMO(vmName, hyperHost);
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter";
+                s_logger.error(msg);
+                throw new CloudRuntimeException(msg);
+            }
+
+            String poolUuid = cmd.getDestinationPool();
+            return migrateAndAnswer(vmMo, poolUuid, hyperHost, cmd);
+        } catch (Throwable e) { // hopefully only CloudRuntimeException :/
+            if (e instanceof Exception) {
+                return new Answer(cmd, (Exception) e);
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("problem" , e);
+            }
+            s_logger.error(e.getLocalizedMessage());
+            return new Answer(cmd, false, "unknown problem: " + e.getLocalizedMessage());
+        }
+    }
+
+    private Answer migrateAndAnswer(VirtualMachineMO vmMo, String poolUuid, VmwareHypervisorHost hyperHost, Command cmd) throws Exception {
+        ManagedObjectReference morDs = getTargetDatastoreMOReference(poolUuid, hyperHost);
+
+        try {
+            // OfflineVmwareMigration: getVolumesFromCommand(cmd);
+            Map<Integer, Long> volumeDeviceKey = getVolumesFromCommand(vmMo, cmd);
+            if (s_logger.isTraceEnabled()) {
+                for (Integer diskId: volumeDeviceKey.keySet()) {
+                    s_logger.trace(String.format("disk to migrate has disk id %d and volumeId %d", diskId, volumeDeviceKey.get(diskId)));
+                }
+            }
+            if (vmMo.changeDatastore(morDs)) {
+                // OfflineVmwareMigration: create target specification to include in answer
+                // Consolidate VM disks after successful VM migration
+                // In case of a linked clone VM, if VM's disks are not consolidated, further VM operations such as volume snapshot, VM snapshot etc. will result in DB inconsistencies.
+                if (!vmMo.consolidateVmDisks()) {
+                    s_logger.warn("VM disk consolidation failed after storage migration. Yet proceeding with VM migration.");
+                } else {
+                    s_logger.debug("Successfully consolidated disks of VM " + vmMo.getVmName() + ".");
+                }
+                return createAnswerForCmd(vmMo, poolUuid, cmd, volumeDeviceKey);
+            } else {
+                return new Answer(cmd, false, "failed to changes data store for VM" + vmMo.getVmName());
+            }
+        } catch (Exception e) {
+            String msg = "change data store for VM " + vmMo.getVmName() + " failed";
+            s_logger.error(msg + ": " + e.getLocalizedMessage());
+            throw new CloudRuntimeException(msg,e);
+        }
+    }
+
+    Answer createAnswerForCmd(VirtualMachineMO vmMo, String poolUuid, Command cmd, Map<Integer, Long> volumeDeviceKey) throws Exception {
+        List<VolumeObjectTO> volumeToList =  new ArrayList<>();
+        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
+        VirtualDisk[] disks = vmMo.getAllDiskDevice();
+        Answer answer;
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace(String.format("creating answer for %s", cmd.getClass().getSimpleName()));
+        }
+        if (cmd instanceof MigrateVolumeCommand) {
+            if (disks.length == 1) {
+                String volumePath = vmMo.getVmdkFileBaseName(disks[0]);
+                return new MigrateVolumeAnswer(cmd, true, null, volumePath);
+            }
+            throw new CloudRuntimeException("not expecting more then  one disk after migrate volume command");
+        } else if (cmd instanceof MigrateVmToPoolCommand) {
+            for (VirtualDisk disk : disks) {
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                String newPath = vmMo.getVmdkFileBaseName(disk);
+                VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolUuid);
+                newVol.setId(volumeDeviceKey.get(disk.getKey()));
+                newVol.setPath(newPath);
+                newVol.setChainInfo(_gson.toJson(diskInfo));
+                volumeToList.add(newVol);
+            }
+            return new MigrateVmToPoolAnswer((MigrateVmToPoolCommand)cmd, volumeToList);
+        }
+        return new Answer(cmd, false, null);
+    }
+
+    private Map<Integer, Long> getVolumesFromCommand(VirtualMachineMO vmMo, Command cmd) throws Exception {
+        Map<Integer, Long> volumeDeviceKey = new HashMap<Integer, Long>();
+        if (cmd instanceof MigrateVmToPoolCommand) {
+            MigrateVmToPoolCommand mcmd = (MigrateVmToPoolCommand)cmd;
+            for (VolumeTO volume : mcmd.getVolumes()) {
+                addVolumeDiskmapping(vmMo, volumeDeviceKey, volume.getPath(), volume.getId());
+            }
+        } else if (cmd instanceof MigrateVolumeCommand) {
+            MigrateVolumeCommand mcmd = (MigrateVolumeCommand)cmd;
+            addVolumeDiskmapping(vmMo, volumeDeviceKey, mcmd.getVolumePath(), mcmd.getVolumeId());
+        }
+        return volumeDeviceKey;
+    }
+
+    private void addVolumeDiskmapping(VirtualMachineMO vmMo, Map<Integer, Long> volumeDeviceKey, String volumePath, long volumeId) throws Exception {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(String.format("locating disk for volume (%d) using path %s", volumeId, volumePath));
+        }
+        Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, volumePath + VMDK_EXTENSION);
+        String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
+        if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+            vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+        }
+        int diskId = diskInfo.first().getKey();
+        volumeDeviceKey.put(diskId, volumeId);
+    }
+
+    private ManagedObjectReference getTargetDatastoreMOReference(String destinationPool, VmwareHypervisorHost hyperHost) {
+        ManagedObjectReference morDs;
+        try {
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug(String.format("finding datastore %s", destinationPool));
+            }
+            morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, destinationPool);
+        } catch (Exception e) {
+            String msg = "exception while finding data store  " + destinationPool;
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg + ": " + e.getLocalizedMessage());
+        }
+        return morDs;
+    }
+
+    private ManagedObjectReference getDataCenterMOReference(String vmName, VmwareHypervisorHost hyperHost) {
+        ManagedObjectReference morDc;
+        try {
+            morDc = hyperHost.getHyperHostDatacenter();
+        } catch (Exception e) {
+            String msg = "exception while finding VMware datacenter to search for VM " + vmName;
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg + ": " + e.getLocalizedMessage());
+        }
+        return morDc;
+    }
+
+    private VirtualMachineMO getVirtualMachineMO(String vmName, VmwareHypervisorHost hyperHost) {
+        VirtualMachineMO vmMo = null;
+        try {
+            // find VM through datacenter (VM is not at the target host yet)
+            vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+        } catch (Exception e) {
+            String msg = "exception while searching for VM " + vmName + " in VMware datacenter";
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg + ": " + e.getLocalizedMessage());
+        }
+        return vmMo;
+    }
+
+    protected Answer execute(MigrateCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource MigrateCommand: " + _gson.toJson(cmd));
+        }
+
+        final String vmName = cmd.getVmName();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
+
+            // find VM through datacenter (VM is not at the target host yet)
+            VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            VmwareHypervisorHost destHyperHost = getTargetHyperHost(new DatacenterMO(hyperHost.getContext(), morDc), cmd.getDestinationIp());
+
+            ManagedObjectReference morTargetPhysicalHost = destHyperHost.findMigrationTarget(vmMo);
+            if (morTargetPhysicalHost == null) {
+                throw new Exception("Unable to find a target capable physical host");
+            }
+
+            if (!vmMo.migrate(destHyperHost.getHyperHostOwnerResourcePool(), morTargetPhysicalHost)) {
+                throw new Exception("Migration failed");
+            }
+
+            return new MigrateAnswer(cmd, true, "migration succeeded", null);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.warn(msg, e);
+            return new MigrateAnswer(cmd, false, msg, null);
+        }
+    }
+
+    protected Answer execute(MigrateWithStorageCommand cmd) {
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource MigrateWithStorageCommand: " + _gson.toJson(cmd));
+        }
+
+        VirtualMachineTO vmTo = cmd.getVirtualMachine();
+        String vmName = vmTo.getName();
+
+        VmwareHypervisorHost srcHyperHost = null;
+        VmwareHypervisorHost tgtHyperHost = null;
+        VirtualMachineMO vmMo = null;
+
+        ManagedObjectReference morDsAtTarget = null;
+        ManagedObjectReference morDsAtSource = null;
+        ManagedObjectReference morDc = null;
+        ManagedObjectReference morDcOfTargetHost = null;
+        ManagedObjectReference morTgtHost = new ManagedObjectReference();
+        ManagedObjectReference morTgtDatastore = new ManagedObjectReference();
+        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
+        List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
+        VirtualMachineRelocateSpecDiskLocator diskLocator = null;
+
+        String tgtDsName = "";
+        String tgtDsHost;
+        String tgtDsPath;
+        int tgtDsPort;
+        VolumeTO volume;
+        StorageFilerTO filerTo;
+        Set<String> mountedDatastoresAtSource = new HashSet<String>();
+        List<VolumeObjectTO> volumeToList = new ArrayList<VolumeObjectTO>();
+        Map<Long, Integer> volumeDeviceKey = new HashMap<Long, Integer>();
+
+        List<Pair<VolumeTO, StorageFilerTO>> volToFiler = cmd.getVolumeToFilerAsList();
+        String tgtHost = cmd.getTargetHost();
+        String tgtHostMorInfo = tgtHost.split("@")[0];
+        morTgtHost.setType(tgtHostMorInfo.split(":")[0]);
+        morTgtHost.setValue(tgtHostMorInfo.split(":")[1]);
+
+        try {
+            srcHyperHost = getHyperHost(getServiceContext());
+            tgtHyperHost = new HostMO(getServiceContext(), morTgtHost);
+            morDc = srcHyperHost.getHyperHostDatacenter();
+            morDcOfTargetHost = tgtHyperHost.getHyperHostDatacenter();
+            if (!morDc.getValue().equalsIgnoreCase(morDcOfTargetHost.getValue())) {
+                String msg = "Source host & target host are in different datacentesr";
+                throw new CloudRuntimeException(msg);
+            }
+            VmwareManager mgr = tgtHyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            String srcHostApiVersion = ((HostMO)srcHyperHost).getHostAboutInfo().getApiVersion();
+
+            // find VM through datacenter (VM is not at the target host yet)
+            vmMo = srcHyperHost.findVmOnPeerHyperHost(vmName);
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+            vmName = vmMo.getName();
+
+            // Specify destination datastore location for each volume
+            for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
+                volume = entry.first();
+                filerTo = entry.second();
+
+                s_logger.debug("Preparing spec for volume : " + volume.getName());
+                morDsAtTarget = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, filerTo.getUuid());
+                morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, filerTo.getUuid());
+                if (morDsAtTarget == null) {
+                    String msg = "Unable to find the target datastore: " + filerTo.getUuid() + " on target host: " + tgtHyperHost.getHyperHostName()
+                            + " to execute MigrateWithStorageCommand";
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+                morTgtDatastore = morDsAtTarget;
+
+                // If host version is below 5.1 then simultaneous change of VM's datastore and host is not supported.
+                // So since only the datastore will be changed first, ensure the target datastore is mounted on source host.
+                if (srcHostApiVersion.compareTo("5.1") < 0) {
+                    tgtDsName = filerTo.getUuid().replace("-", "");
+                    tgtDsHost = filerTo.getHost();
+                    tgtDsPath = filerTo.getPath();
+                    tgtDsPort = filerTo.getPort();
+
+                    // If datastore is NFS and target datastore is not already mounted on source host then mount the datastore.
+                    if (filerTo.getType().equals(StoragePoolType.NetworkFilesystem)) {
+                        if (morDsAtSource == null) {
+                            morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName);
+                            if (morDsAtSource == null) {
+                                throw new Exception("Unable to mount NFS datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
+                            }
+                            mountedDatastoresAtSource.add(tgtDsName);
+                            s_logger.debug("Mounted datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
+                        }
+                    }
+
+                    // If datastore is VMFS and target datastore is not mounted or accessible to source host then fail migration.
+                    if (filerTo.getType().equals(StoragePoolType.VMFS)) {
+                        if (morDsAtSource == null) {
+                            s_logger.warn(
+                                    "If host version is below 5.1, then target VMFS datastore(s) need to manually mounted on source host for a successful live storage migration.");
+                            throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not mounted on source host: " + _hostName);
+                        }
+                        DatastoreMO dsAtSourceMo = new DatastoreMO(getServiceContext(), morDsAtSource);
+                        String srcHostValue = srcHyperHost.getMor().getValue();
+                        if (!dsAtSourceMo.isAccessibleToHost(srcHostValue)) {
+                            s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to accessible to source host for a successful live storage migration.");
+                            throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not accessible on source host: " + _hostName);
+                        }
+                    }
+                    morTgtDatastore = morDsAtSource;
+                }
+
+                if (volume.getType() == Volume.Type.ROOT) {
+                    relocateSpec.setDatastore(morTgtDatastore);
+                }
+                diskLocator = new VirtualMachineRelocateSpecDiskLocator();
+                diskLocator.setDatastore(morDsAtSource);
+                Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volume.getPath(), VMDK_EXTENSION));
+                String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
+                if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+                    vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+                }
+                int diskId = diskInfo.first().getKey();
+                diskLocator.setDiskId(diskId);
+
+                diskLocators.add(diskLocator);
+                volumeDeviceKey.put(volume.getId(), diskId);
+            }
+            // If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
+            // Hence set the existing datastore as target datastore for volumes that are not to be migrated.
+            List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
+            for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
+                if (!volumeDeviceKey.containsValue(diskDatastore.first().intValue())) {
+                    diskLocator = new VirtualMachineRelocateSpecDiskLocator();
+                    diskLocator.setDiskId(diskDatastore.first().intValue());
+                    diskLocator.setDatastore(diskDatastore.second());
+                    diskLocators.add(diskLocator);
+                }
+            }
+
+            relocateSpec.getDisk().addAll(diskLocators);
+
+            // Prepare network at target before migration
+            NicTO[] nics = vmTo.getNics();
+            for (NicTO nic : nics) {
+                // prepare network on the host
+                prepareNetworkFromNicInfo(new HostMO(getServiceContext(), morTgtHost), nic, false, vmTo.getType());
+            }
+
+            // Ensure secondary storage mounted on target host
+            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
+            String secStoreUrl = secStoreUrlAndId.first();
+            Long secStoreId = secStoreUrlAndId.second();
+            if (secStoreUrl == null) {
+                String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
+                throw new Exception(msg);
+            }
+            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
+            ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
+            if (morSecDs == null) {
+                String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
+                throw new Exception(msg);
+            }
+
+            if (srcHostApiVersion.compareTo("5.1") < 0) {
+                // Migrate VM's volumes to target datastore(s).
+                if (!vmMo.changeDatastore(relocateSpec)) {
+                    throw new Exception("Change datastore operation failed during storage migration");
+                } else {
+                    s_logger.debug("Successfully migrated storage of VM " + vmName + " to target datastore(s)");
+                }
+
+                // Migrate VM to target host.
+                ManagedObjectReference morPool = tgtHyperHost.getHyperHostOwnerResourcePool();
+                if (!vmMo.migrate(morPool, tgtHyperHost.getMor())) {
+                    throw new Exception("VM migration to target host failed during storage migration");
+                } else {
+                    s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName());
+                }
+            } else {
+                // Simultaneously migrate VM's volumes to target datastore and VM to target host.
+                relocateSpec.setHost(tgtHyperHost.getMor());
+                relocateSpec.setPool(tgtHyperHost.getHyperHostOwnerResourcePool());
+                if (!vmMo.changeDatastore(relocateSpec)) {
+                    throw new Exception("Change datastore operation failed during storage migration");
+                } else {
+                    s_logger.debug(
+                            "Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName() + " and its storage to target datastore(s)");
+                }
+            }
+
+            // Consolidate VM disks.
+            // In case of a linked clone VM, if VM's disks are not consolidated, further VM operations such as volume snapshot, VM snapshot etc. will result in DB inconsistencies.
+            if (!vmMo.consolidateVmDisks()) {
+                s_logger.warn("VM disk consolidation failed after storage migration. Yet proceeding with VM migration.");
+            } else {
+                s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
+            }
+
+            // Update and return volume path and chain info for every disk because that could have changed after migration
+            VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
+            for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
+                volume = entry.first();
+                long volumeId = volume.getId();
+                VirtualDisk[] disks = vmMo.getAllDiskDevice();
+                for (VirtualDisk disk : disks) {
+                    if (volumeDeviceKey.get(volumeId) == disk.getKey()) {
+                        VolumeObjectTO newVol = new VolumeObjectTO();
+                        String newPath = vmMo.getVmdkFileBaseName(disk);
+                        String poolName = entry.second().getUuid().replace("-", "");
+                        VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolName);
+                        newVol.setId(volumeId);
+                        newVol.setPath(newPath);
+                        newVol.setChainInfo(_gson.toJson(diskInfo));
+                        volumeToList.add(newVol);
+                        break;
+                    }
+                }
+            }
+
+            return new MigrateWithStorageAnswer(cmd, volumeToList);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encountered remote exception at vCenter, invalidating VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.warn(msg, e);
+            return new MigrateWithStorageAnswer(cmd, (Exception)e);
+        } finally {
+            // Cleanup datastores mounted on source host
+            for (String mountedDatastore : mountedDatastoresAtSource) {
+                s_logger.debug("Attempting to unmount datastore " + mountedDatastore + " at " + _hostName);
+                try {
+                    srcHyperHost.unmountDatastore(mountedDatastore);
+                } catch (Exception unmountEx) {
+                    s_logger.debug("Failed to unmount datastore " + mountedDatastore + " at " + _hostName + ". Seems the datastore is still being used by " + _hostName
+                            + ". Please unmount manually to cleanup.");
+                }
+                s_logger.debug("Successfully unmounted datastore " + mountedDatastore + " at " + _hostName);
+            }
+        }
+    }
+
+    private Answer migrateVolume(MigrateVolumeCommand cmd) {
+        Answer answer = null;
+        String path = cmd.getVolumePath();
+
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        VirtualMachineMO vmMo = null;
+        DatastoreMO dsMo = null;
+        ManagedObjectReference morSourceDS = null;
+        String vmdkDataStorePath = null;
+
+        String vmName = null;
+        try {
+            // OfflineVmwareMigration: we need to refactor the worker vm creation out for use in migration methods as well as here
+            // OfflineVmwareMigration: this method is 100 lines and needs refactorring anyway
+            // we need to spawn a worker VM to attach the volume to and move it
+            vmName = getWorkerName(getServiceContext(), cmd, 0);
+
+                // OfflineVmwareMigration: refactor for re-use
+                // OfflineVmwareMigration: 1. find data(store)
+            // OfflineVmwareMigration: more robust would be to find the store given the volume as it might have been moved out of band or due to error
+// example:            DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
+
+            morSourceDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getSourcePool().getUuid());
+            dsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS);
+            s_logger.info("Create worker VM " + vmName);
+                // OfflineVmwareMigration: 2. create the worker with access to the data(store)
+            vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName);
+            if (vmMo == null) {
+                // OfflineVmwareMigration: don't throw a general Exception but think of a specific one
+                throw new CloudRuntimeException("Unable to create a worker VM for volume operation");
+            }
+
+            synchronized (this) {
+                // OfflineVmwareMigration: 3. attach the disk to the worker
+                String vmdkFileName = path + VMDK_EXTENSION;
+                vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
+                if (!dsMo.fileExists(vmdkDataStorePath)) {
+                    if(s_logger.isDebugEnabled()) {
+                        s_logger.debug(String.format("path not found (%s), trying under '%s'", vmdkFileName, path));
+                    }
+                    vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, path, vmdkFileName);
+                }
+                if (!dsMo.fileExists(vmdkDataStorePath)) {
+                    if(s_logger.isDebugEnabled()) {
+                        s_logger.debug(String.format("path not found (%s), trying under '%s'", vmdkFileName, vmName));
+                    }
+                    vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkFileName);
+                }
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug(String.format("attaching %s to %s for migration", vmdkDataStorePath, vmMo.getVmName()));
+                }
+                vmMo.attachDisk(new String[] { vmdkDataStorePath }, morSourceDS);
+            }
+
+            // OfflineVmwareMigration: 4. find the (worker-) VM
+            // find VM through datacenter (VM is not at the target host yet)
+            vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            if (s_logger.isTraceEnabled()) {
+                VirtualDisk[] disks = vmMo.getAllDiskDevice();
+                String format = "disk %d is attached as %s";
+                for (VirtualDisk disk : disks) {
+                    s_logger.trace(String.format(format,disk.getKey(),vmMo.getVmdkFileBaseName(disk)));
+                }
+            }
+
+            // OfflineVmwareMigration: 5. create a relocate spec and perform
+            Pair<VirtualDisk, String> vdisk = vmMo.getDiskDevice(path);
+            if (vdisk == null) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("migrate volume done (failed)");
+                throw new CloudRuntimeException("No such disk device: " + path);
+            }
+
+            VirtualDisk disk = vdisk.first();
+            String vmdkAbsFile = getAbsoluteVmdkFile(disk);
+            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+            }
+
+            // OfflineVmwareMigration: this may have to be disected and executed in separate steps
+            answer = migrateAndAnswer(vmMo, cmd.getTargetPool().getUuid(), hyperHost, cmd);
+        } catch (Exception e) {
+            String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
+            s_logger.error(msg, e);
+            answer = new Answer(cmd, false, msg);
+        } finally {
+            try {
+                // OfflineVmwareMigration: worker *may* have been renamed
+                vmName = vmMo.getVmName();
+                morSourceDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getTargetPool().getUuid());
+                dsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS);
+                s_logger.info("Dettaching disks before destroying worker VM '" + vmName + "' after volume migration");
+                VirtualDisk[] disks = vmMo.getAllDiskDevice();
+                String format = "disk %d was migrated to %s";
+                for (VirtualDisk disk : disks) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace(String.format(format, disk.getKey(), vmMo.getVmdkFileBaseName(disk)));
+                    }
+                    vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, vmMo.getVmdkFileBaseName(disk) + VMDK_EXTENSION);
+                    vmMo.detachDisk(vmdkDataStorePath, false);
+                }
+                s_logger.info("Destroy worker VM '" + vmName + "' after volume migration");
+                vmMo.destroy();
+            } catch (Throwable e) {
+                s_logger.info("Failed to destroy worker VM: " + vmName);
+            }
+        }
+        if (answer instanceof MigrateVolumeAnswer) {
+            String newPath = ((MigrateVolumeAnswer)answer).getVolumePath();
+            String vmdkFileName = newPath + VMDK_EXTENSION;
+            try {
+                VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, newPath, vmName);
+                vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
+
+                if (!dsMo.fileExists(vmdkDataStorePath)) {
+                    String msg = String.format("Migration of volume '%s' failed; file (%s) not found as path '%s'", cmd.getVolumePath(), vmdkFileName, vmdkDataStorePath);
+                    s_logger.error(msg);
+                    answer = new Answer(cmd, false, msg);
+                }
+            } catch (Exception e) {
+                String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
+                s_logger.error(msg, e);
+                answer = new Answer(cmd, false, msg);
+            }
+        }
+        return answer;
+    }
+
+    // OfflineVmwareMigration: refactor to be able to handle a detached volume
+    private Answer execute(MigrateVolumeCommand cmd) {
+        String volumePath = cmd.getVolumePath();
+        StorageFilerTO poolTo = cmd.getPool();
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource MigrateVolumeCommand: " + _gson.toJson(cmd));
+        }
+
+        String vmName = cmd.getAttachedVmName();
+
+        VirtualMachineMO vmMo = null;
+        VmwareHypervisorHost srcHyperHost = null;
+
+        // OfflineVmwareMigration: ifhost is null ???
+        if (org.apache.commons.lang.StringUtils.isBlank(cmd.getAttachedVmName())) {
+            return migrateVolume(cmd);
+        }
+        ManagedObjectReference morDs = null;
+        ManagedObjectReference morDc = null;
+        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
+        List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
+        VirtualMachineRelocateSpecDiskLocator diskLocator = null;
+
+        String tgtDsName = "";
+
+        try {
+            srcHyperHost = getHyperHost(getServiceContext());
+            morDc = srcHyperHost.getHyperHostDatacenter();
+            tgtDsName = poolTo.getUuid();
+
+            // find VM in this datacenter not just in this cluster.
+            DatacenterMO dcMo = new DatacenterMO(getServiceContext(), morDc);
+            vmMo = dcMo.findVm(vmName);
+
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
+                s_logger.error(msg);
+                throw new CloudRuntimeException(msg);
+            }
+            vmName = vmMo.getName();
+            morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, tgtDsName);
+            if (morDs == null) {
+                String msg = "Unable to find the mounted datastore with name: " + tgtDsName + " on source host: " + srcHyperHost.getHyperHostName()
+                        + " to execute MigrateVolumeCommand";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            DatastoreMO targetDsMo = new DatastoreMO(srcHyperHost.getContext(), morDs);
+            String fullVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(targetDsMo, vmName, volumePath + VMDK_EXTENSION);
+            Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volumePath, VMDK_EXTENSION));
+            String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
+            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+            }
+            int diskId = diskInfo.first().getKey();
+
+            diskLocator = new VirtualMachineRelocateSpecDiskLocator();
+            diskLocator.setDatastore(morDs);
+            diskLocator.setDiskId(diskId);
+            diskLocators.add(diskLocator);
+            if (cmd.getVolumeType() == Volume.Type.ROOT) {
+                relocateSpec.setDatastore(morDs);
+                // If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
+                // Hence set the existing datastore as target datastore for volumes that are not to be migrated.
+                List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
+                for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
+                    if (diskDatastore.first().intValue() != diskId) {
+                        diskLocator = new VirtualMachineRelocateSpecDiskLocator();
+                        diskLocator.setDiskId(diskDatastore.first().intValue());
+                        diskLocator.setDatastore(diskDatastore.second());
+                        diskLocators.add(diskLocator);
+                    }
+                }
+            }
+
+            relocateSpec.getDisk().addAll(diskLocators);
+
+            // Change datastore
+            if (!vmMo.changeDatastore(relocateSpec)) {
+                throw new Exception("Change datastore operation failed during volume migration");
+            } else {
+                s_logger.debug("Successfully migrated volume " + volumePath + " to target datastore " + tgtDsName);
+            }
+
+            // Consolidate VM disks.
+            // In case of a linked clone VM, if VM's disks are not consolidated,
+            // further volume operations on the ROOT volume such as volume snapshot etc. will result in DB inconsistencies.
+            if (!vmMo.consolidateVmDisks()) {
+                s_logger.warn("VM disk consolidation failed after storage migration.");
+            } else {
+                s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
+            }
+
+            // Update and return volume path and chain info because that could have changed after migration
+            if (!targetDsMo.fileExists(fullVolumePath)) {
+                VirtualDisk[] disks = vmMo.getAllDiskDevice();
+                for (VirtualDisk disk : disks)
+                    if (disk.getKey() == diskId) {
+                        volumePath = vmMo.getVmdkFileBaseName(disk);
+                    }
+            }
+            VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
+            String chainInfo = _gson.toJson(diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, poolTo.getUuid().replace("-", "")));
+            MigrateVolumeAnswer answer = new MigrateVolumeAnswer(cmd, true, null, volumePath);
+            answer.setVolumeChainInfo(chainInfo);
+            return answer;
+        } catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
+            s_logger.error(msg, e);
+            return new MigrateVolumeAnswer(cmd, false, msg, null);
+        }
+    }
+
+    private Pair<VirtualDisk, String> getVirtualDiskInfo(VirtualMachineMO vmMo, String srcDiskName) throws Exception {
+        Pair<VirtualDisk, String> deviceInfo = vmMo.getDiskDevice(srcDiskName);
+        if (deviceInfo == null) {
+            throw new Exception("No such disk device: " + srcDiskName);
+        }
+        return deviceInfo;
+    }
+
+    private VmwareHypervisorHost getTargetHyperHost(DatacenterMO dcMo, String destIp) throws Exception {
+
+        VmwareManager mgr = dcMo.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+        List<ObjectContent> ocs = dcMo.getHostPropertiesOnDatacenterHostFolder(new String[] {"name", "parent"});
+        if (ocs != null && ocs.size() > 0) {
+            for (ObjectContent oc : ocs) {
+                HostMO hostMo = new HostMO(dcMo.getContext(), oc.getObj());
+                VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary(mgr.getManagementPortGroupByHost(hostMo));
+                if (destIp.equalsIgnoreCase(netSummary.getHostIp())) {
+                    return new HostMO(dcMo.getContext(), oc.getObj());
+                }
+            }
+        }
+
+        throw new Exception("Unable to locate dest host by " + destIp);
+    }
+
+    protected Answer execute(CreateStoragePoolCommand cmd) {
+        if (cmd.getCreateDatastore()) {
+            try {
+                VmwareContext context = getServiceContext();
+
+                _storageProcessor.prepareManagedDatastore(context, getHyperHost(context), cmd.getDetails().get(CreateStoragePoolCommand.DATASTORE_NAME),
+                        cmd.getDetails().get(CreateStoragePoolCommand.IQN), cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_HOST),
+                        Integer.parseInt(cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_PORT)));
+            } catch (Exception ex) {
+                return new Answer(cmd, false, "Issue creating datastore");
+            }
+        }
+
+        return new Answer(cmd, true, "success");
+    }
+
+    protected Answer execute(ModifyTargetsCommand cmd) {
+        VmwareContext context = getServiceContext(cmd);
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+        List<HostMO> hostMOs = new ArrayList<>();
+
+        if (cmd.getApplyToAllHostsInCluster()) {
+            try {
+                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+                ClusterMO clusterMO = new ClusterMO(context, morCluster);
+
+                List<Pair<ManagedObjectReference, String>> hosts = clusterMO.getClusterHosts();
+
+                for (Pair<ManagedObjectReference, String> host : hosts) {
+                    HostMO hostMO = new HostMO(context, host.first());
+
+                    hostMOs.add(hostMO);
+                }
+            }
+            catch (Exception ex) {
+                s_logger.error(ex.getMessage(), ex);
+
+                throw new CloudRuntimeException(ex.getMessage(), ex);
+            }
+        }
+        else {
+            hostMOs.add((HostMO)hyperHost);
+        }
+
+        handleTargets(cmd.getAdd(), cmd.getTargetTypeToRemove(), cmd.isRemoveAsync(), cmd.getTargets(), hostMOs);
+
+        return new ModifyTargetsAnswer();
+    }
+
+    protected Answer execute(ModifyStoragePoolCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ModifyStoragePoolCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            StorageFilerTO pool = cmd.getPool();
+
+            if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS) {
+                throw new Exception("Unsupported storage pool type " + pool.getType());
+            }
+
+            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid());
+
+            if (morDatastore == null) {
+                morDatastore = hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", ""));
+            }
+
+            assert (morDatastore != null);
+
+            DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
+
+            long capacity = summary.getCapacity();
+            long available = summary.getFreeSpace();
+
+            Map<String, TemplateProp> tInfo = new HashMap<>();
+            ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
+
+            if (cmd.getAdd() && pool.getType() == StoragePoolType.VMFS) {
+                answer.setLocalDatastoreName(morDatastore.getValue());
+            }
+
+            return answer;
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+
+                invalidateServiceContext();
+            }
+
+            String msg = "ModifyStoragePoolCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+
+            s_logger.error(msg, e);
+
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    private void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove, boolean isRemoveAsync,
+                               List<Map<String, String>> targets, List<HostMO> hosts) {
+        if (targets != null && targets.size() > 0) {
+            try {
+                _storageProcessor.handleTargets(add, targetTypeToRemove, isRemoveAsync, targets, hosts);
+            }
+            catch (Exception ex) {
+                s_logger.warn(ex.getMessage());
+            }
+        }
+    }
+
+    protected Answer execute(DeleteStoragePoolCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource DeleteStoragePoolCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            if (cmd.getRemoveDatastore()) {
+                _storageProcessor.handleDatastoreAndVmdkDetach(cmd, cmd.getDetails().get(DeleteStoragePoolCommand.DATASTORE_NAME),
+                        cmd.getDetails().get(DeleteStoragePoolCommand.IQN), cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_HOST),
+                        Integer.parseInt(cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_PORT)));
+
+                return new Answer(cmd, true, "success");
+            } else {
+                // We will leave datastore cleanup management to vCenter. Since for cluster VMFS datastore, it will always
+                // be mounted by vCenter.
+
+                // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext());
+                // hyperHost.unmountDatastore(pool.getUuid());
+
+                return new Answer(cmd, true, "success");
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+
+                invalidateServiceContext();
+            }
+
+            StorageFilerTO pool = cmd.getPool();
+            String msg = "DeleteStoragePoolCommand (pool: " + pool.getHost() + ", path: " + pool.getPath() + ") failed due to " + VmwareHelper.getExceptionMessage(e);
+
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    public static String getDatastoreName(String str) {
+        return str.replace('/', '-');
+    }
+
+    public static String createDatastoreNameFromIqn(String iqn) {
+        return "-" + iqn + "-0";
+    }
+
+    protected AttachIsoAnswer execute(AttachIsoCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource AttachIsoCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+            if (vmMo == null) {
+                String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + cmd.getVmName();
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            String storeUrl = cmd.getStoreUrl();
+            if (storeUrl == null) {
+                if (!cmd.getIsoPath().equalsIgnoreCase("vmware-tools.iso")) {
+                    String msg = "ISO store root url is not found in AttachIsoCommand";
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                } else {
+                    if (cmd.isAttach()) {
+                        vmMo.mountToolsInstaller();
+                    } else {
+                        try {
+                            if (!vmMo.unmountToolsInstaller()) {
+                                return new AttachIsoAnswer(cmd, false,
+                                        "Failed to unmount vmware-tools installer ISO as the corresponding CDROM device is locked by VM. Please unmount the CDROM device inside the VM and ret-try.");
+                            }
+                        } catch (Throwable e) {
+                            vmMo.detachIso(null);
+                        }
+                    }
+
+                    return new AttachIsoAnswer(cmd);
+                }
+            }
+
+            ManagedObjectReference morSecondaryDs = prepareSecondaryDatastoreOnHost(storeUrl);
+            String isoPath = cmd.getIsoPath();
+            if (!isoPath.startsWith(storeUrl)) {
+                assert (false);
+                String msg = "ISO path does not start with the secondary storage root";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            int isoNameStartPos = isoPath.lastIndexOf('/');
+            String isoFileName = isoPath.substring(isoNameStartPos + 1);
+            String isoStorePathFromRoot = isoPath.substring(storeUrl.length() + 1, isoNameStartPos + 1);
+
+
+            // TODO, check if iso is already attached, or if there is a previous
+            // attachment
+            DatastoreMO secondaryDsMo = new DatastoreMO(getServiceContext(), morSecondaryDs);
+            String storeName = secondaryDsMo.getName();
+            String isoDatastorePath = String.format("[%s] %s%s", storeName, isoStorePathFromRoot, isoFileName);
+
+            if (cmd.isAttach()) {
+                vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false, cmd.getDeviceKey());
+                return new AttachIsoAnswer(cmd);
+            } else {
+                int key = vmMo.detachIso(isoDatastorePath, cmd.isForce());
+                return new AttachIsoAnswer(cmd, key);
+            }
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            if (cmd.isAttach()) {
+                String msg = "AttachIsoCommand(attach) failed due to " + VmwareHelper.getExceptionMessage(e);
+                s_logger.error(msg, e);
+                return new AttachIsoAnswer(cmd, false, msg);
+            } else {
+                String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e);
+                s_logger.warn(msg, e);
+                return new AttachIsoAnswer(cmd, false, msg);
+            }
+        }
+    }
+
+    public synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception {
+        String storeName = getSecondaryDatastoreUUID(storeUrl);
+        URI uri = new URI(storeUrl);
+
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
+
+        if (morDatastore == null)
+            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
+
+        return morDatastore;
+    }
+
+    public synchronized ManagedObjectReference prepareSecondaryDatastoreOnSpecificHost(String storeUrl, VmwareHypervisorHost hyperHost) throws Exception {
+        String storeName = getSecondaryDatastoreUUID(storeUrl);
+        URI uri = new URI(storeUrl);
+
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
+
+        if (morDatastore == null)
+            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
+
+        return morDatastore;
+    }
+
+    private static String getSecondaryDatastoreUUID(String storeUrl) {
+        String uuid = null;
+        try {
+            uuid = UUID.nameUUIDFromBytes(storeUrl.getBytes("UTF-8")).toString();
+        } catch (UnsupportedEncodingException e) {
+            s_logger.warn("Failed to create UUID from string " + storeUrl + ". Bad storeUrl or UTF-8 encoding error.");
+        }
+        return uuid;
+    }
+
+    protected Answer execute(ValidateSnapshotCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ValidateSnapshotCommand: " + _gson.toJson(cmd));
+        }
+
+        // the command is no longer available
+        String expectedSnapshotBackupUuid = null;
+        String actualSnapshotBackupUuid = null;
+        String actualSnapshotUuid = null;
+        return new ValidateSnapshotAnswer(cmd, false, "ValidateSnapshotCommand is not supported for vmware yet", expectedSnapshotBackupUuid, actualSnapshotBackupUuid,
+                actualSnapshotUuid);
+    }
+
+    protected Answer execute(ManageSnapshotCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ManageSnapshotCommand: " + _gson.toJson(cmd));
+        }
+
+        long snapshotId = cmd.getSnapshotId();
+
+        /*
+         * "ManageSnapshotCommand",
+         * "{\"_commandSwitch\":\"-c\",\"_volumePath\":\"i-2-3-KY-ROOT\",\"_snapshotName\":\"i-2-3-KY_i-2-3-KY-ROOT_20101102203827\",\"_snapshotId\":1,\"_vmName\":\"i-2-3-KY\"}"
+         */
+        boolean success = false;
+        String cmdSwitch = cmd.getCommandSwitch();
+        String snapshotOp = "Unsupported snapshot command." + cmdSwitch;
+        if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
+            snapshotOp = "create";
+        } else if (cmdSwitch.equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) {
+            snapshotOp = "destroy";
+        }
+
+        String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId;
+        String snapshotUUID = null;
+
+        // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake
+        // a success return here
+        snapshotUUID = UUID.randomUUID().toString();
+        success = true;
+        details = null;
+
+        return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details);
+    }
+
+    protected Answer execute(BackupSnapshotCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource BackupSnapshotCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            return mgr.getStorageManager().execute(this, cmd);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String details = "BackupSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(details, e);
+            return new BackupSnapshotAnswer(cmd, false, details, null, true);
+        }
+    }
+
+    protected Answer execute(CreateVMSnapshotCommand cmd) {
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            return mgr.getStorageManager().execute(this, cmd);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new CreateVMSnapshotAnswer(cmd, false, "");
+        }
+    }
+
+    protected Answer execute(DeleteVMSnapshotCommand cmd) {
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            return mgr.getStorageManager().execute(this, cmd);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new DeleteVMSnapshotAnswer(cmd, false, "");
+        }
+    }
+
+    protected Answer execute(RevertToVMSnapshotCommand cmd) {
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            return mgr.getStorageManager().execute(this, cmd);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new RevertToVMSnapshotAnswer(cmd, false, "");
+        }
+    }
+
+    protected Answer execute(CreateVolumeFromSnapshotCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd));
+        }
+
+        String details = null;
+        boolean success = false;
+        String newVolumeName = UUID.randomUUID().toString();
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            return mgr.getStorageManager().execute(this, cmd);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            details = "CreateVolumeFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(details, e);
+        }
+
+        return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
+    }
+
+    protected Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            return mgr.getStorageManager().execute(this, cmd);
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String details = "CreatePrivateTemplateFromVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(details, e);
+            return new CreatePrivateTemplateAnswer(cmd, false, details);
+        }
+    }
+
+    protected Answer execute(final UpgradeSnapshotCommand cmd) {
+        return new Answer(cmd, true, "success");
+    }
+
+    protected Answer execute(CreatePrivateTemplateFromSnapshotCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CreatePrivateTemplateFromSnapshotCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            return mgr.getStorageManager().execute(this, cmd);
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String details = "CreatePrivateTemplateFromSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(details, e);
+            return new CreatePrivateTemplateAnswer(cmd, false, details);
+        }
+    }
+
+    protected Answer execute(GetStorageStatsCommand cmd) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Executing resource GetStorageStatsCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId());
+
+            if (morDs != null) {
+                DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
+                DatastoreSummary summary = datastoreMo.getSummary();
+                assert (summary != null);
+
+                long capacity = summary.getCapacity();
+                long free = summary.getFreeSpace();
+                long used = capacity - free;
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Datastore summary info, storageId: " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype()
+                            + ", capacity: " + capacity + ", free: " + free + ", used: " + used);
+                }
+
+                if (summary.getCapacity() <= 0) {
+                    s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help");
+                }
+
+                return new GetStorageStatsAnswer(cmd, capacity, used);
+            } else {
+                String msg = "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: "
+                        + cmd.getPooltype();
+
+                s_logger.error(msg);
+                return new GetStorageStatsAnswer(cmd, msg);
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype()
+                    + ") due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new GetStorageStatsAnswer(cmd, msg);
+        }
+    }
+
+    protected Answer execute(GetVncPortCommand cmd) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Executing resource GetVncPortCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            assert (hyperHost instanceof HostMO);
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getName());
+            if (vmMo == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to find the owner VM for GetVncPortCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter");
+                }
+
+                vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getName());
+
+                if (vmMo == null) {
+                    throw new Exception("Unable to find VM in vSphere, vm: " + cmd.getName());
+                }
+            }
+
+            Pair<String, Integer> portInfo = vmMo.getVncPort(mgr.getManagementPortGroupByHost((HostMO)hyperHost));
+
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Found vnc port info. vm: " + cmd.getName() + " host: " + portInfo.first() + ", vnc port: " + portInfo.second());
+            }
+            return new GetVncPortAnswer(cmd, portInfo.first(), portInfo.second());
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "GetVncPortCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new GetVncPortAnswer(cmd, msg);
+        }
+    }
+
+    protected Answer execute(SetupCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource SetupCommand: " + _gson.toJson(cmd));
+        }
+
+        return new SetupAnswer(cmd, false);
+    }
+
+    protected Answer execute(MaintainCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource MaintainCommand: " + _gson.toJson(cmd));
+        }
+
+        return new MaintainAnswer(cmd, "Put host in maintaince");
+    }
+
+    protected Answer execute(PingTestCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PingTestCommand: " + _gson.toJson(cmd));
+        }
+
+        String controlIp = cmd.getRouterIp();
+        if (controlIp != null) {
+            String args = " -c 1 -n -q " + cmd.getPrivateIp();
+            try {
+                Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", getSystemVmKeyFile(), null, "/bin/ping" + args);
+                if (result.first())
+                    return new Answer(cmd);
+            } catch (Exception e) {
+                s_logger.error("Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e);
+            }
+            return new Answer(cmd, false, "PingTestCommand failed");
+        } else {
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+            try {
+                HostMO hostMo = (HostMO)hyperHost;
+                ClusterMO clusterMo = new ClusterMO(context, hostMo.getHyperHostCluster());
+                VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+                List<Pair<ManagedObjectReference, String>> hosts = clusterMo.getClusterHosts();
+                for (Pair<ManagedObjectReference, String> entry : hosts) {
+                    HostMO hostInCluster = new HostMO(context, entry.first());
+                    String hostIp = hostInCluster.getHostManagementIp(mgr.getManagementPortGroupName());
+                    if (hostIp != null && hostIp.equals(cmd.getComputingHostIp())) {
+                        if (hostInCluster.isHyperHostConnected())
+                            return new Answer(cmd);
+                        else
+                            return new Answer(cmd, false, "PingTestCommand failed");
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.error("Unable to execute ping command on host (" + cmd.getComputingHostIp() + "). failure due to " + VmwareHelper.getExceptionMessage(e), e);
+            }
+
+            return new Answer(cmd, false, "PingTestCommand failed");
+        }
+    }
+
+    protected Answer execute(CheckOnHostCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CheckOnHostCommand: " + _gson.toJson(cmd));
+        }
+
+        return new CheckOnHostAnswer(cmd, null, "Not Implmeneted");
+    }
+
+    protected Answer execute(ModifySshKeysCommand cmd) {
+        //do not log the command contents for this command. do NOT log the ssh keys
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource ModifySshKeysCommand.");
+        }
+
+        return new Answer(cmd);
+    }
+
+    protected Answer execute(GetVmIpAddressCommand cmd) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Executing resource command GetVmIpAddressCommand: " + _gson.toJson(cmd));
+        }
+
+        String details = "Unable to find IP Address of VM. ";
+        String vmName = cmd.getVmName();
+        boolean result = false;
+        String ip = null;
+        Answer answer = null;
+
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+
+        if (vmName == null || vmName.isEmpty()) {
+            details += "Name of instance provided is NULL or empty.";
+            return new Answer(cmd, result, details);
+        }
+
+        try {
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+            if (vmMo != null) {
+                GuestInfo guestInfo = vmMo.getGuestInfo();
+                VirtualMachineToolsStatus toolsStatus = guestInfo.getToolsStatus();
+                if (toolsStatus == VirtualMachineToolsStatus.TOOLS_NOT_INSTALLED) {
+                    details += "Vmware tools not installed.";
+                } else {
+                    ip = guestInfo.getIpAddress();
+                    if (ip != null) {
+                        result = true;
+                    }
+                    details = ip;
+                }
+            } else {
+                details += "VM " + vmName + " no longer exists on vSphere host: " + hyperHost.getHyperHostName();
+                s_logger.info(details);
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+            details += "Encountered exception : " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(details);
+        }
+
+        answer = new Answer(cmd, result, details);
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Returning GetVmIpAddressAnswer: " + _gson.toJson(answer));
+        }
+        return answer;
+    }
+
+    @Override
+    public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            return (PrimaryStorageDownloadAnswer)mgr.getStorageManager().execute(this, cmd);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "PrimaryStorageDownloadCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new PrimaryStorageDownloadAnswer(msg);
+        }
+    }
+
+    protected Answer execute(PvlanSetupCommand cmd) {
+        // Pvlan related operations are performed in the start/stop command paths
+        // for vmware. This function is implemented to support mgmt layer code
+        // that issue this command. Note that pvlan operations are supported only
+        // in Distributed Virtual Switch environments for vmware deployments.
+        return new Answer(cmd, true, "success");
+    }
+
+    protected Answer execute(UnregisterVMCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource UnregisterVMCommand: " + _gson.toJson(cmd));
+        }
+
+        VmwareContext context = getServiceContext();
+        VmwareHypervisorHost hyperHost = getHyperHost(context);
+        try {
+            DatacenterMO dataCenterMo = new DatacenterMO(getServiceContext(), hyperHost.getHyperHostDatacenter());
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
+            if (vmMo != null) {
+                try {
+                    VirtualMachineFileLayoutEx vmFileLayout = vmMo.getFileLayout();
+                    context.getService().unregisterVM(vmMo.getMor());
+                    if (cmd.getCleanupVmFiles()) {
+                        deleteUnregisteredVmFiles(vmFileLayout, dataCenterMo, false, null);
+                    }
+                    return new Answer(cmd, true, "unregister succeeded");
+                } catch (Exception e) {
+                    s_logger.warn("We are not able to unregister VM " + VmwareHelper.getExceptionMessage(e));
+                }
+
+                String msg = "Expunge failed in vSphere. vm: " + cmd.getVmName();
+                s_logger.warn(msg);
+                return new Answer(cmd, false, msg);
+            } else {
+                String msg = "Unable to find the VM in vSphere to unregister, assume it is already removed. VM: " + cmd.getVmName();
+                s_logger.warn(msg);
+                return new Answer(cmd, true, msg);
+            }
+        } catch (Exception e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    /**
+     * UnregisterNicCommand is used to remove a portgroup created for this
+     * specific nic. The portgroup will have the name set to the UUID of the
+     * nic. Introduced to cleanup the portgroups created for each nic that is
+     * plugged into an lswitch (Nicira NVP plugin)
+     *
+     * @param cmd
+     * @return
+     */
+    protected Answer execute(UnregisterNicCommand cmd) {
+        s_logger.info("Executing resource UnregisterNicCommand: " + _gson.toJson(cmd));
+
+        if (_guestTrafficInfo == null) {
+            return new Answer(cmd, false, "No Guest Traffic Info found, unable to determine where to clean up");
+        }
+
+        try {
+            if (_guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
+                // For now we only need to cleanup the nvp specific portgroups
+                // on the standard switches
+                return new Answer(cmd, true, "Nothing to do");
+            }
+
+            s_logger.debug("Cleaning up portgroup " + cmd.getNicUuid() + " on switch " + _guestTrafficInfo.getVirtualSwitchName());
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost host = getHyperHost(context);
+            ManagedObjectReference clusterMO = host.getHyperHostCluster();
+
+            // Get a list of all the hosts in this cluster
+            @SuppressWarnings("unchecked")
+            List<ManagedObjectReference> hosts = (List<ManagedObjectReference>)context.getVimClient().getDynamicProperty(clusterMO, "host");
+            if (hosts == null) {
+                return new Answer(cmd, false, "No hosts in cluster, which is pretty weird");
+            }
+
+            for (ManagedObjectReference hostMOR : hosts) {
+                HostMO hostMo = new HostMO(context, hostMOR);
+                hostMo.deletePortGroup(cmd.getNicUuid().toString());
+                s_logger.debug("Removed portgroup " + cmd.getNicUuid() + " from host " + hostMo.getHostName());
+            }
+            return new Answer(cmd, true, "Unregistered resources for NIC " + cmd.getNicUuid());
+        } catch (Exception e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) {
+        // we will no longer cleanup VLAN networks in order to support native VMware HA
+        /*
+         * assert(netDetails.getName() != null); try { synchronized(this) { NetworkMO networkMo = new
+         * NetworkMO(hostMo.getContext(), netDetails.getNetworkMor()); ManagedObjectReference[] vms =
+         * networkMo.getVMsOnNetwork(); if(vms == null || vms.length == 0) { if(s_logger.isInfoEnabled()) {
+         * s_logger.info("Cleanup network as it is currently not in use: " + netDetails.getName()); }
+         *
+         * hostMo.deletePortGroup(netDetails.getName()); } } } catch(Throwable e) {
+         * s_logger.warn("Unable to cleanup network due to exception, skip for next time"); }
+         */
+    }
+
+    @Override
+    public CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource CopyVolumeCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            return (CopyVolumeAnswer)mgr.getStorageManager().execute(this, cmd);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+
+            String msg = "CopyVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new CopyVolumeAnswer(cmd, false, msg, null, null);
+        }
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        try {
+            gcAndKillHungWorkerVMs();
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            try {
+                if (!hyperHost.isHyperHostConnected()) {
+                    return null;
+                }
+            } catch (Exception e) {
+                s_logger.error("Unexpected exception", e);
+                return null;
+            }
+            return new PingRoutingCommand(getType(), id, syncHostVmStates());
+        } finally {
+            recycleServiceContext();
+        }
+    }
+
+    private void gcAndKillHungWorkerVMs() {
+        try {
+            // take the chance to do left-over dummy VM cleanup from previous run
+            VmwareContext context = getServiceContext();
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            if (hyperHost.isHyperHostConnected()) {
+                mgr.gcLeftOverVMs(context);
+
+                s_logger.info("Scan hung worker VM to recycle");
+
+                int workerKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
+                int workerTagKey = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
+                String workerPropName = String.format("value[%d]", workerKey);
+                String workerTagPropName = String.format("value[%d]", workerTagKey);
+
+                // GC worker that has been running for too long
+                ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "config.template", workerPropName, workerTagPropName,});
+                if (ocs != null) {
+                    for (ObjectContent oc : ocs) {
+                        List<DynamicProperty> props = oc.getPropSet();
+                        if (props != null) {
+                            boolean template = false;
+                            boolean isWorker = false;
+                            String workerTag = null;
+
+                            for (DynamicProperty prop : props) {
+                                if (prop.getName().equals("config.template")) {
+                                    template = (Boolean)prop.getVal();
+                                } else if (prop.getName().equals(workerPropName)) {
+                                    CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
+                                    if (val != null && val.getValue() != null && val.getValue().equalsIgnoreCase("true"))
+                                        isWorker = true;
+                                } else if (prop.getName().equals(workerTagPropName)) {
+                                    CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
+                                    workerTag = val.getValue();
+                                }
+                            }
+
+                            VirtualMachineMO vmMo = new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
+                            if (!template && isWorker) {
+                                boolean recycle = false;
+                                recycle = mgr.needRecycle(workerTag);
+
+                                if (recycle) {
+                                    s_logger.info("Recycle pending worker VM: " + vmMo.getName());
+
+                                    vmMo.powerOff();
+                                    vmMo.detachAllDisks();
+                                    vmMo.destroy();
+                                }
+                            }
+                        }
+                    }
+                }
+            } else {
+                s_logger.error("Host is no longer connected.");
+            }
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext();
+            }
+        }
+    }
+
+    @Override
+    public Type getType() {
+        return com.cloud.host.Host.Type.Routing;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        try {
+            String hostApiVersion = "4.1";
+            VmwareContext context = getServiceContext();
+            try {
+                VmwareHypervisorHost hyperHost = getHyperHost(context);
+                assert (hyperHost instanceof HostMO);
+                if (!((HostMO)hyperHost).isHyperHostConnected()) {
+                    s_logger.info("Host " + hyperHost.getHyperHostName() + " is not in connected state");
+                    return null;
+                }
+
+                ((HostMO)hyperHost).enableVncOnHostFirewall();
+
+                AboutInfo aboutInfo = ((HostMO)hyperHost).getHostAboutInfo();
+                hostApiVersion = aboutInfo.getApiVersion();
+
+            } catch (Exception e) {
+                String msg = "VmwareResource intialize() failed due to : " + VmwareHelper.getExceptionMessage(e);
+                s_logger.error(msg);
+                invalidateServiceContext();
+                return null;
+            }
+
+            StartupRoutingCommand cmd = new StartupRoutingCommand();
+            fillHostInfo(cmd);
+            cmd.setHypervisorType(HypervisorType.VMware);
+            cmd.setCluster(_cluster);
+            cmd.setHypervisorVersion(hostApiVersion);
+
+            List<StartupStorageCommand> storageCmds = initializeLocalStorage();
+            StartupCommand[] answerCmds = new StartupCommand[1 + storageCmds.size()];
+            answerCmds[0] = cmd;
+            for (int i = 0; i < storageCmds.size(); i++) {
+                answerCmds[i + 1] = storageCmds.get(i);
+            }
+
+            return answerCmds;
+        } finally {
+            recycleServiceContext();
+        }
+    }
+
+    private List<StartupStorageCommand> initializeLocalStorage() {
+        List<StartupStorageCommand> storageCmds = new ArrayList<StartupStorageCommand>();
+        VmwareContext context = getServiceContext();
+
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            if (hyperHost instanceof HostMO) {
+                HostMO hostMo = (HostMO)hyperHost;
+
+                List<Pair<ManagedObjectReference, String>> dsList = hostMo.getLocalDatastoreOnHost();
+                for (Pair<ManagedObjectReference, String> dsPair : dsList) {
+                    DatastoreMO dsMo = new DatastoreMO(context, dsPair.first());
+
+                    String poolUuid = dsMo.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
+                    if (poolUuid == null || poolUuid.isEmpty()) {
+                        poolUuid = UUID.randomUUID().toString();
+                        dsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, poolUuid);
+                    }
+
+                    DatastoreSummary dsSummary = dsMo.getSummary();
+                    String address = hostMo.getHostName();
+                    StoragePoolInfo pInfo = new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.VMFS, dsSummary.getCapacity(),
+                            dsSummary.getFreeSpace());
+                    StartupStorageCommand cmd = new StartupStorageCommand();
+                    cmd.setName(poolUuid);
+                    cmd.setPoolInfo(pInfo);
+                    cmd.setGuid(poolUuid); // give storage host the same UUID as the local storage pool itself
+                    cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
+                    cmd.setDataCenter(_dcId);
+                    cmd.setPod(_pod);
+                    cmd.setCluster(_cluster);
+
+                    s_logger.info("Add local storage startup command: " + _gson.toJson(cmd));
+                    storageCmds.add(cmd);
+                }
+
+            } else {
+                s_logger.info("Cluster host does not support local storage, skip it");
+            }
+        } catch (Exception e) {
+            String msg = "initializing local storage failed due to : " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg);
+            invalidateServiceContext();
+            throw new CloudRuntimeException(msg);
+        }
+
+        return storageCmds;
+    }
+
+    protected void fillHostInfo(StartupRoutingCommand cmd) {
+        VmwareContext serviceContext = getServiceContext();
+        Map<String, String> details = cmd.getHostDetails();
+        if (details == null) {
+            details = new HashMap<String, String>();
+        }
+
+        try {
+            fillHostHardwareInfo(serviceContext, cmd);
+            fillHostNetworkInfo(serviceContext, cmd);
+            fillHostDetailsInfo(serviceContext, details);
+        } catch (RuntimeFaultFaultMsg e) {
+            s_logger.error("RuntimeFault while retrieving host info: " + e.toString(), e);
+            throw new CloudRuntimeException("RuntimeFault while retrieving host info");
+        } catch (RemoteException e) {
+            s_logger.error("RemoteException while retrieving host info: " + e.toString(), e);
+            invalidateServiceContext();
+            throw new CloudRuntimeException("RemoteException while retrieving host info");
+        } catch (Exception e) {
+            s_logger.error("Exception while retrieving host info: " + e.toString(), e);
+            invalidateServiceContext();
+            throw new CloudRuntimeException("Exception while retrieving host info: " + e.toString());
+        }
+
+        cmd.setHostDetails(details);
+        cmd.setName(_url);
+        cmd.setGuid(_guid);
+        cmd.setDataCenter(_dcId);
+        cmd.setIqn(getIqn());
+        cmd.setPod(_pod);
+        cmd.setCluster(_cluster);
+        cmd.setVersion(VmwareResource.class.getPackage().getImplementationVersion());
+    }
+
+    private String getIqn() {
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+
+            if (hyperHost instanceof HostMO) {
+                HostMO host = (HostMO)hyperHost;
+                HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+                for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+                    if (hba instanceof HostInternetScsiHba) {
+                        HostInternetScsiHba hostInternetScsiHba = (HostInternetScsiHba)hba;
+
+                        if (hostInternetScsiHba.isIsSoftwareBased()) {
+                            return ((HostInternetScsiHba)hba).getIScsiName();
+                        }
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            s_logger.info("Could not locate an IQN for this host.");
+        }
+
+        return null;
+    }
+
+    private void fillHostHardwareInfo(VmwareContext serviceContext, StartupRoutingCommand cmd) throws RuntimeFaultFaultMsg, RemoteException, Exception {
+
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        VmwareHypervisorHostResourceSummary summary = hyperHost.getHyperHostResourceSummary();
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Startup report on host hardware info. " + _gson.toJson(summary));
+        }
+
+        cmd.setCaps("hvm");
+        cmd.setDom0MinMemory(0);
+        cmd.setSpeed(summary.getCpuSpeed());
+        cmd.setCpuSockets(summary.getCpuSockets());
+        cmd.setCpus((int)summary.getCpuCount());
+        cmd.setMemory(summary.getMemoryBytes());
+    }
+
+    private void fillHostNetworkInfo(VmwareContext serviceContext, StartupRoutingCommand cmd) throws RuntimeFaultFaultMsg, RemoteException {
+
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+
+            assert (hyperHost instanceof HostMO);
+            VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+
+            VmwareHypervisorHostNetworkSummary summary = hyperHost.getHyperHostNetworkSummary(mgr.getManagementPortGroupByHost((HostMO)hyperHost));
+            if (summary == null) {
+                throw new Exception("No ESX(i) host found");
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Startup report on host network info. " + _gson.toJson(summary));
+            }
+
+            cmd.setPrivateIpAddress(summary.getHostIp());
+            cmd.setPrivateNetmask(summary.getHostNetmask());
+            cmd.setPrivateMacAddress(summary.getHostMacAddress());
+
+            cmd.setStorageIpAddress(summary.getHostIp());
+            cmd.setStorageNetmask(summary.getHostNetmask());
+            cmd.setStorageMacAddress(summary.getHostMacAddress());
+
+        } catch (Throwable e) {
+            String msg = "querying host network info failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    private void fillHostDetailsInfo(VmwareContext serviceContext, Map<String, String> details) throws Exception {
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+
+        if (hyperHost.isHAEnabled()) {
+            details.put("NativeHA", "true");
+        }
+    }
+
+    protected HashMap<String, HostVmStateReportEntry> syncHostVmStates() {
+        try {
+            return getHostVmStateReport();
+        } catch (Exception e) {
+            return new HashMap<String, HostVmStateReportEntry>();
+        }
+    }
+
+    protected OptionValue[] configureVnc(OptionValue[] optionsToMerge, VmwareHypervisorHost hyperHost, String vmName, String vncPassword, String keyboardLayout) throws Exception {
+
+        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+
+        VmwareManager mgr = hyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        if (!mgr.beginExclusiveOperation(600))
+            throw new Exception("Unable to begin exclusive operation, lock time out");
+
+        try {
+            int maxVncPorts = 64;
+            int vncPort = 0;
+            Random random = new Random();
+
+            HostMO vmOwnerHost = vmMo.getRunningHost();
+
+            ManagedObjectReference morParent = vmOwnerHost.getParentMor();
+            HashMap<String, Integer> portInfo;
+            if (morParent.getType().equalsIgnoreCase("ClusterComputeResource")) {
+                ClusterMO clusterMo = new ClusterMO(vmOwnerHost.getContext(), morParent);
+                portInfo = clusterMo.getVmVncPortsOnCluster();
+            } else {
+                portInfo = vmOwnerHost.getVmVncPortsOnHost();
+            }
+
+            // allocate first at 5900 - 5964 range
+            Collection<Integer> existingPorts = portInfo.values();
+            int val = random.nextInt(maxVncPorts);
+            int startVal = val;
+            do {
+                if (!existingPorts.contains(5900 + val)) {
+                    vncPort = 5900 + val;
+                    break;
+                }
+
+                val = (++val) % maxVncPorts;
+            } while (val != startVal);
+
+            if (vncPort == 0) {
+                s_logger.info("we've run out of range for ports between 5900-5964 for the cluster, we will try port range at 59000-60000");
+
+                Pair<Integer, Integer> additionalRange = mgr.getAddiionalVncPortRange();
+                maxVncPorts = additionalRange.second();
+                val = random.nextInt(maxVncPorts);
+                startVal = val;
+                do {
+                    if (!existingPorts.contains(additionalRange.first() + val)) {
+                        vncPort = additionalRange.first() + val;
+                        break;
+                    }
+
+                    val = (++val) % maxVncPorts;
+                } while (val != startVal);
+            }
+
+            if (vncPort == 0) {
+                throw new Exception("Unable to find an available VNC port on host");
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Configure VNC port for VM " + vmName + ", port: " + vncPort + ", host: " + vmOwnerHost.getHyperHostName());
+            }
+
+            return VmwareHelper.composeVncOptions(optionsToMerge, true, vncPassword, vncPort, keyboardLayout);
+        } finally {
+            try {
+                mgr.endExclusiveOperation();
+            } catch (Throwable e) {
+                assert (false);
+                s_logger.error("Unexpected exception ", e);
+            }
+        }
+    }
+
+    private VirtualMachineGuestOsIdentifier translateGuestOsIdentifier(String cpuArchitecture, String guestOs, String cloudGuestOs) {
+        if (cpuArchitecture == null) {
+            s_logger.warn("CPU arch is not set, default to i386. guest os: " + guestOs);
+            cpuArchitecture = "i386";
+        }
+
+        if (cloudGuestOs == null) {
+            s_logger.warn("Guest OS mapping name is not set for guest os: " + guestOs);
+        }
+
+        VirtualMachineGuestOsIdentifier identifier = null;
+        try {
+            if (cloudGuestOs != null) {
+                identifier = VirtualMachineGuestOsIdentifier.fromValue(cloudGuestOs);
+                s_logger.debug("Using mapping name : " + identifier.toString());
+            }
+        } catch (IllegalArgumentException e) {
+            s_logger.warn("Unable to find Guest OS Identifier in VMware for mapping name: " + cloudGuestOs + ". Continuing with defaults.");
+        }
+        if (identifier != null) {
+            return identifier;
+        }
+
+        if (cpuArchitecture.equalsIgnoreCase("x86_64")) {
+            return VirtualMachineGuestOsIdentifier.OTHER_GUEST_64;
+        }
+        return VirtualMachineGuestOsIdentifier.OTHER_GUEST;
+    }
+
+    private HashMap<String, HostVmStateReportEntry> getHostVmStateReport() throws Exception {
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+
+        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
+        if (key == 0) {
+            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
+        }
+        String instanceNameCustomField = "value[" + key + "]";
+
+        // CLOUD_VM_INTERNAL_NAME stores the internal CS generated vm name. This was earlier stored in name. Now, name can be either the hostname or
+        // the internal CS name, but the custom field CLOUD_VM_INTERNAL_NAME always stores the internal CS name.
+        ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "runtime.powerState", "config.template", instanceNameCustomField});
+
+        HashMap<String, HostVmStateReportEntry> newStates = new HashMap<String, HostVmStateReportEntry>();
+        if (ocs != null && ocs.length > 0) {
+            for (ObjectContent oc : ocs) {
+                List<DynamicProperty> objProps = oc.getPropSet();
+                if (objProps != null) {
+
+                    boolean isTemplate = false;
+                    String name = null;
+                    String VMInternalCSName = null;
+                    VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
+                    for (DynamicProperty objProp : objProps) {
+                        if (objProp.getName().equals("config.template")) {
+                            if (objProp.getVal().toString().equalsIgnoreCase("true")) {
+                                isTemplate = true;
+                            }
+                        } else if (objProp.getName().equals("runtime.powerState")) {
+                            powerState = (VirtualMachinePowerState)objProp.getVal();
+                        } else if (objProp.getName().equals("name")) {
+                            name = (String)objProp.getVal();
+                        } else if (objProp.getName().contains(instanceNameCustomField)) {
+                            if (objProp.getVal() != null)
+                                VMInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
+                        } else {
+                            assert (false);
+                        }
+                    }
+
+                    if (VMInternalCSName != null)
+                        name = VMInternalCSName;
+
+                    if (!isTemplate) {
+                        newStates.put(name, new HostVmStateReportEntry(convertPowerState(powerState), hyperHost.getHyperHostName()));
+                    }
+                }
+            }
+        }
+        return newStates;
+    }
+
+    private HashMap<String, PowerState> getVmStates() throws Exception {
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+
+        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
+        if (key == 0) {
+            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
+        }
+        String instanceNameCustomField = "value[" + key + "]";
+
+        // CLOUD_VM_INTERNAL_NAME stores the internal CS generated vm name. This was earlier stored in name. Now, name can be either the hostname or
+        // the internal CS name, but the custom field CLOUD_VM_INTERNAL_NAME always stores the internal CS name.
+        ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "runtime.powerState", "config.template", instanceNameCustomField});
+
+        HashMap<String, PowerState> newStates = new HashMap<String, PowerState>();
+        if (ocs != null && ocs.length > 0) {
+            for (ObjectContent oc : ocs) {
+                List<DynamicProperty> objProps = oc.getPropSet();
+                if (objProps != null) {
+
+                    boolean isTemplate = false;
+                    String name = null;
+                    String VMInternalCSName = null;
+                    VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
+                    for (DynamicProperty objProp : objProps) {
+                        if (objProp.getName().equals("config.template")) {
+                            if (objProp.getVal().toString().equalsIgnoreCase("true")) {
+                                isTemplate = true;
+                            }
+                        } else if (objProp.getName().equals("runtime.powerState")) {
+                            powerState = (VirtualMachinePowerState)objProp.getVal();
+                        } else if (objProp.getName().equals("name")) {
+                            name = (String)objProp.getVal();
+                        } else if (objProp.getName().contains(instanceNameCustomField)) {
+                            if (objProp.getVal() != null)
+                                VMInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
+                        } else {
+                            assert (false);
+                        }
+                    }
+
+                    if (VMInternalCSName != null)
+                        name = VMInternalCSName;
+
+                    if (!isTemplate) {
+                        newStates.put(name, convertPowerState(powerState));
+                    }
+                }
+            }
+        }
+        return newStates;
+    }
+
+    private HashMap<String, VmStatsEntry> getVmStats(List<String> vmNames) throws Exception {
+        VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
+        HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
+        ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager();
+        VimPortType service = getServiceContext().getService();
+        PerfCounterInfo rxPerfCounterInfo = null;
+        PerfCounterInfo txPerfCounterInfo = null;
+
+        List<PerfCounterInfo> cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter");
+        for (PerfCounterInfo info : cInfo) {
+            if ("net".equalsIgnoreCase(info.getGroupInfo().getKey())) {
+                if ("transmitted".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    txPerfCounterInfo = info;
+                }
+                if ("received".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    rxPerfCounterInfo = info;
+                }
+            }
+        }
+
+        int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
+        if (key == 0) {
+            s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
+        }
+        String instanceNameCustomField = "value[" + key + "]";
+
+        final String numCpuStr = "summary.config.numCpu";
+        final String cpuUseStr = "summary.quickStats.overallCpuUsage";
+        final String guestMemUseStr = "summary.quickStats.guestMemoryUsage";
+        final String memLimitStr = "resourceConfig.memoryAllocation.limit";
+        final String memMbStr = "config.hardware.memoryMB";
+        final String allocatedCpuStr = "summary.runtime.maxCpuUsage";
+
+        ObjectContent[] ocs =
+                hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr ,guestMemUseStr ,memLimitStr ,memMbStr,allocatedCpuStr ,instanceNameCustomField});
+
+        if (ocs != null && ocs.length > 0) {
+            for (ObjectContent oc : ocs) {
+                List<DynamicProperty> objProps = oc.getPropSet();
+                if (objProps != null) {
+                    String name = null;
+                    String numberCPUs = null;
+                    double maxCpuUsage = 0;
+                    String memlimit = null;
+                    String memkb = null;
+                    String guestMemusage = null;
+                    String vmNameOnVcenter = null;
+                    String vmInternalCSName = null;
+                    double allocatedCpu = 0;
+                    for (DynamicProperty objProp : objProps) {
+                        if (objProp.getName().equals("name")) {
+                            vmNameOnVcenter = objProp.getVal().toString();
+                        } else if (objProp.getName().contains(instanceNameCustomField)) {
+                            if (objProp.getVal() != null)
+                                vmInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
+                        } else if (objProp.getName().equals(guestMemusage)) {
+                            guestMemusage = objProp.getVal().toString();
+                        } else if (objProp.getName().equals(numCpuStr)) {
+                            numberCPUs = objProp.getVal().toString();
+                        } else if (objProp.getName().equals(cpuUseStr)) {
+                            maxCpuUsage = NumberUtils.toDouble(objProp.getVal().toString());
+                        } else if (objProp.getName().equals(memLimitStr)) {
+                            memlimit = objProp.getVal().toString();
+                        } else if (objProp.getName().equals(memMbStr)) {
+                            memkb = objProp.getVal().toString();
+                        } else if (objProp.getName().equals(allocatedCpuStr)){
+                            allocatedCpu  = NumberUtils.toDouble(objProp.getVal().toString());
+                        }
+                    }
+
+                    maxCpuUsage = (maxCpuUsage/allocatedCpu)*100;
+                    new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
+                    if (vmInternalCSName != null) {
+                        name = vmInternalCSName;
+                    } else {
+                        name = vmNameOnVcenter;
+                    }
+
+                    if (!vmNames.contains(name)) {
+                        continue;
+                    }
+
+                    ManagedObjectReference vmMor = hyperHost.findVmOnHyperHost(name).getMor();
+                    assert (vmMor != null);
+
+                    ArrayList<PerfMetricId> vmNetworkMetrics = new ArrayList<PerfMetricId>();
+                    // get all the metrics from the available sample period
+                    List<PerfMetricId> perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMor, null, null, null);
+                    if (perfMetrics != null) {
+                        for (int index = 0; index < perfMetrics.size(); ++index) {
+                            if (((rxPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rxPerfCounterInfo.getKey()))
+                                    || ((txPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == txPerfCounterInfo.getKey()))) {
+                                vmNetworkMetrics.add(perfMetrics.get(index));
+                            }
+                        }
+                    }
+
+                    double networkReadKBs = 0;
+                    double networkWriteKBs = 0;
+                    long sampleDuration = 0;
+
+                    if (vmNetworkMetrics.size() != 0) {
+                        PerfQuerySpec qSpec = new PerfQuerySpec();
+                        qSpec.setEntity(vmMor);
+                        PerfMetricId[] availableMetricIds = vmNetworkMetrics.toArray(new PerfMetricId[0]);
+                        qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds));
+                        List<PerfQuerySpec> qSpecs = new ArrayList<PerfQuerySpec>();
+                        qSpecs.add(qSpec);
+                        List<PerfEntityMetricBase> values = service.queryPerf(perfMgr, qSpecs);
+
+                        for (int i = 0; i < values.size(); ++i) {
+                            List<PerfSampleInfo> infos = ((PerfEntityMetric)values.get(i)).getSampleInfo();
+                            if (infos != null && infos.size() > 0) {
+                                int endMs = infos.get(infos.size() - 1).getTimestamp().getSecond() * 1000 + infos.get(infos.size() - 1).getTimestamp().getMillisecond();
+                                int beginMs = infos.get(0).getTimestamp().getSecond() * 1000 + infos.get(0).getTimestamp().getMillisecond();
+                                sampleDuration = (endMs - beginMs) / 1000;
+                                List<PerfMetricSeries> vals = ((PerfEntityMetric)values.get(i)).getValue();
+                                for (int vi = 0; ((vals != null) && (vi < vals.size())); ++vi) {
+                                    if (vals.get(vi) instanceof PerfMetricIntSeries) {
+                                        PerfMetricIntSeries val = (PerfMetricIntSeries)vals.get(vi);
+                                        List<Long> perfValues = val.getValue();
+                                        Long sumRate = 0L;
+                                        for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo
+                                            sumRate += perfValues.get(j);
+                                        }
+                                        Long averageRate = sumRate / infos.size();
+                                        if (vals.get(vi).getId().getCounterId() == rxPerfCounterInfo.getKey()) {
+                                            networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration
+                                        }
+                                        if (vals.get(vi).getId().getCounterId() == txPerfCounterInfo.getKey()) {
+                                            networkWriteKBs = sampleDuration * averageRate;//get the average TX rate multiplied by sampled duration
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    vmResponseMap.put(name, new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024,
+                            maxCpuUsage, networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm"));
+
+                }
+            }
+        }
+        return vmResponseMap;
+    }
+
+    protected String networkUsage(final String privateIpAddress, final String option, final String ethName) {
+        String args = null;
+        if (option.equals("get")) {
+            args = "-g";
+        } else if (option.equals("create")) {
+            args = "-c";
+        } else if (option.equals("reset")) {
+            args = "-r";
+        } else if (option.equals("addVif")) {
+            args = "-a";
+            args += ethName;
+        } else if (option.equals("deleteVif")) {
+            args = "-d";
+            args += ethName;
+        }
+
+        ExecutionResult result = executeInVR(privateIpAddress, "netusage.sh", args);
+
+        if (!result.isSuccess()) {
+            return null;
+        }
+
+        return result.getDetails();
+    }
+
+    private long[] getNetworkStats(String privateIP) {
+        String result = networkUsage(privateIP, "get", null);
+        long[] stats = new long[2];
+        if (result != null) {
+            try {
+                String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += Long.parseLong(splitResult[i++]);
+                    stats[1] += Long.parseLong(splitResult[i++]);
+                }
+            } catch (Throwable e) {
+                s_logger.warn("Unable to parse return from script return of network usage command: " + e.toString(), e);
+            }
+        }
+        return stats;
+    }
+
+    protected String connect(final String vmName, final String ipAddress, final int port) {
+        long startTick = System.currentTimeMillis();
+
+        // wait until we have at least been waiting for _ops_timeout time or
+        // at least have tried _retry times, this is to coordinate with system
+        // VM patching/rebooting time that may need
+        int retry = _retry;
+        while (System.currentTimeMillis() - startTick <= _opsTimeout || --retry > 0) {
+            s_logger.info("Trying to connect to " + ipAddress);
+            try (SocketChannel sch = SocketChannel.open();) {
+                sch.configureBlocking(true);
+                sch.socket().setSoTimeout(5000);
+
+                InetSocketAddress addr = new InetSocketAddress(ipAddress, port);
+                sch.connect(addr);
+                return null;
+            } catch (IOException e) {
+                s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString());
+                if (e instanceof ConnectException) {
+                    // if connection is refused because of VM is being started,
+                    // we give it more sleep time
+                    // to avoid running out of retry quota too quickly
+                    try {
+                        Thread.sleep(5000);
+                    } catch (InterruptedException ex) {
+                        s_logger.debug("[ignored] interupted while waiting to retry connect after failure.", e);
+                    }
+                }
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ex) {
+                s_logger.debug("[ignored] interupted while waiting to retry connect.");
+            }
+        }
+
+        s_logger.info("Unable to logon to " + ipAddress);
+
+        return "Unable to connect";
+    }
+
+    protected String connect(final String vmname, final String ipAddress) {
+        return connect(vmname, ipAddress, 3922);
+    }
+
+    public static PowerState getVmState(VirtualMachineMO vmMo) throws Exception {
+        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
+        return convertPowerState(runtimeInfo.getPowerState());
+    }
+
+    private static PowerState convertPowerState(VirtualMachinePowerState powerState) {
+        return s_powerStatesTable.get(powerState);
+    }
+
+    public static PowerState getVmPowerState(VirtualMachineMO vmMo) throws Exception {
+        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
+        return convertPowerState(runtimeInfo.getPowerState());
+    }
+
+    private static HostStatsEntry getHyperHostStats(VmwareHypervisorHost hyperHost) throws Exception {
+        ComputeResourceSummary hardwareSummary = hyperHost.getHyperHostHardwareSummary();
+        if (hardwareSummary == null)
+            return null;
+
+        HostStatsEntry entry = new HostStatsEntry();
+
+        entry.setEntityType("host");
+        double cpuUtilization = ((double)(hardwareSummary.getTotalCpu() - hardwareSummary.getEffectiveCpu()) / (double)hardwareSummary.getTotalCpu() * 100);
+        entry.setCpuUtilization(cpuUtilization);
+        entry.setTotalMemoryKBs(hardwareSummary.getTotalMemory() / 1024);
+        entry.setFreeMemoryKBs(hardwareSummary.getEffectiveMemory() * 1024);
+
+        return entry;
+    }
+
+    private static String getRouterSshControlIp(NetworkElementCommand cmd) {
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        String routerGuestIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
+        String zoneNetworkType = cmd.getAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE);
+
+        if (routerGuestIp != null && zoneNetworkType != null && NetworkType.valueOf(zoneNetworkType) == NetworkType.Basic) {
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("In Basic zone mode, use router's guest IP for SSH control. guest IP : " + routerGuestIp);
+
+            return routerGuestIp;
+        }
+
+        if (s_logger.isDebugEnabled())
+            s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
+        return routerIp;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        try {
+            _name = name;
+
+            _url = (String)params.get("url");
+            _username = (String)params.get("username");
+            _password = (String)params.get("password");
+            _dcId = (String)params.get("zone");
+            _pod = (String)params.get("pod");
+            _cluster = (String)params.get("cluster");
+
+            _guid = (String)params.get("guid");
+            String[] tokens = _guid.split("@");
+            _vCenterAddress = tokens[1];
+            _morHyperHost = new ManagedObjectReference();
+            String[] hostTokens = tokens[0].split(":");
+            _morHyperHost.setType(hostTokens[0]);
+            _morHyperHost.setValue(hostTokens[1]);
+
+            _guestTrafficInfo = (VmwareTrafficLabel)params.get("guestTrafficInfo");
+            _publicTrafficInfo = (VmwareTrafficLabel)params.get("publicTrafficInfo");
+            VmwareContext context = getServiceContext();
+            VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            if (mgr == null) {
+                throw new ConfigurationException("Invalid vmwareContext:  vmwareMgr stock object is not set or cleared.");
+            }
+            mgr.setupResourceStartupParams(params);
+
+            CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
+            cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
+            if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch
+                    || _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
+                cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
+            }
+            cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
+            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
+            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
+            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
+            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
+            cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
+
+            VmwareHypervisorHost hostMo = this.getHyperHost(context);
+            _hostName = hostMo.getHyperHostName();
+
+            if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch
+                    || _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) {
+                _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware);
+                _vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster));
+            }
+
+            if (_privateNetworkVSwitchName == null) {
+                _privateNetworkVSwitchName = (String)params.get("private.network.vswitch.name");
+            }
+
+            String value = (String)params.get("vmware.recycle.hung.wokervm");
+            if (value != null && value.equalsIgnoreCase("true"))
+                _recycleHungWorker = true;
+
+            value = (String)params.get("vmware.root.disk.controller");
+            if (value != null && value.equalsIgnoreCase("scsi"))
+                _rootDiskController = DiskControllerType.scsi;
+            else if (value != null && value.equalsIgnoreCase("ide"))
+                _rootDiskController = DiskControllerType.ide;
+            else
+                _rootDiskController = DiskControllerType.osdefault;
+
+            Integer intObj = (Integer)params.get("ports.per.dvportgroup");
+            if (intObj != null)
+                _portsPerDvPortGroup = intObj.intValue();
+
+            s_logger.info("VmwareResource network configuration info." + " private traffic over vSwitch: " + _privateNetworkVSwitchName + ", public traffic over "
+                    + _publicTrafficInfo.getVirtualSwitchType() + " : " + _publicTrafficInfo.getVirtualSwitchName() + ", guest traffic over "
+                    + _guestTrafficInfo.getVirtualSwitchType() + " : " + _guestTrafficInfo.getVirtualSwitchName());
+
+            Boolean boolObj = (Boolean)params.get("vmware.create.full.clone");
+            if (boolObj != null && boolObj.booleanValue()) {
+                _fullCloneFlag = true;
+            } else {
+                _fullCloneFlag = false;
+            }
+
+            boolObj = (Boolean)params.get("vm.instancename.flag");
+            if (boolObj != null && boolObj.booleanValue()) {
+                _instanceNameFlag = true;
+            } else {
+                _instanceNameFlag = false;
+            }
+
+            value = (String)params.get("scripts.timeout");
+            int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
+
+            storageNfsVersion = NfsSecondaryStorageResource.retrieveNfsVersionFromParams(params);
+            _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null,
+                    storageNfsVersion);
+            storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, storageNfsVersion);
+
+            _vrResource = new VirtualRoutingResource(this);
+            if (!_vrResource.configure(name, params)) {
+                throw new ConfigurationException("Unable to configure VirtualRoutingResource");
+            }
+
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Successfully configured VmwareResource.");
+            }
+            return true;
+        } catch (Exception e) {
+            s_logger.error("Unexpected Exception ", e);
+            throw new ConfigurationException("Failed to configure VmwareResource due to unexpect exception.");
+        } finally {
+            recycleServiceContext();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    public VmwareContext getServiceContext() {
+        return getServiceContext(null);
+    }
+
+    public void invalidateServiceContext() {
+        invalidateServiceContext(null);
+    }
+
+    public VmwareHypervisorHost getHyperHost(VmwareContext context) {
+        return getHyperHost(context, null);
+    }
+
+    @Override
+    public VmwareContext getServiceContext(Command cmd) {
+        VmwareContext context = null;
+        if (s_serviceContext.get() != null) {
+            context = s_serviceContext.get();
+            String poolKey = VmwareContextPool.composePoolKey(_vCenterAddress, _username);
+            // Before re-using the thread local context, ensure it corresponds to the right vCenter API session and that it is valid to make calls.
+            if (context.getPoolKey().equals(poolKey)) {
+                if (context.validate()) {
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("ThreadLocal context is still valid, just reuse");
+                    }
+                    return context;
+                } else {
+                    s_logger.info("Validation of the context failed, dispose and use a new one");
+                    invalidateServiceContext(context);
+                }
+            } else {
+                // Exisitng ThreadLocal context corresponds to a different vCenter API session. Why has it not been recycled?
+                s_logger.warn("ThreadLocal VMware context: " + poolKey + " doesn't correspond to the right vCenter. Expected VMware context: " + context.getPoolKey());
+            }
+        }
+        try {
+            context = VmwareContextFactory.getContext(_vCenterAddress, _username, _password);
+            s_serviceContext.set(context);
+        } catch (Exception e) {
+            s_logger.error("Unable to connect to vSphere server: " + _vCenterAddress, e);
+            throw new CloudRuntimeException("Unable to connect to vSphere server: " + _vCenterAddress);
+        }
+        return context;
+    }
+
+    @Override
+    public void invalidateServiceContext(VmwareContext context) {
+        assert (s_serviceContext.get() == context);
+
+        s_serviceContext.set(null);
+        if (context != null)
+            context.close();
+    }
+
+    private static void recycleServiceContext() {
+        VmwareContext context = s_serviceContext.get();
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Reset threadlocal context to null");
+        }
+        s_serviceContext.set(null);
+
+        if (context != null) {
+            assert (context.getPool() != null);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Recycling threadlocal context to pool");
+            }
+            context.getPool().registerContext(context);
+        }
+    }
+
+    @Override
+    public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) {
+        if (_morHyperHost.getType().equalsIgnoreCase("HostSystem")) {
+            return new HostMO(context, _morHyperHost);
+        }
+        return new ClusterMO(context, _morHyperHost);
+    }
+
+    @Override
+    @DB
+    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
+        VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        String vmName = mgr.composeWorkerName();
+
+        assert (cmd != null);
+        context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        // TODO: Fix this? long checkPointId = vmwareMgr.pushCleanupCheckpoint(this._guid, vmName);
+        // TODO: Fix this? cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
+        return vmName;
+    }
+
+    @Override
+    public void setName(String name) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Answer execute(DestroyCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource DestroyCommand to evict template from storage pool: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = getServiceContext(null);
+            VmwareHypervisorHost hyperHost = getHyperHost(context, null);
+            VolumeTO vol = cmd.getVolume();
+
+            VirtualMachineMO vmMo = findVmOnDatacenter(context, hyperHost, vol);
+
+            if (vmMo != null && vmMo.isTemplate()) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Destroy template volume " + vol.getPath());
+                }
+                vmMo.destroy();
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Template volume " + vol.getPath() + " is not found, no need to delete.");
+                }
+            }
+            return new Answer(cmd, true, "Success");
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                invalidateServiceContext(null);
+            }
+
+            String msg = "DestroyCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    /**
+     * Use data center to look for vm, instead of randomly picking up a cluster<br/>
+     * (in multiple cluster environments vm could not be found if wrong cluster was chosen)
+     * @param context vmware context
+     * @param hyperHost vmware hv host
+     * @param vol volume
+     * @return a virtualmachinemo if could be found on datacenter.
+     * @throws Exception if there is an error while finding vm
+     * @throws CloudRuntimeException if datacenter cannot be found
+     */
+    protected VirtualMachineMO findVmOnDatacenter(VmwareContext context, VmwareHypervisorHost hyperHost, VolumeTO vol) throws Exception {
+        DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
+        if (dcMo.getMor() == null) {
+            String msg = "Unable to find VMware DC";
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        return dcMo.findVm(vol.getPath());
+    }
+
+    public String getAbsoluteVmdkFile(VirtualDisk disk) {
+        String vmdkAbsFile = null;
+        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
+        if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+            VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+            vmdkAbsFile = diskBackingInfo.getFileName();
+        }
+        return vmdkAbsFile;
+    }
+
+    protected File getSystemVmKeyFile() {
+        if (s_systemVmKeyFile == null) {
+            syncFetchSystemVmKeyFile();
+        }
+        return s_systemVmKeyFile;
+    }
+
+    private static void syncFetchSystemVmKeyFile() {
+        synchronized (s_syncLockObjectFetchKeyFile) {
+            if (s_systemVmKeyFile == null) {
+                s_systemVmKeyFile = fetchSystemVmKeyFile();
+            }
+        }
+    }
+
+    private static File fetchSystemVmKeyFile() {
+        String filePath = s_relativePathSystemVmKeyFileInstallDir;
+        s_logger.debug("Looking for file [" + filePath + "] in the classpath.");
+        URL url = Script.class.getClassLoader().getResource(filePath);
+        File keyFile = null;
+        if (url != null) {
+            keyFile = new File(url.getPath());
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            filePath = s_defaultPathSystemVmKeyFile;
+            keyFile = new File(filePath);
+            s_logger.debug("Looking for file [" + filePath + "] in the classpath.");
+        }
+        if (!keyFile.exists()) {
+            s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
+        }
+        return keyFile;
+    }
+}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDevice.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDevice.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDevice.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDevice.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDeviceVO.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/CiscoNexusVSMDeviceVO.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/VmwareTrafficLabel.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/VmwareTrafficLabel.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/VmwareTrafficLabel.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/VmwareTrafficLabel.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/dao/CiscoNexusVSMDeviceDao.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/dao/CiscoNexusVSMDeviceDao.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/dao/CiscoNexusVSMDeviceDao.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/dao/CiscoNexusVSMDeviceDao.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/dao/CiscoNexusVSMDeviceDaoImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/dao/CiscoNexusVSMDeviceDaoImpl.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/dao/CiscoNexusVSMDeviceDaoImpl.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/dao/CiscoNexusVSMDeviceDaoImpl.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElementService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElementService.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElementService.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElementService.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutType.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutType.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutType.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutType.java
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
new file mode 100644
index 0000000..82cd4ca
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -0,0 +1,3542 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.resource;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.vmware.vim25.DatastoreHostMount;
+import com.vmware.vim25.HostHostBusAdapter;
+import com.vmware.vim25.HostInternetScsiHba;
+import com.vmware.vim25.HostInternetScsiHbaAuthenticationProperties;
+import com.vmware.vim25.HostInternetScsiHbaSendTarget;
+import com.vmware.vim25.HostInternetScsiHbaStaticTarget;
+import com.vmware.vim25.HostInternetScsiTargetTransport;
+import com.vmware.vim25.HostResignatureRescanResult;
+import com.vmware.vim25.HostUnresolvedVmfsResignatureSpec;
+import com.vmware.vim25.HostScsiDisk;
+import com.vmware.vim25.HostScsiTopology;
+import com.vmware.vim25.HostScsiTopologyInterface;
+import com.vmware.vim25.HostScsiTopologyLun;
+import com.vmware.vim25.HostScsiTopologyTarget;
+import com.vmware.vim25.HostUnresolvedVmfsExtent;
+import com.vmware.vim25.HostUnresolvedVmfsVolume;
+import com.vmware.vim25.InvalidStateFaultMsg;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.VirtualDeviceBackingInfo;
+import com.vmware.vim25.VirtualDeviceConfigSpec;
+import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
+import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
+import com.vmware.vim25.VmfsDatastoreExpandSpec;
+import com.vmware.vim25.VmfsDatastoreOption;
+
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.ResignatureAnswer;
+import org.apache.cloudstack.storage.command.ResignatureCommand;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.hypervisor.vmware.manager.VmwareHostService;
+import com.cloud.hypervisor.vmware.manager.VmwareManager;
+import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
+import com.cloud.hypervisor.vmware.mo.ClusterMO;
+import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
+import com.cloud.hypervisor.vmware.mo.DatacenterMO;
+import com.cloud.hypervisor.vmware.mo.DatastoreFile;
+import com.cloud.hypervisor.vmware.mo.DatastoreMO;
+import com.cloud.hypervisor.vmware.mo.DiskControllerType;
+import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
+import com.cloud.hypervisor.vmware.mo.HostMO;
+import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
+import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
+import com.cloud.hypervisor.vmware.mo.NetworkDetails;
+import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
+import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
+import com.cloud.hypervisor.vmware.resource.VmwareResource;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Volume;
+import com.cloud.storage.template.OVAProcessor;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VmDetailConstants;
+
+public class VmwareStorageProcessor implements StorageProcessor {
+
+    public enum VmwareStorageProcessorConfigurableFields {
+        NFS_VERSION("nfsVersion"), FULL_CLONE_FLAG("fullCloneFlag");
+
+        private String name;
+
+        VmwareStorageProcessorConfigurableFields(String name){
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
+    private static final int DEFAULT_NFS_PORT = 2049;
+    private static final int SECONDS_TO_WAIT_FOR_DATASTORE = 120;
+
+    private final VmwareHostService hostService;
+    private boolean _fullCloneFlag;
+    private final VmwareStorageMount mountService;
+    private final VmwareResource resource;
+    private final Integer _timeout;
+    protected Integer _shutdownWaitMs;
+    private final Gson _gson;
+    private final StorageLayer _storage = new JavaStorageLayer();
+    private Integer _nfsVersion;
+    private static final Random RANDOM = new Random(System.nanoTime());
+
+    public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, Integer timeout, VmwareResource resource,
+                                  Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource, Integer nfsVersion) {
+        this.hostService = hostService;
+        _fullCloneFlag = fullCloneFlag;
+        this.mountService = mountService;
+        _timeout = timeout;
+        this.resource = resource;
+        _shutdownWaitMs = shutdownWaitMs;
+        _gson = GsonHelper.getGsonLogger();
+        _nfsVersion = nfsVersion;
+    }
+
+    @Override
+    public SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand cmd) {
+        s_logger.info("'SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand)' not currently used for VmwareStorageProcessor");
+
+        return new SnapshotAndCopyAnswer();
+    }
+
+    @Override
+    public ResignatureAnswer resignature(ResignatureCommand cmd) {
+        final Map<String, String> details = cmd.getDetails();
+
+        String scsiNaaDeviceId = details.get(DiskTO.SCSI_NAA_DEVICE_ID);
+
+        if (scsiNaaDeviceId == null || scsiNaaDeviceId.trim().length() == 0) {
+            throw new CloudRuntimeException("The 'scsiNaaDeviceId' needs to be specified when resignaturing a VMware datastore.");
+        }
+
+        final String iScsiName = details.get(DiskTO.IQN);
+        final String datastoreName = getMaximumDatastoreName(VmwareResource.getDatastoreName(iScsiName));
+
+        String vmdk = null;
+
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+
+            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+            ClusterMO clusterMO = new ClusterMO(context, morCluster);
+
+            List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
+
+            // add iSCSI connection to host
+
+            final String storageHost = details.get(DiskTO.STORAGE_HOST);
+            final int storagePortNumber = Integer.parseInt(details.get(DiskTO.STORAGE_PORT));
+            final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
+            final String chapTargetUsername = details.get(DiskTO.CHAP_TARGET_USERNAME);
+            final String chapTargetSecret = details.get(DiskTO.CHAP_TARGET_SECRET);
+
+            HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
+            List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+            if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+                List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
+                        chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+
+                addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
+            }
+
+            rescanAllHosts(context, lstHosts, true, true);
+
+            // perform resignature operation
+
+            HostMO hostMO = new HostMO(context, lstHosts.get(0).first());
+
+            HostDatastoreSystemMO hostDatastoreSystem = hostMO.getHostDatastoreSystemMO();
+
+            List<HostUnresolvedVmfsVolume> hostUnresolvedVmfsVolumes = hostDatastoreSystem.queryUnresolvedVmfsVolumes();
+
+            if (hostUnresolvedVmfsVolumes == null || hostUnresolvedVmfsVolumes.size() == 0) {
+                throw new CloudRuntimeException("Unable to locate any snapshot datastores");
+            }
+
+            boolean foundExtent = false;
+
+            for (HostUnresolvedVmfsVolume hostUnresolvedVmfsVolume : hostUnresolvedVmfsVolumes) {
+                List<HostUnresolvedVmfsExtent> extents = hostUnresolvedVmfsVolume.getExtent();
+                List<HostUnresolvedVmfsExtent> matchingExtents = getExtentsMatching(extents, scsiNaaDeviceId);
+
+                if (matchingExtents.size() >= 1) {
+                    String extentDevicePath = matchingExtents.get(0).getDevicePath();
+                    HostResignatureRescanResult hostResignatureRescanResult = resignatureDatastore(hostDatastoreSystem, extentDevicePath);
+
+                    if (hostResignatureRescanResult == null) {
+                        throw new CloudRuntimeException("'hostResignatureRescanResult' should not be 'null'.");
+                    }
+
+                    ManagedObjectReference morDs = hostResignatureRescanResult.getResult();
+
+                    if (morDs == null) {
+                        throw new CloudRuntimeException("'morDs' should not be 'null'.");
+                    }
+
+                    DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
+
+                    boolean isOnlyForTemplate = Boolean.parseBoolean(details.get(DiskTO.TEMPLATE_RESIGN));
+
+                    // If this is only for a template, all we really want to do is resignature the datastore (done at this point),
+                    // then rename the datastore.
+                    if (isOnlyForTemplate) {
+                        vmdk = details.get(DiskTO.VMDK);
+                    }
+                    else {
+                        vmdk = cleanUpDatastore(cmd, hostDatastoreSystem, datastoreMO, details);
+                    }
+
+                    if (renameDatastore(context, morDs, datastoreName, lstHosts)) {
+                        foundExtent = true;
+
+                        break;
+                    }
+                }
+            }
+
+            removeVmfsDatastore(cmd, hyperHost, datastoreName, storageHost, storagePortNumber, trimIqn(iScsiName), lstHosts);
+
+            if (!foundExtent) {
+                throw new CloudRuntimeException("Unable to locate the applicable extent");
+            }
+
+            final ResignatureAnswer answer = new ResignatureAnswer();
+
+            final long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
+
+            answer.setSize(volumeSize);
+
+            answer.setPath("[" + datastoreName + "] " + vmdk);
+
+            answer.setFormat(ImageFormat.OVA);
+
+            return answer;
+        }
+        catch (Exception ex) {
+            s_logger.debug(ex.getMessage());
+
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+    }
+
+    private List<HostUnresolvedVmfsExtent> getExtentsMatching(List<HostUnresolvedVmfsExtent> extents, String naa) {
+        List<HostUnresolvedVmfsExtent> matchingExtents = new ArrayList<>();
+
+        if (extents != null) {
+            for (HostUnresolvedVmfsExtent extent : extents) {
+                s_logger.debug("extent devicePath=" + extent.getDevicePath() + ", ordinal=" + extent.getOrdinal()
+                        + ", reason=" + extent.getReason() + ", isHeadExtent=" + extent.isIsHeadExtent());
+
+                String extentDevicePath = extent.getDevicePath();
+
+                if (extentDevicePath.contains(naa)) {
+                    matchingExtents.add(extent);
+                }
+            }
+        }
+
+        return matchingExtents;
+    }
+
+    private class HostUnresolvedVmfsResignatureSpecCustom extends HostUnresolvedVmfsResignatureSpec {
+        private HostUnresolvedVmfsResignatureSpecCustom(String extentDevicePath) {
+            this.extentDevicePath = new ArrayList<>(1);
+
+            this.extentDevicePath.add(extentDevicePath);
+        }
+    }
+
+    private HostResignatureRescanResult resignatureDatastore(HostDatastoreSystemMO hostDatastoreSystemMO, String extentDevicePath) throws Exception {
+        HostUnresolvedVmfsResignatureSpecCustom resignatureSpec = new HostUnresolvedVmfsResignatureSpecCustom(extentDevicePath);
+
+        return hostDatastoreSystemMO.resignatureUnresolvedVmfsVolume(resignatureSpec);
+    }
+
+    private boolean renameDatastore(VmwareContext context, ManagedObjectReference morDs, String newName, List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
+        if (morDs != null) {
+            DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
+
+            datastoreMO.renameDatastore(newName);
+
+            waitForAllHostsToMountDatastore(lstHosts, datastoreMO);
+
+            return true;
+        }
+
+        s_logger.debug("Unable to locate datastore to rename");
+
+        return false;
+    }
+
+    private String getMaximumDatastoreName(String datastoreName) {
+        final int maxDatastoreNameLength = 80;
+
+        return datastoreName.length() > maxDatastoreNameLength ? datastoreName.substring(0, maxDatastoreNameLength) : datastoreName;
+    }
+
+    /**
+     * 1) Possibly expand the datastore.
+     * 2) Possibly consolidate all relevant VMDK files into one VMDK file.
+     * 3) Possibly move the VMDK file to the root folder (may already be there).
+     * 4) If the VMDK file wasn't already in the root folder, then delete the folder the VMDK file was in.
+     * 5) Possibly rename the VMDK file (this will lead to there being a delta file with the new name and the
+     *    original file with the original name).
+     *
+     * Note: If the underlying VMDK file was for a root disk, the 'vmdk' parameter's value might look, for example,
+     *  like "i-2-32-VM/ROOT-32.vmdk".
+     *
+     * Note: If the underlying VMDK file was for a data disk, the 'vmdk' parameter's value might look, for example,
+     *  like "-iqn.2010-01.com.solidfire:4nhe.data-32.79-0.vmdk".
+     *
+     * Returns the (potentially new) name of the VMDK file.
+     */
+    private String cleanUpDatastore(Command cmd, HostDatastoreSystemMO hostDatastoreSystem, DatastoreMO dsMo, Map<String, String> details) throws Exception {
+        boolean expandDatastore = Boolean.parseBoolean(details.get(DiskTO.EXPAND_DATASTORE));
+
+        // A volume on the storage system holding a template uses a minimum hypervisor snapshot reserve value.
+        // When this volume is cloned to a new volume, the new volume can be expanded (to take a new hypervisor snapshot reserve value
+        // into consideration). If expandDatastore is true, we want to expand the datastore in the new volume to the size of the cloned volume.
+        // It's possible that expandDatastore might be true and there isn't any extra space in the cloned volume (if the hypervisor snapshot
+        // reserve value in use is set to the minimum for the cloned volume), but that's fine.
+        if (expandDatastore) {
+            expandDatastore(hostDatastoreSystem, dsMo);
+        }
+
+        String vmdk = details.get(DiskTO.VMDK);
+        String fullVmdkPath = new DatastoreFile(dsMo.getName(), vmdk).getPath();
+
+        VmwareContext context = hostService.getServiceContext(null);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+
+        DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
+
+        String vmName = getVmName(vmdk);
+
+        // If vmName is not null, then move all VMDK files out of this folder to the root folder and then delete the folder named vmName.
+        if (vmName != null) {
+            String workerVmName = hostService.getWorkerName(context, cmd, 0);
+
+            VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
+
+            if (vmMo == null) {
+                throw new Exception("Unable to create a worker VM for volume creation");
+            }
+
+            vmMo.attachDisk(new String[] { fullVmdkPath }, dsMo.getMor());
+
+            List<String> backingFiles = new ArrayList<>(1);
+
+            List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
+
+            VirtualDisk virtualDisk = virtualDisks.get(0);
+
+            VirtualDeviceBackingInfo virtualDeviceBackingInfo = virtualDisk.getBacking();
+
+            while (virtualDeviceBackingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDeviceBackingInfo;
+
+                backingFiles.add(backingInfo.getFileName());
+
+                virtualDeviceBackingInfo = backingInfo.getParent();
+            }
+
+            vmMo.detachAllDisks();
+            vmMo.destroy();
+
+            VmwareStorageLayoutHelper.moveVolumeToRootFolder(dcMo, backingFiles);
+
+            vmdk = new DatastoreFile(vmdk).getFileName();
+
+            // Delete the folder the VMDK file was in.
+
+            DatastoreFile folderToDelete = new DatastoreFile(dsMo.getName(), vmName);
+
+            dsMo.deleteFolder(folderToDelete.getPath(), dcMo.getMor());
+        }
+
+        return vmdk;
+    }
+
+    /**
+     * Example input for the 'vmdk' parameter:
+     *  i-2-32-VM/ROOT-32.vmdk
+     *  -iqn.2010-01.com.solidfire:4nhe.data-32.79-0.vmdk
+     */
+    private String getVmName(String vmdk) {
+        int indexOf = vmdk.indexOf("/");
+
+        if (indexOf == -1) {
+            return null;
+        }
+
+        return vmdk.substring(0, indexOf).trim();
+    }
+
+    public void expandDatastore(HostDatastoreSystemMO hostDatastoreSystem, DatastoreMO datastoreMO) throws Exception {
+        List<VmfsDatastoreOption> vmfsDatastoreOptions = hostDatastoreSystem.queryVmfsDatastoreExpandOptions(datastoreMO);
+
+        if (vmfsDatastoreOptions != null && vmfsDatastoreOptions.size() > 0) {
+            VmfsDatastoreExpandSpec vmfsDatastoreExpandSpec = (VmfsDatastoreExpandSpec)vmfsDatastoreOptions.get(0).getSpec();
+
+            hostDatastoreSystem.expandVmfsDatastore(datastoreMO, vmfsDatastoreExpandSpec);
+        }
+    }
+
+    private String getOVFFilePath(String srcOVAFileName) {
+        File file = new File(srcOVAFileName);
+        assert (_storage != null);
+        String[] files = _storage.listFiles(file.getParent());
+        if (files != null) {
+            for (String fileName : files) {
+                if (fileName.toLowerCase().endsWith(".ovf")) {
+                    File ovfFile = new File(fileName);
+                    return file.getParent() + File.separator + ovfFile.getName();
+                }
+            }
+        }
+        return null;
+    }
+
+    private Pair<VirtualMachineMO, Long> copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
+                                                                            String templatePathAtSecondaryStorage, String templateName, String templateUuid,
+                                                                            boolean createSnapshot, Integer nfsVersion) throws Exception {
+        s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
+                templatePathAtSecondaryStorage + ", templateName: " + templateName);
+
+        String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
+        s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
+
+        String srcOVAFileName =
+                VmwareStorageLayoutHelper.getTemplateOnSecStorageFilePath(secondaryMountPoint, templatePathAtSecondaryStorage, templateName,
+                        ImageFormat.OVA.getFileExtension());
+
+        String srcFileName = getOVFFilePath(srcOVAFileName);
+        if (srcFileName == null) {
+            Script command = new Script("tar", 0, s_logger);
+            command.add("--no-same-owner");
+            command.add("-xf", srcOVAFileName);
+            command.setWorkDir(secondaryMountPoint + "/" + templatePathAtSecondaryStorage);
+            s_logger.info("Executing command: " + command.toString());
+            String result = command.execute();
+            if (result != null) {
+                String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+        }
+
+        srcFileName = getOVFFilePath(srcOVAFileName);
+        if (srcFileName == null) {
+            String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
+            s_logger.error(msg);
+            throw new Exception(msg);
+        }
+
+        String vmName = templateUuid;
+        hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin");
+
+        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+        if (vmMo == null) {
+            String msg =
+                    "Failed to import OVA template. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage +
+                            ", templateName: " + templateName + ", templateUuid: " + templateUuid;
+            s_logger.error(msg);
+            throw new Exception(msg);
+        }
+
+        OVAProcessor processor = new OVAProcessor();
+        Map<String, Object> params = new HashMap<>();
+        params.put(StorageLayer.InstanceConfigKey, _storage);
+        processor.configure("OVA Processor", params);
+        long virtualSize = processor.getTemplateVirtualSize(secondaryMountPoint + "/" + templatePathAtSecondaryStorage, templateName);
+
+        if (createSnapshot) {
+            if (vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) {
+                // the same template may be deployed with multiple copies at per-datastore per-host basis,
+                // save the original template name from CloudStack DB as the UUID to associate them.
+                vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateName);
+                vmMo.markAsTemplate();
+            } else {
+                vmMo.destroy();
+
+                String msg = "Unable to create base snapshot for template, templateName: " + templateName + ", templateUuid: " + templateUuid;
+
+                s_logger.error(msg);
+
+                throw new Exception(msg);
+            }
+        }
+
+        return new Pair<>(vmMo, virtualSize);
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)srcData;
+        DataStoreTO srcStore = srcData.getDataStore();
+
+        if (!(srcStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)srcStore;
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO destStore = destData.getDataStore();
+        DataStoreTO primaryStore = destStore;
+
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+
+        assert secondaryStorageUrl != null;
+
+        boolean managed = false;
+        String storageHost = null;
+        int storagePort = Integer.MIN_VALUE;
+        String managedStoragePoolName = null;
+        String managedStoragePoolRootVolumeName = null;
+        String chapInitiatorUsername = null;
+        String chapInitiatorSecret = null;
+        String chapTargetUsername = null;
+        String chapTargetSecret = null;
+
+        if (destStore instanceof PrimaryDataStoreTO) {
+            PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destStore;
+
+            Map<String, String> details = destPrimaryDataStoreTo.getDetails();
+
+            if (details != null) {
+                managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
+
+                if (managed) {
+                    storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
+
+                    try {
+                        storagePort = Integer.parseInt(details.get(PrimaryDataStoreTO.STORAGE_PORT));
+                    }
+                    catch (Exception ex) {
+                        storagePort = 3260;
+                    }
+
+                    managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
+                    managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
+                    chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
+                    chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
+                    chapTargetUsername = details.get(PrimaryDataStoreTO.CHAP_TARGET_USERNAME);
+                    chapTargetSecret = details.get(PrimaryDataStoreTO.CHAP_TARGET_SECRET);
+                }
+            }
+        }
+
+        String templateUrl = secondaryStorageUrl + "/" + srcData.getPath();
+        Pair<String, String> templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+
+        if (context == null) {
+            return new CopyCmdAnswer("Failed to create a VMware context, check the management server logs or the SSVM log for details");
+        }
+
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+        DatastoreMO dsMo = null;
+
+        try {
+            String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
+            String templateUuidName = deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
+            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
+            VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
+            Pair<VirtualMachineMO, Long> vmInfo = null;
+
+            if (templateMo == null) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
+                }
+
+                final ManagedObjectReference morDs;
+
+                if (managed) {
+                    morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort,
+                                chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+                }
+                else {
+                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
+                }
+
+                assert (morDs != null);
+
+                dsMo = new DatastoreMO(context, morDs);
+
+                if (managed) {
+                    vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
+                            managedStoragePoolRootVolumeName, false, _nfsVersion);
+
+                    VirtualMachineMO vmMo = vmInfo.first();
+                    vmMo.unregisterVm();
+
+                    String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName,
+                            managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false);
+                    String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null,
+                            managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
+
+                    dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
+                    dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
+
+                    String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
+                    dsMo.deleteFolder(folderToDelete, dcMo.getMor());
+                }
+                else {
+                    vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
+                            templateUuidName, true, _nfsVersion);
+                }
+            } else {
+                s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
+            }
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            if (managed) {
+                if (dsMo != null) {
+                    String path = dsMo.getDatastorePath(managedStoragePoolRootVolumeName + ".vmdk");
+
+                    newTemplate.setPath(path);
+                }
+            }
+            else {
+                newTemplate.setPath(templateUuidName);
+            }
+
+            newTemplate.setSize((vmInfo != null)? vmInfo.second() : new Long(0));
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            String msg = "Unable to copy template to primary storage due to exception:" + VmwareHelper.getExceptionMessage(e);
+
+            s_logger.error(msg, e);
+
+            return new CopyCmdAnswer(msg);
+        }
+        finally {
+            if (dsMo != null && managedStoragePoolName != null) {
+                try {
+                    removeVmfsDatastore(cmd, hyperHost, VmwareResource.getDatastoreName(managedStoragePoolName), storageHost, storagePort, trimIqn(managedStoragePoolName));
+                }
+                catch (Exception ex) {
+                    s_logger.error("Unable to remove the following datastore: " + VmwareResource.getDatastoreName(managedStoragePoolName), ex);
+                }
+            }
+        }
+    }
+
+    private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, String vmdkName, ManagedObjectReference morDatastore,
+                                        ManagedObjectReference morPool) throws Exception {
+        return createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool, null);
+    }
+
+    private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, String vmdkName, ManagedObjectReference morDatastore,
+                                        ManagedObjectReference morPool, ManagedObjectReference morBaseSnapshot) throws Exception {
+        if (morBaseSnapshot == null) {
+            morBaseSnapshot = vmTemplate.getSnapshotMor("cloud.template.base");
+        }
+
+        if (morBaseSnapshot == null) {
+            String msg = "Unable to find template base snapshot, invalid template";
+
+            s_logger.error(msg);
+
+            throw new Exception(msg);
+        }
+
+        s_logger.info("creating linked clone from template");
+
+        if (!vmTemplate.createLinkedClone(vmdkName, morBaseSnapshot, dcMo.getVmFolder(), morPool, morDatastore)) {
+            String msg = "Unable to clone from the template";
+
+            s_logger.error(msg);
+
+            throw new Exception(msg);
+        }
+
+        return true;
+    }
+
+    private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, String vmdkName, ManagedObjectReference morDatastore,
+                                      ManagedObjectReference morPool) throws Exception {
+        s_logger.info("creating full clone from template");
+
+        if (!vmTemplate.createFullClone(vmdkName, dcMo.getVmFolder(), morPool, morDatastore)) {
+            String msg = "Unable to create full clone from the template";
+
+            s_logger.error(msg);
+
+            throw new Exception(msg);
+        }
+
+        return true;
+    }
+
+    @Override
+    public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)srcData;
+        DataTO destData = cmd.getDestTO();
+        VolumeObjectTO volume = (VolumeObjectTO)destData;
+        DataStoreTO primaryStore = volume.getDataStore();
+        DataStoreTO srcStore = template.getDataStore();
+        String searchExcludedFolders = cmd.getContextParam("searchexludefolders");
+
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
+            VirtualMachineMO vmMo = null;
+            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
+            if (morDatastore == null) {
+                throw new Exception("Unable to find datastore in vSphere");
+            }
+
+            DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
+
+            String vmdkName = volume.getName();
+            String vmdkFileBaseName;
+            if (srcStore == null) {
+                // create a root volume for blank VM (created from ISO)
+                String dummyVmName = hostService.getWorkerName(context, cmd, 0);
+
+                try {
+                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
+                    if (vmMo == null) {
+                        throw new Exception("Unable to create a dummy VM for volume creation");
+                    }
+
+                    vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
+                    // we only use the first file in the pair, linked or not will not matter
+                    String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
+                    String volumeDatastorePath = vmdkFilePair[0];
+                    synchronized (this) {
+                        s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
+                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo, searchExcludedFolders);
+                        vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, -1);
+                        vmMo.detachDisk(volumeDatastorePath, false);
+                    }
+                } finally {
+                    s_logger.info("Destroy dummy VM after volume creation");
+                    if (vmMo != null) {
+                        s_logger.warn("Unable to destroy a null VM ManagedObjectReference");
+                        vmMo.detachAllDisks();
+                        vmMo.destroy();
+                    }
+                }
+            } else {
+                String templatePath = template.getPath();
+                VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true);
+                if (vmTemplate == null) {
+                    s_logger.warn("Template host in vSphere is not in connected state, request template reload");
+                    return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload");
+                }
+
+                ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
+                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+                if (template.getSize() != null){
+                    _fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
+                }
+                if (!_fullCloneFlag) {
+                    createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool);
+                } else {
+                    createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
+                }
+
+                vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName);
+                assert (vmMo != null);
+
+                vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
+                s_logger.info("Move volume out of volume-wrapper VM " + vmdkFileBaseName);
+                String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag);
+                String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
+
+                dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
+                dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
+
+                s_logger.info("detach disks from volume-wrapper VM " + vmdkName);
+                vmMo.detachAllDisks();
+
+                s_logger.info("destroy volume-wrapper VM " + vmdkName);
+                vmMo.destroy();
+
+                String srcFile = dsMo.getDatastorePath(vmdkName, true);
+
+                dsMo.deleteFile(srcFile, dcMo.getMor(), true, searchExcludedFolders);
+
+                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) {
+                    dsMo.deleteFolder(srcFile, dcMo.getMor());
+                }
+            }
+            // restoreVM - move the new ROOT disk into corresponding VM folder
+            VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
+            if (restoreVmMo != null) {
+                String vmNameInVcenter = restoreVmMo.getName(); // VM folder name in datastore will be VM's name in vCenter.
+                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
+                    VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName, searchExcludedFolders);
+                }
+            }
+
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(vmdkFileBaseName);
+            if (template.getSize() != null){
+                newVol.setSize(template.getSize());
+            }
+            else {
+                newVol.setSize(volume.getSize());
+            }
+            return new CopyCmdAnswer(newVol);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                hostService.invalidateServiceContext(null);
+            }
+
+            String msg = "clone volume from base image failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl,
+                                                          long wait, Integer nfsVersion) throws Exception {
+        String volumeFolder;
+        String volumeName;
+        String sufix = ".ova";
+        int index = srcVolumePath.lastIndexOf(File.separator);
+        if (srcVolumePath.endsWith(sufix)) {
+            volumeFolder = srcVolumePath.substring(0, index);
+            volumeName = srcVolumePath.substring(index + 1).replace(sufix, "");
+        } else {
+            volumeFolder = srcVolumePath;
+            volumeName = srcVolumePath.substring(index + 1);
+        }
+
+        String newVolume = VmwareHelper.getVCenterSafeUuid();
+        restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion);
+
+        return new Pair<>(volumeFolder, newVolume);
+    }
+
+    private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl, Integer nfsVersion) throws Exception {
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
+        String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir;
+
+        return deleteDir(volumeMountRoot);
+    }
+
+    private String deleteDir(String dir) {
+        synchronized (dir.intern()) {
+            Script command = new Script(false, "rm", _timeout, s_logger);
+            command.add("-rf");
+            command.add(dir);
+            return command.execute();
+        }
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+        VmwareContext context = hostService.getServiceContext(cmd);
+        try {
+
+            NfsTO srcStore = (NfsTO)srcVolume.getDataStore();
+            DataStoreTO destStore = destVolume.getDataStore();
+
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+            String uuid = destStore.getUuid();
+
+            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, uuid);
+            if (morDatastore == null) {
+                URI uri = new URI(destStore.getUrl());
+
+                morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), destStore.getUuid().replace("-", ""));
+
+                if (morDatastore == null) {
+                    throw new Exception("Unable to mount storage pool on host. storeUrl: " + uri.getHost() + ":/" + uri.getPath());
+                }
+            }
+
+            Pair<String, String> result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000, _nfsVersion);
+            deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl(), _nfsVersion);
+            VolumeObjectTO newVolume = new VolumeObjectTO();
+            newVolume.setPath(result.second());
+            return new CopyCmdAnswer(newVolume);
+        } catch (Throwable t) {
+            if (t instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            String msg = "Unable to execute CopyVolumeCommand due to exception";
+            s_logger.error(msg, t);
+            return new CopyCmdAnswer("copy volume secondary to primary failed due to exception: " + VmwareHelper.getExceptionMessage(t));
+        }
+
+    }
+
+    private String getVolumePathInDatastore(DatastoreMO dsMo, String volumeFileName, String searchExcludedFolders) throws Exception {
+        String datastoreVolumePath = dsMo.searchFileInSubFolders(volumeFileName, true, searchExcludedFolders);
+        assert (datastoreVolumePath != null) : "Virtual disk file missing from datastore.";
+        return datastoreVolumePath;
+    }
+
+    private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyCommand cmd, String vmName, String poolId,
+                                                        String volumePath, String destVolumePath, String secStorageUrl, String workerVmName) throws Exception {
+        VirtualMachineMO workerVm = null;
+        VirtualMachineMO vmMo = null;
+        String exportName = UUID.randomUUID().toString().replace("-", "");
+        String searchExcludedFolders = cmd.getContextParam("searchexludefolders");
+
+        try {
+            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
+
+            if (morDs == null) {
+                String msg = "Unable to find volumes's storage pool for copy volume operation";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            vmMo = hyperHost.findVmOnHyperHost(vmName);
+            if (vmMo == null || VmwareResource.getVmState(vmMo) == PowerState.PowerOff) {
+                // create a dummy worker vm for attaching the volume
+                DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
+                workerVm = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName);
+
+                if (workerVm == null) {
+                    String msg = "Unable to create worker VM to execute CopyVolumeCommand";
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+
+                // attach volume to worker VM
+                String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk", searchExcludedFolders);
+                workerVm.attachDisk(new String[] {datastoreVolumePath}, morDs);
+                vmMo = workerVm;
+            }
+
+            vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
+
+            exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion);
+            return new Pair<>(destVolumePath, exportName);
+
+        } finally {
+            vmMo.removeSnapshot(exportName, false);
+            if (workerVm != null) {
+                //detach volume and destroy worker vm
+                workerVm.detachAllDisks();
+                workerVm.destroy();
+            }
+        }
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+        VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+        VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+        String vmName = srcVolume.getVmName();
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+        try {
+            DataStoreTO primaryStorage = srcVolume.getDataStore();
+            NfsTO destStore = (NfsTO)destVolume.getDataStore();
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+
+            Pair<String, String> result;
+
+            result =
+                    copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, primaryStorage.getUuid(), srcVolume.getPath(), destVolume.getPath(), destStore.getUrl(),
+                            hostService.getWorkerName(context, cmd, 0));
+            VolumeObjectTO newVolume = new VolumeObjectTO();
+            newVolume.setPath(result.first() + File.separator + result.second());
+            return new CopyCmdAnswer(newVolume);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            String msg = "Unable to execute CopyVolumeCommand due to exception";
+            s_logger.error(msg, e);
+            return new CopyCmdAnswer("copy volume from primary to secondary failed due to exception: " + VmwareHelper.getExceptionMessage(e));
+        }
+    }
+
+    private void postCreatePrivateTemplate(String installFullPath, long templateId, String templateName, long size, long virtualSize) throws Exception {
+
+        // TODO a bit ugly here
+        BufferedWriter out = null;
+        try {
+            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/template.properties"),"UTF-8"));
+            out.write("filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("description=");
+            out.newLine();
+            out.write("checksum=");
+            out.newLine();
+            out.write("hvm=false");
+            out.newLine();
+            out.write("size=" + size);
+            out.newLine();
+            out.write("ova=true");
+            out.newLine();
+            out.write("id=" + templateId);
+            out.newLine();
+            out.write("public=false");
+            out.newLine();
+            out.write("ova.filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("uniquename=" + templateName);
+            out.newLine();
+            out.write("ova.virtualsize=" + virtualSize);
+            out.newLine();
+            out.write("virtualsize=" + virtualSize);
+            out.newLine();
+            out.write("ova.size=" + size);
+            out.newLine();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
+                                                                 String secStorageUrl, String volumePath, String workerVmName, Integer nfsVersion) throws Exception {
+
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
+        String installFullPath = secondaryMountPoint + "/" + installPath;
+        synchronized (installPath.intern()) {
+            Script command = new Script(false, "mkdir", _timeout, s_logger);
+            command.add("-p");
+            command.add(installFullPath);
+
+            String result = command.execute();
+            if (result != null) {
+                String msg = "unable to prepare template directory: " + installPath + ", storage: " + secStorageUrl + ", error msg: " + result;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+        }
+
+        VirtualMachineMO clonedVm = null;
+        try {
+            Pair<VirtualDisk, String> volumeDeviceInfo = vmMo.getDiskDevice(volumePath);
+            if (volumeDeviceInfo == null) {
+                String msg = "Unable to find related disk device for volume. volume path: " + volumePath;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            if (!vmMo.createSnapshot(templateUniqueName, "Temporary snapshot for template creation", false, false)) {
+                String msg = "Unable to take snapshot for creating template from volume. volume path: " + volumePath;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            // 4 MB is the minimum requirement for VM memory in VMware
+            Pair<VirtualMachineMO, String[]> cloneResult =
+                    vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
+            clonedVm = cloneResult.first();
+
+            clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false);
+
+            // Get VMDK filename
+            String templateVMDKName = "";
+            File[] files = new File(installFullPath).listFiles();
+            if(files != null) {
+                for(File file : files) {
+                    String fileName = file.getName();
+                    if(fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
+                        templateVMDKName += fileName;
+                        break;
+                    }
+                }
+            }
+
+            long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
+            OVAProcessor processor = new OVAProcessor();
+
+            Map<String, Object> params = new HashMap<>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            processor.configure("OVA Processor", params);
+            long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
+
+            postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
+            writeMetaOvaForTemplate(installFullPath, templateUniqueName + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
+            return new Ternary<String, Long, Long>(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize);
+
+        } finally {
+            if (clonedVm != null) {
+                clonedVm.detachAllDisks();
+                clonedVm.destroy();
+            }
+
+            vmMo.removeSnapshot(templateUniqueName, false);
+        }
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(CopyCommand cmd) {
+        VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
+        DataStoreTO imageStore = template.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+        String secondaryStoragePoolURL = nfsImageStore.getUrl();
+        String volumePath = volume.getPath();
+
+        String details = null;
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+        try {
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName());
+            if (vmMo == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() +
+                            ", try within datacenter");
+                }
+                vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName());
+
+                if (vmMo == null) {
+                    // This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
+                    // Look for the VM in the datacenter.
+                    ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
+                    DatacenterMO dcMo = new DatacenterMO(context, dcMor);
+                    vmMo = dcMo.findVm(volume.getVmName());
+                }
+
+                if (vmMo == null) {
+                    String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+            }
+
+            Ternary<String, Long, Long> result =
+                    createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
+                            hostService.getWorkerName(context, cmd, 0), _nfsVersion);
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(result.first());
+            newTemplate.setFormat(ImageFormat.OVA);
+            newTemplate.setSize(result.third());
+            newTemplate.setPhysicalSize(result.second());
+            return new CopyCmdAnswer(newTemplate);
+
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            s_logger.error("Unexpecpted exception ", e);
+
+            details = "create template from volume exception: " + VmwareHelper.getExceptionMessage(e);
+            return new CopyCmdAnswer(details);
+        }
+    }
+
+    private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename, String templateName, long diskSize) throws Exception {
+
+        // TODO a bit ugly here
+        BufferedWriter out = null;
+        try {
+            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName + ".ova.meta"),"UTF-8"));
+            out.write("ova.filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("version=1.0");
+            out.newLine();
+            out.write("ovf=" + ovfFilename);
+            out.newLine();
+            out.write("numDisks=1");
+            out.newLine();
+            out.write("disk1.name=" + vmdkFilename);
+            out.newLine();
+            out.write("disk1.size=" + diskSize);
+            out.newLine();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    private Ternary<String, Long, Long> createTemplateFromSnapshot(String installPath, String templateUniqueName, String secStorageUrl, String snapshotPath,
+                                                                   Long templateId, long wait, Integer nfsVersion) throws Exception {
+        //Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid
+        String backupSSUuid;
+        String snapshotFolder;
+        if (snapshotPath.endsWith(".ova")) {
+            int index = snapshotPath.lastIndexOf(File.separator);
+            backupSSUuid = snapshotPath.substring(index + 1).replace(".ova", "");
+            snapshotFolder = snapshotPath.substring(0, index);
+        } else {
+            String[] tokens = snapshotPath.split(File.separatorChar == '\\' ? "\\\\" : File.separator);
+            backupSSUuid = tokens[tokens.length - 1];
+            snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1);
+        }
+
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
+        String installFullPath = secondaryMountPoint + "/" + installPath;
+        String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova";  //Note: volss for tmpl
+        String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder;
+        String snapshotFullOVAName = snapshotRoot + "/" + backupSSUuid + ".ova";
+        String snapshotFullOvfName = snapshotRoot + "/" + backupSSUuid + ".ovf";
+        String result;
+        Script command;
+        String templateVMDKName = "";
+        String snapshotFullVMDKName = snapshotRoot + "/" + backupSSUuid + "/";
+
+        synchronized (installPath.intern()) {
+            command = new Script(false, "mkdir", _timeout, s_logger);
+            command.add("-p");
+            command.add(installFullPath);
+
+            result = command.execute();
+            if (result != null) {
+                String msg = "unable to prepare template directory: " + installPath + ", storage: " + secStorageUrl + ", error msg: " + result;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+        }
+
+        try {
+            if (new File(snapshotFullOVAName).exists()) {
+                command = new Script(false, "cp", wait, s_logger);
+                command.add(snapshotFullOVAName);
+                command.add(installFullOVAName);
+                result = command.execute();
+                if (result != null) {
+                    String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath;
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+
+                // untar OVA file at template directory
+                command = new Script("tar", wait, s_logger);
+                command.add("--no-same-owner");
+                command.add("-xf", installFullOVAName);
+                command.setWorkDir(installFullPath);
+                s_logger.info("Executing command: " + command.toString());
+                result = command.execute();
+                if (result != null) {
+                    String msg = "unable to untar snapshot " + snapshotFullOVAName + " to " + installFullPath;
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+
+            } else {  // there is no ova file, only ovf originally;
+                if (new File(snapshotFullOvfName).exists()) {
+                    command = new Script(false, "cp", wait, s_logger);
+                    command.add(snapshotFullOvfName);
+                    //command.add(installFullOvfName);
+                    command.add(installFullPath);
+                    result = command.execute();
+                    if (result != null) {
+                        String msg = "unable to copy snapshot " + snapshotFullOvfName + " to " + installFullPath;
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+
+                    s_logger.info("vmdkfile parent dir: " + snapshotRoot);
+                    File snapshotdir = new File(snapshotRoot);
+                    File[] ssfiles = snapshotdir.listFiles();
+                    if (ssfiles == null) {
+                        String msg = "unable to find snapshot vmdk files in " + snapshotRoot;
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+                    // List<String> filenames = new ArrayList<String>();
+                    for (int i = 0; i < ssfiles.length; i++) {
+                        String vmdkfile = ssfiles[i].getName();
+                        s_logger.info("vmdk file name: " + vmdkfile);
+                        if (vmdkfile.toLowerCase().startsWith(backupSSUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) {
+                            snapshotFullVMDKName = snapshotRoot + File.separator + vmdkfile;
+                            templateVMDKName += vmdkfile;
+                            break;
+                        }
+                    }
+                    if (snapshotFullVMDKName != null) {
+                        command = new Script(false, "cp", wait, s_logger);
+                        command.add(snapshotFullVMDKName);
+                        command.add(installFullPath);
+                        result = command.execute();
+                        s_logger.info("Copy VMDK file: " + snapshotFullVMDKName);
+                        if (result != null) {
+                            String msg = "unable to copy snapshot vmdk file " + snapshotFullVMDKName + " to " + installFullPath;
+                            s_logger.error(msg);
+                            throw new Exception(msg);
+                        }
+                    }
+                } else {
+                    String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath;
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+            }
+
+            Size size = handleMetadataCreateTemplateFromSnapshot(installFullPath, templateVMDKName, templateId, templateUniqueName, backupSSUuid);
+
+            return new Ternary<>(installPath + "/" + templateUniqueName + ".ova", size.getPhysicalSize(), size.getVirtualSize());
+        } finally {
+            // TODO, clean up left over files
+        }
+    }
+
+    private class Size {
+        private final long _physicalSize;
+        private final long _virtualSize;
+
+        Size(long physicalSize, long virtualSize) {
+            _physicalSize = physicalSize;
+            _virtualSize = virtualSize;
+        }
+
+        long getPhysicalSize() {
+            return _physicalSize;
+        }
+
+        long getVirtualSize() {
+            return _virtualSize;
+        }
+    }
+
+    private Size handleMetadataCreateTemplateFromSnapshot(String installFullPath, String templateVMDKName, long templateId, String templateUniqueName,
+                                                          String ovfFilename) throws Exception {
+        long physicalSize = new File(installFullPath + "/" + templateVMDKName).length();
+
+        OVAProcessor processor = new OVAProcessor();
+
+        Map<String, Object> params = new HashMap<>();
+
+        params.put(StorageLayer.InstanceConfigKey, _storage);
+
+        processor.configure("OVA Processor", params);
+
+        long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName);
+
+        postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize);
+
+        writeMetaOvaForTemplate(installFullPath, ovfFilename + ".ovf", templateVMDKName, templateUniqueName, physicalSize);
+
+        return new Size(physicalSize, virtualSize);
+    }
+
+    private void setUpManagedStorageCopyTemplateFromSnapshot(CopyCommand cmd) throws Exception {
+        VmwareContext context = hostService.getServiceContext(cmd);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO clusterMO = new ClusterMO(context, morCluster);
+
+        List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
+
+        final Map<String, String> options = cmd.getOptions();
+
+        final String storageHost = options.get(DiskTO.STORAGE_HOST);
+        final int storagePortNumber = Integer.parseInt(options.get(DiskTO.STORAGE_PORT));
+        final String iScsiName = options.get(DiskTO.IQN);
+        final String snapshotPath = options.get(DiskTO.VMDK);
+        final String chapInitiatorUsername = options.get(DiskTO.CHAP_INITIATOR_USERNAME);
+        final String chapInitiatorSecret = options.get(DiskTO.CHAP_INITIATOR_SECRET);
+        final String chapTargetUsername = options.get(DiskTO.CHAP_TARGET_USERNAME);
+        final String chapTargetSecret = options.get(DiskTO.CHAP_TARGET_SECRET);
+
+        String datastoreName = getManagedDatastoreNameFromPath(snapshotPath);
+
+        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
+        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+            final List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
+                    chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+
+            addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
+        }
+
+        rescanAllHosts(context, lstHosts, true, true);
+
+        Pair<ManagedObjectReference, String> firstHost = lstHosts.get(0);
+        HostMO firstHostMO = new HostMO(context, firstHost.first());
+        HostDatastoreSystemMO firstHostDatastoreSystemMO = firstHostMO.getHostDatastoreSystemMO();
+        ManagedObjectReference morDs = firstHostDatastoreSystemMO.findDatastoreByName(datastoreName);
+        DatastoreMO datastoreMO = new DatastoreMO(context, morDs);
+
+        mountVmfsDatastore(datastoreMO, lstHosts);
+    }
+
+    private void takeDownManagedStorageCopyTemplateFromSnapshot(CopyCommand cmd) throws Exception {
+        VmwareContext context = hostService.getServiceContext(cmd);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO clusterMO = new ClusterMO(context, morCluster);
+
+        List<Pair<ManagedObjectReference, String>> lstHosts = clusterMO.getClusterHosts();
+
+        final Map<String, String> options = cmd.getOptions();
+
+        final String storageHost = options.get(DiskTO.STORAGE_HOST);
+        final int storagePortNumber = Integer.parseInt(options.get(DiskTO.STORAGE_PORT));
+        final String iScsiName = options.get(DiskTO.IQN);
+        final String snapshotPath = options.get(DiskTO.VMDK);
+
+        String datastoreName = getManagedDatastoreNameFromPath(snapshotPath);
+
+        unmountVmfsDatastore(context, hyperHost, datastoreName, lstHosts);
+
+        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageHost, lstHosts);
+        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+            final List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageHost, storagePortNumber, trimIqn(iScsiName),
+                    null, null, null, null);
+
+            addRemoveInternetScsiTargetsToAllHosts(false, lstTargets, hostsUsingStaticDiscovery);
+
+            rescanAllHosts(context, lstHosts, true, false);
+        }
+    }
+
+    private void createTemplateFolder(String installPath, String installFullPath, NfsTO nfsSvr) {
+        synchronized (installPath.intern()) {
+            Script command = new Script(false, "mkdir", _timeout, s_logger);
+
+            command.add("-p");
+            command.add(installFullPath);
+
+            String result = command.execute();
+
+            if (result != null) {
+                String secStorageUrl = nfsSvr.getUrl();
+                String msg = "unable to prepare template directory: " + installPath + "; storage: " + secStorageUrl + "; error msg: " + result;
+
+                s_logger.error(msg);
+
+                throw new CloudRuntimeException(msg);
+            }
+        }
+    }
+
+    private void exportManagedStorageSnapshotToTemplate(CopyCommand cmd, String installFullPath, String snapshotPath, String exportName) throws Exception {
+        DatastoreFile dsFile = new DatastoreFile(snapshotPath);
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+
+        String workerVMName = hostService.getWorkerName(context, cmd, 0);
+
+        ManagedObjectReference dsMor = hyperHost.findDatastoreByName(dsFile.getDatastoreName());
+        DatastoreMO dsMo = new DatastoreMO(context, dsMor);
+
+        VirtualMachineMO workerVM = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
+
+        if (workerVM == null) {
+            throw new CloudRuntimeException("Failed to find the newly created worker VM: " + workerVMName);
+        }
+
+        workerVM.attachDisk(new String[]{snapshotPath}, dsMor);
+
+        workerVM.exportVm(installFullPath, exportName, false, false);
+
+        workerVM.detachAllDisks();
+        workerVM.destroy();
+    }
+
+    private String getTemplateVmdkName(String installFullPath, String exportName) {
+        File templateDir = new File(installFullPath);
+        File[] templateFiles = templateDir.listFiles();
+
+        if (templateFiles == null) {
+            String msg = "Unable to find template files in " + installFullPath;
+
+            s_logger.error(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        for (int i = 0; i < templateFiles.length; i++) {
+            String templateFile = templateFiles[i].getName();
+
+            if (templateFile.toLowerCase().startsWith(exportName) && templateFile.toLowerCase().endsWith(".vmdk")) {
+                return templateFile;
+            }
+        }
+
+        throw new CloudRuntimeException("Unable to locate the template VMDK file");
+    }
+
+    private Answer handleManagedStorageCreateTemplateFromSnapshot(CopyCommand cmd, TemplateObjectTO template, NfsTO nfsSvr) {
+        try {
+            setUpManagedStorageCopyTemplateFromSnapshot(cmd);
+
+            final Map<String, String> options = cmd.getOptions();
+
+            String snapshotPath = options.get(DiskTO.VMDK);
+
+            String secondaryMountPoint = mountService.getMountPoint(nfsSvr.getUrl(), _nfsVersion);
+            String installPath = template.getPath();
+            String installFullPath = secondaryMountPoint + "/" + installPath;
+
+            createTemplateFolder(installPath, installFullPath, nfsSvr);
+
+            String exportName = UUID.randomUUID().toString();
+
+            exportManagedStorageSnapshotToTemplate(cmd, installFullPath, snapshotPath, exportName);
+
+            String templateVmdkName = getTemplateVmdkName(installFullPath, exportName);
+
+            String uniqueName = options.get(DiskTO.UUID);
+
+            Size size = handleMetadataCreateTemplateFromSnapshot(installFullPath, templateVmdkName, template.getId(), uniqueName, exportName);
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(installPath + "/" + uniqueName + ".ova");
+            newTemplate.setPhysicalSize(size.getPhysicalSize());
+            newTemplate.setSize(size.getVirtualSize());
+            newTemplate.setFormat(ImageFormat.OVA);
+            newTemplate.setName(uniqueName);
+
+            return new CopyCmdAnswer(newTemplate);
+        }
+        catch (Exception ex) {
+            String errMsg = "Problem creating a template from a snapshot for managed storage: " + ex.getMessage();
+
+            s_logger.error(errMsg);
+
+            throw new CloudRuntimeException(errMsg, ex);
+        }
+        finally {
+            try {
+                takeDownManagedStorageCopyTemplateFromSnapshot(cmd);
+            }
+            catch (Exception ex) {
+                s_logger.warn("Unable to remove one or more static targets");
+            }
+        }
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        String details;
+
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getSrcTO();
+        TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
+
+        DataStoreTO imageStore = template.getDataStore();
+
+        String uniqueName = UUID.randomUUID().toString();
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+
+        try {
+            if (!(imageStore instanceof NfsTO)) {
+                return new CopyCmdAnswer("Creating a template from a snapshot is only supported when the destination store is NFS.");
+            }
+
+            NfsTO nfsSvr = (NfsTO)imageStore;
+
+            if (snapshot.getDataStore() instanceof PrimaryDataStoreTO && template.getDataStore() instanceof NfsTO) {
+                return handleManagedStorageCreateTemplateFromSnapshot(cmd, template, nfsSvr);
+            }
+
+            Ternary<String, Long, Long> result = createTemplateFromSnapshot(template.getPath(), uniqueName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(),
+                    cmd.getWait() * 1000, _nfsVersion);
+
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(result.first());
+            newTemplate.setPhysicalSize(result.second());
+            newTemplate.setSize(result.third());
+            newTemplate.setFormat(ImageFormat.OVA);
+            newTemplate.setName(uniqueName);
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            s_logger.error("Unexpected exception ", e);
+
+            details = "create template from snapshot exception: " + VmwareHelper.getExceptionMessage(e);
+
+            return new CopyCmdAnswer(details);
+        }
+    }
+
+    // return Pair<String(divice bus name), String[](disk chain)>
+    private Pair<String, String[]> exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
+                                                                  String exportName, String workerVmName, Integer nfsVersion) throws Exception {
+
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
+        String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
+
+        synchronized (exportPath.intern()) {
+            if (!new File(exportPath).exists()) {
+                Script command = new Script(false, "mkdir", _timeout, s_logger);
+                command.add("-p");
+                command.add(exportPath);
+                if (command.execute() != null) {
+                    throw new Exception("unable to prepare snapshot backup directory");
+                }
+            }
+        }
+
+        VirtualMachineMO clonedVm = null;
+        try {
+
+            Pair<VirtualDisk, String> volumeDeviceInfo = vmMo.getDiskDevice(volumePath);
+            if (volumeDeviceInfo == null) {
+                String msg = "Unable to find related disk device for volume. volume path: " + volumePath;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            // 4 MB is the minimum requirement for VM memory in VMware
+            Pair<VirtualMachineMO, String[]> cloneResult =
+                    vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
+            clonedVm = cloneResult.first();
+            String disks[] = cloneResult.second();
+
+            clonedVm.exportVm(exportPath, exportName, false, false);
+            return new Pair<>(volumeDeviceInfo.second(), disks);
+        } finally {
+            if (clonedVm != null) {
+                clonedVm.detachAllDisks();
+                clonedVm.destroy();
+            }
+        }
+    }
+
+    // Ternary<String(backup uuid in secondary storage), String(device bus name), String[](original disk chain in the snapshot)>
+    private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid,
+                                                                               String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName,
+                                                                               Integer nfsVersion) throws Exception {
+
+        String backupUuid = UUID.randomUUID().toString();
+        Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion);
+        return new Ternary<>(backupUuid, snapshotInfo.first(), snapshotInfo.second());
+    }
+
+    @Override
+    public Answer backupSnapshot(CopyCommand cmd) {
+        SnapshotObjectTO srcSnapshot = (SnapshotObjectTO)cmd.getSrcTO();
+        DataStoreTO primaryStore = srcSnapshot.getDataStore();
+        SnapshotObjectTO destSnapshot = (SnapshotObjectTO)cmd.getDestTO();
+        DataStoreTO destStore = destSnapshot.getDataStore();
+        if (!(destStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO destNfsStore = (NfsTO)destStore;
+
+        String secondaryStorageUrl = destNfsStore.getUrl();
+        String snapshotUuid = srcSnapshot.getPath();
+        String prevSnapshotUuid = srcSnapshot.getParentSnapshotPath();
+        String prevBackupUuid = destSnapshot.getParentSnapshotPath();
+        VirtualMachineMO workerVm = null;
+        String workerVMName = null;
+        String volumePath = srcSnapshot.getVolume().getPath();
+        ManagedObjectReference morDs;
+        DatastoreMO dsMo;
+
+        // By default assume failure
+        String details;
+        boolean success;
+        String snapshotBackupUuid;
+
+        boolean hasOwnerVm = false;
+        Ternary<String, String, String[]> backupResult = null;
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+        VirtualMachineMO vmMo = null;
+        String vmName = srcSnapshot.getVmName();
+        try {
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+            morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
+
+            CopyCmdAnswer answer = null;
+
+            try {
+                if(vmName != null) {
+                    vmMo = hyperHost.findVmOnHyperHost(vmName);
+                    if (vmMo == null) {
+                        if(s_logger.isDebugEnabled()) {
+                            s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
+                        }
+                        vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+                    }
+                }
+                if(vmMo == null) {
+                    dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
+                    workerVMName = hostService.getWorkerName(context, cmd, 0);
+                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
+                    if (vmMo == null) {
+                        throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
+                    }
+                    workerVm = vmMo;
+                    // attach volume to worker VM
+                    String datastoreVolumePath = dsMo.getDatastorePath(volumePath + ".vmdk");
+                    vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
+                } else {
+                    s_logger.info("Using owner VM " + vmName + " for snapshot operation");
+                    hasOwnerVm = true;
+                }
+
+                if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) {
+                    throw new Exception("Failed to take snapshot " + srcSnapshot.getName() + " on vm: " + vmName);
+                }
+
+                backupResult =
+                        backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
+                                prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
+                snapshotBackupUuid = backupResult.first();
+
+                success = (snapshotBackupUuid != null);
+                if (!success) {
+                    details = "Failed to backUp the snapshot with uuid: " + snapshotUuid + " to secondary storage.";
+                    answer = new CopyCmdAnswer(details);
+                } else {
+                    details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage.";
+
+                    // Get snapshot physical size
+                    long physicalSize = 0;
+                    String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
+                    String snapshotDir =  destSnapshot.getPath() + "/" + snapshotBackupUuid;
+                    File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
+                    if(files != null) {
+                        for(File file : files) {
+                            String fileName = file.getName();
+                            if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
+                                physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
+                                break;
+                            }
+                        }
+                    }
+
+                    SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+                    newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid);
+                    newSnapshot.setPhysicalSize(physicalSize);
+                    answer = new CopyCmdAnswer(newSnapshot);
+                }
+            } finally {
+                if (vmMo != null) {
+                    ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid);
+                    if (snapshotMor != null) {
+                        vmMo.removeSnapshot(snapshotUuid, false);
+
+                        // Snapshot operation may cause disk consolidation in VMware, when this happens
+                        // we need to update CloudStack DB
+                        //
+                        // TODO: this post operation fixup is not atomic and not safe when management server stops
+                        // in the middle
+                        if (backupResult != null && hasOwnerVm) {
+                            s_logger.info("Check if we have disk consolidation after snapshot operation");
+
+                            boolean chainConsolidated = false;
+                            for (String vmdkDsFilePath : backupResult.third()) {
+                                s_logger.info("Validate disk chain file:" + vmdkDsFilePath);
+
+                                if (vmMo.getDiskDevice(vmdkDsFilePath) == null) {
+                                    s_logger.info("" + vmdkDsFilePath + " no longer exists, consolidation detected");
+                                    chainConsolidated = true;
+                                    break;
+                                } else {
+                                    s_logger.info("" + vmdkDsFilePath + " is found still in chain");
+                                }
+                            }
+
+                            if (chainConsolidated) {
+                                String topVmdkFilePath = null;
+                                try {
+                                    topVmdkFilePath = vmMo.getDiskCurrentTopBackingFileInChain(backupResult.second());
+                                } catch (Exception e) {
+                                    s_logger.error("Unexpected exception", e);
+                                }
+
+                                s_logger.info("Disk has been consolidated, top VMDK is now: " + topVmdkFilePath);
+                                if (topVmdkFilePath != null) {
+                                    DatastoreFile file = new DatastoreFile(topVmdkFilePath);
+
+                                    SnapshotObjectTO snapshotInfo = (SnapshotObjectTO)answer.getNewData();
+                                    VolumeObjectTO vol = new VolumeObjectTO();
+                                    vol.setUuid(srcSnapshot.getVolume().getUuid());
+                                    vol.setPath(file.getFileBaseName());
+                                    snapshotInfo.setVolume(vol);
+                                } else {
+                                    s_logger.error("Disk has been consolidated, but top VMDK is not found ?!");
+                                }
+                            }
+                        }
+                    } else {
+                        s_logger.error("Can not find the snapshot we just used ?!");
+                    }
+                }
+
+                try {
+                    if (workerVm != null) {
+                        // detach volume and destroy worker vm
+                        workerVm.detachAllDisks();
+                        workerVm.destroy();
+                    }
+                } catch (Throwable e) {
+                    s_logger.warn("Failed to destroy worker VM: " + workerVMName);
+                }
+            }
+
+            return answer;
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            s_logger.error("Unexpecpted exception ", e);
+
+            details = "backup snapshot exception: " + VmwareHelper.getExceptionMessage(e);
+            return new CopyCmdAnswer(details);
+        }
+    }
+
+    @Override
+    public Answer attachIso(AttachCommand cmd) {
+        return this.attachIso(cmd.getDisk(), true, cmd.getVmName());
+    }
+
+    @Override
+    public Answer attachVolume(AttachCommand cmd) {
+        Map<String, String> details = cmd.getDisk().getDetails();
+        boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+        String iScsiName = details.get(DiskTO.IQN);
+        String storageHost = details.get(DiskTO.STORAGE_HOST);
+        int storagePort = Integer.parseInt(details.get(DiskTO.STORAGE_PORT));
+
+        return this.attachVolume(cmd, cmd.getDisk(), true, isManaged, cmd.getVmName(), iScsiName, storageHost, storagePort, cmd.getControllerInfo());
+    }
+
+    private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean isManaged, String vmName, String iScsiName,
+                                String storageHost, int storagePort, Map<String, String> controllerInfo) {
+        VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData();
+        DataStoreTO primaryStore = volumeTO.getDataStore();
+
+        String vmdkPath = isManaged ? resource.getVmdkPath(volumeTO.getPath()) : null;
+
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+
+            if (vmMo == null) {
+                vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
+
+                if (vmMo == null) {
+                    String msg = "Unable to find the VM to execute AttachCommand, vmName: " + vmName;
+
+                    s_logger.error(msg);
+
+                    throw new Exception(msg);
+                }
+            }
+
+            vmName = vmMo.getName();
+
+            ManagedObjectReference morDs;
+            String diskUuid =  volumeTO.getUuid().replace("-", "");
+
+            if (isAttach && isManaged) {
+                Map<String, String> details = disk.getDetails();
+
+                morDs = prepareManagedStorage(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort, vmdkPath,
+                            details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
+                            details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
+                            volumeTO.getSize(), cmd);
+            }
+            else {
+                if (storagePort == DEFAULT_NFS_PORT) {
+                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(diskUuid) : primaryStore.getUuid());
+                } else {
+                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
+                }
+            }
+
+            if (morDs == null) {
+                String msg = "Unable to find the mounted datastore to execute AttachCommand, vmName: " + vmName;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            DatastoreMO dsMo = new DatastoreMO(context, morDs);
+            String datastoreVolumePath;
+
+            if (isAttach) {
+                if (isManaged) {
+                    datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
+                } else {
+                    datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName, dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
+                }
+            } else {
+                if (isManaged) {
+                    datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
+                } else {
+                    datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
+
+                    if (!dsMo.fileExists(datastoreVolumePath)) {
+                        datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
+                    }
+                }
+            }
+
+            disk.setPath(datastoreVolumePath);
+
+            AttachAnswer answer = new AttachAnswer(disk);
+
+            if (isAttach) {
+                String diskController = getLegacyVmDataDiskController();
+
+                if (controllerInfo != null && !Strings.isNullOrEmpty(controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER))) {
+                    diskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
+                }
+
+                if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
+                    diskController = vmMo.getRecommendedDiskController(null);
+                }
+
+                vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController);
+
+                if (isManaged) {
+                    expandVirtualDisk(vmMo, datastoreVolumePath, volumeTO.getSize());
+                }
+            } else {
+                vmMo.removeAllSnapshots();
+                vmMo.detachDisk(datastoreVolumePath, false);
+
+                if (isManaged) {
+                    handleDatastoreAndVmdkDetachManaged(cmd, diskUuid, iScsiName, storageHost, storagePort);
+                } else {
+                    VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath(), vmName, VmwareManager.s_vmwareSearchExcludeFolder.value());
+                }
+            }
+
+            return answer;
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+
+                hostService.invalidateServiceContext(null);
+            }
+
+            String msg = "";
+
+            if (isAttach) {
+                msg += "Failed to attach volume: " + e.getMessage();
+            }
+            else {
+                msg += "Failed to detach volume: " + e.getMessage();
+            }
+
+            s_logger.error(msg, e);
+
+            return new AttachAnswer(msg);
+        }
+    }
+
+    private boolean expandVirtualDisk(VirtualMachineMO vmMo, String datastoreVolumePath, long currentSizeInBytes) throws Exception {
+        long currentSizeInKB = currentSizeInBytes / 1024;
+
+        Pair<VirtualDisk, String> vDiskPair = vmMo.getDiskDevice(datastoreVolumePath);
+
+        VirtualDisk vDisk = vDiskPair.first();
+
+        if (vDisk.getCapacityInKB() < currentSizeInKB) {
+            // IDE virtual disk cannot be re-sized if VM is running
+            if (vDiskPair.second() != null && vDiskPair.second().contains("ide")) {
+                throw new Exception("Re-sizing a virtual disk over an IDE controller is not supported in VMware hypervisor. " +
+                        "Please re-try when virtual disk is attached to a VM using a SCSI controller.");
+            }
+
+            String vmdkAbsFile = resource.getAbsoluteVmdkFile(vDisk);
+
+            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
+                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
+            }
+
+            vDisk.setCapacityInKB(currentSizeInKB);
+
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(vDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            if (!vmMo.configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to configure VM to resize disk. vmName: " + vmMo.getName());
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private static String getSecondaryDatastoreUUID(String storeUrl) {
+        String uuid = null;
+        try{
+            uuid=UUID.nameUUIDFromBytes(storeUrl.getBytes("UTF-8")).toString();
+        }catch(UnsupportedEncodingException e){
+            s_logger.warn("Failed to create UUID from string " + storeUrl + ". Bad storeUrl or UTF-8 encoding error." );
+        }
+        return uuid;
+    }
+
+    private synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception {
+        String storeName = getSecondaryDatastoreUUID(storeUrl);
+        URI uri = new URI(storeUrl);
+
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(hostService.getServiceContext(null), null);
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
+
+        if (morDatastore == null) {
+            throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
+        }
+
+        return morDatastore;
+    }
+
+    private Answer attachIso(DiskTO disk, boolean isAttach, String vmName) {
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
+            if (vmMo == null) {
+                String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + vmName;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+            TemplateObjectTO iso = (TemplateObjectTO)disk.getData();
+            NfsTO nfsImageStore = (NfsTO)iso.getDataStore();
+            String storeUrl = null;
+            if (nfsImageStore != null) {
+                storeUrl = nfsImageStore.getUrl();
+            }
+            if (storeUrl == null) {
+                if (!iso.getName().equalsIgnoreCase("vmware-tools.iso")) {
+                    String msg = "ISO store root url is not found in AttachIsoCommand";
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                } else {
+                    if (isAttach) {
+                        vmMo.mountToolsInstaller();
+                    } else {
+                        try{
+                            if (!vmMo.unmountToolsInstaller()) {
+                                return new AttachAnswer("Failed to unmount vmware-tools installer ISO as the corresponding CDROM device is locked by VM. Please unmount the CDROM device inside the VM and ret-try.");
+                            }
+                        } catch(Throwable e){
+                            vmMo.detachIso(null);
+                        }
+                    }
+
+                    return new AttachAnswer(disk);
+                }
+            }
+
+            ManagedObjectReference morSecondaryDs = prepareSecondaryDatastoreOnHost(storeUrl);
+            String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
+            if (!isoPath.startsWith(storeUrl)) {
+                assert (false);
+                String msg = "ISO path does not start with the secondary storage root";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            int isoNameStartPos = isoPath.lastIndexOf('/');
+            String isoFileName = isoPath.substring(isoNameStartPos + 1);
+            String isoStorePathFromRoot = isoPath.substring(storeUrl.length() + 1, isoNameStartPos);
+
+            // TODO, check if iso is already attached, or if there is a previous
+            // attachment
+            DatastoreMO secondaryDsMo = new DatastoreMO(context, morSecondaryDs);
+            String storeName = secondaryDsMo.getName();
+            String isoDatastorePath = String.format("[%s] %s/%s", storeName, isoStorePathFromRoot, isoFileName);
+
+            if (isAttach) {
+                vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false);
+            } else {
+                vmMo.detachIso(isoDatastorePath);
+            }
+
+            return new AttachAnswer(disk);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                hostService.invalidateServiceContext(null);
+            }
+
+            if (isAttach) {
+                String msg = "AttachIsoCommand(attach) failed due to " + VmwareHelper.getExceptionMessage(e);
+                msg = msg + " Also check if your guest os is a supported version";
+                s_logger.error(msg, e);
+                return new AttachAnswer(msg);
+            } else {
+                String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e);
+                msg = msg + " Also check if your guest os is a supported version";
+                s_logger.warn(msg, e);
+                return new AttachAnswer(msg);
+            }
+        }
+    }
+
+    @Override
+    public Answer dettachIso(DettachCommand cmd) {
+        return this.attachIso(cmd.getDisk(), false, cmd.getVmName());
+    }
+
+    @Override
+    public Answer dettachVolume(DettachCommand cmd) {
+        return this.attachVolume(cmd, cmd.getDisk(), false, cmd.isManaged(), cmd.getVmName(), cmd.get_iScsiName(), cmd.getStorageHost(), cmd.getStoragePort(), null);
+    }
+
+    @Override
+    public Answer createVolume(CreateObjectCommand cmd) {
+
+        VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
+        DataStoreTO primaryStore = volume.getDataStore();
+
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
+
+            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
+            if (morDatastore == null) {
+                throw new Exception("Unable to find datastore in vSphere");
+            }
+
+            DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
+            // create data volume
+            VirtualMachineMO vmMo = null;
+            String volumeUuid = UUID.randomUUID().toString().replace("-", "");
+
+            String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk");
+            String dummyVmName = hostService.getWorkerName(context, cmd, 0);
+            try {
+                s_logger.info("Create worker VM " + dummyVmName);
+                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
+                if (vmMo == null) {
+                    throw new Exception("Unable to create a dummy VM for volume creation");
+                }
+
+                synchronized (this) {
+                    try {
+                        vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey());
+                        vmMo.detachDisk(volumeDatastorePath, false);
+                    }
+                    catch (Exception e) {
+                        s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage());
+                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
+                        throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage());
+                    }
+                }
+
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(volumeUuid);
+                newVol.setSize(volume.getSize());
+                return new CreateObjectAnswer(newVol);
+            } finally {
+                s_logger.info("Destroy dummy VM after volume creation");
+                if (vmMo != null) {
+                    vmMo.detachAllDisks();
+                    vmMo.destroy();
+                }
+            }
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                hostService.invalidateServiceContext(null);
+            }
+
+            String msg = "create volume failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer createSnapshot(CreateObjectCommand cmd) {
+        // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake
+        // a success return here
+        String snapshotUUID = UUID.randomUUID().toString();
+        SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+        newSnapshot.setPath(snapshotUUID);
+        return new CreateObjectAnswer(newSnapshot);
+    }
+
+    // format: [datastore_name] file_name.vmdk (the '[' and ']' chars should only be used to denote the datastore)
+    private String getManagedDatastoreNameFromPath(String path) {
+        int lastIndexOf = path.lastIndexOf("]");
+
+        return path.substring(1, lastIndexOf);
+    }
+
+    @Override
+    public Answer deleteVolume(DeleteCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource DeleteCommand: " + _gson.toJson(cmd));
+        }
+
+        try {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            VolumeObjectTO vol = (VolumeObjectTO)cmd.getData();
+            DataStoreTO store = vol.getDataStore();
+            PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO)store;
+
+            Map<String, String> details = primaryDataStoreTO.getDetails();
+            boolean isManaged = false;
+            String managedDatastoreName = null;
+
+            if (details != null) {
+                isManaged = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
+
+                if (isManaged) {
+                    managedDatastoreName = getManagedDatastoreNameFromPath(vol.getPath());
+                }
+            }
+
+            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost,
+                    isManaged ? managedDatastoreName : store.getUuid());
+
+            if (morDs == null) {
+                String msg = "Unable to find datastore based on volume mount point " + store.getUuid();
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            DatastoreMO dsMo = new DatastoreMO(context, morDs);
+
+            ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
+            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+            ClusterMO clusterMo = new ClusterMO(context, morCluster);
+
+            if (vol.getVolumeType() == Volume.Type.ROOT) {
+
+                String vmName = vol.getVmName();
+                if (vmName != null) {
+                    VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName);
+                    if (vmMo == null) {
+                        // Volume might be on a zone-wide storage pool, look for VM in datacenter
+                        DatacenterMO dcMo = new DatacenterMO(context, morDc);
+                        vmMo = dcMo.findVm(vmName);
+                    }
+
+                    List<Map<String, String>> dynamicTargetsToRemove = null;
+
+                    if (vmMo != null) {
+                        if (s_logger.isInfoEnabled()) {
+                            s_logger.info("Destroy root volume and VM itself. vmName " + vmName);
+                        }
+
+                        VirtualMachineDiskInfo diskInfo = null;
+                        if (vol.getChainInfo() != null)
+                            diskInfo = _gson.fromJson(vol.getChainInfo(), VirtualMachineDiskInfo.class);
+
+                        HostMO hostMo = vmMo.getRunningHost();
+                        List<NetworkDetails> networks = vmMo.getNetworksWithDetails();
+
+                        // tear down all devices first before we destroy the VM to avoid accidently delete disk backing files
+                        if (VmwareResource.getVmState(vmMo) != PowerState.PowerOff) {
+                            vmMo.safePowerOff(_shutdownWaitMs);
+                        }
+
+                        // call this before calling detachAllDisksExcept
+                        // when expunging a VM, we need to see if any of its disks are serviced by managed storage
+                        // if there is one or more disk serviced by managed storage, remove the iSCSI connection(s)
+                        // don't remove the iSCSI connection(s) until the supported disk(s) is/are removed from the VM
+                        // (removeManagedTargetsFromCluster should be called after detachAllDisksExcept and vm.destroy)
+                        List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
+                        List<String> managedDatastoreNames = getManagedDatastoreNamesFromVirtualDisks(virtualDisks);
+
+                        List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
+                        VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
+
+                        // let vmMo.destroy to delete volume for us
+                        // vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
+
+                        if (isManaged) {
+                            vmMo.unregisterVm();
+                        }
+                        else {
+                            vmMo.destroy();
+                        }
+
+                        // this.hostService.handleDatastoreAndVmdkDetach(iScsiName, storageHost, storagePort);
+                        if (managedDatastoreNames != null && !managedDatastoreNames.isEmpty()) {
+                            removeManagedTargetsFromCluster(managedDatastoreNames);
+                        }
+
+                        for (NetworkDetails netDetails : networks) {
+                            if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) {
+                                if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) {
+                                    resource.cleanupNetwork(hostMo, netDetails);
+                                }
+                            }
+                        }
+                    }
+
+                    /*
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk");
+                    }
+
+                    VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc));
+                     */
+
+                    return new Answer(cmd, true, "");
+                }
+
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Destroy root volume directly from datastore");
+                }
+            }
+
+            if (!isManaged) {
+                VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vol.getPath(), new DatacenterMO(context, morDc), VmwareManager.s_vmwareSearchExcludeFolder.value());
+            }
+
+            return new Answer(cmd, true, "Success");
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+                hostService.invalidateServiceContext(null);
+            }
+
+            String msg = "delete volume failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+    }
+
+    public ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
+                                                          String iScsiName, String storageHost, int storagePort) throws Exception {
+        return getVmfsDatastore(context, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iScsiName), null, null, null, null);
+    }
+
+    private ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
+                                                           String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
+                                                           String chapTargetUsername, String chapTargetSecret) throws Exception {
+        if (storagePort == DEFAULT_NFS_PORT) {
+            s_logger.info("creating the NFS datastore with the following configuration - storageHost: " + storageHost + ", storagePort: " + storagePort +
+                    ", exportpath: " + iScsiName + "and diskUuid : " + diskUuid);
+            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+            ClusterMO cluster = new ClusterMO(context, morCluster);
+            List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+
+            HostMO host = new HostMO(context, lstHosts.get(0).first());
+            HostDatastoreSystemMO hostDatastoreSystem = host.getHostDatastoreSystemMO();
+
+            return hostDatastoreSystem.createNfsDatastore(storageHost, storagePort, iScsiName, diskUuid);
+        } else {
+            return getVmfsDatastore(context, hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
+                    trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+        }
+    }
+
+    private List<HostInternetScsiHbaStaticTarget> getTargets(String storageIpAddress, int storagePortNumber, String iqn,
+                                                             String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) {
+        HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
+
+        target.setAddress(storageIpAddress);
+        target.setPort(storagePortNumber);
+        target.setIScsiName(iqn);
+
+        if (StringUtils.isNotBlank(chapName) && StringUtils.isNotBlank(chapSecret)) {
+            HostInternetScsiHbaAuthenticationProperties auth = new HostInternetScsiHbaAuthenticationProperties();
+
+            String strAuthType = "chapRequired";
+
+            auth.setChapAuthEnabled(true);
+            auth.setChapInherited(false);
+            auth.setChapAuthenticationType(strAuthType);
+            auth.setChapName(chapName);
+            auth.setChapSecret(chapSecret);
+
+            if (StringUtils.isNotBlank(mutualChapName) && StringUtils.isNotBlank(mutualChapSecret)) {
+                auth.setMutualChapInherited(false);
+                auth.setMutualChapAuthenticationType(strAuthType);
+                auth.setMutualChapName(mutualChapName);
+                auth.setMutualChapSecret(mutualChapSecret);
+            }
+
+            target.setAuthenticationProperties(auth);
+        }
+
+        final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<>();
+
+        lstTargets.add(target);
+
+        return lstTargets;
+    }
+
+    private class HostDiscoveryMethod {
+        private final List<HostMO> hostsUsingDynamicDiscovery;
+        private final List<HostMO> hostsUsingStaticDiscovery;
+
+        HostDiscoveryMethod(List<HostMO> hostsUsingDynamicDiscovery, List<HostMO> hostsUsingStaticDiscovery) {
+            this.hostsUsingDynamicDiscovery = hostsUsingDynamicDiscovery;
+            this.hostsUsingStaticDiscovery = hostsUsingStaticDiscovery;
+        }
+
+        List<HostMO> getHostsUsingDynamicDiscovery() {
+            return hostsUsingDynamicDiscovery;
+        }
+
+        List<HostMO> getHostsUsingStaticDiscovery() {
+            return hostsUsingStaticDiscovery;
+        }
+    }
+
+    private HostDiscoveryMethod getHostDiscoveryMethod(VmwareContext context, String address,
+                                                       List<Pair<ManagedObjectReference, String>> hostPairs) throws Exception {
+        List<HostMO> hosts = new ArrayList<>();
+
+        for (Pair<ManagedObjectReference, String> hostPair : hostPairs) {
+            HostMO host = new HostMO(context, hostPair.first());
+
+            hosts.add(host);
+        }
+
+        return getHostDiscoveryMethod(address, hosts);
+    }
+
+    private HostDiscoveryMethod getHostDiscoveryMethod(String address, List<HostMO> lstHosts) throws Exception {
+        List<HostMO> hostsUsingDynamicDiscovery = new ArrayList<>();
+        List<HostMO> hostsUsingStaticDiscovery = new ArrayList<>();
+
+        for (HostMO host : lstHosts) {
+            boolean usingDynamicDiscovery = false;
+
+            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+                if (hba instanceof HostInternetScsiHba) {
+                    HostInternetScsiHba hostInternetScsiHba = (HostInternetScsiHba)hba;
+
+                    if (hostInternetScsiHba.isIsSoftwareBased()) {
+                        List<HostInternetScsiHbaSendTarget> sendTargets = hostInternetScsiHba.getConfiguredSendTarget();
+
+                        if (sendTargets != null) {
+                            for (HostInternetScsiHbaSendTarget sendTarget : sendTargets) {
+                                String sendTargetAddress = sendTarget.getAddress();
+
+                                if (sendTargetAddress.contains(address)) {
+                                    usingDynamicDiscovery = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (usingDynamicDiscovery) {
+                hostsUsingDynamicDiscovery.add(host);
+            }
+            else {
+                hostsUsingStaticDiscovery.add(host);
+            }
+        }
+
+        return new HostDiscoveryMethod(hostsUsingDynamicDiscovery, hostsUsingStaticDiscovery);
+    }
+
+    private ManagedObjectReference getVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
+                                                    String iqn, String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception {
+        ManagedObjectReference morDs;
+
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO cluster = new ClusterMO(context, morCluster);
+        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+
+        Pair<ManagedObjectReference, String> firstHost = lstHosts.get(0);
+        HostMO firstHostMO = new HostMO(context, firstHost.first());
+        HostDatastoreSystemMO firstHostDatastoreSystemMO = firstHostMO.getHostDatastoreSystemMO();
+
+        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageIpAddress, lstHosts);
+        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+            List<HostInternetScsiHbaStaticTarget> lstTargets = getTargets(storageIpAddress, storagePortNumber, iqn,
+                    chapName, chapSecret, mutualChapName, mutualChapSecret);
+
+            addRemoveInternetScsiTargetsToAllHosts(true, lstTargets, hostsUsingStaticDiscovery);
+        }
+
+        rescanAllHosts(context, lstHosts, true, false);
+
+        HostStorageSystemMO firstHostStorageSystem = firstHostMO.getHostStorageSystemMO();
+        List<HostScsiDisk> lstHostScsiDisks = firstHostDatastoreSystemMO.queryAvailableDisksForVmfs();
+
+        HostScsiDisk hostScsiDisk = getHostScsiDisk(firstHostStorageSystem.getStorageDeviceInfo().getScsiTopology(), lstHostScsiDisks, iqn);
+
+        if (hostScsiDisk == null) {
+            rescanAllHosts(context, lstHosts, false, true);
+
+            morDs = firstHostDatastoreSystemMO.findDatastoreByName(datastoreName);
+
+            if (morDs != null) {
+                waitForAllHostsToSeeDatastore(lstHosts, new DatastoreMO(context, morDs));
+
+                mountVmfsDatastore(new DatastoreMO(context, morDs), lstHosts);
+
+                expandDatastore(firstHostDatastoreSystemMO, new DatastoreMO(context, morDs));
+
+                return morDs;
+            }
+
+            throw new Exception("A relevant SCSI disk could not be located to use to create a datastore.");
+        }
+
+        morDs = firstHostDatastoreSystemMO.createVmfsDatastore(datastoreName, hostScsiDisk);
+
+        if (morDs != null) {
+            waitForAllHostsToMountDatastore(lstHosts, new DatastoreMO(context, morDs));
+
+            expandDatastore(firstHostDatastoreSystemMO, new DatastoreMO(context, morDs));
+
+            return morDs;
+        }
+
+        throw new Exception("Unable to create a datastore");
+    }
+
+    private void waitForAllHostsToSeeDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
+        long endWaitTime = System.currentTimeMillis() + SECONDS_TO_WAIT_FOR_DATASTORE * 1000;
+
+        boolean isConditionMet = false;
+
+        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
+            Thread.sleep(5000);
+
+            isConditionMet = verifyAllHostsSeeDatastore(lstHosts, dsMO);
+        }
+
+        if (!isConditionMet) {
+            throw new CloudRuntimeException("Not all hosts mounted the datastore");
+        }
+    }
+
+    private boolean verifyAllHostsSeeDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
+        int numHostsChecked = 0;
+
+        for (Pair<ManagedObjectReference, String> host : lstHosts) {
+            ManagedObjectReference morHostToMatch = host.first();
+            HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
+
+            List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
+
+            for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
+                ManagedObjectReference morHost = datastoreHostMount.getKey();
+                HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
+
+                if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
+                    numHostsChecked++;
+                }
+            }
+        }
+
+        return lstHosts.size() == numHostsChecked;
+    }
+
+    private void waitForAllHostsToMountDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
+        long endWaitTime = System.currentTimeMillis() + SECONDS_TO_WAIT_FOR_DATASTORE * 1000;
+
+        boolean isConditionMet = false;
+
+        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
+            Thread.sleep(5000);
+
+            isConditionMet = verifyAllHostsMountedDatastore(lstHosts, dsMO);
+        }
+
+        if (!isConditionMet) {
+            throw new CloudRuntimeException("Not all hosts mounted the datastore");
+        }
+    }
+
+    private void waitForAllHostsToMountDatastore2(List<HostMO> lstHosts, DatastoreMO dsMO) throws Exception {
+        long endWaitTime = System.currentTimeMillis() + SECONDS_TO_WAIT_FOR_DATASTORE * 1000;
+
+        boolean isConditionMet = false;
+
+        while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
+            Thread.sleep(5000);
+
+            isConditionMet = verifyAllHostsMountedDatastore2(lstHosts, dsMO);
+        }
+
+        if (!isConditionMet) {
+            throw new CloudRuntimeException("Not all hosts mounted the datastore");
+        }
+    }
+
+    private boolean verifyAllHostsMountedDatastore(List<Pair<ManagedObjectReference, String>> lstHosts, DatastoreMO dsMO) throws Exception {
+        List<HostMO> hostMOs = new ArrayList<>(lstHosts.size());
+
+        for (Pair<ManagedObjectReference, String> host : lstHosts) {
+            ManagedObjectReference morHostToMatch = host.first();
+            HostMO hostToMatchMO = new HostMO(dsMO.getContext(), morHostToMatch);
+
+            hostMOs.add(hostToMatchMO);
+        }
+
+        return verifyAllHostsMountedDatastore2(hostMOs, dsMO);
+    }
+
+    private boolean verifyAllHostsMountedDatastore2(List<HostMO> lstHosts, DatastoreMO dsMO) throws Exception {
+        int numHostsChecked = 0;
+
+        for (HostMO hostToMatchMO : lstHosts) {
+            List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
+
+            for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
+                ManagedObjectReference morHost = datastoreHostMount.getKey();
+                HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
+
+                if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
+                    if (datastoreHostMount.getMountInfo().isMounted() && datastoreHostMount.getMountInfo().isAccessible()) {
+                        numHostsChecked++;
+                    }
+                    else {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return lstHosts.size() == numHostsChecked;
+    }
+
+    // the purpose of this method is to find the HostScsiDisk in the passed-in array that exists (if any) because
+    // we added the static iqn to an iSCSI HBA
+    private static HostScsiDisk getHostScsiDisk(HostScsiTopology hst, List<HostScsiDisk> lstHostScsiDisks, String iqn) {
+        for (HostScsiTopologyInterface adapter : hst.getAdapter()) {
+            if (adapter.getTarget() != null) {
+                for (HostScsiTopologyTarget target : adapter.getTarget()) {
+                    if (target.getTransport() instanceof HostInternetScsiTargetTransport) {
+                        String iScsiName = ((HostInternetScsiTargetTransport)target.getTransport()).getIScsiName();
+
+                        if (iqn.equals(iScsiName)) {
+                            for (HostScsiDisk hostScsiDisk : lstHostScsiDisks) {
+                                for (HostScsiTopologyLun hstl : target.getLun()) {
+                                    if (hstl.getScsiLun().contains(hostScsiDisk.getUuid())) {
+                                        return hostScsiDisk;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isDatastoreMounted(DatastoreMO dsMO, HostMO hostToMatchMO) throws Exception {
+        List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
+
+        for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
+            ManagedObjectReference morHost = datastoreHostMount.getKey();
+            HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
+
+            if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
+                return datastoreHostMount.getMountInfo().isMounted();
+            }
+        }
+
+        throw new CloudRuntimeException("Unable to locate the applicable host");
+    }
+
+    private String getDatastoreUuid(DatastoreMO dsMO, HostMO hostToMatchMO) throws Exception {
+        List<DatastoreHostMount> datastoreHostMounts = dsMO.getHostMounts();
+
+        for (DatastoreHostMount datastoreHostMount : datastoreHostMounts) {
+            ManagedObjectReference morHost = datastoreHostMount.getKey();
+            HostMO hostMO = new HostMO(dsMO.getContext(), morHost);
+
+            if (hostMO.getHostName().equals(hostToMatchMO.getHostName())) {
+                String path = datastoreHostMount.getMountInfo().getPath();
+
+                String searchStr = "/vmfs/volumes/";
+                int index = path.indexOf(searchStr);
+
+                if (index == -1) {
+                    throw new CloudRuntimeException("Unable to find the following search string: " + searchStr);
+                }
+
+                return path.substring(index + searchStr.length());
+            }
+        }
+
+        throw new CloudRuntimeException("Unable to locate the UUID of the datastore");
+    }
+
+    private void mountVmfsDatastore(DatastoreMO dsMO, List<Pair<ManagedObjectReference, String>> hosts) throws Exception {
+        for (Pair<ManagedObjectReference, String> host : hosts) {
+            HostMO hostMO = new HostMO(dsMO.getContext(), host.first());
+
+            List<HostMO> hostMOs = new ArrayList<>(1);
+
+            hostMOs.add(hostMO);
+
+            mountVmfsDatastore2(dsMO, hostMOs);
+        }
+    }
+
+    private void mountVmfsDatastore2(DatastoreMO dsMO, List<HostMO> hosts) throws Exception {
+        for (HostMO hostMO : hosts) {
+            if (!isDatastoreMounted(dsMO, hostMO)) {
+                HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
+
+                try {
+                    hostStorageSystemMO.mountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+                }
+                catch (InvalidStateFaultMsg ex) {
+                    s_logger.trace("'" + ex.getClass().getName() + "' exception thrown: " + ex.getMessage());
+
+                    List<HostMO> currentHosts = new ArrayList<>(1);
+
+                    currentHosts.add(hostMO);
+
+                    s_logger.trace("Waiting for host " + hostMO.getHostName() + " to mount datastore " + dsMO.getName());
+
+                    waitForAllHostsToMountDatastore2(currentHosts, dsMO);
+                }
+            }
+        }
+    }
+
+    private void unmountVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
+                                      List<Pair<ManagedObjectReference, String>> hosts) throws Exception {
+        for (Pair<ManagedObjectReference, String> host : hosts) {
+            HostMO hostMO = new HostMO(context, host.first());
+
+            List<HostMO> hostMOs = new ArrayList<>(1);
+
+            hostMOs.add(hostMO);
+
+            unmountVmfsDatastore2(context, hyperHost, datastoreName, hostMOs);
+        }
+    }
+
+    private void unmountVmfsDatastore2(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
+                                       List<HostMO> hosts) throws Exception {
+        ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName);
+        DatastoreMO dsMO = new DatastoreMO(context, morDs);
+
+        for (HostMO hostMO : hosts) {
+            unmountVmfsVolume(dsMO, hostMO);
+        }
+    }
+
+    private void unmountVmfsVolume(DatastoreMO dsMO, HostMO hostMO) throws Exception {
+        if (isDatastoreMounted(dsMO, hostMO)) {
+            HostStorageSystemMO hostStorageSystemMO = hostMO.getHostStorageSystemMO();
+
+            hostStorageSystemMO.unmountVmfsVolume(getDatastoreUuid(dsMO, hostMO));
+        }
+    }
+
+    private List<HostInternetScsiHbaStaticTarget> getTargets(List<Map<String, String>> targets) {
+        List<HostInternetScsiHbaStaticTarget> iScsiTargets = new ArrayList<>();
+
+        for (Map<String, String> target : targets) {
+            HostInternetScsiHbaStaticTarget iScsiTarget = new HostInternetScsiHbaStaticTarget();
+
+            iScsiTarget.setAddress(target.get(ModifyTargetsCommand.STORAGE_HOST));
+            iScsiTarget.setPort(Integer.parseInt(target.get(ModifyTargetsCommand.STORAGE_PORT)));
+            iScsiTarget.setIScsiName(trimIqn(target.get(ModifyTargetsCommand.IQN)));
+
+            iScsiTargets.add(iScsiTarget);
+        }
+
+        return iScsiTargets;
+    }
+
+    private void removeVmfsDatastore(Command cmd, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
+                                     String iqn) throws Exception {
+        VmwareContext context = hostService.getServiceContext(cmd);
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO cluster = new ClusterMO(context, morCluster);
+        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+
+        removeVmfsDatastore(cmd, hyperHost, datastoreName, storageIpAddress, storagePortNumber, iqn, lstHosts);
+    }
+
+    private void removeVmfsDatastore(Command cmd, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
+                                     String iqn, List<Pair<ManagedObjectReference, String>> lstHosts) throws Exception {
+        VmwareContext context = hostService.getServiceContext(cmd);
+
+        unmountVmfsDatastore(context, hyperHost, datastoreName, lstHosts);
+
+        HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageIpAddress, lstHosts);
+        List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+        if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+            HostInternetScsiHbaStaticTarget target = new HostInternetScsiHbaStaticTarget();
+
+            target.setAddress(storageIpAddress);
+            target.setPort(storagePortNumber);
+            target.setIScsiName(iqn);
+
+            final List<HostInternetScsiHbaStaticTarget> lstTargets = new ArrayList<>();
+
+            lstTargets.add(target);
+
+            addRemoveInternetScsiTargetsToAllHosts(false, lstTargets, hostsUsingStaticDiscovery);
+
+            rescanAllHosts(hostsUsingStaticDiscovery, true, false);
+        }
+    }
+
+    private void createVmdk(Command cmd, DatastoreMO dsMo, String vmdkDatastorePath, Long volumeSize) throws Exception {
+        VmwareContext context = hostService.getServiceContext(null);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+
+        String dummyVmName = hostService.getWorkerName(context, cmd, 0);
+
+        VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
+
+        if (vmMo == null) {
+            throw new Exception("Unable to create a dummy VM for volume creation");
+        }
+
+        Long volumeSizeToUse = volumeSize < dsMo.getSummary().getFreeSpace() ? volumeSize : dsMo.getSummary().getFreeSpace();
+
+        vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey());
+        vmMo.detachDisk(vmdkDatastorePath, false);
+        vmMo.destroy();
+    }
+
+    private static int getMBsFromBytes(long bytes) {
+        return (int)(bytes / (1024L * 1024L));
+    }
+
+    public void handleTargets(boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove, boolean isRemoveAsync,
+                              List<Map<String, String>> targets, List<HostMO> lstHosts) throws Exception {
+        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
+
+        for (HostMO host : lstHosts) {
+            List<HostMO> hosts = new ArrayList<>();
+
+            hosts.add(host);
+
+            List<Map<String, String>> dynamicTargetsForHost = new ArrayList<>();
+            List<Map<String, String>> staticTargetsForHost = new ArrayList<>();
+
+            for (Map<String, String> target : targets) {
+                String storageAddress = target.get(ModifyTargetsCommand.STORAGE_HOST);
+
+                HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(storageAddress, hosts);
+                List<HostMO> hostsUsingDynamicDiscovery = hostDiscoveryMethod.getHostsUsingDynamicDiscovery();
+
+                if (hostsUsingDynamicDiscovery != null && hostsUsingDynamicDiscovery.size() > 0) {
+                    dynamicTargetsForHost.add(target);
+                }
+                else {
+                    staticTargetsForHost.add(target);
+                }
+            }
+
+            if (add) {
+                executorService.submit(new Thread(() -> {
+                    try {
+                        boolean rescan = false;
+
+                        if (staticTargetsForHost.size() > 0) {
+                            addRemoveInternetScsiTargetsToAllHosts(true, getTargets(staticTargetsForHost), hosts);
+
+                            rescan = true;
+                        }
+
+                        if (dynamicTargetsForHost.size() > 0) {
+                            rescan = true;
+                        }
+
+                        if (rescan) {
+                            rescanAllHosts(hosts, true, false);
+
+                            List<HostInternetScsiHbaStaticTarget> targetsToAdd = new ArrayList<>();
+
+                            targetsToAdd.addAll(getTargets(staticTargetsForHost));
+                            targetsToAdd.addAll(getTargets(dynamicTargetsForHost));
+
+                            for (HostInternetScsiHbaStaticTarget targetToAdd : targetsToAdd) {
+                                HostDatastoreSystemMO hostDatastoreSystemMO = host.getHostDatastoreSystemMO();
+                                String datastoreName = waitForDatastoreName(hostDatastoreSystemMO, targetToAdd.getIScsiName());
+                                ManagedObjectReference morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+                                DatastoreMO datastoreMO = new DatastoreMO(host.getContext(), morDs);
+
+                                mountVmfsDatastore2(datastoreMO, hosts);
+                            }
+                        }
+                    }
+                    catch (Exception ex) {
+                        s_logger.warn(ex.getMessage());
+                    }
+                }));
+            }
+            else {
+                List<HostInternetScsiHbaStaticTarget> targetsToRemove = new ArrayList<>();
+
+                if (staticTargetsForHost.size() > 0 &&
+                        (ModifyTargetsCommand.TargetTypeToRemove.STATIC.equals(targetTypeToRemove) || ModifyTargetsCommand.TargetTypeToRemove.BOTH.equals(targetTypeToRemove))) {
+                    targetsToRemove.addAll(getTargets(staticTargetsForHost));
+                }
+
+                if (dynamicTargetsForHost.size() > 0 &&
+                        (ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC.equals(targetTypeToRemove) || ModifyTargetsCommand.TargetTypeToRemove.BOTH.equals(targetTypeToRemove))) {
+                    targetsToRemove.addAll(getTargets(dynamicTargetsForHost));
+                }
+
+                if (targetsToRemove.size() > 0) {
+                    if (isRemoveAsync) {
+                        new Thread(() -> handleRemove(targetsToRemove, host, hosts)).start();
+                    } else {
+                        executorService.submit(new Thread(() -> handleRemove(targetsToRemove, host, hosts)));
+                    }
+                }
+            }
+        }
+
+        executorService.shutdown();
+
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'handleTargets'.");
+        }
+    }
+
+    private String waitForDatastoreName(HostDatastoreSystemMO hostDatastoreSystemMO, String iqn) throws Exception {
+        long endWaitTime = System.currentTimeMillis() + SECONDS_TO_WAIT_FOR_DATASTORE * 1000;
+
+        do {
+            String datastoreName = getDatastoreName(hostDatastoreSystemMO, iqn);
+
+            if (datastoreName != null) {
+                return datastoreName;
+            }
+
+            Thread.sleep(5000);
+        }
+        while (System.currentTimeMillis() < endWaitTime);
+
+        throw new CloudRuntimeException("Could not find the datastore name");
+    }
+
+    private String getDatastoreName(HostDatastoreSystemMO hostDatastoreSystemMO, String iqn) throws Exception {
+        String datastoreName = "-" + iqn + "-0";
+
+        ManagedObjectReference morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+
+        if (morDs != null) {
+            return datastoreName;
+        }
+
+        datastoreName = "_" + iqn + "_0";
+
+        morDs = hostDatastoreSystemMO.findDatastoreByName(datastoreName);
+
+        if (morDs != null) {
+            return datastoreName;
+        }
+
+        return null;
+    }
+
+    private void handleRemove(List<HostInternetScsiHbaStaticTarget> targetsToRemove, HostMO host, List<HostMO> hosts) {
+        try {
+            for (HostInternetScsiHbaStaticTarget target : targetsToRemove) {
+                String datastoreName = waitForDatastoreName(host.getHostDatastoreSystemMO(), target.getIScsiName());
+
+                unmountVmfsDatastore2(host.getContext(), host, datastoreName, hosts);
+            }
+
+            addRemoveInternetScsiTargetsToAllHosts(false, targetsToRemove, hosts);
+
+            rescanAllHosts(hosts, true, false);
+        }
+        catch (Exception ex) {
+            s_logger.warn(ex.getMessage());
+        }
+    }
+
+    private void addRemoveInternetScsiTargetsToAllHosts(VmwareContext context, final boolean add, final List<HostInternetScsiHbaStaticTarget> targets,
+                                                        List<Pair<ManagedObjectReference, String>> hostPairs) throws Exception {
+        List<HostMO> hosts = new ArrayList<>();
+
+        for (Pair<ManagedObjectReference, String> hostPair : hostPairs) {
+            HostMO host = new HostMO(context, hostPair.first());
+
+            hosts.add(host);
+        }
+
+        addRemoveInternetScsiTargetsToAllHosts(add, targets, hosts);
+    }
+
+    private void addRemoveInternetScsiTargetsToAllHosts(boolean add, List<HostInternetScsiHbaStaticTarget> targets,
+                                                        List<HostMO> hosts) throws Exception {
+        ExecutorService executorService = Executors.newFixedThreadPool(hosts.size());
+
+        final List<Exception> exceptions = new ArrayList<>();
+
+        for (HostMO host : hosts) {
+            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+            boolean iScsiHbaConfigured = false;
+
+            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+                if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
+                    iScsiHbaConfigured = true;
+
+                    final String iScsiHbaDevice = hba.getDevice();
+
+                    final HostStorageSystemMO hss = hostStorageSystem;
+
+                    executorService.submit(new Thread(() -> {
+                        try {
+                            if (add) {
+                                hss.addInternetScsiStaticTargets(iScsiHbaDevice, targets);
+                            } else {
+                                hss.removeInternetScsiStaticTargets(iScsiHbaDevice, targets);
+                            }
+                        } catch (Exception ex) {
+                            synchronized (exceptions) {
+                                exceptions.add(ex);
+                            }
+                        }
+                    }));
+                }
+            }
+
+            if (!iScsiHbaConfigured) {
+                throw new Exception("An iSCSI HBA must be configured before a host can use iSCSI storage.");
+            }
+        }
+
+        executorService.shutdown();
+
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'addRemoveInternetScsiTargetsToAllHosts'.");
+        }
+
+        if (exceptions.size() > 0) {
+            throw new Exception(exceptions.get(0).getMessage());
+        }
+    }
+
+    private void rescanAllHosts(VmwareContext context, List<Pair<ManagedObjectReference, String>> lstHostPairs, boolean rescanHba, boolean rescanVmfs) throws Exception {
+        List<HostMO> hosts = new ArrayList<>(lstHostPairs.size());
+
+        for (Pair<ManagedObjectReference, String> hostPair : lstHostPairs) {
+            HostMO host = new HostMO(context, hostPair.first());
+
+            hosts.add(host);
+        }
+
+        rescanAllHosts(hosts, rescanHba, rescanVmfs);
+    }
+
+    private void rescanAllHosts(List<HostMO> lstHosts, boolean rescanHba, boolean rescanVmfs) throws Exception {
+        if (!rescanHba && !rescanVmfs) {
+            // nothing to do
+            return;
+        }
+
+        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
+
+        final List<Exception> exceptions = new ArrayList<>();
+
+        for (HostMO host : lstHosts) {
+            HostStorageSystemMO hostStorageSystem = host.getHostStorageSystemMO();
+
+            boolean iScsiHbaConfigured = false;
+
+            for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+                if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
+                    iScsiHbaConfigured = true;
+
+                    final String iScsiHbaDevice = hba.getDevice();
+
+                    final HostStorageSystemMO hss = hostStorageSystem;
+
+                    executorService.submit(new Thread(() -> {
+                        try {
+                            if (rescanHba) {
+                                hss.rescanHba(iScsiHbaDevice);
+                            }
+
+                            if (rescanVmfs) {
+                                hss.rescanVmfs();
+                            }
+                        } catch (Exception ex) {
+                            synchronized (exceptions) {
+                                exceptions.add(ex);
+                            }
+                        }
+                    }));
+                }
+            }
+
+            if (!iScsiHbaConfigured) {
+                throw new Exception("An iSCSI HBA must be configured before a host can use iSCSI storage.");
+            }
+        }
+
+        executorService.shutdown();
+
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'rescanAllHosts'.");
+        }
+
+        if (exceptions.size() > 0) {
+            throw new Exception(exceptions.get(0).getMessage());
+        }
+    }
+
+    private static String trimIqn(String iqn) {
+        String[] tmp = iqn.split("/");
+
+        if (tmp.length != 3) {
+            String msg = "Wrong format for iSCSI path: " + iqn + ". It should be formatted as '/targetIQN/LUN'.";
+
+            s_logger.warn(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        return tmp[1].trim();
+    }
+
+    public ManagedObjectReference prepareManagedStorage(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
+                                                        String storageHost, int storagePort, String volumeName, String chapInitiatorUsername, String chapInitiatorSecret,
+                                                        String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception {
+
+        ManagedObjectReference morDs = prepareManagedDatastore(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort,
+                chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+
+        DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs);
+
+        String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeName != null ? volumeName : dsMo.getName());
+
+        if (!dsMo.fileExists(volumeDatastorePath)) {
+            createVmdk(cmd, dsMo, volumeDatastorePath, size);
+        }
+
+        return morDs;
+    }
+
+    public void handleDatastoreAndVmdkDetach(Command cmd, String datastoreName, String iqn, String storageHost, int storagePort) throws Exception {
+        VmwareContext context = hostService.getServiceContext(null);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+
+        removeVmfsDatastore(cmd, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iqn));
+    }
+
+    private void handleDatastoreAndVmdkDetachManaged(Command cmd, String diskUuid, String iqn, String storageHost, int storagePort) throws Exception {
+        if (storagePort == DEFAULT_NFS_PORT) {
+            VmwareContext context = hostService.getServiceContext(null);
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+            // for managed NFS datastore
+            hyperHost.unmountDatastore(diskUuid);
+        } else {
+            handleDatastoreAndVmdkDetach(cmd, VmwareResource.getDatastoreName(iqn), iqn, storageHost, storagePort);
+        }
+    }
+
+    private class ManagedTarget {
+        private final String storageAddress;
+        private final int storagePort;
+        private final String iqn;
+
+        ManagedTarget(String storageAddress, int storagePort, String iqn) {
+            this.storageAddress = storageAddress;
+            this.storagePort = storagePort;
+            this.iqn = iqn;
+        }
+
+        public String toString() {
+            return storageAddress + storagePort + iqn;
+        }
+    }
+
+    private void removeManagedTargetsFromCluster(List<String> managedDatastoreNames) throws Exception {
+        List<HostInternetScsiHbaStaticTarget> lstManagedTargets = new ArrayList<>();
+
+        VmwareContext context = hostService.getServiceContext(null);
+        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
+        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+        ClusterMO cluster = new ClusterMO(context, morCluster);
+        List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
+        HostMO hostMO = new HostMO(context, lstHosts.get(0).first());
+        HostStorageSystemMO hostStorageSystem = hostMO.getHostStorageSystemMO();
+
+        for (String managedDatastoreName : managedDatastoreNames) {
+            unmountVmfsDatastore(context, hyperHost, managedDatastoreName, lstHosts);
+        }
+
+        for (HostHostBusAdapter hba : hostStorageSystem.getStorageDeviceInfo().getHostBusAdapter()) {
+            if (hba instanceof HostInternetScsiHba && ((HostInternetScsiHba)hba).isIsSoftwareBased()) {
+                List<HostInternetScsiHbaStaticTarget> lstTargets = ((HostInternetScsiHba)hba).getConfiguredStaticTarget();
+
+                if (lstTargets != null) {
+                    for (HostInternetScsiHbaStaticTarget target : lstTargets) {
+                        if (managedDatastoreNames.contains(VmwareResource.createDatastoreNameFromIqn(target.getIScsiName()))) {
+                            lstManagedTargets.add(target);
+                        }
+                    }
+                }
+            }
+        }
+
+        ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size());
+
+        for (Pair<ManagedObjectReference, String> host : lstHosts) {
+            List<Pair<ManagedObjectReference, String>> hosts = new ArrayList<>();
+
+            hosts.add(host);
+
+            List<HostInternetScsiHbaStaticTarget> staticTargetsForHost = new ArrayList<>();
+
+            for (HostInternetScsiHbaStaticTarget iScsiManagedTarget : lstManagedTargets) {
+                String storageAddress = iScsiManagedTarget.getAddress();
+
+                HostDiscoveryMethod hostDiscoveryMethod = getHostDiscoveryMethod(context, storageAddress, hosts);
+                List<HostMO> hostsUsingStaticDiscovery = hostDiscoveryMethod.getHostsUsingStaticDiscovery();
+
+                if (hostsUsingStaticDiscovery != null && hostsUsingStaticDiscovery.size() > 0) {
+                    staticTargetsForHost.add(iScsiManagedTarget);
+                }
+            }
+
+            if (staticTargetsForHost.size() > 0) {
+                executorService.submit(new Thread(() -> {
+                    try {
+                        addRemoveInternetScsiTargetsToAllHosts(context, false, staticTargetsForHost, hosts);
+
+                        rescanAllHosts(context, hosts, true, false);
+                    }
+                    catch (Exception ex) {
+                        s_logger.warn(ex.getMessage());
+                    }
+                }));
+            }
+        }
+
+        executorService.shutdown();
+
+        if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES)) {
+            throw new Exception("The system timed out before completing the task 'removeManagedTargetsFromCluster'.");
+        }
+    }
+
+    private List<String> getManagedDatastoreNamesFromVirtualDisks(List<VirtualDisk> virtualDisks) {
+        List<String> managedDatastoreNames = new ArrayList<>();
+
+        if (virtualDisks != null) {
+            for (VirtualDisk virtualDisk : virtualDisks) {
+                if (virtualDisk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
+                    VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
+                    String path = backingInfo.getFileName();
+
+                    String search = "[-";
+                    int index = path.indexOf(search);
+
+                    if (index > -1) {
+                        path = path.substring(index + search.length());
+
+                        String search2 = "-0]";
+
+                        index = path.lastIndexOf(search2);
+
+                        if (index > -1) {
+                            path = path.substring(0, index);
+
+                            if (path.startsWith("iqn.")) {
+                                managedDatastoreNames.add("-" + path + "-0");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return managedDatastoreNames;
+    }
+
+    private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir,
+                                             String backupName, long wait, Integer nfsVersion) throws Exception {
+
+        String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null);
+        String srcOVAFileName;
+        String srcOVFFileName;
+
+        srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension();
+        srcOVFFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + ".ovf";
+
+        String snapshotDir = "";
+        if (backupName.contains("/")) {
+            snapshotDir = backupName.split("/")[0];
+        }
+
+        File ovafile = new File(srcOVAFileName);
+
+        File ovfFile = new File(srcOVFFileName);
+        // String srcFileName = getOVFFilePath(srcOVAFileName);
+        if (!ovfFile.exists()) {
+            srcOVFFileName = getOVFFilePath(srcOVAFileName);
+            if (srcOVFFileName == null && ovafile.exists()) {  // volss: ova file exists; o/w can't do tar
+                Script command = new Script("tar", wait, s_logger);
+                command.add("--no-same-owner");
+                command.add("-xf", srcOVAFileName);
+                command.setWorkDir(secondaryMountPoint + "/" + secStorageDir + "/" + snapshotDir);
+                s_logger.info("Executing command: " + command.toString());
+                String result = command.execute();
+                if (result != null) {
+                    String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+                srcOVFFileName = getOVFFilePath(srcOVAFileName);
+            } else if (srcOVFFileName == null) {
+                String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+        }
+        if (srcOVFFileName == null) {
+            String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName;
+            s_logger.error(msg);
+            throw new Exception(msg);
+        }
+
+        VirtualMachineMO clonedVm = null;
+        try {
+            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin");
+            clonedVm = hyperHost.findVmOnHyperHost(newVolumeName);
+            if (clonedVm == null) {
+                throw new Exception("Unable to create container VM for volume creation");
+            }
+
+            clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false);
+            clonedVm.detachAllDisks();
+            return _storage.getSize(srcOVFFileName);
+        } finally {
+            if (clonedVm != null) {
+                clonedVm.detachAllDisks();
+                clonedVm.destroy();
+            }
+        }
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO pool = destData.getDataStore();
+        DataStoreTO imageStore = srcData.getDataStore();
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+        String primaryStorageNameLabel = pool.getUuid();
+
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+        String backedUpSnapshotUuid = snapshot.getPath();
+        int index = backedUpSnapshotUuid.lastIndexOf(File.separator);
+        String backupPath = backedUpSnapshotUuid.substring(0, index);
+        backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 1);
+        String details;
+        String newVolumeName = VmwareHelper.getVCenterSafeUuid();
+
+        VmwareContext context = hostService.getServiceContext(cmd);
+        try {
+            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
+            ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStorageNameLabel);
+            if (morPrimaryDs == null) {
+                String msg = "Unable to find datastore: " + primaryStorageNameLabel;
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            // strip off the extension since restoreVolumeFromSecStorage internally will append suffix there.
+            if (backedUpSnapshotUuid.endsWith(".ova")){
+                backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ova", "");
+            } else if (backedUpSnapshotUuid.endsWith(".ovf")){
+                backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
+            }
+            DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
+            restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion);
+
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(newVolumeName);
+            return new CopyCmdAnswer(newVol);
+        } catch (Throwable e) {
+            if (e instanceof RemoteException) {
+                hostService.invalidateServiceContext(context);
+            }
+
+            s_logger.error("Unexpecpted exception ", e);
+            details = "create volume from snapshot exception: " + VmwareHelper.getExceptionMessage(e);
+        }
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer deleteSnapshot(DeleteCommand cmd) {
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData();
+        DataStoreTO store = snapshot.getDataStore();
+        if (store.getRole() == DataStoreRole.Primary) {
+            return new Answer(cmd);
+        } else {
+            return new Answer(cmd, false, "unsupported command");
+        }
+    }
+
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        return new Answer(cmd, false, "not implememented yet");
+    }
+
+    private static String deriveTemplateUuidOnHost(VmwareHypervisorHost hyperHost, String storeIdentifier, String templateName) {
+        String templateUuid;
+        try{
+            templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes("UTF-8")).toString();
+        }catch(UnsupportedEncodingException e){
+            s_logger.warn("unexpected encoding error, using default Charset: " + e.getLocalizedMessage());
+            templateUuid = UUID.nameUUIDFromBytes((templateName + "@" + storeIdentifier + "-" + hyperHost.getMor().getValue()).getBytes(Charset.defaultCharset()))
+                    .toString();
+        }
+        templateUuid = templateUuid.replaceAll("-", "");
+        return templateUuid;
+    }
+
+    private String getLegacyVmDataDiskController() throws Exception {
+        return DiskControllerType.lsilogic.toString();
+    }
+
+    void setNfsVersion(Integer nfsVersion){
+        this._nfsVersion = nfsVersion;
+        s_logger.debug("VmwareProcessor instance now using NFS version: " + nfsVersion);
+    }
+
+    void setFullCloneFlag(boolean value){
+        this._fullCloneFlag = value;
+        s_logger.debug("VmwareProcessor instance - create full clone = " + (value ? "TRUE" : "FALSE"));
+    }
+
+    @Override
+    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
+        return null;
+    }
+}
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
rename to plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java
new file mode 100644
index 0000000..e428947
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.api.command.admin.zone;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.hypervisor.vmware.VmwareDatacenter;
+import com.cloud.hypervisor.vmware.VmwareDatacenterService;
+import com.cloud.user.Account;
+
+@APICommand(name = UpdateVmwareDcCmd.APINAME, description = "Updates a VMware datacenter details for a zone",
+        responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
+        since = "4.12.0", authorized = {RoleType.Admin})
+public class UpdateVmwareDcCmd extends BaseCmd {
+    public static final Logger LOG = Logger.getLogger(UpdateVmwareDcCmd.class);
+
+    static final String APINAME = "updateVmwareDc";
+
+    @Inject
+    public VmwareDatacenterService vmwareDatacenterService;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID,
+            entityType = ZoneResponse.class, required = true, description = "The zone ID")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
+            description = "VMware datacenter name.")
+    private String name;
+
+    @Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
+            description = "The name/IP of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
+    private String vCenter;
+
+    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING,
+            description = "The username required to connect to resource.")
+    private String username;
+
+    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING,
+            description = "The password for specified username.")
+    private String password;
+
+    @Parameter(name = ApiConstants.IS_RECURSIVE, type = CommandType.BOOLEAN,
+            description = "Specify if cluster level username/password/url and host level guid need to be updated as well. By default this is true.")
+    private Boolean recursive = true;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public long getZoneId() {
+        return zoneId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVcenter() {
+        return vCenter;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public Boolean isRecursive() {
+        return recursive;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public void execute() {
+        final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
+        if (vmwareDatacenter == null) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VMware datacenter");
+        }
+        final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
+        response.setId(vmwareDatacenter.getUuid());
+        response.setName(vmwareDatacenter.getVmwareDatacenterName());
+        response.setResponseName(getCommandName());
+        response.setObjectName("vmwaredc");
+        setResponseObject(response);
+    }
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
similarity index 100%
rename from plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
new file mode 100644
index 0000000..2463e75
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cloudstack.storage.motion;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.MigrateWithStorageAnswer;
+import com.cloud.agent.api.MigrateWithStorageCommand;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+@Component
+public class VmwareStorageMotionStrategy implements DataMotionStrategy {
+    private static final Logger s_logger = Logger.getLogger(VmwareStorageMotionStrategy.class);
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    VolumeDao volDao;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    PrimaryDataStoreDao storagePoolDao;
+    @Inject
+    VMInstanceDao instanceDao;
+    @Inject
+    private HostDao hostDao;
+
+    @Override
+    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
+        // OfflineVmwareMigration: return StrategyPriority.HYPERVISOR when destData is in a storage pool in the same vmware-cluster and both are volumes
+        if (isOnVmware(srcData, destData)
+                && isOnPrimary(srcData, destData)
+                && isVolumesOnly(srcData, destData)
+                && isDettached(srcData)
+                && isIntraCluster(srcData, destData)
+                && isStoreScopeEqual(srcData, destData)) {
+            if (s_logger.isDebugEnabled()) {
+                String msg = String.format("%s can handle the request because %d(%s) and %d(%s) share the VMware cluster %s (== %s)"
+                        , this.getClass()
+                        , srcData.getId()
+                        , srcData.getUuid()
+                        , destData.getId()
+                        , destData.getUuid()
+                        , storagePoolDao.findById(srcData.getDataStore().getId()).getClusterId()
+                        , storagePoolDao.findById(destData.getDataStore().getId()).getClusterId());
+                s_logger.debug(msg);
+            }
+            return StrategyPriority.HYPERVISOR;
+        }
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    private boolean isDettached(DataObject srcData) {
+        VolumeVO volume = volDao.findById(srcData.getId());
+        return volume.getInstanceId() == null;
+    }
+
+    private boolean isVolumesOnly(DataObject srcData, DataObject destData) {
+        return DataObjectType.VOLUME.equals(srcData.getType())
+                && DataObjectType.VOLUME.equals(destData.getType());
+    }
+
+    private boolean isOnPrimary(DataObject srcData, DataObject destData) {
+        return DataStoreRole.Primary.equals(srcData.getDataStore().getRole())
+                && DataStoreRole.Primary.equals(destData.getDataStore().getRole());
+    }
+
+    private boolean isOnVmware(DataObject srcData, DataObject destData) {
+        return HypervisorType.VMware.equals(srcData.getTO().getHypervisorType())
+                && HypervisorType.VMware.equals(destData.getTO().getHypervisorType());
+    }
+
+    private boolean isIntraCluster(DataObject srcData, DataObject destData) {
+        DataStore srcStore = srcData.getDataStore();
+        StoragePool srcPool = storagePoolDao.findById(srcStore.getId());
+        DataStore destStore = destData.getDataStore();
+        StoragePool destPool = storagePoolDao.findById(destStore.getId());
+        return srcPool.getClusterId().equals(destPool.getClusterId());
+    }
+
+    /**
+     * Ensure that the scope of source and destination storage pools match
+     *
+     * @param srcData
+     * @param destData
+     * @return
+     */
+    private boolean isStoreScopeEqual(DataObject srcData, DataObject destData) {
+        DataStore srcStore = srcData.getDataStore();
+        DataStore destStore = destData.getDataStore();
+        String msg = String.format("Storage scope of source pool is %s and of destination pool is %s", srcStore.getScope().toString(), destStore.getScope().toString());
+        s_logger.debug(msg);
+        return srcStore.getScope().getScopeType() == (destStore.getScope().getScopeType());
+    }
+
+    @Override
+    public StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
+        if (srcHost.getHypervisorType() == HypervisorType.VMware && destHost.getHypervisorType() == HypervisorType.VMware) {
+            s_logger.debug(this.getClass() + " can handle the request because the hosts have VMware hypervisor");
+            return StrategyPriority.HYPERVISOR;
+        }
+        return StrategyPriority.CANT_HANDLE;
+    }
+
+    /**
+     * the Vmware storageMotion strategy allows to copy to a destination pool but not to a destination host
+     *
+     * @param srcData  volume to move
+     * @param destData volume description as intended after the move
+     * @param destHost null or else
+     * @param callback where to report completion or failure to
+     */
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        if (destHost != null) {
+            String format = "%s cannot target a host in moving an object from {%s}\n to {%s}";
+            String msg = String.format(format
+                    , this.getClass().getName()
+                    , srcData.toString()
+                    , destData.toString()
+            );
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        // OfflineVmwareMigration: extract the destination pool from destData and construct a migrateVolume command
+        if (!isOnPrimary(srcData, destData)) {
+            // OfflineVmwareMigration: we shouldn't be here as we would have refused in the canHandle call
+            throw new UnsupportedOperationException();
+        }
+        StoragePool sourcePool = (StoragePool) srcData.getDataStore();
+        StoragePool targetPool = (StoragePool) destData.getDataStore();
+        MigrateVolumeCommand cmd = new MigrateVolumeCommand(srcData.getId()
+                , srcData.getTO().getPath()
+                , sourcePool
+                , targetPool);
+        // OfflineVmwareMigration: should be ((StoragePool)srcData.getDataStore()).getHypervisor() but that is NULL, so hardcoding
+        Answer answer;
+        ScopeType scopeType = srcData.getDataStore().getScope().getScopeType();
+        if (ScopeType.CLUSTER == scopeType) {
+            // Find Volume source cluster and select any Vmware hypervisor host to attach worker VM
+            Long hostId = findSuitableHostIdForWorkerVmPlacement(sourcePool.getClusterId());
+            if (hostId == null) {
+                throw new CloudRuntimeException("Offline Migration failed, unable to find suitable host for worker VM placement in cluster: " + sourcePool.getName());
+            }
+            answer = agentMgr.easySend(hostId, cmd);
+        } else {
+            answer = agentMgr.sendTo(sourcePool.getDataCenterId(), HypervisorType.VMware, cmd);
+        }
+        updateVolumeAfterMigration(answer, srcData, destData);
+        CopyCommandResult result = new CopyCommandResult(null, answer);
+        callback.complete(result);
+    }
+
+    /**
+     * Selects a host from the cluster housing the source storage pool
+     * Assumption is that Primary Storage is cluster-wide
+     * <p>
+     * returns any host ID within the cluster if storage-pool is cluster-wide, and exception is thrown otherwise
+     *
+     * @param clusterId
+     * @return
+     */
+    private Long findSuitableHostIdForWorkerVmPlacement(Long clusterId) {
+        List<HostVO> hostLists = hostDao.findByClusterId(clusterId);
+        Long hostId = null;
+        for (HostVO hostVO : hostLists) {
+            if (hostVO.getHypervisorType().equals(HypervisorType.VMware) && hostVO.getStatus() == Status.Up) {
+                hostId = hostVO.getId();
+                break;
+            }
+        }
+        return hostId;
+    }
+
+    private void updateVolumeAfterMigration(Answer answer, DataObject srcData, DataObject destData) {
+        VolumeVO destinationVO = volDao.findById(destData.getId());
+        if (!(answer instanceof MigrateVolumeAnswer)) {
+            // OfflineVmwareMigration: reset states and such
+            VolumeVO sourceVO = volDao.findById(srcData.getId());
+            sourceVO.setState(Volume.State.Ready);
+            volDao.update(sourceVO.getId(), sourceVO);
+            destinationVO.setState(Volume.State.Expunged);
+            destinationVO.setRemoved(new Date());
+            volDao.update(destinationVO.getId(), destinationVO);
+            throw new CloudRuntimeException("unexpected answer from hypervisor agent: " + answer.getDetails());
+        }
+        MigrateVolumeAnswer ans = (MigrateVolumeAnswer) answer;
+        if (s_logger.isDebugEnabled()) {
+            String format = "retrieved '%s' as new path for volume(%d)";
+            s_logger.debug(String.format(format, ans.getVolumePath(), destData.getId()));
+        }
+        // OfflineVmwareMigration: update the volume with new pool/volume path
+        destinationVO.setPath(ans.getVolumePath());
+        volDao.update(destinationVO.getId(), destinationVO);
+    }
+
+    @Override
+    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
+        Answer answer = null;
+        String errMsg = null;
+        try {
+            VMInstanceVO instance = instanceDao.findById(vmTo.getId());
+            if (instance != null) {
+                if (srcHost.getClusterId().equals(destHost.getClusterId())) {
+                    answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap);
+                } else {
+                    answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap);
+                }
+            } else {
+                throw new CloudRuntimeException("Unsupported operation requested for moving data.");
+            }
+        } catch (Exception e) {
+            s_logger.error("copy failed", e);
+            errMsg = e.toString();
+        }
+
+        CopyCommandResult result = new CopyCommandResult(null, answer);
+        result.setResult(errMsg);
+        callback.complete(result);
+    }
+
+    private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map<VolumeInfo, DataStore> volumeToPool)
+            throws AgentUnavailableException {
+
+        // Initiate migration of a virtual machine with it's volumes.
+        try {
+            List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerto = new ArrayList<Pair<VolumeTO, StorageFilerTO>>();
+            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
+                VolumeInfo volume = entry.getKey();
+                VolumeTO volumeTo = new VolumeTO(volume, storagePoolDao.findById(volume.getPoolId()));
+                StorageFilerTO filerTo = new StorageFilerTO((StoragePool) entry.getValue());
+                volumeToFilerto.add(new Pair<VolumeTO, StorageFilerTO>(volumeTo, filerTo));
+            }
+
+            // Migration across cluster needs to be done in three phases.
+            // 1. Send a migrate command to source resource to initiate migration
+            //      Run validations against target!!
+            // 2. Complete the process. Update the volume details.
+            MigrateWithStorageCommand migrateWithStorageCmd = new MigrateWithStorageCommand(to, volumeToFilerto, destHost.getGuid());
+            MigrateWithStorageAnswer migrateWithStorageAnswer = (MigrateWithStorageAnswer) agentMgr.send(srcHost.getId(), migrateWithStorageCmd);
+            if (migrateWithStorageAnswer == null) {
+                s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed.");
+                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
+            } else if (!migrateWithStorageAnswer.getResult()) {
+                s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + migrateWithStorageAnswer.getDetails());
+                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost + ". " + migrateWithStorageAnswer.getDetails());
+            } else {
+                // Update the volume details after migration.
+                updateVolumesAfterMigration(volumeToPool, migrateWithStorageAnswer.getVolumeTos());
+            }
+            s_logger.debug("Storage migration of VM " + vm.getInstanceName() + " completed successfully. Migrated to host " + destHost.getName());
+
+            return migrateWithStorageAnswer;
+        } catch (OperationTimedoutException e) {
+            s_logger.error("Error while migrating vm " + vm + " to host " + destHost, e);
+            throw new AgentUnavailableException("Operation timed out on storage motion for " + vm, destHost.getId());
+        }
+    }
+
+    private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map<VolumeInfo, DataStore> volumeToPool)
+            throws AgentUnavailableException {
+
+        // Initiate migration of a virtual machine with it's volumes.
+        try {
+            List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerto = new ArrayList<Pair<VolumeTO, StorageFilerTO>>();
+            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
+                VolumeInfo volume = entry.getKey();
+                VolumeTO volumeTo = new VolumeTO(volume, storagePoolDao.findById(volume.getPoolId()));
+                StorageFilerTO filerTo = new StorageFilerTO((StoragePool) entry.getValue());
+                volumeToFilerto.add(new Pair<VolumeTO, StorageFilerTO>(volumeTo, filerTo));
+            }
+
+            MigrateWithStorageCommand command = new MigrateWithStorageCommand(to, volumeToFilerto, destHost.getGuid());
+            MigrateWithStorageAnswer answer = (MigrateWithStorageAnswer) agentMgr.send(srcHost.getId(), command);
+            if (answer == null) {
+                s_logger.error("Migration with storage of vm " + vm + " failed.");
+                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
+            } else if (!answer.getResult()) {
+                s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + answer.getDetails());
+                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost + ". " + answer.getDetails());
+            } else {
+                // Update the volume details after migration.
+                updateVolumesAfterMigration(volumeToPool, answer.getVolumeTos());
+            }
+
+            return answer;
+        } catch (OperationTimedoutException e) {
+            s_logger.error("Error while migrating vm " + vm + " to host " + destHost, e);
+            throw new AgentUnavailableException("Operation timed out on storage motion for " + vm, destHost.getId());
+        }
+    }
+
+    private void updateVolumesAfterMigration(Map<VolumeInfo, DataStore> volumeToPool, List<VolumeObjectTO> volumeTos) {
+        for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
+            boolean updated = false;
+            VolumeInfo volume = entry.getKey();
+            StoragePool pool = (StoragePool) entry.getValue();
+            for (VolumeObjectTO volumeTo : volumeTos) {
+                if (volume.getId() == volumeTo.getId()) {
+                    VolumeVO volumeVO = volDao.findById(volume.getId());
+                    Long oldPoolId = volumeVO.getPoolId();
+                    volumeVO.setPath(volumeTo.getPath());
+                    if (volumeTo.getChainInfo() != null) {
+                        volumeVO.setChainInfo(volumeTo.getChainInfo());
+                    }
+                    volumeVO.setLastPoolId(oldPoolId);
+                    volumeVO.setFolder(pool.getPath());
+                    volumeVO.setPodId(pool.getPodId());
+                    volumeVO.setPoolId(pool.getId());
+                    volDao.update(volume.getId(), volumeVO);
+                    updated = true;
+                    break;
+                }
+            }
+            if (!updated) {
+                s_logger.error("Volume path wasn't updated for volume " + volume + " after it was migrated.");
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/module.properties b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/module.properties
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/module.properties
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/spring-vmware-compute-context.xml
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-compute/vmware-defaults.properties
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/module.properties b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/module.properties
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-discoverer/module.properties
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-discoverer/spring-vmware-discoverer-context.xml
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/module.properties b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-network/module.properties
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/module.properties
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-network/module.properties
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-network/spring-vmware-network-context.xml
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/module.properties b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-storage/module.properties
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/module.properties
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-storage/module.properties
diff --git a/plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml
similarity index 100%
rename from plugins/hypervisors/vmware/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml
rename to plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/vmware-storage/spring-vmware-storage-context.xml
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
deleted file mode 100644
index 23b32a3..0000000
--- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.cloudstack.storage.motion;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.MigrateWithStorageAnswer;
-import com.cloud.agent.api.MigrateWithStorageCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class VmwareStorageMotionStrategy implements DataMotionStrategy {
-    private static final Logger s_logger = Logger.getLogger(VmwareStorageMotionStrategy.class);
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    VolumeDao volDao;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    PrimaryDataStoreDao storagePoolDao;
-    @Inject
-    VMInstanceDao instanceDao;
-
-    @Override
-    public StrategyPriority canHandle(DataObject srcData, DataObject destData) {
-        return StrategyPriority.CANT_HANDLE;
-    }
-
-    @Override
-    public StrategyPriority canHandle(Map<VolumeInfo, DataStore> volumeMap, Host srcHost, Host destHost) {
-        if (srcHost.getHypervisorType() == HypervisorType.VMware && destHost.getHypervisorType() == HypervisorType.VMware) {
-            s_logger.debug(this.getClass() + " can handle the request because the hosts have VMware hypervisor");
-            return StrategyPriority.HYPERVISOR;
-        }
-        return StrategyPriority.CANT_HANDLE;
-    }
-
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
-        Answer answer = null;
-        String errMsg = null;
-        try {
-            VMInstanceVO instance = instanceDao.findById(vmTo.getId());
-            if (instance != null) {
-                if (srcHost.getClusterId().equals(destHost.getClusterId())) {
-                    answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap);
-                } else {
-                    answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap);
-                }
-            } else {
-                throw new CloudRuntimeException("Unsupported operation requested for moving data.");
-            }
-        } catch (Exception e) {
-            s_logger.error("copy failed", e);
-            errMsg = e.toString();
-        }
-
-        CopyCommandResult result = new CopyCommandResult(null, answer);
-        result.setResult(errMsg);
-        callback.complete(result);
-    }
-
-    private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map<VolumeInfo, DataStore> volumeToPool)
-            throws AgentUnavailableException {
-
-        // Initiate migration of a virtual machine with it's volumes.
-        try {
-            List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerto = new ArrayList<Pair<VolumeTO, StorageFilerTO>>();
-            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
-                VolumeInfo volume = entry.getKey();
-                VolumeTO volumeTo = new VolumeTO(volume, storagePoolDao.findById(volume.getPoolId()));
-                StorageFilerTO filerTo = new StorageFilerTO((StoragePool)entry.getValue());
-                volumeToFilerto.add(new Pair<VolumeTO, StorageFilerTO>(volumeTo, filerTo));
-            }
-
-            // Migration across cluster needs to be done in three phases.
-            // 1. Send a migrate command to source resource to initiate migration
-            //      Run validations against target!!
-            // 2. Complete the process. Update the volume details.
-            MigrateWithStorageCommand migrateWithStorageCmd = new MigrateWithStorageCommand(to, volumeToFilerto, destHost.getGuid());
-            MigrateWithStorageAnswer migrateWithStorageAnswer = (MigrateWithStorageAnswer)agentMgr.send(srcHost.getId(), migrateWithStorageCmd);
-            if (migrateWithStorageAnswer == null) {
-                s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed.");
-                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
-            } else if (!migrateWithStorageAnswer.getResult()) {
-                s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + migrateWithStorageAnswer.getDetails());
-                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost + ". " + migrateWithStorageAnswer.getDetails());
-            } else {
-                // Update the volume details after migration.
-                updateVolumesAfterMigration(volumeToPool, migrateWithStorageAnswer.getVolumeTos());
-            }
-            s_logger.debug("Storage migration of VM " + vm.getInstanceName() + " completed successfully. Migrated to host " + destHost.getName());
-
-            return migrateWithStorageAnswer;
-        } catch (OperationTimedoutException e) {
-            s_logger.error("Error while migrating vm " + vm + " to host " + destHost, e);
-            throw new AgentUnavailableException("Operation timed out on storage motion for " + vm, destHost.getId());
-        }
-    }
-
-    private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map<VolumeInfo, DataStore> volumeToPool)
-            throws AgentUnavailableException {
-
-        // Initiate migration of a virtual machine with it's volumes.
-        try {
-            List<Pair<VolumeTO, StorageFilerTO>> volumeToFilerto = new ArrayList<Pair<VolumeTO, StorageFilerTO>>();
-            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
-                VolumeInfo volume = entry.getKey();
-                VolumeTO volumeTo = new VolumeTO(volume, storagePoolDao.findById(volume.getPoolId()));
-                StorageFilerTO filerTo = new StorageFilerTO((StoragePool)entry.getValue());
-                volumeToFilerto.add(new Pair<VolumeTO, StorageFilerTO>(volumeTo, filerTo));
-            }
-
-            MigrateWithStorageCommand command = new MigrateWithStorageCommand(to, volumeToFilerto, destHost.getGuid());
-            MigrateWithStorageAnswer answer = (MigrateWithStorageAnswer)agentMgr.send(srcHost.getId(), command);
-            if (answer == null) {
-                s_logger.error("Migration with storage of vm " + vm + " failed.");
-                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost);
-            } else if (!answer.getResult()) {
-                s_logger.error("Migration with storage of vm " + vm + " failed. Details: " + answer.getDetails());
-                throw new CloudRuntimeException("Error while migrating the vm " + vm + " to host " + destHost + ". " + answer.getDetails());
-            } else {
-                // Update the volume details after migration.
-                updateVolumesAfterMigration(volumeToPool, answer.getVolumeTos());
-            }
-
-            return answer;
-        } catch (OperationTimedoutException e) {
-            s_logger.error("Error while migrating vm " + vm + " to host " + destHost, e);
-            throw new AgentUnavailableException("Operation timed out on storage motion for " + vm, destHost.getId());
-        }
-    }
-
-    private void updateVolumesAfterMigration(Map<VolumeInfo, DataStore> volumeToPool, List<VolumeObjectTO> volumeTos) {
-        for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
-            boolean updated = false;
-            VolumeInfo volume = entry.getKey();
-            StoragePool pool = (StoragePool)entry.getValue();
-            for (VolumeObjectTO volumeTo : volumeTos) {
-                if (volume.getId() == volumeTo.getId()) {
-                    VolumeVO volumeVO = volDao.findById(volume.getId());
-                    Long oldPoolId = volumeVO.getPoolId();
-                    volumeVO.setPath(volumeTo.getPath());
-                    if (volumeTo.getChainInfo() != null) {
-                        volumeVO.setChainInfo(volumeTo.getChainInfo());
-                    }
-                    volumeVO.setLastPoolId(oldPoolId);
-                    volumeVO.setFolder(pool.getPath());
-                    volumeVO.setPodId(pool.getPodId());
-                    volumeVO.setPoolId(pool.getId());
-                    volDao.update(volume.getId(), volumeVO);
-                    updated = true;
-                    break;
-                }
-            }
-            if (!updated) {
-                s_logger.error("Volume path wasn't updated for volume " + volume + " after it was migrated.");
-            }
-        }
-    }
-}
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/guru/VMwareGuruTest.java
similarity index 100%
rename from plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java
rename to plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/guru/VMwareGuruTest.java
diff --git a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
new file mode 100644
index 0000000..eb04139
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -0,0 +1,498 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.hypervisor.vmware;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.api.query.dao.TemplateJoinDao;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.cluster.dao.ManagementServerHostPeerDao;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.ClusterVSMMapDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.event.dao.EventDao;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.hypervisor.vmware.dao.LegacyZoneDao;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
+import com.cloud.hypervisor.vmware.manager.VmwareManagerImpl;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
+import com.cloud.org.Cluster.ClusterType;
+import com.cloud.org.Managed.ManagedState;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.storage.ImageStoreDetailsUtil;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.dao.UserVmCloneSettingDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+@PrepareForTest({ComponentContext.class, ApplicationContext.class})
+public class VmwareDatacenterApiUnitTest {
+
+    @Inject
+    VmwareDatacenterService _vmwareDatacenterService;
+
+    @Inject
+    DataCenterDao _dcDao;
+
+    @Inject
+    HostPodDao _podDao;
+
+    @Inject
+    VmwareDatacenterDao _vmwareDcDao;
+
+    @Inject
+    VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
+
+    @Inject
+    ClusterDao _clusterDao;
+
+    @Inject
+    ClusterDetailsDao _clusterDetailsDao;
+
+    @Inject
+    ConfigurationDao _configDao;
+
+    @Inject
+    AccountDao _accountDao;
+
+    @Inject
+    AccountManager _acctMgr;
+
+    long zoneId;
+    long podId;
+    long clusterId;
+    long vmwareDcId;
+    private static long domainId = 5L;
+    private static String vmwareDcName = "dc";
+    private static String clusterName = "cluster";
+    private static String vCenterHost = "10.1.1.100";
+    private static String url = "http://" + vCenterHost + "/" + vmwareDcName + "/" + clusterName;
+    private static String user = "administrator";
+    private static String password = "password";
+    private static String guid = vmwareDcName + "@" + vCenterHost;
+
+    private static VmwareDatacenterVO dc;
+    private static List<VmwareDatacenterVO> vmwareDcs;
+    private static ClusterVO cluster;
+    private static VmwareDatacenterZoneMapVO dcZoneMap;
+    private static List<ClusterVO> clusterList;
+    private static ClusterDetailsVO clusterDetails;
+
+    @Mock
+    private static AddVmwareDcCmd addCmd;
+    @Mock
+    private static RemoveVmwareDcCmd removeCmd;
+
+    @Before
+    public void testSetUp() {
+        Mockito.when(_configDao.isPremium()).thenReturn(true);
+        ComponentContext.initComponentsLifeCycle();
+        MockitoAnnotations.initMocks(this);
+
+        DataCenterVO zone =
+            new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
+                true, null, null);
+        zoneId = 1L;
+
+        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), zoneId, "192.168.56.1", "192.168.56.0/24", 8, "test");
+        podId = 1L;
+
+        AccountVO acct = new AccountVO(200L);
+        acct.setType(Account.ACCOUNT_TYPE_ADMIN);
+        acct.setAccountName("admin");
+        acct.setDomainId(domainId);
+
+        UserVO user1 = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
+
+        CallContext.register(user1, acct);
+
+        when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(acct);
+
+        dc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, user, password);
+        vmwareDcs = new ArrayList<VmwareDatacenterVO>();
+        vmwareDcs.add(dc);
+        vmwareDcId = dc.getId();
+
+        cluster = new ClusterVO(zone.getId(), pod.getId(), "vmwarecluster");
+        cluster.setHypervisorType(HypervisorType.VMware.toString());
+        cluster.setClusterType(ClusterType.ExternalManaged);
+        cluster.setManagedState(ManagedState.Managed);
+        clusterId = 1L;
+        clusterList = new ArrayList<ClusterVO>();
+        clusterList.add(cluster);
+
+        clusterDetails = new ClusterDetailsVO(clusterId, "url", url);
+
+        dcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDcId);
+
+        Mockito.when(_dcDao.persist(Matchers.any(DataCenterVO.class))).thenReturn(zone);
+        Mockito.when(_dcDao.findById(1L)).thenReturn(zone);
+        Mockito.when(_podDao.persist(Matchers.any(HostPodVO.class))).thenReturn(pod);
+        Mockito.when(_podDao.findById(1L)).thenReturn(pod);
+        Mockito.when(_clusterDao.persist(Matchers.any(ClusterVO.class))).thenReturn(cluster);
+        Mockito.when(_clusterDao.findById(1L)).thenReturn(cluster);
+        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(null);
+        Mockito.when(_clusterDao.expunge(1L)).thenReturn(true);
+        Mockito.when(_clusterDetailsDao.persist(Matchers.any(ClusterDetailsVO.class))).thenReturn(clusterDetails);
+        Mockito.when(_clusterDetailsDao.expunge(1L)).thenReturn(true);
+        Mockito.when(_vmwareDcDao.persist(Matchers.any(VmwareDatacenterVO.class))).thenReturn(dc);
+        Mockito.when(_vmwareDcDao.findById(1L)).thenReturn(null);
+        Mockito.when(_vmwareDcDao.expunge(1L)).thenReturn(true);
+        Mockito.when(_vmwareDcDao.getVmwareDatacenterByNameAndVcenter(vmwareDcName, vCenterHost)).thenReturn(null);
+        Mockito.when(_vmwareDcZoneMapDao.persist(Matchers.any(VmwareDatacenterZoneMapVO.class))).thenReturn(dcZoneMap);
+        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(null);
+        Mockito.when(_vmwareDcZoneMapDao.expunge(1L)).thenReturn(true);
+        Mockito.when(addCmd.getZoneId()).thenReturn(1L);
+        Mockito.when(addCmd.getVcenter()).thenReturn(vCenterHost);
+        Mockito.when(addCmd.getUsername()).thenReturn(user);
+        Mockito.when(addCmd.getPassword()).thenReturn(password);
+        Mockito.when(addCmd.getName()).thenReturn(vmwareDcName);
+        Mockito.when(removeCmd.getZoneId()).thenReturn(1L);
+    }
+
+    @After
+    public void tearDown() {
+        CallContext.unregister();
+    }
+
+    //@Test(expected = InvalidParameterValueException.class)
+    public void testAddVmwareDcToInvalidZone() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(addCmd.getZoneId()).thenReturn(2L);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = ResourceInUseException.class)
+    public void testAddVmwareDcToZoneWithClusters() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(clusterList);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testRemoveVmwareDcToInvalidZone() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(removeCmd.getZoneId()).thenReturn(2L);
+        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
+    }
+
+    @Test(expected = ResourceInUseException.class)
+    public void testRemoveVmwareDcToZoneWithClusters() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(clusterList);
+        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
+    }
+
+    //@Test(expected = ResourceInUseException.class)
+    public void testAddVmwareDcToZoneWithVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(_vmwareDcDao.getVmwareDatacenterByNameAndVcenter(vmwareDcName, vCenterHost)).thenReturn(vmwareDcs);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = InvalidParameterValueException.class)
+    public void testAddVmwareDcWithNullUser() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(addCmd.getUsername()).thenReturn(null);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = InvalidParameterValueException.class)
+    public void testAddVmwareDcWithNullPassword() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(addCmd.getPassword()).thenReturn(null);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = InvalidParameterValueException.class)
+    public void testAddVmwareDcWithNullUrl() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(addCmd.getVcenter()).thenReturn(null);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = InvalidParameterValueException.class)
+    public void testAddVmwareDcWithNullDcName() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(addCmd.getName()).thenReturn(null);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    //@Test(expected = CloudRuntimeException.class)
+    public void testReAddVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(dcZoneMap);
+        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testRemoveNonexistingVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
+        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(null);
+        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {VmwareManagerImpl.class},
+                   includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
+                   useDefaultFilters = false)
+    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        @Bean
+        public AccountDao accountDao() {
+            return Mockito.mock(AccountDao.class);
+        }
+
+        @Bean
+        public AccountService accountService() {
+            return Mockito.mock(AccountService.class);
+        }
+
+        @Bean
+        public DataCenterDao dataCenterDao() {
+            return Mockito.mock(DataCenterDao.class);
+        }
+
+        @Bean
+        public HostPodDao hostPodDao() {
+            return Mockito.mock(HostPodDao.class);
+        }
+
+        @Bean
+        public ClusterDao clusterDao() {
+            return Mockito.mock(ClusterDao.class);
+        }
+
+        @Bean
+        public ClusterDetailsDao clusterDetailsDao() {
+            return Mockito.mock(ClusterDetailsDao.class);
+        }
+
+        @Bean
+        public VmwareDatacenterDao vmwareDatacenterDao() {
+            return Mockito.mock(VmwareDatacenterDao.class);
+        }
+
+        @Bean
+        public VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao() {
+            return Mockito.mock(VmwareDatacenterZoneMapDao.class);
+        }
+
+        @Bean
+        public AgentManager agentManager() {
+            return Mockito.mock(AgentManager.class);
+        }
+
+        @Bean
+        public HostDao hostDao() {
+            return Mockito.mock(HostDao.class);
+        }
+
+        @Bean
+        public HostDetailsDao hostDetailsDao() {
+            return Mockito.mock(HostDetailsDao.class);
+        }
+
+        @Bean
+        public NetworkModel networkModel() {
+            return Mockito.mock(NetworkModel.class);
+        }
+
+        @Bean
+        public ClusterManager clusterManager() {
+            return Mockito.mock(ClusterManager.class);
+        }
+
+        @Bean
+        public CommandExecLogDao commandExecLogDao() {
+            return Mockito.mock(CommandExecLogDao.class);
+        }
+
+        @Bean
+        public CiscoNexusVSMDeviceDao ciscoNexusVSMDeviceDao() {
+            return Mockito.mock(CiscoNexusVSMDeviceDao.class);
+        }
+
+        @Bean
+        public ClusterVSMMapDao clusterVSMMapDao() {
+            return Mockito.mock(ClusterVSMMapDao.class);
+        }
+
+        @Bean
+        public LegacyZoneDao legacyZoneDao() {
+            return Mockito.mock(LegacyZoneDao.class);
+        }
+
+        @Bean
+        public ManagementServerHostPeerDao managementServerHostPeerDao() {
+            return Mockito.mock(ManagementServerHostPeerDao.class);
+        }
+
+        @Bean
+        public ConfigurationDao configurationDao() {
+            return Mockito.mock(ConfigurationDao.class);
+        }
+
+        @Bean
+        public ConfigurationServer configurationServer() {
+            return Mockito.mock(ConfigurationServer.class);
+        }
+
+        @Bean
+        public HypervisorCapabilitiesDao hypervisorCapabilitiesDao() {
+            return Mockito.mock(HypervisorCapabilitiesDao.class);
+        }
+
+        @Bean
+        public AccountManager accountManager() {
+            return Mockito.mock(AccountManager.class);
+        }
+
+        @Bean
+        public EventDao eventDao() {
+            return Mockito.mock(EventDao.class);
+        }
+
+        @Bean
+        public UserVmDao userVMDao() {
+            return Mockito.mock(UserVmDao.class);
+        }
+
+        public AddVmwareDcCmd addVmwareDatacenterCmd() {
+            return Mockito.mock(AddVmwareDcCmd.class);
+        }
+
+        public RemoveVmwareDcCmd removeVmwareDcCmd() {
+            return Mockito.mock(RemoveVmwareDcCmd.class);
+        }
+
+        @Bean
+        public DataStoreManager dataStoreManager() {
+            return Mockito.mock(DataStoreManager.class);
+        }
+
+        @Bean
+        public ImageStoreDetailsUtil imageStoreDetailsUtil() {
+            return Mockito.mock(ImageStoreDetailsUtil.class);
+        }
+
+        //Mocks for ImageStoreDetailsUtil
+        @Bean
+        public ImageStoreDao imageStoreDao() {
+            return Mockito.mock(ImageStoreDao.class);
+        }
+
+        @Bean
+        public ImageStoreDetailsDao imageStoreDetailsDao() {
+            return Mockito.mock(ImageStoreDetailsDao.class);
+        }
+
+        @Bean
+        public VMTemplatePoolDao templateDataStoreDao() {
+            return Mockito.mock(VMTemplatePoolDao.class);
+        }
+
+        @Bean
+        public TemplateJoinDao templateDao() {
+            return Mockito.mock(TemplateJoinDao.class);
+        }
+
+        @Bean
+        public VMInstanceDao vmInstanceDao() {
+            return Mockito.mock(VMInstanceDao.class);
+        }
+
+        @Bean
+        public UserVmCloneSettingDao cloneSettingDao() {
+            return Mockito.mock(UserVmCloneSettingDao.class);
+        }
+
+        @Bean
+        public PrimaryDataStoreDao primaryStorageDao() {
+            return Mockito.mock(PrimaryDataStoreDao.class);
+        }
+
+        @Bean
+        public TemplateManager templateManager() {
+            return Mockito.mock(TemplateManager.class);
+        }
+
+        public static class Library implements TypeFilter {
+
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java
new file mode 100644
index 0000000..499ed24
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java
@@ -0,0 +1,118 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.hypervisor.vmware.manager;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.vmware.VmwareDatacenter;
+import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
+import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
+import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VmwareManagerImplTest {
+
+    @Spy
+    @InjectMocks
+    private VmwareManagerImpl vmwareManager;
+
+    @Mock
+    private UpdateVmwareDcCmd updateVmwareDcCmd;
+    @Mock
+    private VmwareDatacenterDao vmwareDcDao;
+    @Mock
+    private VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao;
+    @Mock
+    private ClusterDao clusterDao;
+    @Mock
+    private ClusterDetailsDao clusterDetailsDao;
+    @Mock
+    private HostDao hostDao;
+    @Mock
+    private HostDetailsDao hostDetailsDao;
+    @Mock
+    private Map<String, String> clusterDetails;
+    @Mock
+    private Map<String, String> hostDetails;
+
+    @Before
+    public void beforeTest() {
+        VmwareDatacenterZoneMapVO vmwareDatacenterZoneMap = new VmwareDatacenterZoneMapVO();
+        vmwareDatacenterZoneMap.setZoneId(1);
+        vmwareDatacenterZoneMap.setVmwareDcId(1);
+        VmwareDatacenterVO vmwareDatacenterVO = new VmwareDatacenterVO(1, "some-guid", "some-name", "10.1.1.1", "username", "password");
+
+        Mockito.doReturn(vmwareDatacenterZoneMap).when(vmwareDatacenterZoneMapDao).findByZoneId(Mockito.anyLong());
+        Mockito.doReturn(vmwareDatacenterVO).when(vmwareDcDao).findById(Mockito.anyLong());
+        Mockito.doReturn(1L).when(updateVmwareDcCmd).getZoneId();
+    }
+
+    @Test
+    public void updateVmwareDatacenterNoUpdate() {
+        VmwareDatacenter vmwareDatacenter = vmwareManager.updateVmwareDatacenter(updateVmwareDcCmd);
+        Assert.assertNull(vmwareDatacenter);
+    }
+
+    @Test
+    public void updateVmwareDatacenterNormalUpdate() {
+        Mockito.doReturn("some-new-username").when(updateVmwareDcCmd).getUsername();
+        Mockito.doReturn("some-new-password").when(updateVmwareDcCmd).getPassword();
+        Mockito.doReturn("some-new-vcenter-address").when(updateVmwareDcCmd).getVcenter();
+        Mockito.doReturn(true).when(updateVmwareDcCmd).isRecursive();
+        Mockito.doReturn(true).when(vmwareDcDao).update(Mockito.anyLong(), Mockito.any(VmwareDatacenterVO.class));
+        Mockito.doReturn(Collections.singletonList(new ClusterVO(1, 1, "some-cluster"))).when(clusterDao).listByDcHyType(Mockito.anyLong(), Mockito.anyString());
+        Mockito.doReturn(clusterDetails).when(clusterDetailsDao).findDetails(Mockito.anyLong());
+
+        final HostVO host = new HostVO("someGuid");
+        host.setDataCenterId(1);
+        host.setHypervisorType(Hypervisor.HypervisorType.VMware);
+        Mockito.doReturn(Collections.singletonList(host)).when(hostDao).listAllHostsByZoneAndHypervisorType(Mockito.anyLong(), Mockito.any());
+        Mockito.doReturn(hostDetails).when(hostDetailsDao).findDetails(Mockito.anyLong());
+        Mockito.doReturn("some-old-guid").when(hostDetails).get("guid");
+        Mockito.doReturn(hostDetails).when(hostDetailsDao).findDetails(Mockito.anyLong());
+
+        final VmwareDatacenter vmwareDatacenter = vmwareManager.updateVmwareDatacenter(updateVmwareDcCmd);
+
+        Assert.assertEquals(vmwareDatacenter.getUser(), updateVmwareDcCmd.getUsername());
+        Assert.assertEquals(vmwareDatacenter.getPassword(), updateVmwareDcCmd.getPassword());
+        Mockito.verify(clusterDetails, Mockito.times(2)).put(Mockito.anyString(), Mockito.anyString());
+        Mockito.verify(clusterDetailsDao, Mockito.times(1)).persist(Mockito.anyLong(), Mockito.anyMapOf(String.class, String.class));
+        Mockito.verify(hostDetails, Mockito.times(3)).put(Mockito.anyString(), Mockito.anyString());
+        Mockito.verify(hostDetailsDao, Mockito.times(1)).persist(Mockito.anyLong(), Mockito.anyMapOf(String.class, String.class));
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
similarity index 100%
rename from plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
rename to plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
diff --git a/plugins/hypervisors/vmware/src/test/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java b/plugins/hypervisors/vmware/src/test/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java
new file mode 100644
index 0000000..4cc3a77
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/test/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java
@@ -0,0 +1,279 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.motion;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.MigrateWithStorageAnswer;
+import com.cloud.agent.api.MigrateWithStorageCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcContext;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class VmwareStorageMotionStrategyTest {
+
+    @Inject
+    VmwareStorageMotionStrategy strategy = new VmwareStorageMotionStrategy();
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    VolumeDao volDao;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    PrimaryDataStoreDao storagePoolDao;
+    @Inject
+    VMInstanceDao instanceDao;
+    @Inject
+    private HostDao hostDao;
+
+    CopyCommandResult result;
+
+    @BeforeClass
+    public static void setUp() throws ConfigurationException {
+    }
+
+    @Before
+    public void testSetUp() {
+        ComponentContext.initComponentsLifeCycle();
+    }
+
+    @Test
+    public void testStrategyHandlesVmwareHosts() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getHypervisorType()).thenReturn(HypervisorType.VMware);
+        when(destHost.getHypervisorType()).thenReturn(HypervisorType.VMware);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost);
+        assertTrue("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR);
+    }
+
+    @Test
+    public void testStrategyDoesnotHandlesNonVmwareHosts() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
+        when(destHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost);
+        assertFalse("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR);
+    }
+
+    @Test
+    public void testMigrateWithinClusterSuccess() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getClusterId()).thenReturn(1L);
+        when(destHost.getClusterId()).thenReturn(1L);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        VirtualMachineTO to = mock(VirtualMachineTO.class);
+        when(to.getId()).thenReturn(6L);
+        VMInstanceVO instance = mock(VMInstanceVO.class);
+        when(instanceDao.findById(6L)).thenReturn(instance);
+
+        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
+        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
+
+        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
+        when(migAnswerMock.getResult()).thenReturn(true);
+        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
+
+        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
+        assertTrue("Migration within cluster isn't successful.", result.isSuccess());
+    }
+
+    @Test
+    public void testMigrateWithinClusterFailure() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getClusterId()).thenReturn(1L);
+        when(destHost.getClusterId()).thenReturn(1L);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        VirtualMachineTO to = mock(VirtualMachineTO.class);
+        when(to.getId()).thenReturn(6L);
+        VMInstanceVO instance = mock(VMInstanceVO.class);
+        when(instanceDao.findById(6L)).thenReturn(instance);
+
+        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
+        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
+
+        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
+        when(migAnswerMock.getResult()).thenReturn(false);
+        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
+
+        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
+        assertFalse("Migration within cluster didn't fail.", result.isSuccess());
+    }
+
+    @Test
+    public void testMigrateAcrossClusterSuccess() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getClusterId()).thenReturn(1L);
+        when(destHost.getClusterId()).thenReturn(2L);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        VirtualMachineTO to = mock(VirtualMachineTO.class);
+        when(to.getId()).thenReturn(6L);
+        VMInstanceVO instance = mock(VMInstanceVO.class);
+        when(instanceDao.findById(6L)).thenReturn(instance);
+
+        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
+        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
+
+        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
+        when(migAnswerMock.getResult()).thenReturn(true);
+        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
+
+        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
+        assertTrue("Migration across cluster isn't successful.", result.isSuccess());
+    }
+
+    @Test
+    public void testMigrateAcrossClusterFailure() throws Exception {
+        Host srcHost = mock(Host.class);
+        Host destHost = mock(Host.class);
+        when(srcHost.getClusterId()).thenReturn(1L);
+        when(destHost.getClusterId()).thenReturn(2L);
+        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
+        VirtualMachineTO to = mock(VirtualMachineTO.class);
+        when(to.getId()).thenReturn(6L);
+        VMInstanceVO instance = mock(VMInstanceVO.class);
+        when(instanceDao.findById(6L)).thenReturn(instance);
+
+        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
+        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
+        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
+
+        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
+        when(migAnswerMock.getResult()).thenReturn(false);
+        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
+
+        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
+        assertFalse("Migration across cluster didn't fail.", result.isSuccess());
+    }
+
+    private class MockContext<T> extends AsyncRpcContext<T> {
+        /**
+         * @param callback
+         */
+        public MockContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future, Map<VolumeInfo, DataStore> volumeToPool) {
+            super(callback);
+        }
+    }
+
+    protected Void mockCallBack(AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> callback, MockContext<CommandResult> context) {
+        result = callback.getResult();
+        return null;
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {VmwareStorageMotionStrategy.class},
+                   includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
+                   useDefaultFilters = false)
+    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        @Bean
+        public VolumeDao volumeDao() {
+            return Mockito.mock(VolumeDao.class);
+        }
+
+        @Bean
+        public VolumeDataFactory volumeDataFactory() {
+            return Mockito.mock(VolumeDataFactory.class);
+        }
+
+        @Bean
+        public PrimaryDataStoreDao primaryDataStoreDao() {
+            return Mockito.mock(PrimaryDataStoreDao.class);
+        }
+
+        @Bean
+        public VMInstanceDao vmInstanceDao() {
+            return Mockito.mock(VMInstanceDao.class);
+        }
+
+        @Bean
+        public AgentManager agentManager() {
+            return Mockito.mock(AgentManager.class);
+        }
+
+        @Bean
+        public HostDao hostDao() {
+            return Mockito.mock(HostDao.class);
+        }
+
+        public static class Library implements TypeFilter {
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
deleted file mode 100644
index e835a0b..0000000
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ /dev/null
@@ -1,492 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.hypervisor.vmware;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.api.query.dao.TemplateJoinDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.cluster.dao.ManagementServerHostPeerDao;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.ClusterVSMMapDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.event.dao.EventDao;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.hypervisor.vmware.dao.LegacyZoneDao;
-import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
-import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
-import com.cloud.hypervisor.vmware.manager.VmwareManagerImpl;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
-import com.cloud.org.Cluster.ClusterType;
-import com.cloud.org.Managed.ManagedState;
-import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.storage.ImageStoreDetailsUtil;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.AccountVO;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.dao.UserVmCloneSettingDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.test.utils.SpringUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import javax.inject.Inject;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import static org.mockito.Mockito.when;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-@PrepareForTest({ComponentContext.class, ApplicationContext.class})
-public class VmwareDatacenterApiUnitTest {
-
-    @Inject
-    VmwareDatacenterService _vmwareDatacenterService;
-
-    @Inject
-    DataCenterDao _dcDao;
-
-    @Inject
-    HostPodDao _podDao;
-
-    @Inject
-    VmwareDatacenterDao _vmwareDcDao;
-
-    @Inject
-    VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
-
-    @Inject
-    ClusterDao _clusterDao;
-
-    @Inject
-    ClusterDetailsDao _clusterDetailsDao;
-
-    @Inject
-    ConfigurationDao _configDao;
-
-    @Inject
-    AccountDao _accountDao;
-
-    @Inject
-    AccountManager _acctMgr;
-
-    long zoneId;
-    long podId;
-    long clusterId;
-    long vmwareDcId;
-    private static long domainId = 5L;
-    private static String vmwareDcName = "dc";
-    private static String clusterName = "cluster";
-    private static String vCenterHost = "10.1.1.100";
-    private static String url = "http://" + vCenterHost + "/" + vmwareDcName + "/" + clusterName;
-    private static String user = "administrator";
-    private static String password = "password";
-    private static String guid = vmwareDcName + "@" + vCenterHost;
-
-    private static VmwareDatacenterVO dc;
-    private static List<VmwareDatacenterVO> vmwareDcs;
-    private static ClusterVO cluster;
-    private static VmwareDatacenterZoneMapVO dcZoneMap;
-    private static List<ClusterVO> clusterList;
-    private static ClusterDetailsVO clusterDetails;
-
-    @Mock
-    private static AddVmwareDcCmd addCmd;
-    @Mock
-    private static RemoveVmwareDcCmd removeCmd;
-
-    @Before
-    public void testSetUp() {
-        Mockito.when(_configDao.isPremium()).thenReturn(true);
-        ComponentContext.initComponentsLifeCycle();
-        MockitoAnnotations.initMocks(this);
-
-        DataCenterVO zone =
-            new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true,
-                true, null, null);
-        zoneId = 1L;
-
-        HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), zoneId, "192.168.56.1", "192.168.56.0/24", 8, "test");
-        podId = 1L;
-
-        AccountVO acct = new AccountVO(200L);
-        acct.setType(Account.ACCOUNT_TYPE_ADMIN);
-        acct.setAccountName("admin");
-        acct.setDomainId(domainId);
-
-        UserVO user1 = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
-
-        CallContext.register(user1, acct);
-
-        when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(acct);
-
-        dc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, user, password);
-        vmwareDcs = new ArrayList<VmwareDatacenterVO>();
-        vmwareDcs.add(dc);
-        vmwareDcId = dc.getId();
-
-        cluster = new ClusterVO(zone.getId(), pod.getId(), "vmwarecluster");
-        cluster.setHypervisorType(HypervisorType.VMware.toString());
-        cluster.setClusterType(ClusterType.ExternalManaged);
-        cluster.setManagedState(ManagedState.Managed);
-        clusterId = 1L;
-        clusterList = new ArrayList<ClusterVO>();
-        clusterList.add(cluster);
-
-        clusterDetails = new ClusterDetailsVO(clusterId, "url", url);
-
-        dcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDcId);
-
-        Mockito.when(_dcDao.persist(Matchers.any(DataCenterVO.class))).thenReturn(zone);
-        Mockito.when(_dcDao.findById(1L)).thenReturn(zone);
-        Mockito.when(_podDao.persist(Matchers.any(HostPodVO.class))).thenReturn(pod);
-        Mockito.when(_podDao.findById(1L)).thenReturn(pod);
-        Mockito.when(_clusterDao.persist(Matchers.any(ClusterVO.class))).thenReturn(cluster);
-        Mockito.when(_clusterDao.findById(1L)).thenReturn(cluster);
-        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(null);
-        Mockito.when(_clusterDao.expunge(1L)).thenReturn(true);
-        Mockito.when(_clusterDetailsDao.persist(Matchers.any(ClusterDetailsVO.class))).thenReturn(clusterDetails);
-        Mockito.when(_clusterDetailsDao.expunge(1L)).thenReturn(true);
-        Mockito.when(_vmwareDcDao.persist(Matchers.any(VmwareDatacenterVO.class))).thenReturn(dc);
-        Mockito.when(_vmwareDcDao.findById(1L)).thenReturn(null);
-        Mockito.when(_vmwareDcDao.expunge(1L)).thenReturn(true);
-        Mockito.when(_vmwareDcDao.getVmwareDatacenterByNameAndVcenter(vmwareDcName, vCenterHost)).thenReturn(null);
-        Mockito.when(_vmwareDcZoneMapDao.persist(Matchers.any(VmwareDatacenterZoneMapVO.class))).thenReturn(dcZoneMap);
-        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(null);
-        Mockito.when(_vmwareDcZoneMapDao.expunge(1L)).thenReturn(true);
-        Mockito.when(addCmd.getZoneId()).thenReturn(1L);
-        Mockito.when(addCmd.getVcenter()).thenReturn(vCenterHost);
-        Mockito.when(addCmd.getUsername()).thenReturn(user);
-        Mockito.when(addCmd.getPassword()).thenReturn(password);
-        Mockito.when(addCmd.getName()).thenReturn(vmwareDcName);
-        Mockito.when(removeCmd.getZoneId()).thenReturn(1L);
-    }
-
-    @After
-    public void tearDown() {
-        CallContext.unregister();
-    }
-
-    //@Test(expected = InvalidParameterValueException.class)
-    public void testAddVmwareDcToInvalidZone() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(addCmd.getZoneId()).thenReturn(2L);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = ResourceInUseException.class)
-    public void testAddVmwareDcToZoneWithClusters() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(clusterList);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testRemoveVmwareDcToInvalidZone() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(removeCmd.getZoneId()).thenReturn(2L);
-        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
-    }
-
-    @Test(expected = ResourceInUseException.class)
-    public void testRemoveVmwareDcToZoneWithClusters() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(_clusterDao.listByZoneId(1L)).thenReturn(clusterList);
-        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
-    }
-
-    //@Test(expected = ResourceInUseException.class)
-    public void testAddVmwareDcToZoneWithVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(_vmwareDcDao.getVmwareDatacenterByNameAndVcenter(vmwareDcName, vCenterHost)).thenReturn(vmwareDcs);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = InvalidParameterValueException.class)
-    public void testAddVmwareDcWithNullUser() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(addCmd.getUsername()).thenReturn(null);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = InvalidParameterValueException.class)
-    public void testAddVmwareDcWithNullPassword() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(addCmd.getPassword()).thenReturn(null);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = InvalidParameterValueException.class)
-    public void testAddVmwareDcWithNullUrl() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(addCmd.getVcenter()).thenReturn(null);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = InvalidParameterValueException.class)
-    public void testAddVmwareDcWithNullDcName() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(addCmd.getName()).thenReturn(null);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    //@Test(expected = CloudRuntimeException.class)
-    public void testReAddVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(dcZoneMap);
-        _vmwareDatacenterService.addVmwareDatacenter(addCmd);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    public void testRemoveNonexistingVmwareDc() throws ResourceInUseException, IllegalArgumentException, DiscoveryException, Exception {
-        Mockito.when(_vmwareDcZoneMapDao.findByZoneId(1L)).thenReturn(null);
-        _vmwareDatacenterService.removeVmwareDatacenter(removeCmd);
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {VmwareManagerImpl.class},
-                   includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
-                   useDefaultFilters = false)
-    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public AccountDao accountDao() {
-            return Mockito.mock(AccountDao.class);
-        }
-
-        @Bean
-        public AccountService accountService() {
-            return Mockito.mock(AccountService.class);
-        }
-
-        @Bean
-        public DataCenterDao dataCenterDao() {
-            return Mockito.mock(DataCenterDao.class);
-        }
-
-        @Bean
-        public HostPodDao hostPodDao() {
-            return Mockito.mock(HostPodDao.class);
-        }
-
-        @Bean
-        public ClusterDao clusterDao() {
-            return Mockito.mock(ClusterDao.class);
-        }
-
-        @Bean
-        public ClusterDetailsDao clusterDetailsDao() {
-            return Mockito.mock(ClusterDetailsDao.class);
-        }
-
-        @Bean
-        public VmwareDatacenterDao vmwareDatacenterDao() {
-            return Mockito.mock(VmwareDatacenterDao.class);
-        }
-
-        @Bean
-        public VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao() {
-            return Mockito.mock(VmwareDatacenterZoneMapDao.class);
-        }
-
-        @Bean
-        public AgentManager agentManager() {
-            return Mockito.mock(AgentManager.class);
-        }
-
-        @Bean
-        public HostDao hostDao() {
-            return Mockito.mock(HostDao.class);
-        }
-
-        @Bean
-        public NetworkModel networkModel() {
-            return Mockito.mock(NetworkModel.class);
-        }
-
-        @Bean
-        public ClusterManager clusterManager() {
-            return Mockito.mock(ClusterManager.class);
-        }
-
-        @Bean
-        public CommandExecLogDao commandExecLogDao() {
-            return Mockito.mock(CommandExecLogDao.class);
-        }
-
-        @Bean
-        public CiscoNexusVSMDeviceDao ciscoNexusVSMDeviceDao() {
-            return Mockito.mock(CiscoNexusVSMDeviceDao.class);
-        }
-
-        @Bean
-        public ClusterVSMMapDao clusterVSMMapDao() {
-            return Mockito.mock(ClusterVSMMapDao.class);
-        }
-
-        @Bean
-        public LegacyZoneDao legacyZoneDao() {
-            return Mockito.mock(LegacyZoneDao.class);
-        }
-
-        @Bean
-        public ManagementServerHostPeerDao managementServerHostPeerDao() {
-            return Mockito.mock(ManagementServerHostPeerDao.class);
-        }
-
-        @Bean
-        public ConfigurationDao configurationDao() {
-            return Mockito.mock(ConfigurationDao.class);
-        }
-
-        @Bean
-        public ConfigurationServer configurationServer() {
-            return Mockito.mock(ConfigurationServer.class);
-        }
-
-        @Bean
-        public HypervisorCapabilitiesDao hypervisorCapabilitiesDao() {
-            return Mockito.mock(HypervisorCapabilitiesDao.class);
-        }
-
-        @Bean
-        public AccountManager accountManager() {
-            return Mockito.mock(AccountManager.class);
-        }
-
-        @Bean
-        public EventDao eventDao() {
-            return Mockito.mock(EventDao.class);
-        }
-
-        @Bean
-        public UserVmDao userVMDao() {
-            return Mockito.mock(UserVmDao.class);
-        }
-
-        public AddVmwareDcCmd addVmwareDatacenterCmd() {
-            return Mockito.mock(AddVmwareDcCmd.class);
-        }
-
-        public RemoveVmwareDcCmd removeVmwareDcCmd() {
-            return Mockito.mock(RemoveVmwareDcCmd.class);
-        }
-
-        @Bean
-        public DataStoreManager dataStoreManager() {
-            return Mockito.mock(DataStoreManager.class);
-        }
-
-        @Bean
-        public ImageStoreDetailsUtil imageStoreDetailsUtil() {
-            return Mockito.mock(ImageStoreDetailsUtil.class);
-        }
-
-        //Mocks for ImageStoreDetailsUtil
-        @Bean
-        public ImageStoreDao imageStoreDao() {
-            return Mockito.mock(ImageStoreDao.class);
-        }
-
-        @Bean
-        public ImageStoreDetailsDao imageStoreDetailsDao() {
-            return Mockito.mock(ImageStoreDetailsDao.class);
-        }
-
-        @Bean
-        public VMTemplatePoolDao templateDataStoreDao() {
-            return Mockito.mock(VMTemplatePoolDao.class);
-        }
-
-        @Bean
-        public TemplateJoinDao templateDao() {
-            return Mockito.mock(TemplateJoinDao.class);
-        }
-
-        @Bean
-        public VMInstanceDao vmInstanceDao() {
-            return Mockito.mock(VMInstanceDao.class);
-        }
-
-        @Bean
-        public UserVmCloneSettingDao cloneSettingDao() {
-            return Mockito.mock(UserVmCloneSettingDao.class);
-        }
-
-        @Bean
-        public PrimaryDataStoreDao primaryStorageDao() {
-            return Mockito.mock(PrimaryDataStoreDao.class);
-        }
-
-        @Bean
-        public TemplateManager templateManager() {
-            return Mockito.mock(TemplateManager.class);
-        }
-
-        public static class Library implements TypeFilter {
-
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-}
diff --git a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java b/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java
deleted file mode 100644
index e3cc2f6..0000000
--- a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.motion;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.async.AsyncRpcContext;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.test.utils.SpringUtils;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.MigrateWithStorageAnswer;
-import com.cloud.agent.api.MigrateWithStorageCommand;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class VmwareStorageMotionStrategyTest {
-
-    @Inject
-    VmwareStorageMotionStrategy strategy = new VmwareStorageMotionStrategy();
-    @Inject
-    AgentManager agentMgr;
-    @Inject
-    VolumeDao volDao;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    PrimaryDataStoreDao storagePoolDao;
-    @Inject
-    VMInstanceDao instanceDao;
-
-    CopyCommandResult result;
-
-    @BeforeClass
-    public static void setUp() throws ConfigurationException {
-    }
-
-    @Before
-    public void testSetUp() {
-        ComponentContext.initComponentsLifeCycle();
-    }
-
-    @Test
-    public void testStrategyHandlesVmwareHosts() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getHypervisorType()).thenReturn(HypervisorType.VMware);
-        when(destHost.getHypervisorType()).thenReturn(HypervisorType.VMware);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost);
-        assertTrue("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR);
-    }
-
-    @Test
-    public void testStrategyDoesnotHandlesNonVmwareHosts() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
-        when(destHost.getHypervisorType()).thenReturn(HypervisorType.XenServer);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        StrategyPriority canHandle = strategy.canHandle(volumeMap, srcHost, destHost);
-        assertFalse("The strategy is only supposed to handle vmware hosts", canHandle == StrategyPriority.HYPERVISOR);
-    }
-
-    @Test
-    public void testMigrateWithinClusterSuccess() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getClusterId()).thenReturn(1L);
-        when(destHost.getClusterId()).thenReturn(1L);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        VirtualMachineTO to = mock(VirtualMachineTO.class);
-        when(to.getId()).thenReturn(6L);
-        VMInstanceVO instance = mock(VMInstanceVO.class);
-        when(instanceDao.findById(6L)).thenReturn(instance);
-
-        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
-        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
-
-        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
-        when(migAnswerMock.getResult()).thenReturn(true);
-        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
-
-        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
-        assertTrue("Migration within cluster isn't successful.", result.isSuccess());
-    }
-
-    @Test
-    public void testMigrateWithinClusterFailure() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getClusterId()).thenReturn(1L);
-        when(destHost.getClusterId()).thenReturn(1L);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        VirtualMachineTO to = mock(VirtualMachineTO.class);
-        when(to.getId()).thenReturn(6L);
-        VMInstanceVO instance = mock(VMInstanceVO.class);
-        when(instanceDao.findById(6L)).thenReturn(instance);
-
-        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
-        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
-
-        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
-        when(migAnswerMock.getResult()).thenReturn(false);
-        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
-
-        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
-        assertFalse("Migration within cluster didn't fail.", result.isSuccess());
-    }
-
-    @Test
-    public void testMigrateAcrossClusterSuccess() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getClusterId()).thenReturn(1L);
-        when(destHost.getClusterId()).thenReturn(2L);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        VirtualMachineTO to = mock(VirtualMachineTO.class);
-        when(to.getId()).thenReturn(6L);
-        VMInstanceVO instance = mock(VMInstanceVO.class);
-        when(instanceDao.findById(6L)).thenReturn(instance);
-
-        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
-        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
-
-        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
-        when(migAnswerMock.getResult()).thenReturn(true);
-        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
-
-        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
-        assertTrue("Migration across cluster isn't successful.", result.isSuccess());
-    }
-
-    @Test
-    public void testMigrateAcrossClusterFailure() throws Exception {
-        Host srcHost = mock(Host.class);
-        Host destHost = mock(Host.class);
-        when(srcHost.getClusterId()).thenReturn(1L);
-        when(destHost.getClusterId()).thenReturn(2L);
-        Map<VolumeInfo, DataStore> volumeMap = new HashMap<VolumeInfo, DataStore>();
-        VirtualMachineTO to = mock(VirtualMachineTO.class);
-        when(to.getId()).thenReturn(6L);
-        VMInstanceVO instance = mock(VMInstanceVO.class);
-        when(instanceDao.findById(6L)).thenReturn(instance);
-
-        MockContext<CommandResult> context = new MockContext<CommandResult>(null, null, volumeMap);
-        AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
-        caller.setCallback(caller.getTarget().mockCallBack(null, null)).setContext(context);
-
-        MigrateWithStorageAnswer migAnswerMock = mock(MigrateWithStorageAnswer.class);
-        when(migAnswerMock.getResult()).thenReturn(false);
-        when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock);
-
-        strategy.copyAsync(volumeMap, to, srcHost, destHost, caller);
-        assertFalse("Migration across cluster didn't fail.", result.isSuccess());
-    }
-
-    private class MockContext<T> extends AsyncRpcContext<T> {
-        /**
-         * @param callback
-         */
-        public MockContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<CommandResult> future, Map<VolumeInfo, DataStore> volumeToPool) {
-            super(callback);
-        }
-    }
-
-    protected Void mockCallBack(AsyncCallbackDispatcher<VmwareStorageMotionStrategyTest, CopyCommandResult> callback, MockContext<CommandResult> context) {
-        result = callback.getResult();
-        return null;
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {VmwareStorageMotionStrategy.class},
-                   includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)},
-                   useDefaultFilters = false)
-    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public VolumeDao volumeDao() {
-            return Mockito.mock(VolumeDao.class);
-        }
-
-        @Bean
-        public VolumeDataFactory volumeDataFactory() {
-            return Mockito.mock(VolumeDataFactory.class);
-        }
-
-        @Bean
-        public PrimaryDataStoreDao primaryDataStoreDao() {
-            return Mockito.mock(PrimaryDataStoreDao.class);
-        }
-
-        @Bean
-        public VMInstanceDao vmInstanceDao() {
-            return Mockito.mock(VMInstanceDao.class);
-        }
-
-        @Bean
-        public AgentManager agentManager() {
-            return Mockito.mock(AgentManager.class);
-        }
-
-        public static class Library implements TypeFilter {
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml
index 0ed9824..60591ff 100644
--- a/plugins/hypervisors/xenserver/pom.xml
+++ b/plugins/hypervisors/xenserver/pom.xml
@@ -1,44 +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. -->
+<!--
+  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-hypervisor-xenserver</artifactId>
-  <name>Apache CloudStack Plugin - Hypervisor XenServer</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-ovs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>net.java.dev.vcc.thirdparty</groupId>
-      <artifactId>xen-api</artifactId>
-      <version>${cs.xapi.version}</version>
-    </dependency>
-  </dependencies>
+    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-hypervisor-xenserver</artifactId>
+    <name>Apache CloudStack Plugin - Hypervisor XenServer</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-ovs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.java.dev.vcc.thirdparty</groupId>
+            <artifactId>xen-api</artifactId>
+            <version>${cs.xapi.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/ha/XenServerFencer.java b/plugins/hypervisors/xenserver/src/com/cloud/ha/XenServerFencer.java
deleted file mode 100644
index af89a0a..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/ha/XenServerFencer.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.ha;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.FenceAnswer;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.VirtualMachine;
-
-public class XenServerFencer extends AdapterBase implements FenceBuilder {
-    private static final Logger s_logger = Logger.getLogger(XenServerFencer.class);
-
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-
-    @Override
-    public Boolean fenceOff(VirtualMachine vm, Host host) {
-        if (host.getHypervisorType() != HypervisorType.XenServer) {
-            s_logger.debug("Don't know how to fence non XenServer hosts " + host.getHypervisorType());
-            return null;
-        }
-
-        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
-        FenceCommand fence = new FenceCommand(vm, host);
-
-        for (HostVO h : hosts) {
-            if (h.getHypervisorType() == HypervisorType.XenServer) {
-                if (h.getStatus() != Status.Up) {
-                    continue;
-                }
-                if (h.getId() == host.getId()) {
-                    continue;
-                }
-                FenceAnswer answer;
-                try {
-                    Answer ans = _agentMgr.send(h.getId(), fence);
-                    if (!(ans instanceof FenceAnswer)) {
-                        s_logger.debug("Answer is not fenceanswer.  Result = " + ans.getResult() + "; Details = " + ans.getDetails());
-                        continue;
-                    }
-                    answer = (FenceAnswer)ans;
-                } catch (AgentUnavailableException e) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                    }
-                    continue;
-                } catch (OperationTimedoutException e) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
-                    }
-                    continue;
-                }
-                if (answer != null && answer.getResult()) {
-                    return true;
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
-        }
-
-        return false;
-    }
-
-    public XenServerFencer() {
-        super();
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java
deleted file mode 100644
index 9664686..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java
+++ /dev/null
@@ -1,704 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.xenserver.discoverer;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.SetupAnswer;
-import com.cloud.agent.api.SetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.DiscoveredWithErrorException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.HostEnvironment;
-import com.cloud.host.HostInfo;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.xenserver.resource.CitrixHelper;
-import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
-import com.cloud.hypervisor.xenserver.resource.XcpOssResource;
-import com.cloud.hypervisor.xenserver.resource.XcpServerResource;
-import com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer56Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer56SP2Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer600Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer610Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer620Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer620SP1Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServer650Resource;
-import com.cloud.hypervisor.xenserver.resource.XenServerConnectionPool;
-import com.cloud.hypervisor.xenserver.resource.Xenserver625Resource;
-import com.cloud.resource.Discoverer;
-import com.cloud.resource.DiscovererBase;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.user.Account;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.HypervisorVersionChangedException;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.HostPatch;
-import com.xensource.xenapi.Pool;
-import com.xensource.xenapi.PoolPatch;
-import com.xensource.xenapi.Session;
-import com.xensource.xenapi.Types.SessionAuthenticationFailed;
-import com.xensource.xenapi.Types.UuidInvalid;
-import com.xensource.xenapi.Types.XenAPIException;
-import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs;
-import org.apache.log4j.Logger;
-import org.apache.xmlrpc.XmlRpcException;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import javax.persistence.EntityExistsException;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-
-
-public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter {
-    private static final Logger s_logger = Logger.getLogger(XcpServerDiscoverer.class);
-    protected String _publicNic;
-    protected String _privateNic;
-    protected String _storageNic1;
-    protected String _storageNic2;
-    protected int _wait;
-    protected XenServerConnectionPool _connPool;
-    protected boolean _checkHvm;
-    protected String _guestNic;
-    protected boolean _setupMultipath;
-    protected String _instance;
-
-    @Inject
-    protected AlertManager _alertMgr;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    private VMTemplateDao _tmpltDao;
-    @Inject
-    private HostPodDao _podDao;
-
-    protected XcpServerDiscoverer() {
-    }
-
-    void setClusterGuid(ClusterVO cluster, String guid) {
-        cluster.setGuid(guid);
-        try {
-            _clusterDao.update(cluster.getId(), cluster);
-        } catch (EntityExistsException e) {
-            QueryBuilder<ClusterVO> sc = QueryBuilder.create(ClusterVO.class);
-            sc.and(sc.entity().getGuid(), Op.EQ, guid);
-            List<ClusterVO> clusters = sc.list();
-            ClusterVO clu = clusters.get(0);
-            List<HostVO> clusterHosts = _resourceMgr.listAllHostsInCluster(clu.getId());
-            if (clusterHosts == null || clusterHosts.size() == 0) {
-                clu.setGuid(null);
-                _clusterDao.update(clu.getId(), clu);
-                _clusterDao.update(cluster.getId(), cluster);
-                return;
-            }
-            throw e;
-        }
-    }
-
-    protected boolean poolHasHotFix(Connection conn, String hostIp, String hotFixUuid) {
-        try {
-            Map<Host, Host.Record> hosts = Host.getAllRecords(conn);
-            for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
-
-                Host.Record re = entry.getValue();
-                if (!re.address.equalsIgnoreCase(hostIp)){
-                    continue;
-                }
-                Set<HostPatch> patches = re.patches;
-                PoolPatch poolPatch = PoolPatch.getByUuid(conn, hotFixUuid);
-                for(HostPatch patch : patches) {
-                    PoolPatch pp = patch.getPoolPatch(conn);
-                    if (pp != null && pp.equals(poolPatch) && patch.getApplied(conn)) {
-                        s_logger.debug("host " + hostIp + " does have " + hotFixUuid +" Hotfix.");
-                        return true;
-                    }
-                }
-            }
-            return false;
-        } catch (UuidInvalid e) {
-            s_logger.debug("host " + hostIp + " doesn't have " + hotFixUuid + " Hotfix");
-        } catch (Exception e) {
-            s_logger.debug("can't get patches information, consider it doesn't have " + hotFixUuid + " Hotfix");
-        }
-        return false;
-    }
-
-
-
-    @Override
-    public Map<? extends ServerResource, Map<String, String>>
-    find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException {
-        Map<CitrixResourceBase, Map<String, String>> resources = new HashMap<CitrixResourceBase, Map<String, String>>();
-        Connection conn = null;
-        if (!url.getScheme().equals("http")) {
-            String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
-            s_logger.debug(msg);
-            return null;
-        }
-        if (clusterId == null) {
-            String msg = "must specify cluster Id when add host";
-            s_logger.debug(msg);
-            throw new RuntimeException(msg);
-        }
-
-        if (podId == null) {
-            String msg = "must specify pod Id when add host";
-            s_logger.debug(msg);
-            throw new RuntimeException(msg);
-        }
-
-        ClusterVO cluster = _clusterDao.findById(clusterId);
-        if (cluster == null || cluster.getHypervisorType() != HypervisorType.XenServer) {
-            if (s_logger.isInfoEnabled())
-                s_logger.info("invalid cluster id or cluster is not for XenServer hypervisors");
-            return null;
-        }
-
-        try {
-            String hostname = url.getHost();
-            InetAddress ia = InetAddress.getByName(hostname);
-            String hostIp = ia.getHostAddress();
-            Queue<String> pass = new LinkedList<String>();
-            pass.add(password);
-            conn = _connPool.getConnect(hostIp, username, pass);
-            if (conn == null) {
-                String msg = "Unable to get a connection to " + url;
-                s_logger.debug(msg);
-                throw new DiscoveryException(msg);
-            }
-
-            Set<Pool> pools = Pool.getAll(conn);
-            Pool pool = pools.iterator().next();
-            Pool.Record pr = pool.getRecord(conn);
-            String poolUuid = pr.uuid;
-            Map<Host, Host.Record> hosts = Host.getAllRecords(conn);
-            String latestHotFix = "";
-            if (poolHasHotFix(conn, hostIp, XenserverConfigs.XSHotFix62ESP1004)) {
-                latestHotFix = XenserverConfigs.XSHotFix62ESP1004;
-            } else if (poolHasHotFix(conn, hostIp, XenserverConfigs.XSHotFix62ESP1)) {
-                latestHotFix = XenserverConfigs.XSHotFix62ESP1;
-            }
-
-            /*set cluster hypervisor type to xenserver*/
-            ClusterVO clu = _clusterDao.findById(clusterId);
-            if (clu.getGuid() == null) {
-                setClusterGuid(clu, poolUuid);
-            } else {
-                List<HostVO> clusterHosts = _resourceMgr.listAllHostsInCluster(clusterId);
-                if (clusterHosts != null && clusterHosts.size() > 0) {
-                    if (!clu.getGuid().equals(poolUuid)) {
-                        String msg = "Please join the host " +  hostIp + " to XS pool  "
-                                       + clu.getGuid() + " through XC/XS before adding it through CS UI";
-                        s_logger.warn(msg);
-                        throw new DiscoveryException(msg);
-                    }
-                } else {
-                    setClusterGuid(clu, poolUuid);
-                }
-            }
-            // can not use this conn after this point, because this host may join a pool, this conn is retired
-            if (conn != null) {
-                try {
-                    Session.logout(conn);
-                } catch (Exception e) {
-                    s_logger.debug("Caught exception during logout", e);
-                }
-                conn.dispose();
-                conn = null;
-            }
-
-            poolUuid = clu.getGuid();
-            _clusterDao.update(clusterId, clu);
-
-            if (_checkHvm) {
-                for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
-                    Host.Record record = entry.getValue();
-
-                    boolean support_hvm = false;
-                    for (String capability : record.capabilities) {
-                        if (capability.contains("hvm")) {
-                            support_hvm = true;
-                            break;
-                        }
-                    }
-                    if (!support_hvm) {
-                        String msg = "Unable to add host " + record.address + " because it doesn't support hvm";
-                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, msg, msg);
-                        s_logger.debug(msg);
-                        throw new RuntimeException(msg);
-                    }
-                }
-            }
-
-            for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
-                Host.Record record = entry.getValue();
-                String hostAddr = record.address;
-
-                String prodVersion = CitrixHelper.getProductVersion(record);
-                String xenVersion = record.softwareVersion.get("xen");
-                String hostOS = record.softwareVersion.get("product_brand");
-                if (hostOS == null) {
-                    hostOS = record.softwareVersion.get("platform_name");
-                }
-
-                String hostOSVer = prodVersion;
-                String hostKernelVer = record.softwareVersion.get("linux");
-
-                if (_resourceMgr.findHostByGuid(record.uuid) != null) {
-                    s_logger.debug("Skipping " + record.address + " because " + record.uuid + " is already in the database.");
-                    continue;
-                }
-
-                CitrixResourceBase resource = createServerResource(dcId, podId, record, latestHotFix);
-                s_logger.info("Found host " + record.hostname + " ip=" + record.address + " product version=" + prodVersion);
-
-                Map<String, String> details = new HashMap<String, String>();
-                Map<String, Object> params = new HashMap<String, Object>();
-                details.put("url", hostAddr);
-                details.put("username", username);
-                params.put("username", username);
-                details.put("password", password);
-                params.put("password", password);
-                params.put("zone", Long.toString(dcId));
-                params.put("guid", record.uuid);
-                params.put("pod", podId.toString());
-                params.put("cluster", clusterId.toString());
-                params.put("pool", poolUuid);
-                params.put("ipaddress", record.address);
-
-                details.put(HostInfo.HOST_OS, hostOS);
-                details.put(HostInfo.HOST_OS_VERSION, hostOSVer);
-                details.put(HostInfo.HOST_OS_KERNEL_VERSION, hostKernelVer);
-                details.put(HostInfo.HYPERVISOR_VERSION, xenVersion);
-
-                String privateNetworkLabel = _networkMgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.XenServer);
-                String storageNetworkLabel = _networkMgr.getDefaultStorageTrafficLabel(dcId, HypervisorType.XenServer);
-
-                if (!params.containsKey("private.network.device") && privateNetworkLabel != null) {
-                    params.put("private.network.device", privateNetworkLabel);
-                    details.put("private.network.device", privateNetworkLabel);
-                }
-
-                if (!params.containsKey("storage.network.device1") && storageNetworkLabel != null) {
-                    params.put("storage.network.device1", storageNetworkLabel);
-                    details.put("storage.network.device1", storageNetworkLabel);
-                }
-
-                DataCenterVO zone = _dcDao.findById(dcId);
-                boolean securityGroupEnabled = zone.isSecurityGroupEnabled();
-                params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
-
-                params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
-                params.put("wait", Integer.toString(_wait));
-                details.put("wait", Integer.toString(_wait));
-                params.put("migratewait", _configDao.getValue(Config.MigrateWait.toString()));
-                params.put(Config.XenServerMaxNics.toString().toLowerCase(), _configDao.getValue(Config.XenServerMaxNics.toString()));
-                params.put(Config.XenServerHeartBeatTimeout.toString().toLowerCase(), _configDao.getValue(Config.XenServerHeartBeatTimeout.toString()));
-                params.put(Config.XenServerHeartBeatInterval.toString().toLowerCase(), _configDao.getValue(Config.XenServerHeartBeatInterval.toString()));
-                params.put(Config.InstanceName.toString().toLowerCase(), _instance);
-                details.put(Config.InstanceName.toString().toLowerCase(), _instance);
-                try {
-                    resource.configure("XenServer", params);
-                } catch (ConfigurationException e) {
-                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + record.address, "Error is " + e.getMessage());
-                    s_logger.warn("Unable to instantiate " + record.address, e);
-                    continue;
-                }
-                resource.start();
-                resources.put(resource, details);
-            }
-        } catch (SessionAuthenticationFailed e) {
-            throw new DiscoveredWithErrorException("Authentication error");
-        } catch (XenAPIException e) {
-            s_logger.warn("XenAPI exception", e);
-            return null;
-        } catch (XmlRpcException e) {
-            s_logger.warn("Xml Rpc Exception", e);
-            return null;
-        } catch (UnknownHostException e) {
-            s_logger.warn("Unable to resolve the host name", e);
-            return null;
-        } catch (Exception e) {
-            s_logger.debug("other exceptions: " + e.toString(), e);
-            return null;
-        }
-        return resources;
-    }
-
-    String getPoolUuid(Connection conn) throws XenAPIException, XmlRpcException {
-        Map<Pool, Pool.Record> pools = Pool.getAllRecords(conn);
-        assert pools.size() == 1 : "Pools size is " + pools.size();
-        return pools.values().iterator().next().uuid;
-    }
-
-    protected void addSamePool(Connection conn, Map<CitrixResourceBase, Map<String, String>> resources) throws XenAPIException, XmlRpcException {
-        Map<Pool, Pool.Record> hps = Pool.getAllRecords(conn);
-        assert (hps.size() == 1) : "How can it be more than one but it's actually " + hps.size();
-
-        // This is the pool.
-        String poolUuid = hps.values().iterator().next().uuid;
-
-        for (Map<String, String> details : resources.values()) {
-            details.put("pool", poolUuid);
-        }
-    }
-
-    protected CitrixResourceBase createServerResource(String prodBrand, String prodVersion, String prodVersionTextShort, String hotfix) {
-        // Xen Cloud Platform group of hypervisors
-        if (prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0")
-              || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4") || prodVersion.startsWith("1.6"))) {
-            return new XcpServerResource();
-        } // Citrix Xenserver group of hypervisors
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.0"))
-            return new XenServer56Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.0"))
-            return new XenServer600Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.2"))
-            return new XenServer600Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.1.0"))
-            return new XenServer610Resource();
-        else if (prodBrand.equals("XenServer") && prodVersion.equals("6.2.0")) {
-            if (hotfix != null && hotfix.equals(XenserverConfigs.XSHotFix62ESP1004)) {
-                return new Xenserver625Resource();
-            } else if (hotfix != null && hotfix.equals(XenserverConfigs.XSHotFix62ESP1)) {
-                return new XenServer620SP1Resource();
-            } else {
-                return new XenServer620Resource();
-            }
-        } else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.100")) {
-            if ("5.6 SP2".equals(prodVersionTextShort.trim())) {
-                return new XenServer56SP2Resource();
-            } else if ("5.6 FP1".equals(prodVersionTextShort.trim())) {
-                return new XenServer56FP1Resource();
-            }
-        } else if (prodBrand.equals("XCP_Kronos")) {
-            return new XcpOssResource();
-        } else if (prodBrand.equals("XenServer") || prodBrand.equals("XCP-ng")) {
-            final String[] items = prodVersion.split("\\.");
-            if ((Integer.parseInt(items[0]) > 6) ||
-                    (Integer.parseInt(items[0]) == 6 && Integer.parseInt(items[1]) >= 4)) {
-                s_logger.warn("defaulting to xenserver650 resource for product brand: " + prodBrand + " with product " +
-                        "version: " + prodVersion);
-                //default to xenserver650 resource.
-                return new XenServer650Resource();
-            }
-        }
-        String msg =
-                "Only support XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; XenServer 5.6,  XenServer 5.6 FP1, XenServer 5.6 SP2, Xenserver 6.0, 6.0.2, 6.1.0, 6.2.0, >6.4.0 but this one is " +
-                        prodBrand + " " + prodVersion;
-        s_logger.warn(msg);
-        throw new RuntimeException(msg);
-    }
-
-
-
-    protected CitrixResourceBase createServerResource(long dcId, Long podId, Host.Record record, String hotfix) {
-        String prodBrand = record.softwareVersion.get("product_brand");
-        if (prodBrand == null) {
-            prodBrand = record.softwareVersion.get("platform_name").trim();
-        } else {
-            prodBrand = prodBrand.trim();
-        }
-        String prodVersion = CitrixHelper.getProductVersion(record);
-
-        String prodVersionTextShort = record.softwareVersion.get("product_version_text_short");
-        return createServerResource(prodBrand, prodVersion, prodVersionTextShort, hotfix);
-    }
-
-    protected void serverConfig() {
-        String value = _params.get(Config.XenServerSetupMultipath.key());
-        _setupMultipath = Boolean.parseBoolean(value);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        serverConfig();
-
-        _publicNic = _params.get(Config.XenServerPublicNetwork.key());
-        _privateNic = _params.get(Config.XenServerPrivateNetwork.key());
-
-        _storageNic1 = _params.get(Config.XenServerStorageNetwork1.key());
-        _storageNic2 = _params.get(Config.XenServerStorageNetwork2.key());
-
-        _guestNic = _params.get(Config.XenServerGuestNetwork.key());
-
-        String value = _params.get(Config.XapiWait.toString());
-        _wait = NumbersUtil.parseInt(value, Integer.parseInt(Config.XapiWait.getDefaultValue()));
-
-        _instance = _params.get(Config.InstanceName.key());
-
-        value = _params.get(Config.XenServerSetupMultipath.key());
-        Boolean.parseBoolean(value);
-
-        value = _params.get("xenserver.check.hvm");
-        _checkHvm = Boolean.parseBoolean(value);
-        _connPool = XenServerConnectionPool.getInstance();
-
-        _agentMgr.registerForHostEvents(this, true, false, true);
-
-        createXsToolsISO();
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        return true;
-    }
-
-    @Override
-    public boolean matchHypervisor(String hypervisor) {
-        if (hypervisor == null)
-            return true;
-        return Hypervisor.HypervisorType.XenServer.toString().equalsIgnoreCase(hypervisor);
-    }
-
-    @Override
-    public Hypervisor.HypervisorType getHypervisorType() {
-        return Hypervisor.HypervisorType.XenServer;
-    }
-
-    @Override
-    public void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException {
-        //do nothing
-    }
-
-    @Override
-    public int getTimeout() {
-        return 0;
-    }
-
-    @Override
-    public boolean isRecurring() {
-        return false;
-    }
-
-    @Override
-    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
-        return false;
-    }
-
-    @Override
-    public boolean processCommands(long agentId, long seq, Command[] commands) {
-        return false;
-    }
-
-    private void createXsToolsISO() {
-        String isoName = "xs-tools.iso";
-        VMTemplateVO tmplt = _tmpltDao.findByTemplateName(isoName);
-        Long id;
-        if (tmplt == null) {
-            id = _tmpltDao.getNextInSequence(Long.class, "id");
-            VMTemplateVO template =
-                    VMTemplateVO.createPreHostIso(id, isoName, isoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64, Account.ACCOUNT_ID_SYSTEM,
-                            null, "XenServer Tools Installer ISO (xen-pv-drv-iso)", false, 1, false, HypervisorType.XenServer);
-            _tmpltDao.persist(template);
-        } else {
-            id = tmplt.getId();
-            tmplt.setTemplateType(TemplateType.PERHOST);
-            tmplt.setUrl(null);
-            _tmpltDao.update(id, tmplt);
-        }
-    }
-
-    @Override
-    public void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
-        if (!(cmd instanceof StartupRoutingCommand)) {
-            return;
-        }
-        long agentId = agent.getId();
-
-        StartupRoutingCommand startup = (StartupRoutingCommand)cmd;
-        if (startup.getHypervisorType() != HypervisorType.XenServer) {
-            s_logger.debug("Not XenServer so moving on.");
-            return;
-        }
-
-        HostVO host = _hostDao.findById(agentId);
-
-        ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-        if (cluster.getGuid() == null) {
-            cluster.setGuid(startup.getPool());
-            _clusterDao.update(cluster.getId(), cluster);
-        } else if (!cluster.getGuid().equals(startup.getPool())) {
-            String msg = "pool uuid for cluster " + cluster.getId() + " changed from " + cluster.getGuid() + " to " + startup.getPool();
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-
-        Map<String, String> details = startup.getHostDetails();
-        String prodBrand = details.get("product_brand").trim();
-        String prodVersion = details.get("product_version").trim();
-        String hotfix = details.get(XenserverConfigs.XS620HotFix);
-        String prodVersionTextShort = details.get("product_version_text_short");
-
-        String resource = createServerResource(prodBrand, prodVersion, prodVersionTextShort, hotfix).getClass().getName();
-
-        if (!resource.equals(host.getResource())) {
-            String msg = "host " + host.getPrivateIpAddress() + " changed from " + host.getResource() + " to " + resource;
-            s_logger.debug(msg);
-            host.setResource(resource);
-            host.setSetup(false);
-            _hostDao.update(agentId, host);
-            throw new HypervisorVersionChangedException(msg);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Setting up host " + agentId);
-        }
-        HostEnvironment env = new HostEnvironment();
-
-        SetupCommand setup = new SetupCommand(env);
-        if (_setupMultipath) {
-            setup.setMultipathOn();
-        }
-        if (!host.isSetup()) {
-            setup.setNeedSetup(true);
-        }
-
-        try {
-            Answer answer = _agentMgr.send(agentId, setup);
-            if (answer != null && answer.getResult() && answer instanceof SetupAnswer) {
-                host.setSetup(true);
-                host.setLastPinged((System.currentTimeMillis() >> 10) - 5 * 60);
-                host.setHypervisorVersion(prodVersion);
-                _hostDao.update(host.getId(), host);
-                if (((SetupAnswer)answer).needReconnect()) {
-                    throw new ConnectionException(false, "Reinitialize agent after setup.");
-                }
-                return;
-            } else {
-                s_logger.warn("Unable to setup agent " + agentId + " due to " + ((answer != null) ? answer.getDetails() : "return null"));
-            }
-        } catch (AgentUnavailableException e) {
-            s_logger.warn("Unable to setup agent " + agentId + " because it became unavailable.", e);
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Unable to setup agent " + agentId + " because it timed out", e);
-        }
-        throw new ConnectionException(true, "Reinitialize agent after setup.");
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
-        return null;
-    }
-
-    @Override
-    public boolean processDisconnect(long agentId, Status state) {
-        return false;
-    }
-
-    @Override
-    public void processHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void processHostRemoved(long hostId, long clusterId) {
-    }
-
-    @Override
-    public boolean processTimeout(long agentId, long seq) {
-        return false;
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        StartupCommand firstCmd = startup[0];
-        if (!(firstCmd instanceof StartupRoutingCommand)) {
-            return null;
-        }
-
-        StartupRoutingCommand ssCmd = ((StartupRoutingCommand)firstCmd);
-        if (ssCmd.getHypervisorType() != HypervisorType.XenServer) {
-            return null;
-        }
-
-        HostPodVO pod = _podDao.findById(host.getPodId());
-        DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
-        s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + HypervisorType.XenServer + ". Checking CIDR...");
-        _resourceMgr.checkCIDR(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPrivateNetmask());
-        return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.XenServer, details, hostTags);
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (host.getType() != com.cloud.host.Host.Type.Routing || host.getHypervisorType() != HypervisorType.XenServer) {
-            return null;
-        }
-
-        _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
-        return new DeleteHostAnswer(true);
-    }
-
-    @Override
-    protected HashMap<String, Object> buildConfigParams(HostVO host) {
-        HashMap<String, Object> params = super.buildConfigParams(host);
-        DataCenterVO zone = _dcDao.findById(host.getDataCenterId());
-        if (zone != null) {
-            boolean securityGroupEnabled = zone.isSecurityGroupEnabled();
-            params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
-        }
-        return params;
-    }
-
-    @Override
-    public boolean stop() {
-        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
-        return super.stop();
-    }
-}
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
deleted file mode 100644
index 77b0bcb..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
+++ /dev/null
@@ -1,5642 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.xenserver.resource;
-
-
-import org.apache.commons.collections.MapUtils;
-import com.cloud.agent.IAgentControl;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.GetVmStatsCommand;
-import com.cloud.agent.api.HostStatsEntry;
-import com.cloud.agent.api.HostVmStateReportEntry;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingRoutingCommand;
-import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
-import com.cloud.agent.api.PingRoutingWithOvsCommand;
-import com.cloud.agent.api.RebootAnswer;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.StartCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.StopCommand;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.VgpuTypesInfo;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.GPUDeviceTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.resource.virtualnetwork.VRScripts;
-import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
-import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.CitrixRequestWrapper;
-import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper;
-import com.cloud.network.Networks;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.hypervisor.HypervisorResource;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.resource.StorageSubsystemCommandHandler;
-import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
-import com.cloud.utils.ExecutionResult;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.Script;
-import com.cloud.utils.ssh.SSHCmdHelper;
-import com.cloud.utils.ssh.SshHelper;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.PowerState;
-import com.trilead.ssh2.SCPClient;
-import com.xensource.xenapi.Bond;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Console;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.HostCpu;
-import com.xensource.xenapi.HostMetrics;
-import com.xensource.xenapi.Network;
-import com.xensource.xenapi.PBD;
-import com.xensource.xenapi.PIF;
-import com.xensource.xenapi.Pool;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Session;
-import com.xensource.xenapi.Task;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.VmPowerState;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VBD;
-import com.xensource.xenapi.VDI;
-import com.xensource.xenapi.VIF;
-import com.xensource.xenapi.VLAN;
-import com.xensource.xenapi.VM;
-import com.xensource.xenapi.XenAPIObject;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.commons.io.FileUtils;
-import org.apache.log4j.Logger;
-import org.apache.xmlrpc.XmlRpcException;
-import org.joda.time.Duration;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.naming.ConfigurationException;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Queue;
-import java.util.Random;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.TimeoutException;
-
-/**
- * CitrixResourceBase encapsulates the calls to the XenServer Xapi process to
- * perform the required functionalities for CloudStack.
- *
- * ==============> READ THIS <============== Because the XenServer objects can
- * expire when the session expires, we cannot keep any of the actual XenServer
- * objects in this class. The only thing that is constant is the UUID of the
- * XenServer objects but not the objects themselves! This is very important
- * before you do any changes in this code here.
- *
- */
-public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer {
-    /**
-     * used to describe what type of resource a storage device is of
-     */
-    public enum SRType {
-        EXT, FILE, ISCSI, ISO, LVM, LVMOHBA, LVMOISCSI,
-        /**
-         * used for resigning metadata (like SR UUID and VDI UUID when a
-         * particular storage manager is installed on a XenServer host (for back-end snapshots to work))
-         */
-        RELVMOISCSI, NFS;
-
-        String _str;
-
-        private SRType() {
-            _str = super.toString().toLowerCase();
-        }
-
-        public boolean equals(final String type) {
-            return _str.equalsIgnoreCase(type);
-        }
-
-        @Override
-        public String toString() {
-            return _str;
-        }
-    }
-
-    private final static int BASE_TO_CONVERT_BYTES_INTO_KILOBYTES = 1024;
-
-    protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance();
-    // static min values for guests on xenserver
-    private static final long mem_128m = 134217728L;
-
-    static final Random Rand = new Random(System.currentTimeMillis());
-    private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class);
-    protected static final HashMap<VmPowerState, PowerState> s_powerStatesTable;
-
-    static {
-        s_powerStatesTable = new HashMap<VmPowerState, PowerState>();
-        s_powerStatesTable.put(VmPowerState.HALTED, PowerState.PowerOff);
-        s_powerStatesTable.put(VmPowerState.PAUSED, PowerState.PowerOff);
-        s_powerStatesTable.put(VmPowerState.RUNNING, PowerState.PowerOn);
-        s_powerStatesTable.put(VmPowerState.SUSPENDED, PowerState.PowerOff);
-        s_powerStatesTable.put(VmPowerState.UNRECOGNIZED, PowerState.PowerUnknown);
-    }
-
-    private static PowerState convertToPowerState(final VmPowerState ps) {
-        final PowerState powerState = s_powerStatesTable.get(ps);
-        return powerState == null ? PowerState.PowerUnknown : powerState;
-    }
-
-    private static boolean isAlienVm(final VM vm, final Connection conn) throws XenAPIException, XmlRpcException {
-        // TODO : we need a better way to tell whether or not the VM belongs to
-        // CloudStack
-        final String vmName = vm.getNameLabel(conn);
-        if (vmName.matches("^[ivs]-\\d+-.+")) {
-            return false;
-        }
-
-        return true;
-    }
-
-    protected IAgentControl _agentControl;
-    protected boolean _canBridgeFirewall = false;
-    protected String _cluster;
-    // Guest and Host Performance Statistics
-    protected String _consolidationFunction = "AVERAGE";
-    protected long _dcId;
-    protected String _guestNetworkName;
-    protected int _heartbeatInterval = 60;
-    protected int _heartbeatTimeout = 120;
-    protected final XsHost _host = new XsHost();
-    protected String _instance; // instance name (default is usually "VM")
-    protected boolean _isOvs = false;
-    protected String _linkLocalPrivateNetworkName;
-    protected int _maxNics = 7;
-
-    final int _maxWeight = 256;
-    protected int _migratewait;
-    protected String _name;
-    protected Queue<String> _password = new LinkedList<String>();
-
-    protected String _pod;
-    protected int _pollingIntervalInSeconds = 60;
-
-    protected String _privateNetworkName;
-    protected String _publicNetworkName;
-
-    protected final int _retry = 100;
-
-    protected boolean _securityGroupEnabled;
-    protected final int _sleep = 10000;
-    protected String _storageNetworkName1;
-    protected String _storageNetworkName2;
-    protected List<VIF> _tmpDom0Vif = new ArrayList<VIF>();
-
-    protected String _username;
-
-    protected VirtualRoutingResource _vrResource;
-
-    protected  String _configDriveIsopath = "/opt/xensource/packages/configdrive_iso/";
-    protected  String _configDriveSRName = "ConfigDriveISOs";
-    public String _attachIsoDeviceNum = "3";
-
-    protected XenServerUtilitiesHelper xenServerUtilitiesHelper = new XenServerUtilitiesHelper();
-
-    protected int _wait;
-    // Hypervisor specific params with generic value, may need to be overridden
-    // for specific versions
-    long _xsMemoryUsed = 128 * 1024 * 1024L; // xenserver hypervisor used 128 M
-
-    double _xsVirtualizationFactor = 63.0 / 64.0; // 1 - virtualization overhead
-
-    protected StorageSubsystemCommandHandler storageHandler;
-
-    private static final String XENSTORE_DATA_IP = "vm-data/ip";
-    private static final String XENSTORE_DATA_GATEWAY = "vm-data/gateway";
-    private static final String XENSTORE_DATA_NETMASK = "vm-data/netmask";
-    private static final String XENSTORE_DATA_CS_INIT = "vm-data/cloudstack/init";
-
-    public CitrixResourceBase() {
-    }
-
-    /**
-     * Replaces the old password with the new password used to connect to the host.
-     *
-     * @param password  - the new host password.
-     * @return the old password.
-     */
-    public String replaceOldPasswdInQueue(final String password) {
-        final String oldPasswd = _password.poll();
-        _password.add(password);
-
-        return oldPasswd;
-    }
-
-    public String getPwdFromQueue() {
-        return _password.peek();
-    }
-
-    public XenServerUtilitiesHelper getXenServerUtilitiesHelper() {
-        return xenServerUtilitiesHelper;
-    }
-
-    protected StorageSubsystemCommandHandler buildStorageHandler() {
-        final XenServerStorageProcessor processor = new XenServerStorageProcessor(this);
-        return new StorageSubsystemCommandHandlerBase(processor);
-    }
-
-    public String callHostPlugin(final Connection conn, final String plugin, final String cmd, final String... params) {
-        final Map<String, String> args = new HashMap<String, String>();
-        String msg;
-        try {
-            for (int i = 0; i < params.length; i += 2) {
-                args.put(params[i], params[i + 1]);
-            }
-
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
-            }
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final String result = host.callPlugin(conn, plugin, cmd, args);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin Result: " + result);
-            }
-            return result.replace("\n", "");
-        } catch (final XenAPIException e) {
-            msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString();
-            s_logger.warn(msg);
-        } catch (final XmlRpcException e) {
-            msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage();
-            s_logger.debug(msg);
-        }
-        throw new CloudRuntimeException(msg);
-    }
-
-    protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final Map<String, String> params) {
-        final int timeout = wait * 1000;
-        final Map<String, String> args = new HashMap<String, String>();
-        Task task = null;
-        try {
-            for (final Map.Entry<String, String> entry : params.entrySet()) {
-                args.put(entry.getKey(), entry.getValue());
-            }
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
-            }
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            task = host.callPluginAsync(conn, plugin, cmd, args);
-            // poll every 1 seconds
-            waitForTask(conn, task, 1000, timeout);
-            checkForSuccess(conn, task);
-            final String result = task.getResult(conn);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin Result: " + result);
-            }
-            return result.replace("<value>", "").replace("</value>", "").replace("\n", "");
-        } catch (final Types.HandleInvalid e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
-        } catch (final Exception e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-        return null;
-    }
-
-    protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final String... params) {
-        final int timeout = wait * 1000;
-        final Map<String, String> args = new HashMap<String, String>();
-        Task task = null;
-        try {
-            for (int i = 0; i < params.length; i += 2) {
-                args.put(params[i], params[i + 1]);
-            }
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
-            }
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            task = host.callPluginAsync(conn, plugin, cmd, args);
-            // poll every 1 seconds
-            waitForTask(conn, task, 1000, timeout);
-            checkForSuccess(conn, task);
-            final String result = task.getResult(conn);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin Result: " + result);
-            }
-            return result.replace("<value>", "").replace("</value>", "").replace("\n", "");
-        } catch (final Types.HandleInvalid e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
-        } catch (final XenAPIException e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
-        } catch (final Exception e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-        return null;
-    }
-
-    public String callHostPluginPremium(final Connection conn, final String cmd, final String... params) {
-        return callHostPlugin(conn, "vmopspremium", cmd, params);
-    }
-
-    protected String callHostPluginThroughMaster(final Connection conn, final String plugin, final String cmd, final String... params) {
-        final Map<String, String> args = new HashMap<String, String>();
-
-        try {
-            final Map<Pool, Pool.Record> poolRecs = Pool.getAllRecords(conn);
-            if (poolRecs.size() != 1) {
-                throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.getUuid());
-            }
-            final Host master = poolRecs.values().iterator().next().master;
-            for (int i = 0; i < params.length; i += 2) {
-                args.put(params[i], params[i + 1]);
-            }
-
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
-            }
-            final String result = master.callPlugin(conn, plugin, cmd, args);
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("callHostPlugin Result: " + result);
-            }
-            return result.replace("\n", "");
-        } catch (final Types.HandleInvalid e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
-        } catch (final XenAPIException e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
-        } catch (final XmlRpcException e) {
-            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e);
-        }
-        return null;
-    }
-
-    public boolean canBridgeFirewall() {
-        return _canBridgeFirewall;
-    }
-
-    public boolean canBridgeFirewall(final Connection conn) {
-        return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance));
-    }
-
-    public void checkForSuccess(final Connection c, final Task task) throws XenAPIException, XmlRpcException {
-        if (task.getStatus(c) == Types.TaskStatusType.SUCCESS) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") completed");
-            }
-            return;
-        } else {
-            final String msg = "Task failed! Task record: " + task.getRecord(c);
-            s_logger.warn(msg);
-            task.cancel(c);
-            task.destroy(c);
-            throw new Types.BadAsyncResult(msg);
-        }
-    }
-
-    protected boolean checkSR(final Connection conn, final SR sr) {
-        try {
-            final SR.Record srr = sr.getRecord(conn);
-            final Set<PBD> pbds = sr.getPBDs(conn);
-            if (pbds.size() == 0) {
-                final String msg = "There is no PBDs for this SR: " + srr.nameLabel + " on host:" + _host.getUuid();
-                s_logger.warn(msg);
-                return false;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Checking " + srr.nameLabel + " or SR " + srr.uuid + " on " + _host);
-            }
-            if (srr.shared) {
-                if (SRType.NFS.equals(srr.type)) {
-                    final Map<String, String> smConfig = srr.smConfig;
-                    if (!smConfig.containsKey("nosubdir")) {
-                        smConfig.put("nosubdir", "true");
-                        sr.setSmConfig(conn, smConfig);
-                    }
-                }
-
-                final Host host = Host.getByUuid(conn, _host.getUuid());
-                boolean found = false;
-                for (final PBD pbd : pbds) {
-                    final PBD.Record pbdr = pbd.getRecord(conn);
-                    if (host.equals(pbdr.host)) {
-                        if (!pbdr.currentlyAttached) {
-                            pbdPlug(conn, pbd, pbdr.uuid);
-                        }
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    final PBD.Record pbdr = srr.PBDs.iterator().next().getRecord(conn);
-                    pbdr.host = host;
-                    pbdr.uuid = "";
-                    final PBD pbd = PBD.create(conn, pbdr);
-                    pbdPlug(conn, pbd, pbd.getUuid(conn));
-                }
-            } else {
-                for (final PBD pbd : pbds) {
-                    final PBD.Record pbdr = pbd.getRecord(conn);
-                    if (!pbdr.currentlyAttached) {
-                        pbdPlug(conn, pbd, pbdr.uuid);
-                    }
-                }
-            }
-
-        } catch (final Exception e) {
-            final String msg = "checkSR failed host:" + _host + " due to " + e.toString();
-            s_logger.warn(msg, e);
-            return false;
-        }
-        return true;
-    }
-
-    private void CheckXenHostInfo() throws ConfigurationException {
-        final Connection conn = ConnPool.getConnect(_host.getIp(), _username, _password);
-        if (conn == null) {
-            throw new ConfigurationException("Can not create connection to " + _host.getIp());
-        }
-        try {
-            Host.Record hostRec = null;
-            try {
-                final Host host = Host.getByUuid(conn, _host.getUuid());
-                hostRec = host.getRecord(conn);
-                final Pool.Record poolRec = Pool.getAllRecords(conn).values().iterator().next();
-                _host.setPool(poolRec.uuid);
-
-            } catch (final Exception e) {
-                throw new ConfigurationException("Can not get host information from " + _host.getIp());
-            }
-            if (!hostRec.address.equals(_host.getIp())) {
-                final String msg = "Host " + _host.getIp() + " seems be reinstalled, please remove this host and readd";
-                s_logger.error(msg);
-                throw new ConfigurationException(msg);
-            }
-        } finally {
-            try {
-                Session.logout(conn);
-            } catch (final Exception e) {
-            }
-        }
-    }
-
-    @Override
-    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
-        if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) {
-            return cleanupNetworkElementCommand((IpAssocCommand) cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    public boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, XmlRpcException {
-        final Host host = Host.getByUuid(conn, _host.getUuid());
-        final Map<VM, VM.Record> vms = VM.getAllRecords(conn);
-        boolean success = true;
-        if (vms != null && !vms.isEmpty()) {
-            for (final Map.Entry<VM, VM.Record> entry : vms.entrySet()) {
-                final VM vm = entry.getKey();
-                final VM.Record vmRec = entry.getValue();
-                if (vmRec.isATemplate || vmRec.isControlDomain) {
-                    continue;
-                }
-
-                if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host) && !isAlienVm(vm, conn)) {
-                    try {
-                        vm.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e);
-                        success = false;
-                    }
-                }
-            }
-        }
-        return success;
-    }
-
-    protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) {
-        final Connection conn = getConnection();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-        final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
-
-        try {
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            final int ipsCount = ips.length;
-            for (final IpAddressTO ip : ips) {
-
-                final VM router = getVM(conn, routerName);
-
-                final NicTO nic = new NicTO();
-                nic.setMac(ip.getVifMacAddress());
-                nic.setType(ip.getTrafficType());
-                if (ip.getBroadcastUri() == null) {
-                    nic.setBroadcastType(BroadcastDomainType.Native);
-                } else {
-                    final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-                    nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
-                    nic.setBroadcastUri(uri);
-                }
-                nic.setDeviceId(0);
-                nic.setNetworkRateMbps(ip.getNetworkRate());
-                nic.setName(ip.getNetworkName());
-
-                Network network = getNetwork(conn, nic);
-
-                // If we are disassociating the last IP address in the VLAN, we
-                // need
-                // to remove a VIF
-                boolean removeVif = false;
-
-                // there is only one ip in this public vlan and removing it, so
-                // remove the nic
-                if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(lastIp, "true") && !ip.isAdd()) {
-                    final VIF correctVif = getCorrectVif(conn, router, network);
-                    // in isolated network eth2 is the default public interface. We don't want to delete it.
-                    if (correctVif != null && !correctVif.getDevice(conn).equals("2")) {
-                        removeVif = true;
-                    }
-                }
-
-                if (removeVif) {
-
-                    // Determine the correct VIF on DomR to
-                    // associate/disassociate the
-                    // IP address with
-
-                    final VIF correctVif = getCorrectVif(conn, router, network);
-                    if (correctVif != null) {
-                        network = correctVif.getNetwork(conn);
-
-                        // Mark this vif to be removed from network usage
-                        networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn));
-
-                        // Remove the VIF from DomR
-                        correctVif.unplug(conn);
-                        correctVif.destroy(conn);
-
-                        // Disable the VLAN network if necessary
-                        disableVlanNetwork(conn, network);
-                    }
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.debug("Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    public void cleanupTemplateSR(final Connection conn) {
-        Set<PBD> pbds = null;
-        try {
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            pbds = host.getPBDs(conn);
-        } catch (final XenAPIException e) {
-            s_logger.warn("Unable to get the SRs " + e.toString(), e);
-            throw new CloudRuntimeException("Unable to get SRs " + e.toString(), e);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Unable to get SRs " + e.getMessage(), e);
-        }
-        for (final PBD pbd : pbds) {
-            SR sr = null;
-            SR.Record srRec = null;
-            try {
-                sr = pbd.getSR(conn);
-                srRec = sr.getRecord(conn);
-            } catch (final Exception e) {
-                s_logger.warn("pbd.getSR get Exception due to ", e);
-                continue;
-            }
-            final String type = srRec.type;
-            if (srRec.shared) {
-                continue;
-            }
-            if (SRType.NFS.equals(type) || SRType.ISO.equals(type) && srRec.nameDescription.contains("template")) {
-                try {
-                    pbd.unplug(conn);
-                    pbd.destroy(conn);
-                    sr.forget(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("forget SR catch Exception due to ", e);
-                }
-            }
-        }
-    }
-
-    public void cleanUpTmpDomVif(final Connection conn, final Network nw) throws XenAPIException, XmlRpcException {
-
-        final Pair<VM, VM.Record> vm = getControlDomain(conn);
-        final VM dom0 = vm.first();
-        final Set<VIF> dom0Vifs = dom0.getVIFs(conn);
-        for (final VIF v : dom0Vifs) {
-            String vifName = "unknown";
-            try {
-                final VIF.Record vifr = v.getRecord(conn);
-                if (v.getNetwork(conn).getUuid(conn).equals(nw.getUuid(conn))) {
-                    if (vifr != null) {
-                        final Map<String, String> config = vifr.otherConfig;
-                        vifName = config.get("nameLabel");
-                    }
-                    s_logger.debug("A VIF in dom0 for the network is found - so destroy the vif");
-                    v.destroy(conn);
-                    s_logger.debug("Destroy temp dom0 vif" + vifName + " success");
-                }
-            } catch (final Exception e) {
-                s_logger.warn("Destroy temp dom0 vif " + vifName + "failed", e);
-            }
-        }
-    }
-
-    protected VDI cloudVDIcopy(final Connection conn, final VDI vdi, final SR sr, int wait) throws Exception {
-        Task task = null;
-        if (wait == 0) {
-            wait = 2 * 60 * 60;
-        }
-        try {
-            task = vdi.copyAsync(conn, sr);
-            // poll every 1 seconds , timeout after 2 hours
-            waitForTask(conn, task, 1000, (long) wait * 1000);
-            checkForSuccess(conn, task);
-            final VDI dvdi = Types.toVDI(task, conn);
-            return dvdi;
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e.toString());
-                }
-            }
-        }
-    }
-
-    public HashMap<String, String> clusterVMMetaDataSync(final Connection conn) {
-        final HashMap<String, String> vmMetaDatum = new HashMap<String, String>();
-        try {
-            final Map<VM, VM.Record> vm_map = VM.getAllRecords(conn); // USE
-            // THIS TO
-            // GET ALL
-            // VMS
-            // FROM A
-            // CLUSTER
-            if (vm_map != null) {
-                for (final VM.Record record : vm_map.values()) {
-                    if (record.isControlDomain || record.isASnapshot || record.isATemplate) {
-                        continue; // Skip DOM0
-                    }
-                    final String platform = StringUtils.mapToString(record.platform);
-                    if (platform.isEmpty()) {
-                        continue; //Skip if platform is null
-                    }
-                    vmMetaDatum.put(record.nameLabel, StringUtils.mapToString(record.platform));
-                }
-            }
-        } catch (final Throwable e) {
-            final String msg = "Unable to get vms through host " + _host.getUuid() + " due to to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-        return vmMetaDatum;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        try {
-            _dcId = Long.parseLong((String) params.get("zone"));
-        } catch (final NumberFormatException e) {
-            throw new ConfigurationException("Unable to get the zone " + params.get("zone"));
-        }
-
-        _host.setUuid((String) params.get("guid"));
-
-        _name = _host.getUuid();
-        _host.setIp((String) params.get("ipaddress"));
-
-        _username = (String) params.get("username");
-        _password.add((String) params.get("password"));
-        _pod = (String) params.get("pod");
-        _cluster = (String) params.get("cluster");
-        _privateNetworkName = (String) params.get("private.network.device");
-        _publicNetworkName = (String) params.get("public.network.device");
-        _guestNetworkName = (String) params.get("guest.network.device");
-        _instance = (String) params.get("instance.name");
-        _securityGroupEnabled = Boolean.parseBoolean((String) params.get("securitygroupenabled"));
-
-        _linkLocalPrivateNetworkName = (String) params.get("private.linkLocal.device");
-        if (_linkLocalPrivateNetworkName == null) {
-            _linkLocalPrivateNetworkName = "cloud_link_local_network";
-        }
-
-        _storageNetworkName1 = (String) params.get("storage.network.device1");
-        _storageNetworkName2 = (String) params.get("storage.network.device2");
-
-        _heartbeatTimeout = NumbersUtil.parseInt((String) params.get("xenserver.heartbeat.timeout"), 120);
-        _heartbeatInterval = NumbersUtil.parseInt((String) params.get("xenserver.heartbeat.interval"), 60);
-
-        String value = (String) params.get("wait");
-        _wait = NumbersUtil.parseInt(value, 600);
-
-        value = (String) params.get("migratewait");
-        _migratewait = NumbersUtil.parseInt(value, 3600);
-
-        _maxNics = NumbersUtil.parseInt((String) params.get("xenserver.nics.max"), 7);
-
-        if (_pod == null) {
-            throw new ConfigurationException("Unable to get the pod");
-        }
-
-        if (_host.getIp() == null) {
-            throw new ConfigurationException("Unable to get the host address");
-        }
-
-        if (_username == null) {
-            throw new ConfigurationException("Unable to get the username");
-        }
-
-        if (_password.peek() == null) {
-            throw new ConfigurationException("Unable to get the password");
-        }
-
-        if (_host.getUuid() == null) {
-            throw new ConfigurationException("Unable to get the uuid");
-        }
-
-        CheckXenHostInfo();
-
-        storageHandler = buildStorageHandler();
-
-        _vrResource = new VirtualRoutingResource(this);
-        if (!_vrResource.configure(name, params)) {
-            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
-        }
-        return true;
-    }
-
-    /**
-     * This method creates a XenServer network and configures it for being used
-     * as a L2-in-L3 tunneled network
-     */
-    public synchronized Network configureTunnelNetwork(final Connection conn, final Long networkId, final long hostId, final String bridgeName) {
-        try {
-            final Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
-            // Invoke plugin to setup the bridge which will be used by this
-            // network
-            final String bridge = nw.getBridge(conn);
-            final Map<String, String> nwOtherConfig = nw.getOtherConfig(conn);
-            final String configuredHosts = nwOtherConfig.get("ovs-host-setup");
-            boolean configured = false;
-            if (configuredHosts != null) {
-                final String hostIdsStr[] = configuredHosts.split(",");
-                for (final String hostIdStr : hostIdsStr) {
-                    if (hostIdStr.equals(((Long) hostId).toString())) {
-                        configured = true;
-                        break;
-                    }
-                }
-            }
-
-            if (!configured) {
-                String result;
-                if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) {
-                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge, "key", bridgeName, "xs_nw_uuid", nw.getUuid(conn),
-                            "cs_host_id", ((Long) hostId).toString());
-                } else {
-                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, "key", bridgeName, "xs_nw_uuid", nw.getUuid(conn), "cs_host_id",
-                            ((Long) hostId).toString());
-                }
-
-                // Note down the fact that the ovs bridge has been setup
-                final String[] res = result.split(":");
-                if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
-                    // TODO: Should make this error not fatal?
-                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge);
-                }
-            }
-            return nw;
-        } catch (final Exception e) {
-            s_logger.warn("createandConfigureTunnelNetwork failed", e);
-            return null;
-        }
-    }
-
-    public String connect(final Connection conn, final String vmname, final String ipAddress) {
-        return connect(conn, vmname, ipAddress, 3922);
-    }
-
-    public String connect(final Connection conn, final String vmName, final String ipAddress, final int port) {
-        for (int i = 0; i <= _retry; i++) {
-            try {
-                final Set<VM> vms = VM.getByNameLabel(conn, vmName);
-                if (vms.size() < 1) {
-                    final String msg = "VM " + vmName + " is not running";
-                    s_logger.warn(msg);
-                    return msg;
-                }
-            } catch (final Exception e) {
-                final String msg = "VM.getByNameLabel " + vmName + " failed due to " + e.toString();
-                s_logger.warn(msg, e);
-                return msg;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Trying to connect to " + ipAddress + " attempt " + i + " of " + _retry);
-            }
-            if (pingdomr(conn, ipAddress, Integer.toString(port))) {
-                return null;
-            }
-            try {
-                Thread.sleep(_sleep);
-            } catch (final InterruptedException e) {
-            }
-        }
-        final String msg = "Timeout, Unable to logon to " + ipAddress;
-        s_logger.debug(msg);
-
-        return msg;
-    }
-
-    public String copyVhdFromSecondaryStorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) {
-        final String nameLabel = "cloud-" + UUID.randomUUID().toString();
-        final String results = callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel",
-                nameLabel);
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg = "copy_vhd_from_secondarystorage return null";
-        } else {
-            final String[] tmp = results.split("#");
-            final String status = tmp[0];
-            if (status.equals("0")) {
-                return tmp[1];
-            } else {
-                errMsg = tmp[1];
-            }
-        }
-        final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1);
-        if (killCopyProcess(conn, source)) {
-            destroyVDIbyNameLabel(conn, nameLabel);
-        }
-        s_logger.warn(errMsg);
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    @Override
-    public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) {
-        final Connection conn = getConnection();
-        final String hostPath = "/tmp/";
-
-        s_logger.debug("Copying VR with ip " + routerIp + " config file into host " + _host.getIp());
-        try {
-            SshHelper.scpTo(_host.getIp(), 22, _username, null, _password.peek(), hostPath, content.getBytes(Charset.defaultCharset()), filename, null);
-        } catch (final Exception e) {
-            s_logger.warn("scp VR config file into host " + _host.getIp() + " failed with exception " + e.getMessage().toString());
-        }
-
-        final String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "srcfilepath", hostPath + filename, "dstfilepath", path);
-        s_logger.debug("VR Config file " + filename + " got created in VR, ip " + routerIp + " with content \n" + content);
-
-        return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5));
-    }
-
-    protected SR createIsoSRbyURI(final Connection conn, final URI uri, final String vmName, final boolean shared) {
-        try {
-            final Map<String, String> deviceConfig = new HashMap<String, String>();
-            String path = uri.getPath();
-            path = path.replace("//", "/");
-            deviceConfig.put("location", uri.getHost() + ":" + path);
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uri.getHost() + path, "iso", "iso", "iso", shared, new HashMap<String, String>());
-            sr.setNameLabel(conn, vmName + "-ISO");
-            sr.setNameDescription(conn, deviceConfig.get("location"));
-
-            sr.scan(conn);
-            return sr;
-        } catch (final XenAPIException e) {
-            final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        } catch (final Exception e) {
-            final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        }
-    }
-
-    protected SR createNfsSRbyURI(final Connection conn, final URI uri, final boolean shared) {
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Creating a " + (shared ? "shared SR for " : "not shared SR for ") + uri);
-            }
-
-            final Map<String, String> deviceConfig = new HashMap<String, String>();
-            String path = uri.getPath();
-            path = path.replace("//", "/");
-            deviceConfig.put("server", uri.getHost());
-            deviceConfig.put("serverpath", path);
-            final String name = UUID.nameUUIDFromBytes(new String(uri.getHost() + path).getBytes()).toString();
-            if (!shared) {
-                final Set<SR> srs = SR.getByNameLabel(conn, name);
-                for (final SR sr : srs) {
-                    final SR.Record record = sr.getRecord(conn);
-                    if (SRType.NFS.equals(record.type) && record.contentType.equals("user") && !record.shared) {
-                        removeSRSync(conn, sr);
-                    }
-                }
-            }
-
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final Map<String, String> smConfig = new HashMap<String, String>();
-            smConfig.put("nosubdir", "true");
-            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, smConfig);
-
-            if (!checkSR(conn, sr)) {
-                throw new Exception("no attached PBD");
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(logX(sr, "Created a SR; UUID is " + sr.getUuid(conn) + " device config is " + deviceConfig));
-            }
-            sr.scan(conn);
-            return sr;
-        } catch (final XenAPIException e) {
-            final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        } catch (final Exception e) {
-            final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        }
-    }
-
-    public VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException {
-
-        if (_host.getSystemvmisouuid() == null) {
-            Set<SR> srs = SR.getByNameLabel(conn, "XenServer Tools");
-            if (srs.size() != 1) {
-                s_logger.debug("Failed to find SR by name 'XenServer Tools', will try to find 'XCP-ng Tools' SR");
-                srs = SR.getByNameLabel(conn, "XCP-ng Tools");
-                if (srs.size() != 1) {
-                    throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools");
-                }
-            }
-            final SR sr = srs.iterator().next();
-            sr.scan(conn);
-
-            final SR.Record srr = sr.getRecord(conn);
-
-            if (_host.getSystemvmisouuid() == null) {
-                for (final VDI vdi : srr.VDIs) {
-                    final VDI.Record vdir = vdi.getRecord(conn);
-                    if (vdir.nameLabel.contains("systemvm.iso")) {
-                        _host.setSystemvmisouuid(vdir.uuid);
-                        break;
-                    }
-                }
-            }
-            if (_host.getSystemvmisouuid() == null) {
-                throw new CloudRuntimeException("can not find systemvmiso");
-            }
-        }
-
-        final VBD.Record cdromVBDR = new VBD.Record();
-        cdromVBDR.VM = vm;
-        cdromVBDR.empty = true;
-        cdromVBDR.bootable = false;
-        cdromVBDR.userdevice = "3";
-        cdromVBDR.mode = Types.VbdMode.RO;
-        cdromVBDR.type = Types.VbdType.CD;
-        final VBD cdromVBD = VBD.create(conn, cdromVBDR);
-        cdromVBD.insert(conn, VDI.getByUuid(conn, _host.getSystemvmisouuid()));
-
-        return cdromVBD;
-    }
-
-    protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder) {
-        final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder);
-        return result != null;
-    }
-
-    String createTemplateFromSnapshot(final Connection conn, final String templatePath, final String snapshotPath, final int wait) {
-        final String tmpltLocalDir = UUID.randomUUID().toString();
-        final String results = callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath,
-                "tmpltLocalDir", tmpltLocalDir);
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg = "create_privatetemplate_from_snapshot return null";
-        } else {
-            final String[] tmp = results.split("#");
-            final String status = tmp[0];
-            if (status.equals("0")) {
-                return results;
-            } else {
-                errMsg = "create_privatetemplate_from_snapshot failed due to " + tmp[1];
-            }
-        }
-        final String source = "cloud_mount/" + tmpltLocalDir;
-        killCopyProcess(conn, source);
-        s_logger.warn(errMsg);
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    public VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException,
-    XenAPIException {
-        final Volume.Type type = volume.getType();
-
-        if (vdi == null) {
-            vdi = mount(conn, vmName, volume);
-        }
-
-        if (vdi != null) {
-            if ("detached".equals(vdi.getNameLabel(conn))) {
-                vdi.setNameLabel(conn, vmName + "-DATA");
-            }
-
-            final Map<String, String> smConfig = vdi.getSmConfig(conn);
-            for (final String key : smConfig.keySet()) {
-                if (key.startsWith("host_")) {
-                    vdi.removeFromSmConfig(conn, key);
-                    break;
-                }
-            }
-        }
-        final VBD.Record vbdr = new VBD.Record();
-        vbdr.VM = vm;
-        if (vdi != null) {
-            vbdr.VDI = vdi;
-        } else {
-            vbdr.empty = true;
-        }
-        if (type == Volume.Type.ROOT && bootLoaderType == BootloaderType.PyGrub) {
-            vbdr.bootable = true;
-        } else if (type == Volume.Type.ISO && bootLoaderType == BootloaderType.CD) {
-            vbdr.bootable = true;
-        }
-
-        if (volume.getType() == Volume.Type.ISO) {
-            vbdr.mode = Types.VbdMode.RO;
-            vbdr.type = Types.VbdType.CD;
-            vbdr.userdevice = "3";
-        } else {
-            vbdr.mode = Types.VbdMode.RW;
-            vbdr.type = Types.VbdType.DISK;
-            vbdr.unpluggable = (volume.getType() == Volume.Type.ROOT) ? false : true;
-            vbdr.userdevice = "autodetect";
-            final Long deviceId = volume.getDiskSeq();
-            if (deviceId != null && (!isDeviceUsed(conn, vm, deviceId) || deviceId > 3)) {
-                    vbdr.userdevice = deviceId.toString();
-            }
-        }
-        final VBD vbd = VBD.create(conn, vbdr);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("VBD " + vbd.getUuid(conn) + " created for " + volume);
-        }
-
-        return vbd;
-    }
-
-    public VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize) throws Types.XenAPIException, XmlRpcException {
-        final Connection conn = getConnection();
-
-        final VDI.Record vdir = new VDI.Record();
-
-        vdir.nameLabel = vdiNameLabel;
-        vdir.SR = sr;
-        vdir.type = Types.VdiType.USER;
-
-        final long totalSrSpace = sr.getPhysicalSize(conn);
-        final long unavailableSrSpace = sr.getPhysicalUtilisation(conn);
-        final long availableSrSpace = totalSrSpace - unavailableSrSpace;
-
-        if (availableSrSpace < volumeSize) {
-            throw new CloudRuntimeException("Available space for SR cannot be less than " + volumeSize + ".");
-        }
-
-        vdir.virtualSize = volumeSize;
-
-        return VDI.create(conn, vdir);
-    }
-
-    public void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException {
-    }
-
-    public VIF createVif(final Connection conn, final String vmName, final VM vm, final VirtualMachineTO vmSpec, final NicTO nic) throws XmlRpcException, XenAPIException {
-        assert nic.getUuid() != null : "Nic should have a uuid value";
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Creating VIF for " + vmName + " on nic " + nic);
-        }
-        VIF.Record vifr = new VIF.Record();
-        vifr.VM = vm;
-        vifr.device = Integer.toString(nic.getDeviceId());
-        vifr.MAC = nic.getMac();
-
-        // Nicira needs these IDs to find the NIC
-        vifr.otherConfig = new HashMap<String, String>();
-        vifr.otherConfig.put("nicira-iface-id", nic.getUuid());
-        vifr.otherConfig.put("nicira-vm-id", vm.getUuid(conn));
-        // Provide XAPI with the cloudstack vm and nic uids.
-        vifr.otherConfig.put("cloudstack-nic-id", nic.getUuid());
-        if (vmSpec != null) {
-            vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid());
-        }
-
-        // OVS plugin looks at network UUID in the vif 'otherconfig' details to
-        // group VIF's & tunnel ports as part of tier
-        // when bridge is setup for distributed routing
-        vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid());
-
-        // Nuage Vsp needs Virtual Router IP to be passed in the otherconfig
-        // get the virtual router IP information from broadcast uri
-        final URI broadcastUri = nic.getBroadcastUri();
-        if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) {
-            final String path = broadcastUri.getPath();
-            vifr.otherConfig.put("vsp-vr-ip", path.substring(1));
-        }
-        vifr.network = getNetwork(conn, nic);
-
-        if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
-            vifr.qosAlgorithmType = "ratelimit";
-            vifr.qosAlgorithmParams = new HashMap<String, String>();
-            // convert mbs to kilobyte per second
-            vifr.qosAlgorithmParams.put("kbps", Integer.toString(nic.getNetworkRateMbps() * 128));
-        }
-
-        vifr.lockingMode = Types.VifLockingMode.NETWORK_DEFAULT;
-        final VIF vif = VIF.create(conn, vifr);
-        if (s_logger.isDebugEnabled()) {
-            vifr = vif.getRecord(conn);
-            if (vifr != null) {
-                s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId());
-            }
-        }
-
-        return vif;
-    }
-
-    public VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException {
-        final String guestOsTypeName = getGuestOsType(vmSpec.getPlatformEmulator());
-        final Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
-        if (templates == null || templates.isEmpty()) {
-            throw new CloudRuntimeException("Cannot find template " + guestOsTypeName + " on XenServer host");
-        }
-        assert templates.size() == 1 : "Should only have 1 template but found " + templates.size();
-        final VM template = templates.iterator().next();
-
-        final VM.Record vmr = template.getRecord(conn);
-        vmr.affinity = host;
-        vmr.otherConfig.remove("disks");
-        vmr.otherConfig.remove("default_template");
-        vmr.otherConfig.remove("mac_seed");
-        vmr.isATemplate = false;
-        vmr.nameLabel = vmSpec.getName();
-        vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY;
-        vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
-        vmr.otherConfig.put("vm_uuid", vmSpec.getUuid());
-        vmr.VCPUsMax = (long) vmSpec.getCpus(); // FIX ME: In case of dynamic
-        // scaling this VCPU max should
-        // be the minumum of
-        // recommended value for that template and capacity remaining on host
-
-        long recommendedMemoryMin = 0l;
-        long recommendedMemoryMax = 0l;
-
-        Map<String,String> guestOsDetails = vmSpec.getGuestOsDetails();
-
-        if(guestOsDetails != null){
-            if(guestOsDetails.containsKey("xenserver.dynamicMin")){
-                recommendedMemoryMin = Long.valueOf(guestOsDetails.get("xenserver.dynamicMin")).longValue();
-            }
-
-            if(guestOsDetails.containsKey("xenserver.dynamicMax")){
-                recommendedMemoryMax = Long.valueOf(guestOsDetails.get("xenserver.dynamicMax")).longValue();
-            }
-        }
-
-        if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) {
-            // scaling is allowed
-            vmr.memoryStaticMin = getStaticMin(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam(),recommendedMemoryMin);
-            vmr.memoryStaticMax = getStaticMax(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam(),recommendedMemoryMax);
-            vmr.memoryDynamicMin = vmSpec.getMinRam();
-            vmr.memoryDynamicMax = vmSpec.getMaxRam();
-            if (guestOsTypeName.toLowerCase().contains("windows")) {
-                vmr.VCPUsMax = (long) vmSpec.getCpus();
-            } else {
-                if (vmSpec.getVcpuMaxLimit() != null) {
-                    vmr.VCPUsMax = (long) vmSpec.getVcpuMaxLimit();
-                }
-            }
-        } else {
-            // scaling disallowed, set static memory target
-            if (vmSpec.isEnableDynamicallyScaleVm() && !isDmcEnabled(conn, host)) {
-                s_logger.warn("Host " + host.getHostname(conn) + " does not support dynamic scaling, so the vm " + vmSpec.getName() + " is not dynamically scalable");
-            }
-            vmr.memoryStaticMin = vmSpec.getMinRam();
-            vmr.memoryStaticMax = vmSpec.getMaxRam();
-            vmr.memoryDynamicMin = vmSpec.getMinRam();
-            vmr.memoryDynamicMax = vmSpec.getMaxRam();
-
-            vmr.VCPUsMax = (long) vmSpec.getCpus();
-        }
-
-        vmr.VCPUsAtStartup = (long) vmSpec.getCpus();
-        vmr.consoles.clear();
-        vmr.xenstoreData.clear();
-        //Add xenstore data for the NetscalerVM
-        if(vmSpec.getType()== VirtualMachine.Type.NetScalerVm) {
-            NicTO mgmtNic = vmSpec.getNics()[0];
-            if(mgmtNic != null ) {
-                Map<String, String> xenstoreData = new HashMap<String, String>(3);
-                xenstoreData.put(XENSTORE_DATA_IP, mgmtNic.getIp().toString().trim());
-                xenstoreData.put(XENSTORE_DATA_GATEWAY, mgmtNic.getGateway().toString().trim());
-                xenstoreData.put(XENSTORE_DATA_NETMASK, mgmtNic.getNetmask().toString().trim());
-                vmr.xenstoreData = xenstoreData;
-            }
-        }
-
-        final VM vm = VM.create(conn, vmr);
-        s_logger.debug("Created VM " + vm.getUuid(conn) + " for " + vmSpec.getName());
-
-        final Map<String, String> vcpuParams = new HashMap<String, String>();
-
-        final Integer speed = vmSpec.getMinSpeed();
-        if (speed != null) {
-        int cpuWeight = _maxWeight; // cpu_weight
-            int utilization = 0; // max CPU cap, default is unlimited
-
-            // weight based allocation, CPU weight is calculated per VCPU
-            cpuWeight = (int) (speed * 0.99 / _host.getSpeed() * _maxWeight);
-            if (cpuWeight > _maxWeight) {
-                cpuWeight = _maxWeight;
-            }
-
-            if (vmSpec.getLimitCpuUse()) {
-                // CPU cap is per VM, so need to assign cap based on the number
-                // of vcpus
-                utilization = (int) (vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100);
-            }
-
-            vcpuParams.put("weight", Integer.toString(cpuWeight));
-            vcpuParams.put("cap", Integer.toString(utilization));
-
-        }
-
-        if (vcpuParams.size() > 0) {
-            vm.setVCPUsParams(conn, vcpuParams);
-        }
-
-        final String bootArgs = vmSpec.getBootArgs();
-        if (bootArgs != null && bootArgs.length() > 0) {
-            // send boot args for PV instances
-            String pvargs = vm.getPVArgs(conn);
-            pvargs = pvargs + vmSpec.getBootArgs().replaceAll(" ", "%");
-            vm.setPVArgs(conn, pvargs);
-            s_logger.debug("PV args are " + pvargs);
-
-            // send boot args into xenstore-data for HVM instances
-            Map<String, String> xenstoreData = new HashMap<>();
-
-            xenstoreData.put(XENSTORE_DATA_CS_INIT, bootArgs);
-            vm.setXenstoreData(conn, xenstoreData);
-            s_logger.debug("HVM args are " + bootArgs);
-        }
-
-        if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) {
-            if (vmSpec.getBootloader() == BootloaderType.CD) {
-                final DiskTO[] disks = vmSpec.getDisks();
-                for (final DiskTO disk : disks) {
-                    if (disk.getType() == Volume.Type.ISO) {
-                        final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
-                        final String osType = iso.getGuestOsType();
-                        if (osType != null) {
-                            final String isoGuestOsName = getGuestOsType(vmSpec.getPlatformEmulator());
-                            if (!isoGuestOsName.equals(guestOsTypeName)) {
-                                vmSpec.setBootloader(BootloaderType.PyGrub);
-                            }
-                        }
-                    }
-                }
-            }
-            if (vmSpec.getBootloader() == BootloaderType.CD) {
-                vm.setPVBootloader(conn, "eliloader");
-                if (!vm.getOtherConfig(conn).containsKey("install-repository")) {
-                    vm.addToOtherConfig(conn, "install-repository", "cdrom");
-                }
-            } else if (vmSpec.getBootloader() == BootloaderType.PyGrub) {
-                vm.setPVBootloader(conn, "pygrub");
-                vm.setPVBootloaderArgs(conn,CitrixHelper.getPVbootloaderArgs(guestOsTypeName));
-            } else {
-                vm.destroy(conn);
-                throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader());
-            }
-        }
-        try {
-            finalizeVmMetaData(vm, conn, vmSpec);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Unable to finalize VM MetaData: " + vmSpec);
-        }
-        return vm;
-    }
-
-    public VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List<VolumeObjectTO> listVolumeTo)
-            throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, Types.OperationNotAllowed, XenAPIException, XmlRpcException {
-        // below is redundant but keeping for consistency and code readabilty
-        final String guestOsTypeName = platformEmulator;
-        if (guestOsTypeName == null) {
-            final String msg = " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType
-                    + ". you can choose 'Other install media' to run it as HVM";
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        final VM template = getVM(conn, guestOsTypeName);
-        final VM vm = template.createClone(conn, vmName);
-        vm.setIsATemplate(conn, false);
-        final Map<VDI, VolumeObjectTO> vdiMap = new HashMap<VDI, VolumeObjectTO>();
-        for (final VolumeObjectTO volume : listVolumeTo) {
-            final String vdiUuid = volume.getPath();
-            try {
-                final VDI vdi = VDI.getByUuid(conn, vdiUuid);
-                vdiMap.put(vdi, volume);
-            } catch (final Types.UuidInvalid e) {
-                s_logger.warn("Unable to find vdi by uuid: " + vdiUuid + ", skip it");
-            }
-        }
-        for (final Map.Entry<VDI, VolumeObjectTO> entry : vdiMap.entrySet()) {
-            final VDI vdi = entry.getKey();
-            final VolumeObjectTO volumeTO = entry.getValue();
-            final VBD.Record vbdr = new VBD.Record();
-            vbdr.VM = vm;
-            vbdr.VDI = vdi;
-            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
-                vbdr.bootable = true;
-                vbdr.unpluggable = false;
-            } else {
-                vbdr.bootable = false;
-                vbdr.unpluggable = true;
-            }
-            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;
-    }
-
-    protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder) {
-        final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder);
-        return details != null && details.equals("1");
-    }
-
-    protected String deleteSnapshotBackup(final Connection conn, final Long dcId, final Long accountId, final Long volumeId, final String secondaryStorageMountPath,
-            final String backupUUID) {
-
-        // If anybody modifies the formatting below again, I'll skin them
-        final String result = callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(),
-                "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath);
-
-        return result;
-    }
-
-    public void destroyPatchVbd(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException {
-        try {
-            if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) {
-                return;
-            }
-            final Set<VM> vms = VM.getByNameLabel(conn, vmName);
-            for (final VM vm : vms) {
-                final Set<VBD> vbds = vm.getVBDs(conn);
-                for (final VBD vbd : vbds) {
-                    if (vbd.getType(conn) == Types.VbdType.CD) {
-                        vbd.eject(conn);
-                        vbd.destroy(conn);
-                        break;
-                    }
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e);
-        }
-    }
-
-    public synchronized void destroyTunnelNetwork(final Connection conn, final Network nw, final long hostId) {
-        try {
-            final String bridge = nw.getBridge(conn);
-            final String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge, "cs_host_id", ((Long) hostId).toString());
-            final String[] res = result.split(":");
-            if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
-                // TODO: Should make this error not fatal?
-                // Can Concurrent VM shutdown/migration/reboot events can cause
-                // this method
-                // to be executed on a bridge which has already been removed?
-                throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge + ":" + result);
-            }
-            return;
-        } catch (final Exception e) {
-            s_logger.warn("destroyTunnelNetwork failed:", e);
-            return;
-        }
-    }
-
-    void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) {
-        try {
-            final Set<VDI> vdis = VDI.getByNameLabel(conn, nameLabel);
-            if (vdis.size() != 1) {
-                s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel);
-                return;
-            }
-            for (final VDI vdi : vdis) {
-                try {
-                    vdi.destroy(conn);
-                } catch (final Exception e) {
-                    final String msg = "Failed to destroy VDI : " + nameLabel + "due to " + e.toString() + "\n Force deleting VDI using system 'rm' command";
-                    s_logger.warn(msg);
-                    try {
-                        final String srUUID = vdi.getSR(conn).getUuid(conn);
-                        final String vdiUUID = vdi.getUuid(conn);
-                        final String vdifile = "/var/run/sr-mount/" + srUUID + "/" + vdiUUID + ".vhd";
-                        callHostPluginAsync(conn, "vmopspremium", "remove_corrupt_vdi", 10, "vdifile", vdifile);
-                    } catch (final Exception e2) {
-                        s_logger.warn(e2);
-                    }
-                }
-            }
-        } catch (final Exception e) {
-        }
-    }
-
-    public void disableVlanNetwork(final Connection conn, final Network network) {
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    public boolean doPingTest(final Connection conn, final String computingHostIp) {
-        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
-        try {
-            sshConnection.connect(null, 60000, 60000);
-            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
-                throw new CloudRuntimeException("Unable to authenticate");
-            }
-
-            final String cmd = "ping -c 2 " + computingHostIp;
-            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
-                throw new CloudRuntimeException("Cannot ping host " + computingHostIp + " from host " + _host.getIp());
-            }
-            return true;
-        } catch (final Exception e) {
-            s_logger.warn("Catch exception " + e.toString(), e);
-            return false;
-        } finally {
-            sshConnection.close();
-        }
-    }
-
-    public boolean doPingTest(final Connection conn, final String domRIp, final String vmIp) {
-        final String args = "-i " + domRIp + " -p " + vmIp;
-        final String result = callHostPlugin(conn, "vmops", "pingtest", "args", args);
-        if (result == null || result.isEmpty()) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * enableVlanNetwork creates a Network object, Vlan object, and thereby a
-     * tagged PIF object in Xapi.
-     *
-     * In XenServer, VLAN is added by - Create a network, which is unique
-     * cluster wide. - Find the PIF that you want to create the VLAN on. -
-     * Create a VLAN using the network and the PIF. As a result of this
-     * operation, a tagged PIF object is also created.
-     *
-     * Here is a list of problems with clustered Xapi implementation that we are
-     * trying to circumvent. - There can be multiple Networks with the same
-     * name-label so searching using name-label is not unique. - There are no
-     * other ways to search for Networks other than listing all of them which is
-     * not efficient in our implementation because we can have over 4000 VLAN
-     * networks. - In a clustered situation, it's possible for both hosts to
-     * detect that the Network is missing and both creates it. This causes a lot
-     * of problems as one host may be using one Network and another may be using
-     * a different network for their VMs. This causes problems in migration
-     * because the VMs are logically attached to different networks in Xapi's
-     * database but in reality, they are attached to the same network.
-     *
-     * To work around these problems, we do the following.
-     *
-     * - When creating the VLAN network, we name it as VLAN-UUID of the Network
-     * it is created on-VLAN Tag. Because VLAN tags is unique with one
-     * particular network, this is a unique name-label to quickly retrieve the
-     * the VLAN network with when we need it again. - When we create the VLAN
-     * network, we add a timestamp and a random number as a tag into the
-     * network. Then instead of creating VLAN on that network, we actually
-     * retrieve the Network again and this time uses the VLAN network with
-     * lowest timestamp or lowest random number as the VLAN network. This allows
-     * VLAN creation to happen on multiple hosts concurrently but even if two
-     * VLAN networks were created with the same name, only one of them is used.
-     *
-     * One cavaet about this approach is that it relies on the timestamp to be
-     * relatively accurate among different hosts.
-     *
-     * @param conn
-     *            Xapi Connection
-     * @param tag
-     *            VLAN tag
-     * @param network
-     *            network on this host to create the VLAN on.
-     * @return VLAN Network created.
-     * @throws XenAPIException
-     * @throws XmlRpcException
-     */
-    protected Network enableVlanNetwork(final Connection conn, final long tag, final XsLocalNetwork network) throws XenAPIException, XmlRpcException {
-        Network vlanNetwork = null;
-        final String oldName = "VLAN" + Long.toString(tag);
-        final String newName = "VLAN-" + network.getNetworkRecord(conn).uuid + "-" + tag;
-        XsLocalNetwork vlanNic = getNetworkByName(conn, newName);
-        if (vlanNic == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Couldn't find vlan network with the new name so trying old name: " + oldName);
-            }
-            vlanNic = getNetworkByName(conn, oldName);
-            if (vlanNic != null) {
-                s_logger.info("Renaming VLAN with old name " + oldName + " to " + newName);
-                vlanNic.getNetwork().setNameLabel(conn, newName);
-            }
-        }
-        if (vlanNic == null) { // Can't find it, then create it.
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.getIp());
-            }
-            final Network.Record nwr = new Network.Record();
-            nwr.nameLabel = newName;
-            nwr.tags = new HashSet<String>();
-            nwr.tags.add(generateTimeStamp());
-            vlanNetwork = Network.create(conn, nwr);
-            vlanNic = getNetworkByName(conn, newName);
-            if (vlanNic == null) { // Still vlanNic is null means we could not
-                // create it for some reason and no exception
-                // capture happened.
-                throw new CloudRuntimeException("Could not find/create vlan network with name: " + newName);
-            }
-        }
-
-        final PIF nPif = network.getPif(conn);
-        final PIF.Record nPifr = network.getPifRecord(conn);
-
-        vlanNetwork = vlanNic.getNetwork();
-        if (vlanNic.getPif(conn) != null) {
-            return vlanNetwork;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Creating VLAN " + tag + " on host " + _host.getIp() + " on device " + nPifr.device);
-        }
-        final VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork);
-        if (vlan != null) {
-            final VLAN.Record vlanr = vlan.getRecord(conn);
-            if (vlanr != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("VLAN is created for " + tag + ".  The uuid is " + vlanr.uuid);
-                }
-            }
-        }
-        return vlanNetwork;
-    }
-
-    @Override
-    public RebootAnswer execute(final RebootCommand cmd) {
-        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixRebootCommandWrapper. "
-                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
-    }
-
-    @Override
-    public StartAnswer execute(final StartCommand cmd) {
-        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStartCommandWrapper. "
-                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
-    }
-
-    @Override
-    public StopAnswer execute(final StopCommand cmd) {
-        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStopCommandWrapper. "
-                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
-    }
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIP, final String script, final String args) {
-        // Timeout is 120 seconds by default
-        return executeInVR(routerIP, script, args, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
-    }
-
-    @Override
-    public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) {
-        Pair<Boolean, String> result;
-        String cmdline = "/opt/cloud/bin/router_proxy.sh " + script + " " + routerIP + " " + args;
-        // semicolon need to be escape for bash
-        cmdline = cmdline.replaceAll(";", "\\\\;");
-        try {
-            s_logger.debug("Executing command in VR: " + cmdline);
-            result = SshHelper.sshExecute(_host.getIp(), 22, _username, null, _password.peek(), cmdline, VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout);
-        } catch (final Exception e) {
-            return new ExecutionResult(false, e.getMessage());
-        }
-        return new ExecutionResult(result.first(), result.second());
-    }
-
-    @Override
-    public Answer executeRequest(final Command cmd) {
-        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
-        try {
-            return wrapper.execute(cmd, this);
-        } catch (final Exception e) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) {
-        final StringBuilder caps = new StringBuilder();
-        try {
-
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final Host.Record hr = host.getRecord(conn);
-
-            Map<String, String> details = cmd.getHostDetails();
-            if (details == null) {
-                details = new HashMap<String, String>();
-            }
-
-            String productBrand = hr.softwareVersion.get("product_brand");
-            if (productBrand == null) {
-                productBrand = hr.softwareVersion.get("platform_name");
-            }
-            details.put("product_brand", productBrand);
-            details.put("product_version", _host.getProductVersion());
-            if (hr.softwareVersion.get("product_version_text_short") != null) {
-                details.put("product_version_text_short", hr.softwareVersion.get("product_version_text_short"));
-                cmd.setHypervisorVersion(hr.softwareVersion.get("product_version_text_short"));
-
-                cmd.setHypervisorVersion(_host.getProductVersion());
-            }
-            if (_privateNetworkName != null) {
-                details.put("private.network.device", _privateNetworkName);
-            }
-
-            cmd.setHostDetails(details);
-            cmd.setName(hr.nameLabel);
-            cmd.setGuid(_host.getUuid());
-            cmd.setPool(_host.getPool());
-            cmd.setDataCenter(Long.toString(_dcId));
-            for (final String cap : hr.capabilities) {
-                if (cap.length() > 0) {
-                    caps.append(cap).append(" , ");
-                }
-            }
-            if (caps.length() > 0) {
-                caps.delete(caps.length() - 3, caps.length());
-            }
-            cmd.setCaps(caps.toString());
-
-            cmd.setSpeed(_host.getSpeed());
-            cmd.setCpuSockets(_host.getCpuSockets());
-            cmd.setCpus(_host.getCpus());
-
-            final HostMetrics hm = host.getMetrics(conn);
-
-            long ram = 0;
-            long dom0Ram = 0;
-            ram = hm.getMemoryTotal(conn);
-            final Set<VM> vms = host.getResidentVMs(conn);
-            for (final VM vm : vms) {
-                if (vm.getIsControlDomain(conn)) {
-                    dom0Ram = vm.getMemoryStaticMax(conn);
-                    break;
-                }
-            }
-
-            ram = (long) ((ram - dom0Ram - _xsMemoryUsed) * _xsVirtualizationFactor);
-            cmd.setMemory(ram);
-            cmd.setDom0MinMemory(dom0Ram);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Total Ram: " + ram + " dom0 Ram: " + dom0Ram);
-            }
-
-            PIF pif = PIF.getByUuid(conn, _host.getPrivatePif());
-            PIF.Record pifr = pif.getRecord(conn);
-            if (pifr.IP != null && pifr.IP.length() > 0) {
-                cmd.setPrivateIpAddress(pifr.IP);
-                cmd.setPrivateMacAddress(pifr.MAC);
-                cmd.setPrivateNetmask(pifr.netmask);
-            } else {
-                cmd.setPrivateIpAddress(_host.getIp());
-                cmd.setPrivateMacAddress(pifr.MAC);
-                cmd.setPrivateNetmask("255.255.255.0");
-            }
-
-            pif = PIF.getByUuid(conn, _host.getPublicPif());
-            pifr = pif.getRecord(conn);
-            if (pifr.IP != null && pifr.IP.length() > 0) {
-                cmd.setPublicIpAddress(pifr.IP);
-                cmd.setPublicMacAddress(pifr.MAC);
-                cmd.setPublicNetmask(pifr.netmask);
-            }
-
-            if (_host.getStoragePif1() != null) {
-                pif = PIF.getByUuid(conn, _host.getStoragePif1());
-                pifr = pif.getRecord(conn);
-                if (pifr.IP != null && pifr.IP.length() > 0) {
-                    cmd.setStorageIpAddress(pifr.IP);
-                    cmd.setStorageMacAddress(pifr.MAC);
-                    cmd.setStorageNetmask(pifr.netmask);
-                }
-            }
-
-            if (_host.getStoragePif2() != null) {
-                pif = PIF.getByUuid(conn, _host.getStoragePif2());
-                pifr = pif.getRecord(conn);
-                if (pifr.IP != null && pifr.IP.length() > 0) {
-                    cmd.setStorageIpAddressDeux(pifr.IP);
-                    cmd.setStorageMacAddressDeux(pifr.MAC);
-                    cmd.setStorageNetmaskDeux(pifr.netmask);
-                }
-            }
-
-            final Map<String, String> configs = hr.otherConfig;
-            cmd.setIqn(configs.get("iscsi_iqn"));
-
-            cmd.setPod(_pod);
-            cmd.setVersion(CitrixResourceBase.class.getPackage().getImplementationVersion());
-
-            try {
-                final String cmdLine = "xe sm-list | grep \"resigning of duplicates\"";
-
-                final XenServerUtilitiesHelper xenServerUtilitiesHelper = getXenServerUtilitiesHelper();
-
-                Pair<Boolean, String> result = xenServerUtilitiesHelper.executeSshWrapper(_host.getIp(), 22, _username, null, getPwdFromQueue(), cmdLine);
-
-                boolean supportsClonedVolumes = result != null && result.first() != null && result.first() &&
-                        result.second() != null && result.second().length() > 0;
-
-                cmd.setSupportsClonedVolumes(supportsClonedVolumes);
-            } catch (NumberFormatException ex) {
-                s_logger.warn("Issue sending 'xe sm-list' via SSH to XenServer host: " + ex.getMessage());
-            }
-        } catch (final XmlRpcException e) {
-            throw new CloudRuntimeException("XML RPC Exception: " + e.getMessage(), e);
-        } catch (final XenAPIException e) {
-            throw new CloudRuntimeException("XenAPIException: " + e.toString(), e);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Exception: " + e.toString(), e);
-        }
-    }
-
-    protected void finalizeVmMetaData(final VM vm, final Connection conn, final VirtualMachineTO vmSpec) throws Exception {
-
-        final Map<String, String> details = vmSpec.getDetails();
-        if (details != null) {
-            final String platformstring = details.get("platform");
-            if (platformstring != null && !platformstring.isEmpty()) {
-                final Map<String, String> platform = StringUtils.stringToMap(platformstring);
-                vm.setPlatform(conn, platform);
-            } else {
-                final String timeoffset = details.get("timeoffset");
-                if (timeoffset != null) {
-                    final Map<String, String> platform = vm.getPlatform(conn);
-                    platform.put("timeoffset", timeoffset);
-                    vm.setPlatform(conn, platform);
-                }
-                final String coresPerSocket = details.get("cpu.corespersocket");
-                if (coresPerSocket != null) {
-                    final Map<String, String> platform = vm.getPlatform(conn);
-                    platform.put("cores-per-socket", coresPerSocket);
-                    vm.setPlatform(conn, platform);
-                }
-            }
-            if (!BootloaderType.CD.equals(vmSpec.getBootloader())) {
-                final String xenservertoolsversion = details.get("hypervisortoolsversion");
-                if ((xenservertoolsversion == null || !xenservertoolsversion.equalsIgnoreCase("xenserver61")) && vmSpec.getGpuDevice() == null) {
-                    final Map<String, String> platform = vm.getPlatform(conn);
-                    platform.remove("device_id");
-                    vm.setPlatform(conn, platform);
-                }
-            }
-        }
-    }
-
-    /**
-     * This method just creates a XenServer network following the tunnel network
-     * naming convention
-     */
-    public synchronized Network findOrCreateTunnelNetwork(final Connection conn, final String nwName) {
-        try {
-            Network nw = null;
-            final Network.Record rec = new Network.Record();
-            final Set<Network> networks = Network.getByNameLabel(conn, nwName);
-
-            if (networks.size() == 0) {
-                rec.nameDescription = "tunnel network id# " + nwName;
-                rec.nameLabel = nwName;
-                // Initialize the ovs-host-setup to avoid error when doing
-                // get-param in plugin
-                final Map<String, String> otherConfig = new HashMap<String, String>();
-                otherConfig.put("ovs-host-setup", "");
-                // Mark 'internal network' as shared so bridge gets
-                // automatically created on each host in the cluster
-                // when VM with vif connected to this internal network is
-                // started
-                otherConfig.put("assume_network_is_shared", "true");
-                rec.otherConfig = otherConfig;
-                nw = Network.create(conn, rec);
-                s_logger.debug("### XenServer network for tunnels created:" + nwName);
-            } else {
-                nw = networks.iterator().next();
-                s_logger.debug("XenServer network for tunnels found:" + nwName);
-            }
-            return nw;
-        } catch (final Exception e) {
-            s_logger.warn("createTunnelNetwork failed", e);
-            return null;
-        }
-    }
-
-    void forceShutdownVM(final Connection conn, final VM vm) {
-        try {
-            final Long domId = vm.getDomid(conn);
-            callHostPlugin(conn, "vmopspremium", "forceShutdownVM", "domId", domId.toString());
-            vm.powerStateReset(conn);
-            vm.destroy(conn);
-        } catch (final Exception e) {
-            final String msg = "forceShutdown failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    protected String generateTimeStamp() {
-        return new StringBuilder("CsCreateTime-").append(System.currentTimeMillis()).append("-").append(Rand.nextInt(Integer.MAX_VALUE)).toString();
-    }
-
-    @Override
-    public IAgentControl getAgentControl() {
-        return _agentControl;
-    }
-
-    protected String getArgsString(final Map<String, String> args) {
-        final StringBuilder argString = new StringBuilder();
-        for (final Map.Entry<String, String> arg : args.entrySet()) {
-            argString.append(arg.getKey() + ": " + arg.getValue() + ", ");
-        }
-        return argString.toString();
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        return null;
-    }
-
-    public Connection getConnection() {
-        return ConnPool.connect(_host.getUuid(), _host.getPool(), _host.getIp(), _username, _password, _wait);
-    }
-
-    protected Pair<VM, VM.Record> getControlDomain(final Connection conn) throws XenAPIException, XmlRpcException {
-        final Host host = Host.getByUuid(conn, _host.getUuid());
-        Set<VM> vms = null;
-        vms = host.getResidentVMs(conn);
-        for (final VM vm : vms) {
-            if (vm.getIsControlDomain(conn)) {
-                return new Pair<VM, VM.Record>(vm, vm.getRecord(conn));
-            }
-        }
-
-        throw new CloudRuntimeException("Com'on no control domain?  What the crap?!#@!##$@");
-    }
-
-    protected VIF getCorrectVif(final Connection conn, final VM router, final IpAddressTO ip) throws XmlRpcException, XenAPIException {
-        final NicTO nic = new NicTO();
-        nic.setType(ip.getTrafficType());
-        nic.setName(ip.getNetworkName());
-        if (ip.getBroadcastUri() == null) {
-            nic.setBroadcastType(BroadcastDomainType.Native);
-        } else {
-            final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-            nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
-            nic.setBroadcastUri(uri);
-        }
-        final Network network = getNetwork(conn, nic);
-        // Determine the correct VIF on DomR to associate/disassociate the
-        // IP address with
-        final Set<VIF> routerVIFs = router.getVIFs(conn);
-        for (final VIF vif : routerVIFs) {
-            final Network vifNetwork = vif.getNetwork(conn);
-            if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) {
-                return vif;
-            }
-        }
-        return null;
-    }
-
-    protected VIF getCorrectVif(final Connection conn, final VM router, final Network network) throws XmlRpcException, XenAPIException {
-        final Set<VIF> routerVIFs = router.getVIFs(conn);
-        for (final VIF vif : routerVIFs) {
-            final Network vifNetwork = vif.getNetwork(conn);
-            if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) {
-                return vif;
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(final long id) {
-        try {
-            if (!pingXAPI()) {
-                Thread.sleep(1000);
-                if (!pingXAPI()) {
-                    s_logger.warn("can not ping xenserver " + _host.getUuid());
-                    return null;
-                }
-            }
-            final Connection conn = getConnection();
-            if (!_canBridgeFirewall && !_isOvs) {
-                return new PingRoutingCommand(getType(), id, getHostVmStateReport(conn));
-            } else if (_isOvs) {
-                final List<Pair<String, Long>> ovsStates = ovsFullSyncStates();
-                return new PingRoutingWithOvsCommand(getType(), id, getHostVmStateReport(conn), ovsStates);
-            } else {
-                final HashMap<String, Pair<Long, Long>> nwGrpStates = syncNetworkGroups(conn, id);
-                return new PingRoutingWithNwGroupsCommand(getType(), id, getHostVmStateReport(conn), nwGrpStates);
-            }
-        } catch (final Exception e) {
-            s_logger.warn("Unable to get current status", e);
-            return null;
-        }
-    }
-
-    protected double getDataAverage(final Node dataNode, final int col, final int numRows) {
-        double value = 0;
-        final double dummy = 0;
-        int numRowsUsed = 0;
-        for (int row = 0; row < numRows; row++) {
-            final Node data = dataNode.getChildNodes().item(numRows - 1 - row).getChildNodes().item(col + 1);
-            final Double currentDataAsDouble = Double.valueOf(getXMLNodeValue(data));
-            if (!currentDataAsDouble.equals(Double.NaN)) {
-                numRowsUsed += 1;
-                value += currentDataAsDouble;
-            }
-        }
-
-        if (numRowsUsed == 0) {
-            if (!Double.isInfinite(value) && !Double.isNaN(value)) {
-                return value;
-            } else {
-                s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows=0");
-                return dummy;
-            }
-        } else {
-            if (!Double.isInfinite(value / numRowsUsed) && !Double.isNaN(value / numRowsUsed)) {
-                return value / numRowsUsed;
-            } else {
-                s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows>0");
-                return dummy;
-            }
-        }
-
-    }
-
-    public HashMap<String, HashMap<String, VgpuTypesInfo>> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException {
-        return null;
-    }
-
-    protected String getGuestOsType(String platformEmulator) {
-        if (org.apache.commons.lang.StringUtils.isBlank(platformEmulator)) {
-            s_logger.debug("no guest OS type, start it as HVM guest");
-            platformEmulator = "Other install media";
-        }
-        return platformEmulator;
-    }
-
-    public XsHost getHost() {
-        return _host;
-    }
-
-    public int getMigrateWait() {
-        return _migratewait;
-    }
-
-    public StorageSubsystemCommandHandler getStorageHandler() {
-        return storageHandler;
-    }
-
-    protected boolean getHostInfo(final Connection conn) throws IllegalArgumentException {
-        try {
-            final Host myself = Host.getByUuid(conn, _host.getUuid());
-            Set<HostCpu> hcs = null;
-            for (int i = 0; i < 10; i++) {
-                hcs = myself.getHostCPUs(conn);
-                if (hcs != null) {
-                    _host.setCpus(hcs.size());
-                    if (_host.getCpus() > 0) {
-                        break;
-                    }
-                }
-                Thread.sleep(5000);
-            }
-            if (_host.getCpus() <= 0) {
-                throw new CloudRuntimeException("Cannot get the numbers of cpu from XenServer host " + _host.getIp());
-            }
-            final Map<String, String> cpuInfo = myself.getCpuInfo(conn);
-            if (cpuInfo.get("socket_count") != null) {
-                _host.setCpuSockets(Integer.parseInt(cpuInfo.get("socket_count")));
-            }
-            // would hcs be null we would have thrown an exception on condition
-            // (_host.getCpus() <= 0) by now
-            for (final HostCpu hc : hcs) {
-                _host.setSpeed(hc.getSpeed(conn).intValue());
-                break;
-            }
-            final Host.Record hr = myself.getRecord(conn);
-            _host.setProductVersion(CitrixHelper.getProductVersion(hr));
-
-            final XsLocalNetwork privateNic = getManagementNetwork(conn);
-            _privateNetworkName = privateNic.getNetworkRecord(conn).nameLabel;
-            _host.setPrivatePif(privateNic.getPifRecord(conn).uuid);
-            _host.setPrivateNetwork(privateNic.getNetworkRecord(conn).uuid);
-            _host.setSystemvmisouuid(null);
-
-            XsLocalNetwork guestNic = null;
-            if (_guestNetworkName != null && !_guestNetworkName.equals(_privateNetworkName)) {
-                guestNic = getNetworkByName(conn, _guestNetworkName);
-                if (guestNic == null) {
-                    s_logger.warn("Unable to find guest network " + _guestNetworkName);
-                    throw new IllegalArgumentException("Unable to find guest network " + _guestNetworkName + " for host " + _host.getIp());
-                }
-            } else {
-                guestNic = privateNic;
-                _guestNetworkName = _privateNetworkName;
-            }
-            _host.setGuestNetwork(guestNic.getNetworkRecord(conn).uuid);
-            _host.setGuestPif(guestNic.getPifRecord(conn).uuid);
-
-            XsLocalNetwork publicNic = null;
-            if (_publicNetworkName != null && !_publicNetworkName.equals(_guestNetworkName)) {
-                publicNic = getNetworkByName(conn, _publicNetworkName);
-                if (publicNic == null) {
-                    s_logger.warn("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp());
-                    throw new IllegalArgumentException("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp());
-                }
-            } else {
-                publicNic = guestNic;
-                _publicNetworkName = _guestNetworkName;
-            }
-            _host.setPublicPif(publicNic.getPifRecord(conn).uuid);
-            _host.setPublicNetwork(publicNic.getNetworkRecord(conn).uuid);
-            if (_storageNetworkName1 == null) {
-                _storageNetworkName1 = _guestNetworkName;
-            }
-            XsLocalNetwork storageNic1 = null;
-            storageNic1 = getNetworkByName(conn, _storageNetworkName1);
-            if (storageNic1 == null) {
-                s_logger.warn("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp());
-                throw new IllegalArgumentException("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp());
-            } else {
-                _host.setStorageNetwork1(storageNic1.getNetworkRecord(conn).uuid);
-                _host.setStoragePif1(storageNic1.getPifRecord(conn).uuid);
-            }
-
-            XsLocalNetwork storageNic2 = null;
-            if (_storageNetworkName2 != null) {
-                storageNic2 = getNetworkByName(conn, _storageNetworkName2);
-                if (storageNic2 != null) {
-                    _host.setStoragePif2(storageNic2.getPifRecord(conn).uuid);
-                }
-            }
-
-            s_logger.info("XenServer Version is " + _host.getProductVersion() + " for host " + _host.getIp());
-            s_logger.info("Private Network is " + _privateNetworkName + " for host " + _host.getIp());
-            s_logger.info("Guest Network is " + _guestNetworkName + " for host " + _host.getIp());
-            s_logger.info("Public Network is " + _publicNetworkName + " for host " + _host.getIp());
-
-            return true;
-        } catch (final XenAPIException e) {
-            s_logger.warn("Unable to get host information for " + _host.getIp(), e);
-            return false;
-        } catch (final Exception e) {
-            s_logger.warn("Unable to get host information for " + _host.getIp(), e);
-            return false;
-        }
-    }
-
-    public HostStatsEntry getHostStats(final Connection conn, final GetHostStatsCommand cmd, final String hostGuid, final long hostId) {
-
-        final HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0);
-        final Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1
-        // for host
-
-        if (rrdData == null) {
-            return null;
-        }
-
-        final Integer numRows = (Integer) rrdData[0];
-        final Integer numColumns = (Integer) rrdData[1];
-        final Node legend = (Node) rrdData[2];
-        final Node dataNode = (Node) rrdData[3];
-
-        final NodeList legendChildren = legend.getChildNodes();
-        for (int col = 0; col < numColumns; col++) {
-
-            if (legendChildren == null || legendChildren.item(col) == null) {
-                continue;
-            }
-
-            final String columnMetadata = getXMLNodeValue(legendChildren.item(col));
-
-            if (columnMetadata == null) {
-                continue;
-            }
-
-            final String[] columnMetadataList = columnMetadata.split(":");
-
-            if (columnMetadataList.length != 4) {
-                continue;
-            }
-
-            final String type = columnMetadataList[1];
-            final String param = columnMetadataList[3];
-
-            if (type.equalsIgnoreCase("host")) {
-
-                if (param.matches("pif_eth0_rx")) {
-                    hostStats.setNetworkReadKBs(getDataAverage(dataNode, col, numRows) / 1000);
-                } else if (param.matches("pif_eth0_tx")) {
-                    hostStats.setNetworkWriteKBs(getDataAverage(dataNode, col, numRows) / 1000);
-                } else if (param.contains("memory_total_kib")) {
-                    hostStats.setTotalMemoryKBs(getDataAverage(dataNode, col, numRows));
-                } else if (param.contains("memory_free_kib")) {
-                    hostStats.setFreeMemoryKBs(getDataAverage(dataNode, col, numRows));
-                } else if (param.matches("cpu_avg")) {
-                    // hostStats.setNumCpus(hostStats.getNumCpus() + 1);
-                    hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows));
-                }
-
-                /*
-                 * if (param.contains("loadavg")) {
-                 * hostStats.setAverageLoad((hostStats.getAverageLoad() +
-                 * getDataAverage(dataNode, col, numRows))); }
-                 */
-            }
-        }
-
-        // add the host cpu utilization
-        /*
-         * if (hostStats.getNumCpus() != 0) {
-         * hostStats.setCpuUtilization(hostStats.getCpuUtilization() /
-         * hostStats.getNumCpus()); s_logger.debug("Host cpu utilization " +
-         * hostStats.getCpuUtilization()); }
-         */
-
-        return hostStats;
-    }
-
-    protected HashMap<String, HostVmStateReportEntry> getHostVmStateReport(final Connection conn) {
-
-        // TODO : new VM sync model does not require a cluster-scope report, we
-        // need to optimize
-        // the report accordingly
-        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
-        Map<VM, VM.Record> vm_map = null;
-        for (int i = 0; i < 2; i++) {
-            try {
-                vm_map = VM.getAllRecords(conn); // USE THIS TO GET ALL VMS FROM
-                // A CLUSTER
-                break;
-            } catch (final Throwable e) {
-                s_logger.warn("Unable to get vms", e);
-            }
-            try {
-                Thread.sleep(1000);
-            } catch (final InterruptedException ex) {
-
-            }
-        }
-
-        if (vm_map == null) {
-            return vmStates;
-        }
-        for (final VM.Record record : vm_map.values()) {
-            if (record.isControlDomain || record.isASnapshot || record.isATemplate) {
-                continue; // Skip DOM0
-            }
-
-            final VmPowerState ps = record.powerState;
-            final Host host = record.residentOn;
-            String host_uuid = null;
-            if (!isRefNull(host)) {
-                try {
-                    host_uuid = host.getUuid(conn);
-                } catch (final BadServerResponse e) {
-                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
-                } catch (final XenAPIException e) {
-                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
-                } catch (final XmlRpcException e) {
-                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
-                }
-
-                if (host_uuid.equalsIgnoreCase(_host.getUuid())) {
-                    vmStates.put(record.nameLabel, new HostVmStateReportEntry(convertToPowerState(ps), host_uuid));
-                }
-            }
-        }
-
-        return vmStates;
-    }
-
-    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername,
-            final String chapInitiatorPassword, final boolean ignoreIntroduceException) {
-
-        return getIscsiSR(conn, srNameLabel, target, path, chapInitiatorUsername,
-                chapInitiatorPassword, false, SRType.LVMOISCSI.toString(),
-                ignoreIntroduceException);
-    }
-
-    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername,
-            final String chapInitiatorPassword, final boolean resignature, final boolean ignoreIntroduceException) {
-
-        return getIscsiSR(conn, srNameLabel, target, path, chapInitiatorUsername,
-                chapInitiatorPassword, resignature, SRType.LVMOISCSI.toString(),
-                ignoreIntroduceException);
-    }
-
-    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername,
-            final String chapInitiatorPassword, final boolean resignature, final  String srType, final boolean ignoreIntroduceException) {
-        synchronized (srNameLabel.intern()) {
-            final Map<String, String> deviceConfig = new HashMap<String, String>();
-            try {
-                if (path.endsWith("/")) {
-                    path = path.substring(0, path.length() - 1);
-                }
-
-                final String tmp[] = path.split("/");
-                if (tmp.length != 3) {
-                    final String msg = "Wrong iscsi path " + path + " it should be /targetIQN/LUN";
-                    s_logger.warn(msg);
-                    throw new CloudRuntimeException(msg);
-                }
-                final String targetiqn = tmp[1].trim();
-                final String lunid = tmp[2].trim();
-                String scsiid = "";
-
-                //Throws an exception if SR already exists and is attached
-                checkIfIscsiSrExisits(conn, srNameLabel, target, targetiqn, lunid);
-
-                // We now know the SR is not attached to the XenServer. We probe the
-                // LUN to see if an SR was already exists on it, if so, we just
-                // attach it or else we create a brand new SR
-
-                deviceConfig.put("target", target);
-                deviceConfig.put("targetIQN", targetiqn);
-
-                if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorPassword)) {
-                    deviceConfig.put("chapuser", chapInitiatorUsername);
-                    deviceConfig.put("chappassword", chapInitiatorPassword);
-                }
-
-                final Host host = Host.getByUuid(conn, _host.getUuid());
-                final Map<String, String> smConfig = new HashMap<String, String>();
-                SR sr = null;
-                String pooluuid = null;
-
-                if (SRType.LVMOISCSI.equals(srType)) {
-                    scsiid = probeScisiId(conn, host, deviceConfig, srType, srNameLabel, lunid, smConfig);
-                    deviceConfig.put("SCSIid", scsiid);
-
-                    String result = SR.probe(conn, host, deviceConfig, srType, smConfig);
-                    if (result.indexOf("<UUID>") != -1) {
-                        pooluuid = result.substring(result.indexOf("<UUID>") + 6, result.indexOf("</UUID>")).trim();
-                    }
-                }
-
-                if (pooluuid == null || pooluuid.length() != 36) {
-                    sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, srType, "user", true, smConfig);
-                }
-                else {
-                    if (resignature) {
-                        // We resignature the SR for managed storage if needed. At the end of this
-                        // we have an SR which is ready to be attached. For VHDoISCSI SR,
-                        // we don't need to resignature
-                        pooluuid = resignatureIscsiSr(conn, host, deviceConfig, srNameLabel, smConfig);
-                    }
-                    sr = introduceAndPlugIscsiSr(conn, pooluuid, srNameLabel, srType, smConfig, deviceConfig, ignoreIntroduceException);
-                }
-
-                sr.scan(conn);
-                return sr;
-
-            } catch (final XenAPIException e) {
-                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.toString();
-                s_logger.warn(msg, e);
-                throw new CloudRuntimeException(msg, e);
-            } catch (final Exception e) {
-                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.getMessage();
-                s_logger.warn(msg, e);
-                throw new CloudRuntimeException(msg, e);
-            }
-        }
-    }
-
-    private SR introduceAndPlugIscsiSr(Connection conn, String pooluuid, String srNameLabel, String type, Map<String, String> smConfig, Map<String, String> deviceConfig, boolean ignoreIntroduceException) throws XmlRpcException, XenAPIException {
-        SR sr = null;
-        try {
-            sr = SR.introduce(conn, pooluuid, srNameLabel, srNameLabel, type, "user", true, smConfig);
-        } catch (final XenAPIException ex) {
-            if (ignoreIntroduceException) {
-                return sr;
-            }
-
-            throw ex;
-        }
-
-        final Set<Host> setHosts = Host.getAll(conn);
-
-        if (setHosts == null) {
-            final String msg = "Unable to create iSCSI SR " + deviceConfig + " due to hosts not available.";
-
-            s_logger.warn(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        for (final Host currentHost : setHosts) {
-            final PBD.Record rec = new PBD.Record();
-
-            rec.deviceConfig = deviceConfig;
-            rec.host = currentHost;
-            rec.SR = sr;
-
-            final PBD pbd = PBD.create(conn, rec);
-
-            pbd.plug(conn);
-        }
-
-        return sr;
-    }
-
-    private String resignatureIscsiSr(Connection conn, Host host, Map<String, String> deviceConfig, String srNameLabel, Map<String, String> smConfig)
-            throws XmlRpcException, XenAPIException {
-        String pooluuid;
-
-        try {
-            SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, SRType.RELVMOISCSI.toString(), "user", true, smConfig);
-
-            // The successful outcome of SR.create (right above) is to throw an exception of type XenAPIException (with expected
-            // toString() text) after resigning the metadata (we indicated to perform a resign by passing in SRType.RELVMOISCSI.toString()).
-            // That being the case, if this CloudRuntimeException statement is executed, there appears to have been some kind
-            // of failure in the execution of the above SR.create (resign) method.
-            throw new CloudRuntimeException("Problem resigning the metadata");
-        }
-        catch (XenAPIException ex) {
-            String msg = ex.toString();
-
-            if (!msg.contains("successfully resigned")) {
-                throw ex;
-            }
-
-            String type = SRType.LVMOISCSI.toString();
-            String result = SR.probe(conn, host, deviceConfig, type, smConfig);
-
-            pooluuid = null;
-
-            if (result.indexOf("<UUID>") != -1) {
-                pooluuid = result.substring(result.indexOf("<UUID>") + 6, result.indexOf("</UUID>")).trim();
-            }
-
-            if (pooluuid == null || pooluuid.length() != 36) {
-                throw new CloudRuntimeException("Non-existent or invalid SR UUID");
-            }
-        }
-
-        return pooluuid;
-    }
-
-    private void checkIfIscsiSrExisits(Connection conn, String srNameLabel, String target, String targetiqn, String lunid) throws XenAPIException, XmlRpcException {
-                final Set<SR> srs = SR.getByNameLabel(conn, srNameLabel);
-                for (final SR sr : srs) {
-                    if (!(SRType.LVMOISCSI.equals(sr.getType(conn)))) {
-                        continue;
-                    }
-                    final Set<PBD> pbds = sr.getPBDs(conn);
-                    if (pbds.isEmpty()) {
-                        continue;
-                    }
-                    final PBD pbd = pbds.iterator().next();
-                    final Map<String, String> dc = pbd.getDeviceConfig(conn);
-                    if (dc == null) {
-                        continue;
-                    }
-                    if (dc.get("target") == null) {
-                        continue;
-                    }
-                    if (dc.get("targetIQN") == null) {
-                        continue;
-                    }
-                    if (dc.get("lunid") == null) {
-                        continue;
-                    }
-                    if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) {
-                        throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ",  targetIQN:" + dc.get("targetIQN")
-                                + ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.getUuid());
-                    }
-                }
-
-    }
-
-    private String probeScisiId(Connection conn, Host host, Map<String, String> deviceConfig, String type, String srNameLabel, String lunid, Map<String, String> smConfig) throws XenAPIException, XmlRpcException {
-        SR sr = null;
-        String scsiid = null;
-
-        try {
-            sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig);
-        } catch (final XenAPIException e) {
-            final String errmsg = e.toString();
-            if (errmsg.contains("SR_BACKEND_FAILURE_107")) {
-                final String lun[] = errmsg.split("<LUN>");
-                boolean found = false;
-                for (int i = 1; i < lun.length; i++) {
-                    final int blunindex = lun[i].indexOf("<LUNid>") + 7;
-                    final int elunindex = lun[i].indexOf("</LUNid>");
-                    String ilun = lun[i].substring(blunindex, elunindex);
-                    ilun = ilun.trim();
-                    if (ilun.equals(lunid)) {
-                        final int bscsiindex = lun[i].indexOf("<SCSIid>") + 8;
-                        final int escsiindex = lun[i].indexOf("</SCSIid>");
-                        scsiid = lun[i].substring(bscsiindex, escsiindex);
-                        scsiid = scsiid.trim();
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    final String msg = "can not find LUN " + lunid + " in " + errmsg;
-                    s_logger.warn(msg);
-                    throw new CloudRuntimeException(msg);
-                }
-            } else {
-                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.toString();
-                s_logger.warn(msg, e);
-                throw new CloudRuntimeException(msg, e);
-            }
-        }
-        return scsiid;
-    }
-
-    public SR getISOSRbyVmName(final Connection conn, final String vmName) {
-        try {
-            final Set<SR> srs = SR.getByNameLabel(conn, vmName + "-ISO");
-            if (srs.size() == 0) {
-                return null;
-            } else if (srs.size() == 1) {
-                return srs.iterator().next();
-            } else {
-                final String msg = "getIsoSRbyVmName failed due to there are more than 1 SR having same Label";
-                s_logger.warn(msg);
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "getIsoSRbyVmName failed due to " + e.toString();
-            s_logger.warn(msg, e);
-        } catch (final Exception e) {
-            final String msg = "getIsoSRbyVmName failed due to " + e.getMessage();
-            s_logger.warn(msg, e);
-        }
-        return null;
-    }
-
-    public VDI getIsoVDIByURL(final Connection conn, final String vmName, final String isoURL) {
-        SR isoSR = null;
-        String mountpoint = null;
-        if (isoURL.startsWith("xs-tools")) {
-            try {
-                final String actualIsoURL = actualIsoTemplate(conn);
-                final Set<VDI> vdis = VDI.getByNameLabel(conn, actualIsoURL);
-                if (vdis.isEmpty()) {
-                    throw new CloudRuntimeException("Could not find ISO with URL: " + actualIsoURL);
-                }
-                return vdis.iterator().next();
-
-            } catch (final XenAPIException e) {
-                throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString());
-            } catch (final Exception e) {
-                throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString());
-            }
-        }
-
-        final int index = isoURL.lastIndexOf("/");
-        mountpoint = isoURL.substring(0, index);
-
-        URI uri;
-        try {
-            uri = new URI(mountpoint);
-        } catch (final URISyntaxException e) {
-            throw new CloudRuntimeException("isoURL is wrong: " + isoURL);
-        }
-        isoSR = getISOSRbyVmName(conn, vmName);
-        if (isoSR == null) {
-            isoSR = createIsoSRbyURI(conn, uri, vmName, false);
-        }
-
-        final String isoName = isoURL.substring(index + 1);
-
-        final VDI isoVDI = getVDIbyLocationandSR(conn, isoName, isoSR);
-
-        if (isoVDI != null) {
-            return isoVDI;
-        } else {
-            throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL);
-        }
-    }
-
-    private String actualIsoTemplate(final Connection conn) throws BadServerResponse, XenAPIException, XmlRpcException {
-        final Host host = Host.getByUuid(conn, _host.getUuid());
-        final Host.Record record = host.getRecord(conn);
-        final String xenBrand = record.softwareVersion.get("product_brand");
-        final String xenVersion = record.softwareVersion.get("product_version");
-        final String[] items = xenVersion.split("\\.");
-
-        // guest-tools.iso for XenServer version 7.0+
-        if ((xenBrand.equals("XenServer") || xenBrand.equals("XCP-ng")) && Integer.parseInt(items[0]) >= 7) {
-            return "guest-tools.iso";
-        }
-
-        // xs-tools.iso for older XenServer versions
-        return "xs-tools.iso";
-    }
-
-    public String getLabel() {
-        final Connection conn = getConnection();
-        final String result = callHostPlugin(conn, "ovstunnel", "getLabel");
-        return result;
-    }
-
-    protected SR getLocalEXTSR(final Connection conn) {
-        try {
-            final Map<SR, SR.Record> map = SR.getAllRecords(conn);
-            if (map != null && !map.isEmpty()) {
-                for (final Map.Entry<SR, SR.Record> entry : map.entrySet()) {
-                    final SR.Record srRec = entry.getValue();
-                    if (SRType.FILE.equals(srRec.type) || SRType.EXT.equals(srRec.type)) {
-                        final Set<PBD> pbds = srRec.PBDs;
-                        if (pbds == null) {
-                            continue;
-                        }
-                        for (final PBD pbd : pbds) {
-                            final Host host = pbd.getHost(conn);
-                            if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) {
-                                if (!pbd.getCurrentlyAttached(conn)) {
-                                    pbd.plug(conn);
-                                }
-                                final SR sr = entry.getKey();
-                                sr.scan(conn);
-                                return sr;
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.toString();
-            s_logger.warn(msg);
-        } catch (final XmlRpcException e) {
-            final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.getCause();
-            s_logger.warn(msg);
-        }
-        return null;
-    }
-
-    protected SR getLocalLVMSR(final Connection conn) {
-        try {
-            final Map<SR, SR.Record> map = SR.getAllRecords(conn);
-            if (map != null && !map.isEmpty()) {
-                for (final Map.Entry<SR, SR.Record> entry : map.entrySet()) {
-                    final SR.Record srRec = entry.getValue();
-                    if (SRType.LVM.equals(srRec.type)) {
-                        final Set<PBD> pbds = srRec.PBDs;
-                        if (pbds == null) {
-                            continue;
-                        }
-                        for (final PBD pbd : pbds) {
-                            final Host host = pbd.getHost(conn);
-                            if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) {
-                                if (!pbd.getCurrentlyAttached(conn)) {
-                                    pbd.plug(conn);
-                                }
-                                final SR sr = entry.getKey();
-                                sr.scan(conn);
-                                return sr;
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.toString();
-            s_logger.warn(msg);
-        } catch (final XmlRpcException e) {
-            final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.getCause();
-            s_logger.warn(msg);
-        }
-        return null;
-    }
-
-    public String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) {
-        String vmName = "";
-        try {
-            vmName = vm.getNameLabel(conn);
-            final List<Integer> usedDeviceNums = new ArrayList<Integer>();
-            final Set<VIF> vifs = vm.getVIFs(conn);
-            final Iterator<VIF> vifIter = vifs.iterator();
-            while (vifIter.hasNext()) {
-                final VIF vif = vifIter.next();
-                try {
-                    final String deviceId = vif.getDevice(conn);
-                    if (vm.getIsControlDomain(conn) || vif.getCurrentlyAttached(conn)) {
-                        usedDeviceNums.add(Integer.valueOf(deviceId));
-                    } else {
-                        s_logger.debug("Found unplugged VIF " + deviceId + " in VM " + vmName + " destroy it");
-                        vif.destroy(conn);
-                    }
-                } catch (final NumberFormatException e) {
-                    final String msg = "Obtained an invalid value for an allocated VIF device number for VM: " + vmName;
-                    s_logger.debug(msg, e);
-                    throw new CloudRuntimeException(msg);
-                }
-            }
-
-            for (Integer i = 0; i < _maxNics; i++) {
-                if (!usedDeviceNums.contains(i)) {
-                    s_logger.debug("Lowest available Vif device number: " + i + " for VM: " + vmName);
-                    return i.toString();
-                }
-            }
-        } catch (final XmlRpcException e) {
-            final String msg = "Caught XmlRpcException: " + e.getMessage();
-            s_logger.warn(msg, e);
-        } catch (final XenAPIException e) {
-            final String msg = "Caught XenAPIException: " + e.toString();
-            s_logger.warn(msg, e);
-        }
-
-        throw new CloudRuntimeException("Could not find available VIF slot in VM with name: " + vmName);
-    }
-
-    protected XsLocalNetwork getManagementNetwork(final Connection conn) throws XmlRpcException, XenAPIException {
-        PIF mgmtPif = null;
-        PIF.Record mgmtPifRec = null;
-        final Host host = Host.getByUuid(conn, _host.getUuid());
-        final Set<PIF> hostPifs = host.getPIFs(conn);
-        for (final PIF pif : hostPifs) {
-            final PIF.Record rec = pif.getRecord(conn);
-            if (rec.management) {
-                if (rec.VLAN != null && rec.VLAN != -1) {
-                    final String msg = new StringBuilder("Unsupported configuration.  Management network is on a VLAN.  host=").append(_host.getUuid()).append("; pif=")
-                            .append(rec.uuid).append("; vlan=").append(rec.VLAN).toString();
-                    s_logger.warn(msg);
-                    throw new CloudRuntimeException(msg);
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Management network is on pif=" + rec.uuid);
-                }
-                mgmtPif = pif;
-                mgmtPifRec = rec;
-                break;
-            }
-        }
-        if (mgmtPif == null) {
-            final String msg = "Unable to find management network for " + _host.getUuid();
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        final Bond bond = mgmtPifRec.bondSlaveOf;
-        if (!isRefNull(bond)) {
-            final String msg = "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.getUuid()
-                    + "), please move management interface to bond!";
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        final Network nk = mgmtPifRec.network;
-        final Network.Record nkRec = nk.getRecord(conn);
-        return new XsLocalNetwork(this, nk, nkRec, mgmtPif, mgmtPifRec);
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    public XsLocalNetwork getNativeNetworkForTraffic(final Connection conn, final TrafficType type, final String name) throws XenAPIException, XmlRpcException {
-        if (name != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Looking for network named " + name);
-            }
-            return getNetworkByName(conn, name);
-        }
-
-        if (type == TrafficType.Guest) {
-            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getGuestNetwork()), null, PIF.getByUuid(conn, _host.getGuestPif()), null);
-        } else if (type == TrafficType.Control) {
-            setupLinkLocalNetwork(conn);
-            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getLinkLocalNetwork()));
-        } else if (type == TrafficType.Management) {
-            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPrivateNetwork()), null, PIF.getByUuid(conn, _host.getPrivatePif()), null);
-        } else if (type == TrafficType.Public) {
-            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPublicNetwork()), null, PIF.getByUuid(conn, _host.getPublicPif()), null);
-        } else if (type == TrafficType.Storage) {
-            /*
-             * TrafficType.Storage is for secondary storage, while
-             * storageNetwork1 is for primary storage, we need better name here
-             */
-            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getStorageNetwork1()), null, PIF.getByUuid(conn, _host.getStoragePif1()), null);
-        }
-
-        throw new CloudRuntimeException("Unsupported network type: " + type);
-    }
-
-    public Network getNetwork(final Connection conn, final NicTO nic) throws XenAPIException, XmlRpcException {
-        final String name = nic.getName();
-        final XsLocalNetwork network = getNativeNetworkForTraffic(conn, nic.getType(), name);
-        if (network == null) {
-            s_logger.error("Network is not configured on the backend for nic " + nic.toString());
-            throw new CloudRuntimeException("Network for the backend is not configured correctly for network broadcast domain: " + nic.getBroadcastUri());
-        }
-        final URI uri = nic.getBroadcastUri();
-        final BroadcastDomainType type = nic.getBroadcastType();
-        if (uri != null && uri.toString().contains("untagged")) {
-            return network.getNetwork();
-        } else if (uri != null && type == BroadcastDomainType.Vlan) {
-            assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Vlan;
-            final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri));
-            return enableVlanNetwork(conn, vlan, network);
-        } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal || type == BroadcastDomainType.Vsp) {
-            return network.getNetwork();
-        } else if (uri != null && type == BroadcastDomainType.Vswitch) {
-            final String header = uri.toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length());
-            if (header.startsWith("vlan")) {
-                _isOvs = true;
-                return setupvSwitchNetwork(conn);
-            } else {
-                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority()));
-            }
-        } else if (type == BroadcastDomainType.Storage) {
-            if (uri == null) {
-                return network.getNetwork();
-            } else {
-                final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri));
-                return enableVlanNetwork(conn, vlan, network);
-            }
-        } else if (type == BroadcastDomainType.Lswitch) {
-            // Nicira Logical Switch
-            return network.getNetwork();
-        } else if (uri != null && type == BroadcastDomainType.Pvlan) {
-            assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Pvlan;
-            // should we consider moving this NetUtils method to
-            // BroadcastDomainType?
-            final long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(uri));
-            return enableVlanNetwork(conn, vlan, network);
-        }
-
-        throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
-    }
-
-    /**
-     * getNetworkByName() retrieves what the server thinks is the actual network
-     * used by the XenServer host. This method should always be used to talk to
-     * retrieve a network by the name. The reason is because of the problems in
-     * using the name label as the way to find the Network.
-     *
-     * To see how we are working around these problems, take a look at
-     * enableVlanNetwork(). The following description assumes you have looked at
-     * the description on that method.
-     *
-     * In order to understand this, we have to see what type of networks are
-     * within a XenServer that's under CloudStack control.
-     *
-     * - Native Networks: these are networks that are untagged on the XenServer
-     * and are used to crate VLAN networks on. These are created by the user and
-     * is assumed to be one per cluster. - VLAN Networks: these are dynamically
-     * created by CloudStack and can have problems with duplicated names. -
-     * LinkLocal Networks: these are dynamically created by CloudStack and can
-     * also have problems with duplicated names but these don't have actual
-     * PIFs.
-     *
-     * In order to speed to retrieval of a network, we do the following: - We
-     * retrieve by the name. If only one network is retrieved, we assume we
-     * retrieved the right network. - If more than one network is retrieved, we
-     * check to see which one has the pif for the local host and use that. - If
-     * a pif is not found, then we look at the tags and find the one with the
-     * lowest timestamp. (See enableVlanNetwork())
-     *
-     * @param conn
-     *            Xapi connection
-     * @param name
-     *            name of the network
-     * @return XsNic an object that contains network, network record, pif, and
-     *         pif record.
-     * @throws XenAPIException
-     * @throws XmlRpcException
-     *
-     * @see CitrixResourceBase#enableVlanNetwork
-     */
-    public XsLocalNetwork getNetworkByName(final Connection conn, final String name) throws XenAPIException, XmlRpcException {
-        final Set<Network> networks = Network.getByNameLabel(conn, name);
-        if (networks.size() == 1) {
-            return new XsLocalNetwork(this, networks.iterator().next(), null, null, null);
-        }
-
-        if (networks.size() == 0) {
-            return null;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Found more than one network with the name " + name);
-        }
-        Network earliestNetwork = null;
-        Network.Record earliestNetworkRecord = null;
-        long earliestTimestamp = Long.MAX_VALUE;
-        int earliestRandom = Integer.MAX_VALUE;
-        for (final Network network : networks) {
-            final XsLocalNetwork nic = new XsLocalNetwork(this, network);
-
-            if (nic.getPif(conn) != null) {
-                return nic;
-            }
-
-            final Network.Record record = network.getRecord(conn);
-            if (record.tags != null) {
-                for (final String tag : record.tags) {
-                    final Pair<Long, Integer> stamp = parseTimestamp(tag);
-                    if (stamp == null) {
-                        continue;
-                    }
-
-                    if (stamp.first() < earliestTimestamp || stamp.first() == earliestTimestamp && stamp.second() < earliestRandom) {
-                        earliestTimestamp = stamp.first();
-                        earliestRandom = stamp.second();
-                        earliestNetwork = network;
-                        earliestNetworkRecord = record;
-                    }
-                }
-            }
-        }
-
-        return earliestNetwork != null ? new XsLocalNetwork(this, earliestNetwork, earliestNetworkRecord, null, null) : null;
-    }
-
-    public long[] getNetworkStats(final Connection conn, final String privateIP) {
-        final String result = networkUsage(conn, privateIP, "get", null);
-        final long[] stats = new long[2];
-        if (result != null) {
-            final String[] splitResult = result.split(":");
-            int i = 0;
-            while (i < splitResult.length - 1) {
-                stats[0] += Long.parseLong(splitResult[i++]);
-                stats[1] += Long.parseLong(splitResult[i++]);
-            }
-        }
-        return stats;
-    }
-
-    public SR getNfsSR(final Connection conn, final String poolid, final String uuid, final String server, String serverpath, final String pooldesc) {
-        final Map<String, String> deviceConfig = new HashMap<String, String>();
-        try {
-            serverpath = serverpath.replace("//", "/");
-            final Set<SR> srs = SR.getAll(conn);
-            if (srs != null && !srs.isEmpty()) {
-                for (final SR sr : srs) {
-                    if (!SRType.NFS.equals(sr.getType(conn))) {
-                        continue;
-                    }
-
-                    final Set<PBD> pbds = sr.getPBDs(conn);
-                    if (pbds.isEmpty()) {
-                        continue;
-                    }
-
-                    final PBD pbd = pbds.iterator().next();
-
-                    final Map<String, String> dc = pbd.getDeviceConfig(conn);
-
-                    if (dc == null) {
-                        continue;
-                    }
-
-                    if (dc.get("server") == null) {
-                        continue;
-                    }
-
-                    if (dc.get("serverpath") == null) {
-                        continue;
-                    }
-
-                    if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) {
-                        throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath")
-                                + " for pool " + uuid + " on host:" + _host.getUuid());
-                    }
-
-                }
-            }
-            deviceConfig.put("server", server);
-            deviceConfig.put("serverpath", serverpath);
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final Map<String, String> smConfig = new HashMap<String, String>();
-            smConfig.put("nosubdir", "true");
-            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uuid, poolid, SRType.NFS.toString(), "user", true, smConfig);
-            sr.scan(conn);
-            return sr;
-        } catch (final XenAPIException e) {
-            throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e);
-        } catch (final XmlRpcException e) {
-            throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e);
-        }
-    }
-
-    private String getOvsTunnelNetworkName(final String broadcastUri) {
-        if (broadcastUri.contains(".")) {
-            final String[] parts = broadcastUri.split("\\.");
-            return "OVS-DR-VPC-Bridge" + parts[0];
-        } else {
-            try {
-                return "OVSTunnel" + broadcastUri;
-            } catch (final Exception e) {
-                return null;
-            }
-        }
-    }
-
-    protected List<File> getPatchFiles() {
-        String patch = getPatchFilePath();
-        String patchfilePath = Script.findScript("", patch);
-        if (patchfilePath == null) {
-            throw new CloudRuntimeException("Unable to find patch file "+patch);
-        }
-        List<File> files = new ArrayList<File>();
-        files.add(new File(patchfilePath));
-        return files;
-    }
-
-    protected abstract String getPatchFilePath();
-
-    public String getPerfMon(final Connection conn, final Map<String, String> params, final int wait) {
-        String result = null;
-        try {
-            result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, params);
-            if (result != null) {
-                return result;
-            }
-        } catch (final Exception e) {
-            s_logger.error("Can not get performance monitor for AS due to ", e);
-        }
-        return null;
-    }
-
-    protected Object[] getRRDData(final Connection conn, final int flag) {
-
-        /*
-         * Note: 1 => called from host, hence host stats 2 => called from vm,
-         * hence vm stats
-         */
-        Document doc = null;
-
-        try {
-            doc = getStatsRawXML(conn, flag == 1 ? true : false);
-        } catch (final Exception e1) {
-            s_logger.warn("Error whilst collecting raw stats from plugin: ", e1);
-            return null;
-        }
-
-        if (doc == null) { // stats are null when the host plugin call fails
-            // (host down state)
-            return null;
-        }
-
-        final NodeList firstLevelChildren = doc.getChildNodes();
-        final NodeList secondLevelChildren = firstLevelChildren.item(0).getChildNodes();
-        final Node metaNode = secondLevelChildren.item(0);
-        final Node dataNode = secondLevelChildren.item(1);
-
-        Integer numRows = 0;
-        Integer numColumns = 0;
-        Node legend = null;
-        final NodeList metaNodeChildren = metaNode.getChildNodes();
-        for (int i = 0; i < metaNodeChildren.getLength(); i++) {
-            final Node n = metaNodeChildren.item(i);
-            if (n.getNodeName().equals("rows")) {
-                numRows = Integer.valueOf(getXMLNodeValue(n));
-            } else if (n.getNodeName().equals("columns")) {
-                numColumns = Integer.valueOf(getXMLNodeValue(n));
-            } else if (n.getNodeName().equals("legend")) {
-                legend = n;
-            }
-        }
-
-        return new Object[] { numRows, numColumns, legend, dataNode };
-    }
-
-    @Override
-    public int getRunLevel() {
-        return 0;
-    }
-
-    protected SR getSRByNameLabelandHost(final Connection conn, final String name) throws BadServerResponse, XenAPIException, XmlRpcException {
-        final Set<SR> srs = SR.getByNameLabel(conn, name);
-        SR ressr = null;
-        for (final SR sr : srs) {
-            Set<PBD> pbds;
-            pbds = sr.getPBDs(conn);
-            for (final PBD pbd : pbds) {
-                final PBD.Record pbdr = pbd.getRecord(conn);
-                if (pbdr.host != null && pbdr.host.getUuid(conn).equals(_host.getUuid())) {
-                    if (!pbdr.currentlyAttached) {
-                        pbd.plug(conn);
-                    }
-                    ressr = sr;
-                    break;
-                }
-            }
-        }
-        return ressr;
-    }
-
-    private long getStaticMax(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam, final long recommendedValue) {
-        if (recommendedValue == 0) {
-            s_logger.warn("No recommended value found for dynamic max, setting static max and dynamic max equal");
-            return dynamicMaxRam;
-        }
-        final long staticMax = Math.min(recommendedValue, 4l * dynamicMinRam); // XS
-        // constraint
-        // for
-        // stability
-        if (dynamicMaxRam > staticMax) { // XS contraint that dynamic max <=
-            // static max
-            s_logger.warn("dynamixMax " + dynamicMaxRam + " cant be greater than static max " + staticMax
-                    + ", can lead to stability issues. Setting static max as much as dynamic max ");
-            return dynamicMaxRam;
-        }
-        return staticMax;
-    }
-
-    private long getStaticMin(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam, final long recommendedValue) {
-        if (recommendedValue == 0) {
-            s_logger.warn("No recommended value found for dynamic min");
-            return dynamicMinRam;
-        }
-
-        if (dynamicMinRam < recommendedValue) { // XS contraint that dynamic min
-            // > static min
-            s_logger.warn("Vm is set to dynamixMin " + dynamicMinRam + " less than the recommended static min " + recommendedValue + ", could lead to stability issues");
-        }
-        return dynamicMinRam;
-    }
-
-    protected Document getStatsRawXML(final Connection conn, final boolean host) {
-        final Date currentDate = new Date();
-        String urlStr = "http://" + _host.getIp() + "/rrd_updates?";
-        urlStr += "session_id=" + conn.getSessionReference();
-        urlStr += "&host=" + (host ? "true" : "false");
-        urlStr += "&cf=" + _consolidationFunction;
-        urlStr += "&interval=" + _pollingIntervalInSeconds;
-        urlStr += "&start=" + (currentDate.getTime() / 1000 - 1000 - 100);
-
-        URL url;
-        BufferedReader in = null;
-        try {
-            url = new URL(urlStr);
-            url.openConnection();
-            final URLConnection uc = url.openConnection();
-            in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
-            final InputSource statsSource = new InputSource(in);
-            return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(statsSource);
-        } catch (final MalformedURLException e) {
-            s_logger.warn("Malformed URL?  come on...." + urlStr);
-            return null;
-        } catch (final IOException e) {
-            s_logger.warn("Problems getting stats using " + urlStr, e);
-            return null;
-        } catch (final SAXException e) {
-            s_logger.warn("Problems getting stats using " + urlStr, e);
-            return null;
-        } catch (final ParserConfigurationException e) {
-            s_logger.warn("Problems getting stats using " + urlStr, e);
-            return null;
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (final IOException e) {
-                    s_logger.warn("Unable to close the buffer ", e);
-                }
-            }
-        }
-    }
-
-    public SR getStorageRepository(final Connection conn, final String srNameLabel) {
-        Set<SR> srs;
-        try {
-            srs = SR.getByNameLabel(conn, srNameLabel);
-        } catch (final XenAPIException e) {
-            throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.toString(), e);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.getMessage(), e);
-        }
-
-        if (srs.size() > 1) {
-            throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + srNameLabel);
-        } else if (srs.size() == 1) {
-            final SR sr = srs.iterator().next();
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("SR retrieved for " + srNameLabel);
-            }
-
-            if (checkSR(conn, sr)) {
-                return sr;
-            }
-            throw new CloudRuntimeException("SR check failed for storage pool: " + srNameLabel + "on host:" + _host.getUuid());
-        } else {
-            throw new CloudRuntimeException("Can not see storage pool: " + srNameLabel + " from on host:" + _host.getUuid());
-        }
-    }
-
-    protected Storage.StorageResourceType getStorageResourceType() {
-        return Storage.StorageResourceType.STORAGE_POOL;
-    }
-
-    @Override
-    public Type getType() {
-        return com.cloud.host.Host.Type.Routing;
-    }
-
-    protected VDI getVDIbyLocationandSR(final Connection conn, final String loc, final SR sr) {
-        try {
-            final Set<VDI> vdis = sr.getVDIs(conn);
-            for (final VDI vdi : vdis) {
-                if (vdi.getLocation(conn).startsWith(loc)) {
-                    return vdi;
-                }
-            }
-
-            final String msg = "can not getVDIbyLocationandSR " + loc;
-            s_logger.warn(msg);
-            return null;
-        } catch (final XenAPIException e) {
-            final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        } catch (final Exception e) {
-            final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        }
-
-    }
-
-    public VDI getVDIbyUuid(final Connection conn, final String uuid) {
-        return getVDIbyUuid(conn, uuid, true);
-    }
-
-    public VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound) {
-        try {
-            return VDI.getByUuid(conn, uuid);
-        } catch (final Exception e) {
-            if (throwExceptionIfNotFound) {
-                final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString();
-
-                s_logger.debug(msg);
-
-                throw new CloudRuntimeException(msg, e);
-            }
-
-            return null;
-        }
-    }
-
-    public String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
-        final String parentUuid = callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI",
-                isISCSI.toString());
-
-        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
-            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
-            // errString is already logged.
-            return null;
-        }
-        return parentUuid;
-    }
-
-    public VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException {
-        final Set<VIF> routerVIFs = router.getVIFs(conn);
-        mac = mac.trim();
-        for (final VIF vif : routerVIFs) {
-            final String lmac = vif.getMAC(conn);
-            if (lmac.trim().equals(mac)) {
-                return vif;
-            }
-        }
-        return null;
-    }
-
-    public VirtualRoutingResource getVirtualRoutingResource() {
-        return _vrResource;
-    }
-
-    public VM getVM(final Connection conn, final String vmName) {
-        // Look up VMs with the specified name
-        Set<VM> vms;
-        try {
-            vms = VM.getByNameLabel(conn, vmName);
-        } catch (final XenAPIException e) {
-            throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.toString(), e);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.getMessage(), e);
-        }
-
-        // If there are no VMs, throw an exception
-        if (vms.size() == 0) {
-            throw new CloudRuntimeException("VM with name: " + vmName + " does not exist.");
-        }
-
-        // If there is more than one VM, print a warning
-        if (vms.size() > 1) {
-            s_logger.warn("Found " + vms.size() + " VMs with name: " + vmName);
-        }
-
-        // Return the first VM in the set
-        return vms.iterator().next();
-    }
-
-    public String getVMInstanceName() {
-        return _instance;
-    }
-
-    public long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName, final String vmSnapshotName) throws BadServerResponse, XenAPIException, XmlRpcException {
-        if (volumeTo.getVolumeType() == Volume.Type.DATADISK) {
-            final VDI dataDisk = VDI.getByUuid(conn, volumeTo.getPath());
-            if (dataDisk != null) {
-                final String dataDiskName = dataDisk.getNameLabel(conn);
-                if (dataDiskName != null && !dataDiskName.isEmpty()) {
-                    volumeTo.setName(dataDiskName);
-                }
-            }
-        }
-        final Set<VDI> allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName());
-        long size = 0;
-        for (final VDI vdi : allvolumeVDIs) {
-            try {
-                if (vdi.getIsASnapshot(conn) && vdi.getSmConfig(conn).get("vhd-parent") != null) {
-                    final String parentUuid = vdi.getSmConfig(conn).get("vhd-parent");
-                    final VDI parentVDI = VDI.getByUuid(conn, parentUuid);
-                    // add size of snapshot vdi node, usually this only contains
-                    // meta data
-                    size = size + vdi.getPhysicalUtilisation(conn);
-                    // add size of snapshot vdi parent, this contains data
-                    if (!isRefNull(parentVDI)) {
-                        size = size + parentVDI.getPhysicalUtilisation(conn).longValue();
-                    }
-                }
-            } catch (final Exception e) {
-                s_logger.debug("Exception occurs when calculate snapshot capacity for volumes: due to " + e.toString());
-                continue;
-            }
-        }
-        if (volumeTo.getVolumeType() == Volume.Type.ROOT) {
-            VM vm = getVM(conn, vmName);
-            if(vm != null){
-                Set<VM> vmSnapshots=vm.getSnapshots(conn);
-                if(vmSnapshots != null){
-                    for(VM vmsnap: vmSnapshots){
-                        try {
-                            final String vmSnapName = vmsnap.getNameLabel(conn);
-                            s_logger.debug("snapname " + vmSnapName);
-                            if (vmSnapName != null && vmSnapName.contains(vmSnapshotName) && vmsnap.getIsASnapshot(conn)) {
-                                s_logger.debug("snapname " + vmSnapName + "isASnapshot");
-                                VDI memoryVDI = vmsnap.getSuspendVDI(conn);
-                                if (!isRefNull(memoryVDI)) {
-                                    size = size + memoryVDI.getPhysicalUtilisation(conn);
-                                    s_logger.debug("memoryVDI size :"+size);
-                                    String parentUuid = memoryVDI.getSmConfig(conn).get("vhd-parent");
-                                    VDI pMemoryVDI = VDI.getByUuid(conn, parentUuid);
-                                    if (!isRefNull(pMemoryVDI)) {
-                                        size = size + pMemoryVDI.getPhysicalUtilisation(conn);
-                                    }
-                                    s_logger.debug("memoryVDI size+parent :"+size);
-                                }
-                            }
-                           } catch (Exception e) {
-                            s_logger.debug("Exception occurs when calculate snapshot capacity for memory: due to " + e.toString());
-                            continue;
-                        }
-
-                    }
-                }
-            }
-        }
-        return size;
-    }
-
-    public PowerState getVmState(final Connection conn, final String vmName) {
-        int retry = 3;
-        while (retry-- > 0) {
-            try {
-                final Set<VM> vms = VM.getByNameLabel(conn, vmName);
-                for (final VM vm : vms) {
-                    return convertToPowerState(vm.getPowerState(conn));
-                }
-            } catch (final BadServerResponse e) {
-                // There is a race condition within xenserver such that if a vm
-                // is
-                // deleted and we
-                // happen to ask for it, it throws this stupid response. So
-                // if this happens,
-                // we take a nap and try again which then avoids the race
-                // condition because
-                // the vm's information is now cleaned up by xenserver. The
-                // error
-                // is as follows
-                // com.xensource.xenapi.Types$BadServerResponse
-                // [HANDLE_INVALID, VM,
-                // 3dde93f9-c1df-55a7-2cde-55e1dce431ab]
-                s_logger.info("Unable to get a vm PowerState due to " + e.toString() + ". We are retrying.  Count: " + retry);
-                try {
-                    Thread.sleep(3000);
-                } catch (final InterruptedException ex) {
-
-                }
-            } catch (final XenAPIException e) {
-                final String msg = "Unable to get a vm PowerState due to " + e.toString();
-                s_logger.warn(msg, e);
-                break;
-            } catch (final XmlRpcException e) {
-                final String msg = "Unable to get a vm PowerState due to " + e.getMessage();
-                s_logger.warn(msg, e);
-                break;
-            }
-        }
-
-        return PowerState.PowerOff;
-    }
-
-    public HashMap<String, VmStatsEntry> getVmStats(final Connection conn, final GetVmStatsCommand cmd, final List<String> vmUUIDs, final String hostGuid) {
-        final HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
-
-        for (final String vmUUID : vmUUIDs) {
-            vmResponseMap.put(vmUUID, new VmStatsEntry(0,0,0,0, 0, 0, 0, "vm"));
-        }
-
-        final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for
-        // vm
-
-        if (rrdData == null) {
-            return null;
-        }
-
-        final Integer numRows = (Integer) rrdData[0];
-        final Integer numColumns = (Integer) rrdData[1];
-        final Node legend = (Node) rrdData[2];
-        final Node dataNode = (Node) rrdData[3];
-
-        final NodeList legendChildren = legend.getChildNodes();
-        for (int col = 0; col < numColumns; col++) {
-
-            if (legendChildren == null || legendChildren.item(col) == null) {
-                continue;
-            }
-
-            final String columnMetadata = getXMLNodeValue(legendChildren.item(col));
-
-            if (columnMetadata == null) {
-                continue;
-            }
-
-            final String[] columnMetadataList = columnMetadata.split(":");
-
-            if (columnMetadataList.length != 4) {
-                continue;
-            }
-
-            final String type = columnMetadataList[1];
-            final String uuid = columnMetadataList[2];
-            final String param = columnMetadataList[3];
-
-            if (type.equals("vm") && vmResponseMap.keySet().contains(uuid)) {
-                final VmStatsEntry vmStatsAnswer = vmResponseMap.get(uuid);
-
-                vmStatsAnswer.setEntityType("vm");
-
-                if (param.contains("cpu")) {
-                    vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1);
-                    vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows));
-                } else if (param.matches("vif_\\d*_rx")) {
-                    vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.matches("vif_\\d*_tx")) {
-                    vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.matches("vbd_.*_read")) {
-                    vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.matches("vbd_.*_write")) {
-                    vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.contains("memory_internal_free")) {
-                    vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.contains("memory_target")) {
-                    vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                } else if (param.contains("memory")) {
-                    vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
-                }
-
-            }
-        }
-
-        for (final Map.Entry<String, VmStatsEntry> entry : vmResponseMap.entrySet()) {
-            final VmStatsEntry vmStatsAnswer = entry.getValue();
-
-            if (vmStatsAnswer.getNumCPUs() != 0) {
-                vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() / vmStatsAnswer.getNumCPUs());
-            }
-
-            vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() * 100);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization());
-            }
-        }
-
-        return vmResponseMap;
-    }
-
-    public String getVncUrl(final Connection conn, final VM vm) {
-        VM.Record record;
-        Console c;
-        try {
-            record = vm.getRecord(conn);
-            final Set<Console> consoles = record.consoles;
-
-            if (consoles.isEmpty()) {
-                s_logger.warn("There are no Consoles available to the vm : " + record.nameDescription);
-                return null;
-            }
-            final Iterator<Console> i = consoles.iterator();
-            while (i.hasNext()) {
-                c = i.next();
-                if (c.getProtocol(conn) == Types.ConsoleProtocol.RFB) {
-                    return c.getLocation(conn);
-                }
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to get console url due to " + e.toString();
-            s_logger.warn(msg, e);
-            return null;
-        } catch (final XmlRpcException e) {
-            final String msg = "Unable to get console url due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            return null;
-        }
-        return null;
-    }
-
-    protected String getXMLNodeValue(final Node n) {
-        return n.getChildNodes().item(0).getNodeValue();
-    }
-
-    public void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception {
-        final SR sr = getStorageRepository(conn, iqn);
-
-        removeSR(conn, sr);
-    }
-
-    protected void destroyUnattachedVBD(Connection conn, VM vm) {
-        try {
-            for (VBD vbd : vm.getVBDs(conn)) {
-                if (Types.VbdType.DISK.equals(vbd.getType(conn)) && !vbd.getCurrentlyAttached(conn)) {
-                    vbd.destroy(conn);
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.debug("Failed to destroy unattached VBD due to ", e);
-        }
-    }
-
-    public String handleVmStartFailure(final Connection conn, final String vmName, final VM vm, final String message, final Throwable th) {
-        final String msg = "Unable to start " + vmName + " due to " + message;
-        s_logger.warn(msg, th);
-
-        if (vm == null) {
-            return msg;
-        }
-
-        try {
-            final VM.Record vmr = vm.getRecord(conn);
-            final List<Network> networks = new ArrayList<Network>();
-            for (final VIF vif : vmr.VIFs) {
-                try {
-                    final VIF.Record rec = vif.getRecord(conn);
-                    if (rec != null) {
-                        networks.add(rec.network);
-                    } else {
-                        s_logger.warn("Unable to cleanup VIF: " + vif.toWireString() + " As vif record is null");
-                    }
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to cleanup VIF", e);
-                }
-            }
-            if (vmr.powerState == VmPowerState.RUNNING) {
-                try {
-                    vm.hardShutdown(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("VM hardshutdown failed due to ", e);
-                }
-            }
-            if (vm.getPowerState(conn) == VmPowerState.HALTED) {
-                try {
-                    vm.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("VM destroy failed due to ", e);
-                }
-            }
-            for (final VBD vbd : vmr.VBDs) {
-                try {
-                    vbd.unplug(conn);
-                    vbd.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to clean up VBD due to ", e);
-                }
-            }
-            for (final VIF vif : vmr.VIFs) {
-                try {
-                    vif.unplug(conn);
-                    vif.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to cleanup VIF", e);
-                }
-            }
-            for (final Network network : networks) {
-                if (network.getNameLabel(conn).startsWith("VLAN")) {
-                    disableVlanNetwork(conn, network);
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.warn("VM getRecord failed due to ", e);
-        }
-
-        return msg;
-    }
-
-    @Override
-    public StartupCommand[] initialize() throws IllegalArgumentException {
-        final Connection conn = getConnection();
-        if (!getHostInfo(conn)) {
-            s_logger.warn("Unable to get host information for " + _host.getIp());
-            return null;
-        }
-        final StartupRoutingCommand cmd = new StartupRoutingCommand();
-        fillHostInfo(conn, cmd);
-        cmd.setHypervisorType(HypervisorType.XenServer);
-        cmd.setCluster(_cluster);
-        cmd.setPoolSync(false);
-
-        try {
-            final Pool pool = Pool.getByUuid(conn, _host.getPool());
-            final Pool.Record poolr = pool.getRecord(conn);
-            poolr.master.getRecord(conn);
-        } catch (final Throwable e) {
-            s_logger.warn("Check for master failed, failing the FULL Cluster sync command");
-        }
-        final StartupStorageCommand sscmd = initializeLocalSR(conn);
-        if (sscmd != null) {
-            return new StartupCommand[] { cmd, sscmd };
-        }
-        return new StartupCommand[] { cmd };
-    }
-
-    protected StartupStorageCommand initializeLocalSR(final Connection conn) {
-        final SR lvmsr = getLocalLVMSR(conn);
-        if (lvmsr != null) {
-            try {
-                _host.setLocalSRuuid(lvmsr.getUuid(conn));
-
-                final String lvmuuid = lvmsr.getUuid(conn);
-                final long cap = lvmsr.getPhysicalSize(conn);
-                if (cap > 0) {
-                    final long avail = cap - lvmsr.getPhysicalUtilisation(conn);
-                    lvmsr.setNameLabel(conn, lvmuuid);
-                    final String name = "Cloud Stack Local LVM Storage Pool for " + _host.getUuid();
-                    lvmsr.setNameDescription(conn, name);
-                    final Host host = Host.getByUuid(conn, _host.getUuid());
-                    final String address = host.getAddress(conn);
-                    final StoragePoolInfo pInfo = new StoragePoolInfo(lvmuuid, address, SRType.LVM.toString(), SRType.LVM.toString(), StoragePoolType.LVM, cap, avail);
-                    final StartupStorageCommand cmd = new StartupStorageCommand();
-                    cmd.setPoolInfo(pInfo);
-                    cmd.setGuid(_host.getUuid());
-                    cmd.setDataCenter(Long.toString(_dcId));
-                    cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
-                    return cmd;
-                }
-            } catch (final XenAPIException e) {
-                final String msg = "build local LVM info err in host:" + _host.getUuid() + e.toString();
-                s_logger.warn(msg);
-            } catch (final XmlRpcException e) {
-                final String msg = "build local LVM info err in host:" + _host.getUuid() + e.getMessage();
-                s_logger.warn(msg);
-            }
-        }
-
-        final SR extsr = getLocalEXTSR(conn);
-        if (extsr != null) {
-            try {
-                final String extuuid = extsr.getUuid(conn);
-                _host.setLocalSRuuid(extuuid);
-                final long cap = extsr.getPhysicalSize(conn);
-                if (cap > 0) {
-                    final long avail = cap - extsr.getPhysicalUtilisation(conn);
-                    extsr.setNameLabel(conn, extuuid);
-                    final String name = "Cloud Stack Local EXT Storage Pool for " + _host.getUuid();
-                    extsr.setNameDescription(conn, name);
-                    final Host host = Host.getByUuid(conn, _host.getUuid());
-                    final String address = host.getAddress(conn);
-                    final StoragePoolInfo pInfo = new StoragePoolInfo(extuuid, address, SRType.EXT.toString(), SRType.EXT.toString(), StoragePoolType.EXT, cap, avail);
-                    final StartupStorageCommand cmd = new StartupStorageCommand();
-                    cmd.setPoolInfo(pInfo);
-                    cmd.setGuid(_host.getUuid());
-                    cmd.setDataCenter(Long.toString(_dcId));
-                    cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
-                    return cmd;
-                }
-            } catch (final XenAPIException e) {
-                final String msg = "build local EXT info err in host:" + _host.getUuid() + e.toString();
-                s_logger.warn(msg);
-            } catch (final XmlRpcException e) {
-                final String msg = "build local EXT info err in host:" + _host.getUuid() + e.getMessage();
-                s_logger.warn(msg);
-            }
-        }
-        return null;
-    }
-
-    public boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId) {
-        // Figure out the disk number to attach the VM to
-
-        String msg = null;
-        try {
-            final Set<String> allowedVBDDevices = vm.getAllowedVBDDevices(conn);
-            if (allowedVBDDevices.contains(deviceId.toString())) {
-                return false;
-            }
-            return true;
-        } catch (final XmlRpcException e) {
-            msg = "Catch XmlRpcException due to: " + e.getMessage();
-            s_logger.warn(msg, e);
-        } catch (final XenAPIException e) {
-            msg = "Catch XenAPIException due to: " + e.toString();
-            s_logger.warn(msg, e);
-        }
-        throw new CloudRuntimeException("When check deviceId " + msg);
-    }
-
-    /**
-     * When Dynamic Memory Control (DMC) is enabled - xenserver allows scaling
-     * the guest memory while the guest is running
-     *
-     * By default this is disallowed, override the specific xenserver resource
-     * if this is enabled
-     */
-    public boolean isDmcEnabled(final Connection conn, final Host host) throws XenAPIException, XmlRpcException {
-        return false;
-    }
-
-    public boolean IsISCSI(final String type) {
-        return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
-    }
-
-    public boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException {
-        if (nameTag != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Looking for network setup by name " + nameTag);
-            }
-            final Connection conn = getConnection();
-            final XsLocalNetwork network = getNetworkByName(conn, nameTag);
-            if (network == null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean isOvs() {
-        return _isOvs;
-    }
-
-    public boolean isRefNull(final XenAPIObject object) {
-        return object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals("<not in database>");
-    }
-
-    public boolean isSecurityGroupEnabled() {
-        return _securityGroupEnabled;
-    }
-
-    public boolean isXcp() {
-        final Connection conn = getConnection();
-        final String result = callHostPlugin(conn, "ovstunnel", "is_xcp");
-        if (result.equals("XCP")) {
-            return true;
-        }
-        return false;
-    }
-
-    boolean killCopyProcess(final Connection conn, final String nameLabel) {
-        final String results = callHostPluginAsync(conn, "vmops", "kill_copy_process", 60, "namelabel", nameLabel);
-        String errMsg = null;
-        if (results == null || results.equals("false")) {
-            errMsg = "kill_copy_process failed";
-            s_logger.warn(errMsg);
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    public boolean launchHeartBeat(final Connection conn) {
-        final String result = callHostPluginPremium(conn, "heartbeat", "host", _host.getUuid(), "timeout", Integer.toString(_heartbeatTimeout), "interval",
-                Integer.toString(_heartbeatInterval));
-        if (result == null || !result.contains("> DONE <")) {
-            s_logger.warn("Unable to launch the heartbeat process on " + _host.getIp());
-            return false;
-        }
-        return true;
-    }
-
-    protected String logX(final XenAPIObject obj, final String msg) {
-        return new StringBuilder("Host ").append(_host.getIp()).append(" ").append(obj.toWireString()).append(": ").append(msg).toString();
-    }
-
-    public void migrateVM(final Connection conn, final Host destHost, final VM vm, final String vmName) throws Exception {
-        Task task = null;
-        try {
-            final Map<String, String> other = new HashMap<String, String>();
-            other.put("live", "true");
-            task = vm.poolMigrateAsync(conn, destHost, other);
-            try {
-                // poll every 1 seconds
-                final long timeout = _migratewait * 1000L;
-                waitForTask(conn, task, 1000, timeout);
-                checkForSuccess(conn, task);
-            } catch (final Types.HandleInvalid e) {
-                if (vm.getResidentOn(conn).equals(destHost)) {
-                    task = null;
-                    return;
-                }
-                throw new CloudRuntimeException("migrate VM catch HandleInvalid and VM is not running on dest host");
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to migrate VM(" + vmName + ") from host(" + _host.getUuid() + ")";
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-    }
-
-    protected VDI mount(final Connection conn, final StoragePoolType poolType, final String volumeFolder, final String volumePath) {
-        return getVDIbyUuid(conn, volumePath);
-    }
-
-    protected VDI mount(final Connection conn, final String vmName, final DiskTO volume) throws XmlRpcException, XenAPIException {
-        final DataTO data = volume.getData();
-        final Volume.Type type = volume.getType();
-        if (type == Volume.Type.ISO) {
-            final TemplateObjectTO iso = (TemplateObjectTO) data;
-            final DataStoreTO store = iso.getDataStore();
-
-            if (store == null) {
-                // It's a fake iso
-                return null;
-            }
-
-            // corer case, xenserver pv driver iso
-            final String templateName = iso.getName();
-            if (templateName.startsWith("xs-tools")) {
-                try {
-                    final String actualTemplateName = actualIsoTemplate(conn);
-                    final Set<VDI> vdis = VDI.getByNameLabel(conn, actualTemplateName);
-                    if (vdis.isEmpty()) {
-                        throw new CloudRuntimeException("Could not find ISO with URL: " + actualTemplateName);
-                    }
-                    return vdis.iterator().next();
-                } catch (final XenAPIException e) {
-                    throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString());
-                } catch (final Exception e) {
-                    throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString());
-                }
-            }
-
-            if (!(store instanceof NfsTO)) {
-                throw new CloudRuntimeException("only support mount iso on nfs");
-            }
-            final NfsTO nfsStore = (NfsTO) store;
-            final String isoPath = nfsStore.getUrl() + File.separator + iso.getPath();
-            final int index = isoPath.lastIndexOf("/");
-
-            final String mountpoint = isoPath.substring(0, index);
-            URI uri;
-            try {
-                uri = new URI(mountpoint);
-            } catch (final URISyntaxException e) {
-                throw new CloudRuntimeException("Incorrect uri " + mountpoint, e);
-            }
-            final SR isoSr = createIsoSRbyURI(conn, uri, vmName, false);
-
-            final String isoname = isoPath.substring(index + 1);
-
-            final VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr);
-
-            if (isoVdi == null) {
-                throw new CloudRuntimeException("Unable to find ISO " + isoPath);
-            }
-            return isoVdi;
-        } else {
-            final VolumeObjectTO vol = (VolumeObjectTO) data;
-            return VDI.getByUuid(conn, vol.getPath());
-        }
-    }
-
-    public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) {
-        if (option.equals("get")) {
-            return "0:0";
-        }
-        return null;
-    }
-
-    private List<Pair<String, Long>> ovsFullSyncStates() {
-        final Connection conn = getConnection();
-        final String result = callHostPlugin(conn, "ovsgre", "ovs_get_vm_log", "host_uuid", _host.getUuid());
-        final String[] logs = result != null ? result.split(";") : new String[0];
-        final List<Pair<String, Long>> states = new ArrayList<Pair<String, Long>>();
-        for (final String log : logs) {
-            final String[] info = log.split(",");
-            if (info.length != 5) {
-                s_logger.warn("Wrong element number in ovs log(" + log + ")");
-                continue;
-            }
-
-            // ','.join([bridge, vmName, vmId, seqno, tag])
-            try {
-                states.add(new Pair<String, Long>(info[0], Long.parseLong(info[3])));
-            } catch (final NumberFormatException nfe) {
-                states.add(new Pair<String, Long>(info[0], -1L));
-            }
-        }
-        return states;
-    }
-
-    public HashMap<String, String> parseDefaultOvsRuleComamnd(final String str) {
-        final HashMap<String, String> cmd = new HashMap<String, String>();
-        final String[] sarr = str.split("/");
-        for (int i = 0; i < sarr.length; i++) {
-            String c = sarr[i];
-            c = c.startsWith("/") ? c.substring(1) : c;
-            c = c.endsWith("/") ? c.substring(0, c.length() - 1) : c;
-            final String[] p = c.split(";");
-            if (p.length != 2) {
-                continue;
-            }
-            if (p[0].equalsIgnoreCase("vlans")) {
-                p[1] = p[1].replace("@", "[");
-                p[1] = p[1].replace("#", "]");
-            }
-            cmd.put(p[0], p[1]);
-        }
-        return cmd;
-    }
-
-    protected Pair<Long, Integer> parseTimestamp(final String timeStampStr) {
-        final String[] tokens = timeStampStr.split("-");
-        if (tokens.length != 3) {
-            s_logger.debug("timeStamp in network has wrong pattern: " + timeStampStr);
-            return null;
-        }
-        if (!tokens[0].equals("CsCreateTime")) {
-            s_logger.debug("timeStamp in network doesn't start with CsCreateTime: " + timeStampStr);
-            return null;
-        }
-        return new Pair<Long, Integer>(Long.parseLong(tokens[1]), Integer.parseInt(tokens[2]));
-    }
-
-    private void pbdPlug(final Connection conn, final PBD pbd, final String uuid) {
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Plugging in PBD " + uuid + " for " + _host);
-            }
-            pbd.plug(conn);
-        } catch (final Exception e) {
-            final String msg = "PBD " + uuid + " is not attached! and PBD plug failed due to " + e.toString() + ". Please check this PBD in " + _host;
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    protected boolean pingdomr(final Connection conn, final String host, final String port) {
-        String status;
-        status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port);
-
-        if (status == null || status.isEmpty()) {
-            return false;
-        }
-
-        return true;
-
-    }
-
-    public boolean pingXAPI() {
-        final Connection conn = getConnection();
-        try {
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            if (!host.getEnabled(conn)) {
-                s_logger.debug("Host " + _host.getIp() + " is not enabled!");
-                return false;
-            }
-        } catch (final Exception e) {
-            s_logger.debug("cannot get host enabled status, host " + _host.getIp() + " due to " + e.toString(), e);
-            return false;
-        }
-        try {
-            callHostPlugin(conn, "echo", "main");
-        } catch (final Exception e) {
-            s_logger.debug("cannot ping host " + _host.getIp() + " due to " + e.toString(), e);
-            return false;
-        }
-        return true;
-    }
-
-    protected void plugDom0Vif(final Connection conn, final VIF dom0Vif) throws XmlRpcException, XenAPIException {
-        if (dom0Vif != null) {
-            dom0Vif.plug(conn);
-        }
-    }
-
-    protected boolean postCreatePrivateTemplate(final Connection conn, final String templatePath, final String tmpltFilename, final String templateName,
-            String templateDescription, String checksum, final long size, final long virtualSize, final long templateId) {
-
-        if (templateDescription == null) {
-            templateDescription = "";
-        }
-
-        if (checksum == null) {
-            checksum = "";
-        }
-
-        final String result = callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename,
-                "templateName", templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize",
-                String.valueOf(virtualSize), "templateId", String.valueOf(templateId));
-
-        boolean success = false;
-        if (result != null && !result.isEmpty()) {
-            // Else, command threw an exception which has already been logged.
-
-            if (result.equalsIgnoreCase("1")) {
-                s_logger.debug("Successfully created template.properties file on secondary storage for " + tmpltFilename);
-                success = true;
-            } else {
-                s_logger.warn("Could not create template.properties file on secondary storage for " + tmpltFilename + " for templateId: " + templateId);
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
-        // Update IP used to access router
-        cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP));
-        assert cmd.getRouterAccessIp() != null;
-
-        if (cmd instanceof IpAssocVpcCommand) {
-            return prepareNetworkElementCommand((IpAssocVpcCommand) cmd);
-        } else if (cmd instanceof IpAssocCommand) {
-            return prepareNetworkElementCommand((IpAssocCommand) cmd);
-        } else if (cmd instanceof SetupGuestNetworkCommand) {
-            return prepareNetworkElementCommand((SetupGuestNetworkCommand) cmd);
-        } else if (cmd instanceof SetSourceNatCommand) {
-            return prepareNetworkElementCommand((SetSourceNatCommand) cmd);
-        } else if (cmd instanceof SetNetworkACLCommand) {
-            return prepareNetworkElementCommand((SetNetworkACLCommand) cmd);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    public void prepareISO(final Connection conn, final String vmName,  List<String[]> vmDataList, String configDriveLabel) throws XmlRpcException, XenAPIException {
-
-        final Set<VM> vms = VM.getByNameLabel(conn, vmName);
-        if (vms == null || vms.size() != 1) {
-            throw new CloudRuntimeException("There are " + (vms == null ? "0" : vms.size()) + " VMs named " + vmName);
-        }
-        final VM vm = vms.iterator().next();
-
-        if (vmDataList != null) {
-            // create SR
-            SR sr =  createLocalIsoSR(conn, _configDriveSRName+getHost().getIp());
-
-            // 1. create vm data files
-            createVmdataFiles(vmName, vmDataList, configDriveLabel);
-
-            // 2. copy config drive iso to host
-            copyConfigDriveIsoToHost(conn, sr, vmName);
-        }
-
-        final Set<VBD> vbds = vm.getVBDs(conn);
-        for (final VBD vbd : vbds) {
-            final VBD.Record vbdr = vbd.getRecord(conn);
-            if (vbdr.type == Types.VbdType.CD && vbdr.empty == false && vbdr.userdevice.equals(_attachIsoDeviceNum)) {
-                final VDI vdi = vbdr.VDI;
-                final SR sr = vdi.getSR(conn);
-                final Set<PBD> pbds = sr.getPBDs(conn);
-                if (pbds == null) {
-                    throw new CloudRuntimeException("There is no pbd for sr " + sr);
-                }
-                for (final PBD pbd : pbds) {
-                    final PBD.Record pbdr = pbd.getRecord(conn);
-                    if (pbdr.host.getUuid(conn).equals(_host.getUuid())) {
-                        return;
-                    }
-                }
-                sr.setShared(conn, true);
-                final Host host = Host.getByUuid(conn, _host.getUuid());
-                final PBD.Record pbdr = pbds.iterator().next().getRecord(conn);
-                pbdr.host = host;
-                pbdr.uuid = "";
-                final PBD pbd = PBD.create(conn, pbdr);
-                pbdPlug(conn, pbd, pbd.getUuid(conn));
-                break;
-            }
-        }
-    }
-
-    // The idea here is to see if the DiskTO in question is from managed storage and does not yet have an SR.
-    // If no SR, create it and create a VDI in it.
-    public VDI prepareManagedDisk(final Connection conn, final DiskTO disk, final long vmId, final String vmName) throws Exception {
-        final Map<String, String> details = disk.getDetails();
-
-        if (details == null) {
-            return null;
-        }
-
-        final boolean isManaged = new Boolean(details.get(DiskTO.MANAGED)).booleanValue();
-
-        if (!isManaged) {
-            return null;
-        }
-
-        final String iqn = details.get(DiskTO.IQN);
-
-        final Set<SR> srNameLabels = SR.getByNameLabel(conn, iqn);
-
-        if (srNameLabels.size() != 0) {
-            return null;
-        }
-
-        final String vdiNameLabel = Volume.Type.ROOT.equals(disk.getType()) ? ("ROOT-" + vmId) : (vmName + "-DATA");
-
-        return prepareManagedStorage(conn, details, null, vdiNameLabel);
-    }
-
-    protected SR prepareManagedSr(final Connection conn, final Map<String, String> details) {
-        final String iScsiName = details.get(DiskTO.IQN);
-        final String storageHost = details.get(DiskTO.STORAGE_HOST);
-        final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
-        final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
-        final String mountpoint = details.get(DiskTO.MOUNT_POINT);
-        final String protocoltype = details.get(DiskTO.PROTOCOL_TYPE);
-
-        if (StoragePoolType.NetworkFilesystem.toString().equalsIgnoreCase(protocoltype)) {
-            final String poolid = storageHost + ":" + mountpoint;
-            final String namelable = mountpoint;
-            final String volumedesc = storageHost + ":" + mountpoint;
-
-            return getNfsSR(conn, poolid, namelable, storageHost, mountpoint, volumedesc);
-        } else {
-            return getIscsiSR(conn, iScsiName, storageHost, iScsiName,
-                    chapInitiatorUsername, chapInitiatorSecret, false, SRType.LVMOISCSI.toString(), true);
-        }
-    }
-
-    protected VDI prepareManagedStorage(final Connection conn, final Map<String, String> details, final String path, final String vdiNameLabel) throws Exception {
-        final SR sr = prepareManagedSr(conn, details);
-
-        VDI vdi = getVDIbyUuid(conn, path, false);
-        final Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
-
-        Set<VDI> vdisInSr = sr.getVDIs(conn);
-
-        // If a VDI already exists in the SR (in case we cloned from a template cache), use that.
-        if (vdisInSr.size() == 1) {
-            vdi = vdisInSr.iterator().next();
-        }
-
-        if (vdi == null) {
-            vdi = createVdi(sr, vdiNameLabel, volumeSize);
-        } else {
-            // If vdi is not null, it must have already been created, so check whether a resize of the volume was performed.
-            // If true, resize the VDI to the volume size.
-
-            s_logger.info("Checking for the resize of the datadisk");
-
-            final long vdiVirtualSize = vdi.getVirtualSize(conn);
-
-            if (vdiVirtualSize != volumeSize) {
-                s_logger.info("Resizing the data disk (VDI) from vdiVirtualSize: " + vdiVirtualSize + " to volumeSize: " + volumeSize);
-
-                try {
-                    vdi.resize(conn, volumeSize);
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to resize volume", e);
-                }
-            }
-
-            // change the name-label in case of a cloned VDI
-            if (!Objects.equals(vdi.getNameLabel(conn), vdiNameLabel)) {
-                try {
-                    vdi.setNameLabel(conn, vdiNameLabel);
-                } catch (final Exception e) {
-                    s_logger.warn("Unable to rename volume", e);
-                }
-            }
-        }
-
-        return vdi;
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
-        final Connection conn = getConnection();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-
-        try {
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            for (final IpAddressTO ip : ips) {
-
-                final VM router = getVM(conn, routerName);
-
-                final NicTO nic = new NicTO();
-                nic.setMac(ip.getVifMacAddress());
-                nic.setType(ip.getTrafficType());
-                if (ip.getBroadcastUri() == null) {
-                    nic.setBroadcastType(BroadcastDomainType.Native);
-                } else {
-                    final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-                    nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
-                    nic.setBroadcastUri(uri);
-                }
-                nic.setDeviceId(0);
-                nic.setNetworkRateMbps(ip.getNetworkRate());
-                nic.setName(ip.getNetworkName());
-
-                final Network network = getNetwork(conn, nic);
-
-                // Determine the correct VIF on DomR to associate/disassociate
-                // the
-                // IP address with
-                VIF correctVif = getCorrectVif(conn, router, network);
-
-                // If we are associating an IP address and DomR doesn't have a
-                // VIF
-                // for the specified vlan ID, we need to add a VIF
-                // If we are disassociating the last IP address in the VLAN, we
-                // need
-                // to remove a VIF
-                boolean addVif = false;
-                if (ip.isAdd() && correctVif == null) {
-                    addVif = true;
-                }
-
-                if (addVif) {
-                    // Add a new VIF to DomR
-                    final String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router);
-
-                    if (vifDeviceNum == null) {
-                        throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn));
-                    }
-
-                    nic.setDeviceId(Integer.parseInt(vifDeviceNum));
-
-                    correctVif = createVif(conn, routerName, router, null, nic);
-                    correctVif.plug(conn);
-                    // Add iptables rule for network usage
-                    networkUsage(conn, routerIp, "addVif", "eth" + correctVif.getDevice(conn));
-                }
-
-                if (ip.isAdd() && correctVif == null) {
-                    throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
-                }
-                if (correctVif != null) {
-                    ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
-                    ip.setNewNic(addVif);
-                }
-            }
-        } catch (final InternalErrorException e) {
-            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.getMessage());
-        } catch (final Exception e) {
-            return new ExecutionResult(false, e.getMessage());
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
-        final Connection conn = getConnection();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        try {
-            final IpAddressTO[] ips = cmd.getIpAddresses();
-            for (final IpAddressTO ip : ips) {
-
-                final VM router = getVM(conn, routerName);
-
-                final VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress());
-                setNicDevIdIfCorrectVifIsNotNull(conn, ip, correctVif);
-            }
-        } catch (final Exception e) {
-            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
-            return new ExecutionResult(false, e.getMessage());
-        }
-
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) {
-        final Connection conn = getConnection();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-
-        try {
-            final VM router = getVM(conn, routerName);
-
-            final NicTO nic = cmd.getNic();
-            if (nic != null) {
-                final VIF vif = getVifByMac(conn, router, nic.getMac());
-                if (vif == null) {
-                    final String msg = "Prepare SetNetworkACL failed due to VIF is null for : " + nic.getMac() + " with routername: " + routerName;
-                    s_logger.error(msg);
-                    return new ExecutionResult(false, msg);
-                }
-                nic.setDeviceId(Integer.parseInt(vif.getDevice(conn)));
-            } else {
-                final String msg = "Prepare SetNetworkACL failed due to nic is null for : " + routerName;
-                s_logger.error(msg);
-                return new ExecutionResult(false, msg);
-            }
-        } catch (final Exception e) {
-            final String msg = "Prepare SetNetworkACL failed due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
-        final Connection conn = getConnection();
-        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        final IpAddressTO pubIp = cmd.getIpAddress();
-        try {
-            final VM router = getVM(conn, routerName);
-
-            final VIF correctVif = getCorrectVif(conn, router, pubIp);
-
-            pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
-
-        } catch (final Exception e) {
-            final String msg = "Ip SNAT failure due to " + e.toString();
-            s_logger.error(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    /**
-     * @param cmd
-     * @return
-     */
-    private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
-        final Connection conn = getConnection();
-        final NicTO nic = cmd.getNic();
-        final String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        try {
-            final Set<VM> vms = VM.getByNameLabel(conn, domrName);
-            if (vms == null || vms.isEmpty()) {
-                return new ExecutionResult(false, "Can not find VM " + domrName);
-            }
-            final VM vm = vms.iterator().next();
-            final String mac = nic.getMac();
-            VIF domrVif = null;
-            for (final VIF vif : vm.getVIFs(conn)) {
-                final String lmac = vif.getMAC(conn);
-                if (lmac.equals(mac)) {
-                    domrVif = vif;
-                    // Do not break it! We have 2 routers.
-                    // break;
-                }
-            }
-            if (domrVif == null) {
-                return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName);
-            }
-
-            nic.setDeviceId(Integer.parseInt(domrVif.getDevice(conn)));
-        } catch (final Exception e) {
-            final String msg = "Creating guest network failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new ExecutionResult(false, msg);
-        }
-        return new ExecutionResult(true, null);
-    }
-
-    public void rebootVM(final Connection conn, final VM vm, final String vmName) throws Exception {
-        Task task = null;
-        try {
-            task = vm.cleanRebootAsync(conn);
-            try {
-                // poll every 1 seconds , timeout after 10 minutes
-                waitForTask(conn, task, 1000, 10 * 60 * 1000);
-                checkForSuccess(conn, task);
-            } catch (final Types.HandleInvalid e) {
-                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
-                    task = null;
-                    return;
-                }
-                throw new CloudRuntimeException("Reboot VM catch HandleInvalid and VM is not in RUNNING state");
-            }
-        } catch (final XenAPIException e) {
-            s_logger.debug("Unable to Clean Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString() + ", try hard reboot");
-            try {
-                vm.hardReboot(conn);
-            } catch (final Exception e1) {
-                final String msg = "Unable to hard Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
-                s_logger.warn(msg, e1);
-                throw new CloudRuntimeException(msg);
-            }
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-    }
-
-    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;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(logX(sr, "Removing SR"));
-        }
-
-        for (int i = 0; i < 2; i++) {
-            try {
-                final Set<VDI> vdis = sr.getVDIs(conn);
-                for (final VDI vdi : vdis) {
-                    vdi.forget(conn);
-                }
-
-                Set<PBD> pbds = sr.getPBDs(conn);
-                for (final PBD pbd : pbds) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug(logX(pbd, "Unplugging pbd"));
-                    }
-
-                    // if (pbd.getCurrentlyAttached(conn)) {
-                    pbd.unplug(conn);
-                    // }
-
-                    pbd.destroy(conn);
-                }
-
-                pbds = sr.getPBDs(conn);
-
-                if (pbds.size() == 0) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug(logX(sr, "Forgetting"));
-                    }
-
-                    sr.forget(conn);
-
-                    return;
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(logX(sr, "There is still one or more PBDs attached."));
-
-                    if (s_logger.isTraceEnabled()) {
-                        for (final PBD pbd : pbds) {
-                            s_logger.trace(logX(pbd, " Still attached"));
-                        }
-                    }
-                }
-            } catch (final XenAPIException e) {
-                s_logger.debug(logX(sr, "Catch XenAPIException: " + e.toString()));
-            } catch (final XmlRpcException e) {
-                s_logger.debug(logX(sr, "Catch Exception: " + e.getMessage()));
-            }
-        }
-
-        s_logger.warn(logX(sr, "Unable to remove SR"));
-    }
-
-    protected String removeSRSync(final Connection conn, final SR sr) {
-        if (sr == null) {
-            return null;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(logX(sr, "Removing SR"));
-        }
-        long waittime = 0;
-        try {
-            final Set<VDI> vdis = sr.getVDIs(conn);
-            for (final VDI vdi : vdis) {
-                final Map<java.lang.String, Types.VdiOperations> currentOperation = vdi.getCurrentOperations(conn);
-                if (currentOperation == null || currentOperation.size() == 0) {
-                    continue;
-                }
-                if (waittime >= 1800000) {
-                    final String msg = "This template is being used, try late time";
-                    s_logger.warn(msg);
-                    return msg;
-                }
-                waittime += 30000;
-                try {
-                    Thread.sleep(30000);
-                } catch (final InterruptedException ex) {
-                }
-            }
-            removeSR(conn, sr);
-            return null;
-        } catch (final XenAPIException e) {
-            s_logger.warn(logX(sr, "Unable to get current opertions " + e.toString()), e);
-        } catch (final XmlRpcException e) {
-            s_logger.warn(logX(sr, "Unable to get current opertions " + e.getMessage()), e);
-        }
-        final String msg = "Remove SR failed";
-        s_logger.warn(msg);
-        return msg;
-
-    }
-
-    public String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID)
-            throws XenAPIException, XmlRpcException {
-
-        final String results = callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName,
-                "oldVmUuid", oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID);
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg = "revert_memory_snapshot return null";
-        } else {
-            if (results.equals("0")) {
-                return results;
-            } else {
-                errMsg = "revert_memory_snapshot exception";
-            }
-        }
-        s_logger.warn(errMsg);
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    public void scaleVM(final Connection conn, final VM vm, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException {
-
-        final Long staticMemoryMax = vm.getMemoryStaticMax(conn);
-        final Long staticMemoryMin = vm.getMemoryStaticMin(conn);
-        final Long newDynamicMemoryMin = vmSpec.getMinRam();
-        final Long newDynamicMemoryMax = vmSpec.getMaxRam();
-        if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) {
-            throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin
-                    + ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")");
-        }
-
-        vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax);
-        vm.setVCPUsNumberLive(conn, (long) vmSpec.getCpus());
-
-        final Integer speed = vmSpec.getMinSpeed();
-        if (speed != null) {
-
-            int cpuWeight = _maxWeight; // cpu_weight
-
-            // weight based allocation
-
-            cpuWeight = (int) (speed * 0.99 / _host.getSpeed() * _maxWeight);
-            if (cpuWeight > _maxWeight) {
-                cpuWeight = _maxWeight;
-            }
-
-            if (vmSpec.getLimitCpuUse()) {
-                long utilization = 0; // max CPU cap, default is unlimited
-                utilization = (int) (vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100);
-                // vm.addToVCPUsParamsLive(conn, "cap",
-                // Long.toString(utilization)); currently xenserver doesnot
-                // support Xapi to add VCPUs params live.
-                callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", Long.toString(utilization), "vmname", vmSpec.getName());
-            }
-            // vm.addToVCPUsParamsLive(conn, "weight",
-            // Integer.toString(cpuWeight));
-            callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName());
-        }
-    }
-
-    @Override
-    public void setAgentControl(final IAgentControl agentControl) {
-        _agentControl = agentControl;
-    }
-
-    public void setCanBridgeFirewall(final boolean canBridgeFirewall) {
-        _canBridgeFirewall = canBridgeFirewall;
-    }
-
-    @Override
-    public void setConfigParams(final Map<String, Object> params) {
-    }
-
-    public boolean setIptables(final Connection conn) {
-        final String result = callHostPlugin(conn, "vmops", "setIptables");
-        if (result == null || result.isEmpty()) {
-            return false;
-        }
-        return true;
-    }
-
-    public void setIsOvs(final boolean isOvs) {
-        _isOvs = isOvs;
-    }
-
-    /**
-     * WARN: static-min <= dynamic-min <= dynamic-max <= static-max
-     *
-     * @see XcpServerResource#setMemory(com.xensource.xenapi.Connection,
-     *      com.xensource.xenapi.VM, long, long)
-     * @param conn
-     * @param vm
-     * @param minMemsize
-     * @param maxMemsize
-     * @throws XmlRpcException
-     * @throws XenAPIException
-     */
-    protected void setMemory(final Connection conn, final VM vm, final long minMemsize, final long maxMemsize) throws XmlRpcException, XenAPIException {
-        vm.setMemoryLimits(conn, mem_128m, maxMemsize, minMemsize, maxMemsize);
-    }
-
-    @Override
-    public void setName(final String name) {
-    }
-
-    protected void setNicDevIdIfCorrectVifIsNotNull(final Connection conn, final IpAddressTO ip, final VIF correctVif) throws InternalErrorException, BadServerResponse,
-    XenAPIException, XmlRpcException {
-        if (correctVif == null) {
-            if (ip.isAdd()) {
-                throw new InternalErrorException("Failed to find DomR VIF to associate IP with.");
-            } else {
-                s_logger.debug("VIF to deassociate IP with does not exist, return success");
-            }
-        } else {
-            ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
-        }
-    }
-
-    @Override
-    public void setRunLevel(final int level) {
-    }
-
-    public String setupHeartbeatSr(final Connection conn, final SR sr, final boolean force) throws XenAPIException, XmlRpcException {
-        final SR.Record srRec = sr.getRecord(conn);
-        final String srUuid = srRec.uuid;
-        if (!srRec.shared || !SRType.LVMOHBA.equals(srRec.type) && !SRType.LVMOISCSI.equals(srRec.type) && !SRType.NFS.equals(srRec.type)) {
-            return srUuid;
-        }
-        String result = null;
-        final Host host = Host.getByUuid(conn, _host.getUuid());
-        final Set<String> tags = host.getTags(conn);
-        if (force || !tags.contains("cloud-heartbeat-" + srUuid)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Setting up the heartbeat sr for host " + _host.getIp() + " and sr " + srUuid);
-            }
-            final Set<PBD> pbds = sr.getPBDs(conn);
-            for (final PBD pbd : pbds) {
-                final PBD.Record pbdr = pbd.getRecord(conn);
-                if (!pbdr.currentlyAttached && pbdr.host.getUuid(conn).equals(_host.getUuid())) {
-                    pbd.plug(conn);
-                    break;
-                }
-            }
-            result = callHostPluginThroughMaster(conn, "vmopspremium", "setup_heartbeat_sr", "host", _host.getUuid(), "sr", srUuid);
-            if (result == null || !result.split("#")[1].equals("0")) {
-                throw new CloudRuntimeException("Unable to setup heartbeat sr on SR " + srUuid + " due to " + result);
-            }
-
-            if (!tags.contains("cloud-heartbeat-" + srUuid)) {
-                tags.add("cloud-heartbeat-" + srUuid);
-                host.setTags(conn, tags);
-            }
-        }
-        result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.getUuid(), "sr", srUuid, "add", "true");
-        if (result == null || !result.split("#")[1].equals("0")) {
-            throw new CloudRuntimeException("Unable to setup heartbeat file entry on SR " + srUuid + " due to " + result);
-        }
-        return srUuid;
-    }
-
-    public void setupLinkLocalNetwork(final Connection conn) {
-        try {
-            final Network.Record rec = new Network.Record();
-            final Set<Network> networks = Network.getByNameLabel(conn, _linkLocalPrivateNetworkName);
-            Network linkLocal = null;
-
-            if (networks.size() == 0) {
-                rec.nameDescription = "link local network used by system vms";
-                rec.nameLabel = _linkLocalPrivateNetworkName;
-                final Map<String, String> configs = new HashMap<String, String>();
-                configs.put("ip_begin", NetUtils.getLinkLocalGateway());
-                configs.put("ip_end", NetUtils.getLinkLocalIpEnd());
-                configs.put("netmask", NetUtils.getLinkLocalNetMask());
-                configs.put("vswitch-disable-in-band", "true");
-                rec.otherConfig = configs;
-                linkLocal = Network.create(conn, rec);
-            } else {
-                linkLocal = networks.iterator().next();
-                if (!linkLocal.getOtherConfig(conn).containsKey("vswitch-disable-in-band")) {
-                    linkLocal.addToOtherConfig(conn, "vswitch-disable-in-band", "true");
-                }
-            }
-
-            /* Make sure there is a physical bridge on this network */
-            VIF dom0vif = null;
-            final Pair<VM, VM.Record> vm = getControlDomain(conn);
-            final VM dom0 = vm.first();
-            final Set<VIF> vifs = dom0.getVIFs(conn);
-            if (vifs.size() != 0) {
-                for (final VIF vif : vifs) {
-                    final Map<String, String> otherConfig = vif.getOtherConfig(conn);
-                    if (otherConfig != null) {
-                        final String nameLabel = otherConfig.get("nameLabel");
-                        if (nameLabel != null && nameLabel.equalsIgnoreCase("link_local_network_vif")) {
-                            dom0vif = vif;
-                        }
-                    }
-                }
-            }
-
-            /* create temp VIF0 */
-            if (dom0vif == null) {
-                s_logger.debug("Can't find a vif on dom0 for link local, creating a new one");
-                final VIF.Record vifr = new VIF.Record();
-                vifr.VM = dom0;
-                vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0);
-                if (vifr.device == null) {
-                    s_logger.debug("Failed to create link local network, no vif available");
-                    return;
-                }
-                final Map<String, String> config = new HashMap<String, String>();
-                config.put("nameLabel", "link_local_network_vif");
-                vifr.otherConfig = config;
-                vifr.MAC = "FE:FF:FF:FF:FF:FF";
-                vifr.network = linkLocal;
-                vifr.lockingMode = Types.VifLockingMode.NETWORK_DEFAULT;
-                dom0vif = VIF.create(conn, vifr);
-                plugDom0Vif(conn, dom0vif);
-            } else {
-                s_logger.debug("already have a vif on dom0 for link local network");
-                if (!dom0vif.getCurrentlyAttached(conn)) {
-                    plugDom0Vif(conn, dom0vif);
-                }
-            }
-
-            final String brName = linkLocal.getBridge(conn);
-            callHostPlugin(conn, "vmops", "setLinkLocalIP", "brName", brName);
-            _host.setLinkLocalNetwork(linkLocal.getUuid(conn));
-
-        } catch (final XenAPIException e) {
-            s_logger.warn("Unable to create local link network", e);
-            throw new CloudRuntimeException("Unable to create local link network due to " + e.toString(), e);
-        } catch (final XmlRpcException e) {
-            s_logger.warn("Unable to create local link network", e);
-            throw new CloudRuntimeException("Unable to create local link network due to " + e.toString(), e);
-        }
-    }
-
-    /* return : if setup is needed */
-    public boolean setupServer(final Connection conn, final Host host) {
-        final String packageVersion = CitrixResourceBase.class.getPackage().getImplementationVersion();
-        final String version = this.getClass().getName() + "-" + (packageVersion == null ? Long.toString(System.currentTimeMillis()) : packageVersion);
-
-        try {
-            /* push patches to XenServer */
-            final Host.Record hr = host.getRecord(conn);
-
-            final Iterator<String> it = hr.tags.iterator();
-
-            while (it.hasNext()) {
-                final String tag = it.next();
-                if (tag.startsWith("vmops-version-")) {
-                    if (tag.contains(version)) {
-                        s_logger.info(logX(host, "Host " + hr.address + " is already setup."));
-                        return false;
-                    } else {
-                        it.remove();
-                    }
-                }
-            }
-
-            final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22);
-            try {
-                sshConnection.connect(null, 60000, 60000);
-                if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
-                    throw new CloudRuntimeException("Unable to authenticate");
-                }
-
-                final String cmd = "mkdir -p /opt/cloud/bin /var/log/cloud";
-                if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
-                    throw new CloudRuntimeException("Cannot create directory /opt/cloud/bin on XenServer hosts");
-                }
-
-                final SCPClient scp = new SCPClient(sshConnection);
-
-                final List<File> files = getPatchFiles();
-                if (files == null || files.isEmpty()) {
-                    throw new CloudRuntimeException("Can not find patch file");
-                }
-                for (final File file : files) {
-                    final String path = file.getParentFile().getAbsolutePath() + "/";
-                    final Properties props = PropertiesUtil.loadFromFile(file);
-
-                    for (final Map.Entry<Object, Object> entry : props.entrySet()) {
-                        final String k = (String) entry.getKey();
-                        final String v = (String) entry.getValue();
-
-                        assert k != null && k.length() > 0 && v != null && v.length() > 0 : "Problems with " + k + "=" + v;
-
-                        final String[] tokens = v.split(",");
-                        String f = null;
-                        if (tokens.length == 3 && tokens[0].length() > 0) {
-                            if (tokens[0].startsWith("/")) {
-                                f = tokens[0];
-                            } else if (tokens[0].startsWith("~")) {
-                                final String homedir = System.getenv("HOME");
-                                f = homedir + tokens[0].substring(1) + k;
-                            } else {
-                                f = path + tokens[0] + '/' + k;
-                            }
-                        } else {
-                            f = path + k;
-                        }
-                        final String directoryPath = tokens[tokens.length - 1];
-
-                        f = f.replace('/', File.separatorChar);
-
-                        String permissions = "0755";
-                        if (tokens.length == 3) {
-                            permissions = tokens[1];
-                        } else if (tokens.length == 2) {
-                            permissions = tokens[0];
-                        }
-
-                        if (!new File(f).exists()) {
-                            s_logger.warn("We cannot locate " + f);
-                            continue;
-                        }
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Copying " + f + " to " + directoryPath + " on " + hr.address + " with permission " + permissions);
-                        }
-
-                        if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "mkdir -m 700 -p " + directoryPath)) {
-                            s_logger.debug("Unable to create destination path: " + directoryPath + " on " + hr.address + ".");
-                        }
-
-                        try {
-                            scp.put(f, directoryPath, permissions);
-                        } catch (final IOException e) {
-                            final String msg = "Unable to copy file " + f + " to path " + directoryPath + " with permissions  " + permissions;
-                            s_logger.debug(msg);
-                            throw new CloudRuntimeException("Unable to setup the server: " + msg, e);
-                        }
-                    }
-                }
-
-            } catch (final IOException e) {
-                throw new CloudRuntimeException("Unable to setup the server correctly", e);
-            } finally {
-                sshConnection.close();
-            }
-            hr.tags.add("vmops-version-" + version);
-            host.setTags(conn, hr.tags);
-            return true;
-        } catch (final XenAPIException e) {
-            final String msg = "XenServer setup failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException("Unable to get host information " + e.toString(), e);
-        } catch (final XmlRpcException e) {
-            final String msg = "XenServer setup failed due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException("Unable to get host information ", e);
-        }
-    }
-
-    public synchronized Network setupvSwitchNetwork(final Connection conn) {
-        try {
-            if (_host.getVswitchNetwork() == null) {
-                Network vswitchNw = null;
-                final Network.Record rec = new Network.Record();
-                final String nwName = Networks.BroadcastScheme.VSwitch.toString();
-                final Set<Network> networks = Network.getByNameLabel(conn, nwName);
-
-                if (networks.size() == 0) {
-                    rec.nameDescription = "vswitch network for " + nwName;
-                    rec.nameLabel = nwName;
-                    vswitchNw = Network.create(conn, rec);
-                } else {
-                    vswitchNw = networks.iterator().next();
-                }
-                _host.setVswitchNetwork(vswitchNw);
-            }
-            return _host.getVswitchNetwork();
-        } catch (final BadServerResponse e) {
-            s_logger.error("Failed to setup vswitch network", e);
-        } catch (final XenAPIException e) {
-            s_logger.error("Failed to setup vswitch network", e);
-        } catch (final XmlRpcException e) {
-            s_logger.error("Failed to setup vswitch network", e);
-        }
-
-        return null;
-    }
-
-    public void shutdownVM(final Connection conn, final VM vm, final String vmName, final boolean forcedStop) throws XmlRpcException {
-        Task task = null;
-        try {
-            if (forcedStop) {
-                task = vm.hardShutdownAsync(conn);
-            } else {
-                task = vm.cleanShutdownAsync(conn);
-            }
-
-            try {
-                // poll every 1 seconds , timeout after 10 minutes
-                waitForTask(conn, task, 1000, 10 * 60 * 1000);
-                checkForSuccess(conn, task);
-            } catch (final TimeoutException e) {
-                if (vm.getPowerState(conn) == VmPowerState.HALTED) {
-                    task = null;
-                    return;
-                }
-                throw new CloudRuntimeException("Shutdown VM catch HandleInvalid and VM is not in HALTED state");
-            }
-        } catch (final XenAPIException e) {
-            s_logger.debug("Unable to shutdown VM(" + vmName + ") with force=" + forcedStop + " on host(" + _host.getUuid() + ") due to " + e.toString());
-            try {
-                VmPowerState state = vm.getPowerState(conn);
-                if (state == VmPowerState.RUNNING) {
-                    try {
-                        vm.hardShutdown(conn);
-                    } catch (final Exception e1) {
-                        s_logger.debug("Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString());
-                        state = vm.getPowerState(conn);
-                        if (state == VmPowerState.RUNNING) {
-                            forceShutdownVM(conn, vm);
-                        }
-                        return;
-                    }
-                } else if (state == VmPowerState.HALTED) {
-                    return;
-                } else {
-                    final String msg = "After cleanShutdown the VM status is " + state.toString() + ", that is not expected";
-                    s_logger.warn(msg);
-                    throw new CloudRuntimeException(msg);
-                }
-            } catch (final Exception e1) {
-                final String msg = "Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
-                s_logger.warn(msg, e1);
-                throw new CloudRuntimeException(msg);
-            }
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    public void startVM(final Connection conn, final Host host, final VM vm, final String vmName) throws Exception {
-        Task task = null;
-        try {
-            task = vm.startOnAsync(conn, host, false, true);
-            try {
-                // poll every 1 seconds , timeout after 10 minutes
-                waitForTask(conn, task, 1000, 10 * 60 * 1000);
-                checkForSuccess(conn, task);
-            } catch (final Types.HandleInvalid e) {
-                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
-                    s_logger.debug("VM " + vmName + " is in Running status");
-                    task = null;
-                    return;
-                }
-                throw new CloudRuntimeException("Start VM " + vmName + " catch HandleInvalid and VM is not in RUNNING state");
-            } catch (final TimeoutException e) {
-                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
-                    s_logger.debug("VM " + vmName + " is in Running status");
-                    task = null;
-                    return;
-                }
-                throw new CloudRuntimeException("Start VM " + vmName + " catch BadAsyncResult and VM is not in RUNNING state");
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to start VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e1) {
-                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
-                }
-            }
-        }
-    }
-
-    protected void startvmfailhandle(final Connection conn, final VM vm, final List<Ternary<SR, VDI, VolumeVO>> mounts) {
-        if (vm != null) {
-            try {
-
-                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
-                    try {
-                        vm.hardShutdown(conn);
-                    } catch (final Exception e) {
-                        final String msg = "VM hardshutdown failed due to " + e.toString();
-                        s_logger.warn(msg, e);
-                    }
-                }
-                if (vm.getPowerState(conn) == VmPowerState.HALTED) {
-                    try {
-                        vm.destroy(conn);
-                    } catch (final Exception e) {
-                        final String msg = "VM destroy failed due to " + e.toString();
-                        s_logger.warn(msg, e);
-                    }
-                }
-            } catch (final Exception e) {
-                final String msg = "VM getPowerState failed due to " + e.toString();
-                s_logger.warn(msg, e);
-            }
-        }
-        if (mounts != null) {
-            for (final Ternary<SR, VDI, VolumeVO> mount : mounts) {
-                final VDI vdi = mount.second();
-                Set<VBD> vbds = null;
-                try {
-                    vbds = vdi.getVBDs(conn);
-                } catch (final Exception e) {
-                    final String msg = "VDI getVBDS failed due to " + e.toString();
-                    s_logger.warn(msg, e);
-                    continue;
-                }
-                for (final VBD vbd : vbds) {
-                    try {
-                        vbd.unplug(conn);
-                        vbd.destroy(conn);
-                    } catch (final Exception e) {
-                        final String msg = "VBD destroy failed due to " + e.toString();
-                        s_logger.warn(msg, e);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean stop() {
-        disconnected();
-        return true;
-    }
-
-    private HashMap<String, Pair<Long, Long>> syncNetworkGroups(final Connection conn, final long id) {
-        final HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
-
-        final String result = callHostPlugin(conn, "vmops", "get_rule_logs_for_vms", "host_uuid", _host.getUuid());
-        s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result);
-        final String[] rulelogs = result != null ? result.split(";") : new String[0];
-        for (final String rulesforvm : rulelogs) {
-            final String[] log = rulesforvm.split(",");
-            if (log.length != 6) {
-                continue;
-            }
-            // output = ','.join([vmName, vmID, vmIP, domID, signature, seqno])
-            try {
-                states.put(log[0], new Pair<Long, Long>(Long.parseLong(log[1]), Long.parseLong(log[5])));
-            } catch (final NumberFormatException nfe) {
-                states.put(log[0], new Pair<Long, Long>(-1L, -1L));
-            }
-        }
-        return states;
-    }
-
-    public boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException {
-        dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS);
-        Host.managementReconfigure(conn, dest);
-        String hostUuid = null;
-        int count = 0;
-        while (count < 10) {
-            try {
-                Thread.sleep(10000);
-                hostUuid = host.getUuid(conn);
-                if (hostUuid != null) {
-                    break;
-                }
-                ++count;
-            } catch (final XmlRpcException e) {
-                s_logger.debug("Waiting for host to come back: " + e.getMessage());
-            } catch (final XenAPIException e) {
-                s_logger.debug("Waiting for host to come back: " + e.getMessage());
-            } catch (final InterruptedException e) {
-                s_logger.debug("Gotta run");
-                return false;
-            }
-        }
-        if (hostUuid == null) {
-            s_logger.warn("Unable to transfer the management network from " + spr.uuid);
-            return false;
-        }
-
-        src.reconfigureIp(conn, Types.IpConfigurationMode.NONE, null, null, null, null);
-        return true;
-    }
-
-    protected void umount(final Connection conn, final VDI vdi) {
-
-    }
-
-    public void umountSnapshotDir(final Connection conn, final Long dcId) {
-        try {
-            callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString());
-        } catch (final Exception e) {
-            s_logger.debug("Failed to umount snapshot dir", e);
-        }
-    }
-
-    public String upgradeSnapshot(final Connection conn, final String templatePath, final String snapshotPath) {
-        final String results = callHostPluginAsync(conn, "vmopspremium", "upgrade_snapshot", 2 * 60 * 60, "templatePath", templatePath, "snapshotPath", snapshotPath);
-
-        if (results == null || results.isEmpty()) {
-            final String msg = "upgrade_snapshot return null";
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        final String[] tmp = results.split("#");
-        final String status = tmp[0];
-        if (status.equals("0")) {
-            return results;
-        } else {
-            s_logger.warn(results);
-            throw new CloudRuntimeException(results);
-        }
-    }
-
-    public void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
-        final long beginTime = System.currentTimeMillis();
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout
-                    + "ms timeout");
-        }
-        while (task.getStatus(c) == Types.TaskStatusType.PENDING) {
-            try {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") is pending, sleeping for " + pollInterval + "ms");
-                }
-                Thread.sleep(pollInterval);
-            } catch (final InterruptedException e) {
-            }
-            if (System.currentTimeMillis() - beginTime > timeout) {
-                final String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
-                s_logger.warn(msg);
-                task.cancel(c);
-                task.destroy(c);
-                throw new TimeoutException(msg);
-            }
-        }
-    }
-
-    public boolean createAndAttachConfigDriveIsoForVM(final Connection conn, final VM vm, final List<String[]> vmDataList, final String configDriveLabel) throws XenAPIException, XmlRpcException {
-
-        final String vmName = vm.getNameLabel(conn);
-
-        // create SR
-        final SR sr =  createLocalIsoSR(conn, _configDriveSRName+_host.getIp());
-        if (sr == null) {
-            s_logger.debug("Failed to create local SR for the config drive");
-            return false;
-        }
-
-        s_logger.debug("Creating vm data files in config drive for vm "+vmName);
-        // 1. create vm data files
-        if (!createVmdataFiles(vmName, vmDataList, configDriveLabel)) {
-            s_logger.debug("Failed to create vm data files in config drive for vm "+vmName);
-            return false;
-        }
-
-        // 2. copy config drive iso to host
-        if (!copyConfigDriveIsoToHost(conn, sr, vmName)) {
-            return false;
-        }
-
-        // 3. attachIsoToVM
-        if (!attachConfigDriveIsoToVm(conn, vm)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public boolean createVmdataFiles(final String vmName, final List<String[]> vmDataList, final String configDriveLabel) {
-
-        // add vm iso to the isolibrary
-        final String isoPath = "/tmp/"+vmName+"/configDrive/";
-        final String configDriveName = "cloudstack/";
-
-        //create folder for the VM
-        //Remove the folder before creating it.
-
-        try {
-            deleteLocalFolder("/tmp/" + isoPath);
-        } catch (final IOException e) {
-            s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
-        } catch (final Exception e) {
-            s_logger.debug("Failed to delete the exiting config drive for vm "+vmName+ " "+ e.getMessage());
-        }
-
-
-        if (vmDataList != null) {
-            for (final String[] item : vmDataList) {
-                final String dataType = item[0];
-                final String fileName = item[1];
-                final String content = item[2];
-
-                // create file with content in folder
-
-                if (dataType != null && !dataType.isEmpty()) {
-                    //create folder
-                    final String  folder = isoPath+configDriveName+dataType;
-                    if (folder != null && !folder.isEmpty()) {
-                        final File dir = new File(folder);
-                        final boolean result = true;
-
-                        try {
-                            if (!dir.exists()) {
-                                dir.mkdirs();
-                            }
-                        }catch (final SecurityException ex) {
-                            s_logger.debug("Failed to create dir "+ ex.getMessage());
-                            return false;
-                        }
-
-                        if (result && content != null && !content.isEmpty()) {
-                            File file = new File(folder+"/"+fileName+".txt");
-                            try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(file.getAbsoluteFile()),"UTF-8");
-                                 BufferedWriter bw = new BufferedWriter(fw);
-                                ) {
-                                bw.write(content);
-                                s_logger.debug("created file: "+ file + " in folder:"+folder);
-                            } catch (final IOException ex) {
-                                s_logger.debug("Failed to create file "+ ex.getMessage());
-                                return false;
-                            }
-                        }
-                    }
-                }
-            }
-            s_logger.debug("Created the vm data in "+ isoPath);
-        }
-
-        String s = null;
-        try {
-
-            final String cmd =  "mkisofs -iso-level 3 -V "+ configDriveLabel +" -o "+ isoPath+vmName +".iso " + isoPath;
-            final Process p = Runtime.getRuntime().exec(cmd);
-
-            final BufferedReader stdInput = new BufferedReader(new
-                    InputStreamReader(p.getInputStream(),Charset.defaultCharset()));
-
-            final BufferedReader stdError = new BufferedReader(new
-                    InputStreamReader(p.getErrorStream(),Charset.defaultCharset()));
-
-            // read the output from the command
-            while ((s = stdInput.readLine()) != null) {
-                s_logger.debug(s);
-            }
-
-            // read any errors from the attempted command
-            while ((s = stdError.readLine()) != null) {
-                s_logger.debug(s);
-            }
-            s_logger.debug(" Created config drive ISO using the command " + cmd +" in the host "+ _host.getIp());
-        } catch (final IOException e) {
-            s_logger.debug(e.getMessage());
-            return false;
-        }
-
-        return true;
-    }
-
-    public boolean copyConfigDriveIsoToHost(final Connection conn, final SR sr, final String vmName) {
-
-        final String vmIso = "/tmp/"+vmName+"/configDrive/"+vmName+".iso";
-        //scp file into the host
-        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
-
-        try {
-            sshConnection.connect(null, 60000, 60000);
-            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
-                throw new CloudRuntimeException("Unable to authenticate");
-            }
-
-            s_logger.debug("scp config drive iso file "+vmIso +" to host " + _host.getIp() +" path "+_configDriveIsopath);
-            final SCPClient scp = new SCPClient(sshConnection);
-            final String p = "0755";
-
-            scp.put(vmIso, _configDriveIsopath, p);
-            sr.scan(conn);
-            s_logger.debug("copied config drive iso to host " + _host);
-        } catch (final IOException e) {
-            s_logger.debug("failed to copy configdrive iso " + vmIso + " to host " + _host, e);
-            return false;
-        } catch (final XmlRpcException e) {
-            s_logger.debug("Failed to scan config drive iso SR "+ _configDriveSRName+_host.getIp() + " in host "+ _host, e);
-            return false;
-        } finally {
-            sshConnection.close();
-            //clean up the config drive files
-
-            final String configDir = "/tmp/"+vmName;
-            try {
-                deleteLocalFolder(configDir);
-                s_logger.debug("Successfully cleaned up config drive directory " + configDir
-                        + " after copying it to host ");
-            } catch (final Exception e) {
-                s_logger.debug("Failed to delete config drive folder :" + configDir + " for VM " + vmName + " "
-                        + e.getMessage());
-            }
-        }
-
-        return true;
-    }
-
-    public boolean attachConfigDriveIsoToVm(final Connection conn, final VM vm) throws XenAPIException, XmlRpcException {
-
-        final String vmName = vm.getNameLabel(conn);
-        final String isoURL = _configDriveIsopath + vmName+".iso";
-        VDI srVdi;
-
-        //1. find the vdi of the iso
-        //2. find the vbd for the vdi
-        //3. attach iso to vm
-
-        try {
-            final Set<VDI> vdis = VDI.getByNameLabel(conn, vmName+".iso");
-            if (vdis.isEmpty()) {
-                throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL);
-            }
-            srVdi =  vdis.iterator().next();
-
-        } catch (final XenAPIException e) {
-            s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
-            return false;
-        } catch (final Exception e) {
-            s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
-            return false;
-        }
-
-        VBD isoVBD = null;
-
-        // Find the VM's CD-ROM VBD
-        final Set<VBD> vbds = vm.getVBDs(conn);
-        for (final VBD vbd : vbds) {
-            final Types.VbdType type = vbd.getType(conn);
-
-            final VBD.Record vbdr = vbd.getRecord(conn);
-
-            // if the device exists then attach it
-            if (!vbdr.userdevice.equals(_attachIsoDeviceNum) && type == Types.VbdType.CD) {
-                isoVBD = vbd;
-                break;
-            }
-        }
-
-        if (isoVBD == null) {
-            //create vbd
-            final VBD.Record cfgDriveVbdr = new VBD.Record();
-            cfgDriveVbdr.VM = vm;
-            cfgDriveVbdr.empty = true;
-            cfgDriveVbdr.bootable = false;
-            cfgDriveVbdr.userdevice = "autodetect";
-            cfgDriveVbdr.mode = Types.VbdMode.RO;
-            cfgDriveVbdr.type = Types.VbdType.CD;
-            final VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr);
-            isoVBD = cfgDriveVBD;
-
-            s_logger.debug("Created CD-ROM VBD for VM: " + vm);
-        }
-
-        if (isoVBD != null) {
-            // If an ISO is already inserted, eject it
-            if (isoVBD.getEmpty(conn) == false) {
-                isoVBD.eject(conn);
-            }
-
-            try {
-                // Insert the new ISO
-                isoVBD.insert(conn, srVdi);
-                s_logger.debug("Attached config drive iso to vm " + vmName);
-            }catch (final XmlRpcException ex) {
-                s_logger.debug("Failed to attach config drive iso to vm " + vmName);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public SR createLocalIsoSR(final Connection conn, final String srName) throws XenAPIException, XmlRpcException {
-
-        // if config drive sr already exists then return
-        SR sr = getSRByNameLabelandHost(conn, _configDriveSRName+_host.getIp());
-
-        if (sr != null) {
-            s_logger.debug("Config drive SR already exist, returing it");
-            return sr;
-        }
-
-        try{
-            final Map<String, String> deviceConfig = new HashMap<String, String>();
-
-            final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
-            try {
-                sshConnection.connect(null, 60000, 60000);
-                if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
-                    throw new CloudRuntimeException("Unable to authenticate");
-                }
-
-                final String cmd = "mkdir -p " + _configDriveIsopath;
-                if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
-                    throw new CloudRuntimeException("Cannot create directory configdrive_iso on XenServer hosts");
-                }
-            } catch (final IOException e) {
-                throw new CloudRuntimeException("Unable to create iso folder", e);
-            } finally {
-                sshConnection.close();
-            }
-            s_logger.debug("Created the config drive SR " + srName +" folder path "+ _configDriveIsopath);
-
-            deviceConfig.put("location",  _configDriveIsopath);
-            deviceConfig.put("legacy_mode", "true");
-            final Host host = Host.getByUuid(conn, _host.getUuid());
-            final String type = SRType.ISO.toString();
-            sr = SR.create(conn, host, deviceConfig, new Long(0),  _configDriveIsopath, "iso", type, "iso", false, new HashMap<String, String>());
-
-            sr.setNameLabel(conn, srName);
-            sr.setNameDescription(conn, deviceConfig.get("location"));
-
-            sr.scan(conn);
-            s_logger.debug("Config drive ISO SR at the path " + _configDriveIsopath  +" got created in host " + _host);
-            return sr;
-        } catch (final XenAPIException e) {
-            final String msg = "createLocalIsoSR failed! mountpoint " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        } catch (final Exception e) {
-            final String msg = "createLocalIsoSR failed! mountpoint:  due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        }
-
-    }
-
-    public void deleteLocalFolder(final String directory) throws Exception {
-        if (directory == null || directory.isEmpty()) {
-            final String msg = "Invalid directory path (null/empty) detected. Cannot delete specified directory.";
-            s_logger.debug(msg);
-            throw new Exception(msg);
-        }
-
-        try {
-            FileUtils.deleteDirectory(new File(directory));
-        } catch (final IOException e) {
-            // IOException here means failure to delete. Not swallowing it here to
-            // let the caller handle with appropriate contextual log message.
-            throw e;
-        }
-    }
-
-    protected SR getSRByNameLabel(Connection conn, String name) throws BadServerResponse, XenAPIException, XmlRpcException {
-        Set<SR> srs = SR.getByNameLabel(conn, name);
-        SR ressr = null;
-        for (SR sr : srs) {
-            Set<PBD> pbds;
-            pbds = sr.getPBDs(conn);
-            for (PBD pbd : pbds) {
-                PBD.Record pbdr = pbd.getRecord(conn);
-                if (pbdr.host != null) {
-                    ressr = sr;
-                    break;
-                }
-            }
-        }
-        return ressr;
-    }
-
-
-    public boolean attachConfigDriveToMigratedVm(Connection conn, String vmName, String ipAddr) {
-
-        // attach the config drive in destination host
-
-        try {
-            s_logger.debug("Attaching config drive iso device for the VM "+ vmName + " In host "+ ipAddr);
-            Set<VM> vms = VM.getByNameLabel(conn, vmName);
-
-            SR sr = getSRByNameLabel(conn, _configDriveSRName + ipAddr);
-            //Here you will find only two vdis with the <vmname>.iso.
-            //one is from source host and second from dest host
-            Set<VDI> vdis = VDI.getByNameLabel(conn, vmName + ".iso");
-            if (vdis.isEmpty()) {
-                s_logger.debug("Could not find config drive ISO: " + vmName);
-                return false;
-            }
-
-            VDI configdriveVdi = null;
-            for (VDI vdi : vdis) {
-                SR vdiSr = vdi.getSR(conn);
-                if (vdiSr.getUuid(conn).equals(sr.getUuid(conn))) {
-                    //get this vdi to attach to vbd
-                    configdriveVdi = vdi;
-                    s_logger.debug("VDI for the config drive ISO  " + vdi);
-                } else {
-                    // delete the vdi in source host so that the <vmname>.iso file is get removed
-                    s_logger.debug("Removing the source host VDI for the config drive ISO  " + vdi);
-                    vdi.destroy(conn);
-                }
-            }
-
-            if (configdriveVdi == null) {
-                s_logger.debug("Config drive ISO VDI is not found ");
-                return false;
-            }
-
-            for (VM vm : vms) {
-
-                //create vbd
-                VBD.Record cfgDriveVbdr = new VBD.Record();
-                cfgDriveVbdr.VM = vm;
-                cfgDriveVbdr.empty = true;
-                cfgDriveVbdr.bootable = false;
-                cfgDriveVbdr.userdevice = "autodetect";
-                cfgDriveVbdr.mode = Types.VbdMode.RO;
-                cfgDriveVbdr.type = Types.VbdType.CD;
-
-                VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr);
-
-                s_logger.debug("Inserting vbd " + configdriveVdi);
-                cfgDriveVBD.insert(conn, configdriveVdi);
-                break;
-
-            }
-
-            return true;
-
-        } catch (BadServerResponse e) {
-            s_logger.warn("Failed to attach config drive ISO to the VM  "+ vmName + " In host " + ipAddr + " due to a bad server response.", e);
-            return false;
-        } catch (XenAPIException e) {
-            s_logger.warn("Failed to attach config drive ISO to the VM  "+ vmName + " In host " + ipAddr + " due to a xapi problem.", e);
-            return false;
-        } catch (XmlRpcException e) {
-            s_logger.warn("Failed to attach config drive ISO to the VM  "+ vmName + " In host " + ipAddr + " due to a problem in a remote call.", e);
-            return false;
-        }
-
-    }
-
-}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java
deleted file mode 100644
index e8e21d4..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.xenserver.resource;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.ssh.SSHCmdHelper;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.Network;
-import com.xensource.xenapi.PIF;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VLAN;
-
-public class XenServer56Resource extends CitrixResourceBase {
-    private final static Logger s_logger = Logger.getLogger(XenServer56Resource.class);
-
-    @Override
-    protected String getPatchFilePath() {
-        return "scripts/vm/hypervisor/xenserver/xenserver56/patch";
-    }
-
-    @Override
-    public void disableVlanNetwork(final Connection conn, final Network network) {
-        try {
-            final Network.Record networkr = network.getRecord(conn);
-            if (!networkr.nameLabel.startsWith("VLAN")) {
-                return;
-            }
-            final String bridge = networkr.bridge.trim();
-            for (final PIF pif : networkr.PIFs) {
-                final PIF.Record pifr = pif.getRecord(conn);
-                if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.getUuid())) {
-                    continue;
-                }
-
-                final VLAN vlan = pifr.VLANMasterOf;
-                if (vlan != null) {
-                    final String vlannum = pifr.VLAN.toString();
-                    final String device = pifr.device.trim();
-                    if (vlannum.equals("-1")) {
-                        return;
-                    }
-                    try {
-                        vlan.destroy(conn);
-                        final Host host = Host.getByUuid(conn, _host.getUuid());
-                        host.forgetDataSourceArchives(conn, "pif_" + bridge + "_tx");
-                        host.forgetDataSourceArchives(conn, "pif_" + bridge + "_rx");
-                        host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx");
-                        host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx");
-                    } catch (final XenAPIException e) {
-                        s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.getUuid() + " due to " + e.toString());
-                    }
-                }
-                return;
-            }
-        } catch (final XenAPIException e) {
-            final String msg = "Unable to disable VLAN network due to " + e.toString();
-            s_logger.warn(msg, e);
-        } catch (final Exception e) {
-            final String msg = "Unable to disable VLAN network due to " + e.getMessage();
-            s_logger.warn(msg, e);
-        }
-    }
-
-    @Override
-    public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) {
-        String args = "";
-        if (option.equals("get")) {
-            args += "-g";
-        } else if (option.equals("create")) {
-            args += "-c";
-        } else if (option.equals("reset")) {
-            args += "-r";
-        } else if (option.equals("addVif")) {
-            args += "-a ";
-            args += vif;
-        } else if (option.equals("deleteVif")) {
-            args += "-d ";
-            args += vif;
-        }
-
-        return executeInVR(privateIpAddress, "netusage.sh", args).getDetails();
-    }
-
-    public Boolean checkHeartbeat(final String hostuuid) {
-        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
-        try {
-            sshConnection.connect(null, 60000, 60000);
-            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
-                throw new CloudRuntimeException("Unable to authenticate");
-            }
-
-            final String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " + Integer.toString(_heartbeatInterval * 2);
-            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, shcmd)) {
-                s_logger.debug("Heart beat is gone so dead.");
-                return false;
-            }
-            s_logger.debug("Heart beat is still going");
-            return true;
-        } catch (final Exception e) {
-            s_logger.debug("health check failed due to catch exception " + e.toString());
-            return null;
-        } finally {
-            sshConnection.close();
-        }
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-        pingXAPI();
-        final StartupCommand[] cmds = super.initialize();
-        return cmds;
-    }
-}
\ No newline at end of file
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
deleted file mode 100644
index 76c09dc..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
+++ /dev/null
@@ -1,1690 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.hypervisor.xenserver.resource;
-
-import static com.cloud.utils.ReflectUtil.flattenProperties;
-import static com.google.common.collect.Lists.newArrayList;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.log4j.Logger;
-import org.apache.xmlrpc.XmlRpcException;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.VmPowerState;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VBD;
-import com.xensource.xenapi.VDI;
-import com.xensource.xenapi.VM;
-
-import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DettachAnswer;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.command.ForgetObjectCmd;
-import org.apache.cloudstack.storage.command.IntroduceObjectAnswer;
-import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
-import org.apache.cloudstack.storage.command.ResignatureAnswer;
-import org.apache.cloudstack.storage.command.ResignatureCommand;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
-import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
-import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.resource.StorageProcessor;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.storage.S3.ClientOptions;
-
-public class XenServerStorageProcessor implements StorageProcessor {
-    private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
-    protected CitrixResourceBase hypervisorResource;
-    protected String BaseMountPointOnHost = "/var/run/cloud_mount";
-
-    public XenServerStorageProcessor(final CitrixResourceBase resource) {
-        hypervisorResource = resource;
-    }
-
-    // if the source SR needs to be attached to, do so
-    // take a snapshot of the source VDI (on the source SR)
-    // create an iSCSI SR based on the new back-end volume
-    // copy the snapshot to the new SR
-    // delete the snapshot
-    // detach the new SR
-    // if we needed to perform an attach to the source SR, detach from it
-    @Override
-    public SnapshotAndCopyAnswer snapshotAndCopy(final SnapshotAndCopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-
-        try {
-            SR sourceSr = null;
-
-            final Map<String, String> sourceDetails = cmd.getSourceDetails();
-
-            if (sourceDetails != null && sourceDetails.keySet().size() > 0) {
-                final String iScsiName = sourceDetails.get(DiskTO.IQN);
-                final String storageHost = sourceDetails.get(DiskTO.STORAGE_HOST);
-                final String chapInitiatorUsername = sourceDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-                final String chapInitiatorSecret = sourceDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-                sourceSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false);
-            }
-
-            final VDI vdiToSnapshot = VDI.getByUuid(conn, cmd.getUuidOfSourceVdi());
-
-            final VDI vdiSnapshot = vdiToSnapshot.snapshot(conn, new HashMap<String, String>());
-
-            final Map<String, String> destDetails = cmd.getDestDetails();
-
-            final String iScsiName = destDetails.get(DiskTO.IQN);
-            final String storageHost = destDetails.get(DiskTO.STORAGE_HOST);
-            final String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-            final SR newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false);
-
-            final VDI vdiCopy = vdiSnapshot.copy(conn, newSr);
-
-            final String vdiUuid = vdiCopy.getUuid(conn);
-
-            vdiSnapshot.destroy(conn);
-
-            if (sourceSr != null) {
-                hypervisorResource.removeSR(conn, sourceSr);
-            }
-
-            hypervisorResource.removeSR(conn, newSr);
-
-            final SnapshotAndCopyAnswer snapshotAndCopyAnswer = new SnapshotAndCopyAnswer();
-
-            snapshotAndCopyAnswer.setPath(vdiUuid);
-
-            return snapshotAndCopyAnswer;
-        }
-        catch (final Exception ex) {
-            s_logger.warn("Failed to take and copy snapshot: " + ex.toString(), ex);
-
-            return new SnapshotAndCopyAnswer(ex.getMessage());
-        }
-    }
-
-    @Override
-    public ResignatureAnswer resignature(final ResignatureCommand cmd) {
-        SR newSr = null;
-
-        final Connection conn = hypervisorResource.getConnection();
-
-        try {
-            final Map<String, String> details = cmd.getDetails();
-
-            final String iScsiName = details.get(DiskTO.IQN);
-            final String storageHost = details.get(DiskTO.STORAGE_HOST);
-            final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-            newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true, false);
-
-            Set<VDI> vdis = newSr.getVDIs(conn);
-
-            if (vdis.size() != 1) {
-                throw new RuntimeException("There were " + vdis.size() + " VDIs in the SR.");
-            }
-
-            VDI vdi = vdis.iterator().next();
-
-            final ResignatureAnswer resignatureAnswer = new ResignatureAnswer();
-
-            resignatureAnswer.setSize(vdi.getVirtualSize(conn));
-            resignatureAnswer.setPath(vdi.getUuid(conn));
-            resignatureAnswer.setFormat(ImageFormat.VHD);
-
-            return resignatureAnswer;
-        }
-        catch (final Exception ex) {
-            s_logger.warn("Failed to resignature: " + ex.toString(), ex);
-
-            return new ResignatureAnswer(ex.getMessage());
-        }
-        finally {
-            if (newSr != null) {
-                hypervisorResource.removeSR(conn, newSr);
-            }
-        }
-    }
-
-    @Override
-    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
-        //Not implemented for Xen
-        return null;
-    }
-
-    @Override
-    public AttachAnswer attachIso(final AttachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final DataTO data = disk.getData();
-        final DataStoreTO store = data.getDataStore();
-
-        String isoURL = null;
-        if (store == null) {
-            final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
-            isoURL = iso.getName();
-        } else {
-            if (!(store instanceof NfsTO)) {
-                s_logger.debug("Can't attach a iso which is not created on nfs: ");
-                return new AttachAnswer("Can't attach a iso which is not created on nfs: ");
-            }
-            final NfsTO nfsStore = (NfsTO) store;
-            isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
-        }
-
-        final String vmName = cmd.getVmName();
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-
-            VBD isoVBD = null;
-
-            // Find the VM
-            final VM vm = hypervisorResource.getVM(conn, vmName);
-            // Find the ISO VDI
-            final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL);
-
-            // Find the VM's CD-ROM VBD
-            final Set<VBD> vbds = vm.getVBDs(conn);
-            for (final VBD vbd : vbds) {
-                final String userDevice = vbd.getUserdevice(conn);
-                final Types.VbdType type = vbd.getType(conn);
-
-                if (userDevice.equals("3") && type == Types.VbdType.CD) {
-                    isoVBD = vbd;
-                    break;
-                }
-            }
-
-            if (isoVBD == null) {
-                throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName);
-            } else {
-                // If an ISO is already inserted, eject it
-                if (!isoVBD.getEmpty(conn)) {
-                    isoVBD.eject(conn);
-                }
-
-                // Insert the new ISO
-                isoVBD.insert(conn, isoVDI);
-            }
-
-            return new AttachAnswer(disk);
-
-        } catch (final XenAPIException e) {
-            s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
-            return new AttachAnswer(e.toString());
-        } catch (final Exception e) {
-            s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
-            return new AttachAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public AttachAnswer attachVolume(final AttachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final DataTO data = disk.getData();
-        try {
-            final String vmName = cmd.getVmName();
-            final String vdiNameLabel = vmName + "-DATA";
-
-            final Connection conn = hypervisorResource.getConnection();
-            VM vm = null;
-
-            boolean vmNotRunning = true;
-
-            try {
-                vm = hypervisorResource.getVM(conn, vmName);
-
-                final VM.Record vmr = vm.getRecord(conn);
-
-                vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
-            } catch (final CloudRuntimeException ex) {
-            }
-
-            final Map<String, String> details = disk.getDetails();
-            final boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
-
-            // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
-            // this should probably never actually happen
-            if (vmNotRunning && !isManaged) {
-                return new AttachAnswer(disk);
-            }
-
-            VDI vdi;
-
-            if (isManaged) {
-                vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel);
-
-                if (vmNotRunning) {
-                    final DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType());
-
-                    return new AttachAnswer(newDisk);
-                }
-            } else {
-                vdi = hypervisorResource.mount(conn, null, null, data.getPath());
-            }
-
-            hypervisorResource.destroyUnattachedVBD(conn, vm);
-
-            final VBD.Record vbdr = new VBD.Record();
-
-            vbdr.VM = vm;
-            vbdr.VDI = vdi;
-            vbdr.bootable = false;
-            vbdr.userdevice = "autodetect";
-
-            final Long deviceId = disk.getDiskSeq();
-
-            if (deviceId != null && !hypervisorResource.isDeviceUsed(conn, vm, deviceId)) {
-                vbdr.userdevice = deviceId.toString();
-            }
-
-            vbdr.mode = Types.VbdMode.RW;
-            vbdr.type = Types.VbdType.DISK;
-            vbdr.unpluggable = true;
-
-            final VBD vbd = VBD.create(conn, vbdr);
-
-            // Attach the VBD to the VM
-            try {
-                vbd.plug(conn);
-            } catch (final Exception e) {
-                vbd.destroy(conn);
-                throw e;
-            }
-
-            // Update the VDI's label to include the VM name
-            vdi.setNameLabel(conn, vdiNameLabel);
-
-            final DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(vbd.getUserdevice(conn)), vdi.getUuid(conn), disk.getType());
-
-            return new AttachAnswer(newDisk);
-        } catch (final Exception e) {
-            final String msg = "Failed to attach volume for uuid: " + data.getPath() + " due to "  + e.toString();
-
-            s_logger.warn(msg, e);
-
-            return new AttachAnswer(msg);
-        }
-    }
-
-    @Override
-    public Answer dettachIso(final DettachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final DataTO data = disk.getData();
-        final DataStoreTO store = data.getDataStore();
-
-        String isoURL = null;
-        if (store == null) {
-            final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
-            isoURL = iso.getName();
-        } else {
-            if (!(store instanceof NfsTO)) {
-                s_logger.debug("Can't attach a iso which is not created on nfs: ");
-                return new AttachAnswer("Can't attach a iso which is not created on nfs: ");
-            }
-            final NfsTO nfsStore = (NfsTO) store;
-            isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
-        }
-
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-            // Find the VM
-            final VM vm = hypervisorResource.getVM(conn, cmd.getVmName());
-            final String vmUUID = vm.getUuid(conn);
-
-            // Find the ISO VDI
-            final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL);
-
-            final SR sr = isoVDI.getSR(conn);
-
-            // Look up all VBDs for this VDI
-            final Set<VBD> vbds = isoVDI.getVBDs(conn);
-
-            // Iterate through VBDs, and if the VBD belongs the VM, eject
-            // the ISO from it
-            for (final VBD vbd : vbds) {
-                final VM vbdVM = vbd.getVM(conn);
-                final String vbdVmUUID = vbdVM.getUuid(conn);
-
-                if (vbdVmUUID.equals(vmUUID)) {
-                    // If an ISO is already inserted, eject it
-                    if (!vbd.getEmpty(conn)) {
-                        vbd.eject(conn);
-                    }
-                    break;
-                }
-            }
-
-            if (!XenServerUtilitiesHelper.isXenServerToolsSR(sr.getNameLabel(conn))) {
-                hypervisorResource.removeSR(conn, sr);
-            }
-
-            return new DettachAnswer(disk);
-        } catch (final XenAPIException e) {
-            final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + "  due to " + e.toString();
-            s_logger.warn(msg, e);
-            return new DettachAnswer(msg);
-        } catch (final Exception e) {
-            final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + "  due to " + e.getMessage();
-            s_logger.warn(msg, e);
-            return new DettachAnswer(msg);
-        }
-    }
-
-    @Override
-    public Answer dettachVolume(final DettachCommand cmd) {
-        final DiskTO disk = cmd.getDisk();
-        final DataTO data = disk.getData();
-
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-
-            final String vmName = cmd.getVmName();
-            VM vm = null;
-
-            boolean vmNotRunning = true;
-
-            try {
-                vm = hypervisorResource.getVM(conn, vmName);
-
-                final VM.Record vmr = vm.getRecord(conn);
-
-                vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
-            } catch (final CloudRuntimeException ex) {
-            }
-
-            // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
-            // this should probably never actually happen
-            if (vmNotRunning && !cmd.isManaged()) {
-                return new DettachAnswer(disk);
-            }
-
-            if (!vmNotRunning) {
-                final VDI vdi = hypervisorResource.mount(conn, null, null, data.getPath());
-
-                // Look up all VBDs for this VDI
-                final Set<VBD> vbds = vdi.getVBDs(conn);
-
-                // Detach each VBD from its VM, and then destroy it
-                for (final VBD vbd : vbds) {
-                    final VBD.Record vbdr = vbd.getRecord(conn);
-
-                    if (vbdr.currentlyAttached) {
-                        vbd.unplug(conn);
-                    }
-
-                    vbd.destroy(conn);
-                }
-
-                hypervisorResource.umount(conn, vdi);
-            }
-
-            if (cmd.isManaged()) {
-                hypervisorResource.handleSrAndVdiDetach(cmd.get_iScsiName(), conn);
-            }
-
-            return new DettachAnswer(disk);
-        } catch (final Exception e) {
-            s_logger.warn("Failed dettach volume: " + data.getPath());
-            return new DettachAnswer("Failed dettach volume: " + data.getPath() + ", due to " + e.toString());
-        }
-    }
-
-    protected VDI createVdi(final Connection conn, final String vdiName, final SR sr, final long size) throws BadServerResponse, XenAPIException, XmlRpcException {
-        final VDI.Record vdir = new VDI.Record();
-        vdir.nameLabel = vdiName;
-        vdir.SR = sr;
-        vdir.type = Types.VdiType.USER;
-
-        vdir.virtualSize = size;
-        final VDI vdi = VDI.create(conn, vdir);
-        return vdi;
-    }
-
-    protected void deleteVDI(final Connection conn, final VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException {
-        vdi.destroy(conn);
-    }
-
-    @Override
-    public Answer createSnapshot(final CreateObjectCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData();
-        final long snapshotId = snapshotTO.getId();
-        final String snapshotName = snapshotTO.getName();
-        String details = "create snapshot operation Failed for snapshotId: " + snapshotId;
-        String snapshotUUID = null;
-
-        try {
-            final String volumeUUID = snapshotTO.getVolume().getPath();
-            final VDI volume = VDI.getByUuid(conn, volumeUUID);
-
-            final VDI snapshot = volume.snapshot(conn, new HashMap<String, String>());
-
-            if (snapshotName != null) {
-                snapshot.setNameLabel(conn, snapshotName);
-            }
-
-            snapshotUUID = snapshot.getUuid(conn);
-            final String preSnapshotUUID = snapshotTO.getParentSnapshotPath();
-            //check if it is a empty snapshot
-            if (preSnapshotUUID != null) {
-                final SR sr = volume.getSR(conn);
-                final String srUUID = sr.getUuid(conn);
-                final String type = sr.getType(conn);
-                final Boolean isISCSI = IsISCSI(type);
-                final String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI);
-
-                try {
-                    final String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI);
-                    if (snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) {
-                        // this is empty snapshot, remove it
-                        snapshot.destroy(conn);
-                        snapshotUUID = preSnapshotUUID;
-                    }
-                } catch (final Exception e) {
-                    s_logger.debug("Failed to get parent snapshot", e);
-                }
-            }
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            newSnapshot.setPath(snapshotUUID);
-            return new CreateObjectAnswer(newSnapshot);
-        } catch (final XenAPIException e) {
-            details += ", reason: " + e.toString();
-            s_logger.warn(details, e);
-        } catch (final Exception e) {
-            details += ", reason: " + e.toString();
-            s_logger.warn(details, e);
-        }
-
-        return new CreateObjectAnswer(details);
-    }
-
-    @Override
-    public Answer deleteVolume(final DeleteCommand cmd) {
-        final DataTO volume = cmd.getData();
-        final Connection conn = hypervisorResource.getConnection();
-        String errorMsg = null;
-        try {
-            final VDI vdi = VDI.getByUuid(conn, volume.getPath());
-            for(VDI svdi : vdi.getSnapshots(conn)) {
-                deleteVDI(conn, svdi);
-            }
-            deleteVDI(conn, vdi);
-            return new Answer(null);
-        } catch (final BadServerResponse e) {
-            s_logger.debug("Failed to delete volume", e);
-            errorMsg = e.toString();
-        } catch (final XenAPIException e) {
-            s_logger.debug("Failed to delete volume", e);
-            errorMsg = e.toString();
-        } catch (final XmlRpcException e) {
-            s_logger.debug("Failed to delete volume", e);
-            errorMsg = e.toString();
-        }
-        return new Answer(null, false, errorMsg);
-    }
-
-    protected boolean IsISCSI(final String type) {
-        return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
-    }
-
-    private String copy_vhd_from_secondarystorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) {
-        final String nameLabel = "cloud-" + UUID.randomUUID().toString();
-        final String results =
-                hypervisorResource.callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel",
-                        nameLabel);
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg = "copy_vhd_from_secondarystorage return null";
-        } else {
-            final String[] tmp = results.split("#");
-            final String status = tmp[0];
-            if (status.equals("0")) {
-                return tmp[1];
-            } else {
-                errMsg = tmp[1];
-            }
-        }
-        final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1);
-        if (hypervisorResource.killCopyProcess(conn, source)) {
-            destroyVDIbyNameLabel(conn, nameLabel);
-        }
-        s_logger.warn(errMsg);
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    private void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) {
-        try {
-            final Set<VDI> vdis = VDI.getByNameLabel(conn, nameLabel);
-            if (vdis.size() != 1) {
-                s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel);
-                return;
-            }
-            for (final VDI vdi : vdis) {
-                try {
-                    vdi.destroy(conn);
-                } catch (final Exception e) {
-                }
-            }
-        } catch (final Exception e) {
-        }
-    }
-
-    protected VDI getVDIbyUuid(final Connection conn, final String uuid) {
-        try {
-            return VDI.getByUuid(conn, uuid);
-        } catch (final Exception e) {
-            final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString();
-            s_logger.debug(msg);
-            throw new CloudRuntimeException(msg, e);
-        }
-    }
-
-    protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
-        final String parentUuid =
-                hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid,
-                        "isISCSI", isISCSI.toString());
-
-        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
-            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
-            // errString is already logged.
-            return null;
-        }
-        return parentUuid;
-    }
-
-    @Override
-    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
-        final DataTO srcDataTo = cmd.getSrcTO();
-        final DataTO destDataTo = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final DataStoreTO srcDataStoreTo = srcDataTo.getDataStore();
-        final Connection conn = hypervisorResource.getConnection();
-        SR sr = null;
-        boolean removeSrAfterCopy = false;
-
-        try {
-            if (srcDataStoreTo instanceof NfsTO && srcDataTo.getObjectType() == DataObjectType.TEMPLATE) {
-                final NfsTO srcImageStore = (NfsTO) srcDataStoreTo;
-                final TemplateObjectTO srcTemplateObjectTo = (TemplateObjectTO) srcDataTo;
-                final String storeUrl = srcImageStore.getUrl();
-                final URI uri = new URI(storeUrl);
-                final String tmplPath = uri.getHost() + ":" + uri.getPath() + "/" + srcDataTo.getPath();
-                final DataStoreTO destDataStoreTo = destDataTo.getDataStore();
-
-                boolean managed = false;
-                String storageHost = null;
-                String managedStoragePoolName = null;
-                String managedStoragePoolRootVolumeName = null;
-                String managedStoragePoolRootVolumeSize = null;
-                String chapInitiatorUsername = null;
-                String chapInitiatorSecret = null;
-
-                if (destDataStoreTo instanceof PrimaryDataStoreTO) {
-                    final PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo;
-
-                    final Map<String, String> details = destPrimaryDataStoreTo.getDetails();
-
-                    if (details != null) {
-                        managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
-
-                        if (managed) {
-                            storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
-                            managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
-                            managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
-                            managedStoragePoolRootVolumeSize = details.get(PrimaryDataStoreTO.VOLUME_SIZE);
-                            chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
-                            chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
-                            removeSrAfterCopy = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.REMOVE_AFTER_COPY));
-                        }
-                    }
-                }
-
-                if (managed) {
-                    final Map<String, String> details = new HashMap<String, String>();
-
-                    details.put(DiskTO.STORAGE_HOST, storageHost);
-                    details.put(DiskTO.IQN, managedStoragePoolName);
-                    details.put(DiskTO.VOLUME_SIZE, managedStoragePoolRootVolumeSize);
-                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInitiatorUsername);
-                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInitiatorSecret);
-
-                    sr = hypervisorResource.prepareManagedSr(conn, details);
-                } else {
-                    final String srName = destDataStoreTo.getUuid();
-                    final Set<SR> srs = SR.getByNameLabel(conn, srName);
-
-                    if (srs.size() != 1) {
-                        final String msg = "There are " + srs.size() + " SRs with same name: " + srName;
-
-                        s_logger.warn(msg);
-
-                        return new CopyCmdAnswer(msg);
-                    } else {
-                        sr = srs.iterator().next();
-                    }
-                }
-
-                final String srUuid = sr.getUuid(conn);
-                final String tmplUuid = copy_vhd_from_secondarystorage(conn, tmplPath, srUuid, wait);
-                final VDI tmplVdi = getVDIbyUuid(conn, tmplUuid);
-
-                final String uuidToReturn;
-                final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn);
-
-                if (managed) {
-                    uuidToReturn = tmplUuid;
-
-                    tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName);
-                } else {
-                    final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap<String, String>());
-
-                    uuidToReturn = snapshotVdi.getUuid(conn);
-
-                    snapshotVdi.setNameLabel(conn, "Template " + srcTemplateObjectTo.getName());
-
-                    tmplVdi.destroy(conn);
-                }
-
-                sr.scan(conn);
-
-                try {
-                    Thread.sleep(5000);
-                } catch (final InterruptedException e) {
-                }
-
-                final TemplateObjectTO newVol = new TemplateObjectTO();
-
-                newVol.setUuid(uuidToReturn);
-                newVol.setPath(uuidToReturn);
-
-                if (physicalSize != null) {
-                    newVol.setSize(physicalSize);
-                }
-
-                newVol.setFormat(ImageFormat.VHD);
-
-                return new CopyCmdAnswer(newVol);
-            }
-        } catch (final Exception e) {
-            final String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString();
-
-            s_logger.warn(msg, e);
-
-            return new CopyCmdAnswer(msg);
-        }
-        finally {
-            if (removeSrAfterCopy && sr != null) {
-                hypervisorResource.removeSR(conn, sr);
-            }
-        }
-
-        return new CopyCmdAnswer("not implemented yet");
-    }
-
-    @Override
-    public Answer createVolume(final CreateObjectCommand cmd) {
-        final DataTO data = cmd.getData();
-        final VolumeObjectTO volume = (VolumeObjectTO) data;
-
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-            final SR poolSr = hypervisorResource.getStorageRepository(conn, data.getDataStore().getUuid());
-            VDI.Record vdir = new VDI.Record();
-            vdir.nameLabel = volume.getName();
-            vdir.SR = poolSr;
-            vdir.type = Types.VdiType.USER;
-
-            vdir.virtualSize = volume.getSize();
-            VDI vdi;
-
-            vdi = VDI.create(conn, vdir);
-            vdir = vdi.getRecord(conn);
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setName(vdir.nameLabel);
-            newVol.setSize(vdir.virtualSize);
-            newVol.setPath(vdir.uuid);
-
-            return new CreateObjectAnswer(newVol);
-        } catch (final Exception e) {
-            s_logger.debug("create volume failed: " + e.toString());
-            return new CreateObjectAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final VolumeObjectTO volume = (VolumeObjectTO) destData;
-        VDI vdi = null;
-        try {
-            VDI tmpltvdi = null;
-
-            tmpltvdi = getVDIbyUuid(conn, srcData.getPath());
-            vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
-            Long virtualSize  = vdi.getVirtualSize(conn);
-            if (volume.getSize() > virtualSize) {
-                s_logger.debug("Overriding provided template's size with new size " + volume.getSize() + " for volume: " + volume.getName());
-                vdi.resize(conn, volume.getSize());
-            } else {
-                s_logger.debug("Using templates disk size of " + virtualSize + " for volume: " + volume.getName() + " since size passed was " + volume.getSize());
-            }
-            vdi.setNameLabel(conn, volume.getName());
-
-            VDI.Record vdir;
-            vdir = vdi.getRecord(conn);
-            s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid);
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setName(vdir.nameLabel);
-            newVol.setSize(vdir.virtualSize);
-            newVol.setPath(vdir.uuid);
-
-            return new CopyCmdAnswer(newVol);
-        } catch (final Exception e) {
-            s_logger.warn("Unable to create volume; Pool=" + destData + "; Disk: ", e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    @Override
-    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final VolumeObjectTO srcVolume = (VolumeObjectTO) srcData;
-        final VolumeObjectTO destVolume = (VolumeObjectTO) destData;
-        final DataStoreTO srcStore = srcVolume.getDataStore();
-
-        if (srcStore instanceof NfsTO) {
-            final NfsTO nfsStore = (NfsTO) srcStore;
-            try {
-                final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, destVolume.getDataStore().getUuid());
-                final String srUuid = primaryStoragePool.getUuid(conn);
-                final URI uri = new URI(nfsStore.getUrl());
-                final String volumePath = uri.getHost() + ":" + uri.getPath() + nfsStore.getPathSeparator() + srcVolume.getPath();
-                final String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait);
-                final VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(uuid);
-                newVol.setSize(srcVolume.getSize());
-
-                return new CopyCmdAnswer(newVol);
-            } catch (final Exception e) {
-                final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
-                s_logger.warn(msg, e);
-                return new CopyCmdAnswer(e.toString());
-            }
-        }
-
-        s_logger.debug("unsupported protocol");
-        return new CopyCmdAnswer("unsupported protocol");
-    }
-
-    @Override
-    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO();
-        final VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final DataStoreTO destStore = destVolume.getDataStore();
-
-        if (destStore instanceof NfsTO) {
-            SR secondaryStorage = null;
-            try {
-                final NfsTO nfsStore = (NfsTO) destStore;
-                final URI uri = new URI(nfsStore.getUrl());
-                // Create the volume folder
-                if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
-                    throw new InternalErrorException("Failed to create the volume folder.");
-                }
-
-                // Create a SR for the volume UUID folder
-                secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + nfsStore.getPathSeparator() + destVolume.getPath()), false);
-                // Look up the volume on the source primary storage pool
-                final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
-                // Copy the volume to secondary storage
-                final VDI destVdi = hypervisorResource.cloudVDIcopy(conn, srcVdi, secondaryStorage, wait);
-                final String destVolumeUUID = destVdi.getUuid(conn);
-
-                final VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(destVolume.getPath() + nfsStore.getPathSeparator() + destVolumeUUID + ".vhd");
-                newVol.setSize(srcVolume.getSize());
-                return new CopyCmdAnswer(newVol);
-            } catch (final Exception e) {
-                s_logger.debug("Failed to copy volume to secondary: " + e.toString());
-                return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString());
-            } finally {
-                hypervisorResource.removeSR(conn, secondaryStorage);
-            }
-        }
-        return new CopyCmdAnswer("unsupported protocol");
-    }
-
-    private boolean swiftUpload(final Connection conn, final SwiftTO swift, final String container, final String ldir, final String lfilename, final Boolean isISCSI,
-            final int wait) {
-
-        List<String> params = getSwiftParams(swift, container, ldir, lfilename, isISCSI);
-
-        try {
-            String result = hypervisorResource.callHostPluginAsync(conn, "swiftxenserver", "swift", wait, params.toArray(new String[params.size()]));
-            return BooleanUtils.toBoolean(result);
-        } catch (final Exception e) {
-            s_logger.warn("swift upload failed due to " + e.toString(), e);
-        }
-        return false;
-    }
-
-    @VisibleForTesting
-    List<String> getSwiftParams(SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI) {
-        // ORDER IS IMPORTANT
-        List<String> params = new ArrayList<>();
-
-        //operation
-        params.add("op");
-        params.add("upload");
-
-        //auth
-        params.add("url");
-        params.add(swift.getUrl());
-        params.add("account");
-        params.add(swift.getAccount());
-        params.add("username");
-        params.add(swift.getUserName());
-        params.add("key");
-        params.add(swift.getKey());
-
-        // object info
-        params.add("container");
-        params.add(container);
-        params.add("ldir");
-        params.add(ldir);
-        params.add("lfilename");
-        params.add(lfilename);
-        params.add("isISCSI");
-        params.add(isISCSI.toString());
-
-        if (swift.getStoragePolicy() != null) {
-            params.add("storagepolicy");
-            params.add(swift.getStoragePolicy());
-        }
-
-        return params;
-    }
-
-    protected String deleteSnapshotBackup(final Connection conn, final String localMountPoint, final String path, final String secondaryStorageMountPath, final String backupUUID) {
-
-        // If anybody modifies the formatting below again, I'll skin them
-        final String result =
-                hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath",
-                        secondaryStorageMountPath, "localMountPoint", localMountPoint);
-
-        return result;
-    }
-
-    protected String swiftBackupSnapshot(final Connection conn, final SwiftTO swift, final String srUuid, final String snapshotUuid, final String container, final Boolean isISCSI,
-            final int wait) {
-        String lfilename;
-        String ldir;
-        if (isISCSI) {
-            ldir = "/dev/VG_XenStorage-" + srUuid;
-            lfilename = "VHD-" + snapshotUuid;
-        } else {
-            ldir = "/var/run/sr-mount/" + srUuid;
-            lfilename = snapshotUuid + ".vhd";
-        }
-        swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait);
-        return lfilename;
-    }
-
-    protected String backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String folder, final String snapshotUuid,
-            final Boolean iSCSIFlag, final int wait) {
-
-        final String filename = iSCSIFlag ? "VHD-" + snapshotUuid : snapshotUuid + ".vhd";
-        final String dir = (iSCSIFlag ? "/dev/VG_XenStorage-" : "/var/run/sr-mount/") + srUuid;
-        final String key = folder + "/" + filename; // String.format("/snapshots/%1$s", snapshotUuid);
-
-        try {
-
-            final List<String> parameters = newArrayList(flattenProperties(s3, ClientOptions.class));
-            // https workaround for Introspector bug that does not
-            // recognize Boolean accessor methods ...
-
-            parameters.addAll(Arrays.asList("operation", "put", "filename", dir + "/" + filename, "iSCSIFlag", iSCSIFlag.toString(), "bucket", s3.getBucketName(), "key",
-                    key, "https", s3.isHttps() != null ? s3.isHttps().toString() : "null", "maxSingleUploadSizeInBytes", String.valueOf(s3.getMaxSingleUploadSizeInBytes())));
-            final String result = hypervisorResource.callHostPluginAsync(connection, "s3xenserver", "s3", wait, parameters.toArray(new String[parameters.size()]));
-
-            if (result != null && result.equals("true")) {
-                return key;
-            }
-            return null;
-
-        } catch (final Exception e) {
-            s_logger.error(String.format("S3 upload failed of snapshot %1$s due to %2$s.", snapshotUuid, e.toString()), e);
-        }
-
-        return null;
-
-    }
-
-    private Long getSnapshotSize(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI, final int wait) {
-        final String physicalSize = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "getSnapshotSize", wait,
-                "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString());
-        if (physicalSize == null || physicalSize.isEmpty()) {
-            return (long) 0;
-        } else {
-            return Long.parseLong(physicalSize);
-        }
-    }
-
-    private String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, final String secondaryStorageMountPath,
-            final String snapshotUuid, String prevBackupUuid, final Boolean isISCSI, final int wait) {
-        String backupSnapshotUuid = null;
-
-        if (prevBackupUuid == null) {
-            prevBackupUuid = "";
-        }
-
-        // Each argument is put in a separate line for readability.
-        // Using more lines does not harm the environment.
-        final String backupUuid = UUID.randomUUID().toString();
-        final String results =
-                hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait, "primaryStorageSRUuid", primaryStorageSRUuid, "path", path,
-                        "secondaryStorageMountPath", secondaryStorageMountPath, "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid,
-                        "isISCSI", isISCSI.toString(), "localMountPoint", localMountPoint);
-        String errMsg = null;
-        if (results == null || results.isEmpty()) {
-            errMsg =
-                    "Could not copy backupUuid: " + backupSnapshotUuid + " from primary storage " + primaryStorageSRUuid + " to secondary storage " +
-                            secondaryStorageMountPath + " due to null";
-        } else {
-
-            final String[] tmp = results.split("#");
-            final String status = tmp[0];
-            backupSnapshotUuid = tmp[1];
-            // status == "1" if and only if backupSnapshotUuid != null
-            // So we don't rely on status value but return backupSnapshotUuid as an
-            // indicator of success.
-            if (status != null && status.equalsIgnoreCase("1") && backupSnapshotUuid != null) {
-                s_logger.debug("Successfully copied backupUuid: " + backupSnapshotUuid + " to secondary storage");
-                return results;
-            } else {
-                errMsg =
-                        "Could not copy backupUuid: " + backupSnapshotUuid + " from primary storage " + primaryStorageSRUuid + " to secondary storage " +
-                                secondaryStorageMountPath + " due to " + tmp[1];
-            }
-        }
-        final String source = backupUuid + ".vhd";
-        hypervisorResource.killCopyProcess(conn, source);
-        s_logger.warn(errMsg);
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    protected boolean destroySnapshotOnPrimaryStorageExceptThis(final Connection conn, final String volumeUuid, final String avoidSnapshotUuid) {
-        try {
-            final VDI volume = getVDIbyUuid(conn, volumeUuid);
-            if (volume == null) {
-                throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it");
-            }
-            // To avoid deleting snapshots which are still waiting in queue to get backed up.
-            VDI avoidSnapshot = getVDIbyUuid(conn, avoidSnapshotUuid);
-            if (avoidSnapshot == null) {
-                throw new InternalErrorException("Could not find current snapshot " + avoidSnapshotUuid);
-            }
-            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)) && snapshot.getVBDs(conn).isEmpty()) {
-                        snapshot.destroy(conn);
-                    }
-                } catch (final Exception e) {
-                    final String msg = "Destroying snapshot: " + snapshot + " on primary storage failed due to " + e.toString();
-                    s_logger.warn(msg, e);
-                }
-            }
-            s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid);
-            return true;
-        } catch (final XenAPIException e) {
-            final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-        } catch (final Exception e) {
-            final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString();
-            s_logger.warn(msg, e);
-        }
-
-        return false;
-    }
-
-    protected boolean destroySnapshotOnPrimaryStorage(final Connection conn, final String lastSnapshotUuid) {
-        try {
-            final VDI snapshot = getVDIbyUuid(conn, lastSnapshotUuid);
-            if (snapshot == null) {
-                // since this is just used to cleanup leftover bad snapshots, no need to throw exception
-                s_logger.warn("Could not destroy snapshot " + lastSnapshotUuid + " due to can not find it");
-                return false;
-            }
-            snapshot.destroy(conn);
-            return true;
-        } catch (final XenAPIException e) {
-            final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-        } catch (final Exception e) {
-            final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString();
-            s_logger.warn(msg, e);
-        }
-        return false;
-    }
-
-    @Override
-    public Answer backupSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO cacheData = cmd.getCacheTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final String primaryStorageNameLabel = srcData.getDataStore().getUuid();
-        String secondaryStorageUrl = null;
-        NfsTO cacheStore = null;
-        String destPath = null;
-        if (cacheData != null) {
-            cacheStore = (NfsTO) cacheData.getDataStore();
-            secondaryStorageUrl = cacheStore.getUrl();
-            destPath = cacheData.getPath();
-        } else {
-            cacheStore = (NfsTO) destData.getDataStore();
-            secondaryStorageUrl = cacheStore.getUrl();
-            destPath = destData.getPath();
-        }
-
-        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData;
-        final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData;
-        final String snapshotUuid = snapshotTO.getPath();
-        final String volumeUuid = snapshotTO.getVolume().getPath();
-
-        final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
-        final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
-
-        // By default assume failure
-        String details = null;
-        String snapshotBackupUuid = null;
-        Long physicalSize = null;
-        final Map<String, String> options = cmd.getOptions();
-        boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
-        boolean result = false;
-        try {
-            final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " +
-                        primaryStorageNameLabel);
-            }
-            final String psUuid = primaryStorageSR.getUuid(conn);
-            final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
-
-            final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
-            String snapshotPaUuid = null;
-
-            if (prevSnapshotUuid != null && !fullbackup) {
-                try {
-                    snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI);
-                    if (snapshotPaUuid != null) {
-                        final String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI);
-                        final String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI);
-                        if (snashotPaPaPaUuid != null && prevSnashotPaUuid != null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) {
-                            fullbackup = false;
-                        } else {
-                            fullbackup = true;
-                        }
-                    }
-                } catch (final Exception e) {
-                    s_logger.debug("Failed to get parent snapshots, take full snapshot", e);
-                    fullbackup = true;
-                }
-            }
-
-            final URI uri = new URI(secondaryStorageUrl);
-            final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            final DataStoreTO destStore = destData.getDataStore();
-            final String folder = destPath;
-            String finalPath = null;
-
-            final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
-            if (fullbackup) {
-                // the first snapshot is always a full snapshot
-
-                if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) {
-                    details = " Filed to create folder " + folder + " in secondary storage";
-                    s_logger.warn(details);
-                    return new CopyCmdAnswer(details);
-                }
-                final String snapshotMountpoint = secondaryStorageUrl + "/" + folder;
-                SR snapshotSr = null;
-                try {
-                    snapshotSr = hypervisorResource.createNfsSRbyURI(conn, new URI(snapshotMountpoint), false);
-                    final VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait);
-                    snapshotBackupUuid = backedVdi.getUuid(conn);
-                    final String primarySRuuid = snapshotSr.getUuid(conn);
-                    physicalSize = getSnapshotSize(conn, primarySRuuid, snapshotBackupUuid, isISCSI, wait);
-
-                    if (destStore instanceof SwiftTO) {
-                        try {
-                            final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
-                            final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
-                            final String swiftPath = container + File.separator + destSnapshotName;
-                            finalPath = swiftPath;
-                        } finally {
-                            try {
-                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
-                            } catch (final Exception e) {
-                                s_logger.debug("Failed to delete snapshot on cache storages", e);
-                            }
-                        }
-
-                    } else if (destStore instanceof S3TO) {
-                        try {
-                            finalPath = backupSnapshotToS3(conn, (S3TO) destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
-                            if (finalPath == null) {
-                                throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
-                            }
-                        } finally {
-                            try {
-                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
-                            } catch (final Exception e) {
-                                s_logger.debug("Failed to delete snapshot on cache storages", e);
-                            }
-                        }
-                        // finalPath = folder + File.separator + snapshotBackupUuid;
-                    } else {
-                        finalPath = folder + cacheStore.getPathSeparator() + snapshotBackupUuid;
-                    }
-
-                } finally {
-                    if (snapshotSr != null) {
-                        hypervisorResource.removeSR(conn, snapshotSr);
-                    }
-                }
-            } else {
-                final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
-                if (destStore instanceof SwiftTO) {
-                    final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
-                    snapshotBackupUuid =
-                            swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(),
-                                    isISCSI, wait);
-                    finalPath = container + File.separator + snapshotBackupUuid;
-                } else if (destStore instanceof S3TO) {
-                    finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
-                    if (finalPath == null) {
-                        throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
-                    }
-                } else {
-                    final String results =
-                            backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait);
-
-                    final String[] tmp = results.split("#");
-                    snapshotBackupUuid = tmp[1];
-                    physicalSize = Long.parseLong(tmp[2]);
-                    finalPath = folder + cacheStore.getPathSeparator() + snapshotBackupUuid;
-                }
-            }
-            // delete primary snapshots with only the last one left
-            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
-
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            newSnapshot.setPath(finalPath);
-            newSnapshot.setPhysicalSize(physicalSize);
-            if (fullbackup) {
-                newSnapshot.setParentSnapshotPath(null);
-            } else {
-                newSnapshot.setParentSnapshotPath(prevBackupUuid);
-            }
-            result = true;
-            return new CopyCmdAnswer(newSnapshot);
-        } catch (final XenAPIException e) {
-            details = "BackupSnapshot Failed due to " + e.toString();
-            s_logger.warn(details, e);
-        } catch (final Exception e) {
-            details = "BackupSnapshot Failed due to " + e.getMessage();
-            s_logger.warn(details, e);
-        } finally {
-            if (!result) {
-                // remove last bad primary snapshot when exception happens
-                try {
-                    destroySnapshotOnPrimaryStorage(conn, snapshotUuid);
-                } catch (final Exception e) {
-                    s_logger.debug("clean up snapshot failed", e);
-                }
-            }
-        }
-
-        return new CopyCmdAnswer(details);
-    }
-
-    @Override
-    public Answer createTemplateFromVolume(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO();
-        final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
-        final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore();
-        final int wait = cmd.getWait();
-
-        final String secondaryStoragePoolURL = destStore.getUrl();
-        final String volumeUUID = volume.getPath();
-
-        final String userSpecifiedName = template.getName();
-
-        String details = null;
-        SR tmpltSR = null;
-        boolean result = false;
-        String secondaryStorageMountPath = null;
-        String installPath = null;
-        try {
-            final URI uri = new URI(secondaryStoragePoolURL);
-            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            installPath = template.getPath();
-            if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
-                details = " Filed to create folder " + installPath + " in secondary storage";
-                s_logger.warn(details);
-                return new CopyCmdAnswer(details);
-            }
-
-            final VDI vol = getVDIbyUuid(conn, volumeUUID);
-            // create template SR
-            final URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath);
-            tmpltSR = hypervisorResource.createNfsSRbyURI(conn, tmpltURI, false);
-
-            // copy volume to template SR
-            final VDI tmpltVDI = hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait);
-            // scan makes XenServer pick up VDI physicalSize
-            tmpltSR.scan(conn);
-            if (userSpecifiedName != null) {
-                tmpltVDI.setNameLabel(conn, userSpecifiedName);
-            }
-
-            final String tmpltUUID = tmpltVDI.getUuid(conn);
-            final String tmpltFilename = tmpltUUID + ".vhd";
-            final long virtualSize = tmpltVDI.getVirtualSize(conn);
-            final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
-            // create the template.properties file
-            final String templatePath = secondaryStorageMountPath + "/" + installPath;
-            result =
-                    hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize,
-                            template.getId());
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI);
-            }
-            installPath = installPath + "/" + tmpltFilename;
-            hypervisorResource.removeSR(conn, tmpltSR);
-            tmpltSR = null;
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(installPath);
-            newTemplate.setFormat(ImageFormat.VHD);
-            newTemplate.setSize(virtualSize);
-            newTemplate.setPhysicalSize(physicalSize);
-            newTemplate.setName(tmpltUUID);
-            final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
-            return answer;
-        } catch (final Exception e) {
-            if (tmpltSR != null) {
-                hypervisorResource.removeSR(conn, tmpltSR);
-            }
-            if (secondaryStorageMountPath != null) {
-                hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
-            }
-            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
-            s_logger.error(details, e);
-        }
-        return new CopyCmdAnswer(details);
-    }
-
-    @Override
-    public Answer createTemplateFromSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-
-        final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO();
-        final TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO();
-
-        if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) {
-            return null;
-        }
-
-        final String userSpecifiedTemplateName = templateObjTO.getName();
-
-        NfsTO destStore = null;
-        URI destUri = null;
-
-        try {
-            destStore = (NfsTO)templateObjTO.getDataStore();
-
-            destUri = new URI(destStore.getUrl());
-        } catch (final Exception ex) {
-            s_logger.debug("Invalid URI", ex);
-
-            return new CopyCmdAnswer("Invalid URI: " + ex.toString());
-        }
-
-        SR srcSr = null;
-        SR destSr = null;
-
-        final String destDir = templateObjTO.getPath();
-        VDI destVdi = null;
-
-        boolean result = false;
-
-        try {
-            final Map<String, String> srcDetails = cmd.getOptions();
-
-            final String iScsiName = srcDetails.get(DiskTO.IQN);
-            final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
-            final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-            srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true);
-
-            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
-
-            if (!hypervisorResource.createSecondaryStorageFolder(conn, destNfsPath, destDir)) {
-                final String details = " Failed to create folder " + destDir + " in secondary storage";
-
-                s_logger.warn(details);
-
-                return new CopyCmdAnswer(details);
-            }
-
-            final URI templateUri = new URI(destStore.getUrl() + "/" + destDir);
-
-            destSr = hypervisorResource.createNfsSRbyURI(conn, templateUri, false);
-
-            // there should only be one VDI in this SR
-            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
-
-            destVdi = srcVdi.copy(conn, destSr);
-
-            // scan makes XenServer pick up VDI physicalSize
-            destSr.scan(conn);
-
-            if (userSpecifiedTemplateName != null) {
-                destVdi.setNameLabel(conn, userSpecifiedTemplateName);
-            }
-
-            final String templateUuid = destVdi.getUuid(conn);
-            final String templateFilename = templateUuid + ".vhd";
-            final long virtualSize = destVdi.getVirtualSize(conn);
-            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
-
-            // create the template.properties file
-            String templatePath = destNfsPath + "/" + destDir;
-
-            templatePath = templatePath.replaceAll("//", "/");
-
-            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, userSpecifiedTemplateName, null,
-                    physicalSize, virtualSize, templateObjTO.getId());
-
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri);
-            }
-
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(destDir + "/" + templateFilename);
-            newTemplate.setFormat(Storage.ImageFormat.VHD);
-            newTemplate.setHypervisorType(HypervisorType.XenServer);
-            newTemplate.setSize(virtualSize);
-            newTemplate.setPhysicalSize(physicalSize);
-            newTemplate.setName(templateUuid);
-
-            result = true;
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (final Exception ex) {
-            s_logger.error("Failed to create a template from a snapshot", ex);
-
-            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + ex.toString());
-        } finally {
-            if (!result) {
-                if (destVdi != null) {
-                    try {
-                        destVdi.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e);
-                    }
-                }
-            }
-
-            if (srcSr != null) {
-                hypervisorResource.removeSR(conn, srcSr);
-            }
-
-            if (destSr != null) {
-                hypervisorResource.removeSR(conn, destSr);
-            }
-        }
-    }
-
-    @Override
-    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
-        final DataTO destData = cmd.getDestTO();
-        final DataStoreTO imageStore = srcData.getDataStore();
-
-        if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof PrimaryDataStoreTO) {
-            return createVolumeFromSnapshot2(cmd);
-        }
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        final NfsTO nfsImageStore = (NfsTO) imageStore;
-        final String primaryStorageNameLabel = destData.getDataStore().getUuid();
-        final String secondaryStorageUrl = nfsImageStore.getUrl();
-        final int wait = cmd.getWait();
-        boolean result = false;
-        // Generic error message.
-        String details = null;
-        String volumeUUID = null;
-
-        if (secondaryStorageUrl == null) {
-            details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
-            return new CopyCmdAnswer(details);
-        }
-        try {
-            final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " +
-                        primaryStorageNameLabel);
-            }
-            // Get the absolute path of the snapshot on the secondary storage.
-            String snapshotInstallPath = snapshot.getPath();
-            final int index = snapshotInstallPath.lastIndexOf(nfsImageStore.getPathSeparator());
-            final String snapshotName = snapshotInstallPath.substring(index + 1);
-
-            if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
-                snapshotInstallPath = snapshotInstallPath + ".vhd";
-            }
-            final URI snapshotURI = new URI(secondaryStorageUrl + nfsImageStore.getPathSeparator() + snapshotInstallPath);
-            final String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath();
-            final String srUuid = primaryStorageSR.getUuid(conn);
-            volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait);
-            result = true;
-            final VDI volume = VDI.getByUuid(conn, volumeUUID);
-            final VDI.Record vdir = volume.getRecord(conn);
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(volumeUUID);
-            newVol.setSize(vdir.virtualSize);
-            return new CopyCmdAnswer(newVol);
-        } catch (final XenAPIException e) {
-            details += " due to " + e.toString();
-            s_logger.warn(details, e);
-        } catch (final Exception e) {
-            details += " due to " + e.getMessage();
-            s_logger.warn(details, e);
-        }
-        if (!result) {
-            // Is this logged at a higher level?
-            s_logger.error(details);
-        }
-
-        // In all cases return something.
-        return new CopyCmdAnswer(details);
-    }
-
-    protected Answer createVolumeFromSnapshot2(final CopyCommand cmd) {
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-
-            final Map<String, String> srcOptions = cmd.getOptions();
-
-            final String src_iScsiName = srcOptions.get(DiskTO.IQN);
-            final String srcStorageHost = srcOptions.get(DiskTO.STORAGE_HOST);
-            final String srcChapInitiatorUsername = srcOptions.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String srcChapInitiatorSecret = srcOptions.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-            final SR srcSr = hypervisorResource.getIscsiSR(conn, src_iScsiName, srcStorageHost, src_iScsiName, srcChapInitiatorUsername, srcChapInitiatorSecret, false);
-
-            final Map<String, String> destOptions = cmd.getOptions2();
-
-            final String dest_iScsiName = destOptions.get(DiskTO.IQN);
-            final String destStorageHost = destOptions.get(DiskTO.STORAGE_HOST);
-            final String destChapInitiatorUsername = destOptions.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String destChapInitiatorSecret = destOptions.get(DiskTO.CHAP_INITIATOR_SECRET);
-
-            final SR destSr = hypervisorResource.getIscsiSR(conn, dest_iScsiName, destStorageHost, dest_iScsiName, destChapInitiatorUsername, destChapInitiatorSecret, false);
-
-            // there should only be one VDI in this SR
-            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
-
-            final VDI vdiCopy = srcVdi.copy(conn, destSr);
-
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-
-            newVol.setSize(vdiCopy.getVirtualSize(conn));
-            newVol.setPath(vdiCopy.getUuid(conn));
-            newVol.setFormat(ImageFormat.VHD);
-
-            hypervisorResource.removeSR(conn, srcSr);
-            hypervisorResource.removeSR(conn, destSr);
-
-            return new CopyCmdAnswer(newVol);
-        }
-        catch (final Exception ex) {
-            s_logger.warn("Failed to copy snapshot to volume: " + ex.toString(), ex);
-
-            return new CopyCmdAnswer(ex.getMessage());
-        }
-    }
-
-    @Override
-    public Answer deleteSnapshot(final DeleteCommand cmd) {
-        final SnapshotObjectTO snapshot = (SnapshotObjectTO) cmd.getData();
-        final DataStoreTO store = snapshot.getDataStore();
-        if (store.getRole() == DataStoreRole.Primary) {
-            final Connection conn = hypervisorResource.getConnection();
-            final VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath());
-            if (snapshotVdi == null) {
-                return new Answer(null);
-            }
-            String errMsg = null;
-            try {
-                deleteVDI(conn, snapshotVdi);
-            } catch (final BadServerResponse e) {
-                s_logger.debug("delete snapshot failed:" + e.toString());
-                errMsg = e.toString();
-            } catch (final XenAPIException e) {
-                s_logger.debug("delete snapshot failed:" + e.toString());
-                errMsg = e.toString();
-            } catch (final XmlRpcException e) {
-                s_logger.debug("delete snapshot failed:" + e.toString());
-                errMsg = e.toString();
-            }
-            return new Answer(cmd, false, errMsg);
-        }
-        return new Answer(cmd, false, "unsupported storage type");
-    }
-
-    @Override
-    public Answer introduceObject(final IntroduceObjectCmd cmd) {
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-            final DataStoreTO store = cmd.getDataTO().getDataStore();
-            final SR poolSr = hypervisorResource.getStorageRepository(conn, store.getUuid());
-            poolSr.scan(conn);
-            return new IntroduceObjectAnswer(cmd.getDataTO());
-        } catch (final Exception e) {
-            s_logger.debug("Failed to introduce object", e);
-            return new Answer(cmd, false, e.toString());
-        }
-    }
-
-    @Override
-    public Answer forgetObject(final ForgetObjectCmd cmd) {
-        try {
-            final Connection conn = hypervisorResource.getConnection();
-            final DataTO data = cmd.getDataTO();
-            final VDI vdi = VDI.getByUuid(conn, data.getPath());
-            vdi.forget(conn);
-            return new IntroduceObjectAnswer(cmd.getDataTO());
-        } catch (final Exception e) {
-            s_logger.debug("Failed to introduce object", e);
-            return new Answer(cmd, false, e.toString());
-        }
-    }
-}
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
deleted file mode 100644
index dea1752..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.hypervisor.xenserver.resource;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.PBD;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Task;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.Types.BadServerResponse;
-import com.xensource.xenapi.Types.XenAPIException;
-import com.xensource.xenapi.VDI;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.apache.xmlrpc.XmlRpcException;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
-    private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
-
-    public Xenserver625StorageProcessor(final CitrixResourceBase resource) {
-        super(resource);
-    }
-
-    protected boolean mountNfs(final Connection conn, final String remoteDir, String localDir) {
-        if (localDir == null) {
-            localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remoteDir.getBytes());
-        }
-
-        final String results = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir",
-                remoteDir);
-
-        if (results == null || results.isEmpty()) {
-            final String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir;
-
-            s_logger.warn(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        return true;
-    }
-
-    protected boolean makeDirectory(final Connection conn, final String path) {
-        final String result = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "makeDirectory", "path", path);
-
-        if (result == null || result.isEmpty()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    protected SR createFileSR(final Connection conn, final String path) {
-        SR sr = null;
-        PBD pbd = null;
-
-        try {
-            final String srname = path.trim();
-            synchronized (srname.intern()) {
-                final Set<SR> srs = SR.getByNameLabel(conn, srname);
-                if (srs != null && !srs.isEmpty()) {
-                    return srs.iterator().next();
-                }
-                final Map<String, String> smConfig = new HashMap<String, String>();
-                final Host host = Host.getByUuid(conn, hypervisorResource.getHost().getUuid());
-                final String uuid = UUID.randomUUID().toString();
-                sr = SR.introduce(conn, uuid, srname, srname, "file", "file", false, smConfig);
-                final PBD.Record record = new PBD.Record();
-                record.host = host;
-                record.SR = sr;
-                smConfig.put("location", path);
-                record.deviceConfig = smConfig;
-                pbd = PBD.create(conn, record);
-                pbd.plug(conn);
-                sr.scan(conn);
-            }
-            return sr;
-        } catch (final Exception ex) {
-            try {
-                if (pbd != null) {
-                    pbd.destroy(conn);
-                }
-            } catch (final Exception e1) {
-                s_logger.debug("Failed to destroy PBD", ex);
-            }
-
-            try {
-                if (sr != null) {
-                    sr.forget(conn);
-                }
-            } catch (final Exception e2) {
-                s_logger.error("Failed to forget SR", ex);
-            }
-
-            final String msg = "createFileSR failed! due to the following: " + ex.toString();
-
-            s_logger.warn(msg, ex);
-
-            throw new CloudRuntimeException(msg, ex);
-        }
-    }
-
-    protected SR createFileSr(final Connection conn, final String remotePath, final String dir) {
-        final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remotePath.getBytes());
-        mountNfs(conn, remotePath, localDir);
-        final SR sr = createFileSR(conn, localDir + "/" + dir);
-        return sr;
-    }
-
-    @Override
-    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final DataStoreTO srcStore = srcData.getDataStore();
-        final Connection conn = hypervisorResource.getConnection();
-        SR srcSr = null;
-        SR destSr = null;
-        boolean removeSrAfterCopy = false;
-        Task task = null;
-
-        try {
-            if (srcStore instanceof NfsTO && srcData.getObjectType() == DataObjectType.TEMPLATE) {
-                final NfsTO srcImageStore = (NfsTO) srcStore;
-                final TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData;
-                final String storeUrl = srcImageStore.getUrl();
-                final URI uri = new URI(storeUrl);
-                String volumePath = srcData.getPath();
-
-                volumePath = StringUtils.stripEnd(volumePath, "/");
-
-                final String[] splits = volumePath.split("/");
-                String volumeDirectory = volumePath;
-
-                if (splits.length > 4) {
-                    // "template/tmpl/dcid/templateId/templatename"
-                    final int index = volumePath.lastIndexOf("/");
-
-                    volumeDirectory = volumePath.substring(0, index);
-                }
-
-                srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
-
-                final Set<VDI> setVdis = srcSr.getVDIs(conn);
-
-                if (setVdis.size() != 1) {
-                    return new CopyCmdAnswer("Expected 1 VDI template, but found " + setVdis.size() + " VDI templates on: " +
-                            uri.getHost() + ":" + uri.getPath() + "/" + volumeDirectory);
-                }
-
-                final VDI srcVdi = setVdis.iterator().next();
-
-                boolean managed = false;
-                String storageHost = null;
-                String managedStoragePoolName = null;
-                String managedStoragePoolRootVolumeName = null;
-                String managedStoragePoolRootVolumeSize = null;
-                String chapInitiatorUsername = null;
-                String chapInitiatorSecret = null;
-
-                final PrimaryDataStoreTO destStore = (PrimaryDataStoreTO) destData.getDataStore();
-
-                Map<String, String> details = destStore.getDetails();
-
-                if (details != null) {
-                    managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
-
-                    if (managed) {
-                        storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
-                        managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
-                        managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
-                        managedStoragePoolRootVolumeSize = details.get(PrimaryDataStoreTO.VOLUME_SIZE);
-                        chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
-                        chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
-                        removeSrAfterCopy = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.REMOVE_AFTER_COPY));
-                    }
-                }
-
-                if (managed) {
-                    details = new HashMap<String, String>();
-
-                    details.put(DiskTO.STORAGE_HOST, storageHost);
-                    details.put(DiskTO.IQN, managedStoragePoolName);
-                    details.put(DiskTO.VOLUME_SIZE, managedStoragePoolRootVolumeSize);
-                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInitiatorUsername);
-                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInitiatorSecret);
-
-                    destSr = hypervisorResource.prepareManagedSr(conn, details);
-                } else {
-                    final String srName = destStore.getUuid();
-                    final Set<SR> srs = SR.getByNameLabel(conn, srName);
-
-                    if (srs.size() != 1) {
-                        final String msg = "There are " + srs.size() + " SRs with same name: " + srName;
-
-                        s_logger.warn(msg);
-
-                        return new CopyCmdAnswer(msg);
-                    } else {
-                        destSr = srs.iterator().next();
-                    }
-                }
-
-                task = srcVdi.copyAsync(conn, destSr, null, null);
-
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-
-                final VDI tmplVdi = Types.toVDI(task, conn);
-
-                final String uuidToReturn;
-                final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn);
-
-                if (managed) {
-                    uuidToReturn = tmplVdi.getUuid(conn);
-
-                    tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName);
-                } else {
-                    final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap<String, String>());
-
-                    uuidToReturn = snapshotVdi.getUuid(conn);
-
-                    snapshotVdi.setNameLabel(conn, "Template " + srcTemplate.getName());
-
-                    tmplVdi.destroy(conn);
-                }
-
-                destSr.scan(conn);
-
-                try {
-                    Thread.sleep(5000);
-                } catch (final Exception e) {
-                }
-
-                final TemplateObjectTO newVol = new TemplateObjectTO();
-
-                newVol.setUuid(uuidToReturn);
-                newVol.setPath(uuidToReturn);
-
-                if (physicalSize != null) {
-                    newVol.setSize(physicalSize);
-                }
-
-                newVol.setFormat(Storage.ImageFormat.VHD);
-
-                return new CopyCmdAnswer(newVol);
-            }
-        } catch (final Exception e) {
-            final String msg = "Catch Exception " + e.getClass().getName() + " for template due to " + e.toString();
-
-            s_logger.warn(msg, e);
-
-            return new CopyCmdAnswer(msg);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.debug("unable to destroy task (" + task.toWireString() + ") due to " + e.toString());
-                }
-            }
-
-            if (srcSr != null) {
-                hypervisorResource.removeSR(conn, srcSr);
-            }
-
-            if (removeSrAfterCopy && destSr != null) {
-                hypervisorResource.removeSR(conn, destSr);
-            }
-        }
-
-        return new CopyCmdAnswer("not implemented yet");
-    }
-
-    protected String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path,
-            final String secondaryStorageMountPath, final String snapshotUuid, String prevBackupUuid, final String prevSnapshotUuid, final Boolean isISCSI, int wait) {
-        boolean filesrcreated = false;
-        // boolean copied = false;
-
-        if (prevBackupUuid == null) {
-            prevBackupUuid = "";
-        }
-        SR ssSR = null;
-
-        final String remoteDir = secondaryStorageMountPath;
-        try {
-            ssSR = createFileSr(conn, remoteDir, path);
-            filesrcreated = true;
-
-            final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid);
-            if (wait == 0) {
-                wait = 2 * 60 * 60;
-            }
-            VDI dvdi = null;
-            Task task = null;
-            try {
-                VDI previousSnapshotVdi = null;
-                if (prevSnapshotUuid != null) {
-                    previousSnapshotVdi = VDI.getByUuid(conn, prevSnapshotUuid);
-                }
-                task = snapshotvdi.copyAsync(conn, ssSR, previousSnapshotVdi, null);
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-                dvdi = Types.toVDI(task, conn);
-                ssSR.scan(conn);
-                // copied = true;
-            } finally {
-                if (task != null) {
-                    try {
-                        task.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
-                    }
-                }
-            }
-            final String result = dvdi.getUuid(conn).concat("#").concat(dvdi.getPhysicalUtilisation(conn).toString());
-            return result;
-        } catch (final Exception e) {
-            final String msg = "Exception in backupsnapshot stage due to " + e.toString();
-            s_logger.debug(msg);
-            throw new CloudRuntimeException(msg, e);
-        } finally {
-            try {
-                if (filesrcreated && ssSR != null) {
-                    hypervisorResource.removeSR(conn, ssSR);
-                }
-            } catch (final Exception e) {
-                s_logger.debug("Exception in backupsnapshot cleanup stage due to " + e.toString());
-            }
-        }
-    }
-
-    @Override
-    protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
-        final String parentUuid = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid",
-                snapshotUuid, "isISCSI", isISCSI.toString());
-
-        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
-            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
-            // errString is already logged.
-            return null;
-        }
-        return parentUuid;
-    }
-
-    @Override
-    public Answer backupSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO cacheData = cmd.getCacheTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) srcData.getDataStore();
-        final String primaryStorageNameLabel = primaryStore.getUuid();
-        String secondaryStorageUrl = null;
-        NfsTO cacheStore = null;
-        String destPath = null;
-        if (cacheData != null) {
-            cacheStore = (NfsTO) cacheData.getDataStore();
-            secondaryStorageUrl = cacheStore.getUrl();
-            destPath = cacheData.getPath();
-        } else {
-            cacheStore = (NfsTO) destData.getDataStore();
-            secondaryStorageUrl = cacheStore.getUrl();
-            destPath = destData.getPath();
-        }
-
-        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData;
-        final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData;
-        String snapshotUuid = snapshotTO.getPath();
-
-        final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
-        final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
-        final Map<String, String> options = cmd.getOptions();
-        // By default assume failure
-        String details = null;
-        String snapshotBackupUuid = null;
-        boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
-        Long physicalSize = null;
-        try {
-
-            SR primaryStorageSR = null;
-            if (primaryStore.isManaged()) {
-                fullbackup = true; // currently, managed storage only supports full backup
-
-                final Map<String, String> srcDetails = cmd.getOptions();
-
-                final String iScsiName = srcDetails.get(DiskTO.IQN);
-                final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
-                final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-                final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-                final String srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
-
-                primaryStorageSR = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName,
-                        chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
-
-                final VDI srcVdi = primaryStorageSR.getVDIs(conn).iterator().next();
-                if (srcVdi == null) {
-                    throw new InternalErrorException("Could not Find a VDI on the SR: " + primaryStorageSR.getNameLabel(conn));
-                }
-                snapshotUuid = srcVdi.getUuid(conn);
-
-            } else {
-                primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            }
-
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
-            }
-            // String psUuid = primaryStorageSR.getUuid(conn);
-            final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
-
-            final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
-            final String snapshotPaUuid = snapshotVdi.getUuid(conn);
-
-            final URI uri = new URI(secondaryStorageUrl);
-            final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            final DataStoreTO destStore = destData.getDataStore();
-            final String folder = destPath;
-            String finalPath = null;
-
-            final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
-            if (fullbackup) {
-                SR snapshotSr = null;
-                Task task = null;
-                try {
-                    final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes());
-                    mountNfs(conn, secondaryStorageMountPath, localDir);
-                    final boolean result = makeDirectory(conn, localDir + "/" + folder);
-                    if (!result) {
-                        details = " Filed to create folder " + folder + " in secondary storage";
-                        s_logger.warn(details);
-                        return new CopyCmdAnswer(details);
-                    }
-
-                    snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder);
-
-                    task = snapshotVdi.copyAsync(conn, snapshotSr, null, null);
-                    // poll every 1 seconds ,
-                    hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                    hypervisorResource.checkForSuccess(conn, task);
-                    final VDI backedVdi = Types.toVDI(task, conn);
-                    snapshotBackupUuid = backedVdi.getUuid(conn);
-                    snapshotSr.scan(conn);
-                    physicalSize = backedVdi.getPhysicalUtilisation(conn);
-
-                    if (destStore instanceof SwiftTO) {
-                        try {
-                            final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
-                            final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
-                            final String swiftPath = container + File.separator + destSnapshotName;
-                            finalPath = swiftPath;
-                        } finally {
-                            try {
-                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
-                            } catch (final Exception e) {
-                                s_logger.debug("Failed to delete snapshot on cache storages", e);
-                            }
-                        }
-
-                    } else if (destStore instanceof S3TO) {
-                        try {
-                            finalPath = backupSnapshotToS3(conn, (S3TO) destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
-                            if (finalPath == null) {
-                                throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
-                            }
-                        } finally {
-                            try {
-                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
-                            } catch (final Exception e) {
-                                s_logger.debug("Failed to delete snapshot on cache storages", e);
-                            }
-                        }
-                        // finalPath = folder + File.separator +
-                        // snapshotBackupUuid;
-                    } else {
-                        finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
-                    }
-
-                } finally {
-                    if (task != null) {
-                        try {
-                            task.destroy(conn);
-                        } catch (final Exception e) {
-                            s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
-                        }
-                    }
-                    if (snapshotSr != null) {
-                        hypervisorResource.removeSR(conn, snapshotSr);
-                    }
-
-                    if (primaryStore.isManaged()) {
-                        hypervisorResource.removeSR(conn, primaryStorageSR);
-                    }
-                }
-            } else {
-                final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
-                if (destStore instanceof SwiftTO) {
-                    final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
-                    snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-"
-                            + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait);
-                    finalPath = container + File.separator + snapshotBackupUuid;
-                } else if (destStore instanceof S3TO) {
-                    finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
-                    if (finalPath == null) {
-                        throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
-                    }
-                } else {
-                    final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid,
-                            prevSnapshotUuid, isISCSI, wait);
-                    final String[] tmp = result.split("#");
-                    snapshotBackupUuid = tmp[0];
-                    physicalSize = Long.parseLong(tmp[1]);
-                    finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
-                }
-            }
-
-            // remove every snapshot except this one from primary storage
-            final String volumeUuid = snapshotTO.getVolume().getPath();
-            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
-
-            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-            newSnapshot.setPath(finalPath);
-            newSnapshot.setPhysicalSize(physicalSize);
-            if (fullbackup) {
-                newSnapshot.setParentSnapshotPath(null);
-            } else {
-                newSnapshot.setParentSnapshotPath(prevBackupUuid);
-            }
-            s_logger.info("New snapshot details: " + newSnapshot.toString());
-            s_logger.info("New snapshot physical utilization: "+physicalSize);
-
-            return new CopyCmdAnswer(newSnapshot);
-        } catch (final Exception e) {
-            final String reason = e instanceof Types.XenAPIException ? e.toString() : e.getMessage();
-            details = "BackupSnapshot Failed due to " + reason;
-            s_logger.warn(details, e);
-
-            // remove last bad primary snapshot when exception happens
-            destroySnapshotOnPrimaryStorage(conn, snapshotUuid);
-        }
-
-        return new CopyCmdAnswer(details);
-    }
-
-    @Override
-    public Answer createTemplateFromVolume(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO();
-        final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
-        final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore();
-        final int wait = cmd.getWait();
-
-        final String secondaryStoragePoolURL = destStore.getUrl();
-        final String volumeUUID = volume.getPath();
-
-        final String userSpecifiedName = template.getName();
-
-        String details = null;
-        SR tmpltSR = null;
-        boolean result = false;
-        String secondaryStorageMountPath = null;
-        String installPath = null;
-        Task task = null;
-        try {
-            final URI uri = new URI(secondaryStoragePoolURL);
-            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
-            installPath = template.getPath();
-            if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
-                details = " Filed to create folder " + installPath + " in secondary storage";
-                s_logger.warn(details);
-                return new CopyCmdAnswer(details);
-            }
-
-            final VDI vol = getVDIbyUuid(conn, volumeUUID);
-            // create template SR
-            tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath);
-
-            // copy volume to template SR
-            task = vol.copyAsync(conn, tmpltSR, null, null);
-            // poll every 1 seconds ,
-            hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-            hypervisorResource.checkForSuccess(conn, task);
-            final VDI tmpltVDI = Types.toVDI(task, conn);
-            // scan makes XenServer pick up VDI physicalSize
-            tmpltSR.scan(conn);
-            if (userSpecifiedName != null) {
-                tmpltVDI.setNameLabel(conn, userSpecifiedName);
-            }
-
-            final String tmpltUUID = tmpltVDI.getUuid(conn);
-            final String tmpltFilename = tmpltUUID + ".vhd";
-            final long virtualSize = tmpltVDI.getVirtualSize(conn);
-            final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
-            // create the template.properties file
-            final String templatePath = secondaryStorageMountPath + "/" + installPath;
-            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize,
-                    template.getId());
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
-            }
-            installPath = installPath + "/" + tmpltFilename;
-            hypervisorResource.removeSR(conn, tmpltSR);
-            tmpltSR = null;
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(installPath);
-            newTemplate.setFormat(Storage.ImageFormat.VHD);
-            newTemplate.setSize(virtualSize);
-            newTemplate.setPhysicalSize(physicalSize);
-            newTemplate.setName(tmpltUUID);
-            final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
-            return answer;
-        } catch (final Exception e) {
-            if (tmpltSR != null) {
-                hypervisorResource.removeSR(conn, tmpltSR);
-            }
-            if (secondaryStorageMountPath != null) {
-                hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
-            }
-            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
-            s_logger.error(details, e);
-        } finally {
-            if (task != null) {
-                try {
-                    task.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
-                }
-            }
-        }
-        return new CopyCmdAnswer(details);
-    }
-
-    protected String getSnapshotUuid(final String snapshotPath) {
-        int index = snapshotPath.lastIndexOf(File.separator);
-        String snapshotUuid = snapshotPath.substring(index + 1);
-        index = snapshotUuid.lastIndexOf(".");
-        if (index != -1) {
-            snapshotUuid = snapshotUuid.substring(0, index);
-        }
-        return snapshotUuid;
-    }
-
-    @Override
-    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
-        final DataTO destData = cmd.getDestTO();
-        final PrimaryDataStoreTO pool = (PrimaryDataStoreTO) destData.getDataStore();
-        final VolumeObjectTO volume = (VolumeObjectTO) destData;
-        final DataStoreTO imageStore = srcData.getDataStore();
-
-        if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof PrimaryDataStoreTO) {
-            return createVolumeFromSnapshot2(cmd);
-        }
-
-        if (!(imageStore instanceof NfsTO)) {
-            return new CopyCmdAnswer("unsupported protocol");
-        }
-
-        final NfsTO nfsImageStore = (NfsTO) imageStore;
-        final String primaryStorageNameLabel = pool.getUuid();
-        final String secondaryStorageUrl = nfsImageStore.getUrl();
-        final int wait = cmd.getWait();
-        boolean result = false;
-        // Generic error message.
-        String details = null;
-        String volumeUUID = null;
-
-        if (secondaryStorageUrl == null) {
-            details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
-            return new CopyCmdAnswer(details);
-        }
-        SR srcSr = null;
-        VDI destVdi = null;
-
-        SR primaryStorageSR = null;
-
-        try {
-            if (pool.isManaged()) {
-                Map<String,String> destDetails = cmd.getOptions2();
-
-                final String iScsiName = destDetails.get(DiskTO.IQN);
-                final String storageHost = destDetails.get(DiskTO.STORAGE_HOST);
-                final String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-                final String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-                final String srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
-
-                primaryStorageSR = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName,
-                        chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
-
-            } else {
-                primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
-            }
-
-            if (primaryStorageSR == null) {
-                throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: "
-                        + primaryStorageNameLabel);
-            }
-
-            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
-            destVdi = createVdi(conn, nameLabel, primaryStorageSR, volume.getSize());
-            volumeUUID = destVdi.getUuid(conn);
-            final String snapshotInstallPath = snapshot.getPath();
-            final int index = snapshotInstallPath.lastIndexOf(File.separator);
-            final String snapshotDirectory = snapshotInstallPath.substring(0, index);
-            final String snapshotUuid = getSnapshotUuid(snapshotInstallPath);
-
-            final URI uri = new URI(secondaryStorageUrl);
-            srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory);
-
-            final String[] parents = snapshot.getParents();
-            final List<VDI> snapshotChains = new ArrayList<VDI>();
-            if (parents != null) {
-                for (int i = 0; i < parents.length; i++) {
-                    final String snChainPath = parents[i];
-                    final String uuid = getSnapshotUuid(snChainPath);
-                    final VDI chain = VDI.getByUuid(conn, uuid);
-                    snapshotChains.add(chain);
-                }
-            }
-
-            final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
-            snapshotChains.add(snapshotVdi);
-
-            for (final VDI snapChain : snapshotChains) {
-                final Task task = snapChain.copyAsync(conn, null, null, destVdi);
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-                task.destroy(conn);
-            }
-
-            result = true;
-            destVdi = VDI.getByUuid(conn, volumeUUID);
-            final VDI.Record vdir = destVdi.getRecord(conn);
-            final VolumeObjectTO newVol = new VolumeObjectTO();
-            newVol.setPath(volumeUUID);
-            newVol.setSize(vdir.virtualSize);
-
-            return new CopyCmdAnswer(newVol);
-        } catch (final Types.XenAPIException e) {
-            details += " due to " + e.toString();
-            s_logger.warn(details, e);
-        } catch (final Exception e) {
-            details += " due to " + e.getMessage();
-            s_logger.warn(details, e);
-        } finally {
-            if (srcSr != null) {
-                hypervisorResource.skipOrRemoveSR(conn, srcSr);
-            }
-
-            if (pool.isManaged()) {
-                hypervisorResource.removeSR(conn, primaryStorageSR);
-            }
-
-            if (!result && destVdi != null) {
-                try {
-                    destVdi.destroy(conn);
-                } catch (final Exception e) {
-                    s_logger.debug("destroy dest vdi failed", e);
-                }
-            }
-        }
-        if (!result) {
-            // Is this logged at a higher level?
-            s_logger.error(details);
-        }
-
-        // In all cases return something.
-        return new CopyCmdAnswer(details);
-    }
-
-    @Override
-    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO();
-        final VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final DataStoreTO destStore = destVolume.getDataStore();
-
-        if (destStore instanceof NfsTO) {
-            SR secondaryStorage = null;
-            Task task = null;
-            try {
-                final NfsTO nfsStore = (NfsTO) destStore;
-                final URI uri = new URI(nfsStore.getUrl());
-                // Create the volume folder
-                if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
-                    throw new InternalErrorException("Failed to create the volume folder.");
-                }
-
-                // Create a SR for the volume UUID folder
-                secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath());
-                // Look up the volume on the source primary storage pool
-                final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
-                // Copy the volume to secondary storage
-                task = srcVdi.copyAsync(conn, secondaryStorage, null, null);
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-                final VDI destVdi = Types.toVDI(task, conn);
-                final String destVolumeUUID = destVdi.getUuid(conn);
-
-                final VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(destVolume.getPath() + File.separator + destVolumeUUID + ".vhd");
-                newVol.setSize(srcVolume.getSize());
-                return new CopyCmdAnswer(newVol);
-            } catch (final Exception e) {
-                s_logger.debug("Failed to copy volume to secondary: " + e.toString());
-                return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString());
-            } finally {
-                if (task != null) {
-                    try {
-                        task.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
-                    }
-                }
-                hypervisorResource.removeSR(conn, secondaryStorage);
-            }
-        }
-        return new CopyCmdAnswer("unsupported protocol");
-    }
-
-    @Override
-    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        final int wait = cmd.getWait();
-        final VolumeObjectTO srcVolume = (VolumeObjectTO) srcData;
-        final VolumeObjectTO destVolume = (VolumeObjectTO) destData;
-        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destVolume.getDataStore();
-        final DataStoreTO srcStore = srcVolume.getDataStore();
-
-        if (srcStore instanceof NfsTO) {
-            final NfsTO nfsStore = (NfsTO) srcStore;
-            final String volumePath = srcVolume.getPath();
-            int index = volumePath.lastIndexOf("/");
-            final String volumeDirectory = volumePath.substring(0, index);
-            String volumeUuid = volumePath.substring(index + 1);
-            index = volumeUuid.indexOf(".");
-            if (index != -1) {
-                volumeUuid = volumeUuid.substring(0, index);
-            }
-            URI uri = null;
-            try {
-                uri = new URI(nfsStore.getUrl());
-            } catch (final Exception e) {
-                return new CopyCmdAnswer(e.toString());
-            }
-            final SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
-            Task task = null;
-            try {
-                final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid());
-                final VDI srcVdi = VDI.getByUuid(conn, volumeUuid);
-                task = srcVdi.copyAsync(conn, primaryStoragePool, null, null);
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-                final VDI destVdi = Types.toVDI(task, conn);
-                final VolumeObjectTO newVol = new VolumeObjectTO();
-                destVdi.setNameLabel(conn, srcVolume.getName());
-                newVol.setPath(destVdi.getUuid(conn));
-                newVol.setSize(srcVolume.getSize());
-
-                return new CopyCmdAnswer(newVol);
-            } catch (final Exception e) {
-                final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
-                s_logger.warn(msg, e);
-                return new CopyCmdAnswer(e.toString());
-            } finally {
-                if (task != null) {
-                    try {
-                        task.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.warn("unable to destroy task(" + task.toString() + ") due to " + e.toString());
-                    }
-                }
-                if (srcSr != null) {
-                    hypervisorResource.removeSR(conn, srcSr);
-                }
-            }
-        }
-
-        s_logger.debug("unsupported protocol");
-        return new CopyCmdAnswer("unsupported protocol");
-    }
-
-    @Override
-    public Answer createTemplateFromSnapshot(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-
-        if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof NfsTO) {
-            return createTemplateFromSnapshot2(cmd);
-        }
-
-        final int wait = cmd.getWait();
-
-        final SnapshotObjectTO srcObj = (SnapshotObjectTO) srcData;
-        final TemplateObjectTO destObj = (TemplateObjectTO) destData;
-
-        final NfsTO srcStore = (NfsTO) srcObj.getDataStore();
-        final NfsTO destStore = (NfsTO) destObj.getDataStore();
-
-        URI srcUri = null;
-        URI destUri = null;
-
-        try {
-            srcUri = new URI(srcStore.getUrl());
-            destUri = new URI(destStore.getUrl());
-        } catch (final Exception e) {
-            s_logger.debug("incorrect url", e);
-
-            return new CopyCmdAnswer("incorrect url" + e.toString());
-        }
-
-        final String srcPath = srcObj.getPath();
-        final int index = srcPath.lastIndexOf("/");
-        final String srcDir = srcPath.substring(0, index);
-        final String destDir = destObj.getPath();
-
-        SR srcSr = null;
-        SR destSr = null;
-
-        VDI destVdi = null;
-
-        boolean result = false;
-
-        try {
-            srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir);
-
-            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
-            final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
-
-            mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir);
-            makeDirectory(conn, localDir + "/" + destDir);
-
-            destSr = createFileSR(conn, localDir + "/" + destDir);
-
-            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
-
-            final String[] parents = srcObj.getParents();
-            final List<VDI> snapshotChains = new ArrayList<VDI>();
-
-            if (parents != null) {
-                for (int i = 0; i < parents.length; i++) {
-                    final String snChainPath = parents[i];
-                    final String uuid = getSnapshotUuid(snChainPath);
-                    final VDI chain = VDI.getByUuid(conn, uuid);
-
-                    snapshotChains.add(chain);
-                }
-            }
-
-            final String snapshotUuid = getSnapshotUuid(srcPath);
-            final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
-
-            snapshotChains.add(snapshotVdi);
-
-            final long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn);
-
-            destVdi = createVdi(conn, nameLabel, destSr, templateVirtualSize);
-
-            final String destVdiUuid = destVdi.getUuid(conn);
-
-            for (final VDI snapChain : snapshotChains) {
-                final Task task = snapChain.copyAsync(conn, null, null, destVdi);
-                // poll every 1 seconds ,
-                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
-                hypervisorResource.checkForSuccess(conn, task);
-
-                task.destroy(conn);
-            }
-
-            destVdi = VDI.getByUuid(conn, destVdiUuid);
-
-            // scan makes XenServer pick up VDI physicalSize
-            destSr.scan(conn);
-
-            final String templateUuid = destVdi.getUuid(conn);
-            final String templateFilename = templateUuid + ".vhd";
-            final long virtualSize = destVdi.getVirtualSize(conn);
-            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
-
-            String templatePath = destNfsPath + "/" + destDir;
-
-            templatePath = templatePath.replaceAll("//", "/");
-
-            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId());
-
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
-            }
-
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(destDir + "/" + templateFilename);
-            newTemplate.setFormat(Storage.ImageFormat.VHD);
-            newTemplate.setSize(destVdi.getVirtualSize(conn));
-            newTemplate.setPhysicalSize(destVdi.getPhysicalUtilisation(conn));
-            newTemplate.setName(destVdiUuid);
-
-            result = true;
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (final Exception e) {
-            s_logger.error("Failed create template from snapshot", e);
-
-            return new CopyCmdAnswer("Failed create template from snapshot " + e.toString());
-        } finally {
-            if (!result) {
-                if (destVdi != null) {
-                    try {
-                        destVdi.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.debug("Clean up left over on dest storage failed: ", e);
-                    }
-                }
-            }
-
-            if (srcSr != null) {
-                hypervisorResource.removeSR(conn, srcSr);
-            }
-
-            if (destSr != null) {
-                hypervisorResource.removeSR(conn, destSr);
-            }
-        }
-    }
-
-    private Answer createTemplateFromSnapshot2(final CopyCommand cmd) {
-        final Connection conn = hypervisorResource.getConnection();
-
-        final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO) cmd.getSrcTO();
-        final TemplateObjectTO templateObjTO = (TemplateObjectTO) cmd.getDestTO();
-
-        if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) {
-            return null;
-        }
-
-        NfsTO destStore;
-        URI destUri;
-
-        try {
-            destStore = (NfsTO)templateObjTO.getDataStore();
-            destUri = new URI(destStore.getUrl());
-        } catch (final Exception ex) {
-            s_logger.debug("Invalid URI", ex);
-
-            return new CopyCmdAnswer("Invalid URI: " + ex.toString());
-        }
-
-        SR srcSr = null;
-        SR destSr = null;
-
-        final String destDir = templateObjTO.getPath();
-        VDI destVdi = null;
-
-        boolean result = false;
-
-        try {
-            final Map<String, String> srcDetails = cmd.getOptions();
-
-            final String iScsiName = srcDetails.get(DiskTO.IQN);
-            final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
-            final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
-            final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
-            String srType;
-
-            srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
-
-            srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
-
-            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
-            final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
-
-            mountNfs(conn, destNfsPath, localDir);
-            makeDirectory(conn, localDir + "/" + destDir);
-
-            destSr = createFileSR(conn, localDir + "/" + destDir);
-
-            // there should only be one VDI in this SR
-            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
-
-            destVdi = srcVdi.copy(conn, destSr);
-
-            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
-
-            destVdi.setNameLabel(conn, nameLabel);
-
-            // scan makes XenServer pick up VDI physicalSize
-            destSr.scan(conn);
-
-            final String templateUuid = destVdi.getUuid(conn);
-            final String templateFilename = templateUuid + ".vhd";
-            final long virtualSize = destVdi.getVirtualSize(conn);
-            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
-
-            // create the template.properties file
-            String templatePath = destNfsPath + "/" + destDir;
-
-            templatePath = templatePath.replaceAll("//", "/");
-
-            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize,
-                    templateObjTO.getId());
-
-            if (!result) {
-                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
-            }
-
-            final TemplateObjectTO newTemplate = new TemplateObjectTO();
-
-            newTemplate.setPath(destDir + "/" + templateFilename);
-            newTemplate.setFormat(Storage.ImageFormat.VHD);
-            newTemplate.setHypervisorType(HypervisorType.XenServer);
-            newTemplate.setSize(virtualSize);
-            newTemplate.setPhysicalSize(physicalSize);
-            newTemplate.setName(templateUuid);
-
-            result = true;
-
-            return new CopyCmdAnswer(newTemplate);
-        } catch (final BadServerResponse e) {
-            s_logger.error("Failed to create a template from a snapshot due to incomprehensible server response", e);
-
-            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
-        } catch (final XenAPIException e) {
-            s_logger.error("Failed to create a template from a snapshot due to xenapi error", e);
-
-            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
-        } catch (final XmlRpcException e) {
-            s_logger.error("Failed to create a template from a snapshot due to rpc error", e);
-
-            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
-        } finally {
-            if (!result) {
-                if (destVdi != null) {
-                    try {
-                        destVdi.destroy(conn);
-                    } catch (final Exception e) {
-                        s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e);
-                    }
-                }
-            }
-
-            if (srcSr != null) {
-                hypervisorResource.removeSR(conn, srcSr);
-            }
-
-            if (destSr != null) {
-                hypervisorResource.removeSR(conn, destSr);
-            }
-        }
-    }
-}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java
deleted file mode 100644
index e17a017..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.xenserver.resource;
-
-import com.xensource.xenapi.Network;
-
-/**
- * A list of UUIDs that are gathered from the XenServer when the resource first
- * connects to XenServer. These UUIDs do not change over time.
- */
-public class XsHost {
-
-    private String systemvmisouuid;
-    private String uuid;
-    private String ip;
-    private String publicNetwork;
-    private String privateNetwork;
-    private String linkLocalNetwork;
-    private Network vswitchNetwork;
-    private String storageNetwork1;
-    private String guestNetwork;
-    private String guestPif;
-    private String publicPif;
-    private String privatePif;
-    private String storagePif1;
-    private String storagePif2;
-    private String pool;
-    private int speed;
-    private Integer cpuSockets;
-    private int cpus;
-    private String productVersion;
-    private String localSRuuid;
-
-    public String getSystemvmisouuid() {
-        return systemvmisouuid;
-    }
-
-    public void setSystemvmisouuid(final String systemvmisouuid) {
-        this.systemvmisouuid = systemvmisouuid;
-    }
-
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(final String uuid) {
-        this.uuid = uuid;
-    }
-
-    public String getIp() {
-        return ip;
-    }
-
-    public void setIp(final String ip) {
-        this.ip = ip;
-    }
-
-    public String getPublicNetwork() {
-        return publicNetwork;
-    }
-
-    public void setPublicNetwork(final String publicNetwork) {
-        this.publicNetwork = publicNetwork;
-    }
-
-    public String getPrivateNetwork() {
-        return privateNetwork;
-    }
-
-    public void setPrivateNetwork(final String privateNetwork) {
-        this.privateNetwork = privateNetwork;
-    }
-
-    public String getLinkLocalNetwork() {
-        return linkLocalNetwork;
-    }
-
-    public void setLinkLocalNetwork(final String linkLocalNetwork) {
-        this.linkLocalNetwork = linkLocalNetwork;
-    }
-
-    public Network getVswitchNetwork() {
-        return vswitchNetwork;
-    }
-
-    public void setVswitchNetwork(final Network vswitchNetwork) {
-        this.vswitchNetwork = vswitchNetwork;
-    }
-
-    public String getStorageNetwork1() {
-        return storageNetwork1;
-    }
-
-    public void setStorageNetwork1(final String storageNetwork1) {
-        this.storageNetwork1 = storageNetwork1;
-    }
-
-    public String getGuestNetwork() {
-        return guestNetwork;
-    }
-
-    public void setGuestNetwork(final String guestNetwork) {
-        this.guestNetwork = guestNetwork;
-    }
-
-    public String getGuestPif() {
-        return guestPif;
-    }
-
-    public void setGuestPif(final String guestPif) {
-        this.guestPif = guestPif;
-    }
-
-    public String getPublicPif() {
-        return publicPif;
-    }
-
-    public void setPublicPif(final String publicPif) {
-        this.publicPif = publicPif;
-    }
-
-    public String getPrivatePif() {
-        return privatePif;
-    }
-
-    public void setPrivatePif(final String privatePif) {
-        this.privatePif = privatePif;
-    }
-
-    public String getStoragePif1() {
-        return storagePif1;
-    }
-
-    public void setStoragePif1(final String storagePif1) {
-        this.storagePif1 = storagePif1;
-    }
-
-    public String getStoragePif2() {
-        return storagePif2;
-    }
-
-    public void setStoragePif2(final String storagePif2) {
-        this.storagePif2 = storagePif2;
-    }
-
-    public String getPool() {
-        return pool;
-    }
-
-    public void setPool(final String pool) {
-        this.pool = pool;
-    }
-
-    public int getSpeed() {
-        return speed;
-    }
-
-    public void setSpeed(final int speed) {
-        this.speed = speed;
-    }
-
-    public Integer getCpuSockets() {
-        return cpuSockets;
-    }
-
-    public void setCpuSockets(final Integer cpuSockets) {
-        this.cpuSockets = cpuSockets;
-    }
-
-    public int getCpus() {
-        return cpus;
-    }
-
-    public void setCpus(final int cpus) {
-        this.cpus = cpus;
-    }
-
-    public String getProductVersion() {
-        return productVersion;
-    }
-
-    public void setProductVersion(final String productVersion) {
-        this.productVersion = productVersion;
-    }
-
-    public String getLocalSRuuid() {
-        return localSRuuid;
-    }
-
-    public void setLocalSRuuid(final String localSRuuid) {
-        this.localSRuuid = localSRuuid;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder("XS[").append(uuid).append("-").append(ip).append("]").toString();
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java
deleted file mode 100644
index 72208ea..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.xenserver.resource.wrapper.xen610;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.MigrateVolumeAnswer;
-import com.cloud.agent.api.storage.MigrateVolumeCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.hypervisor.xenserver.resource.XenServer610Resource;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.SR;
-import com.xensource.xenapi.Task;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.VDI;
-
-@ResourceWrapper(handles =  MigrateVolumeCommand.class)
-public final class XenServer610MigrateVolumeCommandWrapper extends CommandWrapper<MigrateVolumeCommand, Answer, XenServer610Resource> {
-
-    private static final Logger s_logger = Logger.getLogger(XenServer610MigrateVolumeCommandWrapper.class);
-
-    @Override
-    public Answer execute(final MigrateVolumeCommand command, final XenServer610Resource xenServer610Resource) {
-        final Connection connection = xenServer610Resource.getConnection();
-        final String volumeUUID = command.getVolumePath();
-        final StorageFilerTO poolTO = command.getPool();
-
-        try {
-            final String uuid = poolTO.getUuid();
-            final SR destinationPool = xenServer610Resource.getStorageRepository(connection, uuid);
-            final VDI srcVolume = xenServer610Resource.getVDIbyUuid(connection, volumeUUID);
-            final Map<String, String> other = new HashMap<String, String>();
-            other.put("live", "true");
-
-            // Live migrate the vdi across pool.
-            final Task task = srcVolume.poolMigrateAsync(connection, destinationPool, other);
-            final long timeout = xenServer610Resource.getMigrateWait() * 1000L;
-            xenServer610Resource.waitForTask(connection, task, 1000, timeout);
-            xenServer610Resource.checkForSuccess(connection, task);
-
-            final VDI dvdi = Types.toVDI(task, connection);
-
-            return new MigrateVolumeAnswer(command, true, null, dvdi.getUuid(connection));
-        } catch (final Exception e) {
-            final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
-            s_logger.error(msg, e);
-            return new MigrateVolumeAnswer(command, false, msg, null);
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java
deleted file mode 100644
index 21930ee..0000000
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
-
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.MigrateAnswer;
-import com.cloud.agent.api.MigrateCommand;
-import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
-import com.cloud.resource.CommandWrapper;
-import com.cloud.resource.ResourceWrapper;
-import com.xensource.xenapi.Connection;
-import com.xensource.xenapi.Host;
-import com.xensource.xenapi.Types;
-import com.xensource.xenapi.VBD;
-import com.xensource.xenapi.VM;
-
-@ResourceWrapper(handles =  MigrateCommand.class)
-public final class CitrixMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, CitrixResourceBase> {
-
-    private static final Logger s_logger = Logger.getLogger(CitrixMigrateCommandWrapper.class);
-
-    @Override
-    public Answer execute(final MigrateCommand command, final CitrixResourceBase citrixResourceBase) {
-        final Connection conn = citrixResourceBase.getConnection();
-        final String vmName = command.getVmName();
-        final String dstHostIpAddr = command.getDestinationIp();
-
-        try {
-            final Set<VM> vms = VM.getByNameLabel(conn, vmName);
-
-            final Set<Host> hosts = Host.getAll(conn);
-            Host dsthost = null;
-            if(hosts != null) {
-                for (final Host host : hosts) {
-                    if (host.getAddress(conn).equals(dstHostIpAddr)) {
-                        dsthost = host;
-                        break;
-                    }
-                }
-            }
-            if (dsthost == null) {
-                final String msg = "Migration failed due to unable to find host " + dstHostIpAddr + " in XenServer pool " + citrixResourceBase.getHost().getPool();
-                s_logger.warn(msg);
-                return new MigrateAnswer(command, false, msg, null);
-            }
-            for (final VM vm : vms) {
-                final Set<VBD> vbds = vm.getVBDs(conn);
-                for (final VBD vbd : vbds) {
-                    final VBD.Record vbdRec = vbd.getRecord(conn);
-                    if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) {
-                        vbd.eject(conn);
-                        // for config drive vbd destroy the vbd.
-                        if (!vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) {
-                            if (vbdRec.currentlyAttached) {
-                                vbd.destroy(conn);
-                            }
-                        }
-                        continue;
-                    }
-                }
-                citrixResourceBase.migrateVM(conn, dsthost, vm, vmName);
-                vm.setAffinity(conn, dsthost);
-            }
-
-            // The iso can be attached to vm only once the vm is (present in the host) migrated.
-            // Attach the config drive iso device to VM
-            if (!citrixResourceBase.attachConfigDriveToMigratedVm(conn, vmName, dstHostIpAddr)) {
-                s_logger.debug("Config drive ISO attach failed after migration for vm "+vmName);
-            }
-
-            return new MigrateAnswer(command, true, "migration succeeded", null);
-        } catch (final Exception e) {
-            s_logger.warn(e.getMessage(), e);
-            return new MigrateAnswer(command, false, e.getMessage(), null);
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/ha/XenServerFencer.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/ha/XenServerFencer.java
new file mode 100644
index 0000000..72ec375
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/ha/XenServerFencer.java
@@ -0,0 +1,127 @@
+// 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.ha;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+public class XenServerFencer extends AdapterBase implements FenceBuilder {
+    private static final Logger s_logger = Logger.getLogger(XenServerFencer.class);
+
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.XenServer) {
+            s_logger.debug("Don't know how to fence non XenServer hosts " + host.getHypervisorType());
+            return null;
+        }
+
+        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() == HypervisorType.XenServer) {
+                if (h.getStatus() != Status.Up) {
+                    continue;
+                }
+                if (h.getId() == host.getId()) {
+                    continue;
+                }
+                FenceAnswer answer;
+                try {
+                    Answer ans = _agentMgr.send(h.getId(), fence);
+                    if (!(ans instanceof FenceAnswer)) {
+                        s_logger.debug("Answer is not fenceanswer.  Result = " + ans.getResult() + "; Details = " + ans.getDetails());
+                        continue;
+                    }
+                    answer = (FenceAnswer)ans;
+                } catch (AgentUnavailableException e) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    }
+                    continue;
+                } catch (OperationTimedoutException e) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    }
+                    continue;
+                }
+                if (answer != null && answer.getResult()) {
+                    return true;
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
+        }
+
+        return false;
+    }
+
+    public XenServerFencer() {
+        super();
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/XenServerGuru.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/XenServerGuru.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java
new file mode 100644
index 0000000..fd95da2
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java
@@ -0,0 +1,698 @@
+// 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.xenserver.discoverer;
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.persistence.EntityExistsException;
+
+import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.SetupAnswer;
+import com.cloud.agent.api.SetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.DiscoveredWithErrorException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.HostEnvironment;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.xenserver.resource.CitrixHelper;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.hypervisor.xenserver.resource.XcpOssResource;
+import com.cloud.hypervisor.xenserver.resource.XcpServerResource;
+import com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer56Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer56SP2Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer600Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer610Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer620Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer620SP1Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServer650Resource;
+import com.cloud.hypervisor.xenserver.resource.XenServerConnectionPool;
+import com.cloud.hypervisor.xenserver.resource.Xenserver625Resource;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.HypervisorVersionChangedException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.HostPatch;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.PoolPatch;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Types.SessionAuthenticationFailed;
+import com.xensource.xenapi.Types.UuidInvalid;
+import com.xensource.xenapi.Types.XenAPIException;
+
+
+public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter {
+    private static final Logger s_logger = Logger.getLogger(XcpServerDiscoverer.class);
+    private int _wait;
+    private XenServerConnectionPool _connPool;
+    private boolean _checkHvm;
+    private boolean _setupMultipath;
+    private String _instance;
+
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private VMTemplateDao _tmpltDao;
+    @Inject
+    private HostPodDao _podDao;
+
+    private String xenServerIsoName = "xs-tools.iso";
+    private String xenServerIsoDisplayText = "XenServer Tools Installer ISO (xen-pv-drv-iso)";
+
+    protected XcpServerDiscoverer() {
+    }
+
+    void setClusterGuid(ClusterVO cluster, String guid) {
+        cluster.setGuid(guid);
+        try {
+            _clusterDao.update(cluster.getId(), cluster);
+        } catch (EntityExistsException e) {
+            QueryBuilder<ClusterVO> sc = QueryBuilder.create(ClusterVO.class);
+            sc.and(sc.entity().getGuid(), Op.EQ, guid);
+            List<ClusterVO> clusters = sc.list();
+            ClusterVO clu = clusters.get(0);
+            List<HostVO> clusterHosts = _resourceMgr.listAllHostsInCluster(clu.getId());
+            if (clusterHosts == null || clusterHosts.size() == 0) {
+                clu.setGuid(null);
+                _clusterDao.update(clu.getId(), clu);
+                _clusterDao.update(cluster.getId(), cluster);
+                return;
+            }
+            throw e;
+        }
+    }
+
+    protected boolean poolHasHotFix(Connection conn, String hostIp, String hotFixUuid) {
+        try {
+            Map<Host, Host.Record> hosts = Host.getAllRecords(conn);
+            for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
+
+                Host.Record re = entry.getValue();
+                if (!re.address.equalsIgnoreCase(hostIp)){
+                    continue;
+                }
+                Set<HostPatch> patches = re.patches;
+                PoolPatch poolPatch = PoolPatch.getByUuid(conn, hotFixUuid);
+                for(HostPatch patch : patches) {
+                    PoolPatch pp = patch.getPoolPatch(conn);
+                    if (pp != null && pp.equals(poolPatch) && patch.getApplied(conn)) {
+                        s_logger.debug("host " + hostIp + " does have " + hotFixUuid +" Hotfix.");
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } catch (UuidInvalid e) {
+            s_logger.debug("host " + hostIp + " doesn't have " + hotFixUuid + " Hotfix");
+        } catch (Exception e) {
+            s_logger.debug("can't get patches information, consider it doesn't have " + hotFixUuid + " Hotfix");
+        }
+        return false;
+    }
+
+
+
+    @Override
+    public Map<? extends ServerResource, Map<String, String>>
+    find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException {
+        Map<CitrixResourceBase, Map<String, String>> resources = new HashMap<CitrixResourceBase, Map<String, String>>();
+        Connection conn = null;
+        if (!url.getScheme().equals("http")) {
+            String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
+            s_logger.debug(msg);
+            return null;
+        }
+        if (clusterId == null) {
+            String msg = "must specify cluster Id when add host";
+            s_logger.debug(msg);
+            throw new RuntimeException(msg);
+        }
+
+        if (podId == null) {
+            String msg = "must specify pod Id when add host";
+            s_logger.debug(msg);
+            throw new RuntimeException(msg);
+        }
+
+        ClusterVO cluster = _clusterDao.findById(clusterId);
+        if (cluster == null || cluster.getHypervisorType() != HypervisorType.XenServer) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("invalid cluster id or cluster is not for XenServer hypervisors");
+            }
+            return null;
+        }
+
+        try {
+            String hostname = url.getHost();
+            InetAddress ia = InetAddress.getByName(hostname);
+            String hostIp = ia.getHostAddress();
+            Queue<String> pass = new LinkedList<String>();
+            pass.add(password);
+            conn = _connPool.getConnect(hostIp, username, pass);
+            if (conn == null) {
+                String msg = "Unable to get a connection to " + url;
+                s_logger.debug(msg);
+                throw new DiscoveryException(msg);
+            }
+
+            Set<Pool> pools = Pool.getAll(conn);
+            Pool pool = pools.iterator().next();
+            Pool.Record pr = pool.getRecord(conn);
+            String poolUuid = pr.uuid;
+            Map<Host, Host.Record> hosts = Host.getAllRecords(conn);
+            String latestHotFix = "";
+            if (poolHasHotFix(conn, hostIp, XenserverConfigs.XSHotFix62ESP1004)) {
+                latestHotFix = XenserverConfigs.XSHotFix62ESP1004;
+            } else if (poolHasHotFix(conn, hostIp, XenserverConfigs.XSHotFix62ESP1)) {
+                latestHotFix = XenserverConfigs.XSHotFix62ESP1;
+            }
+
+            /*set cluster hypervisor type to xenserver*/
+            ClusterVO clu = _clusterDao.findById(clusterId);
+            if (clu.getGuid() == null) {
+                setClusterGuid(clu, poolUuid);
+            } else {
+                List<HostVO> clusterHosts = _resourceMgr.listAllHostsInCluster(clusterId);
+                if (clusterHosts != null && clusterHosts.size() > 0) {
+                    if (!clu.getGuid().equals(poolUuid)) {
+                        String msg = "Please join the host " +  hostIp + " to XS pool  "
+                                + clu.getGuid() + " through XC/XS before adding it through CS UI";
+                        s_logger.warn(msg);
+                        throw new DiscoveryException(msg);
+                    }
+                } else {
+                    setClusterGuid(clu, poolUuid);
+                }
+            }
+            // can not use this conn after this point, because this host may join a pool, this conn is retired
+            if (conn != null) {
+                try {
+                    Session.logout(conn);
+                } catch (Exception e) {
+                    s_logger.debug("Caught exception during logout", e);
+                }
+                conn.dispose();
+                conn = null;
+            }
+
+            poolUuid = clu.getGuid();
+            _clusterDao.update(clusterId, clu);
+
+            if (_checkHvm) {
+                for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
+                    Host.Record record = entry.getValue();
+
+                    boolean support_hvm = false;
+                    for (String capability : record.capabilities) {
+                        if (capability.contains("hvm")) {
+                            support_hvm = true;
+                            break;
+                        }
+                    }
+                    if (!support_hvm) {
+                        String msg = "Unable to add host " + record.address + " because it doesn't support hvm";
+                        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, msg, msg);
+                        s_logger.debug(msg);
+                        throw new RuntimeException(msg);
+                    }
+                }
+            }
+
+            for (Map.Entry<Host, Host.Record> entry : hosts.entrySet()) {
+                Host.Record record = entry.getValue();
+                String hostAddr = record.address;
+
+                String prodVersion = CitrixHelper.getProductVersion(record);
+                String xenVersion = record.softwareVersion.get("xen");
+                String hostOS = record.softwareVersion.get("product_brand");
+                if (hostOS == null) {
+                    hostOS = record.softwareVersion.get("platform_name");
+                }
+
+                String hostOSVer = prodVersion;
+                String hostKernelVer = record.softwareVersion.get("linux");
+
+                if (_resourceMgr.findHostByGuid(record.uuid) != null) {
+                    s_logger.debug("Skipping " + record.address + " because " + record.uuid + " is already in the database.");
+                    continue;
+                }
+
+                CitrixResourceBase resource = createServerResource(dcId, podId, record, latestHotFix);
+                s_logger.info("Found host " + record.hostname + " ip=" + record.address + " product version=" + prodVersion);
+
+                Map<String, String> details = new HashMap<String, String>();
+                Map<String, Object> params = new HashMap<String, Object>();
+                details.put("url", hostAddr);
+                details.put("username", username);
+                params.put("username", username);
+                details.put("password", password);
+                params.put("password", password);
+                params.put("zone", Long.toString(dcId));
+                params.put("guid", record.uuid);
+                params.put("pod", podId.toString());
+                params.put("cluster", clusterId.toString());
+                params.put("pool", poolUuid);
+                params.put("ipaddress", record.address);
+
+                details.put(HostInfo.HOST_OS, hostOS);
+                details.put(HostInfo.HOST_OS_VERSION, hostOSVer);
+                details.put(HostInfo.HOST_OS_KERNEL_VERSION, hostKernelVer);
+                details.put(HostInfo.HYPERVISOR_VERSION, xenVersion);
+
+                String privateNetworkLabel = _networkMgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.XenServer);
+                String storageNetworkLabel = _networkMgr.getDefaultStorageTrafficLabel(dcId, HypervisorType.XenServer);
+
+                if (!params.containsKey("private.network.device") && privateNetworkLabel != null) {
+                    params.put("private.network.device", privateNetworkLabel);
+                    details.put("private.network.device", privateNetworkLabel);
+                }
+
+                if (!params.containsKey("storage.network.device1") && storageNetworkLabel != null) {
+                    params.put("storage.network.device1", storageNetworkLabel);
+                    details.put("storage.network.device1", storageNetworkLabel);
+                }
+
+                DataCenterVO zone = _dcDao.findById(dcId);
+                boolean securityGroupEnabled = zone.isSecurityGroupEnabled();
+                params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
+
+                params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
+                params.put("wait", Integer.toString(_wait));
+                details.put("wait", Integer.toString(_wait));
+                params.put("migratewait", _configDao.getValue(Config.MigrateWait.toString()));
+                params.put(Config.XenServerMaxNics.toString().toLowerCase(), _configDao.getValue(Config.XenServerMaxNics.toString()));
+                params.put(Config.XenServerHeartBeatTimeout.toString().toLowerCase(), _configDao.getValue(Config.XenServerHeartBeatTimeout.toString()));
+                params.put(Config.XenServerHeartBeatInterval.toString().toLowerCase(), _configDao.getValue(Config.XenServerHeartBeatInterval.toString()));
+                params.put(Config.InstanceName.toString().toLowerCase(), _instance);
+                details.put(Config.InstanceName.toString().toLowerCase(), _instance);
+                try {
+                    resource.configure("XenServer", params);
+                } catch (ConfigurationException e) {
+                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + record.address, "Error is " + e.getMessage());
+                    s_logger.warn("Unable to instantiate " + record.address, e);
+                    continue;
+                }
+                resource.start();
+                resources.put(resource, details);
+            }
+        } catch (SessionAuthenticationFailed e) {
+            throw new DiscoveredWithErrorException("Authentication error");
+        } catch (XenAPIException e) {
+            s_logger.warn("XenAPI exception", e);
+            return null;
+        } catch (XmlRpcException e) {
+            s_logger.warn("Xml Rpc Exception", e);
+            return null;
+        } catch (UnknownHostException e) {
+            s_logger.warn("Unable to resolve the host name", e);
+            return null;
+        } catch (Exception e) {
+            s_logger.debug("other exceptions: " + e.toString(), e);
+            return null;
+        }
+        return resources;
+    }
+
+    String getPoolUuid(Connection conn) throws XenAPIException, XmlRpcException {
+        Map<Pool, Pool.Record> pools = Pool.getAllRecords(conn);
+        assert pools.size() == 1 : "Pools size is " + pools.size();
+        return pools.values().iterator().next().uuid;
+    }
+
+    protected void addSamePool(Connection conn, Map<CitrixResourceBase, Map<String, String>> resources) throws XenAPIException, XmlRpcException {
+        Map<Pool, Pool.Record> hps = Pool.getAllRecords(conn);
+        assert (hps.size() == 1) : "How can it be more than one but it's actually " + hps.size();
+
+        // This is the pool.
+        String poolUuid = hps.values().iterator().next().uuid;
+
+        for (Map<String, String> details : resources.values()) {
+            details.put("pool", poolUuid);
+        }
+    }
+
+    protected CitrixResourceBase createServerResource(String prodBrand, String prodVersion, String prodVersionTextShort, String hotfix) {
+        // Xen Cloud Platform group of hypervisors
+        if (prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0")
+                || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4") || prodVersion.startsWith("1.6"))) {
+            return new XcpServerResource();
+        } // Citrix Xenserver group of hypervisors
+        else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) {
+            return new XenServer56Resource();
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.0")) {
+            return new XenServer600Resource();
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.2")) {
+            return new XenServer600Resource();
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.1.0")) {
+            return new XenServer610Resource();
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("6.2.0")) {
+            if (hotfix != null && hotfix.equals(XenserverConfigs.XSHotFix62ESP1004)) {
+                return new Xenserver625Resource();
+            } else if (hotfix != null && hotfix.equals(XenserverConfigs.XSHotFix62ESP1)) {
+                return new XenServer620SP1Resource();
+            } else {
+                return new XenServer620Resource();
+            }
+        } else if (prodBrand.equals("XenServer") && prodVersion.equals("5.6.100")) {
+            if ("5.6 SP2".equals(prodVersionTextShort.trim())) {
+                return new XenServer56SP2Resource();
+            } else if ("5.6 FP1".equals(prodVersionTextShort.trim())) {
+                return new XenServer56FP1Resource();
+            }
+        } else if (prodBrand.equals("XCP_Kronos")) {
+            return new XcpOssResource();
+        } else if (prodBrand.equals("XenServer") || prodBrand.equals("XCP-ng")) {
+            final String[] items = prodVersion.split("\\.");
+            if ((Integer.parseInt(items[0]) > 6) ||
+                    (Integer.parseInt(items[0]) == 6 && Integer.parseInt(items[1]) >= 4)) {
+                s_logger.warn("defaulting to xenserver650 resource for product brand: " + prodBrand + " with product " +
+                        "version: " + prodVersion);
+                //default to xenserver650 resource.
+                return new XenServer650Resource();
+            }
+        }
+        String msg =
+                "Only support XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; XenServer 5.6,  XenServer 5.6 FP1, XenServer 5.6 SP2, Xenserver 6.0, 6.0.2, 6.1.0, 6.2.0, >6.4.0 but this one is " +
+                        prodBrand + " " + prodVersion;
+        s_logger.warn(msg);
+        throw new RuntimeException(msg);
+    }
+
+
+
+    protected CitrixResourceBase createServerResource(long dcId, Long podId, Host.Record record, String hotfix) {
+        String prodBrand = record.softwareVersion.get("product_brand");
+        if (prodBrand == null) {
+            prodBrand = record.softwareVersion.get("platform_name").trim();
+        } else {
+            prodBrand = prodBrand.trim();
+        }
+        String prodVersion = CitrixHelper.getProductVersion(record);
+
+        String prodVersionTextShort = record.softwareVersion.get("product_version_text_short");
+        return createServerResource(prodBrand, prodVersion, prodVersionTextShort, hotfix);
+    }
+
+    protected void serverConfig() {
+        String value = _params.get(Config.XenServerSetupMultipath.key());
+        _setupMultipath = Boolean.parseBoolean(value);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        serverConfig();
+
+        String value = _params.get(Config.XapiWait.toString());
+        _wait = NumbersUtil.parseInt(value, Integer.parseInt(Config.XapiWait.getDefaultValue()));
+
+        _instance = _params.get(Config.InstanceName.key());
+
+        value = _params.get("xenserver.check.hvm");
+        _checkHvm = Boolean.parseBoolean(value);
+        _connPool = XenServerConnectionPool.getInstance();
+
+        _agentMgr.registerForHostEvents(this, true, false, true);
+
+        createXenServerToolsIsoEntryInDatabase();
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+        return true;
+    }
+
+    @Override
+    public boolean matchHypervisor(String hypervisor) {
+        if (hypervisor == null) {
+            return true;
+        }
+        return Hypervisor.HypervisorType.XenServer.toString().equalsIgnoreCase(hypervisor);
+    }
+
+    @Override
+    public Hypervisor.HypervisorType getHypervisorType() {
+        return Hypervisor.HypervisorType.XenServer;
+    }
+
+    @Override
+    public void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException {
+        //do nothing
+    }
+
+    @Override
+    public int getTimeout() {
+        return 0;
+    }
+
+    @Override
+    public boolean isRecurring() {
+        return false;
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        return false;
+    }
+
+    /**
+     * Create the XenServer tools ISO entry in the database.
+     * If there is already an entry with 'isoName' equals to {@value #xenServerIsoName} , we update its 'displayText' to {@value #xenServerIsoDisplayText}.
+     * Otherwise, we create a new entry.
+     */
+    protected void createXenServerToolsIsoEntryInDatabase() {
+        VMTemplateVO tmplt = _tmpltDao.findByTemplateName(xenServerIsoName);
+        if (tmplt == null) {
+            long id = _tmpltDao.getNextInSequence(Long.class, "id");
+            VMTemplateVO template = VMTemplateVO.createPreHostIso(id, xenServerIsoName, xenServerIsoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64,
+                    Account.ACCOUNT_ID_SYSTEM, null, xenServerIsoDisplayText, false, 1, false, HypervisorType.XenServer);
+            _tmpltDao.persist(template);
+        } else {
+            long id = tmplt.getId();
+            tmplt.setTemplateType(TemplateType.PERHOST);
+            tmplt.setUrl(null);
+            tmplt.setDisplayText(xenServerIsoDisplayText);
+            _tmpltDao.update(id, tmplt);
+        }
+    }
+
+    @Override
+    public void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+        if (!(cmd instanceof StartupRoutingCommand)) {
+            return;
+        }
+        long agentId = agent.getId();
+
+        StartupRoutingCommand startup = (StartupRoutingCommand)cmd;
+        if (startup.getHypervisorType() != HypervisorType.XenServer) {
+            s_logger.debug("Not XenServer so moving on.");
+            return;
+        }
+
+        HostVO host = _hostDao.findById(agentId);
+
+        ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+        if (cluster.getGuid() == null) {
+            cluster.setGuid(startup.getPool());
+            _clusterDao.update(cluster.getId(), cluster);
+        } else if (!cluster.getGuid().equals(startup.getPool())) {
+            String msg = "pool uuid for cluster " + cluster.getId() + " changed from " + cluster.getGuid() + " to " + startup.getPool();
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        Map<String, String> details = startup.getHostDetails();
+        String prodBrand = details.get("product_brand").trim();
+        String prodVersion = details.get("product_version").trim();
+        String hotfix = details.get(XenserverConfigs.XS620HotFix);
+        String prodVersionTextShort = details.get("product_version_text_short");
+
+        String resource = createServerResource(prodBrand, prodVersion, prodVersionTextShort, hotfix).getClass().getName();
+
+        if (!resource.equals(host.getResource())) {
+            String msg = "host " + host.getPrivateIpAddress() + " changed from " + host.getResource() + " to " + resource;
+            s_logger.debug(msg);
+            host.setResource(resource);
+            host.setSetup(false);
+            _hostDao.update(agentId, host);
+            throw new HypervisorVersionChangedException(msg);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Setting up host " + agentId);
+        }
+        HostEnvironment env = new HostEnvironment();
+
+        SetupCommand setup = new SetupCommand(env);
+        if (_setupMultipath) {
+            setup.setMultipathOn();
+        }
+        if (!host.isSetup()) {
+            setup.setNeedSetup(true);
+        }
+
+        try {
+            Answer answer = _agentMgr.send(agentId, setup);
+            if (answer != null && answer.getResult() && answer instanceof SetupAnswer) {
+                host.setSetup(true);
+                host.setLastPinged((System.currentTimeMillis() >> 10) - 5 * 60);
+                host.setHypervisorVersion(prodVersion);
+                _hostDao.update(host.getId(), host);
+                if (((SetupAnswer)answer).needReconnect()) {
+                    throw new ConnectionException(false, "Reinitialize agent after setup.");
+                }
+                return;
+            } else {
+                s_logger.warn("Unable to setup agent " + agentId + " due to " + ((answer != null) ? answer.getDetails() : "return null"));
+            }
+        } catch (AgentUnavailableException e) {
+            s_logger.warn("Unable to setup agent " + agentId + " because it became unavailable.", e);
+        } catch (OperationTimedoutException e) {
+            s_logger.warn("Unable to setup agent " + agentId + " because it timed out", e);
+        }
+        throw new ConnectionException(true, "Reinitialize agent after setup.");
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
+        return null;
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        return false;
+    }
+
+    @Override
+    public void processHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void processHostRemoved(long hostId, long clusterId) {
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        return false;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        StartupCommand firstCmd = startup[0];
+        if (!(firstCmd instanceof StartupRoutingCommand)) {
+            return null;
+        }
+
+        StartupRoutingCommand ssCmd = ((StartupRoutingCommand)firstCmd);
+        if (ssCmd.getHypervisorType() != HypervisorType.XenServer) {
+            return null;
+        }
+
+        HostPodVO pod = _podDao.findById(host.getPodId());
+        DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
+        s_logger.info("Host: " + host.getName() + " connected with hypervisor type: " + HypervisorType.XenServer + ". Checking CIDR...");
+        _resourceMgr.checkCIDR(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPrivateNetmask());
+        return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.XenServer, details, hostTags);
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (host.getType() != com.cloud.host.Host.Type.Routing || host.getHypervisorType() != HypervisorType.XenServer) {
+            return null;
+        }
+
+        _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
+        return new DeleteHostAnswer(true);
+    }
+
+    @Override
+    protected HashMap<String, Object> buildConfigParams(HostVO host) {
+        HashMap<String, Object> params = super.buildConfigParams(host);
+        DataCenterVO zone = _dcDao.findById(host.getDataCenterId());
+        if (zone != null) {
+            boolean securityGroupEnabled = zone.isSecurityGroupEnabled();
+            params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
+        }
+        return params;
+    }
+
+    @Override
+    public boolean stop() {
+        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+        return super.stop();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
new file mode 100644
index 0000000..e1066b7
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
@@ -0,0 +1,5614 @@
+// 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.xenserver.resource;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.joda.time.Duration;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
+import com.cloud.agent.api.PingRoutingWithOvsCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.VgpuTypesInfo;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.GPUDeviceTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VRScripts;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.CitrixRequestWrapper;
+import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.hypervisor.HypervisorResource;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.ExecutionResult;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.utils.ssh.SshHelper;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.trilead.ssh2.SCPClient;
+import com.xensource.xenapi.Bond;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Console;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.HostCpu;
+import com.xensource.xenapi.HostMetrics;
+import com.xensource.xenapi.Network;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.VmPowerState;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VIF;
+import com.xensource.xenapi.VLAN;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.XenAPIObject;
+
+/**
+ * CitrixResourceBase encapsulates the calls to the XenServer Xapi process to
+ * perform the required functionalities for CloudStack.
+ *
+ * ==============> READ THIS <============== Because the XenServer objects can
+ * expire when the session expires, we cannot keep any of the actual XenServer
+ * objects in this class. The only thing that is constant is the UUID of the
+ * XenServer objects but not the objects themselves! This is very important
+ * before you do any changes in this code here.
+ *
+ */
+public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer {
+    /**
+     * used to describe what type of resource a storage device is of
+     */
+    public enum SRType {
+        EXT, ISO, LVM, LVMOHBA, LVMOISCSI,
+        /**
+         * used for resigning metadata (like SR UUID and VDI UUID when a
+         * particular storage manager is installed on a XenServer host (for back-end snapshots to work))
+         */
+        RELVMOISCSI, NFS;
+
+        String _str;
+
+        private SRType() {
+            _str = super.toString().toLowerCase();
+        }
+
+        public boolean equals(final String type) {
+            return _str.equalsIgnoreCase(type);
+        }
+
+        @Override
+        public String toString() {
+            return _str;
+        }
+    }
+
+    private final static int BASE_TO_CONVERT_BYTES_INTO_KILOBYTES = 1024;
+
+    private static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance();
+    // static min values for guests on xenserver
+    private static final long mem_128m = 134217728L;
+
+    static final Random Rand = new Random(System.currentTimeMillis());
+    private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class);
+    protected static final HashMap<VmPowerState, PowerState> s_powerStatesTable;
+
+    private String xenServer70plusGuestToolsName = "guest-tools.iso";
+    private String xenServerBefore70GuestToolsName = "xs-tools.iso";
+
+    static {
+        s_powerStatesTable = new HashMap<VmPowerState, PowerState>();
+        s_powerStatesTable.put(VmPowerState.HALTED, PowerState.PowerOff);
+        s_powerStatesTable.put(VmPowerState.PAUSED, PowerState.PowerOff);
+        s_powerStatesTable.put(VmPowerState.RUNNING, PowerState.PowerOn);
+        s_powerStatesTable.put(VmPowerState.SUSPENDED, PowerState.PowerOff);
+        s_powerStatesTable.put(VmPowerState.UNRECOGNIZED, PowerState.PowerUnknown);
+    }
+
+    private static PowerState convertToPowerState(final VmPowerState ps) {
+        final PowerState powerState = s_powerStatesTable.get(ps);
+        return powerState == null ? PowerState.PowerUnknown : powerState;
+    }
+
+    private static boolean isAlienVm(final VM vm, final Connection conn) throws XenAPIException, XmlRpcException {
+        // TODO : we need a better way to tell whether or not the VM belongs to
+        // CloudStack
+        final String vmName = vm.getNameLabel(conn);
+        if (vmName.matches("^[ivs]-\\d+-.+")) {
+            return false;
+        }
+
+        return true;
+    }
+
+    protected IAgentControl _agentControl;
+    protected boolean _canBridgeFirewall = false;
+    protected String _cluster;
+    // Guest and Host Performance Statistics
+    protected String _consolidationFunction = "AVERAGE";
+    protected long _dcId;
+    protected String _guestNetworkName;
+    protected int _heartbeatInterval = 60;
+    protected int _heartbeatTimeout = 120;
+    protected XsHost _host = new XsHost();
+    protected String _instance; // instance name (default is usually "VM")
+    protected boolean _isOvs = false;
+    protected String _linkLocalPrivateNetworkName;
+    protected int _maxNics = 7;
+
+    final int _maxWeight = 256;
+    protected int _migratewait;
+    protected String _name;
+    protected Queue<String> _password = new LinkedList<String>();
+
+    protected String _pod;
+    protected int _pollingIntervalInSeconds = 60;
+
+    protected String _privateNetworkName;
+    protected String _publicNetworkName;
+
+    protected final int _retry = 100;
+
+    protected boolean _securityGroupEnabled;
+    protected final int _sleep = 10000;
+    protected String _storageNetworkName1;
+    protected String _storageNetworkName2;
+    protected List<VIF> _tmpDom0Vif = new ArrayList<VIF>();
+
+    protected String _username;
+
+    protected VirtualRoutingResource _vrResource;
+
+    protected String _configDriveIsopath = "/opt/xensource/packages/configdrive_iso/";
+    protected String _configDriveSRName = "ConfigDriveISOs";
+    public String _attachIsoDeviceNum = "3";
+
+    protected XenServerUtilitiesHelper xenServerUtilitiesHelper = new XenServerUtilitiesHelper();
+
+    protected int _wait;
+    // Hypervisor specific params with generic value, may need to be overridden
+    // for specific versions
+    long _xsMemoryUsed = 128 * 1024 * 1024L; // xenserver hypervisor used 128 M
+
+    double _xsVirtualizationFactor = 63.0 / 64.0; // 1 - virtualization overhead
+
+    protected StorageSubsystemCommandHandler storageHandler;
+
+    private static final String XENSTORE_DATA_IP = "vm-data/ip";
+    private static final String XENSTORE_DATA_GATEWAY = "vm-data/gateway";
+    private static final String XENSTORE_DATA_NETMASK = "vm-data/netmask";
+    private static final String XENSTORE_DATA_CS_INIT = "vm-data/cloudstack/init";
+
+    public CitrixResourceBase() {
+    }
+
+    /**
+     * Replaces the old password with the new password used to connect to the host.
+     *
+     * @param password  - the new host password.
+     * @return the old password.
+     */
+    public String replaceOldPasswdInQueue(final String password) {
+        final String oldPasswd = _password.poll();
+        _password.add(password);
+
+        return oldPasswd;
+    }
+
+    public String getPwdFromQueue() {
+        return _password.peek();
+    }
+
+    public XenServerUtilitiesHelper getXenServerUtilitiesHelper() {
+        return xenServerUtilitiesHelper;
+    }
+
+    protected StorageSubsystemCommandHandler buildStorageHandler() {
+        final XenServerStorageProcessor processor = new XenServerStorageProcessor(this);
+        return new StorageSubsystemCommandHandlerBase(processor);
+    }
+
+    public String callHostPlugin(final Connection conn, final String plugin, final String cmd, final String... params) {
+        final Map<String, String> args = new HashMap<String, String>();
+        String msg;
+        try {
+            for (int i = 0; i < params.length; i += 2) {
+                args.put(params[i], params[i + 1]);
+            }
+
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
+            }
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final String result = host.callPlugin(conn, plugin, cmd, args);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin Result: " + result);
+            }
+            return result.replace("\n", "");
+        } catch (final XenAPIException e) {
+            msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString();
+            s_logger.warn(msg);
+        } catch (final XmlRpcException e) {
+            msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage();
+            s_logger.debug(msg);
+        }
+        throw new CloudRuntimeException(msg);
+    }
+
+    protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final Map<String, String> params) {
+        final int timeout = wait * 1000;
+        final Map<String, String> args = new HashMap<String, String>();
+        Task task = null;
+        try {
+            for (final Map.Entry<String, String> entry : params.entrySet()) {
+                args.put(entry.getKey(), entry.getValue());
+            }
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
+            }
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            task = host.callPluginAsync(conn, plugin, cmd, args);
+            // poll every 1 seconds
+            waitForTask(conn, task, 1000, timeout);
+            checkForSuccess(conn, task);
+            final String result = task.getResult(conn);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin Result: " + result);
+            }
+            return result.replace("<value>", "").replace("</value>", "").replace("\n", "");
+        } catch (final Types.HandleInvalid e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
+        } catch (final Exception e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+        return null;
+    }
+
+    protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final String... params) {
+        final int timeout = wait * 1000;
+        final Map<String, String> args = new HashMap<String, String>();
+        Task task = null;
+        try {
+            for (int i = 0; i < params.length; i += 2) {
+                args.put(params[i], params[i + 1]);
+            }
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
+            }
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            task = host.callPluginAsync(conn, plugin, cmd, args);
+            // poll every 1 seconds
+            waitForTask(conn, task, 1000, timeout);
+            checkForSuccess(conn, task);
+            final String result = task.getResult(conn);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin Result: " + result);
+            }
+            return result.replace("<value>", "").replace("</value>", "").replace("\n", "");
+        } catch (final Types.HandleInvalid e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
+        } catch (final XenAPIException e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
+        } catch (final Exception e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+        return null;
+    }
+
+    public String callHostPluginPremium(final Connection conn, final String cmd, final String... params) {
+        return callHostPlugin(conn, "vmopspremium", cmd, params);
+    }
+
+    protected String callHostPluginThroughMaster(final Connection conn, final String plugin, final String cmd, final String... params) {
+        final Map<String, String> args = new HashMap<String, String>();
+
+        try {
+            final Map<Pool, Pool.Record> poolRecs = Pool.getAllRecords(conn);
+            if (poolRecs.size() != 1) {
+                throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.getUuid());
+            }
+            final Host master = poolRecs.values().iterator().next().master;
+            for (int i = 0; i < params.length; i += 2) {
+                args.put(params[i], params[i + 1]);
+            }
+
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args));
+            }
+            final String result = master.callPlugin(conn, plugin, cmd, args);
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("callHostPlugin Result: " + result);
+            }
+            return result.replace("\n", "");
+        } catch (final Types.HandleInvalid e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle);
+        } catch (final XenAPIException e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e);
+        } catch (final XmlRpcException e) {
+            s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e);
+        }
+        return null;
+    }
+
+    public boolean canBridgeFirewall() {
+        return _canBridgeFirewall;
+    }
+
+    public boolean canBridgeFirewall(final Connection conn) {
+        return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance));
+    }
+
+    public void checkForSuccess(final Connection c, final Task task) throws XenAPIException, XmlRpcException {
+        if (task.getStatus(c) == Types.TaskStatusType.SUCCESS) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") completed");
+            }
+            return;
+        } else {
+            final String msg = "Task failed! Task record: " + task.getRecord(c);
+            s_logger.warn(msg);
+            task.cancel(c);
+            task.destroy(c);
+            throw new Types.BadAsyncResult(msg);
+        }
+    }
+
+    protected boolean checkSR(final Connection conn, final SR sr) {
+        try {
+            final SR.Record srr = sr.getRecord(conn);
+            final Set<PBD> pbds = sr.getPBDs(conn);
+            if (pbds.size() == 0) {
+                final String msg = "There is no PBDs for this SR: " + srr.nameLabel + " on host:" + _host.getUuid();
+                s_logger.warn(msg);
+                return false;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Checking " + srr.nameLabel + " or SR " + srr.uuid + " on " + _host);
+            }
+            if (srr.shared) {
+                if (SRType.NFS.equals(srr.type)) {
+                    final Map<String, String> smConfig = srr.smConfig;
+                    if (!smConfig.containsKey("nosubdir")) {
+                        smConfig.put("nosubdir", "true");
+                        sr.setSmConfig(conn, smConfig);
+                    }
+                }
+
+                final Host host = Host.getByUuid(conn, _host.getUuid());
+                boolean found = false;
+                for (final PBD pbd : pbds) {
+                    final PBD.Record pbdr = pbd.getRecord(conn);
+                    if (host.equals(pbdr.host)) {
+                        if (!pbdr.currentlyAttached) {
+                            pbdPlug(conn, pbd, pbdr.uuid);
+                        }
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    final PBD.Record pbdr = srr.PBDs.iterator().next().getRecord(conn);
+                    pbdr.host = host;
+                    pbdr.uuid = "";
+                    final PBD pbd = PBD.create(conn, pbdr);
+                    pbdPlug(conn, pbd, pbd.getUuid(conn));
+                }
+            } else {
+                for (final PBD pbd : pbds) {
+                    final PBD.Record pbdr = pbd.getRecord(conn);
+                    if (!pbdr.currentlyAttached) {
+                        pbdPlug(conn, pbd, pbdr.uuid);
+                    }
+                }
+            }
+
+        } catch (final Exception e) {
+            final String msg = "checkSR failed host:" + _host + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            return false;
+        }
+        return true;
+    }
+
+    private void CheckXenHostInfo() throws ConfigurationException {
+        final Connection conn = ConnPool.getConnect(_host.getIp(), _username, _password);
+        if (conn == null) {
+            throw new ConfigurationException("Can not create connection to " + _host.getIp());
+        }
+        try {
+            Host.Record hostRec = null;
+            try {
+                final Host host = Host.getByUuid(conn, _host.getUuid());
+                hostRec = host.getRecord(conn);
+                final Pool.Record poolRec = Pool.getAllRecords(conn).values().iterator().next();
+                _host.setPool(poolRec.uuid);
+
+            } catch (final Exception e) {
+                throw new ConfigurationException("Can not get host information from " + _host.getIp());
+            }
+            if (!hostRec.address.equals(_host.getIp())) {
+                final String msg = "Host " + _host.getIp() + " seems be reinstalled, please remove this host and readd";
+                s_logger.error(msg);
+                throw new ConfigurationException(msg);
+            }
+        } finally {
+            try {
+                Session.logout(conn);
+            } catch (final Exception e) {
+            }
+        }
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) {
+        if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) {
+            return cleanupNetworkElementCommand((IpAssocCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    public boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, XmlRpcException {
+        final Host host = Host.getByUuid(conn, _host.getUuid());
+        final Map<VM, VM.Record> vms = VM.getAllRecords(conn);
+        boolean success = true;
+        if (vms != null && !vms.isEmpty()) {
+            for (final Map.Entry<VM, VM.Record> entry : vms.entrySet()) {
+                final VM vm = entry.getKey();
+                final VM.Record vmRec = entry.getValue();
+                if (vmRec.isATemplate || vmRec.isControlDomain) {
+                    continue;
+                }
+
+                if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host) && !isAlienVm(vm, conn)) {
+                    try {
+                        vm.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e);
+                        success = false;
+                    }
+                }
+            }
+        }
+        return success;
+    }
+
+    protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) {
+        final Connection conn = getConnection();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        final String lastIp = cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
+
+        try {
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            for (final IpAddressTO ip : ips) {
+
+                final VM router = getVM(conn, routerName);
+
+                final NicTO nic = new NicTO();
+                nic.setMac(ip.getVifMacAddress());
+                nic.setType(ip.getTrafficType());
+                if (ip.getBroadcastUri() == null) {
+                    nic.setBroadcastType(BroadcastDomainType.Native);
+                } else {
+                    final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                    nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
+                    nic.setBroadcastUri(uri);
+                }
+                nic.setDeviceId(0);
+                nic.setNetworkRateMbps(ip.getNetworkRate());
+                nic.setName(ip.getNetworkName());
+
+                Network network = getNetwork(conn, nic);
+
+                // If we are disassociating the last IP address in the VLAN, we
+                // need
+                // to remove a VIF
+                boolean removeVif = false;
+
+                // there is only one ip in this public vlan and removing it, so
+                // remove the nic
+                if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(lastIp, "true") && !ip.isAdd()) {
+                    final VIF correctVif = getCorrectVif(conn, router, network);
+                    // in isolated network eth2 is the default public interface. We don't want to delete it.
+                    if (correctVif != null && !correctVif.getDevice(conn).equals("2")) {
+                        removeVif = true;
+                    }
+                }
+
+                if (removeVif) {
+
+                    // Determine the correct VIF on DomR to
+                    // associate/disassociate the
+                    // IP address with
+
+                    final VIF correctVif = getCorrectVif(conn, router, network);
+                    if (correctVif != null) {
+                        network = correctVif.getNetwork(conn);
+
+                        // Mark this vif to be removed from network usage
+                        networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn));
+
+                        // Remove the VIF from DomR
+                        correctVif.unplug(conn);
+                        correctVif.destroy(conn);
+
+                        // Disable the VLAN network if necessary
+                        disableVlanNetwork(conn, network);
+                    }
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.debug("Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    public void cleanupTemplateSR(final Connection conn) {
+        Set<PBD> pbds = null;
+        try {
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            pbds = host.getPBDs(conn);
+        } catch (final XenAPIException e) {
+            s_logger.warn("Unable to get the SRs " + e.toString(), e);
+            throw new CloudRuntimeException("Unable to get SRs " + e.toString(), e);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to get SRs " + e.getMessage(), e);
+        }
+        for (final PBD pbd : pbds) {
+            SR sr = null;
+            SR.Record srRec = null;
+            try {
+                sr = pbd.getSR(conn);
+                srRec = sr.getRecord(conn);
+            } catch (final Exception e) {
+                s_logger.warn("pbd.getSR get Exception due to ", e);
+                continue;
+            }
+            final String type = srRec.type;
+            if (srRec.shared) {
+                continue;
+            }
+            if (SRType.NFS.equals(type) || SRType.ISO.equals(type) && srRec.nameDescription.contains("template")) {
+                try {
+                    pbd.unplug(conn);
+                    pbd.destroy(conn);
+                    sr.forget(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("forget SR catch Exception due to ", e);
+                }
+            }
+        }
+    }
+
+    public void cleanUpTmpDomVif(final Connection conn, final Network nw) throws XenAPIException, XmlRpcException {
+
+        final Pair<VM, VM.Record> vm = getControlDomain(conn);
+        final VM dom0 = vm.first();
+        final Set<VIF> dom0Vifs = dom0.getVIFs(conn);
+        for (final VIF v : dom0Vifs) {
+            String vifName = "unknown";
+            try {
+                final VIF.Record vifr = v.getRecord(conn);
+                if (v.getNetwork(conn).getUuid(conn).equals(nw.getUuid(conn))) {
+                    if (vifr != null) {
+                        final Map<String, String> config = vifr.otherConfig;
+                        vifName = config.get("nameLabel");
+                    }
+                    s_logger.debug("A VIF in dom0 for the network is found - so destroy the vif");
+                    v.destroy(conn);
+                    s_logger.debug("Destroy temp dom0 vif" + vifName + " success");
+                }
+            } catch (final Exception e) {
+                s_logger.warn("Destroy temp dom0 vif " + vifName + "failed", e);
+            }
+        }
+    }
+
+    protected VDI cloudVDIcopy(final Connection conn, final VDI vdi, final SR sr, int wait) throws Exception {
+        Task task = null;
+        if (wait == 0) {
+            wait = 2 * 60 * 60;
+        }
+        try {
+            task = vdi.copyAsync(conn, sr);
+            // poll every 1 seconds , timeout after 2 hours
+            waitForTask(conn, task, 1000, (long)wait * 1000);
+            checkForSuccess(conn, task);
+            final VDI dvdi = Types.toVDI(task, conn);
+            return dvdi;
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e.toString());
+                }
+            }
+        }
+    }
+
+    public HashMap<String, String> clusterVMMetaDataSync(final Connection conn) {
+        final HashMap<String, String> vmMetaDatum = new HashMap<String, String>();
+        try {
+            final Map<VM, VM.Record> vm_map = VM.getAllRecords(conn); // USE
+            if (vm_map != null) {
+                for (final VM.Record record : vm_map.values()) {
+                    if (record.isControlDomain || record.isASnapshot || record.isATemplate) {
+                        continue; // Skip DOM0
+                    }
+                    final String platform = StringUtils.mapToString(record.platform);
+                    if (platform.isEmpty()) {
+                        continue; //Skip if platform is null
+                    }
+                    vmMetaDatum.put(record.nameLabel, StringUtils.mapToString(record.platform));
+                }
+            }
+        } catch (final Throwable e) {
+            final String msg = "Unable to get vms through host " + _host.getUuid() + " due to to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+        return vmMetaDatum;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+
+        try {
+            _dcId = Long.parseLong((String)params.get("zone"));
+        } catch (final NumberFormatException e) {
+            throw new ConfigurationException("Unable to get the zone " + params.get("zone"));
+        }
+
+        _host.setUuid((String)params.get("guid"));
+
+        _name = _host.getUuid();
+        _host.setIp((String)params.get("ipaddress"));
+
+        _username = (String)params.get("username");
+        _password.add((String)params.get("password"));
+        _pod = (String)params.get("pod");
+        _cluster = (String)params.get("cluster");
+        _privateNetworkName = (String)params.get("private.network.device");
+        _publicNetworkName = (String)params.get("public.network.device");
+        _guestNetworkName = (String)params.get("guest.network.device");
+        _instance = (String)params.get("instance.name");
+        _securityGroupEnabled = Boolean.parseBoolean((String)params.get("securitygroupenabled"));
+
+        _linkLocalPrivateNetworkName = (String)params.get("private.linkLocal.device");
+        if (_linkLocalPrivateNetworkName == null) {
+            _linkLocalPrivateNetworkName = "cloud_link_local_network";
+        }
+
+        _storageNetworkName1 = (String)params.get("storage.network.device1");
+        _storageNetworkName2 = (String)params.get("storage.network.device2");
+
+        _heartbeatTimeout = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.timeout"), 120);
+        _heartbeatInterval = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.interval"), 60);
+
+        String value = (String)params.get("wait");
+        _wait = NumbersUtil.parseInt(value, 600);
+
+        value = (String)params.get("migratewait");
+        _migratewait = NumbersUtil.parseInt(value, 3600);
+
+        _maxNics = NumbersUtil.parseInt((String)params.get("xenserver.nics.max"), 7);
+
+        if (_pod == null) {
+            throw new ConfigurationException("Unable to get the pod");
+        }
+
+        if (_host.getIp() == null) {
+            throw new ConfigurationException("Unable to get the host address");
+        }
+
+        if (_username == null) {
+            throw new ConfigurationException("Unable to get the username");
+        }
+
+        if (_password.peek() == null) {
+            throw new ConfigurationException("Unable to get the password");
+        }
+
+        if (_host.getUuid() == null) {
+            throw new ConfigurationException("Unable to get the uuid");
+        }
+
+        CheckXenHostInfo();
+
+        storageHandler = buildStorageHandler();
+
+        _vrResource = new VirtualRoutingResource(this);
+        if (!_vrResource.configure(name, params)) {
+            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
+        }
+        return true;
+    }
+
+    /**
+     * This method creates a XenServer network and configures it for being used
+     * as a L2-in-L3 tunneled network
+     */
+    public synchronized Network configureTunnelNetwork(final Connection conn, final Long networkId, final long hostId, final String bridgeName) {
+        try {
+            final Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
+            // Invoke plugin to setup the bridge which will be used by this
+            // network
+            final String bridge = nw.getBridge(conn);
+            final Map<String, String> nwOtherConfig = nw.getOtherConfig(conn);
+            final String configuredHosts = nwOtherConfig.get("ovs-host-setup");
+            boolean configured = false;
+            if (configuredHosts != null) {
+                final String hostIdsStr[] = configuredHosts.split(",");
+                for (final String hostIdStr : hostIdsStr) {
+                    if (hostIdStr.equals(((Long)hostId).toString())) {
+                        configured = true;
+                        break;
+                    }
+                }
+            }
+
+            if (!configured) {
+                String result;
+                if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge, "key", bridgeName, "xs_nw_uuid", nw.getUuid(conn), "cs_host_id",
+                            ((Long)hostId).toString());
+                } else {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, "key", bridgeName, "xs_nw_uuid", nw.getUuid(conn), "cs_host_id", ((Long)hostId).toString());
+                }
+
+                // Note down the fact that the ovs bridge has been setup
+                final String[] res = result.split(":");
+                if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
+                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge);
+                }
+            }
+            return nw;
+        } catch (final Exception e) {
+            s_logger.warn("createandConfigureTunnelNetwork failed", e);
+            return null;
+        }
+    }
+
+    public String connect(final Connection conn, final String vmname, final String ipAddress) {
+        return connect(conn, vmname, ipAddress, 3922);
+    }
+
+    public String connect(final Connection conn, final String vmName, final String ipAddress, final int port) {
+        for (int i = 0; i <= _retry; i++) {
+            try {
+                final Set<VM> vms = VM.getByNameLabel(conn, vmName);
+                if (vms.size() < 1) {
+                    final String msg = "VM " + vmName + " is not running";
+                    s_logger.warn(msg);
+                    return msg;
+                }
+            } catch (final Exception e) {
+                final String msg = "VM.getByNameLabel " + vmName + " failed due to " + e.toString();
+                s_logger.warn(msg, e);
+                return msg;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Trying to connect to " + ipAddress + " attempt " + i + " of " + _retry);
+            }
+            if (pingdomr(conn, ipAddress, Integer.toString(port))) {
+                return null;
+            }
+            try {
+                Thread.sleep(_sleep);
+            } catch (final InterruptedException e) {
+            }
+        }
+        final String msg = "Timeout, Unable to logon to " + ipAddress;
+        s_logger.debug(msg);
+
+        return msg;
+    }
+
+    public String copyVhdFromSecondaryStorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) {
+        final String nameLabel = "cloud-" + UUID.randomUUID().toString();
+        final String results = callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel);
+        String errMsg = null;
+        if (results == null || results.isEmpty()) {
+            errMsg = "copy_vhd_from_secondarystorage return null";
+        } else {
+            final String[] tmp = results.split("#");
+            final String status = tmp[0];
+            if (status.equals("0")) {
+                return tmp[1];
+            } else {
+                errMsg = tmp[1];
+            }
+        }
+        final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1);
+        if (killCopyProcess(conn, source)) {
+            destroyVDIbyNameLabel(conn, nameLabel);
+        }
+        s_logger.warn(errMsg);
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) {
+        final Connection conn = getConnection();
+        final String hostPath = "/tmp/";
+
+        s_logger.debug("Copying VR with ip " + routerIp + " config file into host " + _host.getIp());
+        try {
+            SshHelper.scpTo(_host.getIp(), 22, _username, null, _password.peek(), hostPath, content.getBytes(Charset.defaultCharset()), filename, null);
+        } catch (final Exception e) {
+            s_logger.warn("scp VR config file into host " + _host.getIp() + " failed with exception " + e.getMessage().toString());
+        }
+
+        final String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "srcfilepath", hostPath + filename, "dstfilepath", path);
+        s_logger.debug("VR Config file " + filename + " got created in VR, ip " + routerIp + " with content \n" + content);
+
+        return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5));
+    }
+
+    protected SR createIsoSRbyURI(final Connection conn, final URI uri, final String vmName, final boolean shared) {
+        try {
+            final Map<String, String> deviceConfig = new HashMap<String, String>();
+            String path = uri.getPath();
+            path = path.replace("//", "/");
+            deviceConfig.put("location", uri.getHost() + ":" + path);
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uri.getHost() + path, "iso", "iso", "iso", shared, new HashMap<String, String>());
+            sr.setNameLabel(conn, vmName + "-ISO");
+            sr.setNameDescription(conn, deviceConfig.get("location"));
+
+            sr.scan(conn);
+            return sr;
+        } catch (final XenAPIException e) {
+            final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        } catch (final Exception e) {
+            final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+    }
+
+    protected SR createNfsSRbyURI(final Connection conn, final URI uri, final boolean shared) {
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Creating a " + (shared ? "shared SR for " : "not shared SR for ") + uri);
+            }
+
+            final Map<String, String> deviceConfig = new HashMap<String, String>();
+            String path = uri.getPath();
+            path = path.replace("//", "/");
+            deviceConfig.put("server", uri.getHost());
+            deviceConfig.put("serverpath", path);
+            final String name = UUID.nameUUIDFromBytes(new String(uri.getHost() + path).getBytes()).toString();
+            if (!shared) {
+                final Set<SR> srs = SR.getByNameLabel(conn, name);
+                for (final SR sr : srs) {
+                    final SR.Record record = sr.getRecord(conn);
+                    if (SRType.NFS.equals(record.type) && record.contentType.equals("user") && !record.shared) {
+                        removeSRSync(conn, sr);
+                    }
+                }
+            }
+
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final Map<String, String> smConfig = new HashMap<String, String>();
+            smConfig.put("nosubdir", "true");
+            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, smConfig);
+
+            if (!checkSR(conn, sr)) {
+                throw new Exception("no attached PBD");
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(logX(sr, "Created a SR; UUID is " + sr.getUuid(conn) + " device config is " + deviceConfig));
+            }
+            sr.scan(conn);
+            return sr;
+        } catch (final XenAPIException e) {
+            final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        } catch (final Exception e) {
+            final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+    }
+
+    public VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException {
+
+        if (_host.getSystemvmisouuid() == null) {
+            Set<SR> srs = SR.getByNameLabel(conn, "XenServer Tools");
+            if (srs.size() != 1) {
+                s_logger.debug("Failed to find SR by name 'XenServer Tools', will try to find 'XCP-ng Tools' SR");
+                srs = SR.getByNameLabel(conn, "XCP-ng Tools");
+                if (srs.size() != 1) {
+                    throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools");
+                }
+            }
+            final SR sr = srs.iterator().next();
+            sr.scan(conn);
+
+            final SR.Record srr = sr.getRecord(conn);
+
+            if (_host.getSystemvmisouuid() == null) {
+                for (final VDI vdi : srr.VDIs) {
+                    final VDI.Record vdir = vdi.getRecord(conn);
+                    if (vdir.nameLabel.contains("systemvm.iso")) {
+                        _host.setSystemvmisouuid(vdir.uuid);
+                        break;
+                    }
+                }
+            }
+            if (_host.getSystemvmisouuid() == null) {
+                throw new CloudRuntimeException("can not find systemvmiso");
+            }
+        }
+
+        final VBD.Record cdromVBDR = new VBD.Record();
+        cdromVBDR.VM = vm;
+        cdromVBDR.empty = true;
+        cdromVBDR.bootable = false;
+        cdromVBDR.userdevice = "3";
+        cdromVBDR.mode = Types.VbdMode.RO;
+        cdromVBDR.type = Types.VbdType.CD;
+        final VBD cdromVBD = VBD.create(conn, cdromVBDR);
+        cdromVBD.insert(conn, VDI.getByUuid(conn, _host.getSystemvmisouuid()));
+
+        return cdromVBD;
+    }
+
+    protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder) {
+        final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder);
+        return result != null;
+    }
+
+    String createTemplateFromSnapshot(final Connection conn, final String templatePath, final String snapshotPath, final int wait) {
+        final String tmpltLocalDir = UUID.randomUUID().toString();
+        final String results = callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, "tmpltLocalDir",
+                tmpltLocalDir);
+        String errMsg = null;
+        if (results == null || results.isEmpty()) {
+            errMsg = "create_privatetemplate_from_snapshot return null";
+        } else {
+            final String[] tmp = results.split("#");
+            final String status = tmp[0];
+            if (status.equals("0")) {
+                return results;
+            } else {
+                errMsg = "create_privatetemplate_from_snapshot failed due to " + tmp[1];
+            }
+        }
+        final String source = "cloud_mount/" + tmpltLocalDir;
+        killCopyProcess(conn, source);
+        s_logger.warn(errMsg);
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    public VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException {
+        final Volume.Type type = volume.getType();
+
+        if (vdi == null) {
+            vdi = mount(conn, vmName, volume);
+        }
+
+        if (vdi != null) {
+            if ("detached".equals(vdi.getNameLabel(conn))) {
+                vdi.setNameLabel(conn, vmName + "-DATA");
+            }
+
+            final Map<String, String> smConfig = vdi.getSmConfig(conn);
+            for (final String key : smConfig.keySet()) {
+                if (key.startsWith("host_")) {
+                    vdi.removeFromSmConfig(conn, key);
+                    break;
+                }
+            }
+        }
+        final VBD.Record vbdr = new VBD.Record();
+        vbdr.VM = vm;
+        if (vdi != null) {
+            vbdr.VDI = vdi;
+        } else {
+            vbdr.empty = true;
+        }
+        if (type == Volume.Type.ROOT && bootLoaderType == BootloaderType.PyGrub) {
+            vbdr.bootable = true;
+        } else if (type == Volume.Type.ISO && bootLoaderType == BootloaderType.CD) {
+            vbdr.bootable = true;
+        }
+
+        if (volume.getType() == Volume.Type.ISO) {
+            vbdr.mode = Types.VbdMode.RO;
+            vbdr.type = Types.VbdType.CD;
+            vbdr.userdevice = "3";
+        } else {
+            vbdr.mode = Types.VbdMode.RW;
+            vbdr.type = Types.VbdType.DISK;
+            vbdr.unpluggable = (volume.getType() == Volume.Type.ROOT) ? false : true;
+            vbdr.userdevice = "autodetect";
+            final Long deviceId = volume.getDiskSeq();
+            if (deviceId != null && (!isDeviceUsed(conn, vm, deviceId) || deviceId > 3)) {
+                vbdr.userdevice = deviceId.toString();
+            }
+        }
+        final VBD vbd = VBD.create(conn, vbdr);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("VBD " + vbd.getUuid(conn) + " created for " + volume);
+        }
+
+        return vbd;
+    }
+
+    public VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize) throws Types.XenAPIException, XmlRpcException {
+        final Connection conn = getConnection();
+
+        final VDI.Record vdir = new VDI.Record();
+
+        vdir.nameLabel = vdiNameLabel;
+        vdir.SR = sr;
+        vdir.type = Types.VdiType.USER;
+
+        final long totalSrSpace = sr.getPhysicalSize(conn);
+        final long unavailableSrSpace = sr.getPhysicalUtilisation(conn);
+        final long availableSrSpace = totalSrSpace - unavailableSrSpace;
+
+        if (availableSrSpace < volumeSize) {
+            throw new CloudRuntimeException("Available space for SR cannot be less than " + volumeSize + ".");
+        }
+
+        vdir.virtualSize = volumeSize;
+
+        return VDI.create(conn, vdir);
+    }
+
+    public void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException {
+    }
+
+    public VIF createVif(final Connection conn, final String vmName, final VM vm, final VirtualMachineTO vmSpec, final NicTO nic) throws XmlRpcException, XenAPIException {
+        assert nic.getUuid() != null : "Nic should have a uuid value";
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Creating VIF for " + vmName + " on nic " + nic);
+        }
+        VIF.Record vifr = new VIF.Record();
+        vifr.VM = vm;
+        vifr.device = Integer.toString(nic.getDeviceId());
+        vifr.MAC = nic.getMac();
+
+        // Nicira needs these IDs to find the NIC
+        vifr.otherConfig = new HashMap<String, String>();
+        vifr.otherConfig.put("nicira-iface-id", nic.getUuid());
+        vifr.otherConfig.put("nicira-vm-id", vm.getUuid(conn));
+        // Provide XAPI with the cloudstack vm and nic uids.
+        vifr.otherConfig.put("cloudstack-nic-id", nic.getUuid());
+        if (vmSpec != null) {
+            vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid());
+        }
+
+        // OVS plugin looks at network UUID in the vif 'otherconfig' details to
+        // group VIF's & tunnel ports as part of tier
+        // when bridge is setup for distributed routing
+        vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid());
+
+        // Nuage Vsp needs Virtual Router IP to be passed in the otherconfig
+        // get the virtual router IP information from broadcast uri
+        final URI broadcastUri = nic.getBroadcastUri();
+        if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) {
+            final String path = broadcastUri.getPath();
+            vifr.otherConfig.put("vsp-vr-ip", path.substring(1));
+        }
+        vifr.network = getNetwork(conn, nic);
+
+        if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
+            vifr.qosAlgorithmType = "ratelimit";
+            vifr.qosAlgorithmParams = new HashMap<String, String>();
+            // convert mbs to kilobyte per second
+            vifr.qosAlgorithmParams.put("kbps", Integer.toString(nic.getNetworkRateMbps() * 128));
+        }
+
+        vifr.lockingMode = Types.VifLockingMode.NETWORK_DEFAULT;
+        final VIF vif = VIF.create(conn, vifr);
+        if (s_logger.isDebugEnabled()) {
+            vifr = vif.getRecord(conn);
+            if (vifr != null) {
+                s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId());
+            }
+        }
+
+        return vif;
+    }
+
+    public VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException {
+        final String guestOsTypeName = getGuestOsType(vmSpec.getPlatformEmulator());
+        final Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
+        if (templates == null || templates.isEmpty()) {
+            throw new CloudRuntimeException("Cannot find template " + guestOsTypeName + " on XenServer host");
+        }
+        assert templates.size() == 1 : "Should only have 1 template but found " + templates.size();
+        final VM template = templates.iterator().next();
+
+        final VM.Record vmr = template.getRecord(conn);
+        vmr.affinity = host;
+        vmr.otherConfig.remove("disks");
+        vmr.otherConfig.remove("default_template");
+        vmr.otherConfig.remove("mac_seed");
+        vmr.isATemplate = false;
+        vmr.nameLabel = vmSpec.getName();
+        vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY;
+        vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
+        vmr.otherConfig.put("vm_uuid", vmSpec.getUuid());
+        vmr.VCPUsMax = (long)vmSpec.getCpus(); // FIX ME: In case of dynamic
+        // scaling this VCPU max should
+        // be the minumum of
+        // recommended value for that template and capacity remaining on host
+
+        long recommendedMemoryMin = 0l;
+        long recommendedMemoryMax = 0l;
+
+        Map<String, String> guestOsDetails = vmSpec.getGuestOsDetails();
+
+        if (guestOsDetails != null) {
+            if (guestOsDetails.containsKey("xenserver.dynamicMin")) {
+                recommendedMemoryMin = Long.valueOf(guestOsDetails.get("xenserver.dynamicMin")).longValue();
+            }
+
+            if (guestOsDetails.containsKey("xenserver.dynamicMax")) {
+                recommendedMemoryMax = Long.valueOf(guestOsDetails.get("xenserver.dynamicMax")).longValue();
+            }
+        }
+
+        if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) {
+            // scaling is allowed
+            vmr.memoryStaticMin = getStaticMin(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam(), recommendedMemoryMin);
+            vmr.memoryStaticMax = getStaticMax(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam(), recommendedMemoryMax);
+            vmr.memoryDynamicMin = vmSpec.getMinRam();
+            vmr.memoryDynamicMax = vmSpec.getMaxRam();
+            if (guestOsTypeName.toLowerCase().contains("windows")) {
+                vmr.VCPUsMax = (long)vmSpec.getCpus();
+            } else {
+                if (vmSpec.getVcpuMaxLimit() != null) {
+                    vmr.VCPUsMax = (long)vmSpec.getVcpuMaxLimit();
+                }
+            }
+        } else {
+            // scaling disallowed, set static memory target
+            if (vmSpec.isEnableDynamicallyScaleVm() && !isDmcEnabled(conn, host)) {
+                s_logger.warn("Host " + host.getHostname(conn) + " does not support dynamic scaling, so the vm " + vmSpec.getName() + " is not dynamically scalable");
+            }
+            vmr.memoryStaticMin = vmSpec.getMinRam();
+            vmr.memoryStaticMax = vmSpec.getMaxRam();
+            vmr.memoryDynamicMin = vmSpec.getMinRam();
+            vmr.memoryDynamicMax = vmSpec.getMaxRam();
+
+            vmr.VCPUsMax = (long)vmSpec.getCpus();
+        }
+
+        vmr.VCPUsAtStartup = (long)vmSpec.getCpus();
+        vmr.consoles.clear();
+        vmr.xenstoreData.clear();
+        //Add xenstore data for the NetscalerVM
+        if (vmSpec.getType() == VirtualMachine.Type.NetScalerVm) {
+            NicTO mgmtNic = vmSpec.getNics()[0];
+            if (mgmtNic != null) {
+                Map<String, String> xenstoreData = new HashMap<String, String>(3);
+                xenstoreData.put(XENSTORE_DATA_IP, mgmtNic.getIp().toString().trim());
+                xenstoreData.put(XENSTORE_DATA_GATEWAY, mgmtNic.getGateway().toString().trim());
+                xenstoreData.put(XENSTORE_DATA_NETMASK, mgmtNic.getNetmask().toString().trim());
+                vmr.xenstoreData = xenstoreData;
+            }
+        }
+
+        final VM vm = VM.create(conn, vmr);
+        s_logger.debug("Created VM " + vm.getUuid(conn) + " for " + vmSpec.getName());
+
+        final Map<String, String> vcpuParams = new HashMap<String, String>();
+
+        final Integer speed = vmSpec.getMinSpeed();
+        if (speed != null) {
+            int cpuWeight = _maxWeight; // cpu_weight
+            int utilization = 0; // max CPU cap, default is unlimited
+
+            // weight based allocation, CPU weight is calculated per VCPU
+            cpuWeight = (int)(speed * 0.99 / _host.getSpeed() * _maxWeight);
+            if (cpuWeight > _maxWeight) {
+                cpuWeight = _maxWeight;
+            }
+
+            if (vmSpec.getLimitCpuUse()) {
+                // CPU cap is per VM, so need to assign cap based on the number
+                // of vcpus
+                utilization = (int)(vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100);
+            }
+
+            vcpuParams.put("weight", Integer.toString(cpuWeight));
+            vcpuParams.put("cap", Integer.toString(utilization));
+
+        }
+
+        if (vcpuParams.size() > 0) {
+            vm.setVCPUsParams(conn, vcpuParams);
+        }
+
+        final String bootArgs = vmSpec.getBootArgs();
+        if (bootArgs != null && bootArgs.length() > 0) {
+            // send boot args for PV instances
+            String pvargs = vm.getPVArgs(conn);
+            pvargs = pvargs + vmSpec.getBootArgs().replaceAll(" ", "%");
+            vm.setPVArgs(conn, pvargs);
+            s_logger.debug("PV args are " + pvargs);
+
+            // send boot args into xenstore-data for HVM instances
+            Map<String, String> xenstoreData = new HashMap<>();
+
+            xenstoreData.put(XENSTORE_DATA_CS_INIT, bootArgs);
+            vm.setXenstoreData(conn, xenstoreData);
+            s_logger.debug("HVM args are " + bootArgs);
+        }
+
+        if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) {
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                final DiskTO[] disks = vmSpec.getDisks();
+                for (final DiskTO disk : disks) {
+                    if (disk.getType() == Volume.Type.ISO) {
+                        final TemplateObjectTO iso = (TemplateObjectTO)disk.getData();
+                        final String osType = iso.getGuestOsType();
+                        if (osType != null) {
+                            final String isoGuestOsName = getGuestOsType(vmSpec.getPlatformEmulator());
+                            if (!isoGuestOsName.equals(guestOsTypeName)) {
+                                vmSpec.setBootloader(BootloaderType.PyGrub);
+                            }
+                        }
+                    }
+                }
+            }
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                vm.setPVBootloader(conn, "eliloader");
+                if (!vm.getOtherConfig(conn).containsKey("install-repository")) {
+                    vm.addToOtherConfig(conn, "install-repository", "cdrom");
+                }
+            } else if (vmSpec.getBootloader() == BootloaderType.PyGrub) {
+                vm.setPVBootloader(conn, "pygrub");
+                vm.setPVBootloaderArgs(conn, CitrixHelper.getPVbootloaderArgs(guestOsTypeName));
+            } else {
+                vm.destroy(conn);
+                throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader());
+            }
+        }
+        try {
+            finalizeVmMetaData(vm, conn, vmSpec);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to finalize VM MetaData: " + vmSpec);
+        }
+        return vm;
+    }
+
+    public VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List<VolumeObjectTO> listVolumeTo)
+            throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, Types.OperationNotAllowed, XenAPIException, XmlRpcException {
+        // below is redundant but keeping for consistency and code readabilty
+        final String guestOsTypeName = platformEmulator;
+        if (guestOsTypeName == null) {
+            final String msg = " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        final VM template = getVM(conn, guestOsTypeName);
+        final VM vm = template.createClone(conn, vmName);
+        vm.setIsATemplate(conn, false);
+        final Map<VDI, VolumeObjectTO> vdiMap = new HashMap<VDI, VolumeObjectTO>();
+        for (final VolumeObjectTO volume : listVolumeTo) {
+            final String vdiUuid = volume.getPath();
+            try {
+                final VDI vdi = VDI.getByUuid(conn, vdiUuid);
+                vdiMap.put(vdi, volume);
+            } catch (final Types.UuidInvalid e) {
+                s_logger.warn("Unable to find vdi by uuid: " + vdiUuid + ", skip it");
+            }
+        }
+        for (final Map.Entry<VDI, VolumeObjectTO> entry : vdiMap.entrySet()) {
+            final VDI vdi = entry.getKey();
+            final VolumeObjectTO volumeTO = entry.getValue();
+            final VBD.Record vbdr = new VBD.Record();
+            vbdr.VM = vm;
+            vbdr.VDI = vdi;
+            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
+                vbdr.bootable = true;
+                vbdr.unpluggable = false;
+            } else {
+                vbdr.bootable = false;
+                vbdr.unpluggable = true;
+            }
+            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;
+    }
+
+    protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder) {
+        final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder);
+        return details != null && details.equals("1");
+    }
+
+    protected String deleteSnapshotBackup(final Connection conn, final Long dcId, final Long accountId, final Long volumeId, final String secondaryStorageMountPath, final String backupUUID) {
+
+        // If anybody modifies the formatting below again, I'll skin them
+        final String result = callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), "volumeId",
+                volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath);
+
+        return result;
+    }
+
+    public void destroyPatchVbd(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException {
+        try {
+            if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) {
+                return;
+            }
+            final Set<VM> vms = VM.getByNameLabel(conn, vmName);
+            for (final VM vm : vms) {
+                final Set<VBD> vbds = vm.getVBDs(conn);
+                for (final VBD vbd : vbds) {
+                    if (vbd.getType(conn) == Types.VbdType.CD) {
+                        vbd.eject(conn);
+                        vbd.destroy(conn);
+                        break;
+                    }
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e);
+        }
+    }
+
+    public synchronized void destroyTunnelNetwork(final Connection conn, final Network nw, final long hostId) {
+        try {
+            final String bridge = nw.getBridge(conn);
+            final String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge, "cs_host_id", ((Long)hostId).toString());
+            final String[] res = result.split(":");
+            if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
+                throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge + ":" + result);
+            }
+            return;
+        } catch (final Exception e) {
+            s_logger.warn("destroyTunnelNetwork failed:", e);
+            return;
+        }
+    }
+
+    void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) {
+        try {
+            final Set<VDI> vdis = VDI.getByNameLabel(conn, nameLabel);
+            if (vdis.size() != 1) {
+                s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel);
+                return;
+            }
+            for (final VDI vdi : vdis) {
+                try {
+                    vdi.destroy(conn);
+                } catch (final Exception e) {
+                    final String msg = "Failed to destroy VDI : " + nameLabel + "due to " + e.toString() + "\n Force deleting VDI using system 'rm' command";
+                    s_logger.warn(msg);
+                    try {
+                        final String srUUID = vdi.getSR(conn).getUuid(conn);
+                        final String vdiUUID = vdi.getUuid(conn);
+                        final String vdifile = "/var/run/sr-mount/" + srUUID + "/" + vdiUUID + ".vhd";
+                        callHostPluginAsync(conn, "vmopspremium", "remove_corrupt_vdi", 10, "vdifile", vdifile);
+                    } catch (final Exception e2) {
+                        s_logger.warn(e2);
+                    }
+                }
+            }
+        } catch (final Exception e) {
+        }
+    }
+
+    public void disableVlanNetwork(final Connection conn, final Network network) {
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    public boolean doPingTest(final Connection conn, final String computingHostIp) {
+        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
+        try {
+            sshConnection.connect(null, 60000, 60000);
+            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
+                throw new CloudRuntimeException("Unable to authenticate");
+            }
+
+            final String cmd = "ping -c 2 " + computingHostIp;
+            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+                throw new CloudRuntimeException("Cannot ping host " + computingHostIp + " from host " + _host.getIp());
+            }
+            return true;
+        } catch (final Exception e) {
+            s_logger.warn("Catch exception " + e.toString(), e);
+            return false;
+        } finally {
+            sshConnection.close();
+        }
+    }
+
+    public boolean doPingTest(final Connection conn, final String domRIp, final String vmIp) {
+        final String args = "-i " + domRIp + " -p " + vmIp;
+        final String result = callHostPlugin(conn, "vmops", "pingtest", "args", args);
+        if (result == null || result.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * enableVlanNetwork creates a Network object, Vlan object, and thereby a
+     * tagged PIF object in Xapi.
+     *
+     * In XenServer, VLAN is added by - Create a network, which is unique
+     * cluster wide. - Find the PIF that you want to create the VLAN on. -
+     * Create a VLAN using the network and the PIF. As a result of this
+     * operation, a tagged PIF object is also created.
+     *
+     * Here is a list of problems with clustered Xapi implementation that we are
+     * trying to circumvent. - There can be multiple Networks with the same
+     * name-label so searching using name-label is not unique. - There are no
+     * other ways to search for Networks other than listing all of them which is
+     * not efficient in our implementation because we can have over 4000 VLAN
+     * networks. - In a clustered situation, it's possible for both hosts to
+     * detect that the Network is missing and both creates it. This causes a lot
+     * of problems as one host may be using one Network and another may be using
+     * a different network for their VMs. This causes problems in migration
+     * because the VMs are logically attached to different networks in Xapi's
+     * database but in reality, they are attached to the same network.
+     *
+     * To work around these problems, we do the following.
+     *
+     * - When creating the VLAN network, we name it as VLAN-UUID of the Network
+     * it is created on-VLAN Tag. Because VLAN tags is unique with one
+     * particular network, this is a unique name-label to quickly retrieve the
+     * the VLAN network with when we need it again. - When we create the VLAN
+     * network, we add a timestamp and a random number as a tag into the
+     * network. Then instead of creating VLAN on that network, we actually
+     * retrieve the Network again and this time uses the VLAN network with
+     * lowest timestamp or lowest random number as the VLAN network. This allows
+     * VLAN creation to happen on multiple hosts concurrently but even if two
+     * VLAN networks were created with the same name, only one of them is used.
+     *
+     * One cavaet about this approach is that it relies on the timestamp to be
+     * relatively accurate among different hosts.
+     *
+     * @param conn
+     *            Xapi Connection
+     * @param tag
+     *            VLAN tag
+     * @param network
+     *            network on this host to create the VLAN on.
+     * @return VLAN Network created.
+     * @throws XenAPIException
+     * @throws XmlRpcException
+     */
+    protected Network enableVlanNetwork(final Connection conn, final long tag, final XsLocalNetwork network) throws XenAPIException, XmlRpcException {
+        Network vlanNetwork = null;
+        final String oldName = "VLAN" + Long.toString(tag);
+        final String newName = "VLAN-" + network.getNetworkRecord(conn).uuid + "-" + tag;
+        XsLocalNetwork vlanNic = getNetworkByName(conn, newName);
+        if (vlanNic == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Couldn't find vlan network with the new name so trying old name: " + oldName);
+            }
+            vlanNic = getNetworkByName(conn, oldName);
+            if (vlanNic != null) {
+                s_logger.info("Renaming VLAN with old name " + oldName + " to " + newName);
+                vlanNic.getNetwork().setNameLabel(conn, newName);
+            }
+        }
+        if (vlanNic == null) { // Can't find it, then create it.
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.getIp());
+            }
+            final Network.Record nwr = new Network.Record();
+            nwr.nameLabel = newName;
+            nwr.tags = new HashSet<String>();
+            nwr.tags.add(generateTimeStamp());
+            vlanNetwork = Network.create(conn, nwr);
+            vlanNic = getNetworkByName(conn, newName);
+            if (vlanNic == null) { // Still vlanNic is null means we could not
+                // create it for some reason and no exception
+                // capture happened.
+                throw new CloudRuntimeException("Could not find/create vlan network with name: " + newName);
+            }
+        }
+
+        final PIF nPif = network.getPif(conn);
+        final PIF.Record nPifr = network.getPifRecord(conn);
+
+        vlanNetwork = vlanNic.getNetwork();
+        if (vlanNic.getPif(conn) != null) {
+            return vlanNetwork;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Creating VLAN " + tag + " on host " + _host.getIp() + " on device " + nPifr.device);
+        }
+        final VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork);
+        if (vlan != null) {
+            final VLAN.Record vlanr = vlan.getRecord(conn);
+            if (vlanr != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("VLAN is created for " + tag + ".  The uuid is " + vlanr.uuid);
+                }
+            }
+        }
+        return vlanNetwork;
+    }
+
+    @Override
+    public RebootAnswer execute(final RebootCommand cmd) {
+        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixRebootCommandWrapper. "
+                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
+    }
+
+    @Override
+    public StartAnswer execute(final StartCommand cmd) {
+        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStartCommandWrapper. "
+                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
+    }
+
+    @Override
+    public StopAnswer execute(final StopCommand cmd) {
+        throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStopCommandWrapper. "
+                + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper.");
+    }
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIP, final String script, final String args) {
+        // Timeout is 120 seconds by default
+        return executeInVR(routerIP, script, args, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
+    }
+
+    @Override
+    public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final Duration timeout) {
+        Pair<Boolean, String> result;
+        String cmdline = "/opt/cloud/bin/router_proxy.sh " + script + " " + routerIP + " " + args;
+        // semicolon need to be escape for bash
+        cmdline = cmdline.replaceAll(";", "\\\\;");
+        try {
+            s_logger.debug("Executing command in VR: " + cmdline);
+            result = SshHelper.sshExecute(_host.getIp(), 22, _username, null, _password.peek(), cmdline, VRScripts.CONNECTION_TIMEOUT, VRScripts.CONNECTION_TIMEOUT, timeout);
+        } catch (final Exception e) {
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(result.first(), result.second());
+    }
+
+    @Override
+    public Answer executeRequest(final Command cmd) {
+        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
+        try {
+            return wrapper.execute(cmd, this);
+        } catch (final Exception e) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) {
+        final StringBuilder caps = new StringBuilder();
+        try {
+
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final Host.Record hr = host.getRecord(conn);
+
+            Map<String, String> details = cmd.getHostDetails();
+            if (details == null) {
+                details = new HashMap<String, String>();
+            }
+
+            String productBrand = hr.softwareVersion.get("product_brand");
+            if (productBrand == null) {
+                productBrand = hr.softwareVersion.get("platform_name");
+            }
+            details.put("product_brand", productBrand);
+            details.put("product_version", _host.getProductVersion());
+            if (hr.softwareVersion.get("product_version_text_short") != null) {
+                details.put("product_version_text_short", hr.softwareVersion.get("product_version_text_short"));
+                cmd.setHypervisorVersion(hr.softwareVersion.get("product_version_text_short"));
+
+                cmd.setHypervisorVersion(_host.getProductVersion());
+            }
+            if (_privateNetworkName != null) {
+                details.put("private.network.device", _privateNetworkName);
+            }
+
+            cmd.setHostDetails(details);
+            cmd.setName(hr.nameLabel);
+            cmd.setGuid(_host.getUuid());
+            cmd.setPool(_host.getPool());
+            cmd.setDataCenter(Long.toString(_dcId));
+            for (final String cap : hr.capabilities) {
+                if (cap.length() > 0) {
+                    caps.append(cap).append(" , ");
+                }
+            }
+            if (caps.length() > 0) {
+                caps.delete(caps.length() - 3, caps.length());
+            }
+            cmd.setCaps(caps.toString());
+
+            cmd.setSpeed(_host.getSpeed());
+            cmd.setCpuSockets(_host.getCpuSockets());
+            cmd.setCpus(_host.getCpus());
+
+            final HostMetrics hm = host.getMetrics(conn);
+
+            long ram = 0;
+            long dom0Ram = 0;
+            ram = hm.getMemoryTotal(conn);
+            final Set<VM> vms = host.getResidentVMs(conn);
+            for (final VM vm : vms) {
+                if (vm.getIsControlDomain(conn)) {
+                    dom0Ram = vm.getMemoryStaticMax(conn);
+                    break;
+                }
+            }
+
+            ram = (long)((ram - dom0Ram - _xsMemoryUsed) * _xsVirtualizationFactor);
+            cmd.setMemory(ram);
+            cmd.setDom0MinMemory(dom0Ram);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Total Ram: " + ram + " dom0 Ram: " + dom0Ram);
+            }
+
+            PIF pif = PIF.getByUuid(conn, _host.getPrivatePif());
+            PIF.Record pifr = pif.getRecord(conn);
+            if (pifr.IP != null && pifr.IP.length() > 0) {
+                cmd.setPrivateIpAddress(pifr.IP);
+                cmd.setPrivateMacAddress(pifr.MAC);
+                cmd.setPrivateNetmask(pifr.netmask);
+            } else {
+                cmd.setPrivateIpAddress(_host.getIp());
+                cmd.setPrivateMacAddress(pifr.MAC);
+                cmd.setPrivateNetmask("255.255.255.0");
+            }
+
+            pif = PIF.getByUuid(conn, _host.getPublicPif());
+            pifr = pif.getRecord(conn);
+            if (pifr.IP != null && pifr.IP.length() > 0) {
+                cmd.setPublicIpAddress(pifr.IP);
+                cmd.setPublicMacAddress(pifr.MAC);
+                cmd.setPublicNetmask(pifr.netmask);
+            }
+
+            if (_host.getStoragePif1() != null) {
+                pif = PIF.getByUuid(conn, _host.getStoragePif1());
+                pifr = pif.getRecord(conn);
+                if (pifr.IP != null && pifr.IP.length() > 0) {
+                    cmd.setStorageIpAddress(pifr.IP);
+                    cmd.setStorageMacAddress(pifr.MAC);
+                    cmd.setStorageNetmask(pifr.netmask);
+                }
+            }
+
+            if (_host.getStoragePif2() != null) {
+                pif = PIF.getByUuid(conn, _host.getStoragePif2());
+                pifr = pif.getRecord(conn);
+                if (pifr.IP != null && pifr.IP.length() > 0) {
+                    cmd.setStorageIpAddressDeux(pifr.IP);
+                    cmd.setStorageMacAddressDeux(pifr.MAC);
+                    cmd.setStorageNetmaskDeux(pifr.netmask);
+                }
+            }
+
+            final Map<String, String> configs = hr.otherConfig;
+            cmd.setIqn(configs.get("iscsi_iqn"));
+
+            cmd.setPod(_pod);
+            cmd.setVersion(CitrixResourceBase.class.getPackage().getImplementationVersion());
+
+            try {
+                final String cmdLine = "xe sm-list | grep \"resigning of duplicates\"";
+
+                final XenServerUtilitiesHelper xenServerUtilitiesHelper = getXenServerUtilitiesHelper();
+
+                Pair<Boolean, String> result = xenServerUtilitiesHelper.executeSshWrapper(_host.getIp(), 22, _username, null, getPwdFromQueue(), cmdLine);
+
+                boolean supportsClonedVolumes = result != null && result.first() != null && result.first() && result.second() != null && result.second().length() > 0;
+
+                cmd.setSupportsClonedVolumes(supportsClonedVolumes);
+            } catch (NumberFormatException ex) {
+                s_logger.warn("Issue sending 'xe sm-list' via SSH to XenServer host: " + ex.getMessage());
+            }
+        } catch (final XmlRpcException e) {
+            throw new CloudRuntimeException("XML RPC Exception: " + e.getMessage(), e);
+        } catch (final XenAPIException e) {
+            throw new CloudRuntimeException("XenAPIException: " + e.toString(), e);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Exception: " + e.toString(), e);
+        }
+    }
+
+    protected void finalizeVmMetaData(final VM vm, final Connection conn, final VirtualMachineTO vmSpec) throws Exception {
+
+        final Map<String, String> details = vmSpec.getDetails();
+        if (details != null) {
+            final String platformstring = details.get("platform");
+            if (platformstring != null && !platformstring.isEmpty()) {
+                final Map<String, String> platform = StringUtils.stringToMap(platformstring);
+                vm.setPlatform(conn, platform);
+            } else {
+                final String timeoffset = details.get("timeoffset");
+                if (timeoffset != null) {
+                    final Map<String, String> platform = vm.getPlatform(conn);
+                    platform.put("timeoffset", timeoffset);
+                    vm.setPlatform(conn, platform);
+                }
+                final String coresPerSocket = details.get("cpu.corespersocket");
+                if (coresPerSocket != null) {
+                    final Map<String, String> platform = vm.getPlatform(conn);
+                    platform.put("cores-per-socket", coresPerSocket);
+                    vm.setPlatform(conn, platform);
+                }
+            }
+            if (!BootloaderType.CD.equals(vmSpec.getBootloader())) {
+                final String xenservertoolsversion = details.get("hypervisortoolsversion");
+                if ((xenservertoolsversion == null || !xenservertoolsversion.equalsIgnoreCase("xenserver61")) && vmSpec.getGpuDevice() == null) {
+                    final Map<String, String> platform = vm.getPlatform(conn);
+                    platform.remove("device_id");
+                    vm.setPlatform(conn, platform);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method just creates a XenServer network following the tunnel network
+     * naming convention
+     */
+    public synchronized Network findOrCreateTunnelNetwork(final Connection conn, final String nwName) {
+        try {
+            Network nw = null;
+            final Network.Record rec = new Network.Record();
+            final Set<Network> networks = Network.getByNameLabel(conn, nwName);
+
+            if (networks.size() == 0) {
+                rec.nameDescription = "tunnel network id# " + nwName;
+                rec.nameLabel = nwName;
+                // Initialize the ovs-host-setup to avoid error when doing
+                // get-param in plugin
+                final Map<String, String> otherConfig = new HashMap<String, String>();
+                otherConfig.put("ovs-host-setup", "");
+                // Mark 'internal network' as shared so bridge gets
+                // automatically created on each host in the cluster
+                // when VM with vif connected to this internal network is
+                // started
+                otherConfig.put("assume_network_is_shared", "true");
+                rec.otherConfig = otherConfig;
+                nw = Network.create(conn, rec);
+                s_logger.debug("### XenServer network for tunnels created:" + nwName);
+            } else {
+                nw = networks.iterator().next();
+                s_logger.debug("XenServer network for tunnels found:" + nwName);
+            }
+            return nw;
+        } catch (final Exception e) {
+            s_logger.warn("createTunnelNetwork failed", e);
+            return null;
+        }
+    }
+
+    void forceShutdownVM(final Connection conn, final VM vm) {
+        try {
+            final Long domId = vm.getDomid(conn);
+            callHostPlugin(conn, "vmopspremium", "forceShutdownVM", "domId", domId.toString());
+            vm.powerStateReset(conn);
+            vm.destroy(conn);
+        } catch (final Exception e) {
+            final String msg = "forceShutdown failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    protected String generateTimeStamp() {
+        return new StringBuilder("CsCreateTime-").append(System.currentTimeMillis()).append("-").append(Rand.nextInt(Integer.MAX_VALUE)).toString();
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return _agentControl;
+    }
+
+    protected String getArgsString(final Map<String, String> args) {
+        final StringBuilder argString = new StringBuilder();
+        for (final Map.Entry<String, String> arg : args.entrySet()) {
+            argString.append(arg.getKey() + ": " + arg.getValue() + ", ");
+        }
+        return argString.toString();
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        return null;
+    }
+
+    public Connection getConnection() {
+        return ConnPool.connect(_host.getUuid(), _host.getPool(), _host.getIp(), _username, _password, _wait);
+    }
+
+    protected Pair<VM, VM.Record> getControlDomain(final Connection conn) throws XenAPIException, XmlRpcException {
+        final Host host = Host.getByUuid(conn, _host.getUuid());
+        Set<VM> vms = null;
+        vms = host.getResidentVMs(conn);
+        for (final VM vm : vms) {
+            if (vm.getIsControlDomain(conn)) {
+                return new Pair<VM, VM.Record>(vm, vm.getRecord(conn));
+            }
+        }
+
+        throw new CloudRuntimeException("Com'on no control domain?  What the crap?!#@!##$@");
+    }
+
+    protected VIF getCorrectVif(final Connection conn, final VM router, final IpAddressTO ip) throws XmlRpcException, XenAPIException {
+        final NicTO nic = new NicTO();
+        nic.setType(ip.getTrafficType());
+        nic.setName(ip.getNetworkName());
+        if (ip.getBroadcastUri() == null) {
+            nic.setBroadcastType(BroadcastDomainType.Native);
+        } else {
+            final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+            nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
+            nic.setBroadcastUri(uri);
+        }
+        final Network network = getNetwork(conn, nic);
+        // Determine the correct VIF on DomR to associate/disassociate the
+        // IP address with
+        final Set<VIF> routerVIFs = router.getVIFs(conn);
+        for (final VIF vif : routerVIFs) {
+            final Network vifNetwork = vif.getNetwork(conn);
+            if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) {
+                return vif;
+            }
+        }
+        return null;
+    }
+
+    protected VIF getCorrectVif(final Connection conn, final VM router, final Network network) throws XmlRpcException, XenAPIException {
+        final Set<VIF> routerVIFs = router.getVIFs(conn);
+        for (final VIF vif : routerVIFs) {
+            final Network vifNetwork = vif.getNetwork(conn);
+            if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) {
+                return vif;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(final long id) {
+        try {
+            if (!pingXAPI()) {
+                Thread.sleep(1000);
+                if (!pingXAPI()) {
+                    s_logger.warn("can not ping xenserver " + _host.getUuid());
+                    return null;
+                }
+            }
+            final Connection conn = getConnection();
+            if (!_canBridgeFirewall && !_isOvs) {
+                return new PingRoutingCommand(getType(), id, getHostVmStateReport(conn));
+            } else if (_isOvs) {
+                final List<Pair<String, Long>> ovsStates = ovsFullSyncStates();
+                return new PingRoutingWithOvsCommand(getType(), id, getHostVmStateReport(conn), ovsStates);
+            } else {
+                final HashMap<String, Pair<Long, Long>> nwGrpStates = syncNetworkGroups(conn, id);
+                return new PingRoutingWithNwGroupsCommand(getType(), id, getHostVmStateReport(conn), nwGrpStates);
+            }
+        } catch (final Exception e) {
+            s_logger.warn("Unable to get current status", e);
+            return null;
+        }
+    }
+
+    protected double getDataAverage(final Node dataNode, final int col, final int numRows) {
+        double value = 0;
+        final double dummy = 0;
+        int numRowsUsed = 0;
+        for (int row = 0; row < numRows; row++) {
+            final Node data = dataNode.getChildNodes().item(numRows - 1 - row).getChildNodes().item(col + 1);
+            final Double currentDataAsDouble = Double.valueOf(getXMLNodeValue(data));
+            if (!currentDataAsDouble.equals(Double.NaN)) {
+                numRowsUsed += 1;
+                value += currentDataAsDouble;
+            }
+        }
+
+        if (numRowsUsed == 0) {
+            if (!Double.isInfinite(value) && !Double.isNaN(value)) {
+                return value;
+            } else {
+                s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows=0");
+                return dummy;
+            }
+        } else {
+            if (!Double.isInfinite(value / numRowsUsed) && !Double.isNaN(value / numRowsUsed)) {
+                return value / numRowsUsed;
+            } else {
+                s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows>0");
+                return dummy;
+            }
+        }
+
+    }
+
+    public HashMap<String, HashMap<String, VgpuTypesInfo>> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException {
+        return null;
+    }
+
+    protected String getGuestOsType(String platformEmulator) {
+        if (org.apache.commons.lang.StringUtils.isBlank(platformEmulator)) {
+            s_logger.debug("no guest OS type, start it as HVM guest");
+            platformEmulator = "Other install media";
+        }
+        return platformEmulator;
+    }
+
+    public XsHost getHost() {
+        return _host;
+    }
+
+    public int getMigrateWait() {
+        return _migratewait;
+    }
+
+    public StorageSubsystemCommandHandler getStorageHandler() {
+        return storageHandler;
+    }
+
+    protected boolean getHostInfo(final Connection conn) throws IllegalArgumentException {
+        try {
+            final Host myself = Host.getByUuid(conn, _host.getUuid());
+            Set<HostCpu> hcs = null;
+            for (int i = 0; i < 10; i++) {
+                hcs = myself.getHostCPUs(conn);
+                if (hcs != null) {
+                    _host.setCpus(hcs.size());
+                    if (_host.getCpus() > 0) {
+                        break;
+                    }
+                }
+                Thread.sleep(5000);
+            }
+            if (_host.getCpus() <= 0) {
+                throw new CloudRuntimeException("Cannot get the numbers of cpu from XenServer host " + _host.getIp());
+            }
+            final Map<String, String> cpuInfo = myself.getCpuInfo(conn);
+            if (cpuInfo.get("socket_count") != null) {
+                _host.setCpuSockets(Integer.parseInt(cpuInfo.get("socket_count")));
+            }
+            // would hcs be null we would have thrown an exception on condition
+            // (_host.getCpus() <= 0) by now
+            for (final HostCpu hc : hcs) {
+                _host.setSpeed(hc.getSpeed(conn).intValue());
+                break;
+            }
+            final Host.Record hr = myself.getRecord(conn);
+            _host.setProductVersion(CitrixHelper.getProductVersion(hr));
+
+            final XsLocalNetwork privateNic = getManagementNetwork(conn);
+            _privateNetworkName = privateNic.getNetworkRecord(conn).nameLabel;
+            _host.setPrivatePif(privateNic.getPifRecord(conn).uuid);
+            _host.setPrivateNetwork(privateNic.getNetworkRecord(conn).uuid);
+            _host.setSystemvmisouuid(null);
+
+            XsLocalNetwork guestNic = null;
+            if (_guestNetworkName != null && !_guestNetworkName.equals(_privateNetworkName)) {
+                guestNic = getNetworkByName(conn, _guestNetworkName);
+                if (guestNic == null) {
+                    s_logger.warn("Unable to find guest network " + _guestNetworkName);
+                    throw new IllegalArgumentException("Unable to find guest network " + _guestNetworkName + " for host " + _host.getIp());
+                }
+            } else {
+                guestNic = privateNic;
+                _guestNetworkName = _privateNetworkName;
+            }
+            _host.setGuestNetwork(guestNic.getNetworkRecord(conn).uuid);
+            _host.setGuestPif(guestNic.getPifRecord(conn).uuid);
+
+            XsLocalNetwork publicNic = null;
+            if (_publicNetworkName != null && !_publicNetworkName.equals(_guestNetworkName)) {
+                publicNic = getNetworkByName(conn, _publicNetworkName);
+                if (publicNic == null) {
+                    s_logger.warn("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp());
+                    throw new IllegalArgumentException("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp());
+                }
+            } else {
+                publicNic = guestNic;
+                _publicNetworkName = _guestNetworkName;
+            }
+            _host.setPublicPif(publicNic.getPifRecord(conn).uuid);
+            _host.setPublicNetwork(publicNic.getNetworkRecord(conn).uuid);
+            if (_storageNetworkName1 == null) {
+                _storageNetworkName1 = _guestNetworkName;
+            }
+            XsLocalNetwork storageNic1 = null;
+            storageNic1 = getNetworkByName(conn, _storageNetworkName1);
+            if (storageNic1 == null) {
+                s_logger.warn("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp());
+                throw new IllegalArgumentException("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp());
+            } else {
+                _host.setStorageNetwork1(storageNic1.getNetworkRecord(conn).uuid);
+                _host.setStoragePif1(storageNic1.getPifRecord(conn).uuid);
+            }
+
+            XsLocalNetwork storageNic2 = null;
+            if (_storageNetworkName2 != null) {
+                storageNic2 = getNetworkByName(conn, _storageNetworkName2);
+                if (storageNic2 != null) {
+                    _host.setStoragePif2(storageNic2.getPifRecord(conn).uuid);
+                }
+            }
+
+            s_logger.info("XenServer Version is " + _host.getProductVersion() + " for host " + _host.getIp());
+            s_logger.info("Private Network is " + _privateNetworkName + " for host " + _host.getIp());
+            s_logger.info("Guest Network is " + _guestNetworkName + " for host " + _host.getIp());
+            s_logger.info("Public Network is " + _publicNetworkName + " for host " + _host.getIp());
+
+            return true;
+        } catch (final XenAPIException e) {
+            s_logger.warn("Unable to get host information for " + _host.getIp(), e);
+            return false;
+        } catch (final Exception e) {
+            s_logger.warn("Unable to get host information for " + _host.getIp(), e);
+            return false;
+        }
+    }
+
+    public HostStatsEntry getHostStats(final Connection conn, final GetHostStatsCommand cmd, final String hostGuid, final long hostId) {
+
+        final HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0);
+        final Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1
+        // for host
+
+        if (rrdData == null) {
+            return null;
+        }
+
+        final Integer numRows = (Integer)rrdData[0];
+        final Integer numColumns = (Integer)rrdData[1];
+        final Node legend = (Node)rrdData[2];
+        final Node dataNode = (Node)rrdData[3];
+
+        final NodeList legendChildren = legend.getChildNodes();
+        for (int col = 0; col < numColumns; col++) {
+
+            if (legendChildren == null || legendChildren.item(col) == null) {
+                continue;
+            }
+
+            final String columnMetadata = getXMLNodeValue(legendChildren.item(col));
+
+            if (columnMetadata == null) {
+                continue;
+            }
+
+            final String[] columnMetadataList = columnMetadata.split(":");
+
+            if (columnMetadataList.length != 4) {
+                continue;
+            }
+
+            final String type = columnMetadataList[1];
+            final String param = columnMetadataList[3];
+
+            if (type.equalsIgnoreCase("host")) {
+
+                if (param.matches("pif_eth0_rx")) {
+                    hostStats.setNetworkReadKBs(getDataAverage(dataNode, col, numRows) / 1000);
+                } else if (param.matches("pif_eth0_tx")) {
+                    hostStats.setNetworkWriteKBs(getDataAverage(dataNode, col, numRows) / 1000);
+                } else if (param.contains("memory_total_kib")) {
+                    hostStats.setTotalMemoryKBs(getDataAverage(dataNode, col, numRows));
+                } else if (param.contains("memory_free_kib")) {
+                    hostStats.setFreeMemoryKBs(getDataAverage(dataNode, col, numRows));
+                } else if (param.matches("cpu_avg")) {
+                    // hostStats.setNumCpus(hostStats.getNumCpus() + 1);
+                    hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows));
+                }
+
+                /*
+                 * if (param.contains("loadavg")) {
+                 * hostStats.setAverageLoad((hostStats.getAverageLoad() +
+                 * getDataAverage(dataNode, col, numRows))); }
+                 */
+            }
+        }
+
+        // add the host cpu utilization
+        /*
+         * if (hostStats.getNumCpus() != 0) {
+         * hostStats.setCpuUtilization(hostStats.getCpuUtilization() /
+         * hostStats.getNumCpus()); s_logger.debug("Host cpu utilization " +
+         * hostStats.getCpuUtilization()); }
+         */
+
+        return hostStats;
+    }
+
+    protected HashMap<String, HostVmStateReportEntry> getHostVmStateReport(final Connection conn) {
+        final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        Map<VM, VM.Record> vm_map = null;
+        for (int i = 0; i < 2; i++) {
+            try {
+                vm_map = VM.getAllRecords(conn);
+                break;
+            } catch (final Throwable e) {
+                s_logger.warn("Unable to get vms", e);
+            }
+            try {
+                Thread.sleep(1000);
+            } catch (final InterruptedException ex) {
+
+            }
+        }
+
+        if (vm_map == null) {
+            return vmStates;
+        }
+        for (final VM.Record record : vm_map.values()) {
+            if (record.isControlDomain || record.isASnapshot || record.isATemplate) {
+                continue; // Skip DOM0
+            }
+
+            final VmPowerState ps = record.powerState;
+            final Host host = record.residentOn;
+            String host_uuid = null;
+            if (!isRefNull(host)) {
+                try {
+                    host_uuid = host.getUuid(conn);
+                } catch (final BadServerResponse e) {
+                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
+                } catch (final XenAPIException e) {
+                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
+                } catch (final XmlRpcException e) {
+                    s_logger.error("Failed to get host uuid for host " + host.toWireString(), e);
+                }
+
+                if (host_uuid.equalsIgnoreCase(_host.getUuid())) {
+                    vmStates.put(record.nameLabel, new HostVmStateReportEntry(convertToPowerState(ps), host_uuid));
+                }
+            }
+        }
+
+        return vmStates;
+    }
+
+    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername, final String chapInitiatorPassword,
+            final boolean ignoreIntroduceException) {
+
+        return getIscsiSR(conn, srNameLabel, target, path, chapInitiatorUsername, chapInitiatorPassword, false, SRType.LVMOISCSI.toString(), ignoreIntroduceException);
+    }
+
+    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername, final String chapInitiatorPassword,
+            final boolean resignature, final boolean ignoreIntroduceException) {
+
+        return getIscsiSR(conn, srNameLabel, target, path, chapInitiatorUsername, chapInitiatorPassword, resignature, SRType.LVMOISCSI.toString(), ignoreIntroduceException);
+    }
+
+    public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername, final String chapInitiatorPassword,
+            final boolean resignature, final String srType, final boolean ignoreIntroduceException) {
+        synchronized (srNameLabel.intern()) {
+            final Map<String, String> deviceConfig = new HashMap<String, String>();
+            try {
+                if (path.endsWith("/")) {
+                    path = path.substring(0, path.length() - 1);
+                }
+
+                final String tmp[] = path.split("/");
+                if (tmp.length != 3) {
+                    final String msg = "Wrong iscsi path " + path + " it should be /targetIQN/LUN";
+                    s_logger.warn(msg);
+                    throw new CloudRuntimeException(msg);
+                }
+                final String targetiqn = tmp[1].trim();
+                final String lunid = tmp[2].trim();
+                String scsiid = "";
+
+                //Throws an exception if SR already exists and is attached
+                checkIfIscsiSrExisits(conn, srNameLabel, target, targetiqn, lunid);
+
+                // We now know the SR is not attached to the XenServer. We probe the
+                // LUN to see if an SR was already exists on it, if so, we just
+                // attach it or else we create a brand new SR
+
+                deviceConfig.put("target", target);
+                deviceConfig.put("targetIQN", targetiqn);
+
+                if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorPassword)) {
+                    deviceConfig.put("chapuser", chapInitiatorUsername);
+                    deviceConfig.put("chappassword", chapInitiatorPassword);
+                }
+
+                final Host host = Host.getByUuid(conn, _host.getUuid());
+                final Map<String, String> smConfig = new HashMap<String, String>();
+                SR sr = null;
+                String pooluuid = null;
+
+                if (SRType.LVMOISCSI.equals(srType)) {
+                    scsiid = probeScisiId(conn, host, deviceConfig, srType, srNameLabel, lunid, smConfig);
+                    deviceConfig.put("SCSIid", scsiid);
+
+                    String result = SR.probe(conn, host, deviceConfig, srType, smConfig);
+                    if (result.indexOf("<UUID>") != -1) {
+                        pooluuid = result.substring(result.indexOf("<UUID>") + 6, result.indexOf("</UUID>")).trim();
+                    }
+                }
+
+                if (pooluuid == null || pooluuid.length() != 36) {
+                    sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, srType, "user", true, smConfig);
+                } else {
+                    if (resignature) {
+                        // We resignature the SR for managed storage if needed. At the end of this
+                        // we have an SR which is ready to be attached. For VHDoISCSI SR,
+                        // we don't need to resignature
+                        pooluuid = resignatureIscsiSr(conn, host, deviceConfig, srNameLabel, smConfig);
+                    }
+                    sr = introduceAndPlugIscsiSr(conn, pooluuid, srNameLabel, srType, smConfig, deviceConfig, ignoreIntroduceException);
+                }
+
+                sr.scan(conn);
+                return sr;
+
+            } catch (final XenAPIException e) {
+                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.toString();
+                s_logger.warn(msg, e);
+                throw new CloudRuntimeException(msg, e);
+            } catch (final Exception e) {
+                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.getMessage();
+                s_logger.warn(msg, e);
+                throw new CloudRuntimeException(msg, e);
+            }
+        }
+    }
+
+    private SR introduceAndPlugIscsiSr(Connection conn, String pooluuid, String srNameLabel, String type, Map<String, String> smConfig, Map<String, String> deviceConfig,
+            boolean ignoreIntroduceException) throws XmlRpcException, XenAPIException {
+        SR sr = null;
+        try {
+            sr = SR.introduce(conn, pooluuid, srNameLabel, srNameLabel, type, "user", true, smConfig);
+        } catch (final XenAPIException ex) {
+            if (ignoreIntroduceException) {
+                return sr;
+            }
+
+            throw ex;
+        }
+
+        final Set<Host> setHosts = Host.getAll(conn);
+
+        if (setHosts == null) {
+            final String msg = "Unable to create iSCSI SR " + deviceConfig + " due to hosts not available.";
+
+            s_logger.warn(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        for (final Host currentHost : setHosts) {
+            final PBD.Record rec = new PBD.Record();
+
+            rec.deviceConfig = deviceConfig;
+            rec.host = currentHost;
+            rec.SR = sr;
+
+            final PBD pbd = PBD.create(conn, rec);
+
+            pbd.plug(conn);
+        }
+
+        return sr;
+    }
+
+    private String resignatureIscsiSr(Connection conn, Host host, Map<String, String> deviceConfig, String srNameLabel, Map<String, String> smConfig) throws XmlRpcException, XenAPIException {
+        String pooluuid;
+
+        try {
+            SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, SRType.RELVMOISCSI.toString(), "user", true, smConfig);
+
+            // The successful outcome of SR.create (right above) is to throw an exception of type XenAPIException (with expected
+            // toString() text) after resigning the metadata (we indicated to perform a resign by passing in SRType.RELVMOISCSI.toString()).
+            // That being the case, if this CloudRuntimeException statement is executed, there appears to have been some kind
+            // of failure in the execution of the above SR.create (resign) method.
+            throw new CloudRuntimeException("Problem resigning the metadata");
+        } catch (XenAPIException ex) {
+            String msg = ex.toString();
+
+            if (!msg.contains("successfully resigned")) {
+                throw ex;
+            }
+
+            String type = SRType.LVMOISCSI.toString();
+            String result = SR.probe(conn, host, deviceConfig, type, smConfig);
+
+            pooluuid = null;
+
+            if (result.indexOf("<UUID>") != -1) {
+                pooluuid = result.substring(result.indexOf("<UUID>") + 6, result.indexOf("</UUID>")).trim();
+            }
+
+            if (pooluuid == null || pooluuid.length() != 36) {
+                throw new CloudRuntimeException("Non-existent or invalid SR UUID");
+            }
+        }
+
+        return pooluuid;
+    }
+
+    private void checkIfIscsiSrExisits(Connection conn, String srNameLabel, String target, String targetiqn, String lunid) throws XenAPIException, XmlRpcException {
+        final Set<SR> srs = SR.getByNameLabel(conn, srNameLabel);
+        for (final SR sr : srs) {
+            if (!(SRType.LVMOISCSI.equals(sr.getType(conn)))) {
+                continue;
+            }
+            final Set<PBD> pbds = sr.getPBDs(conn);
+            if (pbds.isEmpty()) {
+                continue;
+            }
+            final PBD pbd = pbds.iterator().next();
+            final Map<String, String> dc = pbd.getDeviceConfig(conn);
+            if (dc == null) {
+                continue;
+            }
+            if (dc.get("target") == null) {
+                continue;
+            }
+            if (dc.get("targetIQN") == null) {
+                continue;
+            }
+            if (dc.get("lunid") == null) {
+                continue;
+            }
+            if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) {
+                throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ",  targetIQN:" + dc.get("targetIQN") + ", lunid:" + dc.get("lunid")
+                + " for pool " + srNameLabel + "on host:" + _host.getUuid());
+            }
+        }
+
+    }
+
+    private String probeScisiId(Connection conn, Host host, Map<String, String> deviceConfig, String type, String srNameLabel, String lunid, Map<String, String> smConfig)
+            throws XenAPIException, XmlRpcException {
+        String scsiid = null;
+
+        try {
+            SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig);
+        } catch (final XenAPIException e) {
+            final String errmsg = e.toString();
+            if (errmsg.contains("SR_BACKEND_FAILURE_107")) {
+                final String lun[] = errmsg.split("<LUN>");
+                boolean found = false;
+                for (int i = 1; i < lun.length; i++) {
+                    final int blunindex = lun[i].indexOf("<LUNid>") + 7;
+                    final int elunindex = lun[i].indexOf("</LUNid>");
+                    String ilun = lun[i].substring(blunindex, elunindex);
+                    ilun = ilun.trim();
+                    if (ilun.equals(lunid)) {
+                        final int bscsiindex = lun[i].indexOf("<SCSIid>") + 8;
+                        final int escsiindex = lun[i].indexOf("</SCSIid>");
+                        scsiid = lun[i].substring(bscsiindex, escsiindex);
+                        scsiid = scsiid.trim();
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    final String msg = "can not find LUN " + lunid + " in " + errmsg;
+                    s_logger.warn(msg);
+                    throw new CloudRuntimeException(msg);
+                }
+            } else {
+                final String msg = "Unable to create Iscsi SR  " + deviceConfig + " due to  " + e.toString();
+                s_logger.warn(msg, e);
+                throw new CloudRuntimeException(msg, e);
+            }
+        }
+        return scsiid;
+    }
+
+    public SR getISOSRbyVmName(final Connection conn, final String vmName) {
+        try {
+            final Set<SR> srs = SR.getByNameLabel(conn, vmName + "-ISO");
+            if (srs.size() == 0) {
+                return null;
+            } else if (srs.size() == 1) {
+                return srs.iterator().next();
+            } else {
+                final String msg = "getIsoSRbyVmName failed due to there are more than 1 SR having same Label";
+                s_logger.warn(msg);
+            }
+        } catch (final XenAPIException e) {
+            final String msg = "getIsoSRbyVmName failed due to " + e.toString();
+            s_logger.warn(msg, e);
+        } catch (final Exception e) {
+            final String msg = "getIsoSRbyVmName failed due to " + e.getMessage();
+            s_logger.warn(msg, e);
+        }
+        return null;
+    }
+
+    public VDI getIsoVDIByURL(final Connection conn, final String vmName, final String isoURL) {
+        SR isoSR = null;
+        String mountpoint = null;
+        if (isoURL.startsWith("xs-tools")) {
+            try {
+                final String actualIsoURL = getActualIsoTemplate(conn);
+                final Set<VDI> vdis = VDI.getByNameLabel(conn, actualIsoURL);
+                if (vdis.isEmpty()) {
+                    throw new CloudRuntimeException("Could not find ISO with URL: " + actualIsoURL);
+                }
+                return vdis.iterator().next();
+
+            } catch (final XenAPIException e) {
+                throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString());
+            } catch (final Exception e) {
+                throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString());
+            }
+        }
+
+        final int index = isoURL.lastIndexOf("/");
+        mountpoint = isoURL.substring(0, index);
+
+        URI uri;
+        try {
+            uri = new URI(mountpoint);
+        } catch (final URISyntaxException e) {
+            throw new CloudRuntimeException("isoURL is wrong: " + isoURL);
+        }
+        isoSR = getISOSRbyVmName(conn, vmName);
+        if (isoSR == null) {
+            isoSR = createIsoSRbyURI(conn, uri, vmName, false);
+        }
+
+        final String isoName = isoURL.substring(index + 1);
+
+        final VDI isoVDI = getVDIbyLocationandSR(conn, isoName, isoSR);
+
+        if (isoVDI != null) {
+            return isoVDI;
+        } else {
+            throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL);
+        }
+    }
+
+    /**
+     * Retrieve the actual ISO 'name-label' to be used.
+     * We based our decision on XenServer version.
+     * <ul>
+     *  <li> for XenServer 7.0+, we use {@value #xenServer70plusGuestToolsName};
+     *  <li> for versions before 7.0, we use {@value #xenServerBefore70GuestToolsName}.
+     * </ul>
+     *
+     * For XCP we always use {@value #xenServerBefore70GuestToolsName}.
+     */
+    protected String getActualIsoTemplate(Connection conn) throws XenAPIException, XmlRpcException {
+        Host host = Host.getByUuid(conn, _host.getUuid());
+        Host.Record record = host.getRecord(conn);
+        String xenBrand = record.softwareVersion.get("product_brand");
+        String xenVersion = record.softwareVersion.get("product_version");
+        String[] items = xenVersion.split("\\.");
+
+        if ((xenBrand.equals("XenServer") || xenBrand.equals("XCP-ng")) && Integer.parseInt(items[0]) >= 7) {
+            return xenServer70plusGuestToolsName;
+        }
+        return xenServerBefore70GuestToolsName;
+    }
+
+    public String getLabel() {
+        final Connection conn = getConnection();
+        final String result = callHostPlugin(conn, "ovstunnel", "getLabel");
+        return result;
+    }
+
+    public String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) {
+        String vmName = "";
+        try {
+            vmName = vm.getNameLabel(conn);
+            final List<Integer> usedDeviceNums = new ArrayList<Integer>();
+            final Set<VIF> vifs = vm.getVIFs(conn);
+            final Iterator<VIF> vifIter = vifs.iterator();
+            while (vifIter.hasNext()) {
+                final VIF vif = vifIter.next();
+                try {
+                    final String deviceId = vif.getDevice(conn);
+                    if (vm.getIsControlDomain(conn) || vif.getCurrentlyAttached(conn)) {
+                        usedDeviceNums.add(Integer.valueOf(deviceId));
+                    } else {
+                        s_logger.debug("Found unplugged VIF " + deviceId + " in VM " + vmName + " destroy it");
+                        vif.destroy(conn);
+                    }
+                } catch (final NumberFormatException e) {
+                    final String msg = "Obtained an invalid value for an allocated VIF device number for VM: " + vmName;
+                    s_logger.debug(msg, e);
+                    throw new CloudRuntimeException(msg);
+                }
+            }
+
+            for (Integer i = 0; i < _maxNics; i++) {
+                if (!usedDeviceNums.contains(i)) {
+                    s_logger.debug("Lowest available Vif device number: " + i + " for VM: " + vmName);
+                    return i.toString();
+                }
+            }
+        } catch (final XmlRpcException e) {
+            final String msg = "Caught XmlRpcException: " + e.getMessage();
+            s_logger.warn(msg, e);
+        } catch (final XenAPIException e) {
+            final String msg = "Caught XenAPIException: " + e.toString();
+            s_logger.warn(msg, e);
+        }
+
+        throw new CloudRuntimeException("Could not find available VIF slot in VM with name: " + vmName);
+    }
+
+    protected XsLocalNetwork getManagementNetwork(final Connection conn) throws XmlRpcException, XenAPIException {
+        PIF mgmtPif = null;
+        PIF.Record mgmtPifRec = null;
+        final Host host = Host.getByUuid(conn, _host.getUuid());
+        final Set<PIF> hostPifs = host.getPIFs(conn);
+        for (final PIF pif : hostPifs) {
+            final PIF.Record rec = pif.getRecord(conn);
+            if (rec.management) {
+                if (rec.VLAN != null && rec.VLAN != -1) {
+                    final String msg = new StringBuilder("Unsupported configuration.  Management network is on a VLAN.  host=").append(_host.getUuid()).append("; pif=").append(rec.uuid)
+                            .append("; vlan=").append(rec.VLAN).toString();
+                    s_logger.warn(msg);
+                    throw new CloudRuntimeException(msg);
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Management network is on pif=" + rec.uuid);
+                }
+                mgmtPif = pif;
+                mgmtPifRec = rec;
+                break;
+            }
+        }
+        if (mgmtPif == null) {
+            final String msg = "Unable to find management network for " + _host.getUuid();
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        final Bond bond = mgmtPifRec.bondSlaveOf;
+        if (!isRefNull(bond)) {
+            final String msg = "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.getUuid()
+            + "), please move management interface to bond!";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        final Network nk = mgmtPifRec.network;
+        final Network.Record nkRec = nk.getRecord(conn);
+        return new XsLocalNetwork(this, nk, nkRec, mgmtPif, mgmtPifRec);
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    public XsLocalNetwork getNativeNetworkForTraffic(final Connection conn, final TrafficType type, final String name) throws XenAPIException, XmlRpcException {
+        if (name != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Looking for network named " + name);
+            }
+            return getNetworkByName(conn, name);
+        }
+
+        if (type == TrafficType.Guest) {
+            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getGuestNetwork()), null, PIF.getByUuid(conn, _host.getGuestPif()), null);
+        } else if (type == TrafficType.Control) {
+            setupLinkLocalNetwork(conn);
+            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getLinkLocalNetwork()));
+        } else if (type == TrafficType.Management) {
+            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPrivateNetwork()), null, PIF.getByUuid(conn, _host.getPrivatePif()), null);
+        } else if (type == TrafficType.Public) {
+            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPublicNetwork()), null, PIF.getByUuid(conn, _host.getPublicPif()), null);
+        } else if (type == TrafficType.Storage) {
+            /*
+             * TrafficType.Storage is for secondary storage, while
+             * storageNetwork1 is for primary storage, we need better name here
+             */
+            return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getStorageNetwork1()), null, PIF.getByUuid(conn, _host.getStoragePif1()), null);
+        }
+
+        throw new CloudRuntimeException("Unsupported network type: " + type);
+    }
+
+    public Network getNetwork(final Connection conn, final NicTO nic) throws XenAPIException, XmlRpcException {
+        final String name = nic.getName();
+        final XsLocalNetwork network = getNativeNetworkForTraffic(conn, nic.getType(), name);
+        if (network == null) {
+            s_logger.error("Network is not configured on the backend for nic " + nic.toString());
+            throw new CloudRuntimeException("Network for the backend is not configured correctly for network broadcast domain: " + nic.getBroadcastUri());
+        }
+        final URI uri = nic.getBroadcastUri();
+        final BroadcastDomainType type = nic.getBroadcastType();
+        if (uri != null && uri.toString().contains("untagged")) {
+            return network.getNetwork();
+        } else if (uri != null && type == BroadcastDomainType.Vlan) {
+            assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Vlan;
+            final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri));
+            return enableVlanNetwork(conn, vlan, network);
+        } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal || type == BroadcastDomainType.Vsp) {
+            return network.getNetwork();
+        } else if (uri != null && type == BroadcastDomainType.Vswitch) {
+            final String header = uri.toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length());
+            if (header.startsWith("vlan")) {
+                _isOvs = true;
+                return setupvSwitchNetwork(conn);
+            } else {
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority()));
+            }
+        } else if (type == BroadcastDomainType.Storage) {
+            if (uri == null) {
+                return network.getNetwork();
+            } else {
+                final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri));
+                return enableVlanNetwork(conn, vlan, network);
+            }
+        } else if (type == BroadcastDomainType.Lswitch) {
+            // Nicira Logical Switch
+            return network.getNetwork();
+        } else if (uri != null && type == BroadcastDomainType.Pvlan) {
+            assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Pvlan;
+            // should we consider moving this NetUtils method to
+            // BroadcastDomainType?
+            final long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(uri));
+            return enableVlanNetwork(conn, vlan, network);
+        }
+
+        throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
+    }
+
+    /**
+     * getNetworkByName() retrieves what the server thinks is the actual network
+     * used by the XenServer host. This method should always be used to talk to
+     * retrieve a network by the name. The reason is because of the problems in
+     * using the name label as the way to find the Network.
+     *
+     * To see how we are working around these problems, take a look at
+     * enableVlanNetwork(). The following description assumes you have looked at
+     * the description on that method.
+     *
+     * In order to understand this, we have to see what type of networks are
+     * within a XenServer that's under CloudStack control.
+     *
+     * - Native Networks: these are networks that are untagged on the XenServer
+     * and are used to crate VLAN networks on. These are created by the user and
+     * is assumed to be one per cluster. - VLAN Networks: these are dynamically
+     * created by CloudStack and can have problems with duplicated names. -
+     * LinkLocal Networks: these are dynamically created by CloudStack and can
+     * also have problems with duplicated names but these don't have actual
+     * PIFs.
+     *
+     * In order to speed to retrieval of a network, we do the following: - We
+     * retrieve by the name. If only one network is retrieved, we assume we
+     * retrieved the right network. - If more than one network is retrieved, we
+     * check to see which one has the pif for the local host and use that. - If
+     * a pif is not found, then we look at the tags and find the one with the
+     * lowest timestamp. (See enableVlanNetwork())
+     *
+     * @param conn
+     *            Xapi connection
+     * @param name
+     *            name of the network
+     * @return XsNic an object that contains network, network record, pif, and
+     *         pif record.
+     * @throws XenAPIException
+     * @throws XmlRpcException
+     *
+     * @see CitrixResourceBase#enableVlanNetwork
+     */
+    public XsLocalNetwork getNetworkByName(final Connection conn, final String name) throws XenAPIException, XmlRpcException {
+        final Set<Network> networks = Network.getByNameLabel(conn, name);
+        if (networks.size() == 1) {
+            return new XsLocalNetwork(this, networks.iterator().next(), null, null, null);
+        }
+
+        if (networks.size() == 0) {
+            return null;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Found more than one network with the name " + name);
+        }
+        Network earliestNetwork = null;
+        Network.Record earliestNetworkRecord = null;
+        long earliestTimestamp = Long.MAX_VALUE;
+        int earliestRandom = Integer.MAX_VALUE;
+        for (final Network network : networks) {
+            final XsLocalNetwork nic = new XsLocalNetwork(this, network);
+
+            if (nic.getPif(conn) != null) {
+                return nic;
+            }
+
+            final Network.Record record = network.getRecord(conn);
+            if (record.tags != null) {
+                for (final String tag : record.tags) {
+                    final Pair<Long, Integer> stamp = parseTimestamp(tag);
+                    if (stamp == null) {
+                        continue;
+                    }
+
+                    if (stamp.first() < earliestTimestamp || stamp.first() == earliestTimestamp && stamp.second() < earliestRandom) {
+                        earliestTimestamp = stamp.first();
+                        earliestRandom = stamp.second();
+                        earliestNetwork = network;
+                        earliestNetworkRecord = record;
+                    }
+                }
+            }
+        }
+
+        return earliestNetwork != null ? new XsLocalNetwork(this, earliestNetwork, earliestNetworkRecord, null, null) : null;
+    }
+
+    public long[] getNetworkStats(final Connection conn, final String privateIP) {
+        final String result = networkUsage(conn, privateIP, "get", null);
+        final long[] stats = new long[2];
+        if (result != null) {
+            final String[] splitResult = result.split(":");
+            int i = 0;
+            while (i < splitResult.length - 1) {
+                stats[0] += Long.parseLong(splitResult[i++]);
+                stats[1] += Long.parseLong(splitResult[i++]);
+            }
+        }
+        return stats;
+    }
+
+    public SR getNfsSR(final Connection conn, final String poolid, final String uuid, final String server, String serverpath, final String pooldesc) {
+        final Map<String, String> deviceConfig = new HashMap<String, String>();
+        try {
+            serverpath = serverpath.replace("//", "/");
+            final Set<SR> srs = SR.getAll(conn);
+            if (srs != null && !srs.isEmpty()) {
+                for (final SR sr : srs) {
+                    if (!SRType.NFS.equals(sr.getType(conn))) {
+                        continue;
+                    }
+
+                    final Set<PBD> pbds = sr.getPBDs(conn);
+                    if (pbds.isEmpty()) {
+                        continue;
+                    }
+
+                    final PBD pbd = pbds.iterator().next();
+
+                    final Map<String, String> dc = pbd.getDeviceConfig(conn);
+
+                    if (dc == null) {
+                        continue;
+                    }
+
+                    if (dc.get("server") == null) {
+                        continue;
+                    }
+
+                    if (dc.get("serverpath") == null) {
+                        continue;
+                    }
+
+                    if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) {
+                        throw new CloudRuntimeException(
+                                "There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + " for pool " + uuid + " on host:" + _host.getUuid());
+                    }
+
+                }
+            }
+            deviceConfig.put("server", server);
+            deviceConfig.put("serverpath", serverpath);
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final Map<String, String> smConfig = new HashMap<String, String>();
+            smConfig.put("nosubdir", "true");
+            final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uuid, poolid, SRType.NFS.toString(), "user", true, smConfig);
+            sr.scan(conn);
+            return sr;
+        } catch (final XenAPIException e) {
+            throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e);
+        } catch (final XmlRpcException e) {
+            throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e);
+        }
+    }
+
+    private String getOvsTunnelNetworkName(final String broadcastUri) {
+        if (broadcastUri.contains(".")) {
+            final String[] parts = broadcastUri.split("\\.");
+            return "OVS-DR-VPC-Bridge" + parts[0];
+        } else {
+            try {
+                return "OVSTunnel" + broadcastUri;
+            } catch (final Exception e) {
+                return null;
+            }
+        }
+    }
+
+    protected List<File> getPatchFiles() {
+        String patch = getPatchFilePath();
+        String patchfilePath = Script.findScript("", patch);
+        if (patchfilePath == null) {
+            throw new CloudRuntimeException("Unable to find patch file " + patch);
+        }
+        List<File> files = new ArrayList<File>();
+        files.add(new File(patchfilePath));
+        return files;
+    }
+
+    protected abstract String getPatchFilePath();
+
+    public String getPerfMon(final Connection conn, final Map<String, String> params, final int wait) {
+        String result = null;
+        try {
+            result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, params);
+            if (result != null) {
+                return result;
+            }
+        } catch (final Exception e) {
+            s_logger.error("Can not get performance monitor for AS due to ", e);
+        }
+        return null;
+    }
+
+    protected Object[] getRRDData(final Connection conn, final int flag) {
+
+        /*
+         * Note: 1 => called from host, hence host stats 2 => called from vm,
+         * hence vm stats
+         */
+        Document doc = null;
+
+        try {
+            doc = getStatsRawXML(conn, flag == 1 ? true : false);
+        } catch (final Exception e1) {
+            s_logger.warn("Error whilst collecting raw stats from plugin: ", e1);
+            return null;
+        }
+
+        if (doc == null) { // stats are null when the host plugin call fails
+            // (host down state)
+            return null;
+        }
+
+        final NodeList firstLevelChildren = doc.getChildNodes();
+        final NodeList secondLevelChildren = firstLevelChildren.item(0).getChildNodes();
+        final Node metaNode = secondLevelChildren.item(0);
+        final Node dataNode = secondLevelChildren.item(1);
+
+        Integer numRows = 0;
+        Integer numColumns = 0;
+        Node legend = null;
+        final NodeList metaNodeChildren = metaNode.getChildNodes();
+        for (int i = 0; i < metaNodeChildren.getLength(); i++) {
+            final Node n = metaNodeChildren.item(i);
+            if (n.getNodeName().equals("rows")) {
+                numRows = Integer.valueOf(getXMLNodeValue(n));
+            } else if (n.getNodeName().equals("columns")) {
+                numColumns = Integer.valueOf(getXMLNodeValue(n));
+            } else if (n.getNodeName().equals("legend")) {
+                legend = n;
+            }
+        }
+
+        return new Object[] {numRows, numColumns, legend, dataNode};
+    }
+
+    @Override
+    public int getRunLevel() {
+        return 0;
+    }
+
+    protected SR getSRByNameLabelandHost(final Connection conn, final String name) throws BadServerResponse, XenAPIException, XmlRpcException {
+        final Set<SR> srs = SR.getByNameLabel(conn, name);
+        SR ressr = null;
+        for (final SR sr : srs) {
+            Set<PBD> pbds;
+            pbds = sr.getPBDs(conn);
+            for (final PBD pbd : pbds) {
+                final PBD.Record pbdr = pbd.getRecord(conn);
+                if (pbdr.host != null && pbdr.host.getUuid(conn).equals(_host.getUuid())) {
+                    if (!pbdr.currentlyAttached) {
+                        pbd.plug(conn);
+                    }
+                    ressr = sr;
+                    break;
+                }
+            }
+        }
+        return ressr;
+    }
+
+    private long getStaticMax(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam, final long recommendedValue) {
+        if (recommendedValue == 0) {
+            s_logger.warn("No recommended value found for dynamic max, setting static max and dynamic max equal");
+            return dynamicMaxRam;
+        }
+        final long staticMax = Math.min(recommendedValue, 4l * dynamicMinRam); // XS
+        // constraint
+        // for
+        // stability
+        if (dynamicMaxRam > staticMax) { // XS contraint that dynamic max <=
+            // static max
+            s_logger.warn("dynamixMax " + dynamicMaxRam + " cant be greater than static max " + staticMax + ", can lead to stability issues. Setting static max as much as dynamic max ");
+            return dynamicMaxRam;
+        }
+        return staticMax;
+    }
+
+    private long getStaticMin(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam, final long recommendedValue) {
+        if (recommendedValue == 0) {
+            s_logger.warn("No recommended value found for dynamic min");
+            return dynamicMinRam;
+        }
+
+        if (dynamicMinRam < recommendedValue) { // XS contraint that dynamic min
+            // > static min
+            s_logger.warn("Vm is set to dynamixMin " + dynamicMinRam + " less than the recommended static min " + recommendedValue + ", could lead to stability issues");
+        }
+        return dynamicMinRam;
+    }
+
+    protected Document getStatsRawXML(final Connection conn, final boolean host) {
+        final Date currentDate = new Date();
+        String urlStr = "http://" + _host.getIp() + "/rrd_updates?";
+        urlStr += "session_id=" + conn.getSessionReference();
+        urlStr += "&host=" + (host ? "true" : "false");
+        urlStr += "&cf=" + _consolidationFunction;
+        urlStr += "&interval=" + _pollingIntervalInSeconds;
+        urlStr += "&start=" + (currentDate.getTime() / 1000 - 1000 - 100);
+
+        URL url;
+        BufferedReader in = null;
+        try {
+            url = new URL(urlStr);
+            url.openConnection();
+            final URLConnection uc = url.openConnection();
+            in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
+            final InputSource statsSource = new InputSource(in);
+            return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(statsSource);
+        } catch (final MalformedURLException e) {
+            s_logger.warn("Malformed URL?  come on...." + urlStr);
+            return null;
+        } catch (final IOException e) {
+            s_logger.warn("Problems getting stats using " + urlStr, e);
+            return null;
+        } catch (final SAXException e) {
+            s_logger.warn("Problems getting stats using " + urlStr, e);
+            return null;
+        } catch (final ParserConfigurationException e) {
+            s_logger.warn("Problems getting stats using " + urlStr, e);
+            return null;
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (final IOException e) {
+                    s_logger.warn("Unable to close the buffer ", e);
+                }
+            }
+        }
+    }
+
+    public SR getStorageRepository(final Connection conn, final String srNameLabel) {
+        Set<SR> srs;
+        try {
+            srs = SR.getByNameLabel(conn, srNameLabel);
+        } catch (final XenAPIException e) {
+            throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.toString(), e);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.getMessage(), e);
+        }
+
+        if (srs.size() > 1) {
+            throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + srNameLabel);
+        } else if (srs.size() == 1) {
+            final SR sr = srs.iterator().next();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("SR retrieved for " + srNameLabel);
+            }
+
+            if (checkSR(conn, sr)) {
+                return sr;
+            }
+            throw new CloudRuntimeException("SR check failed for storage pool: " + srNameLabel + "on host:" + _host.getUuid());
+        } else {
+            throw new CloudRuntimeException("Can not see storage pool: " + srNameLabel + " from on host:" + _host.getUuid());
+        }
+    }
+
+    protected Storage.StorageResourceType getStorageResourceType() {
+        return Storage.StorageResourceType.STORAGE_POOL;
+    }
+
+    @Override
+    public Type getType() {
+        return com.cloud.host.Host.Type.Routing;
+    }
+
+    protected VDI getVDIbyLocationandSR(final Connection conn, final String loc, final SR sr) {
+        try {
+            final Set<VDI> vdis = sr.getVDIs(conn);
+            for (final VDI vdi : vdis) {
+                if (vdi.getLocation(conn).startsWith(loc)) {
+                    return vdi;
+                }
+            }
+
+            final String msg = "can not getVDIbyLocationandSR " + loc;
+            s_logger.warn(msg);
+            return null;
+        } catch (final XenAPIException e) {
+            final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        } catch (final Exception e) {
+            final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+
+    }
+
+    public VDI getVDIbyUuid(final Connection conn, final String uuid) {
+        return getVDIbyUuid(conn, uuid, true);
+    }
+
+    public VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound) {
+        try {
+            return VDI.getByUuid(conn, uuid);
+        } catch (final Exception e) {
+            if (throwExceptionIfNotFound) {
+                final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString();
+
+                s_logger.debug(msg);
+
+                throw new CloudRuntimeException(msg, e);
+            }
+
+            return null;
+        }
+    }
+
+    public String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
+        final String parentUuid = callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString());
+
+        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
+            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
+            // errString is already logged.
+            return null;
+        }
+        return parentUuid;
+    }
+
+    public VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException {
+        final Set<VIF> routerVIFs = router.getVIFs(conn);
+        mac = mac.trim();
+        for (final VIF vif : routerVIFs) {
+            final String lmac = vif.getMAC(conn);
+            if (lmac.trim().equals(mac)) {
+                return vif;
+            }
+        }
+        return null;
+    }
+
+    public VirtualRoutingResource getVirtualRoutingResource() {
+        return _vrResource;
+    }
+
+    public VM getVM(final Connection conn, final String vmName) {
+        // Look up VMs with the specified name
+        Set<VM> vms;
+        try {
+            vms = VM.getByNameLabel(conn, vmName);
+        } catch (final XenAPIException e) {
+            throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.toString(), e);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.getMessage(), e);
+        }
+
+        // If there are no VMs, throw an exception
+        if (vms.size() == 0) {
+            throw new CloudRuntimeException("VM with name: " + vmName + " does not exist.");
+        }
+
+        // If there is more than one VM, print a warning
+        if (vms.size() > 1) {
+            s_logger.warn("Found " + vms.size() + " VMs with name: " + vmName);
+        }
+
+        // Return the first VM in the set
+        return vms.iterator().next();
+    }
+
+    public String getVMInstanceName() {
+        return _instance;
+    }
+
+    public long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName, final String vmSnapshotName)
+            throws BadServerResponse, XenAPIException, XmlRpcException {
+        if (volumeTo.getVolumeType() == Volume.Type.DATADISK) {
+            final VDI dataDisk = VDI.getByUuid(conn, volumeTo.getPath());
+            if (dataDisk != null) {
+                final String dataDiskName = dataDisk.getNameLabel(conn);
+                if (dataDiskName != null && !dataDiskName.isEmpty()) {
+                    volumeTo.setName(dataDiskName);
+                }
+            }
+        }
+        final Set<VDI> allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName());
+        long size = 0;
+        for (final VDI vdi : allvolumeVDIs) {
+            try {
+                if (vdi.getIsASnapshot(conn) && vdi.getSmConfig(conn).get("vhd-parent") != null) {
+                    final String parentUuid = vdi.getSmConfig(conn).get("vhd-parent");
+                    final VDI parentVDI = VDI.getByUuid(conn, parentUuid);
+                    // add size of snapshot vdi node, usually this only contains
+                    // meta data
+                    size = size + vdi.getPhysicalUtilisation(conn);
+                    // add size of snapshot vdi parent, this contains data
+                    if (!isRefNull(parentVDI)) {
+                        size = size + parentVDI.getPhysicalUtilisation(conn).longValue();
+                    }
+                }
+            } catch (final Exception e) {
+                s_logger.debug("Exception occurs when calculate snapshot capacity for volumes: due to " + e.toString());
+                continue;
+            }
+        }
+        if (volumeTo.getVolumeType() == Volume.Type.ROOT) {
+            VM vm = getVM(conn, vmName);
+            if (vm != null) {
+                Set<VM> vmSnapshots = vm.getSnapshots(conn);
+                if (vmSnapshots != null) {
+                    for (VM vmsnap : vmSnapshots) {
+                        try {
+                            final String vmSnapName = vmsnap.getNameLabel(conn);
+                            s_logger.debug("snapname " + vmSnapName);
+                            if (vmSnapName != null && vmSnapName.contains(vmSnapshotName) && vmsnap.getIsASnapshot(conn)) {
+                                s_logger.debug("snapname " + vmSnapName + "isASnapshot");
+                                VDI memoryVDI = vmsnap.getSuspendVDI(conn);
+                                if (!isRefNull(memoryVDI)) {
+                                    size = size + memoryVDI.getPhysicalUtilisation(conn);
+                                    s_logger.debug("memoryVDI size :" + size);
+                                    String parentUuid = memoryVDI.getSmConfig(conn).get("vhd-parent");
+                                    VDI pMemoryVDI = VDI.getByUuid(conn, parentUuid);
+                                    if (!isRefNull(pMemoryVDI)) {
+                                        size = size + pMemoryVDI.getPhysicalUtilisation(conn);
+                                    }
+                                    s_logger.debug("memoryVDI size+parent :" + size);
+                                }
+                            }
+                        } catch (Exception e) {
+                            s_logger.debug("Exception occurs when calculate snapshot capacity for memory: due to " + e.toString());
+                            continue;
+                        }
+
+                    }
+                }
+            }
+        }
+        return size;
+    }
+
+    public PowerState getVmState(final Connection conn, final String vmName) {
+        int retry = 3;
+        while (retry-- > 0) {
+            try {
+                final Set<VM> vms = VM.getByNameLabel(conn, vmName);
+                for (final VM vm : vms) {
+                    return convertToPowerState(vm.getPowerState(conn));
+                }
+            } catch (final BadServerResponse e) {
+                // There is a race condition within xenserver such that if a vm
+                // is
+                // deleted and we
+                // happen to ask for it, it throws this stupid response. So
+                // if this happens,
+                // we take a nap and try again which then avoids the race
+                // condition because
+                // the vm's information is now cleaned up by xenserver. The
+                // error
+                // is as follows
+                // com.xensource.xenapi.Types$BadServerResponse
+                // [HANDLE_INVALID, VM,
+                // 3dde93f9-c1df-55a7-2cde-55e1dce431ab]
+                s_logger.info("Unable to get a vm PowerState due to " + e.toString() + ". We are retrying.  Count: " + retry);
+                try {
+                    Thread.sleep(3000);
+                } catch (final InterruptedException ex) {
+
+                }
+            } catch (final XenAPIException e) {
+                final String msg = "Unable to get a vm PowerState due to " + e.toString();
+                s_logger.warn(msg, e);
+                break;
+            } catch (final XmlRpcException e) {
+                final String msg = "Unable to get a vm PowerState due to " + e.getMessage();
+                s_logger.warn(msg, e);
+                break;
+            }
+        }
+
+        return PowerState.PowerOff;
+    }
+
+    public HashMap<String, VmStatsEntry> getVmStats(final Connection conn, final GetVmStatsCommand cmd, final List<String> vmUUIDs, final String hostGuid) {
+        final HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
+
+        for (final String vmUUID : vmUUIDs) {
+            vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, 0, 0, 0, "vm"));
+        }
+
+        final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for
+        // vm
+
+        if (rrdData == null) {
+            return null;
+        }
+
+        final Integer numRows = (Integer)rrdData[0];
+        final Integer numColumns = (Integer)rrdData[1];
+        final Node legend = (Node)rrdData[2];
+        final Node dataNode = (Node)rrdData[3];
+
+        final NodeList legendChildren = legend.getChildNodes();
+        for (int col = 0; col < numColumns; col++) {
+
+            if (legendChildren == null || legendChildren.item(col) == null) {
+                continue;
+            }
+
+            final String columnMetadata = getXMLNodeValue(legendChildren.item(col));
+
+            if (columnMetadata == null) {
+                continue;
+            }
+
+            final String[] columnMetadataList = columnMetadata.split(":");
+
+            if (columnMetadataList.length != 4) {
+                continue;
+            }
+
+            final String type = columnMetadataList[1];
+            final String uuid = columnMetadataList[2];
+            final String param = columnMetadataList[3];
+
+            if (type.equals("vm") && vmResponseMap.keySet().contains(uuid)) {
+                final VmStatsEntry vmStatsAnswer = vmResponseMap.get(uuid);
+
+                vmStatsAnswer.setEntityType("vm");
+
+                if (param.contains("cpu")) {
+                    vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1);
+                    vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows));
+                } else if (param.matches("vif_\\d*_rx")) {
+                    vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.matches("vif_\\d*_tx")) {
+                    vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.matches("vbd_.*_read")) {
+                    vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.matches("vbd_.*_write")) {
+                    vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.contains("memory_internal_free")) {
+                    vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.contains("memory_target")) {
+                    vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                } else if (param.contains("memory")) {
+                    vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES);
+                }
+
+            }
+        }
+
+        for (final Map.Entry<String, VmStatsEntry> entry : vmResponseMap.entrySet()) {
+            final VmStatsEntry vmStatsAnswer = entry.getValue();
+
+            if (vmStatsAnswer.getNumCPUs() != 0) {
+                vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() / vmStatsAnswer.getNumCPUs());
+            }
+
+            vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() * 100);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization());
+            }
+        }
+
+        return vmResponseMap;
+    }
+
+    public String getVncUrl(final Connection conn, final VM vm) {
+        VM.Record record;
+        Console c;
+        try {
+            record = vm.getRecord(conn);
+            final Set<Console> consoles = record.consoles;
+
+            if (consoles.isEmpty()) {
+                s_logger.warn("There are no Consoles available to the vm : " + record.nameDescription);
+                return null;
+            }
+            final Iterator<Console> i = consoles.iterator();
+            while (i.hasNext()) {
+                c = i.next();
+                if (c.getProtocol(conn) == Types.ConsoleProtocol.RFB) {
+                    return c.getLocation(conn);
+                }
+            }
+        } catch (final XenAPIException e) {
+            final String msg = "Unable to get console url due to " + e.toString();
+            s_logger.warn(msg, e);
+            return null;
+        } catch (final XmlRpcException e) {
+            final String msg = "Unable to get console url due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            return null;
+        }
+        return null;
+    }
+
+    protected String getXMLNodeValue(final Node n) {
+        return n.getChildNodes().item(0).getNodeValue();
+    }
+
+    public void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception {
+        final SR sr = getStorageRepository(conn, iqn);
+
+        removeSR(conn, sr);
+    }
+
+    protected void destroyUnattachedVBD(Connection conn, VM vm) {
+        try {
+            for (VBD vbd : vm.getVBDs(conn)) {
+                if (Types.VbdType.DISK.equals(vbd.getType(conn)) && !vbd.getCurrentlyAttached(conn)) {
+                    vbd.destroy(conn);
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.debug("Failed to destroy unattached VBD due to ", e);
+        }
+    }
+
+    public String handleVmStartFailure(final Connection conn, final String vmName, final VM vm, final String message, final Throwable th) {
+        final String msg = "Unable to start " + vmName + " due to " + message;
+        s_logger.warn(msg, th);
+
+        if (vm == null) {
+            return msg;
+        }
+
+        try {
+            final VM.Record vmr = vm.getRecord(conn);
+            final List<Network> networks = new ArrayList<Network>();
+            for (final VIF vif : vmr.VIFs) {
+                try {
+                    final VIF.Record rec = vif.getRecord(conn);
+                    if (rec != null) {
+                        networks.add(rec.network);
+                    } else {
+                        s_logger.warn("Unable to cleanup VIF: " + vif.toWireString() + " As vif record is null");
+                    }
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to cleanup VIF", e);
+                }
+            }
+            if (vmr.powerState == VmPowerState.RUNNING) {
+                try {
+                    vm.hardShutdown(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("VM hardshutdown failed due to ", e);
+                }
+            }
+            if (vm.getPowerState(conn) == VmPowerState.HALTED) {
+                try {
+                    vm.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("VM destroy failed due to ", e);
+                }
+            }
+            for (final VBD vbd : vmr.VBDs) {
+                try {
+                    vbd.unplug(conn);
+                    vbd.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to clean up VBD due to ", e);
+                }
+            }
+            for (final VIF vif : vmr.VIFs) {
+                try {
+                    vif.unplug(conn);
+                    vif.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to cleanup VIF", e);
+                }
+            }
+            for (final Network network : networks) {
+                if (network.getNameLabel(conn).startsWith("VLAN")) {
+                    disableVlanNetwork(conn, network);
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.warn("VM getRecord failed due to ", e);
+        }
+
+        return msg;
+    }
+
+    @Override
+    public StartupCommand[] initialize() throws IllegalArgumentException {
+        final Connection conn = getConnection();
+        if (!getHostInfo(conn)) {
+            s_logger.warn("Unable to get host information for " + _host.getIp());
+            return null;
+        }
+        final StartupRoutingCommand cmd = new StartupRoutingCommand();
+        fillHostInfo(conn, cmd);
+        cmd.setHypervisorType(HypervisorType.XenServer);
+        cmd.setCluster(_cluster);
+        cmd.setPoolSync(false);
+
+        try {
+            final Pool pool = Pool.getByUuid(conn, _host.getPool());
+            final Pool.Record poolr = pool.getRecord(conn);
+            poolr.master.getRecord(conn);
+        } catch (final Throwable e) {
+            s_logger.warn("Check for master failed, failing the FULL Cluster sync command");
+        }
+        List<StartupStorageCommand> startUpLocalStorageCommands = null;
+        try {
+            startUpLocalStorageCommands = initializeLocalSrs(conn);
+        } catch (XenAPIException | XmlRpcException e) {
+            s_logger.warn("Could not initialize local SRs on host: " + _host.getUuid(), e);
+        }
+        if (CollectionUtils.isEmpty(startUpLocalStorageCommands)) {
+            return new StartupCommand[] {cmd};
+        }
+        return createStartupCommandsArray(cmd, startUpLocalStorageCommands);
+    }
+
+    /**
+     * We simply create an array and add the {@link StartupRoutingCommand} as the first element of the array. Then, we add all elements from startUpLocalStorageCommands
+     */
+    private StartupCommand[] createStartupCommandsArray(StartupRoutingCommand startupRoutingCommand, List<StartupStorageCommand> startUpLocalStorageCommands) {
+        StartupCommand[] startupCommands = new StartupCommand[startUpLocalStorageCommands.size() + 1];
+        startupCommands[0] = startupRoutingCommand;
+        for (int i = 1; i < startupCommands.length; i++) {
+            startupCommands[i] = startUpLocalStorageCommands.get(i - 1);
+        }
+        return startupCommands;
+    }
+
+    /**
+     * This  method will return a list of all local SRs.
+     * An SR is considered local if it meets all of the following criteria:
+     * <ul>
+     *  <li> {@link Record#shared} is equal to false
+     *  <li> The PBDs of the SR ({@link Record#PBDs}) are connected to host {@link #_host}
+     *  <li> SR type is equal to the {@link SRType} sent as parameter
+     * </ul>
+     */
+    protected List<SR> getAllLocalSrForType(Connection conn, SRType srType) throws XenAPIException, XmlRpcException {
+        List<SR> localSrs = new ArrayList<>();
+        Map<SR, SR.Record> allSrRecords = SR.getAllRecords(conn);
+        if (MapUtils.isEmpty(allSrRecords)) {
+            return localSrs;
+        }
+        for (Map.Entry<SR, SR.Record> entry : allSrRecords.entrySet()) {
+            SR.Record srRec = entry.getValue();
+            if (!srType.equals(srRec.type)) {
+                continue;
+            }
+            if (BooleanUtils.toBoolean(srRec.shared)) {
+                continue;
+            }
+            Set<PBD> pbds = srRec.PBDs;
+            if (CollectionUtils.isEmpty(pbds)) {
+                continue;
+            }
+            for (PBD pbd : pbds) {
+                Host host = pbd.getHost(conn);
+                if (!isRefNull(host) && org.apache.commons.lang3.StringUtils.equals(host.getUuid(conn), _host.getUuid())) {
+                    if (!pbd.getCurrentlyAttached(conn)) {
+                        s_logger.debug(String.format("PBD [%s] of local SR [%s] was unplugged, pluggin it now", pbd.getUuid(conn), srRec.uuid));
+                        pbd.plug(conn);
+                    }
+                    s_logger.debug("Scanning local SR: " + srRec.uuid);
+                    SR sr = entry.getKey();
+                    sr.scan(conn);
+                    localSrs.add(sr);
+                }
+            }
+        }
+        s_logger.debug(String.format("Found %d local storage of type [%s] for host [%s]", localSrs.size(), srType.toString(), _host.getUuid()));
+        return localSrs;
+    }
+
+    /**
+     *  This method will prepare Local SRs to be used by Apache CloudStack.
+     */
+    protected List<StartupStorageCommand> initializeLocalSrs(Connection conn) throws XenAPIException, XmlRpcException {
+        List<StartupStorageCommand> localStorageStartupCommands = new ArrayList<>();
+        List<SR> allLocalSrs = getAllLocalSrs(conn);
+
+        for (SR sr : allLocalSrs) {
+            long totalCapacity = sr.getPhysicalSize(conn);
+            if (totalCapacity > 0) {
+                StartupStorageCommand cmd = createStartUpStorageCommand(conn, sr);
+                localStorageStartupCommands.add(cmd);
+            }
+        }
+        return localStorageStartupCommands;
+    }
+
+    /**
+     * This method will retrieve all Local SRs according to {@link #getAllLocalSrForType(Connection, SRType)}.
+     * The types used are {@link SRType#LVM} and {@link SRType#EXT}.
+     *
+     */
+    protected List<SR> getAllLocalSrs(Connection conn) throws XenAPIException, XmlRpcException {
+        List<SR> allLocalSrLvmType = getAllLocalSrForType(conn, SRType.LVM);
+        List<SR> allLocalSrExtType = getAllLocalSrForType(conn, SRType.EXT);
+        List<SR> allLocalSrs = new ArrayList<>(allLocalSrLvmType);
+        allLocalSrs.addAll(allLocalSrExtType);
+        return allLocalSrs;
+    }
+
+    /**
+     * This method creates the StartUp storage command for the local SR.
+     * We will configure 'name-label' and 'description' using {@link #configureStorageNameAndDescription(Connection, SR)}.
+     * Then, we will create the POJO {@link StoragePoolInfo} with SR's information using method {@link #createStoragePoolInfo(Connection, SR)}.
+     */
+    protected StartupStorageCommand createStartUpStorageCommand(Connection conn, SR sr) throws XenAPIException, XmlRpcException {
+        configureStorageNameAndDescription(conn, sr);
+
+        StoragePoolInfo storagePoolInfo = createStoragePoolInfo(conn, sr);
+
+        StartupStorageCommand cmd = new StartupStorageCommand();
+        cmd.setPoolInfo(storagePoolInfo);
+        cmd.setGuid(_host.getUuid());
+        cmd.setDataCenter(Long.toString(_dcId));
+        cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
+
+        String.format("StartUp command created for local storage [%s] of type [%s] on host [%s]", storagePoolInfo.getUuid(), storagePoolInfo.getPoolType(), _host.getUuid());
+        return cmd;
+    }
+
+    /**
+     *  Instantiate {@link StoragePoolInfo} with SR's information.
+     */
+    protected StoragePoolInfo createStoragePoolInfo(Connection conn, SR sr) throws XenAPIException, XmlRpcException {
+        long totalCapacity = sr.getPhysicalSize(conn);
+        String srUuid = sr.getUuid(conn);
+        Host host = Host.getByUuid(conn, _host.getUuid());
+        String address = host.getAddress(conn);
+        long availableCapacity = totalCapacity - sr.getPhysicalUtilisation(conn);
+        String srType = sr.getType(conn).toUpperCase();
+        return new StoragePoolInfo(srUuid, address, srType, srType, StoragePoolType.valueOf(srType), totalCapacity, availableCapacity);
+    }
+
+    protected void configureStorageNameAndDescription(Connection conn, SR sr) throws XenAPIException, XmlRpcException {
+        String srUuid = sr.getUuid(conn);
+        sr.setNameLabel(conn, srUuid);
+
+        String nameFormat = "Cloud Stack Local (%s) Storage Pool for %s";
+        sr.setNameDescription(conn, String.format(nameFormat, sr.getType(conn), _host.getUuid()));
+    }
+
+    public boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId) {
+        // Figure out the disk number to attach the VM to
+
+        String msg = null;
+        try {
+            final Set<String> allowedVBDDevices = vm.getAllowedVBDDevices(conn);
+            if (allowedVBDDevices.contains(deviceId.toString())) {
+                return false;
+            }
+            return true;
+        } catch (final XmlRpcException e) {
+            msg = "Catch XmlRpcException due to: " + e.getMessage();
+            s_logger.warn(msg, e);
+        } catch (final XenAPIException e) {
+            msg = "Catch XenAPIException due to: " + e.toString();
+            s_logger.warn(msg, e);
+        }
+        throw new CloudRuntimeException("When check deviceId " + msg);
+    }
+
+    /**
+     * When Dynamic Memory Control (DMC) is enabled - xenserver allows scaling
+     * the guest memory while the guest is running
+     *
+     * By default this is disallowed, override the specific xenserver resource
+     * if this is enabled
+     */
+    public boolean isDmcEnabled(final Connection conn, final Host host) throws XenAPIException, XmlRpcException {
+        return false;
+    }
+
+    public boolean IsISCSI(final String type) {
+        return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
+    }
+
+    public boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException {
+        if (nameTag != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Looking for network setup by name " + nameTag);
+            }
+            final Connection conn = getConnection();
+            final XsLocalNetwork network = getNetworkByName(conn, nameTag);
+            if (network == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean isOvs() {
+        return _isOvs;
+    }
+
+    public boolean isRefNull(final XenAPIObject object) {
+        return object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals("<not in database>");
+    }
+
+    public boolean isSecurityGroupEnabled() {
+        return _securityGroupEnabled;
+    }
+
+    public boolean isXcp() {
+        final Connection conn = getConnection();
+        final String result = callHostPlugin(conn, "ovstunnel", "is_xcp");
+        if (result.equals("XCP")) {
+            return true;
+        }
+        return false;
+    }
+
+    boolean killCopyProcess(final Connection conn, final String nameLabel) {
+        final String results = callHostPluginAsync(conn, "vmops", "kill_copy_process", 60, "namelabel", nameLabel);
+        String errMsg = null;
+        if (results == null || results.equals("false")) {
+            errMsg = "kill_copy_process failed";
+            s_logger.warn(errMsg);
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public boolean launchHeartBeat(final Connection conn) {
+        final String result = callHostPluginPremium(conn, "heartbeat", "host", _host.getUuid(), "timeout", Integer.toString(_heartbeatTimeout), "interval", Integer.toString(_heartbeatInterval));
+        if (result == null || !result.contains("> DONE <")) {
+            s_logger.warn("Unable to launch the heartbeat process on " + _host.getIp());
+            return false;
+        }
+        return true;
+    }
+
+    protected String logX(final XenAPIObject obj, final String msg) {
+        return new StringBuilder("Host ").append(_host.getIp()).append(" ").append(obj.toWireString()).append(": ").append(msg).toString();
+    }
+
+    public void migrateVM(final Connection conn, final Host destHost, final VM vm, final String vmName) throws Exception {
+        Task task = null;
+        try {
+            final Map<String, String> other = new HashMap<String, String>();
+            other.put("live", "true");
+            task = vm.poolMigrateAsync(conn, destHost, other);
+            try {
+                // poll every 1 seconds
+                final long timeout = _migratewait * 1000L;
+                waitForTask(conn, task, 1000, timeout);
+                checkForSuccess(conn, task);
+            } catch (final Types.HandleInvalid e) {
+                if (vm.getResidentOn(conn).equals(destHost)) {
+                    task = null;
+                    return;
+                }
+                throw new CloudRuntimeException("migrate VM catch HandleInvalid and VM is not running on dest host");
+            }
+        } catch (final XenAPIException e) {
+            final String msg = "Unable to migrate VM(" + vmName + ") from host(" + _host.getUuid() + ")";
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+    }
+
+    protected VDI mount(final Connection conn, final StoragePoolType poolType, final String volumeFolder, final String volumePath) {
+        return getVDIbyUuid(conn, volumePath);
+    }
+
+    protected VDI mount(final Connection conn, final String vmName, final DiskTO volume) throws XmlRpcException, XenAPIException {
+        final DataTO data = volume.getData();
+        final Volume.Type type = volume.getType();
+        if (type == Volume.Type.ISO) {
+            final TemplateObjectTO iso = (TemplateObjectTO)data;
+            final DataStoreTO store = iso.getDataStore();
+
+            if (store == null) {
+                // It's a fake iso
+                return null;
+            }
+
+            // corer case, xenserver pv driver iso
+            final String templateName = iso.getName();
+            if (templateName.startsWith("xs-tools")) {
+                try {
+                    final String actualTemplateName = getActualIsoTemplate(conn);
+                    final Set<VDI> vdis = VDI.getByNameLabel(conn, actualTemplateName);
+                    if (vdis.isEmpty()) {
+                        throw new CloudRuntimeException("Could not find ISO with URL: " + actualTemplateName);
+                    }
+                    return vdis.iterator().next();
+                } catch (final XenAPIException e) {
+                    throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString());
+                } catch (final Exception e) {
+                    throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString());
+                }
+            }
+
+            if (!(store instanceof NfsTO)) {
+                throw new CloudRuntimeException("only support mount iso on nfs");
+            }
+            final NfsTO nfsStore = (NfsTO)store;
+            final String isoPath = nfsStore.getUrl() + File.separator + iso.getPath();
+            final int index = isoPath.lastIndexOf("/");
+
+            final String mountpoint = isoPath.substring(0, index);
+            URI uri;
+            try {
+                uri = new URI(mountpoint);
+            } catch (final URISyntaxException e) {
+                throw new CloudRuntimeException("Incorrect uri " + mountpoint, e);
+            }
+            final SR isoSr = createIsoSRbyURI(conn, uri, vmName, false);
+
+            final String isoname = isoPath.substring(index + 1);
+
+            final VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr);
+
+            if (isoVdi == null) {
+                throw new CloudRuntimeException("Unable to find ISO " + isoPath);
+            }
+            return isoVdi;
+        } else {
+            final VolumeObjectTO vol = (VolumeObjectTO)data;
+            return VDI.getByUuid(conn, vol.getPath());
+        }
+    }
+
+    public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) {
+        if (option.equals("get")) {
+            return "0:0";
+        }
+        return null;
+    }
+
+    private List<Pair<String, Long>> ovsFullSyncStates() {
+        final Connection conn = getConnection();
+        final String result = callHostPlugin(conn, "ovsgre", "ovs_get_vm_log", "host_uuid", _host.getUuid());
+        final String[] logs = result != null ? result.split(";") : new String[0];
+        final List<Pair<String, Long>> states = new ArrayList<Pair<String, Long>>();
+        for (final String log : logs) {
+            final String[] info = log.split(",");
+            if (info.length != 5) {
+                s_logger.warn("Wrong element number in ovs log(" + log + ")");
+                continue;
+            }
+
+            // ','.join([bridge, vmName, vmId, seqno, tag])
+            try {
+                states.add(new Pair<String, Long>(info[0], Long.parseLong(info[3])));
+            } catch (final NumberFormatException nfe) {
+                states.add(new Pair<String, Long>(info[0], -1L));
+            }
+        }
+        return states;
+    }
+
+    public HashMap<String, String> parseDefaultOvsRuleComamnd(final String str) {
+        final HashMap<String, String> cmd = new HashMap<String, String>();
+        final String[] sarr = str.split("/");
+        for (int i = 0; i < sarr.length; i++) {
+            String c = sarr[i];
+            c = c.startsWith("/") ? c.substring(1) : c;
+            c = c.endsWith("/") ? c.substring(0, c.length() - 1) : c;
+            final String[] p = c.split(";");
+            if (p.length != 2) {
+                continue;
+            }
+            if (p[0].equalsIgnoreCase("vlans")) {
+                p[1] = p[1].replace("@", "[");
+                p[1] = p[1].replace("#", "]");
+            }
+            cmd.put(p[0], p[1]);
+        }
+        return cmd;
+    }
+
+    protected Pair<Long, Integer> parseTimestamp(final String timeStampStr) {
+        final String[] tokens = timeStampStr.split("-");
+        if (tokens.length != 3) {
+            s_logger.debug("timeStamp in network has wrong pattern: " + timeStampStr);
+            return null;
+        }
+        if (!tokens[0].equals("CsCreateTime")) {
+            s_logger.debug("timeStamp in network doesn't start with CsCreateTime: " + timeStampStr);
+            return null;
+        }
+        return new Pair<Long, Integer>(Long.parseLong(tokens[1]), Integer.parseInt(tokens[2]));
+    }
+
+    private void pbdPlug(final Connection conn, final PBD pbd, final String uuid) {
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Plugging in PBD " + uuid + " for " + _host);
+            }
+            pbd.plug(conn);
+        } catch (final Exception e) {
+            final String msg = "PBD " + uuid + " is not attached! and PBD plug failed due to " + e.toString() + ". Please check this PBD in " + _host;
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    protected boolean pingdomr(final Connection conn, final String host, final String port) {
+        String status;
+        status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port);
+
+        if (status == null || status.isEmpty()) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    public boolean pingXAPI() {
+        final Connection conn = getConnection();
+        try {
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            if (!host.getEnabled(conn)) {
+                s_logger.debug("Host " + _host.getIp() + " is not enabled!");
+                return false;
+            }
+        } catch (final Exception e) {
+            s_logger.debug("cannot get host enabled status, host " + _host.getIp() + " due to " + e.toString(), e);
+            return false;
+        }
+        try {
+            callHostPlugin(conn, "echo", "main");
+        } catch (final Exception e) {
+            s_logger.debug("cannot ping host " + _host.getIp() + " due to " + e.toString(), e);
+            return false;
+        }
+        return true;
+    }
+
+    protected void plugDom0Vif(final Connection conn, final VIF dom0Vif) throws XmlRpcException, XenAPIException {
+        if (dom0Vif != null) {
+            dom0Vif.plug(conn);
+        }
+    }
+
+    protected boolean postCreatePrivateTemplate(final Connection conn, final String templatePath, final String tmpltFilename, final String templateName, String templateDescription, String checksum,
+            final long size, final long virtualSize, final long templateId) {
+
+        if (templateDescription == null) {
+            templateDescription = "";
+        }
+
+        if (checksum == null) {
+            checksum = "";
+        }
+
+        final String result = callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", templateName,
+                "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), "templateId", String.valueOf(templateId));
+
+        boolean success = false;
+        if (result != null && !result.isEmpty()) {
+            // Else, command threw an exception which has already been logged.
+
+            if (result.equalsIgnoreCase("1")) {
+                s_logger.debug("Successfully created template.properties file on secondary storage for " + tmpltFilename);
+                success = true;
+            } else {
+                s_logger.warn("Could not create template.properties file on secondary storage for " + tmpltFilename + " for templateId: " + templateId);
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(final NetworkElementCommand cmd) {
+        // Update IP used to access router
+        cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            return prepareNetworkElementCommand((SetNetworkACLCommand)cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    public void prepareISO(final Connection conn, final String vmName, List<String[]> vmDataList, String configDriveLabel) throws XmlRpcException, XenAPIException {
+
+        final Set<VM> vms = VM.getByNameLabel(conn, vmName);
+        if (vms == null || vms.size() != 1) {
+            throw new CloudRuntimeException("There are " + (vms == null ? "0" : vms.size()) + " VMs named " + vmName);
+        }
+        final VM vm = vms.iterator().next();
+
+        if (vmDataList != null) {
+            // create SR
+            SR sr = createLocalIsoSR(conn, _configDriveSRName + getHost().getIp());
+
+            // 1. create vm data files
+            createVmdataFiles(vmName, vmDataList, configDriveLabel);
+
+            // 2. copy config drive iso to host
+            copyConfigDriveIsoToHost(conn, sr, vmName);
+        }
+
+        final Set<VBD> vbds = vm.getVBDs(conn);
+        for (final VBD vbd : vbds) {
+            final VBD.Record vbdr = vbd.getRecord(conn);
+            if (vbdr.type == Types.VbdType.CD && vbdr.empty == false && vbdr.userdevice.equals(_attachIsoDeviceNum)) {
+                final VDI vdi = vbdr.VDI;
+                final SR sr = vdi.getSR(conn);
+                final Set<PBD> pbds = sr.getPBDs(conn);
+                if (pbds == null) {
+                    throw new CloudRuntimeException("There is no pbd for sr " + sr);
+                }
+                for (final PBD pbd : pbds) {
+                    final PBD.Record pbdr = pbd.getRecord(conn);
+                    if (pbdr.host.getUuid(conn).equals(_host.getUuid())) {
+                        return;
+                    }
+                }
+                sr.setShared(conn, true);
+                final Host host = Host.getByUuid(conn, _host.getUuid());
+                final PBD.Record pbdr = pbds.iterator().next().getRecord(conn);
+                pbdr.host = host;
+                pbdr.uuid = "";
+                final PBD pbd = PBD.create(conn, pbdr);
+                pbdPlug(conn, pbd, pbd.getUuid(conn));
+                break;
+            }
+        }
+    }
+
+    // The idea here is to see if the DiskTO in question is from managed storage and does not yet have an SR.
+    // If no SR, create it and create a VDI in it.
+    public VDI prepareManagedDisk(final Connection conn, final DiskTO disk, final long vmId, final String vmName) throws Exception {
+        final Map<String, String> details = disk.getDetails();
+
+        if (details == null) {
+            return null;
+        }
+
+        final boolean isManaged = new Boolean(details.get(DiskTO.MANAGED)).booleanValue();
+
+        if (!isManaged) {
+            return null;
+        }
+
+        final String iqn = details.get(DiskTO.IQN);
+
+        final Set<SR> srNameLabels = SR.getByNameLabel(conn, iqn);
+
+        if (srNameLabels.size() != 0) {
+            return null;
+        }
+
+        final String vdiNameLabel = Volume.Type.ROOT.equals(disk.getType()) ? ("ROOT-" + vmId) : (vmName + "-DATA");
+
+        return prepareManagedStorage(conn, details, null, vdiNameLabel);
+    }
+
+    protected SR prepareManagedSr(final Connection conn, final Map<String, String> details) {
+        final String iScsiName = details.get(DiskTO.IQN);
+        final String storageHost = details.get(DiskTO.STORAGE_HOST);
+        final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
+        final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
+        final String mountpoint = details.get(DiskTO.MOUNT_POINT);
+        final String protocoltype = details.get(DiskTO.PROTOCOL_TYPE);
+
+        if (StoragePoolType.NetworkFilesystem.toString().equalsIgnoreCase(protocoltype)) {
+            final String poolid = storageHost + ":" + mountpoint;
+            final String namelable = mountpoint;
+            final String volumedesc = storageHost + ":" + mountpoint;
+
+            return getNfsSR(conn, poolid, namelable, storageHost, mountpoint, volumedesc);
+        } else {
+            return getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, SRType.LVMOISCSI.toString(), true);
+        }
+    }
+
+    protected VDI prepareManagedStorage(final Connection conn, final Map<String, String> details, final String path, final String vdiNameLabel) throws Exception {
+        final SR sr = prepareManagedSr(conn, details);
+
+        VDI vdi = getVDIbyUuid(conn, path, false);
+        final Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
+
+        Set<VDI> vdisInSr = sr.getVDIs(conn);
+
+        // If a VDI already exists in the SR (in case we cloned from a template cache), use that.
+        if (vdisInSr.size() == 1) {
+            vdi = vdisInSr.iterator().next();
+        }
+
+        if (vdi == null) {
+            vdi = createVdi(sr, vdiNameLabel, volumeSize);
+        } else {
+            // If vdi is not null, it must have already been created, so check whether a resize of the volume was performed.
+            // If true, resize the VDI to the volume size.
+
+            s_logger.info("Checking for the resize of the datadisk");
+
+            final long vdiVirtualSize = vdi.getVirtualSize(conn);
+
+            if (vdiVirtualSize != volumeSize) {
+                s_logger.info("Resizing the data disk (VDI) from vdiVirtualSize: " + vdiVirtualSize + " to volumeSize: " + volumeSize);
+
+                try {
+                    vdi.resize(conn, volumeSize);
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to resize volume", e);
+                }
+            }
+
+            // change the name-label in case of a cloned VDI
+            if (!Objects.equals(vdi.getNameLabel(conn), vdiNameLabel)) {
+                try {
+                    vdi.setNameLabel(conn, vdiNameLabel);
+                } catch (final Exception e) {
+                    s_logger.warn("Unable to rename volume", e);
+                }
+            }
+        }
+
+        return vdi;
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) {
+        final Connection conn = getConnection();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+
+        try {
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            for (final IpAddressTO ip : ips) {
+
+                final VM router = getVM(conn, routerName);
+
+                final NicTO nic = new NicTO();
+                nic.setMac(ip.getVifMacAddress());
+                nic.setType(ip.getTrafficType());
+                if (ip.getBroadcastUri() == null) {
+                    nic.setBroadcastType(BroadcastDomainType.Native);
+                } else {
+                    final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+                    nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri));
+                    nic.setBroadcastUri(uri);
+                }
+                nic.setDeviceId(0);
+                nic.setNetworkRateMbps(ip.getNetworkRate());
+                nic.setName(ip.getNetworkName());
+
+                final Network network = getNetwork(conn, nic);
+
+                // Determine the correct VIF on DomR to associate/disassociate
+                // the
+                // IP address with
+                VIF correctVif = getCorrectVif(conn, router, network);
+
+                // If we are associating an IP address and DomR doesn't have a
+                // VIF
+                // for the specified vlan ID, we need to add a VIF
+                // If we are disassociating the last IP address in the VLAN, we
+                // need
+                // to remove a VIF
+                boolean addVif = false;
+                if (ip.isAdd() && correctVif == null) {
+                    addVif = true;
+                }
+
+                if (addVif) {
+                    // Add a new VIF to DomR
+                    final String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router);
+
+                    if (vifDeviceNum == null) {
+                        throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn));
+                    }
+
+                    nic.setDeviceId(Integer.parseInt(vifDeviceNum));
+
+                    correctVif = createVif(conn, routerName, router, null, nic);
+                    correctVif.plug(conn);
+                    // Add iptables rule for network usage
+                    networkUsage(conn, routerIp, "addVif", "eth" + correctVif.getDevice(conn));
+                }
+
+                if (ip.isAdd() && correctVif == null) {
+                    throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
+                }
+                if (correctVif != null) {
+                    ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
+                    ip.setNewNic(addVif);
+                }
+            }
+        } catch (final InternalErrorException e) {
+            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.getMessage());
+        } catch (final Exception e) {
+            return new ExecutionResult(false, e.getMessage());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) {
+        final Connection conn = getConnection();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        try {
+            final IpAddressTO[] ips = cmd.getIpAddresses();
+            for (final IpAddressTO ip : ips) {
+
+                final VM router = getVM(conn, routerName);
+
+                final VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress());
+                setNicDevIdIfCorrectVifIsNotNull(conn, ip, correctVif);
+            }
+        } catch (final Exception e) {
+            s_logger.error("Ip Assoc failure on applying one ip due to exception:  ", e);
+            return new ExecutionResult(false, e.getMessage());
+        }
+
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) {
+        final Connection conn = getConnection();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+        try {
+            final VM router = getVM(conn, routerName);
+
+            final NicTO nic = cmd.getNic();
+            if (nic != null) {
+                final VIF vif = getVifByMac(conn, router, nic.getMac());
+                if (vif == null) {
+                    final String msg = "Prepare SetNetworkACL failed due to VIF is null for : " + nic.getMac() + " with routername: " + routerName;
+                    s_logger.error(msg);
+                    return new ExecutionResult(false, msg);
+                }
+                nic.setDeviceId(Integer.parseInt(vif.getDevice(conn)));
+            } else {
+                final String msg = "Prepare SetNetworkACL failed due to nic is null for : " + routerName;
+                s_logger.error(msg);
+                return new ExecutionResult(false, msg);
+            }
+        } catch (final Exception e) {
+            final String msg = "Prepare SetNetworkACL failed due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) {
+        final Connection conn = getConnection();
+        final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        final IpAddressTO pubIp = cmd.getIpAddress();
+        try {
+            final VM router = getVM(conn, routerName);
+
+            final VIF correctVif = getCorrectVif(conn, router, pubIp);
+
+            pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
+
+        } catch (final Exception e) {
+            final String msg = "Ip SNAT failure due to " + e.toString();
+            s_logger.error(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    /**
+     * @param cmd
+     * @return
+     */
+    private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) {
+        final Connection conn = getConnection();
+        final NicTO nic = cmd.getNic();
+        final String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        try {
+            final Set<VM> vms = VM.getByNameLabel(conn, domrName);
+            if (vms == null || vms.isEmpty()) {
+                return new ExecutionResult(false, "Can not find VM " + domrName);
+            }
+            final VM vm = vms.iterator().next();
+            final String mac = nic.getMac();
+            VIF domrVif = null;
+            for (final VIF vif : vm.getVIFs(conn)) {
+                final String lmac = vif.getMAC(conn);
+                if (lmac.equals(mac)) {
+                    domrVif = vif;
+                    // Do not break it! We have 2 routers.
+                    // break;
+                }
+            }
+            if (domrVif == null) {
+                return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName);
+            }
+
+            nic.setDeviceId(Integer.parseInt(domrVif.getDevice(conn)));
+        } catch (final Exception e) {
+            final String msg = "Creating guest network failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    public void rebootVM(final Connection conn, final VM vm, final String vmName) throws Exception {
+        Task task = null;
+        try {
+            task = vm.cleanRebootAsync(conn);
+            try {
+                // poll every 1 seconds , timeout after 10 minutes
+                waitForTask(conn, task, 1000, 10 * 60 * 1000);
+                checkForSuccess(conn, task);
+            } catch (final Types.HandleInvalid e) {
+                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
+                    task = null;
+                    return;
+                }
+                throw new CloudRuntimeException("Reboot VM catch HandleInvalid and VM is not in RUNNING state");
+            }
+        } catch (final XenAPIException e) {
+            s_logger.debug("Unable to Clean Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString() + ", try hard reboot");
+            try {
+                vm.hardReboot(conn);
+            } catch (final Exception e1) {
+                final String msg = "Unable to hard Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
+                s_logger.warn(msg, e1);
+                throw new CloudRuntimeException(msg);
+            }
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+    }
+
+    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;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(logX(sr, "Removing SR"));
+        }
+
+        for (int i = 0; i < 2; i++) {
+            try {
+                final Set<VDI> vdis = sr.getVDIs(conn);
+                for (final VDI vdi : vdis) {
+                    vdi.forget(conn);
+                }
+
+                Set<PBD> pbds = sr.getPBDs(conn);
+                for (final PBD pbd : pbds) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug(logX(pbd, "Unplugging pbd"));
+                    }
+
+                    // if (pbd.getCurrentlyAttached(conn)) {
+                    pbd.unplug(conn);
+                    // }
+
+                    pbd.destroy(conn);
+                }
+
+                pbds = sr.getPBDs(conn);
+
+                if (pbds.size() == 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug(logX(sr, "Forgetting"));
+                    }
+
+                    sr.forget(conn);
+
+                    return;
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(logX(sr, "There is still one or more PBDs attached."));
+
+                    if (s_logger.isTraceEnabled()) {
+                        for (final PBD pbd : pbds) {
+                            s_logger.trace(logX(pbd, " Still attached"));
+                        }
+                    }
+                }
+            } catch (final XenAPIException e) {
+                s_logger.debug(logX(sr, "Catch XenAPIException: " + e.toString()));
+            } catch (final XmlRpcException e) {
+                s_logger.debug(logX(sr, "Catch Exception: " + e.getMessage()));
+            }
+        }
+
+        s_logger.warn(logX(sr, "Unable to remove SR"));
+    }
+
+    protected String removeSRSync(final Connection conn, final SR sr) {
+        if (sr == null) {
+            return null;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(logX(sr, "Removing SR"));
+        }
+        long waittime = 0;
+        try {
+            final Set<VDI> vdis = sr.getVDIs(conn);
+            for (final VDI vdi : vdis) {
+                final Map<java.lang.String, Types.VdiOperations> currentOperation = vdi.getCurrentOperations(conn);
+                if (currentOperation == null || currentOperation.size() == 0) {
+                    continue;
+                }
+                if (waittime >= 1800000) {
+                    final String msg = "This template is being used, try late time";
+                    s_logger.warn(msg);
+                    return msg;
+                }
+                waittime += 30000;
+                try {
+                    Thread.sleep(30000);
+                } catch (final InterruptedException ex) {
+                }
+            }
+            removeSR(conn, sr);
+            return null;
+        } catch (final XenAPIException e) {
+            s_logger.warn(logX(sr, "Unable to get current opertions " + e.toString()), e);
+        } catch (final XmlRpcException e) {
+            s_logger.warn(logX(sr, "Unable to get current opertions " + e.getMessage()), e);
+        }
+        final String msg = "Remove SR failed";
+        s_logger.warn(msg);
+        return msg;
+
+    }
+
+    public String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID)
+            throws XenAPIException, XmlRpcException {
+
+        final String results = callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", oldVmUuid,
+                "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID);
+        String errMsg = null;
+        if (results == null || results.isEmpty()) {
+            errMsg = "revert_memory_snapshot return null";
+        } else {
+            if (results.equals("0")) {
+                return results;
+            } else {
+                errMsg = "revert_memory_snapshot exception";
+            }
+        }
+        s_logger.warn(errMsg);
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    public void scaleVM(final Connection conn, final VM vm, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException {
+
+        final Long staticMemoryMax = vm.getMemoryStaticMax(conn);
+        final Long staticMemoryMin = vm.getMemoryStaticMin(conn);
+        final Long newDynamicMemoryMin = vmSpec.getMinRam();
+        final Long newDynamicMemoryMax = vmSpec.getMaxRam();
+        if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) {
+            throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin + ") <= memory-dynamic-min("
+                    + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")");
+        }
+
+        vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax);
+        vm.setVCPUsNumberLive(conn, (long)vmSpec.getCpus());
+
+        final Integer speed = vmSpec.getMinSpeed();
+        if (speed != null) {
+
+            int cpuWeight = _maxWeight; // cpu_weight
+
+            // weight based allocation
+
+            cpuWeight = (int)(speed * 0.99 / _host.getSpeed() * _maxWeight);
+            if (cpuWeight > _maxWeight) {
+                cpuWeight = _maxWeight;
+            }
+
+            if (vmSpec.getLimitCpuUse()) {
+                long utilization = 0; // max CPU cap, default is unlimited
+                utilization = (int)(vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100);
+                // vm.addToVCPUsParamsLive(conn, "cap",
+                // Long.toString(utilization)); currently xenserver doesnot
+                // support Xapi to add VCPUs params live.
+                callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", Long.toString(utilization), "vmname", vmSpec.getName());
+            }
+            // vm.addToVCPUsParamsLive(conn, "weight",
+            // Integer.toString(cpuWeight));
+            callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName());
+        }
+    }
+
+    @Override
+    public void setAgentControl(final IAgentControl agentControl) {
+        _agentControl = agentControl;
+    }
+
+    public void setCanBridgeFirewall(final boolean canBridgeFirewall) {
+        _canBridgeFirewall = canBridgeFirewall;
+    }
+
+    @Override
+    public void setConfigParams(final Map<String, Object> params) {
+    }
+
+    public boolean setIptables(final Connection conn) {
+        final String result = callHostPlugin(conn, "vmops", "setIptables");
+        if (result == null || result.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    public void setIsOvs(final boolean isOvs) {
+        _isOvs = isOvs;
+    }
+
+    /**
+     * WARN: static-min <= dynamic-min <= dynamic-max <= static-max
+     *
+     * @see XcpServerResource#setMemory(com.xensource.xenapi.Connection,
+     *      com.xensource.xenapi.VM, long, long)
+     * @param conn
+     * @param vm
+     * @param minMemsize
+     * @param maxMemsize
+     * @throws XmlRpcException
+     * @throws XenAPIException
+     */
+    protected void setMemory(final Connection conn, final VM vm, final long minMemsize, final long maxMemsize) throws XmlRpcException, XenAPIException {
+        vm.setMemoryLimits(conn, mem_128m, maxMemsize, minMemsize, maxMemsize);
+    }
+
+    @Override
+    public void setName(final String name) {
+    }
+
+    protected void setNicDevIdIfCorrectVifIsNotNull(final Connection conn, final IpAddressTO ip, final VIF correctVif)
+            throws InternalErrorException, BadServerResponse, XenAPIException, XmlRpcException {
+        if (correctVif == null) {
+            if (ip.isAdd()) {
+                throw new InternalErrorException("Failed to find DomR VIF to associate IP with.");
+            } else {
+                s_logger.debug("VIF to deassociate IP with does not exist, return success");
+            }
+        } else {
+            ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn)));
+        }
+    }
+
+    @Override
+    public void setRunLevel(final int level) {
+    }
+
+    public String setupHeartbeatSr(final Connection conn, final SR sr, final boolean force) throws XenAPIException, XmlRpcException {
+        final SR.Record srRec = sr.getRecord(conn);
+        final String srUuid = srRec.uuid;
+        if (!srRec.shared || !SRType.LVMOHBA.equals(srRec.type) && !SRType.LVMOISCSI.equals(srRec.type) && !SRType.NFS.equals(srRec.type)) {
+            return srUuid;
+        }
+        String result = null;
+        final Host host = Host.getByUuid(conn, _host.getUuid());
+        final Set<String> tags = host.getTags(conn);
+        if (force || !tags.contains("cloud-heartbeat-" + srUuid)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Setting up the heartbeat sr for host " + _host.getIp() + " and sr " + srUuid);
+            }
+            final Set<PBD> pbds = sr.getPBDs(conn);
+            for (final PBD pbd : pbds) {
+                final PBD.Record pbdr = pbd.getRecord(conn);
+                if (!pbdr.currentlyAttached && pbdr.host.getUuid(conn).equals(_host.getUuid())) {
+                    pbd.plug(conn);
+                    break;
+                }
+            }
+            result = callHostPluginThroughMaster(conn, "vmopspremium", "setup_heartbeat_sr", "host", _host.getUuid(), "sr", srUuid);
+            if (result == null || !result.split("#")[1].equals("0")) {
+                throw new CloudRuntimeException("Unable to setup heartbeat sr on SR " + srUuid + " due to " + result);
+            }
+
+            if (!tags.contains("cloud-heartbeat-" + srUuid)) {
+                tags.add("cloud-heartbeat-" + srUuid);
+                host.setTags(conn, tags);
+            }
+        }
+        result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.getUuid(), "sr", srUuid, "add", "true");
+        if (result == null || !result.split("#")[1].equals("0")) {
+            throw new CloudRuntimeException("Unable to setup heartbeat file entry on SR " + srUuid + " due to " + result);
+        }
+        return srUuid;
+    }
+
+    public void setupLinkLocalNetwork(final Connection conn) {
+        try {
+            final Network.Record rec = new Network.Record();
+            final Set<Network> networks = Network.getByNameLabel(conn, _linkLocalPrivateNetworkName);
+            Network linkLocal = null;
+
+            if (networks.size() == 0) {
+                rec.nameDescription = "link local network used by system vms";
+                rec.nameLabel = _linkLocalPrivateNetworkName;
+                final Map<String, String> configs = new HashMap<String, String>();
+                configs.put("ip_begin", NetUtils.getLinkLocalGateway());
+                configs.put("ip_end", NetUtils.getLinkLocalIpEnd());
+                configs.put("netmask", NetUtils.getLinkLocalNetMask());
+                configs.put("vswitch-disable-in-band", "true");
+                rec.otherConfig = configs;
+                linkLocal = Network.create(conn, rec);
+            } else {
+                linkLocal = networks.iterator().next();
+                if (!linkLocal.getOtherConfig(conn).containsKey("vswitch-disable-in-band")) {
+                    linkLocal.addToOtherConfig(conn, "vswitch-disable-in-band", "true");
+                }
+            }
+
+            /* Make sure there is a physical bridge on this network */
+            VIF dom0vif = null;
+            final Pair<VM, VM.Record> vm = getControlDomain(conn);
+            final VM dom0 = vm.first();
+            final Set<VIF> vifs = dom0.getVIFs(conn);
+            if (vifs.size() != 0) {
+                for (final VIF vif : vifs) {
+                    final Map<String, String> otherConfig = vif.getOtherConfig(conn);
+                    if (otherConfig != null) {
+                        final String nameLabel = otherConfig.get("nameLabel");
+                        if (nameLabel != null && nameLabel.equalsIgnoreCase("link_local_network_vif")) {
+                            dom0vif = vif;
+                        }
+                    }
+                }
+            }
+
+            /* create temp VIF0 */
+            if (dom0vif == null) {
+                s_logger.debug("Can't find a vif on dom0 for link local, creating a new one");
+                final VIF.Record vifr = new VIF.Record();
+                vifr.VM = dom0;
+                vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0);
+                if (vifr.device == null) {
+                    s_logger.debug("Failed to create link local network, no vif available");
+                    return;
+                }
+                final Map<String, String> config = new HashMap<String, String>();
+                config.put("nameLabel", "link_local_network_vif");
+                vifr.otherConfig = config;
+                vifr.MAC = "FE:FF:FF:FF:FF:FF";
+                vifr.network = linkLocal;
+                vifr.lockingMode = Types.VifLockingMode.NETWORK_DEFAULT;
+                dom0vif = VIF.create(conn, vifr);
+                plugDom0Vif(conn, dom0vif);
+            } else {
+                s_logger.debug("already have a vif on dom0 for link local network");
+                if (!dom0vif.getCurrentlyAttached(conn)) {
+                    plugDom0Vif(conn, dom0vif);
+                }
+            }
+
+            final String brName = linkLocal.getBridge(conn);
+            callHostPlugin(conn, "vmops", "setLinkLocalIP", "brName", brName);
+            _host.setLinkLocalNetwork(linkLocal.getUuid(conn));
+
+        } catch (final XenAPIException e) {
+            s_logger.warn("Unable to create local link network", e);
+            throw new CloudRuntimeException("Unable to create local link network due to " + e.toString(), e);
+        } catch (final XmlRpcException e) {
+            s_logger.warn("Unable to create local link network", e);
+            throw new CloudRuntimeException("Unable to create local link network due to " + e.toString(), e);
+        }
+    }
+
+    /* return : if setup is needed */
+    public boolean setupServer(final Connection conn, final Host host) {
+        final String packageVersion = CitrixResourceBase.class.getPackage().getImplementationVersion();
+        final String version = this.getClass().getName() + "-" + (packageVersion == null ? Long.toString(System.currentTimeMillis()) : packageVersion);
+
+        try {
+            /* push patches to XenServer */
+            final Host.Record hr = host.getRecord(conn);
+
+            final Iterator<String> it = hr.tags.iterator();
+
+            while (it.hasNext()) {
+                final String tag = it.next();
+                if (tag.startsWith("vmops-version-")) {
+                    if (tag.contains(version)) {
+                        s_logger.info(logX(host, "Host " + hr.address + " is already setup."));
+                        return false;
+                    } else {
+                        it.remove();
+                    }
+                }
+            }
+
+            final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22);
+            try {
+                sshConnection.connect(null, 60000, 60000);
+                if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
+                    throw new CloudRuntimeException("Unable to authenticate");
+                }
+
+                final String cmd = "mkdir -p /opt/cloud/bin /var/log/cloud";
+                if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+                    throw new CloudRuntimeException("Cannot create directory /opt/cloud/bin on XenServer hosts");
+                }
+
+                final SCPClient scp = new SCPClient(sshConnection);
+
+                final List<File> files = getPatchFiles();
+                if (files == null || files.isEmpty()) {
+                    throw new CloudRuntimeException("Can not find patch file");
+                }
+                for (final File file : files) {
+                    final String path = file.getParentFile().getAbsolutePath() + "/";
+                    final Properties props = PropertiesUtil.loadFromFile(file);
+
+                    for (final Map.Entry<Object, Object> entry : props.entrySet()) {
+                        final String k = (String)entry.getKey();
+                        final String v = (String)entry.getValue();
+
+                        assert k != null && k.length() > 0 && v != null && v.length() > 0 : "Problems with " + k + "=" + v;
+
+                        final String[] tokens = v.split(",");
+                        String f = null;
+                        if (tokens.length == 3 && tokens[0].length() > 0) {
+                            if (tokens[0].startsWith("/")) {
+                                f = tokens[0];
+                            } else if (tokens[0].startsWith("~")) {
+                                final String homedir = System.getenv("HOME");
+                                f = homedir + tokens[0].substring(1) + k;
+                            } else {
+                                f = path + tokens[0] + '/' + k;
+                            }
+                        } else {
+                            f = path + k;
+                        }
+                        final String directoryPath = tokens[tokens.length - 1];
+
+                        f = f.replace('/', File.separatorChar);
+
+                        String permissions = "0755";
+                        if (tokens.length == 3) {
+                            permissions = tokens[1];
+                        } else if (tokens.length == 2) {
+                            permissions = tokens[0];
+                        }
+
+                        if (!new File(f).exists()) {
+                            s_logger.warn("We cannot locate " + f);
+                            continue;
+                        }
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Copying " + f + " to " + directoryPath + " on " + hr.address + " with permission " + permissions);
+                        }
+
+                        if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "mkdir -m 700 -p " + directoryPath)) {
+                            s_logger.debug("Unable to create destination path: " + directoryPath + " on " + hr.address + ".");
+                        }
+
+                        try {
+                            scp.put(f, directoryPath, permissions);
+                        } catch (final IOException e) {
+                            final String msg = "Unable to copy file " + f + " to path " + directoryPath + " with permissions  " + permissions;
+                            s_logger.debug(msg);
+                            throw new CloudRuntimeException("Unable to setup the server: " + msg, e);
+                        }
+                    }
+                }
+
+            } catch (final IOException e) {
+                throw new CloudRuntimeException("Unable to setup the server correctly", e);
+            } finally {
+                sshConnection.close();
+            }
+            hr.tags.add("vmops-version-" + version);
+            host.setTags(conn, hr.tags);
+            return true;
+        } catch (final XenAPIException e) {
+            final String msg = "XenServer setup failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException("Unable to get host information " + e.toString(), e);
+        } catch (final XmlRpcException e) {
+            final String msg = "XenServer setup failed due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException("Unable to get host information ", e);
+        }
+    }
+
+    public synchronized Network setupvSwitchNetwork(final Connection conn) {
+        try {
+            if (_host.getVswitchNetwork() == null) {
+                Network vswitchNw = null;
+                final Network.Record rec = new Network.Record();
+                final String nwName = Networks.BroadcastScheme.VSwitch.toString();
+                final Set<Network> networks = Network.getByNameLabel(conn, nwName);
+
+                if (networks.size() == 0) {
+                    rec.nameDescription = "vswitch network for " + nwName;
+                    rec.nameLabel = nwName;
+                    vswitchNw = Network.create(conn, rec);
+                } else {
+                    vswitchNw = networks.iterator().next();
+                }
+                _host.setVswitchNetwork(vswitchNw);
+            }
+            return _host.getVswitchNetwork();
+        } catch (final BadServerResponse e) {
+            s_logger.error("Failed to setup vswitch network", e);
+        } catch (final XenAPIException e) {
+            s_logger.error("Failed to setup vswitch network", e);
+        } catch (final XmlRpcException e) {
+            s_logger.error("Failed to setup vswitch network", e);
+        }
+
+        return null;
+    }
+
+    public void shutdownVM(final Connection conn, final VM vm, final String vmName, final boolean forcedStop) throws XmlRpcException {
+        Task task = null;
+        try {
+            if (forcedStop) {
+                task = vm.hardShutdownAsync(conn);
+            } else {
+                task = vm.cleanShutdownAsync(conn);
+            }
+
+            try {
+                // poll every 1 seconds , timeout after 10 minutes
+                waitForTask(conn, task, 1000, 10 * 60 * 1000);
+                checkForSuccess(conn, task);
+            } catch (final TimeoutException e) {
+                if (vm.getPowerState(conn) == VmPowerState.HALTED) {
+                    task = null;
+                    return;
+                }
+                throw new CloudRuntimeException("Shutdown VM catch HandleInvalid and VM is not in HALTED state");
+            }
+        } catch (final XenAPIException e) {
+            s_logger.debug("Unable to shutdown VM(" + vmName + ") with force=" + forcedStop + " on host(" + _host.getUuid() + ") due to " + e.toString());
+            try {
+                VmPowerState state = vm.getPowerState(conn);
+                if (state == VmPowerState.RUNNING) {
+                    try {
+                        vm.hardShutdown(conn);
+                    } catch (final Exception e1) {
+                        s_logger.debug("Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString());
+                        state = vm.getPowerState(conn);
+                        if (state == VmPowerState.RUNNING) {
+                            forceShutdownVM(conn, vm);
+                        }
+                        return;
+                    }
+                } else if (state == VmPowerState.HALTED) {
+                    return;
+                } else {
+                    final String msg = "After cleanShutdown the VM status is " + state.toString() + ", that is not expected";
+                    s_logger.warn(msg);
+                    throw new CloudRuntimeException(msg);
+                }
+            } catch (final Exception e1) {
+                final String msg = "Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
+                s_logger.warn(msg, e1);
+                throw new CloudRuntimeException(msg);
+            }
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    public void startVM(final Connection conn, final Host host, final VM vm, final String vmName) throws Exception {
+        Task task = null;
+        try {
+            task = vm.startOnAsync(conn, host, false, true);
+            try {
+                // poll every 1 seconds , timeout after 10 minutes
+                waitForTask(conn, task, 1000, 10 * 60 * 1000);
+                checkForSuccess(conn, task);
+            } catch (final Types.HandleInvalid e) {
+                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
+                    s_logger.debug("VM " + vmName + " is in Running status", e);
+                    task = null;
+                    return;
+                }
+                throw new CloudRuntimeException("Start VM " + vmName + " catch HandleInvalid and VM is not in RUNNING state");
+            } catch (final TimeoutException e) {
+                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
+                    s_logger.debug("VM " + vmName + " is in Running status", e);
+                    task = null;
+                    return;
+                }
+                throw new CloudRuntimeException("Start VM " + vmName + " catch BadAsyncResult and VM is not in RUNNING state");
+            }
+        } catch (final XenAPIException e) {
+            final String msg = "Unable to start VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e1) {
+                    s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString());
+                }
+            }
+        }
+    }
+
+    protected void startvmfailhandle(final Connection conn, final VM vm, final List<Ternary<SR, VDI, VolumeVO>> mounts) {
+        if (vm != null) {
+            try {
+
+                if (vm.getPowerState(conn) == VmPowerState.RUNNING) {
+                    try {
+                        vm.hardShutdown(conn);
+                    } catch (final Exception e) {
+                        final String msg = "VM hardshutdown failed due to " + e.toString();
+                        s_logger.warn(msg, e);
+                    }
+                }
+                if (vm.getPowerState(conn) == VmPowerState.HALTED) {
+                    try {
+                        vm.destroy(conn);
+                    } catch (final Exception e) {
+                        final String msg = "VM destroy failed due to " + e.toString();
+                        s_logger.warn(msg, e);
+                    }
+                }
+            } catch (final Exception e) {
+                final String msg = "VM getPowerState failed due to " + e.toString();
+                s_logger.warn(msg, e);
+            }
+        }
+        if (mounts != null) {
+            for (final Ternary<SR, VDI, VolumeVO> mount : mounts) {
+                final VDI vdi = mount.second();
+                Set<VBD> vbds = null;
+                try {
+                    vbds = vdi.getVBDs(conn);
+                } catch (final Exception e) {
+                    final String msg = "VDI getVBDS failed due to " + e.toString();
+                    s_logger.warn(msg, e);
+                    continue;
+                }
+                for (final VBD vbd : vbds) {
+                    try {
+                        vbd.unplug(conn);
+                        vbd.destroy(conn);
+                    } catch (final Exception e) {
+                        final String msg = "VBD destroy failed due to " + e.toString();
+                        s_logger.warn(msg, e);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean stop() {
+        disconnected();
+        return true;
+    }
+
+    private HashMap<String, Pair<Long, Long>> syncNetworkGroups(final Connection conn, final long id) {
+        final HashMap<String, Pair<Long, Long>> states = new HashMap<String, Pair<Long, Long>>();
+
+        final String result = callHostPlugin(conn, "vmops", "get_rule_logs_for_vms", "host_uuid", _host.getUuid());
+        s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result);
+        final String[] rulelogs = result != null ? result.split(";") : new String[0];
+        for (final String rulesforvm : rulelogs) {
+            final String[] log = rulesforvm.split(",");
+            if (log.length != 6) {
+                continue;
+            }
+            // output = ','.join([vmName, vmID, vmIP, domID, signature, seqno])
+            try {
+                states.put(log[0], new Pair<Long, Long>(Long.parseLong(log[1]), Long.parseLong(log[5])));
+            } catch (final NumberFormatException nfe) {
+                states.put(log[0], new Pair<Long, Long>(-1L, -1L));
+            }
+        }
+        return states;
+    }
+
+    public boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException {
+        dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS);
+        Host.managementReconfigure(conn, dest);
+        String hostUuid = null;
+        int count = 0;
+        while (count < 10) {
+            try {
+                Thread.sleep(10000);
+                hostUuid = host.getUuid(conn);
+                if (hostUuid != null) {
+                    break;
+                }
+                ++count;
+            } catch (final XmlRpcException e) {
+                s_logger.debug("Waiting for host to come back: " + e.getMessage());
+            } catch (final XenAPIException e) {
+                s_logger.debug("Waiting for host to come back: " + e.getMessage());
+            } catch (final InterruptedException e) {
+                s_logger.debug("Gotta run");
+                return false;
+            }
+        }
+        if (hostUuid == null) {
+            s_logger.warn("Unable to transfer the management network from " + spr.uuid);
+            return false;
+        }
+
+        src.reconfigureIp(conn, Types.IpConfigurationMode.NONE, null, null, null, null);
+        return true;
+    }
+
+    protected void umount(final Connection conn, final VDI vdi) {
+
+    }
+
+    public void umountSnapshotDir(final Connection conn, final Long dcId) {
+        try {
+            callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString());
+        } catch (final Exception e) {
+            s_logger.debug("Failed to umount snapshot dir", e);
+        }
+    }
+
+    public String upgradeSnapshot(final Connection conn, final String templatePath, final String snapshotPath) {
+        final String results = callHostPluginAsync(conn, "vmopspremium", "upgrade_snapshot", 2 * 60 * 60, "templatePath", templatePath, "snapshotPath", snapshotPath);
+
+        if (results == null || results.isEmpty()) {
+            final String msg = "upgrade_snapshot return null";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        final String[] tmp = results.split("#");
+        final String status = tmp[0];
+        if (status.equals("0")) {
+            return results;
+        } else {
+            s_logger.warn(results);
+            throw new CloudRuntimeException(results);
+        }
+    }
+
+    public void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException {
+        final long beginTime = System.currentTimeMillis();
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + "ms timeout");
+        }
+        while (task.getStatus(c) == Types.TaskStatusType.PENDING) {
+            try {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") is pending, sleeping for " + pollInterval + "ms");
+                }
+                Thread.sleep(pollInterval);
+            } catch (final InterruptedException e) {
+            }
+            if (System.currentTimeMillis() - beginTime > timeout) {
+                final String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString();
+                s_logger.warn(msg);
+                task.cancel(c);
+                task.destroy(c);
+                throw new TimeoutException(msg);
+            }
+        }
+    }
+
+    public boolean createAndAttachConfigDriveIsoForVM(final Connection conn, final VM vm, final List<String[]> vmDataList, final String configDriveLabel) throws XenAPIException, XmlRpcException {
+
+        final String vmName = vm.getNameLabel(conn);
+
+        // create SR
+        final SR sr = createLocalIsoSR(conn, _configDriveSRName + _host.getIp());
+        if (sr == null) {
+            s_logger.debug("Failed to create local SR for the config drive");
+            return false;
+        }
+
+        s_logger.debug("Creating vm data files in config drive for vm " + vmName);
+        // 1. create vm data files
+        if (!createVmdataFiles(vmName, vmDataList, configDriveLabel)) {
+            s_logger.debug("Failed to create vm data files in config drive for vm " + vmName);
+            return false;
+        }
+
+        // 2. copy config drive iso to host
+        if (!copyConfigDriveIsoToHost(conn, sr, vmName)) {
+            return false;
+        }
+
+        // 3. attachIsoToVM
+        if (!attachConfigDriveIsoToVm(conn, vm)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public boolean createVmdataFiles(final String vmName, final List<String[]> vmDataList, final String configDriveLabel) {
+
+        // add vm iso to the isolibrary
+        final String isoPath = "/tmp/" + vmName + "/configDrive/";
+        final String configDriveName = "cloudstack/";
+
+        //create folder for the VM
+        //Remove the folder before creating it.
+
+        try {
+            deleteLocalFolder("/tmp/" + isoPath);
+        } catch (final IOException e) {
+            s_logger.debug("Failed to delete the exiting config drive for vm " + vmName + " " + e.getMessage());
+        } catch (final Exception e) {
+            s_logger.debug("Failed to delete the exiting config drive for vm " + vmName + " " + e.getMessage());
+        }
+
+        if (vmDataList != null) {
+            for (final String[] item : vmDataList) {
+                final String dataType = item[0];
+                final String fileName = item[1];
+                final String content = item[2];
+
+                // create file with content in folder
+
+                if (dataType != null && !dataType.isEmpty()) {
+                    //create folder
+                    final String folder = isoPath + configDriveName + dataType;
+                    if (folder != null && !folder.isEmpty()) {
+                        final File dir = new File(folder);
+                        final boolean result = true;
+
+                        try {
+                            if (!dir.exists()) {
+                                dir.mkdirs();
+                            }
+                        } catch (final SecurityException ex) {
+                            s_logger.debug("Failed to create dir " + ex.getMessage());
+                            return false;
+                        }
+
+                        if (result && content != null && !content.isEmpty()) {
+                            File file = new File(folder + "/" + fileName + ".txt");
+                            try (OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(file.getAbsoluteFile()), "UTF-8");
+                                    BufferedWriter bw = new BufferedWriter(fw);) {
+                                bw.write(content);
+                                s_logger.debug("created file: " + file + " in folder:" + folder);
+                            } catch (final IOException ex) {
+                                s_logger.debug("Failed to create file " + ex.getMessage());
+                                return false;
+                            }
+                        }
+                    }
+                }
+            }
+            s_logger.debug("Created the vm data in " + isoPath);
+        }
+
+        String s = null;
+        try {
+
+            final String cmd = "mkisofs -iso-level 3 -V " + configDriveLabel + " -o " + isoPath + vmName + ".iso " + isoPath;
+            final Process p = Runtime.getRuntime().exec(cmd);
+
+            final BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.defaultCharset()));
+
+            final BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream(), Charset.defaultCharset()));
+
+            // read the output from the command
+            while ((s = stdInput.readLine()) != null) {
+                s_logger.debug(s);
+            }
+
+            // read any errors from the attempted command
+            while ((s = stdError.readLine()) != null) {
+                s_logger.debug(s);
+            }
+            s_logger.debug(" Created config drive ISO using the command " + cmd + " in the host " + _host.getIp());
+        } catch (final IOException e) {
+            s_logger.debug(e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    public boolean copyConfigDriveIsoToHost(final Connection conn, final SR sr, final String vmName) {
+
+        final String vmIso = "/tmp/" + vmName + "/configDrive/" + vmName + ".iso";
+        //scp file into the host
+        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
+
+        try {
+            sshConnection.connect(null, 60000, 60000);
+            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
+                throw new CloudRuntimeException("Unable to authenticate");
+            }
+
+            s_logger.debug("scp config drive iso file " + vmIso + " to host " + _host.getIp() + " path " + _configDriveIsopath);
+            final SCPClient scp = new SCPClient(sshConnection);
+            final String p = "0755";
+
+            scp.put(vmIso, _configDriveIsopath, p);
+            sr.scan(conn);
+            s_logger.debug("copied config drive iso to host " + _host);
+        } catch (final IOException e) {
+            s_logger.debug("failed to copy configdrive iso " + vmIso + " to host " + _host, e);
+            return false;
+        } catch (final XmlRpcException e) {
+            s_logger.debug("Failed to scan config drive iso SR " + _configDriveSRName + _host.getIp() + " in host " + _host, e);
+            return false;
+        } finally {
+            sshConnection.close();
+            //clean up the config drive files
+
+            final String configDir = "/tmp/" + vmName;
+            try {
+                deleteLocalFolder(configDir);
+                s_logger.debug("Successfully cleaned up config drive directory " + configDir + " after copying it to host ");
+            } catch (final Exception e) {
+                s_logger.debug("Failed to delete config drive folder :" + configDir + " for VM " + vmName + " " + e.getMessage());
+            }
+        }
+
+        return true;
+    }
+
+    public boolean attachConfigDriveIsoToVm(final Connection conn, final VM vm) throws XenAPIException, XmlRpcException {
+
+        final String vmName = vm.getNameLabel(conn);
+        final String isoURL = _configDriveIsopath + vmName + ".iso";
+        VDI srVdi;
+
+        //1. find the vdi of the iso
+        //2. find the vbd for the vdi
+        //3. attach iso to vm
+
+        try {
+            final Set<VDI> vdis = VDI.getByNameLabel(conn, vmName + ".iso");
+            if (vdis.isEmpty()) {
+                throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL);
+            }
+            srVdi = vdis.iterator().next();
+
+        } catch (final XenAPIException e) {
+            s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
+            return false;
+        } catch (final Exception e) {
+            s_logger.debug("Unable to get config drive iso: " + isoURL + " due to " + e.toString());
+            return false;
+        }
+
+        VBD isoVBD = null;
+
+        // Find the VM's CD-ROM VBD
+        final Set<VBD> vbds = vm.getVBDs(conn);
+        for (final VBD vbd : vbds) {
+            final Types.VbdType type = vbd.getType(conn);
+
+            final VBD.Record vbdr = vbd.getRecord(conn);
+
+            // if the device exists then attach it
+            if (!vbdr.userdevice.equals(_attachIsoDeviceNum) && type == Types.VbdType.CD) {
+                isoVBD = vbd;
+                break;
+            }
+        }
+
+        if (isoVBD == null) {
+            //create vbd
+            final VBD.Record cfgDriveVbdr = new VBD.Record();
+            cfgDriveVbdr.VM = vm;
+            cfgDriveVbdr.empty = true;
+            cfgDriveVbdr.bootable = false;
+            cfgDriveVbdr.userdevice = "autodetect";
+            cfgDriveVbdr.mode = Types.VbdMode.RO;
+            cfgDriveVbdr.type = Types.VbdType.CD;
+            final VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr);
+            isoVBD = cfgDriveVBD;
+
+            s_logger.debug("Created CD-ROM VBD for VM: " + vm);
+        }
+
+        if (isoVBD != null) {
+            // If an ISO is already inserted, eject it
+            if (isoVBD.getEmpty(conn) == false) {
+                isoVBD.eject(conn);
+            }
+
+            try {
+                // Insert the new ISO
+                isoVBD.insert(conn, srVdi);
+                s_logger.debug("Attached config drive iso to vm " + vmName);
+            } catch (final XmlRpcException ex) {
+                s_logger.debug("Failed to attach config drive iso to vm " + vmName);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public SR createLocalIsoSR(final Connection conn, final String srName) throws XenAPIException, XmlRpcException {
+
+        // if config drive sr already exists then return
+        SR sr = getSRByNameLabelandHost(conn, _configDriveSRName + _host.getIp());
+
+        if (sr != null) {
+            s_logger.debug("Config drive SR already exist, returing it");
+            return sr;
+        }
+
+        try {
+            final Map<String, String> deviceConfig = new HashMap<String, String>();
+
+            final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
+            try {
+                sshConnection.connect(null, 60000, 60000);
+                if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
+                    throw new CloudRuntimeException("Unable to authenticate");
+                }
+
+                final String cmd = "mkdir -p " + _configDriveIsopath;
+                if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+                    throw new CloudRuntimeException("Cannot create directory configdrive_iso on XenServer hosts");
+                }
+            } catch (final IOException e) {
+                throw new CloudRuntimeException("Unable to create iso folder", e);
+            } finally {
+                sshConnection.close();
+            }
+            s_logger.debug("Created the config drive SR " + srName + " folder path " + _configDriveIsopath);
+
+            deviceConfig.put("location", _configDriveIsopath);
+            deviceConfig.put("legacy_mode", "true");
+            final Host host = Host.getByUuid(conn, _host.getUuid());
+            final String type = SRType.ISO.toString();
+            sr = SR.create(conn, host, deviceConfig, new Long(0), _configDriveIsopath, "iso", type, "iso", false, new HashMap<String, String>());
+
+            sr.setNameLabel(conn, srName);
+            sr.setNameDescription(conn, deviceConfig.get("location"));
+
+            sr.scan(conn);
+            s_logger.debug("Config drive ISO SR at the path " + _configDriveIsopath + " got created in host " + _host);
+            return sr;
+        } catch (final XenAPIException e) {
+            final String msg = "createLocalIsoSR failed! mountpoint " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        } catch (final Exception e) {
+            final String msg = "createLocalIsoSR failed! mountpoint:  due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg, e);
+        }
+
+    }
+
+    public void deleteLocalFolder(final String directory) throws Exception {
+        if (directory == null || directory.isEmpty()) {
+            final String msg = "Invalid directory path (null/empty) detected. Cannot delete specified directory.";
+            s_logger.debug(msg);
+            throw new Exception(msg);
+        }
+
+        try {
+            FileUtils.deleteDirectory(new File(directory));
+        } catch (final IOException e) {
+            // IOException here means failure to delete. Not swallowing it here to
+            // let the caller handle with appropriate contextual log message.
+            throw e;
+        }
+    }
+
+    protected SR getSRByNameLabel(Connection conn, String name) throws BadServerResponse, XenAPIException, XmlRpcException {
+        Set<SR> srs = SR.getByNameLabel(conn, name);
+        SR ressr = null;
+        for (SR sr : srs) {
+            Set<PBD> pbds;
+            pbds = sr.getPBDs(conn);
+            for (PBD pbd : pbds) {
+                PBD.Record pbdr = pbd.getRecord(conn);
+                if (pbdr.host != null) {
+                    ressr = sr;
+                    break;
+                }
+            }
+        }
+        return ressr;
+    }
+
+    public boolean attachConfigDriveToMigratedVm(Connection conn, String vmName, String ipAddr) {
+
+        // attach the config drive in destination host
+
+        try {
+            s_logger.debug("Attaching config drive iso device for the VM " + vmName + " In host " + ipAddr);
+            Set<VM> vms = VM.getByNameLabel(conn, vmName);
+
+            SR sr = getSRByNameLabel(conn, _configDriveSRName + ipAddr);
+            //Here you will find only two vdis with the <vmname>.iso.
+            //one is from source host and second from dest host
+            Set<VDI> vdis = VDI.getByNameLabel(conn, vmName + ".iso");
+            if (vdis.isEmpty()) {
+                s_logger.debug("Could not find config drive ISO: " + vmName);
+                return false;
+            }
+
+            VDI configdriveVdi = null;
+            for (VDI vdi : vdis) {
+                SR vdiSr = vdi.getSR(conn);
+                if (vdiSr.getUuid(conn).equals(sr.getUuid(conn))) {
+                    //get this vdi to attach to vbd
+                    configdriveVdi = vdi;
+                    s_logger.debug("VDI for the config drive ISO  " + vdi);
+                } else {
+                    // delete the vdi in source host so that the <vmname>.iso file is get removed
+                    s_logger.debug("Removing the source host VDI for the config drive ISO  " + vdi);
+                    vdi.destroy(conn);
+                }
+            }
+
+            if (configdriveVdi == null) {
+                s_logger.debug("Config drive ISO VDI is not found ");
+                return false;
+            }
+
+            for (VM vm : vms) {
+
+                //create vbd
+                VBD.Record cfgDriveVbdr = new VBD.Record();
+                cfgDriveVbdr.VM = vm;
+                cfgDriveVbdr.empty = true;
+                cfgDriveVbdr.bootable = false;
+                cfgDriveVbdr.userdevice = "autodetect";
+                cfgDriveVbdr.mode = Types.VbdMode.RO;
+                cfgDriveVbdr.type = Types.VbdType.CD;
+
+                VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr);
+
+                s_logger.debug("Inserting vbd " + configdriveVdi);
+                cfgDriveVBD.insert(conn, configdriveVdi);
+                break;
+
+            }
+
+            return true;
+
+        } catch (BadServerResponse e) {
+            s_logger.warn("Failed to attach config drive ISO to the VM  " + vmName + " In host " + ipAddr + " due to a bad server response.", e);
+            return false;
+        } catch (XenAPIException e) {
+            s_logger.warn("Failed to attach config drive ISO to the VM  " + vmName + " In host " + ipAddr + " due to a xapi problem.", e);
+            return false;
+        } catch (XmlRpcException e) {
+            s_logger.warn("Failed to attach config drive ISO to the VM  " + vmName + " In host " + ipAddr + " due to a problem in a remote call.", e);
+            return false;
+        }
+
+    }
+
+}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java
new file mode 100644
index 0000000..b7d0273
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java
@@ -0,0 +1,130 @@
+// 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.xenserver.resource;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Network;
+import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VLAN;
+
+public class XenServer56Resource extends CitrixResourceBase {
+    private final static Logger s_logger = Logger.getLogger(XenServer56Resource.class);
+
+    @Override
+    protected String getPatchFilePath() {
+        return "scripts/vm/hypervisor/xenserver/xenserver56/patch";
+    }
+
+    @Override
+    public void disableVlanNetwork(final Connection conn, final Network network) {
+        try {
+            final Network.Record networkr = network.getRecord(conn);
+            if (!networkr.nameLabel.startsWith("VLAN")) {
+                return;
+            }
+            final String bridge = networkr.bridge.trim();
+            for (final PIF pif : networkr.PIFs) {
+                final PIF.Record pifr = pif.getRecord(conn);
+                if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.getUuid())) {
+                    continue;
+                }
+
+                final VLAN vlan = pifr.VLANMasterOf;
+                if (vlan != null) {
+                    final String vlannum = pifr.VLAN.toString();
+                    final String device = pifr.device.trim();
+                    if (vlannum.equals("-1")) {
+                        return;
+                    }
+                    try {
+                        vlan.destroy(conn);
+                        final Host host = Host.getByUuid(conn, _host.getUuid());
+                        host.forgetDataSourceArchives(conn, "pif_" + bridge + "_tx");
+                        host.forgetDataSourceArchives(conn, "pif_" + bridge + "_rx");
+                        host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx");
+                        host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx");
+                    } catch (final XenAPIException e) {
+                        s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.getUuid() + " due to " + e.toString());
+                    }
+                }
+                return;
+            }
+        } catch (final XenAPIException e) {
+            final String msg = "Unable to disable VLAN network due to " + e.toString();
+            s_logger.warn(msg, e);
+        } catch (final Exception e) {
+            final String msg = "Unable to disable VLAN network due to " + e.getMessage();
+            s_logger.warn(msg, e);
+        }
+    }
+
+    @Override
+    public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) {
+        String args = "";
+        if (option.equals("get")) {
+            args += "-g";
+        } else if (option.equals("create")) {
+            args += "-c";
+        } else if (option.equals("reset")) {
+            args += "-r";
+        } else if (option.equals("addVif")) {
+            args += "-a ";
+            args += vif;
+        } else if (option.equals("deleteVif")) {
+            args += "-d ";
+            args += vif;
+        }
+
+        return executeInVR(privateIpAddress, "netusage.sh", args).getDetails();
+    }
+
+    public Boolean checkHeartbeat(final String hostuuid) {
+        final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22);
+        try {
+            sshConnection.connect(null, 60000, 60000);
+            if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
+                throw new CloudRuntimeException("Unable to authenticate");
+            }
+
+            final String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " + Integer.toString(_heartbeatInterval * 2);
+            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, shcmd)) {
+                s_logger.debug("Heart beat is gone so dead.");
+                return false;
+            }
+            s_logger.debug("Heart beat is still going");
+            return true;
+        } catch (final Exception e) {
+            s_logger.debug("health check failed due to catch exception " + e.toString());
+            return null;
+        } finally {
+            sshConnection.close();
+        }
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        pingXAPI();
+        return super.initialize();
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerConnectionPool.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerConnectionPool.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerConnectionPool.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerConnectionPool.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
new file mode 100644
index 0000000..fc72e79
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
@@ -0,0 +1,1782 @@
+/*
+ * 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.xenserver.resource;
+
+import static com.cloud.utils.ReflectUtil.flattenProperties;
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.VmPowerState;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VM;
+
+import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachAnswer;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectAnswer;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.ResignatureAnswer;
+import org.apache.cloudstack.storage.command.ResignatureCommand;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
+import com.cloud.hypervisor.xenserver.resource.wrapper.xenbase.XenServerUtilitiesHelper;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.resource.StorageProcessor;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.storage.S3.ClientOptions;
+
+public class XenServerStorageProcessor implements StorageProcessor {
+    private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
+    protected CitrixResourceBase hypervisorResource;
+    protected String BaseMountPointOnHost = "/var/run/cloud_mount";
+
+    public XenServerStorageProcessor(final CitrixResourceBase resource) {
+        hypervisorResource = resource;
+    }
+
+    // if the source SR needs to be attached to, do so
+    // take a snapshot of the source VDI (on the source SR)
+    // create an iSCSI SR based on the new back-end volume
+    // copy the snapshot to the new SR
+    // delete the snapshot
+    // detach the new SR
+    // if we needed to perform an attach to the source SR, detach from it
+    @Override
+    public SnapshotAndCopyAnswer snapshotAndCopy(final SnapshotAndCopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+
+        try {
+            SR sourceSr = null;
+
+            final Map<String, String> sourceDetails = cmd.getSourceDetails();
+
+            if (sourceDetails != null && sourceDetails.keySet().size() > 0) {
+                final String iScsiName = sourceDetails.get(DiskTO.IQN);
+                final String storageHost = sourceDetails.get(DiskTO.STORAGE_HOST);
+                final String chapInitiatorUsername = sourceDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+                final String chapInitiatorSecret = sourceDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+                sourceSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false);
+            }
+
+            final VDI vdiToSnapshot = VDI.getByUuid(conn, cmd.getUuidOfSourceVdi());
+
+            final VDI vdiSnapshot = vdiToSnapshot.snapshot(conn, new HashMap<String, String>());
+
+            final Map<String, String> destDetails = cmd.getDestDetails();
+
+            final String iScsiName = destDetails.get(DiskTO.IQN);
+            final String storageHost = destDetails.get(DiskTO.STORAGE_HOST);
+            final String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            final SR newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false);
+
+            final VDI vdiCopy = vdiSnapshot.copy(conn, newSr);
+
+            final String vdiUuid = vdiCopy.getUuid(conn);
+
+            vdiSnapshot.destroy(conn);
+
+            if (sourceSr != null) {
+                hypervisorResource.removeSR(conn, sourceSr);
+            }
+
+            hypervisorResource.removeSR(conn, newSr);
+
+            final SnapshotAndCopyAnswer snapshotAndCopyAnswer = new SnapshotAndCopyAnswer();
+
+            snapshotAndCopyAnswer.setPath(vdiUuid);
+
+            return snapshotAndCopyAnswer;
+        }
+        catch (final Exception ex) {
+            s_logger.warn("Failed to take and copy snapshot: " + ex.toString(), ex);
+
+            return new SnapshotAndCopyAnswer(ex.getMessage());
+        }
+    }
+
+    @Override
+    public ResignatureAnswer resignature(final ResignatureCommand cmd) {
+        SR newSr = null;
+
+        final Connection conn = hypervisorResource.getConnection();
+
+        try {
+            final Map<String, String> details = cmd.getDetails();
+
+            final String iScsiName = details.get(DiskTO.IQN);
+            final String storageHost = details.get(DiskTO.STORAGE_HOST);
+            final String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true, false);
+
+            Set<VDI> vdis = newSr.getVDIs(conn);
+
+            if (vdis.size() != 1) {
+                throw new RuntimeException("There were " + vdis.size() + " VDIs in the SR.");
+            }
+
+            VDI vdi = vdis.iterator().next();
+
+            final ResignatureAnswer resignatureAnswer = new ResignatureAnswer();
+
+            resignatureAnswer.setSize(vdi.getVirtualSize(conn));
+            resignatureAnswer.setPath(vdi.getUuid(conn));
+            resignatureAnswer.setFormat(ImageFormat.VHD);
+
+            return resignatureAnswer;
+        }
+        catch (final Exception ex) {
+            s_logger.warn("Failed to resignature: " + ex.toString(), ex);
+
+            return new ResignatureAnswer(ex.getMessage());
+        }
+        finally {
+            if (newSr != null) {
+                hypervisorResource.removeSR(conn, newSr);
+            }
+        }
+    }
+
+    @Override
+    public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) {
+        //Not implemented for Xen
+        return null;
+    }
+
+    @Override
+    public AttachAnswer attachIso(final AttachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final DataTO data = disk.getData();
+        final DataStoreTO store = data.getDataStore();
+
+        String isoURL = null;
+        if (store == null) {
+            final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
+            isoURL = iso.getName();
+        } else {
+            if (!(store instanceof NfsTO)) {
+                s_logger.debug("Can't attach a iso which is not created on nfs: ");
+                return new AttachAnswer("Can't attach a iso which is not created on nfs: ");
+            }
+            final NfsTO nfsStore = (NfsTO) store;
+            isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
+        }
+
+        final String vmName = cmd.getVmName();
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+
+            VBD isoVBD = null;
+
+            // Find the VM
+            final VM vm = hypervisorResource.getVM(conn, vmName);
+            // Find the ISO VDI
+            final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL);
+
+            // Find the VM's CD-ROM VBD
+            final Set<VBD> vbds = vm.getVBDs(conn);
+            for (final VBD vbd : vbds) {
+                final String userDevice = vbd.getUserdevice(conn);
+                final Types.VbdType type = vbd.getType(conn);
+
+                if (userDevice.equals("3") && type == Types.VbdType.CD) {
+                    isoVBD = vbd;
+                    break;
+                }
+            }
+
+            if (isoVBD == null) {
+                throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName);
+            } else {
+                // If an ISO is already inserted, eject it
+                if (!isoVBD.getEmpty(conn)) {
+                    isoVBD.eject(conn);
+                }
+
+                // Insert the new ISO
+                isoVBD.insert(conn, isoVDI);
+            }
+
+            return new AttachAnswer(disk);
+
+        } catch (final XenAPIException e) {
+            s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
+            return new AttachAnswer(e.toString());
+        } catch (final Exception e) {
+            s_logger.warn("Failed to attach iso" + ": " + e.toString(), e);
+            return new AttachAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public AttachAnswer attachVolume(final AttachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final DataTO data = disk.getData();
+        try {
+            final String vmName = cmd.getVmName();
+            final String vdiNameLabel = vmName + "-DATA";
+
+            final Connection conn = hypervisorResource.getConnection();
+            VM vm = null;
+
+            boolean vmNotRunning = true;
+
+            try {
+                vm = hypervisorResource.getVM(conn, vmName);
+
+                final VM.Record vmr = vm.getRecord(conn);
+
+                vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
+            } catch (final CloudRuntimeException ex) {
+            }
+
+            final Map<String, String> details = disk.getDetails();
+            final boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+
+            // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
+            // this should probably never actually happen
+            if (vmNotRunning && !isManaged) {
+                return new AttachAnswer(disk);
+            }
+
+            VDI vdi;
+
+            if (isManaged) {
+                vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel);
+
+                if (vmNotRunning) {
+                    final DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType());
+
+                    return new AttachAnswer(newDisk);
+                }
+            } else {
+                vdi = hypervisorResource.mount(conn, null, null, data.getPath());
+            }
+
+            hypervisorResource.destroyUnattachedVBD(conn, vm);
+
+            final VBD.Record vbdr = new VBD.Record();
+
+            vbdr.VM = vm;
+            vbdr.VDI = vdi;
+            vbdr.bootable = false;
+            vbdr.userdevice = "autodetect";
+
+            final Long deviceId = disk.getDiskSeq();
+
+            if (deviceId != null && !hypervisorResource.isDeviceUsed(conn, vm, deviceId)) {
+                vbdr.userdevice = deviceId.toString();
+            }
+
+            vbdr.mode = Types.VbdMode.RW;
+            vbdr.type = Types.VbdType.DISK;
+            vbdr.unpluggable = true;
+
+            final VBD vbd = VBD.create(conn, vbdr);
+
+            // Attach the VBD to the VM
+            try {
+                vbd.plug(conn);
+            } catch (final Exception e) {
+                vbd.destroy(conn);
+                throw e;
+            }
+
+            // Update the VDI's label to include the VM name
+            vdi.setNameLabel(conn, vdiNameLabel);
+
+            final DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(vbd.getUserdevice(conn)), vdi.getUuid(conn), disk.getType());
+
+            return new AttachAnswer(newDisk);
+        } catch (final Exception e) {
+            final String msg = "Failed to attach volume for uuid: " + data.getPath() + " due to "  + e.toString();
+
+            s_logger.warn(msg, e);
+
+            return new AttachAnswer(msg);
+        }
+    }
+
+    @Override
+    public Answer dettachIso(final DettachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final DataTO data = disk.getData();
+        final DataStoreTO store = data.getDataStore();
+
+        String isoURL = null;
+        if (store == null) {
+            final TemplateObjectTO iso = (TemplateObjectTO) disk.getData();
+            isoURL = iso.getName();
+        } else {
+            if (!(store instanceof NfsTO)) {
+                s_logger.debug("Can't detach a iso which is not created on nfs: ");
+                return new AttachAnswer("Can't detach a iso which is not created on nfs: ");
+            }
+            final NfsTO nfsStore = (NfsTO) store;
+            isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath();
+        }
+
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+            // Find the VM
+            final VM vm = hypervisorResource.getVM(conn, cmd.getVmName());
+            final String vmUUID = vm.getUuid(conn);
+
+            // Find the ISO VDI
+            final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL);
+
+            final SR sr = isoVDI.getSR(conn);
+
+            // Look up all VBDs for this VDI
+            final Set<VBD> vbds = isoVDI.getVBDs(conn);
+
+            // Iterate through VBDs, and if the VBD belongs the VM, eject
+            // the ISO from it
+            for (final VBD vbd : vbds) {
+                final VM vbdVM = vbd.getVM(conn);
+                final String vbdVmUUID = vbdVM.getUuid(conn);
+
+                if (vbdVmUUID.equals(vmUUID)) {
+                    // If an ISO is already inserted, eject it
+                    if (!vbd.getEmpty(conn)) {
+                        vbd.eject(conn);
+                    }
+                    break;
+                }
+            }
+
+            if (!XenServerUtilitiesHelper.isXenServerToolsSR(sr.getNameLabel(conn))) {
+                hypervisorResource.removeSR(conn, sr);
+            }
+
+            return new DettachAnswer(disk);
+        } catch (final XenAPIException e) {
+            final String msg = "Failed to detach volume" + " for uuid: " + data.getPath() + "  due to " + e.toString();
+            s_logger.warn(msg, e);
+            return new DettachAnswer(msg);
+        } catch (final Exception e) {
+            final String msg = "Failed to detach volume" + " for uuid: " + data.getPath() + "  due to " + e.getMessage();
+            s_logger.warn(msg, e);
+            return new DettachAnswer(msg);
+        }
+    }
+
+    @Override
+    public Answer dettachVolume(final DettachCommand cmd) {
+        final DiskTO disk = cmd.getDisk();
+        final DataTO data = disk.getData();
+
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+
+            final String vmName = cmd.getVmName();
+            VM vm = null;
+
+            boolean vmNotRunning = true;
+
+            try {
+                vm = hypervisorResource.getVM(conn, vmName);
+
+                final VM.Record vmr = vm.getRecord(conn);
+
+                vmNotRunning = vmr.powerState != VmPowerState.RUNNING;
+            } catch (final CloudRuntimeException ex) {
+            }
+
+            // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here)
+            // this should probably never actually happen
+            if (vmNotRunning && !cmd.isManaged()) {
+                return new DettachAnswer(disk);
+            }
+
+            if (!vmNotRunning) {
+                final VDI vdi = hypervisorResource.mount(conn, null, null, data.getPath());
+
+                // Look up all VBDs for this VDI
+                final Set<VBD> vbds = vdi.getVBDs(conn);
+
+                // Detach each VBD from its VM, and then destroy it
+                for (final VBD vbd : vbds) {
+                    final VBD.Record vbdr = vbd.getRecord(conn);
+
+                    if (vbdr.currentlyAttached) {
+                        vbd.unplug(conn);
+                    }
+
+                    vbd.destroy(conn);
+                }
+
+                hypervisorResource.umount(conn, vdi);
+            }
+
+            if (cmd.isManaged()) {
+                hypervisorResource.handleSrAndVdiDetach(cmd.get_iScsiName(), conn);
+            }
+
+            return new DettachAnswer(disk);
+        } catch (final Exception e) {
+            s_logger.warn("Failed dettach volume: " + data.getPath());
+            return new DettachAnswer("Failed dettach volume: " + data.getPath() + ", due to " + e.toString());
+        }
+    }
+
+    protected VDI createVdi(final Connection conn, final String vdiName, final SR sr, final long size) throws BadServerResponse, XenAPIException, XmlRpcException {
+        final VDI.Record vdir = new VDI.Record();
+        vdir.nameLabel = vdiName;
+        vdir.SR = sr;
+        vdir.type = Types.VdiType.USER;
+
+        vdir.virtualSize = size;
+        final VDI vdi = VDI.create(conn, vdir);
+        return vdi;
+    }
+
+    protected void deleteVDI(final Connection conn, final VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException {
+        vdi.destroy(conn);
+    }
+
+    @Override
+    public Answer createSnapshot(final CreateObjectCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData();
+        final long snapshotId = snapshotTO.getId();
+        final String snapshotName = snapshotTO.getName();
+        String details = "create snapshot operation Failed for snapshotId: " + snapshotId;
+        String snapshotUUID = null;
+
+        try {
+            final String volumeUUID = snapshotTO.getVolume().getPath();
+            final VDI volume = VDI.getByUuid(conn, volumeUUID);
+
+            final VDI snapshot = volume.snapshot(conn, new HashMap<String, String>());
+
+            if (snapshotName != null) {
+                snapshot.setNameLabel(conn, snapshotName);
+            }
+
+            snapshotUUID = snapshot.getUuid(conn);
+            final String preSnapshotUUID = snapshotTO.getParentSnapshotPath();
+            //check if it is a empty snapshot
+            if (preSnapshotUUID != null) {
+                final SR sr = volume.getSR(conn);
+                final String srUUID = sr.getUuid(conn);
+                final String type = sr.getType(conn);
+                final Boolean isISCSI = IsISCSI(type);
+                final String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI);
+
+                try {
+                    final String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI);
+                    if (snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) {
+                        // this is empty snapshot, remove it
+                        snapshot.destroy(conn);
+                        snapshotUUID = preSnapshotUUID;
+                    }
+                } catch (final Exception e) {
+                    s_logger.debug("Failed to get parent snapshot", e);
+                }
+            }
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(snapshotUUID);
+            return new CreateObjectAnswer(newSnapshot);
+        } catch (final XenAPIException e) {
+            details += ", reason: " + e.toString();
+            s_logger.warn(details, e);
+        } catch (final Exception e) {
+            details += ", reason: " + e.toString();
+            s_logger.warn(details, e);
+        }
+
+        return new CreateObjectAnswer(details);
+    }
+
+    @Override
+    public Answer deleteVolume(final DeleteCommand cmd) {
+        final DataTO volume = cmd.getData();
+        final Connection conn = hypervisorResource.getConnection();
+        String errorMsg = null;
+        try {
+            final VDI vdi = VDI.getByUuid(conn, volume.getPath());
+            for(VDI svdi : vdi.getSnapshots(conn)) {
+                deleteVDI(conn, svdi);
+            }
+            deleteVDI(conn, vdi);
+            return new Answer(null);
+        } catch (final BadServerResponse e) {
+            s_logger.debug("Failed to delete volume", e);
+            errorMsg = e.toString();
+        } catch (final XenAPIException e) {
+            s_logger.debug("Failed to delete volume", e);
+            errorMsg = e.toString();
+        } catch (final XmlRpcException e) {
+            s_logger.debug("Failed to delete volume", e);
+            errorMsg = e.toString();
+        }
+        return new Answer(null, false, errorMsg);
+    }
+
+    protected boolean IsISCSI(final String type) {
+        return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type);
+    }
+
+    private String copy_vhd_from_secondarystorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) {
+        final String nameLabel = "cloud-" + UUID.randomUUID().toString();
+        final String results =
+                hypervisorResource.callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel",
+                        nameLabel);
+        String errMsg = null;
+        if (results == null || results.isEmpty()) {
+            errMsg = "copy_vhd_from_secondarystorage return null";
+        } else {
+            final String[] tmp = results.split("#");
+            final String status = tmp[0];
+            if (status.equals("0")) {
+                return tmp[1];
+            } else {
+                errMsg = tmp[1];
+            }
+        }
+        final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1);
+        if (hypervisorResource.killCopyProcess(conn, source)) {
+            destroyVDIbyNameLabel(conn, nameLabel);
+        }
+        s_logger.warn(errMsg);
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    private void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) {
+        try {
+            final Set<VDI> vdis = VDI.getByNameLabel(conn, nameLabel);
+            if (vdis.size() != 1) {
+                s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel);
+                return;
+            }
+            for (final VDI vdi : vdis) {
+                try {
+                    vdi.destroy(conn);
+                } catch (final Exception e) {
+                }
+            }
+        } catch (final Exception e) {
+        }
+    }
+
+    protected VDI getVDIbyUuid(final Connection conn, final String uuid) {
+        try {
+            return VDI.getByUuid(conn, uuid);
+        } catch (final Exception e) {
+            final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString();
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        }
+    }
+
+    protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
+        final String parentUuid =
+                hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid,
+                        "isISCSI", isISCSI.toString());
+
+        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
+            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
+            // errString is already logged.
+            return null;
+        }
+        return parentUuid;
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
+        final DataTO srcDataTo = cmd.getSrcTO();
+        final DataTO destDataTo = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final DataStoreTO srcDataStoreTo = srcDataTo.getDataStore();
+        final Connection conn = hypervisorResource.getConnection();
+        SR sr = null;
+        boolean removeSrAfterCopy = false;
+
+        try {
+            if (srcDataStoreTo instanceof NfsTO && srcDataTo.getObjectType() == DataObjectType.TEMPLATE) {
+                final NfsTO srcImageStore = (NfsTO) srcDataStoreTo;
+                final TemplateObjectTO srcTemplateObjectTo = (TemplateObjectTO) srcDataTo;
+                final String storeUrl = srcImageStore.getUrl();
+                final URI uri = new URI(storeUrl);
+                final String tmplPath = uri.getHost() + ":" + uri.getPath() + "/" + srcDataTo.getPath();
+                final DataStoreTO destDataStoreTo = destDataTo.getDataStore();
+
+                boolean managed = false;
+                String storageHost = null;
+                String managedStoragePoolName = null;
+                String managedStoragePoolRootVolumeName = null;
+                String managedStoragePoolRootVolumeSize = null;
+                String chapInitiatorUsername = null;
+                String chapInitiatorSecret = null;
+
+                if (destDataStoreTo instanceof PrimaryDataStoreTO) {
+                    final PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo;
+
+                    final Map<String, String> details = destPrimaryDataStoreTo.getDetails();
+
+                    if (details != null) {
+                        managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
+
+                        if (managed) {
+                            storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
+                            managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
+                            managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
+                            managedStoragePoolRootVolumeSize = details.get(PrimaryDataStoreTO.VOLUME_SIZE);
+                            chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
+                            chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
+                            removeSrAfterCopy = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.REMOVE_AFTER_COPY));
+                        }
+                    }
+                }
+
+                if (managed) {
+                    final Map<String, String> details = new HashMap<String, String>();
+
+                    details.put(DiskTO.STORAGE_HOST, storageHost);
+                    details.put(DiskTO.IQN, managedStoragePoolName);
+                    details.put(DiskTO.VOLUME_SIZE, managedStoragePoolRootVolumeSize);
+                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInitiatorUsername);
+                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInitiatorSecret);
+
+                    sr = hypervisorResource.prepareManagedSr(conn, details);
+                } else {
+                    final String srName = destDataStoreTo.getUuid();
+                    final Set<SR> srs = SR.getByNameLabel(conn, srName);
+
+                    if (srs.size() != 1) {
+                        final String msg = "There are " + srs.size() + " SRs with same name: " + srName;
+
+                        s_logger.warn(msg);
+
+                        return new CopyCmdAnswer(msg);
+                    } else {
+                        sr = srs.iterator().next();
+                    }
+                }
+
+                final String srUuid = sr.getUuid(conn);
+                final String tmplUuid = copy_vhd_from_secondarystorage(conn, tmplPath, srUuid, wait);
+                final VDI tmplVdi = getVDIbyUuid(conn, tmplUuid);
+
+                final String uuidToReturn;
+                final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn);
+
+                if (managed) {
+                    uuidToReturn = tmplUuid;
+
+                    tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName);
+                } else {
+                    final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap<String, String>());
+
+                    uuidToReturn = snapshotVdi.getUuid(conn);
+
+                    snapshotVdi.setNameLabel(conn, "Template " + srcTemplateObjectTo.getName());
+
+                    tmplVdi.destroy(conn);
+                }
+
+                sr.scan(conn);
+
+                try {
+                    Thread.sleep(5000);
+                } catch (final InterruptedException e) {
+                }
+
+                final TemplateObjectTO newVol = new TemplateObjectTO();
+
+                newVol.setUuid(uuidToReturn);
+                newVol.setPath(uuidToReturn);
+
+                if (physicalSize != null) {
+                    newVol.setSize(physicalSize);
+                }
+
+                newVol.setFormat(ImageFormat.VHD);
+
+                return new CopyCmdAnswer(newVol);
+            }
+        } catch (final Exception e) {
+            final String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString();
+
+            s_logger.warn(msg, e);
+
+            return new CopyCmdAnswer(msg);
+        }
+        finally {
+            if (removeSrAfterCopy && sr != null) {
+                hypervisorResource.removeSR(conn, sr);
+            }
+        }
+
+        return new CopyCmdAnswer("not implemented yet");
+    }
+
+    @Override
+    public Answer createVolume(final CreateObjectCommand cmd) {
+        final DataTO data = cmd.getData();
+        final VolumeObjectTO volume = (VolumeObjectTO) data;
+
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+            final SR poolSr = hypervisorResource.getStorageRepository(conn, data.getDataStore().getUuid());
+            VDI.Record vdir = new VDI.Record();
+            vdir.nameLabel = volume.getName();
+            vdir.SR = poolSr;
+            vdir.type = Types.VdiType.USER;
+
+            vdir.virtualSize = volume.getSize();
+            VDI vdi;
+
+            vdi = VDI.create(conn, vdir);
+            vdir = vdi.getRecord(conn);
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setName(vdir.nameLabel);
+            newVol.setSize(vdir.virtualSize);
+            newVol.setPath(vdir.uuid);
+
+            return new CreateObjectAnswer(newVol);
+        } catch (final Exception e) {
+            s_logger.debug("create volume failed: " + e.toString());
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final VolumeObjectTO volume = (VolumeObjectTO) destData;
+        VDI vdi = null;
+        try {
+            VDI tmpltvdi = null;
+
+            tmpltvdi = getVDIbyUuid(conn, srcData.getPath());
+            vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
+            Long virtualSize  = vdi.getVirtualSize(conn);
+            if (volume.getSize() > virtualSize) {
+                s_logger.debug("Overriding provided template's size with new size " + volume.getSize() + " for volume: " + volume.getName());
+                vdi.resize(conn, volume.getSize());
+            } else {
+                s_logger.debug("Using templates disk size of " + virtualSize + " for volume: " + volume.getName() + " since size passed was " + volume.getSize());
+            }
+            vdi.setNameLabel(conn, volume.getName());
+
+            VDI.Record vdir;
+            vdir = vdi.getRecord(conn);
+            s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid);
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setName(vdir.nameLabel);
+            newVol.setSize(vdir.virtualSize);
+            newVol.setPath(vdir.uuid);
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final Exception e) {
+            s_logger.warn("Unable to create volume; Pool=" + destData + "; Disk: ", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final VolumeObjectTO srcVolume = (VolumeObjectTO) srcData;
+        final VolumeObjectTO destVolume = (VolumeObjectTO) destData;
+        final DataStoreTO srcStore = srcVolume.getDataStore();
+
+        if (srcStore instanceof NfsTO) {
+            final NfsTO nfsStore = (NfsTO) srcStore;
+            try {
+                final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, destVolume.getDataStore().getUuid());
+                final String srUuid = primaryStoragePool.getUuid(conn);
+                final URI uri = new URI(nfsStore.getUrl());
+                final String volumePath = uri.getHost() + ":" + uri.getPath() + nfsStore.getPathSeparator() + srcVolume.getPath();
+                final String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait);
+                final VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(uuid);
+                newVol.setSize(srcVolume.getSize());
+
+                return new CopyCmdAnswer(newVol);
+            } catch (final Exception e) {
+                final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
+                s_logger.warn(msg, e);
+                return new CopyCmdAnswer(e.toString());
+            }
+        }
+
+        s_logger.debug("unsupported protocol");
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO();
+        final VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final DataStoreTO destStore = destVolume.getDataStore();
+
+        if (destStore instanceof NfsTO) {
+            SR secondaryStorage = null;
+            try {
+                final NfsTO nfsStore = (NfsTO) destStore;
+                final URI uri = new URI(nfsStore.getUrl());
+                // Create the volume folder
+                if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
+                    throw new InternalErrorException("Failed to create the volume folder.");
+                }
+
+                // Create a SR for the volume UUID folder
+                secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + nfsStore.getPathSeparator() + destVolume.getPath()), false);
+                // Look up the volume on the source primary storage pool
+                final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
+                // Copy the volume to secondary storage
+                final VDI destVdi = hypervisorResource.cloudVDIcopy(conn, srcVdi, secondaryStorage, wait);
+                final String destVolumeUUID = destVdi.getUuid(conn);
+
+                final VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVolume.getPath() + nfsStore.getPathSeparator() + destVolumeUUID + ".vhd");
+                newVol.setSize(srcVolume.getSize());
+                return new CopyCmdAnswer(newVol);
+            } catch (final Exception e) {
+                s_logger.debug("Failed to copy volume to secondary: " + e.toString());
+                return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString());
+            } finally {
+                hypervisorResource.removeSR(conn, secondaryStorage);
+            }
+        }
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    private boolean swiftUpload(final Connection conn, final SwiftTO swift, final String container, final String ldir, final String lfilename, final Boolean isISCSI,
+            final int wait) {
+
+        List<String> params = getSwiftParams(swift, container, ldir, lfilename, isISCSI);
+
+        try {
+            String result = hypervisorResource.callHostPluginAsync(conn, "swiftxenserver", "swift", wait, params.toArray(new String[params.size()]));
+            return BooleanUtils.toBoolean(result);
+        } catch (final Exception e) {
+            s_logger.warn("swift upload failed due to " + e.toString(), e);
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    List<String> getSwiftParams(SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI) {
+        // ORDER IS IMPORTANT
+        List<String> params = new ArrayList<>();
+
+        //operation
+        params.add("op");
+        params.add("upload");
+
+        //auth
+        params.add("url");
+        params.add(swift.getUrl());
+        params.add("account");
+        params.add(swift.getAccount());
+        params.add("username");
+        params.add(swift.getUserName());
+        params.add("key");
+        params.add(swift.getKey());
+
+        // object info
+        params.add("container");
+        params.add(container);
+        params.add("ldir");
+        params.add(ldir);
+        params.add("lfilename");
+        params.add(lfilename);
+        params.add("isISCSI");
+        params.add(isISCSI.toString());
+
+        if (swift.getStoragePolicy() != null) {
+            params.add("storagepolicy");
+            params.add(swift.getStoragePolicy());
+        }
+
+        return params;
+    }
+
+    protected String deleteSnapshotBackup(final Connection conn, final String localMountPoint, final String path, final String secondaryStorageMountPath, final String backupUUID) {
+
+        // If anybody modifies the formatting below again, I'll skin them
+        final String result =
+                hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath",
+                        secondaryStorageMountPath, "localMountPoint", localMountPoint);
+
+        return result;
+    }
+
+    protected String swiftBackupSnapshot(final Connection conn, final SwiftTO swift, final String srUuid, final String snapshotUuid, final String container, final Boolean isISCSI,
+            final int wait) {
+        String lfilename;
+        String ldir;
+        if (isISCSI) {
+            ldir = "/dev/VG_XenStorage-" + srUuid;
+            lfilename = "VHD-" + snapshotUuid;
+        } else {
+            ldir = "/var/run/sr-mount/" + srUuid;
+            lfilename = snapshotUuid + ".vhd";
+        }
+        swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait);
+        return lfilename;
+    }
+
+    protected String backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String folder, final String snapshotUuid,
+            final Boolean iSCSIFlag, final int wait) {
+
+        final String filename = iSCSIFlag ? "VHD-" + snapshotUuid : snapshotUuid + ".vhd";
+        final String dir = (iSCSIFlag ? "/dev/VG_XenStorage-" : "/var/run/sr-mount/") + srUuid;
+        final String key = folder + "/" + filename; // String.format("/snapshots/%1$s", snapshotUuid);
+
+        try {
+
+            final List<String> parameters = newArrayList(flattenProperties(s3, ClientOptions.class));
+            // https workaround for Introspector bug that does not
+            // recognize Boolean accessor methods ...
+
+            parameters.addAll(Arrays.asList("operation", "put", "filename", dir + "/" + filename, "iSCSIFlag", iSCSIFlag.toString(), "bucket", s3.getBucketName(), "key",
+                    key, "https", s3.isHttps() != null ? s3.isHttps().toString() : "null", "maxSingleUploadSizeInBytes", String.valueOf(s3.getMaxSingleUploadSizeInBytes())));
+            final String result = hypervisorResource.callHostPluginAsync(connection, "s3xenserver", "s3", wait, parameters.toArray(new String[parameters.size()]));
+
+            if (result != null && result.equals("true")) {
+                return key;
+            }
+            return null;
+
+        } catch (final Exception e) {
+            s_logger.error(String.format("S3 upload failed of snapshot %1$s due to %2$s.", snapshotUuid, e.toString()), e);
+        }
+
+        return null;
+
+    }
+
+    private Long getSnapshotSize(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI, final int wait) {
+        final String physicalSize = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "getSnapshotSize", wait,
+                "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString());
+        if (physicalSize == null || physicalSize.isEmpty()) {
+            return (long) 0;
+        } else {
+            return Long.parseLong(physicalSize);
+        }
+    }
+
+    private String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, final String secondaryStorageMountPath,
+            final String snapshotUuid, String prevBackupUuid, final Boolean isISCSI, final int wait) {
+        String backupSnapshotUuid = null;
+
+        if (prevBackupUuid == null) {
+            prevBackupUuid = "";
+        }
+
+        // Each argument is put in a separate line for readability.
+        // Using more lines does not harm the environment.
+        final String backupUuid = UUID.randomUUID().toString();
+        final String results =
+                hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait, "primaryStorageSRUuid", primaryStorageSRUuid, "path", path,
+                        "secondaryStorageMountPath", secondaryStorageMountPath, "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid,
+                        "isISCSI", isISCSI.toString(), "localMountPoint", localMountPoint);
+        String errMsg = null;
+        if (results == null || results.isEmpty()) {
+            errMsg =
+                    "Could not copy backupUuid: " + backupSnapshotUuid + " from primary storage " + primaryStorageSRUuid + " to secondary storage " +
+                            secondaryStorageMountPath + " due to null";
+        } else {
+
+            final String[] tmp = results.split("#");
+            final String status = tmp[0];
+            backupSnapshotUuid = tmp[1];
+            // status == "1" if and only if backupSnapshotUuid != null
+            // So we don't rely on status value but return backupSnapshotUuid as an
+            // indicator of success.
+            if (status != null && status.equalsIgnoreCase("1") && backupSnapshotUuid != null) {
+                s_logger.debug("Successfully copied backupUuid: " + backupSnapshotUuid + " to secondary storage");
+                return results;
+            } else {
+                errMsg =
+                        "Could not copy backupUuid: " + backupSnapshotUuid + " from primary storage " + primaryStorageSRUuid + " to secondary storage " +
+                                secondaryStorageMountPath + " due to " + tmp[1];
+            }
+        }
+        final String source = backupUuid + ".vhd";
+        hypervisorResource.killCopyProcess(conn, source);
+        s_logger.warn(errMsg);
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    protected boolean destroySnapshotOnPrimaryStorageExceptThis(final Connection conn, final String volumeUuid, final String avoidSnapshotUuid) {
+        try {
+            final VDI volume = getVDIbyUuid(conn, volumeUuid);
+            if (volume == null) {
+                throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it");
+            }
+            // To avoid deleting snapshots which are still waiting in queue to get backed up.
+            VDI avoidSnapshot = getVDIbyUuid(conn, avoidSnapshotUuid);
+            if (avoidSnapshot == null) {
+                throw new InternalErrorException("Could not find current snapshot " + avoidSnapshotUuid);
+            }
+            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)) && snapshot.getVBDs(conn).isEmpty()) {
+                        snapshot.destroy(conn);
+                    }
+                } catch (final Exception e) {
+                    final String msg = "Destroying snapshot: " + snapshot + " on primary storage failed due to " + e.toString();
+                    s_logger.warn(msg, e);
+                }
+            }
+            s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid);
+            return true;
+        } catch (final XenAPIException e) {
+            final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+        } catch (final Exception e) {
+            final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString();
+            s_logger.warn(msg, e);
+        }
+
+        return false;
+    }
+
+    protected boolean destroySnapshotOnPrimaryStorage(final Connection conn, final String lastSnapshotUuid) {
+        try {
+            final VDI snapshot = getVDIbyUuid(conn, lastSnapshotUuid);
+            if (snapshot == null) {
+                // since this is just used to cleanup leftover bad snapshots, no need to throw exception
+                s_logger.warn("Could not destroy snapshot " + lastSnapshotUuid + " due to can not find it");
+                return false;
+            }
+            snapshot.destroy(conn);
+            return true;
+        } catch (final XenAPIException e) {
+            final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+        } catch (final Exception e) {
+            final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString();
+            s_logger.warn(msg, e);
+        }
+        return false;
+    }
+
+    @Override
+    public Answer backupSnapshot(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO cacheData = cmd.getCacheTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final String primaryStorageNameLabel = srcData.getDataStore().getUuid();
+        String secondaryStorageUrl = null;
+        NfsTO cacheStore = null;
+        String destPath = null;
+        if (cacheData != null) {
+            cacheStore = (NfsTO) cacheData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = cacheData.getPath();
+        } else {
+            cacheStore = (NfsTO) destData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = destData.getPath();
+        }
+
+        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData;
+        final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData;
+        final String snapshotUuid = snapshotTO.getPath();
+        final String volumeUuid = snapshotTO.getVolume().getPath();
+
+        final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
+        final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
+
+        // By default assume failure
+        String details = null;
+        String snapshotBackupUuid = null;
+        Long physicalSize = null;
+        final Map<String, String> options = cmd.getOptions();
+        boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
+        boolean result = false;
+        try {
+            final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " +
+                        primaryStorageNameLabel);
+            }
+            final String psUuid = primaryStorageSR.getUuid(conn);
+            final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
+
+            final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
+            String snapshotPaUuid = null;
+
+            if (prevSnapshotUuid != null && !fullbackup) {
+                try {
+                    snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI);
+                    if (snapshotPaUuid != null) {
+                        final String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI);
+                        final String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI);
+                        if (snashotPaPaPaUuid != null && prevSnashotPaUuid != null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) {
+                            fullbackup = false;
+                        } else {
+                            fullbackup = true;
+                        }
+                    }
+                } catch (final Exception e) {
+                    s_logger.debug("Failed to get parent snapshots, take full snapshot", e);
+                    fullbackup = true;
+                }
+            }
+
+            final URI uri = new URI(secondaryStorageUrl);
+            final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            final DataStoreTO destStore = destData.getDataStore();
+            final String folder = destPath;
+            String finalPath = null;
+
+            final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
+            if (fullbackup) {
+                // the first snapshot is always a full snapshot
+
+                if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) {
+                    details = " Filed to create folder " + folder + " in secondary storage";
+                    s_logger.warn(details);
+                    return new CopyCmdAnswer(details);
+                }
+                final String snapshotMountpoint = secondaryStorageUrl + "/" + folder;
+                SR snapshotSr = null;
+                try {
+                    snapshotSr = hypervisorResource.createNfsSRbyURI(conn, new URI(snapshotMountpoint), false);
+                    final VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait);
+                    snapshotBackupUuid = backedVdi.getUuid(conn);
+                    final String primarySRuuid = snapshotSr.getUuid(conn);
+                    physicalSize = getSnapshotSize(conn, primarySRuuid, snapshotBackupUuid, isISCSI, wait);
+
+                    if (destStore instanceof SwiftTO) {
+                        try {
+                            final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                            final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
+                            final String swiftPath = container + File.separator + destSnapshotName;
+                            finalPath = swiftPath;
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (final Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages", e);
+                            }
+                        }
+
+                    } else if (destStore instanceof S3TO) {
+                        try {
+                            finalPath = backupSnapshotToS3(conn, (S3TO) destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
+                            if (finalPath == null) {
+                                throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
+                            }
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (final Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages", e);
+                            }
+                        }
+                        // finalPath = folder + File.separator + snapshotBackupUuid;
+                    } else {
+                        finalPath = folder + cacheStore.getPathSeparator() + snapshotBackupUuid;
+                    }
+
+                } finally {
+                    if (snapshotSr != null) {
+                        hypervisorResource.removeSR(conn, snapshotSr);
+                    }
+                }
+            } else {
+                final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
+                if (destStore instanceof SwiftTO) {
+                    final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                    snapshotBackupUuid =
+                            swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(),
+                                    isISCSI, wait);
+                    finalPath = container + File.separator + snapshotBackupUuid;
+                } else if (destStore instanceof S3TO) {
+                    finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
+                    if (finalPath == null) {
+                        throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
+                    }
+                } else {
+                    final String results =
+                            backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait);
+
+                    final String[] tmp = results.split("#");
+                    snapshotBackupUuid = tmp[1];
+                    physicalSize = Long.parseLong(tmp[2]);
+                    finalPath = folder + cacheStore.getPathSeparator() + snapshotBackupUuid;
+                }
+            }
+            // delete primary snapshots with only the last one left
+            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
+
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(finalPath);
+            newSnapshot.setPhysicalSize(physicalSize);
+            if (fullbackup) {
+                newSnapshot.setParentSnapshotPath(null);
+            } else {
+                newSnapshot.setParentSnapshotPath(prevBackupUuid);
+            }
+            result = true;
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (final XenAPIException e) {
+            details = "BackupSnapshot Failed due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (final Exception e) {
+            details = "BackupSnapshot Failed due to " + e.getMessage();
+            s_logger.warn(details, e);
+        } finally {
+            if (!result) {
+                // remove last bad primary snapshot when exception happens
+                try {
+                    destroySnapshotOnPrimaryStorage(conn, snapshotUuid);
+                } catch (final Exception e) {
+                    s_logger.debug("clean up snapshot failed", e);
+                }
+            }
+        }
+
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO();
+        final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
+        final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore();
+        final int wait = cmd.getWait();
+
+        final String secondaryStoragePoolURL = destStore.getUrl();
+        final String volumeUUID = volume.getPath();
+
+        final String userSpecifiedName = template.getName();
+
+        String details = null;
+        SR tmpltSR = null;
+        boolean result = false;
+        String secondaryStorageMountPath = null;
+        String installPath = null;
+        try {
+            final URI uri = new URI(secondaryStoragePoolURL);
+            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            installPath = template.getPath();
+            if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
+                details = " Filed to create folder " + installPath + " in secondary storage";
+                s_logger.warn(details);
+                return new CopyCmdAnswer(details);
+            }
+
+            final VDI vol = getVDIbyUuid(conn, volumeUUID);
+            // create template SR
+            final URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath);
+            tmpltSR = hypervisorResource.createNfsSRbyURI(conn, tmpltURI, false);
+
+            // copy volume to template SR
+            final VDI tmpltVDI = hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait);
+            // scan makes XenServer pick up VDI physicalSize
+            tmpltSR.scan(conn);
+            if (userSpecifiedName != null) {
+                tmpltVDI.setNameLabel(conn, userSpecifiedName);
+            }
+
+            final String tmpltUUID = tmpltVDI.getUuid(conn);
+            final String tmpltFilename = tmpltUUID + ".vhd";
+            final long virtualSize = tmpltVDI.getVirtualSize(conn);
+            final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
+            // create the template.properties file
+            final String templatePath = secondaryStorageMountPath + "/" + installPath;
+            result =
+                    hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize,
+                            template.getId());
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI);
+            }
+            installPath = installPath + "/" + tmpltFilename;
+            hypervisorResource.removeSR(conn, tmpltSR);
+            tmpltSR = null;
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(installPath);
+            newTemplate.setFormat(ImageFormat.VHD);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(tmpltUUID);
+            final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
+            return answer;
+        } catch (final Exception e) {
+            if (tmpltSR != null) {
+                hypervisorResource.removeSR(conn, tmpltSR);
+            }
+            if (secondaryStorageMountPath != null) {
+                hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
+            }
+            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
+            s_logger.error(details, e);
+        }
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+
+        final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO();
+        final TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO();
+
+        if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) {
+            return null;
+        }
+
+        final String userSpecifiedTemplateName = templateObjTO.getName();
+
+        NfsTO destStore = null;
+        URI destUri = null;
+
+        try {
+            destStore = (NfsTO)templateObjTO.getDataStore();
+
+            destUri = new URI(destStore.getUrl());
+        } catch (final Exception ex) {
+            s_logger.debug("Invalid URI", ex);
+
+            return new CopyCmdAnswer("Invalid URI: " + ex.toString());
+        }
+
+        SR srcSr = null;
+        SR destSr = null;
+
+        final String destDir = templateObjTO.getPath();
+        VDI destVdi = null;
+
+        boolean result = false;
+
+        try {
+            final Map<String, String> srcDetails = cmd.getOptions();
+
+            final String iScsiName = srcDetails.get(DiskTO.IQN);
+            final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
+            final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true);
+
+            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
+
+            if (!hypervisorResource.createSecondaryStorageFolder(conn, destNfsPath, destDir)) {
+                final String details = " Failed to create folder " + destDir + " in secondary storage";
+
+                s_logger.warn(details);
+
+                return new CopyCmdAnswer(details);
+            }
+
+            final URI templateUri = new URI(destStore.getUrl() + "/" + destDir);
+
+            destSr = hypervisorResource.createNfsSRbyURI(conn, templateUri, false);
+
+            // there should only be one VDI in this SR
+            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
+
+            destVdi = srcVdi.copy(conn, destSr);
+
+            // scan makes XenServer pick up VDI physicalSize
+            destSr.scan(conn);
+
+            if (userSpecifiedTemplateName != null) {
+                destVdi.setNameLabel(conn, userSpecifiedTemplateName);
+            }
+
+            final String templateUuid = destVdi.getUuid(conn);
+            final String templateFilename = templateUuid + ".vhd";
+            final long virtualSize = destVdi.getVirtualSize(conn);
+            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
+
+            // create the template.properties file
+            String templatePath = destNfsPath + "/" + destDir;
+
+            templatePath = templatePath.replaceAll("//", "/");
+
+            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, userSpecifiedTemplateName, null,
+                    physicalSize, virtualSize, templateObjTO.getId());
+
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri);
+            }
+
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(destDir + "/" + templateFilename);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setHypervisorType(HypervisorType.XenServer);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(templateUuid);
+
+            result = true;
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (final Exception ex) {
+            s_logger.error("Failed to create a template from a snapshot", ex);
+
+            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + ex.toString());
+        } finally {
+            if (!result) {
+                if (destVdi != null) {
+                    try {
+                        destVdi.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e);
+                    }
+                }
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+
+            if (destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+        }
+    }
+
+    private boolean isManaged(Map<String, String> options) {
+        if (options == null) {
+            return false;
+        }
+
+        String iqn = options.get(DiskTO.IQN);
+
+        if (iqn == null || iqn.trim().length() == 0) {
+            return false;
+        }
+
+        String storageHost = options.get(DiskTO.STORAGE_HOST);
+
+        if (storageHost == null || storageHost.trim().length() == 0) {
+            return false;
+        }
+
+        return true;
+    }
+
+    boolean isCreateManagedVolumeFromManagedSnapshot(Map<String, String> volumeOptions, Map<String, String> snapshotOptions) {
+        return isManaged(volumeOptions) && isManaged(snapshotOptions);
+    }
+
+    boolean isCreateNonManagedVolumeFromManagedSnapshot(Map<String, String> volumeOptions, Map<String, String> snapshotOptions) {
+        return !isManaged(volumeOptions) && isManaged(snapshotOptions);
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+
+        DataTO srcData = cmd.getSrcTO();
+        SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        DataStoreTO imageStore = srcData.getDataStore();
+        DataTO destData = cmd.getDestTO();
+
+        if (isCreateManagedVolumeFromManagedSnapshot(cmd.getOptions2(), cmd.getOptions())) {
+            return createManagedVolumeFromManagedSnapshot(cmd);
+        }
+
+        if (isCreateNonManagedVolumeFromManagedSnapshot(cmd.getOptions2(), cmd.getOptions())) {
+            return createNonManagedVolumeFromManagedSnapshot(cmd);
+        }
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        NfsTO nfsImageStore = (NfsTO)imageStore;
+        String primaryStorageNameLabel = destData.getDataStore().getUuid();
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+
+        int wait = cmd.getWait();
+        boolean result = false;
+
+        // Generic error message.
+        String details;
+        String volumeUUID;
+
+        if (secondaryStorageUrl == null) {
+            details = "The URL passed in 'null'.";
+
+            return new CopyCmdAnswer(details);
+        }
+
+        try {
+            SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not create volume from snapshot because the primary storage SR could not be " +
+                        "created from the name label: " + primaryStorageNameLabel);
+            }
+
+            // Get the absolute path of the snapshot on the secondary storage.
+            String snapshotInstallPath = snapshot.getPath();
+            int index = snapshotInstallPath.lastIndexOf(nfsImageStore.getPathSeparator());
+            String snapshotName = snapshotInstallPath.substring(index + 1);
+
+            if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
+                snapshotInstallPath = snapshotInstallPath + ".vhd";
+            }
+
+            URI snapshotURI = new URI(secondaryStorageUrl + nfsImageStore.getPathSeparator() + snapshotInstallPath);
+            String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath();
+            String srUuid = primaryStorageSR.getUuid(conn);
+
+            volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait);
+            result = true;
+
+            VDI volume = VDI.getByUuid(conn, volumeUUID);
+            VDI.Record vdir = volume.getRecord(conn);
+            VolumeObjectTO newVol = new VolumeObjectTO();
+
+            newVol.setPath(volumeUUID);
+            newVol.setSize(vdir.virtualSize);
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final XenAPIException e) {
+            details = "Exception due to " + e.toString();
+
+            s_logger.warn(details, e);
+        } catch (final Exception e) {
+            details = "Exception due to " + e.getMessage();
+
+            s_logger.warn(details, e);
+        }
+
+        if (!result) {
+            // Is this logged at a higher level?
+            s_logger.error(details);
+        }
+
+        // In all cases return something.
+        return new CopyCmdAnswer(details);
+    }
+
+    Answer createManagedVolumeFromManagedSnapshot(final CopyCommand cmd) {
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+
+            final Map<String, String> srcOptions = cmd.getOptions();
+
+            final String src_iScsiName = srcOptions.get(DiskTO.IQN);
+            final String srcStorageHost = srcOptions.get(DiskTO.STORAGE_HOST);
+            final String srcChapInitiatorUsername = srcOptions.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String srcChapInitiatorSecret = srcOptions.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            final SR srcSr = hypervisorResource.getIscsiSR(conn, src_iScsiName, srcStorageHost, src_iScsiName, srcChapInitiatorUsername, srcChapInitiatorSecret, false);
+
+            final Map<String, String> destOptions = cmd.getOptions2();
+
+            final String dest_iScsiName = destOptions.get(DiskTO.IQN);
+            final String destStorageHost = destOptions.get(DiskTO.STORAGE_HOST);
+            final String destChapInitiatorUsername = destOptions.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String destChapInitiatorSecret = destOptions.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            final SR destSr = hypervisorResource.getIscsiSR(conn, dest_iScsiName, destStorageHost, dest_iScsiName, destChapInitiatorUsername, destChapInitiatorSecret, false);
+
+            // there should only be one VDI in this SR
+            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
+
+            final VDI vdiCopy = srcVdi.copy(conn, destSr);
+
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+
+            newVol.setSize(vdiCopy.getVirtualSize(conn));
+            newVol.setPath(vdiCopy.getUuid(conn));
+            newVol.setFormat(ImageFormat.VHD);
+
+            hypervisorResource.removeSR(conn, srcSr);
+            hypervisorResource.removeSR(conn, destSr);
+
+            return new CopyCmdAnswer(newVol);
+        }
+        catch (final Exception ex) {
+            s_logger.warn("Failed to copy snapshot to volume: " + ex.toString(), ex);
+
+            return new CopyCmdAnswer(ex.getMessage());
+        }
+    }
+
+    Answer createNonManagedVolumeFromManagedSnapshot(final CopyCommand cmd) {
+        Connection conn = hypervisorResource.getConnection();
+        SR srcSr = null;
+
+        try {
+            Map<String, String> srcOptions = cmd.getOptions();
+
+            String src_iScsiName = srcOptions.get(DiskTO.IQN);
+            String srcStorageHost = srcOptions.get(DiskTO.STORAGE_HOST);
+            String srcChapInitiatorUsername = srcOptions.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            String srcChapInitiatorSecret = srcOptions.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+            srcSr = hypervisorResource.getIscsiSR(conn, src_iScsiName, srcStorageHost, src_iScsiName,
+                    srcChapInitiatorUsername, srcChapInitiatorSecret, false);
+
+            // there should only be one VDI in this SR
+            VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
+
+            DataTO destData = cmd.getDestTO();
+            String primaryStorageNameLabel = destData.getDataStore().getUuid();
+
+            SR destSr = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+
+            VDI vdiCopy = srcVdi.copy(conn, destSr);
+
+            VolumeObjectTO newVol = new VolumeObjectTO();
+
+            newVol.setSize(vdiCopy.getVirtualSize(conn));
+            newVol.setPath(vdiCopy.getUuid(conn));
+            newVol.setFormat(ImageFormat.VHD);
+
+            return new CopyCmdAnswer(newVol);
+        }
+        catch (Exception ex) {
+            s_logger.warn("Failed to copy snapshot to volume: " + ex.toString(), ex);
+
+            return new CopyCmdAnswer(ex.getMessage());
+        }
+        finally {
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+        }
+    }
+
+    @Override
+    public Answer deleteSnapshot(final DeleteCommand cmd) {
+        final SnapshotObjectTO snapshot = (SnapshotObjectTO) cmd.getData();
+        final DataStoreTO store = snapshot.getDataStore();
+        if (store.getRole() == DataStoreRole.Primary) {
+            final Connection conn = hypervisorResource.getConnection();
+            final VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath());
+            if (snapshotVdi == null) {
+                return new Answer(null);
+            }
+            String errMsg = null;
+            try {
+                deleteVDI(conn, snapshotVdi);
+            } catch (final BadServerResponse e) {
+                s_logger.debug("delete snapshot failed:" + e.toString());
+                errMsg = e.toString();
+            } catch (final XenAPIException e) {
+                s_logger.debug("delete snapshot failed:" + e.toString());
+                errMsg = e.toString();
+            } catch (final XmlRpcException e) {
+                s_logger.debug("delete snapshot failed:" + e.toString());
+                errMsg = e.toString();
+            }
+            return new Answer(cmd, false, errMsg);
+        }
+        return new Answer(cmd, false, "unsupported storage type");
+    }
+
+    @Override
+    public Answer introduceObject(final IntroduceObjectCmd cmd) {
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+            final DataStoreTO store = cmd.getDataTO().getDataStore();
+            final SR poolSr = hypervisorResource.getStorageRepository(conn, store.getUuid());
+            poolSr.scan(conn);
+            return new IntroduceObjectAnswer(cmd.getDataTO());
+        } catch (final Exception e) {
+            s_logger.debug("Failed to introduce object", e);
+            return new Answer(cmd, false, e.toString());
+        }
+    }
+
+    @Override
+    public Answer forgetObject(final ForgetObjectCmd cmd) {
+        try {
+            final Connection conn = hypervisorResource.getConnection();
+            final DataTO data = cmd.getDataTO();
+            final VDI vdi = VDI.getByUuid(conn, data.getPath());
+            vdi.forget(conn);
+            return new IntroduceObjectAnswer(cmd.getDataTO());
+        } catch (final Exception e) {
+            s_logger.debug("Failed to forget object", e);
+            return new Answer(cmd, false, e.toString());
+        }
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
new file mode 100644
index 0000000..ddafc15
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
@@ -0,0 +1,1298 @@
+/*
+ * 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.xenserver.resource;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.StorageOperations;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VDI;
+
+public class Xenserver625StorageProcessor extends XenServerStorageProcessor {
+    private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class);
+
+    public Xenserver625StorageProcessor(final CitrixResourceBase resource) {
+        super(resource);
+    }
+
+    private void mountNfs(Connection conn, String remoteDir, String localDir) {
+        if (localDir == null) {
+            localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remoteDir.getBytes());
+        }
+        String result = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir", remoteDir);
+        if (StringUtils.isBlank(result)) {
+            String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir;
+            s_logger.warn(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+    }
+
+    protected boolean makeDirectory(Connection conn, String path) {
+        String result = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "makeDirectory", "path", path);
+        return StringUtils.isNotBlank(result);
+    }
+
+    /**
+     *  Creates the file SR for the given path. If there already exist a file SR for the path, we return the existing one.
+     *  This method uses a synchronized block to guarantee that only a single file SR is created per path.
+     *  If it is not possible to retrieve one file SR or to create one, a runtime exception will be thrown.
+     */
+    protected SR createFileSR(Connection conn, String path) {
+        String srPath = StringUtils.trim(path);
+        synchronized (srPath) {
+            SR sr = retrieveAlreadyConfiguredSrWithoutException(conn, srPath);
+            if (sr == null) {
+                sr = createNewFileSr(conn, srPath);
+            }
+            if (sr == null) {
+                String hostUuid = this.hypervisorResource._host.getUuid();
+                throw new CloudRuntimeException(String.format("Could not retrieve an already used file SR for path [%s] or create a new file SR on host [%s]", srPath, hostUuid));
+            }
+            return sr;
+        }
+    }
+
+    /**
+     * Creates a new file SR for the given path. If any of XenServer's checked exception occurs, we use method {@link #removeSrAndPbdIfPossible(Connection, SR, PBD)} to clean the created PBD and SR entries.
+     * To avoid race conditions between management servers, we are using a deterministic srUuid for the file SR to be created (we are leaving XenServer with the burden of managing race conditions). The UUID is based on the SR file path, and is generated using {@link UUID#nameUUIDFromBytes(byte[])}.
+     * If there is an SR with the generated UUID, this means that some other management server has just created it. An exception will occur and this exception will be an {@link InternalError}. The exception will contain {@link InternalError#message} a message saying 'Db_exn.Uniqueness_constraint_violation'.
+     * For cases where the previous described error happens, we catch the exception and use the method {@link #retrieveAlreadyConfiguredSrWithoutException(Connection, String)}.
+     */
+    protected SR createNewFileSr(Connection conn, String srPath) {
+        String hostUuid = hypervisorResource.getHost().getUuid();
+        s_logger.debug(String.format("Creating file SR for path [%s] on host [%s]", srPath, this.hypervisorResource._host.getUuid()));
+        SR sr = null;
+        PBD pbd = null;
+        try {
+            Host host = Host.getByUuid(conn, hostUuid);
+            String srUuid = UUID.nameUUIDFromBytes(srPath.getBytes()).toString();
+
+            Map<String, String> smConfig = new HashMap<String, String>();
+            sr = SR.introduce(conn, srUuid, srPath, srPath, "file", "file", false, smConfig);
+
+            PBD.Record record = new PBD.Record();
+            record.host = host;
+            record.SR = sr;
+            smConfig.put("location", srPath);
+            record.deviceConfig = smConfig;
+            pbd = PBD.create(conn, record);
+            pbd.plug(conn);
+            sr.scan(conn);
+            return sr;
+        } catch (XenAPIException | XmlRpcException e) {
+            if (e instanceof Types.InternalError) {
+                String expectedDuplicatedFileSrErrorMessage = "Db_exn.Uniqueness_constraint_violation";
+
+                Types.InternalError internalErrorException = (Types.InternalError)e;
+                if (StringUtils.contains(internalErrorException.message, expectedDuplicatedFileSrErrorMessage)) {
+                    s_logger.debug(String.format(
+                            "It seems that we have hit a race condition case here while creating file SR for [%s]. Instead of creating one, we will reuse the one that already exist in the XenServer pool.",
+                            srPath));
+                    return retrieveAlreadyConfiguredSrWithoutException(conn, srPath);
+                }
+            }
+            removeSrAndPbdIfPossible(conn, sr, pbd);
+            s_logger.debug(String.format("Could not create file SR [%s] on host [%s].", srPath, hostUuid), e);
+            return null;
+        }
+    }
+
+    /**
+     * Calls {@link #unplugPbd(Connection, PBD)} and {@link #forgetSr(Connection, SR)}, if respective objects are not null.
+     */
+    protected void removeSrAndPbdIfPossible(Connection conn, SR sr, PBD pbd) {
+        if (pbd != null) {
+            unplugPbd(conn, pbd);
+        }
+        if (sr != null) {
+            forgetSr(conn, sr);
+        }
+    }
+
+    /**
+     * This is a simple facade for {@link #retrieveAlreadyConfiguredSr(Connection, String)} method.
+     * If we catch any of the checked exception of {@link #retrieveAlreadyConfiguredSr(Connection, String)}, we re-throw as a {@link CloudRuntimeException}.
+     */
+    protected SR retrieveAlreadyConfiguredSrWithoutException(Connection conn, String srPath) {
+        try {
+            return retrieveAlreadyConfiguredSr(conn, srPath);
+        } catch (XenAPIException | XmlRpcException e) {
+            throw new CloudRuntimeException("Unexpected exception while trying to retrieve an already configured file SR for path: " + srPath);
+        }
+    }
+
+    /**
+     *  This method will check if there is an already configured file SR for the given path. If by any chance we find more than one SR with the same name (mount point path) we throw a runtime exception because this situation should never happen.
+     *  If we find an SR, we check if the SR is working properly (performing an {@link SR#scan(Connection)}). If everything is ok with the SR, we return it.
+     *  Otherwise, we remove the SR using {@link #forgetSr(Connection, SR)} method;
+     */
+    protected SR retrieveAlreadyConfiguredSr(Connection conn, String path) throws XenAPIException, XmlRpcException {
+        Set<SR> srs = SR.getByNameLabel(conn, path);
+        if (CollectionUtils.isEmpty(srs)) {
+            s_logger.debug("No file SR found for path: " + path);
+            return null;
+        }
+        if (srs.size() > 1) {
+            throw new CloudRuntimeException("There should be only one SR with name-label: " + path);
+        }
+        SR sr = srs.iterator().next();
+        String srUuid = sr.getUuid(conn);
+        s_logger.debug(String.format("SR [%s] was already introduced in XenServer. Checking if we can reuse it.", srUuid));
+        Map<String, StorageOperations> currentOperations = sr.getCurrentOperations(conn);
+        if (MapUtils.isEmpty(currentOperations)) {
+            s_logger.debug(String.format("There are no current operation in SR [%s]. It looks like an unusual condition. We will check if it is usable before returning it.", srUuid));
+        }
+        try {
+            sr.scan(conn);
+        } catch (XenAPIException | XmlRpcException e) {
+            s_logger.debug(String.format("Problems while checking if cached temporary SR [%s] is working properly (we executed sr-scan). We will not reuse it.", srUuid));
+            forgetSr(conn, sr);
+            return null;
+        }
+        s_logger.debug(String.format("Cached temporary SR [%s] is working properly. We will reuse it.", srUuid));
+        return sr;
+    }
+
+    /**
+     *  Forgets the given SR. Before executing the command {@link SR#forget(Connection)}, we will unplug all of its PBDs using {@link PBD#unplug(Connection)}.
+     *  Checked exceptions are captured and re-thrown as {@link CloudRuntimeException}.
+     */
+    protected void forgetSr(Connection conn, SR sr) {
+        String srUuid = StringUtils.EMPTY;
+        try {
+            srUuid = sr.getUuid(conn);
+            Set<PBD> pbDs = sr.getPBDs(conn);
+            for (PBD pbd : pbDs) {
+                s_logger.debug(String.format("Unpluging PBD [%s] of SR [%s] as it is not working properly.", pbd.getUuid(conn), srUuid));
+                unplugPbd(conn, pbd);
+            }
+            s_logger.debug(String.format("Forgetting SR [%s] as it is not working properly.", srUuid));
+            sr.forget(conn);
+        } catch (XenAPIException | XmlRpcException e) {
+            throw new CloudRuntimeException("Exception while forgeting SR: " + srUuid, e);
+        }
+    }
+
+    /**
+     * Unplugs the given {@link PBD}. If checked exception happens, we re-throw as {@link CloudRuntimeException}
+     */
+    protected void unplugPbd(Connection conn, PBD pbd) {
+        String pbdUuid = StringUtils.EMPTY;
+        try {
+            pbdUuid = pbd.getUuid(conn);
+            pbd.unplug(conn);
+        } catch (XenAPIException | XmlRpcException e) {
+            throw new CloudRuntimeException(String.format("Exception while unpluging PBD [%s].", pbdUuid));
+        }
+    }
+
+    protected SR createFileSr(Connection conn, String remotePath, String dir) {
+        String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remotePath.getBytes());
+        mountNfs(conn, remotePath, localDir);
+        return createFileSR(conn, localDir + "/" + dir);
+    }
+
+    @Override
+    public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final DataStoreTO srcStore = srcData.getDataStore();
+        final Connection conn = hypervisorResource.getConnection();
+        SR srcSr = null;
+        SR destSr = null;
+        boolean removeSrAfterCopy = false;
+        Task task = null;
+
+        try {
+            if (srcStore instanceof NfsTO && srcData.getObjectType() == DataObjectType.TEMPLATE) {
+                final NfsTO srcImageStore = (NfsTO)srcStore;
+                final TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData;
+                final String storeUrl = srcImageStore.getUrl();
+                final URI uri = new URI(storeUrl);
+                String volumePath = srcData.getPath();
+
+                volumePath = StringUtils.stripEnd(volumePath, "/");
+
+                final String[] splits = volumePath.split("/");
+                String volumeDirectory = volumePath;
+
+                if (splits.length > 4) {
+                    // "template/tmpl/dcid/templateId/templatename"
+                    final int index = volumePath.lastIndexOf("/");
+
+                    volumeDirectory = volumePath.substring(0, index);
+                }
+
+                srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
+
+                final Set<VDI> setVdis = srcSr.getVDIs(conn);
+
+                if (setVdis.size() != 1) {
+                    return new CopyCmdAnswer("Expected 1 VDI template, but found " + setVdis.size() + " VDI templates on: " + uri.getHost() + ":" + uri.getPath() + "/" + volumeDirectory);
+                }
+
+                final VDI srcVdi = setVdis.iterator().next();
+
+                boolean managed = false;
+                String storageHost = null;
+                String managedStoragePoolName = null;
+                String managedStoragePoolRootVolumeName = null;
+                String managedStoragePoolRootVolumeSize = null;
+                String chapInitiatorUsername = null;
+                String chapInitiatorSecret = null;
+
+                final PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore();
+
+                Map<String, String> details = destStore.getDetails();
+
+                if (details != null) {
+                    managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
+
+                    if (managed) {
+                        storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
+                        managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
+                        managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
+                        managedStoragePoolRootVolumeSize = details.get(PrimaryDataStoreTO.VOLUME_SIZE);
+                        chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
+                        chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
+                        removeSrAfterCopy = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.REMOVE_AFTER_COPY));
+                    }
+                }
+
+                if (managed) {
+                    details = new HashMap<String, String>();
+
+                    details.put(DiskTO.STORAGE_HOST, storageHost);
+                    details.put(DiskTO.IQN, managedStoragePoolName);
+                    details.put(DiskTO.VOLUME_SIZE, managedStoragePoolRootVolumeSize);
+                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInitiatorUsername);
+                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInitiatorSecret);
+
+                    destSr = hypervisorResource.prepareManagedSr(conn, details);
+                } else {
+                    final String srName = destStore.getUuid();
+                    final Set<SR> srs = SR.getByNameLabel(conn, srName);
+
+                    if (srs.size() != 1) {
+                        final String msg = "There are " + srs.size() + " SRs with same name: " + srName;
+
+                        s_logger.warn(msg);
+
+                        return new CopyCmdAnswer(msg);
+                    } else {
+                        destSr = srs.iterator().next();
+                    }
+                }
+
+                task = srcVdi.copyAsync(conn, destSr, null, null);
+
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+
+                final VDI tmplVdi = Types.toVDI(task, conn);
+
+                final String uuidToReturn;
+                final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn);
+
+                if (managed) {
+                    uuidToReturn = tmplVdi.getUuid(conn);
+
+                    tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName);
+                } else {
+                    final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap<String, String>());
+
+                    uuidToReturn = snapshotVdi.getUuid(conn);
+
+                    snapshotVdi.setNameLabel(conn, "Template " + srcTemplate.getName());
+
+                    tmplVdi.destroy(conn);
+                }
+
+                destSr.scan(conn);
+
+                try {
+                    Thread.sleep(5000);
+                } catch (final Exception e) {
+                }
+
+                final TemplateObjectTO newVol = new TemplateObjectTO();
+
+                newVol.setUuid(uuidToReturn);
+                newVol.setPath(uuidToReturn);
+
+                if (physicalSize != null) {
+                    newVol.setSize(physicalSize);
+                }
+
+                newVol.setFormat(Storage.ImageFormat.VHD);
+
+                return new CopyCmdAnswer(newVol);
+            }
+        } catch (final Exception e) {
+            final String msg = "Catch Exception " + e.getClass().getName() + " for template due to " + e.toString();
+
+            s_logger.warn(msg, e);
+
+            return new CopyCmdAnswer(msg);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.debug("unable to destroy task (" + task.toWireString() + ") due to " + e.toString());
+                }
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+
+            if (removeSrAfterCopy && destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+        }
+
+        return new CopyCmdAnswer("not implemented yet");
+    }
+
+    protected String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, final String secondaryStorageMountPath,
+            final String snapshotUuid, String prevBackupUuid, final String prevSnapshotUuid, final Boolean isISCSI, int wait) {
+        boolean filesrcreated = false;
+        // boolean copied = false;
+
+        if (prevBackupUuid == null) {
+            prevBackupUuid = "";
+        }
+        SR ssSR = null;
+
+        final String remoteDir = secondaryStorageMountPath;
+        try {
+            ssSR = createFileSr(conn, remoteDir, path);
+            filesrcreated = true;
+
+            final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid);
+            if (wait == 0) {
+                wait = 2 * 60 * 60;
+            }
+            VDI dvdi = null;
+            Task task = null;
+            try {
+                VDI previousSnapshotVdi = null;
+                if (prevSnapshotUuid != null) {
+                    previousSnapshotVdi = VDI.getByUuid(conn, prevSnapshotUuid);
+                }
+                task = snapshotvdi.copyAsync(conn, ssSR, previousSnapshotVdi, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                dvdi = Types.toVDI(task, conn);
+                ssSR.scan(conn);
+                // copied = true;
+            } finally {
+                if (task != null) {
+                    try {
+                        task.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
+                    }
+                }
+            }
+            final String result = dvdi.getUuid(conn).concat("#").concat(dvdi.getPhysicalUtilisation(conn).toString());
+            return result;
+        } catch (final Exception e) {
+            final String msg = "Exception in backupsnapshot stage due to " + e.toString();
+            s_logger.debug(msg);
+            throw new CloudRuntimeException(msg, e);
+        } finally {
+            try {
+                if (filesrcreated && ssSR != null) {
+                    hypervisorResource.removeSR(conn, ssSR);
+                }
+            } catch (final Exception e) {
+                s_logger.debug("Exception in backupsnapshot cleanup stage due to " + e.toString());
+            }
+        }
+    }
+
+    @Override
+    protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) {
+        final String parentUuid = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI",
+                isISCSI.toString());
+
+        if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) {
+            s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid);
+            // errString is already logged.
+            return null;
+        }
+        return parentUuid;
+    }
+
+    @Override
+    public Answer backupSnapshot(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO cacheData = cmd.getCacheTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore();
+        final String primaryStorageNameLabel = primaryStore.getUuid();
+        String secondaryStorageUrl = null;
+        NfsTO cacheStore = null;
+        String destPath = null;
+        if (cacheData != null) {
+            cacheStore = (NfsTO)cacheData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = cacheData.getPath();
+        } else {
+            cacheStore = (NfsTO)destData.getDataStore();
+            secondaryStorageUrl = cacheStore.getUrl();
+            destPath = destData.getPath();
+        }
+
+        final SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData;
+        final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData;
+        String snapshotUuid = snapshotTO.getPath();
+
+        final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
+        final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
+        final Map<String, String> options = cmd.getOptions();
+        // By default assume failure
+        String details = null;
+        String snapshotBackupUuid = null;
+        boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
+        Long physicalSize = null;
+        try {
+
+            SR primaryStorageSR = null;
+            if (primaryStore.isManaged()) {
+                fullbackup = true; // currently, managed storage only supports full backup
+
+                final Map<String, String> srcDetails = cmd.getOptions();
+
+                final String iScsiName = srcDetails.get(DiskTO.IQN);
+                final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
+                final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+                final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+                final String srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
+
+                primaryStorageSR = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
+
+                final VDI srcVdi = primaryStorageSR.getVDIs(conn).iterator().next();
+                if (srcVdi == null) {
+                    throw new InternalErrorException("Could not Find a VDI on the SR: " + primaryStorageSR.getNameLabel(conn));
+                }
+                snapshotUuid = srcVdi.getUuid(conn);
+
+            } else {
+                primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            }
+
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
+            }
+            // String psUuid = primaryStorageSR.getUuid(conn);
+            final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
+
+            final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
+            final String snapshotPaUuid = snapshotVdi.getUuid(conn);
+
+            final URI uri = new URI(secondaryStorageUrl);
+            final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            final DataStoreTO destStore = destData.getDataStore();
+            final String folder = destPath;
+            String finalPath = null;
+
+            final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
+            if (fullbackup) {
+                SR snapshotSr = null;
+                Task task = null;
+                try {
+                    final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes());
+                    mountNfs(conn, secondaryStorageMountPath, localDir);
+                    final boolean result = makeDirectory(conn, localDir + "/" + folder);
+                    if (!result) {
+                        details = " Failed to create folder " + folder + " in secondary storage";
+                        s_logger.warn(details);
+                        return new CopyCmdAnswer(details);
+                    }
+
+                    snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder);
+
+                    task = snapshotVdi.copyAsync(conn, snapshotSr, null, null);
+                    // poll every 1 seconds ,
+                    hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                    hypervisorResource.checkForSuccess(conn, task);
+                    final VDI backedVdi = Types.toVDI(task, conn);
+                    snapshotBackupUuid = backedVdi.getUuid(conn);
+                    snapshotSr.scan(conn);
+                    physicalSize = backedVdi.getPhysicalUtilisation(conn);
+
+                    if (destStore instanceof SwiftTO) {
+                        try {
+                            final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                            final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
+                            final String swiftPath = container + File.separator + destSnapshotName;
+                            finalPath = swiftPath;
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (final Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages", e);
+                            }
+                        }
+
+                    } else if (destStore instanceof S3TO) {
+                        try {
+                            finalPath = backupSnapshotToS3(conn, (S3TO)destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
+                            if (finalPath == null) {
+                                throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
+                            }
+                        } finally {
+                            try {
+                                deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
+                            } catch (final Exception e) {
+                                s_logger.debug("Failed to delete snapshot on cache storages", e);
+                            }
+                        }
+                        // finalPath = folder + File.separator +
+                        // snapshotBackupUuid;
+                    } else {
+                        finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
+                    }
+
+                } finally {
+                    if (task != null) {
+                        try {
+                            task.destroy(conn);
+                        } catch (final Exception e) {
+                            s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
+                        }
+                    }
+                    if (snapshotSr != null) {
+                        hypervisorResource.removeSR(conn, snapshotSr);
+                    }
+
+                    if (primaryStore.isManaged()) {
+                        hypervisorResource.removeSR(conn, primaryStorageSR);
+                    }
+                }
+            } else {
+                final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
+                if (destStore instanceof SwiftTO) {
+                    final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
+                    snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO)destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait);
+                    finalPath = container + File.separator + snapshotBackupUuid;
+                } else if (destStore instanceof S3TO) {
+                    finalPath = backupSnapshotToS3(conn, (S3TO)destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
+                    if (finalPath == null) {
+                        throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
+                    }
+                } else {
+                    final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait);
+                    final String[] tmp = result.split("#");
+                    snapshotBackupUuid = tmp[0];
+                    physicalSize = Long.parseLong(tmp[1]);
+                    finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
+                }
+            }
+
+            // remove every snapshot except this one from primary storage
+            final String volumeUuid = snapshotTO.getVolume().getPath();
+            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
+
+            final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+            newSnapshot.setPath(finalPath);
+            newSnapshot.setPhysicalSize(physicalSize);
+            if (fullbackup) {
+                newSnapshot.setParentSnapshotPath(null);
+            } else {
+                newSnapshot.setParentSnapshotPath(prevBackupUuid);
+            }
+            s_logger.info("New snapshot details: " + newSnapshot.toString());
+            s_logger.info("New snapshot physical utilization: " + physicalSize);
+
+            return new CopyCmdAnswer(newSnapshot);
+        } catch (final Exception e) {
+            final String reason = e instanceof Types.XenAPIException ? e.toString() : e.getMessage();
+            details = "BackupSnapshot Failed due to " + reason;
+            s_logger.warn(details, e);
+
+            // remove last bad primary snapshot when exception happens
+            destroySnapshotOnPrimaryStorage(conn, snapshotUuid);
+        }
+
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer createTemplateFromVolume(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO();
+        final TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO();
+        final NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore();
+        final int wait = cmd.getWait();
+
+        final String secondaryStoragePoolURL = destStore.getUrl();
+        final String volumeUUID = volume.getPath();
+
+        final String userSpecifiedName = template.getName();
+
+        String details = null;
+        SR tmpltSR = null;
+        boolean result = false;
+        String secondaryStorageMountPath = null;
+        String installPath = null;
+        Task task = null;
+        try {
+            final URI uri = new URI(secondaryStoragePoolURL);
+            secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            installPath = template.getPath();
+            if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) {
+                details = " Filed to create folder " + installPath + " in secondary storage";
+                s_logger.warn(details);
+                return new CopyCmdAnswer(details);
+            }
+
+            final VDI vol = getVDIbyUuid(conn, volumeUUID);
+            // create template SR
+            tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath);
+
+            // copy volume to template SR
+            task = vol.copyAsync(conn, tmpltSR, null, null);
+            // poll every 1 seconds ,
+            hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+            hypervisorResource.checkForSuccess(conn, task);
+            final VDI tmpltVDI = Types.toVDI(task, conn);
+            // scan makes XenServer pick up VDI physicalSize
+            tmpltSR.scan(conn);
+            if (userSpecifiedName != null) {
+                tmpltVDI.setNameLabel(conn, userSpecifiedName);
+            }
+
+            final String tmpltUUID = tmpltVDI.getUuid(conn);
+            final String tmpltFilename = tmpltUUID + ".vhd";
+            final long virtualSize = tmpltVDI.getVirtualSize(conn);
+            final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn);
+            // create the template.properties file
+            final String templatePath = secondaryStorageMountPath + "/" + installPath;
+            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId());
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
+            }
+            installPath = installPath + "/" + tmpltFilename;
+            hypervisorResource.removeSR(conn, tmpltSR);
+            tmpltSR = null;
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(installPath);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(tmpltUUID);
+            final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
+            return answer;
+        } catch (final Exception e) {
+            if (tmpltSR != null) {
+                hypervisorResource.removeSR(conn, tmpltSR);
+            }
+            if (secondaryStorageMountPath != null) {
+                hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath);
+            }
+            details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString();
+            s_logger.error(details, e);
+        } finally {
+            if (task != null) {
+                try {
+                    task.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
+                }
+            }
+        }
+        return new CopyCmdAnswer(details);
+    }
+
+    protected String getSnapshotUuid(final String snapshotPath) {
+        int index = snapshotPath.lastIndexOf(File.separator);
+        String snapshotUuid = snapshotPath.substring(index + 1);
+        index = snapshotUuid.lastIndexOf(".");
+        if (index != -1) {
+            snapshotUuid = snapshotUuid.substring(0, index);
+        }
+        return snapshotUuid;
+    }
+
+    @Override
+    public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+        final DataTO destData = cmd.getDestTO();
+        final PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore();
+        final VolumeObjectTO volume = (VolumeObjectTO)destData;
+        final DataStoreTO imageStore = srcData.getDataStore();
+
+        if (isCreateManagedVolumeFromManagedSnapshot(cmd.getOptions2(), cmd.getOptions())) {
+            return createManagedVolumeFromManagedSnapshot(cmd);
+        }
+
+        if (isCreateNonManagedVolumeFromManagedSnapshot(cmd.getOptions2(), cmd.getOptions())) {
+            return createNonManagedVolumeFromManagedSnapshot(cmd);
+        }
+
+        if (!(imageStore instanceof NfsTO)) {
+            return new CopyCmdAnswer("unsupported protocol");
+        }
+
+        final NfsTO nfsImageStore = (NfsTO)imageStore;
+        final String primaryStorageNameLabel = pool.getUuid();
+        final String secondaryStorageUrl = nfsImageStore.getUrl();
+        final int wait = cmd.getWait();
+        boolean result = false;
+        // Generic error message.
+        String details = null;
+        String volumeUUID = null;
+
+        if (secondaryStorageUrl == null) {
+            details += " because the URL passed: " + secondaryStorageUrl + " is invalid.";
+            return new CopyCmdAnswer(details);
+        }
+        SR srcSr = null;
+        VDI destVdi = null;
+
+        SR primaryStorageSR = null;
+
+        try {
+            if (pool.isManaged()) {
+                Map<String, String> destDetails = cmd.getOptions2();
+
+                final String iScsiName = destDetails.get(DiskTO.IQN);
+                final String storageHost = destDetails.get(DiskTO.STORAGE_HOST);
+                final String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+                final String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+                final String srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
+
+                primaryStorageSR = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
+
+            } else {
+                primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+            }
+
+            if (primaryStorageSR == null) {
+                throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
+            }
+
+            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
+            destVdi = createVdi(conn, nameLabel, primaryStorageSR, volume.getSize());
+            volumeUUID = destVdi.getUuid(conn);
+            final String snapshotInstallPath = snapshot.getPath();
+            final int index = snapshotInstallPath.lastIndexOf(File.separator);
+            final String snapshotDirectory = snapshotInstallPath.substring(0, index);
+            final String snapshotUuid = getSnapshotUuid(snapshotInstallPath);
+
+            final URI uri = new URI(secondaryStorageUrl);
+            srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory);
+
+            final String[] parents = snapshot.getParents();
+            final List<VDI> snapshotChains = new ArrayList<VDI>();
+            if (parents != null) {
+                for (int i = 0; i < parents.length; i++) {
+                    final String snChainPath = parents[i];
+                    final String uuid = getSnapshotUuid(snChainPath);
+                    final VDI chain = VDI.getByUuid(conn, uuid);
+                    snapshotChains.add(chain);
+                }
+            }
+
+            final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
+            snapshotChains.add(snapshotVdi);
+
+            for (final VDI snapChain : snapshotChains) {
+                final Task task = snapChain.copyAsync(conn, null, null, destVdi);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                task.destroy(conn);
+            }
+
+            result = true;
+            destVdi = VDI.getByUuid(conn, volumeUUID);
+            final VDI.Record vdir = destVdi.getRecord(conn);
+            final VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setPath(volumeUUID);
+            newVol.setSize(vdir.virtualSize);
+
+            return new CopyCmdAnswer(newVol);
+        } catch (final Types.XenAPIException e) {
+            details += " due to " + e.toString();
+            s_logger.warn(details, e);
+        } catch (final Exception e) {
+            details += " due to " + e.getMessage();
+            s_logger.warn(details, e);
+        } finally {
+            if (srcSr != null) {
+                hypervisorResource.skipOrRemoveSR(conn, srcSr);
+            }
+
+            if (pool.isManaged()) {
+                hypervisorResource.removeSR(conn, primaryStorageSR);
+            }
+
+            if (!result && destVdi != null) {
+                try {
+                    destVdi.destroy(conn);
+                } catch (final Exception e) {
+                    s_logger.debug("destroy dest vdi failed", e);
+                }
+            }
+        }
+        if (!result) {
+            // Is this logged at a higher level?
+            s_logger.error(details);
+        }
+
+        // In all cases return something.
+        return new CopyCmdAnswer(details);
+    }
+
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
+        final VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final DataStoreTO destStore = destVolume.getDataStore();
+
+        if (destStore instanceof NfsTO) {
+            SR secondaryStorage = null;
+            Task task = null;
+            try {
+                final NfsTO nfsStore = (NfsTO)destStore;
+                final URI uri = new URI(nfsStore.getUrl());
+                // Create the volume folder
+                if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) {
+                    throw new InternalErrorException("Failed to create the volume folder.");
+                }
+
+                // Create a SR for the volume UUID folder
+                secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath());
+                // Look up the volume on the source primary storage pool
+                final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath());
+                // Copy the volume to secondary storage
+                task = srcVdi.copyAsync(conn, secondaryStorage, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                final VDI destVdi = Types.toVDI(task, conn);
+                final String destVolumeUUID = destVdi.getUuid(conn);
+
+                final VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(destVolume.getPath() + File.separator + destVolumeUUID + ".vhd");
+                newVol.setSize(srcVolume.getSize());
+                return new CopyCmdAnswer(newVol);
+            } catch (final Exception e) {
+                s_logger.debug("Failed to copy volume to secondary: " + e.toString());
+                return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString());
+            } finally {
+                if (task != null) {
+                    try {
+                        task.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
+                    }
+                }
+                hypervisorResource.removeSR(conn, secondaryStorage);
+            }
+        }
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        final int wait = cmd.getWait();
+        final VolumeObjectTO srcVolume = (VolumeObjectTO)srcData;
+        final VolumeObjectTO destVolume = (VolumeObjectTO)destData;
+        final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destVolume.getDataStore();
+        final DataStoreTO srcStore = srcVolume.getDataStore();
+
+        if (srcStore instanceof NfsTO) {
+            final NfsTO nfsStore = (NfsTO)srcStore;
+            final String volumePath = srcVolume.getPath();
+            int index = volumePath.lastIndexOf("/");
+            final String volumeDirectory = volumePath.substring(0, index);
+            String volumeUuid = volumePath.substring(index + 1);
+            index = volumeUuid.indexOf(".");
+            if (index != -1) {
+                volumeUuid = volumeUuid.substring(0, index);
+            }
+            URI uri = null;
+            try {
+                uri = new URI(nfsStore.getUrl());
+            } catch (final Exception e) {
+                return new CopyCmdAnswer(e.toString());
+            }
+            final SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory);
+            Task task = null;
+            try {
+                final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid());
+                final VDI srcVdi = VDI.getByUuid(conn, volumeUuid);
+                task = srcVdi.copyAsync(conn, primaryStoragePool, null, null);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+                final VDI destVdi = Types.toVDI(task, conn);
+                final VolumeObjectTO newVol = new VolumeObjectTO();
+                destVdi.setNameLabel(conn, srcVolume.getName());
+                newVol.setPath(destVdi.getUuid(conn));
+                newVol.setSize(srcVolume.getSize());
+
+                return new CopyCmdAnswer(newVol);
+            } catch (final Exception e) {
+                final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
+                s_logger.warn(msg, e);
+                return new CopyCmdAnswer(e.toString());
+            } finally {
+                if (task != null) {
+                    try {
+                        task.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.warn("unable to destroy task(" + task.toString() + ") due to " + e.toString());
+                    }
+                }
+                if (srcSr != null) {
+                    hypervisorResource.removeSR(conn, srcSr);
+                }
+            }
+        }
+
+        s_logger.debug("unsupported protocol");
+        return new CopyCmdAnswer("unsupported protocol");
+    }
+
+    @Override
+    public Answer createTemplateFromSnapshot(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+
+        if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof NfsTO) {
+            return createTemplateFromSnapshot2(cmd);
+        }
+
+        final int wait = cmd.getWait();
+
+        final SnapshotObjectTO srcObj = (SnapshotObjectTO)srcData;
+        final TemplateObjectTO destObj = (TemplateObjectTO)destData;
+
+        final NfsTO srcStore = (NfsTO)srcObj.getDataStore();
+        final NfsTO destStore = (NfsTO)destObj.getDataStore();
+
+        URI srcUri = null;
+        URI destUri = null;
+
+        try {
+            srcUri = new URI(srcStore.getUrl());
+            destUri = new URI(destStore.getUrl());
+        } catch (final Exception e) {
+            s_logger.debug("incorrect url", e);
+
+            return new CopyCmdAnswer("incorrect url" + e.toString());
+        }
+
+        final String srcPath = srcObj.getPath();
+        final int index = srcPath.lastIndexOf("/");
+        final String srcDir = srcPath.substring(0, index);
+        final String destDir = destObj.getPath();
+
+        SR srcSr = null;
+        SR destSr = null;
+
+        VDI destVdi = null;
+
+        boolean result = false;
+
+        try {
+            srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir);
+
+            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
+            final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
+
+            mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir);
+            makeDirectory(conn, localDir + "/" + destDir);
+
+            destSr = createFileSR(conn, localDir + "/" + destDir);
+
+            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
+
+            final String[] parents = srcObj.getParents();
+            final List<VDI> snapshotChains = new ArrayList<VDI>();
+
+            if (parents != null) {
+                for (int i = 0; i < parents.length; i++) {
+                    final String snChainPath = parents[i];
+                    final String uuid = getSnapshotUuid(snChainPath);
+                    final VDI chain = VDI.getByUuid(conn, uuid);
+
+                    snapshotChains.add(chain);
+                }
+            }
+
+            final String snapshotUuid = getSnapshotUuid(srcPath);
+            final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid);
+
+            snapshotChains.add(snapshotVdi);
+
+            final long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn);
+
+            destVdi = createVdi(conn, nameLabel, destSr, templateVirtualSize);
+
+            final String destVdiUuid = destVdi.getUuid(conn);
+
+            for (final VDI snapChain : snapshotChains) {
+                final Task task = snapChain.copyAsync(conn, null, null, destVdi);
+                // poll every 1 seconds ,
+                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
+                hypervisorResource.checkForSuccess(conn, task);
+
+                task.destroy(conn);
+            }
+
+            destVdi = VDI.getByUuid(conn, destVdiUuid);
+
+            // scan makes XenServer pick up VDI physicalSize
+            destSr.scan(conn);
+
+            final String templateUuid = destVdi.getUuid(conn);
+            final String templateFilename = templateUuid + ".vhd";
+            final long virtualSize = destVdi.getVirtualSize(conn);
+            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
+
+            String templatePath = destNfsPath + "/" + destDir;
+
+            templatePath = templatePath.replaceAll("//", "/");
+
+            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId());
+
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
+            }
+
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(destDir + "/" + templateFilename);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setSize(destVdi.getVirtualSize(conn));
+            newTemplate.setPhysicalSize(destVdi.getPhysicalUtilisation(conn));
+            newTemplate.setName(destVdiUuid);
+
+            result = true;
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (final Exception e) {
+            s_logger.error("Failed create template from snapshot", e);
+
+            return new CopyCmdAnswer("Failed create template from snapshot " + e.toString());
+        } finally {
+            if (!result) {
+                if (destVdi != null) {
+                    try {
+                        destVdi.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.debug("Clean up left over on dest storage failed: ", e);
+                    }
+                }
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+
+            if (destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+        }
+    }
+
+    private Answer createTemplateFromSnapshot2(final CopyCommand cmd) {
+        final Connection conn = hypervisorResource.getConnection();
+
+        final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO();
+        final TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO();
+
+        if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) {
+            return null;
+        }
+
+        NfsTO destStore;
+        URI destUri;
+
+        try {
+            destStore = (NfsTO)templateObjTO.getDataStore();
+            destUri = new URI(destStore.getUrl());
+        } catch (final Exception ex) {
+            s_logger.debug("Invalid URI", ex);
+
+            return new CopyCmdAnswer("Invalid URI: " + ex.toString());
+        }
+
+        SR srcSr = null;
+        SR destSr = null;
+
+        final String destDir = templateObjTO.getPath();
+        VDI destVdi = null;
+
+        boolean result = false;
+
+        try {
+            final Map<String, String> srcDetails = cmd.getOptions();
+
+            final String iScsiName = srcDetails.get(DiskTO.IQN);
+            final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
+            final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+            final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+            String srType;
+
+            srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
+
+            srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
+
+            final String destNfsPath = destUri.getHost() + ":" + destUri.getPath();
+            final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes());
+
+            mountNfs(conn, destNfsPath, localDir);
+            makeDirectory(conn, localDir + "/" + destDir);
+
+            destSr = createFileSR(conn, localDir + "/" + destDir);
+
+            // there should only be one VDI in this SR
+            final VDI srcVdi = srcSr.getVDIs(conn).iterator().next();
+
+            destVdi = srcVdi.copy(conn, destSr);
+
+            final String nameLabel = "cloud-" + UUID.randomUUID().toString();
+
+            destVdi.setNameLabel(conn, nameLabel);
+
+            // scan makes XenServer pick up VDI physicalSize
+            destSr.scan(conn);
+
+            final String templateUuid = destVdi.getUuid(conn);
+            final String templateFilename = templateUuid + ".vhd";
+            final long virtualSize = destVdi.getVirtualSize(conn);
+            final long physicalSize = destVdi.getPhysicalUtilisation(conn);
+
+            // create the template.properties file
+            String templatePath = destNfsPath + "/" + destDir;
+
+            templatePath = templatePath.replaceAll("//", "/");
+
+            result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, templateObjTO.getId());
+
+            if (!result) {
+                throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir");
+            }
+
+            final TemplateObjectTO newTemplate = new TemplateObjectTO();
+
+            newTemplate.setPath(destDir + "/" + templateFilename);
+            newTemplate.setFormat(Storage.ImageFormat.VHD);
+            newTemplate.setHypervisorType(HypervisorType.XenServer);
+            newTemplate.setSize(virtualSize);
+            newTemplate.setPhysicalSize(physicalSize);
+            newTemplate.setName(templateUuid);
+
+            result = true;
+
+            return new CopyCmdAnswer(newTemplate);
+        } catch (final BadServerResponse e) {
+            s_logger.error("Failed to create a template from a snapshot due to incomprehensible server response", e);
+
+            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
+        } catch (final XenAPIException e) {
+            s_logger.error("Failed to create a template from a snapshot due to xenapi error", e);
+
+            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
+        } catch (final XmlRpcException e) {
+            s_logger.error("Failed to create a template from a snapshot due to rpc error", e);
+
+            return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString());
+        } finally {
+            if (!result) {
+                if (destVdi != null) {
+                    try {
+                        destVdi.destroy(conn);
+                    } catch (final Exception e) {
+                        s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e);
+                    }
+                }
+            }
+
+            if (srcSr != null) {
+                hypervisorResource.removeSR(conn, srcSr);
+            }
+
+            if (destSr != null) {
+                hypervisorResource.removeSR(conn, destSr);
+            }
+        }
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XsHost.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XsHost.java
new file mode 100644
index 0000000..dcc5ff2
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XsHost.java
@@ -0,0 +1,203 @@
+// 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.xenserver.resource;
+
+import com.xensource.xenapi.Network;
+
+/**
+ * A list of UUIDs that are gathered from the XenServer when the resource first
+ * connects to XenServer. These UUIDs do not change over time.
+ */
+public class XsHost {
+
+    private String systemvmisouuid;
+    private String uuid;
+    private String ip;
+    private String publicNetwork;
+    private String privateNetwork;
+    private String linkLocalNetwork;
+    private Network vswitchNetwork;
+    private String storageNetwork1;
+    private String guestNetwork;
+    private String guestPif;
+    private String publicPif;
+    private String privatePif;
+    private String storagePif1;
+    private String storagePif2;
+    private String pool;
+    private int speed;
+    private Integer cpuSockets;
+    private int cpus;
+    private String productVersion;
+
+    public String getSystemvmisouuid() {
+        return systemvmisouuid;
+    }
+
+    public void setSystemvmisouuid(final String systemvmisouuid) {
+        this.systemvmisouuid = systemvmisouuid;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(final String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(final String ip) {
+        this.ip = ip;
+    }
+
+    public String getPublicNetwork() {
+        return publicNetwork;
+    }
+
+    public void setPublicNetwork(final String publicNetwork) {
+        this.publicNetwork = publicNetwork;
+    }
+
+    public String getPrivateNetwork() {
+        return privateNetwork;
+    }
+
+    public void setPrivateNetwork(final String privateNetwork) {
+        this.privateNetwork = privateNetwork;
+    }
+
+    public String getLinkLocalNetwork() {
+        return linkLocalNetwork;
+    }
+
+    public void setLinkLocalNetwork(final String linkLocalNetwork) {
+        this.linkLocalNetwork = linkLocalNetwork;
+    }
+
+    public Network getVswitchNetwork() {
+        return vswitchNetwork;
+    }
+
+    public void setVswitchNetwork(final Network vswitchNetwork) {
+        this.vswitchNetwork = vswitchNetwork;
+    }
+
+    public String getStorageNetwork1() {
+        return storageNetwork1;
+    }
+
+    public void setStorageNetwork1(final String storageNetwork1) {
+        this.storageNetwork1 = storageNetwork1;
+    }
+
+    public String getGuestNetwork() {
+        return guestNetwork;
+    }
+
+    public void setGuestNetwork(final String guestNetwork) {
+        this.guestNetwork = guestNetwork;
+    }
+
+    public String getGuestPif() {
+        return guestPif;
+    }
+
+    public void setGuestPif(final String guestPif) {
+        this.guestPif = guestPif;
+    }
+
+    public String getPublicPif() {
+        return publicPif;
+    }
+
+    public void setPublicPif(final String publicPif) {
+        this.publicPif = publicPif;
+    }
+
+    public String getPrivatePif() {
+        return privatePif;
+    }
+
+    public void setPrivatePif(final String privatePif) {
+        this.privatePif = privatePif;
+    }
+
+    public String getStoragePif1() {
+        return storagePif1;
+    }
+
+    public void setStoragePif1(final String storagePif1) {
+        this.storagePif1 = storagePif1;
+    }
+
+    public String getStoragePif2() {
+        return storagePif2;
+    }
+
+    public void setStoragePif2(final String storagePif2) {
+        this.storagePif2 = storagePif2;
+    }
+
+    public String getPool() {
+        return pool;
+    }
+
+    public void setPool(final String pool) {
+        this.pool = pool;
+    }
+
+    public int getSpeed() {
+        return speed;
+    }
+
+    public void setSpeed(final int speed) {
+        this.speed = speed;
+    }
+
+    public Integer getCpuSockets() {
+        return cpuSockets;
+    }
+
+    public void setCpuSockets(final Integer cpuSockets) {
+        this.cpuSockets = cpuSockets;
+    }
+
+    public int getCpus() {
+        return cpus;
+    }
+
+    public void setCpus(final int cpus) {
+        this.cpus = cpus;
+    }
+
+    public String getProductVersion() {
+        return productVersion;
+    }
+
+    public void setProductVersion(final String productVersion) {
+        this.productVersion = productVersion;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("XS[").append(uuid).append("-").append(ip).append("]").toString();
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xcp/XcpServerNetworkUsageCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xcp/XcpServerNetworkUsageCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xcp/XcpServerNetworkUsageCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xcp/XcpServerNetworkUsageCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56CheckOnHostCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56CheckOnHostCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56CheckOnHostCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56CheckOnHostCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56FenceCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56FenceCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56FenceCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56FenceCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56NetworkUsageCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56NetworkUsageCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56NetworkUsageCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56/XenServer56NetworkUsageCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56p1/XenServer56FP1FenceCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56p1/XenServer56FP1FenceCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen56p1/XenServer56FP1FenceCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen56p1/XenServer56FP1FenceCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java
new file mode 100644
index 0000000..896df6a
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateVolumeCommandWrapper.java
@@ -0,0 +1,98 @@
+//
+// 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.xenserver.resource.wrapper.xen610;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeCommand;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.hypervisor.xenserver.resource.XenServer610Resource;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Task;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.VDI;
+
+@ResourceWrapper(handles =  MigrateVolumeCommand.class)
+public final class XenServer610MigrateVolumeCommandWrapper extends CommandWrapper<MigrateVolumeCommand, Answer, XenServer610Resource> {
+    private static final Logger LOGGER = Logger.getLogger(XenServer610MigrateVolumeCommandWrapper.class);
+
+    @Override
+    public Answer execute(final MigrateVolumeCommand command, final XenServer610Resource xenServer610Resource) {
+        Connection connection = xenServer610Resource.getConnection();
+        String srcVolumeUuid = command.getVolumePath();
+        SR destPool = null;
+        Map<String, String> destDetails = command.getDestDetails();
+
+        try {
+            VDI srcVolume = xenServer610Resource.getVDIbyUuid(connection, srcVolumeUuid);
+
+            if (destDetails != null && Boolean.parseBoolean(destDetails.get(DiskTO.MANAGED))) {
+                String iScsiName = destDetails.get(DiskTO.IQN);
+                String storageHost = destDetails.get(DiskTO.STORAGE_HOST);
+                String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
+                String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
+
+                destPool = xenServer610Resource.getIscsiSR(connection, iScsiName, storageHost, iScsiName,
+                        chapInitiatorUsername, chapInitiatorSecret, false);
+            }
+            else {
+                StorageFilerTO destPoolTO = command.getPool();
+                String destPoolUuid = destPoolTO.getUuid();
+
+                destPool = xenServer610Resource.getStorageRepository(connection, destPoolUuid);
+            }
+
+            Map<String, String> other = new HashMap<>();
+
+            other.put("live", "true");
+
+            // Live migrate the VDI.
+            Task task = srcVolume.poolMigrateAsync(connection, destPool, other);
+
+            long timeout = xenServer610Resource.getMigrateWait() * 1000L;
+
+            xenServer610Resource.waitForTask(connection, task, 1000, timeout);
+            xenServer610Resource.checkForSuccess(connection, task);
+
+            VDI destVdi = Types.toVDI(task, connection);
+
+            return new MigrateVolumeAnswer(command, true, null, destVdi.getUuid(connection));
+        } catch (Exception ex) {
+            if (destDetails != null && Boolean.parseBoolean(destDetails.get(DiskTO.MANAGED)) && destPool != null) {
+                xenServer610Resource.removeSR(connection, destPool);
+            }
+
+            String msg = "Caught exception " + ex.getClass().getName() + " due to the following: " + ex.toString();
+
+            LOGGER.error(msg, ex);
+
+            return new MigrateVolumeAnswer(command, false, msg, null);
+        }
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCompleteCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCompleteCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCompleteCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCompleteCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageReceiveCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageReceiveCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageReceiveCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageReceiveCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageSendCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageSendCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageSendCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageSendCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen620sp1/XenServer620SP1GetGPUStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen620sp1/XenServer620SP1GetGPUStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen620sp1/XenServer620SP1GetGPUStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xen620sp1/XenServer620SP1GetGPUStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachIsoCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachIsoCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachIsoCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachIsoCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckHealthCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckHealthCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckHealthCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckHealthCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckNetworkCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckNetworkCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckNetworkCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckNetworkCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckOnHostCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckOnHostCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckOnHostCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckOnHostCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckVirtualMachineCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckVirtualMachineCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckVirtualMachineCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckVirtualMachineCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupNetworkRulesCmdWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupNetworkRulesCmdWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupNetworkRulesCmdWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCleanupNetworkRulesCmdWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixClusterVMMetaDataSyncCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixClusterVMMetaDataSyncCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixClusterVMMetaDataSyncCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixClusterVMMetaDataSyncCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateStoragePoolCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCreateVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteStoragePoolCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDeleteVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDestroyCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDestroyCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDestroyCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixDestroyCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHostStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHostStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHostStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetHostStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetStorageStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetStorageStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetStorageStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetStorageStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVncPortCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVncPortCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVncPortCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVncPortCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVolumeStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVolumeStatsCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVolumeStatsCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVolumeStatsCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMaintainCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMaintainCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMaintainCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMaintainCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java
new file mode 100644
index 0000000..12d19c8
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java
@@ -0,0 +1,119 @@
+//
+// 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.xenserver.resource.wrapper.xenbase;
+
+import java.util.Set;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VM;
+
+@ResourceWrapper(handles =  MigrateCommand.class)
+public class CitrixMigrateCommandWrapper extends CommandWrapper<MigrateCommand, Answer, CitrixResourceBase> {
+
+    private static final Logger s_logger = Logger.getLogger(CitrixMigrateCommandWrapper.class);
+
+    @Override
+    public Answer execute(final MigrateCommand command, final CitrixResourceBase citrixResourceBase) {
+        final Connection conn = citrixResourceBase.getConnection();
+        final String vmName = command.getVmName();
+        final String dstHostIpAddr = command.getDestinationIp();
+
+        try {
+            final Set<VM> vms = VM.getByNameLabel(conn, vmName);
+
+            final Set<Host> hosts = Host.getAll(conn);
+            Host dsthost = null;
+            if(hosts != null) {
+                for (final Host host : hosts) {
+                    if (host.getAddress(conn).equals(dstHostIpAddr)) {
+                        dsthost = host;
+                        break;
+                    }
+                }
+            }
+            if (dsthost == null) {
+                final String msg = "Migration failed due to unable to find host " + dstHostIpAddr + " in XenServer pool " + citrixResourceBase.getHost().getPool();
+                s_logger.warn(msg);
+                return new MigrateAnswer(command, false, msg, null);
+            }
+            for (final VM vm : vms) {
+                final Set<VBD> vbds = vm.getVBDs(conn);
+                for (final VBD vbd : vbds) {
+                    final VBD.Record vbdRec = vbd.getRecord(conn);
+                    if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) {
+                        vbd.eject(conn);
+                        // for config drive vbd destroy the vbd.
+                        if (!vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) {
+                            if (vbdRec.currentlyAttached) {
+                                vbd.destroy(conn);
+                            }
+                        }
+                        continue;
+                    }
+                }
+                citrixResourceBase.migrateVM(conn, dsthost, vm, vmName);
+                vm.setAffinity(conn, dsthost);
+
+                destroyMigratedVmNetworkRulesOnSourceHost(command, citrixResourceBase, conn, dsthost);
+            }
+
+            // The iso can be attached to vm only once the vm is (present in the host) migrated.
+            // Attach the config drive iso device to VM
+            if (!citrixResourceBase.attachConfigDriveToMigratedVm(conn, vmName, dstHostIpAddr)) {
+                s_logger.debug("Config drive ISO attach failed after migration for vm "+vmName);
+            }
+
+            return new MigrateAnswer(command, true, "migration succeeded", null);
+        } catch (final Exception e) {
+            s_logger.warn(e.getMessage(), e);
+            return new MigrateAnswer(command, false, e.getMessage(), null);
+        }
+    }
+
+    /**
+     * On networks with security group, it removes the network rules related to the migrated VM from the source host.
+     */
+    protected void destroyMigratedVmNetworkRulesOnSourceHost(final MigrateCommand command, final CitrixResourceBase citrixResourceBase, final Connection conn, Host dsthost)
+            throws BadServerResponse, XenAPIException, XmlRpcException {
+        if (citrixResourceBase.canBridgeFirewall()) {
+            final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", command.getVmName());
+            if (BooleanUtils.toBoolean(result)) {
+                s_logger.debug(String.format("Removed network rules from source host [%s] for migrated vm [%s]", dsthost.getHostname(conn), command.getVmName()));
+            } else {
+                s_logger.warn(String.format("Failed to remove network rules from source host [%s] for migrated vm [%s]", dsthost.getHostname(conn), command.getVmName()));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifySshKeysCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifySshKeysCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifySshKeysCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifySshKeysCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifyStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifyStoragePoolCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifyStoragePoolCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixModifyStoragePoolCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkElementCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkElementCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkElementCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkElementCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesSystemVmCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesSystemVmCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesSystemVmCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesSystemVmCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateGreTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateGreTunnelCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateGreTunnelCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateGreTunnelCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateTunnelCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateTunnelCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsCreateTunnelCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDeleteFlowCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDeleteFlowCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDeleteFlowCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDeleteFlowCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyBridgeCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyBridgeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyBridgeCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyBridgeCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyTunnelCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyTunnelCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsDestroyTunnelCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsFetchInterfaceCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsFetchInterfaceCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsFetchInterfaceCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsFetchInterfaceCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetTagAndFlowCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetTagAndFlowCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetTagAndFlowCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetTagAndFlowCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetupBridgeCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetupBridgeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetupBridgeCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsSetupBridgeCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPerformanceMonitorCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPerformanceMonitorCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPerformanceMonitorCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPerformanceMonitorCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPingTestCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPingTestCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPingTestCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPingTestCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPlugNicCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPlugNicCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPlugNicCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPlugNicCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrimaryStorageDownloadCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrimaryStorageDownloadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrimaryStorageDownloadCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrimaryStorageDownloadCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPvlanSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPvlanSetupCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPvlanSetupCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPvlanSetupCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootRouterCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootRouterCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootRouterCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRebootRouterCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixResizeVolumeCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixResizeVolumeCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixResizeVolumeCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixResizeVolumeCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRevertToVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRevertToVMSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRevertToVMSnapshotCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRevertToVMSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixScaleVmCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixScaleVmCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixScaleVmCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixScaleVmCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSecurityGroupRulesCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSecurityGroupRulesCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSecurityGroupRulesCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSecurityGroupRulesCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStopCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStopCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStopCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStopCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStorageSubSystemCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStorageSubSystemCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStorageSubSystemCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStorageSubSystemCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUnPlugNicCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUnPlugNicCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUnPlugNicCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUnPlugNicCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpdateHostPasswordCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpdateHostPasswordCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpdateHostPasswordCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpdateHostPasswordCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpgradeSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpgradeSnapshotCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpgradeSnapshotCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixUpgradeSnapshotCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixWatchConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixWatchConsoleProxyLoadCommandWrapper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixWatchConsoleProxyLoadCommandWrapper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixWatchConsoleProxyLoadCommandWrapper.java
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServerUtilitiesHelper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServerUtilitiesHelper.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServerUtilitiesHelper.java
rename to plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServerUtilitiesHelper.java
diff --git a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java b/plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
rename to plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java
diff --git a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenserverConfigs.java b/plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/hypervisor/xenserver/XenserverConfigs.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenserverConfigs.java
rename to plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/hypervisor/xenserver/XenserverConfigs.java
diff --git a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java
similarity index 100%
rename from plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java
rename to plugins/hypervisors/xenserver/src/main/java/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java
diff --git a/plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-compute/module.properties b/plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-compute/module.properties
similarity index 100%
rename from plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-compute/module.properties
rename to plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-compute/module.properties
diff --git a/plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml b/plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml
similarity index 100%
rename from plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml
rename to plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-compute/spring-xenserver-compute-context.xml
diff --git a/plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-discoverer/module.properties b/plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-discoverer/module.properties
similarity index 100%
rename from plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-discoverer/module.properties
rename to plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-discoverer/module.properties
diff --git a/plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml b/plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml
similarity index 100%
rename from plugins/hypervisors/xenserver/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml
rename to plugins/hypervisors/xenserver/src/main/resources/META-INF/cloudstack/xenserver-discoverer/spring-xenserver-discoverer-context.xml
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/XenServerGuruTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/XenServerGuruTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/XenServerGuruTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/XenServerGuruTest.java
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java
new file mode 100644
index 0000000..a3082c6
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java
@@ -0,0 +1,72 @@
+// 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.xenserver.discoverer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class XcpServerDiscovererTest {
+
+    @Spy
+    @InjectMocks
+    private XcpServerDiscoverer xcpServerDiscoverer;
+
+    @Mock
+    private VMTemplateDao vmTemplateDao;
+
+    @Test
+    public void createXenServerToolsIsoEntryInDatabaseTestNoEntryFound() {
+        Mockito.when(vmTemplateDao.findByTemplateName("xs-tools.iso")).thenReturn(null);
+        Mockito.when(vmTemplateDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
+
+        xcpServerDiscoverer.createXenServerToolsIsoEntryInDatabase();
+
+        InOrder inOrder = Mockito.inOrder(vmTemplateDao);
+        inOrder.verify(vmTemplateDao).findByTemplateName("xs-tools.iso");
+        inOrder.verify(vmTemplateDao).getNextInSequence(Long.class, "id");
+        inOrder.verify(vmTemplateDao).persist(Mockito.any(VMTemplateVO.class));
+    }
+
+    @Test
+    public void createXenServerToolsIsoEntryInDatabaseTestEntryAlreadyExist() {
+        VMTemplateVO vmTemplateVOMock = Mockito.mock(VMTemplateVO.class);
+        Mockito.when(vmTemplateDao.findByTemplateName("xs-tools.iso")).thenReturn(vmTemplateVOMock);
+        Mockito.when(vmTemplateVOMock.getId()).thenReturn(1L);
+
+        xcpServerDiscoverer.createXenServerToolsIsoEntryInDatabase();
+
+        InOrder inOrder = Mockito.inOrder(vmTemplateDao, vmTemplateVOMock);
+        inOrder.verify(vmTemplateDao).findByTemplateName("xs-tools.iso");
+        inOrder.verify(vmTemplateDao, Mockito.times(0)).getNextInSequence(Long.class, "id");
+        inOrder.verify(vmTemplateVOMock).setTemplateType(TemplateType.PERHOST);
+        inOrder.verify(vmTemplateVOMock).setUrl(null);
+        inOrder.verify(vmTemplateVOMock).setDisplayText("XenServer Tools Installer ISO (xen-pv-drv-iso)");
+        inOrder.verify(vmTemplateDao).update(1L, vmTemplateVOMock);
+    }
+}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java
new file mode 100644
index 0000000..b34bba0
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.BDDMockito;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.StorageResourceType;
+import com.cloud.utils.script.Script;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Host.Record;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types.XenAPIException;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Host.class, Script.class, SR.class})
+public class CitrixResourceBaseTest {
+
+    @Spy
+    protected CitrixResourceBase citrixResourceBase = new CitrixResourceBase() {
+        @Override
+        protected String getPatchFilePath() {
+            return null;
+        }
+    };
+
+    @Mock
+    private Connection connectionMock;
+    @Mock
+    private Host hostMock;
+    @Mock
+    private Record hostRecordMock;
+
+    private String hostUuidMock = "hostUuidMock";
+
+    @Before
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        citrixResourceBase._host.setUuid(hostUuidMock);
+
+        PowerMockito.mockStatic(Host.class);
+        PowerMockito.when(Host.getByUuid(connectionMock, hostUuidMock)).thenReturn(hostMock);
+
+        hostRecordMock.softwareVersion = new HashMap<>();
+        Mockito.when(hostMock.getRecord(connectionMock)).thenReturn(hostRecordMock);
+
+    }
+
+    public void testGetPathFilesExeption() {
+        String patch = citrixResourceBase.getPatchFilePath();
+
+        PowerMockito.mockStatic(Script.class);
+        Mockito.when(Script.findScript("", patch)).thenReturn(null);
+
+        citrixResourceBase.getPatchFiles();
+
+    }
+
+    public void testGetPathFilesListReturned() {
+        String patch = citrixResourceBase.getPatchFilePath();
+
+        PowerMockito.mockStatic(Script.class);
+        Mockito.when(Script.findScript("", patch)).thenReturn(patch);
+
+        File expected = new File(patch);
+        String pathExpected = expected.getAbsolutePath();
+
+        List<File> files = citrixResourceBase.getPatchFiles();
+        String receivedPath = files.get(0).getAbsolutePath();
+        Assert.assertEquals(receivedPath, pathExpected);
+    }
+
+    @Test
+    public void testGetGuestOsTypeNull() {
+        String platformEmulator = null;
+
+        String expected = "Other install media";
+        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
+        Assert.assertEquals(expected, guestOsType);
+    }
+
+    @Test
+    public void testGetGuestOsTypeEmpty() {
+        String platformEmulator = "";
+
+        String expected = "Other install media";
+        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
+        Assert.assertEquals(expected, guestOsType);
+    }
+
+    @Test
+    public void testGetGuestOsTypeBlank() {
+        String platformEmulator = "    ";
+
+        String expected = "Other install media";
+        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
+        Assert.assertEquals(expected, guestOsType);
+    }
+
+    @Test
+    public void testGetGuestOsTypeOther() {
+        String platformEmulator = "My Own Linux Distribution Y.M (64-bit)";
+
+        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
+        Assert.assertEquals(platformEmulator, guestOsType);
+    }
+
+    @Test
+    public void actualIsoTemplateTestXcpHots() throws XenAPIException, XmlRpcException {
+        hostRecordMock.softwareVersion.put("product_brand", "XCP");
+        hostRecordMock.softwareVersion.put("product_version", "1.0");
+
+        String returnedIsoTemplateName = citrixResourceBase.getActualIsoTemplate(connectionMock);
+
+        Assert.assertEquals("xs-tools.iso", returnedIsoTemplateName);
+    }
+
+    @Test
+    public void actualIsoTemplateTestXenServerBefore70() throws XenAPIException, XmlRpcException {
+        hostRecordMock.softwareVersion.put("product_brand", "XenServer");
+        hostRecordMock.softwareVersion.put("product_version", "6.0");
+
+        String returnedIsoTemplateName = citrixResourceBase.getActualIsoTemplate(connectionMock);
+
+        Assert.assertEquals("xs-tools.iso", returnedIsoTemplateName);
+    }
+
+    @Test
+    public void actualIsoTemplateTestXenServer70() throws XenAPIException, XmlRpcException {
+        hostRecordMock.softwareVersion.put("product_brand", "XenServer");
+        hostRecordMock.softwareVersion.put("product_version", "7.0");
+
+        String returnedIsoTemplateName = citrixResourceBase.getActualIsoTemplate(connectionMock);
+
+        Assert.assertEquals("guest-tools.iso", returnedIsoTemplateName);
+    }
+
+    @Test
+    public void actualIsoTemplateTestXenServer71() throws XenAPIException, XmlRpcException {
+        hostRecordMock.softwareVersion.put("product_brand", "XenServer");
+        hostRecordMock.softwareVersion.put("product_version", "7.1");
+
+        String returnedIsoTemplateName = citrixResourceBase.getActualIsoTemplate(connectionMock);
+
+        Assert.assertEquals("guest-tools.iso", returnedIsoTemplateName);
+    }
+
+    @Test
+    public void getAllLocalSrForTypeTest() throws Exception {
+        String mockHostUuid = "hostUuid";
+        citrixResourceBase._host.setUuid(mockHostUuid);
+
+        Connection connectionMock = Mockito.mock(Connection.class);
+
+        SR srExtShared = Mockito.mock(SR.class);
+        SR srExtNonShared = Mockito.mock(SR.class);
+
+        List<SR> expectedListOfSrs = new ArrayList<>();
+        expectedListOfSrs.add(srExtNonShared);
+
+        Set<PBD> pbds = new HashSet<>();
+        PBD pbdMock = Mockito.mock(PBD.class);
+        Host hostMock = Mockito.mock(Host.class);
+        Mockito.when(hostMock.getUuid(connectionMock)).thenReturn(mockHostUuid);
+        Mockito.when(hostMock.toWireString()).thenReturn(mockHostUuid);
+
+        Mockito.when(pbdMock.getHost(connectionMock)).thenReturn(hostMock);
+        pbds.add(pbdMock);
+
+        SR.Record srExtSharedRecord = Mockito.mock(SR.Record.class);
+        srExtSharedRecord.type = "EXT";
+        srExtSharedRecord.shared = true;
+        srExtSharedRecord.PBDs = pbds;
+
+        SR.Record srExtNonSharedRecord = Mockito.mock(SR.Record.class);
+        srExtNonSharedRecord.type = "EXT";
+        srExtNonSharedRecord.shared = false;
+        srExtNonSharedRecord.PBDs = pbds;
+
+        Map<SR, SR.Record> mapOfSrsRecords = new HashMap<>();
+        mapOfSrsRecords.put(srExtShared, srExtSharedRecord);
+        mapOfSrsRecords.put(srExtNonShared, srExtNonSharedRecord);
+
+        PowerMockito.mockStatic(SR.class);
+        BDDMockito.given(SR.getAllRecords(connectionMock)).willReturn(mapOfSrsRecords);
+
+        List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
+
+        Assert.assertEquals(expectedListOfSrs.size(), allLocalSrForType.size());
+        Assert.assertEquals(expectedListOfSrs.get(0), allLocalSrForType.get(0));
+    }
+
+    @Test
+    public void getAllLocalSrForTypeNoSrsFoundTest() throws XenAPIException, XmlRpcException {
+        Connection connectionMock = Mockito.mock(Connection.class);
+        List<SR> allLocalSrForType = citrixResourceBase.getAllLocalSrForType(connectionMock, SRType.EXT);
+        Assert.assertTrue(allLocalSrForType.isEmpty());
+    }
+
+    @Test
+    public void getAllLocalSrsTest() throws XenAPIException, XmlRpcException {
+        Connection connectionMock = Mockito.mock(Connection.class);
+        SR sr1 = Mockito.mock(SR.class);
+        List<SR> srsExt = new ArrayList<>();
+        srsExt.add(sr1);
+
+        SR sr2 = Mockito.mock(SR.class);
+        List<SR> srsLvm = new ArrayList<>();
+        srsLvm.add(sr2);
+
+        Mockito.doReturn(srsExt).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
+        Mockito.doReturn(srsLvm).when(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
+
+        List<SR> allLocalSrs = citrixResourceBase.getAllLocalSrs(connectionMock);
+
+        Assert.assertEquals(srsExt.size() + srsLvm.size(), allLocalSrs.size());
+        Assert.assertEquals(srsExt.get(0), allLocalSrs.get(1));
+        Assert.assertEquals(srsLvm.get(0), allLocalSrs.get(0));
+
+        InOrder inOrder = Mockito.inOrder(citrixResourceBase);
+        inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.LVM);
+        inOrder.verify(citrixResourceBase).getAllLocalSrForType(connectionMock, SRType.EXT);
+    }
+
+    @Test
+    public void createStoragePoolInfoTest() throws XenAPIException, XmlRpcException {
+        Connection connectionMock = Mockito.mock(Connection.class);
+        Host hostMock = Mockito.mock(Host.class);
+        SR srMock = Mockito.mock(SR.class);
+
+        String hostAddress = "hostAddress";
+        Mockito.when(hostMock.getAddress(connectionMock)).thenReturn(hostAddress);
+
+        String hostUuid = "hostUuid";
+        citrixResourceBase._host.setUuid(hostUuid);
+
+        PowerMockito.mockStatic(Host.class);
+        PowerMockito.when(Host.getByUuid(connectionMock, hostUuid)).thenReturn(hostMock);
+
+        String srType = "ext";
+        String srUuid = "srUuid";
+        long srPhysicalSize = 100l;
+        long physicalUtilization = 10l;
+
+        Mockito.when(srMock.getPhysicalSize(connectionMock)).thenReturn(srPhysicalSize);
+        Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
+        Mockito.when(srMock.getPhysicalUtilisation(connectionMock)).thenReturn(physicalUtilization);
+        Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
+
+        StoragePoolInfo storagePoolInfo = citrixResourceBase.createStoragePoolInfo(connectionMock, srMock);
+
+        Assert.assertEquals(srUuid, storagePoolInfo.getUuid());
+        Assert.assertEquals(hostAddress, storagePoolInfo.getHost());
+        Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getHostPath());
+        Assert.assertEquals(srType.toUpperCase(), storagePoolInfo.getLocalPath());
+        Assert.assertEquals(StoragePoolType.EXT, storagePoolInfo.getPoolType());
+        Assert.assertEquals(srPhysicalSize, storagePoolInfo.getCapacityBytes());
+        Assert.assertEquals(srPhysicalSize - physicalUtilization, storagePoolInfo.getAvailableBytes());
+    }
+
+    @Test
+    public void configureStorageNameAndDescriptionTest() throws XenAPIException, XmlRpcException {
+        String nameFormat = "Cloud Stack Local (%s) Storage Pool for %s";
+
+        String hostUuid = "hostUuid";
+        citrixResourceBase._host.setUuid(hostUuid);
+
+        Connection connectionMock = Mockito.mock(Connection.class);
+        SR srMock = Mockito.mock(SR.class);
+
+        String srUuid = "srUuid";
+        String srType = "ext";
+        String expectedNameDescription = String.format(nameFormat, srType, hostUuid);
+
+        Mockito.when(srMock.getUuid(connectionMock)).thenReturn(srUuid);
+        Mockito.when(srMock.getType(connectionMock)).thenReturn(srType);
+
+        Mockito.doNothing().when(srMock).setNameLabel(connectionMock, srUuid);
+        Mockito.doNothing().when(srMock).setNameDescription(connectionMock, expectedNameDescription);
+
+        citrixResourceBase.configureStorageNameAndDescription(connectionMock, srMock);
+
+        Mockito.verify(srMock).setNameLabel(connectionMock, srUuid);
+        Mockito.verify(srMock).setNameDescription(connectionMock, expectedNameDescription);
+    }
+
+    @Test
+    public void createStartUpStorageCommandTest() throws XenAPIException, XmlRpcException {
+        String hostUuid = "hostUUid";
+        citrixResourceBase._host.setUuid(hostUuid);
+        citrixResourceBase._dcId = 1;
+
+        Connection connectionMock = Mockito.mock(Connection.class);
+        SR srMock = Mockito.mock(SR.class);
+
+        StoragePoolInfo storagePoolInfoMock = Mockito.mock(StoragePoolInfo.class);
+
+        Mockito.doNothing().when(citrixResourceBase).configureStorageNameAndDescription(connectionMock, srMock);
+        Mockito.doReturn(storagePoolInfoMock).when(citrixResourceBase).createStoragePoolInfo(connectionMock, srMock);
+
+        StartupStorageCommand startUpStorageCommand = citrixResourceBase.createStartUpStorageCommand(connectionMock, srMock);
+
+        Assert.assertEquals(hostUuid, startUpStorageCommand.getGuid());
+        Assert.assertEquals(storagePoolInfoMock, startUpStorageCommand.getPoolInfo());
+        Assert.assertEquals(citrixResourceBase._dcId + "", startUpStorageCommand.getDataCenter());
+        Assert.assertEquals(StorageResourceType.STORAGE_POOL, startUpStorageCommand.getResourceType());
+    }
+
+    @Test
+    public void initializeLocalSrTest() throws XenAPIException, XmlRpcException {
+        Connection connectionMock = Mockito.mock(Connection.class);
+
+        List<SR> srsMocks = new ArrayList<>();
+        SR srMock1 = Mockito.mock(SR.class);
+        SR srMock2 = Mockito.mock(SR.class);
+
+        Mockito.when(srMock1.getPhysicalSize(connectionMock)).thenReturn(0l);
+        Mockito.when(srMock2.getPhysicalSize(connectionMock)).thenReturn(100l);
+        srsMocks.add(srMock1);
+        srsMocks.add(srMock2);
+
+        Mockito.doReturn(srsMocks).when(citrixResourceBase).getAllLocalSrs(connectionMock);
+
+        StartupStorageCommand startupStorageCommandMock = Mockito.mock(StartupStorageCommand.class);
+        Mockito.doReturn(startupStorageCommandMock).when(citrixResourceBase).createStartUpStorageCommand(Mockito.eq(connectionMock), Mockito.any(SR.class));
+
+        List<StartupStorageCommand> startUpCommandsForLocalStorage = citrixResourceBase.initializeLocalSrs(connectionMock);
+
+        Mockito.verify(citrixResourceBase, Mockito.times(0)).createStartUpStorageCommand(connectionMock, srMock1);
+        Mockito.verify(citrixResourceBase, Mockito.times(1)).createStartUpStorageCommand(connectionMock, srMock2);
+
+        Assert.assertEquals(1, startUpCommandsForLocalStorage.size());
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java
new file mode 100644
index 0000000..8f703ed
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XcpOssResourceTest extends CitrixResourceBaseTest {
+
+    @Before
+    @Override
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XcpOssResource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xcposs/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java
new file mode 100644
index 0000000..f1022cf
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XcpServerResourceTest extends CitrixResourceBaseTest {
+
+    @Before
+    @Override
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XcpServerResource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xcpserver/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFilesExeption() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java
new file mode 100644
index 0000000..902e8fd
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer56FP1ResourceTest extends CitrixResourceBaseTest {
+
+    @Before
+    @Override
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XenServer56FP1Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java
new file mode 100644
index 0000000..7d8d5d9
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer56ResourceTest extends CitrixResourceBaseTest {
+
+    @Override
+    @Before
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XenServer56Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java
new file mode 100644
index 0000000..65a9b47
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer56SP2ResourceTest extends CitrixResourceBaseTest {
+
+    @Override
+    @Before
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XenServer56SP2Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java
new file mode 100644
index 0000000..2175884
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer600ResourceTest extends CitrixResourceBaseTest {
+
+    @Before
+    @Override
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XenServer600Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java
new file mode 100644
index 0000000..fc14d9f
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer625ResourceTest extends CitrixResourceBaseTest {
+
+    @Before
+    @Override
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new Xenserver625Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver62/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java
new file mode 100644
index 0000000..be41840
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 The Apache Software Foundation.
+ *
+ * Licensed 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.xenserver.resource;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServer650ResourceTest extends CitrixResourceBaseTest {
+
+    @Override
+    @Before
+    public void beforeTest() throws XenAPIException, XmlRpcException {
+        super.citrixResourceBase = Mockito.spy(new XenServer650Resource());
+        super.beforeTest();
+    }
+
+    @Test
+    public void testPatchFilePath() {
+        String patchFilePath = citrixResourceBase.getPatchFilePath();
+        String patch = "scripts/vm/hypervisor/xenserver/xenserver65/patch";
+
+        Assert.assertEquals(patch, patchFilePath);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testGetFiles() {
+        testGetPathFilesExeption();
+    }
+
+    @Test
+    public void testGetFilesListReturned() {
+        testGetPathFilesListReturned();
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessorTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessorTest.java
new file mode 100644
index 0000000..0cf99b6
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessorTest.java
@@ -0,0 +1,459 @@
+/*
+ * 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.xenserver.resource;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.times;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PBD.Record;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types.InternalError;
+import com.xensource.xenapi.Types.XenAPIException;
+
+@RunWith(PowerMockRunner.class)
+public class Xenserver625StorageProcessorTest {
+
+    @InjectMocks
+    private Xenserver625StorageProcessor xenserver625StorageProcessor;
+
+    @Mock
+    private CitrixResourceBase citrixResourceBase;
+
+    @Mock
+    private Connection connectionMock;
+
+    private String pathMock = "pathMock";
+
+    @Before
+    public void before() {
+        xenserver625StorageProcessor = Mockito.spy(new Xenserver625StorageProcessor(citrixResourceBase));
+        citrixResourceBase._host = Mockito.mock(XsHost.class);
+        Mockito.when(citrixResourceBase.getHost()).thenReturn(citrixResourceBase._host);
+    }
+
+    @Test
+    public void makeDirectoryTestCallHostPlugingReturningEmpty() {
+        boolean makeDirectoryReturn = configureAndExecuteMakeDirectoryMethodForTest(pathMock, StringUtils.EMPTY);
+
+        assertFalse(makeDirectoryReturn);
+    }
+
+    @Test
+    public void makeDirectoryTestCallHostPlugingReturningNull() {
+        boolean makeDirectoryReturn = configureAndExecuteMakeDirectoryMethodForTest(pathMock, null);
+
+        assertFalse(makeDirectoryReturn);
+    }
+
+    @Test
+    public void makeDirectoryTestCallHostPlugingReturningSomething() {
+        boolean makeDirectoryReturn = configureAndExecuteMakeDirectoryMethodForTest(pathMock, "/fictitious/path/to/use/in/unit/test");
+
+        assertTrue(makeDirectoryReturn);
+    }
+
+    private boolean configureAndExecuteMakeDirectoryMethodForTest(String path, String returnMakeDirectory) {
+        Mockito.when(citrixResourceBase.callHostPlugin(connectionMock, "cloud-plugin-storage", "makeDirectory", "path", path)).thenReturn(returnMakeDirectory);
+        return xenserver625StorageProcessor.makeDirectory(connectionMock, path);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createFileSRTestNoSrRetrieveNoSrCreated() {
+        Mockito.doReturn(null).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        Mockito.doReturn(null).when(xenserver625StorageProcessor).createNewFileSr(connectionMock, pathMock);
+
+        xenserver625StorageProcessor.createFileSR(connectionMock, pathMock);
+    }
+
+    @Test
+    public void createFileSRTestSrAlreadyConfigured() {
+        SR srMockRetrievedMethod = Mockito.mock(SR.class);
+        SR srMockCreateMethod = Mockito.mock(SR.class);
+
+        Mockito.doReturn(srMockRetrievedMethod).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        Mockito.doReturn(srMockCreateMethod).when(xenserver625StorageProcessor).createNewFileSr(connectionMock, pathMock);
+
+        SR methodCreateFileSrResult = xenserver625StorageProcessor.createFileSR(connectionMock, pathMock);
+
+        InOrder inOrder = Mockito.inOrder(xenserver625StorageProcessor);
+        inOrder.verify(xenserver625StorageProcessor, times(1)).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        inOrder.verify(xenserver625StorageProcessor, times(0)).createNewFileSr(connectionMock, pathMock);
+
+        Assert.assertEquals(srMockRetrievedMethod, methodCreateFileSrResult);
+    }
+
+    @Test
+    public void createFileSRTestSrNotConfiguredAlreadyCreatingSr() {
+        SR srMockCreateMethod = Mockito.mock(SR.class);
+
+        Mockito.doReturn(null).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        Mockito.doReturn(srMockCreateMethod).when(xenserver625StorageProcessor).createNewFileSr(connectionMock, pathMock);
+
+        SR methodCreateFileSrResult = xenserver625StorageProcessor.createFileSR(connectionMock, pathMock);
+
+        InOrder inOrder = Mockito.inOrder(xenserver625StorageProcessor);
+        inOrder.verify(xenserver625StorageProcessor, times(1)).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        inOrder.verify(xenserver625StorageProcessor, times(1)).createNewFileSr(connectionMock, pathMock);
+
+        Assert.assertEquals(srMockCreateMethod, methodCreateFileSrResult);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void retrieveAlreadyConfiguredSrWithoutExceptionThrowingXenAPIException() throws XenAPIException, XmlRpcException {
+        Mockito.doThrow(XenAPIException.class).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        xenserver625StorageProcessor.retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void retrieveAlreadyConfiguredSrWithoutExceptionThrowingXmlRpcException() throws XenAPIException, XmlRpcException {
+        Mockito.doThrow(XmlRpcException.class).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        xenserver625StorageProcessor.retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void retrieveAlreadyConfiguredSrWithoutExceptionThrowingOtherException() throws XenAPIException, XmlRpcException {
+        Mockito.doThrow(RuntimeException.class).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        xenserver625StorageProcessor.retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+    }
+
+    @Test
+    public void retrieveAlreadyConfiguredSrWithoutExceptionMethodWorking() throws XenAPIException, XmlRpcException {
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doReturn(srMock).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        SR sr = xenserver625StorageProcessor.retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+
+        Mockito.verify(xenserver625StorageProcessor).retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+        Assert.assertEquals(srMock, sr);
+    }
+
+    @Test
+    @PrepareForTest(SR.class)
+    public void retrieveAlreadyConfiguredSrTestNoSrFound() throws XenAPIException, XmlRpcException {
+        prepareToReturnSrs(null);
+
+        SR sr = xenserver625StorageProcessor.retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        PowerMockito.verifyStatic();
+        SR.getByNameLabel(connectionMock, pathMock);
+        Assert.assertNull(sr);
+    }
+
+    private void prepareToReturnSrs(Set<SR> srs) throws XenAPIException, XmlRpcException {
+        PowerMockito.mockStatic(SR.class);
+        PowerMockito.when(SR.getByNameLabel(connectionMock, pathMock)).thenReturn(srs);
+    }
+
+    @PrepareForTest(SR.class)
+    @Test(expected = CloudRuntimeException.class)
+    public void retrieveAlreadyConfiguredSrTestMultipleSrsFound() throws XenAPIException, XmlRpcException {
+        HashSet<SR> srs = new HashSet<>();
+        srs.add(Mockito.mock(SR.class));
+        srs.add(Mockito.mock(SR.class));
+
+        prepareToReturnSrs(srs);
+
+        xenserver625StorageProcessor.retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+    }
+
+    @Test
+    @PrepareForTest(SR.class)
+    public void retrieveAlreadyConfiguredSrTestSrFailsSanityCheckWithXenAPIException() throws XenAPIException, XmlRpcException {
+        configureAndExecuteMethodRetrieveAlreadyConfiguredSrTestSrFailsSanityCheckForException(XenAPIException.class);
+    }
+
+    @Test
+    @PrepareForTest(SR.class)
+    public void retrieveAlreadyConfiguredSrTestSrFailsSanityCheckWithXmlRpcException() throws XenAPIException, XmlRpcException {
+        configureAndExecuteMethodRetrieveAlreadyConfiguredSrTestSrFailsSanityCheckForException(XmlRpcException.class);
+    }
+
+    @PrepareForTest(SR.class)
+    @Test(expected = RuntimeException.class)
+    public void retrieveAlreadyConfiguredSrTestSrFailsSanityCheckWithRuntimeException() throws XenAPIException, XmlRpcException {
+        configureAndExecuteMethodRetrieveAlreadyConfiguredSrTestSrFailsSanityCheckForException(RuntimeException.class);
+    }
+
+    private void configureAndExecuteMethodRetrieveAlreadyConfiguredSrTestSrFailsSanityCheckForException(Class<? extends Throwable> exceptionClass) throws XenAPIException, XmlRpcException {
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doThrow(exceptionClass).when(srMock).scan(connectionMock);
+
+        HashSet<SR> srs = new HashSet<>();
+        srs.add(srMock);
+
+        prepareToReturnSrs(srs);
+        Mockito.doNothing().when(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+
+        SR sr = xenserver625StorageProcessor.retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        Assert.assertNull(sr);
+        Mockito.verify(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+    }
+
+    @Test
+    @PrepareForTest(SR.class)
+    public void methodRetrieveAlreadyConfiguredSrTestSrScanSucceeds() throws XenAPIException, XmlRpcException {
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doNothing().when(srMock).scan(connectionMock);
+
+        HashSet<SR> srs = new HashSet<>();
+        srs.add(srMock);
+
+        prepareToReturnSrs(srs);
+        Mockito.doNothing().when(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+
+        SR sr = xenserver625StorageProcessor.retrieveAlreadyConfiguredSr(connectionMock, pathMock);
+
+        Assert.assertEquals(srMock, sr);
+        Mockito.verify(xenserver625StorageProcessor, times(0)).forgetSr(connectionMock, srMock);
+    }
+
+    @Test
+    public void forgetSrTest() throws XenAPIException, XmlRpcException {
+        PBD pbdMock = Mockito.mock(PBD.class);
+        Set<PBD> pbds = new HashSet<>();
+        pbds.add(pbdMock);
+
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.when(srMock.getPBDs(connectionMock)).thenReturn(pbds);
+
+        Mockito.doNothing().when(xenserver625StorageProcessor).unplugPbd(connectionMock, pbdMock);
+
+        xenserver625StorageProcessor.forgetSr(connectionMock, srMock);
+        Mockito.verify(srMock).getPBDs(connectionMock);
+        Mockito.verify(xenserver625StorageProcessor, times(1)).unplugPbd(connectionMock, pbdMock);
+        Mockito.verify(srMock).forget(connectionMock);
+    }
+
+    @Test
+    public void unplugPbdTest() throws XenAPIException, XmlRpcException {
+        PBD pbdMock = Mockito.mock(PBD.class);
+
+        xenserver625StorageProcessor.unplugPbd(connectionMock, pbdMock);
+
+        Mockito.verify(pbdMock).getUuid(connectionMock);
+        Mockito.verify(pbdMock).unplug(connectionMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void unplugPbdTestThrowXenAPIException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteUnplugMethodForException(XenAPIException.class);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void unplugPbdTestThrowXmlRpcException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteUnplugMethodForException(XmlRpcException.class);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void unplugPbdTestThrowRuntimeException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteUnplugMethodForException(RuntimeException.class);
+    }
+
+    private void prepareAndExecuteUnplugMethodForException(Class<? extends Throwable> exceptionClass) throws XenAPIException, XmlRpcException {
+        PBD pbdMock = Mockito.mock(PBD.class);
+        Mockito.doThrow(exceptionClass).when(pbdMock).unplug(connectionMock);
+        xenserver625StorageProcessor.unplugPbd(connectionMock, pbdMock);
+    }
+
+    @Test
+    @PrepareForTest({Host.class, SR.class})
+    public void createNewFileSrTestThrowingXenAPIException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteTestcreateNewFileSrTestThrowingException(XenAPIException.class);
+    }
+
+    @Test
+    @PrepareForTest({Host.class, SR.class})
+    public void createNewFileSrTestThrowingXmlRpcException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteTestcreateNewFileSrTestThrowingException(XmlRpcException.class);
+    }
+
+    @Test(expected = RuntimeException.class)
+    @PrepareForTest({Host.class, SR.class})
+    public void createNewFileSrTestThrowingRuntimeException() throws XenAPIException, XmlRpcException {
+        prepareAndExecuteTestcreateNewFileSrTestThrowingException(RuntimeException.class);
+    }
+
+    private void prepareAndExecuteTestcreateNewFileSrTestThrowingException(Class<? extends Throwable> exceptionClass) throws XenAPIException, XmlRpcException {
+        String uuid = "hostUuid";
+        Mockito.when(citrixResourceBase._host.getUuid()).thenReturn(uuid);
+
+        String srUuid = UUID.nameUUIDFromBytes(pathMock.getBytes()).toString();
+
+        Host hostMock = Mockito.mock(Host.class);
+
+        PowerMockito.mockStatic(Host.class);
+        PowerMockito.when(Host.getByUuid(connectionMock, uuid)).thenReturn(hostMock);
+
+        PowerMockito.mockStatic(SR.class);
+        PowerMockito.when(SR.introduce(Mockito.eq(connectionMock), Mockito.eq(srUuid), Mockito.eq(pathMock), Mockito.eq(pathMock), Mockito.eq("file"), Mockito.eq("file"), Mockito.eq(false),
+                Mockito.anyMapOf(String.class, String.class))).thenThrow(Mockito.mock(exceptionClass));
+
+        Mockito.doNothing().when(xenserver625StorageProcessor).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+
+        SR sr = xenserver625StorageProcessor.createNewFileSr(connectionMock, pathMock);
+
+        assertNull(sr);
+        Mockito.verify(xenserver625StorageProcessor).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+    }
+
+    @Test
+    @PrepareForTest({Host.class, SR.class})
+    public void createNewFileSrTestThrowingDbUniqueException() throws XenAPIException, XmlRpcException {
+        String uuid = "hostUuid";
+        Mockito.when(citrixResourceBase._host.getUuid()).thenReturn(uuid);
+
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doReturn(srMock).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        String srUuid = UUID.nameUUIDFromBytes(pathMock.getBytes()).toString();
+
+        Host hostMock = Mockito.mock(Host.class);
+
+        PowerMockito.mockStatic(Host.class);
+        PowerMockito.when(Host.getByUuid(connectionMock, uuid)).thenReturn(hostMock);
+
+        PowerMockito.mockStatic(SR.class);
+        InternalError dbUniquenessException = new InternalError("message: Db_exn.Uniqueness_constraint_violation(\"SR\", \"uuid\", \"fd3edbcf-f142-83d1-3fcb-029ca2446b68\")");
+
+        PowerMockito.when(SR.introduce(Mockito.eq(connectionMock), Mockito.eq(srUuid), Mockito.eq(pathMock), Mockito.eq(pathMock), Mockito.eq("file"), Mockito.eq("file"), Mockito.eq(false),
+                Mockito.anyMapOf(String.class, String.class))).thenThrow(dbUniquenessException);
+
+        Mockito.doNothing().when(xenserver625StorageProcessor).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+
+        SR sr = xenserver625StorageProcessor.createNewFileSr(connectionMock, pathMock);
+
+        Assert.assertEquals(srMock, sr);
+        Mockito.verify(xenserver625StorageProcessor, times(0)).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+        Mockito.verify(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+    }
+
+    @Test
+    @PrepareForTest({Host.class, SR.class, PBD.class})
+    public void createNewFileSrTest() throws XenAPIException, XmlRpcException {
+        String uuid = "hostUuid";
+        Mockito.when(citrixResourceBase._host.getUuid()).thenReturn(uuid);
+
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doReturn(srMock).when(xenserver625StorageProcessor).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+        String srUuid = UUID.nameUUIDFromBytes(pathMock.getBytes()).toString();
+
+        Host hostMock = Mockito.mock(Host.class);
+
+        PowerMockito.mockStatic(Host.class);
+        PowerMockito.when(Host.getByUuid(connectionMock, uuid)).thenReturn(hostMock);
+
+        PowerMockito.mockStatic(SR.class);
+        PowerMockito.when(SR.introduce(Mockito.eq(connectionMock), Mockito.eq(srUuid), Mockito.eq(pathMock), Mockito.eq(pathMock), Mockito.eq("file"), Mockito.eq("file"), Mockito.eq(false),
+                Mockito.anyMapOf(String.class, String.class))).thenReturn(srMock);
+
+        PowerMockito.mockStatic(PBD.class);
+        PBD pbdMock = Mockito.mock(PBD.class);
+        PowerMockito.when(PBD.create(Mockito.eq(connectionMock), Mockito.any(Record.class))).thenReturn(pbdMock);
+
+        Mockito.doNothing().when(xenserver625StorageProcessor).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+        SR sr = xenserver625StorageProcessor.createNewFileSr(connectionMock, pathMock);
+
+        Assert.assertEquals(srMock, sr);
+        Mockito.verify(xenserver625StorageProcessor, times(0)).removeSrAndPbdIfPossible(Mockito.eq(connectionMock), Mockito.any(SR.class), Mockito.any(PBD.class));
+        Mockito.verify(xenserver625StorageProcessor, times(0)).retrieveAlreadyConfiguredSrWithoutException(connectionMock, pathMock);
+
+        Mockito.verify(srMock).scan(connectionMock);
+        Mockito.verify(pbdMock).plug(connectionMock);
+
+        PowerMockito.verifyStatic();
+        SR.introduce(Mockito.eq(connectionMock), Mockito.eq(srUuid), Mockito.eq(pathMock), Mockito.eq(pathMock), Mockito.eq("file"), Mockito.eq("file"), Mockito.eq(false),
+                Mockito.anyMapOf(String.class, String.class));
+        PBD.create(Mockito.eq(connectionMock), Mockito.any(Record.class));
+    }
+
+    @Test
+    public void removeSrAndPbdIfPossibleBothPbdAndSrNotNull() {
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doNothing().when(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+
+        PBD pbdMock = Mockito.mock(PBD.class);
+        Mockito.doNothing().when(xenserver625StorageProcessor).unplugPbd(connectionMock, pbdMock);
+
+        xenserver625StorageProcessor.removeSrAndPbdIfPossible(connectionMock, srMock, pbdMock);
+
+        Mockito.verify(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+        Mockito.verify(xenserver625StorageProcessor).unplugPbd(connectionMock, pbdMock);
+
+    }
+
+    @Test
+    public void removeSrAndPbdIfPossiblePbdNullAndSrNotNull() {
+        SR srMock = Mockito.mock(SR.class);
+        Mockito.doNothing().when(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+
+        xenserver625StorageProcessor.removeSrAndPbdIfPossible(connectionMock, srMock, null);
+
+        Mockito.verify(xenserver625StorageProcessor).forgetSr(connectionMock, srMock);
+        Mockito.verify(xenserver625StorageProcessor, times(0)).unplugPbd(Mockito.eq(connectionMock), Mockito.any(PBD.class));
+
+    }
+
+    @Test
+    public void removeSrAndPbdIfPossiblePbdNotNullButSrNull() {
+        PBD pbdMock = Mockito.mock(PBD.class);
+        Mockito.doNothing().when(xenserver625StorageProcessor).unplugPbd(connectionMock, pbdMock);
+
+        xenserver625StorageProcessor.removeSrAndPbdIfPossible(connectionMock, null, pbdMock);
+
+        Mockito.verify(xenserver625StorageProcessor, times(0)).forgetSr(Mockito.eq(connectionMock), Mockito.any(SR.class));
+        Mockito.verify(xenserver625StorageProcessor).unplugPbd(connectionMock, pbdMock);
+
+    }
+
+    @Test
+    public void removeSrAndPbdIfPossibleBothPbdAndSrNull() {
+        xenserver625StorageProcessor.removeSrAndPbdIfPossible(connectionMock, null, null);
+
+        Mockito.verify(xenserver625StorageProcessor, times(0)).forgetSr(Mockito.eq(connectionMock), Mockito.any(SR.class));
+        Mockito.verify(xenserver625StorageProcessor, times(0)).unplugPbd(Mockito.eq(connectionMock), Mockito.any(PBD.class));
+
+    }
+}
diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapperTest.java
new file mode 100644
index 0000000..95fb5ae
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapperTest.java
@@ -0,0 +1,70 @@
+//
+// 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.xenserver.resource.wrapper.xenbase;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.XenAPIException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CitrixMigrateCommandWrapperTest {
+
+    @Mock
+    private CitrixResourceBase citrixResourceBase;
+    @Spy
+    private CitrixMigrateCommandWrapper citrixMigrateCommandWrapper;
+
+    @Test
+    public void destroyNetworkRulesOnSourceHostForMigratedVmTestSupportSecurityGroup() throws BadServerResponse, XenAPIException, XmlRpcException {
+        configureExecuteAndVerifyDestroyNetworkRulesOnSourceHostForMigratedVmTest(true, 1);
+    }
+
+    @Test
+    public void destroyNetworkRulesOnSourceHostForMigratedVmTestDoesNotSupportSecurityGroup() throws BadServerResponse, XenAPIException, XmlRpcException {
+        configureExecuteAndVerifyDestroyNetworkRulesOnSourceHostForMigratedVmTest(false, 0);
+    }
+
+    private void configureExecuteAndVerifyDestroyNetworkRulesOnSourceHostForMigratedVmTest(boolean canBridgeFirewall, int timesCallHostPlugin)
+            throws BadServerResponse, XenAPIException, XmlRpcException {
+
+        final MigrateCommand command = new MigrateCommand("migratedVmName", "destHostIp", false, Mockito.mock(VirtualMachineTO.class), true);
+        Connection conn = Mockito.mock(Connection.class);
+        Host dsthost = Mockito.mock(Host.class);
+        Mockito.doReturn("hostname").when(dsthost).getHostname(conn);
+
+        Mockito.doReturn(canBridgeFirewall).when(citrixResourceBase).canBridgeFirewall();
+
+        citrixMigrateCommandWrapper.destroyMigratedVmNetworkRulesOnSourceHost(command, citrixResourceBase, conn, dsthost);
+
+        Mockito.verify(citrixResourceBase, Mockito.times(timesCallHostPlugin)).callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", "migratedVmName");
+    }
+
+}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixRequestWrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XcpServerWrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XcpServerWrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XcpServerWrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XcpServerWrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56FP1WrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56FP1WrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56FP1WrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56FP1WrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56WrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56WrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56WrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer56WrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620SP1WrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620SP1WrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620SP1WrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620SP1WrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620WrapperTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620WrapperTest.java
similarity index 100%
rename from plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620WrapperTest.java
rename to plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer620WrapperTest.java
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java
deleted file mode 100644
index 67fce92..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import java.io.File;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-
-import com.cloud.utils.script.Script;
-
-public class CitrixResourceBaseTest {
-
-    protected CitrixResourceBase citrixResourceBase = new CitrixResourceBase() {
-        @Override
-        protected String getPatchFilePath() {
-            return null;
-        }
-    };
-
-    public void testGetPathFilesExeption() {
-        String patch = citrixResourceBase.getPatchFilePath();
-
-        PowerMockito.mockStatic(Script.class);
-        Mockito.when(Script.findScript("", patch)).thenReturn(null);
-
-        citrixResourceBase.getPatchFiles();
-
-    }
-
-    public void testGetPathFilesListReturned() {
-        String patch = citrixResourceBase.getPatchFilePath();
-
-        PowerMockito.mockStatic(Script.class);
-        Mockito.when(Script.findScript("", patch)).thenReturn(patch);
-
-        File expected = new File(patch);
-        String pathExpected = expected.getAbsolutePath();
-
-        List<File> files = citrixResourceBase.getPatchFiles();
-        String receivedPath = files.get(0).getAbsolutePath();
-        Assert.assertEquals(receivedPath, pathExpected);
-    }
-
-    @Test
-    public void testGetGuestOsTypeNull() {
-        String platformEmulator = null;
-
-        String expected = "Other install media";
-        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
-        Assert.assertEquals(expected, guestOsType);
-    }
-
-    @Test
-    public void testGetGuestOsTypeEmpty() {
-        String platformEmulator = "";
-
-        String expected = "Other install media";
-        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
-        Assert.assertEquals(expected, guestOsType);
-    }
-
-    @Test
-    public void testGetGuestOsTypeBlank() {
-        String platformEmulator = "    ";
-
-        String expected = "Other install media";
-        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
-        Assert.assertEquals(expected, guestOsType);
-    }
-
-    @Test
-    public void testGetGuestOsTypeOther() {
-        String platformEmulator = "My Own Linux Distribution Y.M (64-bit)";
-
-        String guestOsType = citrixResourceBase.getGuestOsType(platformEmulator);
-        Assert.assertEquals(platformEmulator, guestOsType);
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java
deleted file mode 100644
index 9266bf9..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpOssResourceTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-@RunWith(PowerMockRunner.class)
-public class XcpOssResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XcpOssResource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xcposs/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java
deleted file mode 100644
index 5b80a1d..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XcpServerResourceTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-@RunWith(PowerMockRunner.class)
-public class XcpServerResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XcpServerResource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xcpserver/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFilesExeption(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java
deleted file mode 100644
index d2edbd4..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56FP1ResourceTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-@RunWith(PowerMockRunner.class)
-public class XenServer56FP1ResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XenServer56FP1Resource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java
deleted file mode 100644
index dccdb28..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56ResourceTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-@RunWith(PowerMockRunner.class)
-public class XenServer56ResourceTest extends CitrixResourceBaseTest {
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XenServer56Resource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java
deleted file mode 100644
index 4cc9470..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer56SP2ResourceTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-@RunWith(PowerMockRunner.class)
-public class XenServer56SP2ResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XenServer56SP2Resource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java
deleted file mode 100644
index d5eba2af..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer600ResourceTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-@RunWith(PowerMockRunner.class)
-public class XenServer600ResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XenServer600Resource();
-    }
-
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java
deleted file mode 100644
index 9998c2f..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer625ResourceTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-@RunWith(PowerMockRunner.class)
-public class XenServer625ResourceTest extends CitrixResourceBaseTest {
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new Xenserver625Resource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver62/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class)
-    public void testGetFiles() {
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class)
-    public void testGetFilesListReturned() {
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java
deleted file mode 100644
index 5195025..0000000
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/XenServer650ResourceTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015 The Apache Software Foundation.
- *
- * Licensed 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.xenserver.resource;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-@RunWith(PowerMockRunner.class)
-public class XenServer650ResourceTest extends CitrixResourceBaseTest{
-
-    @Before
-    public void beforeTest() {
-        super.citrixResourceBase = new XenServer650Resource();
-    }
-
-    @Test
-    public void testPatchFilePath() {
-        String patchFilePath = citrixResourceBase.getPatchFilePath();
-        String patch = "scripts/vm/hypervisor/xenserver/xenserver65/patch";
-
-        Assert.assertEquals(patch, patchFilePath);
-    }
-
-    @Test(expected = CloudRuntimeException.class)
-    @PrepareForTest(Script.class )
-    public void testGetFiles(){
-        testGetPathFilesExeption();
-    }
-
-    @Test
-    @PrepareForTest(Script.class )
-    public void testGetFilesListReturned(){
-        testGetPathFilesListReturned();
-    }
-}
diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml
index 2f95b31..abe7934 100644
--- a/plugins/integrations/cloudian/pom.xml
+++ b/plugins/integrations/cloudian/pom.xml
@@ -1,60 +1,58 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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
+<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-integrations-cloudian-connector</artifactId>
-  <name>Apache CloudStack Plugin - Cloudian Connector</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.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>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-      <version>${cs.httpclient.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.github.tomakehurst</groupId>
-      <artifactId>wiremock-standalone</artifactId>
-      <version>${cs.wiremock.version}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>cloud-plugin-integrations-cloudian-connector</artifactId>
+    <name>Apache CloudStack Plugin - Cloudian Connector</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</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>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.tomakehurst</groupId>
+            <artifactId>wiremock-standalone</artifactId>
+            <version>${cs.wiremock.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/CloudianConnector.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/CloudianConnector.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/CloudianConnector.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/CloudianConnector.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/CloudianConnectorImpl.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/CloudianConnectorImpl.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/CloudianConnectorImpl.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/CloudianConnectorImpl.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianIsEnabledCmd.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/api/CloudianSsoLoginCmd.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianSsoLoginCmd.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/api/CloudianSsoLoginCmd.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/api/CloudianSsoLoginCmd.java
diff --git a/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianClient.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianClient.java
new file mode 100644
index 0000000..45d0964
--- /dev/null
+++ b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianClient.java
@@ -0,0 +1,347 @@
+// 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.cloudian.client;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.utils.security.SSLUtils;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.nio.TrustAllManager;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Strings;
+
+public class CloudianClient {
+    private static final Logger LOG = Logger.getLogger(CloudianClient.class);
+
+    private final HttpClient httpClient;
+    private final HttpClientContext httpContext;
+    private final String adminApiUrl;
+
+    public CloudianClient(final String host, final Integer port, final String scheme, final String username, final String password, final boolean validateSSlCertificate, final int timeout) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
+        final CredentialsProvider provider = new BasicCredentialsProvider();
+        provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
+        final HttpHost adminHost = new HttpHost(host, port, scheme);
+        final AuthCache authCache = new BasicAuthCache();
+        authCache.put(adminHost, new BasicScheme());
+
+        this.adminApiUrl = adminHost.toURI();
+        this.httpContext = HttpClientContext.create();
+        this.httpContext.setCredentialsProvider(provider);
+        this.httpContext.setAuthCache(authCache);
+
+        final RequestConfig config = RequestConfig.custom()
+                .setConnectTimeout(timeout * 1000)
+                .setConnectionRequestTimeout(timeout * 1000)
+                .setSocketTimeout(timeout * 1000)
+                .build();
+
+        if (!validateSSlCertificate) {
+            final SSLContext sslcontext = SSLUtils.getSSLContext();
+            sslcontext.init(null, new X509TrustManager[]{new TrustAllManager()}, new SecureRandom());
+            final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
+            this.httpClient = HttpClientBuilder.create()
+                    .setDefaultCredentialsProvider(provider)
+                    .setDefaultRequestConfig(config)
+                    .setSSLSocketFactory(factory)
+                    .build();
+        } else {
+            this.httpClient = HttpClientBuilder.create()
+                    .setDefaultCredentialsProvider(provider)
+                    .setDefaultRequestConfig(config)
+                    .build();
+        }
+    }
+
+    private void checkAuthFailure(final HttpResponse response) {
+        if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+            final Credentials credentials = httpContext.getCredentialsProvider().getCredentials(AuthScope.ANY);
+            LOG.error("Cloudian admin API authentication failed, please check Cloudian configuration. Admin auth principal=" + credentials.getUserPrincipal() + ", password=" + credentials.getPassword() + ", API url=" + adminApiUrl);
+            throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "Cloudian backend API call unauthorized, please ask your administrator to fix integration issues.");
+        }
+    }
+
+    private void checkResponseOK(final HttpResponse response) {
+        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
+            LOG.debug("Requested Cloudian resource does not exist");
+            return;
+        }
+        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK && response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find the requested resource and get valid response from Cloudian backend API call, please ask your administrator to diagnose and fix issues.");
+        }
+    }
+
+    private boolean checkEmptyResponse(final HttpResponse response) throws IOException {
+        return response != null && (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT ||
+                response.getEntity() == null ||
+                response.getEntity().getContent() == null);
+    }
+
+    private void checkResponseTimeOut(final Exception e) {
+        if (e instanceof ConnectTimeoutException || e instanceof SocketTimeoutException) {
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "Operation timed out, please try again.");
+        }
+    }
+
+    private HttpResponse delete(final String path) throws IOException {
+        final HttpResponse response = httpClient.execute(new HttpDelete(adminApiUrl + path), httpContext);
+        checkAuthFailure(response);
+        return response;
+    }
+
+    private HttpResponse get(final String path) throws IOException {
+        final HttpResponse response = httpClient.execute(new HttpGet(adminApiUrl + path), httpContext);
+        checkAuthFailure(response);
+        return response;
+    }
+
+    private HttpResponse post(final String path, final Object item) throws IOException {
+        final ObjectMapper mapper = new ObjectMapper();
+        final String json = mapper.writeValueAsString(item);
+        final StringEntity entity = new StringEntity(json);
+        final HttpPost request = new HttpPost(adminApiUrl + path);
+        request.setHeader("Content-type", "application/json");
+        request.setEntity(entity);
+        final HttpResponse response = httpClient.execute(request, httpContext);
+        checkAuthFailure(response);
+        return response;
+    }
+
+    private HttpResponse put(final String path, final Object item) throws IOException {
+        final ObjectMapper mapper = new ObjectMapper();
+        final String json = mapper.writeValueAsString(item);
+        final StringEntity entity = new StringEntity(json);
+        final HttpPut request = new HttpPut(adminApiUrl + path);
+        request.setHeader("Content-type", "application/json");
+        request.setEntity(entity);
+        final HttpResponse response = httpClient.execute(request, httpContext);
+        checkAuthFailure(response);
+        return response;
+    }
+
+    ////////////////////////////////////////////////////////
+    //////////////// Public APIs: User /////////////////////
+    ////////////////////////////////////////////////////////
+
+    public boolean addUser(final CloudianUser user) {
+        if (user == null) {
+            return false;
+        }
+        LOG.debug("Adding Cloudian user: " + user);
+        try {
+            final HttpResponse response = put("/user", user);
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to add Cloudian user due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+
+    public CloudianUser listUser(final String userId, final String groupId) {
+        if (Strings.isNullOrEmpty(userId) || Strings.isNullOrEmpty(groupId)) {
+            return null;
+        }
+        LOG.debug("Trying to find Cloudian user with id=" + userId + " and group id=" + groupId);
+        try {
+            final HttpResponse response = get(String.format("/user?userId=%s&groupId=%s", userId, groupId));
+            checkResponseOK(response);
+            if (checkEmptyResponse(response)) {
+                return null;
+            }
+            final ObjectMapper mapper = new ObjectMapper();
+            return mapper.readValue(response.getEntity().getContent(), CloudianUser.class);
+        } catch (final IOException e) {
+            LOG.error("Failed to list Cloudian user due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return null;
+    }
+
+    public List<CloudianUser> listUsers(final String groupId) {
+        if (Strings.isNullOrEmpty(groupId)) {
+            return new ArrayList<>();
+        }
+        LOG.debug("Trying to list Cloudian users in group id=" + groupId);
+        try {
+            final HttpResponse response = get(String.format("/user/list?groupId=%s&userType=all&userStatus=active", groupId));
+            checkResponseOK(response);
+            if (checkEmptyResponse(response)) {
+                return new ArrayList<>();
+            }
+            final ObjectMapper mapper = new ObjectMapper();
+            return Arrays.asList(mapper.readValue(response.getEntity().getContent(), CloudianUser[].class));
+        } catch (final IOException e) {
+            LOG.error("Failed to list Cloudian users due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return new ArrayList<>();
+    }
+
+    public boolean updateUser(final CloudianUser user) {
+        if (user == null) {
+            return false;
+        }
+        LOG.debug("Updating Cloudian user: " + user);
+        try {
+            final HttpResponse response = post("/user", user);
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to update Cloudian user due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+
+    public boolean removeUser(final String userId, final String groupId) {
+        if (Strings.isNullOrEmpty(userId) || Strings.isNullOrEmpty(groupId)) {
+            return false;
+        }
+        LOG.debug("Removing Cloudian user with user id=" + userId + " in group id=" + groupId);
+        try {
+            final HttpResponse response = delete(String.format("/user?userId=%s&groupId=%s", userId, groupId));
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to remove Cloudian user due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+
+    /////////////////////////////////////////////////////////
+    //////////////// Public APIs: Group /////////////////////
+    /////////////////////////////////////////////////////////
+
+    public boolean addGroup(final CloudianGroup group) {
+        if (group == null) {
+            return false;
+        }
+        LOG.debug("Adding Cloudian group: " + group);
+        try {
+            final HttpResponse response = put("/group", group);
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to add Cloudian group due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+
+    public CloudianGroup listGroup(final String groupId) {
+        if (Strings.isNullOrEmpty(groupId)) {
+            return null;
+        }
+        LOG.debug("Trying to find Cloudian group with id=" + groupId);
+        try {
+            final HttpResponse response = get(String.format("/group?groupId=%s", groupId));
+            checkResponseOK(response);
+            if (checkEmptyResponse(response)) {
+                return null;
+            }
+            final ObjectMapper mapper = new ObjectMapper();
+            return mapper.readValue(response.getEntity().getContent(), CloudianGroup.class);
+        } catch (final IOException e) {
+            LOG.error("Failed to list Cloudian group due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return null;
+    }
+
+    public List<CloudianGroup> listGroups() {
+        LOG.debug("Trying to list Cloudian groups");
+        try {
+            final HttpResponse response = get("/group/list");
+            checkResponseOK(response);
+            if (checkEmptyResponse(response)) {
+                return new ArrayList<>();
+            }
+            final ObjectMapper mapper = new ObjectMapper();
+            return Arrays.asList(mapper.readValue(response.getEntity().getContent(), CloudianGroup[].class));
+        } catch (final IOException e) {
+            LOG.error("Failed to list Cloudian groups due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return new ArrayList<>();
+    }
+
+    public boolean updateGroup(final CloudianGroup group) {
+        if (group == null) {
+            return false;
+        }
+        LOG.debug("Updating Cloudian group: " + group);
+        try {
+            final HttpResponse response = post("/group", group);
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to update group due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+
+    public boolean removeGroup(final String groupId) {
+        if (Strings.isNullOrEmpty(groupId)) {
+            return false;
+        }
+        LOG.debug("Removing Cloudian group id=" + groupId);
+        try {
+            final HttpResponse response = delete(String.format("/group?groupId=%s", groupId));
+            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
+        } catch (final IOException e) {
+            LOG.error("Failed to remove group due to:", e);
+            checkResponseTimeOut(e);
+        }
+        return false;
+    }
+}
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianGroup.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianGroup.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianGroup.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianGroup.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianUser.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianUser.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianUser.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianUser.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianUtils.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianUtils.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianUtils.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/client/CloudianUtils.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/response/CloudianEnabledResponse.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/response/CloudianEnabledResponse.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/response/CloudianEnabledResponse.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/response/CloudianEnabledResponse.java
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/response/CloudianSsoLoginResponse.java b/plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/response/CloudianSsoLoginResponse.java
similarity index 100%
rename from plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/response/CloudianSsoLoginResponse.java
rename to plugins/integrations/cloudian/src/main/java/org/apache/cloudstack/cloudian/response/CloudianSsoLoginResponse.java
diff --git a/plugins/integrations/cloudian/resources/META-INF/cloudstack/cloudian/module.properties b/plugins/integrations/cloudian/src/main/resources/META-INF/cloudstack/cloudian/module.properties
similarity index 100%
rename from plugins/integrations/cloudian/resources/META-INF/cloudstack/cloudian/module.properties
rename to plugins/integrations/cloudian/src/main/resources/META-INF/cloudstack/cloudian/module.properties
diff --git a/plugins/integrations/cloudian/resources/META-INF/cloudstack/cloudian/spring-cloudian-context.xml b/plugins/integrations/cloudian/src/main/resources/META-INF/cloudstack/cloudian/spring-cloudian-context.xml
similarity index 100%
rename from plugins/integrations/cloudian/resources/META-INF/cloudstack/cloudian/spring-cloudian-context.xml
rename to plugins/integrations/cloudian/src/main/resources/META-INF/cloudstack/cloudian/spring-cloudian-context.xml
diff --git a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianClient.java b/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianClient.java
deleted file mode 100644
index 11f2055..0000000
--- a/plugins/integrations/cloudian/src/org/apache/cloudstack/cloudian/client/CloudianClient.java
+++ /dev/null
@@ -1,347 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.cloudian.client;
-
-import java.io.IOException;
-import java.net.SocketTimeoutException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.utils.security.SSLUtils;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.nio.TrustAllManager;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.base.Strings;
-
-public class CloudianClient {
-    private static final Logger LOG = Logger.getLogger(CloudianClient.class);
-
-    private final HttpClient httpClient;
-    private final HttpClientContext httpContext;
-    private final String adminApiUrl;
-
-    public CloudianClient(final String host, final Integer port, final String scheme, final String username, final String password, final boolean validateSSlCertificate, final int timeout) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
-        final CredentialsProvider provider = new BasicCredentialsProvider();
-        provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
-        final HttpHost adminHost = new HttpHost(host, port, scheme);
-        final AuthCache authCache = new BasicAuthCache();
-        authCache.put(adminHost, new BasicScheme());
-
-        this.adminApiUrl = adminHost.toURI();
-        this.httpContext = HttpClientContext.create();
-        this.httpContext.setCredentialsProvider(provider);
-        this.httpContext.setAuthCache(authCache);
-
-        final RequestConfig config = RequestConfig.custom()
-                .setConnectTimeout(timeout * 1000)
-                .setConnectionRequestTimeout(timeout * 1000)
-                .setSocketTimeout(timeout * 1000)
-                .build();
-
-        if (!validateSSlCertificate) {
-            final SSLContext sslcontext = SSLUtils.getSSLContext();
-            sslcontext.init(null, new X509TrustManager[]{new TrustAllManager()}, new SecureRandom());
-            final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
-            this.httpClient = HttpClientBuilder.create()
-                    .setDefaultCredentialsProvider(provider)
-                    .setDefaultRequestConfig(config)
-                    .setSSLSocketFactory(factory)
-                    .build();
-        } else {
-            this.httpClient = HttpClientBuilder.create()
-                    .setDefaultCredentialsProvider(provider)
-                    .setDefaultRequestConfig(config)
-                    .build();
-        }
-    }
-
-    private void checkAuthFailure(final HttpResponse response) {
-        if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
-            final Credentials credentials = httpContext.getCredentialsProvider().getCredentials(AuthScope.ANY);
-            LOG.error("Cloudian admin API authentication failed, please check Cloudian configuration. Admin auth principal=" + credentials.getUserPrincipal() + ", password=" + credentials.getPassword() + ", API url=" + adminApiUrl);
-            throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "Cloudian backend API call unauthorized, please ask your administrator to fix integration issues.");
-        }
-    }
-
-    private void checkResponseOK(final HttpResponse response) {
-        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
-            LOG.debug("Requested Cloudian resource does not exist");
-            return;
-        }
-        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK && response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find the requested resource and get valid response from Cloudian backend API call, please ask your administrator to diagnose and fix issues.");
-        }
-    }
-
-    private boolean checkEmptyResponse(final HttpResponse response) throws IOException {
-        return response != null && (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT ||
-                response.getEntity() == null ||
-                response.getEntity().getContent() == null);
-    }
-
-    private void checkResponseTimeOut(final Exception e) {
-        if (e instanceof ConnectTimeoutException || e instanceof SocketTimeoutException) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "Operation timed out, please try again.");
-        }
-    }
-
-    private HttpResponse delete(final String path) throws IOException {
-        final HttpResponse response = httpClient.execute(new HttpDelete(adminApiUrl + path), httpContext);
-        checkAuthFailure(response);
-        return response;
-    }
-
-    private HttpResponse get(final String path) throws IOException {
-        final HttpResponse response = httpClient.execute(new HttpGet(adminApiUrl + path), httpContext);
-        checkAuthFailure(response);
-        return response;
-    }
-
-    private HttpResponse post(final String path, final Object item) throws IOException {
-        final ObjectMapper mapper = new ObjectMapper();
-        final String json = mapper.writeValueAsString(item);
-        final StringEntity entity = new StringEntity(json);
-        final HttpPost request = new HttpPost(adminApiUrl + path);
-        request.setHeader("Content-type", "application/json");
-        request.setEntity(entity);
-        final HttpResponse response = httpClient.execute(request, httpContext);
-        checkAuthFailure(response);
-        return response;
-    }
-
-    private HttpResponse put(final String path, final Object item) throws IOException {
-        final ObjectMapper mapper = new ObjectMapper();
-        final String json = mapper.writeValueAsString(item);
-        final StringEntity entity = new StringEntity(json);
-        final HttpPut request = new HttpPut(adminApiUrl + path);
-        request.setHeader("Content-type", "application/json");
-        request.setEntity(entity);
-        final HttpResponse response = httpClient.execute(request, httpContext);
-        checkAuthFailure(response);
-        return response;
-    }
-
-    ////////////////////////////////////////////////////////
-    //////////////// Public APIs: User /////////////////////
-    ////////////////////////////////////////////////////////
-
-    public boolean addUser(final CloudianUser user) {
-        if (user == null) {
-            return false;
-        }
-        LOG.debug("Adding Cloudian user: " + user);
-        try {
-            final HttpResponse response = put("/user", user);
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to add Cloudian user due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-
-    public CloudianUser listUser(final String userId, final String groupId) {
-        if (Strings.isNullOrEmpty(userId) || Strings.isNullOrEmpty(groupId)) {
-            return null;
-        }
-        LOG.debug("Trying to find Cloudian user with id=" + userId + " and group id=" + groupId);
-        try {
-            final HttpResponse response = get(String.format("/user?userId=%s&groupId=%s", userId, groupId));
-            checkResponseOK(response);
-            if (checkEmptyResponse(response)) {
-                return null;
-            }
-            final ObjectMapper mapper = new ObjectMapper();
-            return mapper.readValue(response.getEntity().getContent(), CloudianUser.class);
-        } catch (final IOException e) {
-            LOG.error("Failed to list Cloudian user due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return null;
-    }
-
-    public List<CloudianUser> listUsers(final String groupId) {
-        if (Strings.isNullOrEmpty(groupId)) {
-            return new ArrayList<>();
-        }
-        LOG.debug("Trying to list Cloudian users in group id=" + groupId);
-        try {
-            final HttpResponse response = get(String.format("/user/list?groupId=%s&userType=all&userStatus=active", groupId));
-            checkResponseOK(response);
-            if (checkEmptyResponse(response)) {
-                return new ArrayList<>();
-            }
-            final ObjectMapper mapper = new ObjectMapper();
-            return Arrays.asList(mapper.readValue(response.getEntity().getContent(), CloudianUser[].class));
-        } catch (final IOException e) {
-            LOG.error("Failed to list Cloudian users due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return new ArrayList<>();
-    }
-
-    public boolean updateUser(final CloudianUser user) {
-        if (user == null) {
-            return false;
-        }
-        LOG.debug("Updating Cloudian user: " + user);
-        try {
-            final HttpResponse response = post("/user", user);
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to update Cloudian user due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-
-    public boolean removeUser(final String userId, final String groupId) {
-        if (Strings.isNullOrEmpty(userId) || Strings.isNullOrEmpty(groupId)) {
-            return false;
-        }
-        LOG.debug("Removing Cloudian user with user id=" + userId + " in group id=" + groupId);
-        try {
-            final HttpResponse response = delete(String.format("/user?userId=%s&groupId=%s", userId, groupId));
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to remove Cloudian user due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-
-    /////////////////////////////////////////////////////////
-    //////////////// Public APIs: Group /////////////////////
-    /////////////////////////////////////////////////////////
-
-    public boolean addGroup(final CloudianGroup group) {
-        if (group == null) {
-            return false;
-        }
-        LOG.debug("Adding Cloudian group: " + group);
-        try {
-            final HttpResponse response = put("/group", group);
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to add Cloudian group due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-
-    public CloudianGroup listGroup(final String groupId) {
-        if (Strings.isNullOrEmpty(groupId)) {
-            return null;
-        }
-        LOG.debug("Trying to find Cloudian group with id=" + groupId);
-        try {
-            final HttpResponse response = get(String.format("/group?groupId=%s", groupId));
-            checkResponseOK(response);
-            if (checkEmptyResponse(response)) {
-                return null;
-            }
-            final ObjectMapper mapper = new ObjectMapper();
-            return mapper.readValue(response.getEntity().getContent(), CloudianGroup.class);
-        } catch (final IOException e) {
-            LOG.error("Failed to list Cloudian group due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return null;
-    }
-
-    public List<CloudianGroup> listGroups() {
-        LOG.debug("Trying to list Cloudian groups");
-        try {
-            final HttpResponse response = get("/group/list");
-            checkResponseOK(response);
-            if (checkEmptyResponse(response)) {
-                return new ArrayList<>();
-            }
-            final ObjectMapper mapper = new ObjectMapper();
-            return Arrays.asList(mapper.readValue(response.getEntity().getContent(), CloudianGroup[].class));
-        } catch (final IOException e) {
-            LOG.error("Failed to list Cloudian groups due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return new ArrayList<>();
-    }
-
-    public boolean updateGroup(final CloudianGroup group) {
-        if (group == null) {
-            return false;
-        }
-        LOG.debug("Updating Cloudian group: " + group);
-        try {
-            final HttpResponse response = post("/group", group);
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to remove group due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-
-    public boolean removeGroup(final String groupId) {
-        if (Strings.isNullOrEmpty(groupId)) {
-            return false;
-        }
-        LOG.debug("Removing Cloudian group id=" + groupId);
-        try {
-            final HttpResponse response = delete(String.format("/group?groupId=%s", groupId));
-            return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
-        } catch (final IOException e) {
-            LOG.error("Failed to remove group due to:", e);
-            checkResponseTimeOut(e);
-        }
-        return false;
-    }
-}
diff --git a/plugins/integrations/cloudian/test/org/apache/cloudstack/cloudian/CloudianClientTest.java b/plugins/integrations/cloudian/src/test/java/org/apache/cloudstack/cloudian/CloudianClientTest.java
similarity index 100%
rename from plugins/integrations/cloudian/test/org/apache/cloudstack/cloudian/CloudianClientTest.java
rename to plugins/integrations/cloudian/src/test/java/org/apache/cloudstack/cloudian/CloudianClientTest.java
diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml
index 2d7e110..1821783 100644
--- a/plugins/integrations/prometheus/pom.xml
+++ b/plugins/integrations/prometheus/pom.xml
@@ -1,48 +1,47 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-integrations-prometheus-exporter</artifactId>
-  <name>Apache CloudStack Plugin - Prometheus Exporter</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+<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-integrations-prometheus-exporter</artifactId>
+    <name>Apache CloudStack Plugin - Prometheus Exporter</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporter.java b/plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporter.java
similarity index 100%
rename from plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporter.java
rename to plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporter.java
diff --git a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterImpl.java b/plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
similarity index 100%
rename from plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
rename to plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterImpl.java
diff --git a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServer.java b/plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterServer.java
similarity index 100%
rename from plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServer.java
rename to plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterServer.java
diff --git a/plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java b/plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
similarity index 100%
rename from plugins/integrations/prometheus/src/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
rename to plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterServerImpl.java
diff --git a/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/module.properties b/plugins/integrations/prometheus/src/main/resources/META-INF/cloudstack/prometheus/module.properties
similarity index 100%
rename from plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/module.properties
rename to plugins/integrations/prometheus/src/main/resources/META-INF/cloudstack/prometheus/module.properties
diff --git a/plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml b/plugins/integrations/prometheus/src/main/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
similarity index 100%
rename from plugins/integrations/prometheus/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
rename to plugins/integrations/prometheus/src/main/resources/META-INF/cloudstack/prometheus/spring-prometheus-context.xml
diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml
index ff3ee6e..e5dafb3 100644
--- a/plugins/metrics/pom.xml
+++ b/plugins/metrics/pom.xml
@@ -1,55 +1,53 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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.11.4.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 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.12.0.0</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/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListClustersMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListClustersMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListHostsMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListHostsMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListInfrastructureCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListInfrastructureCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVMsMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListVolumesMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java b/plugins/metrics/src/main/java/org/apache/cloudstack/api/ListZonesMetricsCmd.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/api/ListZonesMetricsCmd.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsService.java
diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
new file mode 100644
index 0000000..37f1f55
--- /dev/null
+++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -0,0 +1,573 @@
+// 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.cluster.dao.ManagementServerHostDao;
+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;
+    @Inject
+    private ManagementServerHostDao managementServerHostDao;
+
+    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);
+        response.setManagementServers(managementServerHostDao.listAll().size());
+        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);
+
+            // 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 Host host: hostDao.findByClusterId(clusterId)) {
+                if (host == null || host.getType() != Host.Type.Routing) {
+                    continue;
+                }
+                if (host.getStatus() == Status.Up) {
+                    metrics.incrUpResources();
+                }
+                metrics.incrTotalResources();
+                updateHostMetrics(metrics, hostJoinDao.findById(host.getId()));
+            }
+
+            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(), 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<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)) {
+                if (cluster == null) {
+                    continue;
+                }
+                metrics.incrTotalResources();
+                if (cluster.getAllocationState() == Grouping.AllocationState.Enabled
+                        && cluster.getManagedState() == Managed.ManagedState.Managed) {
+                    metrics.incrUpResources();
+                }
+
+                for (final Host host: hostDao.findByClusterId(cluster.getId())) {
+                    if (host == null || host.getType() != Host.Type.Routing) {
+                        continue;
+                    }
+                    updateHostMetrics(metrics, hostJoinDao.findById(host.getId()));
+                }
+            }
+
+            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/main/java/org/apache/cloudstack/response/ClusterMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/ClusterMetricsResponse.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java
diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/response/InfrastructureResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/InfrastructureResponse.java
new file mode 100644
index 0000000..03b54ab
--- /dev/null
+++ b/plugins/metrics/src/main/java/org/apache/cloudstack/response/InfrastructureResponse.java
@@ -0,0 +1,109 @@
+// 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;
+
+    @SerializedName("managementservers")
+    @Param(description = "Number of management servers")
+    private Integer managementServers;
+
+    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;
+    }
+
+    public void setManagementServers(Integer managementServers) {
+        this.managementServers = managementServers;
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/StoragePoolMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/StoragePoolMetricsResponse.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/ZoneMetricsResponse.java
similarity index 100%
rename from plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java
rename to plugins/metrics/src/main/java/org/apache/cloudstack/response/ZoneMetricsResponse.java
diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties b/plugins/metrics/src/main/resources/META-INF/cloudstack/metrics/module.properties
similarity index 100%
rename from plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties
rename to plugins/metrics/src/main/resources/META-INF/cloudstack/metrics/module.properties
diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml b/plugins/metrics/src/main/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml
similarity index 100%
rename from plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml
rename to plugins/metrics/src/main/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml
diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java
deleted file mode 100644
index 8b76a17..0000000
--- a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java
+++ /dev/null
@@ -1,569 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.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);
-
-            // 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 Host host: hostDao.findByClusterId(clusterId)) {
-                if (host == null || host.getType() != Host.Type.Routing) {
-                    continue;
-                }
-                if (host.getStatus() == Status.Up) {
-                    metrics.incrUpResources();
-                }
-                metrics.incrTotalResources();
-                updateHostMetrics(metrics, hostJoinDao.findById(host.getId()));
-            }
-
-            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(), 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<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)) {
-                if (cluster == null) {
-                    continue;
-                }
-                metrics.incrTotalResources();
-                if (cluster.getAllocationState() == Grouping.AllocationState.Enabled
-                        && cluster.getManagedState() == Managed.ManagedState.Managed) {
-                    metrics.incrUpResources();
-                }
-
-                for (final Host host: hostDao.findByClusterId(cluster.getId())) {
-                    if (host == null || host.getType() != Host.Type.Routing) {
-                        continue;
-                    }
-                    updateHostMetrics(metrics, hostJoinDao.findById(host.getId()));
-                }
-            }
-
-            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/InfrastructureResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java
deleted file mode 100644
index a4db345..0000000
--- a/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.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/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml
index 51dd6ac..468fc4f 100644
--- a/plugins/network-elements/bigswitch/pom.xml
+++ b/plugins/network-elements/bigswitch/pom.xml
@@ -1,52 +1,30 @@
 <!--
+  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
 
-    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
 
-      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.
-
+  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-network-bigswitch</artifactId>
-  <name>Apache CloudStack Plugin - BigSwitch Virtual Network Segment</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-pmd-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
+<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-network-bigswitch</artifactId>
+    <name>Apache CloudStack Plugin - BigSwitch Virtual Network Segment</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/BcfAnswer.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/BcfAnswer.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/BcfAnswer.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/BcfAnswer.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/BcfCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/BcfCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/BcfCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/BcfCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CacheBcfTopologyCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CacheBcfTopologyCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CacheBcfTopologyCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CacheBcfTopologyCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfAttachmentCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfAttachmentCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfAttachmentCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfAttachmentCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfRouterCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfRouterCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfRouterCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfRouterCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfRouterInterfaceCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfRouterInterfaceCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfRouterInterfaceCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfRouterInterfaceCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfSegmentCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfSegmentCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfSegmentCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfSegmentCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfStaticNatCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfStaticNatCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/CreateBcfStaticNatCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/CreateBcfStaticNatCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfAttachmentCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfAttachmentCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfAttachmentCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfAttachmentCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfSegmentCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfSegmentCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfSegmentCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfSegmentCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfStaticNatCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfStaticNatCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/DeleteBcfStaticNatCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/DeleteBcfStaticNatCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerDataAnswer.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerDataAnswer.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerDataAnswer.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerDataAnswer.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerDataCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerDataCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerDataCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerDataCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerHostsAnswer.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerHostsAnswer.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerHostsAnswer.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerHostsAnswer.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerHostsCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerHostsCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/GetControllerHostsCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/GetControllerHostsCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/StartupBigSwitchBcfCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/StartupBigSwitchBcfCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/StartupBigSwitchBcfCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/StartupBigSwitchBcfCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/SyncBcfTopologyCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/SyncBcfTopologyCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/SyncBcfTopologyCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/SyncBcfTopologyCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/UpdateBcfAttachmentCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/UpdateBcfAttachmentCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/UpdateBcfAttachmentCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/UpdateBcfAttachmentCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/agent/api/UpdateBcfRouterCommand.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/UpdateBcfRouterCommand.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/agent/api/UpdateBcfRouterCommand.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/agent/api/UpdateBcfRouterCommand.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/AddBigSwitchBcfDeviceCmd.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/commands/BcfConstants.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/BcfConstants.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/api/commands/BcfConstants.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/BcfConstants.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/DeleteBigSwitchBcfDeviceCmd.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/commands/ListBigSwitchBcfDevicesCmd.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/ListBigSwitchBcfDevicesCmd.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/api/commands/ListBigSwitchBcfDevicesCmd.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/api/commands/ListBigSwitchBcfDevicesCmd.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/api/response/BigSwitchBcfDeviceResponse.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/api/response/BigSwitchBcfDeviceResponse.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/api/response/BigSwitchBcfDeviceResponse.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/BigSwitchBcfDeviceVO.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/BigSwitchBcfDeviceVO.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/BigSwitchBcfDeviceVO.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/BigSwitchBcfDeviceVO.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/AclData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/AclData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/AclData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/AclData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/AttachmentData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/AttachmentData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/AttachmentData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/AttachmentData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfApi.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfApi.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfApi.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfApi.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfApiException.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfApiException.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfApiException.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfApiException.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfUtils.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfUtils.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchBcfUtils.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchBcfUtils.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchStatus.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchStatus.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/BigSwitchStatus.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/BigSwitchStatus.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/Capabilities.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/Capabilities.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/Capabilities.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/Capabilities.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControlClusterData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControlClusterData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControlClusterData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControlClusterData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControlClusterStatus.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControlClusterStatus.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControlClusterStatus.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControlClusterStatus.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControllerData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControllerData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/ControllerData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/ControllerData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/FloatingIpData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/FloatingIpData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/FloatingIpData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/FloatingIpData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/NetworkData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/NetworkData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/NetworkData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/NetworkData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/RouterData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/RouterData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/RouterData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/RouterData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/RouterInterfaceData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/RouterInterfaceData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/RouterInterfaceData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/RouterInterfaceData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/TopologyData.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/TopologyData.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/TopologyData.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/TopologyData.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/TrustingProtocolSocketFactory.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/TrustingProtocolSocketFactory.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/bigswitch/TrustingProtocolSocketFactory.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/bigswitch/TrustingProtocolSocketFactory.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/dao/BigSwitchBcfDao.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/dao/BigSwitchBcfDao.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/dao/BigSwitchBcfDao.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/dao/BigSwitchBcfDao.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/dao/BigSwitchBcfDaoImpl.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/dao/BigSwitchBcfDaoImpl.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/dao/BigSwitchBcfDaoImpl.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/dao/BigSwitchBcfDaoImpl.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/element/BigSwitchBcfElement.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/element/BigSwitchBcfElement.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/element/BigSwitchBcfElementService.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElementService.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/element/BigSwitchBcfElementService.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElementService.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/guru/BigSwitchBcfGuestNetworkGuru.java
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/resource/BigSwitchBcfResource.java
similarity index 100%
rename from plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java
rename to plugins/network-elements/bigswitch/src/main/java/com/cloud/network/resource/BigSwitchBcfResource.java
diff --git a/plugins/network-elements/bigswitch/resources/META-INF/cloudstack/bigswitch/module.properties b/plugins/network-elements/bigswitch/src/main/resources/META-INF/cloudstack/bigswitch/module.properties
similarity index 100%
rename from plugins/network-elements/bigswitch/resources/META-INF/cloudstack/bigswitch/module.properties
rename to plugins/network-elements/bigswitch/src/main/resources/META-INF/cloudstack/bigswitch/module.properties
diff --git a/plugins/network-elements/bigswitch/resources/META-INF/cloudstack/bigswitch/spring-bigswitch-context.xml b/plugins/network-elements/bigswitch/src/main/resources/META-INF/cloudstack/bigswitch/spring-bigswitch-context.xml
similarity index 100%
rename from plugins/network-elements/bigswitch/resources/META-INF/cloudstack/bigswitch/spring-bigswitch-context.xml
rename to plugins/network-elements/bigswitch/src/main/resources/META-INF/cloudstack/bigswitch/spring-bigswitch-context.xml
diff --git a/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java b/plugins/network-elements/bigswitch/src/test/java/com/cloud/network/bigswitch/BigSwitchApiTest.java
similarity index 100%
rename from plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java
rename to plugins/network-elements/bigswitch/src/test/java/com/cloud/network/bigswitch/BigSwitchApiTest.java
diff --git a/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchBcfUtilsTest.java b/plugins/network-elements/bigswitch/src/test/java/com/cloud/network/bigswitch/BigSwitchBcfUtilsTest.java
similarity index 100%
rename from plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchBcfUtilsTest.java
rename to plugins/network-elements/bigswitch/src/test/java/com/cloud/network/bigswitch/BigSwitchBcfUtilsTest.java
diff --git a/plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java b/plugins/network-elements/bigswitch/src/test/java/com/cloud/network/resource/BigSwitchBcfResourceTest.java
similarity index 100%
rename from plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java
rename to plugins/network-elements/bigswitch/src/test/java/com/cloud/network/resource/BigSwitchBcfResourceTest.java
diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml
index 9a24c87..20a984c 100644
--- a/plugins/network-elements/brocade-vcs/pom.xml
+++ b/plugins/network-elements/brocade-vcs/pom.xml
@@ -1,78 +1,83 @@
-<!-- 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. -->
+<!--
+  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-network-vcs</artifactId>
-	<name>Apache CloudStack Plugin - Network Brocade VCS</name>
-	<parent>
-		<groupId>org.apache.cloudstack</groupId>
-		<artifactId>cloudstack-plugins</artifactId>
-		<version>4.11.4.0-SNAPSHOT</version>
-		<relativePath>../../pom.xml</relativePath>
-	</parent>
-
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.jvnet.jaxb2.maven2</groupId>
-				<artifactId>maven-jaxb2-plugin</artifactId>
-				<version>0.7.1</version>
-				<executions>
-					<execution>
-						<id>interface</id>
-						<goals>
-							<goal>generate</goal>
-						</goals>
-						<configuration>
-							<generateDirectory>${project.basedir}/target/generated-sources/xjc1</generateDirectory>
-							<schemaDirectory>${project.basedir}/resources</schemaDirectory>
-							<schemaIncludes>
-								<include>BrocadeInterfaceSchema.xsd</include>
-							</schemaIncludes>
-							<generatePackage>com.cloud.network.schema.interfacevlan</generatePackage>
-						</configuration>
-					</execution>
-					<execution>
-						<id>portprofile</id>
-						<goals>
-							<goal>generate</goal>
-						</goals>
-						<configuration>
-							<generateDirectory>${project.basedir}/target/generated-sources/xjc2</generateDirectory>
-							<schemaDirectory>${project.basedir}/resources</schemaDirectory>
-							<schemaIncludes>
-								<include>BrocadePortProfileSchema.xsd</include>
-							</schemaIncludes>
-							<generatePackage>com.cloud.network.schema.portprofile</generatePackage>
-						</configuration>
-					</execution>
-					<execution>
-						<id>show-vcs</id>
-						<goals>
-							<goal>generate</goal>
-						</goals>
-						<configuration>
-							<generateDirectory>${project.basedir}/target/generated-sources/xjc3</generateDirectory>
-							<schemaDirectory>${project.basedir}/resources</schemaDirectory>
-							<schemaIncludes>
-								<include>BrocadeShowVcsSchema.xsd</include>
-							</schemaIncludes>
-							<generatePackage>com.cloud.network.schema.showvcs</generatePackage>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-		</plugins>
-	</build>
-
+    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-network-vcs</artifactId>
+    <name>Apache CloudStack Plugin - Network Brocade VCS</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jvnet.jaxb2.maven2</groupId>
+                <artifactId>maven-jaxb2-plugin</artifactId>
+                <version>0.7.1</version>
+                <executions>
+                    <execution>
+                        <id>interface</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <generateDirectory>${project.build.directory}/generated-sources/xjc1</generateDirectory>
+                            <schemaDirectory>${project.build.resources[0].directory}</schemaDirectory>
+                            <schemaIncludes>
+                                <include>BrocadeInterfaceSchema.xsd</include>
+                            </schemaIncludes>
+                            <generatePackage>com.cloud.network.schema.interfacevlan</generatePackage>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>portprofile</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <generateDirectory>${project.build.directory}/generated-sources/xjc2</generateDirectory>
+                            <schemaDirectory>${project.build.resources[0].directory}</schemaDirectory>
+                            <schemaIncludes>
+                                <include>BrocadePortProfileSchema.xsd</include>
+                            </schemaIncludes>
+                            <generatePackage>com.cloud.network.schema.portprofile</generatePackage>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>show-vcs</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <generateDirectory>${project.build.directory}/generated-sources/xjc3</generateDirectory>
+                            <schemaDirectory>${project.build.resources[0].directory}</schemaDirectory>
+                            <schemaIncludes>
+                                <include>BrocadeShowVcsSchema.xsd</include>
+                            </schemaIncludes>
+                            <generatePackage>com.cloud.network.schema.showvcs</generatePackage>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/AssociateMacToNetworkAnswer.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkAnswer.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/AssociateMacToNetworkAnswer.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/AssociateMacToNetworkCommand.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/AssociateMacToNetworkCommand.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/AssociateMacToNetworkCommand.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/CreateNetworkAnswer.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkAnswer.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/CreateNetworkAnswer.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/CreateNetworkCommand.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/CreateNetworkCommand.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/CreateNetworkCommand.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DeleteNetworkAnswer.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkAnswer.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DeleteNetworkAnswer.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DeleteNetworkCommand.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DeleteNetworkCommand.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DeleteNetworkCommand.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DisassociateMacFromNetworkAnswer.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/DisassociateMacFromNetworkCommand.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/StartupBrocadeVcsCommand.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/agent/api/StartupBrocadeVcsCommand.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/agent/api/StartupBrocadeVcsCommand.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/AddBrocadeVcsDeviceCmd.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/DeleteBrocadeVcsDeviceCmd.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/ListBrocadeVcsDeviceNetworksCmd.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/commands/ListBrocadeVcsDevicesCmd.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/response/BrocadeVcsDeviceResponse.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/api/response/BrocadeVcsDeviceResponse.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/api/response/BrocadeVcsDeviceResponse.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/BrocadeVcsDeviceVO.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsDeviceVO.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/BrocadeVcsDeviceVO.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/BrocadeVcsNetworkVlanMappingVO.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/BrocadeVcsApi.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApi.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/BrocadeVcsApi.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/BrocadeVcsApiException.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/BrocadeVcsApiException.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/BrocadeVcsApiException.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/Constants.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/brocade/Constants.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/brocade/Constants.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsDao.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDao.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsDao.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsDaoImpl.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsDaoImpl.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsDaoImpl.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDao.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/dao/BrocadeVcsNetworkVlanMappingDaoImpl.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElement.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElementService.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/element/BrocadeVcsElementService.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElementService.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/guru/BrocadeVcsGuestNetworkGuru.java
diff --git a/plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/resource/BrocadeVcsResource.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/src/com/cloud/network/resource/BrocadeVcsResource.java
rename to plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/resource/BrocadeVcsResource.java
diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd b/plugins/network-elements/brocade-vcs/src/main/resources/BrocadeInterfaceSchema.xsd
similarity index 100%
rename from plugins/network-elements/brocade-vcs/resources/BrocadeInterfaceSchema.xsd
rename to plugins/network-elements/brocade-vcs/src/main/resources/BrocadeInterfaceSchema.xsd
diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd b/plugins/network-elements/brocade-vcs/src/main/resources/BrocadePortProfileSchema.xsd
similarity index 100%
rename from plugins/network-elements/brocade-vcs/resources/BrocadePortProfileSchema.xsd
rename to plugins/network-elements/brocade-vcs/src/main/resources/BrocadePortProfileSchema.xsd
diff --git a/plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd b/plugins/network-elements/brocade-vcs/src/main/resources/BrocadeShowVcsSchema.xsd
similarity index 100%
rename from plugins/network-elements/brocade-vcs/resources/BrocadeShowVcsSchema.xsd
rename to plugins/network-elements/brocade-vcs/src/main/resources/BrocadeShowVcsSchema.xsd
diff --git a/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties b/plugins/network-elements/brocade-vcs/src/main/resources/META-INF/cloudstack/vcs/module.properties
similarity index 100%
rename from plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/module.properties
rename to plugins/network-elements/brocade-vcs/src/main/resources/META-INF/cloudstack/vcs/module.properties
diff --git a/plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml b/plugins/network-elements/brocade-vcs/src/main/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml
similarity index 100%
rename from plugins/network-elements/brocade-vcs/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml
rename to plugins/network-elements/brocade-vcs/src/main/resources/META-INF/cloudstack/vcs/spring-vcs-context.xml
diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java b/plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/brocade/BrocadeVcsApiTest.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/test/com/cloud/network/brocade/BrocadeVcsApiTest.java
rename to plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/brocade/BrocadeVcsApiTest.java
diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java b/plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/test/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
rename to plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/guru/BrocadeVcsGuestNetworkGuruTest.java
diff --git a/plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java b/plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/resource/BrocadeVcsResourceTest.java
similarity index 100%
rename from plugins/network-elements/brocade-vcs/test/com/cloud/network/resource/BrocadeVcsResourceTest.java
rename to plugins/network-elements/brocade-vcs/src/test/java/com/cloud/network/resource/BrocadeVcsResourceTest.java
diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml
index e3bc8bc..386e6ad 100644
--- a/plugins/network-elements/cisco-vnmc/pom.xml
+++ b/plugins/network-elements/cisco-vnmc/pom.xml
@@ -1,42 +1,42 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-cisco-vnmc</artifactId>
-  <name>Apache CloudStack Plugin - Cisco VNMC</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-vmware-base</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-network-cisco-vnmc</artifactId>
+    <name>Apache CloudStack Plugin - Cisco VNMC</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-vmware-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/AssociateAsaWithLogicalEdgeFirewallCommand.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/AssociateAsaWithLogicalEdgeFirewallCommand.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/AssociateAsaWithLogicalEdgeFirewallCommand.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/AssociateAsaWithLogicalEdgeFirewallCommand.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/CleanupLogicalEdgeFirewallCommand.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/CleanupLogicalEdgeFirewallCommand.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/CleanupLogicalEdgeFirewallCommand.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/CleanupLogicalEdgeFirewallCommand.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/ConfigureNexusVsmForAsaCommand.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/ConfigureNexusVsmForAsaCommand.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/ConfigureNexusVsmForAsaCommand.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/ConfigureNexusVsmForAsaCommand.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/CreateLogicalEdgeFirewallCommand.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/CreateLogicalEdgeFirewallCommand.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/agent/api/CreateLogicalEdgeFirewallCommand.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/agent/api/CreateLogicalEdgeFirewallCommand.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/AddCiscoAsa1000vResourceCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/AddCiscoAsa1000vResourceCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/AddCiscoAsa1000vResourceCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/AddCiscoAsa1000vResourceCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/AddCiscoVnmcResourceCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/AddCiscoVnmcResourceCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/AddCiscoVnmcResourceCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/AddCiscoVnmcResourceCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/DeleteCiscoAsa1000vResourceCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/DeleteCiscoAsa1000vResourceCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/DeleteCiscoAsa1000vResourceCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/DeleteCiscoAsa1000vResourceCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/DeleteCiscoVnmcResourceCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/DeleteCiscoVnmcResourceCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/DeleteCiscoVnmcResourceCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/DeleteCiscoVnmcResourceCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/ListCiscoAsa1000vResourcesCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/commands/ListCiscoVnmcResourcesCmd.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/response/CiscoAsa1000vResourceResponse.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoAsa1000vResourceResponse.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/response/CiscoAsa1000vResourceResponse.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/response/CiscoVnmcResourceResponse.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/api/response/CiscoVnmcResourceResponse.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/api/response/CiscoVnmcResourceResponse.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoAsa1000vDevice.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoAsa1000vDevice.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoAsa1000vDevice.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoAsa1000vDevice.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoAsa1000vDeviceVO.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoAsa1000vDeviceVO.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoAsa1000vDeviceVO.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoAsa1000vDeviceVO.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcConnection.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnection.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcConnection.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcController.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcController.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcController.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcController.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcControllerVO.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcControllerVO.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcControllerVO.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/CiscoVnmcControllerVO.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/NetworkAsa1000vMap.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/NetworkAsa1000vMap.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/NetworkAsa1000vMap.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/NetworkAsa1000vMap.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/NetworkAsa1000vMapVO.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/NetworkAsa1000vMapVO.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/NetworkAsa1000vMapVO.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/cisco/NetworkAsa1000vMapVO.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoAsa1000vDao.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoAsa1000vDao.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoAsa1000vDao.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoAsa1000vDao.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoAsa1000vDaoImpl.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoAsa1000vDaoImpl.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoAsa1000vDaoImpl.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoAsa1000vDaoImpl.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoVnmcDao.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoVnmcDao.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoVnmcDao.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoVnmcDao.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoVnmcDaoImpl.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoVnmcDaoImpl.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/CiscoVnmcDaoImpl.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/CiscoVnmcDaoImpl.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/NetworkAsa1000vMapDao.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/NetworkAsa1000vMapDao.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/NetworkAsa1000vMapDao.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/NetworkAsa1000vMapDao.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/NetworkAsa1000vMapDaoImpl.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/NetworkAsa1000vMapDaoImpl.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/dao/NetworkAsa1000vMapDaoImpl.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/dao/NetworkAsa1000vMapDaoImpl.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoAsa1000vService.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoAsa1000vService.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElementService.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElementService.java
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/resource/CiscoVnmcResource.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java
rename to plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/resource/CiscoVnmcResource.java
diff --git a/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties b/plugins/network-elements/cisco-vnmc/src/main/resources/META-INF/cloudstack/cisco-vnmc/module.properties
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/module.properties
rename to plugins/network-elements/cisco-vnmc/src/main/resources/META-INF/cloudstack/cisco-vnmc/module.properties
diff --git a/plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml b/plugins/network-elements/cisco-vnmc/src/main/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml
rename to plugins/network-elements/cisco-vnmc/src/main/resources/META-INF/cloudstack/cisco-vnmc/spring-cisco-vnmc-context.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/assoc-asa1000v.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/assoc-asa1000v.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/assoc-asa1000v.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/assoc-asa1000v.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-acl-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-acl-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-acl-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-acl-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-dhcp-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-dhcp-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-dhcp-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-dhcp-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-dhcp-server.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-dhcp-server.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-dhcp-server.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-dhcp-server.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-nat-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-nat-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-nat-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-nat-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-route-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-route-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/associate-route-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/associate-route-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy-ref.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy-ref.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy-ref.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy-ref.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-rule-for-dnat.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-rule-for-dnat.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-rule-for-dnat.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-rule-for-dnat.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-rule-for-pf.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-rule-for-pf.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-acl-rule-for-pf.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-acl-rule-for-pf.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-dhcp-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-dhcp-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-dhcp-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-dhcp-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-dnat-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-dnat-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-dnat-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-dnat-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-profile.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-profile.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-profile.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-profile.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-route-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-route-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-route-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-route-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-route.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-route.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-device-route.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-device-route.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-firewall.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-firewall.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-firewall.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-firewall.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-security-profile.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-security-profile.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-edge-security-profile.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-edge-security-profile.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-egress-acl-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-egress-acl-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-egress-acl-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-egress-acl-no-protocol-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-egress-acl-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-egress-acl-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-egress-acl-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-ingress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-ingress-acl-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-generic-ingress-acl-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-generic-ingress-acl-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-ingress-acl-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ingress-acl-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-ingress-acl-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ip-pool.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-ip-pool.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-ip-pool.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-ip-pool.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy-ref.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy-ref.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy-ref.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy-ref.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-nat-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-nat-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-pf-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-pf-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-pf-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-pf-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-port-pool.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-port-pool.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-port-pool.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-port-pool.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-source-nat-pool.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-source-nat-pool.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-source-nat-pool.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-source-nat-pool.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-source-nat-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-source-nat-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-source-nat-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-source-nat-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-tenant.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-tenant.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-tenant.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-tenant.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-vdc.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-vdc.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/create-vdc.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/create-vdc.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-acl-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-acl-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-acl-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-acl-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-acl-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-acl-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-acl-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-acl-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-edge-firewall.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-edge-firewall.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-edge-firewall.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-edge-firewall.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-edge-security-profile.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-edge-security-profile.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-edge-security-profile.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-edge-security-profile.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-nat-policy-set.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-nat-policy-set.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-nat-policy-set.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-nat-policy-set.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-nat-policy.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-nat-policy.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-nat-policy.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-nat-policy.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-rule.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-rule.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-rule.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-rule.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-tenant.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-tenant.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-tenant.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-tenant.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-vdc.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-vdc.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/delete-vdc.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/delete-vdc.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/disassoc-asa1000v.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/disassoc-asa1000v.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/disassoc-asa1000v.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/disassoc-asa1000v.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-acl-policies.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-acl-policies.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-acl-policies.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-acl-policies.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-children.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-children.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-children.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-children.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-nat-policies.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-nat-policies.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-nat-policies.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-nat-policies.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-policyrefs-in-policyset.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-policyrefs-in-policyset.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-policyrefs-in-policyset.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-policyrefs-in-policyset.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-tenants.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-tenants.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-tenants.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-tenants.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-unassigned-asa1000v.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-unassigned-asa1000v.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/list-unassigned-asa1000v.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/list-unassigned-asa1000v.xml
diff --git a/plugins/network-elements/cisco-vnmc/scripts/network/cisco/login.xml b/plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/login.xml
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/scripts/network/cisco/login.xml
rename to plugins/network-elements/cisco-vnmc/src/main/scripts/network/cisco/login.xml
diff --git a/plugins/network-elements/cisco-vnmc/test/com/cloud/network/cisco/CiscoVnmcConnectionTest.java b/plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/cisco/CiscoVnmcConnectionTest.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/test/com/cloud/network/cisco/CiscoVnmcConnectionTest.java
rename to plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/cisco/CiscoVnmcConnectionTest.java
diff --git a/plugins/network-elements/cisco-vnmc/test/com/cloud/network/element/CiscoVnmcElementTest.java b/plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/element/CiscoVnmcElementTest.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/test/com/cloud/network/element/CiscoVnmcElementTest.java
rename to plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/element/CiscoVnmcElementTest.java
diff --git a/plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java b/plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/resource/CiscoVnmcResourceTest.java
similarity index 100%
rename from plugins/network-elements/cisco-vnmc/test/com/cloud/network/resource/CiscoVnmcResourceTest.java
rename to plugins/network-elements/cisco-vnmc/src/test/java/com/cloud/network/resource/CiscoVnmcResourceTest.java
diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml
index 90ceb5e..f822dff 100644
--- a/plugins/network-elements/dns-notifier/pom.xml
+++ b/plugins/network-elements/dns-notifier/pom.xml
@@ -1,48 +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.
--->
-<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>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <artifactId>cloud-plugin-example-dns-notifier</artifactId>
-  <name>Apache CloudStack Plugin - Dns Notifier Example</name>
-  <description>This is sample source code on how to write a plugin for CloudStack</description>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-  </build>
-  <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>
-</project>
+<!--
+  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>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <artifactId>cloud-plugin-example-dns-notifier</artifactId>
+    <name>Apache CloudStack Plugin - Dns Notifier Example</name>
+    <description>This is sample source code on how to write a plugin for CloudStack</description>
+    <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>
+</project>
diff --git a/plugins/network-elements/dns-notifier/src/org/apache/cloudstack/network/element/DnsNotifier.java b/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
similarity index 100%
rename from plugins/network-elements/dns-notifier/src/org/apache/cloudstack/network/element/DnsNotifier.java
rename to plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
diff --git a/plugins/network-elements/dns-notifier/resources/components-example.xml b/plugins/network-elements/dns-notifier/src/main/resources/components-example.xml
similarity index 100%
rename from plugins/network-elements/dns-notifier/resources/components-example.xml
rename to plugins/network-elements/dns-notifier/src/main/resources/components-example.xml
diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml
index b355e57..8afd571 100644
--- a/plugins/network-elements/elastic-loadbalancer/pom.xml
+++ b/plugins/network-elements/elastic-loadbalancer/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-elb</artifactId>
-  <name>Apache CloudStack Plugin - Network Elastic Load Balancer</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-network-elb</artifactId>
+    <name>Apache CloudStack Plugin - Network Elastic Load Balancer</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/LoadBalanceRuleHandler.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/LoadBalanceRuleHandler.java
deleted file mode 100644
index dc5f0ab..0000000
--- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/LoadBalanceRuleHandler.java
+++ /dev/null
@@ -1,483 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.lb;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.ConfigurationManagerImpl;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.network.ElasticLbVmMapVO;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.VirtualRouterProvider.Type;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.lb.dao.ElasticLbVmMapDao;
-import com.cloud.network.router.VirtualRouter.RedundantState;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.VirtualMachineProfile.Param;
-import com.cloud.vm.dao.DomainRouterDao;
-
-public class LoadBalanceRuleHandler {
-
-    private static final Logger s_logger = Logger.getLogger(LoadBalanceRuleHandler.class);
-
-    @Inject
-    private IPAddressDao _ipAddressDao;
-    @Inject
-    private NetworkModel _networkModel;
-    @Inject
-    private NetworkOrchestrationService _networkMgr;
-    @Inject
-    private final LoadBalancerDao _loadBalancerDao = null;
-    @Inject
-    private LoadBalancingRulesManager _lbMgr;
-    @Inject
-    private final DomainRouterDao _routerDao = null;
-    @Inject
-    protected HostPodDao _podDao = null;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    private final DataCenterDao _dcDao = null;
-    @Inject
-    private IpAddressManager _ipAddrMgr;
-    @Inject
-    protected NetworkDao _networkDao;
-    @Inject
-    protected NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    private final VMTemplateDao _templateDao = null;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private AccountService _accountService;
-    @Inject
-    private LoadBalancerDao _lbDao;
-    @Inject
-    private PodVlanMapDao _podVlanMapDao;
-    @Inject
-    private ElasticLbVmMapDao _elbVmMapDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private PhysicalNetworkServiceProviderDao _physicalProviderDao;
-    @Inject
-    private VirtualRouterProviderDao _vrProviderDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private UserDao _userDao;
-
-    static final private String ELB_VM_NAME_PREFIX = "l";
-
-    private final String _instance;
-    private final Account _systemAcct;
-
-    public LoadBalanceRuleHandler(String instance, Account systemAcct) {
-        _instance = instance;
-        _systemAcct = systemAcct;
-    }
-
-    public void handleDeleteLoadBalancerRule(final LoadBalancer lb, final long userId, final Account caller) {
-        final List<LoadBalancerVO> remainingLbs = _loadBalancerDao.listByIpAddress(lb.getSourceIpAddressId());
-        if (remainingLbs.size() == 0) {
-            s_logger.debug("ELB mgr: releasing ip " + lb.getSourceIpAddressId() + " since  no LB rules remain for this ip address");
-            releaseIp(lb.getSourceIpAddressId(), userId, caller);
-        }
-    }
-
-    public LoadBalancer handleCreateLoadBalancerRule(final CreateLoadBalancerRuleCmd lb, Account account, final long networkId) throws InsufficientAddressCapacityException,
-    NetworkRuleConflictException {
-        //this part of code is executed when the LB provider is Elastic Load Balancer vm
-        if (!_networkModel.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) {
-            return null;
-        }
-
-        final Long ipId = lb.getSourceIpAddressId();
-        if (ipId != null) {
-            return null;
-        }
-
-        account = _accountDao.acquireInLockTable(account.getId());
-        if (account == null) {
-            s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account");
-            throw new CloudRuntimeException("Failed to acquire lock on account");
-        }
-        try {
-            return handleCreateLoadBalancerRuleWithLock(lb, account, networkId);
-        } finally {
-            if (account != null) {
-                _accountDao.releaseFromLockTable(account.getId());
-            }
-        }
-    }
-
-    private DomainRouterVO deployLoadBalancerVM(final Long networkId, final IPAddressVO ipAddr) {
-        final NetworkVO network = _networkDao.findById(networkId);
-        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        final Long podId = getPodIdForDirectIp(ipAddr);
-        final Pod pod = podId == null ? null : _podDao.findById(podId);
-        final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
-        params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
-        final Account owner = _accountService.getActiveAccountByName("system", new Long(1));
-        final DeployDestination dest = new DeployDestination(dc, pod, null, null);
-        s_logger.debug("About to deploy ELB vm ");
-
-        try {
-            final DomainRouterVO elbVm = deployELBVm(network, dest, owner, params);
-            if (elbVm == null) {
-                throw new InvalidParameterValueException("Could not deploy or find existing ELB VM");
-            }
-            s_logger.debug("Deployed ELB  vm = " + elbVm);
-
-            return elbVm;
-
-        } catch (final Throwable t) {
-            s_logger.warn("Error while deploying ELB VM:  ", t);
-            return null;
-        }
-
-    }
-
-    private DomainRouterVO deployELBVm(Network guestNetwork, final DeployDestination dest, Account owner, final Map<Param, Object> params) throws ConcurrentOperationException,
-    InsufficientCapacityException {
-        final long dcId = dest.getDataCenter().getId();
-
-        // lock guest network
-        final Long guestNetworkId = guestNetwork.getId();
-        guestNetwork = _networkDao.acquireInLockTable(guestNetworkId);
-
-        if (guestNetwork == null) {
-            throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId);
-        }
-
-        try {
-
-            if (_networkModel.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) {
-                owner = _accountService.getSystemAccount();
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Starting a ELB vm for network configurations: " + guestNetwork + " in " + dest);
-            }
-            assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: "
-                    + guestNetwork;
-
-            DataCenterDeployment plan = null;
-            DomainRouterVO elbVm = null;
-
-            plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null);
-
-            if (elbVm == null) {
-                final long id = _routerDao.getNextInSequence(Long.class, "id");
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Creating the ELB vm " + id);
-                }
-
-                final List<? extends NetworkOffering> offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
-                final NetworkOffering controlOffering = offerings.get(0);
-                final Network controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0);
-
-                final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(2);
-                final NicProfile guestNic = new NicProfile();
-                guestNic.setDefaultNic(true);
-                networks.put(controlConfig, new ArrayList<NicProfile>());
-                networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(guestNic)));
-
-                final VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId);
-
-                final String typeString = "ElasticLoadBalancerVm";
-                final Long physicalNetworkId = _networkModel.getPhysicalNetworkId(guestNetwork);
-                final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString);
-                if (provider == null) {
-                    throw new CloudRuntimeException("Cannot find service provider " + typeString + " in physical network " + physicalNetworkId);
-                }
-                final VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), Type.ElasticLoadBalancerVm);
-                if (vrProvider == null) {
-                    throw new CloudRuntimeException("Cannot find virtual router provider " + typeString + " as service provider " + provider.getId());
-                }
-
-                long userId = CallContext.current().getCallingUserId();
-                if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
-                    List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
-                    if (!userVOs.isEmpty()) {
-                        userId =  userVOs.get(0).getId();
-                    }
-                }
-
-                ServiceOfferingVO elasticLbVmOffering = _serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.elbVmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dest.getDataCenter().getId()));
-                elbVm = new DomainRouterVO(id, elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, ELB_VM_NAME_PREFIX),
-                        template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN,
-                        elasticLbVmOffering.getOfferHA(), false, null);
-                elbVm.setRole(Role.LB);
-                elbVm = _routerDao.persist(elbVm);
-                _itMgr.allocate(elbVm.getInstanceName(), template, elasticLbVmOffering, networks, plan, null);
-                elbVm = _routerDao.findById(elbVm.getId());
-                //TODO: create usage stats
-            }
-
-            final State state = elbVm.getState();
-            if (state != State.Running) {
-                elbVm = start(elbVm, params);
-            }
-
-            return elbVm;
-        } finally {
-            _networkDao.releaseFromLockTable(guestNetworkId);
-        }
-    }
-
-    private void releaseIp(final long ipId, final long userId, final Account caller) {
-        s_logger.info("ELB: Release public IP for loadbalancing " + ipId);
-        final IPAddressVO ipvo = _ipAddressDao.findById(ipId);
-        ipvo.setAssociatedWithNetworkId(null);
-        _ipAddressDao.update(ipvo.getId(), ipvo);
-        _ipAddrMgr.disassociatePublicIpAddress(ipId, userId, caller);
-        _ipAddressDao.unassignIpAddress(ipId);
-    }
-
-    protected Long getPodIdForDirectIp(final IPAddressVO ipAddr) {
-        final PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(ipAddr.getVlanId());
-        if (podVlanMaps == null) {
-            return null;
-        } else {
-            return podVlanMaps.getPodId();
-        }
-    }
-
-    private LoadBalancer handleCreateLoadBalancerRuleWithLock(final CreateLoadBalancerRuleCmd lb, final Account account, final long networkId) throws InsufficientAddressCapacityException,
-    NetworkRuleConflictException {
-        Long ipId = null;
-        boolean newIp = false;
-        List<LoadBalancerVO> existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), lb.getSourcePortStart());
-        if (existingLbs == null) {
-            existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null);
-            if (existingLbs == null) {
-                if (lb.getSourceIpAddressId() != null) {
-                    throwExceptionIfSuppliedlLbNameIsNotAssociatedWithIpAddress(lb);
-                } else {
-                    s_logger.debug("Could not find any existing frontend ips for this account for this LB rule, acquiring a new frontent IP for ELB");
-                    final PublicIp ip = allocDirectIp(account, networkId);
-                    ipId = ip.getId();
-                    newIp = true;
-                }
-            } else {
-                ipId = existingLbs.get(0).getSourceIpAddressId();
-                s_logger.debug("ELB: Found existing frontend ip for this account for this LB rule " + ipId);
-            }
-        } else {
-            s_logger.warn("ELB: Found existing load balancers matching requested new LB");
-            throw new NetworkRuleConflictException("ELB: Found existing load balancers matching requested new LB");
-        }
-
-        final IPAddressVO ipAddr = _ipAddressDao.findById(ipId);
-
-        LoadBalancer result = null;
-        try {
-            lb.setSourceIpAddressId(ipId);
-
-            result = _lbMgr.createPublicLoadBalancer(lb.getXid(), lb.getName(), lb.getDescription(), lb.getSourcePortStart(), lb.getDefaultPortStart(), ipId.longValue(),
-                    lb.getProtocol(), lb.getAlgorithm(), false, CallContext.current(), lb.getLbProtocol(), true);
-        } catch (final NetworkRuleConflictException e) {
-            s_logger.warn("Failed to create LB rule, not continuing with ELB deployment");
-            if (newIp) {
-                releaseIp(ipId, CallContext.current().getCallingUserId(), account);
-            }
-            throw e;
-        }
-
-        DomainRouterVO elbVm = null;
-
-        if (existingLbs == null) {
-            elbVm = findElbVmWithCapacity(ipAddr);
-            if (elbVm == null) {
-                elbVm = deployLoadBalancerVM(networkId, ipAddr);
-                if (elbVm == null) {
-                    final Network network = _networkModel.getNetwork(networkId);
-                    s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName());
-                    if (newIp) {
-                        releaseIp(ipId, CallContext.current().getCallingUserId(), account);
-                    }
-                }
-            }
-
-        } else {
-            final ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId);
-            if (elbVmMap != null) {
-                elbVm = _routerDao.findById(elbVmMap.getElbVmId());
-            }
-        }
-
-        if (elbVm == null) {
-            s_logger.warn("No ELB VM can be found or deployed");
-            s_logger.warn("Deleting LB since we failed to deploy ELB VM");
-            _lbDao.remove(result.getId());
-            return null;
-        }
-
-        final ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId(), result.getId());
-        _elbVmMapDao.persist(mapping);
-        return result;
-    }
-
-    private void throwExceptionIfSuppliedlLbNameIsNotAssociatedWithIpAddress(final CreateLoadBalancerRuleCmd lb) {
-        final List<LoadBalancerVO> existingLbs = findExistingLoadBalancers(lb.getName(), null, lb.getAccountId(), lb.getDomainId(), null);
-        if (existingLbs != null) {
-            throw new InvalidParameterValueException("Supplied LB name " + lb.getName() + " is not associated with IP " + lb.getSourceIpAddressId());
-        }
-    }
-
-    protected List<LoadBalancerVO> findExistingLoadBalancers(final String lbName, final Long ipId, final Long accountId, final Long domainId, final Integer publicPort) {
-        final SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
-        sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
-        if (ipId != null) {
-            sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
-        }
-        if (domainId != null) {
-            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-        }
-        if (publicPort != null) {
-            sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
-        }
-        final SearchCriteria<LoadBalancerVO> sc = sb.create();
-        sc.setParameters("name", lbName);
-        sc.setParameters("accountId", accountId);
-        if (ipId != null) {
-            sc.setParameters("sourceIpAddress", ipId);
-        }
-        if (domainId != null) {
-            sc.setParameters("domainId", domainId);
-        }
-        if (publicPort != null) {
-            sc.setParameters("publicPort", publicPort);
-        }
-        final List<LoadBalancerVO> lbs = _lbDao.search(sc, null);
-
-        return lbs == null || lbs.size() == 0 ? null : lbs;
-    }
-
-    @DB
-    private PublicIp allocDirectIp(final Account account, final long guestNetworkId) throws InsufficientAddressCapacityException {
-        return Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
-            @Override
-            public PublicIp doInTransaction(final TransactionStatus status) throws InsufficientAddressCapacityException {
-                final Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId);
-
-                final PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true, false);
-                final IPAddressVO ipvo = _ipAddressDao.findById(ip.getId());
-                ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId());
-                _ipAddressDao.update(ipvo.getId(), ipvo);
-                s_logger.info("Acquired frontend IP for ELB " + ip);
-
-                return ip;
-            }
-        });
-    }
-
-    protected DomainRouterVO findElbVmWithCapacity(final IPAddressVO ipAddr) {
-        final List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms();
-        if (unusedElbVms.size() > 0) {
-            final List<DomainRouterVO> candidateVms = new ArrayList<DomainRouterVO>();
-            for (final DomainRouterVO candidateVm : unusedElbVms) {
-                addCandidateVmIsPodIpMatches(candidateVm, getPodIdForDirectIp(ipAddr), candidateVms);
-            }
-            return candidateVms.size() == 0 ? null : candidateVms.get(new Random().nextInt(candidateVms.size()));
-        }
-        return null;
-    }
-
-    protected static void addCandidateVmIsPodIpMatches(final DomainRouterVO candidateVm, final Long podIdForDirectIp, final List<DomainRouterVO> candidateVms) {
-        if (candidateVm.getPodIdToDeployIn().equals(podIdForDirectIp)) {
-            candidateVms.add(candidateVm);
-        }
-    }
-
-    protected DomainRouterVO start(final DomainRouterVO elbVm, final Map<Param, Object> params) throws ConcurrentOperationException {
-        s_logger.debug("Starting ELB VM " + elbVm);
-        _itMgr.start(elbVm.getUuid(), params);
-        return _routerDao.findById(elbVm.getId());
-    }
-}
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/ElasticLbVmMapVO.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/ElasticLbVmMapVO.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManager.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/ElasticLoadBalancerManager.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManager.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/ElasticLoadBalancerManager.java
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java
diff --git a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/LoadBalanceRuleHandler.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/LoadBalanceRuleHandler.java
new file mode 100644
index 0000000..05ed615
--- /dev/null
+++ b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/LoadBalanceRuleHandler.java
@@ -0,0 +1,483 @@
+// 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.network.lb;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.ConfigurationManagerImpl;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.network.ElasticLbVmMapVO;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.VirtualRouterProvider.Type;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.lb.dao.ElasticLbVmMapDao;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachineProfile.Param;
+import com.cloud.vm.dao.DomainRouterDao;
+
+public class LoadBalanceRuleHandler {
+
+    private static final Logger s_logger = Logger.getLogger(LoadBalanceRuleHandler.class);
+
+    @Inject
+    private IPAddressDao _ipAddressDao;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private NetworkOrchestrationService _networkMgr;
+    @Inject
+    private final LoadBalancerDao _loadBalancerDao = null;
+    @Inject
+    private LoadBalancingRulesManager _lbMgr;
+    @Inject
+    private final DomainRouterDao _routerDao = null;
+    @Inject
+    protected HostPodDao _podDao = null;
+    @Inject
+    protected ClusterDao _clusterDao;
+    @Inject
+    private final DataCenterDao _dcDao = null;
+    @Inject
+    private IpAddressManager _ipAddrMgr;
+    @Inject
+    protected NetworkDao _networkDao;
+    @Inject
+    protected NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    private final VMTemplateDao _templateDao = null;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private AccountService _accountService;
+    @Inject
+    private LoadBalancerDao _lbDao;
+    @Inject
+    private PodVlanMapDao _podVlanMapDao;
+    @Inject
+    private ElasticLbVmMapDao _elbVmMapDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Inject
+    private VirtualRouterProviderDao _vrProviderDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private UserDao _userDao;
+
+    static final private String ELB_VM_NAME_PREFIX = "l";
+
+    private final String _instance;
+    private final Account _systemAcct;
+
+    public LoadBalanceRuleHandler(String instance, Account systemAcct) {
+        _instance = instance;
+        _systemAcct = systemAcct;
+    }
+
+    public void handleDeleteLoadBalancerRule(final LoadBalancer lb, final long userId, final Account caller) {
+        final List<LoadBalancerVO> remainingLbs = _loadBalancerDao.listByIpAddress(lb.getSourceIpAddressId());
+        if (remainingLbs.size() == 0) {
+            s_logger.debug("ELB mgr: releasing ip " + lb.getSourceIpAddressId() + " since  no LB rules remain for this ip address");
+            releaseIp(lb.getSourceIpAddressId(), userId, caller);
+        }
+    }
+
+    public LoadBalancer handleCreateLoadBalancerRule(final CreateLoadBalancerRuleCmd lb, Account account, final long networkId) throws InsufficientAddressCapacityException,
+    NetworkRuleConflictException {
+        //this part of code is executed when the LB provider is Elastic Load Balancer vm
+        if (!_networkModel.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, Provider.ElasticLoadBalancerVm)) {
+            return null;
+        }
+
+        final Long ipId = lb.getSourceIpAddressId();
+        if (ipId != null) {
+            return null;
+        }
+
+        account = _accountDao.acquireInLockTable(account.getId());
+        if (account == null) {
+            s_logger.warn("ELB: CreateLoadBalancer: Failed to acquire lock on account");
+            throw new CloudRuntimeException("Failed to acquire lock on account");
+        }
+        try {
+            return handleCreateLoadBalancerRuleWithLock(lb, account, networkId);
+        } finally {
+            if (account != null) {
+                _accountDao.releaseFromLockTable(account.getId());
+            }
+        }
+    }
+
+    private DomainRouterVO deployLoadBalancerVM(final Long networkId, final IPAddressVO ipAddr) {
+        final NetworkVO network = _networkDao.findById(networkId);
+        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        final Long podId = getPodIdForDirectIp(ipAddr);
+        final Pod pod = podId == null ? null : _podDao.findById(podId);
+        final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
+        params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
+        final Account owner = _accountService.getActiveAccountByName("system", new Long(1));
+        final DeployDestination dest = new DeployDestination(dc, pod, null, null);
+        s_logger.debug("About to deploy ELB vm ");
+
+        try {
+            final DomainRouterVO elbVm = deployELBVm(network, dest, owner, params);
+            if (elbVm == null) {
+                throw new InvalidParameterValueException("Could not deploy or find existing ELB VM");
+            }
+            s_logger.debug("Deployed ELB  vm = " + elbVm);
+
+            return elbVm;
+
+        } catch (final Throwable t) {
+            s_logger.warn("Error while deploying ELB VM:  ", t);
+            return null;
+        }
+
+    }
+
+    private DomainRouterVO deployELBVm(Network guestNetwork, final DeployDestination dest, Account owner, final Map<Param, Object> params) throws ConcurrentOperationException,
+    InsufficientCapacityException {
+        final long dcId = dest.getDataCenter().getId();
+
+        // lock guest network
+        final Long guestNetworkId = guestNetwork.getId();
+        guestNetwork = _networkDao.acquireInLockTable(guestNetworkId);
+
+        if (guestNetwork == null) {
+            throw new ConcurrentOperationException("Unable to acquire network lock: " + guestNetworkId);
+        }
+
+        try {
+
+            if (_networkModel.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) {
+                owner = _accountService.getSystemAccount();
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Starting a ELB vm for network configurations: " + guestNetwork + " in " + dest);
+            }
+            assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: "
+                    + guestNetwork;
+
+            DataCenterDeployment plan = null;
+            DomainRouterVO elbVm = null;
+
+            plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null, null);
+
+            if (elbVm == null) {
+                final long id = _routerDao.getNextInSequence(Long.class, "id");
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Creating the ELB vm " + id);
+                }
+
+                final List<? extends NetworkOffering> offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
+                final NetworkOffering controlOffering = offerings.get(0);
+                final Network controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0);
+
+                final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(2);
+                final NicProfile guestNic = new NicProfile();
+                guestNic.setDefaultNic(true);
+                networks.put(controlConfig, new ArrayList<NicProfile>());
+                networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(guestNic)));
+
+                final VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId);
+
+                final String typeString = "ElasticLoadBalancerVm";
+                final Long physicalNetworkId = _networkModel.getPhysicalNetworkId(guestNetwork);
+                final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, typeString);
+                if (provider == null) {
+                    throw new CloudRuntimeException("Cannot find service provider " + typeString + " in physical network " + physicalNetworkId);
+                }
+                final VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), Type.ElasticLoadBalancerVm);
+                if (vrProvider == null) {
+                    throw new CloudRuntimeException("Cannot find virtual router provider " + typeString + " as service provider " + provider.getId());
+                }
+
+                long userId = CallContext.current().getCallingUserId();
+                if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
+                    List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
+                    if (!userVOs.isEmpty()) {
+                        userId =  userVOs.get(0).getId();
+                    }
+                }
+
+                ServiceOfferingVO elasticLbVmOffering = _serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.elbVmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dest.getDataCenter().getId()));
+                elbVm = new DomainRouterVO(id, elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, ELB_VM_NAME_PREFIX),
+                        template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN,
+                        elasticLbVmOffering.isOfferHA(), false, null);
+                elbVm.setRole(Role.LB);
+                elbVm = _routerDao.persist(elbVm);
+                _itMgr.allocate(elbVm.getInstanceName(), template, elasticLbVmOffering, networks, plan, null);
+                elbVm = _routerDao.findById(elbVm.getId());
+                //TODO: create usage stats
+            }
+
+            final State state = elbVm.getState();
+            if (state != State.Running) {
+                elbVm = start(elbVm, params);
+            }
+
+            return elbVm;
+        } finally {
+            _networkDao.releaseFromLockTable(guestNetworkId);
+        }
+    }
+
+    private void releaseIp(final long ipId, final long userId, final Account caller) {
+        s_logger.info("ELB: Release public IP for loadbalancing " + ipId);
+        final IPAddressVO ipvo = _ipAddressDao.findById(ipId);
+        ipvo.setAssociatedWithNetworkId(null);
+        _ipAddressDao.update(ipvo.getId(), ipvo);
+        _ipAddrMgr.disassociatePublicIpAddress(ipId, userId, caller);
+        _ipAddressDao.unassignIpAddress(ipId);
+    }
+
+    protected Long getPodIdForDirectIp(final IPAddressVO ipAddr) {
+        final PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(ipAddr.getVlanId());
+        if (podVlanMaps == null) {
+            return null;
+        } else {
+            return podVlanMaps.getPodId();
+        }
+    }
+
+    private LoadBalancer handleCreateLoadBalancerRuleWithLock(final CreateLoadBalancerRuleCmd lb, final Account account, final long networkId) throws InsufficientAddressCapacityException,
+    NetworkRuleConflictException {
+        Long ipId = null;
+        boolean newIp = false;
+        List<LoadBalancerVO> existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), lb.getSourcePortStart());
+        if (existingLbs == null) {
+            existingLbs = findExistingLoadBalancers(lb.getName(), lb.getSourceIpAddressId(), lb.getAccountId(), lb.getDomainId(), null);
+            if (existingLbs == null) {
+                if (lb.getSourceIpAddressId() != null) {
+                    throwExceptionIfSuppliedlLbNameIsNotAssociatedWithIpAddress(lb);
+                } else {
+                    s_logger.debug("Could not find any existing frontend ips for this account for this LB rule, acquiring a new frontent IP for ELB");
+                    final PublicIp ip = allocDirectIp(account, networkId);
+                    ipId = ip.getId();
+                    newIp = true;
+                }
+            } else {
+                ipId = existingLbs.get(0).getSourceIpAddressId();
+                s_logger.debug("ELB: Found existing frontend ip for this account for this LB rule " + ipId);
+            }
+        } else {
+            s_logger.warn("ELB: Found existing load balancers matching requested new LB");
+            throw new NetworkRuleConflictException("ELB: Found existing load balancers matching requested new LB");
+        }
+
+        final IPAddressVO ipAddr = _ipAddressDao.findById(ipId);
+
+        LoadBalancer result = null;
+        try {
+            lb.setSourceIpAddressId(ipId);
+
+            result = _lbMgr.createPublicLoadBalancer(lb.getXid(), lb.getName(), lb.getDescription(), lb.getSourcePortStart(), lb.getDefaultPortStart(), ipId.longValue(),
+                    lb.getProtocol(), lb.getAlgorithm(), false, CallContext.current(), lb.getLbProtocol(), true);
+        } catch (final NetworkRuleConflictException e) {
+            s_logger.warn("Failed to create LB rule, not continuing with ELB deployment");
+            if (newIp) {
+                releaseIp(ipId, CallContext.current().getCallingUserId(), account);
+            }
+            throw e;
+        }
+
+        DomainRouterVO elbVm = null;
+
+        if (existingLbs == null) {
+            elbVm = findElbVmWithCapacity(ipAddr);
+            if (elbVm == null) {
+                elbVm = deployLoadBalancerVM(networkId, ipAddr);
+                if (elbVm == null) {
+                    final Network network = _networkModel.getNetwork(networkId);
+                    s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName());
+                    if (newIp) {
+                        releaseIp(ipId, CallContext.current().getCallingUserId(), account);
+                    }
+                }
+            }
+
+        } else {
+            final ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(ipId);
+            if (elbVmMap != null) {
+                elbVm = _routerDao.findById(elbVmMap.getElbVmId());
+            }
+        }
+
+        if (elbVm == null) {
+            s_logger.warn("No ELB VM can be found or deployed");
+            s_logger.warn("Deleting LB since we failed to deploy ELB VM");
+            _lbDao.remove(result.getId());
+            return null;
+        }
+
+        final ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId(), result.getId());
+        _elbVmMapDao.persist(mapping);
+        return result;
+    }
+
+    private void throwExceptionIfSuppliedlLbNameIsNotAssociatedWithIpAddress(final CreateLoadBalancerRuleCmd lb) {
+        final List<LoadBalancerVO> existingLbs = findExistingLoadBalancers(lb.getName(), null, lb.getAccountId(), lb.getDomainId(), null);
+        if (existingLbs != null) {
+            throw new InvalidParameterValueException("Supplied LB name " + lb.getName() + " is not associated with IP " + lb.getSourceIpAddressId());
+        }
+    }
+
+    protected List<LoadBalancerVO> findExistingLoadBalancers(final String lbName, final Long ipId, final Long accountId, final Long domainId, final Integer publicPort) {
+        final SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+        sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
+        if (ipId != null) {
+            sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
+        }
+        if (domainId != null) {
+            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+        }
+        if (publicPort != null) {
+            sb.and("publicPort", sb.entity().getSourcePortStart(), SearchCriteria.Op.EQ);
+        }
+        final SearchCriteria<LoadBalancerVO> sc = sb.create();
+        sc.setParameters("name", lbName);
+        sc.setParameters("accountId", accountId);
+        if (ipId != null) {
+            sc.setParameters("sourceIpAddress", ipId);
+        }
+        if (domainId != null) {
+            sc.setParameters("domainId", domainId);
+        }
+        if (publicPort != null) {
+            sc.setParameters("publicPort", publicPort);
+        }
+        final List<LoadBalancerVO> lbs = _lbDao.search(sc, null);
+
+        return lbs == null || lbs.size() == 0 ? null : lbs;
+    }
+
+    @DB
+    private PublicIp allocDirectIp(final Account account, final long guestNetworkId) throws InsufficientAddressCapacityException {
+        return Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
+            @Override
+            public PublicIp doInTransaction(final TransactionStatus status) throws InsufficientAddressCapacityException {
+                final Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId);
+
+                final PublicIp ip = _ipAddrMgr.assignPublicIpAddress(frontEndNetwork.getDataCenterId(), null, account, VlanType.DirectAttached, frontEndNetwork.getId(), null, true, false);
+                final IPAddressVO ipvo = _ipAddressDao.findById(ip.getId());
+                ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId());
+                _ipAddressDao.update(ipvo.getId(), ipvo);
+                s_logger.info("Acquired frontend IP for ELB " + ip);
+
+                return ip;
+            }
+        });
+    }
+
+    protected DomainRouterVO findElbVmWithCapacity(final IPAddressVO ipAddr) {
+        final List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms();
+        if (unusedElbVms.size() > 0) {
+            final List<DomainRouterVO> candidateVms = new ArrayList<DomainRouterVO>();
+            for (final DomainRouterVO candidateVm : unusedElbVms) {
+                addCandidateVmIsPodIpMatches(candidateVm, getPodIdForDirectIp(ipAddr), candidateVms);
+            }
+            return candidateVms.size() == 0 ? null : candidateVms.get(new Random().nextInt(candidateVms.size()));
+        }
+        return null;
+    }
+
+    protected static void addCandidateVmIsPodIpMatches(final DomainRouterVO candidateVm, final Long podIdForDirectIp, final List<DomainRouterVO> candidateVms) {
+        if (candidateVm.getPodIdToDeployIn().equals(podIdForDirectIp)) {
+            candidateVms.add(candidateVm);
+        }
+    }
+
+    protected DomainRouterVO start(final DomainRouterVO elbVm, final Map<Param, Object> params) throws ConcurrentOperationException {
+        s_logger.debug("Starting ELB VM " + elbVm);
+        _itMgr.start(elbVm.getUuid(), params);
+        return _routerDao.findById(elbVm.getId());
+    }
+}
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/dao/ElasticLbVmMapDao.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/dao/ElasticLbVmMapDao.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/dao/ElasticLbVmMapDao.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/dao/ElasticLbVmMapDao.java
diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java
rename to plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java
diff --git a/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/module.properties b/plugins/network-elements/elastic-loadbalancer/src/main/resources/META-INF/cloudstack/elb/module.properties
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/module.properties
rename to plugins/network-elements/elastic-loadbalancer/src/main/resources/META-INF/cloudstack/elb/module.properties
diff --git a/plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/spring-elb-context.xml b/plugins/network-elements/elastic-loadbalancer/src/main/resources/META-INF/cloudstack/elb/spring-elb-context.xml
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/resources/META-INF/cloudstack/elb/spring-elb-context.xml
rename to plugins/network-elements/elastic-loadbalancer/src/main/resources/META-INF/cloudstack/elb/spring-elb-context.xml
diff --git a/plugins/network-elements/elastic-loadbalancer/test/com/cloud/network/lb/ElasticLoadBalancerManagerImplTest.java b/plugins/network-elements/elastic-loadbalancer/src/test/java/com/cloud/network/lb/ElasticLoadBalancerManagerImplTest.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/test/com/cloud/network/lb/ElasticLoadBalancerManagerImplTest.java
rename to plugins/network-elements/elastic-loadbalancer/src/test/java/com/cloud/network/lb/ElasticLoadBalancerManagerImplTest.java
diff --git a/plugins/network-elements/elastic-loadbalancer/test/com/cloud/network/lb/LoadBalanceRuleHandlerTest.java b/plugins/network-elements/elastic-loadbalancer/src/test/java/com/cloud/network/lb/LoadBalanceRuleHandlerTest.java
similarity index 100%
rename from plugins/network-elements/elastic-loadbalancer/test/com/cloud/network/lb/LoadBalanceRuleHandlerTest.java
rename to plugins/network-elements/elastic-loadbalancer/src/test/java/com/cloud/network/lb/LoadBalanceRuleHandlerTest.java
diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml
index bc2e09d..1f6f230 100644
--- a/plugins/network-elements/f5/pom.xml
+++ b/plugins/network-elements/f5/pom.xml
@@ -1,49 +1,49 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-f5</artifactId>
-  <name>Apache CloudStack Plugin - F5</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis-jaxrpc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.cloud.com.f5</groupId>
-      <artifactId>icontrol</artifactId>
-      <version>12.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis</artifactId>
-    </dependency>
-   <dependency>
-      <groupId>commons-discovery</groupId>
-       <artifactId>commons-discovery</artifactId>
-       <version>0.5</version>
-   </dependency>
-  </dependencies>
+<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-network-f5</artifactId>
+    <name>Apache CloudStack Plugin - F5</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis-jaxrpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.cloud.com.f5</groupId>
+            <artifactId>icontrol</artifactId>
+            <version>12.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-discovery</groupId>
+            <artifactId>commons-discovery</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/AddExternalLoadBalancerCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/AddExternalLoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/AddExternalLoadBalancerCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/AddExternalLoadBalancerCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/AddF5LoadBalancerCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/AddF5LoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/AddF5LoadBalancerCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/AddF5LoadBalancerCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/ConfigureF5LoadBalancerCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ConfigureF5LoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/ConfigureF5LoadBalancerCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ConfigureF5LoadBalancerCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/DeleteExternalLoadBalancerCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/DeleteExternalLoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/DeleteExternalLoadBalancerCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/DeleteExternalLoadBalancerCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/DeleteF5LoadBalancerCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/DeleteF5LoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/DeleteF5LoadBalancerCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/DeleteF5LoadBalancerCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/ListExternalLoadBalancersCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListExternalLoadBalancersCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/ListExternalLoadBalancersCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListExternalLoadBalancersCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/ListF5LoadBalancerNetworksCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListF5LoadBalancerNetworksCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/ListF5LoadBalancerNetworksCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListF5LoadBalancerNetworksCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/commands/ListF5LoadBalancersCmd.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListF5LoadBalancersCmd.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/commands/ListF5LoadBalancersCmd.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/commands/ListF5LoadBalancersCmd.java
diff --git a/plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java b/plugins/network-elements/f5/src/main/java/com/cloud/api/response/F5LoadBalancerResponse.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/api/response/F5LoadBalancerResponse.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/api/response/F5LoadBalancerResponse.java
diff --git a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java b/plugins/network-elements/f5/src/main/java/com/cloud/network/element/F5ExternalLoadBalancerElement.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/network/element/F5ExternalLoadBalancerElement.java
diff --git a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElementService.java b/plugins/network-elements/f5/src/main/java/com/cloud/network/element/F5ExternalLoadBalancerElementService.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElementService.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/network/element/F5ExternalLoadBalancerElementService.java
diff --git a/plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java b/plugins/network-elements/f5/src/main/java/com/cloud/network/resource/F5BigIpResource.java
similarity index 100%
rename from plugins/network-elements/f5/src/com/cloud/network/resource/F5BigIpResource.java
rename to plugins/network-elements/f5/src/main/java/com/cloud/network/resource/F5BigIpResource.java
diff --git a/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties b/plugins/network-elements/f5/src/main/resources/META-INF/cloudstack/f5/module.properties
similarity index 100%
rename from plugins/network-elements/f5/resources/META-INF/cloudstack/f5/module.properties
rename to plugins/network-elements/f5/src/main/resources/META-INF/cloudstack/f5/module.properties
diff --git a/plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml b/plugins/network-elements/f5/src/main/resources/META-INF/cloudstack/f5/spring-f5-context.xml
similarity index 100%
rename from plugins/network-elements/f5/resources/META-INF/cloudstack/f5/spring-f5-context.xml
rename to plugins/network-elements/f5/src/main/resources/META-INF/cloudstack/f5/spring-f5-context.xml
diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml
index afbcb55..ba93f1a 100644
--- a/plugins/network-elements/globodns/pom.xml
+++ b/plugins/network-elements/globodns/pom.xml
@@ -1,37 +1,36 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-globodns</artifactId>
-  <name>Apache CloudStack Plugin - GloboDNS</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>com.globo.globodns</groupId>
-      <artifactId>globodns-client</artifactId>
-      <version>0.0.23</version>
-    </dependency>
-  </dependencies>
+    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-network-globodns</artifactId>
+    <name>Apache CloudStack Plugin - GloboDNS</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>com.globo.globodns</groupId>
+            <artifactId>globodns-client</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/api/AddGloboDnsHostCmd.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/CreateOrUpdateDomainCommand.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/CreateOrUpdateDomainCommand.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/CreateOrUpdateDomainCommand.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/CreateOrUpdateDomainCommand.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/CreateOrUpdateRecordAndReverseCommand.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/CreateOrUpdateRecordAndReverseCommand.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/CreateOrUpdateRecordAndReverseCommand.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/CreateOrUpdateRecordAndReverseCommand.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/RemoveDomainCommand.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/RemoveDomainCommand.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/RemoveDomainCommand.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/RemoveDomainCommand.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/RemoveRecordCommand.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/RemoveRecordCommand.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/RemoveRecordCommand.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/RemoveRecordCommand.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/SignInCommand.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/SignInCommand.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/commands/SignInCommand.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/commands/SignInCommand.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/element/GloboDnsElement.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/element/GloboDnsElement.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/element/GloboDnsElementService.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElementService.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/element/GloboDnsElementService.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElementService.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/resource/GloboDnsResource.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/resource/GloboDnsResource.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/resource/GloboDnsResource.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/resource/GloboDnsResource.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsDomainListResponse.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsDomainListResponse.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsDomainListResponse.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsDomainListResponse.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsDomainResponse.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsDomainResponse.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsDomainResponse.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsDomainResponse.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsExportResponse.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsExportResponse.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsExportResponse.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsExportResponse.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsRecordListResponse.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsRecordListResponse.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsRecordListResponse.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsRecordListResponse.java
diff --git a/plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsRecordResponse.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsRecordResponse.java
similarity index 100%
rename from plugins/network-elements/globodns/src/com/globo/globodns/cloudstack/response/GloboDnsRecordResponse.java
rename to plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/response/GloboDnsRecordResponse.java
diff --git a/plugins/network-elements/globodns/resources/META-INF/cloudstack/globodns/module.properties b/plugins/network-elements/globodns/src/main/resources/META-INF/cloudstack/globodns/module.properties
similarity index 100%
rename from plugins/network-elements/globodns/resources/META-INF/cloudstack/globodns/module.properties
rename to plugins/network-elements/globodns/src/main/resources/META-INF/cloudstack/globodns/module.properties
diff --git a/plugins/network-elements/globodns/resources/META-INF/cloudstack/globodns/spring-globodns-context.xml b/plugins/network-elements/globodns/src/main/resources/META-INF/cloudstack/globodns/spring-globodns-context.xml
similarity index 100%
rename from plugins/network-elements/globodns/resources/META-INF/cloudstack/globodns/spring-globodns-context.xml
rename to plugins/network-elements/globodns/src/main/resources/META-INF/cloudstack/globodns/spring-globodns-context.xml
diff --git a/plugins/network-elements/globodns/test/com/globo/globodns/cloudstack/element/GloboDnsElementTest.java b/plugins/network-elements/globodns/src/test/java/com/globo/globodns/cloudstack/element/GloboDnsElementTest.java
similarity index 100%
rename from plugins/network-elements/globodns/test/com/globo/globodns/cloudstack/element/GloboDnsElementTest.java
rename to plugins/network-elements/globodns/src/test/java/com/globo/globodns/cloudstack/element/GloboDnsElementTest.java
diff --git a/plugins/network-elements/globodns/test/com/globo/globodns/cloudstack/resource/GloboDnsResourceTest.java b/plugins/network-elements/globodns/src/test/java/com/globo/globodns/cloudstack/resource/GloboDnsResourceTest.java
similarity index 100%
rename from plugins/network-elements/globodns/test/com/globo/globodns/cloudstack/resource/GloboDnsResourceTest.java
rename to plugins/network-elements/globodns/src/test/java/com/globo/globodns/cloudstack/resource/GloboDnsResourceTest.java
diff --git a/plugins/network-elements/globodns/test/resources/db.properties b/plugins/network-elements/globodns/src/test/resources/db.properties
similarity index 100%
rename from plugins/network-elements/globodns/test/resources/db.properties
rename to plugins/network-elements/globodns/src/test/resources/db.properties
diff --git a/plugins/network-elements/globodns/test/resources/log4j.properties b/plugins/network-elements/globodns/src/test/resources/log4j.properties
similarity index 100%
rename from plugins/network-elements/globodns/test/resources/log4j.properties
rename to plugins/network-elements/globodns/src/test/resources/log4j.properties
diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml
index a07da43..8db1ae1 100644
--- a/plugins/network-elements/internal-loadbalancer/pom.xml
+++ b/plugins/network-elements/internal-loadbalancer/pom.xml
@@ -1,50 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-internallb</artifactId>
-  <name>Apache CloudStack Plugin - Network Internal Load Balancer</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>resources</directory>
-        <includes>
-          <include>**/*.xml</include>
-        </includes>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>test/resources</directory>
-          <excludes>
-              <exclude>%regex[.*[0-9]*To[0-9]*.*Test.*]</exclude>
-          </excludes>
-      </testResource>
-    </testResources>
-  </build>
+<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-network-internallb</artifactId>
+    <name>Apache CloudStack Plugin - Network Internal Load Balancer</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
rename to plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java
rename to plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManager.java
diff --git a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
rename to plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/lb/InternalLoadBalancerVMManagerImpl.java
diff --git a/plugins/network-elements/internal-loadbalancer/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml b/plugins/network-elements/internal-loadbalancer/src/main/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml
rename to plugins/network-elements/internal-loadbalancer/src/main/resources/META-INF/cloudstack/core/spring-internallb-core-context.xml
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/InternalLbElementServiceTest.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/InternalLbElementTest.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/InternalLbElementTest.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbelement/InternalLbElementTest.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/InternalLBVMManagerTest.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/InternalLBVMServiceTest.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java
rename to plugins/network-elements/internal-loadbalancer/src/test/java/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java
diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml b/plugins/network-elements/internal-loadbalancer/src/test/resources/lb_element.xml
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/resources/lb_element.xml
rename to plugins/network-elements/internal-loadbalancer/src/test/resources/lb_element.xml
diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml b/plugins/network-elements/internal-loadbalancer/src/test/resources/lb_mgr.xml
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/resources/lb_mgr.xml
rename to plugins/network-elements/internal-loadbalancer/src/test/resources/lb_mgr.xml
diff --git a/plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml b/plugins/network-elements/internal-loadbalancer/src/test/resources/lb_svc.xml
similarity index 100%
rename from plugins/network-elements/internal-loadbalancer/test/resources/lb_svc.xml
rename to plugins/network-elements/internal-loadbalancer/src/test/resources/lb_svc.xml
diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml
index 46900fe..fe9b10c 100644
--- a/plugins/network-elements/juniper-contrail/pom.xml
+++ b/plugins/network-elements/juniper-contrail/pom.xml
@@ -1,156 +1,142 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-contrail</artifactId>
-  <name>Apache CloudStack Plugin - Network Juniper Contrail</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <repositories>
-    <repository>
-      <id>juniper-contrail</id>
-      <url>http://juniper.github.io/contrail-maven/snapshots</url>
-    </repository>
-  </repositories>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-network-internallb</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-orchestration</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-      <exclusions>
-        <exclusion>
-           <artifactId>xml-apis</artifactId>
-           <groupId>xml-apis</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-spring-lifecycle</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-security</artifactId>
-      <version>${cs.jetty.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>net.juniper.contrail</groupId>
-      <artifactId>juniper-contrail-api</artifactId>
-      <version>1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-exec</artifactId>
-        <version>1.3</version>
-    </dependency>
-    <dependency>
-        <groupId>org.mockito</groupId>
-        <artifactId>mockito-all</artifactId>
-        <version>1.10.19</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <testResources>
-      <testResource>
-        <directory>test/resources</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <forkMode>always</forkMode>
-          <argLine>-Xmx1024m</argLine>
-	  <excludes>
-	    <exclude>**/NetworkProviderTest.java</exclude>
-	    <exclude>**/PublicNetworkTest.java</exclude>
-	    </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+<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-network-contrail</artifactId>
+    <name>Apache CloudStack Plugin - Network Juniper Contrail</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <repositories>
+        <repository>
+            <id>juniper-contrail</id>
+            <url>http://juniper.github.io/contrail-maven/snapshots</url>
+        </repository>
+    </repositories>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-hypervisor-xenserver</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-network-internallb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-orchestration</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>xml-apis</artifactId>
+                    <groupId>xml-apis</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-spring-lifecycle</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-security</artifactId>
+            <version>${cs.jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.juniper.contrail</groupId>
+            <artifactId>juniper-contrail-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-exec</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkMode>always</forkMode>
+                    <argLine>-Xmx1024m</argLine>
+                    <excludes>
+                        <exclude>**/NetworkProviderTest.java</exclude>
+                        <exclude>**/PublicNetworkTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElement.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElement.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
new file mode 100644
index 0000000..775ca7e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
@@ -0,0 +1,389 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.network.contrail.model.InstanceIpModel;
+import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+
+import net.juniper.contrail.api.types.MacAddressesType;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+
+public class ContrailGuru extends AdapterBase implements NetworkGuru {
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    ContrailManager _manager;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    DataCenterDao _dcDao;
+
+    private static final Logger s_logger = Logger.getLogger(ContrailGuru.class);
+    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
+
+    private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) {
+        if (physicalNetwork == null) {
+            // Physical network can be false for system network during initial setup of CloudStack
+            return false;
+        }
+
+        if (_manager.getRouterOffering() == null || _manager.getVpcRouterOffering() == null) {
+            // FIXME The resource is apparently not configured, we need another way to check this.
+            return false;
+        }
+
+        if (networkType == NetworkType.Advanced
+                && (offering.getId() == _manager.getRouterOffering().getId() || offering.getId() == _manager.getVpcRouterOffering().getId())
+                && isMyTrafficType(offering.getTrafficType())
+                && offering.getGuestType() == Network.GuestType.Isolated
+                && physicalNetwork.getIsolationMethods().contains("L3VPN"))
+            return true;
+
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return "ContrailGuru";
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        // Check of the isolation type of the related physical network is L3VPN
+        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        if (!canHandle(offering, dc.getNetworkType(),physnet)) {
+            s_logger.debug("Refusing to design this network");
+            return null;
+        }
+        NetworkVO network =
+                new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), State.Allocated, plan.getDataCenterId(),
+                        plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        if (userSpecified.getCidr() != null) {
+            network.setCidr(userSpecified.getCidr());
+            network.setGateway(userSpecified.getGateway());
+        }
+        s_logger.debug("Allocated network " + userSpecified.getName() + (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
+        return network;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+            throws InsufficientVirtualNetworkCapacityException {
+        s_logger.debug("Implement network: " + network.getName() + ", traffic type: " + network.getTrafficType());
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            vnModel = new VirtualNetworkModel(network, network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+            vnModel.setProperties(_manager.getModelController(), network);
+        }
+
+        try {
+            if (!vnModel.verify(_manager.getModelController())) {
+                vnModel.update(_manager.getModelController());
+            }
+        } catch (Exception ex) {
+            s_logger.warn("virtual-network update: ", ex);
+            return network;
+        }
+        _manager.getDatabase().getVirtualNetworks().add(vnModel);
+
+        if (network.getVpcId() != null) {
+            List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
+            if (ips.isEmpty()) {
+                s_logger.debug("Creating a source nat ip for network " + network);
+                Account owner = _accountMgr.getAccount(network.getAccountId());
+                try {
+                    PublicIp publicIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
+                    IPAddressVO ip = publicIp.ip();
+                    ip.setVpcId(network.getVpcId());
+                    _ipAddressDao.acquireInLockTable(ip.getId());
+                    _ipAddressDao.update(ip.getId(), ip);
+                    _ipAddressDao.releaseFromLockTable(ip.getId());
+                } catch (Exception e) {
+                    s_logger.error("Unable to allocate source nat ip: " + e);
+                }
+            }
+        }
+
+        return network;
+    }
+
+    /**
+     * Allocate the NicProfile object.
+     * At this point the UUID of the nic is not yet known. We defer allocating the VMI and instance-ip objects
+     * until the reserve API is called because of this reason.
+     */
+    @Override
+    public NicProfile allocate(Network network, NicProfile profile, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+    InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("allocate NicProfile on " + network.getName());
+
+        if (profile != null && profile.getRequestedIPv4() != null) {
+            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + profile);
+        }
+        if (profile == null) {
+            profile = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        }
+
+        profile.setReservationStrategy(ReservationStrategy.Start);
+        URI broadcastUri = null;
+        try {
+            broadcastUri = new URI("vlan://untagged");
+        } catch (Exception e) {
+            s_logger.warn("unable to instantiate broadcast URI: " + e);
+        }
+        profile.setBroadcastUri(broadcastUri);
+
+        return profile;
+    }
+
+    /**
+     * Allocate the ip address (and mac) for the specified VM device.
+     */
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("reserve NicProfile on network id: " + network.getId() + " " + network.getName());
+        s_logger.debug("deviceId: " + nic.getDeviceId());
+
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        /* Network must have been implemented */
+        assert vnModel != null;
+
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            VMInstanceVO vmVo = (VMInstanceVO)vm.getVirtualMachine();
+            vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
+            vmModel.setProperties(_manager.getModelController(), vmVo);
+        }
+
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            vmiModel = new VMInterfaceModel(nicVO.getUuid());
+            vmiModel.addToVirtualMachine(vmModel);
+            vmiModel.addToVirtualNetwork(vnModel);
+        }
+        try {
+            vmiModel.build(_manager.getModelController(), (VMInstanceVO)vm.getVirtualMachine(), nicVO);
+            vmiModel.setActive();
+        } catch (IOException ex) {
+            s_logger.error("virtual-machine-interface set", ex);
+            return;
+        }
+
+        InstanceIpModel ipModel = vmiModel.getInstanceIp();
+        if (ipModel == null) {
+            ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
+            ipModel.addToVMInterface(vmiModel);
+        } else {
+            s_logger.debug("Reuse existing instance-ip object on " + ipModel.getName());
+        }
+        if (nic.getIPv4Address() != null) {
+            s_logger.debug("Nic using existing IP address " + nic.getIPv4Address());
+            ipModel.setAddress(nic.getIPv4Address());
+        }
+
+        try {
+            vmModel.update(_manager.getModelController());
+        } catch (Exception ex) {
+            s_logger.warn("virtual-machine update", ex);
+            return;
+        }
+
+        _manager.getDatabase().getVirtualMachines().add(vmModel);
+
+        VirtualMachineInterface vmi = vmiModel.getVMInterface();
+        // allocate mac address
+        if (nic.getMacAddress() == null) {
+            MacAddressesType macs = vmi.getMacAddresses();
+            if (macs == null) {
+                s_logger.debug("no mac address is allocated for Nic " + nicVO.getUuid());
+            } else {
+                s_logger.info("VMI " + _manager.getVifNameByVmUuid(vm.getUuid(), nicVO.getDeviceId()) + " got mac address: " + macs.getMacAddress().get(0));
+                nic.setMacAddress(macs.getMacAddress().get(0));
+            }
+        }
+
+        if (nic.getIPv4Address() == null) {
+            s_logger.debug("Allocated IP address " + ipModel.getAddress());
+            nic.setIPv4Address(ipModel.getAddress());
+            if (network.getCidr() != null) {
+                nic.setIPv4Netmask(NetUtils.cidr2Netmask(network.getCidr()));
+            }
+            nic.setIPv4Gateway(network.getGateway());
+            nic.setFormat(AddressFormat.Ip4);
+        }
+    }
+
+    /**
+     * When a VM is stopped this API is called to release transient resources.
+     */
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+
+        s_logger.debug("release NicProfile " + nic.getId());
+
+        return true;
+    }
+
+    /**
+     * Release permanent resources of a Nic (VMI and addresses).
+     */
+    @Override
+    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
+        s_logger.debug("deallocate NicProfile " + nic.getId() + " on " + network.getName());
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            return;
+        }
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            return;
+        }
+        try {
+            vmiModel.destroy(_manager.getModelController());
+        } catch (IOException ex) {
+            return;
+        }
+        vmModel.removeSuccessor(vmiModel);
+
+        if (!vmModel.hasDescendents()) {
+            _manager.getDatabase().getVirtualMachines().remove(vmModel);
+            try {
+                vmModel.delete(_manager.getModelController());
+            } catch (IOException ex) {
+                s_logger.warn("virtual-machine delete", ex);
+                return;
+            }
+        }
+
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        // TODO Auto-generated method stub
+        s_logger.debug("update NicProfile " + profile.getId() + " on " + network.getName());
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering) {
+        s_logger.debug("NetworkGuru shutdown");
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            return;
+        }
+        try {
+            _manager.getDatabase().getVirtualNetworks().remove(vnModel);
+            vnModel.delete(_manager.getModelController());
+        } catch (IOException e) {
+            s_logger.warn("virtual-network delete", e);
+        }
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru trash");
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru updateNetworkProfile");
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManager.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManager.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/EventUtils.java
diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
new file mode 100644
index 0000000..6ad0746
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
@@ -0,0 +1,130 @@
+// 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.network.contrail.management;
+
+import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.PropertiesUtil;
+/**
+ * ManagementNetworkGuru
+ *
+ * Replace the default management network strategy (PodBasedNetworkGuru) by using a Isolated network for management
+ * traffic.
+ */
+@Component
+public class ManagementNetworkGuru extends ContrailGuru {
+    private static final Logger s_logger = Logger.getLogger(ManagementNetworkGuru.class);
+    private static final TrafficType[] TrafficTypes = {TrafficType.Management};
+
+    private final String configuration = "contrail.properties";
+    private String _mgmtCidr;
+    private String _mgmtGateway;
+
+    @Override
+    public String getName() {
+        return "ManagementNetworkGuru";
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        File configFile = PropertiesUtil.findConfigFile(configuration);
+        FileInputStream inputFile = null;
+
+        try {
+            if (null == configFile) {
+                throw new FileNotFoundException("Configuration file was not found!");
+            }
+            inputFile = new FileInputStream(configFile);
+        } catch (FileNotFoundException e) {
+            s_logger.error(e.getMessage());
+            throw new ConfigurationException(e.getMessage());
+        }
+
+        final Properties configProps = new Properties();
+        try {
+            configProps.load(inputFile);
+        } catch (IOException e) {
+            s_logger.error(e.getMessage());
+            throw new ConfigurationException(e.getMessage());
+        } finally {
+            closeAutoCloseable(inputFile, "error closing config file");
+        }
+        _mgmtCidr = configProps.getProperty("management.cidr");
+        _mgmtGateway = configProps.getProperty("management.gateway");
+        s_logger.info("Management network " + _mgmtCidr + " gateway: " + _mgmtGateway);
+        return true;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean canHandle(NetworkOffering offering) {
+        TrafficType type = offering.getTrafficType();
+        return (isMyTrafficType(type));
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+
+        if (!canHandle(offering)) {
+            return null;
+        }
+        NetworkVO network =
+            new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), Network.State.Allocated, plan.getDataCenterId(),
+                plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        if (_mgmtCidr != null) {
+            network.setCidr(_mgmtCidr);
+            network.setGateway(_mgmtGateway);
+        }
+        s_logger.debug("Allocated network " + userSpecified.getName() + (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
+        return network;
+    }
+
+}
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceManager.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceManager.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelController.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelController.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelObject.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelObject.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
rename to plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties b/plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/contrail/module.properties
similarity index 100%
rename from plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties
rename to plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/contrail/module.properties
diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml b/plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml
similarity index 100%
rename from plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml
rename to plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml
diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/system/spring-contrail-system-context-inheritable.xml b/plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/system/spring-contrail-system-context-inheritable.xml
similarity index 100%
rename from plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/system/spring-contrail-system-context-inheritable.xml
rename to plugins/network-elements/juniper-contrail/src/main/resources/META-INF/cloudstack/system/spring-contrail-system-context-inheritable.xml
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
deleted file mode 100644
index 364118f..0000000
--- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
+++ /dev/null
@@ -1,389 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.network.contrail.management;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.network.contrail.model.InstanceIpModel;
-import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
-import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
-import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-
-import net.juniper.contrail.api.types.MacAddressesType;
-import net.juniper.contrail.api.types.VirtualMachineInterface;
-
-public class ContrailGuru extends AdapterBase implements NetworkGuru {
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    ContrailManager _manager;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    DataCenterDao _dcDao;
-
-    private static final Logger s_logger = Logger.getLogger(ContrailGuru.class);
-    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
-
-    private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) {
-        if (physicalNetwork == null) {
-            // Physical network can be false for system network during initial setup of CloudStack
-            return false;
-        }
-
-        if (_manager.getRouterOffering() == null || _manager.getVpcRouterOffering() == null) {
-            // FIXME The resource is apparently not configured, we need another way to check this.
-            return false;
-        }
-
-        if (networkType == NetworkType.Advanced
-                && (offering.getId() == _manager.getRouterOffering().getId() || offering.getId() == _manager.getVpcRouterOffering().getId())
-                && isMyTrafficType(offering.getTrafficType())
-                && offering.getGuestType() == Network.GuestType.Isolated
-                && physicalNetwork.getIsolationMethods().contains("L3VPN"))
-            return true;
-
-        return false;
-    }
-
-    @Override
-    public String getName() {
-        return "ContrailGuru";
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        // Check of the isolation type of the related physical network is L3VPN
-        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-        if (!canHandle(offering, dc.getNetworkType(),physnet)) {
-            s_logger.debug("Refusing to design this network");
-            return null;
-        }
-        NetworkVO network =
-                new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), State.Allocated, plan.getDataCenterId(),
-                        plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        if (userSpecified.getCidr() != null) {
-            network.setCidr(userSpecified.getCidr());
-            network.setGateway(userSpecified.getGateway());
-        }
-        s_logger.debug("Allocated network " + userSpecified.getName() + (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
-        return network;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-            throws InsufficientVirtualNetworkCapacityException {
-        s_logger.debug("Implement network: " + network.getName() + ", traffic type: " + network.getTrafficType());
-
-        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
-        if (vnModel == null) {
-            vnModel = new VirtualNetworkModel(network, network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
-            vnModel.setProperties(_manager.getModelController(), network);
-        }
-
-        try {
-            if (!vnModel.verify(_manager.getModelController())) {
-                vnModel.update(_manager.getModelController());
-            }
-        } catch (Exception ex) {
-            s_logger.warn("virtual-network update: ", ex);
-            return network;
-        }
-        _manager.getDatabase().getVirtualNetworks().add(vnModel);
-
-        if (network.getVpcId() != null) {
-            List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
-            if (ips.isEmpty()) {
-                s_logger.debug("Creating a source nat ip for network " + network);
-                Account owner = _accountMgr.getAccount(network.getAccountId());
-                try {
-                    PublicIp publicIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
-                    IPAddressVO ip = publicIp.ip();
-                    ip.setVpcId(network.getVpcId());
-                    _ipAddressDao.acquireInLockTable(ip.getId());
-                    _ipAddressDao.update(ip.getId(), ip);
-                    _ipAddressDao.releaseFromLockTable(ip.getId());
-                } catch (Exception e) {
-                    s_logger.error("Unable to allocate source nat ip: " + e);
-                }
-            }
-        }
-
-        return network;
-    }
-
-    /**
-     * Allocate the NicProfile object.
-     * At this point the UUID of the nic is not yet known. We defer allocating the VMI and instance-ip objects
-     * until the reserve API is called because of this reason.
-     */
-    @Override
-    public NicProfile allocate(Network network, NicProfile profile, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-    InsufficientAddressCapacityException, ConcurrentOperationException {
-        s_logger.debug("allocate NicProfile on " + network.getName());
-
-        if (profile != null && profile.getRequestedIPv4() != null) {
-            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + profile);
-        }
-        if (profile == null) {
-            profile = new NicProfile(ReservationStrategy.Create, null, null, null, null);
-        }
-
-        profile.setReservationStrategy(ReservationStrategy.Start);
-        URI broadcastUri = null;
-        try {
-            broadcastUri = new URI("vlan://untagged");
-        } catch (Exception e) {
-            s_logger.warn("unable to instantiate broadcast URI: " + e);
-        }
-        profile.setBroadcastUri(broadcastUri);
-
-        return profile;
-    }
-
-    /**
-     * Allocate the ip address (and mac) for the specified VM device.
-     */
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-        s_logger.debug("reserve NicProfile on network id: " + network.getId() + " " + network.getName());
-        s_logger.debug("deviceId: " + nic.getDeviceId());
-
-        NicVO nicVO = _nicDao.findById(nic.getId());
-        assert nicVO != null;
-
-        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
-        /* Network must have been implemented */
-        assert vnModel != null;
-
-        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
-        if (vmModel == null) {
-            VMInstanceVO vmVo = (VMInstanceVO)vm.getVirtualMachine();
-            vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
-            vmModel.setProperties(_manager.getModelController(), vmVo);
-        }
-
-        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
-        if (vmiModel == null) {
-            vmiModel = new VMInterfaceModel(nicVO.getUuid());
-            vmiModel.addToVirtualMachine(vmModel);
-            vmiModel.addToVirtualNetwork(vnModel);
-        }
-        try {
-            vmiModel.build(_manager.getModelController(), (VMInstanceVO)vm.getVirtualMachine(), nicVO);
-            vmiModel.setActive();
-        } catch (IOException ex) {
-            s_logger.error("virtual-machine-interface set", ex);
-            return;
-        }
-
-        InstanceIpModel ipModel = vmiModel.getInstanceIp();
-        if (ipModel == null) {
-            ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
-            ipModel.addToVMInterface(vmiModel);
-        } else {
-            s_logger.debug("Reuse existing instance-ip object on " + ipModel.getName());
-        }
-        if (nic.getIPv4Address() != null) {
-            s_logger.debug("Nic using existing IP address " + nic.getIPv4Address());
-            ipModel.setAddress(nic.getIPv4Address());
-        }
-
-        try {
-            vmModel.update(_manager.getModelController());
-        } catch (Exception ex) {
-            s_logger.warn("virtual-machine update", ex);
-            return;
-        }
-
-        _manager.getDatabase().getVirtualMachines().add(vmModel);
-
-        VirtualMachineInterface vmi = vmiModel.getVMInterface();
-        // allocate mac address
-        if (nic.getMacAddress() == null) {
-            MacAddressesType macs = vmi.getMacAddresses();
-            if (macs == null) {
-                s_logger.debug("no mac address is allocated for Nic " + nicVO.getUuid());
-            } else {
-                s_logger.info("VMI " + _manager.getVifNameByVmUuid(vm.getUuid(), nicVO.getDeviceId()) + " got mac address: " + macs.getMacAddress().get(0));
-                nic.setMacAddress(macs.getMacAddress().get(0));
-            }
-        }
-
-        if (nic.getIPv4Address() == null) {
-            s_logger.debug("Allocated IP address " + ipModel.getAddress());
-            nic.setIPv4Address(ipModel.getAddress());
-            if (network.getCidr() != null) {
-                nic.setIPv4Netmask(NetUtils.cidr2Netmask(network.getCidr()));
-            }
-            nic.setIPv4Gateway(network.getGateway());
-            nic.setFormat(AddressFormat.Ip4);
-        }
-    }
-
-    /**
-     * When a VM is stopped this API is called to release transient resources.
-     */
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-
-        s_logger.debug("release NicProfile " + nic.getId());
-
-        return true;
-    }
-
-    /**
-     * Release permanent resources of a Nic (VMI and addresses).
-     */
-    @Override
-    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
-        s_logger.debug("deallocate NicProfile " + nic.getId() + " on " + network.getName());
-        NicVO nicVO = _nicDao.findById(nic.getId());
-        assert nicVO != null;
-
-        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
-        if (vmModel == null) {
-            return;
-        }
-        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
-        if (vmiModel == null) {
-            return;
-        }
-        try {
-            vmiModel.destroy(_manager.getModelController());
-        } catch (IOException ex) {
-            return;
-        }
-        vmModel.removeSuccessor(vmiModel);
-
-        if (!vmModel.hasDescendents()) {
-            _manager.getDatabase().getVirtualMachines().remove(vmModel);
-            try {
-                vmModel.delete(_manager.getModelController());
-            } catch (IOException ex) {
-                s_logger.warn("virtual-machine delete", ex);
-                return;
-            }
-        }
-
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-        // TODO Auto-generated method stub
-        s_logger.debug("update NicProfile " + profile.getId() + " on " + network.getName());
-    }
-
-    @Override
-    public void shutdown(NetworkProfile network, NetworkOffering offering) {
-        s_logger.debug("NetworkGuru shutdown");
-        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
-        if (vnModel == null) {
-            return;
-        }
-        try {
-            _manager.getDatabase().getVirtualNetworks().remove(vnModel);
-            vnModel.delete(_manager.getModelController());
-        } catch (IOException e) {
-            s_logger.warn("virtual-network delete", e);
-        }
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        // TODO Auto-generated method stub
-        s_logger.debug("NetworkGuru trash");
-        return true;
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-        // TODO Auto-generated method stub
-        s_logger.debug("NetworkGuru updateNetworkProfile");
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-}
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
deleted file mode 100644
index fd29ca9..0000000
--- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.network.contrail.management;
-
-import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.network.Network;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.PropertiesUtil;
-/**
- * ManagementNetworkGuru
- *
- * Replace the default management network strategy (PodBasedNetworkGuru) by using a Isolated network for management
- * traffic.
- */
-@Component
-public class ManagementNetworkGuru extends ContrailGuru {
-    private static final Logger s_logger = Logger.getLogger(ManagementNetworkGuru.class);
-    private static final TrafficType[] TrafficTypes = {TrafficType.Management};
-
-    private final String configuration = "contrail.properties";
-    private String _mgmtCidr;
-    private String _mgmtGateway;
-
-    @Override
-    public String getName() {
-        return "ManagementNetworkGuru";
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        File configFile = PropertiesUtil.findConfigFile(configuration);
-        FileInputStream inputFile = null;
-
-        try {
-            if (null == configFile) {
-                throw new FileNotFoundException("Configuration file was not found!");
-            }
-            inputFile = new FileInputStream(configFile);
-        } catch (FileNotFoundException e) {
-            s_logger.error(e.getMessage());
-            throw new ConfigurationException(e.getMessage());
-        }
-
-        final Properties configProps = new Properties();
-        try {
-            configProps.load(inputFile);
-        } catch (IOException e) {
-            s_logger.error(e.getMessage());
-            throw new ConfigurationException(e.getMessage());
-        } finally {
-            closeAutoCloseable(inputFile, "error closing config file");
-        }
-        _mgmtCidr = configProps.getProperty("management.cidr");
-        _mgmtGateway = configProps.getProperty("management.gateway");
-        s_logger.info("Management network " + _mgmtCidr + " gateway: " + _mgmtGateway);
-        return true;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean canHandle(NetworkOffering offering) {
-        TrafficType type = offering.getTrafficType();
-        return (isMyTrafficType(type));
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-
-        if (!canHandle(offering)) {
-            return null;
-        }
-        NetworkVO network =
-            new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch, offering.getId(), Network.State.Allocated, plan.getDataCenterId(),
-                plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        if (_mgmtCidr != null) {
-            network.setCidr(_mgmtCidr);
-            network.setGateway(_mgmtGateway);
-        }
-        s_logger.debug("Allocated network " + userSpecified.getName() + (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
-        return network;
-    }
-
-}
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
diff --git a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
new file mode 100644
index 0000000..100f380
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
@@ -0,0 +1,461 @@
+// 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.network.contrail.management;
+
+import java.util.List;
+import java.util.Map;
+import java.net.InetAddress;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+
+public class MockAccountManager extends ManagerBase implements AccountManager {
+    private static final Logger s_logger = Logger.getLogger(MockAccountManager.class);
+
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    ResourceCountDao _resourceCountDao;
+
+    @Inject
+    UserDao _userDao;
+
+    UserVO _systemUser;
+    AccountVO _systemAccount;
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
+        if (_systemAccount == null) {
+            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        _systemUser = _userDao.findById(User.UID_SYSTEM);
+        if (_systemUser == null) {
+            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
+        }
+        CallContext.register(_systemUser, _systemAccount);
+        s_logger.info("MockAccountManager initialization successful");
+        return true;
+    }
+
+    @Override
+    public void checkAccess(Account arg0, Domain arg1) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public UserAccount getUserAccountById(Long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void checkAccess(Account arg0, AccessType arg1, boolean arg2, ControlledEntity... arg3) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(RegisterCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(final long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override public User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
+                                     String userUUID, User.Source source) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, short arg7, Long roleId, Long arg8, String arg9,
+        Map<String, String> arg10, String arg11, String arg12) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId,
+                                         Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account finalizeOwner(Account arg0, String arg1, Long arg2, Long arg3) {
+        return _systemAccount;
+    }
+
+    @Override
+    public Account getActiveAccountByName(String arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount getActiveUserAccount(String username, Long domainId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getActiveUser(long arg0) {
+        return _systemUser;
+    }
+
+    @Override
+    public User getActiveUserByRegistrationToken(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RoleType getRoleType(Account arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getSystemAccount() {
+        return _systemAccount;
+    }
+
+    @Override
+    public User getSystemUser() {
+        return _systemUser;
+    }
+
+    @Override
+    public UserAccount getUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getUserIncludingRemoved(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isRootAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isDomainAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isNormalUser(long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<String> listAclGroupsByAccount(Long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount lockUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void markUserRegistered(long arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public UserAccount authenticateUser(String arg0, String arg1, Long arg2, InetAddress arg3, Map<String, Object[]> arg4) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void buildACLSearchBuilder(
+            SearchBuilder<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLSearchCriteria(
+            SearchCriteria<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLSearchParameters(Account arg0, Long arg1, String arg2,
+            Long arg3, List<Long> arg4,
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> arg5,
+            boolean arg6, boolean arg7) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean deleteAccount(AccountVO arg0, long arg1, Account arg2) {
+        return true;
+    }
+
+    @Override
+    public boolean deleteUser(DeleteUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean moveUser(MoveUserCmd moveUserCmd) {
+        return false;
+    }
+
+    @Override
+    public boolean moveUser(long id, Long domainId, long accountId) {
+        return false;
+    }
+
+    @Override
+    public boolean deleteUserAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean disableAccount(long arg0) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account disableAccount(String arg0, Long arg1, Long arg2) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount disableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean enableAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account enableAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount enableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<User, Account> findUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account lockAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account updateAccount(UpdateAccountCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount updateUser(UpdateUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getActiveAccountById(long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getAccount(long accountId) {
+        return _systemAccount;
+    }
+
+    @Override
+    public Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
+        final AccountVO account = new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid);
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+
+                _accountDao.persist(account);
+                _resourceCountDao.createResourceCounts(account.getId(), ResourceLimit.ResourceOwnerType.Account);
+            }
+        });
+        return account;
+    }
+
+    @Override
+    public void logoutUser(long userId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
+            ControlledEntity... entities) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Map<String, String> getKeys(GetUserKeysCmd cmd){
+        return null;
+    }
+
+    @Override
+    public void checkAccess(User user, ControlledEntity entity)
+            throws PermissionDeniedException {
+
+    }
+    @Override
+    public String getConfigComponentName() {
+        return null;
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return null;
+    }
+}
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/InstanceIpModelTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/InstanceIpModelTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/InstanceIpModelTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/InstanceIpModelTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VMInterfaceModelTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VMInterfaceModelTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VMInterfaceModelTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VMInterfaceModelTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VirtualMachineModelTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VirtualMachineModelTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VirtualMachineModelTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VirtualMachineModelTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VirtualNetworkModelTest.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VirtualNetworkModelTest.java
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/model/VirtualNetworkModelTest.java
rename to plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/model/VirtualNetworkModelTest.java
diff --git a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml b/plugins/network-elements/juniper-contrail/src/test/resources/commonContext.xml
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/commonContext.xml
rename to plugins/network-elements/juniper-contrail/src/test/resources/commonContext.xml
diff --git a/plugins/network-elements/juniper-contrail/test/resources/contrail.properties b/plugins/network-elements/juniper-contrail/src/test/resources/contrail.properties
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/contrail.properties
rename to plugins/network-elements/juniper-contrail/src/test/resources/contrail.properties
diff --git a/plugins/network-elements/juniper-contrail/test/resources/db.properties b/plugins/network-elements/juniper-contrail/src/test/resources/db.properties
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/db.properties
rename to plugins/network-elements/juniper-contrail/src/test/resources/db.properties
diff --git a/plugins/network-elements/juniper-contrail/test/resources/log4j.properties b/plugins/network-elements/juniper-contrail/src/test/resources/log4j.properties
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/log4j.properties
rename to plugins/network-elements/juniper-contrail/src/test/resources/log4j.properties
diff --git a/plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh b/plugins/network-elements/juniper-contrail/src/test/resources/mysql_db_start.sh
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh
rename to plugins/network-elements/juniper-contrail/src/test/resources/mysql_db_start.sh
diff --git a/plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh b/plugins/network-elements/juniper-contrail/src/test/resources/mysql_db_stop.sh
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh
rename to plugins/network-elements/juniper-contrail/src/test/resources/mysql_db_stop.sh
diff --git a/plugins/network-elements/juniper-contrail/test/resources/providerContext.xml b/plugins/network-elements/juniper-contrail/src/test/resources/providerContext.xml
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/providerContext.xml
rename to plugins/network-elements/juniper-contrail/src/test/resources/providerContext.xml
diff --git a/plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml b/plugins/network-elements/juniper-contrail/src/test/resources/publicNetworkContext.xml
similarity index 100%
rename from plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml
rename to plugins/network-elements/juniper-contrail/src/test/resources/publicNetworkContext.xml
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
deleted file mode 100644
index 37ca2bc..0000000
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
+++ /dev/null
@@ -1,468 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.network.contrail.management;
-
-import java.util.List;
-import java.util.Map;
-import java.net.InetAddress;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.api.query.vo.ControlledViewEntity;
-import com.cloud.configuration.ResourceLimit;
-import com.cloud.configuration.dao.ResourceCountDao;
-import com.cloud.domain.Domain;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-
-public class MockAccountManager extends ManagerBase implements AccountManager {
-    private static final Logger s_logger = Logger.getLogger(MockAccountManager.class);
-
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    ResourceCountDao _resourceCountDao;
-
-    @Inject
-    UserDao _userDao;
-
-    UserVO _systemUser;
-    AccountVO _systemAccount;
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
-        if (_systemAccount == null) {
-            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
-        }
-
-        _systemUser = _userDao.findById(User.UID_SYSTEM);
-        if (_systemUser == null) {
-            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
-        }
-        CallContext.register(_systemUser, _systemAccount);
-        s_logger.info("MockAccountManager initialization successful");
-        return true;
-    }
-
-    @Override
-    public void checkAccess(Account arg0, Domain arg1) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public UserAccount getUserAccountById(Long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void checkAccess(Account arg0, AccessType arg1, boolean arg2, ControlledEntity... arg3) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public String[] createApiKeyAndSecretKey(RegisterCmd arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] createApiKeyAndSecretKey(final long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override public User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
-                                     String userUUID, User.Source source) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount createUserAccount(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, short arg7, Long roleId, Long arg8, String arg9,
-        Map<String, String> arg10, String arg11, String arg12) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId,
-                                         Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account finalizeOwner(Account arg0, String arg1, Long arg2, Long arg3) {
-        return _systemAccount;
-    }
-
-    @Override
-    public Account getActiveAccountByName(String arg0, Long arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount getActiveUserAccount(String username, Long domainId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
-                                  String timeZone) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User getActiveUser(long arg0) {
-        return _systemUser;
-    }
-
-    @Override
-    public User getActiveUserByRegistrationToken(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public RoleType getRoleType(Account arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getSystemAccount() {
-        return _systemAccount;
-    }
-
-    @Override
-    public User getSystemUser() {
-        return _systemUser;
-    }
-
-    @Override
-    public UserAccount getUserByApiKey(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User getUserIncludingRemoved(long arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isRootAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isDomainAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isNormalUser(long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public List<String> listAclGroupsByAccount(Long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount lockUser(long arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void markUserRegistered(long arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public UserAccount authenticateUser(String arg0, String arg1, Long arg2, InetAddress arg3, Map<String, Object[]> arg4) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void buildACLSearchBuilder(
-            SearchBuilder<? extends ControlledEntity> arg0, Long arg1,
-            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchCriteria(
-            SearchCriteria<? extends ControlledEntity> arg0, Long arg1,
-            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchParameters(Account arg0, Long arg1, String arg2,
-            Long arg3, List<Long> arg4,
-            Ternary<Long, Boolean, ListProjectResourcesCriteria> arg5,
-            boolean arg6, boolean arg7) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean deleteAccount(AccountVO arg0, long arg1, Account arg2) {
-        return true;
-    }
-
-    @Override
-    public boolean deleteUser(DeleteUserCmd arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean moveUser(MoveUserCmd moveUserCmd) {
-        return false;
-    }
-
-    @Override
-    public boolean moveUser(long id, Long domainId, long accountId) {
-        return false;
-    }
-
-    @Override
-    public boolean deleteUserAccount(long arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean disableAccount(long arg0) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Account disableAccount(String arg0, Long arg1, Long arg2) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount disableUser(long arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean enableAccount(long arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Account enableAccount(String arg0, Long arg1, Long arg2) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount enableUser(long arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Pair<User, Account> findUserByApiKey(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account lockAccount(String arg0, Long arg1, Long arg2) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account updateAccount(UpdateAccountCmd arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount updateUser(UpdateUserCmd arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getActiveAccountById(long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getAccount(long accountId) {
-        return _systemAccount;
-    }
-
-    @Override
-    public Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
-        final AccountVO account = new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid);
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-
-                _accountDao.persist(account);
-                _resourceCountDao.createResourceCounts(account.getId(), ResourceLimit.ResourceOwnerType.Account);
-            }
-        });
-        return account;
-    }
-
-    @Override
-    public void logoutUser(long userId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
-            ControlledEntity... entities) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Map<String, String> getKeys(GetUserKeysCmd cmd){
-        return null;
-    }
-
-    @Override
-    public void checkAccess(User user, ControlledEntity entity)
-            throws PermissionDeniedException {
-
-    }
-    @Override
-    public String getConfigComponentName() {
-        return null;
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return null;
-    }
-}
diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml
index 0c31365..34c85dc 100644
--- a/plugins/network-elements/juniper-srx/pom.xml
+++ b/plugins/network-elements/juniper-srx/pom.xml
@@ -1,40 +1,41 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-srx</artifactId>
-  <name>Apache CloudStack Plugin - Juniper SRX</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>com.cloud.com.f5</groupId>
-      <artifactId>icontrol</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis</artifactId>
-    </dependency>
-  </dependencies>
+<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-network-srx</artifactId>
+    <name>Apache CloudStack Plugin - Juniper SRX</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>com.cloud.com.f5</groupId>
+            <artifactId>icontrol</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/AddExternalFirewallCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/AddExternalFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/AddExternalFirewallCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/AddExternalFirewallCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/AddSrxFirewallCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/AddSrxFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/AddSrxFirewallCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/AddSrxFirewallCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ConfigureSrxFirewallCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ConfigureSrxFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ConfigureSrxFirewallCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ConfigureSrxFirewallCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/DeleteExternalFirewallCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/DeleteExternalFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/DeleteExternalFirewallCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/DeleteExternalFirewallCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/DeleteSrxFirewallCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/DeleteSrxFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/DeleteSrxFirewallCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/DeleteSrxFirewallCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListExternalFirewallsCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListExternalFirewallsCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListExternalFirewallsCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListExternalFirewallsCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListSrxFirewallNetworksCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListSrxFirewallNetworksCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListSrxFirewallNetworksCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListSrxFirewallNetworksCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListSrxFirewallsCmd.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListSrxFirewallsCmd.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/commands/ListSrxFirewallsCmd.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/commands/ListSrxFirewallsCmd.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/api/response/SrxFirewallResponse.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/response/SrxFirewallResponse.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/api/response/SrxFirewallResponse.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/api/response/SrxFirewallResponse.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXFirewallElementService.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/element/JuniperSRXFirewallElementService.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXFirewallElementService.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/element/JuniperSRXFirewallElementService.java
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java b/plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/resource/JuniperSrxResource.java
similarity index 100%
rename from plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java
rename to plugins/network-elements/juniper-srx/src/main/java/com/cloud/network/resource/JuniperSrxResource.java
diff --git a/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties b/plugins/network-elements/juniper-srx/src/main/resources/META-INF/cloudstack/srx/module.properties
similarity index 100%
rename from plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/module.properties
rename to plugins/network-elements/juniper-srx/src/main/resources/META-INF/cloudstack/srx/module.properties
diff --git a/plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml b/plugins/network-elements/juniper-srx/src/main/resources/META-INF/cloudstack/srx/spring-srx-context.xml
similarity index 100%
rename from plugins/network-elements/juniper-srx/resources/META-INF/cloudstack/srx/spring-srx-context.xml
rename to plugins/network-elements/juniper-srx/src/main/resources/META-INF/cloudstack/srx/spring-srx-context.xml
diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml
index a1bc19f..661761a 100644
--- a/plugins/network-elements/netscaler/pom.xml
+++ b/plugins/network-elements/netscaler/pom.xml
@@ -1,46 +1,46 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-netscaler</artifactId>
-  <name>Apache CloudStack Plugin - Network Netscaler</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-        <groupId>com.citrix.netscaler.nitro</groupId>
-        <artifactId>nitro</artifactId>
-        <version>${cs.nitro.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.citrix.netscaler.nitro</groupId>
-      <artifactId>sdx_nitro</artifactId>
-      <version>${cs.nitro.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.json</groupId>
-      <artifactId>json</artifactId>
-      <version>20090211</version>
-    </dependency>
-  </dependencies>
+<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-network-netscaler</artifactId>
+    <name>Apache CloudStack Plugin - Network Netscaler</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>com.citrix.netscaler.nitro</groupId>
+            <artifactId>nitro</artifactId>
+            <version>${cs.nitro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.citrix.netscaler.nitro</groupId>
+            <artifactId>sdx_nitro</artifactId>
+            <version>${cs.nitro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
deleted file mode 100644
index fdef005..0000000
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
+++ /dev/null
@@ -1,95 +0,0 @@
-//Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements.  See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.cloud.api.commands;
-
-import javax.inject.Inject;
-import javax.persistence.EntityExistsException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.api.response.NetScalerServicePackageResponse;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.element.NetscalerLoadBalancerElementService;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@APICommand(name = "registerNetscalerServicePackage", responseObject = NetScalerServicePackageResponse.class, description = "Registers NCC Service Package")
-public class RegisterServicePackageCmd extends BaseCmd {
-
-    public static final Logger s_logger = Logger.getLogger(RegisterServicePackageCmd.class.getName());
-    private static final String s_name = "registerNetscalerServicePackage";
-
-    @Inject
-    NetscalerLoadBalancerElementService _netsclarLbService;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the service Package.")
-    private String spName;
-
-    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true, description = "Description of Service Package")
-    private String description;
-
-
-    @Override
-    public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
-        try {
-            NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this);
-            if (response != null) {
-                response.setObjectName("netscalerservicepackage");
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Service Package due to internal error.");
-            }
-        } catch (InvalidParameterValueException invalidParamExcp) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
-        } catch (CloudRuntimeException runtimeExcp) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
-        } catch (EntityExistsException runtimeExcp) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Service Pacakge Already Exists with Name " + getSpName());
-        }
-
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccount().getId();
-    }
-
-    public String getSpName() {
-        return spName;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
deleted file mode 100644
index 38a836d..0000000
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
+++ /dev/null
@@ -1,1526 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.element;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import com.google.gson.Gson;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
-import org.apache.cloudstack.region.gslb.GslbServiceProvider;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.NetScalerImplementNetworkCommand;
-import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
-import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.commands.AddNetscalerLoadBalancerCmd;
-import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd;
-import com.cloud.api.commands.DeleteNetscalerControlCenterCmd;
-import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd;
-import com.cloud.api.commands.DeleteServicePackageOfferingCmd;
-import com.cloud.api.commands.DeployNetscalerVpxCmd;
-import com.cloud.api.commands.ListNetscalerControlCenterCmd;
-import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd;
-import com.cloud.api.commands.ListNetscalerLoadBalancersCmd;
-import com.cloud.api.commands.ListRegisteredServicePackageCmd;
-import com.cloud.api.commands.RegisterNetscalerControlCenterCmd;
-import com.cloud.api.commands.RegisterServicePackageCmd;
-import com.cloud.api.commands.StopNetScalerVMCmd;
-import com.cloud.api.response.NetScalerServicePackageResponse;
-import com.cloud.api.response.NetscalerControlCenterResponse;
-import com.cloud.api.response.NetscalerLoadBalancerResponse;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterIpAddressDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.network.ExternalLoadBalancerDeviceManager;
-import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.NetScalerControlCenterVO;
-import com.cloud.network.NetScalerPodVO;
-import com.cloud.network.NetScalerServicePackageVO;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.as.AutoScaleCounter;
-import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState;
-import com.cloud.network.dao.NetScalerControlCenterDao;
-import com.cloud.network.dao.NetScalerPodDao;
-import com.cloud.network.dao.NetScalerServicePackageDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
-import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRule.LbDestination;
-import com.cloud.network.resource.NetScalerControlCenterResource;
-import com.cloud.network.resource.NetscalerResource;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.LbStickinessMethod;
-import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
-import com.cloud.network.rules.LoadBalancerContainer;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.vm.NetScalerVMManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.resource.ServerResource;
-import com.cloud.user.Account;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.UrlUtil;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
-        implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager,
-        IpDeployer, StaticNatServiceProvider, GslbServiceProvider {
-
-    private static final Logger s_logger = Logger.getLogger(NetscalerElement.class);
-    public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp");
-    public static final AutoScaleCounterType AutoScaleCounterNetscaler = new AutoScaleCounterType("netscaler");
-
-    @Inject
-    NetworkModel _networkManager;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    NetworkModel _networkMgr;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    ExternalLoadBalancerDeviceDao _lbDeviceDao;
-    @Inject
-    NetScalerControlCenterDao _netscalerControlCenterDao;
-    @Inject
-    NetworkExternalLoadBalancerDao _networkLBDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    HostDetailsDao _detailsDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    NetScalerPodDao _netscalerPodDao;
-    @Inject
-    DataCenterIpAddressDao _privateIpAddressDao;
-    @Inject
-    ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
-    @Inject
-    NetScalerServicePackageDao _netscalerServicePackageDao;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    HostDetailsDao _hostDetailDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    NetworkOrchestrationService _networkService;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao = null;
-    @Inject
-    NetScalerVMManager _netScalerVMManager;
-
-    private boolean canHandle(Network config, Service service) {
-        DataCenter zone = _dcDao.findById(config.getDataCenterId());
-        // Create a NCC Resource on Demand for the zone.
-
-        boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced
-                && (config.getGuestType() == Network.GuestType.Isolated
-                        || config.getGuestType() == Network.GuestType.Shared)
-                && config.getTrafficType() == TrafficType.Guest);
-        boolean handleInBasicZone = (zone.getNetworkType() == NetworkType.Basic
-                && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest);
-
-        if (!(handleInAdvanceZone || handleInBasicZone)) {
-            s_logger.trace("Not handling network with Type  " + config.getGuestType() + " and traffic type "
-                    + config.getTrafficType() + " in zone of type " + zone.getNetworkType());
-            return false;
-        }
-
-        return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao
-                .canProviderSupportServiceInNetwork(config.getId(), service, Network.Provider.Netscaler));
-    }
-
-    private boolean isBasicZoneNetwok(Network config) {
-        DataCenter zone = _dcDao.findById(config.getDataCenterId());
-        return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared
-                && config.getTrafficType() == TrafficType.Guest);
-    }
-
-    @Override
-    public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest,
-            ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException,
-                    InsufficientNetworkCapacityException {
-
-        if (!canHandle(guestConfig, Service.Lb)) {
-            return false;
-        }
-
-        if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestConfig.getId(), Service.StaticNat,
-                Network.Provider.Netscaler) && !isBasicZoneNetwok(guestConfig)) {
-            s_logger.error("NetScaler provider can not be Static Nat service provider for the network "
-                    + guestConfig.getGuestType() + " and traffic type " + guestConfig.getTrafficType());
-            return false;
-        }
-
-        try {
-            if (offering.getServicePackage() == null) {
-                return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
-            } else {
-                // if the network offering has service package implement it with
-                // Netscaler Control Center
-                return manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
-            }
-        } catch (InsufficientCapacityException capacityException) {
-            throw new ResourceUnavailableException(
-                    "There are no NetScaler load balancer devices with the free capacity for implementing this network",
-                    DataCenter.class, guestConfig.getDataCenterId());
-        } catch (ConfigurationException e) {
-            throw new ResourceUnavailableException(
-                    "There are no NetScaler load balancer devices with the free capacity for implementing this network : "
-                            + e.getMessage(),
-                    DataCenter.class, guestConfig.getDataCenterId());
-        }
-    }
-
-    @Override
-    public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) {
-        long zoneId = guestConfig.getDataCenterId();
-        return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter);
-    }
-
-    public HostVO allocateNCCResourceForNetwork(Network guestConfig) throws ConfigurationException {
-
-        Map<String, String> _configs;
-        List<NetScalerControlCenterVO> ncc = _netscalerControlCenterDao.listAll();
-        HostVO hostVO = null;
-        Map<String, Object> params;
-        if (ncc.size() > 0) {
-            NetScalerControlCenterVO nccVO = ncc.get(0);
-            String ipAddress = nccVO.getNccip();
-            Map hostDetails = new HashMap<String, String>();
-            String hostName = "NetscalerControlCenter";
-            hostDetails.put("name", hostName);
-            hostDetails.put("guid", UUID.randomUUID().toString());
-            hostDetails.put("zoneId", Long.toString(guestConfig.getDataCenterId()));
-            hostDetails.put("ip", ipAddress);
-            hostDetails.put("username", nccVO.getUsername());
-            hostDetails.put("password", DBEncryptionUtil.decrypt(nccVO.getPassword()));
-            hostDetails.put("deviceName", "netscaler control center");
-            hostDetails.put("cmdTimeOut", Long.toString(NumbersUtil.parseInt(_configDao.getValue(Config.NCCCmdTimeOut.key()), 600000)));
-            ServerResource resource = new NetScalerControlCenterResource();
-            resource.configure(hostName, hostDetails);
-            final Host host = _resourceMgr.addHost(guestConfig.getDataCenterId(), resource, Host.Type.NetScalerControlCenter, hostDetails);
-            hostVO = _hostDao.findById(host.getId());
-        }
-        return hostVO;
-    }
-
-    public boolean manageGuestNetworkWithNetscalerControlCenter(boolean add, Network guestConfig,
-            NetworkOffering offering)
-                    throws ResourceUnavailableException, InsufficientCapacityException, ConfigurationException {
-
-        if (guestConfig.getTrafficType() != TrafficType.Guest) {
-            s_logger.trace("External load balancer can only be used for guest networks.");
-            return false;
-        }
-
-        long zoneId = guestConfig.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        HostVO netscalerControlCenter = null;
-
-        if (add) {
-            HostVO lbDeviceVO = null;
-            // on restart network, device could have been allocated already,
-            // skip allocation if a device is assigned
-            lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
-            if (lbDeviceVO == null) {
-                // allocate a load balancer device for the network
-                lbDeviceVO = allocateNCCResourceForNetwork(guestConfig);
-                if (lbDeviceVO == null) {
-                    String msg = "failed to allocate Netscaler ControlCenter Resource for the zone in the network "
-                            + guestConfig.getId();
-                    s_logger.error(msg);
-                    throw new InsufficientNetworkCapacityException(msg, DataCenter.class,
-                            guestConfig.getDataCenterId());
-                }
-            }
-            netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
-            s_logger.debug("Allocated Netscaler Control Center device:" + lbDeviceVO.getId() + " for the network: "
-                    + guestConfig.getId());
-        } else {
-            // find the load balancer device allocated for the network
-
-            HostVO lbDeviceVO = null;
-            // on restart network, device could have been allocated already, skip allocation if a device is assigned
-            lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
-            if (lbDeviceVO == null) {
-                s_logger.warn(
-                        "Network shutdwon requested on external load balancer element, which did not implement the network."
-                                + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
-                return true;
-            }
-
-            netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
-            assert(netscalerControlCenter != null) : "There is no device assigned to this network how did shutdown network ended up here??";
-        }
-        JSONObject networkDetails = new JSONObject();
-        JSONObject networkPayload = new JSONObject();
-
-        String selfIp = null;
-        try {
-            networkDetails.put("id", guestConfig.getId());
-            networkDetails.put("vlan", guestConfig.getBroadcastUri());
-            networkDetails.put("cidr", guestConfig.getCidr());
-            networkDetails.put("gateway", guestConfig.getGateway());
-            networkDetails.put("servicepackage_id", offering.getServicePackage());
-            networkDetails.put("zone_id", zone.getUuid());
-            networkDetails.put("account_id", guestConfig.getAccountId());
-            networkDetails.put("add", Boolean.toString(add));
-            selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
-            if (selfIp == null) {
-                String msg = "failed to acquire guest IP address so not implementing the network on the NetscalerControlCenter";
-                s_logger.error(msg);
-                throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
-            }
-            networkDetails.put("snip", selfIp);
-            // TODO region is hardcoded make it dynamic
-            networkDetails.put("region_id", 1);
-            networkDetails.put("name", guestConfig.getName());
-            networkPayload.put("network", networkDetails);
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-
-        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zone.getUuid(), netscalerControlCenter.getId(), networkPayload.toString());
-        Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
-        if (add) {
-            //TODO After getting the answer check with the job id and do poll on the job and then save the selfip or acquired guest ip to the Nics table
-            if (answer != null) {
-                if (answer.getResult() == true) {
-                    if (add) {
-                        // Insert a new NIC for this guest network to reserve the self IP
-                        _networkService.savePlaceholderNic(guestConfig, selfIp, null, null);
-                    }
-                } else {
-                    return false;
-                }
-            }
-        } else {
-            if (answer != null) {
-                if (answer.getResult() == true) {
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest,
-            ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException,
-                    ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) {
-        return true;
-    }
-
-    @Override
-    public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup)
-            throws ResourceUnavailableException, ConcurrentOperationException {
-        if (!canHandle(guestConfig, Service.Lb)) {
-            return false;
-        }
-
-        try {
-
-            NetworkOffering networkOffering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
-            if (networkOffering.getServicePackage() == null) {
-                return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
-            } else {
-                // if the network offering has service package implement it with Netscaler Control Center
-                return manageGuestNetworkWithNetscalerControlCenter(false, guestConfig, networkOffering);
-            }
-        } catch (InsufficientCapacityException capacityException) {
-            // TODO: handle out of capacity exception gracefully in case of
-            // multple providers available
-            return false;
-        } catch (ConfigurationException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean destroy(Network config, ReservationContext context) {
-        return true;
-    }
-
-    @Override
-    public boolean validateLBRule(Network network, LoadBalancingRule rule) {
-        if (canHandle(network, Service.Lb)) {
-            String algo = rule.getAlgorithm();
-            return (algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source"));
-        }
-        return true;
-    }
-
-    @Override
-    public boolean applyLBRules(Network config, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
-        if (!canHandle(config, Service.Lb)) {
-            return false;
-        }
-
-        if (!canHandleLbRules(rules)) {
-            return false;
-        }
-
-        if (isBasicZoneNetwok(config)) {
-            return applyElasticLoadBalancerRules(config, rules);
-        } else {
-            return applyLoadBalancerRules(config, rules);
-        }
-    }
-
-    @Override
-    public Map<Service, Map<Capability, String>> getCapabilities() {
-        Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
-
-        // Set capabilities for LB service
-        Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
-
-        // Specifies that the RoundRobin and Leastconn algorithms are supported for load balancing rules
-        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin, leastconn, source");
-
-        // specifies that Netscaler network element can provided both shared and
-        // isolation modes
-        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated, shared");
-
-        // Specifies that load balancing rules can be made for either TCP or UDP
-        // traffic
-        lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp,http");
-
-        // Specifies that this element can measure network usage on a per public
-        // IP basis
-        lbCapabilities.put(Capability.TrafficStatistics, "per public ip");
-
-        // Specifies that load balancing rules can only be made with public IPs
-        // that aren't source NAT IPs
-        lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional");
-
-        // Supports only Public load balancing
-        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
-
-        // Support inline mode with firewall
-        lbCapabilities.put(Capability.InlineMode, "true");
-
-        // Specifies that load balancing rules can support autoscaling and the list of counters it supports
-        // list of counters it supports
-        AutoScaleCounter counter;
-        List<AutoScaleCounter> counterList = new ArrayList<AutoScaleCounter>();
-        counter = new AutoScaleCounter(AutoScaleCounterSnmp);
-        counterList.add(counter);
-        counter.addParam("snmpcommunity", true,
-                "the community string that has to be used to do a SNMP GET on the AutoScaled Vm", false);
-        counter.addParam("snmpport", false, "the port at which SNMP agent is running on the AutoScaled Vm", false);
-
-        counter = new AutoScaleCounter(AutoScaleCounterNetscaler);
-        counterList.add(counter);
-
-        Gson gson = new Gson();
-        String autoScaleCounterList = gson.toJson(counterList);
-        lbCapabilities.put(Capability.AutoScaleCounters, autoScaleCounterList);
-
-        LbStickinessMethod method;
-        List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>();
-        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased,
-                "This is cookie based sticky method, can be used only for http");
-        methodList.add(method);
-        method.addParam("holdtime", false, "time period in minutes for which persistence is in effect.", false);
-
-        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
-                "This is app session based sticky method, can be used only for http");
-        methodList.add(method);
-        method.addParam("name", true, "cookie name passed in http header by apllication to the client", false);
-
-        method = new LbStickinessMethod(StickinessMethodType.SourceBased,
-                "This is source based sticky method, can be used for any type of protocol.");
-        methodList.add(method);
-        method.addParam("holdtime", false, "time period for which persistence is in effect.", false);
-
-        String stickyMethodList = gson.toJson(methodList);
-        lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList);
-
-        lbCapabilities.put(Capability.ElasticLb, "true");
-        // Setting HealthCheck Capability to True for Netscaler element
-        lbCapabilities.put(Capability.HealthCheckPolicy, "true");
-        capabilities.put(Service.Lb, lbCapabilities);
-
-        Map<Capability, String> staticNatCapabilities = new HashMap<Capability, String>();
-        staticNatCapabilities.put(Capability.ElasticIp, "true");
-        capabilities.put(Service.StaticNat, staticNatCapabilities);
-
-        // Supports SSL offloading
-        lbCapabilities.put(Capability.SslTermination, "true");
-
-        // TODO - Murali, please put correct capabilities here
-        Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
-        firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
-        firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
-        firewallCapabilities.put(Capability.MultipleIps, "true");
-        capabilities.put(Service.Firewall, firewallCapabilities);
-
-        return capabilities;
-    }
-
-    @Override
-    public ExternalLoadBalancerDeviceVO addNetscalerLoadBalancer(AddNetscalerLoadBalancerCmd cmd) {
-        String deviceName = cmd.getDeviceType();
-
-        if (!isNetscalerDevice(deviceName)) {
-            throw new InvalidParameterValueException("Invalid Netscaler device type");
-        }
-
-        URI uri;
-        try {
-            uri = new URI(cmd.getUrl());
-        } catch (Exception e) {
-            String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to "
-                    + e.getMessage();
-            s_logger.debug(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-        Map<String, String> configParams = new HashMap<String, String>();
-        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
-        boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null)
-                ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false;
-
-        if (dedicatedUse && !deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())) {
-            String msg = "Only Netscaler VPX load balancers can be specified for dedicated use";
-            s_logger.debug(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-
-        if (cmd.isGslbProvider()) {
-
-            if (!deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())
-                    && !deviceName.equals(NetworkDevice.NetscalerMPXLoadBalancer.getName())) {
-                String msg = "Only Netscaler VPX or MPX load balancers can be specified as GSLB service provider";
-                s_logger.debug(msg);
-                throw new InvalidParameterValueException(msg);
-            }
-
-            if (cmd.getSitePublicIp() == null || cmd.getSitePrivateIp() == null) {
-                String msg = "Public and Privae IP needs to provided for NetScaler that will be GSLB provider";
-                s_logger.debug(msg);
-                throw new InvalidParameterValueException(msg);
-            }
-
-            if (dedicatedUse) {
-                throw new InvalidParameterValueException(
-                        "NetScaler provisioned to be GSLB service provider can only be configured for shared usage.");
-            }
-
-        }
-
-        if (cmd.isExclusiveGslbProvider() && !cmd.isGslbProvider()) {
-            throw new InvalidParameterValueException(
-                    "NetScaler can be provisioned to be exclusive GSLB service provider"
-                            + " only if its being configured as GSLB service provider also.");
-        }
-
-        ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(),
-                cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource(), cmd.isGslbProvider(),
-                cmd.isExclusiveGslbProvider(), cmd.getSitePublicIp(), cmd.getSitePrivateIp());
-
-        return lbDeviceVO;
-    }
-
-    @Override
-    public boolean deleteNetscalerLoadBalancer(DeleteNetscalerLoadBalancerCmd cmd) {
-        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
-
-        ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
-        if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
-            throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
-        }
-
-        return deleteExternalLoadBalancer(lbDeviceVo.getHostId());
-    }
-
-    @Override
-    public ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(ConfigureNetscalerLoadBalancerCmd cmd) {
-        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
-        Boolean dedicatedUse = cmd.getLoadBalancerDedicated();
-        Long capacity = cmd.getLoadBalancerCapacity();
-        List<Long> podIds = cmd.getPodIds();
-        try {
-            return configureNetscalerLoadBalancer(lbDeviceId, capacity, dedicatedUse, podIds);
-        } catch (Exception e) {
-            throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage());
-        }
-    }
-
-    @DB
-    private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity,
-            Boolean dedicatedUse, List<Long> newPodsConfig) {
-        final ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
-        final Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId());
-
-        if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
-            throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
-        }
-
-        List<Long> currentPodsConfig = new ArrayList<Long>();
-        List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVo.getId());
-        if (currentPodVOs != null && currentPodVOs.size() > 0) {
-            for (NetScalerPodVO nsPodVo : currentPodVOs) {
-                currentPodsConfig.add(nsPodVo.getPodId());
-            }
-        }
-
-        final List<Long> podsToAssociate = new ArrayList<Long>();
-        if (newPodsConfig != null && newPodsConfig.size() > 0) {
-            for (Long podId : newPodsConfig) {
-                HostPodVO pod = _podDao.findById(podId);
-                if (pod == null) {
-                    throw new InvalidParameterValueException("Can't find pod by id " + podId);
-                }
-            }
-
-            for (Long podId : newPodsConfig) {
-                if (!currentPodsConfig.contains(podId)) {
-                    podsToAssociate.add(podId);
-                }
-            }
-        }
-
-        final List<Long> podsToDeassociate = new ArrayList<Long>();
-        for (Long podId : currentPodsConfig) {
-            if (!newPodsConfig.contains(podId)) {
-                podsToDeassociate.add(podId);
-            }
-        }
-
-        String deviceName = lbDeviceVo.getDeviceName();
-        if (dedicatedUse != null || capacity != null) {
-            if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)
-                    || NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) {
-                if (dedicatedUse != null && dedicatedUse == true) {
-                    throw new InvalidParameterValueException(
-                            "Netscaler MPX and SDX device should be shared and can not be dedicated to a single account.");
-                }
-            }
-
-            // check if any networks are using this netscaler device
-            List<NetworkExternalLoadBalancerVO> networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
-            if ((networks != null) && !networks.isEmpty()) {
-                if (capacity != null && capacity < networks.size()) {
-                    throw new CloudRuntimeException(
-                            "There are more number of networks already using this netscaler device than configured capacity");
-                }
-
-                if (dedicatedUse != null && dedicatedUse == true) {
-                    throw new CloudRuntimeException(
-                            "There are networks already using this netscaler device to make device dedicated");
-                }
-            }
-        }
-
-        if (!NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)) {
-            if (capacity != null) {
-                lbDeviceVo.setCapacity(capacity);
-            }
-        } else {
-            // FIXME how to interpret configured capacity of the SDX device
-        }
-
-        if (dedicatedUse != null) {
-            lbDeviceVo.setIsDedicatedDevice(dedicatedUse);
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                _lbDeviceDao.update(lbDeviceId, lbDeviceVo);
-
-                for (Long podId : podsToAssociate) {
-                    NetScalerPodVO nsPodVo = new NetScalerPodVO(lbDeviceId, podId);
-                    _netscalerPodDao.persist(nsPodVo);
-                }
-
-                for (Long podId : podsToDeassociate) {
-                    NetScalerPodVO nsPodVo = _netscalerPodDao.findByPodId(podId);
-                    _netscalerPodDao.remove(nsPodVo.getId());
-                }
-
-                // FIXME get the row lock to avoid race condition
-                _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails);
-
-            }
-        });
-        HostVO host = _hostDao.findById(lbDeviceVo.getHostId());
-
-        _agentMgr.reconnect(host.getId());
-        return lbDeviceVo;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(AddNetscalerLoadBalancerCmd.class);
-        cmdList.add(ConfigureNetscalerLoadBalancerCmd.class);
-        cmdList.add(DeleteNetscalerLoadBalancerCmd.class);
-        cmdList.add(ListNetscalerLoadBalancerNetworksCmd.class);
-        cmdList.add(ListNetscalerLoadBalancersCmd.class);
-        cmdList.add(RegisterServicePackageCmd.class);
-        cmdList.add(RegisterNetscalerControlCenterCmd.class);
-        cmdList.add(ListRegisteredServicePackageCmd.class);
-        cmdList.add(ListNetscalerControlCenterCmd.class);
-        cmdList.add(DeleteServicePackageOfferingCmd.class);
-        cmdList.add(DeleteNetscalerControlCenterCmd.class);
-        cmdList.add(DeployNetscalerVpxCmd.class);
-        cmdList.add(StopNetScalerVMCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public List<? extends Network> listNetworks(ListNetscalerLoadBalancerNetworksCmd cmd) {
-        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
-        List<NetworkVO> networks = new ArrayList<NetworkVO>();
-
-        ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
-        if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
-            throw new InvalidParameterValueException(
-                    "Could not find Netscaler load balancer device with ID " + lbDeviceId);
-        }
-
-        List<NetworkExternalLoadBalancerVO> networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
-        if (networkLbMaps != null && !networkLbMaps.isEmpty()) {
-            for (NetworkExternalLoadBalancerVO networkLbMap : networkLbMaps) {
-                NetworkVO network = _networkDao.findById(networkLbMap.getNetworkId());
-                networks.add(network);
-            }
-        }
-
-        return networks;
-    }
-
-    @Override
-    public List<ExternalLoadBalancerDeviceVO> listNetscalerLoadBalancers(ListNetscalerLoadBalancersCmd cmd) {
-        Long physcialNetworkId = cmd.getPhysicalNetworkId();
-        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
-        PhysicalNetworkVO pNetwork = null;
-        List<ExternalLoadBalancerDeviceVO> lbDevices = new ArrayList<ExternalLoadBalancerDeviceVO>();
-
-        if (physcialNetworkId == null && lbDeviceId == null) {
-            throw new InvalidParameterValueException(
-                    "Either physical network Id or load balancer device Id must be specified");
-        }
-
-        if (lbDeviceId != null) {
-            ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
-            if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
-                throw new InvalidParameterValueException(
-                        "Could not find Netscaler load balancer device with ID: " + lbDeviceId);
-            }
-            lbDevices.add(lbDeviceVo);
-            return lbDevices;
-        }
-
-        if (physcialNetworkId != null) {
-            pNetwork = _physicalNetworkDao.findById(physcialNetworkId);
-            if (pNetwork == null) {
-                throw new InvalidParameterValueException(
-                        "Could not find phyical network with ID: " + physcialNetworkId);
-            }
-            lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName());
-            return lbDevices;
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<NetScalerServicePackageVO> listRegisteredServicePackages(ListRegisteredServicePackageCmd cmd) {
-
-        List<NetScalerServicePackageVO> lrsPackages = new ArrayList<NetScalerServicePackageVO>();
-        lrsPackages = _netscalerServicePackageDao.listAll();
-        return lrsPackages;
-    }
-
-    @Override
-    public List<NetScalerControlCenterVO> listNetscalerControlCenter(ListNetscalerControlCenterCmd cmd) {
-        return _netscalerControlCenterDao.listAll();
-    }
-
-    @Override
-    public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException {
-        NetScalerServicePackageVO result = null;
-        boolean flag=false;
-        try {
-            result = _netscalerServicePackageDao.findByUuid(cmd.getId());
-            if (result == null)
-                throw new CloudRuntimeException("Record does not Exists in the Table");
-
-            if(_networkOfferingDao.isUsingServicePackage(result.getUuid()))
-            {
-                throw new CloudRuntimeException("Network offering is using the service package. First delete the NeworkOffering and then delete ServicePackage");
-            }
-
-            flag = _netscalerServicePackageDao.remove(result.getId());
-
-        } catch (Exception e) {
-            if (e instanceof InvalidParameterValueException)
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
-            else
-               throw e;
-
-        }
-        return flag;
-
-    }
-
-    @DB
-    @Override
-    public boolean deleteNetscalerControlCenter(DeleteNetscalerControlCenterCmd cmd) throws CloudRuntimeException {
-
-        NetScalerControlCenterVO result = _netscalerControlCenterDao.findByUuid(cmd.getId());
-        if (result == null)
-            throw new CloudRuntimeException("External Netscaler Control Center Table does not contain record with this ID");
-        else {
-            //ID list of Network Offering which are not removed and have service Package Uuid field not null.
-            List<Long> servicePackageId_list = _networkOfferingDao.listNetworkOfferingID();
-
-            if (servicePackageId_list.size() != 0) {
-                //VO list of Networks  which are using Network Offering.
-                List<NetworkVO> networkVO_list = _networkDao.listNetworkVO(servicePackageId_list);
-                if (networkVO_list != null && networkVO_list.size() != 0)
-                    throw new CloudRuntimeException(
-                            "ServicePackages published by NetScalerControlCenter are being used by NetworkOfferings. Try deleting NetworkOffering with ServicePackages and then delete NetScalerControlCenter.");
-            }
-        }
-        try {
-            _netscalerServicePackageDao.removeAll();
-        } catch (CloudRuntimeException ce) {
-            throw new CloudRuntimeException("Service Package is being used by Network Offering, Try deleting Network Offering and then delete Service Package.");
-        }
-
-        // delete Netscaler Control Center
-        _netscalerControlCenterDao.remove(result.getId());
-
-        //Removal of  NCC from Host Table
-        List<HostVO> ncc_list = _hostDao.listAll();
-        if (ncc_list == null) {
-            throw new CloudRuntimeException("Could not find Netscaler Control Center in Database");
-        }
-        for (HostVO ncc : ncc_list) {
-            if (ncc.getType().equals(Host.Type.NetScalerControlCenter)) {
-                try {
-                    // put the host in maintenance state in order for it to be deleted
-                    ncc.setResourceState(ResourceState.Maintenance);
-                    _hostDao.update(ncc.getId(), ncc);
-                    _resourceMgr.deleteHost(ncc.getId(), false, false);
-                } catch (Exception e) {
-                    s_logger.debug(e);
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO) {
-        NetscalerLoadBalancerResponse response = new NetscalerLoadBalancerResponse();
-        Host lbHost = _hostDao.findById(lbDeviceVO.getHostId());
-        Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVO.getHostId());
-        response.setId(lbDeviceVO.getUuid());
-        response.setIpAddress(lbHost.getPrivateIpAddress());
-        PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(lbDeviceVO.getPhysicalNetworkId());
-        if (pnw != null) {
-            response.setPhysicalNetworkId(pnw.getUuid());
-        }
-        response.setPublicInterface(lbDetails.get("publicInterface"));
-        response.setPrivateInterface(lbDetails.get("privateInterface"));
-        response.setDeviceName(lbDeviceVO.getDeviceName());
-        if (lbDeviceVO.getCapacity() == 0) {
-            long defaultLbCapacity = NumbersUtil
-                    .parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
-            response.setDeviceCapacity(defaultLbCapacity);
-        } else {
-            response.setDeviceCapacity(lbDeviceVO.getCapacity());
-        }
-        response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice());
-        response.setProvider(lbDeviceVO.getProviderName());
-        response.setDeviceState(lbDeviceVO.getState().name());
-        response.setObjectName("netscalerloadbalancer");
-
-        response.setGslbProvider(lbDeviceVO.getGslbProvider());
-        response.setExclusiveGslbProvider(lbDeviceVO.getExclusiveGslbProvider());
-        response.setGslbSitePublicIp(lbDeviceVO.getGslbSitePublicIP());
-        response.setGslbSitePrivateIp(lbDeviceVO.getGslbSitePrivateIP());
-
-        List<Long> associatedPods = new ArrayList<Long>();
-        List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVO.getId());
-        if (currentPodVOs != null && currentPodVOs.size() > 0) {
-            for (NetScalerPodVO nsPodVo : currentPodVOs) {
-                associatedPods.add(nsPodVo.getPodId());
-            }
-        }
-        response.setAssociatedPods(associatedPods);
-        return response;
-    }
-
-    @Override
-    public NetscalerControlCenterResponse createNetscalerControlCenterResponse(NetScalerControlCenterVO lncCentersVO) {
-        NetscalerControlCenterResponse response = new NetscalerControlCenterResponse(lncCentersVO);
-        response.setObjectName("netscalercontrolcenter");
-        return response;
-    }
-
-    @Override
-    public NetScalerServicePackageResponse createRegisteredServicePackageResponse(
-            NetScalerServicePackageVO lrsPackageVO) {
-        NetScalerServicePackageResponse response = new NetScalerServicePackageResponse();
-        response.setId(lrsPackageVO.getUuid());
-        response.setName(lrsPackageVO.getName());
-        response.setDescription(lrsPackageVO.getDescription());
-        response.setObjectName("registeredServicepackage");
-        return response;
-    }
-
-    @Override
-    public Provider getProvider() {
-        return Provider.Netscaler;
-    }
-
-    @Override
-    public boolean isReady(PhysicalNetworkServiceProvider provider) {
-        List<ExternalLoadBalancerDeviceVO> lbDevices = _lbDeviceDao
-                .listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), Provider.Netscaler.getName());
-
-        // true if at-least one Netscaler device is added in to physical network
-        // and is in configured (in enabled state)
-        // state
-        if (lbDevices != null && !lbDevices.isEmpty()) {
-            for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) {
-                if (lbDevice.getState() == LBDeviceState.Enabled) {
-                    return true;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context)
-            throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO reset the configuration on all of the netscaler devices in this
-        // physical network
-        return true;
-    }
-
-    @Override
-    public boolean canEnableIndividualServices() {
-        return true;
-    }
-
-    private boolean isNetscalerDevice(String deviceName) {
-        if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName()))
-                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName()))
-                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public boolean verifyServicesCombination(Set<Service> services) {
-        Set<Service> netscalerServices = new HashSet<Service>();
-        netscalerServices.add(Service.Lb);
-        netscalerServices.add(Service.StaticNat);
-
-        // NetScaler can only act as Lb and Static Nat service provider
-        if (services != null && !services.isEmpty() && !netscalerServices.containsAll(services)) {
-            s_logger.warn(
-                    "NetScaler network element can only support LB and Static NAT services and service combination "
-                            + services + " is not supported.");
-
-            StringBuffer buff = new StringBuffer();
-            for (Service service : services) {
-                buff.append(service.getName());
-                buff.append(" ");
-            }
-            s_logger.warn(
-                    "NetScaler network element can only support LB and Static NAT services and service combination "
-                            + buff.toString() + " is not supported.");
-            s_logger.warn(
-                    "NetScaler network element can only support LB and Static NAT services and service combination "
-                            + services + " is not supported.");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service)
-            throws ResourceUnavailableException {
-        // return true, as IP will be associated as part of LB rule
-        // configuration
-        return true;
-    }
-
-    @Override
-    public IpDeployer getIpDeployer(Network network) {
-
-        if (_networkMgr.isNetworkInlineMode(network)) {
-            return getIpDeployerForInlineMode(network);
-        }
-
-        return this;
-    }
-
-    public boolean applyElasticLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules)
-            throws ResourceUnavailableException {
-
-        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
-            return true;
-        }
-
-        String errMsg = null;
-        ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
-        if (lbDeviceVO == null) {
-            try {
-                lbDeviceVO = allocateLoadBalancerForNetwork(network);
-            } catch (Exception e) {
-                errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to "
-                        + e.getMessage();
-                s_logger.error(errMsg);
-                throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-            }
-        }
-
-        if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) {
-            errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules.";
-            s_logger.error(errMsg);
-            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-        }
-
-        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
-        for (int i = 0; i < loadBalancingRules.size(); i++) {
-            LoadBalancingRule rule = loadBalancingRules.get(i);
-            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
-            String protocol = rule.getProtocol();
-            String algorithm = rule.getAlgorithm();
-            String lbUuid = rule.getUuid();
-            String srcIp = rule.getSourceIp().addr();
-            int srcPort = rule.getSourcePortStart();
-            List<LbDestination> destinations = rule.getDestinations();
-
-            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
-                LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
-                        false, false, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies(),
-                        rule.getLbSslCert(), rule.getLbProtocol());
-                if (rule.isAutoScaleConfig()) {
-                    loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
-                }
-                loadBalancersToApply.add(loadBalancer);
-            }
-        }
-
-        if (loadBalancersToApply.size() > 0) {
-            int numLoadBalancersForCommand = loadBalancersToApply.size();
-            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
-                    .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-            LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null);
-
-            HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
-            if (answer == null || !answer.getResult()) {
-                String details = (answer != null) ? answer.getDetails() : "details unavailable";
-                String msg = "Unable to apply elastic load balancer rules to the external load balancer appliance in zone "
-                        + network.getDataCenterId() + " due to: " + details + ".";
-                s_logger.error(msg);
-                throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyStaticNats(Network config, List<? extends StaticNat> rules)
-            throws ResourceUnavailableException {
-
-        if (!canHandle(config, Service.StaticNat)) {
-            return false;
-        }
-
-        boolean multiNetScalerDeployment = Boolean
-                .valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key()));
-
-        try {
-            if (!multiNetScalerDeployment) {
-                String errMsg;
-                ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config);
-                if (lbDevice == null) {
-                    try {
-                        lbDevice = allocateLoadBalancerForNetwork(config);
-                    } catch (Exception e) {
-                        errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to"
-                                + e.getMessage();
-                        s_logger.error(errMsg);
-                        throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-                    }
-                }
-
-                if (!isNetscalerDevice(lbDevice.getDeviceName())) {
-                    errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules.";
-                    s_logger.error(errMsg);
-                    throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-                }
-                SetStaticNatRulesAnswer answer = null;
-                List<StaticNatRuleTO> rulesTO = null;
-                if (rules != null) {
-                    rulesTO = new ArrayList<StaticNatRuleTO>();
-                    for (StaticNat rule : rules) {
-                        IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
-                        StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null,
-                                rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
-                        rulesTO.add(ruleTO);
-                    }
-                }
-
-                SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null);
-                answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(), cmd);
-                if (answer == null) {
-                    return false;
-                } else {
-                    return answer.getResult();
-                }
-            } else {
-                if (rules != null) {
-                    for (StaticNat rule : rules) {
-                        // validate if EIP rule can be configured.
-                        ExternalLoadBalancerDeviceVO lbDevice = getNetScalerForEIP(rule);
-                        if (lbDevice == null) {
-                            String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: "
-                                    + rule.getDestIpAddress();
-                            s_logger.error(errMsg);
-                            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-                        }
-
-                        List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
-                        IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
-                        StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null,
-                                rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
-                        rulesTO.add(ruleTO);
-                        SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null);
-
-                        // send commands to configure INAT rule on the NetScaler
-                        // device
-                        SetStaticNatRulesAnswer answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(),
-                                cmd);
-                        if (answer == null) {
-                            String errMsg = "Failed to configure INAT rule on NetScaler device " + lbDevice.getHostId();
-                            s_logger.error(errMsg);
-                            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-                        }
-                    }
-                    return true;
-                }
-            }
-            return true;
-        } catch (Exception e) {
-            s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage());
-            return false;
-        }
-    }
-
-    // returns configured NetScaler device that is associated with the pod that
-    // owns guest IP
-    private ExternalLoadBalancerDeviceVO getNetScalerForEIP(StaticNat rule) {
-        String guestIP = rule.getDestIpAddress();
-        List<DataCenterIpAddressVO> dcGuestIps = _privateIpAddressDao.listAll();
-        if (dcGuestIps != null) {
-            for (DataCenterIpAddressVO dcGuestIp : dcGuestIps) {
-                if (dcGuestIp.getIpAddress().equalsIgnoreCase(guestIP)) {
-                    long podId = dcGuestIp.getPodId();
-                    NetScalerPodVO nsPodVO = _netscalerPodDao.findByPodId(podId);
-                    if (nsPodVO != null) {
-                        ExternalLoadBalancerDeviceVO lbDeviceVO = _lbDeviceDao.findById(nsPodVO.getNetscalerDeviceId());
-                        return lbDeviceVO;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    public List<LoadBalancerTO> getElasticLBRulesHealthCheck(Network network,
-            List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
-
-        HealthCheckLBConfigAnswer answer = null;
-
-        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
-            return null;
-        }
-
-        String errMsg = null;
-        ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
-
-        if (lbDeviceVO == null) {
-            s_logger.warn(
-                    "There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
-            return null;
-        }
-
-        if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) {
-            errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules.";
-            s_logger.error(errMsg);
-            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
-        }
-
-        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
-        for (int i = 0; i < loadBalancingRules.size(); i++) {
-            LoadBalancingRule rule = loadBalancingRules.get(i);
-            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
-            String protocol = rule.getProtocol();
-            String algorithm = rule.getAlgorithm();
-            String lbUuid = rule.getUuid();
-            String srcIp = rule.getSourceIp().addr();
-            int srcPort = rule.getSourcePortStart();
-            List<LbDestination> destinations = rule.getDestinations();
-
-            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
-                LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
-                        false, false, destinations, null, rule.getHealthCheckPolicies(), rule.getLbSslCert(),
-                        rule.getLbProtocol());
-                loadBalancersToApply.add(loadBalancer);
-            }
-        }
-
-        if (loadBalancersToApply.size() > 0) {
-            int numLoadBalancersForCommand = loadBalancersToApply.size();
-            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
-                    .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-            HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
-            HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            answer = (HealthCheckLBConfigAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd);
-            return answer.getLoadBalancers();
-        }
-        return null;
-    }
-
-    @Override
-    public List<LoadBalancerTO> updateHealthChecks(Network network, List<LoadBalancingRule> lbrules) {
-
-        if (canHandle(network, Service.Lb) && canHandleLbRules(lbrules)) {
-            try {
-
-                if (isBasicZoneNetwok(network)) {
-                    return getElasticLBRulesHealthCheck(network, lbrules);
-                } else {
-                    return getLBHealthChecks(network, lbrules);
-                }
-            } catch (ResourceUnavailableException e) {
-                s_logger.error("Error in getting the LB Rules from NetScaler " + e);
-            }
-        } else {
-            s_logger.error("Network cannot handle to LB service ");
-        }
-        return null;
-    }
-
-    @Override
-    public boolean handlesOnlyRulesInTransitionState() {
-        return true;
-    }
-
-    @Override
-    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> rules)
-            throws ResourceUnavailableException {
-        return super.getLBHealthChecks(network, rules);
-    }
-
-    @Override
-    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        return null;
-    }
-
-    @Override
-    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        return null;
-    }
-
-    @Override
-    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
-        return null;
-    }
-
-    @Override
-    public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId,
-            GlobalLoadBalancerConfigCommand gslbConfigCmd) throws ResourceUnavailableException {
-
-        long zoneGslbProviderHosId = 0;
-
-        // find the NetScaler device configured as gslb service provider in the
-        // zone
-        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
-        if (nsGslbProvider == null) {
-            String msg = "Unable to find a NetScaler configured as gslb service provider in zone " + zoneId;
-            s_logger.debug(msg);
-            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
-        }
-
-        // get the host Id corresponding to NetScaler acting as GSLB service
-        // provider in the zone
-        zoneGslbProviderHosId = nsGslbProvider.getHostId();
-
-        // send gslb configuration to NetScaler device
-        Answer answer = _agentMgr.easySend(zoneGslbProviderHosId, gslbConfigCmd);
-        if (answer == null || !answer.getResult()) {
-            String msg = "Unable to apply global load balancer rule to the gslb service provider in zone " + zoneId;
-            s_logger.debug(msg);
-            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
-        }
-
-        return true;
-    }
-
-    private ExternalLoadBalancerDeviceVO findGslbProvider(long zoneId, long physicalNetworkId) {
-        List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest);
-
-        if (pNtwks == null || pNtwks.isEmpty()) {
-            throw new InvalidParameterValueException(
-                    "Unable to get physical network: " + physicalNetworkId + " in zone id = " + zoneId);
-        } else {
-            for (PhysicalNetwork physicalNetwork : pNtwks) {
-                if (physicalNetwork.getId() == physicalNetworkId) {
-                    PhysicalNetworkVO physNetwork = pNtwks.get(0);
-                    ExternalLoadBalancerDeviceVO nsGslbProvider = _externalLoadBalancerDeviceDao
-                            .findGslbServiceProvider(physNetwork.getId(), Provider.Netscaler.getName());
-                    return nsGslbProvider;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean isServiceEnabledInZone(long zoneId, long physicalNetworkId) {
-
-        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
-        // return true if a NetScaler device is configured in the zone
-        return (nsGslbProvider != null);
-    }
-
-    @Override
-    public String getZoneGslbProviderPublicIp(long zoneId, long physicalNetworkId) {
-        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
-        if (nsGslbProvider != null) {
-            return nsGslbProvider.getGslbSitePublicIP();
-        }
-        return null;
-    }
-
-    @Override
-    public String getZoneGslbProviderPrivateIp(long zoneId, long physicalNetworkId) {
-        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
-        if (nsGslbProvider != null) {
-            return nsGslbProvider.getGslbSitePrivateIP();
-        }
-        return null;
-    }
-
-    private boolean canHandleLbRules(List<LoadBalancingRule> rules) {
-        Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
-        if (!lbCaps.isEmpty()) {
-            String schemeCaps = lbCaps.get(Capability.LbSchemes);
-            if (schemeCaps != null) {
-                for (LoadBalancingRule rule : rules) {
-                    if (!schemeCaps.contains(rule.getScheme().toString())) {
-                        s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider "
-                                + getName());
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD, eventDescription = "Registering NetScaler Service Package")
-    public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        NetScalerServicePackageVO servicePackage = new NetScalerServicePackageVO(cmd);
-        NetScalerServicePackageResponse response = null;
-        _netscalerServicePackageDao.persist(servicePackage);
-        response = new NetScalerServicePackageResponse(servicePackage);
-        return response;
-    }
-
-    @Override
-    @DB
-    public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd cmd) {
-
-        if (_netscalerControlCenterDao.listAll() != null && _netscalerControlCenterDao.listAll().size() != 0)
-            throw new CloudRuntimeException("One Netscaler Control Center already exist in the DataBase. At a time only one Netscaler Control Center is allowed");
-
-        final RegisterNetscalerControlCenterCmd cmdinfo = cmd;
-        String ipAddress = cmd.getIpaddress();
-        Map hostDetails = new HashMap<String, String>();
-        String hostName = "NetscalerControlCenter";
-        hostDetails.put("name", hostName);
-        hostDetails.put("guid", UUID.randomUUID().toString());
-        List<DataCenterVO> dcVO = _dcDao.listEnabledZones();
-        if (dcVO.size() == 0) {
-            throw new CloudRuntimeException("There is no single enabled zone. Please add a zone, enable it and then add Netscaler ControlCenter");
-        }
-        hostDetails.put("zoneId", "1");
-        hostDetails.put("ip", ipAddress);
-        hostDetails.put("username", cmd.getUsername());
-        hostDetails.put("password", cmd.getPassword());
-        hostDetails.put("deviceName", "Netscaler ControlCenter");
-        ServerResource resource = new NetScalerControlCenterResource();
-        try {
-            resource.configure(hostName, hostDetails);
-            return Transaction.execute(new TransactionCallback<NetScalerControlCenterVO>() {
-                @Override
-                public NetScalerControlCenterVO doInTransaction(TransactionStatus status) {
-                    NetScalerControlCenterVO nccVO = new NetScalerControlCenterVO(cmdinfo.getUsername(), DBEncryptionUtil.encrypt(cmdinfo.getPassword()),
-                            cmdinfo.getIpaddress(), cmdinfo.getNumretries());
-                    _netscalerControlCenterDao.persist(nccVO);
-                    return nccVO;
-                }
-            });
-        } catch (ConfigurationException e) {
-            resource = null;
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @Override
-    public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) {
-        DataCenter zone = _dcDao.findById(cmd.getZoneId());
-        DeployDestination dest = new DeployDestination(zone, null, null, null);
-        Map<String,Object> resp = new HashMap<String, Object>();
-        Long templateId = cmd.getTemplateId();
-        Long serviceOfferingId = cmd.getServiceOfferingId();
-        DeploymentPlan plan = new DataCenterDeployment(dest.getDataCenter().getId());
-        try {
-             resp =  _netScalerVMManager.deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
-        } catch (InsufficientCapacityException e) {
-            e.printStackTrace();
-        }
-        return resp;
-    }
-
-    @Override
-    public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException,
-            ResourceUnavailableException {
-        return _netScalerVMManager.stopNetScalerVm(id, forced, callingAccount, callingUserId);
-    }
-}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
deleted file mode 100644
index 347186c..0000000
--- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
+++ /dev/null
@@ -1,924 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.resource;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.lang.StringEscapeUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.conn.ssl.TrustStrategy;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.BasicClientConnectionManager;
-import org.apache.http.util.EntityUtils;
-import org.apache.log4j.Logger;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import com.google.gson.Gson;
-
-import com.cloud.agent.IAgentControl;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
-import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
-import com.cloud.agent.api.MaintainAnswer;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.NetScalerImplementNetworkCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
-import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
-import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
-import com.cloud.agent.api.routing.IpAssocAnswer;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
-import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
-import com.cloud.resource.ServerResource;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.utils.net.NetUtils;
-
-class NccHttpCode {
-    static final String INTERNAL_ERROR  = "INTERNAL ERROR";
-    static final String NOT_FOUND = "NOT FOUND";
-    static final String JOB_ID = "Job_id";
-    static final String UNAUTHORIZED  = "UNAUTHORIZED";
-}
-
-public class NetScalerControlCenterResource implements ServerResource {
-
-    // deployment configuration
-    private String _name;
-    private String _zoneId;
-    private String _ip;
-    private String _username;
-    private String _password;
-    private String _publicInterface;
-    private String _privateInterface;
-    private Integer _numRetries;
-    private Long _nccCmdTimeout;
-    private String _guid;
-    private boolean _inline;
-    private String _deviceName;
-    private String _sessionid;
-    public static final int DEFAULT_PORT = 443;
-    private static final Gson s_gson = GsonHelper.getGson();
-    private static final Logger s_logger = Logger.getLogger(NetScalerControlCenterResource.class);
-    protected Gson _gson;
-    private final String _objectNamePathSep = "-";
-    final String protocol="https";
-    private static String nccsession;
-    private int pingCount = 0;
-
-    public NetScalerControlCenterResource() {
-        _gson = GsonHelper.getGsonLogger();
-    }
-
-
-    public static String get_nccsession() {
-        return nccsession;
-    }
-
-
-    public static void set_nccsession(String nccsession) {
-        NetScalerControlCenterResource.nccsession = nccsession;
-    }
-
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        JSONObject jsonResponse = null;
-        try {
-            _name = (String)params.get("name");
-            if (_name == null) {
-                throw new ConfigurationException("Unable to find name in the configuration parameters");
-            }
-
-            _zoneId = (String)params.get("zoneId");
-            if (_zoneId == null) {
-                throw new ConfigurationException("Unable to find zone Id  in the configuration parameters");
-            }
-
-            _ip = (String)params.get("ip");
-            if (_ip == null) {
-                throw new ConfigurationException("Unable to find IP address in the configuration parameters");
-            }
-
-            _username = (String)params.get("username");
-            if (_username == null) {
-                throw new ConfigurationException("Unable to find username in the configuration parameters");
-            }
-
-            _password =  (String)params.get("password");
-            if (_password == null) {
-                throw new ConfigurationException("Unable to find password in the configuration parameters");
-            }
-
-            _numRetries = NumbersUtil.parseInt((String)params.get("numretries"), 2);
-
-            _guid = (String)params.get("guid");
-            if (_guid == null) {
-                throw new ConfigurationException("Unable to find the guid in the configuration parameters");
-            }
-
-            _deviceName = (String)params.get("deviceName");
-            if (_deviceName == null) {
-                throw new ConfigurationException("Unable to find the device name in the configuration parameters");
-            }
-            _nccCmdTimeout = NumbersUtil.parseLong((String)params.get("numretries"), 600000);
-
-            // validate device configuration parameters
-            login();
-
-            return true;
-        } catch (ConfigurationException e) {
-            throw new ConfigurationException(e.getMessage());
-        } catch (ExecutionException e) {
-            s_logger.debug("Execution Exception :" +  e.getMessage());
-            throw new ConfigurationException("Failed to add the device. Please check the device is NCC and It is reachable from Management Server.");
-        }
-    }
-
-    public void getServicePackages() throws ExecutionException {
-            String result = null;
-            try {
-                URI agentUri = null;
-                agentUri =
-                        new URI("https", null, _ip, DEFAULT_PORT,
-                                "/admin/v1/servicepackages", null, null);
-
-                org.json.JSONObject jsonBody = new JSONObject();
-                org.json.JSONObject jsonCredentials = new JSONObject();
-                result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-                s_logger.debug("List of Service Packages in NCC:: " + result);
-                } catch (URISyntaxException e) {
-                    String errMsg = "Could not generate URI for Hyper-V agent";
-                    s_logger.error(errMsg, e);
-
-                } catch (Exception e) {
-                throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
-            }
-    }
-
-    private synchronized String login() throws ExecutionException{
-        String result = null;
-        JSONObject jsonResponse = null;
-        try {
-            URI agentUri = null;
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/nitro/v2/config/" + "login", null, null);
-            org.json.JSONObject jsonBody = new JSONObject();
-            org.json.JSONObject jsonCredentials = new JSONObject();
-            jsonCredentials.put("username", _username);
-            jsonCredentials.put("password", _password);
-            jsonBody.put("login", jsonCredentials);
-
-            result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-            if (result == null) {
-                throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
-            } else {
-                jsonResponse = new JSONObject(result);
-                org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
-                _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
-                s_logger.debug("New Session id from NCC :" + _sessionid);
-                set_nccsession(_sessionid);
-                s_logger.debug("session on Static Session variable" + get_nccsession());
-            }
-            s_logger.debug("Login to NCC Device response :: " + result);
-            return result;
-            } catch (URISyntaxException e) {
-                String errMsg = "Could not generate URI for Hyper-V agent";
-                s_logger.error(errMsg, e);
-
-            } catch (JSONException e) {
-                s_logger.debug("JSON Exception :" +  e.getMessage());
-                throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
-            } catch (Exception e) {
-            throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
-        }
-        return result;
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-        StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand(Host.Type.NetScalerControlCenter);
-        cmd.setName(_name);
-        cmd.setDataCenter(_zoneId);
-        cmd.setPod("");
-        cmd.setPrivateIpAddress(_ip);
-        cmd.setStorageIpAddress("");
-        cmd.setVersion(NetScalerControlCenterResource.class.getPackage().getImplementationVersion());
-        cmd.setGuid(_guid);
-        return new StartupCommand[] {cmd};
-    }
-
-    @Override
-    public Answer executeRequest(Command cmd) {
-        return executeRequest(cmd, _numRetries);
-    }
-
-    private Answer executeRequest(Command cmd, int numRetries) {
-        if (cmd instanceof ReadyCommand) {
-            return execute((ReadyCommand)cmd);
-        } else if (cmd instanceof MaintainCommand) {
-            return execute((MaintainCommand)cmd);
-        } else if (cmd instanceof IpAssocCommand) {
-            return execute((IpAssocCommand)cmd, numRetries);
-        } else if (cmd instanceof LoadBalancerConfigCommand) {
-            return execute((LoadBalancerConfigCommand)cmd, numRetries);
-        } else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
-            return execute((ExternalNetworkResourceUsageCommand)cmd, numRetries);
-        } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        } else if (cmd instanceof SetStaticNatRulesCommand) {
-            return execute((SetStaticNatRulesCommand)cmd, numRetries);
-        } else if (cmd instanceof GlobalLoadBalancerConfigCommand) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        } else if (cmd instanceof HealthCheckLBConfigCommand) {
-            return execute((HealthCheckLBConfigCommand)cmd, numRetries);
-        } else if (cmd instanceof NetScalerImplementNetworkCommand ) {
-            return execute((NetScalerImplementNetworkCommand)cmd, numRetries);
-        }
-        else {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    private Answer execute(ReadyCommand cmd) {
-        return new ReadyAnswer(cmd);
-    }
-
-    protected Answer execute(MaintainCommand cmd) {
-        return new MaintainAnswer(cmd);
-    }
-
-    private void keepSessionAlive() throws ExecutionException {
-        URI agentUri = null;
-        try {
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/cca/v1/cloudstacks", null, null);
-            org.json.JSONObject jsonBody = new JSONObject();
-            getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-            s_logger.debug("Keeping Session Alive");
-        } catch (URISyntaxException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private String queryAsyncJob(String jobId) throws ExecutionException {
-        String result = null;
-        try {
-            URI agentUri = null;
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/admin/v1/journalcontexts/" + jobId, null, null);
-
-            org.json.JSONObject jsonBody = new JSONObject();
-
-            long startTick = System.currentTimeMillis();
-            while (System.currentTimeMillis() - startTick <  _nccCmdTimeout) {
-                result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-                JSONObject response = new JSONObject(result);
-                if(response != null ) {
-                    s_logger.debug("Job Status result for ["+jobId + "]:: " + result + " Tick and currentTime :" +  System.currentTimeMillis() +" -" + startTick + "job cmd timeout :" +_nccCmdTimeout);
-                    String status = response.getJSONObject("journalcontext").getString("status").toUpperCase();
-                    String message = response.getJSONObject("journalcontext").getString("message");
-                    s_logger.debug("Job Status Progress Status ["+ jobId + "]:: " + status);
-                    switch(status) {
-                    case "FINISHED":
-                            return status;
-                    case "IN PROGRESS":
-                        break;
-                    case "ERROR, ROLLBACK IN PROGRESS":
-                        break;
-                    case "ERROR, ROLLBACK COMPLETED":
-                        throw new ExecutionException("ERROR, ROLLBACK COMPLETED " + message);
-                    case "ERROR, ROLLBACK FAILED":
-                        throw new ExecutionException("ERROR, ROLLBACK FAILED " + message);
-                    }
-                }
-            }
-
-        } catch (URISyntaxException e) {
-            String errMsg = "Could not generate URI for NetScaler ControlCenter";
-            s_logger.error(errMsg, e);
-          } catch (JSONException e) {
-            e.printStackTrace();
-        }
-        return result;
-    }
-    private synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) {
-        String result = null;
-        try {
-            URI agentUri = null;
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/adcaas/v1/networks", null, null);
-            org.json.JSONObject jsonBody = new JSONObject(cmd.getDetails());
-            s_logger.debug("Sending Network Implement to NCC:: " + jsonBody);
-            result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-            s_logger.debug("Result of Network Implement to NCC:: " + result);
-            result = queryAsyncJob(result);
-            s_logger.debug("Done query async of network implement request :: " + result);
-            return new Answer(cmd, true, "Successfully allocated device");
-            } catch (URISyntaxException e) {
-                String errMsg = "Could not generate URI for NetScaler ControlCenter ";
-                s_logger.error(errMsg, e);
-            } catch (ExecutionException e) {
-                if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) {
-                    return new Answer(cmd, true, "Successfully unallocated the device");
-                }else if(e.getMessage().startsWith("ERROR, ROLLBACK") ) {
-                    s_logger.error(e.getMessage());
-                    return new Answer(cmd, false, e.getMessage());
-                }
-                else {
-                    if (shouldRetry(numRetries)) {
-                        s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries );
-                        return retry(cmd, numRetries);
-                    } else {
-                        return new Answer(cmd, false, e.getMessage());
-                    }
-                }
-            } catch (Exception e) {
-                if (shouldRetry(numRetries)) {
-                    s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries );
-                    return retry(cmd, numRetries);
-                } else {
-                    return new Answer(cmd, false, e.getMessage());
-                }
-            }
-
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    private synchronized Answer execute(IpAssocCommand cmd,  int numRetries) {
-
-        String[] results = new String[cmd.getIpAddresses().length];
-        int i = 0;
-        IpAddressTO[] ips = cmd.getIpAddresses();
-        for (IpAddressTO ip : ips) {
-            results[i++] = ip.getPublicIp() + " - success";
-        }
-
-        return new IpAssocAnswer(cmd, results);
-    }
-
-    private Answer execute(HealthCheckLBConfigCommand cmd, int numRetries) {
-
-        List<LoadBalancerTO> hcLB = new ArrayList<LoadBalancerTO>();
-        try {
-
-            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
-
-            if (loadBalancers == null) {
-                return new HealthCheckLBConfigAnswer(hcLB);
-            }
-            String result = getLBHealthChecks(cmd.getNetworkId());
-            JSONObject res =  new JSONObject(result);
-            JSONArray lbstatus = res.getJSONArray("lbhealthstatus");
-            for(int i=0; i<lbstatus.length(); i++) {
-                JSONObject lbstat = lbstatus.getJSONObject(i);
-                LoadBalancerTO loadBalancer = null;
-                JSONArray dest = lbstat.getJSONArray("destinations");
-                List<DestinationTO> listDestTo = new ArrayList<DestinationTO>();
-                for(int d=0; d<dest.length(); d++ ) {
-                    JSONObject dt = dest.getJSONObject(d);
-                    if( dt!=null ) {
-                        DestinationTO destTO = new DestinationTO(dt.getString("destIp"), dt.getInt("destPort"), dt.getString("monitorState"));
-                        listDestTo.add(destTO);
-                    }
-                }
-                loadBalancer = new LoadBalancerTO(lbstat.getString("lb_uuid"),listDestTo);
-                hcLB.add(loadBalancer);
-            }
-        } catch (ExecutionException e) {
-            s_logger.error("Failed to execute HealthCheckLBConfigCommand due to ", e);
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new HealthCheckLBConfigAnswer(hcLB);
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to execute HealthCheckLBConfigCommand due to ", e);
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new HealthCheckLBConfigAnswer(hcLB);
-            }
-        }
-        return new HealthCheckLBConfigAnswer(hcLB);
-    }
-
-    private String getLBHealthChecks(long networkid) throws ExecutionException  {
-        URI agentUri = null;
-        String response = null;
-        try {
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/adcaas/v1/networks/"+ networkid +"/lbhealthstatus", null, null);
-            org.json.JSONObject jsonBody = new JSONObject();
-            response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-            s_logger.debug("LBHealthcheck Response :" + response);
-        } catch (URISyntaxException e) {
-            e.printStackTrace();
-        }
-        return response;
-    }
-    private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
-        try {
-            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
-            if (loadBalancers == null) {
-                return new Answer(cmd);
-            }
-            JSONObject lbConfigPaylod = new JSONObject(cmd);
-            String gsonLBConfig =  _gson.toJson(cmd);
-            URI agentUri = null;
-            agentUri =
-                    new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/adcaas/v1/loadbalancerCmds", null, null);
-            JSONObject lbConfigCmd = new JSONObject();
-            JSONObject lbcmd = new JSONObject(gsonLBConfig);
-            s_logger.debug("LB config from gsonstring to JSONObject : " +  lbcmd.toString() + "\n" + "gson cmd is :: \t" + gsonLBConfig);
-            lbConfigCmd.put("LoadBalancerConfigCommand",  lbcmd.getJSONArray("loadBalancers"));
-            s_logger.debug("LB config paylod : " +  lbConfigCmd.toString());
-
-            String result = postHttpRequest(lbConfigCmd.toString(), agentUri, _sessionid);
-            s_logger.debug("Result of lbconfigcmg is "+ result);
-            result = queryAsyncJob(result);
-            s_logger.debug("Done query async of LB ConfigCmd implement request and result:: " + result);
-            return new Answer(cmd);
-        } catch (ExecutionException e) {
-            s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
-            if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) {
-                return new Answer(cmd, true, "LB Rule is not present in NS device. So returning as removed the LB Rule");
-            } else  if(e.getMessage().startsWith("ERROR, ROLLBACK COMPLETED") || e.getMessage().startsWith("ERROR, ROLLBACK FAILED")) {
-                s_logger.error("Failed to execute LoadBalancerConfigCommand due to : " + e.getMessage());
-                return new Answer(cmd, false, e.getMessage());
-            } else if (e.getMessage().startsWith(NccHttpCode.INTERNAL_ERROR)) {
-                s_logger.error("Failed to execute LoadBalancerConfigCommand as Internal Error returning Internal error ::" + e.getMessage() );
-                return new Answer(cmd, false, e.getMessage());
-            }
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new Answer(cmd, false, e.getMessage());
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new Answer(cmd, false, e.getMessage());
-            }
-        }
-    }
-
-    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
-        try {
-
-            return getPublicIpBytesSentAndReceived(cmd);
-
-        } catch (ExecutionException e) {
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new ExternalNetworkResourceUsageAnswer(cmd, e);
-            }
-        }
-    }
-
-
-    private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException {
-        String port = Integer.toString(loadBalancer.getSrcPort());
-        String lbProtocol = loadBalancer.getLbProtocol();
-        StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies();
-        String nsProtocol = "TCP";
-
-        if (lbProtocol == null)
-            lbProtocol = loadBalancer.getProtocol();
-
-        if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)) {
-            StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
-            if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) ||
-                    (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) {
-                nsProtocol = "HTTP";
-                return nsProtocol;
-            }
-        }
-
-        if (lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO) || lbProtocol.equalsIgnoreCase(NetUtils.HTTP_PROTO))
-            return lbProtocol.toUpperCase();
-
-        if (port.equals(NetUtils.HTTP_PORT)) {
-            nsProtocol = "HTTP";
-        } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) {
-            nsProtocol = "TCP";
-        } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) {
-            nsProtocol = "UDP";
-        }
-
-        return nsProtocol;
-    }
-
-
-    private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
-        ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
-        long networkid = cmd.getNetworkid();
-        try {
-            //TODO send GET cmd to get the network stats
-
-            URI agentUri = null;
-            String response = null;
-            try {
-                agentUri =
-                        new URI("https", null, _ip, DEFAULT_PORT,
-                                "/cs/adcaas/v1/networks/"+ networkid +"/ipStats", null, null);
-                org.json.JSONObject jsonBody = new JSONObject();
-                response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-                JSONArray statsIPList = null;
-                if(response !=null ) {
-                    statsIPList = new JSONObject(response).getJSONObject("stats") .getJSONArray("ipBytes");
-                }
-                if(statsIPList != null) {
-                    for(int i=0; i<statsIPList.length(); i++) {
-                        JSONObject ipstat = statsIPList.getJSONObject(i);
-                        JSONObject ipvalues =  ipstat.getJSONObject("ipstats");
-                        if(ipstat != null) {
-                            long[] bytesSentAndReceived = new long[] {0, 0};
-                            bytesSentAndReceived[0] = ipvalues.getLong("received");
-                            bytesSentAndReceived[1] = ipvalues.getLong("sent");
-
-                            if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
-                                answer.ipBytes.put(ipstat.getString("ip"), bytesSentAndReceived);
-                            }
-                       }
-                    }
-                }
-                s_logger.debug("IPStats Response :" + response);
-            } catch (URISyntaxException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                s_logger.debug("Seesion Alive" + e.getMessage());
-                e.printStackTrace();
-            }
-
-        } catch (Exception e) {
-            s_logger.error("Failed to get bytes sent and recived statistics due to " + e);
-            throw new ExecutionException(e.getMessage());
-        }
-
-        return answer;
-    }
-
-    private Answer retry(Command cmd, int numRetries) {
-        int numRetriesRemaining = numRetries - 1;
-        s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining);
-        return executeRequest(cmd, numRetriesRemaining);
-    }
-
-    private boolean shouldRetry(int numRetries) {
-        try {
-            if (numRetries > 0) {
-                login();
-                return true;
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to log in to Netscaler ControlCenter device at " + _ip + " due to " + e.getMessage());
-            return false;
-        }
-        return false;
-    }
-
-
-    @Override
-    public IAgentControl getAgentControl() {
-        return null;
-    }
-
-    private boolean refreshNCCConnection() {
-        boolean ret = false;
-        try {
-            keepSessionAlive();
-            return true;
-        } catch (ExecutionException ex) {
-            s_logger.debug("Failed to keep up the session alive ", ex);
-        }
-        return ret;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(long id) {
-        pingCount++;
-        if (pingCount > 10 && refreshNCCConnection()) {
-            pingCount = 0;
-        }
-        return new PingCommand(Host.Type.NetScalerControlCenter, id);
-    }
-
-    @Override
-    public Type getType() {
-        return Host.Type.NetScalerControlCenter ;
-    }
-
-    @Override
-    public void setAgentControl(IAgentControl agentControl) {
-        return;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public void setName(String name) {
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public void disconnected() {
-        return;
-    }
-
-    @Override
-    public void setConfigParams(Map<String, Object> params) {
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        return null;
-    }
-
-    @Override
-    public int getRunLevel() {
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(int level) {
-    }
-
-    public String getSessionID() {
-        return _sessionid;
-    }
-    public static String cleanPassword(String logString) {
-        String cleanLogString = null;
-        if (logString != null) {
-            cleanLogString = logString;
-            String[] temp = logString.split(",");
-            int i = 0;
-            if (temp != null) {
-                while (i < temp.length) {
-                    temp[i] = StringUtils.cleanString(temp[i]);
-                    i++;
-                }
-                List<String> stringList = new ArrayList<String>();
-                Collections.addAll(stringList, temp);
-                cleanLogString = StringUtils.join(stringList, ",");
-            }
-        }
-        return cleanLogString;
-    }
-    public static HttpClient getHttpClient() {
-
-        HttpClient httpClient = null;
-        TrustStrategy easyStrategy = new TrustStrategy() {
-            @Override
-            public boolean isTrusted(X509Certificate[] chain, String authType)
-                    throws CertificateException {
-                return true;
-            }
-        };
-
-        try {
-            SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
-            SchemeRegistry registry = new SchemeRegistry();
-            registry.register(new Scheme("https", DEFAULT_PORT, sf));
-            ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
-            httpClient = new DefaultHttpClient(ccm);
-        } catch (KeyManagementException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (UnrecoverableKeyException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (NoSuchAlgorithmException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (KeyStoreException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        }
-        return httpClient;
-    }
-
-    public static String getHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException {
-        // Using Apache's HttpClient for HTTP POST
-        // Java-only approach discussed at on StackOverflow concludes with
-        // comment to use Apache HttpClient
-        // http://stackoverflow.com/a/2793153/939250, but final comment is to
-        // use Apache.
-        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
-        logMessage = cleanPassword(logMessage);
-        s_logger.debug("POST request to " + agentUri.toString()
-                + " with contents " + logMessage);
-
-        // Create request
-        HttpClient httpClient = getHttpClient();
-        String result = null;
-
-        // TODO: are there timeout settings and worker thread settings to tweak?
-        try {
-            HttpGet request = new HttpGet(agentUri);
-
-            // JSON encode command
-            // Assumes command sits comfortably in a string, i.e. not used for
-            // large data transfers
-            StringEntity cmdJson = new StringEntity(jsonCmd);
-            request.addHeader("content-type", "application/json");
-            request.addHeader("Cookie", "SessId=" + sessionID);
-            s_logger.debug("Sending cmd to " + agentUri.toString()
-                    + " cmd data:" + logMessage);
-            HttpResponse response = httpClient.execute(request);
-
-            // Unsupported commands will not route.
-            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
-                String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode();
-                s_logger.error(errMsg);
-                String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right f of" + " server?";
-                Answer ans = new UnsupportedAnswer(null, unsupportMsg);
-                s_logger.error(ans);
-                result = s_gson.toJson(new Answer[] {ans});
-            } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-                String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
-                s_logger.error(errMsg);
-                throw new ExecutionException("UNAUTHORIZED");
-            } else {
-                result = EntityUtils.toString(response.getEntity());
-                String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
-                s_logger.debug("Get response is " + logResult);
-            }
-        } catch (ClientProtocolException protocolEx) {
-            // Problem with HTTP message exchange
-            s_logger.error(protocolEx);
-        } catch (IOException connEx) {
-            // Problem with underlying communications
-            s_logger.error(connEx);
-        } finally {
-            httpClient.getConnectionManager().shutdown();
-        }
-        return result;
-    }
-
-    public static String postHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException {
-        // Using Apache's HttpClient for HTTP POST
-        // Java-only approach discussed at on StackOverflow concludes with
-        // comment to use Apache HttpClient
-        // http://stackoverflow.com/a/2793153/939250, but final comment is to
-        // use Apache.
-        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
-        logMessage = cleanPassword(logMessage);
-        s_logger.debug("POST request to " + agentUri.toString()
-                + " with contents " + logMessage);
-
-        // Create request
-        HttpClient httpClient = getHttpClient();
-        TrustStrategy easyStrategy = new TrustStrategy() {
-            @Override
-            public boolean isTrusted(X509Certificate[] chain, String authType)
-                    throws CertificateException {
-                return true;
-            }
-        };
-
-        try {
-            SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
-            SchemeRegistry registry = new SchemeRegistry();
-            registry.register(new Scheme("https", DEFAULT_PORT, sf));
-            ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
-            httpClient = new DefaultHttpClient(ccm);
-        } catch (KeyManagementException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (UnrecoverableKeyException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (NoSuchAlgorithmException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        } catch (KeyStoreException e) {
-            s_logger.error("failed to initialize http client " + e.getMessage());
-        }
-
-        String result = null;
-
-        // TODO: are there timeout settings and worker thread settings to tweak?
-        try {
-            HttpPost request = new HttpPost(agentUri);
-
-            // JSON encode command
-            // Assumes command sits comfortably in a string, i.e. not used for
-            // large data transfers
-            StringEntity cmdJson = new StringEntity(jsonCmd);
-            request.addHeader("content-type", "application/json");
-            request.addHeader("Cookie", "SessId=" + sessionID);
-            request.setEntity(cmdJson);
-            s_logger.debug("Sending cmd to " + agentUri.toString()
-                    + " cmd data:" + logMessage + "SEssion id: " + sessionID);
-            HttpResponse response = httpClient.execute(request);
-
-            // Unsupported commands will not route.
-            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
-                String errMsg = "Failed : HTTP error code : " + response.getStatusLine().getStatusCode();
-                throw new ExecutionException(NccHttpCode.NOT_FOUND);
-            } else if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK ) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED )) {
-                String errMsg = "Command Not Success " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
-                s_logger.error(errMsg);
-                throw new ExecutionException(NccHttpCode.INTERNAL_ERROR + " " + errMsg);
-            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
-                //Successfully created the resource in the NCC, Now get the Job ID and send to the response
-                // make login request and store new session id
-                throw new ExecutionException(NccHttpCode.UNAUTHORIZED);
-            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
-                //Successfully created the resource in the NCC, Now get the Job ID and send to the response
-                result = response.getFirstHeader(NccHttpCode.JOB_ID).getValue();
-            } else {
-                result = EntityUtils.toString(response.getEntity());
-                String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
-                s_logger.debug("POST response is " + logResult);
-            }
-
-        } catch (ClientProtocolException protocolEx) {
-            // Problem with HTTP message exchange
-            s_logger.error(protocolEx);
-        } catch (IOException connEx) {
-            // Problem with underlying communications
-            s_logger.error(connEx);
-        } finally {
-            httpClient.getConnectionManager().shutdown();
-        }
-        return result;
-    }
-}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/AddNetscalerLoadBalancerCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ConfigureNetscalerLoadBalancerCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/DeployNetscalerVpxCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerControlCenterCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerControlCenterCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerLoadBalancerNetworksCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerLoadBalancerNetworksCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerLoadBalancerNetworksCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerLoadBalancerNetworksCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerLoadBalancersCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerLoadBalancersCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerLoadBalancersCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListNetscalerLoadBalancersCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListRegisteredServicePackageCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/ListRegisteredServicePackageCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/RegisterServicePackageCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/RegisterServicePackageCmd.java
new file mode 100644
index 0000000..ae2d59b
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/RegisterServicePackageCmd.java
@@ -0,0 +1,95 @@
+//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.api.commands;
+
+import javax.inject.Inject;
+import javax.persistence.EntityExistsException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.api.response.NetScalerServicePackageResponse;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.element.NetscalerLoadBalancerElementService;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "registerNetscalerServicePackage", responseObject = NetScalerServicePackageResponse.class, description = "Registers NCC Service Package")
+public class RegisterServicePackageCmd extends BaseCmd {
+
+    public static final Logger s_logger = Logger.getLogger(RegisterServicePackageCmd.class.getName());
+    private static final String s_name = "registerNetscalerServicePackage";
+
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the service Package.")
+    private String spName;
+
+    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true, description = "Description of Service Package")
+    private String description;
+
+
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
+        try {
+            NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this);
+            if (response != null) {
+                response.setObjectName("netscalerservicepackage");
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Service Package due to internal error.");
+            }
+        } catch (InvalidParameterValueException invalidParamExcp) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
+        } catch (CloudRuntimeException runtimeExcp) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
+        } catch (EntityExistsException runtimeExcp) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Service Package Already Exists with Name " + getSpName());
+        }
+
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccount().getId();
+    }
+
+    public String getSpName() {
+        return spName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/commands/StopNetScalerVMCmd.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetScalerServicePackageResponse.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetScalerServicePackageResponse.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetscalerControlCenterResponse.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetscalerControlCenterResponse.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetscalerLoadBalancerResponse.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerLoadBalancerResponse.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/api/response/NetscalerLoadBalancerResponse.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerControlCenterVO.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerControlCenterVO.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerPodVO.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerPodVO.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/NetScalerPodVO.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerPodVO.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerServicePackageVO.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/NetScalerServicePackageVO.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerControlCenterDao.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerControlCenterDao.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerPodDao.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerPodDao.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerPodDao.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerPodDao.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerPodDaoImpl.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerPodDaoImpl.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerPodDaoImpl.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerPodDaoImpl.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerServicePackageDao.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerServicePackageDao.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
new file mode 100644
index 0000000..1df1640
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
@@ -0,0 +1,1532 @@
+// 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.network.element;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+import org.apache.cloudstack.region.gslb.GslbServiceProvider;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.NetScalerImplementNetworkCommand;
+import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
+import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.commands.AddNetscalerLoadBalancerCmd;
+import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd;
+import com.cloud.api.commands.DeleteNetscalerControlCenterCmd;
+import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd;
+import com.cloud.api.commands.DeleteServicePackageOfferingCmd;
+import com.cloud.api.commands.DeployNetscalerVpxCmd;
+import com.cloud.api.commands.ListNetscalerControlCenterCmd;
+import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd;
+import com.cloud.api.commands.ListNetscalerLoadBalancersCmd;
+import com.cloud.api.commands.ListRegisteredServicePackageCmd;
+import com.cloud.api.commands.RegisterNetscalerControlCenterCmd;
+import com.cloud.api.commands.RegisterServicePackageCmd;
+import com.cloud.api.commands.StopNetScalerVMCmd;
+import com.cloud.api.response.NetScalerServicePackageResponse;
+import com.cloud.api.response.NetscalerControlCenterResponse;
+import com.cloud.api.response.NetscalerLoadBalancerResponse;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterIpAddressVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.ExternalLoadBalancerDeviceManager;
+import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.NetScalerControlCenterVO;
+import com.cloud.network.NetScalerPodVO;
+import com.cloud.network.NetScalerServicePackageVO;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.as.AutoScaleCounter;
+import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState;
+import com.cloud.network.dao.NetScalerControlCenterDao;
+import com.cloud.network.dao.NetScalerPodDao;
+import com.cloud.network.dao.NetScalerServicePackageDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
+import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRule.LbDestination;
+import com.cloud.network.resource.NetScalerControlCenterResource;
+import com.cloud.network.resource.NetscalerResource;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.LbStickinessMethod;
+import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
+import com.cloud.network.rules.LoadBalancerContainer;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.vm.NetScalerVMManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ServerResource;
+import com.cloud.user.Account;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.UrlUtil;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+import com.google.gson.Gson;
+
+public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
+implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager,
+IpDeployer, StaticNatServiceProvider, GslbServiceProvider {
+
+    private static final Logger s_logger = Logger.getLogger(NetscalerElement.class);
+    public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp");
+    public static final AutoScaleCounterType AutoScaleCounterNetscaler = new AutoScaleCounterType("netscaler");
+
+    @Inject
+    NetworkModel _networkManager;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    NetworkModel _networkMgr;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    ExternalLoadBalancerDeviceDao _lbDeviceDao;
+    @Inject
+    NetScalerControlCenterDao _netscalerControlCenterDao;
+    @Inject
+    NetworkExternalLoadBalancerDao _networkLBDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    HostDetailsDao _detailsDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    NetScalerPodDao _netscalerPodDao;
+    @Inject
+    DataCenterIpAddressDao _privateIpAddressDao;
+    @Inject
+    ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
+    @Inject
+    NetScalerServicePackageDao _netscalerServicePackageDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    HostDetailsDao _hostDetailDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    NetworkOrchestrationService _networkService;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao = null;
+    @Inject
+    NetScalerVMManager _netScalerVMManager;
+
+    private boolean canHandle(Network config, Service service) {
+        DataCenter zone = _dcDao.findById(config.getDataCenterId());
+        // Create a NCC Resource on Demand for the zone.
+
+        boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced
+                && (config.getGuestType() == Network.GuestType.Isolated
+                || config.getGuestType() == Network.GuestType.Shared)
+                && config.getTrafficType() == TrafficType.Guest);
+        boolean handleInBasicZone = (zone.getNetworkType() == NetworkType.Basic
+                && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest);
+
+        if (!(handleInAdvanceZone || handleInBasicZone)) {
+            s_logger.trace("Not handling network with Type  " + config.getGuestType() + " and traffic type "
+                    + config.getTrafficType() + " in zone of type " + zone.getNetworkType());
+            return false;
+        }
+
+        return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao
+                .canProviderSupportServiceInNetwork(config.getId(), service, Network.Provider.Netscaler));
+    }
+
+    private boolean isBasicZoneNetwok(Network config) {
+        DataCenter zone = _dcDao.findById(config.getDataCenterId());
+        return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared
+                && config.getTrafficType() == TrafficType.Guest);
+    }
+
+    @Override
+    public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest,
+            ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException,
+    InsufficientNetworkCapacityException {
+
+        if (!canHandle(guestConfig, Service.Lb)) {
+            return false;
+        }
+
+        if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestConfig.getId(), Service.StaticNat,
+                Network.Provider.Netscaler) && !isBasicZoneNetwok(guestConfig)) {
+            s_logger.error("NetScaler provider can not be Static Nat service provider for the network "
+                    + guestConfig.getGuestType() + " and traffic type " + guestConfig.getTrafficType());
+            return false;
+        }
+
+        try {
+            if (offering.getServicePackage() == null) {
+                return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
+            } else {
+                // if the network offering has service package implement it with
+                // Netscaler Control Center
+                return manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
+            }
+        } catch (InsufficientCapacityException capacityException) {
+            throw new ResourceUnavailableException(
+                    "There are no NetScaler load balancer devices with the free capacity for implementing this network",
+                    DataCenter.class, guestConfig.getDataCenterId());
+        } catch (ConfigurationException e) {
+            throw new ResourceUnavailableException(
+                    "There are no NetScaler load balancer devices with the free capacity for implementing this network : "
+                            + e.getMessage(),
+                            DataCenter.class, guestConfig.getDataCenterId());
+        }
+    }
+
+    @Override
+    public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) {
+        long zoneId = guestConfig.getDataCenterId();
+        return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter);
+    }
+
+    public HostVO allocateNCCResourceForNetwork(Network guestConfig) throws ConfigurationException {
+
+        Map<String, String> _configs;
+        List<NetScalerControlCenterVO> ncc = _netscalerControlCenterDao.listAll();
+        HostVO hostVO = null;
+        if (ncc.size() > 0) {
+            NetScalerControlCenterVO nccVO = ncc.get(0);
+            String ipAddress = nccVO.getNccip();
+            Map hostDetails = new HashMap<String, String>();
+            String hostName = "NetscalerControlCenter";
+            hostDetails.put("name", hostName);
+            hostDetails.put("guid", UUID.randomUUID().toString());
+            hostDetails.put("zoneId", Long.toString(guestConfig.getDataCenterId()));
+            hostDetails.put("ip", ipAddress);
+            hostDetails.put("username", nccVO.getUsername());
+            hostDetails.put("password", DBEncryptionUtil.decrypt(nccVO.getPassword()));
+            hostDetails.put("deviceName", "netscaler control center");
+            hostDetails.put("cmdTimeOut", Long.toString(NumbersUtil.parseInt(_configDao.getValue(Config.NCCCmdTimeOut.key()), 600000)));
+            ServerResource resource = new NetScalerControlCenterResource();
+            resource.configure(hostName, hostDetails);
+            final Host host = _resourceMgr.addHost(guestConfig.getDataCenterId(), resource, Host.Type.NetScalerControlCenter, hostDetails);
+            hostVO = _hostDao.findById(host.getId());
+        }
+        return hostVO;
+    }
+
+    public boolean manageGuestNetworkWithNetscalerControlCenter(boolean add, Network guestConfig,
+            NetworkOffering offering)
+                    throws ResourceUnavailableException, InsufficientCapacityException, ConfigurationException {
+
+        if (guestConfig.getTrafficType() != TrafficType.Guest) {
+            s_logger.trace("External load balancer can only be used for guest networks.");
+            return false;
+        }
+
+        long zoneId = guestConfig.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        HostVO netscalerControlCenter = null;
+
+        if (add) {
+            HostVO lbDeviceVO = null;
+            // on restart network, device could have been allocated already,
+            // skip allocation if a device is assigned
+            lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
+            if (lbDeviceVO == null) {
+                // allocate a load balancer device for the network
+                lbDeviceVO = allocateNCCResourceForNetwork(guestConfig);
+                if (lbDeviceVO == null) {
+                    String msg = "failed to allocate Netscaler ControlCenter Resource for the zone in the network "
+                            + guestConfig.getId();
+                    s_logger.error(msg);
+                    throw new InsufficientNetworkCapacityException(msg, DataCenter.class,
+                            guestConfig.getDataCenterId());
+                }
+            }
+            netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
+            s_logger.debug("Allocated Netscaler Control Center device:" + lbDeviceVO.getId() + " for the network: "
+                    + guestConfig.getId());
+        } else {
+            // find the load balancer device allocated for the network
+
+            HostVO lbDeviceVO = null;
+            // on restart network, device could have been allocated already, skip allocation if a device is assigned
+            lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig);
+            if (lbDeviceVO == null) {
+                s_logger.warn(
+                        "Network shutdwon requested on external load balancer element, which did not implement the network."
+                                + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
+                return true;
+            }
+
+            netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId());
+            assert(netscalerControlCenter != null) : "There is no device assigned to this network how did shutdown network ended up here??";
+        }
+        JSONObject networkDetails = new JSONObject();
+        JSONObject networkPayload = new JSONObject();
+
+        String selfIp = null;
+        try {
+            networkDetails.put("id", guestConfig.getId());
+            networkDetails.put("vlan", guestConfig.getBroadcastUri());
+            networkDetails.put("cidr", guestConfig.getCidr());
+            networkDetails.put("gateway", guestConfig.getGateway());
+            networkDetails.put("servicepackage_id", offering.getServicePackage());
+            networkDetails.put("zone_id", zone.getUuid());
+            networkDetails.put("account_id", guestConfig.getAccountId());
+            networkDetails.put("add", Boolean.toString(add));
+            selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
+            if (selfIp == null) {
+                String msg = "failed to acquire guest IP address so not implementing the network on the NetscalerControlCenter";
+                s_logger.error(msg);
+                throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
+            }
+            networkDetails.put("snip", selfIp);
+            // TODO region is hardcoded make it dynamic
+            networkDetails.put("region_id", 1);
+            networkDetails.put("name", guestConfig.getName());
+            networkPayload.put("network", networkDetails);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+
+        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zone.getUuid(), netscalerControlCenter.getId(), networkPayload.toString());
+        Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
+        if (add) {
+            //TODO After getting the answer check with the job id and do poll on the job and then save the selfip or acquired guest ip to the Nics table
+            if (answer != null) {
+                if (answer.getResult() == true) {
+                    if (add) {
+                        // Insert a new NIC for this guest network to reserve the self IP
+                        _networkService.savePlaceholderNic(guestConfig, selfIp, null, null);
+                    }
+                } else {
+                    return false;
+                }
+            }
+        } else {
+            if (answer != null) {
+                if (answer.getResult() == true) {
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest,
+            ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException,
+    ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) {
+        return true;
+    }
+
+    @Override
+    public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup)
+            throws ResourceUnavailableException, ConcurrentOperationException {
+        if (!canHandle(guestConfig, Service.Lb)) {
+            return false;
+        }
+
+        try {
+
+            NetworkOffering networkOffering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
+            if (networkOffering.getServicePackage() == null) {
+                return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
+            } else {
+                // if the network offering has service package implement it with Netscaler Control Center
+                return manageGuestNetworkWithNetscalerControlCenter(false, guestConfig, networkOffering);
+            }
+        } catch (InsufficientCapacityException capacityException) {
+            // TODO: handle out of capacity exception gracefully in case of
+            // multple providers available
+            return false;
+        } catch (ConfigurationException e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public boolean destroy(Network config, ReservationContext context) {
+        return true;
+    }
+
+    @Override
+    public boolean validateLBRule(Network network, LoadBalancingRule rule) {
+        if (canHandle(network, Service.Lb)) {
+            String algo = rule.getAlgorithm();
+            return (algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source"));
+        }
+        return true;
+    }
+
+    @Override
+    public boolean applyLBRules(Network config, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
+        if (!canHandle(config, Service.Lb)) {
+            return false;
+        }
+
+        if (!canHandleLbRules(rules)) {
+            return false;
+        }
+
+        if (isBasicZoneNetwok(config)) {
+            return applyElasticLoadBalancerRules(config, rules);
+        } else {
+            return applyLoadBalancerRules(config, rules);
+        }
+    }
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+
+        // Set capabilities for LB service
+        Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
+
+        // Specifies that the RoundRobin and Leastconn algorithms are supported for load balancing rules
+        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin, leastconn, source");
+
+        // specifies that Netscaler network element can provided both shared and
+        // isolation modes
+        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated, shared");
+
+        // Specifies that load balancing rules can be made for either TCP or UDP
+        // traffic
+        lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp,http");
+
+        // Specifies that this element can measure network usage on a per public
+        // IP basis
+        lbCapabilities.put(Capability.TrafficStatistics, "per public ip");
+
+        // Specifies that load balancing rules can only be made with public IPs
+        // that aren't source NAT IPs
+        lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional");
+
+        // Supports only Public load balancing
+        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
+
+        // Support inline mode with firewall
+        lbCapabilities.put(Capability.InlineMode, "true");
+
+        // Specifies that load balancing rules can support autoscaling and the list of counters it supports
+        // list of counters it supports
+        AutoScaleCounter counter;
+        List<AutoScaleCounter> counterList = new ArrayList<AutoScaleCounter>();
+        counter = new AutoScaleCounter(AutoScaleCounterSnmp);
+        counterList.add(counter);
+        counter.addParam("snmpcommunity", true,
+                "the community string that has to be used to do a SNMP GET on the AutoScaled Vm", false);
+        counter.addParam("snmpport", false, "the port at which SNMP agent is running on the AutoScaled Vm", false);
+
+        counter = new AutoScaleCounter(AutoScaleCounterNetscaler);
+        counterList.add(counter);
+
+        Gson gson = new Gson();
+        String autoScaleCounterList = gson.toJson(counterList);
+        lbCapabilities.put(Capability.AutoScaleCounters, autoScaleCounterList);
+
+        LbStickinessMethod method;
+        List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>();
+        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased,
+                "This is cookie based sticky method, can be used only for http");
+        methodList.add(method);
+        method.addParam("holdtime", false, "time period in minutes for which persistence is in effect.", false);
+
+        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
+                "This is app session based sticky method, can be used only for http");
+        methodList.add(method);
+        method.addParam("name", true, "cookie name passed in http header by apllication to the client", false);
+
+        method = new LbStickinessMethod(StickinessMethodType.SourceBased,
+                "This is source based sticky method, can be used for any type of protocol.");
+        methodList.add(method);
+        method.addParam("holdtime", false, "time period for which persistence is in effect.", false);
+
+        String stickyMethodList = gson.toJson(methodList);
+        lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList);
+
+        lbCapabilities.put(Capability.ElasticLb, "true");
+        // Setting HealthCheck Capability to True for Netscaler element
+        lbCapabilities.put(Capability.HealthCheckPolicy, "true");
+        capabilities.put(Service.Lb, lbCapabilities);
+
+        Map<Capability, String> staticNatCapabilities = new HashMap<Capability, String>();
+        staticNatCapabilities.put(Capability.ElasticIp, "true");
+        capabilities.put(Service.StaticNat, staticNatCapabilities);
+
+        // Supports SSL offloading
+        lbCapabilities.put(Capability.SslTermination, "true");
+
+        // TODO - Murali, please put correct capabilities here
+        Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
+        firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
+        firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
+        firewallCapabilities.put(Capability.MultipleIps, "true");
+        capabilities.put(Service.Firewall, firewallCapabilities);
+
+        return capabilities;
+    }
+
+    @Override
+    public ExternalLoadBalancerDeviceVO addNetscalerLoadBalancer(AddNetscalerLoadBalancerCmd cmd) {
+        String deviceName = cmd.getDeviceType();
+
+        if (!isNetscalerDevice(deviceName)) {
+            throw new InvalidParameterValueException("Invalid Netscaler device type");
+        }
+
+        URI uri;
+        try {
+            uri = new URI(cmd.getUrl());
+        } catch (Exception e) {
+            String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to "
+                    + e.getMessage();
+            s_logger.debug(msg);
+            throw new InvalidParameterValueException(msg);
+        }
+        Map<String, String> configParams = new HashMap<String, String>();
+        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
+        boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null)
+                ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false;
+
+                if (dedicatedUse && !deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())) {
+                    String msg = "Only Netscaler VPX load balancers can be specified for dedicated use";
+                    s_logger.debug(msg);
+                    throw new InvalidParameterValueException(msg);
+                }
+
+                if (cmd.isGslbProvider()) {
+
+                    if (!deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())
+                            && !deviceName.equals(NetworkDevice.NetscalerMPXLoadBalancer.getName())) {
+                        String msg = "Only Netscaler VPX or MPX load balancers can be specified as GSLB service provider";
+                        s_logger.debug(msg);
+                        throw new InvalidParameterValueException(msg);
+                    }
+
+                    if (cmd.getSitePublicIp() == null || cmd.getSitePrivateIp() == null) {
+                        String msg = "Public and Privae IP needs to provided for NetScaler that will be GSLB provider";
+                        s_logger.debug(msg);
+                        throw new InvalidParameterValueException(msg);
+                    }
+
+                    if (dedicatedUse) {
+                        throw new InvalidParameterValueException(
+                                "NetScaler provisioned to be GSLB service provider can only be configured for shared usage.");
+                    }
+
+                }
+
+                if (cmd.isExclusiveGslbProvider() && !cmd.isGslbProvider()) {
+                    throw new InvalidParameterValueException(
+                            "NetScaler can be provisioned to be exclusive GSLB service provider"
+                                    + " only if its being configured as GSLB service provider also.");
+                }
+
+                ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(),
+                        cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource(), cmd.isGslbProvider(),
+                        cmd.isExclusiveGslbProvider(), cmd.getSitePublicIp(), cmd.getSitePrivateIp());
+
+                return lbDeviceVO;
+    }
+
+    @Override
+    public boolean deleteNetscalerLoadBalancer(DeleteNetscalerLoadBalancerCmd cmd) {
+        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
+
+        ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
+        if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
+            throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
+        }
+
+        return deleteExternalLoadBalancer(lbDeviceVo.getHostId());
+    }
+
+    @Override
+    public ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(ConfigureNetscalerLoadBalancerCmd cmd) {
+        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
+        Boolean dedicatedUse = cmd.getLoadBalancerDedicated();
+        Long capacity = cmd.getLoadBalancerCapacity();
+        List<Long> podIds = cmd.getPodIds();
+        try {
+            return configureNetscalerLoadBalancer(lbDeviceId, capacity, dedicatedUse, podIds);
+        } catch (Exception e) {
+            throw new CloudRuntimeException("failed to configure netscaler device due to " + e.getMessage());
+        }
+    }
+
+    @DB
+    private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity,
+            Boolean dedicatedUse, List<Long> newPodsConfig) {
+        final ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
+        final Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId());
+
+        if ((lbDeviceVo == null) || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
+            throw new InvalidParameterValueException("No netscaler device found with ID: " + lbDeviceId);
+        }
+
+        List<Long> currentPodsConfig = new ArrayList<Long>();
+        List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVo.getId());
+        if (currentPodVOs != null && currentPodVOs.size() > 0) {
+            for (NetScalerPodVO nsPodVo : currentPodVOs) {
+                currentPodsConfig.add(nsPodVo.getPodId());
+            }
+        }
+
+        final List<Long> podsToAssociate = new ArrayList<Long>();
+        if (newPodsConfig != null && newPodsConfig.size() > 0) {
+            for (Long podId : newPodsConfig) {
+                HostPodVO pod = _podDao.findById(podId);
+                if (pod == null) {
+                    throw new InvalidParameterValueException("Can't find pod by id " + podId);
+                }
+            }
+
+            for (Long podId : newPodsConfig) {
+                if (!currentPodsConfig.contains(podId)) {
+                    podsToAssociate.add(podId);
+                }
+            }
+        }
+
+        final List<Long> podsToDeassociate = new ArrayList<Long>();
+        for (Long podId : currentPodsConfig) {
+            if (!newPodsConfig.contains(podId)) {
+                podsToDeassociate.add(podId);
+            }
+        }
+
+        String deviceName = lbDeviceVo.getDeviceName();
+        if (dedicatedUse != null || capacity != null) {
+            if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)
+                    || NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) {
+                if (dedicatedUse != null && dedicatedUse == true) {
+                    throw new InvalidParameterValueException(
+                            "Netscaler MPX and SDX device should be shared and can not be dedicated to a single account.");
+                }
+            }
+
+            // check if any networks are using this netscaler device
+            List<NetworkExternalLoadBalancerVO> networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
+            if ((networks != null) && !networks.isEmpty()) {
+                if (capacity != null && capacity < networks.size()) {
+                    throw new CloudRuntimeException(
+                            "There are more number of networks already using this netscaler device than configured capacity");
+                }
+
+                if (dedicatedUse != null && dedicatedUse == true) {
+                    throw new CloudRuntimeException(
+                            "There are networks already using this netscaler device to make device dedicated");
+                }
+            }
+        }
+
+        if (!NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName)) {
+            if (capacity != null) {
+                lbDeviceVo.setCapacity(capacity);
+            }
+        } else {
+            // FIXME how to interpret configured capacity of the SDX device
+        }
+
+        if (dedicatedUse != null) {
+            lbDeviceVo.setIsDedicatedDevice(dedicatedUse);
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                _lbDeviceDao.update(lbDeviceId, lbDeviceVo);
+
+                for (Long podId : podsToAssociate) {
+                    NetScalerPodVO nsPodVo = new NetScalerPodVO(lbDeviceId, podId);
+                    _netscalerPodDao.persist(nsPodVo);
+                }
+
+                for (Long podId : podsToDeassociate) {
+                    NetScalerPodVO nsPodVo = _netscalerPodDao.findByPodId(podId);
+                    _netscalerPodDao.remove(nsPodVo.getId());
+                }
+
+                // FIXME get the row lock to avoid race condition
+                _detailsDao.persist(lbDeviceVo.getHostId(), lbDetails);
+
+            }
+        });
+        HostVO host = _hostDao.findById(lbDeviceVo.getHostId());
+
+        try {
+            _agentMgr.reconnect(host.getId());
+        } catch (AgentUnavailableException e) {
+            s_logger.warn("failed to reconnect host " + host, e);
+        }
+        return lbDeviceVo;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(AddNetscalerLoadBalancerCmd.class);
+        cmdList.add(ConfigureNetscalerLoadBalancerCmd.class);
+        cmdList.add(DeleteNetscalerLoadBalancerCmd.class);
+        cmdList.add(ListNetscalerLoadBalancerNetworksCmd.class);
+        cmdList.add(ListNetscalerLoadBalancersCmd.class);
+        cmdList.add(RegisterServicePackageCmd.class);
+        cmdList.add(RegisterNetscalerControlCenterCmd.class);
+        cmdList.add(ListRegisteredServicePackageCmd.class);
+        cmdList.add(ListNetscalerControlCenterCmd.class);
+        cmdList.add(DeleteServicePackageOfferingCmd.class);
+        cmdList.add(DeleteNetscalerControlCenterCmd.class);
+        cmdList.add(DeployNetscalerVpxCmd.class);
+        cmdList.add(StopNetScalerVMCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    public List<? extends Network> listNetworks(ListNetscalerLoadBalancerNetworksCmd cmd) {
+        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
+        List<NetworkVO> networks = new ArrayList<NetworkVO>();
+
+        ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
+        if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
+            throw new InvalidParameterValueException(
+                    "Could not find Netscaler load balancer device with ID " + lbDeviceId);
+        }
+
+        List<NetworkExternalLoadBalancerVO> networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
+        if (networkLbMaps != null && !networkLbMaps.isEmpty()) {
+            for (NetworkExternalLoadBalancerVO networkLbMap : networkLbMaps) {
+                NetworkVO network = _networkDao.findById(networkLbMap.getNetworkId());
+                networks.add(network);
+            }
+        }
+
+        return networks;
+    }
+
+    @Override
+    public List<ExternalLoadBalancerDeviceVO> listNetscalerLoadBalancers(ListNetscalerLoadBalancersCmd cmd) {
+        Long physcialNetworkId = cmd.getPhysicalNetworkId();
+        Long lbDeviceId = cmd.getLoadBalancerDeviceId();
+        PhysicalNetworkVO pNetwork = null;
+        List<ExternalLoadBalancerDeviceVO> lbDevices = new ArrayList<ExternalLoadBalancerDeviceVO>();
+
+        if (physcialNetworkId == null && lbDeviceId == null) {
+            throw new InvalidParameterValueException(
+                    "Either physical network Id or load balancer device Id must be specified");
+        }
+
+        if (lbDeviceId != null) {
+            ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
+            if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
+                throw new InvalidParameterValueException(
+                        "Could not find Netscaler load balancer device with ID: " + lbDeviceId);
+            }
+            lbDevices.add(lbDeviceVo);
+            return lbDevices;
+        }
+
+        if (physcialNetworkId != null) {
+            pNetwork = _physicalNetworkDao.findById(physcialNetworkId);
+            if (pNetwork == null) {
+                throw new InvalidParameterValueException(
+                        "Could not find phyical network with ID: " + physcialNetworkId);
+            }
+            lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName());
+            return lbDevices;
+        }
+
+        return null;
+    }
+
+    @Override
+    public List<NetScalerServicePackageVO> listRegisteredServicePackages(ListRegisteredServicePackageCmd cmd) {
+
+        List<NetScalerServicePackageVO> lrsPackages = new ArrayList<NetScalerServicePackageVO>();
+        lrsPackages = _netscalerServicePackageDao.listAll();
+        return lrsPackages;
+    }
+
+    @Override
+    public List<NetScalerControlCenterVO> listNetscalerControlCenter(ListNetscalerControlCenterCmd cmd) {
+        return _netscalerControlCenterDao.listAll();
+    }
+
+    @Override
+    public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException {
+        NetScalerServicePackageVO result = null;
+        boolean flag=false;
+        try {
+            result = _netscalerServicePackageDao.findByUuid(cmd.getId());
+            if (result == null) {
+                throw new CloudRuntimeException("Record does not Exists in the Table");
+            }
+
+            if(_networkOfferingDao.isUsingServicePackage(result.getUuid()))
+            {
+                throw new CloudRuntimeException("Network offering is using the service package. First delete the NeworkOffering and then delete ServicePackage");
+            }
+
+            flag = _netscalerServicePackageDao.remove(result.getId());
+
+        } catch (Exception e) {
+            if (e instanceof InvalidParameterValueException) {
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+            } else {
+                throw e;
+            }
+
+        }
+        return flag;
+
+    }
+
+    @DB
+    @Override
+    public boolean deleteNetscalerControlCenter(DeleteNetscalerControlCenterCmd cmd) throws CloudRuntimeException {
+
+        NetScalerControlCenterVO result = _netscalerControlCenterDao.findByUuid(cmd.getId());
+        if (result == null) {
+            throw new CloudRuntimeException("External Netscaler Control Center Table does not contain record with this ID");
+        } else {
+            //ID list of Network Offering which are not removed and have service Package Uuid field not null.
+            List<Long> servicePackageId_list = _networkOfferingDao.listNetworkOfferingID();
+
+            if (servicePackageId_list.size() != 0) {
+                //VO list of Networks  which are using Network Offering.
+                List<NetworkVO> networkVO_list = _networkDao.listNetworkVO(servicePackageId_list);
+                if (networkVO_list != null && networkVO_list.size() != 0) {
+                    throw new CloudRuntimeException(
+                            "ServicePackages published by NetScalerControlCenter are being used by NetworkOfferings. Try deleting NetworkOffering with ServicePackages and then delete NetScalerControlCenter.");
+                }
+            }
+        }
+        try {
+            _netscalerServicePackageDao.removeAll();
+        } catch (CloudRuntimeException ce) {
+            throw new CloudRuntimeException("Service Package is being used by Network Offering, Try deleting Network Offering and then delete Service Package.");
+        }
+
+        // delete Netscaler Control Center
+        _netscalerControlCenterDao.remove(result.getId());
+
+        //Removal of  NCC from Host Table
+        List<HostVO> ncc_list = _hostDao.listAll();
+        if (ncc_list == null) {
+            throw new CloudRuntimeException("Could not find Netscaler Control Center in Database");
+        }
+        for (HostVO ncc : ncc_list) {
+            if (ncc.getType().equals(Host.Type.NetScalerControlCenter)) {
+                try {
+                    // put the host in maintenance state in order for it to be deleted
+                    ncc.setResourceState(ResourceState.Maintenance);
+                    _hostDao.update(ncc.getId(), ncc);
+                    _resourceMgr.deleteHost(ncc.getId(), false, false);
+                } catch (Exception e) {
+                    s_logger.debug(e);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO) {
+        NetscalerLoadBalancerResponse response = new NetscalerLoadBalancerResponse();
+        Host lbHost = _hostDao.findById(lbDeviceVO.getHostId());
+        Map<String, String> lbDetails = _detailsDao.findDetails(lbDeviceVO.getHostId());
+        response.setId(lbDeviceVO.getUuid());
+        response.setIpAddress(lbHost.getPrivateIpAddress());
+        PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(lbDeviceVO.getPhysicalNetworkId());
+        if (pnw != null) {
+            response.setPhysicalNetworkId(pnw.getUuid());
+        }
+        response.setPublicInterface(lbDetails.get("publicInterface"));
+        response.setPrivateInterface(lbDetails.get("privateInterface"));
+        response.setDeviceName(lbDeviceVO.getDeviceName());
+        if (lbDeviceVO.getCapacity() == 0) {
+            long defaultLbCapacity = NumbersUtil
+                    .parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
+            response.setDeviceCapacity(defaultLbCapacity);
+        } else {
+            response.setDeviceCapacity(lbDeviceVO.getCapacity());
+        }
+        response.setDedicatedLoadBalancer(lbDeviceVO.getIsDedicatedDevice());
+        response.setProvider(lbDeviceVO.getProviderName());
+        response.setDeviceState(lbDeviceVO.getState().name());
+        response.setObjectName("netscalerloadbalancer");
+
+        response.setGslbProvider(lbDeviceVO.getGslbProvider());
+        response.setExclusiveGslbProvider(lbDeviceVO.getExclusiveGslbProvider());
+        response.setGslbSitePublicIp(lbDeviceVO.getGslbSitePublicIP());
+        response.setGslbSitePrivateIp(lbDeviceVO.getGslbSitePrivateIP());
+
+        List<Long> associatedPods = new ArrayList<Long>();
+        List<NetScalerPodVO> currentPodVOs = _netscalerPodDao.listByNetScalerDeviceId(lbDeviceVO.getId());
+        if (currentPodVOs != null && currentPodVOs.size() > 0) {
+            for (NetScalerPodVO nsPodVo : currentPodVOs) {
+                associatedPods.add(nsPodVo.getPodId());
+            }
+        }
+        response.setAssociatedPods(associatedPods);
+        return response;
+    }
+
+    @Override
+    public NetscalerControlCenterResponse createNetscalerControlCenterResponse(NetScalerControlCenterVO lncCentersVO) {
+        NetscalerControlCenterResponse response = new NetscalerControlCenterResponse(lncCentersVO);
+        response.setObjectName("netscalercontrolcenter");
+        return response;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse createRegisteredServicePackageResponse(
+            NetScalerServicePackageVO lrsPackageVO) {
+        NetScalerServicePackageResponse response = new NetScalerServicePackageResponse();
+        response.setId(lrsPackageVO.getUuid());
+        response.setName(lrsPackageVO.getName());
+        response.setDescription(lrsPackageVO.getDescription());
+        response.setObjectName("registeredServicepackage");
+        return response;
+    }
+
+    @Override
+    public Provider getProvider() {
+        return Provider.Netscaler;
+    }
+
+    @Override
+    public boolean isReady(PhysicalNetworkServiceProvider provider) {
+        List<ExternalLoadBalancerDeviceVO> lbDevices = _lbDeviceDao
+                .listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), Provider.Netscaler.getName());
+
+        // true if at-least one Netscaler device is added in to physical network
+        // and is in configured (in enabled state)
+        // state
+        if (lbDevices != null && !lbDevices.isEmpty()) {
+            for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) {
+                if (lbDevice.getState() == LBDeviceState.Enabled) {
+                    return true;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO reset the configuration on all of the netscaler devices in this
+        // physical network
+        return true;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        return true;
+    }
+
+    private boolean isNetscalerDevice(String deviceName) {
+        if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName()))
+                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName()))
+                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public boolean verifyServicesCombination(Set<Service> services) {
+        Set<Service> netscalerServices = new HashSet<Service>();
+        netscalerServices.add(Service.Lb);
+        netscalerServices.add(Service.StaticNat);
+
+        // NetScaler can only act as Lb and Static Nat service provider
+        if (services != null && !services.isEmpty() && !netscalerServices.containsAll(services)) {
+            s_logger.warn(
+                    "NetScaler network element can only support LB and Static NAT services and service combination "
+                            + services + " is not supported.");
+
+            StringBuffer buff = new StringBuffer();
+            for (Service service : services) {
+                buff.append(service.getName());
+                buff.append(" ");
+            }
+            s_logger.warn(
+                    "NetScaler network element can only support LB and Static NAT services and service combination "
+                            + buff.toString() + " is not supported.");
+            s_logger.warn(
+                    "NetScaler network element can only support LB and Static NAT services and service combination "
+                            + services + " is not supported.");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service)
+            throws ResourceUnavailableException {
+        // return true, as IP will be associated as part of LB rule
+        // configuration
+        return true;
+    }
+
+    @Override
+    public IpDeployer getIpDeployer(Network network) {
+
+        if (_networkMgr.isNetworkInlineMode(network)) {
+            return getIpDeployerForInlineMode(network);
+        }
+
+        return this;
+    }
+
+    public boolean applyElasticLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules)
+            throws ResourceUnavailableException {
+
+        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
+            return true;
+        }
+
+        String errMsg = null;
+        ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+        if (lbDeviceVO == null) {
+            try {
+                lbDeviceVO = allocateLoadBalancerForNetwork(network);
+            } catch (Exception e) {
+                errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to "
+                        + e.getMessage();
+                s_logger.error(errMsg);
+                throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+            }
+        }
+
+        if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) {
+            errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules.";
+            s_logger.error(errMsg);
+            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+        }
+
+        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
+        for (int i = 0; i < loadBalancingRules.size(); i++) {
+            LoadBalancingRule rule = loadBalancingRules.get(i);
+            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
+            String protocol = rule.getProtocol();
+            String algorithm = rule.getAlgorithm();
+            String lbUuid = rule.getUuid();
+            String srcIp = rule.getSourceIp().addr();
+            int srcPort = rule.getSourcePortStart();
+            List<LbDestination> destinations = rule.getDestinations();
+
+            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
+                LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
+                        false, false, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies(),
+                        rule.getLbSslCert(), rule.getLbProtocol());
+                if (rule.isAutoScaleConfig()) {
+                    loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
+                }
+                loadBalancersToApply.add(loadBalancer);
+            }
+        }
+
+        if (loadBalancersToApply.size() > 0) {
+            int numLoadBalancersForCommand = loadBalancersToApply.size();
+            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
+                    .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
+            LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null);
+
+            HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+            if (answer == null || !answer.getResult()) {
+                String details = (answer != null) ? answer.getDetails() : "details unavailable";
+                String msg = "Unable to apply elastic load balancer rules to the external load balancer appliance in zone "
+                        + network.getDataCenterId() + " due to: " + details + ".";
+                s_logger.error(msg);
+                throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNats(Network config, List<? extends StaticNat> rules)
+            throws ResourceUnavailableException {
+
+        if (!canHandle(config, Service.StaticNat)) {
+            return false;
+        }
+
+        boolean multiNetScalerDeployment = Boolean
+                .valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key()));
+
+        try {
+            if (!multiNetScalerDeployment) {
+                String errMsg;
+                ExternalLoadBalancerDeviceVO lbDevice = getExternalLoadBalancerForNetwork(config);
+                if (lbDevice == null) {
+                    try {
+                        lbDevice = allocateLoadBalancerForNetwork(config);
+                    } catch (Exception e) {
+                        errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to"
+                                + e.getMessage();
+                        s_logger.error(errMsg);
+                        throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+                    }
+                }
+
+                if (!isNetscalerDevice(lbDevice.getDeviceName())) {
+                    errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element will not be handling the static nat rules.";
+                    s_logger.error(errMsg);
+                    throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+                }
+                SetStaticNatRulesAnswer answer = null;
+                List<StaticNatRuleTO> rulesTO = null;
+                if (rules != null) {
+                    rulesTO = new ArrayList<StaticNatRuleTO>();
+                    for (StaticNat rule : rules) {
+                        IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
+                        StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null,
+                                rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
+                        rulesTO.add(ruleTO);
+                    }
+                }
+
+                SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null);
+                answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(), cmd);
+                if (answer == null) {
+                    return false;
+                } else {
+                    return answer.getResult();
+                }
+            } else {
+                if (rules != null) {
+                    for (StaticNat rule : rules) {
+                        // validate if EIP rule can be configured.
+                        ExternalLoadBalancerDeviceVO lbDevice = getNetScalerForEIP(rule);
+                        if (lbDevice == null) {
+                            String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: "
+                                    + rule.getDestIpAddress();
+                            s_logger.error(errMsg);
+                            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+                        }
+
+                        List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
+                        IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId());
+                        StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null,
+                                rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
+                        rulesTO.add(ruleTO);
+                        SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null);
+
+                        // send commands to configure INAT rule on the NetScaler
+                        // device
+                        SetStaticNatRulesAnswer answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(),
+                                cmd);
+                        if (answer == null) {
+                            String errMsg = "Failed to configure INAT rule on NetScaler device " + lbDevice.getHostId();
+                            s_logger.error(errMsg);
+                            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+                        }
+                    }
+                    return true;
+                }
+            }
+            return true;
+        } catch (Exception e) {
+            s_logger.error("Failed to configure StaticNat rule due to " + e.getMessage());
+            return false;
+        }
+    }
+
+    // returns configured NetScaler device that is associated with the pod that
+    // owns guest IP
+    private ExternalLoadBalancerDeviceVO getNetScalerForEIP(StaticNat rule) {
+        String guestIP = rule.getDestIpAddress();
+        List<DataCenterIpAddressVO> dcGuestIps = _privateIpAddressDao.listAll();
+        if (dcGuestIps != null) {
+            for (DataCenterIpAddressVO dcGuestIp : dcGuestIps) {
+                if (dcGuestIp.getIpAddress().equalsIgnoreCase(guestIP)) {
+                    long podId = dcGuestIp.getPodId();
+                    NetScalerPodVO nsPodVO = _netscalerPodDao.findByPodId(podId);
+                    if (nsPodVO != null) {
+                        ExternalLoadBalancerDeviceVO lbDeviceVO = _lbDeviceDao.findById(nsPodVO.getNetscalerDeviceId());
+                        return lbDeviceVO;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public List<LoadBalancerTO> getElasticLBRulesHealthCheck(Network network,
+            List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
+
+        HealthCheckLBConfigAnswer answer = null;
+
+        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
+            return null;
+        }
+
+        String errMsg = null;
+        ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+
+        if (lbDeviceVO == null) {
+            s_logger.warn(
+                    "There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
+            return null;
+        }
+
+        if (!isNetscalerDevice(lbDeviceVO.getDeviceName())) {
+            errMsg = "There are no NetScaler load balancer assigned for this network. So NetScaler element can not be handle elastic load balancer rules.";
+            s_logger.error(errMsg);
+            throw new ResourceUnavailableException(errMsg, this.getClass(), 0);
+        }
+
+        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
+        for (int i = 0; i < loadBalancingRules.size(); i++) {
+            LoadBalancingRule rule = loadBalancingRules.get(i);
+            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
+            String protocol = rule.getProtocol();
+            String algorithm = rule.getAlgorithm();
+            String lbUuid = rule.getUuid();
+            String srcIp = rule.getSourceIp().addr();
+            int srcPort = rule.getSourcePortStart();
+            List<LbDestination> destinations = rule.getDestinations();
+
+            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
+                LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked,
+                        false, false, destinations, null, rule.getHealthCheckPolicies(), rule.getLbSslCert(),
+                        rule.getLbProtocol());
+                loadBalancersToApply.add(loadBalancer);
+            }
+        }
+
+        if (loadBalancersToApply.size() > 0) {
+            int numLoadBalancersForCommand = loadBalancersToApply.size();
+            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
+                    .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
+            HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
+            HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            answer = (HealthCheckLBConfigAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+            return answer.getLoadBalancers();
+        }
+        return null;
+    }
+
+    @Override
+    public List<LoadBalancerTO> updateHealthChecks(Network network, List<LoadBalancingRule> lbrules) {
+
+        if (canHandle(network, Service.Lb) && canHandleLbRules(lbrules)) {
+            try {
+
+                if (isBasicZoneNetwok(network)) {
+                    return getElasticLBRulesHealthCheck(network, lbrules);
+                } else {
+                    return getLBHealthChecks(network, lbrules);
+                }
+            } catch (ResourceUnavailableException e) {
+                s_logger.error("Error in getting the LB Rules from NetScaler " + e);
+            }
+        } else {
+            s_logger.error("Network cannot handle to LB service ");
+        }
+        return null;
+    }
+
+    @Override
+    public boolean handlesOnlyRulesInTransitionState() {
+        return true;
+    }
+
+    @Override
+    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> rules)
+            throws ResourceUnavailableException {
+        return super.getLBHealthChecks(network, rules);
+    }
+
+    @Override
+    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
+        return null;
+    }
+
+    @Override
+    public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId,
+            GlobalLoadBalancerConfigCommand gslbConfigCmd) throws ResourceUnavailableException {
+
+        long zoneGslbProviderHosId = 0;
+
+        // find the NetScaler device configured as gslb service provider in the
+        // zone
+        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
+        if (nsGslbProvider == null) {
+            String msg = "Unable to find a NetScaler configured as gslb service provider in zone " + zoneId;
+            s_logger.debug(msg);
+            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
+        }
+
+        // get the host Id corresponding to NetScaler acting as GSLB service
+        // provider in the zone
+        zoneGslbProviderHosId = nsGslbProvider.getHostId();
+
+        // send gslb configuration to NetScaler device
+        Answer answer = _agentMgr.easySend(zoneGslbProviderHosId, gslbConfigCmd);
+        if (answer == null || !answer.getResult()) {
+            String msg = "Unable to apply global load balancer rule to the gslb service provider in zone " + zoneId;
+            s_logger.debug(msg);
+            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
+        }
+
+        return true;
+    }
+
+    private ExternalLoadBalancerDeviceVO findGslbProvider(long zoneId, long physicalNetworkId) {
+        List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest);
+
+        if (pNtwks == null || pNtwks.isEmpty()) {
+            throw new InvalidParameterValueException(
+                    "Unable to get physical network: " + physicalNetworkId + " in zone id = " + zoneId);
+        } else {
+            for (PhysicalNetwork physicalNetwork : pNtwks) {
+                if (physicalNetwork.getId() == physicalNetworkId) {
+                    PhysicalNetworkVO physNetwork = pNtwks.get(0);
+                    ExternalLoadBalancerDeviceVO nsGslbProvider = _externalLoadBalancerDeviceDao
+                            .findGslbServiceProvider(physNetwork.getId(), Provider.Netscaler.getName());
+                    return nsGslbProvider;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public boolean isServiceEnabledInZone(long zoneId, long physicalNetworkId) {
+
+        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
+        // return true if a NetScaler device is configured in the zone
+        return (nsGslbProvider != null);
+    }
+
+    @Override
+    public String getZoneGslbProviderPublicIp(long zoneId, long physicalNetworkId) {
+        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
+        if (nsGslbProvider != null) {
+            return nsGslbProvider.getGslbSitePublicIP();
+        }
+        return null;
+    }
+
+    @Override
+    public String getZoneGslbProviderPrivateIp(long zoneId, long physicalNetworkId) {
+        ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
+        if (nsGslbProvider != null) {
+            return nsGslbProvider.getGslbSitePrivateIP();
+        }
+        return null;
+    }
+
+    private boolean canHandleLbRules(List<LoadBalancingRule> rules) {
+        Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
+        if (!lbCaps.isEmpty()) {
+            String schemeCaps = lbCaps.get(Capability.LbSchemes);
+            if (schemeCaps != null) {
+                for (LoadBalancingRule rule : rules) {
+                    if (!schemeCaps.contains(rule.getScheme().toString())) {
+                        s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider "
+                                + getName());
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD, eventDescription = "Registering NetScaler Service Package")
+    public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        NetScalerServicePackageVO servicePackage = new NetScalerServicePackageVO(cmd);
+        NetScalerServicePackageResponse response = null;
+        _netscalerServicePackageDao.persist(servicePackage);
+        response = new NetScalerServicePackageResponse(servicePackage);
+        return response;
+    }
+
+    @Override
+    @DB
+    public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd cmd) {
+
+        if (_netscalerControlCenterDao.listAll() != null && _netscalerControlCenterDao.listAll().size() != 0) {
+            throw new CloudRuntimeException("One Netscaler Control Center already exist in the DataBase. At a time only one Netscaler Control Center is allowed");
+        }
+
+        final RegisterNetscalerControlCenterCmd cmdinfo = cmd;
+        String ipAddress = cmd.getIpaddress();
+        Map hostDetails = new HashMap<String, String>();
+        String hostName = "NetscalerControlCenter";
+        hostDetails.put("name", hostName);
+        hostDetails.put("guid", UUID.randomUUID().toString());
+        List<DataCenterVO> dcVO = _dcDao.listEnabledZones();
+        if (dcVO.size() == 0) {
+            throw new CloudRuntimeException("There is no single enabled zone. Please add a zone, enable it and then add Netscaler ControlCenter");
+        }
+        hostDetails.put("zoneId", "1");
+        hostDetails.put("ip", ipAddress);
+        hostDetails.put("username", cmd.getUsername());
+        hostDetails.put("password", cmd.getPassword());
+        hostDetails.put("deviceName", "Netscaler ControlCenter");
+        ServerResource resource = new NetScalerControlCenterResource();
+        try {
+            resource.configure(hostName, hostDetails);
+            return Transaction.execute(new TransactionCallback<NetScalerControlCenterVO>() {
+                @Override
+                public NetScalerControlCenterVO doInTransaction(TransactionStatus status) {
+                    NetScalerControlCenterVO nccVO = new NetScalerControlCenterVO(cmdinfo.getUsername(), DBEncryptionUtil.encrypt(cmdinfo.getPassword()),
+                            cmdinfo.getIpaddress(), cmdinfo.getNumretries());
+                    _netscalerControlCenterDao.persist(nccVO);
+                    return nccVO;
+                }
+            });
+        } catch (ConfigurationException e) {
+            resource = null;
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @Override
+    public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) {
+        DataCenter zone = _dcDao.findById(cmd.getZoneId());
+        DeployDestination dest = new DeployDestination(zone, null, null, null);
+        Map<String,Object> resp = new HashMap<String, Object>();
+        Long templateId = cmd.getTemplateId();
+        Long serviceOfferingId = cmd.getServiceOfferingId();
+        DeploymentPlan plan = new DataCenterDeployment(dest.getDataCenter().getId());
+        try {
+            resp =  _netScalerVMManager.deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
+        } catch (InsufficientCapacityException e) {
+            e.printStackTrace();
+        }
+        return resp;
+    }
+
+    @Override
+    public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        return _netScalerVMManager.stopNetScalerVm(id, forced, callingAccount, callingUserId);
+    }
+}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerLoadBalancerElementService.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerLoadBalancerElementService.java
diff --git a/plugins/network-elements/netscaler/src/main/java/com/cloud/network/resource/NetScalerControlCenterResource.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/resource/NetScalerControlCenterResource.java
new file mode 100644
index 0000000..e23cb0b
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/resource/NetScalerControlCenterResource.java
@@ -0,0 +1,924 @@
+// 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.network.resource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.BasicClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.google.gson.Gson;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.NetScalerImplementNetworkCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
+import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
+import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
+import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
+import com.cloud.resource.ServerResource;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+
+class NccHttpCode {
+    static final String INTERNAL_ERROR  = "INTERNAL ERROR";
+    static final String NOT_FOUND = "NOT FOUND";
+    static final String JOB_ID = "Job_id";
+    static final String UNAUTHORIZED  = "UNAUTHORIZED";
+}
+
+public class NetScalerControlCenterResource implements ServerResource {
+
+    // deployment configuration
+    private String _name;
+    private String _zoneId;
+    private String _ip;
+    private String _username;
+    private String _password;
+    private String _publicInterface;
+    private String _privateInterface;
+    private Integer _numRetries;
+    private Long _nccCmdTimeout;
+    private String _guid;
+    private boolean _inline;
+    private String _deviceName;
+    private String _sessionid;
+    public static final int DEFAULT_PORT = 443;
+    private static final Gson s_gson = GsonHelper.getGson();
+    private static final Logger s_logger = Logger.getLogger(NetScalerControlCenterResource.class);
+    protected Gson _gson;
+    private final String _objectNamePathSep = "-";
+    final String protocol="https";
+    private static String nccsession;
+    private int pingCount = 0;
+
+    public NetScalerControlCenterResource() {
+        _gson = GsonHelper.getGsonLogger();
+    }
+
+
+    public static String get_nccsession() {
+        return nccsession;
+    }
+
+
+    public static void set_nccsession(String nccsession) {
+        NetScalerControlCenterResource.nccsession = nccsession;
+    }
+
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        JSONObject jsonResponse = null;
+        try {
+            _name = (String)params.get("name");
+            if (_name == null) {
+                throw new ConfigurationException("Unable to find name in the configuration parameters");
+            }
+
+            _zoneId = (String)params.get("zoneId");
+            if (_zoneId == null) {
+                throw new ConfigurationException("Unable to find zone Id  in the configuration parameters");
+            }
+
+            _ip = (String)params.get("ip");
+            if (_ip == null) {
+                throw new ConfigurationException("Unable to find IP address in the configuration parameters");
+            }
+
+            _username = (String)params.get("username");
+            if (_username == null) {
+                throw new ConfigurationException("Unable to find username in the configuration parameters");
+            }
+
+            _password =  (String)params.get("password");
+            if (_password == null) {
+                throw new ConfigurationException("Unable to find password in the configuration parameters");
+            }
+
+            _numRetries = NumbersUtil.parseInt((String)params.get("numretries"), 2);
+
+            _guid = (String)params.get("guid");
+            if (_guid == null) {
+                throw new ConfigurationException("Unable to find the guid in the configuration parameters");
+            }
+
+            _deviceName = (String)params.get("deviceName");
+            if (_deviceName == null) {
+                throw new ConfigurationException("Unable to find the device name in the configuration parameters");
+            }
+            _nccCmdTimeout = NumbersUtil.parseLong((String)params.get("numretries"), 600000);
+
+            // validate device configuration parameters
+            login();
+
+            return true;
+        } catch (ConfigurationException e) {
+            throw new ConfigurationException(e.getMessage());
+        } catch (ExecutionException e) {
+            s_logger.debug("Execution Exception :" +  e.getMessage());
+            throw new ConfigurationException("Failed to add the device. Please check the device is NCC and It is reachable from Management Server.");
+        }
+    }
+
+    public void getServicePackages() throws ExecutionException {
+            String result = null;
+            try {
+                URI agentUri = null;
+                agentUri =
+                        new URI("https", null, _ip, DEFAULT_PORT,
+                                "/admin/v1/servicepackages", null, null);
+
+                org.json.JSONObject jsonBody = new JSONObject();
+                org.json.JSONObject jsonCredentials = new JSONObject();
+                result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+                s_logger.debug("List of Service Packages in NCC:: " + result);
+                } catch (URISyntaxException e) {
+                    String errMsg = "Could not generate URI for Hyper-V agent";
+                    s_logger.error(errMsg, e);
+
+                } catch (Exception e) {
+                throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
+            }
+    }
+
+    private synchronized String login() throws ExecutionException{
+        String result = null;
+        JSONObject jsonResponse = null;
+        try {
+            URI agentUri = null;
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/nitro/v2/config/" + "login", null, null);
+            org.json.JSONObject jsonBody = new JSONObject();
+            org.json.JSONObject jsonCredentials = new JSONObject();
+            jsonCredentials.put("username", _username);
+            jsonCredentials.put("password", _password);
+            jsonBody.put("login", jsonCredentials);
+
+            result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+            if (result == null) {
+                throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
+            } else {
+                jsonResponse = new JSONObject(result);
+                org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
+                _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
+                s_logger.debug("New Session id from NCC :" + _sessionid);
+                set_nccsession(_sessionid);
+                s_logger.debug("session on Static Session variable" + get_nccsession());
+            }
+            s_logger.debug("Login to NCC Device response :: " + result);
+            return result;
+            } catch (URISyntaxException e) {
+                String errMsg = "Could not generate URI for Hyper-V agent";
+                s_logger.error(errMsg, e);
+
+            } catch (JSONException e) {
+                s_logger.debug("JSON Exception :" +  e.getMessage());
+                throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
+            } catch (Exception e) {
+            throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
+        }
+        return result;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand(Host.Type.NetScalerControlCenter);
+        cmd.setName(_name);
+        cmd.setDataCenter(_zoneId);
+        cmd.setPod("");
+        cmd.setPrivateIpAddress(_ip);
+        cmd.setStorageIpAddress("");
+        cmd.setVersion(NetScalerControlCenterResource.class.getPackage().getImplementationVersion());
+        cmd.setGuid(_guid);
+        return new StartupCommand[] {cmd};
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        return executeRequest(cmd, _numRetries);
+    }
+
+    private Answer executeRequest(Command cmd, int numRetries) {
+        if (cmd instanceof ReadyCommand) {
+            return execute((ReadyCommand)cmd);
+        } else if (cmd instanceof MaintainCommand) {
+            return execute((MaintainCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return execute((IpAssocCommand)cmd, numRetries);
+        } else if (cmd instanceof LoadBalancerConfigCommand) {
+            return execute((LoadBalancerConfigCommand)cmd, numRetries);
+        } else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
+            return execute((ExternalNetworkResourceUsageCommand)cmd, numRetries);
+        } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        } else if (cmd instanceof SetStaticNatRulesCommand) {
+            return execute((SetStaticNatRulesCommand)cmd, numRetries);
+        } else if (cmd instanceof GlobalLoadBalancerConfigCommand) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        } else if (cmd instanceof HealthCheckLBConfigCommand) {
+            return execute((HealthCheckLBConfigCommand)cmd, numRetries);
+        } else if (cmd instanceof NetScalerImplementNetworkCommand ) {
+            return execute((NetScalerImplementNetworkCommand)cmd, numRetries);
+        }
+        else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(ReadyCommand cmd) {
+        return new ReadyAnswer(cmd);
+    }
+
+    protected Answer execute(MaintainCommand cmd) {
+        return new MaintainAnswer(cmd);
+    }
+
+    private void keepSessionAlive() throws ExecutionException {
+        URI agentUri = null;
+        try {
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/cs/cca/v1/cloudstacks", null, null);
+            org.json.JSONObject jsonBody = new JSONObject();
+            getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+            s_logger.debug("Keeping Session Alive");
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private String queryAsyncJob(String jobId) throws ExecutionException {
+        String result = null;
+        try {
+            URI agentUri = null;
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/admin/v1/journalcontexts/" + jobId, null, null);
+
+            org.json.JSONObject jsonBody = new JSONObject();
+
+            long startTick = System.currentTimeMillis();
+            while (System.currentTimeMillis() - startTick <  _nccCmdTimeout) {
+                result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+                JSONObject response = new JSONObject(result);
+                if(response != null ) {
+                    s_logger.debug("Job Status result for ["+jobId + "]:: " + result + " Tick and currentTime :" +  System.currentTimeMillis() +" -" + startTick + "job cmd timeout :" +_nccCmdTimeout);
+                    String status = response.getJSONObject("journalcontext").getString("status").toUpperCase();
+                    String message = response.getJSONObject("journalcontext").getString("message");
+                    s_logger.debug("Job Status Progress Status ["+ jobId + "]:: " + status);
+                    switch(status) {
+                    case "FINISHED":
+                            return status;
+                    case "IN PROGRESS":
+                        break;
+                    case "ERROR, ROLLBACK IN PROGRESS":
+                        break;
+                    case "ERROR, ROLLBACK COMPLETED":
+                        throw new ExecutionException("ERROR, ROLLBACK COMPLETED " + message);
+                    case "ERROR, ROLLBACK FAILED":
+                        throw new ExecutionException("ERROR, ROLLBACK FAILED " + message);
+                    }
+                }
+            }
+
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for NetScaler ControlCenter";
+            s_logger.error(errMsg, e);
+          } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+    private synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) {
+        String result = null;
+        try {
+            URI agentUri = null;
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/cs/adcaas/v1/networks", null, null);
+            org.json.JSONObject jsonBody = new JSONObject(cmd.getDetails());
+            s_logger.debug("Sending Network Implement to NCC:: " + jsonBody);
+            result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+            s_logger.debug("Result of Network Implement to NCC:: " + result);
+            result = queryAsyncJob(result);
+            s_logger.debug("Done query async of network implement request :: " + result);
+            return new Answer(cmd, true, "Successfully allocated device");
+            } catch (URISyntaxException e) {
+                String errMsg = "Could not generate URI for NetScaler ControlCenter ";
+                s_logger.error(errMsg, e);
+            } catch (ExecutionException e) {
+                if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) {
+                    return new Answer(cmd, true, "Successfully unallocated the device");
+                }else if(e.getMessage().startsWith("ERROR, ROLLBACK") ) {
+                    s_logger.error(e.getMessage());
+                    return new Answer(cmd, false, e.getMessage());
+                }
+                else {
+                    if (shouldRetry(numRetries)) {
+                        s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries, e);
+                        return retry(cmd, numRetries);
+                    } else {
+                        return new Answer(cmd, false, e.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                if (shouldRetry(numRetries)) {
+                    s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries, e);
+                    return retry(cmd, numRetries);
+                } else {
+                    return new Answer(cmd, false, e.getMessage());
+                }
+            }
+
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    private synchronized Answer execute(IpAssocCommand cmd,  int numRetries) {
+
+        String[] results = new String[cmd.getIpAddresses().length];
+        int i = 0;
+        IpAddressTO[] ips = cmd.getIpAddresses();
+        for (IpAddressTO ip : ips) {
+            results[i++] = ip.getPublicIp() + " - success";
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+    private Answer execute(HealthCheckLBConfigCommand cmd, int numRetries) {
+
+        List<LoadBalancerTO> hcLB = new ArrayList<LoadBalancerTO>();
+        try {
+
+            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
+
+            if (loadBalancers == null) {
+                return new HealthCheckLBConfigAnswer(hcLB);
+            }
+            String result = getLBHealthChecks(cmd.getNetworkId());
+            JSONObject res =  new JSONObject(result);
+            JSONArray lbstatus = res.getJSONArray("lbhealthstatus");
+            for(int i=0; i<lbstatus.length(); i++) {
+                JSONObject lbstat = lbstatus.getJSONObject(i);
+                LoadBalancerTO loadBalancer = null;
+                JSONArray dest = lbstat.getJSONArray("destinations");
+                List<DestinationTO> listDestTo = new ArrayList<DestinationTO>();
+                for(int d=0; d<dest.length(); d++ ) {
+                    JSONObject dt = dest.getJSONObject(d);
+                    if( dt!=null ) {
+                        DestinationTO destTO = new DestinationTO(dt.getString("destIp"), dt.getInt("destPort"), dt.getString("monitorState"));
+                        listDestTo.add(destTO);
+                    }
+                }
+                loadBalancer = new LoadBalancerTO(lbstat.getString("lb_uuid"),listDestTo);
+                hcLB.add(loadBalancer);
+            }
+        } catch (ExecutionException e) {
+            s_logger.error("Failed to execute HealthCheckLBConfigCommand due to ", e);
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new HealthCheckLBConfigAnswer(hcLB);
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to execute HealthCheckLBConfigCommand due to ", e);
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new HealthCheckLBConfigAnswer(hcLB);
+            }
+        }
+        return new HealthCheckLBConfigAnswer(hcLB);
+    }
+
+    private String getLBHealthChecks(long networkid) throws ExecutionException  {
+        URI agentUri = null;
+        String response = null;
+        try {
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/cs/adcaas/v1/networks/"+ networkid +"/lbhealthstatus", null, null);
+            org.json.JSONObject jsonBody = new JSONObject();
+            response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+            s_logger.debug("LBHealthcheck Response :" + response);
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+    private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
+        try {
+            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
+            if (loadBalancers == null) {
+                return new Answer(cmd);
+            }
+            JSONObject lbConfigPaylod = new JSONObject(cmd);
+            String gsonLBConfig =  _gson.toJson(cmd);
+            URI agentUri = null;
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/cs/adcaas/v1/loadbalancerCmds", null, null);
+            JSONObject lbConfigCmd = new JSONObject();
+            JSONObject lbcmd = new JSONObject(gsonLBConfig);
+            s_logger.debug("LB config from gsonstring to JSONObject : " +  lbcmd.toString() + "\n" + "gson cmd is :: \t" + gsonLBConfig);
+            lbConfigCmd.put("LoadBalancerConfigCommand",  lbcmd.getJSONArray("loadBalancers"));
+            s_logger.debug("LB config paylod : " +  lbConfigCmd.toString());
+
+            String result = postHttpRequest(lbConfigCmd.toString(), agentUri, _sessionid);
+            s_logger.debug("Result of lbconfigcmg is "+ result);
+            result = queryAsyncJob(result);
+            s_logger.debug("Done query async of LB ConfigCmd implement request and result:: " + result);
+            return new Answer(cmd);
+        } catch (ExecutionException e) {
+            s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
+            if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) {
+                return new Answer(cmd, true, "LB Rule is not present in NS device. So returning as removed the LB Rule");
+            } else  if(e.getMessage().startsWith("ERROR, ROLLBACK COMPLETED") || e.getMessage().startsWith("ERROR, ROLLBACK FAILED")) {
+                s_logger.error("Failed to execute LoadBalancerConfigCommand due to : " + e.getMessage());
+                return new Answer(cmd, false, e.getMessage());
+            } else if (e.getMessage().startsWith(NccHttpCode.INTERNAL_ERROR)) {
+                s_logger.error("Failed to execute LoadBalancerConfigCommand as Internal Error returning Internal error ::" + e.getMessage() );
+                return new Answer(cmd, false, e.getMessage());
+            }
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new Answer(cmd, false, e.getMessage());
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new Answer(cmd, false, e.getMessage());
+            }
+        }
+    }
+
+    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
+        try {
+
+            return getPublicIpBytesSentAndReceived(cmd);
+
+        } catch (ExecutionException e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new ExternalNetworkResourceUsageAnswer(cmd, e);
+            }
+        }
+    }
+
+
+    private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException {
+        String port = Integer.toString(loadBalancer.getSrcPort());
+        String lbProtocol = loadBalancer.getLbProtocol();
+        StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies();
+        String nsProtocol = "TCP";
+
+        if (lbProtocol == null)
+            lbProtocol = loadBalancer.getProtocol();
+
+        if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)) {
+            StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
+            if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) ||
+                    (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) {
+                nsProtocol = "HTTP";
+                return nsProtocol;
+            }
+        }
+
+        if (lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO) || lbProtocol.equalsIgnoreCase(NetUtils.HTTP_PROTO))
+            return lbProtocol.toUpperCase();
+
+        if (port.equals(NetUtils.HTTP_PORT)) {
+            nsProtocol = "HTTP";
+        } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) {
+            nsProtocol = "TCP";
+        } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) {
+            nsProtocol = "UDP";
+        }
+
+        return nsProtocol;
+    }
+
+
+    private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
+        ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
+        long networkid = cmd.getNetworkid();
+        try {
+            //TODO send GET cmd to get the network stats
+
+            URI agentUri = null;
+            String response = null;
+            try {
+                agentUri =
+                        new URI("https", null, _ip, DEFAULT_PORT,
+                                "/cs/adcaas/v1/networks/"+ networkid +"/ipStats", null, null);
+                org.json.JSONObject jsonBody = new JSONObject();
+                response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+                JSONArray statsIPList = null;
+                if(response !=null ) {
+                    statsIPList = new JSONObject(response).getJSONObject("stats") .getJSONArray("ipBytes");
+                }
+                if(statsIPList != null) {
+                    for(int i=0; i<statsIPList.length(); i++) {
+                        JSONObject ipstat = statsIPList.getJSONObject(i);
+                        JSONObject ipvalues =  ipstat.getJSONObject("ipstats");
+                        if(ipstat != null) {
+                            long[] bytesSentAndReceived = new long[] {0, 0};
+                            bytesSentAndReceived[0] = ipvalues.getLong("received");
+                            bytesSentAndReceived[1] = ipvalues.getLong("sent");
+
+                            if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
+                                answer.ipBytes.put(ipstat.getString("ip"), bytesSentAndReceived);
+                            }
+                       }
+                    }
+                }
+                s_logger.debug("IPStats Response :" + response);
+            } catch (URISyntaxException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                s_logger.debug("Seesion Alive" + e.getMessage());
+                e.printStackTrace();
+            }
+
+        } catch (Exception e) {
+            s_logger.error("Failed to get bytes sent and recived statistics due to " + e);
+            throw new ExecutionException(e.getMessage());
+        }
+
+        return answer;
+    }
+
+    private Answer retry(Command cmd, int numRetries) {
+        int numRetriesRemaining = numRetries - 1;
+        s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining);
+        return executeRequest(cmd, numRetriesRemaining);
+    }
+
+    private boolean shouldRetry(int numRetries) {
+        try {
+            if (numRetries > 0) {
+                login();
+                return true;
+            }
+        } catch (Exception e) {
+            s_logger.error("Failed to log in to Netscaler ControlCenter device at " + _ip + " due to " + e.getMessage());
+            return false;
+        }
+        return false;
+    }
+
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
+
+    private boolean refreshNCCConnection() {
+        boolean ret = false;
+        try {
+            keepSessionAlive();
+            return true;
+        } catch (ExecutionException ex) {
+            s_logger.debug("Failed to keep up the session alive ", ex);
+        }
+        return ret;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        pingCount++;
+        if (pingCount > 10 && refreshNCCConnection()) {
+            pingCount = 0;
+        }
+        return new PingCommand(Host.Type.NetScalerControlCenter, id);
+    }
+
+    @Override
+    public Type getType() {
+        return Host.Type.NetScalerControlCenter ;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        return;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public void setName(String name) {
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public void disconnected() {
+        return;
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        return null;
+    }
+
+    @Override
+    public int getRunLevel() {
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+    }
+
+    public String getSessionID() {
+        return _sessionid;
+    }
+    public static String cleanPassword(String logString) {
+        String cleanLogString = null;
+        if (logString != null) {
+            cleanLogString = logString;
+            String[] temp = logString.split(",");
+            int i = 0;
+            if (temp != null) {
+                while (i < temp.length) {
+                    temp[i] = StringUtils.cleanString(temp[i]);
+                    i++;
+                }
+                List<String> stringList = new ArrayList<String>();
+                Collections.addAll(stringList, temp);
+                cleanLogString = StringUtils.join(stringList, ",");
+            }
+        }
+        return cleanLogString;
+    }
+    public static HttpClient getHttpClient() {
+
+        HttpClient httpClient = null;
+        TrustStrategy easyStrategy = new TrustStrategy() {
+            @Override
+            public boolean isTrusted(X509Certificate[] chain, String authType)
+                    throws CertificateException {
+                return true;
+            }
+        };
+
+        try {
+            SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
+            SchemeRegistry registry = new SchemeRegistry();
+            registry.register(new Scheme("https", DEFAULT_PORT, sf));
+            ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
+            httpClient = new DefaultHttpClient(ccm);
+        } catch (KeyManagementException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (UnrecoverableKeyException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (NoSuchAlgorithmException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (KeyStoreException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        }
+        return httpClient;
+    }
+
+    public static String getHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException {
+        // Using Apache's HttpClient for HTTP POST
+        // Java-only approach discussed at on StackOverflow concludes with
+        // comment to use Apache HttpClient
+        // http://stackoverflow.com/a/2793153/939250, but final comment is to
+        // use Apache.
+        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
+        logMessage = cleanPassword(logMessage);
+        s_logger.debug("GET request to " + agentUri.toString()
+                + " with contents " + logMessage);
+
+        // Create request
+        HttpClient httpClient = getHttpClient();
+        String result = null;
+
+        // TODO: are there timeout settings and worker thread settings to tweak?
+        try {
+            HttpGet request = new HttpGet(agentUri);
+
+            // JSON encode command
+            // Assumes command sits comfortably in a string, i.e. not used for
+            // large data transfers
+            StringEntity cmdJson = new StringEntity(jsonCmd);
+            request.addHeader("content-type", "application/json");
+            request.addHeader("Cookie", "SessId=" + sessionID);
+            s_logger.debug("Sending cmd to " + agentUri.toString()
+                    + " cmd data:" + logMessage);
+            HttpResponse response = httpClient.execute(request);
+
+            // Unsupported commands will not route.
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+                String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode();
+                s_logger.error(errMsg);
+                String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right f of" + " server?";
+                Answer ans = new UnsupportedAnswer(null, unsupportMsg);
+                s_logger.error(ans);
+                result = s_gson.toJson(new Answer[] {ans});
+            } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+                String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
+                s_logger.error(errMsg);
+                throw new ExecutionException("UNAUTHORIZED");
+            } else {
+                result = EntityUtils.toString(response.getEntity());
+                String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
+                s_logger.debug("Get response is " + logResult);
+            }
+        } catch (ClientProtocolException protocolEx) {
+            // Problem with HTTP message exchange
+            s_logger.error(protocolEx);
+        } catch (IOException connEx) {
+            // Problem with underlying communications
+            s_logger.error(connEx);
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+        return result;
+    }
+
+    public static String postHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException {
+        // Using Apache's HttpClient for HTTP POST
+        // Java-only approach discussed at on StackOverflow concludes with
+        // comment to use Apache HttpClient
+        // http://stackoverflow.com/a/2793153/939250, but final comment is to
+        // use Apache.
+        String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
+        logMessage = cleanPassword(logMessage);
+        s_logger.debug("POST request to " + agentUri.toString()
+                + " with contents " + logMessage);
+
+        // Create request
+        HttpClient httpClient = getHttpClient();
+        TrustStrategy easyStrategy = new TrustStrategy() {
+            @Override
+            public boolean isTrusted(X509Certificate[] chain, String authType)
+                    throws CertificateException {
+                return true;
+            }
+        };
+
+        try {
+            SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier());
+            SchemeRegistry registry = new SchemeRegistry();
+            registry.register(new Scheme("https", DEFAULT_PORT, sf));
+            ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
+            httpClient = new DefaultHttpClient(ccm);
+        } catch (KeyManagementException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (UnrecoverableKeyException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (NoSuchAlgorithmException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        } catch (KeyStoreException e) {
+            s_logger.error("failed to initialize http client " + e.getMessage());
+        }
+
+        String result = null;
+
+        // TODO: are there timeout settings and worker thread settings to tweak?
+        try {
+            HttpPost request = new HttpPost(agentUri);
+
+            // JSON encode command
+            // Assumes command sits comfortably in a string, i.e. not used for
+            // large data transfers
+            StringEntity cmdJson = new StringEntity(jsonCmd);
+            request.addHeader("content-type", "application/json");
+            request.addHeader("Cookie", "SessId=" + sessionID);
+            request.setEntity(cmdJson);
+            s_logger.debug("Sending cmd to " + agentUri.toString()
+                    + " cmd data:" + logMessage + "SEssion id: " + sessionID);
+            HttpResponse response = httpClient.execute(request);
+
+            // Unsupported commands will not route.
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+                String errMsg = "Failed : HTTP error code : " + response.getStatusLine().getStatusCode();
+                throw new ExecutionException(NccHttpCode.NOT_FOUND);
+            } else if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK ) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED )) {
+                String errMsg = "Command Not Success " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
+                s_logger.error(errMsg);
+                throw new ExecutionException(NccHttpCode.INTERNAL_ERROR + " " + errMsg);
+            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+                //Successfully created the resource in the NCC, Now get the Job ID and send to the response
+                // make login request and store new session id
+                throw new ExecutionException(NccHttpCode.UNAUTHORIZED);
+            } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) {
+                //Successfully created the resource in the NCC, Now get the Job ID and send to the response
+                result = response.getFirstHeader(NccHttpCode.JOB_ID).getValue();
+            } else {
+                result = EntityUtils.toString(response.getEntity());
+                String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
+                s_logger.debug("POST response is " + logResult);
+            }
+
+        } catch (ClientProtocolException protocolEx) {
+            // Problem with HTTP message exchange
+            s_logger.error(protocolEx);
+        } catch (IOException connEx) {
+            // Problem with underlying communications
+            s_logger.error(connEx);
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+        return result;
+    }
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/resource/NetscalerResource.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/resource/NetscalerResource.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/vm/NetScalerVMManager.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/vm/NetScalerVMManager.java
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/vm/NetScalerVMManagerImpl.java
similarity index 100%
rename from plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
rename to plugins/network-elements/netscaler/src/main/java/com/cloud/network/vm/NetScalerVMManagerImpl.java
diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties b/plugins/network-elements/netscaler/src/main/resources/META-INF/cloudstack/netscaler/module.properties
similarity index 100%
rename from plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/module.properties
rename to plugins/network-elements/netscaler/src/main/resources/META-INF/cloudstack/netscaler/module.properties
diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml b/plugins/network-elements/netscaler/src/main/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
similarity index 100%
rename from plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
rename to plugins/network-elements/netscaler/src/main/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml
index e7cd0ae..b900959 100644
--- a/plugins/network-elements/nicira-nvp/pom.xml
+++ b/plugins/network-elements/nicira-nvp/pom.xml
@@ -1,102 +1,60 @@
 <!--
+  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
 
-    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
 
-      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.
-
+  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-network-nvp</artifactId>
-  <name>Apache CloudStack Plugin - Network Nicira NVP</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>4.11.4.0-SNAPSHOT</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <sourceDirectory>src/main/java</sourceDirectory>
-    <testSourceDirectory>src/test/java</testSourceDirectory>
-    <outputDirectory>target/classes</outputDirectory>
-    <testOutputDirectory>target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>src/test/resources</directory>
-        <filtering>true</filtering>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-pmd-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-
-  <profiles>
-    <profile>
-      <id>integration</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
+    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-network-nvp</artifactId>
+    <name>Apache CloudStack Plugin - Network Nicira NVP</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>integration</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
index 548884e..3ffc601 100644
--- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
+++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
@@ -182,7 +182,7 @@
         }
 
         final NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(),
-                State.Allocated, network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
+                State.Allocated, network.getDataCenterId(), physicalNetworkId, offering.isRedundantRouter());
 
         if (network.getGateway() != null) {
             implemented.setGateway(network.getGateway());
diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
index 3d52f84..1fc000a 100644
--- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
+++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java
@@ -469,7 +469,7 @@
         final NetworkProfile implementednetwork = mock(NetworkProfile.class);
         when(implementednetwork.getId()).thenReturn(NETWORK_ID);
         when(implementednetwork.getBroadcastUri()).thenReturn(new URI("lswitch:aaaa"));
-        when(offering.getSpecifyVlan()).thenReturn(false);
+        when(offering.isSpecifyVlan()).thenReturn(false);
 
         guru.shutdown(implementednetwork, offering);
         verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any());
diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml
index 7195e32..8c82acb 100644
--- a/plugins/network-elements/nuage-vsp/pom.xml
+++ b/plugins/network-elements/nuage-vsp/pom.xml
@@ -1,64 +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
 
-    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
 
-      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.
-
+  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-network-vsp</artifactId>
-  <name>Apache CloudStack Plugin - Nuage VSP</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <repositories>
-    <repository>
-      <id>nuage-vsp</id>
-      <url>http://cs.mv.nuagenetworks.net/releases/</url>
-    </repository>
-  </repositories>
-  <properties>
-      <nuage.vsp.client.version>1.0.8</nuage.vsp.client.version>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>net.nuagenetworks.vsp</groupId>
-      <artifactId>nuage-vsp-acs-client</artifactId>
-      <version>${nuage.vsp.client.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+<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-network-vsp</artifactId>
+    <name>Apache CloudStack Plugin - Nuage VSP</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <repositories>
+        <repository>
+            <id>nuage-vsp</id>
+            <url>http://cs.mv.nuagenetworks.net/releases/</url>
+        </repository>
+    </repositories>
+    <properties>
+        <nuage.vsp.client.version>1.0.8</nuage.vsp.client.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>net.nuagenetworks.vsp</groupId>
+            <artifactId>nuage-vsp-acs-client</artifactId>
+            <version>${nuage.vsp.client.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java
deleted file mode 100644
index 0f6bff9..0000000
--- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java
+++ /dev/null
@@ -1,793 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.network.element;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import net.nuage.vsp.acs.client.api.model.VspAclRule;
-import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
-import net.nuage.vsp.acs.client.api.model.VspNetwork;
-import net.nuage.vsp.acs.client.api.model.VspStaticNat;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.network.ExternalNetworkDeviceManager;
-import org.apache.cloudstack.resourcedetail.VpcDetailVO;
-import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupVspCommand;
-import com.cloud.agent.api.element.ApplyAclRuleVspCommand;
-import com.cloud.agent.api.element.ApplyStaticNatVspCommand;
-import com.cloud.agent.api.element.ExtraDhcpOptionsVspCommand;
-import com.cloud.agent.api.element.ImplementVspCommand;
-import com.cloud.agent.api.element.ShutDownVpcVspCommand;
-import com.cloud.agent.api.element.ShutDownVspCommand;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.dc.dao.VlanDetailsDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkMigrationManager;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.dao.FirewallRulesCidrsDao;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.manager.NuageVspManagerImpl;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.FirewallRuleType;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.StaticRouteProfile;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcOfferingServiceMapVO;
-import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.server.ResourceTag;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.util.NuageVspEntityBuilder;
-import com.cloud.util.NuageVspUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-
-public class NuageVspElement extends AdapterBase implements ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
-        DhcpServiceProvider, ResourceStateAdapter, VpcProvider, NetworkACLServiceProvider {
-
-    private static final Logger s_logger = Logger.getLogger(NuageVspElement.class);
-
-    private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
-
-    private static final Set<Service> REQUIRED_SERVICES = ImmutableSet.of(
-            Service.Connectivity,
-            Service.Dhcp
-    );
-    private static final Set<Service> NUAGE_ONLY_SERVICES = ImmutableSet.of(
-            Service.SourceNat,
-            Service.StaticNat,
-            Service.Gateway
-    );
-    private static final Set<Service> UNSUPPORTED_SERVICES = ImmutableSet.of(
-            Service.Vpn,
-            Service.Dns,
-            Service.PortForwarding,
-            Service.SecurityGroup
-    );
-    private static final Set<Pair<Service, Service>> ANY_REQUIRED_SERVICES = ImmutableSet.of(
-            new Pair<>(Service.SourceNat, Service.StaticNat)
-    );
-
-
-    public static final ExternalNetworkDeviceManager.NetworkDevice NuageVspDevice = new ExternalNetworkDeviceManager.NetworkDevice("NuageVsp", Provider.NuageVsp.getName());
-
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    VlanDetailsDao _vlanDetailsDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    VpcOfferingServiceMapDao _vpcOfferingSrvcDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    NetworkOfferingDao _ntwkOfferingDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    NuageVspManager _nuageVspManager;
-    @Inject
-    FirewallRulesDao _firewallRulesDao;
-    @Inject
-    FirewallRulesCidrsDao _firewallRulesCidrsDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    @Inject
-    NuageVspEntityBuilder _nuageVspEntityBuilder;
-    @Inject
-    VpcDetailsDao _vpcDetailsDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-
-    @Override
-    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
-        return false;
-    }
-
-    @Override
-    public Map<Service, Map<Capability, String>> getCapabilities() {
-        return capabilities;
-    }
-
-    private static Map<Service, Map<Capability, String>> setCapabilities() {
-        return ImmutableMap.<Service, Map<Capability, String>>builder()
-            .put(Service.Connectivity, ImmutableMap.of(
-                    Capability.NoVlan, "",
-                    Capability.PublicAccess, ""
-            ))
-            .put(Service.Gateway, ImmutableMap.<Capability, String>of())
-            .put(Service.SourceNat, ImmutableMap.of(
-                    Capability.SupportedSourceNatTypes, "perzone",
-                    Capability.RedundantRouter, "false"
-            ))
-            .put(Service.StaticNat, ImmutableMap.<Capability, String>of())
-            .put(Service.SecurityGroup, ImmutableMap.<Capability, String>of())
-            .put(Service.Firewall, ImmutableMap.of(
-                    Capability.TrafficStatistics, "per public ip",
-                    Capability.SupportedProtocols, "tcp,udp,icmp",
-                    Capability.SupportedEgressProtocols, "tcp,udp,icmp, all",
-                    Capability.SupportedTrafficDirection, "ingress, egress",
-                    Capability.MultipleIps, "true"
-            ))
-            .put(Service.Dhcp, ImmutableMap.of(
-                    Capability.DhcpAccrossMultipleSubnets, "true",
-                    Capability.ExtraDhcpOptions, "true"
-            ))
-            .put(Service.NetworkACL, ImmutableMap.of(
-                    Capability.SupportedProtocols, "tcp,udp,icmp"
-            ))
-            .build();
-    }
-
-    @Override
-    public Provider getProvider() {
-        return Provider.NuageVsp;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        _resourceMgr.registerResourceStateAdapter(name, this);
-        return true;
-    }
-
-    @Override
-    public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
-            ResourceUnavailableException, InsufficientCapacityException {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Entering NuageElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")");
-        }
-
-        if (network.getVpcId() != null) {
-            return applyACLRulesForVpc(network, offering);
-        }
-
-        if (!canHandle(network, offering, Service.Connectivity)) {
-            return false;
-        }
-
-        if (network.getBroadcastUri() == null) {
-            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
-            return false;
-        }
-
-        _nuageVspManager.updateBroadcastUri(network);
-        network = _networkDao.findById(network.getId());
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-        List<VspAclRule> ingressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Ingress);
-        List<VspAclRule> egressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Egress);
-
-        List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(network.getId());
-        List<String> floatingIpUuids = new ArrayList<String>();
-        for (IPAddressVO ip : ips) {
-            floatingIpUuids.add(ip.getUuid());
-        }
-        VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering);
-        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
-        ImplementVspCommand cmd = new ImplementVspCommand(vspNetwork, ingressFirewallRules, egressFirewallRules, floatingIpUuids, vspDhcpOptions);
-        send(cmd, network);
-
-        return true;
-    }
-
-    private void send(Command cmd, Network network)
-            throws ResourceUnavailableException {
-        send(cmd, network.getPhysicalNetworkId(), Network.class, network);
-    }
-
-    private void send(Command cmd, Vpc vpc)
-            throws ResourceUnavailableException {
-        send(cmd, getPhysicalNetworkId(vpc.getZoneId()), Vpc.class, vpc);
-    }
-
-
-    private <R extends InternalIdentity> void send(Command cmd, long physicalNetworkId, Class<R> resourceClass,
-            R resource)
-            throws ResourceUnavailableException {
-        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
-        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-        if (isFailure(answer)) {
-            s_logger.error(cmd.getClass().getName() + " for " + resourceClass.getName() + " " + resource.getId() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-            if (hasFailureDetails(answer)) {
-                throw new ResourceUnavailableException(answer.getDetails(), resourceClass, resource.getId());
-            }
-        }
-    }
-
-    private boolean hasFailureDetails(Answer answer) {
-        return (null != answer) && (null != answer.getDetails());
-    }
-
-    private boolean isFailure(Answer answer) {
-        return answer == null || !answer.getResult();
-    }
-
-    private boolean applyACLRulesForVpc(Network network, NetworkOffering offering) throws ResourceUnavailableException {
-        List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(network.getNetworkACLId());
-        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.NetworkACL)) {
-            applyACLRules(network, rules, true, false);
-        }
-        return true;
-    }
-
-    private List<VspAclRule> getFirewallRulesToApply(final Network network, FirewallRule.TrafficType trafficType) {
-        List<FirewallRuleVO> firewallRulesToApply = _firewallRulesDao.listByNetworkPurposeTrafficType(network.getId(), FirewallRule.Purpose.Firewall, trafficType);
-        List<VspAclRule> vspAclRulesToApply = Lists.newArrayListWithExpectedSize(firewallRulesToApply.size());
-
-        for (FirewallRuleVO rule : firewallRulesToApply) {
-            rule.setSourceCidrList(_firewallRulesCidrsDao.getSourceCidrs(rule.getId()));
-            VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(rule, network);
-            vspAclRulesToApply.add(vspAclRule);
-        }
-        return vspAclRulesToApply;
-    }
-
-    @Override
-    public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
-            ResourceUnavailableException, InsufficientCapacityException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-
-        if (network.getBroadcastUri() == null) {
-            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-
-        if (network.getBroadcastUri() == null) {
-            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-        if (cleanup && isDnsSupportedByVR(network)) {
-            // The network is restarted, possibly the domain name is changed, update the dhcpOptions as soon as possible
-            NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
-            VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO);
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-
-            ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions);
-            send(cmd, network);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean isReady(PhysicalNetworkServiceProvider provider) {
-        return true;
-    }
-
-    @Override
-    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean canEnableIndividualServices() {
-        return true;
-    }
-
-    @Override
-    public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
-        return canHandle(network, Service.Connectivity);
-    }
-
-    @Override
-    public boolean verifyServicesCombination(Set<Service> services) {
-        Preconditions.checkNotNull(services);
-        final Sets.SetView<Service> missingServices = Sets.difference(REQUIRED_SERVICES, services);
-        final Sets.SetView<Service> unsupportedServices = Sets.intersection(UNSUPPORTED_SERVICES, services);
-        final Sets.SetView<Service> wantedServices = Sets.intersection(NUAGE_ONLY_SERVICES, new HashSet<>());
-
-        if (!missingServices.isEmpty()) {
-            throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " requires services: " + missingServices);
-        }
-
-        if (!unsupportedServices.isEmpty()) {
-            // NuageVsp doesn't implement any of these services.
-            // So if these services are requested, we can't handle it.
-            s_logger.debug("Unable to support services combination. The services " + unsupportedServices + " are not supported by Nuage VSP.");
-            return false;
-        }
-
-        if (!wantedServices.isEmpty()) {
-            throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " does not support services to be implemented by another provider: " + wantedServices);
-        }
-
-        return true;
-    }
-
-    protected boolean canHandle(Network network, Service service) {
-        NetworkOffering networkOffering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
-        return canHandle(network, networkOffering, service);
-    }
-
-    protected boolean canHandle(Network network, NetworkOffering networkOffering, Service service) {
-        if (network.getBroadcastDomainType() != Networks.BroadcastDomainType.Vsp) {
-            return false;
-        }
-
-        if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp is not a provider for network " + network.getDisplayText());
-            }
-            return false;
-        }
-
-        if (service != null) {
-            if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("NuageVsp can't provide the " + service.getName() + " service on network " + network.getDisplayText());
-                }
-                return false;
-            }
-        }
-
-        if (service != Service.Connectivity
-                && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
-            }
-            return false;
-        }
-
-        if (service != Service.SourceNat
-                && networkOffering.getGuestType() == Network.GuestType.Isolated
-                && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
-            }
-            return false;
-        }
-
-        if (networkOffering.getSpecifyVlan()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp doesn't support VLAN values for networks");
-            }
-            return false;
-        }
-
-        if (network.getVpcId() != null && !networkOffering.getIsPersistent()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent");
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
-            InsufficientCapacityException, ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        return true;
-    }
-
-    private boolean isDnsSupportedByVR(Network network) {
-        return (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns) &&
-                ( _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns,  Provider.VirtualRouter) ||
-                  _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns,  Provider.VPCVirtualRouter)));
-    }
-
-    @Override
-    public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
-        if (network.isRollingRestart()) {
-            return true;
-        }
-
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
-        NicVO nic = _nicDao.findById(nicId);
-
-        ExtraDhcpOptionsVspCommand extraDhcpOptionsVspCommand = new ExtraDhcpOptionsVspCommand(vspNetwork, nic.getUuid(), dhcpOptions);
-        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), extraDhcpOptionsVspCommand);
-        if (isFailure(answer)) {
-            s_logger.error("[setExtraDhcpOptions] setting extra DHCP options for nic " + nic.getUuid() + " failed.");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) {
-        return false;
-    }
-
-    @Override
-    public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
-        List<VspStaticNat> vspStaticNatDetails = new ArrayList<VspStaticNat>();
-        for (StaticNat staticNat : rules) {
-            IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId());
-            VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId());
-            checkVlanUnderlayCompatibility(sourceNatVlan);
-
-            if (!staticNat.isForRevoke()) {
-                final List<FirewallRuleVO> firewallRules = _firewallRulesDao.listByIpAndNotRevoked(staticNat.getSourceIpAddressId());
-                for (FirewallRuleVO firewallRule : firewallRules) {
-                    _nuageVspEntityBuilder.buildVspAclRule(firewallRule, config, sourceNatIp);
-                }
-            }
-
-            NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId());
-            VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(staticNat.isForRevoke(), sourceNatIp, sourceNatVlan, nicVO);
-            vspStaticNatDetails.add(vspStaticNat);
-
-
-        }
-
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config);
-        ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails);
-        send(cmd,
-             config);
-
-        return true;
-    }
-
-    private void checkVlanUnderlayCompatibility(VlanVO newVlan) throws ResourceUnavailableException {
-        List<VlanVO> vlans = _vlanDao.listByZone(newVlan.getDataCenterId());
-        if (CollectionUtils.isNotEmpty(vlans)) {
-            boolean newVlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, newVlan);
-            final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(newVlan.getVlanGateway(), newVlan.getVlanNetmask());
-
-            for (VlanVO vlan : vlans) {
-                if (vlan.getId() == newVlan.getId()) continue;
-
-                final String existingCidr = NetUtils.getCidrFromGatewayAndNetmask(vlan.getVlanGateway(), vlan.getVlanNetmask());
-
-                NetUtils.SupersetOrSubset supersetOrSubset = NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(newCidr, existingCidr);
-                if (supersetOrSubset == NetUtils.SupersetOrSubset.sameSubnet) {
-                    boolean vlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan);
-                    if (newVlanUnderlay != vlanUnderlay) {
-                        throw new ResourceUnavailableException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported", Vlan.class, newVlan.getId());
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    @Override
-    public IpDeployer getIpDeployer(Network network) {
-        return this;
-    }
-
-    @Override
-    public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
-        if (rules == null || rules.isEmpty()) {
-            return true;
-        }
-
-        if (rules.size() == 1 && rules.iterator().next().getType().equals(FirewallRuleType.System)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Default ACL added by CS as system is ignored for network " + network.getName() + " with rule " + rules);
-            }
-            return true;
-        }
-
-        s_logger.info("Applying " + rules.size() + " Firewall Rules for network " + network.getName());
-        return applyACLRules(network, rules, false, false);
-    }
-
-    protected boolean applyACLRules(final Network network, List<? extends InternalIdentity> rules, boolean isNetworkAcl, boolean networkReset)
-            throws ResourceUnavailableException {
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-        List<VspAclRule> vspAclRules = Lists.transform(rules, new Function<InternalIdentity, VspAclRule>() {
-            @Nullable
-            @Override
-            public VspAclRule apply(@Nullable InternalIdentity input) {
-                if (input instanceof FirewallRule) {
-                    return _nuageVspEntityBuilder.buildVspAclRule((FirewallRule) input, network);
-                }
-                return _nuageVspEntityBuilder.buildVspAclRule((NetworkACLItem) input);
-            }
-        });
-
-        VspAclRule.ACLType vspAclType = isNetworkAcl ? VspAclRule.ACLType.NetworkACL : VspAclRule.ACLType.Firewall;
-        ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(vspAclType, vspNetwork, vspAclRules, networkReset);
-        send(cmd,
-             network);
-        return true;
-    }
-
-    @Override
-    public boolean applyNetworkACLs(Network config, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
-        if (rules == null || rules.isEmpty()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("No rules to apply. So, delete all the existing ACL in VSP from Subnet with uuid " + config.getUuid());
-            }
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("New rules has to applied. So, delete all the existing ACL in VSP from Subnet with uuid " + config.getUuid());
-            }
-        }
-        if (rules != null) {
-            s_logger.info("Applying " + rules.size() + " Network ACLs for network " + config.getName());
-            applyACLRules(config, rules, true, rules.isEmpty());
-        }
-        return true;
-    }
-
-    @Override
-    public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        List<VpcOfferingServiceMapVO> vpcOfferingServices = _vpcOfferingSrvcDao.listByVpcOffId(vpc.getVpcOfferingId());
-        Multimap<Service, Provider> supportedVpcServices = NuageVspManagerImpl.SUPPORTED_NUAGE_VSP_VPC_SERVICE_MAP;
-        for (VpcOfferingServiceMapVO vpcOfferingService : vpcOfferingServices) {
-            Network.Service service = Network.Service.getService(vpcOfferingService.getService());
-            if (!supportedVpcServices.containsKey(service)) {
-                s_logger.warn(String.format("NuageVsp doesn't support service %s for VPCs", service.getName()));
-                return false;
-            }
-
-            Network.Provider provider = Network.Provider.getProvider(vpcOfferingService.getProvider());
-            if (!supportedVpcServices.containsEntry(service, provider)) {
-                s_logger.warn(String.format("NuageVsp doesn't support provider %s for service %s for VPCs", provider.getName(), service.getName()));
-                return false;
-            }
-        }
-
-        String globalDomainTemplate = _nuageVspManager.NuageVspVpcDomainTemplateName.value();
-        if (StringUtils.isNotBlank(globalDomainTemplate) && !_nuageVspManager.checkIfDomainTemplateExist(vpc.getDomainId(),globalDomainTemplate,vpc.getZoneId(),null)) {
-            s_logger.warn("The global pre configured domain template does not exist on the VSD.");
-            throw new CloudRuntimeException("The global pre configured domain template does not exist on the VSD.");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
-        if (vpc.getState().equals(Vpc.State.Inactive)) {
-            List<DomainRouterVO> routers = _routerDao.listByVpcId(vpc.getId());
-            if (CollectionUtils.isEmpty(routers)) {
-                routers = _routerDao.listIncludingRemovedByVpcId(vpc.getId());
-            }
-
-            List<String> domainRouterUuids = Lists.transform(routers, new Function<DomainRouterVO, String>() {
-                @Nullable
-                @Override
-                public String apply(@Nullable DomainRouterVO input) {
-                    return input != null ? input.getUuid() : null;
-                }
-            });
-
-            Domain vpcDomain = _domainDao.findById(vpc.getDomainId());
-
-            String preConfiguredDomainTemplateName;
-            VpcDetailVO domainTemplateNameDetail = _vpcDetailsDao.findDetail(vpc.getId(), NuageVspManager.nuageDomainTemplateDetailName);
-            if (domainTemplateNameDetail != null) {
-                preConfiguredDomainTemplateName = domainTemplateNameDetail.getValue();
-            } else {
-                preConfiguredDomainTemplateName = _configDao.getValue(NuageVspManager.NuageVspVpcDomainTemplateName.key());
-            }
-
-            Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpc.getId(), false);
-
-            cleanUpVpcCaching(vpc.getId());
-            //related to migration caching
-            List<? extends ResourceTag> vpcResourceDetails = _resourceTagDao.listByResourceUuid(vpc.getUuid());
-            if (vpcResourceDetails != null) {
-                vpcResourceDetails.stream()
-                                  .filter(item -> item.getKey().equals(NetworkMigrationManager.MIGRATION))
-                                  .findFirst()
-                                  .map(ResourceTag::getResourceId)
-                                  .ifPresent(this::cleanUpVpcCaching);
-            }
-
-            ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids, vpcDetails);
-            send(cmd, vpc);
-        }
-        return true;
-    }
-
-    private void cleanUpVpcCaching(long vpcId) {
-        _vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
-        _vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
-    }
-
-    private Long getPhysicalNetworkId(Long zoneId) {
-        Long guestPhysicalNetworkId = 0L;
-        List<PhysicalNetworkVO> physicalNetworkList = _physicalNetworkDao.listByZone(zoneId);
-        for (PhysicalNetworkVO phyNtwk : physicalNetworkList) {
-            if (phyNtwk.getIsolationMethods().contains("VSP")) {
-                guestPhysicalNetworkId = phyNtwk.getId();
-                break;
-            }
-        }
-        return guestPhysicalNetworkId;
-    }
-
-    @Override
-    public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException {
-        return false;
-    }
-
-    @Override
-    public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException {
-        return false;
-    }
-
-    @Override
-    public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
-        return false;
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        return null;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        if (!(startup[0] instanceof StartupVspCommand)) {
-            return null;
-        }
-        host.setType(Host.Type.L2Networking);
-        return host;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (!(host.getType() == Host.Type.L2Networking)) {
-            return null;
-        }
-        return new DeleteHostAnswer(true);
-    }
-}
\ No newline at end of file
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java
deleted file mode 100644
index 8d53f0f..0000000
--- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java
+++ /dev/null
@@ -1,874 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.network.guru;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
-import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
-import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
-import net.nuage.vsp.acs.client.api.model.VspDomain;
-import net.nuage.vsp.acs.client.api.model.VspNetwork;
-import net.nuage.vsp.acs.client.api.model.VspNic;
-import net.nuage.vsp.acs.client.api.model.VspStaticNat;
-import net.nuage.vsp.acs.client.api.model.VspVm;
-
-import org.apache.log4j.Logger;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.resourcedetail.VpcDetailVO;
-import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.guru.DeallocateVmVspCommand;
-import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
-import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
-import com.cloud.agent.api.guru.TrashNetworkVspCommand;
-import com.cloud.agent.api.guru.UpdateDhcpOptionVspCommand;
-import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterDetailVO;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.dc.dao.VlanDetailsDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.HostVO;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.util.NuageVspEntityBuilder;
-import com.cloud.util.NuageVspUtil;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions {
-    public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class);
-
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    NetworkOfferingDao _ntwkOfferingDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    NuageVspManager _nuageVspManager;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NuageVspEntityBuilder _nuageVspEntityBuilder;
-    @Inject
-    NetworkDetailsDao _networkDetailsDao;
-    @Inject
-    VpcDetailsDao _vpcDetailsDao;
-    @Inject
-    NetworkOrchestrationService _networkOrchestrationService;
-    @Inject
-    DataCenterDetailsDao _dcDetailsDao;
-    @Inject
-    VlanDetailsDao _vlanDetailsDao;
-    @Inject
-    private DomainRouterDao _routerDao;
-
-    public NuageVspGuestNetworkGuru() {
-        super();
-        _isolationMethods = new IsolationMethod[] {new IsolationMethod("VSP")};
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Refusing to design network using network offering " +  offering.getId() + (physnet != null ? " on physical network " + physnet.getId() : ""));
-            }
-            return null;
-        }
-
-        NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
-        if (networkObject == null) {
-            return null;
-        }
-
-        networkObject.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
-
-        if (userSpecified instanceof NetworkVO && userSpecified.getExternalId() != null) {
-            if (owner.getType() < Account.ACCOUNT_TYPE_ADMIN) {
-                throw new IllegalArgumentException("vsdManaged networks are only useable by admins.");
-            }
-
-            if (!isUniqueReference(plan.getDataCenterId(), userSpecified.getExternalId())) {
-                s_logger.debug("Refusing to design network. VsdManaged network object already present in zone.");
-                return null;
-            }
-        }
-
-        return networkObject;
-    }
-
-    private boolean isUniqueReference(long dataCenterId, String vsdSubnetId) {
-        DataCenterDetailVO detail = _dcDetailsDao.findDetail(dataCenterId, vsdSubnetId);
-        return detail == null;
-    }
-
-    private boolean isVsdManagedVpc(long vpcId) {
-        //Check if it's a vpc and if the vpc is already vsdManaged OR if it has 0 tiers
-        Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
-        return vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED) != null && vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED).equals("true");
-    }
-
-    /** In case an externalId is specified, we get called here, and store the id the same way as cached data */
-    @Override
-    public void finalizeNetworkDesign(long networkId, String vlanIdAsUUID) {
-        NetworkVO designedNetwork = _networkDao.findById(networkId);
-        String externalId = designedNetwork.getExternalId();
-        boolean isVpc = designedNetwork.getVpcId() != null;
-
-        if (isVpc && _networkDao.listByVpc(designedNetwork.getVpcId()).size() > 1) {
-            boolean isVsdManagedVpc = isVsdManagedVpc(designedNetwork.getVpcId());
-            if (isVsdManagedVpc && externalId == null) {
-                throw new CloudRuntimeException("Refusing to design network. Network is vsdManaged but is part of a non vsd managed vpc.");
-            } else if (!isVsdManagedVpc && externalId != null) {
-                throw new CloudRuntimeException("Refusing to design network. Network is not vsdManaged but is part of a vsd managed vpc.");
-            }
-        }
-
-        if (externalId == null) {
-            return;
-        }
-
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(designedNetwork, externalId);
-        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(designedNetwork.getPhysicalNetworkId());
-
-        ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, null, true);
-        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-        if (answer == null || !answer.getResult()) {
-            s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-            if ((null != answer) && (null != answer.getDetails())) {
-                s_logger.error(answer.getDetails());
-            }
-            throw new CloudRuntimeException("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-        }
-
-        //check if the network does not violate the uuid cidr
-        ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
-        VspNetwork updatedVspNetwork = implementAnswer.getVspNetwork();
-        NetworkVO forUpdate = _networkDao.createForUpdate(networkId);
-
-        if (isVpc && (!designedNetwork.getCidr().equals(updatedVspNetwork.getCidr()) || !designedNetwork.getGateway().equals(updatedVspNetwork.getGateway()))) {
-         throw new CloudRuntimeException("Tier network does not match the VsdManaged subnet cidr or gateway.");
-        } else {
-            forUpdate.setCidr(updatedVspNetwork.getCidr());
-            forUpdate.setGateway(updatedVspNetwork.getGateway());
-        }
-
-        saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), designedNetwork.getVpcId());
-        saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, externalId);
-        saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
-
-        forUpdate.setState(State.Allocated);
-        _networkDao.update(networkId, forUpdate);
-    }
-
-    @Override
-    public Map<String, ? extends Object> listAdditionalNicParams(String nicUuid) {
-        return null;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException {
-        long networkId = network.getId();
-        network = _networkDao.acquireInLockTable(network.getId(), 1200);
-        if (network == null) {
-            throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
-        }
-
-        /* Check if an acl template is used in combination with a pre-configured DT. -> show an error if there is
-        Rollback of the network fails in core CS -> networkOrchestrator. */
-        if(network.getVpcId() != null) {
-            VpcDetailVO detail = _vpcDetailsDao.findDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName);
-            if (detail != null && network.getNetworkACLId() != null) {
-                s_logger.error("Pre-configured DT are used in combination with ACL lists. Which is not supported.");
-                throw new IllegalArgumentException("CloudStack ACLs are not supported with Nuage Pre-configured Domain Template");
-            }
-
-            if(detail != null && !_nuageVspManager.checkIfDomainTemplateExist(network.getDomainId(),detail.getValue(),network.getDataCenterId(),null)){
-                s_logger.error("The provided domain template does not exist on the VSD.");
-                throw new IllegalArgumentException("The provided domain template does not exist on the VSD anymore.");
-            }
-        }
-
-        NetworkVO implemented = null;
-        try {
-            if (offering.getGuestType() == GuestType.Isolated && network.getState() != State.Implementing) {
-                throw new IllegalStateException("Network " + networkId + " is not in expected state Implementing, but is in state " + network.getState());
-            }
-
-            //Get the Account details and find the type
-            AccountVO networksAccount = _accountDao.findById(network.getAccountId());
-            if (networksAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                String errorMessage = "Networks created by account " + networksAccount.getAccountName() + " of type Project (" + Account.ACCOUNT_TYPE_PROJECT + ") " +
-                        "are not yet supported by NuageVsp provider";
-                s_logger.error(errorMessage);
-                throw new InsufficientVirtualNetworkCapacityException(errorMessage, Account.class, network.getAccountId());
-            }
-
-            //We don't support a shared network with UserData and multiple IP ranges at the same time.
-            checkMultipleSubnetsCombinedWithUseData(network);
-
-            long dcId = dest.getDataCenter().getId();
-            //Get physical network id
-            Long physicalNetworkId = network.getPhysicalNetworkId();
-            //Physical network id can be null in Guest Network in Basic zone, so locate the physical network
-            if (physicalNetworkId == null) {
-                physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
-            }
-
-            implemented = new NetworkVO(network.getId(), network, network.getNetworkOfferingId(), network.getGuruName(), network.getDomainId(), network.getAccountId(),
-                    network.getRelated(), network.getName(), network.getDisplayText(), network.getNetworkDomain(), network.getGuestType(), network.getDataCenterId(),
-                    physicalNetworkId, network.getAclType(), network.getSpecifyIpRanges(), network.getVpcId(), offering.getRedundantRouter(), network.getExternalId());
-            implemented.setUuid(network.getUuid());
-            implemented.setState(State.Allocated);
-            if (network.getGateway() != null) {
-                implemented.setGateway(network.getGateway());
-            }
-            if (network.getCidr() != null) {
-                implemented.setCidr(network.getCidr());
-            }
-
-            implemented.setBroadcastUri(_nuageVspManager.calculateBroadcastUri(implemented));
-            implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented);
-
-            if (vspNetwork.isShared()) {
-                Boolean previousUnderlay= null;
-                for (VlanVO vlan : _vlanDao.listVlansByNetworkId(networkId)) {
-                    boolean underlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan);
-                    if (previousUnderlay == null || underlay == previousUnderlay) {
-                        previousUnderlay = underlay;
-                    } else {
-                        throw new CloudRuntimeException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported");
-                    }
-                }
-                if (previousUnderlay != null) {
-                    vspNetwork = new VspNetwork.Builder().fromObject(vspNetwork)
-                            .vlanUnderlay(previousUnderlay)
-                            .build();
-                }
-            }
-
-            boolean implementSucceeded = implement(network.getVpcId(), physicalNetworkId, vspNetwork, implemented, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering));
-
-            if (!implementSucceeded) {
-                return null;
-            }
-
-            if (StringUtils.isNotBlank(vspNetwork.getDomainTemplateName())) {
-                if (network.getVpcId() != null) {
-                    saveVpcDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
-                } else {
-                    saveNetworkDetail(implemented.getId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
-                }
-            }
-
-            String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId();
-            s_logger.info("Implemented OK, network " + implemented.getUuid() + " in tenant " + tenantId + " linked to " + implemented.getBroadcastUri());
-        } finally {
-            _networkDao.releaseFromLockTable(network.getId());
-        }
-        return implemented;
-    }
-
-    private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, NetworkVO implemented, VspDhcpDomainOption vspDhcpDomainOption) {
-        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
-        final boolean isVsdManaged = vspNetwork.getNetworkRelatedVsdIds()
-                                          .getVsdSubnetId()
-                                          .isPresent();
-        if (isVsdManaged) {
-            //Implement cmd was already send in design step.
-            _dcDetailsDao.persist(implemented.getDataCenterId(), vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().orElseThrow(() -> new CloudRuntimeException("Managed but no subnetId. How can this happen?")), implemented.getUuid());
-            return true;
-        }
-
-        ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption, false);
-        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-        if (answer == null || !answer.getResult()) {
-            s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-            if ((null != answer) && (null != answer.getDetails())) {
-                s_logger.error(answer.getDetails());
-            }
-            return false;
-        }
-
-        ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
-        saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), vpcId);
-        return true;
-    }
-
-    private void saveNetworkAndVpcDetails(VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds, Long vpcId) {
-        if (!vspNetwork.isShared() && !vspNetwork.getNetworkRelatedVsdIds().equals(networkRelatedVsdIds)) {
-            Map<String, String> networkDetails = constructNetworkDetails(networkRelatedVsdIds, vspNetwork.isVpc());
-
-            long networkId = vspNetwork.getId();
-
-            for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
-                saveNetworkDetail(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue());
-            }
-
-            if(vspNetwork.isVpc()) {
-                Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);
-
-                for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
-                    saveVpcDetail(vpcId, vpcDetail.getKey(), vpcDetail.getValue());
-                }
-            }
-        }
-    }
-
-    private void saveVpcDetail(Long vpcId, String key, String value) {
-        _vpcDetailsDao.addDetail(vpcId, key, value, false);
-    }
-
-    private void saveNetworkDetail(long networkId, String key, String value) {
-         _networkDetailsDao.addDetail(networkId, key, value, false);
-    }
-
-    private static Map<String, String> constructNetworkDetails(NetworkRelatedVsdIds networkRelatedVsdIds, boolean isVpc) {
-        Map<String, String> networkDetails = Maps.newHashMap();
-
-        if (!isVpc) {
-            networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
-            networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
-        }
-        networkRelatedVsdIds.getVsdSubnetId().ifPresent(v ->  networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, v));
-
-        return networkDetails;
-    }
-
-    private static Map<String, String> constructVpcDetails(NetworkRelatedVsdIds networkRelatedVsdIds) {
-        Map<String, String> vpcDetails = Maps.newHashMap();
-
-        networkRelatedVsdIds.getVsdDomainId().ifPresent(v ->  vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
-        networkRelatedVsdIds.getVsdZoneId().ifPresent(v ->  vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
-        if (networkRelatedVsdIds.isVsdManaged()) {
-            vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
-        }
-
-        return vpcDetails;
-    }
-
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        if (vm.getType() != VirtualMachine.Type.DomainRouter && _nuageVspEntityBuilder.usesVirtualRouter(network.getNetworkOfferingId())) {
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-            if (nic != null && nic.getRequestedIPv4() != null && nic.getRequestedIPv4().equals(vspNetwork.getVirtualRouterIp())) {
-                DataCenter dc = _dcDao.findById(network.getDataCenterId());
-                s_logger.error("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved for the VR in network " + network);
-                throw new InsufficientVirtualNetworkCapacityException("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved " +
-                        "for the VR in network " + network, DataCenter.class,dc.getId());
-            }
-        }
-
-        return super.allocate(network, nic, vm);
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        boolean lockedNetwork = lockNetworkForUserVm(network, vm);
-        if (lockedNetwork && s_logger.isDebugEnabled()) {
-            s_logger.debug("Locked network " + network.getId() + " for creation of user VM " + vm.getInstanceName());
-        }
-
-        try {
-            //We don't support a shared network with UserData and multiple IP ranges at the same time.
-            checkMultipleSubnetsCombinedWithUseData(network);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Handling reserve() call back to with Create a new VM or add an interface to existing VM in network " + network.getName());
-            }
-
-            DataCenter dc = _dcDao.findById(network.getDataCenterId());
-            AccountVO neworkAccountDetails = _accountDao.findById(network.getAccountId());
-            if (neworkAccountDetails.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                throw new InsufficientVirtualNetworkCapacityException("CS project support is not yet implemented in NuageVsp", DataCenter.class, dc.getId());
-            }
-
-            if (Strings.isNullOrEmpty(network.getBroadcastUri().getPath()) || !network.getBroadcastUri().getPath().startsWith("/")) {
-                throw new IllegalStateException("The broadcast URI path " + network.getBroadcastUri() + " is empty or in an incorrect format.");
-            }
-
-            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network);
-
-            boolean vrAddedToNuage = vm.getType() == VirtualMachine.Type.DomainRouter && vspNetwork.getVirtualRouterIp()
-                                                                                          .equals("null");
-            if (vrAddedToNuage) {
-                //In case a VR is added due to upgrade network offering - recalculate the broadcast uri before using it.
-                _nuageVspManager.updateBroadcastUri(network);
-                network = _networkDao.findById(network.getId());
-                vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network, null);
-            }
-
-            if (vspNetwork.isShared()) {
-                vspNetwork = _nuageVspEntityBuilder.updateVspNetworkByPublicIp(vspNetwork, network, nic.getIPv4Address());
-
-                if (VirtualMachine.Type.DomainRouter.equals(vm.getType()) && !nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
-                    if(s_logger.isDebugEnabled()) {
-                        s_logger.debug("VR got spawned with a different IP, releasing the previously allocated public IP " + nic.getIPv4Address());
-                    }
-                    IPAddressVO oldIpAddress = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address());
-                    _ipAddressDao.unassignIpAddress(oldIpAddress.getId());
-                    _ipAddressDao.mark(network.getDataCenterId(), new Ip(vspNetwork.getVirtualRouterIp()));
-                } else if (VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
-                    s_logger.error("Deploying a user VM with the same IP as the VR is not allowed.");
-                    throw new InsufficientVirtualNetworkCapacityException("Deploying a user VM with the same IP " + nic.getIPv4Address() + " as the VR is not allowed.",
-                            Network.class, network.getId());
-                }
-
-                // Make sure the shared network is present
-                NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
-                if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, null, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
-                    s_logger.error("Failed to implement shared network " + network.getUuid() + " under domain " + context.getDomain().getUuid());
-                    throw new InsufficientVirtualNetworkCapacityException("Failed to implement shared network " + network.getUuid() + " under domain " +
-                            context.getDomain().getUuid(), Network.class, network.getId());
-                }
-            }
-
-            // Set flags for dhcp options
-            boolean networkHasDns = networkHasDns(network);
-
-            Map<Long, Boolean> networkHasDnsCache = Maps.newHashMap();
-            networkHasDnsCache.put(network.getId(), networkHasDns);
-
-            // Determine if dhcp options of the other nics in the network need to be updated
-            if (vm.getType() == VirtualMachine.Type.DomainRouter && network.getState() != State.Implementing) {
-                updateDhcpOptionsForExistingVms(network, nuageVspHost, vspNetwork, networkHasDns, networkHasDnsCache);
-                //update the extra DHCP options
-
-            }
-            // Update broadcast Uri to enable VR ip update
-            if (!network.getBroadcastUri().getPath().substring(1).equals(vspNetwork.getVirtualRouterIp())) {
-                NetworkVO networkToUpdate = _networkDao.findById(network.getId());
-                String broadcastUriStr = networkToUpdate.getUuid() + "/" + vspNetwork.getVirtualRouterIp();
-                networkToUpdate.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
-                _networkDao.update(network.getId(), networkToUpdate);
-                if (network instanceof NetworkVO) {
-                    ((NetworkVO) network).setBroadcastUri(networkToUpdate.getBroadcastUri());
-                }
-            }
-
-            nic.setBroadcastUri(network.getBroadcastUri());
-            nic.setIsolationUri(network.getBroadcastUri());
-
-            VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network);
-
-            if (vm.isRollingRestart()) {
-                ((NetworkVO)network).setRollingRestart(true);
-            } else {
-                //NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort
-                //that we create in VSP
-                NicVO nicFromDb = _nicDao.findById(nic.getId());
-                IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(network.getId(), vm.getId());
-                VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
-                VspStaticNat vspStaticNat = null;
-                if (staticNatIp != null) {
-                    VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
-                    vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(null, staticNatIp, staticNatVlan, vspNic);
-                }
-
-                boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, nicFromDb);
-                VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, defaultHasDns, networkHasDns);
-                ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, vspStaticNat, dhcpOption);
-                Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-
-                if (answer == null || !answer.getResult()) {
-                    s_logger.error("ReserveVmInterfaceNuageVspCommand failed for NIC " + nic.getId() + " attached to VM " + vm.getId() + " in network " + network.getId());
-                    if ((null != answer) && (null != answer.getDetails())) {
-                        s_logger.error(answer.getDetails());
-                    }
-                    throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
-                }
-            }
-
-            if (vspVm.getDomainRouter() == Boolean.TRUE) {
-                nic.setIPv4Address(vspVm.getDomainRouterIp());
-            }
-
-        } finally {
-            if (network != null && lockedNetwork) {
-                _networkDao.releaseFromLockTable(network.getId());
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unlocked network " + network.getId() + " for creation of user VM " + vm.getInstanceName());
-                }
-            }
-        }
-    }
-
-    private void updateExtraDhcpOptionsForExistingVm(Network network, Nic nic) {
-        _networkOrchestrationService.configureExtraDhcpOptions(network, nic.getId());
-    }
-
-    private void updateDhcpOptionsForExistingVms(Network network, HostVO nuageVspHost, VspNetwork vspNetwork, boolean networkHasDns, Map<Long, Boolean> networkHasDnsCache)
-            throws InsufficientVirtualNetworkCapacityException {
-        // Update dhcp options if a VR is added when we are not initiating the network
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug(String.format("DomainRouter is added to an existing network: %s in state: %s", network.getName(), network.getState()));
-        }
-
-        List<NicVO> userNics = _nicDao.listByNetworkId(network.getId());
-        LinkedListMultimap<Long, VspDhcpVMOption> dhcpOptionsPerDomain = LinkedListMultimap.create();
-
-        for (Iterator<NicVO> iterator = userNics.iterator(); iterator.hasNext(); ) {
-            NicVO userNic = iterator.next();
-            if (userNic.getVmType() == VirtualMachine.Type.DomainRouter || userNic.getState() != Nic.State.Reserved) {
-                iterator.remove();
-                continue;
-            }
-
-            VMInstanceVO userVm = _vmInstanceDao.findById(userNic.getInstanceId());
-            boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, userNic);
-            VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(userNic, defaultHasDns, networkHasDns);
-            dhcpOptionsPerDomain.put(userVm.getDomainId(), dhcpOption);
-        }
-
-        for (Long domainId : dhcpOptionsPerDomain.keySet()) {
-            VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(_domainDao.findById(domainId));
-            VspNetwork vspNetworkForDomain = new VspNetwork.Builder().fromObject(vspNetwork).domain(vspDomain).build();
-            List<VspDhcpVMOption> dhcpOptions = dhcpOptionsPerDomain.get(domainId);
-            UpdateDhcpOptionVspCommand cmd = new UpdateDhcpOptionVspCommand(dhcpOptions, vspNetworkForDomain);
-            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-
-            if (answer == null || !answer.getResult()) {
-                s_logger.error("UpdateDhcpOptionVspCommand failed at \"reserve\" for network " + vspNetwork.getName() + " under domain " + vspNetwork.getVspDomain().getName());
-                if ((null != answer) && (null != answer.getDetails())) {
-                    s_logger.error(answer.getDetails());
-                }
-                throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
-            }
-        }
-
-        for (NicVO userNic : userNics) {
-            updateExtraDhcpOptionsForExistingVm(network, userNic);
-        }
-    }
-
-
-    private boolean isServiceProvidedByVR(Network network, Network.Service service ) {
-        return (_networkModel.areServicesSupportedInNetwork(network.getId(), service) &&
-                ( _networkModel.isProviderSupportServiceInNetwork(network.getId(), service,  Network.Provider.VirtualRouter) ||
-                        _networkModel.isProviderSupportServiceInNetwork(network.getId(), service,  Network.Provider.VPCVirtualRouter)));
-    }
-
-    private void checkMultipleSubnetsCombinedWithUseData(Network network) {
-        if (isServiceProvidedByVR(network, Network.Service.UserData)) {
-            List<VlanVO> vlanVOs = _vlanDao.listVlansByNetworkId(network.getId());
-            if (vlanVOs.stream()
-                       .map(VlanVO::getVlanGateway)
-                       .distinct()
-                       .count() > 1) {
-                        s_logger.error("NuageVsp provider does not support multiple subnets in combination with user data. Network: " + network + ", vlans: " + vlanVOs);
-                        throw new UnsupportedServiceException("NuageVsp provider does not support multiple subnets in combination with user data.");
-            }
-        }
-    }
-
-    @Override
-    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
-        if (networkType == NetworkType.Advanced
-                && isMyTrafficType(offering.getTrafficType())
-                && isMyIsolationMethod(physicalNetwork)
-                && (offering.getGuestType() == GuestType.Isolated || offering.getGuestType() == GuestType.Shared)
-                && hasRequiredServices(offering)) {
-            if (_configMgr.isOfferingForVpc(offering) && !offering.getIsPersistent()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent");
-                }
-                return false;
-            } else if (offering.getGuestType() == GuestType.Shared) {
-                List<String> supportedSharedNetworkServices = Lists.newArrayList(Network.Service.Connectivity.getName(), Network.Service.Dhcp.getName(), Network.Service.UserData.getName());
-                List<String> offeringServices = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(offering.getId());
-                if (!supportedSharedNetworkServices.containsAll(offeringServices)) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("We only support " + Iterables.toString(supportedSharedNetworkServices) + " services for shared networks");
-                    }
-                    return false;
-                }
-            }
-            return true;
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("We only take care of networks in zone of type " + NetworkType.Advanced + " without VLAN");
-            }
-            return false;
-        }
-    }
-
-    private boolean hasRequiredServices(NetworkOffering networkOffering) {
-        final Map<Network.Service, Set<Network.Provider>> serviceProviderMap = _networkModel.getNetworkOfferingServiceProvidersMap(networkOffering.getId());
-
-        if (!serviceProviderMap.get(Network.Service.Connectivity).contains(Network.Provider.NuageVsp)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
-            }
-            return false;
-        }
-
-        if (networkOffering.getGuestType() == GuestType.Isolated
-                && !serviceProviderMap.get(Network.Service.SourceNat).contains(Network.Provider.NuageVsp)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
-            }
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    @DB
-    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
-        boolean lockedNetwork = lockNetworkForUserVm(network, vm);
-        if (lockedNetwork && s_logger.isDebugEnabled()) {
-            s_logger.debug("Locked network " + network.getId() + " for deallocation of user VM " + vm.getInstanceName());
-        }
-
-        try {
-            final VirtualMachine virtualMachine = vm.getVirtualMachine();
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Handling deallocate() call back, which is called when a VM is destroyed or interface is removed, " + "to delete VM Interface with IP "
-                        + nic.getIPv4Address() + " from a VM " + vm.getInstanceName() + " with state " + virtualMachine
-                                                                                                           .getState());
-            }
-
-            NicVO nicFromDb = _nicDao.findById(nic.getId());
-
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(virtualMachine
-                                                                             .getDomainId(), network);
-            VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(virtualMachine, network);
-            VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
-            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
-
-            DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(vspNetwork, vspVm, vspNic);
-            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-            if (answer == null || !answer.getResult()) {
-                s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-                if ((null != answer) && (null != answer.getDetails())) {
-                    s_logger.error(answer.getDetails());
-                }
-            }
-
-            // In case of shared network, when a User VM is spawned with the same IP as the VR, and it gets cleaned up, make sure we do not release the public IP
-            // because it is still allocated for the VR.
-            if (vspNetwork.isShared() && VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
-                nic.deallocate();
-            } else {
-                super.deallocate(network, nic, vm);
-            }
-
-            if (virtualMachine.getType() == VirtualMachine.Type.DomainRouter) {
-                final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
-                final DomainRouterVO otherRouter = routers.stream()
-                                                          .filter(r -> r.getId() != vm.getId())
-                                                          .findFirst()
-                                                          .orElse(null);
-
-                if (otherRouter != null) {
-                    nicFromDb = _nicDao.findByNtwkIdAndInstanceId(network.getId(), otherRouter.getId());
-                    vspVm = _nuageVspEntityBuilder.buildVspVm(otherRouter, network);
-                    vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb);
-
-                    VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, false, false);
-                    ReserveVmInterfaceVspCommand reserveCmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, null, dhcpOption);
-
-                    answer = _agentMgr.easySend(nuageVspHost.getId(), reserveCmd);
-                    if (answer == null || !answer.getResult()) {
-                        s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
-                        if ((null != answer) && (null != answer.getDetails())) {
-                            s_logger.error(answer.getDetails());
-                        }
-                    }
-                }
-
-            }
-        } finally {
-            if (network != null && lockedNetwork) {
-                _networkDao.releaseFromLockTable(network.getId());
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unlocked network " + network.getId() + " for deallocation of user VM " + vm.getInstanceName());
-                }
-            }
-        }
-    }
-
-    private boolean lockNetworkForUserVm(Network network, VirtualMachineProfile vm) {
-        if (!vm.getVirtualMachine().getType().isUsedBySystem()) {
-            long networkId = network.getId();
-            network = _networkDao.acquireInLockTable(network.getId(), 1200);
-            if (network == null) {
-                throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
-        super.shutdown(profile, offering);
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        long networkId = network.getId();
-        network = _networkDao.acquireInLockTable(networkId, 1200);
-        if (network == null) {
-            throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
-        }
-
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP");
-            }
-
-            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
-
-            boolean networkMigrationCopy = network.getRelated() != network.getId();
-
-            if (networkMigrationCopy) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Network " + network.getName() + " is a copy of a migrated network. Cleaning up network details of related network.");
-                }
-                cleanUpNetworkCaching(network.getRelated());
-            }
-            cleanUpNetworkCaching(network.getId());
-
-            //Clean up VSD managed subnet caching
-            if (vspNetwork.getNetworkRelatedVsdIds().isVsdManaged()) {
-                final long dataCenterId = network.getDataCenterId();
-                vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().ifPresent(subnetId -> {
-                    _dcDetailsDao.removeDetail(dataCenterId, subnetId);
-                });
-            }
-
-            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
-            TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork);
-            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
-            if (answer == null || !answer.getResult()) {
-                s_logger.error("TrashNetworkNuageVspCommand for network " + network.getUuid() + " failed");
-                if ((null != answer) && (null != answer.getDetails())) {
-                    s_logger.error(answer.getDetails());
-                }
-                return false;
-            }
-        } finally {
-            _networkDao.releaseFromLockTable(network.getId());
-        }
-        return super.trash(network, offering);
-    }
-
-    private void cleanUpNetworkCaching(long id) {
-        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
-        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
-        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID);
-        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_MANAGED);
-    }
-
-    private boolean networkHasDns(Network network) {
-
-        if (network != null) {
-            List<String> dnsProviders = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(network.getNetworkOfferingId(), Network.Service.Dns);
-            return dnsProviders.contains(Network.Provider.VirtualRouter.getName())
-                || dnsProviders.contains(Network.Provider.VPCVirtualRouter.getName());
-
-        }
-
-        return false;
-    }
-
-    private boolean getDefaultHasDns(Map<Long, Boolean> cache, Nic nic) {
-        Long networkId = nic.isDefaultNic()
-                ? Long.valueOf(nic.getNetworkId())
-                : getDefaultNetwork(nic.getInstanceId());
-
-        Boolean hasDns = cache.computeIfAbsent(networkId, k -> networkHasDns(_networkDao.findById(networkId)));
-        return hasDns;
-    }
-
-    private Long getDefaultNetwork(long vmId) {
-        NicVO defaultNic = _nicDao.findDefaultNicForVM(vmId);
-        if (defaultNic != null) return defaultNic.getNetworkId();
-        return  null;
-    }
-}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java
deleted file mode 100644
index dae21a9..0000000
--- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java
+++ /dev/null
@@ -1,310 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.network.resource;
-
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import com.google.common.base.Strings;
-
-import net.nuage.vsp.acs.client.api.NuageVspAclClient;
-import net.nuage.vsp.acs.client.api.NuageVspApiClient;
-import net.nuage.vsp.acs.client.api.NuageVspElementClient;
-import net.nuage.vsp.acs.client.api.NuageVspGuruClient;
-import net.nuage.vsp.acs.client.api.NuageVspManagerClient;
-import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader;
-import net.nuage.vsp.acs.client.api.model.VspHost;
-import net.nuage.vsp.acs.client.common.RequestType;
-import net.nuage.vsp.acs.client.common.model.NuageVspEntity;
-import net.nuage.vsp.acs.client.exception.NuageVspException;
-
-import com.cloud.agent.IAgentControl;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingNuageVspCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupVspCommand;
-import com.cloud.host.Host;
-import com.cloud.resource.ServerResource;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.mgmt.JmxUtil;
-
-public class NuageVspResource extends ManagerBase implements ServerResource, VspStatisticsMBean {
-    private static final Logger s_logger = Logger.getLogger(NuageVspResource.class);
-
-    private String _guid;
-    private String _zoneId;
-    private String _hostName;
-    private boolean _shouldAudit = true;
-
-    private VspHost _vspHost;
-
-    private static final String NUAGE_VSP_PLUGIN_ERROR_MESSAGE = "Nuage Vsp plugin client is not installed";
-    protected NuageVspPluginClientLoader _clientLoader;
-
-    public VspHost validate(Map<String, ?> params) throws ConfigurationException {
-        return validate(NuageVspResourceConfiguration.fromConfiguration(params));
-    }
-
-    public VspHost validate(NuageVspResourceConfiguration configuration) throws ConfigurationException {
-        configuration.validate();
-
-        VspHost newVspHost = configuration.buildVspHost();
-
-
-        if (!newVspHost.getApiVersion().isSupported()) {
-            s_logger.warn(String.format("[UPGRADE] API version %s of Nuage Vsp Device %s should be updated.", newVspHost.getApiVersion(), configuration.hostName()));
-        }
-
-        _guid = configuration.guid();
-        _zoneId = configuration.zoneId();
-        _hostName = configuration.hostName();
-        _name = configuration.name();
-
-        try {
-            final NuageVspPluginClientLoader clientLoader = getClientLoader(newVspHost);
-            clientLoader.getNuageVspApiClient().login();
-
-            _vspHost = newVspHost;
-            _clientLoader = clientLoader;
-        } catch (NuageVspException e) {
-            s_logger.error(e.getMessage(), e);
-            throw new CloudRuntimeException(e.getMessage(), e);
-        }
-
-        return _vspHost;
-    }
-
-    @Override
-    public long getVSDStatistics() {
-        return _clientLoader.getNuageVspStatistics().getVsdCount();
-    }
-
-
-    @Override
-    public long getVsdStatisticsByEntityType(String entity) {
-        try {
-            NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
-            return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity);
-        } catch (IllegalArgumentException e) {
-            return -1;
-        }
-    }
-
-    @Override
-    public long getVsdStatisticsByRequestType(String requestType) {
-        try {
-            RequestType requestTypeValue = RequestType.valueOf(requestType);
-            return _clientLoader.getNuageVspStatistics().getVsdCount(requestTypeValue);
-        } catch (IllegalArgumentException e) {
-            return -1;
-        }
-
-    }
-
-    @Override
-    public long getVsdStatisticsByEntityAndRequestType(String entity, String requestType) {
-        try {
-            RequestType requestTypeValue = RequestType.valueOf(requestType);
-            NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
-            return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity, requestTypeValue);
-        } catch (IllegalArgumentException e) {
-            return -1;
-        }
-    }
-
-    private static Map<String, AtomicLong> convertHashMap(Map<RequestType, AtomicLong> map) {
-        return map.entrySet()
-                .stream()
-                .collect(Collectors.toMap(
-                        e -> e.getKey().toString(),
-                        Map.Entry::getValue)
-                );
-    }
-
-    @Override
-    public Map<String, Map<String, AtomicLong>> getVsdStatisticsReport() {
-       return _clientLoader.getNuageVspStatistics()
-                .getVsdCountReport()
-                .entrySet().stream()
-                .collect(Collectors.toMap(
-                        e -> e.getKey().toString(),
-                        e -> convertHashMap(e.getValue())
-                ));
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        if(super.configure(name, params)) {
-            validate(params);
-        }
-        return true;
-    }
-
-    protected void login() throws ConfigurationException, NuageVspException {
-        getNuageVspApiClient().login();
-    }
-
-    protected NuageVspPluginClientLoader getClientLoader(VspHost vspHost) {
-        return NuageVspPluginClientLoader.getClientLoader(vspHost);
-    }
-
-    @Override
-    public boolean start() {
-        try {
-            JmxUtil.registerMBean("NuageVspResource", _name, new VspStatisticsMBeanImpl(this));
-        } catch (Exception e) {
-            s_logger.warn("Unable to initialize statistics Mbean", e);
-        }
-
-        return true;
-
-    }
-
-    @Override
-    public boolean stop() {
-
-        try {
-            JmxUtil.unregisterMBean("NuageVspResource", _name);
-        } catch (Exception e) {
-            s_logger.warn("Unable to initialize inaccurate clock", e);
-        }
-
-        return true;
-    }
-
-    @Override
-    public Host.Type getType() {
-        return Host.Type.L2Networking;
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-        StartupVspCommand sc = new StartupVspCommand();
-        sc.setGuid(_guid);
-        sc.setName(_name);
-        sc.setDataCenter(_zoneId);
-        sc.setPod("");
-        sc.setPrivateIpAddress("");
-        sc.setStorageIpAddress("");
-        sc.setVersion(NuageVspResource.class.getPackage().getImplementationVersion());
-        return new StartupCommand[] {sc};
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(long id) {
-        if (Strings.isNullOrEmpty(_vspHost.getRestRelativePath())) {
-            s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the relative path information");
-            _shouldAudit = true;
-            return null;
-        }
-
-        if (Strings.isNullOrEmpty(_vspHost.getCmsUserLogin()) || Strings.isNullOrEmpty(_vspHost.getCmsUserPassword())) {
-            s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the CMS user information");
-            _shouldAudit = true;
-            return null;
-        }
-
-        try {
-            login();
-        } catch (NuageVspException | ConfigurationException e) {
-            s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
-            _shouldAudit = true;
-            return null;
-        }
-        PingNuageVspCommand pingNuageVspCommand = new PingNuageVspCommand(Host.Type.L2Networking, id, _shouldAudit);
-        _shouldAudit = false;
-        return pingNuageVspCommand;
-    }
-
-    public boolean getStatus() {
-        try {
-            login();
-            return true;
-        } catch (NuageVspException | ConfigurationException e) {
-            s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
-            return false;
-        }
-    }
-
-    @Override
-    public Answer executeRequest(final Command cmd) {
-        final NuageVspRequestWrapper wrapper = NuageVspRequestWrapper.getInstance();
-        try {
-            return wrapper.execute(cmd, this);
-        } catch (final Exception e) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Received unsupported command " + cmd.toString(), e);
-            }
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    @Override
-    public IAgentControl getAgentControl() {
-        return null;
-    }
-
-    @Override
-    public void setAgentControl(IAgentControl agentControl) {
-    }
-
-    protected void assertNuageVspClientsLoaded() throws ConfigurationException {
-        if (_clientLoader == null) {
-            throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE);
-        }
-    }
-
-    public NuageVspApiClient getNuageVspApiClient() throws ConfigurationException {
-        assertNuageVspClientsLoaded();
-        return _clientLoader.getNuageVspApiClient();
-
-    }
-
-    public NuageVspGuruClient getNuageVspGuruClient() throws ConfigurationException {
-        assertNuageVspClientsLoaded();
-        return _clientLoader.getNuageVspGuruClient();
-    }
-
-    public NuageVspAclClient getNuageVspAclClient() throws ConfigurationException {
-        assertNuageVspClientsLoaded();
-        return _clientLoader.getNuageVspAclClient();
-    }
-
-    public NuageVspElementClient getNuageVspElementClient() throws ConfigurationException {
-        assertNuageVspClientsLoaded();
-        return _clientLoader.getNuageVspElementClient();
-    }
-
-    public NuageVspManagerClient getNuageVspManagerClient() throws ConfigurationException {
-        assertNuageVspClientsLoaded();
-        return _clientLoader.getNuageVspManagerClient();
-    }
-
-}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java
deleted file mode 100644
index 5b1419f..0000000
--- a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java
+++ /dev/null
@@ -1,463 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.util;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-
-import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
-import net.nuage.vsp.acs.client.api.model.VspAclRule;
-import net.nuage.vsp.acs.client.api.model.VspAddressRange;
-import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
-import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
-import net.nuage.vsp.acs.client.api.model.VspDomain;
-import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp;
-import net.nuage.vsp.acs.client.api.model.VspNetwork;
-import net.nuage.vsp.acs.client.api.model.VspNic;
-import net.nuage.vsp.acs.client.api.model.VspStaticNat;
-import net.nuage.vsp.acs.client.api.model.VspVm;
-import net.nuage.vsp.acs.client.common.model.Pair;
-
-import org.apache.commons.collections.MapUtils;
-import org.apache.log4j.Logger;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
-
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.dc.dao.VlanDetailsDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class NuageVspEntityBuilder {
-    private static final Logger s_logger = Logger.getLogger(NuageVspEntityBuilder.class);
-
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    VlanDetailsDao _vlanDetailsDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    NetworkDetailsDao _networkDetailsDao;
-    @Inject
-    VpcDetailsDao _vpcDetailsDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    NuageVspManager _nuageVspManager;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-
-
-    public VspDomain buildVspDomain(Domain domain) {
-        return new VspDomain.Builder()
-                .uuid(domain.getUuid())
-                .name(domain.getName())
-                .path(domain.getPath())
-                .build();
-    }
-
-    public VspDomainCleanUp buildVspDomainCleanUp(Domain domain) {
-        VspDomainCleanUp.Builder vspDomainCleanUpBuilder = new VspDomainCleanUp.Builder().uuid(domain.getUuid());
-
-        Map<String, List<String>> sharedNetworkUuids = Maps.newHashMap();
-        List<NetworkVO> allSharedNetworks = _networkDao.listByGuestType(Network.GuestType.Shared);
-        for (NetworkVO sharedNetwork : allSharedNetworks) {
-            if (_networkModel.isNetworkAvailableInDomain(sharedNetwork.getId(), domain.getId())) {
-                String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(sharedNetwork);
-                if (!sharedNetworkUuids.containsKey(preConfiguredDomainTemplateName)) {
-                    sharedNetworkUuids.put(preConfiguredDomainTemplateName, Lists.<String>newArrayList());
-                }
-                sharedNetworkUuids.get(preConfiguredDomainTemplateName).add(sharedNetwork.getUuid());
-            }
-        }
-        vspDomainCleanUpBuilder.sharedNetworkUuids(sharedNetworkUuids);
-
-        return vspDomainCleanUpBuilder.build();
-    }
-
-    public VspNetwork buildVspNetwork(Network network) {
-        return buildVspNetwork(network.getDomainId(), network, null);
-    }
-
-    public VspNetwork buildVspNetwork(Network network, String vsdSubnetId) {
-        return buildVspNetwork(network.getDomainId(), network, vsdSubnetId);
-    }
-
-    public VspNetwork buildVspNetwork(long domainId, Network network) {
-        return buildVspNetwork(domainId, network, null);
-    }
-
-    public VspNetwork buildVspNetwork(long domainId, Network network, String vsdSubnetId) {
-        VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder()
-                .id(network.getId())
-                .uuid(network.getUuid())
-                .name(network.getName())
-                .cidr(network.getCidr())
-                .gateway(network.getGateway());
-
-        DomainVO domain = _domainDao.findById(domainId);
-        VspDomain vspDomain = buildVspDomain(domain);
-        vspNetworkBuilder.domain(vspDomain);
-
-
-        AccountVO account = _accountDao.findById(network.getAccountId());
-        if (account != null) {
-            vspNetworkBuilder.accountUuid(account.getUuid()).accountName(account.getAccountName());
-        }
-
-        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy())
-                         .publicAccess(networkOffering.getSupportsPublicAccess());
-
-        Map<String, String> networkDetails = _networkDetailsDao.listDetailsKeyPairs(network.getId(), false);
-
-        final NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder = new NetworkRelatedVsdIds.Builder();
-
-        if (MapUtils.isNotEmpty(networkDetails)) {
-            relatedVsdIdsBuilder.vsdSubnetId(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID))
-                                .withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
-        } else if (vsdSubnetId != null) {
-            relatedVsdIdsBuilder.vsdSubnetId(vsdSubnetId)
-                                .withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
-        }
-
-        if (network.getVpcId() != null) {
-            long vpcId = network.getVpcId();
-            VpcVO vpc = _vpcDao.findById(vpcId);
-            vspNetworkBuilder.vpcUuid(vpc.getUuid())
-                    .vpcName(vpc.getName())
-                    .networkType(VspNetwork.NetworkType.Vpc);
-            Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
-            applyDomainAndZoneId(relatedVsdIdsBuilder, vpcDetails);
-        } else {
-            applyDomainAndZoneId(relatedVsdIdsBuilder, networkDetails);
-
-            if (networkOffering.getGuestType() == Network.GuestType.Shared) {
-                List<VlanVO> vlans = _vlanDao.listVlansByNetworkIdIncludingRemoved(network.getId());
-                List<VspAddressRange> vspAddressRanges =
-                        vlans.stream()
-                             .map(vlan -> new VspAddressRange.Builder().gateway(vlan.getVlanGateway()).netmask(vlan.getVlanNetmask()).build())
-                             .collect(Collectors.toList());
-
-
-                vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared)
-                                 .addressRanges(vspAddressRanges);
-            } else if (_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.SourceNat)
-                    || _networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.StaticNat)) {
-                vspNetworkBuilder.networkType(VspNetwork.NetworkType.L3);
-            } else {
-                vspNetworkBuilder.networkType(VspNetwork.NetworkType.L2);
-            }
-
-        }
-
-        NetworkRelatedVsdIds networkRelatedVsdIds = relatedVsdIdsBuilder.build();
-        vspNetworkBuilder.networkRelatedVsdIds(networkRelatedVsdIds);
-
-        boolean firewallServiceSupported = _networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.Firewall);
-        vspNetworkBuilder.firewallServiceSupported(firewallServiceSupported);
-
-        String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(network);
-        vspNetworkBuilder.domainTemplateName(preConfiguredDomainTemplateName);
-
-        if (usesVirtualRouter(networkOffering.getId())) {
-                String virtualRouterIp = getVirtualRouterIP(network);
-                vspNetworkBuilder.virtualRouterIp(virtualRouterIp);
-        }
-
-        return vspNetworkBuilder.build();
-    }
-
-    private void applyDomainAndZoneId(NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder, Map<String, String> details) {
-        if (MapUtils.isNotEmpty(details)) {
-            relatedVsdIdsBuilder
-                    .vsdDomainId(details.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID))
-                    .vsdZoneId(details.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID));
-        }
-    }
-
-    public boolean usesVirtualRouter(long networkOfferingId) {
-        return _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VirtualRouter) ||
-                _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VPCVirtualRouter);
-    }
-
-    public VspNetwork updateVspNetworkByPublicIp(VspNetwork vspNetwork, Network network, String publicIp) {
-        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
-        final long ip = NetUtils.ip2Long(publicIp);
-        VlanVO matchingVlan = vlans.stream()
-                                   .filter(vlan -> isVlanContainingIp(vlan, ip))
-                                   .findFirst()
-                                   .get();
-
-        boolean underlayEnabled = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, matchingVlan);
-        return new VspNetwork.Builder().fromObject(vspNetwork)
-                .gateway(matchingVlan.getVlanGateway())
-                .cidr(NetUtils.getCidrFromGatewayAndNetmask(matchingVlan.getVlanGateway(), matchingVlan.getVlanNetmask()))
-                .vlanUnderlay(underlayEnabled)
-                .build();
-    }
-
-    private boolean isVlanContainingIp(Vlan vlan, long ip) {
-        Pair<String, String> ipAddressRange =  NuageVspUtil.getIpAddressRange(vlan);
-        long startIp = NetUtils.ip2Long(ipAddressRange.getLeft());
-        long endIp = NetUtils.ip2Long(ipAddressRange.getRight());
-        return startIp <= ip && ip <= endIp;
-    }
-
-    private String getVirtualRouterIP(Network network) {
-        return network.getBroadcastUri() != null ? network.getBroadcastUri().getPath().substring(1) : null;
-    }
-
-
-    public VspVm buildVspVm(VirtualMachine vm, Network network) {
-        VspVm.Builder vspVmBuilder = new VspVm.Builder()
-                .uuid(vm.getUuid())
-                .name(vm.getInstanceName())
-                .state(getEnumValue(vm.getState(), VspVm.State.Unknown));
-
-        boolean isDomainRouter = vm.getType().equals(VirtualMachine.Type.DomainRouter);
-        vspVmBuilder.domainRouter(isDomainRouter);
-
-        if (network.getBroadcastUri() != null) {
-            String domainRouterIp = network.getBroadcastUri().getPath().substring(1);
-            vspVmBuilder.domainRouterIp(domainRouterIp);
-        }
-
-        return vspVmBuilder.build();
-    }
-
-    public VspNic buildVspNic(String nicUuid, NicProfile nicProfile) {
-        return buildVspNic(nicUuid, nicProfile.getMacAddress(), nicProfile.getIPv4Address(), nicProfile.getNetworkId(), null);
-    }
-
-    public VspNic buildVspNic(NicVO nic) {
-        return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), null);
-    }
-
-    public VspNic buildVspNic(NicVO nic, NicSecondaryIpVO nicSecondaryIp) {
-        return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), nicSecondaryIp);
-    }
-
-    private VspNic buildVspNic(String uuid, String macAddress, String ip, long networkId, NicSecondaryIpVO nicSecondaryIp) {
-        VspNic.Builder vspNicBuilder = new VspNic.Builder()
-                .uuid(uuid)
-                .macAddress(macAddress)
-                .useStaticIp(true)
-                .ip(ip);
-
-        if (nicSecondaryIp != null) {
-            vspNicBuilder.secondaryIpUuid(nicSecondaryIp.getUuid()).secondaryIpAddress(nicSecondaryIp.getIp4Address());
-        }
-
-        Network network = _networkDao.findById(networkId);
-        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-
-        return vspNicBuilder.build();
-    }
-
-    public VspStaticNat buildVspStaticNat(Boolean forRevoke, IPAddressVO staticNatIp, VlanVO staticNatVlan, VspNic vspNic) {
-        VspStaticNat.Builder vspStaticNatBuilder = new VspStaticNat.Builder()
-                .ipUuid(staticNatIp.getUuid())
-                .ipAddress(staticNatIp.getAddress().addr())
-                .revoke(forRevoke)
-                .oneToOneNat(staticNatIp.isOneToOneNat())
-                .state(getEnumValue(staticNatIp.getState(), VspStaticNat.State.class))
-                .vlanUuid(staticNatVlan.getUuid())
-                .vlanGateway(staticNatVlan.getVlanGateway())
-                .vlanNetmask(staticNatVlan.getVlanNetmask())
-                .vlanUnderlay(NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, staticNatVlan));
-
-        if (staticNatIp.getVmIp() != null) {
-            vspStaticNatBuilder.destinationIp(staticNatIp.getVmIp() + "/32");
-        }
-
-        if (vspNic != null) {
-            vspStaticNatBuilder.nic(vspNic);
-        }
-
-        return vspStaticNatBuilder.build();
-    }
-
-    public VspStaticNat buildVspStaticNat(Boolean forRevoke, IPAddressVO staticNatIp, VlanVO staticNatVlan, NicVO nic) {
-        NicSecondaryIpVO nicSecondaryIp = null;
-
-        if (nic == null && staticNatIp.getAssociatedWithVmId() != null && staticNatIp.getVmIp() != null) {
-            nicSecondaryIp = _nicSecondaryIpDao.findByIp4AddressAndInstanceId(staticNatIp.getAssociatedWithVmId(), staticNatIp.getVmIp());
-            if (nicSecondaryIp != null) {
-                nic = _nicDao.findById(nicSecondaryIp.getNicId());
-            }
-        }
-
-        VspNic vspNic = (nic != null) ? buildVspNic(nic, nicSecondaryIp) : null;
-        return buildVspStaticNat(forRevoke, staticNatIp, staticNatVlan, vspNic);
-    }
-
-    public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network) {
-        return buildVspAclRule(firewallRule, network, null);
-    }
-
-    public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network, IPAddressVO staticNat) {
-        VspAclRule.Builder vspAclRuleBuilder = new VspAclRule.Builder()
-                .uuid(firewallRule.getUuid())
-                .protocol(firewallRule.getProtocol())
-                .startPort(firewallRule.getSourcePortStart())
-                .endPort(firewallRule.getSourcePortEnd())
-                .sourceCidrList(firewallRule.getSourceCidrList())
-                .priority(-1)
-                .type(VspAclRule.ACLType.Firewall)
-                .state(getEnumValue(firewallRule.getState(), VspAclRule.ACLState.class))
-                .trafficType(getEnumValue(firewallRule.getTrafficType(), VspAclRule.ACLTrafficType.class));
-
-        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if (firewallRule.getTrafficType() == FirewallRule.TrafficType.Egress && networkOffering.getEgressDefaultPolicy()) {
-            vspAclRuleBuilder.deny();
-        } else {
-            vspAclRuleBuilder.allow();
-        }
-
-        if (staticNat == null && firewallRule.getSourceIpAddressId() != null) {
-            IPAddressVO staticNatIp = _ipAddressDao.findById(firewallRule.getSourceIpAddressId());
-
-            if (staticNatIp != null) {
-                VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
-                NicVO nic = _nicDao.findByIp4AddressAndNetworkId(staticNatIp.getVmIp(), staticNatIp.getAssociatedWithNetworkId());
-
-                vspAclRuleBuilder.staticNat(buildVspStaticNat(null, staticNatIp, staticNatVlan, nic));
-            }
-        }
-
-        return vspAclRuleBuilder.build();
-    }
-
-    public VspAclRule buildVspAclRule(NetworkACLItem networkAcl) {
-        return new VspAclRule.Builder()
-                .uuid(networkAcl.getUuid())
-                .protocol(networkAcl.getProtocol())
-                .startPort(networkAcl.getSourcePortStart())
-                .endPort(networkAcl.getSourcePortEnd())
-                .sourceIpAddress(null)
-                .sourceCidrList(networkAcl.getSourceCidrList())
-                .priority(networkAcl.getNumber())
-                .type(VspAclRule.ACLType.NetworkACL)
-                .state(getEnumValue(networkAcl.getState(), VspAclRule.ACLState.class))
-                .trafficType(getEnumValue(networkAcl.getTrafficType(), VspAclRule.ACLTrafficType.class))
-                .action(getEnumValue(networkAcl.getAction(), VspAclRule.ACLAction.class))
-                .build();
-    }
-
-    /** Build VspDhcpVMOption to put on the VM interface */
-    public VspDhcpVMOption buildVmDhcpOption (NicVO userNic, boolean defaultHasDns, boolean networkHasDns) {
-        VMInstanceVO userVm  = _vmInstanceDao.findById(userNic.getInstanceId());
-        VspDhcpVMOption.Builder vspDhcpVMOptionBuilder = new VspDhcpVMOption.Builder()
-                .nicUuid(userNic.getUuid())
-                .defaultHasDns(defaultHasDns)
-                .hostname(userVm.getHostName())
-                .networkHasDns(networkHasDns)
-                .isDefaultInterface(userNic.isDefaultNic())
-                .domainRouter(VirtualMachine.Type.DomainRouter.equals(userNic.getVmType()));
-        return vspDhcpVMOptionBuilder.build();
-    }
-
-    /** Build VspDhcpVMOption to put on the subnet */
-    public VspDhcpDomainOption buildNetworkDhcpOption(Network network, NetworkOffering offering) {
-        List<String> dnsProvider = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), Network.Service.Dns);
-        boolean isVrDnsProvider = dnsProvider.contains("VirtualRouter") || dnsProvider.contains("VpcVirtualRouter");
-        VspDhcpDomainOption.Builder vspDhcpDomainBuilder = new VspDhcpDomainOption.Builder()
-                .dnsServers(_nuageVspManager.getDnsDetails(network.getDataCenterId()))
-                .vrIsDnsProvider(isVrDnsProvider);
-
-        if (isVrDnsProvider) {
-            vspDhcpDomainBuilder.networkDomain(network.getVpcId() != null ? _vpcDao.findById(network.getVpcId()).getNetworkDomain() : network.getNetworkDomain());
-        }
-
-        return vspDhcpDomainBuilder.build();
-    }
-
-    private <E extends Enum<E>> E getEnumValue(Enum cloudstackValue, Class<E> target) {
-        try {
-            return Enum.valueOf(target, cloudstackValue.name());
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-    }
-
-    private <E extends Enum<E>> E getEnumValue(Enum cloudstackValue, E defaultValue) {
-        try {
-            return Enum.valueOf(defaultValue.getDeclaringClass(), cloudstackValue.name());
-        } catch (IllegalArgumentException e) {
-            return defaultValue;
-        }
-    }
-}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/CmdBuilder.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/CmdBuilder.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/CmdBuilder.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/CmdBuilder.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/PingNuageVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/PingNuageVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/PingNuageVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/PingNuageVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/StartupVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/StartupVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ExtraDhcpOptionsVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ExtraDhcpOptionsVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ExtraDhcpOptionsVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ExtraDhcpOptionsVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ImplementVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ImplementVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ImplementVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ImplementVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ShutDownVpcVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ShutDownVpcVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ShutDownVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/element/ShutDownVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/DeallocateVmVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/DeallocateVmVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/TrashNetworkVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/TrashNetworkVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/UpdateDhcpOptionVspCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/UpdateDhcpOptionVspCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/UpdateDhcpOptionVspCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/guru/UpdateDhcpOptionVspCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/CleanUpDomainCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/CleanUpDomainCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/CleanUpDomainCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/CleanUpDomainCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/EntityExistsCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/EntityExistsCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/GetApiDefaultsAnswer.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/GetApiDefaultsAnswer.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/GetApiDefaultsAnswer.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/GetApiDefaultsAnswer.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/GetApiDefaultsCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/GetApiDefaultsCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/GetApiDefaultsCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/GetApiDefaultsCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ImplementNetworkVspAnswer.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ImplementNetworkVspAnswer.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ImplementNetworkVspAnswer.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ImplementNetworkVspAnswer.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ListVspDomainTemplatesAnswer.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/ListVspDomainTemplatesCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/SupportedApiVersionCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/SupportedApiVersionCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/SupportedApiVersionCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/SupportedApiVersionCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncDomainAnswer.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncDomainAnswer.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncDomainAnswer.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncDomainAnswer.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncDomainCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncDomainCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncDomainCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncDomainCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdCommand.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncNuageVspCmsIdCommand.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdCommand.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/agent/api/sync/SyncNuageVspCmsIdCommand.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/AddNuageVspDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/AddNuageVspDeviceCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/AssociateNuageVspDomainTemplateCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspDevicesCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspDevicesCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspDomainTemplatesCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/ListNuageVspGlobalDomainTemplateCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/UpdateNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/UpdateNuageVspDeviceCmd.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/UpdateNuageVspDeviceCmd.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/UpdateNuageVspDeviceCmd.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/VspConstants.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/commands/VspConstants.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVlanIpRangeResponse.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVlanIpRangeResponse.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspDeviceResponse.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspDeviceResponse.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspDomainTemplateResponse.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDomainTemplateResponse.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspDomainTemplateResponse.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspResourceResponse.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/api/response/NuageVspResourceResponse.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/NuageVspDeviceVO.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/NuageVspDeviceVO.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/dao/NuageVspDao.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/dao/NuageVspDao.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/dao/NuageVspDaoImpl.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/dao/NuageVspDaoImpl.java
diff --git a/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/element/NuageVspElement.java
new file mode 100644
index 0000000..93b660a
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/element/NuageVspElement.java
@@ -0,0 +1,793 @@
+//
+// 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.network.element;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import net.nuage.vsp.acs.client.api.model.VspAclRule;
+import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
+import net.nuage.vsp.acs.client.api.model.VspNetwork;
+import net.nuage.vsp.acs.client.api.model.VspStaticNat;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager;
+import org.apache.cloudstack.resourcedetail.VpcDetailVO;
+import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupVspCommand;
+import com.cloud.agent.api.element.ApplyAclRuleVspCommand;
+import com.cloud.agent.api.element.ApplyStaticNatVspCommand;
+import com.cloud.agent.api.element.ExtraDhcpOptionsVspCommand;
+import com.cloud.agent.api.element.ImplementVspCommand;
+import com.cloud.agent.api.element.ShutDownVpcVspCommand;
+import com.cloud.agent.api.element.ShutDownVspCommand;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.Domain;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationManager;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.manager.NuageVspManagerImpl;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.FirewallRuleType;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRouteProfile;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcOfferingServiceMapVO;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.server.ResourceTag;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.util.NuageVspEntityBuilder;
+import com.cloud.util.NuageVspUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+public class NuageVspElement extends AdapterBase implements ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
+        DhcpServiceProvider, ResourceStateAdapter, VpcProvider, NetworkACLServiceProvider {
+
+    private static final Logger s_logger = Logger.getLogger(NuageVspElement.class);
+
+    private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
+
+    private static final Set<Service> REQUIRED_SERVICES = ImmutableSet.of(
+            Service.Connectivity,
+            Service.Dhcp
+    );
+    private static final Set<Service> NUAGE_ONLY_SERVICES = ImmutableSet.of(
+            Service.SourceNat,
+            Service.StaticNat,
+            Service.Gateway
+    );
+    private static final Set<Service> UNSUPPORTED_SERVICES = ImmutableSet.of(
+            Service.Vpn,
+            Service.Dns,
+            Service.PortForwarding,
+            Service.SecurityGroup
+    );
+    private static final Set<Pair<Service, Service>> ANY_REQUIRED_SERVICES = ImmutableSet.of(
+            new Pair<>(Service.SourceNat, Service.StaticNat)
+    );
+
+
+    public static final ExternalNetworkDeviceManager.NetworkDevice NuageVspDevice = new ExternalNetworkDeviceManager.NetworkDevice("NuageVsp", Provider.NuageVsp.getName());
+
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    VlanDetailsDao _vlanDetailsDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    VpcOfferingServiceMapDao _vpcOfferingSrvcDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    NetworkOfferingDao _ntwkOfferingDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    NuageVspManager _nuageVspManager;
+    @Inject
+    FirewallRulesDao _firewallRulesDao;
+    @Inject
+    FirewallRulesCidrsDao _firewallRulesCidrsDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    NuageVspEntityBuilder _nuageVspEntityBuilder;
+    @Inject
+    VpcDetailsDao _vpcDetailsDao;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+
+    @Override
+    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> service) throws ResourceUnavailableException {
+        return false;
+    }
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        return capabilities;
+    }
+
+    private static Map<Service, Map<Capability, String>> setCapabilities() {
+        return ImmutableMap.<Service, Map<Capability, String>>builder()
+            .put(Service.Connectivity, ImmutableMap.of(
+                    Capability.NoVlan, "",
+                    Capability.PublicAccess, ""
+            ))
+            .put(Service.Gateway, ImmutableMap.<Capability, String>of())
+            .put(Service.SourceNat, ImmutableMap.of(
+                    Capability.SupportedSourceNatTypes, "perzone",
+                    Capability.RedundantRouter, "false"
+            ))
+            .put(Service.StaticNat, ImmutableMap.<Capability, String>of())
+            .put(Service.SecurityGroup, ImmutableMap.<Capability, String>of())
+            .put(Service.Firewall, ImmutableMap.of(
+                    Capability.TrafficStatistics, "per public ip",
+                    Capability.SupportedProtocols, "tcp,udp,icmp",
+                    Capability.SupportedEgressProtocols, "tcp,udp,icmp, all",
+                    Capability.SupportedTrafficDirection, "ingress, egress",
+                    Capability.MultipleIps, "true"
+            ))
+            .put(Service.Dhcp, ImmutableMap.of(
+                    Capability.DhcpAccrossMultipleSubnets, "true",
+                    Capability.ExtraDhcpOptions, "true"
+            ))
+            .put(Service.NetworkACL, ImmutableMap.of(
+                    Capability.SupportedProtocols, "tcp,udp,icmp"
+            ))
+            .build();
+    }
+
+    @Override
+    public Provider getProvider() {
+        return Provider.NuageVsp;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        _resourceMgr.registerResourceStateAdapter(name, this);
+        return true;
+    }
+
+    @Override
+    public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+            ResourceUnavailableException, InsufficientCapacityException {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Entering NuageElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")");
+        }
+
+        if (network.getVpcId() != null) {
+            return applyACLRulesForVpc(network, offering);
+        }
+
+        if (!canHandle(network, offering, Service.Connectivity)) {
+            return false;
+        }
+
+        if (network.getBroadcastUri() == null) {
+            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
+            return false;
+        }
+
+        _nuageVspManager.updateBroadcastUri(network);
+        network = _networkDao.findById(network.getId());
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+        List<VspAclRule> ingressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Ingress);
+        List<VspAclRule> egressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Egress);
+
+        List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(network.getId());
+        List<String> floatingIpUuids = new ArrayList<String>();
+        for (IPAddressVO ip : ips) {
+            floatingIpUuids.add(ip.getUuid());
+        }
+        VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering);
+        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
+        ImplementVspCommand cmd = new ImplementVspCommand(vspNetwork, ingressFirewallRules, egressFirewallRules, floatingIpUuids, vspDhcpOptions);
+        send(cmd, network);
+
+        return true;
+    }
+
+    private void send(Command cmd, Network network)
+            throws ResourceUnavailableException {
+        send(cmd, network.getPhysicalNetworkId(), Network.class, network);
+    }
+
+    private void send(Command cmd, Vpc vpc)
+            throws ResourceUnavailableException {
+        send(cmd, getPhysicalNetworkId(vpc.getZoneId()), Vpc.class, vpc);
+    }
+
+
+    private <R extends InternalIdentity> void send(Command cmd, long physicalNetworkId, Class<R> resourceClass,
+            R resource)
+            throws ResourceUnavailableException {
+        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
+        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+        if (isFailure(answer)) {
+            s_logger.error(cmd.getClass().getName() + " for " + resourceClass.getName() + " " + resource.getId() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+            if (hasFailureDetails(answer)) {
+                throw new ResourceUnavailableException(answer.getDetails(), resourceClass, resource.getId());
+            }
+        }
+    }
+
+    private boolean hasFailureDetails(Answer answer) {
+        return (null != answer) && (null != answer.getDetails());
+    }
+
+    private boolean isFailure(Answer answer) {
+        return answer == null || !answer.getResult();
+    }
+
+    private boolean applyACLRulesForVpc(Network network, NetworkOffering offering) throws ResourceUnavailableException {
+        List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(network.getNetworkACLId());
+        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.NetworkACL)) {
+            applyACLRules(network, rules, true, false);
+        }
+        return true;
+    }
+
+    private List<VspAclRule> getFirewallRulesToApply(final Network network, FirewallRule.TrafficType trafficType) {
+        List<FirewallRuleVO> firewallRulesToApply = _firewallRulesDao.listByNetworkPurposeTrafficType(network.getId(), FirewallRule.Purpose.Firewall, trafficType);
+        List<VspAclRule> vspAclRulesToApply = Lists.newArrayListWithExpectedSize(firewallRulesToApply.size());
+
+        for (FirewallRuleVO rule : firewallRulesToApply) {
+            rule.setSourceCidrList(_firewallRulesCidrsDao.getSourceCidrs(rule.getId()));
+            VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(rule, network);
+            vspAclRulesToApply.add(vspAclRule);
+        }
+        return vspAclRulesToApply;
+    }
+
+    @Override
+    public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+            ResourceUnavailableException, InsufficientCapacityException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+
+        if (network.getBroadcastUri() == null) {
+            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+
+        if (network.getBroadcastUri() == null) {
+            s_logger.error("Nic has no broadcast Uri with the virtual router IP");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+        if (cleanup && isDnsSupportedByVR(network)) {
+            // The network is restarted, possibly the domain name is changed, update the dhcpOptions as soon as possible
+            NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
+            VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO);
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+
+            ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions);
+            send(cmd, network);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean isReady(PhysicalNetworkServiceProvider provider) {
+        return true;
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        return true;
+    }
+
+    @Override
+    public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        return canHandle(network, Service.Connectivity);
+    }
+
+    @Override
+    public boolean verifyServicesCombination(Set<Service> services) {
+        Preconditions.checkNotNull(services);
+        final Sets.SetView<Service> missingServices = Sets.difference(REQUIRED_SERVICES, services);
+        final Sets.SetView<Service> unsupportedServices = Sets.intersection(UNSUPPORTED_SERVICES, services);
+        final Sets.SetView<Service> wantedServices = Sets.intersection(NUAGE_ONLY_SERVICES, new HashSet<>());
+
+        if (!missingServices.isEmpty()) {
+            throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " requires services: " + missingServices);
+        }
+
+        if (!unsupportedServices.isEmpty()) {
+            // NuageVsp doesn't implement any of these services.
+            // So if these services are requested, we can't handle it.
+            s_logger.debug("Unable to support services combination. The services " + unsupportedServices + " are not supported by Nuage VSP.");
+            return false;
+        }
+
+        if (!wantedServices.isEmpty()) {
+            throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " does not support services to be implemented by another provider: " + wantedServices);
+        }
+
+        return true;
+    }
+
+    protected boolean canHandle(Network network, Service service) {
+        NetworkOffering networkOffering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
+        return canHandle(network, networkOffering, service);
+    }
+
+    protected boolean canHandle(Network network, NetworkOffering networkOffering, Service service) {
+        if (network.getBroadcastDomainType() != Networks.BroadcastDomainType.Vsp) {
+            return false;
+        }
+
+        if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp is not a provider for network " + network.getDisplayText());
+            }
+            return false;
+        }
+
+        if (service != null) {
+            if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("NuageVsp can't provide the " + service.getName() + " service on network " + network.getDisplayText());
+                }
+                return false;
+            }
+        }
+
+        if (service != Service.Connectivity
+                && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
+            }
+            return false;
+        }
+
+        if (service != Service.SourceNat
+                && networkOffering.getGuestType() == Network.GuestType.Isolated
+                && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
+            }
+            return false;
+        }
+
+        if (networkOffering.isSpecifyVlan()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp doesn't support VLAN values for networks");
+            }
+            return false;
+        }
+
+        if (network.getVpcId() != null && !networkOffering.isPersistent()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent");
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+            InsufficientCapacityException, ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        return true;
+    }
+
+    private boolean isDnsSupportedByVR(Network network) {
+        return (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns) &&
+                ( _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns,  Provider.VirtualRouter) ||
+                  _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns,  Provider.VPCVirtualRouter)));
+    }
+
+    @Override
+    public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
+        if (network.isRollingRestart()) {
+            return true;
+        }
+
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
+        NicVO nic = _nicDao.findById(nicId);
+
+        ExtraDhcpOptionsVspCommand extraDhcpOptionsVspCommand = new ExtraDhcpOptionsVspCommand(vspNetwork, nic.getUuid(), dhcpOptions);
+        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), extraDhcpOptionsVspCommand);
+        if (isFailure(answer)) {
+            s_logger.error("[setExtraDhcpOptions] setting extra DHCP options for nic " + nic.getUuid() + " failed.");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) {
+        return false;
+    }
+
+    @Override
+    public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
+        List<VspStaticNat> vspStaticNatDetails = new ArrayList<VspStaticNat>();
+        for (StaticNat staticNat : rules) {
+            IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId());
+            VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId());
+            checkVlanUnderlayCompatibility(sourceNatVlan);
+
+            if (!staticNat.isForRevoke()) {
+                final List<FirewallRuleVO> firewallRules = _firewallRulesDao.listByIpAndNotRevoked(staticNat.getSourceIpAddressId());
+                for (FirewallRuleVO firewallRule : firewallRules) {
+                    _nuageVspEntityBuilder.buildVspAclRule(firewallRule, config, sourceNatIp);
+                }
+            }
+
+            NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId());
+            VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(staticNat.isForRevoke(), sourceNatIp, sourceNatVlan, nicVO);
+            vspStaticNatDetails.add(vspStaticNat);
+
+
+        }
+
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config);
+        ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails);
+        send(cmd,
+             config);
+
+        return true;
+    }
+
+    private void checkVlanUnderlayCompatibility(VlanVO newVlan) throws ResourceUnavailableException {
+        List<VlanVO> vlans = _vlanDao.listByZone(newVlan.getDataCenterId());
+        if (CollectionUtils.isNotEmpty(vlans)) {
+            boolean newVlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, newVlan);
+            final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(newVlan.getVlanGateway(), newVlan.getVlanNetmask());
+
+            for (VlanVO vlan : vlans) {
+                if (vlan.getId() == newVlan.getId()) continue;
+
+                final String existingCidr = NetUtils.getCidrFromGatewayAndNetmask(vlan.getVlanGateway(), vlan.getVlanNetmask());
+
+                NetUtils.SupersetOrSubset supersetOrSubset = NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(newCidr, existingCidr);
+                if (supersetOrSubset == NetUtils.SupersetOrSubset.sameSubnet) {
+                    boolean vlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan);
+                    if (newVlanUnderlay != vlanUnderlay) {
+                        throw new ResourceUnavailableException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported", Vlan.class, newVlan.getId());
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public IpDeployer getIpDeployer(Network network) {
+        return this;
+    }
+
+    @Override
+    public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
+        if (rules == null || rules.isEmpty()) {
+            return true;
+        }
+
+        if (rules.size() == 1 && rules.iterator().next().getType().equals(FirewallRuleType.System)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Default ACL added by CS as system is ignored for network " + network.getName() + " with rule " + rules);
+            }
+            return true;
+        }
+
+        s_logger.info("Applying " + rules.size() + " Firewall Rules for network " + network.getName());
+        return applyACLRules(network, rules, false, false);
+    }
+
+    protected boolean applyACLRules(final Network network, List<? extends InternalIdentity> rules, boolean isNetworkAcl, boolean networkReset)
+            throws ResourceUnavailableException {
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+        List<VspAclRule> vspAclRules = Lists.transform(rules, new Function<InternalIdentity, VspAclRule>() {
+            @Nullable
+            @Override
+            public VspAclRule apply(@Nullable InternalIdentity input) {
+                if (input instanceof FirewallRule) {
+                    return _nuageVspEntityBuilder.buildVspAclRule((FirewallRule) input, network);
+                }
+                return _nuageVspEntityBuilder.buildVspAclRule((NetworkACLItem) input);
+            }
+        });
+
+        VspAclRule.ACLType vspAclType = isNetworkAcl ? VspAclRule.ACLType.NetworkACL : VspAclRule.ACLType.Firewall;
+        ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(vspAclType, vspNetwork, vspAclRules, networkReset);
+        send(cmd,
+             network);
+        return true;
+    }
+
+    @Override
+    public boolean applyNetworkACLs(Network config, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
+        if (rules == null || rules.isEmpty()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("No rules to apply. So, delete all the existing ACL in VSP from Subnet with uuid " + config.getUuid());
+            }
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("New rules has to applied. So, delete all the existing ACL in VSP from Subnet with uuid " + config.getUuid());
+            }
+        }
+        if (rules != null) {
+            s_logger.info("Applying " + rules.size() + " Network ACLs for network " + config.getName());
+            applyACLRules(config, rules, true, rules.isEmpty());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        List<VpcOfferingServiceMapVO> vpcOfferingServices = _vpcOfferingSrvcDao.listByVpcOffId(vpc.getVpcOfferingId());
+        Multimap<Service, Provider> supportedVpcServices = NuageVspManagerImpl.SUPPORTED_NUAGE_VSP_VPC_SERVICE_MAP;
+        for (VpcOfferingServiceMapVO vpcOfferingService : vpcOfferingServices) {
+            Network.Service service = Network.Service.getService(vpcOfferingService.getService());
+            if (!supportedVpcServices.containsKey(service)) {
+                s_logger.warn(String.format("NuageVsp doesn't support service %s for VPCs", service.getName()));
+                return false;
+            }
+
+            Network.Provider provider = Network.Provider.getProvider(vpcOfferingService.getProvider());
+            if (!supportedVpcServices.containsEntry(service, provider)) {
+                s_logger.warn(String.format("NuageVsp doesn't support provider %s for service %s for VPCs", provider.getName(), service.getName()));
+                return false;
+            }
+        }
+
+        String globalDomainTemplate = _nuageVspManager.NuageVspVpcDomainTemplateName.value();
+        if (StringUtils.isNotBlank(globalDomainTemplate) && !_nuageVspManager.checkIfDomainTemplateExist(vpc.getDomainId(),globalDomainTemplate,vpc.getZoneId(),null)) {
+            s_logger.warn("The global pre configured domain template does not exist on the VSD.");
+            throw new CloudRuntimeException("The global pre configured domain template does not exist on the VSD.");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        if (vpc.getState().equals(Vpc.State.Inactive)) {
+            List<DomainRouterVO> routers = _routerDao.listByVpcId(vpc.getId());
+            if (CollectionUtils.isEmpty(routers)) {
+                routers = _routerDao.listIncludingRemovedByVpcId(vpc.getId());
+            }
+
+            List<String> domainRouterUuids = Lists.transform(routers, new Function<DomainRouterVO, String>() {
+                @Nullable
+                @Override
+                public String apply(@Nullable DomainRouterVO input) {
+                    return input != null ? input.getUuid() : null;
+                }
+            });
+
+            Domain vpcDomain = _domainDao.findById(vpc.getDomainId());
+
+            String preConfiguredDomainTemplateName;
+            VpcDetailVO domainTemplateNameDetail = _vpcDetailsDao.findDetail(vpc.getId(), NuageVspManager.nuageDomainTemplateDetailName);
+            if (domainTemplateNameDetail != null) {
+                preConfiguredDomainTemplateName = domainTemplateNameDetail.getValue();
+            } else {
+                preConfiguredDomainTemplateName = _configDao.getValue(NuageVspManager.NuageVspVpcDomainTemplateName.key());
+            }
+
+            Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpc.getId(), false);
+
+            cleanUpVpcCaching(vpc.getId());
+            //related to migration caching
+            List<? extends ResourceTag> vpcResourceDetails = _resourceTagDao.listByResourceUuid(vpc.getUuid());
+            if (vpcResourceDetails != null) {
+                vpcResourceDetails.stream()
+                                  .filter(item -> item.getKey().equals(NetworkMigrationManager.MIGRATION))
+                                  .findFirst()
+                                  .map(ResourceTag::getResourceId)
+                                  .ifPresent(this::cleanUpVpcCaching);
+            }
+
+            ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids, vpcDetails);
+            send(cmd, vpc);
+        }
+        return true;
+    }
+
+    private void cleanUpVpcCaching(long vpcId) {
+        _vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
+        _vpcDetailsDao.removeDetail(vpcId, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
+    }
+
+    private Long getPhysicalNetworkId(Long zoneId) {
+        Long guestPhysicalNetworkId = 0L;
+        List<PhysicalNetworkVO> physicalNetworkList = _physicalNetworkDao.listByZone(zoneId);
+        for (PhysicalNetworkVO phyNtwk : physicalNetworkList) {
+            if (phyNtwk.getIsolationMethods().contains("VSP")) {
+                guestPhysicalNetworkId = phyNtwk.getId();
+                break;
+            }
+        }
+        return guestPhysicalNetworkId;
+    }
+
+    @Override
+    public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException {
+        return false;
+    }
+
+    @Override
+    public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException {
+        return false;
+    }
+
+    @Override
+    public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
+        return false;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        return null;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        if (!(startup[0] instanceof StartupVspCommand)) {
+            return null;
+        }
+        host.setType(Host.Type.L2Networking);
+        return host;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (!(host.getType() == Host.Type.L2Networking)) {
+            return null;
+        }
+        return new DeleteHostAnswer(true);
+    }
+}
\ No newline at end of file
diff --git a/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/guru/NuageVspGuestNetworkGuru.java
new file mode 100644
index 0000000..00b1283
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/guru/NuageVspGuestNetworkGuru.java
@@ -0,0 +1,874 @@
+//
+// 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.network.guru;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
+import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
+import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
+import net.nuage.vsp.acs.client.api.model.VspDomain;
+import net.nuage.vsp.acs.client.api.model.VspNetwork;
+import net.nuage.vsp.acs.client.api.model.VspNic;
+import net.nuage.vsp.acs.client.api.model.VspStaticNat;
+import net.nuage.vsp.acs.client.api.model.VspVm;
+
+import org.apache.log4j.Logger;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.resourcedetail.VpcDetailVO;
+import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.guru.DeallocateVmVspCommand;
+import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
+import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
+import com.cloud.agent.api.guru.TrashNetworkVspCommand;
+import com.cloud.agent.api.guru.UpdateDhcpOptionVspCommand;
+import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterDetailVO;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDetailsDao;
+import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.HostVO;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.util.NuageVspEntityBuilder;
+import com.cloud.util.NuageVspUtil;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions {
+    public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class);
+
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    NetworkOfferingDao _ntwkOfferingDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    NuageVspManager _nuageVspManager;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NuageVspEntityBuilder _nuageVspEntityBuilder;
+    @Inject
+    NetworkDetailsDao _networkDetailsDao;
+    @Inject
+    VpcDetailsDao _vpcDetailsDao;
+    @Inject
+    NetworkOrchestrationService _networkOrchestrationService;
+    @Inject
+    DataCenterDetailsDao _dcDetailsDao;
+    @Inject
+    VlanDetailsDao _vlanDetailsDao;
+    @Inject
+    private DomainRouterDao _routerDao;
+
+    public NuageVspGuestNetworkGuru() {
+        super();
+        _isolationMethods = new IsolationMethod[] {new IsolationMethod("VSP")};
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Refusing to design network using network offering " +  offering.getId() + (physnet != null ? " on physical network " + physnet.getId() : ""));
+            }
+            return null;
+        }
+
+        NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
+        if (networkObject == null) {
+            return null;
+        }
+
+        networkObject.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
+
+        if (userSpecified instanceof NetworkVO && userSpecified.getExternalId() != null) {
+            if (owner.getType() < Account.ACCOUNT_TYPE_ADMIN) {
+                throw new IllegalArgumentException("vsdManaged networks are only useable by admins.");
+            }
+
+            if (!isUniqueReference(plan.getDataCenterId(), userSpecified.getExternalId())) {
+                s_logger.debug("Refusing to design network. VsdManaged network object already present in zone.");
+                return null;
+            }
+        }
+
+        return networkObject;
+    }
+
+    private boolean isUniqueReference(long dataCenterId, String vsdSubnetId) {
+        DataCenterDetailVO detail = _dcDetailsDao.findDetail(dataCenterId, vsdSubnetId);
+        return detail == null;
+    }
+
+    private boolean isVsdManagedVpc(long vpcId) {
+        //Check if it's a vpc and if the vpc is already vsdManaged OR if it has 0 tiers
+        Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
+        return vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED) != null && vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED).equals("true");
+    }
+
+    /** In case an externalId is specified, we get called here, and store the id the same way as cached data */
+    @Override
+    public void finalizeNetworkDesign(long networkId, String vlanIdAsUUID) {
+        NetworkVO designedNetwork = _networkDao.findById(networkId);
+        String externalId = designedNetwork.getExternalId();
+        boolean isVpc = designedNetwork.getVpcId() != null;
+
+        if (isVpc && _networkDao.listByVpc(designedNetwork.getVpcId()).size() > 1) {
+            boolean isVsdManagedVpc = isVsdManagedVpc(designedNetwork.getVpcId());
+            if (isVsdManagedVpc && externalId == null) {
+                throw new CloudRuntimeException("Refusing to design network. Network is vsdManaged but is part of a non vsd managed vpc.");
+            } else if (!isVsdManagedVpc && externalId != null) {
+                throw new CloudRuntimeException("Refusing to design network. Network is not vsdManaged but is part of a vsd managed vpc.");
+            }
+        }
+
+        if (externalId == null) {
+            return;
+        }
+
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(designedNetwork, externalId);
+        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(designedNetwork.getPhysicalNetworkId());
+
+        ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, null, true);
+        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+        if (answer == null || !answer.getResult()) {
+            s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+            if ((null != answer) && (null != answer.getDetails())) {
+                s_logger.error(answer.getDetails());
+            }
+            throw new CloudRuntimeException("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+        }
+
+        //check if the network does not violate the uuid cidr
+        ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
+        VspNetwork updatedVspNetwork = implementAnswer.getVspNetwork();
+        NetworkVO forUpdate = _networkDao.createForUpdate(networkId);
+
+        if (isVpc && (!designedNetwork.getCidr().equals(updatedVspNetwork.getCidr()) || !designedNetwork.getGateway().equals(updatedVspNetwork.getGateway()))) {
+         throw new CloudRuntimeException("Tier network does not match the VsdManaged subnet cidr or gateway.");
+        } else {
+            forUpdate.setCidr(updatedVspNetwork.getCidr());
+            forUpdate.setGateway(updatedVspNetwork.getGateway());
+        }
+
+        saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), designedNetwork.getVpcId());
+        saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, externalId);
+        saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
+
+        forUpdate.setState(State.Allocated);
+        _networkDao.update(networkId, forUpdate);
+    }
+
+    @Override
+    public Map<String, ? extends Object> listAdditionalNicParams(String nicUuid) {
+        return null;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException {
+        long networkId = network.getId();
+        network = _networkDao.acquireInLockTable(network.getId(), 1200);
+        if (network == null) {
+            throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
+        }
+
+        /* Check if an acl template is used in combination with a pre-configured DT. -> show an error if there is
+        Rollback of the network fails in core CS -> networkOrchestrator. */
+        if(network.getVpcId() != null) {
+            VpcDetailVO detail = _vpcDetailsDao.findDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName);
+            if (detail != null && network.getNetworkACLId() != null) {
+                s_logger.error("Pre-configured DT are used in combination with ACL lists. Which is not supported.");
+                throw new IllegalArgumentException("CloudStack ACLs are not supported with Nuage Pre-configured Domain Template");
+            }
+
+            if(detail != null && !_nuageVspManager.checkIfDomainTemplateExist(network.getDomainId(),detail.getValue(),network.getDataCenterId(),null)){
+                s_logger.error("The provided domain template does not exist on the VSD.");
+                throw new IllegalArgumentException("The provided domain template does not exist on the VSD anymore.");
+            }
+        }
+
+        NetworkVO implemented = null;
+        try {
+            if (offering.getGuestType() == GuestType.Isolated && network.getState() != State.Implementing) {
+                throw new IllegalStateException("Network " + networkId + " is not in expected state Implementing, but is in state " + network.getState());
+            }
+
+            //Get the Account details and find the type
+            AccountVO networksAccount = _accountDao.findById(network.getAccountId());
+            if (networksAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                String errorMessage = "Networks created by account " + networksAccount.getAccountName() + " of type Project (" + Account.ACCOUNT_TYPE_PROJECT + ") " +
+                        "are not yet supported by NuageVsp provider";
+                s_logger.error(errorMessage);
+                throw new InsufficientVirtualNetworkCapacityException(errorMessage, Account.class, network.getAccountId());
+            }
+
+            //We don't support a shared network with UserData and multiple IP ranges at the same time.
+            checkMultipleSubnetsCombinedWithUseData(network);
+
+            long dcId = dest.getDataCenter().getId();
+            //Get physical network id
+            Long physicalNetworkId = network.getPhysicalNetworkId();
+            //Physical network id can be null in Guest Network in Basic zone, so locate the physical network
+            if (physicalNetworkId == null) {
+                physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
+            }
+
+            implemented = new NetworkVO(network.getId(), network, network.getNetworkOfferingId(), network.getGuruName(), network.getDomainId(), network.getAccountId(),
+                    network.getRelated(), network.getName(), network.getDisplayText(), network.getNetworkDomain(), network.getGuestType(), network.getDataCenterId(),
+                    physicalNetworkId, network.getAclType(), network.getSpecifyIpRanges(), network.getVpcId(), offering.isRedundantRouter(), network.getExternalId());
+            implemented.setUuid(network.getUuid());
+            implemented.setState(State.Allocated);
+            if (network.getGateway() != null) {
+                implemented.setGateway(network.getGateway());
+            }
+            if (network.getCidr() != null) {
+                implemented.setCidr(network.getCidr());
+            }
+
+            implemented.setBroadcastUri(_nuageVspManager.calculateBroadcastUri(implemented));
+            implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented);
+
+            if (vspNetwork.isShared()) {
+                Boolean previousUnderlay= null;
+                for (VlanVO vlan : _vlanDao.listVlansByNetworkId(networkId)) {
+                    boolean underlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan);
+                    if (previousUnderlay == null || underlay == previousUnderlay) {
+                        previousUnderlay = underlay;
+                    } else {
+                        throw new CloudRuntimeException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported");
+                    }
+                }
+                if (previousUnderlay != null) {
+                    vspNetwork = new VspNetwork.Builder().fromObject(vspNetwork)
+                            .vlanUnderlay(previousUnderlay)
+                            .build();
+                }
+            }
+
+            boolean implementSucceeded = implement(network.getVpcId(), physicalNetworkId, vspNetwork, implemented, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering));
+
+            if (!implementSucceeded) {
+                return null;
+            }
+
+            if (StringUtils.isNotBlank(vspNetwork.getDomainTemplateName())) {
+                if (network.getVpcId() != null) {
+                    saveVpcDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
+                } else {
+                    saveNetworkDetail(implemented.getId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
+                }
+            }
+
+            String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId();
+            s_logger.info("Implemented OK, network " + implemented.getUuid() + " in tenant " + tenantId + " linked to " + implemented.getBroadcastUri());
+        } finally {
+            _networkDao.releaseFromLockTable(network.getId());
+        }
+        return implemented;
+    }
+
+    private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, NetworkVO implemented, VspDhcpDomainOption vspDhcpDomainOption) {
+        HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
+        final boolean isVsdManaged = vspNetwork.getNetworkRelatedVsdIds()
+                                          .getVsdSubnetId()
+                                          .isPresent();
+        if (isVsdManaged) {
+            //Implement cmd was already send in design step.
+            _dcDetailsDao.persist(implemented.getDataCenterId(), vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().orElseThrow(() -> new CloudRuntimeException("Managed but no subnetId. How can this happen?")), implemented.getUuid());
+            return true;
+        }
+
+        ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption, false);
+        Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+        if (answer == null || !answer.getResult()) {
+            s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+            if ((null != answer) && (null != answer.getDetails())) {
+                s_logger.error(answer.getDetails());
+            }
+            return false;
+        }
+
+        ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
+        saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), vpcId);
+        return true;
+    }
+
+    private void saveNetworkAndVpcDetails(VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds, Long vpcId) {
+        if (!vspNetwork.isShared() && !vspNetwork.getNetworkRelatedVsdIds().equals(networkRelatedVsdIds)) {
+            Map<String, String> networkDetails = constructNetworkDetails(networkRelatedVsdIds, vspNetwork.isVpc());
+
+            long networkId = vspNetwork.getId();
+
+            for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
+                saveNetworkDetail(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue());
+            }
+
+            if(vspNetwork.isVpc()) {
+                Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);
+
+                for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
+                    saveVpcDetail(vpcId, vpcDetail.getKey(), vpcDetail.getValue());
+                }
+            }
+        }
+    }
+
+    private void saveVpcDetail(Long vpcId, String key, String value) {
+        _vpcDetailsDao.addDetail(vpcId, key, value, false);
+    }
+
+    private void saveNetworkDetail(long networkId, String key, String value) {
+         _networkDetailsDao.addDetail(networkId, key, value, false);
+    }
+
+    private static Map<String, String> constructNetworkDetails(NetworkRelatedVsdIds networkRelatedVsdIds, boolean isVpc) {
+        Map<String, String> networkDetails = Maps.newHashMap();
+
+        if (!isVpc) {
+            networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
+            networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
+        }
+        networkRelatedVsdIds.getVsdSubnetId().ifPresent(v ->  networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, v));
+
+        return networkDetails;
+    }
+
+    private static Map<String, String> constructVpcDetails(NetworkRelatedVsdIds networkRelatedVsdIds) {
+        Map<String, String> vpcDetails = Maps.newHashMap();
+
+        networkRelatedVsdIds.getVsdDomainId().ifPresent(v ->  vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
+        networkRelatedVsdIds.getVsdZoneId().ifPresent(v ->  vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
+        if (networkRelatedVsdIds.isVsdManaged()) {
+            vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
+        }
+
+        return vpcDetails;
+    }
+
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        if (vm.getType() != VirtualMachine.Type.DomainRouter && _nuageVspEntityBuilder.usesVirtualRouter(network.getNetworkOfferingId())) {
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+            if (nic != null && nic.getRequestedIPv4() != null && nic.getRequestedIPv4().equals(vspNetwork.getVirtualRouterIp())) {
+                DataCenter dc = _dcDao.findById(network.getDataCenterId());
+                s_logger.error("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved for the VR in network " + network);
+                throw new InsufficientVirtualNetworkCapacityException("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved " +
+                        "for the VR in network " + network, DataCenter.class,dc.getId());
+            }
+        }
+
+        return super.allocate(network, nic, vm);
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        boolean lockedNetwork = lockNetworkForUserVm(network, vm);
+        if (lockedNetwork && s_logger.isDebugEnabled()) {
+            s_logger.debug("Locked network " + network.getId() + " for creation of user VM " + vm.getInstanceName());
+        }
+
+        try {
+            //We don't support a shared network with UserData and multiple IP ranges at the same time.
+            checkMultipleSubnetsCombinedWithUseData(network);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Handling reserve() call back to with Create a new VM or add an interface to existing VM in network " + network.getName());
+            }
+
+            DataCenter dc = _dcDao.findById(network.getDataCenterId());
+            AccountVO neworkAccountDetails = _accountDao.findById(network.getAccountId());
+            if (neworkAccountDetails.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                throw new InsufficientVirtualNetworkCapacityException("CS project support is not yet implemented in NuageVsp", DataCenter.class, dc.getId());
+            }
+
+            if (Strings.isNullOrEmpty(network.getBroadcastUri().getPath()) || !network.getBroadcastUri().getPath().startsWith("/")) {
+                throw new IllegalStateException("The broadcast URI path " + network.getBroadcastUri() + " is empty or in an incorrect format.");
+            }
+
+            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network);
+
+            boolean vrAddedToNuage = vm.getType() == VirtualMachine.Type.DomainRouter && vspNetwork.getVirtualRouterIp()
+                                                                                          .equals("null");
+            if (vrAddedToNuage) {
+                //In case a VR is added due to upgrade network offering - recalculate the broadcast uri before using it.
+                _nuageVspManager.updateBroadcastUri(network);
+                network = _networkDao.findById(network.getId());
+                vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network, null);
+            }
+
+            if (vspNetwork.isShared()) {
+                vspNetwork = _nuageVspEntityBuilder.updateVspNetworkByPublicIp(vspNetwork, network, nic.getIPv4Address());
+
+                if (VirtualMachine.Type.DomainRouter.equals(vm.getType()) && !nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
+                    if(s_logger.isDebugEnabled()) {
+                        s_logger.debug("VR got spawned with a different IP, releasing the previously allocated public IP " + nic.getIPv4Address());
+                    }
+                    IPAddressVO oldIpAddress = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address());
+                    _ipAddressDao.unassignIpAddress(oldIpAddress.getId());
+                    _ipAddressDao.mark(network.getDataCenterId(), new Ip(vspNetwork.getVirtualRouterIp()));
+                } else if (VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
+                    s_logger.error("Deploying a user VM with the same IP as the VR is not allowed.");
+                    throw new InsufficientVirtualNetworkCapacityException("Deploying a user VM with the same IP " + nic.getIPv4Address() + " as the VR is not allowed.",
+                            Network.class, network.getId());
+                }
+
+                // Make sure the shared network is present
+                NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
+                if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, null, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
+                    s_logger.error("Failed to implement shared network " + network.getUuid() + " under domain " + context.getDomain().getUuid());
+                    throw new InsufficientVirtualNetworkCapacityException("Failed to implement shared network " + network.getUuid() + " under domain " +
+                            context.getDomain().getUuid(), Network.class, network.getId());
+                }
+            }
+
+            // Set flags for dhcp options
+            boolean networkHasDns = networkHasDns(network);
+
+            Map<Long, Boolean> networkHasDnsCache = Maps.newHashMap();
+            networkHasDnsCache.put(network.getId(), networkHasDns);
+
+            // Determine if dhcp options of the other nics in the network need to be updated
+            if (vm.getType() == VirtualMachine.Type.DomainRouter && network.getState() != State.Implementing) {
+                updateDhcpOptionsForExistingVms(network, nuageVspHost, vspNetwork, networkHasDns, networkHasDnsCache);
+                //update the extra DHCP options
+
+            }
+            // Update broadcast Uri to enable VR ip update
+            if (!network.getBroadcastUri().getPath().substring(1).equals(vspNetwork.getVirtualRouterIp())) {
+                NetworkVO networkToUpdate = _networkDao.findById(network.getId());
+                String broadcastUriStr = networkToUpdate.getUuid() + "/" + vspNetwork.getVirtualRouterIp();
+                networkToUpdate.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
+                _networkDao.update(network.getId(), networkToUpdate);
+                if (network instanceof NetworkVO) {
+                    ((NetworkVO) network).setBroadcastUri(networkToUpdate.getBroadcastUri());
+                }
+            }
+
+            nic.setBroadcastUri(network.getBroadcastUri());
+            nic.setIsolationUri(network.getBroadcastUri());
+
+            VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network);
+
+            if (vm.isRollingRestart()) {
+                ((NetworkVO)network).setRollingRestart(true);
+            } else {
+                //NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort
+                //that we create in VSP
+                NicVO nicFromDb = _nicDao.findById(nic.getId());
+                IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(network.getId(), vm.getId());
+                VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
+                VspStaticNat vspStaticNat = null;
+                if (staticNatIp != null) {
+                    VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
+                    vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(null, staticNatIp, staticNatVlan, vspNic);
+                }
+
+                boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, nicFromDb);
+                VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, defaultHasDns, networkHasDns);
+                ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, vspStaticNat, dhcpOption);
+                Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+
+                if (answer == null || !answer.getResult()) {
+                    s_logger.error("ReserveVmInterfaceNuageVspCommand failed for NIC " + nic.getId() + " attached to VM " + vm.getId() + " in network " + network.getId());
+                    if ((null != answer) && (null != answer.getDetails())) {
+                        s_logger.error(answer.getDetails());
+                    }
+                    throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
+                }
+            }
+
+            if (vspVm.getDomainRouter() == Boolean.TRUE) {
+                nic.setIPv4Address(vspVm.getDomainRouterIp());
+            }
+
+        } finally {
+            if (network != null && lockedNetwork) {
+                _networkDao.releaseFromLockTable(network.getId());
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unlocked network " + network.getId() + " for creation of user VM " + vm.getInstanceName());
+                }
+            }
+        }
+    }
+
+    private void updateExtraDhcpOptionsForExistingVm(Network network, Nic nic) {
+        _networkOrchestrationService.configureExtraDhcpOptions(network, nic.getId());
+    }
+
+    private void updateDhcpOptionsForExistingVms(Network network, HostVO nuageVspHost, VspNetwork vspNetwork, boolean networkHasDns, Map<Long, Boolean> networkHasDnsCache)
+            throws InsufficientVirtualNetworkCapacityException {
+        // Update dhcp options if a VR is added when we are not initiating the network
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug(String.format("DomainRouter is added to an existing network: %s in state: %s", network.getName(), network.getState()));
+        }
+
+        List<NicVO> userNics = _nicDao.listByNetworkId(network.getId());
+        LinkedListMultimap<Long, VspDhcpVMOption> dhcpOptionsPerDomain = LinkedListMultimap.create();
+
+        for (Iterator<NicVO> iterator = userNics.iterator(); iterator.hasNext(); ) {
+            NicVO userNic = iterator.next();
+            if (userNic.getVmType() == VirtualMachine.Type.DomainRouter || userNic.getState() != Nic.State.Reserved) {
+                iterator.remove();
+                continue;
+            }
+
+            VMInstanceVO userVm = _vmInstanceDao.findById(userNic.getInstanceId());
+            boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, userNic);
+            VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(userNic, defaultHasDns, networkHasDns);
+            dhcpOptionsPerDomain.put(userVm.getDomainId(), dhcpOption);
+        }
+
+        for (Long domainId : dhcpOptionsPerDomain.keySet()) {
+            VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(_domainDao.findById(domainId));
+            VspNetwork vspNetworkForDomain = new VspNetwork.Builder().fromObject(vspNetwork).domain(vspDomain).build();
+            List<VspDhcpVMOption> dhcpOptions = dhcpOptionsPerDomain.get(domainId);
+            UpdateDhcpOptionVspCommand cmd = new UpdateDhcpOptionVspCommand(dhcpOptions, vspNetworkForDomain);
+            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+
+            if (answer == null || !answer.getResult()) {
+                s_logger.error("UpdateDhcpOptionVspCommand failed at \"reserve\" for network " + vspNetwork.getName() + " under domain " + vspNetwork.getVspDomain().getName());
+                if ((null != answer) && (null != answer.getDetails())) {
+                    s_logger.error(answer.getDetails());
+                }
+                throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId());
+            }
+        }
+
+        for (NicVO userNic : userNics) {
+            updateExtraDhcpOptionsForExistingVm(network, userNic);
+        }
+    }
+
+
+    private boolean isServiceProvidedByVR(Network network, Network.Service service ) {
+        return (_networkModel.areServicesSupportedInNetwork(network.getId(), service) &&
+                ( _networkModel.isProviderSupportServiceInNetwork(network.getId(), service,  Network.Provider.VirtualRouter) ||
+                        _networkModel.isProviderSupportServiceInNetwork(network.getId(), service,  Network.Provider.VPCVirtualRouter)));
+    }
+
+    private void checkMultipleSubnetsCombinedWithUseData(Network network) {
+        if (isServiceProvidedByVR(network, Network.Service.UserData)) {
+            List<VlanVO> vlanVOs = _vlanDao.listVlansByNetworkId(network.getId());
+            if (vlanVOs.stream()
+                       .map(VlanVO::getVlanGateway)
+                       .distinct()
+                       .count() > 1) {
+                        s_logger.error("NuageVsp provider does not support multiple subnets in combination with user data. Network: " + network + ", vlans: " + vlanVOs);
+                        throw new UnsupportedServiceException("NuageVsp provider does not support multiple subnets in combination with user data.");
+            }
+        }
+    }
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+        if (networkType == NetworkType.Advanced
+                && isMyTrafficType(offering.getTrafficType())
+                && isMyIsolationMethod(physicalNetwork)
+                && (offering.getGuestType() == GuestType.Isolated || offering.getGuestType() == GuestType.Shared)
+                && hasRequiredServices(offering)) {
+            if (_configMgr.isOfferingForVpc(offering) && !offering.isPersistent()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent");
+                }
+                return false;
+            } else if (offering.getGuestType() == GuestType.Shared) {
+                List<String> supportedSharedNetworkServices = Lists.newArrayList(Network.Service.Connectivity.getName(), Network.Service.Dhcp.getName(), Network.Service.UserData.getName());
+                List<String> offeringServices = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(offering.getId());
+                if (!supportedSharedNetworkServices.containsAll(offeringServices)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("We only support " + Iterables.toString(supportedSharedNetworkServices) + " services for shared networks");
+                    }
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("We only take care of networks in zone of type " + NetworkType.Advanced + " without VLAN");
+            }
+            return false;
+        }
+    }
+
+    private boolean hasRequiredServices(NetworkOffering networkOffering) {
+        final Map<Network.Service, Set<Network.Provider>> serviceProviderMap = _networkModel.getNetworkOfferingServiceProvidersMap(networkOffering.getId());
+
+        if (!serviceProviderMap.get(Network.Service.Connectivity).contains(Network.Provider.NuageVsp)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
+            }
+            return false;
+        }
+
+        if (networkOffering.getGuestType() == GuestType.Isolated
+                && !serviceProviderMap.get(Network.Service.SourceNat).contains(Network.Provider.NuageVsp)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
+            }
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    @DB
+    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
+        boolean lockedNetwork = lockNetworkForUserVm(network, vm);
+        if (lockedNetwork && s_logger.isDebugEnabled()) {
+            s_logger.debug("Locked network " + network.getId() + " for deallocation of user VM " + vm.getInstanceName());
+        }
+
+        try {
+            final VirtualMachine virtualMachine = vm.getVirtualMachine();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Handling deallocate() call back, which is called when a VM is destroyed or interface is removed, " + "to delete VM Interface with IP "
+                        + nic.getIPv4Address() + " from a VM " + vm.getInstanceName() + " with state " + virtualMachine
+                                                                                                           .getState());
+            }
+
+            NicVO nicFromDb = _nicDao.findById(nic.getId());
+
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(virtualMachine
+                                                                             .getDomainId(), network);
+            VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(virtualMachine, network);
+            VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
+            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
+
+            DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(vspNetwork, vspVm, vspNic);
+            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+            if (answer == null || !answer.getResult()) {
+                s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+                if ((null != answer) && (null != answer.getDetails())) {
+                    s_logger.error(answer.getDetails());
+                }
+            }
+
+            // In case of shared network, when a User VM is spawned with the same IP as the VR, and it gets cleaned up, make sure we do not release the public IP
+            // because it is still allocated for the VR.
+            if (vspNetwork.isShared() && VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) {
+                nic.deallocate();
+            } else {
+                super.deallocate(network, nic, vm);
+            }
+
+            if (virtualMachine.getType() == VirtualMachine.Type.DomainRouter) {
+                final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
+                final DomainRouterVO otherRouter = routers.stream()
+                                                          .filter(r -> r.getId() != vm.getId())
+                                                          .findFirst()
+                                                          .orElse(null);
+
+                if (otherRouter != null) {
+                    nicFromDb = _nicDao.findByNtwkIdAndInstanceId(network.getId(), otherRouter.getId());
+                    vspVm = _nuageVspEntityBuilder.buildVspVm(otherRouter, network);
+                    vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb);
+
+                    VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(nicFromDb, false, false);
+                    ReserveVmInterfaceVspCommand reserveCmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, null, dhcpOption);
+
+                    answer = _agentMgr.easySend(nuageVspHost.getId(), reserveCmd);
+                    if (answer == null || !answer.getResult()) {
+                        s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
+                        if ((null != answer) && (null != answer.getDetails())) {
+                            s_logger.error(answer.getDetails());
+                        }
+                    }
+                }
+
+            }
+        } finally {
+            if (network != null && lockedNetwork) {
+                _networkDao.releaseFromLockTable(network.getId());
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unlocked network " + network.getId() + " for deallocation of user VM " + vm.getInstanceName());
+                }
+            }
+        }
+    }
+
+    private boolean lockNetworkForUserVm(Network network, VirtualMachineProfile vm) {
+        if (!vm.getVirtualMachine().getType().isUsedBySystem()) {
+            long networkId = network.getId();
+            network = _networkDao.acquireInLockTable(network.getId(), 1200);
+            if (network == null) {
+                throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+        super.shutdown(profile, offering);
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        long networkId = network.getId();
+        network = _networkDao.acquireInLockTable(networkId, 1200);
+        if (network == null) {
+            throw new ConcurrentOperationException("Unable to acquire lock on network " + networkId);
+        }
+
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP");
+            }
+
+            VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
+
+            boolean networkMigrationCopy = network.getRelated() != network.getId();
+
+            if (networkMigrationCopy) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Network " + network.getName() + " is a copy of a migrated network. Cleaning up network details of related network.");
+                }
+                cleanUpNetworkCaching(network.getRelated());
+            }
+            cleanUpNetworkCaching(network.getId());
+
+            //Clean up VSD managed subnet caching
+            if (vspNetwork.getNetworkRelatedVsdIds().isVsdManaged()) {
+                final long dataCenterId = network.getDataCenterId();
+                vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().ifPresent(subnetId -> {
+                    _dcDetailsDao.removeDetail(dataCenterId, subnetId);
+                });
+            }
+
+            HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
+            TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork);
+            Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
+            if (answer == null || !answer.getResult()) {
+                s_logger.error("TrashNetworkNuageVspCommand for network " + network.getUuid() + " failed");
+                if ((null != answer) && (null != answer.getDetails())) {
+                    s_logger.error(answer.getDetails());
+                }
+                return false;
+            }
+        } finally {
+            _networkDao.releaseFromLockTable(network.getId());
+        }
+        return super.trash(network, offering);
+    }
+
+    private void cleanUpNetworkCaching(long id) {
+        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
+        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
+        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID);
+        _networkDetailsDao.removeDetail(id, NuageVspManager.NETWORK_METADATA_VSD_MANAGED);
+    }
+
+    private boolean networkHasDns(Network network) {
+
+        if (network != null) {
+            List<String> dnsProviders = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(network.getNetworkOfferingId(), Network.Service.Dns);
+            return dnsProviders.contains(Network.Provider.VirtualRouter.getName())
+                || dnsProviders.contains(Network.Provider.VPCVirtualRouter.getName());
+
+        }
+
+        return false;
+    }
+
+    private boolean getDefaultHasDns(Map<Long, Boolean> cache, Nic nic) {
+        Long networkId = nic.isDefaultNic()
+                ? Long.valueOf(nic.getNetworkId())
+                : getDefaultNetwork(nic.getInstanceId());
+
+        Boolean hasDns = cache.computeIfAbsent(networkId, k -> networkHasDns(_networkDao.findById(networkId)));
+        return hasDns;
+    }
+
+    private Long getDefaultNetwork(long vmId) {
+        NicVO defaultNic = _nicDao.findDefaultNicForVM(vmId);
+        if (defaultNic != null) return defaultNic.getNetworkId();
+        return  null;
+    }
+}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/AbstractListener.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/AbstractListener.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/AbstractListener.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/AbstractListener.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/NuageVspManager.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/NuageVspManager.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/NuageVspManagerImpl.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/manager/NuageVspManagerImpl.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspRequestWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspRequestWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspRequestWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspRequestWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspResource.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspResource.java
new file mode 100644
index 0000000..74b9c1d
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspResource.java
@@ -0,0 +1,310 @@
+//
+// 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.network.resource;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import com.google.common.base.Strings;
+
+import net.nuage.vsp.acs.client.api.NuageVspAclClient;
+import net.nuage.vsp.acs.client.api.NuageVspApiClient;
+import net.nuage.vsp.acs.client.api.NuageVspElementClient;
+import net.nuage.vsp.acs.client.api.NuageVspGuruClient;
+import net.nuage.vsp.acs.client.api.NuageVspManagerClient;
+import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader;
+import net.nuage.vsp.acs.client.api.model.VspHost;
+import net.nuage.vsp.acs.client.common.RequestType;
+import net.nuage.vsp.acs.client.common.model.NuageVspEntity;
+import net.nuage.vsp.acs.client.exception.NuageVspException;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingNuageVspCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupVspCommand;
+import com.cloud.host.Host;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.mgmt.JmxUtil;
+
+public class NuageVspResource extends ManagerBase implements ServerResource, VspStatisticsMBean {
+    private static final Logger s_logger = Logger.getLogger(NuageVspResource.class);
+
+    private String _guid;
+    private String _zoneId;
+    private String _hostName;
+    private boolean _shouldAudit = true;
+
+    private VspHost _vspHost;
+
+    private static final String NUAGE_VSP_PLUGIN_ERROR_MESSAGE = "Nuage Vsp plugin client is not installed";
+    protected NuageVspPluginClientLoader _clientLoader;
+
+    public VspHost validate(Map<String, ?> params) throws ConfigurationException {
+        return validate(NuageVspResourceConfiguration.fromConfiguration(params));
+    }
+
+    public VspHost validate(NuageVspResourceConfiguration configuration) throws ConfigurationException {
+        configuration.validate();
+
+        VspHost newVspHost = configuration.buildVspHost();
+
+
+        if (!newVspHost.getApiVersion().isSupported()) {
+            s_logger.warn(String.format("[UPGRADE] API version %s of Nuage Vsp Device %s should be updated.", newVspHost.getApiVersion(), configuration.hostName()));
+        }
+
+        _guid = configuration.guid();
+        _zoneId = configuration.zoneId();
+        _hostName = configuration.hostName();
+        _name = configuration.name();
+
+        try {
+            final NuageVspPluginClientLoader clientLoader = getClientLoader(newVspHost);
+            clientLoader.getNuageVspApiClient().login();
+
+            _vspHost = newVspHost;
+            _clientLoader = clientLoader;
+        } catch (NuageVspException e) {
+            s_logger.error(e.getMessage(), e);
+            throw new CloudRuntimeException(e.getMessage(), e);
+        }
+
+        return _vspHost;
+    }
+
+    @Override
+    public long getVSDStatistics() {
+        return _clientLoader.getNuageVspStatistics().getVsdCount();
+    }
+
+
+    @Override
+    public long getVsdStatisticsByEntityType(String entity) {
+        try {
+            NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
+            return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity);
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    @Override
+    public long getVsdStatisticsByRequestType(String requestType) {
+        try {
+            RequestType requestTypeValue = RequestType.valueOf(requestType);
+            return _clientLoader.getNuageVspStatistics().getVsdCount(requestTypeValue);
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+
+    }
+
+    @Override
+    public long getVsdStatisticsByEntityAndRequestType(String entity, String requestType) {
+        try {
+            RequestType requestTypeValue = RequestType.valueOf(requestType);
+            NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
+            return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity, requestTypeValue);
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    private static Map<String, AtomicLong> convertHashMap(Map<RequestType, AtomicLong> map) {
+        return map.entrySet()
+                .stream()
+                .collect(Collectors.toMap(
+                        e -> e.getKey().toString(),
+                        Map.Entry::getValue)
+                );
+    }
+
+    @Override
+    public Map<String, Map<String, AtomicLong>> getVsdStatisticsReport() {
+       return _clientLoader.getNuageVspStatistics()
+                .getVsdCountReport()
+                .entrySet().stream()
+                .collect(Collectors.toMap(
+                        e -> e.getKey().toString(),
+                        e -> convertHashMap(e.getValue())
+                ));
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if(super.configure(name, params)) {
+            validate(params);
+        }
+        return true;
+    }
+
+    protected void login() throws ConfigurationException, NuageVspException {
+        getNuageVspApiClient().login();
+    }
+
+    protected NuageVspPluginClientLoader getClientLoader(VspHost vspHost) {
+        return NuageVspPluginClientLoader.getClientLoader(vspHost);
+    }
+
+    @Override
+    public boolean start() {
+        try {
+            JmxUtil.registerMBean("NuageVspResource", _name, new VspStatisticsMBeanImpl(this));
+        } catch (Exception e) {
+            s_logger.warn("Unable to initialize statistics Mbean", e);
+        }
+
+        return true;
+
+    }
+
+    @Override
+    public boolean stop() {
+
+        try {
+            JmxUtil.unregisterMBean("NuageVspResource", _name);
+        } catch (Exception e) {
+            s_logger.warn("Unable to stop NuageVspResource", e);
+        }
+
+        return true;
+    }
+
+    @Override
+    public Host.Type getType() {
+        return Host.Type.L2Networking;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        StartupVspCommand sc = new StartupVspCommand();
+        sc.setGuid(_guid);
+        sc.setName(_name);
+        sc.setDataCenter(_zoneId);
+        sc.setPod("");
+        sc.setPrivateIpAddress("");
+        sc.setStorageIpAddress("");
+        sc.setVersion(NuageVspResource.class.getPackage().getImplementationVersion());
+        return new StartupCommand[] {sc};
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        if (Strings.isNullOrEmpty(_vspHost.getRestRelativePath())) {
+            s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the relative path information");
+            _shouldAudit = true;
+            return null;
+        }
+
+        if (Strings.isNullOrEmpty(_vspHost.getCmsUserLogin()) || Strings.isNullOrEmpty(_vspHost.getCmsUserPassword())) {
+            s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the CMS user information");
+            _shouldAudit = true;
+            return null;
+        }
+
+        try {
+            login();
+        } catch (NuageVspException | ConfigurationException e) {
+            s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
+            _shouldAudit = true;
+            return null;
+        }
+        PingNuageVspCommand pingNuageVspCommand = new PingNuageVspCommand(Host.Type.L2Networking, id, _shouldAudit);
+        _shouldAudit = false;
+        return pingNuageVspCommand;
+    }
+
+    public boolean getStatus() {
+        try {
+            login();
+            return true;
+        } catch (NuageVspException | ConfigurationException e) {
+            s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
+            return false;
+        }
+    }
+
+    @Override
+    public Answer executeRequest(final Command cmd) {
+        final NuageVspRequestWrapper wrapper = NuageVspRequestWrapper.getInstance();
+        try {
+            return wrapper.execute(cmd, this);
+        } catch (final Exception e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Received unsupported command " + cmd.toString(), e);
+            }
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+    }
+
+    protected void assertNuageVspClientsLoaded() throws ConfigurationException {
+        if (_clientLoader == null) {
+            throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE);
+        }
+    }
+
+    public NuageVspApiClient getNuageVspApiClient() throws ConfigurationException {
+        assertNuageVspClientsLoaded();
+        return _clientLoader.getNuageVspApiClient();
+
+    }
+
+    public NuageVspGuruClient getNuageVspGuruClient() throws ConfigurationException {
+        assertNuageVspClientsLoaded();
+        return _clientLoader.getNuageVspGuruClient();
+    }
+
+    public NuageVspAclClient getNuageVspAclClient() throws ConfigurationException {
+        assertNuageVspClientsLoaded();
+        return _clientLoader.getNuageVspAclClient();
+    }
+
+    public NuageVspElementClient getNuageVspElementClient() throws ConfigurationException {
+        assertNuageVspClientsLoaded();
+        return _clientLoader.getNuageVspElementClient();
+    }
+
+    public NuageVspManagerClient getNuageVspManagerClient() throws ConfigurationException {
+        assertNuageVspClientsLoaded();
+        return _clientLoader.getNuageVspManagerClient();
+    }
+
+}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResourceConfiguration.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspResourceConfiguration.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResourceConfiguration.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/NuageVspResourceConfiguration.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/VspStatisticsMBean.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/VspStatisticsMBean.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/VspStatisticsMBean.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/VspStatisticsMBean.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/VspStatisticsMBeanImpl.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/VspStatisticsMBeanImpl.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/VspStatisticsMBeanImpl.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/resource/VspStatisticsMBeanImpl.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCheckHealthCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCheckHealthCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCheckHealthCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCheckHealthCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspExtraDhcpOptionsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspExtraDhcpOptionsCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspExtraDhcpOptionsCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspExtraDhcpOptionsCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspListDomainTemplatesCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java
diff --git a/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/util/NuageVspEntityBuilder.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/util/NuageVspEntityBuilder.java
new file mode 100644
index 0000000..c26b9ae
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/util/NuageVspEntityBuilder.java
@@ -0,0 +1,463 @@
+//
+// 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.util;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
+import net.nuage.vsp.acs.client.api.model.VspAclRule;
+import net.nuage.vsp.acs.client.api.model.VspAddressRange;
+import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
+import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
+import net.nuage.vsp.acs.client.api.model.VspDomain;
+import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp;
+import net.nuage.vsp.acs.client.api.model.VspNetwork;
+import net.nuage.vsp.acs.client.api.model.VspNic;
+import net.nuage.vsp.acs.client.api.model.VspStaticNat;
+import net.nuage.vsp.acs.client.api.model.VspVm;
+import net.nuage.vsp.acs.client.common.model.Pair;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
+
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class NuageVspEntityBuilder {
+    private static final Logger s_logger = Logger.getLogger(NuageVspEntityBuilder.class);
+
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    VlanDetailsDao _vlanDetailsDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    NetworkDetailsDao _networkDetailsDao;
+    @Inject
+    VpcDetailsDao _vpcDetailsDao;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    NuageVspManager _nuageVspManager;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+
+
+    public VspDomain buildVspDomain(Domain domain) {
+        return new VspDomain.Builder()
+                .uuid(domain.getUuid())
+                .name(domain.getName())
+                .path(domain.getPath())
+                .build();
+    }
+
+    public VspDomainCleanUp buildVspDomainCleanUp(Domain domain) {
+        VspDomainCleanUp.Builder vspDomainCleanUpBuilder = new VspDomainCleanUp.Builder().uuid(domain.getUuid());
+
+        Map<String, List<String>> sharedNetworkUuids = Maps.newHashMap();
+        List<NetworkVO> allSharedNetworks = _networkDao.listByGuestType(Network.GuestType.Shared);
+        for (NetworkVO sharedNetwork : allSharedNetworks) {
+            if (_networkModel.isNetworkAvailableInDomain(sharedNetwork.getId(), domain.getId())) {
+                String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(sharedNetwork);
+                if (!sharedNetworkUuids.containsKey(preConfiguredDomainTemplateName)) {
+                    sharedNetworkUuids.put(preConfiguredDomainTemplateName, Lists.<String>newArrayList());
+                }
+                sharedNetworkUuids.get(preConfiguredDomainTemplateName).add(sharedNetwork.getUuid());
+            }
+        }
+        vspDomainCleanUpBuilder.sharedNetworkUuids(sharedNetworkUuids);
+
+        return vspDomainCleanUpBuilder.build();
+    }
+
+    public VspNetwork buildVspNetwork(Network network) {
+        return buildVspNetwork(network.getDomainId(), network, null);
+    }
+
+    public VspNetwork buildVspNetwork(Network network, String vsdSubnetId) {
+        return buildVspNetwork(network.getDomainId(), network, vsdSubnetId);
+    }
+
+    public VspNetwork buildVspNetwork(long domainId, Network network) {
+        return buildVspNetwork(domainId, network, null);
+    }
+
+    public VspNetwork buildVspNetwork(long domainId, Network network, String vsdSubnetId) {
+        VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder()
+                .id(network.getId())
+                .uuid(network.getUuid())
+                .name(network.getName())
+                .cidr(network.getCidr())
+                .gateway(network.getGateway());
+
+        DomainVO domain = _domainDao.findById(domainId);
+        VspDomain vspDomain = buildVspDomain(domain);
+        vspNetworkBuilder.domain(vspDomain);
+
+
+        AccountVO account = _accountDao.findById(network.getAccountId());
+        if (account != null) {
+            vspNetworkBuilder.accountUuid(account.getUuid()).accountName(account.getAccountName());
+        }
+
+        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        vspNetworkBuilder.egressDefaultPolicy(networkOffering.isEgressDefaultPolicy())
+                         .publicAccess(networkOffering.isSupportingPublicAccess());
+
+        Map<String, String> networkDetails = _networkDetailsDao.listDetailsKeyPairs(network.getId(), false);
+
+        final NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder = new NetworkRelatedVsdIds.Builder();
+
+        if (MapUtils.isNotEmpty(networkDetails)) {
+            relatedVsdIdsBuilder.vsdSubnetId(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID))
+                                .withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
+        } else if (vsdSubnetId != null) {
+            relatedVsdIdsBuilder.vsdSubnetId(vsdSubnetId)
+                                .withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
+        }
+
+        if (network.getVpcId() != null) {
+            long vpcId = network.getVpcId();
+            VpcVO vpc = _vpcDao.findById(vpcId);
+            vspNetworkBuilder.vpcUuid(vpc.getUuid())
+                    .vpcName(vpc.getName())
+                    .networkType(VspNetwork.NetworkType.Vpc);
+            Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
+            applyDomainAndZoneId(relatedVsdIdsBuilder, vpcDetails);
+        } else {
+            applyDomainAndZoneId(relatedVsdIdsBuilder, networkDetails);
+
+            if (networkOffering.getGuestType() == Network.GuestType.Shared) {
+                List<VlanVO> vlans = _vlanDao.listVlansByNetworkIdIncludingRemoved(network.getId());
+                List<VspAddressRange> vspAddressRanges =
+                        vlans.stream()
+                             .map(vlan -> new VspAddressRange.Builder().gateway(vlan.getVlanGateway()).netmask(vlan.getVlanNetmask()).build())
+                             .collect(Collectors.toList());
+
+
+                vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared)
+                                 .addressRanges(vspAddressRanges);
+            } else if (_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.SourceNat)
+                    || _networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.StaticNat)) {
+                vspNetworkBuilder.networkType(VspNetwork.NetworkType.L3);
+            } else {
+                vspNetworkBuilder.networkType(VspNetwork.NetworkType.L2);
+            }
+
+        }
+
+        NetworkRelatedVsdIds networkRelatedVsdIds = relatedVsdIdsBuilder.build();
+        vspNetworkBuilder.networkRelatedVsdIds(networkRelatedVsdIds);
+
+        boolean firewallServiceSupported = _networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.Firewall);
+        vspNetworkBuilder.firewallServiceSupported(firewallServiceSupported);
+
+        String preConfiguredDomainTemplateName = _nuageVspManager.getPreConfiguredDomainTemplateName(network);
+        vspNetworkBuilder.domainTemplateName(preConfiguredDomainTemplateName);
+
+        if (usesVirtualRouter(networkOffering.getId())) {
+                String virtualRouterIp = getVirtualRouterIP(network);
+                vspNetworkBuilder.virtualRouterIp(virtualRouterIp);
+        }
+
+        return vspNetworkBuilder.build();
+    }
+
+    private void applyDomainAndZoneId(NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder, Map<String, String> details) {
+        if (MapUtils.isNotEmpty(details)) {
+            relatedVsdIdsBuilder
+                    .vsdDomainId(details.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID))
+                    .vsdZoneId(details.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID));
+        }
+    }
+
+    public boolean usesVirtualRouter(long networkOfferingId) {
+        return _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VirtualRouter) ||
+                _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VPCVirtualRouter);
+    }
+
+    public VspNetwork updateVspNetworkByPublicIp(VspNetwork vspNetwork, Network network, String publicIp) {
+        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
+        final long ip = NetUtils.ip2Long(publicIp);
+        VlanVO matchingVlan = vlans.stream()
+                                   .filter(vlan -> isVlanContainingIp(vlan, ip))
+                                   .findFirst()
+                                   .get();
+
+        boolean underlayEnabled = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, matchingVlan);
+        return new VspNetwork.Builder().fromObject(vspNetwork)
+                .gateway(matchingVlan.getVlanGateway())
+                .cidr(NetUtils.getCidrFromGatewayAndNetmask(matchingVlan.getVlanGateway(), matchingVlan.getVlanNetmask()))
+                .vlanUnderlay(underlayEnabled)
+                .build();
+    }
+
+    private boolean isVlanContainingIp(Vlan vlan, long ip) {
+        Pair<String, String> ipAddressRange =  NuageVspUtil.getIpAddressRange(vlan);
+        long startIp = NetUtils.ip2Long(ipAddressRange.getLeft());
+        long endIp = NetUtils.ip2Long(ipAddressRange.getRight());
+        return startIp <= ip && ip <= endIp;
+    }
+
+    private String getVirtualRouterIP(Network network) {
+        return network.getBroadcastUri() != null ? network.getBroadcastUri().getPath().substring(1) : null;
+    }
+
+
+    public VspVm buildVspVm(VirtualMachine vm, Network network) {
+        VspVm.Builder vspVmBuilder = new VspVm.Builder()
+                .uuid(vm.getUuid())
+                .name(vm.getInstanceName())
+                .state(getEnumValue(vm.getState(), VspVm.State.Unknown));
+
+        boolean isDomainRouter = vm.getType().equals(VirtualMachine.Type.DomainRouter);
+        vspVmBuilder.domainRouter(isDomainRouter);
+
+        if (network.getBroadcastUri() != null) {
+            String domainRouterIp = network.getBroadcastUri().getPath().substring(1);
+            vspVmBuilder.domainRouterIp(domainRouterIp);
+        }
+
+        return vspVmBuilder.build();
+    }
+
+    public VspNic buildVspNic(String nicUuid, NicProfile nicProfile) {
+        return buildVspNic(nicUuid, nicProfile.getMacAddress(), nicProfile.getIPv4Address(), nicProfile.getNetworkId(), null);
+    }
+
+    public VspNic buildVspNic(NicVO nic) {
+        return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), null);
+    }
+
+    public VspNic buildVspNic(NicVO nic, NicSecondaryIpVO nicSecondaryIp) {
+        return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), nicSecondaryIp);
+    }
+
+    private VspNic buildVspNic(String uuid, String macAddress, String ip, long networkId, NicSecondaryIpVO nicSecondaryIp) {
+        VspNic.Builder vspNicBuilder = new VspNic.Builder()
+                .uuid(uuid)
+                .macAddress(macAddress)
+                .useStaticIp(true)
+                .ip(ip);
+
+        if (nicSecondaryIp != null) {
+            vspNicBuilder.secondaryIpUuid(nicSecondaryIp.getUuid()).secondaryIpAddress(nicSecondaryIp.getIp4Address());
+        }
+
+        Network network = _networkDao.findById(networkId);
+        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+
+        return vspNicBuilder.build();
+    }
+
+    public VspStaticNat buildVspStaticNat(Boolean forRevoke, IPAddressVO staticNatIp, VlanVO staticNatVlan, VspNic vspNic) {
+        VspStaticNat.Builder vspStaticNatBuilder = new VspStaticNat.Builder()
+                .ipUuid(staticNatIp.getUuid())
+                .ipAddress(staticNatIp.getAddress().addr())
+                .revoke(forRevoke)
+                .oneToOneNat(staticNatIp.isOneToOneNat())
+                .state(getEnumValue(staticNatIp.getState(), VspStaticNat.State.class))
+                .vlanUuid(staticNatVlan.getUuid())
+                .vlanGateway(staticNatVlan.getVlanGateway())
+                .vlanNetmask(staticNatVlan.getVlanNetmask())
+                .vlanUnderlay(NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, staticNatVlan));
+
+        if (staticNatIp.getVmIp() != null) {
+            vspStaticNatBuilder.destinationIp(staticNatIp.getVmIp() + "/32");
+        }
+
+        if (vspNic != null) {
+            vspStaticNatBuilder.nic(vspNic);
+        }
+
+        return vspStaticNatBuilder.build();
+    }
+
+    public VspStaticNat buildVspStaticNat(Boolean forRevoke, IPAddressVO staticNatIp, VlanVO staticNatVlan, NicVO nic) {
+        NicSecondaryIpVO nicSecondaryIp = null;
+
+        if (nic == null && staticNatIp.getAssociatedWithVmId() != null && staticNatIp.getVmIp() != null) {
+            nicSecondaryIp = _nicSecondaryIpDao.findByIp4AddressAndInstanceId(staticNatIp.getAssociatedWithVmId(), staticNatIp.getVmIp());
+            if (nicSecondaryIp != null) {
+                nic = _nicDao.findById(nicSecondaryIp.getNicId());
+            }
+        }
+
+        VspNic vspNic = (nic != null) ? buildVspNic(nic, nicSecondaryIp) : null;
+        return buildVspStaticNat(forRevoke, staticNatIp, staticNatVlan, vspNic);
+    }
+
+    public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network) {
+        return buildVspAclRule(firewallRule, network, null);
+    }
+
+    public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network, IPAddressVO staticNat) {
+        VspAclRule.Builder vspAclRuleBuilder = new VspAclRule.Builder()
+                .uuid(firewallRule.getUuid())
+                .protocol(firewallRule.getProtocol())
+                .startPort(firewallRule.getSourcePortStart())
+                .endPort(firewallRule.getSourcePortEnd())
+                .sourceCidrList(firewallRule.getSourceCidrList())
+                .priority(-1)
+                .type(VspAclRule.ACLType.Firewall)
+                .state(getEnumValue(firewallRule.getState(), VspAclRule.ACLState.class))
+                .trafficType(getEnumValue(firewallRule.getTrafficType(), VspAclRule.ACLTrafficType.class));
+
+        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if (firewallRule.getTrafficType() == FirewallRule.TrafficType.Egress && networkOffering.isEgressDefaultPolicy()) {
+            vspAclRuleBuilder.deny();
+        } else {
+            vspAclRuleBuilder.allow();
+        }
+
+        if (staticNat == null && firewallRule.getSourceIpAddressId() != null) {
+            IPAddressVO staticNatIp = _ipAddressDao.findById(firewallRule.getSourceIpAddressId());
+
+            if (staticNatIp != null) {
+                VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
+                NicVO nic = _nicDao.findByIp4AddressAndNetworkId(staticNatIp.getVmIp(), staticNatIp.getAssociatedWithNetworkId());
+
+                vspAclRuleBuilder.staticNat(buildVspStaticNat(null, staticNatIp, staticNatVlan, nic));
+            }
+        }
+
+        return vspAclRuleBuilder.build();
+    }
+
+    public VspAclRule buildVspAclRule(NetworkACLItem networkAcl) {
+        return new VspAclRule.Builder()
+                .uuid(networkAcl.getUuid())
+                .protocol(networkAcl.getProtocol())
+                .startPort(networkAcl.getSourcePortStart())
+                .endPort(networkAcl.getSourcePortEnd())
+                .sourceIpAddress(null)
+                .sourceCidrList(networkAcl.getSourceCidrList())
+                .priority(networkAcl.getNumber())
+                .type(VspAclRule.ACLType.NetworkACL)
+                .state(getEnumValue(networkAcl.getState(), VspAclRule.ACLState.class))
+                .trafficType(getEnumValue(networkAcl.getTrafficType(), VspAclRule.ACLTrafficType.class))
+                .action(getEnumValue(networkAcl.getAction(), VspAclRule.ACLAction.class))
+                .build();
+    }
+
+    /** Build VspDhcpVMOption to put on the VM interface */
+    public VspDhcpVMOption buildVmDhcpOption (NicVO userNic, boolean defaultHasDns, boolean networkHasDns) {
+        VMInstanceVO userVm  = _vmInstanceDao.findById(userNic.getInstanceId());
+        VspDhcpVMOption.Builder vspDhcpVMOptionBuilder = new VspDhcpVMOption.Builder()
+                .nicUuid(userNic.getUuid())
+                .defaultHasDns(defaultHasDns)
+                .hostname(userVm.getHostName())
+                .networkHasDns(networkHasDns)
+                .isDefaultInterface(userNic.isDefaultNic())
+                .domainRouter(VirtualMachine.Type.DomainRouter.equals(userNic.getVmType()));
+        return vspDhcpVMOptionBuilder.build();
+    }
+
+    /** Build VspDhcpVMOption to put on the subnet */
+    public VspDhcpDomainOption buildNetworkDhcpOption(Network network, NetworkOffering offering) {
+        List<String> dnsProvider = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), Network.Service.Dns);
+        boolean isVrDnsProvider = dnsProvider.contains("VirtualRouter") || dnsProvider.contains("VpcVirtualRouter");
+        VspDhcpDomainOption.Builder vspDhcpDomainBuilder = new VspDhcpDomainOption.Builder()
+                .dnsServers(_nuageVspManager.getDnsDetails(network.getDataCenterId()))
+                .vrIsDnsProvider(isVrDnsProvider);
+
+        if (isVrDnsProvider) {
+            vspDhcpDomainBuilder.networkDomain(network.getVpcId() != null ? _vpcDao.findById(network.getVpcId()).getNetworkDomain() : network.getNetworkDomain());
+        }
+
+        return vspDhcpDomainBuilder.build();
+    }
+
+    private <E extends Enum<E>> E getEnumValue(Enum cloudstackValue, Class<E> target) {
+        try {
+            return Enum.valueOf(target, cloudstackValue.name());
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
+
+    private <E extends Enum<E>> E getEnumValue(Enum cloudstackValue, E defaultValue) {
+        try {
+            return Enum.valueOf(defaultValue.getDeclaringClass(), cloudstackValue.name());
+        } catch (IllegalArgumentException e) {
+            return defaultValue;
+        }
+    }
+}
diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java b/plugins/network-elements/nuage-vsp/src/main/java/com/cloud/util/NuageVspUtil.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java
rename to plugins/network-elements/nuage-vsp/src/main/java/com/cloud/util/NuageVspUtil.java
diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties b/plugins/network-elements/nuage-vsp/src/main/resources/META-INF/cloudstack/vsp/module.properties
similarity index 100%
rename from plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties
rename to plugins/network-elements/nuage-vsp/src/main/resources/META-INF/cloudstack/vsp/module.properties
diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml b/plugins/network-elements/nuage-vsp/src/main/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml
similarity index 100%
rename from plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml
rename to plugins/network-elements/nuage-vsp/src/main/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/NuageTest.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java
rename to plugins/network-elements/nuage-vsp/src/test/java/com/cloud/NuageTest.java
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/agent/api/CommandsTest.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java
rename to plugins/network-elements/nuage-vsp/src/test/java/com/cloud/agent/api/CommandsTest.java
diff --git a/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/element/NuageVspElementTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/element/NuageVspElementTest.java
new file mode 100644
index 0000000..da4312c
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/element/NuageVspElementTest.java
@@ -0,0 +1,382 @@
+//
+// 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.network.element;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import com.cloud.NuageTest;
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.CloudException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.NuageVspDeviceVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.NuageVspDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.util.NuageVspEntityBuilder;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class NuageVspElementTest extends NuageTest {
+
+    @InjectMocks
+    private NuageVspElement _nuageVspElement = new NuageVspElement();
+
+    @Mock private NetworkServiceMapDao _networkServiceMapDao;
+    @Mock private AgentManager _agentManager;
+    @Mock private HostDao _hostDao;
+    @Mock private NuageVspDao _nuageVspDao;
+    @Mock private DomainDao _domainDao;
+    @Mock private NetworkOfferingDao _networkOfferingDao;
+    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
+    @Mock private NuageVspManager _nuageVspManager;
+    @Mock private FirewallRulesDao _firewallRulesDao;
+    @Mock private IPAddressDao _ipAddressDao;
+    @Mock private PhysicalNetworkDao _physicalNetworkDao;
+    @Mock private NuageVspEntityBuilder _nuageVspEntityBuilder;
+    @Mock private VpcDetailsDao _vpcDetailsDao;
+    @Mock private DomainRouterDao _domainRouterDao;
+    @Mock private ResourceManager _resourceManager;
+    @Mock private ResourceTagDao _resourceTagDao;
+    @Mock private NetworkDao _networkDao;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        _nuageVspElement._nuageVspEntityBuilder = _nuageVspEntityBuilder;
+        _nuageVspElement._vpcDetailsDao = _vpcDetailsDao;
+        _nuageVspElement._routerDao = _domainRouterDao;
+        _nuageVspElement._networkDao = _networkDao;
+
+        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
+        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NuageVsp)).thenReturn(true);
+
+        _nuageVspElement.configure("NuageVspTestElement", Collections.<String, Object>emptyMap());
+    }
+
+    @Test
+    public void testCanHandle() {
+        final Network net = mock(Network.class);
+        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
+        when(net.getId()).thenReturn(NETWORK_ID);
+        when(net.getNetworkOfferingId()).thenReturn(NETWORK_ID);
+
+        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
+        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
+        when(ntwkoffer.isPersistent()).thenReturn(true);
+        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
+
+        // Golden path
+        assertTrue(_nuageVspElement.canHandle(net, Service.Connectivity));
+
+        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan);
+        // Only broadcastdomaintype Vsp is supported
+        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
+
+        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
+        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(false);
+        // No NuageVsp provider in the network
+        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
+
+        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(false);
+        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
+        // NusageVsp provider does not provide Connectivity for this network
+        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
+
+        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true);
+        // Only service Connectivity is supported
+        assertFalse(_nuageVspElement.canHandle(net, Service.Dhcp));
+
+        // Can't handle network offerings with specify vlan = true
+        when(ntwkoffer.isSpecifyVlan()).thenReturn(true);
+        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
+    }
+
+    @Test
+    public void testImplement() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException {
+        final Network network = mock(NetworkVO.class, withSettings().extraInterfaces(Network.class));
+        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
+        when(network.getId()).thenReturn(NETWORK_ID);
+        when(network.getVpcId()).thenReturn(null);
+        when(network.getBroadcastUri()).thenReturn(new URI(""));
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDomainId()).thenReturn(NETWORK_ID);
+        when(network.getDataCenterId()).thenReturn(NETWORK_ID);
+        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true);
+
+        final NetworkVO networkVO = mock(NetworkVO.class);
+        when(network.getUuid()).thenReturn("aaaaaa");
+
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(networkVO);
+
+        final NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(NETWORK_ID);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        DeployDestination deployDest = mock(DeployDestination.class);
+
+        final DomainVO dom = mock(DomainVO.class);
+        when(dom.getName()).thenReturn("domain");
+        when(_domainDao.findById(NETWORK_ID)).thenReturn(dom);
+        final Account acc = mock(Account.class);
+        when(acc.getAccountName()).thenReturn("accountname");
+        final ReservationContext context = mock(ReservationContext.class);
+        when(context.getDomain()).thenReturn(dom);
+        when(context.getAccount()).thenReturn(acc);
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(NETWORK_ID);
+        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
+        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
+        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress)).thenReturn(new ArrayList<FirewallRuleVO>());
+        when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress)).thenReturn(new ArrayList<FirewallRuleVO>());
+        when(_ipAddressDao.listStaticNatPublicIps(NETWORK_ID)).thenReturn(new ArrayList<IPAddressVO>());
+        when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<String>());
+        when(_networkDao.findById(network.getId())).thenReturn((NetworkVO)network);
+
+        assertTrue(_nuageVspElement.implement(network, offering, deployDest, context));
+    }
+
+    @Test
+    public void testVerifyServiceCombination() {
+
+        Set<Service> services = Sets.newHashSet(
+            Service.Dhcp,
+            Service.StaticNat,
+            Service.SourceNat,
+            Service.Connectivity,
+            Service.Firewall);
+        assertTrue(_nuageVspElement.verifyServicesCombination(services));
+
+        services = Sets.newHashSet(
+                Service.Dhcp,
+                Service.StaticNat,
+                Service.Connectivity,
+                Service.Firewall);
+        assertTrue(_nuageVspElement.verifyServicesCombination(services));
+
+
+        services = Sets.newHashSet(
+                Service.Dhcp,
+                Service.StaticNat,
+                Service.Firewall);
+        try {
+            _nuageVspElement.verifyServicesCombination(services);
+            fail("Expected Exception");
+        } catch (UnsupportedServiceException e) {
+            assertThat(e.getMessage(), is("Provider Network.Provider[name=NuageVsp] requires services: [Network.Service[name=Connectivity]]"));
+        }
+    }
+
+    @Test
+    public void testApplyStaticNats() throws CloudException {
+        final Network network = mock(Network.class);
+        when(network.getUuid()).thenReturn("aaaaaa");
+        when(network.getVpcId()).thenReturn(null);
+        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDomainId()).thenReturn(NETWORK_ID);
+
+        final DomainVO domVo = mock(DomainVO.class);
+        when(_domainDao.findById(41l)).thenReturn(domVo);
+
+        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
+        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
+        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(NETWORK_ID);
+        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
+        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
+        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
+        final Answer answer = mock(Answer.class);
+        when(answer.getResult()).thenReturn(true);
+        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
+        assertTrue(_nuageVspElement.applyStaticNats(network, new ArrayList<StaticNat>()));
+    }
+
+    @Test
+    public void testApplyFWRules() throws Exception {
+        final Network network = mock(Network.class);
+        when(network.getUuid()).thenReturn("aaaaaa");
+        when(network.getVpcId()).thenReturn(null);
+        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDomainId()).thenReturn(NETWORK_ID);
+
+        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
+        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
+        when(ntwkoffer.isEgressDefaultPolicy()).thenReturn(true);
+        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(NETWORK_ID);
+        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
+        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
+        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
+
+        final Answer answer = mock(Answer.class);
+        when(answer.getResult()).thenReturn(true);
+        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
+        assertTrue(_nuageVspElement.applyFWRules(network, new ArrayList<FirewallRule>()));
+    }
+
+    @Test
+    public void testApplyNetworkACL() throws Exception {
+        final Network network = mock(Network.class);
+        when(network.getUuid()).thenReturn("aaaaaa");
+        when(network.getVpcId()).thenReturn(null);
+        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDomainId()).thenReturn(NETWORK_ID);
+
+        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
+        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
+        when(ntwkoffer.isEgressDefaultPolicy()).thenReturn(true);
+        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(NETWORK_ID);
+        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
+        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
+        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
+        final Answer answer = mock(Answer.class);
+        when(answer.getResult()).thenReturn(true);
+        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
+        assertTrue(_nuageVspElement.applyNetworkACLs(network, new ArrayList<NetworkACLItem>()));
+    }
+
+    @Test
+    public void testShutdownVpc() throws Exception {
+        final Vpc vpc = mock(Vpc.class);
+        when(vpc.getUuid()).thenReturn("aaaaaa");
+        when(vpc.getState()).thenReturn(Vpc.State.Inactive);
+        when(vpc.getDomainId()).thenReturn(NETWORK_ID);
+        when(vpc.getZoneId()).thenReturn(NETWORK_ID);
+        when(vpc.getId()).thenReturn(NETWORK_ID);
+
+        final DomainVO dom = mock(DomainVO.class);
+        when(dom.getName()).thenReturn("domain");
+        when(_domainDao.findById(NETWORK_ID)).thenReturn(dom);
+        final Account acc = mock(Account.class);
+        when(acc.getAccountName()).thenReturn("accountname");
+        final ReservationContext context = mock(ReservationContext.class);
+        when(context.getDomain()).thenReturn(dom);
+        when(context.getAccount()).thenReturn(acc);
+
+        PhysicalNetworkVO physNet = mock(PhysicalNetworkVO.class);
+        when(physNet.getIsolationMethods()).thenReturn(Lists.newArrayList("VSP"));
+        when(physNet.getId()).thenReturn(NETWORK_ID);
+        when(_physicalNetworkDao.listByZone(NETWORK_ID)).thenReturn(Lists.newArrayList(physNet));
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(NETWORK_ID);
+        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
+        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Lists.newArrayList(nuageVspDevice));
+        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        DomainRouterVO domainRouter = mock(DomainRouterVO.class);
+        when(domainRouter.getUuid()).thenReturn("aaaaaa");
+        when(_domainRouterDao.listByVpcId(NETWORK_ID)).thenReturn(Lists.newArrayList(domainRouter));
+
+        final Answer answer = mock(Answer.class);
+        when(answer.getResult()).thenReturn(true);
+        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
+        assertTrue(_nuageVspElement.shutdownVpc(vpc, context));
+    }
+}
\ No newline at end of file
diff --git a/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java
new file mode 100644
index 0000000..8a0488d
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java
@@ -0,0 +1,511 @@
+//
+// 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.network.guru;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.internal.util.collections.Sets;
+import org.mockito.invocation.InvocationOnMock;
+
+import com.google.common.collect.ImmutableMap;
+
+import com.cloud.NuageTest;
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.guru.DeallocateVmVspCommand;
+import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
+import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
+import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterDetailsDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.NuageVspDeviceVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.NuageVspDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+public class NuageVspGuestNetworkGuruTest extends NuageTest {
+    private static final long DATACENTER_ID = 100L;
+    private static final long HOST_ID = 101L;
+    private static final long DOMAIN_ID = 1L;
+    private static final long ACCOUNT_ID = 2L;
+    private static final long OFFERING_ID = 40L;
+    private static final long NETWORK_ID = 42L;
+    private static final long VM_ID = 242L;
+    private static final long NIC_ID = 342L;
+
+    private static final String DATACENTER_UUID = "uuid-datacenter-100";
+    private static final String HOST_UUID = "uuid-host-101";
+    private static final String DOMAIN_UUID = "uuid-domain-001";
+    private static final String ACCOUNT_UUID = "uuid-account-002";
+    private static final String OFFERING_UUID = "uuid-offering-040";
+    private static final String NETWORK_UUID = "uuid-network-000-42";
+    private static final String VM_UUID = "uuid-vm-002-42";
+    private static final String NIC_UUID = "uuid-nic-003-42";
+
+    @Mock private PhysicalNetworkDao _physicalNetworkDao;
+    @Mock private DataCenterDao _dataCenterDao;
+    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
+    @Mock private AgentManager _agentManager;
+    @Mock private AccountDao _accountDao;
+    @Mock private DomainDao _domainDao;
+    @Mock private NicDao _nicDao;
+    @Mock private NetworkOfferingDao _networkOfferingDao;
+    @Mock private NuageVspDao _nuageVspDao;
+    @Mock private HostDao _hostDao;
+    @Mock private NetworkDao _networkDao;
+    @Mock private IPAddressDao _ipAddressDao;
+    @Mock private NuageVspManager _nuageVspManager;
+    @Mock private ConfigurationManager _configurationManager;
+    @Mock private DataCenterDetailsDao _dcDetailsDao;
+    @Mock private NetworkDetailsDao _networkDetailsDao;
+    @Mock private PhysicalNetworkVO physnet;
+    @Mock private DomainRouterDao _routerDao;
+
+    private Account _account;
+    private Domain _domain;
+    private DataCenterVO _dc;
+    private ReservationContext _reservationContext;
+
+    @InjectMocks
+    private NuageVspGuestNetworkGuru _nuageVspGuestNetworkGuru = new NuageVspGuestNetworkGuru();
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        _account = getMockAccount();
+        _domain = getMockDomain();
+        _dc = mockDataCenter();
+        _reservationContext = getMockReservationContext(_account, _domain);
+
+        when(_physicalNetworkDao.findById(any(Long.class))).thenReturn(physnet);
+        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VSP"));
+        when(physnet.getId()).thenReturn(NETWORK_ID);
+
+        final HostVO host = mock(HostVO.class);
+        when(host.getId()).thenReturn(HOST_ID);
+        when(host.getUuid()).thenReturn(HOST_UUID);
+        when(_hostDao.findById(HOST_ID)).thenReturn(host);
+
+        when(_agentManager.easySend(eq(HOST_ID), any(Command.class))).thenReturn(new Answer(null));
+        when(_agentManager.easySend(eq(HOST_ID), any(ImplementNetworkVspCommand.class))).thenAnswer(this::mockImplement);
+        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
+
+        final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
+        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections.singletonList(device));
+        when(device.getId()).thenReturn(1L);
+        when(device.getHostId()).thenReturn(HOST_ID);
+    }
+
+    Answer mockImplement(InvocationOnMock invocation) {
+        if (invocation.getArguments()[1] instanceof ImplementNetworkVspCommand) {
+            ImplementNetworkVspCommand command = (ImplementNetworkVspCommand)(invocation.getArguments()[1]);
+            return new ImplementNetworkVspAnswer(command, command.getNetwork(), new NetworkRelatedVsdIds.Builder().build());
+        } else {
+            return new Answer(null);
+        }
+    }
+
+    @Test
+    public void testCanHandle() {
+        final NetworkOffering offering = mockNetworkOffering(false);
+
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(true));
+
+        // Not supported TrafficType != Guest
+        when(offering.getTrafficType()).thenReturn(TrafficType.Management);
+        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(false));
+
+        // Supported: GuestType Shared
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Shared);
+        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(true));
+
+        // Not supported: Basic networking
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
+
+        // Not supported: IsolationMethod != VSP
+        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
+        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
+
+        // Not supported: Non-persistent VPC tier
+        when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(true);
+        assertFalse(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet));
+    }
+
+    @Test
+    public void testDesign() {
+        final NetworkOffering offering = mockNetworkOffering(false);
+        when(offering.isPersistent()).thenReturn(false);
+
+        final DeploymentPlan plan = mockDeploymentPlan();
+        final Network network = mock(Network.class);
+
+        final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, _account);
+        assertThat(designednetwork, notNullValue(Network.class));
+        assertThat(designednetwork.getBroadcastDomainType(), is(BroadcastDomainType.Vsp));
+
+        // Can't design non-persistent VPC tier
+        when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(true);
+        assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
+    }
+
+    @Test
+    public void testDesignNoIsolationMethodVSP() {
+        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
+
+        final NetworkOffering offering = mockNetworkOffering(false);
+
+        final DeploymentPlan plan = mockDeploymentPlan();
+        final Network network = mock(Network.class);
+
+        assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
+    }
+
+    @Test
+    public void testReserve() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
+        final NetworkVO network = mockNetwork();
+        final NicProfile nicProfile = mockNicProfile();
+        final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Starting);
+
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
+
+        _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
+
+        verify(_agentManager).easySend(anyLong(), any(Command.class));
+    }
+
+    @Test
+    public void testReserveVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
+        final NetworkVO network = mockNetwork();
+        final NicProfile nicProfile = mockNicProfile();
+        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Starting);
+
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
+
+        _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
+
+        verifyZeroInteractions(_agentManager);
+        verify(network).setRollingRestart(true);
+    }
+
+    @Test
+    public void testImplementNetwork() throws URISyntaxException, InsufficientVirtualNetworkCapacityException {
+        final NetworkVO network = mockNetwork();
+
+        when(network.getState()).thenReturn(com.cloud.network.Network.State.Implementing);
+
+        final NetworkOffering offering = mockNetworkOffering(false);
+
+        final DeployDestination deployDest = mock(DeployDestination.class);
+        when(deployDest.getDataCenter()).thenReturn(_dc);
+        _nuageVspGuestNetworkGuru.implement(network, offering, deployDest, _reservationContext);
+    }
+
+    @Test
+    public void testDeallocate() throws Exception {
+        final NetworkVO network = mockNetwork();
+        final NicProfile nicProfile = mockNicProfile();
+        final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Expunging);
+
+        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
+    }
+
+    @Test
+    public void testDeallocateVR() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
+        final NetworkVO network = mockNetwork();
+        final NicProfile nicProfile = mockNicProfile();
+        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
+
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
+
+        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
+    }
+
+    @Test
+    public void testDeallocateVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
+        final NetworkVO network = mockNetwork();
+        final NicProfile nicProfile = mockNicProfile();
+        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
+
+        DomainRouterVO newVR = mock(DomainRouterVO.class);
+
+        when(_routerDao.listByNetworkAndRole(NETWORK_ID, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(Collections.singletonList(newVR));
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
+
+        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
+
+        ArgumentCaptor<Command> argumentCaptor = ArgumentCaptor.forClass(Command.class);
+        verify(_agentManager, times(2)).easySend(eq(HOST_ID), argumentCaptor.capture());
+        final List<Command> commands = argumentCaptor.getAllValues();
+        assertThat(commands.get(0) instanceof DeallocateVmVspCommand, is(true));
+        assertThat(commands.get(1) instanceof ReserveVmInterfaceVspCommand, is(true));
+    }
+
+    @Test
+    public void testTrash() throws Exception {
+        final NetworkVO network = mock(NetworkVO.class);
+        when(network.getId()).thenReturn(NETWORK_ID);
+        when(network.getUuid()).thenReturn(NETWORK_UUID);
+        when(network.getName()).thenReturn("trash");
+        when(network.getDomainId()).thenReturn(DOMAIN_ID);
+        when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
+        when(network.getVpcId()).thenReturn(null);
+        when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
+
+        final NetworkOffering offering = mockNetworkOffering(false);
+
+        when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<>());
+        when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList<>());
+
+        assertTrue(_nuageVspGuestNetworkGuru.trash(network, offering));
+    }
+
+    @Nonnull
+    private NetworkVO mockNetwork() throws URISyntaxException {
+        final NetworkVO network = mock(NetworkVO.class);
+        when(network.getId()).thenReturn(NETWORK_ID);
+        when(network.getUuid()).thenReturn(NETWORK_UUID);
+        when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
+        when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
+        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
+        when(network.getDomainId()).thenReturn(DOMAIN_ID);
+        when(network.getAccountId()).thenReturn(ACCOUNT_ID);
+        when(network.getVpcId()).thenReturn(null);
+        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(network.getMode()).thenReturn(Mode.Dhcp);
+        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
+        when(network.getBroadcastUri()).thenReturn(new URI("vsp://" + NETWORK_UUID + "/10.1.1.1"));
+        when(network.getGateway()).thenReturn("10.1.1.1");
+        when(network.getCidr()).thenReturn("10.1.1.0/24");
+        when(network.getName()).thenReturn("iso");
+
+        when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
+
+        return network;
+    }
+
+    @Nonnull
+    private NetworkOffering mockNetworkOffering(boolean forVpc) {
+        final NetworkOfferingVO offering = mock(NetworkOfferingVO.class);
+        when(offering.getId()).thenReturn(OFFERING_ID);
+        when(offering.getUuid()).thenReturn(OFFERING_UUID);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+        when(offering.isForVpc()).thenReturn(forVpc);
+        when(offering.isPersistent()).thenReturn(false);
+        when(offering.getTags()).thenReturn("aaaa");
+        when(offering.isEgressDefaultPolicy()).thenReturn(true);
+
+        when(_networkOfferingDao.findById(OFFERING_ID)).thenReturn(offering);
+
+        when(_configurationManager.isOfferingForVpc(offering)).thenReturn(forVpc);
+
+        when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
+        when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
+
+        when(_networkModel.getNetworkOfferingServiceProvidersMap(OFFERING_ID)).thenReturn(ImmutableMap.of(
+                Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp),
+                Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp)
+        ));
+
+        return offering;
+    }
+
+    private DeploymentPlan mockDeploymentPlan() {
+        final DeploymentPlan deploymentPlan = mock(DeploymentPlan.class);
+        when(deploymentPlan.getDataCenterId()).thenReturn(DATACENTER_ID);
+        return deploymentPlan;
+    }
+
+    private DataCenterVO mockDataCenter() {
+        DataCenterVO dc = mock(DataCenterVO.class);
+        when(dc.getId()).thenReturn(DATACENTER_ID);
+        when(dc.getUuid()).thenReturn(DATACENTER_UUID);
+        when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
+        when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
+        when(_dataCenterDao.findById(DATACENTER_ID)).thenReturn(dc);
+
+        return dc;
+    }
+
+    @Nonnull
+    private Account getMockAccount() {
+        final AccountVO account = mock(AccountVO.class);
+        when(account.getId()).thenReturn(ACCOUNT_ID);
+        when(account.getAccountId()).thenReturn(ACCOUNT_ID);
+        when(account.getUuid()).thenReturn(ACCOUNT_UUID);
+        when(account.getDomainId()).thenReturn(DOMAIN_ID);
+        when(account.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL);
+
+        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);
+
+        return account;
+    }
+
+    @Nonnull
+    private Domain getMockDomain() {
+        final DomainVO domain = mock(DomainVO.class);
+        when(domain.getId()).thenReturn(DOMAIN_ID);
+        when(domain.getUuid()).thenReturn(DOMAIN_UUID);
+        when(domain.getName()).thenReturn("aaaaa");
+
+        when(_domainDao.findById(DOMAIN_ID)).thenReturn(domain);
+
+        return domain;
+    }
+
+    @Nonnull
+    private VirtualMachineProfile mockVirtualMachineProfile(VirtualMachine.State state) {
+        final VirtualMachine vm = mock(VirtualMachine.class);
+        when(vm.getId()).thenReturn(VM_ID);
+        when(vm.getType()).thenReturn(VirtualMachine.Type.User);
+        when(vm.getState()).thenReturn(state);
+
+        final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
+        when(vmProfile.getType()).thenReturn(VirtualMachine.Type.User);
+        when(vmProfile.getInstanceName()).thenReturn("Test-VM");
+        when(vmProfile.getUuid()).thenReturn(VM_UUID);
+        when(vmProfile.getVirtualMachine()).thenReturn(vm);
+        return vmProfile;
+    }
+
+    @Nonnull
+    private VirtualMachineProfile mockVRProfile(VirtualMachine.State state) {
+        final VirtualMachine vm = mock(VirtualMachine.class);
+        when(vm.getId()).thenReturn(VM_ID);
+        when(vm.getUuid()).thenReturn(VM_UUID);
+        when(vm.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vm.getState()).thenReturn(state);
+
+
+        final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
+        when(vmProfile.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
+        when(vmProfile.getInstanceName()).thenReturn("Test-VR");
+        when(vmProfile.getId()).thenReturn(VM_ID);
+        when(vmProfile.getUuid()).thenReturn(VM_UUID);
+        when(vmProfile.getVirtualMachine()).thenReturn(vm);
+        when(vmProfile.isRollingRestart()).thenReturn(true);
+        return vmProfile;
+    }
+
+    @Nonnull
+    private NicProfile mockNicProfile() {
+        final NicVO nicvo = mock(NicVO.class);
+        when(nicvo.getId()).thenReturn(NIC_ID);
+        when(nicvo.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
+        when(nicvo.getIPv4Address()).thenReturn("10.10.10.10");
+        when(nicvo.getUuid()).thenReturn("aaaa-fffff");
+        when(nicvo.getNetworkId()).thenReturn(NETWORK_ID);
+        when(nicvo.getInstanceId()).thenReturn(VM_ID);
+        when(_nicDao.findById(NIC_ID)).thenReturn(nicvo);
+        when(_nicDao.findDefaultNicForVM(VM_ID)).thenReturn(nicvo);
+
+        NicProfile nicProfile = mock(NicProfile.class);
+        when(nicProfile.getUuid()).thenReturn("aaa-bbbb");
+        when(nicProfile.getId()).thenReturn(NIC_ID);
+        when(nicProfile.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
+        when(nicProfile.getIPv4Address()).thenReturn("10.10.10.10");
+        return nicProfile;
+    }
+
+    @Nonnull
+    private static ReservationContext getMockReservationContext(Account networksAccount, Domain networksDomain) {
+        final ReservationContext reservationContext = mock(ReservationContext.class);
+        when(reservationContext.getAccount()).thenReturn(networksAccount);
+        when(reservationContext.getDomain()).thenReturn(networksDomain);
+        return reservationContext;
+    }
+
+}
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/manager/NuageVspManagerTest.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java
rename to plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/manager/NuageVspManagerTest.java
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/resource/NuageVspResourceTest.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java
rename to plugins/network-elements/nuage-vsp/src/test/java/com/cloud/network/resource/NuageVspResourceTest.java
diff --git a/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/util/NuageVspEntityBuilderTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/util/NuageVspEntityBuilderTest.java
new file mode 100644
index 0000000..f5124b2
--- /dev/null
+++ b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/util/NuageVspEntityBuilderTest.java
@@ -0,0 +1,435 @@
+//
+// 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.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.nuage.vsp.acs.client.api.model.Protocol;
+import net.nuage.vsp.acs.client.api.model.VspAclRule;
+import net.nuage.vsp.acs.client.api.model.VspDomain;
+import net.nuage.vsp.acs.client.api.model.VspNetwork;
+import net.nuage.vsp.acs.client.api.model.VspNic;
+import net.nuage.vsp.acs.client.api.model.VspStaticNat;
+import net.nuage.vsp.acs.client.api.model.VspVm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import com.google.common.collect.Lists;
+
+import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
+
+import com.cloud.NuageTest;
+import com.cloud.dc.VlanDetailsVO;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.manager.NuageVspManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.net.Ip;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+
+
+public class NuageVspEntityBuilderTest extends NuageTest {
+
+    private static final long DOMAIN_ID = 1L;
+    private static final long ACCOUNT_ID = 1L;
+    private static final long NETWORK_OFFERING_ID = 1L;
+    private static final long SHARED_NETWORK_OFFERING_ID = 2L;
+    private static final long L2_NETWORK_OFFERING_ID = 3L;
+    private static final long VPC_ID = 1L;
+    private static final long SOURCE_IP_ADDRESS_ID = 1L;
+    private static final long VM_ID = 4L;
+    private static final long VLAN_ID = 5L;
+    public static final String VM_IP = "192.168.0.24";
+
+    @Mock private AccountDao _accountDao;
+    @Mock private DomainDao _domainDao;
+    @Mock private IPAddressDao _ipAddressDao;
+    @Mock private NetworkDao _networkDao;
+    @Mock private NetworkDetailsDao _networkDetailsDao;
+    @Mock private NetworkOfferingDao _networkOfferingDao;
+    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
+    @Mock private NicDao _nicDao;
+    @Mock private NicSecondaryIpDao _nicSecondaryIpDao;
+    @Mock private VlanDao _vlanDao;
+    @Mock private VlanDetailsDao _vlanDetailsDao;
+    @Mock private VpcDao _vpcDao;
+    @Mock private VpcDetailsDao _vpcDetailsDao;
+
+    @Mock private NuageVspManager _nuageVspManager;
+
+    @InjectMocks
+    private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder();
+
+    private DomainVO _mockedDomain = mock(DomainVO.class);
+    private AccountVO _mockedAccount = mock(AccountVO.class);
+    private NetworkOfferingVO _mockedNetworkOffering = mock(NetworkOfferingVO.class);
+    private NetworkOfferingVO _mockedSharedNetworkOffering = mock(NetworkOfferingVO.class);
+    private NetworkOfferingVO _mockedL2NetworkOffering = mock(NetworkOfferingVO.class);
+    private VlanVO _mockedVlan = mock(VlanVO.class);
+    private VlanDetailsVO _mockedVlanDetail = mock(VlanDetailsVO.class);
+    private VpcVO _mockedVpc = mock(VpcVO.class);
+    private NetworkVO _mockedNetwork = mock(NetworkVO.class);
+    private NetworkVO _mockedVpcNetwork = mock(NetworkVO.class);
+    private NetworkVO _mockedSharedNetwork = mock(NetworkVO.class);
+    private NetworkVO _mockedL2Network = mock(NetworkVO.class);
+    private VirtualMachine _mockedUserVirtualMachine = mock(VirtualMachine.class);
+    private VirtualMachine _mockedDomainRouterVirtualMachine = mock(VirtualMachine.class);
+    private NicProfile _mockedNicProfile = mock(NicProfile.class);
+    private NicVO _mockedNic = mock(NicVO.class);
+    private IPAddressVO _mockedStaticNatIp = mock(IPAddressVO.class);
+    private VlanVO _mockedStaticNatVlan = mock(VlanVO.class);
+    private FirewallRule _mockedFirewallRule = mock(FirewallRule.class);
+    private NetworkACLItem _mockedNetworkAclItem = mock(NetworkACLItem.class);
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        setUpMockedDomain();
+        setUpMockedAccount();
+        setUpMockedNetworkOffering(_mockedNetworkOffering, Network.GuestType.Isolated);
+        setUpMockedNetworkOffering(_mockedSharedNetworkOffering, Network.GuestType.Shared);
+        setUpMockedNetworkOffering(_mockedL2NetworkOffering, Network.GuestType.Isolated);
+        setUpMockedVlan();
+        setUpMockedVlanDetail();
+        setUpMockedVpc();
+        setUpMockedNetwork(_mockedNetwork, NETWORK_OFFERING_ID, null);
+        setUpMockedNetwork(_mockedVpcNetwork, NETWORK_OFFERING_ID, VPC_ID);
+        setUpMockedNetwork(_mockedSharedNetwork, SHARED_NETWORK_OFFERING_ID, null);
+        setUpMockedNetwork(_mockedL2Network, L2_NETWORK_OFFERING_ID, null);
+        setUpMockedVirtualMachine(_mockedUserVirtualMachine, false);
+        setUpMockedVirtualMachine(_mockedDomainRouterVirtualMachine, true);
+        setUpMockedNicProfile();
+        setUpMockedNic();
+        setUpMockedStaticNatIp();
+        setUpMockedStaticNatVlan();
+        setUpMockedFirewallRule();
+        setUpMockedNetworkAclItem();
+        setUpMockedDaoCalls();
+    }
+
+    @Test
+    public void testBuildVspDomain() {
+        VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(_mockedDomain);
+        validateVspDomain(vspDomain);
+    }
+
+    @Test
+    public void testBuildVspNetwork() {
+        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network);
+        validateVspNetwork(vspNetwork, true, false, false, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network);
+        validateVspNetwork(vspNetwork, true, false, false, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork);
+        validateVspNetwork(vspNetwork, false, true, false, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork);
+        validateVspNetwork(vspNetwork, false, true, false, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork);
+        validateVspNetwork(vspNetwork, false, false, true, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork);
+        validateVspNetwork(vspNetwork, false, false, true, false);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork);
+        validateVspNetwork(vspNetwork, false, false, false, true);
+
+        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork);
+        validateVspNetwork(vspNetwork, false, false, false, true);
+    }
+
+    @Test
+    public void testBuildVspVm() {
+        VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(_mockedUserVirtualMachine, _mockedNetwork);
+        validateVspVm(vspVm, false);
+
+        vspVm = _nuageVspEntityBuilder.buildVspVm(_mockedDomainRouterVirtualMachine, _mockedNetwork);
+        validateVspVm(vspVm, true);
+    }
+
+    @Test
+    public void testBuildVspNic() {
+        VspNic vspNic = _nuageVspEntityBuilder.buildVspNic("nicUuid", _mockedNicProfile);
+        validateVspNic(vspNic);
+
+        vspNic = _nuageVspEntityBuilder.buildVspNic(_mockedNic);
+        validateVspNic(vspNic);
+    }
+
+    @Test
+    public void testBuildVspStaticNat() {
+        VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(true, _mockedStaticNatIp, _mockedStaticNatVlan, _mockedNic);
+        validateVspStaticNat(vspStaticNat, true);
+    }
+
+    @Test
+    public void testBuildVspAclRuleAcl() {
+        VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedNetworkAclItem);
+        validateVspAclRule(vspAclRule, false);
+    }
+
+    @Test
+    public void testBuildVspAclRuleFirewall() {
+        VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedFirewallRule, _mockedNetwork);
+        validateVspAclRule(vspAclRule, true);
+    }
+
+    private void validateVspDomain(VspDomain vspDomain) {
+        assertEquals("domainUuid", vspDomain.getUuid());
+        assertEquals("domainName", vspDomain.getName());
+        assertEquals("domainPath", vspDomain.getPath());
+    }
+
+    private void validateVspNetwork(VspNetwork vspNetwork, boolean isL2, boolean isL3, boolean isVpc, boolean isShared) {
+        assertEquals(NETWORK_ID, vspNetwork.getId());
+        assertEquals("networkUuid", vspNetwork.getUuid());
+        assertEquals("networkName", vspNetwork.getName());
+        assertNotNull(vspNetwork.getVspDomain());
+        validateVspDomain(vspNetwork.getVspDomain());
+
+        assertEquals("accountName", vspNetwork.getAccountName());
+        assertEquals("accountUuid", vspNetwork.getAccountUuid());
+
+        if (isVpc) {
+            assertEquals("vpcUuid", vspNetwork.getVpcUuid());
+            assertEquals("vpcName", vspNetwork.getVpcName());
+        } else {
+            assertNull(vspNetwork.getVpcUuid());
+            assertNull(vspNetwork.getVpcName());
+        }
+
+        assertEquals(isL2, vspNetwork.isL2());
+        assertEquals(isL3, vspNetwork.isL3());
+        assertEquals(isVpc, vspNetwork.isVpc());
+        assertEquals(isShared, vspNetwork.isShared());
+        assertEquals(true, vspNetwork.isFirewallServiceSupported());
+        assertEquals(true, vspNetwork.isEgressDefaultPolicy());
+        assertEquals("10.10.10.0/24", vspNetwork.getCidr());
+        assertEquals("10.10.10.1", vspNetwork.getGateway());
+    }
+
+    private void validateVspVm(VspVm vspVm, boolean isDomainRouter) {
+        assertEquals("virtualMachineUuid", vspVm.getUuid());
+        assertEquals("virtualMachineInstanceName", vspVm.getName());
+        assertEquals(VspVm.State.Running, vspVm.getState());
+        assertEquals(isDomainRouter, vspVm.getDomainRouter());
+    }
+
+    private void validateVspNic(VspNic vspNic) {
+        assertEquals("nicUuid", vspNic.getUuid());
+        assertEquals("macAddress", vspNic.getMacAddress());
+        assertEquals(true, vspNic.getUseStaticIp());
+        assertEquals("192.168.0.24", vspNic.getIp());
+    }
+
+    private void validateVspStaticNat(VspStaticNat vspStaticNat, Boolean forRevoke) {
+        assertEquals("staticNatIpUuid", vspStaticNat.getIpUuid());
+        assertEquals("10.10.10.2", vspStaticNat.getIpAddress());
+        assertEquals(forRevoke, vspStaticNat.getRevoke());
+        assertEquals(VspStaticNat.State.Allocated, vspStaticNat.getState());
+        assertEquals(true, vspStaticNat.getOneToOneNat());
+        assertEquals("staticNatVlanUuid", vspStaticNat.getVlanUuid());
+        assertEquals("10.10.10.1", vspStaticNat.getVlanGateway());
+        assertEquals("255.255.255.0", vspStaticNat.getVlanNetmask());
+    }
+
+    private void validateVspAclRule(VspAclRule vspAclRule, boolean isFirewall) {
+        assertEquals("aclUuid", vspAclRule.getUuid());
+        assertEquals(Protocol.TCP, vspAclRule.getProtocol());
+        assertEquals(new Integer(1), vspAclRule.getStartPort());
+        assertEquals(new Integer(20), vspAclRule.getEndPort());
+        assertEquals(Lists.newArrayList("10.10.0.0/16"), vspAclRule.getSourceCidrList());
+        assertEquals(VspAclRule.ACLState.Active, vspAclRule.getState());
+        assertEquals(VspAclRule.ACLTrafficType.Egress, vspAclRule.getTrafficType());
+
+        if (isFirewall) {
+            assertEquals(VspAclRule.ACLType.Firewall, vspAclRule.getType());
+            final VspStaticNat staticNat = vspAclRule.getStaticNat();
+            assertNotNull(staticNat);
+            assertEquals("192.168.0.24/32", staticNat.getDestinationIp());
+            assertEquals(VspAclRule.ACLAction.Deny, vspAclRule.getAction());
+        } else {
+            assertEquals(VspAclRule.ACLType.NetworkACL, vspAclRule.getType());
+            assertNull(vspAclRule.getStaticNat());
+            assertNull(vspAclRule.getSourceIpAddress());
+            assertEquals(VspAclRule.ACLAction.Allow, vspAclRule.getAction());
+        }
+    }
+
+    private void setUpMockedDomain() {
+        when(_mockedDomain.getUuid()).thenReturn("domainUuid");
+        when(_mockedDomain.getName()).thenReturn("domainName");
+        when(_mockedDomain.getPath()).thenReturn("domainPath");
+    }
+
+    private void setUpMockedAccount() {
+        when(_mockedAccount.getUuid()).thenReturn("accountUuid");
+        when(_mockedAccount.getAccountName()).thenReturn("accountName");
+    }
+
+    private void setUpMockedNetworkOffering(NetworkOfferingVO networkOfferingToMock, Network.GuestType guestType) {
+        when(networkOfferingToMock.isEgressDefaultPolicy()).thenReturn(true);
+        when(networkOfferingToMock.getGuestType()).thenReturn(guestType);
+    }
+
+    private void setUpMockedVlan() {
+        when(_mockedVlan.getIpRange()).thenReturn("192.168.2.2-192.168.2.200");
+    }
+
+    private void setUpMockedVlanDetail() {
+        when(_mockedVlanDetail.getValue()).thenReturn("true");
+    }
+
+    private void setUpMockedVpc() {
+        when(_mockedVpc.getUuid()).thenReturn("vpcUuid");
+        when(_mockedVpc.getName()).thenReturn("vpcName");
+    }
+
+    private void setUpMockedNetwork(NetworkVO networkToMock, long networkOfferingId, Long vpcId) {
+        when(networkToMock.getId()).thenReturn(NETWORK_ID);
+        when(networkToMock.getUuid()).thenReturn("networkUuid");
+        when(networkToMock.getName()).thenReturn("networkName");
+        when(networkToMock.getCidr()).thenReturn("10.10.10.0/24");
+        when(networkToMock.getGateway()).thenReturn("10.10.10.1");
+        when(networkToMock.getDomainId()).thenReturn(DOMAIN_ID);
+        when(networkToMock.getAccountId()).thenReturn(ACCOUNT_ID);
+        when(networkToMock.getNetworkOfferingId()).thenReturn(networkOfferingId);
+        when(networkToMock.getVpcId()).thenReturn(vpcId != null ? vpcId : null);
+    }
+
+    private void setUpMockedVirtualMachine(VirtualMachine virtualMachineToMock, boolean isDomainRouter) {
+        when(virtualMachineToMock.getUuid()).thenReturn("virtualMachineUuid");
+        when(virtualMachineToMock.getInstanceName()).thenReturn("virtualMachineInstanceName");
+        when(virtualMachineToMock.getState()).thenReturn(VirtualMachine.State.Running);
+        when(virtualMachineToMock.getType()).thenReturn(isDomainRouter ? VirtualMachine.Type.DomainRouter : VirtualMachine.Type.User);
+    }
+
+    private void setUpMockedNicProfile() {
+        when(_mockedNicProfile.getMacAddress()).thenReturn("macAddress");
+        when(_mockedNicProfile.getIPv4Address()).thenReturn(VM_IP);
+        when(_mockedNicProfile.getNetworkId()).thenReturn(NETWORK_ID);
+    }
+
+    private void setUpMockedNic() {
+        when(_mockedNic.getUuid()).thenReturn("nicUuid");
+        when(_mockedNic.getMacAddress()).thenReturn("macAddress");
+        when(_mockedNic.getIPv4Address()).thenReturn(VM_IP);
+        when(_mockedNic.getNetworkId()).thenReturn(NETWORK_ID);
+    }
+
+    private void setUpMockedStaticNatIp() {
+        when(_mockedStaticNatIp.getUuid()).thenReturn("staticNatIpUuid");
+        when(_mockedStaticNatIp.getAddress()).thenReturn(new Ip("10.10.10.2"));
+        when(_mockedStaticNatIp.isOneToOneNat()).thenReturn(true);
+        when(_mockedStaticNatIp.getVmIp()).thenReturn(VM_IP);
+        when(_mockedStaticNatIp.getAssociatedWithNetworkId()).thenReturn(NETWORK_ID);
+        when(_mockedStaticNatIp.getAssociatedWithVmId()).thenReturn(VM_ID);
+        when(_mockedStaticNatIp.getState()).thenReturn(IpAddress.State.Allocated);
+        when(_mockedStaticNatIp.getVlanId()).thenReturn(VLAN_ID);
+    }
+
+    private void setUpMockedStaticNatVlan() {
+        when(_mockedStaticNatVlan.getUuid()).thenReturn("staticNatVlanUuid");
+        when(_mockedStaticNatVlan.getVlanGateway()).thenReturn("10.10.10.1");
+        when(_mockedStaticNatVlan.getVlanNetmask()).thenReturn("255.255.255.0");
+    }
+
+    private void setUpMockedFirewallRule() {
+        when(_mockedFirewallRule.getUuid()).thenReturn("aclUuid");
+        when(_mockedFirewallRule.getProtocol()).thenReturn("TCP");
+        when(_mockedFirewallRule.getSourcePortStart()).thenReturn(1);
+        when(_mockedFirewallRule.getSourcePortEnd()).thenReturn(20);
+        when(_mockedFirewallRule.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16"));
+        when(_mockedFirewallRule.getState()).thenReturn(FirewallRule.State.Active);
+        when(_mockedFirewallRule.getTrafficType()).thenReturn(FirewallRule.TrafficType.Egress);
+        when(_mockedFirewallRule.getSourceIpAddressId()).thenReturn(SOURCE_IP_ADDRESS_ID);
+    }
+
+    private void setUpMockedNetworkAclItem() {
+        when(_mockedNetworkAclItem.getUuid()).thenReturn("aclUuid");
+        when(_mockedNetworkAclItem.getProtocol()).thenReturn("TCP");
+        when(_mockedNetworkAclItem.getSourcePortStart()).thenReturn(1);
+        when(_mockedNetworkAclItem.getSourcePortEnd()).thenReturn(20);
+        when(_mockedNetworkAclItem.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16"));
+        when(_mockedNetworkAclItem.getNumber()).thenReturn(1337);
+        when(_mockedNetworkAclItem.getState()).thenReturn(NetworkACLItem.State.Active);
+        when(_mockedNetworkAclItem.getTrafficType()).thenReturn(NetworkACLItem.TrafficType.Egress);
+        when(_mockedNetworkAclItem.getAction()).thenReturn(NetworkACLItem.Action.Allow);
+    }
+
+    private void setUpMockedDaoCalls() {
+        when(_domainDao.findById(DOMAIN_ID)).thenReturn(_mockedDomain);
+        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(_mockedAccount);
+        when(_networkDao.findById(NETWORK_ID)).thenReturn(_mockedNetwork);
+        when(_networkOfferingDao.findById(NETWORK_OFFERING_ID)).thenReturn(_mockedNetworkOffering);
+        when(_networkOfferingDao.findById(SHARED_NETWORK_OFFERING_ID)).thenReturn(_mockedSharedNetworkOffering);
+        when(_networkOfferingDao.findById(L2_NETWORK_OFFERING_ID)).thenReturn(_mockedL2NetworkOffering);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(true);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(true);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(true);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(true);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(false);
+        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(false);
+        when(_networkModel.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
+        when(_networkModel.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
+        when(_networkModel.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
+        when(_vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Lists.newArrayList(_mockedVlan));
+        when(_vlanDao.findById(VLAN_ID)).thenReturn(_mockedVlan);
+        when(_vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(_mockedVlanDetail);
+        when(_vpcDao.findById(VPC_ID)).thenReturn(_mockedVpc);
+        when(_ipAddressDao.findById(SOURCE_IP_ADDRESS_ID)).thenReturn(_mockedStaticNatIp);
+        when(_vpcDetailsDao.listDetailsKeyPairs(VPC_ID)).thenReturn(null);
+        when(_nicDao.findByIp4AddressAndNetworkId("192.168.0.24", NETWORK_ID)).thenReturn(_mockedNic);
+    }
+}
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspUtilTest.java b/plugins/network-elements/nuage-vsp/src/test/java/com/cloud/util/NuageVspUtilTest.java
similarity index 100%
rename from plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspUtilTest.java
rename to plugins/network-elements/nuage-vsp/src/test/java/com/cloud/util/NuageVspUtilTest.java
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java
deleted file mode 100644
index 9a87dac..0000000
--- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java
+++ /dev/null
@@ -1,384 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.network.element;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
-
-import com.cloud.NuageTest;
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.CloudException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.NuageVspDeviceVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.NuageVspDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.util.NuageVspEntityBuilder;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.dao.DomainRouterDao;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
-
-public class NuageVspElementTest extends NuageTest {
-
-    @InjectMocks
-    private NuageVspElement _nuageVspElement = new NuageVspElement();
-
-    @Mock private NetworkServiceMapDao _networkServiceMapDao;
-    @Mock private AgentManager _agentManager;
-    @Mock private HostDao _hostDao;
-    @Mock private NuageVspDao _nuageVspDao;
-    @Mock private DomainDao _domainDao;
-    @Mock private NetworkOfferingDao _networkOfferingDao;
-    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
-    @Mock private NuageVspManager _nuageVspManager;
-    @Mock private FirewallRulesDao _firewallRulesDao;
-    @Mock private IPAddressDao _ipAddressDao;
-    @Mock private PhysicalNetworkDao _physicalNetworkDao;
-    @Mock private NuageVspEntityBuilder _nuageVspEntityBuilder;
-    @Mock private VpcDetailsDao _vpcDetailsDao;
-    @Mock private DomainRouterDao _domainRouterDao;
-    @Mock private ResourceManager _resourceManager;
-    @Mock private ResourceTagDao _resourceTagDao;
-    @Mock private NetworkDao _networkDao;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        _nuageVspElement._nuageVspEntityBuilder = _nuageVspEntityBuilder;
-        _nuageVspElement._vpcDetailsDao = _vpcDetailsDao;
-        _nuageVspElement._routerDao = _domainRouterDao;
-        _nuageVspElement._networkDao = _networkDao;
-
-        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
-        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NuageVsp)).thenReturn(true);
-
-        _nuageVspElement.configure("NuageVspTestElement", Collections.<String, Object>emptyMap());
-    }
-
-    @Test
-    public void testCanHandle() {
-        final Network net = mock(Network.class);
-        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
-        when(net.getId()).thenReturn(NETWORK_ID);
-        when(net.getNetworkOfferingId()).thenReturn(NETWORK_ID);
-
-        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
-        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
-        when(ntwkoffer.getIsPersistent()).thenReturn(true);
-        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
-
-        // Golden path
-        assertTrue(_nuageVspElement.canHandle(net, Service.Connectivity));
-
-        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan);
-        // Only broadcastdomaintype Vsp is supported
-        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
-
-        when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
-        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(false);
-        // No NuageVsp provider in the network
-        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
-
-        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(false);
-        when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
-        // NusageVsp provider does not provide Connectivity for this network
-        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
-
-        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true);
-        // Only service Connectivity is supported
-        assertFalse(_nuageVspElement.canHandle(net, Service.Dhcp));
-
-        // Can't handle network offerings with specify vlan = true
-        when(ntwkoffer.getSpecifyVlan()).thenReturn(true);
-        assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity));
-    }
-
-    @Test
-    public void testImplement() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException {
-        final Network network = mock(NetworkVO.class, withSettings().extraInterfaces(Network.class));
-        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
-        when(network.getId()).thenReturn(NETWORK_ID);
-        when(network.getVpcId()).thenReturn(null);
-        when(network.getBroadcastUri()).thenReturn(new URI(""));
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDomainId()).thenReturn(NETWORK_ID);
-        when(network.getDataCenterId()).thenReturn(NETWORK_ID);
-        when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true);
-
-        final NetworkVO networkVO = mock(NetworkVO.class);
-        when(network.getUuid()).thenReturn("aaaaaa");
-
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(networkVO);
-
-        final NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(NETWORK_ID);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        DeployDestination deployDest = mock(DeployDestination.class);
-
-        final DomainVO dom = mock(DomainVO.class);
-        when(dom.getName()).thenReturn("domain");
-        when(_domainDao.findById(NETWORK_ID)).thenReturn(dom);
-        final Account acc = mock(Account.class);
-        when(acc.getAccountName()).thenReturn("accountname");
-        final ReservationContext context = mock(ReservationContext.class);
-        when(context.getDomain()).thenReturn(dom);
-        when(context.getAccount()).thenReturn(acc);
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(NETWORK_ID);
-        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
-        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
-        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress)).thenReturn(new ArrayList<FirewallRuleVO>());
-        when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress)).thenReturn(new ArrayList<FirewallRuleVO>());
-        when(_ipAddressDao.listStaticNatPublicIps(NETWORK_ID)).thenReturn(new ArrayList<IPAddressVO>());
-        when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<String>());
-        when(_networkDao.findById(network.getId())).thenReturn((NetworkVO)network);
-
-        assertTrue(_nuageVspElement.implement(network, offering, deployDest, context));
-    }
-
-    @Test
-    public void testVerifyServiceCombination() {
-
-        Set<Service> services = Sets.newHashSet(
-            Service.Dhcp,
-            Service.StaticNat,
-            Service.SourceNat,
-            Service.Connectivity,
-            Service.Firewall);
-        assertTrue(_nuageVspElement.verifyServicesCombination(services));
-
-        services = Sets.newHashSet(
-                Service.Dhcp,
-                Service.StaticNat,
-                Service.Connectivity,
-                Service.Firewall);
-        assertTrue(_nuageVspElement.verifyServicesCombination(services));
-
-
-        services = Sets.newHashSet(
-                Service.Dhcp,
-                Service.StaticNat,
-                Service.Firewall);
-        try {
-            _nuageVspElement.verifyServicesCombination(services);
-            fail("Expected Exception");
-        } catch (UnsupportedServiceException e) {
-            assertThat(e.getMessage(), is("Provider Network.Provider[name=NuageVsp] requires services: [Network.Service[name=Connectivity]]"));
-        }
-    }
-
-    @Test
-    public void testApplyStaticNats() throws CloudException {
-        final Network network = mock(Network.class);
-        when(network.getUuid()).thenReturn("aaaaaa");
-        when(network.getVpcId()).thenReturn(null);
-        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDomainId()).thenReturn(NETWORK_ID);
-
-        final DomainVO domVo = mock(DomainVO.class);
-        when(_domainDao.findById(41l)).thenReturn(domVo);
-
-        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
-        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
-        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(NETWORK_ID);
-        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
-        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
-        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
-        final Answer answer = mock(Answer.class);
-        when(answer.getResult()).thenReturn(true);
-        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
-        assertTrue(_nuageVspElement.applyStaticNats(network, new ArrayList<StaticNat>()));
-    }
-
-    @Test
-    public void testApplyFWRules() throws Exception {
-        final Network network = mock(Network.class);
-        when(network.getUuid()).thenReturn("aaaaaa");
-        when(network.getVpcId()).thenReturn(null);
-        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDomainId()).thenReturn(NETWORK_ID);
-
-        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
-        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
-        when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true);
-        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(NETWORK_ID);
-        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
-        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
-        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
-
-        final Answer answer = mock(Answer.class);
-        when(answer.getResult()).thenReturn(true);
-        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
-        assertTrue(_nuageVspElement.applyFWRules(network, new ArrayList<FirewallRule>()));
-    }
-
-    @Test
-    public void testApplyNetworkACL() throws Exception {
-        final Network network = mock(Network.class);
-        when(network.getUuid()).thenReturn("aaaaaa");
-        when(network.getVpcId()).thenReturn(null);
-        when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID);
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDomainId()).thenReturn(NETWORK_ID);
-
-        final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class);
-        when(ntwkoffer.getId()).thenReturn(NETWORK_ID);
-        when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true);
-        when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(NETWORK_ID);
-        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
-        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
-        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
-        final Answer answer = mock(Answer.class);
-        when(answer.getResult()).thenReturn(true);
-        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
-        assertTrue(_nuageVspElement.applyNetworkACLs(network, new ArrayList<NetworkACLItem>()));
-    }
-
-    @Test
-    public void testShutdownVpc() throws Exception {
-        final Vpc vpc = mock(Vpc.class);
-        when(vpc.getUuid()).thenReturn("aaaaaa");
-        when(vpc.getState()).thenReturn(Vpc.State.Inactive);
-        when(vpc.getDomainId()).thenReturn(NETWORK_ID);
-        when(vpc.getZoneId()).thenReturn(NETWORK_ID);
-        when(vpc.getId()).thenReturn(NETWORK_ID);
-
-        final DomainVO dom = mock(DomainVO.class);
-        when(dom.getName()).thenReturn("domain");
-        when(_domainDao.findById(NETWORK_ID)).thenReturn(dom);
-        final Account acc = mock(Account.class);
-        when(acc.getAccountName()).thenReturn("accountname");
-        final ReservationContext context = mock(ReservationContext.class);
-        when(context.getDomain()).thenReturn(dom);
-        when(context.getAccount()).thenReturn(acc);
-
-        PhysicalNetworkVO physNet = mock(PhysicalNetworkVO.class);
-        when(physNet.getIsolationMethods()).thenReturn(Lists.newArrayList("VSP"));
-        when(physNet.getId()).thenReturn(NETWORK_ID);
-        when(_physicalNetworkDao.listByZone(NETWORK_ID)).thenReturn(Lists.newArrayList(physNet));
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(NETWORK_ID);
-        final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class);
-        when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Lists.newArrayList(nuageVspDevice));
-        when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        DomainRouterVO domainRouter = mock(DomainRouterVO.class);
-        when(domainRouter.getUuid()).thenReturn("aaaaaa");
-        when(_domainRouterDao.listByVpcId(NETWORK_ID)).thenReturn(Lists.newArrayList(domainRouter));
-
-        final Answer answer = mock(Answer.class);
-        when(answer.getResult()).thenReturn(true);
-        when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer);
-        assertTrue(_nuageVspElement.shutdownVpc(vpc, context));
-    }
-}
\ No newline at end of file
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java
deleted file mode 100644
index 0708202..0000000
--- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java
+++ /dev/null
@@ -1,511 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.network.guru;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.annotation.Nonnull;
-
-import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.internal.util.collections.Sets;
-import org.mockito.invocation.InvocationOnMock;
-
-import com.google.common.collect.ImmutableMap;
-
-import com.cloud.NuageTest;
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.guru.DeallocateVmVspCommand;
-import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
-import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
-import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.NuageVspDeviceVO;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.NuageVspDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-
-public class NuageVspGuestNetworkGuruTest extends NuageTest {
-    private static final long DATACENTER_ID = 100L;
-    private static final long HOST_ID = 101L;
-    private static final long DOMAIN_ID = 1L;
-    private static final long ACCOUNT_ID = 2L;
-    private static final long OFFERING_ID = 40L;
-    private static final long NETWORK_ID = 42L;
-    private static final long VM_ID = 242L;
-    private static final long NIC_ID = 342L;
-
-    private static final String DATACENTER_UUID = "uuid-datacenter-100";
-    private static final String HOST_UUID = "uuid-host-101";
-    private static final String DOMAIN_UUID = "uuid-domain-001";
-    private static final String ACCOUNT_UUID = "uuid-account-002";
-    private static final String OFFERING_UUID = "uuid-offering-040";
-    private static final String NETWORK_UUID = "uuid-network-000-42";
-    private static final String VM_UUID = "uuid-vm-002-42";
-    private static final String NIC_UUID = "uuid-nic-003-42";
-
-    @Mock private PhysicalNetworkDao _physicalNetworkDao;
-    @Mock private DataCenterDao _dataCenterDao;
-    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
-    @Mock private AgentManager _agentManager;
-    @Mock private AccountDao _accountDao;
-    @Mock private DomainDao _domainDao;
-    @Mock private NicDao _nicDao;
-    @Mock private NetworkOfferingDao _networkOfferingDao;
-    @Mock private NuageVspDao _nuageVspDao;
-    @Mock private HostDao _hostDao;
-    @Mock private NetworkDao _networkDao;
-    @Mock private IPAddressDao _ipAddressDao;
-    @Mock private NuageVspManager _nuageVspManager;
-    @Mock private ConfigurationManager _configurationManager;
-    @Mock private DataCenterDetailsDao _dcDetailsDao;
-    @Mock private NetworkDetailsDao _networkDetailsDao;
-    @Mock private PhysicalNetworkVO physnet;
-    @Mock private DomainRouterDao _routerDao;
-
-    private Account _account;
-    private Domain _domain;
-    private DataCenterVO _dc;
-    private ReservationContext _reservationContext;
-
-    @InjectMocks
-    private NuageVspGuestNetworkGuru _nuageVspGuestNetworkGuru = new NuageVspGuestNetworkGuru();
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        _account = getMockAccount();
-        _domain = getMockDomain();
-        _dc = mockDataCenter();
-        _reservationContext = getMockReservationContext(_account, _domain);
-
-        when(_physicalNetworkDao.findById(any(Long.class))).thenReturn(physnet);
-        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VSP"));
-        when(physnet.getId()).thenReturn(NETWORK_ID);
-
-        final HostVO host = mock(HostVO.class);
-        when(host.getId()).thenReturn(HOST_ID);
-        when(host.getUuid()).thenReturn(HOST_UUID);
-        when(_hostDao.findById(HOST_ID)).thenReturn(host);
-
-        when(_agentManager.easySend(eq(HOST_ID), any(Command.class))).thenReturn(new Answer(null));
-        when(_agentManager.easySend(eq(HOST_ID), any(ImplementNetworkVspCommand.class))).thenAnswer(this::mockImplement);
-        when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
-
-        final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
-        when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections.singletonList(device));
-        when(device.getId()).thenReturn(1L);
-        when(device.getHostId()).thenReturn(HOST_ID);
-    }
-
-    Answer mockImplement(InvocationOnMock invocation) {
-        if (invocation.getArguments()[1] instanceof ImplementNetworkVspCommand) {
-            ImplementNetworkVspCommand command = (ImplementNetworkVspCommand)(invocation.getArguments()[1]);
-            return new ImplementNetworkVspAnswer(command, command.getNetwork(), new NetworkRelatedVsdIds.Builder().build());
-        } else {
-            return new Answer(null);
-        }
-    }
-
-    @Test
-    public void testCanHandle() {
-        final NetworkOffering offering = mockNetworkOffering(false);
-
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(true));
-
-        // Not supported TrafficType != Guest
-        when(offering.getTrafficType()).thenReturn(TrafficType.Management);
-        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(false));
-
-        // Supported: GuestType Shared
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Shared);
-        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(true));
-
-        // Not supported: Basic networking
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
-
-        // Not supported: IsolationMethod != VSP
-        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
-        assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Basic, physnet), is(false));
-
-        // Not supported: Non-persistent VPC tier
-        when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(true);
-        assertFalse(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet));
-    }
-
-    @Test
-    public void testDesign() {
-        final NetworkOffering offering = mockNetworkOffering(false);
-        when(offering.getIsPersistent()).thenReturn(false);
-
-        final DeploymentPlan plan = mockDeploymentPlan();
-        final Network network = mock(Network.class);
-
-        final Network designednetwork = _nuageVspGuestNetworkGuru.design(offering, plan, network, _account);
-        assertThat(designednetwork, notNullValue(Network.class));
-        assertThat(designednetwork.getBroadcastDomainType(), is(BroadcastDomainType.Vsp));
-
-        // Can't design non-persistent VPC tier
-        when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(true);
-        assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
-    }
-
-    @Test
-    public void testDesignNoIsolationMethodVSP() {
-        when(physnet.getIsolationMethods()).thenReturn(Collections.singletonList("VLAN"));
-
-        final NetworkOffering offering = mockNetworkOffering(false);
-
-        final DeploymentPlan plan = mockDeploymentPlan();
-        final Network network = mock(Network.class);
-
-        assertThat(_nuageVspGuestNetworkGuru.design(offering, plan, network, _account), nullValue(Network.class));
-    }
-
-    @Test
-    public void testReserve() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
-        final NetworkVO network = mockNetwork();
-        final NicProfile nicProfile = mockNicProfile();
-        final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Starting);
-
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
-
-        _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
-
-        verify(_agentManager).easySend(anyLong(), any(Command.class));
-    }
-
-    @Test
-    public void testReserveVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
-        final NetworkVO network = mockNetwork();
-        final NicProfile nicProfile = mockNicProfile();
-        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Starting);
-
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
-
-        _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), _reservationContext);
-
-        verifyZeroInteractions(_agentManager);
-        verify(network).setRollingRestart(true);
-    }
-
-    @Test
-    public void testImplementNetwork() throws URISyntaxException, InsufficientVirtualNetworkCapacityException {
-        final NetworkVO network = mockNetwork();
-
-        when(network.getState()).thenReturn(com.cloud.network.Network.State.Implementing);
-
-        final NetworkOffering offering = mockNetworkOffering(false);
-
-        final DeployDestination deployDest = mock(DeployDestination.class);
-        when(deployDest.getDataCenter()).thenReturn(_dc);
-        _nuageVspGuestNetworkGuru.implement(network, offering, deployDest, _reservationContext);
-    }
-
-    @Test
-    public void testDeallocate() throws Exception {
-        final NetworkVO network = mockNetwork();
-        final NicProfile nicProfile = mockNicProfile();
-        final VirtualMachineProfile vmProfile = mockVirtualMachineProfile(VirtualMachine.State.Expunging);
-
-        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
-    }
-
-    @Test
-    public void testDeallocateVR() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
-        final NetworkVO network = mockNetwork();
-        final NicProfile nicProfile = mockNicProfile();
-        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
-
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
-
-        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
-    }
-
-    @Test
-    public void testDeallocateVRRollingRestart() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException {
-        final NetworkVO network = mockNetwork();
-        final NicProfile nicProfile = mockNicProfile();
-        final VirtualMachineProfile vmProfile = mockVRProfile(VirtualMachine.State.Expunging);
-
-        DomainRouterVO newVR = mock(DomainRouterVO.class);
-
-        when(_routerDao.listByNetworkAndRole(NETWORK_ID, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(Collections.singletonList(newVR));
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
-
-        _nuageVspGuestNetworkGuru.deallocate(network, nicProfile, vmProfile);
-
-        ArgumentCaptor<Command> argumentCaptor = ArgumentCaptor.forClass(Command.class);
-        verify(_agentManager, times(2)).easySend(eq(HOST_ID), argumentCaptor.capture());
-        final List<Command> commands = argumentCaptor.getAllValues();
-        assertThat(commands.get(0) instanceof DeallocateVmVspCommand, is(true));
-        assertThat(commands.get(1) instanceof ReserveVmInterfaceVspCommand, is(true));
-    }
-
-    @Test
-    public void testTrash() throws Exception {
-        final NetworkVO network = mock(NetworkVO.class);
-        when(network.getId()).thenReturn(NETWORK_ID);
-        when(network.getUuid()).thenReturn(NETWORK_UUID);
-        when(network.getName()).thenReturn("trash");
-        when(network.getDomainId()).thenReturn(DOMAIN_ID);
-        when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
-        when(network.getVpcId()).thenReturn(null);
-        when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
-
-        final NetworkOffering offering = mockNetworkOffering(false);
-
-        when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList<>());
-        when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList<>());
-
-        assertTrue(_nuageVspGuestNetworkGuru.trash(network, offering));
-    }
-
-    @Nonnull
-    private NetworkVO mockNetwork() throws URISyntaxException {
-        final NetworkVO network = mock(NetworkVO.class);
-        when(network.getId()).thenReturn(NETWORK_ID);
-        when(network.getUuid()).thenReturn(NETWORK_UUID);
-        when(network.getDataCenterId()).thenReturn(DATACENTER_ID);
-        when(network.getNetworkOfferingId()).thenReturn(OFFERING_ID);
-        when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
-        when(network.getDomainId()).thenReturn(DOMAIN_ID);
-        when(network.getAccountId()).thenReturn(ACCOUNT_ID);
-        when(network.getVpcId()).thenReturn(null);
-        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(network.getMode()).thenReturn(Mode.Dhcp);
-        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp);
-        when(network.getBroadcastUri()).thenReturn(new URI("vsp://" + NETWORK_UUID + "/10.1.1.1"));
-        when(network.getGateway()).thenReturn("10.1.1.1");
-        when(network.getCidr()).thenReturn("10.1.1.0/24");
-        when(network.getName()).thenReturn("iso");
-
-        when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network);
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(network);
-
-        return network;
-    }
-
-    @Nonnull
-    private NetworkOffering mockNetworkOffering(boolean forVpc) {
-        final NetworkOfferingVO offering = mock(NetworkOfferingVO.class);
-        when(offering.getId()).thenReturn(OFFERING_ID);
-        when(offering.getUuid()).thenReturn(OFFERING_UUID);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-        when(offering.getForVpc()).thenReturn(forVpc);
-        when(offering.getIsPersistent()).thenReturn(false);
-        when(offering.getTags()).thenReturn("aaaa");
-        when(offering.getEgressDefaultPolicy()).thenReturn(true);
-
-        when(_networkOfferingDao.findById(OFFERING_ID)).thenReturn(offering);
-
-        when(_configurationManager.isOfferingForVpc(offering)).thenReturn(forVpc);
-
-        when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
-        when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(OFFERING_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
-
-        when(_networkModel.getNetworkOfferingServiceProvidersMap(OFFERING_ID)).thenReturn(ImmutableMap.of(
-                Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp),
-                Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp)
-        ));
-
-        return offering;
-    }
-
-    private DeploymentPlan mockDeploymentPlan() {
-        final DeploymentPlan deploymentPlan = mock(DeploymentPlan.class);
-        when(deploymentPlan.getDataCenterId()).thenReturn(DATACENTER_ID);
-        return deploymentPlan;
-    }
-
-    private DataCenterVO mockDataCenter() {
-        DataCenterVO dc = mock(DataCenterVO.class);
-        when(dc.getId()).thenReturn(DATACENTER_ID);
-        when(dc.getUuid()).thenReturn(DATACENTER_UUID);
-        when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
-        when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
-        when(_dataCenterDao.findById(DATACENTER_ID)).thenReturn(dc);
-
-        return dc;
-    }
-
-    @Nonnull
-    private Account getMockAccount() {
-        final AccountVO account = mock(AccountVO.class);
-        when(account.getId()).thenReturn(ACCOUNT_ID);
-        when(account.getAccountId()).thenReturn(ACCOUNT_ID);
-        when(account.getUuid()).thenReturn(ACCOUNT_UUID);
-        when(account.getDomainId()).thenReturn(DOMAIN_ID);
-        when(account.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL);
-
-        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);
-
-        return account;
-    }
-
-    @Nonnull
-    private Domain getMockDomain() {
-        final DomainVO domain = mock(DomainVO.class);
-        when(domain.getId()).thenReturn(DOMAIN_ID);
-        when(domain.getUuid()).thenReturn(DOMAIN_UUID);
-        when(domain.getName()).thenReturn("aaaaa");
-
-        when(_domainDao.findById(DOMAIN_ID)).thenReturn(domain);
-
-        return domain;
-    }
-
-    @Nonnull
-    private VirtualMachineProfile mockVirtualMachineProfile(VirtualMachine.State state) {
-        final VirtualMachine vm = mock(VirtualMachine.class);
-        when(vm.getId()).thenReturn(VM_ID);
-        when(vm.getType()).thenReturn(VirtualMachine.Type.User);
-        when(vm.getState()).thenReturn(state);
-
-        final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
-        when(vmProfile.getType()).thenReturn(VirtualMachine.Type.User);
-        when(vmProfile.getInstanceName()).thenReturn("Test-VM");
-        when(vmProfile.getUuid()).thenReturn(VM_UUID);
-        when(vmProfile.getVirtualMachine()).thenReturn(vm);
-        return vmProfile;
-    }
-
-    @Nonnull
-    private VirtualMachineProfile mockVRProfile(VirtualMachine.State state) {
-        final VirtualMachine vm = mock(VirtualMachine.class);
-        when(vm.getId()).thenReturn(VM_ID);
-        when(vm.getUuid()).thenReturn(VM_UUID);
-        when(vm.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vm.getState()).thenReturn(state);
-
-
-        final VirtualMachineProfile vmProfile = mock(VirtualMachineProfile.class);
-        when(vmProfile.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
-        when(vmProfile.getInstanceName()).thenReturn("Test-VR");
-        when(vmProfile.getId()).thenReturn(VM_ID);
-        when(vmProfile.getUuid()).thenReturn(VM_UUID);
-        when(vmProfile.getVirtualMachine()).thenReturn(vm);
-        when(vmProfile.isRollingRestart()).thenReturn(true);
-        return vmProfile;
-    }
-
-    @Nonnull
-    private NicProfile mockNicProfile() {
-        final NicVO nicvo = mock(NicVO.class);
-        when(nicvo.getId()).thenReturn(NIC_ID);
-        when(nicvo.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
-        when(nicvo.getIPv4Address()).thenReturn("10.10.10.10");
-        when(nicvo.getUuid()).thenReturn("aaaa-fffff");
-        when(nicvo.getNetworkId()).thenReturn(NETWORK_ID);
-        when(nicvo.getInstanceId()).thenReturn(VM_ID);
-        when(_nicDao.findById(NIC_ID)).thenReturn(nicvo);
-        when(_nicDao.findDefaultNicForVM(VM_ID)).thenReturn(nicvo);
-
-        NicProfile nicProfile = mock(NicProfile.class);
-        when(nicProfile.getUuid()).thenReturn("aaa-bbbb");
-        when(nicProfile.getId()).thenReturn(NIC_ID);
-        when(nicProfile.getMacAddress()).thenReturn("c8:60:00:56:e5:58");
-        when(nicProfile.getIPv4Address()).thenReturn("10.10.10.10");
-        return nicProfile;
-    }
-
-    @Nonnull
-    private static ReservationContext getMockReservationContext(Account networksAccount, Domain networksDomain) {
-        final ReservationContext reservationContext = mock(ReservationContext.class);
-        when(reservationContext.getAccount()).thenReturn(networksAccount);
-        when(reservationContext.getDomain()).thenReturn(networksDomain);
-        return reservationContext;
-    }
-
-}
diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java
deleted file mode 100644
index b34b1a8..0000000
--- a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java
+++ /dev/null
@@ -1,435 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import net.nuage.vsp.acs.client.api.model.Protocol;
-import net.nuage.vsp.acs.client.api.model.VspAclRule;
-import net.nuage.vsp.acs.client.api.model.VspDomain;
-import net.nuage.vsp.acs.client.api.model.VspNetwork;
-import net.nuage.vsp.acs.client.api.model.VspNic;
-import net.nuage.vsp.acs.client.api.model.VspStaticNat;
-import net.nuage.vsp.acs.client.api.model.VspVm;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-
-import com.google.common.collect.Lists;
-
-import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
-
-import com.cloud.NuageTest;
-import com.cloud.dc.VlanDetailsVO;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.dc.dao.VlanDetailsDao;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.manager.NuageVspManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.net.Ip;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-
-
-public class NuageVspEntityBuilderTest extends NuageTest {
-
-    private static final long DOMAIN_ID = 1L;
-    private static final long ACCOUNT_ID = 1L;
-    private static final long NETWORK_OFFERING_ID = 1L;
-    private static final long SHARED_NETWORK_OFFERING_ID = 2L;
-    private static final long L2_NETWORK_OFFERING_ID = 3L;
-    private static final long VPC_ID = 1L;
-    private static final long SOURCE_IP_ADDRESS_ID = 1L;
-    private static final long VM_ID = 4L;
-    private static final long VLAN_ID = 5L;
-    public static final String VM_IP = "192.168.0.24";
-
-    @Mock private AccountDao _accountDao;
-    @Mock private DomainDao _domainDao;
-    @Mock private IPAddressDao _ipAddressDao;
-    @Mock private NetworkDao _networkDao;
-    @Mock private NetworkDetailsDao _networkDetailsDao;
-    @Mock private NetworkOfferingDao _networkOfferingDao;
-    @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
-    @Mock private NicDao _nicDao;
-    @Mock private NicSecondaryIpDao _nicSecondaryIpDao;
-    @Mock private VlanDao _vlanDao;
-    @Mock private VlanDetailsDao _vlanDetailsDao;
-    @Mock private VpcDao _vpcDao;
-    @Mock private VpcDetailsDao _vpcDetailsDao;
-
-    @Mock private NuageVspManager _nuageVspManager;
-
-    @InjectMocks
-    private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder();
-
-    private DomainVO _mockedDomain = mock(DomainVO.class);
-    private AccountVO _mockedAccount = mock(AccountVO.class);
-    private NetworkOfferingVO _mockedNetworkOffering = mock(NetworkOfferingVO.class);
-    private NetworkOfferingVO _mockedSharedNetworkOffering = mock(NetworkOfferingVO.class);
-    private NetworkOfferingVO _mockedL2NetworkOffering = mock(NetworkOfferingVO.class);
-    private VlanVO _mockedVlan = mock(VlanVO.class);
-    private VlanDetailsVO _mockedVlanDetail = mock(VlanDetailsVO.class);
-    private VpcVO _mockedVpc = mock(VpcVO.class);
-    private NetworkVO _mockedNetwork = mock(NetworkVO.class);
-    private NetworkVO _mockedVpcNetwork = mock(NetworkVO.class);
-    private NetworkVO _mockedSharedNetwork = mock(NetworkVO.class);
-    private NetworkVO _mockedL2Network = mock(NetworkVO.class);
-    private VirtualMachine _mockedUserVirtualMachine = mock(VirtualMachine.class);
-    private VirtualMachine _mockedDomainRouterVirtualMachine = mock(VirtualMachine.class);
-    private NicProfile _mockedNicProfile = mock(NicProfile.class);
-    private NicVO _mockedNic = mock(NicVO.class);
-    private IPAddressVO _mockedStaticNatIp = mock(IPAddressVO.class);
-    private VlanVO _mockedStaticNatVlan = mock(VlanVO.class);
-    private FirewallRule _mockedFirewallRule = mock(FirewallRule.class);
-    private NetworkACLItem _mockedNetworkAclItem = mock(NetworkACLItem.class);
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        setUpMockedDomain();
-        setUpMockedAccount();
-        setUpMockedNetworkOffering(_mockedNetworkOffering, Network.GuestType.Isolated);
-        setUpMockedNetworkOffering(_mockedSharedNetworkOffering, Network.GuestType.Shared);
-        setUpMockedNetworkOffering(_mockedL2NetworkOffering, Network.GuestType.Isolated);
-        setUpMockedVlan();
-        setUpMockedVlanDetail();
-        setUpMockedVpc();
-        setUpMockedNetwork(_mockedNetwork, NETWORK_OFFERING_ID, null);
-        setUpMockedNetwork(_mockedVpcNetwork, NETWORK_OFFERING_ID, VPC_ID);
-        setUpMockedNetwork(_mockedSharedNetwork, SHARED_NETWORK_OFFERING_ID, null);
-        setUpMockedNetwork(_mockedL2Network, L2_NETWORK_OFFERING_ID, null);
-        setUpMockedVirtualMachine(_mockedUserVirtualMachine, false);
-        setUpMockedVirtualMachine(_mockedDomainRouterVirtualMachine, true);
-        setUpMockedNicProfile();
-        setUpMockedNic();
-        setUpMockedStaticNatIp();
-        setUpMockedStaticNatVlan();
-        setUpMockedFirewallRule();
-        setUpMockedNetworkAclItem();
-        setUpMockedDaoCalls();
-    }
-
-    @Test
-    public void testBuildVspDomain() {
-        VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(_mockedDomain);
-        validateVspDomain(vspDomain);
-    }
-
-    @Test
-    public void testBuildVspNetwork() {
-        VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network);
-        validateVspNetwork(vspNetwork, true, false, false, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network);
-        validateVspNetwork(vspNetwork, true, false, false, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork);
-        validateVspNetwork(vspNetwork, false, true, false, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork);
-        validateVspNetwork(vspNetwork, false, true, false, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork);
-        validateVspNetwork(vspNetwork, false, false, true, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork);
-        validateVspNetwork(vspNetwork, false, false, true, false);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork);
-        validateVspNetwork(vspNetwork, false, false, false, true);
-
-        vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork);
-        validateVspNetwork(vspNetwork, false, false, false, true);
-    }
-
-    @Test
-    public void testBuildVspVm() {
-        VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(_mockedUserVirtualMachine, _mockedNetwork);
-        validateVspVm(vspVm, false);
-
-        vspVm = _nuageVspEntityBuilder.buildVspVm(_mockedDomainRouterVirtualMachine, _mockedNetwork);
-        validateVspVm(vspVm, true);
-    }
-
-    @Test
-    public void testBuildVspNic() {
-        VspNic vspNic = _nuageVspEntityBuilder.buildVspNic("nicUuid", _mockedNicProfile);
-        validateVspNic(vspNic);
-
-        vspNic = _nuageVspEntityBuilder.buildVspNic(_mockedNic);
-        validateVspNic(vspNic);
-    }
-
-    @Test
-    public void testBuildVspStaticNat() {
-        VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(true, _mockedStaticNatIp, _mockedStaticNatVlan, _mockedNic);
-        validateVspStaticNat(vspStaticNat, true);
-    }
-
-    @Test
-    public void testBuildVspAclRuleAcl() {
-        VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedNetworkAclItem);
-        validateVspAclRule(vspAclRule, false);
-    }
-
-    @Test
-    public void testBuildVspAclRuleFirewall() {
-        VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedFirewallRule, _mockedNetwork);
-        validateVspAclRule(vspAclRule, true);
-    }
-
-    private void validateVspDomain(VspDomain vspDomain) {
-        assertEquals("domainUuid", vspDomain.getUuid());
-        assertEquals("domainName", vspDomain.getName());
-        assertEquals("domainPath", vspDomain.getPath());
-    }
-
-    private void validateVspNetwork(VspNetwork vspNetwork, boolean isL2, boolean isL3, boolean isVpc, boolean isShared) {
-        assertEquals(NETWORK_ID, vspNetwork.getId());
-        assertEquals("networkUuid", vspNetwork.getUuid());
-        assertEquals("networkName", vspNetwork.getName());
-        assertNotNull(vspNetwork.getVspDomain());
-        validateVspDomain(vspNetwork.getVspDomain());
-
-        assertEquals("accountName", vspNetwork.getAccountName());
-        assertEquals("accountUuid", vspNetwork.getAccountUuid());
-
-        if (isVpc) {
-            assertEquals("vpcUuid", vspNetwork.getVpcUuid());
-            assertEquals("vpcName", vspNetwork.getVpcName());
-        } else {
-            assertNull(vspNetwork.getVpcUuid());
-            assertNull(vspNetwork.getVpcName());
-        }
-
-        assertEquals(isL2, vspNetwork.isL2());
-        assertEquals(isL3, vspNetwork.isL3());
-        assertEquals(isVpc, vspNetwork.isVpc());
-        assertEquals(isShared, vspNetwork.isShared());
-        assertEquals(true, vspNetwork.isFirewallServiceSupported());
-        assertEquals(true, vspNetwork.isEgressDefaultPolicy());
-        assertEquals("10.10.10.0/24", vspNetwork.getCidr());
-        assertEquals("10.10.10.1", vspNetwork.getGateway());
-    }
-
-    private void validateVspVm(VspVm vspVm, boolean isDomainRouter) {
-        assertEquals("virtualMachineUuid", vspVm.getUuid());
-        assertEquals("virtualMachineInstanceName", vspVm.getName());
-        assertEquals(VspVm.State.Running, vspVm.getState());
-        assertEquals(isDomainRouter, vspVm.getDomainRouter());
-    }
-
-    private void validateVspNic(VspNic vspNic) {
-        assertEquals("nicUuid", vspNic.getUuid());
-        assertEquals("macAddress", vspNic.getMacAddress());
-        assertEquals(true, vspNic.getUseStaticIp());
-        assertEquals("192.168.0.24", vspNic.getIp());
-    }
-
-    private void validateVspStaticNat(VspStaticNat vspStaticNat, Boolean forRevoke) {
-        assertEquals("staticNatIpUuid", vspStaticNat.getIpUuid());
-        assertEquals("10.10.10.2", vspStaticNat.getIpAddress());
-        assertEquals(forRevoke, vspStaticNat.getRevoke());
-        assertEquals(VspStaticNat.State.Allocated, vspStaticNat.getState());
-        assertEquals(true, vspStaticNat.getOneToOneNat());
-        assertEquals("staticNatVlanUuid", vspStaticNat.getVlanUuid());
-        assertEquals("10.10.10.1", vspStaticNat.getVlanGateway());
-        assertEquals("255.255.255.0", vspStaticNat.getVlanNetmask());
-    }
-
-    private void validateVspAclRule(VspAclRule vspAclRule, boolean isFirewall) {
-        assertEquals("aclUuid", vspAclRule.getUuid());
-        assertEquals(Protocol.TCP, vspAclRule.getProtocol());
-        assertEquals(new Integer(1), vspAclRule.getStartPort());
-        assertEquals(new Integer(20), vspAclRule.getEndPort());
-        assertEquals(Lists.newArrayList("10.10.0.0/16"), vspAclRule.getSourceCidrList());
-        assertEquals(VspAclRule.ACLState.Active, vspAclRule.getState());
-        assertEquals(VspAclRule.ACLTrafficType.Egress, vspAclRule.getTrafficType());
-
-        if (isFirewall) {
-            assertEquals(VspAclRule.ACLType.Firewall, vspAclRule.getType());
-            final VspStaticNat staticNat = vspAclRule.getStaticNat();
-            assertNotNull(staticNat);
-            assertEquals("192.168.0.24/32", staticNat.getDestinationIp());
-            assertEquals(VspAclRule.ACLAction.Deny, vspAclRule.getAction());
-        } else {
-            assertEquals(VspAclRule.ACLType.NetworkACL, vspAclRule.getType());
-            assertNull(vspAclRule.getStaticNat());
-            assertNull(vspAclRule.getSourceIpAddress());
-            assertEquals(VspAclRule.ACLAction.Allow, vspAclRule.getAction());
-        }
-    }
-
-    private void setUpMockedDomain() {
-        when(_mockedDomain.getUuid()).thenReturn("domainUuid");
-        when(_mockedDomain.getName()).thenReturn("domainName");
-        when(_mockedDomain.getPath()).thenReturn("domainPath");
-    }
-
-    private void setUpMockedAccount() {
-        when(_mockedAccount.getUuid()).thenReturn("accountUuid");
-        when(_mockedAccount.getAccountName()).thenReturn("accountName");
-    }
-
-    private void setUpMockedNetworkOffering(NetworkOfferingVO networkOfferingToMock, Network.GuestType guestType) {
-        when(networkOfferingToMock.getEgressDefaultPolicy()).thenReturn(true);
-        when(networkOfferingToMock.getGuestType()).thenReturn(guestType);
-    }
-
-    private void setUpMockedVlan() {
-        when(_mockedVlan.getIpRange()).thenReturn("192.168.2.2-192.168.2.200");
-    }
-
-    private void setUpMockedVlanDetail() {
-        when(_mockedVlanDetail.getValue()).thenReturn("true");
-    }
-
-    private void setUpMockedVpc() {
-        when(_mockedVpc.getUuid()).thenReturn("vpcUuid");
-        when(_mockedVpc.getName()).thenReturn("vpcName");
-    }
-
-    private void setUpMockedNetwork(NetworkVO networkToMock, long networkOfferingId, Long vpcId) {
-        when(networkToMock.getId()).thenReturn(NETWORK_ID);
-        when(networkToMock.getUuid()).thenReturn("networkUuid");
-        when(networkToMock.getName()).thenReturn("networkName");
-        when(networkToMock.getCidr()).thenReturn("10.10.10.0/24");
-        when(networkToMock.getGateway()).thenReturn("10.10.10.1");
-        when(networkToMock.getDomainId()).thenReturn(DOMAIN_ID);
-        when(networkToMock.getAccountId()).thenReturn(ACCOUNT_ID);
-        when(networkToMock.getNetworkOfferingId()).thenReturn(networkOfferingId);
-        when(networkToMock.getVpcId()).thenReturn(vpcId != null ? vpcId : null);
-    }
-
-    private void setUpMockedVirtualMachine(VirtualMachine virtualMachineToMock, boolean isDomainRouter) {
-        when(virtualMachineToMock.getUuid()).thenReturn("virtualMachineUuid");
-        when(virtualMachineToMock.getInstanceName()).thenReturn("virtualMachineInstanceName");
-        when(virtualMachineToMock.getState()).thenReturn(VirtualMachine.State.Running);
-        when(virtualMachineToMock.getType()).thenReturn(isDomainRouter ? VirtualMachine.Type.DomainRouter : VirtualMachine.Type.User);
-    }
-
-    private void setUpMockedNicProfile() {
-        when(_mockedNicProfile.getMacAddress()).thenReturn("macAddress");
-        when(_mockedNicProfile.getIPv4Address()).thenReturn(VM_IP);
-        when(_mockedNicProfile.getNetworkId()).thenReturn(NETWORK_ID);
-    }
-
-    private void setUpMockedNic() {
-        when(_mockedNic.getUuid()).thenReturn("nicUuid");
-        when(_mockedNic.getMacAddress()).thenReturn("macAddress");
-        when(_mockedNic.getIPv4Address()).thenReturn(VM_IP);
-        when(_mockedNic.getNetworkId()).thenReturn(NETWORK_ID);
-    }
-
-    private void setUpMockedStaticNatIp() {
-        when(_mockedStaticNatIp.getUuid()).thenReturn("staticNatIpUuid");
-        when(_mockedStaticNatIp.getAddress()).thenReturn(new Ip("10.10.10.2"));
-        when(_mockedStaticNatIp.isOneToOneNat()).thenReturn(true);
-        when(_mockedStaticNatIp.getVmIp()).thenReturn(VM_IP);
-        when(_mockedStaticNatIp.getAssociatedWithNetworkId()).thenReturn(NETWORK_ID);
-        when(_mockedStaticNatIp.getAssociatedWithVmId()).thenReturn(VM_ID);
-        when(_mockedStaticNatIp.getState()).thenReturn(IpAddress.State.Allocated);
-        when(_mockedStaticNatIp.getVlanId()).thenReturn(VLAN_ID);
-    }
-
-    private void setUpMockedStaticNatVlan() {
-        when(_mockedStaticNatVlan.getUuid()).thenReturn("staticNatVlanUuid");
-        when(_mockedStaticNatVlan.getVlanGateway()).thenReturn("10.10.10.1");
-        when(_mockedStaticNatVlan.getVlanNetmask()).thenReturn("255.255.255.0");
-    }
-
-    private void setUpMockedFirewallRule() {
-        when(_mockedFirewallRule.getUuid()).thenReturn("aclUuid");
-        when(_mockedFirewallRule.getProtocol()).thenReturn("TCP");
-        when(_mockedFirewallRule.getSourcePortStart()).thenReturn(1);
-        when(_mockedFirewallRule.getSourcePortEnd()).thenReturn(20);
-        when(_mockedFirewallRule.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16"));
-        when(_mockedFirewallRule.getState()).thenReturn(FirewallRule.State.Active);
-        when(_mockedFirewallRule.getTrafficType()).thenReturn(FirewallRule.TrafficType.Egress);
-        when(_mockedFirewallRule.getSourceIpAddressId()).thenReturn(SOURCE_IP_ADDRESS_ID);
-    }
-
-    private void setUpMockedNetworkAclItem() {
-        when(_mockedNetworkAclItem.getUuid()).thenReturn("aclUuid");
-        when(_mockedNetworkAclItem.getProtocol()).thenReturn("TCP");
-        when(_mockedNetworkAclItem.getSourcePortStart()).thenReturn(1);
-        when(_mockedNetworkAclItem.getSourcePortEnd()).thenReturn(20);
-        when(_mockedNetworkAclItem.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16"));
-        when(_mockedNetworkAclItem.getNumber()).thenReturn(1337);
-        when(_mockedNetworkAclItem.getState()).thenReturn(NetworkACLItem.State.Active);
-        when(_mockedNetworkAclItem.getTrafficType()).thenReturn(NetworkACLItem.TrafficType.Egress);
-        when(_mockedNetworkAclItem.getAction()).thenReturn(NetworkACLItem.Action.Allow);
-    }
-
-    private void setUpMockedDaoCalls() {
-        when(_domainDao.findById(DOMAIN_ID)).thenReturn(_mockedDomain);
-        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(_mockedAccount);
-        when(_networkDao.findById(NETWORK_ID)).thenReturn(_mockedNetwork);
-        when(_networkOfferingDao.findById(NETWORK_OFFERING_ID)).thenReturn(_mockedNetworkOffering);
-        when(_networkOfferingDao.findById(SHARED_NETWORK_OFFERING_ID)).thenReturn(_mockedSharedNetworkOffering);
-        when(_networkOfferingDao.findById(L2_NETWORK_OFFERING_ID)).thenReturn(_mockedL2NetworkOffering);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(true);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(true);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(true);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(true);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.SourceNat)).thenReturn(false);
-        when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.StaticNat)).thenReturn(false);
-        when(_networkModel.areServicesSupportedByNetworkOffering(NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
-        when(_networkModel.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
-        when(_networkModel.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
-        when(_vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Lists.newArrayList(_mockedVlan));
-        when(_vlanDao.findById(VLAN_ID)).thenReturn(_mockedVlan);
-        when(_vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(_mockedVlanDetail);
-        when(_vpcDao.findById(VPC_ID)).thenReturn(_mockedVpc);
-        when(_ipAddressDao.findById(SOURCE_IP_ADDRESS_ID)).thenReturn(_mockedStaticNatIp);
-        when(_vpcDetailsDao.listDetailsKeyPairs(VPC_ID)).thenReturn(null);
-        when(_nicDao.findByIp4AddressAndNetworkId("192.168.0.24", NETWORK_ID)).thenReturn(_mockedNic);
-    }
-}
diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml
index a650b12..61398f6 100644
--- a/plugins/network-elements/opendaylight/pom.xml
+++ b/plugins/network-elements/opendaylight/pom.xml
@@ -1,86 +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
 
-    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
 
-      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.
-
+  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-network-opendaylight</artifactId>
-  <name>Apache CloudStack Plugin - Network Opendaylight</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-
-  <!-- not parenting to the maven-default pom, as we want this in services -->
-  <build>
-    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
-    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
-    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
-    <outputDirectory>${basedir}/target/classes</outputDirectory>
-    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>${basedir}/src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${basedir}/src/test/resources</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>integration</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+<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-network-opendaylight</artifactId>
+    <name>Apache CloudStack Plugin - Network Opendaylight</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <profiles>
+        <profile>
+            <id>integration</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
index 4e2bf89..e99ec55 100644
--- a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightGuestNetworkGuru.java
@@ -140,7 +140,7 @@
         }
 
         NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
-                network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
+                network.getDataCenterId(), physicalNetworkId, offering.isRedundantRouter());
 
         if (network.getGateway() != null) {
             implemented.setGateway(network.getGateway());
diff --git a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/resources/Action.java b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/resources/Action.java
index 2711fef..0038ffd 100644
--- a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/resources/Action.java
+++ b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/api/resources/Action.java
@@ -175,7 +175,7 @@
                 String errorMessage = responseToErrorMessage(putMethod);
                 putMethod.releaseConnection();
                 s_logger.error("Failed to update object : " + errorMessage);
-                throw new NeutronRestApiException("Failed to create object : " + errorMessage);
+                throw new NeutronRestApiException("Failed to update object : " + errorMessage);
             }
         } catch (NeutronRestApiException e) {
             s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
@@ -207,7 +207,7 @@
                 String errorMessage = responseToErrorMessage(putMethod);
                 putMethod.releaseConnection();
                 s_logger.error("Failed to update object : " + errorMessage);
-                throw new NeutronRestApiException("Failed to create object : " + errorMessage);
+                throw new NeutronRestApiException("Failed to update object : " + errorMessage);
             }
 
             return putMethod.getResponseBodyAsString();
@@ -244,8 +244,8 @@
             if (deleteMethod.getStatusCode() != HttpStatus.SC_NO_CONTENT) {
                 String errorMessage = responseToErrorMessage(deleteMethod);
                 deleteMethod.releaseConnection();
-                s_logger.error("Failed to update object : " + errorMessage);
-                throw new NeutronRestApiException("Failed to create object : " + errorMessage);
+                s_logger.error("Failed to delete object : " + errorMessage);
+                throw new NeutronRestApiException("Failed to delete object : " + errorMessage);
             }
         } catch (NeutronRestApiException e) {
             s_logger.error("NeutronRestApiException caught while trying to execute HTTP Method on the Neutron Controller", e);
diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml
index 3807ab5..a364e61 100644
--- a/plugins/network-elements/ovs/pom.xml
+++ b/plugins/network-elements/ovs/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-ovs</artifactId>
-  <name>Apache CloudStack Plugin - Open vSwitch</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-network-ovs</artifactId>
+    <name>Apache CloudStack Plugin - Open vSwitch</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
deleted file mode 100644
index bfb92f9..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ /dev/null
@@ -1,728 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.element;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.network.topology.NetworkTopology;
-import org.apache.cloudstack.network.topology.NetworkTopologyContext;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupOvsCommand;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkMigrationResponder;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
-import com.cloud.network.ovs.OvsTunnelManager;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.network.rules.LbStickinessMethod;
-import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
-import com.cloud.network.rules.LoadBalancerContainer;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.google.gson.Gson;
-
-public class OvsElement extends AdapterBase implements NetworkElement,
-OvsElementService, ConnectivityProvider, ResourceStateAdapter,
-PortForwardingServiceProvider, LoadBalancingServiceProvider, NetworkMigrationResponder,
-StaticNatServiceProvider, IpDeployer {
-    @Inject
-    OvsTunnelManager _ovsTunnelMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    DataCenterDao _dcDao;
-
-    @Inject
-    NetworkTopologyContext _networkTopologyContext;
-
-    private static final Logger s_logger = Logger.getLogger(OvsElement.class);
-    private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
-
-    @Override
-    public Map<Service, Map<Capability, String>> getCapabilities() {
-        return capabilities;
-    }
-
-    @Override
-    public Provider getProvider() {
-        return Provider.Ovs;
-    }
-
-    protected boolean canHandle(final Network network, final Service service) {
-        s_logger.debug("Checking if OvsElement can handle service "
-                + service.getName() + " on network " + network.getDisplayText());
-        if (network.getBroadcastDomainType() != BroadcastDomainType.Vswitch) {
-            return false;
-        }
-
-        if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
-            s_logger.debug("OvsElement is not a provider for network "
-                    + network.getDisplayText());
-            return false;
-        }
-
-        if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(),
-                service, Network.Provider.Ovs)) {
-            s_logger.debug("OvsElement can't provide the " + service.getName()
-                    + " service on network " + network.getDisplayText());
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params)
-            throws ConfigurationException {
-        super.configure(name, params);
-        _resourceMgr.registerResourceStateAdapter(name, this);
-        return true;
-    }
-
-    @Override
-    public boolean implement(final Network network, final NetworkOffering offering,
-            final DeployDestination dest, final ReservationContext context)
-                    throws ConcurrentOperationException, ResourceUnavailableException,
-                    InsufficientCapacityException {
-        s_logger.debug("entering OvsElement implement function for network "
-                + network.getDisplayText() + " (state " + network.getState()
-                + ")");
-
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean prepare(final Network network, final NicProfile nic,
-            final VirtualMachineProfile vm,
-            final DeployDestination dest, final ReservationContext context)
-                    throws ConcurrentOperationException, ResourceUnavailableException,
-                    InsufficientCapacityException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
-            return false;
-        }
-
-        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
-            return false;
-        }
-
-        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
-            return false;
-        }
-
-        // prepare the tunnel network on the host, in order for VM to get launched
-        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
-
-        return true;
-    }
-
-    @Override
-    public boolean release(final Network network, final NicProfile nic,
-            final VirtualMachineProfile vm,
-            final ReservationContext context) throws ConcurrentOperationException,
-            ResourceUnavailableException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
-            return false;
-        }
-
-        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
-            return false;
-        }
-
-        final HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
-        _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
-        return true;
-    }
-
-    @Override
-    public boolean shutdown(final Network network, final ReservationContext context,
-            final boolean cleanup) throws ConcurrentOperationException,
-            ResourceUnavailableException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean destroy(final Network network, final ReservationContext context)
-            throws ConcurrentOperationException, ResourceUnavailableException {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean isReady(final PhysicalNetworkServiceProvider provider) {
-        return true;
-    }
-
-    @Override
-    public boolean shutdownProviderInstances(
-            final PhysicalNetworkServiceProvider provider, final ReservationContext context)
-                    throws ConcurrentOperationException, ResourceUnavailableException {
-        return true;
-    }
-
-    @Override
-    public boolean canEnableIndividualServices() {
-        return true;
-    }
-
-    @Override
-    public boolean verifyServicesCombination(final Set<Service> services) {
-        if (!services.contains(Service.Connectivity)) {
-            s_logger.warn("Unable to provide services without Connectivity service enabled for this element");
-            return false;
-        }
-
-        return true;
-    }
-
-    private static Map<Service, Map<Capability, String>> setCapabilities() {
-        final Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
-
-        // L2 Support : SDN provisioning
-        final Map<Capability, String> connectivityCapabilities = new HashMap<Capability, String>();
-        connectivityCapabilities.put(Capability.DistributedRouter, null);
-        connectivityCapabilities.put(Capability.StretchedL2Subnet, null);
-        connectivityCapabilities.put(Capability.RegionLevelVpc, null);
-        capabilities.put(Service.Connectivity, connectivityCapabilities);
-
-
-        // L3 Support : Port Forwarding
-        capabilities.put(Service.PortForwarding, null);
-
-        // L3 support : StaticNat
-        capabilities.put(Service.StaticNat, null);
-
-        // L3 support : Load Balancer
-        // Set capabilities for LB service
-        final Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
-        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source");
-        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated");
-        lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp");
-        lbCapabilities.put(Capability.SupportedStickinessMethods, getHAProxyStickinessCapability());
-        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
-
-        capabilities.put(Service.Lb, lbCapabilities);
-
-        return capabilities;
-    }
-
-    public static String getHAProxyStickinessCapability() {
-        LbStickinessMethod method;
-        final List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>(1);
-
-        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method.");
-        method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false);
-        method.addParam("mode", false,
-                "Valid values: insert, rewrite, prefix. Default value: insert.  In the insert mode cookie will be created" +
-                        " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false);
-        method.addParam(
-                "nocache",
-                false,
-                "This option is recommended in conjunction with the insert mode when there is a cache between the client" +
-                        " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if  a cookie needs " +
-                        "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" +
-                        " for instance, then all customers will then fetch the page from an outer cache and will all share the " +
-                        "same persistence cookie, leading to one server receiving much more traffic than others. See also the " +
-                        "insert and postonly options. ",
-                        true);
-        method.addParam(
-                "indirect",
-                false,
-                "When this option is specified in insert mode, cookies will only be added when the server was not reached" +
-                        " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," +
-                        " or after a redispatch, then the cookie  will be inserted. If the client has all the required information" +
-                        " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " +
-                        "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " +
-                        "the server. The persistence mechanism then becomes totally transparent from the application point of view.",
-                        true);
-        method.addParam(
-                "postonly",
-                false,
-                "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" +
-                        " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " +
-                        "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" +
-                        " first POST which generally is a login request, this is a very efficient method to optimize caching " +
-                        "without risking to find a persistence cookie in the cache. See also the insert and nocache options.",
-                        true);
-        method.addParam(
-                "domain",
-                false,
-                "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" +
-                        " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " +
-                        "ending with that name. It is also possible to specify several domain names by invoking this option multiple" +
-                        " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " +
-                        "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.",
-                        false);
-        methodList.add(method);
-
-        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
-                "This is App session based sticky method. Define session stickiness on an existing application cookie. " +
-                "It can be used only for a specific http traffic");
-        method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " +
-                "have to learn for each new session. Default value: Auto geneared based on ip", false);
-        method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " +
-                "each cookie value. Default value:52", false);
-        method.addParam(
-                "holdtime",
-                false,
-                "This is the time after which the cookie will be removed from memory if unused. The value should be in " +
-                        "the format Example : 20s or 30m  or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," +
-                        " cannot use th combinations like 20h30m. Default value:3h ",
-                        false);
-        method.addParam(
-                "request-learn",
-                false,
-                "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability",
-                true);
-        method.addParam(
-                "prefix",
-                false,
-                "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). "
-                        +
-                        "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix  This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.",
-                        true);
-        method.addParam(
-                "mode",
-                false,
-                "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " +
-                        ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " +
-                        "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" +
-                        " In this mode, the parser will look for the appsession in the query string.",
-                        false);
-        methodList.add(method);
-
-        method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " +
-                "it can be used for any type of protocol.");
-        method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" +
-                " or 400g. Default value:200k", false);
-        method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." +
-                " example: expire=30m 20s 50h 4d. Default value:3h", false);
-        methodList.add(method);
-
-        final Gson gson = new Gson();
-        final String capability = gson.toJson(methodList);
-        return capability;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        return cmdList;
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(final HostVO host,
-            final StartupCommand[] cmd) {
-        return null;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(final HostVO host,
-            final StartupCommand[] startup, final ServerResource resource,
-            final Map<String, String> details, final List<String> hostTags) {
-        if (!(startup[0] instanceof StartupOvsCommand)) {
-            return null;
-        }
-        host.setType(Host.Type.L2Networking);
-        return host;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(final HostVO host, final boolean isForced,
-            final boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (!(host.getType() == Host.Type.L2Networking)) {
-            return null;
-        }
-        return new DeleteHostAnswer(true);
-    }
-
-    @Override
-    public IpDeployer getIpDeployer(final Network network) {
-        return this;
-    }
-
-    @Override
-    public boolean applyIps(final Network network,
-            final List<? extends PublicIpAddress> ipAddress, final Set<Service> services)
-                    throws ResourceUnavailableException {
-        boolean canHandle = true;
-        for (final Service service : services) {
-            // check if Ovs can handle services except SourceNat & Firewall
-            if (!canHandle(network, service) && service != Service.SourceNat && service != Service.Firewall) {
-                canHandle = false;
-                break;
-            }
-        }
-        boolean result = true;
-        if (canHandle) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
-                    network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router element doesn't need to associate ip addresses on the backend; virtual "
-                        + "router doesn't exist in the network "
-                        + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules)
-            throws ResourceUnavailableException {
-        if (!canHandle(network, Service.StaticNat)) {
-            return false;
-        }
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
-                network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Ovs element doesn't need to apply static nat on the backend; virtual "
-                    + "router doesn't exist in the network " + network.getId());
-            return true;
-        }
-
-        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-        final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-        boolean result = true;
-        for (final DomainRouterVO domainRouterVO : routers) {
-            result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
-        }
-        return result;
-    }
-
-    @Override
-    public boolean applyPFRules(final Network network, final List<PortForwardingRule> rules)
-            throws ResourceUnavailableException {
-        if (!canHandle(network, Service.PortForwarding)) {
-            return false;
-        }
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
-                network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Ovs element doesn't need to apply firewall rules on the backend; virtual "
-                    + "router doesn't exist in the network " + network.getId());
-            return true;
-        }
-
-        boolean result = true;
-        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-        final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-        for (final DomainRouterVO domainRouterVO : routers) {
-            result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
-        }
-        return result;
-    }
-
-    @Override
-    public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules)
-            throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.Lb)) {
-            if (!canHandleLbRules(rules)) {
-                return false;
-            }
-
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
-                    network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual "
-                        + "router doesn't exist in the network "
-                        + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
-                if (!result) {
-                    s_logger.debug("Failed to apply load balancing rules in network " + network.getId());
-                }
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean validateLBRule(final Network network, final LoadBalancingRule rule) {
-        final List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
-        rules.add(rule);
-        if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
-                    network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                return true;
-            }
-            return validateHAProxyLBRule(rule);
-        }
-        return true;
-    }
-
-    @Override
-    public List<LoadBalancerTO> updateHealthChecks(final Network network,
-            final List<LoadBalancingRule> lbrules) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean handlesOnlyRulesInTransitionState() {
-        return true;
-    }
-
-    private boolean canHandleLbRules(final List<LoadBalancingRule> rules) {
-        final Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
-        if (!lbCaps.isEmpty()) {
-            final String schemeCaps = lbCaps.get(Capability.LbSchemes);
-            if (schemeCaps != null) {
-                for (final LoadBalancingRule rule : rules) {
-                    if (!schemeCaps.contains(rule.getScheme().toString())) {
-                        s_logger.debug("Scheme " + rules.get(0).getScheme()
-                                + " is not supported by the provider "
-                                + getName());
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    public static boolean validateHAProxyLBRule(final LoadBalancingRule rule) {
-        final String timeEndChar = "dhms";
-
-        for (final LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) {
-            final List<Pair<String, String>> paramsList = stickinessPolicy
-                    .getParams();
-
-            if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(
-                    stickinessPolicy.getMethodName())) {
-
-            } else if (StickinessMethodType.SourceBased.getName()
-                    .equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                String tablesize = "200k"; // optional
-                String expire = "30m"; // optional
-
-                /* overwrite default values with the stick parameters */
-                for (final Pair<String, String> paramKV : paramsList) {
-                    final String key = paramKV.first();
-                    final String value = paramKV.second();
-                    if ("tablesize".equalsIgnoreCase(key)) {
-                        tablesize = value;
-                    }
-                    if ("expire".equalsIgnoreCase(key)) {
-                        expire = value;
-                    }
-                }
-                if (expire != null
-                        && !containsOnlyNumbers(expire, timeEndChar)) {
-                    throw new InvalidParameterValueException(
-                            "Failed LB in validation rule id: " + rule.getId()
-                            + " Cause: expire is not in timeformat: "
-                            + expire);
-                }
-                if (tablesize != null
-                        && !containsOnlyNumbers(tablesize, "kmg")) {
-                    throw new InvalidParameterValueException(
-                            "Failed LB in validation rule id: "
-                                    + rule.getId()
-                                    + " Cause: tablesize is not in size format: "
-                                    + tablesize);
-
-                }
-            } else if (StickinessMethodType.AppCookieBased.getName()
-                    .equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                String length = null; // optional
-                String holdTime = null; // optional
-
-                for (final Pair<String, String> paramKV : paramsList) {
-                    final String key = paramKV.first();
-                    final String value = paramKV.second();
-                    if ("length".equalsIgnoreCase(key)) {
-                        length = value;
-                    }
-                    if ("holdtime".equalsIgnoreCase(key)) {
-                        holdTime = value;
-                    }
-                }
-
-                if (length != null && !containsOnlyNumbers(length, null)) {
-                    throw new InvalidParameterValueException(
-                            "Failed LB in validation rule id: " + rule.getId()
-                            + " Cause: length is not a number: "
-                            + length);
-                }
-                if (holdTime != null
-                        && !containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(
-                                holdTime, null)) {
-                    throw new InvalidParameterValueException(
-                            "Failed LB in validation rule id: " + rule.getId()
-                            + " Cause: holdtime is not in timeformat: "
-                            + holdTime);
-                }
-            }
-        }
-        return true;
-    }
-
-    /*
-     * This function detects numbers like 12 ,32h ,42m .. etc,. 1) plain number
-     * like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here last
-     * character is non-digit but from known characters .
-     */
-    private static boolean containsOnlyNumbers(final String str, final String endChar) {
-        if (str == null) {
-            return false;
-        }
-
-        String number = str;
-        if (endChar != null) {
-            boolean matchedEndChar = false;
-            if (str.length() < 2)
-            {
-                return false; // atleast one numeric and one char. example:
-            }
-            // 3h
-            final char strEnd = str.toCharArray()[str.length() - 1];
-            for (final char c : endChar.toCharArray()) {
-                if (strEnd == c) {
-                    number = str.substring(0, str.length() - 1);
-                    matchedEndChar = true;
-                    break;
-                }
-            }
-            if (!matchedEndChar) {
-                return false;
-            }
-        }
-        try {
-            Integer.parseInt(number);
-        } catch (final NumberFormatException e) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean prepareMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) {
-        if (!canHandle(network, Service.Connectivity)) {
-            return false;
-        }
-
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
-            return false;
-        }
-
-        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
-            return false;
-        }
-
-        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
-            return false;
-        }
-
-        // prepare the tunnel network on the host, in order for VM to get launched
-        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
-
-        return true;
-    }
-
-    @Override
-    public void rollbackMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
-        return;
-    }
-
-    @Override
-    public void commitMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
-        return;
-    }
-}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
deleted file mode 100644
index 50b9857..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.ovs.OvsTunnelManager;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import javax.inject.Inject;
-
-@Component
-public class OvsGuestNetworkGuru extends GuestNetworkGuru {
-    private static final Logger s_logger = Logger
-        .getLogger(OvsGuestNetworkGuru.class);
-
-    @Inject
-    OvsTunnelManager _ovsTunnelMgr;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    VpcDao _vpcDao;
-
-    OvsGuestNetworkGuru() {
-        super();
-        _isolationMethods = new IsolationMethod[] {new IsolationMethod("GRE"),
-            new IsolationMethod("L3"), new IsolationMethod("VLAN")};
-    }
-
-    @Override
-    protected boolean canHandle(NetworkOffering offering,
-        final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
-        // This guru handles only Guest Isolated network that supports Source
-        // nat service
-        if (networkType == NetworkType.Advanced
-            && isMyTrafficType(offering.getTrafficType())
-            && offering.getGuestType() == Network.GuestType.Isolated
-            && isMyIsolationMethod(physicalNetwork)
-            && _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(
-                offering.getId(), Service.Connectivity)) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of Guest networks of type   "
-                + GuestType.Isolated + " in zone of type "
-                + NetworkType.Advanced);
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan,
-        Network userSpecified, Account owner) {
-
-        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan
-            .getPhysicalNetworkId());
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
-            s_logger.debug("Refusing to design this network");
-            return null;
-        }
-        NetworkVO config = (NetworkVO)super.design(offering, plan,
-            userSpecified, owner);
-        if (config == null) {
-            return null;
-        }
-
-        config.setBroadcastDomainType(BroadcastDomainType.Vswitch);
-
-        return config;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering,
-        DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        assert (network.getState() == State.Implementing) : "Why are we implementing "
-            + network;
-
-        long dcId = dest.getDataCenter().getId();
-        NetworkType nwType = dest.getDataCenter().getNetworkType();
-        // get physical network id
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-        // physical network id can be null in Guest Network in Basic zone, so
-        // locate the physical network
-        if (physicalNetworkId == null) {
-            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId,
-                offering.getTags(), offering.getTrafficType());
-        }
-        PhysicalNetworkVO physnet = _physicalNetworkDao
-            .findById(physicalNetworkId);
-
-        if (!canHandle(offering, nwType, physnet)) {
-            s_logger.debug("Refusing to design this network");
-            return null;
-        }
-        NetworkVO implemented = (NetworkVO)super.implement(network, offering,
-            dest, context);
-
-        if (network.getGateway() != null) {
-            implemented.setGateway(network.getGateway());
-        }
-
-        if (network.getCidr() != null) {
-            implemented.setCidr(network.getCidr());
-        }
-
-        implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);
-
-        // for the networks that are part of VPC enabled for distributed routing use scheme vs://vpcid.GRE key for network
-        if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
-            String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
-            Long vpcid= network.getVpcId();
-            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString() + "." + keyStr));
-        }
-
-        return implemented;
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network,
-        VirtualMachineProfile vm,
-        DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-        // TODO Auto-generated method stub
-        super.reserve(nic, network, vm, dest, context);
-    }
-
-    @Override
-    public boolean release(NicProfile nic,
-        VirtualMachineProfile vm,
-        String reservationId) {
-        // TODO Auto-generated method stub
-        return super.release(nic, vm, reservationId);
-    }
-
-    @Override
-    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
-        NetworkVO networkObject = _networkDao.findById(profile.getId());
-        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vswitch
-            || networkObject.getBroadcastUri() == null) {
-            s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork "
-                + networkObject.getDisplayText());
-            return;
-        }
-
-        if (profile.getBroadcastDomainType() == BroadcastDomainType.Vswitch ) {
-            s_logger.debug("Releasing vnet for the network id=" + profile.getId());
-            _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(),
-                    profile.getAccountId(), profile.getReservationId());
-        }
-        profile.setBroadcastUri(null);
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        return super.trash(network, offering);
-    }
-
-    @Override
-    protected void allocateVnet(Network network, NetworkVO implemented,
-        long dcId, long physicalNetworkId, String reservationId)
-        throws InsufficientVirtualNetworkCapacityException {
-        if (network.getBroadcastUri() == null) {
-            String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId,
-                network.getAccountId(), reservationId,
-                UseSystemGuestVlans.valueIn(network.getAccountId()));
-            if (vnet == null) {
-                throw new InsufficientVirtualNetworkCapacityException(
-                    "Unable to allocate vnet as a part of network "
-                        + network + " implement ", DataCenter.class,
-                    dcId);
-            }
-            implemented
-                .setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vnet));
-            ActionEventUtils.onCompletedActionEvent(
-                CallContext.current().getCallingUserId(),
-                network.getAccountId(),
-                EventVO.LEVEL_INFO,
-                EventTypes.EVENT_ZONE_VLAN_ASSIGN,
-                "Assigned Zone Vlan: " + vnet + " Network Id: "
-                    + network.getId(), 0);
-        } else {
-            implemented.setBroadcastUri(network.getBroadcastUri());
-        }
-    }
-
-    boolean isVpcEnabledForDistributedRouter(long vpcId) {
-        VpcVO vpc = _vpcDao.findById(vpcId);
-        return vpc.usesDistributedRouter();
-    }
-}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
deleted file mode 100644
index cde4ee8..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ /dev/null
@@ -1,956 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.ovs;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import javax.persistence.EntityExistsException;
-
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.OvsCreateTunnelAnswer;
-import com.cloud.agent.api.OvsCreateTunnelCommand;
-import com.cloud.agent.api.OvsDestroyBridgeCommand;
-import com.cloud.agent.api.OvsDestroyTunnelCommand;
-import com.cloud.agent.api.OvsFetchInterfaceAnswer;
-import com.cloud.agent.api.OvsFetchInterfaceCommand;
-import com.cloud.agent.api.OvsSetupBridgeCommand;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
-import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
-import com.cloud.agent.manager.Commands;
-import com.cloud.configuration.Config;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetworkTrafficType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.ovs.dao.OvsTunnel;
-import com.cloud.network.ovs.dao.OvsTunnelInterfaceDao;
-import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
-import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
-import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
-import com.cloud.network.ovs.dao.VpcDistributedRouterSeqNoDao;
-import com.cloud.network.ovs.dao.VpcDistributedRouterSeqNoVO;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.network.vpc.NetworkACLVO;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
-    public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
-
-    // boolean _isEnabled;
-    ScheduledExecutorService _executorPool;
-    ScheduledExecutorService _cleanupExecutor;
-
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _physNetTTDao;
-
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    OvsTunnelNetworkDao _tunnelNetworkDao;
-    @Inject
-    OvsTunnelInterfaceDao _tunnelInterfaceDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    OvsNetworkTopologyGuru _ovsNetworkToplogyGuru;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    MessageBus _messageBus;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    @Inject
-    VpcDistributedRouterSeqNoDao _vpcDrSeqNoDao;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params)
-            throws ConfigurationException {
-        _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
-        _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
-
-        // register for network ACL updated for a VPC.
-        _messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
-
-        // register for VM state transition updates
-        VirtualMachine.State.getStateMachine().registerListener(this);
-
-        return true;
-    }
-
-    @DB
-    protected OvsTunnelInterfaceVO createInterfaceRecord(String ip,
-            String netmask, String mac, long hostId, String label) {
-        OvsTunnelInterfaceVO ti = null;
-        try {
-            ti = new OvsTunnelInterfaceVO(ip, netmask, mac, hostId, label);
-            // TODO: Is locking really necessary here?
-            OvsTunnelInterfaceVO lock = _tunnelInterfaceDao
-                    .acquireInLockTable(Long.valueOf(1));
-            if (lock == null) {
-                s_logger.warn("Cannot lock table ovs_tunnel_account");
-                return null;
-            }
-            _tunnelInterfaceDao.persist(ti);
-            _tunnelInterfaceDao.releaseFromLockTable(lock.getId());
-        } catch (EntityExistsException e) {
-            s_logger.debug("A record for the interface for network " + label
-                    + " on host id " + hostId + " already exists");
-        }
-        return ti;
-    }
-
-    private String handleFetchInterfaceAnswer(Answer[] answers, Long hostId) {
-        OvsFetchInterfaceAnswer ans = (OvsFetchInterfaceAnswer)answers[0];
-        if (ans.getResult()) {
-            if (ans.getIp() != null && !("".equals(ans.getIp()))) {
-                OvsTunnelInterfaceVO ti = createInterfaceRecord(ans.getIp(),
-                        ans.getNetmask(), ans.getMac(), hostId, ans.getLabel());
-                return ti.getIp();
-            }
-        }
-        // Fetch interface failed!
-        s_logger.warn("Unable to fetch the IP address for the GRE tunnel endpoint"
-                + ans.getDetails());
-        return null;
-    }
-
-    @DB
-    protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId, int key) {
-        OvsTunnelNetworkVO ta = null;
-        try {
-            ta = new OvsTunnelNetworkVO(from, to, key, networkId);
-            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
-            if (lock == null) {
-                s_logger.warn("Cannot lock table ovs_tunnel_account");
-                return null;
-            }
-            _tunnelNetworkDao.persist(ta);
-            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
-        } catch (EntityExistsException e) {
-            s_logger.debug("A record for the tunnel from " + from + " to " + to + " already exists");
-        }
-        return ta;
-    }
-
-    private void handleCreateTunnelAnswer(Answer[] answers) {
-        OvsCreateTunnelAnswer r = (OvsCreateTunnelAnswer)answers[0];
-        String s =
-                String.format("(hostIP:%1$s, remoteIP:%2$s, bridge:%3$s," + "greKey:%4$s, portName:%5$s)",
-                        r.getFromIp(), r.getToIp(), r.getBridge(), r.getKey(), r.getInPortName());
-        Long from = r.getFrom();
-        Long to = r.getTo();
-        long networkId = r.getNetworkId();
-        OvsTunnelNetworkVO tunnel = _tunnelNetworkDao.getByFromToNetwork(from, to, networkId);
-        if (tunnel == null) {
-            throw new CloudRuntimeException(
-                    String.format("Unable find tunnelNetwork record" +
-                            "(from=%1$s,to=%2$s, account=%3$s",
-                            from, to, networkId));
-        }
-        if (!r.getResult()) {
-            tunnel.setState(OvsTunnel.State.Failed.name());
-            s_logger.warn("Create GRE tunnel from " + from + " to " + to + " failed due to " + r.getDetails()
-                    + s);
-        } else {
-            tunnel.setState(OvsTunnel.State.Established.name());
-            tunnel.setPortName(r.getInPortName());
-            s_logger.info("Create GRE tunnel from " + from + " to " + to + " succeeded." + r.getDetails() + s);
-        }
-        _tunnelNetworkDao.update(tunnel.getId(), tunnel);
-    }
-
-    private String getGreEndpointIP(Host host, Network nw)
-            throws AgentUnavailableException, OperationTimedoutException {
-        String endpointIp = null;
-        // Fetch fefault name for network label from configuration
-        String physNetLabel = _configDao.getValue(Config.OvsTunnelNetworkDefaultLabel.key());
-        Long physNetId = nw.getPhysicalNetworkId();
-        PhysicalNetworkTrafficType physNetTT =
-                _physNetTTDao.findBy(physNetId, TrafficType.Guest);
-        HypervisorType hvType = host.getHypervisorType();
-
-        String label = null;
-        switch (hvType) {
-        case XenServer:
-            label = physNetTT.getXenNetworkLabel();
-            if ((label != null) && (!label.equals(""))) {
-                physNetLabel = label;
-            }
-            break;
-        case KVM:
-            label = physNetTT.getKvmNetworkLabel();
-            if ((label != null) && (!label.equals(""))) {
-                physNetLabel = label;
-            }
-            break;
-        default:
-            throw new CloudRuntimeException("Hypervisor " +
-                    hvType.toString() +
-                    " unsupported by OVS Tunnel Manager");
-        }
-
-        // Try to fetch GRE endpoint IP address for cloud db
-        // If not found, then find it on the hypervisor
-        OvsTunnelInterfaceVO tunnelIface =
-                _tunnelInterfaceDao.getByHostAndLabel(host.getId(),
-                        physNetLabel);
-        if (tunnelIface == null) {
-            //Now find and fetch configuration for physical interface
-            //for network with label on target host
-            Commands fetchIfaceCmds =
-                    new Commands(new OvsFetchInterfaceCommand(physNetLabel));
-            s_logger.debug("Ask host " + host.getId() +
-                    " to retrieve interface for phy net with label:" +
-                    physNetLabel);
-            Answer[] fetchIfaceAnswers = _agentMgr.send(host.getId(), fetchIfaceCmds);
-            //And finally save it for future use
-            endpointIp = handleFetchInterfaceAnswer(fetchIfaceAnswers, host.getId());
-        } else {
-            endpointIp = tunnelIface.getIp();
-        }
-        return endpointIp;
-    }
-
-    private int getGreKey(Network network) {
-        int key = 0;
-        try {
-            //The GRE key is actually in the host part of the URI
-            String keyStr = network.getBroadcastUri().getAuthority();
-            if (keyStr.contains(".")) {
-                String[] parts = keyStr.split("\\.");
-                key = Integer.parseInt(parts[1]);
-            } else {
-                key = Integer.parseInt(keyStr);
-            }
-
-            return key;
-        } catch (NumberFormatException e) {
-            s_logger.debug("Well well, how did '" + key
-                    + "' end up in the broadcast URI for the network?");
-            throw new CloudRuntimeException(String.format(
-                    "Invalid GRE key parsed from"
-                            + "network broadcast URI (%s)", network
-                            .getBroadcastUri().toString()));
-        }
-    }
-
-    @DB
-    protected void checkAndCreateTunnel(Network nw, Host host) {
-
-        s_logger.debug("Creating tunnels with OVS tunnel manager");
-
-        long hostId = host.getId();
-        int key = getGreKey(nw);
-        String bridgeName = generateBridgeName(nw, key);
-        List<Long> toHostIds = new ArrayList<Long>();
-        List<Long> fromHostIds = new ArrayList<Long>();
-        List<Long> networkSpannedHosts = _ovsNetworkToplogyGuru.getNetworkSpanedHosts(nw.getId());
-        for (Long rh : networkSpannedHosts) {
-            if (rh == hostId) {
-                continue;
-            }
-            OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), nw.getId());
-            // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
-                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
-                if (ta == null) {
-                    createTunnelRecord(hostId, rh.longValue(), nw.getId(), key);
-                }
-                if (!toHostIds.contains(rh)) {
-                    toHostIds.add(rh);
-                }
-            }
-
-            ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
-                    hostId, nw.getId());
-            // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
-                s_logger.debug("Attempting to create tunnel from:" +
-                        rh.longValue() + " to:" + hostId);
-                if (ta == null) {
-                    createTunnelRecord(rh.longValue(), hostId,
-                            nw.getId(), key);
-                }
-                if (!fromHostIds.contains(rh)) {
-                    fromHostIds.add(rh);
-                }
-            }
-        }
-        //TODO: Should we propagate the exception here?
-        try {
-            String myIp = getGreEndpointIP(host, nw);
-            if (myIp == null)
-                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + host.getId());
-            boolean noHost = true;
-            for (Long i : toHostIds) {
-                HostVO rHost = _hostDao.findById(i);
-                String otherIp = getGreEndpointIP(rHost, nw);
-                if (otherIp == null)
-                    throw new GreTunnelException(
-                            "Unable to retrieve the remote "
-                                    + "endpoint for the GRE tunnel."
-                                    + "Failure is on host:" + rHost.getId());
-                Commands cmds = new Commands(
-                        new OvsCreateTunnelCommand(otherIp, key,
-                                Long.valueOf(hostId), i, nw.getId(), myIp, bridgeName, nw.getUuid()));
-                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network " + nw.getId());
-                s_logger.debug("Ask host " + hostId
-                        + " to create gre tunnel to " + i);
-                Answer[] answers = _agentMgr.send(hostId, cmds);
-                handleCreateTunnelAnswer(answers);
-                noHost = false;
-            }
-
-            for (Long i : fromHostIds) {
-                HostVO rHost = _hostDao.findById(i);
-                String otherIp = getGreEndpointIP(rHost, nw);
-                Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
-                        key, i, Long.valueOf(hostId), nw.getId(), otherIp, bridgeName, nw.getUuid()));
-                s_logger.debug("Ask host " + i + " to create gre tunnel to "
-                        + hostId);
-                Answer[] answers = _agentMgr.send(i, cmds);
-                handleCreateTunnelAnswer(answers);
-                noHost = false;
-            }
-
-            // If no tunnels have been configured, perform the bridge setup
-            // anyway. This will ensure VIF rules will be triggered
-            if (noHost) {
-                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, nw.getId()));
-                s_logger.debug("Ask host " + hostId + " to configure bridge for network:" + nw.getId());
-                Answer[] answers = _agentMgr.send(hostId, cmds);
-                handleSetupBridgeAnswer(answers);
-            }
-        } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
-            // I really thing we should do a better handling of these exceptions
-            s_logger.warn("Ovs Tunnel network created tunnel failed", e);
-        }
-    }
-
-    @Override
-    public boolean isOvsTunnelEnabled() {
-        return true;
-    }
-
-    boolean isVpcEnabledForDistributedRouter(long vpcId) {
-        VpcVO vpc = _vpcDao.findById(vpcId);
-        return vpc.usesDistributedRouter();
-    }
-
-    @Override
-    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host) {
-        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
-            // check and setup host to be in full tunnel mesh with each of the network in the VPC
-            checkAndCreateVpcTunnelNetworks(host, nw.getVpcId());
-        } else {
-            // check and setup host to be in full tunnel mesh with the network
-            checkAndCreateTunnel(nw, host);
-        }
-    }
-
-    @DB
-    private void handleDestroyTunnelAnswer(Answer ans, long from, long to, long networkId) {
-        if (ans.getResult()) {
-            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
-            if (lock == null) {
-                s_logger.warn(String.format("failed to lock" +
-                        "ovs_tunnel_account, remove record of " +
-                        "tunnel(from=%1$s, to=%2$s account=%3$s) failed",
-                        from, to, networkId));
-                return;
-            }
-
-            _tunnelNetworkDao.removeByFromToNetwork(from, to, networkId);
-            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
-
-            s_logger.debug(String.format("Destroy tunnel(account:%1$s," +
-                    "from:%2$s, to:%3$s) successful",
-                    networkId, from, to));
-        } else {
-            s_logger.debug(String.format("Destroy tunnel(account:%1$s," + "from:%2$s, to:%3$s) failed", networkId, from, to));
-        }
-    }
-
-    @DB
-    private void handleDestroyBridgeAnswer(Answer ans, long hostId, long networkId) {
-
-        if (ans.getResult()) {
-            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
-            if (lock == null) {
-                s_logger.warn("failed to lock ovs_tunnel_network," + "remove record");
-                return;
-            }
-
-            _tunnelNetworkDao.removeByFromNetwork(hostId, networkId);
-            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
-
-            s_logger.debug(String.format("Destroy bridge for" +
-                    "network %1$s successful", networkId));
-        } else {
-            s_logger.debug(String.format("Destroy bridge for" +
-                    "network %1$s failed", networkId));
-        }
-    }
-
-    private void handleSetupBridgeAnswer(Answer[] answers) {
-        //TODO: Add some error management here?
-        s_logger.debug("Placeholder for something more meanginful to come");
-    }
-
-    @Override
-    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
-
-        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
-            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(nw.getVpcId(), host.getId());
-
-            if (vmIds != null && !vmIds.isEmpty()) {
-                return;
-            }
-
-            // there are not active VM's on this host belonging to any of the tiers in the VPC, so remove
-            // the host from the tunnel mesh network and destroy the bridge
-            List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(nw.getVpcId());
-            try {
-                for (Network network: vpcNetworks) {
-                    int key = getGreKey(nw);
-                    String bridgeName = generateBridgeName(nw, key);
-                    /* Then ask hosts have peer tunnel with me to destroy them */
-                    List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(host.getId(),nw.getId());
-                    for (OvsTunnelNetworkVO p : peers) {
-                        // If the tunnel was not successfully created don't bother to remove it
-                        if (p.getState().equals(OvsTunnel.State.Established.name())) {
-                            Command cmd= new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
-                                    p.getPortName());
-                            s_logger.debug("Destroying tunnel to " + host.getId() +
-                                    " from " + p.getFrom());
-                            Answer ans = _agentMgr.send(p.getFrom(), cmd);
-                            handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
-                        }
-                    }
-                }
-
-                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), generateBridgeNameForVpc(nw.getVpcId()),
-                        host.getId());
-                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
-                Answer ans = _agentMgr.send(host.getId(), cmd);
-                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
-            } catch (Exception e) {
-                s_logger.info("[ignored]"
-                        + "exception while removing host from networks: " + e.getLocalizedMessage());
-            }
-        } else {
-            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInNetworkOnHost(nw.getId(), host.getId(), true);
-            if (vmIds != null && !vmIds.isEmpty()) {
-                return;
-            }
-            try {
-                /* Now we are last one on host, destroy the bridge with all
-                * the tunnels for this network  */
-                int key = getGreKey(nw);
-                String bridgeName = generateBridgeName(nw, key);
-                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName, host.getId());
-                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
-                Answer ans = _agentMgr.send(host.getId(), cmd);
-                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
-
-                /* Then ask hosts have peer tunnel with me to destroy them */
-                List<OvsTunnelNetworkVO> peers =
-                        _tunnelNetworkDao.listByToNetwork(host.getId(),
-                                nw.getId());
-                for (OvsTunnelNetworkVO p : peers) {
-                    // If the tunnel was not successfully created don't bother to remove it
-                    if (p.getState().equals(OvsTunnel.State.Established.name())) {
-                        cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
-                                p.getPortName());
-                        s_logger.debug("Destroying tunnel to " + host.getId() +
-                                " from " + p.getFrom());
-                        ans = _agentMgr.send(p.getFrom(), cmd);
-                        handleDestroyTunnelAnswer(ans, p.getFrom(),
-                                p.getTo(), p.getNetworkId());
-                    }
-                }
-            } catch (Exception e) {
-                s_logger.warn("Destroy tunnel failed", e);
-            }
-        }
-    }
-
-    private String generateBridgeName(Network nw, int key) {
-        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
-            return "OVS-DR-VPC-Bridge" + nw.getVpcId();
-        } else {
-            return "OVSTunnel"+key;
-        }
-    }
-    private String generateBridgeNameForVpc(long vpcId) {
-        return "OVS-DR-VPC-Bridge" + vpcId;
-    }
-
-    @DB
-    protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
-
-        long hostId = host.getId();
-        String bridgeName=generateBridgeNameForVpc(vpcId);
-
-        List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(vpcId, hostId);
-
-        if (vmIds == null || vmIds.isEmpty()) {
-
-            // since this is the first VM from the VPC being launched on the host, first setup the bridge
-            try {
-                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, null));
-                s_logger.debug("Ask host " + hostId + " to create bridge for vpc " + vpcId + " and configure the "
-                        + " bridge for distributed routing.");
-                Answer[] answers = _agentMgr.send(hostId, cmds);
-                handleSetupBridgeAnswer(answers);
-            } catch (OperationTimedoutException | AgentUnavailableException e) {
-                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
-            }
-
-            // now that bridge is setup, populate network acl's before the VM gets created
-            OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
-            cmd.setSequenceNumber(getNextRoutingPolicyUpdateSequenceNumber(vpcId));
-
-            if (!sendVpcRoutingPolicyChangeUpdate(cmd, hostId, bridgeName)) {
-                s_logger.debug("Failed to send VPC routing policy change update to host : " + hostId +
-                        ". But moving on with sending the updates to the rest of the hosts.");
-            }
-        }
-
-        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
-        List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
-        for (Network vpcNetwork: vpcNetworks) {
-            if (vpcNetwork.getState() != Network.State.Implemented &&
-                    vpcNetwork.getState() != Network.State.Implementing && vpcNetwork.getState() != Network.State.Setup)
-                continue;
-
-            int key = getGreKey(vpcNetwork);
-            List<Long> toHostIds = new ArrayList<Long>();
-            List<Long> fromHostIds = new ArrayList<Long>();
-            OvsTunnelNetworkVO tunnelRecord = null;
-
-            for (Long rh : vpcSpannedHostIds) {
-                if (rh == hostId) {
-                    continue;
-                }
-                tunnelRecord = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), vpcNetwork.getId());
-                // Try and create the tunnel if does not exit or previous attempt failed
-                if (tunnelRecord == null || tunnelRecord.getState().equals(OvsTunnel.State.Failed.name())) {
-                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
-                    if (tunnelRecord == null) {
-                        createTunnelRecord(hostId, rh.longValue(), vpcNetwork.getId(), key);
-                    }
-                    if (!toHostIds.contains(rh)) {
-                        toHostIds.add(rh);
-                    }
-                }
-                tunnelRecord = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(), hostId, vpcNetwork.getId());
-                // Try and create the tunnel if does not exit or previous attempt failed
-                if (tunnelRecord == null || tunnelRecord.getState().equals(OvsTunnel.State.Failed.name())) {
-                    s_logger.debug("Attempting to create tunnel from:" + rh.longValue() + " to:" + hostId);
-                    if (tunnelRecord == null) {
-                        createTunnelRecord(rh.longValue(), hostId, vpcNetwork.getId(), key);
-                    }
-                    if (!fromHostIds.contains(rh)) {
-                        fromHostIds.add(rh);
-                    }
-                }
-            }
-
-            try {
-                String myIp = getGreEndpointIP(host, vpcNetwork);
-                if (myIp == null)
-                    throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel."
-                            + "Failure is on host:" + host.getId());
-                boolean noHost = true;
-
-                for (Long i : toHostIds) {
-                    HostVO rHost = _hostDao.findById(i);
-                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
-                    if (otherIp == null)
-                        throw new GreTunnelException(
-                                "Unable to retrieve the remote endpoint for the GRE tunnel."
-                                        + "Failure is on host:" + rHost.getId());
-                    Commands cmds = new Commands( new OvsCreateTunnelCommand(otherIp, key, Long.valueOf(hostId),
-                                     i, vpcNetwork.getId(), myIp, bridgeName, vpcNetwork.getUuid()));
-                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network "
-                            + vpcNetwork.getId());
-                    s_logger.debug("Ask host " + hostId
-                            + " to create gre tunnel to " + i);
-                    Answer[] answers = _agentMgr.send(hostId, cmds);
-                    handleCreateTunnelAnswer(answers);
-                }
-
-                for (Long i : fromHostIds) {
-                    HostVO rHost = _hostDao.findById(i);
-                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
-                    Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
-                            key, i, Long.valueOf(hostId), vpcNetwork.getId(), otherIp, bridgeName,
-                            vpcNetwork.getUuid()));
-                    s_logger.debug("Ask host " + i + " to create gre tunnel to "
-                            + hostId);
-                    Answer[] answers = _agentMgr.send(i, cmds);
-                    handleCreateTunnelAnswer(answers);
-                }
-            } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
-                // I really thing we should do a better handling of these exceptions
-                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
-            }
-        }
-    }
-
-    @Override
-    public boolean preStateTransitionEvent(VirtualMachine.State oldState,
-                                           VirtualMachine.Event event, VirtualMachine.State newState,
-                                           VirtualMachine vo, boolean status, Object opaque) {
-        return true;
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, VirtualMachine vm, boolean status, Object opaque) {
-      if (!status) {
-        return false;
-      }
-
-      VirtualMachine.State oldState = transition.getCurrentState();
-      VirtualMachine.State newState = transition.getToState();
-      VirtualMachine.Event event = transition.getEvent();
-      if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
-        handleVmStateChange((VMInstanceVO)vm);
-      } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
-        handleVmStateChange((VMInstanceVO)vm);
-      } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
-        handleVmStateChange((VMInstanceVO)vm);
-      }
-
-      return true;
-    }
-
-  private void handleVmStateChange(VMInstanceVO vm) {
-
-        // get the VPC's impacted with the VM start
-        List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
-        if (vpcIds == null || vpcIds.isEmpty()) {
-            return;
-        }
-
-        for (Long vpcId: vpcIds) {
-            VpcVO vpc = _vpcDao.findById(vpcId);
-            // nothing to do if the VPC is not setup for distributed routing
-            if (vpc == null || !vpc.usesDistributedRouter()) {
-                return;
-            }
-
-            // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
-            List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
-            String bridgeName=generateBridgeNameForVpc(vpcId);
-
-            OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
-            topologyConfigCommand.setSequenceNumber(getNextTopologyUpdateSequenceNumber(vpcId));
-
-            // send topology change update to VPC spanned hosts
-            for (Long id: vpcSpannedHostIds) {
-                if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
-                    s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on " +
-                            "with rest of the host update.");
-                }
-            }
-        }
-    }
-
-    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
-        try {
-            s_logger.debug("Sending VPC topology change update to the host " + hostId);
-            updateCmd.setHostId(hostId);
-            updateCmd.setBridgeName(bridgeName);
-            Answer ans = _agentMgr.send(hostId, updateCmd);
-            if (ans.getResult()) {
-                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
-                return true;
-            }  else {
-                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
-                return false;
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology.", e );
-            return false;
-        }
-    }
-
-    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
-        VpcVO vpc = _vpcDao.findById(vpcId);
-        assert (vpc != null): "invalid vpc id";
-
-        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
-        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
-        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
-
-        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
-
-        for (Long hostId : hostIds) {
-            HostVO hostDetails = _hostDao.findById(hostId);
-            String remoteIp = null;
-            for (Network network: vpcNetworks) {
-                try {
-                    remoteIp = getGreEndpointIP(hostDetails, network);
-                } catch (Exception e) {
-                    s_logger.info("[ignored]"
-                            + "error getting GRE endpoint: " + e.getLocalizedMessage());
-                }
-            }
-            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
-            hosts.add(host);
-        }
-
-        for (Network network: vpcNetworks) {
-            String key = network.getBroadcastUri().getAuthority();
-            long gre_key;
-            if (key.contains(".")) {
-                String[] parts = key.split("\\.");
-                gre_key = Long.parseLong(parts[1]);
-            } else {
-                try {
-                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
-                } catch (Exception e) {
-                    return null;
-                }
-            }
-            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
-            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
-                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
-            tiers.add(tier);
-        }
-
-        for (long vmId: vmIds) {
-            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
-            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
-            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
-                Network network = _networkDao.findById(vmNic.getNetworkId());
-                if (network.getTrafficType() == TrafficType.Guest) {
-                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
-                            vmNic.getIPv4Address(), vmNic.getMacAddress(), network.getUuid());
-                    vmNics.add(nic);
-                }
-            }
-            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
-                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
-            vms.add(vm);
-        }
-
-        return new OvsVpcPhysicalTopologyConfigCommand(
-                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
-                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
-                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
-                vpc.getCidr());
-    }
-
-    // Subscriber to ACL replace events. On acl replace event, if the vpc for the tier is enabled for
-    // distributed routing send the ACL update to all the hosts on which VPC spans
-    public class NetworkAclEventsSubscriber implements MessageSubscriber {
-        @Override
-        public void onPublishMessage(String senderAddress, String subject, Object args) {
-            try {
-                NetworkVO network = (NetworkVO) args;
-                String bridgeName=generateBridgeNameForVpc(network.getVpcId());
-                if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
-                    long vpcId = network.getVpcId();
-                    OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
-                    cmd.setSequenceNumber(getNextRoutingPolicyUpdateSequenceNumber(vpcId));
-
-                    // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC
-                    // network ACL update)
-                    List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
-                    for (Long id: vpcSpannedHostIds) {
-                        if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
-                            s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
-                                    ". But moving on with sending the updates to the rest of the hosts.");
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                s_logger.debug("Failed to send VPC routing policy change updates all hosts in vpc", e);
-            }
-        }
-    }
-
-    private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
-
-        List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();
-        List<OvsVpcRoutingPolicyConfigCommand.Tier> tiers = new ArrayList<>();
-
-        VpcVO vpc = _vpcDao.findById(vpcId);
-        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
-        assert (vpc != null && (vpcNetworks != null && !vpcNetworks.isEmpty())): "invalid vpc id";
-
-        for (Network network : vpcNetworks) {
-            Long networkAclId = network.getNetworkACLId();
-            if (networkAclId == null)
-                continue;
-            NetworkACLVO networkAcl = _networkACLDao.findById(networkAclId);
-
-            List<OvsVpcRoutingPolicyConfigCommand.AclItem> aclItems = new ArrayList<>();
-            List<NetworkACLItemVO> aclItemVos = _networkACLItemDao.listByACL(networkAclId);
-            for (NetworkACLItemVO aclItem : aclItemVos) {
-                String[] sourceCidrs = aclItem.getSourceCidrList().toArray(new String[aclItem.getSourceCidrList().size()]);
-
-                aclItems.add(new OvsVpcRoutingPolicyConfigCommand.AclItem(
-                        aclItem.getNumber(), aclItem.getUuid(), aclItem.getAction().name(),
-                        aclItem.getTrafficType().name(),
-                        ((aclItem.getSourcePortStart() != null) ?aclItem.getSourcePortStart().toString() :null),
-                        ((aclItem.getSourcePortEnd() != null) ?aclItem.getSourcePortEnd().toString() :null),
-                        aclItem.getProtocol(),
-                        sourceCidrs));
-            }
-
-            OvsVpcRoutingPolicyConfigCommand.Acl acl = new OvsVpcRoutingPolicyConfigCommand.Acl(networkAcl.getUuid(),
-                    aclItems.toArray(new OvsVpcRoutingPolicyConfigCommand.AclItem[aclItems.size()]));
-            acls.add(acl);
-
-            OvsVpcRoutingPolicyConfigCommand.Tier tier = new OvsVpcRoutingPolicyConfigCommand.Tier(network.getUuid(),
-                    network.getCidr(), networkAcl.getUuid());
-            tiers.add(tier);
-        }
-
-        OvsVpcRoutingPolicyConfigCommand cmd = new OvsVpcRoutingPolicyConfigCommand(vpc.getUuid(), vpc.getCidr(),
-                acls.toArray(new OvsVpcRoutingPolicyConfigCommand.Acl[acls.size()]),
-                tiers.toArray(new OvsVpcRoutingPolicyConfigCommand.Tier[tiers.size()]));
-        return cmd;
-    }
-
-    private boolean sendVpcRoutingPolicyChangeUpdate(OvsVpcRoutingPolicyConfigCommand updateCmd, long hostId, String bridgeName) {
-        try {
-            s_logger.debug("Sending VPC routing policies change update to the host " + hostId);
-            updateCmd.setHostId(hostId);
-            updateCmd.setBridgeName(bridgeName);
-            Answer ans = _agentMgr.send(hostId, updateCmd);
-            if (ans.getResult()) {
-                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC routing policies." );
-                return true;
-            }  else {
-                s_logger.debug("Failed to update the host " + hostId + " with latest routing policies." );
-                return false;
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to updated the host " + hostId + " with latest routing policies due to" , e );
-            return false;
-        }
-    }
-
-    private long getNextTopologyUpdateSequenceNumber(final long vpcId) {
-
-        try {
-            return  Transaction.execute(new TransactionCallback<Long>() {
-                @Override
-                public Long doInTransaction(TransactionStatus status) {
-                    VpcDistributedRouterSeqNoVO seqVo = _vpcDrSeqNoDao.findByVpcId(vpcId);
-                    if (seqVo == null) {
-                        seqVo = new VpcDistributedRouterSeqNoVO(vpcId);
-                        _vpcDrSeqNoDao.persist(seqVo);
-                    }
-                    seqVo = _vpcDrSeqNoDao.lockRow(seqVo.getId(), true);
-                    seqVo.incrTopologyUpdateSequenceNo();
-                    _vpcDrSeqNoDao.update(seqVo.getId(), seqVo);
-                    return seqVo.getTopologyUpdateSequenceNo();
-                }
-            });
-        } finally {
-
-        }
-    }
-
-    private long getNextRoutingPolicyUpdateSequenceNumber(final long vpcId) {
-
-        try {
-            return  Transaction.execute(new TransactionCallback<Long>() {
-                @Override
-                public Long doInTransaction(TransactionStatus status) {
-                    VpcDistributedRouterSeqNoVO seqVo = _vpcDrSeqNoDao.findByVpcId(vpcId);
-                    if (seqVo == null) {
-                        seqVo = new VpcDistributedRouterSeqNoVO(vpcId);
-                        _vpcDrSeqNoDao.persist(seqVo);
-                    }
-                    seqVo = _vpcDrSeqNoDao.lockRow(seqVo.getId(), true);
-                    seqVo.incrPolicyUpdateSequenceNo();
-                    _vpcDrSeqNoDao.update(seqVo.getId(), seqVo);
-                    return seqVo.getPolicyUpdateSequenceNo();
-                }
-            });
-        } finally {
-
-        }
-    }
-}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java
deleted file mode 100644
index 1c7f493..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.ovs.dao;
-
-import java.util.List;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface OvsTunnelNetworkDao extends GenericDao<OvsTunnelNetworkVO, Long> {
-    OvsTunnelNetworkVO getByFromToNetwork(long from, long to, long networkId);
-
-    void removeByFromNetwork(long from, long networkId);
-
-    void removeByFromToNetwork(long from, long to, long networkId);
-
-    List<OvsTunnelNetworkVO> listByToNetwork(long to, long networkId);
-}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java
deleted file mode 100644
index 5e314f0..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.ovs.dao;
-
-import java.util.List;
-
-
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-
-@Component
-public class OvsTunnelNetworkDaoImpl extends GenericDaoBase<OvsTunnelNetworkVO, Long> implements OvsTunnelNetworkDao {
-
-    protected final SearchBuilder<OvsTunnelNetworkVO> fromToNetworkSearch;
-    protected final SearchBuilder<OvsTunnelNetworkVO> fromNetworkSearch;
-    protected final SearchBuilder<OvsTunnelNetworkVO> toNetworkSearch;
-
-    public OvsTunnelNetworkDaoImpl() {
-        fromToNetworkSearch = createSearchBuilder();
-        fromToNetworkSearch.and("from", fromToNetworkSearch.entity().getFrom(), Op.EQ);
-        fromToNetworkSearch.and("to", fromToNetworkSearch.entity().getTo(), Op.EQ);
-        fromToNetworkSearch.and("network_id", fromToNetworkSearch.entity().getNetworkId(), Op.EQ);
-        fromToNetworkSearch.done();
-
-        fromNetworkSearch = createSearchBuilder();
-        fromNetworkSearch.and("from", fromNetworkSearch.entity().getFrom(), Op.EQ);
-        fromNetworkSearch.and("network_id", fromNetworkSearch.entity().getNetworkId(), Op.EQ);
-        fromNetworkSearch.done();
-
-        toNetworkSearch = createSearchBuilder();
-        toNetworkSearch.and("to", toNetworkSearch.entity().getTo(), Op.EQ);
-        toNetworkSearch.and("network_id", toNetworkSearch.entity().getNetworkId(), Op.EQ);
-        toNetworkSearch.done();
-    }
-
-    @Override
-    public OvsTunnelNetworkVO getByFromToNetwork(long from, long to, long networkId) {
-        SearchCriteria<OvsTunnelNetworkVO> sc = fromToNetworkSearch.create();
-        sc.setParameters("from", from);
-        sc.setParameters("to", to);
-        sc.setParameters("network_id", networkId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public void removeByFromNetwork(long from, long networkId) {
-        SearchCriteria<OvsTunnelNetworkVO> sc = fromNetworkSearch.create();
-        sc.setParameters("from", from);
-        sc.setParameters("network_id", networkId);
-        remove(sc);
-    }
-
-    @Override
-    public List<OvsTunnelNetworkVO> listByToNetwork(long to, long networkId) {
-        SearchCriteria<OvsTunnelNetworkVO> sc = toNetworkSearch.create();
-        sc.setParameters("to", to);
-        sc.setParameters("network_id", networkId);
-        return listBy(sc);
-    }
-
-    @Override
-    public void removeByFromToNetwork(long from, long to, long networkId) {
-        SearchCriteria<OvsTunnelNetworkVO> sc = fromToNetworkSearch.create();
-        sc.setParameters("from", from);
-        sc.setParameters("to", to);
-        sc.setParameters("network_id", networkId);
-        remove(sc);
-    }
-
-}
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateGreTunnelAnswer.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateGreTunnelAnswer.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateGreTunnelAnswer.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateGreTunnelAnswer.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateGreTunnelCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateGreTunnelCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateGreTunnelCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateGreTunnelCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelAnswer.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateTunnelAnswer.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelAnswer.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateTunnelAnswer.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateTunnelCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsCreateTunnelCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDeleteFlowCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDeleteFlowCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDeleteFlowCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDeleteFlowCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDestroyBridgeCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDestroyBridgeCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDestroyTunnelCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsDestroyTunnelCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsFetchInterfaceAnswer.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsFetchInterfaceAnswer.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsFetchInterfaceAnswer.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsFetchInterfaceAnswer.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsFetchInterfaceCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsFetchInterfaceCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsFetchInterfaceCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsFetchInterfaceCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetTagAndFlowAnswer.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetTagAndFlowAnswer.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetTagAndFlowAnswer.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetTagAndFlowAnswer.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetTagAndFlowCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetTagAndFlowCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetTagAndFlowCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetTagAndFlowCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetupBridgeCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsSetupBridgeCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/StartupOvsCommand.java b/plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/StartupOvsCommand.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/agent/api/StartupOvsCommand.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/agent/api/StartupOvsCommand.java
diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
new file mode 100644
index 0000000..4e89e7b
--- /dev/null
+++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
@@ -0,0 +1,728 @@
+// 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.network.element;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.network.topology.NetworkTopology;
+import org.apache.cloudstack.network.topology.NetworkTopologyContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupOvsCommand;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationResponder;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
+import com.cloud.network.ovs.OvsTunnelManager;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.rules.LbStickinessMethod;
+import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
+import com.cloud.network.rules.LoadBalancerContainer;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.google.gson.Gson;
+
+public class OvsElement extends AdapterBase implements NetworkElement,
+OvsElementService, ConnectivityProvider, ResourceStateAdapter,
+PortForwardingServiceProvider, LoadBalancingServiceProvider, NetworkMigrationResponder,
+StaticNatServiceProvider, IpDeployer {
+    @Inject
+    OvsTunnelManager _ovsTunnelMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    DataCenterDao _dcDao;
+
+    @Inject
+    NetworkTopologyContext _networkTopologyContext;
+
+    private static final Logger s_logger = Logger.getLogger(OvsElement.class);
+    private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        return capabilities;
+    }
+
+    @Override
+    public Provider getProvider() {
+        return Provider.Ovs;
+    }
+
+    protected boolean canHandle(final Network network, final Service service) {
+        s_logger.debug("Checking if OvsElement can handle service "
+                + service.getName() + " on network " + network.getDisplayText());
+        if (network.getBroadcastDomainType() != BroadcastDomainType.Vswitch) {
+            return false;
+        }
+
+        if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
+            s_logger.debug("OvsElement is not a provider for network "
+                    + network.getDisplayText());
+            return false;
+        }
+
+        if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(),
+                service, Network.Provider.Ovs)) {
+            s_logger.debug("OvsElement can't provide the " + service.getName()
+                    + " service on network " + network.getDisplayText());
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params)
+            throws ConfigurationException {
+        super.configure(name, params);
+        _resourceMgr.registerResourceStateAdapter(name, this);
+        return true;
+    }
+
+    @Override
+    public boolean implement(final Network network, final NetworkOffering offering,
+            final DeployDestination dest, final ReservationContext context)
+                    throws ConcurrentOperationException, ResourceUnavailableException,
+                    InsufficientCapacityException {
+        s_logger.debug("entering OvsElement implement function for network "
+                + network.getDisplayText() + " (state " + network.getState()
+                + ")");
+
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepare(final Network network, final NicProfile nic,
+            final VirtualMachineProfile vm,
+            final DeployDestination dest, final ReservationContext context)
+                    throws ConcurrentOperationException, ResourceUnavailableException,
+                    InsufficientCapacityException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
+            return false;
+        }
+
+        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
+            return false;
+        }
+
+        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
+            return false;
+        }
+
+        // prepare the tunnel network on the host, in order for VM to get launched
+        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
+
+        return true;
+    }
+
+    @Override
+    public boolean release(final Network network, final NicProfile nic,
+            final VirtualMachineProfile vm,
+            final ReservationContext context) throws ConcurrentOperationException,
+            ResourceUnavailableException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
+            return false;
+        }
+
+        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
+            return false;
+        }
+
+        final HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
+        _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
+        return true;
+    }
+
+    @Override
+    public boolean shutdown(final Network network, final ReservationContext context,
+            final boolean cleanup) throws ConcurrentOperationException,
+            ResourceUnavailableException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean destroy(final Network network, final ReservationContext context)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean isReady(final PhysicalNetworkServiceProvider provider) {
+        return true;
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(
+            final PhysicalNetworkServiceProvider provider, final ReservationContext context)
+                    throws ConcurrentOperationException, ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        return true;
+    }
+
+    @Override
+    public boolean verifyServicesCombination(final Set<Service> services) {
+        if (!services.contains(Service.Connectivity)) {
+            s_logger.warn("Unable to provide services without Connectivity service enabled for this element");
+            return false;
+        }
+
+        return true;
+    }
+
+    private static Map<Service, Map<Capability, String>> setCapabilities() {
+        final Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+
+        // L2 Support : SDN provisioning
+        final Map<Capability, String> connectivityCapabilities = new HashMap<Capability, String>();
+        connectivityCapabilities.put(Capability.DistributedRouter, null);
+        connectivityCapabilities.put(Capability.StretchedL2Subnet, null);
+        connectivityCapabilities.put(Capability.RegionLevelVpc, null);
+        capabilities.put(Service.Connectivity, connectivityCapabilities);
+
+
+        // L3 Support : Port Forwarding
+        capabilities.put(Service.PortForwarding, null);
+
+        // L3 support : StaticNat
+        capabilities.put(Service.StaticNat, null);
+
+        // L3 support : Load Balancer
+        // Set capabilities for LB service
+        final Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
+        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source");
+        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated");
+        lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp");
+        lbCapabilities.put(Capability.SupportedStickinessMethods, getHAProxyStickinessCapability());
+        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
+
+        capabilities.put(Service.Lb, lbCapabilities);
+
+        return capabilities;
+    }
+
+    public static String getHAProxyStickinessCapability() {
+        LbStickinessMethod method;
+        final List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>(1);
+
+        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method.");
+        method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false);
+        method.addParam("mode", false,
+                "Valid values: insert, rewrite, prefix. Default value: insert.  In the insert mode cookie will be created" +
+                        " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false);
+        method.addParam(
+                "nocache",
+                false,
+                "This option is recommended in conjunction with the insert mode when there is a cache between the client" +
+                        " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if  a cookie needs " +
+                        "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" +
+                        " for instance, then all customers will then fetch the page from an outer cache and will all share the " +
+                        "same persistence cookie, leading to one server receiving much more traffic than others. See also the " +
+                        "insert and postonly options. ",
+                        true);
+        method.addParam(
+                "indirect",
+                false,
+                "When this option is specified in insert mode, cookies will only be added when the server was not reached" +
+                        " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," +
+                        " or after a redispatch, then the cookie  will be inserted. If the client has all the required information" +
+                        " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " +
+                        "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " +
+                        "the server. The persistence mechanism then becomes totally transparent from the application point of view.",
+                        true);
+        method.addParam(
+                "postonly",
+                false,
+                "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" +
+                        " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " +
+                        "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" +
+                        " first POST which generally is a login request, this is a very efficient method to optimize caching " +
+                        "without risking to find a persistence cookie in the cache. See also the insert and nocache options.",
+                        true);
+        method.addParam(
+                "domain",
+                false,
+                "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" +
+                        " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " +
+                        "ending with that name. It is also possible to specify several domain names by invoking this option multiple" +
+                        " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " +
+                        "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.",
+                        false);
+        methodList.add(method);
+
+        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
+                "This is App session based sticky method. Define session stickiness on an existing application cookie. " +
+                "It can be used only for a specific http traffic");
+        method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " +
+                "have to learn for each new session. Default value: Auto geneared based on ip", false);
+        method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " +
+                "each cookie value. Default value:52", false);
+        method.addParam(
+                "holdtime",
+                false,
+                "This is the time after which the cookie will be removed from memory if unused. The value should be in " +
+                        "the format Example : 20s or 30m  or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," +
+                        " cannot use th combinations like 20h30m. Default value:3h ",
+                        false);
+        method.addParam(
+                "request-learn",
+                false,
+                "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability",
+                true);
+        method.addParam(
+                "prefix",
+                false,
+                "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). "
+                        +
+                        "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix  This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.",
+                        true);
+        method.addParam(
+                "mode",
+                false,
+                "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " +
+                        ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " +
+                        "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" +
+                        " In this mode, the parser will look for the appsession in the query string.",
+                        false);
+        methodList.add(method);
+
+        method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " +
+                "it can be used for any type of protocol.");
+        method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" +
+                " or 400g. Default value:200k", false);
+        method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." +
+                " example: expire=30m 20s 50h 4d. Default value:3h", false);
+        methodList.add(method);
+
+        final Gson gson = new Gson();
+        final String capability = gson.toJson(methodList);
+        return capability;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        return cmdList;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(final HostVO host,
+            final StartupCommand[] cmd) {
+        return null;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(final HostVO host,
+            final StartupCommand[] startup, final ServerResource resource,
+            final Map<String, String> details, final List<String> hostTags) {
+        if (!(startup[0] instanceof StartupOvsCommand)) {
+            return null;
+        }
+        host.setType(Host.Type.L2Networking);
+        return host;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(final HostVO host, final boolean isForced,
+            final boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (!(host.getType() == Host.Type.L2Networking)) {
+            return null;
+        }
+        return new DeleteHostAnswer(true);
+    }
+
+    @Override
+    public IpDeployer getIpDeployer(final Network network) {
+        return this;
+    }
+
+    @Override
+    public boolean applyIps(final Network network,
+            final List<? extends PublicIpAddress> ipAddress, final Set<Service> services)
+                    throws ResourceUnavailableException {
+        boolean canHandle = true;
+        for (final Service service : services) {
+            // check if Ovs can handle services except SourceNat & Firewall
+            if (!canHandle(network, service) && service != Service.SourceNat && service != Service.Firewall) {
+                canHandle = false;
+                break;
+            }
+        }
+        boolean result = true;
+        if (canHandle) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+                    network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router element doesn't need to associate ip addresses on the backend; virtual "
+                        + "router doesn't exist in the network "
+                        + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules)
+            throws ResourceUnavailableException {
+        if (!canHandle(network, Service.StaticNat)) {
+            return false;
+        }
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+                network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            s_logger.debug("Ovs element doesn't need to apply static nat on the backend; virtual "
+                    + "router doesn't exist in the network " + network.getId());
+            return true;
+        }
+
+        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+        final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+        boolean result = true;
+        for (final DomainRouterVO domainRouterVO : routers) {
+            result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean applyPFRules(final Network network, final List<PortForwardingRule> rules)
+            throws ResourceUnavailableException {
+        if (!canHandle(network, Service.PortForwarding)) {
+            return false;
+        }
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+                network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            s_logger.debug("Ovs element doesn't need to apply firewall rules on the backend; virtual "
+                    + "router doesn't exist in the network " + network.getId());
+            return true;
+        }
+
+        boolean result = true;
+        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+        final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+        for (final DomainRouterVO domainRouterVO : routers) {
+            result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules)
+            throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.Lb)) {
+            if (!canHandleLbRules(rules)) {
+                return false;
+            }
+
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+                    network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply load balancing rules on the backend; virtual "
+                        + "router doesn't exist in the network "
+                        + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
+                if (!result) {
+                    s_logger.debug("Failed to apply load balancing rules in network " + network.getId());
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean validateLBRule(final Network network, final LoadBalancingRule rule) {
+        final List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
+        rules.add(rule);
+        if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(
+                    network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                return true;
+            }
+            return validateHAProxyLBRule(rule);
+        }
+        return true;
+    }
+
+    @Override
+    public List<LoadBalancerTO> updateHealthChecks(final Network network,
+            final List<LoadBalancingRule> lbrules) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean handlesOnlyRulesInTransitionState() {
+        return true;
+    }
+
+    private boolean canHandleLbRules(final List<LoadBalancingRule> rules) {
+        final Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
+        if (!lbCaps.isEmpty()) {
+            final String schemeCaps = lbCaps.get(Capability.LbSchemes);
+            if (schemeCaps != null) {
+                for (final LoadBalancingRule rule : rules) {
+                    if (!schemeCaps.contains(rule.getScheme().toString())) {
+                        s_logger.debug("Scheme " + rules.get(0).getScheme()
+                                + " is not supported by the provider "
+                                + getName());
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    public static boolean validateHAProxyLBRule(final LoadBalancingRule rule) {
+        final String timeEndChar = "dhms";
+
+        for (final LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) {
+            final List<Pair<String, String>> paramsList = stickinessPolicy
+                    .getParams();
+
+            if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(
+                    stickinessPolicy.getMethodName())) {
+
+            } else if (StickinessMethodType.SourceBased.getName()
+                    .equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                String tablesize = "200k"; // optional
+                String expire = "30m"; // optional
+
+                /* overwrite default values with the stick parameters */
+                for (final Pair<String, String> paramKV : paramsList) {
+                    final String key = paramKV.first();
+                    final String value = paramKV.second();
+                    if ("tablesize".equalsIgnoreCase(key)) {
+                        tablesize = value;
+                    }
+                    if ("expire".equalsIgnoreCase(key)) {
+                        expire = value;
+                    }
+                }
+                if (expire != null
+                        && !containsOnlyNumbers(expire, timeEndChar)) {
+                    throw new InvalidParameterValueException(
+                            "Failed LB in validation rule id: " + rule.getId()
+                            + " Cause: expire is not in timeformat: "
+                            + expire);
+                }
+                if (tablesize != null
+                        && !containsOnlyNumbers(tablesize, "kmg")) {
+                    throw new InvalidParameterValueException(
+                            "Failed LB in validation rule id: "
+                                    + rule.getId()
+                                    + " Cause: tablesize is not in size format: "
+                                    + tablesize);
+
+                }
+            } else if (StickinessMethodType.AppCookieBased.getName()
+                    .equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                String length = null; // optional
+                String holdTime = null; // optional
+
+                for (final Pair<String, String> paramKV : paramsList) {
+                    final String key = paramKV.first();
+                    final String value = paramKV.second();
+                    if ("length".equalsIgnoreCase(key)) {
+                        length = value;
+                    }
+                    if ("holdtime".equalsIgnoreCase(key)) {
+                        holdTime = value;
+                    }
+                }
+
+                if (length != null && !containsOnlyNumbers(length, null)) {
+                    throw new InvalidParameterValueException(
+                            "Failed LB in validation rule id: " + rule.getId()
+                            + " Cause: length is not a number: "
+                            + length);
+                }
+                if (holdTime != null
+                        && !containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(
+                                holdTime, null)) {
+                    throw new InvalidParameterValueException(
+                            "Failed LB in validation rule id: " + rule.getId()
+                            + " Cause: holdtime is not in timeformat: "
+                            + holdTime);
+                }
+            }
+        }
+        return true;
+    }
+
+    /*
+     * This function detects numbers like 12 ,32h ,42m .. etc,. 1) plain number
+     * like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here last
+     * character is non-digit but from known characters .
+     */
+    private static boolean containsOnlyNumbers(final String str, final String endChar) {
+        if (str == null) {
+            return false;
+        }
+
+        String number = str;
+        if (endChar != null) {
+            boolean matchedEndChar = false;
+            if (str.length() < 2)
+            {
+                return false; // atleast one numeric and one char. example:
+            }
+            // 3h
+            final char strEnd = str.toCharArray()[str.length() - 1];
+            for (final char c : endChar.toCharArray()) {
+                if (strEnd == c) {
+                    number = str.substring(0, str.length() - 1);
+                    matchedEndChar = true;
+                    break;
+                }
+            }
+            if (!matchedEndChar) {
+                return false;
+            }
+        }
+        try {
+            Integer.parseInt(number);
+        } catch (final NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepareMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) {
+        if (!canHandle(network, Service.Connectivity)) {
+            return false;
+        }
+
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Vswitch) {
+            return false;
+        }
+
+        if (nic.getTrafficType() != Networks.TrafficType.Guest) {
+            return false;
+        }
+
+        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
+            return false;
+        }
+
+        // prepare the tunnel network on the host, in order for VM to get launched
+        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
+
+        return true;
+    }
+
+    @Override
+    public void rollbackMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
+        return;
+    }
+
+    @Override
+    public void commitMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
+        return;
+    }
+}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElementService.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElementService.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/element/OvsElementService.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElementService.java
diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java
new file mode 100644
index 0000000..45969e7
--- /dev/null
+++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -0,0 +1,234 @@
+// 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.network.guru;
+
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.ovs.OvsTunnelManager;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+
+@Component
+public class OvsGuestNetworkGuru extends GuestNetworkGuru {
+    private static final Logger s_logger = Logger
+        .getLogger(OvsGuestNetworkGuru.class);
+
+    @Inject
+    OvsTunnelManager _ovsTunnelMgr;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    VpcDao _vpcDao;
+
+    OvsGuestNetworkGuru() {
+        super();
+        _isolationMethods = new IsolationMethod[] {new IsolationMethod("GRE"),
+            new IsolationMethod("L3"), new IsolationMethod("VLAN")};
+    }
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering,
+        final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+        // This guru handles only Guest Isolated network that supports Source
+        // nat service
+        if (networkType == NetworkType.Advanced
+            && isMyTrafficType(offering.getTrafficType())
+            && offering.getGuestType() == Network.GuestType.Isolated
+            && isMyIsolationMethod(physicalNetwork)
+            && _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(
+                offering.getId(), Service.Connectivity)) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest networks of type   "
+                + GuestType.Isolated + " in zone of type "
+                + NetworkType.Advanced);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan,
+        Network userSpecified, Account owner) {
+
+        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan
+            .getPhysicalNetworkId());
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
+            s_logger.debug("Refusing to design this network");
+            return null;
+        }
+        NetworkVO config = (NetworkVO)super.design(offering, plan,
+            userSpecified, owner);
+        if (config == null) {
+            return null;
+        }
+
+        config.setBroadcastDomainType(BroadcastDomainType.Vswitch);
+
+        return config;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering,
+        DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        assert (network.getState() == State.Implementing) : "Why are we implementing "
+            + network;
+
+        long dcId = dest.getDataCenter().getId();
+        NetworkType nwType = dest.getDataCenter().getNetworkType();
+        // get physical network id
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+        // physical network id can be null in Guest Network in Basic zone, so
+        // locate the physical network
+        if (physicalNetworkId == null) {
+            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId,
+                offering.getTags(), offering.getTrafficType());
+        }
+        PhysicalNetworkVO physnet = _physicalNetworkDao
+            .findById(physicalNetworkId);
+
+        if (!canHandle(offering, nwType, physnet)) {
+            s_logger.debug("Refusing to implement this network");
+            return null;
+        }
+        NetworkVO implemented = (NetworkVO)super.implement(network, offering,
+            dest, context);
+
+        if (network.getGateway() != null) {
+            implemented.setGateway(network.getGateway());
+        }
+
+        if (network.getCidr() != null) {
+            implemented.setCidr(network.getCidr());
+        }
+
+        implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);
+
+        // for the networks that are part of VPC enabled for distributed routing use scheme vs://vpcid.GRE key for network
+        if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
+            String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
+            Long vpcid= network.getVpcId();
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString() + "." + keyStr));
+        }
+
+        return implemented;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network,
+        VirtualMachineProfile vm,
+        DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+        // TODO Auto-generated method stub
+        super.reserve(nic, network, vm, dest, context);
+    }
+
+    @Override
+    public boolean release(NicProfile nic,
+        VirtualMachineProfile vm,
+        String reservationId) {
+        // TODO Auto-generated method stub
+        return super.release(nic, vm, reservationId);
+    }
+
+    @Override
+    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+        NetworkVO networkObject = _networkDao.findById(profile.getId());
+        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vswitch
+            || networkObject.getBroadcastUri() == null) {
+            s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork "
+                + networkObject.getDisplayText());
+            return;
+        }
+
+        if (profile.getBroadcastDomainType() == BroadcastDomainType.Vswitch ) {
+            s_logger.debug("Releasing vnet for the network id=" + profile.getId());
+            _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(),
+                    profile.getAccountId(), profile.getReservationId());
+        }
+        profile.setBroadcastUri(null);
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        return super.trash(network, offering);
+    }
+
+    @Override
+    protected void allocateVnet(Network network, NetworkVO implemented,
+        long dcId, long physicalNetworkId, String reservationId)
+        throws InsufficientVirtualNetworkCapacityException {
+        if (network.getBroadcastUri() == null) {
+            String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId,
+                network.getAccountId(), reservationId,
+                UseSystemGuestVlans.valueIn(network.getAccountId()));
+            if (vnet == null) {
+                throw new InsufficientVirtualNetworkCapacityException(
+                    "Unable to allocate vnet as a part of network "
+                        + network + " implement ", DataCenter.class,
+                    dcId);
+            }
+            implemented
+                .setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vnet));
+            ActionEventUtils.onCompletedActionEvent(
+                CallContext.current().getCallingUserId(),
+                network.getAccountId(),
+                EventVO.LEVEL_INFO,
+                EventTypes.EVENT_ZONE_VLAN_ASSIGN,
+                "Assigned Zone Vlan: " + vnet + " Network Id: "
+                    + network.getId(), 0);
+        } else {
+            implemented.setBroadcastUri(network.getBroadcastUri());
+        }
+    }
+
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
+}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/GreTunnelException.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/GreTunnelException.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/GreTunnelException.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/GreTunnelException.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsTunnelManager.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsTunnelManager.java
diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsTunnelManagerImpl.java
new file mode 100644
index 0000000..aca3609
--- /dev/null
+++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -0,0 +1,956 @@
+// 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.network.ovs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.persistence.EntityExistsException;
+
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.OvsCreateTunnelAnswer;
+import com.cloud.agent.api.OvsCreateTunnelCommand;
+import com.cloud.agent.api.OvsDestroyBridgeCommand;
+import com.cloud.agent.api.OvsDestroyTunnelCommand;
+import com.cloud.agent.api.OvsFetchInterfaceAnswer;
+import com.cloud.agent.api.OvsFetchInterfaceCommand;
+import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
+import com.cloud.agent.manager.Commands;
+import com.cloud.configuration.Config;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.ovs.dao.OvsTunnel;
+import com.cloud.network.ovs.dao.OvsTunnelInterfaceDao;
+import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
+import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
+import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
+import com.cloud.network.ovs.dao.VpcDistributedRouterSeqNoDao;
+import com.cloud.network.ovs.dao.VpcDistributedRouterSeqNoVO;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.NetworkACLVO;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
+    public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
+
+    // boolean _isEnabled;
+    ScheduledExecutorService _executorPool;
+    ScheduledExecutorService _cleanupExecutor;
+
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _physNetTTDao;
+
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    OvsTunnelNetworkDao _tunnelNetworkDao;
+    @Inject
+    OvsTunnelInterfaceDao _tunnelInterfaceDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    OvsNetworkTopologyGuru _ovsNetworkToplogyGuru;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    protected VMInstanceDao _vmInstanceDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    NetworkACLDao _networkACLDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    VpcDistributedRouterSeqNoDao _vpcDrSeqNoDao;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
+        _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
+
+        // register for network ACL updated for a VPC.
+        _messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
+
+        // register for VM state transition updates
+        VirtualMachine.State.getStateMachine().registerListener(this);
+
+        return true;
+    }
+
+    @DB
+    protected OvsTunnelInterfaceVO createInterfaceRecord(String ip,
+            String netmask, String mac, long hostId, String label) {
+        OvsTunnelInterfaceVO ti = null;
+        try {
+            ti = new OvsTunnelInterfaceVO(ip, netmask, mac, hostId, label);
+            // TODO: Is locking really necessary here?
+            OvsTunnelInterfaceVO lock = _tunnelInterfaceDao
+                    .acquireInLockTable(Long.valueOf(1));
+            if (lock == null) {
+                s_logger.warn("Cannot lock table ovs_tunnel_account");
+                return null;
+            }
+            _tunnelInterfaceDao.persist(ti);
+            _tunnelInterfaceDao.releaseFromLockTable(lock.getId());
+        } catch (EntityExistsException e) {
+            s_logger.debug("A record for the interface for network " + label
+                    + " on host id " + hostId + " already exists");
+        }
+        return ti;
+    }
+
+    private String handleFetchInterfaceAnswer(Answer[] answers, Long hostId) {
+        OvsFetchInterfaceAnswer ans = (OvsFetchInterfaceAnswer)answers[0];
+        if (ans.getResult()) {
+            if (ans.getIp() != null && !("".equals(ans.getIp()))) {
+                OvsTunnelInterfaceVO ti = createInterfaceRecord(ans.getIp(),
+                        ans.getNetmask(), ans.getMac(), hostId, ans.getLabel());
+                return ti.getIp();
+            }
+        }
+        // Fetch interface failed!
+        s_logger.warn("Unable to fetch the IP address for the GRE tunnel endpoint"
+                + ans.getDetails());
+        return null;
+    }
+
+    @DB
+    protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId, int key) {
+        OvsTunnelNetworkVO ta = null;
+        try {
+            ta = new OvsTunnelNetworkVO(from, to, key, networkId);
+            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
+            if (lock == null) {
+                s_logger.warn("Cannot lock table ovs_tunnel_account");
+                return null;
+            }
+            _tunnelNetworkDao.persist(ta);
+            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
+        } catch (EntityExistsException e) {
+            s_logger.debug("A record for the tunnel from " + from + " to " + to + " already exists");
+        }
+        return ta;
+    }
+
+    private void handleCreateTunnelAnswer(Answer[] answers) {
+        OvsCreateTunnelAnswer r = (OvsCreateTunnelAnswer)answers[0];
+        String s =
+                String.format("(hostIP:%1$s, remoteIP:%2$s, bridge:%3$s," + "greKey:%4$s, portName:%5$s)",
+                        r.getFromIp(), r.getToIp(), r.getBridge(), r.getKey(), r.getInPortName());
+        Long from = r.getFrom();
+        Long to = r.getTo();
+        long networkId = r.getNetworkId();
+        OvsTunnelNetworkVO tunnel = _tunnelNetworkDao.findByFromToNetwork(from, to, networkId);
+        if (tunnel == null) {
+            throw new CloudRuntimeException(
+                    String.format("Unable find tunnelNetwork record" +
+                            "(from=%1$s,to=%2$s, account=%3$s",
+                            from, to, networkId));
+        }
+        if (!r.getResult()) {
+            tunnel.setState(OvsTunnel.State.Failed.name());
+            s_logger.warn("Create GRE tunnel from " + from + " to " + to + " failed due to " + r.getDetails()
+                    + s);
+        } else {
+            tunnel.setState(OvsTunnel.State.Established.name());
+            tunnel.setPortName(r.getInPortName());
+            s_logger.info("Create GRE tunnel from " + from + " to " + to + " succeeded." + r.getDetails() + s);
+        }
+        _tunnelNetworkDao.update(tunnel.getId(), tunnel);
+    }
+
+    private String getGreEndpointIP(Host host, Network nw)
+            throws AgentUnavailableException, OperationTimedoutException {
+        String endpointIp = null;
+        // Fetch fefault name for network label from configuration
+        String physNetLabel = _configDao.getValue(Config.OvsTunnelNetworkDefaultLabel.key());
+        Long physNetId = nw.getPhysicalNetworkId();
+        PhysicalNetworkTrafficType physNetTT =
+                _physNetTTDao.findBy(physNetId, TrafficType.Guest);
+        HypervisorType hvType = host.getHypervisorType();
+
+        String label = null;
+        switch (hvType) {
+        case XenServer:
+            label = physNetTT.getXenNetworkLabel();
+            if ((label != null) && (!label.equals(""))) {
+                physNetLabel = label;
+            }
+            break;
+        case KVM:
+            label = physNetTT.getKvmNetworkLabel();
+            if ((label != null) && (!label.equals(""))) {
+                physNetLabel = label;
+            }
+            break;
+        default:
+            throw new CloudRuntimeException("Hypervisor " +
+                    hvType.toString() +
+                    " unsupported by OVS Tunnel Manager");
+        }
+
+        // Try to fetch GRE endpoint IP address for cloud db
+        // If not found, then find it on the hypervisor
+        OvsTunnelInterfaceVO tunnelIface =
+                _tunnelInterfaceDao.getByHostAndLabel(host.getId(),
+                        physNetLabel);
+        if (tunnelIface == null) {
+            //Now find and fetch configuration for physical interface
+            //for network with label on target host
+            Commands fetchIfaceCmds =
+                    new Commands(new OvsFetchInterfaceCommand(physNetLabel));
+            s_logger.debug("Ask host " + host.getId() +
+                    " to retrieve interface for phy net with label:" +
+                    physNetLabel);
+            Answer[] fetchIfaceAnswers = _agentMgr.send(host.getId(), fetchIfaceCmds);
+            //And finally save it for future use
+            endpointIp = handleFetchInterfaceAnswer(fetchIfaceAnswers, host.getId());
+        } else {
+            endpointIp = tunnelIface.getIp();
+        }
+        return endpointIp;
+    }
+
+    private int getGreKey(Network network) {
+        int key = 0;
+        try {
+            //The GRE key is actually in the host part of the URI
+            String keyStr = network.getBroadcastUri().getAuthority();
+            if (keyStr.contains(".")) {
+                String[] parts = keyStr.split("\\.");
+                key = Integer.parseInt(parts[1]);
+            } else {
+                key = Integer.parseInt(keyStr);
+            }
+
+            return key;
+        } catch (NumberFormatException e) {
+            s_logger.debug("Well well, how did '" + key
+                    + "' end up in the broadcast URI for the network?");
+            throw new CloudRuntimeException(String.format(
+                    "Invalid GRE key parsed from"
+                            + "network broadcast URI (%s)", network
+                            .getBroadcastUri().toString()));
+        }
+    }
+
+    @DB
+    protected void checkAndCreateTunnel(Network nw, Host host) {
+
+        s_logger.debug("Creating tunnels with OVS tunnel manager");
+
+        long hostId = host.getId();
+        int key = getGreKey(nw);
+        String bridgeName = generateBridgeName(nw, key);
+        List<Long> toHostIds = new ArrayList<Long>();
+        List<Long> fromHostIds = new ArrayList<Long>();
+        List<Long> networkSpannedHosts = _ovsNetworkToplogyGuru.getNetworkSpanedHosts(nw.getId());
+        for (Long rh : networkSpannedHosts) {
+            if (rh == hostId) {
+                continue;
+            }
+            OvsTunnelNetworkVO ta = _tunnelNetworkDao.findByFromToNetwork(hostId, rh.longValue(), nw.getId());
+            // Try and create the tunnel even if a previous attempt failed
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
+                if (ta == null) {
+                    createTunnelRecord(hostId, rh.longValue(), nw.getId(), key);
+                }
+                if (!toHostIds.contains(rh)) {
+                    toHostIds.add(rh);
+                }
+            }
+
+            ta = _tunnelNetworkDao.findByFromToNetwork(rh.longValue(),
+                    hostId, nw.getId());
+            // Try and create the tunnel even if a previous attempt failed
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                s_logger.debug("Attempting to create tunnel from:" +
+                        rh.longValue() + " to:" + hostId);
+                if (ta == null) {
+                    createTunnelRecord(rh.longValue(), hostId,
+                            nw.getId(), key);
+                }
+                if (!fromHostIds.contains(rh)) {
+                    fromHostIds.add(rh);
+                }
+            }
+        }
+        //TODO: Should we propagate the exception here?
+        try {
+            String myIp = getGreEndpointIP(host, nw);
+            if (myIp == null)
+                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + host.getId());
+            boolean noHost = true;
+            for (Long i : toHostIds) {
+                HostVO rHost = _hostDao.findById(i);
+                String otherIp = getGreEndpointIP(rHost, nw);
+                if (otherIp == null)
+                    throw new GreTunnelException(
+                            "Unable to retrieve the remote "
+                                    + "endpoint for the GRE tunnel."
+                                    + "Failure is on host:" + rHost.getId());
+                Commands cmds = new Commands(
+                        new OvsCreateTunnelCommand(otherIp, key,
+                                Long.valueOf(hostId), i, nw.getId(), myIp, bridgeName, nw.getUuid()));
+                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network " + nw.getId());
+                s_logger.debug("Ask host " + hostId
+                        + " to create gre tunnel to " + i);
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleCreateTunnelAnswer(answers);
+                noHost = false;
+            }
+
+            for (Long i : fromHostIds) {
+                HostVO rHost = _hostDao.findById(i);
+                String otherIp = getGreEndpointIP(rHost, nw);
+                Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
+                        key, i, Long.valueOf(hostId), nw.getId(), otherIp, bridgeName, nw.getUuid()));
+                s_logger.debug("Ask host " + i + " to create gre tunnel to "
+                        + hostId);
+                Answer[] answers = _agentMgr.send(i, cmds);
+                handleCreateTunnelAnswer(answers);
+                noHost = false;
+            }
+
+            // If no tunnels have been configured, perform the bridge setup
+            // anyway. This will ensure VIF rules will be triggered
+            if (noHost) {
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, nw.getId()));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for network:" + nw.getId());
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleSetupBridgeAnswer(answers);
+            }
+        } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
+            // I really thing we should do a better handling of these exceptions
+            s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+        }
+    }
+
+    @Override
+    public boolean isOvsTunnelEnabled() {
+        return true;
+    }
+
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
+
+    @Override
+    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            // check and setup host to be in full tunnel mesh with each of the network in the VPC
+            checkAndCreateVpcTunnelNetworks(host, nw.getVpcId());
+        } else {
+            // check and setup host to be in full tunnel mesh with the network
+            checkAndCreateTunnel(nw, host);
+        }
+    }
+
+    @DB
+    private void handleDestroyTunnelAnswer(Answer ans, long from, long to, long networkId) {
+        if (ans.getResult()) {
+            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
+            if (lock == null) {
+                s_logger.warn(String.format("failed to lock" +
+                        "ovs_tunnel_account, remove record of " +
+                        "tunnel(from=%1$s, to=%2$s account=%3$s) failed",
+                        from, to, networkId));
+                return;
+            }
+
+            _tunnelNetworkDao.removeByFromToNetwork(from, to, networkId);
+            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
+
+            s_logger.debug(String.format("Destroy tunnel(account:%1$s," +
+                    "from:%2$s, to:%3$s) successful",
+                    networkId, from, to));
+        } else {
+            s_logger.debug(String.format("Destroy tunnel(account:%1$s," + "from:%2$s, to:%3$s) failed", networkId, from, to));
+        }
+    }
+
+    @DB
+    private void handleDestroyBridgeAnswer(Answer ans, long hostId, long networkId) {
+
+        if (ans.getResult()) {
+            OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
+            if (lock == null) {
+                s_logger.warn("failed to lock ovs_tunnel_network," + "remove record");
+                return;
+            }
+
+            _tunnelNetworkDao.removeByFromNetwork(hostId, networkId);
+            _tunnelNetworkDao.releaseFromLockTable(lock.getId());
+
+            s_logger.debug(String.format("Destroy bridge for" +
+                    "network %1$s successful", networkId));
+        } else {
+            s_logger.debug(String.format("Destroy bridge for" +
+                    "network %1$s failed", networkId));
+        }
+    }
+
+    private void handleSetupBridgeAnswer(Answer[] answers) {
+        //TODO: Add some error management here?
+        s_logger.debug("Placeholder for something more meanginful to come");
+    }
+
+    @Override
+    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
+
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(nw.getVpcId(), host.getId());
+
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+
+            // there are not active VM's on this host belonging to any of the tiers in the VPC, so remove
+            // the host from the tunnel mesh network and destroy the bridge
+            List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(nw.getVpcId());
+            try {
+                for (Network network: vpcNetworks) {
+                    int key = getGreKey(nw);
+                    String bridgeName = generateBridgeName(nw, key);
+                    /* Then ask hosts have peer tunnel with me to destroy them */
+                    List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(host.getId(),nw.getId());
+                    for (OvsTunnelNetworkVO p : peers) {
+                        // If the tunnel was not successfully created don't bother to remove it
+                        if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                            Command cmd= new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                    p.getPortName());
+                            s_logger.debug("Destroying tunnel to " + host.getId() +
+                                    " from " + p.getFrom());
+                            Answer ans = _agentMgr.send(p.getFrom(), cmd);
+                            handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
+                        }
+                    }
+                }
+
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), generateBridgeNameForVpc(nw.getVpcId()),
+                        host.getId());
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+            } catch (Exception e) {
+                s_logger.info("[ignored]"
+                        + "exception while removing host from networks: " + e.getLocalizedMessage());
+            }
+        } else {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInNetworkOnHost(nw.getId(), host.getId(), true);
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            try {
+                /* Now we are last one on host, destroy the bridge with all
+                * the tunnels for this network  */
+                int key = getGreKey(nw);
+                String bridgeName = generateBridgeName(nw, key);
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName, host.getId());
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+
+                /* Then ask hosts have peer tunnel with me to destroy them */
+                List<OvsTunnelNetworkVO> peers =
+                        _tunnelNetworkDao.listByToNetwork(host.getId(),
+                                nw.getId());
+                for (OvsTunnelNetworkVO p : peers) {
+                    // If the tunnel was not successfully created don't bother to remove it
+                    if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                        cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                p.getPortName());
+                        s_logger.debug("Destroying tunnel to " + host.getId() +
+                                " from " + p.getFrom());
+                        ans = _agentMgr.send(p.getFrom(), cmd);
+                        handleDestroyTunnelAnswer(ans, p.getFrom(),
+                                p.getTo(), p.getNetworkId());
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.warn("Destroy tunnel failed", e);
+            }
+        }
+    }
+
+    private String generateBridgeName(Network nw, int key) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            return "OVS-DR-VPC-Bridge" + nw.getVpcId();
+        } else {
+            return "OVSTunnel"+key;
+        }
+    }
+    private String generateBridgeNameForVpc(long vpcId) {
+        return "OVS-DR-VPC-Bridge" + vpcId;
+    }
+
+    @DB
+    protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
+
+        long hostId = host.getId();
+        String bridgeName=generateBridgeNameForVpc(vpcId);
+
+        List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(vpcId, hostId);
+
+        if (vmIds == null || vmIds.isEmpty()) {
+
+            // since this is the first VM from the VPC being launched on the host, first setup the bridge
+            try {
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, null));
+                s_logger.debug("Ask host " + hostId + " to create bridge for vpc " + vpcId + " and configure the "
+                        + " bridge for distributed routing.");
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleSetupBridgeAnswer(answers);
+            } catch (OperationTimedoutException | AgentUnavailableException e) {
+                s_logger.warn("Ovs Tunnel network created bridge failed", e);
+            }
+
+            // now that bridge is setup, populate network acl's before the VM gets created
+            OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
+            cmd.setSequenceNumber(getNextRoutingPolicyUpdateSequenceNumber(vpcId));
+
+            if (!sendVpcRoutingPolicyChangeUpdate(cmd, hostId, bridgeName)) {
+                s_logger.debug("Failed to send VPC routing policy change update to host : " + hostId +
+                        ". But moving on with sending the updates to the rest of the hosts.");
+            }
+        }
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        for (Network vpcNetwork: vpcNetworks) {
+            if (vpcNetwork.getState() != Network.State.Implemented &&
+                    vpcNetwork.getState() != Network.State.Implementing && vpcNetwork.getState() != Network.State.Setup)
+                continue;
+
+            int key = getGreKey(vpcNetwork);
+            List<Long> toHostIds = new ArrayList<Long>();
+            List<Long> fromHostIds = new ArrayList<Long>();
+            OvsTunnelNetworkVO tunnelRecord = null;
+
+            for (Long rh : vpcSpannedHostIds) {
+                if (rh == hostId) {
+                    continue;
+                }
+                tunnelRecord = _tunnelNetworkDao.findByFromToNetwork(hostId, rh.longValue(), vpcNetwork.getId());
+                // Try and create the tunnel if does not exit or previous attempt failed
+                if (tunnelRecord == null || tunnelRecord.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
+                    if (tunnelRecord == null) {
+                        createTunnelRecord(hostId, rh.longValue(), vpcNetwork.getId(), key);
+                    }
+                    if (!toHostIds.contains(rh)) {
+                        toHostIds.add(rh);
+                    }
+                }
+                tunnelRecord = _tunnelNetworkDao.findByFromToNetwork(rh.longValue(), hostId, vpcNetwork.getId());
+                // Try and create the tunnel if does not exit or previous attempt failed
+                if (tunnelRecord == null || tunnelRecord.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" + rh.longValue() + " to:" + hostId);
+                    if (tunnelRecord == null) {
+                        createTunnelRecord(rh.longValue(), hostId, vpcNetwork.getId(), key);
+                    }
+                    if (!fromHostIds.contains(rh)) {
+                        fromHostIds.add(rh);
+                    }
+                }
+            }
+
+            try {
+                String myIp = getGreEndpointIP(host, vpcNetwork);
+                if (myIp == null)
+                    throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel."
+                            + "Failure is on host:" + host.getId());
+                boolean noHost = true;
+
+                for (Long i : toHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    if (otherIp == null)
+                        throw new GreTunnelException(
+                                "Unable to retrieve the remote endpoint for the GRE tunnel."
+                                        + "Failure is on host:" + rHost.getId());
+                    Commands cmds = new Commands( new OvsCreateTunnelCommand(otherIp, key, Long.valueOf(hostId),
+                                     i, vpcNetwork.getId(), myIp, bridgeName, vpcNetwork.getUuid()));
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network "
+                            + vpcNetwork.getId());
+                    s_logger.debug("Ask host " + hostId
+                            + " to create gre tunnel to " + i);
+                    Answer[] answers = _agentMgr.send(hostId, cmds);
+                    handleCreateTunnelAnswer(answers);
+                }
+
+                for (Long i : fromHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
+                            key, i, Long.valueOf(hostId), vpcNetwork.getId(), otherIp, bridgeName,
+                            vpcNetwork.getUuid()));
+                    s_logger.debug("Ask host " + i + " to create gre tunnel to "
+                            + hostId);
+                    Answer[] answers = _agentMgr.send(i, cmds);
+                    handleCreateTunnelAnswer(answers);
+                }
+            } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(VirtualMachine.State oldState,
+                                           VirtualMachine.Event event, VirtualMachine.State newState,
+                                           VirtualMachine vo, boolean status, Object opaque) {
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, VirtualMachine vm, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+
+      VirtualMachine.State oldState = transition.getCurrentState();
+      VirtualMachine.State newState = transition.getToState();
+      VirtualMachine.Event event = transition.getEvent();
+      if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      }
+
+      return true;
+    }
+
+  private void handleVmStateChange(VMInstanceVO vm) {
+
+        // get the VPC's impacted with the VM start
+        List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
+        if (vpcIds == null || vpcIds.isEmpty()) {
+            return;
+        }
+
+        for (Long vpcId: vpcIds) {
+            VpcVO vpc = _vpcDao.findById(vpcId);
+            // nothing to do if the VPC is not setup for distributed routing
+            if (vpc == null || !vpc.usesDistributedRouter()) {
+                return;
+            }
+
+            // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
+            List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+            String bridgeName=generateBridgeNameForVpc(vpcId);
+
+            OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
+            topologyConfigCommand.setSequenceNumber(getNextTopologyUpdateSequenceNumber(vpcId));
+
+            // send topology change update to VPC spanned hosts
+            for (Long id: vpcSpannedHostIds) {
+                if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
+                    s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on " +
+                            "with rest of the host update.");
+                }
+            }
+        }
+    }
+
+    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC topology change update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology.", e );
+            return false;
+        }
+    }
+
+    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
+
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
+
+        for (Long hostId : hostIds) {
+            HostVO hostDetails = _hostDao.findById(hostId);
+            String remoteIp = null;
+            for (Network network: vpcNetworks) {
+                try {
+                    remoteIp = getGreEndpointIP(hostDetails, network);
+                } catch (Exception e) {
+                    s_logger.info("[ignored]"
+                            + "error getting GRE endpoint: " + e.getLocalizedMessage());
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
+            hosts.add(host);
+        }
+
+        for (Network network: vpcNetworks) {
+            String key = network.getBroadcastUri().getAuthority();
+            long gre_key;
+            if (key.contains(".")) {
+                String[] parts = key.split("\\.");
+                gre_key = Long.parseLong(parts[1]);
+            } else {
+                try {
+                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
+            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
+                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
+            tiers.add(tier);
+        }
+
+        for (long vmId: vmIds) {
+            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
+            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
+            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
+                Network network = _networkDao.findById(vmNic.getNetworkId());
+                if (network.getTrafficType() == TrafficType.Guest) {
+                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
+                            vmNic.getIPv4Address(), vmNic.getMacAddress(), network.getUuid());
+                    vmNics.add(nic);
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
+                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
+            vms.add(vm);
+        }
+
+        return new OvsVpcPhysicalTopologyConfigCommand(
+                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
+                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
+                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
+                vpc.getCidr());
+    }
+
+    // Subscriber to ACL replace events. On acl replace event, if the vpc for the tier is enabled for
+    // distributed routing send the ACL update to all the hosts on which VPC spans
+    public class NetworkAclEventsSubscriber implements MessageSubscriber {
+        @Override
+        public void onPublishMessage(String senderAddress, String subject, Object args) {
+            try {
+                NetworkVO network = (NetworkVO) args;
+                String bridgeName=generateBridgeNameForVpc(network.getVpcId());
+                if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
+                    long vpcId = network.getVpcId();
+                    OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
+                    cmd.setSequenceNumber(getNextRoutingPolicyUpdateSequenceNumber(vpcId));
+
+                    // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC
+                    // network ACL update)
+                    List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+                    for (Long id: vpcSpannedHostIds) {
+                        if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
+                            s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
+                                    ". But moving on with sending the updates to the rest of the hosts.");
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to send VPC routing policy change updates all hosts in vpc", e);
+            }
+        }
+    }
+
+    private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
+
+        List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();
+        List<OvsVpcRoutingPolicyConfigCommand.Tier> tiers = new ArrayList<>();
+
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        assert (vpc != null && (vpcNetworks != null && !vpcNetworks.isEmpty())): "invalid vpc id";
+
+        for (Network network : vpcNetworks) {
+            Long networkAclId = network.getNetworkACLId();
+            if (networkAclId == null)
+                continue;
+            NetworkACLVO networkAcl = _networkACLDao.findById(networkAclId);
+
+            List<OvsVpcRoutingPolicyConfigCommand.AclItem> aclItems = new ArrayList<>();
+            List<NetworkACLItemVO> aclItemVos = _networkACLItemDao.listByACL(networkAclId);
+            for (NetworkACLItemVO aclItem : aclItemVos) {
+                String[] sourceCidrs = aclItem.getSourceCidrList().toArray(new String[aclItem.getSourceCidrList().size()]);
+
+                aclItems.add(new OvsVpcRoutingPolicyConfigCommand.AclItem(
+                        aclItem.getNumber(), aclItem.getUuid(), aclItem.getAction().name(),
+                        aclItem.getTrafficType().name(),
+                        ((aclItem.getSourcePortStart() != null) ?aclItem.getSourcePortStart().toString() :null),
+                        ((aclItem.getSourcePortEnd() != null) ?aclItem.getSourcePortEnd().toString() :null),
+                        aclItem.getProtocol(),
+                        sourceCidrs));
+            }
+
+            OvsVpcRoutingPolicyConfigCommand.Acl acl = new OvsVpcRoutingPolicyConfigCommand.Acl(networkAcl.getUuid(),
+                    aclItems.toArray(new OvsVpcRoutingPolicyConfigCommand.AclItem[aclItems.size()]));
+            acls.add(acl);
+
+            OvsVpcRoutingPolicyConfigCommand.Tier tier = new OvsVpcRoutingPolicyConfigCommand.Tier(network.getUuid(),
+                    network.getCidr(), networkAcl.getUuid());
+            tiers.add(tier);
+        }
+
+        OvsVpcRoutingPolicyConfigCommand cmd = new OvsVpcRoutingPolicyConfigCommand(vpc.getUuid(), vpc.getCidr(),
+                acls.toArray(new OvsVpcRoutingPolicyConfigCommand.Acl[acls.size()]),
+                tiers.toArray(new OvsVpcRoutingPolicyConfigCommand.Tier[tiers.size()]));
+        return cmd;
+    }
+
+    private boolean sendVpcRoutingPolicyChangeUpdate(OvsVpcRoutingPolicyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC routing policies change update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC routing policies." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest routing policies." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest routing policies due to" , e );
+            return false;
+        }
+    }
+
+    private long getNextTopologyUpdateSequenceNumber(final long vpcId) {
+
+        try {
+            return  Transaction.execute(new TransactionCallback<Long>() {
+                @Override
+                public Long doInTransaction(TransactionStatus status) {
+                    VpcDistributedRouterSeqNoVO seqVo = _vpcDrSeqNoDao.findByVpcId(vpcId);
+                    if (seqVo == null) {
+                        seqVo = new VpcDistributedRouterSeqNoVO(vpcId);
+                        _vpcDrSeqNoDao.persist(seqVo);
+                    }
+                    seqVo = _vpcDrSeqNoDao.lockRow(seqVo.getId(), true);
+                    seqVo.incrTopologyUpdateSequenceNo();
+                    _vpcDrSeqNoDao.update(seqVo.getId(), seqVo);
+                    return seqVo.getTopologyUpdateSequenceNo();
+                }
+            });
+        } finally {
+
+        }
+    }
+
+    private long getNextRoutingPolicyUpdateSequenceNumber(final long vpcId) {
+
+        try {
+            return  Transaction.execute(new TransactionCallback<Long>() {
+                @Override
+                public Long doInTransaction(TransactionStatus status) {
+                    VpcDistributedRouterSeqNoVO seqVo = _vpcDrSeqNoDao.findByVpcId(vpcId);
+                    if (seqVo == null) {
+                        seqVo = new VpcDistributedRouterSeqNoVO(vpcId);
+                        _vpcDrSeqNoDao.persist(seqVo);
+                    }
+                    seqVo = _vpcDrSeqNoDao.lockRow(seqVo.getId(), true);
+                    seqVo.incrPolicyUpdateSequenceNo();
+                    _vpcDrSeqNoDao.update(seqVo.getId(), seqVo);
+                    return seqVo.getPolicyUpdateSequenceNo();
+                }
+            });
+        } finally {
+
+        }
+    }
+}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnel.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnel.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java
diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java
new file mode 100644
index 0000000..0aeb271
--- /dev/null
+++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDao.java
@@ -0,0 +1,32 @@
+// 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.network.ovs.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface OvsTunnelNetworkDao extends GenericDao<OvsTunnelNetworkVO, Long> {
+    OvsTunnelNetworkVO findByFromToNetwork(long from, long to, long networkId);
+
+    void removeByFromNetwork(long from, long networkId);
+
+    void removeByFromToNetwork(long from, long to, long networkId);
+
+    List<OvsTunnelNetworkVO> listByToNetwork(long to, long networkId);
+}
diff --git a/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java
new file mode 100644
index 0000000..6d12c19
--- /dev/null
+++ b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkDaoImpl.java
@@ -0,0 +1,89 @@
+// 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.network.ovs.dao;
+
+import java.util.List;
+
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+public class OvsTunnelNetworkDaoImpl extends GenericDaoBase<OvsTunnelNetworkVO, Long> implements OvsTunnelNetworkDao {
+
+    protected final SearchBuilder<OvsTunnelNetworkVO> fromToNetworkSearch;
+    protected final SearchBuilder<OvsTunnelNetworkVO> fromNetworkSearch;
+    protected final SearchBuilder<OvsTunnelNetworkVO> toNetworkSearch;
+
+    public OvsTunnelNetworkDaoImpl() {
+        fromToNetworkSearch = createSearchBuilder();
+        fromToNetworkSearch.and("from", fromToNetworkSearch.entity().getFrom(), Op.EQ);
+        fromToNetworkSearch.and("to", fromToNetworkSearch.entity().getTo(), Op.EQ);
+        fromToNetworkSearch.and("network_id", fromToNetworkSearch.entity().getNetworkId(), Op.EQ);
+        fromToNetworkSearch.done();
+
+        fromNetworkSearch = createSearchBuilder();
+        fromNetworkSearch.and("from", fromNetworkSearch.entity().getFrom(), Op.EQ);
+        fromNetworkSearch.and("network_id", fromNetworkSearch.entity().getNetworkId(), Op.EQ);
+        fromNetworkSearch.done();
+
+        toNetworkSearch = createSearchBuilder();
+        toNetworkSearch.and("to", toNetworkSearch.entity().getTo(), Op.EQ);
+        toNetworkSearch.and("network_id", toNetworkSearch.entity().getNetworkId(), Op.EQ);
+        toNetworkSearch.done();
+    }
+
+    @Override
+    public OvsTunnelNetworkVO findByFromToNetwork(long from, long to, long networkId) {
+        SearchCriteria<OvsTunnelNetworkVO> sc = fromToNetworkSearch.create();
+        sc.setParameters("from", from);
+        sc.setParameters("to", to);
+        sc.setParameters("network_id", networkId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public void removeByFromNetwork(long from, long networkId) {
+        SearchCriteria<OvsTunnelNetworkVO> sc = fromNetworkSearch.create();
+        sc.setParameters("from", from);
+        sc.setParameters("network_id", networkId);
+        remove(sc);
+    }
+
+    @Override
+    public List<OvsTunnelNetworkVO> listByToNetwork(long to, long networkId) {
+        SearchCriteria<OvsTunnelNetworkVO> sc = toNetworkSearch.create();
+        sc.setParameters("to", to);
+        sc.setParameters("network_id", networkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void removeByFromToNetwork(long from, long to, long networkId) {
+        SearchCriteria<OvsTunnelNetworkVO> sc = fromToNetworkSearch.create();
+        sc.setParameters("from", from);
+        sc.setParameters("to", to);
+        sc.setParameters("network_id", networkId);
+        remove(sc);
+    }
+
+}
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDao.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDao.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDao.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDao.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDaoImpl.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDaoImpl.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDaoImpl.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoDaoImpl.java
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoVO.java b/plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoVO.java
similarity index 100%
rename from plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoVO.java
rename to plugins/network-elements/ovs/src/main/java/com/cloud/network/ovs/dao/VpcDistributedRouterSeqNoVO.java
diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/module.properties b/plugins/network-elements/ovs/src/main/resources/META-INF/cloudstack/ovs/module.properties
similarity index 100%
rename from plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/module.properties
rename to plugins/network-elements/ovs/src/main/resources/META-INF/cloudstack/ovs/module.properties
diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml b/plugins/network-elements/ovs/src/main/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
similarity index 100%
rename from plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
rename to plugins/network-elements/ovs/src/main/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml
index 84e8a79..0445444 100644
--- a/plugins/network-elements/palo-alto/pom.xml
+++ b/plugins/network-elements/palo-alto/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-palo-alto</artifactId>
-  <name>Apache CloudStack Plugin - Palo Alto</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-network-palo-alto</artifactId>
+    <name>Apache CloudStack Plugin - Palo Alto</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/commands/AddPaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/commands/AddPaloAltoFirewallCmd.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/AddPaloAltoFirewallCmd.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ConfigurePaloAltoFirewallCmd.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/DeletePaloAltoFirewallCmd.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/commands/ListPaloAltoFirewallNetworksCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ListPaloAltoFirewallNetworksCmd.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/commands/ListPaloAltoFirewallNetworksCmd.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ListPaloAltoFirewallNetworksCmd.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/commands/ListPaloAltoFirewallsCmd.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ListPaloAltoFirewallsCmd.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/commands/ListPaloAltoFirewallsCmd.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/commands/ListPaloAltoFirewallsCmd.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/api/response/PaloAltoFirewallResponse.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/api/response/PaloAltoFirewallResponse.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/api/response/PaloAltoFirewallResponse.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/api/response/PaloAltoFirewallResponse.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/network/element/PaloAltoExternalFirewallElement.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/network/element/PaloAltoExternalFirewallElement.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/network/element/PaloAltoFirewallElementService.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoFirewallElementService.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/network/element/PaloAltoFirewallElementService.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoFirewallElementService.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/network/resource/PaloAltoResource.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/resource/PaloAltoResource.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/network/resource/PaloAltoResource.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/network/resource/PaloAltoResource.java
diff --git a/plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/utils/HttpClientWrapper.java
similarity index 100%
rename from plugins/network-elements/palo-alto/src/com/cloud/network/utils/HttpClientWrapper.java
rename to plugins/network-elements/palo-alto/src/main/java/com/cloud/network/utils/HttpClientWrapper.java
diff --git a/plugins/network-elements/palo-alto/resources/META-INF/cloudstack/paloalto/module.properties b/plugins/network-elements/palo-alto/src/main/resources/META-INF/cloudstack/paloalto/module.properties
similarity index 100%
rename from plugins/network-elements/palo-alto/resources/META-INF/cloudstack/paloalto/module.properties
rename to plugins/network-elements/palo-alto/src/main/resources/META-INF/cloudstack/paloalto/module.properties
diff --git a/plugins/network-elements/palo-alto/resources/META-INF/cloudstack/paloalto/spring-paloalto-context.xml b/plugins/network-elements/palo-alto/src/main/resources/META-INF/cloudstack/paloalto/spring-paloalto-context.xml
similarity index 100%
rename from plugins/network-elements/palo-alto/resources/META-INF/cloudstack/paloalto/spring-paloalto-context.xml
rename to plugins/network-elements/palo-alto/src/main/resources/META-INF/cloudstack/paloalto/spring-paloalto-context.xml
diff --git a/plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java b/plugins/network-elements/palo-alto/src/test/java/com/cloud/network/resource/MockablePaloAltoResource.java
similarity index 100%
rename from plugins/network-elements/palo-alto/test/com/cloud/network/resource/MockablePaloAltoResource.java
rename to plugins/network-elements/palo-alto/src/test/java/com/cloud/network/resource/MockablePaloAltoResource.java
diff --git a/plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java b/plugins/network-elements/palo-alto/src/test/java/com/cloud/network/resource/PaloAltoResourceTest.java
similarity index 100%
rename from plugins/network-elements/palo-alto/test/com/cloud/network/resource/PaloAltoResourceTest.java
rename to plugins/network-elements/palo-alto/src/test/java/com/cloud/network/resource/PaloAltoResourceTest.java
diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml
index 788b967..6b9fd55 100644
--- a/plugins/network-elements/stratosphere-ssp/pom.xml
+++ b/plugins/network-elements/stratosphere-ssp/pom.xml
@@ -1,31 +1,31 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-ssp</artifactId>
-  <name>Apache CloudStack Plugin - Stratosphere SSP</name>
-  <url>http://www.stratosphere.co.jp/</url>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+    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-network-ssp</artifactId>
+    <name>Apache CloudStack Plugin - Stratosphere SSP</name>
+    <url>http://www.stratosphere.co.jp/</url>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/commands/AddSspCmd.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/AddSspCmd.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/commands/AddSspCmd.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/commands/DeleteSspCmd.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/commands/DeleteSspCmd.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/commands/DeleteSspCmd.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/response/SspResponse.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/response/SspResponse.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/api/response/SspResponse.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/api/response/SspResponse.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialDao.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialDao.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialDao.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialDao.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialDaoImpl.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialDaoImpl.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialDaoImpl.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialDaoImpl.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialVO.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspCredentialVO.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspCredentialVO.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantDao.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantDao.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantDao.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantDao.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantDaoImpl.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantDaoImpl.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantDaoImpl.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantDaoImpl.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantVO.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantVO.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspTenantVO.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspTenantVO.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidDao.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidDao.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidDao.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidDao.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidDaoImpl.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidDaoImpl.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidDaoImpl.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidDaoImpl.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidVO.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidVO.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/dao/SspUuidVO.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/dao/SspUuidVO.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspClient.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspClient.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspManager.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspManager.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspManager.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspManager.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspService.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspService.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspService.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspService.java
diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
rename to plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/guru/SspGuestNetworkGuru.java
diff --git a/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/module.properties b/plugins/network-elements/stratosphere-ssp/src/main/resources/META-INF/cloudstack/ssp/module.properties
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/module.properties
rename to plugins/network-elements/stratosphere-ssp/src/main/resources/META-INF/cloudstack/ssp/module.properties
diff --git a/plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml b/plugins/network-elements/stratosphere-ssp/src/main/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml
rename to plugins/network-elements/stratosphere-ssp/src/main/resources/META-INF/cloudstack/ssp/spring-ssp-context.xml
diff --git a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java b/plugins/network-elements/stratosphere-ssp/src/test/java/org/apache/cloudstack/network/element/SspClientTest.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java
rename to plugins/network-elements/stratosphere-ssp/src/test/java/org/apache/cloudstack/network/element/SspClientTest.java
diff --git a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspElementTest.java b/plugins/network-elements/stratosphere-ssp/src/test/java/org/apache/cloudstack/network/element/SspElementTest.java
similarity index 100%
rename from plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspElementTest.java
rename to plugins/network-elements/stratosphere-ssp/src/test/java/org/apache/cloudstack/network/element/SspElementTest.java
diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml
index 24f6903..def7f81 100644
--- a/plugins/network-elements/vxlan/pom.xml
+++ b/plugins/network-elements/vxlan/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-network-vxlan</artifactId>
-  <name>Apache CloudStack Plugin - Network VXLAN</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-network-vxlan</artifactId>
+    <name>Apache CloudStack Plugin - Network VXLAN</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java b/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java
deleted file mode 100644
index 35f588f..0000000
--- a/plugins/network-elements/vxlan/src/com/cloud/network/guru/VxlanGuestNetworkGuru.java
+++ /dev/null
@@ -1,167 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-@Component
-public class VxlanGuestNetworkGuru extends GuestNetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(VxlanGuestNetworkGuru.class);
-
-    public VxlanGuestNetworkGuru() {
-        super();
-        _isolationMethods = new IsolationMethod[] {new IsolationMethod("VXLAN")};
-    }
-
-    @Override
-    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
-        // This guru handles only Guest Isolated network that supports Source nat service
-        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) &&
-                (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.L2) &&
-                isMyIsolationMethod(physicalNetwork)) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " or " + GuestType.L2 + " in zone of type " + NetworkType.Advanced);
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-
-        NetworkVO network = (NetworkVO)super.design(offering, plan, userSpecified, owner);
-        if (network == null) {
-            return null;
-        }
-
-        if (offering.getGuestType() == GuestType.L2 && network.getBroadcastUri() != null) {
-            String vxlan = BroadcastDomainType.getValue(network.getBroadcastUri());
-            network.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vxlan));
-        }
-        network.setBroadcastDomainType(BroadcastDomainType.Vxlan);
-
-        return network;
-    }
-
-    @Override
-    protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId)
-        throws InsufficientVirtualNetworkCapacityException {
-        if (network.getBroadcastUri() == null) {
-            String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, UseSystemGuestVlans.valueIn(network.getAccountId()));
-            if (vnet == null) {
-                throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class,
-                    dcId);
-            }
-            implemented.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vnet));
-            allocateVnetComplete(network, implemented, dcId, physicalNetworkId, reservationId, vnet);
-        } else {
-            implemented.setBroadcastUri(network.getBroadcastUri());
-        }
-    }
-
-    // For Test: Mockit cannot mock static method, wrap it
-    protected void allocateVnetComplete(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId, String vnet) {
-        //TODO(VXLAN): Add new event type for vxlan?
-        ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN,
-            "Assigned Zone vNet: " + vnet + " Network Id: " + network.getId(), 0);
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
-
-        long dcId = dest.getDataCenter().getId();
-
-        //get physical network id
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-
-        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
-        if (physicalNetworkId == null) {
-            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
-        }
-
-        NetworkVO implemented =
-            new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
-                network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
-
-        allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
-
-        if (network.getGateway() != null) {
-            implemented.setGateway(network.getGateway());
-        }
-
-        if (network.getCidr() != null) {
-            implemented.setCidr(network.getCidr());
-        }
-
-        return implemented;
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        super.reserve(nic, network, vm, dest, context);
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        return super.release(nic, vm, reservationId);
-    }
-
-    @Override
-    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
-        NetworkVO networkObject = _networkDao.findById(profile.getId());
-        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vxlan || networkObject.getBroadcastUri() == null) {
-            s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
-            return;
-        }
-
-        super.shutdown(profile, offering);
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        return super.trash(network, offering);
-    }
-
-}
diff --git a/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java b/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java
new file mode 100644
index 0000000..8a45f75
--- /dev/null
+++ b/plugins/network-elements/vxlan/src/main/java/com/cloud/network/guru/VxlanGuestNetworkGuru.java
@@ -0,0 +1,167 @@
+// 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.network.guru;
+
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+@Component
+public class VxlanGuestNetworkGuru extends GuestNetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(VxlanGuestNetworkGuru.class);
+
+    public VxlanGuestNetworkGuru() {
+        super();
+        _isolationMethods = new IsolationMethod[] {new IsolationMethod("VXLAN")};
+    }
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+        // This guru handles only Guest Isolated network that supports Source nat service
+        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) &&
+                (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.L2) &&
+                isMyIsolationMethod(physicalNetwork)) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " or " + GuestType.L2 + " in zone of type " + NetworkType.Advanced);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+
+        NetworkVO network = (NetworkVO)super.design(offering, plan, userSpecified, owner);
+        if (network == null) {
+            return null;
+        }
+
+        if (offering.getGuestType() == GuestType.L2 && network.getBroadcastUri() != null) {
+            String vxlan = BroadcastDomainType.getValue(network.getBroadcastUri());
+            network.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vxlan));
+        }
+        network.setBroadcastDomainType(BroadcastDomainType.Vxlan);
+
+        return network;
+    }
+
+    @Override
+    protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId)
+        throws InsufficientVirtualNetworkCapacityException {
+        if (network.getBroadcastUri() == null) {
+            String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, UseSystemGuestVlans.valueIn(network.getAccountId()));
+            if (vnet == null) {
+                throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class,
+                    dcId);
+            }
+            implemented.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(vnet));
+            allocateVnetComplete(network, implemented, dcId, physicalNetworkId, reservationId, vnet);
+        } else {
+            implemented.setBroadcastUri(network.getBroadcastUri());
+        }
+    }
+
+    // For Test: Mockit cannot mock static method, wrap it
+    protected void allocateVnetComplete(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId, String vnet) {
+        //TODO(VXLAN): Add new event type for vxlan?
+        ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN,
+            "Assigned Zone vNet: " + vnet + " Network Id: " + network.getId(), 0);
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
+
+        long dcId = dest.getDataCenter().getId();
+
+        //get physical network id
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
+        if (physicalNetworkId == null) {
+            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
+        }
+
+        NetworkVO implemented =
+            new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
+                network.getDataCenterId(), physicalNetworkId, offering.isRedundantRouter());
+
+        allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
+
+        if (network.getGateway() != null) {
+            implemented.setGateway(network.getGateway());
+        }
+
+        if (network.getCidr() != null) {
+            implemented.setCidr(network.getCidr());
+        }
+
+        return implemented;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        super.reserve(nic, network, vm, dest, context);
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        return super.release(nic, vm, reservationId);
+    }
+
+    @Override
+    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+        NetworkVO networkObject = _networkDao.findById(profile.getId());
+        if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vxlan || networkObject.getBroadcastUri() == null) {
+            s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
+            return;
+        }
+
+        super.shutdown(profile, offering);
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        return super.trash(network, offering);
+    }
+
+}
diff --git a/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/module.properties b/plugins/network-elements/vxlan/src/main/resources/META-INF/cloudstack/vxlan/module.properties
similarity index 100%
rename from plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/module.properties
rename to plugins/network-elements/vxlan/src/main/resources/META-INF/cloudstack/vxlan/module.properties
diff --git a/plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml b/plugins/network-elements/vxlan/src/main/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml
similarity index 100%
rename from plugins/network-elements/vxlan/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml
rename to plugins/network-elements/vxlan/src/main/resources/META-INF/cloudstack/vxlan/spring-vxlan-context.xml
diff --git a/plugins/network-elements/vxlan/src/test/java/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java b/plugins/network-elements/vxlan/src/test/java/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
new file mode 100644
index 0000000..27c2ad5
--- /dev/null
+++ b/plugins/network-elements/vxlan/src/test/java/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
@@ -0,0 +1,280 @@
+// 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.network.guru;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.domain.Domain;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.user.Account;
+import com.cloud.vm.ReservationContext;
+
+public class VxlanGuestNetworkGuruTest {
+    PhysicalNetworkDao physnetdao = mock(PhysicalNetworkDao.class);
+    DataCenterDao dcdao = mock(DataCenterDao.class);
+    AgentManager agentmgr = mock(AgentManager.class);
+    NetworkOrchestrationService netmgr = mock(NetworkOrchestrationService.class);
+    NetworkModel netmodel = mock(NetworkModel.class);
+    ConfigurationServer confsvr = mock(ConfigurationServer.class);
+
+    NetworkDao netdao = mock(NetworkDao.class);
+    VxlanGuestNetworkGuru guru;
+
+    @Before
+    public void setUp() {
+        guru = spy(new VxlanGuestNetworkGuru());
+        ((GuestNetworkGuru)guru)._physicalNetworkDao = physnetdao;
+        guru._physicalNetworkDao = physnetdao;
+        guru._dcDao = dcdao;
+        guru._networkModel = netmodel;
+        guru._networkDao = netdao;
+        ((GuestNetworkGuru)guru)._configServer = confsvr;
+
+        DataCenterVO dc = mock(DataCenterVO.class);
+        when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
+        when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
+
+        when(dcdao.findById(anyLong())).thenReturn(dc);
+    }
+
+    @Test
+    public void testCanHandle() {
+        NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(42L);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
+        when(physnet.getId()).thenReturn(42L);
+
+        assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+        // Not supported TrafficType != Guest
+        when(offering.getTrafficType()).thenReturn(TrafficType.Management);
+        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+        // Not supported: GuestType Shared
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Shared);
+        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+        // Not supported: Basic networking
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+        assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true);
+
+        // Not supported: IsolationMethod != VXLAN
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"}));
+        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
+
+    }
+
+    @Test
+    public void testDesign() {
+        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+        when(physnetdao.findById(anyLong())).thenReturn(physnet);
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
+        when(physnet.getId()).thenReturn(42L);
+
+        NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(42L);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        DeploymentPlan plan = mock(DeploymentPlan.class);
+        Network network = mock(Network.class);
+        Account account = mock(Account.class);
+
+        Network designednetwork = guru.design(offering, plan, network, account);
+        assertTrue(designednetwork != null);
+        assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vxlan);
+    }
+
+    @Test
+    public void testImplement() throws InsufficientVirtualNetworkCapacityException {
+        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+        when(physnetdao.findById(anyLong())).thenReturn(physnet);
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
+        when(physnet.getId()).thenReturn(42L);
+
+        NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(42L);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        NetworkVO network = mock(NetworkVO.class);
+        when(network.getName()).thenReturn("testnetwork");
+        when(network.getState()).thenReturn(State.Implementing);
+        when(network.getPhysicalNetworkId()).thenReturn(42L);
+
+        DeployDestination dest = mock(DeployDestination.class);
+
+        DataCenter dc = mock(DataCenter.class);
+        when(dest.getDataCenter()).thenReturn(dc);
+
+        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
+        //TODO(VXLAN): doesn't support VNI specified
+        //when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
+        when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String)any(), eq(true))).thenReturn("42");
+        doNothing().when(guru).allocateVnetComplete((Network)any(), (NetworkVO)any(), anyLong(), anyLong(), (String)any(), eq("42"));
+
+        Domain dom = mock(Domain.class);
+        when(dom.getName()).thenReturn("domain");
+
+        Account acc = mock(Account.class);
+        when(acc.getAccountName()).thenReturn("accountname");
+
+        ReservationContext res = mock(ReservationContext.class);
+        when(res.getDomain()).thenReturn(dom);
+        when(res.getAccount()).thenReturn(acc);
+
+        Network implementednetwork = guru.implement(network, offering, dest, res);
+        assertTrue(implementednetwork != null);
+    }
+
+    @Test
+    public void testImplementWithCidr() throws InsufficientVirtualNetworkCapacityException {
+        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+        when(physnetdao.findById(anyLong())).thenReturn(physnet);
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
+        when(physnet.getId()).thenReturn(42L);
+
+        NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(42L);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        NetworkVO network = mock(NetworkVO.class);
+        when(network.getName()).thenReturn("testnetwork");
+        when(network.getState()).thenReturn(State.Implementing);
+        when(network.getGateway()).thenReturn("10.1.1.1");
+        when(network.getCidr()).thenReturn("10.1.1.0/24");
+        when(network.getPhysicalNetworkId()).thenReturn(42L);
+
+        DeployDestination dest = mock(DeployDestination.class);
+
+        DataCenter dc = mock(DataCenter.class);
+        when(dest.getDataCenter()).thenReturn(dc);
+
+        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
+
+        //TODO(VXLAN): doesn't support VNI specified
+        //when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
+        when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String)any(), eq(true))).thenReturn("42");
+        doNothing().when(guru).allocateVnetComplete((Network)any(), (NetworkVO)any(), anyLong(), anyLong(), (String)any(), eq("42"));
+
+        Domain dom = mock(Domain.class);
+        when(dom.getName()).thenReturn("domain");
+
+        Account acc = mock(Account.class);
+        when(acc.getAccountName()).thenReturn("accountname");
+
+        ReservationContext res = mock(ReservationContext.class);
+        when(res.getDomain()).thenReturn(dom);
+        when(res.getAccount()).thenReturn(acc);
+
+        Network implementednetwork = guru.implement(network, offering, dest, res);
+        assertTrue(implementednetwork != null);
+        assertTrue(implementednetwork.getCidr().equals("10.1.1.0/24"));
+        assertTrue(implementednetwork.getGateway().equals("10.1.1.1"));
+    }
+
+    @Test
+    public void testShutdown() throws InsufficientVirtualNetworkCapacityException, URISyntaxException {
+        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
+        when(physnetdao.findById(anyLong())).thenReturn(physnet);
+        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
+        when(physnet.getId()).thenReturn(42L);
+
+        NetworkOffering offering = mock(NetworkOffering.class);
+        when(offering.getId()).thenReturn(42L);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
+
+        NetworkVO network = mock(NetworkVO.class);
+        when(network.getName()).thenReturn("testnetwork");
+        when(network.getState()).thenReturn(State.Implementing);
+        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vxlan);
+        when(network.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
+        when(network.getPhysicalNetworkId()).thenReturn(42L);
+        when(netdao.findById(42L)).thenReturn(network);
+
+        DeployDestination dest = mock(DeployDestination.class);
+
+        DataCenter dc = mock(DataCenter.class);
+        when(dest.getDataCenter()).thenReturn(dc);
+
+        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
+
+        Domain dom = mock(Domain.class);
+        when(dom.getName()).thenReturn("domain");
+
+        Account acc = mock(Account.class);
+        when(acc.getAccountName()).thenReturn("accountname");
+
+        ReservationContext res = mock(ReservationContext.class);
+        when(res.getDomain()).thenReturn(dom);
+        when(res.getAccount()).thenReturn(acc);
+
+        NetworkProfile implementednetwork = mock(NetworkProfile.class);
+        when(implementednetwork.getId()).thenReturn(42L);
+        when(implementednetwork.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
+        when(offering.isSpecifyVlan()).thenReturn(false);
+
+        guru.shutdown(implementednetwork, offering);
+        verify(implementednetwork, times(1)).setBroadcastUri(null);
+    }
+}
diff --git a/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java b/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
deleted file mode 100644
index 4754aa5..0000000
--- a/plugins/network-elements/vxlan/test/com/cloud/network/guru/VxlanGuestNetworkGuruTest.java
+++ /dev/null
@@ -1,280 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.domain.Domain;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.user.Account;
-import com.cloud.vm.ReservationContext;
-
-public class VxlanGuestNetworkGuruTest {
-    PhysicalNetworkDao physnetdao = mock(PhysicalNetworkDao.class);
-    DataCenterDao dcdao = mock(DataCenterDao.class);
-    AgentManager agentmgr = mock(AgentManager.class);
-    NetworkOrchestrationService netmgr = mock(NetworkOrchestrationService.class);
-    NetworkModel netmodel = mock(NetworkModel.class);
-    ConfigurationServer confsvr = mock(ConfigurationServer.class);
-
-    NetworkDao netdao = mock(NetworkDao.class);
-    VxlanGuestNetworkGuru guru;
-
-    @Before
-    public void setUp() {
-        guru = spy(new VxlanGuestNetworkGuru());
-        ((GuestNetworkGuru)guru)._physicalNetworkDao = physnetdao;
-        guru._physicalNetworkDao = physnetdao;
-        guru._dcDao = dcdao;
-        guru._networkModel = netmodel;
-        guru._networkDao = netdao;
-        ((GuestNetworkGuru)guru)._configServer = confsvr;
-
-        DataCenterVO dc = mock(DataCenterVO.class);
-        when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
-        when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24");
-
-        when(dcdao.findById(anyLong())).thenReturn(dc);
-    }
-
-    @Test
-    public void testCanHandle() {
-        NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(42L);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
-        when(physnet.getId()).thenReturn(42L);
-
-        assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
-
-        // Not supported TrafficType != Guest
-        when(offering.getTrafficType()).thenReturn(TrafficType.Management);
-        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
-
-        // Not supported: GuestType Shared
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Shared);
-        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
-
-        // Not supported: Basic networking
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-        assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true);
-
-        // Not supported: IsolationMethod != VXLAN
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"}));
-        assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true);
-
-    }
-
-    @Test
-    public void testDesign() {
-        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
-        when(physnetdao.findById(anyLong())).thenReturn(physnet);
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
-        when(physnet.getId()).thenReturn(42L);
-
-        NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(42L);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        DeploymentPlan plan = mock(DeploymentPlan.class);
-        Network network = mock(Network.class);
-        Account account = mock(Account.class);
-
-        Network designednetwork = guru.design(offering, plan, network, account);
-        assertTrue(designednetwork != null);
-        assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vxlan);
-    }
-
-    @Test
-    public void testImplement() throws InsufficientVirtualNetworkCapacityException {
-        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
-        when(physnetdao.findById(anyLong())).thenReturn(physnet);
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
-        when(physnet.getId()).thenReturn(42L);
-
-        NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(42L);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        NetworkVO network = mock(NetworkVO.class);
-        when(network.getName()).thenReturn("testnetwork");
-        when(network.getState()).thenReturn(State.Implementing);
-        when(network.getPhysicalNetworkId()).thenReturn(42L);
-
-        DeployDestination dest = mock(DeployDestination.class);
-
-        DataCenter dc = mock(DataCenter.class);
-        when(dest.getDataCenter()).thenReturn(dc);
-
-        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
-        //TODO(VXLAN): doesn't support VNI specified
-        //when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
-        when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String)any(), eq(true))).thenReturn("42");
-        doNothing().when(guru).allocateVnetComplete((Network)any(), (NetworkVO)any(), anyLong(), anyLong(), (String)any(), eq("42"));
-
-        Domain dom = mock(Domain.class);
-        when(dom.getName()).thenReturn("domain");
-
-        Account acc = mock(Account.class);
-        when(acc.getAccountName()).thenReturn("accountname");
-
-        ReservationContext res = mock(ReservationContext.class);
-        when(res.getDomain()).thenReturn(dom);
-        when(res.getAccount()).thenReturn(acc);
-
-        Network implementednetwork = guru.implement(network, offering, dest, res);
-        assertTrue(implementednetwork != null);
-    }
-
-    @Test
-    public void testImplementWithCidr() throws InsufficientVirtualNetworkCapacityException {
-        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
-        when(physnetdao.findById(anyLong())).thenReturn(physnet);
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
-        when(physnet.getId()).thenReturn(42L);
-
-        NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(42L);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        NetworkVO network = mock(NetworkVO.class);
-        when(network.getName()).thenReturn("testnetwork");
-        when(network.getState()).thenReturn(State.Implementing);
-        when(network.getGateway()).thenReturn("10.1.1.1");
-        when(network.getCidr()).thenReturn("10.1.1.0/24");
-        when(network.getPhysicalNetworkId()).thenReturn(42L);
-
-        DeployDestination dest = mock(DeployDestination.class);
-
-        DataCenter dc = mock(DataCenter.class);
-        when(dest.getDataCenter()).thenReturn(dc);
-
-        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
-
-        //TODO(VXLAN): doesn't support VNI specified
-        //when(confsvr.getConfigValue((String) any(), (String) any(), anyLong())).thenReturn("true");
-        when(dcdao.allocateVnet(anyLong(), anyLong(), anyLong(), (String)any(), eq(true))).thenReturn("42");
-        doNothing().when(guru).allocateVnetComplete((Network)any(), (NetworkVO)any(), anyLong(), anyLong(), (String)any(), eq("42"));
-
-        Domain dom = mock(Domain.class);
-        when(dom.getName()).thenReturn("domain");
-
-        Account acc = mock(Account.class);
-        when(acc.getAccountName()).thenReturn("accountname");
-
-        ReservationContext res = mock(ReservationContext.class);
-        when(res.getDomain()).thenReturn(dom);
-        when(res.getAccount()).thenReturn(acc);
-
-        Network implementednetwork = guru.implement(network, offering, dest, res);
-        assertTrue(implementednetwork != null);
-        assertTrue(implementednetwork.getCidr().equals("10.1.1.0/24"));
-        assertTrue(implementednetwork.getGateway().equals("10.1.1.1"));
-    }
-
-    @Test
-    public void testShutdown() throws InsufficientVirtualNetworkCapacityException, URISyntaxException {
-        PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class);
-        when(physnetdao.findById(anyLong())).thenReturn(physnet);
-        when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VXLAN"}));
-        when(physnet.getId()).thenReturn(42L);
-
-        NetworkOffering offering = mock(NetworkOffering.class);
-        when(offering.getId()).thenReturn(42L);
-        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
-        when(offering.getGuestType()).thenReturn(GuestType.Isolated);
-
-        NetworkVO network = mock(NetworkVO.class);
-        when(network.getName()).thenReturn("testnetwork");
-        when(network.getState()).thenReturn(State.Implementing);
-        when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vxlan);
-        when(network.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
-        when(network.getPhysicalNetworkId()).thenReturn(42L);
-        when(netdao.findById(42L)).thenReturn(network);
-
-        DeployDestination dest = mock(DeployDestination.class);
-
-        DataCenter dc = mock(DataCenter.class);
-        when(dest.getDataCenter()).thenReturn(dc);
-
-        when(netmodel.findPhysicalNetworkId(anyLong(), (String)any(), (TrafficType)any())).thenReturn(42L);
-
-        Domain dom = mock(Domain.class);
-        when(dom.getName()).thenReturn("domain");
-
-        Account acc = mock(Account.class);
-        when(acc.getAccountName()).thenReturn("accountname");
-
-        ReservationContext res = mock(ReservationContext.class);
-        when(res.getDomain()).thenReturn(dom);
-        when(res.getAccount()).thenReturn(acc);
-
-        NetworkProfile implementednetwork = mock(NetworkProfile.class);
-        when(implementednetwork.getId()).thenReturn(42L);
-        when(implementednetwork.getBroadcastUri()).thenReturn(new URI("vxlan:12345"));
-        when(offering.getSpecifyVlan()).thenReturn(false);
-
-        guru.shutdown(implementednetwork, offering);
-        verify(implementednetwork, times(1)).setBroadcastUri(null);
-    }
-}
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
index 44e1316..83444c4 100644
--- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
+++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
@@ -1,41 +1,42 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-outofbandmanagement-driver-ipmitool</artifactId>
-  <name>Apache CloudStack Plugin - Power Management Driver ipmitool</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+<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-outofbandmanagement-driver-ipmitool</artifactId>
+    <name>Apache CloudStack Plugin - Power Management Driver ipmitool</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/src/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java b/plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java
similarity index 100%
rename from plugins/outofbandmanagement-drivers/ipmitool/src/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java
rename to plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolOutOfBandManagementDriver.java
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/src/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapper.java b/plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapper.java
similarity index 100%
rename from plugins/outofbandmanagement-drivers/ipmitool/src/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapper.java
rename to plugins/outofbandmanagement-drivers/ipmitool/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapper.java
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/resources/META-INF/cloudstack/ipmitool/module.properties b/plugins/outofbandmanagement-drivers/ipmitool/src/main/resources/META-INF/cloudstack/ipmitool/module.properties
similarity index 100%
rename from plugins/outofbandmanagement-drivers/ipmitool/resources/META-INF/cloudstack/ipmitool/module.properties
rename to plugins/outofbandmanagement-drivers/ipmitool/src/main/resources/META-INF/cloudstack/ipmitool/module.properties
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/resources/META-INF/cloudstack/ipmitool/spring-ipmitool-context.xml b/plugins/outofbandmanagement-drivers/ipmitool/src/main/resources/META-INF/cloudstack/ipmitool/spring-ipmitool-context.xml
similarity index 100%
rename from plugins/outofbandmanagement-drivers/ipmitool/resources/META-INF/cloudstack/ipmitool/spring-ipmitool-context.xml
rename to plugins/outofbandmanagement-drivers/ipmitool/src/main/resources/META-INF/cloudstack/ipmitool/spring-ipmitool-context.xml
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/test/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapperTest.java b/plugins/outofbandmanagement-drivers/ipmitool/src/test/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapperTest.java
similarity index 100%
rename from plugins/outofbandmanagement-drivers/ipmitool/test/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapperTest.java
rename to plugins/outofbandmanagement-drivers/ipmitool/src/test/java/org/apache/cloudstack/outofbandmanagement/driver/ipmitool/IpmitoolWrapperTest.java
diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml
index 0ae1250..d6dc491 100644
--- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml
+++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml
@@ -1,46 +1,46 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-outofbandmanagement-driver-nested-cloudstack</artifactId>
-  <name>Apache CloudStack Plugin - Power Management Driver nested-cloudstack</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-        <groupId>br.com.autonomiccs</groupId>
-        <artifactId>apache-cloudstack-java-client</artifactId>
-        <version>1.0.9</version>
-    </dependency>
-  </dependencies>
+<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-outofbandmanagement-driver-nested-cloudstack</artifactId>
+    <name>Apache CloudStack Plugin - Power Management Driver nested-cloudstack</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>br.com.autonomiccs</groupId>
+            <artifactId>apache-cloudstack-java-client</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/src/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriver.java b/plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriver.java
similarity index 100%
rename from plugins/outofbandmanagement-drivers/nested-cloudstack/src/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriver.java
rename to plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/java/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriver.java
diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/resources/META-INF/cloudstack/nested-cloudstack/module.properties b/plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/resources/META-INF/cloudstack/nested-cloudstack/module.properties
similarity index 100%
rename from plugins/outofbandmanagement-drivers/nested-cloudstack/resources/META-INF/cloudstack/nested-cloudstack/module.properties
rename to plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/resources/META-INF/cloudstack/nested-cloudstack/module.properties
diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/resources/META-INF/cloudstack/nested-cloudstack/spring-nested-cloudstack-context.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/resources/META-INF/cloudstack/nested-cloudstack/spring-nested-cloudstack-context.xml
similarity index 100%
rename from plugins/outofbandmanagement-drivers/nested-cloudstack/resources/META-INF/cloudstack/nested-cloudstack/spring-nested-cloudstack-context.xml
rename to plugins/outofbandmanagement-drivers/nested-cloudstack/src/main/resources/META-INF/cloudstack/nested-cloudstack/spring-nested-cloudstack-context.xml
diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/test/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriverTest.java b/plugins/outofbandmanagement-drivers/nested-cloudstack/src/test/java/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriverTest.java
similarity index 100%
rename from plugins/outofbandmanagement-drivers/nested-cloudstack/test/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriverTest.java
rename to plugins/outofbandmanagement-drivers/nested-cloudstack/src/test/java/org/apache/cloudstack/outofbandmanagement/driver/nestedcloudstack/NestedCloudStackOutOfBandManagementDriverTest.java
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 8aaae7a..9ed2f81 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -1,225 +1,228 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>cloudstack-plugins</artifactId>
-  <name>Apache CloudStack Plugin POM</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
+    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>cloudstack-plugins</artifactId>
+    <name>Apache CloudStack Plugin POM</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <!-- keep in alphabetic order -->
+        <module>acl/dynamic-role-based</module>
+        <module>acl/static-role-based</module>
 
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>none</phase>
-              <inherited>false</inherited>
-            </execution>
-          </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <modules>
-    <module>api/rate-limit</module>
-    <module>api/solidfire-intg-test</module>
-    <module>api/discovery</module>
-    <module>acl/static-role-based</module>
-    <module>acl/dynamic-role-based</module>
-    <module>affinity-group-processors/host-anti-affinity</module>
-    <module>affinity-group-processors/explicit-dedication</module>
-    <module>ca/root-ca</module>
-    <module>deployment-planners/user-concentrated-pod</module>
-    <module>deployment-planners/user-dispersing</module>
-    <module>deployment-planners/implicit-dedication</module>
-    <module>ha-planners/skip-heurestics</module>
-    <module>host-allocators/random</module>
-    <module>dedicated-resources</module>
-    <module>hypervisors/ovm</module>
-    <module>hypervisors/xenserver</module>
-    <module>hypervisors/kvm</module>
-    <module>event-bus/rabbitmq</module>
-    <module>event-bus/inmemory</module>
-    <module>event-bus/kafka</module>
-    <module>hypervisors/baremetal</module>
-    <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>
-    <module>network-elements/palo-alto</module>
-    <module>network-elements/netscaler</module>
-    <module>network-elements/nicira-nvp</module>
-    <module>network-elements/nuage-vsp</module>
-    <module>network-elements/bigswitch</module>
-    <module>network-elements/brocade-vcs</module>
-    <module>network-elements/stratosphere-ssp</module>
-    <module>network-elements/opendaylight</module>
-    <module>outofbandmanagement-drivers/ipmitool</module>
-    <module>outofbandmanagement-drivers/nested-cloudstack</module>
-    <module>storage-allocators/random</module>
-    <module>user-authenticators/ldap</module>
-    <module>user-authenticators/md5</module>
-    <module>user-authenticators/pbkdf2</module>
-    <module>user-authenticators/plain-text</module>
-    <module>user-authenticators/saml2</module>
-    <module>user-authenticators/sha256salted</module>
-    <module>network-elements/dns-notifier</module>
-    <module>storage/image/s3</module>
-    <module>storage/image/swift</module>
-    <module>storage/image/default</module>
-    <module>storage/image/sample</module>
-    <module>storage/volume/nexenta</module>
-    <module>storage/volume/solidfire</module>
-    <module>storage/volume/cloudbyte</module>
-    <module>storage/volume/default</module>
-    <module>storage/volume/sample</module>
-    <module>alert-handlers/snmp-alerts</module>
-    <module>alert-handlers/syslog-alerts</module>
-    <module>network-elements/internal-loadbalancer</module>
-    <module>network-elements/vxlan</module>
-    <module>network-elements/globodns</module>
-    <module>database/quota</module>
-    <module>integrations/cloudian</module>
-    <module>integrations/prometheus</module>
-    <module>affinity-group-processors/host-affinity</module>
-  </modules>
+        <module>affinity-group-processors/explicit-dedication</module>
+        <module>affinity-group-processors/host-affinity</module>
+        <module>affinity-group-processors/host-anti-affinity</module>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <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>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>      
-    </dependency>
-  </dependencies>
+        <module>alert-handlers/snmp-alerts</module>
+        <module>alert-handlers/syslog-alerts</module>
 
-  <profiles>
-    <profile>
-      <id>netapp</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>file-systems/netapp</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>f5</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>network-elements/f5</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>srx</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>network-elements/juniper-srx</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>vmware</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>hypervisors/vmware</module>
-        <module>network-elements/cisco-vnmc</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>vmware-sioc</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>api/vmware-sioc</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>mysqlha</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>database/mysql-ha</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>simulator</id>
-      <activation>
-        <property>
-          <name>simulator</name>
-        </property>
-      </activation>
-      <modules>
-        <module>hypervisors/simulator</module>
-      </modules>
-    </profile>
-  </profiles>
+        <module>api/discovery</module>
+        <module>api/rate-limit</module>
+        <module>api/solidfire-intg-test</module>
+
+        <module>ca/root-ca</module>
+
+        <module>database/quota</module>
+
+        <module>dedicated-resources</module>
+
+        <module>deployment-planners/implicit-dedication</module>
+        <module>deployment-planners/user-concentrated-pod</module>
+        <module>deployment-planners/user-dispersing</module>
+
+        <module>event-bus/inmemory</module>
+        <module>event-bus/kafka</module>
+        <module>event-bus/rabbitmq</module>
+
+        <module>ha-planners/skip-heurestics</module>
+
+        <module>host-allocators/random</module>
+
+        <module>hypervisors/baremetal</module>
+        <module>hypervisors/hyperv</module>
+        <module>hypervisors/kvm</module>
+        <module>hypervisors/ovm3</module>
+        <module>hypervisors/ovm</module>
+        <module>hypervisors/ucs</module>
+        <module>hypervisors/xenserver</module>
+
+        <module>integrations/cloudian</module>
+        <module>integrations/prometheus</module>
+
+        <module>metrics</module>
+
+        <module>network-elements/bigswitch</module>
+        <module>network-elements/dns-notifier</module>
+        <module>network-elements/juniper-contrail</module>
+        <module>network-elements/elastic-loadbalancer</module>
+        <module>network-elements/globodns</module>
+        <module>network-elements/internal-loadbalancer</module>
+        <module>network-elements/netscaler</module>
+        <module>network-elements/nicira-nvp</module>
+        <module>network-elements/opendaylight</module>
+        <module>network-elements/ovs</module>
+        <module>network-elements/palo-alto</module>
+        <module>network-elements/stratosphere-ssp</module>
+        <module>network-elements/brocade-vcs</module>
+        <module>network-elements/nuage-vsp</module>
+        <module>network-elements/vxlan</module>
+
+        <module>outofbandmanagement-drivers/ipmitool</module>
+        <module>outofbandmanagement-drivers/nested-cloudstack</module>
+
+        <module>storage/image/default</module>
+        <module>storage/image/s3</module>
+        <module>storage/image/sample</module>
+        <module>storage/image/swift</module>
+        <module>storage/volume/cloudbyte</module>
+        <module>storage/volume/default</module>
+        <module>storage/volume/nexenta</module>
+        <module>storage/volume/sample</module>
+        <module>storage/volume/solidfire</module>
+
+        <module>storage-allocators/random</module>
+
+        <module>user-authenticators/ldap</module>
+        <module>user-authenticators/md5</module>
+        <module>user-authenticators/pbkdf2</module>
+        <module>user-authenticators/plain-text</module>
+        <module>user-authenticators/saml2</module>
+        <module>user-authenticators/sha256salted</module>
+    </modules>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <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>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>f5</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>network-elements/f5</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>srx</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>network-elements/juniper-srx</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>vmware</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>hypervisors/vmware</module>
+                <module>network-elements/cisco-vnmc</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>vmware-sioc</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>api/vmware-sioc</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>mysqlha</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>database/mysql-ha</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>simulator</id>
+            <activation>
+                <property>
+                    <name>simulator</name>
+                </property>
+            </activation>
+            <modules>
+                <module>hypervisors/simulator</module>
+            </modules>
+        </profile>
+    </profiles>
 </project>
diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml
index 9903217..7cb90cc 100644
--- a/plugins/storage-allocators/random/pom.xml
+++ b/plugins/storage-allocators/random/pom.xml
@@ -1,37 +1,37 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-storage-allocator-random</artifactId>
-  <name>Apache CloudStack Plugin - Storage Allocator Random</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+    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-storage-allocator-random</artifactId>
+    <name>Apache CloudStack Plugin - Storage Allocator Random</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
new file mode 100644
index 0000000..6b912fb
--- /dev/null
+++ b/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.cloudstack.storage.allocator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.StoragePool;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator {
+    private static final Logger s_logger = Logger.getLogger(RandomStoragePoolAllocator.class);
+
+    @Override
+    public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+
+        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
+
+        long dcId = plan.getDataCenterId();
+        Long podId = plan.getPodId();
+        Long clusterId = plan.getClusterId();
+
+        if (podId == null) {
+            return null;
+        }
+
+        s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId);
+        List<StoragePoolVO> pools = storagePoolDao.listBy(dcId, podId, clusterId, ScopeType.CLUSTER);
+        if (pools.size() == 0) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("No storage pools available for allocation, returning");
+            }
+            return suitablePools;
+        }
+
+        Collections.shuffle(pools);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("RandomStoragePoolAllocator has " + pools.size() + " pools to check for allocation");
+        }
+        for (StoragePoolVO pool : pools) {
+            if (suitablePools.size() == returnUpTo) {
+                break;
+            }
+            StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
+
+            if (filter(avoid, pol, dskCh, plan)) {
+                suitablePools.add(pol);
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("RandomStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
+        }
+
+        return suitablePools;
+    }
+}
diff --git a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
deleted file mode 100644
index 4417490..0000000
--- a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements.  See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.cloudstack.storage.allocator;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.StoragePool;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator {
-    private static final Logger s_logger = Logger.getLogger(RandomStoragePoolAllocator.class);
-
-    @Override
-    public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-
-        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        long dcId = plan.getDataCenterId();
-        Long podId = plan.getPodId();
-        Long clusterId = plan.getClusterId();
-
-        if (podId == null) {
-            return null;
-        }
-
-        s_logger.debug("Looking for pools in dc: " + dcId + "  pod:" + podId + "  cluster:" + clusterId);
-        List<StoragePoolVO> pools = _storagePoolDao.listBy(dcId, podId, clusterId, ScopeType.CLUSTER);
-        if (pools.size() == 0) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("No storage pools available for allocation, returning");
-            }
-            return suitablePools;
-        }
-
-        Collections.shuffle(pools);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("RandomStoragePoolAllocator has " + pools.size() + " pools to check for allocation");
-        }
-        for (StoragePoolVO pool : pools) {
-            if (suitablePools.size() == returnUpTo) {
-                break;
-            }
-            StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
-
-            if (filter(avoid, pol, dskCh, plan)) {
-                suitablePools.add(pol);
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("RandomStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
-        }
-
-        return suitablePools;
-    }
-}
diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml
index b6d9dce..8207f14 100644
--- a/plugins/storage/image/default/pom.xml
+++ b/plugins/storage/image/default/pom.xml
@@ -1,62 +1,70 @@
-<!-- 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. -->
+<!--
+  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-storage-image-default</artifactId>
-  <name>Apache CloudStack Plugin - Storage Image default provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>  
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-    </dependency>        
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-image-default</artifactId>
+    <name>Apache CloudStack Plugin - Storage Image default provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
similarity index 100%
rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
rename to plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java
rename to plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java
diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java
similarity index 100%
rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java
rename to plugins/storage/image/default/src/main/java/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java
diff --git a/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/module.properties b/plugins/storage/image/default/src/main/resources/META-INF/cloudstack/storage-image-default/module.properties
similarity index 100%
rename from plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/module.properties
rename to plugins/storage/image/default/src/main/resources/META-INF/cloudstack/storage-image-default/module.properties
diff --git a/plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml b/plugins/storage/image/default/src/main/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml
similarity index 100%
rename from plugins/storage/image/default/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml
rename to plugins/storage/image/default/src/main/resources/META-INF/cloudstack/storage-image-default/spring-storage-image-default-context.xml
diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml
index 287d941..2f0573b 100644
--- a/plugins/storage/image/s3/pom.xml
+++ b/plugins/storage/image/s3/pom.xml
@@ -1,51 +1,52 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-storage-image-s3</artifactId>
-  <name>Apache CloudStack Plugin - Storage Image S3 provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>  
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-    </dependency>            
-  </dependencies>
+<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-storage-image-s3</artifactId>
+    <name>Apache CloudStack Plugin - Storage Image S3 provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
similarity index 100%
rename from plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
rename to plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java
diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java
rename to plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java
diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java
similarity index 100%
rename from plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java
rename to plugins/storage/image/s3/src/main/java/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java
diff --git a/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/module.properties b/plugins/storage/image/s3/src/main/resources/META-INF/cloudstack/storage-image-s3/module.properties
similarity index 100%
rename from plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/module.properties
rename to plugins/storage/image/s3/src/main/resources/META-INF/cloudstack/storage-image-s3/module.properties
diff --git a/plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml b/plugins/storage/image/s3/src/main/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml
similarity index 100%
rename from plugins/storage/image/s3/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml
rename to plugins/storage/image/s3/src/main/resources/META-INF/cloudstack/storage-image-s3/spring-storage-image-s3-context.xml
diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml
index 25f4439..69367db 100644
--- a/plugins/storage/image/sample/pom.xml
+++ b/plugins/storage/image/sample/pom.xml
@@ -1,62 +1,70 @@
-<!-- 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. -->
+<!--
+  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-storage-image-sample</artifactId>
-  <name>Apache CloudStack Plugin - Storage Image sample provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-    </dependency>            
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-image-sample</artifactId>
+    <name>Apache CloudStack Plugin - Storage Image sample provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
similarity index 100%
rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
rename to plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java
diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java b/plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java
rename to plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java
diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java
similarity index 100%
rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java
rename to plugins/storage/image/sample/src/main/java/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java
diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml
index 3508ef1..f6739ab 100644
--- a/plugins/storage/image/swift/pom.xml
+++ b/plugins/storage/image/swift/pom.xml
@@ -1,62 +1,70 @@
-<!-- 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. -->
+<!--
+  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-storage-image-swift</artifactId>
-  <name>Apache CloudStack Plugin - Storage Image Swift provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-image</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>    
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-snapshot</artifactId>
-      <version>${project.version}</version>
-    </dependency>            
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-image-swift</artifactId>
+    <name>Apache CloudStack Plugin - Storage Image Swift provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-image</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-snapshot</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
similarity index 100%
rename from plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
rename to plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java
diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java
rename to plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java
diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java
similarity index 100%
rename from plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java
rename to plugins/storage/image/swift/src/main/java/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java
diff --git a/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/module.properties b/plugins/storage/image/swift/src/main/resources/META-INF/cloudstack/storage-image-swift/module.properties
similarity index 100%
rename from plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/module.properties
rename to plugins/storage/image/swift/src/main/resources/META-INF/cloudstack/storage-image-swift/module.properties
diff --git a/plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml b/plugins/storage/image/swift/src/main/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml
similarity index 100%
rename from plugins/storage/image/swift/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml
rename to plugins/storage/image/swift/src/main/resources/META-INF/cloudstack/storage-image-swift/spring-storage-image-swift-context.xml
diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml
old mode 100755
new mode 100644
index 34b0303..17120fc
--- a/plugins/storage/volume/cloudbyte/pom.xml
+++ b/plugins/storage/volume/cloudbyte/pom.xml
@@ -1,94 +1,73 @@
 <!--
+  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
 
-    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
 
-      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.
-
+  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-storage-volume-cloudbyte</artifactId>
-  <name>Apache CloudStack Plugin - Storage Volume CloudByte Provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-default</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <version>${cs.mysql.version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <version>${cs.gson.version}</version>
-    </dependency>
-    <dependency>
-	<groupId>com.sun.jersey</groupId>
-	<artifactId>jersey-bundle</artifactId>
-	<version>1.19.4</version>
-</dependency>
-  </dependencies>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>process-classes</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-volume-cloudbyte</artifactId>
+    <name>Apache CloudStack Plugin - Storage Volume CloudByte Provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-bundle</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java
new file mode 100644
index 0000000..89e8c4f
--- /dev/null
+++ b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java
@@ -0,0 +1,412 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package org.apache.cloudstack.storage.datastore.driver;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.ElastistorUtil;
+import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ResizeVolumePayload;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeDetailVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+/**
+ * The implementation class for <code>ElastistorPrimaryDataStoreDriver</code>.
+ * This directs the public interface methods to use CloudByte's Elastistor based
+ * volumes.
+ */
+public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
+
+    private static final Logger s_logger = Logger.getLogger(ElastistorPrimaryDataStoreDriver.class);
+
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    StorageManager storageMgr;
+    @Inject
+    VolumeDetailsDao _volumeDetailsDao;
+
+    @Override
+    public DataTO getTO(DataObject data) {
+        return null;
+    }
+
+    @Override
+    public DataStoreTO getStoreTO(DataStore store) {
+        return null;
+    }
+
+    @Override
+    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
+
+        String iqn = null;
+        String errMsg = null;
+
+        CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
+
+        if (dataObject.getType() == DataObjectType.VOLUME) {
+
+            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
+
+            long storagePoolId = dataStore.getId();
+            String volumeName = volumeInfo.getName();
+            Long Iops = volumeInfo.getMaxIops();
+            // quota size of the cloudbyte volume will be increased with the given HypervisorSnapshotReserve
+            Long quotaSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId));
+
+            StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
+            VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
+
+            // if the primary storage is not managed (thick provisioned)
+            // then no need to create volume at elastistor,
+            // calling super(default) that creates a vdi(disk) only.
+            if (!(storagePool.isManaged())) {
+                super.createAsync(dataStore, dataObject, callback);
+
+                // update the volume property
+                volume.setPoolType(storagePool.getPoolType());
+                _volumeDao.update(volume.getId(), volume);
+
+                return;
+            }
+
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeInfo.getDiskOfferingId());
+
+            long capacityIops = storagePool.getCapacityIops();
+            capacityIops = capacityIops - Iops;
+
+            if (capacityIops < 0) {
+                throw new CloudRuntimeException("IOPS not available. [pool:" + storagePool.getName() + "] [availiops:" + capacityIops + "] [requirediops:" + Iops + "]");
+            }
+
+            String protocoltype = null;
+            StoragePoolVO dataStoreVO = _storagePoolDao.findById(storagePoolId);
+            String desc = diskOffering.getDisplayText();
+
+            if (desc.toLowerCase().contains("iscsi")) {
+                protocoltype = "iscsi";
+            } else if (dataStoreVO.getPoolType().equals(StoragePoolType.NetworkFilesystem) || dataStoreVO.getPoolType().equals(StoragePoolType.Filesystem)) {
+                protocoltype = "nfs";
+            } else {
+                protocoltype = "iscsi";
+            }
+
+            FileSystem esvolume = null;
+            try {
+                esvolume = ElastistorUtil.createElastistorVolume(volumeName, dataStoreVO.getUuid(), quotaSize, Iops, protocoltype, volumeName);
+            } catch (Throwable e) {
+                s_logger.error(e.toString(), e);
+                result.setResult(e.toString());
+                callback.complete(result);
+                throw new CloudRuntimeException(e.getMessage());
+            }
+
+            if (esvolume.getNfsenabled().equalsIgnoreCase("true")) {
+                volume.set_iScsiName(esvolume.getPath());
+                volume.setPoolType(StoragePoolType.NetworkFilesystem);
+            } else {
+                iqn = esvolume.getIqn();
+                String modifiediqn = "/" + iqn + "/0";
+                volume.set_iScsiName(modifiediqn);
+                volume.setPoolType(StoragePoolType.IscsiLUN);
+            }
+
+            volume.setFolder(String.valueOf(esvolume.getUuid()));
+            volume.setPoolId(storagePoolId);
+            volume.setUuid(esvolume.getUuid());
+            volume.setPath(null);
+
+            _volumeDao.update(volume.getId(), volume);
+
+            // create new volume details for the volume
+            //updateVolumeDetails(volume, esvolume);
+
+            long capacityBytes = storagePool.getCapacityBytes();
+            long usedBytes = storagePool.getUsedBytes();
+
+            Long inbytes = volume.getSize();
+
+            usedBytes += inbytes;
+
+            storagePool.setCapacityIops(capacityIops);
+            storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
+
+            _storagePoolDao.update(storagePoolId, storagePool);
+            s_logger.info("Elastistor volume creation complete.");
+        } else {
+            errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
+            s_logger.error(errMsg);
+        }
+
+        result.setResult(errMsg);
+
+        callback.complete(result);
+    }
+
+    @Override
+    public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
+
+        String errMsg = null;
+
+        StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
+
+        // if the primary storage is not managed(thick provisioned) then no need
+        // to delete volume at elastistor, just
+        // call the super(default) to delete a vdi(disk) only.
+
+        if (!(storagePool.isManaged())) {
+            super.deleteAsync(dataStore, dataObject, callback);
+            return;
+        }
+
+        if (dataObject.getType() == DataObjectType.VOLUME) {
+            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
+
+            long storagePoolId = dataStore.getId();
+            boolean result = false;
+            try {
+                result = ElastistorUtil.deleteElastistorVolume(volumeInfo.getUuid());
+            } catch (Throwable e) {
+                e.printStackTrace();
+                CommandResult result2 = new CommandResult();
+                result2.setResult(e.toString());
+                callback.complete(result2);
+            }
+
+            if (result) {
+                long usedBytes = storagePool.getUsedBytes();
+                long capacityIops = storagePool.getCapacityIops();
+
+                usedBytes -= volumeInfo.getSize();
+                capacityIops += volumeInfo.getMaxIops();
+
+                storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
+                storagePool.setCapacityIops(capacityIops < 0 ? 0 : capacityIops);
+
+                _storagePoolDao.update(storagePoolId, storagePool);
+            } else {
+                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
+            }
+
+        } else {
+            errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
+        }
+
+        CommandResult result = new CommandResult();
+
+        result.setResult(errMsg);
+
+        callback.complete(result);
+    }
+
+    @Override
+    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public boolean canCopy(DataObject srcData, DataObject destData) {
+        return false;
+    }
+
+    @Override
+    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
+
+        s_logger.debug("Resize elastistor volume started");
+        Boolean status = false;
+        VolumeObject vol = (VolumeObject) data;
+        StoragePool pool = (StoragePool) data.getDataStore();
+
+        ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload();
+
+        CreateCmdResult result = new CreateCmdResult(null, null);
+
+        StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
+
+        if (!(poolVO.isManaged())) {
+            super.resize(data, callback);
+            return;
+        }
+
+        try {
+
+            status = ElastistorUtil.updateElastistorVolumeSize(vol.getUuid(), resizeParameter.newSize);
+
+        } catch (Throwable e) {
+            s_logger.error("Resize elastistor volume failed, please contact elastistor admin.", e);
+            result.setResult(e.toString());
+            callback.complete(result);
+        }
+
+        if (status) {
+            // now updating the cloudstack storagepool usedbytes and volume
+            Long usedBytes = poolVO.getUsedBytes();
+            Long currentVolumeSize = vol.getSize();
+            Long newUsedBytes;
+
+            if (currentVolumeSize < resizeParameter.newSize) {
+                newUsedBytes = usedBytes + (resizeParameter.newSize - currentVolumeSize);
+                poolVO.setUsedBytes(newUsedBytes);
+            } else {
+                newUsedBytes = usedBytes - (currentVolumeSize - resizeParameter.newSize);
+                poolVO.setUsedBytes(newUsedBytes);
+            }
+
+            _storagePoolDao.update(pool.getId(), poolVO);
+
+            vol.getVolume().setSize(resizeParameter.newSize);
+            vol.update();
+            callback.complete(result);
+        } else {
+            callback.complete(result);
+        }
+
+    }
+
+    @Override
+    public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) {}
+
+    //this method will utilize the volume details table to add third party volume properties
+    public void updateVolumeDetails(VolumeVO volume, FileSystem esvolume) {
+
+        VolumeDetailVO compression = new VolumeDetailVO(volume.getId(), "compression", esvolume.getCompression(), false);
+        _volumeDetailsDao.persist(compression);
+        VolumeDetailVO deduplication = new VolumeDetailVO(volume.getId(), "deduplication", esvolume.getDeduplication(), false);
+        _volumeDetailsDao.persist(deduplication);
+        VolumeDetailVO sync = new VolumeDetailVO(volume.getId(), "sync", esvolume.getSync(), false);
+        _volumeDetailsDao.persist(sync);
+        VolumeDetailVO graceallowed = new VolumeDetailVO(volume.getId(), "graceallowed", esvolume.getGraceallowed(), false);
+        _volumeDetailsDao.persist(graceallowed);
+
+    }
+
+    @Override
+    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
+        VolumeInfo volume = (VolumeInfo)dataObject;
+        long volumeSize = volume.getSize();
+        Integer hypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
+
+        if (hypervisorSnapshotReserve != null) {
+            if (hypervisorSnapshotReserve < 25) {
+                hypervisorSnapshotReserve = 25;
+            }
+
+            volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
+        }
+
+        return volumeSize;
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject) {
+        return null;
+    }
+
+    @Override
+    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
+        CreateCmdResult result = null;
+        try {
+            s_logger.info("taking elastistor volume snapshot");
+            SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO();
+
+            String volumeid = snapshotTO.getVolume().getUuid();
+            String snapshotname = snapshotTO.getName();
+
+            Answer answer = ElastistorUtil.createElastistorVolumeSnapshot(volumeid, snapshotname);
+
+            if(answer.getResult() == false){
+                s_logger.info("elastistor volume snapshot failed");
+                throw new CloudRuntimeException("elastistor volume snapshot failed");
+            }else{
+                s_logger.info("elastistor volume snapshot succesfull");
+
+                snapshotTO.setPath(answer.getDetails());
+
+                CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotTO);
+
+                result = new CreateCmdResult(null, createObjectAnswer);
+
+                result.setResult(null);
+            }
+        }
+         catch (Throwable e) {
+            s_logger.debug("Failed to take snapshot: " + e.getMessage());
+            result = new CreateCmdResult(null, null);
+            result.setResult(e.toString());
+        }
+        callback.complete(result);
+    }
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Map<String, String> getCapabilities() {
+        Map<String, String> mapCapabilities = new HashMap<String, String>();
+
+        mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString());
+
+        return mapCapabilities;
+    }
+
+}
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/ElastistorPrimaryDataStoreLifeCycle.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/provider/ElastistorHostListener.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/provider/ElastistorPrimaryDataStoreProvider.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorUtil.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiService.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ElastistorVolumeApiServiceImpl.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceCmd.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorInterfaceResponse.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolCmd.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorPoolResponse.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeCmd.java
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java b/plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java
similarity index 100%
rename from plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java
rename to plugins/storage/volume/cloudbyte/src/main/java/org/apache/cloudstack/storage/datastore/util/ListElastistorVolumeResponse.java
diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties b/plugins/storage/volume/cloudbyte/src/main/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties
similarity index 100%
rename from plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties
rename to plugins/storage/volume/cloudbyte/src/main/resources/META-INF/cloudstack/storage-volume-cloudbyte/module.properties
diff --git a/plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml b/plugins/storage/volume/cloudbyte/src/main/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml
similarity index 100%
rename from plugins/storage/volume/cloudbyte/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml
rename to plugins/storage/volume/cloudbyte/src/main/resources/META-INF/cloudstack/storage-volume-cloudbyte/spring-storage-volume-cloudbyte-context.xml
diff --git a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java b/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java
deleted file mode 100644
index 74fbde5..0000000
--- a/plugins/storage/volume/cloudbyte/src/org/apache/cloudstack/storage/datastore/driver/ElastistorPrimaryDataStoreDriver.java
+++ /dev/null
@@ -1,409 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package org.apache.cloudstack.storage.datastore.driver;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.ElastistorUtil;
-import org.apache.cloudstack.storage.datastore.util.ElastistorUtil.FileSystem;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.ResizeVolumePayload;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-/**
- * The implementation class for <code>ElastistorPrimaryDataStoreDriver</code>.
- * This directs the public interface methods to use CloudByte's Elastistor based
- * volumes.
- */
-public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
-
-    private static final Logger s_logger = Logger.getLogger(ElastistorPrimaryDataStoreDriver.class);
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    DiskOfferingDao _diskOfferingDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    StorageManager storageMgr;
-    @Inject
-    VolumeDetailsDao _volumeDetailsDao;
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
-
-    @Override
-    public DataStoreTO getStoreTO(DataStore store) {
-        return null;
-    }
-
-    @Override
-    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
-
-        String iqn = null;
-        String errMsg = null;
-
-        CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
-
-        if (dataObject.getType() == DataObjectType.VOLUME) {
-
-            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
-
-            long storagePoolId = dataStore.getId();
-            String volumeName = volumeInfo.getName();
-            Long Iops = volumeInfo.getMaxIops();
-            // quota size of the cloudbyte volume will be increased with the given HypervisorSnapshotReserve
-            Long quotaSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId));
-
-            StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
-            VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
-
-            // if the primary storage is not managed (thick provisioned)
-            // then no need to create volume at elastistor,
-            // calling super(default) that creates a vdi(disk) only.
-            if (!(storagePool.isManaged())) {
-                super.createAsync(dataStore, dataObject, callback);
-
-                // update the volume property
-                volume.setPoolType(storagePool.getPoolType());
-                _volumeDao.update(volume.getId(), volume);
-
-                return;
-            }
-
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeInfo.getDiskOfferingId());
-
-            long capacityIops = storagePool.getCapacityIops();
-            capacityIops = capacityIops - Iops;
-
-            if (capacityIops < 0) {
-                throw new CloudRuntimeException("IOPS not available. [pool:" + storagePool.getName() + "] [availiops:" + capacityIops + "] [requirediops:" + Iops + "]");
-            }
-
-            String protocoltype = null;
-            StoragePoolVO dataStoreVO = _storagePoolDao.findById(storagePoolId);
-            String desc = diskOffering.getDisplayText();
-
-            if (desc.toLowerCase().contains("iscsi")) {
-                protocoltype = "iscsi";
-            } else if (dataStoreVO.getPoolType().equals(StoragePoolType.NetworkFilesystem) || dataStoreVO.getPoolType().equals(StoragePoolType.Filesystem)) {
-                protocoltype = "nfs";
-            } else {
-                protocoltype = "iscsi";
-            }
-
-            FileSystem esvolume = null;
-            try {
-                esvolume = ElastistorUtil.createElastistorVolume(volumeName, dataStoreVO.getUuid(), quotaSize, Iops, protocoltype, volumeName);
-            } catch (Throwable e) {
-                s_logger.error(e.toString(), e);
-                result.setResult(e.toString());
-                callback.complete(result);
-                throw new CloudRuntimeException(e.getMessage());
-            }
-
-            if (esvolume.getNfsenabled().equalsIgnoreCase("true")) {
-                volume.set_iScsiName(esvolume.getPath());
-                volume.setPoolType(StoragePoolType.NetworkFilesystem);
-            } else {
-                iqn = esvolume.getIqn();
-                String modifiediqn = "/" + iqn + "/0";
-                volume.set_iScsiName(modifiediqn);
-                volume.setPoolType(StoragePoolType.IscsiLUN);
-            }
-
-            volume.setFolder(String.valueOf(esvolume.getUuid()));
-            volume.setPoolId(storagePoolId);
-            volume.setUuid(esvolume.getUuid());
-            volume.setPath(null);
-
-            _volumeDao.update(volume.getId(), volume);
-
-            // create new volume details for the volume
-            //updateVolumeDetails(volume, esvolume);
-
-            long capacityBytes = storagePool.getCapacityBytes();
-            long usedBytes = storagePool.getUsedBytes();
-
-            Long inbytes = volume.getSize();
-
-            usedBytes += inbytes;
-
-            storagePool.setCapacityIops(capacityIops);
-            storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
-
-            _storagePoolDao.update(storagePoolId, storagePool);
-            s_logger.info("Elastistor volume creation complete.");
-        } else {
-            errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
-            s_logger.error(errMsg);
-        }
-
-        result.setResult(errMsg);
-
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
-
-        String errMsg = null;
-
-        StoragePoolVO storagePool = _storagePoolDao.findById(dataStore.getId());
-
-        // if the primary storage is not managed(thick provisioned) then no need
-        // to delete volume at elastistor, just
-        // call the super(default) to delete a vdi(disk) only.
-
-        if (!(storagePool.isManaged())) {
-            super.deleteAsync(dataStore, dataObject, callback);
-            return;
-        }
-
-        if (dataObject.getType() == DataObjectType.VOLUME) {
-            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
-
-            long storagePoolId = dataStore.getId();
-            boolean result = false;
-            try {
-                result = ElastistorUtil.deleteElastistorVolume(volumeInfo.getUuid());
-            } catch (Throwable e) {
-                e.printStackTrace();
-                CommandResult result2 = new CommandResult();
-                result2.setResult(e.toString());
-                callback.complete(result2);
-            }
-
-            if (result) {
-                long usedBytes = storagePool.getUsedBytes();
-                long capacityIops = storagePool.getCapacityIops();
-
-                usedBytes -= volumeInfo.getSize();
-                capacityIops += volumeInfo.getMaxIops();
-
-                storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
-                storagePool.setCapacityIops(capacityIops < 0 ? 0 : capacityIops);
-
-                _storagePoolDao.update(storagePoolId, storagePool);
-            } else {
-                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
-            }
-
-        } else {
-            errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
-        }
-
-        CommandResult result = new CommandResult();
-
-        result.setResult(errMsg);
-
-        callback.complete(result);
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        return false;
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-
-        s_logger.debug("Resize elastistor volume started");
-        Boolean status = false;
-        VolumeObject vol = (VolumeObject) data;
-        StoragePool pool = (StoragePool) data.getDataStore();
-
-        ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload();
-
-        CreateCmdResult result = new CreateCmdResult(null, null);
-
-        StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
-
-        if (!(poolVO.isManaged())) {
-            super.resize(data, callback);
-            return;
-        }
-
-        try {
-
-            status = ElastistorUtil.updateElastistorVolumeSize(vol.getUuid(), resizeParameter.newSize);
-
-        } catch (Throwable e) {
-            s_logger.error("Resize elastistor volume failed, please contact elastistor admin.", e);
-            result.setResult(e.toString());
-            callback.complete(result);
-        }
-
-        if (status) {
-            // now updating the cloudstack storagepool usedbytes and volume
-            Long usedBytes = poolVO.getUsedBytes();
-            Long currentVolumeSize = vol.getSize();
-            Long newUsedBytes;
-
-            if (currentVolumeSize < resizeParameter.newSize) {
-                newUsedBytes = usedBytes + (resizeParameter.newSize - currentVolumeSize);
-                poolVO.setUsedBytes(newUsedBytes);
-            } else {
-                newUsedBytes = usedBytes - (currentVolumeSize - resizeParameter.newSize);
-                poolVO.setUsedBytes(newUsedBytes);
-            }
-
-            _storagePoolDao.update(pool.getId(), poolVO);
-
-            vol.getVolume().setSize(resizeParameter.newSize);
-            vol.update();
-            callback.complete(result);
-        } else {
-            callback.complete(result);
-        }
-
-    }
-
-    //this method will utilize the volume details table to add third party volume properties
-    public void updateVolumeDetails(VolumeVO volume, FileSystem esvolume) {
-
-        VolumeDetailVO compression = new VolumeDetailVO(volume.getId(), "compression", esvolume.getCompression(), false);
-        _volumeDetailsDao.persist(compression);
-        VolumeDetailVO deduplication = new VolumeDetailVO(volume.getId(), "deduplication", esvolume.getDeduplication(), false);
-        _volumeDetailsDao.persist(deduplication);
-        VolumeDetailVO sync = new VolumeDetailVO(volume.getId(), "sync", esvolume.getSync(), false);
-        _volumeDetailsDao.persist(sync);
-        VolumeDetailVO graceallowed = new VolumeDetailVO(volume.getId(), "graceallowed", esvolume.getGraceallowed(), false);
-        _volumeDetailsDao.persist(graceallowed);
-
-    }
-
-    @Override
-    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
-        VolumeInfo volume = (VolumeInfo)dataObject;
-        long volumeSize = volume.getSize();
-        Integer hypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
-
-        if (hypervisorSnapshotReserve != null) {
-            if (hypervisorSnapshotReserve < 25) {
-                hypervisorSnapshotReserve = 25;
-            }
-
-            volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
-        }
-
-        return volumeSize;
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject) {
-        return null;
-    }
-
-    @Override
-    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
-        CreateCmdResult result = null;
-        try {
-            s_logger.info("taking elastistor volume snapshot");
-            SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO();
-
-            String volumeid = snapshotTO.getVolume().getUuid();
-            String snapshotname = snapshotTO.getName();
-
-            Answer answer = ElastistorUtil.createElastistorVolumeSnapshot(volumeid, snapshotname);
-
-            if(answer.getResult() == false){
-                s_logger.info("elastistor volume snapshot failed");
-                throw new CloudRuntimeException("elastistor volume snapshot failed");
-            }else{
-                s_logger.info("elastistor volume snapshot succesfull");
-
-                snapshotTO.setPath(answer.getDetails());
-
-                CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotTO);
-
-                result = new CreateCmdResult(null, createObjectAnswer);
-
-                result.setResult(null);
-            }
-        }
-         catch (Throwable e) {
-            s_logger.debug("Failed to take snapshot: " + e.getMessage());
-            result = new CreateCmdResult(null, null);
-            result.setResult(e.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Map<String, String> getCapabilities() {
-        Map<String, String> mapCapabilities = new HashMap<String, String>();
-
-        mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString());
-
-        return mapCapabilities;
-    }
-
-}
diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml
index e7383c9..6fc9d74 100644
--- a/plugins/storage/volume/default/pom.xml
+++ b/plugins/storage/volume/default/pom.xml
@@ -1,47 +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. -->
+<!--
+  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-storage-volume-default</artifactId>
-  <name>Apache CloudStack Plugin - Storage Volume default provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-volume-default</artifactId>
+    <name>Apache CloudStack Plugin - Storage Volume default provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
new file mode 100644
index 0000000..4153ba1
--- /dev/null
+++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
@@ -0,0 +1,390 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.driver;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
+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.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.RevertSnapshotCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.volume.VolumeObject;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.ResizeVolumeAnswer;
+import com.cloud.agent.api.storage.ResizeVolumeCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ResizeVolumePayload;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
+    @Override
+    public Map<String, String> getCapabilities() {
+        Map<String, String> caps = new HashMap<String, String>();
+        caps.put(DataStoreCapabilities.VOLUME_SNAPSHOT_QUIESCEVM.toString(), "false");
+        return caps;
+    }
+
+    private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class);
+    @Inject
+    DiskOfferingDao diskOfferingDao;
+    @Inject
+    VMTemplateDao templateDao;
+    @Inject
+    VolumeDao volumeDao;
+    @Inject
+    HostDao hostDao;
+    @Inject
+    StorageManager storageMgr;
+    @Inject
+    VMInstanceDao vmDao;
+    @Inject
+    SnapshotDao snapshotDao;
+    @Inject
+    PrimaryDataStoreDao primaryStoreDao;
+    @Inject
+    SnapshotManager snapshotMgr;
+    @Inject
+    EndPointSelector epSelector;
+    @Inject
+    ConfigurationDao configDao;
+    @Inject
+    TemplateManager templateManager;
+    @Inject
+    TemplateDataFactory templateDataFactory;
+
+    @Override
+    public DataTO getTO(DataObject data) {
+        return null;
+    }
+
+    @Override
+    public DataStoreTO getStoreTO(DataStore store) {
+        return null;
+    }
+
+    public Answer createVolume(VolumeInfo volume) throws StorageUnavailableException {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Creating volume: " + volume);
+        }
+
+        CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO());
+        EndPoint ep = epSelector.select(volume);
+        Answer answer = null;
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            answer = new Answer(cmd, false, errMsg);
+        } else {
+            answer = ep.sendMessage(cmd);
+        }
+        return answer;
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject) {
+        return null;
+    }
+
+    @Override
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        return false;
+    }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
+    }
+
+    @Override
+    public long getUsedBytes(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getUsedIops(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
+        return dataObject.getSize();
+    }
+
+    @Override
+    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
+        String errMsg = null;
+        Answer answer = null;
+        CreateCmdResult result = new CreateCmdResult(null, null);
+        if (data.getType() == DataObjectType.VOLUME) {
+            try {
+                answer = createVolume((VolumeInfo) data);
+                if ((answer == null) || (!answer.getResult())) {
+                    result.setSuccess(false);
+                    if (answer != null) {
+                        result.setResult(answer.getDetails());
+                    }
+                } else {
+                    result.setAnswer(answer);
+                }
+            } catch (StorageUnavailableException e) {
+                s_logger.debug("failed to create volume", e);
+                errMsg = e.toString();
+            } catch (Exception e) {
+                s_logger.debug("failed to create volume", e);
+                errMsg = e.toString();
+            }
+        }
+        if (errMsg != null) {
+            result.setResult(errMsg);
+        }
+
+        if (callback != null) {
+            callback.complete(result);
+        }
+    }
+
+    @Override
+    public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
+        DeleteCommand cmd = new DeleteCommand(data.getTO());
+
+        CommandResult result = new CommandResult();
+        try {
+            EndPoint ep = null;
+            if (data.getType() == DataObjectType.VOLUME) {
+                ep = epSelector.select(data, StorageAction.DELETEVOLUME);
+            } else {
+                ep = epSelector.select(data);
+            }
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                result.setResult(errMsg);
+            } else {
+                Answer answer = ep.sendMessage(cmd);
+                if (answer != null && !answer.getResult()) {
+                    result.setResult(answer.getDetails());
+                }
+            }
+        } catch (Exception ex) {
+            s_logger.debug("Unable to destoy volume" + data.getId(), ex);
+            result.setResult(ex.toString());
+        }
+        callback.complete(result);
+    }
+
+    @Override
+    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        DataStore store = destData.getDataStore();
+        if (store.getRole() == DataStoreRole.Primary) {
+            if ((srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE)) {
+                //For CLVM, we need to copy template to primary storage at all, just fake the copy result.
+                TemplateObjectTO templateObjectTO = new TemplateObjectTO();
+                templateObjectTO.setPath(UUID.randomUUID().toString());
+                templateObjectTO.setSize(srcdata.getSize());
+                templateObjectTO.setPhysicalSize(srcdata.getSize());
+                templateObjectTO.setFormat(Storage.ImageFormat.RAW);
+                CopyCmdAnswer answer = new CopyCmdAnswer(templateObjectTO);
+                CopyCommandResult result = new CopyCommandResult("", answer);
+                callback.complete(result);
+            } else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
+                //For CLVM, we need to pass template on secondary storage to hypervisor
+                int primaryStorageDownloadWait = StorageManager.PRIMARY_STORAGE_DOWNLOAD_WAIT.value();
+                StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
+                DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId());
+                DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore);
+
+                CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), primaryStorageDownloadWait, true);
+                EndPoint ep = epSelector.select(srcData, destData);
+                Answer answer = null;
+                if (ep == null) {
+                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                    s_logger.error(errMsg);
+                    answer = new Answer(cmd, false, errMsg);
+                } else {
+                    answer = ep.sendMessage(cmd);
+                }
+                CopyCommandResult result = new CopyCommandResult("", answer);
+                callback.complete(result);
+            }
+        }
+    }
+
+    @Override
+    public boolean canCopy(DataObject srcData, DataObject destData) {
+        //BUG fix for CLOUDSTACK-4618
+        DataStore store = destData.getDataStore();
+        if (store.getRole() == DataStoreRole.Primary && srcData.getType() == DataObjectType.TEMPLATE
+                && (destData.getType() == DataObjectType.TEMPLATE || destData.getType() == DataObjectType.VOLUME)) {
+            StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
+            if (storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.CLVM) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
+        CreateCmdResult result = null;
+        try {
+            SnapshotObjectTO snapshotTO = (SnapshotObjectTO) snapshot.getTO();
+            Object payload = snapshot.getPayload();
+            if (payload != null && payload instanceof CreateSnapshotPayload) {
+                CreateSnapshotPayload snapshotPayload = (CreateSnapshotPayload) payload;
+                snapshotTO.setQuiescevm(snapshotPayload.getQuiescevm());
+            }
+
+            CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO);
+            EndPoint ep = epSelector.select(snapshot, StorageAction.TAKESNAPSHOT);
+            Answer answer = null;
+
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send createObjectCommand, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+
+            result = new CreateCmdResult(null, answer);
+            if (answer != null && !answer.getResult()) {
+                result.setResult(answer.getDetails());
+            }
+
+            callback.complete(result);
+            return;
+        } catch (Exception e) {
+            s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
+            result = new CreateCmdResult(null, null);
+            result.setResult(e.toString());
+        }
+        callback.complete(result);
+    }
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
+        SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO();
+        RevertSnapshotCommand cmd = new RevertSnapshotCommand(snapshotTO);
+
+        CommandResult result = new CommandResult();
+        try {
+            EndPoint ep = epSelector.select(snapshotOnPrimaryStore);
+            if ( ep == null ){
+                String errMsg = "No remote endpoint to send RevertSnapshotCommand, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                result.setResult(errMsg);
+            } else {
+                Answer answer = ep.sendMessage(cmd);
+                if (answer != null && !answer.getResult()) {
+                    result.setResult(answer.getDetails());
+                }
+            }
+        } catch (Exception ex) {
+            s_logger.debug("Unable to revert snapshot " + snapshot.getId(), ex);
+            result.setResult(ex.toString());
+        }
+        callback.complete(result);
+    }
+
+    @Override
+    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
+        VolumeObject vol = (VolumeObject) data;
+        StoragePool pool = (StoragePool) data.getDataStore();
+        ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload();
+
+        ResizeVolumeCommand resizeCmd =
+                new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), resizeParameter.newSize, resizeParameter.shrinkOk,
+                        resizeParameter.instanceName);
+        CreateCmdResult result = new CreateCmdResult(null, null);
+        try {
+            ResizeVolumeAnswer answer = (ResizeVolumeAnswer) storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd);
+            if (answer != null && answer.getResult()) {
+                long finalSize = answer.getNewSize();
+                s_logger.debug("Resize: volume started at size " + vol.getSize() + " and ended at size " + finalSize);
+
+                vol.setSize(finalSize);
+                vol.update();
+            } else if (answer != null) {
+                result.setResult(answer.getDetails());
+            } else {
+                s_logger.debug("return a null answer, mark it as failed for unknown reason");
+                result.setResult("return a null answer, mark it as failed for unknown reason");
+            }
+
+        } catch (Exception e) {
+            s_logger.debug("sending resize command failed", e);
+            result.setResult(e.toString());
+        }
+
+        callback.complete(result);
+    }
+
+    @Override
+    public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) {}
+}
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
rename to plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java
similarity index 100%
rename from plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java
rename to plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java
diff --git a/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/module.properties b/plugins/storage/volume/default/src/main/resources/META-INF/cloudstack/storage-volume-default/module.properties
similarity index 100%
rename from plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/module.properties
rename to plugins/storage/volume/default/src/main/resources/META-INF/cloudstack/storage-volume-default/module.properties
diff --git a/plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml b/plugins/storage/volume/default/src/main/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml
similarity index 100%
rename from plugins/storage/volume/default/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml
rename to plugins/storage/volume/default/src/main/resources/META-INF/cloudstack/storage-volume-default/spring-storage-volume-default-context.xml
diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
deleted file mode 100644
index b5aee54..0000000
--- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.driver;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction;
-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.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.RevertSnapshotCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.volume.VolumeObject;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.storage.ResizeVolumeAnswer;
-import com.cloud.agent.api.storage.ResizeVolumeCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.configuration.Config;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.dao.HostDao;
-import com.cloud.storage.CreateSnapshotPayload;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ResizeVolumePayload;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.template.TemplateManager;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
-    @Override
-    public Map<String, String> getCapabilities() {
-        Map<String, String> caps = new HashMap<String, String>();
-        caps.put(DataStoreCapabilities.VOLUME_SNAPSHOT_QUIESCEVM.toString(), "false");
-        return caps;
-    }
-
-    private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class);
-    @Inject
-    DiskOfferingDao diskOfferingDao;
-    @Inject
-    VMTemplateDao templateDao;
-    @Inject
-    VolumeDao volumeDao;
-    @Inject
-    HostDao hostDao;
-    @Inject
-    StorageManager storageMgr;
-    @Inject
-    VMInstanceDao vmDao;
-    @Inject
-    SnapshotDao snapshotDao;
-    @Inject
-    PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    SnapshotManager snapshotMgr;
-    @Inject
-    EndPointSelector epSelector;
-    @Inject
-    ConfigurationDao configDao;
-    @Inject
-    TemplateManager templateManager;
-    @Inject
-    TemplateDataFactory templateDataFactory;
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
-
-    @Override
-    public DataStoreTO getStoreTO(DataStore store) {
-        return null;
-    }
-
-    public Answer createVolume(VolumeInfo volume) throws StorageUnavailableException {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Creating volume: " + volume);
-        }
-
-        CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO());
-        EndPoint ep = epSelector.select(volume);
-        Answer answer = null;
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            answer = new Answer(cmd, false, errMsg);
-        } else {
-            answer = ep.sendMessage(cmd);
-        }
-        return answer;
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject) {
-        return null;
-    }
-
-    @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        return false;
-    }
-
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
-    }
-
-    @Override
-    public long getUsedBytes(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getUsedIops(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
-        return dataObject.getSize();
-    }
-
-    @Override
-    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public void createAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        String errMsg = null;
-        Answer answer = null;
-        CreateCmdResult result = new CreateCmdResult(null, null);
-        if (data.getType() == DataObjectType.VOLUME) {
-            try {
-                answer = createVolume((VolumeInfo) data);
-                if ((answer == null) || (!answer.getResult())) {
-                    result.setSuccess(false);
-                    if (answer != null) {
-                        result.setResult(answer.getDetails());
-                    }
-                } else {
-                    result.setAnswer(answer);
-                }
-            } catch (StorageUnavailableException e) {
-                s_logger.debug("failed to create volume", e);
-                errMsg = e.toString();
-            } catch (Exception e) {
-                s_logger.debug("failed to create volume", e);
-                errMsg = e.toString();
-            }
-        }
-        if (errMsg != null) {
-            result.setResult(errMsg);
-        }
-
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        DeleteCommand cmd = new DeleteCommand(data.getTO());
-
-        CommandResult result = new CommandResult();
-        try {
-            EndPoint ep = null;
-            if (data.getType() == DataObjectType.VOLUME) {
-                ep = epSelector.select(data, StorageAction.DELETEVOLUME);
-            } else {
-                ep = epSelector.select(data);
-            }
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send DeleteCommand, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                result.setResult(errMsg);
-            } else {
-                Answer answer = ep.sendMessage(cmd);
-                if (answer != null && !answer.getResult()) {
-                    result.setResult(answer.getDetails());
-                }
-            }
-        } catch (Exception ex) {
-            s_logger.debug("Unable to destoy volume" + data.getId(), ex);
-            result.setResult(ex.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        DataStore store = destData.getDataStore();
-        if (store.getRole() == DataStoreRole.Primary) {
-            if ((srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE)) {
-                //For CLVM, we need to copy template to primary storage at all, just fake the copy result.
-                TemplateObjectTO templateObjectTO = new TemplateObjectTO();
-                templateObjectTO.setPath(UUID.randomUUID().toString());
-                templateObjectTO.setSize(srcdata.getSize());
-                templateObjectTO.setPhysicalSize(srcdata.getSize());
-                templateObjectTO.setFormat(Storage.ImageFormat.RAW);
-                CopyCmdAnswer answer = new CopyCmdAnswer(templateObjectTO);
-                CopyCommandResult result = new CopyCommandResult("", answer);
-                callback.complete(result);
-            } else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
-                //For CLVM, we need to pass template on secondary storage to hypervisor
-                String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-                int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
-                StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
-                DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId());
-                DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore);
-
-                CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait, true);
-                EndPoint ep = epSelector.select(srcData, destData);
-                Answer answer = null;
-                if (ep == null) {
-                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                    s_logger.error(errMsg);
-                    answer = new Answer(cmd, false, errMsg);
-                } else {
-                    answer = ep.sendMessage(cmd);
-                }
-                CopyCommandResult result = new CopyCommandResult("", answer);
-                callback.complete(result);
-            }
-        }
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        //BUG fix for CLOUDSTACK-4618
-        DataStore store = destData.getDataStore();
-        if (store.getRole() == DataStoreRole.Primary && srcData.getType() == DataObjectType.TEMPLATE
-                && (destData.getType() == DataObjectType.TEMPLATE || destData.getType() == DataObjectType.VOLUME)) {
-            StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
-            if (storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.CLVM) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
-        CreateCmdResult result = null;
-        try {
-            SnapshotObjectTO snapshotTO = (SnapshotObjectTO) snapshot.getTO();
-            Object payload = snapshot.getPayload();
-            if (payload != null && payload instanceof CreateSnapshotPayload) {
-                CreateSnapshotPayload snapshotPayload = (CreateSnapshotPayload) payload;
-                snapshotTO.setQuiescevm(snapshotPayload.getQuiescevm());
-            }
-
-            CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO);
-            EndPoint ep = epSelector.select(snapshot, StorageAction.TAKESNAPSHOT);
-            Answer answer = null;
-
-            if (ep == null) {
-                String errMsg = "No remote endpoint to send createObjectCommand, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                answer = new Answer(cmd, false, errMsg);
-            } else {
-                answer = ep.sendMessage(cmd);
-            }
-
-            result = new CreateCmdResult(null, answer);
-            if (answer != null && !answer.getResult()) {
-                result.setResult(answer.getDetails());
-            }
-
-            callback.complete(result);
-            return;
-        } catch (Exception e) {
-            s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e);
-            result = new CreateCmdResult(null, null);
-            result.setResult(e.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
-        SnapshotObjectTO snapshotTO = (SnapshotObjectTO)snapshot.getTO();
-        RevertSnapshotCommand cmd = new RevertSnapshotCommand(snapshotTO);
-
-        CommandResult result = new CommandResult();
-        try {
-            EndPoint ep = epSelector.select(snapshotOnPrimaryStore);
-            if ( ep == null ){
-                String errMsg = "No remote endpoint to send RevertSnapshotCommand, check if host or ssvm is down?";
-                s_logger.error(errMsg);
-                result.setResult(errMsg);
-            } else {
-                Answer answer = ep.sendMessage(cmd);
-                if (answer != null && !answer.getResult()) {
-                    result.setResult(answer.getDetails());
-                }
-            }
-        } catch (Exception ex) {
-            s_logger.debug("Unable to revert snapshot " + snapshot.getId(), ex);
-            result.setResult(ex.toString());
-        }
-        callback.complete(result);
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-        VolumeObject vol = (VolumeObject) data;
-        StoragePool pool = (StoragePool) data.getDataStore();
-        ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload();
-
-        ResizeVolumeCommand resizeCmd =
-                new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), resizeParameter.newSize, resizeParameter.shrinkOk,
-                        resizeParameter.instanceName);
-        CreateCmdResult result = new CreateCmdResult(null, null);
-        try {
-            ResizeVolumeAnswer answer = (ResizeVolumeAnswer) storageMgr.sendToPool(pool, resizeParameter.hosts, resizeCmd);
-            if (answer != null && answer.getResult()) {
-                long finalSize = answer.getNewSize();
-                s_logger.debug("Resize: volume started at size " + vol.getSize() + " and ended at size " + finalSize);
-
-                vol.setSize(finalSize);
-                vol.update();
-            } else if (answer != null) {
-                result.setResult(answer.getDetails());
-            } else {
-                s_logger.debug("return a null answer, mark it as failed for unknown reason");
-                result.setResult("return a null answer, mark it as failed for unknown reason");
-            }
-
-        } catch (Exception e) {
-            s_logger.debug("sending resize command failed", e);
-            result.setResult(e.toString());
-        }
-
-        callback.complete(result);
-    }
-}
diff --git a/plugins/storage/volume/default/test/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImplTest.java b/plugins/storage/volume/default/src/test/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImplTest.java
similarity index 100%
rename from plugins/storage/volume/default/test/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImplTest.java
rename to plugins/storage/volume/default/src/test/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImplTest.java
diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml
index 591a5e6..07633e0 100644
--- a/plugins/storage/volume/nexenta/pom.xml
+++ b/plugins/storage/volume/nexenta/pom.xml
@@ -1,47 +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. -->
+<!--
+  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-storage-volume-nexenta</artifactId>
-  <name>Apache CloudStack Plugin - Storage Volume Nexenta Provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-volume-nexenta</artifactId>
+    <name>Apache CloudStack Plugin - Storage Volume Nexenta Provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java
new file mode 100644
index 0000000..d59fce4
--- /dev/null
+++ b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.driver;
+
+import static org.apache.cloudstack.storage.datastore.util.NexentaUtil.NexentaPluginParameters;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance;
+import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.NexentaStorZvol;
+import org.apache.cloudstack.storage.datastore.util.NexentaUtil;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.host.Host;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.dao.AccountDao;
+
+public class NexentaPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
+    private static final Logger logger = Logger.getLogger(NexentaPrimaryDataStoreDriver.class);
+
+    @Override
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        return false;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public long getUsedBytes(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getUsedIops(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
+        return 0;
+    }
+
+    @Override
+    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
+        return 0;
+    }
+
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private StoragePoolDetailsDao _storagePoolDetailsDao;
+    @Inject
+    private AccountDao _accountDao;
+
+    @Override
+    public Map<String, String> getCapabilities() {
+        return null;
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject) {
+        return null;
+    }
+
+    @Override
+    public DataTO getTO(DataObject data) {
+        return null;
+    }
+
+    @Override
+    public DataStoreTO getStoreTO(DataStore store) {
+        return null;
+    }
+
+    private NexentaStorAppliance getNexentaStorAppliance(long storagePoolId) {
+        NexentaPluginParameters parameters = new NexentaPluginParameters();
+
+        parameters.setNmsUrl(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.NMS_URL).getValue());
+        parameters.setVolume(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME).getValue());
+        parameters.setStorageType(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_TYPE).getValue());
+        parameters.setStorageHost(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_HOST).getValue());
+        parameters.setStoragePort(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PORT).getValue());
+        parameters.setStoragePath(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PATH).getValue());
+        parameters.setSparseVolumes(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.SPARSE_VOLUMES).getValue());
+        parameters.setVolumeBlockSize(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME_BLOCK_SIZE).getValue());
+
+        return new NexentaStorAppliance(parameters);
+    }
+
+    @Override
+    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {}
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {}
+
+    @Override
+    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
+        String iqn = null;
+        String errorMessage = null;
+
+        if (dataObject.getType() != DataObjectType.VOLUME) {
+            errorMessage = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
+        } else {
+            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
+
+            long storagePoolId = dataStore.getId();
+            NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
+
+            // TODO: maybe we should use md5(volume name) as volume name
+            NexentaStorZvol zvol = (NexentaStorZvol) appliance.createVolume(volumeInfo.getName(), volumeInfo.getSize());
+            iqn = zvol.getIqn();
+
+            VolumeVO volume = this._volumeDao.findById(volumeInfo.getId());
+            volume.set_iScsiName(iqn);
+            volume.setFolder(zvol.getName());
+            volume.setPoolType(Storage.StoragePoolType.IscsiLUN);
+            volume.setPoolId(storagePoolId);
+            _volumeDao.update(volume.getId(), volume);
+
+            StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
+            long capacityBytes = storagePool.getCapacityBytes();
+            long usedBytes = storagePool.getUsedBytes();
+            usedBytes += volumeInfo.getSize();
+            storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
+            _storagePoolDao.update(storagePoolId, storagePool);
+        }
+
+        CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errorMessage == null, errorMessage));
+        result.setResult(errorMessage);
+        callback.complete(result);
+    }
+
+    @Override
+    public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
+        String errorMessage = null;
+        if (data.getType() == DataObjectType.VOLUME) {
+            VolumeInfo volumeInfo = (VolumeInfo) data;
+            long storagePoolId = store.getId();
+            NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
+            StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
+
+
+
+//            _storagePoolDao.update(stoagePoolId);
+        } else {
+            errorMessage = String.format(
+                    "Invalid DataObjectType(%s) passed to deleteAsync",
+                    data.getType());
+        }
+        CommandResult result = new CommandResult();
+        result.setResult(errorMessage);
+        callback.complete(result);
+    }
+
+    @Override
+    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {}
+
+    @Override
+    public boolean canCopy(DataObject srcData, DataObject destData) {
+        return false;
+    }
+
+    @Override
+    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {}
+
+    @Override
+    public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) {}
+}
diff --git a/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java
new file mode 100644
index 0000000..3273566
--- /dev/null
+++ b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.lifecylce;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.datastore.util.NexentaUtil;
+import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolAutomation;
+
+public class NexentaPrimaryDataStoreLifeCycle
+        implements PrimaryDataStoreLifeCycle {
+    private static final Logger logger =
+            Logger.getLogger(NexentaPrimaryDataStoreLifeCycle.class);
+
+    @Inject
+    private DataCenterDao zoneDao;
+    @Inject
+    private PrimaryDataStoreHelper dataStoreHelper;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    StorageManager _storageMgr;
+    @Inject
+    private StoragePoolAutomation storagePoolAutomation;
+
+    @Override
+    public DataStore initialize(Map<String, Object> dsInfos) {
+        String url = (String) dsInfos.get("url");
+        Long zoneId = (Long) dsInfos.get("zoneId");
+        String storagePoolName = (String) dsInfos.get("name");
+        String providerName = (String) dsInfos.get("providerName");
+        Long capacityBytes = (Long)dsInfos.get("capacityBytes");
+        Long capacityIops = (Long)dsInfos.get("capacityIops");
+        String tags = (String)dsInfos.get("tags");
+        Map<String, String> details = (Map<String, String>) dsInfos.get("details");
+        NexentaUtil.NexentaPluginParameters params = NexentaUtil.parseNexentaPluginUrl(url);
+        DataCenterVO zone = zoneDao.findById(zoneId);
+        String uuid = String.format("%s_%s_%s", NexentaUtil.PROVIDER_NAME, zone.getUuid(), params.getNmsUrl().getHost());
+
+        if (capacityBytes == null || capacityBytes <= 0) {
+            throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0.");
+        }
+
+        if (capacityIops == null || capacityIops <= 0) {
+            throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
+        }
+
+        PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
+
+        parameters.setHost(params.getStorageHost());
+        parameters.setPort(params.getStoragePort());
+        parameters.setPath(params.getStoragePath());
+        parameters.setType(params.getStorageType());
+        parameters.setUuid(uuid);
+        parameters.setZoneId(zoneId);
+        parameters.setName(storagePoolName);
+        parameters.setProviderName(providerName);
+        parameters.setManaged(true);
+        parameters.setCapacityBytes(capacityBytes);
+        parameters.setUsedBytes(0);
+        parameters.setCapacityIops(capacityIops);
+        parameters.setHypervisorType(Hypervisor.HypervisorType.Any);
+        parameters.setTags(tags);
+
+        details.put(NexentaUtil.NMS_URL, params.getNmsUrl().toString());
+
+        details.put(NexentaUtil.VOLUME, params.getVolume());
+        details.put(NexentaUtil.SPARSE_VOLUMES, params.isSparseVolumes().toString());
+
+        details.put(NexentaUtil.STORAGE_TYPE, params.getStorageType().toString());
+        details.put(NexentaUtil.STORAGE_HOST, params.getStorageHost());
+        details.put(NexentaUtil.STORAGE_PORT, params.getStoragePort().toString());
+        details.put(NexentaUtil.STORAGE_PATH, params.getStoragePath());
+
+        parameters.setDetails(details);
+
+        // this adds a row in the cloud.storage_pool table for this SolidFire cluster
+        return dataStoreHelper.createPrimaryDataStore(parameters);
+    }
+
+    @Override
+    public boolean attachCluster(DataStore store, ClusterScope scope) {
+        return true;
+    }
+
+    @Override
+    public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
+        return true;
+    }
+
+    @Override
+    public boolean attachZone(DataStore dataStore, ZoneScope scope, Hypervisor.HypervisorType hypervisorType) {
+        dataStoreHelper.attachZone(dataStore);
+
+        List<HostVO> xenServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.XenServer, scope.getScopeId());
+        List<HostVO> vmWareServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.VMware, scope.getScopeId());
+        List<HostVO> kvmHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.KVM, scope.getScopeId());
+        List<HostVO> hosts = new ArrayList<HostVO>();
+
+        hosts.addAll(xenServerHosts);
+        hosts.addAll(vmWareServerHosts);
+        hosts.addAll(kvmHosts);
+
+        for (HostVO host : hosts) {
+            try {
+                _storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId());
+            } catch (Exception e) {
+                logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean maintain(DataStore store) {
+        storagePoolAutomation.maintain(store);
+        dataStoreHelper.maintain(store);
+
+        return true;
+    }
+
+    @Override
+    public boolean cancelMaintain(DataStore store) {
+        dataStoreHelper.cancelMaintain(store);
+        storagePoolAutomation.cancelMaintain(store);
+
+        return true;
+    }
+
+    @Override
+    public void enableStoragePool(DataStore dataStore) {
+        dataStoreHelper.enable(dataStore);
+    }
+
+    @Override
+    public void disableStoragePool(DataStore dataStore) {
+        dataStoreHelper.disable(dataStore);
+    }
+
+    @Override
+    public boolean deleteDataStore(DataStore store) {
+        return dataStoreHelper.deletePrimaryDataStore(store);
+    }
+
+    @Override
+    public boolean migrateToObjectStore(DataStore store) {
+        return false;
+    }
+
+    @Override
+    public void updateStoragePool(StoragePool storagePool, Map<String, String> details) {
+    }
+}
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java
similarity index 100%
rename from plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java
rename to plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java
similarity index 100%
rename from plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java
rename to plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java
similarity index 100%
rename from plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java
rename to plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java
similarity index 100%
rename from plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java
rename to plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java
diff --git a/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java
new file mode 100644
index 0000000..fbb6645
--- /dev/null
+++ b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java
@@ -0,0 +1,418 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.util;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+import org.apache.cloudstack.storage.datastore.util.NexentaNmsClient.NmsResponse;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.gson.annotations.SerializedName;
+
+public class NexentaStorAppliance {
+    private static final Logger logger = LogManager.getLogger(NexentaStorAppliance.class);
+
+    protected NexentaNmsClient client;
+    protected NexentaUtil.NexentaPluginParameters parameters;
+
+    public NexentaStorAppliance(NexentaUtil.NexentaPluginParameters parameters) {
+        client = new NexentaNmsClient(parameters.getNmsUrl());
+        this.parameters = parameters;
+    }
+
+    NexentaStorAppliance(NexentaNmsClient client, NexentaUtil.NexentaPluginParameters parameters) {
+        this.client = client;
+        this.parameters = parameters;
+    }
+
+    String getVolumeName(String volumeName) {
+        if (volumeName.startsWith("/")) {
+            return String.format("%s%s", parameters.getVolume(), volumeName);
+        }
+        return String.format("%s/%s", parameters.getVolume(), volumeName);
+    }
+
+    static String getTargetName(String volumeName) {
+        return NexentaUtil.ISCSI_TARGET_NAME_PREFIX + volumeName;
+    }
+
+    static String getTargetGroupName(String volumeName) {
+        return NexentaUtil.ISCSI_TARGET_GROUP_PREFIX + volumeName;
+    }
+
+    @SuppressWarnings("unused")
+    static final class IntegerNmsResponse extends NmsResponse {
+        Integer result;
+
+        IntegerNmsResponse(int result) {
+            this.result = Integer.valueOf(result);
+        }
+
+        public Integer getResult() {
+            return result;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static final class IscsiTarget {
+        protected String status;
+        protected String protocol;
+        protected String name;
+        protected String sessions;
+        protected String alias;
+        protected String provider;
+
+        IscsiTarget(String status, String protocol, String name, String sessions, String alias, String provider) {
+            this.status = status;
+            this.protocol = protocol;
+            this.name = name;
+            this.sessions = sessions;
+            this.alias = alias;
+            this.provider = provider;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static final class ListOfIscsiTargetsNmsResponse extends NmsResponse {
+        protected HashMap<String, IscsiTarget> result;
+
+        ListOfIscsiTargetsNmsResponse() {}
+
+        ListOfIscsiTargetsNmsResponse(HashMap<String, IscsiTarget> result) {
+            this.result = result;
+        }
+
+        public HashMap<String, IscsiTarget> getResult() {
+            return result;
+        }
+    }
+
+    /**
+     * Checks if iSCSI target exists.
+     * @param targetName iSCSI target name
+     * @return true if iSCSI target exists, else false
+     */
+    boolean isIscsiTargetExists(String targetName) {
+        ListOfIscsiTargetsNmsResponse response = (ListOfIscsiTargetsNmsResponse) client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets");
+        if (response == null) {
+            return false;
+        }
+        HashMap<String, IscsiTarget> result = response.getResult();
+        return result != null && result.keySet().contains(targetName);
+    }
+
+    @SuppressWarnings("unused")
+    static final class CreateIscsiTargetRequestParams {
+        @SerializedName("target_name") String targetName;
+
+        CreateIscsiTargetRequestParams(String targetName) {
+            this.targetName = targetName;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            return other instanceof CreateIscsiTargetRequestParams && targetName.equals(((CreateIscsiTargetRequestParams) other).targetName);
+        }
+    }
+
+    /**
+     * Creates iSCSI target on NexentaStor Appliance.
+     * @param targetName iSCSI target name
+     */
+    void createIscsiTarget(String targetName) {
+        try {
+            client.execute(NmsResponse.class, "iscsitarget", "create_target", new CreateIscsiTargetRequestParams(targetName));
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("already configured")) {
+                throw ex;
+            }
+            logger.debug("Ignored target creation error: " + ex);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static final class ListOfStringsNmsResponse extends NmsResponse {
+        LinkedList<String> result;
+
+        ListOfStringsNmsResponse() {}
+
+        ListOfStringsNmsResponse(LinkedList<String> result) {
+            this.result = result;
+        }
+
+        public LinkedList<String> getResult() {
+            return result;
+        }
+    }
+
+    /**
+     * Checks if iSCSI target group already exists on NexentaStor Appliance.
+     * @param targetGroupName iSCSI target group name
+     * @return true if iSCSI target group already exists, else false
+     */
+    boolean isIscsiTargetGroupExists(String targetGroupName) {
+        ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups");
+        if (response == null) {
+            return false;
+        }
+        LinkedList<String> result = response.getResult();
+        return result != null && result.contains(targetGroupName);
+    }
+
+    /**
+     * Creates iSCSI target group on NexentaStor Appliance.
+     * @param targetGroupName iSCSI target group name
+     */
+    void createIscsiTargetGroup(String targetGroupName) {
+        try {
+            client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName);
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) {
+                throw ex;
+            }
+            logger.info("Ignored target group creation error: " + ex);
+        }
+    }
+
+    /**
+     * Checks if iSCSI target is member of target group.
+     * @param targetGroupName iSCSI target group name
+     * @param targetName iSCSI target name
+     * @return true if target is member of iSCSI target group, else false
+     */
+    boolean isTargetMemberOfTargetGroup(String targetGroupName, String targetName) {
+        ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName);
+        if (response == null) {
+            return false;
+        }
+        LinkedList<String> result = response.getResult();
+        return result != null && result.contains(targetName);
+    }
+
+    /**
+     * Adds iSCSI target to target group.
+     * @param targetGroupName iSCSI target group name
+     * @param targetName iSCSI target name
+     */
+    void addTargetGroupMember(String targetGroupName, String targetName) {
+        try {
+            client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName);
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) {
+                throw ex;
+            }
+            logger.debug("Ignored target group member addition error: " + ex);
+        }
+    }
+
+    /**
+     * Checks if LU already exists on NexentaStor appliance.
+     * @param luName LU name
+     * @return true if LU already exists, else false
+     */
+    boolean isLuExists(String luName) {
+        IntegerNmsResponse response;
+        try {
+            response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", luName);
+        } catch (CloudRuntimeException ex) {
+            if (ex.getMessage().contains("does not exist")) {
+                return false;
+            }
+            throw ex;
+        }
+        return response!= null && response.getResult() > 0;
+    }
+
+    @SuppressWarnings("unused")
+    static final class LuParams {
+        @Override
+        public boolean equals(Object other) {
+            return other instanceof LuParams;
+        }
+    }
+
+    /**
+     * Creates LU for volume.
+     * @param volumeName volume name
+     */
+    void createLu(String volumeName) {
+        try {
+            client.execute(NmsResponse.class, "scsidisk", "create_lu", volumeName, new LuParams());
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("in use")) {
+                throw ex;
+            }
+            logger.info("Ignored LU creation error: " + ex);
+        }
+    }
+
+    /**
+     * Checks if LU shared on NexentaStor appliance.
+     * @param luName LU name
+     * @return true if LU was already shared, else false
+     */
+    boolean isLuShared(String luName) {
+        IntegerNmsResponse response;
+        try {
+            response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName);
+        } catch (CloudRuntimeException ex) {
+            if (ex.getMessage().contains("does not exist")) {
+                return false;
+            }
+            throw ex;
+        }
+        return response != null && response.getResult() > 0;
+    }
+
+    @SuppressWarnings("unused")
+    static final class MappingEntry {
+        @SerializedName("target_group") String targetGroup;
+        String lun;
+        String zvol;
+        @SerializedName("host_group") String hostGroup;
+        @SerializedName("entry_number") String entryNumber;
+
+        MappingEntry(String targetGroup, String lun) {
+            this.targetGroup = targetGroup;
+            this.lun = lun;
+        }
+
+        static boolean isEquals(Object a, Object b) {
+            return (a == null && b == null) || (a != null && a.equals(b));
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof MappingEntry) {
+                MappingEntry o = (MappingEntry) other;
+                return isEquals(targetGroup, o.targetGroup) && isEquals(lun, o.lun) && isEquals(zvol, o.zvol) &&
+                        isEquals(hostGroup, o.hostGroup) && isEquals(entryNumber, o.entryNumber);
+            }
+            return false;
+        }
+    }
+
+    @SuppressWarnings("unused")
+    static final class AddMappingEntryNmsResponse extends NmsResponse {
+        MappingEntry result;
+    }
+
+    /**
+     * Adds LU mapping entry to iSCSI target group.
+     * @param luName LU name
+     * @param targetGroupName iSCSI target group name
+     */
+    void addLuMappingEntry(String luName, String targetGroupName) {
+        MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0");
+        try {
+            client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry);
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("view already exists")) {
+                throw ex;
+            }
+            logger.debug("Ignored LU mapping entry addition error " + ex);
+        }
+    }
+
+    NexentaStorZvol createIscsiVolume(String volumeName, Long volumeSize) {
+        final String zvolName = getVolumeName(volumeName);
+        String volumeSizeString = String.format("%dB", volumeSize);
+
+        client.execute(NmsResponse.class, "zvol", "create", zvolName, volumeSizeString, parameters.getVolumeBlockSize(), parameters.isSparseVolumes());
+
+        final String targetName = getTargetName(volumeName);
+        final String targetGroupName = getTargetGroupName(volumeName);
+
+        if (!isIscsiTargetExists(targetName)) {
+            createIscsiTarget(targetName);
+        }
+
+        if (!isIscsiTargetGroupExists(targetGroupName)) {
+            createIscsiTargetGroup(targetGroupName);
+        }
+
+        if (!isTargetMemberOfTargetGroup(targetGroupName, targetName)) {
+            addTargetGroupMember(targetGroupName, targetName);
+        }
+
+        if (!isLuExists(zvolName)) {
+            createLu(zvolName);
+        }
+
+        if (!isLuShared(zvolName)) {
+            addLuMappingEntry(zvolName, targetGroupName);
+        }
+
+        return new NexentaStorZvol(zvolName, targetName);
+    }
+
+    static abstract class NexentaStorVolume {
+        protected String name;
+
+        NexentaStorVolume(String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+    public static final class NexentaStorZvol extends NexentaStorVolume {
+        protected String iqn;
+
+        public NexentaStorZvol(String name, String iqn) {
+            super(name);
+            this.iqn = iqn;
+        }
+
+        public String getIqn() {
+            return iqn;
+        }
+    }
+
+    public void deleteIscsiVolume(String volumeName) {
+        try {
+            NmsResponse response = client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "");
+        } catch (CloudRuntimeException ex) {
+            if (!ex.getMessage().contains("does not exist")) {
+                throw ex;
+            }
+            logger.debug(String.format(
+                    "Volume %s does not exist, it seems it was already " +
+                            "deleted.", volumeName));
+        }
+    }
+
+    public NexentaStorVolume createVolume(String volumeName, Long volumeSize) {
+        return createIscsiVolume(volumeName, volumeSize);
+    }
+
+    public void deleteVolume(String volumeName) {
+        deleteIscsiVolume(volumeName);
+    }
+}
diff --git a/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java
new file mode 100644
index 0000000..7eef85b
--- /dev/null
+++ b/plugins/storage/volume/nexenta/src/main/java/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.util;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.StringTokenizer;
+
+import com.cloud.storage.Storage;
+
+public class NexentaUtil {
+    public static final String PROVIDER_NAME = "Nexenta";
+
+    public static final String NMS_URL = "nmsUrl";
+    public static final String VOLUME = "volume";
+
+    public static final String STORAGE_HOST = "storageHost";
+    public static final String STORAGE_PORT = "storagePort";
+    public static final String STORAGE_TYPE = "storageType";
+    public static final String STORAGE_PATH = "storagePath";
+
+    public static final String DEFAULT_NMS_USER = "admin";
+    public static final String DEFAULT_NMS_PASSWORD = "nexenta";
+
+    public static final String SPARSE_VOLUMES = "sparseVolumes";
+    public static final String VOLUME_BLOCK_SIZE = "volumeBlockSize";
+
+    public static final int DEFAULT_NMS_PORT = 2000;
+    public static final int DEFAULT_ISCSI_TARGET_PORTAL_PORT = 3260;
+    public static final int DEFAULT_NFS_PORT = 2049;
+
+    public static final String ISCSI_TARGET_NAME_PREFIX = "iqn.1986-03.com.sun:02:cloudstack-";
+    public static final String ISCSI_TARGET_GROUP_PREFIX = "cloudstack/";
+
+    /**
+     * Parse NMS url into normalized parts like scheme, user, host and others.
+     *
+     * Example NMS URL:
+     *    auto://admin:nexenta@192.168.1.1:2000/
+     *
+     * NMS URL parts:
+     *    auto                true if url starts with auto://, protocol will be automatically switched to https if http not supported;
+     *    scheme (auto)       connection protocol (http or https);
+     *    user (admin)        NMS user;
+     *    password (nexenta)  NMS password;
+     *    host (192.168.1.1)  NMS host;
+     *    port (2000)         NMS port.
+     *
+     * @param nmsUrl url string to parse
+     * @return instance of NexentaConnection class
+     */
+    public static NexentaNmsUrl parseNmsUrl(String nmsUrl) {
+        URI uri;
+
+        try {
+            uri = new URI(nmsUrl);
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException("Invalid URI: " + nmsUrl);
+        }
+
+        boolean isAuto = false;
+        String schema = uri.getScheme();
+        if (schema == null || schema.isEmpty() || "auto".equalsIgnoreCase(schema)) {
+            schema = "http";
+            isAuto = true;
+        }
+
+        String username, password, userInfo = uri.getUserInfo();
+        if (userInfo == null) {
+            username = DEFAULT_NMS_USER;
+            password = DEFAULT_NMS_PASSWORD;
+        } else {
+            if (userInfo.indexOf(':') < 0) {
+                username = userInfo;
+                password = DEFAULT_NMS_PASSWORD;
+            } else {
+                String[] parts = userInfo.split(":", 2);
+                username = parts[0];
+                password = parts[1];
+            }
+        }
+
+        String host = uri.getHost();
+        if (host == null) {
+            throw new IllegalArgumentException(String.format("NMS host required: %s.", nmsUrl));
+        }
+
+        int port = uri.getPort();
+        if (port == -1) {
+            port = DEFAULT_NMS_PORT;
+        }
+
+        return new NexentaNmsUrl(isAuto, schema, username, password, host, port);
+    }
+
+    public static Storage.StoragePoolType getStorageType(String v) {
+        if ("iSCSI".equalsIgnoreCase(v)) {
+            return Storage.StoragePoolType.Iscsi;
+        } else if ("NFS".equalsIgnoreCase(v)) {
+            return Storage.StoragePoolType.NetworkFilesystem;
+        }
+        return Storage.StoragePoolType.Iscsi;
+    }
+
+    public static class NexentaPluginParameters {
+        protected NexentaNmsUrl nmsUrl;
+        protected String volume;
+        protected Storage.StoragePoolType storageType = Storage.StoragePoolType.Iscsi;
+        protected String storageHost;
+        protected Integer storagePort;
+        protected String storagePath;
+        protected Boolean sparseVolumes = false;
+        protected String volumeBlockSize = "8K";
+
+        public void setNmsUrl(String url) {
+            this.nmsUrl = NexentaUtil.parseNmsUrl(url);
+        }
+
+        public NexentaNmsUrl getNmsUrl() {
+            return nmsUrl;
+        }
+
+        public void setVolume(String volume) {
+            if (volume.endsWith("/")) {
+                this.volume = volume.substring(0, volume.length() - 1);
+            } else {
+                this.volume = volume;
+            }
+        }
+
+        public String getVolume() {
+            return volume;
+        }
+
+        public void setStorageType(String storageType) {
+            this.storageType = NexentaUtil.getStorageType(storageType);
+        }
+
+        public Storage.StoragePoolType getStorageType() {
+            return storageType;
+        }
+
+        public void setStorageHost(String host) {
+            this.storageHost = host;
+        }
+
+        public String getStorageHost() {
+            if (storageHost == null && nmsUrl != null) {
+                return nmsUrl.getHost();
+            }
+            return storageHost;
+        }
+
+        public void setStoragePort(String port) {
+            this.storagePort = Integer.parseInt(port);
+        }
+
+        public Integer getStoragePort() {
+            if (storagePort == null && storageType != null) {
+                if (storageType == Storage.StoragePoolType.Iscsi) {
+                    return DEFAULT_ISCSI_TARGET_PORTAL_PORT;
+                } else {
+                    return DEFAULT_NFS_PORT;
+                }
+            }
+            return storagePort;
+        }
+
+        public void setStoragePath(String path) {
+            this.storagePath = path;
+        }
+
+        public String getStoragePath() {
+            return storagePath;
+        }
+
+        public void setSparseVolumes(String sparseVolumes) {
+            this.sparseVolumes = Boolean.TRUE.toString().equalsIgnoreCase(sparseVolumes);
+        }
+
+        public Boolean isSparseVolumes() {
+            return sparseVolumes;
+        }
+
+        public void setVolumeBlockSize(String volumeBlockSize) {
+            this.volumeBlockSize = volumeBlockSize;
+        }
+
+        public String getVolumeBlockSize() {
+            return volumeBlockSize;
+        }
+    }
+
+    public static NexentaPluginParameters parseNexentaPluginUrl(String url) {
+        final String delimiter1 = ";";
+        final String delimiter2 = "=";
+        StringTokenizer st = new StringTokenizer(url, delimiter1);
+        NexentaPluginParameters params = new NexentaPluginParameters();
+        while (st.hasMoreElements()) {
+            String token = st.nextElement().toString();
+            int idx = token.indexOf(delimiter2);
+            if (idx == -1) {
+                throw new RuntimeException("Invalid URL format");
+            }
+            String[] urlKeyAndValue = token.split(delimiter2, 2);
+            if (NMS_URL.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setNmsUrl(urlKeyAndValue[1]);
+            } else if (VOLUME.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setVolume(urlKeyAndValue[1]);
+            } else if (STORAGE_TYPE.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setStorageType(urlKeyAndValue[1]);
+            } else if (STORAGE_HOST.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setStorageHost(urlKeyAndValue[1]);
+            } else if (STORAGE_PORT.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setStoragePort(urlKeyAndValue[1]);
+            } else if (STORAGE_PATH.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setStoragePath(urlKeyAndValue[1]);
+            } else if (SPARSE_VOLUMES.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setSparseVolumes(urlKeyAndValue[1]);
+            } else if (VOLUME_BLOCK_SIZE.equalsIgnoreCase(urlKeyAndValue[0])) {
+                params.setVolumeBlockSize(urlKeyAndValue[1]);
+            }
+        }
+        return params;
+    }
+}
diff --git a/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties b/plugins/storage/volume/nexenta/src/main/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties
similarity index 100%
rename from plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties
rename to plugins/storage/volume/nexenta/src/main/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties
diff --git a/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml b/plugins/storage/volume/nexenta/src/main/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml
similarity index 100%
rename from plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml
rename to plugins/storage/volume/nexenta/src/main/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java
deleted file mode 100644
index c6ae3ed..0000000
--- a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.driver;
-
-import static org.apache.cloudstack.storage.datastore.util.NexentaUtil.NexentaPluginParameters;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance;
-import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.NexentaStorZvol;
-import org.apache.cloudstack.storage.datastore.util.NexentaUtil;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.host.Host;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.dao.AccountDao;
-
-public class NexentaPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
-    private static final Logger logger = Logger.getLogger(NexentaPrimaryDataStoreDriver.class);
-
-    @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
-        //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public long getUsedBytes(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getUsedIops(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
-        return 0;
-    }
-
-    @Override
-    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
-        return 0;
-    }
-
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject
-    private AccountDao _accountDao;
-
-    @Override
-    public Map<String, String> getCapabilities() {
-        return null;
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject) {
-        return null;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
-
-    @Override
-    public DataStoreTO getStoreTO(DataStore store) {
-        return null;
-    }
-
-    private NexentaStorAppliance getNexentaStorAppliance(long storagePoolId) {
-        NexentaPluginParameters parameters = new NexentaPluginParameters();
-
-        parameters.setNmsUrl(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.NMS_URL).getValue());
-        parameters.setVolume(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME).getValue());
-        parameters.setStorageType(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_TYPE).getValue());
-        parameters.setStorageHost(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_HOST).getValue());
-        parameters.setStoragePort(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PORT).getValue());
-        parameters.setStoragePath(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PATH).getValue());
-        parameters.setSparseVolumes(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.SPARSE_VOLUMES).getValue());
-        parameters.setVolumeBlockSize(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME_BLOCK_SIZE).getValue());
-
-        return new NexentaStorAppliance(parameters);
-    }
-
-    @Override
-    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {}
-
-    @Override
-    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {}
-
-    @Override
-    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
-        String iqn = null;
-        String errorMessage = null;
-
-        if (dataObject.getType() != DataObjectType.VOLUME) {
-            errorMessage = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
-        } else {
-            VolumeInfo volumeInfo = (VolumeInfo) dataObject;
-
-            long storagePoolId = dataStore.getId();
-            NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
-
-            // TODO: maybe we should use md5(volume name) as volume name
-            NexentaStorZvol zvol = (NexentaStorZvol) appliance.createVolume(volumeInfo.getName(), volumeInfo.getSize());
-            iqn = zvol.getIqn();
-
-            VolumeVO volume = this._volumeDao.findById(volumeInfo.getId());
-            volume.set_iScsiName(iqn);
-            volume.setFolder(zvol.getName());
-            volume.setPoolType(Storage.StoragePoolType.IscsiLUN);
-            volume.setPoolId(storagePoolId);
-            _volumeDao.update(volume.getId(), volume);
-
-            StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
-            long capacityBytes = storagePool.getCapacityBytes();
-            long usedBytes = storagePool.getUsedBytes();
-            usedBytes += volumeInfo.getSize();
-            storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
-            _storagePoolDao.update(storagePoolId, storagePool);
-        }
-
-        CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errorMessage == null, errorMessage));
-        result.setResult(errorMessage);
-        callback.complete(result);
-    }
-
-    @Override
-    public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
-        String errorMessage = null;
-        if (data.getType() == DataObjectType.VOLUME) {
-            VolumeInfo volumeInfo = (VolumeInfo) data;
-            long storagePoolId = store.getId();
-            NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId);
-            StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
-
-
-
-//            _storagePoolDao.update(stoagePoolId);
-        } else {
-            errorMessage = String.format(
-                    "Invalid DataObjectType(%s) passed to deleteAsync",
-                    data.getType());
-        }
-        CommandResult result = new CommandResult();
-        result.setResult(errorMessage);
-        callback.complete(result);
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {}
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        return false;
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {}
-}
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java
deleted file mode 100644
index 4fffb34..0000000
--- a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.lifecylce;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.storage.datastore.util.NexentaUtil;
-import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.host.HostVO;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolAutomation;
-
-public class NexentaPrimaryDataStoreLifeCycle
-        implements PrimaryDataStoreLifeCycle {
-    private static final Logger logger =
-            Logger.getLogger(NexentaPrimaryDataStoreLifeCycle.class);
-
-    @Inject
-    private DataCenterDao zoneDao;
-    @Inject
-    private PrimaryDataStoreHelper dataStoreHelper;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    StorageManager _storageMgr;
-    @Inject
-    private StoragePoolAutomation storagePoolAutomation;
-
-    @Override
-    public DataStore initialize(Map<String, Object> dsInfos) {
-        String url = (String) dsInfos.get("url");
-        Long zoneId = (Long) dsInfos.get("zoneId");
-        String storagePoolName = (String) dsInfos.get("name");
-        String providerName = (String) dsInfos.get("providerName");
-        Long capacityBytes = (Long)dsInfos.get("capacityBytes");
-        Long capacityIops = (Long)dsInfos.get("capacityIops");
-        String tags = (String)dsInfos.get("tags");
-        Map<String, String> details = (Map<String, String>) dsInfos.get("details");
-        NexentaUtil.NexentaPluginParameters params = NexentaUtil.parseNexentaPluginUrl(url);
-        DataCenterVO zone = zoneDao.findById(zoneId);
-        String uuid = String.format("%s_%s_%s", NexentaUtil.PROVIDER_NAME, zone.getUuid(), params.getNmsUrl().getHost());
-
-        if (capacityBytes == null || capacityBytes <= 0) {
-            throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0.");
-        }
-
-        if (capacityIops == null || capacityIops <= 0) {
-            throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
-        }
-
-        PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
-
-        parameters.setHost(params.getStorageHost());
-        parameters.setPort(params.getStoragePort());
-        parameters.setPath(params.getStoragePath());
-        parameters.setType(params.getStorageType());
-        parameters.setUuid(uuid);
-        parameters.setZoneId(zoneId);
-        parameters.setName(storagePoolName);
-        parameters.setProviderName(providerName);
-        parameters.setManaged(true);
-        parameters.setCapacityBytes(capacityBytes);
-        parameters.setUsedBytes(0);
-        parameters.setCapacityIops(capacityIops);
-        parameters.setHypervisorType(Hypervisor.HypervisorType.Any);
-        parameters.setTags(tags);
-
-        details.put(NexentaUtil.NMS_URL, params.getNmsUrl().toString());
-
-        details.put(NexentaUtil.VOLUME, params.getVolume());
-        details.put(NexentaUtil.SPARSE_VOLUMES, params.getSparseVolumes().toString());
-
-        details.put(NexentaUtil.STORAGE_TYPE, params.getStorageType().toString());
-        details.put(NexentaUtil.STORAGE_HOST, params.getStorageHost());
-        details.put(NexentaUtil.STORAGE_PORT, params.getStoragePort().toString());
-        details.put(NexentaUtil.STORAGE_PATH, params.getStoragePath());
-
-        parameters.setDetails(details);
-
-        // this adds a row in the cloud.storage_pool table for this SolidFire cluster
-        return dataStoreHelper.createPrimaryDataStore(parameters);
-    }
-
-    @Override
-    public boolean attachCluster(DataStore store, ClusterScope scope) {
-        return true;
-    }
-
-    @Override
-    public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
-        return true;
-    }
-
-    @Override
-    public boolean attachZone(DataStore dataStore, ZoneScope scope, Hypervisor.HypervisorType hypervisorType) {
-        dataStoreHelper.attachZone(dataStore);
-
-        List<HostVO> xenServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.XenServer, scope.getScopeId());
-        List<HostVO> vmWareServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.VMware, scope.getScopeId());
-        List<HostVO> kvmHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.KVM, scope.getScopeId());
-        List<HostVO> hosts = new ArrayList<HostVO>();
-
-        hosts.addAll(xenServerHosts);
-        hosts.addAll(vmWareServerHosts);
-        hosts.addAll(kvmHosts);
-
-        for (HostVO host : hosts) {
-            try {
-                _storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId());
-            } catch (Exception e) {
-                logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e);
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean maintain(DataStore store) {
-        storagePoolAutomation.maintain(store);
-        dataStoreHelper.maintain(store);
-
-        return true;
-    }
-
-    @Override
-    public boolean cancelMaintain(DataStore store) {
-        dataStoreHelper.cancelMaintain(store);
-        storagePoolAutomation.cancelMaintain(store);
-
-        return true;
-    }
-
-    @Override
-    public void enableStoragePool(DataStore dataStore) {
-        dataStoreHelper.enable(dataStore);
-    }
-
-    @Override
-    public void disableStoragePool(DataStore dataStore) {
-        dataStoreHelper.disable(dataStore);
-    }
-
-    @Override
-    public boolean deleteDataStore(DataStore store) {
-        return dataStoreHelper.deletePrimaryDataStore(store);
-    }
-
-    @Override
-    public boolean migrateToObjectStore(DataStore store) {
-        return false;
-    }
-
-    @Override
-    public void updateStoragePool(StoragePool storagePool, Map<String, String> details) {
-    }
-}
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java
deleted file mode 100644
index c1efc75..0000000
--- a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.util;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-
-import org.apache.cloudstack.storage.datastore.util.NexentaNmsClient.NmsResponse;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.google.gson.annotations.SerializedName;
-
-public class NexentaStorAppliance {
-    private static final Logger logger = LogManager.getLogger(NexentaStorAppliance.class);
-
-    protected NexentaNmsClient client;
-    protected NexentaUtil.NexentaPluginParameters parameters;
-
-    public NexentaStorAppliance(NexentaUtil.NexentaPluginParameters parameters) {
-        client = new NexentaNmsClient(parameters.getNmsUrl());
-        this.parameters = parameters;
-    }
-
-    NexentaStorAppliance(NexentaNmsClient client, NexentaUtil.NexentaPluginParameters parameters) {
-        this.client = client;
-        this.parameters = parameters;
-    }
-
-    String getVolumeName(String volumeName) {
-        if (volumeName.startsWith("/")) {
-            return String.format("%s%s", parameters.getVolume(), volumeName);
-        }
-        return String.format("%s/%s", parameters.getVolume(), volumeName);
-    }
-
-    static String getTargetName(String volumeName) {
-        return NexentaUtil.ISCSI_TARGET_NAME_PREFIX + volumeName;
-    }
-
-    static String getTargetGroupName(String volumeName) {
-        return NexentaUtil.ISCSI_TARGET_GROUP_PREFIX + volumeName;
-    }
-
-    @SuppressWarnings("unused")
-    static final class IntegerNmsResponse extends NmsResponse {
-        Integer result;
-
-        IntegerNmsResponse(int result) {
-            this.result = Integer.valueOf(result);
-        }
-
-        public Integer getResult() {
-            return result;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    static final class IscsiTarget {
-        protected String status;
-        protected String protocol;
-        protected String name;
-        protected String sessions;
-        protected String alias;
-        protected String provider;
-
-        IscsiTarget(String status, String protocol, String name, String sessions, String alias, String provider) {
-            this.status = status;
-            this.protocol = protocol;
-            this.name = name;
-            this.sessions = sessions;
-            this.alias = alias;
-            this.provider = provider;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    static final class ListOfIscsiTargetsNmsResponse extends NmsResponse {
-        protected HashMap<String, IscsiTarget> result;
-
-        ListOfIscsiTargetsNmsResponse() {}
-
-        ListOfIscsiTargetsNmsResponse(HashMap<String, IscsiTarget> result) {
-            this.result = result;
-        }
-
-        public HashMap<String, IscsiTarget> getResult() {
-            return result;
-        }
-    }
-
-    /**
-     * Checks if iSCSI target exists.
-     * @param targetName iSCSI target name
-     * @return true if iSCSI target exists, else false
-     */
-    boolean isIscsiTargetExists(String targetName) {
-        ListOfIscsiTargetsNmsResponse response = (ListOfIscsiTargetsNmsResponse) client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets");
-        if (response == null) {
-            return false;
-        }
-        HashMap<String, IscsiTarget> result = response.getResult();
-        return result != null && result.keySet().contains(targetName);
-    }
-
-    @SuppressWarnings("unused")
-    static final class CreateIscsiTargetRequestParams {
-        @SerializedName("target_name") String targetName;
-
-        CreateIscsiTargetRequestParams(String targetName) {
-            this.targetName = targetName;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            return other instanceof CreateIscsiTargetRequestParams && targetName.equals(((CreateIscsiTargetRequestParams) other).targetName);
-        }
-    }
-
-    /**
-     * Creates iSCSI target on NexentaStor Appliance.
-     * @param targetName iSCSI target name
-     */
-    void createIscsiTarget(String targetName) {
-        try {
-            client.execute(NmsResponse.class, "iscsitarget", "create_target", new CreateIscsiTargetRequestParams(targetName));
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("already configured")) {
-                throw ex;
-            }
-            logger.debug("Ignored target creation error: " + ex);
-        }
-    }
-
-    @SuppressWarnings("unused")
-    static final class ListOfStringsNmsResponse extends NmsResponse {
-        LinkedList<String> result;
-
-        ListOfStringsNmsResponse() {}
-
-        ListOfStringsNmsResponse(LinkedList<String> result) {
-            this.result = result;
-        }
-
-        public LinkedList<String> getResult() {
-            return result;
-        }
-    }
-
-    /**
-     * Checks if iSCSI target group already exists on NexentaStor Appliance.
-     * @param targetGroupName iSCSI target group name
-     * @return true if iSCSI target group already exists, else false
-     */
-    boolean isIscsiTargetGroupExists(String targetGroupName) {
-        ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups");
-        if (response == null) {
-            return false;
-        }
-        LinkedList<String> result = response.getResult();
-        return result != null && result.contains(targetGroupName);
-    }
-
-    /**
-     * Creates iSCSI target group on NexentaStor Appliance.
-     * @param targetGroupName iSCSI target group name
-     */
-    void createIscsiTargetGroup(String targetGroupName) {
-        try {
-            client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName);
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) {
-                throw ex;
-            }
-            logger.info("Ignored target group creation error: " + ex);
-        }
-    }
-
-    /**
-     * Checks if iSCSI target is member of target group.
-     * @param targetGroupName iSCSI target group name
-     * @param targetName iSCSI target name
-     * @return true if target is member of iSCSI target group, else false
-     */
-    boolean isTargetMemberOfTargetGroup(String targetGroupName, String targetName) {
-        ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName);
-        if (response == null) {
-            return false;
-        }
-        LinkedList<String> result = response.getResult();
-        return result != null && result.contains(targetName);
-    }
-
-    /**
-     * Adds iSCSI target to target group.
-     * @param targetGroupName iSCSI target group name
-     * @param targetName iSCSI target name
-     */
-    void addTargetGroupMember(String targetGroupName, String targetName) {
-        try {
-            client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName);
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) {
-                throw ex;
-            }
-            logger.debug("Ignored target group member addition error: " + ex);
-        }
-    }
-
-    /**
-     * Checks if LU already exists on NexentaStor appliance.
-     * @param luName LU name
-     * @return true if LU already exists, else false
-     */
-    boolean isLuExists(String luName) {
-        IntegerNmsResponse response;
-        try {
-            response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", luName);
-        } catch (CloudRuntimeException ex) {
-            if (ex.getMessage().contains("does not exist")) {
-                return false;
-            }
-            throw ex;
-        }
-        return response!= null && response.getResult() > 0;
-    }
-
-    @SuppressWarnings("unused")
-    static final class LuParams {
-        @Override
-        public boolean equals(Object other) {
-            return other instanceof LuParams;
-        }
-    }
-
-    /**
-     * Creates LU for volume.
-     * @param volumeName volume name
-     */
-    void createLu(String volumeName) {
-        try {
-            client.execute(NmsResponse.class, "scsidisk", "create_lu", volumeName, new LuParams());
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("in use")) {
-                throw ex;
-            }
-            logger.info("Ignored LU creation error: " + ex);
-        }
-    }
-
-    /**
-     * Checks if LU shared on NexentaStor appliance.
-     * @param luName LU name
-     * @return true if LU was already shared, else false
-     */
-    boolean isLuShared(String luName) {
-        IntegerNmsResponse response;
-        try {
-            response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName);
-        } catch (CloudRuntimeException ex) {
-            if (ex.getMessage().contains("does not exist")) {
-                return false;
-            }
-            throw ex;
-        }
-        return response != null && response.getResult() > 0;
-    }
-
-    @SuppressWarnings("unused")
-    static final class MappingEntry {
-        @SerializedName("target_group") String targetGroup;
-        String lun;
-        String zvol;
-        @SerializedName("host_group") String hostGroup;
-        @SerializedName("entry_number") String entryNumber;
-
-        MappingEntry(String targetGroup, String lun) {
-            this.targetGroup = targetGroup;
-            this.lun = lun;
-        }
-
-        static boolean isEquals(Object a, Object b) {
-            return (a == null && b == null) || (a != null && a.equals(b));
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof MappingEntry) {
-                MappingEntry o = (MappingEntry) other;
-                return isEquals(targetGroup, o.targetGroup) && isEquals(lun, o.lun) && isEquals(zvol, o.zvol) &&
-                        isEquals(hostGroup, o.hostGroup) && isEquals(entryNumber, o.entryNumber);
-            }
-            return false;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    static final class AddMappingEntryNmsResponse extends NmsResponse {
-        MappingEntry result;
-    }
-
-    /**
-     * Adds LU mapping entry to iSCSI target group.
-     * @param luName LU name
-     * @param targetGroupName iSCSI target group name
-     */
-    void addLuMappingEntry(String luName, String targetGroupName) {
-        MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0");
-        try {
-            client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry);
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("view already exists")) {
-                throw ex;
-            }
-            logger.debug("Ignored LU mapping entry addition error " + ex);
-        }
-    }
-
-    NexentaStorZvol createIscsiVolume(String volumeName, Long volumeSize) {
-        final String zvolName = getVolumeName(volumeName);
-        String volumeSizeString = String.format("%dB", volumeSize);
-
-        client.execute(NmsResponse.class, "zvol", "create", zvolName, volumeSizeString, parameters.getVolumeBlockSize(), parameters.getSparseVolumes());
-
-        final String targetName = getTargetName(volumeName);
-        final String targetGroupName = getTargetGroupName(volumeName);
-
-        if (!isIscsiTargetExists(targetName)) {
-            createIscsiTarget(targetName);
-        }
-
-        if (!isIscsiTargetGroupExists(targetGroupName)) {
-            createIscsiTargetGroup(targetGroupName);
-        }
-
-        if (!isTargetMemberOfTargetGroup(targetGroupName, targetName)) {
-            addTargetGroupMember(targetGroupName, targetName);
-        }
-
-        if (!isLuExists(zvolName)) {
-            createLu(zvolName);
-        }
-
-        if (!isLuShared(zvolName)) {
-            addLuMappingEntry(zvolName, targetGroupName);
-        }
-
-        return new NexentaStorZvol(zvolName, targetName);
-    }
-
-    static abstract class NexentaStorVolume {
-        protected String name;
-
-        NexentaStorVolume(String name) {
-            this.name = name;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        @Override
-        public String toString() {
-            return name;
-        }
-    }
-
-    public static final class NexentaStorZvol extends NexentaStorVolume {
-        protected String iqn;
-
-        public NexentaStorZvol(String name, String iqn) {
-            super(name);
-            this.iqn = iqn;
-        }
-
-        public String getIqn() {
-            return iqn;
-        }
-    }
-
-    public void deleteIscsiVolume(String volumeName) {
-        try {
-            NmsResponse response = client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "");
-        } catch (CloudRuntimeException ex) {
-            if (!ex.getMessage().contains("does not exist")) {
-                throw ex;
-            }
-            logger.debug(String.format(
-                    "Volume %s does not exist, it seems it was already " +
-                            "deleted.", volumeName));
-        }
-    }
-
-    public NexentaStorVolume createVolume(String volumeName, Long volumeSize) {
-        return createIscsiVolume(volumeName, volumeSize);
-    }
-
-    public void deleteVolume(String volumeName) {
-        deleteIscsiVolume(volumeName);
-    }
-}
diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java
deleted file mode 100644
index ee6a78f..0000000
--- a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.util;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.StringTokenizer;
-
-import com.cloud.storage.Storage;
-
-public class NexentaUtil {
-    public static final String PROVIDER_NAME = "Nexenta";
-
-    public static final String NMS_URL = "nmsUrl";
-    public static final String VOLUME = "volume";
-
-    public static final String STORAGE_HOST = "storageHost";
-    public static final String STORAGE_PORT = "storagePort";
-    public static final String STORAGE_TYPE = "storageType";
-    public static final String STORAGE_PATH = "storagePath";
-
-    public static final String DEFAULT_NMS_USER = "admin";
-    public static final String DEFAULT_NMS_PASSWORD = "nexenta";
-
-    public static final String SPARSE_VOLUMES = "sparseVolumes";
-    public static final String VOLUME_BLOCK_SIZE = "volumeBlockSize";
-
-    public static final int DEFAULT_NMS_PORT = 2000;
-    public static final int DEFAULT_ISCSI_TARGET_PORTAL_PORT = 3260;
-    public static final int DEFAULT_NFS_PORT = 2049;
-
-    public static final String ISCSI_TARGET_NAME_PREFIX = "iqn.1986-03.com.sun:02:cloudstack-";
-    public static final String ISCSI_TARGET_GROUP_PREFIX = "cloudstack/";
-
-    /**
-     * Parse NMS url into normalized parts like scheme, user, host and others.
-     *
-     * Example NMS URL:
-     *    auto://admin:nexenta@192.168.1.1:2000/
-     *
-     * NMS URL parts:
-     *    auto                true if url starts with auto://, protocol will be automatically switched to https if http not supported;
-     *    scheme (auto)       connection protocol (http or https);
-     *    user (admin)        NMS user;
-     *    password (nexenta)  NMS password;
-     *    host (192.168.1.1)  NMS host;
-     *    port (2000)         NMS port.
-     *
-     * @param nmsUrl url string to parse
-     * @return instance of NexentaConnection class
-     */
-    public static NexentaNmsUrl parseNmsUrl(String nmsUrl) {
-        URI uri;
-
-        try {
-            uri = new URI(nmsUrl);
-        } catch (URISyntaxException e) {
-            throw new IllegalArgumentException("Invalid URI: " + nmsUrl);
-        }
-
-        boolean isAuto = false;
-        String schema = uri.getScheme();
-        if (schema == null || schema.isEmpty() || "auto".equalsIgnoreCase(schema)) {
-            schema = "http";
-            isAuto = true;
-        }
-
-        String username, password, userInfo = uri.getUserInfo();
-        if (userInfo == null) {
-            username = DEFAULT_NMS_USER;
-            password = DEFAULT_NMS_PASSWORD;
-        } else {
-            if (userInfo.indexOf(':') < 0) {
-                username = userInfo;
-                password = DEFAULT_NMS_PASSWORD;
-            } else {
-                String[] parts = userInfo.split(":", 2);
-                username = parts[0];
-                password = parts[1];
-            }
-        }
-
-        String host = uri.getHost();
-        if (host == null) {
-            throw new IllegalArgumentException(String.format("NMS host required: %s.", nmsUrl));
-        }
-
-        int port = uri.getPort();
-        if (port == -1) {
-            port = DEFAULT_NMS_PORT;
-        }
-
-        return new NexentaNmsUrl(isAuto, schema, username, password, host, port);
-    }
-
-    public static Storage.StoragePoolType getStorageType(String v) {
-        if ("iSCSI".equalsIgnoreCase(v)) {
-            return Storage.StoragePoolType.Iscsi;
-        } else if ("NFS".equalsIgnoreCase(v)) {
-            return Storage.StoragePoolType.NetworkFilesystem;
-        }
-        return Storage.StoragePoolType.Iscsi;
-    }
-
-    public static class NexentaPluginParameters {
-        protected NexentaNmsUrl nmsUrl;
-        protected String volume;
-        protected Storage.StoragePoolType storageType = Storage.StoragePoolType.Iscsi;
-        protected String storageHost;
-        protected Integer storagePort;
-        protected String storagePath;
-        protected Boolean sparseVolumes = false;
-        protected String volumeBlockSize = "8K";
-
-        public void setNmsUrl(String url) {
-            this.nmsUrl = NexentaUtil.parseNmsUrl(url);
-        }
-
-        public NexentaNmsUrl getNmsUrl() {
-            return nmsUrl;
-        }
-
-        public void setVolume(String volume) {
-            if (volume.endsWith("/")) {
-                this.volume = volume.substring(0, volume.length() - 1);
-            } else {
-                this.volume = volume;
-            }
-        }
-
-        public String getVolume() {
-            return volume;
-        }
-
-        public void setStorageType(String storageType) {
-            this.storageType = NexentaUtil.getStorageType(storageType);
-        }
-
-        public Storage.StoragePoolType getStorageType() {
-            return storageType;
-        }
-
-        public void setStorageHost(String host) {
-            this.storageHost = host;
-        }
-
-        public String getStorageHost() {
-            if (storageHost == null && nmsUrl != null) {
-                return nmsUrl.getHost();
-            }
-            return storageHost;
-        }
-
-        public void setStoragePort(String port) {
-            this.storagePort = Integer.parseInt(port);
-        }
-
-        public Integer getStoragePort() {
-            if (storagePort == null && storageType != null) {
-                if (storageType == Storage.StoragePoolType.Iscsi) {
-                    return DEFAULT_ISCSI_TARGET_PORTAL_PORT;
-                } else {
-                    return DEFAULT_NFS_PORT;
-                }
-            }
-            return storagePort;
-        }
-
-        public void setStoragePath(String path) {
-            this.storagePath = path;
-        }
-
-        public String getStoragePath() {
-            return storagePath;
-        }
-
-        public void setSparseVolumes(String sparseVolumes) {
-            this.sparseVolumes = Boolean.TRUE.toString().equalsIgnoreCase(sparseVolumes);
-        }
-
-        public Boolean getSparseVolumes() {
-            return sparseVolumes;
-        }
-
-        public void setVolumeBlockSize(String volumeBlockSize) {
-            this.volumeBlockSize = volumeBlockSize;
-        }
-
-        public String getVolumeBlockSize() {
-            return volumeBlockSize;
-        }
-    }
-
-    public static NexentaPluginParameters parseNexentaPluginUrl(String url) {
-        final String delimiter1 = ";";
-        final String delimiter2 = "=";
-        StringTokenizer st = new StringTokenizer(url, delimiter1);
-        NexentaPluginParameters params = new NexentaPluginParameters();
-        while (st.hasMoreElements()) {
-            String token = st.nextElement().toString();
-            int idx = token.indexOf(delimiter2);
-            if (idx == -1) {
-                throw new RuntimeException("Invalid URL format");
-            }
-            String[] urlKeyAndValue = token.split(delimiter2, 2);
-            if (NMS_URL.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setNmsUrl(urlKeyAndValue[1]);
-            } else if (VOLUME.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setVolume(urlKeyAndValue[1]);
-            } else if (STORAGE_TYPE.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setStorageType(urlKeyAndValue[1]);
-            } else if (STORAGE_HOST.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setStorageHost(urlKeyAndValue[1]);
-            } else if (STORAGE_PORT.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setStoragePort(urlKeyAndValue[1]);
-            } else if (STORAGE_PATH.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setStoragePath(urlKeyAndValue[1]);
-            } else if (SPARSE_VOLUMES.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setSparseVolumes(urlKeyAndValue[1]);
-            } else if (VOLUME_BLOCK_SIZE.equalsIgnoreCase(urlKeyAndValue[0])) {
-                params.setVolumeBlockSize(urlKeyAndValue[1]);
-            }
-        }
-        return params;
-    }
-}
diff --git a/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java b/plugins/storage/volume/nexenta/src/test/java/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java
similarity index 100%
rename from plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java
rename to plugins/storage/volume/nexenta/src/test/java/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java
diff --git a/plugins/storage/volume/nexenta/src/test/java/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java b/plugins/storage/volume/nexenta/src/test/java/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java
new file mode 100644
index 0000000..45bffb0
--- /dev/null
+++ b/plugins/storage/volume/nexenta/src/test/java/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.util;
+
+import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.cloud.storage.Storage;
+
+@RunWith(JUnit4.class)
+public class NexentaUtilTest {
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
+    @Test
+    public void testParseNmsUrl() {
+        NexentaNmsUrl c;
+
+        c = NexentaUtil.parseNmsUrl("auto://192.168.1.1/");
+        assertEquals(c.toString(), "auto://admin:nexenta@192.168.1.1:2000/rest/nms/");
+        assertEquals(c.getSchema(), "http");
+
+        c = NexentaUtil.parseNmsUrl("http://192.168.1.1/");
+        assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
+
+        c = NexentaUtil.parseNmsUrl("http://192.168.1.1:8080");
+        assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:8080/rest/nms/");
+
+        c = NexentaUtil.parseNmsUrl("https://root@192.168.1.1:8080");
+        assertEquals(c.toString(), "https://root:nexenta@192.168.1.1:8080/rest/nms/");
+
+        c = NexentaUtil.parseNmsUrl("https://root:password@192.168.1.1:8080");
+        assertEquals(c.toString(), "https://root:password@192.168.1.1:8080/rest/nms/");
+    }
+
+    @Test
+    public void testGetStorageType() {
+        assertEquals(NexentaUtil.getStorageType("iscsi"), Storage.StoragePoolType.Iscsi);
+        assertEquals(NexentaUtil.getStorageType("nfs"), Storage.StoragePoolType.NetworkFilesystem);
+        assertEquals(NexentaUtil.getStorageType("any"), Storage.StoragePoolType.Iscsi);
+    }
+
+    @Test
+    public void testParseNexentaPluginUrl() {
+        String url = "nmsUrl=http://admin:nexenta@192.168.1.1:2000;";
+
+        NexentaUtil.NexentaPluginParameters parameters;
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
+        assertNull(parameters.getVolume());
+        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi);
+        assertEquals(parameters.getStorageHost(), "192.168.1.1");
+        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT);
+        assertNull(parameters.getStoragePath());
+        assertEquals((boolean) parameters.isSparseVolumes(), false);
+        assertEquals(parameters.getVolumeBlockSize(), "8K");
+
+        url += "volume=cloudstack";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
+        assertEquals(parameters.getVolume(), "cloudstack");
+
+        url += "/;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getVolume(), "cloudstack");
+
+        url += "storageType=";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url + "nfs");
+        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem);
+        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_NFS_PORT);
+
+        parameters = NexentaUtil.parseNexentaPluginUrl(url + "iscsi");
+        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi);
+        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT);
+
+        url += "nfs;storageHost=192.168.1.2;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getStorageHost(), "192.168.1.2");
+
+        url += "storagePort=3000;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals((int) parameters.getStoragePort(), 3000);
+
+        url += "storagePath=/volumes/cloudstack;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getStoragePath(), "/volumes/cloudstack");
+
+        url += "sparseVolumes=true;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.isSparseVolumes(), Boolean.TRUE);
+
+        url += "volumeBlockSize=128K;";
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+        assertEquals(parameters.getVolumeBlockSize(), "128K");
+
+        url += "unknownParameter=value;";  // NOTE: exception should not be raised
+        parameters = NexentaUtil.parseNexentaPluginUrl(url);
+
+        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
+        assertEquals(parameters.getVolume(), "cloudstack");
+        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem);
+        assertEquals(parameters.getStorageHost(), "192.168.1.2");
+        assertEquals((int) parameters.getStoragePort(), 3000);
+        assertEquals(parameters.getStoragePath(), "/volumes/cloudstack");
+        assertEquals(parameters.isSparseVolumes(), Boolean.TRUE);
+        assertEquals(parameters.getVolumeBlockSize(), "128K");
+
+        exception.expect(RuntimeException.class);
+        exception.expectMessage("Invalid URL format");
+
+        NexentaUtil.parseNexentaPluginUrl(url + "invalidParameter");
+    }
+}
diff --git a/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java b/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java
deleted file mode 100644
index 8f44985..0000000
--- a/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.util;
-
-import static junit.framework.Assert.assertNull;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import com.cloud.storage.Storage;
-
-@RunWith(JUnit4.class)
-public class NexentaUtilTest {
-    @Rule
-    public ExpectedException exception = ExpectedException.none();
-
-    @Test
-    public void testParseNmsUrl() {
-        NexentaNmsUrl c;
-
-        c = NexentaUtil.parseNmsUrl("auto://192.168.1.1/");
-        assertEquals(c.toString(), "auto://admin:nexenta@192.168.1.1:2000/rest/nms/");
-        assertEquals(c.getSchema(), "http");
-
-        c = NexentaUtil.parseNmsUrl("http://192.168.1.1/");
-        assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
-
-        c = NexentaUtil.parseNmsUrl("http://192.168.1.1:8080");
-        assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:8080/rest/nms/");
-
-        c = NexentaUtil.parseNmsUrl("https://root@192.168.1.1:8080");
-        assertEquals(c.toString(), "https://root:nexenta@192.168.1.1:8080/rest/nms/");
-
-        c = NexentaUtil.parseNmsUrl("https://root:password@192.168.1.1:8080");
-        assertEquals(c.toString(), "https://root:password@192.168.1.1:8080/rest/nms/");
-    }
-
-    @Test
-    public void testGetStorageType() {
-        assertEquals(NexentaUtil.getStorageType("iscsi"), Storage.StoragePoolType.Iscsi);
-        assertEquals(NexentaUtil.getStorageType("nfs"), Storage.StoragePoolType.NetworkFilesystem);
-        assertEquals(NexentaUtil.getStorageType("any"), Storage.StoragePoolType.Iscsi);
-    }
-
-    @Test
-    public void testParseNexentaPluginUrl() {
-        String url = "nmsUrl=http://admin:nexenta@192.168.1.1:2000;";
-
-        NexentaUtil.NexentaPluginParameters parameters;
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
-        assertNull(parameters.getVolume());
-        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi);
-        assertEquals(parameters.getStorageHost(), "192.168.1.1");
-        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT);
-        assertNull(parameters.getStoragePath());
-        assertEquals((boolean) parameters.getSparseVolumes(), false);
-        assertEquals(parameters.getVolumeBlockSize(), "8K");
-
-        url += "volume=cloudstack";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
-        assertEquals(parameters.getVolume(), "cloudstack");
-
-        url += "/;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getVolume(), "cloudstack");
-
-        url += "storageType=";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url + "nfs");
-        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem);
-        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_NFS_PORT);
-
-        parameters = NexentaUtil.parseNexentaPluginUrl(url + "iscsi");
-        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi);
-        assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT);
-
-        url += "nfs;storageHost=192.168.1.2;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getStorageHost(), "192.168.1.2");
-
-        url += "storagePort=3000;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals((int) parameters.getStoragePort(), 3000);
-
-        url += "storagePath=/volumes/cloudstack;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getStoragePath(), "/volumes/cloudstack");
-
-        url += "sparseVolumes=true;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getSparseVolumes(), Boolean.TRUE);
-
-        url += "volumeBlockSize=128K;";
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-        assertEquals(parameters.getVolumeBlockSize(), "128K");
-
-        url += "unknownParameter=value;";  // NOTE: exception should not be raised
-        parameters = NexentaUtil.parseNexentaPluginUrl(url);
-
-        assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/");
-        assertEquals(parameters.getVolume(), "cloudstack");
-        assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem);
-        assertEquals(parameters.getStorageHost(), "192.168.1.2");
-        assertEquals((int) parameters.getStoragePort(), 3000);
-        assertEquals(parameters.getStoragePath(), "/volumes/cloudstack");
-        assertEquals(parameters.getSparseVolumes(), Boolean.TRUE);
-        assertEquals(parameters.getVolumeBlockSize(), "128K");
-
-        exception.expect(RuntimeException.class);
-        exception.expectMessage("Invalid URL format");
-
-        NexentaUtil.parseNexentaPluginUrl(url + "invalidParameter");
-    }
-}
diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml
index 9bbfd65..8548487 100644
--- a/plugins/storage/volume/sample/pom.xml
+++ b/plugins/storage/volume/sample/pom.xml
@@ -1,47 +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. -->
+<!--
+  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-storage-volume-sample</artifactId>
-  <name>Apache CloudStack Plugin - Storage Volume sample provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-volume-sample</artifactId>
+    <name>Apache CloudStack Plugin - Storage Volume sample provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
new file mode 100644
index 0000000..fc0186f
--- /dev/null
+++ b/plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
@@ -0,0 +1,239 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.datastore.driver;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.framework.async.AsyncRpcContext;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.datastore.DataObjectManager;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.host.Host;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
+    private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class);
+    @Inject
+    EndPointSelector selector;
+    @Inject
+    StoragePoolHostDao storeHostDao;
+    @Inject
+    DataObjectManager dataObjMgr;
+
+    public SamplePrimaryDataStoreDriverImpl() {
+
+    }
+
+    @Override
+    public Map<String, String> getCapabilities() {
+        return null;
+    }
+
+    @Override
+    public DataTO getTO(DataObject data) {
+        return null;
+    }
+
+    @Override
+    public DataStoreTO getStoreTO(DataStore store) {
+        return null;
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject) {
+        return null;
+    }
+
+    @Override
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) { return false; }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {}
+
+    @Override
+    public long getUsedBytes(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getUsedIops(StoragePool storagePool) {
+        return 0;
+    }
+
+    @Override
+    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
+        return dataObject.getSize();
+    }
+
+    @Override
+    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
+        return 0;
+    }
+
+    private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
+        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume) {
+            super(callback);
+        }
+    }
+
+    public Void createAsyncCallback(AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CreateCmdResult> context) {
+        /*
+         * CreateCmdResult result = null; CreateObjectAnswer volAnswer =
+         * (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult())
+         * { result = new CreateCmdResult(volAnswer.getPath(), volAnswer); }
+         * else { result = new CreateCmdResult("", null);
+         * result.setResult(volAnswer.getDetails()); }
+         *
+         * context.getParentCallback().complete(result);
+         */
+        return null;
+    }
+
+    @Override
+    public void deleteAsync(DataStore dataStore, DataObject vo, AsyncCompletionCallback<CommandResult> callback) {
+        /*
+         * DeleteCommand cmd = new DeleteCommand(vo.getUri());
+         *
+         * EndPoint ep = selector.select(vo); AsyncRpcContext<CommandResult>
+         * context = new AsyncRpcContext<CommandResult>(callback);
+         * AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer>
+         * caller = AsyncCallbackDispatcher.create(this);
+         * caller.setCallback(caller.getTarget().deleteCallback(null, null))
+         * .setContext(context); ep.sendMessageAsync(cmd, caller);
+         */
+    }
+
+    public Void deleteCallback(AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> callback, AsyncRpcContext<CommandResult> context) {
+        CommandResult result = new CommandResult();
+        Answer answer = callback.getResult();
+        if (!answer.getResult()) {
+            result.setResult(answer.getDetails());
+        }
+        context.getParentCallback().complete(result);
+        return null;
+    }
+
+    /*
+     * private class CreateVolumeFromBaseImageContext<T> extends
+     * AsyncRpcContext<T> { private final VolumeObject volume;
+     *
+     * public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T>
+     * callback, VolumeObject volume) { super(callback); this.volume = volume; }
+     *
+     * public VolumeObject getVolume() { return this.volume; }
+     *
+     * }
+     *
+     * @Override public void createVolumeFromBaseImageAsync(VolumeObject volume,
+     * TemplateInfo template, AsyncCompletionCallback<CommandResult> callback) {
+     * VolumeTO vol = this.dataStore.getVolumeTO(volume); List<EndPoint>
+     * endPoints = this.dataStore.getEndPoints(); EndPoint ep =
+     * endPoints.get(0); String templateUri =
+     * template.getDataStore().grantAccess(template, ep);
+     * CreateVolumeFromBaseImageCommand cmd = new
+     * CreateVolumeFromBaseImageCommand(vol, templateUri);
+     *
+     * CreateVolumeFromBaseImageContext<CommandResult> context = new
+     * CreateVolumeFromBaseImageContext<CommandResult>(callback, volume);
+     * AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller
+     * = AsyncCallbackDispatcher.create(this); caller.setContext(context)
+     * .setCallback
+     * (caller.getTarget().createVolumeFromBaseImageAsyncCallback(null, null));
+     *
+     * ep.sendMessageAsync(cmd, caller); }
+     */
+    /*
+     * public Object
+     * createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher
+     * <DefaultPrimaryDataStoreDriverImpl, Answer> callback,
+     * CreateVolumeFromBaseImageContext<CommandResult> context) {
+     * CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult();
+     * CommandResult result = new CommandResult(); if (answer == null ||
+     * answer.getDetails() != null) { result.setSuccess(false); if (answer !=
+     * null) { result.setResult(answer.getDetails()); } } else {
+     * result.setSuccess(true); VolumeObject volume = context.getVolume();
+     * volume.setPath(answer.getVolumeUuid()); }
+     * AsyncCompletionCallback<CommandResult> parentCall =
+     * context.getParentCallback(); parentCall.complete(result); return null; }
+     */
+
+    @Override
+    public void createAsync(DataStore dataStore, DataObject vol, AsyncCompletionCallback<CreateCmdResult> callback) {
+        EndPoint ep = selector.select(vol);
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+        CreateObjectCommand createCmd = new CreateObjectCommand(null);
+
+        CreateVolumeContext<CreateCmdResult> context = new CreateVolumeContext<CreateCmdResult>(callback, vol);
+        AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
+        caller.setContext(context).setCallback(caller.getTarget().createAsyncCallback(null, null));
+
+        ep.sendMessageAsync(createCmd, caller);
+    }
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
+    }
+
+    @Override
+    public boolean canCopy(DataObject srcData, DataObject destData) {
+        return false;
+    }
+
+    @Override
+    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+    }
+
+    @Override
+    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
+    }
+
+    @Override
+    public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) {
+    }
+
+    @Override
+    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
+    }
+
+}
diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java
similarity index 100%
rename from plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java
rename to plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java
diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java b/plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java
similarity index 100%
rename from plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java
rename to plugins/storage/volume/sample/src/main/java/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java
diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
deleted file mode 100644
index 343b08a..0000000
--- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.datastore.driver;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.framework.async.AsyncRpcContext;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.datastore.DataObjectManager;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.host.Host;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
-    private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class);
-    @Inject
-    EndPointSelector selector;
-    @Inject
-    StoragePoolHostDao storeHostDao;
-    @Inject
-    DataObjectManager dataObjMgr;
-
-    public SamplePrimaryDataStoreDriverImpl() {
-
-    }
-
-    @Override
-    public Map<String, String> getCapabilities() {
-        return null;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
-
-    @Override
-    public DataStoreTO getStoreTO(DataStore store) {
-        return null;
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject) {
-        return null;
-    }
-
-    @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) { return false; }
-
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {}
-
-    @Override
-    public long getUsedBytes(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getUsedIops(StoragePool storagePool) {
-        return 0;
-    }
-
-    @Override
-    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
-        return dataObject.getSize();
-    }
-
-    @Override
-    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
-        return 0;
-    }
-
-    private class CreateVolumeContext<T> extends AsyncRpcContext<T> {
-        public CreateVolumeContext(AsyncCompletionCallback<T> callback, DataObject volume) {
-            super(callback);
-        }
-    }
-
-    public Void createAsyncCallback(AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> callback, CreateVolumeContext<CreateCmdResult> context) {
-        /*
-         * CreateCmdResult result = null; CreateObjectAnswer volAnswer =
-         * (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult())
-         * { result = new CreateCmdResult(volAnswer.getPath(), volAnswer); }
-         * else { result = new CreateCmdResult("", null);
-         * result.setResult(volAnswer.getDetails()); }
-         *
-         * context.getParentCallback().complete(result);
-         */
-        return null;
-    }
-
-    @Override
-    public void deleteAsync(DataStore dataStore, DataObject vo, AsyncCompletionCallback<CommandResult> callback) {
-        /*
-         * DeleteCommand cmd = new DeleteCommand(vo.getUri());
-         *
-         * EndPoint ep = selector.select(vo); AsyncRpcContext<CommandResult>
-         * context = new AsyncRpcContext<CommandResult>(callback);
-         * AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer>
-         * caller = AsyncCallbackDispatcher.create(this);
-         * caller.setCallback(caller.getTarget().deleteCallback(null, null))
-         * .setContext(context); ep.sendMessageAsync(cmd, caller);
-         */
-    }
-
-    public Void deleteCallback(AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> callback, AsyncRpcContext<CommandResult> context) {
-        CommandResult result = new CommandResult();
-        Answer answer = callback.getResult();
-        if (!answer.getResult()) {
-            result.setResult(answer.getDetails());
-        }
-        context.getParentCallback().complete(result);
-        return null;
-    }
-
-    /*
-     * private class CreateVolumeFromBaseImageContext<T> extends
-     * AsyncRpcContext<T> { private final VolumeObject volume;
-     *
-     * public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T>
-     * callback, VolumeObject volume) { super(callback); this.volume = volume; }
-     *
-     * public VolumeObject getVolume() { return this.volume; }
-     *
-     * }
-     *
-     * @Override public void createVolumeFromBaseImageAsync(VolumeObject volume,
-     * TemplateInfo template, AsyncCompletionCallback<CommandResult> callback) {
-     * VolumeTO vol = this.dataStore.getVolumeTO(volume); List<EndPoint>
-     * endPoints = this.dataStore.getEndPoints(); EndPoint ep =
-     * endPoints.get(0); String templateUri =
-     * template.getDataStore().grantAccess(template, ep);
-     * CreateVolumeFromBaseImageCommand cmd = new
-     * CreateVolumeFromBaseImageCommand(vol, templateUri);
-     *
-     * CreateVolumeFromBaseImageContext<CommandResult> context = new
-     * CreateVolumeFromBaseImageContext<CommandResult>(callback, volume);
-     * AsyncCallbackDispatcher<DefaultPrimaryDataStoreDriverImpl, Answer> caller
-     * = AsyncCallbackDispatcher.create(this); caller.setContext(context)
-     * .setCallback
-     * (caller.getTarget().createVolumeFromBaseImageAsyncCallback(null, null));
-     *
-     * ep.sendMessageAsync(cmd, caller); }
-     */
-    /*
-     * public Object
-     * createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher
-     * <DefaultPrimaryDataStoreDriverImpl, Answer> callback,
-     * CreateVolumeFromBaseImageContext<CommandResult> context) {
-     * CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult();
-     * CommandResult result = new CommandResult(); if (answer == null ||
-     * answer.getDetails() != null) { result.setSuccess(false); if (answer !=
-     * null) { result.setResult(answer.getDetails()); } } else {
-     * result.setSuccess(true); VolumeObject volume = context.getVolume();
-     * volume.setPath(answer.getVolumeUuid()); }
-     * AsyncCompletionCallback<CommandResult> parentCall =
-     * context.getParentCallback(); parentCall.complete(result); return null; }
-     */
-
-    @Override
-    public void createAsync(DataStore dataStore, DataObject vol, AsyncCompletionCallback<CreateCmdResult> callback) {
-        EndPoint ep = selector.select(vol);
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            throw new CloudRuntimeException(errMsg);
-        }
-        CreateObjectCommand createCmd = new CreateObjectCommand(null);
-
-        CreateVolumeContext<CreateCmdResult> context = new CreateVolumeContext<CreateCmdResult>(callback, vol);
-        AsyncCallbackDispatcher<SamplePrimaryDataStoreDriverImpl, Answer> caller = AsyncCallbackDispatcher.create(this);
-        caller.setContext(context).setCallback(caller.getTarget().createAsyncCallback(null, null));
-
-        ep.sendMessageAsync(createCmd, caller);
-    }
-
-    @Override
-    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback) {
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        return false;
-    }
-
-    @Override
-    public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-    }
-
-    @Override
-    public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
-    }
-
-    @Override
-    public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
-    }
-
-}
diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml
index 46c50e6..f8f885f 100644
--- a/plugins/storage/volume/solidfire/pom.xml
+++ b/plugins/storage/volume/solidfire/pom.xml
@@ -1,66 +1,74 @@
-<!-- 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. -->
+<!--
+  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-storage-volume-solidfire</artifactId>
-  <name>Apache CloudStack Plugin - Storage Volume SolidFire Provider</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>com.solidfire</groupId>
-      <artifactId>solidfire-sdk-java</artifactId>
-      <version>1.2.0.29</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-plugin-storage-volume-default</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-volume</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.aspectj</groupId>
-      <artifactId>aspectjtools</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skipTests>true</skipTests>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-storage-volume-solidfire</artifactId>
+    <name>Apache CloudStack Plugin - Storage Volume SolidFire Provider</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>com.solidfire</groupId>
+            <artifactId>solidfire-sdk-java</artifactId>
+            <version>1.2.0.29</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-plugin-storage-volume-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-volume</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjtools</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
new file mode 100644
index 0000000..370cdb0
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
@@ -0,0 +1,1622 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.datastore.driver;
+
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ResizeVolumePayload;
+import com.cloud.storage.Snapshot.State;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeDetailVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotDetailsDao;
+import com.cloud.storage.dao.SnapshotDetailsVO;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDetailsDao;
+import com.cloud.user.AccountDetailVO;
+import com.cloud.user.AccountDetailsDao;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import com.google.common.base.Preconditions;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
+    private static final Logger LOGGER = Logger.getLogger(SolidFirePrimaryDataStoreDriver.class);
+    private static final int LOWEST_HYPERVISOR_SNAPSHOT_RESERVE = 10;
+    private static final long MIN_IOPS_FOR_TEMPLATE_VOLUME = 100L;
+    private static final long MAX_IOPS_FOR_TEMPLATE_VOLUME = 20000L;
+    private static final long MIN_IOPS_FOR_TEMP_VOLUME = 100L;
+    private static final long MAX_IOPS_FOR_TEMP_VOLUME = 20000L;
+    private static final long MAX_IOPS_FOR_MIGRATING_VOLUME = 20000L;
+    private static final long MIN_IOPS_FOR_SNAPSHOT_VOLUME = 100L;
+    private static final long MAX_IOPS_FOR_SNAPSHOT_VOLUME = 20000L;
+
+    private static final String BASIC_SF_ID = "basicSfId";
+
+    @Inject private AccountDao accountDao;
+    @Inject private AccountDetailsDao accountDetailsDao;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataStoreManager dataStoreMgr;
+    @Inject private HostDao hostDao;
+    @Inject private SnapshotDao snapshotDao;
+    @Inject private SnapshotDetailsDao snapshotDetailsDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject private VMTemplatePoolDao tmpltPoolDao;
+    @Inject private VolumeDao volumeDao;
+    @Inject private VolumeDetailsDao volumeDetailsDao;
+    @Inject private VolumeDataFactory volumeFactory;
+
+    @Override
+    public Map<String, String> getCapabilities() {
+        Map<String, String> mapCapabilities = new HashMap<>();
+
+        mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString());
+        mapCapabilities.put(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_SNAPSHOT.toString(), Boolean.TRUE.toString());
+        mapCapabilities.put(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString(), Boolean.TRUE.toString());
+        mapCapabilities.put(DataStoreCapabilities.CAN_REVERT_VOLUME_TO_SNAPSHOT.toString(), Boolean.TRUE.toString());
+
+        return mapCapabilities;
+    }
+
+    @Override
+    public DataTO getTO(DataObject data) {
+        return null;
+    }
+
+    @Override
+    public DataStoreTO getStoreTO(DataStore store) {
+        return null;
+    }
+
+    private SolidFireUtil.SolidFireAccount createSolidFireAccount(SolidFireUtil.SolidFireConnection sfConnection, String sfAccountName) {
+        long accountNumber = SolidFireUtil.createAccount(sfConnection, sfAccountName);
+
+        return SolidFireUtil.getAccountById(sfConnection, accountNumber);
+    }
+
+    @Override
+    public ChapInfo getChapInfo(DataObject dataObject) {
+        return null;
+    }
+
+    @Override
+    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
+        Preconditions.checkArgument(dataObject != null, "'dataObject' should not be 'null'");
+        Preconditions.checkArgument(host != null, "'host' should not be 'null'");
+        Preconditions.checkArgument(dataStore != null, "'dataStore' should not be 'null'");
+
+        long sfVolumeId = getSolidFireVolumeId(dataObject, true);
+        long clusterId = host.getClusterId();
+        long storagePoolId = dataStore.getId();
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB (in grantAccess) on the following string: " + cluster.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
+
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection, sfVolumeId, hosts);
+
+            return true;
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+    }
+
+    @Override
+    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore)
+    {
+        if (dataObject == null || host == null || dataStore == null) {
+            return;
+        }
+
+        long sfVolumeId = getSolidFireVolumeId(dataObject, false);
+        long clusterId = host.getClusterId();
+        long storagePoolId = dataStore.getId();
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB (in revokeAccess) on the following string: " + cluster.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                if (SolidFireUtil.sfVagContains(sfVag, sfVolumeId, clusterId, hostDao)) {
+                    SolidFireUtil.removeVolumeIdsFromSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+    }
+
+    private long getSolidFireVolumeId(DataObject dataObject, boolean grantAccess) {
+        if (dataObject.getType() == DataObjectType.VOLUME) {
+            final VolumeInfo volumeInfo = (VolumeInfo)dataObject;
+            final long volumeId = volumeInfo.getId();
+
+            if (grantAccess && isBasicGrantAccess(volumeId)) {
+                volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_GRANT_ACCESS);
+
+                final Long sfVolumeId = getBasicSfVolumeId(volumeId);
+
+                Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null' (basic grant access).");
+
+                return sfVolumeId;
+            }
+            else if (!grantAccess && isBasicRevokeAccess(volumeId)) {
+                volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_REVOKE_ACCESS);
+
+                final Long sfVolumeId = getBasicSfVolumeId(volumeId);
+
+                Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null' (basic revoke access).");
+
+                return sfVolumeId;
+            }
+
+            return Long.parseLong(volumeInfo.getFolder());
+        }
+
+        if (dataObject.getType() == DataObjectType.SNAPSHOT) {
+            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(dataObject.getId(), SolidFireUtil.VOLUME_ID);
+
+            if (snapshotDetails == null || snapshotDetails.getValue() == null) {
+                throw new CloudRuntimeException("Unable to locate the volume ID associated with the following snapshot ID: " + dataObject.getId());
+            }
+
+            return Long.parseLong(snapshotDetails.getValue());
+        }
+
+        if (dataObject.getType() == DataObjectType.TEMPLATE) {
+            return getVolumeIdFrom_iScsiPath(((TemplateInfo)dataObject).getInstallPath());
+        }
+
+        throw new CloudRuntimeException("Invalid DataObjectType (" + dataObject.getType() + ") passed to getSolidFireVolumeId(DataObject, boolean)");
+    }
+
+    private long getVolumeIdFrom_iScsiPath(String iScsiPath) {
+        String[] splits = iScsiPath.split("/");
+        String iqn = splits[1];
+
+        String sequenceToSearchFor = ".";
+        int lastIndexOf = iqn.lastIndexOf(sequenceToSearchFor);
+        String volumeIdAsString = iqn.substring(lastIndexOf + sequenceToSearchFor.length());
+
+        return Long.parseLong(volumeIdAsString);
+    }
+
+    private long getDefaultMinIops(long storagePoolId) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS);
+
+        String clusterDefaultMinIops = storagePoolDetail.getValue();
+
+        return Long.parseLong(clusterDefaultMinIops);
+    }
+
+    private long getDefaultMaxIops(long storagePoolId) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS);
+
+        String clusterDefaultMaxIops = storagePoolDetail.getValue();
+
+        return Long.parseLong(clusterDefaultMaxIops);
+    }
+
+    private long getDefaultBurstIops(long storagePoolId, long maxIops) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS);
+
+        String clusterDefaultBurstIopsPercentOfMaxIops = storagePoolDetail.getValue();
+
+        float fClusterDefaultBurstIopsPercentOfMaxIops = Float.parseFloat(clusterDefaultBurstIopsPercentOfMaxIops);
+
+        return Math.min((long)(maxIops * fClusterDefaultBurstIopsPercentOfMaxIops), SolidFireUtil.MAX_IOPS_PER_VOLUME);
+    }
+
+    private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection,
+                                                                DataObject dataObject, long storagePoolId, long sfAccountId) {
+        final Long minIops;
+        final Long maxIops;
+        final Long volumeSize;
+        final String volumeName;
+
+        final Map<String, String> mapAttributes;
+
+        if (dataObject.getType() == DataObjectType.VOLUME) {
+            VolumeInfo volumeInfo = (VolumeInfo)dataObject;
+
+            minIops = volumeInfo.getMinIops();
+            maxIops = volumeInfo.getMaxIops();
+            volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePoolDao.findById(storagePoolId));
+            volumeName = volumeInfo.getName();
+
+            mapAttributes = getVolumeAttributes(volumeInfo);
+        } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
+            TemplateInfo templateInfo = (TemplateInfo)dataObject;
+
+            minIops = MIN_IOPS_FOR_TEMPLATE_VOLUME;
+            maxIops = MAX_IOPS_FOR_TEMPLATE_VOLUME;
+            volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(templateInfo, storagePoolDao.findById(storagePoolId));
+            volumeName = templateInfo.getUniqueName();
+
+            mapAttributes = getTemplateAttributes(templateInfo);
+        }
+        else {
+            throw new CloudRuntimeException("Invalid type passed to createSolidFireVolume: " + dataObject.getType());
+        }
+
+        final Iops iops = getIops(minIops, maxIops, storagePoolId);
+
+        long sfVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeName), sfAccountId,
+                volumeSize, true, mapAttributes, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+
+        return SolidFireUtil.getVolume(sfConnection, sfVolumeId);
+    }
+
+    private Iops getIops(Long minIops, Long maxIops, long storagePoolId) {
+        if (minIops == null || minIops <= 0 || maxIops == null || maxIops <= 0) {
+            long defaultMaxIops = getDefaultMaxIops(storagePoolId);
+
+            return new Iops(getDefaultMinIops(storagePoolId), defaultMaxIops, getDefaultBurstIops(storagePoolId, defaultMaxIops));
+        }
+
+        return new Iops(minIops, maxIops, getDefaultBurstIops(storagePoolId, maxIops));
+    }
+
+    @Override
+    public long getUsedBytes(StoragePool storagePool) {
+        return getUsedBytes(storagePool, Long.MIN_VALUE);
+    }
+
+    private long getUsedBytes(StoragePool storagePool, long volumeIdToIgnore) {
+        long usedSpace = 0;
+
+        List<VolumeVO> lstVolumes = volumeDao.findByPoolId(storagePool.getId(), null);
+
+        if (lstVolumes != null) {
+            for (VolumeVO volume : lstVolumes) {
+                if (volume.getId() == volumeIdToIgnore) {
+                    continue;
+                }
+
+                VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volume.getId(), SolidFireUtil.VOLUME_SIZE);
+
+                if (volumeDetail != null && volumeDetail.getValue() != null) {
+                    long volumeSize = Long.parseLong(volumeDetail.getValue());
+
+                    usedSpace += volumeSize;
+                }
+                else {
+                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                    try {
+                        long lVolumeId = Long.parseLong(volume.getFolder());
+
+                        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, lVolumeId);
+
+                        long volumeSize = sfVolume.getTotalSize();
+
+                        // SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
+                        // To be backward compatible with releases prior to 4.5, call updateVolumeDetails here.
+                        // That way if SolidFireUtil.VOLUME_SIZE wasn't put in the volume_details table when the
+                        // volume was initially created, it can be placed in volume_details here.
+                        updateVolumeDetails(volume.getId(), volumeSize, sfVolume.getScsiNaaDeviceId());
+
+                        usedSpace += volumeSize;
+                    }
+                    catch (Exception ex) {
+                        // can be ignored
+                    }
+                }
+            }
+        }
+
+        List<SnapshotVO> lstSnapshots = snapshotDao.listAll();
+
+        if (lstSnapshots != null) {
+            for (SnapshotVO snapshot : lstSnapshots) {
+                SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.STORAGE_POOL_ID);
+
+                // if this snapshot belongs to the storagePool that was passed in
+                if (snapshotDetails != null && snapshotDetails.getValue() != null && Long.parseLong(snapshotDetails.getValue()) == storagePool.getId()) {
+                    snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.VOLUME_SIZE);
+
+                    if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+                        long snapshotSize = Long.parseLong(snapshotDetails.getValue());
+
+                        usedSpace += snapshotSize;
+                    }
+                }
+            }
+        }
+
+        List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
+
+        if (lstTemplatePoolRefs != null) {
+            for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
+                usedSpace += templatePoolRef.getTemplateSize();
+            }
+        }
+
+        return usedSpace;
+    }
+
+    @Override
+    public long getUsedIops(StoragePool storagePool) {
+        long usedIops = 0;
+
+        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePool.getId(), null);
+
+        if (volumes != null) {
+            for (VolumeVO volume : volumes) {
+                if (!Volume.State.Creating.equals(volume.getState())) {
+                    usedIops += volume.getMinIops() != null ? volume.getMinIops() : 0;
+                }
+            }
+        }
+
+        return usedIops;
+    }
+
+    @Override
+    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
+        long volumeSize = 0;
+
+        if (dataObject.getType() == DataObjectType.VOLUME) {
+            VolumeInfo volume = (VolumeInfo)dataObject;
+
+            volumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volume.getSize(), volume.getHypervisorSnapshotReserve());
+        } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
+            TemplateInfo templateInfo = (TemplateInfo)dataObject;
+
+            // TemplateInfo sometimes has a size equal to null.
+            long templateSize = templateInfo.getSize() != null ? templateInfo.getSize() : 0;
+
+            if (templateInfo.getHypervisorType() == Hypervisor.HypervisorType.KVM) {
+                volumeSize = templateSize;
+            }
+            else {
+                volumeSize = (long)(templateSize + templateSize * (LOWEST_HYPERVISOR_SNAPSHOT_RESERVE / 100f));
+            }
+        }
+
+        return Math.max(volumeSize, SolidFireUtil.MIN_VOLUME_SIZE);
+    }
+
+    private long getVolumeSizeIncludingHypervisorSnapshotReserve(long volumeSize, Integer hypervisorSnapshotReserve) {
+        if (hypervisorSnapshotReserve != null) {
+            hypervisorSnapshotReserve = Math.max(hypervisorSnapshotReserve, LOWEST_HYPERVISOR_SNAPSHOT_RESERVE);
+
+            volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
+        }
+
+        return Math.max(volumeSize, SolidFireUtil.MIN_VOLUME_SIZE);
+    }
+
+    /**
+     * This method is only relevant when storagePool is being used with a compute cluster that supports UUID resigning.
+     */
+    @Override
+    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
+        List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
+
+        if (lstTemplatePoolRefs != null) {
+            for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
+                if (templatePoolRef.getTemplateId() == templateInfo.getId()) {
+                    // This indicates that we already have this template stored on this primary storage, so
+                    // we do not require additional space.
+                    return 0;
+                }
+            }
+        }
+
+        // This indicates that we do not have a copy of this template on this primary storage, so
+        // we need to take it into consideration from a space standpoint (ex. when a new VM is spun
+        // up and wants to use this particular template for its root disk).
+        return getDataObjectSizeIncludingHypervisorSnapshotReserve(templateInfo, storagePool);
+    }
+
+    private static class Iops {
+        private final long _minIops;
+        private final long _maxIops;
+        private final long _burstIops;
+
+        Iops(long minIops, long maxIops, long burstIops) throws IllegalArgumentException {
+            if (minIops <= 0 || maxIops <= 0) {
+                throw new IllegalArgumentException("The 'Min IOPS' and 'Max IOPS' values must be greater than 0.");
+            }
+
+            if (minIops > maxIops) {
+                throw new IllegalArgumentException("The 'Min IOPS' value cannot exceed the 'Max IOPS' value.");
+            }
+
+            if (maxIops > burstIops) {
+                throw new IllegalArgumentException("The 'Max IOPS' value cannot exceed the 'Burst IOPS' value.");
+            }
+
+            _minIops = minIops;
+            _maxIops = maxIops;
+            _burstIops = burstIops;
+        }
+
+        long getMinIops() {
+            return _minIops;
+        }
+
+        long getMaxIops() {
+            return _maxIops;
+        }
+
+        long getBurstIops() {
+            return _burstIops;
+        }
+    }
+
+    private void deleteSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo)
+    {
+        Long storagePoolId = volumeInfo.getPoolId();
+
+        if (storagePoolId == null) {
+            return; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
+        }
+
+        long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
+
+        deleteSolidFireVolume(sfConnection, volumeInfo.getId(), sfVolumeId);
+    }
+
+    @Override
+    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
+        String iqn = null;
+        String errMsg = null;
+
+        try {
+            if (dataObject.getType() == DataObjectType.VOLUME) {
+                iqn = createVolume((VolumeInfo)dataObject, dataStore.getId());
+            } else if (dataObject.getType() == DataObjectType.SNAPSHOT) {
+                createTempVolume((SnapshotInfo)dataObject, dataStore.getId());
+            } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
+                iqn = createTemplateVolume((TemplateInfo)dataObject, dataStore.getId());
+            } else {
+                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
+
+                LOGGER.error(errMsg);
+            }
+        }
+        catch (Exception ex) {
+            errMsg = ex.getMessage();
+
+            LOGGER.error(errMsg);
+
+            if (callback == null) {
+                throw ex;
+            }
+        }
+
+        if (callback != null) {
+            // path = iqn
+            // size is pulled from DataObject instance, if errMsg is null
+            CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+        else {
+            if (errMsg != null) {
+                throw new CloudRuntimeException(errMsg);
+            }
+        }
+    }
+
+    private long getCreateSolidFireAccountId(SolidFireUtil.SolidFireConnection sfConnection, long csAccountId, long storagePoolId) {
+        AccountDetailVO accountDetail = SolidFireUtil.getAccountDetail(csAccountId, storagePoolId, accountDetailsDao);
+
+        if (accountDetail == null || accountDetail.getValue() == null) {
+            AccountVO account = accountDao.findById(csAccountId);
+            String sfAccountName = SolidFireUtil.getSolidFireAccountName(account.getUuid(), account.getAccountId());
+            SolidFireUtil.SolidFireAccount sfAccount = SolidFireUtil.getAccount(sfConnection, sfAccountName);
+
+            if (sfAccount == null) {
+                sfAccount = createSolidFireAccount(sfConnection, sfAccountName);
+            }
+
+            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(account.getId(), sfAccount, storagePoolId, accountDetailsDao);
+
+            accountDetail = SolidFireUtil.getAccountDetail(csAccountId, storagePoolId, accountDetailsDao);
+        }
+
+        return Long.parseLong(accountDetail.getValue());
+    }
+
+    private void handleSnapshotDetails(long csSnapshotId, String name, String value) {
+        snapshotDetailsDao.removeDetail(csSnapshotId, name);
+
+        SnapshotDetailsVO snapshotDetails = new SnapshotDetailsVO(csSnapshotId, name, value, false);
+
+        snapshotDetailsDao.persist(snapshotDetails);
+    }
+
+    private void addTempVolumeId(long csSnapshotId, String tempVolumeId) {
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
+
+        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
+            throw new CloudRuntimeException("'addTempVolumeId' should not be invoked unless " + SolidFireUtil.VOLUME_ID + " exists.");
+        }
+
+        String originalVolumeId = snapshotDetails.getValue();
+
+        handleSnapshotDetails(csSnapshotId, SolidFireUtil.TEMP_VOLUME_ID, originalVolumeId);
+        handleSnapshotDetails(csSnapshotId, SolidFireUtil.VOLUME_ID, tempVolumeId);
+    }
+
+    private void removeTempVolumeId(long csSnapshotId) {
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.TEMP_VOLUME_ID);
+
+        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
+            throw new CloudRuntimeException("'removeTempVolumeId' should not be invoked unless " + SolidFireUtil.TEMP_VOLUME_ID + " exists.");
+        }
+
+        String originalVolumeId = snapshotDetails.getValue();
+
+        handleSnapshotDetails(csSnapshotId, SolidFireUtil.VOLUME_ID, originalVolumeId);
+
+        snapshotDetailsDao.remove(snapshotDetails.getId());
+    }
+
+    private Long getBasicSfVolumeId(long volumeId) {
+        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, BASIC_SF_ID);
+
+        if (volumeDetail != null && volumeDetail.getValue() != null) {
+            return new Long(volumeDetail.getValue());
+        }
+
+        return null;
+    }
+
+    private String getBasicIqn(long volumeId) {
+        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, BASIC_IQN);
+
+        if (volumeDetail != null && volumeDetail.getValue() != null) {
+            return volumeDetail.getValue();
+        }
+
+        return null;
+    }
+
+    // If isBasicCreate returns true, this means the calling code simply wants us to create a SolidFire volume with specified
+    // characteristics. We do not update the cloud.volumes table with this info.
+    private boolean isBasicCreate(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, BASIC_CREATE);
+    }
+
+    private boolean isBasicDelete(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, BASIC_DELETE);
+    }
+
+    private boolean isBasicDeleteFailure(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, BASIC_DELETE_FAILURE);
+    }
+
+    private boolean isBasicDeleteByFolder(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, PrimaryDataStoreDriver.BASIC_DELETE_BY_FOLDER);
+    }
+
+    private boolean isBasicGrantAccess(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, BASIC_GRANT_ACCESS);
+    }
+
+    private boolean isBasicRevokeAccess(long volumeId) {
+        return getBooleanValueFromVolumeDetails(volumeId, BASIC_REVOKE_ACCESS);
+    }
+
+    private boolean getBooleanValueFromVolumeDetails(long volumeId, String name) {
+        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, name);
+
+        return volumeDetail != null && volumeDetail.getValue() != null && Boolean.parseBoolean(volumeDetail.getValue());
+    }
+
+    private long getCsIdForCloning(long volumeId, String cloneOf) {
+        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, cloneOf);
+
+        if (volumeDetail != null && volumeDetail.getValue() != null) {
+            return new Long(volumeDetail.getValue());
+        }
+
+        return Long.MIN_VALUE;
+    }
+
+    private boolean shouldTakeSnapshot(long snapshotId) {
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshotId, "takeSnapshot");
+
+        return snapshotDetails != null && snapshotDetails.getValue() != null && Boolean.parseBoolean(snapshotDetails.getValue());
+    }
+
+    private SolidFireUtil.SolidFireVolume createClone(SolidFireUtil.SolidFireConnection sfConnection, long dataObjectId, VolumeInfo volumeInfo, long sfAccountId,
+            long storagePoolId, DataObjectType dataObjectType) {
+        String sfNewVolumeName = volumeInfo.getName();
+
+        long sfVolumeId = Long.MIN_VALUE;
+        long sfSnapshotId = Long.MIN_VALUE;
+
+        if (dataObjectType == DataObjectType.SNAPSHOT) {
+            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(dataObjectId, SolidFireUtil.SNAPSHOT_ID);
+
+            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+                sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
+            }
+
+            snapshotDetails = snapshotDetailsDao.findDetail(dataObjectId, SolidFireUtil.VOLUME_ID);
+
+            sfVolumeId = Long.parseLong(snapshotDetails.getValue());
+        } else if (dataObjectType == DataObjectType.TEMPLATE) {
+            // get the cached template on this storage
+            VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
+
+            if (templatePoolRef != null) {
+                sfVolumeId = Long.parseLong(templatePoolRef.getLocalDownloadPath());
+            }
+        }
+
+        if (sfVolumeId <= 0) {
+            throw new CloudRuntimeException("Unable to find SolidFire volume for the following data-object ID: " + dataObjectId +
+                    " and data-object type: " + dataObjectType);
+        }
+
+        final long newSfVolumeId = SolidFireUtil.createClone(sfConnection, sfVolumeId, sfSnapshotId, sfAccountId,
+                SolidFireUtil.getSolidFireVolumeName(sfNewVolumeName), getVolumeAttributes(volumeInfo));
+
+        final Iops iops = getIops(volumeInfo.getMinIops(), volumeInfo.getMaxIops(), storagePoolId);
+
+        SolidFireUtil.modifyVolume(sfConnection, newSfVolumeId, null, null, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+
+        return SolidFireUtil.getVolume(sfConnection, newSfVolumeId);
+    }
+
+    private Map<String, String> getVolumeAttributes(VolumeInfo volumeInfo) {
+        Map<String, String> mapAttributes = new HashMap<>();
+
+        mapAttributes.put(SolidFireUtil.CloudStackVolumeId, String.valueOf(volumeInfo.getId()));
+        mapAttributes.put(SolidFireUtil.CloudStackVolumeSize, NumberFormat.getInstance().format(volumeInfo.getSize()));
+
+        return mapAttributes;
+    }
+
+    private Map<String, String> getSnapshotAttributes(SnapshotInfo snapshotInfo) {
+        Map<String, String> mapAttributes = new HashMap<>();
+
+        mapAttributes.put(SolidFireUtil.CloudStackSnapshotId, String.valueOf(snapshotInfo.getId()));
+        mapAttributes.put(SolidFireUtil.CloudStackSnapshotSize, NumberFormat.getInstance().format(snapshotInfo.getSize()));
+
+        return mapAttributes;
+    }
+
+    private Map<String, String> getTemplateAttributes(TemplateInfo templateInfo) {
+        Map<String, String> mapAttributes = new HashMap<>();
+
+        mapAttributes.put(SolidFireUtil.CloudStackTemplateId, String.valueOf(templateInfo.getId()));
+        mapAttributes.put(SolidFireUtil.CloudStackTemplateSize, NumberFormat.getInstance().format(templateInfo.getSize()));
+
+        return mapAttributes;
+    }
+
+    private SolidFireUtil.SolidFireVolume createCloneFromSnapshot(SolidFireUtil.SolidFireConnection sfConnection, long csSnapshotId, long sfAccountId) {
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
+
+        long sfVolumeId = Long.parseLong(snapshotDetails.getValue());
+
+        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
+
+        long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
+
+        SolidFireUtil.SolidFireSnapshot sfSnapshot = SolidFireUtil.getSnapshot(sfConnection, sfVolumeId, sfSnapshotId);
+
+        long newSfVolumeId = SolidFireUtil.createClone(sfConnection, sfVolumeId, sfSnapshotId, sfAccountId, SolidFireUtil.getSolidFireVolumeName(sfSnapshot.getName()), null);
+
+        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.STORAGE_POOL_ID);
+
+        long storagePoolId = Long.parseLong(snapshotDetails.getValue());
+
+        final Iops iops = getIops(MIN_IOPS_FOR_TEMP_VOLUME, MAX_IOPS_FOR_TEMP_VOLUME, storagePoolId);
+
+        SolidFireUtil.modifyVolume(sfConnection, newSfVolumeId, null, null, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+
+        return SolidFireUtil.getVolume(sfConnection, newSfVolumeId);
+    }
+
+    private void updateVolumeDetails(long volumeId, long sfVolumeSize, String scsiNaaDeviceId) {
+        volumeDetailsDao.removeDetail(volumeId, SolidFireUtil.VOLUME_SIZE);
+        volumeDetailsDao.removeDetail(volumeId, DiskTO.SCSI_NAA_DEVICE_ID);
+
+        VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeId, SolidFireUtil.VOLUME_SIZE, String.valueOf(sfVolumeSize), false);
+
+        volumeDetailsDao.persist(volumeDetailVo);
+
+        volumeDetailVo = new VolumeDetailVO(volumeId, DiskTO.SCSI_NAA_DEVICE_ID, scsiNaaDeviceId, false);
+
+        volumeDetailsDao.persist(volumeDetailVo);
+    }
+
+    @Override
+    public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
+        String errMsg = null;
+
+        try {
+            if (dataObject.getType() == DataObjectType.VOLUME) {
+                deleteVolume((VolumeInfo)dataObject, dataStore.getId());
+            } else if (dataObject.getType() == DataObjectType.SNAPSHOT) {
+                deleteSnapshot((SnapshotInfo)dataObject, dataStore.getId());
+            } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
+                deleteTemplate((TemplateInfo)dataObject, dataStore.getId());
+            } else {
+                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
+            }
+        }
+        catch (Exception ex) {
+            errMsg = ex.getMessage();
+
+            LOGGER.error(errMsg);
+        }
+
+        if (callback != null) {
+            CommandResult result = new CommandResult();
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    @Override
+    public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canCopy(DataObject srcData, DataObject destData) {
+        return false;
+    }
+
+    @Override
+    public void takeSnapshot(SnapshotInfo snapshotInfo, AsyncCompletionCallback<CreateCmdResult> callback) {
+        CreateCmdResult result;
+
+        try {
+            VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
+            VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId());
+
+            long sfVolumeId = Long.parseLong(volumeVO.getFolder());
+            long storagePoolId = volumeVO.getPoolId();
+
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
+
+            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+            long capacityBytes = storagePool.getCapacityBytes();
+            // getUsedBytes(StoragePool) will not include the bytes of the proposed new volume or snapshot because
+            // updateSnapshotDetails has not yet been called for this new volume or snapshot
+            long usedBytes = getUsedBytes(storagePool);
+            long sfVolumeSize = sfVolume.getTotalSize();
+
+            usedBytes += sfVolumeSize;
+
+            // For creating a volume or a snapshot, we need to check to make sure a sufficient amount of space remains in the primary storage.
+            // For the purpose of "charging" these bytes against storage_pool.capacity_bytes, we take the full size of the SolidFire volume
+            // that is serving as the volume the snapshot is of (either a new SolidFire volume or a SolidFire snapshot).
+            if (usedBytes > capacityBytes) {
+                throw new CloudRuntimeException("Insufficient amount of space remains in this primary storage to take a snapshot");
+            }
+
+            storagePool.setUsedBytes(usedBytes);
+
+            SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO)snapshotInfo.getTO();
+
+            if (shouldTakeSnapshot(snapshotInfo.getId())) {
+                // We are supposed to take a SolidFire snapshot to serve as the back-end for our CloudStack volume snapshot.
+
+                String sfNewSnapshotName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
+
+                int maxSnapshotNameLength = 64;
+                int trimRequired = sfNewSnapshotName.length() - maxSnapshotNameLength;
+
+                if (trimRequired > 0) {
+                    sfNewSnapshotName = StringUtils.left(volumeInfo.getName(), (volumeInfo.getName().length() - trimRequired)) + "-" + snapshotInfo.getUuid();
+                }
+
+                long sfNewSnapshotId = SolidFireUtil.createSnapshot(sfConnection, sfVolumeId, SolidFireUtil.getSolidFireVolumeName(sfNewSnapshotName),
+                        getSnapshotAttributes(snapshotInfo));
+
+                updateSnapshotDetails(snapshotInfo.getId(), volumeInfo.getId(), sfVolumeId, sfNewSnapshotId, storagePoolId, sfVolumeSize);
+
+                snapshotObjectTo.setPath("SfSnapshotId=" + sfNewSnapshotId);
+            }
+            else {
+                // We are supposed to create a new SolidFire volume to serve as the back-end for our CloudStack volume snapshot.
+
+                String sfNewVolumeName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
+
+                final Iops iops = getIops(MIN_IOPS_FOR_SNAPSHOT_VOLUME, MAX_IOPS_FOR_SNAPSHOT_VOLUME, storagePoolId);
+
+                long sfNewVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(sfNewVolumeName), sfVolume.getAccountId(),
+                        sfVolumeSize, sfVolume.isEnable512e(), getSnapshotAttributes(snapshotInfo), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+
+                SolidFireUtil.SolidFireVolume sfNewVolume = SolidFireUtil.getVolume(sfConnection, sfNewVolumeId);
+
+                updateSnapshotDetails(snapshotInfo.getId(), sfNewVolumeId, storagePoolId, sfVolumeSize, sfNewVolume.getIqn());
+
+                snapshotObjectTo.setPath("SfVolumeId=" + sfNewVolumeId);
+            }
+
+            // Now that we have successfully created a volume or a snapshot, update the space usage in the cloud.storage_pool table
+            // (even though cloud.storage_pool.used_bytes is likely no longer in use).
+            storagePoolDao.update(storagePoolId, storagePool);
+
+            CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotObjectTo);
+
+            result = new CreateCmdResult(null, createObjectAnswer);
+
+            result.setResult(null);
+        }
+        catch (Exception ex) {
+            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to take CloudStack snapshot: " + snapshotInfo.getId(), ex);
+
+            result = new CreateCmdResult(null, new CreateObjectAnswer(ex.toString()));
+
+            result.setResult(ex.toString());
+        }
+
+        callback.complete(result);
+    }
+
+    private void updateSnapshotDetails(long csSnapshotId, long csVolumeId, long sfVolumeId, long sfNewSnapshotId, long storagePoolId, long sfNewVolumeSize) {
+        SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.ORIG_CS_VOLUME_ID,
+                String.valueOf(csVolumeId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.VOLUME_ID,
+                String.valueOf(sfVolumeId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.SNAPSHOT_ID,
+                String.valueOf(sfNewSnapshotId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.STORAGE_POOL_ID,
+                String.valueOf(storagePoolId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.VOLUME_SIZE,
+                String.valueOf(sfNewVolumeSize),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+    }
+
+    private void updateSnapshotDetails(long csSnapshotId, long sfNewVolumeId, long storagePoolId, long sfNewVolumeSize, String sfNewVolumeIqn) {
+        SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.VOLUME_ID,
+                String.valueOf(sfNewVolumeId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.STORAGE_POOL_ID,
+                String.valueOf(storagePoolId),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                SolidFireUtil.VOLUME_SIZE,
+                String.valueOf(sfNewVolumeSize),
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+
+        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
+                DiskTO.IQN,
+                sfNewVolumeIqn,
+                false);
+
+        snapshotDetailsDao.persist(snapshotDetail);
+    }
+
+    private void addBasicCreateInfoToVolumeDetails(long volumeId, SolidFireUtil.SolidFireVolume sfVolume) {
+        VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeId, BASIC_SF_ID, String.valueOf(sfVolume.getId()), false);
+
+        volumeDetailsDao.persist(volumeDetailVo);
+
+        volumeDetailVo = new VolumeDetailVO(volumeId, BASIC_IQN, sfVolume.getIqn(), false);
+
+        volumeDetailsDao.persist(volumeDetailVo);
+    }
+
+    private String createVolume(VolumeInfo volumeInfo, long storagePoolId) {
+        boolean isBasicCreate = isBasicCreate(volumeInfo.getId());
+
+        if (!isBasicCreate) {
+            verifySufficientBytesForStoragePool(volumeInfo, storagePoolId);
+            verifySufficientIopsForStoragePool(volumeInfo.getMinIops() != null ? volumeInfo.getMinIops() : getDefaultMinIops(storagePoolId), storagePoolId);
+        }
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+        long sfAccountId = getCreateSolidFireAccountId(sfConnection, volumeInfo.getAccountId(), storagePoolId);
+
+        SolidFireUtil.SolidFireVolume sfVolume;
+
+        if (isBasicCreate) {
+            sfVolume = createSolidFireVolume(sfConnection, volumeInfo, storagePoolId, sfAccountId);
+
+            volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_CREATE);
+
+            addBasicCreateInfoToVolumeDetails(volumeInfo.getId(), sfVolume);
+
+            return sfVolume.getIqn();
+        }
+
+        long csSnapshotId = getCsIdForCloning(volumeInfo.getId(), "cloneOfSnapshot");
+        long csTemplateId = getCsIdForCloning(volumeInfo.getId(), "cloneOfTemplate");
+
+        if (csSnapshotId > 0) {
+            // We are supposed to create a clone of the underlying volume or snapshot that supports the CloudStack snapshot.
+            sfVolume = createClone(sfConnection, csSnapshotId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.SNAPSHOT);
+        } else if (csTemplateId > 0) {
+            // Clone from template.
+            sfVolume = createClone(sfConnection, csTemplateId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.TEMPLATE);
+
+            long volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePoolDao.findById(storagePoolId));
+
+            if (volumeSize > sfVolume.getTotalSize()) {
+                // Expand the volume to include HSR.
+                SolidFireUtil.modifyVolume(sfConnection, sfVolume.getId(), volumeSize, getVolumeAttributes(volumeInfo),
+                        sfVolume.getMinIops(), sfVolume.getMaxIops(), sfVolume.getBurstIops());
+
+                // Get the SolidFire volume from the SAN again because we just updated its size.
+                sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolume.getId());
+            }
+        }
+        else {
+            sfVolume = createSolidFireVolume(sfConnection, volumeInfo, storagePoolId, sfAccountId);
+        }
+
+        String iqn = sfVolume.getIqn();
+
+        VolumeVO volume = volumeDao.findById(volumeInfo.getId());
+
+        volume.set_iScsiName(iqn);
+        volume.setFolder(String.valueOf(sfVolume.getId()));
+        volume.setPoolType(StoragePoolType.IscsiLUN);
+        volume.setPoolId(storagePoolId);
+
+        volumeDao.update(volume.getId(), volume);
+
+        updateVolumeDetails(volume.getId(), sfVolume.getTotalSize(), sfVolume.getScsiNaaDeviceId());
+
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        long capacityBytes = storagePool.getCapacityBytes();
+        // getUsedBytes(StoragePool) will include the bytes of the newly created volume because
+        // updateVolumeDetails(long, long) has already been called for this volume
+        long usedBytes = getUsedBytes(storagePool);
+
+        storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
+
+        storagePoolDao.update(storagePoolId, storagePool);
+
+        return iqn;
+    }
+
+    private void createTempVolume(SnapshotInfo snapshotInfo, long storagePoolId) {
+        long csSnapshotId = snapshotInfo.getId();
+
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
+
+        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
+            throw new CloudRuntimeException("'createTempVolume(SnapshotInfo, long)' should not be invoked unless " + SolidFireUtil.SNAPSHOT_ID + " exists.");
+        }
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, "tempVolume");
+
+        if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("create")) {
+            long sfAccountId = getCreateSolidFireAccountId(sfConnection, snapshotInfo.getAccountId(), storagePoolId);
+
+            SolidFireUtil.SolidFireVolume sfVolume = createCloneFromSnapshot(sfConnection, csSnapshotId, sfAccountId);
+
+            addTempVolumeId(csSnapshotId, String.valueOf(sfVolume.getId()));
+
+            handleSnapshotDetails(csSnapshotId, DiskTO.IQN, sfVolume.getIqn());
+            handleSnapshotDetails(csSnapshotId, DiskTO.SCSI_NAA_DEVICE_ID, sfVolume.getScsiNaaDeviceId());
+        }
+        else if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("delete")) {
+            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
+
+            SolidFireUtil.deleteVolume(sfConnection, Long.parseLong(snapshotDetails.getValue()));
+
+            removeTempVolumeId(csSnapshotId);
+
+            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, DiskTO.IQN);
+
+            snapshotDetailsDao.remove(snapshotDetails.getId());
+
+            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, DiskTO.SCSI_NAA_DEVICE_ID);
+
+            snapshotDetailsDao.remove(snapshotDetails.getId());
+        }
+        else {
+            throw new CloudRuntimeException("Invalid state in 'createTempVolume(SnapshotInfo, long)'");
+        }
+    }
+
+    private String createTemplateVolume(TemplateInfo templateInfo, long storagePoolId) {
+        verifySufficientBytesForStoragePool(templateInfo, storagePoolId);
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+        long sfAccountId = getCreateSolidFireAccountId(sfConnection, templateInfo.getAccountId(), storagePoolId);
+
+        SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, templateInfo, storagePoolId, sfAccountId);
+
+        String iqn = sfVolume.getIqn();
+
+        VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId());
+
+        templatePoolRef.setInstallPath(iqn);
+        templatePoolRef.setLocalDownloadPath(Long.toString(sfVolume.getId()));
+        templatePoolRef.setTemplateSize(sfVolume.getTotalSize());
+
+        tmpltPoolDao.update(templatePoolRef.getId(), templatePoolRef);
+
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        long capacityBytes = storagePool.getCapacityBytes();
+        // getUsedBytes(StoragePool) will include the bytes of the newly created template volume because
+        // _tmpltPoolDao.update(Long, VMTemplateStoragePoolVO) has already been invoked
+        long usedBytes = getUsedBytes(storagePool);
+
+        storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
+
+        storagePoolDao.update(storagePoolId, storagePool);
+
+        return iqn;
+    }
+
+    private void performBasicDelete(SolidFireUtil.SolidFireConnection sfConnection, long volumeId) {
+        Long sfVolumeId = getBasicSfVolumeId(volumeId);
+
+        Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null'.");
+
+        String iqn = getBasicIqn(volumeId);
+
+        Preconditions.checkNotNull(iqn, "'iqn' should not be 'null'.");
+
+        VolumeVO volumeVO = volumeDao.findById(volumeId);
+
+        deleteSolidFireVolume(sfConnection, volumeId, Long.parseLong(volumeVO.getFolder()));
+
+        volumeVO.setFolder(String.valueOf(sfVolumeId));
+        volumeVO.set_iScsiName(iqn);
+
+        volumeDao.update(volumeId, volumeVO);
+
+        volumeDetailsDao.removeDetail(volumeId, BASIC_SF_ID);
+        volumeDetailsDao.removeDetail(volumeId, BASIC_IQN);
+        volumeDetailsDao.removeDetail(volumeId, BASIC_DELETE);
+    }
+
+    private void performBasicDeleteFailure(SolidFireUtil.SolidFireConnection sfConnection, long volumeId) {
+        Long sfVolumeId = getBasicSfVolumeId(volumeId);
+
+        Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null'.");
+
+        SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
+
+        volumeDetailsDao.removeDetail(volumeId, BASIC_SF_ID);
+        volumeDetailsDao.removeDetail(volumeId, BASIC_IQN);
+        volumeDetailsDao.removeDetail(volumeId, BASIC_DELETE_FAILURE);
+    }
+
+    private void performBasicDeleteByFolder(SolidFireUtil.SolidFireConnection sfConnection, long volumeId) {
+        VolumeVO volumeVO = volumeDao.findById(volumeId);
+
+        Preconditions.checkNotNull(volumeVO, "'volumeVO' should not be 'null'.");
+
+        String folder = volumeVO.getFolder();
+
+        Preconditions.checkNotNull(folder, "'folder' should not be 'null'.");
+
+        long sfVolumeId = Long.parseLong(folder);
+
+        SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
+    }
+
+    private void deleteVolume(VolumeInfo volumeInfo, long storagePoolId) {
+        try {
+            long volumeId = volumeInfo.getId();
+
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            if (isBasicDeleteByFolder(volumeId)) {
+                performBasicDeleteByFolder(sfConnection, volumeId);
+            }
+            else if (isBasicDelete(volumeId)) {
+                performBasicDelete(sfConnection, volumeId);
+            }
+            else if (isBasicDeleteFailure(volumeId)) {
+                performBasicDeleteFailure(sfConnection, volumeId);
+            }
+            else {
+                deleteSolidFireVolume(sfConnection, volumeInfo);
+
+                volumeDetailsDao.removeDetails(volumeId);
+
+                StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+                long usedBytes = getUsedBytes(storagePool, volumeId);
+
+                storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
+
+                storagePoolDao.update(storagePoolId, storagePool);
+            }
+        }
+        catch (Exception ex) {
+            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to delete SolidFire volume. CloudStack volume ID: " + volumeInfo.getId(), ex);
+
+            throw ex;
+        }
+    }
+
+    private void deleteSnapshot(SnapshotInfo snapshotInfo, long storagePoolId) {
+        long csSnapshotId = snapshotInfo.getId();
+
+        try {
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
+
+            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+                // A SolidFire snapshot is being used to support the CloudStack volume snapshot.
+
+                long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
+
+                deleteSolidFireSnapshot(sfConnection, csSnapshotId, sfSnapshotId);
+            }
+            else {
+                // A SolidFire volume is being used to support the CloudStack volume snapshot.
+
+                snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
+
+                long sfVolumeId = Long.parseLong(snapshotDetails.getValue());
+
+                SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
+            }
+
+            snapshotDetailsDao.removeDetails(csSnapshotId);
+
+            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+            // getUsedBytes(StoragePool) will not include the snapshot to delete because it has already been deleted by this point
+            long usedBytes = getUsedBytes(storagePool);
+
+            storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
+
+            storagePoolDao.update(storagePoolId, storagePool);
+        }
+        catch (Exception ex) {
+            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Issue in 'deleteSnapshot(SnapshotInfo, long)'. CloudStack snapshot ID: " + csSnapshotId, ex);
+
+            throw ex;
+        }
+    }
+
+    private void deleteTemplate(TemplateInfo template, long storagePoolId) {
+        try {
+            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+            long sfTemplateVolumeId = getVolumeIdFrom_iScsiPath(template.getInstallPath());
+
+            SolidFireUtil.deleteVolume(sfConnection, sfTemplateVolumeId);
+
+            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+            // getUsedBytes(StoragePool) will not include the template to delete because the "template_spool_ref" table has already been updated by this point
+            long usedBytes = getUsedBytes(storagePool);
+
+            storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
+
+            storagePoolDao.update(storagePoolId, storagePool);
+        }
+        catch (Exception ex) {
+            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to delete SolidFire template volume. CloudStack template ID: " + template.getId(), ex);
+
+            throw ex;
+        }
+    }
+
+    @Override
+    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshot2, AsyncCompletionCallback<CommandResult> callback) {
+        VolumeInfo volumeInfo = snapshot.getBaseVolume();
+
+        VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId());
+
+        if (volumeVO == null || volumeVO.getRemoved() != null) {
+            String errMsg = "The volume that the snapshot belongs to no longer exists.";
+
+            CommandResult commandResult = new CommandResult();
+
+            commandResult.setResult(errMsg);
+
+            callback.complete(commandResult);
+
+            return;
+        }
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(volumeVO.getPoolId(), storagePoolDetailsDao);
+
+        long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
+
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.SNAPSHOT_ID);
+
+        long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
+
+        SolidFireUtil.rollBackVolumeToSnapshot(sfConnection, sfVolumeId, sfSnapshotId);
+
+        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
+
+        updateVolumeDetails(volumeVO.getId(), sfVolume.getTotalSize(), sfVolume.getScsiNaaDeviceId());
+
+        CommandResult commandResult = new CommandResult();
+
+        callback.complete(commandResult);
+    }
+
+    @Override
+    public void resize(DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
+        String iqn = null;
+        String errMsg = null;
+
+        try {
+            if (dataObject.getType() == DataObjectType.VOLUME) {
+                VolumeInfo volumeInfo = (VolumeInfo)dataObject;
+
+                iqn = volumeInfo.get_iScsiName();
+
+                long storagePoolId = volumeInfo.getPoolId();
+                long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
+
+                ResizeVolumePayload payload = (ResizeVolumePayload)volumeInfo.getpayload();
+
+                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+                SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
+
+                long newMinIops = payload.newMinIops != null ? payload.newMinIops : sfVolume.getMinIops();
+
+                verifySufficientIopsForStoragePool(storagePoolId, sfVolume, newMinIops);
+
+                long newSize = payload.newSize != null ? payload.newSize : volumeInfo.getSize();
+
+                verifySufficientBytesForStoragePool(storagePoolId, volumeInfo.getId(), newSize, payload.newHypervisorSnapshotReserve);
+
+                long sfNewVolumeSize = sfVolume.getTotalSize();
+
+                Integer hsr = volumeInfo.getHypervisorSnapshotReserve();
+
+                if (payload.newSize != null || payload.newHypervisorSnapshotReserve != null) {
+                    if (payload.newHypervisorSnapshotReserve != null) {
+                        if (hsr != null) {
+                            if (payload.newHypervisorSnapshotReserve > hsr) {
+                                hsr = payload.newHypervisorSnapshotReserve;
+                            }
+                        } else {
+                            hsr = payload.newHypervisorSnapshotReserve;
+                        }
+                    }
+
+                    sfNewVolumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(newSize, hsr);
+                }
+
+                Map<String, String> mapAttributes = new HashMap<>();
+
+                mapAttributes.put(SolidFireUtil.CloudStackVolumeId, String.valueOf(volumeInfo.getId()));
+                mapAttributes.put(SolidFireUtil.CloudStackVolumeSize, NumberFormat.getInstance().format(payload.newSize));
+
+                long newMaxIops = payload.newMaxIops != null ? payload.newMaxIops : sfVolume.getMaxIops();
+
+                SolidFireUtil.modifyVolume(sfConnection, sfVolumeId, sfNewVolumeSize, mapAttributes,
+                        newMinIops, newMaxIops, getDefaultBurstIops(storagePoolId, newMaxIops));
+
+                VolumeVO volume = volumeDao.findById(volumeInfo.getId());
+
+                volume.setMinIops(newMinIops);
+                volume.setMaxIops(newMaxIops);
+                volume.setHypervisorSnapshotReserve(hsr);
+
+                volumeDao.update(volume.getId(), volume);
+
+                // SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
+                updateVolumeDetails(volume.getId(), sfNewVolumeSize, sfVolume.getScsiNaaDeviceId());
+            } else {
+                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to resize";
+            }
+        }
+        catch (Exception ex) {
+            errMsg = ex.getMessage();
+        }
+        finally {
+            CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
+
+            result.setResult(errMsg);
+
+            callback.complete(result);
+        }
+    }
+
+    @Override
+    public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) {
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(volumeInfo.getPoolId(), storagePoolDetailsDao);
+
+        Iops iops;
+
+        if (QualityOfServiceState.MIGRATION.equals(qualityOfServiceState)) {
+            iops = getIops(volumeInfo.getMinIops(), MAX_IOPS_FOR_MIGRATING_VOLUME, volumeInfo.getPoolId());
+        } else {
+            iops = getIops(volumeInfo.getMinIops(), volumeInfo.getMaxIops(), volumeInfo.getPoolId());
+        }
+
+        SolidFireUtil.modifyVolumeQoS(sfConnection, Long.parseLong(volumeInfo.getFolder()), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+    }
+
+    private void verifySufficientBytesForStoragePool(long requestedBytes, long storagePoolId) {
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        long capacityBytes = storagePool.getCapacityBytes();
+        long usedBytes = getUsedBytes(storagePool);
+
+        usedBytes += requestedBytes;
+
+        if (usedBytes > capacityBytes) {
+            throw new CloudRuntimeException("Insufficient amount of space remains in this primary storage");
+        }
+    }
+
+    private void verifySufficientBytesForStoragePool(DataObject dataObject, long storagePoolId) {
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        long requestedBytes = getDataObjectSizeIncludingHypervisorSnapshotReserve(dataObject, storagePool);
+
+        verifySufficientBytesForStoragePool(requestedBytes, storagePoolId);
+    }
+
+    private void verifySufficientBytesForStoragePool(long storagePoolId, long volumeId, long newSize, Integer newHypervisorSnapshotReserve) {
+        DataStore primaryDataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        VolumeInfo volumeInfo = volumeFactory.getVolume(volumeId, primaryDataStore);
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+        long currentSizeWithHsr = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePool);
+
+        newHypervisorSnapshotReserve = newHypervisorSnapshotReserve == null ? LOWEST_HYPERVISOR_SNAPSHOT_RESERVE :
+                Math.max(newHypervisorSnapshotReserve, LOWEST_HYPERVISOR_SNAPSHOT_RESERVE);
+
+        long newSizeWithHsr = (long)(newSize + newSize * (newHypervisorSnapshotReserve / 100f));
+
+        if (newSizeWithHsr < currentSizeWithHsr) {
+            throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not support shrinking a volume.");
+        }
+
+        long availableBytes = storagePool.getCapacityBytes() - getUsedBytes(storagePool);
+
+        if ((newSizeWithHsr - currentSizeWithHsr) > availableBytes) {
+            throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not have enough space to expand the volume.");
+        }
+    }
+
+    private void verifySufficientIopsForStoragePool(long requestedIops, long storagePoolId) {
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        long usedIops = getUsedIops(storagePool);
+        long capacityIops = storagePool.getCapacityIops();
+
+        if (usedIops + requestedIops > capacityIops) {
+            throw new CloudRuntimeException("Insufficient number of IOPS available in this storage pool");
+        }
+    }
+
+    private void verifySufficientIopsForStoragePool(long storagePoolId, SolidFireUtil.SolidFireVolume sfVolume, long newMinIops) {
+        long currentMinIops = sfVolume.getMinIops();
+        long diffInMinIops = newMinIops - currentMinIops;
+
+        // if the desire is for more IOPS
+        if (diffInMinIops > 0) {
+            verifySufficientIopsForStoragePool(diffInMinIops, storagePoolId);
+        }
+    }
+
+    private void deleteSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, long csVolumeId, long sfVolumeId) {
+        List<SnapshotVO> lstSnapshots = getNonDestroyedSnapshots(csVolumeId);
+
+        boolean deleteVolume = true;
+
+        for (SnapshotVO snapshot : lstSnapshots) {
+            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.SNAPSHOT_ID);
+
+            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+                deleteVolume = false;
+
+                break;
+            }
+        }
+
+        if (deleteVolume) {
+            SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
+        }
+    }
+
+    private void deleteSolidFireSnapshot(SolidFireUtil.SolidFireConnection sfConnection, long csSnapshotId, long sfSnapshotId) {
+        SolidFireUtil.deleteSnapshot(sfConnection, sfSnapshotId);
+
+        final long volumeId;
+        final VolumeVO volume;
+
+        SnapshotVO snapshot = snapshotDao.findById(csSnapshotId);
+        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.ORIG_CS_VOLUME_ID);
+
+        if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+            volumeId = Long.valueOf(snapshotDetails.getValue());
+        }
+        else {
+            volumeId = snapshot.getVolumeId();
+        }
+
+        volume = volumeDao.findById(volumeId);
+
+        if (volume == null) { // if the CloudStack volume has been deleted
+            List<SnapshotVO> lstSnapshots = getNonDestroyedSnapshots(snapshot.getVolumeId());
+
+            List<SnapshotVO> lstSnapshots2 = new ArrayList<>();
+
+            for (SnapshotVO snapshotVo : lstSnapshots) {
+                // The CloudStack volume snapshot has not yet been set to the DESTROYED state, so check to make
+                // sure snapshotVo.getId() != csSnapshotId when determining if any volume snapshots remain for the given CloudStack volume.
+                if (snapshotVo.getId() != csSnapshotId) {
+                    snapshotDetails = snapshotDetailsDao.findDetail(snapshotVo.getId(), SolidFireUtil.SNAPSHOT_ID);
+
+                    // We are only interested here in volume snapshots that make use of SolidFire snapshots (as opposed to ones
+                    // that make use of SolidFire volumes).
+                    if (snapshotDetails != null && snapshotDetails.getValue() != null) {
+                        lstSnapshots2.add(snapshotVo);
+                    }
+                }
+            }
+
+            if (lstSnapshots2.isEmpty()) {
+                VolumeVO volumeToDelete = volumeDao.findByIdIncludingRemoved(volumeId);
+
+                SolidFireUtil.deleteVolume(sfConnection, Long.parseLong(volumeToDelete.getFolder()));
+            }
+        }
+    }
+
+    private List<SnapshotVO> getNonDestroyedSnapshots(long csVolumeId) {
+        List<SnapshotVO> lstSnapshots = snapshotDao.listByVolumeId(csVolumeId);
+
+        if (lstSnapshots == null) {
+            lstSnapshots = new ArrayList<>();
+        }
+
+        List<SnapshotVO> lstSnapshots2 = new ArrayList<>();
+
+        for (SnapshotVO snapshot : lstSnapshots) {
+            if (!State.Destroyed.equals(snapshot.getState())) {
+                lstSnapshots2.add(snapshot);
+            }
+        }
+
+        return lstSnapshots2;
+    }
+}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
similarity index 100%
rename from plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
rename to plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
similarity index 100%
rename from plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
rename to plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
new file mode 100644
index 0000000..2ebd69a
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
@@ -0,0 +1,769 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.lifecycle;
+
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
+import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolAutomation;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountDetailsDao;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SolidFireSharedPrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle {
+    private static final Logger LOGGER = Logger.getLogger(SolidFireSharedPrimaryDataStoreLifeCycle.class);
+
+    @Inject private AccountDao accountDao;
+    @Inject private AccountDetailsDao accountDetailsDao;
+    @Inject private AgentManager agentMgr;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataCenterDao zoneDao;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao primaryDataStoreDao;
+    @Inject private PrimaryDataStoreHelper primaryDataStoreHelper;
+    @Inject private ResourceManager resourceMgr;
+    @Inject private StorageManager storageMgr;
+    @Inject private StoragePoolAutomation storagePoolAutomation;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject private StoragePoolHostDao storagePoolHostDao;
+    @Inject private TemplateManager tmpltMgr;
+
+    // invoked to add primary storage that is based on the SolidFire plug-in
+    @Override
+    public DataStore initialize(Map<String, Object> dsInfos) {
+        final String CAPACITY_IOPS = "capacityIops";
+
+        String url = (String)dsInfos.get("url");
+        Long zoneId = (Long)dsInfos.get("zoneId");
+        Long podId = (Long)dsInfos.get("podId");
+        Long clusterId = (Long)dsInfos.get("clusterId");
+        String storagePoolName = (String)dsInfos.get("name");
+        String providerName = (String)dsInfos.get("providerName");
+        Long capacityBytes = (Long)dsInfos.get("capacityBytes");
+        Long capacityIops = (Long)dsInfos.get(CAPACITY_IOPS);
+        String tags = (String)dsInfos.get("tags");
+        @SuppressWarnings("unchecked")
+        Map<String, String> details = (Map<String, String>)dsInfos.get("details");
+
+        if (podId == null) {
+            throw new CloudRuntimeException("The Pod ID must be specified.");
+        }
+
+        if (clusterId == null) {
+            throw new CloudRuntimeException("The Cluster ID must be specified.");
+        }
+
+        String storageVip = SolidFireUtil.getStorageVip(url);
+        int storagePort = SolidFireUtil.getStoragePort(url);
+
+        if (capacityBytes == null || capacityBytes <= 0) {
+            throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0.");
+        }
+
+        if (capacityIops == null || capacityIops <= 0) {
+            throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
+        }
+
+        HypervisorType hypervisorType = getHypervisorTypeForCluster(clusterId);
+
+        if (!isSupportedHypervisorType(hypervisorType)) {
+            throw new CloudRuntimeException(hypervisorType + " is not a supported hypervisor type.");
+        }
+
+        String datacenter = SolidFireUtil.getValue(SolidFireUtil.DATACENTER, url, false);
+
+        if (HypervisorType.VMware.equals(hypervisorType) && datacenter == null) {
+            throw new CloudRuntimeException("'Datacenter' must be set for hypervisor type of " + HypervisorType.VMware);
+        }
+
+        PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
+
+        parameters.setType(getStorageType(hypervisorType));
+        parameters.setZoneId(zoneId);
+        parameters.setPodId(podId);
+        parameters.setClusterId(clusterId);
+        parameters.setName(storagePoolName);
+        parameters.setProviderName(providerName);
+        parameters.setManaged(false);
+        parameters.setCapacityBytes(capacityBytes);
+        parameters.setUsedBytes(0);
+        parameters.setCapacityIops(capacityIops);
+        parameters.setHypervisorType(hypervisorType);
+        parameters.setTags(tags);
+        parameters.setDetails(details);
+
+        String managementVip = SolidFireUtil.getManagementVip(url);
+        int managementPort = SolidFireUtil.getManagementPort(url);
+
+        details.put(SolidFireUtil.MANAGEMENT_VIP, managementVip);
+        details.put(SolidFireUtil.MANAGEMENT_PORT, String.valueOf(managementPort));
+
+        String clusterAdminUsername = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_USERNAME, url);
+        String clusterAdminPassword = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, url);
+
+        details.put(SolidFireUtil.CLUSTER_ADMIN_USERNAME, clusterAdminUsername);
+        details.put(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, clusterAdminPassword);
+
+        if (capacityBytes < SolidFireUtil.MIN_VOLUME_SIZE) {
+            capacityBytes = SolidFireUtil.MIN_VOLUME_SIZE;
+        }
+
+        long lMinIops = 100;
+        long lMaxIops = 15000;
+        long lBurstIops = 15000;
+
+        try {
+            String minIops = SolidFireUtil.getValue(SolidFireUtil.MIN_IOPS, url);
+
+            if (minIops != null && minIops.trim().length() > 0) {
+                lMinIops = Long.parseLong(minIops);
+            }
+        } catch (Exception ex) {
+            LOGGER.info("[ignored] error getting Min IOPS: " + ex.getLocalizedMessage());
+        }
+
+        try {
+            String maxIops = SolidFireUtil.getValue(SolidFireUtil.MAX_IOPS, url);
+
+            if (maxIops != null && maxIops.trim().length() > 0) {
+                lMaxIops = Long.parseLong(maxIops);
+            }
+        } catch (Exception ex) {
+            LOGGER.info("[ignored] error getting Max IOPS: " + ex.getLocalizedMessage());
+        }
+
+        try {
+            String burstIops = SolidFireUtil.getValue(SolidFireUtil.BURST_IOPS, url);
+
+            if (burstIops != null && burstIops.trim().length() > 0) {
+                lBurstIops = Long.parseLong(burstIops);
+            }
+        } catch (Exception ex) {
+            LOGGER.info("[ignored] error getting Burst IOPS: " + ex.getLocalizedMessage());
+        }
+
+        if (lMinIops > lMaxIops) {
+            throw new CloudRuntimeException("The parameter '" + SolidFireUtil.MIN_IOPS + "' must be less than or equal to the parameter '" + SolidFireUtil.MAX_IOPS + "'.");
+        }
+
+        if (lMaxIops > lBurstIops) {
+            throw new CloudRuntimeException("The parameter '" + SolidFireUtil.MAX_IOPS + "' must be less than or equal to the parameter '" + SolidFireUtil.BURST_IOPS + "'.");
+        }
+
+        if (lMinIops != capacityIops) {
+            throw new CloudRuntimeException("The parameter '" + CAPACITY_IOPS + "' must be equal to the parameter '" + SolidFireUtil.MIN_IOPS + "'.");
+        }
+
+        if (lMinIops > SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) {
+            throw new CloudRuntimeException("This volume's Min IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) + " IOPS.");
+        }
+
+        if (lMaxIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
+            throw new CloudRuntimeException("This volume's Max IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_IOPS_PER_VOLUME) + " IOPS.");
+        }
+
+        if (lBurstIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
+            throw new CloudRuntimeException("This volume's Burst IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_IOPS_PER_VOLUME) + " IOPS.");
+        }
+
+        details.put(SolidFireUtil.MIN_IOPS, String.valueOf(lMinIops));
+        details.put(SolidFireUtil.MAX_IOPS, String.valueOf(lMaxIops));
+        details.put(SolidFireUtil.BURST_IOPS, String.valueOf(lBurstIops));
+
+        SolidFireUtil.SolidFireConnection sfConnection = new SolidFireUtil.SolidFireConnection(managementVip, managementPort, clusterAdminUsername, clusterAdminPassword);
+
+        SolidFireCreateVolume sfCreateVolume = createSolidFireVolume(sfConnection, storagePoolName, capacityBytes, lMinIops, lMaxIops, lBurstIops);
+
+        SolidFireUtil.SolidFireVolume sfVolume = sfCreateVolume.getVolume();
+
+        String iqn = sfVolume.getIqn();
+
+        details.put(SolidFireUtil.VOLUME_ID, String.valueOf(sfVolume.getId()));
+
+        parameters.setUuid(iqn);
+
+        if (HypervisorType.VMware.equals(hypervisorType)) {
+            String datastore = iqn.replace("/", "_");
+            String path = "/" + datacenter + "/" + datastore;
+
+            parameters.setHost("VMFS datastore: " + path);
+            parameters.setPort(0);
+            parameters.setPath(path);
+
+            details.put(SolidFireUtil.DATASTORE_NAME, datastore);
+            details.put(SolidFireUtil.IQN, iqn);
+            details.put(SolidFireUtil.STORAGE_VIP, storageVip);
+            details.put(SolidFireUtil.STORAGE_PORT, String.valueOf(storagePort));
+        }
+        else {
+            parameters.setHost(storageVip);
+            parameters.setPort(storagePort);
+            parameters.setPath(iqn);
+        }
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+        if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
+
+            LOGGER.debug(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        DataStore dataStore = null;
+
+        try {
+            // this adds a row in the cloud.storage_pool table for this SolidFire volume
+            dataStore = primaryDataStoreHelper.createPrimaryDataStore(parameters);
+
+            // now that we have a DataStore (we need the id from the DataStore instance), we can create a Volume Access Group, if need be, and
+            // place the newly created volume in the Volume Access Group
+            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
+
+            SolidFireUtil.placeVolumeInVolumeAccessGroups(sfConnection, sfVolume.getId(), hosts);
+
+            SolidFireUtil.SolidFireAccount sfAccount = sfCreateVolume.getAccount();
+            Account csAccount = CallContext.current().getCallingAccount();
+
+            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccount.getId(), sfAccount, dataStore.getId(), accountDetailsDao);
+        } catch (Exception ex) {
+            if (dataStore != null) {
+                primaryDataStoreDao.expunge(dataStore.getId());
+            }
+
+            throw new CloudRuntimeException(ex.getMessage());
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+
+        return dataStore;
+    }
+
+    private HypervisorType getHypervisorTypeForCluster(long clusterId) {
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        if (cluster == null) {
+            throw new CloudRuntimeException("Cluster ID '" + clusterId + "' was not found in the database.");
+        }
+
+        return cluster.getHypervisorType();
+    }
+
+    private StoragePoolType getStorageType(HypervisorType hypervisorType) {
+        if (HypervisorType.XenServer.equals(hypervisorType)) {
+            return StoragePoolType.IscsiLUN;
+        }
+
+        if (HypervisorType.VMware.equals(hypervisorType)) {
+            return StoragePoolType.VMFS;
+        }
+
+        throw new CloudRuntimeException("The 'hypervisor' parameter must be '" + HypervisorType.XenServer + "' or '" + HypervisorType.VMware + "'.");
+    }
+
+    private class SolidFireCreateVolume {
+        private final SolidFireUtil.SolidFireVolume _sfVolume;
+        private final SolidFireUtil.SolidFireAccount _sfAccount;
+
+        SolidFireCreateVolume(SolidFireUtil.SolidFireVolume sfVolume, SolidFireUtil.SolidFireAccount sfAccount) {
+            _sfVolume = sfVolume;
+            _sfAccount = sfAccount;
+        }
+
+        public SolidFireUtil.SolidFireVolume getVolume() {
+            return _sfVolume;
+        }
+
+        public SolidFireUtil.SolidFireAccount getAccount() {
+            return _sfAccount;
+        }
+    }
+
+    private SolidFireCreateVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection,
+            String volumeName, long volumeSize, long minIops, long maxIops, long burstIops) {
+        try {
+            Account csAccount = CallContext.current().getCallingAccount();
+            long csAccountId = csAccount.getId();
+            AccountVO accountVo = accountDao.findById(csAccountId);
+
+            String sfAccountName = SolidFireUtil.getSolidFireAccountName(accountVo.getUuid(), csAccountId);
+
+            SolidFireUtil.SolidFireAccount sfAccount = SolidFireUtil.getAccount(sfConnection, sfAccountName);
+
+            if (sfAccount == null) {
+                long sfAccountNumber = SolidFireUtil.createAccount(sfConnection, sfAccountName);
+
+                sfAccount = SolidFireUtil.getAccountById(sfConnection, sfAccountNumber);
+            }
+
+            long sfVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeName), sfAccount.getId(), volumeSize,
+                    true, null, minIops, maxIops, burstIops);
+            SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
+
+            return new SolidFireCreateVolume(sfVolume, sfAccount);
+        } catch (Throwable e) {
+            throw new CloudRuntimeException("Failed to create a SolidFire volume: " + e.toString());
+        }
+    }
+
+    @Override
+    public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
+        return true;
+    }
+
+    @Override
+    public boolean attachCluster(DataStore store, ClusterScope scope) {
+        PrimaryDataStoreInfo primaryDataStoreInfo = (PrimaryDataStoreInfo)store;
+
+        // check if there is at least one host up in this cluster
+        List<HostVO> allHosts = resourceMgr.listAllUpHosts(Host.Type.Routing, primaryDataStoreInfo.getClusterId(),
+                primaryDataStoreInfo.getPodId(), primaryDataStoreInfo.getDataCenterId());
+
+        if (allHosts.isEmpty()) {
+            primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
+
+            throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + primaryDataStoreInfo.getClusterId());
+        }
+
+        boolean success = false;
+
+        for (HostVO host : allHosts) {
+            success = createStoragePool(host, primaryDataStoreInfo);
+
+            if (success) {
+                break;
+            }
+        }
+
+        if (!success) {
+            throw new CloudRuntimeException("Unable to create storage in cluster " + primaryDataStoreInfo.getClusterId());
+        }
+
+        List<HostVO> poolHosts = new ArrayList<>();
+
+        for (HostVO host : allHosts) {
+            try {
+                storageMgr.connectHostToSharedPool(host.getId(), primaryDataStoreInfo.getId());
+
+                poolHosts.add(host);
+            } catch (Exception e) {
+                LOGGER.warn("Unable to establish a connection between " + host + " and " + primaryDataStoreInfo, e);
+            }
+        }
+
+        if (poolHosts.isEmpty()) {
+            LOGGER.warn("No host can access storage pool '" + primaryDataStoreInfo + "' on cluster '" + primaryDataStoreInfo.getClusterId() + "'.");
+
+            primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
+
+            throw new CloudRuntimeException("Failed to access storage pool");
+        }
+
+        primaryDataStoreHelper.attachCluster(store);
+
+        return true;
+    }
+
+    private boolean createStoragePool(HostVO host, StoragePool storagePool) {
+        long hostId = host.getId();
+        HypervisorType hypervisorType = host.getHypervisorType();
+        CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, storagePool);
+
+        if (HypervisorType.VMware.equals(hypervisorType)) {
+            cmd.setCreateDatastore(true);
+
+            Map<String, String> details = new HashMap<>();
+
+            StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
+
+            details.put(CreateStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
+
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
+
+            details.put(CreateStoragePoolCommand.IQN, storagePoolDetail.getValue());
+
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
+
+            details.put(CreateStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
+
+            storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
+
+            details.put(CreateStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
+
+            cmd.setDetails(details);
+        }
+
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer != null && answer.getResult()) {
+            return true;
+        } else {
+            primaryDataStoreDao.expunge(storagePool.getId());
+
+            final String msg;
+
+            if (answer != null) {
+                msg = "Cannot create storage pool through host '" + hostId + "' due to the following: " + answer.getDetails();
+            } else {
+                msg = "Cannot create storage pool through host '" + hostId + "' due to CreateStoragePoolCommand returns null";
+            }
+
+            LOGGER.warn(msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    @Override
+    public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
+        return true;
+    }
+
+    @Override
+    public boolean maintain(DataStore dataStore) {
+        storagePoolAutomation.maintain(dataStore);
+        primaryDataStoreHelper.maintain(dataStore);
+
+        return true;
+    }
+
+    @Override
+    public boolean cancelMaintain(DataStore store) {
+        primaryDataStoreHelper.cancelMaintain(store);
+        storagePoolAutomation.cancelMaintain(store);
+
+        return true;
+    }
+
+    // invoked to delete primary storage that is based on the SolidFire plug-in
+    @Override
+    public boolean deleteDataStore(DataStore dataStore) {
+        List<StoragePoolHostVO> hostPoolRecords = storagePoolHostDao.listByPoolId(dataStore.getId());
+
+        HypervisorType hypervisorType = null;
+
+        if (hostPoolRecords.size() > 0 ) {
+            hypervisorType = getHypervisorType(hostPoolRecords.get(0).getHostId());
+        }
+
+        if (!isSupportedHypervisorType(hypervisorType)) {
+            throw new CloudRuntimeException(hypervisorType + " is not a supported hypervisor type.");
+        }
+
+        StoragePool storagePool = (StoragePool)dataStore;
+        StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId());
+        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = tmpltMgr.getUnusedTemplatesInPool(storagePoolVO);
+
+        for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
+            tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
+        }
+
+        Long clusterId = null;
+        Long hostId = null;
+
+        for (StoragePoolHostVO host : hostPoolRecords) {
+            DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(storagePool);
+
+            if (HypervisorType.VMware.equals(hypervisorType)) {
+                deleteCmd.setRemoveDatastore(true);
+
+                Map<String, String> details = new HashMap<>();
+
+                StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
+
+                details.put(DeleteStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
+
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
+
+                details.put(DeleteStoragePoolCommand.IQN, storagePoolDetail.getValue());
+
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
+
+                details.put(DeleteStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
+
+                storagePoolDetail = storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
+
+                details.put(DeleteStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
+
+                deleteCmd.setDetails(details);
+            }
+
+            final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd);
+
+            if (answer != null && answer.getResult()) {
+                LOGGER.info("Successfully deleted storage pool using Host ID " + host.getHostId());
+
+                HostVO hostVO = hostDao.findById(host.getHostId());
+
+                if (hostVO != null) {
+                    clusterId = hostVO.getClusterId();
+                    hostId = hostVO.getId();
+                }
+
+                break;
+            }
+            else {
+                if (answer != null) {
+                    LOGGER.error("Failed to delete storage pool using Host ID " + host.getHostId() + ": " + answer.getResult());
+                }
+                else {
+                    LOGGER.error("Failed to delete storage pool using Host ID " + host.getHostId());
+                }
+            }
+        }
+
+        if (clusterId != null) {
+            ClusterVO cluster = clusterDao.findById(clusterId);
+
+            GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+            if (!lock.lock(SolidFireUtil.LOCK_TIME_IN_SECONDS)) {
+                String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
+
+                LOGGER.debug(errMsg);
+
+                throw new CloudRuntimeException(errMsg);
+            }
+
+            try {
+                long sfVolumeId = getVolumeId(storagePool.getId());
+
+                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+                for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                    if (SolidFireUtil.sfVagContains(sfVag, sfVolumeId, clusterId, hostDao)) {
+                        SolidFireUtil.removeVolumeIdsFromSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                    }
+                }
+            }
+            finally {
+                lock.unlock();
+                lock.releaseRef();
+            }
+        }
+
+        if (hostId != null) {
+            handleTargetsForVMware(hostId, storagePool.getId());
+        }
+
+        deleteSolidFireVolume(storagePool.getId());
+
+        return primaryDataStoreHelper.deletePrimaryDataStore(dataStore);
+    }
+
+    private void handleTargetsForVMware(long hostId, long storagePoolId) {
+        HostVO host = hostDao.findById(hostId);
+
+        if (host.getHypervisorType() == HypervisorType.VMware) {
+            String storageAddress = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP).getValue();
+            int storagePort = Integer.parseInt(storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT).getValue());
+            String iqn = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN).getValue();
+
+            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+            List<Map<String, String>> targets = new ArrayList<>();
+
+            Map<String, String> target = new HashMap<>();
+
+            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
+            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
+            target.put(ModifyTargetsCommand.IQN, iqn);
+
+            targets.add(target);
+
+            cmd.setTargets(targets);
+            cmd.setApplyToAllHostsInCluster(true);
+            cmd.setAdd(false);
+            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+            cmd.setRemoveAsync(true);
+
+            sendModifyTargetsCommand(cmd, hostId);
+        }
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            String msg = "Unable to get an answer to the modify targets command";
+
+            LOGGER.warn(msg);
+        }
+        else if (!answer.getResult()) {
+            String msg = "Unable to modify target on the following host: " + hostId;
+
+            LOGGER.warn(msg);
+        }
+    }
+
+    private void deleteSolidFireVolume(long storagePoolId) {
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
+
+        long sfVolumeId = getVolumeId(storagePoolId);
+
+        SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
+    }
+
+    private long getVolumeId(long storagePoolId) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.VOLUME_ID);
+
+        String volumeId = storagePoolDetail.getValue();
+
+        return Long.parseLong(volumeId);
+    }
+
+    private long getIopsValue(long storagePoolId, String iopsKey) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, iopsKey);
+
+        String iops = storagePoolDetail.getValue();
+
+        return Long.parseLong(iops);
+    }
+
+    private static boolean isSupportedHypervisorType(HypervisorType hypervisorType) {
+        return HypervisorType.XenServer.equals(hypervisorType) || HypervisorType.VMware.equals(hypervisorType);
+    }
+
+    private HypervisorType getHypervisorType(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        if (host != null) {
+            return host.getHypervisorType();
+        }
+
+        return HypervisorType.None;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle#migrateToObjectStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)
+     */
+    @Override
+    public boolean migrateToObjectStore(DataStore store) {
+        return false;
+    }
+
+    @Override
+    public void updateStoragePool(StoragePool storagePool, Map<String, String> details) {
+        String strCapacityBytes = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES);
+        String strCapacityIops = details.get(PrimaryDataStoreLifeCycle.CAPACITY_IOPS);
+
+        Long capacityBytes = strCapacityBytes != null ? Long.parseLong(strCapacityBytes) : null;
+        Long capacityIops = strCapacityIops != null ? Long.parseLong(strCapacityIops) : null;
+
+        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+        long size = capacityBytes != null ? capacityBytes : storagePool.getCapacityBytes();
+
+        long currentMinIops = getIopsValue(storagePool.getId(), SolidFireUtil.MIN_IOPS);
+        long currentMaxIops = getIopsValue(storagePool.getId(), SolidFireUtil.MAX_IOPS);
+        long currentBurstIops = getIopsValue(storagePool.getId(), SolidFireUtil.BURST_IOPS);
+
+        long minIops = currentMinIops;
+        long maxIops = currentMaxIops;
+        long burstIops = currentBurstIops;
+
+        if (capacityIops != null) {
+            if (capacityIops > SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) {
+                throw new CloudRuntimeException("This volume cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) + " IOPS.");
+            }
+
+            float maxPercentOfMin = currentMaxIops / (float)currentMinIops;
+            float burstPercentOfMax = currentBurstIops / (float)currentMaxIops;
+
+            minIops = capacityIops;
+            maxIops = (long)(minIops * maxPercentOfMin);
+            burstIops = (long)(maxIops * burstPercentOfMax);
+
+            if (maxIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
+                maxIops = SolidFireUtil.MAX_IOPS_PER_VOLUME;
+            }
+
+            if (burstIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
+                burstIops = SolidFireUtil.MAX_IOPS_PER_VOLUME;
+            }
+        }
+
+        SolidFireUtil.modifyVolume(sfConnection, getVolumeId(storagePool.getId()), size, null, minIops, maxIops, burstIops);
+
+        SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), primaryDataStoreDao, storagePoolDetailsDao, minIops, maxIops, burstIops);
+    }
+
+    @Override
+    public void enableStoragePool(DataStore dataStore) {
+        primaryDataStoreHelper.enable(dataStore);
+    }
+
+    @Override
+    public void disableStoragePool(DataStore dataStore) {
+        primaryDataStoreHelper.disable(dataStore);
+    }
+}
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
new file mode 100644
index 0000000..4fffb70
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.provider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class SolidFireHostListener implements HypervisorHostListener {
+    private static final Logger LOGGER = Logger.getLogger(SolidFireHostListener.class);
+
+    @Inject private AgentManager agentMgr;
+    @Inject private AlertManager alertMgr;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataStoreManager dataStoreMgr;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject private StoragePoolHostDao storagePoolHostDao;
+    @Inject private VMInstanceDao vmDao;
+    @Inject private VolumeDao volumeDao;
+
+    @Override
+    public boolean hostAdded(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        if (host == null) {
+            LOGGER.error("Failed to add host by SolidFireHostListener as host was not found with id = " + hostId);
+
+            return false;
+        }
+
+        SolidFireUtil.hostAddedToCluster(hostId, host.getClusterId(), SolidFireUtil.PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
+
+        handleVMware(host, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostConnect(long hostId, long storagePoolId) {
+        HostVO host = hostDao.findById(hostId);
+
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost == null) {
+            storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, "");
+
+            storagePoolHostDao.persist(storagePoolHost);
+        }
+
+        if (host.getHypervisorType().equals(HypervisorType.XenServer)) {
+            handleXenServer(host.getClusterId(), host.getId(), storagePoolId);
+        }
+        else if (host.getHypervisorType().equals(HypervisorType.KVM)) {
+            handleKVM(hostId, storagePoolId);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean hostDisconnected(long hostId, long storagePoolId) {
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost != null) {
+            storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean hostAboutToBeRemoved(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        SolidFireUtil.hostRemovedFromCluster(hostId, host.getClusterId(), SolidFireUtil.PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
+
+        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostRemoved(long hostId, long clusterId) {
+        return true;
+    }
+
+    private void handleXenServer(long clusterId, long hostId, long storagePoolId) {
+        List<String> storagePaths = getStoragePaths(clusterId, storagePoolId);
+
+        StoragePool storagePool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        for (String storagePath : storagePaths) {
+            ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
+
+            cmd.setStoragePath(storagePath);
+
+            sendModifyStoragePoolCommand(cmd, storagePool, hostId);
+        }
+    }
+
+    private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
+        if (host != null && HypervisorType.VMware.equals(host.getHypervisorType())) {
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(SolidFireUtil.PROVIDER_NAME);
+
+            if (storagePools != null && storagePools.size() > 0) {
+                List<Map<String, String>> targets = new ArrayList<>();
+
+                for (StoragePoolVO storagePool : storagePools) {
+                    List<Map<String, String>> targetsForClusterAndStoragePool = getTargets(host.getClusterId(), storagePool.getId());
+
+                    targets.addAll(targetsForClusterAndStoragePool);
+                }
+
+                ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+                cmd.setTargets(targets);
+                cmd.setAdd(add);
+                cmd.setTargetTypeToRemove(targetTypeToRemove);
+                cmd.setRemoveAsync(true);
+
+                sendModifyTargetsCommand(cmd, host.getId());
+            }
+        }
+    }
+
+    private void handleKVM(long hostId, long storagePoolId) {
+        StoragePool storagePool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
+
+        sendModifyStoragePoolCommand(cmd, storagePool, hostId);
+    }
+
+    private List<String> getStoragePaths(long clusterId, long storagePoolId) {
+        List<String> storagePaths = new ArrayList<>();
+
+        // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
+        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePoolId, null);
+
+        if (volumes != null) {
+            for (VolumeVO volume : volumes) {
+                Long instanceId = volume.getInstanceId();
+
+                if (instanceId != null) {
+                    VMInstanceVO vmInstance = vmDao.findById(instanceId);
+
+                    Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
+
+                    if (hostIdForVm != null) {
+                        HostVO hostForVm = hostDao.findById(hostIdForVm);
+
+                        if (hostForVm != null && hostForVm.getClusterId().equals(clusterId)) {
+                            storagePaths.add(volume.get_iScsiName());
+                        }
+                    }
+                }
+            }
+        }
+
+        return storagePaths;
+    }
+
+    private List<Map<String, String>> getTargets(long clusterId, long storagePoolId) {
+        List<Map<String, String>> targets = new ArrayList<>();
+
+        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
+
+        // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
+        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePoolId, null);
+
+        if (volumes != null) {
+            for (VolumeVO volume : volumes) {
+                Long instanceId = volume.getInstanceId();
+
+                if (instanceId != null) {
+                    VMInstanceVO vmInstance = vmDao.findById(instanceId);
+
+                    Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
+
+                    if (hostIdForVm != null) {
+                        HostVO hostForVm = hostDao.findById(hostIdForVm);
+
+                        if (hostForVm.getClusterId().equals(clusterId)) {
+                            Map<String, String> details = new HashMap<>();
+
+                            details.put(ModifyTargetsCommand.IQN, volume.get_iScsiName());
+                            details.put(ModifyTargetsCommand.STORAGE_HOST, storagePool.getHostAddress());
+                            details.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
+
+                            targets.add(details);
+                        }
+                    }
+                }
+            }
+        }
+
+        return targets;
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
+        }
+
+        if (!answer.getResult()) {
+            String msg = "Unable to modify targets on the following host: " + hostId;
+
+            HostVO host = hostDao.findById(hostId);
+
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    private void sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StoragePool storagePool, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command (" + storagePool.getId() + ")");
+        }
+
+        if (!answer.getResult()) {
+            String msg = "Unable to attach storage pool " + storagePool.getId() + " to host " + hostId;
+
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
+
+            throw new CloudRuntimeException("Unable to establish a connection from agent to storage pool " + storagePool.getId() + " due to " + answer.getDetails() +
+                " (" + storagePool.getId() + ")");
+        }
+
+        assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer expected ; Pool = " + storagePool.getId() + " Host = " + hostId;
+
+        LOGGER.info("Connection established between storage pool " + storagePool + " and host + " + hostId);
+    }
+}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFirePrimaryDataStoreProvider.java
similarity index 100%
rename from plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFirePrimaryDataStoreProvider.java
rename to plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFirePrimaryDataStoreProvider.java
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
new file mode 100644
index 0000000..575a302
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.datastore.provider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class SolidFireSharedHostListener implements HypervisorHostListener {
+    private static final Logger LOGGER = Logger.getLogger(SolidFireSharedHostListener.class);
+
+    @Inject private AgentManager agentMgr;
+    @Inject private AlertManager alertMgr;
+    @Inject private ClusterDao clusterDao;
+    @Inject private DataStoreManager dataStoreMgr;
+    @Inject private HostDao hostDao;
+    @Inject private PrimaryDataStoreDao storagePoolDao;
+    @Inject private StoragePoolHostDao storagePoolHostDao;
+    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
+
+    @Override
+    public boolean hostAdded(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        if (host == null) {
+            LOGGER.error("Failed to add host by SolidFireSharedHostListener as host was not found with id = " + hostId);
+
+            return false;
+        }
+
+        SolidFireUtil.hostAddedToCluster(hostId, host.getClusterId(), SolidFireUtil.SHARED_PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
+
+        handleVMware(host, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostConnect(long hostId, long storagePoolId) {
+        StoragePool storagePool = (StoragePool) dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
+
+        ModifyStoragePoolAnswer answer = sendModifyStoragePoolCommand(cmd, storagePool, hostId);
+
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost != null) {
+            storagePoolHost.setLocalPath(answer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
+        } else {
+            storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, answer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
+
+            storagePoolHostDao.persist(storagePoolHost);
+        }
+
+        StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId);
+
+        storagePoolVO.setCapacityBytes(answer.getPoolInfo().getCapacityBytes());
+        storagePoolVO.setUsedBytes(answer.getPoolInfo().getCapacityBytes() - answer.getPoolInfo().getAvailableBytes());
+
+        storagePoolDao.update(storagePoolId, storagePoolVO);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostDisconnected(long hostId, long storagePoolId) {
+        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
+
+        if (storagePoolHost != null) {
+            storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean hostAboutToBeRemoved(long hostId) {
+        HostVO host = hostDao.findById(hostId);
+
+        SolidFireUtil.hostRemovedFromCluster(hostId, host.getClusterId(), SolidFireUtil.SHARED_PROVIDER_NAME,
+                clusterDao, hostDao, storagePoolDao, storagePoolDetailsDao);
+
+        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
+
+        return true;
+    }
+
+    @Override
+    public boolean hostRemoved(long hostId, long clusterId) {
+        return true;
+    }
+
+    private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
+        if (HypervisorType.VMware.equals(host.getHypervisorType())) {
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(SolidFireUtil.SHARED_PROVIDER_NAME);
+
+            if (storagePools != null && storagePools.size() > 0) {
+                List<Map<String, String>> targets = new ArrayList<>();
+
+                for (StoragePoolVO storagePool : storagePools) {
+                    if (storagePool.getClusterId().equals(host.getClusterId())) {
+                        long storagePoolId = storagePool.getId();
+
+                        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN);
+
+                        String iqn = storagePoolDetail.getValue();
+
+                        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP);
+
+                        String sVip = storagePoolDetail.getValue();
+
+                        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT);
+
+                        String sPort = storagePoolDetail.getValue();
+
+                        Map<String, String> details = new HashMap<>();
+
+                        details.put(ModifyTargetsCommand.IQN, iqn);
+                        details.put(ModifyTargetsCommand.STORAGE_HOST, sVip);
+                        details.put(ModifyTargetsCommand.STORAGE_PORT, sPort);
+
+                        targets.add(details);
+                    }
+                }
+
+                if (targets.size() > 0) {
+                    ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+                    cmd.setTargets(targets);
+                    cmd.setAdd(add);
+                    cmd.setTargetTypeToRemove(targetTypeToRemove);
+                    cmd.setRemoveAsync(true);
+
+                    sendModifyTargetsCommand(cmd, host.getId());
+                }
+            }
+        }
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
+        }
+
+        if (!answer.getResult()) {
+            String msg = "Unable to modify targets on the following host: " + hostId;
+
+            HostVO host = hostDao.findById(hostId);
+
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    private ModifyStoragePoolAnswer sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StoragePool storagePool, long hostId) {
+        Answer answer = agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command for storage pool: " + storagePool.getId());
+        }
+
+        if (!answer.getResult()) {
+            String msg = "Unable to attach storage pool " + storagePool.getId() + " to the host " + hostId;
+
+            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
+
+            throw new CloudRuntimeException(msg);
+        }
+
+        assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer not returned from ModifyStoragePoolCommand; Storage pool = " +
+            storagePool.getId() + "; Host = " + hostId;
+
+        LOGGER.info("Connection established between storage pool " + storagePool + " and host " + hostId);
+
+        return (ModifyStoragePoolAnswer)answer;
+    }
+}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedPrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedPrimaryDataStoreProvider.java
similarity index 100%
rename from plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedPrimaryDataStoreProvider.java
rename to plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedPrimaryDataStoreProvider.java
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
new file mode 100644
index 0000000..9f7b205
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
@@ -0,0 +1,1363 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.datastore.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.user.AccountDetailVO;
+import com.cloud.user.AccountDetailsDao;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Longs;
+
+import com.solidfire.client.ElementFactory;
+import com.solidfire.element.api.Account;
+import com.solidfire.element.api.AddAccountRequest;
+import com.solidfire.element.api.AddInitiatorsToVolumeAccessGroupRequest;
+import com.solidfire.element.api.AddVolumesToVolumeAccessGroupRequest;
+import com.solidfire.element.api.CloneVolumeRequest;
+import com.solidfire.element.api.CloneVolumeResult;
+import com.solidfire.element.api.CreateSnapshotRequest;
+import com.solidfire.element.api.CreateVolumeAccessGroupRequest;
+import com.solidfire.element.api.CreateVolumeRequest;
+import com.solidfire.element.api.DeleteSnapshotRequest;
+import com.solidfire.element.api.DeleteVolumeRequest;
+import com.solidfire.element.api.GetAccountByIDRequest;
+import com.solidfire.element.api.GetAccountByNameRequest;
+import com.solidfire.element.api.GetAsyncResultRequest;
+import com.solidfire.element.api.ListSnapshotsRequest;
+import com.solidfire.element.api.ListVolumeAccessGroupsRequest;
+import com.solidfire.element.api.ListVolumesRequest;
+import com.solidfire.element.api.ModifyVolumeRequest;
+import com.solidfire.element.api.QoS;
+import com.solidfire.element.api.RemoveInitiatorsFromVolumeAccessGroupRequest;
+import com.solidfire.element.api.RemoveVolumesFromVolumeAccessGroupRequest;
+import com.solidfire.element.api.RollbackToSnapshotRequest;
+import com.solidfire.element.api.Snapshot;
+import com.solidfire.element.api.SolidFireElement;
+import com.solidfire.element.api.Volume;
+import com.solidfire.element.api.VolumeAccessGroup;
+import com.solidfire.jsvcgen.javautil.Optional;
+
+import static org.apache.commons.lang.ArrayUtils.toPrimitive;
+
+public class SolidFireUtil {
+    private static final Logger LOGGER = Logger.getLogger(SolidFireUtil.class);
+
+    public static final String PROVIDER_NAME = "SolidFire";
+    public static final String SHARED_PROVIDER_NAME = "SolidFireShared";
+
+    private static final Random RANDOM = new Random(System.nanoTime());
+    public static final int LOCK_TIME_IN_SECONDS = 300;
+
+    public static final String LOG_PREFIX = "SolidFire: ";
+
+    public static final String MANAGEMENT_VIP = "mVip";
+    public static final String STORAGE_VIP = "sVip";
+
+    public static final String MANAGEMENT_PORT = "mPort";
+    public static final String STORAGE_PORT = "sPort";
+
+    public static final String CLUSTER_ADMIN_USERNAME = "clusterAdminUsername";
+    public static final String CLUSTER_ADMIN_PASSWORD = "clusterAdminPassword";
+
+    // these three variables should only be used for the SolidFire plug-in with the name SolidFireUtil.PROVIDER_NAME
+    public static final String CLUSTER_DEFAULT_MIN_IOPS = "clusterDefaultMinIops";
+    public static final String CLUSTER_DEFAULT_MAX_IOPS = "clusterDefaultMaxIops";
+    public static final String CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS = "clusterDefaultBurstIopsPercentOfMaxIops";
+
+    // these three variables should only be used for the SolidFire plug-in with the name SolidFireUtil.SHARED_PROVIDER_NAME
+    public static final String MIN_IOPS = "minIops";
+    public static final String MAX_IOPS = "maxIops";
+    public static final String BURST_IOPS = "burstIops";
+
+    private static final String ACCOUNT_ID = "accountId";
+
+    public static final String VOLUME_ID = "volumeId";
+    public static final String TEMP_VOLUME_ID = "tempVolumeId";
+    public static final String SNAPSHOT_ID = "snapshotId";
+
+    public static final String CloudStackVolumeId = "CloudStackVolumeId";
+    public static final String CloudStackVolumeSize = "CloudStackVolumeSize";
+    public static final String CloudStackSnapshotId = "CloudStackSnapshotId";
+    public static final String CloudStackSnapshotSize = "CloudStackSnapshotSize";
+    public static final String CloudStackTemplateId = "CloudStackTemplateId";
+    public static final String CloudStackTemplateSize = "CloudStackTemplateSize";
+
+    public static final String ORIG_CS_VOLUME_ID = "originalCloudStackVolumeId";
+
+    public static final String VOLUME_SIZE = "sfVolumeSize";
+
+    public static final String STORAGE_POOL_ID = "sfStoragePoolId";
+
+    public static final String DATACENTER = "datacenter";
+
+    public static final String DATASTORE_NAME = "datastoreName";
+    public static final String IQN = "iqn";
+
+    private static final String SF_CS_ACCOUNT_PREFIX = "CloudStack_";
+
+    public static final long MIN_VOLUME_SIZE = 1000000000;
+
+    public static final long MIN_IOPS_PER_VOLUME = 100;
+    public static final long MAX_MIN_IOPS_PER_VOLUME = 15000;
+    public static final long MAX_IOPS_PER_VOLUME = 100000;
+
+    private static final int DEFAULT_MANAGEMENT_PORT = 443;
+    private static final int DEFAULT_STORAGE_PORT = 3260;
+
+    private static final int MAX_NUM_VAGS_PER_VOLUME = 4;
+    private static final int MAX_NUM_INITIATORS_PER_VAG = 64;
+
+    public static class SolidFireConnection {
+        private final String _managementVip;
+        private final int _managementPort;
+        private final String _clusterAdminUsername;
+        private final String _clusterAdminPassword;
+
+        public SolidFireConnection(String managementVip, int managementPort, String clusterAdminUsername, String clusterAdminPassword) {
+            if (managementVip == null) {
+                throw new CloudRuntimeException("The management VIP cannot be 'null'.");
+            }
+
+            if (managementPort <= 0) {
+                throw new CloudRuntimeException("The management port must be a positive integer.");
+            }
+
+            if (clusterAdminUsername == null) {
+                throw new CloudRuntimeException("The cluster admin username cannot be 'null'.");
+            }
+
+            if (clusterAdminPassword == null) {
+                throw new CloudRuntimeException("The cluster admin password cannot be 'null'.");
+            }
+
+            _managementVip = managementVip;
+            _managementPort = managementPort;
+            _clusterAdminUsername = clusterAdminUsername;
+            _clusterAdminPassword = clusterAdminPassword;
+        }
+
+        String getManagementVip() {
+            return _managementVip;
+        }
+
+        int getManagementPort() {
+            return _managementPort;
+        }
+
+        String getClusterAdminUsername() {
+            return _clusterAdminUsername;
+        }
+
+        private String getClusterAdminPassword() {
+            return _clusterAdminPassword;
+        }
+
+        @Override
+        public int hashCode() {
+            return _managementVip.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof SolidFireConnection)) {
+                return false;
+            }
+
+            SolidFireConnection sfConnection = (SolidFireConnection)obj;
+
+            return _managementVip.equals(sfConnection.getManagementVip());
+        }
+    }
+
+    public static SolidFireConnection getSolidFireConnection(long storagePoolId, StoragePoolDetailsDao storagePoolDetailsDao) {
+        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_VIP);
+
+        String mVip = storagePoolDetail.getValue();
+
+        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_PORT);
+
+        int mPort = Integer.parseInt(storagePoolDetail.getValue());
+
+        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_USERNAME);
+
+        String clusterAdminUsername = storagePoolDetail.getValue();
+
+        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_PASSWORD);
+
+        String clusterAdminPassword = storagePoolDetail.getValue();
+
+        return new SolidFireConnection(mVip, mPort, clusterAdminUsername, clusterAdminPassword);
+    }
+
+    private static SolidFireElement getSolidFireElement(SolidFireConnection sfConnection) {
+        return ElementFactory.create(sfConnection.getManagementVip(), sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword());
+    }
+
+    // used to parse the "url" parameter when creating primary storage that's based on the SolidFire plug-in with the
+    // name SolidFireUtil.PROVIDER_NAME (as opposed to the SolidFire plug-in with the name SolidFireUtil.SHARED_PROVIDER_NAME)
+    // return a String instance that contains at most the MVIP and SVIP info
+    public static String getModifiedUrl(String originalUrl) {
+        StringBuilder sb = new StringBuilder();
+
+        String delimiter = ";";
+
+        StringTokenizer st = new StringTokenizer(originalUrl, delimiter);
+
+        while (st.hasMoreElements()) {
+            String token = st.nextElement().toString().toUpperCase();
+
+            if (token.startsWith(SolidFireUtil.MANAGEMENT_VIP.toUpperCase()) || token.startsWith(SolidFireUtil.STORAGE_VIP.toUpperCase())) {
+                sb.append(token).append(delimiter);
+            }
+        }
+
+        String modifiedUrl = sb.toString();
+        int lastIndexOf = modifiedUrl.lastIndexOf(delimiter);
+
+        if (lastIndexOf == (modifiedUrl.length() - delimiter.length())) {
+            return modifiedUrl.substring(0, lastIndexOf);
+        }
+
+        return modifiedUrl;
+    }
+
+    public static String getManagementVip(String url) {
+        return getVip(SolidFireUtil.MANAGEMENT_VIP, url);
+    }
+
+    public static String getStorageVip(String url) {
+        return getVip(SolidFireUtil.STORAGE_VIP, url);
+    }
+
+    public static int getManagementPort(String url) {
+        return getPort(SolidFireUtil.MANAGEMENT_VIP, url, DEFAULT_MANAGEMENT_PORT);
+    }
+
+    public static int getStoragePort(String url) {
+        return getPort(SolidFireUtil.STORAGE_VIP, url, DEFAULT_STORAGE_PORT);
+    }
+
+    public static String getValue(String keyToMatch, String url) {
+        return getValue(keyToMatch, url, true);
+    }
+
+    public static String getValue(String keyToMatch, String url, boolean throwExceptionIfNotFound) {
+        String delimiter1 = ";";
+        String delimiter2 = "=";
+
+        StringTokenizer st = new StringTokenizer(url, delimiter1);
+
+        while (st.hasMoreElements()) {
+            String token = st.nextElement().toString();
+
+            int index = token.indexOf(delimiter2);
+
+            if (index == -1) {
+                throw new RuntimeException("Invalid URL format");
+            }
+
+            String key = token.substring(0, index);
+
+            if (key.equalsIgnoreCase(keyToMatch)) {
+                return token.substring(index + delimiter2.length());
+            }
+        }
+
+        if (throwExceptionIfNotFound) {
+            throw new RuntimeException("Key not found in URL");
+        }
+
+        return null;
+    }
+
+    public static String getSolidFireAccountName(String csAccountUuid, long csAccountId) {
+        return SF_CS_ACCOUNT_PREFIX + csAccountUuid + "_" + csAccountId;
+    }
+
+    public static void updateCsDbWithSolidFireIopsInfo(long storagePoolId, PrimaryDataStoreDao primaryDataStoreDao,
+                                                       StoragePoolDetailsDao storagePoolDetailsDao, long minIops, long maxIops, long burstIops) {
+        Map<String, String> existingDetails = storagePoolDetailsDao.listDetailsKeyPairs(storagePoolId);
+        Set<String> existingKeys = existingDetails.keySet();
+
+        Map<String, String> existingDetailsToKeep = new HashMap<>();
+
+        for (String existingKey : existingKeys) {
+            String existingValue = existingDetails.get(existingKey);
+
+            if (!SolidFireUtil.MIN_IOPS.equalsIgnoreCase(existingValue) &&
+                    !SolidFireUtil.MAX_IOPS.equalsIgnoreCase(existingValue) &&
+                    !SolidFireUtil.BURST_IOPS.equalsIgnoreCase(existingValue)) {
+                existingDetailsToKeep.put(existingKey, existingValue);
+            }
+        }
+
+        existingDetailsToKeep.put(SolidFireUtil.MIN_IOPS, String.valueOf(minIops));
+        existingDetailsToKeep.put(SolidFireUtil.MAX_IOPS, String.valueOf(maxIops));
+        existingDetailsToKeep.put(SolidFireUtil.BURST_IOPS, String.valueOf(burstIops));
+
+        primaryDataStoreDao.updateDetails(storagePoolId, existingDetailsToKeep);
+    }
+
+    public static void updateCsDbWithSolidFireAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount,
+                                                          long storagePoolId, AccountDetailsDao accountDetailsDao) {
+        AccountDetailVO accountDetail = new AccountDetailVO(csAccountId,
+                SolidFireUtil.getAccountKey(storagePoolId),
+                String.valueOf(sfAccount.getId()));
+
+        accountDetailsDao.persist(accountDetail);
+    }
+
+    public static SolidFireAccount getAccount(SolidFireConnection sfConnection, String sfAccountName) {
+        try {
+            return getAccountByName(sfConnection, sfAccountName);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    private static boolean isCloudStackOnlyVag(SolidFireConnection sfConnection, SolidFireVag sfVag) {
+        long[] volumeIds = sfVag.getVolumeIds();
+
+        if (ArrayUtils.isEmpty(volumeIds)) {
+            // We count this situation as being "CloudStack only" because the reason we call this method is to determine
+            // if we can remove a host from a VAG (we only want to allow the host to be removed from the VAG if there are
+            // no non-CloudStack volumes in it).
+            return true;
+        }
+
+        List<Long> knownSfAccountsForCs = new ArrayList<>();
+
+        for (long volumeId : volumeIds) {
+            SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+            long sfAccountId = sfVolume.getAccountId();
+
+            if (!knownSfAccountsForCs.contains(sfAccountId)) {
+                SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                    knownSfAccountsForCs.add(sfAccountId);
+                }
+                else {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private static boolean isStorageApplicableToZoneOrCluster(StoragePoolVO storagePoolVO, long clusterId, ClusterDao clusterDao) {
+        if (storagePoolVO.getClusterId() != null) {
+            if (storagePoolVO.getClusterId() == clusterId) {
+                return true;
+            }
+        }
+        else {
+            List<ClusterVO> clustersInZone = clusterDao.listByZoneId(storagePoolVO.getDataCenterId());
+
+            if (clustersInZone != null) {
+                for (ClusterVO clusterInZone : clustersInZone) {
+                    if (clusterInZone.getId() == clusterId) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public static void hostRemovedFromCluster(long hostId, long clusterId, String storageProvider, ClusterDao clusterDao, HostDao hostDao,
+                                              PrimaryDataStoreDao storagePoolDao, StoragePoolDetailsDao storagePoolDetailsDao) {
+        HostVO hostVO = hostDao.findByIdIncludingRemoved(hostId);
+
+        Preconditions.checkArgument(hostVO != null, "Could not locate host for ID: " + hostId);
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(storageProvider);
+
+            if (storagePools != null && storagePools.size() > 0) {
+                List<SolidFireUtil.SolidFireConnection> sfConnections = new ArrayList<>();
+
+                for (StoragePoolVO storagePool : storagePools) {
+                    if (!isStorageApplicableToZoneOrCluster(storagePool, clusterId, clusterDao)) {
+                        continue;
+                    }
+
+                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                    if (!sfConnections.contains(sfConnection)) {
+                        sfConnections.add(sfConnection);
+
+                        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+                        SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                        if (sfVag != null && isCloudStackOnlyVag(sfConnection, sfVag)) {
+                            removeInitiatorsFromSolidFireVag(sfConnection, sfVag.getId(), new String[] { hostVO.getStorageUrl() });
+                        }
+                    }
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+    }
+
+    public static void hostAddedToCluster(long hostId, long clusterId, String storageProvider, ClusterDao clusterDao, HostDao hostDao,
+                                          PrimaryDataStoreDao storagePoolDao, StoragePoolDetailsDao storagePoolDetailsDao) {
+        HostVO hostVO = hostDao.findById(hostId);
+
+        Preconditions.checkArgument(hostVO != null, "Could not locate host for ID: " + hostId);
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+
+        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
+
+        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
+            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        try {
+            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(storageProvider);
+
+            if (storagePools != null && storagePools.size() > 0) {
+                List<SolidFireUtil.SolidFireConnection> sfConnections = new ArrayList<>();
+
+                for (StoragePoolVO storagePool : storagePools) {
+                    if (!isStorageApplicableToZoneOrCluster(storagePool, clusterId, clusterDao)) {
+                        continue;
+                    }
+
+                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
+
+                    if (!sfConnections.contains(sfConnection)) {
+                        sfConnections.add(sfConnection);
+
+                        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+                        SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                        if (sfVag != null) {
+                            placeVolumeIdsInVag(sfConnection, sfVags, sfVag, hostVO, hostDao);
+                        } else {
+                            handleVagForHost(sfConnection, sfVags, hostVO, hostDao);
+                        }
+                    }
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+            lock.releaseRef();
+        }
+    }
+
+    // Put the host in an existing VAG or create a new one (only create a new one if all existing VAGs are full (i.e. 64 hosts max per VAG) and if
+    // creating a new VAG won't exceed 4 VAGs for the computer cluster).
+    // If none of the hosts in the cluster are in a VAG, then leave this host out of a VAG.
+    // Place applicable volume IDs in VAG, if need be (account of volume starts with SF_CS_ACCOUNT_PREFIX).
+    private static void handleVagForHost(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags, Host host, HostDao hostDao) {
+        List<HostVO> hostVOs = hostDao.findByClusterId(host.getClusterId());
+
+        if (hostVOs != null) {
+            int numVags = 0;
+
+            Collections.shuffle(hostVOs, RANDOM);
+
+            for (HostVO hostVO : hostVOs) {
+                if (hostVO.getId() != host.getId()) {
+                    SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                    if (sfVag != null) {
+                        numVags++;
+
+                        // A volume should be visible to all hosts that are in the same compute cluster. That being the case, you
+                        // can use MAX_NUM_VAGS_PER_VOLUME here. This is to limit the number of VAGs being used in a compute cluster
+                        // to MAX_NUM_VAGS_PER_VOLUME.
+                        if (numVags > MAX_NUM_VAGS_PER_VOLUME) {
+                            throw new CloudRuntimeException("Can support at most four volume access groups per compute cluster (>)");
+                        }
+
+                        if (sfVag.getInitiators().length < MAX_NUM_INITIATORS_PER_VAG) {
+                            if (!hostSupports_iScsi(host)) {
+                                String errMsg = "Host with ID " + host.getId() + " does not support iSCSI.";
+
+                                LOGGER.warn(errMsg);
+
+                                throw new CloudRuntimeException(errMsg);
+                            }
+
+                            addInitiatorsToSolidFireVag(sfConnection, sfVag.getId(), new String[] { host.getStorageUrl() });
+
+                            return;
+                        }
+                    }
+                }
+            }
+
+            if (numVags == MAX_NUM_VAGS_PER_VOLUME) {
+                throw new CloudRuntimeException("Can support at most four volume access groups per compute cluster (==)");
+            }
+
+            if (numVags > 0) {
+                if (!hostSupports_iScsi(host)) {
+                    String errMsg = "Host with ID " + host.getId() + " does not support iSCSI.";
+
+                    LOGGER.warn(errMsg);
+
+                    throw new CloudRuntimeException(errMsg);
+                }
+
+                SolidFireUtil.createVag(sfConnection, "CloudStack-" + UUID.randomUUID().toString(),
+                        new String[]{host.getStorageUrl()}, getVolumeIds(sfConnection, sfVags, host, hostDao));
+            }
+        }
+    }
+
+    /**
+     * Make use of the volume access group (VAG) of a random host in the cluster. With this VAG, collect all of its volume IDs that are for
+     * volumes that are in SolidFire accounts that are for CloudStack.
+     */
+    private static long[] getVolumeIds(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags,
+                                       Host host, HostDao hostDao) {
+        List<Long> volumeIdsToReturn = new ArrayList<>();
+
+        SolidFireVag sfVagForRandomHostInCluster = getVagForRandomHostInCluster(sfVags, host, hostDao);
+
+        if (sfVagForRandomHostInCluster != null) {
+            long[] volumeIds = sfVagForRandomHostInCluster.getVolumeIds();
+
+            if (volumeIds != null) {
+                List<Long> knownSfAccountsForCs = new ArrayList<>();
+                List<Long> knownSfAccountsNotForCs = new ArrayList<>();
+
+                for (long volumeId : volumeIds) {
+                    SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+                    long sfAccountId = sfVolume.getAccountId();
+
+                    if (knownSfAccountsForCs.contains(sfAccountId)) {
+                        volumeIdsToReturn.add(volumeId);
+                    }
+                    else if (!knownSfAccountsNotForCs.contains(sfAccountId)) {
+                        SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                        if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                            knownSfAccountsForCs.add(sfAccountId);
+
+                            volumeIdsToReturn.add(volumeId);
+                        }
+                        else {
+                            knownSfAccountsNotForCs.add(sfAccountId);
+                        }
+                    }
+                }
+            }
+        }
+
+        return volumeIdsToReturn.stream().mapToLong(l -> l).toArray();
+    }
+
+    private static void placeVolumeIdsInVag(SolidFireUtil.SolidFireConnection sfConnection, List<SolidFireUtil.SolidFireVag> sfVags,
+                                            SolidFireVag sfVag, Host host, HostDao hostDao) {
+        SolidFireVag sfVagForRandomHostInCluster = getVagForRandomHostInCluster(sfVags, host, hostDao);
+
+        if (sfVagForRandomHostInCluster != null) {
+            long[] volumeIds = sfVagForRandomHostInCluster.getVolumeIds();
+
+            if (volumeIds != null) {
+                List<Long> knownSfAccountsForCs = new ArrayList<>();
+                List<Long> knownSfAccountsNotForCs = new ArrayList<>();
+
+                List<Long> newVolumeIds = new ArrayList<>();
+
+                for (long volumeId : volumeIds) {
+                    SolidFireVolume sfVolume = getVolume(sfConnection, volumeId);
+                    long sfAccountId = sfVolume.getAccountId();
+
+                    if (knownSfAccountsForCs.contains(sfAccountId)) {
+                        addVolumeIdToSolidFireVag(volumeId, sfVag, newVolumeIds);
+                    }
+                    else if (!knownSfAccountsNotForCs.contains(sfAccountId)) {
+                        SolidFireAccount sfAccount = getAccountById(sfConnection, sfAccountId);
+
+                        if (sfAccount.getName().startsWith(SF_CS_ACCOUNT_PREFIX)) {
+                            knownSfAccountsForCs.add(sfAccountId);
+
+                            addVolumeIdToSolidFireVag(volumeId, sfVag, newVolumeIds);
+                        }
+                        else {
+                            knownSfAccountsNotForCs.add(sfAccountId);
+                        }
+                    }
+                }
+
+                if (newVolumeIds.size() > 0) {
+                    addVolumeIdsToSolidFireVag(sfConnection, sfVag.getId(), newVolumeIds.toArray(new Long[0]));
+                }
+            }
+        }
+    }
+
+    private static void addVolumeIdToSolidFireVag(long volumeId, SolidFireVag sfVag, List<Long> newVolumeIds) {
+        List<Long> existingVolumeIds = Longs.asList(sfVag.getVolumeIds());
+
+        if (!existingVolumeIds.contains(volumeId) && !newVolumeIds.contains(volumeId)) {
+            newVolumeIds.add(volumeId);
+        }
+    }
+
+    private static SolidFireVag getVagForRandomHostInCluster(List<SolidFireUtil.SolidFireVag> sfVags, Host host, HostDao hostDao) {
+        List<HostVO> hostVOs = hostDao.findByClusterId(host.getClusterId());
+
+        if (hostVOs != null) {
+            Collections.shuffle(hostVOs, RANDOM);
+
+            for (HostVO hostVO : hostVOs) {
+                if (hostVO.getId() != host.getId() && hostSupports_iScsi(hostVO)) {
+                    SolidFireVag sfVag = getVolumeAccessGroup(hostVO.getStorageUrl(), sfVags);
+
+                    if (sfVag != null) {
+                        return sfVag;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static void placeVolumeInVolumeAccessGroups(SolidFireConnection sfConnection, long sfVolumeId, List<HostVO> hosts) {
+        if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
+            String errMsg = "Not all hosts in the compute cluster support iSCSI.";
+
+            LOGGER.warn(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
+
+        Map<SolidFireUtil.SolidFireVag, List<String>> sfVagToIqnsMap = new HashMap<>();
+
+        for (HostVO hostVO : hosts) {
+            String iqn = hostVO.getStorageUrl();
+
+            SolidFireUtil.SolidFireVag sfVag = getVolumeAccessGroup(iqn, sfVags);
+
+            List<String> iqnsInVag = sfVagToIqnsMap.computeIfAbsent(sfVag, k -> new ArrayList<>());
+
+            iqnsInVag.add(iqn);
+        }
+
+        if (sfVagToIqnsMap.size() > MAX_NUM_VAGS_PER_VOLUME) {
+            throw new CloudRuntimeException("A SolidFire volume can be in at most four volume access groups simultaneously.");
+        }
+
+        for (SolidFireUtil.SolidFireVag sfVag : sfVagToIqnsMap.keySet()) {
+            if (sfVag != null) {
+                if (!SolidFireUtil.isVolumeIdInSfVag(sfVolumeId, sfVag)) {
+                    SolidFireUtil.addVolumeIdsToSolidFireVag(sfConnection, sfVag.getId(), new Long[] { sfVolumeId });
+                }
+            }
+            else {
+                List<String> iqnsNotInVag = sfVagToIqnsMap.get(null);
+
+                SolidFireUtil.createVag(sfConnection, "CloudStack-" + UUID.randomUUID().toString(),
+                        iqnsNotInVag.toArray(new String[0]), new long[] { sfVolumeId });
+            }
+        }
+    }
+
+    public static SolidFireUtil.SolidFireVag getVolumeAccessGroup(String hostIqn, List<SolidFireUtil.SolidFireVag> sfVags) {
+        if (hostIqn == null) {
+            return null;
+        }
+
+        hostIqn = hostIqn.toLowerCase();
+
+        if (sfVags != null) {
+            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
+                List<String> lstInitiators = getStringArrayAsLowerCaseStringList(sfVag.getInitiators());
+
+                // lstInitiators should not be returned from getStringArrayAsLowerCaseStringList as null
+                if (lstInitiators.contains(hostIqn)) {
+                    return sfVag;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static boolean sfVagContains(SolidFireUtil.SolidFireVag sfVag, long sfVolumeId, long clusterId, HostDao hostDao) {
+        if (isVolumeIdInSfVag(sfVolumeId, sfVag)) {
+            String[] iqns = sfVag.getInitiators();
+            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
+
+            for (String iqn : iqns) {
+                for (HostVO host : hosts) {
+                    String hostIqn = host.getStorageUrl();
+
+                    if (iqn.equalsIgnoreCase(hostIqn)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean isVolumeIdInSfVag(long sfVolumeIdToCheck, SolidFireUtil.SolidFireVag sfVag) {
+        long[] sfVolumeIds = sfVag.getVolumeIds();
+
+        for (long sfVolumeId : sfVolumeIds) {
+            if (sfVolumeId == sfVolumeIdToCheck) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean hostSupports_iScsi(Host host) {
+        return host != null && host.getStorageUrl() != null && host.getStorageUrl().trim().length() > 0 && host.getStorageUrl().startsWith("iqn");
+    }
+
+    private static boolean hostsSupport_iScsi(List<HostVO> hosts) {
+        if (hosts == null || hosts.size() == 0) {
+            return false;
+        }
+
+        for (Host host : hosts) {
+            if (!hostSupports_iScsi(host)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static String getVagKey(long storagePoolId) {
+        return "sfVolumeAccessGroup_" + storagePoolId;
+    }
+
+    public static String getAccountKey(long storagePoolId) {
+        return SolidFireUtil.ACCOUNT_ID + "_" + storagePoolId;
+    }
+
+    public static AccountDetailVO getAccountDetail(long csAccountId, long storagePoolId, AccountDetailsDao accountDetailsDao) {
+        AccountDetailVO accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId));
+
+        if (accountDetail == null || accountDetail.getValue() == null) {
+            accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.ACCOUNT_ID);
+        }
+
+        return accountDetail;
+    }
+
+    public static String getSolidFireVolumeName(String strCloudStackVolumeName) {
+        final String specialChar = "-";
+
+        StringBuilder strSolidFireVolumeName = new StringBuilder();
+
+        for (int i = 0; i < strCloudStackVolumeName.length(); i++) {
+            String strChar = strCloudStackVolumeName.substring(i, i + 1);
+
+            if (StringUtils.isAlphanumeric(strChar)) {
+                strSolidFireVolumeName.append(strChar);
+            } else {
+                strSolidFireVolumeName.append(specialChar);
+            }
+        }
+
+        return strSolidFireVolumeName.toString();
+    }
+
+    public static long createVolume(SolidFireConnection sfConnection, String volumeName, long accountId, long totalSize,
+                                    boolean enable512e, Map<String, String> mapAttributes, long minIops, long maxIops, long burstIops) {
+        CreateVolumeRequest request = CreateVolumeRequest.builder()
+                .name(volumeName)
+                .accountID(accountId)
+                .totalSize(totalSize)
+                .enable512e(enable512e)
+                .optionalAttributes(convertMap(mapAttributes))
+                .optionalQos(new QoS(Optional.of(minIops), Optional.of(maxIops), Optional.of(burstIops), Optional.EMPTY_LONG))
+                .build();
+
+        return getSolidFireElement(sfConnection).createVolume(request).getVolumeID();
+    }
+
+    public static void modifyVolume(SolidFireConnection sfConnection, long volumeId, Long totalSize, Map<String, String> mapAttributes,
+                                    long minIops, long maxIops, long burstIops) {
+        ModifyVolumeRequest request = ModifyVolumeRequest.builder()
+                .volumeID(volumeId)
+                .optionalTotalSize(totalSize)
+                .optionalAttributes(convertMap(mapAttributes))
+                .optionalQos(new QoS(Optional.of(minIops), Optional.of(maxIops), Optional.of(burstIops), Optional.EMPTY_LONG))
+                .build();
+
+        getSolidFireElement(sfConnection).modifyVolume(request);
+    }
+
+    public static void modifyVolumeQoS(SolidFireConnection sfConnection, long volumeId, long minIops, long maxIops, long burstIops) {
+        ModifyVolumeRequest request = ModifyVolumeRequest.builder()
+                .volumeID(volumeId)
+                .optionalQos(new QoS(Optional.of(minIops), Optional.of(maxIops), Optional.of(burstIops), Optional.EMPTY_LONG))
+                .build();
+
+        getSolidFireElement(sfConnection).modifyVolume(request);
+    }
+
+    public static SolidFireVolume getVolume(SolidFireConnection sfConnection, long volumeId) {
+        ListVolumesRequest request = ListVolumesRequest.builder()
+                .optionalStartVolumeID(volumeId)
+                .optionalLimit(1L)
+                .build();
+
+        Volume volume = getSolidFireElement(sfConnection).listVolumes(request).getVolumes()[0];
+
+        return new SolidFireVolume(volume.getVolumeID(), volume.getName(), volume.getIqn(), volume.getAccountID(), volume.getStatus(),
+                volume.getEnable512e(), volume.getQos().getMinIOPS(), volume.getQos().getMaxIOPS(), volume.getQos().getBurstIOPS(),
+                volume.getTotalSize(), volume.getScsiNAADeviceID());
+    }
+
+    public static void deleteVolume(SolidFireConnection sfConnection, long volumeId) {
+        DeleteVolumeRequest request = DeleteVolumeRequest.builder()
+                .volumeID(volumeId)
+                .build();
+
+        getSolidFireElement(sfConnection).deleteVolume(request);
+    }
+
+    private static final String ACTIVE = "active";
+
+    public static class SolidFireVolume {
+        private final long _id;
+        private final String _name;
+        private final String _iqn;
+        private final long _accountId;
+        private final String _status;
+        private final boolean _enable512e;
+        private final long _minIops;
+        private final long _maxIops;
+        private final long _burstIops;
+        private final long _totalSize;
+        private final String _scsiNaaDeviceId;
+
+        SolidFireVolume(long id, String name, String iqn, long accountId, String status, boolean enable512e,
+                        long minIops, long maxIops, long burstIops, long totalSize, String scsiNaaDeviceId) {
+            _id = id;
+            _name = name;
+            _iqn = "/" + iqn + "/0";
+            _accountId = accountId;
+            _status = status;
+            _enable512e = enable512e;
+            _minIops = minIops;
+            _maxIops = maxIops;
+            _burstIops = burstIops;
+            _totalSize = totalSize;
+            _scsiNaaDeviceId = scsiNaaDeviceId;
+        }
+
+        public long getId() {
+            return _id;
+        }
+
+        public String getName() {
+            return _name;
+        }
+
+        public String getIqn() {
+            return _iqn;
+        }
+
+        public long getAccountId() {
+            return _accountId;
+        }
+
+        public boolean isActive() {
+            return ACTIVE.equalsIgnoreCase(_status);
+        }
+
+        public boolean isEnable512e() {
+            return _enable512e;
+        }
+
+        public long getMinIops() {
+            return _minIops;
+        }
+
+        public long getMaxIops() {
+            return _maxIops;
+        }
+
+        public long getBurstIops() {
+            return _burstIops;
+        }
+
+        public long getTotalSize() {
+            return _totalSize;
+        }
+
+        public String getScsiNaaDeviceId() {
+            return _scsiNaaDeviceId;
+        }
+
+        @Override
+        public int hashCode() {
+            return _iqn.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return _name;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
+            if (!obj.getClass().equals(SolidFireVolume.class)) {
+                return false;
+            }
+
+            SolidFireVolume sfv = (SolidFireVolume)obj;
+
+            return _id == sfv._id && _name.equals(sfv._name) && _iqn.equals(sfv._iqn) && _accountId == sfv._accountId &&
+                    isActive() == sfv.isActive() && getTotalSize() == sfv.getTotalSize();
+        }
+    }
+
+    public static long createSnapshot(SolidFireConnection sfConnection, long volumeId, String snapshotName, Map<String, String> mapAttributes) {
+        CreateSnapshotRequest request = CreateSnapshotRequest.builder()
+                .volumeID(volumeId)
+                .optionalName(snapshotName)
+                .optionalAttributes(convertMap(mapAttributes))
+                .build();
+
+        return getSolidFireElement(sfConnection).createSnapshot(request).getSnapshotID();
+    }
+
+    public static SolidFireSnapshot getSnapshot(SolidFireConnection sfConnection, long volumeId, long snapshotId) {
+        ListSnapshotsRequest request = ListSnapshotsRequest.builder()
+                .optionalVolumeID(volumeId)
+                .build();
+
+        Snapshot[] snapshots = getSolidFireElement(sfConnection).listSnapshots(request).getSnapshots();
+
+        String snapshotName = null;
+        long totalSize = 0;
+
+        if (snapshots != null) {
+            for (Snapshot snapshot : snapshots) {
+                if (snapshot.getSnapshotID() == snapshotId) {
+                    snapshotName = snapshot.getName();
+                    totalSize = snapshot.getTotalSize();
+
+                    break;
+                }
+            }
+        }
+
+        if (snapshotName == null) {
+            throw new CloudRuntimeException("Could not find SolidFire snapshot ID: " + snapshotId + " for the following SolidFire volume ID: " + volumeId);
+        }
+
+        return new SolidFireSnapshot(snapshotId, snapshotName, totalSize);
+    }
+
+    public static void deleteSnapshot(SolidFireConnection sfConnection, long snapshotId) {
+        DeleteSnapshotRequest request = DeleteSnapshotRequest.builder()
+                .snapshotID(snapshotId)
+                .build();
+
+        getSolidFireElement(sfConnection).deleteSnapshot(request);
+    }
+
+    public static void rollBackVolumeToSnapshot(SolidFireConnection sfConnection, long volumeId, long snapshotId) {
+        RollbackToSnapshotRequest request = RollbackToSnapshotRequest.builder()
+                .volumeID(volumeId)
+                .snapshotID(snapshotId)
+                .build();
+
+        getSolidFireElement(sfConnection).rollbackToSnapshot(request);
+    }
+
+    public static class SolidFireSnapshot {
+        private final long _id;
+        private final String _name;
+        private final long _totalSize;
+
+        SolidFireSnapshot(long id, String name, long totalSize) {
+            _id = id;
+            _name = name;
+            _totalSize = totalSize;
+        }
+
+        public long getId() {
+            return _id;
+        }
+
+        public String getName() {
+            return _name;
+        }
+
+        public long getTotalSize() {
+            return _totalSize;
+        }
+    }
+
+    public static long createClone(SolidFireConnection sfConnection, long volumeId, long snapshotId, long accountId,
+                                   String cloneName, Map<String, String> mapAttributes) {
+        CloneVolumeRequest request = CloneVolumeRequest.builder()
+                .volumeID(volumeId)
+                .optionalSnapshotID(snapshotId < 1 ? null : snapshotId)
+                .optionalNewAccountID(accountId)
+                .name(cloneName)
+                .optionalAttributes(convertMap(mapAttributes))
+                .build();
+
+        CloneVolumeResult result = getSolidFireElement(sfConnection).cloneVolume(request);
+
+        // Clone is an async operation. Poll until we get data.
+
+        GetAsyncResultRequest asyncResultRequest = GetAsyncResultRequest.builder()
+                .asyncHandle(result.getAsyncHandle())
+                .build();
+
+        do {
+            String status = getSolidFireElement(sfConnection).getAsyncResult(asyncResultRequest).getStatus();
+
+            if (status.equals("complete")) {
+                break;
+            }
+
+            try {
+                Thread.sleep(500); // sleep for 1/2 of a second
+            }
+            catch (Exception ex) {
+                // ignore
+            }
+        }
+        while (true);
+
+        return result.getVolumeID();
+    }
+
+    public static long createAccount(SolidFireConnection sfConnection, String accountName) {
+        AddAccountRequest request = AddAccountRequest.builder()
+                .username(accountName)
+                .build();
+
+        return getSolidFireElement(sfConnection).addAccount(request).getAccountID();
+    }
+
+    public static SolidFireAccount getAccountById(SolidFireConnection sfConnection, long accountId) {
+        GetAccountByIDRequest request = GetAccountByIDRequest.builder()
+                .accountID(accountId)
+                .build();
+
+        Account sfAccount = getSolidFireElement(sfConnection).getAccountByID(request).getAccount();
+
+        String sfAccountName = sfAccount.getUsername();
+        String sfAccountInitiatorSecret = sfAccount.getInitiatorSecret().isPresent() ? sfAccount.getInitiatorSecret().get().toString() : "";
+        String sfAccountTargetSecret = sfAccount.getTargetSecret().isPresent() ? sfAccount.getTargetSecret().get().toString() : "";
+
+        return new SolidFireAccount(accountId, sfAccountName, sfAccountInitiatorSecret, sfAccountTargetSecret);
+    }
+
+    private static SolidFireAccount getAccountByName(SolidFireConnection sfConnection, String accountName) {
+        GetAccountByNameRequest request = GetAccountByNameRequest.builder()
+                .username(accountName)
+                .build();
+
+        Account sfAccount = getSolidFireElement(sfConnection).getAccountByName(request).getAccount();
+
+        long sfAccountId = sfAccount.getAccountID();
+        String sfAccountInitiatorSecret = sfAccount.getInitiatorSecret().isPresent() ? sfAccount.getInitiatorSecret().get().toString() : "";
+        String sfAccountTargetSecret = sfAccount.getTargetSecret().isPresent() ? sfAccount.getTargetSecret().get().toString() : "";
+
+        return new SolidFireAccount(sfAccountId, accountName, sfAccountInitiatorSecret, sfAccountTargetSecret);
+    }
+
+    public static class SolidFireAccount {
+        private final long _id;
+        private final String _name;
+        private final String _initiatorSecret;
+        private final String _targetSecret;
+
+        SolidFireAccount(long id, String name, String initiatorSecret, String targetSecret) {
+            _id = id;
+            _name = name;
+            _initiatorSecret = initiatorSecret;
+            _targetSecret = targetSecret;
+        }
+
+        public long getId() {
+            return _id;
+        }
+
+        public String getName() {
+            return _name;
+        }
+
+        @Override
+        public int hashCode() {
+            return (_id + _name).hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return _name;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
+            if (!obj.getClass().equals(SolidFireAccount.class)) {
+                return false;
+            }
+
+            SolidFireAccount sfa = (SolidFireAccount)obj;
+
+            return _id == sfa._id && _name.equals(sfa._name) &&
+                    _initiatorSecret.equals(sfa._initiatorSecret) &&
+                    _targetSecret.equals(sfa._targetSecret);
+        }
+    }
+
+    private static long createVag(SolidFireConnection sfConnection, String vagName, String[] iqns, long[] volumeIds) {
+        CreateVolumeAccessGroupRequest request = CreateVolumeAccessGroupRequest.builder()
+                .name(vagName)
+                .optionalInitiators(iqns)
+                .optionalVolumes(Longs.asList(volumeIds).toArray(new Long[volumeIds.length]))
+                .build();
+
+        return getSolidFireElement(sfConnection).createVolumeAccessGroup(request).getVolumeAccessGroupID();
+    }
+
+    private static void addInitiatorsToSolidFireVag(SolidFireConnection sfConnection, long vagId, String[] initiators) {
+        AddInitiatorsToVolumeAccessGroupRequest request = AddInitiatorsToVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .initiators(initiators)
+                .build();
+
+        getSolidFireElement(sfConnection).addInitiatorsToVolumeAccessGroup(request);
+    }
+
+    private static void removeInitiatorsFromSolidFireVag(SolidFireConnection sfConnection, long vagId, String[] initiators) {
+        RemoveInitiatorsFromVolumeAccessGroupRequest request = RemoveInitiatorsFromVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .initiators(initiators)
+                .build();
+
+        getSolidFireElement(sfConnection).removeInitiatorsFromVolumeAccessGroup(request);
+    }
+
+    private static void addVolumeIdsToSolidFireVag(SolidFireConnection sfConnection, long vagId, Long[] volumeIds) {
+        AddVolumesToVolumeAccessGroupRequest request = AddVolumesToVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .volumes(volumeIds)
+                .build();
+
+        getSolidFireElement(sfConnection).addVolumesToVolumeAccessGroup(request);
+    }
+
+    public static void removeVolumeIdsFromSolidFireVag(SolidFireConnection sfConnection, long vagId, Long[] volumeIds) {
+        RemoveVolumesFromVolumeAccessGroupRequest request = RemoveVolumesFromVolumeAccessGroupRequest.builder()
+                .volumeAccessGroupID(vagId)
+                .volumes(volumeIds)
+                .build();
+
+        getSolidFireElement(sfConnection).removeVolumesFromVolumeAccessGroup(request);
+    }
+
+    public static List<SolidFireVag> getAllVags(SolidFireConnection sfConnection)
+    {
+        ListVolumeAccessGroupsRequest request = ListVolumeAccessGroupsRequest.builder().build();
+
+        VolumeAccessGroup[] vags = getSolidFireElement(sfConnection).listVolumeAccessGroups(request).getVolumeAccessGroups();
+
+        List<SolidFireVag> lstSolidFireVags = new ArrayList<>();
+
+        if (vags != null) {
+            for (VolumeAccessGroup vag : vags) {
+                SolidFireVag sfVag = new SolidFireVag(vag.getVolumeAccessGroupID(), vag.getInitiators(), toPrimitive(vag.getVolumes()));
+
+                lstSolidFireVags.add(sfVag);
+            }
+        }
+
+        return lstSolidFireVags;
+    }
+
+    public static class SolidFireVag {
+        private final long _id;
+        private final String[] _initiators;
+        private final long[] _volumeIds;
+
+        SolidFireVag(long id, String[] initiators, long[] volumeIds) {
+            _id = id;
+            _initiators = initiators;
+            _volumeIds = volumeIds;
+        }
+
+        public long getId() {
+            return _id;
+        }
+
+        public String[] getInitiators() {
+            return _initiators;
+        }
+
+        public long[] getVolumeIds() {
+            return _volumeIds;
+        }
+
+        @Override
+        public int hashCode() {
+            return String.valueOf(_id).hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(_id);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
+            if (!obj.getClass().equals(SolidFireVag.class)) {
+                return false;
+            }
+
+            SolidFireVag sfVag = (SolidFireVag)obj;
+
+            return _id == sfVag._id;
+        }
+    }
+
+    private static String getVip(String keyToMatch, String url) {
+        String delimiter = ":";
+
+        String storageVip = getValue(keyToMatch, url);
+
+        int index = storageVip.indexOf(delimiter);
+
+        if (index != -1) {
+            return storageVip.substring(0, index);
+        }
+
+        return storageVip;
+    }
+
+    private static int getPort(String keyToMatch, String url, int defaultPortNumber) {
+        String delimiter = ":";
+
+        String storageVip = getValue(keyToMatch, url);
+
+        int index = storageVip.indexOf(delimiter);
+
+        int portNumber = defaultPortNumber;
+
+        if (index != -1) {
+            String port = storageVip.substring(index + delimiter.length());
+
+            try {
+                portNumber = Integer.parseInt(port);
+            } catch (NumberFormatException ex) {
+                throw new IllegalArgumentException("Invalid URL format (port is not an integer)");
+            }
+        }
+
+        return portNumber;
+    }
+
+    private static List<String> getStringArrayAsLowerCaseStringList(String[] aString) {
+        List<String> lstLowerCaseString = new ArrayList<>();
+
+        if (aString != null) {
+            for (String str : aString) {
+                if (str != null) {
+                    lstLowerCaseString.add(str.toLowerCase());
+                }
+            }
+        }
+
+        return lstLowerCaseString;
+    }
+
+    private static Map<String, Object> convertMap(Map<String, String> map) {
+        if (map == null) {
+            return null;
+        }
+
+        return new HashMap<>(map);
+    }
+}
diff --git a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties b/plugins/storage/volume/solidfire/src/main/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties
similarity index 100%
rename from plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties
rename to plugins/storage/volume/solidfire/src/main/resources/META-INF/cloudstack/storage-volume-solidfire/module.properties
diff --git a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml b/plugins/storage/volume/solidfire/src/main/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
similarity index 100%
rename from plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
rename to plugins/storage/volume/solidfire/src/main/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
deleted file mode 100644
index 3600ea9..0000000
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
+++ /dev/null
@@ -1,1631 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.datastore.driver;
-
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ResizeVolumePayload;
-import com.cloud.storage.Snapshot.State;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotDetailsDao;
-import com.cloud.storage.dao.SnapshotDetailsVO;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.user.AccountDetailVO;
-import com.cloud.user.AccountDetailsDao;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import com.google.common.base.Preconditions;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.CreateObjectAnswer;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-public class SolidFirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
-    private static final Logger LOGGER = Logger.getLogger(SolidFirePrimaryDataStoreDriver.class);
-    private static final int LOCK_TIME_IN_SECONDS = 300;
-    private static final int LOWEST_HYPERVISOR_SNAPSHOT_RESERVE = 10;
-    private static final long MIN_IOPS_FOR_TEMPLATE_VOLUME = 100L;
-    private static final long MAX_IOPS_FOR_TEMPLATE_VOLUME = 20000L;
-    private static final long MIN_IOPS_FOR_TEMP_VOLUME = 100L;
-    private static final long MAX_IOPS_FOR_TEMP_VOLUME = 20000L;
-    private static final long MIN_IOPS_FOR_SNAPSHOT_VOLUME = 100L;
-    private static final long MAX_IOPS_FOR_SNAPSHOT_VOLUME = 20000L;
-
-    private static final String BASIC_SF_ID = "basicSfId";
-
-    @Inject private AccountDao accountDao;
-    @Inject private AccountDetailsDao accountDetailsDao;
-    @Inject private ClusterDao clusterDao;
-    @Inject private ClusterDetailsDao clusterDetailsDao;
-    @Inject private DataStoreManager dataStoreMgr;
-    @Inject private HostDao hostDao;
-    @Inject private SnapshotDao snapshotDao;
-    @Inject private SnapshotDetailsDao snapshotDetailsDao;
-    @Inject private PrimaryDataStoreDao storagePoolDao;
-    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
-    @Inject private VMTemplatePoolDao tmpltPoolDao;
-    @Inject private VolumeDao volumeDao;
-    @Inject private VolumeDetailsDao volumeDetailsDao;
-    @Inject private VolumeDataFactory volumeFactory;
-
-    @Override
-    public Map<String, String> getCapabilities() {
-        Map<String, String> mapCapabilities = new HashMap<>();
-
-        mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString());
-        mapCapabilities.put(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_SNAPSHOT.toString(), Boolean.TRUE.toString());
-        mapCapabilities.put(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString(), Boolean.TRUE.toString());
-        mapCapabilities.put(DataStoreCapabilities.CAN_REVERT_VOLUME_TO_SNAPSHOT.toString(), Boolean.TRUE.toString());
-
-        return mapCapabilities;
-    }
-
-    @Override
-    public DataTO getTO(DataObject data) {
-        return null;
-    }
-
-    @Override
-    public DataStoreTO getStoreTO(DataStore store) {
-        return null;
-    }
-
-    private SolidFireUtil.SolidFireAccount createSolidFireAccount(SolidFireUtil.SolidFireConnection sfConnection, String sfAccountName) {
-        long accountNumber = SolidFireUtil.createAccount(sfConnection, sfAccountName);
-
-        return SolidFireUtil.getAccountById(sfConnection, accountNumber);
-    }
-
-    @Override
-    public ChapInfo getChapInfo(DataObject dataObject) {
-        return null;
-    }
-
-    // get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups)
-    // if the VAG exists
-    //     update the VAG to contain all IQNs of the hosts (ModifyVolumeAccessGroup)
-    //     if the ID of volumeInfo in not in the VAG, add it (ModifyVolumeAccessGroup)
-    // if the VAG doesn't exist, create it with the IQNs of the hosts and the ID of volumeInfo (CreateVolumeAccessGroup)
-    @Override
-    public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore)
-    {
-        Preconditions.checkArgument(dataObject != null, "'dataObject' should not be 'null'");
-        Preconditions.checkArgument(host != null, "'host' should not be 'null'");
-        Preconditions.checkArgument(dataStore != null, "'dataStore' should not be 'null'");
-
-        long sfVolumeId = getSolidFireVolumeId(dataObject, true);
-        long clusterId = host.getClusterId();
-        long storagePoolId = dataStore.getId();
-
-        ClusterVO cluster = clusterDao.findById(clusterId);
-
-        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
-
-        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
-            String errMsg = "Couldn't lock the DB (in grantAccess) on the following string: " + cluster.getUuid();
-
-            LOGGER.warn(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        try {
-            ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-            String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-            List<HostVO> hosts = hostDao.findByClusterId(clusterId);
-
-            if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
-                String errMsg = "Not all hosts in the compute cluster support iSCSI.";
-
-                LOGGER.warn(errMsg);
-
-                throw new CloudRuntimeException(errMsg);
-            }
-
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-            if (vagId != null) {
-                SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-                long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
-
-                SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
-            }
-            else {
-                SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolumeId, storagePoolId, cluster.getUuid(), hosts, clusterDetailsDao);
-            }
-
-            return true;
-        }
-        finally {
-            lock.unlock();
-            lock.releaseRef();
-        }
-    }
-
-    // get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups) // might not exist if using CHAP
-    // if the VAG exists
-    //     remove the ID of volumeInfo from the VAG (ModifyVolumeAccessGroup)
-    @Override
-    public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore)
-    {
-        if (dataObject == null || host == null || dataStore == null) {
-            return;
-        }
-
-        long sfVolumeId = getSolidFireVolumeId(dataObject, false);
-        long clusterId = host.getClusterId();
-        long storagePoolId = dataStore.getId();
-
-        ClusterVO cluster = clusterDao.findById(clusterId);
-
-        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
-
-        if (!lock.lock(LOCK_TIME_IN_SECONDS)) {
-            String errMsg = "Couldn't lock the DB (in revokeAccess) on the following string: " + cluster.getUuid();
-
-            LOGGER.debug(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        try {
-            ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-            String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-            if (vagId != null) {
-                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-                SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-                long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
-
-                SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
-            }
-        }
-        finally {
-            lock.unlock();
-            lock.releaseRef();
-        }
-    }
-
-    private long getSolidFireVolumeId(DataObject dataObject, boolean grantAccess) {
-        if (dataObject.getType() == DataObjectType.VOLUME) {
-            final VolumeInfo volumeInfo = (VolumeInfo)dataObject;
-            final long volumeId = volumeInfo.getId();
-
-            if (grantAccess && isBasicGrantAccess(volumeId)) {
-                volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_GRANT_ACCESS);
-
-                final Long sfVolumeId = getBasicSfVolumeId(volumeId);
-
-                Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null' (basic grant access).");
-
-                return sfVolumeId;
-            }
-            else if (!grantAccess && isBasicRevokeAccess(volumeId)) {
-                volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_REVOKE_ACCESS);
-
-                final Long sfVolumeId = getBasicSfVolumeId(volumeId);
-
-                Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null' (basic revoke access).");
-
-                return sfVolumeId;
-            }
-
-            return Long.parseLong(volumeInfo.getFolder());
-        }
-
-        if (dataObject.getType() == DataObjectType.SNAPSHOT) {
-            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(dataObject.getId(), SolidFireUtil.VOLUME_ID);
-
-            if (snapshotDetails == null || snapshotDetails.getValue() == null) {
-                throw new CloudRuntimeException("Unable to locate the volume ID associated with the following snapshot ID: " + dataObject.getId());
-            }
-
-            return Long.parseLong(snapshotDetails.getValue());
-        }
-
-        if (dataObject.getType() == DataObjectType.TEMPLATE) {
-            return getVolumeIdFrom_iScsiPath(((TemplateInfo)dataObject).getInstallPath());
-        }
-
-        throw new CloudRuntimeException("Invalid DataObjectType (" + dataObject.getType() + ") passed to getSolidFireVolumeId(DataObject, boolean)");
-    }
-
-    private long getVolumeIdFrom_iScsiPath(String iScsiPath) {
-        String[] splits = iScsiPath.split("/");
-        String iqn = splits[1];
-
-        String sequenceToSearchFor = ".";
-        int lastIndexOf = iqn.lastIndexOf(sequenceToSearchFor);
-        String volumeIdAsString = iqn.substring(lastIndexOf + sequenceToSearchFor.length());
-
-        return Long.parseLong(volumeIdAsString);
-    }
-
-    private long getDefaultMinIops(long storagePoolId) {
-        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS);
-
-        String clusterDefaultMinIops = storagePoolDetail.getValue();
-
-        return Long.parseLong(clusterDefaultMinIops);
-    }
-
-    private long getDefaultMaxIops(long storagePoolId) {
-        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS);
-
-        String clusterDefaultMaxIops = storagePoolDetail.getValue();
-
-        return Long.parseLong(clusterDefaultMaxIops);
-    }
-
-    private long getDefaultBurstIops(long storagePoolId, long maxIops) {
-        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS);
-
-        String clusterDefaultBurstIopsPercentOfMaxIops = storagePoolDetail.getValue();
-
-        float fClusterDefaultBurstIopsPercentOfMaxIops = Float.parseFloat(clusterDefaultBurstIopsPercentOfMaxIops);
-
-        return Math.min((long)(maxIops * fClusterDefaultBurstIopsPercentOfMaxIops), SolidFireUtil.MAX_IOPS_PER_VOLUME);
-    }
-
-    private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection,
-                                                                DataObject dataObject, long storagePoolId, long sfAccountId) {
-        final Long minIops;
-        final Long maxIops;
-        final Long volumeSize;
-        final String volumeName;
-
-        final Map<String, String> mapAttributes;
-
-        if (dataObject.getType() == DataObjectType.VOLUME) {
-            VolumeInfo volumeInfo = (VolumeInfo)dataObject;
-
-            minIops = volumeInfo.getMinIops();
-            maxIops = volumeInfo.getMaxIops();
-            volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePoolDao.findById(storagePoolId));
-            volumeName = volumeInfo.getName();
-
-            mapAttributes = getVolumeAttributes(volumeInfo);
-        } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
-            TemplateInfo templateInfo = (TemplateInfo)dataObject;
-
-            minIops = MIN_IOPS_FOR_TEMPLATE_VOLUME;
-            maxIops = MAX_IOPS_FOR_TEMPLATE_VOLUME;
-            volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(templateInfo, storagePoolDao.findById(storagePoolId));
-            volumeName = templateInfo.getUniqueName();
-
-            mapAttributes = getTemplateAttributes(templateInfo);
-        }
-        else {
-            throw new CloudRuntimeException("Invalid type passed to createSolidFireVolume: " + dataObject.getType());
-        }
-
-        final Iops iops = getIops(minIops, maxIops, storagePoolId);
-
-        long sfVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeName), sfAccountId,
-                volumeSize, true, mapAttributes, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
-
-        return SolidFireUtil.getVolume(sfConnection, sfVolumeId);
-    }
-
-    private Iops getIops(Long minIops, Long maxIops, long storagePoolId) {
-        if (minIops == null || minIops <= 0 || maxIops == null || maxIops <= 0) {
-            long defaultMaxIops = getDefaultMaxIops(storagePoolId);
-
-            return new Iops(getDefaultMinIops(storagePoolId), defaultMaxIops, getDefaultBurstIops(storagePoolId, defaultMaxIops));
-        }
-
-        return new Iops(minIops, maxIops, getDefaultBurstIops(storagePoolId, maxIops));
-    }
-
-    @Override
-    public long getUsedBytes(StoragePool storagePool) {
-        return getUsedBytes(storagePool, Long.MIN_VALUE);
-    }
-
-    private long getUsedBytes(StoragePool storagePool, long volumeIdToIgnore) {
-        long usedSpace = 0;
-
-        List<VolumeVO> lstVolumes = volumeDao.findByPoolId(storagePool.getId(), null);
-
-        if (lstVolumes != null) {
-            for (VolumeVO volume : lstVolumes) {
-                if (volume.getId() == volumeIdToIgnore) {
-                    continue;
-                }
-
-                VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volume.getId(), SolidFireUtil.VOLUME_SIZE);
-
-                if (volumeDetail != null && volumeDetail.getValue() != null) {
-                    long volumeSize = Long.parseLong(volumeDetail.getValue());
-
-                    usedSpace += volumeSize;
-                }
-                else {
-                    SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
-
-                    try {
-                        long lVolumeId = Long.parseLong(volume.getFolder());
-
-                        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, lVolumeId);
-
-                        long volumeSize = sfVolume.getTotalSize();
-
-                        // SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
-                        // To be backward compatible with releases prior to 4.5, call updateVolumeDetails here.
-                        // That way if SolidFireUtil.VOLUME_SIZE wasn't put in the volume_details table when the
-                        // volume was initially created, it can be placed in volume_details here.
-                        updateVolumeDetails(volume.getId(), volumeSize, sfVolume.getScsiNaaDeviceId());
-
-                        usedSpace += volumeSize;
-                    }
-                    catch (Exception ex) {
-                        // can be ignored
-                    }
-                }
-            }
-        }
-
-        List<SnapshotVO> lstSnapshots = snapshotDao.listAll();
-
-        if (lstSnapshots != null) {
-            for (SnapshotVO snapshot : lstSnapshots) {
-                SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.STORAGE_POOL_ID);
-
-                // if this snapshot belongs to the storagePool that was passed in
-                if (snapshotDetails != null && snapshotDetails.getValue() != null && Long.parseLong(snapshotDetails.getValue()) == storagePool.getId()) {
-                    snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.VOLUME_SIZE);
-
-                    if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-                        long snapshotSize = Long.parseLong(snapshotDetails.getValue());
-
-                        usedSpace += snapshotSize;
-                    }
-                }
-            }
-        }
-
-        List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
-
-        if (lstTemplatePoolRefs != null) {
-            for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
-                usedSpace += templatePoolRef.getTemplateSize();
-            }
-        }
-
-        return usedSpace;
-    }
-
-    @Override
-    public long getUsedIops(StoragePool storagePool) {
-        long usedIops = 0;
-
-        List<VolumeVO> volumes = volumeDao.findByPoolId(storagePool.getId(), null);
-
-        if (volumes != null) {
-            for (VolumeVO volume : volumes) {
-                if (!Volume.State.Creating.equals(volume.getState())) {
-                    usedIops += volume.getMinIops() != null ? volume.getMinIops() : 0;
-                }
-            }
-        }
-
-        return usedIops;
-    }
-
-    @Override
-    public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool pool) {
-        long volumeSize = 0;
-
-        if (dataObject.getType() == DataObjectType.VOLUME) {
-            VolumeInfo volume = (VolumeInfo)dataObject;
-
-            volumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volume.getSize(), volume.getHypervisorSnapshotReserve());
-        } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
-            TemplateInfo templateInfo = (TemplateInfo)dataObject;
-
-            // TemplateInfo sometimes has a size equal to null.
-            long templateSize = templateInfo.getSize() != null ? templateInfo.getSize() : 0;
-
-            if (templateInfo.getHypervisorType() == Hypervisor.HypervisorType.KVM) {
-                volumeSize = templateSize;
-            }
-            else {
-                volumeSize = (long)(templateSize + templateSize * (LOWEST_HYPERVISOR_SNAPSHOT_RESERVE / 100f));
-            }
-        }
-
-        return Math.max(volumeSize, SolidFireUtil.MIN_VOLUME_SIZE);
-    }
-
-    private long getVolumeSizeIncludingHypervisorSnapshotReserve(long volumeSize, Integer hypervisorSnapshotReserve) {
-        if (hypervisorSnapshotReserve != null) {
-            hypervisorSnapshotReserve = Math.max(hypervisorSnapshotReserve, LOWEST_HYPERVISOR_SNAPSHOT_RESERVE);
-
-            volumeSize += volumeSize * (hypervisorSnapshotReserve / 100f);
-        }
-
-        return Math.max(volumeSize, SolidFireUtil.MIN_VOLUME_SIZE);
-    }
-
-    /**
-     * This method is only relevant when storagePool is being used with a compute cluster that supports UUID resigning.
-     */
-    @Override
-    public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) {
-        List<VMTemplateStoragePoolVO> lstTemplatePoolRefs = tmpltPoolDao.listByPoolId(storagePool.getId());
-
-        if (lstTemplatePoolRefs != null) {
-            for (VMTemplateStoragePoolVO templatePoolRef : lstTemplatePoolRefs) {
-                if (templatePoolRef.getTemplateId() == templateInfo.getId()) {
-                    // This indicates that we already have this template stored on this primary storage, so
-                    // we do not require additional space.
-                    return 0;
-                }
-            }
-        }
-
-        // This indicates that we do not have a copy of this template on this primary storage, so
-        // we need to take it into consideration from a space standpoint (ex. when a new VM is spun
-        // up and wants to use this particular template for its root disk).
-        return getDataObjectSizeIncludingHypervisorSnapshotReserve(templateInfo, storagePool);
-    }
-
-    private static class Iops {
-        private final long _minIops;
-        private final long _maxIops;
-        private final long _burstIops;
-
-        Iops(long minIops, long maxIops, long burstIops) throws IllegalArgumentException {
-            if (minIops <= 0 || maxIops <= 0) {
-                throw new IllegalArgumentException("The 'Min IOPS' and 'Max IOPS' values must be greater than 0.");
-            }
-
-            if (minIops > maxIops) {
-                throw new IllegalArgumentException("The 'Min IOPS' value cannot exceed the 'Max IOPS' value.");
-            }
-
-            if (maxIops > burstIops) {
-                throw new IllegalArgumentException("The 'Max IOPS' value cannot exceed the 'Burst IOPS' value.");
-            }
-
-            _minIops = minIops;
-            _maxIops = maxIops;
-            _burstIops = burstIops;
-        }
-
-        long getMinIops() {
-            return _minIops;
-        }
-
-        long getMaxIops() {
-            return _maxIops;
-        }
-
-        long getBurstIops() {
-            return _burstIops;
-        }
-    }
-
-    private void deleteSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo)
-    {
-        Long storagePoolId = volumeInfo.getPoolId();
-
-        if (storagePoolId == null) {
-            return; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
-        }
-
-        long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
-
-        deleteSolidFireVolume(sfConnection, volumeInfo.getId(), sfVolumeId);
-    }
-
-    @Override
-    public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
-        String iqn = null;
-        String errMsg = null;
-
-        try {
-            if (dataObject.getType() == DataObjectType.VOLUME) {
-                iqn = createVolume((VolumeInfo)dataObject, dataStore.getId());
-            } else if (dataObject.getType() == DataObjectType.SNAPSHOT) {
-                createTempVolume((SnapshotInfo)dataObject, dataStore.getId());
-            } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
-                iqn = createTemplateVolume((TemplateInfo)dataObject, dataStore.getId());
-            } else {
-                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync";
-
-                LOGGER.error(errMsg);
-            }
-        }
-        catch (Exception ex) {
-            errMsg = ex.getMessage();
-
-            LOGGER.error(errMsg);
-
-            if (callback == null) {
-                throw ex;
-            }
-        }
-
-        if (callback != null) {
-            // path = iqn
-            // size is pulled from DataObject instance, if errMsg is null
-            CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-        else {
-            if (errMsg != null) {
-                throw new CloudRuntimeException(errMsg);
-            }
-        }
-    }
-
-    private long getCreateSolidFireAccountId(SolidFireUtil.SolidFireConnection sfConnection, long csAccountId, long storagePoolId) {
-        AccountDetailVO accountDetail = SolidFireUtil.getAccountDetail(csAccountId, storagePoolId, accountDetailsDao);
-
-        if (accountDetail == null || accountDetail.getValue() == null) {
-            AccountVO account = accountDao.findById(csAccountId);
-            String sfAccountName = SolidFireUtil.getSolidFireAccountName(account.getUuid(), account.getAccountId());
-            SolidFireUtil.SolidFireAccount sfAccount = SolidFireUtil.getAccount(sfConnection, sfAccountName);
-
-            if (sfAccount == null) {
-                sfAccount = createSolidFireAccount(sfConnection, sfAccountName);
-            }
-
-            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(account.getId(), sfAccount, storagePoolId, accountDetailsDao);
-
-            accountDetail = SolidFireUtil.getAccountDetail(csAccountId, storagePoolId, accountDetailsDao);
-        }
-
-        return Long.parseLong(accountDetail.getValue());
-    }
-
-    private void handleSnapshotDetails(long csSnapshotId, String name, String value) {
-        snapshotDetailsDao.removeDetail(csSnapshotId, name);
-
-        SnapshotDetailsVO snapshotDetails = new SnapshotDetailsVO(csSnapshotId, name, value, false);
-
-        snapshotDetailsDao.persist(snapshotDetails);
-    }
-
-    private void addTempVolumeId(long csSnapshotId, String tempVolumeId) {
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
-
-        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
-            throw new CloudRuntimeException("'addTempVolumeId' should not be invoked unless " + SolidFireUtil.VOLUME_ID + " exists.");
-        }
-
-        String originalVolumeId = snapshotDetails.getValue();
-
-        handleSnapshotDetails(csSnapshotId, SolidFireUtil.TEMP_VOLUME_ID, originalVolumeId);
-        handleSnapshotDetails(csSnapshotId, SolidFireUtil.VOLUME_ID, tempVolumeId);
-    }
-
-    private void removeTempVolumeId(long csSnapshotId) {
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.TEMP_VOLUME_ID);
-
-        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
-            throw new CloudRuntimeException("'removeTempVolumeId' should not be invoked unless " + SolidFireUtil.TEMP_VOLUME_ID + " exists.");
-        }
-
-        String originalVolumeId = snapshotDetails.getValue();
-
-        handleSnapshotDetails(csSnapshotId, SolidFireUtil.VOLUME_ID, originalVolumeId);
-
-        snapshotDetailsDao.remove(snapshotDetails.getId());
-    }
-
-    private Long getBasicSfVolumeId(long volumeId) {
-        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, BASIC_SF_ID);
-
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return new Long(volumeDetail.getValue());
-        }
-
-        return null;
-    }
-
-    private String getBasicIqn(long volumeId) {
-        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, BASIC_IQN);
-
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return volumeDetail.getValue();
-        }
-
-        return null;
-    }
-
-    // If isBasicCreate returns true, this means the calling code simply wants us to create a SolidFire volume with specified
-    // characteristics. We do not update the cloud.volumes table with this info.
-    private boolean isBasicCreate(long volumeId) {
-        return getBooleanValueFromVolumeDetails(volumeId, BASIC_CREATE);
-    }
-
-    private boolean isBasicDelete(long volumeId) {
-        return getBooleanValueFromVolumeDetails(volumeId, BASIC_DELETE);
-    }
-
-    private boolean isBasicDeleteFailure(long volumeId) {
-        return getBooleanValueFromVolumeDetails(volumeId, BASIC_DELETE_FAILURE);
-    }
-
-    private boolean isBasicGrantAccess(long volumeId) {
-        return getBooleanValueFromVolumeDetails(volumeId, BASIC_GRANT_ACCESS);
-    }
-
-    private boolean isBasicRevokeAccess(long volumeId) {
-        return getBooleanValueFromVolumeDetails(volumeId, BASIC_REVOKE_ACCESS);
-    }
-
-    private boolean getBooleanValueFromVolumeDetails(long volumeId, String name) {
-        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, name);
-
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return Boolean.parseBoolean(volumeDetail.getValue());
-        }
-
-        return false;
-    }
-
-    private long getCsIdForCloning(long volumeId, String cloneOf) {
-        VolumeDetailVO volumeDetail = volumeDetailsDao.findDetail(volumeId, cloneOf);
-
-        if (volumeDetail != null && volumeDetail.getValue() != null) {
-            return new Long(volumeDetail.getValue());
-        }
-
-        return Long.MIN_VALUE;
-    }
-
-    private boolean shouldTakeSnapshot(long snapshotId) {
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshotId, "takeSnapshot");
-
-        if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-            return Boolean.parseBoolean(snapshotDetails.getValue());
-        }
-
-        return false;
-    }
-
-    private SolidFireUtil.SolidFireVolume createClone(SolidFireUtil.SolidFireConnection sfConnection, long dataObjectId, VolumeInfo volumeInfo, long sfAccountId,
-            long storagePoolId, DataObjectType dataObjectType) {
-        String sfNewVolumeName = volumeInfo.getName();
-
-        long sfVolumeId = Long.MIN_VALUE;
-        long sfSnapshotId = Long.MIN_VALUE;
-
-        if (dataObjectType == DataObjectType.SNAPSHOT) {
-            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(dataObjectId, SolidFireUtil.SNAPSHOT_ID);
-
-            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-                sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
-            }
-
-            snapshotDetails = snapshotDetailsDao.findDetail(dataObjectId, SolidFireUtil.VOLUME_ID);
-
-            sfVolumeId = Long.parseLong(snapshotDetails.getValue());
-        } else if (dataObjectType == DataObjectType.TEMPLATE) {
-            // get the cached template on this storage
-            VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
-
-            if (templatePoolRef != null) {
-                sfVolumeId = Long.parseLong(templatePoolRef.getLocalDownloadPath());
-            }
-        }
-
-        if (sfVolumeId <= 0) {
-            throw new CloudRuntimeException("Unable to find SolidFire volume for the following data-object ID: " + dataObjectId +
-                    " and data-object type: " + dataObjectType);
-        }
-
-        final long newSfVolumeId = SolidFireUtil.createClone(sfConnection, sfVolumeId, sfSnapshotId, sfAccountId,
-                SolidFireUtil.getSolidFireVolumeName(sfNewVolumeName), getVolumeAttributes(volumeInfo));
-
-        final Iops iops = getIops(volumeInfo.getMinIops(), volumeInfo.getMaxIops(), storagePoolId);
-
-        SolidFireUtil.modifyVolume(sfConnection, newSfVolumeId, null, null, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
-
-        return SolidFireUtil.getVolume(sfConnection, newSfVolumeId);
-    }
-
-    private Map<String, String> getVolumeAttributes(VolumeInfo volumeInfo) {
-        Map<String, String> mapAttributes = new HashMap<>();
-
-        mapAttributes.put(SolidFireUtil.CloudStackVolumeId, String.valueOf(volumeInfo.getId()));
-        mapAttributes.put(SolidFireUtil.CloudStackVolumeSize, NumberFormat.getInstance().format(volumeInfo.getSize()));
-
-        return mapAttributes;
-    }
-
-    private Map<String, String> getSnapshotAttributes(SnapshotInfo snapshotInfo) {
-        Map<String, String> mapAttributes = new HashMap<>();
-
-        mapAttributes.put(SolidFireUtil.CloudStackSnapshotId, String.valueOf(snapshotInfo.getId()));
-        mapAttributes.put(SolidFireUtil.CloudStackSnapshotSize, NumberFormat.getInstance().format(snapshotInfo.getSize()));
-
-        return mapAttributes;
-    }
-
-    private Map<String, String> getTemplateAttributes(TemplateInfo templateInfo) {
-        Map<String, String> mapAttributes = new HashMap<>();
-
-        mapAttributes.put(SolidFireUtil.CloudStackTemplateId, String.valueOf(templateInfo.getId()));
-        mapAttributes.put(SolidFireUtil.CloudStackTemplateSize, NumberFormat.getInstance().format(templateInfo.getSize()));
-
-        return mapAttributes;
-    }
-
-    private SolidFireUtil.SolidFireVolume createCloneFromSnapshot(SolidFireUtil.SolidFireConnection sfConnection, long csSnapshotId, long sfAccountId) {
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
-
-        long sfVolumeId = Long.parseLong(snapshotDetails.getValue());
-
-        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
-
-        long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
-
-        SolidFireUtil.SolidFireSnapshot sfSnapshot = SolidFireUtil.getSnapshot(sfConnection, sfVolumeId, sfSnapshotId);
-
-        long newSfVolumeId = SolidFireUtil.createClone(sfConnection, sfVolumeId, sfSnapshotId, sfAccountId, SolidFireUtil.getSolidFireVolumeName(sfSnapshot.getName()), null);
-
-        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.STORAGE_POOL_ID);
-
-        long storagePoolId = Long.parseLong(snapshotDetails.getValue());
-
-        final Iops iops = getIops(MIN_IOPS_FOR_TEMP_VOLUME, MAX_IOPS_FOR_TEMP_VOLUME, storagePoolId);
-
-        SolidFireUtil.modifyVolume(sfConnection, newSfVolumeId, null, null, iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
-
-        return SolidFireUtil.getVolume(sfConnection, newSfVolumeId);
-    }
-
-    private void updateVolumeDetails(long volumeId, long sfVolumeSize, String scsiNaaDeviceId) {
-        volumeDetailsDao.removeDetail(volumeId, SolidFireUtil.VOLUME_SIZE);
-        volumeDetailsDao.removeDetail(volumeId, DiskTO.SCSI_NAA_DEVICE_ID);
-
-        VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeId, SolidFireUtil.VOLUME_SIZE, String.valueOf(sfVolumeSize), false);
-
-        volumeDetailsDao.persist(volumeDetailVo);
-
-        volumeDetailVo = new VolumeDetailVO(volumeId, DiskTO.SCSI_NAA_DEVICE_ID, scsiNaaDeviceId, false);
-
-        volumeDetailsDao.persist(volumeDetailVo);
-    }
-
-    @Override
-    public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
-        String errMsg = null;
-
-        try {
-            if (dataObject.getType() == DataObjectType.VOLUME) {
-                deleteVolume((VolumeInfo)dataObject, dataStore.getId());
-            } else if (dataObject.getType() == DataObjectType.SNAPSHOT) {
-                deleteSnapshot((SnapshotInfo)dataObject, dataStore.getId());
-            } else if (dataObject.getType() == DataObjectType.TEMPLATE) {
-                deleteTemplate((TemplateInfo)dataObject, dataStore.getId());
-            } else {
-                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to deleteAsync";
-            }
-        }
-        catch (Exception ex) {
-            errMsg = ex.getMessage();
-
-            LOGGER.error(errMsg);
-        }
-
-        if (callback != null) {
-            CommandResult result = new CommandResult();
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    @Override
-    public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean canCopy(DataObject srcData, DataObject destData) {
-        return false;
-    }
-
-    @Override
-    public void takeSnapshot(SnapshotInfo snapshotInfo, AsyncCompletionCallback<CreateCmdResult> callback) {
-        CreateCmdResult result;
-
-        try {
-            VolumeInfo volumeInfo = snapshotInfo.getBaseVolume();
-            VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId());
-
-            long sfVolumeId = Long.parseLong(volumeVO.getFolder());
-            long storagePoolId = volumeVO.getPoolId();
-
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-            SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
-
-            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-            long capacityBytes = storagePool.getCapacityBytes();
-            // getUsedBytes(StoragePool) will not include the bytes of the proposed new volume or snapshot because
-            // updateSnapshotDetails has not yet been called for this new volume or snapshot
-            long usedBytes = getUsedBytes(storagePool);
-            long sfVolumeSize = sfVolume.getTotalSize();
-
-            usedBytes += sfVolumeSize;
-
-            // For creating a volume or a snapshot, we need to check to make sure a sufficient amount of space remains in the primary storage.
-            // For the purpose of "charging" these bytes against storage_pool.capacity_bytes, we take the full size of the SolidFire volume
-            // that is serving as the volume the snapshot is of (either a new SolidFire volume or a SolidFire snapshot).
-            if (usedBytes > capacityBytes) {
-                throw new CloudRuntimeException("Insufficient amount of space remains in this primary storage to take a snapshot");
-            }
-
-            storagePool.setUsedBytes(usedBytes);
-
-            SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO)snapshotInfo.getTO();
-
-            if (shouldTakeSnapshot(snapshotInfo.getId())) {
-                // We are supposed to take a SolidFire snapshot to serve as the back-end for our CloudStack volume snapshot.
-
-                String sfNewSnapshotName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
-
-                int maxSnapshotNameLength = 64;
-                int trimRequired = sfNewSnapshotName.length() - maxSnapshotNameLength;
-
-                if (trimRequired > 0) {
-                    sfNewSnapshotName = StringUtils.left(volumeInfo.getName(), (volumeInfo.getName().length() - trimRequired)) + "-" + snapshotInfo.getUuid();
-                }
-
-                long sfNewSnapshotId = SolidFireUtil.createSnapshot(sfConnection, sfVolumeId, SolidFireUtil.getSolidFireVolumeName(sfNewSnapshotName),
-                        getSnapshotAttributes(snapshotInfo));
-
-                updateSnapshotDetails(snapshotInfo.getId(), volumeInfo.getId(), sfVolumeId, sfNewSnapshotId, storagePoolId, sfVolumeSize);
-
-                snapshotObjectTo.setPath("SfSnapshotId=" + sfNewSnapshotId);
-            }
-            else {
-                // We are supposed to create a new SolidFire volume to serve as the back-end for our CloudStack volume snapshot.
-
-                String sfNewVolumeName = volumeInfo.getName() + "-" + snapshotInfo.getUuid();
-
-                final Iops iops = getIops(MIN_IOPS_FOR_SNAPSHOT_VOLUME, MAX_IOPS_FOR_SNAPSHOT_VOLUME, storagePoolId);
-
-                long sfNewVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(sfNewVolumeName), sfVolume.getAccountId(),
-                        sfVolumeSize, sfVolume.isEnable512e(), getSnapshotAttributes(snapshotInfo), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
-
-                SolidFireUtil.SolidFireVolume sfNewVolume = SolidFireUtil.getVolume(sfConnection, sfNewVolumeId);
-
-                updateSnapshotDetails(snapshotInfo.getId(), sfNewVolumeId, storagePoolId, sfVolumeSize, sfNewVolume.getIqn());
-
-                snapshotObjectTo.setPath("SfVolumeId=" + sfNewVolumeId);
-            }
-
-            // Now that we have successfully created a volume or a snapshot, update the space usage in the cloud.storage_pool table
-            // (even though cloud.storage_pool.used_bytes is likely no longer in use).
-            storagePoolDao.update(storagePoolId, storagePool);
-
-            CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotObjectTo);
-
-            result = new CreateCmdResult(null, createObjectAnswer);
-
-            result.setResult(null);
-        }
-        catch (Exception ex) {
-            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to take CloudStack snapshot: " + snapshotInfo.getId(), ex);
-
-            result = new CreateCmdResult(null, new CreateObjectAnswer(ex.toString()));
-
-            result.setResult(ex.toString());
-        }
-
-        callback.complete(result);
-    }
-
-    private void updateSnapshotDetails(long csSnapshotId, long csVolumeId, long sfVolumeId, long sfNewSnapshotId, long storagePoolId, long sfNewVolumeSize) {
-        SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.ORIG_CS_VOLUME_ID,
-                String.valueOf(csVolumeId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.VOLUME_ID,
-                String.valueOf(sfVolumeId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.SNAPSHOT_ID,
-                String.valueOf(sfNewSnapshotId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.STORAGE_POOL_ID,
-                String.valueOf(storagePoolId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.VOLUME_SIZE,
-                String.valueOf(sfNewVolumeSize),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-    }
-
-    private void updateSnapshotDetails(long csSnapshotId, long sfNewVolumeId, long storagePoolId, long sfNewVolumeSize, String sfNewVolumeIqn) {
-        SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.VOLUME_ID,
-                String.valueOf(sfNewVolumeId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.STORAGE_POOL_ID,
-                String.valueOf(storagePoolId),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                SolidFireUtil.VOLUME_SIZE,
-                String.valueOf(sfNewVolumeSize),
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-
-        snapshotDetail = new SnapshotDetailsVO(csSnapshotId,
-                DiskTO.IQN,
-                sfNewVolumeIqn,
-                false);
-
-        snapshotDetailsDao.persist(snapshotDetail);
-    }
-
-    private void addBasicCreateInfoToVolumeDetails(long volumeId, SolidFireUtil.SolidFireVolume sfVolume) {
-        VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeId, BASIC_SF_ID, String.valueOf(sfVolume.getId()), false);
-
-        volumeDetailsDao.persist(volumeDetailVo);
-
-        volumeDetailVo = new VolumeDetailVO(volumeId, BASIC_IQN, sfVolume.getIqn(), false);
-
-        volumeDetailsDao.persist(volumeDetailVo);
-    }
-
-    private String createVolume(VolumeInfo volumeInfo, long storagePoolId) {
-        boolean isBasicCreate = isBasicCreate(volumeInfo.getId());
-
-        if (!isBasicCreate) {
-            verifySufficientBytesForStoragePool(volumeInfo, storagePoolId);
-            verifySufficientIopsForStoragePool(volumeInfo.getMinIops() != null ? volumeInfo.getMinIops() : getDefaultMinIops(storagePoolId), storagePoolId);
-        }
-
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-        long sfAccountId = getCreateSolidFireAccountId(sfConnection, volumeInfo.getAccountId(), storagePoolId);
-
-        SolidFireUtil.SolidFireVolume sfVolume;
-
-        if (isBasicCreate) {
-            sfVolume = createSolidFireVolume(sfConnection, volumeInfo, storagePoolId, sfAccountId);
-
-            volumeDetailsDao.removeDetail(volumeInfo.getId(), BASIC_CREATE);
-
-            addBasicCreateInfoToVolumeDetails(volumeInfo.getId(), sfVolume);
-
-            return sfVolume.getIqn();
-        }
-
-        long csSnapshotId = getCsIdForCloning(volumeInfo.getId(), "cloneOfSnapshot");
-        long csTemplateId = getCsIdForCloning(volumeInfo.getId(), "cloneOfTemplate");
-
-        if (csSnapshotId > 0) {
-            // We are supposed to create a clone of the underlying volume or snapshot that supports the CloudStack snapshot.
-            sfVolume = createClone(sfConnection, csSnapshotId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.SNAPSHOT);
-        } else if (csTemplateId > 0) {
-            // Clone from template.
-            sfVolume = createClone(sfConnection, csTemplateId, volumeInfo, sfAccountId, storagePoolId, DataObjectType.TEMPLATE);
-
-            long volumeSize = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePoolDao.findById(storagePoolId));
-
-            if (volumeSize > sfVolume.getTotalSize()) {
-                // Expand the volume to include HSR.
-                SolidFireUtil.modifyVolume(sfConnection, sfVolume.getId(), volumeSize, getVolumeAttributes(volumeInfo),
-                        sfVolume.getMinIops(), sfVolume.getMaxIops(), sfVolume.getBurstIops());
-
-                // Get the SolidFire volume from the SAN again because we just updated its size.
-                sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolume.getId());
-            }
-        }
-        else {
-            sfVolume = createSolidFireVolume(sfConnection, volumeInfo, storagePoolId, sfAccountId);
-        }
-
-        String iqn = sfVolume.getIqn();
-
-        VolumeVO volume = volumeDao.findById(volumeInfo.getId());
-
-        volume.set_iScsiName(iqn);
-        volume.setFolder(String.valueOf(sfVolume.getId()));
-        volume.setPoolType(StoragePoolType.IscsiLUN);
-        volume.setPoolId(storagePoolId);
-
-        volumeDao.update(volume.getId(), volume);
-
-        updateVolumeDetails(volume.getId(), sfVolume.getTotalSize(), sfVolume.getScsiNaaDeviceId());
-
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-        long capacityBytes = storagePool.getCapacityBytes();
-        // getUsedBytes(StoragePool) will include the bytes of the newly created volume because
-        // updateVolumeDetails(long, long) has already been called for this volume
-        long usedBytes = getUsedBytes(storagePool);
-
-        storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
-
-        storagePoolDao.update(storagePoolId, storagePool);
-
-        return iqn;
-    }
-
-    private void createTempVolume(SnapshotInfo snapshotInfo, long storagePoolId) {
-        long csSnapshotId = snapshotInfo.getId();
-
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
-
-        if (snapshotDetails == null || snapshotDetails.getValue() == null) {
-            throw new CloudRuntimeException("'createTempVolume(SnapshotInfo, long)' should not be invoked unless " + SolidFireUtil.SNAPSHOT_ID + " exists.");
-        }
-
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-        snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, "tempVolume");
-
-        if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("create")) {
-            long sfAccountId = getCreateSolidFireAccountId(sfConnection, snapshotInfo.getAccountId(), storagePoolId);
-
-            SolidFireUtil.SolidFireVolume sfVolume = createCloneFromSnapshot(sfConnection, csSnapshotId, sfAccountId);
-
-            addTempVolumeId(csSnapshotId, String.valueOf(sfVolume.getId()));
-
-            handleSnapshotDetails(csSnapshotId, DiskTO.IQN, sfVolume.getIqn());
-            handleSnapshotDetails(csSnapshotId, DiskTO.SCSI_NAA_DEVICE_ID, sfVolume.getScsiNaaDeviceId());
-        }
-        else if (snapshotDetails != null && snapshotDetails.getValue() != null && snapshotDetails.getValue().equalsIgnoreCase("delete")) {
-            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
-
-            SolidFireUtil.deleteVolume(sfConnection, Long.parseLong(snapshotDetails.getValue()));
-
-            removeTempVolumeId(csSnapshotId);
-
-            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, DiskTO.IQN);
-
-            snapshotDetailsDao.remove(snapshotDetails.getId());
-
-            snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, DiskTO.SCSI_NAA_DEVICE_ID);
-
-            snapshotDetailsDao.remove(snapshotDetails.getId());
-        }
-        else {
-            throw new CloudRuntimeException("Invalid state in 'createTempVolume(SnapshotInfo, long)'");
-        }
-    }
-
-    private String createTemplateVolume(TemplateInfo templateInfo, long storagePoolId) {
-        verifySufficientBytesForStoragePool(templateInfo, storagePoolId);
-
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-        long sfAccountId = getCreateSolidFireAccountId(sfConnection, templateInfo.getAccountId(), storagePoolId);
-
-        SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, templateInfo, storagePoolId, sfAccountId);
-
-        String iqn = sfVolume.getIqn();
-
-        VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId());
-
-        templatePoolRef.setInstallPath(iqn);
-        templatePoolRef.setLocalDownloadPath(Long.toString(sfVolume.getId()));
-        templatePoolRef.setTemplateSize(sfVolume.getTotalSize());
-
-        tmpltPoolDao.update(templatePoolRef.getId(), templatePoolRef);
-
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-        long capacityBytes = storagePool.getCapacityBytes();
-        // getUsedBytes(StoragePool) will include the bytes of the newly created template volume because
-        // _tmpltPoolDao.update(Long, VMTemplateStoragePoolVO) has already been invoked
-        long usedBytes = getUsedBytes(storagePool);
-
-        storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes);
-
-        storagePoolDao.update(storagePoolId, storagePool);
-
-        return iqn;
-    }
-
-    private void performBasicDelete(SolidFireUtil.SolidFireConnection sfConnection, long volumeId) {
-        Long sfVolumeId = getBasicSfVolumeId(volumeId);
-
-        Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null'.");
-
-        String iqn = getBasicIqn(volumeId);
-
-        Preconditions.checkNotNull(iqn, "'iqn' should not be 'null'.");
-
-        VolumeVO volumeVO = volumeDao.findById(volumeId);
-
-        deleteSolidFireVolume(sfConnection, volumeId, Long.parseLong(volumeVO.getFolder()));
-
-        volumeVO.setFolder(String.valueOf(sfVolumeId));
-        volumeVO.set_iScsiName(iqn);
-
-        volumeDao.update(volumeId, volumeVO);
-
-        volumeDetailsDao.removeDetail(volumeId, BASIC_SF_ID);
-        volumeDetailsDao.removeDetail(volumeId, BASIC_IQN);
-        volumeDetailsDao.removeDetail(volumeId, BASIC_DELETE);
-    }
-
-    private void performBasicDeleteFailure(SolidFireUtil.SolidFireConnection sfConnection, long volumeId) {
-        Long sfVolumeId = getBasicSfVolumeId(volumeId);
-
-        Preconditions.checkNotNull(sfVolumeId, "'sfVolumeId' should not be 'null'.");
-
-        SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
-
-        volumeDetailsDao.removeDetail(volumeId, BASIC_SF_ID);
-        volumeDetailsDao.removeDetail(volumeId, BASIC_IQN);
-        volumeDetailsDao.removeDetail(volumeId, BASIC_DELETE_FAILURE);
-    }
-
-    private void deleteVolume(VolumeInfo volumeInfo, long storagePoolId) {
-        try {
-            long volumeId = volumeInfo.getId();
-
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-            if (isBasicDelete(volumeId)) {
-                performBasicDelete(sfConnection, volumeId);
-            }
-            else if (isBasicDeleteFailure(volumeId)) {
-                performBasicDeleteFailure(sfConnection, volumeId);
-            }
-            else {
-                deleteSolidFireVolume(sfConnection, volumeInfo);
-
-                volumeDetailsDao.removeDetails(volumeId);
-
-                StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-                long usedBytes = getUsedBytes(storagePool, volumeId);
-
-                storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
-
-                storagePoolDao.update(storagePoolId, storagePool);
-            }
-        }
-        catch (Exception ex) {
-            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to delete SolidFire volume. CloudStack volume ID: " + volumeInfo.getId(), ex);
-
-            throw ex;
-        }
-    }
-
-    private void deleteSnapshot(SnapshotInfo snapshotInfo, long storagePoolId) {
-        long csSnapshotId = snapshotInfo.getId();
-
-        try {
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.SNAPSHOT_ID);
-
-            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-                // A SolidFire snapshot is being used to support the CloudStack volume snapshot.
-
-                long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
-
-                deleteSolidFireSnapshot(sfConnection, csSnapshotId, sfSnapshotId);
-            }
-            else {
-                // A SolidFire volume is being used to support the CloudStack volume snapshot.
-
-                snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.VOLUME_ID);
-
-                long sfVolumeId = Long.parseLong(snapshotDetails.getValue());
-
-                SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
-            }
-
-            snapshotDetailsDao.removeDetails(csSnapshotId);
-
-            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-            // getUsedBytes(StoragePool) will not include the snapshot to delete because it has already been deleted by this point
-            long usedBytes = getUsedBytes(storagePool);
-
-            storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
-
-            storagePoolDao.update(storagePoolId, storagePool);
-        }
-        catch (Exception ex) {
-            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Issue in 'deleteSnapshot(SnapshotInfo, long)'. CloudStack snapshot ID: " + csSnapshotId, ex);
-
-            throw ex;
-        }
-    }
-
-    private void deleteTemplate(TemplateInfo template, long storagePoolId) {
-        try {
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-
-            long sfTemplateVolumeId = getVolumeIdFrom_iScsiPath(template.getInstallPath());
-
-            SolidFireUtil.deleteVolume(sfConnection, sfTemplateVolumeId);
-
-            StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-            // getUsedBytes(StoragePool) will not include the template to delete because the "template_spool_ref" table has already been updated by this point
-            long usedBytes = getUsedBytes(storagePool);
-
-            storagePool.setUsedBytes(usedBytes < 0 ? 0 : usedBytes);
-
-            storagePoolDao.update(storagePoolId, storagePool);
-        }
-        catch (Exception ex) {
-            LOGGER.debug(SolidFireUtil.LOG_PREFIX + "Failed to delete SolidFire template volume. CloudStack template ID: " + template.getId(), ex);
-
-            throw ex;
-        }
-    }
-
-    @Override
-    public void revertSnapshot(SnapshotInfo snapshot, SnapshotInfo snapshot2, AsyncCompletionCallback<CommandResult> callback) {
-        VolumeInfo volumeInfo = snapshot.getBaseVolume();
-
-        VolumeVO volumeVO = volumeDao.findById(volumeInfo.getId());
-
-        if (volumeVO == null || volumeVO.getRemoved() != null) {
-            String errMsg = "The volume that the snapshot belongs to no longer exists.";
-
-            CommandResult commandResult = new CommandResult();
-
-            commandResult.setResult(errMsg);
-
-            callback.complete(commandResult);
-
-            return;
-        }
-
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(volumeVO.getPoolId(), storagePoolDetailsDao);
-
-        long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
-
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.SNAPSHOT_ID);
-
-        long sfSnapshotId = Long.parseLong(snapshotDetails.getValue());
-
-        SolidFireUtil.rollBackVolumeToSnapshot(sfConnection, sfVolumeId, sfSnapshotId);
-
-        SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
-
-        updateVolumeDetails(volumeVO.getId(), sfVolume.getTotalSize(), sfVolume.getScsiNaaDeviceId());
-
-        CommandResult commandResult = new CommandResult();
-
-        callback.complete(commandResult);
-    }
-
-    @Override
-    public void resize(DataObject dataObject, AsyncCompletionCallback<CreateCmdResult> callback) {
-        String iqn = null;
-        String errMsg = null;
-
-        try {
-            if (dataObject.getType() == DataObjectType.VOLUME) {
-                VolumeInfo volumeInfo = (VolumeInfo)dataObject;
-
-                iqn = volumeInfo.get_iScsiName();
-
-                long storagePoolId = volumeInfo.getPoolId();
-                long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
-
-                ResizeVolumePayload payload = (ResizeVolumePayload)volumeInfo.getpayload();
-
-                SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, storagePoolDetailsDao);
-                SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
-
-                long newMinIops = payload.newMinIops != null ? payload.newMinIops : sfVolume.getMinIops();
-
-                verifySufficientIopsForStoragePool(storagePoolId, sfVolume, newMinIops);
-
-                long newSize = payload.newSize != null ? payload.newSize : volumeInfo.getSize();
-
-                verifySufficientBytesForStoragePool(storagePoolId, volumeInfo.getId(), newSize, payload.newHypervisorSnapshotReserve);
-
-                long sfNewVolumeSize = sfVolume.getTotalSize();
-
-                Integer hsr = volumeInfo.getHypervisorSnapshotReserve();
-
-                if (payload.newSize != null || payload.newHypervisorSnapshotReserve != null) {
-                    if (payload.newHypervisorSnapshotReserve != null) {
-                        if (hsr != null) {
-                            if (payload.newHypervisorSnapshotReserve > hsr) {
-                                hsr = payload.newHypervisorSnapshotReserve;
-                            }
-                        } else {
-                            hsr = payload.newHypervisorSnapshotReserve;
-                        }
-                    }
-
-                    sfNewVolumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(newSize, hsr);
-                }
-
-                Map<String, String> mapAttributes = new HashMap<>();
-
-                mapAttributes.put(SolidFireUtil.CloudStackVolumeId, String.valueOf(volumeInfo.getId()));
-                mapAttributes.put(SolidFireUtil.CloudStackVolumeSize, NumberFormat.getInstance().format(payload.newSize));
-
-                long newMaxIops = payload.newMaxIops != null ? payload.newMaxIops : sfVolume.getMaxIops();
-
-                SolidFireUtil.modifyVolume(sfConnection, sfVolumeId, sfNewVolumeSize, mapAttributes,
-                        newMinIops, newMaxIops, getDefaultBurstIops(storagePoolId, newMaxIops));
-
-                VolumeVO volume = volumeDao.findById(volumeInfo.getId());
-
-                volume.setMinIops(newMinIops);
-                volume.setMaxIops(newMaxIops);
-                volume.setHypervisorSnapshotReserve(hsr);
-
-                volumeDao.update(volume.getId(), volume);
-
-                // SolidFireUtil.VOLUME_SIZE was introduced in 4.5.
-                updateVolumeDetails(volume.getId(), sfNewVolumeSize, sfVolume.getScsiNaaDeviceId());
-            } else {
-                errMsg = "Invalid DataObjectType (" + dataObject.getType() + ") passed to resize";
-            }
-        }
-        catch (Exception ex) {
-            errMsg = ex.getMessage();
-        }
-        finally {
-            CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errMsg == null, errMsg));
-
-            result.setResult(errMsg);
-
-            callback.complete(result);
-        }
-    }
-
-    private void verifySufficientBytesForStoragePool(long requestedBytes, long storagePoolId) {
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-        long capacityBytes = storagePool.getCapacityBytes();
-        long usedBytes = getUsedBytes(storagePool);
-
-        usedBytes += requestedBytes;
-
-        if (usedBytes > capacityBytes) {
-            throw new CloudRuntimeException("Insufficient amount of space remains in this primary storage");
-        }
-    }
-
-    private void verifySufficientBytesForStoragePool(DataObject dataObject, long storagePoolId) {
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-        long requestedBytes = getDataObjectSizeIncludingHypervisorSnapshotReserve(dataObject, storagePool);
-
-        verifySufficientBytesForStoragePool(requestedBytes, storagePoolId);
-    }
-
-    private void verifySufficientBytesForStoragePool(long storagePoolId, long volumeId, long newSize, Integer newHypervisorSnapshotReserve) {
-        DataStore primaryDataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-        VolumeInfo volumeInfo = volumeFactory.getVolume(volumeId, primaryDataStore);
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-        long currentSizeWithHsr = getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, storagePool);
-
-        newHypervisorSnapshotReserve = newHypervisorSnapshotReserve == null ? LOWEST_HYPERVISOR_SNAPSHOT_RESERVE :
-                Math.max(newHypervisorSnapshotReserve, LOWEST_HYPERVISOR_SNAPSHOT_RESERVE);
-
-        long newSizeWithHsr = (long)(newSize + newSize * (newHypervisorSnapshotReserve / 100f));
-
-        if (newSizeWithHsr < currentSizeWithHsr) {
-            throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not support shrinking a volume.");
-        }
-
-        long availableBytes = storagePool.getCapacityBytes() - getUsedBytes(storagePool);
-
-        if ((newSizeWithHsr - currentSizeWithHsr) > availableBytes) {
-            throw new CloudRuntimeException("Storage pool " + storagePoolId + " does not have enough space to expand the volume.");
-        }
-    }
-
-    private void verifySufficientIopsForStoragePool(long requestedIops, long storagePoolId) {
-        StoragePoolVO storagePool = storagePoolDao.findById(storagePoolId);
-
-        long usedIops = getUsedIops(storagePool);
-        long capacityIops = storagePool.getCapacityIops();
-
-        if (usedIops + requestedIops > capacityIops) {
-            throw new CloudRuntimeException("Insufficient number of IOPS available in this storage pool");
-        }
-    }
-
-    private void verifySufficientIopsForStoragePool(long storagePoolId, SolidFireUtil.SolidFireVolume sfVolume, long newMinIops) {
-        long currentMinIops = sfVolume.getMinIops();
-        long diffInMinIops = newMinIops - currentMinIops;
-
-        // if the desire is for more IOPS
-        if (diffInMinIops > 0) {
-            verifySufficientIopsForStoragePool(diffInMinIops, storagePoolId);
-        }
-    }
-
-    private void deleteSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, long csVolumeId, long sfVolumeId) {
-        List<SnapshotVO> lstSnapshots = getNonDestroyedSnapshots(csVolumeId);
-
-        boolean deleteVolume = true;
-
-        for (SnapshotVO snapshot : lstSnapshots) {
-            SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(snapshot.getId(), SolidFireUtil.SNAPSHOT_ID);
-
-            if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-                deleteVolume = false;
-
-                break;
-            }
-        }
-
-        if (deleteVolume) {
-            SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
-        }
-    }
-
-    private void deleteSolidFireSnapshot(SolidFireUtil.SolidFireConnection sfConnection, long csSnapshotId, long sfSnapshotId) {
-        SolidFireUtil.deleteSnapshot(sfConnection, sfSnapshotId);
-
-        final long volumeId;
-        final VolumeVO volume;
-
-        SnapshotVO snapshot = snapshotDao.findById(csSnapshotId);
-        SnapshotDetailsVO snapshotDetails = snapshotDetailsDao.findDetail(csSnapshotId, SolidFireUtil.ORIG_CS_VOLUME_ID);
-
-        if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-            volumeId = Long.valueOf(snapshotDetails.getValue());
-        }
-        else {
-            volumeId = snapshot.getVolumeId();
-        }
-
-        volume = volumeDao.findById(volumeId);
-
-        if (volume == null) { // if the CloudStack volume has been deleted
-            List<SnapshotVO> lstSnapshots = getNonDestroyedSnapshots(snapshot.getVolumeId());
-
-            List<SnapshotVO> lstSnapshots2 = new ArrayList<>();
-
-            for (SnapshotVO snapshotVo : lstSnapshots) {
-                // The CloudStack volume snapshot has not yet been set to the DESTROYED state, so check to make
-                // sure snapshotVo.getId() != csSnapshotId when determining if any volume snapshots remain for the given CloudStack volume.
-                if (snapshotVo.getId() != csSnapshotId) {
-                    snapshotDetails = snapshotDetailsDao.findDetail(snapshotVo.getId(), SolidFireUtil.SNAPSHOT_ID);
-
-                    // We are only interested here in volume snapshots that make use of SolidFire snapshots (as opposed to ones
-                    // that make use of SolidFire volumes).
-                    if (snapshotDetails != null && snapshotDetails.getValue() != null) {
-                        lstSnapshots2.add(snapshotVo);
-                    }
-                }
-            }
-
-            if (lstSnapshots2.isEmpty()) {
-                VolumeVO volumeToDelete = volumeDao.findByIdIncludingRemoved(volumeId);
-
-                SolidFireUtil.deleteVolume(sfConnection, Long.parseLong(volumeToDelete.getFolder()));
-            }
-        }
-    }
-
-    private List<SnapshotVO> getNonDestroyedSnapshots(long csVolumeId) {
-        List<SnapshotVO> lstSnapshots = snapshotDao.listByVolumeId(csVolumeId);
-
-        if (lstSnapshots == null) {
-            lstSnapshots = new ArrayList<>();
-        }
-
-        List<SnapshotVO> lstSnapshots2 = new ArrayList<>();
-
-        for (SnapshotVO snapshot : lstSnapshots) {
-            if (!State.Destroyed.equals(snapshot.getState())) {
-                lstSnapshots2.add(snapshot);
-            }
-        }
-
-        return lstSnapshots2;
-    }
-}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
deleted file mode 100644
index 3172b1a..0000000
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.lifecycle;
-
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
-import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CreateStoragePoolCommand;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolAutomation;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountDetailsDao;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class SolidFireSharedPrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeCycle {
-    private static final Logger s_logger = Logger.getLogger(SolidFireSharedPrimaryDataStoreLifeCycle.class);
-
-    @Inject private AccountDao _accountDao;
-    @Inject private AccountDetailsDao _accountDetailsDao;
-    @Inject private AgentManager _agentMgr;
-    @Inject private ClusterDao _clusterDao;
-    @Inject private ClusterDetailsDao _clusterDetailsDao;
-    @Inject private DataCenterDao _zoneDao;
-    @Inject private HostDao _hostDao;
-    @Inject private PrimaryDataStoreDao _primaryDataStoreDao;
-    @Inject private PrimaryDataStoreHelper _primaryDataStoreHelper;
-    @Inject private ResourceManager _resourceMgr;
-    @Inject private StorageManager _storageMgr;
-    @Inject private StoragePoolAutomation _storagePoolAutomation;
-    @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject private StoragePoolHostDao _storagePoolHostDao;
-    @Inject private TemplateManager _tmpltMgr;
-
-    // invoked to add primary storage that is based on the SolidFire plug-in
-    @Override
-    public DataStore initialize(Map<String, Object> dsInfos) {
-        final String CAPACITY_IOPS = "capacityIops";
-
-        String url = (String)dsInfos.get("url");
-        Long zoneId = (Long)dsInfos.get("zoneId");
-        Long podId = (Long)dsInfos.get("podId");
-        Long clusterId = (Long)dsInfos.get("clusterId");
-        String storagePoolName = (String)dsInfos.get("name");
-        String providerName = (String)dsInfos.get("providerName");
-        Long capacityBytes = (Long)dsInfos.get("capacityBytes");
-        Long capacityIops = (Long)dsInfos.get(CAPACITY_IOPS);
-        String tags = (String)dsInfos.get("tags");
-        @SuppressWarnings("unchecked")
-        Map<String, String> details = (Map<String, String>)dsInfos.get("details");
-
-        if (podId == null) {
-            throw new CloudRuntimeException("The Pod ID must be specified.");
-        }
-
-        if (clusterId == null) {
-            throw new CloudRuntimeException("The Cluster ID must be specified.");
-        }
-
-        String storageVip = SolidFireUtil.getStorageVip(url);
-        int storagePort = SolidFireUtil.getStoragePort(url);
-
-        if (capacityBytes == null || capacityBytes <= 0) {
-            throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0.");
-        }
-
-        if (capacityIops == null || capacityIops <= 0) {
-            throw new IllegalArgumentException("'capacityIops' must be present and greater than 0.");
-        }
-
-        HypervisorType hypervisorType = getHypervisorTypeForCluster(clusterId);
-
-        if (!isSupportedHypervisorType(hypervisorType)) {
-            throw new CloudRuntimeException(hypervisorType + " is not a supported hypervisor type.");
-        }
-
-        String datacenter = SolidFireUtil.getValue(SolidFireUtil.DATACENTER, url, false);
-
-        if (HypervisorType.VMware.equals(hypervisorType) && datacenter == null) {
-            throw new CloudRuntimeException("'Datacenter' must be set for hypervisor type of " + HypervisorType.VMware);
-        }
-
-        PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
-
-        parameters.setType(getStorageType(hypervisorType));
-        parameters.setZoneId(zoneId);
-        parameters.setPodId(podId);
-        parameters.setClusterId(clusterId);
-        parameters.setName(storagePoolName);
-        parameters.setProviderName(providerName);
-        parameters.setManaged(false);
-        parameters.setCapacityBytes(capacityBytes);
-        parameters.setUsedBytes(0);
-        parameters.setCapacityIops(capacityIops);
-        parameters.setHypervisorType(hypervisorType);
-        parameters.setTags(tags);
-        parameters.setDetails(details);
-
-        String managementVip = SolidFireUtil.getManagementVip(url);
-        int managementPort = SolidFireUtil.getManagementPort(url);
-
-        details.put(SolidFireUtil.MANAGEMENT_VIP, managementVip);
-        details.put(SolidFireUtil.MANAGEMENT_PORT, String.valueOf(managementPort));
-
-        String clusterAdminUsername = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_USERNAME, url);
-        String clusterAdminPassword = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, url);
-
-        details.put(SolidFireUtil.CLUSTER_ADMIN_USERNAME, clusterAdminUsername);
-        details.put(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, clusterAdminPassword);
-
-        if (capacityBytes < SolidFireUtil.MIN_VOLUME_SIZE) {
-            capacityBytes = SolidFireUtil.MIN_VOLUME_SIZE;
-        }
-
-        long lMinIops = 100;
-        long lMaxIops = 15000;
-        long lBurstIops = 15000;
-
-        try {
-            String minIops = SolidFireUtil.getValue(SolidFireUtil.MIN_IOPS, url);
-
-            if (minIops != null && minIops.trim().length() > 0) {
-                lMinIops = Long.parseLong(minIops);
-            }
-        } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Min IOPS: " + ex.getLocalizedMessage());
-        }
-
-        try {
-            String maxIops = SolidFireUtil.getValue(SolidFireUtil.MAX_IOPS, url);
-
-            if (maxIops != null && maxIops.trim().length() > 0) {
-                lMaxIops = Long.parseLong(maxIops);
-            }
-        } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Max IOPS: " + ex.getLocalizedMessage());
-        }
-
-        try {
-            String burstIops = SolidFireUtil.getValue(SolidFireUtil.BURST_IOPS, url);
-
-            if (burstIops != null && burstIops.trim().length() > 0) {
-                lBurstIops = Long.parseLong(burstIops);
-            }
-        } catch (Exception ex) {
-            s_logger.info("[ignored] error getting Burst IOPS: " + ex.getLocalizedMessage());
-        }
-
-        if (lMinIops > lMaxIops) {
-            throw new CloudRuntimeException("The parameter '" + SolidFireUtil.MIN_IOPS + "' must be less than or equal to the parameter '" + SolidFireUtil.MAX_IOPS + "'.");
-        }
-
-        if (lMaxIops > lBurstIops) {
-            throw new CloudRuntimeException("The parameter '" + SolidFireUtil.MAX_IOPS + "' must be less than or equal to the parameter '" + SolidFireUtil.BURST_IOPS + "'.");
-        }
-
-        if (lMinIops != capacityIops) {
-            throw new CloudRuntimeException("The parameter '" + CAPACITY_IOPS + "' must be equal to the parameter '" + SolidFireUtil.MIN_IOPS + "'.");
-        }
-
-        if (lMinIops > SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) {
-            throw new CloudRuntimeException("This volume's Min IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) + " IOPS.");
-        }
-
-        if (lMaxIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
-            throw new CloudRuntimeException("This volume's Max IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_IOPS_PER_VOLUME) + " IOPS.");
-        }
-
-        if (lBurstIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
-            throw new CloudRuntimeException("This volume's Burst IOPS cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_IOPS_PER_VOLUME) + " IOPS.");
-        }
-
-        details.put(SolidFireUtil.MIN_IOPS, String.valueOf(lMinIops));
-        details.put(SolidFireUtil.MAX_IOPS, String.valueOf(lMaxIops));
-        details.put(SolidFireUtil.BURST_IOPS, String.valueOf(lBurstIops));
-
-        SolidFireUtil.SolidFireConnection sfConnection = new SolidFireUtil.SolidFireConnection(managementVip, managementPort, clusterAdminUsername, clusterAdminPassword);
-
-        SolidFireCreateVolume sfCreateVolume = createSolidFireVolume(sfConnection, storagePoolName, capacityBytes, lMinIops, lMaxIops, lBurstIops);
-
-        SolidFireUtil.SolidFireVolume sfVolume = sfCreateVolume.getVolume();
-
-        String iqn = sfVolume.getIqn();
-
-        details.put(SolidFireUtil.VOLUME_ID, String.valueOf(sfVolume.getId()));
-
-        parameters.setUuid(iqn);
-
-        if (HypervisorType.VMware.equals(hypervisorType)) {
-            String datastore = iqn.replace("/", "_");
-            String path = "/" + datacenter + "/" + datastore;
-
-            parameters.setHost("VMFS datastore: " + path);
-            parameters.setPort(0);
-            parameters.setPath(path);
-
-            details.put(SolidFireUtil.DATASTORE_NAME, datastore);
-            details.put(SolidFireUtil.IQN, iqn);
-            details.put(SolidFireUtil.STORAGE_VIP, storageVip);
-            details.put(SolidFireUtil.STORAGE_PORT, String.valueOf(storagePort));
-        }
-        else {
-            parameters.setHost(storageVip);
-            parameters.setPort(storagePort);
-            parameters.setPath(iqn);
-        }
-
-        ClusterVO cluster = _clusterDao.findById(clusterId);
-
-        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
-
-        if (!lock.lock(SolidFireUtil.s_lockTimeInSeconds)) {
-            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
-
-            s_logger.debug(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        DataStore dataStore = null;
-
-        try {
-            // this adds a row in the cloud.storage_pool table for this SolidFire volume
-            dataStore = _primaryDataStoreHelper.createPrimaryDataStore(parameters);
-
-            // now that we have a DataStore (we need the id from the DataStore instance), we can create a Volume Access Group, if need be, and
-            // place the newly created volume in the Volume Access Group
-            List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
-
-            SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolume.getId(), dataStore.getId(), cluster.getUuid(), hosts, _clusterDetailsDao);
-
-            SolidFireUtil.SolidFireAccount sfAccount = sfCreateVolume.getAccount();
-            Account csAccount = CallContext.current().getCallingAccount();
-
-            SolidFireUtil.updateCsDbWithSolidFireAccountInfo(csAccount.getId(), sfAccount, dataStore.getId(), _accountDetailsDao);
-        } catch (Exception ex) {
-            if (dataStore != null) {
-                _primaryDataStoreDao.expunge(dataStore.getId());
-            }
-
-            throw new CloudRuntimeException(ex.getMessage());
-        }
-        finally {
-            lock.unlock();
-            lock.releaseRef();
-        }
-
-        return dataStore;
-    }
-
-    private HypervisorType getHypervisorTypeForCluster(long clusterId) {
-        ClusterVO cluster = _clusterDao.findById(clusterId);
-
-        if (cluster == null) {
-            throw new CloudRuntimeException("Cluster ID '" + clusterId + "' was not found in the database.");
-        }
-
-        return cluster.getHypervisorType();
-    }
-
-    private StoragePoolType getStorageType(HypervisorType hypervisorType) {
-        if (HypervisorType.XenServer.equals(hypervisorType)) {
-            return StoragePoolType.IscsiLUN;
-        }
-
-        if (HypervisorType.VMware.equals(hypervisorType)) {
-            return StoragePoolType.VMFS;
-        }
-
-        throw new CloudRuntimeException("The 'hypervisor' parameter must be '" + HypervisorType.XenServer + "' or '" + HypervisorType.VMware + "'.");
-    }
-
-    private class SolidFireCreateVolume {
-        private final SolidFireUtil.SolidFireVolume _sfVolume;
-        private final SolidFireUtil.SolidFireAccount _sfAccount;
-
-        SolidFireCreateVolume(SolidFireUtil.SolidFireVolume sfVolume, SolidFireUtil.SolidFireAccount sfAccount) {
-            _sfVolume = sfVolume;
-            _sfAccount = sfAccount;
-        }
-
-        public SolidFireUtil.SolidFireVolume getVolume() {
-            return _sfVolume;
-        }
-
-        public SolidFireUtil.SolidFireAccount getAccount() {
-            return _sfAccount;
-        }
-    }
-
-    private SolidFireCreateVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection,
-            String volumeName, long volumeSize, long minIops, long maxIops, long burstIops) {
-        try {
-            Account csAccount = CallContext.current().getCallingAccount();
-            long csAccountId = csAccount.getId();
-            AccountVO accountVo = _accountDao.findById(csAccountId);
-
-            String sfAccountName = SolidFireUtil.getSolidFireAccountName(accountVo.getUuid(), csAccountId);
-
-            SolidFireUtil.SolidFireAccount sfAccount = SolidFireUtil.getAccount(sfConnection, sfAccountName);
-
-            if (sfAccount == null) {
-                long sfAccountNumber = SolidFireUtil.createAccount(sfConnection, sfAccountName);
-
-                sfAccount = SolidFireUtil.getAccountById(sfConnection, sfAccountNumber);
-            }
-
-            long sfVolumeId = SolidFireUtil.createVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeName), sfAccount.getId(), volumeSize,
-                    true, null, minIops, maxIops, burstIops);
-            SolidFireUtil.SolidFireVolume sfVolume = SolidFireUtil.getVolume(sfConnection, sfVolumeId);
-
-            return new SolidFireCreateVolume(sfVolume, sfAccount);
-        } catch (Throwable e) {
-            throw new CloudRuntimeException("Failed to create a SolidFire volume: " + e.toString());
-        }
-    }
-
-    @Override
-    public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
-        return true;
-    }
-
-    @Override
-    public boolean attachCluster(DataStore store, ClusterScope scope) {
-        PrimaryDataStoreInfo primaryDataStoreInfo = (PrimaryDataStoreInfo)store;
-
-        // check if there is at least one host up in this cluster
-        List<HostVO> allHosts = _resourceMgr.listAllUpHosts(Host.Type.Routing, primaryDataStoreInfo.getClusterId(),
-                primaryDataStoreInfo.getPodId(), primaryDataStoreInfo.getDataCenterId());
-
-        if (allHosts.isEmpty()) {
-            _primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
-
-            throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + primaryDataStoreInfo.getClusterId());
-        }
-
-        boolean success = false;
-
-        for (HostVO host : allHosts) {
-            success = createStoragePool(host, primaryDataStoreInfo);
-
-            if (success) {
-                break;
-            }
-        }
-
-        if (!success) {
-            throw new CloudRuntimeException("Unable to create storage in cluster " + primaryDataStoreInfo.getClusterId());
-        }
-
-        List<HostVO> poolHosts = new ArrayList<>();
-
-        for (HostVO host : allHosts) {
-            try {
-                _storageMgr.connectHostToSharedPool(host.getId(), primaryDataStoreInfo.getId());
-
-                poolHosts.add(host);
-            } catch (Exception e) {
-                s_logger.warn("Unable to establish a connection between " + host + " and " + primaryDataStoreInfo, e);
-            }
-        }
-
-        if (poolHosts.isEmpty()) {
-            s_logger.warn("No host can access storage pool '" + primaryDataStoreInfo + "' on cluster '" + primaryDataStoreInfo.getClusterId() + "'.");
-
-            _primaryDataStoreDao.expunge(primaryDataStoreInfo.getId());
-
-            throw new CloudRuntimeException("Failed to access storage pool");
-        }
-
-        _primaryDataStoreHelper.attachCluster(store);
-
-        return true;
-    }
-
-    private boolean createStoragePool(HostVO host, StoragePool storagePool) {
-        long hostId = host.getId();
-        HypervisorType hypervisorType = host.getHypervisorType();
-        CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, storagePool);
-
-        if (HypervisorType.VMware.equals(hypervisorType)) {
-            cmd.setCreateDatastore(true);
-
-            Map<String, String> details = new HashMap<>();
-
-            StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
-
-            details.put(CreateStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
-
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
-
-            details.put(CreateStoragePoolCommand.IQN, storagePoolDetail.getValue());
-
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
-
-            details.put(CreateStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
-
-            storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
-
-            details.put(CreateStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
-
-            cmd.setDetails(details);
-        }
-
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer != null && answer.getResult()) {
-            return true;
-        } else {
-            _primaryDataStoreDao.expunge(storagePool.getId());
-
-            final String msg;
-
-            if (answer != null) {
-                msg = "Cannot create storage pool through host '" + hostId + "' due to the following: " + answer.getDetails();
-            } else {
-                msg = "Cannot create storage pool through host '" + hostId + "' due to CreateStoragePoolCommand returns null";
-            }
-
-            s_logger.warn(msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    @Override
-    public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) {
-        return true;
-    }
-
-    @Override
-    public boolean maintain(DataStore dataStore) {
-        _storagePoolAutomation.maintain(dataStore);
-        _primaryDataStoreHelper.maintain(dataStore);
-
-        return true;
-    }
-
-    @Override
-    public boolean cancelMaintain(DataStore store) {
-        _primaryDataStoreHelper.cancelMaintain(store);
-        _storagePoolAutomation.cancelMaintain(store);
-
-        return true;
-    }
-
-    // invoked to delete primary storage that is based on the SolidFire plug-in
-    @Override
-    public boolean deleteDataStore(DataStore dataStore) {
-        List<StoragePoolHostVO> hostPoolRecords = _storagePoolHostDao.listByPoolId(dataStore.getId());
-
-        HypervisorType hypervisorType = null;
-
-        if (hostPoolRecords.size() > 0 ) {
-            hypervisorType = getHypervisorType(hostPoolRecords.get(0).getHostId());
-        }
-
-        if (!isSupportedHypervisorType(hypervisorType)) {
-            throw new CloudRuntimeException(hypervisorType + " is not a supported hypervisor type.");
-        }
-
-        StoragePool storagePool = (StoragePool)dataStore;
-        StoragePoolVO storagePoolVO = _primaryDataStoreDao.findById(storagePool.getId());
-        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(storagePoolVO);
-
-        for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
-            _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
-        }
-
-        Long clusterId = null;
-        Long hostId = null;
-
-        for (StoragePoolHostVO host : hostPoolRecords) {
-            DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(storagePool);
-
-            if (HypervisorType.VMware.equals(hypervisorType)) {
-                deleteCmd.setRemoveDatastore(true);
-
-                Map<String, String> details = new HashMap<>();
-
-                StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.DATASTORE_NAME);
-
-                details.put(DeleteStoragePoolCommand.DATASTORE_NAME, storagePoolDetail.getValue());
-
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.IQN);
-
-                details.put(DeleteStoragePoolCommand.IQN, storagePoolDetail.getValue());
-
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_VIP);
-
-                details.put(DeleteStoragePoolCommand.STORAGE_HOST, storagePoolDetail.getValue());
-
-                storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePool.getId(), SolidFireUtil.STORAGE_PORT);
-
-                details.put(DeleteStoragePoolCommand.STORAGE_PORT, storagePoolDetail.getValue());
-
-                deleteCmd.setDetails(details);
-            }
-
-            final Answer answer = _agentMgr.easySend(host.getHostId(), deleteCmd);
-
-            if (answer != null && answer.getResult()) {
-                s_logger.info("Successfully deleted storage pool using Host ID " + host.getHostId());
-
-                HostVO hostVO = _hostDao.findById(host.getHostId());
-
-                if (hostVO != null) {
-                    clusterId = hostVO.getClusterId();
-                    hostId = hostVO.getId();
-                }
-
-                break;
-            }
-            else {
-                if (answer != null) {
-                    s_logger.error("Failed to delete storage pool using Host ID " + host.getHostId() + ": " + answer.getResult());
-                }
-                else {
-                    s_logger.error("Failed to delete storage pool using Host ID " + host.getHostId());
-                }
-            }
-        }
-
-        if (clusterId != null) {
-            ClusterVO cluster = _clusterDao.findById(clusterId);
-
-            GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
-
-            if (!lock.lock(SolidFireUtil.s_lockTimeInSeconds)) {
-                String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
-
-                s_logger.debug(errMsg);
-
-                throw new CloudRuntimeException(errMsg);
-            }
-
-            try {
-                removeVolumeFromVag(storagePool.getId(), clusterId);
-            }
-            finally {
-                lock.unlock();
-                lock.releaseRef();
-            }
-        }
-
-        if (hostId != null) {
-            handleTargetsForVMware(hostId, storagePool.getId());
-        }
-
-        deleteSolidFireVolume(storagePool.getId());
-
-        return _primaryDataStoreHelper.deletePrimaryDataStore(dataStore);
-    }
-
-    private void handleTargetsForVMware(long hostId, long storagePoolId) {
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host.getHypervisorType() == HypervisorType.VMware) {
-            String storageAddress = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP).getValue();
-            int storagePort = Integer.parseInt(_storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT).getValue());
-            String iqn = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN).getValue();
-
-            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-            List<Map<String, String>> targets = new ArrayList<>();
-
-            Map<String, String> target = new HashMap<>();
-
-            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
-            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
-            target.put(ModifyTargetsCommand.IQN, iqn);
-
-            targets.add(target);
-
-            cmd.setTargets(targets);
-            cmd.setApplyToAllHostsInCluster(true);
-            cmd.setAdd(false);
-            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-            cmd.setRemoveAsync(true);
-
-            sendModifyTargetsCommand(cmd, hostId);
-        }
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            String msg = "Unable to get an answer to the modify targets command";
-
-            s_logger.warn(msg);
-        }
-        else if (!answer.getResult()) {
-            String msg = "Unable to modify target on the following host: " + hostId;
-
-            s_logger.warn(msg);
-        }
-    }
-
-    private void removeVolumeFromVag(long storagePoolId, long clusterId) {
-        long sfVolumeId = getVolumeId(storagePoolId);
-        ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
-
-        String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-        if (vagId != null) {
-            SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
-
-            SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-            long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
-
-            SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), sfVag.getInitiators(), volumeIds);
-        }
-    }
-
-    private void deleteSolidFireVolume(long storagePoolId) {
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
-
-        long sfVolumeId = getVolumeId(storagePoolId);
-
-        SolidFireUtil.deleteVolume(sfConnection, sfVolumeId);
-    }
-
-    private long getVolumeId(long storagePoolId) {
-        StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.VOLUME_ID);
-
-        String volumeId = storagePoolDetail.getValue();
-
-        return Long.parseLong(volumeId);
-    }
-
-    private long getIopsValue(long storagePoolId, String iopsKey) {
-        StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, iopsKey);
-
-        String iops = storagePoolDetail.getValue();
-
-        return Long.parseLong(iops);
-    }
-
-    private static boolean isSupportedHypervisorType(HypervisorType hypervisorType) {
-        return HypervisorType.XenServer.equals(hypervisorType) || HypervisorType.VMware.equals(hypervisorType);
-    }
-
-    private HypervisorType getHypervisorType(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host != null) {
-            return host.getHypervisorType();
-        }
-
-        return HypervisorType.None;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle#migrateToObjectStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore)
-     */
-    @Override
-    public boolean migrateToObjectStore(DataStore store) {
-        return false;
-    }
-
-    @Override
-    public void updateStoragePool(StoragePool storagePool, Map<String, String> details) {
-        String strCapacityBytes = details.get(PrimaryDataStoreLifeCycle.CAPACITY_BYTES);
-        String strCapacityIops = details.get(PrimaryDataStoreLifeCycle.CAPACITY_IOPS);
-
-        Long capacityBytes = strCapacityBytes != null ? Long.parseLong(strCapacityBytes) : null;
-        Long capacityIops = strCapacityIops != null ? Long.parseLong(strCapacityIops) : null;
-
-        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), _storagePoolDetailsDao);
-
-        long size = capacityBytes != null ? capacityBytes : storagePool.getCapacityBytes();
-
-        long currentMinIops = getIopsValue(storagePool.getId(), SolidFireUtil.MIN_IOPS);
-        long currentMaxIops = getIopsValue(storagePool.getId(), SolidFireUtil.MAX_IOPS);
-        long currentBurstIops = getIopsValue(storagePool.getId(), SolidFireUtil.BURST_IOPS);
-
-        long minIops = currentMinIops;
-        long maxIops = currentMaxIops;
-        long burstIops = currentBurstIops;
-
-        if (capacityIops != null) {
-            if (capacityIops > SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) {
-                throw new CloudRuntimeException("This volume cannot exceed " + NumberFormat.getInstance().format(SolidFireUtil.MAX_MIN_IOPS_PER_VOLUME) + " IOPS.");
-            }
-
-            float maxPercentOfMin = currentMaxIops / (float)currentMinIops;
-            float burstPercentOfMax = currentBurstIops / (float)currentMaxIops;
-
-            minIops = capacityIops;
-            maxIops = (long)(minIops * maxPercentOfMin);
-            burstIops = (long)(maxIops * burstPercentOfMax);
-
-            if (maxIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
-                maxIops = SolidFireUtil.MAX_IOPS_PER_VOLUME;
-            }
-
-            if (burstIops > SolidFireUtil.MAX_IOPS_PER_VOLUME) {
-                burstIops = SolidFireUtil.MAX_IOPS_PER_VOLUME;
-            }
-        }
-
-        SolidFireUtil.modifyVolume(sfConnection, getVolumeId(storagePool.getId()), size, null, minIops, maxIops, burstIops);
-
-        SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), _primaryDataStoreDao, _storagePoolDetailsDao, minIops, maxIops, burstIops);
-    }
-
-    @Override
-    public void enableStoragePool(DataStore dataStore) {
-        _primaryDataStoreHelper.enable(dataStore);
-    }
-
-    @Override
-    public void disableStoragePool(DataStore dataStore) {
-        _primaryDataStoreHelper.disable(dataStore);
-    }
-}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
deleted file mode 100644
index f2a4b79..0000000
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.provider;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ModifyStoragePoolAnswer;
-import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.alert.AlertManager;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class SolidFireHostListener implements HypervisorHostListener {
-    private static final Logger s_logger = Logger.getLogger(SolidFireHostListener.class);
-
-    @Inject private AgentManager _agentMgr;
-    @Inject private AlertManager _alertMgr;
-    @Inject private ClusterDao _clusterDao;
-    @Inject private ClusterDetailsDao _clusterDetailsDao;
-    @Inject private DataStoreManager _dataStoreMgr;
-    @Inject private HostDao _hostDao;
-    @Inject private PrimaryDataStoreDao _storagePoolDao;
-    @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject private StoragePoolHostDao storagePoolHostDao;
-    @Inject private VMInstanceDao _vmDao;
-    @Inject private VolumeDao _volumeDao;
-
-    @Override
-    public boolean hostAdded(long hostId) {
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host == null) {
-            s_logger.error("Failed to add host by SolidFireHostListener as host was not found with id=" + hostId);
-            return false;
-        }
-
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), true, SolidFireUtil.PROVIDER_NAME,
-                _clusterDao, _clusterDetailsDao, _storagePoolDao, _storagePoolDetailsDao, _hostDao);
-
-        handleVMware(host, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
-
-        return true;
-    }
-
-    @Override
-    public boolean hostConnect(long hostId, long storagePoolId) {
-        HostVO host = _hostDao.findById(hostId);
-
-        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
-
-        if (storagePoolHost == null) {
-            storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, "");
-
-            storagePoolHostDao.persist(storagePoolHost);
-        }
-
-        if (host.getHypervisorType().equals(HypervisorType.XenServer)) {
-            handleXenServer(host.getClusterId(), host.getId(), storagePoolId);
-        }
-        else if (host.getHypervisorType().equals(HypervisorType.KVM)) {
-            handleKVM(hostId, storagePoolId);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean hostDisconnected(long hostId, long storagePoolId) {
-        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
-
-        if (storagePoolHost != null) {
-            storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean hostAboutToBeRemoved(long hostId) {
-        return true;
-    }
-
-    @Override
-    public boolean hostRemoved(long hostId, long clusterId) {
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, clusterId, false, SolidFireUtil.PROVIDER_NAME,
-                _clusterDao, _clusterDetailsDao, _storagePoolDao, _storagePoolDetailsDao, _hostDao);
-
-        HostVO host = _hostDao.findById(hostId);
-
-        handleVMware(host, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
-
-        return true;
-    }
-
-    private void handleXenServer(long clusterId, long hostId, long storagePoolId) {
-        List<String> storagePaths = getStoragePaths(clusterId, storagePoolId);
-
-        StoragePool storagePool = (StoragePool)_dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-
-        for (String storagePath : storagePaths) {
-            ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
-
-            cmd.setStoragePath(storagePath);
-
-            sendModifyStoragePoolCommand(cmd, storagePool, hostId);
-        }
-    }
-
-    private void handleVMware(HostVO host, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
-        if (host != null && HypervisorType.VMware.equals(host.getHypervisorType())) {
-            List<StoragePoolVO> storagePools = _storagePoolDao.findPoolsByProvider(SolidFireUtil.PROVIDER_NAME);
-
-            if (storagePools != null && storagePools.size() > 0) {
-                List<Map<String, String>> targets = new ArrayList<>();
-
-                for (StoragePoolVO storagePool : storagePools) {
-                    List<Map<String, String>> targetsForClusterAndStoragePool = getTargets(host.getClusterId(), storagePool.getId());
-
-                    targets.addAll(targetsForClusterAndStoragePool);
-                }
-
-                ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-                cmd.setTargets(targets);
-                cmd.setAdd(add);
-                cmd.setTargetTypeToRemove(targetTypeToRemove);
-
-                sendModifyTargetsCommand(cmd, host.getId());
-            }
-        }
-    }
-
-    private void handleKVM(long hostId, long storagePoolId) {
-        StoragePool storagePool = (StoragePool)_dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-
-        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
-
-        sendModifyStoragePoolCommand(cmd, storagePool, hostId);
-    }
-
-    private List<String> getStoragePaths(long clusterId, long storagePoolId) {
-        List<String> storagePaths = new ArrayList<>();
-
-        // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
-        List<VolumeVO> volumes = _volumeDao.findByPoolId(storagePoolId, null);
-
-        if (volumes != null) {
-            for (VolumeVO volume : volumes) {
-                Long instanceId = volume.getInstanceId();
-
-                if (instanceId != null) {
-                    VMInstanceVO vmInstance = _vmDao.findById(instanceId);
-
-                    Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
-
-                    if (hostIdForVm != null) {
-                        HostVO hostForVm = _hostDao.findById(hostIdForVm);
-
-                        if (hostForVm != null && hostForVm.getClusterId().equals(clusterId)) {
-                            storagePaths.add(volume.get_iScsiName());
-                        }
-                    }
-                }
-            }
-        }
-
-        return storagePaths;
-    }
-
-    private List<Map<String, String>> getTargets(long clusterId, long storagePoolId) {
-        List<Map<String, String>> targets = new ArrayList<>();
-
-        StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
-
-        // If you do not pass in null for the second parameter, you only get back applicable ROOT disks.
-        List<VolumeVO> volumes = _volumeDao.findByPoolId(storagePoolId, null);
-
-        if (volumes != null) {
-            for (VolumeVO volume : volumes) {
-                Long instanceId = volume.getInstanceId();
-
-                if (instanceId != null) {
-                    VMInstanceVO vmInstance = _vmDao.findById(instanceId);
-
-                    Long hostIdForVm = vmInstance.getHostId() != null ? vmInstance.getHostId() : vmInstance.getLastHostId();
-
-                    if (hostIdForVm != null) {
-                        HostVO hostForVm = _hostDao.findById(hostIdForVm);
-
-                        if (hostForVm.getClusterId().equals(clusterId)) {
-                            Map<String, String> details = new HashMap<>();
-
-                            details.put(ModifyTargetsCommand.IQN, volume.get_iScsiName());
-                            details.put(ModifyTargetsCommand.STORAGE_HOST, storagePool.getHostAddress());
-                            details.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
-
-                            targets.add(details);
-                        }
-                    }
-                }
-            }
-        }
-
-        return targets;
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
-        }
-
-        if (!answer.getResult()) {
-            String msg = "Unable to modify targets on the following host: " + hostId;
-
-            HostVO host = _hostDao.findById(hostId);
-
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    private void sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StoragePool storagePool, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command (" + storagePool.getId() + ")");
-        }
-
-        if (!answer.getResult()) {
-            String msg = "Unable to attach storage pool " + storagePool.getId() + " to host " + hostId;
-
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
-
-            throw new CloudRuntimeException("Unable to establish a connection from agent to storage pool " + storagePool.getId() + " due to " + answer.getDetails() +
-                " (" + storagePool.getId() + ")");
-        }
-
-        assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer expected ; Pool = " + storagePool.getId() + " Host = " + hostId;
-
-        s_logger.info("Connection established between storage pool " + storagePool + " and host + " + hostId);
-    }
-}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
deleted file mode 100644
index 66aafac..0000000
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireSharedHostListener.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.datastore.provider;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ModifyStoragePoolAnswer;
-import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.alert.AlertManager;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class SolidFireSharedHostListener implements HypervisorHostListener {
-    private static final Logger LOGGER = Logger.getLogger(SolidFireSharedHostListener.class);
-
-    @Inject private AgentManager agentMgr;
-    @Inject private AlertManager alertMgr;
-    @Inject private ClusterDao clusterDao;
-    @Inject private ClusterDetailsDao clusterDetailsDao;
-    @Inject private DataStoreManager dataStoreMgr;
-    @Inject private HostDao hostDao;
-    @Inject private PrimaryDataStoreDao storagePoolDao;
-    @Inject private StoragePoolHostDao storagePoolHostDao;
-    @Inject private StoragePoolDetailsDao storagePoolDetailsDao;
-
-    @Override
-    public boolean hostAdded(long hostId) {
-        HostVO host = hostDao.findById(hostId);
-
-        if (host == null) {
-            LOGGER.error("Failed to add host by SolidFireSharedHostListener as host was not found with id=" + hostId);
-            return false;
-        }
-
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), true, SolidFireUtil.SHARED_PROVIDER_NAME,
-                clusterDao, clusterDetailsDao, storagePoolDao, storagePoolDetailsDao, hostDao);
-
-        handleVMware(hostId, true, ModifyTargetsCommand.TargetTypeToRemove.NEITHER);
-
-        return true;
-    }
-
-    @Override
-    public boolean hostConnect(long hostId, long storagePoolId) {
-        StoragePool storagePool = (StoragePool) dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-        ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, storagePool);
-
-        ModifyStoragePoolAnswer answer = sendModifyStoragePoolCommand(cmd, storagePool, hostId);
-
-        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
-
-        if (storagePoolHost != null) {
-            storagePoolHost.setLocalPath(answer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
-        } else {
-            storagePoolHost = new StoragePoolHostVO(storagePoolId, hostId, answer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
-
-            storagePoolHostDao.persist(storagePoolHost);
-        }
-
-        StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId);
-
-        storagePoolVO.setCapacityBytes(answer.getPoolInfo().getCapacityBytes());
-        storagePoolVO.setUsedBytes(answer.getPoolInfo().getCapacityBytes() - answer.getPoolInfo().getAvailableBytes());
-
-        storagePoolDao.update(storagePoolId, storagePoolVO);
-
-        return true;
-    }
-
-    @Override
-    public boolean hostDisconnected(long hostId, long storagePoolId) {
-        StoragePoolHostVO storagePoolHost = storagePoolHostDao.findByPoolHost(storagePoolId, hostId);
-
-        if (storagePoolHost != null) {
-            storagePoolHostDao.deleteStoragePoolHostDetails(hostId, storagePoolId);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean hostAboutToBeRemoved(long hostId) {
-        HostVO host = hostDao.findById(hostId);
-
-        SolidFireUtil.hostAddedToOrRemovedFromCluster(hostId, host.getClusterId(), false, SolidFireUtil.SHARED_PROVIDER_NAME,
-                clusterDao, clusterDetailsDao, storagePoolDao, storagePoolDetailsDao, hostDao);
-
-        handleVMware(hostId, false, ModifyTargetsCommand.TargetTypeToRemove.BOTH);
-
-        return true;
-    }
-
-    @Override
-    public boolean hostRemoved(long hostId, long clusterId) {
-        return true;
-    }
-
-    private void handleVMware(long hostId, boolean add, ModifyTargetsCommand.TargetTypeToRemove targetTypeToRemove) {
-        HostVO host = hostDao.findById(hostId);
-
-        if (HypervisorType.VMware.equals(host.getHypervisorType())) {
-            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(SolidFireUtil.SHARED_PROVIDER_NAME);
-
-            if (storagePools != null && storagePools.size() > 0) {
-                List<Map<String, String>> targets = new ArrayList<>();
-
-                for (StoragePoolVO storagePool : storagePools) {
-                    if (storagePool.getClusterId().equals(host.getClusterId())) {
-                        long storagePoolId = storagePool.getId();
-
-                        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.IQN);
-
-                        String iqn = storagePoolDetail.getValue();
-
-                        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_VIP);
-
-                        String sVip = storagePoolDetail.getValue();
-
-                        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.STORAGE_PORT);
-
-                        String sPort = storagePoolDetail.getValue();
-
-                        Map<String, String> details = new HashMap<>();
-
-                        details.put(ModifyTargetsCommand.IQN, iqn);
-                        details.put(ModifyTargetsCommand.STORAGE_HOST, sVip);
-                        details.put(ModifyTargetsCommand.STORAGE_PORT, sPort);
-
-                        targets.add(details);
-                    }
-                }
-
-                if (targets.size() > 0) {
-                    ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-                    cmd.setTargets(targets);
-                    cmd.setAdd(add);
-                    cmd.setTargetTypeToRemove(targetTypeToRemove);
-                    cmd.setRemoveAsync(true);
-
-                    sendModifyTargetsCommand(cmd, hostId);
-                }
-            }
-        }
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            throw new CloudRuntimeException("Unable to get an answer to the modify targets command");
-        }
-
-        if (!answer.getResult()) {
-            String msg = "Unable to modify targets on the following host: " + hostId;
-
-            HostVO host = hostDao.findById(hostId);
-
-            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), msg, msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    private ModifyStoragePoolAnswer sendModifyStoragePoolCommand(ModifyStoragePoolCommand cmd, StoragePool storagePool, long hostId) {
-        Answer answer = agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            throw new CloudRuntimeException("Unable to get an answer to the modify storage pool command for storage pool: " + storagePool.getId());
-        }
-
-        if (!answer.getResult()) {
-            String msg = "Unable to attach storage pool " + storagePool.getId() + " to the host " + hostId;
-
-            alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, storagePool.getDataCenterId(), storagePool.getPodId(), msg, msg);
-
-            throw new CloudRuntimeException(msg);
-        }
-
-        assert (answer instanceof ModifyStoragePoolAnswer) : "ModifyStoragePoolAnswer not returned from ModifyStoragePoolCommand; Storage pool = " +
-            storagePool.getId() + "; Host = " + hostId;
-
-        LOGGER.info("Connection established between storage pool " + storagePool + " and host " + hostId);
-
-        return (ModifyStoragePoolAnswer)answer;
-    }
-}
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
deleted file mode 100644
index 81adf4b..0000000
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java
+++ /dev/null
@@ -1,1115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.datastore.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.user.AccountDetailVO;
-import com.cloud.user.AccountDetailsDao;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import com.google.common.primitives.Longs;
-
-import com.solidfire.client.ElementFactory;
-import com.solidfire.element.api.Account;
-import com.solidfire.element.api.AddAccountRequest;
-import com.solidfire.element.api.CloneVolumeRequest;
-import com.solidfire.element.api.CloneVolumeResult;
-import com.solidfire.element.api.CreateSnapshotRequest;
-import com.solidfire.element.api.CreateVolumeAccessGroupRequest;
-import com.solidfire.element.api.CreateVolumeRequest;
-import com.solidfire.element.api.DeleteSnapshotRequest;
-import com.solidfire.element.api.DeleteVolumeRequest;
-import com.solidfire.element.api.GetAccountByIDRequest;
-import com.solidfire.element.api.GetAccountByNameRequest;
-import com.solidfire.element.api.GetAsyncResultRequest;
-import com.solidfire.element.api.ListSnapshotsRequest;
-import com.solidfire.element.api.ListVolumeAccessGroupsRequest;
-import com.solidfire.element.api.ListVolumesRequest;
-import com.solidfire.element.api.ModifyVolumeAccessGroupRequest;
-import com.solidfire.element.api.ModifyVolumeRequest;
-import com.solidfire.element.api.QoS;
-import com.solidfire.element.api.RollbackToSnapshotRequest;
-import com.solidfire.element.api.Snapshot;
-import com.solidfire.element.api.SolidFireElement;
-import com.solidfire.element.api.Volume;
-import com.solidfire.element.api.VolumeAccessGroup;
-import com.solidfire.jsvcgen.javautil.Optional;
-
-import static org.apache.commons.lang.ArrayUtils.toPrimitive;
-
-public class SolidFireUtil {
-    private static final Logger s_logger = Logger.getLogger(SolidFireUtil.class);
-
-    public static final String PROVIDER_NAME = "SolidFire";
-    public static final String SHARED_PROVIDER_NAME = "SolidFireShared";
-
-    public static final int s_lockTimeInSeconds = 300;
-
-    public static final String LOG_PREFIX = "SolidFire: ";
-
-    public static final String MANAGEMENT_VIP = "mVip";
-    public static final String STORAGE_VIP = "sVip";
-
-    public static final String MANAGEMENT_PORT = "mPort";
-    public static final String STORAGE_PORT = "sPort";
-
-    public static final String CLUSTER_ADMIN_USERNAME = "clusterAdminUsername";
-    public static final String CLUSTER_ADMIN_PASSWORD = "clusterAdminPassword";
-
-    // these three variables should only be used for the SolidFire plug-in with the name SolidFireUtil.PROVIDER_NAME
-    public static final String CLUSTER_DEFAULT_MIN_IOPS = "clusterDefaultMinIops";
-    public static final String CLUSTER_DEFAULT_MAX_IOPS = "clusterDefaultMaxIops";
-    public static final String CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS = "clusterDefaultBurstIopsPercentOfMaxIops";
-
-    // these three variables should only be used for the SolidFire plug-in with the name SolidFireUtil.SHARED_PROVIDER_NAME
-    public static final String MIN_IOPS = "minIops";
-    public static final String MAX_IOPS = "maxIops";
-    public static final String BURST_IOPS = "burstIops";
-
-    private static final String ACCOUNT_ID = "accountId";
-
-    public static final String VOLUME_ID = "volumeId";
-    public static final String TEMP_VOLUME_ID = "tempVolumeId";
-    public static final String SNAPSHOT_ID = "snapshotId";
-
-    public static final String CloudStackVolumeId = "CloudStackVolumeId";
-    public static final String CloudStackVolumeSize = "CloudStackVolumeSize";
-    public static final String CloudStackSnapshotId = "CloudStackSnapshotId";
-    public static final String CloudStackSnapshotSize = "CloudStackSnapshotSize";
-    public static final String CloudStackTemplateId = "CloudStackTemplateId";
-    public static final String CloudStackTemplateSize = "CloudStackTemplateSize";
-
-    public static final String ORIG_CS_VOLUME_ID = "originalCloudStackVolumeId";
-
-    public static final String VOLUME_SIZE = "sfVolumeSize";
-
-    public static final String STORAGE_POOL_ID = "sfStoragePoolId";
-
-    public static final String DATACENTER = "datacenter";
-
-    public static final String DATASTORE_NAME = "datastoreName";
-    public static final String IQN = "iqn";
-
-    public static final long MIN_VOLUME_SIZE = 1000000000;
-
-    public static final long MIN_IOPS_PER_VOLUME = 100;
-    public static final long MAX_MIN_IOPS_PER_VOLUME = 15000;
-    public static final long MAX_IOPS_PER_VOLUME = 100000;
-
-    private static final int DEFAULT_MANAGEMENT_PORT = 443;
-    private static final int DEFAULT_STORAGE_PORT = 3260;
-
-    public static class SolidFireConnection {
-        private final String _managementVip;
-        private final int _managementPort;
-        private final String _clusterAdminUsername;
-        private final String _clusterAdminPassword;
-
-        public SolidFireConnection(String managementVip, int managementPort, String clusterAdminUsername, String clusterAdminPassword) {
-            if (managementVip == null) {
-                throw new CloudRuntimeException("The management VIP cannot be 'null'.");
-            }
-
-            if (managementPort <= 0) {
-                throw new CloudRuntimeException("The management port must be a positive integer.");
-            }
-
-            if (clusterAdminUsername == null) {
-                throw new CloudRuntimeException("The cluster admin username cannot be 'null'.");
-            }
-
-            if (clusterAdminPassword == null) {
-                throw new CloudRuntimeException("The cluster admin password cannot be 'null'.");
-            }
-
-            _managementVip = managementVip;
-            _managementPort = managementPort;
-            _clusterAdminUsername = clusterAdminUsername;
-            _clusterAdminPassword = clusterAdminPassword;
-        }
-
-        String getManagementVip() {
-            return _managementVip;
-        }
-
-        int getManagementPort() {
-            return _managementPort;
-        }
-
-        String getClusterAdminUsername() {
-            return _clusterAdminUsername;
-        }
-
-        private String getClusterAdminPassword() {
-            return _clusterAdminPassword;
-        }
-
-        @Override
-        public int hashCode() {
-            return _managementVip.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof SolidFireConnection)) {
-                return false;
-            }
-
-            SolidFireConnection sfConnection = (SolidFireConnection)obj;
-
-            return _managementVip.equals(sfConnection.getManagementVip());
-        }
-    }
-
-    public static SolidFireConnection getSolidFireConnection(long storagePoolId, StoragePoolDetailsDao storagePoolDetailsDao) {
-        StoragePoolDetailVO storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_VIP);
-
-        String mVip = storagePoolDetail.getValue();
-
-        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_PORT);
-
-        int mPort = Integer.parseInt(storagePoolDetail.getValue());
-
-        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_USERNAME);
-
-        String clusterAdminUsername = storagePoolDetail.getValue();
-
-        storagePoolDetail = storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_PASSWORD);
-
-        String clusterAdminPassword = storagePoolDetail.getValue();
-
-        return new SolidFireConnection(mVip, mPort, clusterAdminUsername, clusterAdminPassword);
-    }
-
-    private static SolidFireElement getSolidFireElement(SolidFireConnection sfConnection) {
-        return ElementFactory.create(sfConnection.getManagementVip(), sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword());
-    }
-
-    // used to parse the "url" parameter when creating primary storage that's based on the SolidFire plug-in with the
-    // name SolidFireUtil.PROVIDER_NAME (as opposed to the SolidFire plug-in with the name SolidFireUtil.SHARED_PROVIDER_NAME)
-    // return a String instance that contains at most the MVIP and SVIP info
-    public static String getModifiedUrl(String originalUrl) {
-        StringBuilder sb = new StringBuilder();
-
-        String delimiter = ";";
-
-        StringTokenizer st = new StringTokenizer(originalUrl, delimiter);
-
-        while (st.hasMoreElements()) {
-            String token = st.nextElement().toString().toUpperCase();
-
-            if (token.startsWith(SolidFireUtil.MANAGEMENT_VIP.toUpperCase()) || token.startsWith(SolidFireUtil.STORAGE_VIP.toUpperCase())) {
-                sb.append(token).append(delimiter);
-            }
-        }
-
-        String modifiedUrl = sb.toString();
-        int lastIndexOf = modifiedUrl.lastIndexOf(delimiter);
-
-        if (lastIndexOf == (modifiedUrl.length() - delimiter.length())) {
-            return modifiedUrl.substring(0, lastIndexOf);
-        }
-
-        return modifiedUrl;
-    }
-
-    public static String getManagementVip(String url) {
-        return getVip(SolidFireUtil.MANAGEMENT_VIP, url);
-    }
-
-    public static String getStorageVip(String url) {
-        return getVip(SolidFireUtil.STORAGE_VIP, url);
-    }
-
-    public static int getManagementPort(String url) {
-        return getPort(SolidFireUtil.MANAGEMENT_VIP, url, DEFAULT_MANAGEMENT_PORT);
-    }
-
-    public static int getStoragePort(String url) {
-        return getPort(SolidFireUtil.STORAGE_VIP, url, DEFAULT_STORAGE_PORT);
-    }
-
-    public static String getValue(String keyToMatch, String url) {
-        return getValue(keyToMatch, url, true);
-    }
-
-    public static String getValue(String keyToMatch, String url, boolean throwExceptionIfNotFound) {
-        String delimiter1 = ";";
-        String delimiter2 = "=";
-
-        StringTokenizer st = new StringTokenizer(url, delimiter1);
-
-        while (st.hasMoreElements()) {
-            String token = st.nextElement().toString();
-
-            int index = token.indexOf(delimiter2);
-
-            if (index == -1) {
-                throw new RuntimeException("Invalid URL format");
-            }
-
-            String key = token.substring(0, index);
-
-            if (key.equalsIgnoreCase(keyToMatch)) {
-                return token.substring(index + delimiter2.length());
-            }
-        }
-
-        if (throwExceptionIfNotFound) {
-            throw new RuntimeException("Key not found in URL");
-        }
-
-        return null;
-    }
-
-    public static String getSolidFireAccountName(String csAccountUuid, long csAccountId) {
-        return "CloudStack_" + csAccountUuid + "_" + csAccountId;
-    }
-
-    public static void updateCsDbWithSolidFireIopsInfo(long storagePoolId, PrimaryDataStoreDao primaryDataStoreDao,
-                                                       StoragePoolDetailsDao storagePoolDetailsDao, long minIops, long maxIops, long burstIops) {
-        Map<String, String> existingDetails = storagePoolDetailsDao.listDetailsKeyPairs(storagePoolId);
-        Set<String> existingKeys = existingDetails.keySet();
-
-        Map<String, String> existingDetailsToKeep = new HashMap<>();
-
-        for (String existingKey : existingKeys) {
-            String existingValue = existingDetails.get(existingKey);
-
-            if (!SolidFireUtil.MIN_IOPS.equalsIgnoreCase(existingValue) &&
-                    !SolidFireUtil.MAX_IOPS.equalsIgnoreCase(existingValue) &&
-                    !SolidFireUtil.BURST_IOPS.equalsIgnoreCase(existingValue)) {
-                existingDetailsToKeep.put(existingKey, existingValue);
-            }
-        }
-
-        existingDetailsToKeep.put(SolidFireUtil.MIN_IOPS, String.valueOf(minIops));
-        existingDetailsToKeep.put(SolidFireUtil.MAX_IOPS, String.valueOf(maxIops));
-        existingDetailsToKeep.put(SolidFireUtil.BURST_IOPS, String.valueOf(burstIops));
-
-        primaryDataStoreDao.updateDetails(storagePoolId, existingDetailsToKeep);
-    }
-
-    public static void updateCsDbWithSolidFireAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount,
-                                                          long storagePoolId, AccountDetailsDao accountDetailsDao) {
-        AccountDetailVO accountDetail = new AccountDetailVO(csAccountId,
-                SolidFireUtil.getAccountKey(storagePoolId),
-                String.valueOf(sfAccount.getId()));
-
-        accountDetailsDao.persist(accountDetail);
-    }
-
-    public static SolidFireAccount getAccount(SolidFireConnection sfConnection, String sfAccountName) {
-        try {
-            return getAccountByName(sfConnection, sfAccountName);
-        } catch (Exception ex) {
-            return null;
-        }
-    }
-
-    public static void hostAddedToOrRemovedFromCluster(long hostId, long clusterId, boolean added, String storageProvider,
-            ClusterDao clusterDao, ClusterDetailsDao clusterDetailsDao, PrimaryDataStoreDao storagePoolDao,
-            StoragePoolDetailsDao storagePoolDetailsDao, HostDao hostDao) {
-        ClusterVO cluster = clusterDao.findById(clusterId);
-
-        GlobalLock lock = GlobalLock.getInternLock(cluster.getUuid());
-
-        if (!lock.lock(s_lockTimeInSeconds)) {
-            String errMsg = "Couldn't lock the DB on the following string: " + cluster.getUuid();
-
-            s_logger.debug(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        try {
-            List<StoragePoolVO> storagePools = storagePoolDao.findPoolsByProvider(storageProvider);
-
-            if (storagePools != null && storagePools.size() > 0) {
-                List<SolidFireUtil.SolidFireConnection> sfConnections = new ArrayList<>();
-
-                for (StoragePoolVO storagePool : storagePools) {
-                    ClusterDetailsVO clusterDetail = clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePool.getId()));
-
-                    String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
-
-                    if (vagId != null) {
-                        SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePool.getId(), storagePoolDetailsDao);
-
-                        if (!sfConnections.contains(sfConnection)) {
-                            sfConnections.add(sfConnection);
-
-                            SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getVag(sfConnection, Long.parseLong(vagId));
-
-                            List<HostVO> hostsToAddOrRemove = new ArrayList<>();
-                            HostVO hostToAddOrRemove = hostDao.findByIdIncludingRemoved(hostId);
-
-                            hostsToAddOrRemove.add(hostToAddOrRemove);
-
-                            String[] hostIqns = SolidFireUtil.getNewHostIqns(sfVag.getInitiators(), SolidFireUtil.getIqnsFromHosts(hostsToAddOrRemove), added);
-
-                            SolidFireUtil.modifyVag(sfConnection, sfVag.getId(), hostIqns, sfVag.getVolumeIds());
-                        }
-                    }
-                }
-            }
-        }
-        finally {
-            lock.unlock();
-            lock.releaseRef();
-        }
-    }
-
-    public static long placeVolumeInVolumeAccessGroup(SolidFireConnection sfConnection, long sfVolumeId, long storagePoolId,
-                                                      String vagUuid, List<HostVO> hosts, ClusterDetailsDao clusterDetailsDao) {
-        if (hosts == null || hosts.isEmpty()) {
-            throw new CloudRuntimeException("There must be at least one host in the cluster.");
-        }
-
-        long lVagId;
-
-        try {
-            lVagId = SolidFireUtil.createVag(sfConnection, "CloudStack-" + vagUuid,
-                SolidFireUtil.getIqnsFromHosts(hosts), new long[] { sfVolumeId });
-        }
-        catch (Exception ex) {
-            String iqnInVagAlready1 = "Exceeded maximum number of Volume Access Groups per initiator";
-            String iqnInVagAlready2 = "Exceeded maximum number of VolumeAccessGroups per Initiator";
-
-            if (!ex.getMessage().contains(iqnInVagAlready1) && !ex.getMessage().contains(iqnInVagAlready2)) {
-                throw new CloudRuntimeException(ex.getMessage());
-            }
-
-            // getCompatibleVag throws an exception if an existing VAG can't be located
-            SolidFireUtil.SolidFireVag sfVag = getCompatibleVag(sfConnection, hosts);
-
-            lVagId = sfVag.getId();
-
-            long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
-
-            SolidFireUtil.modifyVag(sfConnection, lVagId, sfVag.getInitiators(), volumeIds);
-        }
-
-        ClusterDetailsVO clusterDetail = new ClusterDetailsVO(hosts.get(0).getClusterId(), getVagKey(storagePoolId), String.valueOf(lVagId));
-
-        clusterDetailsDao.persist(clusterDetail);
-
-        return lVagId;
-    }
-
-    public static boolean hostsSupport_iScsi(List<HostVO> hosts) {
-        if (hosts == null || hosts.size() == 0) {
-            return false;
-        }
-
-        for (Host host : hosts) {
-            if (host == null || host.getStorageUrl() == null || host.getStorageUrl().trim().length() == 0 || !host.getStorageUrl().startsWith("iqn")) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public static long[] getNewVolumeIds(long[] volumeIds, long volumeIdToAddOrRemove, boolean add) {
-        if (add) {
-            return getNewVolumeIdsAdd(volumeIds, volumeIdToAddOrRemove);
-        }
-
-        return getNewVolumeIdsRemove(volumeIds, volumeIdToAddOrRemove);
-    }
-
-    public static String getVagKey(long storagePoolId) {
-        return "sfVolumeAccessGroup_" + storagePoolId;
-    }
-
-    public static String getAccountKey(long storagePoolId) {
-        return SolidFireUtil.ACCOUNT_ID + "_" + storagePoolId;
-    }
-
-    public static AccountDetailVO getAccountDetail(long csAccountId, long storagePoolId, AccountDetailsDao accountDetailsDao) {
-        AccountDetailVO accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.getAccountKey(storagePoolId));
-
-        if (accountDetail == null || accountDetail.getValue() == null) {
-            accountDetail = accountDetailsDao.findDetail(csAccountId, SolidFireUtil.ACCOUNT_ID);
-        }
-
-        return accountDetail;
-    }
-
-    public static String getSolidFireVolumeName(String strCloudStackVolumeName) {
-        final String specialChar = "-";
-
-        StringBuilder strSolidFireVolumeName = new StringBuilder();
-
-        for (int i = 0; i < strCloudStackVolumeName.length(); i++) {
-            String strChar = strCloudStackVolumeName.substring(i, i + 1);
-
-            if (StringUtils.isAlphanumeric(strChar)) {
-                strSolidFireVolumeName.append(strChar);
-            } else {
-                strSolidFireVolumeName.append(specialChar);
-            }
-        }
-
-        return strSolidFireVolumeName.toString();
-    }
-
-    public static long createVolume(SolidFireConnection sfConnection, String volumeName, long accountId, long totalSize,
-                                    boolean enable512e, Map<String, String> mapAttributes, long minIops, long maxIops, long burstIops) {
-        CreateVolumeRequest request = CreateVolumeRequest.builder()
-                .name(volumeName)
-                .accountID(accountId)
-                .totalSize(totalSize)
-                .enable512e(enable512e)
-                .optionalAttributes(convertMap(mapAttributes))
-                .optionalQos(new QoS(Optional.of(minIops), Optional.of(maxIops), Optional.of(burstIops), Optional.EMPTY_LONG))
-                .build();
-
-        return getSolidFireElement(sfConnection).createVolume(request).getVolumeID();
-    }
-
-    public static void modifyVolume(SolidFireConnection sfConnection, long volumeId, Long totalSize, Map<String, String> mapAttributes,
-                                    long minIops, long maxIops, long burstIops) {
-        ModifyVolumeRequest request = ModifyVolumeRequest.builder()
-                .volumeID(volumeId)
-                .optionalTotalSize(totalSize)
-                .optionalAttributes(convertMap(mapAttributes))
-                .optionalQos(new QoS(Optional.of(minIops), Optional.of(maxIops), Optional.of(burstIops), Optional.EMPTY_LONG))
-                .build();
-
-        getSolidFireElement(sfConnection).modifyVolume(request);
-    }
-
-    public static SolidFireVolume getVolume(SolidFireConnection sfConnection, long volumeId) {
-        ListVolumesRequest request = ListVolumesRequest.builder()
-                .optionalStartVolumeID(volumeId)
-                .optionalLimit(1L)
-                .build();
-
-        Volume volume = getSolidFireElement(sfConnection).listVolumes(request).getVolumes()[0];
-
-        return new SolidFireVolume(volume.getVolumeID(), volume.getName(), volume.getIqn(), volume.getAccountID(), volume.getStatus(),
-                volume.getEnable512e(), volume.getQos().getMinIOPS(), volume.getQos().getMaxIOPS(), volume.getQos().getBurstIOPS(),
-                volume.getTotalSize(), volume.getScsiNAADeviceID());
-    }
-
-    public static void deleteVolume(SolidFireConnection sfConnection, long volumeId) {
-        DeleteVolumeRequest request = DeleteVolumeRequest.builder()
-                .volumeID(volumeId)
-                .build();
-
-        getSolidFireElement(sfConnection).deleteVolume(request);
-    }
-
-    private static final String ACTIVE = "active";
-
-    public static class SolidFireVolume {
-        private final long _id;
-        private final String _name;
-        private final String _iqn;
-        private final long _accountId;
-        private final String _status;
-        private final boolean _enable512e;
-        private final long _minIops;
-        private final long _maxIops;
-        private final long _burstIops;
-        private final long _totalSize;
-        private final String _scsiNaaDeviceId;
-
-        SolidFireVolume(long id, String name, String iqn, long accountId, String status, boolean enable512e,
-                        long minIops, long maxIops, long burstIops, long totalSize, String scsiNaaDeviceId) {
-            _id = id;
-            _name = name;
-            _iqn = "/" + iqn + "/0";
-            _accountId = accountId;
-            _status = status;
-            _enable512e = enable512e;
-            _minIops = minIops;
-            _maxIops = maxIops;
-            _burstIops = burstIops;
-            _totalSize = totalSize;
-            _scsiNaaDeviceId = scsiNaaDeviceId;
-        }
-
-        public long getId() {
-            return _id;
-        }
-
-        public String getName() {
-            return _name;
-        }
-
-        public String getIqn() {
-            return _iqn;
-        }
-
-        public long getAccountId() {
-            return _accountId;
-        }
-
-        public boolean isActive() {
-            return ACTIVE.equalsIgnoreCase(_status);
-        }
-
-        public boolean isEnable512e() {
-            return _enable512e;
-        }
-
-        public long getMinIops() {
-            return _minIops;
-        }
-
-        public long getMaxIops() {
-            return _maxIops;
-        }
-
-        public long getBurstIops() {
-            return _burstIops;
-        }
-
-        public long getTotalSize() {
-            return _totalSize;
-        }
-
-        public String getScsiNaaDeviceId() {
-            return _scsiNaaDeviceId;
-        }
-
-        @Override
-        public int hashCode() {
-            return _iqn.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return _name;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-
-            if (!obj.getClass().equals(SolidFireVolume.class)) {
-                return false;
-            }
-
-            SolidFireVolume sfv = (SolidFireVolume)obj;
-
-            return _id == sfv._id && _name.equals(sfv._name) && _iqn.equals(sfv._iqn) && _accountId == sfv._accountId &&
-                    isActive() == sfv.isActive() && getTotalSize() == sfv.getTotalSize();
-        }
-    }
-
-    public static long createSnapshot(SolidFireConnection sfConnection, long volumeId, String snapshotName, Map<String, String> mapAttributes) {
-        CreateSnapshotRequest request = CreateSnapshotRequest.builder()
-                .volumeID(volumeId)
-                .optionalName(snapshotName)
-                .optionalAttributes(convertMap(mapAttributes))
-                .build();
-
-        return getSolidFireElement(sfConnection).createSnapshot(request).getSnapshotID();
-    }
-
-    public static SolidFireSnapshot getSnapshot(SolidFireConnection sfConnection, long volumeId, long snapshotId) {
-        ListSnapshotsRequest request = ListSnapshotsRequest.builder()
-                .optionalVolumeID(volumeId)
-                .build();
-
-        Snapshot[] snapshots = getSolidFireElement(sfConnection).listSnapshots(request).getSnapshots();
-
-        String snapshotName = null;
-        long totalSize = 0;
-
-        if (snapshots != null) {
-            for (Snapshot snapshot : snapshots) {
-                if (snapshot.getSnapshotID() == snapshotId) {
-                    snapshotName = snapshot.getName();
-                    totalSize = snapshot.getTotalSize();
-
-                    break;
-                }
-            }
-        }
-
-        if (snapshotName == null) {
-            throw new CloudRuntimeException("Could not find SolidFire snapshot ID: " + snapshotId + " for the following SolidFire volume ID: " + volumeId);
-        }
-
-        return new SolidFireSnapshot(snapshotId, snapshotName, totalSize);
-    }
-
-    public static void deleteSnapshot(SolidFireConnection sfConnection, long snapshotId) {
-        DeleteSnapshotRequest request = DeleteSnapshotRequest.builder()
-                .snapshotID(snapshotId)
-                .build();
-
-        getSolidFireElement(sfConnection).deleteSnapshot(request);
-    }
-
-    public static void rollBackVolumeToSnapshot(SolidFireConnection sfConnection, long volumeId, long snapshotId) {
-        RollbackToSnapshotRequest request = RollbackToSnapshotRequest.builder()
-                .volumeID(volumeId)
-                .snapshotID(snapshotId)
-                .build();
-
-        getSolidFireElement(sfConnection).rollbackToSnapshot(request);
-    }
-
-    public static class SolidFireSnapshot {
-        private final long _id;
-        private final String _name;
-        private final long _totalSize;
-
-        SolidFireSnapshot(long id, String name, long totalSize) {
-            _id = id;
-            _name = name;
-            _totalSize = totalSize;
-        }
-
-        public long getId() {
-            return _id;
-        }
-
-        public String getName() {
-            return _name;
-        }
-
-        public long getTotalSize() {
-            return _totalSize;
-        }
-    }
-
-    public static long createClone(SolidFireConnection sfConnection, long volumeId, long snapshotId, long accountId,
-                                   String cloneName, Map<String, String> mapAttributes) {
-        CloneVolumeRequest request = CloneVolumeRequest.builder()
-                .volumeID(volumeId)
-                .optionalSnapshotID(snapshotId < 1 ? null : snapshotId)
-                .optionalNewAccountID(accountId)
-                .name(cloneName)
-                .optionalAttributes(convertMap(mapAttributes))
-                .build();
-
-        CloneVolumeResult result = getSolidFireElement(sfConnection).cloneVolume(request);
-
-        // Clone is an async operation. Poll until we get data.
-
-        GetAsyncResultRequest asyncResultRequest = GetAsyncResultRequest.builder()
-                .asyncHandle(result.getAsyncHandle())
-                .build();
-
-        do {
-            String status = getSolidFireElement(sfConnection).getAsyncResult(asyncResultRequest).getStatus();
-
-            if (status.equals("complete")) {
-                break;
-            }
-
-            try {
-                Thread.sleep(500); // sleep for 1/2 of a second
-            }
-            catch (Exception ex) {
-                // ignore
-            }
-        }
-        while (true);
-
-        return result.getVolumeID();
-    }
-
-    public static long createAccount(SolidFireConnection sfConnection, String accountName) {
-        AddAccountRequest request = AddAccountRequest.builder()
-                .username(accountName)
-                .build();
-
-        return getSolidFireElement(sfConnection).addAccount(request).getAccountID();
-    }
-
-    public static SolidFireAccount getAccountById(SolidFireConnection sfConnection, long accountId) {
-        GetAccountByIDRequest request = GetAccountByIDRequest.builder()
-                .accountID(accountId)
-                .build();
-
-        Account sfAccount = getSolidFireElement(sfConnection).getAccountByID(request).getAccount();
-
-        String sfAccountName = sfAccount.getUsername();
-        String sfAccountInitiatorSecret = sfAccount.getInitiatorSecret().isPresent() ? sfAccount.getInitiatorSecret().get().toString() : "";
-        String sfAccountTargetSecret = sfAccount.getTargetSecret().isPresent() ? sfAccount.getTargetSecret().get().toString() : "";
-
-        return new SolidFireAccount(accountId, sfAccountName, sfAccountInitiatorSecret, sfAccountTargetSecret);
-    }
-
-    private static SolidFireAccount getAccountByName(SolidFireConnection sfConnection, String accountName) {
-        GetAccountByNameRequest request = GetAccountByNameRequest.builder()
-                .username(accountName)
-                .build();
-
-        Account sfAccount = getSolidFireElement(sfConnection).getAccountByName(request).getAccount();
-
-        long sfAccountId = sfAccount.getAccountID();
-        String sfAccountInitiatorSecret = sfAccount.getInitiatorSecret().isPresent() ? sfAccount.getInitiatorSecret().get().toString() : "";
-        String sfAccountTargetSecret = sfAccount.getTargetSecret().isPresent() ? sfAccount.getTargetSecret().get().toString() : "";
-
-        return new SolidFireAccount(sfAccountId, accountName, sfAccountInitiatorSecret, sfAccountTargetSecret);
-    }
-
-    public static class SolidFireAccount {
-        private final long _id;
-        private final String _name;
-        private final String _initiatorSecret;
-        private final String _targetSecret;
-
-        SolidFireAccount(long id, String name, String initiatorSecret, String targetSecret) {
-            _id = id;
-            _name = name;
-            _initiatorSecret = initiatorSecret;
-            _targetSecret = targetSecret;
-        }
-
-        public long getId() {
-            return _id;
-        }
-
-        public String getName() {
-            return _name;
-        }
-
-        @Override
-        public int hashCode() {
-            return (_id + _name).hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return _name;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-
-            if (!obj.getClass().equals(SolidFireAccount.class)) {
-                return false;
-            }
-
-            SolidFireAccount sfa = (SolidFireAccount)obj;
-
-            return _id == sfa._id && _name.equals(sfa._name) &&
-                    _initiatorSecret.equals(sfa._initiatorSecret) &&
-                    _targetSecret.equals(sfa._targetSecret);
-        }
-    }
-
-    private static long createVag(SolidFireConnection sfConnection, String vagName, String[] iqns, long[] volumeIds) {
-        CreateVolumeAccessGroupRequest request = CreateVolumeAccessGroupRequest.builder()
-                .name(vagName)
-                .optionalInitiators(iqns)
-                .optionalVolumes(Longs.asList(volumeIds).toArray(new Long[volumeIds.length]))
-                .build();
-
-        return getSolidFireElement(sfConnection).createVolumeAccessGroup(request).getVolumeAccessGroupID();
-    }
-
-    public static void modifyVag(SolidFireConnection sfConnection, long vagId, String[] iqns, long[] volumeIds) {
-        ModifyVolumeAccessGroupRequest request = ModifyVolumeAccessGroupRequest.builder()
-                .volumeAccessGroupID(vagId)
-                .optionalInitiators(iqns)
-                .optionalVolumes(Longs.asList(volumeIds).toArray(new Long[volumeIds.length]))
-                .build();
-
-        getSolidFireElement(sfConnection).modifyVolumeAccessGroup(request);
-    }
-
-    public static SolidFireVag getVag(SolidFireConnection sfConnection, long vagId)
-    {
-        ListVolumeAccessGroupsRequest request = ListVolumeAccessGroupsRequest.builder()
-                .optionalStartVolumeAccessGroupID(vagId)
-                .optionalLimit(1L)
-                .build();
-
-        VolumeAccessGroup vag = getSolidFireElement(sfConnection).listVolumeAccessGroups(request).getVolumeAccessGroups()[0];
-
-        String[] vagIqns = vag.getInitiators();
-        long[] vagVolumeIds = toPrimitive(vag.getVolumes());
-
-        return new SolidFireVag(vagId, vagIqns, vagVolumeIds);
-    }
-
-    private static List<SolidFireVag> getAllVags(SolidFireConnection sfConnection)
-    {
-        ListVolumeAccessGroupsRequest request = ListVolumeAccessGroupsRequest.builder().build();
-
-        VolumeAccessGroup[] vags = getSolidFireElement(sfConnection).listVolumeAccessGroups(request).getVolumeAccessGroups();
-
-        List<SolidFireVag> lstSolidFireVags = new ArrayList<>();
-
-        if (vags != null) {
-            for (VolumeAccessGroup vag : vags) {
-                SolidFireVag sfVag = new SolidFireVag(vag.getVolumeAccessGroupID(), vag.getInitiators(), toPrimitive(vag.getVolumes()));
-
-                lstSolidFireVags.add(sfVag);
-            }
-        }
-
-        return lstSolidFireVags;
-    }
-
-    public static class SolidFireVag {
-        private final long _id;
-        private final String[] _initiators;
-        private final long[] _volumeIds;
-
-        SolidFireVag(long id, String[] initiators, long[] volumeIds) {
-            _id = id;
-            _initiators = initiators;
-            _volumeIds = volumeIds;
-        }
-
-        public long getId() {
-            return _id;
-        }
-
-        public String[] getInitiators() {
-            return _initiators;
-        }
-
-        public long[] getVolumeIds() {
-            return _volumeIds;
-        }
-
-        @Override
-        public int hashCode() {
-            return String.valueOf(_id).hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(_id);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) {
-                return false;
-            }
-
-            if (!obj.getClass().equals(SolidFireVag.class)) {
-                return false;
-            }
-
-            SolidFireVag sfVag = (SolidFireVag)obj;
-
-            return _id == sfVag._id;
-        }
-    }
-
-    private static String getVip(String keyToMatch, String url) {
-        String delimiter = ":";
-
-        String storageVip = getValue(keyToMatch, url);
-
-        int index = storageVip.indexOf(delimiter);
-
-        if (index != -1) {
-            return storageVip.substring(0, index);
-        }
-
-        return storageVip;
-    }
-
-    private static int getPort(String keyToMatch, String url, int defaultPortNumber) {
-        String delimiter = ":";
-
-        String storageVip = getValue(keyToMatch, url);
-
-        int index = storageVip.indexOf(delimiter);
-
-        int portNumber = defaultPortNumber;
-
-        if (index != -1) {
-            String port = storageVip.substring(index + delimiter.length());
-
-            try {
-                portNumber = Integer.parseInt(port);
-            } catch (NumberFormatException ex) {
-                throw new IllegalArgumentException("Invalid URL format (port is not an integer)");
-            }
-        }
-
-        return portNumber;
-    }
-
-    private static String[] getNewHostIqns(String[] iqns, String[] iqnsToAddOrRemove, boolean add) {
-        if (add) {
-            return getNewHostIqnsAdd(iqns, iqnsToAddOrRemove);
-        }
-
-        return getNewHostIqnsRemove(iqns, iqnsToAddOrRemove);
-    }
-
-    private static String[] getNewHostIqnsAdd(String[] iqns, String[] iqnsToAdd) {
-        List<String> lstIqns = iqns != null ? new ArrayList<>(Arrays.asList(iqns)) : new ArrayList<String>();
-
-        if (iqnsToAdd != null) {
-            for (String iqnToAdd : iqnsToAdd) {
-                if (!lstIqns.contains(iqnToAdd)) {
-                    lstIqns.add(iqnToAdd);
-                }
-            }
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    private static String[] getNewHostIqnsRemove(String[] iqns, String[] iqnsToRemove) {
-        List<String> lstIqns = iqns != null ? new ArrayList<>(Arrays.asList(iqns)) : new ArrayList<String>();
-
-        if (iqnsToRemove != null) {
-            for (String iqnToRemove : iqnsToRemove) {
-                lstIqns.remove(iqnToRemove);
-            }
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    private static long[] getNewVolumeIdsAdd(long[] volumeIds, long volumeIdToAdd) {
-        List<Long> lstVolumeIds = new ArrayList<>();
-
-        if (volumeIds != null) {
-            for (long volumeId : volumeIds) {
-                lstVolumeIds.add(volumeId);
-            }
-        }
-
-        if (lstVolumeIds.contains(volumeIdToAdd)) {
-            return volumeIds;
-        }
-
-        lstVolumeIds.add(volumeIdToAdd);
-
-        return toPrimitive(lstVolumeIds.toArray(new Long[lstVolumeIds.size()]));
-    }
-
-    private static long[] getNewVolumeIdsRemove(long[] volumeIds, long volumeIdToRemove) {
-        List<Long> lstVolumeIds = new ArrayList<>();
-
-        if (volumeIds != null) {
-            for (long volumeId : volumeIds) {
-                lstVolumeIds.add(volumeId);
-            }
-        }
-
-        lstVolumeIds.remove(volumeIdToRemove);
-
-        return toPrimitive(lstVolumeIds.toArray(new Long[lstVolumeIds.size()]));
-    }
-
-    private static String[] getIqnsFromHosts(List<? extends Host> hosts) {
-        if (hosts == null || hosts.size() == 0) {
-            throw new CloudRuntimeException("There do not appear to be any hosts in this cluster.");
-        }
-
-        List<String> lstIqns = new ArrayList<>();
-
-        for (Host host : hosts) {
-            lstIqns.add(host.getStorageUrl());
-        }
-
-        return lstIqns.toArray(new String[0]);
-    }
-
-    // this method takes in a collection of hosts and tries to find an existing VAG that has all of them in it
-    // if successful, the VAG is returned; else, a CloudRuntimeException is thrown and this issue should be corrected by an admin
-    private static SolidFireUtil.SolidFireVag getCompatibleVag(SolidFireConnection sfConnection, List<HostVO> hosts) {
-        List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllVags(sfConnection);
-
-        if (sfVags != null) {
-            List<String> hostIqns = new ArrayList<>();
-
-            // where the method we're in is called, hosts should not be null
-            for (HostVO host : hosts) {
-                // where the method we're in is called, host.getStorageUrl() should not be null (it actually should start with "iqn")
-                hostIqns.add(host.getStorageUrl().toLowerCase());
-            }
-
-            for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
-                List<String> lstInitiators = getStringArrayAsLowerCaseStringList(sfVag.getInitiators());
-
-                // lstInitiators should not be returned from getStringArrayAsLowerCaseStringList as null
-                if (lstInitiators.containsAll(hostIqns)) {
-                    return sfVag;
-                }
-            }
-        }
-
-        throw new CloudRuntimeException("Unable to locate the appropriate SolidFire Volume Access Group");
-    }
-
-    private static List<String> getStringArrayAsLowerCaseStringList(String[] aString) {
-        List<String> lstLowerCaseString = new ArrayList<>();
-
-        if (aString != null) {
-            for (String str : aString) {
-                if (str != null) {
-                    lstLowerCaseString.add(str.toLowerCase());
-                }
-            }
-        }
-
-        return lstLowerCaseString;
-    }
-
-    private static Map<String, Object> convertMap(Map<String, String> map) {
-        if (map == null) {
-            return null;
-        }
-
-        Map<String, Object> convertedMap = new HashMap<>();
-
-        convertedMap.putAll(map);
-
-        return convertedMap;
-    }
-}
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/AopTestAdvice.java
similarity index 100%
rename from plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java
rename to plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/AopTestAdvice.java
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
similarity index 100%
rename from plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
rename to plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java b/plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/TestConfiguration.java
similarity index 100%
rename from plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java
rename to plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/TestConfiguration.java
diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java
similarity index 100%
rename from plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java
rename to plugins/storage/volume/solidfire/src/test/java/org/apache/cloudstack/storage/test/VolumeTest.java
diff --git a/plugins/storage/volume/solidfire/test/resource/storageContext.xml b/plugins/storage/volume/solidfire/src/test/resource/storageContext.xml
similarity index 100%
rename from plugins/storage/volume/solidfire/test/resource/storageContext.xml
rename to plugins/storage/volume/solidfire/src/test/resource/storageContext.xml
diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml
index aae36be..9109b0a 100644
--- a/plugins/user-authenticators/ldap/pom.xml
+++ b/plugins/user-authenticators/ldap/pom.xml
@@ -1,112 +1,118 @@
-<!-- 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. -->
+<!--
+  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-user-authenticator-ldap</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator LDAP</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+    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-user-authenticator-ldap</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator LDAP</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.gmaven</groupId>
+                <artifactId>gmaven-plugin</artifactId>
+                <version>1.3</version>
+                <configuration>
+                    <providerSelection>1.7</providerSelection>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>testCompile</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <fileset>
+                                    <directory>test</directory>
+                                    <includes>
+                                        <include>groovy/**/*.groovy</include>
+                                    </includes>
+                                </fileset>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.gmaven.runtime</groupId>
+                        <artifactId>gmaven-runtime-1.7</artifactId>
+                        <version>1.3</version>
+                        <exclusions>
+                            <exclusion>
+                                <groupId>org.codehaus.groovy</groupId>
+                                <artifactId>groovy-all</artifactId>
+                            </exclusion>
+                        </exclusions>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.codehaus.groovy</groupId>
+                        <artifactId>groovy-all</artifactId>
+                        <version>${cs.groovy.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <includes>
+                        <include>**/*Spec.groovy</include>
+                        <include>**/*Test.java</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.btmatthews.maven.plugins</groupId>
+                <artifactId>ldap-maven-plugin</artifactId>
+                <version>1.1.0</version>
+                <configuration>
+                    <monitorPort>11389</monitorPort>
+                    <monitorKey>ldap</monitorKey>
+                    <daemon>false</daemon>
+                    <rootDn>dc=cloudstack,dc=org</rootDn>
+                    <ldapPort>10389</ldapPort>
+                    <ldifFile>test/resources/cloudstack.org.ldif</ldifFile>
+                </configuration>
+            </plugin>
+        </plugins>
+        <testSourceDirectory>test</testSourceDirectory>
+    </build>
+    <dependencies>
+        <!-- Mandatory dependencies for using Spock -->
+        <dependency>
+            <groupId>org.spockframework</groupId>
+            <artifactId>spock-core</artifactId>
+            <version>1.1-groovy-2.4</version>
+            <scope>test</scope>
+        </dependency>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.gmaven</groupId>
-        <artifactId>gmaven-plugin</artifactId>
-        <version>1.3</version>
-        <configuration>
-          <providerSelection>1.7</providerSelection>
-        </configuration>
-        <executions>
-          <execution>
-            <goals>
-              <goal>compile</goal>
-              <goal>testCompile</goal>
-            </goals>
-            <configuration>
-              <sources>
-                <fileset>
-                  <directory>test</directory>
-                  <includes>
-                    <include>groovy/**/*.groovy</include>
-                  </includes>
-                </fileset>
-              </sources>
-            </configuration>
-          </execution>
-        </executions>
-        <dependencies>
-          <dependency>
-            <groupId>org.codehaus.gmaven.runtime</groupId>
-            <artifactId>gmaven-runtime-1.7</artifactId>
-            <version>1.3</version>
-            <exclusions>
-              <exclusion>
-                <groupId>org.codehaus.groovy</groupId>
-                <artifactId>groovy-all</artifactId>
-              </exclusion>
-            </exclusions>
-          </dependency>
-          <dependency>
-            <groupId>org.codehaus.groovy</groupId>
-            <artifactId>groovy-all</artifactId>
-            <version>2.0.5</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <includes>
-            <include>**/*Spec.groovy</include>
-            <include>**/*Test.java</include>
-          </includes>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>com.btmatthews.maven.plugins</groupId>
-        <artifactId>ldap-maven-plugin</artifactId>
-        <version>1.1.0</version>
-        <configuration>
-          <monitorPort>11389</monitorPort>
-            <monitorKey>ldap</monitorKey>
-            <daemon>false</daemon>
-            <rootDn>dc=cloudstack,dc=org</rootDn>
-            <ldapPort>10389</ldapPort>
-            <ldifFile>test/resources/cloudstack.org.ldif</ldifFile>
-        </configuration>
-      </plugin>
-
-    </plugins>
-    <testSourceDirectory>test</testSourceDirectory>
-  </build>
-  <dependencies>
-    <!-- Mandatory dependencies for using Spock -->
-    <dependency>
-      <groupId>org.spockframework</groupId>
-      <artifactId>spock-core</artifactId>
-      <version>1.1-groovy-2.4</version>
-      <scope>test</scope>
-    </dependency>
-
-    <!-- Optional dependencies for using Spock -->
-    <dependency> <!-- enables mocking of classes (in addition to interfaces) -->
-      <groupId>cglib</groupId>
-      <artifactId>cglib-nodep</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+        <!-- Optional dependencies for using Spock -->
+        <dependency> <!-- enables mocking of classes (in addition to interfaces) -->
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LDAPConfigCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LDAPConfigCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LDAPConfigCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LDAPConfigCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LDAPRemoveCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LDAPRemoveCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LDAPRemoveCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LDAPRemoveCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapAddConfigurationCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapAddConfigurationCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapAddConfigurationCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapAddConfigurationCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapCreateAccountCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapDeleteConfigurationCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapDeleteConfigurationCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapDeleteConfigurationCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapDeleteConfigurationCmd.java
diff --git a/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
new file mode 100644
index 0000000..9011452
--- /dev/null
+++ b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
@@ -0,0 +1,251 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.LdapUserResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.RoleResponse;
+import org.apache.cloudstack.ldap.LdapManager;
+import org.apache.cloudstack.ldap.LdapUser;
+import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.bouncycastle.util.encoders.Base64;
+
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.DomainService;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+
+@APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class LdapImportUsersCmd extends BaseListCmd {
+
+    public static final Logger s_logger = Logger.getLogger(LdapImportUsersCmd.class.getName());
+
+    private static final String s_name = "ldapuserresponse";
+
+    @Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
+    private String timezone;
+
+    @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, description = "Type of the account.  Specify 0 for user, 1 for root admin, and 2 for domain admin")
+    private Short accountType;
+
+    @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
+    private Long roleId;
+
+    @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
+    private Map<String, String> details;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Specifies the domain to which the ldap users are to be "
+            + "imported. If no domain is specified, a domain will created using group parameter. If the group is also not specified, a domain name based on the OU information will be "
+            + "created. If no OU hierarchy exists, will be defaulted to ROOT domain")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Specifies the group name from which the ldap users are to be imported. "
+            + "If no group is specified, all the users will be imported.")
+    private String groupName;
+
+    private Domain _domain;
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.")
+    private String accountName;
+
+    @Inject
+    private LdapManager _ldapManager;
+
+    public LdapImportUsersCmd() {
+        super();
+    }
+
+    public LdapImportUsersCmd(final LdapManager ldapManager, final DomainService domainService, final AccountService accountService) {
+        super();
+        _ldapManager = ldapManager;
+        _domainService = domainService;
+        _accountService = accountService;
+    }
+
+    private void createCloudstackUserAccount(LdapUser user, String accountName, Domain domain) {
+        Account account = _accountService.getActiveAccountByName(accountName, domain.getId());
+        if (account == null) {
+            s_logger.debug("No account exists with name: " + accountName + " creating the account and an user with name: " + user.getUsername() + " in the account");
+            _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, getAccountType(), getRoleId(),
+                    domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
+        } else {
+//            check if the user exists. if yes, call update
+            UserAccount csuser = _accountService.getActiveUserAccount(user.getUsername(), domain.getId());
+            if (csuser == null) {
+                s_logger.debug("No user exists with name: " + user.getUsername() + " creating a user in the account: " + accountName);
+                _accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(),
+                        UUID.randomUUID().toString(), User.Source.LDAP);
+            } else {
+                s_logger.debug("Account [name=%s] and user [name=%s] already exist in CloudStack. Executing the user update.");
+
+                UpdateUserCmd updateUserCmd = new UpdateUserCmd();
+                updateUserCmd.setId(csuser.getId());
+                updateUserCmd.setFirstname(user.getFirstname());
+                updateUserCmd.setLastname(user.getLastname());
+                updateUserCmd.setEmail(user.getEmail());
+
+                _accountService.updateUser(updateUserCmd);
+            }
+        }
+    }
+
+    @Override
+    public void execute()
+            throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+        if (getAccountType() == null && getRoleId() == null) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
+        }
+        List<LdapUser> users;
+        try {
+            if (StringUtils.isNotBlank(groupName)) {
+
+                users = _ldapManager.getUsersInGroup(groupName, domainId);
+            } else {
+                users = _ldapManager.getUsers(domainId);
+            }
+        } catch (NoLdapUserMatchingQueryException ex) {
+            users = new ArrayList<LdapUser>();
+            s_logger.info("No Ldap user matching query. " + " ::: " + ex.getMessage());
+        }
+
+        List<LdapUser> addedUsers = new ArrayList<LdapUser>();
+        for (LdapUser user : users) {
+            Domain domain = getDomain(user);
+            try {
+                createCloudstackUserAccount(user, getAccountName(user), domain);
+                addedUsers.add(user);
+            } catch (InvalidParameterValueException ex) {
+                s_logger.error("Failed to create user with username: " + user.getUsername() + " ::: " + ex.getMessage());
+            }
+        }
+        ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
+        response.setResponses(createLdapUserResponse(addedUsers));
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    public Short getAccountType() {
+        return RoleType.getAccountTypeByRole(roleService.findRole(roleId), accountType);
+    }
+
+    public Long getRoleId() {
+        return RoleType.getRoleByAccountType(roleId, accountType);
+    }
+
+    private String getAccountName(LdapUser user) {
+        String finalAccountName = accountName;
+        if (finalAccountName == null) {
+            finalAccountName = user.getUsername();
+        }
+        return finalAccountName;
+    }
+
+    private Domain getDomainForName(String name) {
+        Domain domain = null;
+        if (StringUtils.isNotBlank(name)) {
+            //removing all the special characters and trimming its length to 190 to make the domain valid.
+            String domainName = StringUtils.substring(name.replaceAll("\\W", ""), 0, 190);
+            if (StringUtils.isNotBlank(domainName)) {
+                domain = _domainService.getDomainByName(domainName, Domain.ROOT_DOMAIN);
+                if (domain == null) {
+                    domain = _domainService.createDomain(domainName, Domain.ROOT_DOMAIN, domainName, UUID.randomUUID().toString());
+                }
+            }
+        }
+        return domain;
+    }
+
+    private Domain getDomain(LdapUser user) {
+        Domain domain;
+        if (_domain != null) {
+            //this means either domain id or groupname is passed and this will be same for all the users in this call. hence returning it.
+            domain = _domain;
+        } else {
+            if (domainId != null) {
+                // a domain Id is passed. use it for this user and all the users in the same api call (by setting _domain)
+                domain = _domain = _domainService.getDomain(domainId);
+            } else {
+                // a group name is passed. use it for this user and all the users in the same api call(by setting _domain)
+                domain = _domain = getDomainForName(groupName);
+                if (domain == null) {
+                    //use the domain from the LDAP for this user
+                    domain = getDomainForName(user.getDomain());
+                }
+            }
+            if (domain == null) {
+                // could not get a domain using domainId / LDAP group / OU of LDAP user. using ROOT domain for this user
+                domain = _domainService.getDomain(Domain.ROOT_DOMAIN);
+            }
+        }
+        return domain;
+    }
+
+    private List<LdapUserResponse> createLdapUserResponse(List<LdapUser> users) {
+        final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>();
+        for (final LdapUser user : users) {
+            final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user);
+            ldapResponse.setObjectName("LdapUser");
+            ldapResponses.add(ldapResponse);
+        }
+        return ldapResponses;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    private String generatePassword() throws ServerApiException {
+        try {
+            final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
+            final byte bytes[] = new byte[20];
+            randomGen.nextBytes(bytes);
+            return new String(Base64.encode(bytes), "UTF-8");
+        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
+        }
+    }
+}
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListConfigurationCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapListConfigurationCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListConfigurationCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapListConfigurationCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListUsersCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapListUsersCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListUsersCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapListUsersCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapUserSearchCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapUserSearchCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapUserSearchCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapUserSearchCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkAccountToLdapCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LinkAccountToLdapCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkAccountToLdapCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LinkAccountToLdapCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LDAPConfigResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPConfigResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LDAPConfigResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPRemoveResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LDAPRemoveResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LDAPRemoveResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LDAPRemoveResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LdapConfigurationResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LdapConfigurationResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LdapConfigurationResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LdapConfigurationResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LdapUserResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LdapUserResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LdapUserResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LdapUserResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkAccountToLdapResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LinkAccountToLdapResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkAccountToLdapResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LinkAccountToLdapResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapAuthenticator.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapConfiguration.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfiguration.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapConfiguration.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapConfigurationVO.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapConfigurationVO.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapConfigurationVO.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapContextFactory.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapContextFactory.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapContextFactory.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapManager.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapManager.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapManagerImpl.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapManagerImpl.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapTrustMapVO.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapTrustMapVO.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUser.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUser.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUser.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUserManager.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManager.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUserManager.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUserManagerFactory.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUtils.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapUtils.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/LdapUtils.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryException.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapConfigurationDao.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapConfigurationDaoImpl.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapTrustMapDao.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapTrustMapDao.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapTrustMapDao.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapTrustMapDao.java
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapTrustMapDaoImpl.java b/plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapTrustMapDaoImpl.java
similarity index 100%
rename from plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/dao/LdapTrustMapDaoImpl.java
rename to plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/ldap/dao/LdapTrustMapDaoImpl.java
diff --git a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/module.properties b/plugins/user-authenticators/ldap/src/main/resources/META-INF/cloudstack/ldap/module.properties
similarity index 100%
rename from plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/module.properties
rename to plugins/user-authenticators/ldap/src/main/resources/META-INF/cloudstack/ldap/module.properties
diff --git a/plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml b/plugins/user-authenticators/ldap/src/main/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
similarity index 100%
rename from plugins/user-authenticators/ldap/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
rename to plugins/user-authenticators/ldap/src/main/resources/META-INF/cloudstack/ldap/spring-ldap-context.xml
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
deleted file mode 100644
index 564c1d0..0000000
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java
+++ /dev/null
@@ -1,251 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command;
-
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.LdapUserResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.RoleResponse;
-import org.apache.cloudstack.ldap.LdapManager;
-import org.apache.cloudstack.ldap.LdapUser;
-import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.bouncycastle.util.encoders.Base64;
-
-import com.cloud.domain.Domain;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.AccountService;
-import com.cloud.user.DomainService;
-
-@APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0",
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class LdapImportUsersCmd extends BaseListCmd {
-
-    public static final Logger s_logger = Logger.getLogger(LdapImportUsersCmd.class.getName());
-
-    private static final String s_name = "ldapuserresponse";
-
-    @Parameter(name = ApiConstants.TIMEZONE,
-               type = CommandType.STRING,
-               description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
-    private String timezone;
-
-    @Parameter(name = ApiConstants.ACCOUNT_TYPE,
-               type = CommandType.SHORT,
-               description = "Type of the account.  Specify 0 for user, 1 for root admin, and 2 for domain admin")
-    private Short accountType;
-
-    @Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
-    private Long roleId;
-
-    @Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
-    private Map<String, String> details;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID,
-               type = CommandType.UUID,
-               entityType = DomainResponse.class,
-               description = "Specifies the domain to which the ldap users are to be "
-                   + "imported. If no domain is specified, a domain will created using group parameter. If the group is also not specified, a domain name based on the OU information will be "
-                   + "created. If no OU hierarchy exists, will be defaulted to ROOT domain")
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Specifies the group name from which the ldap users are to be imported. "
-        + "If no group is specified, all the users will be imported.")
-    private String groupName;
-
-    private Domain _domain;
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.")
-    private String accountName;
-
-    @Inject
-    private LdapManager _ldapManager;
-
-    public LdapImportUsersCmd() {
-        super();
-    }
-
-    public LdapImportUsersCmd(final LdapManager ldapManager, final DomainService domainService, final AccountService accountService) {
-        super();
-        _ldapManager = ldapManager;
-        _domainService = domainService;
-        _accountService = accountService;
-    }
-
-    private void createCloudstackUserAccount(LdapUser user, String accountName, Domain domain) {
-        Account account = _accountService.getActiveAccountByName(accountName, domain.getId());
-        if (account == null) {
-            s_logger.debug("No account exists with name: " + accountName + " creating the account and an user with name: " + user.getUsername() + " in the account");
-            _accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, getAccountType(), getRoleId(),
-                    domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP);
-        } else {
-//            check if the user exists. if yes, call update
-            UserAccount csuser = _accountService.getActiveUserAccount(user.getUsername(), domain.getId());
-            if(csuser == null) {
-                s_logger.debug("No user exists with name: " + user.getUsername() + " creating a user in the account: " + accountName);
-                _accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(),
-                                           UUID.randomUUID().toString(), User.Source.LDAP);
-            } else {
-                s_logger.debug("account with name: " + accountName + " exist and user with name: " + user.getUsername() + " exists in the account. Updating the account.");
-                _accountService.updateUser(csuser.getId(), user.getFirstname(), user.getLastname(), user.getEmail(), null, null, null, null, null);
-            }
-        }
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
-        ResourceAllocationException, NetworkRuleConflictException {
-        if (getAccountType() == null && getRoleId() == null) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
-        }
-        List<LdapUser> users;
-        try {
-            if (StringUtils.isNotBlank(groupName)) {
-
-                users = _ldapManager.getUsersInGroup(groupName, domainId);
-            } else {
-                users = _ldapManager.getUsers(domainId);
-            }
-        } catch (NoLdapUserMatchingQueryException ex) {
-            users = new ArrayList<LdapUser>();
-            s_logger.info("No Ldap user matching query. " + " ::: " + ex.getMessage());
-        }
-
-        List<LdapUser> addedUsers = new ArrayList<LdapUser>();
-        for (LdapUser user : users) {
-            Domain domain = getDomain(user);
-            try {
-                createCloudstackUserAccount(user, getAccountName(user), domain);
-                addedUsers.add(user);
-            } catch (InvalidParameterValueException ex) {
-                s_logger.error("Failed to create user with username: " + user.getUsername() + " ::: " + ex.getMessage());
-            }
-        }
-        ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
-        response.setResponses(createLdapUserResponse(addedUsers));
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-
-    public Short getAccountType() {
-        return RoleType.getAccountTypeByRole(roleService.findRole(roleId), accountType);
-    }
-
-    public Long getRoleId() {
-        return RoleType.getRoleByAccountType(roleId, accountType);
-    }
-
-    private String getAccountName(LdapUser user) {
-        String finalAccountName = accountName;
-        if(finalAccountName == null ) {
-            finalAccountName = user.getUsername();
-        }
-        return finalAccountName;
-    }
-
-    private Domain getDomainForName(String name) {
-        Domain domain = null;
-        if (StringUtils.isNotBlank(name)) {
-            //removing all the special characters and trimming its length to 190 to make the domain valid.
-            String domainName = StringUtils.substring(name.replaceAll("\\W", ""), 0, 190);
-            if (StringUtils.isNotBlank(domainName)) {
-                domain = _domainService.getDomainByName(domainName, Domain.ROOT_DOMAIN);
-                if (domain == null) {
-                    domain = _domainService.createDomain(domainName, Domain.ROOT_DOMAIN, domainName, UUID.randomUUID().toString());
-                }
-            }
-        }
-        return domain;
-    }
-
-    private Domain getDomain(LdapUser user) {
-        Domain domain;
-        if (_domain != null) {
-            //this means either domain id or groupname is passed and this will be same for all the users in this call. hence returning it.
-            domain = _domain;
-        } else {
-            if (domainId != null) {
-                // a domain Id is passed. use it for this user and all the users in the same api call (by setting _domain)
-                domain = _domain = _domainService.getDomain(domainId);
-            } else {
-                // a group name is passed. use it for this user and all the users in the same api call(by setting _domain)
-                domain = _domain = getDomainForName(groupName);
-                if (domain == null) {
-                    //use the domain from the LDAP for this user
-                    domain = getDomainForName(user.getDomain());
-                }
-            }
-            if (domain == null) {
-                // could not get a domain using domainId / LDAP group / OU of LDAP user. using ROOT domain for this user
-                domain = _domainService.getDomain(Domain.ROOT_DOMAIN);
-            }
-        }
-        return domain;
-    }
-
-    private List<LdapUserResponse> createLdapUserResponse(List<LdapUser> users) {
-        final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>();
-        for (final LdapUser user : users) {
-            final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user);
-            ldapResponse.setObjectName("LdapUser");
-            ldapResponses.add(ldapResponse);
-        }
-        return ldapResponses;
-    }
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    private String generatePassword() throws ServerApiException {
-        try {
-            final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
-            final byte bytes[] = new byte[20];
-            randomGen.nextBytes(bytes);
-            return new String(Base64.encode(bytes), "UTF-8");
-        } catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
-        }
-    }
-}
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/ADLdapUserManagerImplSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/BasicNamingEnumerationImpl.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapAddConfigurationCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapAuthenticatorSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationDaoImplSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationResponseSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapContextFactorySpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapListConfigurationCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapListUsersCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListUsersCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapListUsersCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapManagerImplSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapSearchUserCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserManagerFactorySpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserResponseSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LdapUtilsSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LinkDomainToLdapCmdSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LinkDomainToLdapCmdSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LinkDomainToLdapCmdSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/LinkDomainToLdapCmdSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/NoLdapUserMatchingQueryExceptionSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy b/plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
similarity index 100%
rename from plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
rename to plugins/user-authenticators/ldap/src/test/groovy/org/apache/cloudstack/ldap/OpenLdapUserManagerSpec.groovy
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapConfigurationChanger.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapConfigurationChanger.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapConfigurationChanger.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapConfigurationChanger.java
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapCreateAccountCmdTest.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapCreateAccountCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapCreateAccountCmdTest.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapCreateAccountCmdTest.java
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapImportUsersCmdTest.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapImportUsersCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LdapImportUsersCmdTest.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LdapImportUsersCmdTest.java
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LinkAccountToLdapCmdTest.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LinkAccountToLdapCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LinkAccountToLdapCmdTest.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LinkAccountToLdapCmdTest.java
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LinkDomainToLdapCmdTest.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LinkDomainToLdapCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/api/command/LinkDomainToLdapCmdTest.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/api/command/LinkDomainToLdapCmdTest.java
diff --git a/plugins/user-authenticators/ldap/test/org/apache/cloudstack/ldap/LdapConfigurationTest.java b/plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/ldap/LdapConfigurationTest.java
similarity index 100%
rename from plugins/user-authenticators/ldap/test/org/apache/cloudstack/ldap/LdapConfigurationTest.java
rename to plugins/user-authenticators/ldap/src/test/java/org/apache/cloudstack/ldap/LdapConfigurationTest.java
diff --git a/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif b/plugins/user-authenticators/ldap/src/test/resources/cloudstack.org.ldif
similarity index 100%
rename from plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
rename to plugins/user-authenticators/ldap/src/test/resources/cloudstack.org.ldif
diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml
index e9df596..4045e52 100644
--- a/plugins/user-authenticators/md5/pom.xml
+++ b/plugins/user-authenticators/md5/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-user-authenticator-md5</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator MD5</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-user-authenticator-md5</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator MD5</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java b/plugins/user-authenticators/md5/src/main/java/com/cloud/server/auth/MD5UserAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java
rename to plugins/user-authenticators/md5/src/main/java/com/cloud/server/auth/MD5UserAuthenticator.java
diff --git a/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/module.properties b/plugins/user-authenticators/md5/src/main/resources/META-INF/cloudstack/md5/module.properties
similarity index 100%
rename from plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/module.properties
rename to plugins/user-authenticators/md5/src/main/resources/META-INF/cloudstack/md5/module.properties
diff --git a/plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/spring-md5-context.xml b/plugins/user-authenticators/md5/src/main/resources/META-INF/cloudstack/md5/spring-md5-context.xml
similarity index 100%
rename from plugins/user-authenticators/md5/resources/META-INF/cloudstack/md5/spring-md5-context.xml
rename to plugins/user-authenticators/md5/src/main/resources/META-INF/cloudstack/md5/spring-md5-context.xml
diff --git a/plugins/user-authenticators/md5/test/com/cloud/server/auth/MD5UserAuthenticatorTest.java b/plugins/user-authenticators/md5/src/test/java/com/cloud/server/auth/MD5UserAuthenticatorTest.java
similarity index 100%
rename from plugins/user-authenticators/md5/test/com/cloud/server/auth/MD5UserAuthenticatorTest.java
rename to plugins/user-authenticators/md5/src/test/java/com/cloud/server/auth/MD5UserAuthenticatorTest.java
diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml
index 58eaf74..b166cf0 100644
--- a/plugins/user-authenticators/pbkdf2/pom.xml
+++ b/plugins/user-authenticators/pbkdf2/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-user-authenticator-pbkdf2</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator PBKDF2-SHA-256</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-user-authenticator-pbkdf2</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator PBKDF2-SHA-256</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/user-authenticators/pbkdf2/src/org/apache/cloudstack/server/auth/PBKDF2UserAuthenticator.java b/plugins/user-authenticators/pbkdf2/src/main/java/org/apache/cloudstack/server/auth/PBKDF2UserAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/pbkdf2/src/org/apache/cloudstack/server/auth/PBKDF2UserAuthenticator.java
rename to plugins/user-authenticators/pbkdf2/src/main/java/org/apache/cloudstack/server/auth/PBKDF2UserAuthenticator.java
diff --git a/plugins/user-authenticators/pbkdf2/resources/META-INF/cloudstack/pbkdf2/module.properties b/plugins/user-authenticators/pbkdf2/src/main/resources/META-INF/cloudstack/pbkdf2/module.properties
similarity index 100%
rename from plugins/user-authenticators/pbkdf2/resources/META-INF/cloudstack/pbkdf2/module.properties
rename to plugins/user-authenticators/pbkdf2/src/main/resources/META-INF/cloudstack/pbkdf2/module.properties
diff --git a/plugins/user-authenticators/pbkdf2/resources/META-INF/cloudstack/pbkdf2/spring-pbkdf2-context.xml b/plugins/user-authenticators/pbkdf2/src/main/resources/META-INF/cloudstack/pbkdf2/spring-pbkdf2-context.xml
similarity index 100%
rename from plugins/user-authenticators/pbkdf2/resources/META-INF/cloudstack/pbkdf2/spring-pbkdf2-context.xml
rename to plugins/user-authenticators/pbkdf2/src/main/resources/META-INF/cloudstack/pbkdf2/spring-pbkdf2-context.xml
diff --git a/plugins/user-authenticators/pbkdf2/test/org/apache/cloudstack/server/auth/PBKD2UserAuthenticatorTest.java b/plugins/user-authenticators/pbkdf2/src/test/java/org/apache/cloudstack/server/auth/PBKD2UserAuthenticatorTest.java
similarity index 100%
rename from plugins/user-authenticators/pbkdf2/test/org/apache/cloudstack/server/auth/PBKD2UserAuthenticatorTest.java
rename to plugins/user-authenticators/pbkdf2/src/test/java/org/apache/cloudstack/server/auth/PBKD2UserAuthenticatorTest.java
diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml
index e0d0750..ecea63c 100644
--- a/plugins/user-authenticators/plain-text/pom.xml
+++ b/plugins/user-authenticators/plain-text/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-user-authenticator-plaintext</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator Plain Text</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-user-authenticator-plaintext</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator Plain Text</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java b/plugins/user-authenticators/plain-text/src/main/java/com/cloud/server/auth/PlainTextUserAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java
rename to plugins/user-authenticators/plain-text/src/main/java/com/cloud/server/auth/PlainTextUserAuthenticator.java
diff --git a/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/module.properties b/plugins/user-authenticators/plain-text/src/main/resources/META-INF/cloudstack/plaintext/module.properties
similarity index 100%
rename from plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/module.properties
rename to plugins/user-authenticators/plain-text/src/main/resources/META-INF/cloudstack/plaintext/module.properties
diff --git a/plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml b/plugins/user-authenticators/plain-text/src/main/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml
similarity index 100%
rename from plugins/user-authenticators/plain-text/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml
rename to plugins/user-authenticators/plain-text/src/main/resources/META-INF/cloudstack/plaintext/spring-plaintext-context.xml
diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml
index 1a86f22..ce1ed95 100644
--- a/plugins/user-authenticators/saml2/pom.xml
+++ b/plugins/user-authenticators/saml2/pom.xml
@@ -1,57 +1,57 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-user-authenticator-saml2</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator SAML2</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.opensaml</groupId>
-      <artifactId>opensaml</artifactId>
-      <version>${cs.opensaml.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>xerces</groupId>
-      <artifactId>xercesImpl</artifactId>
-      <version>2.11.0</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+<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-user-authenticator-saml2</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator SAML2</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.opensaml</groupId>
+            <artifactId>opensaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>xerces</groupId>
+            <artifactId>xercesImpl</artifactId>
+            <version>${cs.xercesImpl.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/AuthorizeSAMLSSOCmd.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/GetServiceProviderMetaDataCmd.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListIdpsCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListIdpsCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListIdpsCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListIdpsCmd.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListSamlAuthorizationCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListSamlAuthorizationCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/ListSamlAuthorizationCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListSamlAuthorizationCmd.java
diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
new file mode 100644
index 0000000..4b48646
--- /dev/null
+++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
@@ -0,0 +1,381 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.FactoryConfigurationError;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ApiServerService;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.auth.APIAuthenticationType;
+import org.apache.cloudstack.api.auth.APIAuthenticator;
+import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.saml.SAML2AuthManager;
+import org.apache.cloudstack.saml.SAMLPluginConstants;
+import org.apache.cloudstack.saml.SAMLProviderMetadata;
+import org.apache.cloudstack.saml.SAMLTokenVO;
+import org.apache.cloudstack.saml.SAMLUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.encryption.Decrypter;
+import org.opensaml.xml.ConfigurationException;
+import org.opensaml.xml.encryption.DecryptionException;
+import org.opensaml.xml.encryption.EncryptedKeyResolver;
+import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.security.SecurityHelper;
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureValidator;
+import org.opensaml.xml.validation.ValidationException;
+import org.xml.sax.SAXException;
+
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.user.Account;
+import com.cloud.user.DomainManager;
+import com.cloud.user.UserAccount;
+import com.cloud.user.UserAccountVO;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.utils.db.EntityManager;
+
+@APICommand(name = "samlSso", description = "SP initiated SAML Single Sign On", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
+public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator, Configurable {
+    public static final Logger s_logger = Logger.getLogger(SAML2LoginAPIAuthenticatorCmd.class.getName());
+    private static final String s_name = "loginresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.IDP_ID, type = CommandType.STRING, description = "Identity Provider Entity ID", required = true)
+    private String idpId;
+
+    @Inject
+    ApiServerService apiServer;
+    @Inject
+    EntityManager entityMgr;
+    @Inject
+    DomainManager domainMgr;
+    @Inject
+    private UserAccountDao userAccountDao;
+
+    protected static ConfigKey<String> saml2FailedLoginRedirectUrl = new ConfigKey<String>("Advanced", String.class, "saml2.failed.login.redirect.url", "",
+            "The URL to redirect the SAML2 login failed message (the default vaulue is empty).", true);
+
+    SAML2AuthManager samlAuthManager;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getIdpId() {
+        return idpId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_TYPE_NORMAL;
+    }
+
+    @Override
+    public void execute() throws ServerApiException {
+        // We should never reach here
+        throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
+    }
+
+    public Response processSAMLResponse(String responseMessage) {
+        Response responseObject = null;
+        try {
+            DefaultBootstrap.bootstrap();
+            responseObject = SAMLUtils.decodeSAMLResponse(responseMessage);
+
+        } catch (ConfigurationException | FactoryConfigurationError | ParserConfigurationException | SAXException | IOException | UnmarshallingException e) {
+            s_logger.error("SAMLResponse processing error: " + e.getMessage());
+        }
+        return responseObject;
+    }
+
+    @Override
+    public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, final InetAddress remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletRequest req, final HttpServletResponse resp) throws ServerApiException {
+        try {
+            if (!params.containsKey(SAMLPluginConstants.SAML_RESPONSE) && !params.containsKey("SAMLart")) {
+                String idpId = null;
+                String domainPath = null;
+
+                if (params.containsKey(ApiConstants.IDP_ID)) {
+                    idpId = ((String[])params.get(ApiConstants.IDP_ID))[0];
+                }
+
+                if (params.containsKey(ApiConstants.DOMAIN)) {
+                    domainPath = ((String[])params.get(ApiConstants.DOMAIN))[0];
+                }
+
+                if (domainPath != null && !domainPath.isEmpty()) {
+                    if (!domainPath.startsWith("/")) {
+                        domainPath = "/" + domainPath;
+                    }
+                    if (!domainPath.endsWith("/")) {
+                        domainPath = domainPath + "/";
+                    }
+                }
+
+                SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
+                SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(idpId);
+                if (idpMetadata == null) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(),
+                            "IdP ID (" + idpId + ") is not found in our list of supported IdPs, cannot proceed.",
+                            params, responseType));
+                }
+                if (idpMetadata.getSsoUrl() == null || idpMetadata.getSsoUrl().isEmpty()) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(),
+                            "IdP ID (" + idpId + ") has no Single Sign On URL defined please contact "
+                                    + idpMetadata.getContactPersonName() + " <" + idpMetadata.getContactPersonEmail() + ">, cannot proceed.",
+                            params, responseType));
+                }
+                String authnId = SAMLUtils.generateSecureRandomId();
+                samlAuthManager.saveToken(authnId, domainPath, idpMetadata.getEntityId());
+                s_logger.debug("Sending SAMLRequest id=" + authnId);
+                String redirectUrl = SAMLUtils.buildAuthnRequestUrl(authnId, spMetadata, idpMetadata, SAML2AuthManager.SAMLSignatureAlgorithm.value());
+                resp.sendRedirect(redirectUrl);
+                return "";
+            } if (params.containsKey("SAMLart")) {
+                throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, apiServer.getSerializedApiError(ApiErrorCode.UNSUPPORTED_ACTION_ERROR.getHttpCode(),
+                        "SAML2 HTTP Artifact Binding is not supported",
+                        params, responseType));
+            } else {
+                final String samlResponse = ((String[])params.get(SAMLPluginConstants.SAML_RESPONSE))[0];
+                Response processedSAMLResponse = this.processSAMLResponse(samlResponse);
+                String statusCode = processedSAMLResponse.getStatus().getStatusCode().getValue();
+                if (!statusCode.equals(StatusCode.SUCCESS_URI)) {
+                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                            "Identity Provider send a non-successful authentication status code",
+                            params, responseType));
+                }
+
+                String username = null;
+                Issuer issuer = processedSAMLResponse.getIssuer();
+                SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
+                SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(issuer.getValue());
+
+                String responseToId = processedSAMLResponse.getInResponseTo();
+                s_logger.debug("Received SAMLResponse in response to id=" + responseToId);
+                SAMLTokenVO token = samlAuthManager.getToken(responseToId);
+                if (token != null) {
+                    if (!(token.getEntity().equalsIgnoreCase(issuer.getValue()))) {
+                        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                                "The SAML response contains Issuer Entity ID that is different from the original SAML request",
+                                params, responseType));
+                    }
+                } else {
+                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                            "Received SAML response for a SSO request that we may not have made or has expired, please try logging in again",
+                            params, responseType));
+                }
+
+                // Set IdpId for this session
+                session.setAttribute(SAMLPluginConstants.SAML_IDPID, issuer.getValue());
+
+                Signature sig = processedSAMLResponse.getSignature();
+                if (idpMetadata.getSigningCertificate() != null && sig != null) {
+                    BasicX509Credential credential = new BasicX509Credential();
+                    credential.setEntityCertificate(idpMetadata.getSigningCertificate());
+                    SignatureValidator validator = new SignatureValidator(credential);
+                    try {
+                        validator.validate(sig);
+                    } catch (ValidationException e) {
+                        s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
+                        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                                "SAML Response's signature failed to be validated by IDP signing key",
+                                params, responseType));
+                    }
+                }
+                if (username == null) {
+                    username = SAMLUtils.getValueFromAssertions(processedSAMLResponse.getAssertions(), SAML2AuthManager.SAMLUserAttributeName.value());
+                }
+
+                for (Assertion assertion: processedSAMLResponse.getAssertions()) {
+                    if (assertion!= null && assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
+                        session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
+                        break;
+                    }
+                }
+
+                if (idpMetadata.getEncryptionCertificate() != null && spMetadata != null
+                        && spMetadata.getKeyPair() != null && spMetadata.getKeyPair().getPrivate() != null) {
+                    Credential credential = SecurityHelper.getSimpleCredential(idpMetadata.getEncryptionCertificate().getPublicKey(),
+                            spMetadata.getKeyPair().getPrivate());
+                    StaticKeyInfoCredentialResolver keyInfoResolver = new StaticKeyInfoCredentialResolver(credential);
+                    EncryptedKeyResolver keyResolver = new InlineEncryptedKeyResolver();
+                    Decrypter decrypter = new Decrypter(null, keyInfoResolver, keyResolver);
+                    decrypter.setRootInNewDocument(true);
+                    List<EncryptedAssertion> encryptedAssertions = processedSAMLResponse.getEncryptedAssertions();
+                    if (encryptedAssertions != null) {
+                        for (EncryptedAssertion encryptedAssertion : encryptedAssertions) {
+                            Assertion assertion = null;
+                            try {
+                                assertion = decrypter.decrypt(encryptedAssertion);
+                            } catch (DecryptionException e) {
+                                s_logger.warn("SAML EncryptedAssertion error: " + e.toString());
+                            }
+                            if (assertion == null) {
+                                continue;
+                            }
+                            Signature encSig = assertion.getSignature();
+                            if (idpMetadata.getSigningCertificate() != null && encSig != null) {
+                                BasicX509Credential sigCredential = new BasicX509Credential();
+                                sigCredential.setEntityCertificate(idpMetadata.getSigningCertificate());
+                                SignatureValidator validator = new SignatureValidator(sigCredential);
+                                try {
+                                    validator.validate(encSig);
+                                } catch (ValidationException e) {
+                                    s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
+                                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                                            "SAML Response's signature failed to be validated by IDP signing key",
+                                            params, responseType));
+                                }
+                            }
+                            if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
+                                session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
+                            }
+                            if (username == null) {
+                                username = SAMLUtils.getValueFromAttributeStatements(assertion.getAttributeStatements(), SAML2AuthManager.SAMLUserAttributeName.value());
+                            }
+                        }
+                    }
+                }
+
+                if (username == null) {
+                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                            "Failed to find admin configured username attribute in the SAML Response. Please ask your administrator to check SAML user attribute name.", params, responseType));
+                }
+
+                UserAccount userAccount = null;
+                List<UserAccountVO> possibleUserAccounts = userAccountDao.getAllUsersByNameAndEntity(username, issuer.getValue());
+                if (possibleUserAccounts != null && possibleUserAccounts.size() > 0) {
+                    // Log into the first enabled user account
+                    // Users can switch to other allowed accounts later
+                    for (UserAccountVO possibleUserAccount : possibleUserAccounts) {
+                        if (possibleUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
+                            userAccount = possibleUserAccount;
+                            break;
+                        }
+                    }
+                }
+
+                whenFailToAuthenticateThrowExceptionOrRedirectToUrl(params, responseType, resp, issuer, userAccount);
+
+                try {
+                    if (apiServer.verifyUser(userAccount.getId())) {
+                        LoginCmdResponse loginResponse = (LoginCmdResponse) apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(),
+                                userAccount.getDomainId(), null, remoteAddress, params);
+                        SAMLUtils.setupSamlUserCookies(loginResponse, resp);
+                        resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
+                        return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
+                    }
+                } catch (CloudAuthenticationException | IOException exception) {
+                    s_logger.debug("SAML Login failed to log in the user due to: " + exception.getMessage());
+                }
+            }
+        } catch (IOException e) {
+            auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
+            auditTrailSb.append(e.getMessage());
+        }
+        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                "Unable to authenticate user while performing SAML based SSO. Please make sure your user/account has been added, enable and authorized by the admin before you can authenticate. Please contact your administrator.",
+                params, responseType));
+    }
+
+    /**
+     * If it fails to authenticate the user, the method gets the value from configuration
+     * Saml2FailedLoginRedirectUrl; if the user configured an error URL then it redirects to that
+     * URL, otherwise it throws the ServerApiException
+     */
+    protected void whenFailToAuthenticateThrowExceptionOrRedirectToUrl(final Map<String, Object[]> params, final String responseType, final HttpServletResponse resp, Issuer issuer,
+            UserAccount userAccount) throws IOException {
+        if (userAccount == null || userAccount.getExternalEntity() == null || !samlAuthManager.isUserAuthorized(userAccount.getId(), issuer.getValue())) {
+            String saml2RedirectUrl = saml2FailedLoginRedirectUrl.value();
+            if (StringUtils.isBlank(saml2RedirectUrl)) {
+                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
+                        "Your authenticated user is not authorized for SAML Single Sign-On, please contact your administrator", params, responseType));
+            } else {
+                resp.sendRedirect(saml2RedirectUrl);
+            }
+        }
+    }
+
+    @Override
+    public APIAuthenticationType getAPIType() {
+        return APIAuthenticationType.LOGIN_API;
+    }
+
+    @Override
+    public void setAuthenticators(List<PluggableAPIAuthenticator> authenticators) {
+        for (PluggableAPIAuthenticator authManager: authenticators) {
+            if (authManager != null && authManager instanceof SAML2AuthManager) {
+                samlAuthManager = (SAML2AuthManager) authManager;
+            }
+        }
+        if (samlAuthManager == null) {
+            s_logger.error("No suitable Pluggable Authentication Manager found for SAML2 Login Cmd");
+        }
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return SAML2LoginAPIAuthenticatorCmd.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {saml2FailedLoginRedirectUrl};
+    }
+
+}
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/IdpResponse.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/IdpResponse.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/IdpResponse.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/IdpResponse.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SAMLMetaDataResponse.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SAMLMetaDataResponse.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SAMLMetaDataResponse.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SAMLMetaDataResponse.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SamlAuthorizationResponse.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SamlAuthorizationResponse.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SamlAuthorizationResponse.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SamlAuthorizationResponse.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SamlUserAccountResponse.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SamlUserAccountResponse.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/response/SamlUserAccountResponse.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/response/SamlUserAccountResponse.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2UserAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2UserAuthenticator.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2UserAuthenticator.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLPluginConstants.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLPluginConstants.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLPluginConstants.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLPluginConstants.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLProviderMetadata.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLProviderMetadata.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLProviderMetadata.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLProviderMetadata.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenDao.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenDao.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenDao.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenDao.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenDaoImpl.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenDaoImpl.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenDaoImpl.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenDaoImpl.java
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenVO.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenVO.java
similarity index 100%
rename from plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLTokenVO.java
rename to plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLTokenVO.java
diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java
new file mode 100644
index 0000000..6110cc5
--- /dev/null
+++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java
@@ -0,0 +1,364 @@
+//
+// 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.saml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.List;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.FactoryConfigurationError;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.cloudstack.utils.security.CertUtils;
+import org.apache.log4j.Logger;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.DefaultBootstrap;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.saml2.core.AuthnContext;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.LogoutRequest;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
+import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
+import org.opensaml.saml2.core.impl.IssuerBuilder;
+import org.opensaml.saml2.core.impl.LogoutRequestBuilder;
+import org.opensaml.saml2.core.impl.NameIDBuilder;
+import org.opensaml.saml2.core.impl.RequestedAuthnContextBuilder;
+import org.opensaml.xml.ConfigurationException;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.io.Unmarshaller;
+import org.opensaml.xml.io.UnmarshallerFactory;
+import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.signature.SignatureConstants;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import com.cloud.utils.HttpUtils;
+
+public class SAMLUtils {
+    public static final Logger s_logger = Logger.getLogger(SAMLUtils.class);
+
+    public static String generateSecureRandomId() {
+        return new BigInteger(160, new SecureRandom()).toString(32);
+    }
+
+    public static String getValueFromAttributeStatements(final List<AttributeStatement> attributeStatements, final String attributeKey) {
+        if (attributeStatements == null || attributeStatements.size() < 1 || attributeKey == null) {
+            return null;
+        }
+        for (AttributeStatement attributeStatement : attributeStatements) {
+            if (attributeStatement == null || attributeStatements.size() < 1) {
+                continue;
+            }
+            for (Attribute attribute : attributeStatement.getAttributes()) {
+                if (attribute.getAttributeValues() != null && attribute.getAttributeValues().size() > 0) {
+                    String value = attribute.getAttributeValues().get(0).getDOM().getTextContent();
+                    s_logger.debug("SAML attribute name: " + attribute.getName() + " friendly-name:" + attribute.getFriendlyName() + " value:" + value);
+                    if (attributeKey.equals(attribute.getName()) || attributeKey.equals(attribute.getFriendlyName())) {
+                        return value;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public static String getValueFromAssertions(final List<Assertion> assertions, final String attributeKey) {
+        if (assertions == null || attributeKey == null) {
+            return null;
+        }
+        for (Assertion assertion : assertions) {
+            String value = getValueFromAttributeStatements(assertion.getAttributeStatements(), attributeKey);
+            if (value != null) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    public static String buildAuthnRequestUrl(final String authnId, final SAMLProviderMetadata spMetadata, final SAMLProviderMetadata idpMetadata, final String signatureAlgorithm) {
+        String redirectUrl = "";
+        try {
+            DefaultBootstrap.bootstrap();
+            AuthnRequest authnRequest = SAMLUtils.buildAuthnRequestObject(authnId, spMetadata.getEntityId(), idpMetadata.getSsoUrl(), spMetadata.getSsoUrl());
+            PrivateKey privateKey = null;
+            if (spMetadata.getKeyPair() != null) {
+                privateKey = spMetadata.getKeyPair().getPrivate();
+            }
+            redirectUrl = idpMetadata.getSsoUrl() + "?" + SAMLUtils.generateSAMLRequestSignature("SAMLRequest=" + SAMLUtils.encodeSAMLRequest(authnRequest), privateKey, signatureAlgorithm);
+        } catch (ConfigurationException | FactoryConfigurationError | MarshallingException | IOException | NoSuchAlgorithmException | InvalidKeyException | java.security.SignatureException e) {
+            s_logger.error("SAML AuthnRequest message building error: " + e.getMessage());
+        }
+        return redirectUrl;
+    }
+
+    public static AuthnRequest buildAuthnRequestObject(final String authnId, final String spId, final String idpUrl, final String consumerUrl) {
+        // Issuer object
+        IssuerBuilder issuerBuilder = new IssuerBuilder();
+        Issuer issuer = issuerBuilder.buildObject();
+        issuer.setValue(spId);
+
+        // AuthnContextClass
+        AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
+        AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(
+                SAMLConstants.SAML20_NS,
+                "AuthnContextClassRef", "saml");
+        authnContextClassRef.setAuthnContextClassRef(AuthnContext.PPT_AUTHN_CTX);
+
+        // AuthnContext
+        RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
+        RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
+        requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
+        requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
+
+        // Creation of AuthRequestObject
+        AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder();
+        AuthnRequest authnRequest = authRequestBuilder.buildObject();
+        authnRequest.setID(authnId);
+        authnRequest.setDestination(idpUrl);
+        authnRequest.setVersion(SAMLVersion.VERSION_20);
+        authnRequest.setForceAuthn(false);
+        authnRequest.setIsPassive(false);
+        authnRequest.setIssueInstant(new DateTime());
+        authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
+        authnRequest.setAssertionConsumerServiceURL(consumerUrl);
+        authnRequest.setProviderName(spId);
+        authnRequest.setIssuer(issuer);
+        authnRequest.setRequestedAuthnContext(requestedAuthnContext);
+
+        return authnRequest;
+    }
+
+    public static LogoutRequest buildLogoutRequest(String logoutUrl, String spId, String nameIdString) {
+        Issuer issuer = new IssuerBuilder().buildObject();
+        issuer.setValue(spId);
+        NameID nameID = new NameIDBuilder().buildObject();
+        nameID.setValue(nameIdString);
+        LogoutRequest logoutRequest = new LogoutRequestBuilder().buildObject();
+        logoutRequest.setID(generateSecureRandomId());
+        logoutRequest.setDestination(logoutUrl);
+        logoutRequest.setVersion(SAMLVersion.VERSION_20);
+        logoutRequest.setIssueInstant(new DateTime());
+        logoutRequest.setIssuer(issuer);
+        logoutRequest.setNameID(nameID);
+        return logoutRequest;
+    }
+
+    public static String encodeSAMLRequest(XMLObject authnRequest)
+            throws MarshallingException, IOException {
+        Marshaller marshaller = Configuration.getMarshallerFactory()
+                .getMarshaller(authnRequest);
+        Element authDOM = marshaller.marshall(authnRequest);
+        StringWriter requestWriter = new StringWriter();
+        XMLHelper.writeNode(authDOM, requestWriter);
+        String requestMessage = requestWriter.toString();
+        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
+        deflaterOutputStream.write(requestMessage.getBytes(Charset.forName("UTF-8")));
+        deflaterOutputStream.close();
+        String encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
+        encodedRequestMessage = URLEncoder.encode(encodedRequestMessage, HttpUtils.UTF_8).trim();
+        return encodedRequestMessage;
+    }
+
+    public static Response decodeSAMLResponse(String responseMessage)
+            throws ConfigurationException, ParserConfigurationException,
+            SAXException, IOException, UnmarshallingException {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        documentBuilderFactory.setNamespaceAware(true);
+        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
+        byte[] base64DecodedResponse = Base64.decode(responseMessage);
+        Document document = docBuilder.parse(new ByteArrayInputStream(base64DecodedResponse));
+        Element element = document.getDocumentElement();
+        UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
+        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
+        return (Response) unmarshaller.unmarshall(element);
+    }
+
+    public static String generateSAMLRequestSignature(final String urlEncodedString, final PrivateKey signingKey, final String sigAlgorithmName)
+            throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, UnsupportedEncodingException {
+        if (signingKey == null) {
+            return urlEncodedString;
+        }
+
+        String opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
+        String javaSignatureAlgorithmName = "SHA1withRSA";
+
+        if (sigAlgorithmName.equalsIgnoreCase("SHA256")) {
+            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256;
+            javaSignatureAlgorithmName = "SHA256withRSA";
+        } else if (sigAlgorithmName.equalsIgnoreCase("SHA384")) {
+            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA384;
+            javaSignatureAlgorithmName = "SHA384withRSA";
+        } else if (sigAlgorithmName.equalsIgnoreCase("SHA512")) {
+            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512;
+            javaSignatureAlgorithmName = "SHA512withRSA";
+        }
+
+        String url = urlEncodedString + "&SigAlg=" + URLEncoder.encode(opensamlAlgoIdSignature, HttpUtils.UTF_8);
+        Signature signature = Signature.getInstance(javaSignatureAlgorithmName);
+        signature.initSign(signingKey);
+        signature.update(url.getBytes(Charset.forName("UTF-8")));
+        String signatureString = Base64.encodeBytes(signature.sign(), Base64.DONT_BREAK_LINES);
+        if (signatureString != null) {
+            return url + "&Signature=" + URLEncoder.encode(signatureString, HttpUtils.UTF_8);
+        }
+        return url;
+    }
+
+    public static void setupSamlUserCookies(final LoginCmdResponse loginResponse, final HttpServletResponse resp) throws IOException {
+        resp.addCookie(new Cookie("userid", URLEncoder.encode(loginResponse.getUserId(), HttpUtils.UTF_8)));
+        resp.addCookie(new Cookie("domainid", URLEncoder.encode(loginResponse.getDomainId(), HttpUtils.UTF_8)));
+        resp.addCookie(new Cookie("role", URLEncoder.encode(loginResponse.getType(), HttpUtils.UTF_8)));
+        resp.addCookie(new Cookie("username", URLEncoder.encode(loginResponse.getUsername(), HttpUtils.UTF_8)));
+        resp.addCookie(new Cookie("account", URLEncoder.encode(loginResponse.getAccount(), HttpUtils.UTF_8)));
+        String timezone = loginResponse.getTimeZone();
+        if (timezone != null) {
+            resp.addCookie(new Cookie("timezone", URLEncoder.encode(timezone, HttpUtils.UTF_8)));
+        }
+        resp.addCookie(new Cookie("userfullname", URLEncoder.encode(loginResponse.getFirstName() + " " + loginResponse.getLastName(), HttpUtils.UTF_8).replace("+", "%20")));
+        resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", ApiConstants.SESSIONKEY, loginResponse.getSessionKey()));
+    }
+
+    /**
+     * Returns base64 encoded PublicKey
+     * @param key PublicKey
+     * @return public key encoded string
+     */
+    public static String encodePublicKey(PublicKey key) {
+        try {
+            KeyFactory keyFactory = CertUtils.getKeyFactory();
+            if (keyFactory == null) return null;
+            X509EncodedKeySpec spec = keyFactory.getKeySpec(key, X509EncodedKeySpec.class);
+            return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8"));
+        } catch (InvalidKeySpecException e) {
+            s_logger.error("Unable to get KeyFactory:" + e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Returns base64 encoded PrivateKey
+     * @param key PrivateKey
+     * @return privatekey encoded string
+     */
+    public static String encodePrivateKey(PrivateKey key) {
+        try {
+            KeyFactory keyFactory = CertUtils.getKeyFactory();
+            if (keyFactory == null) return null;
+            PKCS8EncodedKeySpec spec = keyFactory.getKeySpec(key,
+                    PKCS8EncodedKeySpec.class);
+            return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8"));
+        } catch (InvalidKeySpecException e) {
+            s_logger.error("Unable to get KeyFactory:" + e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Decodes base64 encoded public key to PublicKey
+     * @param publicKey encoded public key string
+     * @return returns PublicKey
+     */
+    public static PublicKey decodePublicKey(String publicKey) {
+        byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(publicKey);
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes);
+        KeyFactory keyFactory = CertUtils.getKeyFactory();
+        if (keyFactory == null)
+            return null;
+        try {
+            return keyFactory.generatePublic(x509KeySpec);
+        } catch (InvalidKeySpecException e) {
+            s_logger.error("Unable to create PublicKey from PublicKey string:" + e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Decodes base64 encoded private key to PrivateKey
+     * @param privateKey encoded private key string
+     * @return returns PrivateKey
+     */
+    public static PrivateKey decodePrivateKey(String privateKey) {
+        byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(privateKey);
+        PKCS8EncodedKeySpec pkscs8KeySpec = new PKCS8EncodedKeySpec(sigBytes);
+        KeyFactory keyFactory = CertUtils.getKeyFactory();
+        if (keyFactory == null)
+            return null;
+        try {
+            return keyFactory.generatePrivate(pkscs8KeySpec);
+        } catch (InvalidKeySpecException e) {
+            s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage());
+        }
+        return null;
+    }
+
+    public static X509Certificate generateRandomX509Certificate(KeyPair keyPair) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException, SignatureException, InvalidKeyException, OperatorCreationException {
+        return CertUtils.generateV1Certificate(keyPair,
+                "CN=ApacheCloudStack", "CN=ApacheCloudStack",
+                3, "SHA256WithRSA");
+    }
+}
diff --git a/plugins/user-authenticators/saml2/resources/META-INF/cloudstack/saml2/module.properties b/plugins/user-authenticators/saml2/src/main/resources/META-INF/cloudstack/saml2/module.properties
similarity index 100%
rename from plugins/user-authenticators/saml2/resources/META-INF/cloudstack/saml2/module.properties
rename to plugins/user-authenticators/saml2/src/main/resources/META-INF/cloudstack/saml2/module.properties
diff --git a/plugins/user-authenticators/saml2/resources/META-INF/cloudstack/saml2/spring-saml2-context.xml b/plugins/user-authenticators/saml2/src/main/resources/META-INF/cloudstack/saml2/spring-saml2-context.xml
similarity index 100%
rename from plugins/user-authenticators/saml2/resources/META-INF/cloudstack/saml2/spring-saml2-context.xml
rename to plugins/user-authenticators/saml2/src/main/resources/META-INF/cloudstack/saml2/spring-saml2-context.xml
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
deleted file mode 100644
index 41005ab..0000000
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java
+++ /dev/null
@@ -1,348 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command;
-
-import com.cloud.api.response.ApiResponseSerializer;
-import com.cloud.exception.CloudAuthenticationException;
-import com.cloud.user.Account;
-import com.cloud.user.DomainManager;
-import com.cloud.user.UserAccount;
-import com.cloud.user.UserAccountVO;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.utils.db.EntityManager;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ApiServerService;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.auth.APIAuthenticationType;
-import org.apache.cloudstack.api.auth.APIAuthenticator;
-import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
-import org.apache.cloudstack.api.response.LoginCmdResponse;
-import org.apache.cloudstack.saml.SAML2AuthManager;
-import org.apache.cloudstack.saml.SAMLPluginConstants;
-import org.apache.cloudstack.saml.SAMLProviderMetadata;
-import org.apache.cloudstack.saml.SAMLTokenVO;
-import org.apache.cloudstack.saml.SAMLUtils;
-import org.apache.log4j.Logger;
-import org.opensaml.DefaultBootstrap;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.EncryptedAssertion;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.saml2.encryption.Decrypter;
-import org.opensaml.xml.ConfigurationException;
-import org.opensaml.xml.encryption.DecryptionException;
-import org.opensaml.xml.encryption.EncryptedKeyResolver;
-import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
-import org.opensaml.xml.io.UnmarshallingException;
-import org.opensaml.xml.security.SecurityHelper;
-import org.opensaml.xml.security.credential.Credential;
-import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
-import org.opensaml.xml.security.x509.BasicX509Credential;
-import org.opensaml.xml.signature.Signature;
-import org.opensaml.xml.signature.SignatureValidator;
-import org.opensaml.xml.validation.ValidationException;
-import org.xml.sax.SAXException;
-
-import javax.inject.Inject;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.FactoryConfigurationError;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Map;
-
-@APICommand(name = "samlSso", description = "SP initiated SAML Single Sign On", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
-public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
-    public static final Logger s_logger = Logger.getLogger(SAML2LoginAPIAuthenticatorCmd.class.getName());
-    private static final String s_name = "loginresponse";
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-    @Parameter(name = ApiConstants.IDP_ID, type = CommandType.STRING, description = "Identity Provider Entity ID", required = true)
-    private String idpId;
-
-    @Inject
-    ApiServerService _apiServer;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    DomainManager _domainMgr;
-    @Inject
-    private UserAccountDao _userAccountDao;
-
-    SAML2AuthManager _samlAuthManager;
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public String getIdpId() {
-        return idpId;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_TYPE_NORMAL;
-    }
-
-    @Override
-    public void execute() throws ServerApiException {
-        // We should never reach here
-        throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "This is an authentication api, cannot be used directly");
-    }
-
-    public Response processSAMLResponse(String responseMessage) {
-        Response responseObject = null;
-        try {
-            DefaultBootstrap.bootstrap();
-            responseObject = SAMLUtils.decodeSAMLResponse(responseMessage);
-
-        } catch (ConfigurationException | FactoryConfigurationError | ParserConfigurationException | SAXException | IOException | UnmarshallingException e) {
-            s_logger.error("SAMLResponse processing error: " + e.getMessage());
-        }
-        return responseObject;
-    }
-
-    @Override
-    public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, final InetAddress remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletRequest req, final HttpServletResponse resp) throws ServerApiException {
-        try {
-            if (!params.containsKey(SAMLPluginConstants.SAML_RESPONSE) && !params.containsKey("SAMLart")) {
-                String idpId = null;
-                String domainPath = null;
-
-                if (params.containsKey(ApiConstants.IDP_ID)) {
-                    idpId = ((String[])params.get(ApiConstants.IDP_ID))[0];
-                }
-
-                if (params.containsKey(ApiConstants.DOMAIN)) {
-                    domainPath = ((String[])params.get(ApiConstants.DOMAIN))[0];
-                }
-
-                if (domainPath != null && !domainPath.isEmpty()) {
-                    if (!domainPath.startsWith("/")) {
-                        domainPath = "/" + domainPath;
-                    }
-                    if (!domainPath.endsWith("/")) {
-                        domainPath = domainPath + "/";
-                    }
-                }
-
-                SAMLProviderMetadata spMetadata = _samlAuthManager.getSPMetadata();
-                SAMLProviderMetadata idpMetadata = _samlAuthManager.getIdPMetadata(idpId);
-                if (idpMetadata == null) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(),
-                            "IdP ID (" + idpId + ") is not found in our list of supported IdPs, cannot proceed.",
-                            params, responseType));
-                }
-                if (idpMetadata.getSsoUrl() == null || idpMetadata.getSsoUrl().isEmpty()) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(),
-                            "IdP ID (" + idpId + ") has no Single Sign On URL defined please contact "
-                                    + idpMetadata.getContactPersonName() + " <" + idpMetadata.getContactPersonEmail() + ">, cannot proceed.",
-                            params, responseType));
-                }
-                String authnId = SAMLUtils.generateSecureRandomId();
-                _samlAuthManager.saveToken(authnId, domainPath, idpMetadata.getEntityId());
-                s_logger.debug("Sending SAMLRequest id=" + authnId);
-                String redirectUrl = SAMLUtils.buildAuthnRequestUrl(authnId, spMetadata, idpMetadata, SAML2AuthManager.SAMLSignatureAlgorithm.value());
-                resp.sendRedirect(redirectUrl);
-                return "";
-            } if (params.containsKey("SAMLart")) {
-                throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.UNSUPPORTED_ACTION_ERROR.getHttpCode(),
-                        "SAML2 HTTP Artifact Binding is not supported",
-                        params, responseType));
-            } else {
-                final String samlResponse = ((String[])params.get(SAMLPluginConstants.SAML_RESPONSE))[0];
-                Response processedSAMLResponse = this.processSAMLResponse(samlResponse);
-                String statusCode = processedSAMLResponse.getStatus().getStatusCode().getValue();
-                if (!statusCode.equals(StatusCode.SUCCESS_URI)) {
-                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                            "Identity Provider send a non-successful authentication status code",
-                            params, responseType));
-                }
-
-                String username = null;
-                Issuer issuer = processedSAMLResponse.getIssuer();
-                SAMLProviderMetadata spMetadata = _samlAuthManager.getSPMetadata();
-                SAMLProviderMetadata idpMetadata = _samlAuthManager.getIdPMetadata(issuer.getValue());
-
-                String responseToId = processedSAMLResponse.getInResponseTo();
-                s_logger.debug("Received SAMLResponse in response to id=" + responseToId);
-                SAMLTokenVO token = _samlAuthManager.getToken(responseToId);
-                if (token != null) {
-                    if (!(token.getEntity().equalsIgnoreCase(issuer.getValue()))) {
-                        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                                "The SAML response contains Issuer Entity ID that is different from the original SAML request",
-                                params, responseType));
-                    }
-                } else {
-                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                            "Received SAML response for a SSO request that we may not have made or has expired, please try logging in again",
-                            params, responseType));
-                }
-
-                // Set IdpId for this session
-                session.setAttribute(SAMLPluginConstants.SAML_IDPID, issuer.getValue());
-
-                Signature sig = processedSAMLResponse.getSignature();
-                if (idpMetadata.getSigningCertificate() != null && sig != null) {
-                    BasicX509Credential credential = new BasicX509Credential();
-                    credential.setEntityCertificate(idpMetadata.getSigningCertificate());
-                    SignatureValidator validator = new SignatureValidator(credential);
-                    try {
-                        validator.validate(sig);
-                    } catch (ValidationException e) {
-                        s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
-                        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                                "SAML Response's signature failed to be validated by IDP signing key",
-                                params, responseType));
-                    }
-                }
-                if (username == null) {
-                    username = SAMLUtils.getValueFromAssertions(processedSAMLResponse.getAssertions(), SAML2AuthManager.SAMLUserAttributeName.value());
-                }
-
-                for (Assertion assertion: processedSAMLResponse.getAssertions()) {
-                    if (assertion!= null && assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
-                        session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
-                        break;
-                    }
-                }
-
-                if (idpMetadata.getEncryptionCertificate() != null && spMetadata != null
-                        && spMetadata.getKeyPair() != null && spMetadata.getKeyPair().getPrivate() != null) {
-                    Credential credential = SecurityHelper.getSimpleCredential(idpMetadata.getEncryptionCertificate().getPublicKey(),
-                            spMetadata.getKeyPair().getPrivate());
-                    StaticKeyInfoCredentialResolver keyInfoResolver = new StaticKeyInfoCredentialResolver(credential);
-                    EncryptedKeyResolver keyResolver = new InlineEncryptedKeyResolver();
-                    Decrypter decrypter = new Decrypter(null, keyInfoResolver, keyResolver);
-                    decrypter.setRootInNewDocument(true);
-                    List<EncryptedAssertion> encryptedAssertions = processedSAMLResponse.getEncryptedAssertions();
-                    if (encryptedAssertions != null) {
-                        for (EncryptedAssertion encryptedAssertion : encryptedAssertions) {
-                            Assertion assertion = null;
-                            try {
-                                assertion = decrypter.decrypt(encryptedAssertion);
-                            } catch (DecryptionException e) {
-                                s_logger.warn("SAML EncryptedAssertion error: " + e.toString());
-                            }
-                            if (assertion == null) {
-                                continue;
-                            }
-                            Signature encSig = assertion.getSignature();
-                            if (idpMetadata.getSigningCertificate() != null && encSig != null) {
-                                BasicX509Credential sigCredential = new BasicX509Credential();
-                                sigCredential.setEntityCertificate(idpMetadata.getSigningCertificate());
-                                SignatureValidator validator = new SignatureValidator(sigCredential);
-                                try {
-                                    validator.validate(encSig);
-                                } catch (ValidationException e) {
-                                    s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
-                                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                                            "SAML Response's signature failed to be validated by IDP signing key",
-                                            params, responseType));
-                                }
-                            }
-                            if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
-                                session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
-                            }
-                            if (username == null) {
-                                username = SAMLUtils.getValueFromAttributeStatements(assertion.getAttributeStatements(), SAML2AuthManager.SAMLUserAttributeName.value());
-                            }
-                        }
-                    }
-                }
-
-                if (username == null) {
-                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                            "Failed to find admin configured username attribute in the SAML Response. Please ask your administrator to check SAML user attribute name.", params, responseType));
-                }
-
-                UserAccount userAccount = null;
-                List<UserAccountVO> possibleUserAccounts = _userAccountDao.getAllUsersByNameAndEntity(username, issuer.getValue());
-                if (possibleUserAccounts != null && possibleUserAccounts.size() > 0) {
-                    // Log into the first enabled user account
-                    // Users can switch to other allowed accounts later
-                    for (UserAccountVO possibleUserAccount: possibleUserAccounts) {
-                        if (possibleUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
-                            userAccount = possibleUserAccount;
-                            break;
-                        }
-                    }
-                }
-
-                if (userAccount == null || userAccount.getExternalEntity() == null || !_samlAuthManager.isUserAuthorized(userAccount.getId(), issuer.getValue())) {
-                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                            "Your authenticated user is not authorized for SAML Single Sign-On, please contact your administrator",
-                            params, responseType));
-                }
-
-                try {
-                    if (_apiServer.verifyUser(userAccount.getId())) {
-                        LoginCmdResponse loginResponse = (LoginCmdResponse) _apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(),
-                                userAccount.getDomainId(), null, remoteAddress, params);
-                        SAMLUtils.setupSamlUserCookies(loginResponse, resp);
-                        resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
-                        return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
-                    }
-                } catch (CloudAuthenticationException | IOException exception) {
-                    s_logger.debug("SAML Login failed to log in the user due to: " + exception.getMessage());
-                }
-            }
-        } catch (IOException e) {
-            auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
-            auditTrailSb.append(e.getMessage());
-        }
-        throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, _apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(),
-                "Unable to authenticate user while performing SAML based SSO. Please make sure your user/account has been added, enable and authorized by the admin before you can authenticate. Please contact your administrator.",
-                params, responseType));
-    }
-
-    @Override
-    public APIAuthenticationType getAPIType() {
-        return APIAuthenticationType.LOGIN_API;
-    }
-
-    @Override
-    public void setAuthenticators(List<PluggableAPIAuthenticator> authenticators) {
-        for (PluggableAPIAuthenticator authManager: authenticators) {
-            if (authManager != null && authManager instanceof SAML2AuthManager) {
-                _samlAuthManager = (SAML2AuthManager) authManager;
-            }
-        }
-        if (_samlAuthManager == null) {
-            s_logger.error("No suitable Pluggable Authentication Manager found for SAML2 Login Cmd");
-        }
-    }
-}
diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java
deleted file mode 100644
index 5b00d47..0000000
--- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAMLUtils.java
+++ /dev/null
@@ -1,364 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package org.apache.cloudstack.saml;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.net.URLEncoder;
-import java.nio.charset.Charset;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.List;
-import java.util.zip.Deflater;
-import java.util.zip.DeflaterOutputStream;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.FactoryConfigurationError;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.response.LoginCmdResponse;
-import org.apache.cloudstack.utils.security.CertUtils;
-import org.apache.log4j.Logger;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.joda.time.DateTime;
-import org.opensaml.Configuration;
-import org.opensaml.DefaultBootstrap;
-import org.opensaml.common.SAMLVersion;
-import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.Attribute;
-import org.opensaml.saml2.core.AttributeStatement;
-import org.opensaml.saml2.core.AuthnContext;
-import org.opensaml.saml2.core.AuthnContextClassRef;
-import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
-import org.opensaml.saml2.core.AuthnRequest;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.LogoutRequest;
-import org.opensaml.saml2.core.NameID;
-import org.opensaml.saml2.core.RequestedAuthnContext;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
-import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
-import org.opensaml.saml2.core.impl.IssuerBuilder;
-import org.opensaml.saml2.core.impl.LogoutRequestBuilder;
-import org.opensaml.saml2.core.impl.NameIDBuilder;
-import org.opensaml.saml2.core.impl.RequestedAuthnContextBuilder;
-import org.opensaml.xml.ConfigurationException;
-import org.opensaml.xml.XMLObject;
-import org.opensaml.xml.io.Marshaller;
-import org.opensaml.xml.io.MarshallingException;
-import org.opensaml.xml.io.Unmarshaller;
-import org.opensaml.xml.io.UnmarshallerFactory;
-import org.opensaml.xml.io.UnmarshallingException;
-import org.opensaml.xml.signature.SignatureConstants;
-import org.opensaml.xml.util.Base64;
-import org.opensaml.xml.util.XMLHelper;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-import com.cloud.utils.HttpUtils;
-
-public class SAMLUtils {
-    public static final Logger s_logger = Logger.getLogger(SAMLUtils.class);
-
-    public static String generateSecureRandomId() {
-        return new BigInteger(160, new SecureRandom()).toString(32);
-    }
-
-    public static String getValueFromAttributeStatements(final List<AttributeStatement> attributeStatements, final String attributeKey) {
-        if (attributeStatements == null || attributeStatements.size() < 1 || attributeKey == null) {
-            return null;
-        }
-        for (AttributeStatement attributeStatement : attributeStatements) {
-            if (attributeStatement == null || attributeStatements.size() < 1) {
-                continue;
-            }
-            for (Attribute attribute : attributeStatement.getAttributes()) {
-                if (attribute.getAttributeValues() != null && attribute.getAttributeValues().size() > 0) {
-                    String value = attribute.getAttributeValues().get(0).getDOM().getTextContent();
-                    s_logger.debug("SAML attribute name: " + attribute.getName() + " friendly-name:" + attribute.getFriendlyName() + " value:" + value);
-                    if (attributeKey.equals(attribute.getName()) || attributeKey.equals(attribute.getFriendlyName())) {
-                        return value;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    public static String getValueFromAssertions(final List<Assertion> assertions, final String attributeKey) {
-        if (assertions == null || attributeKey == null) {
-            return null;
-        }
-        for (Assertion assertion : assertions) {
-            String value = getValueFromAttributeStatements(assertion.getAttributeStatements(), attributeKey);
-            if (value != null) {
-                return value;
-            }
-        }
-        return null;
-    }
-
-    public static String buildAuthnRequestUrl(final String authnId, final SAMLProviderMetadata spMetadata, final SAMLProviderMetadata idpMetadata, final String signatureAlgorithm) {
-        String redirectUrl = "";
-        try {
-            DefaultBootstrap.bootstrap();
-            AuthnRequest authnRequest = SAMLUtils.buildAuthnRequestObject(authnId, spMetadata.getEntityId(), idpMetadata.getSsoUrl(), spMetadata.getSsoUrl());
-            PrivateKey privateKey = null;
-            if (spMetadata.getKeyPair() != null) {
-                privateKey = spMetadata.getKeyPair().getPrivate();
-            }
-            redirectUrl = idpMetadata.getSsoUrl() + "?" + SAMLUtils.generateSAMLRequestSignature("SAMLRequest=" + SAMLUtils.encodeSAMLRequest(authnRequest), privateKey, signatureAlgorithm);
-        } catch (ConfigurationException | FactoryConfigurationError | MarshallingException | IOException | NoSuchAlgorithmException | InvalidKeyException | java.security.SignatureException e) {
-            s_logger.error("SAML AuthnRequest message building error: " + e.getMessage());
-        }
-        return redirectUrl;
-    }
-
-    public static AuthnRequest buildAuthnRequestObject(final String authnId, final String spId, final String idpUrl, final String consumerUrl) {
-        // Issuer object
-        IssuerBuilder issuerBuilder = new IssuerBuilder();
-        Issuer issuer = issuerBuilder.buildObject();
-        issuer.setValue(spId);
-
-        // AuthnContextClass
-        AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
-        AuthnContextClassRef authnContextClassRef = authnContextClassRefBuilder.buildObject(
-                SAMLConstants.SAML20_NS,
-                "AuthnContextClassRef", "saml");
-        authnContextClassRef.setAuthnContextClassRef(AuthnContext.PPT_AUTHN_CTX);
-
-        // AuthnContext
-        RequestedAuthnContextBuilder requestedAuthnContextBuilder = new RequestedAuthnContextBuilder();
-        RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
-        requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
-        requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
-
-        // Creation of AuthRequestObject
-        AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder();
-        AuthnRequest authnRequest = authRequestBuilder.buildObject();
-        authnRequest.setID(authnId);
-        authnRequest.setDestination(idpUrl);
-        authnRequest.setVersion(SAMLVersion.VERSION_20);
-        authnRequest.setForceAuthn(false);
-        authnRequest.setIsPassive(false);
-        authnRequest.setIssueInstant(new DateTime());
-        authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
-        authnRequest.setAssertionConsumerServiceURL(consumerUrl);
-        authnRequest.setProviderName(spId);
-        authnRequest.setIssuer(issuer);
-        authnRequest.setRequestedAuthnContext(requestedAuthnContext);
-
-        return authnRequest;
-    }
-
-    public static LogoutRequest buildLogoutRequest(String logoutUrl, String spId, String nameIdString) {
-        Issuer issuer = new IssuerBuilder().buildObject();
-        issuer.setValue(spId);
-        NameID nameID = new NameIDBuilder().buildObject();
-        nameID.setValue(nameIdString);
-        LogoutRequest logoutRequest = new LogoutRequestBuilder().buildObject();
-        logoutRequest.setID(generateSecureRandomId());
-        logoutRequest.setDestination(logoutUrl);
-        logoutRequest.setVersion(SAMLVersion.VERSION_20);
-        logoutRequest.setIssueInstant(new DateTime());
-        logoutRequest.setIssuer(issuer);
-        logoutRequest.setNameID(nameID);
-        return logoutRequest;
-    }
-
-    public static String encodeSAMLRequest(XMLObject authnRequest)
-            throws MarshallingException, IOException {
-        Marshaller marshaller = Configuration.getMarshallerFactory()
-                .getMarshaller(authnRequest);
-        Element authDOM = marshaller.marshall(authnRequest);
-        StringWriter requestWriter = new StringWriter();
-        XMLHelper.writeNode(authDOM, requestWriter);
-        String requestMessage = requestWriter.toString();
-        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
-        deflaterOutputStream.write(requestMessage.getBytes(Charset.forName("UTF-8")));
-        deflaterOutputStream.close();
-        String encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
-        encodedRequestMessage = URLEncoder.encode(encodedRequestMessage, HttpUtils.UTF_8).trim();
-        return encodedRequestMessage;
-    }
-
-    public static Response decodeSAMLResponse(String responseMessage)
-            throws ConfigurationException, ParserConfigurationException,
-            SAXException, IOException, UnmarshallingException {
-        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-        documentBuilderFactory.setNamespaceAware(true);
-        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
-        byte[] base64DecodedResponse = Base64.decode(responseMessage);
-        Document document = docBuilder.parse(new ByteArrayInputStream(base64DecodedResponse));
-        Element element = document.getDocumentElement();
-        UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
-        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
-        return (Response) unmarshaller.unmarshall(element);
-    }
-
-    public static String generateSAMLRequestSignature(final String urlEncodedString, final PrivateKey signingKey, final String sigAlgorithmName)
-            throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, UnsupportedEncodingException {
-        if (signingKey == null) {
-            return urlEncodedString;
-        }
-
-        String opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
-        String javaSignatureAlgorithmName = "SHA1withRSA";
-
-        if (sigAlgorithmName.equalsIgnoreCase("SHA256")) {
-            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256;
-            javaSignatureAlgorithmName = "SHA256withRSA";
-        } else if (sigAlgorithmName.equalsIgnoreCase("SHA384")) {
-            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA384;
-            javaSignatureAlgorithmName = "SHA384withRSA";
-        } else if (sigAlgorithmName.equalsIgnoreCase("SHA512")) {
-            opensamlAlgoIdSignature = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512;
-            javaSignatureAlgorithmName = "SHA512withRSA";
-        }
-
-        String url = urlEncodedString + "&SigAlg=" + URLEncoder.encode(opensamlAlgoIdSignature, HttpUtils.UTF_8);
-        Signature signature = Signature.getInstance(javaSignatureAlgorithmName);
-        signature.initSign(signingKey);
-        signature.update(url.getBytes(Charset.forName("UTF-8")));
-        String signatureString = Base64.encodeBytes(signature.sign(), Base64.DONT_BREAK_LINES);
-        if (signatureString != null) {
-            return url + "&Signature=" + URLEncoder.encode(signatureString, HttpUtils.UTF_8);
-        }
-        return url;
-    }
-
-    public static void setupSamlUserCookies(final LoginCmdResponse loginResponse, final HttpServletResponse resp) throws IOException {
-        resp.addCookie(new Cookie("userid", URLEncoder.encode(loginResponse.getUserId(), HttpUtils.UTF_8)));
-        resp.addCookie(new Cookie("domainid", URLEncoder.encode(loginResponse.getDomainId(), HttpUtils.UTF_8)));
-        resp.addCookie(new Cookie("role", URLEncoder.encode(loginResponse.getType(), HttpUtils.UTF_8)));
-        resp.addCookie(new Cookie("username", URLEncoder.encode(loginResponse.getUsername(), HttpUtils.UTF_8)));
-        resp.addCookie(new Cookie("account", URLEncoder.encode(loginResponse.getAccount(), HttpUtils.UTF_8)));
-        String timezone = loginResponse.getTimeZone();
-        if (timezone != null) {
-            resp.addCookie(new Cookie("timezone", URLEncoder.encode(timezone, HttpUtils.UTF_8)));
-        }
-        resp.addCookie(new Cookie("userfullname", URLEncoder.encode(loginResponse.getFirstName() + " " + loginResponse.getLastName(), HttpUtils.UTF_8).replace("+", "%20")));
-        resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", ApiConstants.SESSIONKEY, loginResponse.getSessionKey()));
-    }
-
-    /**
-     * Returns base64 encoded PublicKey
-     * @param key PublicKey
-     * @return public key encoded string
-     */
-    public static String encodePublicKey(PublicKey key) {
-        try {
-            KeyFactory keyFactory = CertUtils.getKeyFactory();
-            if (keyFactory == null) return null;
-            X509EncodedKeySpec spec = keyFactory.getKeySpec(key, X509EncodedKeySpec.class);
-            return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8"));
-        } catch (InvalidKeySpecException e) {
-            s_logger.error("Unable to create KeyFactory:" + e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Returns base64 encoded PrivateKey
-     * @param key PrivateKey
-     * @return privatekey encoded string
-     */
-    public static String encodePrivateKey(PrivateKey key) {
-        try {
-            KeyFactory keyFactory = CertUtils.getKeyFactory();
-            if (keyFactory == null) return null;
-            PKCS8EncodedKeySpec spec = keyFactory.getKeySpec(key,
-                    PKCS8EncodedKeySpec.class);
-            return new String(org.bouncycastle.util.encoders.Base64.encode(spec.getEncoded()), Charset.forName("UTF-8"));
-        } catch (InvalidKeySpecException e) {
-            s_logger.error("Unable to create KeyFactory:" + e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Decodes base64 encoded public key to PublicKey
-     * @param publicKey encoded public key string
-     * @return returns PublicKey
-     */
-    public static PublicKey decodePublicKey(String publicKey) {
-        byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(publicKey);
-        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes);
-        KeyFactory keyFactory = CertUtils.getKeyFactory();
-        if (keyFactory == null)
-            return null;
-        try {
-            return keyFactory.generatePublic(x509KeySpec);
-        } catch (InvalidKeySpecException e) {
-            s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Decodes base64 encoded private key to PrivateKey
-     * @param privateKey encoded private key string
-     * @return returns PrivateKey
-     */
-    public static PrivateKey decodePrivateKey(String privateKey) {
-        byte[] sigBytes = org.bouncycastle.util.encoders.Base64.decode(privateKey);
-        PKCS8EncodedKeySpec pkscs8KeySpec = new PKCS8EncodedKeySpec(sigBytes);
-        KeyFactory keyFactory = CertUtils.getKeyFactory();
-        if (keyFactory == null)
-            return null;
-        try {
-            return keyFactory.generatePrivate(pkscs8KeySpec);
-        } catch (InvalidKeySpecException e) {
-            s_logger.error("Unable to create PrivateKey from privateKey string:" + e.getMessage());
-        }
-        return null;
-    }
-
-    public static X509Certificate generateRandomX509Certificate(KeyPair keyPair) throws NoSuchAlgorithmException, NoSuchProviderException, CertificateException, SignatureException, InvalidKeyException, OperatorCreationException {
-        return CertUtils.generateV1Certificate(keyPair,
-                "CN=ApacheCloudStack", "CN=ApacheCloudStack",
-                3, "SHA256WithRSA");
-    }
-}
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/GetServiceProviderMetaDataCmdTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/GetServiceProviderMetaDataCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/GetServiceProviderMetaDataCmdTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/GetServiceProviderMetaDataCmdTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2AuthManagerImplTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2AuthManagerImplTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2AuthManagerImplTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2AuthManagerImplTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2UserAuthenticatorTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAML2UserAuthenticatorTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2UserAuthenticatorTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAMLUtilsTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/SAMLUtilsTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAMLUtilsTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java
diff --git a/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java
new file mode 100644
index 0000000..cc45cbb
--- /dev/null
+++ b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cloudstack.api.command;
+
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.security.KeyPair;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.cloudstack.api.ApiServerService;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.auth.APIAuthenticationType;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.saml.SAML2AuthManager;
+import org.apache.cloudstack.saml.SAMLPluginConstants;
+import org.apache.cloudstack.saml.SAMLProviderMetadata;
+import org.apache.cloudstack.saml.SAMLUtils;
+import org.apache.cloudstack.utils.security.CertUtils;
+import org.joda.time.DateTime;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opensaml.common.SAMLVersion;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.saml2.core.AuthnStatement;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.Status;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.core.Subject;
+import org.opensaml.saml2.core.impl.AssertionBuilder;
+import org.opensaml.saml2.core.impl.AttributeStatementBuilder;
+import org.opensaml.saml2.core.impl.AuthnStatementBuilder;
+import org.opensaml.saml2.core.impl.IssuerBuilder;
+import org.opensaml.saml2.core.impl.NameIDBuilder;
+import org.opensaml.saml2.core.impl.ResponseBuilder;
+import org.opensaml.saml2.core.impl.StatusBuilder;
+import org.opensaml.saml2.core.impl.StatusCodeBuilder;
+import org.opensaml.saml2.core.impl.SubjectBuilder;
+
+import com.cloud.domain.Domain;
+import com.cloud.user.AccountService;
+import com.cloud.user.DomainManager;
+import com.cloud.user.UserAccountVO;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.utils.HttpUtils;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SAML2LoginAPIAuthenticatorCmdTest {
+
+    @Mock
+    ApiServerService apiServer;
+
+    @Mock
+    SAML2AuthManager samlAuthManager;
+
+    @Mock
+    DomainManager domainMgr;
+
+    @Mock
+    AccountService accountService;
+
+    @Mock
+    UserAccountDao userAccountDao;
+
+    @Mock
+    Domain domain;
+
+    @Mock
+    HttpSession session;
+
+    @Mock
+    HttpServletResponse resp;
+
+    @Mock
+    HttpServletRequest req;
+
+    @Spy
+    @InjectMocks
+    private SAML2LoginAPIAuthenticatorCmd cmdSpy;
+
+    private Response buildMockResponse() throws Exception {
+        Response samlMessage = new ResponseBuilder().buildObject();
+        samlMessage.setID("foo");
+        samlMessage.setVersion(SAMLVersion.VERSION_20);
+        samlMessage.setIssueInstant(new DateTime(0));
+        Issuer issuer = new IssuerBuilder().buildObject();
+        issuer.setValue("MockedIssuer");
+        samlMessage.setIssuer(issuer);
+        Status status = new StatusBuilder().buildObject();
+        StatusCode statusCode = new StatusCodeBuilder().buildObject();
+        statusCode.setValue(StatusCode.SUCCESS_URI);
+        status.setStatusCode(statusCode);
+        samlMessage.setStatus(status);
+        Assertion assertion = new AssertionBuilder().buildObject();
+        Subject subject = new SubjectBuilder().buildObject();
+        NameID nameID = new NameIDBuilder().buildObject();
+        nameID.setValue("SOME-UNIQUE-ID");
+        nameID.setFormat(NameIDType.PERSISTENT);
+        subject.setNameID(nameID);
+        assertion.setSubject(subject);
+        AuthnStatement authnStatement = new AuthnStatementBuilder().buildObject();
+        authnStatement.setSessionIndex("Some Session String");
+        assertion.getAuthnStatements().add(authnStatement);
+        AttributeStatement attributeStatement = new AttributeStatementBuilder().buildObject();
+        assertion.getAttributeStatements().add(attributeStatement);
+        samlMessage.getAssertions().add(assertion);
+        return samlMessage;
+    }
+
+    @Test
+    public void testAuthenticate() throws Exception {
+        SAML2LoginAPIAuthenticatorCmd cmd = Mockito.spy(new SAML2LoginAPIAuthenticatorCmd());
+
+        Field apiServerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("apiServer");
+        apiServerField.setAccessible(true);
+        apiServerField.set(cmd, apiServer);
+
+        Field managerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("samlAuthManager");
+        managerField.setAccessible(true);
+        managerField.set(cmd, samlAuthManager);
+
+        Field accountServiceField = BaseCmd.class.getDeclaredField("_accountService");
+        accountServiceField.setAccessible(true);
+        accountServiceField.set(cmd, accountService);
+
+        Field domainMgrField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("domainMgr");
+        domainMgrField.setAccessible(true);
+        domainMgrField.set(cmd, domainMgr);
+
+        Field userAccountDaoField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("userAccountDao");
+        userAccountDaoField.setAccessible(true);
+        userAccountDaoField.set(cmd, userAccountDao);
+
+        KeyPair kp = CertUtils.generateRandomKeyPair(4096);
+        X509Certificate cert = SAMLUtils.generateRandomX509Certificate(kp);
+
+        SAMLProviderMetadata providerMetadata = new SAMLProviderMetadata();
+        providerMetadata.setEntityId("random");
+        providerMetadata.setSigningCertificate(cert);
+        providerMetadata.setEncryptionCertificate(cert);
+        providerMetadata.setKeyPair(kp);
+        providerMetadata.setSsoUrl("http://test.local");
+        providerMetadata.setSloUrl("http://test.local");
+
+        Mockito.when(session.getAttribute(Mockito.anyString())).thenReturn(null);
+
+        Mockito.when(domain.getId()).thenReturn(1L);
+        Mockito.when(domainMgr.getDomain(Mockito.anyString())).thenReturn(domain);
+        UserAccountVO user = new UserAccountVO();
+        user.setId(1000L);
+        Mockito.when(userAccountDao.getUserAccount(Mockito.anyString(), Mockito.anyLong())).thenReturn(user);
+        Mockito.when(apiServer.verifyUser(Mockito.anyLong())).thenReturn(false);
+        Mockito.when(samlAuthManager.getSPMetadata()).thenReturn(providerMetadata);
+        Mockito.when(samlAuthManager.getIdPMetadata(Mockito.anyString())).thenReturn(providerMetadata);
+
+        Map<String, Object[]> params = new HashMap<String, Object[]>();
+
+        // SSO redirection test
+        cmd.authenticate("command", params, session, InetAddress.getByName("127.0.0.1"), HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        Mockito.verify(resp, Mockito.times(1)).sendRedirect(Mockito.anyString());
+
+        // SSO SAMLResponse verification test, this should throw ServerApiException for auth failure
+        params.put(SAMLPluginConstants.SAML_RESPONSE, new String[]{"Some String"});
+        Mockito.stub(cmd.processSAMLResponse(Mockito.anyString())).toReturn(buildMockResponse());
+        boolean failing = true;
+        try {
+            cmd.authenticate("command", params, session, InetAddress.getByName("127.0.0.1"), HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
+        } catch (ServerApiException ignored) {
+            failing = false;
+        }
+        assertFalse("authentication should not have succeeded", failing);
+        Mockito.verify(userAccountDao, Mockito.times(0)).getUserAccount(Mockito.anyString(), Mockito.anyLong());
+        Mockito.verify(apiServer, Mockito.times(0)).verifyUser(Mockito.anyLong());
+    }
+
+    @Test
+    public void testGetAPIType() {
+        Assert.assertTrue(new SAML2LoginAPIAuthenticatorCmd().getAPIType() == APIAuthenticationType.LOGIN_API);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlBlank() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", " ", false);
+        boolean expectServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(true, expectServerApiException, 0, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlNull() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", null, false);
+        boolean expectServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(true, expectServerApiException, 0, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlEmpty() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", "", false);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(true, hasThrownServerApiException, 0, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectExternalEntityNullAndUrlNotConfigured() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(null, " ", false);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(true, hasThrownServerApiException, 0, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectExternalEntityNullAndUrlConfigured() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(null, "some.url", true);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(false, hasThrownServerApiException, 1, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlConfigured() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", "some.url", false);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(false, hasThrownServerApiException, 1, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlUserAccountNull() throws IOException {
+        configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", "some.url", true);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(null);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(false, hasThrownServerApiException, 1, 1);
+    }
+
+    @Test
+    public void whenFailToAuthenticateThrowExceptionOrRedirectToUrlTestSaml2FailedLoginRedirectUrlIsUserAuthorized() throws IOException {
+        UserAccountVO userAccount = configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl("entity", "some.url", true);
+        boolean hasThrownServerApiException = runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(userAccount);
+        verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(false, hasThrownServerApiException, 0, 0);
+    }
+
+    private UserAccountVO configureTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(String entity, String configurationValue, Boolean isUserAuthorized)
+            throws IOException {
+        Mockito.when(samlAuthManager.isUserAuthorized(Mockito.anyLong(), Mockito.anyString())).thenReturn(isUserAuthorized);
+        SAML2LoginAPIAuthenticatorCmd.saml2FailedLoginRedirectUrl = new ConfigKey<String>("Advanced", String.class, "saml2.failed.login.redirect.url", configurationValue,
+                "The URL to redirect the SAML2 login failed message (the default vaulue is empty).", true);
+        UserAccountVO userAccount = new UserAccountVO();
+        userAccount.setExternalEntity(entity);
+        userAccount.setId(0l);
+        return userAccount;
+    }
+
+    private void verifyTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(boolean expectServerApiException, boolean hasThrownServerApiException, int timesOfSendRedirect,
+            int timesOfConfigDao) throws IOException {
+        Mockito.verify(resp, Mockito.times(timesOfSendRedirect)).sendRedirect(Mockito.anyString());
+        Assert.assertEquals(expectServerApiException, hasThrownServerApiException);
+    }
+
+    private boolean runTestWhenFailToAuthenticateThrowExceptionOrRedirectToUrl(UserAccountVO userAccount) throws IOException {
+        try {
+            cmdSpy.whenFailToAuthenticateThrowExceptionOrRedirectToUrl(null, "responseType", resp, new IssuerBuilder().buildObject(), userAccount);
+        } catch (ServerApiException e) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmdTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/saml/SAML2AuthManagerImplTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/saml/SAML2AuthManagerImplTest.java
similarity index 100%
rename from plugins/user-authenticators/saml2/test/org/apache/cloudstack/saml/SAML2AuthManagerImplTest.java
rename to plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/saml/SAML2AuthManagerImplTest.java
diff --git a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java b/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java
deleted file mode 100644
index 2ce8841..0000000
--- a/plugins/user-authenticators/saml2/test/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmdTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.cloudstack.api.command;
-
-import static org.junit.Assert.assertFalse;
-
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.security.KeyPair;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.apache.cloudstack.api.ApiServerService;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.auth.APIAuthenticationType;
-import org.apache.cloudstack.saml.SAML2AuthManager;
-import org.apache.cloudstack.saml.SAMLPluginConstants;
-import org.apache.cloudstack.saml.SAMLProviderMetadata;
-import org.apache.cloudstack.saml.SAMLUtils;
-import org.apache.cloudstack.utils.security.CertUtils;
-import org.joda.time.DateTime;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.opensaml.common.SAMLVersion;
-import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.AttributeStatement;
-import org.opensaml.saml2.core.AuthnStatement;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.NameID;
-import org.opensaml.saml2.core.NameIDType;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.core.Status;
-import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.saml2.core.Subject;
-import org.opensaml.saml2.core.impl.AssertionBuilder;
-import org.opensaml.saml2.core.impl.AttributeStatementBuilder;
-import org.opensaml.saml2.core.impl.AuthnStatementBuilder;
-import org.opensaml.saml2.core.impl.IssuerBuilder;
-import org.opensaml.saml2.core.impl.NameIDBuilder;
-import org.opensaml.saml2.core.impl.ResponseBuilder;
-import org.opensaml.saml2.core.impl.StatusBuilder;
-import org.opensaml.saml2.core.impl.StatusCodeBuilder;
-import org.opensaml.saml2.core.impl.SubjectBuilder;
-
-import com.cloud.domain.Domain;
-import com.cloud.user.AccountService;
-import com.cloud.user.DomainManager;
-import com.cloud.user.UserAccountVO;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.utils.HttpUtils;
-
-@RunWith(MockitoJUnitRunner.class)
-public class SAML2LoginAPIAuthenticatorCmdTest {
-
-    @Mock
-    ApiServerService apiServer;
-
-    @Mock
-    SAML2AuthManager samlAuthManager;
-
-    @Mock
-    DomainManager domainMgr;
-
-    @Mock
-    AccountService accountService;
-
-    @Mock
-    UserAccountDao userAccountDao;
-
-    @Mock
-    Domain domain;
-
-    @Mock
-    HttpSession session;
-
-    @Mock
-    HttpServletResponse resp;
-
-    @Mock
-    HttpServletRequest req;
-
-    private Response buildMockResponse() throws Exception {
-        Response samlMessage = new ResponseBuilder().buildObject();
-        samlMessage.setID("foo");
-        samlMessage.setVersion(SAMLVersion.VERSION_20);
-        samlMessage.setIssueInstant(new DateTime(0));
-        Issuer issuer = new IssuerBuilder().buildObject();
-        issuer.setValue("MockedIssuer");
-        samlMessage.setIssuer(issuer);
-        Status status = new StatusBuilder().buildObject();
-        StatusCode statusCode = new StatusCodeBuilder().buildObject();
-        statusCode.setValue(StatusCode.SUCCESS_URI);
-        status.setStatusCode(statusCode);
-        samlMessage.setStatus(status);
-        Assertion assertion = new AssertionBuilder().buildObject();
-        Subject subject = new SubjectBuilder().buildObject();
-        NameID nameID = new NameIDBuilder().buildObject();
-        nameID.setValue("SOME-UNIQUE-ID");
-        nameID.setFormat(NameIDType.PERSISTENT);
-        subject.setNameID(nameID);
-        assertion.setSubject(subject);
-        AuthnStatement authnStatement = new AuthnStatementBuilder().buildObject();
-        authnStatement.setSessionIndex("Some Session String");
-        assertion.getAuthnStatements().add(authnStatement);
-        AttributeStatement attributeStatement = new AttributeStatementBuilder().buildObject();
-        assertion.getAttributeStatements().add(attributeStatement);
-        samlMessage.getAssertions().add(assertion);
-        return samlMessage;
-    }
-
-    @Test
-    public void testAuthenticate() throws Exception {
-        SAML2LoginAPIAuthenticatorCmd cmd = Mockito.spy(new SAML2LoginAPIAuthenticatorCmd());
-
-        Field apiServerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_apiServer");
-        apiServerField.setAccessible(true);
-        apiServerField.set(cmd, apiServer);
-
-        Field managerField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_samlAuthManager");
-        managerField.setAccessible(true);
-        managerField.set(cmd, samlAuthManager);
-
-        Field accountServiceField = BaseCmd.class.getDeclaredField("_accountService");
-        accountServiceField.setAccessible(true);
-        accountServiceField.set(cmd, accountService);
-
-        Field domainMgrField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_domainMgr");
-        domainMgrField.setAccessible(true);
-        domainMgrField.set(cmd, domainMgr);
-
-        Field userAccountDaoField = SAML2LoginAPIAuthenticatorCmd.class.getDeclaredField("_userAccountDao");
-        userAccountDaoField.setAccessible(true);
-        userAccountDaoField.set(cmd, userAccountDao);
-
-        KeyPair kp = CertUtils.generateRandomKeyPair(4096);
-        X509Certificate cert = SAMLUtils.generateRandomX509Certificate(kp);
-
-        SAMLProviderMetadata providerMetadata = new SAMLProviderMetadata();
-        providerMetadata.setEntityId("random");
-        providerMetadata.setSigningCertificate(cert);
-        providerMetadata.setEncryptionCertificate(cert);
-        providerMetadata.setKeyPair(kp);
-        providerMetadata.setSsoUrl("http://test.local");
-        providerMetadata.setSloUrl("http://test.local");
-
-        Mockito.when(session.getAttribute(Mockito.anyString())).thenReturn(null);
-
-        Mockito.when(domain.getId()).thenReturn(1L);
-        Mockito.when(domainMgr.getDomain(Mockito.anyString())).thenReturn(domain);
-        UserAccountVO user = new UserAccountVO();
-        user.setId(1000L);
-        Mockito.when(userAccountDao.getUserAccount(Mockito.anyString(), Mockito.anyLong())).thenReturn(user);
-        Mockito.when(apiServer.verifyUser(Mockito.anyLong())).thenReturn(false);
-        Mockito.when(samlAuthManager.getSPMetadata()).thenReturn(providerMetadata);
-        Mockito.when(samlAuthManager.getIdPMetadata(Mockito.anyString())).thenReturn(providerMetadata);
-
-        Map<String, Object[]> params = new HashMap<String, Object[]>();
-
-        // SSO redirection test
-        cmd.authenticate("command", params, session, InetAddress.getByName("127.0.0.1"), HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
-        Mockito.verify(resp, Mockito.times(1)).sendRedirect(Mockito.anyString());
-
-        // SSO SAMLResponse verification test, this should throw ServerApiException for auth failure
-        params.put(SAMLPluginConstants.SAML_RESPONSE, new String[]{"Some String"});
-        Mockito.stub(cmd.processSAMLResponse(Mockito.anyString())).toReturn(buildMockResponse());
-        boolean failing = true;
-        try {
-            cmd.authenticate("command", params, session, InetAddress.getByName("127.0.0.1"), HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp);
-        } catch (ServerApiException ignored) {
-            failing = false;
-        }
-        assertFalse("authentication should not have succeeded", failing);
-        Mockito.verify(userAccountDao, Mockito.times(0)).getUserAccount(Mockito.anyString(), Mockito.anyLong());
-        Mockito.verify(apiServer, Mockito.times(0)).verifyUser(Mockito.anyLong());
-    }
-
-    @Test
-    public void testGetAPIType() {
-        Assert.assertTrue(new SAML2LoginAPIAuthenticatorCmd().getAPIType() == APIAuthenticationType.LOGIN_API);
-    }
-}
diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml
index 9d09ca6..e18ff84 100644
--- a/plugins/user-authenticators/sha256salted/pom.xml
+++ b/plugins/user-authenticators/sha256salted/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-user-authenticator-sha256salted</artifactId>
-  <name>Apache CloudStack Plugin - User Authenticator SHA256 Salted</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-plugins</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
+<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-user-authenticator-sha256salted</artifactId>
+    <name>Apache CloudStack Plugin - User Authenticator SHA256 Salted</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-plugins</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java b/plugins/user-authenticators/sha256salted/src/main/java/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java
similarity index 100%
rename from plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java
rename to plugins/user-authenticators/sha256salted/src/main/java/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java
diff --git a/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/module.properties b/plugins/user-authenticators/sha256salted/src/main/resources/META-INF/cloudstack/sha256salted/module.properties
similarity index 100%
rename from plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/module.properties
rename to plugins/user-authenticators/sha256salted/src/main/resources/META-INF/cloudstack/sha256salted/module.properties
diff --git a/plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml b/plugins/user-authenticators/sha256salted/src/main/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml
similarity index 100%
rename from plugins/user-authenticators/sha256salted/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml
rename to plugins/user-authenticators/sha256salted/src/main/resources/META-INF/cloudstack/sha256salted/spring-sha256salted-context.xml
diff --git a/plugins/user-authenticators/sha256salted/src/test/java/com/cloud/server/auth/test/AuthenticatorTest.java b/plugins/user-authenticators/sha256salted/src/test/java/com/cloud/server/auth/test/AuthenticatorTest.java
new file mode 100644
index 0000000..f770b74
--- /dev/null
+++ b/plugins/user-authenticators/sha256salted/src/test/java/com/cloud/server/auth/test/AuthenticatorTest.java
@@ -0,0 +1,123 @@
+// 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.server.auth.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.when;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.server.auth.SHA256SaltedUserAuthenticator;
+import com.cloud.user.UserAccount;
+import com.cloud.user.dao.UserAccountDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuthenticatorTest {
+
+    @Mock
+    UserAccount adminAccount;
+
+    @Mock
+    UserAccount adminAccount20Byte;
+
+    @Mock
+    UserAccountDao _userAccountDao;
+
+    @InjectMocks
+    SHA256SaltedUserAuthenticator authenticator;
+
+    @Before
+    public void setUp() throws Exception {
+        try {
+            authenticator.configure("SHA256", Collections.<String, Object> emptyMap());
+        } catch (ConfigurationException e) {
+            fail(e.toString());
+        }
+
+        when(_userAccountDao.getUserAccount("admin", 0L)).thenReturn(adminAccount);
+        when(_userAccountDao.getUserAccount("admin20Byte", 0L)).thenReturn(adminAccount20Byte);
+        when(_userAccountDao.getUserAccount("fake", 0L)).thenReturn(null);
+        //32 byte salt, and password="password"
+        when(adminAccount.getPassword()).thenReturn("WS3UHhBPKHZeV+G3jnn7G2N3luXgLSfL+2ORDieXa1U=:VhuFOrOU2IpsjKYH8cH1VDaDBh/VivjMcuADjeEbIig=");
+        //20 byte salt, and password="password"
+        when(adminAccount20Byte.getPassword()).thenReturn("QL2NsxVEmRuDaNRkvIyADny7C5w=:JoegiytiWnoBAxmSD/PwBZZYqkr746x2KzPrZNw4NgI=");
+
+    }
+
+    @Test
+    public void testEncode() throws UnsupportedEncodingException, NoSuchAlgorithmException {
+
+        String encodedPassword = authenticator.encode("password");
+
+        String storedPassword[] = encodedPassword.split(":");
+        assertEquals("hash must consist of two components", storedPassword.length, 2);
+
+        byte salt[] = Base64.decode(storedPassword[0]);
+        String hashedPassword = authenticator.encode("password", salt);
+
+        assertEquals("compare hashes", storedPassword[1], hashedPassword);
+
+    }
+
+    @Test
+    public void testAuthentication() throws UnsupportedEncodingException, NoSuchAlgorithmException {
+        Map<String, Object[]> dummyMap = new HashMap<String, Object[]>();
+        assertEquals("32 byte salt authenticated", true, authenticator.authenticate("admin", "password", 0L, dummyMap).first());
+        assertEquals("20 byte salt authenticated", true, authenticator.authenticate("admin20Byte", "password", 0L, dummyMap).first());
+        assertEquals("fake user not authenticated", false, authenticator.authenticate("fake", "fake", 0L, dummyMap).first());
+        assertEquals("bad password not authenticated", false, authenticator.authenticate("admin", "fake", 0L, dummyMap).first());
+        assertEquals("20 byte user bad password not authenticated", false, authenticator.authenticate("admin20Byte", "fake", 0L, dummyMap).first());
+    }
+
+//    @Test
+//    public void testTiming() throws UnsupportedEncodingException, NoSuchAlgorithmException {
+//        Map<String, Object[]> dummyMap = new HashMap<String, Object[]>();
+//        Double threshold = (double)500000; //half a millisecond
+//
+//        Long t1 = System.nanoTime();
+//        authenticator.authenticate("admin", "password", 0L, dummyMap);
+//        Long t2 = System.nanoTime();
+//        authenticator.authenticate("admin20Byte", "password", 0L, dummyMap);
+//        Long t3 = System.nanoTime();
+//        authenticator.authenticate("fake", "fake", 0L, dummyMap);
+//        Long t4 = System.nanoTime();
+//        authenticator.authenticate("admin", "fake", 0L, dummyMap);
+//        Long t5 = System.nanoTime();
+//        Long diff1 = t2 - t1;
+//        Long diff2 = t3 - t2;
+//        Long diff3 = t4 - t3;
+//        Long diff4 = t5 - t4;
+//        Assert.assertTrue("All computation times within " + threshold / 1000000 + " milisecond",
+//                (diff1 <= threshold) && (diff2 <= threshold) && (diff3 <= threshold) && (diff4 <= threshold));
+//    }
+}
diff --git a/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java b/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java
deleted file mode 100644
index 0a9bd2f..0000000
--- a/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package src.com.cloud.server.auth.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.when;
-
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import com.cloud.server.auth.SHA256SaltedUserAuthenticator;
-import com.cloud.user.UserAccount;
-import com.cloud.user.dao.UserAccountDao;
-
-@RunWith(MockitoJUnitRunner.class)
-public class AuthenticatorTest {
-
-    @Mock
-    UserAccount adminAccount;
-
-    @Mock
-    UserAccount adminAccount20Byte;
-
-    @Mock
-    UserAccountDao _userAccountDao;
-
-    @InjectMocks
-    SHA256SaltedUserAuthenticator authenticator;
-
-    @Before
-    public void setUp() throws Exception {
-        try {
-            authenticator.configure("SHA256", Collections.<String, Object> emptyMap());
-        } catch (ConfigurationException e) {
-            fail(e.toString());
-        }
-
-        when(_userAccountDao.getUserAccount("admin", 0L)).thenReturn(adminAccount);
-        when(_userAccountDao.getUserAccount("admin20Byte", 0L)).thenReturn(adminAccount20Byte);
-        when(_userAccountDao.getUserAccount("fake", 0L)).thenReturn(null);
-        //32 byte salt, and password="password"
-        when(adminAccount.getPassword()).thenReturn("WS3UHhBPKHZeV+G3jnn7G2N3luXgLSfL+2ORDieXa1U=:VhuFOrOU2IpsjKYH8cH1VDaDBh/VivjMcuADjeEbIig=");
-        //20 byte salt, and password="password"
-        when(adminAccount20Byte.getPassword()).thenReturn("QL2NsxVEmRuDaNRkvIyADny7C5w=:JoegiytiWnoBAxmSD/PwBZZYqkr746x2KzPrZNw4NgI=");
-
-    }
-
-    @Test
-    public void testEncode() throws UnsupportedEncodingException, NoSuchAlgorithmException {
-
-        String encodedPassword = authenticator.encode("password");
-
-        String storedPassword[] = encodedPassword.split(":");
-        assertEquals("hash must consist of two components", storedPassword.length, 2);
-
-        byte salt[] = Base64.decode(storedPassword[0]);
-        String hashedPassword = authenticator.encode("password", salt);
-
-        assertEquals("compare hashes", storedPassword[1], hashedPassword);
-
-    }
-
-    @Test
-    public void testAuthentication() throws UnsupportedEncodingException, NoSuchAlgorithmException {
-        Map<String, Object[]> dummyMap = new HashMap<String, Object[]>();
-        assertEquals("32 byte salt authenticated", true, authenticator.authenticate("admin", "password", 0L, dummyMap).first());
-        assertEquals("20 byte salt authenticated", true, authenticator.authenticate("admin20Byte", "password", 0L, dummyMap).first());
-        assertEquals("fake user not authenticated", false, authenticator.authenticate("fake", "fake", 0L, dummyMap).first());
-        assertEquals("bad password not authenticated", false, authenticator.authenticate("admin", "fake", 0L, dummyMap).first());
-        assertEquals("20 byte user bad password not authenticated", false, authenticator.authenticate("admin20Byte", "fake", 0L, dummyMap).first());
-    }
-
-//    @Test
-//    public void testTiming() throws UnsupportedEncodingException, NoSuchAlgorithmException {
-//        Map<String, Object[]> dummyMap = new HashMap<String, Object[]>();
-//        Double threshold = (double)500000; //half a millisecond
-//
-//        Long t1 = System.nanoTime();
-//        authenticator.authenticate("admin", "password", 0L, dummyMap);
-//        Long t2 = System.nanoTime();
-//        authenticator.authenticate("admin20Byte", "password", 0L, dummyMap);
-//        Long t3 = System.nanoTime();
-//        authenticator.authenticate("fake", "fake", 0L, dummyMap);
-//        Long t4 = System.nanoTime();
-//        authenticator.authenticate("admin", "fake", 0L, dummyMap);
-//        Long t5 = System.nanoTime();
-//        Long diff1 = t2 - t1;
-//        Long diff2 = t3 - t2;
-//        Long diff3 = t4 - t3;
-//        Long diff4 = t5 - t4;
-//        Assert.assertTrue("All computation times within " + threshold / 1000000 + " milisecond",
-//                (diff1 <= threshold) && (diff2 <= threshold) && (diff3 <= threshold) && (diff4 <= threshold));
-//    }
-}
diff --git a/pom.xml b/pom.xml
index 777aa1e..373c567 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,1202 +1,1258 @@
 <!--
-  ~ 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.
-  -->
+  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/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
- 
-  <parent>
-    <groupId>org.apache</groupId>
-    <artifactId>apache</artifactId>
-    <version>11</version>
-  </parent>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
 
-  <groupId>org.apache.cloudstack</groupId>
-  <artifactId>cloudstack</artifactId>
-  <version>4.11.4.0-SNAPSHOT</version>
-  <packaging>pom</packaging>
-  <name>Apache CloudStack</name>
-  <description>Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform.</description>
-  <url>http://www.cloudstack.org</url>
-  <scm>
-    <connection>scm:git:https://gitbox.apache.org/repos/asf/cloudstack.git</connection>
-    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/cloudstack.git</developerConnection>
-  </scm>
-  <issueManagement>
-    <system>jira</system>
-    <url>https://issues.apache.org/jira/browse/CLOUDSTACK</url>
-  </issueManagement>
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>11</version>
+        <relativePath />
+    </parent>
 
-  <properties>
-    <cs.jdk.version>1.8</cs.jdk.version>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack</artifactId>
+    <version>4.12.0.0</version>
+    <packaging>pom</packaging>
+    <name>Apache CloudStack</name>
+    <description>Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform.</description>
+    <url>http://www.cloudstack.org</url>
 
-    <cs.log4j.version>1.2.17</cs.log4j.version>
-    <cs.log4j.extras.version>1.2.17</cs.log4j.extras.version>
-    <cs.cglib.version>3.2.5</cs.cglib.version>
-    <cs.dbcp.version>2.2.0</cs.dbcp.version>
-    <cs.pool.version>2.4.3</cs.pool.version>
-    <cs.codec.version>1.11</cs.codec.version>
-    <cs.configuration.version>1.10</cs.configuration.version>
-    <cs.logging.version>1.1.1</cs.logging.version>
-    <cs.discovery.version>0.5</cs.discovery.version>
-    
-    <!-- do not forget to also upgrade hamcrest library with junit -->
-    <cs.junit.version>4.12</cs.junit.version>
-    <cs.hamcrest.version>1.3</cs.hamcrest.version>
-    <cs.junit.dataprovider.version>1.13.1</cs.junit.dataprovider.version>
-    <cs.bcprov.version>1.59</cs.bcprov.version>
-    <cs.jsch.version>0.1.54</cs.jsch.version>
-    <cs.jpa.version>2.2.0</cs.jpa.version>
-    <cs.jasypt.version>1.9.2</cs.jasypt.version>
-    <cs.trilead.version>1.0.0-build221</cs.trilead.version>
-    <cs.ehcache.version>2.6.11</cs.ehcache.version>
-    <cs.gson.version>1.7.2</cs.gson.version>
-    <cs.guava-testlib.version>18.0</cs.guava-testlib.version>
-    <cs.guava.version>23.6-jre</cs.guava.version>
-    <cs.xapi.version>6.2.0-3.1</cs.xapi.version>
-    <cs.httpclient.version>4.5.4</cs.httpclient.version>
-    <cs.httpcore.version>4.4.8</cs.httpcore.version>
-    <cs.commons-httpclient.version>3.1</cs.commons-httpclient.version>
-    <cs.mysql.version>5.1.34</cs.mysql.version>
-    <cs.xstream.version>1.4.10</cs.xstream.version>
-    <cs.xmlrpc.version>3.1.3</cs.xmlrpc.version>
-    <cs.mail.version>1.5.0-b01</cs.mail.version>
-    <cs.axis.version>1.4</cs.axis.version>
-    <cs.axis2.version>1.5.6</cs.axis2.version>
-    <cs.rampart.version>1.5.1</cs.rampart.version>
-    <cs.axiom.version>1.2.8</cs.axiom.version>
-    <cs.neethi.version>2.0.4</cs.neethi.version>
-    <cs.servlet.version>4.0.0</cs.servlet.version>
-    <cs.jstl.version>1.2</cs.jstl.version>
-    <cs.jstl-api.version>1.2.1</cs.jstl-api.version>
-    <cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version>
-    <cs.vmware.api.version>6.7</cs.vmware.api.version>
-    <org.springframework.version>5.0.2.RELEASE</org.springframework.version>
-    <cs.mockito.version>1.10.19</cs.mockito.version>
-    <cs.powermock.version>1.6.4</cs.powermock.version>
-    <cs.aws.sdk.version>1.11.213</cs.aws.sdk.version>
-    <cs.jackson.version>2.9.2</cs.jackson.version>
-    <cs.lang.version>2.6</cs.lang.version>
-    <cs.commons-lang3.version>3.6</cs.commons-lang3.version>
-    <cs.commons-io.version>2.6</cs.commons-io.version>
-    <cs.commons-fileupload.version>1.3.3</cs.commons-fileupload.version>
-    <cs.commons-collections.version>4.1</cs.commons-collections.version>
-    <cs.commons-validator.version>1.6</cs.commons-validator.version>
-    <cs.reflections.version>0.9.11</cs.reflections.version>
-    <cs.javassist.version>3.22.0-GA</cs.javassist.version>
-    <cs.java-ipv6.version>0.16</cs.java-ipv6.version>
-    <cs.replace.properties>build/replace.properties</cs.replace.properties>
-    <cs.libvirt-java.version>0.5.1</cs.libvirt-java.version>
-    <cs.rados-java.version>0.2.0</cs.rados-java.version>
-    <cs.target.dir>target</cs.target.dir>
-    <cs.daemon.version>1.1.0</cs.daemon.version>
-    <cs.jna.version>4.0.0</cs.jna.version>
-    <cs.checkstyle.version>2.17</cs.checkstyle.version>
-    <cs.mycila.license.version>2.11</cs.mycila.license.version>
-    <cs.findbugs.version>3.0.3</cs.findbugs.version>
-    <cs.javadoc.version>2.10.3</cs.javadoc.version>
-    <cs.opensaml.version>2.6.4</cs.opensaml.version>
-    <cs.xml-apis.version>1.4.01</cs.xml-apis.version>
-    <cs.joda-time.version>2.8.1</cs.joda-time.version>
-    <cs.batik.version>1.9.1</cs.batik.version>
-    <cs.servicemix.version>2.5.8_1</cs.servicemix.version>
-    <cs.cxf.version>3.2.0</cs.cxf.version>
-    <cs.groovy.version>2.4.12</cs.groovy.version>
-    <cs.nitro.version>10.1</cs.nitro.version>
-    <cs.wiremock.version>2.11.0</cs.wiremock.version>
-    <cs.jetty.version>9.4.8.v20171121</cs.jetty.version>
-    <cs.jetty-maven-plugin.version>9.2.22.v20170606</cs.jetty-maven-plugin.version>
-  </properties>
+    <scm>
+        <connection>scm:git:https://gitbox.apache.org/repos/asf/cloudstack.git</connection>
+        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/cloudstack.git</developerConnection>
+    </scm>
 
-  <distributionManagement>
-    <site>
-      <id>apache.cloudstack.site</id>
-      <url>${site.deploy.url}</url>
-    </site>
-  </distributionManagement>
+    <issueManagement>
+        <system>Github</system>
+        <url>https://github.com/apache/cloudstack/issues</url>
+    </issueManagement>
 
-  <inceptionYear>2012</inceptionYear>
+    <properties>
+        <!-- keep in alphabetic order -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-  <mailingLists>
-    <mailingList>
-      <name>Apache CloudStack User List</name>
-      <subscribe>users-subscribe@cloudstack.apache.org</subscribe>
-      <unsubscribe>users-unsubscribe@cloudstack.apache.org</unsubscribe>
-      <post>users@cloudstack.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-users</archive>
-      <otherArchives>
-        <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-users</otherArchive>
-      </otherArchives>
-    </mailingList>
-    <mailingList>
-      <name>Apache CloudStack Developer List</name>
-      <subscribe>dev-subscribe@cloudstack.apache.org</subscribe>
-      <unsubscribe>dev-unsubscribe@cloudstack.apache.org</unsubscribe>
-      <post>dev@cloudstack.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-dev</archive>
-      <otherArchives>
-        <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-dev</otherArchive>
-      </otherArchives>
-    </mailingList>
-    <mailingList>
-      <name>Apache CloudStack Commits List</name>
-      <subscribe>commits-subscribe@cloudstack.apache.org</subscribe>
-      <unsubscribe>commits-unsubscribe@cloudstack.apache.org</unsubscribe>
-      <post>commits@cloudstack.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-commits</archive>
-      <otherArchives>
-        <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-commits</otherArchive>
-      </otherArchives>
-    </mailingList>
-  </mailingLists>
+        <!-- Build properties -->
+        <cs.jdk.version>1.8</cs.jdk.version>
+        <cs.target.dir>target</cs.target.dir>
+        <cs.replace.properties>build/replace.properties</cs.replace.properties>
 
-  <developers>
-    <developer>
-      <name>The Apache CloudStack Team</name>
-      <email>dev@cloudstack.apache.org</email>
-      <url>http://cloudstack.apache.org/</url>
-      <organization>Apache Software Foundation</organization>
-      <organizationUrl>http://apache.org/</organizationUrl>
-    </developer>
-  </developers>
+        <!-- Plugins versions -->
+        <cs.antrun-plugin.version>1.8</cs.antrun-plugin.version>
+        <cs.builder-helper-plugin.version>3.0.0</cs.builder-helper-plugin.version>
+        <cs.checkstyle-plugin.version>3.0.0</cs.checkstyle-plugin.version>
+        <cs.cobertura-plugin.version>2.7</cs.cobertura-plugin.version>
+        <cs.compiler-plugin.version>3.7.0</cs.compiler-plugin.version>
+        <cs.dependency-plugin.version>3.1.0</cs.dependency-plugin.version>
+        <cs.failsafe-plugin.version>2.21.0</cs.failsafe-plugin.version>
+        <cs.findbugs-plugin.version>3.0.5</cs.findbugs-plugin.version>
+        <cs.jar-plugin.version>3.1.0</cs.jar-plugin.version>
+        <cs.pmd-plugin.version>3.9.0</cs.pmd-plugin.version>
+        <cs.project-info-plugin.version>2.9</cs.project-info-plugin.version>
+        <cs.release-plugin.version>2.5.3</cs.release-plugin.version>
+        <cs.resources-plugin.version>3.1.0</cs.resources-plugin.version>
+        <cs.site-plugin.version>3.7.1</cs.site-plugin.version>
+        <cs.surefire-plugin.version>2.21.0</cs.surefire-plugin.version>
 
-  <ciManagement>
-    <system>Jenkins</system>
-    <url>http://builds.apache.org/</url>
-  </ciManagement>
+        <!-- Logging versions -->
+        <cs.log4j.version>1.2.17</cs.log4j.version>
+        <cs.log4j.extras.version>1.2.17</cs.log4j.extras.version>
+        <cs.logging.version>1.1.1</cs.logging.version>
 
-  <licenses>
-    <license>
-      <name>The Apache Software License, Version 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-      <distribution>repo</distribution>
-    </license>
-  </licenses>
+        <!-- Apache Commons versions -->
+        <cs.codec.version>1.11</cs.codec.version>
+        <cs.commons-collections.version>4.1</cs.commons-collections.version>
+        <cs.commons-compress.version>1.15</cs.commons-compress.version>
+        <cs.commons-exec.version>1.3</cs.commons-exec.version>
+        <cs.commons-fileupload.version>1.3.3</cs.commons-fileupload.version>
+        <cs.commons-httpclient.version>3.1</cs.commons-httpclient.version>
+        <cs.commons-io.version>2.6</cs.commons-io.version>
+        <cs.commons-lang3.version>3.6</cs.commons-lang3.version>
+        <cs.commons-net.version>3.6</cs.commons-net.version>
+        <cs.commons-validator.version>1.6</cs.commons-validator.version>
+        <cs.configuration.version>1.10</cs.configuration.version>
+        <cs.daemon.version>1.1.0</cs.daemon.version>
+        <cs.dbcp.version>2.2.0</cs.dbcp.version>
+        <cs.discovery.version>0.5</cs.discovery.version>
+        <cs.lang.version>2.6</cs.lang.version>
+        <cs.pool.version>2.4.3</cs.pool.version>
 
-  <organization>
-    <name>The Apache Software Foundation</name>
-    <url>http://www.apache.org/</url>
-  </organization>
+        <!-- Testing versions -->
+        <!-- do not forget to also upgrade hamcrest library with junit -->
+        <cs.dbunit.version>2.5.4</cs.dbunit.version>
+        <cs.hamcrest.version>1.3</cs.hamcrest.version>
+        <cs.junit.version>4.12</cs.junit.version>
+        <cs.junit.dataprovider.version>1.13.1</cs.junit.dataprovider.version>
+        <cs.guava-testlib.version>18.0</cs.guava-testlib.version>
+        <cs.mockito.version>1.10.19</cs.mockito.version>
+        <cs.powermock.version>1.6.4</cs.powermock.version>
+        <cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version>
+        <cs.selenium-java-client-driver.version>1.0.1</cs.selenium-java-client-driver.version>
+        <cs.testng.version>6.1.1</cs.testng.version>
+        <cs.wiremock.version>2.11.0</cs.wiremock.version>
+        <cs.xercesImpl.version>2.11.0</cs.xercesImpl.version>
 
-  <modules>
-    <module>tools/checkstyle</module>
-    <module>api</module>
-    <module>agent</module>
-    <module>core</module>
-    <module>server</module>
-    <module>usage</module>
-    <module>utils</module>
-    <module>engine</module>
-    <module>plugins</module>
-    <module>framework</module>
-    <module>client</module>
-    <module>services</module>
-    <module>maven-standard</module>
-    <module>quickcloud</module>
-  </modules>
+        <!-- Dependencies versions -->
+        <cs.amqp-client.version>5.1.1</cs.amqp-client.version>
+        <cs.apache-cloudstack-java-client.version>1.0.9</cs.apache-cloudstack-java-client.version>
+        <cs.aspectjrt.version>1.7.1</cs.aspectjrt.version>
+        <cs.aws.sdk.version>1.11.213</cs.aws.sdk.version>
+        <cs.axiom.version>1.2.8</cs.axiom.version>
+        <cs.axis.version>1.4</cs.axis.version>
+        <cs.axis2.version>1.5.6</cs.axis2.version>
+        <cs.batik.version>1.9.1</cs.batik.version>
+        <cs.bcprov.version>1.59</cs.bcprov.version>
+        <cs.cglib.version>3.2.5</cs.cglib.version>
+        <cs.checkstyle-lib.version>8.7</cs.checkstyle-lib.version>
+        <cs.cxf.version>3.2.0</cs.cxf.version>
+        <cs.ehcache.version>2.6.11</cs.ehcache.version>
+        <cs.globodns-client.version>0.0.23</cs.globodns-client.version>
+        <cs.groovy.version>2.4.12</cs.groovy.version>
+        <cs.gson.version>1.7.2</cs.gson.version>
+        <cs.guava.version>23.6-jre</cs.guava.version>
+        <cs.httpclient.version>4.5.4</cs.httpclient.version>
+        <cs.httpcore.version>4.4.8</cs.httpcore.version>
+        <cs.jackson.version>2.9.2</cs.jackson.version>
+        <cs.jasypt.version>1.9.2</cs.jasypt.version>
+        <cs.java-ipv6.version>0.16</cs.java-ipv6.version>
+        <cs.javassist.version>3.22.0-GA</cs.javassist.version>
+        <cs.javadoc.version>2.10.3</cs.javadoc.version>
+        <cs.jersey-bundle.version>1.19.4</cs.jersey-bundle.version>
+        <cs.jetty.version>9.4.8.v20171121</cs.jetty.version>
+        <cs.jetty-maven-plugin.version>9.2.22.v20170606</cs.jetty-maven-plugin.version>
+        <cs.jna.version>4.0.0</cs.jna.version>
+        <cs.joda-time.version>2.8.1</cs.joda-time.version>
+        <cs.jpa.version>2.2.0</cs.jpa.version>
+        <cs.jsch.version>0.1.54</cs.jsch.version>
+        <cs.json.version>20090211</cs.json.version>
+        <cs.jstl.version>1.2</cs.jstl.version>
+        <cs.jstl-api.version>1.2.1</cs.jstl-api.version>
+        <cs.kafka-clients.version>0.11.0.1</cs.kafka-clients.version>
+        <cs.libvirt-java.version>0.5.1</cs.libvirt-java.version>
+        <cs.mail.version>1.5.0-b01</cs.mail.version>
+        <cs.mysql.version>5.1.34</cs.mysql.version>
+        <cs.neethi.version>2.0.4</cs.neethi.version>
+        <cs.nitro.version>10.1</cs.nitro.version>
+        <cs.opensaml.version>2.6.4</cs.opensaml.version>
+        <cs.rados-java.version>0.2.0</cs.rados-java.version>
+        <cs.rampart.version>1.5.1</cs.rampart.version>
+        <cs.reflections.version>0.9.11</cs.reflections.version>
+        <cs.servicemix.version>2.5.8_1</cs.servicemix.version>
+        <cs.servlet.version>4.0.0</cs.servlet.version>
+        <cs.tomcat-embed-core.version>8.0.30</cs.tomcat-embed-core.version>
+        <cs.trilead.version>1.0.0-build221</cs.trilead.version>
+        <cs.vmware.api.version>6.5</cs.vmware.api.version>
+        <cs.xapi.version>6.2.0-3.1</cs.xapi.version>
+        <cs.xml-apis.version>1.4.01</cs.xml-apis.version>
+        <cs.xmlrpc.version>3.1.3</cs.xmlrpc.version>
+        <cs.xstream.version>1.4.10</cs.xstream.version>
+        <org.springframework.version>5.0.2.RELEASE</org.springframework.version>
+    </properties>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.codehaus.groovy</groupId>
-        <artifactId>groovy-all</artifactId>
-        <version>${cs.groovy.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.bouncycastle</groupId>
-        <artifactId>bcprov-jdk15on</artifactId>
-        <version>${cs.bcprov.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.bouncycastle</groupId>
-        <artifactId>bcpkix-jdk15on</artifactId>
-        <version>${cs.bcprov.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.xmlgraphics</groupId>
-        <artifactId>batik-css</artifactId>
-        <version>${cs.batik.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.xmlgraphics</groupId>
-        <artifactId>batik-ext</artifactId>
-        <version>${cs.batik.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.xmlgraphics</groupId>
-        <artifactId>batik-util</artifactId>
-        <version>${cs.batik.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-collections4</artifactId>
-        <version>${cs.commons-collections.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>mysql</groupId>
-        <artifactId>mysql-connector-java</artifactId>
-        <version>${cs.mysql.version}</version>
-        <scope>provided,test</scope>
-      </dependency>
-      <dependency>
-        <groupId>log4j</groupId>
-        <artifactId>log4j</artifactId>
-        <version>${cs.log4j.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-context</artifactId>
-        <version>${org.springframework.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>cglib</groupId>
-        <artifactId>cglib-nodep</artifactId>
-        <version>${cs.cglib.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-dbcp2</artifactId>
-        <version>${cs.dbcp.version}</version>
-        <exclusions>
-          <exclusion>
-            <artifactId>org.apache.commons</artifactId>
-            <groupId>commons-pool2</groupId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>net.sf.ehcache</groupId>
-        <artifactId>ehcache-core</artifactId>
-        <version>${cs.ehcache.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-codec</groupId>
-        <artifactId>commons-codec</artifactId>
-        <version>${cs.codec.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-fileupload</groupId>
-        <artifactId>commons-fileupload</artifactId>
-        <version>${cs.commons-fileupload.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-pool2</artifactId>
-        <version>${cs.pool.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-validator</groupId>
-        <artifactId>commons-validator</artifactId>
-        <version>${cs.commons-validator.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.jcraft</groupId>
-        <artifactId>jsch</artifactId>
-        <version>${cs.jsch.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.jasypt</groupId>
-        <artifactId>jasypt</artifactId>
-        <version>${cs.jasypt.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.trilead</groupId>
-        <artifactId>trilead-ssh2</artifactId>
-        <version>${cs.trilead.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.amazonaws</groupId>
-        <artifactId>aws-java-sdk-core</artifactId>
-        <version>${cs.aws.sdk.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.amazonaws</groupId>
-        <artifactId>aws-java-sdk-s3</artifactId>
-        <version>${cs.aws.sdk.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>log4j</groupId>
-        <artifactId>apache-log4j-extras</artifactId>
-        <version>${cs.log4j.extras.version}</version>
-        <exclusions>
-          <exclusion>
-            <artifactId>log4j</artifactId>
-            <groupId>log4j</groupId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>com.googlecode.java-ipv6</groupId>
-        <artifactId>java-ipv6</artifactId>
-        <version>${cs.java-ipv6.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-configuration</groupId>
-        <artifactId>commons-configuration</artifactId>
-        <version>${cs.configuration.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-io</groupId>
-        <artifactId>commons-io</artifactId>
-        <version>${cs.commons-io.version}</version>
-      </dependency>
-      <!-- Test dependency in mysql for db tests -->
-      <dependency>
-        <groupId>org.reflections</groupId>
-        <artifactId>reflections</artifactId>
-        <version>${cs.reflections.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.javassist</groupId>
-        <artifactId>javassist</artifactId>
-        <version>${cs.javassist.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.owasp.esapi</groupId>
-        <artifactId>esapi</artifactId>
-        <version>2.1.0.1</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.persistence</groupId>
-        <artifactId>javax.persistence</artifactId>
-        <version>${cs.jpa.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-web</artifactId>
-        <version>${org.springframework.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>javax.servlet</groupId>
-        <artifactId>javax.servlet-api</artifactId>
-        <version>${cs.servlet.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.httpcomponents</groupId>
-        <artifactId>httpcore</artifactId>
-        <version>${cs.httpcore.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.httpcomponents</groupId>
-        <artifactId>httpclient</artifactId>
-        <version>${cs.httpclient.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.thoughtworks.xstream</groupId>
-        <artifactId>xstream</artifactId>
-        <version>${cs.xstream.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>javax.mail</groupId>
-        <artifactId>mail</artifactId>
-        <version>${cs.mail.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>jstl</groupId>
-        <artifactId>jstl</artifactId>
-        <version>${cs.jstl.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-aop</artifactId>
-        <version>${org.springframework.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-beans</artifactId>
-        <version>${org.springframework.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.google.code.gson</groupId>
-        <artifactId>gson</artifactId>
-        <version>${cs.gson.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>com.google.guava</groupId>
-        <artifactId>guava</artifactId>
-        <version>${cs.guava.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicemix.bundles</groupId>
-        <artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
-        <version>${cs.servicemix.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.aspectj</groupId>
-        <artifactId>aspectjtools</artifactId>
-        <version>1.8.13</version>
-      </dependency>
-      <dependency>
-        <groupId>org.aspectj</groupId>
-        <artifactId>aspectjweaver</artifactId>
-        <version>1.8.13</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.axis</groupId>
-        <artifactId>axis</artifactId>
-        <version>${cs.axis.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-daemon</groupId>
-        <artifactId>commons-daemon</artifactId>
-        <version>${cs.daemon.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.axis</groupId>
-        <artifactId>axis-jaxrpc</artifactId>
-        <version>${cs.axis.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>wsdl4j</groupId>
-        <artifactId>wsdl4j</artifactId>
-        <version>1.6.3</version>
-      </dependency>
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-api</artifactId>
-        <version>1.7.22</version>
-      </dependency>
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-log4j12</artifactId>
-        <version>1.7.22</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-server</artifactId>
-        <version>${cs.jetty.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-servlets</artifactId>
-        <version>${cs.jetty.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-webapp</artifactId>
-        <version>${cs.jetty.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-jmx</artifactId>
-        <version>${cs.jetty.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.eclipse.jetty</groupId>
-        <artifactId>jetty-util</artifactId>
-        <version>${cs.jetty.version}</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
+    <distributionManagement>
+        <site>
+            <id>apache.cloudstack.site</id>
+            <url>${site.deploy.url}</url>
+        </site>
+    </distributionManagement>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-all</artifactId>
-      <version>${cs.hamcrest.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <version>${cs.mockito.version}</version>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <artifactId>hamcrest-core</artifactId>
-          <groupId>org.hamcrest</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${cs.junit.version}</version>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <artifactId>hamcrest-core</artifactId>
-          <groupId>org.hamcrest</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>com.tngtech.java</groupId>
-      <artifactId>junit-dataprovider</artifactId>
-      <version>${cs.junit.dataprovider.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <version>${cs.powermock.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito</artifactId>
-      <version>${cs.powermock.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-      <version>${org.springframework.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-    </dependency>
-  </dependencies>
+    <inceptionYear>2012</inceptionYear>
 
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <sourceDirectory>src</sourceDirectory>
-    <testSourceDirectory>test</testSourceDirectory>
-    <resources>
-      <resource>
-        <directory>${basedir}/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>test/resources</directory>
-      </testResource>
-    </testResources>
-    <outputDirectory>${basedir}/${cs.target.dir}/classes</outputDirectory>
-    <testOutputDirectory>${basedir}/${cs.target.dir}/test-classes</testOutputDirectory>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checkstyle</id>
-            <phase>none</phase>
-            <inherited>false</inherited>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>com.mycila</groupId>
-        <artifactId>license-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-checklicence</id>
-            <phase>none</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>findbugs-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>cloudstack-findbugs</id>
-            <phase>none</phase>
-            <goals>
-              <goal>check</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-checkstyle-plugin</artifactId>
-          <version>${cs.checkstyle.version}</version>
-          <dependencies>
+    <mailingLists>
+        <mailingList>
+            <name>Apache CloudStack User List</name>
+            <subscribe>users-subscribe@cloudstack.apache.org</subscribe>
+            <unsubscribe>users-unsubscribe@cloudstack.apache.org</unsubscribe>
+            <post>users@cloudstack.apache.org</post>
+            <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-users</archive>
+            <otherArchives>
+                <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-users</otherArchive>
+            </otherArchives>
+        </mailingList>
+        <mailingList>
+            <name>Apache CloudStack Developer List</name>
+            <subscribe>dev-subscribe@cloudstack.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@cloudstack.apache.org</unsubscribe>
+            <post>dev@cloudstack.apache.org</post>
+            <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-dev</archive>
+            <otherArchives>
+                <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-dev</otherArchive>
+            </otherArchives>
+        </mailingList>
+        <mailingList>
+            <name>Apache CloudStack Commits List</name>
+            <subscribe>commits-subscribe@cloudstack.apache.org</subscribe>
+            <unsubscribe>commits-unsubscribe@cloudstack.apache.org</unsubscribe>
+            <post>commits@cloudstack.apache.org</post>
+            <archive>http://mail-archives.apache.org/mod_mbox/cloudstack-commits</archive>
+            <otherArchives>
+                <otherArchive>http://mail-archives.apache.org/mod_mbox/incubator-cloudstack-commits</otherArchive>
+            </otherArchives>
+        </mailingList>
+    </mailingLists>
+
+    <developers>
+        <developer>
+            <name>The Apache CloudStack Team</name>
+            <email>dev@cloudstack.apache.org</email>
+            <url>http://cloudstack.apache.org/</url>
+            <organization>Apache Software Foundation</organization>
+            <organizationUrl>http://apache.org/</organizationUrl>
+        </developer>
+    </developers>
+
+    <ciManagement>
+        <system>Jenkins</system>
+        <url>http://builds.apache.org/</url>
+    </ciManagement>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <organization>
+        <name>The Apache Software Foundation</name>
+        <url>http://www.apache.org/</url>
+    </organization>
+
+    <modules>
+        <module>tools/checkstyle</module>
+        <module>api</module>
+        <module>agent</module>
+        <module>core</module>
+        <module>server</module>
+        <module>usage</module>
+        <module>utils</module>
+        <module>engine</module>
+        <module>plugins</module>
+        <module>framework</module>
+        <module>client</module>
+        <module>services</module>
+        <module>quickcloud</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- keep in alphabetic order -->
             <dependency>
-              <groupId>org.apache.cloudstack</groupId>
-              <artifactId>checkstyle</artifactId>
-              <version>${project.version}</version>
+                <groupId>br.com.autonomiccs</groupId>
+                <artifactId>apache-cloudstack-java-client</artifactId>
+                <version>${cs.apache-cloudstack-java-client.version}</version>
             </dependency>
-          </dependencies>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>validate</phase>
-              <goals>
-                <goal>check</goal>
-              </goals>
-            </execution>
-          </executions>
-          <configuration>
-            <failsOnError>true</failsOnError>
-            <configLocation>cloud-style.xml</configLocation>
-            <consoleOutput>true</consoleOutput>
-            <includeTestSourceDirectory>true</includeTestSourceDirectory>
-            <sourceDirectory>${project.basedir}</sourceDirectory>
-            <includes>**\/*.java</includes>
-            <excludes>**\/deps\/,**\/test\/,**\/target\/,**\/bin\/,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/apidoc\/</excludes>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>com.mycila</groupId>
-          <artifactId>license-maven-plugin</artifactId>
-          <version>${cs.mycila.license.version}</version>
-          <executions>
-            <execution>
-              <id>cloudstack-checklicence</id>
-              <phase>process-classes</phase>
-              <goals>
-                <goal>check</goal>
-              </goals>
-            </execution>
-          </executions>
-          <configuration>
-            <strictCheck>true</strictCheck>
-            <aggregate>true</aggregate>
-            <header>LICENSE.header</header>
-            <mapping>
-              <xml>XML_STYLE</xml>
-              <java>DOUBLESLASH_STYLE</java>
-              <clj>SEMICOLON_STYLE</clj>
-            </mapping>
-            <useDefaultExcludes>false</useDefaultExcludes>
-            <excludes>
-              <exclude>**/target/**</exclude>
-              <exclude>.settings/**</exclude>
-              <exclude>.checkstyle</exclude>
-              <exclude>.project</exclude>
-              <exclude>.classpath</exclude>
-              <exclude>.pmd*</exclude>
-            </excludes>
-          </configuration>
-        </plugin>
-        <plugin>
-          <artifactId>maven-clean-plugin</artifactId>
-          <configuration>
-            <excludeDefaultDirectories>true</excludeDefaultDirectories>
-            <filesets>
-              <fileset>
-                <directory>${cs.target.dir}</directory>
-                <includes>
-                  <include>**/*</include>
-                </includes>
-              </fileset>
-              <fileset>
-                <directory>dist</directory>
-                <includes>
-                  <include>**/*</include>
-                </includes>
-              </fileset>
-              <fileset>
-                <directory>${basedir}</directory>
-                <includes>
-                  <include>${cs.target.dir}</include>
-                  <include>dist</include>
-                </includes>
-              </fileset>
-            </filesets>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-release-plugin</artifactId>
-          <version>2.5.1</version>
-          <executions>
-            <execution>
-              <id>default</id>
-              <goals>
-                <goal>perform</goal>
-              </goals>
-              <configuration>
-                <pomFileName>pom.xml</pomFileName>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-        <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build
-          itself. -->
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
+            <dependency>
+                <groupId>cglib</groupId>
+                <artifactId>cglib-nodep</artifactId>
+                <version>${cs.cglib.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.amazonaws</groupId>
+                <artifactId>aws-java-sdk-core</artifactId>
+                <version>${cs.aws.sdk.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.amazonaws</groupId>
+                <artifactId>aws-java-sdk-s3</artifactId>
+                <version>${cs.aws.sdk.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.globo.globodns</groupId>
+                <artifactId>globodns-client</artifactId>
+                <version>${cs.globodns-client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.code.gson</groupId>
+                <artifactId>gson</artifactId>
+                <version>${cs.gson.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>${cs.guava.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.googlecode.java-ipv6</groupId>
+                <artifactId>java-ipv6</artifactId>
+                <version>${cs.java-ipv6.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.jcraft</groupId>
+                <artifactId>jsch</artifactId>
+                <version>${cs.jsch.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.rabbitmq</groupId>
+                <artifactId>amqp-client</artifactId>
+                <version>${cs.amqp-client.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.sun.jersey</groupId>
+                <artifactId>jersey-bundle</artifactId>
+                <version>${cs.jersey-bundle.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.thoughtworks.xstream</groupId>
+                <artifactId>xstream</artifactId>
+                <version>${cs.xstream.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.trilead</groupId>
+                <artifactId>trilead-ssh2</artifactId>
+                <version>${cs.trilead.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${cs.codec.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-configuration</groupId>
+                <artifactId>commons-configuration</artifactId>
+                <version>${cs.configuration.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-daemon</groupId>
+                <artifactId>commons-daemon</artifactId>
+                <version>${cs.daemon.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-dbcp2</artifactId>
+                <version>${cs.dbcp.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>org.apache.commons</artifactId>
+                        <groupId>commons-pool2</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>commons-discovery</groupId>
+                <artifactId>commons-discovery</artifactId>
+                <version>${cs.discovery.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-fileupload</groupId>
+                <artifactId>commons-fileupload</artifactId>
+                <version>${cs.commons-fileupload.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>${cs.commons-io.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-lang</groupId>
+                <artifactId>commons-lang</artifactId>
+                <version>${cs.lang.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-net</groupId>
+                <artifactId>commons-net</artifactId>
+                <version>${cs.commons-net.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-pool2</artifactId>
+                <version>${cs.pool.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-validator</groupId>
+                <artifactId>commons-validator</artifactId>
+                <version>${cs.commons-validator.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.mail</groupId>
+                <artifactId>mail</artifactId>
+                <version>${cs.mail.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>${cs.servlet.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>jstl</groupId>
+                <artifactId>jstl</artifactId>
+                <version>${cs.jstl.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>log4j</groupId>
+                <artifactId>apache-log4j-extras</artifactId>
+                <version>${cs.log4j.extras.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>log4j</artifactId>
+                        <groupId>log4j</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>log4j</groupId>
+                <artifactId>log4j</artifactId>
+                <version>${cs.log4j.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${cs.mysql.version}</version>
+                <scope>provided,test</scope>
+            </dependency>
+            <dependency>
+                <groupId>net.sf.ehcache</groupId>
+                <artifactId>ehcache-core</artifactId>
+                <version>${cs.ehcache.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.axis</groupId>
+                <artifactId>axis</artifactId>
+                <version>${cs.axis.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.axis</groupId>
+                <artifactId>axis-jaxrpc</artifactId>
+                <version>${cs.axis.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-collections4</artifactId>
+                <version>${cs.commons-collections.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-compress</artifactId>
+                <version>${cs.commons-compress.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-exec</artifactId>
+                <version>${cs.commons-exec.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>${cs.commons-lang3.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient</artifactId>
+                <version>${cs.httpclient.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpcore</artifactId>
+                <version>${cs.httpcore.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.kafka</groupId>
+                <artifactId>kafka-clients</artifactId>
+                <version>${cs.kafka-clients.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.servicemix.bundles</groupId>
+                <artifactId>org.apache.servicemix.bundles.snmp4j</artifactId>
+                <version>${cs.servicemix.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tomcat.embed</groupId>
+                <artifactId>tomcat-embed-core</artifactId>
+                <version>${cs.tomcat-embed-core.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.xmlgraphics</groupId>
+                <artifactId>batik-css</artifactId>
+                <version>${cs.batik.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.xmlgraphics</groupId>
+                <artifactId>batik-ext</artifactId>
+                <version>${cs.batik.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.xmlgraphics</groupId>
+                <artifactId>batik-util</artifactId>
+                <version>${cs.batik.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.aspectj</groupId>
+                <artifactId>aspectjrt</artifactId>
+                <version>${cs.aspectjrt.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.aspectj</groupId>
+                <artifactId>aspectjtools</artifactId>
+                <version>1.8.13</version>
+            </dependency>
+            <dependency>
+                <groupId>org.aspectj</groupId>
+                <artifactId>aspectjweaver</artifactId>
+                <version>1.8.13</version>
+            </dependency>
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcpkix-jdk15on</artifactId>
+                <version>${cs.bcprov.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcprov-jdk15on</artifactId>
+                <version>${cs.bcprov.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.codehaus.groovy</groupId>
+                <artifactId>groovy-all</artifactId>
+                <version>${cs.groovy.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-jmx</artifactId>
+                <version>${cs.jetty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-server</artifactId>
+                <version>${cs.jetty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-servlets</artifactId>
+                <version>${cs.jetty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-util</artifactId>
+                <version>${cs.jetty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-webapp</artifactId>
+                <version>${cs.jetty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.persistence</groupId>
+                <artifactId>javax.persistence</artifactId>
+                <version>${cs.jpa.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jasypt</groupId>
+                <artifactId>jasypt</artifactId>
+                <version>${cs.jasypt.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.javassist</groupId>
+                <artifactId>javassist</artifactId>
+                <version>${cs.javassist.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.json</groupId>
+                <artifactId>json</artifactId>
+                <version>${cs.json.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.opensaml</groupId>
+                <artifactId>opensaml</artifactId>
+                <version>${cs.opensaml.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.owasp.esapi</groupId>
+                <artifactId>esapi</artifactId>
+                <version>2.1.0.1</version>
+            </dependency>
+            <!-- Test dependency in mysql for db tests -->
+            <dependency>
+                <groupId>org.reflections</groupId>
+                <artifactId>reflections</artifactId>
+                <version>${cs.reflections.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>1.7.22</version>
+            </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-log4j12</artifactId>
+                <version>1.7.22</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-aop</artifactId>
+                <version>${org.springframework.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-beans</artifactId>
+                <version>${org.springframework.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-context</artifactId>
+                <version>${org.springframework.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-web</artifactId>
+                <version>${org.springframework.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.testng</groupId>
+                <artifactId>testng</artifactId>
+                <version>${cs.testng.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>wsdl4j</groupId>
+                <artifactId>wsdl4j</artifactId>
+                <version>1.6.3</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <!-- hamcrest should always be the first -->
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <version>${cs.hamcrest.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>${cs.mockito.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>hamcrest-core</artifactId>
+                    <groupId>org.hamcrest</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${cs.junit.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>hamcrest-core</artifactId>
+                    <groupId>org.hamcrest</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.tngtech.java</groupId>
+            <artifactId>junit-dataprovider</artifactId>
+            <version>${cs.junit.dataprovider.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>${cs.powermock.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <version>${cs.powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>${org.springframework.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-findbugs</id>
+                        <phase>none</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <version>${cs.checkstyle-plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.cloudstack</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>${project.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>com.puppycrawl.tools</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>${cs.checkstyle-lib.version}</version>
+                        </dependency>
+                    </dependencies>
+                    <executions>
+                        <execution>
+                            <id>cloudstack-checkstyle</id>
+                            <phase>validate</phase>
+                            <goals>
+                                <goal>check</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <failsOnError>true</failsOnError>
+                        <configLocation>cloud-style.xml</configLocation>
+                        <consoleOutput>true</consoleOutput>
+                        <includeTestSourceDirectory>true</includeTestSourceDirectory>
+                        <sourceDirectories>
+                            <sourceDirectory>${project.basedir}</sourceDirectory>
+                        </sourceDirectories>
+                        <includes>**\/*.java</includes>
+                        <excludes>**\/deps\/,**\/test\/,**\/target\/,**\/bin\/,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/XmlToHtmlConverter*,**\/generated-sources\/**\/*</excludes>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <configuration>
+                        <excludeDefaultDirectories>true</excludeDefaultDirectories>
+                        <filesets>
+                            <fileset>
+                                <directory>${cs.target.dir}</directory>
+                                <includes>
+                                    <include>**/*</include>
+                                </includes>
+                            </fileset>
+                            <fileset>
+                                <directory>dist</directory>
+                                <includes>
+                                    <include>**/*</include>
+                                </includes>
+                            </fileset>
+                            <fileset>
+                                <directory>${basedir}</directory>
+                                <includes>
+                                    <include>${cs.target.dir}</include>
+                                    <include>dist</include>
+                                </includes>
+                            </fileset>
+                        </filesets>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-release-plugin</artifactId>
+                    <version>${cs.release-plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>default</id>
+                            <goals>
+                                <goal>perform</goal>
+                            </goals>
+                            <configuration>
+                                <pomFileName>pom.xml</pomFileName>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. -->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-antrun-plugin</artifactId>
+                                        <versionRange>[1.7,)</versionRange>
+                                        <goals>
+                                            <goal>run</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore />
+                                    </action>
+                                </pluginExecution>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-dependency-plugin</artifactId>
+                                        <versionRange>[2.0,)</versionRange>
+                                        <goals>
+                                            <goal>copy-dependencies</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore />
+                                    </action>
+                                </pluginExecution>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.codehaus.gmaven</groupId>
+                                        <artifactId>gmaven-plugin</artifactId>
+                                        <versionRange>[1.3,)</versionRange>
+                                        <goals>
+                                            <goal>compile</goal>
+                                            <goal>testCompile</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-checkstyle-plugin</artifactId>
+                                        <versionRange>[2.11,)</versionRange>
+                                        <goals>
+                                            <goal>check</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+                <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-antrun-plugin</artifactId>
-                    <versionRange>[1.7,)</versionRange>
-                    <goals>
-                      <goal>run</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore/>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-                  <pluginExecutionFilter>
+                    <version>${cs.antrun-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.rat</groupId>
+                    <artifactId>apache-rat-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>check</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <numUnapprovedLicenses>0</numUnapprovedLicenses>
+                        <excludeSubProjects>false</excludeSubProjects>
+                        <excludes>
+                            <!-- keep in alphabetic order -->
+                            <exclude>**/*.log</exclude>
+                            <exclude>**/*.patch</exclude>
+                            <exclude>**/.classpath</exclude>
+                            <exclude>**/.project</exclude>
+                            <exclude>**/.idea/**</exclude>
+                            <exclude>**/*.iml</exclude>
+                            <exclude>**/.settings/**</exclude>
+                            <exclude>**/*.crt</exclude>
+                            <exclude>**/*.csr</exclude>
+                            <exclude>**/*.key</exclude>
+                            <exclude>**/authorized_keys</exclude>
+                            <exclude>**/*.war</exclude>
+                            <exclude>**/*.mar</exclude>
+                            <exclude>**/*.jar</exclude>
+                            <exclude>**/*.iso</exclude>
+                            <exclude>**/*.tgz</exclude>
+                            <exclude>**/*.zip</exclude>
+                            <exclude>**/target/**</exclude>
+                            <exclude>**/.vagrant</exclude>
+                            <exclude>**/*.json</exclude>
+                            <exclude>**/.checkstyle</exclude>
+                            <exclude>**/*.md</exclude>
+                            <exclude>.java-version</exclude>
+                            <exclude>.python-version</exclude>
+                            <exclude>.idea/</exclude>
+                            <exclude>.metadata/**</exclude>
+                            <exclude>.git/**</exclude>
+                            <exclude>.gitignore</exclude>
+                            <exclude>CHANGES.md</exclude>
+                            <exclude>CONTRIBUTING.md</exclude>
+                            <exclude>README.md</exclude>
+                            <exclude>INSTALL.md</exclude>
+                            <exclude>build/build.number</exclude>
+                            <exclude>debian/cloudstack-agent.dirs</exclude>
+                            <exclude>debian/cloudstack-usage.dirs</exclude>
+                            <exclude>debian/compat</exclude>
+                            <exclude>debian/control</exclude>
+                            <exclude>debian/dirs</exclude>
+                            <exclude>debian/rules</exclude>
+                            <exclude>debian/source/format</exclude>
+                            <exclude>dist/console-proxy/js/jquery.js</exclude>
+                            <exclude>plugins/hypervisors/hyperv/conf/agent.properties</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/packages/**</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/**</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/obj/**</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/bin/**</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/packages.config</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/App.config</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.csproj</exclude>
+                            <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.settings</exclude>
+                            <exclude>scripts/installer/windows/acs_license.rtf</exclude>
+                            <exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
+                            <exclude>services/console-proxy/server/conf/agent.properties</exclude>
+                            <exclude>services/console-proxy/server/conf/environment.properties</exclude>
+                            <exclude>services/console-proxy/server/js/jquery.js</exclude>
+                            <exclude>services/secondary-storage/conf/agent.properties</exclude>
+                            <exclude>services/secondary-storage/conf/environment.properties</exclude>
+                            <exclude>systemvm/agent/conf/agent.properties</exclude>
+                            <exclude>systemvm/agent/conf/environment.properties</exclude>
+                            <exclude>systemvm/agent/js/jquery.js</exclude>
+                            <exclude>systemvm/agent/js/jquery.flot.navigate.js</exclude>
+                            <exclude>systemvm/debian/**</exclude>
+                            <exclude>test/integration/component/test_host_ha.sh</exclude>
+                            <exclude>test/systemvm/README.md</exclude>
+                            <exclude>tools/appliance/*/template.json</exclude>
+                            <exclude>tools/cli/cloudmonkey.egg-info/*</exclude>
+                            <exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
+                            <exclude>tools/docker/Dockerfile</exclude>
+                            <exclude>tools/docker/supervisord.conf</exclude>
+                            <exclude>tools/logo/apache_cloudstack.png</exclude>
+                            <exclude>tools/marvin/Marvin.egg-info/*</exclude>
+                            <exclude>tools/marvin/marvin/sandbox/advanced/sandbox.cfg</exclude>
+                            <exclude>tools/ngui/static/bootstrap/*</exclude>
+                            <exclude>tools/ngui/static/js/lib/*</exclude>
+                            <exclude>tools/transifex/.tx/config</exclude>
+                            <exclude>ui/css/token-input-facebook.css</exclude>
+                            <exclude>ui/l10n/*</exclude>
+                            <exclude>ui/lib/flot/jquery.colorhelpers.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.crosshair.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.fillbetween.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.image.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.navigate.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.pie.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.resize.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.selection.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.stack.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.symbol.js</exclude>
+                            <exclude>ui/lib/flot/jquery.flot.threshold.js</exclude>
+                            <exclude>ui/lib/jquery-ui/css/jquery-ui.css</exclude>
+                            <exclude>ui/lib/jquery-ui/index.html</exclude>
+                            <exclude>ui/lib/jquery-ui/js/jquery-ui.js</exclude>
+                            <exclude>ui/lib/jquery.cookies.js</exclude>
+                            <exclude>ui/lib/jquery.easing.js</exclude>
+                            <exclude>ui/lib/jquery.js</exclude>
+                            <exclude>ui/lib/jquery.md5.js</exclude>
+                            <exclude>ui/lib/jquery.validate.js</exclude>
+                            <exclude>ui/lib/jquery.tokeninput.js</exclude>
+                            <exclude>ui/lib/qunit/qunit.css</exclude>
+                            <exclude>ui/lib/qunit/qunit.js</exclude>
+                            <exclude>ui/lib/reset.css</exclude>
+                            <exclude>ui/lib/require.js</exclude>
+                            <exclude>utils/testsmallfileinactive</exclude>
+                        </excludes>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>${cs.compiler-plugin.version}</version>
+                    <configuration>
+                        <source>${cs.jdk.version}</source>
+                        <target>${cs.jdk.version}</target>
+                        <fork>true</fork>
+                        <meminitial>128m</meminitial>
+                        <maxmem>512m</maxmem>
+                        <compilerArgument>-XDignore.symbol.file=true</compilerArgument>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>${cs.jar-plugin.version}</version>
+                    <configuration>
+                        <archive>
+                            <addMavenDescriptor>false</addMavenDescriptor>
+                            <manifest>
+                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                            </manifest>
+                        </archive>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <version>${cs.builder-helper-plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>remove-old-installers</id>
+                            <goals>
+                                <goal>remove-project-artifact</goal>
+                            </goals>
+                            <configuration>
+                                <removeAll>true</removeAll>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-dependency-plugin</artifactId>
-                    <versionRange>[2.0,)</versionRange>
-                    <goals>
-                      <goal>copy-dependencies</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore/>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>com.mycila</groupId>
-                    <artifactId>license-maven-plugin</artifactId>
-                    <versionRange>[2.5,)</versionRange>
-                    <goals>
-                      <goal>format</goal>
-                      <goal>check</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.codehaus.gmaven</groupId>
-                    <artifactId>gmaven-plugin</artifactId>
-                    <versionRange>[1.3,)</versionRange>
-                    <goals>
-                      <goal>compile</goal>
-                      <goal>testCompile</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-			<pluginExecutionFilter>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-checkstyle-plugin</artifactId>
-				<versionRange>[2.11,)</versionRange>
-				<goals>
-					<goal>check</goal>
-				</goals>
-			</pluginExecutionFilter>
-			<action>
-				<ignore></ignore>
-			</action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-antrun-plugin</artifactId>
-          <version>1.8</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.rat</groupId>
-          <artifactId>apache-rat-plugin</artifactId>
-          <configuration>
-            <numUnapprovedLicenses>0</numUnapprovedLicenses>
-            <excludeSubProjects>false</excludeSubProjects>
-            <excludes>
-              <exclude>CHANGES.md</exclude>
-              <exclude>README.md</exclude>
-              <exclude>INSTALL.md</exclude>
-              <exclude>CONTRIBUTING.md</exclude>
-              <exclude>tools/docker/Dockerfile</exclude>
-              <exclude>tools/docker/supervisord.conf</exclude>
-              <exclude>.java-version</exclude>
-              <exclude>.python-version</exclude>
-              <exclude>.idea/</exclude>
-              <exclude>**/*.log</exclude>
-              <exclude>**/*.patch</exclude>
-              <exclude>**/.classpath</exclude>
-              <exclude>**/.project</exclude>
-              <exclude>**/.idea/**</exclude>
-              <exclude>**/*.iml</exclude>
-              <exclude>**/.settings/**</exclude>
-              <exclude>.metadata/**</exclude>
-              <exclude>.git/**</exclude>
-              <exclude>.gitignore</exclude>
-              <exclude>**/*.crt</exclude>
-              <exclude>**/*.csr</exclude>
-              <exclude>**/*.key</exclude>
-              <exclude>**/authorized_keys</exclude>
-              <exclude>**/*.war</exclude>
-              <exclude>**/*.mar</exclude>
-              <exclude>**/*.jar</exclude>
-              <exclude>**/*.iso</exclude>
-              <exclude>**/*.tgz</exclude>
-              <exclude>**/*.zip</exclude>
-              <exclude>**/target/**</exclude>
-              <exclude>**/.vagrant</exclude>
-              <exclude>**/*.json</exclude>
-              <exclude>build/build.number</exclude>
-              <exclude>services/console-proxy/server/js/jquery.js</exclude>
-              <exclude>debian/cloudstack-usage.dirs</exclude>
-              <exclude>debian/cloudstack-agent.dirs</exclude>
-              <exclude>debian/compat</exclude>
-              <exclude>debian/control</exclude>
-              <exclude>debian/dirs</exclude>
-              <exclude>debian/rules</exclude>
-              <exclude>debian/source/format</exclude>
-              <exclude>dist/console-proxy/js/jquery.js</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/packages/**</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/.nuget/**</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/obj/**</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/bin/**</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/packages.config</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/App.config</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.csproj</exclude>
-              <exclude>plugins/hypervisors/hyperv/DotNet/ServerResource/**/*.settings</exclude>
-              <exclude>plugins/hypervisors/hyperv/conf/agent.properties</exclude>
-              <exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
-              <exclude>services/console-proxy/server/conf/agent.properties</exclude>
-              <exclude>services/console-proxy/server/conf/environment.properties</exclude>
-              <exclude>services/secondary-storage/conf/agent.properties</exclude>
-              <exclude>services/secondary-storage/conf/environment.properties</exclude>
-              <exclude>test/systemvm/README.md</exclude>
-              <exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
-              <exclude>tools/appliance/*/template.json</exclude>
-              <exclude>tools/cli/cloudmonkey.egg-info/*</exclude>
-              <exclude>tools/marvin/Marvin.egg-info/*</exclude>
-              <exclude>ui/css/token-input-facebook.css</exclude>
-              <exclude>ui/l10n/*</exclude>
-              <exclude>ui/lib/flot/jquery.colorhelpers.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.crosshair.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.fillbetween.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.image.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.navigate.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.pie.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.resize.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.selection.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.stack.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.symbol.js</exclude>
-              <exclude>ui/lib/flot/jquery.flot.threshold.js</exclude>
-              <exclude>ui/lib/jquery-ui/css/jquery-ui.css</exclude>
-              <exclude>ui/lib/jquery-ui/index.html</exclude>
-              <exclude>ui/lib/jquery-ui/js/jquery-ui.js</exclude>
-              <exclude>ui/lib/jquery.cookies.js</exclude>
-              <exclude>ui/lib/jquery.easing.js</exclude>
-              <exclude>ui/lib/jquery.js</exclude>
-              <exclude>ui/lib/jquery.md5.js</exclude>
-              <exclude>ui/lib/jquery.validate.js</exclude>
-              <exclude>ui/lib/jquery.tokeninput.js</exclude>
-              <exclude>ui/lib/qunit/qunit.css</exclude>
-              <exclude>ui/lib/qunit/qunit.js</exclude>
-              <exclude>ui/lib/reset.css</exclude>
-              <exclude>ui/lib/require.js</exclude>
-              <exclude>utils/testsmallfileinactive</exclude>
-              <exclude>systemvm/agent/conf/agent.properties</exclude>
-              <exclude>systemvm/agent/conf/environment.properties</exclude>
-              <exclude>systemvm/agent/js/jquery.js</exclude>
-              <exclude>systemvm/agent/js/jquery.flot.navigate.js</exclude>
-              <exclude>systemvm/debian/**</exclude>
-              <exclude>tools/transifex/.tx/config</exclude>
-              <exclude>tools/logo/apache_cloudstack.png</exclude>
-              <exclude>tools/marvin/marvin/sandbox/advanced/sandbox.cfg</exclude>
-              <exclude>tools/ngui/static/bootstrap/*</exclude>
-              <exclude>tools/ngui/static/js/lib/*</exclude>
-              <exclude>**/.checkstyle</exclude>
-              <exclude>scripts/installer/windows/acs_license.rtf</exclude>
-              <exclude>**/*.md</exclude>
-              <exclude>test/integration/component/test_host_ha.sh</exclude>
-            </excludes>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-compiler-plugin</artifactId>
-          <version>3.2</version>
-          <configuration>
-            <source>${cs.jdk.version}</source>
-            <target>${cs.jdk.version}</target>
-            <fork>true</fork>
-            <meminitial>128m</meminitial>
-            <maxmem>512m</maxmem>
-            <compilerArgument>-XDignore.symbol.file=true</compilerArgument>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-jar-plugin</artifactId>
-          <version>2.5</version>
-          <configuration>
-            <archive>
-              <addMavenDescriptor>false</addMavenDescriptor>
-              <manifest>
-                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-              </manifest>
-            </archive>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.codehaus.mojo</groupId>
-          <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.9.1</version>
-          <executions>
-            <execution>
-              <id>remove-old-installers</id>
-              <goals>
-                <goal>remove-project-artifact</goal>
-              </goals>
-              <configuration>
-                <removeAll>true</removeAll>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-dependency-plugin</artifactId>
-          <version>2.9</version>
-        </plugin>
-        <plugin>
-          <groupId>org.codehaus.mojo</groupId>
-          <artifactId>cobertura-maven-plugin</artifactId>
-          <configuration>
-            <formats>
-              <format>html</format>
-              <format>xml</format>
-            </formats>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.codehaus.mojo</groupId>
-          <artifactId>findbugs-maven-plugin</artifactId>
-          <version>${cs.findbugs.version}</version>
-          <dependencies>
-            <dependency>
-              <groupId>org.apache.cloudstack</groupId>
-              <artifactId>checkstyle</artifactId>
-              <version>${project.version}</version>
-            </dependency>
-          </dependencies>
-          <configuration>
-            <effort>Max</effort>
-            <threshold>High</threshold>
-            <xmlOutput>true</xmlOutput>
-            <failOnError>false</failOnError>
-            <maxHeap>2048</maxHeap>
-            <excludeFilterFile>findbugsExcludeFilter.xml</excludeFilterFile>
-          </configuration>
-          <executions>
-            <execution>
-              <id>cloudstack-findbugs</id>
-              <goals>
-                <goal>check</goal>
-              </goals>
-            </execution>
-          </executions>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-pmd-plugin</artifactId>
-          <version>3.3</version>
-          <dependencies>
-            <dependency>
-              <groupId>org.apache.cloudstack</groupId>
-              <artifactId>checkstyle</artifactId>
-              <version>${project.version}</version>
-            </dependency>
-          </dependencies>
-          <configuration>
-            <failOnViolation>false</failOnViolation>
-            <rulesets>
-              <ruleset>cloud-pmd.xml</ruleset>
-            </rulesets>
-          </configuration>
-          <executions>
-            <execution>
-              <id>cloudstack-pmd</id>
-              <goals>
-                <goal>check</goal>
-                <goal>cpd-check</goal>
-              </goals>
-            </execution>
-          </executions>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-surefire-plugin</artifactId>
-          <version>2.18.1</version>
-          <configuration>
-            <useSystemClassLoader>false</useSystemClassLoader>
-            <argLine>-Djava.security.egd=file:/dev/./urandom -noverify</argLine>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-failsafe-plugin</artifactId>
-          <version>2.18.1</version>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-  <reporting>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>findbugs-maven-plugin</artifactId>
-        <version>${cs.findbugs.version}</version>
-        <configuration>
-          <threshold>Low</threshold><!-- High|Normal|Low|Exp|Ignore -->
-          <effort>Default</effort><!-- Min|Default|Max -->
-          <excludeFilterFile>${basedir}/findbugsExcludeFilter.xml</excludeFilterFile>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>${cs.javadoc.version}</version>
-        <configuration>
-          <minmemory>128m</minmemory>
-          <maxmemory>1g</maxmemory>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-project-info-reports-plugin</artifactId>
-        <version>2.7</version>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>cobertura-maven-plugin</artifactId>
-        <version>2.6</version>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-        <version>3.4</version>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-resources-plugin</artifactId>
-        <version>2.7</version>
-      </plugin>
-    </plugins>
-  </reporting>
-  <profiles>
-    <profile>
-      <id>systemvm</id>
-      <activation>
-        <property>
-          <name>systemvm</name>
-        </property>
-      </activation>
-      <modules>
-        <module>systemvm</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>eclipse</id>
-      <properties>
-        <cs.target.dir>target-eclipse</cs.target.dir>
-      </properties>
-    </profile>
-    <profile>
-      <id>developer</id>
-      <properties>
-        <marvin.config>tools/devcloud/devcloud.cfg</marvin.config>
-      </properties>
-      <modules>
-        <module>test</module>
-        <module>developer</module>
-        <module>tools</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>impatient</id>
-      <properties>
-        <marvin.config>tools/devcloud/devcloud.cfg</marvin.config>
-      </properties>
-      <modules>
-        <module>developer</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>vmware</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-      <modules>
-        <module>vmware-base</module>
-      </modules>
-    </profile>
-    <profile>
-      <id>disablecheckstyle</id>
-      <build>
+                    <version>${cs.dependency-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>cobertura-maven-plugin</artifactId>
+                    <configuration>
+                        <formats>
+                            <format>html</format>
+                            <format>xml</format>
+                        </formats>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>findbugs-maven-plugin</artifactId>
+                    <version>${cs.findbugs-plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.cloudstack</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>${project.version}</version>
+                        </dependency>
+                    </dependencies>
+                    <configuration>
+                        <effort>Max</effort>
+                        <threshold>High</threshold>
+                        <xmlOutput>true</xmlOutput>
+                        <failOnError>false</failOnError>
+                        <maxHeap>2048</maxHeap>
+                        <excludeFilterFile>findbugsExcludeFilter.xml</excludeFilterFile>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>cloudstack-findbugs</id>
+                            <goals>
+                                <goal>check</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-pmd-plugin</artifactId>
+                    <version>${cs.pmd-plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.cloudstack</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>${project.version}</version>
+                        </dependency>
+                    </dependencies>
+                    <configuration>
+                        <failOnViolation>false</failOnViolation>
+                        <rulesets>
+                            <ruleset>cloud-pmd.xml</ruleset>
+                        </rulesets>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>cloudstack-pmd</id>
+                            <goals>
+                                <goal>check</goal>
+                                <goal>cpd-check</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${cs.surefire-plugin.version}</version>
+                    <configuration>
+                        <useSystemClassLoader>false</useSystemClassLoader>
+                        <argLine>-Djava.security.egd=file:/dev/./urandom -noverify</argLine>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-failsafe-plugin</artifactId>
+                    <version>${cs.failsafe-plugin.version}</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    <reporting>
         <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-checkstyle-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>cloudstack-checkstyle</id>
-                <phase>none</phase>
-                <inherited>true</inherited>
-              </execution>
-            </executions>
-          </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>${cs.findbugs-plugin.version}</version>
+                <configuration>
+                    <threshold>Low</threshold><!-- High|Normal|Low|Exp|Ignore -->
+                    <effort>Default</effort><!-- Min|Default|Max -->
+                    <excludeFilterFile>${basedir}/findbugsExcludeFilter.xml</excludeFilterFile>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>${cs.javadoc.version}</version>
+                <configuration>
+                    <minmemory>128m</minmemory>
+                    <maxmemory>1g</maxmemory>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>${cs.project-info-plugin.version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>${cs.cobertura-plugin.version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>${cs.site-plugin.version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>${cs.resources-plugin.version}</version>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>enablefindbugs</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>findbugs-maven-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>cloudstack-findbugs</id>
-                <phase>process-classes</phase>
-                <inherited>true</inherited>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>buildw</id>
-      <activation>
-        <property>
-          <name>buildw</name>
-        </property>
-      </activation>
-      <modules>
-        <module>tools/wix-cloudstack-maven-plugin</module>
-      </modules>
-    </profile>
-  </profiles>
+    </reporting>
+    <profiles>
+        <profile>
+            <id>systemvm</id>
+            <activation>
+                <property>
+                    <name>systemvm</name>
+                </property>
+            </activation>
+            <modules>
+                <module>systemvm</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>eclipse</id>
+            <properties>
+                <cs.target.dir>target-eclipse</cs.target.dir>
+            </properties>
+        </profile>
+        <profile>
+            <id>developer</id>
+            <properties>
+                <marvin.config>tools/devcloud/devcloud.cfg</marvin.config>
+            </properties>
+            <modules>
+                <module>test</module>
+                <module>developer</module>
+                <module>tools</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>impatient</id>
+            <properties>
+                <marvin.config>tools/devcloud/devcloud.cfg</marvin.config>
+            </properties>
+            <modules>
+                <module>developer</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>vmware</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <modules>
+                <module>vmware-base</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>disablecheckstyle</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-checkstyle-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>cloudstack-checkstyle</id>
+                                <phase>none</phase>
+                                <inherited>true</inherited>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>enablefindbugs</id>
+            <build>
+                <plugins>
+<!--                     <plugin> -->
+<!--                         <groupId>org.apache.maven.plugins</groupId> -->
+<!--                         <artifactId>maven-pmd-plugin</artifactId> -->
+<!--                     </plugin> -->
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>findbugs-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>cloudstack-findbugs</id>
+                                <phase>process-classes</phase>
+                                <inherited>true</inherited>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py
index 2b27868..994c822 100755
--- a/python/lib/cloudutils/serviceConfig.py
+++ b/python/lib/cloudutils/serviceConfig.py
@@ -23,6 +23,32 @@
 import os
 import shutil
 
+# exit() error constants
+Unknown = 0
+CentOS6 = 1
+CentOS7 = 2
+Ubuntu = 3
+RHEL6 = 4
+RHEL7 = 5
+distro = None
+
+#=================== DISTRIBUTION DETECTION =================
+if os.path.exists("/etc/centos-release"):
+    version = file("/etc/centos-release").readline()
+    if version.find("CentOS release 6") != -1:
+      distro = CentOS6
+    elif version.find("CentOS Linux release 7") != -1:
+      distro = CentOS7
+elif os.path.exists("/etc/redhat-release"):
+    version = file("/etc/redhat-release").readline()
+    if version.find("Red Hat Enterprise Linux Server release 6") != -1:
+      distro = RHEL6
+    elif version.find("Red Hat Enterprise Linux Server 7") != -1:
+      distro = RHEL7
+elif os.path.exists("/etc/lsb-release") and "Ubuntu" in file("/etc/lsb-release").read(-1): distro = Ubuntu
+else: distro = Unknown
+#=================== DISTRIBUTION DETECTION =================
+
 class serviceCfgBase(object):
     def __init__(self, syscfg):
         self.status = None
@@ -498,7 +524,8 @@
             configureLibvirtConfig(self.syscfg.env.secure, self)
 
             cfo = configFileOps("/etc/sysconfig/libvirtd", self)
-            cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")
+            if distro in (CentOS6,RHEL6):
+                cfo.addEntry("export CGROUP_DAEMON", "'cpu:/virt'")
             cfo.addEntry("LIBVIRTD_ARGS", "-l")
             cfo.save()
 
diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml
index 0b29e11..5026636 100644
--- a/quickcloud/pom.xml
+++ b/quickcloud/pom.xml
@@ -1,30 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-quickcloud</artifactId>
-  <name>Apache CloudStack Framework - QuickCloud</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-maven-standard</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../maven-standard/pom.xml</relativePath>
-  </parent>
+    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-quickcloud</artifactId>
+    <name>Apache CloudStack Framework - QuickCloud</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 </project>
diff --git a/requirements.txt b/requirements.txt
index 5f2551e..4485f5d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -21,5 +21,4 @@
 # Marvin dependencies are installed via its bundle
 
 # Install the SolidFire SDK for Python
-solidfire-sdk-python
-
+solidfire-sdk-python
\ No newline at end of file
diff --git a/scripts/installer/windows/Setup_Databases.wxs b/scripts/installer/windows/Setup_Databases.wxs
deleted file mode 100644
index f401e77..0000000
--- a/scripts/installer/windows/Setup_Databases.wxs
+++ /dev/null
@@ -1,39 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to
-  you under the Apache License, Version 2.0 (the "License"); you may not use
-  this file except in compliance with the License. You may obtain a copy of
-  the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-  by applicable law or agreed to in writing, software distributed under the
-  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific
-  language governing permissions and limitations under the License. -->
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-  <Fragment>
-    <UI>
-      <Dialog Id="DatabaseInformation" Width="370" Height="270" Title="!(loc.DatabaseInformationTitle)">
-        <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
-        <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
-                    <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
-        </Control>
-        <Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeDlgBitmap)" />
-        <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />
-        <Control Id="BottomLine" Type="Line" X="0" Y="235" Width="370" Height="0" />
-        <Control Id="Description" Type="Text" X="135" Y="10" Width="220" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.DatabaseInformationDescription)" />
-
-        <Control Id="DbServerIpLabel" Type="Text" X="160" Y="38" Width="40" Height="20" TabSkip="no" Text="!(loc.DbServerIpLabel)" Transparent="yes"/>
-        <Control Id="DbServerIp" Type="Edit" Height="20" Width="92" X="220" Y="33" Property="DB_HOSTNAME" />
-        <Control Id="DbServerPortLabel" Type="Text" X="160" Y="68" Width="40" Height="20" TabSkip="no" Text="!(loc.DbServerPortLabel)" Transparent="yes"/>
-        <Control Id="DbServerPort" Type="Edit" Height="20" Width="92" X="220" Y="63" Property="DB_PORT" />
-        <Control Id="DbUserNameLabel" Type="Text" X="160" Y="98" Width="40" Height="20" TabSkip="no" Text="!(loc.DbUserNameLabel)" Transparent="yes"/>
-        <Control Id="DbUserName" Type="Edit" Height="20" Width="92" X="220" Y="93" Property="DB_USERNAME" />
-        <Control Id="DbPasswordLabel" Type="Text" X="160" Y="128" Width="40" Height="20" TabSkip="no" Text="!(loc.DbPasswordLabel)" Transparent="yes"/>
-        <Control Id="DbPassword" Type="Edit" Height="20" Width="92" X="220" Y="123" Property="DB_PASSWORD" Password="yes"/>
-        <Control Id="DbRootPasswordLabel" Type="Text" X="160" Y="158" Width="40" Height="20" TabSkip="no" Text="!(loc.DbRootPasswordLabel)" Transparent="yes"/>
-        <Control Id="DbRootPassword" Type="Edit" Height="20" Width="92" X="220" Y="153" Property="DB_ROOT_PASSWORD" Password="yes"/>
-        <Control Id="CreateDBCheckBox" Type="CheckBox" X="160" Y="207" Width="10" Height="10" CheckBoxValue="1" Property="CREATE_DATABASE"/>
-        <Control Id="CreateDBCheckBoxLabel" Type="Text" X="176" Y="207" Width="340" Height="20" TabSkip="no" Text="!(loc.CreateDBCheckBoxLabel)" Transparent="yes"/>
-      </Dialog>
-    </UI>
-  </Fragment>
-</Wix>
\ No newline at end of file
diff --git a/scripts/installer/windows/WixInstallerDialog.wxs b/scripts/installer/windows/WixInstallerDialog.wxs
deleted file mode 100644
index 0282d8a..0000000
--- a/scripts/installer/windows/WixInstallerDialog.wxs
+++ /dev/null
@@ -1,76 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to
-  you under the Apache License, Version 2.0 (the "License"); you may not use
-  this file except in compliance with the License. You may obtain a copy of
-  the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-  by applicable law or agreed to in writing, software distributed under the
-  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific
-  language governing permissions and limitations under the License. -->
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-    <Fragment>
-        <UI Id="WixUI_Mondo_Custom">
-          <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
-            <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
-            <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
-
-            <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
-            <Property Id="WixUI_Mode" Value="Mondo" />
-
-            <DialogRef Id="ErrorDlg" />
-            <DialogRef Id="FatalError" />
-            <DialogRef Id="FilesInUse" />
-            <DialogRef Id="MsiRMFilesInUse" />
-            <DialogRef Id="PrepareDlg" />
-            <DialogRef Id="ProgressDlg" />
-            <DialogRef Id="ResumeDlg" />
-            <DialogRef Id="UserExit" />
-            <DialogRef Id="DatabaseInformation" />
-
-            <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
-
-            <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
-
-            <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
-            <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="SetupTypeDlg" Order="2">LicenseAccepted = "1"</Publish>
-
-            <Publish Dialog="SetupTypeDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
-            <Publish Dialog="SetupTypeDlg" Control="TypicalButton" Event="NewDialog" Value="DatabaseInformation">1</Publish>
-            <Publish Dialog="SetupTypeDlg" Control="CustomButton" Event="NewDialog" Value="CustomizeDlg">1</Publish>
-            <Publish Dialog="SetupTypeDlg" Control="CompleteButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
-
-            <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">WixUI_InstallMode = "Change"</Publish>
-            <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="SetupTypeDlg" Order="2">WixUI_InstallMode = "InstallCustom"</Publish>
-            <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="DatabaseInformation">1</Publish>
-
-            <Publish Dialog="DatabaseInformation" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="1">WixUI_InstallMode = "InstallCustom"</Publish>
-            <Publish Dialog="DatabaseInformation" Control="Back" Event="NewDialog" Value="SetupTypeDlg" Order="2">WixUI_InstallMode = "InstallTypical" OR WixUI_InstallMode = "InstallComplete"</Publish>
-            <Publish Dialog="DatabaseInformation" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="2">NOT Installed</Publish>
-            <Publish Dialog="DatabaseInformation" Control="Back" Event="NewDialog" Value="DatabaseInformation" Order="3">WixUI_InstallMode = "Change"</Publish>
-            <Publish Dialog="DatabaseInformation" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="4">WixUI_InstallMode = "Repair" OR WixUI_InstallMode = "Remove"</Publish>
-
-            <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="DatabaseInformation"></Publish>
-            <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
-
-            <Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="DatabaseInformation">1</Publish>
-            <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
-            <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
-            <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
-
-            <!-- Progress Text for Custom Actions STARTs here -->
-            <ProgressText Action="GenerateSSLKey">!(loc.GenerateSSLKey)</ProgressText>
-            <ProgressText Action="DeployDB">!(loc.DeployDB)</ProgressText>
-            <ProgressText Action="SetupDatabases">!(loc.SetupDatabases)</ProgressText>
-            <ProgressText Action="DeleteDirectory">!(loc.DeleteDirectory)</ProgressText>
-            <ProgressText Action="CopySitePackages">!(loc.CopySitePackages)</ProgressText>
-            <ProgressText Action="SetuptoolsInstallation">!(loc.SetuptoolsInstallation)</ProgressText>
-            <ProgressText Action="DeleteFiles">!(loc.DeleteFiles)</ProgressText>
-            <ProgressText Action="UpdateTomcatCatalinaBase">!(loc.UpdateTomcatCatalinaBase)</ProgressText>
-            <ProgressText Action="UpdateTomcatClassPath">!(loc.UpdateTomcatClassPath)</ProgressText>
-
-            <!-- Progress Text for Custom Actions ENDs here -->
-        </UI>
-        <UIRef Id="WixUI_Common" />
-    </Fragment>
-</Wix>
\ No newline at end of file
diff --git a/scripts/installer/windows/acs.wxs b/scripts/installer/windows/acs.wxs
deleted file mode 100644
index 6f2aec0..0000000
--- a/scripts/installer/windows/acs.wxs
+++ /dev/null
@@ -1,307 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to
-  you under the Apache License, Version 2.0 (the "License"); you may not use
-  this file except in compliance with the License. You may obtain a copy of
-  the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-  by applicable law or agreed to in writing, software distributed under the
-  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific
-  language governing permissions and limitations under the License. -->
-<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:fire='http://schemas.microsoft.com/wix/FirewallExtension' xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>
-  <Product Name='!(loc.ProductName)' Id='eea70ed5-5950-4f01-b4aa-4a07636359bb'
-    UpgradeCode='d6208c34-7b50-4512-b19e-b904dcc1373e' Language='1033'
-    Codepage='1252' Version='4.4.0' Manufacturer='!(loc.ProductManufacturer)'>
-
-    <Package Id='*' Keywords='Installer' Description="!(loc.PackageDescription)"
-      Comments='!(loc.PackageComments)'
-      Manufacturer='!(loc.PackageManufacturer)' Languages='1033' Compressed='yes'
-      SummaryCodepage='1252' Platform="x64" InstallerVersion="500" />
-
-    <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
-    <Property Id='DiskPrompt' Value="Apache Cloud Stack Installation program" />
-
-    <!-- Get JAVA_HOME here -->
-    <Property Id='JAVA_HOME'>
-      <RegistrySearch Id="JavaHomeSearch" Name="JavaHome"
-        Root="HKLM" Key="SOFTWARE\JavaSoft\Java Development Kit\1.7"
-        Type="raw" Win64="yes" />
-    </Property>
-    <Condition
-      Message="!(loc.Java7ConditionMessage)"><![CDATA[(Installed OR JAVA_HOME)]]></Condition>
-
-    <!-- Get Tomcat6 installation path -->
-    <Property Id='TOMCATDIRECTORY'>
-      <RegistrySearch Id="TomcatSearch" Name="InstallPath"
-        Root="HKLM" Key="SOFTWARE\Apache Software Foundation\Tomcat\6.0\Tomcat6"
-        Type="raw" Win64="yes" />
-    </Property>
-    <Condition
-      Message="!(loc.Tomcat6ConditionMessage)"><![CDATA[(Installed OR TOMCATDIRECTORY)]]></Condition>
-
-    <!-- Get Python installation path -->
-    <Property Id='PYTHON_HOME'>
-      <RegistrySearch Id="PythonSearch" Root="HKLM"
-        Key="SOFTWARE\Python\PythonCore\2.7\InstallPath" Type="raw"
-        Win64="yes" />
-    </Property>
-    <Condition
-      Message="!(loc.Python2ConditionMessage)"><![CDATA[(Installed OR PYTHON_HOME)]]></Condition>
-
-    <!-- Get 7Z installation path -->
-    <Property Id='SEVENZ_HOME'>
-      <RegistrySearch Id="SecenZSearch" Name="Path" Root="HKLM"
-        Key="SOFTWARE\7-Zip" Type="raw" Win64="yes" />
-    </Property>
-    <Property Id='MYSQL'>
-      <RegistrySearch Id="MySqlSearch" Name="Location" Root="HKLM" Key="SOFTWARE\Wow6432Node\MySQL AB\MySQL Server 5.1" Type="raw" Win64="yes" />
-    </Property>
-    <Condition Message="!(loc.SevenZConditionMessage)"><![CDATA[(Installed OR SEVENZ_HOME)]]></Condition>
-
-    <!-- Properties for Database Related Information to be collected -->
-    <Property Id="DB_USERNAME" Value="cloud" />
-    <Property Id="DB_PASSWORD" Value="cloud" Hidden="yes"/>
-    <Property Id="DB_HOSTNAME" Value="localhost" />
-    <Property Id="DB_PORT" Value="3306" />
-    <Property Id="DB_ROOT_PASSWORD" Hidden="yes"/>
-
-    <Directory Id='TARGETDIR' Name='SourceDir'>
-      <Directory Id='ProgramFilesFolder' Name='PFiles'>
-        <Directory Id='Acme' Name='Apache'>
-          <Directory Id='INSTALLDIR' Name='CS'>
-            <Component Id='MainExecutable'
-              Guid='5980d204-a63a-45db-a7e8-cbd50b2d314b'>
-              <CreateFolder />
-              <Environment Id="CLOUDSTACK_HOME" Action="set"
-                Name="CLOUDSTACK_HOME" Permanent="no" System="yes"
-                Value="[INSTALLDIR]." />
-              <Environment Id="CATALINA_BASE" Action="set"
-                Name="CATALINA_BASE" Permanent="no" System="yes"
-                Value="[INSTALLDIR]." />
-              <Environment Id="CATALINA_OPTS" Action="set"
-                Name="CATALINA_OPTS" Permanent="no" System="yes"
-                Value="-XX:MaxPermSize=512m -Xmx1024m -Xms256m" />
-              <Environment Id="Path" Action="set" Name="Path"
-                Permanent="no" System="yes" Part="last"
-                Value="[JAVA_HOME]bin;[PYTHON_HOME];[SEVENZ_HOME];[ProgramFilesFolder]cdrtools;[MYSQL]bin;[INSTALLDIR]scripts" />
-              <Environment Id="PATHEXT" Action="set" Name="PATHEXT"
-                Permanent="no" System="yes" Part="last"
-                Value=".py" />
-            </Component>
-            <Component Id='setuptools' Guid='019a51dd-7fc4-4d6c-9277-13cc7b600789'>
-              <File Id="ez_setup" Source="ez_setup.py" />
-            </Component>
-          </Directory>
-        </Directory>
-      </Directory>
-
-      <Directory Id="ProgramMenuFolder" Name="Programs">
-        <Directory Id="ProgramMenuDir" Name="ACS">
-          <Component Id="ProgramMenuDir" Guid="69932d81-ea9c-4a74-9013-7da61f291090">
-            <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
-            <RegistryValue Root='HKCU'
-              Key='Software\[Manufacturer]\[ProductName]' Type='string'
-              Value='' KeyPath='yes' />
-          </Component>
-        </Directory>
-      </Directory>
-    </Directory>
-    <Property Id='TOMCATIMAGEPATH'>
-      <RegistrySearch Id="TomcatImagePath" Name="ImagePath"
-        Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\Tomcat6"
-        Type="raw" Win64="yes" />
-    </Property>
-    <util:Group Id="Administrators" Name="Administrators"/>
-    <Component Id="ServiceInstaller" Directory="INSTALLDIR"
-      Guid="dfebb4bb-cac0-4cef-aa91-342bafa18349">
-      <util:User Id="AccountCreation" CreateUser="yes" FailIfExists="no" Name="cloud" Password="C!0ud" RemoveOnUninstall="yes" UpdateIfExists="yes" LogonAsService="yes">
-        <util:GroupRef Id="Administrators" />
-      </util:User>
-      <File Id='ACSServiceEXEFile' Name='start.exe' Source='start.bat'
-        KeyPath='yes' />
-      <ServiceInstall Id='InstallACSService' Name='ACSService'
-        Description='ACS Service' ErrorControl='normal' Start='auto'
-        Type='ownProcess' Vital='yes'>
-        <util:PermissionEx User="cloud" GenericAll="yes" ServiceStart="yes" ServiceStop="yes" ServicePauseContinue="yes" ServiceInterrogate="yes" ServiceChangeConfig="yes" ServiceEnumerateDependents="yes"
-          ServiceQueryConfig="yes" ServiceQueryStatus="yes" ServiceUserDefinedControl="yes" />
-      </ServiceInstall>
-      <ServiceControl Id='UninstallACSService' Name='ACSService'
-        Remove='uninstall' Wait='yes' />
-      <RegistryValue Root='HKLM'
-        Key='SYSTEM\CurrentControlSet\Services\ACSService' Name="ImagePath"
-        Type='expandable' Value='[TOMCATIMAGEPATH]' />
-    </Component>
-    <DirectoryRef Id="INSTALLDIR">
-      <Directory Id="CSMANAGEMENT" Name="cloudstack-management">
-        <Directory Id="WEBAPPS" Name="webapps">
-          <Component Id="webappsFolder" Guid="53c03092-438f-4da1-b14d-ceee90c79de0">
-            <CreateFolder />
-          </Component>
-        </Directory>
-      </Directory>
-    </DirectoryRef>
-    <DirectoryRef Id="WEBAPPS">
-      <Component Id="copyToConf" Guid="99da8926-1eec-4a7f-ac7f-1326d8e73ea0"
-        KeyPath="yes">
-        <File Id="server.xml" Source="client\WEB-INF\classes\server-nonssl.xml"
-          Checksum="no">
-          <CopyFile Id="copyServerXML" DestinationName="server.xml"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="tomcat6.conf" Source="client\WEB-INF\classes\tomcat6-nonssl.conf"
-          Checksum="no">
-          <CopyFile Id="copyTomcat6ConfXML" DestinationName="tomcat6.conf"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="web.xml" Source="client\WEB-INF\classes\web.xml"
-          Checksum="no">
-          <CopyFile Id="copyWebXML" DestinationName="web.xml"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="log4j_cloud.xml" Source="client\WEB-INF\classes\log4j-cloud.xml"
-          Checksum="no">
-          <CopyFile Id="log4j_cloudxml" DestinationName="log4j-cloud.xml"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="environment.properties" Source="client\WEB-INF\classes\environment.properties"
-          Checksum="no">
-          <CopyFile Id="environmentproperties" DestinationName="environment.properties"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="classpath.conf" Source="client\WEB-INF\classes\classpath.conf"
-          Checksum="no">
-          <CopyFile Id="classpathconf" DestinationName="classpath.conf"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="catalina.properties" Source="client\WEB-INF\classes\catalina.properties"
-          Checksum="no">
-          <CopyFile Id="catalinaproperties" DestinationName="catalina.properties"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="tomcat_users.xml" Source="client\WEB-INF\classes\tomcat-users.xml"
-          Checksum="no">
-          <CopyFile Id="tomcat_usersxml" DestinationName="tomcat-users.xml"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="catalina.policy" Source="client\WEB-INF\classes\catalina.policy"
-          Checksum="no">
-          <CopyFile Id="catalinapolicy" DestinationName="catalina.policy"
-            DestinationDirectory="CONF" />
-        </File>
-        <File Id="db.properties" Source="client\WEB-INF\classes\db.properties"
-          Checksum="no">
-          <CopyFile Id="dbproperties" DestinationName="db.properties"
-            DestinationDirectory="LIB" />
-        </File>
-      </Component>
-    </DirectoryRef>
-    <DirectoryRef Id="CSMANAGEMENT">
-      <Directory Id="CONF" Name="conf">
-        <Component Id="confFolder" Guid="ad227f7d-6808-4bdf-8ac6-3b2954d51b96">
-          <CreateFolder />
-        </Component>
-      </Directory>
-    </DirectoryRef>
-    <DirectoryRef Id="CSMANAGEMENT">
-      <Directory Id="LIB" Name="lib">
-        <Component Id="libFolder" Guid="d338841e-2ea4-48b3-ab48-9c42e2961600">
-          <CreateFolder />
-        </Component>
-      </Directory>
-    </DirectoryRef>
-    <Component Id="firewallRules" Guid="2d056999-8191-41a0-94e0-e6dfcc188417"
-      Directory="INSTALLDIR">
-      <CreateFolder />
-      <fire:FirewallException Id="p_8080" Name="port_8080"
-        Description="for cloudstack management server" Port="8080"
-        Profile="all" Protocol="tcp" Scope="any" />
-      <fire:FirewallException Id="p_8096" Name="port_8096"
-        Description="for cloudstack management server admin" Port="8096"
-        Profile="all" Protocol="tcp" Scope="any" />
-      <fire:FirewallException Id="p_8787" Name="port_8787"
-        Description="for cloudstack management server" Port="8787"
-        Profile="all" Protocol="tcp" Scope="any" />
-      <fire:FirewallException Id="p_9090" Name="port_9090"
-        Description="for cloudstack management server" Port="9090"
-        Profile="all" Protocol="tcp" Scope="any" />
-
-      <fire:FirewallException Id="p_3922" Name="port_3922"
-        Description="for cloudstack management server" Port="3922"
-        Profile="all" Protocol="tcp" Scope="any" />
-      <fire:FirewallException Id="p_8250" Name="port_8250"
-        Description="for cloudstack management server" Port="8250"
-        Profile="all" Protocol="tcp" Scope="any" />
-    </Component>
-
-    <!-- Updating Tomcat's catalina base -->
-    <CustomAction Id="TomcatPath" Property="TOMCATDIRECTORY1"
-      Value="[TOMCATDIRECTORY]\bin\Tomcat6.exe">
-    </CustomAction>
-    <CustomAction Id="UpdateTomcatCatalinaBase"
-      ExeCommand='//US//Tomcat6 --JvmOptions=-Dcatalina.base=[CSMANAGEMENT];-Djava.io.tmpdir=[CSMANAGEMENT]\temp;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager;-Dcatalina.home="[TOMCATDIRECTORY]";-Xms512m;-Xmx1024m;-XX:MaxPermSize=512m;-Duser.name=cloud'
-      Property="TOMCATDIRECTORY1" Execute="deferred" Return="check" />
-    <CustomAction Id="UpdateTomcatClassPath"
-      ExeCommand='//US//Tomcat6 --Classpath="[TOMCATDIRECTORY]\bin\bootstrap.jar";"[TOMCATDIRECTORY]\bin\tomcat-juli.jar";[CSMANAGEMENT]\conf;[CSMANAGEMENT]\lib;[CSMANAGEMENT]\setup'
-      Property="TOMCATDIRECTORY1" Execute="deferred" Return="check" />
-    <CustomAction Id="CopySitePackages" Directory='INSTALLDIR'
-      ExeCommand='[SystemFolder]cmd.exe /c xcopy /S "[INSTALLDIR]\python-site-packages" [PYTHON_HOME]\Lib\site-packages'
-      Execute="deferred" Return="check"/>
-    <CustomAction Id="DeleteDirectory" Directory='INSTALLDIR'
-      ExeCommand='[SystemFolder]cmd.exe /c RD /S /Q "[INSTALLDIR]\python-site-packages"'
-      Execute="deferred" Return="check" />
-    <CustomAction Id="DeleteFiles" Directory='CSMANAGEMENT'
-      ExeCommand='[SystemFolder]cmd.exe /c del "[CSMANAGEMENT]\webapps\client\WEB-INF\classes\db.properties" "[CSMANAGEMENT]\webapps\client\WEB-INF\classes\log4j*.xml"'
-      Execute="deferred" Return="check" />
-    <CustomAction Id="SetuptoolsInstallation" Directory='INSTALLDIR'
-      ExeCommand='[PYTHON_HOME]\python "[INSTALLDIR]\ez_setup.py"'
-      Execute="deferred" Return="check" />
-    <CustomAction Id="DbHostWithPort" Execute="immediate" Property="DB_HOSTNAME" Value="[DB_HOSTNAME]:[DB_PORT]" />
-    <CustomAction Id="DeployDB" Directory='CSMANAGEMENT'
-      ExeCommand='[PYTHON_HOME]\python "[INSTALLDIR]\scripts\cloud-setup-databases" [DB_USERNAME]:[DB_PASSWORD]@[DB_HOSTNAME] --deploy-as=root:[DB_ROOT_PASSWORD] -c "[CSMANAGEMENT]\lib" -f "[CSMANAGEMENT]\setup" -j "[CSMANAGEMENT]\webapps\client\WEB-INF\lib\jasypt-1.9.2.jar" -n "[CSMANAGEMENT]\lib\key" -b "[MYSQL]\bin"'
-      Execute="deferred" Return="check" Impersonate="no"/>
-    <CustomAction Id="SetupDatabases" Directory='CSMANAGEMENT'
-      ExeCommand='[PYTHON_HOME]\python "[INSTALLDIR]\scripts\cloud-setup-databases" [DB_USERNAME]:[DB_PASSWORD]@[DB_HOSTNAME] -c "[CSMANAGEMENT]\lib" -f "[CSMANAGEMENT]\setup" -j "[CSMANAGEMENT]\webapps\client\WEB-INF\lib\jasypt-1.9.2.jar" -n "[CSMANAGEMENT]\lib\key" -b "[MYSQL]\bin"'
-      Execute="deferred" Return="check" Impersonate="no"/>
-
-    <InstallExecuteSequence>
-      <InstallServices Sequence="4990"></InstallServices>
-      <Custom Action="TomcatPath" Before="UpdateTomcatClassPath">NOT Installed</Custom>
-      <Custom Action="UpdateTomcatClassPath" Before="UpdateTomcatCatalinaBase">NOT Installed
-      </Custom>
-      <Custom Action="UpdateTomcatCatalinaBase" Before="DeleteFiles">NOT
-        Installed</Custom>
-      <Custom Action="DeleteFiles" Before="SetuptoolsInstallation">NOT Installed</Custom>
-      <Custom Action="SetuptoolsInstallation" Before="GenerateSSLKey">NOT Installed</Custom>
-      <Custom Action="GenerateSSLKey" After="PublishProduct">NOT Installed
-      </Custom>
-      <Custom Action="CopySitePackages" After="GenerateSSLKey">NOT Installed</Custom>
-      <Custom Action="DeleteDirectory" After="CopySitePackages">NOT Installed</Custom>
-      <Custom Action="DbHostWithPort" After="InstallFiles"><![CDATA[DB_PORT]]></Custom>
-      <Custom Action="DeployDB" After="DeleteDirectory">(NOT Installed) AND (CREATE_DATABASE = "1")
-      </Custom>
-      <Custom Action="SetupDatabases" After="DeleteDirectory">(NOT Installed) AND (<![CDATA[CREATE_DATABASE <> "1"]]>)
-      </Custom>
-    </InstallExecuteSequence>
-    <Feature Id='Complete' Title='!(loc.ProductName)' Description='!(loc.FeatureDescription2)'
-      Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
-      <Feature Id='MainProgram' Title='!(loc.FeatureTitle1)' Description='!(loc.FeatureDescription1)'
-        Level='1'>
-        <ComponentRef Id='webappsFolder' />
-        <ComponentGroupRef Id='ClientPath' />
-        <ComponentGroupRef Id='SetupPath' />
-        <ComponentGroupRef Id='UtilitiesPath' />
-        <ComponentGroupRef Id='PythonSitePackagesPath' />
-        <ComponentRef Id='ProgramMenuDir' />
-        <ComponentRef Id='confFolder' />
-        <ComponentRef Id='libFolder' />
-        <ComponentRef Id='copyToConf' />
-        <ComponentRef Id='firewallRules' />
-        <ComponentRef Id='MainExecutable' />
-        <ComponentRef Id='setuptools' />
-        <ComponentRef Id='ServiceInstaller' />
-      </Feature>
-    </Feature>
-		<UIRef Id="WixUI_Mondo_Custom" />
-		<UIRef Id="WixUI_ErrorProgressText" />
-  </Product>
-</Wix>
diff --git a/scripts/installer/windows/acs_license.rtf b/scripts/installer/windows/acs_license.rtf
deleted file mode 100644
index 537b7f4..0000000
--- a/scripts/installer/windows/acs_license.rtf
+++ /dev/null
@@ -1,157 +0,0 @@
-{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31506\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;}
-{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
-{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}
-{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
-{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
-{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
-{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
-{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f409\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f410\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
-{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}
-{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
-{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
-{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
-{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
-{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
-{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}
-{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}
-{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
-{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
-{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
-{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
-{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
-{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
-{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
-{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
-{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
-{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
-{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
-{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
-{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
-{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
-\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp \f31506\fs22 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1
-\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025
-\ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
-\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1
-\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}}
-{\*\rsidtbl \rsid551149\rsid3694456\rsid16267268}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Damodar Reddy}{\operator Damodar Reddy}
-{\creatim\yr2014\mo4\dy23\hr15\min21}{\revtim\yr2014\mo4\dy23\hr15\min21}{\version2}{\edmins0}{\nofpages1}{\nofwords3}{\nofchars22}{\*\company Citrix Systems, Inc}{\nofcharsws24}{\vern49167}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2
-003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
-\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen
-\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1
-\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
-\asianbrkrule\rsidroot16267268\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0
-{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
-{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
-{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
-\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1
-\af31507 \ltrch\fcs0 \insrsid3694456 Please add license here\'85}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid551149
-\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
-9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
-5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
-b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
-0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
-a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
-c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
-0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
-a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
-6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
-4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
-4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210030dd4329a8060000a41b0000160000007468656d652f7468656d652f
-7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87
-615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad
-79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b
-5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab
-999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9
-699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586
-8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6
-0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f
-9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be
-15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979
-3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d
-32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a
-f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86
-e877f0034e16bafb0e258ebb4faf06b769e888340b103d331115bebc4eb813bf83291b63624a0d1475a756c734f9bbc2cd28546ecbe1e20a3794ca175f3fae90
-fb6d2dd99bb07b55e5ccf68942bd0877b23c77b908e8db5f9db7f024d9239010f35bd4bbe2fcae387bfff9e2bc289f2fbe24cfaa301468dd8bd846dbb4ddf1c2
-ae7b4c191ba8292337a469bc25ec3d411f06f53a73e224c5292c8de0516732307070a1c0660d125c7d44553488700a4d7bddd3444299910e254ab984c3a219ae
-a4adf1d0f82b7bd46cea4388ad1c12ab5d1ed8e1153d9c9f350a3246aad01c6873462b9ac05999ad5cc988826eafc3acae853a33b7ba11cd1445875ba1b236b1
-399483c90bd560b0b0263435085a21b0f22a9cf9356b38ec6046026d77eba3dc2dc60b17e92219e180643ed27acffba86e9c94c7ca9c225a0f1b0cfae0788ad5
-4adc5a9aec1b703b8b93caec1a0bd8e5de7b132fe5113cf312503b998e2c2927274bd051db6b35979b1ef271daf6c6704e86c73805af4bdd476216c26593af84
-0dfb5393d964f9cc9bad5c313709ea70f561ed3ea7b053075221d51696910d0d339585004b34272bff7213cc7a510a5454a3b349b1b206c1f0af490176745d4b
-c663e2abb2b34b23da76f6352ba57ca2881844c1111ab189d8c7e07e1daaa04f40255c77988aa05fe06e4e5bdb4cb9c5394bbaf28d98c1d971ccd20867e556a7
-689ec9166e0a522183792b8907ba55ca6e943bbf2a26e52f48957218ffcf54d1fb09dc3eac04da033e5c0d0b8c74a6b43d2e54c4a10aa511f5fb021a07533b20
-5ae07e17a621a8e082dafc17e450ffb739676998b48643a4daa7211214f623150942f6a02c99e83b85583ddbbb2c4996113211551257a656ec1139246ca86be0
-aadedb3d1441a89b6a929501833b197fee7b9641a3503739e57c732a59b1f7da1cf8a73b1f9bcca0945b874d4393dbbf10b1680f66bbaa5d6f96e77b6f59113d
-316bb31a795600b3d256d0cad2fe354538e7566b2bd69cc6cbcd5c38f0e2bcc63058344429dc2121fd07f63f2a7c66bf76e80d75c8f7a1b622f878a18941d840
-545fb28d07d205d20e8ea071b283369834296bdaac75d256cb37eb0bee740bbe278cad253b8bbfcf69eca23973d939b97891c6ce2cecd8da8e2d343578f6648a
-c2d0383fc818c798cf64e52f597c740f1cbd05df0c264c49134cf09d4a60e8a107260f20f92d47b374e32f000000ffff0300504b030414000600080000002100
-0dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f7
-8277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89
-d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd500
-1996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0f
-bfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6
-a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a
-0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d00140006000800000021
-0030dd4329a8060000a41b00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d001400060008
-00000021000dd1909fb60000001b0100002700000000000000000000000000b20900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ad0a00000000}
-{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
-617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
-6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
-656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
-{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
-\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;
-\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7;
-\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;
-\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;
-\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000
-4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
-d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000709d
-38a1d95ecf01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
-000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/scripts/installer/windows/client.wxs b/scripts/installer/windows/client.wxs
deleted file mode 100644
index c54b76c..0000000
--- a/scripts/installer/windows/client.wxs
+++ /dev/null
@@ -1,2393 +0,0 @@
-ï»¿<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to you under
-  the Apache License, Version 2.0 (the "License"); you may not use this file except
-  in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-  Unless required by applicable law or agreed to in writing, software distributed under
-  the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific language
-  governing permissions and limitations under the License. -->
-<?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-    <Fragment>
-        <DirectoryRef Id="WEBAPPS">
-            <Directory Id="dir96B1059B78BC5220348BC64D2C915517" Name="client">
-                <Directory Id="dir1ACEF08E1E39353E790054E32AAB395B" Name="css">
-                    <Component Id="cmp37A6D01A784CC885922881D8CC3D5BB8" Guid="{C7CDB7FC-BBC3-4D16-8841-0ADAAED648DA}">
-                        <File Id="fil057A7F1A7D66E761998D3D3A2F236950" KeyPath="yes" Source="!(wix.SourceClient)\css\cloudstack3-ie7.css" />
-                    </Component>
-                    <Component Id="cmpFFAC5964C1B559F5D69E9D45D9C147B8" Guid="{E6564CD0-67AD-41E0-ADEF-8CE4F1B03C5B}">
-                        <File Id="fil831A7D57997E7EF1C6D7A5A72312F27E" KeyPath="yes" Source="!(wix.SourceClient)\css\cloudstack3.css" />
-                    </Component>
-                    <Component Id="cmp694FC18AC73FEF24D97069F52AD9FC09" Guid="{FEFE6D8B-14F9-4DF4-B12F-533407D5DE63}">
-                        <File Id="filB8A234C51EEE128C3FA376F05780CA72" KeyPath="yes" Source="!(wix.SourceClient)\css\cloudstack3.ja_JP.css" />
-                    </Component>
-                </Directory>
-                <Directory Id="dir589599B03173363B5CAD31FC43ACB681" Name="images">
-                    <Component Id="cmp4A4973B4BE51E3359E297E244D879F48" Guid="{6B17CFD4-4598-44A0-BF5F-17A1DBECA4C8}">
-                        <File Id="fil91A69BC9233DAC7DE673AFD883C1667F" KeyPath="yes" Source="!(wix.SourceClient)\images\ajax-loader-small.gif" />
-                    </Component>
-                    <Component Id="cmpDBAA10EB0F11FA1B83B24A565C454890" Guid="{94000A32-10BE-4F03-A2EE-2F56844EA2FD}">
-                        <File Id="fil6266185D0A743FE70215351084BE335D" KeyPath="yes" Source="!(wix.SourceClient)\images\ajax-loader.gif" />
-                    </Component>
-                    <Component Id="cmp001D278A449DA222443DC90C6457A0AA" Guid="{276BBF28-C9C7-4789-AD26-A850922FA2E1}">
-                        <File Id="filB17F26A3DB0DAEC2B22054D27C27DC76" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-breadcrumb-project-view.png" />
-                    </Component>
-                    <Component Id="cmp699EE66392E8BD62181283BAE3FB8A3C" Guid="{8169BB65-3EE0-4047-8030-3C9A07513380}">
-                        <File Id="filD2B7DC4A58004E5516AEEA8F19AD36CA" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-breadcrumb.png" />
-                    </Component>
-                    <Component Id="cmp921798715C11FE6C4CE02C5309FA4E59" Guid="{D3E796FE-1497-4FEC-A5BA-B610498D22A4}">
-                        <File Id="fil96E88EF448EC4F0BC081ADDB904E603B" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-breadcrumbs-project-view.png" />
-                    </Component>
-                    <Component Id="cmpA7AB5C816F498D515EF3D5FEFD8AA456" Guid="{14C89D18-59BB-4781-BC5E-536CDECFF8B0}">
-                        <File Id="fil093E68A5B4E478200CD9B63FF99536ED" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-breadcrumbs.png" />
-                    </Component>
-                    <Component Id="cmpA6A6B22DF0B4E7A221B70046072548D1" Guid="{2AC99934-A021-40FC-A6D1-CAFF72B6D5B8}">
-                        <File Id="fil24E6DFDED4E01F43C0C4A259E156AD65" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-button-view-more.png" />
-                    </Component>
-                    <Component Id="cmp9B3691B822E42D11260A4FB1DE736FA0" Guid="{8012D397-CDC3-4622-8E5C-230ABEF8F566}">
-                        <File Id="filE603B048D7217C04DD2EFB4B4A3FF82B" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-details-tab-gradient.png" />
-                    </Component>
-                    <Component Id="cmpFFF332A3880849A88855CEB2A49000E7" Guid="{D5655E92-9A4D-4268-ABC2-1A0518F54695}">
-                        <File Id="fil05CF1997B6337FA3AE5E6A4F2A8F97DC" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-dialog-body.png" />
-                    </Component>
-                    <Component Id="cmpE4B5129BCDF4B9ED1D2DF7DAE896AA55" Guid="{A3ECA75C-F0E0-4841-974D-F1C50C6151A2}">
-                        <File Id="filCA5CE57C2C384BFB35C0DFF447E2CFB6" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-dialog-header.png" />
-                    </Component>
-                    <Component Id="cmp61E30D6E1FAB09EEFEAA7BB50D4DA6AE" Guid="{A8CFCFC0-0250-4732-9EC2-B66D32E66E68}">
-                        <File Id="fil2054D165F0FCDEA45FA279C68D97352A" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-gradient-white-transparent.png" />
-                    </Component>
-                    <Component Id="cmp2A053A866278B8A6435A28079840599C" Guid="{308A2BF6-E5D6-47CA-AB2E-B3A9691DCEE8}">
-                        <File Id="fil41C2D76587230DB92F3EADF1853FF589" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-gradients.png" />
-                    </Component>
-                    <Component Id="cmp41626A79664D471C942B94A6FAC377BF" Guid="{43EAAFF0-958A-4A6A-B50E-DBD3694EC885}">
-                        <File Id="filEF9C080A06FAA107D9B9B7011ABB4AC8" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-header.png" />
-                    </Component>
-                    <Component Id="cmp77D0E13995B729E5D67DC50F7F03DDC4" Guid="{8FEFE9A1-8980-4683-AE6B-EEF6686E17AD}">
-                        <File Id="fil19FEF47C4D85324460B36920E8EFEC92" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-install-wizard-header.jpg" />
-                    </Component>
-                    <Component Id="cmp4B1487196540475DE85D83ED0B51DAA0" Guid="{47209345-2FD0-4CE2-A435-95E8B1BB8956}">
-                        <File Id="filC25359F442210C6BC11113AC0A16EE89" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-install-wizard-header.png" />
-                    </Component>
-                    <Component Id="cmpE88A7C334F758F267F3BDA672BA3AD6F" Guid="{7335A4F2-927E-4771-97A5-18FD18DFD327}">
-                        <File Id="fil5CCD7157592840ADA83BB8FEB606EC28" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-login.jpg" />
-                    </Component>
-                    <Component Id="cmp84A913BC71DEC23505B0183AACB43169" Guid="{AE0B3A76-D877-4802-A0A7-B3E2C668D78D}">
-                        <File Id="fil213715BDF5BFDE09BE30A22FBD57AAF4" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-login.png" />
-                    </Component>
-                    <Component Id="cmp358AF2CBCCDEAC74EF66C31443B9D4E1" Guid="{5BF27E77-9FF5-426B-A73B-A465C734D555}">
-                        <File Id="fil43D28113A122E4A9059893394A9B265B" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-naas.png" />
-                    </Component>
-                    <Component Id="cmp9B65184EA19EE89FC312A37AB40C5445" Guid="{FABC46EE-5F4F-429B-AB59-3457A2E15859}">
-                        <File Id="fil2805BCC0C1EDFD13C743A990D252D31B" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-nav-item-active-project-view.png" />
-                    </Component>
-                    <Component Id="cmp953E9ACBDC0C9E8F5837FC99DCF65348" Guid="{D7ED3CE7-9D85-4541-976C-E89442225F76}">
-                        <File Id="fil29DA756A8B7A80DEB2988A423DBFBC30" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-nav-item-active.png" />
-                    </Component>
-                    <Component Id="cmp5BF1C740060955320D9F6A4404B1742E" Guid="{60D61E35-CE4E-49D4-B542-C3E3DA352631}">
-                        <File Id="fil5A3F6775B1BC42FE306FBFD2B156527E" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-nav-item-project-view.png" />
-                    </Component>
-                    <Component Id="cmpCD524965EE7D3214479C877D436CC25A" Guid="{932B3DA9-832C-420D-A832-2497DC163760}">
-                        <File Id="fil98A88D5CF2D5C480935560E398303D21" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-nav-item.png" />
-                    </Component>
-                    <Component Id="cmpD08BCA99B074021280E10519C324E790" Guid="{D7FF8920-1A0B-4F92-89DF-52C50E1ECD9D}">
-                        <File Id="fil6D9EEDA258F5008FE51201A118EB215A" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-network-nat.png" />
-                    </Component>
-                    <Component Id="cmpC16293201DBC9EEF704B7D3B9DA097CB" Guid="{70D52E53-0489-4176-A41F-9F7EC7FF85E6}">
-                        <File Id="fil935382B926B9A72FC0181321F8C1BE6B" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-network.png" />
-                    </Component>
-                    <Component Id="cmp45543CFA36099C39924B174C1D06A2F1" Guid="{24E22B06-C031-453C-A621-29DA02C9A057}">
-                        <File Id="fil1AB3B483E46C31802B063899AEBE3000" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-notifications.png" />
-                    </Component>
-                    <Component Id="cmpEA04275836D88C5DF7EDF8B24FA0C22E" Guid="{E0D2ABFF-F427-4562-973D-7FBABC5B2E58}">
-                        <File Id="fil20A2C70F7F56723335929694087ED51F" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-panel-shadow.png" />
-                    </Component>
-                    <Component Id="cmp0807B9D5A46B8F0627ACB71BBF6F3ADE" Guid="{0C8DBD82-4640-434E-AF9F-68F5AFC94EAD}">
-                        <File Id="filB9F4052049A88058D2C61F1117B3EC28" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-section-switcher.png" />
-                    </Component>
-                    <Component Id="cmp8B663F769A8343653753167A023E9E89" Guid="{E05E8813-176C-45E7-8661-81708842D9F1}">
-                        <File Id="filB57C34C0871657A881F4AEBCC4B72E1E" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-status_box.png" />
-                    </Component>
-                    <Component Id="cmpE34BE2B5CD323AB1181EE3D32B6910EC" Guid="{4F1B4613-574B-4897-949F-71F40387FBFF}">
-                        <File Id="fil6CC6E212EF792822846BFBF0265189D2" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-system-chart-compute.png" />
-                    </Component>
-                    <Component Id="cmpE629675B5F3B5CA6475CA28737C0FAF3" Guid="{FCCD3EAD-B8A5-4D67-A25B-8AFC40346AFA}">
-                        <File Id="fil8F3E44D1C973C756B3663C3BB92BEC6F" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-system-chart-lines.png" />
-                    </Component>
-                    <Component Id="cmpD931241918C8FF9464A80E5CAC921D3A" Guid="{38A6E9F5-0F68-4752-AF1E-10B35B04E02A}">
-                        <File Id="filF020BC68A90E379A629091EA67ABC90F" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-system-network-traffic.png" />
-                    </Component>
-                    <Component Id="cmp10C8FC6390A7D19DF2A617E23302283C" Guid="{9B95E667-6528-4B0C-80BA-FCBA966EA80F}">
-                        <File Id="fil65F759A928A56973BB8F951E0678F07A" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-table-head.png" />
-                    </Component>
-                    <Component Id="cmp175AF405CD11833706ED0B4BF04D274F" Guid="{E40419D7-BEE7-483A-B539-62A92BBF014C}">
-                        <File Id="fil18139F18A15F7E283E01E854C1442E6C" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-transparent-white.png" />
-                    </Component>
-                    <Component Id="cmp8420DC36BDC63CE6EE2175BDC6E3943A" Guid="{F5B73A99-1F9B-4753-8D1A-2DDFE85760B7}">
-                        <File Id="fil88D4855EE2ADE61259470E19469E2C34" KeyPath="yes" Source="!(wix.SourceClient)\images\bg-what-is-cloudstack.png" />
-                    </Component>
-                    <Component Id="cmpAC8E67BEE6565E3D40EB67A5FCC98BDA" Guid="{7E9CFE14-D41F-4ACB-A10D-940ADBF856AD}">
-                        <File Id="filA006FF865AA9485B8B18D36545456B63" KeyPath="yes" Source="!(wix.SourceClient)\images\buttons.png" />
-                    </Component>
-                    <Component Id="cmp740C60E545740A698D5A83B500C1F659" Guid="{A521CED6-0A1F-49BC-907E-F9F81AAB40F7}">
-                        <File Id="fil4E65BAAF9D429C9755775C997912B78A" KeyPath="yes" Source="!(wix.SourceClient)\images\destroy-anim.gif" />
-                    </Component>
-                    <Component Id="cmp5A56787A0DA3FFB130E197ADDA23A0EB" Guid="{5D4E1D65-14BB-4D57-B511-C19C027112D8}">
-                        <File Id="filF645A8E63360DC915BE6E0B932874AB2" KeyPath="yes" Source="!(wix.SourceClient)\images\gradients.png" />
-                    </Component>
-                    <Component Id="cmpBD296011450DE1C0F11EB0FEF5A16BF6" Guid="{D036D4C5-01EB-4CA3-ADD6-F5BDB4D08DE9}">
-                        <File Id="fil34471796C02FE064EF580E61D55E31BA" KeyPath="yes" Source="!(wix.SourceClient)\images\header-gradient.png" />
-                    </Component>
-                    <Component Id="cmpD0010246D4D646A7DF9D13E15F62B5B5" Guid="{F08DAAC7-8458-4BFF-8E6F-F50CD0D89576}">
-                        <File Id="fil17B8BF4A443939FBB8C415EB80D6D62F" KeyPath="yes" Source="!(wix.SourceClient)\images\icons.png" />
-                    </Component>
-                    <Component Id="cmp05395AF83519A533B996404D969144D4" Guid="{71D691BF-23E6-4F81-92CE-112DCA43D002}">
-                        <File Id="fil8028963D1611DAC97104CF75CCFC963C" KeyPath="yes" Source="!(wix.SourceClient)\images\infrastructure-icons.png" />
-                    </Component>
-                    <Component Id="cmpE610FEE8B4F764BC61663BCD33BBA8EA" Guid="{0A5F57D6-847C-4BF6-88EA-44D9031C27D5}">
-                        <File Id="filA2C1B91E3E75DB0856DB31B9B6D03A9E" KeyPath="yes" Source="!(wix.SourceClient)\images\install-wizard-parts.png" />
-                    </Component>
-                    <Component Id="cmp446041577F864F066778735CF97B5941" Guid="{931B1355-0666-41B7-835F-B2752289D075}">
-                        <File Id="fil3342D46D0FC66C0C2DEB6A879FD5B938" KeyPath="yes" Source="!(wix.SourceClient)\images\instance-wizard-parts.png" />
-                    </Component>
-                    <Component Id="cmp786E699F246B34397B746A15229CAC53" Guid="{3D0099F0-BB3E-4B13-8C9B-94324CD99A45}">
-                        <File Id="fil4C77CD8328AD1DBE2390C1B4B72B951F" KeyPath="yes" Source="!(wix.SourceClient)\images\logo-login-oss.png" />
-                    </Component>
-                    <Component Id="cmp8D551322C3C213DE03E2DFE8BE12CAAC" Guid="{CEAAD05D-55EC-4C69-9776-8B612C6BCD5A}">
-                        <File Id="fil3244C191A1C6A8927C810481BB3920FF" KeyPath="yes" Source="!(wix.SourceClient)\images\logo.png" />
-                    </Component>
-                    <Component Id="cmpDFC1633A7E3A2ABB11BAA927DFF04539" Guid="{772EB9EB-39FB-4AF8-9C19-AE9888C44BC0}">
-                        <File Id="fil85700B79A9FA890088BE40B45E529D97" KeyPath="yes" Source="!(wix.SourceClient)\images\minus.png" />
-                    </Component>
-                    <Component Id="cmpEEAF53A0C8D3FDF8D9E19F3E48F25343" Guid="{4FE70AAD-817E-4917-983C-D5D2770EC275}">
-                        <File Id="fil264F167EA9AE30A542F14E80C1EA5319" KeyPath="yes" Source="!(wix.SourceClient)\images\overlay-pattern.png" />
-                    </Component>
-                    <Component Id="cmp6E186870ED4CF468177D7449592B651D" Guid="{1735AF1A-2962-4A6C-9103-A1B891920977}">
-                        <File Id="filFC755B88B988B6799CCF3B813EFE8E8F" KeyPath="yes" Source="!(wix.SourceClient)\images\sample-project-view.png" />
-                    </Component>
-                    <Component Id="cmp1C89ADB77497A7903954C1555FE7D35D" Guid="{9795E109-A613-4891-A396-F6FCDA1121FA}">
-                        <File Id="fil5275F26D095D59CEC0375FDA779A268D" KeyPath="yes" Source="!(wix.SourceClient)\images\sprites.png" />
-                    </Component>
-                    <Component Id="cmp033EEE431FC34259BCA1CE1B246E50F4" Guid="{FEF35205-58DB-42E6-9C9A-2C9CE2C46527}">
-                        <File Id="filABF125D326B2B2880F897A3B8356A17C" KeyPath="yes" Source="!(wix.SourceClient)\images\vm-instance-screen-sample.png" />
-                    </Component>
-                </Directory>
-                <Directory Id="dir0BCC7D5085D0D2A2615E046BFB987A4E" Name="lib">
-                    <Component Id="cmp7865CDD031C64E5AEDC50272B49AA499" Guid="{BF20A618-096B-4B0F-8C97-7D6A3DEDC211}">
-                        <File Id="fil25D062FDA98223E87E630FFF948426CD" KeyPath="yes" Source="!(wix.SourceClient)\lib\date.js" />
-                    </Component>
-                    <Component Id="cmp04B51493F14AA2382A5B8D75BB3170AE" Guid="{9179ADE3-8804-4690-8048-7D3728750187}">
-                        <File Id="fil1B4F601DEBD247F6ADCACC39300943FD" KeyPath="yes" Source="!(wix.SourceClient)\lib\excanvas.js" />
-                    </Component>
-                    <Component Id="cmp187709B7088A01D462071B1644DAD507" Guid="{71DEDF98-8E8E-457B-A4A0-66572962FCFD}">
-                        <File Id="filA26ECBAC3B5B332467D3317AAF760B2F" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery.cookies.js" />
-                    </Component>
-                    <Component Id="cmp689360BFB1D005F5469B2730AA0EF66E" Guid="{02BBC434-34DE-43A2-A28C-2653CDD99E7A}">
-                        <File Id="fil73D69B682B3FE6FA3B8D18651DFFB3F7" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery.easing.js" />
-                    </Component>
-                    <Component Id="cmp831CF8B3F03EFC9A514B88D6AEAC5EA3" Guid="{168B2759-666C-4CA4-BD1D-AF58B14DAD0F}">
-                        <File Id="fil00164449A31199F931EB77B64294A846" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery.js" />
-                    </Component>
-                    <Component Id="cmp231E06009CE8D54EB43B03B874D21646" Guid="{D610E3B7-BD30-42B4-8A82-00E240DA9E56}">
-                        <File Id="filD8AC65943674AC0312AFA2E31E452BF5" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery.md5.js" />
-                    </Component>
-                    <Component Id="cmp00BB4BE58D1A66E07317350D9999B0CC" Guid="{014FA5E6-B6BC-4F10-868D-23AD4AD064A5}">
-                        <File Id="fil7342865268E093BCD1EF15A6DBF3012E" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery.validate.js" />
-                    </Component>
-                    <Component Id="cmpDC1A3A44EFC7FCB16C43B4F459AA9FB5" Guid="{84C0EA60-0AF4-43FF-9780-EA793A6CFC53}">
-                        <File Id="filBBC0D99D8731638C59D61E1D23A9C99F" KeyPath="yes" Source="!(wix.SourceClient)\lib\require.js" />
-                    </Component>
-                    <Component Id="cmpB763DE9DB6AF82BBA5744D06091343F6" Guid="{C4C10418-08BB-40CD-821C-E97226787B32}">
-                        <File Id="fil1CC0FCD719E12491C0E8A57E7BAE1C75" KeyPath="yes" Source="!(wix.SourceClient)\lib\reset.css" />
-                    </Component>
-                    <Directory Id="dirF01A0544E0D0F36037793CCEBBCE1B0B" Name="flot">
-                        <Component Id="cmpDBD014AE3828B43403B00C725132A8A8" Guid="{8847574B-38F2-4CC6-A24A-99E95E003218}">
-                            <File Id="fil0E9EC71E0FB52A2F371881F793FFD22B" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.colorhelpers.js" />
-                        </Component>
-                        <Component Id="cmpC8C9422F944488300ECED38E3C3D34C1" Guid="{A99DF022-B527-489B-9EAD-A7A7B0DAEB57}">
-                            <File Id="fil24835A2D7B88537F17AA301E7FADE042" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.crosshair.js" />
-                        </Component>
-                        <Component Id="cmpF943BE2250F49DDF684BC013C6CB6569" Guid="{E6E1D54E-7004-4FF3-AAB8-35F8225C984F}">
-                            <File Id="fil9BB3C343C03E9957582776F77514F84C" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.fillbetween.js" />
-                        </Component>
-                        <Component Id="cmp6DF1AAE5A63AABEF6537A99FE211CA0C" Guid="{5D39701A-0080-42EC-B841-B43D1F225C8F}">
-                            <File Id="fil8F426CBCE25D52C958AFD1065D6A15F2" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.image.js" />
-                        </Component>
-                        <Component Id="cmpEA38A56F0EBF3FE9A671A194C32017C1" Guid="{F6A2B64A-B476-478C-B0AB-56B836E7F7B7}">
-                            <File Id="filB813A5F56F86064985C27A8464429C4D" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.js" />
-                        </Component>
-                        <Component Id="cmp14ED72882E41B88D5EF5D952A43C4804" Guid="{D62EB496-D91B-4E89-AD5E-A1293D1AA1A2}">
-                            <File Id="fil8CCB7D625242E9E3602180A187C4374F" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.navigate.js" />
-                        </Component>
-                        <Component Id="cmp4E0D9C2555CBECEEC98E424A8D7152AF" Guid="{C0DA9D7D-7A85-490D-BEC4-0636798287C6}">
-                            <File Id="fil01281E286A89B616404EBB9032EE50E1" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.pie.js" />
-                        </Component>
-                        <Component Id="cmp0CD21657758E9F190713A971C7035A72" Guid="{9C90E16B-1285-41ED-AB00-C3EBBA83635D}">
-                            <File Id="fil3DA6160794861FCE8DC326F7A638A384" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.resize.js" />
-                        </Component>
-                        <Component Id="cmp6A605303F9FDDF9ADC6FE9B1223985ED" Guid="{A5AAC893-67D8-4997-92BE-27BF1F147043}">
-                            <File Id="fil6E236AA7B13B57964FD5EBF21A53A6B4" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.selection.js" />
-                        </Component>
-                        <Component Id="cmpBD07E88166153AF0733F4D0D1BBAD82D" Guid="{DB198D7A-ECFD-4A80-BDB8-992394B83BBD}">
-                            <File Id="fil905D3E2020AF0DBBEFA36865285F1915" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.stack.js" />
-                        </Component>
-                        <Component Id="cmpB1A795AD8630C8AA4ACBCA057CADD8F9" Guid="{B2AB572E-3AFF-401F-BE1D-1CF7A6F0BC8C}">
-                            <File Id="fil0EB54AE2FE911CE1B49E4F99D36296F0" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.symbol.js" />
-                        </Component>
-                        <Component Id="cmp5C4C9F9823053BCD798D1613E8B706F9" Guid="{681436F8-3FD4-427E-8A2F-30D298B25669}">
-                            <File Id="fil1D4200F9E1596F4E5954DE4CA739CE3A" KeyPath="yes" Source="!(wix.SourceClient)\lib\flot\jquery.flot.threshold.js" />
-                        </Component>
-                    </Directory>
-                    <Directory Id="dir87E474B92C6D5707C56A0B5535D4E646" Name="jquery-ui">
-                        <Component Id="cmpB896F9C9402F7ED2A5A73E7E72AA47EC" Guid="{09161858-B862-4F63-BFC7-29D987F979B2}">
-                            <File Id="fil6294934093F183677F1A4AD751513E3B" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\index.html" />
-                        </Component>
-                        <Directory Id="dirC806E0BA40BBC0495FCEC8FB488812B0" Name="css">
-                            <Component Id="cmp6BEE710358ED5D0560BAEA9B4BF6830C" Guid="{B59E38D3-875C-4C3A-9F41-15C47EBF5C6B}">
-                                <File Id="filB6CF9EFD6D31DAC31A5451BB68BE7976" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\jquery-ui.css" />
-                            </Component>
-                            <Directory Id="dir40F32B62EF8F8E3765CBA3DB53D9A606" Name="images">
-                                <Component Id="cmp21F37DDAADFFEE972EF4291DE2C0E6CB" Guid="{A149C437-AD9B-40B9-A412-A2084F45E412}">
-                                    <File Id="fil68FD224A3F75BC3917D7BBF14493A630" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_flat_0_aaaaaa_40x100.png" />
-                                </Component>
-                                <Component Id="cmpE4F2B110A7EFD179E687179AE1AA86A2" Guid="{FCD6DE81-D3CE-40F2-AB20-434DEDC45BCD}">
-                                    <File Id="fil1A31F18ECF985E67CA819DC857FD25FA" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_flat_75_ffffff_40x100.png" />
-                                </Component>
-                                <Component Id="cmp818FCCB7641D478456749FAA06AE6D5C" Guid="{5104511A-8782-4EF0-B083-7FC82B07E213}">
-                                    <File Id="filFC158394112CF07E1C65BD8482D95187" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_glass_55_fbf9ee_1x400.png" />
-                                </Component>
-                                <Component Id="cmp44E96AA22DDD71CB6D2AF9F0E94D900A" Guid="{5B9702D4-0326-4ED1-90BD-6DE0D572B506}">
-                                    <File Id="filB158DA221A80AE27D2DF51185F7C9537" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_glass_65_ffffff_1x400.png" />
-                                </Component>
-                                <Component Id="cmp9F07D2C402E481C9A32B832E9767F54A" Guid="{3797F95D-F296-4278-8FEB-EF443DE4C810}">
-                                    <File Id="fil06B08BFD4F535FE76C3945549BF4A68E" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_glass_75_dadada_1x400.png" />
-                                </Component>
-                                <Component Id="cmp4F8EE7EF5CC235B975A88C5F5F7EADB1" Guid="{70337B38-CAEC-4C93-9943-B361AAA5D4A9}">
-                                    <File Id="filEC3A72A46009E27C908675849A49A348" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_glass_75_e6e6e6_1x400.png" />
-                                </Component>
-                                <Component Id="cmp0BF64BE05CC2A27F7E3AA10F198E7258" Guid="{65206B31-FC9C-4FD0-81F6-8A9F444DE240}">
-                                    <File Id="fil7278C7C5E3D8DB4F98F167E48B415041" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_highlight-hard_75_a7c1d2_1x100.png" />
-                                </Component>
-                                <Component Id="cmp097C9AEBBD0BB12A63B41A5505EABF92" Guid="{633B153D-494E-400A-95D5-6AD2013821FE}">
-                                    <File Id="filAD6FE25F6623292C5FAA1833EB693EC8" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-bg_inset-soft_95_fef1ec_1x100.png" />
-                                </Component>
-                                <Component Id="cmpF4E73A2FE6A8101861EBB6248B78CDB9" Guid="{B3F937A5-DFB3-429B-89F7-FF6E59DA6926}">
-                                    <File Id="fil56EC5C018E24F998AEB81B9F6D01019D" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-icons_222222_256x240.png" />
-                                </Component>
-                                <Component Id="cmp17CF84538B1BCD9FF96FBD0F636410B1" Guid="{69B11891-9B51-457B-BEFC-2E361D8FA5AA}">
-                                    <File Id="fil6C4C42211A7E622A380F15EF4FD8F691" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-icons_2e83ff_256x240.png" />
-                                </Component>
-                                <Component Id="cmp27075FFB9AF246A5F27D1B07E59E4807" Guid="{35C7E5C3-5EF9-44CC-958D-4E5E0E03DD68}">
-                                    <File Id="fil7DBFF6F1A5CCF82626E9D02C5E85FBE0" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-icons_454545_256x240.png" />
-                                </Component>
-                                <Component Id="cmp23B407781C5AA7099F7779F0EC9E5239" Guid="{333E199D-F898-4E7E-8F7D-2C6C6BA41EE0}">
-                                    <File Id="filB4656FAE675473310875665E6BE9A9C0" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-icons_888888_256x240.png" />
-                                </Component>
-                                <Component Id="cmpC00F3D14E656727772C11FADE4C236B2" Guid="{650C3EA7-58A2-406F-92FA-633F4D89AD1E}">
-                                    <File Id="fil267CDE35AFF0624F5FAC1FEC6C53ECE5" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\css\images\ui-icons_cd0a0a_256x240.png" />
-                                </Component>
-                            </Directory>
-                        </Directory>
-                        <Directory Id="dir8BD83F54792BF112293F68228061B997" Name="js">
-                            <Component Id="cmpA0734BF7F3979F291D1861DF998DADA5" Guid="{7D82D9A4-D927-4B70-88F3-BB727880B0B8}">
-                                <File Id="fil2785FBE05BDB131F0F6415B8F155621B" KeyPath="yes" Source="!(wix.SourceClient)\lib\jquery-ui\js\jquery-ui.js" />
-                            </Component>
-                        </Directory>
-                    </Directory>
-                    <Directory Id="dirF394956B21DCC92E4D75FA88C9B59B87" Name="qunit">
-                        <Component Id="cmp9F3BE4D0A2BC109FDC307245FD9C487F" Guid="{FA331D16-4335-44D8-B499-A39389E2EB44}">
-                            <File Id="filE1697D26A5AA4547C2368C2C88C852BE" KeyPath="yes" Source="!(wix.SourceClient)\lib\qunit\qunit.css" />
-                        </Component>
-                        <Component Id="cmpA3E293FCC7C5356BDED5B30A37517512" Guid="{377F6A3F-651A-419E-AA6C-FF600D28A30B}">
-                            <File Id="fil327720F80821C49688B39B3EB81CCC58" KeyPath="yes" Source="!(wix.SourceClient)\lib\qunit\qunit.js" />
-                        </Component>
-                    </Directory>
-                </Directory>
-                <Directory Id="dir762D57E87DBC90AF6B63D7159FF9C0CA" Name="META-INF">
-                    <Component Id="cmp1EB24C356668590C2156DA852D3E04C2" Guid="{C631CBBA-8193-4CA0-9E72-F12F32FCD458}" KeyPath="yes">
-                        <CreateFolder />
-                    </Component>
-                </Directory>
-                <Directory Id="dir9D591365751486A2602D460D3C27FCA6" Name="modules">
-                    <Component Id="cmp69189CF65055ACEF36D3DA311FA5E6B8" Guid="{23ED0618-F417-46EA-A959-1C49839CE93B}">
-                        <File Id="fil18F5976647843E048CF4D5C528AC292B" KeyPath="yes" Source="!(wix.SourceClient)\modules\modules.js" />
-                    </Component>
-                    <Directory Id="dirF7F158867ECB6F4113491C4FD8F789AA" Name="infrastructure">
-                        <Component Id="cmp25D9C3278F2FF022D355CA0E26495B38" Guid="{10F9A516-E7A5-48C9-AE16-675A67FF6618}">
-                            <File Id="filC57766DA876497BB4A8DD81DF92D9907" KeyPath="yes" Source="!(wix.SourceClient)\modules\infrastructure\infrastructure.css" />
-                        </Component>
-                        <Component Id="cmp29B4FFC9E3E81907422629F0A64A6B4D" Guid="{850DFA39-2C87-41FD-88E7-9CA381342EEB}">
-                            <File Id="fil6613DF916A41F98C4E0F384279AF168A" KeyPath="yes" Source="!(wix.SourceClient)\modules\infrastructure\infrastructure.js" />
-                        </Component>
-                    </Directory>
-                    <Directory Id="dir58F5821163C42EB5399FCA5AF4129AB4" Name="vnmcAsa1000v">
-                        <Component Id="cmpFFE7740FC808DE88252FBD1E541F28F3" Guid="{06611D4D-B90F-40C0-A9EE-25594E7EA2D2}">
-                            <File Id="fil4BC50E2DEB213EBBFA5ABD7CD2C001DA" KeyPath="yes" Source="!(wix.SourceClient)\modules\vnmcAsa1000v\vnmcAsa1000v.css" />
-                        </Component>
-                        <Component Id="cmpBEFA0A936EC6C24EF1112AE72CD61E90" Guid="{2ED5135A-1E6B-4360-9968-BBA926B0F43C}">
-                            <File Id="filBBFD17A637D9BF8CD69D4AC48A9E9FCB" KeyPath="yes" Source="!(wix.SourceClient)\modules\vnmcAsa1000v\vnmcAsa1000v.js" />
-                        </Component>
-                    </Directory>
-                    <Directory Id="dirB18A450B2C398810EFA2451EA9C0F3D5" Name="vnmcNetworkProvider">
-                        <Component Id="cmpB6FD567D23676EEA6FB33FB954C3E00F" Guid="{59E1BA68-B91A-45B9-B48F-C15EA012AE0C}">
-                            <File Id="fil16BF02751DC28FBA63EB783EEA0B6809" KeyPath="yes" Source="!(wix.SourceClient)\modules\vnmcNetworkProvider\vnmcNetworkProvider.css" />
-                        </Component>
-                        <Component Id="cmp64355DC217B30E7012C07D40333380D3" Guid="{BA9CE518-DE35-425A-9A0C-2EA4B32CC6AA}">
-                            <File Id="fil224A7E8AC59743FF9B4F9117CF817FEA" KeyPath="yes" Source="!(wix.SourceClient)\modules\vnmcNetworkProvider\vnmcNetworkProvider.js" />
-                        </Component>
-                    </Directory>
-                    <Directory Id="dirC4E2F99FED65D7A439E35208A63B7127" Name="vpc">
-                        <Component Id="cmp71B587FC4088B246C47FCD85A8E0C6D2" Guid="{040EF680-A77F-4853-AC8C-3D33FD9BD01C}">
-                            <File Id="fil13A7754DBFD38AEC2D84E7E5460E4D90" KeyPath="yes" Source="!(wix.SourceClient)\modules\vpc\vpc.css" />
-                        </Component>
-                        <Component Id="cmp91BC0E1B2F9438BC80B02A38A7F72F7A" Guid="{0786BCBD-A3B3-49BA-AE64-4585FEB52FA8}">
-                            <File Id="fil3BEBEC0B2BB83AE5C117B0F5E67650FB" KeyPath="yes" Source="!(wix.SourceClient)\modules\vpc\vpc.js" />
-                        </Component>
-                    </Directory>
-                </Directory>
-                <Directory Id="dir961854DC21D0F2B291801A55D716DDCD" Name="plugins">
-                    <Component Id="cmpFC9FD39E7A2F82765B9975065575928B" Guid="{F78B8689-677A-4440-AD16-F4FCDD33D71B}">
-                        <File Id="fil9C4C391BDE3A91B94021FF35B0B6FC89" KeyPath="yes" Source="!(wix.SourceClient)\plugins\plugins.js" />
-                    </Component>
-                    <Directory Id="dirCDC5530C1273383F2BBA2A3F6427C9E1" Name="testPlugin">
-                        <Component Id="cmp8FBD6D5AAC5F5BB99F10BA21DE8F9EE8" Guid="{DE946E21-3786-45ED-B0CD-6D67C24FA810}">
-                            <File Id="fil84FEBE7BE2F6147BB29D76F97259EAD9" KeyPath="yes" Source="!(wix.SourceClient)\plugins\testPlugin\config.js" />
-                        </Component>
-                        <Component Id="cmp1E5D206123A3BC88E972FCF814B06E05" Guid="{DF07E7FF-F031-4CDA-BF0A-9500CCDA05CB}">
-                            <File Id="filDCFC7675D7E3793F22FDAE198ED6CE48" KeyPath="yes" Source="!(wix.SourceClient)\plugins\testPlugin\icon.png" />
-                        </Component>
-                        <Component Id="cmpDFFE3D29580C2378FAB3CE1D144FD7D8" Guid="{3D62509C-FAA7-4270-9EFA-A8446FD69C73}">
-                            <File Id="fil741D744AFE58B7C43FEC1FACDBF6F0C0" KeyPath="yes" Source="!(wix.SourceClient)\plugins\testPlugin\testPlugin.css" />
-                        </Component>
-                        <Component Id="cmp82C3F50315407D120182200AB9F70C04" Guid="{C881BEF5-BA8D-429C-BC36-27FB59FE22E7}">
-                            <File Id="fil62CA99513143ABA8B0EDA54CA2B97943" KeyPath="yes" Source="!(wix.SourceClient)\plugins\testPlugin\testPlugin.js" />
-                        </Component>
-                    </Directory>
-                </Directory>
-                <Directory Id="dir942F9F1C2959BD1F497A763E4B62763A" Name="scripts">
-                    <Component Id="cmp7E0B8E6682A13E7F5222A719C3BD6DE0" Guid="{7B31FC53-10DA-4644-AC4C-E8222047366B}">
-                        <File Id="filF3A3BA2F6B6BAFBF5C329D522128D038" KeyPath="yes" Source="!(wix.SourceClient)\scripts\accounts.js" />
-                    </Component>
-                    <Component Id="cmpF8FB65C9B2E8B4CA81CF005A8308516C" Guid="{9E0DF1DB-724D-41EA-8FF6-4C66F49CE50D}">
-                        <File Id="fil93FE53F38AC33F01AD3645D04A90BCB5" KeyPath="yes" Source="!(wix.SourceClient)\scripts\accountsWizard.js" />
-                    </Component>
-                    <Component Id="cmp70B80107582ED947DEF51FB85F74D03C" Guid="{B272936E-3EC6-4997-A4BE-FDB1C3648B6A}">
-                        <File Id="filF6C33D3CABF7C29BAA05E543A66232CF" KeyPath="yes" Source="!(wix.SourceClient)\scripts\affinity.js" />
-                    </Component>
-                    <Component Id="cmpBF1674BFAE638BF0B6EB4ED6F1157FFA" Guid="{A5511B31-912D-44A6-9F4D-CE658901EFF0}">
-                        <File Id="fil6D4A15318B74C600AE63F85B66D7F6F5" KeyPath="yes" Source="!(wix.SourceClient)\scripts\autoscaler.js" />
-                    </Component>
-                    <Component Id="cmp11BE4ED125E10FA252A41F17998879B1" Guid="{1CFF521E-E633-43D0-A99C-00F2DDCCADDF}">
-                        <File Id="fil247DB8E7E0AEF0F41A89584334FC5E11" KeyPath="yes" Source="!(wix.SourceClient)\scripts\cloud.core.callbacks.js" />
-                    </Component>
-                    <Component Id="cmp3521D3A9B398D6073FBCCC5D8C0D0077" Guid="{0FE11813-A135-41C0-8481-0348C1AA0B8D}">
-                        <File Id="fil05F4B45BA329EAE603FB899847FA69CA" KeyPath="yes" Source="!(wix.SourceClient)\scripts\cloudStack.js" />
-                    </Component>
-                    <Component Id="cmpFFCFF1C360D93AF74355153604851D18" Guid="{0CE93565-3327-4B58-9666-D65E1DE798B3}">
-                        <File Id="fil955B3467E206F988B35C842DDCE607EF" KeyPath="yes" Source="!(wix.SourceClient)\scripts\configuration.js" />
-                    </Component>
-                    <Component Id="cmp70683C01637DAB3762D887EDB06168A2" Guid="{8AA9B27C-64A9-4821-B5C4-C5F29CD8FB54}">
-                        <File Id="fil0F9BB2049BBFE454C6055151FFB07BD0" KeyPath="yes" Source="!(wix.SourceClient)\scripts\dashboard.js" />
-                    </Component>
-                    <Component Id="cmpB96CE3716DAA36ADE4DAFCD51A87B4D0" Guid="{FD68901A-AF69-4421-8A9C-8283710A443D}">
-                        <File Id="filBE04AA4440980D3F5B169DE45EC57D35" KeyPath="yes" Source="!(wix.SourceClient)\scripts\docs.js" />
-                    </Component>
-                    <Component Id="cmpA2A6D7B4BA824E50D0EFD42527A7889E" Guid="{A73A5C0D-713F-4298-8D9B-5ECB61548D8E}">
-                        <File Id="filBC574EDEEDDE63C79A22653A86935D5C" KeyPath="yes" Source="!(wix.SourceClient)\scripts\domains.js" />
-                    </Component>
-                    <Component Id="cmp2A4F0744CB415C1A1E484583EF6908DD" Guid="{91D8A860-4026-4A3E-808E-ED6EDEAB1860}">
-                        <File Id="fil87700BA7601F99CBE6FF688C0C2DF4E2" KeyPath="yes" Source="!(wix.SourceClient)\scripts\events.js" />
-                    </Component>
-                    <Component Id="cmpADB85FE75F1142E56C7DD6DB7A325155" Guid="{28E74442-03B0-4D1A-A97A-BC21181DEA77}">
-                        <File Id="fil194198FBAC60FFC6A0F2D2062824A671" KeyPath="yes" Source="!(wix.SourceClient)\scripts\globalSettings.js" />
-                    </Component>
-                    <Component Id="cmp3B63120621FD8E9F4036253A7F33F516" Guid="{DF9ED9C1-7A23-481F-8DC7-23A5C2FBECB7}">
-                        <File Id="fil8F2BCCC23E531781B92D30023F124969" KeyPath="yes" Source="!(wix.SourceClient)\scripts\installWizard.js" />
-                    </Component>
-                    <Component Id="cmpE36D2A9C60AE213D91AD0E455BF4157D" Guid="{7D82E11E-FB0D-4522-9F25-5190AE40684A}">
-                        <File Id="fil7C59452A3884B81CAEBE43EDD6C51C45" KeyPath="yes" Source="!(wix.SourceClient)\scripts\instances.js" />
-                    </Component>
-                    <Component Id="cmpCCA2B5E63007166F334A93C0A3D70D2B" Guid="{DB86FE88-C374-419F-87A5-7A9AB1578BD5}">
-                        <File Id="filDE6B679405CD7AA60A8B47E69948132F" KeyPath="yes" Source="!(wix.SourceClient)\scripts\instanceWizard.js" />
-                    </Component>
-                    <Component Id="cmp97384255BE6A3A2E252A58B7E6B84244" Guid="{8F14953C-EA81-4FF4-9291-56C74467699A}">
-                        <File Id="fil3610B62BFAB29149C449ED4B1FCA3358" KeyPath="yes" Source="!(wix.SourceClient)\scripts\lbStickyPolicy.js" />
-                    </Component>
-                    <Component Id="cmp795066333B7111FD07AF5A0256019D88" Guid="{EEA16452-E378-4D3C-9F7E-3ADCD5758984}">
-                        <File Id="fil4835B3873BF28AD594051D963E593690" KeyPath="yes" Source="!(wix.SourceClient)\scripts\network.js" />
-                    </Component>
-                    <Component Id="cmp03847F93944302017867D0F358940ECF" Guid="{128E01C3-B102-458C-A3AE-9379E4D1A63A}">
-                        <File Id="fil476B0902A4B874CA099E9652C628AC1F" KeyPath="yes" Source="!(wix.SourceClient)\scripts\plugins.js" />
-                    </Component>
-                    <Component Id="cmp266156DD56681FC28B33AB3E70356D5D" Guid="{1A9A29E6-9DA6-4D55-BD62-5338F9764D86}">
-                        <File Id="fil5104048EB02D2EE1581287E510916DBA" KeyPath="yes" Source="!(wix.SourceClient)\scripts\projects.js" />
-                    </Component>
-                    <Component Id="cmp226A0ADC9F26A371E720DA01B886F58C" Guid="{AD7978B9-FAD1-4FDE-8623-28754D69E1F8}">
-                        <File Id="fil4C3F8C7522FF350EFF3369CE84D5A210" KeyPath="yes" Source="!(wix.SourceClient)\scripts\regions.js" />
-                    </Component>
-                    <Component Id="cmpF77738DC56C492684C7A2CA2164907CA" Guid="{759CA2C5-6E00-4FD0-98E8-4008F58F408F}">
-                        <File Id="fil0A737CD520D8E15635D56BBE8AA7E479" KeyPath="yes" Source="!(wix.SourceClient)\scripts\sharedFunctions.js" />
-                    </Component>
-                    <Component Id="cmp71D078D75E83971F80181453EA717D8B" Guid="{62D0AFD6-573D-4D98-BA12-3A4C6407EC57}">
-                        <File Id="filD8EB165655F5FD156F97887F104D89F2" KeyPath="yes" Source="!(wix.SourceClient)\scripts\storage.js" />
-                    </Component>
-                    <Component Id="cmpD605A23799365004C20E5DE80CA738F3" Guid="{057FD2CC-F1E8-4CA2-B6A0-0D95AAE5669F}">
-                        <File Id="filD1782F047D3CAAA2FA2B78C8641A6AE6" KeyPath="yes" Source="!(wix.SourceClient)\scripts\system.js" />
-                    </Component>
-                    <Component Id="cmpA9C076F1199B904BB57D1BC96A919814" Guid="{91870ECD-F1AA-4B69-BCEC-9536BA94A0DC}">
-                        <File Id="fil4CE0C842A4EF2E3C8322F88626C527E4" KeyPath="yes" Source="!(wix.SourceClient)\scripts\templates.js" />
-                    </Component>
-                    <Component Id="cmp429AD4BBE2ABA44D598EF5DC4482C2A4" Guid="{29B7D8A7-D7FB-46C3-8808-4EBE6D848116}">
-                        <File Id="filDFD0025C484842DE376C881CFB81DC80" KeyPath="yes" Source="!(wix.SourceClient)\scripts\vm_snapshots.js" />
-                    </Component>
-                    <Component Id="cmpA7B70148FAF23BE9246895B84B8E76EE" Guid="{06FB0332-62B7-4753-A0DA-B4906498D3A6}">
-                        <File Id="fil560BA36DCB23B6FD4BCC65D8B062DAE6" KeyPath="yes" Source="!(wix.SourceClient)\scripts\vpc.js" />
-                    </Component>
-                    <Component Id="cmpA09401C5AC6539FD960D21860A2494EA" Guid="{79496A6E-BFA8-4CFA-9CCD-DA9DEE302325}">
-                        <File Id="fil0DDF37D4B701D12F3B3C9CEF6F469284" KeyPath="yes" Source="!(wix.SourceClient)\scripts\zoneWizard.js" />
-                    </Component>
-                    <Directory Id="dirF616BA3D794A96A78E7B32F3FCD238FF" Name="ui">
-                        <Component Id="cmp4EF2024F5F084664B8B4EA6D2CFC68B7" Guid="{FC783070-3947-4012-9AD5-095585230BA5}">
-                            <File Id="fil96FB591964B69916D2B4DD8E80A796F3" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\core.js" />
-                        </Component>
-                        <Component Id="cmp61D0B06384E21EFA69C902826FD73A38" Guid="{2FDE2432-070D-49DA-8D6E-C0453394ED50}">
-                            <File Id="fil50510932A5EC9BFDF634F02031851F75" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\dialog.js" />
-                        </Component>
-                        <Component Id="cmp0829D8177E15FC4F2BA8ED14D52D90CA" Guid="{791F3613-39E6-4082-862C-12089C0C00CA}">
-                            <File Id="filF35FB4941B62DF37E291FA145D987D11" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\events.js" />
-                        </Component>
-                        <Component Id="cmpBE4BD9E19AA1B818D76F55E6388BFD8F" Guid="{ED3FD712-E4D4-4E21-9A90-6EAAF9A0AA71}">
-                            <File Id="fil3D0803AB5234747091860515F0ABD848" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\utils.js" />
-                        </Component>
-                        <Directory Id="dir1551501EE7A3D534FB4147EE456E4BAC" Name="widgets">
-                            <Component Id="cmpA4E356780616647ED7B9BFAE5A1A7117" Guid="{9432E38B-44AD-4CFA-AB5A-BFD9816C9051}">
-                                <File Id="fil8C96D7E4FECC2502244A6BFE76D0E026" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\cloudBrowser.js" />
-                            </Component>
-                            <Component Id="cmp7E9F0B69583DCA396CE7F30A896CA5E6" Guid="{206A6764-D476-4018-AD8F-CE42DAA3A93E}">
-                                <File Id="fil864E472CBF4BB577E45D8DC2B732CF51" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\dataTable.js" />
-                            </Component>
-                            <Component Id="cmp41265EE80AF4DD4A030DA0E2BBC68E25" Guid="{FC773CA1-F7BE-4238-9D9C-2808610A9695}">
-                                <File Id="fil2D0A31BA62053BA489AE2B2D2631791C" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\detailView.js" />
-                            </Component>
-                            <Component Id="cmpF767C585B98E892E3167E0B1CA2790BC" Guid="{34E52035-BFDF-453E-91B4-AC303DD2FF44}">
-                                <File Id="filC74F45FD2A37F7B8277B25AA76EE9592" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\listView.js" />
-                            </Component>
-                            <Component Id="cmp4F98C4132544C7A2EB9AF9C27B97257C" Guid="{2FAC9B5B-186E-4DAB-80A0-1E045EB70446}">
-                                <File Id="fil3D1D810471BA9EE6B3FFC8710C1394A6" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\multiEdit.js" />
-                            </Component>
-                            <Component Id="cmp7D8D9B42874FEBF3F83B13A84E11D79D" Guid="{5153E79B-B8E2-40AE-94D1-7576286785CF}">
-                                <File Id="fil6C1CD19AD917D393439D7CC93F93809B" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\notifications.js" />
-                            </Component>
-                            <Component Id="cmp01AA5255FB5F7C824120B3F35022DCD5" Guid="{8B38D253-7772-4CED-B582-09CE1121BBE1}">
-                                <File Id="fil3231069DEBE8D52BD8003DDC9B8E46CD" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\overlay.js" />
-                            </Component>
-                            <Component Id="cmpF709188CACE4EB7654441941ABD3D0A7" Guid="{5426EB01-4750-423B-A637-100FA822CD78}">
-                                <File Id="filFD16FC1048184E1790E1951C0448FDA8" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\tagger.js" />
-                            </Component>
-                            <Component Id="cmpFBDE9C88FF99E26BFAC1A5480075BB2F" Guid="{E55ADD1A-BE0F-419A-A6B3-837581428E3C}">
-                                <File Id="filC7AAA0EDA8291B2C6383B1C552B9AC3F" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\toolTip.js" />
-                            </Component>
-                            <Component Id="cmp9C3FA328BFF88944027D79762D7A8E6D" Guid="{5733FCAF-45B6-4D9A-8056-8D2EE142F9D5}">
-                                <File Id="filC63EFF968FC76DB338CC852A61360E2F" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui\widgets\treeView.js" />
-                            </Component>
-                        </Directory>
-                    </Directory>
-                    <Directory Id="dir6775A623E3333E45F2BD7BBEC9C660A6" Name="ui-custom">
-                        <Component Id="cmp94D127FCD06877FB65758B769C1DDD8C" Guid="{5303ED9D-5BC7-410D-8CDD-F8D039AAAB40}">
-                            <File Id="fil6943634DFB57313941250A3938B2AC8D" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\accountsWizard.js" />
-                        </Component>
-                        <Component Id="cmp8BAC7A532526B4BF203359AE42CDA911" Guid="{1790760E-1D62-4659-A0F7-94B803D77904}">
-                            <File Id="fil242A3CB131752040C7A0E62DCD4689DE" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\affinity.js" />
-                        </Component>
-                        <Component Id="cmpBD978DAEEFD6AB3B0CB66F1FA461D775" Guid="{AB4C47D6-74E3-4975-A5B5-52554056685C}">
-                            <File Id="filB38A1B5F71B931162270E05A77C2F932" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\autoscaler.js" />
-                        </Component>
-                        <Component Id="cmpC6F1953E0BCC28D4D367E85ADC1FF702" Guid="{ADF5E121-6FC8-4480-9EAC-83C6393666B3}">
-                            <File Id="fil1C84094CFEFAE9CB5FF7D532B24B1920" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\dashboard.js" />
-                        </Component>
-                        <Component Id="cmpC9EBCA902295AD3F9BF6AB2EB75FFF8C" Guid="{1F1E2340-6410-4913-BE2A-E02C768B0D50}">
-                            <File Id="fil07410ACA1BE6D8C5FE3065FBE783BC69" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\enableStaticNAT.js" />
-                        </Component>
-                        <Component Id="cmp45F812B0EEB2FF44A944F306FDBC57C0" Guid="{925BD4B2-6966-43B3-972D-A2114D6CB723}">
-                            <File Id="filE30B4D6194027A5E3D448EEE8F8A2222" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\granularSettings.js" />
-                        </Component>
-                        <Component Id="cmp4872730BA0FC976224C05FE06E381E31" Guid="{F60FEC0A-3F69-4CC8-94F6-2106C5717AEB}">
-                            <File Id="fil7781B6881E04D4E4693541B109817EC2" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\healthCheck.js" />
-                        </Component>
-                        <Component Id="cmp5D7EB210DC50AA3161B95938D7A0BB16" Guid="{8ED5E2A8-F9A8-4B56-81FB-1DD7F2FF4B2F}">
-                            <File Id="fil18F9B5DE36A20F9074DE05C7B91A3A9F" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\installWizard.js" />
-                        </Component>
-                        <Component Id="cmp33EABAC11FAC83EDCC1ED5640E292A0C" Guid="{F3ABAAA9-C0D9-42F2-A3BF-C61D3EC895CD}">
-                            <File Id="fil2B69E63F5E4FBEC26217D40082C75083" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\instanceWizard.js" />
-                        </Component>
-                        <Component Id="cmp4CD4F8D47D84C109495D6E245CED0FA7" Guid="{A79C70BA-78B0-49E7-8CFF-9D85C8C41CC6}">
-                            <File Id="fil792BEA5E715CE41306AD94F0FD043890" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\ipRules.js" />
-                        </Component>
-                        <Component Id="cmp766E41E0F210B801B4EE739E08E0920C" Guid="{BE81D022-B218-4765-9BED-86A00AB2F775}">
-                            <File Id="fil24E9646D60F865FF4EDFC0498E8E833D" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\login.js" />
-                        </Component>
-                        <Component Id="cmpA1EABBABC942D35B436FA9ED8E174B60" Guid="{13D77239-9128-416E-A91E-8C44E295BE15}">
-                            <File Id="filEBDA0AD46BDEBAD8994E8F26B9C557D3" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\physicalResources.js" />
-                        </Component>
-                        <Component Id="cmp46E2A160E5F1D33CED3CB9F39159115F" Guid="{102F1B1D-DB61-44F6-BA62-6C7B38F89858}">
-                            <File Id="fil630C98F2656C4EE450DD6A4C71D50F23" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\pluginListing.js" />
-                        </Component>
-                        <Component Id="cmpA7486FA646A489E4E9E0A0B30783E6E5" Guid="{DEDCFE3F-444F-450B-86BC-A766D7703ABD}">
-                            <File Id="fil2EBA3295B464A11A96005EC3B974E6F8" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\projects.js" />
-                        </Component>
-                        <Component Id="cmpCC8A03A9B688F7BB0A91B5F7264C8941" Guid="{5BB9D540-B5AB-4D07-8697-855F39946254}">
-                            <File Id="fil372E55FE278DCDA4167F10DC1152A885" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\projectSelect.js" />
-                        </Component>
-                        <Component Id="cmp7C025B152163775F85356F0B6C812D52" Guid="{8E0624E0-4AD3-4165-800F-AA7890E04D3B}">
-                            <File Id="fil4F3965E078218124130509A8DDCCF1E3" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\recurringSnapshots.js" />
-                        </Component>
-                        <Component Id="cmp25B1D1B85D37B354846A49BBFF8DB9FD" Guid="{5D53BC20-A5CE-4AFC-BAB5-EFD469CE2BAB}">
-                            <File Id="fil2A9215E93DC4D96C099BBCABF22D1C6D" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\regions.js" />
-                        </Component>
-                        <Component Id="cmp8D8319A1256FB3429270859E27C12621" Guid="{88994B43-23DE-4AE4-88C9-CEC9846E7A04}">
-                            <File Id="fil31F59B02D3D9F617A8C48137C59FAE5E" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\securityRules.js" />
-                        </Component>
-                        <Component Id="cmpE7164AA2D9D19D691D0554B6F74B1DD1" Guid="{2B674C62-D7D1-4CDF-AB31-5A6E39227452}">
-                            <File Id="fil466CC32745FE069C45D781EE62189DCE" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\uploadVolume.js" />
-                        </Component>
-                        <Component Id="cmp74950FBBDFC57288378F498E441E96A7" Guid="{4A0D2810-30A3-47C3-A436-B0CA69BA7B18}">
-                            <File Id="fil523C3B485B1575B0295A571D15FC02FB" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\vpc.js" />
-                        </Component>
-                        <Component Id="cmpB1548E0108F070E8FC0731C1D5CE1181" Guid="{746911A9-7C04-4E29-82B8-3FCC767A9D30}">
-                            <File Id="fil30EBAB57C2C710E4532A9913DD161016" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\zoneChart.js" />
-                        </Component>
-                        <Component Id="cmp55555C69B341A99ECB90776D1DAC7D85" Guid="{9A0E3988-49B6-454A-8CF0-BDCE4C83D702}">
-                            <File Id="filA5CCFBB11527304E71315E0B73FA1F56" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\zoneFilter.js" />
-                        </Component>
-                        <Component Id="cmp872A612056CDE5E1684AC32A97F88956" Guid="{8D293585-35F6-4246-A015-C6BB053A2B82}">
-                            <File Id="fil4E4778EC6FF3FDBA7442D2470E1926E1" KeyPath="yes" Source="!(wix.SourceClient)\scripts\ui-custom\zoneWizard.js" />
-                        </Component>
-                    </Directory>
-                </Directory>
-                <Directory Id="dirAD66193656240E4BE4239B39D549CFCC" Name="tests">
-                    <Component Id="cmpA037346F54E8A743265C825D1126556E" Guid="{9A7901E8-92EB-4B48-9581-B0F38D2A02C4}">
-                        <File Id="fil3488359DD7E383153B791287254D46D9" KeyPath="yes" Source="!(wix.SourceClient)\tests\index.html" />
-                    </Component>
-                    <Component Id="cmpBB0E4B6A05AD9BFB21C53A03E46EB959" Guid="{3B61FD1C-A047-4E71-875B-E3239C5A576C}">
-                        <File Id="filBD3E067F5515B184C2D38E624FD59E68" KeyPath="yes" Source="!(wix.SourceClient)\tests\test.widget.listView.js" />
-                    </Component>
-                </Directory>
-                <Directory Id="dirD48D0D22E4E6D24C65F8D95F24938B85" Name="WEB-INF">
-                    <Component Id="cmp64EF6F10E4ED683EF1866F86EA7D82B7" Guid="{4112615C-E76E-46E8-80B1-B360036C198F}">
-                        <File Id="fil8DA6BA98299368633E3E6B82DF9D73A1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\web.xml" />
-                    </Component>
-                    <Directory Id="dirD63EAC121BDEB79158776F19DC9E69EF" Name="classes">
-                        <Component Id="cmp1026E203EB573420EDAB14EF796B6C88" Guid="{32CC809E-070A-49FA-9663-C3146C896A02}">
-                            <File Id="filE62DEA6135221E4EB903B830E191B37F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\catalina.policy" />
-                        </Component>
-                        <Component Id="cmpDF564722C878E924F38CCDFA7BD81097" Guid="{F9B0FE5B-9774-4C07-A530-4FED0C8B536F}">
-                            <File Id="filBFF4F78B4AE6923FE915AB26B0FE6268" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\catalina.properties" />
-                        </Component>
-                        <Component Id="cmp6001B626D853C4E4FAB8511246B8D2B4" Guid="{DB90C42E-A2DC-4742-8BC8-49AF7556E7D1}">
-                            <File Id="fil5A0CF0340938B7ACC3B69C1353BDC625" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\classpath.conf" />
-                        </Component>
-                        <Component Id="cmp68E096BB729948107692341D8202CC5A" Guid="{0D5D3AF3-0BC0-48EE-ABA3-AF07535169BF}">
-                            <File Id="fil3E9BCB1A8CB8F8415FE3E71B65A94878" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\context.xml" />
-                        </Component>
-                        <Component Id="cmpB674D90EF1AF37E18CC8649284DEC01A" Guid="{D8769B1D-2F28-403A-80E8-601CC4D3CB17}">
-                            <File Id="filCDE656EFDF0359E9EF4C9C9423A5C609" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\db.properties" />
-                        </Component>
-                        <Component Id="cmp08271F681E20C14F2F4B84AFEEC46BAE" Guid="{6BC097E4-52DD-409A-A300-42B1695C6C4A}">
-                            <File Id="filBC2EC6E8D9A0E3F200352A16A853FAB2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\ehcache.xml" />
-                        </Component>
-                        <Component Id="cmp37A1B9AB80FBE69A9DC16D2D96BA27C1" Guid="{A1152CF2-D5DE-411E-84C3-B9A11B4F4479}">
-                            <File Id="filCBA717603C07C03578A7899AE9E7D4E5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\environment.properties" />
-                        </Component>
-                        <Component Id="cmp8417A84DFEA479A7505FFB98ED1CE09A" Guid="{8E9A8212-12A4-4436-A0F7-F431088DD2E5}">
-                            <File Id="filBFD1F1143D998C15638767462B0EDFD3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\log4j-cloud.xml" />
-                        </Component>
-                        <Component Id="cmp6FFD5CD504EEC83740F144C8E87014BF" Guid="{4A3F2F98-DEBE-4ADE-BFE4-4CE7391C26F9}">
-                            <File Id="fil240F99B080F00B70D7544E5E762B7347" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\logging.properties" />
-                        </Component>
-                        <Component Id="cmp2734DCABBEDCAEEC6365AA1B2C22DAB1" Guid="{7F612F4E-6CCF-45D5-9ED9-308C85064EB8}">
-                            <File Id="fil11F996DCBF8E4799BF6B1352754E03C9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\server-nonssl.xml" />
-                        </Component>
-                        <Component Id="cmp0102E6CEE7A7861807FB2772FC0CF208" Guid="{E1287EF3-8FCB-4533-AD4F-3D11156BF6E8}">
-                            <File Id="fil8FE51F8A16FD01851098E45044AB9F5A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\server-ssl.xml" />
-                        </Component>
-                        <Component Id="cmpD938A1152E4F900871FFBA1F13FE9EE8" Guid="{4200C177-D049-4854-B9E5-857F373198E3}">
-                            <File Id="filEF872BFA66262ABC80ECFF61A47B01CE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\tomcat-users.xml" />
-                        </Component>
-                        <Component Id="cmp1F0FDAF8DB4977D61A66753FC97B0887" Guid="{4DA3C15A-10CC-4889-A2C6-CB0B0FBDA9D4}">
-                            <File Id="fil1A4940A0D703498D56E07303E4C20739" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\tomcat6-nonssl.conf" />
-                        </Component>
-                        <Component Id="cmp7848326F517F9EE4782465AAE6BA262D" Guid="{A8A32A72-C97A-40FD-8172-EB9ED20DB0E7}">
-                            <File Id="fil1462F050D0104EF577E5B69090A4430F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\tomcat6-ssl.conf" />
-                        </Component>
-                        <Component Id="cmpEECF5D798BABA658F7C46D7F1E99E796" Guid="{57549ED0-8604-433F-A308-A59EFC042C45}">
-                            <File Id="fil134D8B8381F02982543C4CED962C4A45" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\web.xml" />
-                        </Component>
-                        <Directory Id="dir3F4D2D197FF279C14F32A7CBBAC1CBA8" Name="META-INF">
-                            <Component Id="cmpAA0B38429C92CED7D753A20E7381081E" Guid="{8A1F9CCE-D7F5-42BF-92B5-837984E6F400}">
-                                <File Id="fil410248D5C85E1B748B55271BA6CFC781" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\META-INF\DEPENDENCIES" />
-                            </Component>
-                            <Component Id="cmpC8FFCE17A77CF63EA38472FA15224A37" Guid="{8DFCCBA7-7936-4100-BDE5-2AF02E2C6F51}">
-                                <File Id="fil26AFC47C0F2A53881736E843FE1A217A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\META-INF\LICENSE" />
-                            </Component>
-                            <Component Id="cmp1FEC3E51749CAD255A2B50C1B8F56C4B" Guid="{4C763024-D0CA-46F0-A803-4981651A4ECD}">
-                                <File Id="fil73B8AAC36CCC36AF0D212A0F1F1CD26D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\META-INF\NOTICE" />
-                            </Component>
-                            <Directory Id="dirCE16A26835E64B31045E0EDFC99EA470" Name="cloudstack">
-                                <Component Id="cmp22C74DFC2BFBBA9CE414AEC0A29B43CB" Guid="{C57EEAB2-E04D-496A-910D-9969595027E1}">
-                                    <File Id="filD8983FF07FC89D9F200C24ED4F7598A9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\META-INF\cloudstack\webApplicationContext.xml" />
-                                </Component>
-                            </Directory>
-                        </Directory>
-                        <Directory Id="dirDAEE628CD9BA835F1BBFD7BC319E1D7D" Name="resources">
-                            <Component Id="cmp2C8E3B1A8BF07C9A1733044B175992D8" Guid="{43434555-3D46-4E9D-AC66-E68C5F840E5B}">
-                                <File Id="fil6502B8CC9EC07D6181FDD3C3EA54FD3C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages.properties" />
-                            </Component>
-                            <Component Id="cmpE2AAA9885C512D29CE51E1DCCFE1D960" Guid="{FC978F75-EF24-441D-A99A-AAC0D73A6455}">
-                                <File Id="fil11565AB429383A2665F3AFB8A3E87E50" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_ar.properties" />
-                            </Component>
-                            <Component Id="cmpD91640D74ABBF96CFF2EAE943B35A801" Guid="{68183071-62C8-4B7E-A2AF-15CFF24A3B77}">
-                                <File Id="fil96764B35DCE74D3B43C2121A87A283E0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_ca.properties" />
-                            </Component>
-                            <Component Id="cmpD92CE1E0C057288E3D4FBBDD7F9B311B" Guid="{22167F7E-C75B-4E2E-9D2E-D01FD3E95247}">
-                                <File Id="fil3AFC8D4669557078836F90E856F2878D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_de_DE.properties" />
-                            </Component>
-                            <Component Id="cmpB5DFC53BF25E0DDCA32F21E08BD48FA7" Guid="{A52A1E07-9133-41FE-A220-AAC010BF030E}">
-                                <File Id="fil6DA9D2E97DE472479AB206EDE98DDF99" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_es.properties" />
-                            </Component>
-                            <Component Id="cmpA6FB554ADD7936CC62279F35D5AE82F9" Guid="{6537BDA8-C17F-4A7A-8A59-28F4E16A04CB}">
-                                <File Id="fil8672E6A79A65B6FB6B4490D5034A12DD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_fr_FR.properties" />
-                            </Component>
-                            <Component Id="cmp25A1373E7443967346CAB1C05C9C0F02" Guid="{03338402-97D0-431C-8A76-19133D10B1BC}">
-                                <File Id="fil3B360B1E836B6A13800AB8E3FB3B7C8F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_it_IT.properties" />
-                            </Component>
-                            <Component Id="cmpBB3909EBF3EFC91CF550362308F8B0A3" Guid="{5F4FBAC1-9FB8-45FF-A194-6C881579EA27}">
-                                <File Id="fil73E4F5CE466E159A388449D764FCCE92" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_ja_JP.properties" />
-                            </Component>
-                            <Component Id="cmp8DCF36681B9F03A6CF94EB29C91AD069" Guid="{41B632CA-D4D7-4505-BB8F-A05DD771478C}">
-                                <File Id="filE963398446CA7B8F003D1138A75B46A6" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_ko_KR.properties" />
-                            </Component>
-                            <Component Id="cmp94EAF3A5FE002EA2A74AE138626E8633" Guid="{0ABED371-C5E7-4EDE-822A-47C45CD7FDFB}">
-                                <File Id="fil643C21737B273586FEE19A9A9D5C2ED2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_nb_NO.properties" />
-                            </Component>
-                            <Component Id="cmp4F90CF805DF53A87A67DC0281C16F2E5" Guid="{3F44FC01-0747-4325-A740-037868A669AA}">
-                                <File Id="fil3CFEA38AC587246E9F2753B328ABF614" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_nl_NL.properties" />
-                            </Component>
-                            <Component Id="cmp7615507ECFEAE51CB534D6A1CBFA868B" Guid="{1597759C-8192-4E7D-AF96-8DF3188C118E}">
-                                <File Id="fil85C2E0E9AEF8BFA4DF11691ADCC3052C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_pl.properties" />
-                            </Component>
-                            <Component Id="cmp0EE56AED71758E9A85E744690D00D1BD" Guid="{828AB0CC-37FB-449C-B294-C834DDEA84DF}">
-                                <File Id="filDFED689ADFED0713B1FEB8AD9C9CF6EA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_pt_BR.properties" />
-                            </Component>
-                            <Component Id="cmp626029CAB13CC1C121C26E705C7B17ED" Guid="{71E7102F-0B63-43D6-94E7-7109685D8CE4}">
-                                <File Id="fil85880425605B17BE5F88851A3F201DEA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_ru_RU.properties" />
-                            </Component>
-                            <Component Id="cmpF456FA18A49C014998FD56EBF6F8B3B0" Guid="{D42C3E0B-1F47-4C14-BDA6-CCDE3FC6A7C6}">
-                                <File Id="filAAC103C79C9EE23BA7D63590CE00F4C7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\resources\messages_zh_CN.properties" />
-                            </Component>
-                        </Directory>
-                        <Directory Id="dir954CA95E0C5D023138A47962D4DBD00D" Name="scripts">
-                            <Component Id="cmpBF0D3DFE02C54D8BE2529505EDF9EC71" Guid="{868FC9E3-41AB-406C-ABFE-94AF67726051}">
-                                <File Id="fil1A1E90E8E5B7BC7A5B779321490F2499" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\.pydevproject" />
-                            </Component>
-                            <Directory Id="dir5B27862E98E4FE789BFBC57B90C6FED9" Name="installer">
-                                <Component Id="cmp86CC8A3E641BF344A9FD2652BAE90E6C" Guid="{04D96B7F-2BFD-48D9-AFDE-882EEECB6FFD}">
-                                    <File Id="fil5B692723C0A1B14C97E8E264309BCDB0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\installer\createtmplt.sh" />
-                                </Component>
-                                <Component Id="cmp5995FEBCBF7410C274C54931911DB21E" Guid="{B0A8ED49-2732-48B0-8779-A81B998FB3DE}">
-                                    <File Id="fil9B8D002C2CC536B47B4D1F20870C5762" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\installer\createvolume.sh" />
-                                </Component>
-                                <Component Id="cmpA139EBC5A60DD100082C45EC6C5E33AA" Guid="{101204DC-F03D-4CBF-9425-882F4327DE93}">
-                                    <File Id="filFB581EDD93AF3A623943BC0B6521DD6F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\installer\installcentos.sh" />
-                                </Component>
-                                <Component Id="cmp4185DD7CB0F3EAFE33F882B908B6A7C6" Guid="{ACEFD21C-31C7-491D-B57C-66455CE44DE5}">
-                                    <File Id="fil2F1720D4DF025FC82EA2D271B58AA14F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\installer\installdomp.sh" />
-                                </Component>
-                                <Component Id="cmp661E05AA1427CD13FF5127B2411B1669" Guid="{E3E25570-9D60-4AC8-BB36-86929899BF9A}">
-                                    <File Id="fil72BC2A63FD54F95C1A4865B06CDFEAFD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\installer\run_installer.sh" />
-                                </Component>
-                            </Directory>
-                            <Directory Id="dir518116C981565ACEE07CDD47CFB0D506" Name="network">
-                                <Directory Id="dir716CD1A36DC8088D7B98C63E1C9A15A1" Name="domr">
-                                    <Component Id="cmp7AB4F4DF89552A306F27E9E2F6A623DA" Guid="{2FAC9741-B587-4909-9F1D-2FB663F39D72}">
-                                        <File Id="fil7746B2A1ECFEC67B8F4BE34C4D86644A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\domr\router_proxy.sh" />
-                                    </Component>
-                                </Directory>
-                                <Directory Id="dirC9AB0B58FD8D709B4EB39E79C3DCA1C7" Name="exdhcp">
-                                    <Component Id="cmp1EA67FB49D6BECF6D1B44AB95F04DA5E" Guid="{CA9F4407-67FA-4E18-A633-A035FEDFC3FB}">
-                                        <File Id="fil64500B3EDE1784E031E982FAF4C327BD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\exdhcp\dhcpd_edithosts.py" />
-                                    </Component>
-                                    <Component Id="cmp781BDE48CDBCAE15768480F6F3A052DD" Guid="{D019120A-15E0-45A2-B455-80EAA9E076F1}">
-                                        <File Id="fil75E2A6CE26175CD7C25FAFF6B611EDA0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\exdhcp\dnsmasq_edithosts.sh" />
-                                    </Component>
-                                    <Component Id="cmp385E7781A2840DFBE2DA808615781039" Guid="{F172F995-7188-4EEC-924E-12A0ED12C14C}">
-                                        <File Id="fil886E7C858635C45EBBB9424FE88B5588" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\exdhcp\prepare_dhcpd.sh" />
-                                    </Component>
-                                    <Component Id="cmp9F1B2E8E0DB49F6B9518F4E68E7AC536" Guid="{1E92721A-1163-44A4-8850-EBF001976D82}">
-                                        <File Id="fil609AC8071F847DAA7CAD27F98E0A45C9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\exdhcp\prepare_dnsmasq.sh" />
-                                    </Component>
-                                </Directory>
-                                <Directory Id="dir4512120D3D7F31C313A88394D6E42412" Name="juniper">
-                                    <Component Id="cmp86C96A310F5BB26224B9FF68E053FA0F" Guid="{892ACA96-039B-4C56-B95A-978F3BECB835}">
-                                        <File Id="filDB5E19C85BFCF5B8F30B6DD2DE5DEA29" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\access-profile-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp7676B223C5A4A714E64524264EFFCC54" Guid="{6913B79F-A3F1-411F-8308-29A315A5315B}">
-                                        <File Id="filBC5179EF0D25982D0922239748012BCB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\access-profile-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp52DD60836D83636B4A780DF958F4E61D" Guid="{DBF2D26E-67BB-471E-A3D6-72D1DBB3943D}">
-                                        <File Id="fil4E3796803441D25D4B3DC07131781B9F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\access-profile-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp75597DD51EDC3F51DD5BBB02DD892AC2" Guid="{829DF955-FFC3-4EB4-8C8E-31197CAA65EB}">
-                                        <File Id="fil2F4178F2C5447EEE316907DB5BB4C75B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-book-entry-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpB4720BB9D6705E3D69C6BD1D1FC3E174" Guid="{5030D95C-7EAB-47E9-8149-12A588E7C1AE}">
-                                        <File Id="fil1379138E4A6ED68C519A103F03F5FC83" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-book-entry-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmpCD89301875081054F8C330898519FA7F" Guid="{7EDADC92-0575-4603-8EAE-B7BCB58F43DB}">
-                                        <File Id="fil1F5CCE919E5908197392363D98DA68A1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-book-entry-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp51E672062A347FBE0CB4E8E038AC0D91" Guid="{FA81A504-3699-4187-95EE-32AF4F0FE52B}">
-                                        <File Id="filABD75DB0A2AA0E004EE90DD2E6A4B348" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-pool-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpF8CD8A5BD93BC295BEEEB21BA8EB1846" Guid="{7ADDCF2E-5479-4928-B1F8-2D8E8E986823}">
-                                        <File Id="fil357F0BA0664A5ACDAD96DEB70F94787E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-pool-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp9EC328DCB72D670222F1005E3C108F7B" Guid="{6D1EF371-0EE1-4B5A-B666-B7B9EB93A777}">
-                                        <File Id="filFF0018393C93D432CAA1F9E4AF8A1F0B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\address-pool-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp7DAC596A0CC08D2EFB08695136B0CA17" Guid="{0ECE7417-AF00-47EE-92B4-6223175A0FD9}">
-                                        <File Id="filF89A45BF6E50A67CA9F96514383F4E75" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\application-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp7D17AF015D71B244D376C5F759A9DBD3" Guid="{ABF779A2-A545-4DE9-AE54-2E095459ADD8}">
-                                        <File Id="fil98E350928C409E03D301866DBA0598DC" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\application-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp150A9E66626147512C3DD44E6BE1B1B2" Guid="{4E67A401-01AF-46AD-A9BA-464B76D83D0D}">
-                                        <File Id="fil5471FF706D39F16501F505E598C05862" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\close-configuration.xml" />
-                                    </Component>
-                                    <Component Id="cmp265762AC45A7253A1ACEEEA579E7F79F" Guid="{04CCB0FF-C789-424C-85BC-6ED66A883EA4}">
-                                        <File Id="filD28B56ACC6399926FFF8625BA1BD23F5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\commit.xml" />
-                                    </Component>
-                                    <Component Id="cmp863F4B86882A6C70C2CA5C1C82FCCE79" Guid="{A06281AE-155D-4F48-923C-F61370B87CD7}">
-                                        <File Id="fil20B10EF902F94867226A8B6FB21F9156" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-pool-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp551510470E26572504B92DDD7F677066" Guid="{58D69193-415D-4FDF-AD0F-D22625610D33}">
-                                        <File Id="filDA23AE2DB192BE810632069456B92075" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-pool-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp728004CA9FF6F036824C0BFE3BBEC8BE" Guid="{81D88629-AB22-453E-B80A-D391EB04ADB6}">
-                                        <File Id="filF275503FC79C7A84613E342E0D1ABAC1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-pool-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpA8ACF36F591B0F2596F1DFF01519DDFA" Guid="{D282774E-B232-41F3-8138-3DBB93B2F0FC}">
-                                        <File Id="filF9E03069DC126D0B7DE984300A7F8E76" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-rule-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpC0E4B295A2909130A9AF1F766FA3D866" Guid="{09739245-15F7-4FEF-A2D9-76791445ABC9}">
-                                        <File Id="fil4AB70477DC0373351011105662087FE4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-rule-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp0CF0C5C354A1DADE5E4047BD3E0A71DC" Guid="{FB3052D4-95BF-454C-A5F6-5C6FD876C716}">
-                                        <File Id="filD7A814AEFEFB1C1EC80F90789C5BFFA4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dest-nat-rule-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpAB53A03E2D7C14D4C50D61B5472FCDD6" Guid="{BD091DF8-5859-42A3-A85F-99E3C3DDFBEB}">
-                                        <File Id="filA9FB663C90EFD3C0F1E20533852AB225" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dynamic-vpn-client-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpC110054F558236FC9DE910652CAF19D9" Guid="{6C8D2689-4CB2-42F2-8207-EE06D3832B40}">
-                                        <File Id="filDAA6FC9EA4E87F8AA7E3845F3740D547" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dynamic-vpn-client-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp2663CC5C0CFEF4FF5B1F14EDB4527497" Guid="{82BDBDFA-B9E2-4B31-BBB5-41F7AA597A68}">
-                                        <File Id="filBBFFAABFBBBCBC3141906039EBDE514D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\dynamic-vpn-client-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp9A0276A01FC113C46507093C80D18649" Guid="{32DCE2C1-9EDE-4F53-865C-3DCE3937F469}">
-                                        <File Id="filB652171FC37B3E0F27DCC92B830A2D13" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\filter-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpF254AD87553784310D3D1FE0254614D3" Guid="{38C7486F-85F0-4EF4-9CDE-C07C16204429}">
-                                        <File Id="fil0DFCD0D7CAA434AB10A8F1246543BBF1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\filter-term-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpCE0C7763E8FCEC1220DFCD9E7BB78BCA" Guid="{F28DC7BB-84DC-4545-8ED7-C7E83531DF7E}">
-                                        <File Id="filE02737342CB83454FDD577B8CEA54FDF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\firewall-filter-bytes-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp53CC12797765365E92F73C83ED3D66A2" Guid="{59AA427C-C610-46D3-AE51-A50917C8AB52}">
-                                        <File Id="fil55FA9C528BE274799B3F0E0933D9686C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\firewall-filter-term-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpE055BA8E22750F279015AE949E9077D2" Guid="{3E970150-21CE-483E-B60F-9CD6A6C6E74F}">
-                                        <File Id="filF722CF88FA061894A3FA479B850B6FD5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\firewall-filter-term-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp1D9ED093258286A51677A8823874D81C" Guid="{EE99995D-ECB6-498A-B02E-7F36679B1F82}">
-                                        <File Id="fil4C9AA732283E52D34F8CB406E89DBB0D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\guest-vlan-filter-term-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp932BB7F2D2329C603E4A293676DC569F" Guid="{14FEA932-2442-42A1-82C1-AE5EF23FEAA6}">
-                                        <File Id="fil28EB10E361E200B1A4BECCABDBBF3D82" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-gateway-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp443A9BE389EAC35F776D4AEEC557E7B7" Guid="{6E840DFA-1304-427C-A2C9-3D8C2B3C6551}">
-                                        <File Id="fil77782ABA3ADF5DA0AA4200241C0B0ECC" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-gateway-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmpEB682C2498A83E15460CF3C9A995CFF7" Guid="{9DA898C8-2095-4B1D-AD3F-F7C8D5E40942}">
-                                        <File Id="filE1F528DA3445D095864F5695464BFA62" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-gateway-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp04EC8B1D825B58AA3DA19D924DF8B0B1" Guid="{8B6C78CE-4CED-4162-8120-143142B0F4A5}">
-                                        <File Id="fil6050FBB74E15C503A38C115246140A04" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-policy-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp0F769871ACD853090B5B989D8C137FA7" Guid="{A4F75DBA-D0EC-4F34-AF1C-100D653AF509}">
-                                        <File Id="fil1BF0BE2FA69BFF2BC8D6F438FBD87F80" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-policy-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp291ACA145B7F38DEF0A689817B1848CA" Guid="{C1CE1A3C-07BB-4112-8180-CF84ADF8E278}">
-                                        <File Id="fil444A3792F9A8D1692CD7E8329EC54536" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ike-policy-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp1EA8603BCB8C9F4A002397620B097AA6" Guid="{7248E361-B6A4-4FF1-A8BB-56BAC0DEBE39}">
-                                        <File Id="filCD847C8B8CBAB51CF97EF6488B2966A3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ipsec-vpn-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpD2FE1296E8E0A96EEB2DC75B8F621BA5" Guid="{E47CBA27-8C43-487B-8A71-8824DC9E0269}">
-                                        <File Id="fil580A9D4BD3A30F3CC92B1EA25B813500" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ipsec-vpn-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp98613EE9D27378DB161FB3E84C3348CE" Guid="{DCDF8E87-64B1-4B4C-94C9-DBAEDA52F5C8}">
-                                        <File Id="filC1E7D6321196E5243F09DB09C7F61D05" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\ipsec-vpn-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp6249A00626F75A73A6D54FABB28A8CD0" Guid="{011DBF21-ECAD-45F1-91D0-F3AAF19B509D}">
-                                        <File Id="fil664DF91606B5F3BB279D4759F945202A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\login.xml" />
-                                    </Component>
-                                    <Component Id="cmp723663731EC89E3C5851B5D091C2239F" Guid="{F4BEC9C6-1368-4E93-90C4-119A8E0309E6}">
-                                        <File Id="filA83DA53E50563BB3BC2A89F58FB07D47" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\open-configuration.xml" />
-                                    </Component>
-                                    <Component Id="cmpD2C66446234ADE594038CB5F6A0332FB" Guid="{C056CBD9-DDEF-4848-B844-3EE76442BE2E}">
-                                        <File Id="filB2BE842DF961841C627A9E1EA0828284" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\private-interface-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp8129E3CD6B43C9D748EF59093D50B0AD" Guid="{12837AEA-29EE-449B-A28A-83CE97911480}">
-                                        <File Id="fil96DF7EF51CAC17A7FA0B0C648AD0CB27" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\private-interface-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmpC78528D03802A5D0D1CE3984766C93D1" Guid="{E7E5207F-0E16-4B6B-B080-5E5AA355E7C1}">
-                                        <File Id="filFFA0C7CE49C1EA7CCD66EAD723CB99B0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\private-interface-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp2CC080FB390828F4F14FE06EDC89C5D5" Guid="{46D8FC3C-D40A-46D6-A079-AE50EB5ED9D6}">
-                                        <File Id="fil84C608488619D253E6BDF1BB8B971854" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\private-interface-with-filters-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp38C9BC62FD46E6B5E414E59677DE9357" Guid="{34B8AF79-4EAD-4C50-B69C-E9B35D1F0E4E}">
-                                        <File Id="filB1D0C6D2470E4CC1B071E58585716646" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\proxy-arp-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp6092AEA43E0169389D0505FFA98BF45F" Guid="{1070B788-A62F-4DE4-B180-9BB7BD201615}">
-                                        <File Id="fil1625BAF4BF5D83203E33764A188556F8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\proxy-arp-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp3D44B5797FFF1AB131750A6A5430B320" Guid="{D88ABAAB-DAE7-4060-BE97-099FEF6C77CC}">
-                                        <File Id="filB6EC848D0B29938CF206CFD6D58FF69A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\proxy-arp-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpA2805661D83E6A7F849EFA5E4F37B375" Guid="{BE22ADD9-2255-4460-94A2-68319937500B}">
-                                        <File Id="fil984A760A931AC100D98334085443068C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\public-ip-filter-term-add.xml" />
-                                    </Component>
-                                    <Component Id="cmpEB01C09EE469649460A335BB86939541" Guid="{20CD6345-BBF6-4708-9F11-CE7282DDDF20}">
-                                        <File Id="fil3AC61392C19CBB2FCA32C6DC7F6DDB51" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\rollback.xml" />
-                                    </Component>
-                                    <Component Id="cmp72EC1854B1EEF4661811D651729134DF" Guid="{5D5CE451-8840-4419-9000-DC2D87DAF2A0}">
-                                        <File Id="filC0E60E8B917EED912EE53E0C8A32AB5C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\security-policy-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp76075E5103CAB91D47E004805399916F" Guid="{DBC9B789-DB81-4B4F-A254-F42B2838A143}">
-                                        <File Id="filF9A01113A480805438B1996B3ED635C2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\security-policy-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp1DEC87C5FB6BFCE2AFC70C4A574FE9BE" Guid="{E8E541D5-5322-422E-B9AD-A81E73AAF280}">
-                                        <File Id="fil5422D442688D236AB522AAFA38936DBD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\security-policy-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp8079956D2D7C2017A7871E6EA3020051" Guid="{7B8AED5F-E568-4A49-B738-1D90AA7F79F8}">
-                                        <File Id="fil43A9F0126DB125887F52F6922D2EF187" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\security-policy-group.xml" />
-                                    </Component>
-                                    <Component Id="cmp4B7D72C6B15D0AF2F449A7891A3AC557" Guid="{FE8D35AB-0478-46C7-957E-FD11EE6E1B17}">
-                                        <File Id="filE3A2EADC6089F63282773D3121568794" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\security-policy-rename.xml" />
-                                    </Component>
-                                    <Component Id="cmpFC9EFE272FFDE9600E5148EBBE0110A4" Guid="{C4FCD543-9B28-491F-95D9-05A7C0104632}">
-                                        <File Id="filC4F7B8BA7B6F8AA17236F53C3F62115F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\src-nat-pool-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp7E8098EC6140D1BF019E408363BFFB6C" Guid="{7DA821BE-DE47-4071-9E31-7B96C953C86F}">
-                                        <File Id="fil513058FC0FBE091C1D274D56899BD6ED" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\src-nat-pool-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmpB16694DE02D00ED33D05319AE9B700A2" Guid="{1C4E3E12-E1B0-4FD4-8591-2D23D25FCA4B}">
-                                        <File Id="filEF4C8CB08B187B470E39A451F34F1DED" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\src-nat-rule-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp385055226F2FECF976369FC5ECD5C606" Guid="{975E0F31-9E43-4D5E-A2BF-1E37403D9970}">
-                                        <File Id="filA0ACD116964CC67A51095A2BF9E12BB9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\src-nat-rule-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp4BF28C7182312F272879E70E5E599B35" Guid="{6A11E558-1F8D-4D81-99C7-8BA65760141F}">
-                                        <File Id="filF05BDB172B61C5F1B9324BF23D1425E3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\src-nat-rule-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp40139DE7335CE84CAE8DF50DEE707E0D" Guid="{5DAF8AC5-42C5-4845-B76E-4ED2661D8985}">
-                                        <File Id="filE9D4A32FA9FB350079A795A61B54768A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\static-nat-rule-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp15E56EA78F7945EE73F6F016FC15B74A" Guid="{D1F6B2F1-FFCE-4C0F-9641-967812D36A0D}">
-                                        <File Id="filDF8CF3D20C5AC5BF2D277A64FFD86541" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\static-nat-rule-getall.xml" />
-                                    </Component>
-                                    <Component Id="cmp2C3B23CA2FB10A6A7B890498C9679056" Guid="{C5C3352E-078B-46D7-AFA7-E46C2325F37D}">
-                                        <File Id="filDCE21069DC38E31DC825B93FE31069A9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\static-nat-rule-getone.xml" />
-                                    </Component>
-                                    <Component Id="cmp1C47388B269EB7389524664338D6B228" Guid="{FD0967D1-1213-48DD-95DF-D606C70C5FA3}">
-                                        <File Id="fil916A81AABA6698E52728208E874A10B2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\template-entry.xml" />
-                                    </Component>
-                                    <Component Id="cmpAD947E66C4B72B649DE506CDBB8C1138" Guid="{3758D2B5-EDD4-40D1-A0BD-4F29234845A5}">
-                                        <File Id="fil971F729EF0B3D3A7765ADC3FFFAE76B2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\test.xml" />
-                                    </Component>
-                                    <Component Id="cmpF5D0A2EFB2960C77F65D2CDF2485009C" Guid="{3E9D1475-8322-4DE0-8FCA-7EAF597F5357}">
-                                        <File Id="filD8282BC06EE3A913FD4AF8165EFDC635" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\zone-interface-add.xml" />
-                                    </Component>
-                                    <Component Id="cmp94CB9A1030C9F813F80899B411D3C92B" Guid="{7FA8DCC5-7DA4-4ECC-A607-6FF611E645DB}">
-                                        <File Id="fil90BFB08406144531163911FFC878E01A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\juniper\zone-interface-getone.xml" />
-                                    </Component>
-                                </Directory>
-                                <Directory Id="dirF8A51FB50EA417579DABACDDF721B5BE" Name="ping">
-                                    <Component Id="cmpCAA8C186128C2BA0F14BD8ED233CCAAF" Guid="{C22BCC65-3099-4360-87E6-D2602BAFB2E6}">
-                                        <File Id="fil177A6DFC0997A7436428D975D32020E7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\ping\baremetal_user_data.py" />
-                                    </Component>
-                                    <Component Id="cmp575C261AE2D71C7F8792EB08F136CB7B" Guid="{9079C658-29AE-4B18-9DAD-3EEC8FF40FC6}">
-                                        <File Id="fil05EB2B779C9506E5CAA5A6D790D066F2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\ping\prepare_kickstart_bootfile.py" />
-                                    </Component>
-                                    <Component Id="cmp126992229DE0964A4988DE11FD02AAB1" Guid="{349F1DA8-D230-4678-8FB2-094ADF011FD0}">
-                                        <File Id="filEA711B5BD7565D1CE976AEA150CBE070" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\ping\prepare_kickstart_kernel_initrd.py" />
-                                    </Component>
-                                    <Component Id="cmp6F04A8F4C9403FA24E6A4BE3EDB95BD5" Guid="{9B5B8387-BF91-4D05-AADE-653EFB61919A}">
-                                        <File Id="filC6844B3CFB7DB9C10EEDA1C3EE46859D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\network\ping\prepare_tftp_bootfile.py" />
-                                    </Component>
-                                </Directory>
-                            </Directory>
-                            <Directory Id="dir14171EDE91DE54219E7E72EDE11D7638" Name="storage">
-                                <Component Id="cmp52A47332C80A12129C3CE3E6BEB96DB1" Guid="{08029E02-9BBC-4D10-A068-DE652BD06A62}">
-                                    <File Id="fil09BDAAD24B306234AFC83173909EBB0E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\checkchildren.sh" />
-                                </Component>
-                                <Component Id="cmpC9298B99BC59BA72C93EE04C7E2711B0" Guid="{EA6E852A-16C3-4FA3-9645-142F28877D0F}">
-                                    <File Id="filCEAD06AB1CF44B2FAAB8CFE2AF9D1521" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\installIso.sh" />
-                                </Component>
-                                <Directory Id="dir267FF7CF84C99143BF527628A71E34FB" Name="qcow2">
-                                    <Component Id="cmp9DD0FEC415646B339C592E126D2954D9" Guid="{ABFCC68E-7B12-44E4-8526-A77D4BDE02FA}">
-                                        <File Id="filFE7CDD1EAEAB9EF8465629CA2A4C5E61" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\createtmplt.sh" />
-                                    </Component>
-                                    <Component Id="cmpA33449985BC8453ACF98BF0B72FAF81F" Guid="{7FF154DA-B88F-44FA-BB1B-D5E06598621D}">
-                                        <File Id="fil982000BEAC2FB97B546E2ADF0D698FBF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\createvm.sh" />
-                                    </Component>
-                                    <Component Id="cmpCFE382F379DFFC0DF14109C0BFAF672B" Guid="{F1C9EA5F-1609-4E97-8FAB-6265F5990155}">
-                                        <File Id="filB35AB12B35D27F094BC9DB70C151A734" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\createvolume.sh" />
-                                    </Component>
-                                    <Component Id="cmp839015607706F63D9ED0C70CE10C7359" Guid="{B31D0871-A743-4072-A793-123C43C67285}">
-                                        <File Id="fil1314FE81C65A335F74D65E80468B7C6F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\create_private_template.sh" />
-                                    </Component>
-                                    <Component Id="cmp86150C85856E18065298248A7F309691" Guid="{49E3AB27-3F75-4888-A8F7-547B9B8B30EC}">
-                                        <File Id="fil2E637147522F97F8CEE8F230A5845C70" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\delvm.sh" />
-                                    </Component>
-                                    <Component Id="cmp38059A7D3BE2B614C58838F80922BA67" Guid="{4FFE4635-1E76-4F72-B00F-F1B558437882}">
-                                        <File Id="fil49063DDC41A3A3EFC7CCB40BBE7DD5E6" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\get_domr_kernel.sh" />
-                                    </Component>
-                                    <Component Id="cmp2F26DF2FF57CA8FA951F8EEC3E96E561" Guid="{169FF04E-6649-4724-B940-C4A90FFEB4DC}">
-                                        <File Id="fil184B91C2F3FD83B0ACCF7EC3DA8020D7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\get_iqn.sh" />
-                                    </Component>
-                                    <Component Id="cmp2A138F5AB1828039CAC4C4B46AB0465B" Guid="{1FB97FD7-8AF3-4700-B921-A9A2B3FB1EFF}">
-                                        <File Id="fil3C6B6D8D1F75646F76A278A7EFA41E11" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\importmpl.sh" />
-                                    </Component>
-                                    <Component Id="cmpFDB625A2C53F9EDA18453B064B1105F0" Guid="{F49B1831-93A9-441E-BBC0-26FE2F1EF264}">
-                                        <File Id="filC9C5B8B84B912C4A95B1375B15968DC8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\listvmdisk.sh" />
-                                    </Component>
-                                    <Component Id="cmpD7D383DDE9EBC2AB530686E3A7012478" Guid="{EE420CA9-2A3E-4A97-A124-11B010D614C3}">
-                                        <File Id="filC05E8514EE34A3ECFC177BAA23E6CBD5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\listvmdisksize.sh" />
-                                    </Component>
-                                    <Component Id="cmp90AEE5FA3A9E9C6650D9466EC58FA8A2" Guid="{999F79E9-3321-4C32-B26B-DDE455A5BAFB}">
-                                        <File Id="fil449FACC277BAD0466E24D4C76D67A74A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\listvmtmplt.sh" />
-                                    </Component>
-                                    <Component Id="cmpE7DCF0421AE9B244DC5E0F4C2323DE0B" Guid="{1443E3CC-FBAF-4AAF-8589-F69CB70F1D28}">
-                                        <File Id="filA7702FAF91323856A7AF6D5B8C88EE46" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\listvolume.sh" />
-                                    </Component>
-                                    <Component Id="cmp228F4AF01D3334E5200DE7F251A11FF4" Guid="{89FCAB71-0331-45AD-9FFD-F3BFFF47B01B}">
-                                        <File Id="filD632A2BFBF84FAC60CDBD03B35B9C2F0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\managesnapshot.sh" />
-                                    </Component>
-                                    <Component Id="cmp111F3D7FF73098BD75585376B387F296" Guid="{5F6DD210-D6CB-48E9-B4DF-807C2ED083FD}">
-                                        <File Id="fil9418DD76A00EB56377E7C6E914B0DB39" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\managevolume.sh" />
-                                    </Component>
-                                    <Component Id="cmp7E5C1A2BE845C2CA497F4995A2B8765B" Guid="{1A1865F6-D94E-4AB1-ADFC-C2A3FC0530EA}">
-                                        <File Id="fil1F3A651D6CC34D1BEF89C5EAFC61AE6B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\qcow2\resizevolume.sh" />
-                                    </Component>
-                                </Directory>
-                                <Directory Id="dir05757E2FB24172C0B369EC73470D5322" Name="secondary">
-                                    <Component Id="cmp44D2900C842E2F59FE30E3EB110B24AB" Guid="{F77DB34E-2933-4500-AED3-E6C6480D95E3}">
-                                        <File Id="fil29734A2735AFAABA75DCF54858105B98" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\cloud-install-sys-tmplt" />
-                                    </Component>
-                                    <Component Id="cmpFB9874B5CCB35A38FF21EECFF77A6CC3" Guid="{08831BA7-81A7-4F9D-92DD-FFBA68F2C254}">
-                                        <File Id="fil15AF16CC954EEE5DD7202CD2646B6473" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\createtmplt.sh" />
-                                    </Component>
-                                    <Component Id="cmp01C20BCCA4155D0D9E3B11B514950F83" Guid="{59D1D4AE-88C9-4418-94D6-CB2686D3B32B}">
-                                        <File Id="fil30603CA07002A597CFEF242F0AED183E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\createvolume.sh" />
-                                    </Component>
-                                    <Component Id="cmp8608349CDFD3459A383ED21E3BAE05FE" Guid="{8844004F-85C3-4E05-9461-71FE6E22F0CB}">
-                                        <File Id="fil17A01C9703ECAB9046FDE87E42EEFFA0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\create_privatetemplate_from_snapshot_xen.sh" />
-                                    </Component>
-                                    <Component Id="cmp29E0935C29850733C91824907E6EB7DC" Guid="{E775C47F-A2BA-4FC5-BC2E-C87225379004}">
-                                        <File Id="fil225038A2C5D82D0AEAD8713D4289794A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\installIso.sh" />
-                                    </Component>
-                                    <Component Id="cmpC36A915BD2AC10F337335A4810E75F2E" Guid="{7F9D0145-BA93-4455-9EA0-57BBFBC7F833}">
-                                        <File Id="filE0940BC4B16C19774C3336839BEC8CC9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\listvmtmplt.sh" />
-                                    </Component>
-                                    <Component Id="cmp515AF9D2852DEF323BF42B3D5766C576" Guid="{A4BB79D7-A92E-4EF7-A564-D596AAE28687}">
-                                        <File Id="fil53209751E1C61436AD2DE0A78A3F6B0F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\listvolume.sh" />
-                                    </Component>
-                                    <Component Id="cmp839A7CD1E5B37EC65E5DB75586BEA481" Guid="{CA7B04C6-9F90-494D-AC6E-85344B78FD97}">
-                                        <File Id="fil15276DE9B6A5A74C328B0D0A380BB4B1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\storage\secondary\swift" />
-                                    </Component>
-                                </Directory>
-                            </Directory>
-                            <Directory Id="dir302814EA4C104E95B3E08F54A0D53708" Name="util">
-                                <Component Id="cmp7CF5D412B2F44AD4AEAC7F9CA8BA595B" Guid="{8A95E316-B7EF-4971-8936-154E9522C25D}">
-                                    <File Id="filE9E535A1F23D83A0A7126C9438900B8C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\util\ipmi.py" />
-                                </Component>
-                                <Component Id="cmpA6286623CABD7E5F3A09589B44420746" Guid="{1A38F4A9-2169-4912-9064-82BDAEA2B281}">
-                                    <File Id="filEFFB3DFF57591093159409B7C979D46A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\util\macgen.py" />
-                                </Component>
-                                <Component Id="cmp227D8389040309820B730D258C474CA3" Guid="{030E573B-5158-4E2A-8FE6-9D0B188BDDBA}">
-                                    <File Id="fil826CC845CDB7D3BE8973821DE391F716" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\util\prepare_linmin.sh" />
-                                </Component>
-                                <Component Id="cmpC6C52B6306740C3CA2C37DFFF54FC7AA" Guid="{4321BFE5-C229-424E-BAAA-7AECC0F645F2}">
-                                    <File Id="fil6C6F4A2108BF643BA4330EAA52131F3D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\util\qemu-ifup" />
-                                </Component>
-                            </Directory>
-                            <Directory Id="dir1E26EBCC5137F468F4E5B08868BAC7F6" Name="vm">
-                                <Component Id="cmp1D94BCC20C966E5B40B535336C7D0877" Guid="{CAC775A2-BF91-444D-A5FB-75A965607F81}">
-                                    <File Id="filF8000B96AB819826F796DC75772B904C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\pingtest.sh" />
-                                </Component>
-                                <Directory Id="dir0D8D02815AD516F45F52BABD16FA0573" Name="hypervisor">
-                                    <Component Id="cmp1C463804A269A19B2F7FE9A8CF5B0C9A" Guid="{A3F46BF9-21AF-4F91-B973-69E1901D4AC9}">
-                                        <File Id="fil7F057A931C30E41123500822CC621147" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\versions.sh" />
-                                    </Component>
-                                    <Directory Id="dir8383AC7DE08F85DE0711D3FD71B1B661" Name="kvm">
-                                        <Component Id="cmp1967756DB056E9B0C5782282DE9F7DE4" Guid="{71E999D7-ED97-438A-947E-D019B98191C4}">
-                                            <File Id="fil47212822DDAFFCD71C79615CF4583BAF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\kvm\kvmheartbeat.sh" />
-                                        </Component>
-                                        <Component Id="cmpF2BBDD336FEC0B34B3C744ACF1E4B959" Guid="{56D8ECF7-49F8-4B26-A8F4-662252C0A647}">
-                                            <File Id="filD809C7F728AC5D1BD36E7DB403BFA141" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\kvm\patch.sh" />
-                                        </Component>
-                                        <Component Id="cmp2F4D4D81563D153E86B0A652A83D363A" Guid="{7BFC7637-E33D-4BC4-8B25-3CDEA601110C}">
-                                            <File Id="fil349420D6088A01C9F63E27634623F5BE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\kvm\setup_agent.sh" />
-                                        </Component>
-                                    </Directory>
-                                    <Directory Id="dirA103BCD5DDFD4F34E31B890F426FBE99" Name="xenserver">
-                                        <Component Id="cmp4F0AE38CA01E7A86BE72E3EC71DB3C46" Guid="{361F19BB-EAF5-457B-8776-3DDA1B8780AB}">
-                                            <File Id="fil76ECCE3FFADD95F69FA893362A15987C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\add_to_vcpus_params_live.sh" />
-                                        </Component>
-                                        <Component Id="cmpE4CC8D388C3636F073E7EA031EEE0AC5" Guid="{4D9F2FF4-F5DA-4F4A-B517-84E64FBBD3D1}">
-                                            <File Id="fil1F001800059D60631FB106CCE0431972" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\check_heartbeat.sh" />
-                                        </Component>
-                                        <Component Id="cmp5F9E0C0DFC726F36C6FDE9B90080554E" Guid="{FD1A034A-19D8-4815-91B9-4A179AC4FB60}">
-                                            <File Id="fil34401FA616C0273A47E691686E3C4440" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloud-clean-vlan.sh" />
-                                        </Component>
-                                        <Component Id="cmpDAB537B8A2E977B5A32103CEEC88CD64" Guid="{C3659DDF-8EE9-4F44-BAAD-F6D42ED5D12E}">
-                                            <File Id="filF94B016D1B2738D1E0B062C4DD26CFF8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloud-prepare-upgrade.sh" />
-                                        </Component>
-                                        <Component Id="cmp7F5D5810EF40C3A84188A552DCD00008" Guid="{C9D996A3-704B-46F3-8BA1-73DDE8295AC6}">
-                                            <File Id="filD71F8EBE2E515A3CD296D45413FA065F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloud-propagate-vlan.sh" />
-                                        </Component>
-                                        <Component Id="cmp94FCB11503BBB2699CF1A4DD9E35C52F" Guid="{47D524AA-5830-4D4F-AB32-E97A9A1ED2C2}">
-                                            <File Id="fil3B0841CE39DC6CA46BB7C5118B91A8D2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloud-setup-bonding.sh" />
-                                        </Component>
-                                        <Component Id="cmpF9201D58B47A7E11845A6D127A0EBD85" Guid="{A28F0C08-74E5-4904-816D-ECE9ACF3F09D}">
-                                            <File Id="fil37F45642E828389EFF86AF7A6E0D8744" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloudlog" />
-                                        </Component>
-                                        <Component Id="cmpDA8CA1DBC718994C64120F30E2640107" Guid="{737C6D9A-4743-48CC-BDCC-C6FCDE83D683}">
-                                            <File Id="fil88B2406A33DEB4D1E90381F08C77CEC0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloudstack_pluginlib.py" />
-                                        </Component>
-                                        <Component Id="cmpB39C80D17002F67CA773C426CCD5C79B" Guid="{CA067C5D-2569-4556-A22D-0BE3E23B82B7}">
-                                            <File Id="fil301636E9517EC956481BD9A9EE117807" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\cloudstack_plugins.conf" />
-                                        </Component>
-                                        <Component Id="cmpF6EF0A228CE358A0B2B7FD4D0D7AA004" Guid="{CF6C7A38-A246-4739-BCA1-832F8FF09610}">
-                                            <File Id="filCDA54A9536DB8BC33A8CA11DE0C34315" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\copy_vhd_from_secondarystorage.sh" />
-                                        </Component>
-                                        <Component Id="cmp92583B3440E1EE5CC387DD94671B7914" Guid="{1FE0E364-87EB-4506-8BD9-3AC0F53F9434}">
-                                            <File Id="fil4C463AA8096382C3B40ECE8E909C62C7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\copy_vhd_to_secondarystorage.sh" />
-                                        </Component>
-                                        <Component Id="cmp52C24F1A2966F7C35E7B6E87BA586B54" Guid="{B908519C-790C-407C-A88D-C4F5AAA0053A}">
-                                            <File Id="fil6C7E61679CBACF25A0447AAD39BCBDAB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\createipAlias.sh" />
-                                        </Component>
-                                        <Component Id="cmp014CE8DBFFF159D9AFA21408F8656BFB" Guid="{E0CE1135-1B55-4D65-9CAA-855EDA2212C6}">
-                                            <File Id="fil690B8702F97084E4908C13039E912CEE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\create_privatetemplate_from_snapshot.sh" />
-                                        </Component>
-                                        <Component Id="cmp5826376E0AFEFCA1743441E08045675B" Guid="{5F59FC4C-AE6B-4678-9A12-DBF6932DFC04}">
-                                            <File Id="fil7A48742E97375A43F6FCDA2F68EF33FF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\deleteipAlias.sh" />
-                                        </Component>
-                                        <Component Id="cmpDB4ECA955FC312932FDD1EA7CA8E8886" Guid="{5AF11717-FCA4-4180-ADA5-3D329EC8CFA6}">
-                                            <File Id="filBE608226AF74378033059E023812F241" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\hostvmstats.py" />
-                                        </Component>
-                                        <Component Id="cmpCD085923CB5A46A2995A1C8A5BE2581E" Guid="{7854B383-BB35-4A87-9350-4B1107AD7B80}">
-                                            <File Id="fil0B1D9F14254EBF1F69F3A2717016BFC7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\kill_copy_process.sh" />
-                                        </Component>
-                                        <Component Id="cmpF1ED51DC7C5F55CB79FD066C97F7FE00" Guid="{E5208517-6933-4FE3-842A-7437628C6A0D}">
-                                            <File Id="fil2499492F165614D409B1F030DD87EA2D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\launch_hb.sh" />
-                                        </Component>
-                                        <Component Id="cmp29D62E88C4F24671798BC96D494037FF" Guid="{AA1DA7DF-930D-443F-B7DA-3B90FC105854}">
-                                            <File Id="fil72FC9732055EDC4DA784AEB0C1F4EE19" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\make_migratable.sh" />
-                                        </Component>
-                                        <Component Id="cmp06DF4AD2DD1B4FB716D67F9CC98BDB0F" Guid="{58057F3E-11A2-4614-A008-1BE36F14D698}">
-                                            <File Id="filF655854C663EDAF8844C3DBCA481AB21" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\mockxcpplugin.py" />
-                                        </Component>
-                                        <Component Id="cmp65E094AFC4504694F80D18026D63B5E7" Guid="{0449DE2D-299C-46B6-B988-B0679E0CFA98}">
-                                            <File Id="fil930A5E225EBC24383BE29073BC84DEB7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\network_info.sh" />
-                                        </Component>
-                                        <Component Id="cmp6550D85DB947332EC367B5F10E079957" Guid="{F480F27A-9665-40B8-A869-BEB5674824BD}">
-                                            <File Id="filDF18E1AB440FDD7201EB67CA53324047" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\ovs-get-bridge.sh" />
-                                        </Component>
-                                        <Component Id="cmp4B12A1128884B5E4BFA3A5D2399350B4" Guid="{D8F39BB5-085A-48FC-BDBD-42E7D53624F5}">
-                                            <File Id="filF6CFC3A21A0C6ADF40F1A0FFFAE5B87F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\ovs-get-dhcp-iface.sh" />
-                                        </Component>
-                                        <Component Id="cmp884808A284FD7E5A584874B635CB30E8" Guid="{8BD1F74F-579A-4556-BFE7-30E382A9BE33}">
-                                            <File Id="fil31A4B1A7C35318035475D03EEDB138A4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\ovs-pvlan" />
-                                        </Component>
-                                        <Component Id="cmp0C4FA72B48D1F1DF86C00AC83F161425" Guid="{C23F23AF-310D-481C-B6F9-03780363B5D0}">
-                                            <File Id="fil2E17DA8A85B61B5C3D7341B3A5F49D27" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\ovs-vif-flows.py" />
-                                        </Component>
-                                        <Component Id="cmp7154C18D28D0821B7F9FDA058B7684BF" Guid="{667F7861-793C-4B83-B8DB-76A77447A115}">
-                                            <File Id="fil63928ABD1DFA29DF2A28B53B581238B8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\ovstunnel" />
-                                        </Component>
-                                        <Component Id="cmpA85B375722A33339F828F08D4568D942" Guid="{4D3EE64F-E421-416F-8B18-AAC2CD377E9E}">
-                                            <File Id="fil4573D848D63904E25199DFC7C5F3C630" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\perfmon.py" />
-                                        </Component>
-                                        <Component Id="cmpD76E671ADB5BD6A4D78727948C10979D" Guid="{EA4A8C61-6B09-4489-ACE6-00B9A0F1A4BC}">
-                                            <File Id="filD3A7AE13D824593E31FF5468A9B764AB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\s3xenserver" />
-                                        </Component>
-                                        <Component Id="cmpA5ACE2ABDAD485164B610A43CF7260AC" Guid="{D6BC09D7-775E-4DBE-8E97-603B00B26BC2}">
-                                            <File Id="filA1C0191B48050912F371A13BC75AD95A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\setupxenserver.sh" />
-                                        </Component>
-                                        <Component Id="cmp9EEF37ECA5477759CE2D4970BB1B2231" Guid="{03ABC411-7955-4877-903C-1D01CF0CED7C}">
-                                            <File Id="filD7DEDCC78A58CB05902399D982284342" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\setup_heartbeat_file.sh" />
-                                        </Component>
-                                        <Component Id="cmp9DE8DA0BADB8F3218AF203D5F2093547" Guid="{6B25B900-A715-46C4-8266-A389CFC86D87}">
-                                            <File Id="fil00FC8BFA8A52C4816C1017892D9C4674" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\setup_heartbeat_sr.sh" />
-                                        </Component>
-                                        <Component Id="cmp151AC5940A52B84848B8B31EBDDD0F0F" Guid="{4F2671A3-9715-4114-96BB-BB13F55A78D7}">
-                                            <File Id="fil2671E25ED27BFEC230D8352675D940A7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\setup_iscsi.sh" />
-                                        </Component>
-                                        <Component Id="cmp697767827BDF2487CACDB2D9A09F2901" Guid="{EAB1E5A4-4CC0-456D-9146-D7B282074F88}">
-                                            <File Id="fil26D02B27FA01CAB5ADA6761A17CE287D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\storagePlugin" />
-                                        </Component>
-                                        <Component Id="cmp828DF8125A1571A46643C65AE483B465" Guid="{40052CB5-AD28-4C63-973F-6983BF1939E2}">
-                                            <File Id="fil5C88104CC07D3894D5C6618F2480D894" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\swift" />
-                                        </Component>
-                                        <Component Id="cmp29E6175F9E42A05F0ACA5E9DEC427DA9" Guid="{08A3A34A-662E-40F5-AC4C-6224AF8E3204}">
-                                            <File Id="fil30689D2F97C68DD797DC8681851DC4A0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\swiftxenserver" />
-                                        </Component>
-                                        <Component Id="cmp795E37CA1E2B235A5F5500D0CFC92E07" Guid="{4CAFC2DE-B603-485C-B8ED-A6A016962788}">
-                                            <File Id="filAD37A67E4680F1FFC939AE9759EA6193" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\upgrade_snapshot.sh" />
-                                        </Component>
-                                        <Component Id="cmpA2C045F0BD78D4DABB8EF22E4986156C" Guid="{04C4580F-E42B-46C5-81DC-A0BBCD5B2E07}">
-                                            <File Id="fil4473440D5E9186FEEB10AD78940562FB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\upgrade_vnc_config.sh" />
-                                        </Component>
-                                        <Component Id="cmp312772A42002C17926110BA35DDFEDAC" Guid="{FFBF99DD-60D5-4118-A115-37001898054D}">
-                                            <File Id="filFCB20DDD9C06EA1CD8E93787E53706DB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\vhd-util" />
-                                        </Component>
-                                        <Component Id="cmp70EAE5FACE0198DAE8D72AA3A4DDD8AD" Guid="{651F8776-C849-4660-8129-371E9157A882}">
-                                            <File Id="fil129D0C9AA098CFDC7EBE310D7AF0D22B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\vmops" />
-                                        </Component>
-                                        <Component Id="cmp283D0458C51549C88E126658847DF812" Guid="{04ECE3E1-E57A-4504-8D39-B1CA205E52A7}">
-                                            <File Id="fil1D8FEE002FCC5B193F930C253713BAB4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\vmopspremium" />
-                                        </Component>
-                                        <Component Id="cmpA7CDAE7D43C83449F75B67A9D91C58B7" Guid="{7D5EE788-A34F-472C-829D-340B0E07657A}">
-                                            <File Id="fil4893FEA94CAA0CBC81730555CEF14FC8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\vmopsSnapshot" />
-                                        </Component>
-                                        <Component Id="cmp85AE0727B19590A7FF1A50C5D1AE2205" Guid="{7A6D61D8-4B9A-423E-B509-80195D2C7DE9}">
-                                            <File Id="fil745D6FDB9D3434E0A55B6BDF777C205B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xen-ovs-vif-flows.rules" />
-                                        </Component>
-                                        <Component Id="cmp341D1CF572011F0DD8EA39C96D0E7D17" Guid="{42443EFC-E741-4094-B69B-92024D39CDD1}">
-                                            <File Id="fil99D3B4A49620B805F7A9727ECF11E482" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenheartbeat.sh" />
-                                        </Component>
-                                        <Component Id="cmp095F592845AFE0B3E095BABC7A7DD887" Guid="{A5A5FEB8-7266-4D8E-AF1C-40EC619AD149}">
-                                            <File Id="filD991C3F349A30E268A5ABF395749A963" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xs_cleanup.sh" />
-                                        </Component>
-                                        <Directory Id="dir4B06A194047F2DEB40247CA6CBCB8F3F" Name="xcposs">
-                                            <Component Id="cmp99FE5BF0929D0B39B9A28A30E029E3CD" Guid="{0DA5E7CD-7CD3-41E7-8D14-67DCEEEB749C}">
-                                                <File Id="filAC4FC8F1C782ECB3440E1EE17A7158F5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xcposs\NFSSR.py" />
-                                            </Component>
-                                            <Component Id="cmp68E4CC338F27CEFB9A29482B5F6D970D" Guid="{B9CEA9B9-924C-4CAA-AB24-4D4635A3046B}">
-                                                <File Id="filA741CC61B5626572A8D899AC9F346C39" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xcposs\patch" />
-                                            </Component>
-                                        </Directory>
-                                        <Directory Id="dir577E50C521ACC4901546F1E891382756" Name="xcpserver">
-                                            <Component Id="cmp9D2C30192BAB98A581E527EEE9D775DD" Guid="{9ED0D47E-687C-4ACF-B7EC-EF55E3B72BD0}">
-                                                <File Id="fil20B184FA8C6350142271FC46E5144B91" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xcpserver\NFSSR.py" />
-                                            </Component>
-                                            <Component Id="cmpF7D67DC496EBE7AC2C920439E1996283" Guid="{6755E17A-705D-4970-969D-D07262ED74CA}">
-                                                <File Id="fil50D116431833D7AF8498ECDEB3EBE743" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xcpserver\patch" />
-                                            </Component>
-                                        </Directory>
-                                        <Directory Id="dir016C1DE897013F29277FA8C44F7042F4" Name="xenserver56">
-                                            <Component Id="cmpECE28D947697E1B2574A852B9A5DB097" Guid="{86FE1FB6-8F00-4B6E-AC64-6431F2FE39F2}">
-                                                <File Id="filBF8ADF32C5F0AD1B0A9B22042D5782E0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver56\InterfaceReconfigure.py" />
-                                            </Component>
-                                            <Component Id="cmpB7CF7EED7782B02F1C519469E7B765D5" Guid="{82B9BA11-F579-44F4-ADF2-9C8AC6349343}">
-                                                <File Id="fil014109ABCE5008554B5CB5A8CC03CA00" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver56\NFSSR.py" />
-                                            </Component>
-                                            <Component Id="cmpEBDC2212A7FAB1E5BD6B67587A76AED4" Guid="{E0374E1E-CE89-4CC2-95D6-405CDEB9BB9A}">
-                                                <File Id="fil5726C798A53BA3EC83DE96B795B52A79" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver56\patch" />
-                                            </Component>
-                                        </Directory>
-                                        <Directory Id="dir122AAE0253DA70D74E62E154C0D6E5FB" Name="xenserver56fp1">
-                                            <Component Id="cmp840CA25576C5DF17180F997EE6BEF7D4" Guid="{8DF6B7E4-54C0-4218-91BA-0B5795E9F113}">
-                                                <File Id="filDE26C81CEAA4E3DF80ABAB2B1C4F8EFF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver56fp1\NFSSR.py" />
-                                            </Component>
-                                            <Component Id="cmpC1793F083A67818C741D1223019363EA" Guid="{35CEE455-B440-4B9C-A7FC-63833A5EF6B5}">
-                                                <File Id="fil8C165FF650F7463D5B51A6E63F74AC94" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver56fp1\patch" />
-                                            </Component>
-                                        </Directory>
-                                        <Directory Id="dir11A404676E55808E4CE7443F62D7B652" Name="xenserver60">
-                                            <Component Id="cmp75B69B6523FC3FC29345B566F9470108" Guid="{90C1D320-62F0-4699-AE86-EDCAB6F86A0A}">
-                                                <File Id="fil69EE997B203C7094C0F596DAF6AC054A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver60\NFSSR.py" />
-                                            </Component>
-                                            <Component Id="cmp270BF8B2BC9223CBA67FF4520E0EB0CC" Guid="{227378AE-3716-4DF3-A7F8-139C195C3F1E}">
-                                                <File Id="filAFD32F98A5AF5B6C4A77FF24C07998B9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver60\patch" />
-                                            </Component>
-                                        </Directory>
-                                        <Directory Id="dir7C0B53399FF7EAD9F60810F91C0224E1" Name="xenserver62">
-                                            <Component Id="cmp32FE4A27540A4C0D7DFE0023D10E47C8" Guid="{06FCDE5C-1844-44AA-BAB6-009696BAF317}">
-                                                <File Id="fil726531D50D5B91E8D06446A82ADEA9CD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver62\cloud-plugin-storage" />
-                                            </Component>
-                                            <Component Id="cmp0EA4B4F387D07BD36E57146B6B677CCE" Guid="{D62F3553-97CE-4D53-8F6D-EBD6A6E135EA}">
-                                                <File Id="fil3EB8BCCB3A3A62D666655F2E27FD1C70" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\hypervisor\xenserver\xenserver62\patch" />
-                                            </Component>
-                                        </Directory>
-                                    </Directory>
-                                </Directory>
-                                <Directory Id="dir3602171B00B6DB3E3D05F1E6CB2E4EB2" Name="network">
-                                    <Component Id="cmp76FF40CF7CC84042483AA2633132F6F9" Guid="{74E90222-3865-490C-9904-F33922C8890A}">
-                                        <File Id="filE148D448E16BCA970E61880777BF9D74" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\ovs-pvlan-cleanup.sh" />
-                                    </Component>
-                                    <Component Id="cmp9764EFEB37698149B4CF95E24D6870F8" Guid="{DF82E391-624F-459E-8606-10D17F759D1C}">
-                                        <File Id="filFBB5008B12C0D77C54F4EB2CEBB02E21" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\ovs-pvlan-dhcp-host.sh" />
-                                    </Component>
-                                    <Component Id="cmpF1B0F36254CFC89E6F2FC4668A279880" Guid="{DA7070E4-94E6-48E5-B67E-5825B9CFE209}">
-                                        <File Id="fil1A512A74B83FB8EB95FD43B883A88F99" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\ovs-pvlan-vm.sh" />
-                                    </Component>
-                                    <Component Id="cmpA58BF213DB6BE4CDF38B4373FBE8F0B5" Guid="{38547453-B36B-4E2E-B12D-94BEBE4C4598}">
-                                        <File Id="fil230AD6E67E51E034C26104DF7BEA4A99" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\security_group.py" />
-                                    </Component>
-                                    <Directory Id="dir985A64B336DC8CBBB2EDC9E5C6534DF9" Name="vnet">
-                                        <Component Id="cmpBC451DEE1CF26039CD451D0C148515E3" Guid="{31DE5C8E-298A-4F04-9EB7-5B793F528DD2}">
-                                            <File Id="fil6EB146FB66A3359D9E1AD1ED57FA6DD1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\vnet\cloudstack_pluginlib.py" />
-                                        </Component>
-                                        <Component Id="cmpB35F18E2C81EA247D0A07EC70B15ADCE" Guid="{FE43F3DF-7E4B-4EDE-B343-EC48CED19BCF}">
-                                            <File Id="filDBF0B713DD57F5DF6A3081F880F77EDE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\vnet\modifyvlan.sh" />
-                                        </Component>
-                                        <Component Id="cmp5B195BB800FD7411B27C92CB43108D68" Guid="{EA637D10-6C39-4585-B3D2-F3BDE92153F4}">
-                                            <File Id="filEEB0D05C4FCFDD7927A608146CE5107B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\vnet\modifyvxlan.sh" />
-                                        </Component>
-                                        <Component Id="cmp6AE6EF943B6F1903692B887E285CCFB6" Guid="{93740DFD-5073-4F03-8144-469129F61DFC}">
-                                            <File Id="filCB1D16107A46A1056DDF65835B0EB884" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\network\vnet\ovstunnel.py" />
-                                        </Component>
-                                    </Directory>
-                                </Directory>
-                                <Directory Id="dir0BC4068E93B9F5EC356B44EDBAD06632" Name="systemvm">
-                                    <Component Id="cmpE90BFF212EE36AB7F5BE7066910EF4BF" Guid="{BE1A382E-DF64-479F-A58E-C55974D62CAA}">
-                                        <File Id="fil7CEC4A5007D96F87FEAC06E8B6CFC140" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\systemvm\id_rsa.cloud" />
-                                    </Component>
-                                    <Component Id="cmp49AF1F329C3F7DCBA3BC03E4E79CF94A" Guid="{21015AF2-C238-4C1F-858D-CAF54C850372}">
-                                        <File Id="fil2807E11A2C915C30594BF2FA584064D7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\systemvm\injectkeys.py" />
-                                    </Component>
-                                    <Component Id="cmp2529F0564324F333C6435C250FF5970A" Guid="{661E44F7-CC27-4CE6-9009-8CE647D0A556}">
-                                        <File Id="fil979A8909EC39AAA2CDC94716AA921C46" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\classes\scripts\vm\systemvm\injectkeys.sh" />
-                                    </Component>
-                                </Directory>
-                            </Directory>
-                        </Directory>
-                    </Directory>
-                    <Directory Id="dirD4AD1ED156E30F705BB465B1B807EBE3" Name="lib">
-                        <Component Id="cmpF2D829D6269C06610A0D914F091D2EB6" Guid="{E5A78D69-8E90-4DD0-9826-B43E69308074}">
-                            <File Id="fil7EFDC762A75FE8B72B2856BB3D95936A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\activation-1.1.jar" />
-                        </Component>
-                        <Component Id="cmpA3E143106D868A13F2262CA98833028F" Guid="{6D066367-8A19-446E-ACAC-7731F995AD60}">
-                            <File Id="fil28DBADFA869E8650AC765BABD2F2DC83" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\amqp-client-2.8.7.jar" />
-                        </Component>
-                        <Component Id="cmp2FB05B76F9224338415D5AF2DACC8578" Guid="{9D95AD3A-3CEC-4476-B193-CFE0785BB010}">
-                            <File Id="fil45475CD6BC8715B756A21128471E18DC" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\antisamy-1.4.3.jar" />
-                        </Component>
-                        <Component Id="cmp6B758895DF8C4D51E8547F56A2ADC279" Guid="{833D9FAF-158E-4519-B4C9-5650AB3AD2A1}">
-                            <File Id="fil6A67AE34B04BD219A6A3A283A3F7E223" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\aopalliance-1.0.jar" />
-                        </Component>
-                        <Component Id="cmpAB0C1DB0804EBFC02CA78936EFFF71EF" Guid="{4D586461-E2CE-41FF-8D0D-8AF1E5330C53}">
-                            <File Id="filD03A3AD81C68FFF6373734DFEBEFDA44" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\apache-log4j-extras-1.1.jar" />
-                        </Component>
-                        <Component Id="cmp85716B1B1F1E013696DEDD3474014DB8" Guid="{E5721F13-176D-4831-8D74-30984B239B59}">
-                            <File Id="fil0C12729E14A2993967F3DE4E9A48797F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\aspectjweaver-1.7.0.jar" />
-                        </Component>
-                        <Component Id="cmp737216EFE0F1409C4D1F2265D4E5B2A1" Guid="{24F0D552-C696-48D5-84CB-30EC8EFA9303}">
-                            <File Id="filF9614AD8B885A6E65C55BC631E1AF91F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\aws-java-sdk-1.3.22.jar" />
-                        </Component>
-                        <Component Id="cmpC4B4CBE179C4F76D7969E0429A887CDF" Guid="{62AEAE3D-7411-494E-AE1A-F2E8ACF452F4}">
-                            <File Id="fil36A34BC8196A98C11CB4FC54DDE5C3FA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\batik-css-1.7.jar" />
-                        </Component>
-                        <Component Id="cmpE1BB74D0F1E82DD596BBBB6C676460E3" Guid="{A63730FE-B340-43B5-B19C-AE3BC0E5DAC1}">
-                            <File Id="filF159FD378AB177B918F4E15B3F3BE2E3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\batik-ext-1.7.jar" />
-                        </Component>
-                        <Component Id="cmpFE414A5137D6014C13BEAF7CE666B901" Guid="{4188C05A-68D4-41B6-8A75-E3727A28EE40}">
-                            <File Id="fil93C4C850F4581B29A60B009EED396710" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\batik-util-1.7.jar" />
-                        </Component>
-                        <Component Id="cmp840E48CBACD153B6B20C9CDB810B839A" Guid="{F973C382-2A9D-4269-857A-1EF5693C5502}">
-                            <File Id="fil8A2FE0ECDFF9481B445D5C3853187279" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\bcprov-jdk16-1.46.jar" />
-                        </Component>
-                        <Component Id="cmp95FB8B358EF45F79B9515DEF7E8B29BC" Guid="{82D22BA7-4314-4B6E-BCDF-1CD30E619680}">
-                            <File Id="filA521B1828612B0DA2B95C08C3D3B8182" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\bsh-core-2.0b4.jar" />
-                        </Component>
-                        <Component Id="cmpD05F66DE43ABCFBF23BCB600DE956E3C" Guid="{70F3D2CA-9116-4595-9C4C-3B949B94B633}">
-                            <File Id="filAE47900AF7BE2616ED245CA95A9310D8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cglib-nodep-2.2.2.jar" />
-                        </Component>
-                        <Component Id="cmp68DD2572E139316EAC122073F14C2DBF" Guid="{C6065621-786B-42FA-B1E7-C9EDF612BED1}">
-                            <File Id="fil5704F56CA28594D569F04AC927EBB409" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-agent-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp053FA1BACCC1DFE05BD2A78D3EC9DFD0" Guid="{7816ACEF-F263-4E1F-8278-A28E0834196C}">
-                            <File Id="filBBA6DBAE9B8F8ADE2175AC490A19F8E4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-api-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp10D4FB44E6F41C4867BDC54C65A23F18" Guid="{696B69FB-F361-4529-8145-F12CA2006518}">
-                            <File Id="filE6F461896AA72B9FCAF134D1545A32CB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-controller-secondary-storage-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpB3C2CB2A0C0C44280251610D64EA34A5" Guid="{0C4DE421-ADC1-478B-AD65-B29A7E6236C1}">
-                            <File Id="filDFA662D17EE4A19FA92A661130C9D0C2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-core-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpFAD337F32D9DAD7C1608584D499EC0F7" Guid="{AFD885F9-A1E5-4009-8790-39A8F995037F}">
-                            <File Id="fil3571985F2DE1BF298069A40EBFD1F743" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-api-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp980CEFD22B6EDFB878ADCFCD3C1A6795" Guid="{F1D3EC46-72B8-4348-9C64-0DF7434E9ABC}">
-                            <File Id="fil23019D210DE586BCBB8FA24BD63A042B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-components-api-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpA037D4BC3A7643D66FC93D9DBD3231CF" Guid="{E41AB307-5610-499E-B635-AF960F639A30}">
-                            <File Id="fil0F22A3FF90ADF85751BF8F0583EC1D3B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-network-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp8ECD89F84DDB6A69C5D5400C09DA14CA" Guid="{EFBB5EF0-D840-4390-9343-CBAA40311A88}">
-                            <File Id="filC4CE0EF758E949C45CBF9BC94CA4F4F5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-orchestration-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCB6E48CA739193A15D4AC14E0302A44C" Guid="{5B6DD7A7-327A-4226-8268-8DBBCE414035}">
-                            <File Id="filB66F558A89B520349999D224BD00308A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-schema-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp1E88F28393186242EA3DE3D790EB85CE" Guid="{1BDCF25D-9B96-498F-83B6-D4B3CA8F4596}">
-                            <File Id="fil55C835C6B9E9CDEF50EEAD532FC95B2B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp2C08251BEFAF44B31CEA7847A91AD4F4" Guid="{8C780B31-65BD-4EAD-9EEB-6FD569D1A83B}">
-                            <File Id="fil0BD15BB1058793ACA48708E0598DF262" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-cache-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp7215333AA17AC5DF99CE957BB9438677" Guid="{0E25DD22-0AC0-4461-8562-DC32B2F1FCC0}">
-                            <File Id="filD9BE331B51879411FBB446A6B7453995" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-datamotion-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCBB72D8C2425E17861B303477B6763B5" Guid="{2044DA0D-B21B-4191-81FE-ED7AF5D51E64}">
-                            <File Id="fil8E0285FCC07FA85D066ACD498AB52658" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-image-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp5EB5F77075D2851AEEED7C27D21A45A3" Guid="{DA867317-1897-4682-B2A7-198FF3E9C786}">
-                            <File Id="fil3BE0C9705BE7FFC58FD6019580A8F29E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-snapshot-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp31885389B028B5DB8056CD914990B774" Guid="{3868270C-5F76-41F0-A90F-D5B271ABF5DB}">
-                            <File Id="filBFE94D52B497E31BC481D09D3FE1751F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-engine-storage-volume-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpDEB685A842E2A519A4ABD4D102ED83F4" Guid="{A69B0EFE-4AE3-4C7C-BEC7-586663905BD5}">
-                            <File Id="filD9A9CDF3CA2BC83326C57113CE6E4F34" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-cluster-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp3C03902D82B4504831FF25FE23BFF13C" Guid="{A1B92A0E-D0F9-4AA3-884E-AF7CDE80C9CA}">
-                            <File Id="fil45E319EA3CBB9A3C6552F277DE2B3C38" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-config-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE0C985EACC4891C413624DF04A20082E" Guid="{050F3106-89EB-44DF-8CDB-7917BA957C75}">
-                            <File Id="fil4C08CB1E3416CD63C3F28329223EA6AD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-db-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp0E7A5C73EC5E56E3260BA02ADC05AEFB" Guid="{2B1E2EB7-5655-4970-8882-19053C7223A1}">
-                            <File Id="fil7A045B2B6548EFA98D645A0DCFB411BC" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-events-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp4EC2E4C78AB0864A292331A64B673E80" Guid="{C889B58A-ED5A-4D8E-B9A4-D9A771607C31}">
-                            <File Id="filA5A6C9EC1F9A15006584B8C12F38B87B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-ipc-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCFFB8D44D84C546212B33DE94E42CB5C" Guid="{F6F73609-B6AB-4A2A-AD28-C3A3A28CF09B}">
-                            <File Id="filA754485B727BB6B680C3D9A2198F25A1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-jobs-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpC41CD5F28C01900654FBED380521BBFC" Guid="{7465D890-5A40-41FB-9699-75A1E0A1C7D9}">
-                            <File Id="fil03E1315117D37D87CD8F95F89DF6D6F8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-managed-context-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp43D9195434BB328867E29C03FFD2074C" Guid="{9CD1E337-4381-4BDA-AF17-0B7EF279B58A}">
-                            <File Id="filB92BDFE3B4AE098EA1EE731F3350C378" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-rest-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpDDAA9863C75F24B496C6BA183DB34BA6" Guid="{DA2F94D3-7103-4E7D-A81C-A3D828874D49}">
-                            <File Id="fil66AD0330E3DAB80FB4335BB408DE11D5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-security-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE9422A3EFB96B7D6CF28A20BDE19560C" Guid="{5DABB068-A1F4-49EE-9F84-9AF19E6F0892}">
-                            <File Id="filC68CB8B765F098D8F8A44E51C6EB815A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-spring-lifecycle-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpB2F7E25C01676CA3FFC691CF7DE26670" Guid="{14578618-C17D-460A-8563-25C29A71FCA4}">
-                            <File Id="filE76926093D9C11D9BBA04382AB644257" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-framework-spring-module-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCC739E7B4A6BB506DC1E8596E1D477BB" Guid="{D4F563F4-2978-4F8B-A84C-10A58B6536A4}">
-                            <File Id="fil1E8629BCA894062CA310C6684185C516" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-mom-inmemory-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp4CBDD655EBCB0B3D22E2DBB900B2C682" Guid="{1B44BDDC-D604-4D86-BE9E-553FC583E438}">
-                            <File Id="fil79CFDE4697558AD9C9E7457938690A24" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-mom-rabbitmq-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp880E465D50F8BD6C227EB553504AC571" Guid="{647DA726-5F56-4486-B3B2-E64CA4A60981}">
-                            <File Id="filD54F3E8A6E814E153ACBF033C3B0E03A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-acl-static-role-based-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpFED1E298CC2A536198D364B7BE7F21B9" Guid="{4994ED94-8B84-4FB9-A955-24B06A32AB7B}">
-                            <File Id="fil127BB03C5759D2679228A90F6F1B1CCE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-api-discovery-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp7B84950D2792D889C3BF4348F8D8EDA1" Guid="{267F6321-2FF4-4263-9F8C-BB75B0C8E0B0}">
-                            <File Id="fil2D1862E76D205F73E2B8B76917BEEC93" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-api-limit-account-based-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCFA0598A7D429B5D592FB828E7FF4F3E" Guid="{0C901B6D-4DF8-418E-8B22-69D697D9F6FD}">
-                            <File Id="filDD2E5EE9EE6FFA03654492E8ACDC1753" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-dedicated-resources-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp7937F27BF975D4F3C7DF1694F139FCD5" Guid="{0A4EB86B-489E-49C2-BA56-8A822A9D90CB}">
-                            <File Id="fil41A91ABD0DF6C30EC9502B91AFC4D6B8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-explicit-dedication-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp576112B0425B94FF535E02B9B3A82A21" Guid="{A458538C-0CD9-49D1-A6C1-25C73603685C}">
-                            <File Id="fil0976823117FC5CBA47ACB08C38332A4B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-host-allocator-random-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpB3FB2E1B1AE3A1B861164BFF506E4BB5" Guid="{CABCF338-AD3A-49D7-82EB-2D3D844215AA}">
-                            <File Id="fil814B0D7468CF9EDF4E978A5CA488759E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-host-anti-affinity-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCF13179476AD94F458CA0EA44D7DDAC7" Guid="{793A6616-A744-4E21-975E-9F4521FA3BDD}">
-                            <File Id="fil9474ED93C49F727E170B7BD1AEC82AFE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-baremetal-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp8D67161C7E50EE36669F7C5D9923D91A" Guid="{28CAFB65-2449-45AF-B852-89500C57C079}">
-                            <File Id="fil97A96BADE154B5518AEC86EAD2747D39" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-hyperv-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp39347F69E7E0C55D8FDA48C01CA9B8DE" Guid="{50D3F22B-8EDF-43FF-9A15-70F187450354}">
-                            <File Id="fil4D714C285678D14203968DDA3F9AC604" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-kvm-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp484E9D1B9A1D120F01385D24A44A7909" Guid="{FFE2D8F7-A564-45F2-9A4A-96DF28AD0985}">
-                            <File Id="fil9619E1D73916B76B3DDDEC1F85BD28D3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-ovm-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE66BC3701F4FE7089E72DCE19E655A2E" Guid="{59BC6F6B-4802-46FD-9F15-4E2168EAF9E8}">
-                            <File Id="fil2BBFBA9E0FEE7C9A1BEF9AF7EC944494" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-ucs-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp17CA79361C814E20B9F772CE10EC49DC" Guid="{8B62E635-88A0-4943-84B1-5EE9478DC90E}">
-                            <File Id="fil9E785C78E9734C684056A8B36073EC9F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-hypervisor-xen-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpA6F3B74801C880438FFE04CE4BB76A4D" Guid="{5B636819-436A-4397-A623-7BA563E9C661}">
-                            <File Id="fil70F85DB42E43193785781985C6583A45" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-contrail-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp46FE38B8E6D467E0A461B5D1F5A9C9A8" Guid="{B3918327-34B3-4449-870C-A9997076D1BF}">
-                            <File Id="filAEA74C7A4E6EC4243B5A31E0CE48B26F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-elb-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE79D8DE0A3F5641D63029C9C5BB84D0D" Guid="{71A421D6-EC6B-4410-BEB8-D8A13CBF2F76}">
-                            <File Id="fil26BE9842DE6416E8946A2295439E129D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-internallb-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpBA53547354F4749AB6DB53E652729729" Guid="{0026D30B-04AA-45D9-9582-743650497E99}">
-                            <File Id="filC6F3205D9E0721B202FECAD231D0E72B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-netscaler-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpCD11EA05E25825E7612832BC5B20BA2A" Guid="{143C0989-60D4-4E60-9BEA-FB55129E0450}">
-                            <File Id="fil51EBE2CEBAF72358155A6AD4FBC26891" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-nvp-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpBDFE909E7E379544C61D273DC64AA4C1" Guid="{01D34FCB-498E-4AE5-BE78-5C292EE9014D}">
-                            <File Id="fil08B5347217FB64B10CA6680FB6F79F81" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-opendaylight-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp3ACE0516410DF2135ACB4ECB4C514516" Guid="{0E1A9073-4DD5-49E6-8744-BF3F2797B85F}">
-                            <File Id="filEC2F7FF13555A6E838AAC3D8A8E72A7C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-ovs-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp745688982E1084B904FEA071A184F46B" Guid="{2C8C08F2-2A04-4EE1-9F0C-C2F2A5BEC5C0}">
-                            <File Id="filF0BC533CE50CFDF6A5F9212B3DBCDAD3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-palo-alto-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE09A0EC1AEC3442530CE4D940A0126DE" Guid="{FB6D0CF1-FC9D-4B07-A8A3-E2351EBF2CFD}">
-                            <File Id="filAB23121C159136639196D708A3D87153" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-ssp-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp8AFFC23BCB9CA9B76CCE523A385B70C2" Guid="{078EC5CC-F0F7-408D-BC4E-35A253CDE321}">
-                            <File Id="fil80EBFF4AEB8D75B3F9781E6DF68D8E4D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-vns-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp0C6141EEA4A40393515982D763DAE5FB" Guid="{C4F5354B-9FA5-4FE6-8775-C8FEDA9FFB27}">
-                            <File Id="filE638272BEFE848603183613DCE9458ED" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-network-vxlan-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp4FB659D88A93FF927815E43845491DA9" Guid="{7D84E27D-132E-43C0-A30F-894BDA4BFDC7}">
-                            <File Id="fil9EE3A67A2019BFC4CC118A9B0FC852DB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-planner-implicit-dedication-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp50C956224B366169BA04472188950247" Guid="{C40E3931-25CE-462A-BD3C-1C4C07AA7964}">
-                            <File Id="filC1C9A8745995BDEC5713788F19F783C8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-planner-skip-heurestics-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpA483BD06A7D6334E6405477C56E9DFFD" Guid="{2AA203F8-278C-46F1-9766-57989BAB4AD0}">
-                            <File Id="fil0A7545872DBEB28CC14584AC8BB1A66A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-planner-user-concentrated-pod-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp18A187327523FE95B85904046F0995E7" Guid="{76B1201E-43A3-43A6-9C7D-88F7756FD6C3}">
-                            <File Id="fil00EE7815D372A43628D3E1525E5A1DCF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-planner-user-dispersing-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpDDDD31383EC18DC518164D114B067071" Guid="{B7AA5972-E96E-474E-B740-8750DD44F479}">
-                            <File Id="fil62FA95536B788F362125CB0F858157E9" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-snmp-alerts-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpDD3CA3FC5F636E0CFD5412E59A18A5AF" Guid="{778179B7-14B9-415A-A4D8-4C00B46DCDBD}">
-                            <File Id="filE4A80408291D56CA2C22E218542F6A1C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-allocator-random-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp59307667B29713EE25C4CE3FD0860F96" Guid="{C529E15C-A47C-4422-97BF-A7F7A0CB79F0}">
-                            <File Id="fil0185940209A9067A9E6E713A79BD8F1F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-image-default-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpBEF338145E29BC27474B53158F25FB95" Guid="{3E2EF6E3-DEE4-4DCD-A644-58EC296ED109}">
-                            <File Id="fil1F832096AC1AF4C0D0C946FEA4446C16" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-image-s3-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp8C3019A13CF77EB1A807E2EE9DE4E365" Guid="{1BDB1347-B9C1-4DBC-B084-A8CC046B6F02}">
-                            <File Id="filFCA9A7A3C2862E1484C486E80048B83D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-image-swift-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpD64E6CDD99BF2D21CAE829616DE42236" Guid="{3215DA5A-5E27-451E-ADB9-CA3374CBBE69}">
-                            <File Id="fil188C8EF35489C29B4C7D0860D46D6B85" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-volume-default-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpDC56F1AEA9FABCCA41D117FA3E462B20" Guid="{47543CBB-8E2E-4744-A3D6-70DFF1AFC863}">
-                            <File Id="fil6C1431D9D8E64ED0B29AC46C17B31C9C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-storage-volume-solidfire-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp0523CA11E9A3AD4396B3A4D94126D6A7" Guid="{56884E32-3BCA-4B2D-9B4B-68B6EBFB508B}">
-                            <File Id="filE25110329A3869F9100004F3C6BC2115" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-syslog-alerts-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpBE28EC01FD89E2022706795FE3BE64CF" Guid="{7CFDAA19-18AC-4404-8E22-7A0778477DC4}">
-                            <File Id="filE68C8D1FA4710AA381CC2C023CB8EC1C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-user-authenticator-ldap-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp7598569D1214F0C47C6FDE60A5CF56A1" Guid="{9BB7EE11-975C-46A5-8E5E-B87000078FB8}">
-                            <File Id="filAC8BDDE21AD92AEA27905F304F5CD16A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-user-authenticator-md5-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpA7EB7CE6F51D8AFFB2849A1E45727DD4" Guid="{1A2063D0-2084-444F-9BAC-B816FB516C64}">
-                            <File Id="filB8C7B73768554D66E17F9DAC69CE1D87" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-user-authenticator-plaintext-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp605BEAEE41DE38DF62A7661E5917FFAE" Guid="{C3DCBD0C-D77A-4302-8E69-D37BF9BA6D69}">
-                            <File Id="fil3F542ACF87BFD211D37424D884CE670D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-plugin-user-authenticator-sha256salted-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpE0B719953591863F1C41B9B8D9890FE4" Guid="{F62A3CE3-951B-4408-9499-8F1D5500DC25}">
-                            <File Id="filB9D25EDE99C673A9CD79077D1BD9908F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-secondary-storage-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpC316900EC1F7921DA4B97A0BFDDC6371" Guid="{7F56E576-A46B-4FD8-888A-99C5DD7F2D28}">
-                            <File Id="fil6A3A52DD897E8BCF27A929C3925DE155" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-server-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpEA52008808B8D6CB960FC0B64DBABA18" Guid="{B4A4E794-DEC8-4D46-B749-0530B59B6E9C}">
-                            <File Id="filE30D812BAFBA2BAE7E0C31D6D5E038E8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cloud-utils-4.4.0-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmpAA79BA8C69B3B684C4B541639A4B1B48" Guid="{E893CE7F-CB9F-4087-98DF-D901C2EA21B4}">
-                            <File Id="fil3AE259137B0BED6542BED470C5A30D0B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-beanutils-core-1.7.0.jar" />
-                        </Component>
-                        <Component Id="cmpDEEBED90BCD0AF6DCDCCF3726C454D1A" Guid="{0E70AB80-C2BC-495D-8BBB-8116EDE27721}">
-                            <File Id="fil868F25C481CFD0AFCE7FEB57DFF4BE6C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-codec-1.6.jar" />
-                        </Component>
-                        <Component Id="cmp56904E49C396D6221012E481C76BFEDB" Guid="{01510B23-8475-4CA1-8D79-BC8A2958E1A2}">
-                            <File Id="filA6CF21CB1F687151134149E4CF9DE4CB" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-collections-3.2.jar" />
-                        </Component>
-                        <Component Id="cmpA67AC3C865D3FB5903AC78966B135A5F" Guid="{D1D602CB-7BAA-4D65-A6D5-539640304E98}">
-                            <File Id="fil49BC10E049CBE237FB80827C924AE4A2" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-configuration-1.8.jar" />
-                        </Component>
-                        <Component Id="cmpE2B831E07705E24C1FD0BC0F2AEFCB1A" Guid="{23D4766C-DED9-40B6-87B6-351A991554B5}">
-                            <File Id="filB440E9F7CA30AEE982D86C4692F2AFC3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-daemon-1.0.10.jar" />
-                        </Component>
-                        <Component Id="cmpF09680275C25673EF264EA7BAAFE62B8" Guid="{5D965923-7F59-4BD7-93B3-869AD800512E}">
-                            <File Id="fil4F20AF114B23448F0E4F9CBC1DAE5759" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-dbcp-1.4.jar" />
-                        </Component>
-                        <Component Id="cmp5FB7FBB46BEF31107DD64428F0DF1FC4" Guid="{77A82AC3-F4B3-4F19-9397-30E7ACEB3096}">
-                            <File Id="fil9CE35121666D2F24D87EE11BAF3ABE72" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-exec-1.1.jar" />
-                        </Component>
-                        <Component Id="cmp89DE26021F5BBB23D9756486D57C985E" Guid="{1DD6221A-0964-4643-A7EE-DE9D2CA0258A}">
-                            <File Id="filE9D3CF4D4ADC9D6D8003C33C76095B15" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-fileupload-1.2.jar" />
-                        </Component>
-                        <Component Id="cmpBFA91247D54CF980299DC5DA3B3823FC" Guid="{E8006D2F-0FF4-430C-9491-8706A722352B}">
-                            <File Id="filCE6BCCE301EC3F57097B5B4119C41567" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-httpclient-3.1.jar" />
-                        </Component>
-                        <Component Id="cmpC90D538CF35392DC8C009792FB8E6860" Guid="{315654B3-E4FD-4F14-B0EF-DC71F160546C}">
-                            <File Id="fil4CAB715C556199980A006FDAE22D26B1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-io-1.4.jar" />
-                        </Component>
-                        <Component Id="cmp68A5B8A15810C6912151282F5F5B568F" Guid="{4DF26E80-8009-4836-9C67-5780E64B1714}">
-                            <File Id="fil685FC4F3EA9BAF06DB10A0053FB3C8CE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-lang-2.6.jar" />
-                        </Component>
-                        <Component Id="cmp4196A38C255BB0CCCAA0A70FE7DEEF58" Guid="{4D845861-B796-4FDD-A927-1E02C8646FDA}">
-                            <File Id="fil46D7AA45E37D4B8CE1E20A5CCA93F617" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-logging-1.1.1.jar" />
-                        </Component>
-                        <Component Id="cmpB164A610DB8FDF54ED63DCB498E40A27" Guid="{BF397D1C-6AF7-4540-8054-4AB8684DC6EE}">
-                            <File Id="filC9D92721946B60A6D58B07DA26DEB8CF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-net-3.3.jar" />
-                        </Component>
-                        <Component Id="cmp7531333E7B9F893A3A68372A9B0B779B" Guid="{C5D4F7CD-D231-483E-A0AF-56854E6AB2A4}">
-                            <File Id="filF45A499EB7C2523797AD1D7132C4B05E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\commons-pool-1.6.jar" />
-                        </Component>
-                        <Component Id="cmp1BF05E1306024F72E5F302052C4431B9" Guid="{C1E3BF9B-2AD3-4B0C-9375-0AC29F7A9AF5}">
-                            <File Id="fil0187B1A02C3679ACBF2A2FF17853B8D0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\cxf-bundle-jaxrs-2.7.0.jar" />
-                        </Component>
-                        <Component Id="cmp0F5759F010AAD8E57FEED9BB38D65F91" Guid="{0A7F25E4-2A81-4776-BB79-C33633C87089}">
-                            <File Id="filF809F7E0C1E2C27E71E39AB3803FCC06" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\dom4j-1.6.1.jar" />
-                        </Component>
-                        <Component Id="cmp9FAD7DAD071299E1AAF045F54DE9F495" Guid="{73188CEE-DB1A-48F0-AF78-A37662859327}">
-                            <File Id="filF642ECE1D8F64EBCECFA04A5600BF8E3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\ehcache-core-2.6.6.jar" />
-                        </Component>
-                        <Component Id="cmp0C3372A952450A4EED8FDCC1B8EAF4A3" Guid="{D0DA328A-0956-4341-9D5D-CEAF84470F46}">
-                            <File Id="filD619AEE8A024E5F335662217E6852A4C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\esapi-2.0.1.jar" />
-                        </Component>
-                        <Component Id="cmp9562AE97F33C3CD77EF1E6047705DA8B" Guid="{7C28B686-32DE-4834-BC19-4B6404AAAF87}">
-                            <File Id="filE11F9535C69170721EED4B884EB5956E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\geronimo-javamail_1.4_spec-1.7.1.jar" />
-                        </Component>
-                        <Component Id="cmp8D6DE04804DE7F875BFE1C2B96E6DAAA" Guid="{40259041-4E04-4A6F-B413-5743D718D709}">
-                            <File Id="fil627FBDDEC6C809BF0EF3B1228E70F7C3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\groovy-all-2.0.5.jar" />
-                        </Component>
-                        <Component Id="cmpC8065F5E307AF50C8229837FADEDA835" Guid="{33925555-6FF0-4F85-A55E-66415ABF0577}">
-                            <File Id="fil1B3FFAA34A68CF58B62021CF412F86D5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\gson-1.7.1.jar" />
-                        </Component>
-                        <Component Id="cmp3144F7B0A58AD9EA30445F579EE4F391" Guid="{7E79CA97-6BEE-475C-8F85-EA1E301069D5}">
-                            <File Id="filA7C28BC078793D48AE50E3FA76099394" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\guava-14.0-rc1.jar" />
-                        </Component>
-                        <Component Id="cmp7E3B58D2A4782D7409275BE070F7CF58" Guid="{3C98FC6C-B3E0-4F65-AF4B-D9D7F90E7C45}">
-                            <File Id="filE81AA8DA05A727A344B78853C52D1C2A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\hamcrest-core-1.3.jar" />
-                        </Component>
-                        <Component Id="cmp1FD25AD22B9922A127097A63F2C19C75" Guid="{8B64E6B5-0C1E-4FDC-9FA6-1305A2A7BD79}">
-                            <File Id="fil6BAEA00B6812606D29296CBACFF75FCA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\httpclient-4.2.1.jar" />
-                        </Component>
-                        <Component Id="cmp69F70CB4547BEC51A76EE4FBF29B227D" Guid="{5F203DD7-8F4A-4077-8859-13B1668599F8}">
-                            <File Id="fil0CE56C21CD08E6C6E84752447208BE14" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\httpcore-4.2.1.jar" />
-                        </Component>
-                        <Component Id="cmp64CA09D64F696D3E71B4BE826A07731C" Guid="{067FF9B5-8C20-437D-95DF-952AB9317230}">
-                            <File Id="fil29CEE887539A4CE912A772573127CD31" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-annotations-2.1.1.jar" />
-                        </Component>
-                        <Component Id="cmp03776BC4AEB2E5DC49A619B02A797EB6" Guid="{648EB566-15A2-4F3E-89D9-9D5D0EDDEC22}">
-                            <File Id="filD8335425791A57A1A4A27C77EF3337AF" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-core-2.1.1.jar" />
-                        </Component>
-                        <Component Id="cmpA096FB071D1289FB6EFB128A9B33F801" Guid="{6D11EE10-FF90-4942-87D9-263F2CE429D2}">
-                            <File Id="fil5DEE58B319387CABE61F0782244AC37F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-core-asl-1.9.3.jar" />
-                        </Component>
-                        <Component Id="cmp654DE3A3B029F59772E7A6BB4C754997" Guid="{363480DA-6AEA-46E7-93C1-362454606124}">
-                            <File Id="fil423846B9A493FEFCF921A54B049F2F73" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-databind-2.1.1.jar" />
-                        </Component>
-                        <Component Id="cmpC4FA047DBF629800E5F825023F3DB2E5" Guid="{32A02A01-9F92-406D-A841-51A1A5DCD768}">
-                            <File Id="filBB66AAE9409D5003A9BA3F1336CC5143" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-jaxrs-json-provider-2.1.1.jar" />
-                        </Component>
-                        <Component Id="cmp40E3623765774C3007055646CB0B5CA8" Guid="{D01D9638-F0A4-4E98-81D0-A6362336665A}">
-                            <File Id="fil35F5491947EBA1CE19C0EDCF661D14A4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-mapper-asl-1.9.3.jar" />
-                        </Component>
-                        <Component Id="cmpC34B337EB9BE0D3F92498818BDB6D4B8" Guid="{0913659D-3E68-4C68-8756-5338AD87FF88}">
-                            <File Id="fil48FA51E3DD79B7C9D1227F5C14AF1E16" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jackson-module-jaxb-annotations-2.1.1.jar" />
-                        </Component>
-                        <Component Id="cmpB461DFEF3B05553DE179C1A846F3FF87" Guid="{35A17A68-E6CB-4D49-9B90-A11E904E185E}">
-                            <File Id="filE15E39FEEA47584E295154E280235A62" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jasypt-1.9.2.jar" />
-                        </Component>
-                        <Component Id="cmp18523225741C1B62B821A603B4785A02" Guid="{30FA0BF7-E64F-43EE-8004-0D521C648B40}">
-                            <File Id="filBF2E885F28757D248A6061B3EE3A3831" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\java-ipv6-0.10.jar" />
-                        </Component>
-                        <Component Id="cmp42EC75447FD0FA6501A396F1B6AEED1E" Guid="{940ACD69-B16D-47F6-8EC4-5676096D0F62}">
-                            <File Id="filB68F896C299DBBF4A14DA3FF1188CC5F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\javassist-3.12.1.GA.jar" />
-                        </Component>
-                        <Component Id="cmp8527B9F7536DDAD1A6B2EE190C919F89" Guid="{6B1F2F03-8B13-4EBB-BF1E-3123A6E5D214}">
-                            <File Id="filA1A64CF8C379102E7BC31992B1FF7365" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\javassist-3.18.1-GA.jar" />
-                        </Component>
-                        <Component Id="cmp7338F5B47C99ECFAE998650D3E5470C6" Guid="{25859630-2415-4F55-964F-29BF220AC154}">
-                            <File Id="fil5C7E8F69C91855C8EF1EF3D8B6A580A8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\javax.inject-1.jar" />
-                        </Component>
-                        <Component Id="cmp78A0205F4E525EE76ACF64EFBD247CF4" Guid="{60C848D7-165B-492C-A7A6-2ABAEA7516DA}">
-                            <File Id="fil0696501F24940C2C08737057337BEF60" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\javax.persistence-2.0.0.jar" />
-                        </Component>
-                        <Component Id="cmp1A634B87498A4ECBC74CC11022122FB7" Guid="{0416A36A-CBDF-4B69-923B-08A27B182656}">
-                            <File Id="fil2A642FF20B9F90CDAA0AD4226417F848" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\javax.ws.rs-api-2.0-m10.jar" />
-                        </Component>
-                        <Component Id="cmp19F8CCB28022D4162CD6FFF29BAC0D0F" Guid="{9AB07283-F6E4-4912-81DB-E2826E8E3D3E}">
-                            <File Id="filB577F775B04F02B0DDFA8FC93A32F07D" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jaxen-1.1-beta-8.jar" />
-                        </Component>
-                        <Component Id="cmp0FD86CA93873A376079A34ADB94D9867" Guid="{17DD314E-2BDA-4E9E-95DB-55EE5843881D}">
-                            <File Id="filA84DC362F639113C5428899B1F72F26E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jdom-1.0.jar" />
-                        </Component>
-                        <Component Id="cmpFC5CB0F3E6908AA7A765BF8F4C0D0B02" Guid="{2B3613AC-C186-47D0-8B95-B5ED83B11DB1}">
-                            <File Id="filC88EA950B8C36452C65462985C23D381" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-6.1.26.jar" />
-                        </Component>
-                        <Component Id="cmp10B512385CCF7F61FFFF695BC4E8065D" Guid="{C8B96FBC-EFF4-49A4-9A12-BC069D87EC72}">
-                            <File Id="filB79792F1C046459265BBEBB106EBBC74" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-continuation-8.1.7.v20120910.jar" />
-                        </Component>
-                        <Component Id="cmpF1BC23977D0A9D0287CBDE0C5CA6A73B" Guid="{F6F31C0F-3573-4EAE-90FE-30250112FCC9}">
-                            <File Id="fil83B92C1ECE9436DFA9ADE6ADC8508347" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-http-8.1.7.v20120910.jar" />
-                        </Component>
-                        <Component Id="cmpDC338323A2F5AAC888FE495B1D0CF1C7" Guid="{CA1524DE-0A9E-462D-975C-E5D5463B8417}">
-                            <File Id="filF4C35B9B4315249265A13BED6D26306E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-io-8.1.7.v20120910.jar" />
-                        </Component>
-                        <Component Id="cmpC4C3F4AAB9EC442EF62C8FB38EFF44FE" Guid="{7BD30B52-D921-4A80-B255-DD161280E440}">
-                            <File Id="filFD6B6D4CA38EC2E8CEFA551FE9A498FA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-security-8.1.7.v20120910.jar" />
-                        </Component>
-                        <Component Id="cmp8757A1DAFCE48504153F9107D6164B02" Guid="{96EEF1F2-4C7F-48CD-B140-AF55A5E5B0FE}">
-                            <File Id="fil38B5641C8AC6BF1BA9604B9AD8D794B0" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-util-6.1.26.jar" />
-                        </Component>
-                        <Component Id="cmp48265CD12FCB09ED767A666BEC8EC00D" Guid="{4F5D055F-81B0-4683-A9AD-045B8D28451C}">
-                            <File Id="filA4CBB388D86635D753EEC364447E6A63" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jetty-util-8.1.7.v20120910.jar" />
-                        </Component>
-                        <Component Id="cmp84109123CBE829CC642B7E39E1B5C836" Guid="{913B561F-22AF-4447-A06E-ED28ABB70768}">
-                            <File Id="fil44AA658E3308D7616C576D362E1C4FC4" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jna-4.0.0.jar" />
-                        </Component>
-                        <Component Id="cmpF5E9A752898E9028B0FDFF323F4DEA99" Guid="{A2D36E1E-92B4-4D31-9FE3-8B4CB68368BA}">
-                            <File Id="fil2076DC84A27159F038A8087D36CD2F4B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jsch-0.1.42.jar" />
-                        </Component>
-                        <Component Id="cmpECC9BFD70050CF5CBB298151CC107DD0" Guid="{1C3DE308-474E-4EEF-88CD-DA1BD546AB97}">
-                            <File Id="fil44A3D079F2D3DBE64CB5382027D9EFBA" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\jstl-1.2.jar" />
-                        </Component>
-                        <Component Id="cmp81E203B48ABAD7F52FAF852F7A12145D" Guid="{A6881EC9-C296-48DC-A30C-F0EF0FCAB9AE}">
-                            <File Id="filE90CA6329C56E3CBBD9B484821A01789" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\juniper-contrail-api-1.0-20131001.003401-3.jar" />
-                        </Component>
-                        <Component Id="cmp445572727EA15EB11747C585C114A34C" Guid="{1531D6CF-467D-475C-BCFB-F9D0705CC7C5}">
-                            <File Id="filC4A1FC40379565D8F6A2CE9960B6746B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\junit-dep-4.10.jar" />
-                        </Component>
-                        <Component Id="cmpDB06F91B079F2960625DEBD3F94C2CEF" Guid="{B56EB0A8-02DC-4AAF-9C28-419C870292A5}">
-                            <File Id="fil31990D1934CCD79763130578F12D9D42" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\libvirt-0.5.1.jar" />
-                        </Component>
-                        <Component Id="cmp2FE756BEA5670737A739E40895AF7F92" Guid="{02B29852-F447-489A-A86D-2CE6D15B3235}">
-                            <File Id="fil4EF876373882EAE72AA42C9ACF751DBD" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\log4j-1.2.16.jar" />
-                        </Component>
-                        <Component Id="cmp6114379A976905B2F2770C6E5934AC79" Guid="{8CCECB3F-062A-439E-863E-950BA2B0062F}">
-                            <File Id="fil6A0D7E786C6E6FD2FF2C2D52A4A7FB3E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\mail-1.4.jar" />
-                        </Component>
-                        <Component Id="cmp2210FF2D22610D7C6B5B50F74A6CCFF6" Guid="{8B4D96E1-E8D0-415D-BC1E-0D6B9C2896EB}">
-                            <File Id="fil79A9A35E5D30D89644135E92F334EBC6" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\nekohtml-1.9.12.jar" />
-                        </Component>
-                        <Component Id="cmpFD000330960F806FBE824963957BF7AD" Guid="{11984FB2-2902-400F-96BA-397FD9E8D5B4}">
-                            <File Id="filD16F188C9CDB33F291304D7ED5DA9AC8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\nitro-10.1.jar" />
-                        </Component>
-                        <Component Id="cmp977CF1BC61468FC27B11A540213FE9A5" Guid="{B65A758D-5375-41B4-87F5-4527D6FB4A43}">
-                            <File Id="fil2FD74EA3B30C085078E86D5E04DF56C5" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\objenesis-2.1.jar" />
-                        </Component>
-                        <Component Id="cmp6E4E148E6DE4226B3D6018D8ABE03CF2" Guid="{6C204CB1-BEFB-4275-ACE7-CA54B2F67401}">
-                            <File Id="fil372738C111C4ED6130FC38BE0DE2A97B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\org.apache.servicemix.bundles.snmp4j-2.1.0_1.jar" />
-                        </Component>
-                        <Component Id="cmp9F0F75F617461065DC10DB27BEA1FAF7" Guid="{2EA942E3-6AA6-4324-9DD3-62A048FC5ABC}">
-                            <File Id="filFA487085997D56DB974AC135A4018A27" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\powermock-core-1.5.3.jar" />
-                        </Component>
-                        <Component Id="cmp43FD59D64A3BDA21A1D6F7CEACE2B2FC" Guid="{CCA3990E-F399-4EDB-9495-C9B3158C8A86}">
-                            <File Id="fil4928A11B2EB19B256C2EA71CCCADD90B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\powermock-module-junit4-1.5.3.jar" />
-                        </Component>
-                        <Component Id="cmp4B06F6782804926721B71B853306D808" Guid="{4722738C-BC8A-4F55-8F18-427192462560}">
-                            <File Id="fil92E15601D4276BA8C8D595B55BD70F0C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\powermock-module-junit4-common-1.5.3.jar" />
-                        </Component>
-                        <Component Id="cmp5FEC4120CA054CAB736D40A02B797314" Guid="{591AC6D0-BDB4-425D-8876-71632AE543C0}">
-                            <File Id="fil99CD89B626561DF6F16DBC6F5A32BC3E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\powermock-reflect-1.5.3.jar" />
-                        </Component>
-                        <Component Id="cmp7EF50603559988206A20CF4EFCB03A73" Guid="{A76D8AF7-D653-4D9E-9F52-288C1C8B4BCF}">
-                            <File Id="fil3485D156470EF9609D7BEFDE7FB58D40" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\rados-0.1.3.jar" />
-                        </Component>
-                        <Component Id="cmp42FCB77155A6498CAC4AE0DDE075085D" Guid="{58D7F564-78D0-4EB9-815B-FCF4654C4108}">
-                            <File Id="filCE6912ECF9714BFC43A49A55EA236A99" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\reflections-0.9.8.jar" />
-                        </Component>
-                        <Component Id="cmp7CF8F89A55C985FF68A0C8F2D75BBB1A" Guid="{B7AC5D5D-A7EE-40F2-BB3A-D0187956A2EA}">
-                            <File Id="filB69F5D73B10A43EE4B439BED098F7044" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\scala-library-2.9.2.jar" />
-                        </Component>
-                        <Component Id="cmp6CDF7ADA601388F2E1A733F8E4F0C36F" Guid="{9A49E4F2-E819-4507-9E4D-48E840206634}">
-                            <File Id="fil4E53B4D09319590BCAD389822AD37C49" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\sdx_nitro-10.1.jar" />
-                        </Component>
-                        <Component Id="cmp13F40EF7ACA81350C4F8E813736A2CAE" Guid="{F9B9AE15-A292-41A1-830F-5515977D2100}">
-                            <File Id="fil34FB2D991F3071B2EF73946CB0431D34" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\servlet-api-2.5-20081211.jar" />
-                        </Component>
-                        <Component Id="cmp8CBA9E0D91DF8138E2BF1EEFE71BC07D" Guid="{FA12FAE1-F600-450E-A3D8-F455EA4BAF5D}">
-                            <File Id="fil168484CFF129899A7D518AFE187E4127" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\slf4j-api-1.7.5.jar" />
-                        </Component>
-                        <Component Id="cmpD51A9DB18A9C78D3F72950E5F2EAB25D" Guid="{BAFB763B-69F2-42BB-A152-C59064D2CD5B}">
-                            <File Id="fil16A4FB967AF2762742B451B2B67CC207" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\slf4j-log4j12-1.7.5.jar" />
-                        </Component>
-                        <Component Id="cmpF1031D7436E22BE80D98DE4EB55C7BE3" Guid="{77B3F71F-111B-45AC-A7FB-FEFA507F7D7C}">
-                            <File Id="fil532C144DF3AF862A6374F54E37FFBB6B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spock-core-0.7-groovy-2.0.jar" />
-                        </Component>
-                        <Component Id="cmpDC7CEE74CD7B941AE4E790290079486B" Guid="{4D37B6B7-A9E5-444A-AC48-8EBDDADF3162}">
-                            <File Id="filEB2B01DD1911C665D7D4E89AA922A8D1" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-aop-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmp5BD19F0B4F145CAB9447EBFFB74FC057" Guid="{F08C0565-5034-4D5E-AA49-F5338ED522B4}">
-                            <File Id="fil253CD8F4C3303DF3979ACE2E022F250B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-beans-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmp6E4587E33E92248D1DF802D18D6674EB" Guid="{900F61E6-AA63-4EA5-BD9A-D0103B4EA3AC}">
-                            <File Id="fil514F0DA07A172DEE2E86504C20E3E414" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-context-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmpED118D724F550278A6A5906B4C5570FE" Guid="{65E4B4DF-3E00-4039-AE6D-41415D65E9B5}">
-                            <File Id="filCA1B23449E90526CF78F84B1C642AA80" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-core-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmpF7BF21EAAE348BE08F20AD4FD885B632" Guid="{48792926-5255-4354-9A6C-C14AF6B72343}">
-                            <File Id="fil162CBA0C32C8BC96CC3C4A64C28D72D8" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-expression-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmpE267BC074E9FF03E8FEC15F90F6AC3C5" Guid="{58DBDF8A-070F-48E5-97D6-01F3BD2D72CB}">
-                            <File Id="filCF5A444BF9810AD18166090D3E18A830" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\spring-web-3.2.4.RELEASE.jar" />
-                        </Component>
-                        <Component Id="cmpFC79ECC8852090269FFFB4ED834C20B0" Guid="{ED7C1CC1-940F-426B-8AC3-DB8FA9CA37A9}">
-                            <File Id="fil16DACD795474F719F3C71356022B7E3A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\stax2-api-3.1.1.jar" />
-                        </Component>
-                        <Component Id="cmp2781812D9B5A646D9B6C89E3C24629B7" Guid="{C029BE6F-07DF-4B94-A5C0-FF135FEDD5E3}">
-                            <File Id="fil539419560DA5E0E35D304BDF470D8BE3" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\trilead-ssh2-build213-svnkit-1.3-patch.jar" />
-                        </Component>
-                        <Component Id="cmp3A1296CF9D53E1837B569C22EFAB288A" Guid="{FB73C9A4-9B20-4473-A80C-FF5B9C5A4840}">
-                            <File Id="filF0AF66DC4619D740935480DAE81ED615" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\woodstox-core-asl-4.1.4.jar" />
-                        </Component>
-                        <Component Id="cmp95D4B8057C5B721A30CACE10EDFE7BAB" Guid="{6DE5721C-54A5-459A-9E37-163F4A995F39}">
-                            <File Id="fil3F65E7F62512AD0EC8D8F9D53EB30EB7" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\ws-commons-util-1.0.2.jar" />
-                        </Component>
-                        <Component Id="cmp5BFBD111D93716502AFE619ACC3AF188" Guid="{C09631EB-40C9-4738-B8FE-E7BFD7F8C446}">
-                            <File Id="fil1B39215B251D6B686F620D64E573D9D6" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\wsdl4j-1.4.jar" />
-                        </Component>
-                        <Component Id="cmp79CCF2A220914A861D556F8ED2C42745" Guid="{29045E9D-7A52-45A0-AA08-2EA2FB177901}">
-                            <File Id="fil99FB155CDF9E50509BABB30EC6FC833A" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xalan-2.7.0.jar" />
-                        </Component>
-                        <Component Id="cmp0E31DE92033E0CBE7A7217B8BF3B2192" Guid="{26310D7C-4798-473E-87A5-A54107C73E0D}">
-                            <File Id="fil975374969986BB79046CA54893D3049C" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xapi-6.2.0-1-SNAPSHOT.jar" />
-                        </Component>
-                        <Component Id="cmp0B6AD54A7D460A737BEDE06A452C5A57" Guid="{2504FF2B-0013-49FD-A95E-1B7C1921F8ED}">
-                            <File Id="filCEBD6A5E0C77DECF3A02D580756DB626" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xercesImpl-2.6.2.jar" />
-                        </Component>
-                        <Component Id="cmp97CB02F5412B596F2D6E3A11DA18D3C1" Guid="{9B2676B7-C9EA-4291-BDE3-FCF992D25934}">
-                            <File Id="fil6D908A176836972B864DA79876794C68" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xml-apis-1.0.b2.jar" />
-                        </Component>
-                        <Component Id="cmp48635F1A52681F2B64D6C793909BE56E" Guid="{988C2AFB-EF4E-47BC-89DD-B174D1D584DC}">
-                            <File Id="fil1CC97ED851B03C07D36273E6623F8257" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xmlrpc-client-3.1.3.jar" />
-                        </Component>
-                        <Component Id="cmp6D3E0478E079025DA610BC77ED644157" Guid="{8D250EB8-9B51-4460-B9FB-E7008071A9D9}">
-                            <File Id="filDB6BF4A3E1D1EBA02246617D48446FDE" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xmlrpc-common-3.1.3.jar" />
-                        </Component>
-                        <Component Id="cmpB0CEEF7086AED7FCC4AC1755ACEB99B2" Guid="{F21ED8F5-5BB8-4882-9B81-EB719CB22D92}">
-                            <File Id="filAA0BD6687F2C6DF2E50D0D2C5BC31B7F" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xmlschema-core-2.0.3.jar" />
-                        </Component>
-                        <Component Id="cmpED6FE496E5E9498709BCA934064A975A" Guid="{956805D7-1B17-451F-8E38-E84A3626A245}">
-                            <File Id="fil42F13B27CA06BD450638EE60F53A3C8E" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xom-1.1.jar" />
-                        </Component>
-                        <Component Id="cmp1F284CA13DFED796A81F16057684AB91" Guid="{5F0705EE-3676-4276-9DCB-F012C6064FAC}">
-                            <File Id="fil9B476A2C94FF974D134677A1FF29708B" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xpp3_min-1.1.4c.jar" />
-                        </Component>
-                        <Component Id="cmp776899723BBC0C56DBF1EA389CF3A210" Guid="{E3DC45BD-DDB6-4F54-BF10-7E2508611DF3}">
-                            <File Id="filAC167FEB9189F1B82FF42EEED964A292" KeyPath="yes" Source="!(wix.SourceClient)\WEB-INF\lib\xstream-1.3.1.jar" />
-                        </Component>
-                    </Directory>
-                </Directory>
-            </Directory>
-        </DirectoryRef>
-    </Fragment>
-    <Fragment>
-        <ComponentGroup Id="Test">
-            <ComponentRef Id="cmp6F4C0541A24255F55077C2F2B9EA1716" />
-            <ComponentRef Id="cmpA3EAE442A4EFCD423DEDE8C08275003B" />
-            <ComponentRef Id="cmp37A6D01A784CC885922881D8CC3D5BB8" />
-            <ComponentRef Id="cmpFFAC5964C1B559F5D69E9D45D9C147B8" />
-            <ComponentRef Id="cmp694FC18AC73FEF24D97069F52AD9FC09" />
-            <ComponentRef Id="cmp4A4973B4BE51E3359E297E244D879F48" />
-            <ComponentRef Id="cmpDBAA10EB0F11FA1B83B24A565C454890" />
-            <ComponentRef Id="cmp001D278A449DA222443DC90C6457A0AA" />
-            <ComponentRef Id="cmp699EE66392E8BD62181283BAE3FB8A3C" />
-            <ComponentRef Id="cmp921798715C11FE6C4CE02C5309FA4E59" />
-            <ComponentRef Id="cmpA7AB5C816F498D515EF3D5FEFD8AA456" />
-            <ComponentRef Id="cmpA6A6B22DF0B4E7A221B70046072548D1" />
-            <ComponentRef Id="cmp9B3691B822E42D11260A4FB1DE736FA0" />
-            <ComponentRef Id="cmpFFF332A3880849A88855CEB2A49000E7" />
-            <ComponentRef Id="cmpE4B5129BCDF4B9ED1D2DF7DAE896AA55" />
-            <ComponentRef Id="cmp61E30D6E1FAB09EEFEAA7BB50D4DA6AE" />
-            <ComponentRef Id="cmp2A053A866278B8A6435A28079840599C" />
-            <ComponentRef Id="cmp41626A79664D471C942B94A6FAC377BF" />
-            <ComponentRef Id="cmp77D0E13995B729E5D67DC50F7F03DDC4" />
-            <ComponentRef Id="cmp4B1487196540475DE85D83ED0B51DAA0" />
-            <ComponentRef Id="cmpE88A7C334F758F267F3BDA672BA3AD6F" />
-            <ComponentRef Id="cmp84A913BC71DEC23505B0183AACB43169" />
-            <ComponentRef Id="cmp358AF2CBCCDEAC74EF66C31443B9D4E1" />
-            <ComponentRef Id="cmp9B65184EA19EE89FC312A37AB40C5445" />
-            <ComponentRef Id="cmp953E9ACBDC0C9E8F5837FC99DCF65348" />
-            <ComponentRef Id="cmp5BF1C740060955320D9F6A4404B1742E" />
-            <ComponentRef Id="cmpCD524965EE7D3214479C877D436CC25A" />
-            <ComponentRef Id="cmpD08BCA99B074021280E10519C324E790" />
-            <ComponentRef Id="cmpC16293201DBC9EEF704B7D3B9DA097CB" />
-            <ComponentRef Id="cmp45543CFA36099C39924B174C1D06A2F1" />
-            <ComponentRef Id="cmpEA04275836D88C5DF7EDF8B24FA0C22E" />
-            <ComponentRef Id="cmp0807B9D5A46B8F0627ACB71BBF6F3ADE" />
-            <ComponentRef Id="cmp8B663F769A8343653753167A023E9E89" />
-            <ComponentRef Id="cmpE34BE2B5CD323AB1181EE3D32B6910EC" />
-            <ComponentRef Id="cmpE629675B5F3B5CA6475CA28737C0FAF3" />
-            <ComponentRef Id="cmpD931241918C8FF9464A80E5CAC921D3A" />
-            <ComponentRef Id="cmp10C8FC6390A7D19DF2A617E23302283C" />
-            <ComponentRef Id="cmp175AF405CD11833706ED0B4BF04D274F" />
-            <ComponentRef Id="cmp8420DC36BDC63CE6EE2175BDC6E3943A" />
-            <ComponentRef Id="cmpAC8E67BEE6565E3D40EB67A5FCC98BDA" />
-            <ComponentRef Id="cmp740C60E545740A698D5A83B500C1F659" />
-            <ComponentRef Id="cmp5A56787A0DA3FFB130E197ADDA23A0EB" />
-            <ComponentRef Id="cmpBD296011450DE1C0F11EB0FEF5A16BF6" />
-            <ComponentRef Id="cmpD0010246D4D646A7DF9D13E15F62B5B5" />
-            <ComponentRef Id="cmp05395AF83519A533B996404D969144D4" />
-            <ComponentRef Id="cmpE610FEE8B4F764BC61663BCD33BBA8EA" />
-            <ComponentRef Id="cmp446041577F864F066778735CF97B5941" />
-            <ComponentRef Id="cmp786E699F246B34397B746A15229CAC53" />
-            <ComponentRef Id="cmp8D551322C3C213DE03E2DFE8BE12CAAC" />
-            <ComponentRef Id="cmpDFC1633A7E3A2ABB11BAA927DFF04539" />
-            <ComponentRef Id="cmpEEAF53A0C8D3FDF8D9E19F3E48F25343" />
-            <ComponentRef Id="cmp6E186870ED4CF468177D7449592B651D" />
-            <ComponentRef Id="cmp1C89ADB77497A7903954C1555FE7D35D" />
-            <ComponentRef Id="cmp033EEE431FC34259BCA1CE1B246E50F4" />
-            <ComponentRef Id="cmp7865CDD031C64E5AEDC50272B49AA499" />
-            <ComponentRef Id="cmp04B51493F14AA2382A5B8D75BB3170AE" />
-            <ComponentRef Id="cmp187709B7088A01D462071B1644DAD507" />
-            <ComponentRef Id="cmp689360BFB1D005F5469B2730AA0EF66E" />
-            <ComponentRef Id="cmp831CF8B3F03EFC9A514B88D6AEAC5EA3" />
-            <ComponentRef Id="cmp231E06009CE8D54EB43B03B874D21646" />
-            <ComponentRef Id="cmp00BB4BE58D1A66E07317350D9999B0CC" />
-            <ComponentRef Id="cmpDC1A3A44EFC7FCB16C43B4F459AA9FB5" />
-            <ComponentRef Id="cmpB763DE9DB6AF82BBA5744D06091343F6" />
-            <ComponentRef Id="cmpDBD014AE3828B43403B00C725132A8A8" />
-            <ComponentRef Id="cmpC8C9422F944488300ECED38E3C3D34C1" />
-            <ComponentRef Id="cmpF943BE2250F49DDF684BC013C6CB6569" />
-            <ComponentRef Id="cmp6DF1AAE5A63AABEF6537A99FE211CA0C" />
-            <ComponentRef Id="cmpEA38A56F0EBF3FE9A671A194C32017C1" />
-            <ComponentRef Id="cmp14ED72882E41B88D5EF5D952A43C4804" />
-            <ComponentRef Id="cmp4E0D9C2555CBECEEC98E424A8D7152AF" />
-            <ComponentRef Id="cmp0CD21657758E9F190713A971C7035A72" />
-            <ComponentRef Id="cmp6A605303F9FDDF9ADC6FE9B1223985ED" />
-            <ComponentRef Id="cmpBD07E88166153AF0733F4D0D1BBAD82D" />
-            <ComponentRef Id="cmpB1A795AD8630C8AA4ACBCA057CADD8F9" />
-            <ComponentRef Id="cmp5C4C9F9823053BCD798D1613E8B706F9" />
-            <ComponentRef Id="cmpB896F9C9402F7ED2A5A73E7E72AA47EC" />
-            <ComponentRef Id="cmp6BEE710358ED5D0560BAEA9B4BF6830C" />
-            <ComponentRef Id="cmp21F37DDAADFFEE972EF4291DE2C0E6CB" />
-            <ComponentRef Id="cmpE4F2B110A7EFD179E687179AE1AA86A2" />
-            <ComponentRef Id="cmp818FCCB7641D478456749FAA06AE6D5C" />
-            <ComponentRef Id="cmp44E96AA22DDD71CB6D2AF9F0E94D900A" />
-            <ComponentRef Id="cmp9F07D2C402E481C9A32B832E9767F54A" />
-            <ComponentRef Id="cmp4F8EE7EF5CC235B975A88C5F5F7EADB1" />
-            <ComponentRef Id="cmp0BF64BE05CC2A27F7E3AA10F198E7258" />
-            <ComponentRef Id="cmp097C9AEBBD0BB12A63B41A5505EABF92" />
-            <ComponentRef Id="cmpF4E73A2FE6A8101861EBB6248B78CDB9" />
-            <ComponentRef Id="cmp17CF84538B1BCD9FF96FBD0F636410B1" />
-            <ComponentRef Id="cmp27075FFB9AF246A5F27D1B07E59E4807" />
-            <ComponentRef Id="cmp23B407781C5AA7099F7779F0EC9E5239" />
-            <ComponentRef Id="cmpC00F3D14E656727772C11FADE4C236B2" />
-            <ComponentRef Id="cmpA0734BF7F3979F291D1861DF998DADA5" />
-            <ComponentRef Id="cmp9F3BE4D0A2BC109FDC307245FD9C487F" />
-            <ComponentRef Id="cmpA3E293FCC7C5356BDED5B30A37517512" />
-            <ComponentRef Id="cmp1EB24C356668590C2156DA852D3E04C2" />
-            <ComponentRef Id="cmp69189CF65055ACEF36D3DA311FA5E6B8" />
-            <ComponentRef Id="cmp25D9C3278F2FF022D355CA0E26495B38" />
-            <ComponentRef Id="cmp29B4FFC9E3E81907422629F0A64A6B4D" />
-            <ComponentRef Id="cmpFFE7740FC808DE88252FBD1E541F28F3" />
-            <ComponentRef Id="cmpBEFA0A936EC6C24EF1112AE72CD61E90" />
-            <ComponentRef Id="cmpB6FD567D23676EEA6FB33FB954C3E00F" />
-            <ComponentRef Id="cmp64355DC217B30E7012C07D40333380D3" />
-            <ComponentRef Id="cmp71B587FC4088B246C47FCD85A8E0C6D2" />
-            <ComponentRef Id="cmp91BC0E1B2F9438BC80B02A38A7F72F7A" />
-            <ComponentRef Id="cmpFC9FD39E7A2F82765B9975065575928B" />
-            <ComponentRef Id="cmp8FBD6D5AAC5F5BB99F10BA21DE8F9EE8" />
-            <ComponentRef Id="cmp1E5D206123A3BC88E972FCF814B06E05" />
-            <ComponentRef Id="cmpDFFE3D29580C2378FAB3CE1D144FD7D8" />
-            <ComponentRef Id="cmp82C3F50315407D120182200AB9F70C04" />
-            <ComponentRef Id="cmp7E0B8E6682A13E7F5222A719C3BD6DE0" />
-            <ComponentRef Id="cmpF8FB65C9B2E8B4CA81CF005A8308516C" />
-            <ComponentRef Id="cmp70B80107582ED947DEF51FB85F74D03C" />
-            <ComponentRef Id="cmpBF1674BFAE638BF0B6EB4ED6F1157FFA" />
-            <ComponentRef Id="cmp11BE4ED125E10FA252A41F17998879B1" />
-            <ComponentRef Id="cmp3521D3A9B398D6073FBCCC5D8C0D0077" />
-            <ComponentRef Id="cmpFFCFF1C360D93AF74355153604851D18" />
-            <ComponentRef Id="cmp70683C01637DAB3762D887EDB06168A2" />
-            <ComponentRef Id="cmpB96CE3716DAA36ADE4DAFCD51A87B4D0" />
-            <ComponentRef Id="cmpA2A6D7B4BA824E50D0EFD42527A7889E" />
-            <ComponentRef Id="cmp2A4F0744CB415C1A1E484583EF6908DD" />
-            <ComponentRef Id="cmpADB85FE75F1142E56C7DD6DB7A325155" />
-            <ComponentRef Id="cmp3B63120621FD8E9F4036253A7F33F516" />
-            <ComponentRef Id="cmpE36D2A9C60AE213D91AD0E455BF4157D" />
-            <ComponentRef Id="cmpCCA2B5E63007166F334A93C0A3D70D2B" />
-            <ComponentRef Id="cmp97384255BE6A3A2E252A58B7E6B84244" />
-            <ComponentRef Id="cmp795066333B7111FD07AF5A0256019D88" />
-            <ComponentRef Id="cmp03847F93944302017867D0F358940ECF" />
-            <ComponentRef Id="cmp266156DD56681FC28B33AB3E70356D5D" />
-            <ComponentRef Id="cmp226A0ADC9F26A371E720DA01B886F58C" />
-            <ComponentRef Id="cmpF77738DC56C492684C7A2CA2164907CA" />
-            <ComponentRef Id="cmp71D078D75E83971F80181453EA717D8B" />
-            <ComponentRef Id="cmpD605A23799365004C20E5DE80CA738F3" />
-            <ComponentRef Id="cmpA9C076F1199B904BB57D1BC96A919814" />
-            <ComponentRef Id="cmp429AD4BBE2ABA44D598EF5DC4482C2A4" />
-            <ComponentRef Id="cmpA7B70148FAF23BE9246895B84B8E76EE" />
-            <ComponentRef Id="cmpA09401C5AC6539FD960D21860A2494EA" />
-            <ComponentRef Id="cmp4EF2024F5F084664B8B4EA6D2CFC68B7" />
-            <ComponentRef Id="cmp61D0B06384E21EFA69C902826FD73A38" />
-            <ComponentRef Id="cmp0829D8177E15FC4F2BA8ED14D52D90CA" />
-            <ComponentRef Id="cmpBE4BD9E19AA1B818D76F55E6388BFD8F" />
-            <ComponentRef Id="cmpA4E356780616647ED7B9BFAE5A1A7117" />
-            <ComponentRef Id="cmp7E9F0B69583DCA396CE7F30A896CA5E6" />
-            <ComponentRef Id="cmp41265EE80AF4DD4A030DA0E2BBC68E25" />
-            <ComponentRef Id="cmpF767C585B98E892E3167E0B1CA2790BC" />
-            <ComponentRef Id="cmp4F98C4132544C7A2EB9AF9C27B97257C" />
-            <ComponentRef Id="cmp7D8D9B42874FEBF3F83B13A84E11D79D" />
-            <ComponentRef Id="cmp01AA5255FB5F7C824120B3F35022DCD5" />
-            <ComponentRef Id="cmpF709188CACE4EB7654441941ABD3D0A7" />
-            <ComponentRef Id="cmpFBDE9C88FF99E26BFAC1A5480075BB2F" />
-            <ComponentRef Id="cmp9C3FA328BFF88944027D79762D7A8E6D" />
-            <ComponentRef Id="cmp94D127FCD06877FB65758B769C1DDD8C" />
-            <ComponentRef Id="cmp8BAC7A532526B4BF203359AE42CDA911" />
-            <ComponentRef Id="cmpBD978DAEEFD6AB3B0CB66F1FA461D775" />
-            <ComponentRef Id="cmpC6F1953E0BCC28D4D367E85ADC1FF702" />
-            <ComponentRef Id="cmpC9EBCA902295AD3F9BF6AB2EB75FFF8C" />
-            <ComponentRef Id="cmp45F812B0EEB2FF44A944F306FDBC57C0" />
-            <ComponentRef Id="cmp4872730BA0FC976224C05FE06E381E31" />
-            <ComponentRef Id="cmp5D7EB210DC50AA3161B95938D7A0BB16" />
-            <ComponentRef Id="cmp33EABAC11FAC83EDCC1ED5640E292A0C" />
-            <ComponentRef Id="cmp4CD4F8D47D84C109495D6E245CED0FA7" />
-            <ComponentRef Id="cmp766E41E0F210B801B4EE739E08E0920C" />
-            <ComponentRef Id="cmpA1EABBABC942D35B436FA9ED8E174B60" />
-            <ComponentRef Id="cmp46E2A160E5F1D33CED3CB9F39159115F" />
-            <ComponentRef Id="cmpA7486FA646A489E4E9E0A0B30783E6E5" />
-            <ComponentRef Id="cmpCC8A03A9B688F7BB0A91B5F7264C8941" />
-            <ComponentRef Id="cmp7C025B152163775F85356F0B6C812D52" />
-            <ComponentRef Id="cmp25B1D1B85D37B354846A49BBFF8DB9FD" />
-            <ComponentRef Id="cmp8D8319A1256FB3429270859E27C12621" />
-            <ComponentRef Id="cmpE7164AA2D9D19D691D0554B6F74B1DD1" />
-            <ComponentRef Id="cmp74950FBBDFC57288378F498E441E96A7" />
-            <ComponentRef Id="cmpB1548E0108F070E8FC0731C1D5CE1181" />
-            <ComponentRef Id="cmp55555C69B341A99ECB90776D1DAC7D85" />
-            <ComponentRef Id="cmp872A612056CDE5E1684AC32A97F88956" />
-            <ComponentRef Id="cmpA037346F54E8A743265C825D1126556E" />
-            <ComponentRef Id="cmpBB0E4B6A05AD9BFB21C53A03E46EB959" />
-            <ComponentRef Id="cmp64EF6F10E4ED683EF1866F86EA7D82B7" />
-            <ComponentRef Id="cmp1026E203EB573420EDAB14EF796B6C88" />
-            <ComponentRef Id="cmpDF564722C878E924F38CCDFA7BD81097" />
-            <ComponentRef Id="cmp6001B626D853C4E4FAB8511246B8D2B4" />
-            <ComponentRef Id="cmp71D36BFB6B214FAAD323C31A1CE3BC19" />
-            <ComponentRef Id="cmp19EB0E73466EB36D5AA02AB4CE8164B0" />
-            <ComponentRef Id="cmp68E096BB729948107692341D8202CC5A" />
-            <ComponentRef Id="cmpB674D90EF1AF37E18CC8649284DEC01A" />
-            <ComponentRef Id="cmp08271F681E20C14F2F4B84AFEEC46BAE" />
-            <ComponentRef Id="cmp37A1B9AB80FBE69A9DC16D2D96BA27C1" />
-            <ComponentRef Id="cmp8417A84DFEA479A7505FFB98ED1CE09A" />
-            <ComponentRef Id="cmp6FFD5CD504EEC83740F144C8E87014BF" />
-            <ComponentRef Id="cmp2734DCABBEDCAEEC6365AA1B2C22DAB1" />
-            <ComponentRef Id="cmp0102E6CEE7A7861807FB2772FC0CF208" />
-            <ComponentRef Id="cmpD938A1152E4F900871FFBA1F13FE9EE8" />
-            <ComponentRef Id="cmp1F0FDAF8DB4977D61A66753FC97B0887" />
-            <ComponentRef Id="cmp7848326F517F9EE4782465AAE6BA262D" />
-            <ComponentRef Id="cmpEECF5D798BABA658F7C46D7F1E99E796" />
-            <ComponentRef Id="cmpAA0B38429C92CED7D753A20E7381081E" />
-            <ComponentRef Id="cmpC8FFCE17A77CF63EA38472FA15224A37" />
-            <ComponentRef Id="cmp1FEC3E51749CAD255A2B50C1B8F56C4B" />
-            <ComponentRef Id="cmp22C74DFC2BFBBA9CE414AEC0A29B43CB" />
-            <ComponentRef Id="cmp2C8E3B1A8BF07C9A1733044B175992D8" />
-            <ComponentRef Id="cmpE2AAA9885C512D29CE51E1DCCFE1D960" />
-            <ComponentRef Id="cmpD91640D74ABBF96CFF2EAE943B35A801" />
-            <ComponentRef Id="cmpD92CE1E0C057288E3D4FBBDD7F9B311B" />
-            <ComponentRef Id="cmpB5DFC53BF25E0DDCA32F21E08BD48FA7" />
-            <ComponentRef Id="cmpA6FB554ADD7936CC62279F35D5AE82F9" />
-            <ComponentRef Id="cmp25A1373E7443967346CAB1C05C9C0F02" />
-            <ComponentRef Id="cmpBB3909EBF3EFC91CF550362308F8B0A3" />
-            <ComponentRef Id="cmp8DCF36681B9F03A6CF94EB29C91AD069" />
-            <ComponentRef Id="cmp94EAF3A5FE002EA2A74AE138626E8633" />
-            <ComponentRef Id="cmp4F90CF805DF53A87A67DC0281C16F2E5" />
-            <ComponentRef Id="cmp7615507ECFEAE51CB534D6A1CBFA868B" />
-            <ComponentRef Id="cmp0EE56AED71758E9A85E744690D00D1BD" />
-            <ComponentRef Id="cmp626029CAB13CC1C121C26E705C7B17ED" />
-            <ComponentRef Id="cmpF456FA18A49C014998FD56EBF6F8B3B0" />
-            <ComponentRef Id="cmpBF0D3DFE02C54D8BE2529505EDF9EC71" />
-            <ComponentRef Id="cmp86CC8A3E641BF344A9FD2652BAE90E6C" />
-            <ComponentRef Id="cmp5995FEBCBF7410C274C54931911DB21E" />
-            <ComponentRef Id="cmpA139EBC5A60DD100082C45EC6C5E33AA" />
-            <ComponentRef Id="cmp4185DD7CB0F3EAFE33F882B908B6A7C6" />
-            <ComponentRef Id="cmp661E05AA1427CD13FF5127B2411B1669" />
-            <ComponentRef Id="cmp7AB4F4DF89552A306F27E9E2F6A623DA" />
-            <ComponentRef Id="cmp1EA67FB49D6BECF6D1B44AB95F04DA5E" />
-            <ComponentRef Id="cmp781BDE48CDBCAE15768480F6F3A052DD" />
-            <ComponentRef Id="cmp385E7781A2840DFBE2DA808615781039" />
-            <ComponentRef Id="cmp9F1B2E8E0DB49F6B9518F4E68E7AC536" />
-            <ComponentRef Id="cmp86C96A310F5BB26224B9FF68E053FA0F" />
-            <ComponentRef Id="cmp7676B223C5A4A714E64524264EFFCC54" />
-            <ComponentRef Id="cmp52DD60836D83636B4A780DF958F4E61D" />
-            <ComponentRef Id="cmp75597DD51EDC3F51DD5BBB02DD892AC2" />
-            <ComponentRef Id="cmpB4720BB9D6705E3D69C6BD1D1FC3E174" />
-            <ComponentRef Id="cmpCD89301875081054F8C330898519FA7F" />
-            <ComponentRef Id="cmp51E672062A347FBE0CB4E8E038AC0D91" />
-            <ComponentRef Id="cmpF8CD8A5BD93BC295BEEEB21BA8EB1846" />
-            <ComponentRef Id="cmp9EC328DCB72D670222F1005E3C108F7B" />
-            <ComponentRef Id="cmp7DAC596A0CC08D2EFB08695136B0CA17" />
-            <ComponentRef Id="cmp7D17AF015D71B244D376C5F759A9DBD3" />
-            <ComponentRef Id="cmp150A9E66626147512C3DD44E6BE1B1B2" />
-            <ComponentRef Id="cmp265762AC45A7253A1ACEEEA579E7F79F" />
-            <ComponentRef Id="cmp863F4B86882A6C70C2CA5C1C82FCCE79" />
-            <ComponentRef Id="cmp551510470E26572504B92DDD7F677066" />
-            <ComponentRef Id="cmp728004CA9FF6F036824C0BFE3BBEC8BE" />
-            <ComponentRef Id="cmpA8ACF36F591B0F2596F1DFF01519DDFA" />
-            <ComponentRef Id="cmpC0E4B295A2909130A9AF1F766FA3D866" />
-            <ComponentRef Id="cmp0CF0C5C354A1DADE5E4047BD3E0A71DC" />
-            <ComponentRef Id="cmpAB53A03E2D7C14D4C50D61B5472FCDD6" />
-            <ComponentRef Id="cmpC110054F558236FC9DE910652CAF19D9" />
-            <ComponentRef Id="cmp2663CC5C0CFEF4FF5B1F14EDB4527497" />
-            <ComponentRef Id="cmp9A0276A01FC113C46507093C80D18649" />
-            <ComponentRef Id="cmpF254AD87553784310D3D1FE0254614D3" />
-            <ComponentRef Id="cmpCE0C7763E8FCEC1220DFCD9E7BB78BCA" />
-            <ComponentRef Id="cmp53CC12797765365E92F73C83ED3D66A2" />
-            <ComponentRef Id="cmpE055BA8E22750F279015AE949E9077D2" />
-            <ComponentRef Id="cmp1D9ED093258286A51677A8823874D81C" />
-            <ComponentRef Id="cmp932BB7F2D2329C603E4A293676DC569F" />
-            <ComponentRef Id="cmp443A9BE389EAC35F776D4AEEC557E7B7" />
-            <ComponentRef Id="cmpEB682C2498A83E15460CF3C9A995CFF7" />
-            <ComponentRef Id="cmp04EC8B1D825B58AA3DA19D924DF8B0B1" />
-            <ComponentRef Id="cmp0F769871ACD853090B5B989D8C137FA7" />
-            <ComponentRef Id="cmp291ACA145B7F38DEF0A689817B1848CA" />
-            <ComponentRef Id="cmp1EA8603BCB8C9F4A002397620B097AA6" />
-            <ComponentRef Id="cmpD2FE1296E8E0A96EEB2DC75B8F621BA5" />
-            <ComponentRef Id="cmp98613EE9D27378DB161FB3E84C3348CE" />
-            <ComponentRef Id="cmp6249A00626F75A73A6D54FABB28A8CD0" />
-            <ComponentRef Id="cmp723663731EC89E3C5851B5D091C2239F" />
-            <ComponentRef Id="cmpD2C66446234ADE594038CB5F6A0332FB" />
-            <ComponentRef Id="cmp8129E3CD6B43C9D748EF59093D50B0AD" />
-            <ComponentRef Id="cmpC78528D03802A5D0D1CE3984766C93D1" />
-            <ComponentRef Id="cmp2CC080FB390828F4F14FE06EDC89C5D5" />
-            <ComponentRef Id="cmp38C9BC62FD46E6B5E414E59677DE9357" />
-            <ComponentRef Id="cmp6092AEA43E0169389D0505FFA98BF45F" />
-            <ComponentRef Id="cmp3D44B5797FFF1AB131750A6A5430B320" />
-            <ComponentRef Id="cmpA2805661D83E6A7F849EFA5E4F37B375" />
-            <ComponentRef Id="cmpEB01C09EE469649460A335BB86939541" />
-            <ComponentRef Id="cmp72EC1854B1EEF4661811D651729134DF" />
-            <ComponentRef Id="cmp76075E5103CAB91D47E004805399916F" />
-            <ComponentRef Id="cmp1DEC87C5FB6BFCE2AFC70C4A574FE9BE" />
-            <ComponentRef Id="cmp8079956D2D7C2017A7871E6EA3020051" />
-            <ComponentRef Id="cmp4B7D72C6B15D0AF2F449A7891A3AC557" />
-            <ComponentRef Id="cmpFC9EFE272FFDE9600E5148EBBE0110A4" />
-            <ComponentRef Id="cmp7E8098EC6140D1BF019E408363BFFB6C" />
-            <ComponentRef Id="cmpB16694DE02D00ED33D05319AE9B700A2" />
-            <ComponentRef Id="cmp385055226F2FECF976369FC5ECD5C606" />
-            <ComponentRef Id="cmp4BF28C7182312F272879E70E5E599B35" />
-            <ComponentRef Id="cmp40139DE7335CE84CAE8DF50DEE707E0D" />
-            <ComponentRef Id="cmp15E56EA78F7945EE73F6F016FC15B74A" />
-            <ComponentRef Id="cmp2C3B23CA2FB10A6A7B890498C9679056" />
-            <ComponentRef Id="cmp1C47388B269EB7389524664338D6B228" />
-            <ComponentRef Id="cmpAD947E66C4B72B649DE506CDBB8C1138" />
-            <ComponentRef Id="cmpF5D0A2EFB2960C77F65D2CDF2485009C" />
-            <ComponentRef Id="cmp94CB9A1030C9F813F80899B411D3C92B" />
-            <ComponentRef Id="cmpCAA8C186128C2BA0F14BD8ED233CCAAF" />
-            <ComponentRef Id="cmp575C261AE2D71C7F8792EB08F136CB7B" />
-            <ComponentRef Id="cmp126992229DE0964A4988DE11FD02AAB1" />
-            <ComponentRef Id="cmp6F04A8F4C9403FA24E6A4BE3EDB95BD5" />
-            <ComponentRef Id="cmp52A47332C80A12129C3CE3E6BEB96DB1" />
-            <ComponentRef Id="cmpC9298B99BC59BA72C93EE04C7E2711B0" />
-            <ComponentRef Id="cmp9DD0FEC415646B339C592E126D2954D9" />
-            <ComponentRef Id="cmpA33449985BC8453ACF98BF0B72FAF81F" />
-            <ComponentRef Id="cmpCFE382F379DFFC0DF14109C0BFAF672B" />
-            <ComponentRef Id="cmp839015607706F63D9ED0C70CE10C7359" />
-            <ComponentRef Id="cmp86150C85856E18065298248A7F309691" />
-            <ComponentRef Id="cmp38059A7D3BE2B614C58838F80922BA67" />
-            <ComponentRef Id="cmp2F26DF2FF57CA8FA951F8EEC3E96E561" />
-            <ComponentRef Id="cmp2A138F5AB1828039CAC4C4B46AB0465B" />
-            <ComponentRef Id="cmpFDB625A2C53F9EDA18453B064B1105F0" />
-            <ComponentRef Id="cmpD7D383DDE9EBC2AB530686E3A7012478" />
-            <ComponentRef Id="cmp90AEE5FA3A9E9C6650D9466EC58FA8A2" />
-            <ComponentRef Id="cmpE7DCF0421AE9B244DC5E0F4C2323DE0B" />
-            <ComponentRef Id="cmp228F4AF01D3334E5200DE7F251A11FF4" />
-            <ComponentRef Id="cmp111F3D7FF73098BD75585376B387F296" />
-            <ComponentRef Id="cmp7E5C1A2BE845C2CA497F4995A2B8765B" />
-            <ComponentRef Id="cmp44D2900C842E2F59FE30E3EB110B24AB" />
-            <ComponentRef Id="cmpFB9874B5CCB35A38FF21EECFF77A6CC3" />
-            <ComponentRef Id="cmp01C20BCCA4155D0D9E3B11B514950F83" />
-            <ComponentRef Id="cmp8608349CDFD3459A383ED21E3BAE05FE" />
-            <ComponentRef Id="cmp29E0935C29850733C91824907E6EB7DC" />
-            <ComponentRef Id="cmpC36A915BD2AC10F337335A4810E75F2E" />
-            <ComponentRef Id="cmp515AF9D2852DEF323BF42B3D5766C576" />
-            <ComponentRef Id="cmp839A7CD1E5B37EC65E5DB75586BEA481" />
-            <ComponentRef Id="cmp7CF5D412B2F44AD4AEAC7F9CA8BA595B" />
-            <ComponentRef Id="cmpA6286623CABD7E5F3A09589B44420746" />
-            <ComponentRef Id="cmp227D8389040309820B730D258C474CA3" />
-            <ComponentRef Id="cmpC6C52B6306740C3CA2C37DFFF54FC7AA" />
-            <ComponentRef Id="cmp1D94BCC20C966E5B40B535336C7D0877" />
-            <ComponentRef Id="cmp1C463804A269A19B2F7FE9A8CF5B0C9A" />
-            <ComponentRef Id="cmp1967756DB056E9B0C5782282DE9F7DE4" />
-            <ComponentRef Id="cmpF2BBDD336FEC0B34B3C744ACF1E4B959" />
-            <ComponentRef Id="cmp2F4D4D81563D153E86B0A652A83D363A" />
-            <ComponentRef Id="cmp4F0AE38CA01E7A86BE72E3EC71DB3C46" />
-            <ComponentRef Id="cmpE4CC8D388C3636F073E7EA031EEE0AC5" />
-            <ComponentRef Id="cmp5F9E0C0DFC726F36C6FDE9B90080554E" />
-            <ComponentRef Id="cmpDAB537B8A2E977B5A32103CEEC88CD64" />
-            <ComponentRef Id="cmp7F5D5810EF40C3A84188A552DCD00008" />
-            <ComponentRef Id="cmp94FCB11503BBB2699CF1A4DD9E35C52F" />
-            <ComponentRef Id="cmpF9201D58B47A7E11845A6D127A0EBD85" />
-            <ComponentRef Id="cmpDA8CA1DBC718994C64120F30E2640107" />
-            <ComponentRef Id="cmpB39C80D17002F67CA773C426CCD5C79B" />
-            <ComponentRef Id="cmpF6EF0A228CE358A0B2B7FD4D0D7AA004" />
-            <ComponentRef Id="cmp92583B3440E1EE5CC387DD94671B7914" />
-            <ComponentRef Id="cmp52C24F1A2966F7C35E7B6E87BA586B54" />
-            <ComponentRef Id="cmp014CE8DBFFF159D9AFA21408F8656BFB" />
-            <ComponentRef Id="cmp5826376E0AFEFCA1743441E08045675B" />
-            <ComponentRef Id="cmpDB4ECA955FC312932FDD1EA7CA8E8886" />
-            <ComponentRef Id="cmpCD085923CB5A46A2995A1C8A5BE2581E" />
-            <ComponentRef Id="cmpF1ED51DC7C5F55CB79FD066C97F7FE00" />
-            <ComponentRef Id="cmp29D62E88C4F24671798BC96D494037FF" />
-            <ComponentRef Id="cmp06DF4AD2DD1B4FB716D67F9CC98BDB0F" />
-            <ComponentRef Id="cmp65E094AFC4504694F80D18026D63B5E7" />
-            <ComponentRef Id="cmp6550D85DB947332EC367B5F10E079957" />
-            <ComponentRef Id="cmp4B12A1128884B5E4BFA3A5D2399350B4" />
-            <ComponentRef Id="cmp884808A284FD7E5A584874B635CB30E8" />
-            <ComponentRef Id="cmp0C4FA72B48D1F1DF86C00AC83F161425" />
-            <ComponentRef Id="cmp7154C18D28D0821B7F9FDA058B7684BF" />
-            <ComponentRef Id="cmpA85B375722A33339F828F08D4568D942" />
-            <ComponentRef Id="cmpD76E671ADB5BD6A4D78727948C10979D" />
-            <ComponentRef Id="cmpA5ACE2ABDAD485164B610A43CF7260AC" />
-            <ComponentRef Id="cmp9EEF37ECA5477759CE2D4970BB1B2231" />
-            <ComponentRef Id="cmp9DE8DA0BADB8F3218AF203D5F2093547" />
-            <ComponentRef Id="cmp151AC5940A52B84848B8B31EBDDD0F0F" />
-            <ComponentRef Id="cmp697767827BDF2487CACDB2D9A09F2901" />
-            <ComponentRef Id="cmp828DF8125A1571A46643C65AE483B465" />
-            <ComponentRef Id="cmp29E6175F9E42A05F0ACA5E9DEC427DA9" />
-            <ComponentRef Id="cmp795E37CA1E2B235A5F5500D0CFC92E07" />
-            <ComponentRef Id="cmpA2C045F0BD78D4DABB8EF22E4986156C" />
-            <ComponentRef Id="cmp312772A42002C17926110BA35DDFEDAC" />
-            <ComponentRef Id="cmp70EAE5FACE0198DAE8D72AA3A4DDD8AD" />
-            <ComponentRef Id="cmp283D0458C51549C88E126658847DF812" />
-            <ComponentRef Id="cmpA7CDAE7D43C83449F75B67A9D91C58B7" />
-            <ComponentRef Id="cmp85AE0727B19590A7FF1A50C5D1AE2205" />
-            <ComponentRef Id="cmp341D1CF572011F0DD8EA39C96D0E7D17" />
-            <ComponentRef Id="cmp095F592845AFE0B3E095BABC7A7DD887" />
-            <ComponentRef Id="cmp99FE5BF0929D0B39B9A28A30E029E3CD" />
-            <ComponentRef Id="cmp68E4CC338F27CEFB9A29482B5F6D970D" />
-            <ComponentRef Id="cmp9D2C30192BAB98A581E527EEE9D775DD" />
-            <ComponentRef Id="cmpF7D67DC496EBE7AC2C920439E1996283" />
-            <ComponentRef Id="cmpECE28D947697E1B2574A852B9A5DB097" />
-            <ComponentRef Id="cmpB7CF7EED7782B02F1C519469E7B765D5" />
-            <ComponentRef Id="cmpEBDC2212A7FAB1E5BD6B67587A76AED4" />
-            <ComponentRef Id="cmp840CA25576C5DF17180F997EE6BEF7D4" />
-            <ComponentRef Id="cmpC1793F083A67818C741D1223019363EA" />
-            <ComponentRef Id="cmp75B69B6523FC3FC29345B566F9470108" />
-            <ComponentRef Id="cmp270BF8B2BC9223CBA67FF4520E0EB0CC" />
-            <ComponentRef Id="cmp32FE4A27540A4C0D7DFE0023D10E47C8" />
-            <ComponentRef Id="cmp0EA4B4F387D07BD36E57146B6B677CCE" />
-            <ComponentRef Id="cmp76FF40CF7CC84042483AA2633132F6F9" />
-            <ComponentRef Id="cmp9764EFEB37698149B4CF95E24D6870F8" />
-            <ComponentRef Id="cmpF1B0F36254CFC89E6F2FC4668A279880" />
-            <ComponentRef Id="cmpA58BF213DB6BE4CDF38B4373FBE8F0B5" />
-            <ComponentRef Id="cmpBC451DEE1CF26039CD451D0C148515E3" />
-            <ComponentRef Id="cmpB35F18E2C81EA247D0A07EC70B15ADCE" />
-            <ComponentRef Id="cmp5B195BB800FD7411B27C92CB43108D68" />
-            <ComponentRef Id="cmp6AE6EF943B6F1903692B887E285CCFB6" />
-            <ComponentRef Id="cmpE90BFF212EE36AB7F5BE7066910EF4BF" />
-            <ComponentRef Id="cmp49AF1F329C3F7DCBA3BC03E4E79CF94A" />
-            <ComponentRef Id="cmp2529F0564324F333C6435C250FF5970A" />
-            <ComponentRef Id="cmpF2D829D6269C06610A0D914F091D2EB6" />
-            <ComponentRef Id="cmpA3E143106D868A13F2262CA98833028F" />
-            <ComponentRef Id="cmp2FB05B76F9224338415D5AF2DACC8578" />
-            <ComponentRef Id="cmp6B758895DF8C4D51E8547F56A2ADC279" />
-            <ComponentRef Id="cmpAB0C1DB0804EBFC02CA78936EFFF71EF" />
-            <ComponentRef Id="cmp85716B1B1F1E013696DEDD3474014DB8" />
-            <ComponentRef Id="cmp737216EFE0F1409C4D1F2265D4E5B2A1" />
-            <ComponentRef Id="cmpC4B4CBE179C4F76D7969E0429A887CDF" />
-            <ComponentRef Id="cmpE1BB74D0F1E82DD596BBBB6C676460E3" />
-            <ComponentRef Id="cmpFE414A5137D6014C13BEAF7CE666B901" />
-            <ComponentRef Id="cmp840E48CBACD153B6B20C9CDB810B839A" />
-            <ComponentRef Id="cmp95FB8B358EF45F79B9515DEF7E8B29BC" />
-            <ComponentRef Id="cmpD05F66DE43ABCFBF23BCB600DE956E3C" />
-            <ComponentRef Id="cmp68DD2572E139316EAC122073F14C2DBF" />
-            <ComponentRef Id="cmp053FA1BACCC1DFE05BD2A78D3EC9DFD0" />
-            <ComponentRef Id="cmp10D4FB44E6F41C4867BDC54C65A23F18" />
-            <ComponentRef Id="cmpB3C2CB2A0C0C44280251610D64EA34A5" />
-            <ComponentRef Id="cmpFAD337F32D9DAD7C1608584D499EC0F7" />
-            <ComponentRef Id="cmp980CEFD22B6EDFB878ADCFCD3C1A6795" />
-            <ComponentRef Id="cmpA037D4BC3A7643D66FC93D9DBD3231CF" />
-            <ComponentRef Id="cmp8ECD89F84DDB6A69C5D5400C09DA14CA" />
-            <ComponentRef Id="cmpCB6E48CA739193A15D4AC14E0302A44C" />
-            <ComponentRef Id="cmp1E88F28393186242EA3DE3D790EB85CE" />
-            <ComponentRef Id="cmp2C08251BEFAF44B31CEA7847A91AD4F4" />
-            <ComponentRef Id="cmp7215333AA17AC5DF99CE957BB9438677" />
-            <ComponentRef Id="cmpCBB72D8C2425E17861B303477B6763B5" />
-            <ComponentRef Id="cmp5EB5F77075D2851AEEED7C27D21A45A3" />
-            <ComponentRef Id="cmp31885389B028B5DB8056CD914990B774" />
-            <ComponentRef Id="cmpDEB685A842E2A519A4ABD4D102ED83F4" />
-            <ComponentRef Id="cmp3C03902D82B4504831FF25FE23BFF13C" />
-            <ComponentRef Id="cmpE0C985EACC4891C413624DF04A20082E" />
-            <ComponentRef Id="cmp0E7A5C73EC5E56E3260BA02ADC05AEFB" />
-            <ComponentRef Id="cmp4EC2E4C78AB0864A292331A64B673E80" />
-            <ComponentRef Id="cmpCFFB8D44D84C546212B33DE94E42CB5C" />
-            <ComponentRef Id="cmpC41CD5F28C01900654FBED380521BBFC" />
-            <ComponentRef Id="cmp43D9195434BB328867E29C03FFD2074C" />
-            <ComponentRef Id="cmpDDAA9863C75F24B496C6BA183DB34BA6" />
-            <ComponentRef Id="cmpE9422A3EFB96B7D6CF28A20BDE19560C" />
-            <ComponentRef Id="cmpB2F7E25C01676CA3FFC691CF7DE26670" />
-            <ComponentRef Id="cmpCC739E7B4A6BB506DC1E8596E1D477BB" />
-            <ComponentRef Id="cmp4CBDD655EBCB0B3D22E2DBB900B2C682" />
-            <ComponentRef Id="cmp880E465D50F8BD6C227EB553504AC571" />
-            <ComponentRef Id="cmpFED1E298CC2A536198D364B7BE7F21B9" />
-            <ComponentRef Id="cmp7B84950D2792D889C3BF4348F8D8EDA1" />
-            <ComponentRef Id="cmpCFA0598A7D429B5D592FB828E7FF4F3E" />
-            <ComponentRef Id="cmp7937F27BF975D4F3C7DF1694F139FCD5" />
-            <ComponentRef Id="cmp576112B0425B94FF535E02B9B3A82A21" />
-            <ComponentRef Id="cmpB3FB2E1B1AE3A1B861164BFF506E4BB5" />
-            <ComponentRef Id="cmpCF13179476AD94F458CA0EA44D7DDAC7" />
-            <ComponentRef Id="cmp8D67161C7E50EE36669F7C5D9923D91A" />
-            <ComponentRef Id="cmp39347F69E7E0C55D8FDA48C01CA9B8DE" />
-            <ComponentRef Id="cmp484E9D1B9A1D120F01385D24A44A7909" />
-            <ComponentRef Id="cmpE66BC3701F4FE7089E72DCE19E655A2E" />
-            <ComponentRef Id="cmp17CA79361C814E20B9F772CE10EC49DC" />
-            <ComponentRef Id="cmpA6F3B74801C880438FFE04CE4BB76A4D" />
-            <ComponentRef Id="cmp46FE38B8E6D467E0A461B5D1F5A9C9A8" />
-            <ComponentRef Id="cmpE79D8DE0A3F5641D63029C9C5BB84D0D" />
-            <ComponentRef Id="cmpA6C72B638E002C5141944F120B6B9711" />
-            <ComponentRef Id="cmpBA53547354F4749AB6DB53E652729729" />
-            <ComponentRef Id="cmpCD11EA05E25825E7612832BC5B20BA2A" />
-            <ComponentRef Id="cmpBDFE909E7E379544C61D273DC64AA4C1" />
-            <ComponentRef Id="cmp3ACE0516410DF2135ACB4ECB4C514516" />
-            <ComponentRef Id="cmp745688982E1084B904FEA071A184F46B" />
-            <ComponentRef Id="cmpE09A0EC1AEC3442530CE4D940A0126DE" />
-            <ComponentRef Id="cmp8AFFC23BCB9CA9B76CCE523A385B70C2" />
-            <ComponentRef Id="cmp0C6141EEA4A40393515982D763DAE5FB" />
-            <ComponentRef Id="cmp4FB659D88A93FF927815E43845491DA9" />
-            <ComponentRef Id="cmp50C956224B366169BA04472188950247" />
-            <ComponentRef Id="cmpA483BD06A7D6334E6405477C56E9DFFD" />
-            <ComponentRef Id="cmp18A187327523FE95B85904046F0995E7" />
-            <ComponentRef Id="cmpDDDD31383EC18DC518164D114B067071" />
-            <ComponentRef Id="cmpDD3CA3FC5F636E0CFD5412E59A18A5AF" />
-            <ComponentRef Id="cmp59307667B29713EE25C4CE3FD0860F96" />
-            <ComponentRef Id="cmpBEF338145E29BC27474B53158F25FB95" />
-            <ComponentRef Id="cmp8C3019A13CF77EB1A807E2EE9DE4E365" />
-            <ComponentRef Id="cmpD64E6CDD99BF2D21CAE829616DE42236" />
-            <ComponentRef Id="cmpDC56F1AEA9FABCCA41D117FA3E462B20" />
-            <ComponentRef Id="cmp0523CA11E9A3AD4396B3A4D94126D6A7" />
-            <ComponentRef Id="cmpBE28EC01FD89E2022706795FE3BE64CF" />
-            <ComponentRef Id="cmp7598569D1214F0C47C6FDE60A5CF56A1" />
-            <ComponentRef Id="cmpA7EB7CE6F51D8AFFB2849A1E45727DD4" />
-            <ComponentRef Id="cmp605BEAEE41DE38DF62A7661E5917FFAE" />
-            <ComponentRef Id="cmpE0B719953591863F1C41B9B8D9890FE4" />
-            <ComponentRef Id="cmpC316900EC1F7921DA4B97A0BFDDC6371" />
-            <ComponentRef Id="cmpEA52008808B8D6CB960FC0B64DBABA18" />
-            <ComponentRef Id="cmpAA79BA8C69B3B684C4B541639A4B1B48" />
-            <ComponentRef Id="cmpDEEBED90BCD0AF6DCDCCF3726C454D1A" />
-            <ComponentRef Id="cmp56904E49C396D6221012E481C76BFEDB" />
-            <ComponentRef Id="cmpA67AC3C865D3FB5903AC78966B135A5F" />
-            <ComponentRef Id="cmpE2B831E07705E24C1FD0BC0F2AEFCB1A" />
-            <ComponentRef Id="cmpF09680275C25673EF264EA7BAAFE62B8" />
-            <ComponentRef Id="cmp5FB7FBB46BEF31107DD64428F0DF1FC4" />
-            <ComponentRef Id="cmp89DE26021F5BBB23D9756486D57C985E" />
-            <ComponentRef Id="cmpBFA91247D54CF980299DC5DA3B3823FC" />
-            <ComponentRef Id="cmpC90D538CF35392DC8C009792FB8E6860" />
-            <ComponentRef Id="cmp68A5B8A15810C6912151282F5F5B568F" />
-            <ComponentRef Id="cmp4196A38C255BB0CCCAA0A70FE7DEEF58" />
-            <ComponentRef Id="cmpB164A610DB8FDF54ED63DCB498E40A27" />
-            <ComponentRef Id="cmp7531333E7B9F893A3A68372A9B0B779B" />
-            <ComponentRef Id="cmp1BF05E1306024F72E5F302052C4431B9" />
-            <ComponentRef Id="cmp0F5759F010AAD8E57FEED9BB38D65F91" />
-            <ComponentRef Id="cmp9FAD7DAD071299E1AAF045F54DE9F495" />
-            <ComponentRef Id="cmp89F65AB47003394DE45F2F27D9992C86" />
-            <ComponentRef Id="cmp0C3372A952450A4EED8FDCC1B8EAF4A3" />
-            <ComponentRef Id="cmp9562AE97F33C3CD77EF1E6047705DA8B" />
-            <ComponentRef Id="cmp8D6DE04804DE7F875BFE1C2B96E6DAAA" />
-            <ComponentRef Id="cmpC8065F5E307AF50C8229837FADEDA835" />
-            <ComponentRef Id="cmp3144F7B0A58AD9EA30445F579EE4F391" />
-            <ComponentRef Id="cmp7E3B58D2A4782D7409275BE070F7CF58" />
-            <ComponentRef Id="cmp1FD25AD22B9922A127097A63F2C19C75" />
-            <ComponentRef Id="cmp69F70CB4547BEC51A76EE4FBF29B227D" />
-            <ComponentRef Id="cmp64CA09D64F696D3E71B4BE826A07731C" />
-            <ComponentRef Id="cmp03776BC4AEB2E5DC49A619B02A797EB6" />
-            <ComponentRef Id="cmpA096FB071D1289FB6EFB128A9B33F801" />
-            <ComponentRef Id="cmp654DE3A3B029F59772E7A6BB4C754997" />
-            <ComponentRef Id="cmpC4FA047DBF629800E5F825023F3DB2E5" />
-            <ComponentRef Id="cmp40E3623765774C3007055646CB0B5CA8" />
-            <ComponentRef Id="cmpC34B337EB9BE0D3F92498818BDB6D4B8" />
-            <ComponentRef Id="cmpB461DFEF3B05553DE179C1A846F3FF87" />
-            <ComponentRef Id="cmp18523225741C1B62B821A603B4785A02" />
-            <ComponentRef Id="cmp42EC75447FD0FA6501A396F1B6AEED1E" />
-            <ComponentRef Id="cmp8527B9F7536DDAD1A6B2EE190C919F89" />
-            <ComponentRef Id="cmp7338F5B47C99ECFAE998650D3E5470C6" />
-            <ComponentRef Id="cmp78A0205F4E525EE76ACF64EFBD247CF4" />
-            <ComponentRef Id="cmp1A634B87498A4ECBC74CC11022122FB7" />
-            <ComponentRef Id="cmp19F8CCB28022D4162CD6FFF29BAC0D0F" />
-            <ComponentRef Id="cmp0FD86CA93873A376079A34ADB94D9867" />
-            <ComponentRef Id="cmpFC5CB0F3E6908AA7A765BF8F4C0D0B02" />
-            <ComponentRef Id="cmp10B512385CCF7F61FFFF695BC4E8065D" />
-            <ComponentRef Id="cmpF1BC23977D0A9D0287CBDE0C5CA6A73B" />
-            <ComponentRef Id="cmpDC338323A2F5AAC888FE495B1D0CF1C7" />
-            <ComponentRef Id="cmpC4C3F4AAB9EC442EF62C8FB38EFF44FE" />
-            <ComponentRef Id="cmp8757A1DAFCE48504153F9107D6164B02" />
-            <ComponentRef Id="cmp48265CD12FCB09ED767A666BEC8EC00D" />
-            <ComponentRef Id="cmp84109123CBE829CC642B7E39E1B5C836" />
-            <ComponentRef Id="cmpF5E9A752898E9028B0FDFF323F4DEA99" />
-            <ComponentRef Id="cmpECC9BFD70050CF5CBB298151CC107DD0" />
-            <ComponentRef Id="cmp81E203B48ABAD7F52FAF852F7A12145D" />
-            <ComponentRef Id="cmp445572727EA15EB11747C585C114A34C" />
-            <ComponentRef Id="cmpDB06F91B079F2960625DEBD3F94C2CEF" />
-            <ComponentRef Id="cmp2FE756BEA5670737A739E40895AF7F92" />
-            <ComponentRef Id="cmp6114379A976905B2F2770C6E5934AC79" />
-            <ComponentRef Id="cmpCF3E965E2D26D7E48F44F280084D6836" />
-            <ComponentRef Id="cmp2210FF2D22610D7C6B5B50F74A6CCFF6" />
-            <ComponentRef Id="cmpFD000330960F806FBE824963957BF7AD" />
-            <ComponentRef Id="cmp977CF1BC61468FC27B11A540213FE9A5" />
-            <ComponentRef Id="cmp6E4E148E6DE4226B3D6018D8ABE03CF2" />
-            <ComponentRef Id="cmp9F0F75F617461065DC10DB27BEA1FAF7" />
-            <ComponentRef Id="cmp43FD59D64A3BDA21A1D6F7CEACE2B2FC" />
-            <ComponentRef Id="cmp4B06F6782804926721B71B853306D808" />
-            <ComponentRef Id="cmp5FEC4120CA054CAB736D40A02B797314" />
-            <ComponentRef Id="cmp7EF50603559988206A20CF4EFCB03A73" />
-            <ComponentRef Id="cmp42FCB77155A6498CAC4AE0DDE075085D" />
-            <ComponentRef Id="cmp7CF8F89A55C985FF68A0C8F2D75BBB1A" />
-            <ComponentRef Id="cmp6CDF7ADA601388F2E1A733F8E4F0C36F" />
-            <ComponentRef Id="cmp13F40EF7ACA81350C4F8E813736A2CAE" />
-            <ComponentRef Id="cmp8CBA9E0D91DF8138E2BF1EEFE71BC07D" />
-            <ComponentRef Id="cmpD51A9DB18A9C78D3F72950E5F2EAB25D" />
-            <ComponentRef Id="cmpF1031D7436E22BE80D98DE4EB55C7BE3" />
-            <ComponentRef Id="cmpDC7CEE74CD7B941AE4E790290079486B" />
-            <ComponentRef Id="cmp5BD19F0B4F145CAB9447EBFFB74FC057" />
-            <ComponentRef Id="cmp6E4587E33E92248D1DF802D18D6674EB" />
-            <ComponentRef Id="cmpED118D724F550278A6A5906B4C5570FE" />
-            <ComponentRef Id="cmpF7BF21EAAE348BE08F20AD4FD885B632" />
-            <ComponentRef Id="cmpE267BC074E9FF03E8FEC15F90F6AC3C5" />
-            <ComponentRef Id="cmpFC79ECC8852090269FFFB4ED834C20B0" />
-            <ComponentRef Id="cmp2781812D9B5A646D9B6C89E3C24629B7" />
-            <ComponentRef Id="cmp3A1296CF9D53E1837B569C22EFAB288A" />
-            <ComponentRef Id="cmp95D4B8057C5B721A30CACE10EDFE7BAB" />
-            <ComponentRef Id="cmp5BFBD111D93716502AFE619ACC3AF188" />
-            <ComponentRef Id="cmp79CCF2A220914A861D556F8ED2C42745" />
-            <ComponentRef Id="cmp0E31DE92033E0CBE7A7217B8BF3B2192" />
-            <ComponentRef Id="cmp0B6AD54A7D460A737BEDE06A452C5A57" />
-            <ComponentRef Id="cmp97CB02F5412B596F2D6E3A11DA18D3C1" />
-            <ComponentRef Id="cmp48635F1A52681F2B64D6C793909BE56E" />
-            <ComponentRef Id="cmp6D3E0478E079025DA610BC77ED644157" />
-            <ComponentRef Id="cmpB0CEEF7086AED7FCC4AC1755ACEB99B2" />
-            <ComponentRef Id="cmpED6FE496E5E9498709BCA934064A975A" />
-            <ComponentRef Id="cmp1F284CA13DFED796A81F16057684AB91" />
-            <ComponentRef Id="cmp776899723BBC0C56DBF1EA389CF3A210" />
-        </ComponentGroup>
-    </Fragment>
-</Wix>
diff --git a/scripts/installer/windows/dependencies.wxs b/scripts/installer/windows/dependencies.wxs
deleted file mode 100644
index 987c561..0000000
--- a/scripts/installer/windows/dependencies.wxs
+++ /dev/null
@@ -1,28 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to
-  you under the Apache License, Version 2.0 (the "License"); you may not use
-  this file except in compliance with the License. You may obtain a copy of
-  the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-  by applicable law or agreed to in writing, software distributed under the
-  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific
-  language governing permissions and limitations under the License. -->
-<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
-	 xmlns:bal='http://schemas.microsoft.com/wix/BalExtension'>
-<!-- Installing dependencies -->
-	<Bundle UpgradeCode="7cc78eac-106d-400e-b266-1b2c778b16b9" Version="4.4.0">
-		<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" >
-			<bal:WixStandardBootstrapperApplication LicenseFile="acs_license.rtf" ShowVersion="yes" ThemeFile="optionstheme.xml" LocalizationFile="optionstheme_en-us.wxl"/>
-		</BootstrapperApplicationRef>
-		<Chain>
-			<MsiPackage Id="MySql" Name="mysql-5.1.73-winx64.msi" DownloadUrl="http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.73-winx64.msi" Compressed="no" Visible="yes" ForcePerMachine="yes" DisplayInternalUI="yes" EnableFeatureSelection="yes" InstallCondition="ACSCheckbox"/>
-			<MsiPackage Id="MySqlClient" Name="mysql-5.1.73-winx64.msi" DownloadUrl="http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.73-winx64.msi" Compressed="no" Visible="yes" ForcePerMachine="yes" EnableFeatureSelection="no" DisplayInternalUI="no" InstallCondition="Not ACSCheckbox"/>
-			<MsiPackage Id="SevenZip" Name="7z920-x64.msi" DownloadUrl="http://downloads.sourceforge.net/sevenzip/7z920-x64.msi" Compressed="no" Visible="yes" ForcePerMachine="yes" After="MySql"/>
-			<MsiPackage Id="Python" Name="python-2.7.6.amd64.msi" DownloadUrl="https://www.python.org/ftp/python/2.7.6/python-2.7.6.amd64.msi" Compressed="no" Visible="yes" ForcePerMachine="yes" After="SevenZip"/>
-			<ExePackage Id="Tomcat6" Name="apache-tomcat-6.0.39.exe" PerMachine="yes" DownloadUrl="http://mirror.sdunix.com/apache/tomcat/tomcat-6/v6.0.39/bin/apache-tomcat-6.0.39.exe" Compressed="no" InstallCommand="/S" After="Python"/>
-			<ExePackage Id="CdrTools" Name="CDR-Tools.exe" PerMachine="yes" DownloadUrl="http://sourceforge.net/projects/cdrtoolswin/files/1.0/Binaries/CDR-Tools.exe/download" Compressed="no" InstallCommand="/S" After="Tomcat6"/>
-			<MsiPackage Id="acs" Name="acs.msi" Compressed="yes" Visible="yes" ForcePerMachine="yes" DisplayInternalUI="yes" EnableFeatureSelection="yes" After="CdrTools"/>
-		</Chain>
-	</Bundle>
-</Wix>
\ No newline at end of file
diff --git a/scripts/installer/windows/en-us.wxl b/scripts/installer/windows/en-us.wxl
deleted file mode 100644
index 2f34575..0000000
--- a/scripts/installer/windows/en-us.wxl
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
-  <String Id="ProductName">Apache Cloud Stack</String>
-  <String Id="ProductManufacturer">Apache</String>
-  <String Id="PackageDescription">Apache Cloud Stack Installer</String>
-  <String Id="PackageComments">ACS is a registered trademark</String>
-  <String Id="PackageManufacturer">Apache</String>
-  <String Id="Tomcat6ConditionMessage">Apache tomcat6 is not installed please do install tomcat6 and then try</String>
-  <String Id="Java7ConditionMessage">Java 7 Is not Installed. Please Install Java 7 and then try</String>
-  <String Id="Python2ConditionMessage">Python 2.7 is not installed Please do install python and then try</String>
-  <String Id="SevenZConditionMessage">7Z is not installed please do install 7z and then try</String>
-  <String Id="FeatureTitle1">Management Server</String>
-  <String Id="FeatureDescription1">The Main Executable of Cloud Stack.</String>
-  <String Id="FeatureDescription2">The complete package.</String>
-  <String Id="DatabaseInformationTitle">Provide Database Information</String>
-  <String Id="DatabaseInformationDescription">Please provide the database information that host the cloud schemas</String>
-  <String Id="DbServerIpLabel">Host Name</String>
-  <String Id="DbUserNameLabel">User Name</String>
-  <String Id="DbPasswordLabel">Password</String>
-  <String Id="DbRootPasswordLabel">Root Password</String>
-  <String Id="DbServerPortLabel">Port</String>
-  <String Id="CreateDBCheckBoxLabel">Create Cloud Stack Database</String>
-  <String Id="GenerateSSLKey">Generating SSL Keys which is needed to talk to Management Server.</String>
-  <String Id="DeployDB">Creating Database and needed Schemas for management server.</String>
-  <String Id="SetupDatabases">Updating db.properties with the given database configuration.</String>
-  <String Id="DeleteDirectory">Deleting un-necessary directories from installation directory.</String>
-  <String Id="CopySitePackages">Copying Management Server related python libraries.</String>
-  <String Id="SetuptoolsInstallation">Installing Setup Tools for Python.</String>
-  <String Id="DeleteFiles">Deleting un-necessary files from installation directory.</String>
-  <String Id="UpdateTomcatCatalinaBase">Updating Tomcat Catalina Base with Management Server Home.</String>
-  <String Id="UpdateTomcatClassPath">Updating Tomcat Classpath with necessary paths.</String>
-
-  <String Id="InstallVersion">Version 4.0.0.0</String>
-</WixLocalization>
\ No newline at end of file
diff --git a/scripts/installer/windows/optionstheme.xml b/scripts/installer/windows/optionstheme.xml
deleted file mode 100644
index fa8d585..0000000
--- a/scripts/installer/windows/optionstheme.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
-    <Window Width="485" Height="300" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
-    <Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
-    <Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
-    <Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
-    <Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
-    <Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
-
-    <Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" Visible="yes"/>
-    <Text X="80" Y="11" Width="-11" Height="64" FontId="1" Visible="yes" DisablePrefix="yes">#(loc.Title)</Text>
-
-    <Page Name="Help">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
-        <Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
-        <Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
-    </Page>
-    <Page Name="Install">
-        <Richedit Name="EulaRichedit" X="11" Y="80" Width="-11" Height="-70" TabStop="yes" FontId="0" HexStyle="0x800000" />
-        <Checkbox Name="EulaAcceptCheckbox" X="-11" Y="-41" Width="260" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
-        <Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.InstallOptionsButton)</Button>
-        <Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
-        <Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
-    </Page>
-    <Page Name="Options">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Text>
-        <Checkbox Name="ACSCheckbox" X="31" Y="121" Width="17" Height="17" TabStop="yes" FontId="3">Select to Install Mysql</Checkbox>
-        <Text X="50" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.MysqlInstaller)</Text>
-        <Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsOkButton)</Button>
-        <Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.OptionsCancelButton)</Button>
-    </Page>
-    <Page Name="Progress">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
-        <Text X="11" Y="121" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
-        <Text Name="OverallProgressPackageText" X="85" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
-        <Progressbar Name="OverallCalculatedProgressbar" X="11" Y="143" Width="-11" Height="15" />
-        <Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
-    </Page>
-    <Page Name="Modify">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
-        <Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
-        <Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
-        <Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
-    </Page>
-    <Page Name="Success">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
-        <Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
-        <Text Name="SuccessRestartText" X="-11" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
-        <Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
-        <Button Name="SuccessCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
-    </Page>
-    <Page Name="Failure">
-        <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FailureHeader)</Text>
-        <Hypertext Name="FailureLogFileLink" X="11" Y="121" Width="-11" Height="42" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
-        <Hypertext Name="FailureMessageText" X="22" Y="163" Width="-11" Height="51" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
-        <Text Name="FailureRestartText" X="-11" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
-        <Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
-        <Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
-    </Page>
-</Theme>
\ No newline at end of file
diff --git a/scripts/installer/windows/optionstheme_en-us.wxl b/scripts/installer/windows/optionstheme_en-us.wxl
deleted file mode 100644
index c822929..0000000
--- a/scripts/installer/windows/optionstheme_en-us.wxl
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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. -->
-<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
-
-  <String Id="Caption">Apache Cloud Stack Setup</String>
-  <String Id="Title">Apache Cloud Stack</String>
-  <String Id="MysqlInstaller">Install MySql Database Server</String>
-  <String Id="InstallVersion">Version 4.0.0.0</String>
-
-  <String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
-  <String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
-  <String Id="HelpHeader">Setup Help</String>
-  <String Id="HelpText">/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
-   creates a complete local copy of the bundle in directory. Install is the default.
-
-/passive | /quiet -  displays minimal UI with no prompts or displays no UI and
-   no prompts. By default UI and all prompts are displayed.
-
-/norestart   - suppress any attempts to restart. By default UI will prompt before restart.
-/log log.txt - logs to a specific file. By default a log file is created in %TEMP%.</String>
-  <String Id="HelpCloseButton">&amp;Close</String>
-  <String Id="InstallAcceptCheckbox">I &amp;agree to the license terms and conditions</String>
-  <String Id="InstallOptionsButton">&amp;Options</String>
-  <String Id="InstallInstallButton">&amp;Install</String>
-  <String Id="InstallCloseButton">&amp;Close</String>
-  <String Id="OptionsHeader">Setup Options</String>
-  <String Id="OptionsLocationLabel">Install location:</String>
-  <String Id="OptionsBrowseButton">&amp;Browse</String>
-  <String Id="OptionsOkButton">&amp;OK</String>
-  <String Id="OptionsCancelButton">&amp;Cancel</String>
-  <String Id="ProgressHeader">Setup Progress</String>
-  <String Id="ProgressLabel">Installing:</String>
-  <String Id="OverallProgressPackageText">Initializing...</String>
-  <String Id="ProgressCancelButton">&amp;Cancel</String>
-  <String Id="ModifyHeader">Modify Setup</String>
-  <String Id="ModifyRepairButton">&amp;Repair</String>
-  <String Id="ModifyUninstallButton">&amp;Uninstall</String>
-  <String Id="ModifyCloseButton">&amp;Close</String>
-  <String Id="SuccessHeader">Setup Successful</String>
-  <String Id="SuccessLaunchButton">&amp;Launch</String>
-  <String Id="SuccessRestartText">You must restart your computer before you can use the software.</String>
-  <String Id="SuccessRestartButton">&amp;Restart</String>
-  <String Id="SuccessCloseButton">&amp;Close</String>
-  <String Id="FailureHeader">Setup Failed</String>
-  <String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the &lt;a href="#"&gt;log file&lt;/a&gt;.</String>
-  <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
-  <String Id="FailureRestartButton">&amp;Restart</String>
-  <String Id="FailureCloseButton">&amp;Close</String>
-</WixLocalization>
\ No newline at end of file
diff --git a/scripts/installer/windows/start.bat b/scripts/installer/windows/start.bat
deleted file mode 100644
index e819fa2..0000000
--- a/scripts/installer/windows/start.bat
+++ /dev/null
@@ -1,12 +0,0 @@
-:: Licensed to the Apache Software Foundation (ASF) under one or more contributor
-:: license agreements. See the NOTICE file distributed with this work for additional
-:: information regarding copyright ownership. The ASF licenses this file to you under
-:: the Apache License, Version 2.0 (the "License"); you may not use this file except
-:: in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-:: Unless required by applicable law or agreed to in writing, software distributed under
-:: the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-:: OF ANY KIND, either express or implied. See the License for the specific language
-:: governing permissions and limitations under the License.
-echo Starting Apache CloudStack > C:\Work\tmp.out
-START %CATALINA_HOME%\bin\startup.bat
-echo Started Aoache CloudStack >> C:\Work\tmp.out
\ No newline at end of file
diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops
index b656ce6..d87edff 100755
--- a/scripts/vm/hypervisor/xenserver/vmops
+++ b/scripts/vm/hypervisor/xenserver/vmops
@@ -824,7 +824,7 @@
        logging.debug(" failed to add vm " + vm_ip + " ip to set ")
        return 'false'
 
-    #add secodnary nic ips to ipset
+    #add secondary nic ips to ipset
     secIpSet = "1"
     ips = sec_ips.split(';')
     ips.pop()
@@ -1419,12 +1419,22 @@
         reason = 'domid_change'
 
     rules = args.pop('rules')
+    logging.debug("Network rules compressed in base64 [%s]." % rules)
+
     if deflated.lower() == 'true':
        rules = inflate_rules (rules)
     keyword = '--' + get_ipset_keyword()
+
+    #Split spaces into lines. Example of rule [I:tcp;22;22;0.0.0.0/22,NEXT I:tcp;8001;8010;192.168.100.0/24,NEXT E:tcp;22;22;0.0.0.0/0,NEXT ]
+    #After split:
+    # I:tcp;22;22;0.0.0.0/22,NEXT
+    # I:tcp;8001;8010;192.168.100.0/24,NEXT
+    # E:tcp;22;22;0.0.0.0/0,NEXT
     lines = rules.split(' ')
 
-    logging.debug("Programming network rules for vm  %s seqno=%s numrules=%s signature=%s guestIp=%s,"\
+    logging.info("Network rules to be processed [%s]." % rules)
+
+    logging.info("Programming network rules for vm  %s seqno=%s numrules=%s signature=%s guestIp=%s,"\
               " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason))
 
     # Flush iptables rules to clear ipset references and before re-applying iptable rules
@@ -1438,14 +1448,24 @@
     cmds = []
     egressrules = 0
     for line in lines:
-        tokens = line.split(':')
-        if len(tokens) != 5:
-          continue
-        token_type = tokens[0]
-        protocol = tokens[1]
-        start = tokens[2]
-        end = tokens[3]
-        cidrs = tokens.pop().split(",")
+        logging.debug("Processing rule [%s]." % line)
+        
+        #Example of rule: [I:tcp;12;34;1.2.3.4/24,NEXT] -> tokens: ['I:tcp', '12', '34', '1.2.3.4/24,NEXT'].
+        tokens = line.split(';')
+        logging.debug("Tokens %s." % tokens)
+        
+        tokens_size = len(tokens)
+
+        expected_tokens_size = 4
+        if tokens_size != expected_tokens_size:
+            logging.warning("Network rule tokens size [%s] is different from the expected size [%s], ignoring rule %s" % (str(tokens_size), str(expected_tokens_size), tokens))
+            continue
+
+        token_type, protocol = tokens[0].split(':')
+        start = tokens[1]
+        end = tokens[2]
+        cidrs = tokens[3].split(",")
+        # Remove placeholder 'NEXT' from the cidrs array
         cidrs.pop()
         allow_any = False
 
@@ -1456,17 +1476,22 @@
             action = "RETURN"
             direction = "dst"
             egressrules = egressrules + 1
+            logging.debug("Ipset chaing [%s], VM chain [%s], VM name [%s], Action [%s], Direction [%s], egress rules [%s]" % (ipset_chain, vmchain, vm_name, action, direction, egressrules))
         else:
             #ipset chain name
             ipset_chain = ingress_chain_name_ipset(vm_name)
             vmchain = chain_name(vm_name)
             action = "ACCEPT"
             direction = "src"
-        if  '0.0.0.0/0' in cidrs:
+            logging.debug("Ipset chaing [%s], VM [%s], Action [%s], Direction [%s], egress rules [%s]" % (ipset_chain, vm_name, action, direction, egressrules))
+        if '0.0.0.0/0' in cidrs:
             i = cidrs.index('0.0.0.0/0')
             del cidrs[i]
             allow_any = True
+        
         port_range = start + ":" + end
+        logging.debug("port range [%s]" % port_range)
+
         if cidrs:
             #create seperate ipset name
             ipsetname = ipset_chain + "" + protocol[0:1] + "" + start + "_" + end
@@ -1500,6 +1525,7 @@
             logging.debug(iptables)
 
     for cmd in cmds:
+        logging.debug("Executing command: [%s]." % str(cmd))
         util.pread2(cmd)
 
     vmchain = chain_name(vm_name)
@@ -1517,7 +1543,7 @@
 
     return 'true'
   except:
-    logging.debug("Failed to network rule !")
+    logging.exception("Failed to network rule!")
 
 if __name__ == "__main__":
      XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi,
diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmops b/scripts/vm/hypervisor/xenserver/xcposs/vmops
deleted file mode 100644
index 3581aa7..0000000
--- a/scripts/vm/hypervisor/xenserver/xcposs/vmops
+++ /dev/null
@@ -1,1455 +0,0 @@
-#!/usr/bin/python
-# 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.
-
-# Version @VERSION@
-#
-# A plugin for executing script needed by vmops cloud 
-
-import os, sys, time
-import XenAPIPlugin
-sys.path.extend(["/usr/lib/xcp/sm/", "/usr/local/sbin/", "/sbin/"])
-import base64
-import hostvmstats
-import socket
-import stat
-import tempfile
-import util
-import subprocess
-import zlib
-from util import CommandException
-
-def echo(fn):
-    def wrapped(*v, **k):
-        name = fn.__name__
-        util.SMlog("#### VMOPS enter  %s ####" % name )
-        res = fn(*v, **k)
-        util.SMlog("#### VMOPS exit  %s ####" % name )
-        return res
-    return wrapped
-
-@echo
-def setup_iscsi(session, args):
-   uuid=args['uuid']
-   try:
-       cmd = ["b", "/opt/cloud/bin/setup_iscsi.sh", uuid]
-       txt = util.pread2(cmd)
-   except:
-       txt = ''
-   return '> DONE <'
- 
-@echo
-def preparemigration(session, args):
-    uuid = args['uuid']
-    try:
-        cmd = ["/opt/cloud/bin/make_migratable.sh", uuid]
-        util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("Catch prepare migration exception" )
-        txt = ''
-
-    return txt
-
-@echo
-def setIptables(session, args):
-    try:
-        '''cmd = ["/bin/bash", "/opt/cloud/bin/setupxenserver.sh"]
-        txt = util.pread2(cmd)'''
-        txt = 'success'
-    except:
-        util.SMlog("  setIptables execution failed "  )
-        txt = '' 
-
-    return txt
- 
-@echo
-def pingdomr(session, args):
-    host = args['host']
-    port = args['port']
-    socket.setdefaulttimeout(3)
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    try:
-        s.connect((host,int(port)))
-        txt = 'success'
-    except:
-        txt = ''
-    
-    s.close()
-
-    return txt
-
-@echo
-def kill_copy_process(session, args):
-    namelabel = args['namelabel']
-    try:
-        cmd = ["bash", "/opt/cloud/bin/kill_copy_process.sh", namelabel]
-        txt = util.pread2(cmd)
-    except:
-        txt = 'false'
-    return txt
-
-@echo
-def pingxenserver(session, args):
-    txt = 'success'
-    return txt
-
-@echo
-def ipassoc(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/ipassoc.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("  ip associate failed "  )
-        txt = '' 
-
-    return txt
-
-def pingtest(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/pingtest.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("  pingtest failed "  )
-        txt = ''
-
-    return txt
-
-@echo
-def savePassword(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/save_password_to_domr.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("  save password to domr failed "  )
-        txt = '' 
-
-    return txt
-
-@echo
-def saveDhcpEntry(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/dhcp_entry.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog(" save dhcp entry failed "  )
-        txt = '' 
-
-    return txt
-    
-@echo
-def lt2p_vpn(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/l2tp_vpn.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("l2tp vpn failed "  )
-        txt = '' 
-
-    return txt    
-
-@echo
-def setLinkLocalIP(session, args):
-    brName = args['brName']
-    try:
-        cmd = ["ip", "route", "del", "169.254.0.0/16"]
-        txt = util.pread2(cmd)
-    except:
-        txt = '' 
-    try:
-        cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"]
-        txt = util.pread2(cmd)
-    except:
-
-        try:
-            cmd = ["brctl", "addbr", brName]
-            txt = util.pread2(cmd)
-        except:
-            pass
- 
-        try:
-            cmd = ["ifconfig", brName, "169.254.0.1", "netmask", "255.255.0.0"]
-            txt = util.pread2(cmd)
-        except:
-            pass
-    try:
-        cmd = ["ip", "route", "add", "169.254.0.0/16", "dev", brName, "src", "169.254.0.1"]
-        txt = util.pread2(cmd)
-    except:
-        txt = '' 
-    txt = 'success'
-    return txt
-    
-@echo
-def setFirewallRule(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/call_firewall.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog(" set firewall rule failed "  )
-        txt = '' 
-
-    return txt
-
-@echo
-def setLoadBalancerRule(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/call_loadbalancer.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog(" set loadbalancer rule failed "  )
-        txt = '' 
-
-    return txt
-    
-@echo
-def createFile(session, args):
-    file_path = args['filepath']
-    file_contents = args['filecontents']
-
-    try:
-        f = open(file_path, "w")
-        f.write(file_contents)
-        f.close()
-        txt = 'success'
-    except:
-        util.SMlog(" failed to create HA proxy cfg file ")
-        txt = ''
-
-    return txt
-
-@echo
-def deleteFile(session, args):
-    file_path = args["filepath"]
-
-    try:
-        if os.path.isfile(file_path):
-            os.remove(file_path)
-        txt = 'success'
-    except:
-        util.SMlog(" failed to remove HA proxy cfg file ")
-        txt = ''
-
-    return txt
-
-
-@echo
-def networkUsage(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/networkUsage.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-    except:
-        util.SMlog("  network usage error "  )
-        txt = '' 
-
-    return txt
-    
-def get_private_nic(session, args):
-    vms = session.xenapi.VM.get_all()
-    host_uuid = args.get('host_uuid')
-    host = session.xenapi.host.get_by_uuid(host_uuid)
-    piflist = session.xenapi.host.get_PIFs(host)
-    mgmtnic = 'eth0'
-    for pif in piflist:
-        pifrec = session.xenapi.PIF.get_record(pif)
-        network = pifrec.get('network')
-        nwrec = session.xenapi.network.get_record(network)
-        if nwrec.get('name_label') == 'cloud-guest':
-            return pifrec.get('device')
-        if pifrec.get('management'):
-            mgmtnic = pifrec.get('device')
-    
-    return mgmtnic
-
-def chain_name(vm_name):
-    if vm_name.startswith('i-') or vm_name.startswith('r-'):
-        if vm_name.endswith('untagged'):
-            return '-'.join(vm_name.split('-')[:-1])
-    return vm_name
-
-def chain_name_def(vm_name):
-    if vm_name.startswith('i-'):
-        if vm_name.endswith('untagged'):
-            return '-'.join(vm_name.split('-')[:-2]) + "-def"
-        return '-'.join(vm_name.split('-')[:-1]) + "-def"
-    return vm_name
-  
-def egress_chain_name(vm_name):
-    return chain_name(vm_name) + "-eg"
-      
-@echo
-def can_bridge_firewall(session, args):
-    try:
-        util.pread2(['ebtables', '-V'])
-        util.pread2(['ipset', '-V'])
-    except:
-        return 'false'
-
-    host_uuid = args.get('host_uuid')
-    try:
-        util.pread2(['iptables', '-N', 'BRIDGE-FIREWALL'])
-        util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT'])
-        util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged',  '-p', 'udp', '--dport', '67', '--sport', '68',  '-j', 'ACCEPT'])
-        util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged',  '-p', 'udp', '--dport', '68', '--sport', '67',  '-j', 'ACCEPT'])
-        util.pread2(['iptables', '-D', 'FORWARD',  '-j', 'RH-Firewall-1-INPUT'])
-    except:
-        util.SMlog('Chain BRIDGE-FIREWALL already exists')
-    privnic = get_private_nic(session, args)
-    result = 'true'
-    try:
-        util.pread2(['/bin/bash', '-c', 'iptables -n -L FORWARD | grep BRIDGE-FIREWALL'])
-    except:
-        try:
-            util.pread2(['iptables', '-I', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '-j', 'BRIDGE-FIREWALL'])
-            util.pread2(['iptables', '-A', 'FORWARD', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', privnic, '-j', 'ACCEPT'])
-            util.pread2(['iptables', '-A', 'FORWARD', '-j', 'DROP'])
-        except:
-            return 'false'
-    default_ebtables_rules()
-    allow_egress_traffic(session)
-    if not os.path.exists('/var/run/cloud'):
-        os.makedirs('/var/run/cloud')
-    if not os.path.exists('/var/cache/cloud'):
-        os.makedirs('/var/cache/cloud')
-    #get_ipset_keyword()
- 
-    cleanup_rules_for_dead_vms(session)
-    cleanup_rules(session, args)
-    
-    return result
-
-@echo
-def default_ebtables_rules():
-    try:
-        util.pread2(['ebtables', '-N',  'DEFAULT_EBTABLES'])
-        util.pread2(['ebtables', '-A', 'FORWARD', '-j'  'DEFAULT_EBTABLES'])
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'ACCEPT'])
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Request', '-j', 'ACCEPT'])
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'ARP', '--arp-op', 'Reply', '-j', 'ACCEPT'])
-        # deny mac broadcast and multicast
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Broadcast', '-j', 'DROP']) 
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-d', 'Multicast', '-j', 'DROP']) 
-        # deny ip broadcast and multicast
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '255.255.255.255', '-j', 'DROP'])
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '--ip-dst', '224.0.0.0/4', '-j', 'DROP'])
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv4', '-j', 'RETURN'])
-        # deny ipv6
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv6', '-j', 'DROP'])
-        # deny vlan
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', '802_1Q', '-j', 'DROP'])
-        # deny all others (e.g., 802.1d, CDP)
-        util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES',  '-j', 'DROP'])
-    except:
-        util.SMlog('Chain DEFAULT_EBTABLES already exists')
-
-
-@echo
-def allow_egress_traffic(session):
-    devs = []
-    for pif in session.xenapi.PIF.get_all():
-        pif_rec = session.xenapi.PIF.get_record(pif)
-        vlan = pif_rec.get('VLAN')
-        dev = pif_rec.get('device')
-        if vlan == '-1':
-            devs.append(dev)
-        else:
-            devs.append(dev + "." + vlan)
-    for d in devs:
-        try:
-            util.pread2(['/bin/bash', '-c', "iptables -n -L FORWARD | grep '%s '" % d])
-        except:
-            try:
-                util.pread2(['iptables', '-I', 'FORWARD', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', d, '-j', 'ACCEPT'])
-            except:
-                util.SMlog("Failed to add FORWARD rule through to %s" % d)
-                return 'false'
-    return 'true'
-
-
-def ipset(ipsetname, proto, start, end, ips):
-    try:
-        util.pread2(['ipset', '-N', ipsetname, 'iptreemap'])
-    except:
-        util.SMlog("ipset chain already exists" + ipsetname)
-
-    result = True
-    ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000)
-
-    try: 
-        util.pread2(['ipset', '-N', ipsettmp, 'iptreemap']) 
-    except:
-        util.SMlog("Failed to create temp ipset, reusing old name= " + ipsettmp)
-        try: 
-            util.pread2(['ipset', '-F', ipsettmp]) 
-        except:
-            util.SMlog("Failed to clear old temp ipset name=" + ipsettmp)
-            return False
-        
-    try: 
-        for ip in ips:
-            try:
-                util.pread2(['ipset', '-A', ipsettmp, ip])
-            except CommandException, cex:
-                if cex.reason.rfind('already in set') == -1:
-                   raise
-    except:
-        util.SMlog("Failed to program ipset " + ipsetname)
-        util.pread2(['ipset', '-F', ipsettmp]) 
-        util.pread2(['ipset', '-X', ipsettmp]) 
-        return False
-
-    try: 
-        util.pread2(['ipset', '-W', ipsettmp, ipsetname]) 
-    except:
-        util.SMlog("Failed to swap ipset " + ipsetname)
-        result = False
-
-    try: 
-        util.pread2(['ipset', '-F', ipsettmp]) 
-        util.pread2(['ipset', '-X', ipsettmp]) 
-    except:
-        # if the temporary name clashes next time we'll just reuse it
-        util.SMlog("Failed to delete temp ipset " + ipsettmp)
-
-    return result
-
-@echo 
-def destroy_network_rules_for_vm(session, args):
-    vm_name = args.pop('vmName')
-    vmchain = chain_name(vm_name)
-    vmchain_egress = egress_chain_name(vm_name)
-    vmchain_default = chain_name_def(vm_name)
-    
-    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
-    if vm_name.startswith('i-') or vm_name.startswith('r-') or vm_name.startswith('l-'):
-        try:
-            util.pread2(['iptables', '-F', vmchain_default])
-            util.pread2(['iptables', '-X', vmchain_default])
-        except:
-            util.SMlog("Ignoring failure to delete  chain " + vmchain_default)
-    
-    destroy_ebtables_rules(vmchain)
-    
-    try:
-        util.pread2(['iptables', '-F', vmchain])
-        util.pread2(['iptables', '-X', vmchain])
-    except:
-        util.SMlog("Ignoring failure to delete ingress chain " + vmchain)
-        
-   
-    try:
-        util.pread2(['iptables', '-F', vmchain_egress])
-        util.pread2(['iptables', '-X', vmchain_egress])
-    except:
-        util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress)
-    
-    remove_rule_log_for_vm(vm_name)
-    
-    if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]:
-        return 'true'
-    
-    try:
-        setscmd = "ipset --save | grep " +  vmchain + " | grep '^-N' | awk '{print $2}'"
-        setsforvm = util.pread2(['/bin/bash', '-c', setscmd]).split('\n')
-        for set in setsforvm:
-            if set != '':
-                util.pread2(['ipset', '-F', set])       
-                util.pread2(['ipset', '-X', set])       
-    except:
-        util.SMlog("Failed to destroy ipsets for %" % vm_name)
-    
-    
-    return 'true'
-
-@echo
-def destroy_ebtables_rules(vm_chain):
-    
-    delcmd = "ebtables-save | grep " +  vm_chain + " | sed 's/-A/-D/'"
-    delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n')
-    delcmds.pop()
-    for cmd in delcmds:
-        try:
-            dc = cmd.split(' ')
-            dc.insert(0, 'ebtables')
-            util.pread2(dc)
-        except:
-            util.SMlog("Ignoring failure to delete ebtables rules for vm " + vm_chain)
-    try:
-        util.pread2(['ebtables', '-F', vm_chain])
-        util.pread2(['ebtables', '-X', vm_chain])
-    except:
-            util.SMlog("Ignoring failure to delete ebtables chain for vm " + vm_chain)   
-
-@echo
-def destroy_arptables_rules(vm_chain):
-    delcmd = "arptables -vL FORWARD | grep " + vm_chain + " | sed 's/-i any//' | sed 's/-o any//' | awk '{print $1,$2,$3,$4}' "
-    delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n')
-    delcmds.pop()
-    for cmd in delcmds:
-        try:
-            dc = cmd.split(' ')
-            dc.insert(0, 'arptables')
-            dc.insert(1, '-D')
-            dc.insert(2, 'FORWARD')
-            util.pread2(dc)
-        except:
-            util.SMlog("Ignoring failure to delete arptables rules for vm " + vm_chain)
-    
-    try:
-        util.pread2(['arptables', '-F', vm_chain])
-        util.pread2(['arptables', '-X', vm_chain])
-    except:
-        util.SMlog("Ignoring failure to delete arptables chain for vm " + vm_chain) 
-              
-@echo
-def default_ebtables_antispoof_rules(vm_chain, vifs, vm_ip, vm_mac):
-    if vm_mac == 'ff:ff:ff:ff:ff:ff':
-        util.SMlog("Ignoring since mac address is not valid")
-        return 'true'
-    
-    try:
-        util.pread2(['ebtables', '-N', vm_chain])
-    except:
-        try:
-            util.pread2(['ebtables', '-F', vm_chain])
-        except:
-            util.SMlog("Failed to create ebtables antispoof chain, skipping")
-            return 'true'
-
-    # note all rules for packets into the bridge (-i) precede all output rules (-o)
-    # always start after the first rule in the FORWARD chain that jumps to DEFAULT_EBTABLES chain
-    try:
-        for vif in vifs:
-            util.pread2(['ebtables', '-I', 'FORWARD', '2', '-i',  vif,  '-j', vm_chain])
-            util.pread2(['ebtables', '-A', 'FORWARD', '-o',  vif, '-j', vm_chain])
-    except:
-        util.SMlog("Failed to program default ebtables FORWARD rules for %s" % vm_chain)
-        return 'false'
-
-    try:
-        for vif in vifs:
-            # only allow source mac that belongs to the vm
-	    util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-s', '!', vm_mac,  '-j', 'DROP'])
-            # do not allow fake dhcp responses
-            util.pread2(['ebtables', '-A', vm_chain, '-i', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '68', '-j', 'DROP'])
-            # do not allow snooping of dhcp requests
-            util.pread2(['ebtables', '-A', vm_chain, '-o', vif, '-p', 'IPv4', '--ip-proto', 'udp', '--ip-dport', '67', '-j', 'DROP'])
-    except:
-        util.SMlog("Failed to program default ebtables antispoof rules for %s" % vm_chain)
-        return 'false'
-
-    return 'true'
-
-@echo
-def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac):
-    if vm_mac == 'ff:ff:ff:ff:ff:ff':
-        util.SMlog("Ignoring since mac address is not valid")
-        return 'true'
-
-    try:
-        util.pread2(['arptables',  '-N', vm_chain])
-    except:
-        try:
-            util.pread2(['arptables', '-F', vm_chain])
-        except:
-            util.SMlog("Failed to create arptables rule, skipping")
-            return 'true'
-
-    # note all rules for packets into the bridge (-i) precede all output rules (-o)
-    try:
-        for vif in vifs:
-           util.pread2(['arptables',  '-I', 'FORWARD', '-i',  vif, '-j', vm_chain])
-           util.pread2(['arptables',  '-A', 'FORWARD', '-o',  vif, '-j', vm_chain])
-    except:
-        util.SMlog("Failed to program default arptables rules in FORWARD chain vm=" + vm_chain)
-        return 'false'
-    
-    try:
-        for vif in vifs:
-            #accept arp replies into the bridge as long as the source mac and ips match the vm
-            util.pread2(['arptables',  '-A', vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac',  vm_mac, '--source-ip',  vm_ip, '-j', 'ACCEPT'])
-            #accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts
-            #also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination
-            util.pread2(['arptables',  '-A', vm_chain, '-i', vif, '--opcode', 'Request',  '--source-mac',  vm_mac, '--source-ip',  vm_ip, '-j', 'RETURN'])
-            #accept any arp requests to this vm as long as the request is for this vm's ip
-            util.pread2(['arptables',  '-A', vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT'])   
-            #accept any arp replies to this vm as long as the mac and ip matches
-            util.pread2(['arptables',  '-A', vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT'])   
-        util.pread2(['arptables',  '-A', vm_chain,  '-j', 'DROP'])
-
-    except:
-        util.SMlog("Failed to program default arptables  rules")
-        return 'false'
-
-    return 'true'
-
-@echo
-def default_network_rules_systemvm(session, args):
-    vm_name = args.pop('vmName')
-    try:
-        vm = session.xenapi.VM.get_by_name_label(vm_name)
-        if len(vm) != 1:
-             return 'false'
-        vm_rec = session.xenapi.VM.get_record(vm[0])
-        vm_vifs = vm_rec.get('VIFs')
-        vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs]
-        domid = vm_rec.get('domid')
-    except:
-        util.SMlog("### Failed to get domid or vif list for vm  ##" + vm_name)
-        return 'false'
-    
-    if domid == '-1':
-        util.SMlog("### Failed to get domid for vm (-1):  " + vm_name)
-        return 'false'
-
-    vifs = ["vif" + domid + "." + v for v in vifnums]
-    #vm_name =  '-'.join(vm_name.split('-')[:-1])
-    vmchain = chain_name(vm_name)
-   
- 
-    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
-  
-    try:
-        util.pread2(['iptables', '-N', vmchain])
-    except:
-        util.pread2(['iptables', '-F', vmchain])
-    
-    allow_egress_traffic(session)
-  
-    for vif in vifs:
-        try:
-            util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain])
-            util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain])
-            util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', 'RETURN'])
-        except:
-            util.SMlog("Failed to program default rules")
-            return 'false'
-	
-	
-    util.pread2(['iptables', '-A', vmchain, '-j', 'ACCEPT'])
-    
-    if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False:
-        util.SMlog("Failed to log default network rules for systemvm, ignoring")
-    return 'true'
-
-
-@echo
-def default_network_rules(session, args):
-    vm_name = args.pop('vmName')
-    vm_ip = args.pop('vmIP')
-    vm_id = args.pop('vmID')
-    vm_mac = args.pop('vmMAC')
-    
-    try:
-        vm = session.xenapi.VM.get_by_name_label(vm_name)
-        if len(vm) != 1:
-             util.SMlog("### Failed to get record for vm  " + vm_name)
-             return 'false'
-        vm_rec = session.xenapi.VM.get_record(vm[0])
-        domid = vm_rec.get('domid')
-    except:
-        util.SMlog("### Failed to get domid for vm " + vm_name)
-        return 'false'
-    if domid == '-1':     
-        util.SMlog("### Failed to get domid for vm (-1):  " + vm_name)
-        return 'false'
-    
-    vif = "vif" + domid + ".0"
-    tap = "tap" + domid + ".0"
-    vifs = [vif]
-    try:
-        util.pread2(['ifconfig', tap])
-        vifs.append(tap)
-    except:
-        pass
-
-    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
-
-     
-    vmchain =  chain_name(vm_name)
-    vmchain_egress =  egress_chain_name(vm_name)
-    vmchain_default = chain_name_def(vm_name)
-    
-    destroy_ebtables_rules(vmchain)
-    
-
-    try:
-        util.pread2(['iptables', '-N', vmchain])
-    except:
-        util.pread2(['iptables', '-F', vmchain])
-    
-    try:
-        util.pread2(['iptables', '-N', vmchain_egress])
-    except:
-        util.pread2(['iptables', '-F', vmchain_egress])
-        
-    try:
-        util.pread2(['iptables', '-N', vmchain_default])
-    except:
-        util.pread2(['iptables', '-F', vmchain_default])        
-
-    try:
-        for v in vifs:
-            util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default])
-            util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default])
-        util.pread2(['iptables', '-A', vmchain_default, '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT'])
-        #allow dhcp
-        for v in vifs:
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-p', 'udp', '--dport', '67', '--sport', '68',  '-j', 'ACCEPT'])
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-p', 'udp', '--dport', '68', '--sport', '67',  '-j', 'ACCEPT'])
-
-        #don't let vm spoof its ip address
-        for v in vifs:
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN'])
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', '!', vm_ip, '-j', 'DROP'])
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '--destination', '!', vm_ip, '-j', 'DROP'])
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress])
-        
-        for v in vifs:
-            util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v,  '-j', vmchain])
-    except:
-        util.SMlog("Failed to program default rules for vm " + vm_name)
-        return 'false'
-    
-    default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac)
-    default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac)
-    
-    if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False:
-        util.SMlog("Failed to log default network rules, ignoring")
-        
-    util.SMlog("Programmed default rules for vm " + vm_name)
-    return 'true'
-
-@echo
-def check_domid_changed(session, vmName):
-    curr_domid = '-1'
-    try:
-        vm = session.xenapi.VM.get_by_name_label(vmName)
-        if len(vm) != 1:
-             util.SMlog("### Could not get record for vm ## " + vmName)
-        else:
-            vm_rec = session.xenapi.VM.get_record(vm[0])
-            curr_domid = vm_rec.get('domid')
-    except:
-        util.SMlog("### Failed to get domid for vm  ## " + vmName)
-        
-    
-    logfilename = "/var/run/cloud/" + vmName +".log"
-    if not os.path.exists(logfilename):
-        return ['-1', curr_domid]
-    
-    lines = (line.rstrip() for line in open(logfilename))
-    
-    [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno, _vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff']
-    for line in lines:
-        try:
-            [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno,_vmMac] = line.split(',')
-        except ValueError,v:
-            [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = line.split(',')
-        break
-    
-    return [curr_domid, old_domid]
-
-@echo
-def delete_rules_for_vm_in_bridge_firewall_chain(vmName):
-    vm_name = vmName
-    vmchain = chain_name_def(vm_name)
-    
-    delcmd = "iptables-save | grep '\-A BRIDGE-FIREWALL' | grep " +  vmchain + " | sed 's/-A/-D/'"
-    delcmds = util.pread2(['/bin/bash', '-c', delcmd]).split('\n')
-    delcmds.pop()
-    for cmd in delcmds:
-        try:
-            dc = cmd.split(' ')
-            dc.insert(0, 'iptables')
-            dc.pop()
-            util.pread2(filter(None, dc))
-        except:
-              util.SMlog("Ignoring failure to delete rules for vm " + vmName)
-
-  
-@echo
-def network_rules_for_rebooted_vm(session, vmName):
-    vm_name = vmName
-    [curr_domid, old_domid] = check_domid_changed(session, vm_name)
-    
-    if curr_domid == old_domid:
-        return True
-    
-    if old_domid == '-1':
-        return True
-    
-    if curr_domid == '-1':
-        return True
-    
-    util.SMlog("Found a rebooted VM -- reprogramming rules for  " + vm_name)
-    
-    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
-    if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]:
-        default_network_rules_systemvm(session, {"vmName":vm_name})
-        return True
-    
-    vif = "vif" + curr_domid + ".0"
-    tap = "tap" + curr_domid + ".0"
-    vifs = [vif]
-    try:
-        util.pread2(['ifconfig', tap])
-        vifs.append(tap)
-    except:
-        pass
-    vmchain = chain_name(vm_name)
-    vmchain_default = chain_name_def(vm_name)
-
-    for v in vifs:
-        util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default])
-        util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default])
-
-    #change antispoof rule in vmchain
-    try:
-        delcmd = "iptables-save | grep '\-A " +  vmchain_default + "' | grep  physdev-in | sed 's/-A/-D/'"
-        delcmd2 = "iptables-save | grep '\-A " +  vmchain_default + "' | grep  physdev-out | sed 's/-A/-D/'"
-        inscmd = "iptables-save | grep '\-A " +  vmchain_default + "' | grep  physdev-in | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' "
-        inscmd2 = "iptables-save| grep '\-A " +  vmchain_default + "' | grep  physdev-in | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' "
-        inscmd3 = "iptables-save | grep '\-A " +  vmchain_default + "' | grep  physdev-out | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' "
-        inscmd4 = "iptables-save| grep '\-A " +  vmchain_default + "' | grep  physdev-out | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' "
-        
-        ipts = []
-        for cmd in [delcmd, delcmd2, inscmd, inscmd2, inscmd3, inscmd4]:
-            cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n')
-            cmds.pop()
-            for c in cmds:
-                    ipt = c.split(' ')
-                    ipt.insert(0, 'iptables')
-                    ipt.pop()
-                    ipts.append(ipt)
-        
-        for ipt in ipts:
-            try:
-                util.pread2(filter(None,ipt))
-            except:
-                util.SMlog("Failed to rewrite antispoofing rules for vm " + vm_name)
-        
-        util.pread2(['/bin/bash', '-c', 'iptables -D ' + vmchain_default + " -j " + vmchain])
-        util.pread2(['/bin/bash', '-c', 'iptables -A ' + vmchain_default + " -j " + vmchain])
-    except:
-        util.SMlog("No rules found for vm " + vm_name)
-
-    destroy_ebtables_rules(vmchain)
-    destroy_arptables_rules(vmchain)
-    [vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain)
-    default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac)
-    default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac)
-    rewrite_rule_log_for_vm(vm_name, curr_domid)
-    return True
-
-def rewrite_rule_log_for_vm(vm_name, new_domid):
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-    if not os.path.exists(logfilename):
-        return 
-    lines = (line.rstrip() for line in open(logfilename))
-    
-    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1','ff:ff:ff:ff:ff:ff']
-    for line in lines:
-        try:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',')
-            break
-        except ValueError,v:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
-    
-    write_rule_log_for_vm(_vmName, _vmID, _vmIP, new_domid, _signature, '-1', _vmMac)
-
-def get_rule_log_for_vm(session, vmName):
-    vm_name = vmName;
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-    if not os.path.exists(logfilename):
-        return ''
-    
-    lines = (line.rstrip() for line in open(logfilename))
-    
-    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff']
-    for line in lines:
-        try:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',')
-            break
-        except ValueError,v:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
-    
-    return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno])
-
-@echo
-def get_vm_mac_ip_from_log(vm_name):
-    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '0.0.0.0', '-1', '_', '-1','ff:ff:ff:ff:ff:ff']
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-    if not os.path.exists(logfilename):
-        return ['_', '_']
-    
-    lines = (line.rstrip() for line in open(logfilename))
-    for line in lines:
-        try:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = line.split(',')
-            break
-        except ValueError,v:
-            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
-    
-    return [ _vmIP, _vmMac]
-
-@echo
-def get_rule_logs_for_vms(session, args):
-    host_uuid = args.pop('host_uuid')
-    try:
-        thishost = session.xenapi.host.get_by_uuid(host_uuid)
-        hostrec = session.xenapi.host.get_record(thishost)
-        vms = hostrec.get('resident_VMs')
-    except:
-        util.SMlog("Failed to get host from uuid " + host_uuid)
-        return ' '
-    
-    result = []
-    try:
-        for name in [session.xenapi.VM.get_name_label(x) for x in vms]:
-            if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-', 'l-'] ]:
-                continue
-            network_rules_for_rebooted_vm(session, name)
-            if name.startswith('i-'):
-                log = get_rule_log_for_vm(session, name)
-                result.append(log)
-    except:
-        util.SMlog("Failed to get rule logs, better luck next time!")
-        
-    return ";".join(result)
-
-@echo
-def cleanup_rules_for_dead_vms(session):
-  try:
-    vms = session.xenapi.VM.get_all()
-    cleaned = 0
-    for vm_name in [session.xenapi.VM.get_name_label(x) for x in vms]:
-        if 1 in [ vm_name.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-'] ]:
-            vm = session.xenapi.VM.get_by_name_label(vm_name)
-            if len(vm) != 1:
-                continue
-            vm_rec = session.xenapi.VM.get_record(vm[0])
-            state = vm_rec.get('power_state')
-            if state != 'Running' and state != 'Paused':
-                util.SMlog("vm " + vm_name + " is not running, cleaning up")
-                destroy_network_rules_for_vm(session, {'vmName':vm_name})
-                cleaned = cleaned+1
-                
-    util.SMlog("Cleaned up rules for " + str(cleaned) + " vms")
-  except:
-    util.SMlog("Failed to cleanup rules for dead vms!")
-        
-
-@echo
-def cleanup_rules(session, args):
-  instance = args.get('instance')
-  if not instance:
-    instance = 'VM'
-  resident_vms = []
-  try:
-    hostname = util.pread2(['/bin/bash', '-c', 'hostname']).split('\n')
-    if len(hostname) < 1:
-       raise Exception('Could not find hostname of this host')
-    thishost = session.xenapi.host.get_by_name_label(hostname[0])
-    if len(thishost) < 1:
-       raise Exception("Could not find host record from hostname %s of this host"%hostname[0])
-    hostrec = session.xenapi.host.get_record(thishost[0])
-    vms = hostrec.get('resident_VMs')
-    resident_vms = [session.xenapi.VM.get_name_label(x) for x in vms]
-    util.SMlog('cleanup_rules: found %s resident vms on this host %s' % (len(resident_vms)-1, hostname[0]))
- 
-    chainscmd = "iptables-save | grep '^:' | awk '{print $1}' | cut -d':' -f2 | sed 's/-def/-%s/'| sed 's/-eg//' | sort|uniq" % instance
-    chains = util.pread2(['/bin/bash', '-c', chainscmd]).split('\n')
-    vmchains = [ch  for ch in chains if 1 in [ ch.startswith(c) for c in ['r-', 'i-', 's-', 'v-', 'l-']]]
-    util.SMlog('cleanup_rules: found %s iptables chains for vms on this host %s' % (len(vmchains), hostname[0]))
-    cleaned = 0
-    cleanup = []
-    for chain in vmchains:
-        vm = session.xenapi.VM.get_by_name_label(chain)
-        if len(vm) != 1:
-            vm = session.xenapi.VM.get_by_name_label(chain + "-untagged")
-            if len(vm) != 1:
-                util.SMlog("chain " + chain + " does not correspond to a vm, cleaning up")
-                cleanup.append(chain)
-                continue
-        if chain not in resident_vms:
-            util.SMlog("vm " + chain + " is not running, cleaning up")
-            cleanup.append(chain)
-                
-    for vm_name in cleanup:
-        destroy_network_rules_for_vm(session, {'vmName':vm_name})
-                    
-    util.SMlog("Cleaned up rules for " + str(len(cleanup)) + " chains")
-    return str(len(cleanup))                
-  except Exception, ex:
-    util.SMlog("Failed to cleanup rules, reason= " + str(ex))
-    return '-1';
-
-@echo
-def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno):
-    vm_name = vmName;
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-    if not os.path.exists(logfilename):
-        util.SMlog("Failed to find logfile %s" %logfilename)
-        return [True, True, True]
-        
-    lines = (line.rstrip() for line in open(logfilename))
-    
-    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno,_vmMac] = ['_', '-1', '_', '-1', '_', '-1', 'ff:ff:ff:ff:ff:ff']
-    try:
-        for line in lines:
-            try:
-                [_vmName,_vmID,_vmIP,_domID,_signature,_seqno, _vmMac] = line.split(',')
-            except ValueError,v:
-                [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
-            break
-    except:
-        util.SMlog("Failed to parse log file for vm " + vmName)
-        remove_rule_log_for_vm(vmName)
-        return [True, True, True]
-    
-    reprogramDefault = False
-    if (domID != _domID) or (vmID != _vmID) or (vmIP != _vmIP):
-        util.SMlog("Change in default info set of vm %s" % vmName)
-        return [True, True, True]
-    else:
-        util.SMlog("No change in default info set of vm %s" % vmName)
-    
-    reprogramChain = False
-    rewriteLog = True
-    if (int(seqno) > int(_seqno)):
-        if (_signature != signature):
-            reprogramChain = True
-            util.SMlog("Seqno increased from %s to %s: reprogamming "\
-                        "ingress rules for vm %s" % (_seqno, seqno, vmName))
-        else:
-            util.SMlog("Seqno increased from %s to %s: but no change "\
-                        "in signature for vm: skip programming ingress "\
-                        "rules %s" % (_seqno, seqno, vmName))
-    elif (int(seqno) < int(_seqno)):
-        util.SMlog("Seqno decreased from %s to %s: ignoring these "\
-                        "ingress rules for vm %s" % (_seqno, seqno, vmName))
-        rewriteLog = False
-    elif (signature != _signature):
-        util.SMlog("Seqno %s stayed the same but signature changed from "\
-                    "%s to %s for vm %s" % (seqno, _signature, signature, vmName))
-        rewriteLog = True
-        reprogramChain = True
-    else:
-        util.SMlog("Seqno and signature stayed the same: %s : ignoring these "\
-                        "ingress rules for vm %s" % (seqno, vmName))
-        rewriteLog = False
-        
-    return [reprogramDefault, reprogramChain, rewriteLog]
-    
-
-@echo
-def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'):
-    vm_name = vmName
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-    util.SMlog("Writing log to " + logfilename)
-    logf = open(logfilename, 'w')
-    output = ','.join([vmName, vmID, vmIP, domID, signature, seqno, vmMac])
-    result = True
-    try:
-        logf.write(output)
-        logf.write('\n')
-    except:
-        util.SMlog("Failed to write to rule log file " + logfilename)
-        result = False
-        
-    logf.close()
-    
-    return result
-
-@echo
-def remove_rule_log_for_vm(vmName):
-    vm_name = vmName
-    logfilename = "/var/run/cloud/" + vm_name +".log"
-
-    result = True
-    try:
-        os.remove(logfilename)
-    except:
-        util.SMlog("Failed to delete rule log file " + logfilename)
-        result = False
-    
-    return result
-
-@echo
-def inflate_rules (zipped):
-   return zlib.decompress(base64.b64decode(zipped))
-
-@echo
-def cache_ipset_keyword():
-    tmpname = 'ipsetqzvxtmp'
-    try:
-        util.pread2(['/bin/bash', '-c', 'ipset -N ' + tmpname + ' iptreemap'])
-    except:
-        util.pread2(['/bin/bash', '-c', 'ipset -F ' + tmpname])
-
-    try:
-        util.pread2(['/bin/bash', '-c', 'iptables -A INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT'])
-        util.pread2(['/bin/bash', '-c', 'iptables -D INPUT -m set --set ' + tmpname + ' src' + ' -j ACCEPT'])
-        keyword = 'set'
-    except:
-        keyword = 'match-set'
-    
-    try:
-       util.pread2(['/bin/bash', '-c', 'ipset -X ' + tmpname])
-    except:
-       pass
-       
-    cachefile = "/var/cache/cloud/ipset.keyword"
-    util.SMlog("Writing ipset keyword to " + cachefile)
-    cachef = open(cachefile, 'w')
-    try:
-        cachef.write(keyword)
-        cachef.write('\n')
-    except:
-        util.SMlog("Failed to write to cache file " + cachef)
-        
-    cachef.close()
-    return keyword
-    
-@echo
-def get_ipset_keyword():
-    cachefile = "/var/cache/cloud/ipset.keyword"
-    keyword = 'match-set'
-    
-    if not os.path.exists(cachefile):
-        util.SMlog("Failed to find ipset keyword cachefile %s" %cachefile)
-        keyword = cache_ipset_keyword()
-    else:
-        lines = (line.rstrip() for line in open(cachefile))
-        for line in lines:
-            keyword = line
-            break
-
-    return keyword
-
-@echo
-def network_rules(session, args):
-  try:
-    vm_name = args.get('vmName')
-    vm_ip = args.get('vmIP')
-    vm_id = args.get('vmID')
-    vm_mac = args.get('vmMAC')
-    signature = args.pop('signature')
-    seqno = args.pop('seqno')
-    deflated = 'false'
-    if 'deflated' in args:
-        deflated = args.pop('deflated')
-    
-    try:
-        vm = session.xenapi.VM.get_by_name_label(vm_name)
-        if len(vm) != 1:
-             util.SMlog("### Could not get record for vm ## " + vm_name)
-             return 'false'
-        vm_rec = session.xenapi.VM.get_record(vm[0])
-        domid = vm_rec.get('domid')
-    except:
-        util.SMlog("### Failed to get domid for vm  ## " + vm_name)
-        return 'false'
-    if domid == '-1':
-        util.SMlog("### Failed to get domid for vm (-1):  " + vm_name)
-        return 'false'
-   
-    vif = "vif" + domid + ".0"
-    tap = "tap" + domid + ".0"
-    vifs = [vif]
-    try:
-        util.pread2(['ifconfig', tap])
-        vifs.append(tap)
-    except:
-        pass
-   
-
-    reason = 'seqno_change_or_sig_change'
-    [reprogramDefault, reprogramChain, rewriteLog] = \
-             check_rule_log_for_vm (vm_name, vm_id, vm_ip, domid, signature, seqno)
-    
-    if not reprogramDefault and not reprogramChain:
-        util.SMlog("No changes detected between current state and received state")
-        reason = 'seqno_same_sig_same'
-        if rewriteLog:
-            reason = 'seqno_increased_sig_same'
-            write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac)
-        util.SMlog("Programming network rules for vm  %s seqno=%s signature=%s guestIp=%s,"\
-               " do nothing, reason=%s" % (vm_name, seqno, signature, vm_ip, reason))
-        return 'true'
-           
-    if not reprogramChain:
-        util.SMlog("###Not programming any ingress rules since no changes detected?")
-        return 'true'
-
-    if reprogramDefault:
-        util.SMlog("Change detected in vmId or vmIp or domId, resetting default rules")
-        default_network_rules(session, args)
-        reason = 'domid_change'
-    
-    rules = args.pop('rules')
-    if deflated.lower() == 'true':
-       rules = inflate_rules (rules)
-    keyword = '--' + get_ipset_keyword() 
-    lines = rules.split(' ')
-
-    util.SMlog("Programming network rules for vm  %s seqno=%s numrules=%s signature=%s guestIp=%s,"\
-              " update iptables, reason=%s" % (vm_name, seqno, len(lines), signature, vm_ip, reason))
-    
-    cmds = []
-    egressrules = 0
-    for line in lines:
-        tokens = line.split(':')
-        if len(tokens) != 5:
-          continue
-        type = tokens[0]
-        protocol = tokens[1]
-        start = tokens[2]
-        end = tokens[3]
-        cidrs = tokens.pop();
-        ips = cidrs.split(",")
-        ips.pop()
-        allow_any = False
-
-        if type == 'E':
-            vmchain = egress_chain_name(vm_name)
-            action = "RETURN"
-            direction = "dst"
-            egressrules = egressrules + 1
-        else:
-            vmchain = chain_name(vm_name)
-            action = "ACCEPT"
-            direction = "src"
-        if  '0.0.0.0/0' in ips:
-            i = ips.index('0.0.0.0/0')
-            del ips[i]
-            allow_any = True
-        range = start + ":" + end
-        if ips:    
-            ipsetname = vmchain + "_" + protocol + "_" + start + "_" + end
-            if start == "-1":
-                ipsetname = vmchain + "_" + protocol + "_any"
-
-            if ipset(ipsetname, protocol, start, end, ips) == False:
-                util.SMlog(" failed to create ipset for rule " + str(tokens))
-
-            if protocol == 'all':
-                iptables = ['iptables', '-I', vmchain, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action]
-            elif protocol != 'icmp':
-                iptables = ['iptables', '-I', vmchain, '-p',  protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-m', 'set', keyword, ipsetname, direction, '-j', action]
-            else:
-                range = start + "/" + end
-                if start == "-1":
-                    range = "any"
-                iptables = ['iptables', '-I', vmchain, '-p',  'icmp', '--icmp-type',  range,  '-m', 'set', keyword, ipsetname, direction, '-j', action]
-                
-            cmds.append(iptables)
-            util.SMlog(iptables)
-        
-        if allow_any and protocol != 'all':
-            if protocol != 'icmp':
-                iptables = ['iptables', '-I', vmchain, '-p',  protocol, '-m', protocol, '--dport', range, '-m', 'state', '--state', 'NEW', '-j', action]
-            else:
-                range = start + "/" + end
-                if start == "-1":
-                    range = "any"
-                iptables = ['iptables', '-I', vmchain, '-p',  'icmp', '--icmp-type',  range, '-j', action]
-            cmds.append(iptables)
-            util.SMlog(iptables)
-      
-    vmchain = chain_name(vm_name)        
-    util.pread2(['iptables', '-F', vmchain])
-    egress_vmchain = egress_chain_name(vm_name)        
-    util.pread2(['iptables', '-F', egress_vmchain])
-    
-    for cmd in cmds:
-        util.pread2(cmd)
-        
-    if egressrules == 0 :
-        util.pread2(['iptables', '-A', egress_vmchain, '-j', 'RETURN'])
-    else:
-        util.pread2(['iptables', '-A', egress_vmchain, '-j', 'DROP'])
-   
-    util.pread2(['iptables', '-A', vmchain, '-j', 'DROP'])
-
-    if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, signature, seqno, vm_mac) == False:
-        return 'false'
-    
-    return 'true'
-  except:
-    util.SMlog("Failed to network rule !")
-
-@echo
-def checkRouter(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/getRouterStatus.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-    except:
-        util.SMlog("  check router status fail! ")
-        txt = '' 
-
-    return txt
-
-@echo
-def bumpUpPriority(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/bumpUpPriority.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        util.SMlog("bump up priority fail! ")
-        txt = ''
-
-    return txt
-    
-@echo
-def setDNATRule(session, args):
-    add = args["add"]
-    if add == "false":
-        util.pread2(["iptables", "-t", "nat", "-F"])
-    else:
-        ip = args["ip"]
-        port = args["port"]
-        util.pread2(["iptables", "-t", "nat", "-F"])
-        util.pread2(["iptables", "-t", "nat", "-A", "PREROUTING", "-i", "xenbr0", "-p", "tcp", "--dport", port, "-m", "state", "--state", "NEW", "-j", "DNAT", "--to-destination", ip +":443"])
-    return ""
-
-@echo
-def createISOVHD(session, args):
-    # Should not create the VDI if the systemvm.iso does not exist
-    if not os.path.exists('/usr/share/xcp/packages/iso/systemvm.iso'):
-        return "Failed"
-    #hack for XCP on ubuntu 12.04, as can't attach iso to a vm
-    vdis = session.xenapi.VDI.get_by_name_label("systemvm-vdi");
-    util.SMlog(vdis)
-    if len(vdis) > 0:
-        vdi_record = session.xenapi.VDI.get_record(vdis[0])
-        vdi_uuid = vdi_record['uuid']
-        return vdi_uuid
-    localsrUUid = args['uuid'];
-    sr = session.xenapi.SR.get_by_uuid(localsrUUid)
-    data = {'name_label': "systemvm-vdi",
-            'SR': sr,
-            'virtual_size': '50000000',
-            'type': 'user',
-            'sharable':False,
-            'read_only':False,
-            'other_config':{},
-            }
-    vdi = session.xenapi.VDI.create(data);
-    vdi_record = session.xenapi.VDI.get_record(vdi)
-
-    vdi_uuid = vdi_record['uuid']
-
-    vms = session.xenapi.VM.get_all()
-    ctrldom = None
-    for vm in vms:
-        dom0 = session.xenapi.VM.get_is_control_domain(vm)
-        if dom0 is False:
-            continue
-        else:
-            ctrldom = vm
-
-    if ctrldom is None:
-        return "Failed"
-
-    vbds = session.xenapi.VM.get_VBDs(ctrldom)
-    if len(vbds) == 0:
-        vbd = session.xenapi.VBD.create({"VDI": vdi, "VM": ctrldom, "type":"Disk", "device": "xvda4",  "bootable": False, "mode": "RW", "userdevice": "4", "empty":False,
-                              "other_config":{}, "qos_algorithm_type":"", "qos_algorithm_params":{}})
-    else:
-        vbd = vbds[0]
-
-    vbdr = session.xenapi.VBD.get_record(vbd)
-    if session.xenapi.VBD.get_currently_attached(vbd) is False:
-        session.xenapi.VBD.plug(vbd)
-        vbdr = session.xenapi.VBD.get_record(vbd)
-    util.pread2(["dd", "if=/usr/share/xcp/packages/iso/systemvm.iso", "of=" + "/dev/" + vbdr["device"]])
-    session.xenapi.VBD.unplug(vbd)
-    session.xenapi.VBD.destroy(vbd)
-    return vdi_uuid
-
-@echo
-def getDomRVersion(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/getDomRVersion.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-    except:
-        util.SMlog("  get domR version fail! ")
-        txt = '' 
-
-    return txt
-
-if __name__ == "__main__":
-     XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi,
-                            "preparemigration": preparemigration, 
-                            "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver,  
-                            "ipassoc": ipassoc, "savePassword": savePassword, 
-                            "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, 
-                            "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, 
-                            "networkUsage": networkUsage, "network_rules":network_rules, 
-                            "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules,
-                            "destroy_network_rules_for_vm":destroy_network_rules_for_vm, 
-                            "default_network_rules_systemvm":default_network_rules_systemvm, 
-                            "get_rule_logs_for_vms":get_rule_logs_for_vms, 
-                            "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn,
-                            "cleanup_rules":cleanup_rules, "checkRouter":checkRouter,
-                            "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion,
-                            "kill_copy_process":kill_copy_process,
-                            "createISOVHD":createISOVHD,
-                            "setDNATRule":setDNATRule})
diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py
index e9f49d4..2b81c3f 100755
--- a/scripts/vm/network/security_group.py
+++ b/scripts/vm/network/security_group.py
@@ -16,14 +16,12 @@
 # specific language governing permissions and limitations
 # under the License.
 
-import cloud_utils
-from cloud_utils import Command
-from cloudutils.configFileOps import configFileOps
+import argparse
+from subprocess import check_output, CalledProcessError
 import logging
 import sys
 import os
 import xml.dom.minidom
-from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
 import re
 import libvirt
 import fcntl
@@ -34,17 +32,10 @@
 
 logpath = "/var/run/cloud/"        # FIXME: Logs should reside in /var/log/cloud
 lock_file = "/var/lock/cloudstack_security_group.lock"
-iptables = Command("iptables")
-bash = Command("/bin/bash")
-ebtables = Command("ebtables")
 driver = "qemu:///system"
-cfo = configFileOps("/etc/cloudstack/agent/agent.properties")
-hyper = cfo.getEntry("hypervisor.type")
-if hyper == "lxc":
-    driver = "lxc:///"
-
 lock_handle = None
 
+
 def obtain_file_lock(path):
     global lock_handle
 
@@ -57,21 +48,27 @@
 
     return False
 
+
 def execute(cmd):
     logging.debug(cmd)
-    return bash("-c", cmd).stdout
+    try:
+        return check_output(cmd, shell=True)
+    except CalledProcessError as e:
+        logging.exception('Command exited non-zero: %s', cmd)
+        raise
+
 
 def can_bridge_firewall(privnic):
     try:
         execute("which iptables")
     except:
-        print "no iptables on your host machine"
+        print("no iptables on your host machine")
         sys.exit(1)
 
     try:
         execute("which ebtables")
     except:
-        print "no ebtables on your host machine"
+        print("no ebtables on your host machine")
         sys.exit(2)
 
 
@@ -82,49 +79,29 @@
     cleanup_rules()
 
     return True
-'''
-def ipset(ipsetname, proto, start, end, ips):
-    try:
-        check_call(['ipset', '-N', ipsetname, 'iptreemap'])
-    except:
-        logging.debug("ipset chain already exists" + ipsetname)
 
-    result = True
-    ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000)
 
-    try:
-        check_call(['ipset', '-N', ipsettmp, 'iptreemap'])
-        for ip in ips:
-            try:
-                check_call(['ipset', '-A', ipsettmp, ip])
-            except CommandException, cex:
-                if cex.reason.rfind('already in set') == -1:
-                   raise
-        check_call(['ipset', '-W', ipsettmp, ipsetname])
-        check_call(['ipset', '-X', ipsettmp])
-    except:
-        logging.debug("Failed to program ipset " + ipsetname)
-        result = False
+def get_libvirt_connection():
+    conn = libvirt.openReadOnly(driver)
+    if not conn:
+        raise Exception('Failed to open connection to the hypervisor')
 
-    return result
-'''
+    return conn
+
+
 def virshlist(states):
-
-    libvirt_states={ 'running'  : libvirt.VIR_DOMAIN_RUNNING,
-                     'shutoff'  : libvirt.VIR_DOMAIN_SHUTOFF,
-                     'shutdown' : libvirt.VIR_DOMAIN_SHUTDOWN,
-                     'paused'   : libvirt.VIR_DOMAIN_PAUSED,
-                     'nostate'  : libvirt.VIR_DOMAIN_NOSTATE,
-                     'blocked'  : libvirt.VIR_DOMAIN_BLOCKED,
-                     'crashed'  : libvirt.VIR_DOMAIN_CRASHED,
+    libvirt_states={ 'running': libvirt.VIR_DOMAIN_RUNNING,
+                     'shutoff': libvirt.VIR_DOMAIN_SHUTOFF,
+                     'shutdown': libvirt.VIR_DOMAIN_SHUTDOWN,
+                     'paused': libvirt.VIR_DOMAIN_PAUSED,
+                     'nostate': libvirt.VIR_DOMAIN_NOSTATE,
+                     'blocked': libvirt.VIR_DOMAIN_BLOCKED,
+                     'crashed': libvirt.VIR_DOMAIN_CRASHED,
     }
 
     searchstates = list(libvirt_states[state] for state in states)
 
-    conn = libvirt.openReadOnly(driver)
-    if conn == None:
-       print 'Failed to open connection to the hypervisor'
-       sys.exit(3)
+    conn = get_libvirt_connection()
 
     alldomains = map(conn.lookupByID, conn.listDomainsID())
     alldomains += map(conn.lookupByName, conn.listDefinedDomains())
@@ -138,49 +115,16 @@
 
     return domains
 
-def virshdomstate(domain):
-
-    libvirt_states={ libvirt.VIR_DOMAIN_RUNNING  : 'running',
-                     libvirt.VIR_DOMAIN_SHUTOFF  : 'shut off',
-                     libvirt.VIR_DOMAIN_SHUTDOWN : 'shut down',
-                     libvirt.VIR_DOMAIN_PAUSED   : 'paused',
-                     libvirt.VIR_DOMAIN_NOSTATE  : 'no state',
-                     libvirt.VIR_DOMAIN_BLOCKED  : 'blocked',
-                     libvirt.VIR_DOMAIN_CRASHED  : 'crashed',
-    }
-
-    conn = libvirt.openReadOnly(driver)
-    if conn == None:
-       print 'Failed to open connection to the hypervisor'
-       sys.exit(3)
-
-    try:
-        dom = (conn.lookupByName (domain))
-    except libvirt.libvirtError:
-        return None
-
-    state = libvirt_states[dom.info()[0]]
-    conn.close()
-
-    return state
 
 def virshdumpxml(domain):
-
-    conn = libvirt.openReadOnly(driver)
-    if conn == None:
-       print 'Failed to open connection to the hypervisor'
-       sys.exit(3)
-
     try:
-        dom = (conn.lookupByName (domain))
+        conn = get_libvirt_connection()
+        dom = conn.lookupByName(domain)
+        conn.close()
+        return dom.XMLDesc(0)
     except libvirt.libvirtError:
         return None
 
-    xml = dom.XMLDesc(0)
-    conn.close()
-
-    return xml
-
 
 def ipv6_link_local_addr(mac=None):
     eui64 = re.sub(r'[.:-]', '', mac).lower()
@@ -204,6 +148,11 @@
     return ip4s, ip6s
 
 
+def get_bridge_physdev(brname):
+    physdev = execute("bridge -o link show | awk '/master %s / && !/^[0-9]+: vnet/ {print $2}'" % brname)
+    return physdev.strip()
+
+
 def destroy_network_rules_for_vm(vm_name, vif=None):
     vmchain = iptables_chain_name(vm_name)
     vmchain_egress = egress_chain_name(vm_name)
@@ -238,7 +187,7 @@
     except:
         logging.debug("Ignoring failure to delete ipset " + vmchain)
 
-    if vif is not None:
+    if vif:
         try:
             dnats = execute("""iptables -t nat -S | awk '/%s/ { sub(/-A/, "-D", $1) ; print }'""" % vif ).split("\n")
             for dnat in filter(None, dnats):
@@ -251,13 +200,14 @@
     remove_rule_log_for_vm(vm_name)
     remove_secip_log_for_vm(vm_name)
 
-    if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]:
-        return 'true'
+    if 1 in [vm_name.startswith(c) for c in ['r-', 's-', 'v-']]:
+        return True
 
-    return 'true'
+    return True
+
 
 def destroy_ebtables_rules(vm_name, vif):
-    eb_vm_chain=ebtables_chain_name(vm_name)
+    eb_vm_chain = ebtables_chain_name(vm_name)
     delcmd = "ebtables -t nat -L PREROUTING | grep " + eb_vm_chain
     delcmds = []
     try:
@@ -288,6 +238,7 @@
         except:
             logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_name)
 
+
 def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif):
     eb_vm_chain=ebtables_chain_name(vm_name)
     vmchain_in = eb_vm_chain + "-in"
@@ -309,13 +260,13 @@
         execute("ebtables -t nat -A " + vmchain_out_ips + " -j DROP")
     except:
         logging.debug("Failed to program default rules")
-        return 'false'
+        return False
 
     try:
         execute("ebtables -t nat -A " + vmchain_in + " -s ! " + vm_mac + " -j DROP")
         execute("ebtables -t nat -A " + vmchain_in + " -p ARP -s ! " + vm_mac + " -j DROP")
         execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
-        if vm_ip is not None:
+        if vm_ip:
             execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j " + vmchain_in_ips)
             execute("ebtables -t nat -I " + vmchain_in_ips + " -p ARP --arp-ip-src " + vm_ip + " -j RETURN")
         execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Request -j ACCEPT")
@@ -323,11 +274,11 @@
         execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j DROP")
     except:
         logging.exception("Failed to program default ebtables IN rules")
-        return 'false'
+        return False
 
     try:
         execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP")
-        if vm_ip is not None:
+        if vm_ip:
             execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j " + vmchain_out_ips )
             execute("ebtables -t nat -I " + vmchain_out_ips + " -p ARP --arp-ip-dst " + vm_ip + " -j RETURN")
         execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Request -j ACCEPT")
@@ -335,12 +286,12 @@
         execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j DROP")
     except:
         logging.debug("Failed to program default ebtables OUT rules")
-        return 'false'
+        return False
 
 
 def default_network_rules_systemvm(vm_name, localbrname):
-    bridges = getBridges(vm_name)
-    domid = getvmId(vm_name)
+    bridges = get_bridges(vm_name)
+    domid = get_vm_id(vm_name)
     vmchain = iptables_chain_name(vm_name)
 
     delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
@@ -352,10 +303,10 @@
 
     for bridge in bridges:
         if bridge != localbrname:
-            if not addFWFramework(bridge):
+            if not add_fw_framework(bridge):
                 return False
-            brfw = getBrfw(bridge)
-            vifs = getVifsForBridge(vm_name, bridge)
+            brfw = get_br_fw(bridge)
+            vifs = get_vifs_for_bridge(vm_name, bridge)
             for vif in vifs:
                 try:
                     execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain)
@@ -363,13 +314,14 @@
                     execute("iptables -A " + vmchain + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j RETURN")
                 except:
                     logging.debug("Failed to program default rules")
-                    return 'false'
+                    return False
 
     execute("iptables -A " + vmchain + " -j ACCEPT")
 
-    if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False:
+    if not write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1'):
         logging.debug("Failed to log default network rules for systemvm, ignoring")
-    return 'true'
+    return True
+
 
 def remove_secip_log_for_vm(vmName):
     vm_name = vmName
@@ -384,6 +336,7 @@
 
     return result
 
+
 def write_secip_log_for_vm (vmName, secIps, vmId):
     vm_name = vmName
     logfilename = logpath + vm_name + ".ip"
@@ -403,6 +356,7 @@
 
     return result
 
+
 def create_ipset_forvm(ipsetname, type='iphash', family='inet'):
     result = True
     try:
@@ -416,6 +370,7 @@
 
     return result
 
+
 def add_to_ipset(ipsetname, ips, action):
     result = True
     for ip in ips:
@@ -428,12 +383,11 @@
 
     return result
 
+
 def network_rules_vmSecondaryIp(vm_name, ip_secondary, action):
     logging.debug("vmName = "+ vm_name)
     logging.debug("action = "+ action)
 
-    domid = getvmId(vm_name)
-
     vmchain = vm_name
     vmchain6 = vmchain + '-6'
 
@@ -447,7 +401,8 @@
     #add ipv6 addresses to ipv6 ipset
     add_to_ipset(vmchain6, ip6s, action)
 
-    return 'true'
+    return True
+
 
 def ebtables_rules_vmip (vmname, ips, action):
     eb_vm_chain=ebtables_chain_name(vmname)
@@ -467,13 +422,14 @@
         except:
             logging.debug("Failed to program ebtables rules for secondary ip %s for vm %s with action %s" % (ip, vmname, action))
 
+
 def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, sec_ips):
-    if not addFWFramework(brname):
+    if not add_fw_framework(brname):
         return False
 
     vmName = vm_name
-    brfw = getBrfw(brname)
-    domID = getvmId(vm_name)
+    brfw = get_br_fw(brname)
+    domID = get_vm_id(vm_name)
     delete_rules_for_vm_in_bridge_firewall_chain(vmName)
     vmchain = iptables_chain_name(vm_name)
     vmchain_egress = egress_chain_name(vm_name)
@@ -498,19 +454,20 @@
     vmipsetName6 = vmipsetName + '-6'
 
     #create ipset and add vm ips to that ip set
-    if create_ipset_forvm(vmipsetName) == False:
-       logging.debug(" failed to create ipset for rule " + str(tokens))
-       return 'false'
+    if not create_ipset_forvm(vmipsetName):
+        logging.debug("failed to create ipset for rule %s", vmipsetName)
+        return False
 
     #add primary nic ip to ipset
-    if add_to_ipset(vmipsetName, [vm_ip], action ) == False:
-       logging.debug(" failed to add vm " + vm_ip + " ip to set ")
-       return 'false'
+    if not add_to_ipset(vmipsetName, [vm_ip], action ):
+        logging.debug("failed to add vm " + vm_ip + " ip to set ")
+        return False
 
     #add secodnary nic ips to ipset
     secIpSet = "1"
     ips = sec_ips.split(';')
     ips.pop()
+
     if len(ips) == 0 or ips[0] == "0":
         secIpSet = "0"
         ip4s = []
@@ -522,7 +479,7 @@
 
         add_to_ipset(vmipsetName, ip4s, action)
 
-        if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False:
+        if not write_secip_log_for_vm(vm_name, sec_ips, vm_id):
             logging.debug("Failed to log default network rules, ignoring")
 
     try:
@@ -534,28 +491,28 @@
         execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -p udp --dport 68 --sport 67  -j ACCEPT")
 
         #don't let vm spoof its ip address
-        if vm_ip is not None:
-            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set ! --set " + vmipsetName + " src -j DROP")
-            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p udp --dport 53  -j RETURN ")
-            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p tcp --dport 53  -j RETURN ")
-            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -j " + vmchain_egress)
+        if vm_ip:
+            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set ! --match-set " + vmipsetName + " src -j DROP")
+            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --match-set " + vmipsetName + " src -p udp --dport 53  -j RETURN ")
+            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --match-set " + vmipsetName + " src -p tcp --dport 53  -j RETURN ")
+            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --match-set " + vmipsetName + " src -j " + vmchain_egress)
         execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain)
         execute("iptables -A " + vmchain + " -j DROP")
     except:
         logging.debug("Failed to program default rules for vm " + vm_name)
-        return 'false'
+        return False
 
     default_ebtables_rules(vm_name, vm_ip, vm_mac, vif)
     #default ebtables rules for vm secondary ips
     ebtables_rules_vmip(vm_name, ip4s, "-I")
 
-    if vm_ip is not None:
-        if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False:
+    if vm_ip:
+        if not write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1'):
             logging.debug("Failed to log default network rules, ignoring")
 
     if not create_ipset_forvm(vmipsetName6, family='inet6', type='hash:net'):
-       logging.debug(" failed to create ivp6 ipset for rule " + str(tokens))
-       return 'false'
+        logging.debug(" failed to create ivp6 ipset for rule " + str(tokens))
+        return False
 
     vm_ip6_addr = [ipv6_link_local]
     try:
@@ -623,17 +580,18 @@
         execute('ip6tables -A ' + vmchain + ' -j DROP')
     except:
         logging.debug('Failed to program default rules for vm ' + vm_name)
-        return 'false'
+        return False
 
     logging.debug("Programmed default rules for vm " + vm_name)
-    return 'true'
+    return True
+
 
 def post_default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, dhcpSvr, hostIp, hostMacAddr):
     vmchain_default = '-'.join(vm_name.split('-')[:-1]) + "-def"
     iptables_vmchain=iptables_chain_name(vm_name)
     vmchain_in = iptables_vmchain + "-in"
     vmchain_out = iptables_vmchain + "-out"
-    domID = getvmId(vm_name)
+    domID = get_vm_id(vm_name)
     try:
         execute("iptables -I " + vmchain_default + " 4 -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT")
     except:
@@ -656,9 +614,10 @@
         execute("ebtables -t nat -I " + vmchain_out + " 2 -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP")
     except:
         pass
-    if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domID, '_initial_', '-1') == False:
+    if not write_rule_log_for_vm(vm_name, vm_id, vm_ip, domID, '_initial_', '-1'):
             logging.debug("Failed to log default network rules, ignoring")
 
+
 def delete_rules_for_vm_in_bridge_firewall_chain(vmName):
     vm_name = vmName
     if vm_name.startswith('i-'):
@@ -683,6 +642,7 @@
         except:
               logging.exception("Ignoring failure to delete rules for vm " + vmName)
 
+
 def rewrite_rule_log_for_vm(vm_name, new_domid):
     logfilename = logpath + vm_name + ".log"
     if not os.path.exists(logfilename):
@@ -696,8 +656,9 @@
 
     write_rule_log_for_vm(_vmName, _vmID, '0.0.0.0', new_domid, _signature, '-1')
 
+
 def get_rule_log_for_vm(vmName):
-    vm_name = vmName;
+    vm_name = vmName
     logfilename = logpath + vm_name + ".log"
     if not os.path.exists(logfilename):
         return ''
@@ -711,12 +672,13 @@
 
     return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno])
 
+
 def check_domid_changed(vmName):
-    curr_domid = getvmId(vmName)
+    curr_domid = get_vm_id(vmName)
     if (curr_domid is None) or (not curr_domid.isdigit()):
         curr_domid = '-1'
 
-    vm_name = vmName;
+    vm_name = vmName
     logfilename = logpath + vm_name + ".log"
     if not os.path.exists(logfilename):
         return ['-1', curr_domid]
@@ -730,6 +692,7 @@
 
     return [curr_domid, old_domid]
 
+
 def network_rules_for_rebooted_vm(vmName):
     vm_name = vmName
     [curr_domid, old_domid] = check_domid_changed(vm_name)
@@ -760,13 +723,13 @@
     vmchain = iptables_chain_name(vm_name)
     vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def"
 
-    vifs = getVifs(vmName)
+    vifs = get_vifs(vmName)
     logging.debug(vifs, brName)
     for v in vifs:
-        execute("iptables -A " + getBrfw(brName) + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j "+ vmchain_default)
-        execute("iptables -A " + getBrfw(brName) + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j "+ vmchain_default)
-        execute("ip6tables -A " + getBrfw(brName) + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j " + vmchain_default)
-        execute("ip6tables -A " + getBrfw(brName) + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j " + vmchain_default)
+        execute("iptables -A " + get_br_fw(brName) + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j " + vmchain_default)
+        execute("iptables -A " + get_br_fw(brName) + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j " + vmchain_default)
+        execute("ip6tables -A " + get_br_fw(brName) + "-IN " + " -m physdev --physdev-is-bridged --physdev-in " + v + " -j " + vmchain_default)
+        execute("ip6tables -A " + get_br_fw(brName) + "-OUT " + " -m physdev --physdev-is-bridged --physdev-out " + v + " -j " + vmchain_default)
 
     #change antispoof rule in vmchain
     try:
@@ -791,15 +754,16 @@
     rewrite_rule_log_for_vm(vm_name, curr_domid)
     return True
 
+
 def get_rule_logs_for_vms():
-    state=['running']
+    state = ['running']
     vms = virshlist(state)
 
     result = []
     try:
         for name in vms:
             name = name.rstrip()
-            if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-'] ]:
+            if 1 not in [name.startswith(c) for c in ['r-', 's-', 'v-', 'i-'] ]:
                 continue
             network_rules_for_rebooted_vm(name)
             if name.startswith('i-'):
@@ -808,13 +772,15 @@
     except:
         logging.exception("Failed to get rule logs, better luck next time!")
 
-    print ";".join(result)
+    print(";".join(result))
+
 
 def cleanup_rules_for_dead_vms():
     return True
 
+
 def cleanup_bridge(bridge):
-    bridge_name = getBrfw(bridge)
+    bridge_name = get_br_fw(bridge)
     logging.debug("Cleaning old bridge chains: " + bridge_name)
     if not bridge_name:
         return True
@@ -840,9 +806,10 @@
         except: pass
     return True
 
+
 def cleanup_rules():
     try:
-        states=['running','paused']
+        states = ['running', 'paused']
         vmsInHost = virshlist(states)
 
         logging.debug(" Vms on the host : %s ", vmsInHost)
@@ -856,11 +823,11 @@
         for chain in chains:
             if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]:
                 vm_name = chain
-                vmpresent=False
+                vmpresent = False
 
                 for vm in vmsInHost:
                     if vm_name  in vm:
-                        vmpresent=True
+                        vmpresent = True
                         break
 
                 if vmpresent is False:
@@ -875,12 +842,12 @@
         logging.debug(" ebtables chains in the host: %s ", chains)
 
         for chain in filter(None, chains):
-            if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]:
+            if 1 in [chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-']]:
                 vm_name = chain
-                vmpresent=False
+                vmpresent = False
                 for vm in vmsInHost:
                     if vm_name  in vm:
-                        vmpresent=True
+                        vmpresent = True
                         break
 
                 if vmpresent is False:
@@ -895,8 +862,9 @@
     except:
         logging.debug("Failed to cleanup rules !")
 
+
 def check_rule_log_for_vm(vmName, vmId, vmIP, domID, signature, seqno):
-    vm_name = vmName;
+    vm_name = vmName
     logfilename = logpath + vm_name + ".log"
     if not os.path.exists(logfilename):
         return [True, True, True, True, True, True]
@@ -919,6 +887,7 @@
 
     return [(vm_name != _vmName), (vmId != _vmID), (vmIP != _vmIP), (domID != _domID), (signature != _signature),(seqno != _seqno)]
 
+
 def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno):
     vm_name = vmName
     logfilename = logpath + vm_name + ".log"
@@ -937,6 +906,7 @@
 
     return result
 
+
 def remove_rule_log_for_vm(vmName):
     vm_name = vmName
     logfilename = logpath + vm_name + ".log"
@@ -950,6 +920,7 @@
 
     return result
 
+
 #ebtables chain max len 31 char
 def ebtables_chain_name(vm_name):
     # 23 because there are appends to the chains
@@ -957,6 +928,7 @@
         vm_name = vm_name[0:22]
     return vm_name
 
+
 #ipset chain max len 31 char
 def ipset_chain_name(vm_name):
     if len(vm_name) > 30:
@@ -970,150 +942,152 @@
         vm_name = vm_name[0:24]
     return vm_name
 
+
 def egress_chain_name(vm_name):
     chain_name = iptables_chain_name(vm_name)
     return chain_name + "-eg"
 
 
 def parse_network_rules(rules):
-  ret = []
+    ret = []
 
-  if rules is None or len(rules) == 0:
+    if rules is None or len(rules) == 0:
+        return ret
+
+    lines = rules.split('NEXT;')[:-1]
+    for line in lines:
+        tokens = line.split(';', 3)
+        if len(tokens) != 4:
+            continue
+
+        ruletype, protocol = tokens[0].split(':')
+        start = int(tokens[1])
+        end = int(tokens[2])
+        cidrs = tokens.pop()
+
+        ipv4 = []
+        ipv6 = []
+        for ip in cidrs.split(","):
+            try:
+                network = IPNetwork(ip)
+                if network.version == 4:
+                    ipv4.append(ip)
+                else:
+                    ipv6.append(ip)
+            except:
+                pass
+
+        ret.append({'ipv4': ipv4, 'ipv6': ipv6, 'ruletype': ruletype,
+                    'start': start, 'end': end, 'protocol': protocol})
+
     return ret
 
-  lines = rules.split('NEXT;')[:-1]
-  for line in lines:
-    tokens = line.split(';', 3)
-    if len(tokens) != 4:
-      continue
-
-    ruletype, protocol = tokens[0].split(':')
-    start = int(tokens[1])
-    end = int(tokens[2])
-    cidrs = tokens.pop();
-
-    ipv4 = []
-    ipv6 = []
-    for ip in cidrs.split(","):
-        try:
-            network = IPNetwork(ip)
-            if network.version == 4:
-                ipv4.append(ip)
-            else:
-                ipv6.append(ip)
-        except:
-            pass
-
-    ret.append({'ipv4': ipv4, 'ipv6': ipv6, 'ruletype': ruletype,
-                'start': start, 'end': end, 'protocol': protocol})
-
-  return ret
 
 def add_network_rules(vm_name, vm_id, vm_ip, vm_ip6, signature, seqno, vmMac, rules, vif, brname, sec_ips):
-  try:
-    vmName = vm_name
-    domId = getvmId(vmName)
-
-    changes = []
-    changes = check_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno)
-
-    if not 1 in changes:
-        logging.debug("Rules already programmed for vm " + vm_name)
-        return 'true'
-
-    if changes[0] or changes[1] or changes[2] or changes[3]:
-        default_network_rules(vmName, vm_id, vm_ip, vm_ip6, vmMac, vif, brname, sec_ips)
-
-    logging.debug("    programming network rules for IP: " + vm_ip + " vmname=" + vm_name)
-
-    egress_chain_name(vm_name)
-    vmchain = iptables_chain_name(vm_name)
-    egress_vmchain = egress_chain_name(vm_name)
-
     try:
-      for chain in [vmchain, egress_vmchain]:
-          execute('iptables -F ' + chain)
-          execute('ip6tables -F ' + chain)
-    except:
-      logging.debug("Error flushing iptables rules for " + vm_name + ". Presuming firewall rules deleted, re-initializing." )
-      default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vmMac, vif, brname, sec_ips)
+        vmName = vm_name
+        domId = get_vm_id(vmName)
 
-    egressrule_v4 = 0
-    egressrule_v6 = 0
+        changes = check_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno)
 
-    for rule in parse_network_rules(rules):
-        start = rule['start']
-        end = rule['end']
-        protocol = rule['protocol']
+        if not 1 in changes:
+            logging.debug("Rules already programmed for vm " + vm_name)
+            return True
 
-        if rule['ruletype'] == 'E':
-            vmchain = egress_vmchain
-            direction = "-d"
-            action = "RETURN"
-            if rule['ipv4']:
-                egressrule_v4 =+ 1
+        if changes[0] or changes[1] or changes[2] or changes[3]:
+            default_network_rules(vmName, vm_id, vm_ip, vm_ip6, vmMac, vif, brname, sec_ips)
 
-            if rule['ipv6']:
-                egressrule_v6 +=1
+        logging.debug("programming network rules for IP: " + vm_ip + " vmname=%s", vm_name)
 
-        else:
-            vmchain = vm_name
-            action = "ACCEPT"
-            direction = "-s"
+        egress_chain_name(vm_name)
+        vmchain = iptables_chain_name(vm_name)
+        egress_vmchain = egress_chain_name(vm_name)
 
-        range = str(start) + ':' + str(end)
-        if 'icmp' == protocol:
-            range = str(start) + '/' + str(end)
-            if start == -1:
-                range = 'any'
+        try:
+            for chain in [vmchain, egress_vmchain]:
+                execute('iptables -F ' + chain)
+                execute('ip6tables -F ' + chain)
+        except:
+            logging.debug("Error flushing iptables rules for " + vm_name + ". Presuming firewall rules deleted, re-initializing." )
+            default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vmMac, vif, brname, sec_ips)
 
-        for ip in rule['ipv4']:
-            if protocol == 'all':
-                execute('iptables -I ' + vmchain + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
-            elif protocol != 'icmp':
-                execute('iptables -I ' + vmchain + ' -p ' + protocol + ' -m ' + protocol + ' --dport ' + range + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
+        egressrule_v4 = 0
+        egressrule_v6 = 0
+
+        for rule in parse_network_rules(rules):
+            start = rule['start']
+            end = rule['end']
+            protocol = rule['protocol']
+
+            if rule['ruletype'] == 'E':
+                vmchain = egress_vmchain
+                direction = "-d"
+                action = "RETURN"
+                if rule['ipv4']:
+                    egressrule_v4 =+ 1
+
+                if rule['ipv6']:
+                    egressrule_v6 +=1
+
             else:
-                execute('iptables -I ' + vmchain + ' -p icmp --icmp-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action)
+                vmchain = vm_name
+                action = "ACCEPT"
+                direction = "-s"
 
-        for ip in rule['ipv6']:
-            if protocol == 'all':
-                execute('ip6tables -I ' + vmchain + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
-            elif 'icmp' != protocol:
-                execute('ip6tables -I ' + vmchain + ' -p ' + protocol + ' -m ' + protocol + ' --dport ' + range + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
-            else:
-                # ip6tables does not allow '--icmpv6-type any', allowing all ICMPv6 is done by not allowing a specific type
-                if range == 'any':
-                    execute('ip6tables -I ' + vmchain + ' -p icmpv6 ' + direction + ' ' + ip + ' -j ' + action)
+            range = str(start) + ':' + str(end)
+            if 'icmp' == protocol:
+                range = str(start) + '/' + str(end)
+                if start == -1:
+                    range = 'any'
+
+            for ip in rule['ipv4']:
+                if protocol == 'all':
+                    execute('iptables -I ' + vmchain + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
+                elif protocol != 'icmp':
+                    execute('iptables -I ' + vmchain + ' -p ' + protocol + ' -m ' + protocol + ' --dport ' + range + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
                 else:
-                    execute('ip6tables -I ' + vmchain + ' -p icmpv6 --icmpv6-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action)
+                    execute('iptables -I ' + vmchain + ' -p icmp --icmp-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action)
 
-    egress_vmchain = egress_chain_name(vm_name)
-    if egressrule_v4 == 0 :
-        execute('iptables -A ' + egress_vmchain + ' -j RETURN')
-    else:
-        execute('iptables -A ' + egress_vmchain + ' -j DROP')
+            for ip in rule['ipv6']:
+                if protocol == 'all':
+                    execute('ip6tables -I ' + vmchain + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
+                elif 'icmp' != protocol:
+                    execute('ip6tables -I ' + vmchain + ' -p ' + protocol + ' -m ' + protocol + ' --dport ' + range + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action)
+                else:
+                    # ip6tables does not allow '--icmpv6-type any', allowing all ICMPv6 is done by not allowing a specific type
+                    if range == 'any':
+                        execute('ip6tables -I ' + vmchain + ' -p icmpv6 ' + direction + ' ' + ip + ' -j ' + action)
+                    else:
+                        execute('ip6tables -I ' + vmchain + ' -p icmpv6 --icmpv6-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action)
 
-    if egressrule_v6 == 0 :
-        execute('ip6tables -A ' + egress_vmchain + ' -j RETURN')
-    else:
-        execute('ip6tables -A ' + egress_vmchain + ' -j DROP')
+        egress_vmchain = egress_chain_name(vm_name)
+        if egressrule_v4 == 0 :
+            execute('iptables -A ' + egress_vmchain + ' -j RETURN')
+        else:
+            execute('iptables -A ' + egress_vmchain + ' -j DROP')
 
-    vmchain = iptables_chain_name(vm_name)
+        if egressrule_v6 == 0 :
+            execute('ip6tables -A ' + egress_vmchain + ' -j RETURN')
+        else:
+            execute('ip6tables -A ' + egress_vmchain + ' -j DROP')
 
-    execute('iptables -A ' + vmchain + ' -j DROP')
-    execute('ip6tables -A ' + vmchain + ' -j DROP')
+        vmchain = iptables_chain_name(vm_name)
 
-    if write_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno) == False:
-        return 'false'
+        execute('iptables -A ' + vmchain + ' -j DROP')
+        execute('ip6tables -A ' + vmchain + ' -j DROP')
 
-    return 'true'
-  except:
-    logging.exception("Failed to network rule !")
+        if not write_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno):
+            return False
 
-def getVifs(vmName):
+        return True
+    except:
+        logging.exception("Failed to network rule !")
+
+
+def get_vifs(vm_name):
     vifs = []
-    xmlfile = virshdumpxml(vmName)
-    if xmlfile == None:
+    xmlfile = virshdumpxml(vm_name)
+    if not xmlfile:
         return vifs
 
     dom = xml.dom.minidom.parseString(xmlfile)
@@ -1123,10 +1097,11 @@
         vifs.append(nicdev)
     return vifs
 
-def getVifsForBridge(vmName, brname):
+
+def get_vifs_for_bridge(vm_name, brname):
     vifs = []
-    xmlfile = virshdumpxml(vmName)
-    if xmlfile == None:
+    xmlfile = virshdumpxml(vm_name)
+    if not xmlfile:
         return vifs
 
     dom = xml.dom.minidom.parseString(xmlfile)
@@ -1139,10 +1114,11 @@
             vifs.append(nicdev)
     return list(set(vifs))
 
-def getBridges(vmName):
+
+def get_bridges(vm_name):
     bridges = []
-    xmlfile = virshdumpxml(vmName)
-    if xmlfile == None:
+    xmlfile = virshdumpxml(vm_name)
+    if not xmlfile:
         return bridges
 
     dom = xml.dom.minidom.parseString(xmlfile)
@@ -1152,15 +1128,11 @@
             bridges.append(bridge)
     return list(set(bridges))
 
-def getvmId(vmName):
 
-    conn = libvirt.openReadOnly(driver)
-    if conn == None:
-       print 'Failed to open connection to the hypervisor'
-       sys.exit(3)
-
+def get_vm_id(vm_name):
+    conn = get_libvirt_connection()
     try:
-        dom = (conn.lookupByName (vmName))
+        dom = (conn.lookupByName (vm_name))
     except libvirt.libvirtError:
         return None
 
@@ -1171,14 +1143,16 @@
         res = str(res)
     return res
 
-def getBrfw(brname):
+
+def get_br_fw(brname):
     cmd = "iptables-save |grep physdev-is-bridged |grep FORWARD |grep BF |grep '\-o' | grep -w " + brname  + "|awk '{print $9}' | head -1"
-    brfwname = bash("-c", cmd).stdout.strip()
-    if brfwname == "":
+    brfwname = execute(cmd).strip()
+    if not brfwname:
         brfwname = "BF-" + brname
     return brfwname
 
-def addFWFramework(brname):
+
+def add_fw_framework(brname):
     try:
         execute("sysctl -w net.bridge.bridge-nf-call-arptables=1")
         execute("sysctl -w net.bridge.bridge-nf-call-iptables=1")
@@ -1186,7 +1160,7 @@
     except:
         logging.warn("failed to turn on bridge netfilter")
 
-    brfw = getBrfw(brname)
+    brfw = get_br_fw(brname)
     try:
         execute("iptables -L " + brfw)
     except:
@@ -1221,6 +1195,8 @@
     except:
         execute('ip6tables -N ' + brfwin)
 
+    physdev = get_bridge_physdev(brname)
+
     try:
         refs = int(execute("""iptables -n -L %s | awk '/%s(.*)references/ {gsub(/\(/, "") ;print $3}'""" % (brfw,brfw)).strip())
         refs6 = int(execute("""ip6tables -n -L %s | awk '/%s(.*)references/ {gsub(/\(/, "") ;print $3}'""" % (brfw,brfw)).strip())
@@ -1230,22 +1206,20 @@
             execute("iptables -I FORWARD -o " + brname + " -j DROP")
             execute("iptables -I FORWARD -i " + brname + " -m physdev --physdev-is-bridged -j " + brfw)
             execute("iptables -I FORWARD -o " + brname + " -m physdev --physdev-is-bridged -j " + brfw)
-            phydev = execute("brctl show | awk '/^%s[ \t]/ {print $4}'" % brname ).strip()
             execute("iptables -A " + brfw + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
             execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-in -j " + brfwin)
             execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-out -j " + brfwout)
-            execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT")
+            execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + physdev + " -j ACCEPT")
 
         if refs6 == 0:
             execute('ip6tables -I FORWARD -i ' + brname + ' -j DROP')
             execute('ip6tables -I FORWARD -o ' + brname + ' -j DROP')
             execute('ip6tables -I FORWARD -i ' + brname + ' -m physdev --physdev-is-bridged -j ' + brfw)
             execute('ip6tables -I FORWARD -o ' + brname + ' -m physdev --physdev-is-bridged -j ' + brfw)
-            phydev = execute("brctl show | awk '/^%s[ \t]/ {print $4}'" % brname ).strip()
             execute('ip6tables -A ' + brfw + ' -m state --state RELATED,ESTABLISHED -j ACCEPT')
             execute('ip6tables -A ' + brfw + ' -m physdev --physdev-is-bridged --physdev-is-in -j ' + brfwin)
             execute('ip6tables -A ' + brfw + ' -m physdev --physdev-is-bridged --physdev-is-out -j ' + brfwout)
-            execute('ip6tables -A ' + brfw + ' -m physdev --physdev-is-bridged --physdev-out ' + phydev + ' -j ACCEPT')
+            execute('ip6tables -A ' + brfw + ' -m physdev --physdev-is-bridged --physdev-out ' + physdev + ' -j ACCEPT')
 
         return True
     except:
@@ -1256,57 +1230,57 @@
             return False
         return False
 
+
 if __name__ == '__main__':
     logging.basicConfig(filename="/var/log/cloudstack/agent/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG)
-    parser = OptionParser()
-    parser.add_option("--vmname", dest="vmName")
-    parser.add_option("--vmip", dest="vmIP")
-    parser.add_option("--vmip6", dest="vmIP6")
-    parser.add_option("--vmid", dest="vmID")
-    parser.add_option("--vmmac", dest="vmMAC")
-    parser.add_option("--vif", dest="vif")
-    parser.add_option("--sig", dest="sig")
-    parser.add_option("--seq", dest="seq")
-    parser.add_option("--rules", dest="rules")
-    parser.add_option("--brname", dest="brname")
-    parser.add_option("--localbrname", dest="localbrname")
-    parser.add_option("--dhcpSvr", dest="dhcpSvr")
-    parser.add_option("--hostIp", dest="hostIp")
-    parser.add_option("--hostMacAddr", dest="hostMacAddr")
-    parser.add_option("--nicsecips", dest="nicSecIps")
-    parser.add_option("--action", dest="action")
-    (option, args) = parser.parse_args()
-    if len(args) == 0:
-        logging.debug("No command to execute")
-        sys.exit(1)
-    cmd = args[0]
-    logging.debug("Executing command: " + str(cmd))
+    parser = argparse.ArgumentParser(description='Apache CloudStack Security Groups')
+    parser.add_argument("command")
+    parser.add_argument("--vmname", dest="vmName")
+    parser.add_argument("--vmip", dest="vmIP")
+    parser.add_argument("--vmip6", dest="vmIP6")
+    parser.add_argument("--vmid", dest="vmID")
+    parser.add_argument("--vmmac", dest="vmMAC")
+    parser.add_argument("--vif", dest="vif")
+    parser.add_argument("--sig", dest="sig")
+    parser.add_argument("--seq", dest="seq")
+    parser.add_argument("--rules", dest="rules")
+    parser.add_argument("--brname", dest="brname")
+    parser.add_argument("--localbrname", dest="localbrname")
+    parser.add_argument("--dhcpSvr", dest="dhcpSvr")
+    parser.add_argument("--hostIp", dest="hostIp")
+    parser.add_argument("--hostMacAddr", dest="hostMacAddr")
+    parser.add_argument("--nicsecips", dest="nicSecIps")
+    parser.add_argument("--action", dest="action")
+    parser.add_argument("--privnic", dest="privnic")
+    args = parser.parse_args()
+    cmd = args.command
+    logging.debug("Executing command: %s", cmd)
 
     for i in range(0, 30):
         if obtain_file_lock(lock_file) is False:
-            logging.warn("Lock on %s is being held by other process. Waiting for release." % lock_file)
+            logging.warning("Lock on %s is being held by other process. Waiting for release." % lock_file)
             time.sleep(0.5)
         else:
             break
 
     if cmd == "can_bridge_firewall":
-        can_bridge_firewall(args[1])
+        can_bridge_firewall(args.privnic)
     elif cmd == "default_network_rules":
-        default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmIP6, option.vmMAC, option.vif, option.brname, option.nicSecIps)
+        default_network_rules(args.vmName, args.vmID, args.vmIP, args.vmIP6, args.vmMAC, args.vif, args.brname, args.nicSecIps)
     elif cmd == "destroy_network_rules_for_vm":
-        destroy_network_rules_for_vm(option.vmName, option.vif)
+        destroy_network_rules_for_vm(args.vmName, args.vif)
     elif cmd == "default_network_rules_systemvm":
-        default_network_rules_systemvm(option.vmName, option.localbrname)
+        default_network_rules_systemvm(args.vmName, args.localbrname)
     elif cmd == "get_rule_logs_for_vms":
         get_rule_logs_for_vms()
     elif cmd == "add_network_rules":
-        add_network_rules(option.vmName, option.vmID, option.vmIP, option.vmIP6, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname, option.nicSecIps)
+        add_network_rules(args.vmName, args.vmID, args.vmIP, args.vmIP6, args.sig, args.seq, args.vmMAC, args.rules, args.vif, args.brname, args.nicSecIps)
     elif cmd == "network_rules_vmSecondaryIp":
-        network_rules_vmSecondaryIp(option.vmName, option.nicSecIps, option.action)
+        network_rules_vmSecondaryIp(args.vmName, args.nicSecIps, args.action)
     elif cmd == "cleanup_rules":
         cleanup_rules()
     elif cmd == "post_default_network_rules":
-        post_default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname, option.dhcpSvr, option.hostIp, option.hostMacAddr)
+        post_default_network_rules(args.vmName, args.vmID, args.vmIP, args.vmMAC, args.vif, args.brname, args.dhcpSvr, args.hostIp, args.hostMacAddr)
     else:
         logging.debug("Unknown command: " + cmd)
         sys.exit(1)
diff --git a/scripts/vm/network/vnet/modifyvxlan.sh b/scripts/vm/network/vnet/modifyvxlan.sh
index f7d08f1..3aa19ad 100755
--- a/scripts/vm/network/vnet/modifyvxlan.sh
+++ b/scripts/vm/network/vnet/modifyvxlan.sh
@@ -6,9 +6,9 @@
 # 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
@@ -16,224 +16,130 @@
 # specific language governing permissions and limitations
 # under the License.
 
-# modifyvxlan.sh -- adds and deletes VXLANs from a Routing Server
-# set -x
-
-## TODO(VXLAN): MTU, IPv6 underlying
+# modifyvxlan.sh -- Managed VXLAN devices and Bridges on Linux KVM hypervisor
 
 usage() {
-  printf "Usage: %s: -o <op>(add | delete) -v <vxlan id> -p <pif> -b <bridge name>\n" 
+    echo "Usage: $0: -o <op>(add | delete) -v <vxlan id> -p <pif> -b <bridge name> (-6)"
+}
+
+multicastGroup() {
+    local VNI=$1
+    local FAMILY=$2
+    if [[ -z "$FAMILY" || $FAMILY == "inet" ]]; then
+        echo "239.$(( (${VNI} >> 16) % 256 )).$(( (${VNI} >> 8) % 256 )).$(( ${VNI} % 256 ))"
+    fi
+
+    if [[ "$FAMILY" == "inet6" ]]; then
+        echo "ff05::$(( (${VNI} >> 16) % 256 )):$(( (${VNI} >> 8) % 256 )):$(( ${VNI} % 256 ))"
+    fi
 }
 
 addVxlan() {
-	local vxlanId=$1
-	local pif=$2
-	local vxlanDev=vxlan$vxlanId
-	local vxlanBr=$3
-	local mcastGrp="239.$(( ($vxlanId >> 16) % 256 )).$(( ($vxlanId >> 8) % 256 )).$(( $vxlanId % 256 ))"
-	
-	## TODO(VXLAN): $brif (trafficlabel) should be passed from caller because we cannot assume 1:1 mapping between pif and brif.
-	# lookup bridge interface 
-	local sysfs_dir=/sys/devices/virtual/net/
-	local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'`
-	
-	if [ "$brif " == " " ]
-	then
-		if [ -d "/sys/class/net/${pif}" ]
-		then
-			# if bridge is not found, but matches a pif, use it
-			brif=$pif
-		else
-			printf "Failed to lookup bridge interface which includes pif: $pif."
-			return 1
-		fi
-	else
-		# confirm ip address of $brif
-		ip addr show $brif | grep -w inet
-		if [ $? -gt 0 ]
-		then
-			printf "Failed to find vxlan multicast source ip address on brif: $brif."
-			return 1
-		fi
-	fi
+    local VNI=$1
+    local PIF=$2
+    local VXLAN_BR=$3
+    local FAMILY=$4
+    local VXLAN_DEV=vxlan${VNI}
+    local GROUP=$(multicastGroup ${VNI} ${FAMILY})
 
-	# mcast route
-	## TODO(VXLAN): Can we assume there're only one IP address which can be multicast src IP on the IF?
-	ip route get $mcastGrp | grep -w "dev $brif"
-	if [ $? -gt 0 ]
-	then
-		ip route add $mcastGrp/32 dev $brif
-		if [ $? -gt 0 ]
-		then
-			printf "Failed to add vxlan multicast route on brif: $brif."
-			return 1
-		fi
-	fi
-	
-	if [ ! -d /sys/class/net/$vxlanDev ]
-	then
-		ip link add $vxlanDev type vxlan id $vxlanId group $mcastGrp ttl 10 dev $brif
-		
-		if [ $? -gt 0 ]
-		then
-			# race condition that someone already creates the vxlan 
-			if [ ! -d /sys/class/net/$vxlanDev ]
-			then
-				printf "Failed to create vxlan $vxlanId on brif: $brif."
-				return 1
-			fi
-		fi
-	fi
-	
-	# is up?
-	ip link show $vxlanDev | grep -w UP > /dev/null
-	if [ $? -gt 0 ]
-	then
-		ip link set $vxlanDev up > /dev/null
-	fi
-	
-	if [ ! -d /sys/class/net/$vxlanBr ]
-	then
-		brctl addbr $vxlanBr > /dev/null
-	
-		if [ $? -gt 0 ]
-		then
-			if [ ! -d /sys/class/net/$vxlanBr ]
-			then
-				printf "Failed to create br: $vxlanBr"
-				return 2
-			fi
-		fi
+    echo "multicast ${GROUP} for VNI ${VNI} on ${PIF}"
 
-		brctl setfd $vxlanBr 0
-	fi
-	
-	#pif is eslaved into vxlanBr?
-	ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null 
-	if [ $? -gt 0 ]
-	then
-		brctl addif $vxlanBr $vxlanDev > /dev/null
-		if [ $? -gt 0 ]
-		then
-			ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null 
-			if [ $? -gt 0 ]
-			then
-				printf "Failed to add vxlan: $vxlanDev to $vxlanBr"
-				return 3
-			fi
-		fi
-	fi
-	
-	# is vxlanBr up?
-	ip link show $vxlanBr  | grep -w UP > /dev/null
-	if [ $? -gt 0 ]
-	then
-		ip link set $vxlanBr up
-	fi
-	
-	return 0
+    if [[ ! -d /sys/class/net/${VXLAN_DEV} ]]; then
+        ip -f ${FAMILY} link add ${VXLAN_DEV} type vxlan id ${VNI} group ${GROUP} ttl 10 dev ${PIF}
+        ip link set ${VXLAN_DEV} up
+        ip -f ${FAMILY} route add ${GROUP} dev ${PIF}
+        sysctl -qw net.ipv6.conf.${VXLAN_DEV}.disable_ipv6=1
+    fi
+
+    if [[ ! -d /sys/class/net/$VXLAN_BR ]]; then
+        ip link add name ${VXLAN_BR} type bridge
+        ip link set ${VXLAN_BR} up
+        sysctl -qw net.ipv6.conf.${VXLAN_BR}.disable_ipv6=1
+    fi
+
+    bridge link show|grep ${VXLAN_BR}|awk '{print $2}'|grep "^${VXLAN_DEV}\$" > /dev/null
+    if [[ $? -gt 0 ]]; then
+        ip link set ${VXLAN_DEV} master ${VXLAN_BR}
+    fi
 }
 
 deleteVxlan() {
-	local vxlanId=$1
-	local pif=$2
-	local vxlanDev=vxlan$vxlanId
-	local vxlanBr=$3
-	local mcastGrp="239.$(( ($vxlanId >> 16) % 256 )).$(( ($vxlanId >> 8) % 256 )).$(( $vxlanId % 256 ))"
-	
-	local sysfs_dir=/sys/devices/virtual/net/
-	local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'`
-	
-	ip route del $mcastGrp/32 dev $brif
-	
-	ip link delete $vxlanDev 
-	
-	if [ $? -gt 0 ]
-	then
-		printf "Failed to del vxlan: $vxlanId"
-		printf "Continue..."
-	fi	
-	
-	ip link set $vxlanBr down
-	
-	if [ $? -gt 0 ]
-	then
-		return 1
-	fi
-	
-	brctl delbr $vxlanBr
-	
-	if [ $? -gt 0 ]
-	then
-		printf "Failed to del bridge $vxlanBr"
-		return 1
-	fi
-	
-	return 0
+    local VNI=$1
+    local PIF=$2
+    local VXLAN_BR=$3
+    local FAMILY=$4
+    local VXLAN_DEV=vxlan${VNI}
+    local GROUP=$(multicastGroup ${VNI} ${FAMILY})
+
+    ip -f ${FAMILY} route del ${GROUP} dev ${PIF}
+
+    ip link set ${VXLAN_DEV} nomaster
+    ip link delete ${VXLAN_DEV}
+
+    ip link set ${VXLAN_BR} down
+    ip link delete ${VXLAN_BR} type bridge
 }
 
-op=
-vxlanId=
+OP=
+VNI=
+FAMILY=inet
 option=$@
 
-while getopts 'o:v:p:b:' OPTION
+while getopts 'o:v:p:b:6' OPTION
 do
   case $OPTION in
-  o)	oflag=1
-		op="$OPTARG"
-		;;
-  v)	vflag=1
-		vxlanId="$OPTARG"
-		;;
-  p)	pflag=1
-		pif="$OPTARG"
-		;;
-  b)	bflag=1
-		brName="$OPTARG"
-		;;
-  ?)	usage
-		exit 2
-		;;
+  o)    oflag=1
+        OP="$OPTARG"
+        ;;
+  v)    vflag=1
+        VNI="$OPTARG"
+        ;;
+  p)    pflag=1
+        PIF="$OPTARG"
+        ;;
+  b)    bflag=1
+        BRNAME="$OPTARG"
+        ;;
+  6)
+        FAMILY=inet6
+        ;;
+  ?)    usage
+        exit 2
+        ;;
   esac
 done
 
-# Check that all arguments were passed in
-if [ "$oflag$vflag$pflag$bflag" != "1111" ]
-then
-	usage
-	exit 2
+if [[ "$oflag$vflag$pflag$bflag" != "1111" ]]; then
+    usage
+    exit 2
 fi
 
-# Do we support Vxlan?
 lsmod|grep ^vxlan >& /dev/null
-if [ $? -gt 0 ]
-then
-   modprobe=`modprobe vxlan 2>&1`
-   if [ $? -gt 0 ]
-   then
-     printf "Failed to load vxlan kernel module: $modprobe"
-     exit 1
-   fi
+if [[ $? -gt 0 ]]; then
+    modprobe=`modprobe vxlan 2>&1`
+    if [[ $? -gt 0 ]]; then
+        echo "Failed to load vxlan kernel module: $modprobe"
+        exit 1
+    fi
 fi
 
-if [ "$op" == "add" ]
-then
-	# Add the vxlan
-	addVxlan $vxlanId $pif $brName
-	
-	# If the add fails then return failure
-	if [ $? -gt 0 ]
-	then
-		exit 1
-	fi
-else 
-	if [ "$op" == "delete" ]
-	then
-		# Delete the vxlan
-		deleteVxlan $vxlanId $pif $brName
-		
-		# Always exit with success
-		exit 0
-	fi
-fi
 
+#
+# Add a lockfile to prevent this script from running twice on the same host
+# this can cause a race condition
+#
+
+LOCKFILE=/var/run/cloud/vxlan.lock
+
+(
+    flock -x -w 10 200 || exit 1
+    if [[ "$OP" == "add" ]]; then
+        addVxlan ${VNI} ${PIF} ${BRNAME} ${FAMILY}
+
+        if [[ $? -gt 0 ]]; then
+            exit 1
+        fi
+    elif [[ "$OP" == "delete" ]]; then
+        deleteVxlan ${VNI} ${PIF} ${BRNAME} ${FAMILY}
+    fi
+) 200>${LOCKFILE}
diff --git a/server/pom.xml b/server/pom.xml
index 3824ee5..b12194c 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -1,242 +1,244 @@
-<!-- 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. -->
+<!--
+  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-server</artifactId>
-  <name>Apache CloudStack Server</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-cluster</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-security</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>javax.servlet-api</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore</artifactId>
-      <version>${cs.httpcore.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-jobs</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.thoughtworks.xstream</groupId>
-      <artifactId>xstream</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.mail</groupId>
-      <artifactId>mail</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-      <exclusions>
-      	<exclusion>
-      		<artifactId>xml-apis</artifactId>
-      		<groupId>xml-apis</groupId>
-      	</exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.reflections</groupId>
-      <artifactId>reflections</artifactId>
-      <exclusions>
-      	<exclusion>
-      		<artifactId>xml-apis</artifactId>
-      		<groupId>xml-apis</groupId>
-      	</exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ipc</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-events</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-config</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-agent-lb</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-configdrive</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opensaml</groupId>
-      <artifactId>opensaml</artifactId>
-      <version>${cs.opensaml.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <testResources>
-      <testResource>
-        <directory>test/resources</directory>
-        <excludes>
-          <exclude>%regex[.*[0-9]*To[0-9]*.*Test.*]</exclude>
-        </excludes>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-testCompile</id>
-            <phase>test-compile</phase>
-            <configuration>
-              <testExcludes>
-                <exclude>**/com/cloud/upgrade/*.java</exclude>
-                <exclude>**/com/cloud/async/*.java</exclude>
-              </testExcludes>
-            </configuration>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <argLine>-Xmx2048m -XX:MaxPermSize=512m -Djava.security.egd=file:/dev/./urandom</argLine>
-          <excludes>
-            <exclude>%regex[.*[0-9]*To[0-9]*.*Test.*]</exclude>
-            <exclude>com/cloud/upgrade/AdvanceZone223To224UpgradeTest</exclude>
-            <exclude>com/cloud/upgrade/AdvanceZone217To224UpgradeTest</exclude>
-            <exclude>com/cloud/async/*</exclude>
-            <exclude>com/cloud/cluster/*</exclude>
-            <exclude>com/cloud/snapshot/*</exclude>
-            <exclude>com/cloud/storage/dao/*</exclude>
-            <exclude>com/cloud/vm/dao/*</exclude>
-            <exclude>com/cloud/api/ListPerfTest.java</exclude>
-            <exclude>com/cloud/network/vpn/RemoteAccessVpnTest.java</exclude>
-            <exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
-            <exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
-            <exclude>com/cloud/vpc/VpcTestConfiguration.java</exclude>
-            <exclude>com/cloud/vpc/VpcApiUnitTest.java</exclude>
-            <exclude>com/cloud/vpc/VpcManagerTest.java</exclude>
-          </excludes>
-        </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/conf">
-                  <fileset dir="${basedir}/conf">
-                    <include name="*.in" />
-                  </fileset>
-                  <globmapper from="*.in" to="*" />
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${project.basedir}/../${cs.replace.properties}" />
-                    </filterreader>
-                  </filterchain>
-                </copy>
-                <copy todir="${basedir}/target/conf">
-                  <fileset dir="${basedir}/conf">
-                    <exclude name="*.in" />
-                  </fileset>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+    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-server</artifactId>
+    <name>Apache CloudStack Server</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-cluster</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-security</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-jobs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>xml-apis</artifactId>
+                    <groupId>xml-apis</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>xml-apis</artifactId>
+                    <groupId>xml-apis</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ipc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-events</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-agent-lb</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-configdrive</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opensaml</groupId>
+            <artifactId>opensaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.influxdb</groupId>
+            <artifactId>influxdb-java</artifactId>
+            <version>2.8</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>default-testCompile</id>
+                        <phase>test-compile</phase>
+                        <configuration>
+                            <testExcludes>
+                                <exclude>**/com/cloud/upgrade/*.java</exclude>
+                                <exclude>**/com/cloud/async/*.java</exclude>
+                            </testExcludes>
+                        </configuration>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <argLine>-Xmx2048m -XX:MaxPermSize=512m -Djava.security.egd=file:/dev/./urandom</argLine>
+                    <excludes>
+                        <exclude>%regex[.*[0-9]*To[0-9]*.*Test.*]</exclude>
+                        <exclude>com/cloud/upgrade/AdvanceZone223To224UpgradeTest</exclude>
+                        <exclude>com/cloud/upgrade/AdvanceZone217To224UpgradeTest</exclude>
+                        <exclude>com/cloud/async/*</exclude>
+                        <exclude>com/cloud/cluster/*</exclude>
+                        <exclude>com/cloud/snapshot/*</exclude>
+                        <exclude>com/cloud/storage/dao/*</exclude>
+                        <exclude>com/cloud/vm/dao/*</exclude>
+                        <exclude>com/cloud/api/ListPerfTest.java</exclude>
+                        <exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
+                        <exclude>com/cloud/network/security/SecurityGroupManagerImpl2Test.java</exclude>
+                        <exclude>com/cloud/vpc/VpcTestConfiguration.java</exclude>
+                        <exclude>com/cloud/vpc/VpcApiUnitTest.java</exclude>
+                        <exclude>com/cloud/vpc/VpcManagerTest.java</exclude>
+                    </excludes>
+                </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/conf">
+                                    <fileset dir="${basedir}/conf">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${project.basedir}/../${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                                <copy todir="${basedir}/target/conf">
+                                    <fileset dir="${basedir}/conf">
+                                        <exclude name="*.in" />
+                                    </fileset>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
deleted file mode 100644
index c7715a8..0000000
--- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
+++ /dev/null
@@ -1,301 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xmlns:util="http://www.springframework.org/schema/util"
-       
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/aop 
-                      http://www.springframework.org/schema/aop/spring-aop.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context.xsd
-                      http://www.springframework.org/schema/util
-                      http://www.springframework.org/schema/util/spring-util.xsd"
-                      >
-
-    <bean id="authenticationManagerImpl" class="com.cloud.api.auth.APIAuthenticationManagerImpl">
-        <property name="apiAuthenticators"
-                  value="#{pluggableAPIAuthenticatorsRegistry.registered}" />
-    </bean>
-
-    <bean id="roleManagerImpl" class="org.apache.cloudstack.acl.RoleManagerImpl" />
-
-    <bean id="accountManagerImpl" class="com.cloud.user.AccountManagerImpl">
-        <property name="userAuthenticators"
-            value="#{userAuthenticatorsRegistry.registered}" />
-        <property name="userPasswordEncoders"
-            value="#{userPasswordEncodersRegistry.registered}" />
-        <property name="securityCheckers" value="#{securityCheckersRegistry.registered}" />
-        <property name="querySelectors" value="#{querySelectorsRegistry.registered}" />        
-    </bean>
-
-    <bean id="managementServerImpl" class="com.cloud.server.ManagementServerImpl">
-        <property name="lockMasterListener" ref="lockMasterListener" />
-        <property name="userAuthenticators"
-            value="#{userAuthenticatorsRegistry.registered}" />
-        <property name="userPasswordEncoders"
-            value="#{userPasswordEncodersRegistry.registered}" />
-        <property name="hostAllocators" value="#{hostAllocatorsRegistry.registered}" />
-        <property name="affinityGroupProcessors"
-            value="#{affinityProcessorsRegistry.registered}" />
-        <property name="planners"
-            value="#{deploymentPlannersRegistry.registered}" />
-        <property name="storagePoolAllocators"
-            value="#{storagePoolAllocatorsRegistry.registered}" />
-    </bean>
-
-    <bean id="storageManagerImpl" class="com.cloud.storage.StorageManagerImpl" />
-
-    <bean id="resourceManagerImpl" class="com.cloud.resource.ResourceManagerImpl">
-        <property name="discoverers"
-            value="#{resourceDiscoverersRegistry.registered}" />
-    </bean>
-
-    <!-- the new background poll manager -->
-    <bean id="bgPollManager" class="org.apache.cloudstack.poll.BackgroundPollManagerImpl">
-    </bean>
-
-    <!-- the new HA manager -->
-    <bean id="haManagerImpl" class="org.apache.cloudstack.ha.HAManagerImpl">
-        <property name="haProviders" value="#{haProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl">
-        <property name="investigators" value="#{haInvestigatorsRegistry.registered}" />
-        <property name="fenceBuilders" value="#{haFenceBuildersRegistry.registered}" />
-        <property name="haPlanners" value="#{haPlannersRegistry.registered}" />
-    </bean>
-
-    <bean id="ipAddressManagerImpl" class="com.cloud.network.IpAddressManagerImpl">
-    </bean>
-
-    <bean id="networkModelImpl" class="com.cloud.network.NetworkModelImpl">
-        <property name="networkElements" value="#{networkElementsRegistry.registered}" />
-    </bean>
-
-
-    <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
-
-
-    <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
-
-    <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.ConsoleProxyManagerImpl">
-        <property name="consoleProxyAllocators"
-            value="#{consoleProxyAllocatorsRegistry.registered}" />
-    </bean>
-
-    <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
-
-    <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
-
-    <bean id="NetworkMigrationManagerImpl" class="com.cloud.network.NetworkMigrationManagerImpl" />
-
-
-    <bean id="alertManagerImpl" class="com.cloud.alert.AlertManagerImpl" />
-
-    <bean id="autoScaleManagerImpl" class="com.cloud.network.as.AutoScaleManagerImpl" />
-
-    <bean id="capacityManagerImpl" class="com.cloud.capacity.CapacityManagerImpl" />
-
-    <bean id="configurationManagerImpl" class="com.cloud.configuration.ConfigurationManagerImpl" >  
-        <property name="secChecker" value="#{securityCheckersRegistry.registered}" />
-    </bean>
-
-    <bean id="externalDeviceUsageManagerImpl" class="com.cloud.network.ExternalDeviceUsageManagerImpl" />
-
-    <bean id="externalNetworkDeviceManagerImpl" class="com.cloud.network.ExternalNetworkDeviceManagerImpl" />
-
-    <bean id="firewallManagerImpl" class="com.cloud.network.firewall.FirewallManagerImpl" >
-        <property name="firewallElements" value="#{firewallServiceProvidersRegistry.registered}" />
-        <property name="networkAclElements" value="#{networkACLServiceProvidersRegistry.registered}" />
-        <property name="pfElements" value="#{portForwardingServiceProvidersRegistry.registered}" />
-        <property name="staticNatElements" value="#{staticNatServiceProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="hypervisorGuruManagerImpl" class="com.cloud.hypervisor.HypervisorGuruManagerImpl" >
-        <property name="hvGuruList" value="#{hypervisorGurusRegistry.registered}" />
-    </bean>
-
-    <bean id="uUIDManagerImpl" class="com.cloud.uuididentity.UUIDManagerImpl" />
-
-    <bean id="loadBalancingRulesManagerImpl" class="com.cloud.network.lb.LoadBalancingRulesManagerImpl" >
-        <property name="lbProviders" value="#{loadBalancingServiceProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="networkACLManagerImpl" class="com.cloud.network.vpc.NetworkACLManagerImpl" >
-        <property name="networkAclElements" value="#{networkACLServiceProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="networkACLServiceImpl" class="com.cloud.network.vpc.NetworkACLServiceImpl" />
-
-    <bean id="networkServiceImpl" class="com.cloud.network.NetworkServiceImpl" >
-        <property name="networkGurus" value="#{networkGurusRegistry.registered}" />
-    </bean>
-
-    <bean id="networkUsageManagerImpl" class="com.cloud.network.NetworkUsageManagerImpl" />
-
-    <bean id="oCFS2ManagerImpl" class="com.cloud.storage.OCFS2ManagerImpl" />
-
-    <bean id="outOfBandManagementServiceImpl" class="org.apache.cloudstack.outofbandmanagement.OutOfBandManagementServiceImpl">
-        <property name="outOfBandManagementDrivers" value="#{outOfBandManagementDriversRegistry.registered}" />
-    </bean>
-
-    <bean id="projectManagerImpl" class="com.cloud.projects.ProjectManagerImpl" />
-
-    <bean id="queryManagerImpl" class="com.cloud.api.query.QueryManagerImpl" />
-
-    <bean id="regionManagerImpl" class="org.apache.cloudstack.region.RegionManagerImpl" />
-
-    <bean id="regionServiceImpl" class="org.apache.cloudstack.region.RegionServiceImpl" />
-
-    <bean id="remoteAccessVpnManagerImpl" class="com.cloud.network.vpn.RemoteAccessVpnManagerImpl" >
-        <property name="vpnServiceProviders" value="#{remoteAccessVPNServiceProviderRegistry.registered}" />
-    </bean>
-
-    <bean id="resourceLimitManagerImpl" class="com.cloud.resourcelimit.ResourceLimitManagerImpl" />
-
-    <bean id="rulesManagerImpl" class="com.cloud.network.rules.RulesManagerImpl" />
-
-    <bean id="site2SiteVpnManagerImpl" class="com.cloud.network.vpn.Site2SiteVpnManagerImpl" >
-        <property name="s2sProviders" value="#{site2SiteVpnServiceProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="snapshotManagerImpl" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
-
-    <bean id="snapshotSchedulerImpl" class="com.cloud.storage.snapshot.SnapshotSchedulerImpl" >
-        <property name="asyncJobDispatcher" ref="ApiAsyncJobDispatcher" />
-    </bean>
-    <bean id="storageNetworkManagerImpl" class="com.cloud.network.StorageNetworkManagerImpl" />
-    <bean id="taggedResourceManagerImpl" class="com.cloud.tags.TaggedResourceManagerImpl" />
-    <bean id="resourceMetaDataManagerImpl" class="com.cloud.metadata.ResourceMetaDataManagerImpl" />
-
-    <bean id="templateManagerImpl" class="com.cloud.template.TemplateManagerImpl">
-        <property name="templateAdapters" value="#{templateAdapterRegistry.registered}" />
-    </bean>
-
-    <bean id="uploadMonitorImpl" class="com.cloud.storage.upload.UploadMonitorImpl" />
-    <bean id="usageServiceImpl" class="com.cloud.usage.UsageServiceImpl" />
-    
-    <bean id="virtualNetworkApplianceManagerImpl"
-        class="com.cloud.network.router.VirtualNetworkApplianceManagerImpl" />
-        
-    <bean id="vpcManagerImpl" class="com.cloud.network.vpc.VpcManagerImpl" >
-        <property name="vpcElements" value="#{vpcProvidersRegistry.registered}"></property>
-    </bean>
-    
-    <bean id="vpcTxCallable" class="com.cloud.network.vpc.VpcPrivateGatewayTransactionCallable" />
-    
-    <bean id="vpcVirtualNetworkApplianceManagerImpl"
-        class="com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl" />
-    
-    <bean id="virtualNetworkApplianceFactory"
-        class="com.cloud.network.rules.VirtualNetworkApplianceFactory" />
-    
-    <bean id="topologyContext" class="org.apache.cloudstack.network.topology.NetworkTopologyContext" init-method="init" />
-    
-    <bean id="basicNetworkTopology" class="org.apache.cloudstack.network.topology.BasicNetworkTopology" />
-    <bean id="advancedNetworkTopology" class="org.apache.cloudstack.network.topology.AdvancedNetworkTopology" />
-    
-    <bean id="basicNetworkVisitor" class="org.apache.cloudstack.network.topology.BasicNetworkVisitor" />
-    <bean id="advancedNetworkVisitor" class="org.apache.cloudstack.network.topology.AdvancedNetworkVisitor" />
-    
-    <bean id="commandSetupHelper"
-        class="com.cloud.network.router.CommandSetupHelper" />
-    
-    <bean id="routerControlHelper"
-        class="com.cloud.network.router.RouterControlHelper" />
-        
-    <bean id="networkHelper"
-        class="com.cloud.network.router.NetworkHelperImpl" />
-        
-    <bean id="vpcNetworkHelper"
-        class="com.cloud.network.router.VpcNetworkHelperImpl" />
-        
-    <bean id="nicProfileHelper"
-        class="com.cloud.network.router.NicProfileHelperImpl" />
-        
-    <bean id="routerDeploymentDefinitionBuilder"
-        class="org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder" />
-
-    <bean id="ApiAsyncJobDispatcher" class="com.cloud.api.ApiAsyncJobDispatcher">
-        <property name="name" value="ApiAsyncJobDispatcher" />
-    </bean>
-
-
-    <bean id="statsCollector" class="com.cloud.server.StatsCollector" />
-
-    <bean id="storagePoolAutomationImpl" class="com.cloud.storage.StoragePoolAutomationImpl" />
-
-    <bean id="domainManagerImpl" class="com.cloud.user.DomainManagerImpl" />
-
-    <bean id="downloadMonitorImpl" class="com.cloud.storage.download.DownloadMonitorImpl" />
-  
-    <bean id="lBHealthCheckManagerImpl" class="com.cloud.network.lb.LBHealthCheckManagerImpl" />
-
-    <bean id="volumeApiServiceImpl" class="com.cloud.storage.VolumeApiServiceImpl">
-        <property name="storagePoolAllocators"
-            value="#{storagePoolAllocatorsRegistry.registered}" />
-    </bean>
-    
-    <bean id="ApplicationLoadBalancerService" class="org.apache.cloudstack.network.lb.ApplicationLoadBalancerManagerImpl" />
-
-    <bean id="vMSnapshotManagerImpl" class="com.cloud.vm.snapshot.VMSnapshotManagerImpl" />
-
-    <bean id="AffinityGroupServiceImpl"
-        class="org.apache.cloudstack.affinity.AffinityGroupServiceImpl">
-        <property name="affinityGroupProcessors"
-            value="#{affinityProcessorsRegistry.registered}" />
-    </bean>
-
-    <bean id="DeploymentPlanningManager" class="com.cloud.deploy.DeploymentPlanningManagerImpl">
-        <property name="planners"
-            value="#{deploymentPlannersRegistry.registered}" />
-        <property name="affinityGroupProcessors"
-            value="#{affinityProcessorsRegistry.registered}" />
-        <property name="storagePoolAllocators"
-            value="#{storagePoolAllocatorsRegistry.registered}" />
-        <property name="hostAllocators" value="#{hostAllocatorsRegistry.registered}" />
-    </bean>
-
-    <bean id="AffinityGroupJoinDaoImpl" class="com.cloud.api.query.dao.AffinityGroupJoinDaoImpl" />
-
-    <bean id="PlannerHostReservationDaoImpl" class="com.cloud.deploy.dao.PlannerHostReservationDaoImpl" />
-
-    <bean id="GlobalLoadBalancingRulesServiceImpl"
-        class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" >
-        <property name="gslbServiceProviders" value="#{gslbServiceProvidersRegistry.registered}" />
-    </bean>
-    <bean id="certServiceImpl" class="org.apache.cloudstack.network.ssl.CertServiceImpl" />
-
-    <bean id="imageStoreUploadMonitorImpl" class="com.cloud.storage.ImageStoreUploadMonitorImpl" />
-
-    <!-- the new CA manager -->
-    <bean id="caManager" class="org.apache.cloudstack.ca.CAManagerImpl">
-        <property name="caProviders" value="#{caProvidersRegistry.registered}" />
-    </bean>
-
-    <bean id="annotationService" class="org.apache.cloudstack.annotation.AnnotationManagerImpl" />
-
-    <bean id="indirectAgentLBService" class="org.apache.cloudstack.agent.lb.IndirectAgentLBServiceImpl" />
-
-    <bean id="directDownloadManager" class="org.apache.cloudstack.direct.download.DirectDownloadManagerImpl" />
-</beans>
diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java
deleted file mode 100644
index a58a4f8..0000000
--- a/server/src/com/cloud/alert/AlertManagerImpl.java
+++ /dev/null
@@ -1,868 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.alert;
-
-import java.io.UnsupportedEncodingException;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Timer;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.inject.Inject;
-import javax.mail.Authenticator;
-import javax.mail.Message.RecipientType;
-import javax.mail.MessagingException;
-import javax.mail.PasswordAuthentication;
-import javax.mail.SendFailedException;
-import javax.mail.Session;
-import javax.mail.URLName;
-import javax.mail.internet.InternetAddress;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.sun.mail.smtp.SMTPMessage;
-import com.sun.mail.smtp.SMTPSSLTransport;
-import com.sun.mail.smtp.SMTPTransport;
-
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.alert.dao.AlertDao;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.CapacityState;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterIpAddressDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.AlertGenerator;
-import com.cloud.event.EventTypes;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.org.Grouping.AllocationState;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.StorageManager;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.SearchCriteria;
-
-public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
-    private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName());
-    private static final Logger s_alertsLogger = Logger.getLogger("org.apache.cloudstack.alerts");
-
-    private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
-
-    private static final DecimalFormat DfPct = new DecimalFormat("###.##");
-    private static final DecimalFormat DfWhole = new DecimalFormat("########");
-
-    private EmailAlert _emailAlert;
-    @Inject
-    private AlertDao _alertDao;
-    @Inject
-    protected StorageManager _storageMgr;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    private CapacityDao _capacityDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private HostPodDao _podDao;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private IPAddressDao _publicIPAddressDao;
-    @Inject
-    private DataCenterIpAddressDao _privateIPAddressDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private ConfigurationManager _configMgr;
-    @Inject
-    protected ConfigDepot _configDepot;
-
-    private Timer _timer = null;
-    private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default.
-    private double _publicIPCapacityThreshold = 0.75;
-    private double _privateIPCapacityThreshold = 0.75;
-    private double _secondaryStorageCapacityThreshold = 0.75;
-    private double _vlanCapacityThreshold = 0.75;
-    private double _directNetworkPublicIpCapacityThreshold = 0.75;
-    private double _localStorageCapacityThreshold = 0.75;
-    Map<Short, Double> _capacityTypeThresholdMap = new HashMap<Short, Double>();
-
-    private final ExecutorService _executor;
-
-    public AlertManagerImpl() {
-        _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender"));
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
-        // set up the email system for alerts
-        String emailAddressList = configs.get("alert.email.addresses");
-        String[] emailAddresses = null;
-        if (emailAddressList != null) {
-            emailAddresses = emailAddressList.split(",");
-        }
-
-        String smtpHost = configs.get("alert.smtp.host");
-        int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25);
-        String useAuthStr = configs.get("alert.smtp.useAuth");
-        boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
-        String smtpUsername = configs.get("alert.smtp.username");
-        String smtpPassword = configs.get("alert.smtp.password");
-        String emailSender = configs.get("alert.email.sender");
-        String smtpDebugStr = configs.get("alert.smtp.debug");
-        int smtpTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.timeout"), 30000);
-        int smtpConnectionTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.connectiontimeout"), 30000);
-        boolean smtpDebug = false;
-        if (smtpDebugStr != null) {
-            smtpDebug = Boolean.parseBoolean(smtpDebugStr);
-        }
-
-        _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, smtpConnectionTimeout, smtpTimeout, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
-
-        String publicIPCapacityThreshold = _configDao.getValue(Config.PublicIpCapacityThreshold.key());
-        String privateIPCapacityThreshold = _configDao.getValue(Config.PrivateIpCapacityThreshold.key());
-        String secondaryStorageCapacityThreshold = _configDao.getValue(Config.SecondaryStorageCapacityThreshold.key());
-        String vlanCapacityThreshold = _configDao.getValue(Config.VlanCapacityThreshold.key());
-        String directNetworkPublicIpCapacityThreshold = _configDao.getValue(Config.DirectNetworkPublicIpCapacityThreshold.key());
-        String localStorageCapacityThreshold = _configDao.getValue(Config.LocalStorageCapacityThreshold.key());
-
-        if (publicIPCapacityThreshold != null) {
-            _publicIPCapacityThreshold = Double.parseDouble(publicIPCapacityThreshold);
-        }
-        if (privateIPCapacityThreshold != null) {
-            _privateIPCapacityThreshold = Double.parseDouble(privateIPCapacityThreshold);
-        }
-        if (secondaryStorageCapacityThreshold != null) {
-            _secondaryStorageCapacityThreshold = Double.parseDouble(secondaryStorageCapacityThreshold);
-        }
-        if (vlanCapacityThreshold != null) {
-            _vlanCapacityThreshold = Double.parseDouble(vlanCapacityThreshold);
-        }
-        if (directNetworkPublicIpCapacityThreshold != null) {
-            _directNetworkPublicIpCapacityThreshold = Double.parseDouble(directNetworkPublicIpCapacityThreshold);
-        }
-        if (localStorageCapacityThreshold != null) {
-            _localStorageCapacityThreshold = Double.parseDouble(localStorageCapacityThreshold);
-        }
-
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, _publicIPCapacityThreshold);
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_PRIVATE_IP, _privateIPCapacityThreshold);
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, _secondaryStorageCapacityThreshold);
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VLAN, _vlanCapacityThreshold);
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, _directNetworkPublicIpCapacityThreshold);
-        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_LOCAL_STORAGE, _localStorageCapacityThreshold);
-
-        String capacityCheckPeriodStr = configs.get("capacity.check.period");
-        if (capacityCheckPeriodStr != null) {
-            _capacityCheckPeriod = Long.parseLong(capacityCheckPeriodStr);
-            if (_capacityCheckPeriod <= 0)
-                _capacityCheckPeriod = Long.parseLong(Config.CapacityCheckPeriod.getDefaultValue());
-        }
-
-        _timer = new Timer("CapacityChecker");
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        _timer.schedule(new CapacityChecker(), INITIAL_CAPACITY_CHECK_DELAY, _capacityCheckPeriod);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _timer.cancel();
-        return true;
-    }
-
-    @Override
-    public void clearAlert(AlertType alertType, long dataCenterId, long podId) {
-        try {
-            if (_emailAlert != null) {
-                _emailAlert.clearAlert(alertType.getType(), dataCenterId, podId);
-            }
-        } catch (Exception ex) {
-            s_logger.error("Problem clearing email alert", ex);
-        }
-    }
-
-    @Override
-    public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) {
-
-        // publish alert
-        AlertGenerator.publishAlertOnEventBus(alertType.getName(), dataCenterId, podId, subject, body);
-
-        // TODO:  queue up these messages and send them as one set of issues once a certain number of issues is reached?  If that's the case,
-        //         shouldn't we have a type/severity as part of the API so that severe errors get sent right away?
-        try {
-            if (_emailAlert != null) {
-                _emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body);
-            } else {
-                s_alertsLogger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
-                        " | message:: " + subject + " | body:: " + body);
-            }
-        } catch (Exception ex) {
-            s_logger.error("Problem sending email alert", ex);
-        }
-    }
-
-    @Override
-    public void recalculateCapacity() {
-        // FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener)
-        //        for the vm sync state.  The listener model has connects/disconnects to keep things in sync much better
-        //        than this model right now, so when a VM is started, we update the amount allocated, and when a VM
-        //        is stopped we updated the amount allocated, and when VM sync reports a changed state, we update
-        //        the amount allocated.  Hopefully it's limited to 3 entry points and will keep the amount allocated
-        //        per host accurate.
-
-        try {
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("recalculating system capacity");
-                s_logger.debug("Executing cpu/ram capacity update");
-            }
-
-            // Calculate CPU and RAM capacities
-            //     get all hosts...even if they are not in 'UP' state
-            List<HostVO> hosts = _resourceMgr.listAllNotInMaintenanceHostsInOneZone(Host.Type.Routing, null);
-            if (hosts != null) {
-                for (HostVO host : hosts) {
-                    _capacityMgr.updateCapacityForHost(host);
-                }
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Done executing cpu/ram capacity update");
-                s_logger.debug("Executing storage capacity update");
-            }
-            // Calculate storage pool capacity
-            List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
-            for (StoragePoolVO pool : storagePools) {
-                long disk = _capacityMgr.getAllocatedPoolCapacity(pool, null);
-                if (pool.isShared()) {
-                    _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, disk);
-                } else {
-                    _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, disk);
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Done executing storage capacity update");
-                s_logger.debug("Executing capacity updates for public ip and Vlans");
-            }
-
-            List<DataCenterVO> datacenters = _dcDao.listAll();
-            for (DataCenterVO datacenter : datacenters) {
-                long dcId = datacenter.getId();
-
-                //NOTE
-                //What happens if we have multiple vlans? Dashboard currently shows stats
-                //with no filter based on a vlan
-                //ideal way would be to remove out the vlan param, and filter only on dcId
-                //implementing the same
-
-                // Calculate new Public IP capacity for Virtual Network
-                if (datacenter.getNetworkType() == NetworkType.Advanced) {
-                    createOrUpdateIpCapacity(dcId, null, Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, datacenter.getAllocationState());
-                }
-
-                // Calculate new Public IP capacity for Direct Attached Network
-                createOrUpdateIpCapacity(dcId, null, Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, datacenter.getAllocationState());
-
-                if (datacenter.getNetworkType() == NetworkType.Advanced) {
-                    //Calculate VLAN's capacity
-                    createOrUpdateVlanCapacity(dcId, datacenter.getAllocationState());
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Done capacity updates for public ip and Vlans");
-                s_logger.debug("Executing capacity updates for private ip");
-            }
-
-            // Calculate new Private IP capacity
-            List<HostPodVO> pods = _podDao.listAll();
-            for (HostPodVO pod : pods) {
-                long podId = pod.getId();
-                long dcId = pod.getDataCenterId();
-
-                createOrUpdateIpCapacity(dcId, podId, Capacity.CAPACITY_TYPE_PRIVATE_IP, _configMgr.findPodAllocationState(pod));
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Done executing capacity updates for private ip");
-                s_logger.debug("Done recalculating system capacity");
-            }
-
-        } catch (Throwable t) {
-            s_logger.error("Caught exception in recalculating capacity", t);
-        }
-    }
-
-    private void createOrUpdateVlanCapacity(long dcId, AllocationState capacityState) {
-
-        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
-
-        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
-        capacitySC = _capacityDao.createSearchCriteria();
-        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
-        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_VLAN);
-        capacities = _capacityDao.search(capacitySC, null);
-
-        int totalVlans = _dcDao.countZoneVlans(dcId, false);
-        int allocatedVlans = _dcDao.countZoneVlans(dcId, true);
-
-        CapacityState vlanCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
-        if (capacities.size() == 0) {
-            CapacityVO newVlanCapacity = new CapacityVO(null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN);
-            newVlanCapacity.setCapacityState(vlanCapacityState);
-            _capacityDao.persist(newVlanCapacity);
-        } else if (!(capacities.get(0).getUsedCapacity() == allocatedVlans && capacities.get(0).getTotalCapacity() == totalVlans
-                && capacities.get(0).getCapacityState() == vlanCapacityState)) {
-            CapacityVO capacity = capacities.get(0);
-            capacity.setUsedCapacity(allocatedVlans);
-            capacity.setTotalCapacity(totalVlans);
-            capacity.setCapacityState(vlanCapacityState);
-            _capacityDao.update(capacity.getId(), capacity);
-        }
-
-    }
-
-    public void createOrUpdateIpCapacity(Long dcId, Long podId, short capacityType, AllocationState capacityState) {
-        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
-
-        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
-        capacitySC = _capacityDao.createSearchCriteria();
-        capacitySC.addAnd("podId", SearchCriteria.Op.EQ, podId);
-        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
-        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
-
-        int totalIPs;
-        int allocatedIPs;
-        capacities = _capacityDao.search(capacitySC, null);
-        if (capacityType == Capacity.CAPACITY_TYPE_PRIVATE_IP) {
-            totalIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
-            allocatedIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
-        } else if (capacityType == Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP) {
-            totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.VirtualNetwork);
-            allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.VirtualNetwork);
-        } else {
-            totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.DirectAttached);
-            allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.DirectAttached);
-        }
-
-        CapacityState ipCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
-        if (capacities.size() == 0) {
-            CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType);
-            newPublicIPCapacity.setCapacityState(ipCapacityState);
-            _capacityDao.persist(newPublicIPCapacity);
-        } else if (!(capacities.get(0).getUsedCapacity() == allocatedIPs && capacities.get(0).getTotalCapacity() == totalIPs
-                && capacities.get(0).getCapacityState() == ipCapacityState)) {
-            CapacityVO capacity = capacities.get(0);
-            capacity.setUsedCapacity(allocatedIPs);
-            capacity.setTotalCapacity(totalIPs);
-            capacity.setCapacityState(ipCapacityState);
-            _capacityDao.update(capacity.getId(), capacity);
-        }
-    }
-
-    class CapacityChecker extends ManagedContextTimerTask {
-        @Override
-        protected void runInContext() {
-            try {
-                s_logger.debug("Running Capacity Checker ... ");
-                checkForAlerts();
-                s_logger.debug("Done running Capacity Checker ... ");
-            } catch (Throwable t) {
-                s_logger.error("Exception in CapacityChecker", t);
-            }
-        }
-    }
-
-    public void checkForAlerts() {
-
-        recalculateCapacity();
-
-        // abort if we can't possibly send an alert...
-        if (_emailAlert == null) {
-            return;
-        }
-
-        //Get all datacenters, pods and clusters in the system.
-        List<DataCenterVO> dataCenterList = _dcDao.listAll();
-        List<ClusterVO> clusterList = _clusterDao.listAll();
-        List<HostPodVO> podList = _podDao.listAll();
-        //Get capacity types at different levels
-        List<Short> dataCenterCapacityTypes = getCapacityTypesAtZoneLevel();
-        List<Short> podCapacityTypes = getCapacityTypesAtPodLevel();
-        List<Short> clusterCapacityTypes = getCapacityTypesAtClusterLevel();
-
-        // Generate Alerts for Zone Level capacities
-        for (DataCenterVO dc : dataCenterList) {
-            for (Short capacityType : dataCenterCapacityTypes) {
-                List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
-                capacity = _capacityDao.findCapacityBy(capacityType.intValue(), dc.getId(), null, null);
-
-                if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
-                    capacity.add(getUsedStats(capacityType, dc.getId(), null, null));
-                }
-                if (capacity == null || capacity.size() == 0) {
-                    continue;
-                }
-                double totalCapacity = capacity.get(0).getTotalCapacity();
-                double usedCapacity = capacity.get(0).getUsedCapacity();
-                if (totalCapacity != 0 && usedCapacity / totalCapacity > _capacityTypeThresholdMap.get(capacityType)) {
-                    generateEmailAlert(dc, null, null, totalCapacity, usedCapacity, capacityType);
-                }
-            }
-        }
-
-        // Generate Alerts for Pod Level capacities
-        for (HostPodVO pod : podList) {
-            for (Short capacityType : podCapacityTypes) {
-                List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), pod.getDataCenterId(), pod.getId(), null);
-                if (capacity == null || capacity.size() == 0) {
-                    continue;
-                }
-                double totalCapacity = capacity.get(0).getTotalCapacity();
-                double usedCapacity = capacity.get(0).getUsedCapacity();
-                if (totalCapacity != 0 && usedCapacity / totalCapacity > _capacityTypeThresholdMap.get(capacityType)) {
-                    generateEmailAlert(ApiDBUtils.findZoneById(pod.getDataCenterId()), pod, null, totalCapacity, usedCapacity, capacityType);
-                }
-            }
-        }
-
-        // Generate Alerts for Cluster Level capacities
-        for (ClusterVO cluster : clusterList) {
-            for (Short capacityType : clusterCapacityTypes) {
-                List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
-                capacity = _capacityDao.findCapacityBy(capacityType.intValue(), cluster.getDataCenterId(), null, cluster.getId());
-
-                // cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level
-                double threshold = 0;
-                switch (capacityType) {
-                case Capacity.CAPACITY_TYPE_STORAGE:
-                    capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId()));
-                    threshold = StorageCapacityThreshold.valueIn(cluster.getId());
-                    break;
-                case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED:
-                    threshold = StorageAllocatedCapacityThreshold.valueIn(cluster.getId());
-                    break;
-                case Capacity.CAPACITY_TYPE_CPU:
-                    threshold = CPUCapacityThreshold.valueIn(cluster.getId());
-                    break;
-                case Capacity.CAPACITY_TYPE_MEMORY:
-                    threshold = MemoryCapacityThreshold.valueIn(cluster.getId());
-                    break;
-                default:
-                    threshold = _capacityTypeThresholdMap.get(capacityType);
-                }
-                if (capacity == null || capacity.size() == 0) {
-                    continue;
-                }
-
-                double totalCapacity = capacity.get(0).getTotalCapacity();
-                double usedCapacity = capacity.get(0).getUsedCapacity() + capacity.get(0).getReservedCapacity();
-                if (totalCapacity != 0 && usedCapacity / totalCapacity > threshold) {
-                    generateEmailAlert(ApiDBUtils.findZoneById(cluster.getDataCenterId()), ApiDBUtils.findPodById(cluster.getPodId()), cluster, totalCapacity,
-                            usedCapacity, capacityType);
-                }
-            }
-        }
-
-    }
-
-    private SummedCapacity getUsedStats(short capacityType, long zoneId, Long podId, Long clusterId) {
-        CapacityVO capacity;
-        if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
-            capacity = _storageMgr.getSecondaryStorageUsedStats(null, zoneId);
-        } else {
-            capacity = _storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId);
-        }
-        if (capacity != null) {
-            return new SummedCapacity(capacity.getUsedCapacity(), 0, capacity.getTotalCapacity(), capacityType, clusterId, podId);
-        } else {
-            return null;
-        }
-
-    }
-
-    private void generateEmailAlert(DataCenterVO dc, HostPodVO pod, ClusterVO cluster, double totalCapacity, double usedCapacity, short capacityType) {
-
-        String msgSubject = null;
-        String msgContent = null;
-        String totalStr;
-        String usedStr;
-        String pctStr = formatPercent(usedCapacity / totalCapacity);
-        AlertType alertType = null;
-        Long podId = pod == null ? null : pod.getId();
-        Long clusterId = cluster == null ? null : cluster.getId();
-
-        switch (capacityType) {
-
-        //Cluster Level
-        case Capacity.CAPACITY_TYPE_MEMORY:
-            msgSubject = "System Alert: Low Available Memory in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
-            totalStr = formatBytesToMegabytes(totalCapacity);
-            usedStr = formatBytesToMegabytes(usedCapacity);
-            msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_MEMORY;
-            break;
-        case Capacity.CAPACITY_TYPE_CPU:
-            msgSubject = "System Alert: Low Unallocated CPU in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
-            totalStr = DfWhole.format(totalCapacity);
-            usedStr = DfWhole.format(usedCapacity);
-            msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_CPU;
-            break;
-        case Capacity.CAPACITY_TYPE_STORAGE:
-            msgSubject = "System Alert: Low Available Storage in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
-            totalStr = formatBytesToMegabytes(totalCapacity);
-            usedStr = formatBytesToMegabytes(usedCapacity);
-            msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE;
-            break;
-        case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED:
-            msgSubject = "System Alert: Remaining unallocated Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " +
-                    dc.getName();
-            totalStr = formatBytesToMegabytes(totalCapacity);
-            usedStr = formatBytesToMegabytes(usedCapacity);
-            msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE_ALLOCATED;
-            break;
-        case Capacity.CAPACITY_TYPE_LOCAL_STORAGE:
-            msgSubject = "System Alert: Remaining unallocated Local Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " +
-                    dc.getName();
-            totalStr = formatBytesToMegabytes(totalCapacity);
-            usedStr = formatBytesToMegabytes(usedCapacity);
-            msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_LOCAL_STORAGE;
-            break;
-
-        //Pod Level
-        case Capacity.CAPACITY_TYPE_PRIVATE_IP:
-            msgSubject = "System Alert: Number of unallocated private IPs is low in pod " + pod.getName() + " of availability zone " + dc.getName();
-            totalStr = Double.toString(totalCapacity);
-            usedStr = Double.toString(usedCapacity);
-            msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_PRIVATE_IP;
-            break;
-
-        //Zone Level
-        case Capacity.CAPACITY_TYPE_SECONDARY_STORAGE:
-            msgSubject = "System Alert: Low Available Secondary Storage in availability zone " + dc.getName();
-            totalStr = formatBytesToMegabytes(totalCapacity);
-            usedStr = formatBytesToMegabytes(usedCapacity);
-            msgContent = "Available secondary storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_SECONDARY_STORAGE;
-            break;
-        case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP:
-            msgSubject = "System Alert: Number of unallocated virtual network public IPs is low in availability zone " + dc.getName();
-            totalStr = Double.toString(totalCapacity);
-            usedStr = Double.toString(usedCapacity);
-            msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP;
-            break;
-        case Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP:
-            msgSubject = "System Alert: Number of unallocated shared network IPs is low in availability zone " + dc.getName();
-            totalStr = Double.toString(totalCapacity);
-            usedStr = Double.toString(usedCapacity);
-            msgContent = "Number of unallocated shared network IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP;
-            break;
-        case Capacity.CAPACITY_TYPE_VLAN:
-            msgSubject = "System Alert: Number of unallocated VLANs is low in availability zone " + dc.getName();
-            totalStr = Double.toString(totalCapacity);
-            usedStr = Double.toString(usedCapacity);
-            msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
-            alertType = AlertManager.AlertType.ALERT_TYPE_VLAN;
-            break;
-        }
-
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(msgSubject);
-                s_logger.debug(msgContent);
-            }
-            _emailAlert.sendAlert(alertType, dc.getId(), podId, clusterId, msgSubject, msgContent);
-        } catch (Exception ex) {
-            s_logger.error("Exception in CapacityChecker", ex);
-        }
-    }
-
-    private List<Short> getCapacityTypesAtZoneLevel() {
-
-        List<Short> dataCenterCapacityTypes = new ArrayList<Short>();
-        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP);
-        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP);
-        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
-        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VLAN);
-        return dataCenterCapacityTypes;
-
-    }
-
-    private List<Short> getCapacityTypesAtPodLevel() {
-
-        List<Short> podCapacityTypes = new ArrayList<Short>();
-        podCapacityTypes.add(Capacity.CAPACITY_TYPE_PRIVATE_IP);
-        return podCapacityTypes;
-
-    }
-
-    private List<Short> getCapacityTypesAtClusterLevel() {
-
-        List<Short> clusterCapacityTypes = new ArrayList<Short>();
-        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_CPU);
-        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_MEMORY);
-        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE);
-        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED);
-        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_LOCAL_STORAGE);
-        return clusterCapacityTypes;
-
-    }
-
-    class EmailAlert {
-        private Session _smtpSession;
-        private InternetAddress[] _recipientList;
-        private final String _smtpHost;
-        private int _smtpPort = -1;
-        private boolean _smtpUseAuth = false;
-        private final String _smtpUsername;
-        private final String _smtpPassword;
-        private final String _emailSender;
-        private int _smtpTimeout;
-        private int _smtpConnectionTimeout;
-
-        public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, int smtpConnectionTimeout, int smtpTimeout, boolean smtpUseAuth,
-                final String smtpUsername,
-                final String smtpPassword, String emailSender, boolean smtpDebug) {
-            if (recipientList != null) {
-                _recipientList = new InternetAddress[recipientList.length];
-                for (int i = 0; i < recipientList.length; i++) {
-                    try {
-                        _recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]);
-                    } catch (Exception ex) {
-                        s_logger.error("Exception creating address for: " + recipientList[i], ex);
-                    }
-                }
-            }
-
-            _smtpHost = smtpHost;
-            _smtpPort = smtpPort;
-            _smtpUseAuth = smtpUseAuth;
-            _smtpUsername = smtpUsername;
-            _smtpPassword = smtpPassword;
-            _emailSender = emailSender;
-            _smtpTimeout = smtpTimeout;
-            _smtpConnectionTimeout = smtpConnectionTimeout;
-
-            if (_smtpHost != null) {
-                Properties smtpProps = new Properties();
-                smtpProps.put("mail.smtp.host", smtpHost);
-                smtpProps.put("mail.smtp.port", smtpPort);
-                smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
-                smtpProps.put("mail.smtp.timeout", _smtpTimeout);
-                smtpProps.put("mail.smtp.connectiontimeout", _smtpConnectionTimeout);
-
-                if (smtpUsername != null) {
-                    smtpProps.put("mail.smtp.user", smtpUsername);
-                }
-
-                smtpProps.put("mail.smtps.host", smtpHost);
-                smtpProps.put("mail.smtps.port", smtpPort);
-                smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
-                smtpProps.put("mail.smtps.timeout", _smtpTimeout);
-                smtpProps.put("mail.smtps.connectiontimeout", _smtpConnectionTimeout);
-
-                if (smtpUsername != null) {
-                    smtpProps.put("mail.smtps.user", smtpUsername);
-                }
-
-                if ((smtpUsername != null) && (smtpPassword != null)) {
-                    _smtpSession = Session.getInstance(smtpProps, new Authenticator() {
-                        @Override
-                        protected PasswordAuthentication getPasswordAuthentication() {
-                            return new PasswordAuthentication(smtpUsername, smtpPassword);
-                        }
-                    });
-                } else {
-                    _smtpSession = Session.getInstance(smtpProps);
-                }
-                _smtpSession.setDebug(smtpDebug);
-            } else {
-                _smtpSession = null;
-            }
-        }
-
-        // TODO:  make sure this handles SSL transport (useAuth is true) and regular
-        public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException,
-                UnsupportedEncodingException {
-            s_alertsLogger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " +
-                    podId + " | clusterId:: " + clusterId + " | message:: " + subject);
-            AlertVO alert = null;
-            if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) &&
-                (alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT)) {
-                alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
-            }
-
-            if (alert == null) {
-                // set up a new alert
-                AlertVO newAlert = new AlertVO();
-                newAlert.setType(alertType.getType());
-                newAlert.setSubject(subject);
-                newAlert.setClusterId(clusterId);
-                newAlert.setPodId(podId);
-                newAlert.setDataCenterId(dataCenterId);
-                newAlert.setSentCount(1); // Initialize sent count to 1 since we are now sending an alert.
-                newAlert.setLastSent(new Date());
-                newAlert.setName(alertType.getName());
-                _alertDao.persist(newAlert);
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
-                }
-                return;
-            }
-
-            if (_smtpSession != null) {
-                SMTPMessage msg = new SMTPMessage(_smtpSession);
-                msg.setSender(new InternetAddress(_emailSender, _emailSender));
-                msg.setFrom(new InternetAddress(_emailSender, _emailSender));
-                for (InternetAddress address : _recipientList) {
-                    msg.addRecipient(RecipientType.TO, address);
-                }
-                msg.setSubject(subject);
-                msg.setSentDate(new Date());
-                msg.setContent(content, "text/plain");
-                msg.saveChanges();
-
-                SMTPTransport smtpTrans = null;
-                if (_smtpUseAuth) {
-                    smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
-                } else {
-                    smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
-                }
-                sendMessage(smtpTrans, msg);
-            }
-        }
-
-        private void sendMessage(final SMTPTransport smtpTrans, final SMTPMessage msg) {
-            _executor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        smtpTrans.connect();
-                        smtpTrans.sendMessage(msg, msg.getAllRecipients());
-                        smtpTrans.close();
-                    } catch (SendFailedException e) {
-                        s_logger.error(" Failed to send email alert " + e);
-                    } catch (MessagingException e) {
-                        s_logger.error(" Failed to send email alert " + e);
-                    }
-                }
-            });
-        }
-
-        public void clearAlert(short alertType, long dataCenterId, Long podId) {
-            if (alertType != -1) {
-                AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, null);
-                if (alert != null) {
-                    AlertVO updatedAlert = _alertDao.createForUpdate();
-                    updatedAlert.setResolved(new Date());
-                    _alertDao.update(alert.getId(), updatedAlert);
-                }
-            }
-        }
-    }
-
-    private static String formatPercent(double percentage) {
-        return DfPct.format(percentage * 100);
-    }
-
-    private static String formatBytesToMegabytes(double bytes) {
-        double megaBytes = (bytes / (1024 * 1024));
-        return DfWhole.format(megaBytes);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return AlertManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold};
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.ALERT_GENERATE, eventDescription = "generating alert", async = true)
-    public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg) {
-        try {
-            sendAlert(alertType, dataCenterId, podId, msg, msg);
-            return true;
-        } catch (Exception ex) {
-            s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg);
-            return false;
-        }
-    }
-}
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
deleted file mode 100644
index 7375588..0000000
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api;
-
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import com.cloud.projects.Project;
-import com.cloud.utils.db.EntityManager;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseCustomIdCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-
-import com.cloud.api.dispatch.DispatchChain;
-import com.cloud.api.dispatch.DispatchChainFactory;
-import com.cloud.api.dispatch.DispatchTask;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-
-public class ApiDispatcher {
-    private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
-
-    Long _createSnapshotQueueSizeLimit;
-
-    @Inject
-    AsyncJobManager _asyncMgr;
-
-    @Inject
-    AccountManager _accountMgr;
-
-    @Inject
-    EntityManager _entityMgr;
-
-    @Inject()
-    protected DispatchChainFactory dispatchChainFactory;
-
-    protected DispatchChain standardDispatchChain;
-
-    protected DispatchChain asyncCreationDispatchChain;
-
-    public ApiDispatcher() {
-    }
-
-    @PostConstruct
-    public void setup() {
-        standardDispatchChain = dispatchChainFactory.getStandardDispatchChain();
-        asyncCreationDispatchChain = dispatchChainFactory.getAsyncCreationDispatchChain();
-    }
-
-    public void setCreateSnapshotQueueSizeLimit(final Long snapshotLimit) {
-        _createSnapshotQueueSizeLimit = snapshotLimit;
-    }
-
-
-    public void dispatchCreateCmd(final BaseAsyncCreateCmd cmd, final Map<String, String> params) throws Exception {
-        asyncCreationDispatchChain.dispatch(new DispatchTask(cmd, params));
-    }
-
-    private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class);
-        String apiName = commandAnnotation != null ? commandAnnotation.name() : null;
-
-        if (!entitiesToAccess.isEmpty()) {
-            for (Object entity : entitiesToAccess.keySet()) {
-                if (entity instanceof ControlledEntity) {
-                    _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), false, apiName, (ControlledEntity) entity);
-                } else if (entity instanceof InfrastructureEntity) {
-                    //FIXME: Move this code in adapter, remove code from Account manager
-                }
-            }
-        }
-    }
-
-    public void dispatch(final BaseCmd cmd, final Map<String, String> params, final boolean execute) throws Exception {
-        // Let the chain of responsibility dispatch gradually
-        standardDispatchChain.dispatch(new DispatchTask(cmd, params));
-
-        final CallContext ctx = CallContext.current();
-        ctx.setEventDisplayEnabled(cmd.isDisplay());
-        if(params.get(ApiConstants.PROJECT_ID) != null) {
-            Project project = _entityMgr.findByUuidIncludingRemoved(Project.class, params.get(ApiConstants.PROJECT_ID));
-            ctx.setProject(project);
-        }
-
-        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
-        if (cmd instanceof BaseAsyncCmd) {
-
-            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
-            final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
-            ctx.setStartEventId(Long.parseLong(startEventId));
-
-            // Synchronise job on the object if needed
-            if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {
-                Long queueSizeLimit = null;
-                if (asyncCmd.getSyncObjType() != null && asyncCmd.getSyncObjType().equalsIgnoreCase(BaseAsyncCmd.snapshotHostSyncObject)) {
-                    queueSizeLimit = _createSnapshotQueueSizeLimit;
-                } else {
-                    queueSizeLimit = 1L;
-                }
-
-                if (queueSizeLimit != null) {
-                    if (!execute) {
-                        // if we are not within async-execution context, enqueue the command
-                        _asyncMgr.syncAsyncJobExecution((AsyncJob)asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit);
-                        return;
-                    }
-                } else {
-                    s_logger.trace("The queue size is unlimited, skipping the synchronizing");
-                }
-            }
-        }
-
-        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
-        if (cmd instanceof BaseAsyncCustomIdCmd) {
-            ((BaseAsyncCustomIdCmd)cmd).checkUuid();
-        } else if (cmd instanceof BaseCustomIdCmd) {
-            ((BaseCustomIdCmd)cmd).checkUuid();
-        }
-
-        cmd.execute();
-                            }
-
-}
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
deleted file mode 100644
index c10e259..0000000
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ /dev/null
@@ -1,3967 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api;
-
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.agent.api.VgpuTypesInfo;
-import com.cloud.api.query.ViewResponseHelper;
-import com.cloud.api.query.vo.AccountJoinVO;
-import com.cloud.api.query.vo.AsyncJobJoinVO;
-import com.cloud.api.query.vo.ControlledViewEntity;
-import com.cloud.api.query.vo.DataCenterJoinVO;
-import com.cloud.api.query.vo.DiskOfferingJoinVO;
-import com.cloud.api.query.vo.DomainRouterJoinVO;
-import com.cloud.api.query.vo.EventJoinVO;
-import com.cloud.api.query.vo.HostJoinVO;
-import com.cloud.api.query.vo.ImageStoreJoinVO;
-import com.cloud.api.query.vo.InstanceGroupJoinVO;
-import com.cloud.api.query.vo.ProjectAccountJoinVO;
-import com.cloud.api.query.vo.ProjectInvitationJoinVO;
-import com.cloud.api.query.vo.ProjectJoinVO;
-import com.cloud.api.query.vo.ResourceTagJoinVO;
-import com.cloud.api.query.vo.SecurityGroupJoinVO;
-import com.cloud.api.query.vo.ServiceOfferingJoinVO;
-import com.cloud.api.query.vo.StoragePoolJoinVO;
-import com.cloud.api.query.vo.TemplateJoinVO;
-import com.cloud.api.query.vo.UserAccountJoinVO;
-import com.cloud.api.query.vo.UserVmJoinVO;
-import com.cloud.api.query.vo.VolumeJoinVO;
-import com.cloud.api.response.ApiResponseSerializer;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.configuration.ResourceCount;
-import com.cloud.configuration.ResourceLimit;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.StorageNetworkIpRange;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.event.Event;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.gpu.GPU;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.hypervisor.HypervisorCapabilities;
-import com.cloud.network.GuestVlan;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.OvsProvider;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PhysicalNetworkTrafficType;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteCustomerGateway;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.Site2SiteVpnGateway;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.VpnUser;
-import com.cloud.network.VpnUserVO;
-import com.cloud.network.as.AutoScalePolicy;
-import com.cloud.network.as.AutoScaleVmGroup;
-import com.cloud.network.as.AutoScaleVmProfile;
-import com.cloud.network.as.AutoScaleVmProfileVO;
-import com.cloud.network.as.Condition;
-import com.cloud.network.as.ConditionVO;
-import com.cloud.network.as.Counter;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.HealthCheckPolicy;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.rules.StickinessPolicy;
-import com.cloud.network.security.SecurityGroup;
-import com.cloud.network.security.SecurityGroupVO;
-import com.cloud.network.security.SecurityRule;
-import com.cloud.network.security.SecurityRule.SecurityRuleType;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcOffering;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.org.Cluster;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectAccount;
-import com.cloud.projects.ProjectInvitation;
-import com.cloud.region.ha.GlobalLoadBalancerRule;
-import com.cloud.server.ResourceTag;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.GuestOS;
-import com.cloud.storage.GuestOSCategoryVO;
-import com.cloud.storage.GuestOSHypervisor;
-import com.cloud.storage.ImageStore;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Upload;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotPolicy;
-import com.cloud.storage.snapshot.SnapshotSchedule;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.SSHKeyPair;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.ConsoleProxyVO;
-import com.cloud.vm.InstanceGroup;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicExtraDhcpOptionVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.dao.NicExtraDhcpOptionDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.snapshot.VMSnapshot;
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.api.ApiConstants.HostDetails;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ResponseGenerator;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.ApplicationLoadBalancerInstanceResponse;
-import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
-import org.apache.cloudstack.api.response.ApplicationLoadBalancerRuleResponse;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
-import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
-import org.apache.cloudstack.api.response.CapabilityResponse;
-import org.apache.cloudstack.api.response.CapacityResponse;
-import org.apache.cloudstack.api.response.ClusterResponse;
-import org.apache.cloudstack.api.response.ConditionResponse;
-import org.apache.cloudstack.api.response.ConfigurationResponse;
-import org.apache.cloudstack.api.response.ControlledEntityResponse;
-import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
-import org.apache.cloudstack.api.response.CounterResponse;
-import org.apache.cloudstack.api.response.CreateCmdResponse;
-import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.EventResponse;
-import org.apache.cloudstack.api.response.ExtractResponse;
-import org.apache.cloudstack.api.response.FirewallResponse;
-import org.apache.cloudstack.api.response.FirewallRuleResponse;
-import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
-import org.apache.cloudstack.api.response.GuestOSResponse;
-import org.apache.cloudstack.api.response.GuestOsMappingResponse;
-import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
-import org.apache.cloudstack.api.response.HostForMigrationResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.api.response.InstanceGroupResponse;
-import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
-import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
-import org.apache.cloudstack.api.response.IsolationMethodResponse;
-import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse;
-import org.apache.cloudstack.api.response.LBHealthCheckResponse;
-import org.apache.cloudstack.api.response.LBStickinessPolicyResponse;
-import org.apache.cloudstack.api.response.LBStickinessResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.LoadBalancerResponse;
-import org.apache.cloudstack.api.response.NetworkACLItemResponse;
-import org.apache.cloudstack.api.response.NetworkACLResponse;
-import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.cloudstack.api.response.NetworkResponse;
-import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.OvsProviderResponse;
-import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
-import org.apache.cloudstack.api.response.PodResponse;
-import org.apache.cloudstack.api.response.PortableIpRangeResponse;
-import org.apache.cloudstack.api.response.PortableIpResponse;
-import org.apache.cloudstack.api.response.PrivateGatewayResponse;
-import org.apache.cloudstack.api.response.ProjectAccountResponse;
-import org.apache.cloudstack.api.response.ProjectInvitationResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.ProviderResponse;
-import org.apache.cloudstack.api.response.RegionResponse;
-import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
-import org.apache.cloudstack.api.response.ResourceCountResponse;
-import org.apache.cloudstack.api.response.ResourceLimitResponse;
-import org.apache.cloudstack.api.response.ResourceTagResponse;
-import org.apache.cloudstack.api.response.SSHKeyPairResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.ServiceResponse;
-import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
-import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
-import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
-import org.apache.cloudstack.api.response.StaticRouteResponse;
-import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
-import org.apache.cloudstack.api.response.SystemVmResponse;
-import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.TrafficMonitorResponse;
-import org.apache.cloudstack.api.response.TrafficTypeResponse;
-import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
-import org.apache.cloudstack.api.response.UsageRecordResponse;
-import org.apache.cloudstack.api.response.UserResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VMSnapshotResponse;
-import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
-import org.apache.cloudstack.api.response.VlanIpRangeResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.VpcOfferingResponse;
-import org.apache.cloudstack.api.response.VpcResponse;
-import org.apache.cloudstack.api.response.VpnUsersResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.config.Configuration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
-import org.apache.cloudstack.region.PortableIp;
-import org.apache.cloudstack.region.PortableIpRange;
-import org.apache.cloudstack.region.Region;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.usage.Usage;
-import org.apache.cloudstack.usage.UsageService;
-import org.apache.cloudstack.usage.UsageTypes;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.stream.Collectors;
-
-public class ApiResponseHelper implements ResponseGenerator {
-
-    private static final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
-    private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##");
-
-    @Inject
-    private EntityManager _entityMgr;
-    @Inject
-    private UsageService _usageSvc;
-    @Inject
-    NetworkModel _ntwkModel;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected AsyncJobManager _jobMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    SnapshotDataFactory snapshotfactory;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private DataStoreManager _dataStoreMgr;
-    @Inject
-    private SnapshotDataStoreDao _snapshotStoreDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    private ResourceTagDao _resourceTagDao;
-    @Inject
-    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
-    @Inject
-    private IPAddressDao userIpAddressDao;
-
-    @Override
-    public UserResponse createUserResponse(User user) {
-        UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
-        return ApiDBUtils.newUserResponse(vUser);
-    }
-
-    // this method is used for response generation via createAccount (which
-    // creates an account + user)
-    @Override
-    public AccountResponse createUserAccountResponse(ResponseView view, UserAccount user) {
-        return ApiDBUtils.newAccountResponse(view, ApiDBUtils.findAccountViewById(user.getAccountId()));
-    }
-
-    @Override
-    public AccountResponse createAccountResponse(ResponseView view, Account account) {
-        AccountJoinVO vUser = ApiDBUtils.newAccountView(account);
-        return ApiDBUtils.newAccountResponse(view, vUser);
-    }
-
-    @Override
-    public UserResponse createUserResponse(UserAccount user) {
-        UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
-        return ApiDBUtils.newUserResponse(vUser);
-    }
-
-    @Override
-    public DomainResponse createDomainResponse(Domain domain) {
-        DomainResponse domainResponse = new DomainResponse();
-        domainResponse.setDomainName(domain.getName());
-        domainResponse.setId(domain.getUuid());
-        domainResponse.setLevel(domain.getLevel());
-        domainResponse.setNetworkDomain(domain.getNetworkDomain());
-        Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent());
-        if (parentDomain != null) {
-            domainResponse.setParentDomainId(parentDomain.getUuid());
-        }
-        StringBuilder domainPath = new StringBuilder("ROOT");
-        (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1);
-        domainResponse.setPath(domainPath.toString());
-        if (domain.getParent() != null) {
-            domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName());
-        }
-        if (domain.getChildCount() > 0) {
-            domainResponse.setHasChild(true);
-        }
-        domainResponse.setObjectName("domain");
-        return domainResponse;
-    }
-
-    @Override
-    public DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering) {
-        DiskOfferingJoinVO vOffering = ApiDBUtils.newDiskOfferingView(offering);
-        return ApiDBUtils.newDiskOfferingResponse(vOffering);
-    }
-
-    @Override
-    public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) {
-        ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse();
-        if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) {
-            populateDomain(resourceLimitResponse, limit.getOwnerId());
-        } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) {
-            Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId());
-            populateAccount(resourceLimitResponse, limit.getOwnerId());
-            populateDomain(resourceLimitResponse, accountTemp.getDomainId());
-        }
-        resourceLimitResponse.setResourceType(limit.getType());
-
-        if ((limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) && limit.getMax() >= 0) {
-            resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB));
-        } else {
-            resourceLimitResponse.setMax(limit.getMax());
-        }
-        resourceLimitResponse.setObjectName("resourcelimit");
-
-        return resourceLimitResponse;
-    }
-
-    @Override
-    public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) {
-        ResourceCountResponse resourceCountResponse = new ResourceCountResponse();
-
-        if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) {
-            Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId());
-            if (accountTemp != null) {
-                populateAccount(resourceCountResponse, accountTemp.getId());
-                populateDomain(resourceCountResponse, accountTemp.getDomainId());
-            }
-        } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) {
-            populateDomain(resourceCountResponse, resourceCount.getOwnerId());
-        }
-
-        resourceCountResponse.setResourceType(resourceCount.getType());
-        resourceCountResponse.setResourceCount(resourceCount.getCount());
-        resourceCountResponse.setObjectName("resourcecount");
-        return resourceCountResponse;
-    }
-
-    @Override
-    public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) {
-        ServiceOfferingJoinVO vOffering = ApiDBUtils.newServiceOfferingView(offering);
-        return ApiDBUtils.newServiceOfferingResponse(vOffering);
-    }
-
-    @Override
-    public ConfigurationResponse createConfigurationResponse(Configuration cfg) {
-        ConfigurationResponse cfgResponse = new ConfigurationResponse();
-        cfgResponse.setCategory(cfg.getCategory());
-        cfgResponse.setDescription(cfg.getDescription());
-        cfgResponse.setName(cfg.getName());
-        if(cfg.isEncrypted()) {
-            cfgResponse.setValue(DBEncryptionUtil.encrypt(cfg.getValue()));
-        } else {
-            cfgResponse.setValue(cfg.getValue());
-        }
-        cfgResponse.setObjectName("configuration");
-
-        return cfgResponse;
-    }
-
-    @Override
-    public SnapshotResponse createSnapshotResponse(Snapshot snapshot) {
-        SnapshotResponse snapshotResponse = new SnapshotResponse();
-        snapshotResponse.setId(snapshot.getUuid());
-
-        populateOwner(snapshotResponse, snapshot);
-
-        VolumeVO volume = findVolumeById(snapshot.getVolumeId());
-        String snapshotTypeStr = snapshot.getRecurringType().name();
-        snapshotResponse.setSnapshotType(snapshotTypeStr);
-        if (volume != null) {
-            snapshotResponse.setVolumeId(volume.getUuid());
-            snapshotResponse.setVolumeName(volume.getName());
-            snapshotResponse.setVolumeType(volume.getVolumeType().name());
-            snapshotResponse.setVirtualSize(volume.getSize());
-            DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
-            if (zone != null) {
-                snapshotResponse.setZoneId(zone.getUuid());
-            }
-
-            if (volume.getVolumeType() == Volume.Type.ROOT && volume.getInstanceId() != null) {
-                //TODO combine lines and 489 into a join in the volume dao
-                VMInstanceVO instance = ApiDBUtils.findVMInstanceById(volume.getInstanceId());
-                if (instance != null) {
-                    GuestOS guestOs = ApiDBUtils.findGuestOSById(instance.getGuestOSId());
-                    if (guestOs != null) {
-                        snapshotResponse.setOsTypeId(guestOs.getUuid());
-                        snapshotResponse.setOsDisplayName(guestOs.getDisplayName());
-                    }
-                }
-            }
-        }
-        snapshotResponse.setCreated(snapshot.getCreated());
-        snapshotResponse.setName(snapshot.getName());
-        snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId()));
-        snapshotResponse.setState(snapshot.getState());
-        snapshotResponse.setLocationType(ApiDBUtils.getSnapshotLocationType(snapshot.getId()));
-
-        SnapshotInfo snapshotInfo = null;
-
-        if (snapshot instanceof SnapshotInfo) {
-            snapshotInfo = (SnapshotInfo)snapshot;
-        } else {
-            DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
-
-            snapshotInfo = snapshotfactory.getSnapshot(snapshot.getId(), dataStoreRole);
-        }
-
-        if (snapshotInfo == null) {
-            s_logger.debug("Unable to find info for image store snapshot with uuid " + snapshot.getUuid());
-            snapshotResponse.setRevertable(false);
-        } else {
-        snapshotResponse.setRevertable(snapshotInfo.isRevertable());
-        snapshotResponse.setPhysicaSize(snapshotInfo.getPhysicalSize());
-        }
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Snapshot, snapshot.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        snapshotResponse.setTags(tagResponses);
-
-        snapshotResponse.setObjectName("snapshot");
-        return snapshotResponse;
-    }
-
-    public static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
-        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
-
-        if (snapshotStore == null) {
-            return DataStoreRole.Image;
-        }
-
-        long storagePoolId = snapshotStore.getDataStoreId();
-        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-        if (dataStore == null) {
-            return DataStoreRole.Image;
-        }
-
-        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
-
-        if (mapCapabilities != null) {
-            String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
-            Boolean supportsStorageSystemSnapshots = new Boolean(value);
-
-            if (supportsStorageSystemSnapshots) {
-                return DataStoreRole.Primary;
-            }
-        }
-
-        return DataStoreRole.Image;
-    }
-
-    @Override
-    public VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot) {
-        VMSnapshotResponse vmSnapshotResponse = new VMSnapshotResponse();
-        vmSnapshotResponse.setId(vmSnapshot.getUuid());
-        vmSnapshotResponse.setName(vmSnapshot.getName());
-        vmSnapshotResponse.setState(vmSnapshot.getState());
-        vmSnapshotResponse.setCreated(vmSnapshot.getCreated());
-        vmSnapshotResponse.setDescription(vmSnapshot.getDescription());
-        vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName());
-        UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId());
-        if (vm != null) {
-            vmSnapshotResponse.setVirtualMachineid(vm.getUuid());
-            DataCenterVO datacenter = ApiDBUtils.findZoneById(vm.getDataCenterId());
-            if (datacenter != null) {
-                vmSnapshotResponse.setZoneId(datacenter.getUuid());
-            }
-        }
-        if (vmSnapshot.getParent() != null) {
-            VMSnapshot vmSnapshotParent = ApiDBUtils.getVMSnapshotById(vmSnapshot.getParent());
-            if (vmSnapshotParent != null) {
-                vmSnapshotResponse.setParent(vmSnapshotParent.getUuid());
-                vmSnapshotResponse.setParentName(vmSnapshotParent.getDisplayName());
-            }
-        }
-        populateOwner(vmSnapshotResponse, vmSnapshot);
-        Project project = ApiDBUtils.findProjectByProjectAccountId(vmSnapshot.getAccountId());
-        if (project != null) {
-            vmSnapshotResponse.setProjectId(project.getUuid());
-            vmSnapshotResponse.setProjectName(project.getName());
-        }
-        Account account = ApiDBUtils.findAccountById(vmSnapshot.getAccountId());
-        if (account != null) {
-            vmSnapshotResponse.setAccountName(account.getAccountName());
-        }
-        DomainVO domain = ApiDBUtils.findDomainById(vmSnapshot.getDomainId());
-        if (domain != null) {
-            vmSnapshotResponse.setDomainId(domain.getUuid());
-            vmSnapshotResponse.setDomainName(domain.getName());
-        }
-
-        vmSnapshotResponse.setCurrent(vmSnapshot.getCurrent());
-        vmSnapshotResponse.setType(vmSnapshot.getType().toString());
-        vmSnapshotResponse.setObjectName("vmsnapshot");
-        return vmSnapshotResponse;
-    }
-
-    @Override
-    public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) {
-        SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse();
-        policyResponse.setId(policy.getUuid());
-        Volume vol = ApiDBUtils.findVolumeById(policy.getVolumeId());
-        if (vol != null) {
-            policyResponse.setVolumeId(vol.getUuid());
-        }
-        policyResponse.setSchedule(policy.getSchedule());
-        policyResponse.setIntervalType(policy.getInterval());
-        policyResponse.setMaxSnaps(policy.getMaxSnaps());
-        policyResponse.setTimezone(policy.getTimezone());
-        policyResponse.setForDisplay(policy.isDisplay());
-        policyResponse.setObjectName("snapshotpolicy");
-
-        return policyResponse;
-    }
-
-    @Override
-    public HostResponse createHostResponse(Host host) {
-        return createHostResponse(host, EnumSet.of(HostDetails.all));
-    }
-
-    @Override
-    public HostResponse createHostResponse(Host host, EnumSet<HostDetails> details) {
-        List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
-        List<HostResponse> listHosts = ViewResponseHelper.createHostResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
-        assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
-        return listHosts.get(0);
-    }
-
-    @Override
-    public HostForMigrationResponse createHostForMigrationResponse(Host host) {
-        return createHostForMigrationResponse(host, EnumSet.of(HostDetails.all));
-    }
-
-    @Override
-    public HostForMigrationResponse createHostForMigrationResponse(Host host, EnumSet<HostDetails> details) {
-        List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
-        List<HostForMigrationResponse> listHosts = ViewResponseHelper.createHostForMigrationResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
-        assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
-        return listHosts.get(0);
-    }
-
-    @Override
-    public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) {
-        return createVlanIpRangeResponse(VlanIpRangeResponse.class, vlan);
-    }
-
-    @Override
-    public VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan) {
-        try {
-            Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId());
-
-            VlanIpRangeResponse vlanResponse = subClass.newInstance();
-            vlanResponse.setId(vlan.getUuid());
-            if (vlan.getVlanType() != null) {
-                vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork));
-            }
-            vlanResponse.setVlan(vlan.getVlanTag());
-            DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId());
-            if (zone != null) {
-                vlanResponse.setZoneId(zone.getUuid());
-            }
-
-            if (podId != null) {
-                HostPodVO pod = ApiDBUtils.findPodById(podId);
-                if (pod != null) {
-                    vlanResponse.setPodId(pod.getUuid());
-                    vlanResponse.setPodName(pod.getName());
-                }
-            }
-
-            vlanResponse.setGateway(vlan.getVlanGateway());
-            vlanResponse.setNetmask(vlan.getVlanNetmask());
-
-            // get start ip and end ip of corresponding vlan
-            String ipRange = vlan.getIpRange();
-            if (ipRange != null) {
-                String[] range = ipRange.split("-");
-                vlanResponse.setStartIp(range[0]);
-                vlanResponse.setEndIp(range[1]);
-            }
-
-            vlanResponse.setIp6Gateway(vlan.getIp6Gateway());
-            vlanResponse.setIp6Cidr(vlan.getIp6Cidr());
-
-            String ip6Range = vlan.getIp6Range();
-            if (ip6Range != null) {
-                String[] range = ip6Range.split("-");
-                vlanResponse.setStartIpv6(range[0]);
-                vlanResponse.setEndIpv6(range[1]);
-            }
-
-            if (vlan.getNetworkId() != null) {
-                Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId());
-                if (nw != null) {
-                    vlanResponse.setNetworkId(nw.getUuid());
-                }
-            }
-            Account owner = ApiDBUtils.getVlanAccount(vlan.getId());
-            if (owner != null) {
-                populateAccount(vlanResponse, owner.getId());
-                populateDomain(vlanResponse, owner.getDomainId());
-            } else {
-                Domain domain = ApiDBUtils.getVlanDomain(vlan.getId());
-                if (domain != null) {
-                    populateDomain(vlanResponse, domain.getId());
-                } else {
-                    Long networkId = vlan.getNetworkId();
-                    if (networkId != null) {
-                        Network network = _ntwkModel.getNetwork(networkId);
-                        if (network != null) {
-                            Long accountId = network.getAccountId();
-                            populateAccount(vlanResponse, accountId);
-                            populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId());
-                        }
-                    }
-                }
-            }
-
-            if (vlan.getPhysicalNetworkId() != null) {
-                PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
-                if (pnw != null) {
-                    vlanResponse.setPhysicalNetworkId(pnw.getUuid());
-                }
-            }
-            vlanResponse.setForSystemVms(isForSystemVms(vlan.getId()));
-            vlanResponse.setObjectName("vlan");
-            return vlanResponse;
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new CloudRuntimeException("Failed to create Vlan IP Range response", e);
-        }
-    }
-
-    /**
-     * Return true if vlan IP range is dedicated for system vms (SSVM and CPVM), false if not
-     * @param vlanId vlan id
-     * @return true if VLAN IP range is dedicated to system vms
-     */
-    private boolean isForSystemVms(long vlanId){
-        SearchBuilder<IPAddressVO> sb = userIpAddressDao.createSearchBuilder();
-        sb.and("vlanId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
-        SearchCriteria<IPAddressVO> sc = sb.create();
-        sc.setParameters("vlanId", vlanId);
-        IPAddressVO userIpAddresVO = userIpAddressDao.findOneBy(sc);
-        return userIpAddresVO.isForSystemVms();
-    }
-
-    @Override
-    public IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddr) {
-        VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId());
-        boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork);
-        long zoneId = ipAddr.getDataCenterId();
-
-        IPAddressResponse ipResponse = new IPAddressResponse();
-        ipResponse.setId(ipAddr.getUuid());
-        ipResponse.setIpAddress(ipAddr.getAddress().toString());
-        if (ipAddr.getAllocatedTime() != null) {
-            ipResponse.setAllocated(ipAddr.getAllocatedTime());
-        }
-        DataCenter zone = ApiDBUtils.findZoneById(ipAddr.getDataCenterId());
-        if (zone != null) {
-            ipResponse.setZoneId(zone.getUuid());
-            ipResponse.setZoneName(zone.getName());
-        }
-        ipResponse.setSourceNat(ipAddr.isSourceNat());
-        ipResponse.setIsSystem(ipAddr.getSystem());
-
-        // get account information
-        if (ipAddr.getAllocatedToAccountId() != null) {
-            populateOwner(ipResponse, ipAddr);
-        }
-
-        ipResponse.setForVirtualNetwork(forVirtualNetworks);
-        ipResponse.setStaticNat(ipAddr.isOneToOneNat());
-
-        if (ipAddr.getAssociatedWithVmId() != null) {
-            UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId());
-            if (vm != null) {
-                ipResponse.setVirtualMachineId(vm.getUuid());
-                ipResponse.setVirtualMachineName(vm.getHostName());
-                if (vm.getDisplayName() != null) {
-                    ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
-                } else {
-                    ipResponse.setVirtualMachineDisplayName(vm.getHostName());
-                }
-            }
-        }
-        if (ipAddr.getVmIp() != null) {
-            ipResponse.setVirtualMachineIp(ipAddr.getVmIp());
-        }
-
-        if (ipAddr.getAssociatedWithNetworkId() != null) {
-            Network ntwk = ApiDBUtils.findNetworkById(ipAddr.getAssociatedWithNetworkId());
-            if (ntwk != null) {
-                ipResponse.setAssociatedNetworkId(ntwk.getUuid());
-                ipResponse.setAssociatedNetworkName(ntwk.getName());
-            }
-        }
-
-        if (ipAddr.getVpcId() != null) {
-            Vpc vpc = ApiDBUtils.findVpcById(ipAddr.getVpcId());
-            if (vpc != null) {
-                ipResponse.setVpcId(vpc.getUuid());
-            }
-        }
-
-        // Network id the ip is associated with (if associated networkId is
-        // null, try to get this information from vlan)
-        Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId());
-
-        // Network id the ip belongs to
-        Long networkId;
-        if (vlanNetworkId != null) {
-            networkId = vlanNetworkId;
-        } else {
-            networkId = ApiDBUtils.getPublicNetworkIdByZone(zoneId);
-        }
-
-        if (networkId != null) {
-            NetworkVO nw = ApiDBUtils.findNetworkById(networkId);
-            if (nw != null) {
-                ipResponse.setNetworkId(nw.getUuid());
-            }
-        }
-        ipResponse.setState(ipAddr.getState().toString());
-
-        if (ipAddr.getPhysicalNetworkId() != null) {
-            PhysicalNetworkVO pnw = ApiDBUtils.findPhysicalNetworkById(ipAddr.getPhysicalNetworkId());
-            if (pnw != null) {
-                ipResponse.setPhysicalNetworkId(pnw.getUuid());
-            }
-        }
-
-        // show this info to full view only
-        if (view == ResponseView.Full) {
-            VlanVO vl = ApiDBUtils.findVlanById(ipAddr.getVlanId());
-            if (vl != null) {
-                ipResponse.setVlanId(vl.getUuid());
-                ipResponse.setVlanName(vl.getVlanTag());
-            }
-        }
-
-        if (ipAddr.getSystem()) {
-            if (ipAddr.isOneToOneNat()) {
-                ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString());
-            } else {
-                ipResponse.setPurpose(IpAddress.Purpose.Lb.toString());
-            }
-        }
-
-        ipResponse.setForDisplay(ipAddr.isDisplay());
-
-        ipResponse.setPortable(ipAddr.isPortable());
-
-        //set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PublicIpAddress, ipAddr.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        ipResponse.setTags(tagResponses);
-
-        ipResponse.setObjectName("ipaddress");
-        return ipResponse;
-    }
-
-    @Override
-    public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer) {
-        LoadBalancerResponse lbResponse = new LoadBalancerResponse();
-        lbResponse.setId(loadBalancer.getUuid());
-        lbResponse.setName(loadBalancer.getName());
-        lbResponse.setDescription(loadBalancer.getDescription());
-        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId());
-        lbResponse.setCidrList(StringUtils.join(cidrs, ","));
-
-        IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId());
-        lbResponse.setPublicIpId(publicIp.getUuid());
-        lbResponse.setPublicIp(publicIp.getAddress().addr());
-        lbResponse.setPublicPort(Integer.toString(loadBalancer.getSourcePortStart()));
-        lbResponse.setPrivatePort(Integer.toString(loadBalancer.getDefaultPortStart()));
-        lbResponse.setAlgorithm(loadBalancer.getAlgorithm());
-        lbResponse.setLbProtocol(loadBalancer.getLbProtocol());
-        lbResponse.setForDisplay(loadBalancer.isDisplay());
-        FirewallRule.State state = loadBalancer.getState();
-        String stateToSet = state.toString();
-        if (state.equals(FirewallRule.State.Revoke)) {
-            stateToSet = "Deleting";
-        }
-        lbResponse.setState(stateToSet);
-        populateOwner(lbResponse, loadBalancer);
-        DataCenter zone = ApiDBUtils.findZoneById(publicIp.getDataCenterId());
-        if (zone != null) {
-            lbResponse.setZoneId(zone.getUuid());
-            lbResponse.setZoneName(zone.getName());
-        }
-
-        //set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, loadBalancer.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        lbResponse.setTags(tagResponses);
-
-        Network ntwk = ApiDBUtils.findNetworkById(loadBalancer.getNetworkId());
-        lbResponse.setNetworkId(ntwk.getUuid());
-
-        lbResponse.setObjectName("loadbalancer");
-        return lbResponse;
-    }
-
-    @Override
-    public GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule) {
-        GlobalLoadBalancerResponse response = new GlobalLoadBalancerResponse();
-        response.setAlgorithm(globalLoadBalancerRule.getAlgorithm());
-        response.setStickyMethod(globalLoadBalancerRule.getPersistence());
-        response.setServiceType(globalLoadBalancerRule.getServiceType());
-        response.setServiceDomainName(globalLoadBalancerRule.getGslbDomain() + "." + ApiDBUtils.getDnsNameConfiguredForGslb());
-        response.setName(globalLoadBalancerRule.getName());
-        response.setDescription(globalLoadBalancerRule.getDescription());
-        response.setRegionIdId(globalLoadBalancerRule.getRegion());
-        response.setId(globalLoadBalancerRule.getUuid());
-        populateOwner(response, globalLoadBalancerRule);
-        response.setObjectName("globalloadbalancer");
-
-        List<LoadBalancerResponse> siteLbResponses = new ArrayList<LoadBalancerResponse>();
-        List<? extends LoadBalancer> siteLoadBalaners = ApiDBUtils.listSiteLoadBalancers(globalLoadBalancerRule.getId());
-        for (LoadBalancer siteLb : siteLoadBalaners) {
-            LoadBalancerResponse siteLbResponse = createLoadBalancerResponse(siteLb);
-            siteLbResponses.add(siteLbResponse);
-        }
-        response.setSiteLoadBalancers(siteLbResponses);
-        return response;
-    }
-
-    @Override
-    public PodResponse createPodResponse(Pod pod, Boolean showCapacities) {
-        String[] ipRange = new String[2];
-        List<String> startIp = new ArrayList<String>();
-        List<String> endIp = new ArrayList<String>();
-        List<String> forSystemVms = new ArrayList<String>();
-        List<String> vlanIds = new ArrayList<String>();
-
-        if (pod.getDescription() != null && pod.getDescription().length() > 0) {
-            final String[] existingPodIpRanges = pod.getDescription().split(",");
-
-            for(String podIpRange: existingPodIpRanges) {
-                final String[] existingPodIpRange = podIpRange.split("-");
-
-                startIp.add(((existingPodIpRange.length > 0) && (existingPodIpRange[0] != null)) ? existingPodIpRange[0] : "");
-                endIp.add(((existingPodIpRange.length > 1) && (existingPodIpRange[1] != null)) ? existingPodIpRange[1] : "");
-                forSystemVms.add((existingPodIpRange.length > 2) && (existingPodIpRange[2] != null) ? existingPodIpRange[2] : "0");
-                vlanIds.add((existingPodIpRange.length > 3) &&
-                        (existingPodIpRange[3] != null && !existingPodIpRange.equals("untagged")) ?
-                        BroadcastDomainType.Vlan.toUri(existingPodIpRange[3]).toString() :
-                        BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString());
-            }
-        }
-
-        PodResponse podResponse = new PodResponse();
-        podResponse.setId(pod.getUuid());
-        podResponse.setName(pod.getName());
-        DataCenter zone = ApiDBUtils.findZoneById(pod.getDataCenterId());
-        if (zone != null) {
-            podResponse.setZoneId(zone.getUuid());
-            podResponse.setZoneName(zone.getName());
-        }
-        podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize()));
-        podResponse.setStartIp(startIp);
-        podResponse.setEndIp(endIp);
-        podResponse.setForSystemVms(forSystemVms);
-        podResponse.setVlanId(vlanIds);
-        podResponse.setGateway(pod.getGateway());
-        podResponse.setAllocationState(pod.getAllocationState().toString());
-        if (showCapacities != null && showCapacities) {
-            List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, pod.getId(), null);
-            Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
-            for (SummedCapacity capacity : capacities) {
-                CapacityResponse capacityResponse = new CapacityResponse();
-                capacityResponse.setCapacityType(capacity.getCapacityType());
-                capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
-                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
-                if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
-                    List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null);
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
-                    capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
-                } else {
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
-                }
-                if (capacityResponse.getCapacityTotal() != 0) {
-                    capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
-                } else {
-                    capacityResponse.setPercentUsed(s_percentFormat.format(0L));
-                }
-                capacityResponses.add(capacityResponse);
-            }
-            // Do it for stats as well.
-            capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId()));
-            podResponse.setCapacitites(new ArrayList<CapacityResponse>(capacityResponses));
-        }
-        podResponse.setObjectName("pod");
-        return podResponse;
-    }
-
-    @Override
-    public ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities) {
-        DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter);
-        return ApiDBUtils.newDataCenterResponse(view, vOffering, showCapacities);
-    }
-
-    public static List<CapacityResponse> getDataCenterCapacityResponse(Long zoneId) {
-        List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null);
-        Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
-
-        for (SummedCapacity capacity : capacities) {
-            CapacityResponse capacityResponse = new CapacityResponse();
-            capacityResponse.setCapacityType(capacity.getCapacityType());
-            capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
-            capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
-            if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
-                List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null);
-                capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
-                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
-            } else {
-                capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
-            }
-            if (capacityResponse.getCapacityTotal() != 0) {
-                capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
-            } else {
-                capacityResponse.setPercentUsed(s_percentFormat.format(0L));
-            }
-            capacityResponses.add(capacityResponse);
-        }
-        // Do it for stats as well.
-        capacityResponses.addAll(getStatsCapacityresponse(null, null, null, zoneId));
-
-        return new ArrayList<CapacityResponse>(capacityResponses);
-    }
-
-    private static List<CapacityResponse> getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) {
-        List<CapacityVO> capacities = new ArrayList<CapacityVO>();
-        capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId));
-        if (clusterId == null && podId == null) {
-            capacities.add(ApiDBUtils.getSecondaryStorageUsedStats(poolId, zoneId));
-        }
-
-        List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
-        for (CapacityVO capacity : capacities) {
-            CapacityResponse capacityResponse = new CapacityResponse();
-            capacityResponse.setCapacityType(capacity.getCapacityType());
-            capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
-            capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
-            capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
-            if (capacityResponse.getCapacityTotal() != 0) {
-                capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
-            } else {
-                capacityResponse.setPercentUsed(s_percentFormat.format(0L));
-            }
-            capacityResponses.add(capacityResponse);
-        }
-
-        return capacityResponses;
-    }
-
-    @Override
-    public VolumeResponse createVolumeResponse(ResponseView view, Volume volume) {
-        List<VolumeJoinVO> viewVrs = ApiDBUtils.newVolumeView(volume);
-        List<VolumeResponse> listVrs = ViewResponseHelper.createVolumeResponse(view, viewVrs.toArray(new VolumeJoinVO[viewVrs.size()]));
-        assert listVrs != null && listVrs.size() == 1 : "There should be one volume returned";
-        return listVrs.get(0);
-    }
-
-    @Override
-    public InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group) {
-        InstanceGroupJoinVO vgroup = ApiDBUtils.newInstanceGroupView(group);
-        return ApiDBUtils.newInstanceGroupResponse(vgroup);
-
-    }
-
-    @Override
-    public StoragePoolResponse createStoragePoolResponse(StoragePool pool) {
-        List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
-        List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
-        assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
-        return listPools.get(0);
-    }
-
-    @Override
-    public ImageStoreResponse createImageStoreResponse(ImageStore os) {
-        List<ImageStoreJoinVO> viewStores = ApiDBUtils.newImageStoreView(os);
-        List<ImageStoreResponse> listStores = ViewResponseHelper.createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()]));
-        assert listStores != null && listStores.size() == 1 : "There should be one image data store returned";
-        return listStores.get(0);
-    }
-
-    @Override
-    public StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool) {
-        List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
-        List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolForMigrationResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
-        assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
-        return listPools.get(0);
-    }
-
-    @Override
-    public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) {
-        ClusterResponse clusterResponse = new ClusterResponse();
-        clusterResponse.setId(cluster.getUuid());
-        clusterResponse.setName(cluster.getName());
-        HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
-        if (pod != null) {
-            clusterResponse.setPodId(pod.getUuid());
-            clusterResponse.setPodName(pod.getName());
-        }
-        DataCenter dc = ApiDBUtils.findZoneById(cluster.getDataCenterId());
-        if (dc != null) {
-            clusterResponse.setZoneId(dc.getUuid());
-            clusterResponse.setZoneName(dc.getName());
-        }
-        clusterResponse.setHypervisorType(cluster.getHypervisorType().toString());
-        clusterResponse.setClusterType(cluster.getClusterType().toString());
-        clusterResponse.setAllocationState(cluster.getAllocationState().toString());
-        clusterResponse.setManagedState(cluster.getManagedState().toString());
-        String cpuOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "cpuOvercommitRatio");
-        String memoryOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "memoryOvercommitRatio");
-        clusterResponse.setCpuOvercommitRatio(cpuOvercommitRatio);
-        clusterResponse.setMemoryOvercommitRatio(memoryOvercommitRatio);
-        clusterResponse.setResourceDetails(_clusterDetailsDao.findDetails(cluster.getId()));
-
-        if (showCapacities != null && showCapacities) {
-            List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId());
-            Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
-
-            for (SummedCapacity capacity : capacities) {
-                CapacityResponse capacityResponse = new CapacityResponse();
-                capacityResponse.setCapacityType(capacity.getCapacityType());
-                capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
-                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
-
-                if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
-                    List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId());
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
-                    capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
-                } else {
-                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
-                }
-                if (capacityResponse.getCapacityTotal() != 0) {
-                    capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
-                } else {
-                    capacityResponse.setPercentUsed(s_percentFormat.format(0L));
-                }
-                capacityResponses.add(capacityResponse);
-            }
-            // Do it for stats as well.
-            capacityResponses.addAll(getStatsCapacityresponse(null, cluster.getId(), pod.getId(), pod.getDataCenterId()));
-            clusterResponse.setCapacitites(new ArrayList<CapacityResponse>(capacityResponses));
-        }
-        clusterResponse.setObjectName("cluster");
-        return clusterResponse;
-    }
-
-    @Override
-    public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule) {
-        FirewallRuleResponse response = new FirewallRuleResponse();
-        response.setId(fwRule.getUuid());
-        response.setPrivateStartPort(Integer.toString(fwRule.getDestinationPortStart()));
-        response.setPrivateEndPort(Integer.toString(fwRule.getDestinationPortEnd()));
-        response.setProtocol(fwRule.getProtocol());
-        response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart()));
-        response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd()));
-        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
-        response.setCidrList(StringUtils.join(cidrs, ","));
-
-        Network guestNtwk = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
-        response.setNetworkId(guestNtwk.getUuid());
-
-
-        IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
-
-        if (ip != null)
-        {
-            response.setPublicIpAddressId(ip.getUuid());
-            response.setPublicIpAddress(ip.getAddress().addr());
-            if (fwRule.getDestinationIpAddress() != null)
-            {
-                response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString());
-                UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId());
-                if (vm != null) {
-                    response.setVirtualMachineId(vm.getUuid());
-                    response.setVirtualMachineName(vm.getHostName());
-
-                    if (vm.getDisplayName() != null) {
-                        response.setVirtualMachineDisplayName(vm.getDisplayName());
-                    } else {
-                        response.setVirtualMachineDisplayName(vm.getHostName());
-                    }
-                }
-            }
-        }
-        FirewallRule.State state = fwRule.getState();
-        String stateToSet = state.toString();
-        if (state.equals(FirewallRule.State.Revoke)) {
-            stateToSet = "Deleting";
-        }
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PortForwardingRule, fwRule.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        response.setTags(tagResponses);
-
-        response.setState(stateToSet);
-        response.setForDisplay(fwRule.isDisplay());
-        response.setObjectName("portforwardingrule");
-        return response;
-    }
-
-    @Override
-    public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule) {
-        IpForwardingRuleResponse response = new IpForwardingRuleResponse();
-        response.setId(fwRule.getUuid());
-        response.setProtocol(fwRule.getProtocol());
-
-        IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
-
-        if (ip != null) {
-            response.setPublicIpAddressId(ip.getId());
-            response.setPublicIpAddress(ip.getAddress().addr());
-            if (fwRule.getDestIpAddress() != null) {
-                UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId());
-                if (vm != null) {// vm might be destroyed
-                    response.setVirtualMachineId(vm.getUuid());
-                    response.setVirtualMachineName(vm.getHostName());
-                    if (vm.getDisplayName() != null) {
-                        response.setVirtualMachineDisplayName(vm.getDisplayName());
-                    } else {
-                        response.setVirtualMachineDisplayName(vm.getHostName());
-                    }
-                }
-            }
-        }
-        FirewallRule.State state = fwRule.getState();
-        String stateToSet = state.toString();
-        if (state.equals(FirewallRule.State.Revoke)) {
-            stateToSet = "Deleting";
-        }
-
-        response.setStartPort(fwRule.getSourcePortStart());
-        response.setEndPort(fwRule.getSourcePortEnd());
-        response.setProtocol(fwRule.getProtocol());
-        response.setState(stateToSet);
-        response.setObjectName("ipforwardingrule");
-        return response;
-    }
-
-    /*
-    @Override
-    public List<UserVmResponse> createUserVmResponse(String objectName, UserVm... userVms) {
-        return createUserVmResponse(null, objectName, userVms);
-    }
-
-    @Override
-    public List<UserVmResponse> createUserVmResponse(String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
-        return createUserVmResponse(null, objectName, userVms);
-    }
-    */
-
-    @Override
-    public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
-        List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
-        return ViewResponseHelper.createUserVmResponse(view, objectName, details, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
-
-    }
-
-    @Override
-    public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms) {
-        List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
-        return ViewResponseHelper.createUserVmResponse(view, objectName, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
-    }
-
-    @Override
-    public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) {
-        List<DomainRouterJoinVO> viewVrs = ApiDBUtils.newDomainRouterView(router);
-        List<DomainRouterResponse> listVrs = ViewResponseHelper.createDomainRouterResponse(viewVrs.toArray(new DomainRouterJoinVO[viewVrs.size()]));
-        assert listVrs != null && listVrs.size() == 1 : "There should be one virtual router returned";
-        return listVrs.get(0);
-    }
-
-    @Override
-    public SystemVmResponse createSystemVmResponse(VirtualMachine vm) {
-        SystemVmResponse vmResponse = new SystemVmResponse();
-        if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter || vm.getType() == Type.NetScalerVm) {
-            vmResponse.setId(vm.getUuid());
-            vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
-            vmResponse.setName(vm.getHostName());
-
-            if (vm.getPodIdToDeployIn() != null) {
-                HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn());
-                if (pod != null) {
-                    vmResponse.setPodId(pod.getUuid());
-                }
-            }
-            VMTemplateVO template = ApiDBUtils.findTemplateById(vm.getTemplateId());
-            if (template != null) {
-                vmResponse.setTemplateId(template.getUuid());
-            }
-            vmResponse.setCreated(vm.getCreated());
-
-            if (vm.getHostId() != null) {
-                Host host = ApiDBUtils.findHostById(vm.getHostId());
-                if (host != null) {
-                    vmResponse.setHostId(host.getUuid());
-                    vmResponse.setHostName(host.getName());
-                    vmResponse.setHypervisor(host.getHypervisorType().toString());
-                }
-            }
-
-            if (vm.getState() != null) {
-                vmResponse.setState(vm.getState().toString());
-            }
-
-            // for console proxies, add the active sessions
-            if (vm.getType() == Type.ConsoleProxy) {
-                ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId());
-                // proxy can be already destroyed
-                if (proxy != null) {
-                    vmResponse.setActiveViewerSessions(proxy.getActiveSession());
-                }
-            }
-
-            DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterId());
-            if (zone != null) {
-                vmResponse.setZoneId(zone.getUuid());
-                vmResponse.setZoneName(zone.getName());
-                vmResponse.setDns1(zone.getDns1());
-                vmResponse.setDns2(zone.getDns2());
-            }
-
-            List<NicProfile> nicProfiles = ApiDBUtils.getNics(vm);
-            for (NicProfile singleNicProfile : nicProfiles) {
-                Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId());
-                if (network != null) {
-                    if (network.getTrafficType() == TrafficType.Management) {
-                        vmResponse.setPrivateIp(singleNicProfile.getIPv4Address());
-                        vmResponse.setPrivateMacAddress(singleNicProfile.getMacAddress());
-                        vmResponse.setPrivateNetmask(singleNicProfile.getIPv4Netmask());
-                    } else if (network.getTrafficType() == TrafficType.Control) {
-                        vmResponse.setLinkLocalIp(singleNicProfile.getIPv4Address());
-                        vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress());
-                        vmResponse.setLinkLocalNetmask(singleNicProfile.getIPv4Netmask());
-                    } else if (network.getTrafficType() == TrafficType.Public) {
-                        vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
-                        vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
-                        vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
-                        vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
-                    } else if (network.getTrafficType() == TrafficType.Guest) {
-                        /*
-                          * In basic zone, public ip has TrafficType.Guest in case EIP service is not enabled.
-                          * When EIP service is enabled in the basic zone, system VM by default get the public
-                          * IP allocated for EIP. So return the guest/public IP accordingly.
-                          * */
-                        NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
-                        if (networkOffering.getElasticIp()) {
-                            IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(vm.getId());
-                            if (ip != null) {
-                                Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId());
-                                vmResponse.setPublicIp(ip.getAddress().addr());
-                                vmResponse.setPublicNetmask(vlan.getVlanNetmask());
-                                vmResponse.setGateway(vlan.getVlanGateway());
-                            }
-                        } else {
-                            vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
-                            vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
-                            vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
-                            vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
-                        }
-                    }
-                }
-            }
-        }
-        vmResponse.setObjectName("systemvm");
-        return vmResponse;
-    }
-
-    @Override
-    public Host findHostById(Long hostId) {
-        return ApiDBUtils.findHostById(hostId);
-    }
-
-    @Override
-    public User findUserById(Long userId) {
-        return ApiDBUtils.findUserById(userId);
-    }
-
-    @Override
-    public UserVm findUserVmById(Long vmId) {
-        return ApiDBUtils.findUserVmById(vmId);
-
-    }
-
-    @Override
-    public VolumeVO findVolumeById(Long volumeId) {
-        return ApiDBUtils.findVolumeById(volumeId);
-    }
-
-
-    @Override
-    public Account findAccountByNameDomain(String accountName, Long domainId) {
-        return ApiDBUtils.findAccountByNameDomain(accountName, domainId);
-    }
-
-    @Override
-    public VirtualMachineTemplate findTemplateById(Long templateId) {
-        return ApiDBUtils.findTemplateById(templateId);
-    }
-
-    @Override
-    public DiskOfferingVO findDiskOfferingById(Long diskOfferingId) {
-        return ApiDBUtils.findDiskOfferingById(diskOfferingId);
-    }
-
-    @Override
-    public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) {
-        VpnUsersResponse vpnResponse = new VpnUsersResponse();
-        vpnResponse.setId(vpnUser.getUuid());
-        vpnResponse.setUserName(vpnUser.getUsername());
-        vpnResponse.setState(vpnUser.getState().toString());
-
-        populateOwner(vpnResponse, vpnUser);
-
-        vpnResponse.setObjectName("vpnuser");
-        return vpnResponse;
-    }
-
-    @Override
-    public RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn) {
-        RemoteAccessVpnResponse vpnResponse = new RemoteAccessVpnResponse();
-        IpAddress ip = ApiDBUtils.findIpAddressById(vpn.getServerAddressId());
-        if (ip != null) {
-            vpnResponse.setPublicIpId(ip.getUuid());
-            vpnResponse.setPublicIp(ip.getAddress().addr());
-        }
-        vpnResponse.setIpRange(vpn.getIpRange());
-        vpnResponse.setPresharedKey(vpn.getIpsecPresharedKey());
-        populateOwner(vpnResponse, vpn);
-        vpnResponse.setState(vpn.getState().toString());
-        vpnResponse.setId(vpn.getUuid());
-        vpnResponse.setForDisplay(vpn.isDisplay());
-        vpnResponse.setObjectName("remoteaccessvpn");
-
-        return vpnResponse;
-    }
-
-    @Override
-    public TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result) {
-        List<TemplateJoinVO> tvo = ApiDBUtils.newTemplateView(result);
-        List<TemplateResponse> listVrs = ViewResponseHelper.createTemplateUpdateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
-        assert listVrs != null && listVrs.size() == 1 : "There should be one template returned";
-        return listVrs.get(0);
-    }
-
-    @Override
-    public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
-        List<TemplateJoinVO> tvo = null;
-        if (zoneId == null || zoneId == -1 || result.isCrossZones()) {
-            tvo = ApiDBUtils.newTemplateView(result);
-        } else {
-            tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
-
-        }
-        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
-    }
-
-    @Override
-    public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
-                                                          List<Long> zoneIds, boolean readyOnly) {
-        List<TemplateJoinVO> tvo = null;
-        if (zoneIds == null) {
-            return createTemplateResponses(view, result, (Long)null, readyOnly);
-        } else {
-            for (Long zoneId: zoneIds){
-                if (tvo == null)
-                    tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
-                else
-                    tvo.addAll(ApiDBUtils.newTemplateView(result, zoneId, readyOnly));
-            }
-        }
-        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
-    }
-
-    @Override
-    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly) {
-        VirtualMachineTemplate template = findTemplateById(templateId);
-        return createTemplateResponses(view, template, zoneId, readyOnly);
-    }
-
-    @Override
-    public List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
-        List<TemplateJoinVO> tvo = null;
-        if (zoneId == null || zoneId == -1) {
-            tvo = ApiDBUtils.newTemplateView(result);
-        } else {
-            tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
-        }
-
-        return ViewResponseHelper.createIsoResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
-    }
-
-    @Override
-    public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) {
-        List<SecurityGroupJoinVO> viewSgs = ApiDBUtils.newSecurityGroupView(group);
-        List<SecurityGroupResponse> listSgs = ViewResponseHelper.createSecurityGroupResponses(viewSgs);
-        assert listSgs != null && listSgs.size() == 1 : "There should be one security group returned";
-        return listSgs.get(0);
-    }
-
-    //TODO: we need to deprecate uploadVO, since extract is done in a synchronous fashion
-    @Override
-    public ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
-
-        ExtractResponse response = new ExtractResponse();
-        response.setObjectName("template");
-        VMTemplateVO template = ApiDBUtils.findTemplateById(id);
-        response.setId(template.getUuid());
-        response.setName(template.getName());
-        if (zoneId != null) {
-            DataCenter zone = ApiDBUtils.findZoneById(zoneId);
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-        }
-        response.setMode(mode);
-        response.setUrl(url);
-        response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
-        Account account = ApiDBUtils.findAccountById(accountId);
-        response.setAccountId(account.getUuid());
-
-        return response;
-    }
-
-    @Override
-    public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
-
-        ExtractResponse response = new ExtractResponse();
-        response.setObjectName("template");
-        VMTemplateVO template = ApiDBUtils.findTemplateById(id);
-        response.setId(template.getUuid());
-        response.setName(template.getName());
-        if (zoneId != null) {
-            DataCenter zone = ApiDBUtils.findZoneById(zoneId);
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-        }
-        response.setMode(mode);
-        if (uploadId == null) {
-            // region-wide image store
-            response.setUrl(url);
-            response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
-        } else {
-            UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId);
-            response.setUploadId(uploadInfo.getUuid());
-            response.setState(uploadInfo.getUploadState().toString());
-            response.setUrl(uploadInfo.getUploadUrl());
-        }
-        Account account = ApiDBUtils.findAccountById(accountId);
-        response.setAccountId(account.getUuid());
-
-        return response;
-
-    }
-
-    @Override
-    public String toSerializedString(CreateCmdResponse response, String responseType) {
-        return ApiResponseSerializer.toSerializedString(response, responseType);
-    }
-
-    @Override
-    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly) {
-        Long zoneId = null;
-
-        if (snapshotId != null) {
-            Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId);
-            VolumeVO volume = findVolumeById(snapshot.getVolumeId());
-
-            // it seems that the volume can actually be removed from the DB at some point if it's deleted
-            // if volume comes back null, use another technique to try to discover the zone
-            if (volume == null) {
-                SnapshotDataStoreVO snapshotStore = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
-
-                if (snapshotStore != null) {
-                    long storagePoolId = snapshotStore.getDataStoreId();
-
-                    StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
-
-                    if (storagePool != null) {
-                        zoneId = storagePool.getDataCenterId();
-                    }
-                }
-            }
-            else {
-                zoneId = volume.getDataCenterId();
-            }
-        } else {
-            VolumeVO volume = findVolumeById(volumeId);
-
-            zoneId = volume.getDataCenterId();
-        }
-
-        if (zoneId == null) {
-            throw new CloudRuntimeException("Unable to determine the zone ID");
-        }
-
-        return createTemplateResponses(view, templateId, zoneId, readyOnly);
-    }
-
-    @Override
-    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long vmId) {
-        UserVm vm = findUserVmById(vmId);
-        Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId());
-        Host host = findHostById(hostId);
-        return createTemplateResponses(view, templateId, host.getDataCenterId(), true);
-    }
-
-    @Override
-    public EventResponse createEventResponse(Event event) {
-        EventJoinVO vEvent = ApiDBUtils.newEventView(event);
-        return ApiDBUtils.newEventResponse(vEvent);
-    }
-
-    @Override
-    public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
-        List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
-
-        for (Capacity summedCapacity : result) {
-            CapacityResponse capacityResponse = new CapacityResponse();
-            capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity());
-            if (summedCapacity.getAllocatedCapacity() != null) {
-                capacityResponse.setCapacityAllocated(summedCapacity.getAllocatedCapacity());
-            }
-            capacityResponse.setCapacityType(summedCapacity.getCapacityType());
-            capacityResponse.setCapacityName(CapacityVO.getCapacityName(summedCapacity.getCapacityType()));
-            capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity());
-            if (summedCapacity.getPodId() != null) {
-                capacityResponse.setPodId(ApiDBUtils.findPodById(summedCapacity.getPodId()).getUuid());
-                HostPodVO pod = ApiDBUtils.findPodById(summedCapacity.getPodId());
-                if (pod != null) {
-                    capacityResponse.setPodId(pod.getUuid());
-                    capacityResponse.setPodName(pod.getName());
-                }
-            }
-            if (summedCapacity.getClusterId() != null) {
-                ClusterVO cluster = ApiDBUtils.findClusterById(summedCapacity.getClusterId());
-                if (cluster != null) {
-                    capacityResponse.setClusterId(cluster.getUuid());
-                    capacityResponse.setClusterName(cluster.getName());
-                    if (summedCapacity.getPodId() == null) {
-                        HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
-                        capacityResponse.setPodId(pod.getUuid());
-                        capacityResponse.setPodName(pod.getName());
-                    }
-                }
-            }
-            DataCenter zone = ApiDBUtils.findZoneById(summedCapacity.getDataCenterId());
-            if (zone != null) {
-                capacityResponse.setZoneId(zone.getUuid());
-                capacityResponse.setZoneName(zone.getName());
-            }
-            if (summedCapacity.getUsedPercentage() != null) {
-                capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f));
-            } else if (summedCapacity.getTotalCapacity() != 0) {
-                capacityResponse.setPercentUsed(format.format((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f));
-            } else {
-                capacityResponse.setPercentUsed(format.format(0L));
-            }
-
-            capacityResponse.setObjectName("capacity");
-            capacityResponses.add(capacityResponse);
-        }
-
-        List<VgpuTypesInfo> gpuCapacities;
-        if (result.size() > 1 && (gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId())) != null) {
-            HashMap<String, Long> vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId());
-
-            float capacityUsed = 0;
-            long capacityMax = 0;
-            for (VgpuTypesInfo capacity : gpuCapacities) {
-                if (vgpuVMs.containsKey(capacity.getGroupName().concat(capacity.getModelName()))) {
-                    capacityUsed += (float)vgpuVMs.get(capacity.getGroupName().concat(capacity.getModelName())) / capacity.getMaxVpuPerGpu();
-                }
-                if (capacity.getModelName().equals(GPU.GPUType.passthrough.toString())) {
-                    capacityMax += capacity.getMaxCapacity();
-                }
-            }
-
-            DataCenter zone = ApiDBUtils.findZoneById(result.get(0).getDataCenterId());
-            CapacityResponse capacityResponse = new CapacityResponse();
-            if (zone != null) {
-                capacityResponse.setZoneId(zone.getUuid());
-                capacityResponse.setZoneName(zone.getName());
-            }
-            if (result.get(0).getPodId() != null) {
-                HostPodVO pod = ApiDBUtils.findPodById(result.get(0).getPodId());
-                capacityResponse.setPodId(pod.getUuid());
-                capacityResponse.setPodName(pod.getName());
-            }
-            if (result.get(0).getClusterId() != null) {
-                ClusterVO cluster = ApiDBUtils.findClusterById(result.get(0).getClusterId());
-                capacityResponse.setClusterId(cluster.getUuid());
-                capacityResponse.setClusterName(cluster.getName());
-            }
-            capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU);
-            capacityResponse.setCapacityName(CapacityVO.getCapacityName(Capacity.CAPACITY_TYPE_GPU));
-            capacityResponse.setCapacityUsed((long)Math.ceil(capacityUsed));
-            capacityResponse.setCapacityTotal(capacityMax);
-            if (capacityMax > 0) {
-                capacityResponse.setPercentUsed(format.format(capacityUsed / capacityMax * 100f));
-            } else {
-                capacityResponse.setPercentUsed(format.format(0));
-            }
-            capacityResponse.setObjectName("capacity");
-            capacityResponses.add(capacityResponse);
-        }
-        return capacityResponses;
-    }
-
-    @Override
-    public TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id) {
-        Long templateOwnerDomain = null;
-        VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id);
-        Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId());
-        if (view == ResponseView.Full) {
-            // FIXME: we have just template id and need to get template owner
-            // from that
-            if (templateOwner != null) {
-                templateOwnerDomain = templateOwner.getDomainId();
-            }
-        }
-
-        TemplatePermissionsResponse response = new TemplatePermissionsResponse();
-        response.setId(template.getUuid());
-        response.setPublicTemplate(template.isPublicTemplate());
-        if ((view == ResponseView.Full) && (templateOwnerDomain != null)) {
-            Domain domain = ApiDBUtils.findDomainById(templateOwnerDomain);
-            if (domain != null) {
-                response.setDomainId(domain.getUuid());
-            }
-        }
-
-        // Set accounts
-        List<String> projectIds = new ArrayList<String>();
-        List<String> regularAccounts = new ArrayList<String>();
-        for (String accountName : accountNames) {
-            Account account = ApiDBUtils.findAccountByNameDomain(accountName, templateOwner.getDomainId());
-            if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
-                regularAccounts.add(accountName);
-            } else {
-                // convert account to projectIds
-                Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
-
-                if (project.getUuid() != null && !project.getUuid().isEmpty()) {
-                    projectIds.add(project.getUuid());
-                } else {
-                    projectIds.add(String.valueOf(project.getId()));
-                }
-            }
-        }
-
-        if (!projectIds.isEmpty()) {
-            response.setProjectIds(projectIds);
-        }
-
-        if (!regularAccounts.isEmpty()) {
-            response.setAccountNames(regularAccounts);
-        }
-
-        response.setObjectName("templatepermission");
-        return response;
-    }
-
-    @Override
-    public AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        AsyncJob job = _entityMgr.findById(AsyncJob.class, cmd.getId());
-        if (job == null) {
-            throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
-        }
-
-        User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
-        Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
-
-        //check permissions
-        if (_accountMgr.isNormalUser(caller.getId())) {
-            //regular user can see only jobs he owns
-            if (caller.getId() != jobOwner.getId()) {
-                throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
-            }
-        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
-            _accountMgr.checkAccess(caller, null, true, jobOwner);
-        }
-
-        return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true));
-    }
-
-    public AsyncJobResponse createAsyncJobResponse(AsyncJob job) {
-        AsyncJobJoinVO vJob = ApiDBUtils.newAsyncJobView(job);
-        return ApiDBUtils.newAsyncJobResponse(vJob);
-    }
-
-    @Override
-    public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules) {
-        SecurityGroupResponse response = new SecurityGroupResponse();
-        Map<Long, Account> securiytGroupAccounts = new HashMap<Long, Account>();
-
-        if ((securityRules != null) && !securityRules.isEmpty()) {
-            SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0);
-            response.setId(securityGroup.getUuid());
-            response.setName(securityGroup.getName());
-            response.setDescription(securityGroup.getDescription());
-
-            Account account = securiytGroupAccounts.get(securityGroup.getAccountId());
-
-            if (securityGroup.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
-                response.setProjectId(securityGroup.getProjectUuid());
-                response.setProjectName(securityGroup.getProjectName());
-            } else {
-                response.setAccountName(securityGroup.getAccountName());
-            }
-
-            response.setDomainId(securityGroup.getDomainUuid());
-            response.setDomainName(securityGroup.getDomainName());
-
-            for (SecurityRule securityRule : securityRules) {
-                SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse();
-
-                securityGroupData.setRuleId(securityRule.getUuid());
-                securityGroupData.setProtocol(securityRule.getProtocol());
-                if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) {
-                    securityGroupData.setIcmpType(securityRule.getStartPort());
-                    securityGroupData.setIcmpCode(securityRule.getEndPort());
-                } else {
-                    securityGroupData.setStartPort(securityRule.getStartPort());
-                    securityGroupData.setEndPort(securityRule.getEndPort());
-                }
-
-                Long allowedSecurityGroupId = securityRule.getAllowedNetworkId();
-                if (allowedSecurityGroupId != null) {
-                    List<SecurityGroupJoinVO> sgs = ApiDBUtils.findSecurityGroupViewById(allowedSecurityGroupId);
-                    if (sgs != null && sgs.size() > 0) {
-                        SecurityGroupJoinVO sg = sgs.get(0);
-                        securityGroupData.setSecurityGroupName(sg.getName());
-                        securityGroupData.setAccountName(sg.getAccountName());
-                    }
-                } else {
-                    securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr());
-                }
-                if (securityRule.getRuleType() == SecurityRuleType.IngressRule) {
-                    securityGroupData.setObjectName("ingressrule");
-                    response.addSecurityGroupIngressRule(securityGroupData);
-                } else {
-                    securityGroupData.setObjectName("egressrule");
-                    response.addSecurityGroupEgressRule(securityGroupData);
-                }
-
-            }
-            response.setObjectName("securitygroup");
-
-        }
-        return response;
-    }
-
-    @Override
-    public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) {
-        NetworkOfferingResponse response = new NetworkOfferingResponse();
-        response.setId(offering.getUuid());
-        response.setName(offering.getName());
-        response.setDisplayText(offering.getDisplayText());
-        response.setTags(offering.getTags());
-        response.setTrafficType(offering.getTrafficType().toString());
-        response.setIsDefault(offering.isDefault());
-        response.setSpecifyVlan(offering.getSpecifyVlan());
-        response.setConserveMode(offering.isConserveMode());
-        response.setSpecifyIpRanges(offering.getSpecifyIpRanges());
-        response.setAvailability(offering.getAvailability().toString());
-        response.setIsPersistent(offering.getIsPersistent());
-        response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
-        response.setEgressDefaultPolicy(offering.getEgressDefaultPolicy());
-        response.setConcurrentConnections(offering.getConcurrentConnections());
-        response.setSupportsStrechedL2Subnet(offering.getSupportsStrechedL2());
-        response.setSupportsPublicAccess(offering.getSupportsPublicAccess());
-        Long so = null;
-        if (offering.getServiceOfferingId() != null) {
-            so = offering.getServiceOfferingId();
-        } else {
-            so = ApiDBUtils.findDefaultRouterServiceOffering();
-        }
-        if (so != null) {
-            ServiceOffering soffering = ApiDBUtils.findServiceOfferingById(so);
-            if (soffering != null) {
-                response.setServiceOfferingId(soffering.getUuid());
-            }
-        }
-
-        if (offering.getGuestType() != null) {
-            response.setGuestIpType(offering.getGuestType().toString());
-        }
-
-        response.setState(offering.getState().name());
-
-        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId());
-        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
-        for (Map.Entry<Service,Set<Provider>> entry : serviceProviderMap.entrySet()) {
-            Service service = entry.getKey();
-            Set<Provider> srvc_providers = entry.getValue();
-            ServiceResponse svcRsp = new ServiceResponse();
-            // skip gateway service
-            if (service == Service.Gateway) {
-                continue;
-            }
-            svcRsp.setName(service.getName());
-            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
-            for (Provider provider : srvc_providers) {
-                if (provider != null) {
-                    ProviderResponse providerRsp = new ProviderResponse();
-                    providerRsp.setName(provider.getName());
-                    providers.add(providerRsp);
-                }
-            }
-            svcRsp.setProviders(providers);
-
-            if (Service.Lb == service) {
-                List<CapabilityResponse> lbCapResponse = new ArrayList<CapabilityResponse>();
-
-                CapabilityResponse lbIsoaltion = new CapabilityResponse();
-                lbIsoaltion.setName(Capability.SupportedLBIsolation.getName());
-                lbIsoaltion.setValue(offering.getDedicatedLB() ? "dedicated" : "shared");
-                lbCapResponse.add(lbIsoaltion);
-
-                CapabilityResponse eLb = new CapabilityResponse();
-                eLb.setName(Capability.ElasticLb.getName());
-                eLb.setValue(offering.getElasticLb() ? "true" : "false");
-                lbCapResponse.add(eLb);
-
-                CapabilityResponse inline = new CapabilityResponse();
-                inline.setName(Capability.InlineMode.getName());
-                inline.setValue(offering.isInline() ? "true" : "false");
-                lbCapResponse.add(inline);
-
-                svcRsp.setCapabilities(lbCapResponse);
-            } else if (Service.SourceNat == service) {
-                List<CapabilityResponse> capabilities = new ArrayList<CapabilityResponse>();
-                CapabilityResponse sharedSourceNat = new CapabilityResponse();
-                sharedSourceNat.setName(Capability.SupportedSourceNatTypes.getName());
-                sharedSourceNat.setValue(offering.getSharedSourceNat() ? "perzone" : "peraccount");
-                capabilities.add(sharedSourceNat);
-
-                CapabilityResponse redundantRouter = new CapabilityResponse();
-                redundantRouter.setName(Capability.RedundantRouter.getName());
-                redundantRouter.setValue(offering.getRedundantRouter() ? "true" : "false");
-                capabilities.add(redundantRouter);
-
-                svcRsp.setCapabilities(capabilities);
-            } else if (service == Service.StaticNat) {
-                List<CapabilityResponse> staticNatCapResponse = new ArrayList<CapabilityResponse>();
-
-                CapabilityResponse eIp = new CapabilityResponse();
-                eIp.setName(Capability.ElasticIp.getName());
-                eIp.setValue(offering.getElasticIp() ? "true" : "false");
-                staticNatCapResponse.add(eIp);
-
-                CapabilityResponse associatePublicIp = new CapabilityResponse();
-                associatePublicIp.setName(Capability.AssociatePublicIP.getName());
-                associatePublicIp.setValue(offering.getAssociatePublicIP() ? "true" : "false");
-                staticNatCapResponse.add(associatePublicIp);
-
-                svcRsp.setCapabilities(staticNatCapResponse);
-            }
-
-            serviceResponses.add(svcRsp);
-        }
-        response.setForVpc(_configMgr.isOfferingForVpc(offering));
-
-        response.setServices(serviceResponses);
-
-        //set network offering details
-        Map<Detail, String> details = _ntwkModel.getNtwkOffDetails(offering.getId());
-        if (details != null && !details.isEmpty()) {
-            response.setDetails(details);
-        }
-
-        response.setObjectName("networkoffering");
-        return response;
-    }
-
-    @Override
-    public NetworkResponse createNetworkResponse(ResponseView view, Network network) {
-        // need to get network profile in order to retrieve dns information from
-        // there
-        NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId());
-        NetworkResponse response = new NetworkResponse();
-        response.setId(network.getUuid());
-        response.setName(network.getName());
-        response.setDisplaytext(network.getDisplayText());
-        if (network.getBroadcastDomainType() != null) {
-            response.setBroadcastDomainType(network.getBroadcastDomainType().toString());
-        }
-
-        if (network.getTrafficType() != null) {
-            response.setTrafficType(network.getTrafficType().name());
-        }
-
-        if (network.getGuestType() != null) {
-            response.setType(network.getGuestType().toString());
-        }
-
-        response.setGateway(network.getGateway());
-
-        // FIXME - either set netmask or cidr
-        response.setCidr(network.getCidr());
-        if (network.getNetworkCidr() != null) {
-            response.setNetworkCidr((network.getNetworkCidr()));
-        }
-        // If network has reservation its entire network cidr is defined by
-        // getNetworkCidr()
-        // if no reservation is present then getCidr() will define the entire
-        // network cidr
-        if (network.getNetworkCidr() != null) {
-            response.setNetmask(NetUtils.cidr2Netmask(network.getNetworkCidr()));
-        }
-        if (((network.getCidr()) != null) && (network.getNetworkCidr() == null)) {
-            response.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
-        }
-
-        response.setIp6Gateway(network.getIp6Gateway());
-        response.setIp6Cidr(network.getIp6Cidr());
-
-        // create response for reserved IP ranges that can be used for
-        // non-cloudstack purposes
-        String reservation = null;
-        if ((network.getCidr() != null) && (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr()))) {
-            String[] guestVmCidrPair = network.getCidr().split("\\/");
-            String[] guestCidrPair = network.getNetworkCidr().split("\\/");
-
-            Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]);
-            Long guestCidrSize = Long.valueOf(guestCidrPair[1]);
-
-            String[] guestVmIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], guestVmCidrSize);
-            String[] guestIpRange = NetUtils.getIpRangeFromCidr(guestCidrPair[0], guestCidrSize);
-            long startGuestIp = NetUtils.ip2Long(guestIpRange[0]);
-            long endGuestIp = NetUtils.ip2Long(guestIpRange[1]);
-            long startVmIp = NetUtils.ip2Long(guestVmIpRange[0]);
-            long endVmIp = NetUtils.ip2Long(guestVmIpRange[1]);
-
-            if (startVmIp == startGuestIp && endVmIp < endGuestIp - 1) {
-                reservation = (NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
-            }
-            if (endVmIp == endGuestIp && startVmIp > startGuestIp + 1) {
-                reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1));
-            }
-            if (startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) {
-                reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " ,  " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
-            }
-        }
-        response.setReservedIpRange(reservation);
-
-        // return vlan information only to Root admin
-        if (network.getBroadcastUri() != null && view == ResponseView.Full) {
-            String broadcastUri = network.getBroadcastUri().toString();
-            response.setBroadcastUri(broadcastUri);
-            String vlan = "N/A";
-            switch (BroadcastDomainType.getSchemeValue(network.getBroadcastUri())) {
-            case Vlan:
-            case Vxlan:
-                vlan = BroadcastDomainType.getValue(network.getBroadcastUri());
-                break;
-            }
-            // return vlan information only to Root admin
-            response.setVlan(vlan);
-        }
-
-        DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId());
-        if (zone != null) {
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-        }
-        if (network.getPhysicalNetworkId() != null) {
-            PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId());
-            response.setPhysicalNetworkId(pnet.getUuid());
-        }
-
-        // populate network offering information
-        NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
-        if (networkOffering != null) {
-            response.setNetworkOfferingId(networkOffering.getUuid());
-            response.setNetworkOfferingName(networkOffering.getName());
-            response.setNetworkOfferingDisplayText(networkOffering.getDisplayText());
-            response.setNetworkOfferingConserveMode(networkOffering.isConserveMode());
-            response.setIsSystem(networkOffering.isSystemOnly());
-            response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString());
-            response.setIsPersistent(networkOffering.getIsPersistent());
-        }
-
-        if (network.getAclType() != null) {
-            response.setAclType(network.getAclType().toString());
-        }
-        response.setDisplayNetwork(network.getDisplayNetwork());
-        response.setState(network.getState().toString());
-        response.setRestartRequired(network.isRestartRequired());
-        NetworkVO nw = ApiDBUtils.findNetworkById(network.getRelated());
-        if (nw != null) {
-            response.setRelated(nw.getUuid());
-        }
-        response.setNetworkDomain(network.getNetworkDomain());
-
-        response.setDns1(profile.getDns1());
-        response.setDns2(profile.getDns2());
-        // populate capability
-        Map<Service, Map<Capability, String>> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId());
-        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
-        if (serviceCapabilitiesMap != null) {
-            for (Map.Entry<Service, Map<Capability, String>>entry : serviceCapabilitiesMap.entrySet()) {
-                Service service = entry.getKey();
-                ServiceResponse serviceResponse = new ServiceResponse();
-                // skip gateway service
-                if (service == Service.Gateway) {
-                    continue;
-                }
-                serviceResponse.setName(service.getName());
-
-                // set list of capabilities for the service
-                List<CapabilityResponse> capabilityResponses = new ArrayList<CapabilityResponse>();
-                Map<Capability, String> serviceCapabilities = entry.getValue();
-                if (serviceCapabilities != null) {
-                    for (Map.Entry<Capability,String> ser_cap_entries : serviceCapabilities.entrySet()) {
-                        Capability capability = ser_cap_entries.getKey();
-                        CapabilityResponse capabilityResponse = new CapabilityResponse();
-                        String capabilityValue = ser_cap_entries.getValue();
-                        capabilityResponse.setName(capability.getName());
-                        capabilityResponse.setValue(capabilityValue);
-                        capabilityResponse.setObjectName("capability");
-                        capabilityResponses.add(capabilityResponse);
-                    }
-                    serviceResponse.setCapabilities(capabilityResponses);
-                }
-
-                serviceResponse.setObjectName("service");
-                serviceResponses.add(serviceResponse);
-            }
-        }
-        response.setServices(serviceResponses);
-
-        if (network.getAclType() == null || network.getAclType() == ACLType.Account) {
-            populateOwner(response, network);
-        } else {
-            // get domain from network_domain table
-            Pair<Long, Boolean> domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId());
-            if (domainNetworkDetails.first() != null) {
-                Domain domain = ApiDBUtils.findDomainById(domainNetworkDetails.first());
-                if (domain != null) {
-                    response.setDomainId(domain.getUuid());
-                }
-            }
-            response.setSubdomainAccess(domainNetworkDetails.second());
-        }
-
-        Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId());
-        if (dedicatedDomainId != null) {
-            Domain domain = ApiDBUtils.findDomainById(dedicatedDomainId);
-            if (domain != null) {
-                response.setDomainId(domain.getUuid());
-                response.setDomainName(domain.getName());
-            }
-
-        }
-
-        response.setSpecifyIpRanges(network.getSpecifyIpRanges());
-        if (network.getVpcId() != null) {
-            Vpc vpc = ApiDBUtils.findVpcById(network.getVpcId());
-            if (vpc != null) {
-                response.setVpcId(vpc.getUuid());
-            }
-        }
-        response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network));
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Network, network.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        response.setTags(tagResponses);
-
-        if (network.getNetworkACLId() != null) {
-            NetworkACL acl = ApiDBUtils.findByNetworkACLId(network.getNetworkACLId());
-            if (acl != null) {
-                response.setAclId(acl.getUuid());
-            }
-        }
-
-        response.setStrechedL2Subnet(network.isStrechedL2Network());
-        if (network.isStrechedL2Network()) {
-            Set<String> networkSpannedZones = new  HashSet<String>();
-            List<VMInstanceVO> vmInstances = new ArrayList<VMInstanceVO>();
-            vmInstances.addAll(ApiDBUtils.listUserVMsByNetworkId(network.getId()));
-            vmInstances.addAll(ApiDBUtils.listDomainRoutersByNetworkId(network.getId()));
-            for (VirtualMachine vm : vmInstances) {
-                DataCenter vmZone = ApiDBUtils.findZoneById(vm.getDataCenterId());
-                networkSpannedZones.add(vmZone.getUuid());
-            }
-            response.setNetworkSpannedZones(networkSpannedZones);
-        }
-        response.setExternalId(network.getExternalId());
-        response.setRedundantRouter(network.isRedundant());
-        response.setObjectName("network");
-        return response;
-    }
-
-    @Override
-    public Long getSecurityGroupId(String groupName, long accountId) {
-        SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId);
-        if (sg == null) {
-            return null;
-        } else {
-            return sg.getId();
-        }
-    }
-
-    @Override
-    public ProjectResponse createProjectResponse(Project project) {
-        List<ProjectJoinVO> viewPrjs = ApiDBUtils.newProjectView(project);
-        List<ProjectResponse> listPrjs = ViewResponseHelper.createProjectResponse(viewPrjs.toArray(new ProjectJoinVO[viewPrjs.size()]));
-        assert listPrjs != null && listPrjs.size() == 1 : "There should be one project  returned";
-        return listPrjs.get(0);
-    }
-
-    @Override
-    public FirewallResponse createFirewallResponse(FirewallRule fwRule) {
-        FirewallResponse response = new FirewallResponse();
-
-        response.setId(fwRule.getUuid());
-        response.setProtocol(fwRule.getProtocol());
-        if (fwRule.getSourcePortStart() != null) {
-            response.setStartPort(fwRule.getSourcePortStart());
-        }
-
-        if (fwRule.getSourcePortEnd() != null) {
-            response.setEndPort(fwRule.getSourcePortEnd());
-        }
-
-        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
-        response.setCidrList(StringUtils.join(cidrs, ","));
-
-        if(fwRule.getTrafficType() == FirewallRule.TrafficType.Egress){
-            List<String> destCidrs = ApiDBUtils.findFirewallDestCidrs(fwRule.getId());
-            response.setDestCidr(StringUtils.join(destCidrs,","));
-        }
-
-        if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) {
-            IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
-            response.setPublicIpAddressId(ip.getUuid());
-            response.setPublicIpAddress(ip.getAddress().addr());
-        }
-
-            Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
-            response.setNetworkId(network.getUuid());
-
-        FirewallRule.State state = fwRule.getState();
-        String stateToSet = state.toString();
-        if (state.equals(FirewallRule.State.Revoke)) {
-            stateToSet = "Deleting";
-        }
-
-        response.setIcmpCode(fwRule.getIcmpCode());
-        response.setIcmpType(fwRule.getIcmpType());
-        response.setForDisplay(fwRule.isDisplay());
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        response.setTags(tagResponses);
-
-        response.setState(stateToSet);
-        response.setObjectName("firewallrule");
-        return response;
-    }
-
-    @Override
-    public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem aclItem) {
-        NetworkACLItemResponse response = new NetworkACLItemResponse();
-
-        response.setId(aclItem.getUuid());
-        response.setProtocol(aclItem.getProtocol());
-        if (aclItem.getSourcePortStart() != null) {
-            response.setStartPort(Integer.toString(aclItem.getSourcePortStart()));
-        }
-
-        if (aclItem.getSourcePortEnd() != null) {
-            response.setEndPort(Integer.toString(aclItem.getSourcePortEnd()));
-        }
-
-        response.setCidrList(StringUtils.join(aclItem.getSourceCidrList(), ","));
-
-        response.setTrafficType(aclItem.getTrafficType().toString());
-
-        NetworkACLItem.State state = aclItem.getState();
-        String stateToSet = state.toString();
-        if (state.equals(NetworkACLItem.State.Revoke)) {
-            stateToSet = "Deleting";
-        }
-
-        response.setIcmpCode(aclItem.getIcmpCode());
-        response.setIcmpType(aclItem.getIcmpType());
-
-        response.setState(stateToSet);
-        response.setNumber(aclItem.getNumber());
-        response.setAction(aclItem.getAction().toString());
-        response.setForDisplay(aclItem.isDisplay());
-
-        NetworkACL acl = ApiDBUtils.findByNetworkACLId(aclItem.getAclId());
-        if (acl != null) {
-            response.setAclId(acl.getUuid());
-        }
-
-        //set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.NetworkACL, aclItem.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        response.setTags(tagResponses);
-
-        response.setObjectName("networkacl");
-        return response;
-    }
-
-    @Override
-    public HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities) {
-        HypervisorCapabilitiesResponse hpvCapabilitiesResponse = new HypervisorCapabilitiesResponse();
-        hpvCapabilitiesResponse.setId(hpvCapabilities.getUuid());
-        hpvCapabilitiesResponse.setHypervisor(hpvCapabilities.getHypervisorType());
-        hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion());
-        hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled());
-        hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit());
-        hpvCapabilitiesResponse.setMaxDataVolumesLimit(hpvCapabilities.getMaxDataVolumesLimit());
-        hpvCapabilitiesResponse.setMaxHostsPerCluster(hpvCapabilities.getMaxHostsPerCluster());
-        hpvCapabilitiesResponse.setIsStorageMotionSupported(hpvCapabilities.isStorageMotionSupported());
-        return hpvCapabilitiesResponse;
-    }
-
-    // TODO: we may need to refactor once ControlledEntityResponse and
-    // ControlledEntity id to uuid conversion are all done.
-    // currently code is scattered in
-    private void populateOwner(ControlledEntityResponse response, ControlledEntity object) {
-        Account account = ApiDBUtils.findAccountById(object.getAccountId());
-
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            // find the project
-            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
-            response.setProjectId(project.getUuid());
-            response.setProjectName(project.getName());
-        } else {
-            response.setAccountName(account.getAccountName());
-        }
-
-        Domain domain = ApiDBUtils.findDomainById(object.getDomainId());
-        response.setDomainId(domain.getUuid());
-        response.setDomainName(domain.getName());
-    }
-
-    public static void populateOwner(ControlledViewEntityResponse response, ControlledViewEntity object) {
-
-        if (object.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
-            response.setProjectId(object.getProjectUuid());
-            response.setProjectName(object.getProjectName());
-        } else {
-            response.setAccountName(object.getAccountName());
-        }
-
-        response.setDomainId(object.getDomainUuid());
-        response.setDomainName(object.getDomainName());
-    }
-
-    private void populateAccount(ControlledEntityResponse response, long accountId) {
-        Account account = ApiDBUtils.findAccountById(accountId);
-        if (account == null) {
-            s_logger.debug("Unable to find account with id: " + accountId);
-        } else if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            // find the project
-            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
-            if (project != null) {
-                response.setProjectId(project.getUuid());
-                response.setProjectName(project.getName());
-                response.setAccountName(account.getAccountName());
-            } else {
-                s_logger.debug("Unable to find project with id: " + account.getId());
-            }
-        } else {
-            response.setAccountName(account.getAccountName());
-        }
-    }
-
-    private void populateDomain(ControlledEntityResponse response, long domainId) {
-        Domain domain = ApiDBUtils.findDomainById(domainId);
-
-        response.setDomainId(domain.getUuid());
-        response.setDomainName(domain.getName());
-    }
-
-    @Override
-    public ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount) {
-        ProjectAccountJoinVO vProj = ApiDBUtils.newProjectAccountView(projectAccount);
-        List<ProjectAccountResponse> listProjs = ViewResponseHelper.createProjectAccountResponse(vProj);
-        assert listProjs != null && listProjs.size() == 1 : "There should be one project account returned";
-        return listProjs.get(0);
-    }
-
-    @Override
-    public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) {
-        ProjectInvitationJoinVO vInvite = ApiDBUtils.newProjectInvitationView(invite);
-        return ApiDBUtils.newProjectInvitationResponse(vInvite);
-    }
-
-    @Override
-    public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) {
-        SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse();
-        vmResponse.setId(vm.getUuid());
-        vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
-        vmResponse.setName(vm.getHostName());
-        if (vm.getHostId() != null) {
-            Host host = ApiDBUtils.findHostById(vm.getHostId());
-            if (host != null) {
-                vmResponse.setHostId(host.getUuid());
-            }
-        }
-        if (vm.getState() != null) {
-            vmResponse.setState(vm.getState().toString());
-        }
-        if (vm.getType() == Type.DomainRouter) {
-            VirtualRouter router = (VirtualRouter)vm;
-            if (router.getRole() != null) {
-                vmResponse.setRole(router.getRole().toString());
-            }
-        }
-        vmResponse.setObjectName("systemvminstance");
-        return vmResponse;
-    }
-
-    @Override
-    public PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result) {
-        PhysicalNetworkResponse response = new PhysicalNetworkResponse();
-
-        DataCenter zone = ApiDBUtils.findZoneById(result.getDataCenterId());
-        if (zone != null) {
-            response.setZoneId(zone.getUuid());
-        }
-        response.setNetworkSpeed(result.getSpeed());
-        response.setVlan(result.getVnetString());
-        if (result.getDomainId() != null) {
-            Domain domain = ApiDBUtils.findDomainById(result.getDomainId());
-            if (domain != null) {
-                response.setDomainId(domain.getUuid());
-            }
-        }
-        response.setId(result.getUuid());
-        if (result.getBroadcastDomainRange() != null) {
-            response.setBroadcastDomainRange(result.getBroadcastDomainRange().toString());
-        }
-        response.setIsolationMethods(result.getIsolationMethods());
-        response.setTags(result.getTags());
-        if (result.getState() != null) {
-            response.setState(result.getState().toString());
-        }
-
-        response.setName(result.getName());
-
-        response.setObjectName("physicalnetwork");
-        return response;
-    }
-
-    @Override
-    public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan vlan) {
-        GuestVlanRangeResponse guestVlanRangeResponse = new GuestVlanRangeResponse();
-
-        guestVlanRangeResponse.setId(vlan.getUuid());
-        Long accountId = ApiDBUtils.getAccountIdForGuestVlan(vlan.getId());
-        Account owner = ApiDBUtils.findAccountById(accountId);
-        if (owner != null) {
-            populateAccount(guestVlanRangeResponse, owner.getId());
-            populateDomain(guestVlanRangeResponse, owner.getDomainId());
-        }
-        guestVlanRangeResponse.setGuestVlanRange(vlan.getGuestVlanRange());
-        guestVlanRangeResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId());
-        PhysicalNetworkVO physicalNetwork = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
-        guestVlanRangeResponse.setZoneId(physicalNetwork.getDataCenterId());
-
-        return guestVlanRangeResponse;
-    }
-
-    @Override
-    public ServiceResponse createNetworkServiceResponse(Service service) {
-        ServiceResponse response = new ServiceResponse();
-        response.setName(service.getName());
-
-        // set list of capabilities required for the service
-        List<CapabilityResponse> capabilityResponses = new ArrayList<CapabilityResponse>();
-        Capability[] capabilities = service.getCapabilities();
-        for (Capability cap : capabilities) {
-            CapabilityResponse capabilityResponse = new CapabilityResponse();
-            capabilityResponse.setName(cap.getName());
-            capabilityResponse.setObjectName("capability");
-            if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName())
-                    || cap.getName().equals(Capability.RedundantRouter.getName())) {
-                capabilityResponse.setCanChoose(true);
-            } else {
-                capabilityResponse.setCanChoose(false);
-            }
-            capabilityResponses.add(capabilityResponse);
-        }
-        response.setCapabilities(capabilityResponses);
-
-        // set list of providers providing this service
-        List<? extends Network.Provider> serviceProviders = ApiDBUtils.getProvidersForService(service);
-        List<ProviderResponse> serviceProvidersResponses = new ArrayList<ProviderResponse>();
-        for (Network.Provider serviceProvider : serviceProviders) {
-            // return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
-            if (service == Service.Firewall
-                    && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp || serviceProvider == Provider.BigSwitchBcf)) {
-                continue;
-            }
-
-            ProviderResponse serviceProviderResponse = createServiceProviderResponse(serviceProvider);
-            serviceProvidersResponses.add(serviceProviderResponse);
-        }
-        response.setProviders(serviceProvidersResponses);
-
-        response.setObjectName("networkservice");
-        return response;
-
-    }
-
-    private ProviderResponse createServiceProviderResponse(Provider serviceProvider) {
-        ProviderResponse response = new ProviderResponse();
-        response.setName(serviceProvider.getName());
-        boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
-        response.setCanEnableIndividualServices(canEnableIndividualServices);
-        return response;
-    }
-
-    @Override
-    public ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result) {
-        ProviderResponse response = new ProviderResponse();
-        response.setId(result.getUuid());
-        response.setName(result.getProviderName());
-        PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
-        if (pnw != null) {
-            response.setPhysicalNetworkId(pnw.getUuid());
-        }
-        PhysicalNetwork dnw = ApiDBUtils.findPhysicalNetworkById(result.getDestinationPhysicalNetworkId());
-        if (dnw != null) {
-            response.setDestinationPhysicalNetworkId(dnw.getUuid());
-        }
-        response.setState(result.getState().toString());
-
-        // set enabled services
-        List<String> services = new ArrayList<String>();
-        for (Service service : result.getEnabledServices()) {
-            services.add(service.getName());
-        }
-        response.setServices(services);
-
-        Provider serviceProvider = Provider.getProvider(result.getProviderName());
-        boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
-        response.setCanEnableIndividualServices(canEnableIndividualServices);
-
-        response.setObjectName("networkserviceprovider");
-        return response;
-    }
-
-    @Override
-    public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result) {
-        TrafficTypeResponse response = new TrafficTypeResponse();
-        response.setId(result.getUuid());
-        PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
-        if (pnet != null) {
-            response.setPhysicalNetworkId(pnet.getUuid());
-        }
-        if (result.getTrafficType() != null) {
-            response.setTrafficType(result.getTrafficType().toString());
-        }
-
-        response.setXenLabel(result.getXenNetworkLabel());
-        response.setKvmLabel(result.getKvmNetworkLabel());
-        response.setVmwareLabel(result.getVmwareNetworkLabel());
-        response.setHypervLabel(result.getHypervNetworkLabel());
-        response.setOvm3Label(result.getOvm3NetworkLabel());
-
-        response.setObjectName("traffictype");
-        return response;
-    }
-
-    @Override
-    public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) {
-        //generate only response of the VR/VPCVR provider type
-        if (!(result.getType() == VirtualRouterProvider.Type.VirtualRouter || result.getType() == VirtualRouterProvider.Type.VPCVirtualRouter)) {
-            return null;
-        }
-        VirtualRouterProviderResponse response = new VirtualRouterProviderResponse();
-        response.setId(result.getUuid());
-        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
-        if (nsp != null) {
-            response.setNspId(nsp.getUuid());
-        }
-        response.setEnabled(result.isEnabled());
-
-        response.setObjectName("virtualrouterelement");
-        return response;
-    }
-
-    @Override
-    public OvsProviderResponse createOvsProviderResponse(OvsProvider result) {
-
-        OvsProviderResponse response = new OvsProviderResponse();
-        response.setId(result.getUuid());
-        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
-        if (nsp != null) {
-            response.setNspId(nsp.getUuid());
-        }
-        response.setEnabled(result.isEnabled());
-
-        response.setObjectName("ovselement");
-        return response;
-    }
-
-    @Override
-    public LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb) {
-        LBStickinessResponse spResponse = new LBStickinessResponse();
-
-        spResponse.setlbRuleId(lb.getUuid());
-        Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
-        if (accountTemp != null) {
-            spResponse.setAccountName(accountTemp.getAccountName());
-            Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
-            if (domain != null) {
-                spResponse.setDomainId(domain.getUuid());
-                spResponse.setDomainName(domain.getName());
-            }
-        }
-
-        List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
-        LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
-        responses.add(ruleResponse);
-
-        spResponse.setRules(responses);
-
-        spResponse.setObjectName("stickinesspolicies");
-        return spResponse;
-    }
-
-    @Override
-    public LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb) {
-        LBStickinessResponse spResponse = new LBStickinessResponse();
-
-        if (lb == null) {
-            return spResponse;
-        }
-        spResponse.setlbRuleId(lb.getUuid());
-        Account account = ApiDBUtils.findAccountById(lb.getAccountId());
-        if (account != null) {
-            spResponse.setAccountName(account.getAccountName());
-            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
-            if (domain != null) {
-                spResponse.setDomainId(domain.getUuid());
-                spResponse.setDomainName(domain.getName());
-            }
-        }
-
-        List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
-        for (StickinessPolicy stickinessPolicy : stickinessPolicies) {
-            LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
-            responses.add(ruleResponse);
-        }
-        spResponse.setRules(responses);
-
-        spResponse.setObjectName("stickinesspolicies");
-        return spResponse;
-    }
-
-    @Override
-    public LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb) {
-        LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
-
-        if (lb == null) {
-            return hcResponse;
-        }
-        hcResponse.setlbRuleId(lb.getUuid());
-        Account account = ApiDBUtils.findAccountById(lb.getAccountId());
-        if (account != null) {
-            hcResponse.setAccountName(account.getAccountName());
-            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
-            if (domain != null) {
-                hcResponse.setDomainId(domain.getUuid());
-                hcResponse.setDomainName(domain.getName());
-            }
-        }
-
-        List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
-        for (HealthCheckPolicy healthcheckPolicy : healthcheckPolicies) {
-            LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
-            responses.add(ruleResponse);
-        }
-        hcResponse.setRules(responses);
-
-        hcResponse.setObjectName("healthcheckpolicies");
-        return hcResponse;
-    }
-
-    @Override
-    public LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb) {
-        LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
-
-        hcResponse.setlbRuleId(lb.getUuid());
-        Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
-        if (accountTemp != null) {
-            hcResponse.setAccountName(accountTemp.getAccountName());
-            Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
-            if (domain != null) {
-                hcResponse.setDomainId(domain.getUuid());
-                hcResponse.setDomainName(domain.getName());
-            }
-        }
-
-        List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
-        LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
-        responses.add(ruleResponse);
-        hcResponse.setRules(responses);
-        hcResponse.setObjectName("healthcheckpolicies");
-        return hcResponse;
-    }
-
-    @Override
-    public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
-        StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
-        response.setUuid(result.getUuid());
-        response.setVlan(result.getVlan());
-        response.setEndIp(result.getEndIp());
-        response.setStartIp(result.getStartIp());
-        response.setPodUuid(result.getPodUuid());
-        response.setZoneUuid(result.getZoneUuid());
-        response.setNetworkUuid(result.getNetworkUuid());
-        response.setNetmask(result.getNetmask());
-        response.setGateway(result.getGateway());
-        response.setObjectName("storagenetworkiprange");
-        return response;
-    }
-
-    @Override
-    public RegionResponse createRegionResponse(Region region) {
-        RegionResponse response = new RegionResponse();
-        response.setId(region.getId());
-        response.setName(region.getName());
-        response.setEndPoint(region.getEndPoint());
-        response.setObjectName("region");
-        response.setGslbServiceEnabled(region.checkIfServiceEnabled(Region.Service.Gslb));
-        response.setPortableipServiceEnabled(region.checkIfServiceEnabled(Region.Service.PortableIp));
-        return response;
-    }
-
-    @Override
-    public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) {
-        ResourceTagJoinVO rto = ApiDBUtils.newResourceTagView(resourceTag);
-        if(rto == null)
-            return null;
-        return ApiDBUtils.newResourceTagResponse(rto, keyValueOnly);
-    }
-
-    @Override
-    public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) {
-        VpcOfferingResponse response = new VpcOfferingResponse();
-        response.setId(offering.getUuid());
-        response.setName(offering.getName());
-        response.setDisplayText(offering.getDisplayText());
-        response.setIsDefault(offering.isDefault());
-        response.setState(offering.getState().name());
-        response.setSupportsDistributedRouter(offering.supportsDistributedRouter());
-        response.setSupportsRegionLevelVpc(offering.offersRegionLevelVPC());
-
-        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
-        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
-        for (Map.Entry<Service, Set<Provider>> entry : serviceProviderMap.entrySet()) {
-            Service service = entry.getKey();
-            Set<Provider> srvc_providers = entry.getValue();
-
-            ServiceResponse svcRsp = new ServiceResponse();
-            // skip gateway service
-            if (service == Service.Gateway) {
-                continue;
-            }
-            svcRsp.setName(service.getName());
-            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
-            for (Provider provider : srvc_providers) {
-                if (provider != null) {
-                    ProviderResponse providerRsp = new ProviderResponse();
-                    providerRsp.setName(provider.getName());
-                    providers.add(providerRsp);
-                }
-            }
-            svcRsp.setProviders(providers);
-
-            serviceResponses.add(svcRsp);
-        }
-        response.setServices(serviceResponses);
-        response.setObjectName("vpcoffering");
-        return response;
-    }
-
-    @Override
-    public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) {
-        VpcResponse response = new VpcResponse();
-        response.setId(vpc.getUuid());
-        response.setName(vpc.getName());
-        response.setDisplayText(vpc.getDisplayText());
-        response.setState(vpc.getState().name());
-        VpcOffering voff = ApiDBUtils.findVpcOfferingById(vpc.getVpcOfferingId());
-        if (voff != null) {
-            response.setVpcOfferingId(voff.getUuid());
-        }
-        response.setCidr(vpc.getCidr());
-        response.setRestartRequired(vpc.isRestartRequired());
-        response.setNetworkDomain(vpc.getNetworkDomain());
-        response.setForDisplay(vpc.isDisplay());
-        response.setUsesDistributedRouter(vpc.usesDistributedRouter());
-        response.setRedundantRouter(vpc.isRedundant());
-        response.setRegionLevelVpc(vpc.isRegionLevelVpc());
-
-        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
-        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
-        for (Map.Entry<Service,Set<Provider>>entry : serviceProviderMap.entrySet()) {
-            Service service = entry.getKey();
-            Set<Provider> serviceProviders = entry.getValue();
-            ServiceResponse svcRsp = new ServiceResponse();
-            // skip gateway service
-            if (service == Service.Gateway) {
-                continue;
-            }
-            svcRsp.setName(service.getName());
-            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
-            for (Provider provider : serviceProviders) {
-                if (provider != null) {
-                    ProviderResponse providerRsp = new ProviderResponse();
-                    providerRsp.setName(provider.getName());
-                    providers.add(providerRsp);
-                }
-            }
-            svcRsp.setProviders(providers);
-
-            serviceResponses.add(svcRsp);
-        }
-
-        List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
-        List<? extends Network> networks = ApiDBUtils.listVpcNetworks(vpc.getId());
-        for (Network network : networks) {
-            NetworkResponse ntwkRsp = createNetworkResponse(view, network);
-            networkResponses.add(ntwkRsp);
-        }
-
-        DataCenter zone = ApiDBUtils.findZoneById(vpc.getZoneId());
-        if (zone != null) {
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-        }
-
-        response.setNetworks(networkResponses);
-        response.setServices(serviceResponses);
-        populateOwner(response, vpc);
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Vpc, vpc.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
-        }
-        response.setTags(tagResponses);
-        response.setObjectName("vpc");
-        return response;
-    }
-
-    @Override
-    public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) {
-        PrivateGatewayResponse response = new PrivateGatewayResponse();
-        response.setId(result.getUuid());
-        response.setBroadcastUri(result.getBroadcastUri());
-        response.setGateway(result.getGateway());
-        response.setNetmask(result.getNetmask());
-        if (result.getVpcId() != null) {
-            Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
-            response.setVpcId(vpc.getUuid());
-        }
-
-        DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId());
-        if (zone != null) {
-            response.setZoneId(zone.getUuid());
-            response.setZoneName(zone.getName());
-        }
-        response.setAddress(result.getIp4Address());
-        PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
-        if (pnet != null) {
-            response.setPhysicalNetworkId(pnet.getUuid());
-        }
-
-        populateAccount(response, result.getAccountId());
-        populateDomain(response, result.getDomainId());
-        response.setState(result.getState().toString());
-        response.setSourceNat(result.getSourceNat());
-
-        NetworkACL acl =  ApiDBUtils.findByNetworkACLId(result.getNetworkACLId());
-        if (acl != null) {
-            response.setAclId(acl.getUuid());
-        }
-
-        response.setObjectName("privategateway");
-
-        return response;
-    }
-
-    @Override
-    public CounterResponse createCounterResponse(Counter counter) {
-        CounterResponse response = new CounterResponse();
-        response.setId(counter.getUuid());
-        response.setSource(counter.getSource().toString());
-        response.setName(counter.getName());
-        response.setValue(counter.getValue());
-        response.setObjectName("counter");
-        return response;
-    }
-
-    @Override
-    public ConditionResponse createConditionResponse(Condition condition) {
-        ConditionResponse response = new ConditionResponse();
-        response.setId(condition.getUuid());
-        List<CounterResponse> counterResponseList = new ArrayList<CounterResponse>();
-        counterResponseList.add(createCounterResponse(ApiDBUtils.getCounter(condition.getCounterid())));
-        response.setCounterResponse(counterResponseList);
-        response.setRelationalOperator(condition.getRelationalOperator().toString());
-        response.setThreshold(condition.getThreshold());
-        response.setObjectName("condition");
-        populateOwner(response, condition);
-        return response;
-    }
-
-    @Override
-    public AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile) {
-        AutoScaleVmProfileResponse response = new AutoScaleVmProfileResponse();
-        response.setId(profile.getUuid());
-        if (profile.getZoneId() != null) {
-            DataCenter zone = ApiDBUtils.findZoneById(profile.getZoneId());
-            if (zone != null) {
-                response.setZoneId(zone.getUuid());
-            }
-        }
-        if (profile.getServiceOfferingId() != null) {
-            ServiceOffering so = ApiDBUtils.findServiceOfferingById(profile.getServiceOfferingId());
-            if (so != null) {
-                response.setServiceOfferingId(so.getUuid());
-            }
-        }
-        if (profile.getTemplateId() != null) {
-            VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId());
-            if (template != null) {
-                response.setTemplateId(template.getUuid());
-            }
-        }
-        response.setOtherDeployParams(profile.getOtherDeployParams());
-        response.setCounterParams(profile.getCounterParams());
-        response.setDestroyVmGraceperiod(profile.getDestroyVmGraceperiod());
-        User user = ApiDBUtils.findUserById(profile.getAutoScaleUserId());
-        if (user != null) {
-            response.setAutoscaleUserId(user.getUuid());
-        }
-        response.setObjectName("autoscalevmprofile");
-
-        // Populates the account information in the response
-        populateOwner(response, profile);
-        return response;
-    }
-
-    @Override
-    public AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy) {
-        AutoScalePolicyResponse response = new AutoScalePolicyResponse();
-        response.setId(policy.getUuid());
-        response.setDuration(policy.getDuration());
-        response.setQuietTime(policy.getQuietTime());
-        response.setAction(policy.getAction());
-        List<ConditionVO> vos = ApiDBUtils.getAutoScalePolicyConditions(policy.getId());
-        ArrayList<ConditionResponse> conditions = new ArrayList<ConditionResponse>(vos.size());
-        for (ConditionVO vo : vos) {
-            conditions.add(createConditionResponse(vo));
-        }
-        response.setConditions(conditions);
-        response.setObjectName("autoscalepolicy");
-
-        // Populates the account information in the response
-        populateOwner(response, policy);
-
-        return response;
-    }
-
-    @Override
-    public AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup) {
-        AutoScaleVmGroupResponse response = new AutoScaleVmGroupResponse();
-        response.setId(vmGroup.getUuid());
-        response.setMinMembers(vmGroup.getMinMembers());
-        response.setMaxMembers(vmGroup.getMaxMembers());
-        response.setState(vmGroup.getState());
-        response.setInterval(vmGroup.getInterval());
-        response.setForDisplay(vmGroup.isDisplay());
-        AutoScaleVmProfileVO profile = ApiDBUtils.findAutoScaleVmProfileById(vmGroup.getProfileId());
-        if (profile != null) {
-            response.setProfileId(profile.getUuid());
-        }
-        FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getLoadBalancerId());
-        if (fw != null) {
-            response.setLoadBalancerId(fw.getUuid());
-        }
-
-        List<AutoScalePolicyResponse> scaleUpPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
-        List<AutoScalePolicyResponse> scaleDownPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
-        response.setScaleUpPolicies(scaleUpPoliciesResponse);
-        response.setScaleDownPolicies(scaleDownPoliciesResponse);
-        response.setObjectName("autoscalevmgroup");
-
-        // Fetch policies for vmgroup
-        List<AutoScalePolicy> scaleUpPolicies = new ArrayList<AutoScalePolicy>();
-        List<AutoScalePolicy> scaleDownPolicies = new ArrayList<AutoScalePolicy>();
-        ApiDBUtils.getAutoScaleVmGroupPolicies(vmGroup.getId(), scaleUpPolicies, scaleDownPolicies);
-        // populate policies
-        for (AutoScalePolicy autoScalePolicy : scaleUpPolicies) {
-            scaleUpPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
-        }
-        for (AutoScalePolicy autoScalePolicy : scaleDownPolicies) {
-            scaleDownPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
-        }
-
-        return response;
-    }
-
-    @Override
-    public StaticRouteResponse createStaticRouteResponse(StaticRoute result) {
-        StaticRouteResponse response = new StaticRouteResponse();
-        response.setId(result.getUuid());
-        if (result.getVpcId() != null) {
-            Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
-            if (vpc != null) {
-                response.setVpcId(vpc.getUuid());
-            }
-        }
-        response.setCidr(result.getCidr());
-
-        StaticRoute.State state = result.getState();
-        if (state.equals(StaticRoute.State.Revoke)) {
-            state = StaticRoute.State.Deleting;
-        }
-        response.setState(state.toString());
-        populateAccount(response, result.getAccountId());
-        populateDomain(response, result.getDomainId());
-
-        // set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.StaticRoute, result.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
-        }
-        response.setTags(tagResponses);
-        response.setObjectName("staticroute");
-
-        return response;
-    }
-
-    @Override
-    public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) {
-        Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse();
-        response.setId(result.getUuid());
-        response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString());
-        Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
-        if (vpc != null) {
-            response.setVpcId(vpc.getUuid());
-        }
-        response.setRemoved(result.getRemoved());
-        response.setForDisplay(result.isDisplay());
-        response.setObjectName("vpngateway");
-
-        populateAccount(response, result.getAccountId());
-        populateDomain(response, result.getDomainId());
-        return response;
-    }
-
-    @Override
-    public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) {
-        Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse();
-        response.setId(result.getUuid());
-        response.setName(result.getName());
-        response.setGatewayIp(result.getGatewayIp());
-        response.setGuestCidrList(result.getGuestCidrList());
-        response.setIpsecPsk(result.getIpsecPsk());
-        response.setIkePolicy(result.getIkePolicy());
-        response.setEspPolicy(result.getEspPolicy());
-        response.setIkeLifetime(result.getIkeLifetime());
-        response.setEspLifetime(result.getEspLifetime());
-        response.setDpd(result.getDpd());
-        response.setEncap(result.getEncap());
-        response.setRemoved(result.getRemoved());
-        response.setObjectName("vpncustomergateway");
-
-        populateAccount(response, result.getAccountId());
-        populateDomain(response, result.getDomainId());
-
-        return response;
-    }
-
-    @Override
-    public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) {
-        Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse();
-        response.setId(result.getUuid());
-        response.setPassive(result.isPassive());
-
-        Long vpnGatewayId = result.getVpnGatewayId();
-        if (vpnGatewayId != null) {
-            Site2SiteVpnGateway vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId);
-            if (vpnGateway != null) {
-                response.setVpnGatewayId(vpnGateway.getUuid());
-                long ipId = vpnGateway.getAddrId();
-                IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId);
-                response.setIp(ipObj.getAddress().addr());
-            }
-        }
-
-        Long customerGatewayId = result.getCustomerGatewayId();
-        if (customerGatewayId != null) {
-            Site2SiteCustomerGateway customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId);
-            if (customerGateway != null) {
-                response.setCustomerGatewayId(customerGateway.getUuid());
-                response.setGatewayIp(customerGateway.getGatewayIp());
-                response.setGuestCidrList(customerGateway.getGuestCidrList());
-                response.setIpsecPsk(customerGateway.getIpsecPsk());
-                response.setIkePolicy(customerGateway.getIkePolicy());
-                response.setEspPolicy(customerGateway.getEspPolicy());
-                response.setIkeLifetime(customerGateway.getIkeLifetime());
-                response.setEspLifetime(customerGateway.getEspLifetime());
-                response.setDpd(customerGateway.getDpd());
-                response.setEncap(customerGateway.getEncap());
-            }
-        }
-
-        populateAccount(response, result.getAccountId());
-        populateDomain(response, result.getDomainId());
-
-        response.setState(result.getState().toString());
-        response.setCreated(result.getCreated());
-        response.setRemoved(result.getRemoved());
-        response.setForDisplay(result.isDisplay());
-        response.setObjectName("vpnconnection");
-        return response;
-    }
-
-    @Override
-    public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
-        GuestOSResponse response = new GuestOSResponse();
-        response.setDescription(guestOS.getDisplayName());
-        response.setId(guestOS.getUuid());
-        response.setIsUserDefined(guestOS.getIsUserDefined());
-        GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId());
-        if (category != null) {
-            response.setOsCategoryId(category.getUuid());
-        }
-
-        response.setObjectName("ostype");
-        return response;
-    }
-
-    @Override
-    public GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor guestOSHypervisor) {
-        GuestOsMappingResponse response = new GuestOsMappingResponse();
-        response.setId(guestOSHypervisor.getUuid());
-        response.setHypervisor(guestOSHypervisor.getHypervisorType());
-        response.setHypervisorVersion(guestOSHypervisor.getHypervisorVersion());
-        response.setOsNameForHypervisor((guestOSHypervisor.getGuestOsName()));
-        response.setIsUserDefined(Boolean.valueOf(guestOSHypervisor.getIsUserDefined()).toString());
-        GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOSHypervisor.getGuestOsId());
-        if (guestOs != null) {
-            response.setOsStdName(guestOs.getDisplayName());
-            response.setOsTypeId(guestOs.getUuid());
-        }
-
-        response.setObjectName("guestosmapping");
-        return response;
-    }
-
-    @Override
-    public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
-        SnapshotScheduleResponse response = new SnapshotScheduleResponse();
-        response.setId(snapshotSchedule.getUuid());
-        if (snapshotSchedule.getVolumeId() != null) {
-            Volume vol = ApiDBUtils.findVolumeById(snapshotSchedule.getVolumeId());
-            if (vol != null) {
-                response.setVolumeId(vol.getUuid());
-            }
-        }
-        if (snapshotSchedule.getPolicyId() != null) {
-            SnapshotPolicy policy = ApiDBUtils.findSnapshotPolicyById(snapshotSchedule.getPolicyId());
-            if (policy != null) {
-                response.setSnapshotPolicyId(policy.getUuid());
-            }
-        }
-        response.setScheduled(snapshotSchedule.getScheduledTimestamp());
-
-        response.setObjectName("snapshot");
-        return response;
-    }
-
-    @Override
-    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags()
-    {
-        try {
-            return _resourceTagDao.listTags();
-        } catch(Exception ex) {
-            s_logger.warn("Failed to get resource details for Usage data due to exception : ", ex);
-        }
-        return null;
-    }
-
-    @Override
-    public UsageRecordResponse createUsageResponse(Usage usageRecord) {
-        return createUsageResponse(usageRecord, null);
-    }
-
-    @Override
-    public UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap) {
-        UsageRecordResponse usageRecResponse = new UsageRecordResponse();
-        Account account = ApiDBUtils.findAccountById(usageRecord.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            //find the project
-            Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
-            if (project != null) {
-                usageRecResponse.setProjectId(project.getUuid());
-                usageRecResponse.setProjectName(project.getName());
-            }
-        } else {
-            usageRecResponse.setAccountId(account.getUuid());
-            usageRecResponse.setAccountName(account.getAccountName());
-        }
-
-        Domain domain = ApiDBUtils.findDomainById(usageRecord.getDomainId());
-        if (domain != null) {
-            usageRecResponse.setDomainId(domain.getUuid());
-            usageRecResponse.setDomainName(domain.getName());
-        }
-
-        if (usageRecord.getZoneId() != null) {
-            DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId());
-            if (zone != null) {
-                usageRecResponse.setZoneId(zone.getUuid());
-            }
-        }
-        usageRecResponse.setDescription(usageRecord.getDescription());
-        usageRecResponse.setUsage(usageRecord.getUsageDisplay());
-        usageRecResponse.setUsageType(usageRecord.getUsageType());
-        if (usageRecord.getVmInstanceId() != null) {
-            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId());
-            if (vm != null) {
-                usageRecResponse.setVirtualMachineId(vm.getUuid());
-            }
-        }
-        usageRecResponse.setVmName(usageRecord.getVmName());
-        if (usageRecord.getTemplateId() != null) {
-            VMTemplateVO template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId());
-            if (template != null) {
-                usageRecResponse.setTemplateId(template.getUuid());
-            }
-        }
-
-        ResourceTag.ResourceObjectType resourceType = null;
-        Long resourceId = null;
-        if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
-            ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString());
-            //Service Offering Id
-            if(svcOffering != null) {
-                usageRecResponse.setOfferingId(svcOffering.getUuid());
-            }
-            //VM Instance ID
-            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
-            if (vm != null) {
-                resourceType = ResourceTag.ResourceObjectType.UserVm;
-                usageRecResponse.setUsageId(vm.getUuid());
-                resourceId = vm.getId();
-            }
-            //Hypervisor Type
-            usageRecResponse.setType(usageRecord.getType());
-            //Dynamic compute offerings details
-            if(usageRecord.getCpuCores() != null) {
-                usageRecResponse.setCpuNumber(usageRecord.getCpuCores());
-            } else if (svcOffering.getCpu() != null){
-                usageRecResponse.setCpuNumber(svcOffering.getCpu().longValue());
-            }
-            if(usageRecord.getCpuSpeed() != null) {
-                usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed());
-            } else if(svcOffering.getSpeed() != null){
-                usageRecResponse.setCpuSpeed(svcOffering.getSpeed().longValue());
-            }
-            if(usageRecord.getMemory() != null) {
-                usageRecResponse.setMemory(usageRecord.getMemory());
-            } else if(svcOffering.getRamSize() != null) {
-                usageRecResponse.setMemory(svcOffering.getRamSize().longValue());
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) {
-            //isSourceNAT
-            usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ? true : false);
-            //isSystem
-            usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true : false);
-            //IP Address ID
-            IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString());
-            if (ip != null) {
-                resourceType = ResourceObjectType.PublicIpAddress;
-                resourceId = ip.getId();
-                usageRecResponse.setUsageId(ip.getUuid());
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
-            //Device Type
-            resourceType = ResourceObjectType.UserVm;
-            usageRecResponse.setType(usageRecord.getType());
-            if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) {
-                //Domain Router Id
-                VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
-                if (vm != null) {
-                    resourceId = vm.getId();
-                    usageRecResponse.setUsageId(vm.getUuid());
-                }
-            } else {
-                //External Device Host Id
-                HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString());
-                if (host != null) {
-                    usageRecResponse.setUsageId(host.getUuid());
-                }
-            }
-            //Network ID
-            if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId() != 0)) {
-                NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString());
-                if (network != null) {
-                    resourceType = ResourceObjectType.Network;
-                    resourceId = network.getId();
-                    usageRecResponse.setNetworkId(network.getUuid());
-                }
-            }
-        } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE
-                || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
-            //Device Type
-            usageRecResponse.setType(usageRecord.getType());
-            resourceType = ResourceObjectType.Volume;
-            //VM Instance Id
-            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
-            if (vm != null) {
-                usageRecResponse.setVirtualMachineId(vm.getUuid());
-            }
-            //Volume ID
-            VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
-            if (volume != null) {
-                usageRecResponse.setUsageId(volume.getUuid());
-                resourceId = volume.getId();
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) {
-            //Volume ID
-            VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
-            resourceType = ResourceObjectType.Volume;
-            if (volume != null) {
-                usageRecResponse.setUsageId(volume.getUuid());
-                resourceId = volume.getId();
-            }
-            //Volume Size
-            usageRecResponse.setSize(usageRecord.getSize());
-            //Disk Offering Id
-            if (usageRecord.getOfferingId() != null) {
-                DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString());
-                usageRecResponse.setOfferingId(diskOff.getUuid());
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) {
-            //Template/ISO ID
-            VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString());
-            if (tmpl != null) {
-                usageRecResponse.setUsageId(tmpl.getUuid());
-                resourceId = tmpl.getId();
-            }
-            //Template/ISO Size
-            usageRecResponse.setSize(usageRecord.getSize());
-            if (usageRecord.getUsageType() == UsageTypes.ISO) {
-                usageRecResponse.setVirtualSize(usageRecord.getSize());
-                resourceType = ResourceObjectType.ISO;
-            } else {
-                usageRecResponse.setVirtualSize(usageRecord.getVirtualSize());
-                resourceType = ResourceObjectType.Template;
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) {
-            //Snapshot ID
-            SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString());
-            resourceType = ResourceObjectType.Snapshot;
-            if (snap != null) {
-                usageRecResponse.setUsageId(snap.getUuid());
-                resourceId = snap.getId();
-            }
-            //Snapshot Size
-            usageRecResponse.setSize(usageRecord.getSize());
-
-        } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) {
-            //Load Balancer Policy ID
-            LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString());
-            resourceType = ResourceObjectType.LoadBalancer;
-            if (lb != null) {
-                usageRecResponse.setUsageId(lb.getUuid());
-                resourceId = lb.getId();
-            }
-        } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) {
-            //Port Forwarding Rule ID
-            PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString());
-            resourceType = ResourceObjectType.PortForwardingRule;
-            if (pf != null) {
-                usageRecResponse.setUsageId(pf.getUuid());
-                resourceId = pf.getId();
-            }
-
-        } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) {
-            //Network Offering Id
-            NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString());
-            usageRecResponse.setOfferingId(netOff.getUuid());
-            //is Default
-            usageRecResponse.setDefault((usageRecord.getUsageId() == 1) ? true : false);
-
-        } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) {
-            //VPN User ID
-            VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString());
-            if (vpnUser != null) {
-                usageRecResponse.setUsageId(vpnUser.getUuid());
-            }
-        } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) {
-            //Security Group Id
-            SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString());
-            resourceType = ResourceObjectType.SecurityGroup;
-            if (sg != null) {
-                resourceId = sg.getId();
-                usageRecResponse.setUsageId(sg.getUuid());
-            }
-        } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
-            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
-            resourceType = ResourceObjectType.UserVm;
-            if (vm != null) {
-                resourceId = vm.getId();
-                usageRecResponse.setVmName(vm.getInstanceName());
-                usageRecResponse.setUsageId(vm.getUuid());
-            }
-            usageRecResponse.setSize(usageRecord.getSize());
-            if (usageRecord.getOfferingId() != null) {
-                usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString());
-            }
-        }
-
-        if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId + ":" + resourceType) != null) {
-             usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
-        }
-
-        if (usageRecord.getRawUsage() != null) {
-            DecimalFormat decimalFormat = new DecimalFormat("###########.######");
-            usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));
-        }
-
-        if (usageRecord.getStartDate() != null) {
-            usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate()));
-        }
-        if (usageRecord.getEndDate() != null) {
-            usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate()));
-        }
-
-        return usageRecResponse;
-    }
-
-    public String getDateStringInternal(Date inputDate) {
-        if (inputDate == null) {
-            return null;
-        }
-
-        TimeZone tz = _usageSvc.getUsageTimezone();
-        Calendar cal = Calendar.getInstance(tz);
-        cal.setTime(inputDate);
-
-        StringBuilder sb = new StringBuilder(32);
-        sb.append(cal.get(Calendar.YEAR)).append('-');
-
-        int month = cal.get(Calendar.MONTH) + 1;
-        if (month < 10) {
-            sb.append('0');
-        }
-        sb.append(month).append('-');
-
-        int day = cal.get(Calendar.DAY_OF_MONTH);
-        if (day < 10) {
-            sb.append('0');
-        }
-        sb.append(day);
-
-        sb.append("'T'");
-
-        int hour = cal.get(Calendar.HOUR_OF_DAY);
-        if (hour < 10) {
-            sb.append('0');
-        }
-        sb.append(hour).append(':');
-
-        int minute = cal.get(Calendar.MINUTE);
-        if (minute < 10) {
-            sb.append('0');
-        }
-        sb.append(minute).append(':');
-
-        int seconds = cal.get(Calendar.SECOND);
-        if (seconds < 10) {
-            sb.append('0');
-        }
-        sb.append(seconds);
-
-        double offset = cal.get(Calendar.ZONE_OFFSET);
-        if (tz.inDaylightTime(inputDate)) {
-            offset += (1.0 * tz.getDSTSavings()); // add the timezone's DST
-            // value (typically 1 hour
-            // expressed in milliseconds)
-        }
-
-        offset = offset / (1000d * 60d * 60d);
-        int hourOffset = (int)offset;
-        double decimalVal = Math.abs(offset) - Math.abs(hourOffset);
-        int minuteOffset = (int)(decimalVal * 60);
-
-        if (hourOffset < 0) {
-            if (hourOffset > -10) {
-                sb.append("-0");
-            } else {
-                sb.append('-');
-            }
-            sb.append(Math.abs(hourOffset));
-        } else {
-            if (hourOffset < 10) {
-                sb.append("+0");
-            } else {
-                sb.append("+");
-            }
-            sb.append(hourOffset);
-        }
-
-        sb.append(':');
-
-        if (minuteOffset == 0) {
-            sb.append("00");
-        } else if (minuteOffset < 10) {
-            sb.append('0').append(minuteOffset);
-        } else {
-            sb.append(minuteOffset);
-        }
-
-        return sb.toString();
-    }
-
-    @Override
-    public TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor) {
-        Map<String, String> tmDetails = ApiDBUtils.findHostDetailsById(trafficMonitor.getId());
-        TrafficMonitorResponse response = new TrafficMonitorResponse();
-        response.setId(trafficMonitor.getUuid());
-        response.setIpAddress(trafficMonitor.getPrivateIpAddress());
-        response.setNumRetries(tmDetails.get("numRetries"));
-        response.setTimeout(tmDetails.get("timeout"));
-        return response;
-    }
-
-    @Override
-    public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
-        NicSecondaryIpResponse response = new NicSecondaryIpResponse();
-        NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
-        NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
-        response.setId(result.getUuid());
-        response.setIpAddr(result.getIp4Address());
-        response.setNicId(nic.getUuid());
-        response.setNwId(network.getUuid());
-        response.setObjectName("nicsecondaryip");
-        return response;
-    }
-
-    /**
-     * The resulting Response attempts to be in line with what is returned from
-     * @see com.cloud.api.query.dao.UserVmJoinDaoImpl#setUserVmResponse(ResponseView, UserVmResponse, UserVmJoinVO)
-     */
-    @Override
-    public NicResponse createNicResponse(Nic result) {
-        NicResponse response = new NicResponse();
-        NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
-        VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId());
-        UserVmJoinVO userVm = _entityMgr.findById(UserVmJoinVO.class, result.getInstanceId());
-        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOs = _nicExtraDhcpOptionDao.listByNicId(result.getId());
-
-        // The numbered comments are to keep track of the data returned from here and UserVmJoinDaoImpl.setUserVmResponse()
-        // the data can't be identical but some tidying up/unifying might be possible
-        /*1: nicUuid*/
-        response.setId(result.getUuid());
-        /*2: networkUuid*/
-        response.setNetworkid(network.getUuid());
-        /*3: vmId*/
-        if (vm != null) {
-            response.setVmId(vm.getUuid());
-        }
-
-        if (userVm != null){
-            if (userVm.getTrafficType() != null) {
-                /*4: trafficType*/
-                response.setTrafficType(userVm.getTrafficType().toString());
-            }
-            if (userVm.getGuestType() != null) {
-                /*5: guestType*/
-                response.setType(userVm.getGuestType().toString());
-            }
-        }
-        /*6: ipAddress*/
-        response.setIpaddress(result.getIPv4Address());
-        /*7: gateway*/
-        response.setGateway(result.getIPv4Gateway());
-        /*8: netmask*/
-        response.setNetmask(result.getIPv4Netmask());
-        /*9: networkName*/
-        if(userVm != null && userVm.getNetworkName() != null) {
-            response.setNetworkName(userVm.getNetworkName());
-        }
-        /*10: macAddress*/
-        response.setMacAddress(result.getMacAddress());
-        /*11: IPv6Address*/
-        if (result.getIPv6Address() != null) {
-            response.setIp6Address(result.getIPv6Address());
-        }
-        /*12: IPv6Gateway*/
-        if (result.getIPv6Gateway() != null) {
-            response.setIp6Gateway(result.getIPv6Gateway());
-        }
-        /*13: IPv6Cidr*/
-        if (result.getIPv6Cidr() != null) {
-            response.setIp6Cidr(result.getIPv6Cidr());
-        }
-        /*14: deviceId*/
-        response.setDeviceId(String.valueOf(result.getDeviceId()));
-        /*15: broadcastURI*/
-        if (result.getBroadcastUri() != null) {
-            response.setBroadcastUri(result.getBroadcastUri().toString());
-        }
-        /*16: isolationURI*/
-        if (result.getIsolationUri() != null) {
-            response.setIsolationUri(result.getIsolationUri().toString());
-        }
-        /*17: default*/
-        response.setIsDefault(result.isDefaultNic());
-        if (result.getSecondaryIp()) {
-            List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(result.getId());
-            if (secondaryIps != null) {
-                List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
-                for (NicSecondaryIpVO ip : secondaryIps) {
-                    NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
-                    ipRes.setId(ip.getUuid());
-                    ipRes.setIpAddr(ip.getIp4Address());
-                    ipList.add(ipRes);
-                }
-                response.setSecondaryIps(ipList);
-            }
-        }
-        /*18: extra dhcp options */
-        List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = nicExtraDhcpOptionVOs
-                .stream()
-                .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
-                .collect(Collectors.toList());
-
-        response.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
-
-        if (result instanceof NicVO){
-            if (((NicVO)result).getNsxLogicalSwitchUuid() != null){
-                response.setNsxLogicalSwitch(((NicVO)result).getNsxLogicalSwitchUuid());
-            }
-            if (((NicVO)result).getNsxLogicalSwitchPortUuid() != null){
-                response.setNsxLogicalSwitchPort(((NicVO)result).getNsxLogicalSwitchPortUuid());
-            }
-        }
-        return response;
-    }
-
-    @Override
-    public ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances) {
-
-        ApplicationLoadBalancerResponse lbResponse = new ApplicationLoadBalancerResponse();
-        lbResponse.setId(lb.getUuid());
-        lbResponse.setName(lb.getName());
-        lbResponse.setDescription(lb.getDescription());
-        lbResponse.setAlgorithm(lb.getAlgorithm());
-        lbResponse.setForDisplay(lb.isDisplay());
-        Network nw = ApiDBUtils.findNetworkById(lb.getNetworkId());
-        lbResponse.setNetworkId(nw.getUuid());
-        populateOwner(lbResponse, lb);
-
-        if (lb.getScheme() == Scheme.Internal) {
-            lbResponse.setSourceIp(lb.getSourceIp().addr());
-            //TODO - create the view for the load balancer rule to reflect the network uuid
-            Network network = ApiDBUtils.findNetworkById(lb.getNetworkId());
-            lbResponse.setSourceIpNetworkId(network.getUuid());
-        } else {
-            //for public, populate the ip information from the ip address
-            IpAddress publicIp = ApiDBUtils.findIpAddressById(lb.getSourceIpAddressId());
-            lbResponse.setSourceIp(publicIp.getAddress().addr());
-            Network ntwk = ApiDBUtils.findNetworkById(publicIp.getNetworkId());
-            lbResponse.setSourceIpNetworkId(ntwk.getUuid());
-        }
-
-        //set load balancer rules information (only one rule per load balancer in this release)
-        List<ApplicationLoadBalancerRuleResponse> ruleResponses = new ArrayList<ApplicationLoadBalancerRuleResponse>();
-        ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse();
-        ruleResponse.setInstancePort(lb.getDefaultPortStart());
-        ruleResponse.setSourcePort(lb.getSourcePortStart());
-        FirewallRule.State stateToSet = lb.getState();
-        if (stateToSet.equals(FirewallRule.State.Revoke)) {
-            stateToSet = FirewallRule.State.Deleting;
-        }
-        ruleResponse.setState(stateToSet.toString());
-        ruleResponse.setObjectName("loadbalancerrule");
-        ruleResponses.add(ruleResponse);
-        lbResponse.setLbRules(ruleResponses);
-
-        //set Lb instances information
-        List<ApplicationLoadBalancerInstanceResponse> instanceResponses = new ArrayList<ApplicationLoadBalancerInstanceResponse>();
-        for (Map.Entry<Ip,UserVm> entry : lbInstances.entrySet()) {
-            Ip ip = entry.getKey();
-            UserVm vm = entry.getValue();
-            ApplicationLoadBalancerInstanceResponse instanceResponse = new ApplicationLoadBalancerInstanceResponse();
-            instanceResponse.setIpAddress(ip.addr());
-            instanceResponse.setId(vm.getUuid());
-            instanceResponse.setName(vm.getInstanceName());
-            instanceResponse.setObjectName("loadbalancerinstance");
-            instanceResponses.add(instanceResponse);
-        }
-
-        lbResponse.setLbInstances(instanceResponses);
-
-        //set tag information
-        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, lb.getId());
-        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
-        for (ResourceTag tag : tags) {
-            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
-            CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
-        }
-        lbResponse.setTags(tagResponses);
-
-        lbResponse.setObjectName("loadbalancer");
-        return lbResponse;
-    }
-
-    @Override
-    public AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group) {
-
-        AffinityGroupResponse response = new AffinityGroupResponse();
-
-        Account account = ApiDBUtils.findAccountById(group.getAccountId());
-        response.setId(group.getUuid());
-        response.setAccountName(account.getAccountName());
-        response.setName(group.getName());
-        response.setType(group.getType());
-        response.setDescription(group.getDescription());
-        Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
-        if (domain != null) {
-            response.setDomainId(domain.getUuid());
-            response.setDomainName(domain.getName());
-        }
-
-        response.setObjectName("affinitygroup");
-        return response;
-    }
-
-    @Override
-    public Long getAffinityGroupId(String groupName, long accountId) {
-        AffinityGroup ag = ApiDBUtils.getAffinityGroup(groupName, accountId);
-        if (ag == null) {
-            return null;
-        } else {
-            return ag.getId();
-        }
-    }
-
-
-    @Override
-    public PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange ipRange) {
-        PortableIpRangeResponse response = new PortableIpRangeResponse();
-        response.setId(ipRange.getUuid());
-        String ipRangeStr = ipRange.getIpRange();
-        if (ipRangeStr != null) {
-            String[] range = ipRangeStr.split("-");
-            response.setStartIp(range[0]);
-            response.setEndIp(range[1]);
-        }
-        response.setVlan(ipRange.getVlanTag());
-        response.setGateway(ipRange.getGateway());
-        response.setNetmask(ipRange.getNetmask());
-        response.setRegionId(ipRange.getRegionId());
-        response.setObjectName("portableiprange");
-        return response;
-    }
-
-    @Override
-    public PortableIpResponse createPortableIPResponse(PortableIp portableIp) {
-        PortableIpResponse response = new PortableIpResponse();
-        response.setAddress(portableIp.getAddress());
-        Long accountId =  portableIp.getAllocatedInDomainId();
-        if (accountId != null) {
-            Account account = ApiDBUtils.findAccountById(accountId);
-            response.setAllocatedToAccountId(account.getAccountName());
-            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
-            response.setAllocatedInDomainId(domain.getUuid());
-        }
-
-        response.setAllocatedTime(portableIp.getAllocatedTime());
-
-        if (portableIp.getAssociatedDataCenterId() != null) {
-            DataCenter zone = ApiDBUtils.findZoneById(portableIp.getAssociatedDataCenterId());
-            if (zone != null) {
-                response.setAssociatedDataCenterId(zone.getUuid());
-            }
-        }
-
-        if (portableIp.getPhysicalNetworkId() != null) {
-            PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(portableIp.getPhysicalNetworkId());
-            if (pnw != null) {
-                response.setPhysicalNetworkId(pnw.getUuid());
-            }
-        }
-
-        if (portableIp.getAssociatedWithNetworkId() != null) {
-            Network ntwk = ApiDBUtils.findNetworkById(portableIp.getAssociatedWithNetworkId());
-            if (ntwk != null) {
-                response.setAssociatedWithNetworkId(ntwk.getUuid());
-            }
-        }
-
-        if (portableIp.getAssociatedWithVpcId() != null) {
-            Vpc vpc = ApiDBUtils.findVpcById(portableIp.getAssociatedWithVpcId());
-            if (vpc != null) {
-                response.setAssociatedWithVpcId(vpc.getUuid());
-            }
-        }
-
-        response.setState(portableIp.getState().name());
-        response.setObjectName("portableip");
-        return response;
-    }
-
-    @Override
-    public InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result) {
-        if (result.getType() != VirtualRouterProvider.Type.InternalLbVm) {
-            return null;
-        }
-        InternalLoadBalancerElementResponse response = new InternalLoadBalancerElementResponse();
-        response.setId(result.getUuid());
-        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
-        if (nsp != null) {
-            response.setNspId(nsp.getUuid());
-        }
-        response.setEnabled(result.isEnabled());
-
-        response.setObjectName("internalloadbalancerelement");
-        return response;
-    }
-
-    @Override
-    public IsolationMethodResponse createIsolationMethodResponse(IsolationType method) {
-        IsolationMethodResponse response = new IsolationMethodResponse();
-        response.setIsolationMethodName(method.toString());
-        response.setObjectName("isolationmethod");
-        return response;
-    }
-
-    @Override
-    public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
-        NetworkACLResponse response = new NetworkACLResponse();
-        response.setId(networkACL.getUuid());
-        response.setName(networkACL.getName());
-        response.setDescription(networkACL.getDescription());
-        response.setForDisplay(networkACL.isDisplay());
-        Vpc vpc = ApiDBUtils.findVpcById(networkACL.getVpcId());
-        if (vpc != null) {
-            response.setVpcId(vpc.getUuid());
-        }
-        response.setObjectName("networkacllist");
-        return response;
-    }
-
-    @Override
-    public ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds) {
-        ListResponse<UpgradeRouterTemplateResponse> response = new ListResponse<UpgradeRouterTemplateResponse>();
-        List<UpgradeRouterTemplateResponse> responses = new ArrayList<UpgradeRouterTemplateResponse>();
-        for (Long jobId : jobIds) {
-            UpgradeRouterTemplateResponse routerResponse = new UpgradeRouterTemplateResponse();
-            AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
-            routerResponse.setAsyncJobId((job.getUuid()));
-            routerResponse.setObjectName("asyncjobs");
-            responses.add(routerResponse);
-        }
-        response.setResponses(responses);
-        return response;
-    }
-
-    @Override
-    public SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey) {
-        SSHKeyPairResponse response = new SSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint());
-        if (privatekey) {
-            response = new CreateSSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint(), sshkeyPair.getPrivateKey());
-        }
-        Account account = ApiDBUtils.findAccountById(sshkeyPair.getAccountId());
-        response.setAccountName(account.getAccountName());
-        Domain domain = ApiDBUtils.findDomainById(sshkeyPair.getDomainId());
-        response.setDomainId(domain.getUuid());
-        response.setDomainName(domain.getName());
-        return response;
-    }
-}
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
deleted file mode 100644
index a97984a..0000000
--- a/server/src/com/cloud/api/ApiServer.java
+++ /dev/null
@@ -1,1423 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api;
-
-import com.cloud.api.dispatch.DispatchChainFactory;
-import com.cloud.api.dispatch.DispatchTask;
-import com.cloud.api.response.ApiResponseSerializer;
-import com.cloud.configuration.Config;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventCategory;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.AccountLimitException;
-import com.cloud.exception.CloudAuthenticationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.RequestLimitException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.UnavailableCommandException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import com.cloud.user.User;
-import com.cloud.user.UserAccount;
-import com.cloud.user.UserVO;
-import com.cloud.utils.ConstantTimeComparator;
-import com.cloud.utils.HttpUtils;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.ReflectUtil;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.UUIDManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionProxyObject;
-import com.google.gson.reflect.TypeToken;
-import org.apache.cloudstack.acl.APIChecker;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ApiServerService;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.auth.APIAuthenticationManager;
-import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
-import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
-import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
-import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
-import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
-import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
-import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
-import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
-import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.CreateCmdResponse;
-import org.apache.cloudstack.api.response.ExceptionResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.LoginCmdResponse;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-import org.apache.cloudstack.framework.events.EventBus;
-import org.apache.cloudstack.framework.events.EventBusException;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
-import org.apache.cloudstack.framework.messagebus.MessageHandler;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.http.ConnectionClosedException;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpServerConnection;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.entity.BasicHttpEntity;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.DefaultHttpServerConnection;
-import org.apache.http.impl.NoConnectionReuseStrategy;
-import org.apache.http.impl.SocketHttpServerConnection;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.CoreProtocolPNames;
-import org.apache.http.params.HttpParams;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.BasicHttpProcessor;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpRequestHandlerRegistry;
-import org.apache.http.protocol.HttpService;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-import org.apache.http.protocol.ResponseDate;
-import org.apache.http.protocol.ResponseServer;
-import org.apache.log4j.Logger;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.stereotype.Component;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.lang.reflect.Type;
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-@Component
-public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService, Configurable {
-    private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName());
-    private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName());
-
-    private static boolean encodeApiResponse = false;
-
-    /**
-     * Non-printable ASCII characters - numbers 0 to 31 and 127 decimal
-     */
-    private static final String CONTROL_CHARACTERS = "[\000-\011\013-\014\016-\037\177]";
-
-    @Inject
-    private ApiDispatcher dispatcher;
-    @Inject
-    private DispatchChainFactory dispatchChainFactory;
-    @Inject
-    private AccountManager accountMgr;
-    @Inject
-    private DomainManager domainMgr;
-    @Inject
-    private DomainDao domainDao;
-    @Inject
-    private UUIDManager uuidMgr;
-    @Inject
-    private AsyncJobManager asyncMgr;
-    @Inject
-    private ConfigurationDao configDao;
-    @Inject
-    private EntityManager entityMgr;
-    @Inject
-    private APIAuthenticationManager authManager;
-
-    private List<PluggableService> pluggableServices;
-
-    private List<APIChecker> apiAccessCheckers;
-
-    @Inject
-    private ApiAsyncJobDispatcher asyncDispatcher;
-
-    private static int s_workerCount = 0;
-    private static final DateFormat DateFormatToUse = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
-    private static Map<String, List<Class<?>>> s_apiNameCmdClassMap = new HashMap<String, List<Class<?>>>();
-
-    private static ExecutorService s_executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory(
-            "ApiServer"));
-
-    static final ConfigKey<Boolean> EnableSecureSessionCookie = new ConfigKey<Boolean>("Advanced", Boolean.class, "enable.secure.session.cookie", "false",
-            "Session cookie is marked as secure if this is enabled. Secure cookies only work when HTTPS is used.", false);
-
-    static final ConfigKey<String> JSONcontentType = new ConfigKey<String>(String.class, "json.content.type", "Advanced", "application/json; charset=UTF-8",
-            "Http response content type for .js files (default is text/javascript)", false, ConfigKey.Scope.Global, null);
-    @Inject
-    private MessageBus messageBus;
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        messageBus.subscribe(AsyncJob.Topics.JOB_EVENT_PUBLISH, MessageDispatcher.getDispatcher(this));
-        return true;
-    }
-
-    @MessageHandler(topic = AsyncJob.Topics.JOB_EVENT_PUBLISH)
-    public void handleAsyncJobPublishEvent(String subject, String senderAddress, Object args) {
-        assert (args != null);
-
-        @SuppressWarnings("unchecked")
-        Pair<AsyncJob, String> eventInfo = (Pair<AsyncJob, String>)args;
-        AsyncJob job = eventInfo.first();
-        String jobEvent = eventInfo.second();
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("Handle asyjob publish event " + jobEvent);
-
-        EventBus eventBus = null;
-        try {
-            eventBus = ComponentContext.getComponent(EventBus.class);
-        } catch (NoSuchBeanDefinitionException nbe) {
-            return; // no provider is configured to provide events bus, so just return
-        }
-
-        if (!job.getDispatcher().equalsIgnoreCase("ApiAsyncJobDispatcher")) {
-            return;
-        }
-
-        User userJobOwner = accountMgr.getUserIncludingRemoved(job.getUserId());
-        Account jobOwner = accountMgr.getAccount(userJobOwner.getAccountId());
-
-        // Get the event type from the cmdInfo json string
-        String info = job.getCmdInfo();
-        String cmdEventType = "unknown";
-        if (info != null) {
-            Type type = new TypeToken<Map<String, String>>(){}.getType();
-            Map<String, String> cmdInfo = ApiGsonHelper.getBuilder().create().fromJson(info, type);
-            String eventTypeObj = cmdInfo.get("cmdEventType");
-            if (eventTypeObj != null) {
-                cmdEventType = eventTypeObj;
-
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("Retrieved cmdEventType from job info: " + cmdEventType);
-            } else {
-                if (s_logger.isDebugEnabled())
-                    s_logger.debug("Unable to locate cmdEventType marker in job info. publish as unknown event");
-            }
-        }
-        // For some reason, the instanceType / instanceId are not abstract, which means we may get null values.
-        String instanceType = job.getInstanceType() != null ? job.getInstanceType() : "unknown";
-        String instanceUuid = job.getInstanceId() != null ? ApiDBUtils.findJobInstanceUuid(job) : "";
-        org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event("management-server", EventCategory.ASYNC_JOB_CHANGE_EVENT.getName(),
-                jobEvent, instanceType, instanceUuid);
-
-        Map<String, String> eventDescription = new HashMap<String, String>();
-        eventDescription.put("command", job.getCmd());
-        eventDescription.put("user", userJobOwner.getUuid());
-        eventDescription.put("account", jobOwner.getUuid());
-        eventDescription.put("processStatus", "" + job.getProcessStatus());
-        eventDescription.put("resultCode", "" + job.getResultCode());
-        eventDescription.put("instanceUuid", instanceUuid);
-        eventDescription.put("instanceType", instanceType);
-        eventDescription.put("commandEventType", cmdEventType);
-        eventDescription.put("jobId", job.getUuid());
-        eventDescription.put("jobResult", job.getResult());
-        eventDescription.put("cmdInfo", job.getCmdInfo());
-        eventDescription.put("status", "" + job.getStatus() );
-        // If the event.accountinfo boolean value is set, get the human readable value for the username / domainname
-        Map<String, String> configs = configDao.getConfiguration("management-server", new HashMap<String, String>());
-        if (Boolean.valueOf(configs.get("event.accountinfo"))) {
-            DomainVO domain = domainDao.findById(jobOwner.getDomainId());
-            eventDescription.put("username", userJobOwner.getUsername());
-            eventDescription.put("accountname", jobOwner.getAccountName());
-            eventDescription.put("domainname", domain.getName());
-        }
-        event.setDescription(eventDescription);
-
-        try {
-            eventBus.publish(event);
-        } catch (EventBusException evx) {
-            String errMsg = "Failed to publish async job event on the the event bus.";
-            s_logger.warn(errMsg, evx);
-        }
-    }
-
-    @Override
-    public boolean start() {
-        Security.addProvider(new BouncyCastleProvider());
-        Integer apiPort = null; // api port, null by default
-        final SearchCriteria<ConfigurationVO> sc = configDao.createSearchCriteria();
-        sc.addAnd("name", SearchCriteria.Op.EQ, Config.IntegrationAPIPort.key());
-        final List<ConfigurationVO> values = configDao.search(sc, null);
-        if ((values != null) && (values.size() > 0)) {
-            final ConfigurationVO apiPortConfig = values.get(0);
-            if (apiPortConfig.getValue() != null) {
-                apiPort = Integer.parseInt(apiPortConfig.getValue());
-                apiPort = (apiPort <= 0) ? null : apiPort;
-            }
-        }
-
-        final Map<String, String> configs = configDao.getConfiguration();
-        final String strSnapshotLimit = configs.get(Config.ConcurrentSnapshotsThresholdPerHost.key());
-        if (strSnapshotLimit != null) {
-            final Long snapshotLimit = NumbersUtil.parseLong(strSnapshotLimit, 1L);
-            if (snapshotLimit.longValue() <= 0) {
-                s_logger.debug("Global config parameter " + Config.ConcurrentSnapshotsThresholdPerHost.toString() + " is less or equal 0; defaulting to unlimited");
-            } else {
-                dispatcher.setCreateSnapshotQueueSizeLimit(snapshotLimit);
-            }
-        }
-
-        final Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
-        for (final PluggableService pluggableService : pluggableServices) {
-            cmdClasses.addAll(pluggableService.getCommands());
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Discovered plugin " + pluggableService.getClass().getSimpleName());
-            }
-        }
-
-        for (final Class<?> cmdClass : cmdClasses) {
-            final APICommand at = cmdClass.getAnnotation(APICommand.class);
-            if (at == null) {
-                throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName()));
-            }
-
-            String apiName = at.name();
-            List<Class<?>> apiCmdList = s_apiNameCmdClassMap.get(apiName);
-            if (apiCmdList == null) {
-                apiCmdList = new ArrayList<Class<?>>();
-                s_apiNameCmdClassMap.put(apiName, apiCmdList);
-            }
-            apiCmdList.add(cmdClass);
-
-        }
-
-        setEncodeApiResponse(Boolean.valueOf(configDao.getValue(Config.EncodeApiResponse.key())));
-
-        if (apiPort != null) {
-            final ListenerThread listenerThread = new ListenerThread(this, apiPort);
-            listenerThread.start();
-        }
-
-        return true;
-    }
-
-    // NOTE: handle() only handles over the wire (OTW) requests from integration.api.port 8096
-    // If integration api port is not configured, actual OTW requests will be received by ApiServlet
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    @Override
-    public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException {
-
-        // Create StringBuffer to log information in access log
-        final StringBuilder sb = new StringBuilder();
-        final HttpServerConnection connObj = (HttpServerConnection)context.getAttribute("http.connection");
-        if (connObj instanceof SocketHttpServerConnection) {
-            final InetAddress remoteAddr = ((SocketHttpServerConnection)connObj).getRemoteAddress();
-            sb.append(remoteAddr.toString() + " -- ");
-        }
-        sb.append(StringUtils.cleanString(request.getRequestLine().toString()));
-
-        try {
-            List<NameValuePair> paramList = null;
-            try {
-                paramList = URLEncodedUtils.parse(new URI(request.getRequestLine().getUri()), HttpUtils.UTF_8);
-            } catch (final URISyntaxException e) {
-                s_logger.error("Error parsing url request", e);
-            }
-
-            // Use Multimap as the parameter map should be in the form (name=String, value=String[])
-            // So parameter values are stored in a list for the same name key
-            // APITODO: Use Guava's (import com.google.common.collect.Multimap;)
-            // (Immutable)Multimap<String, String> paramMultiMap = HashMultimap.create();
-            // Map<String, Collection<String>> parameterMap = paramMultiMap.asMap();
-            final Map parameterMap = new HashMap<String, String[]>();
-            String responseType = HttpUtils.RESPONSE_TYPE_XML;
-            if(paramList != null) {
-                for (final NameValuePair param : paramList) {
-                    if (param.getName().equalsIgnoreCase("response")) {
-                        responseType = param.getValue();
-                        continue;
-                    }
-                    parameterMap.put(param.getName(), new String[]{param.getValue()});
-                }
-            }
-
-            // Get the type of http method being used.
-            parameterMap.put("httpmethod", new String[] {request.getRequestLine().getMethod()});
-
-            // Check responseType, if not among valid types, fallback to JSON
-            if (!(responseType.equals(HttpUtils.RESPONSE_TYPE_JSON) || responseType.equals(HttpUtils.RESPONSE_TYPE_XML))) {
-                responseType = HttpUtils.RESPONSE_TYPE_XML;
-            }
-            try {
-                //verify that parameter is legit for passing via admin port
-                String[] command = (String[]) parameterMap.get("command");
-                if (command != null) {
-                    Class<?> cmdClass = getCmdClass(command[0]);
-                    if (cmdClass != null) {
-                        List<Field> fields = ReflectUtil.getAllFieldsForClass(cmdClass, BaseCmd.class);
-                        for (Field field : fields) {
-                            Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
-                            if ((parameterAnnotation == null) || !parameterAnnotation.expose()) {
-                                continue;
-                            }
-                            Object paramObj = parameterMap.get(parameterAnnotation.name());
-                            if (paramObj != null) {
-                                if (!parameterAnnotation.acceptedOnAdminPort()) {
-                                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, "Parameter " + parameterAnnotation.name() + " can't be passed through the API integration port");
-                                }
-                            }
-                        }
-                    }
-                }
-                // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM
-                CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount());
-                sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") ");
-                final String responseText = handleRequest(parameterMap, responseType, sb);
-                sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length()));
-
-                writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null);
-            } catch (final ServerApiException se) {
-                final String responseText = getSerializedApiError(se, parameterMap, responseType);
-                writeResponse(response, responseText, se.getErrorCode().getHttpCode(), responseType, se.getDescription());
-                sb.append(" " + se.getErrorCode() + " " + se.getDescription());
-            } catch (final RuntimeException e) {
-                // log runtime exception like NullPointerException to help identify the source easier
-                s_logger.error("Unhandled exception, ", e);
-                throw e;
-            }
-        } finally {
-            s_accessLogger.info(sb.toString());
-            CallContext.unregister();
-        }
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public void checkCharacterInkParams(final Map params) {
-        final Map<String, String> stringMap = new HashMap<String, String>();
-        final Set keys = params.keySet();
-        final Iterator keysIter = keys.iterator();
-        while (keysIter.hasNext()) {
-            final String key = (String)keysIter.next();
-            final String[] value = (String[])params.get(key);
-            // fail if parameter value contains ASCII control (non-printable) characters
-            if (value[0] != null) {
-                final Pattern pattern = Pattern.compile(CONTROL_CHARACTERS);
-                final Matcher matcher = pattern.matcher(value[0]);
-                if (matcher.find()) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value containing illegal ASCII non-printable characters for parameter " + key);
-                }
-            }
-            stringMap.put(key, value[0]);
-        }
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    public String handleRequest(final Map params, final String responseType, final StringBuilder auditTrailSb) throws ServerApiException {
-        checkCharacterInkParams(params);
-
-        String response = null;
-        String[] command = null;
-
-        try {
-            command = (String[])params.get("command");
-            if (command == null) {
-                s_logger.error("invalid request, no command sent");
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("dumping request parameters");
-                    for (final  Object key : params.keySet()) {
-                        final String keyStr = (String)key;
-                        final String[] value = (String[])params.get(key);
-                        s_logger.trace("   key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0]));
-                    }
-                }
-                throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent");
-            } else {
-                // Don't allow Login/Logout APIs to go past this point
-                if (authManager.getAPIAuthenticator(command[0]) != null) {
-                    return null;
-                }
-                final Map<String, String> paramMap = new HashMap<String, String>();
-                final Set keys = params.keySet();
-                final Iterator keysIter = keys.iterator();
-                while (keysIter.hasNext()) {
-                    final String key = (String)keysIter.next();
-                    if ("command".equalsIgnoreCase(key)) {
-                        continue;
-                    }
-                    final String[] value = (String[])params.get(key);
-                    paramMap.put(key, value[0]);
-                }
-
-                Class<?> cmdClass = getCmdClass(command[0]);
-                if (cmdClass != null) {
-                    APICommand annotation = cmdClass.getAnnotation(APICommand.class);
-                    if (annotation == null) {
-                        s_logger.error("No APICommand annotation found for class " + cmdClass.getCanonicalName());
-                        throw new CloudRuntimeException("No APICommand annotation found for class " + cmdClass.getCanonicalName());
-                    }
-
-                    BaseCmd cmdObj = (BaseCmd)cmdClass.newInstance();
-                    cmdObj = ComponentContext.inject(cmdObj);
-                    cmdObj.configure();
-                    cmdObj.setFullUrlParams(paramMap);
-                    cmdObj.setResponseType(responseType);
-                    cmdObj.setHttpMethod(paramMap.get(ApiConstants.HTTPMETHOD).toString());
-
-                    // This is where the command is either serialized, or directly dispatched
-                    StringBuilder log = new StringBuilder();
-                    response = queueCommand(cmdObj, paramMap, log);
-                    buildAuditTrail(auditTrailSb, command[0], log.toString());
-                } else {
-                    final String errorString = "Unknown API command: " + command[0];
-                    s_logger.warn(errorString);
-                    auditTrailSb.append(" " + errorString);
-                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString);
-                }
-            }
-        } catch (final InvalidParameterValueException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
-        } catch (final IllegalArgumentException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
-        } catch (final PermissionDeniedException ex) {
-            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
-            if (idList != null) {
-                final StringBuffer buf = new StringBuffer();
-                for (final ExceptionProxyObject obj : idList) {
-                    buf.append(obj.getDescription());
-                    buf.append(":");
-                    buf.append(obj.getUuid());
-                    buf.append(" ");
-                }
-                s_logger.info("PermissionDenied: " + ex.getMessage() + " on objs: [" + buf.toString() + "]");
-            } else {
-                s_logger.info("PermissionDenied: " + ex.getMessage());
-            }
-            throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, ex.getMessage(), ex);
-        } catch (final AccountLimitException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.ACCOUNT_RESOURCE_LIMIT_ERROR, ex.getMessage(), ex);
-        } catch (final InsufficientCapacityException ex) {
-            s_logger.info(ex.getMessage());
-            String errorMsg = ex.getMessage();
-            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
-                // hide internal details to non-admin user for security reason
-                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
-            }
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, errorMsg, ex);
-        } catch (final ResourceAllocationException ex) {
-            s_logger.info(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage(), ex);
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.info(ex.getMessage());
-            String errorMsg = ex.getMessage();
-            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
-                // hide internal details to non-admin user for security reason
-                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
-            }
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, errorMsg, ex);
-        } catch (final ServerApiException ex) {
-            s_logger.info(ex.getDescription());
-            throw ex;
-        } catch (final Exception ex) {
-            s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command), ex);
-            String errorMsg = ex.getMessage();
-            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
-                // hide internal details to non-admin user for security reason
-                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
-            }
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg, ex);
-        }
-
-        return response;
-    }
-
-    private String getBaseAsyncResponse(final long jobId, final BaseAsyncCmd cmd) {
-        final AsyncJobResponse response = new AsyncJobResponse();
-
-        final AsyncJob job = entityMgr.findById(AsyncJob.class, jobId);
-        response.setJobId(job.getUuid());
-        response.setResponseName(cmd.getCommandName());
-        return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
-    }
-
-    private String getBaseAsyncCreateResponse(final long jobId, final BaseAsyncCreateCmd cmd, final String objectUuid) {
-        final CreateCmdResponse response = new CreateCmdResponse();
-        final AsyncJob job = entityMgr.findById(AsyncJob.class, jobId);
-        response.setJobId(job.getUuid());
-        response.setId(objectUuid);
-        response.setResponseName(cmd.getCommandName());
-        return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
-    }
-
-    private String queueCommand(final BaseCmd cmdObj, final Map<String, String> params, StringBuilder log) throws Exception {
-        final CallContext ctx = CallContext.current();
-        final Long callerUserId = ctx.getCallingUserId();
-        final Account caller = ctx.getCallingAccount();
-
-        // Queue command based on Cmd super class:
-        // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
-        // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd.
-        // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
-        if (cmdObj instanceof BaseAsyncCmd) {
-            Long objectId = null;
-            String objectUuid = null;
-            if (cmdObj instanceof BaseAsyncCreateCmd) {
-                final BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd)cmdObj;
-                dispatcher.dispatchCreateCmd(createCmd, params);
-                objectId = createCmd.getEntityId();
-                objectUuid = createCmd.getEntityUuid();
-                params.put("id", objectId.toString());
-                Class entityClass = EventTypes.getEntityClassForEvent(createCmd.getEventType());
-                if (entityClass != null)
-                    ctx.putContextParameter(entityClass, objectUuid);
-            } else {
-                // Extract the uuid before params are processed and id reflects internal db id
-                objectUuid = params.get(ApiConstants.ID);
-                dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
-            }
-
-            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmdObj;
-
-            if (callerUserId != null) {
-                params.put("ctxUserId", callerUserId.toString());
-            }
-            if (caller != null) {
-                params.put("ctxAccountId", String.valueOf(caller.getId()));
-            }
-            if (objectUuid != null) {
-                params.put("uuid", objectUuid);
-            }
-
-            long startEventId = ctx.getStartEventId();
-            asyncCmd.setStartEventId(startEventId);
-
-            // save the scheduled event
-            final Long eventId =
-                    ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? (Long)User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
-                            asyncCmd.getEventDescription(), asyncCmd.isDisplay(), startEventId);
-            if (startEventId == 0) {
-                // There was no create event before, set current event id as start eventId
-                startEventId = eventId;
-            }
-
-            params.put("ctxStartEventId", String.valueOf(startEventId));
-            params.put("cmdEventType", asyncCmd.getEventType().toString());
-            params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters()));
-
-            Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
-
-            // users can provide the job id they want to use, so log as it is a uuid and is unique
-            String injectedJobId = asyncCmd.getInjectedJobId();
-            uuidMgr.checkUuidSimple(injectedJobId, AsyncJob.class);
-
-            AsyncJobVO job = new AsyncJobVO("", callerUserId, caller.getId(), cmdObj.getClass().getName(),
-                    ApiGsonHelper.getBuilder().create().toJson(params), instanceId,
-                    asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null,
-                            injectedJobId);
-            job.setDispatcher(asyncDispatcher.getName());
-
-            final long jobId = asyncMgr.submitAsyncJob(job);
-
-            if (jobId == 0L) {
-                final String errorMsg = "Unable to schedule async job for command " + job.getCmd();
-                s_logger.warn(errorMsg);
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
-            }
-            final String response;
-            if (objectId != null) {
-                final String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
-                response = getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd)asyncCmd, objUuid);
-            } else {
-                SerializationContext.current().setUuidTranslation(true);
-                response = getBaseAsyncResponse(jobId, asyncCmd);
-            }
-            // Always log response for async for now, I don't think any sensitive data will be in here.
-            // It might be nice to send this through scrubbing similar to how
-            // ApiResponseSerializer.toSerializedStringWithSecureLogs works. For now, this gets jobid's
-            // in the api logs.
-            log.append(response);
-            return response;
-
-        } else {
-            dispatcher.dispatch(cmdObj, params, false);
-
-            // if the command is of the listXXXCommand, we will need to also return the
-            // the job id and status if possible
-            // For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views.
-            if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListVMsCmdByAdmin) && !(cmdObj instanceof ListRoutersCmd)
-                    && !(cmdObj instanceof ListSecurityGroupsCmd) &&
-                    !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) &&
-                    !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) &&
-                    !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListVolumesCmdByAdmin) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd)
-                    && !(cmdObj instanceof ListAccountsCmdByAdmin) &&
-                    !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) &&
-                    !(cmdObj instanceof ListZonesCmd) && !(cmdObj instanceof ListZonesCmdByAdmin)) {
-                buildAsyncListResponse((BaseListCmd)cmdObj, caller);
-            }
-
-            SerializationContext.current().setUuidTranslation(true);
-            return ApiResponseSerializer.toSerializedStringWithSecureLogs((ResponseObject)cmdObj.getResponseObject(), cmdObj.getResponseType(), log);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private void buildAsyncListResponse(final BaseListCmd command, final Account account) {
-        final List<ResponseObject> responses = ((ListResponse)command.getResponseObject()).getResponses();
-        if (responses != null && responses.size() > 0) {
-            List<? extends AsyncJob> jobs = null;
-
-            // list all jobs for ROOT admin
-            if (accountMgr.isRootAdmin(account.getId())) {
-                jobs = asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), null);
-            } else {
-                jobs = asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), account.getId());
-            }
-
-            if (jobs.size() == 0) {
-                return;
-            }
-
-            final Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>();
-            for (final AsyncJob job : jobs) {
-                if (job.getInstanceId() == null) {
-                    continue;
-                }
-                final String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
-                objectJobMap.put(instanceUuid, job);
-            }
-
-            for (final ResponseObject response : responses) {
-                if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
-                    final AsyncJob job = objectJobMap.get(response.getObjectId());
-                    response.setJobId(job.getUuid());
-                    response.setJobStatus(job.getStatus().ordinal());
-                }
-            }
-        }
-    }
-
-    private void buildAuditTrail(final StringBuilder auditTrailSb, final String command, final String result) {
-        if (result == null) {
-            return;
-        }
-        auditTrailSb.append(" " + HttpServletResponse.SC_OK + " ");
-        if (command.equals("createSSHKeyPair")) {
-            auditTrailSb.append("This result was not logged because it contains sensitive data.");
-        } else {
-            auditTrailSb.append(result);
-        }
-    }
-
-    @Override
-    public boolean verifyRequest(final Map<String, Object[]> requestParameters, final Long userId, InetAddress remoteAddress) throws ServerApiException {
-        try {
-            String apiKey = null;
-            String secretKey = null;
-            String signature = null;
-            String unsignedRequest = null;
-
-            final String[] command = (String[])requestParameters.get(ApiConstants.COMMAND);
-            if (command == null) {
-                s_logger.info("missing command, ignoring request...");
-                return false;
-            }
-
-            final String commandName = command[0];
-
-            // if userId not null, that mean that user is logged in
-            if (userId != null) {
-                final User user = ApiDBUtils.findUserById(userId);
-
-                if (!commandAvailable(remoteAddress, commandName, user)) {
-                    return false;
-                }
-
-                return true;
-            } else {
-                // check against every available command to see if the command exists or not
-                if (!s_apiNameCmdClassMap.containsKey(commandName) && !commandName.equals("login") && !commandName.equals("logout")) {
-                    final String errorMessage = "The given command " + commandName + " either does not exist, is not available" +
-                            " for user, or not available from ip address '" + remoteAddress.getHostAddress() + "'.";
-                    s_logger.debug(errorMessage);
-                    return false;
-                }
-            }
-
-            // - build a request string with sorted params, make sure it's all lowercase
-            // - sign the request, verify the signature is the same
-            final List<String> parameterNames = new ArrayList<String>();
-
-            for (final Object paramNameObj : requestParameters.keySet()) {
-                parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
-            }
-
-            Collections.sort(parameterNames);
-
-            String signatureVersion = null;
-            String expires = null;
-
-            for (final String paramName : parameterNames) {
-                // parameters come as name/value pairs in the form String/String[]
-                final String paramValue = ((String[])requestParameters.get(paramName))[0];
-
-                if (ApiConstants.SIGNATURE.equalsIgnoreCase(paramName)) {
-                    signature = paramValue;
-                } else {
-                    if (ApiConstants.API_KEY.equalsIgnoreCase(paramName)) {
-                        apiKey = paramValue;
-                    } else if (ApiConstants.SIGNATURE_VERSION.equalsIgnoreCase(paramName)) {
-                        signatureVersion = paramValue;
-                    } else if (ApiConstants.EXPIRES.equalsIgnoreCase(paramName)) {
-                        expires = paramValue;
-                    }
-
-                    if (unsignedRequest == null) {
-                        unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, HttpUtils.UTF_8).replaceAll("\\+", "%20");
-                    } else {
-                        unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, HttpUtils.UTF_8).replaceAll("\\+", "%20");
-                    }
-                }
-            }
-
-            // if api/secret key are passed to the parameters
-            if ((signature == null) || (apiKey == null)) {
-                s_logger.debug("Expired session, missing signature, or missing apiKey -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey);
-                return false; // no signature, bad request
-            }
-
-            Date expiresTS = null;
-            // FIXME: Hard coded signature, why not have an enum
-            if ("3".equals(signatureVersion)) {
-                // New signature authentication. Check for expire parameter and its validity
-                if (expires == null) {
-                    s_logger.debug("Missing Expires parameter -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey);
-                    return false;
-                }
-                synchronized (DateFormatToUse) {
-                    try {
-                        expiresTS = DateFormatToUse.parse(expires);
-                    } catch (final ParseException pe) {
-                        s_logger.debug("Incorrect date format for Expires parameter", pe);
-                        return false;
-                    }
-                }
-                final Date now = new Date(System.currentTimeMillis());
-                if (expiresTS.before(now)) {
-                    s_logger.debug("Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey);
-                    return false;
-                }
-            }
-
-            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
-            txn.close();
-            User user = null;
-            // verify there is a user with this api key
-            final Pair<User, Account> userAcctPair = accountMgr.findUserByApiKey(apiKey);
-            if (userAcctPair == null) {
-                s_logger.debug("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey);
-                return false;
-            }
-
-            user = userAcctPair.first();
-            final Account account = userAcctPair.second();
-
-            if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) {
-                s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() +
-                        "; accountState: " + account.getState());
-                return false;
-            }
-
-            if (!commandAvailable(remoteAddress, commandName, user)) {
-                return false;
-            }
-
-            // verify secret key exists
-            secretKey = user.getSecretKey();
-            if (secretKey == null) {
-                s_logger.info("User does not have a secret key associated with the account -- ignoring request, username: " + user.getUsername());
-                return false;
-            }
-
-            unsignedRequest = unsignedRequest.toLowerCase();
-
-            final Mac mac = Mac.getInstance("HmacSHA1");
-            final SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
-            mac.init(keySpec);
-            mac.update(unsignedRequest.getBytes());
-
-            final byte[] encryptedBytes = mac.doFinal();
-            final String computedSignature = Base64.encodeBase64String(encryptedBytes);
-            final boolean equalSig = ConstantTimeComparator.compareStrings(signature, computedSignature);
-
-            if (!equalSig) {
-                s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
-            } else {
-                CallContext.register(user, account);
-            }
-            return equalSig;
-        } catch (final ServerApiException ex) {
-            throw ex;
-        } catch (final Exception ex) {
-            s_logger.error("unable to verify request signature");
-        }
-        return false;
-    }
-
-    private boolean commandAvailable(final InetAddress remoteAddress, final String commandName, final User user) {
-        try {
-            checkCommandAvailable(user, commandName, remoteAddress);
-        } catch (final RequestLimitException ex) {
-            s_logger.debug(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage());
-        }  catch (final UnavailableCommandException ex) {
-            s_logger.debug(ex.getMessage());
-            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
-        } catch (final PermissionDeniedException ex) {
-            final String errorMessage = "The given command '" + commandName + "' either does not exist, is not available" +
-                    " for user, or not available from ip address '" + remoteAddress + "'.";
-            s_logger.debug(errorMessage);
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public Long fetchDomainId(final String domainUUID) {
-        final Domain domain = domainMgr.getDomain(domainUUID);
-        if (domain != null)
-            return domain.getId();
-        else
-            return null;
-    }
-
-    private ResponseObject createLoginResponse(HttpSession session) {
-        LoginCmdResponse response = new LoginCmdResponse();
-        response.setTimeout(session.getMaxInactiveInterval());
-
-        final String user_UUID = (String)session.getAttribute("user_UUID");
-        response.setUserId(user_UUID);
-
-        final String domain_UUID = (String)session.getAttribute("domain_UUID");
-        response.setDomainId(domain_UUID);
-
-        synchronized (session) {
-            session.removeAttribute("user_UUID");
-            session.removeAttribute("domain_UUID");
-        }
-
-        final Enumeration attrNames = session.getAttributeNames();
-        if (attrNames != null) {
-            while (attrNames.hasMoreElements()) {
-                final String attrName = (String) attrNames.nextElement();
-                final Object attrObj = session.getAttribute(attrName);
-                if (ApiConstants.USERNAME.equalsIgnoreCase(attrName)) {
-                    response.setUsername(attrObj.toString());
-                }
-                if (ApiConstants.ACCOUNT.equalsIgnoreCase(attrName)) {
-                    response.setAccount(attrObj.toString());
-                }
-                if (ApiConstants.FIRSTNAME.equalsIgnoreCase(attrName)) {
-                    response.setFirstName(attrObj.toString());
-                }
-                if (ApiConstants.LASTNAME.equalsIgnoreCase(attrName)) {
-                    response.setLastName(attrObj.toString());
-                }
-                if (ApiConstants.TYPE.equalsIgnoreCase(attrName)) {
-                    response.setType((attrObj.toString()));
-                }
-                if (ApiConstants.TIMEZONE.equalsIgnoreCase(attrName)) {
-                    response.setTimeZone(attrObj.toString());
-                }
-                if (ApiConstants.TIMEZONEOFFSET.equalsIgnoreCase(attrName)) {
-                    response.setTimeZoneOffset(attrObj.toString());
-                }
-                if (ApiConstants.REGISTERED.equalsIgnoreCase(attrName)) {
-                    response.setRegistered(attrObj.toString());
-                }
-                if (ApiConstants.SESSIONKEY.equalsIgnoreCase(attrName)) {
-                    response.setSessionKey(attrObj.toString());
-                }
-            }
-        }
-        response.setResponseName("loginresponse");
-        return response;
-    }
-
-    @Override
-    public ResponseObject loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final InetAddress loginIpAddress,
-            final Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
-        // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist
-        // we will default to ROOT
-        final Domain userDomain = domainMgr.findDomainByIdOrPath(domainId, domainPath);
-        if (userDomain == null || userDomain.getId() < 1L) {
-            throw new CloudAuthenticationException("Unable to find the domain from the path " + domainPath);
-        } else {
-            domainId = userDomain.getId();
-        }
-
-        final UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
-        if (userAcct != null) {
-            final String timezone = userAcct.getTimezone();
-            float offsetInHrs = 0f;
-            if (timezone != null) {
-                final TimeZone t = TimeZone.getTimeZone(timezone);
-                s_logger.info("Current user logged in under " + timezone + " timezone");
-
-                final java.util.Date date = new java.util.Date();
-                final long longDate = date.getTime();
-                final float offsetInMs = (t.getOffset(longDate));
-                offsetInHrs = offsetInMs / (1000 * 60 * 60);
-                s_logger.info("Timezone offset from UTC is: " + offsetInHrs);
-            }
-
-            final Account account = accountMgr.getAccount(userAcct.getAccountId());
-
-            // set the userId and account object for everyone
-            session.setAttribute("userid", userAcct.getId());
-            final UserVO user = (UserVO)accountMgr.getActiveUser(userAcct.getId());
-            if (user.getUuid() != null) {
-                session.setAttribute("user_UUID", user.getUuid());
-            }
-
-            session.setAttribute("username", userAcct.getUsername());
-            session.setAttribute("firstname", userAcct.getFirstname());
-            session.setAttribute("lastname", userAcct.getLastname());
-            session.setAttribute("accountobj", account);
-            session.setAttribute("account", account.getAccountName());
-
-            session.setAttribute("domainid", account.getDomainId());
-            final DomainVO domain = (DomainVO)domainMgr.getDomain(account.getDomainId());
-            if (domain.getUuid() != null) {
-                session.setAttribute("domain_UUID", domain.getUuid());
-            }
-
-            session.setAttribute("type", Short.valueOf(account.getType()).toString());
-            session.setAttribute("registrationtoken", userAcct.getRegistrationToken());
-            session.setAttribute("registered", Boolean.toString(userAcct.isRegistered()));
-
-            if (timezone != null) {
-                session.setAttribute("timezone", timezone);
-                session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString());
-            }
-
-            // (bug 5483) generate a session key that the user must submit on every request to prevent CSRF, add that
-            // to the login response so that session-based authenticators know to send the key back
-            final SecureRandom sesssionKeyRandom = new SecureRandom();
-            final byte sessionKeyBytes[] = new byte[20];
-            sesssionKeyRandom.nextBytes(sessionKeyBytes);
-            final String sessionKey = Base64.encodeBase64URLSafeString(sessionKeyBytes);
-            session.setAttribute(ApiConstants.SESSIONKEY, sessionKey);
-
-            return createLoginResponse(session);
-        }
-        throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials");
-    }
-
-    @Override
-    public void logoutUser(final long userId) {
-        accountMgr.logoutUser(userId);
-        return;
-    }
-
-    @Override
-    public boolean verifyUser(final Long userId) {
-        final User user = accountMgr.getUserIncludingRemoved(userId);
-        Account account = null;
-        if (user != null) {
-            account = accountMgr.getAccount(user.getAccountId());
-        }
-
-        if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) ||
-                !account.getState().equals(Account.State.enabled)) {
-            s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API");
-            return false;
-        }
-        return true;
-    }
-
-    private void checkCommandAvailable(final User user, final String commandName, final InetAddress remoteAddress) throws PermissionDeniedException {
-        if (user == null) {
-            throw new PermissionDeniedException("User is null for role based API access check for command" + commandName);
-        }
-
-        final Account account = accountMgr.getAccount(user.getAccountId());
-        final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s","");
-        final Boolean apiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
-
-        if (apiSourceCidrChecksEnabled) {
-            s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs);
-            if (!NetUtils.isIpInCidrList(remoteAddress, accessAllowedCidrs.split(","))) {
-                s_logger.warn("Request by account '" + account.toString() + "' was denied since " + remoteAddress + " does not match " + accessAllowedCidrs);
-                throw new PermissionDeniedException("Calls for domain '" + account.getAccountName() + "' are not allowed from ip address '" + remoteAddress.getHostAddress());
-                }
-        }
-
-
-        for (final APIChecker apiChecker : apiAccessCheckers) {
-            apiChecker.checkAccess(user, commandName);
-        }
-    }
-
-    @Override
-    public Class<?> getCmdClass(String cmdName) {
-        List<Class<?>> cmdList = s_apiNameCmdClassMap.get(cmdName);
-        if (cmdList == null || cmdList.size() == 0)
-            return null;
-        else if (cmdList.size() == 1)
-            return cmdList.get(0);
-        else {
-            // determine the cmd class based on calling context
-            ResponseView view = ResponseView.Restricted;
-            if (CallContext.current() != null
-                    && accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
-                view = ResponseView.Full;
-            }
-            for (Class<?> cmdClass : cmdList) {
-                APICommand at = cmdClass.getAnnotation(APICommand.class);
-                if (at == null) {
-                    throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName()));
-                }
-                if (at.responseView() == null) {
-                    throw new CloudRuntimeException(String.format(
-                            "%s @APICommand annotation should specify responseView attribute to distinguish multiple command classes for a single api name", cmdClass.getName()));
-                } else if (at.responseView() == view) {
-                    return cmdClass;
-                }
-            }
-            return null;
-        }
-    }
-
-    // FIXME: rather than isError, we might was to pass in the status code to give more flexibility
-    private void writeResponse(final HttpResponse resp, final String responseText, final int statusCode, final String responseType, final String reasonPhrase) {
-        try {
-            resp.setStatusCode(statusCode);
-            resp.setReasonPhrase(reasonPhrase);
-
-            final BasicHttpEntity body = new BasicHttpEntity();
-            if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
-                // JSON response
-                body.setContentType(JSONcontentType.value());
-                if (responseText == null) {
-                    body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes(HttpUtils.UTF_8)));
-                }
-            } else {
-                body.setContentType("text/xml");
-                if (responseText == null) {
-                    body.setContent(new ByteArrayInputStream("<error>Internal Server Error</error>".getBytes(HttpUtils.UTF_8)));
-                }
-            }
-
-            if (responseText != null) {
-                body.setContent(new ByteArrayInputStream(responseText.getBytes(HttpUtils.UTF_8)));
-            }
-            resp.setEntity(body);
-        } catch (final Exception ex) {
-            s_logger.error("error!", ex);
-        }
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ApiServer.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] { EnableSecureSessionCookie, JSONcontentType };
-    }
-
-    // FIXME: the following two threads are copied from
-    // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
-    // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or
-    // modify the
-    // code to be very specific to our needs
-    static class ListenerThread extends Thread {
-        private HttpService _httpService = null;
-        private ServerSocket _serverSocket = null;
-        private HttpParams _params = null;
-
-        public ListenerThread(final ApiServer requestHandler, final int port) {
-            try {
-                _serverSocket = new ServerSocket(port);
-            } catch (final IOException ioex) {
-                s_logger.error("error initializing api server", ioex);
-                return;
-            }
-
-            _params = new BasicHttpParams();
-            _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
-            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
-            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
-            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
-
-            // Set up the HTTP protocol processor
-            final BasicHttpProcessor httpproc = new BasicHttpProcessor();
-            httpproc.addInterceptor(new ResponseDate());
-            httpproc.addInterceptor(new ResponseServer());
-            httpproc.addInterceptor(new ResponseContent());
-            httpproc.addInterceptor(new ResponseConnControl());
-
-            // Set up request handlers
-            final HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
-            reqistry.register("*", requestHandler);
-
-            // Set up the HTTP service
-            _httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory());
-            _httpService.setParams(_params);
-            _httpService.setHandlerResolver(reqistry);
-        }
-
-        @Override
-        public void run() {
-            s_logger.info("ApiServer listening on port " + _serverSocket.getLocalPort());
-            while (!Thread.interrupted()) {
-                try {
-                    // Set up HTTP connection
-                    final Socket socket = _serverSocket.accept();
-                    final DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
-                    conn.bind(socket, _params);
-
-                    // Execute a new worker task to handle the request
-                    s_executor.execute(new WorkerTask(_httpService, conn, s_workerCount++));
-                } catch (final InterruptedIOException ex) {
-                    break;
-                } catch (final IOException e) {
-                    s_logger.error("I/O error initializing connection thread", e);
-                    break;
-                }
-            }
-        }
-    }
-
-    static class WorkerTask extends ManagedContextRunnable {
-        private final HttpService _httpService;
-        private final HttpServerConnection _conn;
-
-        public WorkerTask(final HttpService httpService, final HttpServerConnection conn, final int count) {
-            _httpService = httpService;
-            _conn = conn;
-        }
-
-        @Override
-        protected void runInContext() {
-            final HttpContext context = new BasicHttpContext(null);
-            try {
-                while (!Thread.interrupted() && _conn.isOpen()) {
-                    _httpService.handleRequest(_conn, context);
-                    _conn.close();
-                }
-            } catch (final ConnectionClosedException ex) {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("ApiServer:  Client closed connection");
-                }
-            } catch (final IOException ex) {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("ApiServer:  IOException - " + ex);
-                }
-            } catch (final HttpException ex) {
-                s_logger.warn("ApiServer:  Unrecoverable HTTP protocol violation" + ex);
-            } finally {
-                try {
-                    _conn.shutdown();
-                } catch (final IOException ignore) {
-                }
-            }
-        }
-    }
-
-    @Override
-    public String getSerializedApiError(final int errorCode, final String errorText, final Map<String, Object[]> apiCommandParams, final String responseType) {
-        String responseName = null;
-        Class<?> cmdClass = null;
-        String responseText = null;
-
-        try {
-            if (apiCommandParams == null || apiCommandParams.isEmpty()) {
-                responseName = "errorresponse";
-            } else {
-                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
-                // cmd name can be null when "command" parameter is missing in the request
-                if (cmdObj != null) {
-                    final String cmdName = ((String[])cmdObj)[0];
-                    cmdClass = getCmdClass(cmdName);
-                    if (cmdClass != null) {
-                        responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
-                    } else {
-                        responseName = "errorresponse";
-                    }
-                }
-            }
-            final ExceptionResponse apiResponse = new ExceptionResponse();
-            apiResponse.setErrorCode(errorCode);
-            apiResponse.setErrorText(errorText);
-            apiResponse.setResponseName(responseName);
-            SerializationContext.current().setUuidTranslation(true);
-            responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
-
-        } catch (final Exception e) {
-            s_logger.error("Exception responding to http request", e);
-        }
-        return responseText;
-    }
-
-    @Override
-    public String getSerializedApiError(final ServerApiException ex, final Map<String, Object[]> apiCommandParams, final String responseType) {
-        String responseName = null;
-        Class<?> cmdClass = null;
-        String responseText = null;
-
-        if (ex == null) {
-            // this call should not be invoked with null exception
-            return getSerializedApiError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Some internal error happened", apiCommandParams, responseType);
-        }
-        try {
-            if (ex.getErrorCode() == ApiErrorCode.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) {
-                responseName = "errorresponse";
-            } else {
-                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
-                // cmd name can be null when "command" parameter is missing in
-                // the request
-                if (cmdObj != null) {
-                    final String cmdName = ((String[])cmdObj)[0];
-                    cmdClass = getCmdClass(cmdName);
-                    if (cmdClass != null) {
-                        responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
-                    } else {
-                        responseName = "errorresponse";
-                    }
-                }
-            }
-            final ExceptionResponse apiResponse = new ExceptionResponse();
-            apiResponse.setErrorCode(ex.getErrorCode().getHttpCode());
-            apiResponse.setErrorText(ex.getDescription());
-            apiResponse.setResponseName(responseName);
-            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
-            if (idList != null) {
-                for (int i = 0; i < idList.size(); i++) {
-                    apiResponse.addProxyObject(idList.get(i));
-                }
-            }
-            // Also copy over the cserror code and the function/layer in which
-            // it was thrown.
-            apiResponse.setCSErrorCode(ex.getCSErrorCode());
-
-            SerializationContext.current().setUuidTranslation(true);
-            responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
-
-        } catch (final Exception e) {
-            s_logger.error("Exception responding to http request", e);
-        }
-        return responseText;
-    }
-
-    @Inject
-    public void setPluggableServices(final List<PluggableService> pluggableServices) {
-        this.pluggableServices = pluggableServices;
-    }
-
-    @Inject
-    public void setApiAccessCheckers(final List<APIChecker> apiAccessCheckers) {
-        this.apiAccessCheckers = apiAccessCheckers;
-    }
-
-    public static boolean isEncodeApiResponse() {
-        return ApiServer.encodeApiResponse;
-    }
-
-    private static void setEncodeApiResponse(final boolean encodeApiResponse) {
-        ApiServer.encodeApiResponse = encodeApiResponse;
-    }
-
-}
diff --git a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
deleted file mode 100644
index 6509d11..0000000
--- a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.api.dispatch;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.log4j.Logger;
-
-/**
- * This worker validates parameters in a generic way, by using annotated
- * restrictions without involving the {@Link BaseCmd}. This worker doesn't
- * know or care about the meaning of the parameters and that's why we can
- * have it out of the {@Link BaseCmd}
- *
- * @author afornie
- */
-public class ParamGenericValidationWorker implements DispatchWorker {
-
-    static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
-
-    protected static final List<String> defaultParamNames = new ArrayList<String>();
-
-    static {
-        defaultParamNames.add(ApiConstants.ACCOUNT_ID);
-        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
-        defaultParamNames.add(ApiConstants.COMMAND);
-        defaultParamNames.add(ApiConstants.CMD_EVENT_TYPE);
-        defaultParamNames.add(ApiConstants.USERNAME);
-        defaultParamNames.add(ApiConstants.USER_ID);
-        defaultParamNames.add(ApiConstants.PASSWORD);
-        defaultParamNames.add(ApiConstants.DOMAIN);
-        defaultParamNames.add(ApiConstants.DOMAIN_ID);
-        defaultParamNames.add(ApiConstants.DOMAIN__ID);
-        defaultParamNames.add(ApiConstants.SESSIONKEY);
-        defaultParamNames.add(ApiConstants.RESPONSE);
-        defaultParamNames.add(ApiConstants.PAGE);
-        defaultParamNames.add(ApiConstants.USER_API_KEY);
-        defaultParamNames.add(ApiConstants.API_KEY);
-        defaultParamNames.add(ApiConstants.PAGE_SIZE);
-        defaultParamNames.add(ApiConstants.HTTPMETHOD);
-        defaultParamNames.add(ApiConstants.SIGNATURE);
-        defaultParamNames.add(ApiConstants.CTX_ACCOUNT_ID);
-        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
-        defaultParamNames.add(ApiConstants.CTX_USER_ID);
-        defaultParamNames.add(ApiConstants.CTX_DETAILS);
-        defaultParamNames.add(ApiConstants.UUID);
-        defaultParamNames.add(ApiConstants.ID);
-        defaultParamNames.add("_");
-    }
-
-    protected static final String ERROR_MSG_PREFIX = "Unknown parameters :";
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    public void handle(final DispatchTask task) {
-        final BaseCmd cmd = task.getCmd();
-        final Map params = task.getParams();
-
-        final List<String> expectedParamNames = getParamNamesForCommand(cmd);
-
-        final StringBuilder errorMsg = new StringBuilder(ERROR_MSG_PREFIX);
-        boolean foundUnknownParam = false;
-        for (final Object actualParamName : params.keySet()) {
-            // If none of the expected params matches, we have an unknown param
-            boolean matchedCurrentParam = false;
-            for (final String expectedName : expectedParamNames) {
-                if (expectedName.equalsIgnoreCase((String) actualParamName)) {
-                    matchedCurrentParam = true;
-                    break;
-                }
-            }
-            if (!matchedCurrentParam && !((String)actualParamName).equalsIgnoreCase("expires") && !((String)actualParamName).equalsIgnoreCase("signatureversion")) {
-                errorMsg.append(" ").append(actualParamName);
-                foundUnknownParam= true;
-            }
-        }
-
-        if (foundUnknownParam) {
-            s_logger.warn(String.format("Received unknown parameters for command %s. %s", cmd.getActualCommandName(), errorMsg));
-        }
-    }
-
-    protected List<String> getParamNamesForCommand(final BaseCmd cmd) {
-        final List<String> paramNames = new ArrayList<String>();
-        // The expected param names are all the specific for the current command class ...
-        for (final Field field : cmd.getParamFields()) {
-            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
-            paramNames.add(parameterAnnotation.name());
-        }
-        // ... plus the default ones
-        paramNames.addAll(defaultParamNames);
-        return paramNames;
-    }
-}
diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java
deleted file mode 100644
index feefaab..0000000
--- a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java
+++ /dev/null
@@ -1,511 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.api.dispatch;
-
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-
-import java.lang.reflect.Field;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.text.SimpleDateFormat;
-
-import javax.inject.Inject;
-
-import com.google.common.base.Strings;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.InfrastructureEntity;
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseCmd.CommandType;
-import org.apache.cloudstack.api.EntityReference;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.ApiArgValidator;
-import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
-import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
-import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
-import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
-import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class ParamProcessWorker implements DispatchWorker {
-
-    private static final Logger s_logger = Logger.getLogger(ParamProcessWorker.class.getName());
-    public final DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
-    public final DateFormat newInputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
-    @Inject
-    protected AccountManager _accountMgr;
-
-    @Inject
-    protected EntityManager _entityMgr;
-
-    List<SecurityChecker> _secChecker;
-
-    public List<SecurityChecker> getSecChecker() {
-        return _secChecker;
-    }
-
-    @Inject
-    public void setSecChecker(List<SecurityChecker> secChecker) {
-        _secChecker = secChecker;
-    }
-
-    @Override
-    public void handle(final DispatchTask task) {
-        processParameters(task.getCmd(), task.getParams());
-    }
-
-    private void validateNonEmptyString(final Object param, final String argName) {
-        if (param == null || Strings.isNullOrEmpty(param.toString())) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Empty or null value provided for API arg: %s", argName));
-        }
-    }
-
-    private void validateNaturalNumber(final Object param, final String argName) {
-        Long value = null;
-        if (param != null && param instanceof Long) {
-            value = (Long) param;
-        } else if (param != null) {
-            value = Long.valueOf(param.toString());
-        }
-        if (value == null || value < 1L) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Invalid value provided for API arg: %s", argName));
-        }
-    }
-
-    private void validateField(final Object paramObj, final Parameter annotation) throws ServerApiException {
-        if (annotation == null) {
-            return;
-        }
-        final String argName = annotation.name();
-        for (final ApiArgValidator validator : annotation.validations()) {
-            if (validator == null) {
-                continue;
-            }
-            switch (validator) {
-                case NotNullOrEmpty:
-                    switch (annotation.type()) {
-                        case UUID:
-                        case STRING:
-                            validateNonEmptyString(paramObj, argName);
-                            break;
-                    }
-                    break;
-                case PositiveNumber:
-                    switch (annotation.type()) {
-                        case SHORT:
-                        case INTEGER:
-                        case LONG:
-                            validateNaturalNumber(paramObj, argName);
-                            break;
-                    }
-                    break;
-            }
-        }
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public void processParameters(final BaseCmd cmd, final Map params) {
-        final Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
-
-        final List<Field> cmdFields = cmd.getParamFields();
-
-        for (final Field field : cmdFields) {
-            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
-            final Object paramObj = params.get(parameterAnnotation.name());
-            if (paramObj == null) {
-                if (parameterAnnotation.required()) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                            cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) +
-                            " due to missing parameter " + parameterAnnotation.name());
-                }
-                continue;
-            }
-
-            // marshall the parameter into the correct type and set the field value
-            try {
-                validateField(paramObj, parameterAnnotation);
-                setFieldValue(field, cmd, paramObj, parameterAnnotation);
-            } catch (final IllegalArgumentException argEx) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Unable to execute API command " + cmd.getCommandName() + " due to invalid value " + paramObj + " for parameter " +
-                            parameterAnnotation.name());
-                }
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value " + paramObj + " for parameter " +
-                        parameterAnnotation.name());
-            } catch (final ParseException parseEx) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
-                }
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " +
-                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + ", please pass dates in the format mentioned in the api documentation");
-            } catch (final InvalidParameterValueException invEx) {
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
-                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value. " + invEx.getMessage());
-            } catch (final CloudRuntimeException cloudEx) {
-                s_logger.error("CloudRuntimeException", cloudEx);
-                // FIXME: Better error message? This only happens if the API command is not executable, which typically
-                //means
-                // there was
-                // and IllegalAccessException setting one of the parameters.
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal error executing API command " +
-                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
-            }
-
-            //check access on the resource this field points to
-            try {
-                final ACL checkAccess = field.getAnnotation(ACL.class);
-                final CommandType fieldType = parameterAnnotation.type();
-
-                if (checkAccess != null) {
-                    // Verify that caller can perform actions in behalf of vm
-                    // owner acumulate all Controlled Entities together.
-                    // parse the array of resource types and in case of map
-                    // check access on key or value or both as specified in @acl
-                    // implement external dao for classes that need findByName
-                    // for maps, specify access to be checkd on key or value.
-                    // Find the controlled entity DBid by uuid
-
-                    if (parameterAnnotation.entityType() != null && parameterAnnotation.entityType().length > 0
-                            && parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class) != null) {
-                        final Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
-
-                        // Check if the parameter type is a single
-                        // Id or list of id's/name's
-                        switch (fieldType) {
-                        case LIST:
-                            final CommandType listType = parameterAnnotation.collectionType();
-                            switch (listType) {
-                            case LONG:
-                            case UUID:
-                                final List<Long> listParam = (List<Long>) field.get(cmd);
-                                for (final Long entityId : listParam) {
-                                    for (final Class entity : entityList) {
-                                        final Object entityObj = _entityMgr.findById(entity, entityId);
-                                        if(entityObj != null){
-                                            entitiesToAccess.put(entityObj, checkAccess.accessType());
-                                            break;
-                                        }
-                                    }
-                                }
-                                break;
-                                /*
-                                 * case STRING: List<String> listParam = new
-                                 * ArrayList<String>(); listParam =
-                                 * (List)field.get(cmd); for(String entityName:
-                                 * listParam){ ControlledEntity entityObj =
-                                 * (ControlledEntity )daoClassInstance(entityId);
-                                 * entitiesToAccess.add(entityObj); } break;
-                                 */
-                            default:
-                                break;
-                            }
-                            break;
-                        case LONG:
-                        case UUID:
-                            for (final Class entity : entityList) {
-                                final Object entityObj = _entityMgr.findById(entity, (Long) field.get(cmd));
-                                if(entityObj != null){
-                                    entitiesToAccess.put(entityObj, checkAccess.accessType());
-                                    break;
-                                }
-                            }
-                            break;
-                        default:
-                            break;
-                        }
-                    }
-                }
-
-            } catch (final IllegalArgumentException e) {
-                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
-                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
-                        " is not accessible]");
-            } catch (final IllegalAccessException e) {
-                s_logger.error("Error initializing command " + cmd.getCommandName() + ", field " + field.getName() + " is not accessible.");
-                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
-                        " is not accessible]");
-            }
-
-        }
-
-        doAccessChecks(cmd, entitiesToAccess);
-    }
-
-
-    private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
-        Account caller = CallContext.current().getCallingAccount();
-        // due to deleteAccount design flaw CLOUDSTACK-6588, we should still include those removed account as well to clean up leftover resources from that account
-        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
-
-        if (cmd instanceof BaseAsyncCreateCmd) {
-            // check that caller can access the owner account.
-            _accountMgr.checkAccess(caller, null, false, owner);
-        }
-
-        if (!entitiesToAccess.isEmpty()) {
-            // check that caller can access the owner account.
-            _accountMgr.checkAccess(caller, null, false, owner);
-            for (Map.Entry<Object,AccessType>entry : entitiesToAccess.entrySet()) {
-                Object entity = entry.getKey();
-                if (entity instanceof ControlledEntity) {
-                    _accountMgr.checkAccess(caller, entry.getValue(), true, (ControlledEntity) entity);
-                } else if (entity instanceof InfrastructureEntity) {
-                    // FIXME: Move this code in adapter, remove code from
-                    // Account manager
-                }
-            }
-        }
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object paramObj, final Parameter annotation) throws IllegalArgumentException, ParseException {
-        try {
-            field.setAccessible(true);
-            final CommandType fieldType = annotation.type();
-            switch (fieldType) {
-            case BOOLEAN:
-                field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
-                break;
-            case DATE:
-                // This piece of code is for maintaining backward compatibility
-                // and support both the date formats(Bug 9724)
-                if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd ||
-                        cmdObj instanceof ArchiveAlertsCmd || cmdObj instanceof DeleteAlertsCmd || cmdObj instanceof GetUsageRecordsCmd) {
-                    final boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
-                    if (isObjInNewDateFormat) {
-                        final DateFormat newFormat = newInputFormat;
-                        synchronized (newFormat) {
-                            field.set(cmdObj, newFormat.parse(paramObj.toString()));
-                        }
-                    } else {
-                        final DateFormat format = inputFormat;
-                        synchronized (format) {
-                            Date date = format.parse(paramObj.toString());
-                            if (field.getName().equals("startDate")) {
-                                date = messageDate(date, 0, 0, 0);
-                            } else if (field.getName().equals("endDate")) {
-                                date = messageDate(date, 23, 59, 59);
-                            }
-                            field.set(cmdObj, date);
-                        }
-                    }
-                } else {
-                    final DateFormat format = inputFormat;
-                    synchronized (format) {
-                        format.setLenient(false);
-                        field.set(cmdObj, format.parse(paramObj.toString()));
-                    }
-                }
-                break;
-            case FLOAT:
-                // Assuming that the parameters have been checked for required before now,
-                // we ignore blank or null values and defer to the command to set a default
-                // value for optional parameters ...
-                if (paramObj != null && isNotBlank(paramObj.toString())) {
-                    field.set(cmdObj, Float.valueOf(paramObj.toString()));
-                }
-                break;
-            case DOUBLE:
-                // Assuming that the parameters have been checked for required before now,
-                // we ignore blank or null values and defer to the command to set a default
-                // value for optional parameters ...
-                if (paramObj != null && isNotBlank(paramObj.toString())) {
-                    field.set(cmdObj, Double.valueOf(paramObj.toString()));
-                }
-                break;
-            case INTEGER:
-                // Assuming that the parameters have been checked for required before now,
-                // we ignore blank or null values and defer to the command to set a default
-                // value for optional parameters ...
-                if (paramObj != null && isNotBlank(paramObj.toString())) {
-                    field.set(cmdObj, Integer.valueOf(paramObj.toString()));
-                }
-                break;
-            case LIST:
-                final List listParam = new ArrayList();
-                final StringTokenizer st = new StringTokenizer(paramObj.toString(), ",");
-                while (st.hasMoreTokens()) {
-                    final String token = st.nextToken();
-                    final CommandType listType = annotation.collectionType();
-                    switch (listType) {
-                    case INTEGER:
-                        listParam.add(Integer.valueOf(token));
-                        break;
-                    case UUID:
-                        if (token.isEmpty())
-                            break;
-                        final Long internalId = translateUuidToInternalId(token, annotation);
-                        listParam.add(internalId);
-                        break;
-                    case LONG: {
-                        listParam.add(Long.valueOf(token));
-                    }
-                    break;
-                    case SHORT:
-                        listParam.add(Short.valueOf(token));
-                        break;
-                    case STRING:
-                        listParam.add(token);
-                        break;
-                    }
-                }
-                field.set(cmdObj, listParam);
-                break;
-            case UUID:
-                final Long internalId = translateUuidToInternalId(paramObj.toString(), annotation);
-                field.set(cmdObj, internalId);
-                break;
-            case LONG:
-                field.set(cmdObj, Long.valueOf(paramObj.toString()));
-                break;
-            case SHORT:
-                field.set(cmdObj, Short.valueOf(paramObj.toString()));
-                break;
-            case STRING:
-                if ((paramObj != null)) {
-                    if (paramObj.toString().length() > annotation.length()) {
-                        s_logger.error("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
-                        throw new InvalidParameterValueException("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
-                    } else {
-                        field.set(cmdObj, paramObj.toString());
-                    }
-                }
-                break;
-            case TZDATE:
-                field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString()));
-                break;
-            case MAP:
-            default:
-                field.set(cmdObj, paramObj);
-                break;
-            }
-        } catch (final IllegalAccessException ex) {
-            s_logger.error("Error initializing command " + cmdObj.getCommandName() + ", field " + field.getName() + " is not accessible.");
-            throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() +
-                    " is not accessible]");
-        }
-    }
-
-    private boolean isObjInNewDateFormat(final String string) {
-        final Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
-        return matcher.matches();
-    }
-
-    private Date messageDate(final Date date, final int hourOfDay, final int minute, final int second) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
-        cal.set(Calendar.MINUTE, minute);
-        cal.set(Calendar.SECOND, second);
-        return cal.getTime();
-    }
-
-    private Long translateUuidToInternalId(final String uuid, final Parameter annotation) {
-        if (uuid.equals("-1")) {
-            // FIXME: This is to handle a lot of hardcoded special cases where -1 is sent
-            // APITODO: Find and get rid of all hardcoded params in API Cmds and service layer
-            return -1L;
-        }
-        Long internalId = null;
-        // If annotation's empty, the cmd existed before 3.x try conversion to long
-        final boolean isPre3x = annotation.since().isEmpty();
-        // Match against Java's UUID regex to check if input is uuid string
-        final boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
-        // Enforce that it's uuid for newly added apis from version 3.x
-        if (!isPre3x && !isUuid)
-            return null;
-
-        // There may be multiple entities defined on the @EntityReference of a Response.class
-        // UUID CommandType would expect only one entityType, so use the first entityType
-        final Class<?>[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value();
-
-        // Allow both uuid and internal id for pre3x apis
-        if (isPre3x && !isUuid) {
-            try {
-                internalId = Long.parseLong(uuid);
-            } catch (final NumberFormatException e) {
-                internalId = null;
-            }
-            if (internalId != null){
-                // Populate CallContext for each of the entity.
-                for (final Class<?> entity : entities) {
-                    CallContext.current().putContextParameter(entity, internalId);
-                }
-                validateNaturalNumber(internalId, annotation.name());
-                return internalId;
-            }
-        }
-
-        // Go through each entity which is an interface to a VO class and get a VO object
-        // Try to getId() for the object using reflection, break on first non-null value
-        for (final Class<?> entity : entities) {
-            // For backward compatibility, we search within removed entities and let service layer deal
-            // with removed ones, return empty response or error
-            final Object objVO = _entityMgr.findByUuidIncludingRemoved(entity, uuid);
-            if (objVO == null) {
-                continue;
-            }
-            // Invoke the getId method, get the internal long ID
-            // If that fails hide exceptions as the uuid may not exist                                         s
-            try {
-                internalId = ((InternalIdentity)objVO).getId();
-            } catch (final IllegalArgumentException e) {
-            } catch (final NullPointerException e) {
-            }
-            // Return on first non-null Id for the uuid entity
-            if (internalId != null){
-                CallContext.current().putContextParameter(entity, uuid);
-                break;
-            }
-        }
-        if (internalId == null) {
-            if (s_logger.isDebugEnabled())
-                s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
-            throw new InvalidParameterValueException("Invalid parameter " + annotation.name() + " value=" + uuid +
-                    " due to incorrect long value format, or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.");
-        }
-        validateNaturalNumber(internalId, annotation.name());
-        return internalId;
-    }
-}
diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java
deleted file mode 100644
index 9246edd..0000000
--- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java
+++ /dev/null
@@ -1,439 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.doc;
-
-import com.cloud.alert.AlertManager;
-import com.cloud.serializer.Param;
-import com.cloud.utils.IteratorUtil;
-import com.cloud.utils.ReflectUtil;
-import com.google.gson.annotations.SerializedName;
-import com.thoughtworks.xstream.XStream;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.IPAddressResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.SnapshotResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.log4j.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-public class ApiXmlDocWriter {
-    public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName());
-
-    private static String s_dirName = "";
-    private static Map<String, Class<?>> s_apiNameCmdClassMap = new HashMap<String, Class<?>>();
-    private static LinkedHashMap<Object, String> s_allApiCommands = new LinkedHashMap<Object, String>();
-    private static TreeMap<Object, String> s_allApiCommandsSorted = new TreeMap<Object, String>();
-    private static final List<String> AsyncResponses = setAsyncResponses();
-
-    private static List<String> setAsyncResponses() {
-        List<String> asyncResponses = new ArrayList<String>();
-        asyncResponses.add(TemplateResponse.class.getName());
-        asyncResponses.add(VolumeResponse.class.getName());
-        //asyncResponses.add(LoadBalancerResponse.class.getName());
-        asyncResponses.add(HostResponse.class.getName());
-        asyncResponses.add(IPAddressResponse.class.getName());
-        asyncResponses.add(StoragePoolResponse.class.getName());
-        asyncResponses.add(UserVmResponse.class.getName());
-        asyncResponses.add(SecurityGroupResponse.class.getName());
-        //asyncResponses.add(ExternalLoadBalancerResponse.class.getName());
-        asyncResponses.add(SnapshotResponse.class.getName());
-
-        return asyncResponses;
-    }
-
-    public static void main(String[] args) {
-        Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[] {"org.apache.cloudstack.api", "com.cloud.api",
-                "com.cloud.api.commands", "com.globo.globodns.cloudstack.api", "org.apache.cloudstack.network.opendaylight.api",
-                "com.cloud.api.commands.netapp", "org.apache.cloudstack.api.command.admin.zone", "org.apache.cloudstack.network.contrail.api.command"});
-
-        for (Class<?> cmdClass : cmdClasses) {
-            if(cmdClass.getAnnotation(APICommand.class)==null){
-               System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has no APICommand annotation ");
-               continue;
-            }
-            String apiName = cmdClass.getAnnotation(APICommand.class).name();
-            if (s_apiNameCmdClassMap.containsKey(apiName)) {
-                // handle API cmd separation into admin cmd and user cmd with the common api name
-                Class<?> curCmd = s_apiNameCmdClassMap.get(apiName);
-                if (curCmd.isAssignableFrom(cmdClass)) {
-                    // api_cmd map always keep the admin cmd class to get full response and parameters
-                    s_apiNameCmdClassMap.put(apiName, cmdClass);
-                } else if (cmdClass.isAssignableFrom(curCmd)) {
-                    // just skip this one without warning
-                    continue;
-                } else {
-                    System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has non-unique apiname " + apiName);
-                    continue;
-                }
-            } else {
-                s_apiNameCmdClassMap.put(apiName, cmdClass);
-            }
-        }
-        System.out.printf("Scanned and found %d APIs\n", s_apiNameCmdClassMap.size());
-        List<String> argsList = Arrays.asList(args);
-        Iterator<String> iter = argsList.iterator();
-        while (iter.hasNext()) {
-            String arg = iter.next();
-            if (arg.equals("-d")) {
-                s_dirName = iter.next();
-            }
-        }
-
-        for (Map.Entry<String, Class<?>> entry: s_apiNameCmdClassMap.entrySet()) {
-            Class<?> cls = entry.getValue();
-            s_allApiCommands.put(entry.getKey(), cls.getName());
-        }
-
-        s_allApiCommandsSorted.putAll(s_allApiCommands);
-
-        try {
-            // Create object writer
-            XStream xs = new XStream();
-            xs.alias("command", Command.class);
-            xs.alias("arg", Argument.class);
-            String xmlDocDir = s_dirName + "/xmldoc";
-            String rootAdminDirName = xmlDocDir + "/apis";
-            (new File(rootAdminDirName)).mkdirs();
-
-            ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(s_dirName + "/commands.xml"), "commands");
-            ObjectOutputStream rootAdmin = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "apiSummary.xml"), "commands");
-            ObjectOutputStream rootAdminSorted = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "apiSummarySorted.xml"), "commands");
-
-            Iterator<?> it = s_allApiCommands.keySet().iterator();
-            while (it.hasNext()) {
-                String key = (String)it.next();
-                // Write admin commands
-                writeCommand(out, key);
-                writeCommand(rootAdmin, key);
-                // Write single commands to separate xml files
-                ObjectOutputStream singleRootAdminCommandOs = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + key + ".xml"), "command");
-                writeCommand(singleRootAdminCommandOs, key);
-                singleRootAdminCommandOs.close();
-            }
-
-            // Write sorted commands
-            it = s_allApiCommandsSorted.keySet().iterator();
-            while (it.hasNext()) {
-                String key = (String)it.next();
-                writeCommand(rootAdminSorted, key);
-            }
-
-            out.close();
-            rootAdmin.close();
-            rootAdminSorted.close();
-
-            // write alerttypes to xml
-            writeAlertTypes(xmlDocDir);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            System.exit(2);
-        }
-    }
-
-    private static void writeCommand(ObjectOutputStream out, String command) throws ClassNotFoundException, IOException {
-        Class<?> clas = Class.forName(s_allApiCommands.get(command));
-        ArrayList<Argument> request = new ArrayList<Argument>();
-        ArrayList<Argument> response = new ArrayList<Argument>();
-
-        // Create a new command, set name/description/usage
-        Command apiCommand = new Command();
-        apiCommand.setName(command);
-
-        APICommand impl = clas.getAnnotation(APICommand.class);
-        if (impl == null) {
-            impl = clas.getSuperclass().getAnnotation(APICommand.class);
-        }
-
-        if (impl == null) {
-            throw new IllegalStateException(String.format("An %1$s annotation is required for class %2$s.", APICommand.class.getCanonicalName(), clas.getCanonicalName()));
-        }
-
-        if (impl.includeInApiDoc()) {
-            String commandDescription = impl.description();
-            if (commandDescription != null && !commandDescription.isEmpty()) {
-                apiCommand.setDescription(commandDescription);
-            } else {
-                System.out.println("Command " + apiCommand.getName() + " misses description");
-            }
-
-            String commandUsage = impl.usage();
-            if (commandUsage != null && !commandUsage.isEmpty()) {
-                apiCommand.setUsage(commandUsage);
-            }
-
-            //Set version when the API is added
-            if (!impl.since().isEmpty()) {
-                apiCommand.setSinceVersion(impl.since());
-            }
-
-            boolean isAsync = ReflectUtil.isCmdClassAsync(clas, new Class<?>[] {BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
-
-            apiCommand.setAsync(isAsync);
-
-            Set<Field> fields = ReflectUtil.getAllFieldsForClass(clas, new Class<?>[] {BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
-
-            request = setRequestFields(fields);
-
-            // Get response parameters
-            Class<?> responseClas = impl.responseObject();
-            Field[] responseFields = responseClas.getDeclaredFields();
-            response = setResponseFields(responseFields, responseClas);
-
-            apiCommand.setRequest(request);
-            apiCommand.setResponse(response);
-
-            out.writeObject(apiCommand);
-        } else {
-            s_logger.debug("Command " + command + " is not exposed in api doc");
-        }
-    }
-
-    private static ArrayList<Argument> setRequestFields(Set<Field> fields) {
-        ArrayList<Argument> arguments = new ArrayList<Argument>();
-        Set<Argument> requiredArguments = new HashSet<Argument>();
-        Set<Argument> optionalArguments = new HashSet<Argument>();
-        Argument id = null;
-        for (Field f : fields) {
-            Parameter parameterAnnotation = f.getAnnotation(Parameter.class);
-            if (parameterAnnotation != null && parameterAnnotation.expose() && parameterAnnotation.includeInApiDoc()) {
-                Argument reqArg = new Argument(parameterAnnotation.name());
-                reqArg.setRequired(parameterAnnotation.required());
-                if (!parameterAnnotation.description().isEmpty()) {
-                    reqArg.setDescription(parameterAnnotation.description());
-                }
-
-                if (parameterAnnotation.type() == BaseCmd.CommandType.LIST || parameterAnnotation.type() == BaseCmd.CommandType.MAP) {
-                    reqArg.setType(parameterAnnotation.type().toString().toLowerCase());
-                }
-
-                reqArg.setDataType(parameterAnnotation.type().toString().toLowerCase());
-
-                if (!parameterAnnotation.since().isEmpty()) {
-                    reqArg.setSinceVersion(parameterAnnotation.since());
-                }
-
-                if (reqArg.isRequired()) {
-                    if (parameterAnnotation.name().equals("id")) {
-                        id = reqArg;
-                    } else {
-                        requiredArguments.add(reqArg);
-                    }
-                } else {
-                    optionalArguments.add(reqArg);
-                }
-            }
-        }
-
-        // sort required and optional arguments here
-        if (id != null) {
-            arguments.add(id);
-        }
-        arguments.addAll(IteratorUtil.asSortedList(requiredArguments));
-        arguments.addAll(IteratorUtil.asSortedList(optionalArguments));
-
-        return arguments;
-    }
-
-    private static ArrayList<Argument> setResponseFields(Field[] responseFields, Class<?> responseClas) {
-        ArrayList<Argument> arguments = new ArrayList<Argument>();
-        ArrayList<Argument> sortedChildlessArguments = new ArrayList<Argument>();
-        ArrayList<Argument> sortedArguments = new ArrayList<Argument>();
-
-        Argument id = null;
-
-        for (Field responseField : responseFields) {
-            SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class);
-            if (nameAnnotation != null) {
-                Param paramAnnotation = responseField.getAnnotation(Param.class);
-                Argument respArg = new Argument(nameAnnotation.value());
-
-                boolean hasChildren = false;
-                if (paramAnnotation != null && paramAnnotation.includeInApiDoc()) {
-                    String description = paramAnnotation.description();
-                    Class fieldClass = paramAnnotation.responseObject();
-                    if (description != null && !description.isEmpty()) {
-                        respArg.setDescription(description);
-                    }
-
-                    respArg.setDataType(responseField.getType().getSimpleName().toLowerCase());
-
-                    if (!paramAnnotation.since().isEmpty()) {
-                        respArg.setSinceVersion(paramAnnotation.since());
-                    }
-
-                    if (fieldClass != null) {
-                        Class<?> superClass = fieldClass.getSuperclass();
-                        if (superClass != null) {
-                            String superName = superClass.getName();
-                            if (superName.equals(BaseResponse.class.getName())) {
-                                ArrayList<Argument> fieldArguments = new ArrayList<Argument>();
-                                Field[] fields = fieldClass.getDeclaredFields();
-                                fieldArguments = setResponseFields(fields, fieldClass);
-                                respArg.setArguments(fieldArguments);
-                                hasChildren = true;
-                            }
-                        }
-                    }
-                }
-
-                if (paramAnnotation != null && paramAnnotation.includeInApiDoc()) {
-                    if (nameAnnotation.value().equals("id")) {
-                        id = respArg;
-                    } else {
-                        if (hasChildren) {
-                            respArg.setName(nameAnnotation.value() + "(*)");
-                            sortedArguments.add(respArg);
-                        } else {
-                            sortedChildlessArguments.add(respArg);
-                        }
-                    }
-                }
-            }
-        }
-
-        Collections.sort(sortedArguments);
-        Collections.sort(sortedChildlessArguments);
-
-        if (id != null) {
-            arguments.add(id);
-        }
-        arguments.addAll(sortedChildlessArguments);
-        arguments.addAll(sortedArguments);
-
-        if (responseClas.getName().equalsIgnoreCase(AsyncJobResponse.class.getName())) {
-            Argument jobIdArg = new Argument("jobid", "the ID of the async job");
-            arguments.add(jobIdArg);
-        } else if (AsyncResponses.contains(responseClas.getName())) {
-            Argument jobIdArg = new Argument("jobid", "the ID of the latest async job acting on this object");
-            Argument jobStatusArg = new Argument("jobstatus", "the current status of the latest async job acting on this object");
-            arguments.add(jobIdArg);
-            arguments.add(jobStatusArg);
-        }
-
-        return arguments;
-    }
-
-    private static void zipDir(String zipFileName, String dir) throws Exception {
-        File dirObj = new File(dir);
-        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
-        addDir(dirObj, out);
-        out.close();
-    }
-
-    static void addDir(File dirObj, ZipOutputStream out) throws IOException {
-        File[] files = dirObj.listFiles();
-        byte[] tmpBuf = new byte[1024];
-        String pathToDir = s_dirName;
-
-        for (int i = 0; i < files.length; i++) {
-            if (files[i].isDirectory()) {
-                addDir(files[i], out);
-                continue;
-            }
-            try(FileInputStream in = new FileInputStream(files[i].getPath());) {
-                out.putNextEntry(new ZipEntry(files[i].getPath().substring(pathToDir.length())));
-                int len;
-                while ((len = in.read(tmpBuf)) > 0) {
-                    out.write(tmpBuf, 0, len);
-                }
-                out.closeEntry();
-            }catch(IOException ex)
-            {
-                s_logger.error("addDir:Exception:"+ ex.getMessage(),ex);
-            }
-        }
-    }
-
-    private static void deleteDir(File dir) {
-        if (dir.isDirectory()) {
-            String[] children = dir.list();
-            if (children != null) {
-                for (int i = 0; i < children.length; i++) {
-                    deleteDir(new File(dir, children[i]));
-                }
-            }
-        }
-        dir.delete();
-    }
-
-    private static void writeAlertTypes(String dirName) {
-        XStream xs = new XStream();
-        xs.alias("alert", Alert.class);
-        try(ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/alert_types.xml"), "alerts");) {
-            for (Field f : AlertManager.class.getFields()) {
-                if (f.getClass().isAssignableFrom(Number.class)) {
-                    String name = f.getName().substring(11);
-                    Alert alert = new Alert(name, f.getInt(null));
-                    out.writeObject(alert);
-                }
-            }
-        } catch (IOException e) {
-            s_logger.error("Failed to create output stream to write an alert types ", e);
-        } catch (IllegalAccessException e) {
-            s_logger.error("Failed to read alert fields ", e);
-        }
-    }
-
-    private static class LinkedProperties extends Properties {
-        private final LinkedList<Object> keys = new LinkedList<Object>();
-
-        @Override
-        public Enumeration<Object> keys() {
-            return Collections.<Object> enumeration(keys);
-        }
-
-        @Override
-        public Object put(Object key, Object value) {
-            // System.out.println("Adding key" + key);
-            keys.add(key);
-            return super.put(key, value);
-        }
-    }
-}
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
deleted file mode 100644
index 9d24417..0000000
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ /dev/null
@@ -1,3695 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
-import org.apache.cloudstack.api.ResourceDetail;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
-import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
-import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
-import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
-import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
-import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
-import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
-import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
-import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
-import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
-import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
-import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
-import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.EventResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.HostTagResponse;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.api.response.InstanceGroupResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.ProjectAccountResponse;
-import org.apache.cloudstack.api.response.ProjectInvitationResponse;
-import org.apache.cloudstack.api.response.ProjectResponse;
-import org.apache.cloudstack.api.response.ResourceDetailResponse;
-import org.apache.cloudstack.api.response.ResourceTagResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.StorageTagResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.api.response.UserResponse;
-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.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.query.QueryService;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.api.query.dao.AccountJoinDao;
-import com.cloud.api.query.dao.AffinityGroupJoinDao;
-import com.cloud.api.query.dao.AsyncJobJoinDao;
-import com.cloud.api.query.dao.DataCenterJoinDao;
-import com.cloud.api.query.dao.DiskOfferingJoinDao;
-import com.cloud.api.query.dao.DomainJoinDao;
-import com.cloud.api.query.dao.DomainRouterJoinDao;
-import com.cloud.api.query.dao.HostJoinDao;
-import com.cloud.api.query.dao.HostTagDao;
-import com.cloud.api.query.dao.ImageStoreJoinDao;
-import com.cloud.api.query.dao.InstanceGroupJoinDao;
-import com.cloud.api.query.dao.ProjectAccountJoinDao;
-import com.cloud.api.query.dao.ProjectInvitationJoinDao;
-import com.cloud.api.query.dao.ProjectJoinDao;
-import com.cloud.api.query.dao.ResourceTagJoinDao;
-import com.cloud.api.query.dao.SecurityGroupJoinDao;
-import com.cloud.api.query.dao.ServiceOfferingJoinDao;
-import com.cloud.api.query.dao.StoragePoolJoinDao;
-import com.cloud.api.query.dao.TemplateJoinDao;
-import com.cloud.api.query.dao.UserAccountJoinDao;
-import com.cloud.api.query.dao.UserVmJoinDao;
-import com.cloud.api.query.dao.VolumeJoinDao;
-import com.cloud.api.query.vo.AccountJoinVO;
-import com.cloud.api.query.vo.AffinityGroupJoinVO;
-import com.cloud.api.query.vo.AsyncJobJoinVO;
-import com.cloud.api.query.vo.DataCenterJoinVO;
-import com.cloud.api.query.vo.DiskOfferingJoinVO;
-import com.cloud.api.query.vo.DomainJoinVO;
-import com.cloud.api.query.vo.DomainRouterJoinVO;
-import com.cloud.api.query.vo.EventJoinVO;
-import com.cloud.api.query.vo.HostJoinVO;
-import com.cloud.api.query.vo.HostTagVO;
-import com.cloud.api.query.vo.ImageStoreJoinVO;
-import com.cloud.api.query.vo.InstanceGroupJoinVO;
-import com.cloud.api.query.vo.ProjectAccountJoinVO;
-import com.cloud.api.query.vo.ProjectInvitationJoinVO;
-import com.cloud.api.query.vo.ProjectJoinVO;
-import com.cloud.api.query.vo.ResourceTagJoinVO;
-import com.cloud.api.query.vo.SecurityGroupJoinVO;
-import com.cloud.api.query.vo.ServiceOfferingJoinVO;
-import com.cloud.api.query.vo.StoragePoolJoinVO;
-import com.cloud.api.query.vo.TemplateJoinVO;
-import com.cloud.api.query.vo.UserAccountJoinVO;
-import com.cloud.api.query.vo.UserVmJoinVO;
-import com.cloud.api.query.vo.VolumeJoinVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.dao.EventJoinDao;
-import com.cloud.exception.CloudAuthenticationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.security.SecurityGroupVMMapVO;
-import com.cloud.network.security.dao.SecurityGroupVMMapDao;
-import com.cloud.org.Grouping;
-import com.cloud.projects.Project;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.projects.ProjectInvitation;
-import com.cloud.projects.ProjectManager;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.projects.dao.ProjectDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ResourceMetaDataService;
-import com.cloud.server.ResourceTag;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.server.TaggedResourceService;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePoolTagVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.dao.StoragePoolTagsDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.template.VirtualMachineTemplate.State;
-import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements QueryService, Configurable {
-
-    public static final Logger s_logger = Logger.getLogger(QueryManagerImpl.class);
-
-    private static final String ID_FIELD = "id";
-
-    @Inject
-    private AccountManager _accountMgr;
-
-    @Inject
-    private ProjectManager _projectMgr;
-
-    @Inject
-    private DomainDao _domainDao;
-
-    @Inject
-    private DomainJoinDao _domainJoinDao;
-
-    @Inject
-    private UserAccountJoinDao _userAccountJoinDao;
-
-    @Inject
-    private EventJoinDao _eventJoinDao;
-
-    @Inject
-    private ResourceTagJoinDao _resourceTagJoinDao;
-
-    @Inject
-    private InstanceGroupJoinDao _vmGroupJoinDao;
-
-    @Inject
-    private UserVmJoinDao _userVmJoinDao;
-
-    @Inject
-    private UserVmDao _userVmDao;
-
-    @Inject
-    private VMInstanceDao _vmInstanceDao;
-
-    @Inject
-    private SecurityGroupJoinDao _securityGroupJoinDao;
-
-    @Inject
-    private SecurityGroupVMMapDao _securityGroupVMMapDao;
-
-    @Inject
-    private DomainRouterJoinDao _routerJoinDao;
-
-    @Inject
-    private ProjectInvitationJoinDao _projectInvitationJoinDao;
-
-    @Inject
-    private ProjectJoinDao _projectJoinDao;
-
-    @Inject
-    private ProjectDao _projectDao;
-
-    @Inject
-    private ProjectAccountDao _projectAccountDao;
-
-    @Inject
-    private ProjectAccountJoinDao _projectAccountJoinDao;
-
-    @Inject
-    private HostJoinDao _hostJoinDao;
-
-    @Inject
-    private VolumeJoinDao _volumeJoinDao;
-
-    @Inject
-    private AccountDao _accountDao;
-
-    @Inject
-    private ConfigurationDao _configDao;
-
-    @Inject
-    private AccountJoinDao _accountJoinDao;
-
-    @Inject
-    private AsyncJobJoinDao _jobJoinDao;
-
-    @Inject
-    private StoragePoolJoinDao _poolJoinDao;
-
-    @Inject
-    private StoragePoolTagsDao _storageTagDao;
-
-    @Inject
-    private HostTagDao _hostTagDao;
-
-    @Inject
-    private ImageStoreJoinDao _imageStoreJoinDao;
-
-    @Inject
-    private DiskOfferingJoinDao _diskOfferingJoinDao;
-
-    @Inject
-    private ServiceOfferingJoinDao _srvOfferingJoinDao;
-
-    @Inject
-    private ServiceOfferingDao _srvOfferingDao;
-
-    @Inject
-    private DataCenterJoinDao _dcJoinDao;
-
-    @Inject
-    private DomainRouterDao _routerDao;
-
-    @Inject
-    UserVmDetailsDao _userVmDetailDao;
-
-    @Inject
-    private HighAvailabilityManager _haMgr;
-
-    @Inject
-    private VMTemplateDao _templateDao;
-
-    @Inject
-    private TemplateJoinDao _templateJoinDao;
-
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    private ResourceMetaDataService _resourceMetaDataMgr;
-
-    @Inject
-    private TaggedResourceService _taggedResourceMgr;
-
-    @Inject
-    AffinityGroupVMMapDao _affinityGroupVMMapDao;
-
-    @Inject
-    private AffinityGroupJoinDao _affinityGroupJoinDao;
-
-    @Inject
-    private DedicatedResourceDao _dedicatedDao;
-
-    @Inject
-    DataCenterDetailsDao _dcDetailsDao;
-
-    @Inject
-    DomainManager _domainMgr;
-
-    @Inject
-    AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
-
-    @Inject
-    NetworkDetailsDao _networkDetailsDao;
-
-    @Inject
-    ResourceTagDao _resourceTagDao;
-
-    @Inject
-    DataStoreManager dataStoreManager;
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see
-     * com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack
-     * .api.command.admin.user.ListUsersCmd)
-     */
-    @Override
-    public ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
-        Pair<List<UserAccountJoinVO>, Integer> result = searchForUsersInternal(cmd);
-        ListResponse<UserResponse> response = new ListResponse<UserResponse>();
-        List<UserResponse> userResponses = ViewResponseHelper.createUserResponse(CallContext.current().getCallingAccount().getDomainId(),
-                result.first().toArray(new UserAccountJoinVO[result.first().size()]));
-        response.setResponses(userResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<UserAccountJoinVO>, Integer> searchForUsersInternal(ListUsersCmd cmd) throws PermissionDeniedException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        boolean listAll = cmd.listAll();
-        Long id = cmd.getId();
-        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-            long currentId = CallContext.current().getCallingUser().getId();
-            if (id != null && currentId != id.longValue()) {
-                throw new PermissionDeniedException("Calling user is not authorized to see the user requested by id");
-            }
-            id = currentId;
-        }
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(UserAccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        Object username = cmd.getUsername();
-        Object type = cmd.getAccountType();
-        Object accountName = cmd.getAccountName();
-        Object state = cmd.getState();
-        Object keyword = cmd.getKeyword();
-
-        SearchBuilder<UserAccountJoinVO> sb = _userAccountJoinDao.createSearchBuilder();
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.LIKE);
-        if (id != null && id == 1) {
-            // system user should NOT be searchable
-            List<UserAccountJoinVO> emptyList = new ArrayList<UserAccountJoinVO>();
-            return new Pair<List<UserAccountJoinVO>, Integer>(emptyList, 0);
-        } else if (id != null) {
-            sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        } else {
-            // this condition is used to exclude system user from the search
-            // results
-            sb.and("id", sb.entity().getId(), SearchCriteria.Op.NEQ);
-        }
-
-        sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
-        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-        sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-
-        if ((accountName == null) && (domainId != null)) {
-            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-        }
-
-        SearchCriteria<UserAccountJoinVO> sc = sb.create();
-
-        // building ACL condition
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            SearchCriteria<UserAccountJoinVO> ssc = _userAccountJoinDao.createSearchCriteria();
-            ssc.addOr("username", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("firstname", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("lastname", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("email", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("accountType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("username", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (username != null) {
-            sc.setParameters("username", username);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        } else {
-            // Don't return system user, search builder with NEQ
-            sc.setParameters("id", 1);
-        }
-
-        if (type != null) {
-            sc.setParameters("type", type);
-        }
-
-        if (accountName != null) {
-            sc.setParameters("accountName", accountName);
-            if (domainId != null) {
-                sc.setParameters("domainId", domainId);
-            }
-        } else if (domainId != null) {
-            DomainVO domainVO = _domainDao.findById(domainId);
-            sc.setParameters("domainPath", domainVO.getPath() + "%");
-        }
-
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-
-        return _userAccountJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd) {
-        Pair<List<EventJoinVO>, Integer> result = searchForEventsInternal(cmd);
-        ListResponse<EventResponse> response = new ListResponse<EventResponse>();
-        List<EventResponse> eventResponses = ViewResponseHelper.createEventResponse(result.first().toArray(new EventJoinVO[result.first().size()]));
-        response.setResponses(eventResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<EventJoinVO>, Integer> searchForEventsInternal(ListEventsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Long id = cmd.getId();
-        String type = cmd.getType();
-        String level = cmd.getLevel();
-        Date startDate = cmd.getStartDate();
-        Date endDate = cmd.getEndDate();
-        String keyword = cmd.getKeyword();
-        Integer entryTime = cmd.getEntryTime();
-        Integer duration = cmd.getDuration();
-        Long startId = cmd.getStartId();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(EventJoinVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<EventJoinVO> sb = _eventJoinDao.createSearchBuilder();
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("levelL", sb.entity().getLevel(), SearchCriteria.Op.LIKE);
-        sb.and("levelEQ", sb.entity().getLevel(), SearchCriteria.Op.EQ);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
-        sb.and("createDateB", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
-        sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ);
-        sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
-        sb.or("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ);
-        sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
-        sb.and("displayEvent", sb.entity().getDisplay(), SearchCriteria.Op.EQ);
-        sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<EventJoinVO> sc = sb.create();
-        // building ACL condition
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        // For end users display only enabled events
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            sc.setParameters("displayEvent", true);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (startId != null) {
-            sc.setParameters("startId", startId);
-            if (id == null) {
-                sc.setParameters("id", startId);
-            }
-        }
-
-        if (keyword != null) {
-            SearchCriteria<EventJoinVO> ssc = _eventJoinDao.createSearchCriteria();
-            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("level", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("level", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (level != null) {
-            sc.setParameters("levelEQ", level);
-        }
-
-        if (type != null) {
-            sc.setParameters("type", type);
-        }
-
-        if (startDate != null && endDate != null) {
-            sc.setParameters("createDateB", startDate, endDate);
-        } else if (startDate != null) {
-            sc.setParameters("createDateG", startDate);
-        } else if (endDate != null) {
-            sc.setParameters("createDateL", endDate);
-        }
-
-        sc.setParameters("archived", false);
-
-        Pair<List<EventJoinVO>, Integer> eventPair = null;
-        // event_view will not have duplicate rows for each event, so
-        // searchAndCount should be good enough.
-        if ((entryTime != null) && (duration != null)) {
-            // TODO: waiting for response from dev list, logic is mystery to
-            // me!!
-            /*
-             * if (entryTime <= duration) { throw new
-             * InvalidParameterValueException
-             * ("Entry time must be greater than duration"); } Calendar calMin =
-             * Calendar.getInstance(); Calendar calMax = Calendar.getInstance();
-             * calMin.add(Calendar.SECOND, -entryTime);
-             * calMax.add(Calendar.SECOND, -duration); Date minTime =
-             * calMin.getTime(); Date maxTime = calMax.getTime();
-             *
-             * sc.setParameters("state", com.cloud.event.Event.State.Completed);
-             * sc.setParameters("startId", 0); sc.setParameters("createDate",
-             * minTime, maxTime); List<EventJoinVO> startedEvents =
-             * _eventJoinDao.searchAllEvents(sc, searchFilter);
-             * List<EventJoinVO> pendingEvents = new ArrayList<EventJoinVO>();
-             * for (EventVO event : startedEvents) { EventVO completedEvent =
-             * _eventDao.findCompletedEvent(event.getId()); if (completedEvent
-             * == null) { pendingEvents.add(event); } } return pendingEvents;
-             */
-        } else {
-            eventPair = _eventJoinDao.searchAndCount(sc, searchFilter);
-        }
-        return eventPair;
-
-    }
-
-    @Override
-    public ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd) {
-        Pair<List<ResourceTagJoinVO>, Integer> tags = listTagsInternal(cmd);
-        ListResponse<ResourceTagResponse> response = new ListResponse<ResourceTagResponse>();
-        List<ResourceTagResponse> tagResponses = ViewResponseHelper.createResourceTagResponse(false, tags.first().toArray(new ResourceTagJoinVO[tags.first().size()]));
-        response.setResponses(tagResponses, tags.second());
-        return response;
-    }
-
-    private Pair<List<ResourceTagJoinVO>, Integer> listTagsInternal(ListTagsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-        String key = cmd.getKey();
-        String value = cmd.getValue();
-        String resourceId = cmd.getResourceId();
-        String resourceType = cmd.getResourceType();
-        String customerName = cmd.getCustomer();
-        boolean listAll = cmd.listAll();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-
-        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        Filter searchFilter = new Filter(ResourceTagJoinVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        SearchBuilder<ResourceTagJoinVO> sb = _resourceTagJoinDao.createSearchBuilder();
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ);
-        sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ);
-
-        if (resourceId != null) {
-            sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
-            sb.and("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ);
-        }
-
-        sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
-        sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ);
-
-        // now set the SC criteria...
-        SearchCriteria<ResourceTagJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (key != null) {
-            sc.setParameters("key", key);
-        }
-
-        if (value != null) {
-            sc.setParameters("value", value);
-        }
-
-        if (resourceId != null) {
-            try {
-                long rid = Long.parseLong(resourceId);
-                sc.setParameters("resourceId", rid);
-            } catch (NumberFormatException ex) {
-                // internal id instead of resource id is passed
-                sc.setParameters("resourceUuid", resourceId);
-            }
-        }
-
-        if (resourceType != null) {
-            sc.setParameters("resourceType", resourceType);
-        }
-
-        if (customerName != null) {
-            sc.setParameters("customer", customerName);
-        }
-
-        Pair<List<ResourceTagJoinVO>, Integer> result = _resourceTagJoinDao.searchAndCount(sc, searchFilter);
-        return result;
-    }
-
-    @Override
-    public ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd) {
-        Pair<List<InstanceGroupJoinVO>, Integer> groups = searchForVmGroupsInternal(cmd);
-        ListResponse<InstanceGroupResponse> response = new ListResponse<InstanceGroupResponse>();
-        List<InstanceGroupResponse> grpResponses = ViewResponseHelper.createInstanceGroupResponse(groups.first().toArray(new InstanceGroupJoinVO[groups.first().size()]));
-        response.setResponses(grpResponses, groups.second());
-        return response;
-    }
-
-    private Pair<List<InstanceGroupJoinVO>, Integer> searchForVmGroupsInternal(ListVMGroupsCmd cmd) {
-        Long id = cmd.getId();
-        String name = cmd.getGroupName();
-        String keyword = cmd.getKeyword();
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(InstanceGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        SearchBuilder<InstanceGroupJoinVO> sb = _vmGroupJoinDao.createSearchBuilder();
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-
-        SearchCriteria<InstanceGroupJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            SearchCriteria<InstanceGroupJoinVO> ssc = _vmGroupJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-
-        return _vmGroupJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<UserVmResponse> searchForUserVMs(ListVMsCmd cmd) {
-        Pair<List<UserVmJoinVO>, Integer> result = searchForUserVMsInternal(cmd);
-        ListResponse<UserVmResponse> response = new ListResponse<UserVmResponse>();
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListVMsCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-        List<UserVmResponse> vmResponses = ViewResponseHelper.createUserVmResponse(respView, "virtualmachine", cmd.getDetails(), result.first().toArray(new UserVmJoinVO[result.first().size()]));
-
-        response.setResponses(vmResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        boolean listAll = cmd.listAll();
-        Long id = cmd.getId();
-        Long userId = cmd.getUserId();
-        Map<String, String> tags = cmd.getTags();
-        Boolean display = cmd.getDisplay();
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(UserVmJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        List<Long> ids = null;
-        if (cmd.getId() != null) {
-            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
-                throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
-            }
-            ids = new ArrayList<Long>();
-            ids.add(cmd.getId());
-        } else {
-            ids = cmd.getIds();
-        }
-
-        // first search distinct vm id by using query criteria and pagination
-        SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
-
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        String hypervisor = cmd.getHypervisor();
-        Object name = cmd.getName();
-        String state = cmd.getState();
-        Object zoneId = cmd.getZoneId();
-        Object keyword = cmd.getKeyword();
-        boolean isAdmin = false;
-        boolean isRootAdmin = false;
-        if (_accountMgr.isAdmin(caller.getId())) {
-            isAdmin = true;
-        }
-        if (_accountMgr.isRootAdmin(caller.getId())) {
-            isRootAdmin = true;
-        }
-
-        Object groupId = cmd.getGroupId();
-        Object networkId = cmd.getNetworkId();
-        if (HypervisorType.getType(hypervisor) == HypervisorType.None && hypervisor != null) {
-            // invalid hypervisor type input
-            throw new InvalidParameterValueException("Invalid HypervisorType " + hypervisor);
-        }
-        Object templateId = cmd.getTemplateId();
-        Object isoId = cmd.getIsoId();
-        Object vpcId = cmd.getVpcId();
-        Object affinityGroupId = cmd.getAffinityGroupId();
-        Object keyPairName = cmd.getKeyPairName();
-        Object serviceOffId = cmd.getServiceOfferingId();
-        Object pod = null;
-        Object hostId = null;
-        Object storageId = null;
-        if (cmd instanceof ListVMsCmdByAdmin) {
-            ListVMsCmdByAdmin adCmd = (ListVMsCmdByAdmin)cmd;
-            pod = adCmd.getPodId();
-            hostId = adCmd.getHostId();
-            storageId = adCmd.getStorageId();
-        }
-
-        sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
-        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
-        sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
-        sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
-        sb.and("isoId", sb.entity().getIsoId(), SearchCriteria.Op.EQ);
-        sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
-
-        if (serviceOffId != null) {
-            sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ);
-        }
-        if (display != null) {
-            sb.and("display", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ);
-        }
-        if (groupId != null && (Long)groupId != -1) {
-            sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
-        }
-
-        if (userId != null) {
-            sb.and("userId", sb.entity().getUserId(), SearchCriteria.Op.EQ);
-        }
-
-        if (networkId != null) {
-            sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        }
-
-        if (vpcId != null && networkId == null) {
-            sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
-        }
-
-        if (storageId != null) {
-            sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.EQ);
-        }
-
-        if (affinityGroupId != null) {
-            sb.and("affinityGroupId", sb.entity().getAffinityGroupId(), SearchCriteria.Op.EQ);
-        }
-
-        if (keyPairName != null) {
-            sb.and("keyPairName", sb.entity().getKeypairName(), SearchCriteria.Op.EQ);
-        }
-
-        if (!isRootAdmin) {
-            sb.and("displayVm", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ);
-        }
-
-        // populate the search criteria with the values passed in
-        SearchCriteria<UserVmJoinVO> sc = sb.create();
-
-        // building ACL condition
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchCriteria<UserVmJoinVO> tagSc = _userVmJoinDao.createSearchCriteria();
-            for (Map.Entry<String, String> entry : tags.entrySet()) {
-                SearchCriteria<UserVmJoinVO> tsc = _userVmJoinDao.createSearchCriteria();
-                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, entry.getKey());
-                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, entry.getValue());
-                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
-            }
-            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
-        }
-
-        if (groupId != null && (Long)groupId != -1) {
-            sc.setParameters("instanceGroupId", groupId);
-        }
-
-        if (keyword != null) {
-            SearchCriteria<UserVmJoinVO> ssc = _userVmJoinDao.createSearchCriteria();
-            ssc.addOr("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("state", SearchCriteria.Op.EQ, keyword);
-            sc.addAnd("displayName", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (serviceOffId != null) {
-            sc.setParameters("serviceOfferingId", serviceOffId);
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        if (ids != null && !ids.isEmpty()) {
-            sc.setParameters("idIN", ids.toArray());
-        }
-
-        if (templateId != null) {
-            sc.setParameters("templateId", templateId);
-        }
-
-        if (isoId != null) {
-            sc.setParameters("isoId", isoId);
-        }
-
-        if (userId != null) {
-            sc.setParameters("userId", userId);
-        }
-
-        if (networkId != null) {
-            sc.setParameters("networkId", networkId);
-        }
-
-        if (vpcId != null && networkId == null) {
-            sc.setParameters("vpcId", vpcId);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-
-        if (state != null) {
-            if (state.equalsIgnoreCase("present")) {
-                sc.setParameters("stateNIN", "Destroyed", "Expunging");
-            } else {
-                sc.setParameters("stateEQ", state);
-            }
-        }
-
-        if (hypervisor != null) {
-            sc.setParameters("hypervisorType", hypervisor);
-        }
-
-        // Don't show Destroyed and Expunging vms to the end user if the AllowUserViewDestroyedVM flag is not set.
-        if (!isAdmin && !AllowUserViewDestroyedVM.valueIn(caller.getAccountId())) {
-            sc.setParameters("stateNIN", "Destroyed", "Expunging");
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-
-        if (affinityGroupId != null) {
-            sc.setParameters("affinityGroupId", affinityGroupId);
-        }
-
-        if (keyPairName != null) {
-            sc.setParameters("keyPairName", keyPairName);
-        }
-
-        if (cmd instanceof ListVMsCmdByAdmin) {
-            ListVMsCmdByAdmin aCmd = (ListVMsCmdByAdmin)cmd;
-            if (aCmd.getPodId() != null) {
-                sc.setParameters("podId", pod);
-
-                if (state == null) {
-                    sc.setParameters("stateNEQ", "Destroyed");
-                }
-            }
-
-            if (hostId != null) {
-                sc.setParameters("hostIdEQ", hostId);
-            }
-
-            if (storageId != null) {
-                sc.setParameters("poolId", storageId);
-            }
-        }
-
-        if (!isRootAdmin) {
-            sc.setParameters("displayVm", 1);
-        }
-        // search vm details by ids
-        Pair<List<UserVmJoinVO>, Integer> uniqueVmPair = _userVmJoinDao.searchAndDistinctCount(sc, searchFilter);
-        Integer count = uniqueVmPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return uniqueVmPair;
-        }
-        List<UserVmJoinVO> uniqueVms = uniqueVmPair.first();
-        Long[] vmIds = new Long[uniqueVms.size()];
-        int i = 0;
-        for (UserVmJoinVO v : uniqueVms) {
-            vmIds[i++] = v.getId();
-        }
-        List<UserVmJoinVO> vms = _userVmJoinDao.searchByIds(vmIds);
-        return new Pair<List<UserVmJoinVO>, Integer>(vms, count);
-    }
-
-    @Override
-    public ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd) {
-        Pair<List<SecurityGroupJoinVO>, Integer> result = searchForSecurityGroupsInternal(cmd);
-        ListResponse<SecurityGroupResponse> response = new ListResponse<SecurityGroupResponse>();
-        List<SecurityGroupResponse> routerResponses = ViewResponseHelper.createSecurityGroupResponses(result.first());
-        response.setResponses(routerResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<SecurityGroupJoinVO>, Integer> searchForSecurityGroupsInternal(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long instanceId = cmd.getVirtualMachineId();
-        String securityGroup = cmd.getSecurityGroupName();
-        Long id = cmd.getId();
-        Object keyword = cmd.getKeyword();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-        Map<String, String> tags = cmd.getTags();
-
-        if (instanceId != null) {
-            UserVmVO userVM = _userVmDao.findById(instanceId);
-            if (userVM == null) {
-                throw new InvalidParameterValueException("Unable to list network groups for virtual machine instance " + instanceId + "; instance not found.");
-            }
-            _accountMgr.checkAccess(caller, null, true, userVM);
-            return listSecurityGroupRulesByVM(instanceId.longValue(), cmd.getStartIndex(), cmd.getPageSizeVal());
-        }
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(SecurityGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<SecurityGroupJoinVO> sb = _securityGroupJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<SecurityGroupJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchCriteria<SecurityGroupJoinVO> tagSc = _securityGroupJoinDao.createSearchCriteria();
-            for (String key : tags.keySet()) {
-                SearchCriteria<SecurityGroupJoinVO> tsc = _securityGroupJoinDao.createSearchCriteria();
-                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, key);
-                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key));
-                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
-            }
-            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
-        }
-
-        if (securityGroup != null) {
-            sc.setParameters("name", securityGroup);
-        }
-
-        if (keyword != null) {
-            SearchCriteria<SecurityGroupJoinVO> ssc = _securityGroupJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        // search security group together with rules
-        Pair<List<SecurityGroupJoinVO>, Integer> uniqueSgPair = _securityGroupJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueSgPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return uniqueSgPair;
-        }
-
-        List<SecurityGroupJoinVO> uniqueSgs = uniqueSgPair.first();
-        Long[] sgIds = new Long[uniqueSgs.size()];
-        int i = 0;
-        for (SecurityGroupJoinVO v : uniqueSgs) {
-            sgIds[i++] = v.getId();
-        }
-        List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
-        return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
-    }
-
-    private Pair<List<SecurityGroupJoinVO>, Integer> listSecurityGroupRulesByVM(long vmId, long pageInd, long pageSize) {
-        Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize);
-        Pair<List<SecurityGroupVMMapVO>, Integer> sgVmMappingPair = _securityGroupVMMapDao.listByInstanceId(vmId, sf);
-        Integer count = sgVmMappingPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return new Pair<List<SecurityGroupJoinVO>, Integer>(new ArrayList<SecurityGroupJoinVO>(), count);
-        }
-        List<SecurityGroupVMMapVO> sgVmMappings = sgVmMappingPair.first();
-        Long[] sgIds = new Long[sgVmMappings.size()];
-        int i = 0;
-        for (SecurityGroupVMMapVO sgVm : sgVmMappings) {
-            sgIds[i++] = sgVm.getSecurityGroupId();
-        }
-        List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
-        return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
-    }
-
-    @Override
-    public ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd) {
-        Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getClusterId(),
-                cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion());
-        ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
-
-        List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
-        response.setResponses(routerResponses, result.second());
-        return response;
-    }
-
-    @Override
-    public ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd) {
-        Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), null, cmd.getHostId(),
-                cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null);
-        ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
-
-        List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
-        response.setResponses(routerResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<DomainRouterJoinVO>, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, String name, String state, Long zoneId, Long podId, Long clusterId,
-            Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version) {
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        Filter searchFilter = new Filter(DomainRouterJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        SearchBuilder<DomainRouterJoinVO> sb = _routerJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids to get
-        // number of
-        // records with
-        // pagination
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("name", sb.entity().getInstanceName(), SearchCriteria.Op.LIKE);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.IN);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
-        sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ);
-        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
-        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
-        sb.and("version", sb.entity().getTemplateVersion(), SearchCriteria.Op.LIKE);
-
-        if (forVpc != null) {
-            if (forVpc) {
-                sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NNULL);
-            } else {
-                sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NULL);
-            }
-        }
-
-        if (networkId != null) {
-            sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        }
-
-        SearchCriteria<DomainRouterJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            SearchCriteria<DomainRouterJoinVO> ssc = _routerJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("networkName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("vpcName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("instanceName", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-
-        if (podId != null) {
-            sc.setParameters("podId", podId);
-        }
-
-        if (clusterId != null) {
-            sc.setParameters("clusterId", clusterId);
-        }
-
-        if (hostId != null) {
-            sc.setParameters("hostId", hostId);
-        }
-
-        if (networkId != null) {
-            sc.setParameters("networkId", networkId);
-        }
-
-        if (vpcId != null) {
-            sc.setParameters("vpcId", vpcId);
-        }
-
-        if (role != null) {
-            sc.setParameters("role", role);
-        }
-
-        if (version != null) {
-            sc.setParameters("version", "Cloudstack Release " + version + "%");
-        }
-
-        // search VR details by ids
-        Pair<List<DomainRouterJoinVO>, Integer> uniqueVrPair = _routerJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueVrPair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniqueVrPair;
-        }
-        List<DomainRouterJoinVO> uniqueVrs = uniqueVrPair.first();
-        Long[] vrIds = new Long[uniqueVrs.size()];
-        int i = 0;
-        for (DomainRouterJoinVO v : uniqueVrs) {
-            vrIds[i++] = v.getId();
-        }
-        List<DomainRouterJoinVO> vrs = _routerJoinDao.searchByIds(vrIds);
-        return new Pair<List<DomainRouterJoinVO>, Integer>(vrs, count);
-    }
-
-    @Override
-    public ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd) {
-        Pair<List<ProjectJoinVO>, Integer> projects = listProjectsInternal(cmd);
-        ListResponse<ProjectResponse> response = new ListResponse<ProjectResponse>();
-        List<ProjectResponse> projectResponses = ViewResponseHelper.createProjectResponse(projects.first().toArray(new ProjectJoinVO[projects.first().size()]));
-        response.setResponses(projectResponses, projects.second());
-        return response;
-    }
-
-    private Pair<List<ProjectJoinVO>, Integer> listProjectsInternal(ListProjectsCmd cmd) {
-
-        Long id = cmd.getId();
-        String name = cmd.getName();
-        String displayText = cmd.getDisplayText();
-        String state = cmd.getState();
-        String accountName = cmd.getAccountName();
-        Long domainId = cmd.getDomainId();
-        String keyword = cmd.getKeyword();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-        boolean listAll = cmd.listAll();
-        boolean isRecursive = cmd.isRecursive();
-        cmd.getTags();
-
-        Account caller = CallContext.current().getCallingAccount();
-        Long accountId = null;
-        String path = null;
-
-        Filter searchFilter = new Filter(ProjectJoinVO.class, "id", false, startIndex, pageSize);
-        SearchBuilder<ProjectJoinVO> sb = _projectJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-
-        if (_accountMgr.isAdmin(caller.getId())) {
-            if (domainId != null) {
-                DomainVO domain = _domainDao.findById(domainId);
-                if (domain == null) {
-                    throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist in the system");
-                }
-
-                _accountMgr.checkAccess(caller, domain);
-
-                if (accountName != null) {
-                    Account owner = _accountMgr.getActiveAccountByName(accountName, domainId);
-                    if (owner == null) {
-                        throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
-                    }
-                    accountId = owner.getId();
-                }
-            } else { // domainId == null
-                if (accountName != null) {
-                    throw new InvalidParameterValueException("could not find account " + accountName + " because domain is not specified");
-                }
-
-            }
-        } else {
-            if (accountName != null && !accountName.equals(caller.getAccountName())) {
-                throw new PermissionDeniedException("Can't list account " + accountName + " projects; unauthorized");
-            }
-
-            if (domainId != null && !domainId.equals(caller.getDomainId())) {
-                throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized");
-            }
-
-            accountId = caller.getId();
-        }
-
-        if (domainId == null && accountId == null && (_accountMgr.isNormalUser(caller.getId()) || !listAll)) {
-            accountId = caller.getId();
-        } else if (_accountMgr.isDomainAdmin(caller.getId()) || (isRecursive && !listAll)) {
-            DomainVO domain = _domainDao.findById(caller.getDomainId());
-            path = domain.getPath();
-        }
-
-        if (path != null) {
-            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-        }
-
-        if (accountId != null) {
-            sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
-        }
-
-        SearchCriteria<ProjectJoinVO> sc = sb.create();
-
-        if (id != null) {
-            sc.addAnd("id", Op.EQ, id);
-        }
-
-        if (domainId != null && !isRecursive) {
-            sc.addAnd("domainId", Op.EQ, domainId);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", Op.EQ, name);
-        }
-
-        if (displayText != null) {
-            sc.addAnd("displayText", Op.EQ, displayText);
-        }
-
-        if (accountId != null) {
-            sc.setParameters("accountId", accountId);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", Op.EQ, state);
-        }
-
-        if (keyword != null) {
-            SearchCriteria<ProjectJoinVO> ssc = _projectJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (path != null) {
-            sc.setParameters("domainPath", path);
-        }
-
-        // search distinct projects to get count
-        Pair<List<ProjectJoinVO>, Integer> uniquePrjPair = _projectJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniquePrjPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return uniquePrjPair;
-        }
-        List<ProjectJoinVO> uniquePrjs = uniquePrjPair.first();
-        Long[] prjIds = new Long[uniquePrjs.size()];
-        int i = 0;
-        for (ProjectJoinVO v : uniquePrjs) {
-            prjIds[i++] = v.getId();
-        }
-        List<ProjectJoinVO> prjs = _projectJoinDao.searchByIds(prjIds);
-        return new Pair<List<ProjectJoinVO>, Integer>(prjs, count);
-    }
-
-    @Override
-    public ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd) {
-        Pair<List<ProjectInvitationJoinVO>, Integer> invites = listProjectInvitationsInternal(cmd);
-        ListResponse<ProjectInvitationResponse> response = new ListResponse<ProjectInvitationResponse>();
-        List<ProjectInvitationResponse> projectInvitationResponses = ViewResponseHelper.createProjectInvitationResponse(invites.first().toArray(new ProjectInvitationJoinVO[invites.first().size()]));
-
-        response.setResponses(projectInvitationResponses, invites.second());
-        return response;
-    }
-
-    public Pair<List<ProjectInvitationJoinVO>, Integer> listProjectInvitationsInternal(ListProjectInvitationsCmd cmd) {
-        Long id = cmd.getId();
-        Long projectId = cmd.getProjectId();
-        String accountName = cmd.getAccountName();
-        Long domainId = cmd.getDomainId();
-        String state = cmd.getState();
-        boolean activeOnly = cmd.isActiveOnly();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSizeVal = cmd.getPageSizeVal();
-        boolean isRecursive = cmd.isRecursive();
-        boolean listAll = cmd.listAll();
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
-        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, true);
-        domainId = domainIdRecursiveListProject.first();
-        isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(ProjectInvitationJoinVO.class, "id", true, startIndex, pageSizeVal);
-        SearchBuilder<ProjectInvitationJoinVO> sb = _projectInvitationJoinDao.createSearchBuilder();
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("projectId", sb.entity().getProjectId(), SearchCriteria.Op.EQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("created", sb.entity().getCreated(), SearchCriteria.Op.GT);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<ProjectInvitationJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (projectId != null) {
-            sc.setParameters("projectId", projectId);
-        }
-
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (activeOnly) {
-            sc.setParameters("state", ProjectInvitation.State.Pending);
-            sc.setParameters("created", new Date((DateUtil.currentGMTTime().getTime()) - _projectMgr.getInvitationTimeout()));
-        }
-
-        return _projectInvitationJoinDao.searchAndCount(sc, searchFilter);
-
-    }
-
-    @Override
-    public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd) {
-        Pair<List<ProjectAccountJoinVO>, Integer> projectAccounts = listProjectAccountsInternal(cmd);
-        ListResponse<ProjectAccountResponse> response = new ListResponse<ProjectAccountResponse>();
-        List<ProjectAccountResponse> projectResponses = ViewResponseHelper.createProjectAccountResponse(projectAccounts.first().toArray(new ProjectAccountJoinVO[projectAccounts.first().size()]));
-        response.setResponses(projectResponses, projectAccounts.second());
-        return response;
-    }
-
-    public Pair<List<ProjectAccountJoinVO>, Integer> listProjectAccountsInternal(ListProjectAccountsCmd cmd) {
-        long projectId = cmd.getProjectId();
-        String accountName = cmd.getAccountName();
-        String role = cmd.getRole();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSizeVal = cmd.getPageSizeVal();
-
-        // long projectId, String accountName, String role, Long startIndex,
-        // Long pageSizeVal) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        // check that the project exists
-        Project project = _projectDao.findById(projectId);
-
-        if (project == null) {
-            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
-        }
-
-        // verify permissions - only accounts belonging to the project can list
-        // project's account
-        if (!_accountMgr.isAdmin(caller.getId()) && _projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) {
-            throw new PermissionDeniedException("Account " + caller + " is not authorized to list users of the project id=" + projectId);
-        }
-
-        Filter searchFilter = new Filter(ProjectAccountJoinVO.class, "id", false, startIndex, pageSizeVal);
-        SearchBuilder<ProjectAccountJoinVO> sb = _projectAccountJoinDao.createSearchBuilder();
-        sb.and("accountRole", sb.entity().getAccountRole(), Op.EQ);
-        sb.and("projectId", sb.entity().getProjectId(), Op.EQ);
-
-        if (accountName != null) {
-            sb.and("accountName", sb.entity().getAccountName(), Op.EQ);
-        }
-
-        SearchCriteria<ProjectAccountJoinVO> sc = sb.create();
-
-        sc.setParameters("projectId", projectId);
-
-        if (role != null) {
-            sc.setParameters("accountRole", role);
-        }
-
-        if (accountName != null) {
-            sc.setParameters("accountName", accountName);
-        }
-
-        return _projectAccountJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd) {
-        // FIXME: do we need to support list hosts with VmId, maybe we should
-        // create another command just for this
-        // Right now it is handled separately outside this QueryService
-        s_logger.debug(">>>Searching for hosts>>>");
-        Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(cmd);
-        ListResponse<HostResponse> response = new ListResponse<HostResponse>();
-        s_logger.debug(">>>Generating Response>>>");
-        List<HostResponse> hostResponses = ViewResponseHelper.createHostResponse(cmd.getDetails(), hosts.first().toArray(new HostJoinVO[hosts.first().size()]));
-        response.setResponses(hostResponses, hosts.second());
-        return response;
-    }
-
-    public Pair<List<HostJoinVO>, Integer> searchForServersInternal(ListHostsCmd cmd) {
-
-        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        Object name = cmd.getHostName();
-        Object type = cmd.getType();
-        Object state = cmd.getState();
-        Object pod = cmd.getPodId();
-        Object cluster = cmd.getClusterId();
-        Object id = cmd.getId();
-        Object keyword = cmd.getKeyword();
-        Object outOfBandManagementEnabled = cmd.isOutOfBandManagementEnabled();
-        Object powerState = cmd.getHostOutOfBandManagementPowerState();
-        Object resourceState = cmd.getResourceState();
-        Object haHosts = cmd.getHaHost();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-        Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
-
-        Filter searchFilter = new Filter(HostJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
-        SearchBuilder<HostJoinVO> sb = _hostJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
-        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
-        sb.and("oobmEnabled", sb.entity().isOutOfBandManagementEnabled(), SearchCriteria.Op.EQ);
-        sb.and("powerState", sb.entity().getOutOfBandManagementPowerState(), SearchCriteria.Op.EQ);
-        sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
-        sb.and("hypervisor_type", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-
-        String haTag = _haMgr.getHaTag();
-        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
-            if ((Boolean)haHosts) {
-                sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.EQ);
-            } else {
-                sb.and().op("tag", sb.entity().getTag(), SearchCriteria.Op.NEQ);
-                sb.or("tagNull", sb.entity().getTag(), SearchCriteria.Op.NULL);
-                sb.cp();
-            }
-
-        }
-
-        SearchCriteria<HostJoinVO> sc = sb.create();
-
-        if (keyword != null) {
-            SearchCriteria<HostJoinVO> ssc = _hostJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-        if (type != null) {
-            sc.setParameters("type", "%" + type);
-        }
-        if (state != null) {
-            sc.setParameters("status", state);
-        }
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (pod != null) {
-            sc.setParameters("podId", pod);
-        }
-        if (cluster != null) {
-            sc.setParameters("clusterId", cluster);
-        }
-
-        if (outOfBandManagementEnabled != null) {
-            sc.setParameters("oobmEnabled", outOfBandManagementEnabled);
-        }
-
-        if (powerState != null) {
-            sc.setParameters("powerState", powerState);
-        }
-
-        if (resourceState != null) {
-            sc.setParameters("resourceState", resourceState);
-        }
-
-        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
-            sc.setParameters("tag", haTag);
-        }
-
-        if (hypervisorType != HypervisorType.None && hypervisorType != HypervisorType.Any) {
-            sc.setParameters("hypervisor_type", hypervisorType);
-        }
-        // search host details by ids
-        Pair<List<HostJoinVO>, Integer> uniqueHostPair = _hostJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueHostPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return uniqueHostPair;
-        }
-        List<HostJoinVO> uniqueHosts = uniqueHostPair.first();
-        Long[] hostIds = new Long[uniqueHosts.size()];
-        int i = 0;
-        for (HostJoinVO v : uniqueHosts) {
-            hostIds[i++] = v.getId();
-        }
-        List<HostJoinVO> hosts = _hostJoinDao.searchByIds(hostIds);
-        return new Pair<List<HostJoinVO>, Integer>(hosts, count);
-
-    }
-
-    @Override
-    public ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd) {
-        Pair<List<VolumeJoinVO>, Integer> result = searchForVolumesInternal(cmd);
-        ListResponse<VolumeResponse> response = new ListResponse<VolumeResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListVolumesCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<VolumeResponse> volumeResponses = ViewResponseHelper.createVolumeResponse(respView, result.first().toArray(new VolumeJoinVO[result.first().size()]));
-
-        for (VolumeResponse vr : volumeResponses) {
-            String poolId = vr.getStoragePoolId();
-            if (poolId == null) {
-                continue;
-            }
-
-            DataStore store = dataStoreManager.getPrimaryDataStore(poolId);
-            if (store == null) {
-                continue;
-            }
-
-            DataStoreDriver driver = store.getDriver();
-            if (driver == null) {
-                continue;
-            }
-
-            Map<String, String> caps = driver.getCapabilities();
-            if (caps != null) {
-                boolean quiescevm = Boolean.parseBoolean(caps.get(DataStoreCapabilities.VOLUME_SNAPSHOT_QUIESCEVM.toString()));
-                vr.setNeedQuiescevm(quiescevm);
-            }
-        }
-        response.setResponses(volumeResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<VolumeJoinVO>, Integer> searchForVolumesInternal(ListVolumesCmd cmd) {
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Long id = cmd.getId();
-        Long vmInstanceId = cmd.getVirtualMachineId();
-        String name = cmd.getVolumeName();
-        String keyword = cmd.getKeyword();
-        String type = cmd.getType();
-        Map<String, String> tags = cmd.getTags();
-        String storageId = cmd.getStorageId();
-        Long clusterId = cmd.getClusterId();
-        Long diskOffId = cmd.getDiskOfferingId();
-        Boolean display = cmd.getDisplay();
-
-        Long zoneId = cmd.getZoneId();
-        Long podId = cmd.getPodId();
-
-        List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        // hack for now, this should be done better but due to needing a join I
-        // opted to
-        // do this quickly and worry about making it pretty later
-        SearchBuilder<VolumeJoinVO> sb = _volumeJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids to get
-        // number of
-        // records with
-        // pagination
-        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
-        sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
-        sb.and("uuid", sb.entity().getUuid(), SearchCriteria.Op.NNULL);
-        sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.EQ);
-        sb.and("diskOfferingId", sb.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
-        // Only return volumes that are not destroyed
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
-        sb.and("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
-        // display UserVM volumes only
-        sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
-        sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
-        sb.cp();
-
-        // now set the SC criteria...
-        SearchCriteria<VolumeJoinVO> sc = sb.create();
-        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            SearchCriteria<VolumeJoinVO> ssc = _volumeJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", name);
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        setIdsListToSearchCriteria(sc, ids);
-
-        sc.setParameters("systemUse", 1);
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchCriteria<VolumeJoinVO> tagSc = _volumeJoinDao.createSearchCriteria();
-            for (String key : tags.keySet()) {
-                SearchCriteria<VolumeJoinVO> tsc = _volumeJoinDao.createSearchCriteria();
-                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, key);
-                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key));
-                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
-            }
-            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
-        }
-
-        if (diskOffId != null) {
-            sc.setParameters("diskOfferingId", diskOffId);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (type != null) {
-            sc.setParameters("volumeType", "%" + type + "%");
-        }
-        if (vmInstanceId != null) {
-            sc.setParameters("instanceId", vmInstanceId);
-        }
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (podId != null) {
-            sc.setParameters("podId", podId);
-        }
-
-        if (storageId != null) {
-            sc.setParameters("storageId", storageId);
-        }
-
-        if (clusterId != null) {
-            sc.setParameters("clusterId", clusterId);
-        }
-        // Don't return DomR and ConsoleProxy volumes
-        sc.setParameters("type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
-
-        // Only return volumes that are not destroyed
-        sc.setParameters("state", Volume.State.Destroy);
-
-        // search Volume details by ids
-        Pair<List<VolumeJoinVO>, Integer> uniqueVolPair = _volumeJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueVolPair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniqueVolPair;
-        }
-        List<VolumeJoinVO> uniqueVols = uniqueVolPair.first();
-        Long[] vrIds = new Long[uniqueVols.size()];
-        int i = 0;
-        for (VolumeJoinVO v : uniqueVols) {
-            vrIds[i++] = v.getId();
-        }
-        List<VolumeJoinVO> vrs = _volumeJoinDao.searchByIds(vrIds);
-        return new Pair<List<VolumeJoinVO>, Integer>(vrs, count);
-    }
-
-    @Override
-    public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd) {
-        Pair<List<DomainJoinVO>, Integer> result = searchForDomainsInternal(cmd);
-        ListResponse<DomainResponse> response = new ListResponse<DomainResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListDomainsCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<DomainResponse> domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first());
-        response.setResponses(domainResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<DomainJoinVO>, Integer> searchForDomainsInternal(ListDomainsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long domainId = cmd.getId();
-        boolean listAll = cmd.listAll();
-        boolean isRecursive = false;
-        Domain domain = null;
-
-        if (domainId != null) {
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
-            }
-            _accountMgr.checkAccess(caller, domain);
-        } else {
-            if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-                domainId = caller.getDomainId();
-            }
-            if (listAll) {
-                isRecursive = true;
-            }
-        }
-
-        Filter searchFilter = new Filter(DomainJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        String domainName = cmd.getDomainName();
-        Integer level = cmd.getLevel();
-        Object keyword = cmd.getKeyword();
-
-        SearchBuilder<DomainJoinVO> sb = _domainJoinDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ);
-        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<DomainJoinVO> sc = sb.create();
-
-        if (keyword != null) {
-            SearchCriteria<DomainJoinVO> ssc = _domainJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (domainName != null) {
-            sc.setParameters("name", domainName);
-        }
-
-        if (level != null) {
-            sc.setParameters("level", level);
-        }
-
-        if (domainId != null) {
-            if (isRecursive) {
-                if (domain == null) {
-                    domain = _domainDao.findById(domainId);
-                }
-                sc.setParameters("path", domain.getPath() + "%");
-            } else {
-                sc.setParameters("id", domainId);
-            }
-        }
-
-        // return only Active domains to the API
-        sc.setParameters("state", Domain.State.Active);
-
-        return _domainJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd) {
-        Pair<List<AccountJoinVO>, Integer> result = searchForAccountsInternal(cmd);
-        ListResponse<AccountResponse> response = new ListResponse<AccountResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListAccountsCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<AccountResponse> accountResponses = ViewResponseHelper.createAccountResponse(respView, result.first().toArray(new AccountJoinVO[result.first().size()]));
-        response.setResponses(accountResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccountsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long domainId = cmd.getDomainId();
-        Long accountId = cmd.getId();
-        String accountName = cmd.getSearchName();
-        boolean isRecursive = cmd.isRecursive();
-        boolean listAll = cmd.listAll();
-        boolean callerIsAdmin = _accountMgr.isAdmin(caller.getId());
-        Account account;
-        Domain domain = null;
-
-        // if "domainid" specified, perform validation
-        if (domainId != null) {
-            // ensure existence...
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
-            }
-            // ... and check access rights.
-            _accountMgr.checkAccess(caller, domain);
-        }
-
-        // if no "id" specified...
-        if (accountId == null) {
-            // listall only has significance if they are an admin
-            if (listAll && callerIsAdmin) {
-                // if no domain id specified, use caller's domain
-                if (domainId == null) {
-                    domainId = caller.getDomainId();
-                }
-                // mark recursive
-                isRecursive = true;
-            } else if (!callerIsAdmin || domainId == null) {
-                accountId = caller.getAccountId();
-            }
-        } else if (domainId != null && accountName != null) {
-            // if they're looking for an account by name
-            account = _accountDao.findActiveAccount(accountName, domainId);
-            if (account == null || account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain " + domainId);
-            }
-            _accountMgr.checkAccess(caller, null, true, account);
-        } else {
-            // if they specified an "id"...
-            if (domainId == null) {
-                account = _accountDao.findById(accountId);
-            } else {
-                account = _accountDao.findActiveAccountById(accountId, domainId);
-            }
-            if (account == null || account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-                throw new InvalidParameterValueException("Unable to find account by id " + accountId + (domainId == null ? "" : " in domain " + domainId));
-            }
-            _accountMgr.checkAccess(caller, null, true, account);
-        }
-
-        Filter searchFilter = new Filter(AccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        Object type = cmd.getAccountType();
-        Object state = cmd.getState();
-        Object isCleanupRequired = cmd.isCleanupRequired();
-        Object keyword = cmd.getKeyword();
-
-        SearchBuilder<AccountJoinVO> sb = _accountJoinDao.createSearchBuilder();
-        sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ);
-        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("needsCleanup", sb.entity().isNeedsCleanup(), SearchCriteria.Op.EQ);
-        sb.and("typeNEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);
-        sb.and("idNEQ", sb.entity().getId(), SearchCriteria.Op.NEQ);
-
-        if (domainId != null && isRecursive) {
-            sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-        }
-
-        SearchCriteria<AccountJoinVO> sc = sb.create();
-
-        // don't return account of type project to the end user
-        sc.setParameters("typeNEQ", Account.ACCOUNT_TYPE_PROJECT);
-        // don't return system account...
-        sc.setParameters("idNEQ", Account.ACCOUNT_ID_SYSTEM);
-
-        if (keyword != null) {
-            SearchCriteria<AccountJoinVO> ssc = _accountJoinDao.createSearchCriteria();
-            ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("accountName", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (type != null) {
-            sc.setParameters("type", type);
-        }
-
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-
-        if (isCleanupRequired != null) {
-            sc.setParameters("needsCleanup", isCleanupRequired);
-        }
-
-        if (accountName != null) {
-            sc.setParameters("accountName", accountName);
-        }
-
-        if (accountId != null) {
-            sc.setParameters("id", accountId);
-        }
-
-        if (domainId != null) {
-            if (isRecursive) {
-                // will happen if no "domainid" was specified in the request...
-                if (domain == null) {
-                    domain = _domainDao.findById(domainId);
-                }
-                sc.setParameters("path", domain.getPath() + "%");
-            } else {
-                sc.setParameters("domainId", domainId);
-            }
-        }
-
-        return _accountJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<AsyncJobResponse> searchForAsyncJobs(ListAsyncJobsCmd cmd) {
-        Pair<List<AsyncJobJoinVO>, Integer> result = searchForAsyncJobsInternal(cmd);
-        ListResponse<AsyncJobResponse> response = new ListResponse<AsyncJobResponse>();
-        List<AsyncJobResponse> jobResponses = ViewResponseHelper.createAsyncJobResponse(result.first().toArray(new AsyncJobJoinVO[result.first().size()]));
-        response.setResponses(jobResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<AsyncJobJoinVO>, Integer> searchForAsyncJobsInternal(ListAsyncJobsCmd cmd) {
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(AsyncJobJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<AsyncJobJoinVO> sb = _jobJoinDao.createSearchBuilder();
-        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
-        boolean accountJoinIsDone = false;
-        if (permittedAccounts.isEmpty() && domainId != null) {
-            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-            sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-            accountJoinIsDone = true;
-        }
-
-        if (listProjectResourcesCriteria != null) {
-
-            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
-                sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
-            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
-                sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
-            }
-
-            if (!accountJoinIsDone) {
-                sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-                sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-            }
-        }
-
-        Object keyword = cmd.getKeyword();
-        Object startDate = cmd.getStartDate();
-
-        SearchCriteria<AsyncJobJoinVO> sc = sb.create();
-        if (listProjectResourcesCriteria != null) {
-            sc.setParameters("type", Account.ACCOUNT_TYPE_PROJECT);
-        }
-
-        if (!permittedAccounts.isEmpty()) {
-            sc.setParameters("accountIdIN", permittedAccounts.toArray());
-        } else if (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            if (isRecursive) {
-                sc.setParameters("path", domain.getPath() + "%");
-            } else {
-                sc.setParameters("domainId", domainId);
-            }
-        }
-
-        if (keyword != null) {
-            sc.addAnd("cmd", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-        }
-
-        if (startDate != null) {
-            sc.addAnd("created", SearchCriteria.Op.GTEQ, startDate);
-        }
-
-        return _jobJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public ListResponse<StoragePoolResponse> searchForStoragePools(ListStoragePoolsCmd cmd) {
-        Pair<List<StoragePoolJoinVO>, Integer> result = searchForStoragePoolsInternal(cmd);
-        ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
-
-        List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(result.first().toArray(new StoragePoolJoinVO[result.first().size()]));
-        for (StoragePoolResponse poolResponse : poolResponses) {
-            DataStore store = dataStoreManager.getPrimaryDataStore(poolResponse.getId());
-            if (store != null) {
-                DataStoreDriver driver = store.getDriver();
-                if (driver != null && driver.getCapabilities() != null) {
-                    poolResponse.setCaps(driver.getCapabilities());
-                }
-            }
-        }
-
-        response.setResponses(poolResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<StoragePoolJoinVO>, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) {
-        ScopeType scopeType = null;
-        if (cmd.getScope() != null) {
-            try {
-                scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase());
-            } catch (Exception e) {
-                throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope());
-            }
-        }
-
-        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        Object id = cmd.getId();
-        Object name = cmd.getStoragePoolName();
-        Object path = cmd.getPath();
-        Object pod = cmd.getPodId();
-        Object cluster = cmd.getClusterId();
-        Object address = cmd.getIpAddress();
-        Object keyword = cmd.getKeyword();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        Filter searchFilter = new Filter(StoragePoolJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
-        SearchBuilder<StoragePoolJoinVO> sb = _poolJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
-        sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
-        sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<StoragePoolJoinVO> sc = sb.create();
-
-        if (keyword != null) {
-            SearchCriteria<StoragePoolJoinVO> ssc = _poolJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", name);
-        }
-
-        if (path != null) {
-            sc.setParameters("path", path);
-        }
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (pod != null) {
-            sc.setParameters("podId", pod);
-        }
-        if (address != null) {
-            sc.setParameters("hostAddress", address);
-        }
-        if (cluster != null) {
-            sc.setParameters("clusterId", cluster);
-        }
-        if (scopeType != null) {
-            sc.setParameters("scope", scopeType.toString());
-        }
-
-        // search Pool details by ids
-        Pair<List<StoragePoolJoinVO>, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniquePoolPair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniquePoolPair;
-        }
-        List<StoragePoolJoinVO> uniquePools = uniquePoolPair.first();
-        Long[] vrIds = new Long[uniquePools.size()];
-        int i = 0;
-        for (StoragePoolJoinVO v : uniquePools) {
-            vrIds[i++] = v.getId();
-        }
-        List<StoragePoolJoinVO> vrs = _poolJoinDao.searchByIds(vrIds);
-        return new Pair<List<StoragePoolJoinVO>, Integer>(vrs, count);
-
-    }
-
-    @Override
-    public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd) {
-        Pair<List<StoragePoolTagVO>, Integer> result = searchForStorageTagsInternal(cmd);
-        ListResponse<StorageTagResponse> response = new ListResponse<StorageTagResponse>();
-        List<StorageTagResponse> tagResponses = ViewResponseHelper.createStorageTagResponse(result.first().toArray(new StoragePoolTagVO[result.first().size()]));
-
-        response.setResponses(tagResponses, result.second());
-
-        return response;
-    }
-
-    private Pair<List<StoragePoolTagVO>, Integer> searchForStorageTagsInternal(ListStorageTagsCmd cmd) {
-        Filter searchFilter = new Filter(StoragePoolTagVO.class, "id", Boolean.TRUE, null, null);
-
-        SearchBuilder<StoragePoolTagVO> sb = _storageTagDao.createSearchBuilder();
-
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-
-        SearchCriteria<StoragePoolTagVO> sc = sb.create();
-
-        // search storage tag details by ids
-        Pair<List<StoragePoolTagVO>, Integer> uniqueTagPair = _storageTagDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueTagPair.second();
-
-        if (count.intValue() == 0) {
-            return uniqueTagPair;
-        }
-
-        List<StoragePoolTagVO> uniqueTags = uniqueTagPair.first();
-        Long[] vrIds = new Long[uniqueTags.size()];
-        int i = 0;
-
-        for (StoragePoolTagVO v : uniqueTags) {
-            vrIds[i++] = v.getId();
-        }
-
-        List<StoragePoolTagVO> vrs = _storageTagDao.searchByIds(vrIds);
-
-        return new Pair<List<StoragePoolTagVO>, Integer>(vrs, count);
-    }
-
-    @Override
-    public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
-        Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
-        ListResponse<HostTagResponse> response = new ListResponse<HostTagResponse>();
-        List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
-
-        response.setResponses(tagResponses, result.second());
-
-        return response;
-    }
-
-    private Pair<List<HostTagVO>, Integer> searchForHostTagsInternal(ListHostTagsCmd cmd) {
-        Filter searchFilter = new Filter(HostTagVO.class, "id", Boolean.TRUE, null, null);
-
-        SearchBuilder<HostTagVO> sb = _hostTagDao.createSearchBuilder();
-
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-
-        SearchCriteria<HostTagVO> sc = sb.create();
-
-        // search host tag details by ids
-        Pair<List<HostTagVO>, Integer> uniqueTagPair = _hostTagDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueTagPair.second();
-
-        if (count.intValue() == 0) {
-            return uniqueTagPair;
-        }
-
-        List<HostTagVO> uniqueTags = uniqueTagPair.first();
-        Long[] vrIds = new Long[uniqueTags.size()];
-        int i = 0;
-
-        for (HostTagVO v : uniqueTags) {
-            vrIds[i++] = v.getId();
-        }
-
-        List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
-
-        return new Pair<List<HostTagVO>, Integer>(vrs, count);
-    }
-
-    @Override
-    public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
-        Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);
-        ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
-
-        List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
-        response.setResponses(poolResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<ImageStoreJoinVO>, Integer> searchForImageStoresInternal(ListImageStoresCmd cmd) {
-
-        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        Object id = cmd.getId();
-        Object name = cmd.getStoreName();
-        String provider = cmd.getProvider();
-        String protocol = cmd.getProtocol();
-        Object keyword = cmd.getKeyword();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
-        SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ);
-        sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
-        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<ImageStoreJoinVO> sc = sb.create();
-        sc.setParameters("role", DataStoreRole.Image);
-
-        if (keyword != null) {
-            SearchCriteria<ImageStoreJoinVO> ssc = _imageStoreJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("providerName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", name);
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (provider != null) {
-            sc.setParameters("provider", provider);
-        }
-        if (protocol != null) {
-            sc.setParameters("protocol", protocol);
-        }
-
-        // search Store details by ids
-        Pair<List<ImageStoreJoinVO>, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueStorePair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniqueStorePair;
-        }
-        List<ImageStoreJoinVO> uniqueStores = uniqueStorePair.first();
-        Long[] vrIds = new Long[uniqueStores.size()];
-        int i = 0;
-        for (ImageStoreJoinVO v : uniqueStores) {
-            vrIds[i++] = v.getId();
-        }
-        List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
-        return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
-
-    }
-
-    @Override
-    public ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd) {
-        Pair<List<ImageStoreJoinVO>, Integer> result = searchForCacheStoresInternal(cmd);
-        ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
-
-        List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
-        response.setResponses(poolResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<ImageStoreJoinVO>, Integer> searchForCacheStoresInternal(ListSecondaryStagingStoresCmd cmd) {
-
-        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        Object id = cmd.getId();
-        Object name = cmd.getStoreName();
-        String provider = cmd.getProvider();
-        String protocol = cmd.getProtocol();
-        Object keyword = cmd.getKeyword();
-        Long startIndex = cmd.getStartIndex();
-        Long pageSize = cmd.getPageSizeVal();
-
-        Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
-        SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
-        // ids
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ);
-        sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
-        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<ImageStoreJoinVO> sc = sb.create();
-        sc.setParameters("role", DataStoreRole.ImageCache);
-
-        if (keyword != null) {
-            SearchCriteria<ImageStoreJoinVO> ssc = _imageStoreJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("provider", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", name);
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (provider != null) {
-            sc.setParameters("provider", provider);
-        }
-        if (protocol != null) {
-            sc.setParameters("protocol", protocol);
-        }
-
-        // search Store details by ids
-        Pair<List<ImageStoreJoinVO>, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter);
-        Integer count = uniqueStorePair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniqueStorePair;
-        }
-        List<ImageStoreJoinVO> uniqueStores = uniqueStorePair.first();
-        Long[] vrIds = new Long[uniqueStores.size()];
-        int i = 0;
-        for (ImageStoreJoinVO v : uniqueStores) {
-            vrIds[i++] = v.getId();
-        }
-        List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
-        return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
-
-    }
-
-    @Override
-    public ListResponse<DiskOfferingResponse> searchForDiskOfferings(ListDiskOfferingsCmd cmd) {
-        Pair<List<DiskOfferingJoinVO>, Integer> result = searchForDiskOfferingsInternal(cmd);
-        ListResponse<DiskOfferingResponse> response = new ListResponse<DiskOfferingResponse>();
-        List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponse(result.first().toArray(new DiskOfferingJoinVO[result.first().size()]));
-        response.setResponses(offeringResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(ListDiskOfferingsCmd cmd) {
-        // Note
-        // The list method for offerings is being modified in accordance with
-        // discussion with Will/Kevin
-        // For now, we will be listing the following based on the usertype
-        // 1. For root, we will list all offerings
-        // 2. For domainAdmin and regular users, we will list everything in
-        // their domains+parent domains ... all the way
-        // till
-        // root
-
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = (isAscending == null ? true : isAscending);
-        Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
-        sc.addAnd("type", Op.EQ, DiskOfferingVO.Type.Disk);
-
-        Account account = CallContext.current().getCallingAccount();
-        Object name = cmd.getDiskOfferingName();
-        Object id = cmd.getId();
-        Object keyword = cmd.getKeyword();
-        Long domainId = cmd.getDomainId();
-        Boolean isRootAdmin = _accountMgr.isRootAdmin(account.getAccountId());
-        Boolean isRecursive = cmd.isRecursive();
-        // Keeping this logic consistent with domain specific zones
-        // if a domainId is provided, we just return the disk offering
-        // associated with this domain
-        if (domainId != null) {
-            if (_accountMgr.isRootAdmin(account.getId()) || isPermissible(account.getDomainId(), domainId)) {
-                // check if the user's domain == do's domain || user's domain is
-                // a child of so's domain for non-root users
-                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
-                if (!isRootAdmin) {
-                    sc.addAnd("displayOffering", SearchCriteria.Op.EQ, 1);
-                }
-                return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
-            } else {
-                throw new PermissionDeniedException("The account:" + account.getAccountName() + " does not fall in the same domain hierarchy as the disk offering");
-            }
-        }
-
-        List<Long> domainIds = null;
-        // For non-root users, only return all offerings for the user's domain,
-        // and everything above till root
-        if ((_accountMgr.isNormalUser(account.getId()) || _accountMgr.isDomainAdmin(account.getId())) || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-            if (isRecursive) { // domain + all sub-domains
-                if (account.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                    throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list disk offerings with isrecursive=true");
-                }
-                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domainRecord.getPath() + "%");
-            } else { // domain + all ancestors
-                // find all domain Id up to root domain for this account
-                domainIds = new ArrayList<Long>();
-                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-                if (domainRecord == null) {
-                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
-                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
-                }
-                domainIds.add(domainRecord.getId());
-                while (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                    domainIds.add(domainRecord.getId());
-                }
-
-                SearchCriteria<DiskOfferingJoinVO> spc = _diskOfferingJoinDao.createSearchCriteria();
-
-                spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
-                spc.addOr("domainId", SearchCriteria.Op.NULL); // include public offering as where
-                sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
-                sc.addAnd("systemUse", SearchCriteria.Op.EQ, false); // non-root users should not see system offering at all
-            }
-
-        }
-
-        if (keyword != null) {
-            SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        }
-
-        // FIXME: disk offerings should search back up the hierarchy for
-        // available disk offerings...
-        /*
-         * sb.addAnd("domainId", sb.entity().getDomainId(),
-         * SearchCriteria.Op.EQ); if (domainId != null) {
-         * SearchBuilder<DomainVO> domainSearch =
-         * _domainDao.createSearchBuilder(); domainSearch.addAnd("path",
-         * domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
-         * sb.join("domainSearch", domainSearch, sb.entity().getDomainId(),
-         * domainSearch.entity().getId()); }
-         */
-
-        // FIXME: disk offerings should search back up the hierarchy for
-        // available disk offerings...
-        /*
-         * if (domainId != null) { sc.setParameters("domainId", domainId); //
-         * //DomainVO domain = _domainDao.findById((Long)domainId); // // I want
-         * to join on user_vm.domain_id = domain.id where domain.path like
-         * 'foo%' //sc.setJoinParameters("domainSearch", "path",
-         * domain.getPath() + "%"); // }
-         */
-
-        return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    private List<ServiceOfferingJoinVO> filterOfferingsOnCurrentTags(List<ServiceOfferingJoinVO> offerings, ServiceOfferingVO currentVmOffering) {
-        if (currentVmOffering == null) {
-            return offerings;
-        }
-        List<String> currentTagsList = StringUtils.csvTagsToList(currentVmOffering.getTags());
-
-        // New service offering should have all the tags of the current service offering.
-        List<ServiceOfferingJoinVO> filteredOfferings = new ArrayList<>();
-        for (ServiceOfferingJoinVO offering : offerings) {
-            List<String> newTagsList = StringUtils.csvTagsToList(offering.getTags());
-            if (newTagsList.containsAll(currentTagsList)) {
-                filteredOfferings.add(offering);
-            }
-        }
-        return filteredOfferings;
-    }
-
-    @Override
-    public ListResponse<ServiceOfferingResponse> searchForServiceOfferings(ListServiceOfferingsCmd cmd) {
-        Pair<List<ServiceOfferingJoinVO>, Integer> result = searchForServiceOfferingsInternal(cmd);
-        result.first();
-        ListResponse<ServiceOfferingResponse> response = new ListResponse<ServiceOfferingResponse>();
-        List<ServiceOfferingResponse> offeringResponses = ViewResponseHelper.createServiceOfferingResponse(result.first().toArray(new ServiceOfferingJoinVO[result.first().size()]));
-        response.setResponses(offeringResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
-        // Note
-        // The filteredOfferings method for offerings is being modified in accordance with
-        // discussion with Will/Kevin
-        // For now, we will be listing the following based on the usertype
-        // 1. For root, we will filteredOfferings all offerings
-        // 2. For domainAdmin and regular users, we will filteredOfferings everything in
-        // their domains+parent domains ... all the way
-        // till
-        // root
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = (isAscending == null ? true : isAscending);
-        Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        Account caller = CallContext.current().getCallingAccount();
-        Object name = cmd.getServiceOfferingName();
-        Object id = cmd.getId();
-        Object keyword = cmd.getKeyword();
-        Long vmId = cmd.getVirtualMachineId();
-        Long domainId = cmd.getDomainId();
-        Boolean isSystem = cmd.getIsSystem();
-        String vmTypeStr = cmd.getSystemVmType();
-        ServiceOfferingVO currentVmOffering = null;
-        Boolean isRecursive = cmd.isRecursive();
-
-        SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
-        if (!_accountMgr.isRootAdmin(caller.getId()) && isSystem) {
-            throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
-        }
-
-        // Keeping this logic consistent with domain specific zones
-        // if a domainId is provided, we just return the so associated with this
-        // domain
-        if (domainId != null && !_accountMgr.isRootAdmin(caller.getId())) {
-            // check if the user's domain == so's domain || user's domain is a
-            // child of so's domain
-            if (!isPermissible(caller.getDomainId(), domainId)) {
-                throw new PermissionDeniedException("The account:" + caller.getAccountName() + " does not fall in the same domain hierarchy as the service offering");
-            }
-        }
-
-        if (vmId != null) {
-            VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-            if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
-                ex.addProxyObject(vmId.toString(), "vmId");
-                throw ex;
-            }
-
-            _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-            currentVmOffering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
-            sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
-
-            // 1. Only return offerings with the same storage type
-            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, currentVmOffering.getUseLocalStorage());
-
-            // 2.In case vm is running return only offerings greater than equal to current offering compute.
-            if (vmInstance.getState() == VirtualMachine.State.Running) {
-                sc.addAnd("cpu", Op.GTEQ, currentVmOffering.getCpu());
-                sc.addAnd("speed", Op.GTEQ, currentVmOffering.getSpeed());
-                sc.addAnd("ramSize", Op.GTEQ, currentVmOffering.getRamSize());
-            }
-        }
-
-        // boolean includePublicOfferings = false;
-        if ((_accountMgr.isNormalUser(caller.getId()) || _accountMgr.isDomainAdmin(caller.getId())) || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-            // For non-root users.
-            if (isSystem) {
-                throw new InvalidParameterValueException("Only root admins can access system's offering");
-            }
-            if (isRecursive) { // domain + all sub-domains
-                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                    throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list service offerings with isrecursive=true");
-                }
-                DomainVO domainRecord = _domainDao.findById(caller.getDomainId());
-                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domainRecord.getPath() + "%");
-            } else { // domain + all ancestors
-                // find all domain Id up to root domain for this account
-                List<Long> domainIds = new ArrayList<Long>();
-                DomainVO domainRecord;
-                if (vmId != null) {
-                    UserVmVO vmInstance = _userVmDao.findById(vmId);
-                    domainRecord = _domainDao.findById(vmInstance.getDomainId());
-                    if (domainRecord == null) {
-                        s_logger.error("Could not find the domainId for vmId:" + vmId);
-                        throw new CloudAuthenticationException("Could not find the domainId for vmId:" + vmId);
-                    }
-                } else {
-                    domainRecord = _domainDao.findById(caller.getDomainId());
-                    if (domainRecord == null) {
-                        s_logger.error("Could not find the domainId for account:" + caller.getAccountName());
-                        throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName());
-                    }
-                }
-                domainIds.add(domainRecord.getId());
-                while (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                    domainIds.add(domainRecord.getId());
-                }
-
-                SearchCriteria<ServiceOfferingJoinVO> spc = _srvOfferingJoinDao.createSearchCriteria();
-                spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
-                spc.addOr("domainId", SearchCriteria.Op.NULL); // include public offering as well
-                sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
-            }
-        } else {
-            // for root users
-            if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
-                throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
-            }
-            if (domainId != null) {
-                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
-            }
-        }
-
-        if (keyword != null) {
-            SearchCriteria<ServiceOfferingJoinVO> ssc = _srvOfferingJoinDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (isSystem != null) {
-            // note that for non-root users, isSystem is always false when
-            // control comes to here
-            sc.addAnd("systemUse", SearchCriteria.Op.EQ, isSystem);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        }
-
-        if (vmTypeStr != null) {
-            sc.addAnd("vmType", SearchCriteria.Op.EQ, vmTypeStr);
-        }
-
-        Pair<List<ServiceOfferingJoinVO>, Integer> result = _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
-
-        //Couldn't figure out a smart way to filter offerings based on tags in sql so doing it in Java.
-        List<ServiceOfferingJoinVO> filteredOfferings = filterOfferingsOnCurrentTags(result.first(), currentVmOffering);
-        return new Pair<>(filteredOfferings, result.second());
-    }
-
-    @Override
-    public ListResponse<ZoneResponse> listDataCenters(ListZonesCmd cmd) {
-        Pair<List<DataCenterJoinVO>, Integer> result = listDataCentersInternal(cmd);
-        ListResponse<ZoneResponse> response = new ListResponse<ZoneResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListZonesCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<ZoneResponse> dcResponses = ViewResponseHelper.createDataCenterResponse(respView, cmd.getShowCapacities(), result.first().toArray(new DataCenterJoinVO[result.first().size()]));
-        response.setResponses(dcResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<DataCenterJoinVO>, Integer> listDataCentersInternal(ListZonesCmd cmd) {
-        Account account = CallContext.current().getCallingAccount();
-        Long domainId = cmd.getDomainId();
-        Long id = cmd.getId();
-        String keyword = cmd.getKeyword();
-        String name = cmd.getName();
-        String networkType = cmd.getNetworkType();
-        Map<String, String> resourceTags = cmd.getTags();
-
-        SearchBuilder<DataCenterJoinVO> sb = _dcJoinDao.createSearchBuilder();
-        if (resourceTags != null && !resourceTags.isEmpty()) {
-            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < resourceTags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchCriteria<DataCenterJoinVO> sc = sb.create();
-
-        if (networkType != null) {
-            sc.addAnd("networkType", SearchCriteria.Op.EQ, networkType);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        } else if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        } else {
-            if (keyword != null) {
-                SearchCriteria<DataCenterJoinVO> ssc = _dcJoinDao.createSearchCriteria();
-                ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-                ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-                sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-            }
-
-            /*
-             * List all resources due to Explicit Dedication except the
-             * dedicated resources of other account
-             */
-            if (domainId != null) { //
-                // for domainId != null // right now, we made the decision to
-                // only list zones associated // with this domain, private zone
-                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
-
-                if (_accountMgr.isNormalUser(account.getId())) {
-                    // accountId == null (zones dedicated to a domain) or
-                    // accountId = caller
-                    SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
-                    sdc.addOr("accountId", SearchCriteria.Op.EQ, account.getId());
-                    sdc.addOr("accountId", SearchCriteria.Op.NULL);
-
-                    sc.addAnd("accountId", SearchCriteria.Op.SC, sdc);
-                }
-
-            } else if (_accountMgr.isNormalUser(account.getId())) {
-                // it was decided to return all zones for the user's domain, and
-                // everything above till root
-                // list all zones belonging to this domain, and all of its
-                // parents
-                // check the parent, if not null, add zones for that parent to
-                // list
-
-                // find all domain Id up to root domain for this account
-                List<Long> domainIds = new ArrayList<Long>();
-                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-                if (domainRecord == null) {
-                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
-                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
-                }
-                domainIds.add(domainRecord.getId());
-                while (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                    domainIds.add(domainRecord.getId());
-                }
-                // domainId == null (public zones) or domainId IN [all domain id
-                // up to root domain]
-                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
-                sdc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
-                sdc.addOr("domainId", SearchCriteria.Op.NULL);
-                sc.addAnd("domainId", SearchCriteria.Op.SC, sdc);
-
-                // remove disabled zones
-                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
-
-                // accountId == null (zones dedicated to a domain) or
-                // accountId = caller
-                SearchCriteria<DataCenterJoinVO> sdc2 = _dcJoinDao.createSearchCriteria();
-                sdc2.addOr("accountId", SearchCriteria.Op.EQ, account.getId());
-                sdc2.addOr("accountId", SearchCriteria.Op.NULL);
-
-                sc.addAnd("accountId", SearchCriteria.Op.SC, sdc2);
-
-                // remove Dedicated zones not dedicated to this domainId or
-                // subdomainId
-                List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
-                if (!dedicatedZoneIds.isEmpty()) {
-                    sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
-                }
-
-            } else if (_accountMgr.isDomainAdmin(account.getId()) || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-                // it was decided to return all zones for the domain admin, and
-                // everything above till root, as well as zones till the domain
-                // leaf
-                List<Long> domainIds = new ArrayList<Long>();
-                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
-                if (domainRecord == null) {
-                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
-                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
-                }
-                domainIds.add(domainRecord.getId());
-                // find all domain Ids till leaf
-                List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
-                for (DomainVO domain : allChildDomains) {
-                    domainIds.add(domain.getId());
-                }
-                // then find all domain Id up to root domain for this account
-                while (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                    domainIds.add(domainRecord.getId());
-                }
-
-                // domainId == null (public zones) or domainId IN [all domain id
-                // up to root domain]
-                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
-                sdc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
-                sdc.addOr("domainId", SearchCriteria.Op.NULL);
-                sc.addAnd("domainId", SearchCriteria.Op.SC, sdc);
-
-                // remove disabled zones
-                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
-
-                // remove Dedicated zones not dedicated to this domainId or
-                // subdomainId
-                List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
-                if (!dedicatedZoneIds.isEmpty()) {
-                    sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
-                }
-            }
-
-            // handle available=FALSE option, only return zones with at least
-            // one VM running there
-            Boolean available = cmd.isAvailable();
-            if (account != null) {
-                if ((available != null) && Boolean.FALSE.equals(available)) {
-                    Set<Long> dcIds = new HashSet<Long>(); // data centers with
-                    // at least one VM
-                    // running
-                    List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
-                    for (DomainRouterVO router : routers) {
-                        dcIds.add(router.getDataCenterId());
-                    }
-                    if (dcIds.size() == 0) {
-                        return new Pair<List<DataCenterJoinVO>, Integer>(new ArrayList<DataCenterJoinVO>(), 0);
-                    } else {
-                        sc.addAnd("id", SearchCriteria.Op.IN, dcIds.toArray());
-                    }
-
-                }
-            }
-        }
-
-        if (resourceTags != null && !resourceTags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Zone.toString());
-            for (Map.Entry<String, String> entry : resourceTags.entrySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
-                count++;
-            }
-        }
-
-        return _dcJoinDao.searchAndCount(sc, searchFilter);
-    }
-
-    private List<Long> removeDedicatedZoneNotSuitabe(List<Long> domainIds) {
-        // remove dedicated zone of other domain
-        List<Long> dedicatedZoneIds = new ArrayList<Long>();
-        List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listZonesNotInDomainIds(domainIds);
-        for (DedicatedResourceVO dr : dedicatedResources) {
-            if (dr != null) {
-                dedicatedZoneIds.add(dr.getDataCenterId());
-            }
-        }
-        return dedicatedZoneIds;
-    }
-
-    // This method is used for permissions check for both disk and service
-    // offerings
-    private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {
-
-        if (accountDomainId.equals(offeringDomainId)) {
-            return true; // account and service offering in same domain
-        }
-
-        DomainVO domainRecord = _domainDao.findById(accountDomainId);
-
-        if (domainRecord != null) {
-            while (true) {
-                if (domainRecord.getId() == offeringDomainId) {
-                    return true;
-                }
-
-                // try and move on to the next domain
-                if (domainRecord.getParent() != null) {
-                    domainRecord = _domainDao.findById(domainRecord.getParent());
-                } else {
-                    break;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd) {
-        Pair<List<TemplateJoinVO>, Integer> result = searchForTemplatesInternal(cmd);
-        ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListTemplatesCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<TemplateResponse> templateResponses = ViewResponseHelper.createTemplateResponse(respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
-        response.setResponses(templateResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) {
-        TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter());
-        Long id = cmd.getId();
-        Map<String, String> tags = cmd.getTags();
-        boolean showRemovedTmpl = cmd.getShowRemoved();
-        Account caller = CallContext.current().getCallingAccount();
-        Long parentTemplateId = cmd.getParentTemplateId();
-
-        boolean listAll = false;
-        if (templateFilter != null && templateFilter == TemplateFilter.all) {
-            if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only");
-            }
-            listAll = true;
-        }
-
-        List<Long> permittedAccountIds = new ArrayList<Long>();
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false);
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        List<Account> permittedAccounts = new ArrayList<Account>();
-        for (Long accountId : permittedAccountIds) {
-            permittedAccounts.add(_accountMgr.getAccount(accountId));
-        }
-
-        boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured));
-        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
-
-        return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType,
-                showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl, cmd.getIds(), parentTemplateId);
-    }
-
-    private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize,
-            Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List<Account> permittedAccounts, Account caller,
-            ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, boolean showRemovedTmpl, List<Long> ids, Long parentTemplateId) {
-
-        // check if zone is configured, if not, just return empty list
-        List<HypervisorType> hypers = null;
-        if (!isIso) {
-            hypers = _resourceMgr.listAvailHypervisorInZone(null, null);
-            if (hypers == null || hypers.isEmpty()) {
-                return new Pair<List<TemplateJoinVO>, Integer>(new ArrayList<TemplateJoinVO>(), 0);
-            }
-        }
-
-        VMTemplateVO template = null;
-
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = (isAscending == null ? Boolean.TRUE : isAscending);
-        Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize);
-        searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", isAscending);
-
-        SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
-        sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
-        if (ids != null && !ids.isEmpty()) {
-            sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
-        }
-        SearchCriteria<TemplateJoinVO> sc = sb.create();
-
-        // verify templateId parameter and specially handle it
-        if (templateId != null) {
-            template = _templateDao.findByIdIncludingRemoved(templateId); // Done for backward compatibility - Bug-5221
-            if (template == null) {
-                throw new InvalidParameterValueException("Please specify a valid template ID.");
-            }// If ISO requested then it should be ISO.
-            if (isIso && template.getFormat() != ImageFormat.ISO) {
-                s_logger.error("Template Id " + templateId + " is not an ISO");
-                InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO");
-                ex.addProxyObject(template.getUuid(), "templateId");
-                throw ex;
-            }// If ISO not requested then it shouldn't be an ISO.
-            if (!isIso && template.getFormat() == ImageFormat.ISO) {
-                s_logger.error("Incorrect format of the template id " + templateId);
-                InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() + " of the specified template id");
-                ex.addProxyObject(template.getUuid(), "templateId");
-                throw ex;
-            }
-            if (!template.isPublicTemplate() && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-                Account template_acc = _accountMgr.getAccount(template.getAccountId());
-                DomainVO domain = _domainDao.findById(template_acc.getDomainId());
-                _accountMgr.checkAccess(caller, domain);
-            }
-
-            // if template is not public, perform permission check here
-            else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-                _accountMgr.checkAccess(caller, null, false, template);
-            }
-
-            // if templateId is specified, then we will just use the id to
-            // search and ignore other query parameters
-            sc.addAnd("id", SearchCriteria.Op.EQ, templateId);
-        } else {
-
-            DomainVO domain = null;
-            if (!permittedAccounts.isEmpty()) {
-                domain = _domainDao.findById(permittedAccounts.get(0).getDomainId());
-            } else {
-                domain = _domainDao.findById(Domain.ROOT_DOMAIN);
-            }
-
-            // List<HypervisorType> hypers = null;
-            // if (!isIso) {
-            // hypers = _resourceMgr.listAvailHypervisorInZone(null, null);
-            // }
-
-            setIdsListToSearchCriteria(sc, ids);
-
-            // add criteria for project or not
-            if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
-                sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT);
-            } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) {
-                sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT);
-            }
-
-            // add criteria for domain path in case of domain admin
-            if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable)
-                    && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) {
-                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%");
-            }
-
-            List<Long> relatedDomainIds = new ArrayList<Long>();
-            List<Long> permittedAccountIds = new ArrayList<Long>();
-            if (!permittedAccounts.isEmpty()) {
-                for (Account account : permittedAccounts) {
-                    permittedAccountIds.add(account.getId());
-                    boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community);
-
-                    // get all parent domain ID's all the way till root domain
-                    DomainVO domainTreeNode = null;
-                    //if template filter is featured, or community, all child domains should be included in search
-                    if (publicTemplates) {
-                        domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN);
-
-                    } else {
-                        domainTreeNode = _domainDao.findById(account.getDomainId());
-                    }
-                    relatedDomainIds.add(domainTreeNode.getId());
-                    while (domainTreeNode.getParent() != null) {
-                        domainTreeNode = _domainDao.findById(domainTreeNode.getParent());
-                        relatedDomainIds.add(domainTreeNode.getId());
-                    }
-
-                    // get all child domain ID's
-                    if (_accountMgr.isAdmin(account.getId()) || publicTemplates) {
-                        List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId());
-                        for (DomainVO childDomain : allChildDomains) {
-                            relatedDomainIds.add(childDomain.getId());
-                        }
-                    }
-                }
-            }
-
-            if (!isIso) {
-                // add hypervisor criteria for template case
-                if (hypers != null && !hypers.isEmpty()) {
-                    String[] relatedHypers = new String[hypers.size()];
-                    for (int i = 0; i < hypers.size(); i++) {
-                        relatedHypers[i] = hypers.get(i).toString();
-                    }
-                    sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers);
-                }
-            }
-
-            // control different template filters
-            if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) {
-                sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true);
-                if (templateFilter == TemplateFilter.featured) {
-                    sc.addAnd("featured", SearchCriteria.Op.EQ, true);
-                } else {
-                    sc.addAnd("featured", SearchCriteria.Op.EQ, false);
-                }
-                if (!permittedAccounts.isEmpty()) {
-                    SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
-                    scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray());
-                    scc.addOr("domainId", SearchCriteria.Op.NULL);
-                    sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
-                }
-            } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) {
-                if (!permittedAccounts.isEmpty()) {
-                    sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
-                }
-            } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) {
-                // only show templates shared by others
-                sc.addAnd("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
-            } else if (templateFilter == TemplateFilter.executable) {
-                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
-                scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true);
-                if (!permittedAccounts.isEmpty()) {
-                    scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
-                }
-                sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
-            } else if (templateFilter == TemplateFilter.all && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
-                scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true);
-
-                if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
-                    scc.addOr("domainPath", SearchCriteria.Op.LIKE, _domainDao.findById(caller.getDomainId()).getPath() + "%");
-                } else {
-                    if (!permittedAccounts.isEmpty()) {
-                        scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
-                        scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
-                    }
-                }
-                sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
-            }
-
-            // add tags criteria
-            if (tags != null && !tags.isEmpty()) {
-                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
-                for (Map.Entry<String, String> entry : tags.entrySet()) {
-                    SearchCriteria<TemplateJoinVO> scTag = _templateJoinDao.createSearchCriteria();
-                    scTag.addAnd("tagKey", SearchCriteria.Op.EQ, entry.getKey());
-                    scTag.addAnd("tagValue", SearchCriteria.Op.EQ, entry.getValue());
-                    if (isIso) {
-                        scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.ISO);
-                    } else {
-                        scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.Template);
-                    }
-                    scc.addOr("tagKey", SearchCriteria.Op.SC, scTag);
-                }
-                sc.addAnd("tagKey", SearchCriteria.Op.SC, scc);
-            }
-
-            // other criteria
-
-            if (keyword != null) {
-                sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            } else if (name != null) {
-                sc.addAnd("name", SearchCriteria.Op.EQ, name);
-            }
-
-            if (isIso) {
-                sc.addAnd("format", SearchCriteria.Op.EQ, "ISO");
-
-            } else {
-                sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO");
-            }
-
-            if (!hyperType.equals(HypervisorType.None)) {
-                sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType);
-            }
-
-            if (bootable != null) {
-                sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable);
-            }
-
-            if (onlyReady) {
-                SearchCriteria<TemplateJoinVO> readySc = _templateJoinDao.createSearchCriteria();
-                readySc.addOr("state", SearchCriteria.Op.EQ, TemplateState.Ready);
-                readySc.addOr("format", SearchCriteria.Op.EQ, ImageFormat.BAREMETAL);
-                SearchCriteria<TemplateJoinVO> isoPerhostSc = _templateJoinDao.createSearchCriteria();
-                isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO);
-                isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST);
-                readySc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc);
-                sc.addAnd("state", SearchCriteria.Op.SC, readySc);
-            }
-
-            if (!showDomr) {
-                // excluding system template
-                sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM);
-            }
-        }
-
-        if (zoneId != null) {
-            SearchCriteria<TemplateJoinVO> zoneSc = _templateJoinDao.createSearchCriteria();
-            zoneSc.addOr("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-            zoneSc.addOr("dataStoreScope", SearchCriteria.Op.EQ, ScopeType.REGION);
-            // handle the case where xs-tools.iso and vmware-tools.iso do not
-            // have data_center information in template_view
-            SearchCriteria<TemplateJoinVO> isoPerhostSc = _templateJoinDao.createSearchCriteria();
-            isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO);
-            isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST);
-            zoneSc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc);
-            sc.addAnd("dataCenterId", SearchCriteria.Op.SC, zoneSc);
-        }
-
-        if (parentTemplateId != null) {
-            sc.addAnd("parentTemplateId", SearchCriteria.Op.EQ, parentTemplateId);
-        }
-
-        // don't return removed template, this should not be needed since we
-        // changed annotation for removed field in TemplateJoinVO.
-        // sc.addAnd("removed", SearchCriteria.Op.NULL);
-
-        // search unique templates and find details by Ids
-        Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair = null;
-        if (showRemovedTmpl) {
-            uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
-        } else {
-            sc.addAnd("templateState", SearchCriteria.Op.IN, new State[] {State.Active, State.UploadAbandoned, State.UploadError, State.NotUploaded, State.UploadInProgress});
-            final String[] distinctColumns = {"temp_zone_pair"};
-            uniqueTmplPair = _templateJoinDao.searchAndDistinctCount(sc, searchFilter, distinctColumns);
-        }
-
-        Integer count = uniqueTmplPair.second();
-        if (count.intValue() == 0) {
-            // empty result
-            return uniqueTmplPair;
-        }
-        List<TemplateJoinVO> uniqueTmpls = uniqueTmplPair.first();
-        String[] tzIds = new String[uniqueTmpls.size()];
-        int i = 0;
-        for (TemplateJoinVO v : uniqueTmpls) {
-            tzIds[i++] = v.getTempZonePair();
-        }
-        List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds);
-        return new Pair<List<TemplateJoinVO>, Integer>(vrs, count);
-
-        // TODO: revisit the special logic for iso search in
-        // VMTemplateDaoImpl.searchForTemplates and understand why we need to
-        // specially handle ISO. The original logic is very twisted and no idea
-        // about what the code was doing.
-
-    }
-
-    @Override
-    public ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd) {
-        Pair<List<TemplateJoinVO>, Integer> result = searchForIsosInternal(cmd);
-        ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
-
-        ResponseView respView = ResponseView.Restricted;
-        if (cmd instanceof ListIsosCmdByAdmin) {
-            respView = ResponseView.Full;
-        }
-
-        List<TemplateResponse> templateResponses = ViewResponseHelper.createIsoResponse(respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
-        response.setResponses(templateResponses, result.second());
-        return response;
-    }
-
-    private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cmd) {
-        TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter());
-        Long id = cmd.getId();
-        Map<String, String> tags = cmd.getTags();
-        boolean showRemovedISO = cmd.getShowRemoved();
-        Account caller = CallContext.current().getCallingAccount();
-
-        boolean listAll = false;
-        if (isoFilter != null && isoFilter == TemplateFilter.all) {
-            if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only");
-            }
-            listAll = true;
-        }
-
-        List<Long> permittedAccountIds = new ArrayList<Long>();
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false);
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        List<Account> permittedAccounts = new ArrayList<Account>();
-        for (Long accountId : permittedAccountIds) {
-            permittedAccounts.add(_accountMgr.getAccount(accountId));
-        }
-
-        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
-
-        return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(),
-                hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO, null, null);
-    }
-
-    @Override
-    public ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd) {
-        Pair<List<AffinityGroupJoinVO>, Integer> result = searchForAffinityGroupsInternal(cmd);
-        ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();
-        List<AffinityGroupResponse> agResponses = ViewResponseHelper.createAffinityGroupResponses(result.first());
-        response.setResponses(agResponses, result.second());
-        return response;
-    }
-
-    public Pair<List<AffinityGroupJoinVO>, Integer> searchForAffinityGroupsInternal(ListAffinityGroupsCmd cmd) {
-
-        final Long affinityGroupId = cmd.getId();
-        final String affinityGroupName = cmd.getAffinityGroupName();
-        final String affinityGroupType = cmd.getAffinityGroupType();
-        final Long vmId = cmd.getVirtualMachineId();
-        final String accountName = cmd.getAccountName();
-        Long domainId = cmd.getDomainId();
-        final Long projectId = cmd.getProjectId();
-        Boolean isRecursive = cmd.isRecursive();
-        final Boolean listAll = cmd.listAll();
-        final Long startIndex = cmd.getStartIndex();
-        final Long pageSize = cmd.getPageSizeVal();
-        final String keyword = cmd.getKeyword();
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        if (vmId != null) {
-            UserVmVO userVM = _userVmDao.findById(vmId);
-            if (userVM == null) {
-                throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + vmId + "; instance not found.");
-            }
-            _accountMgr.checkAccess(caller, null, true, userVM);
-            return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
-        }
-
-        List<Long> permittedAccounts = new ArrayList<Long>();
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> ternary = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
-
-        _accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, projectId, permittedAccounts, ternary, listAll, false);
-
-        domainId = ternary.first();
-        isRecursive = ternary.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = ternary.third();
-
-        Filter searchFilter = new Filter(AffinityGroupJoinVO.class, ID_FIELD, true, startIndex, pageSize);
-
-        SearchCriteria<AffinityGroupJoinVO> sc = buildAffinityGroupSearchCriteria(domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
-                affinityGroupType, keyword);
-
-        Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
-
-        // search group details by ids
-        List<AffinityGroupJoinVO> affinityGroups = new ArrayList<AffinityGroupJoinVO>();
-
-        Integer count = uniqueGroupsPair.second();
-        if (count.intValue() != 0) {
-            List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
-            Long[] vrIds = new Long[uniqueGroups.size()];
-            int i = 0;
-            for (AffinityGroupJoinVO v : uniqueGroups) {
-                vrIds[i++] = v.getId();
-            }
-            affinityGroups = _affinityGroupJoinDao.searchByIds(vrIds);
-        }
-
-        if (!permittedAccounts.isEmpty()) {
-            // add domain level affinity groups
-            if (domainId != null) {
-                SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
-                        affinityGroupName, affinityGroupType, keyword);
-                affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
-            } else {
-
-                for (Long permAcctId : permittedAccounts) {
-                    Account permittedAcct = _accountDao.findById(permAcctId);
-                    SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
-                            affinityGroupName, affinityGroupType, keyword);
-
-                    affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId()));
-                }
-            }
-        } else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
-            // list all domain level affinity groups for the domain admin case
-            SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
-                    affinityGroupType, keyword);
-            affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
-        }
-
-        return new Pair<List<AffinityGroupJoinVO>, Integer>(affinityGroups, affinityGroups.size());
-
-    }
-
-    private void buildAffinityGroupViewSearchBuilder(SearchBuilder<AffinityGroupJoinVO> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-
-        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
-        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-
-        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
-            // if accountId isn't specified, we can do a domain match for the
-            // admin case if isRecursive is true
-            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-        }
-
-        if (listProjectResourcesCriteria != null) {
-            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
-                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
-            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
-                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
-            }
-        }
-
-    }
-
-    private void buildAffinityGroupViewSearchCriteria(SearchCriteria<AffinityGroupJoinVO> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-
-        if (listProjectResourcesCriteria != null) {
-            sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT);
-        }
-
-        if (!permittedAccounts.isEmpty()) {
-            sc.setParameters("accountIdIN", permittedAccounts.toArray());
-        } else if (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            if (isRecursive) {
-                sc.setParameters("domainPath", domain.getPath() + "%");
-            } else {
-                sc.setParameters("domainId", domainId);
-            }
-        }
-    }
-
-    private SearchCriteria<AffinityGroupJoinVO> buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria, Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) {
-
-        SearchBuilder<AffinityGroupJoinVO> groupSearch = _affinityGroupJoinDao.createSearchBuilder();
-        buildAffinityGroupViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select
-        // distinct
-
-        SearchCriteria<AffinityGroupJoinVO> sc = groupSearch.create();
-        buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (affinityGroupId != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
-        }
-
-        if (affinityGroupName != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName);
-        }
-
-        if (affinityGroupType != null) {
-            sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType);
-        }
-
-        if (keyword != null) {
-            SearchCriteria<AffinityGroupJoinVO> ssc = _affinityGroupJoinDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        return sc;
-    }
-
-    private Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsByVM(long vmId, long pageInd, long pageSize) {
-        Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize);
-        Pair<List<AffinityGroupVMMapVO>, Integer> agVmMappingPair = _affinityGroupVMMapDao.listByInstanceId(vmId, sf);
-        Integer count = agVmMappingPair.second();
-        if (count.intValue() == 0) {
-            // handle empty result cases
-            return new Pair<List<AffinityGroupJoinVO>, Integer>(new ArrayList<AffinityGroupJoinVO>(), count);
-        }
-        List<AffinityGroupVMMapVO> agVmMappings = agVmMappingPair.first();
-        Long[] agIds = new Long[agVmMappings.size()];
-        int i = 0;
-        for (AffinityGroupVMMapVO agVm : agVmMappings) {
-            agIds[i++] = agVm.getAffinityGroupId();
-        }
-        List<AffinityGroupJoinVO> ags = _affinityGroupJoinDao.searchByIds(agIds);
-        return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
-    }
-
-    private List<AffinityGroupJoinVO> listDomainLevelAffinityGroups(SearchCriteria<AffinityGroupJoinVO> sc, Filter searchFilter, long domainId) {
-        List<Long> affinityGroupIds = new ArrayList<Long>();
-        Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
-        List<AffinityGroupDomainMapVO> maps = _affinityGroupDomainMapDao.listByDomain(allowedDomains.toArray());
-
-        for (AffinityGroupDomainMapVO map : maps) {
-            boolean subdomainAccess = map.isSubdomainAccess();
-            if (map.getDomainId() == domainId || subdomainAccess) {
-                affinityGroupIds.add(map.getAffinityGroupId());
-            }
-        }
-
-        if (!affinityGroupIds.isEmpty()) {
-            SearchCriteria<AffinityGroupJoinVO> domainSC = _affinityGroupJoinDao.createSearchCriteria();
-            domainSC.addAnd("id", SearchCriteria.Op.IN, affinityGroupIds.toArray());
-            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
-
-            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
-
-            Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
-            // search group by ids
-            Integer count = uniqueGroupsPair.second();
-            if (count.intValue() == 0) {
-                // empty result
-                return new ArrayList<AffinityGroupJoinVO>();
-            }
-            List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
-            Long[] vrIds = new Long[uniqueGroups.size()];
-            int i = 0;
-            for (AffinityGroupJoinVO v : uniqueGroups) {
-                vrIds[i++] = v.getId();
-            }
-            List<AffinityGroupJoinVO> vrs = _affinityGroupJoinDao.searchByIds(vrIds);
-            return vrs;
-        } else {
-            return new ArrayList<AffinityGroupJoinVO>();
-        }
-    }
-
-    @Override
-    public List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd) {
-        String key = cmd.getKey();
-        Boolean forDisplay = cmd.getDisplay();
-        ResourceTag.ResourceObjectType resourceType = cmd.getResourceType();
-        String resourceIdStr = cmd.getResourceId();
-        String value = cmd.getValue();
-        Long resourceId = null;
-
-        //Validation - 1.1 - resourceId and value cant be null.
-        if (resourceIdStr == null && value == null) {
-            throw new InvalidParameterValueException("Insufficient parameters passed for listing by resourceId OR key,value pair. Please check your params and try again.");
-        }
-
-        //Validation - 1.2 - Value has to be passed along with key.
-        if (value != null && key == null) {
-            throw new InvalidParameterValueException("Listing by (key, value) but key is null. Please check the params and try again");
-        }
-
-        //Validation - 1.3
-        if (resourceIdStr != null) {
-            resourceId = _taggedResourceMgr.getResourceId(resourceIdStr, resourceType);
-            if (resourceId == null) {
-                throw new InvalidParameterValueException("Cannot find resource with resourceId " + resourceIdStr + " and of resource type " + resourceType);
-            }
-        }
-
-        List<? extends ResourceDetail> detailList = new ArrayList<ResourceDetail>();
-        ResourceDetail requestedDetail = null;
-
-        if (key == null) {
-            detailList = _resourceMetaDataMgr.getDetailsList(resourceId, resourceType, forDisplay);
-        } else if (value == null) {
-            requestedDetail = _resourceMetaDataMgr.getDetail(resourceId, resourceType, key);
-            if (requestedDetail != null && forDisplay != null && requestedDetail.isDisplay() != forDisplay) {
-                requestedDetail = null;
-            }
-        } else {
-            detailList = _resourceMetaDataMgr.getDetails(resourceType, key, value, forDisplay);
-        }
-
-        List<ResourceDetailResponse> responseList = new ArrayList<ResourceDetailResponse>();
-        if (requestedDetail != null) {
-            ResourceDetailResponse detailResponse = createResourceDetailsResponse(requestedDetail, resourceType);
-            responseList.add(detailResponse);
-        } else {
-            for (ResourceDetail detail : detailList) {
-                ResourceDetailResponse detailResponse = createResourceDetailsResponse(detail, resourceType);
-                responseList.add(detailResponse);
-            }
-        }
-
-        return responseList;
-    }
-
-    protected ResourceDetailResponse createResourceDetailsResponse(ResourceDetail requestedDetail, ResourceTag.ResourceObjectType resourceType) {
-        ResourceDetailResponse resourceDetailResponse = new ResourceDetailResponse();
-        resourceDetailResponse.setResourceId(String.valueOf(requestedDetail.getResourceId()));
-        resourceDetailResponse.setName(requestedDetail.getName());
-        resourceDetailResponse.setValue(requestedDetail.getValue());
-        resourceDetailResponse.setForDisplay(requestedDetail.isDisplay());
-        resourceDetailResponse.setResourceType(resourceType.toString().toString());
-        resourceDetailResponse.setObjectName("resourcedetail");
-        return resourceDetailResponse;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return QueryService.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {AllowUserViewDestroyedVM};
-    }
-}
diff --git a/server/src/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java
deleted file mode 100644
index fefc896..0000000
--- a/server/src/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.util.Date;
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-
-import com.cloud.api.ApiSerializerHelper;
-import com.cloud.api.SerializationContext;
-import com.cloud.api.query.vo.AsyncJobJoinVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> implements AsyncJobJoinDao {
-    public static final Logger s_logger = Logger.getLogger(AsyncJobJoinDaoImpl.class);
-
-    private final SearchBuilder<AsyncJobJoinVO> jobIdSearch;
-
-    protected AsyncJobJoinDaoImpl() {
-
-        jobIdSearch = createSearchBuilder();
-        jobIdSearch.and("id", jobIdSearch.entity().getId(), SearchCriteria.Op.EQ);
-        jobIdSearch.done();
-
-        _count = "select count(distinct id) from async_job_view WHERE ";
-    }
-
-    @Override
-    public AsyncJobResponse newAsyncJobResponse(AsyncJobJoinVO job) {
-        AsyncJobResponse jobResponse = new AsyncJobResponse();
-        jobResponse.setAccountId(job.getAccountUuid());
-        jobResponse.setUserId(job.getUserUuid());
-        jobResponse.setCmd(job.getCmd());
-        jobResponse.setCreated(job.getCreated());
-        jobResponse.setJobId(job.getUuid());
-        jobResponse.setJobStatus(job.getStatus());
-        jobResponse.setJobProcStatus(job.getProcessStatus());
-
-        if (job.getInstanceType() != null && job.getInstanceId() != null) {
-            jobResponse.setJobInstanceType(job.getInstanceType().toString());
-
-            jobResponse.setJobInstanceId(job.getInstanceUuid());
-
-        }
-        jobResponse.setJobResultCode(job.getResultCode());
-
-        boolean savedValue = SerializationContext.current().getUuidTranslation();
-        SerializationContext.current().setUuidTranslation(false);
-
-        Object resultObject = ApiSerializerHelper.fromSerializedString(job.getResult());
-        jobResponse.setJobResult((ResponseObject)resultObject);
-        SerializationContext.current().setUuidTranslation(savedValue);
-
-        if (resultObject != null) {
-            Class<?> clz = resultObject.getClass();
-            if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) {
-                jobResponse.setJobResultType("text");
-            } else {
-                jobResponse.setJobResultType("object");
-            }
-        }
-
-        jobResponse.setObjectName("asyncjobs");
-        return jobResponse;
-    }
-
-    @Override
-    public AsyncJobJoinVO newAsyncJobView(AsyncJob job) {
-        SearchCriteria<AsyncJobJoinVO> sc = jobIdSearch.create();
-        sc.setParameters("id", job.getId());
-        List<AsyncJobJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
-        assert accounts != null && accounts.size() == 1 : "No async job found for job id " + job.getId();
-        return accounts.get(0);
-
-    }
-
-}
diff --git a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
deleted file mode 100644
index 9ca4487..0000000
--- a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.response.DiskOfferingResponse;
-
-import com.cloud.api.query.vo.DiskOfferingJoinVO;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.utils.db.Attribute;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO, Long> implements DiskOfferingJoinDao {
-    public static final Logger s_logger = Logger.getLogger(DiskOfferingJoinDaoImpl.class);
-
-    private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch;
-    private final Attribute _typeAttr;
-
-    protected DiskOfferingJoinDaoImpl() {
-
-        dofIdSearch = createSearchBuilder();
-        dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
-        dofIdSearch.done();
-
-        _typeAttr = _allAttributes.get("type");
-
-        _count = "select count(distinct id) from disk_offering_view WHERE ";
-    }
-
-    @Override
-    public DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO offering) {
-
-        DiskOfferingResponse diskOfferingResponse = new DiskOfferingResponse();
-        diskOfferingResponse.setId(offering.getUuid());
-        diskOfferingResponse.setName(offering.getName());
-        diskOfferingResponse.setDisplayText(offering.getDisplayText());
-        diskOfferingResponse.setProvisioningType(offering.getProvisioningType().toString());
-        diskOfferingResponse.setCreated(offering.getCreated());
-        diskOfferingResponse.setDiskSize(offering.getDiskSize() / (1024 * 1024 * 1024));
-        diskOfferingResponse.setMinIops(offering.getMinIops());
-        diskOfferingResponse.setMaxIops(offering.getMaxIops());
-
-        diskOfferingResponse.setDomain(offering.getDomainName());
-        diskOfferingResponse.setDomainId(offering.getDomainUuid());
-        diskOfferingResponse.setDisplayOffering(offering.isDisplayOffering());
-
-        diskOfferingResponse.setTags(offering.getTags());
-        diskOfferingResponse.setCustomized(offering.isCustomized());
-        diskOfferingResponse.setCustomizedIops(offering.isCustomizedIops());
-        diskOfferingResponse.setHypervisorSnapshotReserve(offering.getHypervisorSnapshotReserve());
-        diskOfferingResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
-        diskOfferingResponse.setBytesReadRate(offering.getBytesReadRate());
-        diskOfferingResponse.setBytesWriteRate(offering.getBytesWriteRate());
-        diskOfferingResponse.setIopsReadRate(offering.getIopsReadRate());
-        diskOfferingResponse.setIopsWriteRate(offering.getIopsWriteRate());
-        diskOfferingResponse.setCacheMode(offering.getCacheMode());
-        diskOfferingResponse.setObjectName("diskoffering");
-
-        return diskOfferingResponse;
-    }
-
-    @Override
-    public DiskOfferingJoinVO newDiskOfferingView(DiskOffering offering) {
-        SearchCriteria<DiskOfferingJoinVO> sc = dofIdSearch.create();
-        sc.setParameters("id", offering.getId());
-        List<DiskOfferingJoinVO> offerings = searchIncludingRemoved(sc, null, null, false);
-        assert offerings != null && offerings.size() == 1 : "No disk offering found for offering id " + offering.getId();
-        return offerings.get(0);
-    }
-}
diff --git a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
deleted file mode 100644
index ec88033..0000000
--- a/server/src/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
+++ /dev/null
@@ -1,301 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.response.DomainRouterResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.api.ApiResponseHelper;
-import com.cloud.api.query.vo.DomainRouterJoinVO;
-import com.cloud.maint.Version;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO, Long> implements DomainRouterJoinDao {
-    public static final Logger s_logger = Logger.getLogger(DomainRouterJoinDaoImpl.class);
-
-    @Inject
-    private ConfigurationDao  _configDao;
-    @Inject
-    public AccountManager _accountMgr;
-
-    private final SearchBuilder<DomainRouterJoinVO> vrSearch;
-
-    private final SearchBuilder<DomainRouterJoinVO> vrIdSearch;
-
-    protected DomainRouterJoinDaoImpl() {
-
-        vrSearch = createSearchBuilder();
-        vrSearch.and("idIN", vrSearch.entity().getId(), SearchCriteria.Op.IN);
-        vrSearch.done();
-
-        vrIdSearch = createSearchBuilder();
-        vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
-        vrIdSearch.done();
-
-        _count = "select count(distinct id) from domain_router_view WHERE ";
-    }
-
-    @Override
-    public DomainRouterResponse newDomainRouterResponse(DomainRouterJoinVO router, Account caller) {
-        DomainRouterResponse routerResponse = new DomainRouterResponse();
-        routerResponse.setId(router.getUuid());
-        routerResponse.setZoneId(router.getDataCenterUuid());
-        routerResponse.setName(router.getName());
-        routerResponse.setTemplateId(router.getTemplateUuid());
-        routerResponse.setCreated(router.getCreated());
-        routerResponse.setState(router.getState());
-        routerResponse.setIsRedundantRouter(router.isRedundantRouter());
-        if (router.getRedundantState() != null) {
-            routerResponse.setRedundantState(router.getRedundantState().toString());
-        }
-        if (router.getTemplateVersion() != null) {
-            String routerVersion = Version.trimRouterVersion(router.getTemplateVersion());
-            routerResponse.setVersion(routerVersion);
-            routerResponse.setRequiresUpgrade((Version.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId())) < 0));
-        } else {
-            routerResponse.setVersion("UNKNOWN");
-            routerResponse.setRequiresUpgrade(true);
-        }
-
-        if (caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN
-                || _accountMgr.isRootAdmin(caller.getId())) {
-            if (router.getHostId() != null) {
-                routerResponse.setHostId(router.getHostUuid());
-                routerResponse.setHostName(router.getHostName());
-                routerResponse.setHypervisor(router.getHypervisorType().toString());
-            }
-            routerResponse.setPodId(router.getPodUuid());
-            long nic_id = router.getNicId();
-            if (nic_id > 0) {
-                TrafficType ty = router.getTrafficType();
-                if (ty != null) {
-                    // legacy code, public/control/guest nic info is kept in
-                    // nics response object
-                    if (ty == TrafficType.Public) {
-                        routerResponse.setPublicIp(router.getIpAddress());
-                        routerResponse.setPublicMacAddress(router.getMacAddress());
-                        routerResponse.setPublicNetmask(router.getNetmask());
-                        routerResponse.setGateway(router.getGateway());
-                        routerResponse.setPublicNetworkId(router.getNetworkUuid());
-                    } else if (ty == TrafficType.Control) {
-                        routerResponse.setLinkLocalIp(router.getIpAddress());
-                        routerResponse.setLinkLocalMacAddress(router.getMacAddress());
-                        routerResponse.setLinkLocalNetmask(router.getNetmask());
-                        routerResponse.setLinkLocalNetworkId(router.getNetworkUuid());
-                    } else if (ty == TrafficType.Guest) {
-                        routerResponse.setGuestIpAddress(router.getIpAddress());
-                        routerResponse.setGuestMacAddress(router.getMacAddress());
-                        routerResponse.setGuestNetmask(router.getNetmask());
-                        routerResponse.setGuestNetworkId(router.getNetworkUuid());
-                        routerResponse.setGuestNetworkName(router.getNetworkName());
-                        routerResponse.setNetworkDomain(router.getNetworkDomain());
-                    }
-                }
-
-                NicResponse nicResponse = new NicResponse();
-                nicResponse.setId(router.getNicUuid());
-                nicResponse.setIpaddress(router.getIpAddress());
-                nicResponse.setGateway(router.getGateway());
-                nicResponse.setNetmask(router.getNetmask());
-                nicResponse.setNetworkid(router.getNetworkUuid());
-                nicResponse.setNetworkName(router.getNetworkName());
-                nicResponse.setMacAddress(router.getMacAddress());
-                nicResponse.setIp6Address(router.getIp6Address());
-                nicResponse.setIp6Gateway(router.getIp6Gateway());
-                nicResponse.setIp6Cidr(router.getIp6Cidr());
-                if (router.getBroadcastUri() != null) {
-                    nicResponse.setBroadcastUri(router.getBroadcastUri().toString());
-                }
-                if (router.getIsolationUri() != null) {
-                    nicResponse.setIsolationUri(router.getIsolationUri().toString());
-                }
-                if (router.getTrafficType() != null) {
-                    nicResponse.setTrafficType(router.getTrafficType().toString());
-                }
-                if (router.getGuestType() != null) {
-                    nicResponse.setType(router.getGuestType().toString());
-                }
-                nicResponse.setIsDefault(router.isDefaultNic());
-                nicResponse.setObjectName("nic");
-                routerResponse.addNic(nicResponse);
-            }
-        }
-
-        routerResponse.setServiceOfferingId(router.getServiceOfferingUuid());
-        routerResponse.setServiceOfferingName(router.getServiceOfferingName());
-
-        // populate owner.
-        ApiResponseHelper.populateOwner(routerResponse, router);
-
-        routerResponse.setDomainId(router.getDomainUuid());
-        routerResponse.setDomainName(router.getDomainName());
-
-        routerResponse.setZoneName(router.getDataCenterName());
-        routerResponse.setDns1(router.getDns1());
-        routerResponse.setDns2(router.getDns2());
-
-        routerResponse.setIp6Dns1(router.getIp6Dns1());
-        routerResponse.setIp6Dns2(router.getIp6Dns2());
-
-        routerResponse.setVpcId(router.getVpcUuid());
-        routerResponse.setVpcName(router.getVpcName());
-
-        routerResponse.setRole(router.getRole().toString());
-
-        // set async job
-        if (router.getJobId() != null) {
-            routerResponse.setJobId(router.getJobUuid());
-            routerResponse.setJobStatus(router.getJobStatus());
-        }
-
-        if (router.getRole() == Role.INTERNAL_LB_VM) {
-            routerResponse.setObjectName("internalloadbalancervm");
-        } else {
-            routerResponse.setObjectName("router");
-        }
-
-        return routerResponse;
-    }
-
-    @Override
-    public DomainRouterResponse setDomainRouterResponse(DomainRouterResponse vrData, DomainRouterJoinVO vr) {
-        long nic_id = vr.getNicId();
-        if (nic_id > 0) {
-            TrafficType ty = vr.getTrafficType();
-            if (ty != null) {
-                // legacy code, public/control/guest nic info is kept in
-                // nics response object
-                if (ty == TrafficType.Public) {
-                    vrData.setPublicIp(vr.getIpAddress());
-                    vrData.setPublicMacAddress(vr.getMacAddress());
-                    vrData.setPublicNetmask(vr.getNetmask());
-                    vrData.setGateway(vr.getGateway());
-                    vrData.setPublicNetworkId(vr.getNetworkUuid());
-                } else if (ty == TrafficType.Control) {
-                    vrData.setLinkLocalIp(vr.getIpAddress());
-                    vrData.setLinkLocalMacAddress(vr.getMacAddress());
-                    vrData.setLinkLocalNetmask(vr.getNetmask());
-                    vrData.setLinkLocalNetworkId(vr.getNetworkUuid());
-                } else if (ty == TrafficType.Guest) {
-                    vrData.setGuestIpAddress(vr.getIpAddress());
-                    vrData.setGuestMacAddress(vr.getMacAddress());
-                    vrData.setGuestNetmask(vr.getNetmask());
-                    vrData.setGuestNetworkId(vr.getNetworkUuid());
-                    vrData.setGuestNetworkName(vr.getNetworkName());
-                    vrData.setNetworkDomain(vr.getNetworkDomain());
-                }
-            }
-            NicResponse nicResponse = new NicResponse();
-            nicResponse.setId(vr.getNicUuid());
-            nicResponse.setIpaddress(vr.getIpAddress());
-            nicResponse.setGateway(vr.getGateway());
-            nicResponse.setNetmask(vr.getNetmask());
-            nicResponse.setNetworkid(vr.getNetworkUuid());
-            nicResponse.setNetworkName(vr.getNetworkName());
-            nicResponse.setMacAddress(vr.getMacAddress());
-            nicResponse.setIp6Address(vr.getIp6Address());
-            nicResponse.setIp6Gateway(vr.getIp6Gateway());
-            nicResponse.setIp6Cidr(vr.getIp6Cidr());
-            if (vr.getBroadcastUri() != null) {
-                nicResponse.setBroadcastUri(vr.getBroadcastUri().toString());
-            }
-            if (vr.getIsolationUri() != null) {
-                nicResponse.setIsolationUri(vr.getIsolationUri().toString());
-            }
-            if (vr.getTrafficType() != null) {
-                nicResponse.setTrafficType(vr.getTrafficType().toString());
-            }
-            if (vr.getGuestType() != null) {
-                nicResponse.setType(vr.getGuestType().toString());
-            }
-            nicResponse.setIsDefault(vr.isDefaultNic());
-            nicResponse.setObjectName("nic");
-            vrData.addNic(nicResponse);
-        }
-        return vrData;
-    }
-
-    @Override
-    public List<DomainRouterJoinVO> searchByIds(Long... vrIds) {
-        // set detail batch query size
-        int DETAILS_BATCH_SIZE = 2000;
-        String batchCfg = _configDao.getValue("detail.batch.query.size");
-        if (batchCfg != null) {
-            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
-        }
-        // query details by batches
-        List<DomainRouterJoinVO> uvList = new ArrayList<DomainRouterJoinVO>();
-        // query details by batches
-        int curr_index = 0;
-        if (vrIds.length > DETAILS_BATCH_SIZE) {
-            while ((curr_index + DETAILS_BATCH_SIZE) <= vrIds.length) {
-                Long[] ids = new Long[DETAILS_BATCH_SIZE];
-                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
-                    ids[k] = vrIds[j];
-                }
-                SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
-                sc.setParameters("idIN", ids);
-                List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
-                if (vms != null) {
-                    uvList.addAll(vms);
-                }
-                curr_index += DETAILS_BATCH_SIZE;
-            }
-        }
-        if (curr_index < vrIds.length) {
-            int batch_size = (vrIds.length - curr_index);
-            // set the ids value
-            Long[] ids = new Long[batch_size];
-            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
-                ids[k] = vrIds[j];
-            }
-            SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
-            sc.setParameters("idIN", ids);
-            List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
-            if (vms != null) {
-                uvList.addAll(vms);
-            }
-        }
-        return uvList;
-    }
-
-    @Override
-    public List<DomainRouterJoinVO> newDomainRouterView(VirtualRouter vr) {
-
-        SearchCriteria<DomainRouterJoinVO> sc = vrIdSearch.create();
-        sc.setParameters("id", vr.getId());
-        return searchIncludingRemoved(sc, null, null, false);
-    }
-
-}
diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
deleted file mode 100644
index 3627069..0000000
--- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.util.List;
-
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.vo.ServiceOfferingJoinVO;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJoinVO, Long> implements ServiceOfferingJoinDao {
-    public static final Logger s_logger = Logger.getLogger(ServiceOfferingJoinDaoImpl.class);
-
-    private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
-
-    protected ServiceOfferingJoinDaoImpl() {
-
-        sofIdSearch = createSearchBuilder();
-        sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
-        sofIdSearch.done();
-
-        this._count = "select count(distinct service_offering_view.id) from service_offering_view WHERE ";
-    }
-
-    @Override
-    public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offering) {
-
-        ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse();
-        offeringResponse.setId(offering.getUuid());
-        offeringResponse.setName(offering.getName());
-        offeringResponse.setIsSystemOffering(offering.isSystemUse());
-        offeringResponse.setDefaultUse(offering.isDefaultUse());
-        offeringResponse.setSystemVmType(offering.getSystemVmType());
-        offeringResponse.setDisplayText(offering.getDisplayText());
-        offeringResponse.setProvisioningType(offering.getProvisioningType().toString());
-        offeringResponse.setCpuNumber(offering.getCpu());
-        offeringResponse.setCpuSpeed(offering.getSpeed());
-        offeringResponse.setMemory(offering.getRamSize());
-        offeringResponse.setCreated(offering.getCreated());
-        offeringResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
-        offeringResponse.setOfferHa(offering.isOfferHA());
-        offeringResponse.setLimitCpuUse(offering.isLimitCpuUse());
-        offeringResponse.setVolatileVm(offering.getVolatileVm());
-        offeringResponse.setTags(offering.getTags());
-        offeringResponse.setDomain(offering.getDomainName());
-        offeringResponse.setDomainId(offering.getDomainUuid());
-        offeringResponse.setNetworkRate(offering.getRateMbps());
-        offeringResponse.setHostTag(offering.getHostTag());
-        offeringResponse.setDeploymentPlanner(offering.getDeploymentPlanner());
-        offeringResponse.setCustomizedIops(offering.isCustomizedIops());
-        offeringResponse.setMinIops(offering.getMinIops());
-        offeringResponse.setMaxIops(offering.getMaxIops());
-        offeringResponse.setHypervisorSnapshotReserve(offering.getHypervisorSnapshotReserve());
-        offeringResponse.setBytesReadRate(offering.getBytesReadRate());
-        offeringResponse.setBytesWriteRate(offering.getBytesWriteRate());
-        offeringResponse.setIopsReadRate(offering.getIopsReadRate());
-        offeringResponse.setIopsWriteRate(offering.getIopsWriteRate());
-        offeringResponse.setDetails(ApiDBUtils.getResourceDetails(offering.getId(), ResourceObjectType.ServiceOffering));
-        offeringResponse.setObjectName("serviceoffering");
-        offeringResponse.setIscutomized(offering.isDynamic());
-
-        return offeringResponse;
-    }
-
-    @Override
-    public ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering) {
-        SearchCriteria<ServiceOfferingJoinVO> sc = sofIdSearch.create();
-        sc.setParameters("id", offering.getId());
-        List<ServiceOfferingJoinVO> offerings = searchIncludingRemoved(sc, null, null, false);
-        assert offerings != null && offerings.size() == 1 : "No service offering found for offering id " + offering.getId();
-        return offerings.get(0);
-    }
-
-}
diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
deleted file mode 100644
index c0d57d7..0000000
--- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ /dev/null
@@ -1,480 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.utils.security.DigestHelper;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.response.ChildTemplateResponse;
-import org.apache.cloudstack.api.response.TemplateResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.ApiResponseHelper;
-import com.cloud.api.query.vo.ResourceTagJoinVO;
-import com.cloud.api.query.vo.TemplateJoinVO;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-
-@Component
-public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<TemplateJoinVO, TemplateResponse> implements TemplateJoinDao {
-
-    public static final Logger s_logger = Logger.getLogger(TemplateJoinDaoImpl.class);
-
-    @Inject
-    private ConfigurationDao  _configDao;
-    @Inject
-    private AccountService _accountService;
-    @Inject
-    private VMTemplateDao _vmTemplateDao;
-
-    private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
-
-    private final SearchBuilder<TemplateJoinVO> tmpltIdSearch;
-
-    private final SearchBuilder<TemplateJoinVO> tmpltZoneSearch;
-
-    private final SearchBuilder<TemplateJoinVO> activeTmpltSearch;
-
-    protected TemplateJoinDaoImpl() {
-
-        tmpltIdPairSearch = createSearchBuilder();
-        tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.IN);
-        tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN);
-        tmpltIdPairSearch.done();
-
-        tmpltIdSearch = createSearchBuilder();
-        tmpltIdSearch.and("id", tmpltIdSearch.entity().getId(), SearchCriteria.Op.EQ);
-        tmpltIdSearch.done();
-
-        tmpltZoneSearch = createSearchBuilder();
-        tmpltZoneSearch.and("id", tmpltZoneSearch.entity().getId(), SearchCriteria.Op.EQ);
-        tmpltZoneSearch.and("dataCenterId", tmpltZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        tmpltZoneSearch.and("state", tmpltZoneSearch.entity().getState(), SearchCriteria.Op.EQ);
-        tmpltZoneSearch.done();
-
-        activeTmpltSearch = createSearchBuilder();
-        activeTmpltSearch.and("store_id", activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
-        activeTmpltSearch.and("type", activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
-        activeTmpltSearch.and("templateState", activeTmpltSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
-        activeTmpltSearch.done();
-
-        // select distinct pair (template_id, zone_id)
-        _count = "select count(distinct temp_zone_pair) from template_view WHERE ";
-    }
-
-    private String getTemplateStatus(TemplateJoinVO template) {
-        String templateStatus = null;
-        if (template.getDownloadState() != Status.DOWNLOADED) {
-            templateStatus = "Processing";
-            if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
-                if (template.getDownloadPercent() == 100) {
-                    templateStatus = "Installing Template";
-                } else {
-                    templateStatus = template.getDownloadPercent() + "% Downloaded";
-                }
-            } else if (template.getDownloadState() == Status.BYPASSED) {
-                templateStatus = "Bypassed Secondary Storage";
-            }else if (template.getErrorString()==null){
-                templateStatus = template.getTemplateState().toString();
-            }else {
-                templateStatus = template.getErrorString();
-            }
-        } else if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
-            templateStatus = "Download Complete";
-        } else {
-            templateStatus = "Successfully Installed";
-        }
-        return templateStatus;
-    }
-
-    @Override
-    public TemplateResponse newTemplateResponse(ResponseView view, TemplateJoinVO template) {
-        TemplateResponse templateResponse = new TemplateResponse();
-        templateResponse.setId(template.getUuid());
-        templateResponse.setName(template.getName());
-        templateResponse.setDisplayText(template.getDisplayText());
-        templateResponse.setPublic(template.isPublicTemplate());
-        templateResponse.setCreated(template.getCreatedOnStore());
-        if (template.getFormat() == Storage.ImageFormat.BAREMETAL) {
-            // for baremetal template, we didn't download, but is ready to use.
-            templateResponse.setReady(true);
-        } else {
-            templateResponse.setReady(template.getState() == ObjectInDataStoreStateMachine.State.Ready);
-        }
-        templateResponse.setFeatured(template.isFeatured());
-        templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM));
-        templateResponse.setPasswordEnabled(template.isEnablePassword());
-        templateResponse.setDynamicallyScalable(template.isDynamicallyScalable());
-        templateResponse.setSshKeyEnabled(template.isEnableSshKey());
-        templateResponse.setCrossZones(template.isCrossZones());
-        templateResponse.setFormat(template.getFormat());
-        if (template.getTemplateType() != null) {
-            templateResponse.setTemplateType(template.getTemplateType().toString());
-        }
-
-        templateResponse.setHypervisor(template.getHypervisorType().toString());
-
-        templateResponse.setOsTypeId(template.getGuestOSUuid());
-        templateResponse.setOsTypeName(template.getGuestOSName());
-
-        // populate owner.
-        ApiResponseHelper.populateOwner(templateResponse, template);
-
-        // populate domain
-        templateResponse.setDomainId(template.getDomainUuid());
-        templateResponse.setDomainName(template.getDomainName());
-
-        // If the user is an 'Admin' or 'the owner of template', add the template download status
-        if (view == ResponseView.Full ||  template.getAccountId() == CallContext.current().getCallingAccount().getId() ) {
-            String templateStatus = getTemplateStatus(template);
-            if (templateStatus != null) {
-                templateResponse.setStatus(templateStatus);
-            }
-        }
-
-        if (template.getDataCenterId() > 0) {
-            templateResponse.setZoneId(template.getDataCenterUuid());
-            templateResponse.setZoneName(template.getDataCenterName());
-        }
-
-        Long templateSize = template.getSize();
-        if (templateSize > 0) {
-            templateResponse.setSize(templateSize);
-        }
-
-        Long templatePhysicalSize = template.getPhysicalSize();
-        if (templatePhysicalSize > 0) {
-            templateResponse.setPhysicalSize(templatePhysicalSize);
-        }
-
-        templateResponse.setChecksum(DigestHelper.getHashValueFromChecksumValue(template.getChecksum()));
-        if (template.getSourceTemplateId() != null) {
-            templateResponse.setSourceTemplateId(template.getSourceTemplateUuid());
-        }
-        templateResponse.setTemplateTag(template.getTemplateTag());
-
-        if (template.getParentTemplateId() != null) {
-            templateResponse.setParentTemplateId(template.getParentTemplateUuid());
-        }
-
-        // set details map
-        if (template.getDetailName() != null) {
-            Map<String, String> details = new HashMap<>();
-            details.put(template.getDetailName(), template.getDetailValue());
-            templateResponse.setDetails(details);
-        }
-
-        // update tag information
-        long tag_id = template.getTagId();
-        if (tag_id > 0) {
-            addTagInformation(template, templateResponse);
-        }
-
-        templateResponse.setDirectDownload(template.isDirectDownload());
-
-        //set template children disks
-        Set<ChildTemplateResponse> childTemplatesSet = new HashSet<ChildTemplateResponse>();
-        if (template.getHypervisorType() == HypervisorType.VMware) {
-            List<VMTemplateVO> childTemplates = _vmTemplateDao.listByParentTemplatetId(template.getId());
-            for (VMTemplateVO tmpl : childTemplates) {
-                if (tmpl.getTemplateType() != TemplateType.ISODISK) {
-                    ChildTemplateResponse childTempl = new ChildTemplateResponse();
-                    childTempl.setId(tmpl.getUuid());
-                    childTempl.setName(tmpl.getName());
-                    childTempl.setSize(Math.round(tmpl.getSize() / (1024 * 1024 * 1024)));
-                    childTemplatesSet.add(childTempl);
-                }
-            }
-            templateResponse.setChildTemplates(childTemplatesSet);
-        }
-
-        templateResponse.setObjectName("template");
-        return templateResponse;
-    }
-
-    //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse
-    // compared to listTemplates and listIsos.
-    @Override
-    public TemplateResponse newUpdateResponse(TemplateJoinVO result) {
-        TemplateResponse response = new TemplateResponse();
-        response.setId(result.getUuid());
-        response.setName(result.getName());
-        response.setDisplayText(result.getDisplayText());
-        response.setPublic(result.isPublicTemplate());
-        response.setCreated(result.getCreated());
-        response.setFormat(result.getFormat());
-        response.setOsTypeId(result.getGuestOSUuid());
-        response.setOsTypeName(result.getGuestOSName());
-        response.setBootable(result.isBootable());
-        response.setHypervisor(result.getHypervisorType().toString());
-        response.setDynamicallyScalable(result.isDynamicallyScalable());
-
-        // populate owner.
-        ApiResponseHelper.populateOwner(response, result);
-
-        // populate domain
-        response.setDomainId(result.getDomainUuid());
-        response.setDomainName(result.getDomainName());
-
-        // set details map
-        if (result.getDetailName() != null) {
-            Map<String, String> details = new HashMap<>();
-            details.put(result.getDetailName(), result.getDetailValue());
-            response.setDetails(details);
-        }
-
-        // update tag information
-        long tag_id = result.getTagId();
-        if (tag_id > 0) {
-            ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
-            if (vtag != null) {
-                response.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
-            }
-        }
-
-        response.setObjectName("iso");
-        return response;
-    }
-
-    @Override
-    public TemplateResponse setTemplateResponse(ResponseView view, TemplateResponse templateResponse, TemplateJoinVO template) {
-
-        // update details map
-        if (template.getDetailName() != null) {
-            Map<String, String> details = templateResponse.getDetails();
-            if (details == null) {
-                details = new HashMap<>();
-            }
-            details.put(template.getDetailName(), template.getDetailValue());
-            templateResponse.setDetails(details);
-        }
-
-        // update tag information
-        long tag_id = template.getTagId();
-        if (tag_id > 0) {
-            addTagInformation(template, templateResponse);
-        }
-
-        return templateResponse;
-    }
-
-    @Override
-    public TemplateResponse newIsoResponse(TemplateJoinVO iso) {
-
-        TemplateResponse isoResponse = new TemplateResponse();
-        isoResponse.setId(iso.getUuid());
-        isoResponse.setName(iso.getName());
-        isoResponse.setDisplayText(iso.getDisplayText());
-        isoResponse.setPublic(iso.isPublicTemplate());
-        isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST));
-        isoResponse.setCreated(iso.getCreatedOnStore());
-        isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
-        if (iso.getTemplateType() == TemplateType.PERHOST) {
-            // for xs-tools.iso and vmware-tools.iso, we didn't download, but is ready to use.
-            isoResponse.setReady(true);
-        } else {
-            isoResponse.setReady(iso.getState() == ObjectInDataStoreStateMachine.State.Ready);
-        }
-        isoResponse.setBootable(iso.isBootable());
-        isoResponse.setFeatured(iso.isFeatured());
-        isoResponse.setCrossZones(iso.isCrossZones());
-        isoResponse.setPublic(iso.isPublicTemplate());
-        isoResponse.setChecksum(DigestHelper.getHashValueFromChecksumValue(iso.getChecksum()));
-
-        isoResponse.setOsTypeId(iso.getGuestOSUuid());
-        isoResponse.setOsTypeName(iso.getGuestOSName());
-        isoResponse.setBits(iso.getBits());
-
-        // populate owner.
-        ApiResponseHelper.populateOwner(isoResponse, iso);
-
-        // populate domain
-        isoResponse.setDomainId(iso.getDomainUuid());
-        isoResponse.setDomainName(iso.getDomainName());
-
-        Account caller = CallContext.current().getCallingAccount();
-        boolean isAdmin = false;
-        if ((caller == null) || _accountService.isAdmin(caller.getId())) {
-            isAdmin = true;
-        }
-
-        // If the user is an admin, add the template download status
-        if (isAdmin || caller.getId() == iso.getAccountId()) {
-            // add download status
-            if (iso.getDownloadState() != Status.DOWNLOADED) {
-                String isoStatus = "Processing";
-                if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
-                    isoStatus = "Download Complete";
-                } else if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
-                    if (iso.getDownloadPercent() == 100) {
-                        isoStatus = "Installing ISO";
-                    } else {
-                        isoStatus = iso.getDownloadPercent() + "% Downloaded";
-                    }
-                } else if (iso.getDownloadState() == Status.BYPASSED) {
-                    isoStatus = "Bypassed Secondary Storage";
-                } else {
-                    isoStatus = iso.getErrorString();
-                }
-                isoResponse.setStatus(isoStatus);
-            } else {
-                isoResponse.setStatus("Successfully Installed");
-            }
-        }
-
-        if (iso.getDataCenterId() > 0) {
-            isoResponse.setZoneId(iso.getDataCenterUuid());
-            isoResponse.setZoneName(iso.getDataCenterName());
-        }
-
-        Long isoSize = iso.getSize();
-        if (isoSize > 0) {
-            isoResponse.setSize(isoSize);
-        }
-
-        // update tag information
-        long tag_id = iso.getTagId();
-        if (tag_id > 0) {
-            ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
-            if (vtag != null) {
-                isoResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
-            }
-        }
-
-        isoResponse.setDirectDownload(iso.isDirectDownload());
-
-        isoResponse.setObjectName("iso");
-        return isoResponse;
-
-    }
-
-    @Override
-    public List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate template) {
-        SearchCriteria<TemplateJoinVO> sc = tmpltIdSearch.create();
-        sc.setParameters("id", template.getId());
-        return searchIncludingRemoved(sc, null, null, false);
-    }
-
-    @Override
-    public List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate template, long zoneId, boolean readyOnly) {
-        SearchCriteria<TemplateJoinVO> sc = tmpltZoneSearch.create();
-        sc.setParameters("id", template.getId());
-        sc.setParameters("dataCenterId", zoneId);
-        if (readyOnly) {
-            sc.setParameters("state", TemplateState.Ready);
-        }
-        return searchIncludingRemoved(sc, null, null, false);
-    }
-
-    @Override
-    public List<TemplateJoinVO> searchByTemplateZonePair(Boolean showRemoved, String... idPairs) {
-        // set detail batch query size
-        int DETAILS_BATCH_SIZE = 2000;
-        String batchCfg = _configDao.getValue("detail.batch.query.size");
-        if (batchCfg != null) {
-            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
-        }
-        // query details by batches
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = (isAscending == null ? Boolean.TRUE : isAscending);
-        Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, null, null);
-        searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", isAscending);
-        List<TemplateJoinVO> uvList = new ArrayList<TemplateJoinVO>();
-        // query details by batches
-        int curr_index = 0;
-        if (idPairs.length > DETAILS_BATCH_SIZE) {
-            while ((curr_index + DETAILS_BATCH_SIZE) <= idPairs.length) {
-                String[] labels = new String[DETAILS_BATCH_SIZE];
-                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
-                    labels[k] = idPairs[j];
-                }
-                SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
-                if (!showRemoved) {
-                    sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
-                }
-                sc.setParameters("tempZonePairIN", labels);
-                List<TemplateJoinVO> vms = searchIncludingRemoved(sc, searchFilter, null, false);
-                if (vms != null) {
-                    uvList.addAll(vms);
-                }
-                curr_index += DETAILS_BATCH_SIZE;
-            }
-        }
-        if (curr_index < idPairs.length) {
-            int batch_size = (idPairs.length - curr_index);
-            String[] labels = new String[batch_size];
-            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
-                labels[k] = idPairs[j];
-            }
-            SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
-            if (!showRemoved) {
-                sc.setParameters("templateState", VirtualMachineTemplate.State.Active, VirtualMachineTemplate.State.UploadAbandoned, VirtualMachineTemplate.State.UploadError ,VirtualMachineTemplate.State.NotUploaded, VirtualMachineTemplate.State.UploadInProgress);
-            }
-            sc.setParameters("tempZonePairIN", labels);
-            List<TemplateJoinVO> vms = searchIncludingRemoved(sc, searchFilter, null, false);
-            if (vms != null) {
-                uvList.addAll(vms);
-            }
-        }
-        return uvList;
-    }
-
-    @Override
-    public List<TemplateJoinVO> listActiveTemplates(long storeId) {
-        SearchCriteria<TemplateJoinVO> sc = activeTmpltSearch.create();
-        sc.setParameters("store_id", storeId);
-        sc.setParameters("type", TemplateType.USER);
-        sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
-        return searchIncludingRemoved(sc, null, null, false);
-    }
-
-    @Override
-    public Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<TemplateJoinVO> sc, final Filter filter) {
-        List<TemplateJoinVO> objects = searchIncludingRemoved(sc, filter, null, false);
-        Integer count = getCount(sc);
-        return new Pair<List<TemplateJoinVO>, Integer>(objects, count);
-    }
-
-}
diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
deleted file mode 100644
index 00ec61a..0000000
--- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
+++ /dev/null
@@ -1,504 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.dao;
-
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.affinity.AffinityGroupResponse;
-import org.apache.cloudstack.api.ApiConstants.VMDetails;
-import org.apache.cloudstack.api.ResponseObject.ResponseView;
-import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
-import org.apache.cloudstack.api.response.NicResponse;
-import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
-import org.apache.cloudstack.api.response.SecurityGroupResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.vo.UserVmJoinVO;
-import com.cloud.gpu.GPU;
-import com.cloud.service.ServiceOfferingDetailsVO;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-import com.cloud.user.dao.UserDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.net.Dhcp;
-import com.cloud.vm.UserVmDetailVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VmStats;
-import com.cloud.vm.dao.NicExtraDhcpOptionDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.dao.UserVmDetailsDao;
-
-@Component
-public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJoinVO, UserVmResponse> implements UserVmJoinDao {
-    public static final Logger s_logger = Logger.getLogger(UserVmJoinDaoImpl.class);
-
-    @Inject
-    private ConfigurationDao  _configDao;
-    @Inject
-    public AccountManager _accountMgr;
-    @Inject
-    private UserVmDetailsDao _userVmDetailsDao;
-    @Inject
-    private UserDao _userDao;
-    @Inject
-    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
-
-    private final SearchBuilder<UserVmJoinVO> VmDetailSearch;
-    private final SearchBuilder<UserVmJoinVO> activeVmByIsoSearch;
-
-    protected UserVmJoinDaoImpl() {
-
-        VmDetailSearch = createSearchBuilder();
-        VmDetailSearch.and("idIN", VmDetailSearch.entity().getId(), SearchCriteria.Op.IN);
-        VmDetailSearch.done();
-
-        _count = "select count(distinct id) from user_vm_view WHERE ";
-
-        activeVmByIsoSearch = createSearchBuilder();
-        activeVmByIsoSearch.and("isoId", activeVmByIsoSearch.entity().getIsoId(), SearchCriteria.Op.EQ);
-        activeVmByIsoSearch.and("stateNotIn", activeVmByIsoSearch.entity().getState(), SearchCriteria.Op.NIN);
-        activeVmByIsoSearch.done();
-    }
-
-    @Override
-    public List<UserVmJoinVO> listActiveByIsoId(Long isoId) {
-        SearchCriteria<UserVmJoinVO> sc = activeVmByIsoSearch.create();
-        sc.setParameters("isoId", isoId);
-        State[] states = new State[2];
-        states[0] = State.Error;
-        states[1] = State.Expunging;
-        return listBy(sc);
-    }
-
-    @Override
-    public UserVmResponse newUserVmResponse(ResponseView view, String objectName, UserVmJoinVO userVm, EnumSet<VMDetails> details, Account caller) {
-        UserVmResponse userVmResponse = new UserVmResponse();
-
-        if (userVm.getHypervisorType() != null) {
-            userVmResponse.setHypervisor(userVm.getHypervisorType().toString());
-        }
-        userVmResponse.setId(userVm.getUuid());
-        userVmResponse.setName(userVm.getName());
-
-        if (userVm.getDisplayName() != null) {
-        userVmResponse.setDisplayName(userVm.getDisplayName());
-        } else {
-            userVmResponse.setDisplayName(userVm.getName());
-        }
-
-        if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
-            userVmResponse.setProjectId(userVm.getProjectUuid());
-            userVmResponse.setProjectName(userVm.getProjectName());
-        } else {
-            userVmResponse.setAccountName(userVm.getAccountName());
-        }
-
-        User user = _userDao.getUser(userVm.getUserId());
-        if (user != null) {
-            userVmResponse.setUserId(user.getUuid());
-            userVmResponse.setUserName(user.getUsername());
-        }
-        userVmResponse.setDomainId(userVm.getDomainUuid());
-        userVmResponse.setDomainName(userVm.getDomainName());
-
-        userVmResponse.setCreated(userVm.getCreated());
-        userVmResponse.setDisplayVm(userVm.isDisplayVm());
-
-        if (userVm.getState() != null) {
-            userVmResponse.setState(userVm.getState().toString());
-        }
-        userVmResponse.setHaEnable(userVm.isHaEnabled());
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.group)) {
-            userVmResponse.setGroupId(userVm.getInstanceGroupUuid());
-            userVmResponse.setGroup(userVm.getInstanceGroupName());
-        }
-        userVmResponse.setZoneId(userVm.getDataCenterUuid());
-        userVmResponse.setZoneName(userVm.getDataCenterName());
-        if (view == ResponseView.Full) {
-            userVmResponse.setInstanceName(userVm.getInstanceName());
-            userVmResponse.setHostId(userVm.getHostUuid());
-            userVmResponse.setHostName(userVm.getHostName());
-        }
-
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) {
-            userVmResponse.setTemplateId(userVm.getTemplateUuid());
-            userVmResponse.setTemplateName(userVm.getTemplateName());
-            userVmResponse.setTemplateDisplayText(userVm.getTemplateDisplayText());
-            userVmResponse.setPasswordEnabled(userVm.isPasswordEnabled());
-        }
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.iso)) {
-            userVmResponse.setIsoId(userVm.getIsoUuid());
-            userVmResponse.setIsoName(userVm.getIsoName());
-            userVmResponse.setIsoDisplayText(userVm.getIsoDisplayText());
-        }
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) {
-            userVmResponse.setServiceOfferingId(userVm.getServiceOfferingUuid());
-            userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName());
-        }
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.diskoff)) {
-            userVmResponse.setDiskOfferingId(userVm.getDiskOfferingUuid());
-            userVmResponse.setDiskOfferingName(userVm.getDiskOfferingName());
-        }
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff) || details.contains(VMDetails.stats)) {
-            userVmResponse.setCpuNumber(userVm.getCpu());
-            userVmResponse.setCpuSpeed(userVm.getSpeed());
-            userVmResponse.setMemory(userVm.getRamSize());
-            ServiceOfferingDetailsVO serviceOfferingDetail = ApiDBUtils.findServiceOfferingDetail(userVm.getServiceOfferingId(), GPU.Keys.vgpuType.toString());
-            if (serviceOfferingDetail != null) {
-                userVmResponse.setVgpu(serviceOfferingDetail.getValue());
-            }
-        }
-        userVmResponse.setGuestOsId(userVm.getGuestOsUuid());
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.volume)) {
-            userVmResponse.setRootDeviceId(userVm.getVolumeDeviceId());
-            if (userVm.getVolumeType() != null) {
-                userVmResponse.setRootDeviceType(userVm.getVolumeType().toString());
-            }
-        }
-        userVmResponse.setPassword(userVm.getPassword());
-        if (userVm.getJobId() != null) {
-            userVmResponse.setJobId(userVm.getJobUuid());
-            userVmResponse.setJobStatus(userVm.getJobStatus());
-        }
-        //userVmResponse.setForVirtualNetwork(userVm.getForVirtualNetwork());
-
-        userVmResponse.setPublicIpId(userVm.getPublicIpUuid());
-        userVmResponse.setPublicIp(userVm.getPublicIpAddress());
-        userVmResponse.setKeyPairName(userVm.getKeypairName());
-        userVmResponse.setOsTypeId(userVm.getGuestOsUuid());
-
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.stats)) {
-            // stats calculation
-            VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId());
-            if (vmStats != null) {
-                userVmResponse.setCpuUsed(new DecimalFormat("#.##").format(vmStats.getCPUUtilization()) + "%");
-                userVmResponse.setNetworkKbsRead((long)vmStats.getNetworkReadKBs());
-                userVmResponse.setNetworkKbsWrite((long)vmStats.getNetworkWriteKBs());
-                userVmResponse.setDiskKbsRead((long)vmStats.getDiskReadKBs());
-                userVmResponse.setDiskKbsWrite((long)vmStats.getDiskWriteKBs());
-                userVmResponse.setDiskIORead((long)vmStats.getDiskReadIOs());
-                userVmResponse.setDiskIOWrite((long)vmStats.getDiskWriteIOs());
-                userVmResponse.setMemoryKBs((long)vmStats.getMemoryKBs());
-                userVmResponse.setMemoryIntFreeKBs((long)vmStats.getIntFreeMemoryKBs());
-                userVmResponse.setMemoryTargetKBs((long)vmStats.getTargetMemoryKBs());
-
-            }
-        }
-
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.secgrp)) {
-            Long securityGroupId = userVm.getSecurityGroupId();
-            if (securityGroupId != null && securityGroupId.longValue() != 0) {
-                SecurityGroupResponse resp = new SecurityGroupResponse();
-                resp.setId(userVm.getSecurityGroupUuid());
-                resp.setName(userVm.getSecurityGroupName());
-                resp.setDescription(userVm.getSecurityGroupDescription());
-                resp.setObjectName("securitygroup");
-                if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
-                    resp.setProjectId(userVm.getProjectUuid());
-                    resp.setProjectName(userVm.getProjectName());
-                } else {
-                    resp.setAccountName(userVm.getAccountName());
-                }
-                userVmResponse.addSecurityGroup(resp);
-            }
-        }
-
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.nics)) {
-            long nic_id = userVm.getNicId();
-            if (nic_id > 0) {
-                NicResponse nicResponse = new NicResponse();
-                nicResponse.setId(userVm.getNicUuid());
-                nicResponse.setIpaddress(userVm.getIpAddress());
-                nicResponse.setGateway(userVm.getGateway());
-                nicResponse.setNetmask(userVm.getNetmask());
-                nicResponse.setNetworkid(userVm.getNetworkUuid());
-                nicResponse.setNetworkName(userVm.getNetworkName());
-                nicResponse.setMacAddress(userVm.getMacAddress());
-                nicResponse.setIp6Address(userVm.getIp6Address());
-                nicResponse.setIp6Gateway(userVm.getIp6Gateway());
-                nicResponse.setIp6Cidr(userVm.getIp6Cidr());
-                if (userVm.getBroadcastUri() != null) {
-                    nicResponse.setBroadcastUri(userVm.getBroadcastUri().toString());
-                }
-                if (userVm.getIsolationUri() != null) {
-                    nicResponse.setIsolationUri(userVm.getIsolationUri().toString());
-                }
-                if (userVm.getTrafficType() != null) {
-                    nicResponse.setTrafficType(userVm.getTrafficType().toString());
-                }
-                if (userVm.getGuestType() != null) {
-                    nicResponse.setType(userVm.getGuestType().toString());
-                }
-                nicResponse.setIsDefault(userVm.isDefaultNic());
-                List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(userVm.getNicId());
-                if (secondaryIps != null) {
-                    List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
-                    for (NicSecondaryIpVO ip : secondaryIps) {
-                        NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
-                        ipRes.setId(ip.getUuid());
-                        ipRes.setIpAddr(ip.getIp4Address());
-                        ipList.add(ipRes);
-                    }
-                    nicResponse.setSecondaryIps(ipList);
-                }
-                nicResponse.setObjectName("nic");
-
-                List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id)
-                        .stream()
-                        .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
-                        .collect(Collectors.toList());
-                nicResponse.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
-
-                userVmResponse.addNic(nicResponse);
-            }
-        }
-
-        // update tag information
-        long tag_id = userVm.getTagId();
-        if (tag_id > 0 && !userVmResponse.containTag(tag_id)) {
-            addTagInformation(userVm, userVmResponse);
-        }
-
-        if (details.contains(VMDetails.all) || details.contains(VMDetails.affgrp)) {
-            Long affinityGroupId = userVm.getAffinityGroupId();
-            if (affinityGroupId != null && affinityGroupId.longValue() != 0) {
-                AffinityGroupResponse resp = new AffinityGroupResponse();
-                resp.setId(userVm.getAffinityGroupUuid());
-                resp.setName(userVm.getAffinityGroupName());
-                resp.setDescription(userVm.getAffinityGroupDescription());
-                resp.setObjectName("affinitygroup");
-                resp.setAccountName(userVm.getAccountName());
-                userVmResponse.addAffinityGroup(resp);
-            }
-        }
-
-        // set resource details map
-        // Allow passing details to end user
-        List<UserVmDetailVO> vmDetails = _userVmDetailsDao.listDetails(userVm.getId());
-        if (vmDetails != null) {
-            Map<String, String> resourceDetails = new HashMap<String, String>();
-            for (UserVmDetailVO userVmDetailVO : vmDetails) {
-                resourceDetails.put(userVmDetailVO.getName(), userVmDetailVO.getValue());
-            }
-            userVmResponse.setDetails(resourceDetails);
-        }
-
-        userVmResponse.setObjectName(objectName);
-        if (userVm.isDynamicallyScalable() == null) {
-            userVmResponse.setDynamicallyScalable(false);
-        } else {
-            userVmResponse.setDynamicallyScalable(userVm.isDynamicallyScalable());
-        }
-
-        return userVmResponse;
-    }
-
-    /**
-     * The resulting Response attempts to be in line with what is returned from
-     * @see com.cloud.api.ApiResponseHelper#createNicResponse(Nic)
-     */
-    @Override
-    public UserVmResponse setUserVmResponse(ResponseView view, UserVmResponse userVmData, UserVmJoinVO uvo) {
-        Long securityGroupId = uvo.getSecurityGroupId();
-        if (securityGroupId != null && securityGroupId.longValue() != 0) {
-            SecurityGroupResponse resp = new SecurityGroupResponse();
-            resp.setId(uvo.getSecurityGroupUuid());
-            resp.setName(uvo.getSecurityGroupName());
-            resp.setDescription(uvo.getSecurityGroupDescription());
-            resp.setObjectName("securitygroup");
-            if (uvo.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
-                resp.setProjectId(uvo.getProjectUuid());
-                resp.setProjectName(uvo.getProjectName());
-            } else {
-                resp.setAccountName(uvo.getAccountName());
-            }
-            userVmData.addSecurityGroup(resp);
-        }
-
-        long nic_id = uvo.getNicId();
-        if (nic_id > 0) {
-            NicResponse nicResponse = new NicResponse();
-            // The numbered comments are to keep track of the data returned from here and ApiResponseHelper.createNicResponse()
-            // the data can't be identical but some tidying up/unifying might be possible
-            /*1: nicUuid*/
-            nicResponse.setId(uvo.getNicUuid());
-            /*2: networkUuid*/
-            nicResponse.setNetworkid(uvo.getNetworkUuid());
-            /*3: vmId makes no sense on a nested nic object so it is ommited here */
-
-            if (uvo.getTrafficType() != null) {
-            /*4: trafficType*/
-                nicResponse.setTrafficType(uvo.getTrafficType().toString());
-            }
-            if (uvo.getGuestType() != null) {
-                /*5: guestType*/
-                nicResponse.setType(uvo.getGuestType().toString());
-            }
-            /*6: ipAddress*/
-            nicResponse.setIpaddress(uvo.getIpAddress());
-            /*7: gateway*/
-            nicResponse.setGateway(uvo.getGateway());
-            /*8: netmask*/
-            nicResponse.setNetmask(uvo.getNetmask());
-            /*9: networkName*/
-            nicResponse.setNetworkName(uvo.getNetworkName());
-            /*10: macAddress*/
-            nicResponse.setMacAddress(uvo.getMacAddress());
-            /*11: IPv6Address*/
-            nicResponse.setIp6Address(uvo.getIp6Address());
-            /*12: IPv6Gateway*/
-            nicResponse.setIp6Gateway(uvo.getIp6Gateway());
-            /*13: IPv6Cidr*/
-            nicResponse.setIp6Cidr(uvo.getIp6Cidr());
-            /*14: deviceId*/
-// where do we find           nicResponse.setDeviceId(
-// this is probably not String.valueOf(uvo.getNicId())); as this is a db-id
-            /*15: broadcastURI*/
-            if (uvo.getBroadcastUri() != null) {
-                nicResponse.setBroadcastUri(uvo.getBroadcastUri().toString());
-            }
-            /*16: isolationURI*/
-            if (uvo.getIsolationUri() != null) {
-                nicResponse.setIsolationUri(uvo.getIsolationUri().toString());
-            }
-            /*17: default*/
-            nicResponse.setIsDefault(uvo.isDefaultNic());
-            List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(uvo.getNicId());
-            if (secondaryIps != null) {
-                List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
-                for (NicSecondaryIpVO ip : secondaryIps) {
-                    NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
-                    ipRes.setId(ip.getUuid());
-                    ipRes.setIpAddr(ip.getIp4Address());
-                    ipList.add(ipRes);
-                }
-                nicResponse.setSecondaryIps(ipList);
-            }
-
-            /* 18: extra dhcp options */
-            nicResponse.setObjectName("nic");
-            List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id)
-                    .stream()
-                    .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
-                    .collect(Collectors.toList());
-            nicResponse.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
-            userVmData.addNic(nicResponse);
-        }
-
-        long tag_id = uvo.getTagId();
-        if (tag_id > 0 && !userVmData.containTag(tag_id)) {
-            addTagInformation(uvo, userVmData);
-        }
-
-        Long affinityGroupId = uvo.getAffinityGroupId();
-        if (affinityGroupId != null && affinityGroupId.longValue() != 0) {
-            AffinityGroupResponse resp = new AffinityGroupResponse();
-            resp.setId(uvo.getAffinityGroupUuid());
-            resp.setName(uvo.getAffinityGroupName());
-            resp.setDescription(uvo.getAffinityGroupDescription());
-            resp.setObjectName("affinitygroup");
-            resp.setAccountName(uvo.getAccountName());
-            userVmData.addAffinityGroup(resp);
-        }
-
-        return userVmData;
-    }
-
-    @Override
-    public List<UserVmJoinVO> searchByIds(Long... vmIds) {
-        // set detail batch query size
-        int DETAILS_BATCH_SIZE = 2000;
-        String batchCfg = _configDao.getValue("detail.batch.query.size");
-        if (batchCfg != null) {
-            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
-        }
-        // query details by batches
-        List<UserVmJoinVO> uvList = new ArrayList<UserVmJoinVO>();
-        // query details by batches
-        int curr_index = 0;
-        if (vmIds.length > DETAILS_BATCH_SIZE) {
-            while ((curr_index + DETAILS_BATCH_SIZE) <= vmIds.length) {
-                Long[] ids = new Long[DETAILS_BATCH_SIZE];
-                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
-                    ids[k] = vmIds[j];
-                }
-                SearchCriteria<UserVmJoinVO> sc = VmDetailSearch.create();
-                sc.setParameters("idIN", ids);
-                List<UserVmJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
-                if (vms != null) {
-                    uvList.addAll(vms);
-                }
-                curr_index += DETAILS_BATCH_SIZE;
-            }
-        }
-        if (curr_index < vmIds.length) {
-            int batch_size = (vmIds.length - curr_index);
-            // set the ids value
-            Long[] ids = new Long[batch_size];
-            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
-                ids[k] = vmIds[j];
-            }
-            SearchCriteria<UserVmJoinVO> sc = VmDetailSearch.create();
-            sc.setParameters("idIN", ids);
-            List<UserVmJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
-            if (vms != null) {
-                uvList.addAll(vms);
-            }
-        }
-        return uvList;
-    }
-
-    @Override
-    public List<UserVmJoinVO> newUserVmView(UserVm... userVms) {
-
-        Hashtable<Long, UserVm> userVmDataHash = new Hashtable<Long, UserVm>();
-        for (UserVm vm : userVms) {
-            if (!userVmDataHash.containsKey(vm.getId())) {
-                userVmDataHash.put(vm.getId(), vm);
-            }
-        }
-
-        Set<Long> vmIdSet = userVmDataHash.keySet();
-        List<UserVmJoinVO> uvms = searchByIds(vmIdSet.toArray(new Long[vmIdSet.size()]));
-        // populate transit password field from UserVm
-        if (uvms != null) {
-            for (UserVmJoinVO uvm : uvms) {
-                UserVm v = userVmDataHash.get(uvm.getId());
-                uvm.setPassword(v.getPassword());
-            }
-        }
-        return uvms;
-    }
-
-}
diff --git a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
deleted file mode 100644
index e846b0b..0000000
--- a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
+++ /dev/null
@@ -1,242 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.vo;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.storage.Storage;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-import com.cloud.offering.DiskOffering.Type;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "disk_offering_view")
-public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, Identity {
-
-    @Id
-    @Column(name = "id", updatable = false, nullable = false)
-    private long id;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "display_text")
-    private String displayText;
-
-    @Column(name = "provisioning_type")
-    Storage.ProvisioningType provisioningType;
-
-    @Column(name = "disk_size")
-    long diskSize;
-
-    @Column(name = "tags", length = 4096)
-    String tags;
-
-    @Column(name = "use_local_storage")
-    private boolean useLocalStorage;
-
-    @Column(name = "system_use")
-    private boolean systemUse;
-
-    @Column(name = "customized")
-    private boolean customized;
-
-    @Column(name = "customized_iops")
-    private Boolean customizedIops;
-
-    @Column(name = "min_iops")
-    private Long minIops;
-
-    @Column(name = "max_iops")
-    private Long maxIops;
-
-    @Column(name = "hv_ss_reserve")
-    private Integer hypervisorSnapshotReserve;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "bytes_read_rate")
-    Long bytesReadRate;
-
-    @Column(name = "bytes_write_rate")
-    Long bytesWriteRate;
-
-    @Column(name = "iops_read_rate")
-    Long iopsReadRate;
-
-    @Column(name = "iops_write_rate")
-    Long iopsWriteRate;
-
-    @Column(name = "cache_mode")
-    String cacheMode;
-
-    @Column(name = "type")
-    Type type;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = "domain_id")
-    private long domainId;
-
-    @Column(name = "domain_uuid")
-    private String domainUuid;
-
-    @Column(name = "domain_name")
-    private String domainName = null;
-
-    @Column(name = "domain_path")
-    private String domainPath = null;
-
-    @Column(name = "display_offering")
-    boolean displayOffering;
-
-    public DiskOfferingJoinVO() {
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Storage.ProvisioningType getProvisioningType(){
-        return provisioningType;
-    }
-
-    public long getDiskSize() {
-        return diskSize;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public boolean isUseLocalStorage() {
-        return useLocalStorage;
-    }
-
-    public boolean isSystemUse() {
-        return systemUse;
-    }
-
-    public boolean isCustomized() {
-        return customized;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    public String getCacheMode() {
-        return cacheMode;
-    }
-
-    public void setCacheMode(String cacheMode) {
-        this.cacheMode = cacheMode;
-    }
-
-    public boolean isDisplayOffering() {
-        return displayOffering;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public long getDomainId() {
-        return domainId;
-    }
-
-    public String getDomainUuid() {
-        return domainUuid;
-    }
-
-    public String getDomainName() {
-        return domainName;
-    }
-
-    public String getDomainPath() {
-        return domainPath;
-    }
-
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-}
diff --git a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
deleted file mode 100644
index f16ba83..0000000
--- a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
+++ /dev/null
@@ -1,291 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.query.vo;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.storage.Storage;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = "service_offering_view")
-public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentity, Identity {
-
-    @Id
-    @Column(name = "id", updatable = false, nullable = false)
-    private long id;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "display_text")
-    private String displayText;
-
-    @Column(name = "provisioning_type")
-    Storage.ProvisioningType provisioningType;
-
-    @Column(name = "tags", length = 4096)
-    String tags;
-
-    @Column(name = "use_local_storage")
-    private boolean useLocalStorage;
-
-    @Column(name = "system_use")
-    private boolean systemUse;
-
-    @Column(name = "cpu")
-    private Integer cpu;
-
-    @Column(name = "speed")
-    private Integer speed;
-
-    @Column(name = "ram_size")
-    private Integer ramSize;
-
-    @Column(name = "nw_rate")
-    private Integer rateMbps;
-
-    @Column(name = "mc_rate")
-    private Integer multicastRateMbps;
-
-    @Column(name = "ha_enabled")
-    private boolean offerHA;
-
-    @Column(name = "limit_cpu_use")
-    private boolean limitCpuUse;
-
-    @Column(name = "is_volatile")
-    private boolean volatileVm;
-
-    @Column(name = "host_tag")
-    private String hostTag;
-
-    @Column(name = "default_use")
-    private boolean defaultUse;
-
-    @Column(name = "vm_type")
-    private String vmType;
-
-    @Column(name = "customized_iops")
-    private Boolean customizedIops;
-
-    @Column(name = "min_iops")
-    private Long minIops;
-
-    @Column(name = "max_iops")
-    private Long maxIops;
-
-    @Column(name = "hv_ss_reserve")
-    private Integer hypervisorSnapshotReserve;
-
-    @Column(name = "sort_key")
-    int sortKey;
-
-    @Column(name = "bytes_read_rate")
-    Long bytesReadRate;
-
-    @Column(name = "bytes_write_rate")
-    Long bytesWriteRate;
-
-    @Column(name = "iops_read_rate")
-    Long iopsReadRate;
-
-    @Column(name = "iops_write_rate")
-    Long iopsWriteRate;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = "domain_id")
-    private long domainId;
-
-    @Column(name = "domain_uuid")
-    private String domainUuid;
-
-    @Column(name = "domain_name")
-    private String domainName = null;
-
-    @Column(name = "domain_path")
-    private String domainPath = null;
-
-    @Column(name = "deployment_planner")
-    private String deploymentPlanner;
-
-    public ServiceOfferingJoinVO() {
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public Storage.ProvisioningType getProvisioningType(){
-        return provisioningType;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public boolean isUseLocalStorage() {
-        return useLocalStorage;
-    }
-
-    public boolean isSystemUse() {
-        return systemUse;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public long getDomainId() {
-        return domainId;
-    }
-
-    public String getDomainUuid() {
-        return domainUuid;
-    }
-
-    public String getDomainName() {
-        return domainName;
-    }
-
-    public String getDomainPath() {
-        return domainPath;
-    }
-
-    public Boolean isCustomizedIops() {
-        return customizedIops;
-    }
-
-    public Long getMinIops() {
-        return minIops;
-    }
-
-    public Long getMaxIops() {
-        return maxIops;
-    }
-
-    public Integer getHypervisorSnapshotReserve() {
-        return hypervisorSnapshotReserve;
-    }
-
-    public int getSortKey() {
-        return sortKey;
-    }
-
-    public Integer getCpu() {
-        return cpu;
-    }
-
-    public Integer getSpeed() {
-        return speed;
-    }
-
-    public Integer getRamSize() {
-        return ramSize;
-    }
-
-    public Integer getRateMbps() {
-        return rateMbps;
-    }
-
-    public Integer getMulticastRateMbps() {
-        return multicastRateMbps;
-    }
-
-    public boolean isOfferHA() {
-        return offerHA;
-    }
-
-    public boolean isLimitCpuUse() {
-        return limitCpuUse;
-    }
-
-    public String getHostTag() {
-        return hostTag;
-    }
-
-    public boolean isDefaultUse() {
-        return defaultUse;
-    }
-
-    public String getSystemVmType() {
-        return vmType;
-    }
-
-    public String getDeploymentPlanner() {
-        return deploymentPlanner;
-    }
-
-    public boolean getVolatileVm() {
-        return volatileVm;
-    }
-
-    public Long getBytesReadRate() {
-        return bytesReadRate;
-    }
-
-    public Long getBytesWriteRate() {
-        return bytesWriteRate;
-    }
-
-    public Long getIopsReadRate() {
-        return iopsReadRate;
-    }
-
-    public Long getIopsWriteRate() {
-        return iopsWriteRate;
-    }
-
-    public boolean isDynamic() {
-        return cpu == null || speed == null || ramSize == null;
-    }
-}
diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java
deleted file mode 100644
index 2b9717d..0000000
--- a/server/src/com/cloud/api/response/ApiResponseSerializer.java
+++ /dev/null
@@ -1,384 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api.response;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.ApiResponseGsonHelper;
-import com.cloud.api.ApiServer;
-import com.cloud.serializer.Param;
-import com.cloud.user.Account;
-import com.cloud.utils.HttpUtils;
-import com.cloud.utils.encoding.URLEncoder;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionProxyObject;
-import com.google.gson.Gson;
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.ResponseObject;
-import org.apache.cloudstack.api.response.AsyncJobResponse;
-import org.apache.cloudstack.api.response.AuthenticationCmdResponse;
-import org.apache.cloudstack.api.response.CreateCmdResponse;
-import org.apache.cloudstack.api.response.ExceptionResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class ApiResponseSerializer {
-    private static final Logger s_logger = Logger.getLogger(ApiResponseSerializer.class.getName());
-
-    public static String toSerializedString(ResponseObject result, String responseType) {
-        s_logger.trace("===Serializing Response===");
-        if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
-            return toJSONSerializedString(result, new StringBuilder());
-        } else {
-            return toXMLSerializedString(result, new StringBuilder());
-        }
-    }
-
-    public static String toSerializedStringWithSecureLogs(ResponseObject result, String responseType, StringBuilder log) {
-        s_logger.trace("===Serializing Response===");
-        if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
-            return toJSONSerializedString(result, log);
-        } else {
-            return toXMLSerializedString(result, log);
-        }
-    }
-
-    private static final Pattern s_unicodeEscapePattern = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");
-
-    public static String unescape(String escaped) {
-        String str = escaped;
-        Matcher matcher = s_unicodeEscapePattern.matcher(str);
-        while (matcher.find()) {
-            str = str.replaceAll("\\" + matcher.group(0), Character.toString((char)Integer.parseInt(matcher.group(1), 16)));
-        }
-        return str;
-    }
-
-    public static String toJSONSerializedString(ResponseObject result, StringBuilder log) {
-        if (result != null && log != null) {
-            Gson responseBuilder = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
-            Gson logBuilder = ApiResponseGsonHelper.getLogBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
-
-            StringBuilder sb = new StringBuilder();
-
-            sb.append("{\"").append(result.getResponseName()).append("\":");
-            log.append("{\"").append(result.getResponseName()).append("\":");
-            if (result instanceof ListResponse) {
-                List<? extends ResponseObject> responses = ((ListResponse)result).getResponses();
-                Integer count = ((ListResponse)result).getCount();
-                boolean nonZeroCount = (count != null && count.longValue() != 0);
-                if (nonZeroCount) {
-                    sb.append("{\"").append(ApiConstants.COUNT).append("\":").append(count);
-                    log.append("{\"").append(ApiConstants.COUNT).append("\":").append(count);
-                }
-
-                if ((responses != null) && !responses.isEmpty()) {
-                    String jsonStr = responseBuilder.toJson(responses.get(0));
-                    jsonStr = unescape(jsonStr);
-                    String logStr = logBuilder.toJson(responses.get(0));
-                    logStr = unescape(logStr);
-
-                    if (nonZeroCount) {
-                        sb.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(jsonStr);
-                        log.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(logStr);
-                    }
-
-                    for (int i = 1; i < ((ListResponse)result).getResponses().size(); i++) {
-                        jsonStr = responseBuilder.toJson(responses.get(i));
-                        jsonStr = unescape(jsonStr);
-                        logStr = logBuilder.toJson(responses.get(i));
-                        logStr = unescape(logStr);
-                        sb.append(",").append(jsonStr);
-                        log.append(",").append(logStr);
-                    }
-                    sb.append("]}");
-                    log.append("]}");
-                } else  {
-                    if (!nonZeroCount) {
-                        sb.append("{");
-                        log.append("{");
-                    }
-
-                    sb.append("}");
-                    log.append("}");
-                }
-            } else if (result instanceof SuccessResponse) {
-                sb.append("{\"success\":\"").append(((SuccessResponse)result).getSuccess()).append("\"}");
-                log.append("{\"success\":\"").append(((SuccessResponse)result).getSuccess()).append("\"}");
-            } else if (result instanceof ExceptionResponse) {
-                String jsonErrorText = responseBuilder.toJson(result);
-                jsonErrorText = unescape(jsonErrorText);
-                sb.append(jsonErrorText);
-                log.append(jsonErrorText);
-            } else {
-                String jsonStr = responseBuilder.toJson(result);
-                if (jsonStr != null && !jsonStr.isEmpty()) {
-                    jsonStr = unescape(jsonStr);
-                    if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) {
-                        sb.append(jsonStr);
-                    } else {
-                        sb.append("{\"").append(result.getObjectName()).append("\":").append(jsonStr).append("}");
-                    }
-                } else {
-                    sb.append("{}");
-                }
-                String logStr = logBuilder.toJson(result);
-                if (logStr != null && !logStr.isEmpty()) {
-                    logStr = unescape(logStr);
-                    if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) {
-                        log.append(logStr);
-                    } else {
-                        log.append("{\"").append(result.getObjectName()).append("\":").append(logStr).append("}");
-                    }
-                } else {
-                    log.append("{}");
-                }
-            }
-            sb.append("}");
-            log.append("}");
-            return sb.toString();
-        }
-        return null;
-    }
-
-    private static String toXMLSerializedString(ResponseObject result, StringBuilder log) {
-        if (result != null && log != null) {
-            StringBuilder sb = new StringBuilder();
-            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            sb.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
-            log.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            log.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
-
-            if (result instanceof ListResponse) {
-                Integer count = ((ListResponse)result).getCount();
-
-                if (count != null && count != 0) {
-                    sb.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append("</").append(ApiConstants.COUNT).append(">");
-                    log.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append("</").append(ApiConstants.COUNT).append(">");
-                }
-                List<? extends ResponseObject> responses = ((ListResponse)result).getResponses();
-                if ((responses != null) && !responses.isEmpty()) {
-                    for (ResponseObject obj : responses) {
-                        serializeResponseObjXML(sb, log, obj);
-                    }
-                }
-            } else {
-                if (result instanceof CreateCmdResponse || result instanceof AsyncJobResponse || result instanceof AuthenticationCmdResponse) {
-                    serializeResponseObjFieldsXML(sb, log, result);
-                } else {
-                    serializeResponseObjXML(sb, log, result);
-                }
-            }
-
-            sb.append("</").append(result.getResponseName()).append(">");
-            log.append("</").append(result.getResponseName()).append(">");
-            return sb.toString();
-        }
-        return null;
-    }
-
-    private static void serializeResponseObjXML(StringBuilder sb, StringBuilder log, ResponseObject obj) {
-        if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) {
-            sb.append("<").append(obj.getObjectName()).append(">");
-            log.append("<").append(obj.getObjectName()).append(">");
-        }
-        serializeResponseObjFieldsXML(sb, log, obj);
-        if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) {
-            sb.append("</").append(obj.getObjectName()).append(">");
-            log.append("</").append(obj.getObjectName()).append(">");
-        }
-    }
-
-    private static Field[] getFlattenFields(Class<?> clz) {
-        List<Field> fields = new ArrayList<Field>();
-        fields.addAll(Arrays.asList(clz.getDeclaredFields()));
-        if (clz.getSuperclass() != null) {
-            fields.addAll(Arrays.asList(getFlattenFields(clz.getSuperclass())));
-        }
-        return fields.toArray(new Field[] {});
-    }
-
-    private static void serializeResponseObjFieldsXML(StringBuilder sb, StringBuilder log, ResponseObject obj) {
-        boolean isAsync = false;
-        if (obj instanceof AsyncJobResponse)
-            isAsync = true;
-
-        Field[] fields = getFlattenFields(obj.getClass());
-        for (Field field : fields) {
-            if ((field.getModifiers() & Modifier.TRANSIENT) != 0) {
-                continue; // skip transient fields
-            }
-
-            SerializedName serializedName = field.getAnnotation(SerializedName.class);
-            if (serializedName == null) {
-                continue; // skip fields w/o serialized name
-            }
-
-            boolean logField = true;
-            Param param = field.getAnnotation(Param.class);
-            if (param != null) {
-                RoleType[] allowedRoles = param.authorized();
-                if (allowedRoles.length > 0) {
-                    boolean permittedParameter = false;
-                    Account caller = CallContext.current().getCallingAccount();
-                    for (RoleType allowedRole : allowedRoles) {
-                        if (allowedRole.getAccountType() == caller.getType()) {
-                            permittedParameter = true;
-                            break;
-                        }
-                    }
-                    if (!permittedParameter) {
-                        s_logger.trace("Ignoring parameter " + param.name() + " as the caller is not authorized to see it");
-                        continue;
-                    }
-                }
-                if (param.isSensitive()) {
-                    logField = false;
-                }
-            }
-
-            field.setAccessible(true);
-            Object fieldValue = null;
-            try {
-                fieldValue = field.get(obj);
-            } catch (IllegalArgumentException e) {
-                throw new CloudRuntimeException("how illegal is it?", e);
-            } catch (IllegalAccessException e) {
-                throw new CloudRuntimeException("come on...we set accessible already", e);
-            }
-            if (fieldValue != null) {
-                if (fieldValue instanceof ResponseObject) {
-                    ResponseObject subObj = (ResponseObject)fieldValue;
-                    if (isAsync) {
-                        sb.append("<jobresult>");
-                        log.append("<jobresult>");
-                    }
-                    serializeResponseObjXML(sb, log, subObj);
-                    if (isAsync) {
-                        sb.append("</jobresult>");
-                        log.append("</jobresult>");
-                    }
-                } else if (fieldValue instanceof Collection<?>) {
-                    Collection<?> subResponseList = (Collection<?>)fieldValue;
-                    boolean usedUuidList = false;
-                    for (Object value : subResponseList) {
-                        if (value instanceof ResponseObject) {
-                            ResponseObject subObj = (ResponseObject)value;
-                            if (serializedName != null) {
-                                subObj.setObjectName(serializedName.value());
-                            }
-                            serializeResponseObjXML(sb, log, subObj);
-                        } else if (value instanceof ExceptionProxyObject) {
-                            // Only exception reponses carry a list of
-                            // ExceptionProxyObject objects.
-                            ExceptionProxyObject idProxy = (ExceptionProxyObject)value;
-                            // If this is the first IdentityProxy field
-                            // encountered, put in a uuidList tag.
-                            if (!usedUuidList) {
-                                sb.append("<" + serializedName.value() + ">");
-                                log.append("<" + serializedName.value() + ">");
-                                usedUuidList = true;
-                            }
-                            sb.append("<" + "uuid" + ">" + idProxy.getUuid() + "</" + "uuid" + ">");
-                            log.append("<" + "uuid" + ">" + idProxy.getUuid() + "</" + "uuid" + ">");
-                            // Append the new descriptive property also.
-                            String idFieldName = idProxy.getDescription();
-                            if (idFieldName != null) {
-                                sb.append("<" + "uuidProperty" + ">" + idFieldName + "</" + "uuidProperty" + ">");
-                                log.append("<" + "uuidProperty" + ">" + idFieldName + "</" + "uuidProperty" + ">");
-                            }
-                        } else if (value instanceof String) {
-                            sb.append("<").append(serializedName.value()).append(">").append(value).append("</").append(serializedName.value()).append(">");
-                            if (logField) {
-                                log.append("<").append(serializedName.value()).append(">").append(value).append("</").append(serializedName.value()).append(">");
-                            }
-                        }
-                    }
-                    if (usedUuidList) {
-                        // close the uuidList.
-                        sb.append("</").append(serializedName.value()).append(">");
-                        log.append("</").append(serializedName.value()).append(">");
-                    }
-                } else if (fieldValue instanceof Date) {
-                    sb.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append("</").append(serializedName.value()).append(">");
-                    log.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append("</").append(serializedName.value()).append(">");
-                } else {
-                    String resultString = escapeSpecialXmlChars(fieldValue.toString());
-                    if (!(obj instanceof ExceptionResponse)) {
-                        resultString = encodeParam(resultString);
-                    }
-
-                    sb.append("<").append(serializedName.value()).append(">").append(resultString).append("</").append(serializedName.value()).append(">");
-                    if (logField) {
-                        log.append("<").append(serializedName.value()).append(">").append(resultString).append("</").append(serializedName.value()).append(">");
-                    }
-                }
-            }
-        }
-    }
-
-    private static String escapeSpecialXmlChars(String originalString) {
-        char[] origChars = originalString.toCharArray();
-        StringBuilder resultString = new StringBuilder();
-
-        for (char singleChar : origChars) {
-            if (singleChar == '"') {
-                resultString.append("&quot;");
-            } else if (singleChar == '\'') {
-                resultString.append("&apos;");
-            } else if (singleChar == '<') {
-                resultString.append("&lt;");
-            } else if (singleChar == '>') {
-                resultString.append("&gt;");
-            } else if (singleChar == '&') {
-                resultString.append("&amp;");
-            } else {
-                resultString.append(singleChar);
-            }
-        }
-
-        return resultString.toString();
-    }
-
-    private static String encodeParam(String value) {
-        if (!ApiServer.isEncodeApiResponse()) {
-            return value;
-        }
-        try {
-            return new URLEncoder().encode(value).replaceAll("\\+", "%20");
-        } catch (Exception e) {
-            s_logger.warn("Unable to encode: " + value, e);
-        }
-        return value;
-    }
-
-}
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
deleted file mode 100644
index a9042a7..0000000
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ /dev/null
@@ -1,1148 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.capacity;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.deploy.DeploymentClusterPlanner;
-import com.cloud.event.UsageEventVO;
-import com.cloud.exception.ConnectionException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.resource.ResourceListener;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.resource.ServerResource;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.UserVmDetailVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-public class CapacityManagerImpl extends ManagerBase implements CapacityManager, StateListener<State, VirtualMachine.Event, VirtualMachine>, Listener, ResourceListener,
-        Configurable {
-    private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class);
-    @Inject
-    CapacityDao _capacityDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ServiceOfferingDao _offeringsDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    VMInstanceDao _vmDao;
-    @Inject
-    VolumeDao _volumeDao;
-    @Inject
-    VMTemplatePoolDao _templatePoolDao;
-    @Inject
-    AgentManager _agentManager;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    StorageManager _storageMgr;
-    @Inject
-    HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject
-    protected VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    protected UserVmDao _userVMDao;
-    @Inject
-    protected UserVmDetailsDao _userVmDetailsDao;
-    @Inject
-    ClusterDao _clusterDao;
-    @Inject
-    DataStoreProviderManager _dataStoreProviderMgr;
-
-    @Inject
-    ClusterDetailsDao _clusterDetailsDao;
-    private int _vmCapacityReleaseInterval;
-    long _extraBytesPerVolume = 0;
-
-    @Inject
-    MessageBus _messageBus;
-
-    private static final String MESSAGE_RESERVED_CAPACITY_FREED_FLAG = "Message.ReservedCapacityFreed.Flag";
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
-
-        VirtualMachine.State.getStateMachine().registerListener(this);
-        _agentManager.registerForHostEvents(new StorageCapacityListener(_capacityDao, _storageMgr), true, false, false);
-        _agentManager.registerForHostEvents(new ComputeCapacityListener(_capacityDao, this), true, false, false);
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        _resourceMgr.registerResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, this);
-        _resourceMgr.registerResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, this);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @DB
-    @Override
-    public boolean releaseVmCapacity(VirtualMachine vm, final boolean moveFromReserved, final boolean moveToReservered, final Long hostId) {
-        if (hostId == null) {
-            return true;
-        }
-
-        final ServiceOfferingVO svo = _offeringsDao.findById(vm.getId(), vm.getServiceOfferingId());
-        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
-        CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
-        Long clusterId = null;
-        if (hostId != null) {
-            HostVO host = _hostDao.findById(hostId);
-            if (host == null) {
-                s_logger.warn("Host " + hostId + " no long exist anymore!");
-                return true;
-            }
-
-            clusterId = host.getClusterId();
-        }
-        if (capacityCpu == null || capacityMemory == null || svo == null) {
-            return false;
-        }
-
-        try {
-            final Long clusterIdFinal = clusterId;
-            final long capacityCpuId = capacityCpu.getId();
-            final long capacityMemoryId = capacityMemory.getId();
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true);
-                    CapacityVO capacityMemory = _capacityDao.lockRow(capacityMemoryId, true);
-
-                    long usedCpu = capacityCpu.getUsedCapacity();
-                    long usedMem = capacityMemory.getUsedCapacity();
-                    long reservedCpu = capacityCpu.getReservedCapacity();
-                    long reservedMem = capacityMemory.getReservedCapacity();
-                    long actualTotalCpu = capacityCpu.getTotalCapacity();
-                    float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal, "cpuOvercommitRatio").getValue());
-                    float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal, "memoryOvercommitRatio").getValue());
-                    int vmCPU = svo.getCpu() * svo.getSpeed();
-                    long vmMem = svo.getRamSize() * 1024L * 1024L;
-                    long actualTotalMem = capacityMemory.getTotalCapacity();
-                    long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
-                    long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
-                        s_logger.debug("Hosts's actual total RAM: " + actualTotalMem + " and RAM after applying overprovisioning: " + totalMem);
-                    }
-
-                    if (!moveFromReserved) {
-                        /* move resource from used */
-                        if (usedCpu >= vmCPU) {
-                            capacityCpu.setUsedCapacity(usedCpu - vmCPU);
-                        }
-                        if (usedMem >= vmMem) {
-                            capacityMemory.setUsedCapacity(usedMem - vmMem);
-                        }
-
-                        if (moveToReservered) {
-                            if (reservedCpu + vmCPU <= totalCpu) {
-                                capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
-                            }
-                            if (reservedMem + vmMem <= totalMem) {
-                                capacityMemory.setReservedCapacity(reservedMem + vmMem);
-                            }
-                        }
-                    } else {
-                        if (reservedCpu >= vmCPU) {
-                            capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
-                        }
-                        if (reservedMem >= vmMem) {
-                            capacityMemory.setReservedCapacity(reservedMem - vmMem);
-                        }
-                    }
-
-                    s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", actual total: " + actualTotalCpu +
-                        ", total with overprovisioning: " + totalCpu + "; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + capacityCpu.getReservedCapacity() +
-                        "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
-
-                    s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem + "; new used: " +
-                        capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() + "; movedfromreserved: " + moveFromReserved +
-                        ",moveToReservered" + moveToReservered);
-
-                    _capacityDao.update(capacityCpu.getId(), capacityCpu);
-                    _capacityDao.update(capacityMemory.getId(), capacityMemory);
-                }
-            });
-
-            return true;
-        } catch (Exception e) {
-            s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
-            return false;
-        }
-    }
-
-    @DB
-    @Override
-    public void allocateVmCapacity(VirtualMachine vm, final boolean fromLastHost) {
-
-        final long hostId = vm.getHostId();
-        HostVO host = _hostDao.findById(hostId);
-        final long clusterId = host.getClusterId();
-        final float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue());
-        final float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue());
-
-        final ServiceOfferingVO svo = _offeringsDao.findById(vm.getId(), vm.getServiceOfferingId());
-
-        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
-        CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
-
-        if (capacityCpu == null || capacityMem == null || svo == null) {
-            return;
-        }
-
-        final int cpu = svo.getCpu() * svo.getSpeed();
-        final long ram = svo.getRamSize() * 1024L * 1024L;
-
-        try {
-            final long capacityCpuId = capacityCpu.getId();
-            final long capacityMemId = capacityMem.getId();
-
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true);
-                    CapacityVO capacityMem = _capacityDao.lockRow(capacityMemId, true);
-
-                    long usedCpu = capacityCpu.getUsedCapacity();
-                    long usedMem = capacityMem.getUsedCapacity();
-                    long reservedCpu = capacityCpu.getReservedCapacity();
-                    long reservedMem = capacityMem.getReservedCapacity();
-                    long actualTotalCpu = capacityCpu.getTotalCapacity();
-                    long actualTotalMem = capacityMem.getTotalCapacity();
-                    long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
-                    long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
-                    }
-
-                    long freeCpu = totalCpu - (reservedCpu + usedCpu);
-                    long freeMem = totalMem - (reservedMem + usedMem);
-
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("We are allocating VM, increasing the used capacity of this host:" + hostId);
-                        s_logger.debug("Current Used CPU: " + usedCpu + " , Free CPU:" + freeCpu + " ,Requested CPU: " + cpu);
-                        s_logger.debug("Current Used RAM: " + usedMem + " , Free RAM:" + freeMem + " ,Requested RAM: " + ram);
-                    }
-                    capacityCpu.setUsedCapacity(usedCpu + cpu);
-                    capacityMem.setUsedCapacity(usedMem + ram);
-
-                    if (fromLastHost) {
-                        /* alloc from reserved */
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required");
-                            s_logger.debug("Reserved CPU: " + reservedCpu + " , Requested CPU: " + cpu);
-                            s_logger.debug("Reserved RAM: " + reservedMem + " , Requested RAM: " + ram);
-                        }
-                        if (reservedCpu >= cpu && reservedMem >= ram) {
-                            capacityCpu.setReservedCapacity(reservedCpu - cpu);
-                            capacityMem.setReservedCapacity(reservedMem - ram);
-                        }
-                    } else {
-                        /* alloc from free resource */
-                        if (!((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem))) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, " +
-                                    "since the VM is already starting on this host ");
-                            }
-                        }
-                    }
-
-                    s_logger.debug("CPU STATS after allocation: for host: " + hostId + ", old used: " + usedCpu + ", old reserved: " + reservedCpu + ", actual total: " +
-                        actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used:" + capacityCpu.getUsedCapacity() + ", reserved:" +
-                        capacityCpu.getReservedCapacity() + "; requested cpu:" + cpu + ",alloc_from_last:" + fromLastHost);
-
-                    s_logger.debug("RAM STATS after allocation: for host: " + hostId + ", old used: " + usedMem + ", old reserved: " + reservedMem + ", total: " +
-                        totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " + capacityMem.getReservedCapacity() + "; requested mem: " + ram +
-                        ",alloc_from_last:" + fromLastHost);
-
-                    _capacityDao.update(capacityCpu.getId(), capacityCpu);
-                    _capacityDao.update(capacityMem.getId(), capacityMem);
-                }
-            });
-        } catch (Exception e) {
-            s_logger.error("Exception allocating VM capacity", e);
-            return;
-        }
-    }
-
-    @Override
-    public boolean checkIfHostHasCpuCapability(long hostId, Integer cpuNum, Integer cpuSpeed) {
-
-        // Check host can support the Cpu Number and Speed.
-        Host host = _hostDao.findById(hostId);
-        boolean isCpuNumGood = host.getCpus().intValue() >= cpuNum;
-        boolean isCpuSpeedGood = host.getSpeed().intValue() >= cpuSpeed;
-        if (isCpuNumGood && isCpuSpeedGood) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host: " + hostId + " has cpu capability (cpu:" + host.getCpus() + ", speed:" + host.getSpeed() +
-                    ") to support requested CPU: " + cpuNum + " and requested speed: " + cpuSpeed);
-            }
-            return true;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host: " + hostId + " doesn't have cpu capability (cpu:" + host.getCpus() + ", speed:" + host.getSpeed() +
-                    ") to support requested CPU: " + cpuNum + " and requested speed: " + cpuSpeed);
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOvercommitRatio, float memoryOvercommitRatio,
-        boolean considerReservedCapacity) {
-        boolean hasCapacity = false;
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Checking if host: " + hostId + " has enough capacity for requested CPU: " + cpu + " and requested RAM: " + ram +
-                " , cpuOverprovisioningFactor: " + cpuOvercommitRatio);
-        }
-
-        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
-        CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
-
-        if (capacityCpu == null || capacityMem == null) {
-            if (capacityCpu == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for CPU not found in Db, for hostId: " + hostId);
-                }
-            }
-            if (capacityMem == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for RAM not found in Db, for hostId: " + hostId);
-                }
-            }
-
-            return false;
-        }
-
-        long usedCpu = capacityCpu.getUsedCapacity();
-        long usedMem = capacityMem.getUsedCapacity();
-        long reservedCpu = capacityCpu.getReservedCapacity();
-        long reservedMem = capacityMem.getReservedCapacity();
-        long actualTotalCpu = capacityCpu.getTotalCapacity();
-        long actualTotalMem = capacityMem.getTotalCapacity();
-        long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
-        long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
-        }
-
-        String failureReason = "";
-        if (checkFromReservedCapacity) {
-            long freeCpu = reservedCpu;
-            long freeMem = reservedMem;
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("We need to allocate to the last host again, so checking if there is enough reserved capacity");
-                s_logger.debug("Reserved CPU: " + freeCpu + " , Requested CPU: " + cpu);
-                s_logger.debug("Reserved RAM: " + freeMem + " , Requested RAM: " + ram);
-            }
-            /* alloc from reserved */
-            if (reservedCpu >= cpu) {
-                if (reservedMem >= ram) {
-                    hasCapacity = true;
-                } else {
-                    failureReason = "Host does not have enough reserved RAM available";
-                }
-            } else {
-                failureReason = "Host does not have enough reserved CPU available";
-            }
-        } else {
-
-            long reservedCpuValueToUse = reservedCpu;
-            long reservedMemValueToUse = reservedMem;
-
-            if (!considerReservedCapacity) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("considerReservedCapacity is" + considerReservedCapacity + " , not considering reserved capacity for calculating free capacity");
-                }
-                reservedCpuValueToUse = 0;
-                reservedMemValueToUse = 0;
-            }
-            long freeCpu = totalCpu - (reservedCpuValueToUse + usedCpu);
-            long freeMem = totalMem - (reservedMemValueToUse + usedMem);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Free CPU: " + freeCpu + " , Requested CPU: " + cpu);
-                s_logger.debug("Free RAM: " + freeMem + " , Requested RAM: " + ram);
-            }
-            /* alloc from free resource */
-            if ((reservedCpuValueToUse + usedCpu + cpu <= totalCpu)) {
-                if ((reservedMemValueToUse + usedMem + ram <= totalMem)) {
-                    hasCapacity = true;
-                } else {
-                    failureReason = "Host does not have enough RAM available";
-                }
-            } else {
-                failureReason = "Host does not have enough CPU available";
-            }
-        }
-
-        if (hasCapacity) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host has enough CPU and RAM available");
-            }
-
-            s_logger.debug("STATS: Can alloc CPU from host: " + hostId + ", used: " + usedCpu + ", reserved: " + reservedCpu + ", actual total: " + actualTotalCpu +
-                ", total with overprovisioning: " + totalCpu + "; requested cpu:" + cpu + ",alloc_from_last_host?:" + checkFromReservedCapacity +
-                " ,considerReservedCapacity?: " + considerReservedCapacity);
-
-            s_logger.debug("STATS: Can alloc MEM from host: " + hostId + ", used: " + usedMem + ", reserved: " + reservedMem + ", total: " + totalMem +
-                "; requested mem: " + ram + ",alloc_from_last_host?:" + checkFromReservedCapacity + " ,considerReservedCapacity?: " + considerReservedCapacity);
-        } else {
-
-            if (checkFromReservedCapacity) {
-                s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", requested cpu: " + cpu + ", reservedMem: " +
-                    reservedMem + ", requested mem: " + ram);
-            } else {
-                s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", used cpu: " + usedCpu + ", requested cpu: " +
-                    cpu + ", actual total cpu: " + actualTotalCpu + ", total cpu with overprovisioning: " + totalCpu + ", reservedMem: " + reservedMem + ", used Mem: " +
-                    usedMem + ", requested mem: " + ram + ", total Mem:" + totalMem + " ,considerReservedCapacity?: " + considerReservedCapacity);
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(failureReason + ", cannot allocate to this host.");
-            }
-        }
-
-        return hasCapacity;
-
-    }
-
-    @Override
-    public long getUsedBytes(StoragePoolVO pool) {
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
-        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
-
-        if (storeDriver instanceof PrimaryDataStoreDriver) {
-            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
-
-            return primaryStoreDriver.getUsedBytes(pool);
-        }
-
-        throw new CloudRuntimeException("Storage driver in CapacityManagerImpl.getUsedBytes(StoragePoolVO) is not a PrimaryDataStoreDriver.");
-    }
-
-    @Override
-    public long getUsedIops(StoragePoolVO pool) {
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
-        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
-
-        if (storeDriver instanceof PrimaryDataStoreDriver) {
-            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
-
-            return primaryStoreDriver.getUsedIops(pool);
-        }
-
-        throw new CloudRuntimeException("Storage driver in CapacityManagerImpl.getUsedIops(StoragePoolVO) is not a PrimaryDataStoreDriver.");
-    }
-
-    @Override
-    public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation) {
-        long totalAllocatedSize = 0;
-
-        // if the storage pool is managed, the used bytes can be larger than the sum of the sizes of all of the non-destroyed volumes
-        // in this case, call getUsedBytes(StoragePoolVO)
-        if (pool.isManaged()) {
-            return getUsedBytes(pool);
-        }
-        else {
-            // Get size for all the non-destroyed volumes.
-            Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
-
-            totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
-        }
-
-        // Get size for VM Snapshots.
-        totalAllocatedSize += _volumeDao.getVMSnapshotSizeByPool(pool.getId());
-
-        boolean tmpInstalled = false;
-        // Iterate through all templates on this storage pool.
-        List<VMTemplateStoragePoolVO> templatePoolVOs = _templatePoolDao.listByPoolId(pool.getId());
-
-        for (VMTemplateStoragePoolVO templatePoolVO : templatePoolVOs) {
-            if ((templateForVmCreation != null) && !tmpInstalled && (templatePoolVO.getTemplateId() == templateForVmCreation.getId())) {
-                tmpInstalled = true;
-            }
-
-            long templateSize = templatePoolVO.getTemplateSize();
-
-            totalAllocatedSize += templateSize + _extraBytesPerVolume;
-        }
-
-        if ((templateForVmCreation != null) && !tmpInstalled) {
-            long templateForVmCreationSize = templateForVmCreation.getSize() != null ? templateForVmCreation.getSize() : 0;
-
-            totalAllocatedSize += templateForVmCreationSize + _extraBytesPerVolume;
-        }
-
-        return totalAllocatedSize;
-    }
-
-    @DB
-    @Override
-    public void updateCapacityForHost(final Host host) {
-        // prepare the service offerings
-        List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
-        Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
-        for (ServiceOfferingVO offering : offerings) {
-            offeringsMap.put(offering.getId(), offering);
-        }
-
-        long usedCpuCore = 0;
-        long reservedCpuCore = 0;
-        long usedCpu = 0;
-        long usedMemory = 0;
-        long reservedMemory = 0;
-        long reservedCpu = 0;
-        final CapacityState capacityState = (host.getResourceState() == ResourceState.Enabled) ? CapacityState.Enabled : CapacityState.Disabled;
-
-        List<VMInstanceVO> vms = _vmDao.listUpByHostId(host.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Found " + vms.size() + " VMs on host " + host.getId());
-        }
-
-        ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-        ClusterDetailsVO clusterDetailCpu = _clusterDetailsDao.findDetail(cluster.getId(), "cpuOvercommitRatio");
-        ClusterDetailsVO clusterDetailRam = _clusterDetailsDao.findDetail(cluster.getId(), "memoryOvercommitRatio");
-        Float clusterCpuOvercommitRatio = Float.parseFloat(clusterDetailCpu.getValue());
-        Float clusterRamOvercommitRatio = Float.parseFloat(clusterDetailRam.getValue());
-        for (VMInstanceVO vm : vms) {
-            Float cpuOvercommitRatio = 1.0f;
-            Float ramOvercommitRatio = 1.0f;
-            Map<String, String> vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
-            String vmDetailCpu = vmDetails.get("cpuOvercommitRatio");
-            String vmDetailRam = vmDetails.get("memoryOvercommitRatio");
-            if (vmDetailCpu != null) {
-                //if vmDetail_cpu is not null it means it is running in a overcommited cluster.
-                cpuOvercommitRatio = Float.parseFloat(vmDetailCpu);
-                ramOvercommitRatio = Float.parseFloat(vmDetailRam);
-            }
-            ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
-            if (so.isDynamic()) {
-                usedMemory +=
-                    ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L) / ramOvercommitRatio) *
-                        clusterRamOvercommitRatio;
-                usedCpu +=
-                    ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
-                        clusterCpuOvercommitRatio;
-                usedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
-            } else {
-                usedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
-                usedCpu += ((so.getCpu() * so.getSpeed()) / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
-                usedCpuCore += so.getCpu();
-            }
-        }
-
-        List<VMInstanceVO> vmsByLastHostId = _vmDao.listByLastHostId(host.getId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Found " + vmsByLastHostId.size() + " VM, not running on host " + host.getId());
-        }
-        for (VMInstanceVO vm : vmsByLastHostId) {
-            Float cpuOvercommitRatio = 1.0f;
-            Float ramOvercommitRatio = 1.0f;
-            long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime()) / 1000;
-            if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
-                UserVmDetailVO vmDetailCpu = _userVmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio");
-                UserVmDetailVO vmDetailRam = _userVmDetailsDao.findDetail(vm.getId(), "memoryOvercommitRatio");
-                if (vmDetailCpu != null) {
-                    //if vmDetail_cpu is not null it means it is running in a overcommited cluster.
-                    cpuOvercommitRatio = Float.parseFloat(vmDetailCpu.getValue());
-                    ramOvercommitRatio = Float.parseFloat(vmDetailRam.getValue());
-                }
-                ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
-                Map<String, String> vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
-                if (so.isDynamic()) {
-                    reservedMemory +=
-                        ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L) / ramOvercommitRatio) *
-                            clusterRamOvercommitRatio;
-                    reservedCpu +=
-                        ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
-                            clusterCpuOvercommitRatio;
-                    reservedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
-                } else {
-                    reservedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
-                    reservedCpu += (so.getCpu() * so.getSpeed() / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
-                    reservedCpuCore += so.getCpu();
-                }
-            } else {
-                // signal if not done already, that the VM has been stopped for skip.counting.hours,
-                // hence capacity will not be reserved anymore.
-                UserVmDetailVO messageSentFlag = _userVmDetailsDao.findDetail(vm.getId(), MESSAGE_RESERVED_CAPACITY_FREED_FLAG);
-                if (messageSentFlag == null || !Boolean.valueOf(messageSentFlag.getValue())) {
-                    _messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
-
-                    if (vm.getType() == VirtualMachine.Type.User) {
-                        UserVmVO userVM = _userVMDao.findById(vm.getId());
-                        _userVMDao.loadDetails(userVM);
-                        userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "true");
-                        _userVMDao.saveDetails(userVM);
-                    }
-                }
-            }
-        }
-
-        CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU);
-        CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
-        CapacityVO cpuCoreCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU_CORE);
-
-        if (cpuCoreCap != null) {
-            long hostTotalCpuCore = host.getCpus().longValue();
-
-            if (cpuCoreCap.getTotalCapacity() != hostTotalCpuCore) {
-                s_logger.debug("Calibrate total cpu for host: " + host.getId() + " old total CPU:"
-                        + cpuCoreCap.getTotalCapacity() + " new total CPU:" + hostTotalCpuCore);
-                cpuCoreCap.setTotalCapacity(hostTotalCpuCore);
-
-            }
-
-            if (cpuCoreCap.getUsedCapacity() == usedCpuCore && cpuCoreCap.getReservedCapacity() == reservedCpuCore) {
-                s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpuCore: " + cpuCoreCap.getUsedCapacity()
-                        + " reservedCpuCore: " + cpuCoreCap.getReservedCapacity());
-            } else {
-                if (cpuCoreCap.getReservedCapacity() != reservedCpuCore) {
-                    s_logger.debug("Calibrate reserved cpu core for host: " + host.getId() + " old reservedCpuCore:"
-                            + cpuCoreCap.getReservedCapacity() + " new reservedCpuCore:" + reservedCpuCore);
-                    cpuCoreCap.setReservedCapacity(reservedCpuCore);
-                }
-                if (cpuCoreCap.getUsedCapacity() != usedCpuCore) {
-                    s_logger.debug("Calibrate used cpu core for host: " + host.getId() + " old usedCpuCore:"
-                            + cpuCoreCap.getUsedCapacity() + " new usedCpuCore:" + usedCpuCore);
-                    cpuCoreCap.setUsedCapacity(usedCpuCore);
-                }
-            }
-            try {
-                _capacityDao.update(cpuCoreCap.getId(), cpuCoreCap);
-            } catch (Exception e) {
-                s_logger.error("Caught exception while updating cpucore capacity for the host " +host.getId(), e);
-            }
-        } else {
-            final long usedCpuCoreFinal = usedCpuCore;
-            final long reservedCpuCoreFinal = reservedCpuCore;
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    CapacityVO capacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedCpuCoreFinal, host.getCpus().longValue(),
-                            CapacityVO.CAPACITY_TYPE_CPU_CORE);
-                    capacity.setReservedCapacity(reservedCpuCoreFinal);
-                    capacity.setCapacityState(capacityState);
-                    _capacityDao.persist(capacity);
-                }
-            });
-        }
-
-        if (cpuCap != null && memCap != null) {
-            if (host.getTotalMemory() != null) {
-                memCap.setTotalCapacity(host.getTotalMemory());
-            }
-            long hostTotalCpu = host.getCpus().longValue() * host.getSpeed().longValue();
-
-            if (cpuCap.getTotalCapacity() != hostTotalCpu) {
-                s_logger.debug("Calibrate total cpu for host: " + host.getId() + " old total CPU:" + cpuCap.getTotalCapacity() + " new total CPU:" + hostTotalCpu);
-                cpuCap.setTotalCapacity(hostTotalCpu);
-
-            }
-            // Set the capacity state as per the host allocation state.
-            if(capacityState != cpuCap.getCapacityState()){
-                s_logger.debug("Calibrate cpu capacity state for host: " + host.getId() + " old capacity state:" + cpuCap.getTotalCapacity() + " new capacity state:" + hostTotalCpu);
-                cpuCap.setCapacityState(capacityState);
-            }
-            memCap.setCapacityState(capacityState);
-
-            if (cpuCap.getUsedCapacity() == usedCpu && cpuCap.getReservedCapacity() == reservedCpu) {
-                s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpu: " + cpuCap.getUsedCapacity() + " reservedCpu: " +
-                    cpuCap.getReservedCapacity());
-            } else {
-                if (cpuCap.getReservedCapacity() != reservedCpu) {
-                    s_logger.debug("Calibrate reserved cpu for host: " + host.getId() + " old reservedCpu:" + cpuCap.getReservedCapacity() + " new reservedCpu:" +
-                        reservedCpu);
-                    cpuCap.setReservedCapacity(reservedCpu);
-                }
-                if (cpuCap.getUsedCapacity() != usedCpu) {
-                    s_logger.debug("Calibrate used cpu for host: " + host.getId() + " old usedCpu:" + cpuCap.getUsedCapacity() + " new usedCpu:" + usedCpu);
-                    cpuCap.setUsedCapacity(usedCpu);
-                }
-            }
-
-            if (memCap.getTotalCapacity() != host.getTotalMemory()) {
-                s_logger.debug("Calibrate total memory for host: " + host.getId() + " old total memory:" + memCap.getTotalCapacity() + " new total memory:" +
-                    host.getTotalMemory());
-                memCap.setTotalCapacity(host.getTotalMemory());
-
-            }
-            // Set the capacity state as per the host allocation state.
-            if(capacityState != memCap.getCapacityState()){
-                s_logger.debug("Calibrate memory capacity state for host: " + host.getId() + " old capacity state:" + memCap.getTotalCapacity() + " new capacity state:" + hostTotalCpu);
-                memCap.setCapacityState(capacityState);
-            }
-
-            if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) {
-                s_logger.debug("No need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " +
-                    memCap.getReservedCapacity());
-            } else {
-                if (memCap.getReservedCapacity() != reservedMemory) {
-                    s_logger.debug("Calibrate reserved memory for host: " + host.getId() + " old reservedMem:" + memCap.getReservedCapacity() + " new reservedMem:" +
-                        reservedMemory);
-                    memCap.setReservedCapacity(reservedMemory);
-                }
-                if (memCap.getUsedCapacity() != usedMemory) {
-                    /*
-                     * Didn't calibrate for used memory, because VMs can be in
-                     * state(starting/migrating) that I don't know on which host
-                     * they are allocated
-                     */
-                    s_logger.debug("Calibrate used memory for host: " + host.getId() + " old usedMem: " + memCap.getUsedCapacity() + " new usedMem: " + usedMemory);
-                    memCap.setUsedCapacity(usedMemory);
-                }
-            }
-
-            try {
-                _capacityDao.update(cpuCap.getId(), cpuCap);
-                _capacityDao.update(memCap.getId(), memCap);
-            } catch (Exception e) {
-                s_logger.error("Caught exception while updating cpu/memory capacity for the host " + host.getId(), e);
-            }
-        } else {
-            final long usedMemoryFinal = usedMemory;
-            final long reservedMemoryFinal = reservedMemory;
-            final long usedCpuFinal = usedCpu;
-            final long reservedCpuFinal = reservedCpu;
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    CapacityVO capacity =
-                        new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedMemoryFinal, host.getTotalMemory(),
-                            Capacity.CAPACITY_TYPE_MEMORY);
-                    capacity.setReservedCapacity(reservedMemoryFinal);
-                    capacity.setCapacityState(capacityState);
-                    _capacityDao.persist(capacity);
-
-                    capacity =
-                        new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedCpuFinal, host.getCpus().longValue() *
-                            host.getSpeed().longValue(), Capacity.CAPACITY_TYPE_CPU);
-                    capacity.setReservedCapacity(reservedCpuFinal);
-                    capacity.setCapacityState(capacityState);
-                    _capacityDao.persist(capacity);
-                }
-            });
-
-        }
-
-    }
-
-    @Override
-    public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean transitionStatus, Object opaque) {
-        return true;
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
-      if (!status) {
-        return false;
-      }
-      @SuppressWarnings("unchecked")
-      Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
-      Long oldHostId = hosts.first();
-
-      State oldState = transition.getCurrentState();
-      State newState = transition.getToState();
-      Event event = transition.getEvent();
-      s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
-              " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
-
-      if (oldState == State.Starting) {
-        if (newState != State.Running) {
-          releaseVmCapacity(vm, false, false, oldHostId);
-        }
-      } else if (oldState == State.Running) {
-        if (event == Event.AgentReportStopped) {
-          releaseVmCapacity(vm, false, true, oldHostId);
-        } else if (event == Event.AgentReportMigrated) {
-          releaseVmCapacity(vm, false, false, oldHostId);
-        }
-      } else if (oldState == State.Migrating) {
-        if (event == Event.AgentReportStopped) {
-                /* Release capacity from original host */
-          releaseVmCapacity(vm, false, false, vm.getLastHostId());
-          releaseVmCapacity(vm, false, false, oldHostId);
-        } else if (event == Event.OperationFailed) {
-                /* Release from dest host */
-          releaseVmCapacity(vm, false, false, oldHostId);
-        } else if (event == Event.OperationSucceeded) {
-          releaseVmCapacity(vm, false, false, vm.getLastHostId());
-        }
-      } else if (oldState == State.Stopping) {
-        if (event == Event.OperationSucceeded) {
-          releaseVmCapacity(vm, false, true, oldHostId);
-        } else if (event == Event.AgentReportStopped) {
-          releaseVmCapacity(vm, false, false, oldHostId);
-        } else if (event == Event.AgentReportMigrated) {
-          releaseVmCapacity(vm, false, false, oldHostId);
-        }
-      } else if (oldState == State.Stopped) {
-        if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
-          releaseVmCapacity(vm, true, false, vm.getLastHostId());
-        } else if (event == Event.AgentReportMigrated) {
-          releaseVmCapacity(vm, false, false, oldHostId);
-        }
-      }
-
-      if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
-        boolean fromLastHost = false;
-        if (vm.getHostId().equals(vm.getLastHostId())) {
-          s_logger.debug("VM starting again on the last host it was stopped on");
-          fromLastHost = true;
-        }
-        allocateVmCapacity(vm, fromLastHost);
-      }
-
-      if (newState == State.Stopped) {
-        if (vm.getType() == VirtualMachine.Type.User) {
-
-          UserVmVO userVM = _userVMDao.findById(vm.getId());
-          _userVMDao.loadDetails(userVM);
-          // free the message sent flag if it exists
-          userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
-          _userVMDao.saveDetails(userVM);
-
-        }
-      }
-
-      return true;
-    }
-
-  // TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
-    // create capacity entries if none exist for this server
-    private void createCapacityEntry(StartupCommand startup, HostVO server) {
-        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
-        capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
-        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
-        capacitySC.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
-
-        if (startup instanceof StartupRoutingCommand) {
-            SearchCriteria<CapacityVO> capacityCPU = _capacityDao.createSearchCriteria();
-            capacityCPU.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
-            capacityCPU.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
-            capacityCPU.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
-            capacityCPU.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_CPU);
-            List<CapacityVO> capacityVOCpus = _capacityDao.search(capacitySC, null);
-            Float cpuovercommitratio = Float.parseFloat(_clusterDetailsDao.findDetail(server.getClusterId(), "cpuOvercommitRatio").getValue());
-            Float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(server.getClusterId(), "memoryOvercommitRatio").getValue());
-
-            if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
-                CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
-                long newTotalCpu = (long)(server.getCpus().longValue() * server.getSpeed().longValue() * cpuovercommitratio);
-                if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu) || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity()) <= newTotalCpu)) {
-                    CapacityVOCpu.setTotalCapacity(newTotalCpu);
-                } else if ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu) && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
-                    CapacityVOCpu.setReservedCapacity(0);
-                    CapacityVOCpu.setTotalCapacity(newTotalCpu);
-                } else {
-                    s_logger.debug("What? new cpu is :" + newTotalCpu + ", old one is " + CapacityVOCpu.getUsedCapacity() + "," + CapacityVOCpu.getReservedCapacity() +
-                        "," + CapacityVOCpu.getTotalCapacity());
-                }
-                _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu);
-            } else {
-                CapacityVO capacity =
-                    new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getCpus().longValue() *
-                        server.getSpeed().longValue(), Capacity.CAPACITY_TYPE_CPU);
-                _capacityDao.persist(capacity);
-            }
-
-            SearchCriteria<CapacityVO> capacityMem = _capacityDao.createSearchCriteria();
-            capacityMem.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
-            capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
-            capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
-            capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_MEMORY);
-            List<CapacityVO> capacityVOMems = _capacityDao.search(capacityMem, null);
-
-            if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
-                CapacityVO CapacityVOMem = capacityVOMems.get(0);
-                long newTotalMem = (long)((server.getTotalMemory()) * memoryOvercommitRatio);
-                if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
-                    CapacityVOMem.setTotalCapacity(newTotalMem);
-                } else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
-                    CapacityVOMem.setReservedCapacity(0);
-                    CapacityVOMem.setTotalCapacity(newTotalMem);
-                } else {
-                    s_logger.debug("What? new cpu is :" + newTotalMem + ", old one is " + CapacityVOMem.getUsedCapacity() + "," + CapacityVOMem.getReservedCapacity() +
-                        "," + CapacityVOMem.getTotalCapacity());
-                }
-                _capacityDao.update(CapacityVOMem.getId(), CapacityVOMem);
-            } else {
-                CapacityVO capacity =
-                    new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getTotalMemory(),
-                        Capacity.CAPACITY_TYPE_MEMORY);
-                _capacityDao.persist(capacity);
-            }
-        }
-
-    }
-
-    @Override
-    public float getClusterOverProvisioningFactor(Long clusterId, short capacityType) {
-
-        String capacityOverProvisioningName = "";
-        if (capacityType == Capacity.CAPACITY_TYPE_CPU) {
-            capacityOverProvisioningName = "cpuOvercommitRatio";
-        } else if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) {
-            capacityOverProvisioningName = "memoryOvercommitRatio";
-        } else {
-            throw new CloudRuntimeException("Invalid capacityType - " + capacityType);
-        }
-
-        ClusterDetailsVO clusterDetailCpu = _clusterDetailsDao.findDetail(clusterId, capacityOverProvisioningName);
-        Float clusterOverProvisioningRatio = Float.parseFloat(clusterDetailCpu.getValue());
-        return clusterOverProvisioningRatio;
-
-    }
-
-    @Override
-    public boolean checkIfClusterCrossesThreshold(Long clusterId, Integer cpuRequested, long ramRequested) {
-
-        Float clusterCpuOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_CPU);
-        Float clusterMemoryOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_MEMORY);
-        Float clusterCpuCapacityDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
-        Float clusterMemoryCapacityDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
-
-        float cpuConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_CPU, cpuRequested);
-        if (cpuConsumption / clusterCpuOverProvisioning > clusterCpuCapacityDisableThreshold) {
-            s_logger.debug("Cluster: " + clusterId + " cpu consumption " + cpuConsumption / clusterCpuOverProvisioning
-                + " crosses disable threshold " + clusterCpuCapacityDisableThreshold);
-            return true;
-        }
-
-        float memoryConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_MEMORY, ramRequested);
-        if (memoryConsumption / clusterMemoryOverProvisioning > clusterMemoryCapacityDisableThreshold) {
-            s_logger.debug("Cluster: " + clusterId + " memory consumption " + memoryConsumption / clusterMemoryOverProvisioning
-                + " crosses disable threshold " + clusterMemoryCapacityDisableThreshold);
-            return true;
-        }
-
-        return false;
-
-    }
-
-    @Override
-    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean processCommands(long agentId, long seq, Command[] commands) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean processDisconnect(long agentId, Status state) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void processHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void processHostRemoved(long hostId, long clusterId) {
-    }
-
-    @Override
-    public boolean isRecurring() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public int getTimeout() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean processTimeout(long agentId, long seq) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void processCancelMaintenaceEventAfter(Long hostId) {
-        updateCapacityForHost(_hostDao.findById(hostId));
-    }
-
-    @Override
-    public void processCancelMaintenaceEventBefore(Long hostId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void processDeletHostEventAfter(Host host) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void processDeleteHostEventBefore(Host host) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void processDiscoverEventAfter(Map<? extends ServerResource, Map<String, String>> resources) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void processDiscoverEventBefore(Long dcid, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void processPrepareMaintenaceEventAfter(Long hostId) {
-        _capacityDao.removeBy(Capacity.CAPACITY_TYPE_MEMORY, null, null, null, hostId);
-        _capacityDao.removeBy(Capacity.CAPACITY_TYPE_CPU, null, null, null, hostId);
-    }
-
-    @Override
-    public void processPrepareMaintenaceEventBefore(Long hostId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean checkIfHostReachMaxGuestLimit(Host host) {
-        Long vmCount = _vmDao.countActiveByHostId(host.getId());
-        HypervisorType hypervisorType = host.getHypervisorType();
-        String hypervisorVersion = host.getHypervisorVersion();
-        Long maxGuestLimit = _hypervisorCapabilitiesDao.getMaxGuestsLimit(hypervisorType, hypervisorVersion);
-        if (vmCount.longValue() >= maxGuestLimit.longValue()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host name: " + host.getName() + ", hostId: " + host.getId() + " already reached max Running VMs(count includes system VMs), limit is: " +
-                    maxGuestLimit + ",Running VM counts is: " + vmCount.longValue());
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return CapacityManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor,
-            StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull, ImageStoreNFSVersion};
-    }
-}
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
deleted file mode 100644
index 098d5d7..0000000
--- a/server/src/com/cloud/configuration/Config.java
+++ /dev/null
@@ -1,2028 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.configuration;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.config.ConfigKey;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.server.ManagementServer;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.template.TemplateManager;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-
-/**
- * @deprecated use the more dynamic ConfigKey
- */
-@Deprecated
-public enum Config {
-
-    // Alert
-
-    AlertEmailAddresses(
-            "Alert",
-            ManagementServer.class,
-            String.class,
-            "alert.email.addresses",
-            null,
-            "Comma separated list of email addresses used for sending alerts.",
-            null),
-    AlertEmailSender("Alert", ManagementServer.class, String.class, "alert.email.sender", null, "Sender of alert email (will be in the From header of the email).", null),
-    AlertSMTPHost("Alert", ManagementServer.class, String.class, "alert.smtp.host", null, "SMTP hostname used for sending out email alerts.", null),
-    AlertSMTPPassword(
-            "Secure",
-            ManagementServer.class,
-            String.class,
-            "alert.smtp.password",
-            null,
-            "Password for SMTP authentication (applies only if alert.smtp.useAuth is true).",
-            null),
-    AlertSMTPPort("Alert", ManagementServer.class, Integer.class, "alert.smtp.port", "465", "Port the SMTP server is listening on.", null),
-    AlertSMTPConnectionTimeout("Alert", ManagementServer.class, Integer.class, "alert.smtp.connectiontimeout", "30000",
-            "Socket connection timeout value in milliseconds. -1 for infinite timeout.", null),
-    AlertSMTPTimeout(
-            "Alert",
-            ManagementServer.class,
-            Integer.class,
-            "alert.smtp.timeout",
-            "30000",
-            "Socket I/O timeout value in milliseconds. -1 for infinite timeout.",
-            null),
-    AlertSMTPUseAuth("Alert", ManagementServer.class, String.class, "alert.smtp.useAuth", null, "If true, use SMTP authentication when sending emails.", null),
-    AlertSMTPUsername(
-            "Alert",
-            ManagementServer.class,
-            String.class,
-            "alert.smtp.username",
-            null,
-            "Username for SMTP authentication (applies only if alert.smtp.useAuth is true).",
-            null),
-    CapacityCheckPeriod("Alert", ManagementServer.class, Integer.class, "capacity.check.period", "300000", "The interval in milliseconds between capacity checks", null),
-    PublicIpCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "zone.virtualnetwork.publicip.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of public IP address space utilization above which alerts will be sent.",
-            null),
-    PrivateIpCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "pod.privateip.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of private IP address space utilization above which alerts will be sent.",
-            null),
-    SecondaryStorageCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "zone.secstorage.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of secondary storage utilization above which alerts will be sent about low storage available.",
-            null),
-    VlanCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "zone.vlan.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of Zone Vlan utilization above which alerts will be sent about low number of Zone Vlans.",
-            null),
-    DirectNetworkPublicIpCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "zone.directnetwork.publicip.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of Direct Network Public Ip Utilization above which alerts will be sent about low number of direct network public ips.",
-            null),
-    LocalStorageCapacityThreshold(
-            "Alert",
-            ManagementServer.class,
-            Float.class,
-            "cluster.localStorage.capacity.notificationthreshold",
-            "0.75",
-            "Percentage (as a value between 0 and 1) of local storage utilization above which alerts will be sent about low local storage available.",
-            null),
-
-    // Storage
-
-    StorageStatsInterval(
-            "Storage",
-            ManagementServer.class,
-            String.class,
-            "storage.stats.interval",
-            "60000",
-            "The interval (in milliseconds) when storage stats (per host) are retrieved from agents.",
-            null),
-    MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null),
-    StorageCacheReplacementLRUTimeInterval(
-            "Storage",
-            ManagementServer.class,
-            Integer.class,
-            "storage.cache.replacement.lru.interval",
-            "30",
-            "time interval for unused data on cache storage (in days).",
-            null),
-    StorageCacheReplacementEnabled(
-            "Storage",
-            ManagementServer.class,
-            Boolean.class,
-            "storage.cache.replacement.enabled",
-            "true",
-            "enable or disable cache storage replacement algorithm.",
-            null),
-    StorageCacheReplacementInterval(
-            "Storage",
-            ManagementServer.class,
-            Integer.class,
-            "storage.cache.replacement.interval",
-            "86400",
-            "time interval between cache replacement threads (in seconds).",
-            null),
-    MaxUploadVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.upload.size", "500", "The maximum size for a uploaded volume(in GB).", null),
-    TotalRetries(
-            "Storage",
-            AgentManager.class,
-            Integer.class,
-            "total.retries",
-            "4",
-            "The number of times each command sent to a host should be retried in case of failure.",
-            null),
-    StoragePoolMaxWaitSeconds(
-            "Storage",
-            ManagementServer.class,
-            Integer.class,
-            "storage.pool.max.waitseconds",
-            "3600",
-            "Timeout (in seconds) to synchronize storage pool operations.",
-            null),
-    PrimaryStorageDownloadWait(
-            "Storage",
-            TemplateManager.class,
-            Integer.class,
-            "primary.storage.download.wait",
-            "10800",
-            "In second, timeout for download template to primary storage",
-            null),
-    CreateVolumeFromSnapshotWait(
-            "Storage",
-            StorageManager.class,
-            Integer.class,
-            "create.volume.from.snapshot.wait",
-            "10800",
-            "In second, timeout for creating volume from snapshot",
-            null),
-    CopyVolumeWait("Storage", StorageManager.class, Integer.class, "copy.volume.wait", "10800", "In second, timeout for copy volume command", null),
-    CreatePrivateTemplateFromVolumeWait(
-            "Storage",
-            UserVmManager.class,
-            Integer.class,
-            "create.private.template.from.volume.wait",
-            "10800",
-            "In second, timeout for CreatePrivateTemplateFromVolumeCommand",
-            null),
-    CreatePrivateTemplateFromSnapshotWait(
-            "Storage",
-            UserVmManager.class,
-            Integer.class,
-            "create.private.template.from.snapshot.wait",
-            "10800",
-            "In second, timeout for CreatePrivateTemplateFromSnapshotCommand",
-            null),
-    BackupSnapshotWait("Storage", StorageManager.class, Integer.class, "backup.snapshot.wait", "21600", "In second, timeout for BackupSnapshotCommand", null),
-    HAStorageMigration(
-            "Storage",
-            ManagementServer.class,
-            Boolean.class,
-            "enable.ha.storage.migration",
-            "true",
-            "Enable/disable storage migration across primary storage during HA",
-            null),
-
-    // Network
-    NetworkLBHaproxyStatsVisbility(
-            "Network",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.haproxy.stats.visibility",
-            "global",
-            "Load Balancer(haproxy) stats visibilty, the value can be one of the following six parameters : global,guest-network,link-local,disabled,all,default",
-            null),
-    NetworkLBHaproxyStatsUri(
-            "Network",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.haproxy.stats.uri",
-            "/admin?stats",
-            "Load Balancer(haproxy) uri.",
-            null),
-    NetworkLBHaproxyStatsAuth(
-            "Secure",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.haproxy.stats.auth",
-            "admin1:AdMiN123",
-            "Load Balancer(haproxy) authetication string in the format username:password",
-            null),
-    NetworkLBHaproxyStatsPort(
-            "Network",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.haproxy.stats.port",
-            "8081",
-            "Load Balancer(haproxy) stats port number.",
-            null),
-    NetworkLBHaproxyMaxConn(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.loadbalancer.haproxy.max.conn",
-            "4096",
-            "Load Balancer(haproxy) maximum number of concurrent connections(global max)",
-            null),
-    NetworkRouterRpFilter(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.disable.rpfilter",
-            "true",
-            "disable rp_filter on Domain Router VM public interfaces.",
-            null),
-
-    GuestVlanBits(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "guest.vlan.bits",
-            "12",
-            "The number of bits to reserve for the VLAN identifier in the guest subnet.",
-            null),
-    //MulticastThrottlingRate("Network", ManagementServer.class, Integer.class, "multicast.throttling.rate", "10", "Default multicast rate in megabits per second allowed.", null),
-    DirectNetworkNoDefaultRoute(
-            "Network",
-            ManagementServer.class,
-            Boolean.class,
-            "direct.network.no.default.route",
-            "false",
-            "Direct Network Dhcp Server should not send a default route",
-            "true/false"),
-    OvsTunnelNetworkDefaultLabel(
-            "Network",
-            ManagementServer.class,
-            String.class,
-            "sdn.ovs.controller.default.label",
-            "cloud-public",
-            "Default network label to be used when fetching interface for GRE endpoints",
-            null),
-    VmNetworkThrottlingRate(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "vm.network.throttling.rate",
-            "200",
-            "Default data transfer rate in megabits per second allowed in User vm's default network.",
-            null),
-
-    SecurityGroupWorkCleanupInterval(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.securitygroups.work.cleanup.interval",
-            "120",
-            "Time interval (seconds) in which finished work is cleaned up from the work table",
-            null),
-    SecurityGroupWorkerThreads(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.securitygroups.workers.pool.size",
-            "50",
-            "Number of worker threads processing the security group update work queue",
-            null),
-    SecurityGroupWorkGlobalLockTimeout(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.securitygroups.work.lock.timeout",
-            "300",
-            "Lock wait timeout (seconds) while updating the security group work queue",
-            null),
-    SecurityGroupWorkPerAgentMaxQueueSize(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.securitygroups.work.per.agent.queue.size",
-            "100",
-            "The number of outstanding security group work items that can be queued to a host. If exceeded, work items will get dropped to conserve memory. Security Group Sync will take care of ensuring that the host gets updated eventually",
-            null),
-
-    SecurityGroupDefaultAdding(
-            "Network",
-            ManagementServer.class,
-            Boolean.class,
-            "network.securitygroups.defaultadding",
-            "true",
-            "If true, the user VM would be added to the default security group by default",
-            null),
-
-    GuestOSNeedGatewayOnNonDefaultNetwork(
-            "Network",
-            NetworkOrchestrationService.class,
-            String.class,
-            "network.dhcp.nondefaultnetwork.setgateway.guestos",
-            "Windows",
-            "The guest OS's name start with this fields would result in DHCP server response gateway information even when the network it's on is not default network. Names are separated by comma.",
-            null),
-
-    //VPN
-    RemoteAccessVpnPskLength(
-            "Network",
-            AgentManager.class,
-            Integer.class,
-            "remote.access.vpn.psk.length",
-            "24",
-            "The length of the ipsec preshared key (minimum 8, maximum 256)",
-            null),
-    RemoteAccessVpnUserLimit(
-            "Network",
-            AgentManager.class,
-            String.class,
-            "remote.access.vpn.user.limit",
-            "8",
-            "The maximum number of VPN users that can be created per account",
-            null),
-    Site2SiteVpnConnectionPerVpnGatewayLimit(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "site2site.vpn.vpngateway.connection.limit",
-            "4",
-            "The maximum number of VPN connection per VPN gateway",
-            null),
-    Site2SiteVpnSubnetsPerCustomerGatewayLimit(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "site2site.vpn.customergateway.subnets.limit",
-            "10",
-            "The maximum number of subnets per customer gateway",
-            null),
-    MaxNumberOfSecondaryIPsPerNIC(
-            "Network", ManagementServer.class, Integer.class,
-            "vm.network.nic.max.secondary.ipaddresses", "256",
-            "Specify the number of secondary ip addresses per nic per vm. Default value 10 is used, if not specified.", null),
-
-    EnableServiceMonitoring(
-            "Network", ManagementServer.class, Boolean.class,
-            "network.router.enableserviceMonitoring", "false",
-            "service monitoring in router enable/disable option, default false", null),
-
-
-    // Console Proxy
-    ConsoleProxyCapacityStandby(
-            "Console Proxy",
-            AgentManager.class,
-            String.class,
-            "consoleproxy.capacity.standby",
-            "10",
-            "The minimal number of console proxy viewer sessions that system is able to serve immediately(standby capacity)",
-            null),
-    ConsoleProxyCapacityScanInterval(
-            "Console Proxy",
-            AgentManager.class,
-            String.class,
-            "consoleproxy.capacityscan.interval",
-            "30000",
-            "The time interval(in millisecond) to scan whether or not system needs more console proxy to ensure minimal standby capacity",
-            null),
-    ConsoleProxyCmdPort(
-            "Console Proxy",
-            AgentManager.class,
-            Integer.class,
-            "consoleproxy.cmd.port",
-            "8001",
-            "Console proxy command port that is used to communicate with management server",
-            null),
-    ConsoleProxyRestart("Console Proxy", AgentManager.class, Boolean.class, "consoleproxy.restart", "true", "Console proxy restart flag, defaulted to true", null),
-    ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "", "Console proxy url domain", "domainName"),
-    ConsoleProxySessionMax(
-            "Console Proxy",
-            AgentManager.class,
-            Integer.class,
-            "consoleproxy.session.max",
-            String.valueOf(ConsoleProxyManager.DEFAULT_PROXY_CAPACITY),
-            "The max number of viewer sessions console proxy is configured to serve for",
-            null),
-    ConsoleProxySessionTimeout(
-            "Console Proxy",
-            AgentManager.class,
-            Integer.class,
-            "consoleproxy.session.timeout",
-            "300000",
-            "Timeout(in milliseconds) that console proxy tries to maintain a viewer session before it times out the session for no activity",
-            null),
-    ConsoleProxyDisableRpFilter(
-            "Console Proxy",
-            AgentManager.class,
-            Integer.class,
-            "consoleproxy.disable.rpfilter",
-            "true",
-            "disable rp_filter on console proxy VM public interface",
-            null),
-    ConsoleProxyLaunchMax(
-            "Console Proxy",
-            AgentManager.class,
-            Integer.class,
-            "consoleproxy.launch.max",
-            "10",
-            "maximum number of console proxy instances per zone can be launched",
-            null),
-    ConsoleProxyManagementState(
-            "Console Proxy",
-            AgentManager.class,
-            String.class,
-            "consoleproxy.management.state",
-            com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
-            "console proxy service management state",
-            null),
-    ConsoleProxyManagementLastState(
-            "Console Proxy",
-            AgentManager.class,
-            String.class,
-            "consoleproxy.management.state.last",
-            com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
-            "last console proxy service management state",
-            null),
-
-    // Snapshots
-
-    SnapshotPollInterval(
-            "Snapshots",
-            SnapshotManager.class,
-            Integer.class,
-            "snapshot.poll.interval",
-            "300",
-            "The time interval in seconds when the management server polls for snapshots to be scheduled.",
-            null),
-    SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
-    KVMSnapshotEnabled("Hidden", SnapshotManager.class, Boolean.class, "kvm.snapshot.enabled", "false", "whether snapshot is enabled for KVM hosts", null),
-
-    // Advanced
-    EventPurgeInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "event.purge.interval",
-            "86400",
-            "The interval (in seconds) to wait before running the event purge thread",
-            null),
-    AccountCleanupInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "account.cleanup.interval",
-            "86400",
-            "The interval (in seconds) between cleanup for removed accounts",
-            null),
-    InstanceName("Advanced", AgentManager.class, String.class, "instance.name", "VM", "Name of the deployment instance.", "instanceName"),
-    ExpungeDelay(
-            "Advanced",
-            UserVmManager.class,
-            Integer.class,
-            "expunge.delay",
-            "86400",
-            "Determines how long (in seconds) to wait before actually expunging destroyed vm. The default value = the default value of expunge.interval",
-            null),
-    ExpungeInterval(
-            "Advanced",
-            UserVmManager.class,
-            Integer.class,
-            "expunge.interval",
-            "86400",
-            "The interval (in seconds) to wait before running the expunge thread.",
-            null),
-    ExpungeWorkers("Advanced", UserVmManager.class, Integer.class, "expunge.workers", "1", "Number of workers performing expunge ", null),
-    ExtractURLCleanUpInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "extract.url.cleanup.interval",
-            "7200",
-            "The interval (in seconds) to wait before cleaning up the extract URL's ",
-            null),
-    DisableExtraction(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "disable.extraction",
-            "false",
-            "Flag for disabling extraction of template, isos and volumes",
-            null),
-    ExtractURLExpirationInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "extract.url.expiration.interval",
-            "14400",
-            "The life of an extract URL after which it is deleted ",
-            null),
-    HostStatsInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "host.stats.interval",
-            "60000",
-            "The interval (in milliseconds) when host stats are retrieved from agents.",
-            null),
-    HostRetry("Advanced", AgentManager.class, Integer.class, "host.retry", "2", "Number of times to retry hosts for creating a volume", null),
-    IntegrationAPIPort("Advanced", ManagementServer.class, Integer.class, "integration.api.port", null, "Default API port. To disable set it to 0 or negative.", null),
-    InvestigateRetryInterval(
-            "Advanced",
-            HighAvailabilityManager.class,
-            Integer.class,
-            "investigate.retry.interval",
-            "60",
-            "Time (in seconds) between VM pings when agent is disconnected",
-            null),
-    MigrateRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "migrate.retry.interval", "120", "Time (in seconds) between migration retries", null),
-    RouterCpuMHz(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.cpu.mhz",
-            String.valueOf(VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ),
-            "Default CPU speed (MHz) for router VM.",
-            null),
-    RestartRetryInterval(
-            "Advanced",
-            HighAvailabilityManager.class,
-            Integer.class,
-            "restart.retry.interval",
-            "600",
-            "Time (in seconds) between retries to restart a vm",
-            null),
-    RouterStatsInterval(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.stats.interval",
-            "300",
-            "Interval (in seconds) to report router statistics.",
-            null),
-    ExternalNetworkStatsInterval(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "external.network.stats.interval",
-            "300",
-            "Interval (in seconds) to report external network statistics.",
-            null),
-    RouterCheckInterval(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.check.interval",
-            "30",
-            "Interval (in seconds) to report redundant router status.",
-            null),
-    RouterCheckPoolSize(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.check.poolsize",
-            "10",
-            "Numbers of threads using to check redundant router status.",
-            null),
-    RouterExtraPublicNics(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.extra.public.nics",
-            "2",
-            "specify extra public nics used for virtual router(up to 5)",
-            "0-5"),
-    ScaleRetry("Advanced", ManagementServer.class, Integer.class, "scale.retry", "2", "Number of times to retry scaling up the vm", null),
-    StopRetryInterval(
-            "Advanced",
-            HighAvailabilityManager.class,
-            Integer.class,
-            "stop.retry.interval",
-            "600",
-            "Time in seconds between retries to stop or destroy a vm",
-            null),
-    UpdateWait("Advanced", AgentManager.class, Integer.class, "update.wait", "600", "Time to wait (in seconds) before alerting on a updating agent", null),
-    XapiWait("Advanced", AgentManager.class, Integer.class, "xapiwait", "60", "Time (in seconds) to wait for XAPI to return", null),
-    MigrateWait("Advanced", AgentManager.class, Integer.class, "migratewait", "3600", "Time (in seconds) to wait for VM migrate finish", null),
-    HAWorkers("Advanced", AgentManager.class, Integer.class, "ha.workers", "5", "Number of ha worker threads.", null),
-    MountParent(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "mount.parent",
-            "/var/cloudstack/mnt",
-            "The mount point on the Management Server for Secondary Storage.",
-            null),
-    SystemVMAutoReserveCapacity(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "system.vm.auto.reserve.capacity",
-            "true",
-            "Indicates whether or not to automatically reserver system VM standby capacity.",
-            null),
-    SystemVMDefaultHypervisor("Advanced",
-            ManagementServer.class,
-            String.class,
-            "system.vm.default.hypervisor",
-            null,
-            "Hypervisor type used to create system vm, valid values are: XenServer, KVM, VMware, Hyperv, VirtualBox, Parralels, BareMetal, Ovm, LXC, Any",
-            null),
-    SystemVMRandomPassword(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "system.vm.random.password",
-            "false",
-            "Randomize system vm password the first time management server starts",
-            null),
-    LinkLocalIpNums("Advanced", ManagementServer.class, Integer.class, "linkLocalIp.nums", "10", "The number of link local ip that needed by domR(in power of 2)", null),
-    HypervisorList(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "hypervisor.list",
-            HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," +
-                HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
-            "The list of hypervisors that this deployment will use.",
-            "hypervisorList"),
-    ManagementNetwork("Advanced", ManagementServer.class, String.class, "management.network.cidr", null, "The cidr of management server network", null),
-    EventPurgeDelay(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "event.purge.delay",
-            "15",
-            "Events older than specified number days will be purged. Set this value to 0 to never delete events",
-            null),
-    SecStorageVmMTUSize(
-            "Advanced",
-            AgentManager.class,
-            Integer.class,
-            "secstorage.vm.mtu.size",
-            String.valueOf(SecondaryStorageVmManager.DEFAULT_SS_VM_MTUSIZE),
-            "MTU size (in Byte) of storage network in secondary storage vms",
-            null),
-    MaxTemplateAndIsoSize(
-            "Advanced",
-            ManagementServer.class,
-            Long.class,
-            "max.template.iso.size",
-            "50",
-            "The maximum size for a downloaded template or ISO (in GB).",
-            null),
-    SecStorageAllowedInternalDownloadSites(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "secstorage.allowed.internal.sites",
-            null,
-            "Comma separated list of cidrs internal to the datacenter that can host template download servers, please note 0.0.0.0 is not a valid site",
-            null),
-    SecStorageEncryptCopy(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "secstorage.encrypt.copy",
-            "false",
-            "Use SSL method used to encrypt copy traffic between zones",
-            "true,false"),
-    SecStorageSecureCopyCert(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "secstorage.ssl.cert.domain",
-            "",
-            "SSL certificate used to encrypt copy traffic between zones",
-            "domainName"),
-    SecStorageCapacityStandby(
-            "Advanced",
-            AgentManager.class,
-            Integer.class,
-            "secstorage.capacity.standby",
-            "10",
-            "The minimal number of command execution sessions that system is able to serve immediately(standby capacity)",
-            null),
-    SecStorageSessionMax(
-            "Advanced",
-            AgentManager.class,
-            Integer.class,
-            "secstorage.session.max",
-            "50",
-            "The max number of command execution sessions that a SSVM can handle",
-            null),
-    SecStorageCmdExecutionTimeMax(
-            "Advanced",
-            AgentManager.class,
-            Integer.class,
-            "secstorage.cmd.execution.time.max",
-            "30",
-            "The max command execution time in minute",
-            null),
-    SecStorageProxy(
-            "Advanced",
-            AgentManager.class,
-            String.class,
-            "secstorage.proxy",
-            null,
-            "http proxy used by ssvm, in http://username:password@proxyserver:port format",
-            null),
-    AlertPurgeInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "alert.purge.interval",
-            "86400",
-            "The interval (in seconds) to wait before running the alert purge thread",
-            null),
-    AlertPurgeDelay(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "alert.purge.delay",
-            "0",
-            "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts",
-            null),
-    HostReservationReleasePeriod(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "host.reservation.release.period",
-            "300000",
-            "The interval in milliseconds between host reservation release checks",
-            null),
-    // LB HealthCheck Interval.
-    LBHealthCheck(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "healthcheck.update.interval",
-            "600",
-            "Time Interval to fetch the LB health check states (in sec)",
-            null),
-    NCCCmdTimeOut(
-            "Advanced",
-            ManagementServer.class,
-            Long.class,
-            "ncc.command.timeout",
-            "600000", // 10 minutes
-            "Command Timeout Interval (in millisec)",
-            null),
-    DirectAttachNetworkEnabled(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "direct.attach.network.externalIpAllocator.enabled",
-            "false",
-            "Direct-attach VMs using external DHCP server",
-            "true,false"),
-    DirectAttachNetworkExternalAPIURL(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "direct.attach.network.externalIpAllocator.url",
-            null,
-            "Direct-attach VMs using external DHCP server (API url)",
-            null),
-    CheckPodCIDRs(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "check.pod.cidrs",
-            "true",
-            "If true, different pods must belong to different CIDR subnets.",
-            "true,false"),
-    NetworkGcWait(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "network.gc.wait",
-            "600",
-            "Time (in seconds) to wait before shutting down a network that's not in used",
-            null),
-    NetworkGcInterval("Advanced", ManagementServer.class, Integer.class, "network.gc.interval", "600", "Seconds to wait before checking for networks to shutdown", null),
-    CapacitySkipcountingHours(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "capacity.skipcounting.hours",
-            "3600",
-            "Time (in seconds) to wait before release VM's cpu and memory when VM in stopped state",
-            null),
-    VmStatsInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.stats.interval",
-            "60000",
-            "The interval (in milliseconds) when vm stats are retrieved from agents.",
-            null),
-    VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null),
-    VolumeStatsInterval("Advanced", ManagementServer.class, Integer.class, "volume.stats.interval", "60000", "Interval (in seconds) to report volume statistics.", null),
-    VmTransitionWaitInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.tranisition.wait.interval",
-            "3600",
-            "Time (in seconds) to wait before taking over a VM in transition state",
-            null),
-    VmDiskThrottlingIopsReadRate(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.disk.throttling.iops_read_rate",
-            "0",
-            "Default disk I/O read rate in requests per second allowed in User vm's disk.",
-            null),
-    VmDiskThrottlingIopsWriteRate(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.disk.throttling.iops_write_rate",
-            "0",
-            "Default disk I/O writerate in requests per second allowed in User vm's disk.",
-            null),
-    VmDiskThrottlingBytesReadRate(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.disk.throttling.bytes_read_rate",
-            "0",
-            "Default disk I/O read rate in bytes per second allowed in User vm's disk.",
-            null),
-    VmDiskThrottlingBytesWriteRate(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vm.disk.throttling.bytes_write_rate",
-            "0",
-            "Default disk I/O writerate in bytes per second allowed in User vm's disk.",
-            null),
-    KvmAutoConvergence(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "kvm.auto.convergence",
-            "false",
-            "Setting this to 'true' allows KVM to use auto convergence to complete VM migration (libvirt version 1.2.3+ and QEMU version 1.6+)",
-            null),
-    ControlCidr(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "control.cidr",
-            "169.254.0.0/16",
-            "Changes the cidr for the control network traffic.  Defaults to using link local.  Must be unique within pods",
-            null),
-    ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null),
-    HostCapacityTypeToOrderClusters(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "host.capacityType.to.order.clusters",
-            "CPU",
-            "The host capacity type (CPU or RAM) is used by deployment planner to order clusters during VM resource allocation",
-            "CPU,RAM"),
-    ApplyAllocationAlgorithmToPods(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "apply.allocation.algorithm.to.pods",
-            "false",
-            "If true, deployment planner applies the allocation heuristics at pods first in the given datacenter during VM resource allocation",
-            "true,false"),
-    VmUserDispersionWeight(
-            "Advanced",
-            ManagementServer.class,
-            Float.class,
-            "vm.user.dispersion.weight",
-            "1",
-            "Weight for user dispersion heuristic (as a value between 0 and 1) applied to resource allocation during vm deployment. Weight for capacity heuristic will be (1 - weight of user dispersion)",
-            null),
-    VmAllocationAlgorithm(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vm.allocation.algorithm",
-            "random",
-            "'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit', 'firstfitleastconsumed' : Order in which hosts within a cluster will be considered for VM/volume allocation.",
-            null),
-    VmDeploymentPlanner(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vm.deployment.planner",
-            "FirstFitPlanner",
-            "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.",
-            null),
-    ElasticLoadBalancerEnabled(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.basiczone.elb.enabled",
-            "false",
-            "Whether the load balancing service is enabled for basic zones",
-            "true,false"),
-    ElasticLoadBalancerNetwork(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "network.loadbalancer.basiczone.elb.network",
-            "guest",
-            "Whether the elastic load balancing service public ips are taken from the public or guest network",
-            "guest,public"),
-    ElasticLoadBalancerVmMemory(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "network.loadbalancer.basiczone.elb.vm.ram.size",
-            "128",
-            "Memory in MB for the elastic load balancer vm",
-            null),
-    ElasticLoadBalancerVmCpuMhz(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "network.loadbalancer.basiczone.elb.vm.cpu.mhz",
-            "128",
-            "CPU speed for the elastic load balancer vm",
-            null),
-    ElasticLoadBalancerVmNumVcpu(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "network.loadbalancer.basiczone.elb.vm.vcpu.num",
-            "1",
-            "Number of VCPU  for the elastic load balancer vm",
-            null),
-    ElasticLoadBalancerVmGcInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "network.loadbalancer.basiczone.elb.gc.interval.minutes",
-            "30",
-            "Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5",
-            null),
-    SortKeyAlgorithm(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "sortkey.algorithm",
-            "false",
-            "Sort algorithm for those who use sort key(template, disk offering, service offering, network offering), true means ascending sort while false means descending sort",
-            null),
-    EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false", "enable EC2 API on CloudStack", null),
-    EnableS3API("Advanced", ManagementServer.class, Boolean.class, "enable.s3.api", "false", "enable Amazon S3 API on CloudStack", null),
-    RecreateSystemVmEnabled(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "recreate.systemvm.enabled",
-            "false",
-            "If true, will recreate system vm root disk whenever starting system vm",
-            "true,false"),
-    SetVmInternalNameUsingDisplayName(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "vm.instancename.flag",
-            "false",
-            "If set to true, will set guest VM's name as it appears on the hypervisor, to its hostname. The flag is supported for VMware hypervisor only",
-            "true,false"),
-    IncorrectLoginAttemptsAllowed(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "incorrect.login.attempts.allowed",
-            "5",
-            "Incorrect login attempts allowed before the user is disabled",
-            null),
-    // Ovm
-    OvmPublicNetwork("Hidden", ManagementServer.class, String.class, "ovm.public.network.device", null, "Specify the public bridge on host for public network", null),
-    OvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm.private.network.device", null, "Specify the private bridge on host for private network", null),
-    OvmGuestNetwork("Hidden", ManagementServer.class, String.class, "ovm.guest.network.device", null, "Specify the private bridge on host for private network", null),
-
-    // Ovm3
-    Ovm3PublicNetwork("Hidden", ManagementServer.class, String.class, "ovm3.public.network.device", null, "Specify the public bridge on host for public network", null),
-    Ovm3PrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm3.private.network.device", null, "Specify the private bridge on host for private network", null),
-    Ovm3GuestNetwork("Hidden", ManagementServer.class, String.class, "ovm3.guest.network.device", null, "Specify the guest bridge on host for guest network", null),
-    Ovm3StorageNetwork("Hidden", ManagementServer.class, String.class, "ovm3.storage.network.device", null, "Specify the storage bridge on host for storage network", null),
-    Ovm3HeartBeatTimeout(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "ovm3.heartbeat.timeout",
-            "120",
-            "timeout used for primary storage check, upon timeout a panic is triggered.",
-            null),
-    Ovm3HeartBeatInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "ovm3.heartbeat.interval",
-            "1",
-            "interval used to check primary storage availability.",
-            null),
-
-
-    // XenServer
-    XenServerPublicNetwork(
-            "Hidden",
-            ManagementServer.class,
-            String.class,
-            "xenserver.public.network.device",
-            null,
-            "[ONLY IF THE PUBLIC NETWORK IS ON A DEDICATED NIC]:The network name label of the physical device dedicated to the public network on a XenServer host",
-            null),
-    XenServerStorageNetwork1("Hidden", ManagementServer.class, String.class, "xenserver.storage.network.device1", null, "Specify when there are storage networks", null),
-    XenServerStorageNetwork2("Hidden", ManagementServer.class, String.class, "xenserver.storage.network.device2", null, "Specify when there are storage networks", null),
-    XenServerPrivateNetwork("Hidden", ManagementServer.class, String.class, "xenserver.private.network.device", null, "Specify when the private network name is different", null),
-    NetworkGuestCidrLimit(
-            "Network",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "network.guest.cidr.limit",
-            "22",
-            "size limit for guest cidr; can't be less than this value",
-            null),
-    XenServerSetupMultipath("Advanced", ManagementServer.class, String.class, "xenserver.setup.multipath", "false", "Setup the host to do multipath", null),
-    XenServerBondStorageNic("Advanced", ManagementServer.class, String.class, "xenserver.bond.storage.nics", null, "Attempt to bond the two networks if found", null),
-    XenServerHeartBeatTimeout(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "xenserver.heartbeat.timeout",
-            "120",
-            "heartbeat timeout to use when implementing XenServer Self Fencing",
-            null),
-    XenServerHeartBeatInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "xenserver.heartbeat.interval",
-            "60",
-            "heartbeat interval to use when checking before XenServer Self Fencing",
-            null),
-    XenServerGuestNetwork("Hidden", ManagementServer.class, String.class, "xenserver.guest.network.device", null, "Specify for guest network name label", null),
-    XenServerMaxNics("Advanced", AgentManager.class, Integer.class, "xenserver.nics.max", "7", "Maximum allowed nics for Vms created on XenServer", null),
-    XenServerPVdriverVersion(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "xenserver.pvdriver.version",
-            "xenserver61",
-            "default Xen PV driver version for registered template, valid value:xenserver56,xenserver61 ",
-            "xenserver56,xenserver61"),
-    XenServerHotFix("Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "xenserver.hotfix.enabled",
-            "false",
-            "Enable/Disable XenServer hot fix",
-            null),
-
-    // VMware
-    VmwareUseNexusVSwitch(
-            "Network",
-            ManagementServer.class,
-            Boolean.class,
-            "vmware.use.nexus.vswitch",
-            "false",
-            "Enable/Disable Cisco Nexus 1000v vSwitch in VMware environment",
-            null),
-    VmwareUseDVSwitch(
-            "Network",
-            ManagementServer.class,
-            Boolean.class,
-            "vmware.use.dvswitch",
-            "false",
-            "Enable/Disable Nexus/Vmware dvSwitch in VMware environment",
-            null),
-    VmwareCreateFullClone(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "vmware.create.full.clone",
-            "true",
-            "If set to true, creates guest VMs as full clones on ESX",
-            null),
-    VmwareServiceConsole(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vmware.service.console",
-            "Service Console",
-            "Specify the service console network name(for ESX hosts)",
-            null),
-    VmwareManagementPortGroup(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vmware.management.portgroup",
-            "Management Network",
-            "Specify the management network name(for ESXi hosts)",
-            null),
-    VmwareAdditionalVncPortRangeStart(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vmware.additional.vnc.portrange.start",
-            "50000",
-            "Start port number of additional VNC port range",
-            null),
-    VmwareAdditionalVncPortRangeSize(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vmware.additional.vnc.portrange.size",
-            "1000",
-            "Start port number of additional VNC port range",
-            null),
-    //VmwareGuestNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.guest.nic.device.type", "E1000", "Ethernet card type used in guest VM, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null),
-    VmwareRootDiskControllerType(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vmware.root.disk.controller",
-            "ide",
-            "Specify the default disk controller for root volumes, valid values are scsi, ide, osdefault. Please check documentation for more details on each of these values.",
-            null),
-    VmwareSystemVmNicDeviceType(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "vmware.systemvm.nic.device.type",
-            "E1000",
-            "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3",
-            null),
-    VmwareRecycleHungWorker(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "vmware.recycle.hung.wokervm",
-            "false",
-            "Specify whether or not to recycle hung worker VMs",
-            null),
-    VmwareHungWorkerTimeout("Advanced", ManagementServer.class, Long.class, "vmware.hung.wokervm.timeout", "7200", "Worker VM timeout in seconds", null),
-    VmwareVcenterSessionTimeout("Advanced", ManagementServer.class, Long.class, "vmware.vcenter.session.timeout", "1200", "VMware client timeout in seconds", null),
-
-    // KVM
-    KvmPublicNetwork("Hidden", ManagementServer.class, String.class, "kvm.public.network.device", null, "Specify the public bridge on host for public network", null),
-    KvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "kvm.private.network.device", null, "Specify the private bridge on host for private network", null),
-    KvmGuestNetwork("Hidden", ManagementServer.class, String.class, "kvm.guest.network.device", null, "Specify the private bridge on host for private network", null),
-
-    // Hyperv
-    HypervPublicNetwork(
-            "Hidden",
-            ManagementServer.class,
-            String.class,
-            "hyperv.public.network.device",
-            null,
-            "Specify the public virtual switch on host for public network",
-            null),
-    HypervPrivateNetwork(
-            "Hidden",
-            ManagementServer.class,
-            String.class,
-            "hyperv.private.network.device",
-            null,
-            "Specify the virtual switch on host for private network",
-            null),
-    HypervGuestNetwork(
-            "Hidden",
-            ManagementServer.class,
-            String.class,
-            "hyperv.guest.network.device",
-            null,
-            "Specify the virtual switch on host for private network",
-            null),
-
-    // Usage
-    UsageExecutionTimezone("Usage", ManagementServer.class, String.class, "usage.execution.timezone", null, "The timezone to use for usage job execution time", null),
-    UsageStatsJobAggregationRange(
-            "Usage",
-            ManagementServer.class,
-            Integer.class,
-            "usage.stats.job.aggregation.range",
-            "1440",
-            "The range of time for aggregating the user statistics specified in minutes (e.g. 1440 for daily, 60 for hourly.",
-            null),
-    UsageStatsJobExecTime(
-            "Usage",
-            ManagementServer.class,
-            String.class,
-            "usage.stats.job.exec.time",
-            "00:15",
-            "The time at which the usage statistics aggregation job will run as an HH24:MM time, e.g. 00:30 to run at 12:30am.",
-            null),
-    EnableUsageServer("Usage", ManagementServer.class, Boolean.class, "enable.usage.server", "true", "Flag for enabling usage", null),
-    DirectNetworkStatsInterval(
-            "Usage",
-            ManagementServer.class,
-            Integer.class,
-            "direct.network.stats.interval",
-            "86400",
-            "Interval (in seconds) to collect stats from Traffic Monitor",
-            null),
-    UsageSanityCheckInterval(
-            "Usage",
-            ManagementServer.class,
-            Integer.class,
-            "usage.sanity.check.interval",
-            null,
-            "Interval (in days) to check sanity of usage data. To disable set it to 0 or negative.",
-            null),
-    UsageAggregationTimezone("Usage", ManagementServer.class, String.class, "usage.aggregation.timezone", "GMT", "The timezone to use for usage stats aggregation", null),
-    TrafficSentinelIncludeZones(
-            "Usage",
-            ManagementServer.class,
-            Integer.class,
-            "traffic.sentinel.include.zones",
-            "EXTERNAL",
-            "Traffic going into specified list of zones is metered. For metering all traffic leave this parameter empty",
-            null),
-    TrafficSentinelExcludeZones(
-            "Usage",
-            ManagementServer.class,
-            Integer.class,
-            "traffic.sentinel.exclude.zones",
-            "",
-            "Traffic going into specified list of zones is not metered.",
-            null),
-
-    // Hidden
-    UseSecondaryStorageVm(
-            "Hidden",
-            ManagementServer.class,
-            Boolean.class,
-            "secondary.storage.vm",
-            "false",
-            "Deploys a VM per zone to manage secondary storage if true, otherwise secondary storage is mounted on management server",
-            null),
-    CreatePoolsInPod(
-            "Hidden",
-            ManagementServer.class,
-            Boolean.class,
-            "xenserver.create.pools.in.pod",
-            "false",
-            "Should we automatically add XenServers into pools that are inside a Pod",
-            null),
-    CloudIdentifier("Hidden", ManagementServer.class, String.class, "cloud.identifier", null, "A unique identifier for the cloud.", null),
-    SSOKey("Secure", ManagementServer.class, String.class, "security.singlesignon.key", null, "A Single Sign-On key used for logging into the cloud", null),
-    SSOAuthTolerance(
-            "Advanced",
-            ManagementServer.class,
-            Long.class,
-            "security.singlesignon.tolerance.millis",
-            "300000",
-            "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.",
-            null),
-    //NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"),
-    RouterRamSize("Hidden", NetworkOrchestrationService.class, Integer.class, "router.ram.size", "256", "Default RAM for router VM (in MB).", null),
-
-    DefaultPageSize("Advanced", ManagementServer.class, Long.class, "default.page.size", "500", "Default page size for API list* commands", null),
-
-    TaskCleanupRetryInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "task.cleanup.retry.interval",
-            "600",
-            "Time (in seconds) to wait before retrying cleanup of tasks if the cleanup failed previously.  0 means to never retry.",
-            "Seconds"),
-
-    // Account Default Limits
-    DefaultMaxAccountUserVms(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.user.vms",
-            "20",
-            "The default maximum number of user VMs that can be deployed for an account",
-            null),
-    DefaultMaxAccountPublicIPs(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.public.ips",
-            "20",
-            "The default maximum number of public IPs that can be consumed by an account",
-            null),
-    DefaultMaxAccountTemplates(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.templates",
-            "20",
-            "The default maximum number of templates that can be deployed for an account",
-            null),
-    DefaultMaxAccountSnapshots(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.snapshots",
-            "20",
-            "The default maximum number of snapshots that can be created for an account",
-            null),
-    DefaultMaxAccountVolumes(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.volumes",
-            "20",
-            "The default maximum number of volumes that can be created for an account",
-            null),
-    DefaultMaxAccountNetworks(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.networks",
-            "20",
-            "The default maximum number of networks that can be created for an account",
-            null),
-    DefaultMaxAccountVpcs(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.vpcs",
-            "20",
-            "The default maximum number of vpcs that can be created for an account",
-            null),
-    DefaultMaxAccountCpus(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.cpus",
-            "40",
-            "The default maximum number of cpu cores that can be used for an account",
-            null),
-    DefaultMaxAccountMemory(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.memory",
-            "40960",
-            "The default maximum memory (in MB) that can be used for an account",
-            null),
-    DefaultMaxAccountPrimaryStorage(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.primary.storage",
-            "200",
-            "The default maximum primary storage space (in GiB) that can be used for an account",
-            null),
-    DefaultMaxAccountSecondaryStorage(
-            "Account Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.account.secondary.storage",
-            "400",
-            "The default maximum secondary storage space (in GiB) that can be used for an account",
-            null),
-
-    //disabling lb as cluster sync does not work with distributed cluster
-    SubDomainNetworkAccess(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Boolean.class,
-            "allow.subdomain.network.access",
-            "true",
-            "Allow subdomains to use networks dedicated to their parent domain(s)",
-            null),
-    EncodeApiResponse("Advanced", ManagementServer.class, Boolean.class, "encode.api.response", "false", "Do URL encoding for the api response, false by default", null),
-    DnsBasicZoneUpdates(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            String.class,
-            "network.dns.basiczone.updates",
-            "all",
-            "This parameter can take 2 values: all (default) and pod. It defines if DHCP/DNS requests have to be send to all dhcp servers in cloudstack, or only to the one in the same pod",
-            "all,pod"),
-
-    ClusterMessageTimeOutSeconds(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "cluster.message.timeout.seconds",
-            "300",
-            "Time (in seconds) to wait before a inter-management server message post times out.",
-            null),
-    AgentLoadThreshold(
-            "Advanced",
-            ManagementServer.class,
-            Float.class,
-            "agent.load.threshold",
-            "0.7",
-            "Percentage (as a value between 0 and 1) of connected agents after which agent load balancing will start happening",
-            null),
-
-    DefaultMaxDomainUserVms("Domain Defaults", ManagementServer.class, Long.class, "max.domain.user.vms", "40", "The default maximum number of user VMs that can be deployed for a domain", null),
-    DefaultMaxDomainPublicIPs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.public.ips", "40", "The default maximum number of public IPs that can be consumed by a domain", null),
-    DefaultMaxDomainTemplates("Domain Defaults", ManagementServer.class, Long.class, "max.domain.templates", "40", "The default maximum number of templates that can be deployed for a domain", null),
-    DefaultMaxDomainSnapshots("Domain Defaults", ManagementServer.class, Long.class, "max.domain.snapshots", "40", "The default maximum number of snapshots that can be created for a domain", null),
-    DefaultMaxDomainVolumes("Domain Defaults", ManagementServer.class, Long.class, "max.domain.volumes", "40", "The default maximum number of volumes that can be created for a domain", null),
-    DefaultMaxDomainNetworks("Domain Defaults", ManagementServer.class, Long.class, "max.domain.networks", "40", "The default maximum number of networks that can be created for a domain", null),
-    DefaultMaxDomainVpcs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.vpcs", "40", "The default maximum number of vpcs that can be created for a domain", null),
-    DefaultMaxDomainCpus("Domain Defaults", ManagementServer.class, Long.class, "max.domain.cpus", "80", "The default maximum number of cpu cores that can be used for a domain", null),
-    DefaultMaxDomainMemory("Domain Defaults", ManagementServer.class, Long.class, "max.domain.memory", "81920", "The default maximum memory (in MB) that can be used for a domain", null),
-    DefaultMaxDomainPrimaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.primary.storage", "400", "The default maximum primary storage space (in GiB) that can be used for a domain", null),
-    DefaultMaxDomainSecondaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.secondary.storage", "800", "The default maximum secondary storage space (in GiB) that can be used for a domain", null),
-
-    DefaultMaxProjectUserVms(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.user.vms",
-            "20",
-            "The default maximum number of user VMs that can be deployed for a project",
-            null),
-    DefaultMaxProjectPublicIPs(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.public.ips",
-            "20",
-            "The default maximum number of public IPs that can be consumed by a project",
-            null),
-    DefaultMaxProjectTemplates(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.templates",
-            "20",
-            "The default maximum number of templates that can be deployed for a project",
-            null),
-    DefaultMaxProjectSnapshots(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.snapshots",
-            "20",
-            "The default maximum number of snapshots that can be created for a project",
-            null),
-    DefaultMaxProjectVolumes(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.volumes",
-            "20",
-            "The default maximum number of volumes that can be created for a project",
-            null),
-    DefaultMaxProjectNetworks(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.networks",
-            "20",
-            "The default maximum number of networks that can be created for a project",
-            null),
-    DefaultMaxProjectVpcs(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.vpcs",
-            "20",
-            "The default maximum number of vpcs that can be created for a project",
-            null),
-    DefaultMaxProjectCpus(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.cpus",
-            "40",
-            "The default maximum number of cpu cores that can be used for a project",
-            null),
-    DefaultMaxProjectMemory(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.memory",
-            "40960",
-            "The default maximum memory (in MB) that can be used for a project",
-            null),
-    DefaultMaxProjectPrimaryStorage(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.primary.storage",
-            "200",
-            "The default maximum primary storage space (in GiB) that can be used for an project",
-            null),
-    DefaultMaxProjectSecondaryStorage(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "max.project.secondary.storage",
-            "400",
-            "The default maximum secondary storage space (in GiB) that can be used for an project",
-            null),
-
-    ProjectInviteRequired(
-            "Project Defaults",
-            ManagementServer.class,
-            Boolean.class,
-            "project.invite.required",
-            "false",
-            "If invitation confirmation is required when add account to project. Default value is false",
-            null),
-    ProjectInvitationExpirationTime(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "project.invite.timeout",
-            "86400",
-            "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds",
-            null),
-    AllowUserToCreateProject(
-            "Project Defaults",
-            ManagementServer.class,
-            Long.class,
-            "allow.user.create.projects",
-            "true",
-            "If regular user can create a project; true by default",
-            null),
-
-    ProjectEmailSender(
-            "Project Defaults",
-            ManagementServer.class,
-            String.class,
-            "project.email.sender",
-            null,
-            "Sender of project invitation email (will be in the From header of the email)",
-            null),
-    ProjectSMTPHost(
-            "Project Defaults",
-            ManagementServer.class,
-            String.class,
-            "project.smtp.host",
-            null,
-            "SMTP hostname used for sending out email project invitations",
-            null),
-    ProjectSMTPPassword(
-            "Secure",
-            ManagementServer.class,
-            String.class,
-            "project.smtp.password",
-            null,
-            "Password for SMTP authentication (applies only if project.smtp.useAuth is true)",
-            null),
-    ProjectSMTPPort("Project Defaults", ManagementServer.class, Integer.class, "project.smtp.port", "465", "Port the SMTP server is listening on", null),
-    ProjectSMTPUseAuth(
-            "Project Defaults",
-            ManagementServer.class,
-            String.class,
-            "project.smtp.useAuth",
-            null,
-            "If true, use SMTP authentication when sending emails",
-            null),
-    ProjectSMTPUsername(
-            "Project Defaults",
-            ManagementServer.class,
-            String.class,
-            "project.smtp.username",
-            null,
-            "Username for SMTP authentication (applies only if project.smtp.useAuth is true)",
-            null),
-
-    DefaultExternalLoadBalancerCapacity(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "external.lb.default.capacity",
-            "50",
-            "default number of networks permitted per external load balancer device",
-            null),
-    DefaultExternalFirewallCapacity(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "external.firewall.default.capacity",
-            "50",
-            "default number of networks permitted per external load firewall device",
-            null),
-    EIPWithMultipleNetScalersEnabled(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "eip.use.multiple.netscalers",
-            "false",
-            "Should be set to true, if there will be multiple NetScaler devices providing EIP service in a zone",
-            null),
-    ConsoleProxyServiceOffering(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "consoleproxy.service.offering",
-            null,
-            "Uuid of the service offering used by console proxy; if NULL - system offering will be used",
-            null),
-    SecondaryStorageServiceOffering(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "secstorage.service.offering",
-            null,
-            "Uuid of the service offering used by secondary storage; if NULL - system offering will be used",
-            null),
-    HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null),
-    ImplicitHostTags(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "implicit.host.tags",
-            "GPU",
-            "Tag hosts at the time of host disovery based on the host properties/capabilities",
-            null),
-    VpcCleanupInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "vpc.cleanup.interval",
-            "3600",
-            "The interval (in seconds) between cleanup for Inactive VPCs",
-            null),
-    VpcMaxNetworks("Advanced", ManagementServer.class, Integer.class, "vpc.max.networks", "3", "Maximum number of networks per vpc", null),
-    DetailBatchQuerySize("Advanced", ManagementServer.class, Integer.class, "detail.batch.query.size", "2000", "Default entity detail batch query size for listing", null),
-    ConcurrentSnapshotsThresholdPerHost(
-            "Advanced",
-            ManagementServer.class,
-            Long.class,
-            "concurrent.snapshots.threshold.perhost",
-            null,
-            "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited",
-            null),
-    NetworkIPv6SearchRetryMax(
-            "Network",
-            ManagementServer.class,
-            Integer.class,
-            "network.ipv6.search.retry.max",
-            "10000",
-            "The maximum number of retrying times to search for an available IPv6 address in the table",
-            null),
-
-    BaremetalInternalStorageServer(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "baremetal.internal.storage.server.ip",
-            null,
-            "the ip address of server that stores kickstart file, kernel, initrd, ISO for advanced networking baremetal provisioning",
-            null),
-    BaremetalProvisionDoneNotificationEnabled(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "baremetal.provision.done.notification.enabled",
-            "true",
-            "whether to enable baremetal provison done notification",
-            null),
-    BaremetalProvisionDoneNotificationTimeout(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "baremetal.provision.done.notification.timeout",
-            "1800",
-            "the max time to wait before treating a baremetal provision as failure if no provision done notification is not received, in secs",
-            null),
-    BaremetalProvisionDoneNotificationPort(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "baremetal.provision.done.notification.port",
-            "8080",
-            "the port that listens baremetal provision done notification. Should be the same to port management server listening on for now. Please change it to management server port if it's not default 8080",
-            null),
-    ExternalBaremetalSystemUrl(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "external.baremetal.system.url",
-            null,
-            "url of external baremetal system that CloudStack will talk to",
-            null),
-    ExternalBaremetalResourceClassName(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "external.baremetal.resource.classname",
-            null,
-            "class name for handling external baremetal resource",
-            null),
-    EnableBaremetalSecurityGroupAgentEcho(
-            "Advanced",
-            ManagementServer.class,
-            Boolean.class,
-            "enable.baremetal.securitygroup.agent.echo",
-            "false",
-            "After starting provision process, periodcially echo security agent installed in the template. Treat provisioning as success only if echo successfully",
-            null),
-    IntervalToEchoBaremetalSecurityGroupAgent(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "interval.baremetal.securitygroup.agent.echo",
-            "10",
-            "Interval to echo baremetal security group agent, in seconds",
-            null),
-    TimeoutToEchoBaremetalSecurityGroupAgent(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "timeout.baremetal.securitygroup.agent.echo",
-            "3600",
-            "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure",
-            null),
-
-    BaremetalIpmiLanInterface(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "baremetal.ipmi.lan.interface",
-            "default",
-            "option specified in -I option of impitool. candidates are: open/bmc/lipmi/lan/lanplus/free/imb, see ipmitool man page for details. default valule 'default' means using default option of ipmitool",
-            null),
-
-    BaremetalIpmiRetryTimes("Advanced",
-            ManagementServer.class,
-            String.class,
-            "baremetal.ipmi.fail.retry",
-            "5",
-            "ipmi interface will be temporary out of order after power opertions(e.g. cycle, on), it leads following commands fail immediately. The value specifies retry times before accounting it as real failure",
-            null),
-
-    ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null),
-    ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null),
-    ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null),
-    ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null),
-
-    // object store
-    S3EnableRRS("Advanced", ManagementServer.class, Boolean.class, "s3.rrs.enabled", "false", "enable s3 reduced redundancy storage", null),
-    S3MaxSingleUploadSize(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "s3.singleupload.max.size",
-            "5",
-            "The maximum size limit for S3 single part upload API(in GB). If it is set to 0, then it means always use multi-part upload to upload object to S3. "
-                + "If it is set to -1, then it means always use single-part upload to upload object to S3. ",
-            null),
-
-    // VMSnapshots
-    VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
-    VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
-
-    CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", null, "DNS name of the cloud for the GSLB service", null),
-    InternalLbVmServiceOfferingId(
-            "Advanced",
-            ManagementServer.class,
-            String.class,
-            "internallbvm.service.offering",
-            null,
-            "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used",
-            null),
-    ExecuteInSequenceNetworkElementCommands(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Boolean.class,
-            "execute.in.sequence.network.element.commands",
-            "false",
-            "If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side."
-                + " If set to false, these commands become asynchronous. Default value is false.",
-            null),
-
-    UCSSyncBladeInterval(
-            "Advanced",
-            ManagementServer.class,
-            Integer.class,
-            "ucs.sync.blade.interval",
-            "3600",
-            "the interval cloudstack sync with UCS manager for available blades in case user remove blades from chassis without notifying CloudStack",
-            null),
-
-    RedundantRouterVrrpInterval(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.redundant.vrrp.interval",
-            "1",
-            "seconds between VRRP broadcast. It would 3 times broadcast fail to trigger fail-over mechanism of redundant router",
-            null),
-
-    RouterAggregationCommandEachTimeout(
-            "Advanced",
-            NetworkOrchestrationService.class,
-            Integer.class,
-            "router.aggregation.command.each.timeout",
-            "600",
-            "timeout in seconds for each Virtual Router command being aggregated. The final aggregation command timeout would be determined by this timeout * commands counts ",
-            null),
-
-    ManagementServerVendor("Advanced", ManagementServer.class, String.class, "mgt.server.vendor", "ACS", "the vendor of management server", null),
-    PublishActionEvent("Advanced", ManagementServer.class, Boolean.class, "publish.action.events", "true", "enable or disable publishing of action events on the event bus", null),
-    PublishAlertEvent("Advanced", ManagementServer.class, Boolean.class, "publish.alert.events", "true", "enable or disable publishing of alert events on the event bus", null),
-    PublishResourceStateEvent("Advanced", ManagementServer.class, Boolean.class, "publish.resource.state.events", "true", "enable or disable publishing of alert events on the event bus", null),
-    PublishUsageEvent("Advanced", ManagementServer.class, Boolean.class, "publish.usage.events", "true", "enable or disable publishing of usage events on the event bus", null),
-    PublishAsynJobEvent("Advanced", ManagementServer.class, Boolean.class, "publish.async.job.events", "true", "enable or disable publishing of usage events on the event bus", null),
-
-    // StatsCollector
-    StatsOutPutGraphiteHost("Advanced", ManagementServer.class, String.class, "stats.output.uri", "", "URI to additionally send StatsCollector statistics to", null),
-
-    SSVMPSK("Hidden", ManagementServer.class, String.class, "upload.post.secret.key", "", "PSK with SSVM", null);
-
-    private final String _category;
-    private final Class<?> _componentClass;
-    private final Class<?> _type;
-    private final String _name;
-    private final String _defaultValue;
-    private final String _description;
-    private final String _range;
-    private final String _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
-
-    private static final HashMap<String, List<Config>> s_scopeLevelConfigsMap = new HashMap<String, List<Config>>();
-    static {
-        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Zone.toString(), new ArrayList<Config>());
-        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster.toString(), new ArrayList<Config>());
-        s_scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool.toString(), new ArrayList<Config>());
-        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Account.toString(), new ArrayList<Config>());
-        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Global.toString(), new ArrayList<Config>());
-
-        for (Config c : Config.values()) {
-            //Creating group of parameters per each level (zone/cluster/pool/account)
-            StringTokenizer tokens = new StringTokenizer(c.getScope(), ",");
-            while (tokens.hasMoreTokens()) {
-                String scope = tokens.nextToken().trim();
-                List<Config> currentConfigs = s_scopeLevelConfigsMap.get(scope);
-                currentConfigs.add(c);
-                s_scopeLevelConfigsMap.put(scope, currentConfigs);
-            }
-        }
-    }
-
-    private static final HashMap<String, List<Config>> Configs = new HashMap<String, List<Config>>();
-    static {
-        // Add categories
-        Configs.put("Alert", new ArrayList<Config>());
-        Configs.put("Storage", new ArrayList<Config>());
-        Configs.put("Snapshots", new ArrayList<Config>());
-        Configs.put("Network", new ArrayList<Config>());
-        Configs.put("Usage", new ArrayList<Config>());
-        Configs.put("Console Proxy", new ArrayList<Config>());
-        Configs.put("Advanced", new ArrayList<Config>());
-        Configs.put("Usage", new ArrayList<Config>());
-        Configs.put("Developer", new ArrayList<Config>());
-        Configs.put("Hidden", new ArrayList<Config>());
-        Configs.put("Account Defaults", new ArrayList<Config>());
-        Configs.put("Domain Defaults", new ArrayList<Config>());
-        Configs.put("Project Defaults", new ArrayList<Config>());
-        Configs.put("Secure", new ArrayList<Config>());
-
-        // Add values into HashMap
-        for (Config c : Config.values()) {
-            String category = c.getCategory();
-            List<Config> currentConfigs = Configs.get(category);
-            currentConfigs.add(c);
-            Configs.put(category, currentConfigs);
-        }
-    }
-
-    private Config(String category, Class<?> componentClass, Class<?> type, String name, String defaultValue, String description, String range) {
-        _category = category;
-        _componentClass = componentClass;
-        _type = type;
-        _name = name;
-        _defaultValue = defaultValue;
-        _description = description;
-        _range = range;
-        _scope = ConfigKey.Scope.Global.toString();
-    }
-
-    public String getCategory() {
-        return _category;
-    }
-
-    public String key() {
-        return _name;
-    }
-
-    public String getDescription() {
-        return _description;
-    }
-
-    public String getDefaultValue() {
-        return _defaultValue;
-    }
-
-    public Class<?> getType() {
-        return _type;
-    }
-
-    public String getScope() {
-        return _scope;
-    }
-
-    public String getComponent() {
-        if (_componentClass == ManagementServer.class) {
-            return "management-server";
-        } else if (_componentClass == AgentManager.class) {
-            return "AgentManager";
-        } else if (_componentClass == UserVmManager.class) {
-            return "UserVmManager";
-        } else if (_componentClass == HighAvailabilityManager.class) {
-            return "HighAvailabilityManager";
-        } else if (_componentClass == StoragePoolAllocator.class) {
-            return "StorageAllocator";
-        } else if (_componentClass == NetworkOrchestrationService.class) {
-            return "NetworkManager";
-        } else if (_componentClass == StorageManager.class) {
-            return "StorageManager";
-        } else if (_componentClass == TemplateManager.class) {
-            return "TemplateManager";
-        } else if (_componentClass == VpcManager.class) {
-            return "VpcManager";
-        } else if (_componentClass == SnapshotManager.class) {
-            return "SnapshotManager";
-        } else if (_componentClass == VMSnapshotManager.class) {
-            return "VMSnapshotManager";
-        } else {
-            return "none";
-        }
-    }
-
-    public String getRange() {
-        return _range;
-    }
-
-    @Override
-    public String toString() {
-        return _name;
-    }
-
-    public static List<Config> getConfigs(String category) {
-        return Configs.get(category);
-    }
-
-    public static Config getConfig(String name) {
-        List<String> categories = getCategories();
-        for (String category : categories) {
-            List<Config> currentList = getConfigs(category);
-            for (Config c : currentList) {
-                if (c.key().equals(name)) {
-                    return c;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public static List<String> getCategories() {
-        Object[] keys = Configs.keySet().toArray();
-        List<String> categories = new ArrayList<String>();
-        for (Object key : keys) {
-            categories.add((String)key);
-        }
-        return categories;
-    }
-}
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
deleted file mode 100755
index d023075..0000000
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ /dev/null
@@ -1,5693 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.configuration;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.google.common.collect.Sets;
-
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.AffinityGroupService;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
-import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
-import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
-import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
-import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
-import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
-import org.apache.cloudstack.config.Configuration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.region.PortableIp;
-import org.apache.cloudstack.region.PortableIpDao;
-import org.apache.cloudstack.region.PortableIpRange;
-import org.apache.cloudstack.region.PortableIpRangeDao;
-import org.apache.cloudstack.region.PortableIpRangeVO;
-import org.apache.cloudstack.region.PortableIpVO;
-import org.apache.cloudstack.region.Region;
-import org.apache.cloudstack.region.RegionVO;
-import org.apache.cloudstack.region.dao.RegionDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.AccountVlanMapVO;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.DataCenterLinkLocalIpAddressVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.DomainVlanMapVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.AccountVlanMapDao;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.dc.dao.DataCenterIpAddressDao;
-import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.dc.dao.DomainVlanMapDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeploymentClusterPlanner;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainDetailVO;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.domain.dao.DomainDetailsDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.gpu.GPU;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkService;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.org.Grouping;
-import com.cloud.org.Grouping.AllocationState;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectManager;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.server.ManagementService;
-import com.cloud.service.ServiceOfferingDetailsVO;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.test.IPRangeConfig;
-import com.cloud.user.Account;
-import com.cloud.user.AccountDetailVO;
-import com.cloud.user.AccountDetailsDao;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.NicIpAlias;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicIpAliasVO;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-
-public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
-    public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
-
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ConfigDepot _configDepot;
-    @Inject
-    HostPodDao _podDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    VolumeDao _volumeDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    AccountVlanMapDao _accountVlanMapDao;
-    @Inject
-    DomainVlanMapDao _domainVlanMapDao;
-    @Inject
-    PodVlanMapDao _podVlanMapDao;
-    @Inject
-    DataCenterDao _zoneDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-    @Inject
-    DiskOfferingDao _diskOfferingDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    IPAddressDao _publicIpAddressDao;
-    @Inject
-    DataCenterIpAddressDao _privateIpAddressDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkService _networkSvc;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    ClusterDao _clusterDao;
-    @Inject
-    AlertManager _alertMgr;
-    List<SecurityChecker> _secChecker;
-
-    @Inject
-    CapacityDao _capacityDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    ProjectManager _projectMgr;
-    @Inject
-    DataStoreManager _dataStoreMgr;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOffServiceMapDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _trafficTypeDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    UserDao _userDao;
-    @Inject
-    PortableIpRangeDao _portableIpRangeDao;
-    @Inject
-    RegionDao _regionDao;
-    @Inject
-    PortableIpDao _portableIpDao;
-    @Inject
-    ConfigurationServer _configServer;
-    @Inject
-    DataCenterDetailsDao _dcDetailsDao;
-    @Inject
-    ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject
-    AccountDetailsDao _accountDetailsDao;
-    @Inject
-    DomainDetailsDao _domainDetailsDao;
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    NicIpAliasDao _nicIpAliasDao;
-    @Inject
-    public ManagementService _mgr;
-    @Inject
-    DedicatedResourceDao _dedicatedDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    AffinityGroupDao _affinityGroupDao;
-    @Inject
-    AffinityGroupService _affinityGroupService;
-    @Inject
-    StorageManager _storageManager;
-    @Inject
-    ImageStoreDao _imageStoreDao;
-    @Inject
-    ImageStoreDetailsDao _imageStoreDetailsDao;
-    @Inject
-    MessageBus messageBus;
-
-
-    // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
-    @Inject
-    protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao;
-
-    private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.getDefaultValue());
-    private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue());
-    private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$";
-    protected Set<String> configValuesForValidation;
-    private Set<String> weightBasedParametersForValidation;
-    private Set<String> overprovisioningFactorsForValidation;
-
-    public static final ConfigKey<Boolean> SystemVMUseLocalStorage = new ConfigKey<Boolean>(Boolean.class, "system.vm.use.local.storage", "Advanced", "false",
-            "Indicates whether to use local storage pools or shared storage pools for system VMs.", false, ConfigKey.Scope.Zone, null);
-
-    private static final String DefaultForSystemVmsForPodIpRange = "0";
-    private static final String DefaultVlanForPodIpRange = Vlan.UNTAGGED.toString();
-
-    private static final Set<Provider> VPC_ONLY_PROVIDERS = Sets.newHashSet(Provider.VPCVirtualRouter, Provider.JuniperContrailVpcRouter, Provider.InternalLbVm);
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        final String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key());
-        _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, Integer.parseInt(Config.MaxVolumeSize.getDefaultValue()));
-
-        final String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key());
-        _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue()));
-
-        populateConfigValuesForValidationSet();
-        weightBasedParametersForValidation();
-        overProvisioningFactorsForValidation();
-        return true;
-    }
-
-    private void populateConfigValuesForValidationSet() {
-        configValuesForValidation = new HashSet<String>();
-        configValuesForValidation.add("event.purge.interval");
-        configValuesForValidation.add("account.cleanup.interval");
-        configValuesForValidation.add("alert.wait");
-        configValuesForValidation.add("consoleproxy.capacityscan.interval");
-        configValuesForValidation.add("expunge.interval");
-        configValuesForValidation.add("host.stats.interval");
-        configValuesForValidation.add("investigate.retry.interval");
-        configValuesForValidation.add("migrate.retry.interval");
-        configValuesForValidation.add("network.gc.interval");
-        configValuesForValidation.add("ping.interval");
-        configValuesForValidation.add("snapshot.poll.interval");
-        configValuesForValidation.add("stop.retry.interval");
-        configValuesForValidation.add("storage.stats.interval");
-        configValuesForValidation.add("storage.cleanup.interval");
-        configValuesForValidation.add("wait");
-        configValuesForValidation.add("xenserver.heartbeat.interval");
-        configValuesForValidation.add("xenserver.heartbeat.timeout");
-        configValuesForValidation.add("ovm3.heartbeat.interval");
-        configValuesForValidation.add("ovm3.heartbeat.timeout");
-        configValuesForValidation.add("incorrect.login.attempts.allowed");
-        configValuesForValidation.add("vm.password.length");
-        configValuesForValidation.add("externaldhcp.vmip.retrieval.interval");
-        configValuesForValidation.add("externaldhcp.vmip.max.retry");
-        configValuesForValidation.add("externaldhcp.vmipFetch.threadPool.max");
-        configValuesForValidation.add("remote.access.vpn.psk.length");
-    }
-
-    private void weightBasedParametersForValidation() {
-        weightBasedParametersForValidation = new HashSet<String>();
-        weightBasedParametersForValidation.add(AlertManager.CPUCapacityThreshold.key());
-        weightBasedParametersForValidation.add(AlertManager.StorageAllocatedCapacityThreshold.key());
-        weightBasedParametersForValidation.add(AlertManager.StorageCapacityThreshold.key());
-        weightBasedParametersForValidation.add(AlertManager.MemoryCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.PublicIpCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.PrivateIpCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.SecondaryStorageCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.VlanCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.DirectNetworkPublicIpCapacityThreshold.key());
-        weightBasedParametersForValidation.add(Config.LocalStorageCapacityThreshold.key());
-        weightBasedParametersForValidation.add(CapacityManager.StorageAllocatedCapacityDisableThreshold.key());
-        weightBasedParametersForValidation.add(CapacityManager.StorageCapacityDisableThreshold.key());
-        weightBasedParametersForValidation.add(DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.key());
-        weightBasedParametersForValidation.add(DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.key());
-        weightBasedParametersForValidation.add(Config.AgentLoadThreshold.key());
-        weightBasedParametersForValidation.add(Config.VmUserDispersionWeight.key());
-
-    }
-
-    private void overProvisioningFactorsForValidation() {
-        overprovisioningFactorsForValidation = new HashSet<String>();
-        overprovisioningFactorsForValidation.add(CapacityManager.MemOverprovisioningFactor.key());
-        overprovisioningFactorsForValidation.add(CapacityManager.CpuOverprovisioningFactor.key());
-        overprovisioningFactorsForValidation.add(CapacityManager.StorageOverprovisioningFactor.key());
-    }
-
-    @Override
-    public boolean start() {
-
-        // TODO : this may not be a good place to do integrity check here, we
-        // put it here as we need _alertMgr to be properly
-        // configured
-        // before we can use it
-
-        // As it is so common for people to forget about configuring
-        // management.network.cidr,
-        final String mgtCidr = _configDao.getValue(Config.ManagementNetwork.key());
-        if (mgtCidr == null || mgtCidr.trim().isEmpty()) {
-            final String[] localCidrs = NetUtils.getLocalCidrs();
-            if (localCidrs != null && localCidrs.length > 0) {
-                s_logger.warn("Management network CIDR is not configured originally. Set it default to " + localCidrs[0]);
-
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to "
-                        + localCidrs[0], "");
-                _configDao.update(Config.ManagementNetwork.key(), Config.ManagementNetwork.getCategory(), localCidrs[0]);
-            } else {
-                s_logger.warn("Management network CIDR is not properly configured and we are not able to find a default setting");
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0),
-                        "Management network CIDR is not properly configured and we are not able to find a default setting", "");
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    @DB
-    public String updateConfiguration(final long userId, final String name, final String category, final String value, final String scope, final Long resourceId) {
-        final String validationMsg = validateConfigurationValue(name, value, scope);
-
-        if (validationMsg != null) {
-            s_logger.error("Invalid configuration option, name: " + name + ", value:" + value);
-            throw new InvalidParameterValueException(validationMsg);
-        }
-
-        // If scope of the parameter is given then it needs to be updated in the
-        // corresponding details table,
-        // if scope is mentioned as global or not mentioned then it is normal
-        // global parameter updation
-        if (scope != null && !scope.isEmpty() && !ConfigKey.Scope.Global.toString().equalsIgnoreCase(scope)) {
-            switch (ConfigKey.Scope.valueOf(scope)) {
-            case Zone:
-                final DataCenterVO zone = _zoneDao.findById(resourceId);
-                if (zone == null) {
-                    throw new InvalidParameterValueException("unable to find zone by id " + resourceId);
-                }
-                _dcDetailsDao.addDetail(resourceId, name, value, true);
-                break;
-            case Cluster:
-                final ClusterVO cluster = _clusterDao.findById(resourceId);
-                if (cluster == null) {
-                    throw new InvalidParameterValueException("unable to find cluster by id " + resourceId);
-                }
-                ClusterDetailsVO clusterDetailsVO = _clusterDetailsDao.findDetail(resourceId, name);
-                if (clusterDetailsVO == null) {
-                    clusterDetailsVO = new ClusterDetailsVO(resourceId, name, value);
-                    _clusterDetailsDao.persist(clusterDetailsVO);
-                } else {
-                    clusterDetailsVO.setValue(value);
-                    _clusterDetailsDao.update(clusterDetailsVO.getId(), clusterDetailsVO);
-                }
-                break;
-
-            case StoragePool:
-                final StoragePoolVO pool = _storagePoolDao.findById(resourceId);
-                if (pool == null) {
-                    throw new InvalidParameterValueException("unable to find storage pool by id " + resourceId);
-                }
-                if(name.equals(CapacityManager.StorageOverprovisioningFactor.key())) {
-                    if(!pool.getPoolType().supportsOverProvisioning() ) {
-                        throw new InvalidParameterValueException("Unable to update  storage pool with id " + resourceId + ". Overprovision not supported for " + pool.getPoolType());
-                    }
-                }
-
-                _storagePoolDetailsDao.addDetail(resourceId, name, value, true);
-
-                break;
-
-            case Account:
-                final AccountVO account = _accountDao.findById(resourceId);
-                if (account == null) {
-                    throw new InvalidParameterValueException("unable to find account by id " + resourceId);
-                }
-                AccountDetailVO accountDetailVO = _accountDetailsDao.findDetail(resourceId, name);
-                if (accountDetailVO == null) {
-                    accountDetailVO = new AccountDetailVO(resourceId, name, value);
-                    _accountDetailsDao.persist(accountDetailVO);
-                } else {
-                    accountDetailVO.setValue(value);
-                    _accountDetailsDao.update(accountDetailVO.getId(), accountDetailVO);
-                }
-                break;
-
-            case ImageStore:
-                final ImageStoreVO imgStore = _imageStoreDao.findById(resourceId);
-                Preconditions.checkState(imgStore != null);
-                _imageStoreDetailsDao.addDetail(resourceId, name, value, true);
-                break;
-
-            case Domain:
-                final DomainVO domain = _domainDao.findById(resourceId);
-                if (domain == null) {
-                    throw new InvalidParameterValueException("unable to find domain by id " + resourceId);
-                }
-                DomainDetailVO domainDetailVO = _domainDetailsDao.findDetail(resourceId, name);
-                if (domainDetailVO == null) {
-                    domainDetailVO = new DomainDetailVO(resourceId, name, value);
-                    _domainDetailsDao.persist(domainDetailVO);
-                } else {
-                    domainDetailVO.setValue(value);
-                    _domainDetailsDao.update(domainDetailVO.getId(), domainDetailVO);
-                }
-                break;
-
-            default:
-                throw new InvalidParameterValueException("Scope provided is invalid");
-            }
-            return value;
-        }
-
-        // Execute all updates in a single transaction
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-
-        if (!_configDao.update(name, category, value)) {
-            s_logger.error("Failed to update configuration option, name: " + name + ", value:" + value);
-            throw new CloudRuntimeException("Failed to update configuration value. Please contact Cloud Support.");
-        }
-
-        PreparedStatement pstmt = null;
-        if (Config.XenServerGuestNetwork.key().equalsIgnoreCase(name)) {
-            final String sql = "update host_details set value=? where name=?";
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setString(1, value);
-                pstmt.setString(2, "guest.network.device");
-
-                pstmt.executeUpdate();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to update guest.network.device in host_details due to exception ", e);
-            }
-        } else if (Config.XenServerPrivateNetwork.key().equalsIgnoreCase(name)) {
-            final String sql = "update host_details set value=? where name=?";
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setString(1, value);
-                pstmt.setString(2, "private.network.device");
-
-                pstmt.executeUpdate();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to update private.network.device in host_details due to exception ", e);
-            }
-        } else if (Config.XenServerPublicNetwork.key().equalsIgnoreCase(name)) {
-            final String sql = "update host_details set value=? where name=?";
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setString(1, value);
-                pstmt.setString(2, "public.network.device");
-
-                pstmt.executeUpdate();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to update public.network.device in host_details due to exception ", e);
-            }
-        } else if (Config.XenServerStorageNetwork1.key().equalsIgnoreCase(name)) {
-            final String sql = "update host_details set value=? where name=?";
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setString(1, value);
-                pstmt.setString(2, "storage.network.device1");
-
-                pstmt.executeUpdate();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to update storage.network.device1 in host_details due to exception ", e);
-            }
-        } else if (Config.XenServerStorageNetwork2.key().equals(name)) {
-            final String sql = "update host_details set value=? where name=?";
-            try {
-                pstmt = txn.prepareAutoCloseStatement(sql);
-                pstmt.setString(1, value);
-                pstmt.setString(2, "storage.network.device2");
-
-                pstmt.executeUpdate();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to update storage.network.device2 in host_details due to exception ", e);
-            }
-        } else if (Config.SecStorageSecureCopyCert.key().equalsIgnoreCase(name)) {
-            //FIXME - Ideally there should be a listener model to listen to global config changes and be able to take action gracefully.
-            //Expire the download urls
-            final String sqlTemplate = "update template_store_ref set download_url_created=?";
-            final String sqlVolume = "update volume_store_ref set download_url_created=?";
-            try {
-                // Change for templates
-                pstmt = txn.prepareAutoCloseStatement(sqlTemplate);
-                pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time.
-                pstmt.executeUpdate();
-                // Change for volumes
-                pstmt = txn.prepareAutoCloseStatement(sqlVolume);
-                pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time.
-                pstmt.executeUpdate();
-                // Cleanup the download urls
-                _storageManager.cleanupDownloadUrls();
-            } catch (final Throwable e) {
-                throw new CloudRuntimeException("Failed to clean up download URLs in template_store_ref or volume_store_ref due to exception ", e);
-            }
-        }
-
-        txn.commit();
-        messageBus.publish(_name, EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, PublishScope.GLOBAL, name);
-        return _configDao.getValue(name);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, eventDescription = "updating configuration")
-    public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidParameterValueException {
-        final Long userId = CallContext.current().getCallingUserId();
-        final String name = cmd.getCfgName();
-        String value = cmd.getValue();
-        final Long zoneId = cmd.getZoneId();
-        final Long clusterId = cmd.getClusterId();
-        final Long storagepoolId = cmd.getStoragepoolId();
-        final Long accountId = cmd.getAccountId();
-        final Long imageStoreId = cmd.getImageStoreId();
-        final Long domainId = cmd.getDomainId();
-        CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : value == null ? "" : value));
-        // check if config value exists
-        final ConfigurationVO config = _configDao.findByName(name);
-        String catergory = null;
-
-        // FIX ME - All configuration parameters are not moved from config.java to configKey
-        if (config == null) {
-            if (_configDepot.get(name) == null) {
-                s_logger.warn("Probably the component manager where configuration variable " + name + " is defined needs to implement Configurable interface");
-                throw new InvalidParameterValueException("Config parameter with name " + name + " doesn't exist");
-            }
-            catergory = _configDepot.get(name).category();
-        } else {
-            catergory = config.getCategory();
-        }
-
-        if (value == null) {
-            return _configDao.findByName(name);
-        }
-
-        value = value.trim();
-
-        if (value.isEmpty() || value.equals("null")) {
-            value = null;
-        }
-
-        String scope = null;
-        Long id = null;
-        int paramCountCheck = 0;
-
-        if (zoneId != null) {
-            scope = ConfigKey.Scope.Zone.toString();
-            id = zoneId;
-            paramCountCheck++;
-        }
-        if (clusterId != null) {
-            scope = ConfigKey.Scope.Cluster.toString();
-            id = clusterId;
-            paramCountCheck++;
-        }
-        if (accountId != null) {
-            scope = ConfigKey.Scope.Account.toString();
-            id = accountId;
-            paramCountCheck++;
-        }
-        if (domainId != null) {
-            scope = ConfigKey.Scope.Domain.toString();
-            id = domainId;
-            paramCountCheck++;
-        }
-        if (storagepoolId != null) {
-            scope = ConfigKey.Scope.StoragePool.toString();
-            id = storagepoolId;
-            paramCountCheck++;
-        }
-        if (imageStoreId != null) {
-            scope = ConfigKey.Scope.ImageStore.toString();
-            id = imageStoreId;
-            paramCountCheck++;
-        }
-
-        if (paramCountCheck > 1) {
-            throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
-        }
-
-        final String updatedValue = updateConfiguration(userId, name, catergory, value, scope, id);
-        if (value == null && updatedValue == null || updatedValue.equalsIgnoreCase(value)) {
-            return _configDao.findByName(name);
-        } else {
-            throw new CloudRuntimeException("Unable to update configuration parameter " + name);
-        }
-    }
-
-    private String validateConfigurationValue(final String name, String value, final String scope) {
-
-        final ConfigurationVO cfg = _configDao.findByName(name);
-        if (cfg == null) {
-            s_logger.error("Missing configuration variable " + name + " in configuration table");
-            return "Invalid configuration variable.";
-        }
-
-        final String configScope = cfg.getScope();
-        if (scope != null) {
-            if (!configScope.contains(scope)) {
-                s_logger.error("Invalid scope id provided for the parameter " + name);
-                return "Invalid scope id provided for the parameter " + name;
-            }
-        }
-        Class<?> type = null;
-        final Config c = Config.getConfig(name);
-        if (c == null) {
-            s_logger.warn("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot");
-            final ConfigKey<?> configKey = _configDepot.get(name);
-            if(configKey == null) {
-                s_logger.warn("Did not find configuration " + name + " in ConfigDepot too.");
-                return null;
-            }
-            type = configKey.type();
-        } else {
-            type = c.getType();
-        }
-        //no need to validate further if a
-        //config can have null value.
-        String errMsg = null;
-        try {
-            if (type.equals(Integer.class)) {
-                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid integer value for parameter " + name;
-                Integer.parseInt(value);
-            } else if (type.equals(Float.class)) {
-                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid float value for parameter " + name;
-                Float.parseFloat(value);
-            } else if (type.equals(Long.class)) {
-                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid long value for parameter " + name;
-                Long.parseLong(value);
-            }
-        } catch (final Exception e) {
-            // catching generic exception as some throws NullPointerException and some throws NumberFormatExcpeion
-            s_logger.error(errMsg);
-            return errMsg;
-        }
-
-        if (value == null) {
-            if (type.equals(Boolean.class)) {
-                return "Please enter either 'true' or 'false'.";
-            }
-            if (overprovisioningFactorsForValidation.contains(name)) {
-                final String msg = "value cannot be null for the parameter " + name;
-                s_logger.error(msg);
-                return msg;
-            }
-            return null;
-        }
-
-        value = value.trim();
-        try {
-            if (overprovisioningFactorsForValidation.contains(name) && Float.parseFloat(value) < 1f) {
-                final String msg = name + " should be greater than or equal to 1";
-                s_logger.error(msg);
-                throw new InvalidParameterValueException(msg);
-            }
-        } catch (final NumberFormatException e) {
-            final String msg = "There was an error trying to parse the float value for: " + name;
-            s_logger.error(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-
-        if (type.equals(Boolean.class)) {
-            if (!(value.equals("true") || value.equals("false"))) {
-                s_logger.error("Configuration variable " + name + " is expecting true or false instead of " + value);
-                return "Please enter either 'true' or 'false'.";
-            }
-            return null;
-        }
-
-        if (type.equals(Integer.class) && NetworkModel.MACIdentifier.key().equalsIgnoreCase(name)) {
-            try {
-                final int val = Integer.parseInt(value);
-                //The value need to be between 0 to 255 because the mac generation needs a value of 8 bit
-                //0 value is considered as disable.
-                if(val < 0 || val > 255){
-                    throw new InvalidParameterValueException(name+" value should be between 0 and 255. 0 value will disable this feature");
-                }
-            } catch (final NumberFormatException e) {
-                s_logger.error("There was an error trying to parse the integer value for:" + name);
-                throw new InvalidParameterValueException("There was an error trying to parse the integer value for:" + name);
-            }
-        }
-
-        if (type.equals(Integer.class) && configValuesForValidation.contains(name)) {
-            try {
-                final int val = Integer.parseInt(value);
-                if (val <= 0) {
-                    throw new InvalidParameterValueException("Please enter a positive value for the configuration parameter:" + name);
-                }
-                if ("vm.password.length".equalsIgnoreCase(name) && val < 6) {
-                    throw new InvalidParameterValueException("Please enter a value greater than 5 for the configuration parameter:" + name);
-                }
-                if ("remote.access.vpn.psk.length".equalsIgnoreCase(name)) {
-                    if (val < 8) {
-                        throw new InvalidParameterValueException("Please enter a value greater than 7 for the configuration parameter:" + name);
-                    }
-                    if (val > 256) {
-                        throw new InvalidParameterValueException("Please enter a value less than 257 for the configuration parameter:" + name);
-                    }
-                }
-            } catch (final NumberFormatException e) {
-                s_logger.error("There was an error trying to parse the integer value for:" + name);
-                throw new InvalidParameterValueException("There was an error trying to parse the integer value for:" + name);
-            }
-        }
-
-        if (type.equals(Float.class)) {
-            try {
-                final Float val = Float.parseFloat(value);
-                if (weightBasedParametersForValidation.contains(name) && (val < 0f || val > 1f)) {
-                    throw new InvalidParameterValueException("Please enter a value between 0 and 1 for the configuration parameter: " + name);
-                }
-            } catch (final NumberFormatException e) {
-                s_logger.error("There was an error trying to parse the float value for:" + name);
-                throw new InvalidParameterValueException("There was an error trying to parse the float value for:" + name);
-            }
-        }
-
-        if(c == null ) {
-            //range validation has to be done per case basis, for now
-            //return in case of Configkey parameters
-            return null;
-        }
-
-        final String range = c.getRange();
-        if (range == null) {
-            return null;
-        }
-
-        if (type.equals(String.class)) {
-            if (range.equals("privateip")) {
-                try {
-                    if (!NetUtils.isSiteLocalAddress(value)) {
-                        s_logger.error("privateip range " + value + " is not a site local address for configuration variable " + name);
-                        return "Please enter a site local IP address.";
-                    }
-                } catch (final NullPointerException e) {
-                    s_logger.error("Error parsing ip address for " + name);
-                    throw new InvalidParameterValueException("Error parsing ip address");
-                }
-            } else if (range.equals("netmask")) {
-                if (!NetUtils.isValidIp4Netmask(value)) {
-                    s_logger.error("netmask " + value + " is not a valid net mask for configuration variable " + name);
-                    return "Please enter a valid netmask.";
-                }
-            } else if (range.equals("hypervisorList")) {
-                final String[] hypervisors = value.split(",");
-                if (hypervisors == null) {
-                    return "Please enter hypervisor list, separated by comma";
-                }
-                for (final String hypervisor : hypervisors) {
-                    if (HypervisorType.getType(hypervisor) == HypervisorType.Any || HypervisorType.getType(hypervisor) == HypervisorType.None) {
-                        return "Please enter a valid hypervisor type";
-                    }
-                }
-            } else if (range.equalsIgnoreCase("instanceName")) {
-                if (!NetUtils.verifyInstanceName(value)) {
-                    return "Instance name can not contain hyphen, space or plus sign";
-                }
-            } else if (range.equalsIgnoreCase("domainName")) {
-                String domainName = value;
-                if (value.startsWith("*")) {
-                    domainName = value.substring(2); //skip the "*."
-                }
-                //max length for FQDN is 253 + 2, code adds xxx-xxx-xxx-xxx to domain name when creating URL
-                if (domainName.length() >= 238 || !domainName.matches(DOMAIN_NAME_PATTERN)) {
-                    return "Please enter a valid string for domain name, prefixed with '*.' if applicable";
-                }
-            } else if (range.equals("routes")) {
-                final String[] routes = value.split(",");
-                for (final String route : routes) {
-                    if (route != null) {
-                        final String routeToVerify = route.trim();
-                        if (!NetUtils.isValidIp4Cidr(routeToVerify)) {
-                            throw new InvalidParameterValueException("Invalid value for blacklisted route: " + route + ". Valid format is list"
-                                    + " of cidrs separated by coma. Example: 10.1.1.0/24,192.168.0.0/24");
-                        }
-                    }
-                }
-            } else {
-                final String[] options = range.split(",");
-                for (final String option : options) {
-                    if (option.trim().equalsIgnoreCase(value)) {
-                        return null;
-                    }
-                }
-                s_logger.error("configuration value for " + name + " is invalid");
-                return "Please enter : " + range;
-
-            }
-        } else if (type.equals(Integer.class)) {
-            final String[] options = range.split("-");
-            if (options.length != 2) {
-                final String msg = "configuration range " + range + " for " + name + " is invalid";
-                s_logger.error(msg);
-                return msg;
-            }
-            final int min = Integer.parseInt(options[0]);
-            final int max = Integer.parseInt(options[1]);
-            final int val = Integer.parseInt(value);
-            if (val < min || val > max) {
-                s_logger.error("configuration value for " + name + " is invalid");
-                return "Please enter : " + range;
-            }
-        }
-        return null;
-    }
-
-    private boolean podHasAllocatedPrivateIPs(final long podId) {
-        final HostPodVO pod = _podDao.findById(podId);
-        final int count = _privateIpAddressDao.countIPs(podId, pod.getDataCenterId(), true);
-        return count > 0;
-    }
-
-    protected void checkIfPodIsDeletable(final long podId) {
-        final HostPodVO pod = _podDao.findById(podId);
-
-        final String errorMsg = "The pod cannot be deleted because ";
-
-        // Check if there are allocated private IP addresses in the pod
-        if (_privateIpAddressDao.countIPs(podId, pod.getDataCenterId(), true) != 0) {
-            throw new CloudRuntimeException(errorMsg + "there are private IP addresses allocated in this pod.");
-        }
-
-        // Check if there are any non-removed volumes in the pod.
-        if (!_volumeDao.findByPod(podId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are storage volumes in this pod.");
-        }
-
-        // Check if there are any non-removed hosts in the pod.
-        if (!_hostDao.findByPodId(podId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are servers in this pod.");
-        }
-
-        // Check if there are any non-removed vms in the pod.
-        if (!_vmInstanceDao.listByPodId(podId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are virtual machines in this pod.");
-        }
-
-        // Check if there are any non-removed clusters in the pod.
-        if (!_clusterDao.listByPodId(podId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are clusters in this pod.");
-        }
-    }
-
-    private void checkPodAttributes(final long podId, final String podName, final long zoneId, final String gateway, final String cidr, final String startIp, final String endIp, final String allocationStateStr,
-            final boolean checkForDuplicates, final boolean skipGatewayOverlapCheck) {
-        if (checkForDuplicates) {
-            // Check if the pod already exists
-            if (validPod(podName, zoneId)) {
-                throw new InvalidParameterValueException("A pod with name: " + podName + " already exists in zone " + zoneId + ". Please specify a different pod name. ");
-            }
-        }
-
-        String cidrAddress;
-        long cidrSize;
-        // Get the individual cidrAddress and cidrSize values, if the CIDR is
-        // valid. If it's not valid, return an error.
-        if (NetUtils.isValidIp4Cidr(cidr)) {
-            cidrAddress = getCidrAddress(cidr);
-            cidrSize = getCidrSize(cidr);
-        } else {
-            throw new InvalidParameterValueException("Please enter a valid CIDR for pod: " + podName);
-        }
-
-        // Check if the IP range is valid
-        checkIpRange(startIp, endIp, cidrAddress, cidrSize);
-
-        // Check if the IP range overlaps with the public ip
-        if(!Strings.isNullOrEmpty(startIp)) {
-            checkOverlapPublicIpRange(zoneId, startIp, endIp);
-        }
-
-        // Check if the gateway is a valid IP address
-        if (!NetUtils.isValidIp4(gateway)) {
-            throw new InvalidParameterValueException("The gateway is not a valid IP address.");
-        }
-
-        // Check if the gateway is in the CIDR subnet
-        if (!NetUtils.getCidrSubNet(gateway, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-            throw new InvalidParameterValueException("The gateway is not in the CIDR subnet.");
-        }
-
-        // Don't allow gateway to overlap with start/endIp
-        if (!skipGatewayOverlapCheck) {
-            if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
-                throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
-            }
-        }
-
-        final String checkPodCIDRs = _configDao.getValue("check.pod.cidrs");
-        if (checkPodCIDRs == null || checkPodCIDRs.trim().isEmpty() || Boolean.parseBoolean(checkPodCIDRs)) {
-            checkPodCidrSubnets(zoneId, podId, cidr);
-        }
-
-        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
-            try {
-                Grouping.AllocationState.valueOf(allocationStateStr);
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationStateStr + "' to a supported state");
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public boolean deletePod(final DeletePodCmd cmd) {
-        final Long podId = cmd.getId();
-
-        // Make sure the pod exists
-        if (!validPod(podId)) {
-            throw new InvalidParameterValueException("A pod with ID: " + podId + " does not exist.");
-        }
-
-        checkIfPodIsDeletable(podId);
-
-        final HostPodVO pod = _podDao.findById(podId);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                // Delete private ip addresses for the pod if there are any
-                final List<DataCenterIpAddressVO> privateIps = _privateIpAddressDao.listByPodIdDcId(podId, pod.getDataCenterId());
-                if (!privateIps.isEmpty()) {
-                    if (!_privateIpAddressDao.deleteIpAddressByPod(podId)) {
-                        throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
-                    }
-                }
-
-                // Delete link local ip addresses for the pod
-                final List<DataCenterLinkLocalIpAddressVO> localIps = _linkLocalIpAllocDao.listByPodIdDcId(podId, pod.getDataCenterId());
-                if (!localIps.isEmpty()) {
-                    if (!_linkLocalIpAllocDao.deleteIpAddressByPod(podId)) {
-                        throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
-                    }
-                }
-
-                // Delete vlans associated with the pod
-                final List<? extends Vlan> vlans = _networkModel.listPodVlans(podId);
-                if (vlans != null && !vlans.isEmpty()) {
-                    for (final Vlan vlan : vlans) {
-                        _vlanDao.remove(vlan.getId());
-                    }
-                }
-
-                // Delete corresponding capacity records
-                _capacityDao.removeBy(null, null, podId, null, null);
-
-                // Delete the pod
-                if (!_podDao.remove(podId)) {
-                    throw new CloudRuntimeException("Failed to delete pod " + podId);
-                }
-
-                // remove from dedicated resources
-                final DedicatedResourceVO dr = _dedicatedDao.findByPodId(podId);
-                if (dr != null) {
-                    _dedicatedDao.remove(dr.getId());
-                }
-            }
-        });
-
-        return true;
-    }
-
-    /**
-     * Get vlan number from vlan uri
-     * @param vlan
-     * @return
-     */
-    protected String getVlanNumberFromUri(String vlan) {
-        URI uri;
-        try {
-            uri = new URI(vlan);
-            String vlanId = BroadcastDomainType.getValue(uri);
-            if (vlanId == null || !uri.getScheme().equalsIgnoreCase("vlan")) {
-                throw new CloudRuntimeException("Vlan parameter : " + vlan + " is not in valid format");
-            }
-            return vlanId;
-        } catch (URISyntaxException e) {
-            throw new CloudRuntimeException("Invalid vlan parameter: " + vlan + " can't get vlan number from it due to: " + e.getMessage());
-        }
-    }
-
-    @Override
-    @DB
-    public Pod createPodIpRange(final CreateManagementNetworkIpRangeCmd cmd) {
-
-        final Account account = CallContext.current().getCallingAccount();
-
-        if(!_accountMgr.isRootAdmin(account.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Calling account is not root admin: " + account.getId());
-        }
-
-        final long podId = cmd.getPodId();
-        final String gateway = cmd.getGateWay();
-        final String netmask = cmd.getNetmask();
-        final String startIp = cmd.getStartIp();
-        String endIp = cmd.getEndIp();
-        final boolean forSystemVms = cmd.isForSystemVms();
-        String vlan = cmd.getVlan();
-        if (!(Strings.isNullOrEmpty(vlan) || vlan.startsWith(BroadcastDomainType.Vlan.scheme()))) {
-            vlan = BroadcastDomainType.Vlan.toUri(vlan).toString();
-        }
-
-        String vlanNumberFromUri = getVlanNumberFromUri(vlan);
-        final Integer vlanId = vlanNumberFromUri.equals(Vlan.UNTAGGED.toString()) ? null : Integer.parseInt(vlanNumberFromUri);
-
-        final HostPodVO pod = _podDao.findById(podId);
-
-        if(pod == null) {
-            throw new InvalidParameterValueException("Unable to find pod by ID: " + podId);
-        }
-
-        final long zoneId = pod.getDataCenterId();
-
-        if(!NetUtils.isValidIp4(gateway)) {
-            throw new InvalidParameterValueException("The gateway IP address is invalid.");
-        }
-
-        if(!NetUtils.isValidIp4Netmask(netmask)) {
-            throw new InvalidParameterValueException("The netmask IP address is invalid.");
-        }
-
-        if(endIp == null) {
-            endIp = startIp;
-        }
-
-        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-
-        if(!NetUtils.isValidIp4Cidr(cidr)) {
-            throw new InvalidParameterValueException("The CIDR is invalid " + cidr);
-        }
-
-        final String cidrAddress = pod.getCidrAddress();
-        final long cidrSize = pod.getCidrSize();
-
-        // Because each pod has only one Gateway and Netmask.
-        if (!gateway.equals(pod.getGateway())) {
-            throw new InvalidParameterValueException("Multiple gateways for the POD: " + pod.getId() + " are not allowed. The Gateway should be same as the existing Gateway " + pod.getGateway());
-        }
-
-        if (!netmask.equals(NetUtils.getCidrNetmask(cidrSize))) {
-            throw new InvalidParameterValueException("Multiple subnets for the POD: " + pod.getId() + " are not allowed. The Netmask should be same as the existing Netmask " + NetUtils.getCidrNetmask(cidrSize));
-        }
-
-        // Check if the IP range is valid.
-        checkIpRange(startIp, endIp, cidrAddress, cidrSize);
-
-        // Check if the IP range overlaps with the public ip.
-        checkOverlapPublicIpRange(zoneId, startIp, endIp);
-
-        // Check if the gateway is in the CIDR subnet
-        if (!NetUtils.getCidrSubNet(gateway, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-            throw new InvalidParameterValueException("The gateway is not in the CIDR subnet.");
-        }
-
-        if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
-            throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
-        }
-
-        final String[] existingPodIpRanges = pod.getDescription().split(",");
-
-        for(String podIpRange: existingPodIpRanges) {
-            final String[] existingPodIpRange = podIpRange.split("-");
-
-            if (existingPodIpRange.length > 1) {
-                if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
-                    continue;
-                }
-                // Check if the range overlaps with any existing range.
-                if (NetUtils.ipRangesOverlap(startIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
-                    throw new InvalidParameterValueException("The new range overlaps with existing range. Please add a mutually exclusive range.");
-                }
-            }
-        }
-
-        try {
-            final String endIpFinal = endIp;
-
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    String ipRange = pod.getDescription();
-
-                    /*
-                     * POD Description is refactored to:
-                     * <START_IP>-<END_IP>-<FOR_SYSTEM_VMS>-<VLAN>,<START_IP>-<END_IP>-<FOR_SYSTEM_VMS>-<VLAN>,...
-                    */
-                    String range = startIp + "-" + endIpFinal + "-" + (forSystemVms ? "1" : "0") + "-" + (vlanId == null ? DefaultVlanForPodIpRange : vlanId);
-                    if(ipRange != null && !ipRange.isEmpty())
-                        ipRange += ("," + range);
-                    else
-                        ipRange = (range);
-
-                    pod.setDescription(ipRange);
-
-                    HostPodVO lock = null;
-                    try {
-                        lock = _podDao.acquireInLockTable(podId);
-
-                        if (lock == null) {
-                            String msg = "Unable to acquire lock on table to update the ip range of POD: " + pod.getName() + ", Creation failed.";
-                            s_logger.warn(msg);
-                            throw new CloudRuntimeException(msg);
-                        }
-
-                        _podDao.update(podId, pod);
-                    } finally {
-                        if (lock != null) {
-                            _podDao.releaseFromLockTable(podId);
-                        }
-                    }
-
-                    _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, forSystemVms, vlanId);
-                }
-            });
-        } catch (final Exception e) {
-            s_logger.error("Unable to create Pod IP range due to " + e.getMessage(), e);
-            throw new CloudRuntimeException("Failed to create Pod IP range. Please contact Cloud Support.");
-        }
-
-        return pod;
-    }
-
-    @Override
-    @DB
-    public void deletePodIpRange(final DeleteManagementNetworkIpRangeCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
-        final long podId = cmd.getPodId();
-        final String startIp = cmd.getStartIp();
-        final String endIp = cmd.getEndIp();
-        String vlan = cmd.getVlan();
-        try {
-            vlan = BroadcastDomainType.getValue(vlan);
-        } catch (URISyntaxException e) {
-            throw new CloudRuntimeException("Incorrect vlan " + vlan);
-        }
-
-        final HostPodVO pod = _podDao.findById(podId);
-
-        if(pod == null) {
-            throw new InvalidParameterValueException("Unable to find pod by id " + podId);
-        }
-
-        if (startIp == null || !NetUtils.isValidIp4(startIp)) {
-            throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address.");
-        }
-
-        if (endIp == null || !NetUtils.isValidIp4(endIp)) {
-            throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address.");
-        }
-
-        if (NetUtils.ip2Long(startIp) > NetUtils.ip2Long(endIp)) {
-            throw new InvalidParameterValueException("The start IP address must have a lower value than the end IP address.");
-        }
-
-        for(long ipAddr = NetUtils.ip2Long(startIp); ipAddr <= NetUtils.ip2Long(endIp); ipAddr++) {
-            if(_privateIpAddressDao.countIpAddressUsage(NetUtils.long2Ip(ipAddr), podId, pod.getDataCenterId(), true) > 0) {
-                throw new CloudRuntimeException("Some IPs of the range has been allocated, so it cannot be deleted.");
-            }
-        }
-
-        final String[] existingPodIpRanges = pod.getDescription().split(",");
-
-        if(existingPodIpRanges.length == 0) {
-            throw new InvalidParameterValueException("The IP range cannot be found. As the existing IP range is empty.");
-        }
-
-        final String[] newPodIpRanges = new String[existingPodIpRanges.length-1];
-        int index = existingPodIpRanges.length-2;
-        boolean foundRange = false;
-
-        for(String podIpRange: existingPodIpRanges) {
-            final String[] existingPodIpRange = podIpRange.split("-");
-
-            if(existingPodIpRange.length > 1) {
-                if (startIp.equals(existingPodIpRange[0]) && endIp.equals(existingPodIpRange[1]) &&
-                        (existingPodIpRange.length > 3 ? vlan.equals(existingPodIpRange[3]) : vlan.equals(DefaultVlanForPodIpRange))) {
-                    foundRange = true;
-                } else if (index >= 0) {
-                    newPodIpRanges[index--] = (existingPodIpRange[0] + "-" + existingPodIpRange[1] + "-" +
-                            (existingPodIpRange.length > 2 ? existingPodIpRange[2] : DefaultForSystemVmsForPodIpRange) + "-" +
-                            (existingPodIpRange.length > 3 ? existingPodIpRange[3] : DefaultVlanForPodIpRange));
-                }
-            }
-        }
-
-        if(!foundRange) {
-            throw new InvalidParameterValueException("The input IP range: " + startIp + "-" + endIp + " of pod: " + podId + "is not present. Please input an existing range.");
-        }
-
-        final StringBuilder newPodIpRange = new StringBuilder();
-        boolean first = true;
-        for (String podIpRange : newPodIpRanges) {
-            if (first)
-                first = false;
-            else
-                newPodIpRange.append(",");
-
-            newPodIpRange.append(podIpRange);
-        }
-
-        try {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    pod.setDescription(newPodIpRange.toString());
-
-                    HostPodVO lock = null;
-                    try {
-                        lock = _podDao.acquireInLockTable(podId);
-
-                        if (lock == null) {
-                            String msg = "Unable to acquire lock on table to update the ip range of POD: " + pod.getName() + ", Deletion failed.";
-                            s_logger.warn(msg);
-                            throw new CloudRuntimeException(msg);
-                        }
-
-                        _podDao.update(podId, pod);
-                    } finally {
-                        if (lock != null) {
-                            _podDao.releaseFromLockTable(podId);
-                        }
-                    }
-
-                    for(long ipAddr = NetUtils.ip2Long(startIp); ipAddr <= NetUtils.ip2Long(endIp); ipAddr++) {
-                        if (!_privateIpAddressDao.deleteIpAddressByPodDc(NetUtils.long2Ip(ipAddr), podId, pod.getDataCenterId())) {
-                            throw new CloudRuntimeException("Failed to cleanup private ip address: " + NetUtils.long2Ip(ipAddr) + " of Pod: " + podId + " DC: " + pod.getDataCenterId());
-                        }
-                    }
-                }
-            });
-        } catch (final Exception e) {
-            s_logger.error("Unable to delete Pod " + podId + "IP range due to " + e.getMessage(), e);
-            throw new CloudRuntimeException("Failed to delete Pod " + podId + "IP range. Please contact Cloud Support.");
-        }
-    }
-
-    @Override
-    public Pod editPod(final UpdatePodCmd cmd) {
-        return editPod(cmd.getId(), cmd.getPodName(), null, null, cmd.getGateway(), cmd.getNetmask(), cmd.getAllocationState());
-    }
-
-    @Override
-    @DB
-    public Pod editPod(final long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr) {
-
-        // verify parameters
-        final HostPodVO pod = _podDao.findById(id);
-
-        if (pod == null) {
-            throw new InvalidParameterValueException("Unable to find pod by id " + id);
-        }
-
-        // If the gateway, CIDR, private IP range is being changed, check if the
-        // pod has allocated private IP addresses
-        if (podHasAllocatedPrivateIPs(id)) {
-
-            if (!Strings.isNullOrEmpty(netmask)) {
-                final long newCidr = NetUtils.getCidrSize(netmask);
-                final long oldCidr = pod.getCidrSize();
-
-                if (newCidr > oldCidr) {
-                    throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
-                }
-            }
-        }
-
-        if (gateway == null) {
-            gateway = pod.getGateway();
-        }
-
-        if (netmask == null) {
-            netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
-        }
-
-        final String oldPodName = pod.getName();
-        if (name == null) {
-            name = oldPodName;
-        }
-
-        if (allocationStateStr == null) {
-            allocationStateStr = pod.getAllocationState().toString();
-        }
-
-        // Verify pod's attributes
-        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-        final boolean checkForDuplicates = !oldPodName.equals(name);
-        checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, true);
-
-        // Valid check is already done in checkPodAttributes method.
-        final String cidrAddress = getCidrAddress(cidr);
-        final long cidrSize = getCidrSize(cidr);
-
-        // Check if start IP and end IP of all the ranges lie in the CIDR subnet.
-        final String[] existingPodIpRanges = pod.getDescription().split(",");
-
-        for(String podIpRange: existingPodIpRanges) {
-            final String[] existingPodIpRange = podIpRange.split("-");
-
-            if (existingPodIpRange.length > 1) {
-                if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
-                    continue;
-                }
-
-                if (!NetUtils.getCidrSubNet(existingPodIpRange[0], cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-                    throw new InvalidParameterValueException("The start address of the some IP range is not in the CIDR subnet.");
-                }
-
-                if (!NetUtils.getCidrSubNet(existingPodIpRange[1], cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-                    throw new InvalidParameterValueException("The end address of the some IP range is not in the CIDR subnet.");
-                }
-
-                if (NetUtils.ipRangesOverlap(existingPodIpRange[0], existingPodIpRange[1], gateway, gateway)) {
-                    throw new InvalidParameterValueException("The gateway shouldn't overlap some start/end ip addresses");
-                }
-            }
-        }
-
-        try {
-            final String allocationStateStrFinal = allocationStateStr;
-            final String nameFinal = name;
-            final String gatewayFinal = gateway;
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    final long zoneId = pod.getDataCenterId();
-
-                    pod.setName(nameFinal);
-                    pod.setDataCenterId(zoneId);
-                    pod.setGateway(gatewayFinal);
-                    pod.setCidrAddress(getCidrAddress(cidr));
-                    pod.setCidrSize(getCidrSize(cidr));
-
-                    Grouping.AllocationState allocationState = null;
-                    if (allocationStateStrFinal != null && !allocationStateStrFinal.isEmpty()) {
-                        allocationState = Grouping.AllocationState.valueOf(allocationStateStrFinal);
-                        pod.setAllocationState(allocationState);
-                    }
-
-                    _podDao.update(id, pod);
-                }
-            });
-        } catch (final Exception e) {
-            s_logger.error("Unable to edit pod due to " + e.getMessage(), e);
-            throw new CloudRuntimeException("Failed to edit pod. Please contact Cloud Support.");
-        }
-
-        return pod;
-    }
-
-    @Override
-    public Pod createPod(final long zoneId, final String name, final String startIp, final String endIp, final String gateway, final String netmask, String allocationState) {
-        // Check if the gateway is a valid IP address
-        if (!NetUtils.isValidIp4(gateway)) {
-            throw new InvalidParameterValueException("The gateway is invalid");
-        }
-
-        if (!NetUtils.isValidIp4Netmask(netmask)) {
-            throw new InvalidParameterValueException("The netmask is invalid");
-        }
-
-        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-
-        final Long userId = CallContext.current().getCallingUserId();
-
-        if (allocationState == null) {
-            allocationState = Grouping.AllocationState.Enabled.toString();
-        }
-        return createPod(userId.longValue(), name, zoneId, gateway, cidr, startIp, endIp, allocationState, false);
-    }
-
-    @Override
-    @DB
-    public HostPodVO createPod(final long userId, final String podName, final long zoneId, final String gateway, final String cidr, final String startIp, String endIp, final String allocationStateStr,
-            final boolean skipGatewayOverlapCheck) {
-
-        // Check if the zone is valid
-        if (!validZone(zoneId)) {
-            throw new InvalidParameterValueException("Please specify a valid zone.");
-        }
-
-        // Check if zone is disabled
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        final Account account = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
-                && !_accountMgr.isRootAdmin(account.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-        }
-
-        final String cidrAddress = getCidrAddress(cidr);
-        final int cidrSize = getCidrSize(cidr);
-
-        // endIp is an optional parameter; if not specified - default it to the
-        // end ip of the pod's cidr
-        if (!Strings.isNullOrEmpty(startIp)) {
-            if (endIp == null) {
-                endIp = NetUtils.getIpRangeEndIpFromCidr(cidrAddress, cidrSize);
-            }
-        }
-
-        // Validate new pod settings
-        checkPodAttributes(-1, podName, zoneId, gateway, cidr, startIp, endIp, allocationStateStr, true, skipGatewayOverlapCheck);
-
-        // Create the new pod in the database
-        String ipRange;
-
-        if (!Strings.isNullOrEmpty(startIp)) {
-            ipRange = startIp + "-" + endIp + "-" + DefaultForSystemVmsForPodIpRange + "-" + DefaultVlanForPodIpRange;
-        } else {
-            throw new InvalidParameterValueException("Start ip is required parameter");
-        }
-
-        final HostPodVO podFinal = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange);
-
-        Grouping.AllocationState allocationState = null;
-        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
-            allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
-            podFinal.setAllocationState(allocationState);
-        }
-
-        final String endIpFinal = endIp;
-        return Transaction.execute(new TransactionCallback<HostPodVO>() {
-            @Override
-            public HostPodVO doInTransaction(final TransactionStatus status) {
-
-                final HostPodVO pod = _podDao.persist(podFinal);
-
-                if (!Strings.isNullOrEmpty(startIp)) {
-                    _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, false, null);
-                }
-
-                final String[] linkLocalIpRanges = getLinkLocalIPRange();
-                if (linkLocalIpRanges != null) {
-                    _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
-                }
-
-                return pod;
-            }
-        });
-    }
-
-    @DB
-    protected void checkIfZoneIsDeletable(final long zoneId) {
-        final String errorMsg = "The zone cannot be deleted because ";
-
-
-        // Check if there are any non-removed hosts in the zone.
-        if (!_hostDao.listByDataCenterId(zoneId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are servers in this zone.");
-        }
-
-        // Check if there are any non-removed pods in the zone.
-        if (!_podDao.listByDataCenterId(zoneId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are pods in this zone.");
-        }
-
-        // Check if there are allocated private IP addresses in the zone.
-        if (_privateIpAddressDao.countIPs(zoneId, true) != 0) {
-            throw new CloudRuntimeException(errorMsg + "there are private IP addresses allocated in this zone.");
-        }
-
-        // Check if there are allocated public IP addresses in the zone.
-        if (_publicIpAddressDao.countIPs(zoneId, true) != 0) {
-            throw new CloudRuntimeException(errorMsg + "there are public IP addresses allocated in this zone.");
-        }
-
-        // Check if there are any non-removed vms in the zone.
-        if (!_vmInstanceDao.listByZoneId(zoneId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are virtual machines in this zone.");
-        }
-
-        // Check if there are any non-removed volumes in the zone.
-        if (!_volumeDao.findByDc(zoneId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are storage volumes in this zone.");
-        }
-
-        // Check if there are any non-removed physical networks in the zone.
-        if (!_physicalNetworkDao.listByZone(zoneId).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are physical networks in this zone.");
-        }
-
-        //check if there are any secondary stores attached to the zone
-        if(!_imageStoreDao.findByScope(new ZoneScope(zoneId)).isEmpty()) {
-            throw new CloudRuntimeException(errorMsg + "there are Secondary storages in this zone");
-        }
-
-        // Check if there are any non-removed VMware datacenters in the zone.
-        //if (_vmwareDatacenterZoneMapDao.findByZoneId(zoneId) != null) {
-        //    throw new CloudRuntimeException(errorMsg + "there are VMware datacenters in this zone.");
-        //}
-    }
-
-    private void checkZoneParameters(final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final boolean checkForDuplicates, final Long domainId,
-            final String allocationStateStr, final String ip6Dns1, final String ip6Dns2) {
-        if (checkForDuplicates) {
-            // Check if a zone with the specified name already exists
-            if (validZone(zoneName)) {
-                throw new InvalidParameterValueException("A zone with that name already exists. Please specify a unique zone name.");
-            }
-        }
-
-        // check if valid domain
-        if (domainId != null) {
-            final DomainVO domain = _domainDao.findById(domainId);
-
-            if (domain == null) {
-                throw new InvalidParameterValueException("Please specify a valid domain id");
-            }
-        }
-
-        // Check IP validity for DNS addresses
-        // Empty strings is a valid input -- hence the length check
-        if (dns1 != null && dns1.length() > 0 && !NetUtils.isValidIp4(dns1)) {
-            throw new InvalidParameterValueException("Please enter a valid IP address for DNS1");
-        }
-
-        if (dns2 != null && dns2.length() > 0 && !NetUtils.isValidIp4(dns2)) {
-            throw new InvalidParameterValueException("Please enter a valid IP address for DNS2");
-        }
-
-        if (internalDns1 != null && internalDns1.length() > 0 && !NetUtils.isValidIp4(internalDns1)) {
-            throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS1");
-        }
-
-        if (internalDns2 != null && internalDns2.length() > 0 && !NetUtils.isValidIp4(internalDns2)) {
-            throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS2");
-        }
-
-        if (ip6Dns1 != null && ip6Dns1.length() > 0 && !NetUtils.isValidIp6(ip6Dns1)) {
-            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS1");
-        }
-
-        if (ip6Dns2 != null && ip6Dns2.length() > 0 && !NetUtils.isValidIp6(ip6Dns2)) {
-            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS2");
-        }
-
-        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
-            try {
-                Grouping.AllocationState.valueOf(allocationStateStr);
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationStateStr + "' to a supported state");
-            }
-        }
-    }
-
-    private void checkIpRange(final String startIp, final String endIp, final String cidrAddress, final long cidrSize) {
-        //Checking not null for start IP as well. Previously we assumed to be not null always.
-        //But the check is required for the change in updatePod API.
-        if (!Strings.isNullOrEmpty(startIp) && !NetUtils.isValidIp4(startIp)) {
-            throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address.");
-        }
-
-        if (!Strings.isNullOrEmpty(endIp) && !NetUtils.isValidIp4(endIp)) {
-            throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address.");
-        }
-
-        //Not null check is required for the change in updatePod API.
-        if (!Strings.isNullOrEmpty(startIp) && !NetUtils.getCidrSubNet(startIp, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-            throw new InvalidParameterValueException("The start address of the IP range is not in the CIDR subnet.");
-        }
-
-        if (!Strings.isNullOrEmpty(endIp) && !NetUtils.getCidrSubNet(endIp, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
-            throw new InvalidParameterValueException("The end address of the IP range is not in the CIDR subnet.");
-        }
-
-        if (!Strings.isNullOrEmpty(endIp) && NetUtils.ip2Long(startIp) > NetUtils.ip2Long(endIp)) {
-            throw new InvalidParameterValueException("The start IP address must have a lower value than the end IP address.");
-        }
-
-    }
-
-    private void checkOverlapPublicIpRange(final Long zoneId, final String startIp, final String endIp) {
-        final long privateStartIp = NetUtils.ip2Long(startIp);
-        final long privateEndIp = NetUtils.ip2Long(endIp);
-
-        final List<IPAddressVO> existingPublicIPs = _publicIpAddressDao.listByDcId(zoneId);
-        for (final IPAddressVO publicIPVO : existingPublicIPs) {
-            final long publicIP = NetUtils.ip2Long(publicIPVO.getAddress().addr());
-            if (publicIP >= privateStartIp && publicIP <= privateEndIp) {
-                throw new InvalidParameterValueException("The Start IP and endIP address range overlap with Public IP :" + publicIPVO.getAddress().addr());
-            }
-        }
-    }
-
-    private void checkOverlapPrivateIpRange(final Long zoneId, final String startIp, final String endIp) {
-
-        final List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
-        for (final HostPodVO hostPod : podsInZone) {
-            final String[] existingPodIpRanges = hostPod.getDescription().split(",");
-
-            for(String podIpRange: existingPodIpRanges) {
-                final String[] existingPodIpRange = podIpRange.split("-");
-
-                if (existingPodIpRange.length > 1) {
-                    if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
-                        continue;
-                    }
-
-                    if (NetUtils.ipRangesOverlap(startIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
-                        throw new InvalidParameterValueException("The Start IP and EndIP address range overlap with private IP :" + existingPodIpRange[0] + ":" + existingPodIpRange[1]);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_ZONE_DELETE, eventDescription = "deleting zone", async = false)
-    public boolean deleteZone(final DeleteZoneCmd cmd) {
-
-        final Long zoneId = cmd.getId();
-
-        // Make sure the zone exists
-        if (!validZone(zoneId)) {
-            throw new InvalidParameterValueException("A zone with ID: " + zoneId + " does not exist.");
-        }
-
-        checkIfZoneIsDeletable(zoneId);
-
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(final TransactionStatus status) {
-                // delete vlans for this zone
-                final List<VlanVO> vlans = _vlanDao.listByZone(zoneId);
-                for (final VlanVO vlan : vlans) {
-                    _vlanDao.remove(vlan.getId());
-                }
-
-                final boolean success = _zoneDao.remove(zoneId);
-
-                if (success) {
-                    // delete all capacity records for the zone
-                    _capacityDao.removeBy(null, zoneId, null, null, null);
-                    // remove from dedicated resources
-                    final DedicatedResourceVO dr = _dedicatedDao.findByZoneId(zoneId);
-                    if (dr != null) {
-                        _dedicatedDao.remove(dr.getId());
-                        // find the group associated and check if there are any more
-                        // resources under that group
-                        final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(dr.getAffinityGroupId());
-                        if (resourcesInGroup.isEmpty()) {
-                            // delete the group
-                            _affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null, null);
-                        }
-                    }
-                }
-
-                return success;
-            }
-        });
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "editing zone", async = false)
-    public DataCenter editZone(final UpdateZoneCmd cmd) {
-        // Parameter validation as from execute() method in V1
-        final Long zoneId = cmd.getId();
-        String zoneName = cmd.getZoneName();
-        String dns1 = cmd.getDns1();
-        String dns2 = cmd.getDns2();
-        String ip6Dns1 = cmd.getIp6Dns1();
-        String ip6Dns2 = cmd.getIp6Dns2();
-        String internalDns1 = cmd.getInternalDns1();
-        String internalDns2 = cmd.getInternalDns2();
-        String guestCidr = cmd.getGuestCidrAddress();
-        final List<String> dnsSearchOrder = cmd.getDnsSearchOrder();
-        final Boolean isPublic = cmd.isPublic();
-        final String allocationStateStr = cmd.getAllocationState();
-        final String dhcpProvider = cmd.getDhcpProvider();
-        final Map<?, ?> detailsMap = cmd.getDetails();
-        final String networkDomain = cmd.getDomain();
-        final Boolean localStorageEnabled = cmd.getLocalStorageEnabled();
-
-        final Map<String, String> newDetails = new HashMap<String, String>();
-        if (detailsMap != null) {
-            final Collection<?> zoneDetailsCollection = detailsMap.values();
-            final Iterator<?> iter = zoneDetailsCollection.iterator();
-            while (iter.hasNext()) {
-                final HashMap<?, ?> detail = (HashMap<?, ?>)iter.next();
-                final String key = (String)detail.get("key");
-                final String value = (String)detail.get("value");
-                if (key == null || value == null) {
-                    throw new InvalidParameterValueException(
-                            "Invalid Zone Detail specified, fields 'key' and 'value' cannot be null, please specify details in the form:  details[0].key=XXX&details[0].value=YYY");
-                }
-                newDetails.put(key, value);
-            }
-        }
-
-        // add the domain prefix list to details if not null
-        if (dnsSearchOrder != null) {
-            for (final String dom : dnsSearchOrder) {
-                if (!NetUtils.verifyDomainName(dom)) {
-                    throw new InvalidParameterValueException(
-                            "Invalid network domain suffixes. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                    + "and the hyphen ('-'); can't start or end with \"-\"");
-                }
-            }
-            newDetails.put(ZoneConfig.DnsSearchOrder.getName(), StringUtils.join(dnsSearchOrder, ","));
-        }
-
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("unable to find zone by id " + zoneId);
-        }
-
-        if (zoneName == null) {
-            zoneName = zone.getName();
-        }
-
-        if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
-            throw new InvalidParameterValueException("Please enter a valid guest cidr");
-        }
-
-        // Make sure the zone exists
-        if (!validZone(zoneId)) {
-            throw new InvalidParameterValueException("A zone with ID: " + zoneId + " does not exist.");
-        }
-
-        final String oldZoneName = zone.getName();
-
-        if (zoneName == null) {
-            zoneName = oldZoneName;
-        }
-
-        if (dns1 == null) {
-            dns1 = zone.getDns1();
-        }
-
-        if (dns2 == null) {
-            dns2 = zone.getDns2();
-        }
-
-        if (ip6Dns1 == null) {
-            ip6Dns1 = zone.getIp6Dns1();
-        }
-
-        if (ip6Dns2 == null) {
-            ip6Dns2 = zone.getIp6Dns2();
-        }
-
-        if (internalDns1 == null) {
-            internalDns1 = zone.getInternalDns1();
-        }
-
-        if (internalDns2 == null) {
-            internalDns2 = zone.getInternalDns2();
-        }
-
-        if (guestCidr == null) {
-            guestCidr = zone.getGuestNetworkCidr();
-        }
-
-        // validate network domain
-        if (networkDomain != null && !networkDomain.isEmpty()) {
-            if (!NetUtils.verifyDomainName(networkDomain)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-        }
-
-        final boolean checkForDuplicates = !zoneName.equals(oldZoneName);
-        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, checkForDuplicates, null, allocationStateStr, ip6Dns1, ip6Dns2);// not allowing updating
-        // domain associated with
-        // a zone, once created
-
-        zone.setName(zoneName);
-        zone.setDns1(dns1);
-        zone.setDns2(dns2);
-        zone.setIp6Dns1(ip6Dns1);
-        zone.setIp6Dns2(ip6Dns2);
-        zone.setInternalDns1(internalDns1);
-        zone.setInternalDns2(internalDns2);
-        zone.setGuestNetworkCidr(guestCidr);
-        if (localStorageEnabled != null) {
-            zone.setLocalStorageEnabled(localStorageEnabled.booleanValue());
-        }
-
-        if (networkDomain != null) {
-            if (networkDomain.isEmpty()) {
-                zone.setDomain(null);
-            } else {
-                zone.setDomain(networkDomain);
-            }
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                final Map<String, String> updatedDetails = new HashMap<String, String>();
-                _zoneDao.loadDetails(zone);
-                if (zone.getDetails() != null) {
-                    updatedDetails.putAll(zone.getDetails());
-                }
-                updatedDetails.putAll(newDetails);
-                zone.setDetails(updatedDetails);
-
-                if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
-                    final Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
-
-                    if (allocationState == Grouping.AllocationState.Enabled) {
-                        // check if zone has necessary trafficTypes before enabling
-                        try {
-                            PhysicalNetwork mgmtPhyNetwork;
-                            // zone should have a physical network with management
-                            // traffiType
-                            mgmtPhyNetwork = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Management);
-                            if (NetworkType.Advanced == zone.getNetworkType() && !zone.isSecurityGroupEnabled()) {
-                                // advanced zone without SG should have a physical
-                                // network with public Thpe
-                                _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public);
-                            }
-
-                            try {
-                                _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage);
-                            } catch (final InvalidParameterValueException noStorage) {
-                                final PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
-                                _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(),
-                                        mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(),
-                                        mgmtTraffic.getHypervNetworkLabel(), mgmtTraffic.getOvm3NetworkLabel());
-                                s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId()
-                                        + " with same configure of management traffic type");
-                            }
-                        } catch (final InvalidParameterValueException ex) {
-                            throw new InvalidParameterValueException("Cannot enable this Zone since: " + ex.getMessage());
-                        }
-                    }
-                    zone.setAllocationState(allocationState);
-                }
-
-                if (dhcpProvider != null) {
-                    zone.setDhcpProvider(dhcpProvider);
-                }
-
-                // update a private zone to public; not vice versa
-                if (isPublic != null && isPublic) {
-                    zone.setDomainId(null);
-                    zone.setDomain(null);
-
-                    // release the dedication for this zone
-                    final DedicatedResourceVO resource = _dedicatedDao.findByZoneId(zoneId);
-                    Long resourceId = null;
-                    if (resource != null) {
-                        resourceId = resource.getId();
-                        if (!_dedicatedDao.remove(resourceId)) {
-                            throw new CloudRuntimeException("Failed to delete dedicated Zone Resource " + resourceId);
-                        }
-                        // find the group associated and check if there are any more
-                        // resources under that group
-                        final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
-                        if (resourcesInGroup.isEmpty()) {
-                            // delete the group
-                            _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
-                        }
-                    }
-                }
-
-                if (!_zoneDao.update(zoneId, zone)) {
-                    throw new CloudRuntimeException("Failed to edit zone. Please contact Cloud Support.");
-                }
-            }
-        });
-
-        return zone;
-    }
-
-    @Override
-    @DB
-    public DataCenterVO createZone(final long userId, final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final String guestCidr, final String domain,
-            final Long domainId, final NetworkType zoneType, final String allocationStateStr, final String networkDomain, final boolean isSecurityGroupEnabled, final boolean isLocalStorageEnabled,
-            final String ip6Dns1, final String ip6Dns2) {
-
-        // checking the following params outside checkzoneparams method as we do
-        // not use these params for updatezone
-        // hence the method below is generic to check for common params
-        if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
-            throw new InvalidParameterValueException("Please enter a valid guest cidr");
-        }
-
-        // Validate network domain
-        if (networkDomain != null) {
-            if (!NetUtils.verifyDomainName(networkDomain)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-        }
-
-        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, true, domainId, allocationStateStr, ip6Dns1, ip6Dns2);
-
-        final byte[] bytes = (zoneName + System.currentTimeMillis()).getBytes();
-        final String zoneToken = UUID.nameUUIDFromBytes(bytes).toString();
-
-        // Create the new zone in the database
-        final DataCenterVO zoneFinal = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain,
-                isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
-        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
-            final Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
-            zoneFinal.setAllocationState(allocationState);
-        } else {
-            // Zone will be disabled since 3.0. Admin should enable it after
-            // physical network and providers setup.
-            zoneFinal.setAllocationState(Grouping.AllocationState.Disabled);
-        }
-
-        return Transaction.execute(new TransactionCallback<DataCenterVO>() {
-            @Override
-            public DataCenterVO doInTransaction(final TransactionStatus status) {
-                final DataCenterVO zone = _zoneDao.persist(zoneFinal);
-                CallContext.current().putContextParameter(DataCenter.class, zone.getUuid());
-                if (domainId != null) {
-                    // zone is explicitly dedicated to this domain
-                    // create affinity group associated and dedicate the zone.
-                    final AffinityGroup group = createDedicatedAffinityGroup(null, domainId, null);
-                    final DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null, domainId, null, group.getId());
-                    _dedicatedDao.persist(dedicatedResource);
-                }
-
-                // Create default system networks
-                createDefaultSystemNetworks(zone.getId());
-
-                return zone;
-            }
-        });
-    }
-
-    private AffinityGroup createDedicatedAffinityGroup(String affinityGroupName, final Long domainId, final Long accountId) {
-        if (affinityGroupName == null) {
-            // default to a groupname with account/domain information
-            affinityGroupName = "ZoneDedicatedGrp-domain-" + domainId + (accountId != null ? "-acct-" + accountId : "");
-        }
-
-        AffinityGroup group = null;
-        String accountName = null;
-
-        if (accountId != null) {
-            final AccountVO account = _accountDao.findById(accountId);
-            accountName = account.getAccountName();
-
-            group = _affinityGroupDao.findByAccountAndName(accountId, affinityGroupName);
-            if (group != null) {
-                return group;
-            }
-        } else {
-            // domain level group
-            group = _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName);
-            if (group != null) {
-                return group;
-            }
-        }
-
-        group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
-
-        return group;
-
-    }
-
-    @Override
-    public void createDefaultSystemNetworks(final long zoneId) throws ConcurrentOperationException {
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        final String networkDomain = null;
-        // Create public, management, control and storage networks as a part of
-        // the zone creation
-        if (zone != null) {
-            final List<NetworkOfferingVO> ntwkOff = _networkOfferingDao.listSystemNetworkOfferings();
-
-            for (final NetworkOfferingVO offering : ntwkOff) {
-                final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null, null, null);
-                final NetworkVO userNetwork = new NetworkVO();
-
-                final Account systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
-
-                BroadcastDomainType broadcastDomainType = null;
-                if (offering.getTrafficType() == TrafficType.Management) {
-                    broadcastDomainType = BroadcastDomainType.Native;
-                } else if (offering.getTrafficType() == TrafficType.Control) {
-                    broadcastDomainType = BroadcastDomainType.LinkLocal;
-                } else if (offering.getTrafficType() == TrafficType.Public) {
-                    if (zone.getNetworkType() == NetworkType.Advanced && !zone.isSecurityGroupEnabled() || zone.getNetworkType() == NetworkType.Basic) {
-                        broadcastDomainType = BroadcastDomainType.Vlan;
-                    } else {
-                        continue; // so broadcastDomainType remains null! why have None/Undecided/UnKnown?
-                    }
-                } else if (offering.getTrafficType() == TrafficType.Guest) {
-                    continue;
-                }
-
-                userNetwork.setBroadcastDomainType(broadcastDomainType);
-                userNetwork.setNetworkDomain(networkDomain);
-                _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, Domain.ROOT_DOMAIN, null, null, null, true);
-            }
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ZONE_CREATE, eventDescription = "creating zone", async = false)
-    public DataCenter createZone(final CreateZoneCmd cmd) {
-        // grab parameters from the command
-        final Long userId = CallContext.current().getCallingUserId();
-        final String zoneName = cmd.getZoneName();
-        final String dns1 = cmd.getDns1();
-        final String dns2 = cmd.getDns2();
-        final String ip6Dns1 = cmd.getIp6Dns1();
-        final String ip6Dns2 = cmd.getIp6Dns2();
-        final String internalDns1 = cmd.getInternalDns1();
-        final String internalDns2 = cmd.getInternalDns2();
-        final String guestCidr = cmd.getGuestCidrAddress();
-        final Long domainId = cmd.getDomainId();
-        final String type = cmd.getNetworkType();
-        Boolean isBasic = false;
-        String allocationState = cmd.getAllocationState();
-        final String networkDomain = cmd.getDomain();
-        boolean isSecurityGroupEnabled = cmd.getSecuritygroupenabled();
-        final boolean isLocalStorageEnabled = cmd.getLocalStorageEnabled();
-
-        if (allocationState == null) {
-            allocationState = Grouping.AllocationState.Disabled.toString();
-        }
-
-        if (!type.equalsIgnoreCase(NetworkType.Basic.toString()) && !type.equalsIgnoreCase(NetworkType.Advanced.toString())) {
-            throw new InvalidParameterValueException("Invalid zone type; only Advanced and Basic values are supported");
-        } else if (type.equalsIgnoreCase(NetworkType.Basic.toString())) {
-            isBasic = true;
-        }
-
-        final NetworkType zoneType = isBasic ? NetworkType.Basic : NetworkType.Advanced;
-
-        // error out when the parameter specified for Basic zone
-        if (zoneType == NetworkType.Basic && guestCidr != null) {
-            throw new InvalidParameterValueException("guestCidrAddress parameter is not supported for Basic zone");
-        }
-
-        DomainVO domainVO = null;
-
-        if (domainId != null) {
-            domainVO = _domainDao.findById(domainId);
-        }
-
-        if (zoneType == NetworkType.Basic) {
-            isSecurityGroupEnabled = true;
-        }
-
-        return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, allocationState,
-                networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering")
-    public ServiceOffering createServiceOffering(final CreateServiceOfferingCmd cmd) {
-        final Long userId = CallContext.current().getCallingUserId();
-
-        final String name = cmd.getServiceOfferingName();
-        if (name == null || name.length() == 0) {
-            throw new InvalidParameterValueException("Failed to create service offering: specify the name that has non-zero length");
-        }
-
-        final String displayText = cmd.getDisplayText();
-        if (displayText == null || displayText.length() == 0) {
-            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the display text that has non-zero length");
-        }
-
-        final Integer cpuNumber = cmd.getCpuNumber();
-        final Integer cpuSpeed = cmd.getCpuSpeed();
-        final Integer memory = cmd.getMemory();
-
-        //restricting the createserviceoffering to allow setting all or none of the dynamic parameters to null
-        if (cpuNumber == null || cpuSpeed == null || memory == null) {
-            if (cpuNumber != null || cpuSpeed != null || memory != null) {
-                throw new InvalidParameterValueException("For creating a custom compute offering cpu, cpu speed and memory all should be null");
-            }
-        }
-
-        if (cpuNumber != null && (cpuNumber.intValue() <= 0 || cpuNumber.longValue() > Integer.MAX_VALUE)) {
-            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu number value between 1 and " + Integer.MAX_VALUE);
-        }
-        if (cpuSpeed != null && (cpuSpeed.intValue() < 0 || cpuSpeed.longValue() > Integer.MAX_VALUE)) {
-            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu speed value between 0 and " + Integer.MAX_VALUE);
-        }
-        if (memory != null && (memory.intValue() < 32 || memory.longValue() > Integer.MAX_VALUE)) {
-            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the memory value between 32 and " + Integer.MAX_VALUE + " MB");
-        }
-
-        // check if valid domain
-        if (cmd.getDomainId() != null && _domainDao.findById(cmd.getDomainId()) == null) {
-            throw new InvalidParameterValueException("Please specify a valid domain id");
-        }
-
-        final Boolean offerHA = cmd.getOfferHa();
-
-        boolean localStorageRequired = false;
-        final String storageType = cmd.getStorageType();
-        if (storageType != null) {
-            if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.local.toString())) {
-                if(offerHA) {
-                    throw new InvalidParameterValueException("HA offering with local storage is not supported. ");
-                }
-                localStorageRequired = true;
-            } else if (!storageType.equalsIgnoreCase(ServiceOffering.StorageType.shared.toString())) {
-                throw new InvalidParameterValueException("Invalid storage type " + storageType + " specified, valid types are: 'local' and 'shared'");
-            }
-        }
-
-        final Boolean limitCpuUse = cmd.GetLimitCpuUse();
-        final Boolean volatileVm = cmd.getVolatileVm();
-
-        final String vmTypeString = cmd.getSystemVmType();
-        VirtualMachine.Type vmType = null;
-        boolean allowNetworkRate = false;
-
-        Boolean isCustomizedIops;
-
-        if (cmd.getIsSystem()) {
-            if (vmTypeString == null || VirtualMachine.Type.DomainRouter.toString().toLowerCase().equals(vmTypeString)) {
-                vmType = VirtualMachine.Type.DomainRouter;
-                allowNetworkRate = true;
-            } else if (VirtualMachine.Type.ConsoleProxy.toString().toLowerCase().equals(vmTypeString)) {
-                vmType = VirtualMachine.Type.ConsoleProxy;
-            } else if (VirtualMachine.Type.SecondaryStorageVm.toString().toLowerCase().equals(vmTypeString)) {
-                vmType = VirtualMachine.Type.SecondaryStorageVm;
-            } else if (VirtualMachine.Type.InternalLoadBalancerVm.toString().toLowerCase().equals(vmTypeString)) {
-                vmType = VirtualMachine.Type.InternalLoadBalancerVm;
-            } else {
-                throw new InvalidParameterValueException("Invalid systemVmType. Supported types are: " + VirtualMachine.Type.DomainRouter + ", " + VirtualMachine.Type.ConsoleProxy
-                        + ", " + VirtualMachine.Type.SecondaryStorageVm);
-            }
-
-            if (cmd.isCustomizedIops() != null) {
-                throw new InvalidParameterValueException("Customized IOPS is not a valid parameter for a system VM.");
-            }
-
-            isCustomizedIops = false;
-
-            if (cmd.getHypervisorSnapshotReserve() != null) {
-                throw new InvalidParameterValueException("Hypervisor snapshot reserve is not a valid parameter for a system VM.");
-            }
-        } else {
-            allowNetworkRate = true;
-            isCustomizedIops = cmd.isCustomizedIops();
-        }
-
-        if (cmd.getNetworkRate() != null) {
-            if(!allowNetworkRate) {
-                throw new InvalidParameterValueException("Network rate can be specified only for non-System offering and system offerings having \"domainrouter\" systemvmtype");
-            }
-            if(cmd.getNetworkRate().intValue() < 0) {
-                throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the network rate value more than 0");
-            }
-        }
-
-        if (cmd.getDeploymentPlanner() != null) {
-            final List<String> planners = _mgr.listDeploymentPlanners();
-            if (planners != null && !planners.isEmpty()) {
-                if (!planners.contains(cmd.getDeploymentPlanner())) {
-                    throw new InvalidParameterValueException("Invalid name for Deployment Planner specified, please use listDeploymentPlanners to get the valid set");
-                }
-            } else {
-                throw new InvalidParameterValueException("No deployment planners found");
-            }
-        }
-
-        return createServiceOffering(userId, cmd.getIsSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
-                cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), cmd.getHostTag(),
-                cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails(), isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
-                cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate(), cmd.getHypervisorSnapshotReserve());
-    }
-
-    protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
-            final String name, final Integer cpu, final Integer ramSize, final Integer speed, final String displayText, final String provisioningType, final boolean localStorageRequired,
-            final boolean offerHA, final boolean limitResourceUse, final boolean volatileVm,  String tags, final Long domainId, final String hostTag,
-            final Integer networkRate, final String deploymentPlanner, final Map<String, String> details, final Boolean isCustomizedIops, Long minIops, Long maxIops,
-            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate, final Integer hypervisorSnapshotReserve) {
-
-        // Check if user exists in the system
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (domainId == null) {
-                throw new InvalidParameterValueException("Unable to create public service offering by id " + userId + " because it is domain-admin");
-            }
-            if (tags != null || hostTag != null) {
-                throw new InvalidParameterValueException("Unable to create service offering with storage tags or host tags by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), domainId)) {
-                throw new InvalidParameterValueException("Unable to create service offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to create service offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);
-
-        tags = StringUtils.cleanupTags(tags);
-
-        ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA,
-                limitResourceUse, volatileVm, displayText, typedProvisioningType, localStorageRequired, false, tags, isSystem, vmType,
-                domainId, hostTag, deploymentPlanner);
-
-        if (isCustomizedIops != null) {
-            bytesReadRate = null;
-            bytesWriteRate = null;
-            iopsReadRate = null;
-            iopsWriteRate = null;
-
-            if (isCustomizedIops) {
-                minIops = null;
-                maxIops = null;
-            } else {
-                if (minIops == null && maxIops == null) {
-                    minIops = 0L;
-                    maxIops = 0L;
-                } else {
-                    if (minIops == null || minIops <= 0) {
-                        throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
-                    }
-
-                    if (maxIops == null) {
-                        maxIops = 0L;
-                    }
-
-                    if (minIops > maxIops) {
-                        throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
-                    }
-                }
-            }
-        } else {
-            minIops = null;
-            maxIops = null;
-        }
-
-        offering.setCustomizedIops(isCustomizedIops);
-        offering.setMinIops(minIops);
-        offering.setMaxIops(maxIops);
-
-        if (bytesReadRate != null && bytesReadRate > 0) {
-            offering.setBytesReadRate(bytesReadRate);
-        }
-        if (bytesWriteRate != null && bytesWriteRate > 0) {
-            offering.setBytesWriteRate(bytesWriteRate);
-        }
-        if (iopsReadRate != null && iopsReadRate > 0) {
-            offering.setIopsReadRate(iopsReadRate);
-        }
-        if (iopsWriteRate != null && iopsWriteRate > 0) {
-            offering.setIopsWriteRate(iopsWriteRate);
-        }
-
-        if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
-            throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
-        }
-
-        offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
-
-        List<ServiceOfferingDetailsVO> detailsVO = null;
-        if (details != null) {
-            // To have correct input, either both gpu card name and VGPU type should be passed or nothing should be passed.
-            // Use XOR condition to verify that.
-            final boolean entry1 = details.containsKey(GPU.Keys.pciDevice.toString());
-            final boolean entry2 = details.containsKey(GPU.Keys.vgpuType.toString());
-            if ((entry1 || entry2) && !(entry1 && entry2)) {
-                throw new InvalidParameterValueException("Please specify the pciDevice and vgpuType correctly.");
-            }
-            detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
-            for (final Entry<String, String> detailEntry : details.entrySet()) {
-                if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) {
-                    if (detailEntry.getValue() == null) {
-                        throw new InvalidParameterValueException("Please specify a GPU Card.");
-                    }
-                }
-                if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) {
-                    if (detailEntry.getValue() == null) {
-                        throw new InvalidParameterValueException("vGPUType value cannot be null");
-                    }
-                }
-                detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
-            }
-        }
-
-        if ((offering = _serviceOfferingDao.persist(offering)) != null) {
-            if (detailsVO != null && !detailsVO.isEmpty()) {
-                for (int index = 0; index < detailsVO.size(); index++) {
-                    detailsVO.get(index).setResourceId(offering.getId());
-                }
-                _serviceOfferingDetailsDao.saveDetails(detailsVO);
-            }
-            CallContext.current().setEventDetails("Service offering id=" + offering.getId());
-            return offering;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_EDIT, eventDescription = "updating service offering")
-    public ServiceOffering updateServiceOffering(final UpdateServiceOfferingCmd cmd) {
-        final String displayText = cmd.getDisplayText();
-        final Long id = cmd.getId();
-        final String name = cmd.getServiceOfferingName();
-        final Integer sortKey = cmd.getSortKey();
-        Long userId = CallContext.current().getCallingUserId();
-
-        if (userId == null) {
-            userId = Long.valueOf(User.UID_SYSTEM);
-        }
-
-        // Verify input parameters
-        final ServiceOffering offeringHandle = _entityMgr.findById(ServiceOffering.class, id);
-
-        if (offeringHandle == null) {
-            throw new InvalidParameterValueException("unable to find service offering " + id);
-        }
-
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (offeringHandle.getDomainId() == null) {
-                throw new InvalidParameterValueException("Unable to update public service offering by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), offeringHandle.getDomainId() )) {
-                throw new InvalidParameterValueException("Unable to update service offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to update service offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        final boolean updateNeeded = name != null || displayText != null || sortKey != null;
-        if (!updateNeeded) {
-            return _serviceOfferingDao.findById(id);
-        }
-
-        ServiceOfferingVO offering = _serviceOfferingDao.createForUpdate(id);
-
-        if (name != null) {
-            offering.setName(name);
-        }
-
-        if (displayText != null) {
-            offering.setDisplayText(displayText);
-        }
-
-        if (sortKey != null) {
-            offering.setSortKey(sortKey);
-        }
-
-        // Note: tag editing commented out for now; keeping the code intact,
-        // might need to re-enable in next releases
-        // if (tags != null)
-        // {
-        // if (tags.trim().isEmpty() && offeringHandle.getTags() == null)
-        // {
-        // //no new tags; no existing tags
-        // offering.setTagsArray(csvTagsToList(null));
-        // }
-        // else if (!tags.trim().isEmpty() && offeringHandle.getTags() != null)
-        // {
-        // //new tags + existing tags
-        // List<String> oldTags = csvTagsToList(offeringHandle.getTags());
-        // List<String> newTags = csvTagsToList(tags);
-        // oldTags.addAll(newTags);
-        // offering.setTagsArray(oldTags);
-        // }
-        // else if(!tags.trim().isEmpty())
-        // {
-        // //new tags; NO existing tags
-        // offering.setTagsArray(csvTagsToList(tags));
-        // }
-        // }
-
-        if (_serviceOfferingDao.update(id, offering)) {
-            offering = _serviceOfferingDao.findById(id);
-            CallContext.current().setEventDetails("Service offering id=" + offering.getId());
-            return offering;
-        } else {
-            return null;
-        }
-    }
-
-    protected DiskOfferingVO createDiskOffering(final Long userId, final Long domainId, final String name, final String description, final String provisioningType,
-            final Long numGibibytes, String tags, boolean isCustomized, final boolean localStorageRequired,
-            final boolean isDisplayOfferingEnabled, final Boolean isCustomizedIops, Long minIops, Long maxIops,
-            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate,
-            final Integer hypervisorSnapshotReserve) {
-        long diskSize = 0;// special case for custom disk offerings
-        if (numGibibytes != null && numGibibytes <= 0) {
-            throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
-        } else if (numGibibytes != null && numGibibytes > _maxVolumeSizeInGb) {
-            throw new InvalidParameterValueException("The maximum size for a disk is " + _maxVolumeSizeInGb + " Gb.");
-        }
-        final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);
-
-        if (numGibibytes != null) {
-            diskSize = numGibibytes * 1024 * 1024 * 1024;
-        }
-
-        if (diskSize == 0) {
-            isCustomized = true;
-        }
-
-        if (isCustomizedIops != null) {
-            bytesReadRate = null;
-            bytesWriteRate = null;
-            iopsReadRate = null;
-            iopsWriteRate = null;
-
-            if (isCustomizedIops) {
-                minIops = null;
-                maxIops = null;
-            } else {
-                if (minIops == null && maxIops == null) {
-                    minIops = 0L;
-                    maxIops = 0L;
-                } else {
-                    if (minIops == null || minIops <= 0) {
-                        throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
-                    }
-
-                    if (maxIops == null) {
-                        maxIops = 0L;
-                    }
-
-                    if (minIops > maxIops) {
-                        throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
-                    }
-                }
-            }
-        } else {
-            minIops = null;
-            maxIops = null;
-        }
-
-        // Check if user exists in the system
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (domainId == null) {
-                throw new InvalidParameterValueException("Unable to create public disk offering by id " + userId + " because it is domain-admin");
-            }
-            if (tags != null) {
-                throw new InvalidParameterValueException("Unable to create disk offering with storage tags by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), domainId)) {
-                throw new InvalidParameterValueException("Unable to create disk offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to create disk offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        tags = StringUtils.cleanupTags(tags);
-        final DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, typedProvisioningType, diskSize, tags, isCustomized,
-                isCustomizedIops, minIops, maxIops);
-        newDiskOffering.setUseLocalStorage(localStorageRequired);
-        newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled);
-
-        if (bytesReadRate != null && bytesReadRate > 0) {
-            newDiskOffering.setBytesReadRate(bytesReadRate);
-        }
-        if (bytesWriteRate != null && bytesWriteRate > 0) {
-            newDiskOffering.setBytesWriteRate(bytesWriteRate);
-        }
-        if (iopsReadRate != null && iopsReadRate > 0) {
-            newDiskOffering.setIopsReadRate(iopsReadRate);
-        }
-        if (iopsWriteRate != null && iopsWriteRate > 0) {
-            newDiskOffering.setIopsWriteRate(iopsWriteRate);
-        }
-
-        if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
-            throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
-        }
-
-        newDiskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
-
-        CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
-        final DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering);
-        if (offering != null) {
-            CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
-            return offering;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering")
-    public DiskOffering createDiskOffering(final CreateDiskOfferingCmd cmd) {
-        final String name = cmd.getOfferingName();
-        final String description = cmd.getDisplayText();
-        final String provisioningType = cmd.getProvisioningType();
-        final Long numGibibytes = cmd.getDiskSize();
-        final boolean isDisplayOfferingEnabled = cmd.getDisplayOffering() != null ? cmd.getDisplayOffering() : true;
-        final boolean isCustomized = cmd.isCustomized() != null ? cmd.isCustomized() : false; // false
-        // by
-        // default
-        final String tags = cmd.getTags();
-        // Long domainId = cmd.getDomainId() != null ? cmd.getDomainId() :
-        // Long.valueOf(DomainVO.ROOT_DOMAIN); // disk offering
-        // always gets created under the root domain.Bug # 6055 if not passed in
-        // cmd
-        final Long domainId = cmd.getDomainId();
-
-        if (!isCustomized && numGibibytes == null) {
-            throw new InvalidParameterValueException("Disksize is required for a non-customized disk offering");
-        }
-
-        if (isCustomized && numGibibytes != null) {
-            throw new InvalidParameterValueException("Disksize is not allowed for a customized disk offering");
-        }
-
-        boolean localStorageRequired = false;
-        final String storageType = cmd.getStorageType();
-        if (storageType != null) {
-            if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.local.toString())) {
-                localStorageRequired = true;
-            } else if (!storageType.equalsIgnoreCase(ServiceOffering.StorageType.shared.toString())) {
-                throw new InvalidParameterValueException("Invalid storage type " + storageType + " specified, valid types are: 'local' and 'shared'");
-            }
-        }
-
-        final Boolean isCustomizedIops = cmd.isCustomizedIops();
-        final Long minIops = cmd.getMinIops();
-        final Long maxIops = cmd.getMaxIops();
-        final Long bytesReadRate = cmd.getBytesReadRate();
-        final Long bytesWriteRate = cmd.getBytesWriteRate();
-        final Long iopsReadRate = cmd.getIopsReadRate();
-        final Long iopsWriteRate = cmd.getIopsWriteRate();
-        final Integer hypervisorSnapshotReserve = cmd.getHypervisorSnapshotReserve();
-
-        final Long userId = CallContext.current().getCallingUserId();
-        return createDiskOffering(userId, domainId, name, description, provisioningType, numGibibytes, tags, isCustomized,
-                localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops,
-                maxIops, bytesReadRate, bytesWriteRate, iopsReadRate, iopsWriteRate, hypervisorSnapshotReserve);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_EDIT, eventDescription = "updating disk offering")
-    public DiskOffering updateDiskOffering(final UpdateDiskOfferingCmd cmd) {
-        final Long diskOfferingId = cmd.getId();
-        final String name = cmd.getDiskOfferingName();
-        final String displayText = cmd.getDisplayText();
-        final Integer sortKey = cmd.getSortKey();
-        final Boolean displayDiskOffering = cmd.getDisplayOffering();
-
-        // Check if diskOffering exists
-        final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId);
-
-        if (diskOfferingHandle == null) {
-            throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId);
-        }
-
-        Long userId = CallContext.current().getCallingUserId();
-        if (userId == null) {
-            userId = Long.valueOf(User.UID_SYSTEM);
-        }
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (diskOfferingHandle.getDomainId() == null) {
-                throw new InvalidParameterValueException("Unable to update public disk offering by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), diskOfferingHandle.getDomainId() )) {
-                throw new InvalidParameterValueException("Unable to update disk offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to update disk offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        final boolean updateNeeded = name != null || displayText != null || sortKey != null || displayDiskOffering != null;
-        if (!updateNeeded) {
-            return _diskOfferingDao.findById(diskOfferingId);
-        }
-
-        final DiskOfferingVO diskOffering = _diskOfferingDao.createForUpdate(diskOfferingId);
-
-        if (name != null) {
-            diskOffering.setName(name);
-        }
-
-        if (displayText != null) {
-            diskOffering.setDisplayText(displayText);
-        }
-
-        if (sortKey != null) {
-            diskOffering.setSortKey(sortKey);
-        }
-
-        if (displayDiskOffering != null) {
-            diskOffering.setDisplayOffering(displayDiskOffering);
-        }
-
-        // Note: tag editing commented out for now;keeping the code intact,
-        // might need to re-enable in next releases
-        // if (tags != null)
-        // {
-        // if (tags.trim().isEmpty() && diskOfferingHandle.getTags() == null)
-        // {
-        // //no new tags; no existing tags
-        // diskOffering.setTagsArray(csvTagsToList(null));
-        // }
-        // else if (!tags.trim().isEmpty() && diskOfferingHandle.getTags() !=
-        // null)
-        // {
-        // //new tags + existing tags
-        // List<String> oldTags = csvTagsToList(diskOfferingHandle.getTags());
-        // List<String> newTags = csvTagsToList(tags);
-        // oldTags.addAll(newTags);
-        // diskOffering.setTagsArray(oldTags);
-        // }
-        // else if(!tags.trim().isEmpty())
-        // {
-        // //new tags; NO existing tags
-        // diskOffering.setTagsArray(csvTagsToList(tags));
-        // }
-        // }
-
-        if (_diskOfferingDao.update(diskOfferingId, diskOffering)) {
-            CallContext.current().setEventDetails("Disk offering id=" + diskOffering.getId());
-            return _diskOfferingDao.findById(diskOfferingId);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_DELETE, eventDescription = "deleting disk offering")
-    public boolean deleteDiskOffering(final DeleteDiskOfferingCmd cmd) {
-        final Long diskOfferingId = cmd.getId();
-
-        final DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
-
-        if (offering == null) {
-            throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId);
-        }
-
-        Long userId = CallContext.current().getCallingUserId();
-        if (userId == null) {
-            userId = Long.valueOf(User.UID_SYSTEM);
-        }
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (offering.getDomainId() == null) {
-                throw new InvalidParameterValueException("Unable to delete public disk offering by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), offering.getDomainId() )) {
-                throw new InvalidParameterValueException("Unable to delete disk offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to delete disk offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        offering.setState(DiskOffering.State.Inactive);
-        if (_diskOfferingDao.update(offering.getId(), offering)) {
-            CallContext.current().setEventDetails("Disk offering id=" + diskOfferingId);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_DELETE, eventDescription = "deleting service offering")
-    public boolean deleteServiceOffering(final DeleteServiceOfferingCmd cmd) {
-
-        final Long offeringId = cmd.getId();
-        Long userId = CallContext.current().getCallingUserId();
-
-        if (userId == null) {
-            userId = Long.valueOf(User.UID_SYSTEM);
-        }
-
-        // Verify service offering id
-        final ServiceOfferingVO offering = _serviceOfferingDao.findById(offeringId);
-        if (offering == null) {
-            throw new InvalidParameterValueException("unable to find service offering " + offeringId);
-        }
-
-        if (offering.getDefaultUse()) {
-            throw new InvalidParameterValueException("Default service offerings cannot be deleted");
-        }
-
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-        final Account account = _accountDao.findById(user.getAccountId());
-        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-            if (offering.getDomainId() == null) {
-                throw new InvalidParameterValueException("Unable to delete public service offering by id " + userId + " because it is domain-admin");
-            }
-            if (! _domainDao.isChildDomain(account.getDomainId(), offering.getDomainId() )) {
-                throw new InvalidParameterValueException("Unable to delete service offering by another domain admin with id " + userId);
-            }
-        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Unable to delete service offering by id " + userId + " because it is not root-admin or domain-admin");
-        }
-
-        offering.setState(DiskOffering.State.Inactive);
-        if (_serviceOfferingDao.update(offeringId, offering)) {
-            CallContext.current().setEventDetails("Service offering id=" + offeringId);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_CREATE, eventDescription = "creating vlan ip range", async = false)
-    public Vlan createVlanAndPublicIpRange(final CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
-    ResourceAllocationException {
-        Long zoneId = cmd.getZoneId();
-        final Long podId = cmd.getPodId();
-        final String startIP = cmd.getStartIp();
-        String endIP = cmd.getEndIp();
-        final String newVlanGateway = cmd.getGateway();
-        final String newVlanNetmask = cmd.getNetmask();
-        String vlanId = cmd.getVlan();
-        // TODO decide if we should be forgiving or demand a valid and complete URI
-        if (!(vlanId == null || "".equals(vlanId) || vlanId.startsWith(BroadcastDomainType.Vlan.scheme()))) {
-            vlanId = BroadcastDomainType.Vlan.toUri(vlanId).toString();
-        }
-        final Boolean forVirtualNetwork = cmd.isForVirtualNetwork();
-        Long networkId = cmd.getNetworkID();
-        Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        final String accountName = cmd.getAccountName();
-        final Long projectId = cmd.getProjectId();
-        final Long domainId = cmd.getDomainId();
-        final String startIPv6 = cmd.getStartIpv6();
-        String endIPv6 = cmd.getEndIpv6();
-        final String ip6Gateway = cmd.getIp6Gateway();
-        final String ip6Cidr = cmd.getIp6Cidr();
-        final Boolean forSystemVms = cmd.isForSystemVms();
-
-        Account vlanOwner = null;
-
-        if (forSystemVms && accountName != null) {
-            throw new InvalidParameterValueException("Account name should not be provided when ForSystemVMs is enabled");
-        }
-
-        final boolean ipv4 = startIP != null;
-        final boolean ipv6 = startIPv6 != null;
-
-        if (!ipv4 && !ipv6) {
-            throw new InvalidParameterValueException("StartIP or StartIPv6 is missing in the parameters!");
-        }
-
-        if (ipv4) {
-            // if end ip is not specified, default it to startIp
-            if (endIP == null && startIP != null) {
-                endIP = startIP;
-            }
-        }
-
-        if (ipv6) {
-            // if end ip is not specified, default it to startIp
-            if (endIPv6 == null && startIPv6 != null) {
-                endIPv6 = startIPv6;
-            }
-        }
-
-        if (projectId != null) {
-            if (accountName != null) {
-                throw new InvalidParameterValueException("Account and projectId are mutually exclusive");
-            }
-            final Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-            }
-
-            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
-            if (vlanOwner == null) {
-                throw new InvalidParameterValueException("Please specify a valid projectId");
-            }
-        }
-
-        Domain domain = null;
-        if (accountName != null && domainId != null) {
-            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
-            if (vlanOwner == null) {
-                throw new InvalidParameterValueException("Please specify a valid account.");
-            } else if (vlanOwner.getId() == Account.ACCOUNT_ID_SYSTEM) {
-                // by default vlan is dedicated to system account
-                vlanOwner = null;
-            }
-        } else if (domainId != null) {
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Please specify a valid domain id");
-            }
-        }
-
-        // Verify that network exists
-        Network network = null;
-        if (networkId != null) {
-            network = _networkDao.findById(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find network by id " + networkId);
-            } else {
-                zoneId = network.getDataCenterId();
-                physicalNetworkId = network.getPhysicalNetworkId();
-            }
-        } else if (ipv6) {
-            throw new InvalidParameterValueException("Only support IPv6 on extending existed network");
-        }
-
-        // Verify that zone exists
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        }
-
-        if (ipv6) {
-            if (network.getGuestType() != GuestType.Shared || zone.isSecurityGroupEnabled()) {
-                throw new InvalidParameterValueException("Only support IPv6 on extending existed share network without SG");
-            }
-        }
-        // verify that physical network exists
-        PhysicalNetworkVO pNtwk = null;
-        if (physicalNetworkId != null) {
-            pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
-            if (pNtwk == null) {
-                throw new InvalidParameterValueException("Unable to find Physical Network with id=" + physicalNetworkId);
-            }
-            if (zoneId == null) {
-                zoneId = pNtwk.getDataCenterId();
-            }
-        } else {
-            if (zoneId == null) {
-                throw new InvalidParameterValueException("");
-            }
-            // deduce physicalNetworkFrom Zone or Network.
-            if (network != null && network.getPhysicalNetworkId() != null) {
-                physicalNetworkId = network.getPhysicalNetworkId();
-            } else {
-                if (forVirtualNetwork) {
-                    // default physical network with public traffic in the zone
-                    physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId();
-                } else {
-                    if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
-                        // default physical network with guest traffic in the
-                        // zone
-                        physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId();
-                    } else if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
-                        if (zone.isSecurityGroupEnabled()) {
-                            physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId();
-                        } else {
-                            throw new InvalidParameterValueException("Physical Network Id is null, please provide the Network id for Direct vlan creation ");
-                        }
-                    }
-                }
-            }
-        }
-
-        // Check if zone is enabled
-        final Account caller = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
-                && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-        }
-
-        if (zone.isSecurityGroupEnabled() && zone.getNetworkType() != DataCenter.NetworkType.Basic && forVirtualNetwork) {
-            throw new InvalidParameterValueException("Can't add virtual ip range into a zone with security group enabled");
-        }
-
-        // If networkId is not specified, and vlan is Virtual or Direct
-        // Untagged, try to locate default networks
-        if (forVirtualNetwork) {
-            if (network == null) {
-                // find default public network in the zone
-                networkId = _networkModel.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId();
-                network = _networkModel.getNetwork(networkId);
-            } else if (network.getGuestType() != null || network.getTrafficType() != TrafficType.Public) {
-                throw new InvalidParameterValueException("Can't find Public network by id=" + networkId);
-            }
-        } else {
-            if (network == null) {
-                if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
-                    networkId = _networkModel.getExclusiveGuestNetwork(zoneId).getId();
-                    network = _networkModel.getNetwork(networkId);
-                } else {
-                    network = _networkModel.getNetworkWithSecurityGroupEnabled(zoneId);
-                    if (network == null) {
-                        throw new InvalidParameterValueException("Nework id is required for Direct vlan creation ");
-                    }
-                    networkId = network.getId();
-                    zoneId = network.getDataCenterId();
-                }
-            } else if (network.getGuestType() == null ||
-                    network.getGuestType() == Network.GuestType.Isolated
-                    && _ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.SourceNat)) {
-                throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId + " with type: " + network.getGuestType());
-            }
-        }
-
-        Pair<Boolean, Pair<String, String>> sameSubnet = null;
-        // Can add vlan range only to the network which allows it
-        if (!network.getSpecifyIpRanges()) {
-            throw new InvalidParameterValueException("Network " + network + " doesn't support adding ip ranges");
-        }
-
-        if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
-            if (network.getTrafficType() == TrafficType.Guest) {
-                if (network.getGuestType() != GuestType.Shared) {
-                    throw new InvalidParameterValueException("Can execute createVLANIpRanges on shared guest network, but type of this guest network " + network.getId() + " is "
-                            + network.getGuestType());
-                }
-
-                final List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
-                if (vlans != null && vlans.size() > 0) {
-                    final VlanVO vlan = vlans.get(0);
-                    if (vlanId == null || vlanId.contains(Vlan.UNTAGGED)) {
-                        vlanId = vlan.getVlanTag();
-                    } else if (!NetUtils.isSameIsolationId(vlan.getVlanTag(), vlanId)) {
-                        throw new InvalidParameterValueException("there is already one vlan " + vlan.getVlanTag() + " on network :" + +network.getId()
-                                + ", only one vlan is allowed on guest network");
-                    }
-                }
-                sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
-
-            }
-
-        } else if (network.getTrafficType() == TrafficType.Management) {
-            throw new InvalidParameterValueException("Cannot execute createVLANIpRanges on management network");
-        } else if (zone.getNetworkType() == NetworkType.Basic) {
-            final List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
-            sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
-        }
-
-        if (zoneId == null || ipv6 && (ip6Gateway == null || ip6Cidr == null)) {
-            throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks");
-        }
-
-        if (forVirtualNetwork) {
-            if (vlanOwner != null) {
-
-                final long accountIpRange = NetUtils.ip2Long(endIP) - NetUtils.ip2Long(startIP) + 1;
-
-                // check resource limits
-                _resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountIpRange);
-            }
-        }
-        // Check if the IP range overlaps with the private ip
-        if (ipv4) {
-            checkOverlapPrivateIpRange(zoneId, startIP, endIP);
-        }
-
-        return commitVlan(zoneId, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId, forVirtualNetwork, forSystemVms, networkId, physicalNetworkId, startIPv6, endIPv6, ip6Gateway,
-                ip6Cidr, domain, vlanOwner, network, sameSubnet);
-    }
-
-    private Vlan commitVlan(final Long zoneId, final Long podId, final String startIP, final String endIP, final String newVlanGatewayFinal, final String newVlanNetmaskFinal,
-            final String vlanId, final Boolean forVirtualNetwork, final Boolean forSystemVms, final Long networkId, final Long physicalNetworkId, final String startIPv6, final String endIPv6,
-            final String ip6Gateway, final String ip6Cidr, final Domain domain, final Account vlanOwner, final Network network, final Pair<Boolean, Pair<String, String>> sameSubnet) {
-        final GlobalLock commitVlanLock = GlobalLock.getInternLock("CommitVlan");
-        commitVlanLock.lock(5);
-        s_logger.debug("Acquiring lock for committing vlan");
-        try {
-            return Transaction.execute(new TransactionCallback<Vlan>() {
-                @Override
-                public Vlan doInTransaction(final TransactionStatus status) {
-                    String newVlanNetmask = newVlanNetmaskFinal;
-                    String newVlanGateway = newVlanGatewayFinal;
-
-                    if ((sameSubnet == null || !sameSubnet.first()) && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared
-                            && _vlanDao.listVlansByNetworkId(networkId) != null) {
-                        final Map<Capability, String> dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()),
-                            Service.Dhcp);
-                        final String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets);
-                        if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) {
-                            throw new  InvalidParameterValueException("The dhcp service provider for this network does not support dhcp across multiple subnets");
-                        }
-                        s_logger.info("adding a new subnet to the network " + network.getId());
-                    } else if (sameSubnet != null) {
-                        // if it is same subnet the user might not send the vlan and the
-                        // netmask details. so we are
-                        // figuring out while validation and setting them here.
-                        newVlanGateway = sameSubnet.second().first();
-                        newVlanNetmask = sameSubnet.second().second();
-                    }
-                    final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, forSystemVms, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
-                            false, domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
-                    // create an entry in the nic_secondary table. This will be the new
-                    // gateway that will be configured on the corresponding routervm.
-                    return vlan;
-                }
-            });
-        } finally {
-            commitVlanLock.unlock();
-        }
-    }
-
-    public NetUtils.SupersetOrSubset checkIfSubsetOrSuperset(String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, final String newStartIP, final String newEndIP) {
-        if (newVlanGateway == null && newVlanNetmask == null) {
-            newVlanGateway = vlanGateway;
-            newVlanNetmask = vlanNetmask;
-            // this means he is trying to add to the existing subnet.
-            if (NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) {
-                if (NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) {
-                    return NetUtils.SupersetOrSubset.sameSubnet;
-                }
-            }
-            return NetUtils.SupersetOrSubset.neitherSubetNorSuperset;
-        } else if (newVlanGateway == null || newVlanNetmask == null) {
-            throw new InvalidParameterValueException(
-                    "either both netmask and gateway should be passed or both should me omited.");
-        } else {
-            if (!NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) {
-                throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet");
-            }
-            if (!NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) {
-                throw new InvalidParameterValueException("The end ip and gateway do not belong to the same subnet");
-            }
-        }
-        final String cidrnew = NetUtils.getCidrFromGatewayAndNetmask(newVlanGateway, newVlanNetmask);
-        final String existing_cidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
-
-        return NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(cidrnew, existing_cidr);
-    }
-
-    public Pair<Boolean, Pair<String, String>> validateIpRange(final String startIP, final String endIP, final String newVlanGateway, final String newVlanNetmask, final List<VlanVO> vlans, final boolean ipv4,
-            final boolean ipv6, String ip6Gateway, String ip6Cidr, final String startIPv6, final String endIPv6, final Network network) {
-        String vlanGateway = null;
-        String vlanNetmask = null;
-        boolean sameSubnet = false;
-        if (CollectionUtils.isNotEmpty(vlans)) {
-            for (final VlanVO vlan : vlans) {
-                vlanGateway = vlan.getVlanGateway();
-                vlanNetmask = vlan.getVlanNetmask();
-                sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP,
-                        ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
-                if (sameSubnet) break;
-            }
-        } else if(network.getGateway() != null && network.getCidr() != null) {
-            vlanGateway = network.getGateway();
-            vlanNetmask = NetUtils.getCidrNetmask(network.getCidr());
-            sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP,
-                    ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
-        }
-        if (newVlanGateway == null && newVlanNetmask == null && !sameSubnet) {
-            throw new InvalidParameterValueException("The ip range dose not belong to any of the existing subnets, Provide the netmask and gateway if you want to add new subnet");
-        }
-        Pair<String, String> vlanDetails = null;
-
-        if (sameSubnet) {
-            vlanDetails = new Pair<String, String>(vlanGateway, vlanNetmask);
-        } else {
-            vlanDetails = new Pair<String, String>(newVlanGateway, newVlanNetmask);
-        }
-        // check if the gatewayip is the part of the ip range being added.
-        if (ipv4 && NetUtils.ipRangesOverlap(startIP, endIP, vlanDetails.first(), vlanDetails.first())) {
-            throw new InvalidParameterValueException("The gateway ip should not be the part of the ip range being added.");
-        }
-
-        return new Pair<Boolean, Pair<String, String>>(sameSubnet, vlanDetails);
-    }
-
-    public boolean hasSameSubnet(boolean ipv4, String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, String newStartIp, String newEndIp,
-                                  boolean ipv6, String newIp6Gateway, String newIp6Cidr, String newIp6StartIp, String newIp6EndIp, Network network) {
-        if (ipv4) {
-            // check if subset or super set or neither.
-            final NetUtils.SupersetOrSubset val = checkIfSubsetOrSuperset(vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, newStartIp, newEndIp);
-            if (val == NetUtils.SupersetOrSubset.isSuperset) {
-                // this means that new cidr is a superset of the
-                // existing subnet.
-                throw new InvalidParameterValueException("The subnet you are trying to add is a superset of the existing subnet having gateway " + vlanGateway
-                        + " and netmask " + vlanNetmask);
-            } else if (val == NetUtils.SupersetOrSubset.neitherSubetNorSuperset) {
-                // this implies the user is trying to add a new subnet
-                // which is not a superset or subset of this subnet.
-            } else if (val == NetUtils.SupersetOrSubset.isSubset) {
-                // this means he is trying to add to the same subnet.
-                throw new InvalidParameterValueException("The subnet you are trying to add is a subset of the existing subnet having gateway " + vlanGateway
-                        + " and netmask " + vlanNetmask);
-            } else if (val == NetUtils.SupersetOrSubset.sameSubnet) {
-                //check if the gateway provided by the user is same as that of the subnet.
-                if (newVlanGateway != null && !newVlanGateway.equals(vlanGateway)) {
-                    throw new InvalidParameterValueException("The gateway of the subnet should be unique. The subnet already has a gateway " + vlanGateway);
-                }
-                return true;
-            }
-        }
-        if (ipv6) {
-            if (newIp6Gateway != null && !newIp6Gateway.equals(network.getIp6Gateway())) {
-                throw new InvalidParameterValueException("The input gateway " + newIp6Gateway + " is not same as network gateway " + network.getIp6Gateway());
-            }
-            if (newIp6Cidr != null && !newIp6Cidr.equals(network.getIp6Cidr())) {
-                throw new InvalidParameterValueException("The input cidr " + newIp6Cidr + " is not same as network cidr " + network.getIp6Cidr());
-            }
-
-            newIp6Gateway = MoreObjects.firstNonNull(newIp6Gateway, network.getIp6Gateway());
-            newIp6Cidr = MoreObjects.firstNonNull(newIp6Cidr, network.getIp6Cidr());
-            _networkModel.checkIp6Parameters(newIp6StartIp, newIp6EndIp, newIp6Gateway, newIp6Cidr);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    @DB
-    public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final boolean forSystemVms, final Long podId, final String startIP, final String endIP,
-            final String vlanGateway, final String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
-        final Network network = _networkModel.getNetwork(networkId);
-
-        boolean ipv4 = false, ipv6 = false;
-
-        if (startIP != null) {
-            ipv4 = true;
-        }
-
-        if (startIPv6 != null) {
-            ipv6 = true;
-        }
-
-        if (!ipv4 && !ipv6) {
-            throw new InvalidParameterValueException("Please specify IPv4 or IPv6 address.");
-        }
-
-        // Validate the zone
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Please specify a valid zone.");
-        }
-
-        // ACL check
-        checkZoneAccess(CallContext.current().getCallingAccount(), zone);
-
-        // Validate the physical network
-        if (_physicalNetworkDao.findById(physicalNetworkId) == null) {
-            throw new InvalidParameterValueException("Please specify a valid physical network id");
-        }
-
-        // Validate the pod
-        if (podId != null) {
-            final Pod pod = _podDao.findById(podId);
-            if (pod == null) {
-                throw new InvalidParameterValueException("Please specify a valid pod.");
-            }
-            if (pod.getDataCenterId() != zoneId) {
-                throw new InvalidParameterValueException("Pod id=" + podId + " doesn't belong to zone id=" + zoneId);
-            }
-            // pod vlans can be created in basic zone only
-            if (zone.getNetworkType() != NetworkType.Basic || network.getTrafficType() != TrafficType.Guest) {
-                throw new InvalidParameterValueException("Pod id can be specified only for the networks of type " + TrafficType.Guest + " in zone of type " + NetworkType.Basic);
-            }
-        }
-
-
-        // 1) if vlan is specified for the guest network range, it should be the
-        // same as network's vlan
-        // 2) if vlan is missing, default it to the guest network's vlan
-        if (network.getTrafficType() == TrafficType.Guest) {
-            String networkVlanId = null;
-            boolean connectivityWithoutVlan = false;
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) {
-                Map<Capability, String> connectivityCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Connectivity);
-                connectivityWithoutVlan = MapUtils.isNotEmpty(connectivityCapabilities) && connectivityCapabilities.containsKey(Capability.NoVlan);
-            }
-
-            final URI uri = network.getBroadcastUri();
-            if (connectivityWithoutVlan) {
-                networkVlanId = network.getBroadcastDomainType().toUri(network.getUuid()).toString();
-            } else if (uri != null) {
-                // Do not search for the VLAN tag when the network doesn't support VLAN
-               if (uri.toString().startsWith("vlan")) {
-                    final String[] vlan = uri.toString().split("vlan:\\/\\/");
-                    networkVlanId = vlan[1];
-                    // For pvlan
-                    if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
-                        networkVlanId = networkVlanId.split("-")[0];
-                    }
-               }
-            }
-
-            if (vlanId != null && !connectivityWithoutVlan) {
-                // if vlan is specified, throw an error if it's not equal to
-                // network's vlanId
-                if (networkVlanId != null && !NetUtils.isSameIsolationId(networkVlanId, vlanId)) {
-                    throw new InvalidParameterValueException("Vlan doesn't match vlan of the network");
-                }
-            } else {
-                vlanId = networkVlanId;
-            }
-        } else if (network.getTrafficType() == TrafficType.Public && vlanId == null) {
-            throw new InvalidParameterValueException("Unable to determine vlan id or untagged vlan for public network");
-        }
-
-        if (vlanId == null) {
-            vlanId = Vlan.UNTAGGED;
-        }
-
-        final VlanType vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached;
-
-        if ((domain != null || vlanOwner != null) && zone.getNetworkType() != NetworkType.Advanced) {
-            throw new InvalidParameterValueException("Vlan owner can be defined only in the zone of type " + NetworkType.Advanced);
-        }
-
-        if (ipv4) {
-            // Make sure the gateway is valid
-            if (!NetUtils.isValidIp4(vlanGateway)) {
-                throw new InvalidParameterValueException("Please specify a valid gateway");
-            }
-
-            // Make sure the netmask is valid
-            if (!NetUtils.isValidIp4Netmask(vlanNetmask)) {
-                throw new InvalidParameterValueException("Please specify a valid netmask");
-            }
-        }
-
-        if (ipv6) {
-            if (!NetUtils.isValidIp6(vlanIp6Gateway)) {
-                throw new InvalidParameterValueException("Please specify a valid IPv6 gateway");
-            }
-            if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) {
-                throw new InvalidParameterValueException("Please specify a valid IPv6 CIDR");
-            }
-        }
-
-        if (ipv4) {
-            final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
-
-            //Make sure start and end ips are with in the range of cidr calculated for this gateway and netmask {
-            if (!NetUtils.isIpWithInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithInCidrRange(startIP, newCidr) || !NetUtils.isIpWithInCidrRange(endIP, newCidr)) {
-                throw new InvalidParameterValueException("Please specify a valid IP range or valid netmask or valid gateway");
-            }
-
-            // Check if the new VLAN's subnet conflicts with the guest network
-            // in
-            // the specified zone (guestCidr is null for basic zone)
-            // when adding shared network with same cidr of zone guest cidr,
-            // if the specified vlan is not present in zone, physical network, allow to create the network as the isolation is based on VLAN.
-            final String guestNetworkCidr = zone.getGuestNetworkCidr();
-            if (guestNetworkCidr != null && NetUtils.isNetworksOverlap(newCidr, guestNetworkCidr) && _zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).isEmpty() != true) {
-                throw new InvalidParameterValueException("The new IP range you have specified has  overlapped with the guest network in zone: " + zone.getName()
-                        + "along with existing Vlan also. Please specify a different gateway/netmask");
-            }
-
-            // Check if there are any errors with the IP range
-            checkPublicIpRangeErrors(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
-
-            checkConflictsWithPortableIpRange(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
-
-            // Throw an exception if this subnet overlaps with subnet on other VLAN,
-            // if this is ip range extension, gateway, network mask should be same and ip range should not overlap
-
-            final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
-            for (final VlanVO vlan : vlans) {
-                final String otherVlanGateway = vlan.getVlanGateway();
-                final String otherVlanNetmask = vlan.getVlanNetmask();
-                // Continue if it's not IPv4
-                if ( otherVlanGateway == null || otherVlanNetmask == null ) {
-                    continue;
-                }
-                if ( vlan.getNetworkId() == null ) {
-                    continue;
-                }
-                final String otherCidr = NetUtils.getCidrFromGatewayAndNetmask(otherVlanGateway, otherVlanNetmask);
-                if( !NetUtils.isNetworksOverlap(newCidr,  otherCidr)) {
-                    continue;
-                }
-                // from here, subnet overlaps
-                if (!UriUtils.checkVlanUriOverlap(
-                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
-                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
-                    boolean overlapped = false;
-                    if( network.getTrafficType() == TrafficType.Public ) {
-                        overlapped = true;
-                    } else {
-                        final Long nwId = vlan.getNetworkId();
-                        if ( nwId != null ) {
-                            final Network nw = _networkModel.getNetwork(nwId);
-                            if ( nw != null && nw.getTrafficType() == TrafficType.Public ) {
-                                overlapped = true;
-                            }
-                        }
-
-                    }
-                    if ( overlapped ) {
-                        throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag()
-                                + " in zone " + zone.getName()
-                                + " has overlapped with the subnet. Please specify a different gateway/netmask.");
-                    }
-                } else {
-
-                    final String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
-                    final String otherVlanStartIP = otherVlanIpRange[0];
-                    String otherVlanEndIP = null;
-                    if (otherVlanIpRange.length > 1) {
-                        otherVlanEndIP = otherVlanIpRange[1];
-                    }
-
-                    // extend IP range
-                    if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
-                        throw new InvalidParameterValueException("The IP range has already been added with gateway "
-                                + otherVlanGateway + " ,and netmask " + otherVlanNetmask
-                                + ", Please specify the gateway/netmask if you want to extend ip range" );
-                    }
-                    if (!NetUtils.is31PrefixCidr(newCidr)) {
-                        if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
-                            throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
-                                " Please specify a different start IP/end IP.");
-                        }
-                    }
-                }
-            }
-        }
-
-        String ipv6Range = null;
-        if (ipv6) {
-            ipv6Range = startIPv6;
-            if (endIPv6 != null) {
-                ipv6Range += "-" + endIPv6;
-            }
-
-            final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
-            for (final VlanVO vlan : vlans) {
-                if (vlan.getIp6Gateway() == null) {
-                    continue;
-                }
-                if (NetUtils.isSameIsolationId(vlanId, vlan.getVlanTag())) {
-                    if (NetUtils.isIp6RangeOverlap(ipv6Range, vlan.getIp6Range())) {
-                        throw new InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag()
-                                + " already has IPs that overlap with the new range. Please specify a different start IP/end IP.");
-                    }
-
-                    if (!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
-                        throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " has already been added with gateway " + vlan.getIp6Gateway()
-                                + ". Please specify a different tag.");
-                    }
-                }
-            }
-        }
-
-        // Check if the vlan is being used
-        if (!bypassVlanOverlapCheck && _zoneDao.findVnet(zoneId, physicalNetworkId, BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId))).size() > 0) {
-            throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
-                    + zone.getName());
-        }
-
-        String ipRange = null;
-
-        if (ipv4) {
-            ipRange = startIP;
-            if (endIP != null) {
-                ipRange += "-" + endIP;
-            }
-        }
-
-        // Everything was fine, so persist the VLAN
-        final VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, domain, vlanOwner, vlanIp6Gateway, vlanIp6Cidr,
-                ipv4, zone, vlanType, ipv6Range, ipRange, forSystemVms);
-
-        return vlan;
-    }
-
-    private VlanVO commitVlanAndIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final Long podId, final String startIP, final String endIP,
-            final String vlanGateway, final String vlanNetmask, final String vlanId, final Domain domain, final Account vlanOwner, final String vlanIp6Gateway, final String vlanIp6Cidr,
-            final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, final String ipv6Range, final String ipRange, final boolean forSystemVms) {
-        return Transaction.execute(new TransactionCallback<VlanVO>() {
-            @Override
-            public VlanVO doInTransaction(final TransactionStatus status) {
-                VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, physicalNetworkId, vlanIp6Gateway, vlanIp6Cidr, ipv6Range);
-                s_logger.debug("Saving vlan range " + vlan);
-                vlan = _vlanDao.persist(vlan);
-
-                // IPv6 use a used ip map, is different from ipv4, no need to save
-                // public ip range
-                if (ipv4) {
-                    if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId, forSystemVms)) {
-                        throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support.");
-                    }
-                }
-
-                if (vlanOwner != null) {
-                    // This VLAN is account-specific, so create an AccountVlanMapVO
-                    // entry
-                    final AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId());
-                    _accountVlanMapDao.persist(accountVlanMapVO);
-
-                    // generate usage event for dedication of every ip address in the
-                    // range
-                    final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlan.getId());
-                    for (final IPAddressVO ip : ips) {
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(),
-                                ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
-                    }
-                    // increment resource count for dedicated public ip's
-                    _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size()));
-                } else if (domain != null && !forSystemVms) {
-                    // This VLAN is domain-wide, so create a DomainVlanMapVO entry
-                    final DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
-                    _domainVlanMapDao.persist(domainVlanMapVO);
-                } else if (podId != null) {
-                    // This VLAN is pod-wide, so create a PodVlanMapVO entry
-                    final PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId());
-                    _podVlanMapDao.persist(podVlanMapVO);
-                }
-                return vlan;
-            }
-        });
-
-    }
-
-    @Override
-    @DB
-    public boolean deleteVlanAndPublicIpRange(final long userId, final long vlanDbId, final Account caller) {
-        VlanVO vlanRange = _vlanDao.findById(vlanDbId);
-        if (vlanRange == null) {
-            throw new InvalidParameterValueException("Please specify a valid IP range id.");
-        }
-
-        boolean isAccountSpecific = false;
-        final List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanRange.getId());
-        // Check for account wide pool. It will have an entry for
-        // account_vlan_map.
-        if (acctVln != null && !acctVln.isEmpty()) {
-            isAccountSpecific = true;
-        }
-
-        boolean isDomainSpecific = false;
-        List<DomainVlanMapVO> domainVlan = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanRange.getId());
-        // Check for domain wide pool. It will have an entry for domain_vlan_map.
-        if (domainVlan != null && !domainVlan.isEmpty()) {
-            isDomainSpecific = true;
-        }
-
-        // Check if the VLAN has any allocated public IPs
-        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
-        if (isAccountSpecific) {
-            int resourceCountToBeDecrement = 0;
-            try {
-                vlanRange = _vlanDao.acquireInLockTable(vlanDbId, 30);
-                if (vlanRange == null) {
-                    throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("lock vlan " + vlanDbId + " is acquired");
-                }
-                for (final IPAddressVO ip : ips) {
-                    boolean success = true;
-                    if (ip.isOneToOneNat()) {
-                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
-                                + " belonging to the range is used for static nat purposes. Cleanup the rules first");
-                    }
-
-                    if (ip.isSourceNat()) {
-                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
-                                + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId()
-                                + ". IP range with the source nat ip address can be removed either as a part of Network, or account removal");
-                    }
-
-                    if (_firewallDao.countRulesByIpId(ip.getId()) > 0) {
-                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
-                                + " belonging to the range has firewall rules applied. Cleanup the rules first");
-                    }
-                    if (ip.getAllocatedTime() != null) {// This means IP is allocated
-                        // release public ip address here
-                        success = _ipAddrMgr.disassociatePublicIpAddress(ip.getId(), userId, caller);
-                    }
-                    if (!success) {
-                        s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal");
-                    } else {
-                        resourceCountToBeDecrement++;
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getAccountId(), ip.getDataCenterId(), ip.getId(),
-                                ip.getAddress().toString(), ip.isSourceNat(), vlanRange.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
-                    }
-                }
-            } finally {
-                _vlanDao.releaseFromLockTable(vlanDbId);
-                if (resourceCountToBeDecrement > 0) {  //Making sure to decrement the count of only success operations above. For any reaason if disassociation fails then this number will vary from original range length.
-                    _resourceLimitMgr.decrementResourceCount(acctVln.get(0).getAccountId(), ResourceType.public_ip, new Long(resourceCountToBeDecrement));
-                }
-            }
-        } else {   // !isAccountSpecific
-            final NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(vlanRange.getVlanGateway(), vlanRange.getNetworkId(), NicIpAlias.State.active);
-            //check if the ipalias belongs to the vlan range being deleted.
-            if (ipAlias != null && vlanDbId == _publicIpAddressDao.findByIpAndSourceNetworkId(vlanRange.getNetworkId(), ipAlias.getIp4Address()).getVlanId()) {
-                throw new InvalidParameterValueException("Cannot delete vlan range " + vlanDbId + " as " + ipAlias.getIp4Address()
-                        + "is being used for providing dhcp service in this subnet. Delete all VMs in this subnet and try again");
-            }
-            final long allocIpCount = _publicIpAddressDao.countIPs(vlanRange.getDataCenterId(), vlanDbId, true);
-            if (allocIpCount > 0) {
-                throw new InvalidParameterValueException(allocIpCount + "  Ips are in use. Cannot delete this vlan");
-            }
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                _publicIpAddressDao.deletePublicIPRange(vlanDbId);
-                _vlanDao.remove(vlanDbId);
-            }
-        });
-
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DEDICATE, eventDescription = "dedicating vlan ip range", async = false)
-    public Vlan dedicatePublicIpRange(final DedicatePublicIpRangeCmd cmd) throws ResourceAllocationException {
-        final Long vlanDbId = cmd.getId();
-        final String accountName = cmd.getAccountName();
-        final Long domainId = cmd.getDomainId();
-        final Long projectId = cmd.getProjectId();
-
-        // Check if account is valid
-        Account vlanOwner = null;
-        if (projectId != null) {
-            if (accountName != null) {
-                throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
-            }
-            final Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-            }
-            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
-            if (vlanOwner == null) {
-                throw new InvalidParameterValueException("Please specify a valid projectId");
-            }
-        }
-
-        Domain domain = null;
-        if (accountName != null && domainId != null) {
-            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
-            if (vlanOwner == null) {
-                throw new InvalidParameterValueException("Unable to find account by name " + accountName);
-            } else if (vlanOwner.getId() == Account.ACCOUNT_ID_SYSTEM) {
-                throw new InvalidParameterValueException("Please specify a valid account. Cannot dedicate IP range to system account");
-            }
-        } else if (domainId != null) {
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Please specify a valid domain id");
-            }
-        }
-
-        // Check if range is valid
-        final VlanVO vlan = _vlanDao.findById(vlanDbId);
-        if (vlan == null) {
-            throw new InvalidParameterValueException("Unable to find vlan by id " + vlanDbId);
-        }
-
-        // Check if range has already been dedicated
-        final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
-        if (maps != null && !maps.isEmpty()) {
-            throw new InvalidParameterValueException("Specified Public IP range has already been dedicated");
-        }
-
-        List<DomainVlanMapVO> domainmaps = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanDbId);
-        if (domainmaps != null && !domainmaps.isEmpty()) {
-            throw new InvalidParameterValueException("Specified Public IP range has already been dedicated to a domain");
-        }
-
-        // Verify that zone exists and is advanced
-        final Long zoneId = vlan.getDataCenterId();
-        final DataCenterVO zone = _zoneDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        }
-        if (zone.getNetworkType() == NetworkType.Basic) {
-            throw new InvalidParameterValueException("Public IP range can be dedicated to an account only in the zone of type " + NetworkType.Advanced);
-        }
-
-        // Check Public IP resource limits
-        if (vlanOwner != null) {
-            final int accountPublicIpRange = _publicIpAddressDao.countIPs(zoneId, vlanDbId, false);
-            _resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountPublicIpRange);
-        }
-
-        // Check if any of the Public IP addresses is allocated to another
-        // account
-        boolean forSystemVms = false;
-        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
-        for (final IPAddressVO ip : ips) {
-            forSystemVms = ip.isForSystemVms();
-            final Long allocatedToAccountId = ip.getAllocatedToAccountId();
-            if (allocatedToAccountId != null) {
-                if (vlanOwner != null && allocatedToAccountId != vlanOwner.getId()) {
-                    throw new InvalidParameterValueException(ip.getAddress() + " Public IP address in range is allocated to another account ");
-                }
-                final Account accountAllocatedTo = _accountMgr.getActiveAccountById(allocatedToAccountId);
-                if (vlanOwner == null && domain != null && domain.getId() != accountAllocatedTo.getDomainId()){
-                    throw new InvalidParameterValueException(ip.getAddress()
-                            + " Public IP address in range is allocated to another domain/account ");
-                }
-            }
-        }
-
-        if (vlanOwner != null) {
-            // Create an AccountVlanMapVO entry
-            final AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId());
-            _accountVlanMapDao.persist(accountVlanMapVO);
-
-           // generate usage event for dedication of every ip address in the range
-            for (final IPAddressVO ip : ips) {
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(),
-                        vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
-            }
-        } else if (domain != null && !forSystemVms) {
-            // Create an DomainVlanMapVO entry
-            DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
-            _domainVlanMapDao.persist(domainVlanMapVO);
-        }
-
-        // increment resource count for dedicated public ip's
-        if (vlanOwner != null) {
-            _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size()));
-        }
-
-        return vlan;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_RELEASE, eventDescription = "releasing a public ip range", async = false)
-    public boolean releasePublicIpRange(final ReleasePublicIpRangeCmd cmd) {
-        final Long vlanDbId = cmd.getId();
-
-        final VlanVO vlan = _vlanDao.findById(vlanDbId);
-        if (vlan == null) {
-            throw new InvalidParameterValueException("Please specify a valid IP range id.");
-        }
-
-        return releasePublicIpRange(vlanDbId, CallContext.current().getCallingUserId(), CallContext.current().getCallingAccount());
-    }
-
-    @DB
-    public boolean releasePublicIpRange(final long vlanDbId, final long userId, final Account caller) {
-        VlanVO vlan = _vlanDao.findById(vlanDbId);
-        if(vlan == null) {
-            s_logger.warn("VLAN information for Account '" + caller + "', User '" + userId + "' VLAN '" + vlanDbId + "' is null. This is NPE situation.");
-        }
-
-        // Verify range is dedicated
-        boolean isAccountSpecific = false;
-        final List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
-        // Verify range is dedicated
-        if (acctVln != null && !acctVln.isEmpty()) {
-            isAccountSpecific = true;
-        }
-
-        boolean isDomainSpecific = false;
-        final List<DomainVlanMapVO> domainVlan = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanDbId);
-        // Check for domain wide pool. It will have an entry for domain_vlan_map.
-        if (domainVlan != null && !domainVlan.isEmpty()) {
-            isDomainSpecific = true;
-        }
-
-        if (!isAccountSpecific && !isDomainSpecific) {
-            throw new InvalidParameterValueException("Can't release Public IP range " + vlanDbId
-                    + " as it not dedicated to any domain and any account");
-        }
-        // Check if range has any allocated public IPs
-        final long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true);
-        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
-        boolean success = true;
-        final List<IPAddressVO> ipsInUse = new ArrayList<IPAddressVO>();
-        if (allocIpCount > 0) {
-            try {
-                vlan = _vlanDao.acquireInLockTable(vlanDbId, 30);
-                if (vlan == null) {
-                    throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("lock vlan " + vlanDbId + " is acquired");
-                }
-                for (final IPAddressVO ip : ips) {
-                    // Disassociate allocated IP's that are not in use
-                    if (!ip.isOneToOneNat() && !ip.isSourceNat() && !(_firewallDao.countRulesByIpId(ip.getId()) > 0)) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Releasing Public IP addresses" + ip + " of vlan " + vlanDbId + " as part of Public IP" + " range release to the system pool");
-                        }
-                        success = success && _ipAddrMgr.disassociatePublicIpAddress(ip.getId(), userId, caller);
-                    } else {
-                        ipsInUse.add(ip);
-                    }
-                }
-                if (!success) {
-                    s_logger.warn("Some Public IP addresses that were not in use failed to be released as a part of" + " vlan " + vlanDbId + "release to the system pool");
-                }
-            } finally {
-                _vlanDao.releaseFromLockTable(vlanDbId);
-            }
-        }
-
-        // A Public IP range can only be dedicated to one account at a time
-        if (isAccountSpecific && _accountVlanMapDao.remove(acctVln.get(0).getId())) {
-            // generate usage events to remove dedication for every ip in the range that has been disassociated
-            for (final IPAddressVO ip : ips) {
-                if (!ipsInUse.contains(ip)) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getAccountId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(),
-                            ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
-                }
-            }
-            // decrement resource count for dedicated public ip's
-            _resourceLimitMgr.decrementResourceCount(acctVln.get(0).getAccountId(), ResourceType.public_ip, new Long(ips.size()));
-            return true;
-        } else if (isDomainSpecific && _domainVlanMapDao.remove(domainVlan.get(0).getId())) {
-            s_logger.debug("Remove the vlan from domain_vlan_map successfully.");
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @DB
-    protected boolean savePublicIPRange(final String startIP, final String endIP, final long zoneId, final long vlanDbId, final long sourceNetworkid, final long physicalNetworkId, final boolean forSystemVms) {
-        final long startIPLong = NetUtils.ip2Long(startIP);
-        final long endIPLong = NetUtils.ip2Long(endIP);
-
-        final List<String> problemIps = Transaction.execute(new TransactionCallback<List<String>>() {
-            @Override
-            public List<String> doInTransaction(final TransactionStatus status) {
-                final IPRangeConfig config = new IPRangeConfig();
-                return config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkid, physicalNetworkId, forSystemVms);
-            }
-        });
-
-        return problemIps != null && problemIps.size() == 0;
-    }
-
-    private void checkPublicIpRangeErrors(final long zoneId, final String vlanId, final String vlanGateway, final String vlanNetmask, final String startIP, final String endIP) {
-        // Check that the start and end IPs are valid
-        if (!NetUtils.isValidIp4(startIP)) {
-            throw new InvalidParameterValueException("Please specify a valid start IP");
-        }
-
-        if (endIP != null && !NetUtils.isValidIp4(endIP)) {
-            throw new InvalidParameterValueException("Please specify a valid end IP");
-        }
-
-        if (endIP != null && !NetUtils.validIpRange(startIP, endIP)) {
-            throw new InvalidParameterValueException("Please specify a valid IP range.");
-        }
-
-        // Check that the IPs that are being added are compatible with the
-        // VLAN's gateway and netmask
-        if (vlanNetmask == null) {
-            throw new InvalidParameterValueException("Please ensure that your IP range's netmask is specified");
-        }
-
-        if (endIP != null && !NetUtils.sameSubnet(startIP, endIP, vlanNetmask)) {
-            throw new InvalidParameterValueException("Please ensure that your start IP and end IP are in the same subnet, as per the IP range's netmask.");
-        }
-
-        if (!NetUtils.sameSubnet(startIP, vlanGateway, vlanNetmask)) {
-            throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as your IP range's gateway, as per the IP range's netmask.");
-        }
-
-        if (endIP != null && !NetUtils.sameSubnet(endIP, vlanGateway, vlanNetmask)) {
-            throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as your IP range's gateway, as per the IP range's netmask.");
-        }
-        // check if the gatewayip is the part of the ip range being added.
-        // RFC 3021 - 31-Bit Prefixes on IPv4 Point-to-Point Links
-        //     GW              Netmask         Stat IP        End IP
-        // 192.168.24.0 - 255.255.255.254 - 192.168.24.0 - 192.168.24.1
-        // https://tools.ietf.org/html/rfc3021
-        // Added by Wilder Rodrigues
-        final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
-        if (!NetUtils.is31PrefixCidr(newCidr)) {
-            if (NetUtils.ipRangesOverlap(startIP, endIP, vlanGateway, vlanGateway)) {
-                throw new InvalidParameterValueException(
-                        "The gateway ip should not be the part of the ip range being added.");
-            }
-        }
-    }
-
-    private void checkConflictsWithPortableIpRange(final long zoneId, final String vlanId, final String vlanGateway, final String vlanNetmask, final String startIP, final String endIP) {
-        // check and throw exception if there is portable IP range that overlaps with public ip range being configured
-        if (checkOverlapPortableIpRange(_regionDao.getRegionId(), startIP, endIP)) {
-            throw new InvalidParameterValueException("Ip range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region "
-                    + _regionDao.getRegionId());
-        }
-
-        // verify and throw exception if the VLAN Id is used by any portable IP range
-        final List<PortableIpRangeVO> existingPortableIPRanges = _portableIpRangeDao.listByRegionId(_regionDao.getRegionId());
-        if (existingPortableIPRanges != null && !existingPortableIPRanges.isEmpty()) {
-            for (final PortableIpRangeVO portableIpRange : existingPortableIPRanges) {
-                if (NetUtils.isSameIsolationId(portableIpRange.getVlanTag(), vlanId)) {
-                    throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for portable ip range in this region");
-                }
-            }
-        }
-    }
-
-    private String getCidrAddress(final String cidr) {
-        final String[] cidrPair = cidr.split("\\/");
-        return cidrPair[0];
-    }
-
-    private int getCidrSize(final String cidr) {
-        final String[] cidrPair = cidr.split("\\/");
-        return Integer.parseInt(cidrPair[1]);
-    }
-
-    @Override
-    public void checkPodCidrSubnets(final long dcId, final Long podIdToBeSkipped, final String cidr) {
-        // For each pod, return an error if any of the following is true:
-        // The pod's CIDR subnet conflicts with the CIDR subnet of any other pod
-
-        // Check if the CIDR conflicts with the Guest Network or other pods
-        long skipPod = 0;
-        if (podIdToBeSkipped != null) {
-            skipPod = podIdToBeSkipped;
-        }
-        final HashMap<Long, List<Object>> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(dcId, skipPod);
-        final List<Object> newCidrPair = new ArrayList<Object>();
-        newCidrPair.add(0, getCidrAddress(cidr));
-        newCidrPair.add(1, (long)getCidrSize(cidr));
-        currentPodCidrSubnets.put(new Long(-1), newCidrPair);
-
-        final DataCenterVO dcVo = _zoneDao.findById(dcId);
-        final String guestNetworkCidr = dcVo.getGuestNetworkCidr();
-
-        // Guest cidr can be null for Basic zone
-        String guestIpNetwork = null;
-        Long guestCidrSize = null;
-        if (guestNetworkCidr != null) {
-            final String[] cidrTuple = guestNetworkCidr.split("\\/");
-            guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]));
-            guestCidrSize = Long.parseLong(cidrTuple[1]);
-        }
-
-        final String zoneName = getZoneName(dcId);
-
-        // Iterate through all pods in this zone
-        for (final Long podId : currentPodCidrSubnets.keySet()) {
-            String podName;
-            if (podId.longValue() == -1) {
-                podName = "newPod";
-            } else {
-                podName = getPodName(podId.longValue());
-            }
-
-            final List<Object> cidrPair = currentPodCidrSubnets.get(podId);
-            final String cidrAddress = (String)cidrPair.get(0);
-            final long cidrSize = ((Long)cidrPair.get(1)).longValue();
-
-            long cidrSizeToUse = -1;
-            if (guestCidrSize == null || cidrSize < guestCidrSize) {
-                cidrSizeToUse = cidrSize;
-            } else {
-                cidrSizeToUse = guestCidrSize;
-            }
-
-            String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
-
-            if (guestNetworkCidr != null) {
-                final String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse);
-                // Check that cidrSubnet does not equal guestSubnet
-                if (cidrSubnet.equals(guestSubnet)) {
-                    if (podName.equals("newPod")) {
-                        throw new InvalidParameterValueException(
-                                "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR.");
-                    } else {
-                        throw new InvalidParameterValueException(
-                                "Warning: The subnet of pod "
-                                        + podName
-                                        + " in zone "
-                                        + zoneName
-                                        + " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management.");
-                    }
-                }
-            }
-
-            // Iterate through the rest of the pods
-            for (final Long otherPodId : currentPodCidrSubnets.keySet()) {
-                if (podId.equals(otherPodId)) {
-                    continue;
-                }
-
-                // Check that cidrSubnet does not equal otherCidrSubnet
-                final List<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId);
-                final String otherCidrAddress = (String)otherCidrPair.get(0);
-                final long otherCidrSize = ((Long)otherCidrPair.get(1)).longValue();
-
-                if (cidrSize < otherCidrSize) {
-                    cidrSizeToUse = cidrSize;
-                } else {
-                    cidrSizeToUse = otherCidrSize;
-                }
-
-                cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
-                final String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse);
-
-                if (cidrSubnet.equals(otherCidrSubnet)) {
-                    final String otherPodName = getPodName(otherPodId.longValue());
-                    if (podName.equals("newPod")) {
-                        throw new InvalidParameterValueException("The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName
-                                + ". Please specify a different CIDR.");
-                    } else {
-                        throw new InvalidParameterValueException("Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName
-                                + " have conflicting CIDR subnets. Please change the CIDR of one of these pods.");
-                    }
-                }
-            }
-        }
-
-    }
-
-    private boolean validPod(final long podId) {
-        return _podDao.findById(podId) != null;
-    }
-
-    private boolean validPod(final String podName, final long zoneId) {
-        if (!validZone(zoneId)) {
-            return false;
-        }
-
-        return _podDao.findByName(podName, zoneId) != null;
-    }
-
-    private String getPodName(final long podId) {
-        return _podDao.findById(new Long(podId)).getName();
-    }
-
-    private boolean validZone(final String zoneName) {
-        return _zoneDao.findByName(zoneName) != null;
-    }
-
-    private boolean validZone(final long zoneId) {
-        return _zoneDao.findById(zoneId) != null;
-    }
-
-    private String getZoneName(final long zoneId) {
-        final DataCenterVO zone = _zoneDao.findById(new Long(zoneId));
-        if (zone != null) {
-            return zone.getName();
-        } else {
-            return null;
-        }
-    }
-
-    private String[] getLinkLocalIPRange() {
-        final String ipNums = _configDao.getValue("linkLocalIp.nums");
-        final int nums = Integer.parseInt(ipNums);
-        if (nums > 16 || nums <= 0) {
-            throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
-        }
-        /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
-        final String[] ipRanges = NetUtils.getLinkLocalIPRange(nums);
-        if (ipRanges == null) {
-            throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
-        }
-        return ipRanges;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DELETE, eventDescription = "deleting vlan ip range", async = false)
-    public boolean deleteVlanIpRange(final DeleteVlanIpRangeCmd cmd) {
-        final Long vlanDbId = cmd.getId();
-
-        final VlanVO vlan = _vlanDao.findById(vlanDbId);
-        if (vlan == null) {
-            throw new InvalidParameterValueException("Please specify a valid IP range id.");
-        }
-
-        return deleteVlanAndPublicIpRange(CallContext.current().getCallingUserId(), vlanDbId, CallContext.current().getCallingAccount());
-    }
-
-    @Override
-    public void checkDiskOfferingAccess(final Account caller, final DiskOffering dof) {
-        for (final SecurityChecker checker : _secChecker) {
-            if (checker.checkAccess(caller, dof)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + caller + " to disk offering:" + dof.getId() + " by " + checker.getName());
-                }
-                return;
-            } else {
-                throw new PermissionDeniedException("Access denied to " + caller + " by " + checker.getName());
-            }
-        }
-
-        assert false : "How can all of the security checkers pass on checking this caller?";
-        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to disk offering:" + dof.getId());
-    }
-
-    @Override
-    public void checkZoneAccess(final Account caller, final DataCenter zone) {
-        for (final SecurityChecker checker : _secChecker) {
-            if (checker.checkAccess(caller, zone)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + caller + " to zone:" + zone.getId() + " by " + checker.getName());
-                }
-                return;
-            } else {
-                throw new PermissionDeniedException("Access denied to " + caller + " by " + checker.getName() + " for zone " + zone.getId());
-            }
-        }
-
-        assert false : "How can all of the security checkers pass on checking this caller?";
-        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to zone:" + zone.getId());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_CREATE, eventDescription = "creating network offering")
-    public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) {
-        final String name = cmd.getNetworkOfferingName();
-        final String displayText = cmd.getDisplayText();
-        final String tags = cmd.getTags();
-        final String trafficTypeString = cmd.getTraffictype();
-        final boolean specifyVlan = cmd.getSpecifyVlan();
-        final boolean conserveMode = cmd.getConserveMode();
-        final String availabilityStr = cmd.getAvailability();
-        Integer networkRate = cmd.getNetworkRate();
-        TrafficType trafficType = null;
-        Availability availability = null;
-        Network.GuestType guestType = null;
-        final boolean specifyIpRanges = cmd.getSpecifyIpRanges();
-        final boolean isPersistent = cmd.getIsPersistent();
-        final Map<String, String> detailsStr = cmd.getDetails();
-        final Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy();
-        Boolean forVpc = cmd.getForVpc();
-
-        Integer maxconn = null;
-        boolean enableKeepAlive = false;
-        String servicePackageuuid = cmd.getServicePackageId();
-        // Verify traffic type
-        for (final TrafficType tType : TrafficType.values()) {
-            if (tType.name().equalsIgnoreCase(trafficTypeString)) {
-                trafficType = tType;
-                break;
-            }
-        }
-        if (trafficType == null) {
-            throw new InvalidParameterValueException("Invalid value for traffictype. Supported traffic types: Public, Management, Control, Guest, Vlan or Storage");
-        }
-
-        // Only GUEST traffic type is supported in Acton
-        if (trafficType != TrafficType.Guest) {
-            throw new InvalidParameterValueException("Only traffic type " + TrafficType.Guest + " is supported in the current release");
-        }
-
-        // Verify offering type
-        for (final Network.GuestType offType : Network.GuestType.values()) {
-            if (offType.name().equalsIgnoreCase(cmd.getGuestIpType())) {
-                guestType = offType;
-                break;
-            }
-        }
-
-        if (guestType == null) {
-            throw new InvalidParameterValueException("Invalid \"type\" parameter is given; can have Shared and Isolated values");
-        }
-
-        // Verify availability
-        for (final Availability avlb : Availability.values()) {
-            if (avlb.name().equalsIgnoreCase(availabilityStr)) {
-                availability = avlb;
-            }
-        }
-
-        if (availability == null) {
-            throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
-        }
-
-        if (networkRate != null && networkRate < 0) {
-            networkRate = 0;
-        }
-
-        final Long serviceOfferingId = cmd.getServiceOfferingId();
-
-        if (serviceOfferingId != null) {
-            final ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOfferingId);
-            if (offering == null) {
-                throw new InvalidParameterValueException("Cannot find specified service offering: " + serviceOfferingId);
-            }
-            if (!VirtualMachine.Type.DomainRouter.toString().equalsIgnoreCase(offering.getSystemVmType())) {
-                throw new InvalidParameterValueException("The specified service offering " + serviceOfferingId + " cannot be used by virtual router!");
-            }
-        }
-
-        // configure service provider map
-        final Map<Network.Service, Set<Network.Provider>> serviceProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
-        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
-
-        // populate the services first
-        for (final String serviceName : cmd.getSupportedServices()) {
-            // validate if the service is supported
-            final Service service = Network.Service.getService(serviceName);
-            if (service == null || service == Service.Gateway) {
-                throw new InvalidParameterValueException("Invalid service " + serviceName);
-            }
-
-            if (forVpc == null) {
-                if (service == Service.SecurityGroup || service == Service.Firewall) {
-                    forVpc = false;
-                } else if (service == Service.NetworkACL) {
-                    forVpc = true;
-                }
-            }
-
-            if (service == Service.SecurityGroup) {
-                // allow security group service for Shared networks only
-                if (guestType != GuestType.Shared) {
-                    throw new InvalidParameterValueException("Secrity group service is supported for network offerings with guest ip type " + GuestType.Shared);
-                }
-                final Set<Network.Provider> sgProviders = new HashSet<Network.Provider>();
-                sgProviders.add(Provider.SecurityGroupProvider);
-                serviceProviderMap.put(Network.Service.SecurityGroup, sgProviders);
-                continue;
-            }
-
-            serviceProviderMap.put(service, defaultProviders);
-        }
-
-        // add gateway provider (if sourceNat provider is enabled)
-        final Set<Provider> sourceNatServiceProviders = serviceProviderMap.get(Service.SourceNat);
-        if (sourceNatServiceProviders != null && !sourceNatServiceProviders.isEmpty()) {
-            serviceProviderMap.put(Service.Gateway, sourceNatServiceProviders);
-        }
-
-        // populate providers
-        final Map<Provider, Set<Service>> providerCombinationToVerify = new HashMap<Provider, Set<Service>>();
-        final Map<String, List<String>> svcPrv = cmd.getServiceProviders();
-        Provider firewallProvider = null;
-        Provider dhcpProvider = null;
-        Boolean IsVrUserdataProvider = false;
-        if (svcPrv != null) {
-            for (final String serviceStr : svcPrv.keySet()) {
-                final Network.Service service = Network.Service.getService(serviceStr);
-                if (serviceProviderMap.containsKey(service)) {
-                    final Set<Provider> providers = new HashSet<Provider>();
-                    // Allow to specify more than 1 provider per service only if
-                    // the service is LB
-                    if (!serviceStr.equalsIgnoreCase(Service.Lb.getName()) && svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) {
-                        throw new InvalidParameterValueException("In the current release only one provider can be " + "specified for the service if the service is not LB");
-                    }
-                    for (final String prvNameStr : svcPrv.get(serviceStr)) {
-                        // check if provider is supported
-                        final Network.Provider provider = Network.Provider.getProvider(prvNameStr);
-                        if (provider == null) {
-                            throw new InvalidParameterValueException("Invalid service provider: " + prvNameStr);
-                        }
-
-                        if (provider == Provider.JuniperSRX || provider == Provider.CiscoVnmc) {
-                            firewallProvider = provider;
-                        }
-
-                        if (provider == Provider.PaloAlto) {
-                            firewallProvider = Provider.PaloAlto;
-                        }
-
-                        if ((service == Service.PortForwarding || service == Service.StaticNat) && provider == Provider.VirtualRouter) {
-                            firewallProvider = Provider.VirtualRouter;
-                        }
-
-                        if (forVpc == null && VPC_ONLY_PROVIDERS.contains(provider)) {
-                            forVpc = true;
-                        }
-
-                        if (service == Service.Dhcp) {
-                            dhcpProvider = provider;
-                        }
-
-                        if (service == Service.UserData && provider == Provider.VirtualRouter) {
-                            IsVrUserdataProvider = true;
-                        }
-
-                        providers.add(provider);
-
-                        Set<Service> serviceSet = null;
-                        if (providerCombinationToVerify.get(provider) == null) {
-                            serviceSet = new HashSet<Service>();
-                        } else {
-                            serviceSet = providerCombinationToVerify.get(provider);
-                        }
-                        serviceSet.add(service);
-                        providerCombinationToVerify.put(provider, serviceSet);
-
-                    }
-                    serviceProviderMap.put(service, providers);
-                } else {
-                    throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network " + "offering, can't add a provider to it");
-                }
-            }
-        }
-
-        // dhcp provider and userdata provider should be same because vm will be contacting dhcp server for user data.
-        if (dhcpProvider == null && IsVrUserdataProvider) {
-            s_logger.debug("User data provider VR can't be selected without VR as dhcp provider. In this case VM fails to contact the DHCP server for userdata");
-            throw new InvalidParameterValueException("Without VR as dhcp provider, User data can't selected for VR. Please select VR as DHCP provider ");
-        }
-
-        // validate providers combination here
-        _networkModel.canProviderSupportServices(providerCombinationToVerify);
-
-        // validate the LB service capabilities specified in the network
-        // offering
-        final Map<Capability, String> lbServiceCapabilityMap = cmd.getServiceCapabilities(Service.Lb);
-        if (!serviceProviderMap.containsKey(Service.Lb) && lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
-            throw new InvalidParameterValueException("Capabilities for LB service can be specifed only when LB service is enabled for network offering.");
-        }
-        validateLoadBalancerServiceCapabilities(lbServiceCapabilityMap);
-
-        if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
-            maxconn = cmd.getMaxconnections();
-            if (maxconn == null) {
-                maxconn = Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyMaxConn.key()));
-            }
-        }
-        if (cmd.getKeepAliveEnabled() != null && cmd.getKeepAliveEnabled()) {
-            enableKeepAlive = true;
-        }
-
-        // validate the Source NAT service capabilities specified in the network
-        // offering
-        final Map<Capability, String> sourceNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.SourceNat);
-        if (!serviceProviderMap.containsKey(Service.SourceNat) && sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
-            throw new InvalidParameterValueException("Capabilities for source NAT service can be specifed only when source NAT service is enabled for network offering.");
-        }
-        validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
-
-        // validate the Static Nat service capabilities specified in the network
-        // offering
-        final Map<Capability, String> staticNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.StaticNat);
-        if (!serviceProviderMap.containsKey(Service.StaticNat) && sourceNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
-            throw new InvalidParameterValueException("Capabilities for static NAT service can be specifed only when static NAT service is enabled for network offering.");
-        }
-        validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
-
-        // validate the 'Connectivity' service capabilities specified in the network offering, if 'Connectivity' service
-        // is in the supported services of network offering
-        final Map<Capability, String> connectivityServiceCapabilityMap = cmd.getServiceCapabilities(Service.Connectivity);
-        if (!serviceProviderMap.containsKey(Service.Connectivity) &&
-                connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty())  {
-            throw new InvalidParameterValueException("Capabilities for 'Connectivity' service can be specified " +
-                    "only when Connectivity service is enabled for network offering.");
-        }
-        validateConnectivityServiceCapablities(guestType, serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap);
-
-        final Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
-        serviceCapabilityMap.put(Service.Lb, lbServiceCapabilityMap);
-        serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap);
-        serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap);
-        serviceCapabilityMap.put(Service.Connectivity, connectivityServiceCapabilityMap);
-
-        // if Firewall service is missing, add Firewall service/provider
-        // combination
-        if (firewallProvider != null) {
-            s_logger.debug("Adding Firewall service with provider " + firewallProvider.getName());
-            final Set<Provider> firewallProviderSet = new HashSet<Provider>();
-            firewallProviderSet.add(firewallProvider);
-            serviceProviderMap.put(Service.Firewall, firewallProviderSet);
-            if (!(firewallProvider.getName().equals(Provider.JuniperSRX.getName()) || firewallProvider.getName().equals(Provider.PaloAlto.getName()) || firewallProvider.getName()
-                    .equals(Provider.VirtualRouter.getName())) && egressDefaultPolicy == false) {
-                throw new InvalidParameterValueException("Firewall egress with default policy " + egressDefaultPolicy + " is not supported by the provider "
-                        + firewallProvider.getName());
-            }
-        }
-
-        final Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>();
-        if (detailsStr != null) {
-            for (final String detailStr : detailsStr.keySet()) {
-                NetworkOffering.Detail offDetail = null;
-                for (final NetworkOffering.Detail supportedDetail : NetworkOffering.Detail.values()) {
-                    if (detailStr.equalsIgnoreCase(supportedDetail.toString())) {
-                        offDetail = supportedDetail;
-                        break;
-                    }
-                }
-                if (offDetail == null) {
-                    throw new InvalidParameterValueException("Unsupported detail " + detailStr);
-                }
-                details.put(offDetail, detailsStr.get(detailStr));
-            }
-        }
-
-        if (forVpc == null) {
-            forVpc = false;
-        }
-
-        final NetworkOffering offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false,
-                serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc);
-        CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
-        return offering;
-    }
-
-    void validateLoadBalancerServiceCapabilities(final Map<Capability, String> lbServiceCapabilityMap) {
-        if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
-            if (lbServiceCapabilityMap.keySet().size() > 3 || !lbServiceCapabilityMap.containsKey(Capability.SupportedLBIsolation)) {
-                throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", "
-                        + Capability.InlineMode.getName() + " capabilities can be sepcified for LB service");
-            }
-
-            for (final Capability cap : lbServiceCapabilityMap.keySet()) {
-                final String value = lbServiceCapabilityMap.get(cap);
-                if (cap == Capability.SupportedLBIsolation) {
-                    final boolean dedicatedLb = value.contains("dedicated");
-                    final boolean sharedLB = value.contains("shared");
-                    if (dedicatedLb && sharedLB || !dedicatedLb && !sharedLB) {
-                        throw new InvalidParameterValueException("Either dedicated or shared isolation can be specified for " + Capability.SupportedLBIsolation.getName());
-                    }
-                } else if (cap == Capability.ElasticLb) {
-                    final boolean enabled = value.contains("true");
-                    final boolean disabled = value.contains("false");
-                    if (!enabled && !disabled) {
-                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.ElasticLb.getName());
-                    }
-                } else if (cap == Capability.InlineMode) {
-                    final boolean enabled = value.contains("true");
-                    final boolean disabled = value.contains("false");
-                    if (!enabled && !disabled) {
-                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.InlineMode.getName());
-                    }
-                } else if (cap == Capability.LbSchemes) {
-                    final boolean internalLb = value.contains("internal");
-                    final boolean publicLb = value.contains("public");
-                    if (!internalLb && !publicLb) {
-                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.LbSchemes.getName());
-                    }
-                } else {
-                    throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", "
-                            + Capability.InlineMode.getName() + ", " + Capability.LbSchemes.getName() + " capabilities can be sepcified for LB service");
-                }
-            }
-        }
-    }
-
-    void validateSourceNatServiceCapablities(final Map<Capability, String> sourceNatServiceCapabilityMap) {
-        if (sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
-            if (sourceNatServiceCapabilityMap.keySet().size() > 2) {
-                throw new InvalidParameterValueException("Only " + Capability.SupportedSourceNatTypes.getName() + " and " + Capability.RedundantRouter
-                        + " capabilities can be sepcified for source nat service");
-            }
-
-            for (final Map.Entry<Capability ,String> srcNatPair : sourceNatServiceCapabilityMap.entrySet()) {
-                final Capability capability = srcNatPair.getKey();
-                final String value = srcNatPair.getValue();
-                if (capability == Capability.SupportedSourceNatTypes) {
-                    final boolean perAccount = value.contains("peraccount");
-                    final boolean perZone = value.contains("perzone");
-                    if (perAccount && perZone || !perAccount && !perZone) {
-                        throw new InvalidParameterValueException("Either peraccount or perzone source NAT type can be specified for "
-                                + Capability.SupportedSourceNatTypes.getName());
-                    }
-                } else if (capability == Capability.RedundantRouter) {
-                    final boolean enabled = value.contains("true");
-                    final boolean disabled = value.contains("false");
-                    if (!enabled && !disabled) {
-                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.RedundantRouter.getName());
-                    }
-                } else {
-                    throw new InvalidParameterValueException("Only " + Capability.SupportedSourceNatTypes.getName() + " and " + Capability.RedundantRouter
-                            + " capabilities can be sepcified for source nat service");
-                }
-            }
-        }
-    }
-
-    void validateStaticNatServiceCapablities(final Map<Capability, String> staticNatServiceCapabilityMap) {
-        if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
-            boolean eipEnabled = false;
-            boolean associatePublicIP = true;
-            for (final Capability capability : staticNatServiceCapabilityMap.keySet()) {
-                final String value = staticNatServiceCapabilityMap.get(capability).toLowerCase();
-                if (!(value.contains("true") ^ value.contains("false"))) {
-                    throw new InvalidParameterValueException("Unknown specified value (" + value + ") for " + capability);
-                }
-                if (capability == Capability.ElasticIp) {
-                    eipEnabled = value.contains("true");
-                } else if (capability == Capability.AssociatePublicIP) {
-                    associatePublicIP = value.contains("true");
-                } else {
-                    throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and " + Capability.AssociatePublicIP.getName()
-                            + " capabilitiy can be sepcified for static nat service");
-                }
-            }
-            if (!eipEnabled && associatePublicIP) {
-                throw new InvalidParameterValueException("Capability " + Capability.AssociatePublicIP.getName() + " can only be set when capability "
-                        + Capability.ElasticIp.getName() + " is true");
-            }
-        }
-    }
-
-    void validateConnectivityServiceCapablities(final Network.GuestType guestType, final Set<Provider> providers, final Map<Capability, String> connectivityServiceCapabilityMap) {
-        if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
-            for (final Map.Entry<Capability, String>entry: connectivityServiceCapabilityMap.entrySet()) {
-                final Capability capability = entry.getKey();
-                if (capability == Capability.StretchedL2Subnet || capability == Capability.PublicAccess) {
-                    final String value = entry.getValue().toLowerCase();
-                    if (!(value.contains("true") ^ value.contains("false"))) {
-                        throw new InvalidParameterValueException("Invalid value (" + value + ") for " + capability +
-                                " should be true/false");
-                    } else if (capability == Capability.PublicAccess && guestType != GuestType.Shared) {
-                        throw new InvalidParameterValueException("Capability " + capability.getName() + " can only be enabled for network offerings " +
-                                "with guest type Shared.");
-                    }
-                } else {
-                    throw new InvalidParameterValueException("Capability " + capability.getName() + " can not be "
-                            + " specified with connectivity service.");
-                }
-            }
-
-            // validate connectivity service provider actually supports specified capabilities
-            if (providers != null && !providers.isEmpty()) {
-                for (Capability capability : connectivityServiceCapabilityMap.keySet()) {
-                    _networkModel.providerSupportsCapability(providers, Service.Connectivity, capability);
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public NetworkOfferingVO createNetworkOffering(final String name, final String displayText, final TrafficType trafficType, String tags, final boolean specifyVlan,
-            final Availability availability,
-            final Integer networkRate, final Map<Service, Set<Provider>> serviceProviderMap, final boolean isDefault, final GuestType type, final boolean systemOnly,
-            final Long serviceOfferingId,
-            final boolean conserveMode, final Map<Service, Map<Capability, String>> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent,
-            final Map<Detail, String> details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive, Boolean forVpc) {
-
-        String servicePackageUuid;
-        String spDescription = null;
-        if (details == null) {
-            servicePackageUuid = null;
-        } else {
-            servicePackageUuid = details.get(NetworkOffering.Detail.servicepackageuuid);
-            spDescription = details.get(NetworkOffering.Detail.servicepackagedescription);
-        }
-
-
-        final String multicastRateStr = _configDao.getValue("multicast.throttling.rate");
-        final int multicastRate = multicastRateStr == null ? 10 : Integer.parseInt(multicastRateStr);
-        tags = StringUtils.cleanupTags(tags);
-
-        // specifyVlan should always be true for Shared network offerings
-        if (!specifyVlan && type == GuestType.Shared) {
-            Set<Provider> connectivityProviders = serviceProviderMap != null ? serviceProviderMap.get(Service.Connectivity) : null;
-            if (CollectionUtils.isEmpty(connectivityProviders) || !_networkModel.providerSupportsCapability(connectivityProviders, Service.Connectivity, Capability.NoVlan)) {
-                throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type);
-            }
-        }
-
-        // specifyIpRanges should always be true for Shared networks
-        // specifyIpRanges can only be true for Isolated networks with no Source
-        // Nat service
-        if (specifyIpRanges) {
-            if (type == GuestType.Isolated) {
-                if (serviceProviderMap.containsKey(Service.SourceNat)) {
-                    throw new InvalidParameterValueException("SpecifyIpRanges can only be true for Shared network offerings and Isolated with no SourceNat service");
-                }
-            }
-        } else {
-            if (type == GuestType.Shared) {
-                throw new InvalidParameterValueException("SpecifyIpRanges should always be true for Shared network offerings");
-            }
-        }
-
-        // isPersistent should always be false for Shared network Offerings
-        if (isPersistent && type == GuestType.Shared) {
-            throw new InvalidParameterValueException("isPersistent should be false if network offering's type is " + type);
-        }
-
-        // validate availability value
-        if (availability == NetworkOffering.Availability.Required) {
-            final boolean canOffBeRequired = type == GuestType.Isolated && serviceProviderMap.containsKey(Service.SourceNat);
-            if (!canOffBeRequired) {
-                throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
-                        + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
-            }
-
-            // only one network offering in the system can be Required
-            final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-            if (!offerings.isEmpty()) {
-                throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required);
-            }
-        }
-
-        boolean dedicatedLb = false;
-        boolean elasticLb = false;
-        boolean sharedSourceNat = false;
-        boolean redundantRouter = false;
-        boolean elasticIp = false;
-        boolean associatePublicIp = false;
-        boolean inline = false;
-        boolean publicLb = false;
-        boolean internalLb = false;
-        boolean strechedL2Subnet = false;
-        boolean publicAccess = false;
-
-        if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) {
-            final Map<Capability, String> lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb);
-
-            if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
-                final String isolationCapability = lbServiceCapabilityMap.get(Capability.SupportedLBIsolation);
-                if (isolationCapability != null) {
-                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.SupportedLBIsolation, isolationCapability);
-                    dedicatedLb = isolationCapability.contains("dedicated");
-                } else {
-                    dedicatedLb = true;
-                }
-
-                final String param = lbServiceCapabilityMap.get(Capability.ElasticLb);
-                if (param != null) {
-                    elasticLb = param.contains("true");
-                }
-
-                final String inlineMode = lbServiceCapabilityMap.get(Capability.InlineMode);
-                if (inlineMode != null) {
-                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.InlineMode, inlineMode);
-                    inline = inlineMode.contains("true");
-                } else {
-                    inline = false;
-                }
-
-                final String publicLbStr = lbServiceCapabilityMap.get(Capability.LbSchemes);
-                if (serviceProviderMap.containsKey(Service.Lb)) {
-                    if (publicLbStr != null) {
-                        _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.LbSchemes, publicLbStr);
-                        internalLb = publicLbStr.contains("internal");
-                        publicLb = publicLbStr.contains("public");
-                    }
-                }
-            }
-
-            // in the current version of the code, publicLb and specificLb can't
-            // both be set to true for the same network offering
-            if (publicLb && internalLb) {
-                throw new InvalidParameterValueException("Public lb and internal lb can't be enabled at the same time on the offering");
-            }
-
-            final Map<Capability, String> sourceNatServiceCapabilityMap = serviceCapabilityMap.get(Service.SourceNat);
-            if (sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
-                final String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes);
-                if (sourceNatType != null) {
-                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType);
-                    sharedSourceNat = sourceNatType.contains("perzone");
-                }
-
-                final String param = sourceNatServiceCapabilityMap.get(Capability.RedundantRouter);
-                if (param != null) {
-                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.RedundantRouter, param);
-                    redundantRouter = param.contains("true");
-                }
-            }
-
-            final Map<Capability, String> staticNatServiceCapabilityMap = serviceCapabilityMap.get(Service.StaticNat);
-            if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
-                final String param = staticNatServiceCapabilityMap.get(Capability.ElasticIp);
-                if (param != null) {
-                    elasticIp = param.contains("true");
-                    final String associatePublicIP = staticNatServiceCapabilityMap.get(Capability.AssociatePublicIP);
-                    if (associatePublicIP != null) {
-                        associatePublicIp = associatePublicIP.contains("true");
-                    }
-                }
-            }
-
-            final Map<Capability, String> connectivityServiceCapabilityMap = serviceCapabilityMap.get(Service.Connectivity);
-            if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
-                if (connectivityServiceCapabilityMap.containsKey(Capability.StretchedL2Subnet)) {
-                    final String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet);
-                    if ("true".equalsIgnoreCase(value)) {
-                        strechedL2Subnet = true;
-                    }
-                }
-
-                if (connectivityServiceCapabilityMap.containsKey(Capability.PublicAccess)) {
-                    final String value = connectivityServiceCapabilityMap.get(Capability.PublicAccess);
-                    if ("true".equalsIgnoreCase(value)) {
-                        publicAccess = true;
-                    }
-                }
-            }
-        }
-
-        if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) {
-            //if not specified, default public lb to true
-            publicLb = true;
-        }
-
-        final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability,
-                tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb,
-                internalLb, forVpc, egressDefaultPolicy, strechedL2Subnet, publicAccess);
-
-        if (serviceOfferingId != null) {
-            offeringFinal.setServiceOfferingId(serviceOfferingId);
-        }
-
-        //Set Service package id
-        offeringFinal.setServicePackage(servicePackageUuid);
-        // validate the details
-        if (details != null) {
-            validateNtwkOffDetails(details, serviceProviderMap);
-        }
-
-        boolean vpcOff = false;
-        boolean nsOff = false;
-
-        if (serviceProviderMap != null && spDescription != null) {
-            for (final Network.Service service : serviceProviderMap.keySet()) {
-                final Set<Provider> providers = serviceProviderMap.get(service);
-                if (providers != null && !providers.isEmpty()) {
-                    for (final Network.Provider provider : providers) {
-                        if (provider == Provider.VPCVirtualRouter) {
-                            vpcOff = true;
-                        }
-                        if (provider == Provider.Netscaler) {
-                            nsOff = true;
-                        }
-                    }
-                }
-            }
-            if(vpcOff && nsOff) {
-                if(!(spDescription.equalsIgnoreCase("A NetScalerVPX is dedicated per network.") || spDescription.contains("dedicated NetScaler"))) {
-                    throw new InvalidParameterValueException("Only NetScaler Service Pacakge with Dedicated Device Mode is Supported in VPC Type Guest Network");
-                }
-            }
-        }
-
-        return Transaction.execute(new TransactionCallback<NetworkOfferingVO>() {
-            @Override
-            public NetworkOfferingVO doInTransaction(final TransactionStatus status) {
-                NetworkOfferingVO offering = offeringFinal;
-
-                // 1) create network offering object
-                s_logger.debug("Adding network offering " + offering);
-                offering.setConcurrentConnections(maxconn);
-                offering.setKeepAliveEnabled(enableKeepAlive);
-                offering = _networkOfferingDao.persist(offering, details);
-                // 2) populate services and providers
-                if (serviceProviderMap != null) {
-                    for (final Network.Service service : serviceProviderMap.keySet()) {
-                        final Set<Provider> providers = serviceProviderMap.get(service);
-                        if (providers != null && !providers.isEmpty()) {
-                            boolean vpcOff = false;
-                            for (final Network.Provider provider : providers) {
-                                if (provider == Provider.VPCVirtualRouter) {
-                                    vpcOff = true;
-                                }
-                                final NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, provider);
-                                _ntwkOffServiceMapDao.persist(offService);
-                                s_logger.trace("Added service for the network offering: " + offService + " with provider " + provider.getName());
-                            }
-
-                            if (vpcOff) {
-                                final List<Service> supportedSvcs = new ArrayList<Service>();
-                                supportedSvcs.addAll(serviceProviderMap.keySet());
-                                _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs);
-                            }
-                        } else {
-                            final NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, null);
-                            _ntwkOffServiceMapDao.persist(offService);
-                            s_logger.trace("Added service for the network offering: " + offService + " with null provider");
-                        }
-                    }
-                }
-
-                return offering;
-            }
-        });
-    }
-
-    protected void validateNtwkOffDetails(final Map<Detail, String> details, final Map<Service, Set<Provider>> serviceProviderMap) {
-        for (final Detail detail : details.keySet()) {
-
-            Provider lbProvider = null;
-            if (detail == NetworkOffering.Detail.InternalLbProvider || detail == NetworkOffering.Detail.PublicLbProvider) {
-                // 1) Vaidate the detail values - have to match the lb provider
-                // name
-                final String providerStr = details.get(detail);
-                if (Network.Provider.getProvider(providerStr) == null) {
-                    throw new InvalidParameterValueException("Invalid value " + providerStr + " for the detail " + detail);
-                }
-                if (serviceProviderMap.get(Service.Lb) != null) {
-                    for (final Provider provider : serviceProviderMap.get(Service.Lb)) {
-                        if (provider.getName().equalsIgnoreCase(providerStr)) {
-                            lbProvider = provider;
-                            break;
-                        }
-                    }
-                }
-
-                if (lbProvider == null) {
-                    throw new InvalidParameterValueException("Invalid value " + details.get(detail) + " for the detail " + detail
-                            + ". The provider is not supported by the network offering");
-                }
-
-                // 2) validate if the provider supports the scheme
-                final Set<Provider> lbProviders = new HashSet<Provider>();
-                lbProviders.add(lbProvider);
-                if (detail == NetworkOffering.Detail.InternalLbProvider) {
-                    _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Internal.toString());
-                } else if (detail == NetworkOffering.Detail.PublicLbProvider) {
-                    _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Public.toString());
-                }
-            }
-        }
-    }
-
-    @Override
-    public Pair<List<? extends NetworkOffering>, Integer> searchForNetworkOfferings(final ListNetworkOfferingsCmd cmd) {
-        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
-        isAscending = isAscending == null ? Boolean.TRUE : isAscending;
-        final Filter searchFilter = new Filter(NetworkOfferingVO.class, "sortKey", isAscending, null, null);
-        final Account caller = CallContext.current().getCallingAccount();
-        final SearchCriteria<NetworkOfferingVO> sc = _networkOfferingDao.createSearchCriteria();
-
-        final Long id = cmd.getId();
-        final Object name = cmd.getNetworkOfferingName();
-        final Object displayText = cmd.getDisplayText();
-        final Object trafficType = cmd.getTrafficType();
-        final Object isDefault = cmd.getIsDefault();
-        final Object specifyVlan = cmd.getSpecifyVlan();
-        final Object availability = cmd.getAvailability();
-        final Object state = cmd.getState();
-        final Long zoneId = cmd.getZoneId();
-        DataCenter zone = null;
-        final Long networkId = cmd.getNetworkId();
-        final String guestIpType = cmd.getGuestIpType();
-        final List<String> supportedServicesStr = cmd.getSupportedServices();
-        final Object specifyIpRanges = cmd.getSpecifyIpRanges();
-        final String tags = cmd.getTags();
-        final Boolean isTagged = cmd.isTagged();
-        final Boolean forVpc = cmd.getForVpc();
-
-        if (zoneId != null) {
-            zone = _entityMgr.findById(DataCenter.class, zoneId);
-            if (zone == null) {
-                throw new InvalidParameterValueException("Unable to find the zone by id=" + zoneId);
-            }
-        }
-
-        final Object keyword = cmd.getKeyword();
-
-        if (keyword != null) {
-            final SearchCriteria<NetworkOfferingVO> ssc = _networkOfferingDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        }
-
-        if (guestIpType != null) {
-            sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType);
-        }
-
-        if (displayText != null) {
-            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
-        }
-
-        if (trafficType != null) {
-            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
-        }
-
-        if (isDefault != null) {
-            sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault);
-        }
-
-        // only root admin can list network offering with specifyVlan = true
-        if (specifyVlan != null) {
-            sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, specifyVlan);
-        }
-
-        if (availability != null) {
-            sc.addAnd("availability", SearchCriteria.Op.EQ, availability);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", SearchCriteria.Op.EQ, state);
-        }
-
-        if (specifyIpRanges != null) {
-            sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges);
-        }
-
-        if (zone != null) {
-            if (zone.getNetworkType() == NetworkType.Basic) {
-                // return empty list as we don't allow to create networks in
-                // basic zone, and shouldn't display networkOfferings
-                return new Pair<List<? extends NetworkOffering>, Integer>(new ArrayList<NetworkOffering>(), 0);
-            }
-        }
-
-        // Don't return system network offerings to the user
-        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, false);
-
-        // if networkId is specified, list offerings available for upgrade only
-        // (for this network)
-        Network network = null;
-        if (networkId != null) {
-            // check if network exists and the caller can operate with it
-            network = _networkModel.getNetwork(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find the network by id=" + networkId);
-            }
-            // Don't allow to update system network
-            final NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-            if (offering.isSystemOnly()) {
-                throw new InvalidParameterValueException("Can't update system networks");
-            }
-
-            _accountMgr.checkAccess(caller, null, true, network);
-
-            final List<Long> offeringIds = _networkModel.listNetworkOfferingsForUpgrade(networkId);
-
-            if (!offeringIds.isEmpty()) {
-                sc.addAnd("id", SearchCriteria.Op.IN, offeringIds.toArray());
-            } else {
-                return new Pair<List<? extends NetworkOffering>, Integer>(new ArrayList<NetworkOffering>(), 0);
-            }
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (tags != null) {
-            sc.addAnd("tags", SearchCriteria.Op.EQ, tags);
-        }
-
-        if (isTagged != null) {
-            if (isTagged) {
-                sc.addAnd("tags", SearchCriteria.Op.NNULL);
-            } else {
-                sc.addAnd("tags", SearchCriteria.Op.NULL);
-            }
-        }
-
-        final List<NetworkOfferingVO> offerings = _networkOfferingDao.search(sc, searchFilter);
-        final Boolean sourceNatSupported = cmd.getSourceNatSupported();
-        final List<String> pNtwkTags = new ArrayList<String>();
-        boolean checkForTags = false;
-        if (zone != null) {
-            final List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest);
-            if (pNtwks.size() > 1) {
-                checkForTags = true;
-                // go through tags
-                for (final PhysicalNetworkVO pNtwk : pNtwks) {
-                    final List<String> pNtwkTag = pNtwk.getTags();
-                    if (pNtwkTag == null || pNtwkTag.isEmpty()) {
-                        throw new CloudRuntimeException("Tags are not defined for physical network in the zone id=" + zoneId);
-                    }
-                    pNtwkTags.addAll(pNtwkTag);
-                }
-            }
-        }
-
-        // filter by supported services
-        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty();
-        final boolean checkIfProvidersAreEnabled = zoneId != null;
-        final boolean parseOfferings = listBySupportedServices || sourceNatSupported != null || checkIfProvidersAreEnabled || forVpc != null || network != null;
-
-        if (parseOfferings) {
-            final List<NetworkOfferingVO> supportedOfferings = new ArrayList<NetworkOfferingVO>();
-            Service[] supportedServices = null;
-
-            if (listBySupportedServices) {
-                supportedServices = new Service[supportedServicesStr.size()];
-                int i = 0;
-                for (final String supportedServiceStr : supportedServicesStr) {
-                    final Service service = Service.getService(supportedServiceStr);
-                    if (service == null) {
-                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
-                    } else {
-                        supportedServices[i] = service;
-                    }
-                    i++;
-                }
-            }
-
-            for (final NetworkOfferingVO offering : offerings) {
-                boolean addOffering = true;
-                List<Service> checkForProviders = new ArrayList<Service>();
-
-                if (checkForTags) {
-                    if (!pNtwkTags.contains(offering.getTags())) {
-                        continue;
-                    }
-                }
-
-                if (listBySupportedServices) {
-                    addOffering = addOffering && _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), supportedServices);
-                }
-
-                if (checkIfProvidersAreEnabled) {
-                    if (supportedServices != null && supportedServices.length > 0) {
-                        checkForProviders = Arrays.asList(supportedServices);
-                    } else {
-                        checkForProviders = _networkModel.listNetworkOfferingServices(offering.getId());
-                    }
-
-                    addOffering = addOffering && _networkModel.areServicesEnabledInZone(zoneId, offering, checkForProviders);
-                }
-
-                if (sourceNatSupported != null) {
-                    addOffering = addOffering && _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.SourceNat) == sourceNatSupported;
-                }
-
-                if (forVpc != null) {
-                    addOffering = addOffering && isOfferingForVpc(offering) == forVpc.booleanValue();
-                } else if (network != null) {
-                    addOffering = addOffering && isOfferingForVpc(offering) == (network.getVpcId() != null);
-                }
-
-                if (addOffering) {
-                    supportedOfferings.add(offering);
-                }
-
-            }
-
-            // Now apply pagination
-            final List<? extends NetworkOffering> wPagination = StringUtils.applyPagination(supportedOfferings, cmd.getStartIndex(), cmd.getPageSizeVal());
-            if (wPagination != null) {
-                final Pair<List<? extends NetworkOffering>, Integer> listWPagination = new Pair<List<? extends NetworkOffering>, Integer>(wPagination, supportedOfferings.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends NetworkOffering>, Integer>(supportedOfferings, supportedOfferings.size());
-        } else {
-            final List<? extends NetworkOffering> wPagination = StringUtils.applyPagination(offerings, cmd.getStartIndex(), cmd.getPageSizeVal());
-            if (wPagination != null) {
-                final Pair<List<? extends NetworkOffering>, Integer> listWPagination = new Pair<List<? extends NetworkOffering>, Integer>(wPagination, offerings.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends NetworkOffering>, Integer>(offerings, offerings.size());
-        }
-    }
-
-    @Override
-    public boolean isOfferingForVpc(final NetworkOffering offering) {
-        return offering.getForVpc();
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_DELETE, eventDescription = "deleting network offering")
-    public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) {
-        final Long offeringId = cmd.getId();
-        CallContext.current().setEventDetails(" Id: " + offeringId);
-
-        // Verify network offering id
-        final NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId);
-        if (offering == null) {
-            throw new InvalidParameterValueException("unable to find network offering " + offeringId);
-        } else if (offering.getRemoved() != null || offering.isSystemOnly()) {
-            throw new InvalidParameterValueException("unable to find network offering " + offeringId);
-        }
-
-        // Don't allow to delete default network offerings
-        if (offering.isDefault() == true) {
-            throw new InvalidParameterValueException("Default network offering can't be deleted");
-        }
-
-        // don't allow to delete network offering if it's in use by existing
-        // networks (the offering can be disabled
-        // though)
-        final int networkCount = _networkDao.getNetworkCountByNetworkOffId(offeringId);
-        if (networkCount > 0) {
-            throw new InvalidParameterValueException("Can't delete network offering " + offeringId + " as its used by " + networkCount + " networks. "
-                    + "To make the network offering unavaiable, disable it");
-        }
-
-        if (_networkOfferingDao.remove(offeringId)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_EDIT, eventDescription = "updating network offering")
-    public NetworkOffering updateNetworkOffering(final UpdateNetworkOfferingCmd cmd) {
-        final String displayText = cmd.getDisplayText();
-        final Long id = cmd.getId();
-        final String name = cmd.getNetworkOfferingName();
-        final String availabilityStr = cmd.getAvailability();
-        final Integer sortKey = cmd.getSortKey();
-        final Integer maxconn = cmd.getMaxconnections();
-        Availability availability = null;
-        final String state = cmd.getState();
-        final String tags = cmd.getTags();
-        CallContext.current().setEventDetails(" Id: " + id);
-
-        // Verify input parameters
-        final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id);
-        if (offeringToUpdate == null) {
-            throw new InvalidParameterValueException("unable to find network offering " + id);
-        }
-
-        // Don't allow to update system network offering
-        if (offeringToUpdate.isSystemOnly()) {
-            throw new InvalidParameterValueException("Can't update system network offerings");
-        }
-
-        final NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id);
-
-        if (name != null) {
-            offering.setName(name);
-        }
-
-        if (displayText != null) {
-            offering.setDisplayText(displayText);
-        }
-
-        if (sortKey != null) {
-            offering.setSortKey(sortKey);
-        }
-
-        if (state != null) {
-            boolean validState = false;
-            for (final NetworkOffering.State st : NetworkOffering.State.values()) {
-                if (st.name().equalsIgnoreCase(state)) {
-                    validState = true;
-                    offering.setState(st);
-                }
-            }
-            if (!validState) {
-                throw new InvalidParameterValueException("Incorrect state value: " + state);
-            }
-        }
-
-        if (tags != null) {
-            List<DataCenterVO> dataCenters = _zoneDao.listAll();
-            TrafficType trafficType = offeringToUpdate.getTrafficType();
-            String oldTags = offeringToUpdate.getTags();
-
-            for (DataCenterVO dataCenter : dataCenters) {
-                long zoneId = dataCenter.getId();
-                long newPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, tags, trafficType);
-                if (oldTags != null) {
-                    long oldPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, oldTags, trafficType);
-                    if (newPhysicalNetworkId != oldPhysicalNetworkId) {
-                        throw new InvalidParameterValueException("New tags: selects different physical network for zone " + zoneId);
-                    }
-                }
-            }
-
-            offering.setTags(tags);
-        }
-
-        // Verify availability
-        if (availabilityStr != null) {
-            for (final Availability avlb : Availability.values()) {
-                if (avlb.name().equalsIgnoreCase(availabilityStr)) {
-                    availability = avlb;
-                }
-            }
-            if (availability == null) {
-                throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
-            } else {
-                if (availability == NetworkOffering.Availability.Required) {
-                    final boolean canOffBeRequired = offeringToUpdate.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedByNetworkOffering(
-                            offeringToUpdate.getId(), Service.SourceNat);
-                    if (!canOffBeRequired) {
-                        throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
-                                + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
-                    }
-
-                    // only one network offering in the system can be Required
-                    final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-                    if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) {
-                        throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability "
-                                + Availability.Required);
-                    }
-                }
-                offering.setAvailability(availability);
-            }
-        }
-        if (_ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Lb)) {
-            if (maxconn != null) {
-                offering.setConcurrentConnections(maxconn);
-            }
-        }
-
-        if (_networkOfferingDao.update(id, offering)) {
-            return _networkOfferingDao.findById(id);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + "default zone", async = true)
-    public AccountVO markDefaultZone(final String accountName, final long domainId, final long defaultZoneId) {
-
-        // Check if the account exists
-        final Account account = _accountDao.findEnabledAccount(accountName, domainId);
-        if (account == null) {
-            s_logger.error("Unable to find account by name: " + accountName + " in domain " + domainId);
-            throw new InvalidParameterValueException("Account by name: " + accountName + " doesn't exist in domain " + domainId);
-        }
-
-        // Don't allow modification of system account
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new InvalidParameterValueException("Can not modify system account");
-        }
-
-        final AccountVO acctForUpdate = _accountDao.findById(account.getId());
-
-        acctForUpdate.setDefaultZoneId(defaultZoneId);
-
-        if (_accountDao.update(account.getId(), acctForUpdate)) {
-            CallContext.current().setEventDetails("Default zone id= " + defaultZoneId);
-            return _accountDao.findById(account.getId());
-        } else {
-            return null;
-        }
-    }
-
-    // Note: This method will be used for entity name validations in the coming
-    // releases (place holder for now)
-    @SuppressWarnings("unused")
-    private void validateEntityName(final String str) {
-        final String forbidden = "~!@#$%^&*()+=";
-        final char[] searchChars = forbidden.toCharArray();
-        if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) {
-            return;
-        }
-        for (int i = 0; i < str.length(); i++) {
-            final char ch = str.charAt(i);
-            for (int j = 0; j < searchChars.length; j++) {
-                if (searchChars[j] == ch) {
-                    throw new InvalidParameterValueException("Name cannot contain any of the following special characters:" + forbidden);
-                }
-            }
-        }
-    }
-
-    @Override
-    public Integer getNetworkOfferingNetworkRate(final long networkOfferingId, final Long dataCenterId) {
-
-        // validate network offering information
-        final NetworkOffering no = _entityMgr.findById(NetworkOffering.class, networkOfferingId);
-        if (no == null) {
-            throw new InvalidParameterValueException("Unable to find network offering by id=" + networkOfferingId);
-        }
-
-        Integer networkRate;
-        if (no.getRateMbps() != null) {
-            networkRate = no.getRateMbps();
-        } else {
-            networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
-        }
-
-        // networkRate is unsigned int in netowrkOfferings table, and can't be
-        // set to -1
-        // so 0 means unlimited; we convert it to -1, so we are consistent with
-        // all our other resources where -1 means unlimited
-        if (networkRate == 0) {
-            networkRate = -1;
-        }
-
-        return networkRate;
-    }
-
-    @Override
-    public Account getVlanAccount(final long vlanId) {
-        final Vlan vlan = _vlanDao.findById(vlanId);
-
-        // if vlan is Virtual Account specific, get vlan information from the
-        // accountVlanMap; otherwise get account information
-        // from the network
-        if (vlan.getVlanType() == VlanType.VirtualNetwork) {
-            final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanId);
-            if (maps != null && !maps.isEmpty()) {
-                return _accountMgr.getAccount(maps.get(0).getAccountId());
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Domain getVlanDomain(long vlanId) {
-        Vlan vlan = _vlanDao.findById(vlanId);
-        Long domainId = null;
-
-        // if vlan is Virtual Domain specific, get vlan information from the
-        // accountVlanMap; otherwise get account information
-        // from the network
-        if (vlan.getVlanType() == VlanType.VirtualNetwork) {
-            List<DomainVlanMapVO> maps = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanId);
-            if (maps != null && !maps.isEmpty()) {
-                return _domainDao.findById(maps.get(0).getDomainId());
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<? extends NetworkOffering> listNetworkOfferings(final TrafficType trafficType, final boolean systemOnly) {
-        final Filter searchFilter = new Filter(NetworkOfferingVO.class, "created", false, null, null);
-        final SearchCriteria<NetworkOfferingVO> sc = _networkOfferingDao.createSearchCriteria();
-        if (trafficType != null) {
-            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
-        }
-        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, systemOnly);
-
-        return _networkOfferingDao.search(sc, searchFilter);
-    }
-
-     @Override
-     @DB
-     public boolean releaseDomainSpecificVirtualRanges(final long domainId) {
-        final List<DomainVlanMapVO> maps = _domainVlanMapDao.listDomainVlanMapsByDomain(domainId);
-        if (CollectionUtils.isNotEmpty(maps)) {
-            try {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        for (DomainVlanMapVO map : maps) {
-                            if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
-                                throw new CloudRuntimeException("Failed to release domain specific virtual ip ranges for domain id=" + domainId);
-                            }
-                        }
-                    }
-                });
-            } catch (final CloudRuntimeException e) {
-                s_logger.error(e);
-                return false;
-            }
-        } else {
-            s_logger.trace("Domain id=" + domainId + " has no domain specific virtual ip ranges, nothing to release");
-        }
-        return true;
-    }
-
-    @Override
-    @DB
-    public boolean releaseAccountSpecificVirtualRanges(final long accountId) {
-        final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId);
-        if (maps != null && !maps.isEmpty()) {
-            try {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        for (final AccountVlanMapVO map : maps) {
-                            if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
-                                throw new CloudRuntimeException("Failed to release account specific virtual ip ranges for account id=" + accountId);
-                            }
-                        }
-                    }
-                });
-            } catch (final CloudRuntimeException e) {
-                s_logger.error(e);
-                return false;
-            }
-        } else {
-            s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to release");
-        }
-        return true;
-    }
-
-    @Override
-    public AllocationState findClusterAllocationState(final ClusterVO cluster) {
-
-        if (cluster.getAllocationState() == AllocationState.Disabled) {
-            return AllocationState.Disabled;
-        } else if (ApiDBUtils.findPodById(cluster.getPodId()).getAllocationState() == AllocationState.Disabled) {
-            return AllocationState.Disabled;
-        } else {
-            final DataCenterVO zone = ApiDBUtils.findZoneById(cluster.getDataCenterId());
-            return zone.getAllocationState();
-        }
-    }
-
-    @Override
-    public AllocationState findPodAllocationState(final HostPodVO pod) {
-
-        if (pod.getAllocationState() == AllocationState.Disabled) {
-            return AllocationState.Disabled;
-        } else {
-            final DataCenterVO zone = ApiDBUtils.findZoneById(pod.getDataCenterId());
-            return zone.getAllocationState();
-        }
-    }
-
-    @Override
-    public Long getDefaultPageSize() {
-        return _defaultPageSize;
-    }
-
-    @Override
-    public Integer getServiceOfferingNetworkRate(final long serviceOfferingId, final Long dataCenterId) {
-
-        // validate network offering information
-        final ServiceOffering offering = _serviceOfferingDao.findById(serviceOfferingId);
-        if (offering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering by id=" + serviceOfferingId);
-        }
-
-        Integer networkRate;
-        if (offering.getRateMbps() != null) {
-            networkRate = offering.getRateMbps();
-        } else {
-            // for domain router service offering, get network rate from
-            if (offering.getSystemVmType() != null && offering.getSystemVmType().equalsIgnoreCase(VirtualMachine.Type.DomainRouter.toString())) {
-                networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
-            } else {
-                networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key()));
-            }
-        }
-
-        // networkRate is unsigned int in serviceOffering table, and can't be
-        // set to -1
-        // so 0 means unlimited; we convert it to -1, so we are consistent with
-        // all our other resources where -1 means unlimited
-        if (networkRate == 0) {
-            networkRate = -1;
-        }
-
-        return networkRate;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false)
-    public PortableIpRange createPortableIpRange(final CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
-        final Integer regionId = cmd.getRegionId();
-        final String startIP = cmd.getStartIp();
-        final String endIP = cmd.getEndIp();
-        final String gateway = cmd.getGateway();
-        final String netmask = cmd.getNetmask();
-        String vlanId = cmd.getVlan();
-
-        final RegionVO region = _regionDao.findById(regionId);
-        if (region == null) {
-            throw new InvalidParameterValueException("Invalid region ID: " + regionId);
-        }
-
-        if (!NetUtils.isValidIp4(startIP) || !NetUtils.isValidIp4(endIP) || !NetUtils.validIpRange(startIP, endIP)) {
-            throw new InvalidParameterValueException("Invalid portable ip  range: " + startIP + "-" + endIP);
-        }
-
-        if (!NetUtils.sameSubnet(startIP, gateway, netmask)) {
-            throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as "
-                    + "your portable IP range's gateway and as per the IP range's netmask.");
-        }
-
-        if (!NetUtils.sameSubnet(endIP, gateway, netmask)) {
-            throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as "
-                    + "your portable IP range's gateway and as per the IP range's netmask.");
-        }
-
-        if (checkOverlapPortableIpRange(regionId, startIP, endIP)) {
-            throw new InvalidParameterValueException("Ip  range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region " + regionId);
-        }
-
-        if (vlanId == null) {
-            vlanId = Vlan.UNTAGGED;
-        } else {
-            if (!NetUtils.isValidVlan(vlanId)) {
-                throw new InvalidParameterValueException("Invalid vlan id " + vlanId);
-            }
-
-            final List<DataCenterVO> zones = _zoneDao.listAllZones();
-            if (zones != null && !zones.isEmpty()) {
-                for (final DataCenterVO zone : zones) {
-                    // check if there is zone vlan with same id
-                    if (_vlanDao.findByZoneAndVlanId(zone.getId(), vlanId) != null) {
-                        throw new InvalidParameterValueException("Found a VLAN id " + vlanId + " already existing in" + " zone " + zone.getUuid()
-                                + " that conflicts with VLAN id of the portable ip range being configured");
-                    }
-                    //check if there is a public ip range that overlaps with portable ip range being created
-                    checkOverlapPublicIpRange(zone.getId(), startIP, endIP);
-                }
-            }
-
-        }
-        final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
-        portableIpLock.lock(5);
-        try {
-            final String vlanIdFinal = vlanId;
-            return Transaction.execute(new TransactionCallback<PortableIpRangeVO>() {
-                @Override
-                public PortableIpRangeVO doInTransaction(final TransactionStatus status) {
-                    PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanIdFinal, gateway, netmask, startIP, endIP);
-                    portableIpRange = _portableIpRangeDao.persist(portableIpRange);
-
-                    long startIpLong = NetUtils.ip2Long(startIP);
-                    final long endIpLong = NetUtils.ip2Long(endIP);
-                    while (startIpLong <= endIpLong) {
-                        final PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanIdFinal, gateway, netmask, NetUtils.long2Ip(startIpLong));
-                        _portableIpDao.persist(portableIP);
-                        startIpLong++;
-                    }
-
-                    // implicitly enable portable IP service for the region
-                    region.setPortableipEnabled(true);
-                    _regionDao.update(region.getId(), region);
-
-                    return portableIpRange;
-                }
-            });
-        } finally {
-            portableIpLock.unlock();
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_DELETE, eventDescription = "deleting portable ip range", async = false)
-    public boolean deletePortableIpRange(final DeletePortableIpRangeCmd cmd) {
-        final long rangeId = cmd.getId();
-
-        final PortableIpRangeVO portableIpRange = _portableIpRangeDao.findById(rangeId);
-        if (portableIpRange == null) {
-            throw new InvalidParameterValueException("Please specify a valid portable IP range id.");
-        }
-
-        final List<PortableIpVO> fullIpRange = _portableIpDao.listByRangeId(portableIpRange.getId());
-        final List<PortableIpVO> freeIpRange = _portableIpDao.listByRangeIdAndState(portableIpRange.getId(), PortableIp.State.Free);
-
-        if (fullIpRange != null && freeIpRange != null) {
-            if (fullIpRange.size() == freeIpRange.size()) {
-                _portableIpRangeDao.expunge(portableIpRange.getId());
-                final List<PortableIpRangeVO> pipranges = _portableIpRangeDao.listAll();
-                if (pipranges == null || pipranges.isEmpty()) {
-                    final RegionVO region = _regionDao.findById(portableIpRange.getRegionId());
-                    region.setPortableipEnabled(false);
-                    _regionDao.update(region.getId(), region);
-                }
-                return true;
-            } else {
-                throw new InvalidParameterValueException("Can't delete portable IP range as there are IP's assigned.");
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public List<? extends PortableIpRange> listPortableIpRanges(final ListPortableIpRangesCmd cmd) {
-        final Integer regionId = cmd.getRegionIdId();
-        final Long rangeId = cmd.getPortableIpRangeId();
-
-        final List<PortableIpRangeVO> ranges = new ArrayList<PortableIpRangeVO>();
-        if (regionId != null) {
-            final Region region = _regionDao.findById(regionId);
-            if (region == null) {
-                throw new InvalidParameterValueException("Invalid region ID: " + regionId);
-            }
-            return _portableIpRangeDao.listByRegionId(regionId);
-        }
-
-        if (rangeId != null) {
-            final PortableIpRangeVO range = _portableIpRangeDao.findById(rangeId);
-            if (range == null) {
-                throw new InvalidParameterValueException("Invalid portable IP range ID: " + regionId);
-            }
-            ranges.add(range);
-            return ranges;
-        }
-
-        return _portableIpRangeDao.listAll();
-    }
-
-    @Override
-    public List<? extends PortableIp> listPortableIps(final long id) {
-
-        final PortableIpRangeVO portableIpRange = _portableIpRangeDao.findById(id);
-        if (portableIpRange == null) {
-            throw new InvalidParameterValueException("Please specify a valid portable IP range id.");
-        }
-
-        return _portableIpDao.listByRangeId(portableIpRange.getId());
-    }
-
-    private boolean checkOverlapPortableIpRange(final int regionId, final String newStartIpStr, final String newEndIpStr) {
-        final long newStartIp = NetUtils.ip2Long(newStartIpStr);
-        final long newEndIp = NetUtils.ip2Long(newEndIpStr);
-
-        final List<PortableIpRangeVO> existingPortableIPRanges = _portableIpRangeDao.listByRegionId(regionId);
-
-        if (existingPortableIPRanges == null || existingPortableIPRanges.isEmpty()) {
-            return false;
-        }
-
-        for (final PortableIpRangeVO portableIpRange : existingPortableIPRanges) {
-            final String ipRangeStr = portableIpRange.getIpRange();
-            final String[] range = ipRangeStr.split("-");
-            final long startip = NetUtils.ip2Long(range[0]);
-            final long endIp = NetUtils.ip2Long(range[1]);
-
-            if (newStartIp >= startip && newStartIp <= endIp || newEndIp >= startip && newEndIp <= endIp) {
-                return true;
-            }
-
-            if (startip >= newStartIp && startip <= newEndIp || endIp >= newStartIp && endIp <= newEndIp) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public List<SecurityChecker> getSecChecker() {
-        return _secChecker;
-    }
-
-    @Inject
-    public void setSecChecker(final List<SecurityChecker> secChecker) {
-        _secChecker = secChecker;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ConfigurationManagerImpl.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {SystemVMUseLocalStorage};
-    }
-}
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
deleted file mode 100644
index e9cf926..0000000
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ /dev/null
@@ -1,1737 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.consoleproxy;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.agent.lb.IndirectAgentLB;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keys.KeysManager;
-import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.framework.security.keystore.KeystoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
-import com.cloud.agent.manager.Commands;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManagerImpl;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.ConsoleProxyConnectionInfo;
-import com.cloud.info.ConsoleProxyInfo;
-import com.cloud.info.ConsoleProxyLoadInfo;
-import com.cloud.info.ConsoleProxyStatus;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.info.RunningHostInfoAgregator;
-import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.events.SubscriptionMgr;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.ConsoleProxyVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.SystemVmLoadScanHandler;
-import com.cloud.vm.SystemVmLoadScanner;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineGuru;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-//
-// Possible console proxy state transition cases
-//        Stopped --> Starting -> Running
-//        HA -> Stopped -> Starting -> Running
-//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
-//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
-//        Running -> HA            (if agent lost connection)
-//        Stopped -> Destroyed
-//
-// Starting, HA, Migrating, Running state are all counted as "Open" for available capacity calculation
-// because sooner or later, it will be driven into Running state
-//
-public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
-    private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
-
-    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3 minutes
-
-    private static final int STARTUP_DELAY = 60000; // 60 seconds
-
-    private int _consoleProxyPort = ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT;
-
-    private int _mgmtPort = 8250;
-
-    private List<ConsoleProxyAllocator> _consoleProxyAllocators;
-
-    @Inject
-    private ConsoleProxyDao _consoleProxyDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private HostPodDao _podDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private VMInstanceDao _instanceDao;
-    @Inject
-    private TemplateDataStoreDao _vmTemplateStoreDao;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private NetworkOrchestrationService _networkMgr;
-    @Inject
-    private NetworkModel _networkModel;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private ServiceOfferingDao _offeringDao;
-    @Inject
-    private NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private RulesManager _rulesMgr;
-    @Inject
-    private IPAddressDao _ipAddressDao;
-    @Inject
-    private KeysManager _keysMgr;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private IndirectAgentLB indirectAgentLB;
-
-    private ConsoleProxyListener _listener;
-
-    private ServiceOfferingVO _serviceOffering;
-
-    /*
-     * private final ExecutorService _requestHandlerScheduler = Executors.newCachedThreadPool(new
-     * NamedThreadFactory("Request-handler"));
-     */
-    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
-    private int _capacityPerProxy = ConsoleProxyManager.DEFAULT_PROXY_CAPACITY;
-    private int _standbyCapacity = ConsoleProxyManager.DEFAULT_STANDBY_CAPACITY;
-
-    private boolean _useStorageVm;
-    private boolean _disableRpFilter = false;
-    private String _instance;
-
-    private int _proxySessionTimeoutValue = DEFAULT_PROXY_SESSION_TIMEOUT;
-    private boolean _sslEnabled = false;
-    private String _consoleProxyUrlDomain;
-
-    // global load picture at zone basis
-    private SystemVmLoadScanner<Long> _loadScanner;
-    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
-    private Map<Long, ConsoleProxyLoadInfo> _zoneProxyCountMap; // map <zone id, info about proxy VMs count in zone>
-    private Map<Long, ConsoleProxyLoadInfo> _zoneVmCountMap; // map <zone id, info about running VMs count in zone>
-
-    private String _staticPublicIp;
-    private int _staticPort;
-
-    private final GlobalLock _allocProxyLock = GlobalLock.getInternLock(getAllocProxyLockName());
-
-    @Inject
-    private KeystoreDao _ksDao;
-    @Inject
-    private KeystoreManager _ksMgr;
-
-    public class VmBasedAgentHook extends AgentHookBase {
-
-        public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) {
-            super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr);
-        }
-
-        @Override
-        public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
-            if (cmd.getLoadInfo() == null) {
-                return;
-            }
-
-            ConsoleProxyStatus status = null;
-            try {
-                GsonBuilder gb = new GsonBuilder();
-                gb.setVersion(1.3);
-                Gson gson = gb.create();
-                status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
-            } catch (Throwable e) {
-                s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
-            }
-
-            if (status != null) {
-                int count = 0;
-                if (status.getConnections() != null) {
-                    count = status.getConnections().length;
-                }
-
-                byte[] details = null;
-                if (cmd.getLoadInfo() != null) {
-                    details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
-                }
-                _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
-            } else {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
-                }
-
-                _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
-            }
-        }
-
-        @Override
-        public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
-
-            if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
-                // be it either in alert or in disconnected state, the agent
-                // process
-                // may be gone in the VM,
-                // we will be reacting to stop the corresponding VM and let the
-                // scan
-                // process to
-                HostVO host = _hostDao.findById(agentId);
-                if (host.getType() == Type.ConsoleProxy) {
-                    String name = host.getName();
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Console proxy agent disconnected, proxy: " + name);
-                    }
-                    if (name != null && name.startsWith("v-")) {
-                        String[] tokens = name.split("-");
-                        long proxyVmId = 0;
-                        try {
-                            proxyVmId = Long.parseLong(tokens[1]);
-                        } catch (NumberFormatException e) {
-                            s_logger.error("Unexpected exception " + e.getMessage(), e);
-                            return;
-                        }
-
-                        final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-                        if (proxy != null) {
-
-                            // Disable this feature for now, as it conflicts
-                            // with
-                            // the case of allowing user to reboot console proxy
-                            // when rebooting happens, we will receive
-                            // disconnect
-                            // here and we can't enter into stopping process,
-                            // as when the rebooted one comes up, it will kick
-                            // off a
-                            // newly started one and trigger the process
-                            // continue on forever
-
-                            /*
-                             * _capacityScanScheduler.execute(new Runnable() {
-                             * public void run() { if(s_logger.isInfoEnabled())
-                             * s_logger.info("Stop console proxy " +
-                             * proxy.getName() +
-                             * " VM because of that the agent running inside it has disconnected"
-                             * ); stopProxy(proxy.getId()); } });
-                             */
-                        } else {
-                            if (s_logger.isInfoEnabled()) {
-                                s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: " + name);
-                            }
-                        }
-                    } else {
-                        assert (false) : "Invalid console proxy name: " + name;
-                    }
-                }
-            }
-
-        }
-
-        @Override
-        protected HostVO findConsoleProxyHost(StartupProxyCommand startupCmd) {
-            long proxyVmId = startupCmd.getProxyVmId();
-            ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
-            if (consoleProxy == null) {
-                s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
-                return null;
-            }
-
-            assert (consoleProxy != null);
-            return findConsoleProxyHostByName(consoleProxy.getHostName());
-        }
-
-    }
-
-    @Override
-    public ConsoleProxyInfo assignProxy(final long dataCenterId, final long vmId) {
-        ConsoleProxyVO proxy = doAssignProxy(dataCenterId, vmId);
-        if (proxy == null) {
-            return null;
-        }
-
-        if (proxy.getPublicIpAddress() == null) {
-            s_logger.warn("Assigned console proxy does not have a valid public IP address");
-            return null;
-        }
-
-        KeystoreVO ksVo = _ksDao.findByName(ConsoleProxyManager.CERTIFICATE_NAME);
-        if (proxy.isSslEnabled() && ksVo == null) {
-            s_logger.warn("SSL enabled for console proxy but no server certificate found in database");
-        }
-
-        if (_staticPublicIp == null) {
-            return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), _consoleProxyUrlDomain);
-        } else {
-            return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, _consoleProxyUrlDomain);
-        }
-    }
-
-    public ConsoleProxyVO doAssignProxy(long dataCenterId, long vmId) {
-        ConsoleProxyVO proxy = null;
-        VMInstanceVO vm = _instanceDao.findById(vmId);
-
-        if (vm == null) {
-            s_logger.warn("VM " + vmId + " no longer exists, return a null proxy for vm:" + vmId);
-            return null;
-        }
-
-        if (vm != null && vm.getState() != State.Starting && vm.getState() != State.Running) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Detected that vm : " + vmId + " is not currently in starting or running state, we will fail the proxy assignment for it");
-            }
-            return null;
-        }
-
-        if (_allocProxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-            try {
-                if (vm.getProxyId() != null) {
-                    proxy = _consoleProxyDao.findById(vm.getProxyId());
-
-                    if (proxy != null) {
-                        if (!isInAssignableState(proxy)) {
-                            if (s_logger.isInfoEnabled()) {
-                                s_logger.info("A previous assigned proxy is not assignable now, reassign console proxy for user vm : " + vmId);
-                            }
-                            proxy = null;
-                        } else {
-                            if (_consoleProxyDao.getProxyActiveLoad(proxy.getId()) < _capacityPerProxy || hasPreviousSession(proxy, vm)) {
-                                if (s_logger.isTraceEnabled()) {
-                                    s_logger.trace("Assign previous allocated console proxy for user vm : " + vmId);
-                                }
-
-                                if (proxy.getActiveSession() >= _capacityPerProxy) {
-                                    s_logger.warn("Assign overloaded proxy to user VM as previous session exists, user vm : " + vmId);
-                                }
-                            } else {
-                                proxy = null;
-                            }
-                        }
-                    }
-                }
-
-                if (proxy == null) {
-                    proxy = assignProxyFromRunningPool(dataCenterId);
-                }
-            } finally {
-                _allocProxyLock.unlock();
-            }
-        } else {
-            s_logger.error("Unable to acquire synchronization lock to get/allocate proxy resource for vm :" + vmId +
-                ". Previous console proxy allocation is taking too long");
-        }
-
-        if (proxy == null) {
-            s_logger.warn("Unable to find or allocate console proxy resource");
-            return null;
-        }
-
-        // if it is a new assignment or a changed assignment, update the record
-        if (vm.getProxyId() == null || vm.getProxyId().longValue() != proxy.getId()) {
-            _instanceDao.updateProxyId(vmId, proxy.getId(), DateUtil.currentGMTTime());
-        }
-
-        proxy.setSslEnabled(_sslEnabled);
-        if (_sslEnabled) {
-            proxy.setPort(443);
-        } else {
-            proxy.setPort(80);
-        }
-
-        return proxy;
-    }
-
-    private static boolean isInAssignableState(ConsoleProxyVO proxy) {
-        // console proxies that are in states of being able to serve user VM
-        State state = proxy.getState();
-        if (state == State.Running) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private boolean hasPreviousSession(ConsoleProxyVO proxy, VMInstanceVO vm) {
-
-        ConsoleProxyStatus status = null;
-        try {
-            GsonBuilder gb = new GsonBuilder();
-            gb.setVersion(1.3);
-            Gson gson = gb.create();
-
-            byte[] details = proxy.getSessionDetails();
-            status = gson.fromJson(details != null ? new String(details, Charset.forName("US-ASCII")) : null, ConsoleProxyStatus.class);
-        } catch (Throwable e) {
-            s_logger.warn("Unable to parse proxy session details : " + Arrays.toString(proxy.getSessionDetails()));
-        }
-
-        if (status != null && status.getConnections() != null) {
-            ConsoleProxyConnectionInfo[] connections = status.getConnections();
-            for (int i = 0; i < connections.length; i++) {
-                long taggedVmId = 0;
-                if (connections[i].tag != null) {
-                    try {
-                        taggedVmId = Long.parseLong(connections[i].tag);
-                    } catch (NumberFormatException e) {
-                        s_logger.warn("Unable to parse console proxy connection info passed through tag: " + connections[i].tag, e);
-                    }
-                }
-                if (taggedVmId == vm.getId()) {
-                    return true;
-                }
-            }
-
-            //
-            // even if we are not in the list, it may because we haven't
-            // received load-update yet
-            // wait until session time
-            //
-            if (DateUtil.currentGMTTime().getTime() - vm.getProxyAssignTime().getTime() < _proxySessionTimeoutValue) {
-                return true;
-            }
-
-            return false;
-        } else {
-            s_logger.error("No proxy load info on an overloaded proxy ?");
-            return false;
-        }
-    }
-
-    @Override
-    public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
-        try {
-            ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-            if (proxy.getState() == VirtualMachine.State.Running) {
-                return proxy;
-            }
-
-            String restart = _configDao.getValue(Config.ConsoleProxyRestart.key());
-            if (!ignoreRestartSetting && restart != null && restart.equalsIgnoreCase("false")) {
-                return null;
-            }
-
-            if (proxy.getState() == VirtualMachine.State.Stopped) {
-                _itMgr.advanceStart(proxy.getUuid(), null, null);
-                proxy = _consoleProxyDao.findById(proxy.getId());
-                return proxy;
-            }
-
-            // For VMs that are in Stopping, Starting, Migrating state, let client to wait by returning null
-            // as sooner or later, Starting/Migrating state will be transited to Running and Stopping will be transited
-            // to Stopped to allow Starting of it
-            s_logger.warn("Console proxy is not in correct state to be started: " + proxy.getState());
-            return null;
-        } catch (StorageUnavailableException e) {
-            s_logger.warn("Exception while trying to start console proxy", e);
-            return null;
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("Exception while trying to start console proxy", e);
-            return null;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Exception while trying to start console proxy", e);
-            return null;
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Runtime Exception while trying to start console proxy", e);
-            return null;
-        } catch (CloudRuntimeException e) {
-            s_logger.warn("Runtime Exception while trying to start console proxy", e);
-            return null;
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Runtime Exception while trying to start console proxy", e);
-            return null;
-        }
-    }
-
-    public ConsoleProxyVO assignProxyFromRunningPool(long dataCenterId) {
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Assign console proxy from running pool for request from data center : " + dataCenterId);
-        }
-
-        ConsoleProxyAllocator allocator = getCurrentAllocator();
-        assert (allocator != null);
-        List<ConsoleProxyVO> runningList = _consoleProxyDao.getProxyListInStates(dataCenterId, State.Running);
-        if (runningList != null && runningList.size() > 0) {
-            Iterator<ConsoleProxyVO> it = runningList.iterator();
-            while (it.hasNext()) {
-                ConsoleProxyVO proxy = it.next();
-                if (proxy.getActiveSession() >= _capacityPerProxy) {
-                    it.remove();
-                }
-            }
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Running proxy pool size : " + runningList.size());
-                for (ConsoleProxyVO proxy : runningList) {
-                    s_logger.trace("Running proxy instance : " + proxy.getHostName());
-                }
-            }
-
-            List<Pair<Long, Integer>> l = _consoleProxyDao.getProxyLoadMatrix();
-            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
-            if (l != null) {
-                for (Pair<Long, Integer> p : l) {
-                    loadInfo.put(p.first(), p.second());
-
-                    if (s_logger.isTraceEnabled()) {
-                        s_logger.trace("Running proxy instance allocation load { proxy id : " + p.first() + ", load : " + p.second() + "}");
-                    }
-                }
-            }
-            Long allocated = allocator.allocProxy(runningList, loadInfo, dataCenterId);
-            if (allocated == null) {
-                s_logger.debug("Unable to find a console proxy ");
-                return null;
-            }
-            return _consoleProxyDao.findById(allocated);
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Empty running proxy pool for now in data center : " + dataCenterId);
-            }
-        }
-        return null;
-    }
-
-    public ConsoleProxyVO assignProxyFromStoppedPool(long dataCenterId) {
-
-        // practically treat all console proxy VM that is not in Running state but can be entering into Running state as
-        // candidates
-        // this is to prevent launching unneccessary console proxy VMs because of temporarily unavailable state
-        List<ConsoleProxyVO> l = _consoleProxyDao.getProxyListInStates(dataCenterId, State.Starting, State.Stopped, State.Migrating, State.Stopping);
-        if (l != null && l.size() > 0) {
-            return l.get(0);
-        }
-
-        return null;
-    }
-
-    public ConsoleProxyVO startNew(long dataCenterId) throws ConcurrentOperationException {
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
-        }
-
-        if (!allowToLaunchNew(dataCenterId)) {
-            s_logger.warn("The number of launched console proxy on zone " + dataCenterId + " has reached to limit");
-            return null;
-        }
-
-        VMTemplateVO template = null;
-        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
-        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
-        if (template == null) {
-            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
-        }
-
-        Map<String, Object> context = createProxyInstance(dataCenterId, template);
-
-        long proxyVmId = (Long)context.get("proxyVmId");
-        if (proxyVmId == 0) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Creating proxy instance failed, data center id : " + dataCenterId);
-            }
-            return null;
-        }
-
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-        if (proxy != null) {
-            SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
-                new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_CREATED, dataCenterId, proxy.getId(), proxy, null));
-            return proxy;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to allocate console proxy storage, remove the console proxy record from DB, proxy id: " + proxyVmId);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the default network for the console proxy VM, based on the zone it is in. Delegates to
-     * either {@link #getDefaultNetworkForZone(DataCenter)} or {@link #getDefaultNetworkForAdvancedSGZone(DataCenter)},
-     * depending on the zone network type and whether or not security groups are enabled in the zone.
-     * @param dc - The zone (DataCenter) of the console proxy VM.
-     * @return The default network for use with the console proxy VM.
-     */
-    protected NetworkVO getDefaultNetworkForCreation(DataCenter dc) {
-        if (dc.getNetworkType() == NetworkType.Advanced) {
-            return getDefaultNetworkForAdvancedZone(dc);
-        } else {
-            return getDefaultNetworkForBasicZone(dc);
-        }
-    }
-
-    /**
-     * Get default network for a console proxy VM starting up in an advanced zone. If the zone
-     * is security group-enabled, the first network found that supports SG services is returned.
-     * If the zone is not SG-enabled, the Public network is returned.
-     * @param dc - The zone.
-     * @return The selected default network.
-     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
-     */
-    protected NetworkVO getDefaultNetworkForAdvancedZone(DataCenter dc) {
-        if (dc.getNetworkType() != NetworkType.Advanced) {
-            throw new CloudRuntimeException("Zone " + dc + " is not advanced.");
-        }
-
-        if (dc.isSecurityGroupEnabled()) {
-            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dc.getId());
-            if (CollectionUtils.isEmpty(networks)) {
-                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
-            }
-
-            return networks.get(0);
-        }
-        else {
-            TrafficType defaultTrafficType = TrafficType.Public;
-            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
-
-            // api should never allow this situation to happen
-            if (defaultNetworks.size() != 1) {
-                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-            }
-
-            return defaultNetworks.get(0);
-        }
-    }
-
-    /**
-     * Get default network for console proxy VM for starting up in a basic zone. Basic zones select
-     * the Guest network whether or not the zone is SG-enabled.
-     * @param dc - The zone.
-     * @return The default network according to the zone's network selection rules.
-     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
-     */
-    protected NetworkVO getDefaultNetworkForBasicZone(DataCenter dc) {
-        if (dc.getNetworkType() != NetworkType.Basic) {
-            throw new CloudRuntimeException("Zone " + dc + "is not basic.");
-        }
-
-        TrafficType defaultTrafficType = TrafficType.Guest;
-        List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
-
-        // api should never allow this situation to happen
-        if (defaultNetworks.size() != 1) {
-            throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-        }
-
-        return defaultNetworks.get(0);
-    }
-
-    protected Map<String, Object> createProxyInstance(long dataCenterId, VMTemplateVO template) throws ConcurrentOperationException {
-
-        long id = _consoleProxyDao.getNextInSequence(Long.class, "id");
-        String name = VirtualMachineName.getConsoleProxyName(id, _instance);
-        DataCenterVO dc = _dcDao.findById(dataCenterId);
-        Account systemAcct = _accountMgr.getSystemAccount();
-
-        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
-
-        NetworkVO defaultNetwork = getDefaultNetworkForCreation(dc);
-
-        List<? extends NetworkOffering> offerings =
-            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork);
-        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(offerings.size() + 1);
-        NicProfile defaultNic = new NicProfile();
-        defaultNic.setDefaultNic(true);
-        defaultNic.setDeviceId(2);
-
-        networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
-                new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
-
-        for (NetworkOffering offering : offerings) {
-            networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), new ArrayList<NicProfile>());
-        }
-
-        ServiceOfferingVO serviceOffering = _serviceOffering;
-        if (serviceOffering == null) {
-            serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
-        }
-        ConsoleProxyVO proxy =
-            new ConsoleProxyVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
-                systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), 0, serviceOffering.getOfferHA());
-        proxy.setDynamicallyScalable(template.isDynamicallyScalable());
-        proxy = _consoleProxyDao.persist(proxy);
-        try {
-            _itMgr.allocate(name, template, serviceOffering, networks, plan, null);
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("InsufficientCapacity", e);
-            throw new CloudRuntimeException("Insufficient capacity exception", e);
-        }
-
-        Map<String, Object> context = new HashMap<String, Object>();
-        context.put("dc", dc);
-        HostPodVO pod = _podDao.findById(proxy.getPodIdToDeployIn());
-        context.put("pod", pod);
-        context.put("proxyVmId", proxy.getId());
-
-        return context;
-    }
-
-    private ConsoleProxyAllocator getCurrentAllocator() {
-        // for now, only one adapter is supported
-        for (ConsoleProxyAllocator allocator : _consoleProxyAllocators) {
-            return allocator;
-        }
-
-        return null;
-    }
-
-    public void onLoadAnswer(ConsoleProxyLoadAnswer answer) {
-        if (answer.getDetails() == null) {
-            return;
-        }
-
-        ConsoleProxyStatus status = null;
-        try {
-            GsonBuilder gb = new GsonBuilder();
-            gb.setVersion(1.3);
-            Gson gson = gb.create();
-            status = gson.fromJson(answer.getDetails(), ConsoleProxyStatus.class);
-        } catch (Throwable e) {
-            s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + answer.getProxyVmId() + ", info : " + answer.getDetails());
-        }
-
-        if (status != null) {
-            int count = 0;
-            if (status.getConnections() != null) {
-                count = status.getConnections().length;
-            }
-
-            byte[] details = null;
-            if (answer.getDetails() != null) {
-                details = answer.getDetails().getBytes(Charset.forName("US-ASCII"));
-            }
-            _consoleProxyDao.update(answer.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Unable to get console proxy load info, id : " + answer.getProxyVmId());
-            }
-
-            _consoleProxyDao.update(answer.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
-            // TODO : something is wrong with the VM, restart it?
-        }
-    }
-
-    public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
-        if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
-            // be it either in alert or in disconnected state, the agent process
-            // may be gone in the VM,
-            // we will be reacting to stop the corresponding VM and let the scan
-            // process to
-            HostVO host = _hostDao.findById(agentId);
-            if (host.getType() == Type.ConsoleProxy) {
-                String name = host.getName();
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Console proxy agent disconnected, proxy: " + name);
-                }
-                if (name != null && name.startsWith("v-")) {
-                    String[] tokens = name.split("-");
-                    long proxyVmId = 0;
-                    try {
-                        proxyVmId = Long.parseLong(tokens[1]);
-                    } catch (NumberFormatException e) {
-                        s_logger.error("Unexpected exception " + e.getMessage(), e);
-                        return;
-                    }
-
-                    final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-                    if (proxy != null) {
-
-                        // Disable this feature for now, as it conflicts with
-                        // the case of allowing user to reboot console proxy
-                        // when rebooting happens, we will receive disconnect
-                        // here and we can't enter into stopping process,
-                        // as when the rebooted one comes up, it will kick off a
-                        // newly started one and trigger the process
-                        // continue on forever
-
-                        /*
-                         * _capacityScanScheduler.execute(new Runnable() { public void run() {
-                         * if(s_logger.isInfoEnabled())
-                         * s_logger.info("Stop console proxy " + proxy.getName() +
-                         * " VM because of that the agent running inside it has disconnected" );
-                         * stopProxy(proxy.getId()); } });
-                         */
-                    } else {
-                        if (s_logger.isInfoEnabled()) {
-                            s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: " + name);
-                        }
-                    }
-                } else {
-                    assert (false) : "Invalid console proxy name: " + name;
-                }
-            }
-        }
-    }
-
-    private boolean reserveStandbyCapacity() {
-        ConsoleProxyManagementState state = getManagementState();
-        if (state == null || state != ConsoleProxyManagementState.Auto) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean isConsoleProxyVmRequired(long dcId) {
-        DataCenterVO dc = _dcDao.findById(dcId);
-        _dcDao.loadDetails(dc);
-        String cpvmReq = dc.getDetail(ZoneConfig.EnableConsoleProxyVm.key());
-        if (cpvmReq != null) {
-            return Boolean.parseBoolean(cpvmReq);
-        }
-        return true;
-    }
-
-    private boolean allowToLaunchNew(long dcId) {
-        if (!isConsoleProxyVmRequired(dcId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Console proxy vm not required in zone " + dcId + " not launching");
-            }
-            return false;
-        }
-        List<ConsoleProxyVO> l =
-            _consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping,
-                VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdowned, VirtualMachine.State.Unknown);
-
-        String value = _configDao.getValue(Config.ConsoleProxyLaunchMax.key());
-        int launchLimit = NumbersUtil.parseInt(value, 10);
-        return l.size() < launchLimit;
-    }
-
-    private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo) {
-
-        if (proxyCountInfo.getCount() * _capacityPerProxy - vmCountInfo.getCount() <= _standbyCapacity) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private void allocCapacity(long dataCenterId) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Allocate console proxy standby capacity for data center : " + dataCenterId);
-        }
-
-        ConsoleProxyVO proxy = null;
-        String errorString = null;
-        try {
-            boolean consoleProxyVmFromStoppedPool = false;
-            proxy = assignProxyFromStoppedPool(dataCenterId);
-            if (proxy == null) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("No stopped console proxy is available, need to allocate a new console proxy");
-                }
-
-                if (_allocProxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                    try {
-                        proxy = startNew(dataCenterId);
-                    } catch (ConcurrentOperationException e) {
-                        s_logger.info("Concurrent operation exception caught " + e);
-                    } finally {
-                        _allocProxyLock.unlock();
-                    }
-                } else {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Unable to acquire synchronization lock for console proxy vm allocation, wait for next scan");
-                    }
-                }
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Found a stopped console proxy, starting it. Vm id : " + proxy.getId());
-                }
-                consoleProxyVmFromStoppedPool = true;
-            }
-
-            if (proxy != null) {
-                long proxyVmId = proxy.getId();
-                proxy = startProxy(proxyVmId, false);
-
-                if (proxy != null) {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Console proxy " + proxy.getHostName() + " is started");
-                    }
-                    SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
-                        new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_UP, dataCenterId, proxy.getId(), proxy, null));
-                } else {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Unable to start console proxy vm for standby capacity, vm id : " + proxyVmId + ", will recycle it and start a new one");
-                    }
-
-                    if (consoleProxyVmFromStoppedPool) {
-                        destroyProxy(proxyVmId);
-                    }
-                }
-            }
-        } catch (Exception e) {
-           errorString = e.getMessage();
-           throw e;
-        } finally {
-            // TODO - For now put all the alerts as creation failure. Distinguish between creation vs start failure in future.
-            // Also add failure reason since startvm masks some of them.
-            if (proxy == null || proxy.getState() != State.Running)
-                SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
-                    new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_CREATE_FAILURE, dataCenterId, 0l, null, errorString));
-        }
-    }
-
-    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
-        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
-        if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
-            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
-            if (template == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch console proxy vm");
-                }
-                return false;
-            }
-            TemplateDataStoreVO templateHostRef = _vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dataCenterId, Status.DOWNLOADED);
-
-            if (templateHostRef != null) {
-                boolean useLocalStorage = false;
-                Boolean useLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId);
-                if (useLocal != null) {
-                    useLocalStorage = useLocal.booleanValue();
-                }
-                List<Pair<Long, Integer>> l = _consoleProxyDao.getDatacenterStoragePoolHostInfo(dataCenterId, useLocalStorage);
-                if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
-                    return true;
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
-                    }
-                }
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage.");
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean isZoneHostReady(ZoneHostInfo zoneHostInfo) {
-        int expectedFlags = 0;
-        if (_useStorageVm) {
-            expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK;
-        } else {
-            expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ALL_HOST_MASK;
-        }
-
-        return (zoneHostInfo.getFlags() & expectedFlags) == expectedFlags;
-    }
-
-    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
-        Date cutTime = DateUtil.currentGMTTime();
-        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
-
-        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
-        if (l.size() > 0) {
-            for (RunningHostCountInfo countInfo : l) {
-                aggregator.aggregate(countInfo);
-            }
-        }
-
-        return aggregator.getZoneHostInfoMap();
-    }
-
-    @Override
-    public boolean start() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start console proxy manager");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Stop console proxy manager");
-        }
-
-        _loadScanner.stop();
-        _allocProxyLock.releaseRef();
-        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
-        return true;
-    }
-
-    @Override
-    public boolean stopProxy(long proxyVmId) {
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-        if (proxy == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Stopping console proxy failed: console proxy " + proxyVmId + " no longer exists");
-            }
-            return false;
-        }
-
-        try {
-            _itMgr.stop(proxy.getUuid());
-            return true;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Stopping console proxy " + proxy.getHostName() + " failed : exception ", e);
-            return false;
-        } catch (CloudRuntimeException e) {
-            s_logger.warn("Unable to stop proxy ", e);
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    public void setManagementState(final ConsoleProxyManagementState state) {
-        try {
-            final ConsoleProxyManagementState lastState = getManagementState();
-            if (lastState == null) {
-                return;
-            }
-
-            if (lastState != state) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        _configDao.update(Config.ConsoleProxyManagementLastState.key(), Config.ConsoleProxyManagementLastState.getCategory(), lastState.toString());
-                        _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), state.toString());
-                    }
-                });
-            }
-        } catch (Throwable e) {
-            s_logger.error("Failed to set managment state", e);
-        }
-    }
-
-    @Override
-    public ConsoleProxyManagementState getManagementState() {
-        String value = _configDao.getValue(Config.ConsoleProxyManagementState.key());
-        if (value != null) {
-            ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
-
-            if (state == null) {
-                s_logger.error("Invalid console proxy management state: " + value);
-            }
-            return state;
-        }
-
-        s_logger.error("Invalid console proxy management state: " + value);
-        return null;
-    }
-
-    @Override
-    @DB
-    public void resumeLastManagementState() {
-        try {
-            ConsoleProxyManagementState state = getManagementState();
-            ConsoleProxyManagementState lastState = getLastManagementState();
-            if (lastState == null) {
-                return;
-            }
-
-            if (lastState != state) {
-                _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), lastState.toString());
-            }
-        } catch (Throwable e) {
-            s_logger.error("Failed to resume last management state", e);
-        }
-    }
-
-    private ConsoleProxyManagementState getLastManagementState() {
-        String value = _configDao.getValue(Config.ConsoleProxyManagementLastState.key());
-        if (value != null) {
-            ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
-
-            if (state == null) {
-                s_logger.error("Invalid console proxy management state: " + value);
-            }
-            return state;
-        }
-
-        s_logger.error("Invalid console proxy management state: " + value);
-        return null;
-    }
-
-    @Override
-    public boolean rebootProxy(long proxyVmId) {
-        final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
-
-        if (proxy == null || proxy.getState() == State.Destroyed) {
-            return false;
-        }
-
-        if (proxy.getState() == State.Running && proxy.getHostId() != null) {
-            final RebootCommand cmd = new RebootCommand(proxy.getInstanceName(), _itMgr.getExecuteInSequence(proxy.getHypervisorType()));
-            final Answer answer = _agentMgr.easySend(proxy.getHostId(), cmd);
-
-            if (answer != null && answer.getResult()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully reboot console proxy " + proxy.getHostName());
-                }
-
-                SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
-                    new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_REBOOTED, proxy.getDataCenterId(), proxy.getId(), proxy, null));
-
-                return true;
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("failed to reboot console proxy : " + proxy.getHostName());
-                }
-
-                return false;
-            }
-        } else {
-            return startProxy(proxyVmId, false) != null;
-        }
-    }
-
-    @Override
-    public boolean destroyProxy(long vmId) {
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(vmId);
-        try {
-            //expunge the vm
-            _itMgr.expunge(proxy.getUuid());
-            proxy.setPublicIpAddress(null);
-            proxy.setPublicMacAddress(null);
-            proxy.setPublicNetmask(null);
-            proxy.setPrivateMacAddress(null);
-            proxy.setPrivateIpAddress(null);
-            _consoleProxyDao.update(proxy.getId(), proxy);
-            _consoleProxyDao.remove(vmId);
-            HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Host.Type.ConsoleProxy);
-            if (host != null) {
-                s_logger.debug("Removing host entry for proxy id=" + vmId);
-                return _hostDao.remove(host.getId());
-            }
-
-            return true;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to expunge " + proxy, e);
-            return false;
-        }
-    }
-
-    private String getAllocProxyLockName() {
-        return "consoleproxy.alloc";
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start configuring console proxy manager : " + name);
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
-        String value = configs.get("consoleproxy.sslEnabled");
-        if (value != null && value.equalsIgnoreCase("true")) {
-            _sslEnabled = true;
-        }
-
-        _consoleProxyUrlDomain = configs.get(Config.ConsoleProxyUrlDomain.key());
-        if( _sslEnabled && (_consoleProxyUrlDomain == null || _consoleProxyUrlDomain.isEmpty())) {
-            s_logger.warn("Empty console proxy domain, explicitly disabling SSL");
-            _sslEnabled = false;
-        }
-
-        value = configs.get(Config.ConsoleProxyCapacityScanInterval.key());
-        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
-
-        _capacityPerProxy = NumbersUtil.parseInt(configs.get("consoleproxy.session.max"), DEFAULT_PROXY_CAPACITY);
-        _standbyCapacity = NumbersUtil.parseInt(configs.get("consoleproxy.capacity.standby"), DEFAULT_STANDBY_CAPACITY);
-        _proxySessionTimeoutValue = NumbersUtil.parseInt(configs.get("consoleproxy.session.timeout"), DEFAULT_PROXY_SESSION_TIMEOUT);
-
-        value = configs.get("consoleproxy.port");
-        if (value != null) {
-            _consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
-        }
-
-        value = configs.get(Config.ConsoleProxyDisableRpFilter.key());
-        if (value != null && value.equalsIgnoreCase("true")) {
-            _disableRpFilter = true;
-        }
-
-        value = configs.get("secondary.storage.vm");
-        if (value != null && value.equalsIgnoreCase("true")) {
-            _useStorageVm = true;
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Console proxy max session soft limit : " + _capacityPerProxy);
-            s_logger.info("Console proxy standby capacity : " + _standbyCapacity);
-        }
-
-        _instance = configs.get("instance.name");
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-
-        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
-
-        value = agentMgrConfigs.get("port");
-        _mgmtPort = NumbersUtil.parseInt(value, 8250);
-
-        _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr));
-        _agentMgr.registerForHostEvents(_listener, true, true, false);
-
-        _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
-
-        //check if there is a default service offering configured
-        String cpvmSrvcOffIdStr = configs.get(Config.ConsoleProxyServiceOffering.key());
-        if (cpvmSrvcOffIdStr != null) {
-            _serviceOffering = _offeringDao.findByUuid(cpvmSrvcOffIdStr);
-            if (_serviceOffering == null) {
-                try {
-                    _serviceOffering = _offeringDao.findById(Long.parseLong(cpvmSrvcOffIdStr));
-                } catch (NumberFormatException ex) {
-                    s_logger.debug("The system service offering specified by global config is not id, but uuid=" + cpvmSrvcOffIdStr + " for console proxy vm");
-                }
-            }
-            if (_serviceOffering == null) {
-                s_logger.warn("Can't find system service offering specified by global config, uuid=" + cpvmSrvcOffIdStr + " for console proxy vm");
-            }
-        }
-
-        if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
-            int ramSize = NumbersUtil.parseInt(_configDao.getValue("console.ram.size"), DEFAULT_PROXY_VM_RAMSIZE);
-            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("console.cpu.mhz"), DEFAULT_PROXY_VM_CPUMHZ);
-            List<ServiceOfferingVO> offerings = _offeringDao.createSystemServiceOfferings("System Offering For Console Proxy",
-                    ServiceOffering.consoleProxyDefaultOffUniqueName, 1, ramSize, cpuFreq, 0, 0, false, null,
-                    Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.ConsoleProxy, true);
-            // this can sometimes happen, if DB is manually or programmatically manipulated
-            if (offerings == null || offerings.size() < 2) {
-                String msg = "Data integrity problem : System Offering For Console Proxy has been removed?";
-                s_logger.error(msg);
-                throw new ConfigurationException(msg);
-            }
-        }
-
-        _loadScanner = new SystemVmLoadScanner<Long>(this);
-        _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-
-        _staticPublicIp = _configDao.getValue("consoleproxy.static.publicIp");
-        if (_staticPublicIp != null) {
-            _staticPort = NumbersUtil.parseInt(_configDao.getValue("consoleproxy.static.port"), 8443);
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Console Proxy Manager is configured.");
-        }
-        return true;
-    }
-
-    protected ConsoleProxyManagerImpl() {
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-        ConsoleProxyVO vm = _consoleProxyDao.findById(profile.getId());
-        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
-        vm.setDetails(details);
-
-        StringBuilder buf = profile.getBootArgsBuilder();
-        buf.append(" template=domP type=consoleproxy");
-        buf.append(" host=").append(StringUtils.toCSVList(indirectAgentLB.getManagementServerList(dest.getHost().getId(), dest.getDataCenter().getId(), null)));
-        buf.append(" port=").append(_mgmtPort);
-        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
-        if (_sslEnabled) {
-            buf.append(" premium=true");
-        }
-        buf.append(" zone=").append(dest.getDataCenter().getId());
-        buf.append(" pod=").append(dest.getPod().getId());
-        buf.append(" guid=Proxy.").append(profile.getId());
-        buf.append(" proxy_vm=").append(profile.getId());
-        if (_disableRpFilter) {
-            buf.append(" disable_rp_filter=true");
-        }
-
-        boolean externalDhcp = false;
-        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
-        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
-            externalDhcp = true;
-        }
-
-        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
-            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
-        }
-
-        for (NicProfile nic : profile.getNics()) {
-            int deviceId = nic.getDeviceId();
-            if (nic.getIPv4Address() == null) {
-                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
-                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
-            } else {
-                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
-                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
-            }
-
-            if (nic.isDefaultNic()) {
-                buf.append(" gateway=").append(nic.getIPv4Gateway());
-            }
-
-            if (nic.getTrafficType() == TrafficType.Management) {
-                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
-                if (NetUtils.isValidIp4Cidr(mgmt_cidr)) {
-                    buf.append(" mgmtcidr=").append(mgmt_cidr);
-                }
-                buf.append(" localgw=").append(dest.getPod().getGateway());
-            }
-        }
-
-        /* External DHCP mode */
-        if (externalDhcp) {
-            buf.append(" bootproto=dhcp");
-        }
-        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
-        buf.append(" internaldns1=").append(dc.getInternalDns1());
-        if (dc.getInternalDns2() != null) {
-            buf.append(" internaldns2=").append(dc.getInternalDns2());
-        }
-        buf.append(" dns1=").append(dc.getDns1());
-        if (dc.getDns2() != null) {
-            buf.append(" dns2=").append(dc.getDns2());
-        }
-
-        String bootArgs = buf.toString();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-        finalizeCommandsOnStart(cmds, profile);
-
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(profile.getId());
-        DataCenter dc = dest.getDataCenter();
-        List<NicProfile> nics = profile.getNics();
-        for (NicProfile nic : nics) {
-            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
-                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
-                proxy.setPublicIpAddress(nic.getIPv4Address());
-                proxy.setPublicNetmask(nic.getIPv4Netmask());
-                proxy.setPublicMacAddress(nic.getMacAddress());
-            } else if (nic.getTrafficType() == TrafficType.Management) {
-                proxy.setPrivateIpAddress(nic.getIPv4Address());
-                proxy.setPrivateMacAddress(nic.getMacAddress());
-            }
-        }
-        _consoleProxyDao.update(proxy.getId(), proxy);
-        return true;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-
-        NicProfile managementNic = null;
-        NicProfile controlNic = null;
-        for (NicProfile nic : profile.getNics()) {
-            if (nic.getTrafficType() == TrafficType.Management) {
-                managementNic = nic;
-            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
-                controlNic = nic;
-            }
-        }
-
-        if (controlNic == null) {
-            if (managementNic == null) {
-                s_logger.error("Management network doesn't exist for the console proxy vm " + profile.getVirtualMachine());
-                return false;
-            }
-            controlNic = managementNic;
-        }
-
-        // verify ssh access on management nic for system vm running on HyperV
-        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
-            controlNic = managementNic;
-        }
-
-        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922);
-        cmds.addCommand("checkSsh", check);
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
-        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
-        if (answer == null || !answer.getResult()) {
-            if (answer != null) {
-                s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
-            } else {
-                s_logger.warn("Unable to ssh to the VM: null answer");
-            }
-            return false;
-        }
-
-        try {
-            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
-            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
-            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
-            if (ipaddr != null && ipaddr.getSystem()) {
-                ConsoleProxyVO consoleVm = _consoleProxyDao.findById(profile.getId());
-                // override CPVM guest IP with EIP, so that console url's will be prepared with EIP
-                consoleVm.setPublicIpAddress(ipaddr.getAddress().addr());
-                _consoleProxyDao.update(consoleVm.getId(), consoleVm);
-            }
-        } catch (Exception ex) {
-            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void finalizeExpunge(VirtualMachine vm) {
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(vm.getId());
-        proxy.setPublicIpAddress(null);
-        proxy.setPublicMacAddress(null);
-        proxy.setPublicNetmask(null);
-        proxy.setPrivateMacAddress(null);
-        proxy.setPrivateIpAddress(null);
-        _consoleProxyDao.update(proxy.getId(), proxy);
-    }
-
-    @Override
-    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
-        //release elastic IP here if assigned
-        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
-        if (ip != null && ip.getSystem()) {
-            CallContext ctx = CallContext.current();
-            try {
-                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
-                    ex);
-            }
-        }
-    }
-
-    @Override
-    public String getScanHandlerName() {
-        return "consoleproxy";
-    }
-
-    @Override
-    public void onScanStart() {
-        // to reduce possible number of DB queries for capacity scan, we run following aggregated queries in preparation
-        // stage
-        _zoneHostInfoMap = getZoneHostInfo();
-
-        _zoneProxyCountMap = new HashMap<Long, ConsoleProxyLoadInfo>();
-        List<ConsoleProxyLoadInfo> listProxyCounts = _consoleProxyDao.getDatacenterProxyLoadMatrix();
-        for (ConsoleProxyLoadInfo info : listProxyCounts) {
-            _zoneProxyCountMap.put(info.getId(), info);
-        }
-
-        _zoneVmCountMap = new HashMap<Long, ConsoleProxyLoadInfo>();
-        List<ConsoleProxyLoadInfo> listVmCounts = _consoleProxyDao.getDatacenterSessionLoadMatrix();
-        for (ConsoleProxyLoadInfo info : listVmCounts) {
-            _zoneVmCountMap.put(info.getId(), info);
-        }
-    }
-
-    private void scanManagementState() {
-        ConsoleProxyManagementState state = getManagementState();
-        if (state != null) {
-            switch (state) {
-                case Auto:
-                case Manual:
-                case Suspending:
-                    break;
-
-                case ResetSuspending:
-                    handleResetSuspending();
-                    break;
-
-                default:
-                    assert (false);
-            }
-        }
-    }
-
-    private void handleResetSuspending() {
-        List<ConsoleProxyVO> runningProxies = _consoleProxyDao.getProxyListInStates(State.Running);
-        for (ConsoleProxyVO proxy : runningProxies) {
-            s_logger.info("Stop console proxy " + proxy.getId() + " because of we are currently in ResetSuspending management mode");
-            stopProxy(proxy.getId());
-        }
-
-        // check if it is time to resume
-        List<ConsoleProxyVO> proxiesInTransition = _consoleProxyDao.getProxyListInStates(State.Running, State.Starting, State.Stopping);
-        if (proxiesInTransition.size() == 0) {
-            s_logger.info("All previous console proxy VMs in transition mode ceased the mode, we will now resume to last management state");
-            resumeLastManagementState();
-        }
-    }
-
-    @Override
-    public boolean canScan() {
-        // take the chance to do management-state management
-        scanManagementState();
-
-        if (!reserveStandbyCapacity()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Reserving standby capacity is disabled, skip capacity scan");
-            }
-            return false;
-        }
-
-        List<StoragePoolVO> upPools = _storagePoolDao.listByStatus(StoragePoolStatus.Up);
-        if (upPools == null || upPools.size() == 0) {
-            s_logger.debug("Skip capacity scan as there is no Primary Storage in 'Up' state");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public Long[] getScannablePools() {
-        List<DataCenterVO> zones = _dcDao.listEnabledZones();
-
-        Long[] dcIdList = new Long[zones.size()];
-        int i = 0;
-        for (DataCenterVO dc : zones) {
-            dcIdList[i++] = dc.getId();
-        }
-
-        return dcIdList;
-    }
-
-    @Override
-    public boolean isPoolReadyForScan(Long pool) {
-        // pool is at zone basis
-        long dataCenterId = pool.longValue();
-
-        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Zone " + dataCenterId + " is not ready to launch console proxy yet");
-            }
-            return false;
-        }
-
-        List<ConsoleProxyVO> l = _consoleProxyDao.getProxyListInStates(VirtualMachine.State.Starting, VirtualMachine.State.Stopping);
-        if (l.size() > 0) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Zone " + dataCenterId + " has " + l.size() + " console proxy VM(s) in transition state");
-            }
-
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Zone " + dataCenterId + " is ready to launch console proxy");
-        }
-        return true;
-    }
-
-    @Override
-    public Pair<AfterScanAction, Object> scanPool(Long pool) {
-        long dataCenterId = pool.longValue();
-
-        ConsoleProxyLoadInfo proxyInfo = _zoneProxyCountMap.get(dataCenterId);
-        if (proxyInfo == null) {
-            return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-        }
-
-        ConsoleProxyLoadInfo vmInfo = _zoneVmCountMap.get(dataCenterId);
-        if (vmInfo == null) {
-            vmInfo = new ConsoleProxyLoadInfo();
-        }
-
-        if (!checkCapacity(proxyInfo, vmInfo)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Expand console proxy standby capacity for zone " + proxyInfo.getName());
-            }
-
-            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, null);
-        }
-
-        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-    }
-
-    @Override
-    public void expandPool(Long pool, Object actionArgs) {
-        long dataCenterId = pool.longValue();
-        allocCapacity(dataCenterId);
-    }
-
-    @Override
-    public void shrinkPool(Long pool, Object actionArgs) {
-    }
-
-    @Override
-    public void onScanEnd() {
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        if (!(cmd[0] instanceof StartupProxyCommand)) {
-            return null;
-        }
-
-        host.setType(com.cloud.host.Host.Type.ConsoleProxy);
-        return host;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        return null;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        return null;
-    }
-
-    protected HostVO findConsoleProxyHostByName(String name) {
-        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.ConsoleProxy);
-        sc.and(sc.entity().getName(), Op.EQ, name);
-        return sc.find();
-    }
-
-    @Override
-    public void prepareStop(VirtualMachineProfile profile) {
-    }
-
-    public List<ConsoleProxyAllocator> getConsoleProxyAllocators() {
-        return _consoleProxyAllocators;
-    }
-
-    @Inject
-    public void setConsoleProxyAllocators(List<ConsoleProxyAllocator> consoleProxyAllocators) {
-        _consoleProxyAllocators = consoleProxyAllocators;
-    }
-
-}
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
deleted file mode 100644
index 64fabb9..0000000
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ /dev/null
@@ -1,1618 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deploy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TreeSet;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.fsm.StateMachine2;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-import org.apache.cloudstack.affinity.AffinityGroupProcessor;
-import org.apache.cloudstack.affinity.AffinityGroupService;
-import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
-import org.apache.cloudstack.affinity.AffinityGroupVO;
-import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
-import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO;
-import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
-import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.manager.allocator.HostAllocator;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManagerImpl;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
-import com.cloud.deploy.dao.PlannerHostReservationDao;
-import com.cloud.exception.AffinityConflictException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.gpu.GPU;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.org.Cluster;
-import com.cloud.org.Grouping;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.service.ServiceOfferingDetailsVO;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Event;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener,
-StateListener<State, VirtualMachine.Event, VirtualMachine> {
-
-    private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    protected UserVmDao _vmDao;
-    @Inject
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    protected AffinityGroupDao _affinityGroupDao;
-    @Inject
-    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
-    @Inject
-    protected AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
-    @Inject
-    AffinityGroupService _affinityGroupService;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    PlannerHostReservationDao _plannerHostReserveDao;
-    private int _vmCapacityReleaseInterval;
-    @Inject
-    MessageBus _messageBus;
-    private Timer _timer = null;
-    private long _hostReservationReleasePeriod = 60L * 60L * 1000L; // one hour by default
-    @Inject
-    protected VMReservationDao _reservationDao;
-
-    private static final long INITIAL_RESERVATION_RELEASE_CHECKER_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
-    protected long _nodeId = -1;
-
-    protected List<StoragePoolAllocator> _storagePoolAllocators;
-
-    public List<StoragePoolAllocator> getStoragePoolAllocators() {
-        return _storagePoolAllocators;
-    }
-
-    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
-        _storagePoolAllocators = storagePoolAllocators;
-    }
-
-    protected List<HostAllocator> _hostAllocators;
-
-    public List<HostAllocator> getHostAllocators() {
-        return _hostAllocators;
-    }
-
-    public void setHostAllocators(List<HostAllocator> hostAllocators) {
-        _hostAllocators = hostAllocators;
-    }
-
-    @Inject
-    protected HostDao _hostDao;
-    @Inject
-    protected HostPodDao _podDao;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    protected DedicatedResourceDao _dedicatedDao;
-    @Inject
-    protected GuestOSDao _guestOSDao = null;
-    @Inject
-    protected GuestOSCategoryDao _guestOSCategoryDao = null;
-    @Inject
-    protected DiskOfferingDao _diskOfferingDao;
-    @Inject
-    protected StoragePoolHostDao _poolHostDao;
-
-    @Inject
-    protected VolumeDao _volsDao;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    protected ConfigurationDao _configDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected StorageManager _storageMgr;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    protected ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    protected ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-
-    protected List<DeploymentPlanner> _planners;
-
-    public List<DeploymentPlanner> getPlanners() {
-        return _planners;
-    }
-
-    public void setPlanners(List<DeploymentPlanner> planners) {
-        _planners = planners;
-    }
-
-    protected List<AffinityGroupProcessor> _affinityProcessors;
-
-    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
-        return _affinityProcessors;
-    }
-
-    public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
-        _affinityProcessors = affinityProcessors;
-    }
-
-    @Override
-    public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner)
-            throws InsufficientServerCapacityException, AffinityConflictException {
-
-        ServiceOffering offering = vmProfile.getServiceOffering();
-        int cpu_requested = offering.getCpu() * offering.getSpeed();
-        long ram_requested = offering.getRamSize() * 1024L * 1024L;
-        VirtualMachine vm = vmProfile.getVirtualMachine();
-        DataCenter dc = _dcDao.findById(vm.getDataCenterId());
-
-
-        if (vm.getType() == VirtualMachine.Type.User || vm.getType() == VirtualMachine.Type.DomainRouter) {
-            checkForNonDedicatedResources(vmProfile, dc, avoids);
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("DeploymentPlanner allocation algorithm: " + planner);
-
-            s_logger.debug("Trying to allocate a host and storage pools from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" +
-                    plan.getClusterId() + ", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested);
-
-            s_logger.debug("Is ROOT volume READY (pool already allocated)?: " + (plan.getPoolId() != null ? "Yes" : "No"));
-        }
-
-        String haVmTag = (String)vmProfile.getParameter(VirtualMachineProfile.Param.HaTag);
-
-        if (plan.getHostId() != null && haVmTag == null) {
-            Long hostIdSpecified = plan.getHostId();
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: " + hostIdSpecified);
-            }
-            HostVO host = _hostDao.findById(hostIdSpecified);
-            if (host == null) {
-                s_logger.debug("The specified host cannot be found");
-            } else if (avoids.shouldAvoid(host)) {
-                s_logger.debug("The specified host is in avoid set");
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(
-                            "Looking for suitable pools for this host under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId());
-                }
-
-                Pod pod = _podDao.findById(host.getPodId());
-                // check if the cluster or the pod is disabled
-                if (pod.getAllocationState() != Grouping.AllocationState.Enabled) {
-                    s_logger.warn("The Pod containing this host is in disabled state, PodId= " + pod.getId());
-                    return null;
-                }
-
-                Cluster cluster = _clusterDao.findById(host.getClusterId());
-                if (cluster.getAllocationState() != Grouping.AllocationState.Enabled) {
-                    s_logger.warn("The Cluster containing this host is in disabled state, PodId= " + cluster.getId());
-                    return null;
-                }
-
-                if (vm.getHypervisorType() == HypervisorType.BareMetal) {
-                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
-                    s_logger.debug("Returning Deployment Destination: " + dest);
-                    return dest;
-                }
-
-                // search for storage under the zone, pod, cluster of the host.
-                DataCenterDeployment lastPlan =
-                        new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), hostIdSpecified, plan.getPoolId(), null,
-                                plan.getReservationContext());
-
-                Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
-                Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
-                List<Volume> readyAndReusedVolumes = result.second();
-
-                // choose the potential pool for this VM for this host
-                if (!suitableVolumeStoragePools.isEmpty()) {
-                    List<Host> suitableHosts = new ArrayList<Host>();
-                    suitableHosts.add(host);
-                    Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
-                            suitableHosts, suitableVolumeStoragePools, avoids,
-                            getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
-                    if (potentialResources != null) {
-                        pod = _podDao.findById(host.getPodId());
-                        cluster = _clusterDao.findById(host.getClusterId());
-                        Map<Volume, StoragePool> storageVolMap = potentialResources.second();
-                        // remove the reused vol<->pool from destination, since
-                        // we don't have to prepare this volume.
-                        for (Volume vol : readyAndReusedVolumes) {
-                            storageVolMap.remove(vol);
-                        }
-                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
-                        s_logger.debug("Returning Deployment Destination: " + dest);
-                        return dest;
-                    }
-                }
-            }
-            s_logger.debug("Cannot deploy to specified host, returning.");
-            return null;
-        }
-
-        // call affinitygroup chain
-        long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
-
-        if (vmGroupCount > 0) {
-            for (AffinityGroupProcessor processor : _affinityProcessors) {
-                processor.process(vmProfile, plan, avoids);
-            }
-        }
-
-        if (vm.getType() == VirtualMachine.Type.User) {
-            checkForNonDedicatedResources(vmProfile, dc, avoids);
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
-        }
-
-        // call planners
-        // DataCenter dc = _dcDao.findById(vm.getDataCenterId());
-        // check if datacenter is in avoid set
-        if (avoids.shouldAvoid(dc)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("DataCenter id = '" + dc.getId() + "' provided is in avoid set, DeploymentPlanner cannot allocate the VM, returning.");
-            }
-            return null;
-        }
-
-        if (planner == null) {
-            String plannerName = offering.getDeploymentPlanner();
-            if (plannerName == null) {
-                if (vm.getHypervisorType() == HypervisorType.BareMetal) {
-                    plannerName = "BareMetalPlanner";
-                } else {
-                    plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
-                }
-            }
-            planner = getDeploymentPlannerByName(plannerName);
-        }
-
-        if (vm.getLastHostId() != null && haVmTag == null) {
-            s_logger.debug("This VM has last host_id specified, trying to choose the same host: " + vm.getLastHostId());
-
-            HostVO host = _hostDao.findById(vm.getLastHostId());
-            ServiceOfferingDetailsVO offeringDetails = null;
-            if (host == null) {
-                s_logger.debug("The last host of this VM cannot be found");
-            } else if (avoids.shouldAvoid(host)) {
-                s_logger.debug("The last host of this VM is in avoid set");
-            } else if (plan.getClusterId() != null && host.getClusterId() != null
-                    && !plan.getClusterId().equals(host.getClusterId())) {
-                s_logger.debug("The last host of this VM cannot be picked as the plan specifies different clusterId: "
-                        + plan.getClusterId());
-            } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
-                s_logger.debug("The last Host, hostId: " + host.getId() +
-                        " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
-            } else if ((offeringDetails  = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
-                ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
-                if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){
-                    s_logger.debug("The last host of this VM does not have required GPU devices available");
-                }
-            } else {
-                if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
-                    boolean hostTagsMatch = true;
-                    if(offering.getHostTag() != null){
-                        _hostDao.loadHostTags(host);
-                        if (!(host.getHostTags() != null && host.getHostTags().contains(offering.getHostTag()))) {
-                            hostTagsMatch = false;
-                        }
-                    }
-                    if (hostTagsMatch) {
-                        long cluster_id = host.getClusterId();
-                        ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id,
-                                "cpuOvercommitRatio");
-                        ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id,
-                                "memoryOvercommitRatio");
-                        Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue());
-                        Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue());
-
-                        boolean hostHasCpuCapability, hostHasCapacity = false;
-                        hostHasCpuCapability = _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed());
-
-                        if (hostHasCpuCapability) {
-                            // first check from reserved capacity
-                            hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOvercommitRatio, memoryOvercommitRatio, true);
-
-                            // if not reserved, check the free capacity
-                            if (!hostHasCapacity)
-                                hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, false, cpuOvercommitRatio, memoryOvercommitRatio, true);
-                        }
-
-                        if (hostHasCapacity
-                                && hostHasCpuCapability) {
-                            s_logger.debug("The last host of this VM is UP and has enough capacity");
-                            s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId()
-                                    + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId());
-
-                            Pod pod = _podDao.findById(host.getPodId());
-                            Cluster cluster = _clusterDao.findById(host.getClusterId());
-                            if (vm.getHypervisorType() == HypervisorType.BareMetal) {
-                                DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
-                                s_logger.debug("Returning Deployment Destination: " + dest);
-                                return dest;
-                            }
-
-                            // search for storage under the zone, pod, cluster
-                            // of
-                            // the last host.
-                            DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(),
-                                    host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null);
-                            Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(
-                                    vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
-                            Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
-                            List<Volume> readyAndReusedVolumes = result.second();
-
-                            // choose the potential pool for this VM for this
-                            // host
-                            if (!suitableVolumeStoragePools.isEmpty()) {
-                                List<Host> suitableHosts = new ArrayList<Host>();
-                                suitableHosts.add(host);
-                                Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
-                                        suitableHosts, suitableVolumeStoragePools, avoids,
-                                        getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
-                                if (potentialResources != null) {
-                                    Map<Volume, StoragePool> storageVolMap = potentialResources.second();
-                                    // remove the reused vol<->pool from
-                                    // destination, since we don't have to
-                                    // prepare
-                                    // this volume.
-                                    for (Volume vol : readyAndReusedVolumes) {
-                                        storageVolMap.remove(vol);
-                                    }
-                                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host,
-                                            storageVolMap);
-                                    s_logger.debug("Returning Deployment Destination: " + dest);
-                                    return dest;
-                                }
-                            }
-                        } else {
-                            s_logger.debug("The last host of this VM does not have enough capacity");
-                        }
-                    } else {
-                        s_logger.debug("Service Offering host tag does not match the last host of this VM");
-                    }
-                } else {
-                    s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " +
-                            host.getResourceState());
-                }
-            }
-            s_logger.debug("Cannot choose the last host to deploy this VM ");
-        }
-
-        DeployDestination dest = null;
-        List<Long> clusterList = null;
-
-        if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
-            while (true) {
-                if (planner instanceof DeploymentClusterPlanner) {
-
-                    ExcludeList plannerAvoidInput =
-                            new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
-                                    avoids.getPoolsToAvoid());
-
-                    clusterList = ((DeploymentClusterPlanner)planner).orderClusters(vmProfile, plan, avoids);
-
-                    if (clusterList != null && !clusterList.isEmpty()) {
-                        // planner refactoring. call allocators to list hosts
-                        ExcludeList plannerAvoidOutput =
-                                new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
-                                        avoids.getPoolsToAvoid());
-
-                        resetAvoidSet(plannerAvoidOutput, plannerAvoidInput);
-
-                        dest =
-                                checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc, getPlannerUsage(planner, vmProfile, plan, avoids), plannerAvoidOutput);
-                        if (dest != null) {
-                            return dest;
-                        }
-                        // reset the avoid input to the planners
-                        resetAvoidSet(avoids, plannerAvoidOutput);
-
-                    } else {
-                        return null;
-                    }
-                } else {
-                    dest = planner.plan(vmProfile, plan, avoids);
-                    if (dest != null) {
-                        long hostId = dest.getHost().getId();
-                        avoids.addHost(dest.getHost().getId());
-
-                        if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
-                            // found destination
-                            return dest;
-                        } else {
-                            // find another host - seems some concurrent
-                            // deployment picked it up for dedicated access
-                            continue;
-                        }
-                    } else {
-                        return null;
-                    }
-                }
-            }
-        }
-
-        return dest;
-    }
-
-    @Override
-    public DeploymentPlanner getDeploymentPlannerByName(String plannerName) {
-        if (plannerName != null) {
-            for (DeploymentPlanner plannerInList : _planners) {
-                if (plannerName.equalsIgnoreCase(plannerInList.getName())) {
-                    return plannerInList;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) {
-        boolean isExplicit = false;
-        VirtualMachine vm = vmProfile.getVirtualMachine();
-
-        // check if zone is dedicated. if yes check if vm owner has access to it.
-        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
-        if (dedicatedZone != null && !_accountMgr.isRootAdmin(vmProfile.getOwner().getId())) {
-            long accountDomainId = vmProfile.getOwner().getDomainId();
-            long accountId = vmProfile.getOwner().getAccountId();
-
-            // If a zone is dedicated to an account then all hosts in this zone
-            // will be explicitly dedicated to
-            // that account. So there won't be any shared hosts in the zone, the
-            // only way to deploy vms from that
-            // account will be to use explicit dedication affinity group.
-            if (dedicatedZone.getAccountId() != null) {
-                if (dedicatedZone.getAccountId().equals(accountId)) {
-                    return;
-                } else {
-                    throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user account " + vmProfile.getOwner());
-                }
-            }
-
-            // if zone is dedicated to a domain. Check owner's access to the
-            // domain level dedication group
-            if (!_affinityGroupService.isAffinityGroupAvailableInDomain(dedicatedZone.getAffinityGroupId(), accountDomainId)) {
-                throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user domain " + vmProfile.getOwner());
-            }
-
-        }
-
-        // check affinity group of type Explicit dedication exists. If No put
-        // dedicated pod/cluster/host in avoid list
-        List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication");
-
-        if (vmGroupMappings != null && !vmGroupMappings.isEmpty()) {
-            isExplicit = true;
-        }
-
-        List<Long> allPodsInDc = _podDao.listAllPods(dc.getId());
-        List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
-        allPodsInDc.retainAll(allDedicatedPods);
-
-        List<Long> allClustersInDc = _clusterDao.listAllClusters(dc.getId());
-        List<Long> allDedicatedClusters = _dedicatedDao.listAllClusters();
-        allClustersInDc.retainAll(allDedicatedClusters);
-
-        List<Long> allHostsInDc = _hostDao.listAllHosts(dc.getId());
-        List<Long> allDedicatedHosts = _dedicatedDao.listAllHosts();
-        allHostsInDc.retainAll(allDedicatedHosts);
-
-        //Only when the type is instance VM and not explicitly dedicated.
-        if (vm.getType() == VirtualMachine.Type.User && !isExplicit) {
-            //add explicitly dedicated resources in avoidList
-
-            avoids.addPodList(allPodsInDc);
-            avoids.addClusterList(allClustersInDc);
-            avoids.addHostList(allHostsInDc);
-        }
-
-        //Handle the Virtual Router Case
-        //No need to check the isExplicit. As both the cases are handled.
-        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-            long vmAccountId = vm.getAccountId();
-            long vmDomainId = vm.getDomainId();
-
-            //Lists all explicitly dedicated resources from vm account ID or domain ID.
-            List<Long> allPodsFromDedicatedID = new ArrayList<Long>();
-            List<Long> allClustersFromDedicatedID = new ArrayList<Long>();
-            List<Long> allHostsFromDedicatedID = new ArrayList<Long>();
-
-            //Whether the dedicated resources belong to Domain or not. If not, it may belongs to Account or no dedication.
-            List<AffinityGroupDomainMapVO> domainGroupMappings = _affinityGroupDomainMapDao.listByDomain(vmDomainId);
-
-            //For temporary storage and indexing.
-            List<DedicatedResourceVO> tempStorage;
-
-            if (domainGroupMappings == null || domainGroupMappings.isEmpty()) {
-                //The dedicated resource belongs to VM Account ID.
-
-                tempStorage = _dedicatedDao.searchDedicatedPods(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allPodsFromDedicatedID.add(vo.getPodId());
-                }
-
-                tempStorage.clear();
-                tempStorage = _dedicatedDao.searchDedicatedClusters(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allClustersFromDedicatedID.add(vo.getClusterId());
-                }
-
-                tempStorage.clear();
-                tempStorage = _dedicatedDao.searchDedicatedHosts(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allHostsFromDedicatedID.add(vo.getHostId());
-                }
-
-                //Remove the dedicated ones from main list
-                allPodsInDc.removeAll(allPodsFromDedicatedID);
-                allClustersInDc.removeAll(allClustersFromDedicatedID);
-                allHostsInDc.removeAll(allHostsFromDedicatedID);
-            }
-            else {
-                //The dedicated resource belongs to VM Domain ID or No dedication.
-
-                tempStorage = _dedicatedDao.searchDedicatedPods(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allPodsFromDedicatedID.add(vo.getPodId());
-                }
-
-                tempStorage.clear();
-                tempStorage = _dedicatedDao.searchDedicatedClusters(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allClustersFromDedicatedID.add(vo.getClusterId());
-                }
-
-                tempStorage.clear();
-                tempStorage = _dedicatedDao.searchDedicatedHosts(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
-
-                for(DedicatedResourceVO vo : tempStorage) {
-                    allHostsFromDedicatedID.add(vo.getHostId());
-                }
-
-                //Remove the dedicated ones from main list
-                allPodsInDc.removeAll(allPodsFromDedicatedID);
-                allClustersInDc.removeAll(allClustersFromDedicatedID);
-                allHostsInDc.removeAll(allHostsFromDedicatedID);
-            }
-
-            //Add in avoid list or no addition if no dedication
-            avoids.addPodList(allPodsInDc);
-            avoids.addClusterList(allClustersInDc);
-            avoids.addHostList(allHostsInDc);
-        }
-    }
-
-    private void resetAvoidSet(ExcludeList avoidSet, ExcludeList removeSet) {
-        if (avoidSet.getDataCentersToAvoid() != null && removeSet.getDataCentersToAvoid() != null) {
-            avoidSet.getDataCentersToAvoid().removeAll(removeSet.getDataCentersToAvoid());
-        }
-        if (avoidSet.getPodsToAvoid() != null && removeSet.getPodsToAvoid() != null) {
-            avoidSet.getPodsToAvoid().removeAll(removeSet.getPodsToAvoid());
-        }
-        if (avoidSet.getClustersToAvoid() != null && removeSet.getClustersToAvoid() != null) {
-            avoidSet.getClustersToAvoid().removeAll(removeSet.getClustersToAvoid());
-        }
-        if (avoidSet.getHostsToAvoid() != null && removeSet.getHostsToAvoid() != null) {
-            avoidSet.getHostsToAvoid().removeAll(removeSet.getHostsToAvoid());
-        }
-        if (avoidSet.getPoolsToAvoid() != null && removeSet.getPoolsToAvoid() != null) {
-            avoidSet.getPoolsToAvoid().removeAll(removeSet.getPoolsToAvoid());
-        }
-    }
-
-    private PlannerResourceUsage getPlannerUsage(DeploymentPlanner planner, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids)
-            throws InsufficientServerCapacityException {
-        if (planner != null && planner instanceof DeploymentClusterPlanner) {
-            return ((DeploymentClusterPlanner)planner).getResourceUsage(vmProfile, plan, avoids);
-        } else {
-            return DeploymentPlanner.PlannerResourceUsage.Shared;
-        }
-
-    }
-
-    @DB
-    private boolean checkIfHostFitsPlannerUsage(final long hostId, final PlannerResourceUsage resourceUsageRequired) {
-        // TODO Auto-generated method stub
-        // check if this host has been picked up by some other planner
-        // exclusively
-        // if planner can work with shared host, check if this host has
-        // been marked as 'shared'
-        // else if planner needs dedicated host,
-
-        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
-        if (reservationEntry != null) {
-            final long id = reservationEntry.getId();
-            PlannerResourceUsage hostResourceType = reservationEntry.getResourceUsage();
-
-            if (hostResourceType != null) {
-                if (hostResourceType == resourceUsageRequired) {
-                    return true;
-                } else {
-                    s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " +
-                            hostResourceType);
-                    return false;
-                }
-            } else {
-                final PlannerResourceUsage hostResourceTypeFinal = hostResourceType;
-                // reserve the host for required resourceType
-                // let us lock the reservation entry before updating.
-                return Transaction.execute(new TransactionCallback<Boolean>() {
-                    @Override
-                    public Boolean doInTransaction(TransactionStatus status) {
-                        final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
-                        if (lockedEntry == null) {
-                            s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
-                            return false;
-                        }
-                        // check before updating
-                        if (lockedEntry.getResourceUsage() == null) {
-                            lockedEntry.setResourceUsage(resourceUsageRequired);
-                            _plannerHostReserveDao.persist(lockedEntry);
-                            return true;
-                        } else {
-                            // someone updated it earlier. check if we can still use it
-                            if (lockedEntry.getResourceUsage() == resourceUsageRequired) {
-                                return true;
-                            } else {
-                                s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " +
-                                        hostResourceTypeFinal);
-                                return false;
-                            }
-                        }
-                    }
-                });
-
-            }
-
-        }
-
-        return false;
-    }
-
-    @DB
-    public boolean checkHostReservationRelease(final Long hostId) {
-
-        if (hostId != null) {
-            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
-            if (reservationEntry != null && reservationEntry.getResourceUsage() != null) {
-
-                // check if any VMs are starting or running on this host
-                List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
-                if (vms.size() > 0) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host " + hostId);
-                    }
-                    return false;
-                }
-
-                List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
-                if (vmsByLastHostId.size() > 0) {
-                    // check if any VMs are within skip.counting.hours, if yes
-                    // we
-                    // cannot release the host
-                    for (VMInstanceVO stoppedVM : vmsByLastHostId) {
-                        long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
-                        if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Cannot release reservation, Found VM: " + stoppedVM + " Stopped but reserved on host " + hostId);
-                            }
-                            return false;
-                        }
-                    }
-                }
-
-                // check if any VMs are stopping on or migrating to this host
-                List<VMInstanceVO> vmsStoppingMigratingByHostId = _vmInstanceDao.findByHostInStates(hostId, State.Stopping, State.Migrating, State.Starting);
-                if (vmsStoppingMigratingByHostId.size() > 0) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Cannot release reservation, Found " + vmsStoppingMigratingByHostId.size() + " VMs stopping/migrating/starting on host " + hostId);
-                    }
-                    return false;
-                }
-
-                // check if any VMs are in starting state with no hostId set yet
-                // -
-                // just ignore host release to avoid race condition
-                List<VMInstanceVO> vmsStartingNoHost = _vmInstanceDao.listStartingWithNoHostId();
-
-                if (vmsStartingNoHost.size() > 0) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs starting as of now and no hostId yet stored");
-                    }
-                    return false;
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId);
-                }
-
-                final long id = reservationEntry.getId();
-
-                return Transaction.execute(new TransactionCallback<Boolean>() {
-                    @Override
-                    public Boolean doInTransaction(TransactionStatus status) {
-                        final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
-                        if (lockedEntry == null) {
-                            s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
-                            return false;
-                        }
-                        // check before updating
-                        if (lockedEntry.getResourceUsage() != null) {
-                            lockedEntry.setResourceUsage(null);
-                            _plannerHostReserveDao.persist(lockedEntry);
-                            return true;
-                        }
-
-                        return false;
-                    }
-                });
-            }
-
-        }
-        return false;
-    }
-
-    class HostReservationReleaseChecker extends ManagedContextTimerTask {
-        @Override
-        protected void runInContext() {
-            try {
-                s_logger.debug("Checking if any host reservation can be released ... ");
-                checkHostReservations();
-                s_logger.debug("Done running HostReservationReleaseChecker ... ");
-            } catch (Throwable t) {
-                s_logger.error("Exception in HostReservationReleaseChecker", t);
-            }
-        }
-    }
-
-    private void checkHostReservations() {
-        List<PlannerHostReservationVO> reservedHosts = _plannerHostReserveDao.listAllReservedHosts();
-
-        for (PlannerHostReservationVO hostReservation : reservedHosts) {
-            HostVO host = _hostDao.findById(hostReservation.getHostId());
-            if (host != null && host.getManagementServerId() != null && host.getManagementServerId() == _nodeId) {
-                checkHostReservationRelease(hostReservation.getHostId());
-            }
-        }
-
-    }
-
-    @Override
-    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean processCommands(long agentId, long seq, Command[] commands) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
-        if (!(cmd instanceof StartupRoutingCommand)) {
-            return;
-        }
-
-        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(host.getId());
-        if (reservationEntry == null) {
-            // record the host in this table
-            PlannerHostReservationVO newHost = new PlannerHostReservationVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId());
-            _plannerHostReserveDao.persist(newHost);
-        }
-
-    }
-
-    @Override
-    public boolean processDisconnect(long agentId, Status state) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void processHostAboutToBeRemoved(long hostId) {
-    }
-
-    @Override
-    public void processHostRemoved(long hostId, long clusterId) {
-    }
-
-    @Override
-    public boolean isRecurring() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public int getTimeout() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean processTimeout(long agentId, long seq) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _agentMgr.registerForHostEvents(this, true, false, true);
-        VirtualMachine.State.getStateMachine().registerListener(this);
-        _messageBus.subscribe("VM_ReservedCapacity_Free", new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                VMInstanceVO vm = ((VMInstanceVO)obj);
-                s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId() +
-                        ", checking if host reservation can be released for host:" + vm.getLastHostId());
-                Long hostId = vm.getLastHostId();
-                checkHostReservationRelease(hostId);
-            }
-        });
-
-        _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
-
-        String hostReservationReleasePeriod = _configDao.getValue(Config.HostReservationReleasePeriod.key());
-        if (hostReservationReleasePeriod != null) {
-            _hostReservationReleasePeriod = Long.parseLong(hostReservationReleasePeriod);
-            if (_hostReservationReleasePeriod <= 0)
-                _hostReservationReleasePeriod = Long.parseLong(Config.HostReservationReleasePeriod.getDefaultValue());
-        }
-
-        _timer = new Timer("HostReservationReleaseChecker");
-
-        _nodeId = ManagementServerNode.getManagementServerId();
-
-        return super.configure(name, params);
-    }
-
-    @Override
-    public boolean start() {
-        _timer.schedule(new HostReservationReleaseChecker(), INITIAL_RESERVATION_RELEASE_CHECKER_DELAY, _hostReservationReleasePeriod);
-        cleanupVMReservations();
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _timer.cancel();
-        return true;
-    }
-
-    @Override
-    public void cleanupVMReservations() {
-        List<VMReservationVO> reservations = _reservationDao.listAll();
-
-        for (VMReservationVO reserv : reservations) {
-            VMInstanceVO vm = _vmInstanceDao.findById(reserv.getVmId());
-            if (vm != null) {
-                if (vm.getState() == State.Starting || (vm.getState() == State.Stopped && vm.getLastHostId() == null)) {
-                    continue;
-                } else {
-                    // delete reservation
-                    _reservationDao.remove(reserv.getId());
-                }
-            } else {
-                // delete reservation
-                _reservationDao.remove(reserv.getId());
-            }
-        }
-    }
-
-    // /refactoring planner methods
-    private DeployDestination checkClustersforDestination(List<Long> clusterList, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, DataCenter dc,
-            DeploymentPlanner.PlannerResourceUsage resourceUsageRequired, ExcludeList plannerAvoidOutput) {
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("ClusterId List to consider: " + clusterList);
-        }
-
-        for (Long clusterId : clusterList) {
-            ClusterVO clusterVO = _clusterDao.findById(clusterId);
-
-            if (clusterVO.getAllocationState() == Grouping.AllocationState.Disabled) {
-                s_logger.debug("Cannot deploy in disabled cluster " + clusterId + ", skipping this cluster");
-                avoid.addCluster(clusterVO.getId());
-            }
-
-            if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
-                s_logger.debug("Cluster: " + clusterId + " has HyperVisorType that does not match the VM, skipping this cluster");
-                avoid.addCluster(clusterVO.getId());
-                continue;
-            }
-
-            s_logger.debug("Checking resources in Cluster: " + clusterId + " under Pod: " + clusterVO.getPodId());
-            // search for resources(hosts and storage) under this zone, pod,
-            // cluster.
-            DataCenterDeployment potentialPlan =
-                    new DataCenterDeployment(plan.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null, plan.getPoolId(), null, plan.getReservationContext());
-
-            Pod pod = _podDao.findById(clusterVO.getPodId());
-            if (pod.getAllocationState() == Grouping.AllocationState.Enabled ) {
-                // find suitable hosts under this cluster, need as many hosts as we
-                // get.
-                List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
-                // if found suitable hosts in this cluster, find suitable storage
-                // pools for each volume of the VM
-                if (suitableHosts != null && !suitableHosts.isEmpty()) {
-                    if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
-                        DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
-                        return dest;
-                    }
-
-                    Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, potentialPlan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
-                    Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
-                    List<Volume> readyAndReusedVolumes = result.second();
-
-                    // choose the potential host and pool for the VM
-                    if (!suitableVolumeStoragePools.isEmpty()) {
-                        Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(suitableHosts, suitableVolumeStoragePools, avoid,
-                                resourceUsageRequired, readyAndReusedVolumes, plan.getPreferredHosts());
-
-                        if (potentialResources != null) {
-                            Host host = _hostDao.findById(potentialResources.first().getId());
-                            Map<Volume, StoragePool> storageVolMap = potentialResources.second();
-                            // remove the reused vol<->pool from destination, since
-                            // we don't have to prepare this volume.
-                            for (Volume vol : readyAndReusedVolumes) {
-                                storageVolMap.remove(vol);
-                            }
-                            DeployDestination dest = new DeployDestination(dc, pod, clusterVO, host, storageVolMap);
-                            s_logger.debug("Returning Deployment Destination: " + dest);
-                            return dest;
-                        }
-                    } else {
-                        s_logger.debug("No suitable storagePools found under this Cluster: " + clusterId);
-                    }
-                } else {
-                    s_logger.debug("No suitable hosts found under this Cluster: " + clusterId);
-                }
-            }
-            else {
-                s_logger.debug("The cluster is in a disabled pod : " + pod.getId());
-            }
-
-            if (canAvoidCluster(clusterVO, avoid, plannerAvoidOutput, vmProfile)) {
-                avoid.addCluster(clusterVO.getId());
-            }
-        }
-        s_logger.debug("Could not find suitable Deployment Destination for this VM under any clusters, returning. ");
-        return null;
-    }
-
-    private boolean canAvoidCluster(Cluster clusterVO, ExcludeList avoids, ExcludeList plannerAvoidOutput, VirtualMachineProfile vmProfile) {
-
-        ExcludeList allocatorAvoidOutput =
-                new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(), avoids.getPoolsToAvoid());
-
-        // remove any hosts/pools that the planners might have added
-        // to get the list of hosts/pools that Allocators flagged as 'avoid'
-
-        resetAvoidSet(allocatorAvoidOutput, plannerAvoidOutput);
-
-        // if all hosts or all pools in the cluster are in avoid set after this
-        // pass, then put the cluster in avoid set.
-        boolean avoidAllHosts = true;
-        boolean avoidAllPools = true;
-        boolean avoidAllLocalPools = true;
-        boolean avoidAllSharedPools = true;
-
-        List<HostVO> allhostsInCluster =
-                _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, clusterVO.getId(), clusterVO.getPodId(), clusterVO.getDataCenterId(), null);
-        for (HostVO host : allhostsInCluster) {
-            if (!allocatorAvoidOutput.shouldAvoid(host)) {
-                // there's some host in the cluster that is not yet in avoid set
-                avoidAllHosts = false;
-                break;
-            }
-        }
-
-        // all hosts in avoid set, avoid the cluster. Otherwise check the pools
-        if (avoidAllHosts) {
-            return true;
-        }
-
-        // Cluster can be put in avoid set in following scenarios:
-        // 1. If storage allocators haven't put any pools in avoid set means either no pools in cluster
-        // or pools not suitable for the allocators to handle or there is no
-        // linkage of any suitable host to any of the pools in cluster
-        // 2. If all 'shared' or 'local' pools are in avoid set
-        if  (allocatorAvoidOutput.getPoolsToAvoid() != null && !allocatorAvoidOutput.getPoolsToAvoid().isEmpty()) {
-
-            Pair<Boolean, Boolean> storageRequirements = findVMStorageRequirements(vmProfile);
-            boolean vmRequiresSharedStorage = storageRequirements.first();
-            boolean vmRequiresLocalStorege = storageRequirements.second();
-
-            if (vmRequiresSharedStorage) {
-                // check shared pools
-                List<StoragePoolVO> allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null);
-                for (StoragePoolVO pool : allPoolsInCluster) {
-                    if (!allocatorAvoidOutput.shouldAvoid(pool)) {
-                        // there's some pool in the cluster that is not yet in avoid set
-                        avoidAllSharedPools = false;
-                        break;
-                    }
-                }
-            }
-
-            if (vmRequiresLocalStorege) {
-                // check local pools
-                List<StoragePoolVO> allLocalPoolsInCluster =
-                        _storagePoolDao.findLocalStoragePoolsByTags(clusterVO.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null);
-                for (StoragePoolVO pool : allLocalPoolsInCluster) {
-                    if (!allocatorAvoidOutput.shouldAvoid(pool)) {
-                        // there's some pool in the cluster that is not yet
-                        // in avoid set
-                        avoidAllLocalPools = false;
-                        break;
-                    }
-                }
-            }
-
-            if (vmRequiresSharedStorage && vmRequiresLocalStorege) {
-                avoidAllPools = (avoidAllLocalPools || avoidAllSharedPools) ? true : false;
-            } else if (vmRequiresSharedStorage) {
-                avoidAllPools = avoidAllSharedPools;
-            } else if (vmRequiresLocalStorege) {
-                avoidAllPools = avoidAllLocalPools;
-            }
-        }
-
-        if (avoidAllHosts || avoidAllPools) {
-            return true;
-        }
-        return false;
-    }
-
-    private Pair<Boolean, Boolean> findVMStorageRequirements(VirtualMachineProfile vmProfile) {
-
-        boolean requiresShared = false, requiresLocal = false;
-
-        List<VolumeVO> volumesTobeCreated = _volsDao.findUsableVolumesForInstance(vmProfile.getId());
-
-        // for each volume find whether shared or local pool is required
-        for (VolumeVO toBeCreated : volumesTobeCreated) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
-
-            if (diskOffering != null) {
-                if (diskOffering.getUseLocalStorage()) {
-                    requiresLocal = true;
-                } else {
-                    requiresShared = true;
-                }
-            }
-        }
-
-        return new Pair<Boolean, Boolean>(requiresShared, requiresLocal);
-    }
-
-    protected Pair<Host, Map<Volume, StoragePool>> findPotentialDeploymentResources(List<Host> suitableHosts, Map<Volume, List<StoragePool>> suitableVolumeStoragePools,
-            ExcludeList avoid, DeploymentPlanner.PlannerResourceUsage resourceUsageRequired, List<Volume> readyAndReusedVolumes, List<Long> preferredHosts) {
-        s_logger.debug("Trying to find a potenial host and associated storage pools from the suitable host/pool lists for this VM");
-
-        boolean hostCanAccessPool = false;
-        boolean haveEnoughSpace = false;
-        boolean hostAffinityCheck = false;
-
-        if (readyAndReusedVolumes == null) {
-            readyAndReusedVolumes = new ArrayList<Volume>();
-        }
-        Map<Volume, StoragePool> storage = new HashMap<Volume, StoragePool>();
-        TreeSet<Volume> volumesOrderBySizeDesc = new TreeSet<Volume>(new Comparator<Volume>() {
-            @Override
-            public int compare(Volume v1, Volume v2) {
-                if (v1.getSize() < v2.getSize())
-                    return 1;
-                else
-                    return -1;
-            }
-        });
-        volumesOrderBySizeDesc.addAll(suitableVolumeStoragePools.keySet());
-        boolean multipleVolume = volumesOrderBySizeDesc.size() > 1;
-        for (Host potentialHost : suitableHosts) {
-            Map<StoragePool, List<Volume>> volumeAllocationMap = new HashMap<StoragePool, List<Volume>>();
-            for (Volume vol : volumesOrderBySizeDesc) {
-                haveEnoughSpace = false;
-                s_logger.debug("Checking if host: " + potentialHost.getId() + " can access any suitable storage pool for volume: " + vol.getVolumeType());
-                List<StoragePool> volumePoolList = suitableVolumeStoragePools.get(vol);
-                hostCanAccessPool = false;
-                hostAffinityCheck = checkAffinity(potentialHost, preferredHosts);
-                for (StoragePool potentialSPool : volumePoolList) {
-                    if (hostCanAccessSPool(potentialHost, potentialSPool)) {
-                        hostCanAccessPool = true;
-                        if (multipleVolume && !readyAndReusedVolumes.contains(vol)) {
-                            List<Volume> requestVolumes = null;
-                            if (volumeAllocationMap.containsKey(potentialSPool))
-                                requestVolumes = volumeAllocationMap.get(potentialSPool);
-                            else
-                                requestVolumes = new ArrayList<Volume>();
-                            requestVolumes.add(vol);
-
-                            if (!_storageMgr.storagePoolHasEnoughIops(requestVolumes, potentialSPool) ||
-                                !_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool, potentialHost.getClusterId()))
-                                continue;
-                            volumeAllocationMap.put(potentialSPool, requestVolumes);
-                        }
-                        storage.put(vol, potentialSPool);
-                        haveEnoughSpace = true;
-                        break;
-                    }
-                }
-                if (!hostCanAccessPool) {
-                    break;
-                }
-                if (!haveEnoughSpace) {
-                    s_logger.warn("insufficient capacity to allocate all volumes");
-                    break;
-                }
-                if (!hostAffinityCheck) {
-                    s_logger.debug("Host affinity check failed");
-                    break;
-                }
-            }
-            if (hostCanAccessPool && haveEnoughSpace && hostAffinityCheck && checkIfHostFitsPlannerUsage(potentialHost.getId(), resourceUsageRequired)) {
-                s_logger.debug("Found a potential host " + "id: " + potentialHost.getId() + " name: " + potentialHost.getName() +
-                        " and associated storage pools for this VM");
-                return new Pair<Host, Map<Volume, StoragePool>>(potentialHost, storage);
-            } else {
-                avoid.addHost(potentialHost.getId());
-            }
-        }
-        s_logger.debug("Could not find a potential host that has associated storage pools from the suitable host/pool lists for this VM");
-        return null;
-    }
-
-    /**
-     * True if:
-     * - Affinity is not enabled (preferred host is empty)
-     * - Affinity is enabled and potential host is on the preferred hosts list
-     *
-     * False if not
-     */
-    @DB
-    public boolean checkAffinity(Host potentialHost, List<Long> preferredHosts) {
-        boolean hostAffinityEnabled = CollectionUtils.isNotEmpty(preferredHosts);
-        boolean hostAffinityMatches = hostAffinityEnabled && preferredHosts.contains(potentialHost.getId());
-        return !hostAffinityEnabled || hostAffinityMatches;
-    }
-
-    protected boolean hostCanAccessSPool(Host host, StoragePool pool) {
-        boolean hostCanAccessSPool = false;
-
-        StoragePoolHostVO hostPoolLinkage = _poolHostDao.findByPoolHost(pool.getId(), host.getId());
-        if (hostPoolLinkage != null) {
-            hostCanAccessSPool = true;
-        }
-
-        s_logger.debug("Host: " + host.getId() + (hostCanAccessSPool ? " can" : " cannot") + " access pool: " + pool.getId());
-        return hostCanAccessSPool;
-    }
-
-    protected List<Host> findSuitableHosts(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
-        List<Host> suitableHosts = new ArrayList<Host>();
-        for (HostAllocator allocator : _hostAllocators) {
-            suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
-            if (suitableHosts != null && !suitableHosts.isEmpty()) {
-                break;
-            }
-        }
-
-        if (suitableHosts.isEmpty()) {
-            s_logger.debug("No suitable hosts found");
-        }
-        return suitableHosts;
-    }
-
-    protected Pair<Map<Volume, List<StoragePool>>, List<Volume>> findSuitablePoolsForVolumes(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid,
-            int returnUpTo) {
-        List<VolumeVO> volumesTobeCreated = _volsDao.findUsableVolumesForInstance(vmProfile.getId());
-        Map<Volume, List<StoragePool>> suitableVolumeStoragePools = new HashMap<Volume, List<StoragePool>>();
-        List<Volume> readyAndReusedVolumes = new ArrayList<Volume>();
-
-        // There should be atleast the ROOT volume of the VM in usable state
-        if (volumesTobeCreated.isEmpty()) {
-            throw new CloudRuntimeException("Unable to create deployment, no usable volumes found for the VM");
-        }
-
-        // don't allow to start vm that doesn't have a root volume
-        if (_volsDao.findByInstanceAndType(vmProfile.getId(), Volume.Type.ROOT).isEmpty()) {
-            throw new CloudRuntimeException("Unable to prepare volumes for vm as ROOT volume is missing");
-        }
-
-        // for each volume find list of suitable storage pools by calling the
-        // allocators
-        Set<Long> originalAvoidPoolSet = avoid.getPoolsToAvoid();
-        if (originalAvoidPoolSet == null) {
-            originalAvoidPoolSet = new HashSet<Long>();
-        }
-        Set<Long> poolsToAvoidOutput = new HashSet<Long>(originalAvoidPoolSet);
-
-        for (VolumeVO toBeCreated : volumesTobeCreated) {
-            s_logger.debug("Checking suitable pools for volume (Id, Type): (" + toBeCreated.getId() + "," + toBeCreated.getVolumeType().name() + ")");
-
-            // If the plan specifies a poolId, it means that this VM's ROOT
-            // volume is ready and the pool should be reused.
-            // In this case, also check if rest of the volumes are ready and can
-            // be reused.
-            if (plan.getPoolId() != null || (toBeCreated.getVolumeType() == Volume.Type.DATADISK && toBeCreated.getPoolId() != null && toBeCreated.getState() == Volume.State.Ready)) {
-                s_logger.debug("Volume has pool already allocated, checking if pool can be reused, poolId: " + toBeCreated.getPoolId());
-                List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-                StoragePool pool = null;
-                if (toBeCreated.getPoolId() != null) {
-                    pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
-                } else {
-                    pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
-                }
-
-                if (!pool.isInMaintenance()) {
-                    if (!avoid.shouldAvoid(pool)) {
-                        long exstPoolDcId = pool.getDataCenterId();
-                        long exstPoolPodId = pool.getPodId() != null ? pool.getPodId() : -1;
-                        long exstPoolClusterId = pool.getClusterId() != null ? pool.getClusterId() : -1;
-                        boolean canReusePool = false;
-                        if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) {
-                            canReusePool = true;
-                        } else if (plan.getDataCenterId() == exstPoolDcId) {
-                            DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId());
-                            if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) {
-                                canReusePool = true;
-                            }
-                        } else {
-                            s_logger.debug("Pool of the volume does not fit the specified plan, need to reallocate a pool for this volume");
-                            canReusePool = false;
-                        }
-
-                        if (canReusePool) {
-                            s_logger.debug("Planner need not allocate a pool for this volume since its READY");
-                            suitablePools.add(pool);
-                            suitableVolumeStoragePools.put(toBeCreated, suitablePools);
-                            if (!(toBeCreated.getState() == Volume.State.Allocated || toBeCreated.getState() == Volume.State.Creating)) {
-                                readyAndReusedVolumes.add(toBeCreated);
-                            }
-                            continue;
-                        }
-                    } else {
-                        s_logger.debug("Pool of the volume is in avoid set, need to reallocate a pool for this volume");
-                    }
-                } else {
-                    s_logger.debug("Pool of the volume is in maintenance, need to reallocate a pool for this volume");
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("We need to allocate new storagepool for this volume");
-            }
-            if (!isRootAdmin(vmProfile)) {
-                if (!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled");
-                        s_logger.debug("Cannot deploy to this specified plan, allocation state is disabled, returning.");
-                    }
-                    // Cannot find suitable storage pools under this cluster for
-                    // this volume since allocation_state is disabled.
-                    // - remove any suitable pools found for other volumes.
-                    // All volumes should get suitable pools under this cluster;
-                    // else we cant use this cluster.
-                    suitableVolumeStoragePools.clear();
-                    break;
-                }
-            }
-
-            s_logger.debug("Calling StoragePoolAllocators to find suitable pools");
-
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
-
-            if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) {
-                diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray()));
-            }
-
-            DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
-            boolean useLocalStorage = false;
-            if (vmProfile.getType() != VirtualMachine.Type.User) {
-                DataCenterVO zone = _dcDao.findById(plan.getDataCenterId());
-                assert (zone != null) : "Invalid zone in deployment plan";
-                Boolean useLocalStorageForSystemVM = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(zone.getId());
-                if (useLocalStorageForSystemVM != null) {
-                    useLocalStorage = useLocalStorageForSystemVM.booleanValue();
-                    s_logger.debug("System VMs will use " + (useLocalStorage ? "local" : "shared") + " storage for zone id=" + plan.getDataCenterId());
-                }
-            } else {
-                useLocalStorage = diskOffering.getUseLocalStorage();
-
-                // TODO: this is a hacking fix for the problem of deploy
-                // ISO-based VM on local storage
-                // when deploying VM based on ISO, we have a service offering
-                // and an additional disk offering, use-local storage flag is
-                // actually
-                // saved in service offering, override the flag from service
-                // offering when it is a ROOT disk
-                if (!useLocalStorage && vmProfile.getServiceOffering().getUseLocalStorage()) {
-                    if (toBeCreated.getVolumeType() == Volume.Type.ROOT) {
-                        useLocalStorage = true;
-                    }
-                }
-            }
-            diskProfile.setUseLocalStorage(useLocalStorage);
-
-            boolean foundPotentialPools = false;
-            for (StoragePoolAllocator allocator : _storagePoolAllocators) {
-                final List<StoragePool> suitablePools = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, returnUpTo);
-                if (suitablePools != null && !suitablePools.isEmpty()) {
-                    suitableVolumeStoragePools.put(toBeCreated, suitablePools);
-                    foundPotentialPools = true;
-                    break;
-                }
-            }
-
-            if (avoid.getPoolsToAvoid() != null) {
-                poolsToAvoidOutput.addAll(avoid.getPoolsToAvoid());
-                avoid.getPoolsToAvoid().retainAll(originalAvoidPoolSet);
-            }
-
-            if (!foundPotentialPools) {
-                s_logger.debug("No suitable pools found for volume: " + toBeCreated + " under cluster: " + plan.getClusterId());
-                // No suitable storage pools found under this cluster for this
-                // volume. - remove any suitable pools found for other volumes.
-                // All volumes should get suitable pools under this cluster;
-                // else we cant use this cluster.
-                suitableVolumeStoragePools.clear();
-                break;
-            }
-        }
-
-        HashSet<Long> toRemove = new HashSet<Long>();
-        for (List<StoragePool> lsp : suitableVolumeStoragePools.values()) {
-            for (StoragePool sp : lsp) {
-                toRemove.add(sp.getId());
-            }
-        }
-        poolsToAvoidOutput.removeAll(toRemove);
-
-        if (avoid.getPoolsToAvoid() != null) {
-            avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput);
-        }
-
-        if (suitableVolumeStoragePools.isEmpty()) {
-            s_logger.debug("No suitable pools found");
-        }
-
-        return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes);
-    }
-
-    private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) {
-        // Check if the zone exists in the system
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone != null && Grouping.AllocationState.Disabled == zone.getAllocationState()) {
-            s_logger.info("Zone is currently disabled, cannot allocate to this zone: " + zoneId);
-            return false;
-        }
-
-        Pod pod = _podDao.findById(podId);
-        if (pod != null && Grouping.AllocationState.Disabled == pod.getAllocationState()) {
-            s_logger.info("Pod is currently disabled, cannot allocate to this pod: " + podId);
-            return false;
-        }
-
-        Cluster cluster = _clusterDao.findById(clusterId);
-        if (cluster != null && Grouping.AllocationState.Disabled == cluster.getAllocationState()) {
-            s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: " + clusterId);
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean isRootAdmin(VirtualMachineProfile vmProfile) {
-        if (vmProfile != null) {
-            if (vmProfile.getOwner() != null) {
-                return _accountMgr.isRootAdmin(vmProfile.getOwner().getId());
-            } else {
-                return false;
-            }
-        }
-        return false;
-    }
-
-    @DB
-    @Override
-    public String finalizeReservation(final DeployDestination plannedDestination, final VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, final DeploymentPlanner planner)
-            throws InsufficientServerCapacityException, AffinityConflictException {
-
-        final VirtualMachine vm = vmProfile.getVirtualMachine();
-        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
-
-        return Transaction.execute(new TransactionCallback<String>() {
-            @Override
-            public String doInTransaction(TransactionStatus status) {
-                boolean saveReservation = true;
-
-                if (vmGroupCount > 0) {
-                    List<Long> groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId());
-                    SearchCriteria<AffinityGroupVO> criteria = _affinityGroupDao.createSearchCriteria();
-                    criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()]));
-                    _affinityGroupDao.lockRows(criteria, null, true);
-
-                    for (AffinityGroupProcessor processor : _affinityProcessors) {
-                        if (!processor.check(vmProfile, plannedDestination)) {
-                            saveReservation = false;
-                            break;
-                        }
-                    }
-                }
-
-                if (saveReservation) {
-                    VMReservationVO vmReservation =
-                            new VMReservationVO(vm.getId(), plannedDestination.getDataCenter().getId(), plannedDestination.getPod().getId(), plannedDestination.getCluster()
-                                    .getId(), plannedDestination.getHost().getId());
-                    if (planner != null) {
-                        vmReservation.setDeploymentPlanner(planner.getName());
-                    }
-                    Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>();
-
-                    if (vm.getHypervisorType() != HypervisorType.BareMetal) {
-                        for (Volume vo : plannedDestination.getStorageForDisks().keySet()) {
-                            volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId());
-                        }
-                        vmReservation.setVolumeReservation(volumeReservationMap);
-                    }
-                    _reservationDao.persist(vmReservation);
-                    return vmReservation.getUuid();
-                }
-
-                return null;
-            }
-        });
-    }
-
-    @Override
-    public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        return true;
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
-      if (!status) {
-        return false;
-      }
-      State oldState = transition.getCurrentState();
-      State newState = transition.getToState();
-      if ((oldState == State.Starting) && (newState != State.Starting)) {
-        // cleanup all VM reservation entries
-        SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
-        sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
-        _reservationDao.expunge(sc);
-      }
-      return true;
-    }
-}
diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
deleted file mode 100644
index fe6b717..0000000
--- a/server/src/com/cloud/ha/HighAvailabilityManagerImpl.java
+++ /dev/null
@@ -1,1007 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.ha;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContext;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.alert.AlertManager;
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.deploy.HAPlanner;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.ha.Investigator.UnknownVM;
-import com.cloud.ha.dao.HighAvailabilityDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ManagementServer;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.VMInstanceDao;
-
-/**
- * HighAvailabilityManagerImpl coordinates the HA process. VMs are registered with the HA Manager for HA. The request is stored
- * within a database backed work queue. HAManager has a number of workers that pick up these work items to perform HA on the
- * VMs.
- *
- * The HA process goes as follows: 1. Check with the list of Investigators to determine that the VM is no longer running. If a
- * Investigator finds the VM is still alive, the HA process is stopped and the state of the VM reverts back to its previous
- * state. If a Investigator finds the VM is dead, then HA process is started on the VM, skipping step 2. 2. If the list of
- * Investigators can not determine if the VM is dead or alive. The list of FenceBuilders is invoked to fence off the VM so that
- * it won't do any damage to the storage and network. 3. The VM is marked as stopped. 4. The VM is started again via the normal
- * process of starting VMs. Note that once the VM is marked as stopped, the user may have started the VM himself. 5. VMs that
- * have re-started more than the configured number of times are marked as in Error state and the user is not allowed to restart
- * the VM.
- *
- * @config {@table || Param Name | Description | Values | Default || || workers | number of worker threads to spin off to do the
- *         processing | int | 1 || || time.to.sleep | Time to sleep if no work items are found | seconds | 60 || || max.retries
- *         | number of times to retry start | int | 5 || || time.between.failure | Time elapsed between failures before we
- *         consider it as another retry | seconds | 3600 || || time.between.cleanup | Time to wait before the cleanup thread
- *         runs | seconds | 86400 || || force.ha | Force HA to happen even if the VM says no | boolean | false || ||
- *         ha.retry.wait | time to wait before retrying the work item | seconds | 120 || || stop.retry.wait | time to wait
- *         before retrying the stop | seconds | 120 || * }
- **/
-public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener {
-
-    protected static final Logger s_logger = Logger.getLogger(HighAvailabilityManagerImpl.class);
-    WorkerThread[] _workers;
-    boolean _stopped;
-    long _timeToSleep;
-    @Inject
-    HighAvailabilityDao _haDao;
-    @Inject
-    VMInstanceDao _instanceDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    HostPodDao _podDao;
-    @Inject
-    ClusterDetailsDao _clusterDetailsDao;
-
-    @Inject
-    ServiceOfferingDao _serviceOfferingDao;
-
-    long _serverId;
-
-    @Inject
-    ManagedContext _managedContext;
-
-    List<Investigator> investigators;
-
-    public List<Investigator> getInvestigators() {
-        return investigators;
-    }
-
-    public void setInvestigators(List<Investigator> investigators) {
-        this.investigators = investigators;
-    }
-
-    List<FenceBuilder> fenceBuilders;
-
-    public List<FenceBuilder> getFenceBuilders() {
-        return fenceBuilders;
-    }
-
-    public void setFenceBuilders(List<FenceBuilder> fenceBuilders) {
-        this.fenceBuilders = fenceBuilders;
-    }
-
-    List<HAPlanner> _haPlanners;
-    public List<HAPlanner> getHaPlanners() {
-        return _haPlanners;
-    }
-
-    public void setHaPlanners(List<HAPlanner> haPlanners) {
-        _haPlanners = haPlanners;
-    }
-
-
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    AlertManager _alertMgr;
-    @Inject
-    StorageManager _storageMgr;
-    @Inject
-    GuestOSDao _guestOSDao;
-    @Inject
-    GuestOSCategoryDao _guestOSCategoryDao;
-    @Inject
-    VirtualMachineManager _itMgr;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    ManagementServer _msServer;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    VolumeOrchestrationService volumeMgr;
-
-    String _instance;
-    ScheduledExecutorService _executor;
-    int _stopRetryInterval;
-    int _investigateRetryInterval;
-    int _migrateRetryInterval;
-    int _restartRetryInterval;
-
-    int _maxRetries;
-    long _timeBetweenFailures;
-    long _timeBetweenCleanups;
-    boolean _forceHA;
-    String _haTag = null;
-
-    protected HighAvailabilityManagerImpl() {
-    }
-
-    @Override
-    public Status investigate(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            return Status.Alert;
-        }
-
-        Status hostState = null;
-        for (Investigator investigator : investigators) {
-            hostState = investigator.isAgentAlive(host);
-            if (hostState != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(investigator.getName() + " was able to determine host " + hostId + " is in " + hostState.toString());
-                }
-                return hostState;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(investigator.getName() + " unable to determine the state of the host.  Moving on.");
-            }
-        }
-
-        return hostState;
-    }
-
-    @Override
-    public void scheduleRestartForVmsOnHost(final HostVO host, boolean investigate) {
-
-        if (host.getType() != Host.Type.Routing) {
-            return;
-        }
-
-        if (host.getHypervisorType() == HypervisorType.VMware || host.getHypervisorType() == HypervisorType.Hyperv) {
-            s_logger.info("Don't restart VMs on host " + host.getId() + " as it is a " + host.getHypervisorType().toString() + " host");
-            return;
-        }
-
-        s_logger.warn("Scheduling restart for VMs on host " + host.getId() + "-" + host.getName());
-
-        final List<VMInstanceVO> vms = _instanceDao.listByHostId(host.getId());
-        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-
-        // send an email alert that the host is down
-        StringBuilder sb = null;
-        List<VMInstanceVO> reorderedVMList = new ArrayList<VMInstanceVO>();
-        if ((vms != null) && !vms.isEmpty()) {
-            sb = new StringBuilder();
-            sb.append("  Starting HA on the following VMs:");
-            // collect list of vm names for the alert email
-            for (int i = 0; i < vms.size(); i++) {
-                VMInstanceVO vm = vms.get(i);
-                if (vm.getType() == VirtualMachine.Type.User) {
-                    reorderedVMList.add(vm);
-                } else {
-                    reorderedVMList.add(0, vm);
-                }
-                if (vm.isHaEnabled()) {
-                    sb.append(" " + vm.getHostName());
-                }
-            }
-        }
-
-        // send an email alert that the host is down, include VMs
-        HostPodVO podVO = _podDao.findById(host.getPodId());
-        String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host is down, " + hostDesc,
-                "Host [" + hostDesc + "] is down." + ((sb != null) ? sb.toString() : ""));
-
-        for (VMInstanceVO vm : reorderedVMList) {
-            ServiceOfferingVO vmOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
-            if (vmOffering.getUseLocalStorage()) {
-                if (s_logger.isDebugEnabled()){
-                    s_logger.debug("Skipping HA on vm " + vm + ", because it uses local storage. Its fate is tied to the host.");
-                }
-                continue;
-            }
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Notifying HA Mgr of to restart vm " + vm.getId() + "-" + vm.getInstanceName());
-            }
-            vm = _instanceDao.findByUuid(vm.getUuid());
-            Long hostId = vm.getHostId();
-            if (hostId != null && !hostId.equals(host.getId())) {
-                s_logger.debug("VM " + vm.getInstanceName() + " is not on down host " + host.getId() + " it is on other host "
-                        + hostId + " VM HA is done");
-                continue;
-            }
-            scheduleRestart(vm, investigate);
-        }
-    }
-
-    @Override
-    public void scheduleStop(VMInstanceVO vm, long hostId, WorkType type) {
-        assert (type == WorkType.CheckStop || type == WorkType.ForceStop || type == WorkType.Stop);
-
-        if (_haDao.hasBeenScheduled(vm.getId(), type)) {
-            s_logger.info("There's already a job scheduled to stop " + vm);
-            return;
-        }
-
-        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), type, Step.Scheduled, hostId, vm.getState(), 0, vm.getUpdated());
-        _haDao.persist(work);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Scheduled " + work);
-        }
-        wakeupWorkers();
-    }
-
-    protected void wakeupWorkers() {
-        for (WorkerThread worker : _workers) {
-            worker.wakup();
-        }
-    }
-
-    @Override
-    public boolean scheduleMigration(final VMInstanceVO vm) {
-        if (vm.getHostId() != null) {
-            final HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.Migration, Step.Scheduled, vm.getHostId(), vm.getState(), 0, vm.getUpdated());
-            _haDao.persist(work);
-            wakeupWorkers();
-        }
-        return true;
-    }
-
-    @Override
-    public void scheduleRestart(VMInstanceVO vm, boolean investigate) {
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            try {
-                s_logger.debug("Found a vm that is scheduled to be restarted but has no host id: " + vm);
-                _itMgr.advanceStop(vm.getUuid(), true);
-            } catch (ResourceUnavailableException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            } catch (OperationTimedoutException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            } catch (ConcurrentOperationException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            }
-        }
-
-        if (vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.Hyperv) {
-            s_logger.info("Skip HA for VMware VM or Hyperv VM" + vm.getInstanceName());
-            return;
-        }
-
-        if (!investigate) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM does not require investigation so I'm marking it as Stopped: " + vm.toString());
-            }
-
-            AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM;
-            if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
-                alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER;
-            } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
-                alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY;
-            } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) {
-                alertType = AlertManager.AlertType.ALERT_TYPE_SSVM;
-            }
-
-            if (!(_forceHA || vm.isHaEnabled())) {
-                String hostDesc = "id:" + vm.getHostId() + ", availability zone id:" + vm.getDataCenterId() + ", pod id:" + vm.getPodIdToDeployIn();
-                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getHostName() + ", id: " + vm.getId() +
-                    ") stopped unexpectedly on host " + hostDesc, "Virtual Machine " + vm.getHostName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() +
-                    "] stopped unexpectedly.");
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("VM is not HA enabled so we're done.");
-                }
-            }
-
-            try {
-                _itMgr.advanceStop(vm.getUuid(), true);
-                vm = _instanceDao.findByUuid(vm.getUuid());
-            } catch (ResourceUnavailableException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            } catch (OperationTimedoutException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            } catch (ConcurrentOperationException e) {
-                assert false : "How do we hit this when force is true?";
-                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-            }
-        }
-
-        if (vm.getHypervisorType() == HypervisorType.VMware) {
-            s_logger.info("Skip HA for VMware VM " + vm.getInstanceName());
-            return;
-        }
-
-        List<HaWorkVO> items = _haDao.findPreviousHA(vm.getId());
-        int timesTried = 0;
-        for (HaWorkVO item : items) {
-            if (timesTried < item.getTimesTried() && !item.canScheduleNew(_timeBetweenFailures)) {
-                timesTried = item.getTimesTried();
-                break;
-            }
-        }
-
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-        }
-
-        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.HA, investigate ? Step.Investigating : Step.Scheduled,
-                hostId != null ? hostId : 0L, vm.getState(), timesTried, vm.getUpdated());
-        _haDao.persist(work);
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Schedule vm for HA:  " + vm);
-        }
-
-        wakeupWorkers();
-
-    }
-
-    protected Long restart(final HaWorkVO work) {
-        List<HaWorkVO> items = _haDao.listFutureHaWorkForVm(work.getInstanceId(), work.getId());
-        if (items.size() > 0) {
-            StringBuilder str = new StringBuilder("Cancelling this work item because newer ones have been scheduled.  Work Ids = [");
-            for (HaWorkVO item : items) {
-                str.append(item.getId()).append(", ");
-            }
-            str.delete(str.length() - 2, str.length()).append("]");
-            s_logger.info(str.toString());
-            return null;
-        }
-
-        items = _haDao.listRunningHaWorkForVm(work.getInstanceId());
-        if (items.size() > 0) {
-            StringBuilder str = new StringBuilder("Waiting because there's HA work being executed on an item currently.  Work Ids =[");
-            for (HaWorkVO item : items) {
-                str.append(item.getId()).append(", ");
-            }
-            str.delete(str.length() - 2, str.length()).append("]");
-            s_logger.info(str.toString());
-            return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
-        }
-
-        long vmId = work.getInstanceId();
-
-        VirtualMachine vm = _itMgr.findById(work.getInstanceId());
-        if (vm == null) {
-            s_logger.info("Unable to find vm: " + vmId);
-            return null;
-        }
-
-        s_logger.info("HA on " + vm);
-        if (vm.getState() != work.getPreviousState() || vm.getUpdated() != work.getUpdateTime()) {
-            s_logger.info("VM " + vm + " has been changed.  Current State = " + vm.getState() + " Previous State = " + work.getPreviousState() + " last updated = " +
-                vm.getUpdated() + " previous updated = " + work.getUpdateTime());
-            return null;
-        }
-
-        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM;
-        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER;
-        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY;
-        } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) {
-            alertType = AlertManager.AlertType.ALERT_TYPE_SSVM;
-        }
-
-        HostVO host = _hostDao.findById(work.getHostId());
-        boolean isHostRemoved = false;
-        if (host == null) {
-            host = _hostDao.findByIdIncludingRemoved(work.getHostId());
-            if (host != null) {
-                s_logger.debug("VM " + vm.toString() + " is now no longer on host " + work.getHostId() + " as the host is removed");
-                isHostRemoved = true;
-            }
-        }
-
-        DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
-        HostPodVO podVO = _podDao.findById(host.getPodId());
-        String hostDesc = "name: " + host.getName() + "(id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
-
-        Boolean alive = null;
-        if (work.getStep() == Step.Investigating) {
-            if (!isHostRemoved) {
-                if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) {
-                    s_logger.info("VM " + vm.toString() + " is now no longer on host " + work.getHostId());
-                    return null;
-                }
-
-                Investigator investigator = null;
-                for (Investigator it : investigators) {
-                    investigator = it;
-                    try
-                    {
-                        alive = investigator.isVmAlive(vm, host);
-                        s_logger.info(investigator.getName() + " found " + vm + " to be alive? " + alive);
-                        break;
-                    } catch (UnknownVM e) {
-                        s_logger.info(investigator.getName() + " could not find " + vm);
-                    }
-                }
-
-                boolean fenced = false;
-                if (alive == null) {
-                    s_logger.debug("Fencing off VM that we don't know the state of");
-                    for (FenceBuilder fb : fenceBuilders) {
-                        Boolean result = fb.fenceOff(vm, host);
-                        s_logger.info("Fencer " + fb.getName() + " returned " + result);
-                        if (result != null && result) {
-                            fenced = true;
-                            break;
-                        }
-                    }
-
-                } else if (!alive) {
-                    fenced = true;
-                } else {
-                    s_logger.debug("VM " + vm.getInstanceName() + " is found to be alive by " + investigator.getName());
-                    if (host.getStatus() == Status.Up) {
-                        s_logger.info(vm + " is alive and host is up. No need to restart it.");
-                        return null;
-                    } else {
-                        s_logger.debug("Rescheduling because the host is not up but the vm is alive");
-                        return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
-                    }
-                }
-
-                if (!fenced) {
-                    s_logger.debug("We were unable to fence off the VM " + vm);
-                    _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() +
-                        " which was running on host " + hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId +
-                        " which was running on host " + hostDesc);
-                    return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
-                }
-
-                try {
-                    _itMgr.advanceStop(vm.getUuid(), true);
-                } catch (ResourceUnavailableException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                } catch (OperationTimedoutException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                } catch (ConcurrentOperationException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                }
-
-                work.setStep(Step.Scheduled);
-                _haDao.update(work.getId(), work);
-            } else {
-                s_logger.debug("How come that HA step is Investigating and the host is removed? Calling forced Stop on Vm anyways");
-                try {
-                    _itMgr.advanceStop(vm.getUuid(), true);
-                } catch (ResourceUnavailableException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                } catch (OperationTimedoutException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                } catch (ConcurrentOperationException e) {
-                    assert false : "How do we hit this when force is true?";
-                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
-                }
-            }
-        }
-
-        vm = _itMgr.findById(vm.getId());
-
-        if (!_forceHA && !vm.isHaEnabled()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not HA enabled so we're done.");
-            }
-            return null; // VM doesn't require HA
-        }
-
-        if ((host == null || host.getRemoved() != null || host.getState() != Status.Up)
-                 && !volumeMgr.canVmRestartOnAnotherServer(vm.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM can not restart on another server.");
-            }
-            return null;
-        }
-
-        try {
-            HashMap<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
-            if (_haTag != null) {
-                params.put(VirtualMachineProfile.Param.HaTag, _haTag);
-            }
-            WorkType wt = work.getWorkType();
-            if (wt.equals(WorkType.HA)) {
-                params.put(VirtualMachineProfile.Param.HaOperation, true);
-            }
-
-            try{
-                // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
-                _itMgr.advanceStart(vm.getUuid(), params, null);
-            }catch (InsufficientCapacityException e){
-                s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner");
-                _itMgr.advanceStart(vm.getUuid(), params, _haPlanners.get(0));
-            }
-
-            VMInstanceVO started = _instanceDao.findById(vm.getId());
-            if (started != null && started.getState() == VirtualMachine.State.Running) {
-                s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
-                return null;
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
-            }
-        } catch (final InsufficientCapacityException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
-                hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (final ResourceUnavailableException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
-                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
-                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
-            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
-                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
-        }
-        vm = _itMgr.findById(vm.getId());
-        work.setUpdateTime(vm.getUpdated());
-        work.setPreviousState(vm.getState());
-        return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
-    }
-
-    public Long migrate(final HaWorkVO work) {
-        long vmId = work.getInstanceId();
-
-        long srcHostId = work.getHostId();
-        try {
-            work.setStep(Step.Migrating);
-            _haDao.update(work.getId(), work);
-
-            VMInstanceVO vm = _instanceDao.findById(vmId);
-            if (vm == null) {
-                return null;
-            }
-            // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
-            _itMgr.migrateAway(vm.getUuid(), srcHostId);
-            return null;
-        } catch (InsufficientServerCapacityException e) {
-            s_logger.warn("Insufficient capacity for migrating a VM.");
-            _resourceMgr.maintenanceFailed(srcHostId);
-            return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
-        }
-    }
-
-    @Override
-    public void scheduleDestroy(VMInstanceVO vm, long hostId) {
-        final HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.Destroy, Step.Scheduled, hostId, vm.getState(), 0, vm.getUpdated());
-        _haDao.persist(work);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Scheduled " + work.toString());
-        }
-        wakeupWorkers();
-    }
-
-    @Override
-    public void cancelDestroy(VMInstanceVO vm, Long hostId) {
-        _haDao.delete(vm.getId(), WorkType.Destroy);
-    }
-
-    protected Long destroyVM(final HaWorkVO work) {
-        final VirtualMachine vm = _itMgr.findById(work.getInstanceId());
-        s_logger.info("Destroying " + vm.toString());
-        try {
-            if (vm.getState() != State.Destroyed) {
-                s_logger.info("VM is no longer in Destroyed state " + vm.toString());
-                return null;
-            }
-
-            if (vm.getHostId() != null) {
-                _itMgr.destroy(vm.getUuid(), false);
-                s_logger.info("Successfully destroy " + vm);
-                return null;
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(vm + " has already been stopped");
-                }
-                return null;
-            }
-        } catch (final AgentUnavailableException e) {
-            s_logger.debug("Agnet is not available" + e.getMessage());
-        } catch (OperationTimedoutException e) {
-            s_logger.debug("operation timed out: " + e.getMessage());
-        } catch (ConcurrentOperationException e) {
-            s_logger.debug("concurrent operation: " + e.getMessage());
-        }
-
-        return (System.currentTimeMillis() >> 10) + _stopRetryInterval;
-    }
-
-    protected Long stopVM(final HaWorkVO work) throws ConcurrentOperationException {
-        VirtualMachine vm = _itMgr.findById(work.getInstanceId());
-        if (vm == null) {
-            s_logger.info("No longer can find VM " + work.getInstanceId() + ". Throwing away " + work);
-            work.setStep(Step.Done);
-            return null;
-        }
-        s_logger.info("Stopping " + vm);
-        try {
-            if (work.getWorkType() == WorkType.Stop) {
-                _itMgr.advanceStop(vm.getUuid(), false);
-                s_logger.info("Successfully stopped " + vm);
-                return null;
-            } else if (work.getWorkType() == WorkType.CheckStop) {
-                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null ||
-                    vm.getHostId().longValue() != work.getHostId()) {
-                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " +
-                        (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
-                    return null;
-                }
-
-                _itMgr.advanceStop(vm.getUuid(), false);
-                s_logger.info("Stop for " + vm + " was successful");
-                return null;
-            } else if (work.getWorkType() == WorkType.ForceStop) {
-                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null ||
-                    vm.getHostId().longValue() != work.getHostId()) {
-                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " +
-                        (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
-                    return null;
-                }
-
-                _itMgr.advanceStop(vm.getUuid(), true);
-                s_logger.info("Stop for " + vm + " was successful");
-                return null;
-            } else {
-                assert false : "Who decided there's other steps but didn't modify the guy who does the work?";
-            }
-        } catch (final ResourceUnavailableException e) {
-            s_logger.debug("Agnet is not available" + e.getMessage());
-        } catch (OperationTimedoutException e) {
-            s_logger.debug("operation timed out: " + e.getMessage());
-        }
-
-        return (System.currentTimeMillis() >> 10) + _stopRetryInterval;
-    }
-
-    @Override
-    public void cancelScheduledMigrations(final HostVO host) {
-        WorkType type = host.getType() == HostVO.Type.Storage ? WorkType.Stop : WorkType.Migration;
-
-        _haDao.deleteMigrationWorkItems(host.getId(), type, _serverId);
-    }
-
-    @Override
-    public List<VMInstanceVO> findTakenMigrationWork() {
-        List<HaWorkVO> works = _haDao.findTakenWorkItems(WorkType.Migration);
-        List<VMInstanceVO> vms = new ArrayList<VMInstanceVO>(works.size());
-        for (HaWorkVO work : works) {
-            VMInstanceVO vm = _instanceDao.findById(work.getInstanceId());
-            if (vm != null) {
-                vms.add(vm);
-            }
-        }
-        return vms;
-    }
-
-    private void rescheduleWork(final HaWorkVO work, final long nextTime) {
-        s_logger.info("Rescheduling work " + work + " to try again at " + new Date(nextTime << 10));
-        work.setTimeToTry(nextTime);
-        work.setTimesTried(work.getTimesTried() + 1);
-        work.setServerId(null);
-        work.setDateTaken(null);
-    }
-
-    private long getRescheduleTime(WorkType workType) {
-        switch (workType) {
-            case Migration:
-                return ((System.currentTimeMillis() >> 10) + _migrateRetryInterval);
-            case HA:
-                return ((System.currentTimeMillis() >> 10) + _restartRetryInterval);
-            case Stop:
-            case CheckStop:
-            case ForceStop:
-                return ((System.currentTimeMillis() >> 10) + _stopRetryInterval);
-            case Destroy:
-                return ((System.currentTimeMillis() >> 10) + _restartRetryInterval);
-        }
-        return 0;
-    }
-
-    private void processWork(final HaWorkVO work) {
-        final WorkType wt = work.getWorkType();
-        try {
-            Long nextTime = null;
-            if (wt == WorkType.Migration) {
-                nextTime = migrate(work);
-            } else if (wt == WorkType.HA) {
-                nextTime = restart(work);
-            } else if (wt == WorkType.Stop || wt == WorkType.CheckStop || wt == WorkType.ForceStop) {
-                nextTime = stopVM(work);
-            } else if (wt == WorkType.Destroy) {
-                nextTime = destroyVM(work);
-            } else {
-                assert false : "How did we get here with " + wt.toString();
-                return;
-            }
-
-            if (nextTime == null) {
-                s_logger.info("Completed work " + work);
-                work.setStep(Step.Done);
-            } else {
-                rescheduleWork(work, nextTime.longValue());
-            }
-        } catch (Exception e) {
-            s_logger.warn("Encountered unhandled exception during HA process, reschedule work", e);
-
-            long nextTime = getRescheduleTime(wt);
-            rescheduleWork(work, nextTime);
-
-            // if restart failed in the middle due to exception, VM state may has been changed
-            // recapture into the HA worker so that it can really continue in it next turn
-            VMInstanceVO vm = _instanceDao.findById(work.getInstanceId());
-            work.setUpdateTime(vm.getUpdated());
-            work.setPreviousState(vm.getState());
-        }
-        if (!Step.Done.equals(work.getStep()) && work.getTimesTried() >= _maxRetries) {
-            s_logger.warn("Giving up, retried max. times for work: " + work);
-            work.setStep(Step.Done);
-        }
-        _haDao.update(work.getId(), work);
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
-        _serverId = _msServer.getId();
-
-        Map<String, String> params = new HashMap<String, String>();
-        params = _configDao.getConfiguration(Long.toHexString(_serverId), xmlParams);
-
-        String value = params.get(Config.HAWorkers.key());
-        final int count = NumbersUtil.parseInt(value, 1);
-        _workers = new WorkerThread[count];
-        for (int i = 0; i < _workers.length; i++) {
-            _workers[i] = new WorkerThread("HA-Worker-" + i);
-        }
-
-        value = params.get("force.ha");
-        _forceHA = Boolean.parseBoolean(value);
-
-        value = params.get("time.to.sleep");
-        _timeToSleep = (long)NumbersUtil.parseInt(value, 60) * 1000;
-
-        value = params.get("max.retries");
-        _maxRetries = NumbersUtil.parseInt(value, 5);
-
-        value = params.get("time.between.failures");
-        _timeBetweenFailures = NumbersUtil.parseLong(value, 3600) * 1000;
-
-        value = params.get("time.between.cleanup");
-        _timeBetweenCleanups = NumbersUtil.parseLong(value, 3600 * 24);
-
-        value = params.get("stop.retry.interval");
-        _stopRetryInterval = NumbersUtil.parseInt(value, 10 * 60);
-
-        value = params.get("restart.retry.interval");
-        _restartRetryInterval = NumbersUtil.parseInt(value, 10 * 60);
-
-        value = params.get("investigate.retry.interval");
-        _investigateRetryInterval = NumbersUtil.parseInt(value, 1 * 60);
-
-        value = params.get("migrate.retry.interval");
-        _migrateRetryInterval = NumbersUtil.parseInt(value, 2 * 60);
-
-        _instance = params.get("instance");
-        if (_instance == null) {
-            _instance = "VMOPS";
-        }
-
-        _haTag = params.get("ha.tag");
-
-        _haDao.releaseWorkItems(_serverId);
-
-        _stopped = true;
-
-        _executor = Executors.newScheduledThreadPool(count, new NamedThreadFactory("HA"));
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        _stopped = false;
-
-        for (final WorkerThread thread : _workers) {
-            thread.start();
-        }
-
-        _executor.scheduleAtFixedRate(new CleanupTask(), _timeBetweenCleanups, _timeBetweenCleanups, TimeUnit.SECONDS);
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _stopped = true;
-
-        wakeupWorkers();
-
-        _executor.shutdown();
-
-        return true;
-    }
-
-    protected class CleanupTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            s_logger.info("HA Cleanup Thread Running");
-
-            try {
-                _haDao.cleanup(System.currentTimeMillis() - _timeBetweenFailures);
-            } catch (Exception e) {
-                s_logger.warn("Error while cleaning up", e);
-            }
-        }
-    }
-
-    protected class WorkerThread extends Thread {
-        public WorkerThread(String name) {
-            super(name);
-        }
-
-        @Override
-        public void run() {
-            s_logger.info("Starting work");
-            while (!_stopped) {
-                _managedContext.runWithContext(new Runnable() {
-                    @Override
-                    public void run() {
-                        runWithContext();
-                    }
-                });
-            }
-            s_logger.info("Time to go home!");
-        }
-
-        private void runWithContext() {
-            HaWorkVO work = null;
-            try {
-                s_logger.trace("Checking the database for work");
-                work = _haDao.take(_serverId);
-                if (work == null) {
-                    try {
-                        synchronized (this) {
-                            wait(_timeToSleep);
-                        }
-                        return;
-                    } catch (final InterruptedException e) {
-                        s_logger.info("Interrupted");
-                        return;
-                    }
-                }
-
-                NDC.push("work-" + work.getId());
-                s_logger.info("Processing work " + work);
-                processWork(work);
-            } catch (final Throwable th) {
-                s_logger.error("Caught this throwable, ", th);
-            } finally {
-                if (work != null) {
-                    NDC.pop();
-                }
-            }
-        }
-
-        public synchronized void wakup() {
-            notifyAll();
-        }
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (ManagementServerHost node : nodeList) {
-            _haDao.releaseWorkItems(node.getMsid());
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public String getHaTag() {
-        return _haTag;
-    }
-
-    @Override
-    public DeploymentPlanner getHAPlanner() {
-        return _haPlanners.get(0);
-    }
-
-    @Override
-    public boolean hasPendingHaWork(long vmId) {
-        List<HaWorkVO> haWorks = _haDao.listPendingHaWorkForVm(vmId);
-        return haWorks.size() > 0;
-    }
-}
diff --git a/server/src/com/cloud/ha/KVMFencer.java b/server/src/com/cloud/ha/KVMFencer.java
deleted file mode 100644
index 3f06872..0000000
--- a/server/src/com/cloud/ha/KVMFencer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.ha;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.alert.AlertManager;
-import com.cloud.agent.api.FenceAnswer;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.VirtualMachine;
-
-public class KVMFencer extends AdapterBase implements FenceBuilder {
-    private static final Logger s_logger = Logger.getLogger(KVMFencer.class);
-
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    AlertManager _alertMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public KVMFencer() {
-        super();
-    }
-
-    @Override
-    public Boolean fenceOff(VirtualMachine vm, Host host) {
-        if (host.getHypervisorType() != HypervisorType.KVM && host.getHypervisorType() != HypervisorType.LXC) {
-            s_logger.warn("Don't know how to fence non kvm hosts " + host.getHypervisorType());
-            return null;
-        }
-
-        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
-        FenceCommand fence = new FenceCommand(vm, host);
-
-        int i = 0;
-        for (HostVO h : hosts) {
-            if (h.getHypervisorType() == HypervisorType.KVM || h.getHypervisorType() == HypervisorType.LXC) {
-                if (h.getStatus() != Status.Up) {
-                    continue;
-                }
-
-                i++;
-
-                if (h.getId() == host.getId()) {
-                    continue;
-                }
-                FenceAnswer answer;
-                try {
-                    answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
-                } catch (AgentUnavailableException e) {
-                    s_logger.info("Moving on to the next host because " + h.toString() + " is unavailable");
-                    continue;
-                } catch (OperationTimedoutException e) {
-                    s_logger.info("Moving on to the next host because " + h.toString() + " is unavailable");
-                    continue;
-                }
-                if (answer != null && answer.getResult()) {
-                    return true;
-                }
-            }
-        }
-
-        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(),
-                            "Unable to fence off host: " + host.getId(),
-                            "Fencing off host " + host.getId() + " did not succeed after asking " + i + " hosts. " +
-                            "Check Agent logs for more information.");
-
-        s_logger.error("Unable to fence off " + vm.toString() + " on " + host.toString());
-
-        return false;
-    }
-}
diff --git a/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java b/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java
deleted file mode 100644
index 2aa9b04..0000000
--- a/server/src/com/cloud/hypervisor/CloudZonesStartupProcessor.java
+++ /dev/null
@@ -1,507 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.ResourceDetail;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.StartupCommandProcessor;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.StartupStorageCommand;
-import com.cloud.agent.manager.authn.AgentAuthnException;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.exception.ConnectionException;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.MacAddress;
-import com.cloud.utils.net.NetUtils;
-
-/**
- * Creates a host record and supporting records such as pod and ip address
- *
- */
-@Component
-public class CloudZonesStartupProcessor extends AdapterBase implements StartupCommandProcessor {
-    private static final Logger s_logger = Logger.getLogger(CloudZonesStartupProcessor.class);
-    @Inject
-    ClusterDao _clusterDao = null;
-    @Inject
-    ConfigurationDao _configDao = null;
-    @Inject
-    DataCenterDao _zoneDao = null;
-    @Inject
-    HostDao _hostDao = null;
-    @Inject
-    private HostDetailsDao hostDetailsDao;
-    @Inject
-    HostPodDao _podDao = null;
-    @Inject
-    DataCenterDetailsDao _zoneDetailsDao = null;
-
-    @Inject
-    AgentManager _agentManager = null;
-    @Inject
-    ConfigurationManager _configurationManager = null;
-
-    long _nodeId = -1;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _agentManager.registerForInitialConnects(this, false);
-        if (_nodeId == -1) {
-            // FIXME: We really should not do this like this. It should be done
-            // at config time and is stored as a config variable.
-            _nodeId = MacAddress.getMacAddress().toLong();
-        }
-        return true;
-    }
-
-    @Override
-    public boolean processInitialConnect(StartupCommand[] cmd) throws ConnectionException {
-        StartupCommand startup = cmd[0];
-        if (startup instanceof StartupRoutingCommand) {
-            return processHostStartup((StartupRoutingCommand)startup);
-        } else if (startup instanceof StartupStorageCommand) {
-            return processStorageStartup((StartupStorageCommand)startup);
-        }
-
-        return false;
-    }
-
-    protected boolean processHostStartup(StartupRoutingCommand startup) throws ConnectionException {
-        /*
-        boolean found = false;
-        Type type = Host.Type.Routing;
-        final Map<String, String> hostDetails = startup.getHostDetails();
-        HostVO server = _hostDao.findByGuid(startup.getGuid());
-        if (server == null) {
-            server = _hostDao.findByGuid(startup.getGuidWithoutResource());
-        }
-        if (server != null && server.getRemoved() == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found the host " + server.getId() + " by guid: "
-                        + startup.getGuid());
-            }
-            found = true;
-
-        } else {
-            server = new HostVO(startup.getGuid());
-        }
-        server.setDetails(hostDetails);
-
-        try {
-            updateComputeHost(server, startup, type);
-        } catch (AgentAuthnException e) {
-            throw new ConnectionException(true, "Failed to authorize host, invalid configuration", e);
-        }
-        if (!found) {
-            server.setHostAllocationState(Host.HostAllocationState.Enabled);
-            server = _hostDao.persist(server);
-        } else {
-            if (!_hostDao.connect(server, _nodeId)) {
-                throw new CloudRuntimeException(
-                        "Agent cannot connect because the current state is "
-                        + server.getStatus().toString());
-            }
-            s_logger.info("Old " + server.getType().toString()
-                    + " host reconnected w/ id =" + server.getId());
-        }
-        */
-        return true;
-
-    }
-
-    protected void updateComputeHost(final HostVO host, final StartupCommand startup, final Host.Type type) throws AgentAuthnException {
-
-        String zoneToken = startup.getDataCenter();
-        if (zoneToken == null) {
-            s_logger.warn("No Zone Token passed in, cannot not find zone for the agent");
-            throw new AgentAuthnException("No Zone Token passed in, cannot not find zone for agent");
-        }
-
-        DataCenterVO zone = _zoneDao.findByToken(zoneToken);
-        if (zone == null) {
-            zone = _zoneDao.findByName(zoneToken);
-            if (zone == null) {
-                try {
-                    long zoneId = Long.parseLong(zoneToken);
-                    zone = _zoneDao.findById(zoneId);
-                    if (zone == null) {
-                        throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
-                    }
-                } catch (NumberFormatException nfe) {
-                    throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
-                }
-            }
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully loaded the DataCenter from the zone token passed in ");
-        }
-
-        long zoneId = zone.getId();
-        ResourceDetail maxHostsInZone = _zoneDetailsDao.findDetail(zoneId, ZoneConfig.MaxHosts.key());
-        if (maxHostsInZone != null) {
-            long maxHosts = Long.parseLong(maxHostsInZone.getValue());
-            long currentCountOfHosts = _hostDao.countRoutingHostsByDataCenter(zoneId);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Number of hosts in Zone:" + currentCountOfHosts + ", max hosts limit: " + maxHosts);
-            }
-            if (currentCountOfHosts >= maxHosts) {
-                throw new AgentAuthnException("Number of running Routing hosts in the Zone:" + zone.getName() + " is already at the max limit:" + maxHosts +
-                    ", cannot start one more host");
-            }
-        }
-
-        HostPodVO pod = null;
-
-        if (startup.getPrivateIpAddress() == null) {
-            s_logger.warn("No private IP address passed in for the agent, cannot not find pod for agent");
-            throw new AgentAuthnException("No private IP address passed in for the agent, cannot not find pod for agent");
-        }
-
-        if (startup.getPrivateNetmask() == null) {
-            s_logger.warn("No netmask passed in for the agent, cannot not find pod for agent");
-            throw new AgentAuthnException("No netmask passed in for the agent, cannot not find pod for agent");
-        }
-
-        if (host.getPodId() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Pod is already created for this agent, looks like agent is reconnecting...");
-            }
-            pod = _podDao.findById(host.getPodId());
-            if (!checkCIDR(type, pod, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
-                pod = null;
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Subnet of Pod does not match the subnet of the agent, not using this Pod: " + host.getPodId());
-                }
-            } else {
-                updatePodNetmaskIfNeeded(pod, startup.getPrivateNetmask());
-            }
-        }
-
-        if (pod == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Trying to detect the Pod to use from the agent's ip address and netmask passed in ");
-            }
-
-            //deduce pod
-            boolean podFound = false;
-            List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
-            for (HostPodVO hostPod : podsInZone) {
-                if (checkCIDR(type, hostPod, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
-                    pod = hostPod;
-
-                    //found the default POD having the same subnet.
-                    updatePodNetmaskIfNeeded(pod, startup.getPrivateNetmask());
-                    podFound = true;
-                    break;
-                }
-            }
-
-            if (!podFound) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Creating a new Pod since no default Pod found that matches the agent's ip address and netmask passed in ");
-                }
-
-                if (startup.getGatewayIpAddress() == null) {
-                    s_logger.warn("No Gateway IP address passed in for the agent, cannot create a new pod for the agent");
-                    throw new AgentAuthnException("No Gateway IP address passed in for the agent, cannot create a new pod for the agent");
-                }
-                //auto-create a new pod, since pod matching the agent's ip is not found
-                String podName = "POD-" + (podsInZone.size() + 1);
-                try {
-                    String gateway = startup.getGatewayIpAddress();
-                    String cidr = NetUtils.getCidrFromGatewayAndNetmask(gateway, startup.getPrivateNetmask());
-                    String[] cidrPair = cidr.split("\\/");
-                    String cidrAddress = cidrPair[0];
-                    long cidrSize = Long.parseLong(cidrPair[1]);
-                    String startIp = NetUtils.getIpRangeStartIpFromCidr(cidrAddress, cidrSize);
-                    String endIp = NetUtils.getIpRangeEndIpFromCidr(cidrAddress, cidrSize);
-                    pod = _configurationManager.createPod(-1, podName, zoneId, gateway, cidr, startIp, endIp, null, true);
-                } catch (Exception e) {
-                    // no longer tolerate exception during the cluster creation phase
-                    throw new CloudRuntimeException("Unable to create new Pod " + podName + " in Zone: " + zoneId, e);
-                }
-
-            }
-        }
-        final StartupRoutingCommand scc = (StartupRoutingCommand)startup;
-
-        ClusterVO cluster = null;
-        if (host.getClusterId() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Cluster is already created for this agent, looks like agent is reconnecting...");
-            }
-            cluster = _clusterDao.findById(host.getClusterId());
-        }
-        if (cluster == null) {
-            //auto-create cluster - assume one host per cluster
-            String clusterName = "Cluster-" + startup.getPrivateIpAddress();
-            ClusterVO existingCluster = _clusterDao.findBy(clusterName, pod.getId());
-            if (existingCluster != null) {
-                cluster = existingCluster;
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Creating a new Cluster for this agent with name: " + clusterName + " in Pod: " + pod.getId() + ", in Zone:" + zoneId);
-                }
-
-                cluster = new ClusterVO(zoneId, pod.getId(), clusterName);
-                cluster.setHypervisorType(scc.getHypervisorType().toString());
-                try {
-                    cluster = _clusterDao.persist(cluster);
-                } catch (Exception e) {
-                    // no longer tolerate exception during the cluster creation phase
-                    throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + pod.getId() + " and data center " + zoneId, e);
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Detected Zone: " + zoneId + ", Pod: " + pod.getId() + ", Cluster:" + cluster.getId());
-        }
-        host.setDataCenterId(zone.getId());
-        host.setPodId(pod.getId());
-        host.setClusterId(cluster.getId());
-        host.setPrivateIpAddress(startup.getPrivateIpAddress());
-        host.setPrivateNetmask(startup.getPrivateNetmask());
-        host.setPrivateMacAddress(startup.getPrivateMacAddress());
-        host.setPublicIpAddress(startup.getPublicIpAddress());
-        host.setPublicMacAddress(startup.getPublicMacAddress());
-        host.setPublicNetmask(startup.getPublicNetmask());
-        host.setStorageIpAddress(startup.getStorageIpAddress());
-        host.setStorageMacAddress(startup.getStorageMacAddress());
-        host.setStorageNetmask(startup.getStorageNetmask());
-        host.setVersion(startup.getVersion());
-        host.setName(startup.getName());
-        host.setType(type);
-        host.setStorageUrl(startup.getIqn());
-        host.setLastPinged(System.currentTimeMillis() >> 10);
-        host.setCaps(scc.getCapabilities());
-        host.setCpus(scc.getCpus());
-        host.setTotalMemory(scc.getMemory());
-        host.setSpeed(scc.getSpeed());
-        HypervisorType hyType = scc.getHypervisorType();
-        host.setHypervisorType(hyType);
-        host.setHypervisorVersion(scc.getHypervisorVersion());
-
-        updateHostDetails(host, scc);
-    }
-
-    private void updateHostDetails(HostVO host, StartupRoutingCommand startupRoutingCmd) {
-        final String name = "supportsResign";
-        final String value = String.valueOf(startupRoutingCmd.getSupportsClonedVolumes());
-
-        DetailVO hostDetail = hostDetailsDao.findDetail(host.getId(), name);
-
-        if (hostDetail != null) {
-            hostDetail.setValue(value);
-
-            hostDetailsDao.update(hostDetail.getId(), hostDetail);
-        }
-        else {
-            hostDetail = new DetailVO(host.getId(), name, value);
-
-            hostDetailsDao.persist(hostDetail);
-        }
-    }
-
-    private boolean checkCIDR(Host.Type type, HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) {
-        if (serverPrivateIP == null) {
-            return true;
-        }
-        // Get the CIDR address and CIDR size
-        String cidrAddress = pod.getCidrAddress();
-        long cidrSize = pod.getCidrSize();
-
-        // If the server's private IP address is not in the same subnet as the
-        // pod's CIDR, return false
-        String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
-        String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
-        if (!cidrSubnet.equals(serverSubnet)) {
-            return false;
-        }
-        return true;
-    }
-
-    private void updatePodNetmaskIfNeeded(HostPodVO pod, String agentNetmask) {
-        // If the server's private netmask is less inclusive than the pod's CIDR
-        // netmask, update cidrSize of the default POD
-        //(reason: we are maintaining pods only for internal accounting.)
-        long cidrSize = pod.getCidrSize();
-        String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
-        long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
-        long serverNetmaskNumeric = NetUtils.ip2Long(agentNetmask);//
-        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
-            //update pod's cidrsize
-            int newCidrSize = new Long(NetUtils.getCidrSize(agentNetmask)).intValue();
-            pod.setCidrSize(newCidrSize);
-            _podDao.update(pod.getId(), pod);
-        }
-    }
-
-    protected boolean processStorageStartup(StartupStorageCommand startup) throws ConnectionException {
-        /*
-        if (startup.getResourceType() != Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
-            return false;
-        }
-        boolean found = false;
-        Type type = Host.Type.LocalSecondaryStorage;
-        final Map<String, String> hostDetails = startup.getHostDetails();
-        HostVO server = _hostDao.findByGuid(startup.getGuid());
-        if (server == null) {
-            server = _hostDao.findByGuid(startup.getGuidWithoutResource());
-        }
-        if (server != null && server.getRemoved() == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found the host " + server.getId() + " by guid: "
-                        + startup.getGuid());
-            }
-            found = true;
-
-        } else {
-            server = new HostVO(startup.getGuid());
-        }
-        server.setDetails(hostDetails);
-
-        try {
-            updateSecondaryHost(server, startup, type);
-        } catch (AgentAuthnException e) {
-            throw new ConnectionException(true, "Failed to authorize host, invalid configuration", e);
-        }
-        if (!found) {
-            server.setHostAllocationState(Host.HostAllocationState.Enabled);
-            server = _hostDao.persist(server);
-        } else {
-            if (!_hostDao.connect(server, _nodeId)) {
-                throw new CloudRuntimeException(
-                        "Agent cannot connect because the current state is "
-                        + server.getStatus().toString());
-            }
-            s_logger.info("Old " + server.getType().toString()
-                    + " host reconnected w/ id =" + server.getId());
-        }
-        */
-        return true;
-
-    }
-
-    protected void updateSecondaryHost(final HostVO host, final StartupStorageCommand startup, final Host.Type type) throws AgentAuthnException {
-
-        String zoneToken = startup.getDataCenter();
-        if (zoneToken == null) {
-            s_logger.warn("No Zone Token passed in, cannot not find zone for the agent");
-            throw new AgentAuthnException("No Zone Token passed in, cannot not find zone for agent");
-        }
-
-        DataCenterVO zone = _zoneDao.findByToken(zoneToken);
-        if (zone == null) {
-            zone = _zoneDao.findByName(zoneToken);
-            if (zone == null) {
-                try {
-                    long zoneId = Long.parseLong(zoneToken);
-                    zone = _zoneDao.findById(zoneId);
-                    if (zone == null) {
-                        throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
-                    }
-                } catch (NumberFormatException nfe) {
-                    throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
-                }
-            }
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully loaded the DataCenter from the zone token passed in ");
-        }
-
-        HostPodVO pod = findPod(startup, zone.getId(), Host.Type.Routing); //yes, routing
-        Long podId = null;
-        if (pod != null) {
-            s_logger.debug("Found pod " + pod.getName() + " for the secondary storage host " + startup.getName());
-            podId = pod.getId();
-        }
-        host.setDataCenterId(zone.getId());
-        host.setPodId(podId);
-        host.setClusterId(null);
-        host.setPrivateIpAddress(startup.getPrivateIpAddress());
-        host.setPrivateNetmask(startup.getPrivateNetmask());
-        host.setPrivateMacAddress(startup.getPrivateMacAddress());
-        host.setPublicIpAddress(startup.getPublicIpAddress());
-        host.setPublicMacAddress(startup.getPublicMacAddress());
-        host.setPublicNetmask(startup.getPublicNetmask());
-        host.setStorageIpAddress(startup.getStorageIpAddress());
-        host.setStorageMacAddress(startup.getStorageMacAddress());
-        host.setStorageNetmask(startup.getStorageNetmask());
-        host.setVersion(startup.getVersion());
-        host.setName(startup.getName());
-        host.setType(type);
-        host.setStorageUrl(startup.getIqn());
-        host.setLastPinged(System.currentTimeMillis() >> 10);
-        host.setCaps(null);
-        host.setCpus(null);
-        host.setTotalMemory(0);
-        host.setSpeed(null);
-        host.setParent(startup.getParent());
-        host.setTotalSize(startup.getTotalSize());
-        host.setHypervisorType(HypervisorType.None);
-        if (startup.getNfsShare() != null) {
-            host.setStorageUrl(startup.getNfsShare());
-        }
-
-    }
-
-    private HostPodVO findPod(StartupCommand startup, long zoneId, Host.Type type) {
-        HostPodVO pod = null;
-        List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
-        for (HostPodVO hostPod : podsInZone) {
-            if (checkCIDR(type, hostPod, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
-                pod = hostPod;
-
-                //found the default POD having the same subnet.
-                updatePodNetmaskIfNeeded(pod, startup.getPrivateNetmask());
-
-                break;
-            }
-        }
-        return pod;
-
-    }
-
-}
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
deleted file mode 100644
index 9f67d34..0000000
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ /dev/null
@@ -1,227 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor;
-
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.gpu.GPU;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.service.ServiceOfferingDetailsVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
-    public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
-
-    @Inject
-    private NicDao _nicDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private NetworkOfferingDetailsDao networkOfferingDetailsDao;
-    @Inject
-    private VMInstanceDao _virtualMachineDao;
-    @Inject
-    private UserVmDetailsDao _userVmDetailsDao;
-    @Inject
-    private NicSecondaryIpDao _nicSecIpDao;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-
-    @Override
-    public NicTO toNicTO(NicProfile profile) {
-        NicTO to = new NicTO();
-        to.setDeviceId(profile.getDeviceId());
-        to.setBroadcastType(profile.getBroadcastType());
-        to.setType(profile.getTrafficType());
-        to.setIp(profile.getIPv4Address());
-        to.setNetmask(profile.getIPv4Netmask());
-        to.setMac(profile.getMacAddress());
-        to.setDns1(profile.getIPv4Dns1());
-        to.setDns2(profile.getIPv4Dns2());
-        to.setGateway(profile.getIPv4Gateway());
-        to.setDefaultNic(profile.isDefaultNic());
-        to.setBroadcastUri(profile.getBroadCastUri());
-        to.setIsolationuri(profile.getIsolationUri());
-        to.setNetworkRateMbps(profile.getNetworkRate());
-        to.setName(profile.getName());
-        to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
-        to.setIp6Address(profile.getIPv6Address());
-        to.setIp6Cidr(profile.getIPv6Cidr());
-
-        NetworkVO network = _networkDao.findById(profile.getNetworkId());
-        to.setNetworkUuid(network.getUuid());
-
-        // Workaround to make sure the TO has the UUID we need for Nicira integration
-        NicVO nicVO = _nicDao.findById(profile.getId());
-        if (nicVO != null) {
-            to.setUuid(nicVO.getUuid());
-            // disable pxe on system vm nics to speed up boot time
-            if (nicVO.getVmType() != VirtualMachine.Type.User) {
-                to.setPxeDisable(true);
-            }
-            List<String> secIps = null;
-            if (nicVO.getSecondaryIp()) {
-                secIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nicVO.getId());
-            }
-            to.setNicSecIps(secIps);
-        } else {
-            s_logger.warn("Unabled to load NicVO for NicProfile " + profile.getId());
-            //Workaround for dynamically created nics
-            //FixMe: uuid and secondary IPs can be made part of nic profile
-            to.setUuid(UUID.randomUUID().toString());
-        }
-
-        //check whether the this nic has secondary ip addresses set
-        //set nic secondary ip address in NicTO which are used for security group
-        // configuration. Use full when vm stop/start
-        return to;
-    }
-
-    protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
-        ServiceOffering offering = _serviceOfferingDao.findById(vmProfile.getId(), vmProfile.getServiceOfferingId());
-        VirtualMachine vm = vmProfile.getVirtualMachine();
-        Long minMemory = (long)(offering.getRamSize() / vmProfile.getMemoryOvercommitRatio());
-        int minspeed = (int)(offering.getSpeed() / vmProfile.getCpuOvercommitRatio());
-        int maxspeed = (offering.getSpeed());
-        VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), minspeed, maxspeed, minMemory * 1024l * 1024l,
-                offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword());
-        to.setBootArgs(vmProfile.getBootArgs());
-
-        List<NicProfile> nicProfiles = vmProfile.getNics();
-        NicTO[] nics = new NicTO[nicProfiles.size()];
-        int i = 0;
-        for (NicProfile nicProfile : nicProfiles) {
-            if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
-                nicProfile.setBroadcastType(BroadcastDomainType.Native);
-            }
-            NicTO nicTo = toNicTO(nicProfile);
-            final NetworkVO network = _networkDao.findByUuid(nicTo.getNetworkUuid());
-            if (network != null) {
-                final Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
-                if (details != null) {
-                    details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
-                    details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
-                    details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
-                }
-                nicTo.setDetails(details);
-            }
-            nics[i++] = nicTo;
-        }
-
-        to.setNics(nics);
-        to.setDisks(vmProfile.getDisks().toArray(new DiskTO[vmProfile.getDisks().size()]));
-
-        if (vmProfile.getTemplate().getBits() == 32) {
-            to.setArch("i686");
-        } else {
-            to.setArch("x86_64");
-        }
-
-        Map<String, String> detailsInVm = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
-        if (detailsInVm != null) {
-            to.setDetails(detailsInVm);
-        }
-
-        // Set GPU details
-        ServiceOfferingDetailsVO offeringDetail = null;
-        if ((offeringDetail = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
-            ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
-            to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), groupName.getValue(), offeringDetail.getValue()));
-        }
-
-        // Workaround to make sure the TO has the UUID we need for Niciri integration
-        VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId());
-        // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global)
-        Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId());
-        to.setEnableDynamicallyScaleVm(isDynamicallyScalable);
-        to.setUuid(vmInstance.getUuid());
-
-        to.setVmData(vmProfile.getVmData());
-        to.setConfigDriveLabel(vmProfile.getConfigDriveLabel());
-        to.setConfigDriveIsoRootFolder(vmProfile.getConfigDriveIsoRootFolder());
-        to.setConfigDriveIsoFile(vmProfile.getConfigDriveIsoFile());
-
-        return to;
-    }
-
-    @Override
-    /**
-     * The basic implementation assumes that the initial "host" defined to execute the command is the host that is in fact going to execute it.
-     * However, subclasses can extend this behavior, changing the host that is going to execute the command in runtime.
-     * The first element of the 'Pair' indicates if the hostId has been changed; this means, if you change the hostId, but you do not inform this action in the return 'Pair' object, we will use the original "hostId".
-     *
-     * Side note: it seems that the 'hostId' received here is normally the ID of the SSVM that has an entry at the host table. Therefore, this methods gives the opportunity to change from the SSVM to a real host to execute a command.
-     */
-    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
-        return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
-    }
-
-    @Override
-    public List<Command> finalizeExpunge(VirtualMachine vm) {
-        return null;
-    }
-
-    @Override
-    public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
-        return null;
-    }
-
-    @Override
-    public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
-        return null;
-    }
-
-    @Override
-    public Map<String, String> getClusterSettings(long vmId) {
-        return null;
-    }
-
-}
diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
deleted file mode 100644
index f0d8622..0000000
--- a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
+++ /dev/null
@@ -1,843 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.response.ExternalFirewallResponse;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupExternalFirewallCommand;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.to.FirewallRuleTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.ExternalFirewallDeviceDao;
-import com.cloud.network.dao.ExternalFirewallDeviceVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
-import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkExternalFirewallDao;
-import com.cloud.network.dao.NetworkExternalFirewallVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.net.UrlUtil;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-
-public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase implements ExternalFirewallDeviceManager, ResourceStateAdapter {
-
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcProviderDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    UserStatisticsDao _userStatsDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    LoadBalancerDao _loadBalancerDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingRulesDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ExternalFirewallDeviceDao _externalFirewallDeviceDao;
-    @Inject
-    NetworkExternalFirewallDao _networkExternalFirewallDao;
-    @Inject
-    VpnUserDao _vpnUsersDao;
-    @Inject
-    HostDetailsDao _hostDetailDao;
-    @Inject
-    FirewallRulesDao _fwRulesDao;
-
-    private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalFirewallDeviceManagerImpl.class);
-    private long _defaultFwCapacity;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        _defaultFwCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalFirewallCapacity.key()), 50);
-        return true;
-    }
-
-    @Override
-    @DB
-    public ExternalFirewallDeviceVO addExternalFirewall(long physicalNetworkId, String url, String username, String password, final String deviceName,
-        ServerResource resource) {
-        String guid;
-        PhysicalNetworkVO pNetwork = null;
-        NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName);
-        long zoneId;
-
-        if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) {
-            throw new InvalidParameterValueException("Atleast one of the required parameters (url, username, password,"
-                + " server resource, zone id/physical network id) is not specified or a valid parameter.");
-        }
-
-        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
-        }
-        zoneId = pNetwork.getDataCenterId();
-
-        final PhysicalNetworkServiceProviderVO ntwkSvcProvider =
-            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
-        if (ntwkSvcProvider == null) {
-            throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: " +
-                physicalNetworkId + "to add this device");
-        } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
-            throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() +
-                " is not added or in shutdown state in the physical network: " + physicalNetworkId + "to add this device");
-        }
-
-        URI uri;
-        try {
-            uri = new URI(url);
-        } catch (Exception e) {
-            s_logger.debug(e);
-            throw new InvalidParameterValueException(e.getMessage());
-        }
-
-        String ipAddress = uri.getHost();
-        Map hostDetails = new HashMap<String, String>();
-        guid = getExternalNetworkResourceGuid(pNetwork.getId(), deviceName, ipAddress);
-        hostDetails.put("name", guid);
-        hostDetails.put("guid", guid);
-        hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId()));
-        hostDetails.put("ip", ipAddress);
-        hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId()));
-        hostDetails.put("username", username);
-        hostDetails.put("password", password);
-        hostDetails.put("deviceName", deviceName);
-        final Map<String, String> configParams = new HashMap<String, String>();
-        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
-        hostDetails.putAll(configParams);
-
-        // let the server resource to do parameters validation
-        try {
-            resource.configure(guid, hostDetails);
-        } catch (ConfigurationException e) {
-            throw new CloudRuntimeException(e.getMessage());
-        }
-
-        final Host externalFirewall = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, hostDetails);
-        if (externalFirewall != null) {
-            final PhysicalNetworkVO pNetworkFinal = pNetwork;
-            return Transaction.execute(new TransactionCallback<ExternalFirewallDeviceVO>() {
-                @Override
-                public ExternalFirewallDeviceVO doInTransaction(TransactionStatus status) {
-                    boolean dedicatedUse =
-                        (configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED))
-                            : false;
-                    long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.FIREWALL_DEVICE_CAPACITY), 0);
-                    if (capacity == 0) {
-                        capacity = _defaultFwCapacity;
-                    }
-
-                    ExternalFirewallDeviceVO fwDevice =
-                        new ExternalFirewallDeviceVO(externalFirewall.getId(), pNetworkFinal.getId(), ntwkSvcProvider.getProviderName(), deviceName, capacity,
-                            dedicatedUse);
-
-                    _externalFirewallDeviceDao.persist(fwDevice);
-
-                    DetailVO hostDetail = new DetailVO(externalFirewall.getId(), ApiConstants.FIREWALL_DEVICE_ID, String.valueOf(fwDevice.getId()));
-                    _hostDetailDao.persist(hostDetail);
-
-                    return fwDevice;
-                }
-            });
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public boolean deleteExternalFirewall(Long hostId) {
-        HostVO externalFirewall = _hostDao.findById(hostId);
-        if (externalFirewall == null) {
-            throw new InvalidParameterValueException("Could not find an external firewall with ID: " + hostId);
-        }
-
-        DetailVO fwHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.FIREWALL_DEVICE_ID);
-        long fwDeviceId = Long.parseLong(fwHostDetails.getValue());
-
-        // check if any networks are using this balancer device
-        List<NetworkExternalFirewallVO> networks = _networkExternalFirewallDao.listByFirewallDeviceId(fwDeviceId);
-        if ((networks != null) && !networks.isEmpty()) {
-            throw new CloudRuntimeException("Delete can not be done as there are networks using the firewall device ");
-        }
-
-        try {
-            // put the host in maintenance state in order for it to be deleted
-            externalFirewall.setResourceState(ResourceState.Maintenance);
-            _hostDao.update(hostId, externalFirewall);
-            _resourceMgr.deleteHost(hostId, false, false);
-
-            // delete the external load balancer entry
-            _externalFirewallDeviceDao.remove(fwDeviceId);
-            return true;
-        } catch (Exception e) {
-            s_logger.debug("Failed to delete external firewall device due to " + e.getMessage());
-            return false;
-        }
-    }
-
-    @Override
-    public List<Host> listExternalFirewalls(long physicalNetworkId, String deviceName) {
-        List<Host> firewallHosts = new ArrayList<Host>();
-        NetworkDevice fwNetworkDevice = NetworkDevice.getNetworkDevice(deviceName);
-        PhysicalNetworkVO pNetwork = null;
-
-        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
-        }
-
-        if ((pNetwork == null) || (fwNetworkDevice == null)) {
-            throw new InvalidParameterValueException("Atleast one of ther required parameter physical networkId, device name is missing or invalid.");
-        }
-
-        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
-            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), fwNetworkDevice.getNetworkServiceProvder());
-        if (ntwkSvcProvider == null) {
-            return null;
-        }
-
-        List<ExternalFirewallDeviceVO> fwDevices = _externalFirewallDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, ntwkSvcProvider.getProviderName());
-        for (ExternalFirewallDeviceVO fwDevice : fwDevices) {
-            firewallHosts.add(_hostDao.findById(fwDevice.getHostId()));
-        }
-        return firewallHosts;
-    }
-
-    @Override
-    public ExternalFirewallDeviceVO getExternalFirewallForNetwork(Network network) {
-        NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
-        if (fwDeviceForNetwork != null) {
-            long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId();
-            ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId);
-            assert (fwDevice != null);
-            return fwDevice;
-        }
-        return null;
-    }
-
-    public void setExternalFirewallForNetwork(Network network, long externalFWDeviceID) {
-        NetworkExternalFirewallVO fwDeviceForNetwork = new NetworkExternalFirewallVO(network.getId(), externalFWDeviceID);
-        _networkExternalFirewallDao.persist(fwDeviceForNetwork);
-    }
-
-    @Override
-    public ExternalFirewallDeviceVO findSuitableFirewallForNetwork(Network network) throws InsufficientCapacityException {
-        long physicalNetworkId = network.getPhysicalNetworkId();
-        List<ExternalFirewallDeviceVO> fwDevices = _externalFirewallDeviceDao.listByPhysicalNetwork(physicalNetworkId);
-
-        // loop through the firewall device in the physical network and pick the first-fit
-        for (ExternalFirewallDeviceVO fwDevice : fwDevices) {
-            // max number of guest networks that can be mapped to this device
-            long fullCapacity = fwDevice.getCapacity();
-            if (fullCapacity == 0) {
-                fullCapacity = _defaultFwCapacity; // if capacity not configured then use the default
-            }
-
-            // get the list of guest networks that are mapped to this load balancer
-            List<NetworkExternalFirewallVO> mappedNetworks = _networkExternalFirewallDao.listByFirewallDeviceId(fwDevice.getId());
-
-            long usedCapacity = (mappedNetworks == null) ? 0 : mappedNetworks.size();
-            if ((fullCapacity - usedCapacity) > 0) {
-                return fwDevice;
-            }
-        }
-        throw new InsufficientNetworkCapacityException("Unable to find a firewall provider with sufficient capcity " + " to implement the network", DataCenter.class,
-            network.getDataCenterId());
-    }
-
-    @DB
-    protected boolean freeFirewallForNetwork(Network network) {
-        GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
-        try {
-            if (deviceMapLock.lock(120)) {
-                try {
-                    NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
-                    if (fwDeviceForNetwork != null) {
-                        _networkExternalFirewallDao.remove(fwDeviceForNetwork.getId());
-                    }
-                } catch (Exception exception) {
-                    s_logger.error("Failed to release firewall device for the network" + network.getId() + " due to " + exception.getMessage());
-                    return false;
-                } finally {
-                    deviceMapLock.unlock();
-                }
-            }
-        } finally {
-            deviceMapLock.releaseRef();
-        }
-        return true;
-    }
-
-    public String getExternalNetworkResourceGuid(long physicalNetworkId, String deviceName, String ip) {
-        return physicalNetworkId + "-" + deviceName + "-" + ip;
-    }
-
-    public ExternalFirewallResponse createExternalFirewallResponse(Host externalFirewall) {
-        Map<String, String> fwDetails = _hostDetailDao.findDetails(externalFirewall.getId());
-        ExternalFirewallResponse response = new ExternalFirewallResponse();
-        response.setId(externalFirewall.getUuid());
-        response.setIpAddress(externalFirewall.getPrivateIpAddress());
-        response.setUsername(fwDetails.get("username"));
-        response.setPublicInterface(fwDetails.get("publicInterface"));
-        response.setUsageInterface(fwDetails.get("usageInterface"));
-        response.setPrivateInterface(fwDetails.get("privateInterface"));
-        response.setPublicZone(fwDetails.get("publicZone"));
-        response.setPrivateZone(fwDetails.get("privateZone"));
-        response.setNumRetries(fwDetails.get("numRetries"));
-        response.setTimeout(fwDetails.get("timeout"));
-        return response;
-    }
-
-    @Override
-    public boolean manageGuestNetworkWithExternalFirewall(boolean add, Network network) throws ResourceUnavailableException, InsufficientCapacityException {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            s_logger.trace("External firewall can only be used for add/remove guest networks.");
-            return false;
-        }
-
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        HostVO externalFirewall = null;
-
-        if (add) {
-            GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
-            try {
-                if (deviceMapLock.lock(120)) {
-                    try {
-                        ExternalFirewallDeviceVO device = findSuitableFirewallForNetwork(network);
-                        long externalFirewallId = device.getId();
-
-                        NetworkExternalFirewallVO networkFW = new NetworkExternalFirewallVO(network.getId(), externalFirewallId);
-                        _networkExternalFirewallDao.persist(networkFW);
-
-                        externalFirewall = _hostDao.findById(device.getHostId());
-                    } finally {
-                        deviceMapLock.unlock();
-                    }
-                }
-            } finally {
-                deviceMapLock.releaseRef();
-            }
-        } else {
-            ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-            if (fwDeviceVO == null) {
-                s_logger.warn("Network shutdown requested on external firewall element, which did not implement the network."
-                    + " Either network implement failed half way through or already network shutdown is completed.");
-                return true;
-            }
-            externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-        }
-
-        Account account = _accountDao.findByIdIncludingRemoved(network.getAccountId());
-
-        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        boolean sharedSourceNat = offering.getSharedSourceNat();
-
-        IPAddressVO sourceNatIp = null;
-        if (!sharedSourceNat) {
-            // Get the source NAT IP address for this network
-            List<? extends IpAddress> sourceNatIps = _networkModel.listPublicIpsAssignedToAccount(network.getAccountId(), zoneId, true);
-
-            for (IpAddress ipAddress : sourceNatIps) {
-                if (ipAddress.getAssociatedWithNetworkId().longValue() == network.getId()) {
-                    sourceNatIp = _ipAddressDao.findById(ipAddress.getId());
-                    break;
-                }
-            }
-            if (sourceNatIp == null) {
-                String errorMsg = "External firewall was unable to find the source NAT IP address for network " + network.getName();
-                s_logger.error(errorMsg);
-                return true;
-            }
-        }
-
-        // Send a command to the external firewall to implement or shutdown the guest network
-        long guestVlanTag = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri()));
-        String guestVlanGateway = network.getGateway();
-        String guestVlanCidr = network.getCidr();
-        String sourceNatIpAddress = null;
-        String publicVlanTag = null;
-
-        if (sourceNatIp != null) {
-            sourceNatIpAddress = sourceNatIp.getAddress().addr();
-            VlanVO publicVlan = _vlanDao.findById(sourceNatIp.getVlanId());
-            publicVlanTag = publicVlan.getVlanTag();
-        }
-
-        // Get network rate
-        Integer networkRate = _networkModel.getNetworkRate(network.getId(), null);
-
-        IpAddressTO ip = new IpAddressTO(account.getAccountId(), sourceNatIpAddress, add, false, !sharedSourceNat, publicVlanTag, null, null, null, networkRate, false);
-        IpAddressTO[] ips = new IpAddressTO[1];
-        ips[0] = ip;
-        IpAssocCommand cmd = new IpAssocCommand(ips);
-        cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, guestVlanGateway);
-        cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, guestVlanCidr);
-        cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
-        Answer answer = _agentMgr.easySend(externalFirewall.getId(), cmd);
-
-        List<String> reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(network.getId());
-
-        if (answer == null || !answer.getResult()) {
-            String action = add ? "implement" : "shutdown";
-            String answerDetails = (answer != null) ? answer.getDetails() : "answer was null";
-            String msg =
-                "External firewall was unable to " + action + " the guest network on the external firewall in zone " + zone.getName() + " due to " + answerDetails;
-            s_logger.error(msg);
-            if (!add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
-                // If we failed the implementation as well, then just return, no complain
-                s_logger.error("Skip the shutdown of guest network on SRX because it seems we didn't implement it as well");
-                return true;
-            }
-            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
-        }
-
-        if (add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
-            // Insert a new NIC for this guest network to reserve the gateway address
-            _networkMgr.savePlaceholderNic(network, network.getGateway(), null, null);
-        }
-
-        // Delete any mappings used for inline external load balancers in this network
-        List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(network.getId());
-        for (NicVO nic : nicsInNetwork) {
-            InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByNicId(nic.getId());
-
-            if (mapping != null) {
-                _nicDao.expunge(mapping.getNicId());
-                _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
-            }
-        }
-
-        // on network shutdown, delete placeHolder nics used for the firewall device
-        if (!add) {
-            List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
-            for (NicVO nic : nics) {
-                if (nic.getVmType() == null && nic.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && nic.getIPv4Address().equals(network.getGateway())) {
-                    s_logger.debug("Removing placeholder nic " + nic + " for the network " + network);
-                    _nicDao.remove(nic.getId());
-                }
-            }
-            freeFirewallForNetwork(network);
-        }
-
-        String action = add ? "implemented" : "shut down";
-        s_logger.debug("External firewall has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() +
-            ") with VLAN tag " + guestVlanTag);
-
-        return true;
-    }
-
-    @Override
-    public boolean applyFirewallRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
-        // Find the external firewall in this zone
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-        // During destroy, device reference may already been clean up, then we just return true
-        if (fwDeviceVO == null) {
-            return true;
-        }
-        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-
-        assert (externalFirewall != null);
-
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
-                "; this network is not implemented. Skipping backend commands.");
-            return true;
-        }
-
-        List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
-        NetworkVO networkVO = _networkDao.findById(network.getId());
-        NetworkOfferingVO offering = _networkOfferingDao.findById(networkVO.getNetworkOfferingId());
-        Boolean defaultEgressPolicy = offering.getEgressDefaultPolicy();
-
-        for (FirewallRule rule : rules) {
-            if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
-                _fwRulesDao.loadSourceCidrs((FirewallRuleVO)rule);
-            }
-            FirewallRuleTO ruleTO;
-            if (rule.getPurpose() == Purpose.Firewall && rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
-                String guestVlanTag = BroadcastDomainType.getValue(network.getBroadcastUri());
-                String guestCidr = network.getCidr();
-                ruleTO = new FirewallRuleTO(rule, guestVlanTag, rule.getTrafficType(), guestCidr, defaultEgressPolicy, rule.getType());
-            } else {
-                IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
-
-                ruleTO = new FirewallRuleTO(rule, vlan.getVlanTag(), sourceIp.getAddress().addr());
-            }
-            rulesTO.add(ruleTO);
-        }
-
-        //Firewall rules configured for staticNAT/PF
-        sendFirewallRules(rulesTO, zone, externalFirewall.getId());
-
-        return true;
-    }
-
-    public boolean applyStaticNatRules(Network network, List<? extends StaticNat> rules) throws ResourceUnavailableException {
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-
-        assert (externalFirewall != null);
-
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
-                "; this network is not implemented. Skipping backend commands.");
-            return true;
-        }
-
-        List<StaticNatRuleTO> staticNatRules = new ArrayList<StaticNatRuleTO>();
-
-        for (StaticNat rule : rules) {
-            IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-            Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
-
-            StaticNatRuleTO ruleTO =
-                new StaticNatRuleTO(0, vlan.getVlanTag(), sourceIp.getAddress().addr(), -1, -1, rule.getDestIpAddress(), -1, -1, "any", rule.isForRevoke(), false);
-            staticNatRules.add(ruleTO);
-        }
-
-        sendStaticNatRules(staticNatRules, zone, externalFirewall.getId());
-
-        return true;
-    }
-
-    protected void sendFirewallRules(List<FirewallRuleTO> firewallRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
-        if (!firewallRules.isEmpty()) {
-            SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(firewallRules);
-            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
-            if (answer == null || !answer.getResult()) {
-                String details = (answer != null) ? answer.getDetails() : "details unavailable";
-                String msg = "External firewall was unable to apply static nat rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
-                s_logger.error(msg);
-                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
-            }
-        }
-    }
-
-    protected void sendStaticNatRules(List<StaticNatRuleTO> staticNatRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
-        if (!staticNatRules.isEmpty()) {
-            SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null);
-            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
-            if (answer == null || !answer.getResult()) {
-                String details = (answer != null) ? answer.getDetails() : "details unavailable";
-                String msg = "External firewall was unable to apply static nat rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
-                s_logger.error(msg);
-                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
-            }
-        }
-    }
-
-    protected void sendPortForwardingRules(List<PortForwardingRuleTO> portForwardingRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
-        if (!portForwardingRules.isEmpty()) {
-            SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(portForwardingRules);
-            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
-            if (answer == null || !answer.getResult()) {
-                String details = (answer != null) ? answer.getDetails() : "details unavailable";
-                String msg = "External firewall was unable to apply port forwarding rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
-                s_logger.error(msg);
-                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
-            }
-        }
-    }
-
-    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddresses) throws ResourceUnavailableException {
-        return true;
-    }
-
-    public boolean manageRemoteAccessVpn(boolean create, Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException {
-        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-
-        if (externalFirewall == null) {
-            return false;
-        }
-
-        // Create/delete VPN
-        IpAddress ip = _networkModel.getIp(vpn.getServerAddressId());
-
-        // Mask the IP range with the network's VLAN tag
-        String[] ipRange = vpn.getIpRange().split("-");
-        DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
-        int vlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
-        int offset = getVlanOffset(network.getPhysicalNetworkId(), vlanTag);
-        int cidrSize = getGloballyConfiguredCidrSize();
-
-        for (int i = 0; i < 2; i++) {
-            ipRange[i] = NetUtils.long2Ip((NetUtils.ip2Long(ipRange[i]) & 0xff000000) | (offset << (32 - cidrSize)));
-        }
-
-        String maskedIpRange = ipRange[0] + "-" + ipRange[1];
-
-        RemoteAccessVpnCfgCommand createVpnCmd =
-            new RemoteAccessVpnCfgCommand(create, ip.getAddress().addr(), vpn.getLocalIp(), maskedIpRange, vpn.getIpsecPresharedKey(), false);
-        createVpnCmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(network.getAccountId()));
-        createVpnCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
-        Answer answer = _agentMgr.easySend(externalFirewall.getId(), createVpnCmd);
-        if (answer == null || !answer.getResult()) {
-            String details = (answer != null) ? answer.getDetails() : "details unavailable";
-            String msg = "External firewall was unable to create a remote access VPN in zone " + zone.getName() + " due to: " + details + ".";
-            s_logger.error(msg);
-            throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
-        }
-
-        // Add/delete users
-        List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
-        return manageRemoteAccessVpnUsers(network, vpn, vpnUsers);
-    }
-
-    public boolean manageRemoteAccessVpnUsers(Network network, RemoteAccessVpn vpn, List<? extends VpnUser> vpnUsers) throws ResourceUnavailableException {
-        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-
-        if (externalFirewall == null) {
-            return false;
-        }
-
-        List<VpnUser> addUsers = new ArrayList<VpnUser>();
-        List<VpnUser> removeUsers = new ArrayList<VpnUser>();
-        for (VpnUser user : vpnUsers) {
-            if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) {
-                addUsers.add(user);
-            } else if (user.getState() == VpnUser.State.Revoke) {
-                removeUsers.add(user);
-            }
-        }
-
-        VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers);
-        addUsersCmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(network.getAccountId()));
-        addUsersCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
-
-        Answer answer = _agentMgr.easySend(externalFirewall.getId(), addUsersCmd);
-        if (answer == null || !answer.getResult()) {
-            String details = (answer != null) ? answer.getDetails() : "details unavailable";
-            DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
-            String msg = "External firewall was unable to add remote access users in zone " + zone.getName() + " due to: " + details + ".";
-            s_logger.error(msg);
-            throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
-        }
-
-        return true;
-    }
-
-    public int getVlanOffset(long physicalNetworkId, int vlanTag) {
-        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
-        }
-
-        if (pNetwork.getVnet() == null) {
-            throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
-        }
-        Integer lowestVlanTag = null;
-        List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
-        //finding the vlanrange in which the vlanTag lies.
-        for (Pair<Integer, Integer> vnet : vnetList) {
-            if (vlanTag >= vnet.first() && vlanTag <= vnet.second()) {
-                lowestVlanTag = vnet.first();
-            }
-        }
-        if (lowestVlanTag == null) {
-            throw new InvalidParameterValueException("The vlan tag does not belong to any of the existing vlan ranges");
-        }
-        return vlanTag - lowestVlanTag;
-    }
-
-    public int getGloballyConfiguredCidrSize() {
-        try {
-            String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
-            return 8 + Integer.parseInt(globalVlanBits);
-        } catch (Exception e) {
-            throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
-        }
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        if (!(startup[0] instanceof StartupExternalFirewallCommand)) {
-            return null;
-        }
-        host.setType(Host.Type.ExternalFirewall);
-        return host;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (host.getType() != com.cloud.host.Host.Type.ExternalFirewall) {
-            return null;
-        }
-        return new DeleteHostAnswer(true);
-    }
-
-    @Override
-    public boolean applyPortForwardingRules(Network network, List<? extends PortForwardingRule> rules) throws ResourceUnavailableException {
-        // Find the external firewall in this zone
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
-        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
-
-        assert (externalFirewall != null);
-
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
-                "; this network is not implemented. Skipping backend commands.");
-            return true;
-        }
-
-        List<PortForwardingRuleTO> pfRules = new ArrayList<PortForwardingRuleTO>();
-
-        for (PortForwardingRule rule : rules) {
-            IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-            Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
-
-            PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, vlan.getVlanTag(), sourceIp.getAddress().addr());
-            pfRules.add(ruleTO);
-        }
-
-        sendPortForwardingRules(pfRules, zone, externalFirewall.getId());
-        return true;
-    }
-}
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
deleted file mode 100644
index 166fab7..0000000
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ /dev/null
@@ -1,1311 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.response.ExternalLoadBalancerResponse;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
-import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand;
-import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
-import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
-import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.ExternalFirewallDeviceDao;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
-import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
-import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkExternalFirewallDao;
-import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
-import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.element.IpDeployer;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRule.LbDestination;
-import com.cloud.network.resource.CreateLoadBalancerApplianceAnswer;
-import com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StaticNatImpl;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.net.UrlUtil;
-import com.cloud.vm.Nic;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter {
-
-    @Inject
-    NetworkExternalLoadBalancerDao _networkExternalLBDao;
-    @Inject
-    ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    UserStatisticsDao _userStatsDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    LoadBalancerDao _loadBalancerDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingRulesDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    HostDetailsDao _hostDetailDao;
-    @Inject
-    NetworkExternalLoadBalancerDao _networkLBDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcProviderDao;
-    @Inject
-    NetworkExternalFirewallDao _networkExternalFirewallDao;
-    @Inject
-    ExternalFirewallDeviceDao _externalFirewallDeviceDao;
-    @Inject
-    protected HostPodDao _podDao = null;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    protected
-    VirtualMachineManager _itMgr;
-    @Inject
-    VMInstanceDao _vmDao;
-    @Inject
-    VMTemplateDao _templateDao;
-    @Inject
-    ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _physicalProviderDao;
-    @Inject
-    VirtualRouterProviderDao _vrProviderDao;
-
-    private long _defaultLbCapacity;
-    private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class);
-
-    @Override
-    @DB
-    public ExternalLoadBalancerDeviceVO addExternalLoadBalancer(long physicalNetworkId, String url, String username, String password, final String deviceName,
-        ServerResource resource, final boolean gslbProvider, final boolean exclusiveGslbProivider,
-        final String gslbSitePublicIp, final String gslbSitePrivateIp) {
-
-        PhysicalNetworkVO pNetwork = null;
-        final NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName);
-        long zoneId;
-
-        if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) {
-            throw new InvalidParameterValueException("Atleast one of the required parameters (url, username, password,"
-                + " server resource, zone id/physical network id) is not specified or a valid parameter.");
-        }
-
-        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
-        }
-
-        zoneId = pNetwork.getDataCenterId();
-        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
-            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
-
-        ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
-        if (ntwkSvcProvider == null) {
-            throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: " +
-                physicalNetworkId + "to add this device");
-        } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
-            throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + " is in shutdown state in the physical network: " +
-                physicalNetworkId + "to add this device");
-        }
-
-        if (gslbProvider) {
-            ExternalLoadBalancerDeviceVO zoneGslbProvider =
-                _externalLoadBalancerDeviceDao.findGslbServiceProvider(physicalNetworkId, ntwkDevice.getNetworkServiceProvder());
-            if (zoneGslbProvider != null) {
-                throw new CloudRuntimeException("There is a GSLB service provider configured in the zone alredy.");
-            }
-        }
-
-        URI uri;
-        try {
-            uri = new URI(url);
-        } catch (Exception e) {
-            s_logger.debug(e);
-            throw new InvalidParameterValueException(e.getMessage());
-        }
-
-        String ipAddress = uri.getHost();
-        Map hostDetails = new HashMap<String, String>();
-        String hostName = getExternalLoadBalancerResourceGuid(pNetwork.getId(), deviceName, ipAddress);
-        hostDetails.put("name", hostName);
-        hostDetails.put("guid", UUID.randomUUID().toString());
-        hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId()));
-        hostDetails.put("ip", ipAddress);
-        hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId()));
-        hostDetails.put("username", username);
-        hostDetails.put("password", password);
-        hostDetails.put("deviceName", deviceName);
-
-        // leave parameter validation to be part server resource configure
-        Map<String, String> configParams = new HashMap<String, String>();
-        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
-        hostDetails.putAll(configParams);
-
-        try {
-            resource.configure(hostName, hostDetails);
-
-            final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails);
-            if (host != null) {
-
-                final boolean dedicatedUse =
-                    (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED))
-                        : false;
-                long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0);
-                if (capacity == 0) {
-                    capacity = _defaultLbCapacity;
-                }
-
-                final long capacityFinal = capacity;
-                final PhysicalNetworkVO pNetworkFinal = pNetwork;
-                return Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {
-                    @Override
-                    public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
-                        ExternalLoadBalancerDeviceVO lbDeviceVO =
-                            new ExternalLoadBalancerDeviceVO(host.getId(), pNetworkFinal.getId(), ntwkDevice.getNetworkServiceProvder(), deviceName, capacityFinal,
-                                dedicatedUse, gslbProvider);
-                        if (gslbProvider) {
-                            lbDeviceVO.setGslbSitePublicIP(gslbSitePublicIp);
-                            lbDeviceVO.setGslbSitePrivateIP(gslbSitePrivateIp);
-                            lbDeviceVO.setExclusiveGslbProvider(exclusiveGslbProivider);
-                        }
-                        _externalLoadBalancerDeviceDao.persist(lbDeviceVO);
-                        DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId()));
-                        _hostDetailDao.persist(hostDetail);
-
-                        return lbDeviceVO;
-                    }
-                });
-            } else {
-                throw new CloudRuntimeException("Failed to add load balancer device due to internal error.");
-            }
-        } catch (ConfigurationException e) {
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @Override
-    public boolean deleteExternalLoadBalancer(long hostId) {
-        HostVO externalLoadBalancer = _hostDao.findById(hostId);
-        if (externalLoadBalancer == null) {
-            throw new InvalidParameterValueException("Could not find an external load balancer with ID: " + hostId);
-        }
-
-        DetailVO lbHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.LOAD_BALANCER_DEVICE_ID);
-        long lbDeviceId = Long.parseLong(lbHostDetails.getValue());
-
-        ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
-        if (lbDeviceVo.getAllocationState() == LBDeviceAllocationState.Provider) {
-            // check if cloudstack has provisioned any load balancer appliance on the device before deleting
-            List<ExternalLoadBalancerDeviceVO> lbDevices = _externalLoadBalancerDeviceDao.listAll();
-            if (lbDevices != null) {
-                for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) {
-                    if (lbDevice.getParentHostId() == hostId) {
-                        throw new CloudRuntimeException(
-                            "This load balancer device can not be deleted as there are one or more load balancers applainces provisioned by cloudstack on the device.");
-                    }
-                }
-            }
-        } else {
-            // check if any networks are using this load balancer device
-            List<NetworkExternalLoadBalancerVO> networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
-            if ((networks != null) && !networks.isEmpty()) {
-                throw new CloudRuntimeException("Delete can not be done as there are networks using this load balancer device ");
-            }
-        }
-
-        try {
-            // put the host in maintenance state in order for it to be deleted
-            externalLoadBalancer.setResourceState(ResourceState.Maintenance);
-            _hostDao.update(hostId, externalLoadBalancer);
-            _resourceMgr.deleteHost(hostId, false, false);
-
-            // delete the external load balancer entry
-            _externalLoadBalancerDeviceDao.remove(lbDeviceId);
-
-            return true;
-        } catch (Exception e) {
-            s_logger.debug(e);
-            return false;
-        }
-    }
-
-    @Override
-    public List<Host> listExternalLoadBalancers(long physicalNetworkId, String deviceName) {
-        List<Host> lbHosts = new ArrayList<Host>();
-        NetworkDevice lbNetworkDevice = NetworkDevice.getNetworkDevice(deviceName);
-        PhysicalNetworkVO pNetwork = null;
-
-        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-
-        if ((pNetwork == null) || (lbNetworkDevice == null)) {
-            throw new InvalidParameterValueException("Atleast one of the required parameter physical networkId, device name is invalid.");
-        }
-
-        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
-            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), lbNetworkDevice.getNetworkServiceProvder());
-        // if provider not configured in to physical network, then there can be no instances
-        if (ntwkSvcProvider == null) {
-            return null;
-        }
-
-        List<ExternalLoadBalancerDeviceVO> lbDevices =
-            _externalLoadBalancerDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, ntwkSvcProvider.getProviderName());
-        for (ExternalLoadBalancerDeviceVO provderInstance : lbDevices) {
-            lbHosts.add(_hostDao.findById(provderInstance.getHostId()));
-        }
-        return lbHosts;
-    }
-
-    public ExternalLoadBalancerResponse createExternalLoadBalancerResponse(Host externalLoadBalancer) {
-        Map<String, String> lbDetails = _hostDetailDao.findDetails(externalLoadBalancer.getId());
-        ExternalLoadBalancerResponse response = new ExternalLoadBalancerResponse();
-        response.setId(externalLoadBalancer.getUuid());
-        response.setIpAddress(externalLoadBalancer.getPrivateIpAddress());
-        response.setUsername(lbDetails.get("username"));
-        response.setPublicInterface(lbDetails.get("publicInterface"));
-        response.setPrivateInterface(lbDetails.get("privateInterface"));
-        response.setNumRetries(lbDetails.get("numRetries"));
-        return response;
-    }
-
-    public String getExternalLoadBalancerResourceGuid(long physicalNetworkId, String deviceName, String ip) {
-        return physicalNetworkId + "-" + deviceName + "-" + ip;
-    }
-
-    @Override
-    public ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) {
-        NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId());
-        if (lbDeviceForNetwork != null) {
-            long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId();
-            ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
-            assert (lbDeviceVo != null);
-            return lbDeviceVo;
-        }
-        return null;
-    }
-
-    public void setExternalLoadBalancerForNetwork(Network network, long externalLBDeviceID) {
-        NetworkExternalLoadBalancerVO lbDeviceForNetwork = new NetworkExternalLoadBalancerVO(network.getId(), externalLBDeviceID);
-        _networkExternalLBDao.persist(lbDeviceForNetwork);
-    }
-
-    @DB
-    protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(final Network guestConfig) throws InsufficientCapacityException {
-        boolean retry = true;
-        boolean tryLbProvisioning = false;
-        ExternalLoadBalancerDeviceVO lbDevice = null;
-        long physicalNetworkId = guestConfig.getPhysicalNetworkId();
-        NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
-        String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb);
-
-        while (retry) {
-            GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
-            try {
-                if (deviceMapLock.lock(120)) {
-                    try {
-                        final boolean dedicatedLB = offering.getDedicatedLB(); // does network offering supports a dedicated load balancer?
-
-                        try {
-                            lbDevice = Transaction.execute(new TransactionCallbackWithException<ExternalLoadBalancerDeviceVO, InsufficientCapacityException>() {
-                                @Override
-                                public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
-                                    // FIXME: should the device allocation be done during network implement phase or do a
-                                    // lazy allocation when first rule for the network is configured??
-
-                                    // find a load balancer device for this network as per the network offering
-                                    ExternalLoadBalancerDeviceVO lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB);
-                                    long lbDeviceId = lbDevice.getId();
-
-                                    // persist the load balancer device id that will be used for this network. Once a network
-                                    // is implemented on a LB device then later on all rules will be programmed on to same device
-                                    NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId);
-                                    _networkExternalLBDao.persist(networkLB);
-
-                                    // mark device to be either dedicated or shared use
-                                    lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared);
-                                    _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice);
-                                    return lbDevice;
-                                }
-                            });
-
-                            // allocated load balancer for the network, so skip retry
-                            tryLbProvisioning = false;
-                            retry = false;
-                        } catch (InsufficientCapacityException exception) {
-                            // if already attempted to provision load balancer then throw out of capacity exception,
-                            if (tryLbProvisioning) {
-                                retry = false;
-                                // TODO: throwing warning instead of error for now as its possible another provider can service this network
-                                s_logger.warn("There are no load balancer device with the capacity for implementing this network");
-                                throw exception;
-                            } else {
-                                tryLbProvisioning = true; // if possible provision a LB appliance in to the physical network
-                            }
-                        }
-                    } finally {
-                        deviceMapLock.unlock();
-                    }
-                }
-            } finally {
-                deviceMapLock.releaseRef();
-            }
-
-            // there are no LB devices or there is no free capacity on the devices in the physical network so provision a new LB appliance
-            if (tryLbProvisioning) {
-                // check if LB appliance can be dynamically provisioned
-                List<ExternalLoadBalancerDeviceVO> providerLbDevices =
-                    _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider);
-                if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) {
-                    for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) {
-                        if (lbProviderDevice.getState() == LBDeviceState.Enabled) {
-                            // acquire a private IP from the data center which will be used as management IP of provisioned LB appliance,
-                            DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid());
-                            if (dcPrivateIp == null) {
-                                throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() +
-                                    " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId());
-                            }
-                            Pod pod = _podDao.findById(dcPrivateIp.getPodId());
-                            String lbIP = dcPrivateIp.getIpAddress();
-                            String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
-                            String gateway = pod.getGateway();
-
-                            // send CreateLoadBalancerApplianceCommand to the host capable of provisioning
-                            CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway);
-                            CreateLoadBalancerApplianceAnswer createLbAnswer = null;
-                            try {
-                                createLbAnswer = (CreateLoadBalancerApplianceAnswer)_agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd);
-                                if (createLbAnswer == null || !createLbAnswer.getResult()) {
-                                    s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId());
-                                    continue;
-                                }
-                            } catch (Exception agentException) {
-                                s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " +
-                                    agentException.getMessage());
-                                continue;
-                            }
-
-                            String username = createLbAnswer.getUsername();
-                            String password = createLbAnswer.getPassword();
-                            String publicIf = createLbAnswer.getPublicInterface();
-                            String privateIf = createLbAnswer.getPrivateInterface();
-
-                            // we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer
-                            String dedicatedLb = offering.getDedicatedLB() ? "true" : "false";
-                            String capacity = Long.toString(lbProviderDevice.getCapacity());
-
-                            // acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
-                            PublicIp publicIp =
-                                _ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null,
-                                    null, false, false);
-                            String publicIPNetmask = publicIp.getVlanNetmask();
-                            String publicIPgateway = publicIp.getVlanGateway();
-                            String publicIP = publicIp.getAddress().toString();
-                            String publicIPVlanTag="";
-                            try {
-                                publicIPVlanTag = BroadcastDomainType.getValue(publicIp.getVlanTag());
-                            } catch (URISyntaxException e) {
-                                s_logger.error("Failed to parse public ip vlan tag" + e.getMessage());
-                            }
-
-                            String url =
-                                "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb +
-                                    "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity +
-                                    "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
-                            ExternalLoadBalancerDeviceVO lbAppliance = null;
-                            try {
-                                lbAppliance =
-                                    addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(),
-                                        createLbAnswer.getServerResource(), false, false, null, null);
-                            } catch (Exception e) {
-                                s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() +
-                                    ". So provisioned load balancer appliance will be destroyed.");
-                            }
-
-                            if (lbAppliance != null) {
-                                // mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned
-                                ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId());
-                                managedLb.setIsManagedDevice(true);
-                                managedLb.setParentHostId(lbProviderDevice.getHostId());
-                                _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb);
-                            } else {
-                                // failed to add the provisioned load balancer into cloudstack so destroy the appliance
-                                DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
-                                DestroyLoadBalancerApplianceAnswer answer = null;
-                                try {
-                                    answer = (DestroyLoadBalancerApplianceAnswer)_agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd);
-                                    if (answer == null || !answer.getResult()) {
-                                        s_logger.warn("Failed to destroy load balancer appliance created");
-                                    } else {
-                                        // release the public & private IP back to dc pool, as the load balancer appliance is now destroyed
-                                        _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null);
-                                        _ipAddrMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
-                                    }
-                                } catch (Exception e) {
-                                    s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage());
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return lbDevice;
-    }
-
-    @Override
-    public ExternalLoadBalancerDeviceVO findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException {
-        long physicalNetworkId = network.getPhysicalNetworkId();
-        List<ExternalLoadBalancerDeviceVO> lbDevices = null;
-        String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
-        assert (provider != null);
-
-        if (dedicatedLb) {
-            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
-            if (lbDevices != null && !lbDevices.isEmpty()) {
-                // return first device that is free, fully configured and meant for dedicated use
-                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
-                    if (lbdevice.getState() == LBDeviceState.Enabled && lbdevice.getIsDedicatedDevice()) {
-                        return lbdevice;
-                    }
-                }
-            }
-        } else {
-            // get the LB devices that are already allocated for shared use
-            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Shared);
-
-            if (lbDevices != null) {
-
-                ExternalLoadBalancerDeviceVO maxFreeCapacityLbdevice = null;
-                long maxFreeCapacity = 0;
-
-                // loop through the LB device in the physical network and pick the one with maximum free capacity
-                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
-
-                    // skip if device is not enabled
-                    if (lbdevice.getState() != LBDeviceState.Enabled) {
-                        continue;
-                    }
-
-                    // get the used capacity from the list of guest networks that are mapped to this load balancer
-                    List<NetworkExternalLoadBalancerVO> mappedNetworks = _networkExternalLBDao.listByLoadBalancerDeviceId(lbdevice.getId());
-                    long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty())) ? 0 : mappedNetworks.size();
-
-                    // get the configured capacity for this device
-                    long fullCapacity = lbdevice.getCapacity();
-                    if (fullCapacity == 0) {
-                        fullCapacity = _defaultLbCapacity; // if capacity not configured then use the default
-                    }
-
-                    long freeCapacity = fullCapacity - usedCapacity;
-                    if (freeCapacity > 0) {
-                        if (maxFreeCapacityLbdevice == null) {
-                            maxFreeCapacityLbdevice = lbdevice;
-                            maxFreeCapacity = freeCapacity;
-                        } else if (freeCapacity > maxFreeCapacity) {
-                            maxFreeCapacityLbdevice = lbdevice;
-                            maxFreeCapacity = freeCapacity;
-                        }
-                    }
-                }
-
-                // return the device with maximum free capacity and is meant for shared use
-                if (maxFreeCapacityLbdevice != null) {
-                    return maxFreeCapacityLbdevice;
-                }
-            }
-
-            // if we are here then there are no existing LB devices in shared use or the devices in shared use has no
-// free capacity left
-            // so allocate a new load balancer configured for shared use from the pool of free LB devices
-            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
-            if (lbDevices != null && !lbDevices.isEmpty()) {
-                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
-                    if (lbdevice.getState() == LBDeviceState.Enabled && !lbdevice.getIsDedicatedDevice()) {
-                        return lbdevice;
-                    }
-                }
-            }
-        }
-
-        // there are no devices which capacity
-        throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " + " to implement the network", Network.class,
-            network.getId());
-    }
-
-    @DB
-    protected boolean freeLoadBalancerForNetwork(final Network guestConfig) {
-        GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
-
-        try {
-            if (deviceMapLock.lock(120)) {
-                ExternalLoadBalancerDeviceVO lbDevice = Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {
-                    @Override
-                    public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
-                        // since network is shutdown remove the network mapping to the load balancer device
-                        NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId());
-                        long lbDeviceId = networkLBDevice.getExternalLBDeviceId();
-                        _networkExternalLBDao.remove(networkLBDevice.getId());
-
-                        List<NetworkExternalLoadBalancerVO> ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId());
-                        ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
-                        boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty());
-                        boolean lbCloudManaged = lbDevice.getIsManagedDevice();
-
-                        if (!lbInUse && !lbCloudManaged) {
-                            // this is the last network mapped to the load balancer device so set device allocation state to be free
-                            lbDevice.setAllocationState(LBDeviceAllocationState.Free);
-                            _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice);
-                        }
-
-                        // commit the changes before sending agent command to destroy cloudstack managed LB
-                        if (!lbInUse && lbCloudManaged) {
-                            return lbDevice;
-                        } else {
-                            return null;
-                        }
-                    }
-                });
-
-                if (lbDevice != null) {
-                    // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned
-                    Host lbHost = _hostDao.findById(lbDevice.getHostId());
-                    String lbIP = lbHost.getPrivateIpAddress();
-                    DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
-                    DestroyLoadBalancerApplianceAnswer answer = null;
-                    try {
-                        answer = (DestroyLoadBalancerApplianceAnswer)_agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd);
-                        if (answer == null || !answer.getResult()) {
-                            s_logger.warn("Failed to destoy load balancer appliance used by the network"
-                                    + guestConfig.getId() + " due to " + answer == null ? "communication error with agent"
-                                    : answer.getDetails());
-                        }
-                    } catch (Exception e) {
-                        s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage());
-                    }
-
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId());
-                    }
-                    deviceMapLock.unlock();
-
-                    // remove the provisioned load balancer appliance from cloudstack
-                    deleteExternalLoadBalancer(lbHost.getId());
-
-                    // release the private IP back to dc pool, as the load balancer appliance is now destroyed
-                    _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null);
-
-                    // release the public IP allocated for this LB appliance
-                    DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip");
-                    IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString());
-                    _ipAddrMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
-                } else {
-                    deviceMapLock.unlock();
-                }
-
-                return true;
-            } else {
-                s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock ");
-                return false;
-            }
-        } catch (Exception exception) {
-            s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage());
-        } finally {
-            deviceMapLock.releaseRef();
-        }
-
-        return false;
-    }
-
-    private void applyStaticNatRuleForInlineLBRule(DataCenterVO zone, Network network, boolean revoked, String publicIp, String privateIp)
-        throws ResourceUnavailableException {
-        List<StaticNat> staticNats = new ArrayList<StaticNat>();
-        IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0);
-        StaticNatImpl staticNat = new StaticNatImpl(ipVO.getAllocatedToAccountId(), ipVO.getAllocatedInDomainId(), network.getId(), ipVO.getId(), privateIp, revoked);
-        staticNats.add(staticNat);
-        StaticNatServiceProvider element = _networkMgr.getStaticNatProviderForNetwork(network);
-        element.applyStaticNats(network, staticNats);
-    }
-
-    private enum MappingState {
-        Create, Remove, Unchanged,
-    };
-
-    private class MappingNic {
-        private Nic nic;
-        private MappingState state;
-
-        public Nic getNic() {
-            return nic;
-        }
-
-        public void setNic(Nic nic) {
-            this.nic = nic;
-        }
-
-        public MappingState getState() {
-            return state;
-        }
-
-        public void setState(MappingState state) {
-            this.state = state;
-        }
-    };
-
-    private MappingNic getLoadBalancingIpNic(DataCenterVO zone, Network network, long sourceIpId, boolean revoked, String existedGuestIp)
-        throws ResourceUnavailableException {
-        String srcIp = _networkModel.getIp(sourceIpId).getAddress().addr();
-        InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(srcIp);
-        Nic loadBalancingIpNic = null;
-        MappingNic nic = new MappingNic();
-        nic.setState(MappingState.Unchanged);
-        if (!revoked) {
-            if (mapping == null) {
-                // Acquire a new guest IP address and save it as the load balancing IP address
-                String loadBalancingIpAddress = existedGuestIp;
-
-                if (loadBalancingIpAddress == null) {
-                    if (network.getGuestType() == Network.GuestType.Isolated) {
-                        loadBalancingIpAddress = _ipAddrMgr.acquireGuestIpAddress(network, null);
-                    } else if (network.getGuestType() == Network.GuestType.Shared) {
-                        try {
-                            PublicIp directIp =
-                                _ipAddrMgr.assignPublicIpAddress(network.getDataCenterId(), null, _accountDao.findById(network.getAccountId()), VlanType.DirectAttached,
-                                    network.getId(), null, true, false);
-                            loadBalancingIpAddress = directIp.getAddress().addr();
-                        } catch (InsufficientCapacityException capException) {
-                            String msg = "Ran out of guest IP addresses from the shared network.";
-                            s_logger.error(msg);
-                            throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
-                        }
-                    }
-                }
-
-                if (loadBalancingIpAddress == null) {
-                    String msg = "Ran out of guest IP addresses.";
-                    s_logger.error(msg);
-                    throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
-                }
-
-                // If a NIC doesn't exist for the load balancing IP address, create one
-                loadBalancingIpNic = _nicDao.findByIp4AddressAndNetworkId(loadBalancingIpAddress, network.getId());
-                if (loadBalancingIpNic == null) {
-                    loadBalancingIpNic = _networkMgr.savePlaceholderNic(network, loadBalancingIpAddress, null, null);
-                }
-
-                // Save a mapping between the source IP address and the load balancing IP address NIC
-                mapping = new InlineLoadBalancerNicMapVO(srcIp, loadBalancingIpNic.getId());
-                _inlineLoadBalancerNicMapDao.persist(mapping);
-
-                // On the firewall provider for the network, create a static NAT rule between the source IP
-                // address and the load balancing IP address
-                try {
-                    applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
-                } catch (ResourceUnavailableException ex) {
-                    // Rollback db operation
-                    _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
-                    _nicDao.expunge(loadBalancingIpNic.getId());
-                    throw ex;
-                }
-
-                s_logger.debug("Created static nat rule for inline load balancer");
-                nic.setState(MappingState.Create);
-            } else {
-                loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
-            }
-        } else {
-            if (mapping != null) {
-                // Find the NIC that the mapping refers to
-                loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
-
-                int count = _ipAddrMgr.getRuleCountForIp(sourceIpId, Purpose.LoadBalancing, FirewallRule.State.Active);
-                if (count == 0) {
-                    // On the firewall provider for the network, delete the static NAT rule between the source IP
-                    // address and the load balancing IP address
-                    applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
-
-                    // Delete the mapping between the source IP address and the load balancing IP address
-                    _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
-
-                    // Delete the NIC
-                    _nicDao.expunge(loadBalancingIpNic.getId());
-
-                    s_logger.debug("Revoked static nat rule for inline load balancer");
-                    nic.setState(MappingState.Remove);
-                }
-            } else {
-                s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet.");
-                nic.setNic(null);
-                return nic;
-            }
-        }
-
-        nic.setNic(loadBalancingIpNic);
-        return nic;
-    }
-
-    public boolean isNccServiceProvider(Network network) {
-        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if(null!= networkOffering && networkOffering.getServicePackage() != null ) {
-            return true;
-        }
-        else {
-            return false;
-        }
-    }
-
-    public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) {
-        long zoneId = guestConfig.getDataCenterId();
-        return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter);
-    }
-
-    @Override
-    public boolean applyLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
-        // Find the external load balancer in this zone
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-
-        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
-            return true;
-        }
-
-        HostVO externalLoadBalancer = null;
-
-        if(isNccServiceProvider(network)) {
-            externalLoadBalancer  = getNetScalerControlCenterForNetwork(network);
-        } else {
-            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
-            if (lbDeviceVO == null) {
-                s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
-                return true;
-            } else {
-                externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            }
-        }
-
-
-
-        boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network);
-
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() +
-                "; this network is not implemented. Skipping backend commands.");
-            return true;
-        }
-
-        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
-        List<MappingState> mappingStates = new ArrayList<MappingState>();
-        for (int i = 0; i < loadBalancingRules.size(); i++) {
-            LoadBalancingRule rule = loadBalancingRules.get(i);
-
-            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
-            String protocol = rule.getProtocol();
-            String algorithm = rule.getAlgorithm();
-            String uuid = rule.getUuid();
-            String srcIp = rule.getSourceIp().addr();
-            String srcIpVlan = null;
-            String srcIpGateway = null;
-            String srcIpNetmask = null;
-            Long vlanid =  _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId();
-            if(vlanid != null ) {
-              VlanVO publicVlan =   _vlanDao.findById(vlanid);
-              srcIpVlan =  publicVlan.getVlanTag();
-              srcIpGateway = publicVlan.getVlanGateway();
-              srcIpNetmask = publicVlan.getVlanNetmask();
-            }
-            int srcPort = rule.getSourcePortStart();
-            List<LbDestination> destinations = rule.getDestinations();
-
-            if (externalLoadBalancerIsInline) {
-                long ipId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
-                MappingNic nic = getLoadBalancingIpNic(zone, network, ipId, revoked, null);
-                mappingStates.add(nic.getState());
-                Nic loadBalancingIpNic = nic.getNic();
-                if (loadBalancingIpNic == null) {
-                    continue;
-                }
-
-                // Change the source IP address for the load balancing rule to be the load balancing IP address
-                srcIp = loadBalancingIpNic.getIPv4Address();
-            }
-
-            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
-                boolean inline = _networkMgr.isNetworkInlineMode(network);
-                LoadBalancerTO loadBalancer =
-                    new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(),
-                        rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
-                loadBalancer.setNetworkId(network.getId());
-                loadBalancer.setSrcIpVlan(srcIpVlan);
-                loadBalancer.setSrcIpNetmask(srcIpNetmask);
-                loadBalancer.setSrcIpGateway(srcIpGateway);
-                if (rule.isAutoScaleConfig()) {
-                    loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
-                }
-                loadBalancersToApply.add(loadBalancer);
-            }
-        }
-
-        try {
-            if (loadBalancersToApply.size() > 0) {
-                int numLoadBalancersForCommand = loadBalancersToApply.size();
-                LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-                LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null);
-                long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
-                cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
-                Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
-                if (answer == null || !answer.getResult()) {
-                    String details = (answer != null) ? answer.getDetails() : "details unavailable";
-                    String msg = "Unable to apply load balancer rules to the external load balancer appliance in zone " + zone.getName() + " due to: " + details + ".";
-                    s_logger.error(msg);
-                    throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
-                }
-            }
-        } catch (Exception ex) {
-            if (externalLoadBalancerIsInline) {
-                s_logger.error("Rollbacking static nat operation of inline mode load balancing due to error on applying LB rules!");
-                String existedGuestIp = loadBalancersToApply.get(0).getSrcIp();
-                // Rollback static NAT operation in current session
-                for (int i = 0; i < loadBalancingRules.size(); i++) {
-                    LoadBalancingRule rule = loadBalancingRules.get(i);
-                    MappingState state = mappingStates.get(i);
-                    boolean revoke;
-                    if (state == MappingState.Create) {
-                        revoke = true;
-                    } else if (state == MappingState.Remove) {
-                        revoke = false;
-                    } else {
-                        continue;
-                    }
-                    long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
-                    getLoadBalancingIpNic(zone, network, sourceIpId, revoke, existedGuestIp);
-                }
-            }
-            throw new ResourceUnavailableException(ex.getMessage(), DataCenter.class, network.getDataCenterId());
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException {
-        if (guestConfig.getTrafficType() != TrafficType.Guest) {
-            s_logger.trace("External load balancer can only be used for guest networks.");
-            return false;
-        }
-
-        long zoneId = guestConfig.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        HostVO externalLoadBalancer = null;
-
-        if (add) {
-            ExternalLoadBalancerDeviceVO lbDeviceVO = null;
-            // on restart network, device could have been allocated already, skip allocation if a device is assigned
-            lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
-            if (lbDeviceVO == null) {
-                // allocate a load balancer device for the network
-                lbDeviceVO = allocateLoadBalancerForNetwork(guestConfig);
-                if (lbDeviceVO == null) {
-                    String msg = "failed to alloacate a external load balancer for the network " + guestConfig.getId();
-                    s_logger.error(msg);
-                    throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId());
-                }
-            }
-            externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            s_logger.debug("Allocated external load balancer device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId());
-        } else {
-            // find the load balancer device allocated for the network
-            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
-            if (lbDeviceVO == null) {
-                s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network."
-                    + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
-                return true;
-            }
-
-            externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??";
-        }
-
-        // Send a command to the external load balancer to implement or shutdown the guest network
-        String guestVlanTag = BroadcastDomainType.getValue(guestConfig.getBroadcastUri());
-        String selfIp = null;
-        String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr());
-        Integer networkRate = _networkModel.getNetworkRate(guestConfig.getId(), null);
-
-        if (add) {
-            // on restart network, network could have already been implemented. If already implemented then return
-            Nic selfipNic = getPlaceholderNic(guestConfig);
-            if (selfipNic != null) {
-                return true;
-            }
-
-            // Acquire a self-ip address from the guest network IP address range
-            selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
-            if (selfIp == null) {
-                String msg = "failed to acquire guest IP address so not implementing the network on the external load balancer ";
-                s_logger.error(msg);
-                throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
-            }
-        } else {
-            // get the self-ip used by the load balancer
-            Nic selfipNic = getPlaceholderNic(guestConfig);
-            if (selfipNic == null) {
-                s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network."
-                    + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
-                return true;
-            }
-            selfIp = selfipNic.getIPv4Address();
-        }
-
-        // It's a hack, using isOneToOneNat field for indicate if it's inline or not
-        boolean inline = _networkMgr.isNetworkInlineMode(guestConfig);
-        IpAddressTO ip =
-            new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, guestVlanTag, selfIp, guestVlanNetmask, null, networkRate, inline);
-        IpAddressTO[] ips = new IpAddressTO[1];
-        ips[0] = ip;
-        IpAssocCommand cmd = new IpAssocCommand(ips);
-        Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
-
-        if (answer == null || !answer.getResult()) {
-            String action = add ? "implement" : "shutdown";
-            String answerDetails = (answer != null) ? answer.getDetails() : null;
-            answerDetails = (answerDetails != null) ? " due to " + answerDetails : "";
-            String msg = "External load balancer was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + answerDetails;
-            s_logger.error(msg);
-            throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId());
-        }
-
-        if (add) {
-            // Insert a new NIC for this guest network to reserve the self IP
-            _networkMgr.savePlaceholderNic(guestConfig, selfIp, null, null);
-        } else {
-            // release the self-ip obtained from guest network
-            Nic selfipNic = getPlaceholderNic(guestConfig);
-            _nicDao.remove(selfipNic.getId());
-
-            // release the load balancer allocated for the network
-            boolean releasedLB = freeLoadBalancerForNetwork(guestConfig);
-            if (!releasedLB) {
-                String msg = "Failed to release the external load balancer used for the network: " + guestConfig.getId();
-                s_logger.error(msg);
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId());
-            String action = add ? "implemented" : "shut down";
-            s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() +
-                ") with VLAN tag " + guestVlanTag);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        _defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) {
-            return null;
-        }
-        if(host.getName().equalsIgnoreCase("NetScalerControlCenter")) {
-            host.setType(Host.Type.NetScalerControlCenter);
-        }
-        else {
-            host.setType(Host.Type.ExternalLoadBalancer);
-        }
-        return host;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (host.getType() != com.cloud.host.Host.Type.ExternalLoadBalancer) {
-            return null;
-        }
-        return new DeleteHostAnswer(true);
-    }
-
-    protected IpDeployer getIpDeployerForInlineMode(Network network) {
-        //We won't deploy IP, instead the firewall in front of us would do it
-        List<Provider> providers = _networkMgr.getProvidersForServiceInNetwork(network, Service.Firewall);
-        //Only support one provider now
-        if (providers == null) {
-            s_logger.error("Cannot find firewall provider for network " + network.getId());
-            return null;
-        }
-        if (providers.size() != 1) {
-            s_logger.error("Found " + providers.size() + " firewall provider for network " + network.getId());
-            return null;
-        }
-
-        NetworkElement element = _networkModel.getElementImplementingProvider(providers.get(0).getName());
-        if (!(element instanceof IpDeployer)) {
-            s_logger.error("The firewall provider for network " + network.getName() + " don't have ability to deploy IP address!");
-            return null;
-        }
-        s_logger.info("Let " + element.getName() + " handle ip association for " + getName() + " in network " + network.getId());
-        return (IpDeployer)element;
-    }
-
-    @Override
-    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
-
-        // Find the external load balancer in this zone
-        long zoneId = network.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-
-        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
-            return null;
-        }
-
-        HostVO externalLoadBalancer = null;
-
-        if(isNccServiceProvider(network)) {
-            externalLoadBalancer  = getNetScalerControlCenterForNetwork(network);
-        } else {
-            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
-            if (lbDeviceVO == null) {
-                s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
-                return null;
-            } else {
-                externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
-            }
-        }
-
-        boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network);
-
-        if (network.getState() == Network.State.Allocated) {
-            s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() +
-                "; this network is not implemented. Skipping backend commands.");
-            return null;
-        }
-
-        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
-        List<MappingState> mappingStates = new ArrayList<MappingState>();
-        for (final LoadBalancingRule rule : loadBalancingRules) {
-            boolean revoked = (FirewallRule.State.Revoke.equals(rule.getState()));
-            String protocol = rule.getProtocol();
-            String algorithm = rule.getAlgorithm();
-            String uuid = rule.getUuid();
-            String srcIp = rule.getSourceIp().addr();
-            int srcPort = rule.getSourcePortStart();
-            List<LbDestination> destinations = rule.getDestinations();
-
-            if (externalLoadBalancerIsInline) {
-                long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
-                MappingNic nic = getLoadBalancingIpNic(zone, network, sourceIpId, revoked, null);
-                mappingStates.add(nic.getState());
-                Nic loadBalancingIpNic = nic.getNic();
-                if (loadBalancingIpNic == null) {
-                    continue;
-                }
-
-                // Change the source IP address for the load balancing rule to
-                // be the load balancing IP address
-                srcIp = loadBalancingIpNic.getIPv4Address();
-            }
-
-            if ((destinations != null && !destinations.isEmpty()) || !rule.isAutoScaleConfig()) {
-                boolean inline = _networkMgr.isNetworkInlineMode(network);
-                LoadBalancerTO loadBalancer =
-                    new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(),
-                        rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
-                loadBalancersToApply.add(loadBalancer);
-            }
-        }
-
-        try {
-            if (loadBalancersToApply.size() > 0) {
-                int numLoadBalancersForCommand = loadBalancersToApply.size();
-                LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-                HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
-                long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
-                cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
-
-                HealthCheckLBConfigAnswer answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
-                // easySend will return null on error
-                return answer == null ? null : answer.getLoadBalancers();
-            }
-        } catch (Exception ex) {
-            s_logger.error("Exception Occured ", ex);
-        }
-        //null return is handled by clients
-        return null;
-    }
-
-    private NicVO getPlaceholderNic(Network network) {
-        List<NicVO> guestIps = _nicDao.listByNetworkId(network.getId());
-        for (NicVO guestIp : guestIps) {
-            // only external firewall and external load balancer will create NicVO with PlaceHolder reservation strategy
-            if (guestIp.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && guestIp.getVmType() == null && guestIp.getReserver() == null &&
-                !guestIp.getIPv4Address().equals(network.getGateway())) {
-                return guestIp;
-            }
-        }
-        return null;
-    }
-
-}
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
deleted file mode 100644
index 71acc83..0000000
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ /dev/null
@@ -1,2187 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import com.cloud.dc.DomainVlanMapVO;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.region.PortableIp;
-import org.apache.cloudstack.region.PortableIpDao;
-import org.apache.cloudstack.region.PortableIpVO;
-import org.apache.cloudstack.region.Region;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.AccountVlanMapVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.AccountVlanMapDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterIpAddressDao;
-import com.cloud.dc.dao.DataCenterVnetDao;
-import com.cloud.dc.dao.DomainVlanMapDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.AccountLimitException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.network.IpAddress.State;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.AccountGuestVlanMapDao;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.NetworkAccountDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDomainDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.network.element.IpDeployer;
-import com.cloud.network.element.IpDeployingRequester;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.NetworkACLManager;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpn.RemoteAccessVpnService;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.org.Grouping;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.Journal;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class IpAddressManagerImpl extends ManagerBase implements IpAddressManager, Configurable {
-    private static final Logger s_logger = Logger.getLogger(IpAddressManagerImpl.class);
-
-    @Inject
-    NetworkOrchestrationService _networkMgr = null;
-    @Inject
-    EntityManager _entityMgr = null;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    VlanDao _vlanDao = null;
-    @Inject
-    IPAddressDao _ipAddressDao = null;
-    @Inject
-    AccountDao _accountDao = null;
-    @Inject
-    DomainDao _domainDao = null;
-    @Inject
-    UserDao _userDao = null;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    UserVmDao _userVmDao = null;
-    @Inject
-    AlertManager _alertMgr;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    AccountVlanMapDao _accountVlanMapDao;
-    @Inject
-    DomainVlanMapDao _domainVlanMapDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao = null;
-    @Inject
-    NetworkDao _networksDao = null;
-    @Inject
-    NicDao _nicDao = null;
-    @Inject
-    RulesManager _rulesMgr;
-    @Inject
-    LoadBalancingRulesManager _lbMgr;
-    @Inject
-    RemoteAccessVpnService _vpnMgr;
-    @Inject
-    PodVlanMapDao _podVlanMapDao;
-    @Inject
-    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
-    @Inject
-    AccountGuestVlanMapDao _accountGuestVlanMapDao;
-    @Inject
-    DataCenterVnetDao _datacenterVnetDao;
-    @Inject
-    NetworkAccountDao _networkAccountDao;
-    @Inject
-    protected NicIpAliasDao _nicIpAliasDao;
-    @Inject
-    protected IPAddressDao _publicIpAddressDao;
-    @Inject
-    NetworkDomainDao _networkDomainDao;
-    @Inject
-    VMInstanceDao _vmDao;
-    @Inject
-    FirewallManager _firewallMgr;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _pNSPDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingRulesDao;
-    @Inject
-    LoadBalancerDao _lbDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    StorageNetworkManager _stnwMgr;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    PrivateIpDao _privateIpDao;
-    @Inject
-    NetworkACLManager _networkACLMgr;
-    @Inject
-    UsageEventDao _usageEventDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    UserIpv6AddressDao _ipv6Dao;
-    @Inject
-    Ipv6AddressManager _ipv6Mgr;
-    @Inject
-    PortableIpDao _portableIpDao;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    DataCenterIpAddressDao _privateIPAddressDao;
-    @Inject
-    HostPodDao _hpDao;
-
-    SearchBuilder<IPAddressVO> AssignIpAddressSearch;
-    SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
-    private static final Object allocatedLock = new Object();
-
-    static Boolean rulesContinueOnErrFlag = true;
-
-    private static final ConfigKey<Boolean> SystemVmPublicIpReservationModeStrictness = new ConfigKey<Boolean>("Advanced",
-            Boolean.class, "system.vm.public.ip.reservation.mode.strictness", "false",
-            "If enabled, the use of System VMs public IP reservation is strict, preferred if not.", false, ConfigKey.Scope.Global);
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) {
-        // populate providers
-        Map<Network.Service, Set<Network.Provider>> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
-
-        defaultProviders.add(Network.Provider.VirtualRouter);
-        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-
-        Map<Network.Service, Set<Network.Provider>> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
-        defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
-        defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
-
-        Map<Network.Service, Set<Network.Provider>> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        Set<Provider> sgProviders = new HashSet<Provider>();
-        sgProviders.add(Provider.SecurityGroupProvider);
-        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders);
-
-        Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultProviders.clear();
-        defaultProviders.add(Network.Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
-
-        Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        defaultProviders.clear();
-        defaultProviders.add(Network.Provider.VirtualRouter);
-        defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
-        defaultVPCOffProviders.put(Service.Dns, defaultProviders);
-        defaultVPCOffProviders.put(Service.UserData, defaultProviders);
-        defaultVPCOffProviders.put(Service.NetworkACL, defaultProviders);
-        defaultVPCOffProviders.put(Service.Gateway, defaultProviders);
-        defaultVPCOffProviders.put(Service.Lb, defaultProviders);
-        defaultVPCOffProviders.put(Service.SourceNat, defaultProviders);
-        defaultVPCOffProviders.put(Service.StaticNat, defaultProviders);
-        defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders);
-        defaultVPCOffProviders.put(Service.Vpn, defaultProviders);
-
-        //#8 - network offering with internal lb service
-        Map<Network.Service, Set<Network.Provider>> internalLbOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        Set<Network.Provider> defaultVpcProvider = new HashSet<Network.Provider>();
-        defaultVpcProvider.add(Network.Provider.VPCVirtualRouter);
-
-        Set<Network.Provider> defaultInternalLbProvider = new HashSet<Network.Provider>();
-        defaultInternalLbProvider.add(Network.Provider.InternalLbVm);
-
-        internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider);
-        internalLbOffProviders.put(Service.Dns, defaultVpcProvider);
-        internalLbOffProviders.put(Service.UserData, defaultVpcProvider);
-        internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider);
-        internalLbOffProviders.put(Service.Gateway, defaultVpcProvider);
-        internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider);
-        internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider);
-
-        Map<Network.Service, Set<Network.Provider>> netscalerServiceProviders = new HashMap<Network.Service, Set<Network.Provider>>();
-        Set<Network.Provider> vrProvider = new HashSet<Network.Provider>();
-        vrProvider.add(Provider.VirtualRouter);
-        Set<Network.Provider> sgProvider = new HashSet<Network.Provider>();
-        sgProvider.add(Provider.SecurityGroupProvider);
-        Set<Network.Provider> nsProvider = new HashSet<Network.Provider>();
-        nsProvider.add(Provider.Netscaler);
-        netscalerServiceProviders.put(Service.Dhcp, vrProvider);
-        netscalerServiceProviders.put(Service.Dns, vrProvider);
-        netscalerServiceProviders.put(Service.UserData, vrProvider);
-        netscalerServiceProviders.put(Service.SecurityGroup, sgProvider);
-        netscalerServiceProviders.put(Service.StaticNat, nsProvider);
-        netscalerServiceProviders.put(Service.Lb, nsProvider);
-
-        Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
-        Map<Capability, String> elb = new HashMap<Capability, String>();
-        elb.put(Capability.ElasticLb, "true");
-        Map<Capability, String> eip = new HashMap<Capability, String>();
-        eip.put(Capability.ElasticIp, "true");
-        serviceCapabilityMap.put(Service.Lb, elb);
-        serviceCapabilityMap.put(Service.StaticNat, eip);
-
-        AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
-        AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
-        AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
-        AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
-        if (SystemVmPublicIpReservationModeStrictness.value()) {
-            AssignIpAddressSearch.and("forSystemVms", AssignIpAddressSearch.entity().isForSystemVms(), Op.EQ);
-        }
-        SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
-        vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
-        vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
-        AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
-        AssignIpAddressSearch.done();
-
-        AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder();
-        AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ);
-        AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL);
-        AssignIpAddressFromPodVlanSearch.and("vlanId", AssignIpAddressFromPodVlanSearch.entity().getVlanId(), Op.IN);
-
-        SearchBuilder<VlanVO> podVlanSearch = _vlanDao.createSearchBuilder();
-        podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ);
-        podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ);
-        SearchBuilder<PodVlanMapVO> podVlanMapSB = _podVlanMapDao.createSearchBuilder();
-        podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ);
-        AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(),
-                JoinType.INNER);
-        AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
-        AssignIpAddressFromPodVlanSearch.done();
-
-        Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao));
-
-        if (RulesContinueOnError.value() != null) {
-            rulesContinueOnErrFlag = RulesContinueOnError.value();
-        }
-
-        s_logger.info("IPAddress Manager is configured.");
-
-        return true;
-    }
-
-    private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException,
-            ConcurrentOperationException {
-        Account caller = CallContext.current().getCallingAccount();
-        long callerUserId = CallContext.current().getCallingUserId();
-        // check permissions
-        _accountMgr.checkAccess(caller, null, false, ipOwner);
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-
-        return allocateIp(ipOwner, isSystem, caller, callerUserId, zone, null);
-    }
-
-    // An IP association is required in below cases
-    //  1.there is at least one public IP associated with the network on which first rule (PF/static NAT/LB) is being applied.
-    //  2.last rule (PF/static NAT/LB) on the public IP has been revoked. So the public IP should not be associated with any provider
-    boolean checkIfIpAssocRequired(Network network, boolean postApplyRules, List<PublicIp> publicIps) {
-
-        if (network.getState() == Network.State.Implementing) {
-            return true;
-        }
-
-        for (PublicIp ip : publicIps) {
-            if (ip.isSourceNat()) {
-                continue;
-            } else if (ip.isOneToOneNat()) {
-                continue;
-            } else {
-                Long totalCount = null;
-                Long revokeCount = null;
-                Long activeCount = null;
-                Long addCount = null;
-
-                totalCount = _firewallDao.countRulesByIpId(ip.getId());
-                if (postApplyRules) {
-                    revokeCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Revoke);
-                } else {
-                    activeCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active);
-                    addCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Add);
-                }
-
-                if (totalCount == null || totalCount.longValue() == 0L) {
-                    continue;
-                }
-
-                if (postApplyRules) {
-
-                    if (revokeCount != null && revokeCount.longValue() == totalCount.longValue()) {
-                        s_logger.trace("All rules are in Revoke state, have to dis-assiciate IP from the backend");
-                        return true;
-                    }
-                } else {
-                    if (activeCount != null && activeCount > 0) {
-                        if (network.getVpcId() != null) {
-                            // If there are more than one ip in the vpc tier network and services configured on it.
-                            // restart network with cleanup case, on network reprogramming this needs to be return true
-                            // because on the VR ips has removed. In VPC case restart tier network with cleanup will not
-                            // reboot the VR. So ipassoc is needed.
-                            return true;
-                        }
-                        continue;
-                    } else if (addCount != null && addCount.longValue() == totalCount.longValue()) {
-                        s_logger.trace("All rules are in Add state, have to assiciate IP with the backend");
-                        return true;
-                    } else {
-                        continue;
-                    }
-                }
-            }
-        }
-
-        // there are no IP's corresponding to this network that need to be associated with provider
-        return false;
-    }
-
-    @Override
-    public boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
-            throws ResourceUnavailableException {
-        if (rules == null || rules.size() == 0) {
-            s_logger.debug("There are no rules to forward to the network elements");
-            return true;
-        }
-
-        boolean success = true;
-        Network network = _networksDao.findById(rules.get(0).getNetworkId());
-        FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
-        List<PublicIp> publicIps = new ArrayList<PublicIp>();
-
-        if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
-            // get the list of public ip's owned by the network
-            List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
-            if (userIps != null && !userIps.isEmpty()) {
-                for (IPAddressVO userIp : userIps) {
-                    PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                    publicIps.add(publicIp);
-                }
-            }
-        }
-        // rules can not programmed unless IP is associated with network service provider, so run IP assoication for
-        // the network so as to ensure IP is associated before applying rules (in add state)
-        if (checkIfIpAssocRequired(network, false, publicIps)) {
-            applyIpAssociations(network, false, continueOnError, publicIps);
-        }
-
-        try {
-            applier.applyRules(network, purpose, rules);
-        } catch (ResourceUnavailableException e) {
-            if (!continueOnError) {
-                throw e;
-            }
-            s_logger.warn("Problems with applying " + purpose + " rules but pushing on", e);
-            success = false;
-        }
-
-        // if there are no active rules associated with a public IP, then public IP need not be associated with a provider.
-        // This IPAssoc ensures, public IP is dis-associated after last active rule is revoked.
-        if (checkIfIpAssocRequired(network, true, publicIps)) {
-            applyIpAssociations(network, true, continueOnError, publicIps);
-        }
-
-        return success;
-    }
-
-    protected boolean cleanupIpResources(long ipId, long userId, Account caller) {
-        boolean success = true;
-
-        // Revoke all firewall rules for the ip
-        try {
-            s_logger.debug("Revoking all " + Purpose.Firewall + "rules as a part of public IP id=" + ipId + " release...");
-            if (!_firewallMgr.revokeFirewallRulesForIp(ipId, userId, caller)) {
-                s_logger.warn("Unable to revoke all the firewall rules for ip id=" + ipId + " as a part of ip release");
-                success = false;
-            }
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to revoke all firewall rules for ip id=" + ipId + " as a part of ip release", e);
-            success = false;
-        }
-
-        // Revoke all PF/Static nat rules for the ip
-        try {
-            s_logger.debug("Revoking all " + Purpose.PortForwarding + "/" + Purpose.StaticNat + " rules as a part of public IP id=" + ipId + " release...");
-            if (!_rulesMgr.revokeAllPFAndStaticNatRulesForIp(ipId, userId, caller)) {
-                s_logger.warn("Unable to revoke all the port forwarding rules for ip id=" + ipId + " as a part of ip release");
-                success = false;
-            }
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to revoke all the port forwarding rules for ip id=" + ipId + " as a part of ip release", e);
-            success = false;
-        }
-
-        s_logger.debug("Revoking all " + Purpose.LoadBalancing + " rules as a part of public IP id=" + ipId + " release...");
-        if (!_lbMgr.removeAllLoadBalanacersForIp(ipId, caller, userId)) {
-            s_logger.warn("Unable to revoke all the load balancer rules for ip id=" + ipId + " as a part of ip release");
-            success = false;
-        }
-
-        // remote access vpn can be enabled only for static nat ip, so this part should never be executed under normal
-        // conditions
-        // only when ip address failed to be cleaned up as a part of account destroy and was marked as Releasing, this part of
-        // the code would be triggered
-        s_logger.debug("Cleaning up remote access vpns as a part of public IP id=" + ipId + " release...");
-        try {
-            _vpnMgr.destroyRemoteAccessVpnForIp(ipId, caller,false);
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to destroy remote access vpn for ip id=" + ipId + " as a part of ip release", e);
-            success = false;
-        }
-
-        return success;
-    }
-
-    @Override
-    @DB
-    public boolean disassociatePublicIpAddress(long addrId, long userId, Account caller) {
-
-        boolean success = true;
-        // Cleanup all ip address resources - PF/LB/Static nat rules
-        if (!cleanupIpResources(addrId, userId, caller)) {
-            success = false;
-            s_logger.warn("Failed to release resources for ip address id=" + addrId);
-        }
-
-        IPAddressVO ip = markIpAsUnavailable(addrId);
-        if (ip == null) {
-            return true;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing ip id=" + addrId + "; sourceNat = " + ip.isSourceNat());
-        }
-
-        if (ip.getAssociatedWithNetworkId() != null) {
-            Network network = _networksDao.findById(ip.getAssociatedWithNetworkId());
-            try {
-                if (!applyIpAssociations(network, rulesContinueOnErrFlag)) {
-                    s_logger.warn("Unable to apply ip address associations for " + network);
-                    success = false;
-                }
-            } catch (ResourceUnavailableException e) {
-                throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
-            }
-        } else {
-            if (ip.getState() == IpAddress.State.Releasing) {
-                _ipAddressDao.unassignIpAddress(ip.getId());
-            }
-        }
-
-        if (success) {
-            if (ip.isPortable()) {
-                releasePortableIpAddress(addrId);
-            }
-            s_logger.debug("Released a public ip id=" + addrId);
-        }
-
-        return success;
-    }
-
-    @DB
-    @Override
-    public boolean releasePortableIpAddress(final long addrId) {
-        final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
-
-        try {
-            return Transaction.execute(new TransactionCallback<Boolean>() {
-                @Override
-                public Boolean doInTransaction(TransactionStatus status) {
-                    portableIpLock.lock(5);
-                    IPAddressVO ip = _ipAddressDao.findById(addrId);
-
-                    // unassign portable IP
-                    PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr());
-                    _portableIpDao.unassignIpAddress(portableIp.getId());
-
-                    // removed the provisioned vlan
-                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
-                    _vlanDao.remove(vlan.getId());
-
-                    // remove the provisioned public ip address
-                    _ipAddressDao.remove(ip.getId());
-
-                    return true;
-                }
-            });
-        } finally {
-            portableIpLock.releaseRef();
-        }
-    }
-
-    @Override
-    public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
-            throws InsufficientAddressCapacityException {
-        return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null, forSystemVms);
-    }
-
-    @Override
-    public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
-            throws InsufficientAddressCapacityException {
-        return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null, false);
-    }
-
-    @DB
-    public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId,
-            final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms)
-                    throws InsufficientAddressCapacityException {
-        IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
-            @Override
-            public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
-                StringBuilder errorMessage = new StringBuilder("Unable to get ip address in ");
-                boolean fetchFromDedicatedRange = false;
-                List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
-                List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
-                DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
-
-                SearchCriteria<IPAddressVO> sc = null;
-                if (podId != null) {
-                    sc = AssignIpAddressFromPodVlanSearch.create();
-                    sc.setJoinParameters("podVlanMapSB", "podId", podId);
-                    errorMessage.append(" pod id=" + podId);
-                } else {
-                    sc = AssignIpAddressSearch.create();
-                    errorMessage.append(" zone id=" + dcId);
-                }
-
-                // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
-                // Otherwise fetch IP from the system pool
-                Network network = _networksDao.findById(guestNetworkId);
-                //Checking if network is null in the case of system VM's. At the time of allocation of IP address to systemVm, no network is present.
-                if(network == null || !(network.getGuestType() == GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
-                    List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
-                    for (AccountVlanMapVO map : maps) {
-                        if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
-                            dedicatedVlanDbIds.add(map.getVlanDbId());
-                    }
-                }
-                List<DomainVlanMapVO> domainMaps = _domainVlanMapDao.listDomainVlanMapsByDomain(owner.getDomainId());
-                for (DomainVlanMapVO map : domainMaps) {
-                    if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
-                        dedicatedVlanDbIds.add(map.getVlanDbId());
-                }
-                List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
-                for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
-                    if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
-                        nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
-                }
-                if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
-                    fetchFromDedicatedRange = true;
-                    sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
-                    errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
-                } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
-                    sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                    errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
-                } else {
-                    if (podId != null) {
-                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
-                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
-                        throw ex;
-                    }
-                    s_logger.warn(errorMessage.toString());
-                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
-                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
-                    throw ex;
-                }
-
-                sc.setParameters("dc", dcId);
-
-                // for direct network take ip addresses only from the vlans belonging to the network
-                if (vlanUse == VlanType.DirectAttached) {
-                    sc.setJoinParameters("vlan", "networkId", guestNetworkId);
-                    errorMessage.append(", network id=" + guestNetworkId);
-                }
-                sc.setJoinParameters("vlan", "type", vlanUse);
-
-                if (requestedIp != null) {
-                    sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
-                    errorMessage.append(": requested ip " + requestedIp + " is not available");
-                }
-
-                boolean ascOrder = ! forSystemVms;
-                Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0l, 1l);
-                if (SystemVmPublicIpReservationModeStrictness.value()) {
-                    sc.setParameters("forSystemVms", forSystemVms);
-                }
-
-                filter.addOrderBy(IPAddressVO.class,"vlanId", true);
-
-                List<IPAddressVO> addrs = _ipAddressDao.search(sc, filter, false);
-
-                // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
-                if (addrs.size() == 0 && fetchFromDedicatedRange) {
-                    // Verify if account is allowed to acquire IPs from the system
-                    boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
-                    if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
-                        fetchFromDedicatedRange = false;
-                        sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                        errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
-                        addrs = _ipAddressDao.search(sc, filter, false);
-                    }
-                }
-
-                if (addrs.size() == 0) {
-                    if (podId != null) {
-                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
-                        // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
-                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
-                        throw ex;
-                    }
-                    s_logger.warn(errorMessage.toString());
-                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
-                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
-                    throw ex;
-                }
-
-                assert(addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
-
-                if (!fetchFromDedicatedRange && VlanType.VirtualNetwork.equals(vlanUse)) {
-                    // Check that the maximum number of public IPs for the given accountId will not be exceeded
-                    try {
-                        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
-                    } catch (ResourceAllocationException ex) {
-                        s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
-                        throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
-                    }
-                }
-
-                IPAddressVO finalAddr = null;
-                for (final IPAddressVO possibleAddr: addrs) {
-                    if (possibleAddr.getState() != IpAddress.State.Free) {
-                        continue;
-                    }
-                    final IPAddressVO addr = possibleAddr;
-                    addr.setSourceNat(sourceNat);
-                    addr.setAllocatedTime(new Date());
-                    addr.setAllocatedInDomainId(owner.getDomainId());
-                    addr.setAllocatedToAccountId(owner.getId());
-                    addr.setSystem(isSystem);
-
-                    if (displayIp != null) {
-                        addr.setDisplay(displayIp);
-                    }
-
-                    if (vlanUse != VlanType.DirectAttached) {
-                        addr.setAssociatedWithNetworkId(guestNetworkId);
-                        addr.setVpcId(vpcId);
-                    }
-                    if (_ipAddressDao.lockRow(possibleAddr.getId(), true) != null) {
-                        final IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
-                        if (userIp.getState() == IpAddress.State.Free) {
-                            addr.setState(IpAddress.State.Allocating);
-                            if (_ipAddressDao.update(addr.getId(), addr)) {
-                                finalAddr = addr;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                if (finalAddr == null) {
-                    s_logger.error("Failed to fetch any free public IP address");
-                    throw new CloudRuntimeException("Failed to fetch any free public IP address");
-                }
-
-                if (assign) {
-                    markPublicIpAsAllocated(finalAddr);
-                }
-
-                final State expectedAddressState = assign ? State.Allocated : State.Allocating;
-                if (finalAddr.getState() != expectedAddressState) {
-                    s_logger.error("Failed to fetch new public IP and get in expected state=" + expectedAddressState);
-                    throw new CloudRuntimeException("Failed to fetch new public IP with expected state " + expectedAddressState);
-                }
-
-                return finalAddr;
-            }
-        });
-
-        if (vlanUse == VlanType.VirtualNetwork) {
-            _firewallMgr.addSystemFirewallRules(addr, owner);
-        }
-
-        return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
-    }
-
-    @DB
-    @Override
-    public void markPublicIpAsAllocated(final IPAddressVO addr) {
-        synchronized (allocatedLock) {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
-                    if (_ipAddressDao.lockRow(addr.getId(), true) != null) {
-                        final IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
-                        if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) {
-                            addr.setState(IpAddress.State.Allocated);
-                            if (_ipAddressDao.update(addr.getId(), addr)) {
-                                // Save usage event
-                                if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
-                                    VlanVO vlan = _vlanDao.findById(addr.getVlanId());
-                                    String guestType = vlan.getVlanType().toString();
-                                    if (!isIpDedicated(addr)) {
-                                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(),
-                                                addr.getAddress().toString(),
-                                                addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid());
-                                    }
-                                    if (updateIpResourceCount(addr)) {
-                                        _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
-                                    }
-                                }
-                            } else {
-                                s_logger.error("Failed to mark public IP as allocated with id=" + addr.getId() + " address=" + addr.getAddress());
-                            }
-                        }
-                    } else {
-                        s_logger.error("Failed to acquire row lock to mark public IP as allocated with id=" + addr.getId() + " address=" + addr.getAddress());
-                    }
-                }
-            });
-        }
-    }
-
-    private boolean isIpDedicated(IPAddressVO addr) {
-        List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(addr.getVlanId());
-        if (maps != null && !maps.isEmpty())
-            return true;
-        return false;
-    }
-
-    @Override
-    public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException {
-        assert(guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network "
-                + "can't participate in source nat.  What do you have to say for yourself?";
-        long dcId = guestNetwork.getDataCenterId();
-
-        IPAddressVO sourceNatIp = getExistingSourceNatInNetwork(owner.getId(), guestNetwork.getId());
-
-        PublicIp ipToReturn = null;
-        if (sourceNatIp != null) {
-            ipToReturn = PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
-        } else {
-            ipToReturn = assignDedicateIpAddress(owner, guestNetwork.getId(), null, dcId, true);
-        }
-
-        return ipToReturn;
-    }
-
-    @DB
-    @Override
-    public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat)
-            throws ConcurrentOperationException, InsufficientAddressCapacityException {
-
-        final long ownerId = owner.getId();
-
-        PublicIp ip = null;
-        try {
-            ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
-                @Override
-                public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
-                    Account owner = _accountDao.acquireInLockTable(ownerId);
-
-                    if (owner == null) {
-                        // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class
-                        // to get the table name and field name that is queried to fill this ownerid.
-                        ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account");
-                        throw ex;
-                    }
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("lock account " + ownerId + " is acquired");
-                    }
-                    boolean displayIp = true;
-                    if (guestNtwkId != null) {
-                        Network ntwk = _networksDao.findById(guestNtwkId);
-                        displayIp = ntwk.getDisplayNetwork();
-                    } else if (vpcId != null) {
-                        VpcVO vpc = _vpcDao.findById(vpcId);
-                        displayIp = vpc.isDisplay();
-                    }
-                    return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, false, vpcId, displayIp, false);
-                }
-            });
-            if (ip.getState() != State.Allocated) {
-                s_logger.error("Failed to fetch new IP and allocate it for ip with id=" + ip.getId() + ", address=" + ip.getAddress());
-            }
-            return ip;
-        } finally {
-            if (owner != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Releasing lock account " + ownerId);
-                }
-
-                _accountDao.releaseFromLockTable(ownerId);
-            }
-            if (ip == null) {
-                s_logger.error("Unable to get source nat ip address for account " + ownerId);
-            }
-        }
-    }
-
-    @Override
-    public boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException {
-        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
-        boolean success = true;
-        // CloudStack will take a lazy approach to associate an acquired public IP to a network service provider as
-        // it will not know what service an acquired IP will be used for. An IP is actually associated with a provider when first
-        // rule is applied. Similarly when last rule on the acquired IP is revoked, IP is not associated with any provider
-        // but still be associated with the account. At this point just mark IP as allocated or released.
-        for (IPAddressVO addr : userIps) {
-            if (addr.getState() == IpAddress.State.Allocating) {
-                addr.setAssociatedWithNetworkId(network.getId());
-                markPublicIpAsAllocated(addr);
-            } else if (addr.getState() == IpAddress.State.Releasing) {
-                // Cleanup all the resources for ip address if there are any, and only then un-assign ip in the system
-                if (cleanupIpResources(addr.getId(), Account.ACCOUNT_ID_SYSTEM, _accountMgr.getSystemAccount())) {
-                    _ipAddressDao.unassignIpAddress(addr.getId());
-                } else {
-                    success = false;
-                    s_logger.warn("Failed to release resources for ip address id=" + addr.getId());
-                }
-            }
-        }
-        return success;
-    }
-
-    // CloudStack will take a lazy approach to associate an acquired public IP to a network service provider as
-    // it will not know what a acquired IP will be used for. An IP is actually associated with a provider when first
-    // rule is applied. Similarly when last rule on the acquired IP is revoked, IP is not associated with any provider
-    // but still be associated with the account. Its up to caller of this function to decide when to invoke IPAssociation
-    @Override
-    public boolean applyIpAssociations(Network network, boolean postApplyRules, boolean continueOnError, List<? extends PublicIpAddress> publicIps)
-            throws ResourceUnavailableException {
-        boolean success = true;
-
-        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(publicIps, postApplyRules, true);
-        Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = _networkModel.getProviderToIpList(network, ipToServices);
-
-        for (Provider provider : providerToIpList.keySet()) {
-            try {
-                ArrayList<PublicIpAddress> ips = providerToIpList.get(provider);
-                if (ips == null || ips.isEmpty()) {
-                    continue;
-                }
-                IpDeployer deployer = null;
-                NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
-                if (!(element instanceof IpDeployingRequester)) {
-                    throw new CloudRuntimeException("Element " + element + " is not a IpDeployingRequester!");
-                }
-                deployer = ((IpDeployingRequester)element).getIpDeployer(network);
-                if (deployer == null) {
-                    throw new CloudRuntimeException("Fail to get ip deployer for element: " + element);
-                }
-                Set<Service> services = new HashSet<Service>();
-                for (PublicIpAddress ip : ips) {
-                    if (!ipToServices.containsKey(ip)) {
-                        continue;
-                    }
-                    services.addAll(ipToServices.get(ip));
-                }
-                deployer.applyIps(network, ips, services);
-            } catch (ResourceUnavailableException e) {
-                success = false;
-                if (!continueOnError) {
-                    throw e;
-                } else {
-                    s_logger.debug("Resource is not available: " + provider.getName(), e);
-                }
-            }
-        }
-
-        return success;
-    }
-
-    @DB
-    @Override
-    public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException {
-
-        DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId);
-        Account caller = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            ResourceAllocationException ex = new ResourceAllocationException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + zone.getUuid(),
-                    ResourceType.network);
-            throw ex;
-        }
-
-        DataCenterIpAddressVO vo = null;
-        if (podId == null)
-            throw new ResourceAllocationException("Please do not provide NULL podId", ResourceType.network);
-        HostPodVO podvo = null;
-        podvo = _hpDao.findByUuid(podId);
-        if (podvo == null)
-            throw new ResourceAllocationException("No sush pod exists", ResourceType.network);
-
-        vo = _privateIPAddressDao.takeIpAddress(zone.getId(), podvo.getId(), 0, caller.getId() + "", false);
-        if(vo == null)
-            throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
-        if (vo.getIpAddress() == null)
-            throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
-
-        HostPodVO pod_vo = _hpDao.findById(vo.getPodId());
-        AcquirePodIpCmdResponse ret = new AcquirePodIpCmdResponse();
-        ret.setCidrAddress(pod_vo.getCidrAddress());
-        ret.setGateway(pod_vo.getGateway());
-        ret.setInstanceId(vo.getInstanceId());
-        ret.setIpAddress(vo.getIpAddress());
-        ret.setMacAddress(vo.getMacAddress());
-        ret.setPodId(vo.getPodId());
-        ret.setId(vo.getId());
-
-        return ret;
-    }
-
-    @DB
-    @Override
-    public void releasePodIp(Long id) throws CloudRuntimeException {
-
-        // Verify input parameters
-        DataCenterIpAddressVO ipVO = _privateIPAddressDao.findById(id);
-        if (ipVO == null) {
-            throw new CloudRuntimeException("Unable to find ip address by id:" + id);
-        }
-
-        if (ipVO.getTakenAt() == null) {
-            s_logger.debug("Ip Address with id= " + id + " is not allocated, so do nothing.");
-            throw new CloudRuntimeException("Ip Address  with id= " + id + " is not allocated, so do nothing.");
-        }
-        // Verify permission
-        DataCenter zone = _entityMgr.findById(DataCenter.class, ipVO.getDataCenterId());
-        Account caller = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new CloudRuntimeException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + ipVO.getDataCenterId());
-        }
-        try {
-            _privateIPAddressDao.releasePodIpAddress(id);
-        } catch (Exception e) {
-            new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @DB
-    @Override
-    public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone, final Boolean displayIp)
-            throws ConcurrentOperationException,
-            ResourceAllocationException, InsufficientAddressCapacityException {
-
-        final VlanType vlanType = VlanType.VirtualNetwork;
-        final boolean assign = false;
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            // zone is of type DataCenter. See DataCenterVO.java.
-            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, " + "Zone is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "zoneId");
-            throw ex;
-        }
-
-        PublicIp ip = null;
-
-        Account accountToLock = null;
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
-            }
-            accountToLock = _accountDao.acquireInLockTable(ipOwner.getId());
-            if (accountToLock == null) {
-                s_logger.warn("Unable to lock account: " + ipOwner.getId());
-                throw new ConcurrentOperationException("Unable to acquire account lock");
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Associate IP address lock acquired");
-            }
-
-            ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
-                @Override
-                public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
-                    PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp, false);
-
-                    if (ip == null) {
-                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone
-                                .getId());
-                        ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
-                        throw ex;
-
-                    }
-                    CallContext.current().setEventDetails("Ip Id: " + ip.getId());
-                    Ip ipAddress = ip.getAddress();
-
-                    s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
-
-                    return ip;
-                }
-            });
-
-        } finally {
-            if (accountToLock != null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Releasing lock account " + ipOwner);
-                }
-                _accountDao.releaseFromLockTable(ipOwner.getId());
-                s_logger.debug("Associate IP address lock released");
-            }
-        }
-        return ip;
-    }
-
-    @Override
-    @DB
-    public IpAddress allocatePortableIp(final Account ipOwner, Account caller, final long dcId, final Long networkId, final Long vpcID)
-            throws ConcurrentOperationException,
-            ResourceAllocationException, InsufficientAddressCapacityException {
-
-        GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
-        IPAddressVO ipaddr;
-
-        try {
-            portableIpLock.lock(5);
-
-            ipaddr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
-                @Override
-                public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
-                    PortableIpVO allocatedPortableIp;
-
-                    List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
-                    if (portableIpVOs == null || portableIpVOs.isEmpty()) {
-                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class,
-                                new Long(1));
-                        throw ex;
-                    }
-
-                    // allocate first portable IP to the user
-                    allocatedPortableIp = portableIpVOs.get(0);
-                    allocatedPortableIp.setAllocatedTime(new Date());
-                    allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId());
-                    allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId());
-                    allocatedPortableIp.setState(PortableIp.State.Allocated);
-                    _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp);
-
-                    // To make portable IP available as a zone level resource we need to emulate portable IP's (which are
-                    // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the
-                    // identity of a public IP in zone. Create entry for portable ip in these tables.
-
-                    // provision portable IP range VLAN into the zone
-                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId();
-                    Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
-                    String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress();
-                    VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, allocatedPortableIp.getVlan(), allocatedPortableIp.getGateway(), allocatedPortableIp.getNetmask(), dcId,
-                            range, network.getId(), physicalNetworkId, null, null, null);
-                    vlan = _vlanDao.persist(vlan);
-
-                    // provision the portable IP in to user_ip_address table
-                    IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true);
-                    ipaddr.setState(State.Allocated);
-                    ipaddr.setAllocatedTime(new Date());
-                    ipaddr.setAllocatedInDomainId(ipOwner.getDomainId());
-                    ipaddr.setAllocatedToAccountId(ipOwner.getId());
-                    ipaddr = _ipAddressDao.persist(ipaddr);
-
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, ipaddr.getId(), ipaddr.getDataCenterId(), ipaddr.getId(),
-                            ipaddr.getAddress().toString(), ipaddr.isSourceNat(), null, ipaddr.getSystem(), ipaddr.getClass().getName(), ipaddr.getUuid());
-
-                    return ipaddr;
-                }
-            });
-        } finally {
-            portableIpLock.unlock();
-        }
-
-        return ipaddr;
-    }
-
-    protected IPAddressVO getExistingSourceNatInNetwork(long ownerId, Long networkId) {
-        List<? extends IpAddress> addrs;
-        Network guestNetwork = _networksDao.findById(networkId);
-        if (guestNetwork.getGuestType() == GuestType.Shared) {
-            // ignore the account id for the shared network
-            addrs = _networkModel.listPublicIpsAssignedToGuestNtwk(networkId, true);
-        } else {
-            addrs = _networkModel.listPublicIpsAssignedToGuestNtwk(ownerId, networkId, true);
-        }
-
-        IPAddressVO sourceNatIp = null;
-        if (addrs.isEmpty()) {
-            return null;
-        } else {
-            // Account already has ip addresses
-            for (IpAddress addr : addrs) {
-                if (addr.isSourceNat()) {
-                    sourceNatIp = _ipAddressDao.findById(addr.getId());
-                    return sourceNatIp;
-                }
-            }
-
-            assert(sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; networkId=" + networkId;
-        }
-
-        return sourceNatIp;
-    }
-
-    @DB
-    @Override
-    public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException {
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = null;
-
-        IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId);
-        if (ipToAssoc != null) {
-            Network network = _networksDao.findById(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Invalid network id is given");
-            }
-
-            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-            if (zone.getNetworkType() == NetworkType.Advanced) {
-                if (network.getGuestType() == Network.GuestType.Shared) {
-                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
-                        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false,
-                                network);
-                    } else {
-                        throw new InvalidParameterValueException("IP can be associated with guest network of 'shared' type only if "
-                                + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network");
-                    }
-                }
-            } else {
-                _accountMgr.checkAccess(caller, null, true, ipToAssoc);
-            }
-            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
-        } else {
-            s_logger.debug("Unable to find ip address by id: " + ipId);
-            return null;
-        }
-
-        if (ipToAssoc.getAssociatedWithNetworkId() != null) {
-            s_logger.debug("IP " + ipToAssoc + " is already assocaited with network id" + networkId);
-            return ipToAssoc;
-        }
-
-        Network network = _networksDao.findById(networkId);
-        if (network != null) {
-            _accountMgr.checkAccess(owner, AccessType.UseEntry, false, network);
-        } else {
-            s_logger.debug("Unable to find ip address by id: " + ipId);
-            return null;
-        }
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-
-        // allow associating IP addresses to guest network only
-        if (network.getTrafficType() != TrafficType.Guest) {
-            throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest);
-        }
-
-        // Check that network belongs to IP owner - skip this check
-        //     - if zone is basic zone as there is just one guest network,
-        //     - if shared network in Advanced zone
-        //     - and it belongs to the system
-        if (network.getAccountId() != owner.getId()) {
-            if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
-                throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
-            }
-        }
-
-        if (zone.getNetworkType() == NetworkType.Advanced) {
-            // In Advance zone allow to do IP assoc only for Isolated networks with source nat service enabled
-            if (network.getGuestType() == GuestType.Isolated && !(_networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) {
-                if (releaseOnFailure && ipToAssoc != null) {
-                    s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
-                    _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
-                }
-                throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated only to the network of guest type "
-                        + GuestType.Isolated + " with the " + Service.SourceNat.getName() + " enabled");
-            }
-
-            // In Advance zone allow to do IP assoc only for shared networks with source nat/static nat/lb/pf services enabled
-            if (network.getGuestType() == GuestType.Shared && !isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
-                if (releaseOnFailure && ipToAssoc != null) {
-                    s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
-                    _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
-                }
-                throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated with network of guest type " + GuestType.Shared
-                        + "only if at " + "least one of the services " + Service.SourceNat.getName() + "/" + Service.StaticNat.getName() + "/" + Service.Lb.getName() + "/"
-                        + Service.PortForwarding.getName() + " is enabled");
-            }
-        }
-
-        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        boolean sharedSourceNat = offering.getSharedSourceNat();
-        boolean isSourceNat = false;
-        if (!sharedSourceNat) {
-            if (getExistingSourceNatInNetwork(owner.getId(), networkId) == null) {
-                if (network.getGuestType() == GuestType.Isolated && network.getVpcId() == null && !ipToAssoc.isPortable()) {
-                    isSourceNat = true;
-                }
-            }
-        }
-
-        s_logger.debug("Associating ip " + ipToAssoc + " to network " + network);
-
-        IPAddressVO ip = _ipAddressDao.findById(ipId);
-        //update ip address with networkId
-        ip.setAssociatedWithNetworkId(networkId);
-        ip.setSourceNat(isSourceNat);
-        _ipAddressDao.update(ipId, ip);
-
-        boolean success = false;
-        try {
-            success = applyIpAssociations(network, false);
-            if (success) {
-                s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
-            } else {
-                s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
-            }
-            return ip;
-        } finally {
-            if (!success && releaseOnFailure) {
-                if (ip != null) {
-                    try {
-                        s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip);
-                        _ipAddressDao.markAsUnavailable(ip.getId());
-                        if (!applyIpAssociations(network, true)) {
-                            // if fail to apply ip assciations again, unassign ip address without updating resource
-                            // count and generating usage event as there is no need to keep it in the db
-                            _ipAddressDao.unassignIpAddress(ip.getId());
-                        }
-                    } catch (Exception e) {
-                        s_logger.warn("Unable to disassociate ip address for recovery", e);
-                    }
-                }
-            }
-        }
-    }
-
-    protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
-        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
-        if ((networkOffering.getGuestType() == Network.GuestType.Shared)
-                && (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
-                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
-                                networkOfferingId, Service.Lb))) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException {
-        return associateIPToGuestNetwork(ipAddrId, networkId, releaseOnFailure);
-    }
-
-    @DB
-    @Override
-    public IPAddressVO disassociatePortableIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = null;
-
-        Network network = _networksDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId);
-        if (ipToAssoc != null) {
-
-            if (ipToAssoc.getAssociatedWithNetworkId() == null) {
-                throw new InvalidParameterValueException("IP " + ipToAssoc + " is not associated with any network");
-            }
-
-            if (ipToAssoc.getAssociatedWithNetworkId() != network.getId()) {
-                throw new InvalidParameterValueException("IP " + ipToAssoc + " is not associated with network id" + networkId);
-            }
-
-            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-            if (zone.getNetworkType() == NetworkType.Advanced) {
-                if (network.getGuestType() == Network.GuestType.Shared) {
-                    assert(isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()));
-                    _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false,
-                            network);
-                }
-            } else {
-                _accountMgr.checkAccess(caller, null, true, ipToAssoc);
-            }
-            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
-        } else {
-            s_logger.debug("Unable to find ip address by id: " + ipId);
-            return null;
-        }
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-
-        // Check that network belongs to IP owner - skip this check
-        //     - if zone is basic zone as there is just one guest network,
-        //     - if shared network in Advanced zone
-        //     - and it belongs to the system
-        if (network.getAccountId() != owner.getId()) {
-            if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
-                throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
-            }
-        }
-
-        // Check if IP has any services (rules) associated in the network
-        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
-        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipToAssoc, _vlanDao.findById(ipToAssoc.getVlanId()));
-        ipList.add(publicIp);
-        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(ipList, false, true);
-        if (!ipToServices.isEmpty()) {
-            Set<Service> services = ipToServices.get(publicIp);
-            if (services != null && !services.isEmpty()) {
-                throw new InvalidParameterValueException("IP " + ipToAssoc + " has services and rules associated in the network " + networkId);
-            }
-        }
-
-        IPAddressVO ip = _ipAddressDao.findById(ipId);
-        ip.setAssociatedWithNetworkId(null);
-        _ipAddressDao.update(ipId, ip);
-
-        try {
-            boolean success = applyIpAssociations(network, false);
-            if (success) {
-                s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
-            } else {
-                s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
-            }
-            return ip;
-        } finally {
-
-        }
-    }
-
-    @Override
-    public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) {
-        Network network = _networksDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        IPAddressVO ip = _ipAddressDao.findById(ipAddrId);
-        if (ip == null) {
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        // Check if IP has any services (rules) associated in the network
-        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
-        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId()));
-        ipList.add(publicIp);
-        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(ipList, false, true);
-        if (!ipToServices.isEmpty()) {
-            Set<Service> ipServices = ipToServices.get(publicIp);
-            if (ipServices != null && !ipServices.isEmpty()) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @DB
-    @Override
-    public void transferPortableIP(final long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
-            InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        Network srcNetwork = _networksDao.findById(currentNetworkId);
-        if (srcNetwork == null) {
-            throw new InvalidParameterValueException("Invalid source network id " + currentNetworkId + " is given");
-        }
-
-        final Network dstNetwork = _networksDao.findById(newNetworkId);
-        if (dstNetwork == null) {
-            throw new InvalidParameterValueException("Invalid source network id " + newNetworkId + " is given");
-        }
-
-        final IPAddressVO ip = _ipAddressDao.findById(ipAddrId);
-        if (ip == null) {
-            throw new InvalidParameterValueException("Invalid portable ip address id is given");
-        }
-
-        assert(isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId));
-
-        // disassociate portable IP with current network/VPC network
-        if (srcNetwork.getVpcId() != null) {
-            _vpcMgr.unassignIPFromVpcNetwork(ipAddrId, currentNetworkId);
-        } else {
-            disassociatePortableIPToGuestNetwork(ipAddrId, currentNetworkId);
-        }
-
-        // If portable IP need to be transferred across the zones, then mark the entry corresponding to portable ip
-        // in user_ip_address and vlan tables so as to emulate portable IP as provisioned in destination data center
-        if (srcNetwork.getDataCenterId() != dstNetwork.getDataCenterId()) {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
-                    long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
-
-                    ip.setDataCenterId(dstNetwork.getDataCenterId());
-                    ip.setPhysicalNetworkId(physicalNetworkId);
-                    ip.setSourceNetworkId(publicNetworkId);
-                    _ipAddressDao.update(ipAddrId, ip);
-
-                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
-                    vlan.setPhysicalNetworkId(physicalNetworkId);
-                    vlan.setNetworkId(publicNetworkId);
-                    vlan.setDataCenterId(dstNetwork.getDataCenterId());
-                    _vlanDao.update(ip.getVlanId(), vlan);
-                }
-            });
-        }
-
-        // associate portable IP with new network/VPC network
-        associatePortableIPToGuestNetwork(ipAddrId, newNetworkId, false);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                if (dstNetwork.getVpcId() != null) {
-                    ip.setVpcId(dstNetwork.getVpcId());
-                } else {
-                    ip.setVpcId(null);
-                }
-
-                _ipAddressDao.update(ipAddrId, ip);
-            }
-
-        });
-
-        // trigger an action event for the transfer of portable IP across the networks, so that external entities
-        // monitoring for this event can initiate the route advertisement for the availability of IP from the zoe
-        ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, Domain.ROOT_DOMAIN, EventTypes.EVENT_PORTABLE_IP_TRANSFER,
-                "Portable IP associated is transferred from network " + currentNetworkId + " to " + newNetworkId);
-    }
-
-    protected List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
-
-        return _networksDao.listSourceNATEnabledNetworks(owner.getId(), zoneId, Network.GuestType.Isolated);
-    }
-
-    @Override
-    @DB
-    public boolean associateIpAddressListToAccount(long userId, final long accountId, final long zoneId, final Long vlanId, final Network guestNetworkFinal)
-            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException {
-        final Account owner = _accountMgr.getActiveAccountById(accountId);
-
-        if (guestNetworkFinal != null && guestNetworkFinal.getTrafficType() != TrafficType.Guest) {
-            throw new InvalidParameterValueException("Network " + guestNetworkFinal + " is not of a type " + TrafficType.Guest);
-        }
-
-        Ternary<Boolean, List<NetworkOfferingVO>, Network> pair = null;
-        try {
-            pair = Transaction.execute(new TransactionCallbackWithException<Ternary<Boolean, List<NetworkOfferingVO>, Network>, Exception>() {
-                @Override
-                public Ternary<Boolean, List<NetworkOfferingVO>, Network> doInTransaction(TransactionStatus status) throws InsufficientCapacityException,
-                        ResourceAllocationException {
-                    boolean createNetwork = false;
-                    Network guestNetwork = guestNetworkFinal;
-
-                    if (guestNetwork == null) {
-                        List<? extends Network> networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner);
-                        if (networks.size() == 0) {
-                            createNetwork = true;
-                        } else if (networks.size() == 1) {
-                            guestNetwork = networks.get(0);
-                        } else {
-                            throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT "
-                                    + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID");
-                        }
-                    }
-
-                    // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist
-                    List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-                    if (requiredOfferings.size() < 1) {
-                        throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required
-                                + " to automatically create the network as part of createVlanIpRange");
-                    }
-                    if (createNetwork) {
-                        if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
-                            long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
-                            // Validate physical network
-                            PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-                            if (physicalNetwork == null) {
-                                throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
-                                        + requiredOfferings.get(0).getTags());
-                            }
-
-                            s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
-                                    + " as a part of createVlanIpRange process");
-                            guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
-                                    + "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null);
-                            if (guestNetwork == null) {
-                                s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
-                                throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "
-                                        + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId);
-                            }
-                        } else {
-                            throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
-                        }
-                    }
-
-                    // Check if there is a source nat ip address for this account; if not - we have to allocate one
-                    boolean allocateSourceNat = false;
-                    List<IPAddressVO> sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true);
-                    if (sourceNat.isEmpty()) {
-                        allocateSourceNat = true;
-                    }
-
-                    // update all ips with a network id, mark them as allocated and update resourceCount/usage
-                    List<IPAddressVO> ips = _ipAddressDao.listByVlanId(vlanId);
-                    boolean isSourceNatAllocated = false;
-                    for (IPAddressVO addr : ips) {
-                        if (addr.getState() != State.Allocated) {
-                            if (!isSourceNatAllocated && allocateSourceNat) {
-                                addr.setSourceNat(true);
-                                isSourceNatAllocated = true;
-                            } else {
-                                addr.setSourceNat(false);
-                            }
-                            addr.setAssociatedWithNetworkId(guestNetwork.getId());
-                            addr.setVpcId(guestNetwork.getVpcId());
-                            addr.setAllocatedTime(new Date());
-                            addr.setAllocatedInDomainId(owner.getDomainId());
-                            addr.setAllocatedToAccountId(owner.getId());
-                            addr.setSystem(false);
-                            addr.setState(IpAddress.State.Allocating);
-                            markPublicIpAsAllocated(addr);
-                        }
-                    }
-                    return new Ternary<Boolean, List<NetworkOfferingVO>, Network>(createNetwork, requiredOfferings, guestNetwork);
-                }
-            });
-        } catch (Exception e1) {
-            ExceptionUtil.rethrowRuntime(e1);
-            ExceptionUtil.rethrow(e1, InsufficientCapacityException.class);
-            ExceptionUtil.rethrow(e1, ResourceAllocationException.class);
-            throw new IllegalStateException(e1);
-        }
-
-        boolean createNetwork = pair.first();
-        List<NetworkOfferingVO> requiredOfferings = pair.second();
-        Network guestNetwork = pair.third();
-
-        // if the network offering has persistent set to true, implement the network
-        if (createNetwork && requiredOfferings.get(0).getIsPersistent()) {
-            DataCenter zone = _dcDao.findById(zoneId);
-            DeployDestination dest = new DeployDestination(zone, null, null, null);
-            Account callerAccount = CallContext.current().getCallingAccount();
-            UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
-            Journal journal = new Journal.LogJournal("Implementing " + guestNetwork, s_logger);
-            ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, callerAccount);
-            s_logger.debug("Implementing network " + guestNetwork + " as a part of network provision for persistent network");
-            try {
-                Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(guestNetwork.getId(), dest, context);
-                if (implementedNetwork == null || implementedNetwork.first() == null) {
-                    s_logger.warn("Failed to implement the network " + guestNetwork);
-                }
-                if (implementedNetwork != null) {
-                    guestNetwork = implementedNetwork.second();
-                }
-            } catch (Exception ex) {
-                s_logger.warn("Failed to implement network " + guestNetwork + " elements and resources as a part of" + " network provision due to ", ex);
-                CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id)"
-                        + " elements and resources as a part of network provision for persistent network");
-                e.addProxyObject(guestNetwork.getUuid(), "networkId");
-                throw e;
-            }
-        }
-        return true;
-    }
-
-    @DB
-    @Override
-    public IPAddressVO markIpAsUnavailable(final long addrId) {
-        final IPAddressVO ip = _ipAddressDao.findById(addrId);
-
-        if (ip.getAllocatedToAccountId() == null && ip.getAllocatedTime() == null) {
-            s_logger.trace("Ip address id=" + addrId + " is already released");
-            return ip;
-        }
-
-        if (ip.getState() != State.Releasing) {
-            return Transaction.execute(new TransactionCallback<IPAddressVO>() {
-                @Override
-                public IPAddressVO doInTransaction(TransactionStatus status) {
-                    if (updateIpResourceCount(ip)) {
-                        _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip);
-                    }
-
-                    // Save usage event
-                    if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) {
-                        VlanVO vlan = _vlanDao.findById(ip.getVlanId());
-
-                        String guestType = vlan.getVlanType().toString();
-                        if (!isIpDedicated(ip)) {
-                            String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE;
-                            UsageEventUtils.publishUsageEvent(eventType, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(),
-                                    guestType, ip.getSystem(), ip.getClass().getName(), ip.getUuid());
-                        }
-                    }
-
-                    return _ipAddressDao.markAsUnavailable(addrId);
-                }
-            });
-        }
-
-        return ip;
-    }
-
-    protected boolean updateIpResourceCount(IPAddressVO ip) {
-        // don't increment resource count for direct and dedicated ip addresses
-        return (ip.getAssociatedWithNetworkId() != null || ip.getVpcId() != null) && !isIpDedicated(ip);
-    }
-
-    @Override
-    @DB
-    public String acquireGuestIpAddress(Network network, String requestedIp) {
-        if (requestedIp != null && requestedIp.equals(network.getGateway())) {
-            s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network);
-            return null;
-        }
-
-        if (_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty() && network.getCidr() == null) {
-            return null;
-        }
-
-        Set<Long> availableIps = _networkModel.getAvailableIps(network, requestedIp);
-
-        if (availableIps == null || availableIps.isEmpty()) {
-            s_logger.debug("There are no free ips in the  network " + network);
-            return null;
-        }
-
-        Long[] array = availableIps.toArray(new Long[availableIps.size()]);
-
-        if (requestedIp != null) {
-            // check that requested ip has the same cidr
-            String[] cidr = network.getCidr().split("/");
-            boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1]));
-            if (!isSameCidr) {
-                s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr");
-                return null;
-            } else if (NetUtils.IsIpEqualToNetworkOrBroadCastIp(requestedIp, cidr[0], Integer.parseInt(cidr[1]))) {
-                s_logger.warn("Requested ip address " + requestedIp + " is equal to the to the network/broadcast ip of the network" + network);
-                return null;
-            }
-            return requestedIp;
-        }
-
-        return NetUtils.long2Ip(array[_rand.nextInt(array.length)]);
-    }
-
-    Random _rand = new Random(System.currentTimeMillis());
-
-    /**
-     * Get the list of public IPs that need to be applied for a static NAT enable/disable operation.
-     * Manipulating only these ips prevents concurrency issues when disabling static nat at the same time.
-     * @param staticNats
-     * @return The list of IPs that need to be applied for the static NAT to work.
-     */
-    public List<IPAddressVO> getStaticNatSourceIps(List<? extends StaticNat> staticNats) {
-        List<IPAddressVO> userIps = new ArrayList<>();
-
-        for (StaticNat snat : staticNats) {
-            userIps.add(_ipAddressDao.findById(snat.getSourceIpAddressId()));
-        }
-
-        return userIps;
-    }
-
-    @Override
-    public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException {
-        if (staticNats == null || staticNats.size() == 0) {
-            s_logger.debug("There are no static nat rules for the network elements");
-            return true;
-        }
-
-        Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
-        boolean success = true;
-
-        // Check if the StaticNat service is supported
-        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
-            s_logger.debug("StaticNat service is not supported in specified network id");
-            return true;
-        }
-
-        List<IPAddressVO> userIps = getStaticNatSourceIps(staticNats);
-
-        List<PublicIp> publicIps = new ArrayList<PublicIp>();
-        if (userIps != null && !userIps.isEmpty()) {
-            for (IPAddressVO userIp : userIps) {
-                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                publicIps.add(publicIp);
-            }
-        }
-
-        // static NAT rules can not programmed unless IP is associated with source NAT service provider, so run IP
-        // association for the network so as to ensure IP is associated before applying rules
-        if (checkStaticNatIPAssocRequired(network, false, forRevoke, publicIps)) {
-            applyIpAssociations(network, false, continueOnError, publicIps);
-        }
-
-        // get provider
-        StaticNatServiceProvider element = _networkMgr.getStaticNatProviderForNetwork(network);
-        try {
-            success = element.applyStaticNats(network, staticNats);
-        } catch (ResourceUnavailableException e) {
-            if (!continueOnError) {
-                throw e;
-            }
-            s_logger.warn("Problems with " + element.getName() + " but pushing on", e);
-            success = false;
-        }
-
-        // For revoked static nat IP, set the vm_id to null, indicate it should be revoked
-        for (StaticNat staticNat : staticNats) {
-            if (staticNat.isForRevoke()) {
-                for (PublicIp publicIp : publicIps) {
-                    if (publicIp.getId() == staticNat.getSourceIpAddressId()) {
-                        publicIps.remove(publicIp);
-                        IPAddressVO ip = _ipAddressDao.findByIdIncludingRemoved(staticNat.getSourceIpAddressId());
-                        // ip can't be null, otherwise something wrong happened
-                        ip.setAssociatedWithVmId(null);
-                        publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId()));
-                        publicIps.add(publicIp);
-                        break;
-                    }
-                }
-            }
-        }
-
-        // if the static NAT rules configured on public IP is revoked then, dis-associate IP with static NAT service provider
-        if (checkStaticNatIPAssocRequired(network, true, forRevoke, publicIps)) {
-            applyIpAssociations(network, true, continueOnError, publicIps);
-        }
-
-        return success;
-    }
-
-    // checks if there are any public IP assigned to network, that are marked for one-to-one NAT that
-    // needs to be associated/dis-associated with static-nat provider
-    boolean checkStaticNatIPAssocRequired(Network network, boolean postApplyRules, boolean forRevoke, List<PublicIp> publicIps) {
-        for (PublicIp ip : publicIps) {
-            if (ip.isOneToOneNat()) {
-                Long activeFwCount = null;
-                activeFwCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active);
-
-                if (!postApplyRules && !forRevoke) {
-                    if (activeFwCount > 0) {
-                        continue;
-                    } else {
-                        return true;
-                    }
-                } else if (postApplyRules && forRevoke) {
-                    return true;
-                }
-            } else {
-                continue;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException {
-        Network guestNetwork = _networksDao.findById(networkId);
-        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-        IpAddress ip = null;
-        if ((off.getElasticLb() && forElasticLb) || (off.getElasticIp() && forElasticIp)) {
-
-            try {
-                s_logger.debug("Allocating system IP address for load balancer rule...");
-                // allocate ip
-                ip = allocateIP(owner, true, guestNetwork.getDataCenterId());
-                // apply ip associations
-                ip = associateIPToGuestNetwork(ip.getId(), networkId, true);
-                ;
-            } catch (ResourceAllocationException ex) {
-                throw new CloudRuntimeException("Failed to allocate system ip due to ", ex);
-            } catch (ConcurrentOperationException ex) {
-                throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
-            } catch (ResourceUnavailableException ex) {
-                throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
-            }
-
-            if (ip == null) {
-                throw new CloudRuntimeException("Failed to allocate system ip");
-            }
-        }
-
-        return ip;
-    }
-
-    @Override
-    public boolean handleSystemIpRelease(IpAddress ip) {
-        boolean success = true;
-        Long networkId = ip.getAssociatedWithNetworkId();
-        if (networkId != null) {
-            if (ip.getSystem()) {
-                CallContext ctx = CallContext.current();
-                if (!disassociatePublicIpAddress(ip.getId(), ctx.getCallingUserId(), ctx.getCallingAccount())) {
-                    s_logger.warn("Unable to release system ip address id=" + ip.getId());
-                    success = false;
-                } else {
-                    s_logger.warn("Successfully released system ip address id=" + ip.getId());
-                }
-            }
-        }
-        return success;
-    }
-
-    @Override
-    @DB
-    public void allocateDirectIp(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4,
-            final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
-                //This method allocates direct ip for the Shared network in Advance zones
-                boolean ipv4 = false;
-
-                if (network.getGateway() != null) {
-                    if (nic.getIPv4Address() == null) {
-                        ipv4 = true;
-                        PublicIp ip = null;
-
-                        //Get ip address from the placeholder and don't allocate a new one
-                        if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
-                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
-                            if (placeholderNic != null) {
-                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address());
-                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                                s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network);
-                            }
-                        }
-
-                        if (ip == null) {
-                            ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false, false);
-                        }
-
-                        nic.setIPv4Address(ip.getAddress().toString());
-                        nic.setIPv4Gateway(ip.getGateway());
-                        nic.setIPv4Netmask(ip.getNetmask());
-                        nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
-                        nic.setBroadcastType(network.getBroadcastDomainType());
-                        if (network.getBroadcastUri() != null)
-                            nic.setBroadcastUri(network.getBroadcastUri());
-                        else
-                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
-                        nic.setFormat(AddressFormat.Ip4);
-                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
-                        if(nic.getMacAddress() == null) {
-                            nic.setMacAddress(ip.getMacAddress());
-                        }
-                    }
-                    nic.setIPv4Dns1(dc.getDns1());
-                    nic.setIPv4Dns2(dc.getDns2());
-                }
-
-                //FIXME - get ipv6 address from the placeholder if it's stored there
-                if (network.getIp6Gateway() != null) {
-                    if (nic.getIPv6Address() == null) {
-                        UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
-                        Vlan vlan = _vlanDao.findById(ip.getVlanId());
-                        nic.setIPv6Address(ip.getAddress().toString());
-                        nic.setIPv6Gateway(vlan.getIp6Gateway());
-                        nic.setIPv6Cidr(vlan.getIp6Cidr());
-                        if (ipv4) {
-                            nic.setFormat(AddressFormat.DualStack);
-                        } else {
-                            nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag()));
-                            nic.setBroadcastType(BroadcastDomainType.Vlan);
-                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag()));
-                            nic.setFormat(AddressFormat.Ip6);
-                            nic.setReservationId(String.valueOf(vlan.getVlanTag()));
-                            if(nic.getMacAddress() == null) {
-                                nic.setMacAddress(ip.getMacAddress());
-                            }
-                        }
-                    }
-                    nic.setIPv6Dns1(dc.getIp6Dns1());
-                    nic.setIPv6Dns2(dc.getIp6Dns2());
-                }
-            }
-        });
-    }
-
-    @Override
-    @DB
-    public void allocateNicValues(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4,
-            final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
-                //This method allocates direct ip for the Shared network in Advance zones
-                boolean ipv4 = false;
-
-                if (network.getGateway() != null) {
-                    if (nic.getIPv4Address() == null) {
-                        ipv4 = true;
-                        // PublicIp ip = null;
-
-                        //Get ip address from the placeholder and don't allocate a new one
-                        if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
-                            s_logger.debug("There won't be nic assignment for VR id " + vm.getId() + "  in this network " + network);
-
-                        }
-
-                        // nic ip address is not set here. Because the DHCP is external to cloudstack
-                        nic.setIPv4Gateway(network.getGateway());
-                        nic.setIPv4Netmask(NetUtils.getCidrNetmask(network.getCidr()));
-
-                        List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(network.getId());
-
-                        //TODO: get vlan tag for the ntwork
-                        if (vlan != null && !vlan.isEmpty()) {
-                            nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.get(0).getVlanTag()));
-                        }
-
-                        nic.setBroadcastType(BroadcastDomainType.Vlan);
-                        nic.setBroadcastType(network.getBroadcastDomainType());
-
-                        nic.setBroadcastUri(network.getBroadcastUri());
-                        nic.setFormat(AddressFormat.Ip4);
-                        if(nic.getMacAddress() == null) {
-                            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
-                        }
-                    }
-                    nic.setIPv4Dns1(dc.getDns1());
-                    nic.setIPv4Dns2(dc.getDns2());
-                }
-
-                // TODO: the IPv6 logic is not changed.
-                //FIXME - get ipv6 address from the placeholder if it's stored there
-                if (network.getIp6Gateway() != null) {
-                    if (nic.getIPv6Address() == null) {
-                        UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
-                        Vlan vlan = _vlanDao.findById(ip.getVlanId());
-                        nic.setIPv6Address(ip.getAddress().toString());
-                        nic.setIPv6Gateway(vlan.getIp6Gateway());
-                        nic.setIPv6Cidr(vlan.getIp6Cidr());
-                        if (ipv4) {
-                            nic.setFormat(AddressFormat.DualStack);
-                        } else {
-                            nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag()));
-                            nic.setBroadcastType(BroadcastDomainType.Vlan);
-                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag()));
-                            nic.setFormat(AddressFormat.Ip6);
-                            nic.setReservationId(String.valueOf(vlan.getVlanTag()));
-                            nic.setMacAddress(ip.getMacAddress());
-                        }
-                    }
-                    nic.setIPv6Dns1(dc.getIp6Dns1());
-                    nic.setIPv6Dns2(dc.getIp6Dns2());
-                }
-            }
-        });
-    }
-
-    @Override
-    public int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state) {
-        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeWithState(addressId, purpose, state);
-        if (rules == null) {
-            return 0;
-        }
-        return rules.size();
-    }
-
-    @Override
-    public String allocatePublicIpForGuestNic(Network network, Long podId, Account owner, String requestedIp) throws InsufficientAddressCapacityException {
-        PublicIp ip = assignPublicIpAddress(network.getDataCenterId(), podId, owner, VlanType.DirectAttached, network.getId(), requestedIp, false, false);
-        if (ip == null) {
-            s_logger.debug("There is no free public ip address");
-            return null;
-        }
-        Ip ipAddr = ip.getAddress();
-        return ipAddr.addr();
-    }
-
-    @Override
-    public String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException {
-        return acquireGuestIpAddress(network, requestedIp);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return IpAddressManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError, SystemVmPublicIpReservationModeStrictness};
-    }
-}
diff --git a/server/src/com/cloud/network/Ipv6AddressManager.java b/server/src/com/cloud/network/Ipv6AddressManager.java
deleted file mode 100644
index 8a7049b..0000000
--- a/server/src/com/cloud/network/Ipv6AddressManager.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.user.Account;
-import com.cloud.utils.component.Manager;
-
-public interface Ipv6AddressManager extends Manager {
-
-    public UserIpv6Address assignDirectIp6Address(long dcId, Account owner, Long networkId, String requestedIp6) throws InsufficientAddressCapacityException;
-
-    public void revokeDirectIpv6Address(long networkId, String ip6Address);
-}
diff --git a/server/src/com/cloud/network/Ipv6AddressManagerImpl.java b/server/src/com/cloud/network/Ipv6AddressManagerImpl.java
deleted file mode 100644
index 53fb25c..0000000
--- a/server/src/com/cloud/network/Ipv6AddressManagerImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.user.Account;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-
-public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressManager {
-    public static final Logger s_logger = Logger.getLogger(Ipv6AddressManagerImpl.class.getName());
-
-    String _name = null;
-    int _ipv6RetryMax = 0;
-
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    UserIpv6AddressDao _ipv6Dao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    ConfigurationDao _configDao;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-        Map<String, String> configs = _configDao.getConfiguration(params);
-        _ipv6RetryMax = NumbersUtil.parseInt(configs.get(Config.NetworkIPv6SearchRetryMax.key()), 10000);
-        return true;
-    }
-
-    @Override
-    public UserIpv6Address assignDirectIp6Address(long dcId, Account owner, Long networkId, String requestedIp6) throws InsufficientAddressCapacityException {
-        Network network = _networkDao.findById(networkId);
-        if (network == null) {
-            return null;
-        }
-        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
-        if (vlans == null) {
-            s_logger.debug("Cannot find related vlan attached to network " + networkId);
-            return null;
-        }
-        String ip = null;
-        Vlan ipVlan = null;
-        if (requestedIp6 == null) {
-            if (!_networkModel.isIP6AddressAvailableInNetwork(networkId)) {
-                throw new InsufficientAddressCapacityException("There is no more address available in the network " + network.getName(), DataCenter.class,
-                    network.getDataCenterId());
-            }
-            for (Vlan vlan : vlans) {
-                if (!_networkModel.isIP6AddressAvailableInVlan(vlan.getId())) {
-                    continue;
-                }
-                ip = NetUtils.getIp6FromRange(vlan.getIp6Range());
-                int count = 0;
-                while (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) != null) {
-                    ip = NetUtils.getNextIp6InRange(ip, vlan.getIp6Range());
-                    count++;
-                    // It's an arbitrate number to prevent the infinite loop
-                    if (count > _ipv6RetryMax) {
-                        ip = null;
-                        break;
-                    }
-                }
-                if (ip != null) {
-                    ipVlan = vlan;
-                }
-            }
-            if (ip == null) {
-                throw new InsufficientAddressCapacityException("Cannot find a usable IP in the network " + network.getName() + " after " + _ipv6RetryMax +
-                    "(network.ipv6.search.retry.max) times retry!", DataCenter.class, network.getDataCenterId());
-            }
-        } else {
-            for (Vlan vlan : vlans) {
-                if (NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) {
-                    ipVlan = vlan;
-                    break;
-                }
-            }
-            if (ipVlan == null) {
-                throw new CloudRuntimeException("Requested IPv6 is not in the predefined range!");
-            }
-            ip = requestedIp6;
-            if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) != null) {
-                throw new CloudRuntimeException("The requested IP is already taken!");
-            }
-        }
-        DataCenterVO dc = _dcDao.findById(dcId);
-        Long mac = dc.getMacAddress();
-        Long nextMac = mac + 1;
-        dc.setMacAddress(nextMac);
-        _dcDao.update(dc.getId(), dc);
-
-        String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac,NetworkModel.MACIdentifier.value()));
-        UserIpv6AddressVO ipVO = new UserIpv6AddressVO(ip, dcId, macAddress, ipVlan.getId());
-        ipVO.setPhysicalNetworkId(network.getPhysicalNetworkId());
-        ipVO.setSourceNetworkId(networkId);
-        ipVO.setState(UserIpv6Address.State.Allocated);
-        ipVO.setDomainId(owner.getDomainId());
-        ipVO.setAccountId(owner.getAccountId());
-        _ipv6Dao.persist(ipVO);
-        return ipVO;
-    }
-
-    @Override
-    public void revokeDirectIpv6Address(long networkId, String ip6Address) {
-        UserIpv6AddressVO ip = _ipv6Dao.findByNetworkIdAndIp(networkId, ip6Address);
-        if (ip != null) {
-            _ipv6Dao.remove(ip.getId());
-        }
-    }
-}
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
deleted file mode 100644
index 4dae743..0000000
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ /dev/null
@@ -1,2479 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import java.math.BigInteger;
-import java.security.InvalidParameterException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddress.State;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDomainDao;
-import com.cloud.network.dao.NetworkDomainVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkServiceMapVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.network.element.IpDeployer;
-import com.cloud.network.element.IpDeployingRequester;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.DomainManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable {
-    static final Logger s_logger = Logger.getLogger(NetworkModelImpl.class);
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    VlanDao _vlanDao = null;
-    @Inject
-    IPAddressDao _ipAddressDao = null;
-    @Inject
-    AccountDao _accountDao = null;
-    @Inject
-    DomainDao _domainDao = null;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao = null;
-    @Inject
-    NetworkDao _networksDao = null;
-    @Inject
-    NicDao _nicDao = null;
-    @Inject
-    PodVlanMapDao _podVlanMapDao;
-
-    private List<NetworkElement> networkElements;
-
-    public List<NetworkElement> getNetworkElements() {
-        return networkElements;
-    }
-
-    public void setNetworkElements(List<NetworkElement> networkElements) {
-        this.networkElements = networkElements;
-    }
-
-    @Inject
-    NetworkDomainDao _networkDomainDao;
-    @Inject
-    VMInstanceDao _vmDao;
-
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    DomainManager _domainMgr;
-
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _pNSPDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingRulesDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    PrivateIpDao _privateIpDao;
-    @Inject
-    UserIpv6AddressDao _ipv6Dao;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    ApplicationLoadBalancerRuleDao _appLbRuleDao;
-    @Inject
-    private ProjectAccountDao _projectAccountDao;
-    @Inject
-    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
-    @Inject
-    private NetworkService _networkService;
-
-    private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
-    static Long s_privateOfferingId = null;
-
-    SearchBuilder<IPAddressVO> IpAddressSearch;
-    SearchBuilder<NicVO> NicForTrafficTypeSearch;
-
-    private boolean _allowSubdomainNetworkAccess;
-
-    private Map<String, String> _configs;
-
-    protected boolean _executeInSequenceNtwkElmtCmd;
-
-    HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
-
-    static HashMap<Service, List<Provider>> s_serviceToImplementedProvidersMap = new HashMap<Service, List<Provider>>();
-    static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
-
-    /**
-     *
-     */
-    public NetworkModelImpl() {
-        super();
-    }
-
-    @Override
-    public NetworkElement getElementImplementingProvider(String providerName) {
-        String elementName = s_providerToNetworkElementMap.get(providerName);
-        NetworkElement element = AdapterBase.getAdapterByName(networkElements, elementName);
-        return element;
-    }
-
-    @Override
-    public List<Service> getElementServices(Provider provider) {
-        NetworkElement element = getElementImplementingProvider(provider.getName());
-        if (element == null) {
-            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
-        }
-        return new ArrayList<Service>(element.getCapabilities().keySet());
-    }
-
-    @Override
-    public boolean canElementEnableIndividualServices(Provider provider) {
-        NetworkElement element = getElementImplementingProvider(provider.getName());
-        if (element == null) {
-            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
-        }
-        return element.canEnableIndividualServices();
-    }
-
-    Set<Purpose> getPublicIpPurposeInRules(PublicIpAddress ip, boolean includeRevoked, boolean includingFirewall) {
-        Set<Purpose> result = new HashSet<Purpose>();
-        List<FirewallRuleVO> rules = null;
-        if (includeRevoked) {
-            rules = _firewallDao.listByIp(ip.getId());
-        } else {
-            rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
-        }
-
-        if (rules == null || rules.isEmpty()) {
-            return null;
-        }
-
-        for (FirewallRuleVO rule : rules) {
-            if (rule.getPurpose() != Purpose.Firewall || includingFirewall) {
-                result.add(rule.getPurpose());
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean postApplyRules, boolean includingFirewall) {
-        Map<PublicIpAddress, Set<Service>> ipToServices = new HashMap<PublicIpAddress, Set<Service>>();
-
-        if (publicIps != null && !publicIps.isEmpty()) {
-            Set<Long> networkSNAT = new HashSet<Long>();
-            for (PublicIpAddress ip : publicIps) {
-                Set<Service> services = ipToServices.get(ip);
-                if (services == null) {
-                    services = new HashSet<Service>();
-                }
-                if (ip.isSourceNat()) {
-                    if (!networkSNAT.contains(ip.getAssociatedWithNetworkId())) {
-                        services.add(Service.SourceNat);
-                        networkSNAT.add(ip.getAssociatedWithNetworkId());
-                    } else {
-                        CloudRuntimeException ex = new CloudRuntimeException("Multiple generic soure NAT IPs provided for network");
-                        // see the IPAddressVO.java class.
-                        IPAddressVO ipAddr = ApiDBUtils.findIpAddressById(ip.getAssociatedWithNetworkId());
-                        String ipAddrUuid = ip.getAssociatedWithNetworkId().toString();
-                        if (ipAddr != null) {
-                            ipAddrUuid = ipAddr.getUuid();
-                        }
-                        ex.addProxyObject(ipAddrUuid, "networkId");
-                        throw ex;
-                    }
-                }
-                ipToServices.put(ip, services);
-
-                // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service
-                // provider
-                if (ip.getState() == State.Allocating) {
-                    continue;
-                }
-
-                // check if any active rules are applied on the public IP
-                Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false, includingFirewall);
-                // Firewall rules didn't cover static NAT
-                if (ip.isOneToOneNat() && ip.getAssociatedWithVmId() != null) {
-                    if (purposes == null) {
-                        purposes = new HashSet<Purpose>();
-                    }
-                    purposes.add(Purpose.StaticNat);
-                }
-                if (purposes == null || purposes.isEmpty()) {
-                    // since no active rules are there check if any rules are applied on the public IP but are in
-                    // revoking state
-
-                    purposes = getPublicIpPurposeInRules(ip, true, includingFirewall);
-                    if (ip.isOneToOneNat()) {
-                        if (purposes == null) {
-                            purposes = new HashSet<Purpose>();
-                        }
-                        purposes.add(Purpose.StaticNat);
-                    }
-                    if (purposes == null || purposes.isEmpty()) {
-                        // IP is not being used for any purpose so skip IPAssoc to network service provider
-                        continue;
-                    } else {
-                        if (postApplyRules) {
-                            // no active rules/revoked rules are associated with this public IP, so remove the
-                            // association with the provider
-                            if (ip.isSourceNat()) {
-                                s_logger.debug("Not releasing ip " + ip.getAddress().addr() + " as it is in use for SourceNat");
-                            } else {
-                                ip.setState(State.Releasing);
-                            }
-                        } else {
-                            if (ip.getState() == State.Releasing) {
-                                // rules are not revoked yet, so don't let the network service provider revoke the IP
-                                // association
-                                // mark IP is allocated so that IP association will not be removed from the provider
-                                ip.setState(State.Allocated);
-                            }
-                        }
-                    }
-                }
-                if (purposes.contains(Purpose.StaticNat)) {
-                    services.add(Service.StaticNat);
-                }
-                if (purposes.contains(Purpose.LoadBalancing)) {
-                    services.add(Service.Lb);
-                }
-                if (purposes.contains(Purpose.PortForwarding)) {
-                    services.add(Service.PortForwarding);
-                }
-                if (purposes.contains(Purpose.Vpn)) {
-                    services.add(Service.Vpn);
-                }
-                if (purposes.contains(Purpose.Firewall)) {
-                    services.add(Service.Firewall);
-                }
-                if (services.isEmpty()) {
-                    continue;
-                }
-                ipToServices.put(ip, services);
-            }
-        }
-        return ipToServices;
-    }
-
-    public boolean canIpUsedForNonConserveService(PublicIp ip, Service service) {
-        // If it's non-conserve mode, then the new ip should not be used by any other services
-        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
-        ipList.add(ip);
-        Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, false);
-        Set<Service> services = ipToServices.get(ip);
-        // Not used currently, safe
-        if (services == null || services.isEmpty()) {
-            return true;
-        }
-        // Since it's non-conserve mode, only one service should used for IP
-        if (services.size() != 1) {
-            throw new InvalidParameterException("There are multiple services used ip " + ip.getAddress() + ".");
-        }
-        if (service != null && !((Service)services.toArray()[0] == service || service.equals(Service.Firewall))) {
-            throw new InvalidParameterException("The IP " + ip.getAddress() + " is already used as " + ((Service)services.toArray()[0]).getName() + " rather than " +
-                service.getName());
-        }
-        return true;
-    }
-
-    Map<Service, Set<Provider>> getServiceProvidersMap(long networkId) {
-        Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
-        List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
-        for (NetworkServiceMapVO nsm : nsms) {
-            Set<Provider> providers = map.get(Service.getService(nsm.getService()));
-            if (providers == null) {
-                providers = new HashSet<Provider>();
-            }
-            providers.add(Provider.getProvider(nsm.getProvider()));
-            map.put(Service.getService(nsm.getService()), providers);
-        }
-        return map;
-    }
-
-    public boolean canIpUsedForService(PublicIp publicIp, Service service, Long networkId) {
-        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
-        ipList.add(publicIp);
-        Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, true);
-        Set<Service> services = ipToServices.get(publicIp);
-        if (services == null || services.isEmpty()) {
-            return true;
-        }
-
-        if (networkId == null) {
-            networkId = publicIp.getAssociatedWithNetworkId();
-        }
-
-        // We only support one provider for one service now
-        Map<Service, Set<Provider>> serviceToProviders = getServiceProvidersMap(networkId);
-        // Since IP already has service to bind with, the oldProvider can't be null
-        Set<Provider> newProviders = serviceToProviders.get(service);
-        if (newProviders == null || newProviders.isEmpty()) {
-            throw new InvalidParameterException("There is no new provider for IP " + publicIp.getAddress() + " of service " + service.getName() + "!");
-        }
-        Provider newProvider = (Provider)newProviders.toArray()[0];
-        Set<Provider> oldProviders = serviceToProviders.get(services.toArray()[0]);
-        Provider oldProvider = (Provider)oldProviders.toArray()[0];
-        Network network = _networksDao.findById(networkId);
-        NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
-        NetworkElement newElement = getElementImplementingProvider(newProvider.getName());
-        if (oldElement instanceof IpDeployingRequester && newElement instanceof IpDeployingRequester) {
-            IpDeployer oldIpDeployer = ((IpDeployingRequester)oldElement).getIpDeployer(network);
-            IpDeployer newIpDeployer = ((IpDeployingRequester)newElement).getIpDeployer(network);
-            // FIXME: I ignored this check
-        } else {
-            throw new InvalidParameterException("Ip cannot be applied for new provider!");
-        }
-        return true;
-    }
-
-    Map<Provider, Set<Service>> getProviderServicesMap(long networkId) {
-        Map<Provider, Set<Service>> map = new HashMap<Provider, Set<Service>>();
-        List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
-        for (NetworkServiceMapVO nsm : nsms) {
-            Set<Service> services = map.get(Provider.getProvider(nsm.getProvider()));
-            if (services == null) {
-                services = new HashSet<Service>();
-            }
-            services.add(Service.getService(nsm.getService()));
-            map.put(Provider.getProvider(nsm.getProvider()), services);
-        }
-        return map;
-    }
-
-    @Override
-    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
-        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if (!offering.isConserveMode()) {
-            for (PublicIpAddress ip : ipToServices.keySet()) {
-                Set<Service> services = new HashSet<Service>();
-                services.addAll(ipToServices.get(ip));
-                if (services != null && services.contains(Service.Firewall)) {
-                    services.remove(Service.Firewall);
-                }
-                if (services != null && services.size() > 1) {
-                    throw new CloudRuntimeException("Ip " + ip.getAddress() + " is used by multiple services!");
-                }
-            }
-        }
-        Map<Service, Set<PublicIpAddress>> serviceToIps = new HashMap<Service, Set<PublicIpAddress>>();
-        for (PublicIpAddress ip : ipToServices.keySet()) {
-            for (Service service : ipToServices.get(ip)) {
-                Set<PublicIpAddress> ips = serviceToIps.get(service);
-                if (ips == null) {
-                    ips = new HashSet<PublicIpAddress>();
-                }
-                ips.add(ip);
-                serviceToIps.put(service, ips);
-            }
-        }
-        // TODO Check different provider for same IP
-        Map<Provider, Set<Service>> providerToServices = getProviderServicesMap(network.getId());
-        Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = new HashMap<Provider, ArrayList<PublicIpAddress>>();
-        for (Provider provider : providerToServices.keySet()) {
-            if (!(getElementImplementingProvider(provider.getName()) instanceof IpDeployingRequester)) {
-                continue;
-            }
-            Set<Service> services = providerToServices.get(provider);
-            ArrayList<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
-            Set<PublicIpAddress> ipSet = new HashSet<PublicIpAddress>();
-            for (Service service : services) {
-                Set<PublicIpAddress> serviceIps = serviceToIps.get(service);
-                if (serviceIps == null || serviceIps.isEmpty()) {
-                    continue;
-                }
-                ipSet.addAll(serviceIps);
-            }
-            Set<PublicIpAddress> sourceNatIps = serviceToIps.get(Service.SourceNat);
-            if (sourceNatIps != null && !sourceNatIps.isEmpty()) {
-                ipList.addAll(0, sourceNatIps);
-                ipSet.removeAll(sourceNatIps);
-            }
-            ipList.addAll(ipSet);
-            providerToIpList.put(provider, ipList);
-        }
-        return providerToIpList;
-    }
-
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
-        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("associatedWithNetworkId", associatedNetworkId);
-        if (sourceNat != null) {
-            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
-        }
-        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
-
-        return _ipAddressDao.search(sc, null);
-    }
-
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
-        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
-        sc.setParameters("associatedWithNetworkId", associatedNetworkId);
-
-        if (sourceNat != null) {
-            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
-        }
-        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
-
-        return _ipAddressDao.search(sc, null);
-    }
-
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
-        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("dataCenterId", dcId);
-
-        if (sourceNat != null) {
-            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
-        }
-        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
-
-        return _ipAddressDao.search(sc, null);
-    }
-
-    @Override
-    public List<? extends Nic> getNics(long vmId) {
-        return _nicDao.listByVmId(vmId);
-    }
-
-    @Override
-    public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
-        NetworkVO network = _networksDao.findById(networkId);
-        String mac = _networksDao.getNextAvailableMacAddress(networkId, MACIdentifier.value());
-        if (mac == null) {
-            throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
-        }
-        return mac;
-    }
-
-    @Override
-    @DB
-    public Network getNetwork(long id) {
-        return _networksDao.findById(id);
-    }
-
-    @Override
-    public boolean canUseForDeploy(Network network) {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            return false;
-        }
-        if (network.getGuestType() == GuestType.L2 || listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
-            return true; // do not check free IPs if there is no service in the network
-        }
-        boolean hasFreeIps = true;
-        if (network.getGuestType() == GuestType.Shared) {
-            if (network.getGateway() != null) {
-                hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0;
-            }
-            if (!hasFreeIps) {
-                return false;
-            }
-            if (network.getIp6Gateway() != null) {
-                hasFreeIps = isIP6AddressAvailableInNetwork(network.getId());
-            }
-        } else {
-            if (network.getCidr() == null) {
-                s_logger.debug("Network - " + network.getId() +  " has NULL CIDR.");
-                return false;
-            }
-            hasFreeIps = (getAvailableIps(network, null)).size() > 0;
-        }
-
-        return hasFreeIps;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInNetwork(long networkId) {
-        Network network = _networksDao.findById(networkId);
-        if (network == null) {
-            return false;
-        }
-        if (network.getIp6Gateway() == null) {
-            return false;
-        }
-        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
-        for (Vlan vlan : vlans) {
-            if (isIP6AddressAvailableInVlan(vlan.getId())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInVlan(long vlanId) {
-        VlanVO vlan = _vlanDao.findById(vlanId);
-        if (vlan.getIp6Range() == null) {
-            return false;
-        }
-        long existedCount = _ipv6Dao.countExistedIpsInVlan(vlanId);
-        BigInteger existedInt = BigInteger.valueOf(existedCount);
-        BigInteger rangeInt = NetUtils.countIp6InRange(vlan.getIp6Range());
-        return (existedInt.compareTo(rangeInt) < 0);
-    }
-
-    @Override
-    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
-
-        Map<Service, Map<Capability, String>> networkCapabilities = new HashMap<Service, Map<Capability, String>>();
-
-        // list all services of this networkOffering
-        List<NetworkServiceMapVO> servicesMap = _ntwkSrvcDao.getServicesInNetwork(networkId);
-        for (NetworkServiceMapVO instance : servicesMap) {
-            Service service = Service.getService(instance.getService());
-            NetworkElement element = getElementImplementingProvider(instance.getProvider());
-            if (element != null) {
-                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-                if (elementCapabilities != null) {
-                    networkCapabilities.put(service, elementCapabilities.get(service));
-                }
-            }
-        }
-
-        return networkCapabilities;
-    }
-
-    @Override
-    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
-
-        if (!areServicesSupportedInNetwork(networkId, service)) {
-            // TBD: networkId to uuid. No VO object being passed. So we will need to call
-            // addProxyObject with hardcoded tablename. Or we should probably look up the correct dao proxy object.
-            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported in the network id=" + networkId);
-        }
-
-        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
-
-        // get the Provider for this Service for this offering
-        String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
-
-        NetworkElement element = getElementImplementingProvider(provider);
-        if (element != null) {
-            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-            ;
-
-            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
-                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
-                    " implementing Provider=" + provider);
-            }
-            serviceCapabilities = elementCapabilities.get(service);
-        }
-
-        return serviceCapabilities;
-    }
-
-    @Override
-    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
-
-        if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) {
-            // TBD: We should be sending networkOfferingId and not the offering object itself.
-            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering);
-        }
-
-        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
-
-        // get the Provider for this Service for this offering
-        List<String> providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
-        if (providers.isEmpty()) {
-            // TBD: We should be sending networkOfferingId and not the offering object itself.
-            throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering);
-        }
-
-        // FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so
-        // we have to calculate capabilities for all of them
-        String provider = providers.get(0);
-
-        // FIXME we return the capabilities of the first provider of the service - what if we have multiple providers
-        // for same Service?
-        NetworkElement element = getElementImplementingProvider(provider);
-        if (element != null) {
-            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-            ;
-
-            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
-                // TBD: We should be sending providerId and not the offering object itself.
-                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
-                    " implementing Provider=" + provider);
-            }
-            serviceCapabilities = elementCapabilities.get(service);
-        }
-
-        return serviceCapabilities;
-    }
-
-    @Override
-    public NetworkVO getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // find system public network offering
-        Long networkOfferingId = null;
-        List<NetworkOfferingVO> offerings = _networkOfferingDao.listSystemNetworkOfferings();
-        for (NetworkOfferingVO offering : offerings) {
-            if (offering.getTrafficType() == trafficType) {
-                networkOfferingId = offering.getId();
-                break;
-            }
-        }
-
-        if (networkOfferingId == null) {
-            throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType);
-        }
-
-        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId);
-        if (networks == null || networks.isEmpty()) {
-            // TBD: send uuid instead of zoneId. Hardcode tablename in call to addProxyObject().
-            throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId);
-        }
-        return networks.get(0);
-    }
-
-    @Override
-    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
-        List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
-        if (networks == null || networks.isEmpty()) {
-            return null;
-        }
-        NetworkVO ret_network = null;
-        for (NetworkVO nw : networks) {
-            List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(nw.getId());
-            for (VlanVO vlan : vlans) {
-                if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) {
-                    ret_network = nw;
-                    break;
-                }
-            }
-            if (ret_network != null) {
-                break;
-            }
-        }
-        if (ret_network == null) {
-            s_logger.debug("Can not find network with security group enabled with free IPs");
-        }
-        return ret_network;
-    }
-
-    @Override
-    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
-        List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
-        if (networks == null || networks.isEmpty()) {
-            return null;
-        }
-
-        if (networks.size() > 1) {
-            s_logger.debug("There are multiple network with security group enabled? select one of them...");
-        }
-        return networks.get(0);
-    }
-
-    @Override
-    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
-        IPAddressVO addr = _ipAddressDao.findById(ipAddressId);
-        if (addr == null) {
-            return null;
-        }
-
-        return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
-    }
-
-    @Override
-    public List<VlanVO> listPodVlans(long podId) {
-        List<VlanVO> vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached);
-        return vlans;
-    }
-
-    @Override
-    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
-        List<NetworkVO> networks = new ArrayList<NetworkVO>();
-
-        List<NicVO> nics = _nicDao.listByVmId(vmId);
-        if (nics != null) {
-            for (Nic nic : nics) {
-                NetworkVO network = _networksDao.findByIdIncludingRemoved(nic.getNetworkId());
-
-                if (isNetworkSystem(network) == isSystem) {
-                    networks.add(network);
-                }
-            }
-        }
-
-        return networks;
-    }
-
-    @Override
-    public Nic getNicInNetwork(long vmId, long networkId) {
-        return _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
-    }
-
-    @Override
-    public String getIpInNetwork(long vmId, long networkId) {
-        Nic guestNic = getNicInNetwork(vmId, networkId);
-        assert (guestNic != null && guestNic.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
-        return guestNic.getIPv4Address();
-    }
-
-    @Override
-    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
-        Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId);
-        assert (guestNic != null && guestNic.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
-        return guestNic.getIPv4Address();
-    }
-
-    @Override
-    public List<NicVO> getNicsForTraffic(long vmId, TrafficType type) {
-        SearchCriteria<NicVO> sc = NicForTrafficTypeSearch.create();
-        sc.setParameters("instance", vmId);
-        sc.setJoinParameters("network", "traffictype", type);
-
-        return _nicDao.search(sc, null);
-    }
-
-    @Override
-    public IpAddress getIp(long ipAddressId) {
-        return _ipAddressDao.findById(ipAddressId);
-    }
-
-    @Override
-    public Network getDefaultNetworkForVm(long vmId) {
-        Nic defaultNic = getDefaultNic(vmId);
-        if (defaultNic == null) {
-            return null;
-        } else {
-            return _networksDao.findById(defaultNic.getNetworkId());
-        }
-    }
-
-    @Override
-    public Nic getDefaultNic(long vmId) {
-        List<NicVO> nics = _nicDao.listByVmId(vmId);
-        Nic defaultNic = null;
-        if (nics != null) {
-            for (Nic nic : nics) {
-                if (nic.isDefaultNic()) {
-                    defaultNic = nic;
-                    break;
-                }
-            }
-        } else {
-            s_logger.debug("Unable to find default network for the vm; vm doesn't have any nics");
-            return null;
-        }
-
-        if (defaultNic == null) {
-            s_logger.debug("Unable to find default network for the vm; vm doesn't have default nic");
-        }
-
-        return defaultNic;
-
-    }
-
-    @Override
-    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
-        String userDataProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
-
-        if (userDataProvider == null) {
-            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
-            return null;
-        }
-
-        return (UserDataServiceProvider)getElementImplementingProvider(userDataProvider);
-    }
-
-    @Override
-    public  boolean isSharedNetworkWithoutServices (long networkId) {
-
-        Network network = _networksDao.findById(networkId);
-
-        if (network != null && network.getGuestType() != GuestType.Shared) {
-            return false;
-        }
-
-        List<Service> services = listNetworkOfferingServices(network.getNetworkOfferingId());
-
-        if (services == null || services.isEmpty()) {
-            return true;
-        }
-
-        return false;
-    }
-
-
-    @Override
-    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
-        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
-    }
-
-    @Override
-    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
-        return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services));
-    }
-
-    @Override
-    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
-
-        List<NetworkVO> virtualNetworks = _networksDao.listByZoneAndGuestType(accountId, dataCenterId, GuestType.Isolated, false);
-
-        if (virtualNetworks.isEmpty()) {
-            s_logger.trace("Unable to find default Virtual network account id=" + accountId);
-            return null;
-        }
-
-        NetworkVO virtualNetwork = virtualNetworks.get(0);
-
-        NicVO networkElementNic = _nicDao.findByNetworkIdAndType(virtualNetwork.getId(), Type.DomainRouter);
-
-        if (networkElementNic != null) {
-            return networkElementNic.getIPv4Address();
-        } else {
-            s_logger.warn("Unable to set find network element for the network id=" + virtualNetwork.getId());
-            return null;
-        }
-    }
-
-    @Override
-    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
-        List<NetworkVO> accountNetworks = new ArrayList<NetworkVO>();
-        List<NetworkVO> zoneNetworks = _networksDao.listByZone(zoneId);
-
-        for (NetworkVO network : zoneNetworks) {
-            if (!isNetworkSystem(network)) {
-                if (network.getGuestType() == GuestType.Shared || !_networksDao.listBy(accountId, network.getId()).isEmpty()) {
-                    if (type == null || type == network.getGuestType()) {
-                        accountNetworks.add(network);
-                    }
-                }
-            }
-        }
-        return accountNetworks;
-    }
-
-    @Override
-    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
-        List<NetworkVO> networks = new ArrayList<NetworkVO>();
-        for (NetworkVO network : _networksDao.listAll()) {
-            if (!isNetworkSystem(network)) {
-                networks.add(network);
-            }
-        }
-        return networks;
-    }
-
-    @Override
-    public Long getDedicatedNetworkDomain(long networkId) {
-        NetworkDomainVO networkMaps = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
-        if (networkMaps != null) {
-            return networkMaps.getDomainId();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public Integer getNetworkRate(long networkId, Long vmId) {
-        VMInstanceVO vm = null;
-        if (vmId != null) {
-            vm = _vmDao.findById(vmId);
-        }
-        final Network network = getNetwork(networkId);
-        final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-
-        // For user VM: For default nic use network rate from the service/compute offering,
-        //              or on NULL from vm.network.throttling.rate global setting
-        // For router: Get network rate for guest and public networks from the guest network offering
-        //              or on NULL from network.throttling.rate
-        // For others: Use network rate from their network offering,
-        //              or on NULL from network.throttling.rate setting at zone > global level
-        // http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html#network-throttling
-        if (vm != null) {
-            if (vm.getType() == Type.User) {
-                final Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
-                if (nic != null && nic.isDefaultNic()) {
-                    return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
-                }
-            }
-            if (vm.getType() == Type.DomainRouter && (network.getTrafficType() == TrafficType.Public || network.getTrafficType() == TrafficType.Guest)) {
-                for (final Nic nic: _nicDao.listByVmId(vmId)) {
-                    final NetworkVO nw = _networksDao.findById(nic.getNetworkId());
-                    if (nw.getTrafficType() == TrafficType.Guest) {
-                        return _configMgr.getNetworkOfferingNetworkRate(nw.getNetworkOfferingId(), network.getDataCenterId());
-                    }
-                }
-            }
-            if (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm) {
-                return -1;
-            }
-        }
-        if (ntwkOff != null) {
-            return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), network.getDataCenterId());
-        }
-        final Integer networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(network.getDataCenterId());
-        if (networkRate != null && networkRate > 0) {
-            return networkRate;
-        }
-        return -1;
-    }
-
-    @Override
-    public String getAccountNetworkDomain(long accountId, long zoneId) {
-        String networkDomain = _accountDao.findById(accountId).getNetworkDomain();
-
-        if (networkDomain == null) {
-            // get domain level network domain
-            return getDomainNetworkDomain(_accountDao.findById(accountId).getDomainId(), zoneId);
-        }
-
-        return networkDomain;
-    }
-
-    @Override
-    public String getStartIpAddress(long networkId) {
-        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
-        if (vlans.isEmpty()) {
-            return null;
-        }
-
-        String startIP = vlans.get(0).getIpRange().split("-")[0];
-
-        for (VlanVO vlan : vlans) {
-            String startIP1 = vlan.getIpRange().split("-")[0];
-            long startIPLong = NetUtils.ip2Long(startIP);
-            long startIPLong1 = NetUtils.ip2Long(startIP1);
-
-            if (startIPLong1 < startIPLong) {
-                startIP = startIP1;
-            }
-        }
-
-        return startIP;
-    }
-
-    @Override
-    public Long getPodIdForVlan(long vlanDbId) {
-        PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId);
-        if (podVlanMaps == null) {
-            return null;
-        } else {
-            return podVlanMaps.getPodId();
-        }
-    }
-
-    @Override
-    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
-        Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
-        List<NetworkOfferingServiceMapVO> map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId);
-
-        for (NetworkOfferingServiceMapVO instance : map) {
-            String service = instance.getService();
-            Set<Provider> providers;
-            providers = serviceProviderMap.get(Service.getService(service));
-            if (providers == null) {
-                providers = new HashSet<Provider>();
-            }
-            providers.add(Provider.getProvider(instance.getProvider()));
-            serviceProviderMap.put(Service.getService(service), providers);
-        }
-
-        return serviceProviderMap;
-    }
-
-    @Override
-    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
-        return _ntwkSrvcDao.canProviderSupportServiceInNetwork(networkId, service, provider);
-    }
-
-    @Override
-    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
-        Network.Service service = null;
-        if (serviceName != null) {
-            service = Network.Service.getService(serviceName);
-            if (service == null) {
-                throw new InvalidParameterValueException("Invalid Network Service=" + serviceName);
-            }
-        }
-
-        Set<Provider> supportedProviders = new HashSet<Provider>();
-
-        if (service != null) {
-            List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
-            if (providers != null && !providers.isEmpty()) {
-                supportedProviders.addAll(providers);
-            }
-        } else {
-            for (List<Provider> pList : s_serviceToImplementedProvidersMap.values()) {
-                supportedProviders.addAll(pList);
-            }
-        }
-
-        return new ArrayList<Provider>(supportedProviders);
-    }
-
-    @Override
-    public Provider getDefaultUniqueProviderForService(String serviceName) {
-        List<? extends Provider> providers = listSupportedNetworkServiceProviders(serviceName);
-        if (providers.isEmpty()) {
-            throw new CloudRuntimeException("No providers supporting service " + serviceName + " found in cloudStack");
-        }
-        if (providers.size() > 1) {
-            throw new CloudRuntimeException("More than 1 provider supporting service " + serviceName + " found in cloudStack");
-        }
-
-        return providers.get(0);
-    }
-
-    @Override
-    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
-        List<PhysicalNetworkVO> pNtwks = new ArrayList<PhysicalNetworkVO>();
-        if (trafficType != null) {
-            pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
-        } else {
-            pNtwks = _physicalNetworkDao.listByZone(zoneId);
-        }
-
-        if (pNtwks.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId);
-        }
-
-        if (pNtwks.size() > 1) {
-            if (tag == null) {
-                throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId +
-                    " and no tags are specified in order to make a choice");
-            }
-
-            Long pNtwkId = null;
-            for (PhysicalNetwork pNtwk : pNtwks) {
-                if (pNtwk.getTags().contains(tag)) {
-                    s_logger.debug("Found physical network id=" + pNtwk.getId() + " based on requested tags " + tag);
-                    pNtwkId = pNtwk.getId();
-                    break;
-                }
-            }
-            if (pNtwkId == null) {
-                throw new InvalidParameterValueException("Unable to find physical network which match the tags " + tag);
-            }
-            return pNtwkId;
-        } else {
-            return pNtwks.get(0).getId();
-        }
-    }
-
-    @Override
-    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
-        List<Long> offeringsToReturn = new ArrayList<Long>();
-        NetworkOffering originalOffering = _entityMgr.findById(NetworkOffering.class, getNetwork(networkId).getNetworkOfferingId());
-
-        boolean securityGroupSupportedByOriginalOff = areServicesSupportedByNetworkOffering(originalOffering.getId(), Service.SecurityGroup);
-
-        // security group supported property should be the same
-
-        List<Long> offerings = _networkOfferingDao.getOfferingIdsToUpgradeFrom(originalOffering);
-
-        for (Long offeringId : offerings) {
-            if (areServicesSupportedByNetworkOffering(offeringId, Service.SecurityGroup) == securityGroupSupportedByOriginalOff) {
-                offeringsToReturn.add(offeringId);
-            }
-        }
-
-        return offeringsToReturn;
-    }
-
-    @Override
-    public boolean isSecurityGroupSupportedInNetwork(Network network) {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            s_logger.trace("Security group can be enabled for Guest networks only; and network " + network + " has a diff traffic type");
-            return false;
-        }
-
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-
-        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
-        if (physicalNetworkId == null) {
-            physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), null, null);
-        }
-
-        return isServiceEnabledInNetwork(physicalNetworkId, network.getId(), Service.SecurityGroup);
-    }
-
-    @Override
-    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-
-        List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
-        DataCenter dc = ApiDBUtils.findZoneById(zoneId);
-        String dcUuid = String.valueOf(zoneId);
-        if (dc != null) {
-            dcUuid = dc.getUuid();
-        }
-
-        if (networkList.isEmpty()) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in the specified zone id");
-            ex.addProxyObject(dcUuid, "zoneId");
-            throw ex;
-        }
-
-        if (networkList.size() > 1) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType);
-            ex.addProxyObject(dcUuid, "zoneId");
-            throw ex;
-        }
-
-        return networkList.get(0);
-    }
-
-    @Override
-    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        try {
-            PhysicalNetwork mgmtPhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Management);
-            PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
-            if (mgmtTraffic != null) {
-                String label = null;
-                switch (hypervisorType) {
-                    case XenServer:
-                        label = mgmtTraffic.getXenNetworkLabel();
-                        break;
-                    case KVM:
-                        label = mgmtTraffic.getKvmNetworkLabel();
-                        break;
-                    case VMware:
-                        label = mgmtTraffic.getVmwareNetworkLabel();
-                        break;
-                    case Hyperv:
-                        label = mgmtTraffic.getHypervNetworkLabel();
-                        break;
-                    case Ovm3:
-                        label = mgmtTraffic.getOvm3NetworkLabel();
-                        break;
-                }
-                return label;
-            }
-        } catch (Exception ex) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
-                    ex.getMessage());
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        try {
-            PhysicalNetwork storagePhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage);
-            PhysicalNetworkTrafficTypeVO storageTraffic = _pNTrafficTypeDao.findBy(storagePhyNetwork.getId(), TrafficType.Storage);
-            if (storageTraffic != null) {
-                String label = null;
-                switch (hypervisorType) {
-                    case XenServer:
-                        label = storageTraffic.getXenNetworkLabel();
-                        break;
-                    case KVM:
-                        label = storageTraffic.getKvmNetworkLabel();
-                        break;
-                    case VMware:
-                        label = storageTraffic.getVmwareNetworkLabel();
-                        break;
-                    case Hyperv:
-                        label = storageTraffic.getHypervNetworkLabel();
-                        break;
-                    case Ovm3:
-                        label = storageTraffic.getOvm3NetworkLabel();
-                        break;
-                }
-                return label;
-            }
-        } catch (Exception ex) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to retrive the default label for storage traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
-                    ex.getMessage());
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
-        List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
-        List<PhysicalNetworkVO> physicalNtwkList = _physicalNetworkDao.listByZone(dcId);
-        for (PhysicalNetworkVO pNtwk : physicalNtwkList) {
-            String publicName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Public, hypervisorType);
-            String privateName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Management, hypervisorType);
-            String guestName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Guest, hypervisorType);
-            String storageName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Storage, hypervisorType);
-            // String controlName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Control, hypervisorType);
-            PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
-            info.setPhysicalNetworkId(pNtwk.getId());
-            info.setGuestNetworkName(guestName);
-            info.setPrivateNetworkName(privateName);
-            info.setPublicNetworkName(publicName);
-            info.setStorageNetworkName(storageName);
-            PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(pNtwk.getId(), TrafficType.Management);
-            if (mgmtTraffic != null) {
-                String vlan = mgmtTraffic.getVlan();
-                info.setMgmtVlan(vlan);
-            }
-            networkInfoList.add(info);
-        }
-        return networkInfoList;
-    }
-
-    @Override
-    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
-        PhysicalNetworkServiceProviderVO ntwkSvcProvider = _pNSPDao.findByServiceProvider(physicalNetowrkId, providerName);
-        if (ntwkSvcProvider == null) {
-            s_logger.warn("Unable to find provider " + providerName + " in physical network id=" + physicalNetowrkId);
-            return false;
-        }
-        return isProviderEnabled(ntwkSvcProvider);
-    }
-
-    @Override
-    public boolean isProviderEnabledInZone(long zoneId, String provider) {
-        //the provider has to be enabled at least in one network in the zone
-        for (PhysicalNetwork pNtwk : _physicalNetworkDao.listByZone(zoneId)) {
-            if (isProviderEnabledInPhysicalNetwork(pNtwk.getId(), provider)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public String getNetworkTag(HypervisorType hType, Network network) {
-        // no network tag for control traffic type
-        TrafficType effectiveTrafficType = network.getTrafficType();
-        if (hType == HypervisorType.VMware && effectiveTrafficType == TrafficType.Control)
-            effectiveTrafficType = TrafficType.Management;
-
-        if (effectiveTrafficType == TrafficType.Control) {
-            return null;
-        }
-
-        Long physicalNetworkId = null;
-        if (effectiveTrafficType != TrafficType.Guest) {
-            physicalNetworkId = getNonGuestNetworkPhysicalNetworkId(network, effectiveTrafficType);
-        } else {
-            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-            physicalNetworkId = network.getPhysicalNetworkId();
-            if (physicalNetworkId == null) {
-                physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
-            }
-        }
-
-        if (physicalNetworkId == null) {
-            assert (false) : "Can't get the physical network";
-            s_logger.warn("Can't get the physical network");
-            return null;
-        }
-
-        return _pNTrafficTypeDao.getNetworkTag(physicalNetworkId, effectiveTrafficType, hType);
-    }
-
-    @Override
-    public NetworkVO getExclusiveGuestNetwork(long zoneId) {
-        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, zoneId, GuestType.Shared, TrafficType.Guest);
-        if (networks == null || networks.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " +
-                zoneId);
-        }
-
-        if (networks.size() > 1) {
-            throw new InvalidParameterValueException("Found more than 1 network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared +
-                " in zone " + zoneId);
-
-        }
-
-        return networks.get(0);
-    }
-
-    @Override
-    public boolean isNetworkSystem(Network network) {
-        NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        if (no.isSystemOnly()) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public Long getPhysicalNetworkId(Network network) {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            return getNonGuestNetworkPhysicalNetworkId(network);
-        }
-
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-        if (physicalNetworkId == null) {
-            physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
-        }
-        return physicalNetworkId;
-    }
-
-    @Override
-    public boolean getAllowSubdomainAccessGlobal() {
-        return _allowSubdomainNetworkAccess;
-    }
-
-    @Override
-    public boolean isProviderForNetwork(Provider provider, long networkId) {
-        if (_ntwkSrvcDao.isProviderForNetwork(networkId, provider) != null) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
-        if (_ntwkOfferingSrvcDao.isProviderForNetworkOffering(networkOfferingId, provider)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
-        for (Provider provider : providersMap.keySet()) {
-            // check if services can be turned off
-            NetworkElement element = getElementImplementingProvider(provider.getName());
-            if (element == null) {
-                throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
-            }
-
-            Set<Service> enabledServices = new HashSet<Service>();
-            enabledServices.addAll(providersMap.get(provider));
-
-            if (enabledServices != null && !enabledServices.isEmpty()) {
-                if (!element.canEnableIndividualServices()) {
-                    Set<Service> requiredServices = new HashSet<Service>();
-                    requiredServices.addAll(element.getCapabilities().keySet());
-
-                    if (requiredServices.contains(Network.Service.Gateway)) {
-                        requiredServices.remove(Network.Service.Gateway);
-                    }
-
-                    if (requiredServices.contains(Network.Service.Firewall)) {
-                        requiredServices.remove(Network.Service.Firewall);
-                    }
-
-                    if (enabledServices.contains(Network.Service.Firewall)) {
-                        enabledServices.remove(Network.Service.Firewall);
-                    }
-
-                    // exclude gateway service
-                    if (enabledServices.size() != requiredServices.size()) {
-                        StringBuilder servicesSet = new StringBuilder();
-
-                        for (Service requiredService : requiredServices) {
-                            // skip gateway service as we don't allow setting it via API
-                            if (requiredService == Service.Gateway) {
-                                continue;
-                            }
-                            servicesSet.append(requiredService.getName() + ", ");
-                        }
-                        servicesSet.delete(servicesSet.toString().length() - 2, servicesSet.toString().length());
-
-                        throw new InvalidParameterValueException("Cannot enable subset of Services, Please specify the complete list of Services: " +
-                            servicesSet.toString() + "  for Service Provider " + provider.getName());
-                    }
-                }
-                List<String> serviceList = new ArrayList<String>();
-                for (Service service : enabledServices) {
-                    // check if the service is provided by this Provider
-                    if (!element.getCapabilities().containsKey(service)) {
-                        throw new UnsupportedServiceException(provider.getName() + " Provider cannot provide service " + service.getName());
-                    }
-                    serviceList.add(service.getName());
-                }
-                if (!element.verifyServicesCombination(enabledServices)) {
-                    throw new UnsupportedServiceException("Provider " + provider.getName() + " doesn't support services combination: " + serviceList);
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean canAddDefaultSecurityGroup() {
-        String defaultAdding = _configDao.getValue(Config.SecurityGroupDefaultAdding.key());
-        return (defaultAdding != null && defaultAdding.equalsIgnoreCase("true"));
-    }
-
-    @Override
-    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
-        List<Service> services = new ArrayList<Service>();
-        List<String> servicesStr = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(networkOfferingId);
-        for (String serviceStr : servicesStr) {
-            services.add(Service.getService(serviceStr));
-        }
-
-        return services;
-    }
-
-    @Override
-    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
-        long physicalNtwkId = findPhysicalNetworkId(zoneId, offering.getTags(), offering.getTrafficType());
-        boolean result = true;
-        List<String> checkedProvider = new ArrayList<String>();
-        for (Service service : services) {
-            // get all the providers, and check if each provider is enabled
-            List<String> providerNames = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
-            for (String providerName : providerNames) {
-                if (!checkedProvider.contains(providerName)) {
-                    result = result && isProviderEnabledInPhysicalNetwork(physicalNtwkId, providerName);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public boolean checkIpForService(IpAddress userIp, Service service, Long networkId) {
-        if (networkId == null) {
-            networkId = userIp.getAssociatedWithNetworkId();
-        }
-
-        NetworkVO network = _networksDao.findById(networkId);
-        NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if (offering.getGuestType() != GuestType.Isolated) {
-            return true;
-        }
-        IPAddressVO ipVO = _ipAddressDao.findById(userIp.getId());
-        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipVO, _vlanDao.findById(userIp.getVlanId()));
-        if (!canIpUsedForService(publicIp, service, networkId)) {
-            return false;
-        }
-        if (!offering.isConserveMode()) {
-            return canIpUsedForNonConserveService(publicIp, service);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
-        for (Provider provider : providers) {
-            NetworkElement element = getElementImplementingProvider(provider.getName());
-            if (element != null) {
-                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-                if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
-                            " implementing Provider=" + provider.getName());
-                }
-                Map<Capability, String> serviceCapabilities = elementCapabilities.get(service);
-                if (serviceCapabilities == null || serviceCapabilities.isEmpty()) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilites for element=" + element.getName() +
-                            " implementing Provider=" + provider.getName());
-                }
-
-                if (serviceCapabilities.containsKey(cap)) {
-                    return true;
-                }
-            } else {
-                throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName());
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
-        for (Provider provider : providers) {
-            NetworkElement element = getElementImplementingProvider(provider.getName());
-            if (element != null) {
-                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-                if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
-                        " implementing Provider=" + provider.getName());
-                }
-                Map<Capability, String> serviceCapabilities = elementCapabilities.get(service);
-                if (serviceCapabilities == null || serviceCapabilities.isEmpty()) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilities for element=" + element.getName() +
-                        " implementing Provider=" + provider.getName());
-                }
-
-                String value = serviceCapabilities.get(cap);
-                if (value == null || value.isEmpty()) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capability " + cap.getName() + " for element=" +
-                        element.getName() + " implementing Provider=" + provider.getName());
-                }
-
-                if (!value.toLowerCase().contains(capValue.toLowerCase())) {
-                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't support value " + capValue + " for capability " + cap.getName() +
-                        " for element=" + element.getName() + " implementing Provider=" + provider.getName());
-                }
-            } else {
-                throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName());
-            }
-        }
-    }
-
-    @Override
-    public void checkNetworkPermissions(Account owner, Network network) {
-        // dahn 20140310: I was thinking of making this an assert but
-        //                as we hardly ever test with asserts I think
-        //                we better make sure at runtime.
-        if (network == null) {
-            throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
-        }
-        // Perform account permission check
-        if ((network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) ||
-                (network.getGuestType() == GuestType.Shared && network.getAclType() == ACLType.Account)) {
-            AccountVO networkOwner = _accountDao.findById(network.getAccountId());
-            if (networkOwner == null)
-                throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
-                    ", network does not have an owner");
-            if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
-                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
-                        ", permission denied");
-                }
-            } else {
-                List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
-                if (networkMap == null || networkMap.isEmpty()) {
-                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
-                        ", permission denied");
-                }
-            }
-
-        } else {
-            if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) {
-                DomainVO ownerDomain = _domainDao.findById(owner.getDomainId());
-                if (ownerDomain == null) {
-                    throw new CloudRuntimeException("cannot check permission on account " + owner.getAccountName() + " whose domain does not exist");
-                }
-                throw new PermissionDeniedException("Shared network id=" + ((NetworkVO)network).getUuid() + " is not available in domain id=" +
-                        ownerDomain.getUuid());
-            }
-        }
-    }
-
-    @Override
-    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType hypervisorType) {
-        try {
-            PhysicalNetwork publicPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
-            PhysicalNetworkTrafficTypeVO publicTraffic = _pNTrafficTypeDao.findBy(publicPhyNetwork.getId(), TrafficType.Public);
-            if (publicTraffic != null) {
-                String label = null;
-                switch (hypervisorType) {
-                    case XenServer:
-                        label = publicTraffic.getXenNetworkLabel();
-                        break;
-                    case KVM:
-                        label = publicTraffic.getKvmNetworkLabel();
-                        break;
-                    case VMware:
-                        label = publicTraffic.getVmwareNetworkLabel();
-                        break;
-                    case Hyperv:
-                        label = publicTraffic.getHypervNetworkLabel();
-                        break;
-                    case Ovm3:
-                        label = publicTraffic.getOvm3NetworkLabel();
-                        break;
-                }
-                return label;
-            }
-        } catch (Exception ex) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to retrieve the default label for public traffic." + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to: " +
-                    ex.getMessage());
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType hypervisorType) {
-        try {
-            PhysicalNetwork guestPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Guest);
-            PhysicalNetworkTrafficTypeVO guestTraffic = _pNTrafficTypeDao.findBy(guestPhyNetwork.getId(), TrafficType.Guest);
-            if (guestTraffic != null) {
-                String label = null;
-                switch (hypervisorType) {
-                    case XenServer:
-                        label = guestTraffic.getXenNetworkLabel();
-                        break;
-                    case KVM:
-                        label = guestTraffic.getKvmNetworkLabel();
-                        break;
-                    case VMware:
-                        label = guestTraffic.getVmwareNetworkLabel();
-                        break;
-                    case Hyperv:
-                        label = guestTraffic.getHypervNetworkLabel();
-                        break;
-                    case Ovm3:
-                        label = guestTraffic.getOvm3NetworkLabel();
-                        break;
-                }
-                return label;
-            }
-        } catch (Exception ex) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to:" +
-                    ex.getMessage());
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<? extends Network> listNetworksByVpc(long vpcId) {
-        return _networksDao.listByVpc(vpcId);
-    }
-
-    @Override
-    public List<Provider> getNtwkOffDistinctProviders(long ntkwOffId) {
-        List<String> providerNames = _ntwkOfferingSrvcDao.getDistinctProviders(ntkwOffId);
-        List<Provider> providers = new ArrayList<Provider>();
-        for (String providerName : providerNames) {
-            providers.add(Network.Provider.getProvider(providerName));
-        }
-
-        return providers;
-    }
-
-    @Override
-    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
-        if (_nicDao.findNonReleasedByInstanceIdAndNetworkId(ntwkId, vmId) != null) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
-
-        List<? extends PhysicalNetwork> pNtwks = _physicalNetworkDao.listByZone(zoneId);
-
-        Iterator<? extends PhysicalNetwork> it = pNtwks.iterator();
-        while (it.hasNext()) {
-            PhysicalNetwork pNtwk = it.next();
-            if (!_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
-                it.remove();
-            }
-        }
-        return pNtwks;
-    }
-
-    @Override
-    public boolean isPrivateGateway(long ntwkId) {
-        Network network = getNetwork(ntwkId);
-        if (network.getTrafficType() != TrafficType.Guest || network.getNetworkOfferingId() != s_privateOfferingId.longValue()) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
-        List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(offeringNames.length);
-        for (String offeringName : offeringNames) {
-            NetworkOfferingVO network = _systemNetworks.get(offeringName);
-            if (network == null) {
-                throw new CloudRuntimeException("Unable to find system network profile for " + offeringName);
-            }
-            offerings.add(network);
-        }
-        return offerings;
-    }
-
-    @Override
-    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
-        Long networkDomainId = null;
-        Network network = getNetwork(networkId);
-        if (network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) {
-            s_logger.trace("Network id=" + networkId + " is not shared or L2");
-            return false;
-        }
-
-        NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
-        if (networkDomainMap == null) {
-            s_logger.trace("Network id=" + networkId + " is shared or L2, but not domain specific");
-            return true;
-        } else {
-            networkDomainId = networkDomainMap.getDomainId();
-        }
-
-        if (domainId == networkDomainId.longValue()) {
-            return true;
-        }
-
-        if (networkDomainMap.subdomainAccess) {
-            Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
-
-            if (parentDomains.contains(networkDomainId)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public Set<Long> getAvailableIps(Network network, String requestedIp) {
-        if (network.getCidr() == null) {
-            return Collections.emptySet();
-        }
-        String[] cidr = network.getCidr().split("/");
-        List<String> ips = getUsedIpsInNetwork(network);
-        Set<Long> usedIps = new TreeSet<Long>();
-
-        for (String ip : ips) {
-            if (requestedIp != null && requestedIp.equals(ip)) {
-                s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
-                return null;
-            }
-
-            usedIps.add(NetUtils.ip2Long(ip));
-        }
-
-        Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
-
-        String gateway = network.getGateway();
-        if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
-            allPossibleIps.remove(NetUtils.ip2Long(gateway));
-
-        return allPossibleIps;
-    }
-
-    @Override
-    public List<String> getUsedIpsInNetwork(Network network) {
-        //Get all ips used by vms nics
-        List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
-        //Get all secondary ips for nics
-        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
-        ips.addAll(secondaryIps);
-        //Get ips used by load balancers
-        List<String> lbIps = _appLbRuleDao.listLbIpsBySourceIpNetworkId(network.getId());
-        ips.addAll(lbIps);
-        return ips;
-    }
-
-    @Override
-    public String getDomainNetworkDomain(long domainId, long zoneId) {
-        String networkDomain = null;
-        Long searchDomainId = domainId;
-        while (searchDomainId != null) {
-            DomainVO domain = _domainDao.findById(searchDomainId);
-            if (domain.getNetworkDomain() != null) {
-                networkDomain = domain.getNetworkDomain();
-                break;
-            }
-            searchDomainId = domain.getParent();
-        }
-        if (networkDomain == null) {
-            return getZoneNetworkDomain(zoneId);
-        }
-        return networkDomain;
-    }
-
-    boolean isProviderEnabled(PhysicalNetworkServiceProvider provider) {
-        if (provider == null || provider.getState() != PhysicalNetworkServiceProvider.State.Enabled) { // TODO: check
-            // for other states: Shutdown?
-            return false;
-        }
-        return true;
-    }
-
-    boolean isServiceEnabledInNetwork(long physicalNetworkId, long networkId, Service service) {
-        // check if the service is supported in the network
-        if (!areServicesSupportedInNetwork(networkId, service)) {
-            s_logger.debug("Service " + service.getName() + " is not supported in the network id=" + networkId);
-            return false;
-        }
-
-        // get provider for the service and check if all of them are supported
-        String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
-        if (!isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
-            s_logger.debug("Provider " + provider + " is not enabled in physical network id=" + physicalNetworkId);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
-        return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
-    }
-
-    String getZoneNetworkDomain(long zoneId) {
-        return _dcDao.findById(zoneId).getDomain();
-    }
-
-    PhysicalNetwork getOnePhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
-
-        if (networkList.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in zone id=" + zoneId + ". ");
-        }
-
-        if (networkList.size() > 1) {
-            s_logger.info("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType + ". ");
-        }
-
-        return networkList.get(0);
-    }
-
-    protected Long getNonGuestNetworkPhysicalNetworkId(Network network, TrafficType trafficType) {
-        // VMware control network is management network
-        // we need to retrieve traffic label information through physical network
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-
-        if (physicalNetworkId == null) {
-            List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
-            if (pNtwks.size() == 1) {
-                physicalNetworkId = pNtwks.get(0).getId();
-            } else {
-                // locate physicalNetwork with supported traffic type
-                // We can make this assumptions based on the fact that Public/Management/Control traffic types are
-                // supported only in one physical network in the zone in 3.0
-                for (PhysicalNetworkVO pNtwk : pNtwks) {
-                    if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
-                        physicalNetworkId = pNtwk.getId();
-                        break;
-                    }
-                }
-            }
-        }
-        return physicalNetworkId;
-    }
-
-    protected Long getNonGuestNetworkPhysicalNetworkId(Network network) {
-        // no physical network for control traffic type
-
-        // have to remove this sanity check as VMware control network is management network
-        // we need to retrieve traffic label information through physical network
-        /*
-                if (network.getTrafficType() == TrafficType.Control) {
-                    return null;
-                }
-        */
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-
-        if (physicalNetworkId == null) {
-            List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
-            if (pNtwks.size() == 1) {
-                physicalNetworkId = pNtwks.get(0).getId();
-            } else {
-                // locate physicalNetwork with supported traffic type
-                // We can make this assumptions based on the fact that Public/Management/Control traffic types are
-                // supported only in one physical network in the zone in 3.0
-                for (PhysicalNetworkVO pNtwk : pNtwks) {
-                    if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), network.getTrafficType())) {
-                        physicalNetworkId = pNtwk.getId();
-                        break;
-                    }
-                }
-            }
-        }
-        return physicalNetworkId;
-    }
-
-    @Override
-    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
-        NicVO nic = null;
-        if (broadcastUri != null) {
-            nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(networkId, vm.getId(), broadcastUri);
-        } else {
-            nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vm.getId());
-        }
-        if (nic == null) {
-            return null;
-        }
-        NetworkVO network = _networksDao.findById(networkId);
-        Integer networkRate = getNetworkRate(network.getId(), vm.getId());
-
-//        NetworkGuru guru = _networkGurus.get(network.getGuruName());
-        NicProfile profile =
-            new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(
-                vm.getHypervisorType(), network));
-//        guru.updateNicProfile(profile, network);
-        return profile;
-    }
-
-    @Override
-    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
-        List<Provider> networkProviders = getNetworkProviders(networkId);
-        for (Provider provider : networkProviders) {
-            if (provider.isExternal()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private List<Provider> getNetworkProviders(long networkId) {
-        List<String> providerNames = _ntwkSrvcDao.getDistinctProviders(networkId);
-        Map<String, Provider> providers = new HashMap<String, Provider>();
-        for (String providerName : providerNames) {
-            if (!providers.containsKey(providerName)) {
-                providers.put(providerName, Network.Provider.getProvider(providerName));
-            }
-        }
-
-        return new ArrayList<Provider>(providers.values());
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _configs = _configDao.getConfiguration("Network", params);
-        _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key()));
-        _executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key()));
-
-        NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPublicNetwork, TrafficType.Public, true);
-        publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering);
-        _systemNetworks.put(NetworkOffering.SystemPublicNetwork, publicNetworkOffering);
-        NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemManagementNetwork, TrafficType.Management, false);
-        managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering);
-        _systemNetworks.put(NetworkOffering.SystemManagementNetwork, managementNetworkOffering);
-        NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemControlNetwork, TrafficType.Control, false);
-        controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
-        _systemNetworks.put(NetworkOffering.SystemControlNetwork, controlNetworkOffering);
-        NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
-        storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
-        _systemNetworks.put(NetworkOffering.SystemStorageNetwork, storageNetworkOffering);
-        NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
-        privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
-        _systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering);
-        s_privateOfferingId = privateGatewayNetworkOffering.getId();
-
-        IpAddressSearch = _ipAddressDao.createSearchBuilder();
-        IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
-        IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
-        IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ);
-        IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ);
-        SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
-        virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
-        IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(),
-            JoinBuilder.JoinType.INNER);
-        IpAddressSearch.done();
-
-        NicForTrafficTypeSearch = _nicDao.createSearchBuilder();
-        SearchBuilder<NetworkVO> networkSearch = _networksDao.createSearchBuilder();
-        NicForTrafficTypeSearch.join("network", networkSearch, networkSearch.entity().getId(), NicForTrafficTypeSearch.entity().getNetworkId(), JoinType.INNER);
-        NicForTrafficTypeSearch.and("instance", NicForTrafficTypeSearch.entity().getInstanceId(), Op.EQ);
-        networkSearch.and("traffictype", networkSearch.entity().getTrafficType(), Op.EQ);
-        NicForTrafficTypeSearch.done();
-
-        s_logger.info("Network Model is configured.");
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // populate s_serviceToImplementedProvidersMap & s_providerToNetworkElementMap with current _networkElements
-        // Need to do this in start() since _networkElements are not completely configured until then.
-        for (NetworkElement element : networkElements) {
-            Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
-            Provider implementedProvider = element.getProvider();
-            if (implementedProvider != null) {
-                if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) {
-                    s_logger.error("Cannot start NetworkModel: Provider <-> NetworkElement must be a one-to-one map, " + "multiple NetworkElements found for Provider: " +
-                        implementedProvider.getName());
-                    continue;
-                }
-                s_logger.info("Add provider <-> element map entry. " + implementedProvider.getName() + "-" + element.getName() + "-" + element.getClass().getSimpleName());
-                s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName());
-            }
-            if (capabilities != null && implementedProvider != null) {
-                for (Service service : capabilities.keySet()) {
-                    if (s_serviceToImplementedProvidersMap.containsKey(service)) {
-                        List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
-                        providers.add(implementedProvider);
-                    } else {
-                        List<Provider> providers = new ArrayList<Provider>();
-                        providers.add(implementedProvider);
-                        s_serviceToImplementedProvidersMap.put(service, providers);
-                    }
-                }
-            }
-        }
-
-        //After network elements are configured correctly, verify ConfigDrive entries on enabled zones
-        verifyDisabledConfigDriveEntriesOnEnabledZones();
-
-        s_logger.info("Started Network Model");
-        return true;
-    }
-
-    /**
-     * Verifies ConfigDrive entries on a zone and adds disabled ConfigDrive provider if missing.
-     */
-    protected void addDisabledConfigDriveEntriesOnZone(DataCenterVO zone) {
-        if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
-            List<PhysicalNetworkVO> physicalNetworks = _physicalNetworkDao.listByZoneAndTrafficType(
-                    zone.getId(), TrafficType.Guest);
-            for (PhysicalNetworkVO physicalNetworkVO : physicalNetworks) {
-                PhysicalNetworkServiceProviderVO provider = _pNSPDao.findByServiceProvider(
-                        physicalNetworkVO.getId(), Provider.ConfigDrive.getName());
-                if (provider == null) {
-                    _networkService.addProviderToPhysicalNetwork(
-                            physicalNetworkVO.getId(), Provider.ConfigDrive.getName(), null, null);
-                }
-            }
-        }
-    }
-
-    /**
-     * Verifies ConfigDrive entries on enabled zones, adds disabled ConfigDrive provider if missing.
-     */
-    protected void verifyDisabledConfigDriveEntriesOnEnabledZones() {
-        List<DataCenterVO> zones = _dcDao.listEnabledZones();
-        if (CollectionUtils.isNotEmpty(zones)) {
-            for (DataCenterVO zone : zones) {
-                addDisabledConfigDriveEntriesOnZone(zone);
-            }
-        }
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
-        List<? extends IpAddress> addrs = listPublicIpsAssignedToGuestNtwk(owner.getId(), guestNetwork.getId(), true);
-
-        IPAddressVO sourceNatIp = null;
-        if (addrs.isEmpty()) {
-            return null;
-        } else {
-            for (IpAddress addr : addrs) {
-                if (addr.isSourceNat()) {
-                    sourceNatIp = _ipAddressDao.findById(addr.getId());
-                    return PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean isNetworkInlineMode(Network network) {
-        NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        return offering.isInline();
-    }
-
-    @Override
-    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
-        if (!NetUtils.isValidIp6(startIPv6)) {
-            throw new InvalidParameterValueException("Invalid format for the startIPv6 parameter");
-        }
-        if (!NetUtils.isValidIp6(endIPv6)) {
-            throw new InvalidParameterValueException("Invalid format for the endIPv6 parameter");
-        }
-
-        if (!(ip6Gateway != null && ip6Cidr != null)) {
-            throw new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in");
-        }
-
-        if (!NetUtils.isValidIp6(ip6Gateway)) {
-            throw new InvalidParameterValueException("Invalid ip6Gateway");
-        }
-        if (!NetUtils.isValidIp6Cidr(ip6Cidr)) {
-            throw new InvalidParameterValueException("Invalid ip6cidr");
-        }
-        if (!NetUtils.isIp6InNetwork(startIPv6, ip6Cidr)) {
-            throw new InvalidParameterValueException("startIPv6 is not in ip6cidr indicated network!");
-        }
-        if (!NetUtils.isIp6InNetwork(endIPv6, ip6Cidr)) {
-            throw new InvalidParameterValueException("endIPv6 is not in ip6cidr indicated network!");
-        }
-        if (!NetUtils.isIp6InNetwork(ip6Gateway, ip6Cidr)) {
-            throw new InvalidParameterValueException("ip6Gateway is not in ip6cidr indicated network!");
-        }
-
-        int cidrSize = NetUtils.getIp6CidrSize(ip6Cidr);
-        // we only support cidr == 64
-        if (cidrSize != 64) {
-            throw new InvalidParameterValueException("The cidr size of IPv6 network must be 64 bits!");
-        }
-    }
-
-    @Override
-    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
-        String ip4 = ips.getIp4Address();
-        String ip6 = ips.getIp6Address();
-        String mac = ips.getMacAddress();
-        if (ip4 != null) {
-            if (!NetUtils.isValidIp4(ip4)) {
-                throw new InvalidParameterValueException("Invalid specified IPv4 address " + ip4);
-            }
-            //Other checks for ipv4 are done in assignPublicIpAddress()
-        }
-        if (ip6 != null) {
-            if (!NetUtils.isValidIp6(ip6)) {
-                throw new InvalidParameterValueException("Invalid specified IPv6 address " + ip6);
-            }
-            if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip6) != null) {
-                throw new InvalidParameterValueException("The requested IP is already taken!");
-            }
-            List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
-            if (vlans == null) {
-                throw new CloudRuntimeException("Cannot find related vlan attached to network " + networkId);
-            }
-            Vlan ipVlan = null;
-            for (Vlan vlan : vlans) {
-                if (NetUtils.isIp6InRange(ip6, vlan.getIp6Range())) {
-                    ipVlan = vlan;
-                    break;
-                }
-            }
-            if (ipVlan == null) {
-                throw new InvalidParameterValueException("Requested IPv6 is not in the predefined range!");
-            }
-        }
-        if (mac != null) {
-            if(!NetUtils.isValidMac(mac)) {
-                throw new InvalidParameterValueException("Invalid specified MAC address " + mac);
-            }
-            if (_nicDao.findByNetworkIdAndMacAddress(networkId, mac) != null) {
-                throw new InvalidParameterValueException("The requested Mac address is already taken! " + mac);
-            }
-
-        }
-    }
-
-    @Override
-    public String getStartIpv6Address(long networkId) {
-        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
-        if (vlans == null) {
-            return null;
-        }
-        String startIpv6 = null;
-        // Get the start ip of first create vlan(not the lowest, because if you add a lower vlan, lowest vlan would change)
-        for (Vlan vlan : vlans) {
-            if (vlan.getIp6Range() != null) {
-                startIpv6 = vlan.getIp6Range().split("-")[0];
-                break;
-            }
-        }
-        return startIpv6;
-    }
-
-    @Override
-    public NicVO getPlaceholderNicForRouter(Network network, Long podId) {
-        List<NicVO> nics = _nicDao.listPlaceholderNicsByNetworkIdAndVmType(network.getId(), VirtualMachine.Type.DomainRouter);
-        List<? extends Vlan> vlans = new ArrayList<VlanVO>();
-        if (podId != null) {
-            vlans = _vlanDao.listVlansForPod(podId);
-        }
-        for (NicVO nic : nics) {
-            if (nic.getReserver() == null && (nic.getIPv4Address() != null || nic.getIPv6Address() != null)) {
-                if (podId == null) {
-                    return nic;
-                } else {
-                    IpAddress ip = null;
-                    UserIpv6AddressVO ipv6 = null;
-
-                    if (nic.getIPv4Address() != null) {
-                        ip = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address());
-                    } else {
-                        ipv6 = _ipv6Dao.findByNetworkIdAndIp(network.getId(), nic.getIPv6Address());
-                    }
-                    //return nic only when its ip address belong to the pod range (for the Basic zone case)
-                    for (Vlan vlan : vlans) {
-                        if (ip != null && ip.getVlanId() == vlan.getId()) {
-                            return nic;
-                        } else if (ipv6 != null && ipv6.getVlanId() == vlan.getId()) {
-                            return nic;
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
-        List<? extends Network> networks = _networksDao.listByZoneAndTrafficType(zoneId, TrafficType.Public);
-        if (networks.isEmpty() || networks.size() > 1) {
-            throw new CloudRuntimeException("Can't find public network in the zone specified");
-        }
-
-        return _ipAddressDao.findByIpAndSourceNetworkId(networks.get(0).getId(), ipAddress);
-    }
-
-    @Override
-    public Map<Detail, String> getNtwkOffDetails(long offId) {
-        return _ntwkOffDetailsDao.getNtwkOffDetails(offId);
-    }
-
-    @Override
-    public Networks.IsolationType[] listNetworkIsolationMethods() {
-        return Networks.IsolationType.values();
-    }
-
-    @Override
-    public boolean getExecuteInSeqNtwkElmtCmd() {
-        return _executeInSequenceNtwkElmtCmd;
-    }
-
-    @Override
-    public boolean isNetworkReadyForGc(long networkId) {
-        Network network = getNetwork(networkId);
-        List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
-        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(networkId);
-        if (!networkIds.contains(networkId)) {
-            return false;
-        }
-
-        // add an exception for networks that use external networking devices and has secondary guest IP's allocated.
-        // On network GC, when network goes through implement phase a new vlan is allocated, based on the acquired VLAN
-        // id cidr of the network is decided in case of external networking case. While NIC uses reservation strategy 'Start'
-        // which ensures that new primary ip is allocated for the NiC from the new CIDR. Secondary IP's have hardcoded IP's in
-        // network rules. So prevent network GC.
-        if (secondaryIps != null && !secondaryIps.isEmpty() && networkIsConfiguredForExternalNetworking(network.getDataCenterId(), networkId)) {
-            return false;
-        }
-
-        //if the network has vms in Starting state (nics for those might not be allocated yet as Starting state also used when vm is being Created)
-        //don't GC
-        if (_nicDao.countNicsForStartingVms(networkId) > 0) {
-            s_logger.debug("Network id=" + networkId + " is not ready for GC as it has vms that are Starting at the moment");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
-        NetworkVO network = _networksDao.findById(networkId);
-
-        if (network != null) {
-            NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-            return offering.getEgressDefaultPolicy();
-        } else {
-            InvalidParameterValueException ex = new InvalidParameterValueException("network with network id does not exist");
-            throw ex;
-        }
-    }
-
-    @Override
-    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
-                                         String vmName, String vmHostName, long vmId, String vmUuid,
-                                         String guestIpAddress, String publicKey, String password, Boolean isWindows) {
-
-        DataCenterVO dcVo = _dcDao.findById(datacenterId);
-        final String zoneName = dcVo.getName();
-
-        IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId);
-
-        final List<String[]> vmData = new ArrayList<String[]>();
-
-        if (userData != null) {
-            vmData.add(new String[]{USERDATA_DIR, USERDATA_FILE, userData});
-        }
-        vmData.add(new String[]{METATDATA_DIR, SERVICE_OFFERING_FILE, StringUtils.unicodeEscape(serviceOffering)});
-        vmData.add(new String[]{METATDATA_DIR, AVAILABILITY_ZONE_FILE, StringUtils.unicodeEscape(zoneName)});
-        vmData.add(new String[]{METATDATA_DIR, LOCAL_HOSTNAME_FILE, StringUtils.unicodeEscape(vmHostName)});
-        vmData.add(new String[]{METATDATA_DIR, LOCAL_IPV4_FILE, guestIpAddress});
-
-        String publicIpAddress = guestIpAddress;
-        String publicHostName = StringUtils.unicodeEscape(vmHostName);
-
-        if (dcVo.getNetworkType() != DataCenter.NetworkType.Basic) {
-            if (publicIp != null) {
-                publicIpAddress = publicIp.getAddress().addr();
-                publicHostName = publicIp.getAddress().addr();
-            } else {
-                publicHostName = null;
-            }
-        }
-        vmData.add(new String[]{METATDATA_DIR, PUBLIC_IPV4_FILE, publicIpAddress});
-        vmData.add(new String[]{METATDATA_DIR, PUBLIC_HOSTNAME_FILE, publicHostName});
-
-        if (vmUuid == null) {
-            vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmName});
-            vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, String.valueOf(vmId)});
-        } else {
-            vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmUuid});
-            vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, vmUuid});
-        }
-
-        vmData.add(new String[]{METATDATA_DIR, PUBLIC_KEYS_FILE, publicKey});
-
-        String cloudIdentifier = _configDao.getValue("cloud.identifier");
-        if (cloudIdentifier == null) {
-            cloudIdentifier = "";
-        } else {
-            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
-        }
-        vmData.add(new String[]{METATDATA_DIR, CLOUD_IDENTIFIER_FILE, cloudIdentifier});
-
-        if (password != null && !password.isEmpty() && !password.equals("saved_password")) {
-
-            // Here we are calculating MD5 checksum to reduce the over head of calculating MD5 checksum
-            // in windows VM in password reset script.
-
-            if (isWindows) {
-                MessageDigest md5 = null;
-                try {
-                    md5 = MessageDigest.getInstance("MD5");
-                } catch (NoSuchAlgorithmException e) {
-                    s_logger.error("Unexpected exception " + e.getMessage(), e);
-                    throw new CloudRuntimeException("Unable to get MD5 MessageDigest", e);
-                }
-                md5.reset();
-                md5.update(password.getBytes(StringUtils.getPreferredCharset()));
-                byte[] digest = md5.digest();
-                BigInteger bigInt = new BigInteger(1, digest);
-                String hashtext = bigInt.toString(16);
-
-                vmData.add(new String[]{PASSWORD_DIR, PASSWORD_CHECKSUM_FILE, hashtext});
-            }
-
-            vmData.add(new String[]{PASSWORD_DIR, PASSWORD_FILE, password});
-        }
-
-        return vmData;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return NetworkModel.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {MACIdentifier};
-    }
-
-    @Override
-    public String getValidNetworkCidr(Network guestNetwork) {
-        String networkCidr = guestNetwork.getNetworkCidr();
-        return networkCidr == null ? guestNetwork.getCidr() : networkCidr;
-    }
-}
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
deleted file mode 100644
index b0839f9..0000000
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ /dev/null
@@ -1,4517 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network;
-
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.security.InvalidParameterException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
-import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
-import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DataCenterVnetVO;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterVnetDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.UnsupportedServiceException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.network.IpAddress.State;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork.BroadcastDomainRange;
-import com.cloud.network.VirtualRouterProvider.Type;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.AccountGuestVlanMapDao;
-import com.cloud.network.dao.AccountGuestVlanMapVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailVO;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.NetworkDomainDao;
-import com.cloud.network.dao.NetworkDomainVO;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.OvsProviderDao;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
-import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.OvsProviderVO;
-import com.cloud.network.element.VirtualRouterElement;
-import com.cloud.network.element.VpcVirtualRouterElement;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.security.SecurityGroupService;
-import com.cloud.network.vpc.NetworkACL;
-import com.cloud.network.vpc.PrivateIpVO;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.dao.VpcOfferingDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.org.Grouping;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectManager;
-import com.cloud.server.ResourceTag;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.AccountVO;
-import com.cloud.user.DomainManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.Journal;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-/**
- * NetworkServiceImpl implements NetworkService.
- */
-public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
-    private static final Logger s_logger = Logger.getLogger(NetworkServiceImpl.class);
-
-    private static final long MIN_VLAN_ID = 0L;
-    private static final long MAX_VLAN_ID = 4095L; // 2^12 - 1
-    private static final long MIN_GRE_KEY = 0L;
-    private static final long MAX_GRE_KEY = 4294967295L; // 2^32 -1
-    private static final long MIN_VXLAN_VNI = 0L;
-    private static final long MAX_VXLAN_VNI = 16777214L; // 2^24 -2
-    // MAX_VXLAN_VNI should be 16777215L (2^24-1), but Linux vxlan interface doesn't accept VNI:2^24-1 now.
-    // It seems a bug.
-
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    VlanDao _vlanDao = null;
-    @Inject
-    IPAddressDao _ipAddressDao = null;
-    @Inject
-    AccountDao _accountDao = null;
-    @Inject
-    DomainDao _domainDao = null;
-    @Inject
-    UserDao _userDao = null;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    UserVmDao _userVmDao = null;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao = null;
-    @Inject
-    NetworkDao _networksDao = null;
-    @Inject
-    NicDao _nicDao = null;
-    @Inject
-    RulesManager _rulesMgr;
-    List<NetworkGuru> _networkGurus;
-    @Inject
-    NetworkDomainDao _networkDomainDao;
-    @Inject
-    VMInstanceDao _vmDao;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    DomainManager _domainMgr;
-    @Inject
-    ProjectManager _projectMgr;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    PhysicalNetworkServiceProviderDao _pNSPDao;
-    @Inject
-    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    StorageNetworkManager _stnwMgr;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    PrivateIpDao _privateIpDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    PortForwardingRulesDao _portForwardingDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    InternalLoadBalancerElementService _internalLbElementSvc;
-    @Inject
-    DataCenterVnetDao _datacneterVnet;
-    @Inject
-    AccountGuestVlanMapDao _accountGuestVlanMapDao;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    OvsProviderDao _ovsProviderDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    public SecurityGroupService _securityGroupService;
-    @Inject
-    MessageBus _messageBus;
-    @Inject
-    NetworkDetailsDao _networkDetailsDao;
-    @Inject
-    LoadBalancerDao _loadBalancerDao;
-    @Inject
-    NetworkMigrationManager _networkMigrationManager;
-    @Inject
-    VpcOfferingDao _vpcOfferingDao;
-    @Inject
-    AccountService _accountService;
-
-    int _cidrLimit;
-    boolean _allowSubdomainNetworkAccess;
-
-    private Map<String, String> _configs;
-
-    /* Get a list of IPs, classify them by service */
-    protected Map<PublicIp, Set<Service>> getIpToServices(List<PublicIp> publicIps, boolean rulesRevoked, boolean includingFirewall) {
-        Map<PublicIp, Set<Service>> ipToServices = new HashMap<PublicIp, Set<Service>>();
-
-        if (publicIps != null && !publicIps.isEmpty()) {
-            Set<Long> networkSNAT = new HashSet<Long>();
-            for (PublicIp ip : publicIps) {
-                Set<Service> services = ipToServices.get(ip);
-                if (services == null) {
-                    services = new HashSet<Service>();
-                }
-                if (ip.isSourceNat()) {
-                    if (!networkSNAT.contains(ip.getAssociatedWithNetworkId())) {
-                        services.add(Service.SourceNat);
-                        networkSNAT.add(ip.getAssociatedWithNetworkId());
-                    } else {
-                        CloudRuntimeException ex = new CloudRuntimeException("Multiple generic soure NAT IPs provided for network");
-                        // see the IPAddressVO.java class.
-                        IPAddressVO ipAddr = ApiDBUtils.findIpAddressById(ip.getAssociatedWithNetworkId());
-                        String ipAddrUuid = ip.getAssociatedWithNetworkId().toString();
-                        if (ipAddr != null) {
-                            ipAddrUuid = ipAddr.getUuid();
-                        }
-                        ex.addProxyObject(ipAddrUuid, "networkId");
-                        throw ex;
-                    }
-                }
-                ipToServices.put(ip, services);
-
-                // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service
-                // provider
-                if (ip.getState() == State.Allocating) {
-                    continue;
-                }
-
-                // check if any active rules are applied on the public IP
-                Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false, includingFirewall);
-                // Firewall rules didn't cover static NAT
-                if (ip.isOneToOneNat() && ip.getAssociatedWithVmId() != null) {
-                    if (purposes == null) {
-                        purposes = new HashSet<Purpose>();
-                    }
-                    purposes.add(Purpose.StaticNat);
-                }
-                if (purposes == null || purposes.isEmpty()) {
-                    // since no active rules are there check if any rules are applied on the public IP but are in
-// revoking state
-
-                    purposes = getPublicIpPurposeInRules(ip, true, includingFirewall);
-                    if (ip.isOneToOneNat()) {
-                        if (purposes == null) {
-                            purposes = new HashSet<Purpose>();
-                        }
-                        purposes.add(Purpose.StaticNat);
-                    }
-                    if (purposes == null || purposes.isEmpty()) {
-                        // IP is not being used for any purpose so skip IPAssoc to network service provider
-                        continue;
-                    } else {
-                        if (rulesRevoked) {
-                            // no active rules/revoked rules are associated with this public IP, so remove the
-// association with the provider
-                            ip.setState(State.Releasing);
-                        } else {
-                            if (ip.getState() == State.Releasing) {
-                                // rules are not revoked yet, so don't let the network service provider revoke the IP
-// association
-                                // mark IP is allocated so that IP association will not be removed from the provider
-                                ip.setState(State.Allocated);
-                            }
-                        }
-                    }
-                }
-                if (purposes.contains(Purpose.StaticNat)) {
-                    services.add(Service.StaticNat);
-                }
-                if (purposes.contains(Purpose.LoadBalancing)) {
-                    services.add(Service.Lb);
-                }
-                if (purposes.contains(Purpose.PortForwarding)) {
-                    services.add(Service.PortForwarding);
-                }
-                if (purposes.contains(Purpose.Vpn)) {
-                    services.add(Service.Vpn);
-                }
-                if (purposes.contains(Purpose.Firewall)) {
-                    services.add(Service.Firewall);
-                }
-                if (services.isEmpty()) {
-                    continue;
-                }
-                ipToServices.put(ip, services);
-            }
-        }
-        return ipToServices;
-    }
-
-    protected boolean canIpUsedForNonConserveService(PublicIp ip, Service service) {
-        // If it's non-conserve mode, then the new ip should not be used by any other services
-        List<PublicIp> ipList = new ArrayList<PublicIp>();
-        ipList.add(ip);
-        Map<PublicIp, Set<Service>> ipToServices = getIpToServices(ipList, false, false);
-        Set<Service> services = ipToServices.get(ip);
-        // Not used currently, safe
-        if (services == null || services.isEmpty()) {
-            return true;
-        }
-        // Since it's non-conserve mode, only one service should used for IP
-        if (services.size() != 1) {
-            throw new InvalidParameterException("There are multiple services used ip " + ip.getAddress() + ".");
-        }
-        if (service != null && !((Service)services.toArray()[0] == service || service.equals(Service.Firewall))) {
-            throw new InvalidParameterException("The IP " + ip.getAddress() + " is already used as " + ((Service)services.toArray()[0]).getName() + " rather than "
-                    + service.getName());
-        }
-        return true;
-    }
-
-    protected boolean canIpsUsedForNonConserve(List<PublicIp> publicIps) {
-        boolean result = true;
-        for (PublicIp ip : publicIps) {
-            result = canIpUsedForNonConserveService(ip, null);
-            if (!result) {
-                break;
-            }
-        }
-        return result;
-    }
-
-    private boolean canIpsUseOffering(List<PublicIp> publicIps, long offeringId) {
-        Map<PublicIp, Set<Service>> ipToServices = getIpToServices(publicIps, false, true);
-        Map<Service, Set<Provider>> serviceToProviders = _networkModel.getNetworkOfferingServiceProvidersMap(offeringId);
-        NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId);
-        //For inline mode checking, using firewall provider for LB instead, because public ip would apply on firewall provider
-        if (offering.isInline()) {
-            Provider firewallProvider = null;
-            if (serviceToProviders.containsKey(Service.Firewall)) {
-                firewallProvider = (Provider)serviceToProviders.get(Service.Firewall).toArray()[0];
-            }
-            Set<Provider> p = new HashSet<Provider>();
-            p.add(firewallProvider);
-            serviceToProviders.remove(Service.Lb);
-            serviceToProviders.put(Service.Lb, p);
-        }
-        for (PublicIp ip : ipToServices.keySet()) {
-            Set<Service> services = ipToServices.get(ip);
-            Provider provider = null;
-            for (Service service : services) {
-                Set<Provider> curProviders = serviceToProviders.get(service);
-                if (curProviders == null || curProviders.isEmpty()) {
-                    continue;
-                }
-                Provider curProvider = (Provider)curProviders.toArray()[0];
-                if (provider == null) {
-                    provider = curProvider;
-                    continue;
-                }
-                // We don't support multiple providers for one service now
-                if (!provider.equals(curProvider)) {
-                    throw new InvalidParameterException("There would be multiple providers for IP " + ip.getAddress() + " with the new network offering!");
-                }
-            }
-        }
-        return true;
-    }
-
-    private Set<Purpose> getPublicIpPurposeInRules(PublicIp ip, boolean includeRevoked, boolean includingFirewall) {
-        Set<Purpose> result = new HashSet<Purpose>();
-        List<FirewallRuleVO> rules = null;
-        if (includeRevoked) {
-            rules = _firewallDao.listByIp(ip.getId());
-        } else {
-            rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
-        }
-
-        if (rules == null || rules.isEmpty()) {
-            return null;
-        }
-
-        for (FirewallRuleVO rule : rules) {
-            if (rule.getPurpose() != Purpose.Firewall || includingFirewall) {
-                result.add(rule.getPurpose());
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) {
-
-        return _networksDao.listByZoneAndGuestType(owner.getId(), zoneId, Network.GuestType.Isolated, false);
-    }
-
-    @Override
-    public List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
-
-        return _networksDao.listSourceNATEnabledNetworks(owner.getId(), zoneId, Network.GuestType.Isolated);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true)
-    public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp) throws ResourceAllocationException, InsufficientAddressCapacityException,
-            ConcurrentOperationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        long callerUserId = CallContext.current().getCallingUserId();
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-
-        if (networkId != null) {
-            Network network = _networksDao.findById(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Invalid network id is given");
-            }
-
-            if (network.getGuestType() == Network.GuestType.Shared) {
-                if (zone == null) {
-                    throw new InvalidParameterValueException("Invalid zone Id is given");
-                }
-                // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
-                if (zone.getNetworkType() == NetworkType.Advanced) {
-                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
-                        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
-                        }
-                        return _ipAddrMgr.allocateIp(ipOwner, false, caller, callerUserId, zone, displayIp);
-                    } else {
-                        throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone"
-                                + " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
-                    }
-                }
-            }
-        } else {
-            _accountMgr.checkAccess(caller, null, false, ipOwner);
-        }
-
-        return _ipAddrMgr.allocateIp(ipOwner, false, caller, callerUserId, zone, displayIp);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_ASSIGN, eventDescription = "allocating portable public Ip", create = true)
-    public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
-            InsufficientAddressCapacityException, ConcurrentOperationException {
-        Account caller = CallContext.current().getCallingAccount();
-        long callerUserId = CallContext.current().getCallingUserId();
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-
-        if ((networkId == null && vpcId == null) || (networkId != null && vpcId != null)) {
-            throw new InvalidParameterValueException("One of Network id or VPC is should be passed");
-        }
-
-        if (networkId != null) {
-            Network network = _networksDao.findById(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Invalid network id is given");
-            }
-
-            if (network.getGuestType() == Network.GuestType.Shared) {
-                if (zone == null) {
-                    throw new InvalidParameterValueException("Invalid zone Id is given");
-                }
-                // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
-                if (zone.getNetworkType() == NetworkType.Advanced) {
-                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
-                        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
-                        }
-                        return _ipAddrMgr.allocatePortableIp(ipOwner, caller, zoneId, networkId, null);
-                    } else {
-                        throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone"
-                                + " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
-                    }
-                }
-            }
-        }
-
-        if (vpcId != null) {
-            Vpc vpc = _vpcDao.findById(vpcId);
-            if (vpc == null) {
-                throw new InvalidParameterValueException("Invalid vpc id is given");
-            }
-        }
-
-        _accountMgr.checkAccess(caller, null, false, ipOwner);
-
-        return _ipAddrMgr.allocatePortableIp(ipOwner, caller, zoneId, null, null);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RELEASE, eventDescription = "disassociating portable Ip", async = true)
-    public boolean releasePortableIpAddress(long ipAddressId) {
-        try {
-            return releaseIpAddressInternal(ipAddressId);
-        } catch (Exception e) {
-           return false;
-        }
-    }
-
-    @Override
-    @DB
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _configs = _configDao.getConfiguration("Network", params);
-
-        _cidrLimit = NumbersUtil.parseInt(_configs.get(Config.NetworkGuestCidrLimit.key()), 22);
-
-        _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key()));
-
-        s_logger.info("Network Service is configured.");
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    protected NetworkServiceImpl() {
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_CONFIGURE, eventDescription = "Configuring secondary ip " +
-            "rules",  async = true)
-    public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) {
-        boolean success = false;
-
-        if (isZoneSgEnabled) {
-            success = _securityGroupService.securityGroupRulesForVmSecIp(secIp.getNicId(), secIp.getIp4Address(), true);
-            s_logger.info("Associated ip address to NIC : " + secIp.getIp4Address());
-        } else {
-            success = true;
-        }
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN, eventDescription = "assigning secondary ip to nic", create = true)
-    public NicSecondaryIp allocateSecondaryGuestIP(final long nicId, String requestedIp) throws InsufficientAddressCapacityException {
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check whether the nic belongs to user vm.
-        final NicVO nicVO = _nicDao.findById(nicId);
-        if (nicVO == null) {
-            throw new InvalidParameterValueException("There is no nic for the " + nicId);
-        }
-
-        if (nicVO.getVmType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("The nic is not belongs to user vm");
-        }
-
-        VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId());
-        if (vm == null) {
-            throw new InvalidParameterValueException("There is no vm with the nic");
-        }
-
-        final long networkId = nicVO.getNetworkId();
-        final Account ipOwner = _accountMgr.getAccount(vm.getAccountId());
-
-        // verify permissions
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        Network network = _networksDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        int maxAllowedIpsPerNic = NumbersUtil.parseInt(_configDao.getValue(Config.MaxNumberOfSecondaryIPsPerNIC.key()), 10);
-        Long nicWiseIpCount = _nicSecondaryIpDao.countByNicId(nicId);
-        if(nicWiseIpCount.intValue() >= maxAllowedIpsPerNic) {
-            s_logger.error("Maximum Number of Ips \"vm.network.nic.max.secondary.ipaddresses = \"" + maxAllowedIpsPerNic + " per Nic has been crossed for the nic " +  nicId + ".");
-            throw new InsufficientAddressCapacityException("Maximum Number of Ips per Nic has been crossed.", Nic.class, nicId);
-        }
-
-
-        s_logger.debug("Calling the ip allocation ...");
-        String ipaddr = null;
-        //Isolated network can exist in Basic zone only, so no need to verify the zone type
-        if (network.getGuestType() == Network.GuestType.Isolated) {
-            try {
-                ipaddr = _ipAddrMgr.allocateGuestIP(network, requestedIp);
-            } catch (InsufficientAddressCapacityException e) {
-                throw new InvalidParameterValueException("Allocating guest ip for nic failed");
-            }
-        } else if (network.getGuestType() == Network.GuestType.Shared) {
-            //for basic zone, need to provide the podId to ensure proper ip alloation
-            Long podId = null;
-            DataCenter dc = _dcDao.findById(network.getDataCenterId());
-
-            if (dc.getNetworkType() == NetworkType.Basic) {
-            VMInstanceVO vmi = (VMInstanceVO)vm;
-                podId = vmi.getPodIdToDeployIn();
-            if (podId == null) {
-                    throw new InvalidParameterValueException("vm pod id is null in Basic zone; can't decide the range for ip allocation");
-            }
-            }
-
-            try {
-                ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, requestedIp);
-                if (ipaddr == null) {
-                    throw new InvalidParameterValueException("Allocating ip to guest nic " + nicId + " failed");
-                }
-            } catch (InsufficientAddressCapacityException e) {
-                s_logger.error("Allocating ip to guest nic " + nicId + " failed");
-                return null;
-            }
-        } else {
-            s_logger.error("AddIpToVMNic is not supported in this network...");
-            return null;
-        }
-
-        if (ipaddr != null) {
-            // we got the ip addr so up the nics table and secodary ip
-            final String addrFinal = ipaddr;
-            long id = Transaction.execute(new TransactionCallback<Long>() {
-                @Override
-                public Long doInTransaction(TransactionStatus status) {
-            boolean nicSecondaryIpSet = nicVO.getSecondaryIp();
-            if (!nicSecondaryIpSet) {
-                nicVO.setSecondaryIp(true);
-                // commit when previously set ??
-                s_logger.debug("Setting nics table ...");
-                _nicDao.update(nicId, nicVO);
-            }
-
-            s_logger.debug("Setting nic_secondary_ip table ...");
-                    Long vmId = nicVO.getInstanceId();
-                    NicSecondaryIpVO secondaryIpVO = new NicSecondaryIpVO(nicId, addrFinal, vmId, ipOwner.getId(), ipOwner.getDomainId(), networkId);
-            _nicSecondaryIpDao.persist(secondaryIpVO);
-                    return secondaryIpVO.getId();
-                }
-            });
-
-           return getNicSecondaryIp(id);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN, eventDescription = "Removing secondary ip " +
-            "from nic", async = true)
-    public boolean releaseSecondaryIpFromNic(long ipAddressId) {
-        Account caller = CallContext.current().getCallingAccount();
-        boolean success = false;
-
-        // Verify input parameters
-        NicSecondaryIpVO secIpVO = _nicSecondaryIpDao.findById(ipAddressId);
-        if (secIpVO == null) {
-            throw new InvalidParameterValueException("Unable to find secondary ip address by id");
-        }
-
-        VirtualMachine vm = _userVmDao.findById(secIpVO.getVmId());
-        if (vm == null) {
-            throw new InvalidParameterValueException("There is no vm with the given secondary ip");
-        }
-        // verify permissions
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        Network network = _networksDao.findById(secIpVO.getNetworkId());
-
-        if (network == null) {
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        // Validate network offering
-        NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId());
-
-        Long nicId = secIpVO.getNicId();
-        s_logger.debug("ip id = " + ipAddressId + " nic id = " + nicId);
-        //check is this the last secondary ip for NIC
-        List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
-        boolean lastIp = false;
-        if (ipList.size() == 1) {
-            // this is the last secondary ip to nic
-            lastIp = true;
-        }
-
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        if (dc == null) {
-            throw new InvalidParameterValueException("Invalid zone Id is given");
-        }
-
-        s_logger.debug("Calling secondary ip " + secIpVO.getIp4Address() + " release ");
-        if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
-            //check PF or static NAT is configured on this ip address
-            String secondaryIp = secIpVO.getIp4Address();
-            List<FirewallRuleVO> fwRulesList =  _firewallDao.listByNetworkAndPurpose(network.getId(), Purpose.PortForwarding);
-
-            if (fwRulesList.size() != 0) {
-                for (FirewallRuleVO rule : fwRulesList) {
-                    if (_portForwardingDao.findByIdAndIp(rule.getId(), secondaryIp) != null) {
-                        s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
-                        throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
-                    }
-                }
-            }
-            //check if the secondary ip associated with any static nat rule
-            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());
-            }
-
-            if (_loadBalancerDao.isLoadBalancerRulesMappedToVmGuestIp(vm.getId(), secondaryIp, network.getId())) {
-                s_logger.debug("VM nic IP " + secondaryIp + " is mapped to load balancing rule");
-                throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is mapped to load balancing rule");
-            }
-
-        } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
-            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address());
-            if (ip != null) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                _ipAddressDao.unassignIpAddress(ip.getId());
-                    }
-                });
-            }
-        } else {
-            throw new InvalidParameterValueException("Not supported for this network now");
-        }
-
-        success = removeNicSecondaryIP(secIpVO, lastIp);
-        return success;
-    }
-
-    boolean removeNicSecondaryIP(final NicSecondaryIpVO ipVO, final boolean lastIp) {
-        final long nicId = ipVO.getNicId();
-        final NicVO nic = _nicDao.findById(nicId);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-        if (lastIp) {
-            nic.setSecondaryIp(false);
-            s_logger.debug("Setting nics secondary ip to false ...");
-            _nicDao.update(nicId, nic);
-        }
-
-        s_logger.debug("Revoving nic secondary ip entry ...");
-        _nicSecondaryIpDao.remove(ipVO.getId());
-            }
-        });
-
-        return true;
-    }
-
-    NicSecondaryIp getNicSecondaryIp(long id) {
-        NicSecondaryIp nicSecIp = _nicSecondaryIpDao.findById(id);
-        if (nicSecIp == null) {
-            return null;
-        }
-        return nicSecIp;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true)
-    public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
-        return releaseIpAddressInternal(ipAddressId);
-    }
-
-    @DB
-    private boolean releaseIpAddressInternal(long ipAddressId) throws InsufficientAddressCapacityException {
-        Long userId = CallContext.current().getCallingUserId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Verify input parameters
-        IPAddressVO ipVO = _ipAddressDao.findById(ipAddressId);
-        if (ipVO == null) {
-            throw new InvalidParameterValueException("Unable to find ip address by id");
-        }
-
-        if (ipVO.getAllocatedTime() == null) {
-            s_logger.debug("Ip Address id= " + ipAddressId + " is not allocated, so do nothing.");
-            return true;
-        }
-
-        // verify permissions
-        if (ipVO.getAllocatedToAccountId() != null) {
-            _accountMgr.checkAccess(caller, null, true, ipVO);
-        }
-
-        if (ipVO.isSourceNat()) {
-            throw new IllegalArgumentException("ip address is used for source nat purposes and can not be disassociated.");
-        }
-
-        VlanVO vlan = _vlanDao.findById(ipVO.getVlanId());
-        if (!vlan.getVlanType().equals(VlanType.VirtualNetwork)) {
-            throw new IllegalArgumentException("only ip addresses that belong to a virtual network may be disassociated.");
-        }
-
-        // don't allow releasing system ip address
-        if (ipVO.getSystem()) {
-            throwInvalidIdException("Can't release system IP address with specified id", ipVO.getUuid(), "systemIpAddrId");
-        }
-
-        boolean success = _ipAddrMgr.disassociatePublicIpAddress(ipAddressId, userId, caller);
-
-        if (success) {
-            Long networkId = ipVO.getAssociatedWithNetworkId();
-            if (networkId != null) {
-                Network guestNetwork = getNetwork(networkId);
-                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-                Long vmId = ipVO.getAssociatedWithVmId();
-                if (offering.getElasticIp() && vmId != null) {
-                    _rulesMgr.getSystemIpAndEnableStaticNatForVm(_userVmDao.findById(vmId), true);
-                    return true;
-                }
-            }
-        } else {
-            s_logger.warn("Failed to release public ip address id=" + ipAddressId);
-        }
-        return success;
-    }
-
-    @Override
-    @DB
-    public Network getNetwork(long id) {
-        return _networksDao.findById(id);
-    }
-
-    private void checkSharedNetworkCidrOverlap(Long zoneId, long physicalNetworkId, String cidr) {
-        if (zoneId == null || cidr == null) {
-            return;
-        }
-
-        DataCenter zone = _dcDao.findById(zoneId);
-        List<NetworkVO> networks = _networksDao.listByZone(zoneId);
-        Map<Long, String> networkToCidr = new HashMap<Long, String>();
-
-        // check for CIDR overlap with all possible CIDR for isolated guest networks
-        // in the zone when using external networking
-        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork.getVnet() != null) {
-            List<Pair<Integer, Integer>> vlanList = pNetwork.getVnet();
-            for (Pair<Integer, Integer> vlanRange : vlanList) {
-                Integer lowestVlanTag = vlanRange.first();
-                Integer highestVlanTag = vlanRange.second();
-                for (int vlan = lowestVlanTag; vlan <= highestVlanTag; ++vlan) {
-                    int offset = vlan - lowestVlanTag;
-                    String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
-                    int cidrSize = 8 + Integer.parseInt(globalVlanBits);
-                    String guestNetworkCidr = zone.getGuestNetworkCidr();
-                    String[] cidrTuple = guestNetworkCidr.split("\\/");
-                    long newCidrAddress = (NetUtils.ip2Long(cidrTuple[0]) & 0xff000000) | (offset << (32 - cidrSize));
-                    if (NetUtils.isNetworksOverlap(NetUtils.long2Ip(newCidrAddress), cidr)) {
-                        throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR that is reserved for zone vlan " + vlan);
-                    }
-                }
-            }
-        }
-
-        // check for CIDR overlap with all CIDR's of the shared networks in the zone
-        for (NetworkVO network : networks) {
-            if (network.getGuestType() == GuestType.Isolated) {
-                continue;
-            }
-            if (network.getCidr() != null) {
-                networkToCidr.put(network.getId(), network.getCidr());
-            }
-        }
-        if (networkToCidr != null && !networkToCidr.isEmpty()) {
-            for (long networkId : networkToCidr.keySet()) {
-                String ntwkCidr = networkToCidr.get(networkId);
-                if (NetUtils.isNetworksOverlap(ntwkCidr, cidr)) {
-                    throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR of a shared network in the zone.");
-                }
-            }
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
-    public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
-        Long networkOfferingId = cmd.getNetworkOfferingId();
-        String gateway = cmd.getGateway();
-        String startIP = cmd.getStartIp();
-        String endIP = cmd.getEndIp();
-        String netmask = cmd.getNetmask();
-        String networkDomain = cmd.getNetworkDomain();
-        String vlanId = null;
-        boolean bypassVlanOverlapCheck = false;
-        if (cmd instanceof CreateNetworkCmdByAdmin) {
-            vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
-        }
-        if (cmd instanceof CreateNetworkCmdByAdmin) {
-            bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
-        }
-
-        String name = cmd.getNetworkName();
-        String displayText = cmd.getDisplayText();
-        Account caller = CallContext.current().getCallingAccount();
-        Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        Long zoneId = cmd.getZoneId();
-        String aclTypeStr = cmd.getAclType();
-        Long domainId = cmd.getDomainId();
-        boolean isDomainSpecific = false;
-        Boolean subdomainAccess = cmd.getSubdomainAccess();
-        Long vpcId = cmd.getVpcId();
-        String startIPv6 = cmd.getStartIpv6();
-        String endIPv6 = cmd.getEndIpv6();
-        String ip6Gateway = cmd.getIp6Gateway();
-        String ip6Cidr = cmd.getIp6Cidr();
-        Boolean displayNetwork = cmd.getDisplayNetwork();
-        Long aclId = cmd.getAclId();
-        String isolatedPvlan = cmd.getIsolatedPvlan();
-        String externalId = cmd.getExternalId();
-
-        // Validate network offering
-        NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
-        if (ntwkOff == null || ntwkOff.isSystemOnly()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering by specified id");
-            if (ntwkOff != null) {
-                ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
-            }
-            throw ex;
-        }
-        // validate physical network and zone
-        // Check if physical network exists
-        PhysicalNetwork pNtwk = null;
-        if (physicalNetworkId != null) {
-            pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
-            if (pNtwk == null) {
-                throw new InvalidParameterValueException("Unable to find a physical network having the specified physical network id");
-            }
-        }
-
-        if (zoneId == null) {
-            zoneId = pNtwk.getDataCenterId();
-        }
-
-        if (displayNetwork == null) {
-            displayNetwork = true;
-        }
-
-        DataCenter zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Specified zone id was not found");
-        }
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            // See DataCenterVO.java
-            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "zoneId");
-            throw ex;
-        }
-
-        // Only domain and account ACL types are supported in Acton.
-        ACLType aclType = null;
-        if (aclTypeStr != null) {
-            if (aclTypeStr.equalsIgnoreCase(ACLType.Account.toString())) {
-                aclType = ACLType.Account;
-            } else if (aclTypeStr.equalsIgnoreCase(ACLType.Domain.toString())) {
-                aclType = ACLType.Domain;
-            } else {
-                throw new InvalidParameterValueException("Incorrect aclType specified. Check the API documentation for supported types");
-            }
-            // In 3.0 all Shared networks should have aclType == Domain, all Isolated networks aclType==Account
-            if (ntwkOff.getGuestType() == GuestType.Isolated) {
-                if (aclType != ACLType.Account) {
-                    throw new InvalidParameterValueException("AclType should be " + ACLType.Account + " for network of type " + Network.GuestType.Isolated);
-                }
-            } else if (ntwkOff.getGuestType() == GuestType.Shared) {
-                if (!(aclType == ACLType.Domain || aclType == ACLType.Account)) {
-                    throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + ACLType.Account + " for network of type " + Network.GuestType.Shared);
-                }
-            }
-        } else {
-            if (ntwkOff.getGuestType() == GuestType.Isolated || ntwkOff.getGuestType() == GuestType.L2) {
-                aclType = ACLType.Account;
-            } else if (ntwkOff.getGuestType() == GuestType.Shared) {
-                aclType = ACLType.Domain;
-            }
-        }
-
-        // Only Admin can create Shared networks
-        if ((ntwkOff.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
-            throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
-        }
-
-        // Check if the network is domain specific
-        if (aclType == ACLType.Domain) {
-            // only Admin can create domain with aclType=Domain
-            if (!_accountMgr.isAdmin(caller.getId())) {
-                throw new PermissionDeniedException("Only admin can create networks with aclType=Domain");
-            }
-
-            // only shared networks can be Domain specific
-            if (ntwkOff.getGuestType() != GuestType.Shared) {
-                throw new InvalidParameterValueException("Only " + GuestType.Shared + " networks can have aclType=" + ACLType.Domain);
-            }
-
-            if (domainId != null) {
-                if (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Shared) {
-                    throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + TrafficType.Guest + " and guest type "
-                            + Network.GuestType.Shared);
-                }
-
-                DomainVO domain = _domainDao.findById(domainId);
-                if (domain == null) {
-                    throw new InvalidParameterValueException("Unable to find domain by specified id");
-                }
-                _accountMgr.checkAccess(caller, domain);
-            }
-            isDomainSpecific = true;
-
-        } else if (subdomainAccess != null) {
-            throw new InvalidParameterValueException("Parameter subDomainAccess can be specified only with aclType=Domain");
-        }
-        Account owner = null;
-        if ((cmd.getAccountName() != null && domainId != null) || cmd.getProjectId() != null) {
-            owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), domainId, cmd.getProjectId());
-        } else {
-            owner = caller;
-        }
-
-        boolean ipv4 = true, ipv6 = false;
-        if (startIP != null) {
-            ipv4 = true;
-        }
-        if (startIPv6 != null) {
-            ipv6 = true;
-        }
-
-        if (gateway != null) {
-            try {
-                // getByName on a literal representation will only check validity of the address
-                // http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getByName(java.lang.String)
-                InetAddress gatewayAddress = InetAddress.getByName(gateway);
-                if (gatewayAddress instanceof Inet6Address) {
-                    ipv6 = true;
-                } else {
-                    ipv4 = true;
-                }
-            } catch (UnknownHostException e) {
-                s_logger.error("Unable to convert gateway IP to a InetAddress", e);
-                throw new InvalidParameterValueException("Gateway parameter is invalid");
-            }
-        }
-
-        String cidr = null;
-        if (ipv4) {
-            // if end ip is not specified, default it to startIp
-            if (startIP != null) {
-                if (!NetUtils.isValidIp4(startIP)) {
-                    throw new InvalidParameterValueException("Invalid format for the startIp parameter");
-                }
-                if (endIP == null) {
-                    endIP = startIP;
-                } else if (!NetUtils.isValidIp4(endIP)) {
-                    throw new InvalidParameterValueException("Invalid format for the endIp parameter");
-                }
-            }
-
-            if (startIP != null && endIP != null) {
-                if (!(gateway != null && netmask != null)) {
-                    throw new InvalidParameterValueException("gateway and netmask should be defined when startIP/endIP are passed in");
-                }
-            }
-
-            if (gateway != null && netmask != null) {
-                if(NetUtils.isNetworkorBroadcastIP(gateway,netmask)) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("The gateway IP provided is " + gateway + " and netmask is " + netmask + ". The IP is either broadcast or network IP.");
-                    }
-                    throw new InvalidParameterValueException("Invalid gateway IP provided. Either the IP is broadcast or network IP.");
-                }
-
-                if (!NetUtils.isValidIp4(gateway)) {
-                    throw new InvalidParameterValueException("Invalid gateway");
-                }
-                if (!NetUtils.isValidIp4Netmask(netmask)) {
-                    throw new InvalidParameterValueException("Invalid netmask");
-                }
-
-                cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-            }
-
-        }
-
-        if (ipv6) {
-            if (endIPv6 == null) {
-                endIPv6 = startIPv6;
-            }
-            _networkModel.checkIp6Parameters(startIPv6, endIPv6, ip6Gateway, ip6Cidr);
-
-            if (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared) {
-                throw new InvalidParameterValueException("Can only support create IPv6 network with advance shared network!");
-            }
-        }
-
-        if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) {
-            throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!");
-        }
-
-        if (isolatedPvlan != null && ipv6) {
-            throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
-        }
-
-        // Regular user can create Guest Isolated Source Nat enabled network only
-        if (_accountMgr.isNormalUser(caller.getId())
-                && (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated
-                        && areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
-            throw new InvalidParameterValueException("Regular user can create a network only from the network" + " offering having traffic type " + TrafficType.Guest
-                    + " and network type " + Network.GuestType.Isolated + " with a service " + Service.SourceNat.getName() + " enabled");
-        }
-
-        // Don't allow to specify vlan if the caller is not ROOT admin
-        if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.getSpecifyVlan() || vlanId != null || bypassVlanOverlapCheck)) {
-            throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
-        }
-
-        if (ipv4) {
-            // For non-root admins check cidr limit - if it's allowed by global config value
-            if (!_accountMgr.isRootAdmin(caller.getId()) && cidr != null) {
-
-                String[] cidrPair = cidr.split("\\/");
-                int cidrSize = Integer.parseInt(cidrPair[1]);
-
-                if (cidrSize < _cidrLimit) {
-                    throw new InvalidParameterValueException("Cidr size can't be less than " + _cidrLimit);
-                }
-            }
-        }
-
-        Collection<String> ntwkProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(ntwkOff, physicalNetworkId).values();
-        if (ipv6 && providersConfiguredForExternalNetworking(ntwkProviders)) {
-            throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!");
-        }
-
-        if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
-            throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!");
-        }
-
-        if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
-            if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) && isSharedNetworkOfferingWithServices(networkOfferingId)) {
-                // validate if CIDR specified overlaps with any of the CIDR's allocated for isolated networks and shared networks in the zone
-                checkSharedNetworkCidrOverlap(zoneId, pNtwk.getId(), cidr);
-            } else {
-                // if the guest network is for the VPC, if any External Provider are supported in VPC
-                // cidr will not be null as it is generated from the super cidr of vpc.
-                // if cidr is not null and network is not part of vpc then throw the exception
-                if (vpcId == null)
-                    throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!");
-            }
-        }
-
-        // Vlan is created in 1 cases - works in Advance zone only:
-        // 1) GuestType is Shared
-        boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced
-                && ((ntwkOff.getGuestType() == Network.GuestType.Shared)
-                || (ntwkOff.getGuestType() == GuestType.Isolated &&
-                !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))));
-
-        if (!createVlan) {
-            // Only support advance shared network in IPv6, which means createVlan is a must
-            if (ipv6) {
-                createVlan = true;
-            }
-        }
-
-        // Can add vlan range only to the network which allows it
-        if (createVlan && !ntwkOff.getSpecifyIpRanges()) {
-            throwInvalidIdException("Network offering with specified id doesn't support adding multiple ip ranges", ntwkOff.getUuid(), "networkOfferingId");
-        }
-
-        Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId, domainId,
-                isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, aclType, owner, cidr,
-                createVlan, externalId);
-
-        // if the network offering has persistent set to true, implement the network
-        if (ntwkOff.getIsPersistent()) {
-            try {
-                if (network.getState() == Network.State.Setup) {
-                    s_logger.debug("Network id=" + network.getId() + " is already provisioned");
-                    return network;
-                }
-                DeployDestination dest = new DeployDestination(zone, null, null, null);
-                UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
-                Journal journal = new Journal.LogJournal("Implementing " + network, s_logger);
-                ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
-                s_logger.debug("Implementing network " + network + " as a part of network provision for persistent network");
-                Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(network.getId(), dest, context);
-                if (implementedNetwork == null || implementedNetwork.first() == null) {
-                    s_logger.warn("Failed to provision the network " + network);
-                }
-                network = implementedNetwork.second();
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
-                CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
-                e.addProxyObject(network.getUuid(), "networkId");
-                throw e;
-            }
-        }
-        return network;
-    }
-
-    private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain,
-                                  final String vlanId, final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
-                                  final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway,
-                                  final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk,
-                                  final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan, final String externalId) throws InsufficientCapacityException, ResourceAllocationException {
-        try {
-            Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
-                @Override
-                public Network doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException {
-                    Account owner = ownerFinal;
-                    Boolean subdomainAccess = subdomainAccessFinal;
-
-                    Long sharedDomainId = null;
-                    if (isDomainSpecific) {
-                        if (domainId != null) {
-                            sharedDomainId = domainId;
-                        } else {
-                            sharedDomainId = _domainMgr.getDomain(Domain.ROOT_DOMAIN).getId();
-                            subdomainAccess = true;
-                        }
-                    }
-
-                    // default owner to system if network has aclType=Domain
-                    if (aclType == ACLType.Domain) {
-                        owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
-                    }
-
-                    // Create guest network
-                    Network network = null;
-                    if (vpcId != null) {
-                        if (!_configMgr.isOfferingForVpc(ntwkOff)) {
-                            throw new InvalidParameterValueException("Network offering can't be used for VPC networks");
-                        }
-
-                        if (aclId != null) {
-                            NetworkACL acl = _networkACLDao.findById(aclId);
-                            if (acl == null) {
-                                throw new InvalidParameterValueException("Unable to find specified NetworkACL");
-                            }
-
-                            if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
-                                // ACL is not default DENY/ALLOW
-                                // ACL should be associated with a VPC
-                                if (!vpcId.equals(acl.getVpcId())) {
-                                    throw new InvalidParameterValueException("ACL: " + aclId + " do not belong to the VPC");
-                                }
-                            }
-                        }
-                        network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
-                                aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId);
-                    } else {
-                        if (_configMgr.isOfferingForVpc(ntwkOff)) {
-                            throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
-                        }
-                        if (ntwkOff.getInternalLb()) {
-                            throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
-                        }
-
-                        network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
-                                aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, externalId);
-                    }
-
-                    if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
-                        // Create vlan ip range
-                        _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, false, null, startIP, endIP, gateway, netmask, vlanId,
-                                bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
-                    }
-                    return network;
-                }
-            });
-            if (domainId != null && aclType == ACLType.Domain) {
-                // send event for storing the domain wide resource access
-                Map<String, Object> params = new HashMap<String, Object>();
-                params.put(ApiConstants.ENTITY_TYPE, Network.class);
-                params.put(ApiConstants.ENTITY_ID, network.getId());
-                params.put(ApiConstants.DOMAIN_ID, domainId);
-                params.put(ApiConstants.SUBDOMAIN_ACCESS, subdomainAccessFinal == null ? Boolean.TRUE : subdomainAccessFinal);
-                _messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL, params);
-            }
-            return network;
-        } catch (Exception e) {
-            ExceptionUtil.rethrowRuntime(e);
-            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
-            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
-    public Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd) {
-        Long id = cmd.getId();
-        String keyword = cmd.getKeyword();
-        Long zoneId = cmd.getZoneId();
-        Account caller = CallContext.current().getCallingAccount();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        String guestIpType = cmd.getGuestIpType();
-        String trafficType = cmd.getTrafficType();
-        Boolean isSystem = cmd.getIsSystem();
-        String aclType = cmd.getAclType();
-        Long projectId = cmd.getProjectId();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-        String path = null;
-        Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        List<String> supportedServicesStr = cmd.getSupportedServices();
-        Boolean restartRequired = cmd.getRestartRequired();
-        boolean listAll = cmd.listAll();
-        boolean isRecursive = cmd.isRecursive();
-        Boolean specifyIpRanges = cmd.getSpecifyIpRanges();
-        Long vpcId = cmd.getVpcId();
-        Boolean canUseForDeploy = cmd.canUseForDeploy();
-        Map<String, String> tags = cmd.getTags();
-        Boolean forVpc = cmd.getForVpc();
-        Boolean display = cmd.getDisplay();
-
-        // 1) default is system to false if not specified
-        // 2) reset parameter to false if it's specified by the regular user
-        if ((isSystem == null || _accountMgr.isNormalUser(caller.getId())) && id == null) {
-            isSystem = false;
-        }
-
-        // Account/domainId parameters and isSystem are mutually exclusive
-        if (isSystem != null && isSystem && (accountName != null || domainId != null)) {
-            throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified");
-        }
-
-        if (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                // see DomainVO.java
-                throw new InvalidParameterValueException("Specified domain id doesn't exist in the system");
-            }
-
-            _accountMgr.checkAccess(caller, domain);
-            if (accountName != null) {
-                Account owner = _accountMgr.getActiveAccountByName(accountName, domainId);
-                if (owner == null) {
-                    // see DomainVO.java
-                    throw new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain");
-                }
-
-                _accountMgr.checkAccess(caller, null, true, owner);
-                permittedAccounts.add(owner.getId());
-            }
-        }
-
-        if (!_accountMgr.isAdmin(caller.getId()) || (projectId != null && projectId.longValue() != -1 && domainId == null)) {
-            permittedAccounts.add(caller.getId());
-            domainId = caller.getDomainId();
-        }
-
-        // set project information
-        boolean skipProjectNetworks = true;
-        if (projectId != null) {
-            if (projectId.longValue() == -1) {
-                if (!_accountMgr.isAdmin(caller.getId())) {
-                    permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
-                }
-            } else {
-                permittedAccounts.clear();
-                Project project = _projectMgr.getProject(projectId);
-                if (project == null) {
-                    throw new InvalidParameterValueException("Unable to find project by specified id");
-                }
-                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
-                    // getProject() returns type ProjectVO.
-                    throwInvalidIdException("Account " + caller + " cannot access specified project id", project.getUuid(), "projectId");
-                }
-
-                //add project account
-                permittedAccounts.add(project.getProjectAccountId());
-                //add caller account (if admin)
-                if (_accountMgr.isAdmin(caller.getId())) {
-                    permittedAccounts.add(caller.getId());
-                }
-            }
-            skipProjectNetworks = false;
-        }
-
-        if (domainId != null) {
-            path = _domainDao.findById(domainId).getPath();
-        } else {
-        path = _domainDao.findById(caller.getDomainId()).getPath();
-        }
-
-        if (listAll && domainId == null) {
-            isRecursive = true;
-        }
-
-        Filter searchFilter = new Filter(NetworkVO.class, "id", false, null, null);
-        SearchBuilder<NetworkVO> sb = _networksDao.createSearchBuilder();
-
-        if (forVpc != null) {
-            if (forVpc) {
-                sb.and("vpc", sb.entity().getVpcId(), Op.NNULL);
-            } else {
-                sb.and("vpc", sb.entity().getVpcId(), Op.NULL);
-            }
-        }
-
-        // Don't display networks created of system network offerings
-        SearchBuilder<NetworkOfferingVO> networkOfferingSearch = _networkOfferingDao.createSearchBuilder();
-        networkOfferingSearch.and("systemOnly", networkOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
-        if (isSystem != null && isSystem) {
-            networkOfferingSearch.and("trafficType", networkOfferingSearch.entity().getTrafficType(), SearchCriteria.Op.EQ);
-        }
-        sb.join("networkOfferingSearch", networkOfferingSearch, sb.entity().getNetworkOfferingId(), networkOfferingSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-
-        SearchBuilder<DataCenterVO> zoneSearch = _dcDao.createSearchBuilder();
-        zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ);
-        sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        sb.and("removed", sb.entity().getRemoved(), Op.NULL);
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (permittedAccounts.isEmpty()) {
-            SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
-            domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
-            sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-            SearchBuilder<AccountVO> accountSearch = _accountDao.createSearchBuilder();
-        accountSearch.and("typeNEQ", accountSearch.entity().getType(), SearchCriteria.Op.NEQ);
-        accountSearch.and("typeEQ", accountSearch.entity().getType(), SearchCriteria.Op.EQ);
-
-            sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-
-        List<NetworkVO> networksToReturn = new ArrayList<NetworkVO>();
-
-        if (isSystem == null || !isSystem) {
-            if (!permittedAccounts.isEmpty()) {
-                //get account level networks
-                networksToReturn.addAll(listAccountSpecificNetworks(
-                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired,
-                                specifyIpRanges, vpcId, tags, display), searchFilter, permittedAccounts));
-                //get domain level networks
-                if (domainId != null) {
-                    networksToReturn.addAll(listDomainLevelNetworks(
-                            buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true, restartRequired,
-                                    specifyIpRanges, vpcId, tags, display), searchFilter, domainId, false));
-                }
-            } else {
-                //add account specific networks
-                networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(
-                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired,
-                                specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
-                //add domain specific networks of domain + parent domains
-                networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(
-                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired,
-                                specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
-                //add networks of subdomains
-                if (domainId == null) {
-                    networksToReturn.addAll(listDomainLevelNetworks(
-                            buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true, restartRequired,
-                                    specifyIpRanges, vpcId, tags, display), searchFilter, caller.getDomainId(), true));
-                }
-            }
-        } else {
-            networksToReturn = _networksDao.search(
-                    buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired,
-                            specifyIpRanges, vpcId, tags, display), searchFilter);
-        }
-
-        if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) {
-            List<NetworkVO> supportedNetworks = new ArrayList<NetworkVO>();
-            Service[] suppportedServices = new Service[supportedServicesStr.size()];
-            int i = 0;
-            for (String supportedServiceStr : supportedServicesStr) {
-                Service service = Service.getService(supportedServiceStr);
-                if (service == null) {
-                    throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
-                } else {
-                    suppportedServices[i] = service;
-                }
-                i++;
-            }
-
-            for (NetworkVO network : networksToReturn) {
-                if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) {
-                    supportedNetworks.add(network);
-                }
-            }
-
-            networksToReturn = supportedNetworks;
-        }
-
-        if (canUseForDeploy != null) {
-            List<NetworkVO> networksForDeploy = new ArrayList<NetworkVO>();
-            for (NetworkVO network : networksToReturn) {
-                if (_networkModel.canUseForDeploy(network) == canUseForDeploy) {
-                    networksForDeploy.add(network);
-                }
-            }
-
-            networksToReturn = networksForDeploy;
-        }
-
-        //Now apply pagination
-        List<? extends Network> wPagination = StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal());
-        if (wPagination != null) {
-            Pair<List<? extends Network>, Integer> listWPagination = new Pair<List<? extends Network>, Integer>(wPagination, networksToReturn.size());
-            return listWPagination;
-        }
-
-        return new Pair<List<? extends Network>, Integer>(networksToReturn, networksToReturn.size());
-    }
-
-    private SearchCriteria<NetworkVO> buildNetworkSearchCriteria(SearchBuilder<NetworkVO> sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType,
-            String trafficType, Long physicalNetworkId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId,
-            Map<String, String> tags, Boolean display) {
-
-        SearchCriteria<NetworkVO> sc = sb.create();
-
-        if (isSystem != null) {
-            sc.setJoinParameters("networkOfferingSearch", "systemOnly", isSystem);
-        }
-
-        if (keyword != null) {
-            SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (display != null) {
-            sc.addAnd("displayNetwork", SearchCriteria.Op.EQ, display);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (zoneId != null) {
-            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        if (guestIpType != null) {
-            sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType);
-        }
-
-        if (trafficType != null) {
-            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
-        }
-
-        if (aclType != null) {
-            sc.addAnd("aclType", SearchCriteria.Op.EQ, aclType.toString());
-        }
-
-        if (physicalNetworkId != null) {
-            sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId);
-        }
-
-        if (skipProjectNetworks) {
-            sc.setJoinParameters("accountSearch", "typeNEQ", Account.ACCOUNT_TYPE_PROJECT);
-        } else {
-            sc.setJoinParameters("accountSearch", "typeEQ", Account.ACCOUNT_TYPE_PROJECT);
-        }
-
-        if (restartRequired != null) {
-            sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
-        }
-
-        if (specifyIpRanges != null) {
-            sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges);
-        }
-
-        if (vpcId != null) {
-            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Network.toString());
-            for ( Map.Entry<String,String> entry: tags.entrySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
-                count++;
-            }
-        }
-
-        return sc;
-    }
-
-    private List<NetworkVO> listDomainLevelNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) {
-        List<Long> networkIds = new ArrayList<Long>();
-        Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
-        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
-
-        for (NetworkDomainVO map : maps) {
-            if (map.getDomainId() == domainId && parentDomainsOnly) {
-                continue;
-            }
-            boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : getAllowSubdomainAccessGlobal();
-            if (map.getDomainId() == domainId || subdomainAccess) {
-                networkIds.add(map.getNetworkId());
-            }
-        }
-
-        if (!networkIds.isEmpty()) {
-            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
-            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
-            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
-
-            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
-            return _networksDao.search(sc, searchFilter);
-        } else {
-            return new ArrayList<NetworkVO>();
-        }
-    }
-
-    private List<NetworkVO> listAccountSpecificNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, List<Long> permittedAccounts) {
-        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
-        if (!permittedAccounts.isEmpty()) {
-            accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray());
-        }
-
-        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
-
-        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
-        return _networksDao.search(sc, searchFilter);
-    }
-
-    private List<NetworkVO> listAccountSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
-        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
-        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
-
-        if (path != null) {
-            if (isRecursive) {
-                sc.setJoinParameters("domainSearch", "path", path + "%");
-            } else {
-                sc.setJoinParameters("domainSearch", "path", path);
-            }
-        }
-
-        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
-        return _networksDao.search(sc, searchFilter);
-    }
-
-    private List<NetworkVO> listDomainSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
-
-        Set<Long> allowedDomains = new HashSet<Long>();
-        if (path != null) {
-            if (isRecursive) {
-                allowedDomains = _domainMgr.getDomainChildrenIds(path);
-            } else {
-                Domain domain = _domainDao.findDomainByPath(path);
-                allowedDomains.add(domain.getId());
-            }
-        }
-
-        List<Long> networkIds = new ArrayList<Long>();
-
-        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
-
-        for (NetworkDomainVO map : maps) {
-            networkIds.add(map.getNetworkId());
-        }
-
-        if (!networkIds.isEmpty()) {
-            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
-            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
-            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
-
-            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
-        return _networksDao.search(sc, searchFilter);
-        } else {
-            return new ArrayList<NetworkVO>();
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_DELETE, eventDescription = "deleting network", async = true)
-    public boolean deleteNetwork(long networkId, boolean forced) {
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Verify network id
-        NetworkVO network = _networksDao.findById(networkId);
-        if (network == null) {
-            // see NetworkVO.java
-
-            throwInvalidIdException("unable to find network with specified id", String.valueOf(networkId), "networkId");
-        }
-
-        // don't allow to delete system network
-        if (isNetworkSystem(network)) {
-            throwInvalidIdException("Network with specified id is system and can't be removed", network.getUuid(), "networkId");
-        }
-
-        Account owner = _accountMgr.getAccount(network.getAccountId());
-
-        // Only Admin can delete Shared
-        if ((network.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
-            throw new InvalidParameterValueException("Only Admins can delete network with guest type " + network.getGuestType());
-        }
-
-        // Perform permission check
-        _accountMgr.checkAccess(caller, null, true, network);
-
-        if (forced && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new InvalidParameterValueException("Delete network with 'forced' option can only be called by root admins");
-        }
-
-        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-        ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
-
-        return _networkMgr.destroyNetwork(networkId, context, forced);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_RESTART, eventDescription = "restarting network", async = true)
-    public boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        // This method restarts all network elements belonging to the network and re-applies all the rules
-        Long networkId = cmd.getNetworkId();
-
-        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-        Account callerAccount = _accountMgr.getActiveAccountById(callerUser.getAccountId());
-
-        // Check if network exists
-        NetworkVO network = _networksDao.findById(networkId);
-        if (network == null) {
-            throwInvalidIdException("Network with specified id doesn't exist", networkId.toString(), "networkId");
-        }
-
-        // Don't allow to restart network if it's not in Implemented/Setup state
-        if (!(network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) {
-            throw new InvalidParameterValueException("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", "
-                    + Network.State.Setup);
-        }
-
-        if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch) {
-            /**
-             * Unable to restart these networks now.
-             * TODO Restarting a SDN based network requires updating the nics and the configuration
-             * in the controller. This requires a non-trivial rewrite of the restart procedure.
-             */
-            throw new InvalidParameterException("Unable to restart a running SDN network.");
-        }
-
-        _accountMgr.checkAccess(callerAccount, null, true, network);
-
-        if (!network.isRedundant() && makeRedundant) {
-            network.setRedundant(true);
-            if (!_networksDao.update(network.getId(), network)) {
-                throw new CloudRuntimeException("Failed to update network into a redundant one, please try again");
-            }
-            cleanup = true;
-        }
-
-        boolean success = _networkMgr.restartNetwork(networkId, callerAccount, callerUser, cleanup);
-
-        if (success) {
-            s_logger.debug("Network id=" + networkId + " is restarted successfully.");
-        } else {
-            s_logger.warn("Network id=" + networkId + " failed to restart.");
-        }
-
-        return success;
-    }
-
-    @Override
-    public int getActiveNicsInNetwork(long networkId) {
-        return _networksDao.getActiveNicsIn(networkId);
-    }
-
-    @Override
-    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
-
-        if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) {
-            // TBD: We should be sending networkOfferingId and not the offering object itself.
-            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering);
-        }
-
-        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
-
-        // get the Provider for this Service for this offering
-        List<String> providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
-        if (providers.isEmpty()) {
-            // TBD: We should be sending networkOfferingId and not the offering object itself.
-            throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering);
-        }
-
-        // FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so
-        // we have to calculate capabilities for all of them
-        String provider = providers.get(0);
-
-        // FIXME we return the capabilities of the first provider of the service - what if we have multiple providers
-        // for same Service?
-        NetworkElement element = _networkModel.getElementImplementingProvider(provider);
-        if (element != null) {
-            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
-            ;
-
-            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
-                // TBD: We should be sending providerId and not the offering object itself.
-                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() + " implementing Provider="
-                        + provider);
-            }
-            serviceCapabilities = elementCapabilities.get(service);
-        }
-
-        return serviceCapabilities;
-    }
-
-    @Override
-    public IpAddress getIp(long ipAddressId) {
-        return _ipAddressDao.findById(ipAddressId);
-    }
-
-    protected boolean providersConfiguredForExternalNetworking(Collection<String> providers) {
-        for (String providerStr : providers) {
-            Provider provider = Network.Provider.getProvider(providerStr);
-            if (provider.isExternal()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
-        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
-        if ((networkOffering.getGuestType() == Network.GuestType.Shared)
-                && (areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat) || areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
-                        || areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
-                        || areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || areServicesSupportedByNetworkOffering(networkOfferingId, Service.Lb))) {
-            return true;
-        }
-        return false;
-    }
-
-    protected boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
-        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
-    }
-
-    protected boolean areServicesSupportedInNetwork(long networkId, Service... services) {
-        return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services));
-    }
-
-    private boolean checkForNonStoppedVmInNetwork(long networkId) {
-        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Migrating,
-                VirtualMachine.State.Stopping);
-        return vms.isEmpty();
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true)
-    public Network updateGuestNetwork(final long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix,
-            final Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String customId, boolean updateInSequence, boolean forced) {
-        boolean restartNetwork = false;
-
-        // verify input parameters
-        final NetworkVO network = _networksDao.findById(networkId);
-        if (network == null) {
-            // see NetworkVO.java
-            throwInvalidIdException("Specified network id doesn't exist in the system", String.valueOf(networkId), "networkId");
-        }
-
-        //perform below validation if the network is vpc network
-        if (network.getVpcId() != null && networkOfferingId != null) {
-            Vpc vpc = _entityMgr.findById(Vpc.class, network.getVpcId());
-            _vpcMgr.validateNtwkOffForNtwkInVpc(networkId, networkOfferingId, null, null, vpc, null, _accountMgr.getAccount(network.getAccountId()), network.getNetworkACLId());
-        }
-
-        // don't allow to update network in Destroy state
-        if (network.getState() == Network.State.Destroy) {
-            throw new InvalidParameterValueException("Don't allow to update network in state " + Network.State.Destroy);
-        }
-
-        // Don't allow to update system network
-        NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        if (offering.isSystemOnly()) {
-            throw new InvalidParameterValueException("Can't update system networks");
-        }
-
-        // allow to upgrade only Guest networks
-        if (network.getTrafficType() != Networks.TrafficType.Guest) {
-            throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
-        }
-
-        _accountMgr.checkAccess(callerAccount, null, true, network);
-
-        if (name != null) {
-            network.setName(name);
-        }
-
-        if (displayText != null) {
-            network.setDisplayText(displayText);
-        }
-
-        if (customId != null) {
-            network.setUuid(customId);
-        }
-
-        // display flag is not null and has changed
-        if (displayNetwork != null && displayNetwork != network.getDisplayNetwork()) {
-            // Update resource count if it needs to be updated
-            NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-            if (_networkMgr.resourceCountNeedsUpdate(networkOffering, network.getAclType())) {
-                _resourceLimitMgr.changeResourceCount(network.getAccountId(), Resource.ResourceType.network, displayNetwork);
-            }
-
-            network.setDisplayNetwork(displayNetwork);
-        }
-
-        // network offering and domain suffix can be updated for Isolated networks only in 3.0
-        if ((networkOfferingId != null || domainSuffix != null) && network.getGuestType() != GuestType.Isolated) {
-            throw new InvalidParameterValueException("NetworkOffering and domain suffix upgrade can be perfomed for Isolated networks only");
-        }
-
-        boolean networkOfferingChanged = false;
-
-        final long oldNetworkOfferingId = network.getNetworkOfferingId();
-        NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
-        if (networkOfferingId != null) {
-            if (networkOffering == null || networkOffering.isSystemOnly()) {
-                throwInvalidIdException("Unable to find network offering with specified id", networkOfferingId.toString(), "networkOfferingId");
-            }
-
-            // network offering should be in Enabled state
-            if (networkOffering.getState() != NetworkOffering.State.Enabled) {
-                throwInvalidIdException("Network offering with specified id is not in " + NetworkOffering.State.Enabled
-                        + " state, can't upgrade to it", networkOffering.getUuid(), "networkOfferingId");
-            }
-            //can't update from vpc to non-vpc network offering
-            boolean forVpcNew = _configMgr.isOfferingForVpc(networkOffering);
-            boolean vorVpcOriginal = _configMgr.isOfferingForVpc(_entityMgr.findById(NetworkOffering.class, oldNetworkOfferingId));
-            if (forVpcNew != vorVpcOriginal) {
-                String errMsg = forVpcNew ? "a vpc offering " : "not a vpc offering";
-                throw new InvalidParameterValueException("Can't update as the new offering is " + errMsg);
-            }
-
-            if (networkOfferingId != oldNetworkOfferingId) {
-                Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(networkOffering, network.getPhysicalNetworkId()).values();
-                Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values();
-
-                if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders) && !changeCidr) {
-                    throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
-                }
-                if (changeCidr) {
-                    if (!checkForNonStoppedVmInNetwork(network.getId())) {
-                        throwInvalidIdException("All user vm of network of specified id should be stopped before changing CIDR!", network.getUuid(), "networkId");
-                    }
-                }
-                // check if the network is upgradable
-                if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) {
-                    throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + networkOffering.getUuid()
-                            + "; check logs for more information");
-                }
-                restartNetwork = true;
-                networkOfferingChanged = true;
-
-                //Setting the new network's isReduntant to the new network offering's RedundantRouter.
-                network.setRedundant(_networkOfferingDao.findById(networkOfferingId).getRedundantRouter());
-            }
-        }
-
-        final Map<String, String> newSvcProviders = networkOfferingChanged ? _networkMgr.finalizeServicesAndProvidersForNetwork(
-                _entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()) : new HashMap<String, String>();
-
-        // don't allow to modify network domain if the service is not supported
-        if (domainSuffix != null) {
-            // validate network domain
-            if (!NetUtils.verifyDomainName(domainSuffix)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-
-            long offeringId = oldNetworkOfferingId;
-            if (networkOfferingId != null) {
-                offeringId = networkOfferingId;
-            }
-
-            Map<Network.Capability, String> dnsCapabilities = getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, offeringId), Service.Dns);
-            String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
-            if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
-                // TBD: use uuid instead of networkOfferingId. May need to hardcode tablename in call to addProxyObject().
-                throw new InvalidParameterValueException("Domain name change is not supported by the network offering id=" + networkOfferingId);
-            }
-
-            network.setNetworkDomain(domainSuffix);
-            // have to restart the network
-            restartNetwork = true;
-        }
-
-        //IP reservation checks
-        // allow reservation only to Isolated Guest networks
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        String networkCidr = network.getNetworkCidr();
-
-        if (guestVmCidr != null) {
-            if (dc.getNetworkType() == NetworkType.Basic) {
-                throw new InvalidParameterValueException("Guest VM CIDR can't be specified for zone with " + NetworkType.Basic  + " networking");
-            }
-            if (network.getGuestType() != GuestType.Isolated) {
-                throw new InvalidParameterValueException("Can only allow IP Reservation in networks with guest type " + GuestType.Isolated);
-            }
-            if (networkOfferingChanged) {
-                throw new InvalidParameterValueException("Cannot specify this nework offering change and guestVmCidr at same time. Specify only one.");
-            }
-            if (!(network.getState() == Network.State.Implemented)) {
-                throw new InvalidParameterValueException("The network must be in " + Network.State.Implemented + " state. IP Reservation cannot be applied in "
-                        + network.getState() + " state");
-            }
-            if (!NetUtils.isValidIp4Cidr(guestVmCidr)) {
-                throw new InvalidParameterValueException("Invalid format of Guest VM CIDR.");
-            }
-            if (!NetUtils.validateGuestCidr(guestVmCidr)) {
-                throw new InvalidParameterValueException("Invalid format of Guest VM CIDR. Make sure it is RFC1918 compliant. ");
-            }
-
-            // If networkCidr is null it implies that there was no prior IP reservation, so the network cidr is network.getCidr()
-            // But in case networkCidr is a non null value (IP reservation already exists), it implies network cidr is networkCidr
-            if (networkCidr != null) {
-                if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, networkCidr)) {
-                    throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR : "
-                            + networkCidr);
-                }
-            } else {
-                if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, network.getCidr())) {
-                    throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR :  "
-                            + network.getCidr());
-                }
-            }
-
-            // This check makes sure there are no active IPs existing outside the guestVmCidr in the network
-                String[] guestVmCidrPair = guestVmCidr.split("\\/");
-                Long size = Long.valueOf(guestVmCidrPair[1]);
-                List<NicVO> nicsPresent = _nicDao.listByNetworkId(networkId);
-
-                String cidrIpRange[] = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], size);
-            s_logger.info("The start IP of the specified guest vm cidr is: " + cidrIpRange[0] + " and end IP is: " + cidrIpRange[1]);
-                long startIp = NetUtils.ip2Long(cidrIpRange[0]);
-                long endIp = NetUtils.ip2Long(cidrIpRange[1]);
-                long range =  endIp - startIp + 1;
-                s_logger.info("The specified guest vm cidr has " +  range + " IPs");
-
-                for (NicVO nic : nicsPresent) {
-                    long nicIp = NetUtils.ip2Long(nic.getIPv4Address());
-                    //check if nic IP is outside the guest vm cidr
-                    if ((nicIp < startIp || nicIp > endIp) && nic.getState() != Nic.State.Deallocating) {
-                            throw new InvalidParameterValueException("Active IPs like " + nic.getIPv4Address() + " exist outside the Guest VM CIDR. Cannot apply reservation ");
-                    }
-                }
-
-                // In some scenarios even though guesVmCidr and network CIDR do not appear similar but
-                // the IP ranges exactly matches, in these special cases make sure no Reservation gets applied
-                if (network.getNetworkCidr() == null) {
-                    if (NetUtils.isSameIpRange(guestVmCidr, network.getCidr()) && !guestVmCidr.equals(network.getCidr())) {
-                    throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and CIDR: " + network.getCidr() + " are same, "
-                            + "even though both the cidrs appear to be different. As a precaution no IP Reservation will be applied.");
-                    }
-                } else {
-                if (NetUtils.isSameIpRange(guestVmCidr, network.getNetworkCidr()) && !guestVmCidr.equals(network.getNetworkCidr())) {
-                    throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and Network CIDR: " + network.getNetworkCidr()
-                            + " are same, "
-                            + "even though both the cidrs appear to be different. As a precaution IP Reservation will not be affected. If you want to reset IP Reservation, "
-                            + "specify guestVmCidr to be: " + network.getNetworkCidr());
-                    }
-                }
-
-                // When reservation is applied for the first time, network_cidr will be null
-                // Populate it with the actual network cidr
-                if (network.getNetworkCidr() == null) {
-                    network.setNetworkCidr(network.getCidr());
-                }
-
-                // Condition for IP Reservation reset : guestVmCidr and network CIDR are same
-                if (network.getNetworkCidr().equals(guestVmCidr)) {
-                    s_logger.warn("Guest VM CIDR and Network CIDR both are same, reservation will reset.");
-                    network.setNetworkCidr(null);
-                }
-                // Finally update "cidr" with the guestVmCidr
-                // which becomes the effective address space for CloudStack guest VMs
-                network.setCidr(guestVmCidr);
-                _networksDao.update(networkId, network);
-                s_logger.info("IP Reservation has been applied. The new CIDR for Guests Vms is " + guestVmCidr);
-            }
-
-        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
-        // 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
-        // states - Shutdown and Implementing
-        int resourceCount=1;
-        if (updateInSequence && restartNetwork && _networkOfferingDao.findById(network.getNetworkOfferingId()).getRedundantRouter()
-                && (networkOfferingId==null || _networkOfferingDao.findById(networkOfferingId).getRedundantRouter()) && network.getVpcId()==null) {
-            _networkMgr.canUpdateInSequence(network, forced);
-            NetworkDetailVO networkDetail =new NetworkDetailVO(network.getId(),Network.updatingInSequence,"true",true);
-            _networkDetailsDao.persist(networkDetail);
-            _networkMgr.configureUpdateInSequence(network);
-            resourceCount=_networkMgr.getResourceCount(network);
-        }
-        List<String > servicesNotInNewOffering = null;
-        if (networkOfferingId != null) {
-            servicesNotInNewOffering = _networkMgr.getServicesNotSupportedInNewOffering(network, networkOfferingId);
-        }
-        if (!forced && servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
-            NetworkOfferingVO newOffering = _networkOfferingDao.findById(networkOfferingId);
-            throw new CloudRuntimeException("The new offering:"+newOffering.getUniqueName()
-                    +" will remove the following services "+servicesNotInNewOffering +"along with all the related configuration currently in use. will not proceed with the network update." +
-                    "set forced parameter to true for forcing an update.");
-        }
-        try {
-            if (servicesNotInNewOffering!=null && !servicesNotInNewOffering.isEmpty()) {
-                _networkMgr.cleanupConfigForServicesInNetwork(servicesNotInNewOffering,network);
-            }
-        } catch (Throwable e) {
-            s_logger.debug("failed to cleanup config related to unused services error:"+e.getMessage());
-        }
-
-        boolean validStateToShutdown = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated);
-        try {
-
-            do {
-                if (restartNetwork) {
-                    if (validStateToShutdown) {
-                        if (!changeCidr) {
-                            s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update");
-
-                            if (!_networkMgr.shutdownNetworkElementsAndResources(context, true, network)) {
-                                s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network);
-                                CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id");
-                                ex.addProxyObject(network.getUuid(), "networkId");
-                                throw ex;
-                            }
-                        } else {
-                            // We need to shutdown the network, since we want to re-implement the network.
-                            s_logger.debug("Shutting down network id=" + networkId + " as a part of network update");
-
-                            //check if network has reservation
-                            if (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr())) {
-                                s_logger.warn("Existing IP reservation will become ineffective for the network with id =  " + networkId
-                                        + " You need to reapply reservation after network reimplementation.");
-                                //set cidr to the newtork cidr
-                                network.setCidr(network.getNetworkCidr());
-                                //set networkCidr to null to bring network back to no IP reservation state
-                                network.setNetworkCidr(null);
-                            }
-
-                            if (!_networkMgr.shutdownNetwork(network.getId(), context, true)) {
-                                s_logger.warn("Failed to shutdown the network as a part of update to network with specified id");
-                                CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id");
-                                ex.addProxyObject(network.getUuid(), "networkId");
-                                throw ex;
-                            }
-                        }
-                    } else {
-                        CloudRuntimeException ex = new CloudRuntimeException(
-                                "Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState());
-                        ex.addProxyObject(network.getUuid(), "networkId");
-                        throw ex;
-                    }
-                }
-
-                // 2) Only after all the elements and rules are shutdown properly, update the network VO
-                // get updated network
-                Network.State networkState = _networksDao.findById(networkId).getState();
-                boolean validStateToImplement = (networkState == Network.State.Implemented || networkState == Network.State.Setup || networkState == Network.State.Allocated);
-                if (restartNetwork && !validStateToImplement) {
-                    CloudRuntimeException ex = new CloudRuntimeException(
-                            "Failed to implement the network elements and resources as a part of update to network with specified id; network is in wrong state: " + networkState);
-                    ex.addProxyObject(network.getUuid(), "networkId");
-                    throw ex;
-                }
-
-                if (networkOfferingId != null) {
-                    if (networkOfferingChanged) {
-                        Transaction.execute(new TransactionCallbackNoReturn() {
-                            @Override
-                            public void doInTransactionWithoutResult(TransactionStatus status) {
-                                network.setNetworkOfferingId(networkOfferingId);
-                                _networksDao.update(networkId, network, newSvcProviders);
-                                // get all nics using this network
-                                // log remove usage events for old offering
-                                // log assign usage events for new offering
-                                List<NicVO> nics = _nicDao.listByNetworkId(networkId);
-                                for (NicVO nic : nics) {
-                                    long vmId = nic.getInstanceId();
-                                    VMInstanceVO vm = _vmDao.findById(vmId);
-                                    if (vm == null) {
-                                        s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId);
-                                        continue;
-                                    }
-                                    long isDefault = (nic.isDefaultNic()) ? 1 : 0;
-                                    String nicIdString = Long.toString(nic.getId());
-                                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString,
-                                            oldNetworkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
-                                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString,
-                                            networkOfferingId, null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
-                                }
-                            }
-                        });
-                    } else {
-                        network.setNetworkOfferingId(networkOfferingId);
-                        _networksDao.update(networkId, network,
-                                _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()));
-                    }
-                } else {
-                    _networksDao.update(networkId, network);
-                }
-
-                // 3) Implement the elements and rules again
-                if (restartNetwork) {
-                    if (network.getState() != Network.State.Allocated) {
-                        DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
-                        s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
-                        try {
-                            if (!changeCidr) {
-                                _networkMgr.implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId()));
-                            } else {
-                                _networkMgr.implementNetwork(network.getId(), dest, context);
-                            }
-                        } catch (Exception ex) {
-                            s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
-                            CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
-                            e.addProxyObject(network.getUuid(), "networkId");
-                            throw e;
-                        }
-                    }
-                }
-
-                // 4) if network has been upgraded from a non persistent ntwk offering to a persistent ntwk offering,
-                // implement the network if its not already
-                if (networkOfferingChanged && !oldNtwkOff.getIsPersistent() && networkOffering.getIsPersistent()) {
-                    if (network.getState() == Network.State.Allocated) {
-                        try {
-                            DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
-                            _networkMgr.implementNetwork(network.getId(), dest, context);
-                        } catch (Exception ex) {
-                            s_logger.warn("Failed to implement network " + network + " elements and resources as a part o" + "f network update due to ", ex);
-                            CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified" + " id) elements and resources as a part of network update");
-                            e.addProxyObject(network.getUuid(), "networkId");
-                            throw e;
-                        }
-                    }
-                }
-                resourceCount--;
-            } while (updateInSequence && resourceCount>0);
-        } catch (Exception exception) {
-             if (updateInSequence) {
-                 _networkMgr.finalizeUpdateInSequence(network, false);
-             }
-             throw new CloudRuntimeException("failed to update network "+network.getUuid()+" due to "+exception.getMessage());
-        } finally {
-            if (updateInSequence) {
-                if( _networkDetailsDao.findDetail(networkId,Network.updatingInSequence)!=null){
-                    _networkDetailsDao.removeDetail(networkId,Network.updatingInSequence);
-                }
-            }
-        }
-        return getNetwork(network.getId());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_MIGRATE, eventDescription = "migrating network", async = true)
-    public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
-        NetworkVO network = _networksDao.findById(networkId);
-        NetworkOffering newNtwkOff = _networkOfferingDao.findById(networkOfferingId);
-
-        //perform below validation if the network is vpc network
-        if (network.getVpcId() != null) {
-            s_logger.warn("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
-            throw new InvalidParameterValueException("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
-        }
-
-        if (_configMgr.isOfferingForVpc(newNtwkOff)) {
-            s_logger.warn("Failed to migrate network as the specified network offering is a VPC offering");
-            throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is a VPC offering");
-        }
-
-        verifyNetworkCanBeMigrated(callerAccount, network);
-
-        //Retrieve new Physical NetworkId
-        long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
-
-        final long oldNetworkOfferingId = network.getNetworkOfferingId();
-        NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-
-        if (!resume && network.getRelated() != network.getId()) {
-            s_logger.warn("Related network is not equal to network id. You might want to re-run migration with resume = true command.");
-            throw new CloudRuntimeException("Failed to migrate network as previous migration left this network in transient condition. Specify resume as true.");
-        }
-
-        if (networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff)) {
-            return migrateNetworkToPhysicalNetwork(network, oldNtwkOff, newNtwkOff, null, null, newPhysicalNetworkId, callerAccount, callerUser);
-        } else {
-            s_logger.info("Network does not need migration.");
-            return network;
-        }
-    }
-
-    private class NetworkCopy {
-        private Long networkIdInOldPhysicalNet;
-        private Network networkInNewPhysicalNet;
-
-        public NetworkCopy(Long networkIdInOldPhysicalNet, Network networkInNewPhysicalNet) {
-            this.networkIdInOldPhysicalNet = networkIdInOldPhysicalNet;
-            this.networkInNewPhysicalNet = networkInNewPhysicalNet;
-        }
-
-        public Long getNetworkIdInOldPhysicalNet() {
-            return networkIdInOldPhysicalNet;
-        }
-
-        public Network getNetworkInNewPhysicalNet() {
-            return networkInNewPhysicalNet;
-        }
-    }
-
-    private Network migrateNetworkToPhysicalNetwork(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId, Account callerAccount, User callerUser) {
-        boolean resume = network.getRelated() != network.getId();
-
-        NetworkCopy networkCopy;
-
-        // Resume is only true when there is already a copy of the network created
-        if (resume) {
-            Network networkInNewPhysicalNet = network;
-            networkCopy = new NetworkCopy(network.getRelated(), networkInNewPhysicalNet);
-
-            //the new network could already be implemented, check if the already partially upgrade networks has the same network offering as before or check if it still has the original network offering
-            //the old network offering uuid should be the one of the already created copy
-            if (networkInNewPhysicalNet.getNetworkOfferingId() != newNtwkOff.getId()) {
-                throw new InvalidParameterValueException("Failed to resume migrating network as network offering does not match previously specified network offering (" + newNtwkOff.getUuid() + ")");
-            }
-        } else {
-            networkCopy = Transaction.execute(
-                    (TransactionCallback<NetworkCopy>)
-                            (status) -> migrateNetworkInDb(network, oldNtwkOff, newNtwkOff, oldVpcId, newVpcId, newPhysicalNetworkId));
-        }
-
-        Long networkIdInOldPhysicalNet = networkCopy.getNetworkIdInOldPhysicalNet();
-        Network networkInNewPhysicalNet = networkCopy.getNetworkInNewPhysicalNet();
-
-        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
-        DataCenter zone = _dcDao.findById(network.getDataCenterId());
-        NetworkVO networkInOldPhysNet = _networksDao.findById(networkIdInOldPhysicalNet);
-
-        boolean shouldImplement = (newNtwkOff.getIsPersistent()
-                    || networkInOldPhysNet.getState() == Network.State.Implemented)
-                && networkInNewPhysicalNet.getState() != Network.State.Implemented;
-
-        if (shouldImplement) {
-            DeployDestination dest = new DeployDestination(zone, null, null, null);
-            s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
-            try {
-                networkInNewPhysicalNet = _networkMgr.implementNetwork(networkInNewPhysicalNet.getId(), dest, context)
-                                                     .second();
-            } catch (Exception ex) {
-                s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
-                CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
-                e.addProxyObject(network.getUuid(), "networkId");
-                throw e;
-            }
-        }
-
-        _networkMigrationManager.assignNicsToNewPhysicalNetwork(networkInOldPhysNet, networkInNewPhysicalNet);
-        //clean up the old copy of the network
-        _networkMigrationManager.deleteCopyOfNetwork(networkIdInOldPhysicalNet, networkInNewPhysicalNet.getId());
-
-        return getNetwork(network.getId());
-    }
-
-    private NetworkCopy migrateNetworkInDb(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId) {
-        //The copy will be the network in the old physical network
-        //And we will use it to store tmp data while we upgrade or original network to the new physical network
-        Long networkIdInOldPhysicalNet = _networkMigrationManager.makeCopyOfNetwork(network, oldNtwkOff, oldVpcId);
-        Network networkInNewPhysicalNet = _networkMigrationManager.upgradeNetworkToNewNetworkOffering(network.getId(), newPhysicalNetworkId,newNtwkOff.getId(), newVpcId);
-        return new NetworkCopy(networkIdInOldPhysicalNet, networkInNewPhysicalNet);
-    }
-
-    @Override
-    public Vpc migrateVpcNetwork(long vpcId, long vpcOfferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
-        //Check if a previous migration run failed and try to resume if resume = true
-        ResourceTag relatedVpc = _resourceTagDao.findByKey(vpcId, ResourceObjectType.Vpc, NetworkMigrationManager.MIGRATION);
-        long vpcCopyId = 0;
-
-        /*
-         * In the vpc migration process the newly created Vpc will be used as the new VPC (opposed to network tier migration).
-         * In case the copy of the vpc was already created. The uuid where already swapped and the id we receive here is the id of the Copy!
-         * The id stored in the resource tag table under the key "migration" is the id of the ORIGINAL vpc!
-         */
-        if (relatedVpc != null) {
-            if (resume) {
-                vpcCopyId = vpcId;
-                vpcId = Long.parseLong(relatedVpc.getValue());
-                //let's check if the user did not change the vpcoffering opposed to the last failed run.
-                verifyAlreadyMigratedTiers(vpcCopyId, vpcOfferingId, networkToOffering);
-            } else {
-                s_logger.warn("This vpc has a migration row in the resource details table. You might want to re-run migration with resume = true command.");
-                throw new CloudRuntimeException("Failed to migrate VPC as previous migration left this VPC in transient condition. Specify resume as true.");
-            }
-        }
-
-        Vpc vpc = _vpcDao.findById(vpcId);
-        _accountMgr.checkAccess(account, null, true, vpc);
-
-        if (vpc.getVpcOfferingId() == vpcOfferingId) {
-            return vpc;
-        }
-        //Try to fail fast, check networks in the VPC and if we can migrate them before proceeding.
-        List<NetworkVO> tiersInVpc = _networksDao.listByVpc(vpcId);
-        vpcTiersCanBeMigrated(tiersInVpc, account, networkToOffering, resume);
-
-        //In case this is the first time we try to migrate this vpc
-        if (relatedVpc == null) {
-            final long vpcIdFinal = vpcId;
-            vpcCopyId = Transaction.execute((TransactionCallback<Long>)(status) -> _networkMigrationManager.makeCopyOfVpc(vpcIdFinal, vpcOfferingId));
-        }
-
-        Vpc copyOfVpc = _vpcDao.findById(vpcCopyId);
-        _networkMigrationManager.startVpc(copyOfVpc);
-
-        for (Network tier : tiersInVpc) {
-            String networkOfferingUuid = networkToOffering.get(tier.getUuid());
-            //UUID may be swapped already with a new uuid due to previous migration failure.
-            //So we check the related network also in case we don't find the network offering
-            Long networkId = null;
-            if (resume && networkOfferingUuid == null) {
-                tier = _networksDao.findById(tier.getRelated());
-                networkOfferingUuid = networkToOffering.get(tier.getUuid());
-                //In this case the tier already exists so we need to get the id of the tier so we can validate correctly
-                networkId = tier.getId();
-            }
-            NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
-
-            Account networkAccount = _accountService.getActiveAccountById(tier.getAccountId());
-            try {
-                _vpcMgr.validateNtwkOffForNtwkInVpc(networkId, newNtwkOff.getId(), tier.getCidr(), tier.getNetworkDomain(), copyOfVpc, tier.getGateway(), networkAccount, tier.getNetworkACLId());
-            } catch (InvalidParameterValueException e) {
-                s_logger.error("Specified network offering can not be used in combination with specified vpc offering. Aborting migration. You can re-run with resume = true and the correct uuid.");
-                throw e;
-            }
-
-            long newPhysicalNetworkId = findPhysicalNetworkId(tier.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
-
-            final long oldNetworkOfferingId = tier.getNetworkOfferingId();
-            NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-
-            if (networkNeedsMigration(tier, newPhysicalNetworkId, oldNtwkOff, newNtwkOff) || (resume && tier.getRelated() != tier.getId())) {
-                migrateNetworkToPhysicalNetwork(tier, oldNtwkOff, newNtwkOff, vpcId, vpcCopyId, newPhysicalNetworkId, account, callerUser);
-            }
-        }
-        _networkMigrationManager.deleteCopyOfVpc(vpcId, vpcCopyId);
-        return _vpcDao.findById(vpcCopyId);
-    }
-
-    private void vpcTiersCanBeMigrated(List<? extends Network> tiersInVpc, Account account, Map<String, String> networkToOffering, boolean resume) {
-        for (Network network : tiersInVpc) {
-            String networkOfferingUuid = networkToOffering.get(network.getUuid());
-
-            //offering uuid can be a tier where the uuid is previously already swapped in a previous migration
-            if (resume && networkOfferingUuid == null) {
-                NetworkVO oldVPCtier = _networksDao.findById(network.getRelated());
-                networkOfferingUuid = networkToOffering.get(oldVPCtier.getUuid());
-            }
-
-            if (networkOfferingUuid == null) {
-                throwInvalidIdException("Failed to migrate VPC as the specified tierNetworkOfferings is not complete",
-                                        String.valueOf(network.getUuid()), "networkUuid");
-            }
-
-            NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
-
-            if (newNtwkOff == null) {
-                throwInvalidIdException("Failed to migrate VPC as at least one network offering in tierNetworkOfferings does not exist", networkOfferingUuid, "networkOfferingUuid");
-            }
-
-            if (!_configMgr.isOfferingForVpc(newNtwkOff)) {
-                throw new InvalidParameterValueException("Network offering " + newNtwkOff.getName() + " ("+ newNtwkOff.getUuid() +") can't be used for VPC networks for network " + network.getName() + "(" + network.getUuid() + ")");
-            }
-
-            verifyNetworkCanBeMigrated(account, network);
-            long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
-
-            final long oldNetworkOfferingId = network.getNetworkOfferingId();
-            NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-            networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff);
-        }
-    }
-
-    private void verifyAlreadyMigratedTiers(long migratedVpcId, long vpcOfferingId, Map<String, String> networkToOffering) {
-        Vpc migratedVpc = _vpcDao.findById(migratedVpcId);
-        if (migratedVpc.getVpcOfferingId() != vpcOfferingId) {
-            s_logger.error("The vpc is already partially migrated in a previous run. The provided vpc offering is not the same as the one used during the first migration process.");
-            throw new InvalidParameterValueException("Failed to resume migrating VPC as VPC offering does not match previously specified VPC offering (" + migratedVpc.getVpcOfferingId() + ")");
-        }
-
-        List<NetworkVO> migratedTiers = _networksDao.listByVpc(migratedVpcId);
-        for (Network tier : migratedTiers) {
-            String tierNetworkOfferingUuid = networkToOffering.get(tier.getUuid());
-
-            if (!StringUtils.isNotBlank(tierNetworkOfferingUuid)) {
-                throwInvalidIdException("Failed to resume migrating VPC as the specified tierNetworkOfferings is not complete",
-                                        String.valueOf(tier.getUuid()), "networkUuid");
-            }
-
-            NetworkOfferingVO newNetworkOffering = _networkOfferingDao.findByUuid(tierNetworkOfferingUuid);
-            if (newNetworkOffering == null) {
-                throw new InvalidParameterValueException("Failed to migrate VPC as at least one tier offering in tierNetworkOfferings does not exist.");
-            }
-
-            if (newNetworkOffering.getId() != tier.getNetworkOfferingId()) {
-                NetworkOfferingVO tierNetworkOffering = _networkOfferingDao.findById(tier.getNetworkOfferingId());
-                throw new InvalidParameterValueException("Failed to resume migrating VPC as at least one network offering in tierNetworkOfferings does not match previously specified network offering (network uuid=" + tier.getUuid() + " was previously specified with offering uuid=" + tierNetworkOffering.getUuid() + ")");
-            }
-        }
-    }
-
-
-    private void throwInvalidIdException(String message, String uuid, String description) {
-        InvalidParameterValueException ex = new InvalidParameterValueException(message);
-        ex.addProxyObject(uuid, description);
-        throw ex;
-    }
-
-    private boolean networkNeedsMigration(Network network, long newPhysicalNetworkId, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff) {
-
-        if (newNtwkOff == null || newNtwkOff.isSystemOnly()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering.");
-            if (newNtwkOff != null) {
-                ex.addProxyObject(String.valueOf(newNtwkOff.getId()), "networkOfferingId");
-            }
-            throw ex;
-        }
-
-        if (newNtwkOff.getId() != oldNtwkOff.getId() || network.getId() != network.getRelated()) {
-            Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(newNtwkOff, newPhysicalNetworkId)
-                                                         .values();
-            Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId())
-                                                         .values();
-
-            if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders)) {
-                throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
-            }
-
-            // check if the network is moveable
-            if (!canMoveToPhysicalNetwork(network, oldNtwkOff.getId(), newNtwkOff.getId())) {
-                throw new InvalidParameterValueException(
-                        "Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + newNtwkOff.getUuid() + "; check logs for more information");
-            }
-
-            List<VMInstanceVO> vmInstances = _vmDao.listNonRemovedVmsByTypeAndNetwork(network.getId(), null);
-            boolean vmStateIsNotTransitioning = vmInstances.stream()
-                                   .anyMatch(vm -> vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Running);
-            if (vmStateIsNotTransitioning) {
-                throw new CloudRuntimeException("Failed to migrate network as at least one VM is not in running or stopped state.");
-            }
-        } else {
-            return false;
-        }
-
-        // network offering should be in Enabled state
-        if (newNtwkOff.getState() != NetworkOffering.State.Enabled) {
-            throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is not enabled.");
-        }
-        return true;
-    }
-
-    private void verifyNetworkCanBeMigrated(Account callerAccount, Network network) {
-        // Don't allow to update system network
-        NetworkOffering oldOffering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        if (oldOffering.isSystemOnly()) {
-            throw new InvalidParameterValueException("Failed to migrate network as the specified network is a system network.");
-        }
-
-        // allow to upgrade only Guest networks
-        if (network.getTrafficType() != TrafficType.Guest) {
-            throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
-        }
-
-        _accountMgr.checkAccess(callerAccount, null, true, network);
-
-        boolean validateNetworkReadyToMigrate = (network.getState() == Network.State.Implemented
-                || network.getState() == Network.State.Setup
-                || network.getState() == Network.State.Allocated);
-        if (!validateNetworkReadyToMigrate) {
-            s_logger.error("Failed to migrate network as it is in invalid state.");
-            CloudRuntimeException ex = new CloudRuntimeException("Failed to migrate network as it is in invalid state.");
-            ex.addProxyObject(network.getUuid(), "networkId");
-            throw ex;
-        }
-    }
-
-    private boolean canMoveToPhysicalNetwork(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
-        NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-        NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
-
-        // can move only Isolated networks for now
-        if (oldNetworkOffering.getGuestType() != GuestType.Isolated) {
-            throw new InvalidParameterValueException("NetworkOfferingId can be upgraded only for the network of type " + GuestType.Isolated);
-        }
-
-        // Type of the network should be the same
-        if (oldNetworkOffering.getGuestType() != newNetworkOffering.getGuestType()) {
-            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " are of different types, can't upgrade");
-            return false;
-        }
-
-        // Traffic types should be the same
-        if (oldNetworkOffering.getTrafficType() != newNetworkOffering.getTrafficType()) {
-            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different traffic types, can't upgrade");
-            return false;
-        }
-
-        // specify ipRanges should be the same
-        if (oldNetworkOffering.getSpecifyIpRanges() != newNetworkOffering.getSpecifyIpRanges()) {
-            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyIpRangess, can't upgrade");
-            return false;
-        }
-
-        // Check all ips
-        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
-        List<PublicIp> publicIps = new ArrayList<PublicIp>();
-        if (userIps != null && !userIps.isEmpty()) {
-            for (IPAddressVO userIp : userIps) {
-                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                publicIps.add(publicIp);
-            }
-        }
-        if (oldNetworkOffering.isConserveMode() && !newNetworkOffering.isConserveMode()) {
-            if (!canIpsUsedForNonConserve(publicIps)) {
-                return false;
-            }
-        }
-
-        //can't update from internal LB to public LB
-        if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.Lb) && areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.Lb)) {
-            if (oldNetworkOffering.getPublicLb() != newNetworkOffering.getPublicLb() || oldNetworkOffering.getInternalLb() != newNetworkOffering.getInternalLb()) {
-                throw new InvalidParameterValueException("Original and new offerings support different types of LB - Internal vs Public," + " can't upgrade");
-            }
-        }
-
-        return canIpsUseOffering(publicIps, newNetworkOfferingId);
-    }
-
-    protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
-        NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
-        NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
-
-        // security group service should be the same
-        if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.SecurityGroup) != areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.SecurityGroup)) {
-            s_logger.debug("Offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different securityGroupProperty, can't upgrade");
-            return false;
-        }
-
-        // tags should be the same
-        if (newNetworkOffering.getTags() != null) {
-            if (oldNetworkOffering.getTags() == null) {
-                s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade");
-                return false;
-            }
-
-            if (!StringUtils.areTagsEqual(oldNetworkOffering.getTags(), newNetworkOffering.getTags())) {
-                s_logger.debug("Network offerings " + newNetworkOffering.getUuid() + " and " + oldNetworkOffering.getUuid() + " have different tags, can't upgrade");
-                return false;
-            }
-        }
-
-        // specify vlan should be the same
-        if (oldNetworkOffering.getSpecifyVlan() != newNetworkOffering.getSpecifyVlan()) {
-            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyVlan, can't upgrade");
-            return false;
-        }
-
-        return  canMoveToPhysicalNetwork(network, oldNetworkOfferingId, newNetworkOfferingId);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true)
-    public PhysicalNetwork createPhysicalNetwork(final Long zoneId, final String vnetRange, final String networkSpeed, final List<String> isolationMethods,
-            String broadcastDomainRangeStr, final Long domainId, final List<String> tags, final String name) {
-
-        // Check if zone exists
-        if (zoneId == null) {
-            throw new InvalidParameterValueException("Please specify a valid zone.");
-        }
-
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Please specify a valid zone.");
-        }
-
-        if (Grouping.AllocationState.Enabled == zone.getAllocationState()) {
-            // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject().
-            throw new PermissionDeniedException("Cannot create PhysicalNetwork since the Zone is currently enabled, zone Id: " + zoneId);
-        }
-
-        NetworkType zoneType = zone.getNetworkType();
-
-        if (zoneType == NetworkType.Basic) {
-            if (!_physicalNetworkDao.listByZone(zoneId).isEmpty()) {
-                // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject().
-                throw new CloudRuntimeException("Cannot add the physical network to basic zone id: " + zoneId + ", there is a physical network already existing in this basic Zone");
-            }
-        }
-        if (tags != null && tags.size() > 1) {
-            throw new InvalidParameterException("Only one tag can be specified for a physical network at this time");
-        }
-
-        if (isolationMethods != null && isolationMethods.size() > 1) {
-            throw new InvalidParameterException("Only one isolationMethod can be specified for a physical network at this time");
-        }
-
-        if (vnetRange != null) {
-            // Verify zone type
-            if (zoneType == NetworkType.Basic || (zoneType == NetworkType.Advanced && zone.isSecurityGroupEnabled())) {
-                throw new InvalidParameterValueException("Can't add vnet range to the physical network in the zone that supports " + zoneType
-                        + " network, Security Group enabled: " + zone.isSecurityGroupEnabled());
-            }
-        }
-
-        BroadcastDomainRange broadcastDomainRange = null;
-        if (broadcastDomainRangeStr != null && !broadcastDomainRangeStr.isEmpty()) {
-            try {
-                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.valueOf(broadcastDomainRangeStr.toUpperCase());
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve broadcastDomainRange '" + broadcastDomainRangeStr + "' to a supported value {Pod or Zone}");
-            }
-
-            // in Acton release you can specify only Zone broadcastdomain type in Advance zone, and Pod in Basic
-            if (zoneType == NetworkType.Basic && broadcastDomainRange != null && broadcastDomainRange != BroadcastDomainRange.POD) {
-                throw new InvalidParameterValueException("Basic zone can have broadcast domain type of value " + BroadcastDomainRange.POD + " only");
-            } else if (zoneType == NetworkType.Advanced && broadcastDomainRange != null && broadcastDomainRange != BroadcastDomainRange.ZONE) {
-                throw new InvalidParameterValueException("Advance zone can have broadcast domain type of value " + BroadcastDomainRange.ZONE + " only");
-            }
-        }
-
-        if (broadcastDomainRange == null) {
-            if (zoneType == NetworkType.Basic) {
-                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.POD;
-            } else {
-                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.ZONE;
-            }
-        }
-
-        try {
-            final BroadcastDomainRange broadcastDomainRangeFinal = broadcastDomainRange;
-            return Transaction.execute(new TransactionCallback<PhysicalNetworkVO>() {
-                @Override
-                public PhysicalNetworkVO doInTransaction(TransactionStatus status) {
-            // Create the new physical network in the database
-            long id = _physicalNetworkDao.getNextInSequence(Long.class, "id");
-                    PhysicalNetworkVO pNetwork = new PhysicalNetworkVO(id, zoneId, vnetRange, networkSpeed, domainId, broadcastDomainRangeFinal, name);
-            pNetwork.setTags(tags);
-            pNetwork.setIsolationMethods(isolationMethods);
-
-            pNetwork = _physicalNetworkDao.persist(pNetwork);
-
-            // Add vnet entries for the new zone if zone type is Advanced
-            if (vnetRange != null) {
-                addOrRemoveVnets(vnetRange.split(","), pNetwork);
-            }
-
-            // add VirtualRouter as the default network service provider
-            addDefaultVirtualRouterToPhysicalNetwork(pNetwork.getId());
-
-                    if (pNetwork.getIsolationMethods().contains("GRE"))
-                        addDefaultOvsToPhysicalNetwork(pNetwork.getId());
-
-            // add security group provider to the physical network
-            addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId());
-
-            // add VPCVirtualRouter as the defualt network service provider
-            addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId());
-
-            // add baremetal as the defualt network service provider
-            addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId());
-
-            //Add Internal Load Balancer element as a default network service provider
-            addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId());
-
-            // Add the config drive provider
-            addConfigDriveToPhysicalNetwork(pNetwork.getId());
-
-            return pNetwork;
-                }
-            });
-        } catch (Exception ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new CloudRuntimeException("Fail to create a physical network");
-        }
-    }
-
-    @Override
-    public Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) {
-        Filter searchFilter = new Filter(PhysicalNetworkVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-        SearchCriteria<PhysicalNetworkVO> sc = _physicalNetworkDao.createSearchCriteria();
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (zoneId != null) {
-            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-        }
-
-        Pair<List<PhysicalNetworkVO>, Integer> result =  _physicalNetworkDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends PhysicalNetwork>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_UPDATE, eventDescription = "updating physical network", async = true)
-    public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRange, String state) {
-
-        // verify input parameters
-        PhysicalNetworkVO network = _physicalNetworkDao.findById(id);
-        if (network == null) {
-            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", id.toString(), "physicalNetworkId");
-        }
-
-        // if zone is of Basic type, don't allow to add vnet range
-        DataCenter zone = _dcDao.findById(network.getDataCenterId());
-        if (zone == null) {
-            throwInvalidIdException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system", String.valueOf(network.getDataCenterId()), "dataCenterId");
-        }
-        if (newVnetRange != null) {
-            if (zone.getNetworkType() == NetworkType.Basic || (zone.getNetworkType() == NetworkType.Advanced && zone.isSecurityGroupEnabled())) {
-                throw new InvalidParameterValueException("Can't add vnet range to the physical network in the zone that supports " + zone.getNetworkType()
-                        + " network, Security Group enabled: " + zone.isSecurityGroupEnabled());
-            }
-        }
-
-        if (tags != null && tags.size() > 1) {
-            throw new InvalidParameterException("Unable to support more than one tag on network yet");
-        }
-
-        PhysicalNetwork.State networkState = null;
-        if (state != null && !state.isEmpty()) {
-            try {
-                networkState = PhysicalNetwork.State.valueOf(state);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve state '" + state + "' to a supported value {Enabled or Disabled}");
-            }
-        }
-
-        if (state != null) {
-            network.setState(networkState);
-        }
-
-        if (tags != null) {
-            network.setTags(tags);
-        }
-
-        if (networkSpeed != null) {
-            network.setSpeed(networkSpeed);
-        }
-
-        if (newVnetRange != null) {
-            String[] listOfRanges = newVnetRange.split(",");
-            addOrRemoveVnets(listOfRanges, network);
-        }
-        _physicalNetworkDao.update(id, network);
-        return network;
-
-    }
-
-    @DB
-    public void addOrRemoveVnets(String[] listOfRanges, final PhysicalNetworkVO network) {
-        List<String>  addVnets = null;
-        List<String> removeVnets = null;
-        HashSet<String> tempVnets = new HashSet<String>();
-        HashSet<String> vnetsInDb = new HashSet<String>();
-        List<Pair<Integer, Integer>> vnetranges = null;
-        String comaSeperatedStingOfVnetRanges = null;
-        int i = 0;
-        if (listOfRanges.length != 0) {
-            _physicalNetworkDao.acquireInLockTable(network.getId(), 10);
-            vnetranges = validateVlanRange(network, listOfRanges);
-
-            //computing vnets to be removed.
-            removeVnets = getVnetsToremove(network, vnetranges);
-
-            //computing vnets to add
-            vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
-            tempVnets.addAll(vnetsInDb);
-            for (Pair<Integer, Integer> vlan : vnetranges) {
-                for (i = vlan.first(); i <= vlan.second(); i++) {
-                    tempVnets.add(Integer.toString(i));
-                }
-            }
-            tempVnets.removeAll(vnetsInDb);
-
-            //vnets to add in tempVnets.
-            //adding and removing vnets from vnetsInDb
-            if (removeVnets != null && removeVnets.size() != 0) {
-                vnetsInDb.removeAll(removeVnets);
-            }
-
-            if (tempVnets.size() != 0) {
-                addVnets = new ArrayList<String>();
-                addVnets.addAll(tempVnets);
-                vnetsInDb.addAll(tempVnets);
-            }
-
-            //sorting the vnets in Db to generate a coma seperated list of  the vnet string.
-            if (vnetsInDb.size() != 0) {
-                comaSeperatedStingOfVnetRanges = generateVnetString(new ArrayList<String>(vnetsInDb));
-            }
-            network.setVnet(comaSeperatedStingOfVnetRanges);
-
-            final List<String> addVnetsFinal = addVnets;
-            final List<String> removeVnetsFinal = removeVnets;
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    if (addVnetsFinal != null) {
-                        s_logger.debug("Adding vnet range " + addVnetsFinal.toString() + " for the physicalNetwork id= " + network.getId() + " and zone id="
-                                + network.getDataCenterId() + " as a part of updatePhysicalNetwork call");
-                //add vnet takes a list of strings to be added. each string is a vnet.
-                        _dcDao.addVnet(network.getDataCenterId(), network.getId(), addVnetsFinal);
-            }
-                    if (removeVnetsFinal != null) {
-                        s_logger.debug("removing vnet range " + removeVnetsFinal.toString() + " for the physicalNetwork id= " + network.getId() + " and zone id="
-                                + network.getDataCenterId() + " as a part of updatePhysicalNetwork call");
-                //deleteVnets  takes a list of strings to be removed. each string is a vnet.
-                        _datacneterVnet.deleteVnets(TransactionLegacy.currentTxn(), network.getDataCenterId(), network.getId(), removeVnetsFinal);
-            }
-            _physicalNetworkDao.update(network.getId(), network);
-                }
-            });
-
-            _physicalNetworkDao.releaseFromLockTable(network.getId());
-        }
-    }
-
-    private List<Pair<Integer, Integer>> validateVlanRange(PhysicalNetworkVO network, String[] listOfRanges) {
-        Integer StartVnet;
-        Integer EndVnet;
-        List<Pair<Integer, Integer>> vlanTokens = new ArrayList<Pair<Integer, Integer>>();
-        for (String vlanRange : listOfRanges) {
-            String[] VnetRange = vlanRange.split("-");
-
-            // Init with [min,max] of VLAN. Actually 0x000 and 0xFFF are reserved by IEEE, shoudn't be used.
-            long minVnet = MIN_VLAN_ID;
-            long maxVnet = MAX_VLAN_ID;
-
-            // for GRE phynets allow up to 32bits
-            // TODO: Not happy about this test.
-            // What about guru-like objects for physical networs?
-            s_logger.debug("ISOLATION METHODS:" + network.getIsolationMethods());
-            // Java does not have unsigned types...
-            if (network.getIsolationMethods().contains("GRE")) {
-                minVnet = MIN_GRE_KEY;
-                maxVnet = MAX_GRE_KEY;
-            } else if (network.getIsolationMethods().contains("VXLAN")) {
-                minVnet = MIN_VXLAN_VNI;
-                maxVnet = MAX_VXLAN_VNI;
-                // fail if zone already contains VNI, need to be unique per zone.
-                // since adding a range adds each VNI to the database, need only check min/max
-                for (String vnet : VnetRange) {
-                    s_logger.debug("Looking to see if VNI " + vnet + " already exists on another network in zone " + network.getDataCenterId());
-                    List<DataCenterVnetVO> vnis = _datacneterVnet.findVnet(network.getDataCenterId(), vnet);
-                    if (vnis != null && !vnis.isEmpty()) {
-                        for (DataCenterVnetVO vni : vnis) {
-                            if (vni.getPhysicalNetworkId() != network.getId()) {
-                                s_logger.debug("VNI " + vnet + " already exists on another network in zone, please specify a unique range");
-                                throw new InvalidParameterValueException("VNI " + vnet + " already exists on another network in zone, please specify a unique range");
-                            }
-                        }
-                    }
-                }
-            }
-            String rangeMessage = " between " + minVnet + " and " + maxVnet;
-            if (VnetRange.length == 1 && VnetRange[0].equals("")) {
-                return vlanTokens;
-            }
-            if (VnetRange.length < 2) {
-                throw new InvalidParameterValueException("Please provide valid vnet range. vnet range should be a coma seperated list of vlan ranges. example 500-500,600-601"
-                        + rangeMessage);
-            }
-
-            if (VnetRange[0] == null || VnetRange[1] == null) {
-                throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
-            }
-
-            try {
-                StartVnet = Integer.parseInt(VnetRange[0]);
-                EndVnet = Integer.parseInt(VnetRange[1]);
-            } catch (NumberFormatException e) {
-                s_logger.warn("Unable to parse vnet range:", e);
-                throw new InvalidParameterValueException("Please provide valid vnet range. The vnet range should be a coma seperated list example 2001-2012,3000-3005."
-                        + rangeMessage);
-            }
-            if (StartVnet < minVnet || EndVnet > maxVnet) {
-                throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage);
-            }
-
-            if (StartVnet > EndVnet) {
-                throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage + " and start range should be lesser than or equal to stop range");
-            }
-            vlanTokens.add(new Pair<Integer, Integer>(StartVnet, EndVnet));
-        }
-        return vlanTokens;
-
-    }
-
-    public  String generateVnetString(List<String> vnetList) {
-        Collections.sort(vnetList, new Comparator<String>() {
-            @Override
-            public int compare(String s1, String s2) {
-                return Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
-            }
-        });
-        int i;
-        //build the vlan string form the sorted list.
-        String vnetRange = "";
-        String startvnet = vnetList.get(0);
-        String endvnet = "";
-        for (i = 0; i < vnetList.size() - 1; i++) {
-            if (Integer.parseInt(vnetList.get(i + 1)) - Integer.parseInt(vnetList.get(i)) > 1) {
-                endvnet = vnetList.get(i);
-                vnetRange = vnetRange + startvnet + "-" + endvnet + ",";
-                startvnet = vnetList.get(i + 1);
-            }
-        }
-        endvnet = vnetList.get(vnetList.size() - 1);
-        vnetRange = vnetRange + startvnet + "-" + endvnet + ",";
-        vnetRange = vnetRange.substring(0, vnetRange.length() - 1);
-        return vnetRange;
-    }
-
-    private List<String> getVnetsToremove(PhysicalNetworkVO network, List<Pair<Integer, Integer>> vnetRanges) {
-        int i;
-        List<String> removeVnets = new ArrayList<String>();
-        HashSet<String> vnetsInDb = new HashSet<String>();
-        vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
-        //remove all the vnets from vnets in db to check if there are any vnets that are not there in given list.
-        //remove all the vnets not in the list of vnets passed by the user.
-        if (vnetRanges.size() == 0) {
-            //this implies remove all vlans.
-            removeVnets.addAll(vnetsInDb);
-            int allocated_vnets = _datacneterVnet.countAllocatedVnets(network.getId());
-            if (allocated_vnets > 0) {
-                throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has " + allocated_vnets + " vnets in use");
-            }
-            return removeVnets;
-        }
-        for (Pair<Integer, Integer> vlan : vnetRanges) {
-            for (i = vlan.first(); i <= vlan.second(); i++) {
-                vnetsInDb.remove(Integer.toString(i));
-            }
-        }
-        String vnetRange = null;
-        if (vnetsInDb.size() != 0) {
-            removeVnets.addAll(vnetsInDb);
-            vnetRange = generateVnetString(removeVnets);
-        } else {
-            return removeVnets;
-        }
-
-        for (String vnet : vnetRange.split(",")) {
-            String[] range = vnet.split("-");
-            Integer start = Integer.parseInt(range[0]);
-            Integer end = Integer.parseInt(range[1]);
-            _datacneterVnet.lockRange(network.getDataCenterId(), network.getId(), start, end);
-            List<DataCenterVnetVO> result = _datacneterVnet.listAllocatedVnetsInRange(network.getDataCenterId(), network.getId(), start, end);
-            if (!result.isEmpty()) {
-                throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has allocated vnets in the range " + start + "-" + end);
-
-            }
-            // If the range is partially dedicated to an account fail the request
-            List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(network.getId());
-            for (AccountGuestVlanMapVO map : maps) {
-                String[] vlans = map.getGuestVlanRange().split("-");
-                Integer dedicatedStartVlan = Integer.parseInt(vlans[0]);
-                Integer dedicatedEndVlan = Integer.parseInt(vlans[1]);
-                if ((start >= dedicatedStartVlan && start <= dedicatedEndVlan) || (end >= dedicatedStartVlan && end <= dedicatedEndVlan)) {
-                    throw new InvalidParameterValueException("Vnet range " + map.getGuestVlanRange() + " is dedicated" + " to an account. The specified range " + start + "-" + end
-                            + " overlaps with the dedicated range " + " Please release the overlapping dedicated range before deleting the range");
-                }
-            }
-        }
-        return  removeVnets;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_DELETE, eventDescription = "deleting physical network", async = true)
-    @DB
-    public boolean deletePhysicalNetwork(final Long physicalNetworkId) {
-
-        // verify input parameters
-        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
-        }
-
-        checkIfPhysicalNetworkIsDeletable(physicalNetworkId);
-
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-        // delete vlans for this zone
-        List<VlanVO> vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId);
-        for (VlanVO vlan : vlans) {
-            _vlanDao.remove(vlan.getId());
-        }
-
-        // Delete networks
-        List<NetworkVO> networks = _networksDao.listByPhysicalNetwork(physicalNetworkId);
-        if (networks != null && !networks.isEmpty()) {
-            for (NetworkVO network : networks) {
-                _networksDao.remove(network.getId());
-            }
-        }
-
-        // delete vnets
-        _dcDao.deleteVnet(physicalNetworkId);
-
-        // delete service providers
-        List<PhysicalNetworkServiceProviderVO> providers = _pNSPDao.listBy(physicalNetworkId);
-
-                for (PhysicalNetworkServiceProviderVO provider : providers) {
-            try {
-                deleteNetworkServiceProvider(provider.getId());
-                    } catch (ResourceUnavailableException e) {
-                        s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: " + provider.getId(), e);
-                return false;
-            } catch (ConcurrentOperationException e) {
-                        s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: " + provider.getId(), e);
-                return false;
-            }
-        }
-
-        // delete traffic types
-        _pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId);
-
-                return _physicalNetworkDao.remove(physicalNetworkId);
-            }
-        });
-    }
-
-    @DB
-    protected void checkIfPhysicalNetworkIsDeletable(Long physicalNetworkId) {
-        List<List<String>> tablesToCheck = new ArrayList<List<String>>();
-
-        List<String> vnet = new ArrayList<String>();
-        vnet.add(0, "op_dc_vnet_alloc");
-        vnet.add(1, "physical_network_id");
-        vnet.add(2, "there are allocated vnets for this physical network");
-        tablesToCheck.add(vnet);
-
-        List<String> networks = new ArrayList<String>();
-        networks.add(0, "networks");
-        networks.add(1, "physical_network_id");
-        networks.add(2, "there are networks associated to this physical network");
-        tablesToCheck.add(networks);
-
-        /*
-         * List<String> privateIP = new ArrayList<String>();
-         * privateIP.add(0, "op_dc_ip_address_alloc");
-         * privateIP.add(1, "data_center_id");
-         * privateIP.add(2, "there are private IP addresses allocated for this zone");
-         * tablesToCheck.add(privateIP);
-         */
-
-        List<String> publicIP = new ArrayList<String>();
-        publicIP.add(0, "user_ip_address");
-        publicIP.add(1, "physical_network_id");
-        publicIP.add(2, "there are public IP addresses allocated for this physical network");
-        tablesToCheck.add(publicIP);
-
-        for (List<String> table : tablesToCheck) {
-            String tableName = table.get(0);
-            String column = table.get(1);
-            String errorMsg = table.get(2);
-
-            String dbName = "cloud";
-
-            String selectSql = "SELECT * FROM `" + dbName + "`.`" + tableName + "` WHERE " + column + " = ?";
-
-            if (tableName.equals("networks")) {
-                selectSql += " AND removed is NULL";
-            }
-
-            if (tableName.equals("op_dc_vnet_alloc")) {
-                selectSql += " AND taken IS NOT NULL";
-            }
-
-            if (tableName.equals("user_ip_address")) {
-                selectSql += " AND state!='Free'";
-            }
-
-            if (tableName.equals("op_dc_ip_address_alloc")) {
-                selectSql += " AND taken IS NOT NULL";
-            }
-
-            TransactionLegacy txn = TransactionLegacy.currentTxn();
-            try {
-                PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
-                stmt.setLong(1, physicalNetworkId);
-                ResultSet rs = stmt.executeQuery();
-                if (rs != null && rs.next()) {
-                    throw new CloudRuntimeException("The Physical Network is not deletable because " + errorMsg);
-                }
-            } catch (SQLException ex) {
-                throw new CloudRuntimeException("The Management Server failed to detect if physical network is deletable. Please contact Cloud Support.");
-            }
-        }
-
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_VLAN_RANGE_DEDICATE, eventDescription = "dedicating guest vlan range", async = false)
-    public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
-        String vlan = cmd.getVlan();
-        String accountName = cmd.getAccountName();
-        Long domainId = cmd.getDomainId();
-        Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        Long projectId = cmd.getProjectId();
-
-        int startVlan, endVlan;
-        String updatedVlanRange = null;
-        long guestVlanMapId = 0;
-        long guestVlanMapAccountId = 0;
-        long vlanOwnerId = 0;
-
-        // Verify account is valid
-        Account vlanOwner = null;
-        if (projectId != null) {
-            if (accountName != null) {
-                throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
-            }
-            Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-            }
-            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
-        }
-
-        if ((accountName != null) && (domainId != null)) {
-            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
-        }
-        if (vlanOwner == null) {
-            throw new InvalidParameterValueException("Unable to find account by name " + accountName);
-        }
-        vlanOwnerId = vlanOwner.getAccountId();
-
-        // Verify physical network isolation type is VLAN
-        PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (physicalNetwork == null) {
-            throw new InvalidParameterValueException("Unable to find physical network by id " + physicalNetworkId);
-        } else if (!physicalNetwork.getIsolationMethods().isEmpty() && !physicalNetwork.getIsolationMethods().contains("VLAN")) {
-            throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " + "Physical isolation type of network " + physicalNetworkId + " is not VLAN");
-        }
-
-        // Get the start and end vlan
-        String[] vlanRange = vlan.split("-");
-        if (vlanRange.length != 2) {
-            throw new InvalidParameterValueException("Invalid format for parameter value vlan " + vlan + " .Vlan should be specified as 'startvlan-endvlan'");
-        }
-
-        try {
-            startVlan = Integer.parseInt(vlanRange[0]);
-            endVlan = Integer.parseInt(vlanRange[1]);
-        } catch (NumberFormatException e) {
-            s_logger.warn("Unable to parse guest vlan range:", e);
-            throw new InvalidParameterValueException("Please provide valid guest vlan range");
-        }
-
-        // Verify guest vlan range exists in the system
-        List<Pair<Integer, Integer>> existingRanges = physicalNetwork.getVnet();
-        Boolean exists = false;
-        if (!existingRanges.isEmpty()) {
-            for (int i = 0; i < existingRanges.size(); i++) {
-                int existingStartVlan = existingRanges.get(i).first();
-                int existingEndVlan = existingRanges.get(i).second();
-                if (startVlan <= endVlan && startVlan >= existingStartVlan && endVlan <= existingEndVlan) {
-                        exists = true;
-                        break;
-                    }
-            }
-            if (!exists) {
-                throw new InvalidParameterValueException("Unable to find guest vlan by range " + vlan);
-            }
-        }
-
-        // Verify guest vlans in the range don't belong to a network of a different account
-        for (int i = startVlan; i <= endVlan; i++) {
-            List<DataCenterVnetVO> allocatedVlans = _datacneterVnet.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
-            if (allocatedVlans != null && !allocatedVlans.isEmpty()) {
-                for (DataCenterVnetVO allocatedVlan : allocatedVlans) {
-                    if (allocatedVlan.getAccountId() !=  vlanOwner.getAccountId()) {
-                        throw new InvalidParameterValueException("Guest vlan from this range " + allocatedVlan.getVnet() + " is allocated to a different account."
-                                + " Can only dedicate a range which has no allocated vlans or has vlans allocated to the same account ");
-                    }
-                }
-            }
-        }
-
-        List<AccountGuestVlanMapVO> guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId);
-        // Verify if vlan range is already dedicated
-        for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) {
-            List<Integer> vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange());
-            int dedicatedStartVlan = vlanTokens.get(0).intValue();
-            int dedicatedEndVlan = vlanTokens.get(1).intValue();
-            if ((startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan) || (startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan)) {
-                throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + " dedicate guest vlan range " + vlan);
-            }
-        }
-
-        // Sort the existing dedicated vlan ranges
-        Collections.sort(guestVlanMaps, new Comparator<AccountGuestVlanMapVO>() {
-            @Override
-            public int compare(AccountGuestVlanMapVO obj1, AccountGuestVlanMapVO obj2) {
-                List<Integer> vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange());
-                List<Integer> vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange());
-                return vlanTokens1.get(0).compareTo(vlanTokens2.get(0));
-            }
-        });
-
-        // Verify if vlan range extends an already dedicated range
-        for (int i = 0; i < guestVlanMaps.size(); i++) {
-            guestVlanMapId = guestVlanMaps.get(i).getId();
-            guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId();
-            List<Integer> vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange());
-            // Range extends a dedicated vlan range to the left
-            if (endVlan == (vlanTokens1.get(0).intValue() - 1)) {
-                if (guestVlanMapAccountId == vlanOwnerId) {
-                    updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue();
-                }
-                break;
-            }
-            // Range extends a dedicated vlan range to the right
-            if (startVlan == (vlanTokens1.get(1).intValue() + 1) & guestVlanMapAccountId == vlanOwnerId) {
-                if (i != (guestVlanMaps.size() - 1)) {
-                    List<Integer> vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i + 1).getGuestVlanRange());
-                    // Range extends 2 vlan ranges, both to the right and left
-                    if (endVlan == (vlanTokens2.get(0).intValue() - 1) && guestVlanMaps.get(i + 1).getAccountId() == vlanOwnerId) {
-                        _datacneterVnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i + 1).getId());
-                        _accountGuestVlanMapDao.remove(guestVlanMaps.get(i + 1).getId());
-                        updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue();
-                        break;
-                    }
-                }
-                updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan;
-                break;
-            }
-        }
-        // Dedicate vlan range
-        AccountGuestVlanMapVO accountGuestVlanMapVO;
-        if (updatedVlanRange != null) {
-            accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId);
-            accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange);
-            _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO);
-        } else {
-            accountGuestVlanMapVO = new AccountGuestVlanMapVO(vlanOwner.getAccountId(), physicalNetworkId);
-            accountGuestVlanMapVO.setGuestVlanRange(startVlan + "-" +  endVlan);
-            _accountGuestVlanMapDao.persist(accountGuestVlanMapVO);
-        }
-        // For every guest vlan set the corresponding account guest vlan map id
-        List<Integer> finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange());
-        for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) {
-            List<DataCenterVnetVO> dataCenterVnet = _datacneterVnet.findVnet(physicalNetwork.getDataCenterId(), physicalNetworkId, Integer.toString(i));
-            dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId());
-            _datacneterVnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
-        }
-        return accountGuestVlanMapVO;
-    }
-
-    private List<Integer> getVlanFromRange(String vlanRange) {
-        // Get the start and end vlan
-        String[] vlanTokens = vlanRange.split("-");
-        List<Integer> tokens = new ArrayList<Integer>();
-        try {
-            int startVlan = Integer.parseInt(vlanTokens[0]);
-            int endVlan = Integer.parseInt(vlanTokens[1]);
-            tokens.add(startVlan);
-            tokens.add(endVlan);
-        } catch (NumberFormatException e) {
-            s_logger.warn("Unable to parse guest vlan range:", e);
-            throw new InvalidParameterValueException("Please provide valid guest vlan range");
-        }
-        return tokens;
-    }
-
-    @Override
-    public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
-        Long id = cmd.getId();
-        String accountName = cmd.getAccountName();
-        Long domainId = cmd.getDomainId();
-        Long projectId = cmd.getProjectId();
-        String guestVlanRange = cmd.getGuestVlanRange();
-        Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        Long zoneId = cmd.getZoneId();
-
-        Long accountId = null;
-        if (accountName != null && domainId != null) {
-            if (projectId != null) {
-                throw new InvalidParameterValueException("Account and projectId can't be specified together");
-            }
-            Account account = _accountDao.findActiveAccount(accountName, domainId);
-            if (account == null) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName);
-                DomainVO domain = ApiDBUtils.findDomainById(domainId);
-                String domainUuid = domainId.toString();
-                if (domain != null) {
-                    domainUuid = domain.getUuid();
-                }
-                ex.addProxyObject(domainUuid, "domainId");
-                throw ex;
-            } else {
-                accountId = account.getId();
-            }
-        }
-
-        // set project information
-        if (projectId != null) {
-            Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                throwInvalidIdException("Unable to find project by id " + projectId, projectId.toString(), "projectId");
-            }
-            accountId = project.getProjectAccountId();
-        }
-
-        SearchBuilder<AccountGuestVlanMapVO> sb = _accountGuestVlanMapDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
-        sb.and("guestVlanRange", sb.entity().getGuestVlanRange(), SearchCriteria.Op.EQ);
-        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
-
-        if (zoneId != null) {
-            SearchBuilder<PhysicalNetworkVO> physicalnetworkSearch = _physicalNetworkDao.createSearchBuilder();
-            physicalnetworkSearch.and("zoneId", physicalnetworkSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-            sb.join("physicalnetworkSearch", physicalnetworkSearch, sb.entity().getPhysicalNetworkId(), physicalnetworkSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<AccountGuestVlanMapVO> sc = sb.create();
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (accountId != null) {
-            sc.setParameters("accountId", accountId);
-        }
-
-        if (guestVlanRange != null) {
-            sc.setParameters("guestVlanRange", guestVlanRange);
-        }
-
-        if (physicalNetworkId != null) {
-            sc.setParameters("physicalNetworkId", physicalNetworkId);
-        }
-
-        if (zoneId != null) {
-            sc.setJoinParameters("physicalnetworkSearch", "zoneId", zoneId);
-        }
-
-        Filter searchFilter = new Filter(AccountGuestVlanMapVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        Pair<List<AccountGuestVlanMapVO>, Integer> result = _accountGuestVlanMapDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends GuestVlan>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, eventDescription = "releasing" + " dedicated guest vlan range", async = true)
-    @DB
-    public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
-        // Verify dedicated range exists
-        AccountGuestVlanMapVO dedicatedGuestVlan = _accountGuestVlanMapDao.findById(dedicatedGuestVlanRangeId);
-        if (dedicatedGuestVlan == null) {
-            throw new InvalidParameterValueException("Dedicated guest vlan with specified" + " id doesn't exist in the system");
-        }
-
-        // Remove dedication for the guest vlan
-        _datacneterVnet.releaseDedicatedGuestVlans(dedicatedGuestVlan.getId());
-        if (_accountGuestVlanMapDao.remove(dedicatedGuestVlanRangeId)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public List<? extends Service> listNetworkServices(String providerName) {
-
-        Provider provider = null;
-        if (providerName != null) {
-            provider = Network.Provider.getProvider(providerName);
-            if (provider == null) {
-                throw new InvalidParameterValueException("Invalid Network Service Provider=" + providerName);
-            }
-        }
-
-        if (provider != null) {
-            NetworkElement element = _networkModel.getElementImplementingProvider(providerName);
-            if (element == null) {
-                throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + providerName + "'");
-            }
-            return new ArrayList<Service>(element.getCapabilities().keySet());
-        } else {
-            return Service.listAllServices();
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_CREATE, eventDescription = "Creating Physical Network ServiceProvider", create = true)
-    public PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId, List<String> enabledServices) {
-
-        // verify input parameters
-        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
-        if (network == null) {
-            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
-        }
-
-        // verify input parameters
-        if (destinationPhysicalNetworkId != null) {
-            PhysicalNetworkVO destNetwork = _physicalNetworkDao.findById(destinationPhysicalNetworkId);
-            if (destNetwork == null) {
-                throwInvalidIdException("Destination Physical Network with specified id doesn't exist in the system", destinationPhysicalNetworkId.toString(),
-                                        "destinationPhysicalNetworkId");
-            }
-        }
-
-        if (providerName != null) {
-            Provider provider = Network.Provider.getProvider(providerName);
-            if (provider == null) {
-                throw new InvalidParameterValueException("Invalid Network Service Provider=" + providerName);
-            }
-        }
-
-        if (_pNSPDao.findByServiceProvider(physicalNetworkId, providerName) != null) {
-            // TBD: send uuid instead of physicalNetworkId.
-            throw new CloudRuntimeException("The '" + providerName + "' provider already exists on physical network : " + physicalNetworkId);
-        }
-
-        // check if services can be turned off
-        NetworkElement element = _networkModel.getElementImplementingProvider(providerName);
-        if (element == null) {
-            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + providerName + "'");
-        }
-        List<Service> services = new ArrayList<Service>();
-
-        if (enabledServices != null) {
-            if (!element.canEnableIndividualServices()) {
-                if (enabledServices.size() != element.getCapabilities().keySet().size()) {
-                    throw new InvalidParameterValueException("Cannot enable subset of Services, Please specify the complete list of Services for this Service Provider '"
-                            + providerName + "'");
-                }
-            }
-
-            // validate Services
-            boolean addGatewayService = false;
-            for (String serviceName : enabledServices) {
-                Network.Service service = Network.Service.getService(serviceName);
-                if (service == null || service == Service.Gateway) {
-                    throw new InvalidParameterValueException("Invalid Network Service specified=" + serviceName);
-                } else if (service == Service.SourceNat) {
-                    addGatewayService = true;
-                }
-
-                // check if the service is provided by this Provider
-                if (!element.getCapabilities().containsKey(service)) {
-                    throw new InvalidParameterValueException(providerName + " Provider cannot provide this Service specified=" + serviceName);
-                }
-                services.add(service);
-            }
-
-            if (addGatewayService) {
-                services.add(Service.Gateway);
-            }
-        } else {
-            // enable all the default services supported by this element.
-            services = new ArrayList<Service>(element.getCapabilities().keySet());
-        }
-
-        try {
-            // Create the new physical network in the database
-            PhysicalNetworkServiceProviderVO nsp = new PhysicalNetworkServiceProviderVO(physicalNetworkId, providerName);
-            // set enabled services
-            nsp.setEnabledServices(services);
-
-            if (destinationPhysicalNetworkId != null) {
-                nsp.setDestinationPhysicalNetworkId(destinationPhysicalNetworkId);
-            }
-            nsp = _pNSPDao.persist(nsp);
-
-            return nsp;
-        } catch (Exception ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new CloudRuntimeException("Fail to add a provider to physical network");
-        }
-
-    }
-
-    @Override
-    public Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex,
-            Long pageSize) {
-
-        Filter searchFilter = new Filter(PhysicalNetworkServiceProviderVO.class, "id", false, startIndex, pageSize);
-        SearchBuilder<PhysicalNetworkServiceProviderVO> sb = _pNSPDao.createSearchBuilder();
-        SearchCriteria<PhysicalNetworkServiceProviderVO> sc = sb.create();
-
-        if (physicalNetworkId != null) {
-            sc.addAnd("physicalNetworkId", Op.EQ, physicalNetworkId);
-        }
-
-        if (name != null) {
-            sc.addAnd("providerName", Op.EQ, name);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", Op.EQ, state);
-        }
-
-        Pair<List<PhysicalNetworkServiceProviderVO>, Integer> result =  _pNSPDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends PhysicalNetworkServiceProvider>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_UPDATE, eventDescription = "Updating physical network ServiceProvider", async = true)
-    public PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String stateStr, List<String> enabledServices) {
-
-        PhysicalNetworkServiceProviderVO provider = _pNSPDao.findById(id);
-        if (provider == null) {
-            throw new InvalidParameterValueException("Network Service Provider id=" + id + "doesn't exist in the system");
-        }
-
-        NetworkElement element = _networkModel.getElementImplementingProvider(provider.getProviderName());
-        if (element == null) {
-            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getProviderName() + "'");
-        }
-
-        PhysicalNetworkServiceProvider.State state = null;
-        if (stateStr != null && !stateStr.isEmpty()) {
-            try {
-                state = PhysicalNetworkServiceProvider.State.valueOf(stateStr);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve state '" + stateStr + "' to a supported value {Enabled or Disabled}");
-            }
-        }
-
-        boolean update = false;
-
-        if (state != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("trying to update the state of the service provider id=" + id + " on physical network: " + provider.getPhysicalNetworkId() + " to state: "
-                        + stateStr);
-            }
-            switch (state) {
-            case Enabled:
-                if (element != null && element.isReady(provider)) {
-                    provider.setState(PhysicalNetworkServiceProvider.State.Enabled);
-                    update = true;
-                } else {
-                    throw new CloudRuntimeException("Provider is not ready, cannot Enable the provider, please configure the provider first");
-                }
-                break;
-            case Disabled:
-                // do we need to do anything for the provider instances before disabling?
-                provider.setState(PhysicalNetworkServiceProvider.State.Disabled);
-                update = true;
-                break;
-            case Shutdown:
-                throw new  InvalidParameterValueException("Updating the provider state to 'Shutdown' is not supported");
-            }
-        }
-
-        if (enabledServices != null) {
-            // check if services can be turned of
-            if (!element.canEnableIndividualServices()) {
-                throw new InvalidParameterValueException("Cannot update set of Services for this Service Provider '" + provider.getProviderName() + "'");
-            }
-
-            // validate Services
-            List<Service> services = new ArrayList<Service>();
-            for (String serviceName : enabledServices) {
-                Network.Service service = Network.Service.getService(serviceName);
-                if (service == null) {
-                    throw new InvalidParameterValueException("Invalid Network Service specified=" + serviceName);
-                }
-                services.add(service);
-            }
-            // set enabled services
-            provider.setEnabledServices(services);
-            update = true;
-        }
-
-        if (update) {
-            _pNSPDao.update(id, provider);
-        }
-        return provider;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_DELETE, eventDescription = "Deleting physical network ServiceProvider", async = true)
-    public boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException {
-        PhysicalNetworkServiceProviderVO provider = _pNSPDao.findById(id);
-
-        if (provider == null) {
-            throw new InvalidParameterValueException("Network Service Provider id=" + id + "doesn't exist in the system");
-        }
-
-        // check if there are networks using this provider
-        List<NetworkVO> networks = _networksDao.listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), provider.getProviderName());
-        if (networks != null && !networks.isEmpty()) {
-            throw new CloudRuntimeException(
-                    "Provider is not deletable because there are active networks using this provider, please upgrade these networks to new network offerings");
-        }
-
-        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-        Account callerAccount = _accountMgr.getActiveAccountById(callerUser.getAccountId());
-        // shutdown the provider instances
-        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Shutting down the service provider id=" + id + " on physical network: " + provider.getPhysicalNetworkId());
-        }
-        NetworkElement element = _networkModel.getElementImplementingProvider(provider.getProviderName());
-        if (element == null) {
-            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getProviderName() + "'");
-        }
-
-        if (element != null && element.shutdownProviderInstances(provider, context)) {
-            provider.setState(PhysicalNetworkServiceProvider.State.Shutdown);
-        }
-
-        return _pNSPDao.remove(id);
-    }
-
-    @Override
-    public PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId) {
-        return _physicalNetworkDao.findById(physicalNetworkId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", async = true)
-    public PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId) {
-        return getPhysicalNetwork(physicalNetworkId);
-    }
-
-    @Override
-    public PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId) {
-        return _pNSPDao.findById(providerId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_CREATE, eventDescription = "Creating Physical Network ServiceProvider", async = true)
-    public PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId) {
-        return getPhysicalNetworkServiceProvider(providerId);
-    }
-
-    @Override
-    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
-        List<PhysicalNetworkVO> pNtwks = new ArrayList<PhysicalNetworkVO>();
-        if (trafficType != null) {
-            pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
-        } else {
-            pNtwks = _physicalNetworkDao.listByZone(zoneId);
-        }
-
-        if (pNtwks.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId);
-        }
-
-        if (pNtwks.size() > 1) {
-            if (tag == null) {
-                throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " and no tags are specified in order to make a choice");
-            }
-
-            Long pNtwkId = null;
-            for (PhysicalNetwork pNtwk : pNtwks) {
-                if (pNtwk.getTags().contains(tag)) {
-                    s_logger.debug("Found physical network id=" + pNtwk.getId() + " based on requested tags " + tag);
-                    pNtwkId = pNtwk.getId();
-                    break;
-                }
-            }
-            if (pNtwkId == null) {
-                throw new InvalidParameterValueException("Unable to find physical network which match the tags " + tag);
-            }
-            return pNtwkId;
-        } else {
-            return pNtwks.get(0).getId();
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true)
-    public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-            String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
-
-        // verify input parameters
-        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Physical Network id=" + physicalNetworkId + "doesn't exist in the system");
-        }
-
-        Networks.TrafficType trafficType = null;
-        if (trafficTypeStr != null && !trafficTypeStr.isEmpty()) {
-            try {
-                trafficType = Networks.TrafficType.valueOf(trafficTypeStr);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve trafficType '" + trafficTypeStr + "' to a supported value");
-            }
-        }
-
-        if (_pNTrafficTypeDao.isTrafficTypeSupported(physicalNetworkId, trafficType)) {
-            throw new CloudRuntimeException("This physical network already supports the traffic type: " + trafficType);
-        }
-        // For Storage, Control, Management, Public check if the zone has any other physical network with this
-        // traffictype already present
-        // If yes, we cant add these traffics to one more physical network in the zone.
-
-        if (TrafficType.isSystemNetwork(trafficType) || TrafficType.Public.equals(trafficType) || TrafficType.Storage.equals(trafficType)) {
-            if (!_physicalNetworkDao.listByZoneAndTrafficType(network.getDataCenterId(), trafficType).isEmpty()) {
-                throw new CloudRuntimeException("Fail to add the traffic type to physical network because Zone already has a physical network with this traffic type: "
-                        + trafficType);
-            }
-        }
-
-        if (TrafficType.Storage.equals(trafficType)) {
-            List<SecondaryStorageVmVO> ssvms = _stnwMgr.getSSVMWithNoStorageNetwork(network.getDataCenterId());
-            if (!ssvms.isEmpty()) {
-                StringBuilder sb = new StringBuilder(
-                        "Cannot add "
-                                + trafficType
-                                + " traffic type as there are below secondary storage vm still running. Please stop them all and add Storage traffic type again, then destory them all to allow CloudStack recreate them with storage network(If you have added storage network ip range)");
-                sb.append("SSVMs:");
-                for (SecondaryStorageVmVO ssvm : ssvms) {
-                    sb.append(ssvm.getInstanceName()).append(":").append(ssvm.getState());
-                }
-                throw new CloudRuntimeException(sb.toString());
-            }
-        }
-
-        try {
-            // Create the new traffic type in the database
-            if (xenLabel == null) {
-                xenLabel = getDefaultXenNetworkLabel(trafficType);
-            }
-            PhysicalNetworkTrafficTypeVO pNetworktrafficType = new PhysicalNetworkTrafficTypeVO(physicalNetworkId, trafficType, xenLabel, kvmLabel, vmwareLabel, simulatorLabel,
-                    vlan, hypervLabel, ovm3Label);
-            pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType);
-
-            // For public traffic, get isolation method of physical network and update the public network accordingly
-            // each broadcast type will individually need to be qualified for support of public traffic
-            if (TrafficType.Public.equals(trafficType)){
-            List<String> isolationMethods = network.getIsolationMethods();
-            if ((isolationMethods.size() == 1 && isolationMethods.get(0).toLowerCase().equals("vxlan"))
-                || (isolationMethod != null && isolationMethods.contains(isolationMethod) && isolationMethod.toLowerCase().equals("vxlan"))) {
-                // find row in networks table that is defined as 'Public', created when zone was deployed
-                NetworkVO publicNetwork = _networksDao.listByZoneAndTrafficType(network.getDataCenterId(),TrafficType.Public).get(0);
-                if (publicNetwork != null) {
-                    s_logger.debug("setting public network " + publicNetwork + " to broadcast type vxlan");
-                    publicNetwork.setBroadcastDomainType(BroadcastDomainType.Vxlan);
-                    _networksDao.persist(publicNetwork);
-                }
-            }
-            }
-
-            return pNetworktrafficType;
-        } catch (Exception ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new CloudRuntimeException("Fail to add a traffic type to physical network");
-        }
-
-    }
-
-    private String getDefaultXenNetworkLabel(TrafficType trafficType) {
-        String xenLabel = null;
-        switch (trafficType) {
-        case Public:
-            xenLabel = _configDao.getValue(Config.XenServerPublicNetwork.key());
-            break;
-        case Guest:
-            xenLabel = _configDao.getValue(Config.XenServerGuestNetwork.key());
-            break;
-        case Storage:
-            xenLabel = _configDao.getValue(Config.XenServerStorageNetwork1.key());
-            break;
-        case Management:
-            xenLabel = _configDao.getValue(Config.XenServerPrivateNetwork.key());
-            break;
-        case Control:
-            xenLabel = "cloud_link_local_network";
-            break;
-        case Vpn:
-        case None:
-            break;
-        }
-        return xenLabel;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", async = true)
-    public PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id) {
-        return _pNTrafficTypeDao.findById(id);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_UPDATE, eventDescription = "Updating physical network TrafficType", async = true)
-    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
-
-        PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
-
-        if (trafficType == null) {
-            throw new InvalidParameterValueException("Traffic Type with id=" + id + "doesn't exist in the system");
-        }
-
-        if (xenLabel != null) {
-            if ("".equals(xenLabel)) {
-                xenLabel = null;
-            }
-            trafficType.setXenNetworkLabel(xenLabel);
-        }
-        if (kvmLabel != null) {
-            if ("".equals(kvmLabel)) {
-                kvmLabel = null;
-            }
-            trafficType.setKvmNetworkLabel(kvmLabel);
-        }
-        if (vmwareLabel != null) {
-            if ("".equals(vmwareLabel)) {
-                vmwareLabel = null;
-            }
-            trafficType.setVmwareNetworkLabel(vmwareLabel);
-        }
-
-        if (hypervLabel != null) {
-            if ("".equals(hypervLabel)) {
-                hypervLabel = null;
-            }
-            trafficType.setHypervNetworkLabel(hypervLabel);
-        }
-
-        if (ovm3Label != null) {
-            if ("".equals(ovm3Label)) {
-                ovm3Label = null;
-            }
-            trafficType.setOvm3NetworkLabel(ovm3Label);
-        }
-        _pNTrafficTypeDao.update(id, trafficType);
-        return trafficType;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_DELETE, eventDescription = "Deleting physical network TrafficType", async = true)
-    public boolean deletePhysicalNetworkTrafficType(Long id) {
-        PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
-
-        if (trafficType == null) {
-            throw new InvalidParameterValueException("Traffic Type with id=" + id + "doesn't exist in the system");
-        }
-
-        // check if there are any networks associated to this physical network with this traffic type
-        if (TrafficType.Guest.equals(trafficType.getTrafficType())) {
-            if (!_networksDao.listByPhysicalNetworkTrafficType(trafficType.getPhysicalNetworkId(), trafficType.getTrafficType()).isEmpty()) {
-                throw new CloudRuntimeException("The Traffic Type is not deletable because there are existing networks with this traffic type:" + trafficType.getTrafficType());
-            }
-        } else if (TrafficType.Storage.equals(trafficType.getTrafficType())) {
-            PhysicalNetworkVO pn = _physicalNetworkDao.findById(trafficType.getPhysicalNetworkId());
-            if (_stnwMgr.isAnyStorageIpInUseInZone(pn.getDataCenterId())) {
-                throw new CloudRuntimeException("The Traffic Type is not deletable because there are still some storage network ip addresses in use:"
-                        + trafficType.getTrafficType());
-            }
-        }
-        return _pNTrafficTypeDao.remove(id);
-    }
-
-    @Override
-    public Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId) {
-        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
-        if (network == null) {
-            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
-        }
-
-        Pair<List<PhysicalNetworkTrafficTypeVO>, Integer> result = _pNTrafficTypeDao.listAndCountBy(physicalNetworkId);
-        return new Pair<List<? extends PhysicalNetworkTrafficType>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    //TODO: duplicated in NetworkModel
-    public NetworkVO getExclusiveGuestNetwork(long zoneId) {
-        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, zoneId, GuestType.Shared, TrafficType.Guest);
-        if (networks == null || networks.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " + zoneId);
-        }
-
-        if (networks.size() > 1) {
-            throw new InvalidParameterValueException("Found more than 1 network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone "
-                    + zoneId);
-
-        }
-
-        return networks.get(0);
-    }
-
-    protected PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) {
-
-        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName(), null, null);
-        // add instance of the provider
-        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.VirtualRouter.getName());
-        if (networkElement == null) {
-            throw new CloudRuntimeException("Unable to find the Network Element implementing the VirtualRouter Provider");
-        }
-
-        VirtualRouterElement element = (VirtualRouterElement)networkElement;
-        element.addElement(nsp.getId(), Type.VirtualRouter);
-
-        return nsp;
-    }
-
-    private PhysicalNetworkServiceProvider addDefaultOvsToPhysicalNetwork(long physicalNetworkId) {
-        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.Ovs.getName(), null, null);
-        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.Ovs.getName());
-        if (networkElement == null) {
-            throw new CloudRuntimeException("Unable to find the Network Element implementing the Ovs Provider");
-        }
-        OvsProviderVO element = _ovsProviderDao.findByNspId(nsp.getId());
-        if (element != null) {
-            s_logger.debug("There is already a Ovs element with service provider id " + nsp.getId());
-            return nsp;
-        }
-        element = new OvsProviderVO(nsp.getId());
-        _ovsProviderDao.persist(element);
-        return nsp;
-    }
-
-    protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) {
-
-        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName(), null, null);
-
-        NetworkElement networkElement =  _networkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName());
-        if (networkElement == null) {
-            throw new CloudRuntimeException("Unable to find the Network Element implementing the VPCVirtualRouter Provider");
-        }
-
-        VpcVirtualRouterElement element = (VpcVirtualRouterElement)networkElement;
-        element.addElement(nsp.getId(), Type.VPCVirtualRouter);
-
-        return nsp;
-    }
-
-    protected PhysicalNetworkServiceProvider addDefaultInternalLbProviderToPhysicalNetwork(long physicalNetworkId) {
-
-        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.InternalLbVm.getName(), null, null);
-
-        NetworkElement networkElement =  _networkModel.getElementImplementingProvider(Network.Provider.InternalLbVm.getName());
-        if (networkElement == null) {
-            throw new CloudRuntimeException("Unable to find the Network Element implementing the " + Network.Provider.InternalLbVm.getName() + " Provider");
-        }
-
-        _internalLbElementSvc.addInternalLoadBalancerElement(nsp.getId());
-
-        return nsp;
-    }
-
-    protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) {
-
-        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.SecurityGroupProvider.getName(), null, null);
-
-        return nsp;
-    }
-
-    private PhysicalNetworkServiceProvider addDefaultBaremetalProvidersToPhysicalNetwork(long physicalNetworkId) {
-        PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId);
-        DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId());
-        if (dvo.getNetworkType() == NetworkType.Basic) {
-
-            Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider");
-            if (provider == null) {
-                // baremetal is not loaded
-                return null;
-            }
-
-            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalDhcpProvider", null, null);
-            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
-            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalUserdataProvider", null, null);
-        } else if (dvo.getNetworkType() == NetworkType.Advanced) {
-            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
-            enableProvider("BaremetalPxeProvider");
-        }
-
-        return null;
-    }
-
-    private void enableProvider(String providerName) {
-        QueryBuilder<PhysicalNetworkServiceProviderVO> q = QueryBuilder.create(PhysicalNetworkServiceProviderVO.class);
-        q.and(q.entity().getProviderName(), SearchCriteria.Op.EQ, providerName);
-        PhysicalNetworkServiceProviderVO provider = q.find();
-        provider.setState(PhysicalNetworkServiceProvider.State.Enabled);
-        _pNSPDao.update(provider.getId(), provider);
-    }
-
-    private PhysicalNetworkServiceProvider addConfigDriveToPhysicalNetwork(long physicalNetworkId) {
-        PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId);
-        DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId());
-        if (dvo.getNetworkType() == NetworkType.Advanced) {
-
-            Provider provider = Network.Provider.getProvider("ConfigDrive");
-            if (provider == null) {
-                return null;
-            }
-
-            addProviderToPhysicalNetwork(physicalNetworkId, Provider.ConfigDrive.getName(), null, null);
-            enableProvider(Provider.ConfigDrive.getName());
-        }
-        return null;
-
-    }
-    protected boolean isNetworkSystem(Network network) {
-        NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        if (no.isSystemOnly()) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private boolean getAllowSubdomainAccessGlobal() {
-        return _allowSubdomainNetworkAccess;
-    }
-
-    @Override
-    public List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd) {
-        String type = cmd.getTrafficType();
-        List<Pair<TrafficType, String>> results = new ArrayList<Pair<TrafficType, String>>();
-        if (type != null) {
-            for (NetworkGuru guru : _networkGurus) {
-                if (guru.isMyTrafficType(TrafficType.getTrafficType(type))) {
-                    results.add(new Pair<TrafficType, String>(TrafficType.getTrafficType(type), guru.getName()));
-                    break;
-                }
-            }
-        } else {
-            for (NetworkGuru guru : _networkGurus) {
-                TrafficType[] allTypes = guru.getSupportedTrafficType();
-                for (TrafficType t : allTypes) {
-                    results.add(new Pair<TrafficType, String>(t, guru.getName()));
-                }
-            }
-        }
-
-        return results;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
-    public IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException,
-            ConcurrentOperationException {
-
-        Network network = _networksDao.findById(networkId);
-        if (network == null) {
-            // release the acquired IP addrress before throwing the exception
-            // else it will always be in allocating state
-            releaseIpAddress(ipId);
-            throw new InvalidParameterValueException("Invalid network id is given");
-        }
-
-        if (network.getVpcId() != null) {
-            // release the acquired IP addrress before throwing the exception
-            // else it will always be in allocating state
-            releaseIpAddress(ipId);
-            throw new InvalidParameterValueException("Can't assign ip to the network directly when network belongs" + " to VPC.Specify vpcId to associate ip address to VPC");
-        }
-        return _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, true);
-
-    }
-
-    @Override
-    @DB
-    public Network createPrivateNetwork(final String networkName, final String displayText, long physicalNetworkId, String broadcastUriString, final String startIp, String endIp,
-            final String gateway, String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId)
-                    throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
-
-        final Account owner = _accountMgr.getAccount(networkOwnerId);
-
-        // Get system network offering
-        NetworkOfferingVO ntwkOff = null;
-        if (networkOfferingId != null) {
-            ntwkOff = _networkOfferingDao.findById(networkOfferingId);
-        }
-        if (ntwkOff == null) {
-            ntwkOff = findSystemNetworkOffering(NetworkOffering.SystemPrivateGatewayNetworkOffering);
-        }
-
-        // Validate physical network
-        final PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNtwk == null) {
-            throwInvalidIdException("Unable to find a physical network" + " having the given id", String.valueOf(physicalNetworkId), "physicalNetworkId");
-        }
-
-        // VALIDATE IP INFO
-        // if end ip is not specified, default it to startIp
-        if (!NetUtils.isValidIp4(startIp)) {
-            throw new InvalidParameterValueException("Invalid format for the ip address parameter");
-        }
-        if (endIp == null) {
-            endIp = startIp;
-        } else if (!NetUtils.isValidIp4(endIp)) {
-            throw new InvalidParameterValueException("Invalid format for the endIp address parameter");
-        }
-
-        if (!NetUtils.isValidIp4(gateway)) {
-            throw new InvalidParameterValueException("Invalid gateway");
-        }
-        if (!NetUtils.isValidIp4Netmask(netmask)) {
-            throw new InvalidParameterValueException("Invalid netmask");
-        }
-
-        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-
-        URI uri = BroadcastDomainType.fromString(broadcastUriString);
-        final String uriString = uri.toString();
-        BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri);
-        // numeric vlan or vlan uri are ok for now
-        // TODO make a test for any supported scheme
-        if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) {
-            throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString);
-        }
-
-        final NetworkOfferingVO ntwkOffFinal = ntwkOff;
-        try {
-            return Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
-                @Override
-                public Network doInTransaction(TransactionStatus status) throws ResourceAllocationException, InsufficientCapacityException {
-                    //lock datacenter as we need to get mac address seq from there
-                    DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true);
-
-                    //check if we need to create guest network
-                    Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId);
-                    if (privateNetwork == null) {
-                        //create Guest network
-                        privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, false, null, owner, null, pNtwk,
-                                                                        pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null, null);
-                        if (privateNetwork != null) {
-                            s_logger.debug("Successfully created guest network " + privateNetwork);
-                        } else {
-                            throw new CloudRuntimeException("Creating guest network failed");
-                        }
-                    } else {
-                        s_logger.debug("Private network already exists: " + privateNetwork);
-                        //Do not allow multiple private gateways with same Vlan within a VPC
-                        if (vpcId != null && vpcId.equals(privateNetwork.getVpcId())) {
-                            throw new InvalidParameterValueException("Private network for the vlan: " + uriString + " and cidr  " + cidr + "  already exists " + "for Vpc " + vpcId
-                                    + " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
-                        }
-                    }
-                    if (vpcId != null) {
-                        //add entry to private_ip_address table
-                        PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId);
-                        if (privateIp != null) {
-                            throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + " in zone "
-                                    + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
-                        }
-                        Long mac = dc.getMacAddress();
-                        Long nextMac = mac + 1;
-                        dc.setMacAddress(nextMac);
-                        privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat);
-                        _privateIpDao.persist(privateIp);
-                        _dcDao.update(dc.getId(), dc);
-                    }
-
-                    s_logger.debug("Private network " + privateNetwork + " is created");
-
-                    return privateNetwork;
-                }
-            });
-        } catch (Exception e) {
-            ExceptionUtil.rethrowRuntime(e);
-            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
-            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
-            throw new IllegalStateException(e);
-        }
-    }
-
-    private NetworkOfferingVO findSystemNetworkOffering(String offeringName) {
-        List<NetworkOfferingVO> allOfferings = _networkOfferingDao.listSystemNetworkOfferings();
-        for (NetworkOfferingVO offer : allOfferings) {
-            if (offer.getName().equals(offeringName)) {
-                return offer;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Network getNetwork(String networkUuid) {
-       return _networksDao.findByUuid(networkUuid);
-    }
-
-    @Override
-    public List<? extends Nic> listNics(ListNicsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long nicId = cmd.getNicId();
-        long vmId = cmd.getVmId();
-        String keyword = cmd.getKeyword();
-        Long networkId = cmd.getNetworkId();
-        UserVmVO  userVm = _userVmDao.findById(vmId);
-
-        if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
-            throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
-            }
-
-        _accountMgr.checkAccess(caller, null, true, userVm);
-        return _networkMgr.listVmNics(vmId, nicId, networkId, keyword);
-    }
-
-    @Override
-    public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd cmd)
-    {
-        Account caller = CallContext.current().getCallingAccount();
-        Long nicId = cmd.getNicId();
-        long vmId = cmd.getVmId();
-        String keyword = cmd.getKeyword();
-        UserVmVO  userVm = _userVmDao.findById(vmId);
-
-        if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
-            throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, userVm);
-        return _nicSecondaryIpDao.listSecondaryIpUsingKeyword(nicId, keyword);
-    }
-
-    public List<NetworkGuru> getNetworkGurus() {
-        return _networkGurus;
-    }
-
-    @Inject
-    public void setNetworkGurus(List<NetworkGuru> networkGurus) {
-        _networkGurus = networkGurus;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_UPDATE, eventDescription = "updating public ip address", async = true)
-    public IpAddress updateIP(Long id, String customId, Boolean displayIp) {
-        Account caller = CallContext.current().getCallingAccount();
-        IPAddressVO ipVO = _ipAddressDao.findById(id);
-        if (ipVO == null) {
-            throw new InvalidParameterValueException("Unable to find ip address by id");
-        }
-
-        // verify permissions
-        if (ipVO.getAllocatedToAccountId() != null) {
-            _accountMgr.checkAccess(caller, null, true, ipVO);
-        } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new PermissionDeniedException("Only Root admin can update non-allocated ip addresses");
-        }
-
-        if (customId != null) {
-            ipVO.setUuid(customId);
-        }
-
-        if (displayIp != null) {
-            ipVO.setDisplay(displayIp);
-        }
-
-        _ipAddressDao.update(id, ipVO);
-        return _ipAddressDao.findById(id);
-    }
-
-    @Override
-    public AcquirePodIpCmdResponse allocatePodIp(Account ipOwner, String zoneId, String podId) throws ResourceAllocationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        long callerUserId = CallContext.current().getCallingUserId();
-        DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId);
-
-        if (zone == null)
-            throw new InvalidParameterValueException("Invalid zone Id ");
-        if (_accountMgr.checkAccessAndSpecifyAuthority(caller, zone.getId()) != zone.getId())
-            throw new InvalidParameterValueException("Caller does not have permission for this Zone" + "(" + zoneId + ")");
-        if (s_logger.isDebugEnabled())
-            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
-        return _ipAddrMgr.allocatePodIp(zoneId, podId);
-
-    }
-
-    @Override
-    public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
-        _ipAddrMgr.releasePodIp(ip.getId());
-        return true;
-    }
-
-}
diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
deleted file mode 100644
index 0d5da2f..0000000
--- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java
+++ /dev/null
@@ -1,1532 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.as;
-
-import java.security.InvalidParameterException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
-import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmProfileCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateConditionCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScalePoliciesCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmGroupsCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmProfilesCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListConditionsCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListCountersCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
-import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.dispatch.DispatchChainFactory;
-import com.cloud.api.dispatch.DispatchTask;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterParam;
-import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
-import com.cloud.network.as.dao.AutoScalePolicyDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
-import com.cloud.network.as.dao.AutoScaleVmProfileDao;
-import com.cloud.network.as.dao.ConditionDao;
-import com.cloud.network.as.dao.CounterDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.LoadBalancerVMMapVO;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.lb.LoadBalancingRulesService;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmService;
-
-public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScaleManager, AutoScaleService {
-    private static final Logger s_logger = Logger.getLogger(AutoScaleManagerImpl.class);
-    private ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1);
-
-    @Inject
-    protected DispatchChainFactory dispatchChainFactory = null;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    TemplateManager _templateMgr;
-    @Inject
-    LoadBalancingRulesManager _lbRulesMgr;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    CounterDao _counterDao;
-    @Inject
-    ConditionDao _conditionDao;
-    @Inject
-    LoadBalancerVMMapDao _lb2VmMapDao;
-    @Inject
-    LoadBalancerDao _lbDao;
-    @Inject
-    AutoScaleVmProfileDao _autoScaleVmProfileDao;
-    @Inject
-    AutoScalePolicyDao _autoScalePolicyDao;
-    @Inject
-    AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao;
-    @Inject
-    AutoScaleVmGroupDao _autoScaleVmGroupDao;
-    @Inject
-    AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao;
-    @Inject
-    AutoScaleVmGroupVmMapDao _autoScaleVmGroupVmMapDao;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    UserDao _userDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    AccountService _accountService;
-    @Inject
-    UserVmService _userVmService;
-    @Inject
-    UserVmManager _userVmManager;
-    @Inject
-    LoadBalancerVMMapDao _lbVmMapDao;
-    @Inject
-    LoadBalancingRulesService _loadBalancingRulesService;
-
-    public List<AutoScaleCounter> getSupportedAutoScaleCounters(long networkid) {
-        String capability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName());
-        if (capability == null) {
-            return null;
-        }
-        Gson gson = new Gson();
-        java.lang.reflect.Type listType = new TypeToken<List<AutoScaleCounter>>() {
-        }.getType();
-        List<AutoScaleCounter> result = gson.fromJson(capability, listType);
-        return result;
-    }
-
-    public void validateAutoScaleCounters(long networkid, List<Counter> counters, List<Pair<String, String>> counterParamPassed) {
-        List<AutoScaleCounter> supportedCounters = getSupportedAutoScaleCounters(networkid);
-        if (supportedCounters == null) {
-            throw new InvalidParameterException("AutoScale is not supported in the network");
-        }
-        for (Counter counter : counters) {
-            String counterName = counter.getSource().name().toString();
-            boolean isCounterSupported = false;
-            for (AutoScaleCounter autoScaleCounter : supportedCounters) {
-                if (autoScaleCounter.getName().equals(counterName)) {
-                    isCounterSupported = true;
-                    List<AutoScaleCounterParam> counterParams = autoScaleCounter.getParamList();
-                    for (AutoScaleCounterParam autoScaleCounterParam : counterParams) {
-                        boolean isRequiredParameter = autoScaleCounterParam.getRequired();
-                        if (isRequiredParameter) {
-                            boolean isRequiredParamPresent = false;
-                            for (Pair<String, String> pair : counterParamPassed) {
-                                if (pair.first().equals(autoScaleCounterParam.getParamName()))
-                                    isRequiredParamPresent = true;
-
-                            }
-                            if (!isRequiredParamPresent) {
-                                throw new InvalidParameterException("Parameter " + autoScaleCounterParam.getParamName() + " has to be set in AutoScaleVmProfile's " +
-                                    ApiConstants.COUNTERPARAM_LIST);
-                            }
-                        }
-                    }
-                    break;
-                }
-            }
-            if (!isCounterSupported) {
-                throw new InvalidParameterException("AutoScale counter with source='" + counter.getSource().name() + "' is not supported " + "in the network");
-            }
-        }
-    }
-
-    private <VO extends ControlledEntity> VO getEntityInDatabase(Account caller, String paramName, Long id, GenericDao<VO, Long> dao) {
-
-        VO vo = dao.findById(id);
-
-        if (vo == null) {
-            throw new InvalidParameterValueException("Unable to find " + paramName);
-        }
-
-        _accountMgr.checkAccess(caller, null, false, (ControlledEntity)vo);
-
-        return vo;
-    }
-
-    private boolean isAutoScaleScaleUpPolicy(AutoScalePolicy policyVO) {
-        return policyVO.getAction().equals("scaleup");
-    }
-
-    private List<AutoScalePolicyVO> getAutoScalePolicies(String paramName, List<Long> policyIds, List<Counter> counters, int interval, boolean scaleUpPolicies) {
-        SearchBuilder<AutoScalePolicyVO> policySearch = _autoScalePolicyDao.createSearchBuilder();
-        policySearch.and("ids", policySearch.entity().getId(), Op.IN);
-        policySearch.done();
-        SearchCriteria<AutoScalePolicyVO> sc = policySearch.create();
-
-        sc.setParameters("ids", policyIds.toArray(new Object[0]));
-        List<AutoScalePolicyVO> policies = _autoScalePolicyDao.search(sc, null);
-
-        int prevQuietTime = 0;
-
-        for (AutoScalePolicyVO policy : policies) {
-            int quietTime = policy.getQuietTime();
-            if (prevQuietTime == 0) {
-                prevQuietTime = quietTime;
-            }
-            int duration = policy.getDuration();
-            if (duration < interval) {
-                throw new InvalidParameterValueException("duration : " + duration + " specified in a policy cannot be less than vm group's interval : " + interval);
-            }
-
-            if (quietTime != prevQuietTime) {
-                throw new InvalidParameterValueException("quietTime should be same for all the policies specified in " + paramName);
-            }
-
-            if (scaleUpPolicies) {
-                if (!isAutoScaleScaleUpPolicy(policy)) {
-                    throw new InvalidParameterValueException("Only scaleup policies can be specified in scaleuppolicyids");
-                }
-            } else {
-                if (isAutoScaleScaleUpPolicy(policy)) {
-                    throw new InvalidParameterValueException("Only scaledown policies can be specified in scaledownpolicyids");
-                }
-            }
-            List<AutoScalePolicyConditionMapVO> policyConditionMapVOs = _autoScalePolicyConditionMapDao.listByAll(policy.getId(), null);
-            for (AutoScalePolicyConditionMapVO policyConditionMapVO : policyConditionMapVOs) {
-                long conditionid = policyConditionMapVO.getConditionId();
-                Condition condition = _conditionDao.findById(conditionid);
-                Counter counter = _counterDao.findById(condition.getCounterid());
-                counters.add(counter);
-            }
-        }
-        return policies;
-    }
-
-    @DB
-    protected AutoScaleVmProfileVO checkValidityAndPersist(AutoScaleVmProfileVO vmProfile) {
-        long templateId = vmProfile.getTemplateId();
-        long autoscaleUserId = vmProfile.getAutoScaleUserId();
-        int destroyVmGraceperiod = vmProfile.getDestroyVmGraceperiod();
-
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
-        // Make sure a valid template ID was specified
-        if (template == null) {
-            throw new InvalidParameterValueException("Unable to use the given template.");
-        }
-
-        if (destroyVmGraceperiod < 0) {
-            throw new InvalidParameterValueException("Destroy Vm Grace Period cannot be less than 0.");
-        }
-
-        User user = _userDao.findById(autoscaleUserId);
-        if (user.getAccountId() != vmProfile.getAccountId()) {
-            throw new InvalidParameterValueException("AutoScale User id does not belong to the same account");
-        }
-
-        String apiKey = user.getApiKey();
-        String secretKey = user.getSecretKey();
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
-
-        if (apiKey == null) {
-            throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it");
-        }
-
-        if (secretKey == null) {
-            throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it");
-        }
-
-        if (csUrl == null || csUrl.contains("localhost")) {
-            throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
-        }
-
-        vmProfile = _autoScaleVmProfileDao.persist(vmProfile);
-
-        return vmProfile;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, eventDescription = "creating autoscale vm profile", create = true)
-    public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd) {
-
-        Account owner = _accountDao.findById(cmd.getAccountId());
-        Account caller = CallContext.current().getCallingAccount();
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        long zoneId = cmd.getZoneId();
-        long serviceOfferingId = cmd.getServiceOfferingId();
-        long autoscaleUserId = cmd.getAutoscaleUserId();
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id");
-        }
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering by id");
-        }
-
-        // validations
-        HashMap<String, String> deployParams = cmd.getDeployParamMap();
-        if (deployParams.containsKey("networks") && deployParams.get("networks").length() > 0) {
-            throw new InvalidParameterValueException(
-                "'networks' is not a valid parameter, network for an AutoScaled VM is chosen automatically. An autoscaled VM is deployed in the loadbalancer's network");
-        }
-        /*
-         * Just for making sure the values are right in other deploy params.
-         * For ex. if projectId is given as a string instead of an long value, this
-         * will be throwing an error.
-         */
-        dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(ComponentContext.inject(DeployVMCmd.class), deployParams));
-
-        AutoScaleVmProfileVO profileVO =
-            new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(),
-                cmd.getCounterParamList(), cmd.getDestroyVmGraceperiod(), autoscaleUserId);
-
-        if (cmd.getDisplay() != null) {
-            profileVO.setDisplay(cmd.getDisplay());
-        }
-
-        profileVO = checkValidityAndPersist(profileVO);
-        s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId());
-
-        return profileVO;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE, eventDescription = "updating autoscale vm profile")
-    public AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd) {
-        Long profileId = cmd.getId();
-        Long templateId = cmd.getTemplateId();
-        Long autoscaleUserId = cmd.getAutoscaleUserId();
-        Map counterParamList = cmd.getCounterParamList();
-
-        Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod();
-
-        AutoScaleVmProfileVO vmProfile = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao);
-
-        boolean physicalParameterUpdate = (templateId != null || autoscaleUserId != null || counterParamList != null || destroyVmGraceperiod != null);
-
-        if (templateId != null) {
-            vmProfile.setTemplateId(templateId);
-        }
-
-        if (autoscaleUserId != null) {
-            vmProfile.setAutoscaleUserId(autoscaleUserId);
-        }
-
-        if (counterParamList != null) {
-            vmProfile.setCounterParamsForUpdate(counterParamList);
-        }
-
-        if (destroyVmGraceperiod != null) {
-            vmProfile.setDestroyVmGraceperiod(destroyVmGraceperiod);
-        }
-
-        if (cmd.getCustomId() != null) {
-            vmProfile.setUuid(cmd.getCustomId());
-        }
-
-        if (cmd.getDisplay() != null) {
-            vmProfile.setDisplay(cmd.getDisplay());
-        }
-
-        List<AutoScaleVmGroupVO> vmGroupList = _autoScaleVmGroupDao.listByAll(null, profileId);
-        for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) {
-            if (physicalParameterUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
-                throw new InvalidParameterValueException("The AutoScale Vm Profile can be updated only if the Vm Group it is associated with is disabled in state");
-            }
-        }
-
-        vmProfile = checkValidityAndPersist(vmProfile);
-        s_logger.info("Updated Auto Scale Vm Profile id:" + vmProfile.getId());
-
-        return vmProfile;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE, eventDescription = "deleting autoscale vm profile")
-    public boolean deleteAutoScaleVmProfile(long id) {
-        /* Check if entity is in database */
-        getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Profile", id, _autoScaleVmProfileDao);
-        if (_autoScaleVmGroupDao.isProfileInUse(id)) {
-            throw new InvalidParameterValueException("Cannot delete AutoScale Vm Profile when it is in use by one more vm groups");
-        }
-        boolean success = _autoScaleVmProfileDao.remove(id);
-        if (success) {
-            s_logger.info("Successfully deleted AutoScale Vm Profile with Id: " + id);
-        }
-        return success;
-    }
-
-    @Override
-    public List<? extends AutoScaleVmProfile> listAutoScaleVmProfiles(ListAutoScaleVmProfilesCmd cmd) {
-        Long id = cmd.getId();
-        Long templateId = cmd.getTemplateId();
-        String otherDeployParams = cmd.getOtherDeployParams();
-        Long serviceOffId = cmd.getServiceOfferingId();
-        Long zoneId = cmd.getZoneId();
-        Boolean display = cmd.getDisplay();
-
-        SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScaleVmProfileVO> sb = searchWrapper.getSearchBuilder();
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
-        sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ);
-        sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE);
-        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
-        SearchCriteria<AutoScaleVmProfileVO> sc = searchWrapper.buildSearchCriteria();
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-        if (templateId != null) {
-            sc.setParameters("templateId", templateId);
-        }
-        if (otherDeployParams != null) {
-            sc.addAnd("otherDeployParams", SearchCriteria.Op.LIKE, "%" + otherDeployParams + "%");
-        }
-
-        if (serviceOffId != null) {
-            sc.setParameters("serviceOfferingId", serviceOffId);
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("zoneId", zoneId);
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        return searchWrapper.search();
-    }
-
-    @DB
-    protected AutoScalePolicyVO checkValidityAndPersist(final AutoScalePolicyVO autoScalePolicyVOFinal, final List<Long> conditionIds) {
-        final int duration = autoScalePolicyVOFinal.getDuration();
-        final int quietTime = autoScalePolicyVOFinal.getQuietTime();
-
-        if (duration < 0) {
-            throw new InvalidParameterValueException("duration is an invalid value: " + duration);
-        }
-
-        if (quietTime < 0) {
-            throw new InvalidParameterValueException("quiettime is an invalid value: " + quietTime);
-        }
-
-        return Transaction.execute(new TransactionCallback<AutoScalePolicyVO>() {
-            @Override
-            public AutoScalePolicyVO doInTransaction(TransactionStatus status) {
-                AutoScalePolicyVO autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVOFinal);
-
-                if (conditionIds != null) {
-                    SearchBuilder<ConditionVO> conditionsSearch = _conditionDao.createSearchBuilder();
-                    conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN);
-                    conditionsSearch.done();
-                    SearchCriteria<ConditionVO> sc = conditionsSearch.create();
-
-                    sc.setParameters("ids", conditionIds.toArray(new Object[0]));
-                    List<ConditionVO> conditions = _conditionDao.search(sc, null);
-
-                    ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]);
-                    sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO;
-                    _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
-
-                    if (conditionIds.size() != conditions.size()) {
-                        // TODO report the condition id which could not be found
-                        throw new InvalidParameterValueException("Unable to find the condition specified");
-                    }
-
-                    ArrayList<Long> counterIds = new ArrayList<Long>();
-                    for (ConditionVO condition : conditions) {
-                        if (counterIds.contains(condition.getCounterid())) {
-                            throw new InvalidParameterValueException(
-                                "atleast two conditions in the conditionids have the same counter. It is not right to apply two different conditions for the same counter");
-                        }
-                        counterIds.add(condition.getCounterid());
-                    }
-
-                    /* For update case remove the existing mappings and create fresh ones */
-                    _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(autoScalePolicyVO.getId());
-
-                    for (Long conditionId : conditionIds) {
-                        AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId);
-                        _autoScalePolicyConditionMapDao.persist(policyConditionMapVO);
-                    }
-                }
-
-                return autoScalePolicyVO;
-            }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_CREATE, eventDescription = "creating autoscale policy", create = true)
-    public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd cmd) {
-
-        int duration = cmd.getDuration();
-        Integer quietTime = cmd.getQuietTime();
-        String action = cmd.getAction();
-
-        if (quietTime == null) {
-            quietTime = NetUtils.DEFAULT_AUTOSCALE_POLICY_QUIET_TIME;
-        }
-
-        action = action.toLowerCase();
-        if (!NetUtils.isValidAutoScaleAction(action)) {
-            throw new InvalidParameterValueException("action is invalid, only 'scaleup' and 'scaledown' is supported");
-        }
-
-        AutoScalePolicyVO policyVO = new AutoScalePolicyVO(cmd.getDomainId(), cmd.getAccountId(), duration, quietTime, null, action);
-
-        policyVO = checkValidityAndPersist(policyVO, cmd.getConditionIds());
-        s_logger.info("Successfully created AutoScale Policy with Id: " + policyVO.getId());
-        return policyVO;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_DELETE, eventDescription = "deleting autoscale policy")
-    public boolean deleteAutoScalePolicy(final long id) {
-        /* Check if entity is in database */
-        getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Policy", id, _autoScalePolicyDao);
-
-        if (_autoScaleVmGroupPolicyMapDao.isAutoScalePolicyInUse(id)) {
-            throw new InvalidParameterValueException("Cannot delete AutoScale Policy when it is in use by one or more AutoScale Vm Groups");
-        }
-
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                boolean success = true;
-                success = _autoScalePolicyDao.remove(id);
-                if (!success) {
-                    s_logger.warn("Failed to remove AutoScale Policy db object");
-                    return false;
-                }
-                success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id);
-                if (!success) {
-                    s_logger.warn("Failed to remove AutoScale Policy Condition mappings");
-                    return false;
-                }
-                s_logger.info("Successfully deleted autoscale policy id : " + id);
-
-                return success;
-            }
-        });
-    }
-
-    public void checkCallerAccess(String accountName, Long domainId) {
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountDao.findActiveAccount(accountName, domainId);
-        if (owner == null) {
-            List<String> idList = new ArrayList<String>();
-            idList.add(ApiDBUtils.findDomainById(domainId).getUuid());
-            throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain with specifed domainId");
-        }
-        _accountMgr.checkAccess(caller, null, false, owner);
-    }
-
-    private class SearchWrapper<VO extends ControlledEntity> {
-        GenericDao<VO, Long> dao;
-        SearchBuilder<VO> searchBuilder;
-        SearchCriteria<VO> searchCriteria;
-        Long domainId;
-        boolean isRecursive;
-        List<Long> permittedAccounts = new ArrayList<Long>();
-        ListProjectResourcesCriteria listProjectResourcesCriteria;
-        Filter searchFilter;
-
-        public SearchWrapper(GenericDao<VO, Long> dao, Class<VO> entityClass, BaseListAccountResourcesCmd cmd, Long id)
-        {
-            this.dao = dao;
-            this.searchBuilder = dao.createSearchBuilder();
-            domainId = cmd.getDomainId();
-            String accountName = cmd.getAccountName();
-            isRecursive = cmd.isRecursive();
-            boolean listAll = cmd.listAll();
-            long startIndex = cmd.getStartIndex();
-            long pageSizeVal = cmd.getPageSizeVal();
-            Account caller = CallContext.current().getCallingAccount();
-
-            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
-                    ListProjectResourcesCriteria>(domainId, isRecursive, null);
-            _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject,
-                    listAll, false);
-            domainId = domainIdRecursiveListProject.first();
-            isRecursive = domainIdRecursiveListProject.second();
-            ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-            _accountMgr.buildACLSearchBuilder(searchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            searchFilter = new Filter(entityClass, "id", false, startIndex, pageSizeVal);
-        }
-
-        public SearchBuilder<VO> getSearchBuilder() {
-            return searchBuilder;
-        }
-
-        public SearchCriteria<VO> buildSearchCriteria() {
-            searchCriteria = searchBuilder.create();
-            _accountMgr.buildACLSearchCriteria(searchCriteria, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            return searchCriteria;
-        }
-
-        public List<VO> search() {
-            return dao.search(searchCriteria, searchFilter);
-        }
-    }
-
-    @Override
-    public List<? extends AutoScalePolicy> listAutoScalePolicies(ListAutoScalePoliciesCmd cmd) {
-        SearchWrapper<AutoScalePolicyVO> searchWrapper = new SearchWrapper<AutoScalePolicyVO>(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScalePolicyVO> sb = searchWrapper.getSearchBuilder();
-        Long id = cmd.getId();
-        Long conditionId = cmd.getConditionId();
-        String action = cmd.getAction();
-        Long vmGroupId = cmd.getVmGroupId();
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("action", sb.entity().getAction(), SearchCriteria.Op.EQ);
-
-        if (conditionId != null) {
-            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
-            asPolicyConditionSearch.and("conditionId", asPolicyConditionSearch.entity().getConditionId(), SearchCriteria.Op.EQ);
-            sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (vmGroupId != null) {
-            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
-            asVmGroupPolicySearch.and("vmGroupId", asVmGroupPolicySearch.entity().getVmGroupId(), SearchCriteria.Op.EQ);
-            sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<AutoScalePolicyVO> sc = searchWrapper.buildSearchCriteria();
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (action != null) {
-            sc.setParameters("action", action);
-        }
-
-        if (conditionId != null) {
-            sc.setJoinParameters("asPolicyConditionSearch", "conditionId", conditionId);
-        }
-
-        if (vmGroupId != null) {
-            sc.setJoinParameters("asVmGroupPolicySearch", "vmGroupId", vmGroupId);
-        }
-
-        return searchWrapper.search();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_UPDATE, eventDescription = "updating autoscale policy")
-    public AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd) {
-        Long policyId = cmd.getId();
-        Integer duration = cmd.getDuration();
-        Integer quietTime = cmd.getQuietTime();
-        List<Long> conditionIds = cmd.getConditionIds();
-        AutoScalePolicyVO policy = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Policy", policyId, _autoScalePolicyDao);
-
-        if (duration != null) {
-            policy.setDuration(duration);
-        }
-
-        if (quietTime != null) {
-            policy.setQuietTime(quietTime);
-        }
-
-        List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyList = _autoScaleVmGroupPolicyMapDao.listByPolicyId(policyId);
-        for (AutoScaleVmGroupPolicyMapVO vmGroupPolicy : vmGroupPolicyList) {
-            AutoScaleVmGroupVO vmGroupVO = _autoScaleVmGroupDao.findById(vmGroupPolicy.getVmGroupId());
-            if (vmGroupVO == null) {
-                s_logger.warn("Stale database entry! There is an entry in VmGroupPolicyMap but the vmGroup is missing:" + vmGroupPolicy.getVmGroupId());
-
-                continue;
-
-            }
-            if (!vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
-                throw new InvalidParameterValueException("The AutoScale Policy can be updated only if the Vm Group it is associated with is disabled in state");
-            }
-            if (policy.getDuration() < vmGroupVO.getInterval()) {
-                throw new InvalidParameterValueException("duration is less than the associated AutoScaleVmGroup's interval");
-            }
-        }
-
-        policy = checkValidityAndPersist(policy, conditionIds);
-        s_logger.info("Successfully updated Auto Scale Policy id:" + policyId);
-        return policy;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", create = true)
-    public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) {
-        int minMembers = cmd.getMinMembers();
-        int maxMembers = cmd.getMaxMembers();
-        Integer interval = cmd.getInterval();
-        Boolean forDisplay = cmd.getDisplay();
-
-        if (interval == null) {
-            interval = NetUtils.DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME;
-        }
-
-        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, cmd.getLbRuleId(), _lbDao);
-
-        Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId();
-
-        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancer.getId())) {
-            throw new InvalidParameterValueException("an AutoScaleVmGroup is already attached to the lb rule, the existing vm group has to be first deleted");
-        }
-
-        if (_lb2VmMapDao.isVmAttachedToLoadBalancer(loadBalancer.getId())) {
-            throw new InvalidParameterValueException(
-                "there are Vms already bound to the specified LoadBalancing Rule. User bound Vms and AutoScaled Vm Group cannot co-exist on a Load Balancing Rule");
-        }
-
-        AutoScaleVmGroupVO vmGroupVO = new AutoScaleVmGroupVO(cmd.getLbRuleId(), zoneId, loadBalancer.getDomainId(), loadBalancer.getAccountId(), minMembers, maxMembers,
-            loadBalancer.getDefaultPortStart(), interval, null, cmd.getProfileId(), AutoScaleVmGroup.State_New);
-
-        if (forDisplay != null) {
-            vmGroupVO.setDisplay(forDisplay);
-        }
-
-        vmGroupVO = checkValidityAndPersist(vmGroupVO, cmd.getScaleUpPolicyIds(), cmd.getScaleDownPolicyIds());
-        s_logger.info("Successfully created Autoscale Vm Group with Id: " + vmGroupVO.getId());
-
-        return vmGroupVO;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", async = true)
-    public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) throws ResourceUnavailableException {
-        return configureAutoScaleVmGroup(cmd.getEntityId(), AutoScaleVmGroup.State_New);
-    }
-
-    public boolean isLoadBalancerBasedAutoScaleVmGroup(AutoScaleVmGroup vmGroup) {
-        return vmGroup.getLoadBalancerId() != null;
-    }
-
-    private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException {
-        AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
-
-        if (isLoadBalancerBasedAutoScaleVmGroup(vmGroup)) {
-            try {
-                return _lbRulesMgr.configureLbAutoScaleVmGroup(vmGroupid, currentState);
-            } catch (ResourceUnavailableException re) {
-                throw re;
-            } catch (Exception e) {
-                s_logger.warn("Exception during configureLbAutoScaleVmGroup in lb rules manager", e);
-                return false;
-            }
-        }
-
-        // This should never happen, because today loadbalancerruleid is manadatory for AutoScaleVmGroup.
-        throw new InvalidParameterValueException("Only LoadBalancer based AutoScale is supported");
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group", async = true)
-    public boolean deleteAutoScaleVmGroup(final long id) {
-        AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
-
-        if (autoScaleVmGroupVO.getState().equals(AutoScaleVmGroup.State_New)) {
-            /* This condition is for handling failures during creation command */
-            return _autoScaleVmGroupDao.remove(id);
-        }
-        String bakupState = autoScaleVmGroupVO.getState();
-        autoScaleVmGroupVO.setState(AutoScaleVmGroup.State_Revoke);
-        _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
-        boolean success = false;
-
-        try {
-            success = configureAutoScaleVmGroup(id, bakupState);
-        } catch (ResourceUnavailableException e) {
-            autoScaleVmGroupVO.setState(bakupState);
-            _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
-        } finally {
-            if (!success) {
-                s_logger.warn("Could not delete AutoScale Vm Group id : " + id);
-                return false;
-            }
-        }
-
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                boolean success = _autoScaleVmGroupDao.remove(id);
-
-                if (!success) {
-                    s_logger.warn("Failed to remove AutoScale Group db object");
-                    return false;
-                }
-
-                success = _autoScaleVmGroupPolicyMapDao.removeByGroupId(id);
-                if (!success) {
-                    s_logger.warn("Failed to remove AutoScale Group Policy mappings");
-                    return false;
-                }
-
-                s_logger.info("Successfully deleted autoscale vm group id : " + id);
-                return success; // Successfull
-            }
-        });
-
-    }
-
-    @Override
-    public List<? extends AutoScaleVmGroup> listAutoScaleVmGroups(ListAutoScaleVmGroupsCmd cmd) {
-        Long id = cmd.getId();
-        Long policyId = cmd.getPolicyId();
-        Long loadBalancerId = cmd.getLoadBalancerId();
-        Long profileId = cmd.getProfileId();
-        Long zoneId = cmd.getZoneId();
-        Boolean forDisplay = cmd.getDisplay();
-
-        SearchWrapper<AutoScaleVmGroupVO> searchWrapper = new SearchWrapper<AutoScaleVmGroupVO>(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId());
-        SearchBuilder<AutoScaleVmGroupVO> sb = searchWrapper.getSearchBuilder();
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("loadBalancerId", sb.entity().getLoadBalancerId(), SearchCriteria.Op.EQ);
-        sb.and("profileId", sb.entity().getProfileId(), SearchCriteria.Op.EQ);
-        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
-
-        if (policyId != null) {
-            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
-            asVmGroupPolicySearch.and("policyId", asVmGroupPolicySearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
-            sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getVmGroupId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<AutoScaleVmGroupVO> sc = searchWrapper.buildSearchCriteria();
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-        if (loadBalancerId != null) {
-            sc.setParameters("loadBalancerId", loadBalancerId);
-        }
-        if (profileId != null) {
-            sc.setParameters("profileId", profileId);
-        }
-        if (zoneId != null) {
-            sc.setParameters("zoneId", zoneId);
-        }
-        if (policyId != null) {
-            sc.setJoinParameters("asVmGroupPolicySearch", "policyId", policyId);
-        }
-        if (forDisplay != null) {
-            sc.setParameters("display", forDisplay);
-        }
-        return searchWrapper.search();
-    }
-
-    @DB
-    protected AutoScaleVmGroupVO checkValidityAndPersist(final AutoScaleVmGroupVO vmGroup, final List<Long> passedScaleUpPolicyIds,
-        final List<Long> passedScaleDownPolicyIds) {
-        int minMembers = vmGroup.getMinMembers();
-        int maxMembers = vmGroup.getMaxMembers();
-        int interval = vmGroup.getInterval();
-        List<Counter> counters = new ArrayList<Counter>();
-        List<AutoScalePolicyVO> policies = new ArrayList<AutoScalePolicyVO>();
-        final List<Long> policyIds = new ArrayList<Long>();
-        List<Long> currentScaleUpPolicyIds = new ArrayList<Long>();
-        List<Long> currentScaleDownPolicyIds = new ArrayList<Long>();
-        if (vmGroup.getCreated() != null) {
-            ApiDBUtils.getAutoScaleVmGroupPolicyIds(vmGroup.getId(), currentScaleUpPolicyIds, currentScaleDownPolicyIds);
-        }
-
-        if (minMembers < 0) {
-            throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " is an invalid value: " + minMembers);
-        }
-
-        if (maxMembers < 0) {
-            throw new InvalidParameterValueException(ApiConstants.MAX_MEMBERS + " is an invalid value: " + maxMembers);
-        }
-
-        if (minMembers > maxMembers) {
-            throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " (" + minMembers + ")cannot be greater than " + ApiConstants.MAX_MEMBERS + " (" +
-                maxMembers + ")");
-        }
-
-        if (interval < 0) {
-            throw new InvalidParameterValueException("interval is an invalid value: " + interval);
-        }
-
-        if (passedScaleUpPolicyIds != null) {
-            policies.addAll(getAutoScalePolicies("scaleuppolicyid", passedScaleUpPolicyIds, counters, interval, true));
-            policyIds.addAll(passedScaleUpPolicyIds);
-        } else {
-            // Run the interval check for existing policies
-            getAutoScalePolicies("scaleuppolicyid", currentScaleUpPolicyIds, counters, interval, true);
-            policyIds.addAll(currentScaleUpPolicyIds);
-        }
-
-        if (passedScaleDownPolicyIds != null) {
-            policies.addAll(getAutoScalePolicies("scaledownpolicyid", passedScaleDownPolicyIds, counters, interval, false));
-            policyIds.addAll(passedScaleDownPolicyIds);
-        } else {
-            // Run the interval check for existing policies
-            getAutoScalePolicies("scaledownpolicyid", currentScaleDownPolicyIds, counters, interval, false);
-            policyIds.addAll(currentScaleDownPolicyIds);
-        }
-        AutoScaleVmProfileVO profileVO =
-            getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.VMPROFILE_ID, vmGroup.getProfileId(), _autoScaleVmProfileDao);
-
-        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, vmGroup.getLoadBalancerId(), _lbDao);
-        validateAutoScaleCounters(loadBalancer.getNetworkId(), counters, profileVO.getCounterParams());
-
-        ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]);
-        sameOwnerEntities[sameOwnerEntities.length - 2] = loadBalancer;
-        sameOwnerEntities[sameOwnerEntities.length - 1] = profileVO;
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
-
-        return Transaction.execute(new TransactionCallback<AutoScaleVmGroupVO>() {
-            @Override
-            public AutoScaleVmGroupVO doInTransaction(TransactionStatus status) {
-                AutoScaleVmGroupVO vmGroupNew = _autoScaleVmGroupDao.persist(vmGroup);
-
-                if (passedScaleUpPolicyIds != null || passedScaleDownPolicyIds != null) {
-                    _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroupNew.getId());
-
-                    for (Long policyId : policyIds) {
-                        _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroupNew.getId(), policyId));
-                    }
-                }
-
-                return vmGroupNew;
-            }
-        });
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group", async = true)
-    public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) {
-        Long vmGroupId = cmd.getId();
-        Integer minMembers = cmd.getMinMembers();
-        Integer maxMembers = cmd.getMaxMembers();
-        Integer interval = cmd.getInterval();
-        Boolean forDisplay = cmd.getDisplay();
-
-        List<Long> scaleUpPolicyIds = cmd.getScaleUpPolicyIds();
-        List<Long> scaleDownPolicyIds = cmd.getScaleDownPolicyIds();
-
-        AutoScaleVmGroupVO vmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", vmGroupId, _autoScaleVmGroupDao);
-
-        boolean physicalParametersUpdate = (minMembers != null || maxMembers != null || interval != null);
-
-        if (physicalParametersUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
-            throw new InvalidParameterValueException("An AutoScale Vm Group can be updated with minMembers/maxMembers/Interval only when it is in disabled state");
-        }
-
-        if (minMembers != null) {
-            vmGroupVO.setMinMembers(minMembers);
-        }
-
-        if (maxMembers != null) {
-            vmGroupVO.setMaxMembers(maxMembers);
-        }
-
-        if (maxMembers != null) {
-            vmGroupVO.setInterval(interval);
-        }
-
-        if (cmd.getCustomId() != null) {
-            vmGroupVO.setUuid(cmd.getCustomId());
-        }
-
-        if (forDisplay != null) {
-            vmGroupVO.setDisplay(forDisplay);
-        }
-
-        vmGroupVO = checkValidityAndPersist(vmGroupVO, scaleUpPolicyIds, scaleDownPolicyIds);
-        if (vmGroupVO != null) {
-            s_logger.debug("Updated Auto Scale VmGroup id:" + vmGroupId);
-            return vmGroupVO;
-        } else
-            return null;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group", async = true)
-    public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) {
-        AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
-        boolean success = false;
-        if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Disabled)) {
-            throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Disabled state can be enabled.");
-        }
-
-        try {
-            vmGroup.setState(AutoScaleVmGroup.State_Enabled);
-            vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
-            success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Disabled);
-        } catch (ResourceUnavailableException e) {
-            vmGroup.setState(AutoScaleVmGroup.State_Disabled);
-            _autoScaleVmGroupDao.persist(vmGroup);
-        } finally {
-            if (!success) {
-                s_logger.warn("Failed to enable AutoScale Vm Group id : " + id);
-                return null;
-            }
-            s_logger.info("Successfully enabled AutoScale Vm Group with Id:" + id);
-        }
-        return vmGroup;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group", async = true)
-    @DB
-    public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) {
-        AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
-        boolean success = false;
-        if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Enabled)) {
-            throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Enabled state can be disabled.");
-        }
-
-        try {
-            vmGroup.setState(AutoScaleVmGroup.State_Disabled);
-            vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
-            success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Enabled);
-        } catch (ResourceUnavailableException e) {
-            vmGroup.setState(AutoScaleVmGroup.State_Enabled);
-            _autoScaleVmGroupDao.persist(vmGroup);
-        } finally {
-            if (!success) {
-                s_logger.warn("Failed to disable AutoScale Vm Group id : " + id);
-                return null;
-            }
-            s_logger.info("Successfully disabled AutoScale Vm Group with Id:" + id);
-        }
-        return vmGroup;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_COUNTER_CREATE, eventDescription = "Counter", create = true)
-    @DB
-    public Counter createCounter(CreateCounterCmd cmd) {
-        String source = cmd.getSource().toLowerCase();
-        String name = cmd.getName();
-        Counter.Source src;
-        // Validate Source
-        try {
-            src = Counter.Source.valueOf(source);
-        } catch (Exception ex) {
-            throw new InvalidParameterValueException("The Source " + source + " does not exist; Unable to create Counter");
-        }
-
-        CounterVO counter = null;
-
-        s_logger.debug("Adding Counter " + name);
-        counter = _counterDao.persist(new CounterVO(src, name, cmd.getValue()));
-
-        CallContext.current().setEventDetails(" Id: " + counter.getId() + " Name: " + name);
-        return counter;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CONDITION_CREATE, eventDescription = "Condition", create = true)
-    public Condition createCondition(CreateConditionCmd cmd) {
-        checkCallerAccess(cmd.getAccountName(), cmd.getDomainId());
-        String opr = cmd.getRelationalOperator().toUpperCase();
-        long cid = cmd.getCounterId();
-        long threshold = cmd.getThreshold();
-        Condition.Operator op;
-        // Validate Relational Operator
-        try {
-            op = Condition.Operator.valueOf(opr);
-        } catch (IllegalArgumentException ex) {
-            throw new InvalidParameterValueException("The Operator " + opr + " does not exist; Unable to create Condition.");
-        }
-        // TODO - Validate threshold
-
-        CounterVO counter = _counterDao.findById(cid);
-
-        if (counter == null) {
-            throw new InvalidParameterValueException("Unable to find counter");
-        }
-        ConditionVO condition = null;
-
-        condition = _conditionDao.persist(new ConditionVO(cid, threshold, cmd.getEntityOwnerId(), cmd.getDomainId(), op));
-        s_logger.info("Successfully created condition with Id: " + condition.getId());
-
-        CallContext.current().setEventDetails(" Id: " + condition.getId());
-        return condition;
-    }
-
-    @Override
-    public List<? extends Counter> listCounters(ListCountersCmd cmd) {
-        String name = cmd.getName();
-        Long id = cmd.getId();
-        String source = cmd.getSource();
-        if (source != null)
-            source = source.toLowerCase();
-
-        Filter searchFilter = new Filter(CounterVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        List<CounterVO> counters = _counterDao.listCounters(id, name, source, cmd.getKeyword(), searchFilter);
-
-        return counters;
-    }
-
-    @Override
-    public List<? extends Condition> listConditions(ListConditionsCmd cmd) {
-        Long id = cmd.getId();
-        Long counterId = cmd.getCounterId();
-        Long policyId = cmd.getPolicyId();
-        SearchWrapper<ConditionVO> searchWrapper = new SearchWrapper<ConditionVO>(_conditionDao, ConditionVO.class, cmd, cmd.getId());
-        SearchBuilder<ConditionVO> sb = searchWrapper.getSearchBuilder();
-        if (policyId != null) {
-            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
-            asPolicyConditionSearch.and("policyId", asPolicyConditionSearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
-            sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getConditionId(),
-                JoinBuilder.JoinType.INNER);
-        }
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("counterId", sb.entity().getCounterid(), SearchCriteria.Op.EQ);
-
-        // now set the SC criteria...
-        SearchCriteria<ConditionVO> sc = searchWrapper.buildSearchCriteria();
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (counterId != null) {
-            sc.setParameters("counterId", counterId);
-        }
-
-        if (policyId != null) {
-            sc.setJoinParameters("asPolicyConditionSearch", "policyId", policyId);
-        }
-
-        return searchWrapper.search();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_COUNTER_DELETE, eventDescription = "counter")
-    public boolean deleteCounter(long counterId) throws ResourceInUseException {
-        // Verify Counter id
-        CounterVO counter = _counterDao.findById(counterId);
-        if (counter == null) {
-            throw new InvalidParameterValueException("Unable to find Counter");
-        }
-
-        // Verify if it is used in any Condition
-
-        ConditionVO condition = _conditionDao.findByCounterId(counterId);
-        if (condition != null) {
-            s_logger.info("Cannot delete counter " + counter.getName() + " as it is being used in a condition.");
-            throw new ResourceInUseException("Counter is in use.");
-        }
-
-        boolean success = _counterDao.remove(counterId);
-        if (success) {
-            s_logger.info("Successfully deleted counter with Id: " + counterId);
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CONDITION_DELETE, eventDescription = "condition")
-    public boolean deleteCondition(long conditionId) throws ResourceInUseException {
-        /* Check if entity is in database */
-        ConditionVO condition = getEntityInDatabase(CallContext.current().getCallingAccount(), "Condition", conditionId, _conditionDao);
-        if (condition == null) {
-            throw new InvalidParameterValueException("Unable to find Condition");
-        }
-
-        // Verify if condition is used in any autoscale policy
-        if (_autoScalePolicyConditionMapDao.isConditionInUse(conditionId)) {
-            s_logger.info("Cannot delete condition " + conditionId + " as it is being used in a condition.");
-            throw new ResourceInUseException("Cannot delete Condition when it is in use by one or more AutoScale Policies.");
-        }
-        boolean success = _conditionDao.remove(conditionId);
-        if (success) {
-            s_logger.info("Successfully deleted condition " + condition.getId());
-        }
-        return success;
-    }
-
-    @Override
-    public void cleanUpAutoScaleResources(Long accountId) {
-        // cleans Autoscale VmProfiles, AutoScale Policies and Conditions belonging to an account
-        int count = 0;
-        count = _autoScaleVmProfileDao.removeByAccountId(accountId);
-        if (count > 0) {
-            s_logger.debug("Deleted " + count + " AutoScale Vm Profile for account Id: " + accountId);
-        }
-        count = _autoScalePolicyDao.removeByAccountId(accountId);
-        if (count > 0) {
-            s_logger.debug("Deleted " + count + " AutoScale Policies for account Id: " + accountId);
-        }
-        count = _conditionDao.removeByAccountId(accountId);
-        if (count > 0) {
-            s_logger.debug("Deleted " + count + " Conditions for account Id: " + accountId);
-        }
-    }
-
-    private boolean checkConditionUp(AutoScaleVmGroupVO asGroup, Integer numVm) {
-        // check maximum
-        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
-        Integer maxVm = asGroup.getMaxMembers();
-        if (currentVM + numVm > maxVm) {
-            s_logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
-            return false;
-        }
-        return true;
-    }
-
-    private boolean checkConditionDown(AutoScaleVmGroupVO asGroup) {
-        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
-        Integer minVm = asGroup.getMinMembers();
-        if (currentVM - 1 < minVm) {
-            s_logger.warn("number of VM will less than the minimum in this group if scaling down, so do nothing more");
-            return false;
-        }
-        return true;
-    }
-
-    private long createNewVM(AutoScaleVmGroupVO asGroup) {
-        AutoScaleVmProfileVO profileVo = _autoScaleVmProfileDao.findById(asGroup.getProfileId());
-        long templateId = profileVo.getTemplateId();
-        long serviceOfferingId = profileVo.getServiceOfferingId();
-        if (templateId == -1) {
-            return -1;
-        }
-        // create new VM into DB
-        try {
-            //Verify that all objects exist before passing them to the service
-            Account owner = _accountService.getActiveAccountById(profileVo.getAccountId());
-
-            DataCenter zone = _entityMgr.findById(DataCenter.class, profileVo.getZoneId());
-            if (zone == null) {
-                throw new InvalidParameterValueException("Unable to find zone by id=" + profileVo.getZoneId());
-            }
-
-            ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-            if (serviceOffering == null) {
-                throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-            }
-
-            VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
-            // Make sure a valid template ID was specified
-            if (template == null) {
-                throw new InvalidParameterValueException("Unable to use template " + templateId);
-            }
-
-            if (!zone.isLocalStorageEnabled()) {
-                if (serviceOffering.getUseLocalStorage()) {
-                    throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
-                }
-            }
-
-            UserVm vm = null;
-            IpAddresses addrs = new IpAddresses(null, null);
-            if (zone.getNetworkType() == NetworkType.Basic) {
-                vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
-                    getCurrentTimeStampString(),
-                    "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null,
-                    null, true, null, null, null, null, null, null);
-            } else {
-                if (zone.isSecurityGroupEnabled()) {
-                    vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null,
-                        owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
-                        "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null,
-                        null, null, true, null, null, null, null, null, null);
-
-                } else {
-                    vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
-                        getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
-                        null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null);
-
-                }
-            }
-
-            if (vm != null) {
-                return vm.getId();
-            } else {
-                return -1;
-            }
-        } catch (InsufficientCapacityException ex) {
-            s_logger.info(ex);
-            s_logger.trace(ex.getMessage(), ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (ResourceAllocationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
-        }
-    }
-
-    private String getCurrentTimeStampString() {
-        Date current = new Date();
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
-
-        return sdf.format(current);
-    }
-
-    private boolean startNewVM(long vmId) {
-        try {
-            CallContext.current().setEventDetails("Vm Id: " + vmId);
-            _userVmManager.startVirtualMachine(vmId, null, null, null);
-        } catch (final ResourceUnavailableException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
-        } catch (ConcurrentOperationException ex) {
-            s_logger.warn("Exception: ", ex);
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
-        } catch (InsufficientCapacityException ex) {
-            StringBuilder message = new StringBuilder(ex.getMessage());
-            if (ex instanceof InsufficientServerCapacityException) {
-                if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
-                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
-                }
-            }
-            s_logger.info(ex);
-            s_logger.info(message.toString(), ex);
-            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
-        }
-        return true;
-    }
-
-    private boolean assignLBruleToNewVm(long vmId, AutoScaleVmGroupVO asGroup) {
-        List<Long> lstVmId = new ArrayList<Long>();
-        long lbId = asGroup.getLoadBalancerId();
-
-        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
-        if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
-            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
-                long instanceId = LbVmMapVo.getInstanceId();
-                if (instanceId == vmId) {
-                    s_logger.warn("the new VM is already mapped to LB rule. What's wrong?");
-                    return true;
-                }
-            }
-        }
-        lstVmId.add(new Long(vmId));
-        return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId, new HashMap<Long, List<String>>());
-
-    }
-
-    private long removeLBrule(AutoScaleVmGroupVO asGroup) {
-        long lbId = asGroup.getLoadBalancerId();
-        long instanceId = -1;
-        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
-        if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
-            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
-                instanceId = LbVmMapVo.getInstanceId();
-            }
-        }
-        // take last VM out of the list
-        List<Long> lstVmId = new ArrayList<Long>();
-        if (instanceId != -1)
-            lstVmId.add(instanceId);
-        if (_loadBalancingRulesService.removeFromLoadBalancer(lbId, lstVmId, new HashMap<Long, List<String>>()))
-            return instanceId;
-        else
-            return -1;
-    }
-
-    @Override
-    public void doScaleUp(long groupId, Integer numVm) {
-        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
-        if (asGroup == null) {
-            s_logger.error("Can not find the groupid " + groupId + " for scaling up");
-            return;
-        }
-        if (!checkConditionUp(asGroup, numVm)) {
-            return;
-        }
-        for (int i = 0; i < numVm; i++) {
-            long vmId = createNewVM(asGroup);
-            if (vmId == -1) {
-                s_logger.error("Can not deploy new VM for scaling up in the group "
-                    + asGroup.getId() + ". Waiting for next round");
-                break;
-            }
-            if (startNewVM(vmId)) {
-                if (assignLBruleToNewVm(vmId, asGroup)) {
-                    // persist to DB
-                    AutoScaleVmGroupVmMapVO GroupVmVO = new AutoScaleVmGroupVmMapVO(
-                        asGroup.getId(), vmId);
-                    _autoScaleVmGroupVmMapDao.persist(GroupVmVO);
-                    // update last_quiettime
-                    List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao
-                        .listByVmGroupId(groupId);
-                    for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
-                        AutoScalePolicyVO vo = _autoScalePolicyDao
-                            .findById(GroupPolicyVO.getPolicyId());
-                        if (vo.getAction().equals("scaleup")) {
-                            vo.setLastQuiteTime(new Date());
-                            _autoScalePolicyDao.persist(vo);
-                            break;
-                        }
-                    }
-                } else {
-                    s_logger.error("Can not assign LB rule for this new VM");
-                    break;
-                }
-            } else {
-                s_logger.error("Can not deploy new VM for scaling up in the group "
-                    + asGroup.getId() + ". Waiting for next round");
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void doScaleDown(final long groupId) {
-        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
-        if (asGroup == null) {
-            s_logger.error("Can not find the groupid " + groupId + " for scaling up");
-            return;
-        }
-        if (!checkConditionDown(asGroup)) {
-            return;
-        }
-        final long vmId = removeLBrule(asGroup);
-        if (vmId != -1) {
-            long profileId = asGroup.getProfileId();
-
-            // update group-vm mapping
-            _autoScaleVmGroupVmMapDao.remove(groupId, vmId);
-            // update last_quiettime
-            List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(groupId);
-            for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
-                AutoScalePolicyVO vo = _autoScalePolicyDao.findById(GroupPolicyVO.getPolicyId());
-                if (vo.getAction().equals("scaledown")) {
-                    vo.setLastQuiteTime(new Date());
-                    _autoScalePolicyDao.persist(vo);
-                    break;
-                }
-            }
-
-            // get destroyvmgrace param
-            AutoScaleVmProfileVO asProfile = _autoScaleVmProfileDao.findById(profileId);
-            Integer destroyVmGracePeriod = asProfile.getDestroyVmGraceperiod();
-            if (destroyVmGracePeriod >= 0) {
-                _executor.schedule(new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-
-                            _userVmManager.destroyVm(vmId, false);
-
-                        } catch (ResourceUnavailableException e) {
-                            e.printStackTrace();
-                        } catch (ConcurrentOperationException e) {
-                            e.printStackTrace();
-                        }
-                    }
-                }, destroyVmGracePeriod, TimeUnit.SECONDS);
-            }
-        } else {
-            s_logger.error("Can not remove LB rule for the VM being destroyed. Do nothing more.");
-        }
-    }
-
-}
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
deleted file mode 100644
index a854d14..0000000
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ /dev/null
@@ -1,1349 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.element;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-import org.cloud.network.router.deployment.RouterDeploymentDefinition;
-import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-
-import com.google.gson.Gson;
-
-import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
-import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
-import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.network.topology.NetworkTopology;
-import org.apache.cloudstack.network.topology.NetworkTopologyContext;
-
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkMigrationResponder;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.OvsProvider;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.VirtualRouterProvider.Type;
-import com.cloud.network.VpnUser;
-import com.cloud.network.as.AutoScaleCounter;
-import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailVO;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.dao.OvsProviderDao;
-import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.NetworkHelper;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.LbStickinessMethod;
-import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
-import com.cloud.network.rules.LoadBalancerContainer;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.UserVmDao;
-
-public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
-StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
-NetworkMigrationResponder, AggregatedCommandExecutor, RedundantResource, DnsServiceProvider {
-    private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
-    public static final AutoScaleCounterType AutoScaleCounterCpu = new AutoScaleCounterType("cpu");
-    public static final AutoScaleCounterType AutoScaleCounterMemory = new AutoScaleCounterType("memory");
-    protected static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
-
-    @Inject
-    NetworkDao _networksDao;
-    @Inject
-    NetworkModel _networkMdl;
-    @Inject
-    LoadBalancingRulesManager _lbMgr;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-
-    @Inject
-    VpcVirtualNetworkApplianceManager _routerMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    RulesManager _rulesMgr;
-    @Inject
-    UserVmManager _userVmMgr;
-
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    DomainRouterDao _routerDao;
-    @Inject
-    LoadBalancerDao _lbDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    VirtualRouterProviderDao _vrProviderDao;
-    @Inject
-    OvsProviderDao _ovsProviderDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    NetworkModel _networkModel;
-
-    @Inject
-    NetworkTopologyContext networkTopologyContext;
-
-    @Inject
-    NetworkDetailsDao _networkDetailsDao;
-
-    @Inject
-    protected RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder;
-
-    @Autowired
-    @Qualifier("networkHelper")
-    protected NetworkHelper _networkHelper;
-
-    protected boolean canHandle(final Network network, final Service service) {
-        final Long physicalNetworkId = _networkMdl.getPhysicalNetworkId(network);
-        if (physicalNetworkId == null) {
-            return false;
-        }
-
-        if (network.getVpcId() != null) {
-            return false;
-        }
-
-        if (!_networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())) {
-            return false;
-        }
-
-        if (service == null) {
-            if (!_networkMdl.isProviderForNetwork(getProvider(), network.getId())) {
-                s_logger.trace("Element " + getProvider().getName() + " is not a provider for the network " + network);
-                return false;
-            }
-        } else {
-            if (!_networkMdl.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
-                s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context)
-            throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
-
-        if (offering.isSystemOnly()) {
-            return false;
-        }
-
-        final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
-        params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
-
-        if (network.isRollingRestart()) {
-            params.put(VirtualMachineProfile.Param.RollingRestart, true);
-        }
-
-        final RouterDeploymentDefinition routerDeploymentDefinition =
-                routerDeploymentDefinitionBuilder.create()
-                .setGuestNetwork(network)
-                .setDeployDestination(dest)
-                .setAccountOwner(_accountMgr.getAccount(network.getAccountId()))
-                .setParams(params)
-                .build();
-
-        final List<DomainRouterVO> routers = routerDeploymentDefinition.deployVirtualRouter();
-
-        int expectedRouters = 1;
-        if (offering.getRedundantRouter() || network.isRollingRestart()) {
-            expectedRouters = 2;
-        }
-        if (routers == null || routers.size() < expectedRouters) {
-            //we might have a router which is already deployed and running.
-            //so check the no of routers in network currently.
-            List<DomainRouterVO> current_routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (current_routers.size() < 2) {
-                updateToFailedState(network);
-                throw new ResourceUnavailableException("Can't find all necessary running routers!", DataCenter.class, network.getDataCenterId());
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean prepare(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
-            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) {
-            return false;
-        }
-
-        if (!canHandle(network, null)) {
-            return false;
-        }
-
-        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if (offering.isSystemOnly()) {
-            return false;
-        }
-        if (!_networkMdl.isProviderEnabledInPhysicalNetwork(_networkMdl.getPhysicalNetworkId(network), getProvider().getName())) {
-            return false;
-        }
-
-        final RouterDeploymentDefinition routerDeploymentDefinition =
-                routerDeploymentDefinitionBuilder.create()
-                .setGuestNetwork(network)
-                .setDeployDestination(dest)
-                .setAccountOwner(_accountMgr.getAccount(network.getAccountId()))
-                .setParams(vm.getParameters())
-                .build();
-
-        final List<DomainRouterVO> routers = routerDeploymentDefinition.deployVirtualRouter();
-
-        if (routers == null || routers.size() == 0) {
-            throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId());
-        }
-        return true;
-    }
-
-    @Override
-    public boolean applyFWRules(final Network network, final List<? extends FirewallRule> rules) throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.Firewall)) {
-            final List<DomainRouterVO> routers = getRouters(network);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
-                return true;
-            }
-
-            if (rules != null && rules.size() == 1) {
-                // for VR no need to add default egress rule to ALLOW traffic
-                //The default allow rule is added from the router defalut iptables rules iptables-router
-                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System
-                        && _networkMdl.getNetworkEgressDefaultPolicy(network.getId())) {
-                    return true;
-                }
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean validateLBRule(final Network network, final LoadBalancingRule rule) {
-        final List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
-        rules.add(rule);
-        if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                return true;
-            }
-            return _networkHelper.validateHAProxyLBRule(rule);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules) throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.Lb)) {
-            if (!canHandleLbRules(rules)) {
-                return false;
-            }
-
-            final List<DomainRouterVO> routers = getRouters(network);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply lb rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public String[] applyVpnUsers(final RemoteAccessVpn vpn, final List<? extends VpnUser> users) throws ResourceUnavailableException {
-        if (vpn.getNetworkId() == null) {
-            return null;
-        }
-
-        final Network network = _networksDao.findById(vpn.getNetworkId());
-        if (canHandle(network, Service.Vpn)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + " doesn't exist in the network " + network.getId());
-                return null;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            return networkTopology.applyVpnUsers(network, users, routers);
-        } else {
-            s_logger.debug("Element " + getName() + " doesn't handle applyVpnUsers command");
-            return null;
-        }
-    }
-
-    @Override
-    public boolean startVpn(final RemoteAccessVpn vpn) throws ResourceUnavailableException {
-        if (vpn.getNetworkId() == null) {
-            return false;
-        }
-
-        final Network network = _networksDao.findById(vpn.getNetworkId());
-        if (canHandle(network, Service.Vpn)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't" + " exist in the network " + network.getId());
-                return true;
-            }
-            return _routerMgr.startRemoteAccessVpn(network, vpn, routers);
-        } else {
-            s_logger.debug("Element " + getName() + " doesn't handle createVpn command");
-            return false;
-        }
-    }
-
-    @Override
-    public boolean stopVpn(final RemoteAccessVpn vpn) throws ResourceUnavailableException {
-        if (vpn.getNetworkId() == null) {
-            return false;
-        }
-
-        final Network network = _networksDao.findById(vpn.getNetworkId());
-        if (canHandle(network, Service.Vpn)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + "exist in the network " + network.getId());
-                return true;
-            }
-            return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers);
-        } else {
-            s_logger.debug("Element " + getName() + " doesn't handle removeVpn command");
-            return false;
-        }
-    }
-
-    @Override
-    public boolean applyIps(final Network network, final List<? extends PublicIpAddress> ipAddress, final Set<Service> services) throws ResourceUnavailableException {
-        boolean canHandle = true;
-        for (final Service service : services) {
-            if (!canHandle(network, service)) {
-                canHandle = false;
-                break;
-            }
-        }
-        boolean result = true;
-        if (canHandle) {
-            final List<DomainRouterVO> routers = getRouters(network);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + "router doesn't exist in the network " + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public Provider getProvider() {
-        return Provider.VirtualRouter;
-    }
-
-    @Override
-    public Map<Service, Map<Capability, String>> getCapabilities() {
-        return capabilities;
-    }
-
-    public static String getHAProxyStickinessCapability() {
-        LbStickinessMethod method;
-        final List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>(1);
-
-        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method.");
-        method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false);
-        method.addParam("mode", false, "Valid values: insert, rewrite, prefix. Default value: insert.  In the insert mode cookie will be created"
-                + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false);
-        method.addParam("nocache", false, "This option is recommended in conjunction with the insert mode when there is a cache between the client"
-                + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if  a cookie needs "
-                + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page"
-                + " for instance, then all customers will then fetch the page from an outer cache and will all share the "
-                + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + "insert and postonly options. ", true);
-        method.addParam("indirect", false, "When this option is specified in insert mode, cookies will only be added when the server was not reached"
-                + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm,"
-                + " or after a redispatch, then the cookie  will be inserted. If the client has all the required information"
-                + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the "
-                + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to "
-                + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true);
-        method.addParam("postonly", false, "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an"
-                + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the "
-                + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the"
-                + " first POST which generally is a login request, this is a very efficient method to optimize caching "
-                + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true);
-        method.addParam("domain", false, "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:"
-                + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host "
-                + "ending with that name. It is also possible to specify several domain names by invoking this option multiple"
-                + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. "
-                + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false);
-        methodList.add(method);
-
-        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
-                "This is App session based sticky method. Define session stickiness on an existing application cookie. " + "It can be used only for a specific http traffic");
-        method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will "
-                + "have to learn for each new session. Default value: Auto geneared based on ip", false);
-        method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + "each cookie value. Default value:52", false);
-        method.addParam("holdtime", false, "This is the time after which the cookie will be removed from memory if unused. The value should be in "
-                + "the format Example : 20s or 30m  or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid,"
-                + " cannot use th combinations like 20h30m. Default value:3h ", false);
-        method.addParam(
-                "request-learn",
-                false,
-                "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability",
-                true);
-        method.addParam(
-                "prefix",
-                false,
-                "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). "
-                        + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix  This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.",
-                        true);
-        method.addParam("mode", false, "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters "
-                + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), "
-                + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :"
-                + " In this mode, the parser will look for the appsession in the query string.", false);
-        methodList.add(method);
-
-        method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + "it can be used for any type of protocol.");
-        method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + " or 400g. Default value:200k", false);
-        method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ."
-                + " example: expire=30m 20s 50h 4d. Default value:3h", false);
-        methodList.add(method);
-
-        final Gson gson = new Gson();
-        final String capability = gson.toJson(methodList);
-        return capability;
-    }
-
-    private static Map<Service, Map<Capability, String>> setCapabilities() {
-        final Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
-
-        // Set capabilities for LB service
-        final Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
-        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source");
-        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated");
-        lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp, tcp-proxy");
-        lbCapabilities.put(Capability.SupportedStickinessMethods, getHAProxyStickinessCapability());
-        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
-
-        // specifies that LB rules can support autoscaling and the list of
-        // counters it supports
-        AutoScaleCounter counter;
-        final List<AutoScaleCounter> counterList = new ArrayList<AutoScaleCounter>();
-        counter = new AutoScaleCounter(AutoScaleCounterCpu);
-        counterList.add(counter);
-        counter = new AutoScaleCounter(AutoScaleCounterMemory);
-        counterList.add(counter);
-        final Gson gson = new Gson();
-        final String autoScaleCounterList = gson.toJson(counterList);
-        lbCapabilities.put(Capability.AutoScaleCounters, autoScaleCounterList);
-        capabilities.put(Service.Lb, lbCapabilities);
-
-        // Set capabilities for Firewall service
-        final Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
-        firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
-        firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
-        firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all");
-        firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
-        firewallCapabilities.put(Capability.MultipleIps, "true");
-        capabilities.put(Service.Firewall, firewallCapabilities);
-
-        // Set capabilities for vpn
-        final Map<Capability, String> vpnCapabilities = new HashMap<Capability, String>();
-        vpnCapabilities.put(Capability.SupportedVpnProtocols, "pptp,l2tp,ipsec");
-        vpnCapabilities.put(Capability.VpnTypes, "removeaccessvpn");
-        capabilities.put(Service.Vpn, vpnCapabilities);
-
-        final Map<Capability, String> dnsCapabilities = new HashMap<Capability, String>();
-        dnsCapabilities.put(Capability.AllowDnsSuffixModification, "true");
-        capabilities.put(Service.Dns, dnsCapabilities);
-
-        capabilities.put(Service.UserData, null);
-
-        final Map<Capability, String> dhcpCapabilities = new HashMap<Capability, String>();
-        dhcpCapabilities.put(Capability.DhcpAccrossMultipleSubnets, "true");
-        capabilities.put(Service.Dhcp, dhcpCapabilities);
-
-        capabilities.put(Service.Gateway, null);
-
-        final Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
-        sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
-        sourceNatCapabilities.put(Capability.RedundantRouter, "true");
-        capabilities.put(Service.SourceNat, sourceNatCapabilities);
-
-        capabilities.put(Service.StaticNat, null);
-
-        final Map<Capability, String> portForwardingCapabilities = new HashMap<Capability, String>();
-        portForwardingCapabilities.put(Capability.SupportedProtocols, NetUtils.TCP_PROTO + "," + NetUtils.UDP_PROTO);
-        capabilities.put(Service.PortForwarding, portForwardingCapabilities);
-
-        return capabilities;
-    }
-
-    @Override
-    public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules) throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.StaticNat)) {
-            final List<DomainRouterVO> routers = getRouters(network);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + "router doesn't exist in the network " + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    public List<DomainRouterVO> getRouters(Network network){
-        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers !=null && routers.isEmpty()) {
-            return null;
-        }
-        NetworkDetailVO updateInSequence=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
-        if(network.isRedundant() && updateInSequence!=null && "true".equalsIgnoreCase(updateInSequence.getValue())){
-            List<DomainRouterVO> masterRouters=new ArrayList<DomainRouterVO>();
-            int noOfrouters=routers.size();
-            while (noOfrouters>0){
-                DomainRouterVO router = routers.get(0);
-                if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_IN_PROGRESS){
-                    ArrayList<DomainRouterVO> routerList = new ArrayList<DomainRouterVO>();
-                    routerList.add(router);
-                    return routerList;
-                }
-                if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_COMPLETE) {
-                    routers.remove(router);
-                    noOfrouters--;
-                    continue;
-                }
-                if(router.getRedundantState()!=VirtualRouter.RedundantState.BACKUP) {
-                    masterRouters.add(router);
-                    routers.remove(router);
-                }
-                noOfrouters--;
-            }
-            if(routers.size()==0 && masterRouters.size()==0){
-                return null;
-            }
-            if(routers.size()==0 && masterRouters.size()!=0){
-                routers=masterRouters;
-            }
-            routers=routers.subList(0,1);
-            routers.get(0).setUpdateState(VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
-            _routerDao.persist(routers.get(0));
-        }
-        return routers;
-    }
-
-    @Override
-    public boolean shutdown(final Network network, final ReservationContext context, final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
-        final List<DomainRouterVO> routers = getRouters(network);
-        if (routers == null || routers.isEmpty()) {
-            return true;
-        }
-        boolean stopResult = true;
-        boolean destroyResult = true;
-        for (final DomainRouterVO router : routers) {
-            stopResult = stopResult && _routerMgr.stop(router, false, context.getCaller(), context.getAccount()) != null;
-            if (!stopResult) {
-                s_logger.warn("Failed to stop virtual router element " + router + ", but would try to process clean up anyway.");
-            }
-            if (cleanup) {
-                destroyResult = destroyResult && _routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null;
-                if (!destroyResult) {
-                    s_logger.warn("Failed to clean up virtual router element " + router);
-                }
-            }
-        }
-        return stopResult & destroyResult;
-    }
-
-    @Override
-    public boolean destroy(final Network config, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            return true;
-        }
-        boolean result = true;
-        // NOTE that we need to pass caller account to destroyRouter, otherwise
-        // it will fail permission check there. Context passed in from
-        // deleteNetwork is the network account,
-        // not caller account
-        final Account callerAccount = _accountMgr.getAccount(context.getCaller().getAccountId());
-        for (final DomainRouterVO router : routers) {
-            result = result && _routerMgr.destroyRouter(router.getId(), callerAccount, context.getCaller().getId()) != null;
-        }
-        return result;
-    }
-
-    @Override
-    public boolean savePassword(final Network network, final NicProfile nic, final VirtualMachineProfile vm) throws ResourceUnavailableException {
-        if (!canHandle(network, null)) {
-            return false;
-        }
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Can't find virtual router element in network " + network.getId());
-            return true;
-        }
-
-        final VirtualMachineProfile uservm = vm;
-
-        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-        // If any router is running then send save password command otherwise
-        // save the password in DB
-        for (final VirtualRouter router : routers) {
-            if (router.getState() == State.Running) {
-                final boolean result = networkTopology.savePasswordToRouter(network, nic, uservm, router);
-                if (result) {
-                    // Explicit password reset, while VM hasn't generated a password yet.
-                    final UserVmVO userVmVO = _userVmDao.findById(vm.getId());
-                    userVmVO.setUpdateParameters(false);
-                    _userVmDao.update(userVmVO.getId(), userVmVO);
-                }
-                return result;
-            }
-        }
-        final String password = (String) uservm.getParameter(VirtualMachineProfile.Param.VmPassword);
-        final String password_encrypted = DBEncryptionUtil.encrypt(password);
-        final UserVmVO userVmVO = _userVmDao.findById(vm.getId());
-
-        _userVmDao.loadDetails(userVmVO);
-        userVmVO.setDetail("password", password_encrypted);
-        _userVmDao.saveDetails(userVmVO);
-
-        userVmVO.setUpdateParameters(true);
-        _userVmDao.update(userVmVO.getId(), userVmVO);
-
-        return true;
-    }
-
-    @Override
-    public boolean saveSSHKey(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final String sshPublicKey) throws ResourceUnavailableException {
-        if (!canHandle(network, null)) {
-            return false;
-        }
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Can't find virtual router element in network " + network.getId());
-            return true;
-        }
-
-        final VirtualMachineProfile uservm = vm;
-
-        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-        boolean result = true;
-        for (final DomainRouterVO domainRouterVO : routers) {
-            result = result && networkTopology.saveSSHPublicKeyToRouter(network, nic, uservm, domainRouterVO, sshPublicKey);
-        }
-        return result;
-    }
-
-    @Override
-    public boolean saveUserData(final Network network, final NicProfile nic, final VirtualMachineProfile vm) throws ResourceUnavailableException {
-        if (!canHandle(network, null)) {
-            return false;
-        }
-        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Can't find virtual router element in network " + network.getId());
-            return true;
-        }
-
-        final VirtualMachineProfile uservm = vm;
-
-        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-        boolean result = true;
-        for (final DomainRouterVO domainRouterVO : routers) {
-            result = result && networkTopology.saveUserDataToRouter(network, nic, uservm, domainRouterVO);
-        }
-        return result;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(CreateVirtualRouterElementCmd.class);
-        cmdList.add(ConfigureVirtualRouterElementCmd.class);
-        cmdList.add(ListVirtualRouterElementsCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public VirtualRouterProvider configure(final ConfigureVirtualRouterElementCmd cmd) {
-        final VirtualRouterProviderVO element = _vrProviderDao.findById(cmd.getId());
-        if (element == null || !(element.getType() == Type.VirtualRouter || element.getType() == Type.VPCVirtualRouter)) {
-            s_logger.debug("Can't find Virtual Router element with network service provider id " + cmd.getId());
-            return null;
-        }
-
-        element.setEnabled(cmd.getEnabled());
-        _vrProviderDao.persist(element);
-
-        return element;
-    }
-
-    @Override
-    public OvsProvider configure(final ConfigureOvsElementCmd cmd) {
-        final OvsProviderVO element = _ovsProviderDao.findById(cmd.getId());
-        if (element == null) {
-            s_logger.debug("Can't find Ovs element with network service provider id " + cmd.getId());
-            return null;
-        }
-
-        element.setEnabled(cmd.getEnabled());
-        _ovsProviderDao.persist(element);
-
-        return element;
-    }
-
-    @Override
-    public VirtualRouterProvider addElement(final Long nspId, final Type providerType) {
-        if (!(providerType == Type.VirtualRouter || providerType == Type.VPCVirtualRouter)) {
-            throw new InvalidParameterValueException("Element " + getName() + " supports only providerTypes: " + Type.VirtualRouter.toString() + " and " + Type.VPCVirtualRouter);
-        }
-        VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType);
-        if (element != null) {
-            s_logger.debug("There is already a virtual router element with service provider id " + nspId);
-            return null;
-        }
-        element = new VirtualRouterProviderVO(nspId, providerType);
-        _vrProviderDao.persist(element);
-        return element;
-    }
-
-    @Override
-    public boolean applyPFRules(final Network network, final List<PortForwardingRule> rules) throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.PortForwarding)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            if (routers == null || routers.isEmpty()) {
-                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
-                return true;
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean isReady(final PhysicalNetworkServiceProvider provider) {
-        final VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), getVirtualRouterProvider());
-        if (element == null) {
-            return false;
-        }
-        return element.isEnabled();
-    }
-
-    @Override
-    public boolean shutdownProviderInstances(final PhysicalNetworkServiceProvider provider, final ReservationContext context) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        final VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), getVirtualRouterProvider());
-        if (element == null) {
-            return true;
-        }
-        // Find domain routers
-        final long elementId = element.getId();
-        final List<DomainRouterVO> routers = _routerDao.listByElementId(elementId);
-        boolean result = true;
-        for (final DomainRouterVO router : routers) {
-            result = result && _routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null;
-        }
-        _vrProviderDao.remove(elementId);
-
-        return result;
-    }
-
-    @Override
-    public boolean canEnableIndividualServices() {
-        return true;
-    }
-
-    public Long getIdByNspId(final Long nspId) {
-        final VirtualRouterProviderVO vr = _vrProviderDao.findByNspIdAndType(nspId, Type.VirtualRouter);
-        return vr.getId();
-    }
-
-    @Override
-    public VirtualRouterProvider getCreatedElement(final long id) {
-        final VirtualRouterProvider provider = _vrProviderDao.findById(id);
-        if (!(provider.getType() == Type.VirtualRouter || provider.getType() == Type.VPCVirtualRouter)) {
-            throw new InvalidParameterValueException("Unable to find provider by id");
-        }
-        return provider;
-    }
-
-    @Override
-    public boolean release(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final ReservationContext context) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        removeDhcpEntry(network, nic, vm);
-        return true;
-    }
-
-
-    @Override
-    public boolean configDhcpSupportForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest,
-                                              final ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-            return configureDhcpSupport(network, nic, vm, dest, Service.Dhcp);
-    }
-
-    @Override
-    public boolean configDnsSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        // Ignore if virtual router is already dhcp provider
-        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
-            return true;
-        }
-        return configureDhcpSupport(network, nic, vm, dest, Service.Dns);
-    }
-
-    protected boolean configureDhcpSupport(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, Service service) throws ResourceUnavailableException {
-        if (canHandle(network, service)) {
-            if (vm.getType() != VirtualMachine.Type.User) {
-                return false;
-            }
-
-            final VirtualMachineProfile uservm = vm;
-
-            final List<DomainRouterVO> routers = getRouters(network, dest);
-
-            if (routers == null || routers.size() == 0) {
-                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            return networkTopology.configDhcpForSubnet(network, nic, uservm, dest, routers);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean removeDhcpSupportForSubnet(final Network network) throws ResourceUnavailableException {
-        return removeDhcpSupportForSubnet(network, Service.Dhcp);
-    }
-
-    @Override
-    public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
-        return false;
-    }
-
-    @Override
-    public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) throws ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.Dhcp)) {
-            if (vmProfile.getType() != VirtualMachine.Type.User) {
-                return false;
-            }
-
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
-
-            if (CollectionUtils.isEmpty(routers)) {
-                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                if (domainRouterVO.getState() != VirtualMachine.State.Running) {
-                    continue;
-                }
-
-                result = result && networkTopology.removeDhcpEntry(network, nic, vmProfile, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean removeDnsSupportForSubnet(Network network) throws ResourceUnavailableException {
-        // Ignore if virtual router is already dhcp provider
-        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
-            return true;
-        } else {
-            return removeDhcpSupportForSubnet(network, Service.Dns);
-        }
-    }
-
-    protected boolean removeDhcpSupportForSubnet(Network network, Network.Service service) throws ResourceUnavailableException {
-        if (canHandle(network, service)) {
-            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-
-            if (CollectionUtils.isEmpty(routers)) {
-                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-            }
-            try {
-                return _routerMgr.removeDhcpSupportForSubnet(network, routers);
-            } catch (final ResourceUnavailableException e) {
-                s_logger.info("Router resource unavailable ", e);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean addDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
-            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        return applyDhcpEntries(network, nic, vm, dest, Service.Dhcp);
-    }
-
-    @Override
-    public boolean addDnsEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        // Ignore if virtual router is already dhcp provider
-        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
-            return true;
-        }
-
-        return applyDhcpEntries(network, nic, vm, dest, Service.Dns);
-    }
-
-    protected boolean applyDhcpEntries (final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final Network.Service service) throws ResourceUnavailableException {
-
-        boolean result = true;
-        if (canHandle(network, service)) {
-            if (vm.getType() != VirtualMachine.Type.User) {
-                return false;
-            }
-
-            final VirtualMachineProfile uservm = vm;
-            final List<DomainRouterVO> routers = getRouters(network, dest);
-
-            if (routers == null || routers.size() == 0) {
-                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyDhcpEntry(network, nic, uservm, dest, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean addPasswordAndUserdata(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest,
-            final ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
-        boolean result = true;
-        if (canHandle(network, Service.UserData)) {
-            if (vm.getType() != VirtualMachine.Type.User) {
-                return false;
-            }
-
-            if (network.getIp6Gateway() != null) {
-                s_logger.info("Skip password and userdata service setup for IPv6 VM");
-                return true;
-            }
-
-            final VirtualMachineProfile uservm = vm;
-
-            final List<DomainRouterVO> routers = getRouters(network, dest);
-
-            if (routers == null || routers.size() == 0) {
-                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-            }
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            for (final DomainRouterVO domainRouterVO : routers) {
-                result = result && networkTopology.applyUserData(network, nic, uservm, dest, domainRouterVO);
-            }
-        }
-        return result;
-    }
-
-    protected List<DomainRouterVO> getRouters(final Network network, final DeployDestination dest) {
-        boolean publicNetwork = false;
-        if (_networkMdl.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) {
-            publicNetwork = true;
-        }
-        final boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMdl.isSecurityGroupSupportedInNetwork(network))
-                && network.getTrafficType() == TrafficType.Guest;
-
-        List<DomainRouterVO> routers;
-
-        if (publicNetwork) {
-            routers = getRouters(network);
-        } else {
-            if (isPodBased && dest.getPod() != null) {
-                final Long podId = dest.getPod().getId();
-                routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER);
-            } else {
-                // With pod == null, it's network restart case, we would add all
-                // router to it
-                // Ignore DnsBasicZoneUpdate() parameter here
-                routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-            }
-        }
-
-        // for Basic zone, add all Running routers - we have to send
-        // Dhcp/vmData/password info to them when
-        // network.dns.basiczone.updates is set to "all"
-        // With pod == null, it's network restart case, we already add all
-        // routers to it
-        if (isPodBased && dest.getPod() != null && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) {
-            final Long podId = dest.getPod().getId();
-            final List<DomainRouterVO> allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER);
-            routers.addAll(allRunningRoutersOutsideThePod);
-        }
-        return routers;
-    }
-
-    @Override
-    public List<? extends VirtualRouterProvider> searchForVirtualRouterElement(final ListVirtualRouterElementsCmd cmd) {
-        final Long id = cmd.getId();
-        final Long nspId = cmd.getNspId();
-        final Boolean enabled = cmd.getEnabled();
-
-        final QueryBuilder<VirtualRouterProviderVO> sc = QueryBuilder.create(VirtualRouterProviderVO.class);
-        if (id != null) {
-            sc.and(sc.entity().getId(), Op.EQ, id);
-        }
-        if (nspId != null) {
-            sc.and(sc.entity().getNspId(), Op.EQ, nspId);
-        }
-        if (enabled != null) {
-            sc.and(sc.entity().isEnabled(), Op.EQ, enabled);
-        }
-
-        // return only VR and VPC VR
-        sc.and(sc.entity().getType(), Op.IN, VirtualRouterProvider.Type.VPCVirtualRouter, VirtualRouterProvider.Type.VirtualRouter);
-
-        return sc.list();
-    }
-
-    @Override
-    public List<? extends OvsProvider> searchForOvsElement(final ListOvsElementsCmd cmd) {
-        final Long id = cmd.getId();
-        final Long nspId = cmd.getNspId();
-        final Boolean enabled = cmd.getEnabled();
-        final QueryBuilder<OvsProviderVO> sc = QueryBuilder.create(OvsProviderVO.class);
-
-        if (id != null) {
-            sc.and(sc.entity().getId(), Op.EQ, id);
-        }
-        if (nspId != null) {
-            sc.and(sc.entity().getNspId(), Op.EQ, nspId);
-        }
-        if (enabled != null) {
-            sc.and(sc.entity().isEnabled(), Op.EQ, enabled);
-        }
-
-        return sc.list();
-    }
-
-    @Override
-    public boolean verifyServicesCombination(final Set<Service> services) {
-        return true;
-    }
-
-    @Override
-    public IpDeployer getIpDeployer(final Network network) {
-        return this;
-    }
-
-    protected VirtualRouterProvider.Type getVirtualRouterProvider() {
-        return VirtualRouterProvider.Type.VirtualRouter;
-    }
-
-    @Override
-    public List<LoadBalancerTO> updateHealthChecks(final Network network, final List<LoadBalancingRule> lbrules) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean handlesOnlyRulesInTransitionState() {
-        return true;
-    }
-
-    private boolean canHandleLbRules(final List<LoadBalancingRule> rules) {
-        final Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
-        if (!lbCaps.isEmpty()) {
-            final String schemeCaps = lbCaps.get(Capability.LbSchemes);
-            if (schemeCaps != null) {
-                for (final LoadBalancingRule rule : rules) {
-                    if (!schemeCaps.contains(rule.getScheme().toString())) {
-                        s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + getName());
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean prepareMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) {
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
-            return true;
-        }
-        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-            assert vm instanceof DomainRouterVO;
-            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            try {
-                networkTopology.setupDhcpForPvlan(false, router, router.getHostId(), nic);
-            } catch (final ResourceUnavailableException e) {
-                s_logger.warn("Timed Out", e);
-            }
-        } else if (vm.getType() == VirtualMachine.Type.User) {
-            assert vm instanceof UserVmVO;
-            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
-            _userVmMgr.setupVmForPvlan(false, userVm.getHostId(), nic);
-        }
-        return true;
-    }
-
-    @Override
-    public void rollbackMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
-            return;
-        }
-        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-            assert vm instanceof DomainRouterVO;
-            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            try {
-                networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic);
-            } catch (final ResourceUnavailableException e) {
-                s_logger.warn("Timed Out", e);
-            }
-        } else if (vm.getType() == VirtualMachine.Type.User) {
-            assert vm instanceof UserVmVO;
-            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
-            _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
-        }
-    }
-
-    @Override
-    public void commitMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
-        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
-            return;
-        }
-        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-            assert vm instanceof DomainRouterVO;
-            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
-
-            try {
-                networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic);
-            } catch (final ResourceUnavailableException e) {
-                s_logger.warn("Timed Out", e);
-            }
-        } else if (vm.getType() == VirtualMachine.Type.User) {
-            assert vm instanceof UserVmVO;
-            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
-            _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
-        }
-    }
-
-    @Override
-    public boolean prepareAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
-        final List<DomainRouterVO> routers = getRouters(network, dest);
-
-        if (routers == null || routers.size() == 0) {
-            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-        }
-
-        return _routerMgr.prepareAggregatedExecution(network, routers);
-    }
-
-    @Override
-    public boolean completeAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
-        final List<DomainRouterVO> routers = getRouters(network, dest);
-
-        if (routers == null || routers.size() == 0) {
-            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
-        }
-
-        NetworkDetailVO networkDetail=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
-        boolean updateInSequence= "true".equalsIgnoreCase((networkDetail!=null ? networkDetail.getValue() : null));
-        if(updateInSequence){
-            DomainRouterVO router=routers.get(0);
-            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_COMPLETE);
-            _routerDao.persist(router);
-        }
-        boolean result=false;
-        try{
-            result=_routerMgr.completeAggregatedExecution(network, routers);
-        } finally {
-            if(!result && updateInSequence) {
-                //fail the network update. even if one router fails we fail the network update.
-                updateToFailedState(network);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public boolean cleanupAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
-        // The VR code already cleansup in the Finish routine using finally,
-        // lets not waste another command
-        return true;
-    }
-
-    @Override
-    public void configureResource(Network network) {
-        NetworkDetailVO networkDetail=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
-        if(networkDetail==null || !"true".equalsIgnoreCase(networkDetail.getValue()))
-            throw new CloudRuntimeException("failed to configure the resource, network update is not in progress.");
-        List<DomainRouterVO>routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
-        for(DomainRouterVO router : routers){
-            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
-            _routerDao.persist(router);
-        }
-    }
-
-    @Override
-    public int getResourceCount(Network network) {
-        return _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER).size();
-    }
-
-    @Override
-    public void finalize(Network network, boolean success) {
-        if(!success){
-            updateToFailedState(network);
-        }
-    }
-
-    private void updateToFailedState(Network network){
-        //fail the network update. even if one router fails we fail the network update.
-        List<DomainRouterVO> routerList = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
-        for (DomainRouterVO router : routerList) {
-            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_FAILED);
-            _routerDao.persist(router);
-        }
-    }
-
-}
diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
deleted file mode 100644
index cf72ff2..0000000
--- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
+++ /dev/null
@@ -1,1068 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.firewall;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Collections;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.network.dao.FirewallRulesDcidrsDao;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.command.user.firewall.IListFirewallRulesCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
-import com.cloud.configuration.Config;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkRuleApplier;
-import com.cloud.network.dao.FirewallRulesCidrsDao;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.FirewallServiceProvider;
-import com.cloud.network.element.NetworkACLServiceProvider;
-import com.cloud.network.element.PortForwardingServiceProvider;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.FirewallRuleType;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRule.State;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.dao.UserVmDao;
-
-@Component
-public class FirewallManagerImpl extends ManagerBase implements FirewallService, FirewallManager, NetworkRuleApplier {
-    private static final Logger s_logger = Logger.getLogger(FirewallManagerImpl.class);
-
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    EventDao _eventDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    FirewallRulesCidrsDao _firewallCidrsDao;
-    @Inject
-    FirewallRulesDcidrsDao _firewallDcidrsDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    UsageEventDao _usageEventDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    DomainManager _domainMgr;
-    @Inject
-    PortForwardingRulesDao _pfRulesDao;
-    @Inject
-    UserVmDao _vmDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    VpcManager _vpcMgr;
-    List<FirewallServiceProvider> _firewallElements;
-
-    List<PortForwardingServiceProvider> _pfElements;
-
-    List<StaticNatServiceProvider> _staticNatElements;
-
-    List<NetworkACLServiceProvider> _networkAclElements;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-
-    private boolean _elbEnabled = false;
-    static Boolean rulesContinueOnErrFlag = true;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-        String elbEnabledString = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
-        _elbEnabled = Boolean.parseBoolean(elbEnabledString);
-        if (_ipAddrMgr.RulesContinueOnError.value() != null) {
-            rulesContinueOnErrFlag = _ipAddrMgr.RulesContinueOnError.value();
-        }
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        s_logger.info("Firewall provider list is " + _firewallElements.iterator().next());
-        return super.start();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule for network", create = true)
-    public FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        Network network = _networkDao.findById(rule.getNetworkId());
-        if (network.getGuestType() == Network.GuestType.Shared) {
-            throw new InvalidParameterValueException("Egress firewall rules are not supported for " + network.getGuestType() + "  networks");
-        }
-
-        List<String> sourceCidrs = rule.getSourceCidrList();
-        if (sourceCidrs != null && !sourceCidrs.isEmpty())
-        Collections.replaceAll(sourceCidrs, "0.0.0.0/0", network.getCidr());
-
-        return createFirewallRule(null, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), sourceCidrs, rule.getDestinationCidrList(),
-                rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
-    public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
-         Account caller = CallContext.current().getCallingAccount();
-        Long sourceIpAddressId = rule.getSourceIpAddressId();
-
-        return createFirewallRule(sourceIpAddressId, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(),
-            rule.getSourceCidrList(), null, rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
-    }
-    //Destination CIDR capability is currently implemented for egress rules only. For others, the field is passed as null.
-    @DB
-    protected FirewallRule createFirewallRule(final Long ipAddrId, Account caller, final String xId, final Integer portStart, final Integer portEnd,
-        final String protocol, final List<String> sourceCidrList, final List<String> destCidrList, final Integer icmpCode, final Integer icmpType, final Long relatedRuleId,
- final FirewallRule.FirewallRuleType type,
-            final Long networkId, final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
-
-        IPAddressVO ipAddress = null;
-        if (ipAddrId != null) {
-            // this for ingress firewall rule, for egress id is null
-             ipAddress = _ipAddressDao.findById(ipAddrId);
-        // Validate ip address
-        if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
-                throw new InvalidParameterValueException("Unable to create firewall rule; " + "couldn't locate IP address by id in the system");
-        }
-        _networkModel.checkIpForService(ipAddress, Service.Firewall, null);
-        }
-
-        validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type, networkId, trafficType);
-
-        // icmp code and icmp type can't be passed in for any other protocol rather than icmp
-        if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
-            throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
-        }
-
-        if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
-            throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
-        }
-
-        Long accountId = null;
-        Long domainId = null;
-
-        if (ipAddress != null) {
-            //Ingress firewall rule
-            accountId = ipAddress.getAllocatedToAccountId();
-            domainId = ipAddress.getAllocatedInDomainId();
-        } else if (networkId != null) {
-            //egress firewall rule
-                Network network = _networkModel.getNetwork(networkId);
-                accountId = network.getAccountId();
-                domainId = network.getDomainId();
-        }
-
-        final Long accountIdFinal = accountId;
-        final Long domainIdFinal = domainId;
-        return Transaction.execute(new TransactionCallbackWithException<FirewallRuleVO, NetworkRuleConflictException>() {
-            @Override
-            public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
-                FirewallRuleVO newRule =
-                        new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, accountIdFinal, domainIdFinal, Purpose.Firewall,
-                                sourceCidrList, destCidrList, icmpCode, icmpType, relatedRuleId, trafficType);
-                newRule.setType(type);
-                if (forDisplay != null) {
-                    newRule.setDisplay(forDisplay);
-                }
-                newRule = _firewallDao.persist(newRule);
-
-                if (type == FirewallRuleType.User)
-                    detectRulesConflict(newRule);
-
-                if (!_firewallDao.setStateToAdd(newRule)) {
-                    throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
-                }
-                CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
-
-                return newRule;
-            }
-        });
-    }
-
-    @Override
-    public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(IListFirewallRulesCmd cmd) {
-        Long ipId = cmd.getIpAddressId();
-        Long id = cmd.getId();
-        Long networkId = cmd.getNetworkId();
-        Map<String, String> tags = cmd.getTags();
-        FirewallRule.TrafficType trafficType = cmd.getTrafficType();
-        Boolean display = cmd.getDisplay();
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        if (ipId != null) {
-            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
-            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
-                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for firewall rules yet");
-            }
-            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
-        }
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
-            sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
-        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
-        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), Op.EQ);
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<FirewallRuleVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.FirewallRule.toString());
-            for (String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        if (ipId != null) {
-            sc.setParameters("ip", ipId);
-        }
-
-            if (networkId != null) {
-                sc.setParameters("networkId", networkId);
-            }
-
-        sc.setParameters("purpose", Purpose.Firewall);
-        sc.setParameters("trafficType", trafficType);
-
-        Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
-        return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
-    }
-
-    //Intermediate funciton used in detectRulesConflict to check for the conflicting cidrs in the rules already applied and the newRule being applied.
-    boolean detectConflictingCidrs(List<String> cidrList1, List<String> cidrList2){
-        if(cidrList1.isEmpty() && cidrList2.isEmpty()){
-            return true;
-        }
-
-        Collection<String> similar = new HashSet<String>(cidrList1);
-        similar.retainAll(cidrList2);
-        return (similar.size()>0);
-    }
-
-    @Override
-    public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
-        List<FirewallRuleVO> rules;
-        if (newRule.getSourceIpAddressId() != null) {
-             rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
-            assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for "
-                + "network conflicts so we should at least have one rule at this point.";
-        } else {
-            // fetches only firewall egress rules.
-            rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
-            assert (rules.size() >= 1);
-        }
-
-        for (FirewallRuleVO rule : rules) {
-            if (rule.getId() == newRule.getId()) {
-                continue; // Skips my own rule.
-            }
-
-            boolean oneOfRulesIsFirewall =
-                ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
-                            .equalsIgnoreCase(rule.getProtocol()))));
-
-            // if both rules are firewall and their cidrs are different, we can skip port ranges verification
-            boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
-            boolean duplicatedCidrs = false;
-            if (bothRulesFirewall) {
-                _firewallDao.loadSourceCidrs(rule);
-                _firewallDao.loadSourceCidrs((FirewallRuleVO)newRule);
-
-                _firewallDao.loadDestinationCidrs(rule);
-                _firewallDao.loadDestinationCidrs((FirewallRuleVO) newRule);
-
-                if (rule.getSourceCidrList() == null || newRule.getSourceCidrList() == null) {
-                    continue;
-                }
-                duplicatedCidrs = (detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList()) && detectConflictingCidrs(rule.getDestinationCidrList(), newRule.getDestinationCidrList()));
-            }
-
-            if (!oneOfRulesIsFirewall) {
-                if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
-                    throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
-                } else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
-                    throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
-                }
-            }
-
-            // Checking if the rule applied is to the same network that is passed in the rule.
-            if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
-                throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
-            }
-
-            //Check for the ICMP protocol. This has to be done separately from other protocols as we need to check the ICMP codes and ICMP type also.
-            if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
-                if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() &&
-                    newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) {
-                    throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId());
-                }
-            }
-
-            boolean notNullPorts =
-                (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
-            boolean nullPorts =
-                (newRule.getSourcePortStart() == null && newRule.getSourcePortEnd() == null && rule.getSourcePortStart() == null && rule.getSourcePortEnd() == null);
-
-            // If ports are not specified and cidrs are same and protocol is also same(NOT ICMP as it is separately checked above)
-            if(nullPorts && duplicatedCidrs && (rule.getProtocol().equalsIgnoreCase(newRule.getProtocol())) && !newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
-                throw new NetworkRuleConflictException("There is already a firewall rule specified with protocol = " +newRule.getProtocol()+ " and no ports");
-            }
-
-            if (!notNullPorts) {
-                continue;
-            } else if (!oneOfRulesIsFirewall &&
-                !(bothRulesFirewall && !duplicatedCidrs) &&
-                ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() &&
-                    rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) ||
-                    (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() &&
-                    rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) ||
-                    (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() &&
-                    newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) ||
-                (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() &&
-                newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
-                //Above else if conditions checks for the conflicting port ranges.
-
-                // we allow port forwarding rules with the same parameters but different protocols
-                boolean allowPf =
-                    (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(
-                        rule.getProtocol())) || (rule.getPurpose() == Purpose.Vpn && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(
-                            rule.getProtocol()));
-                boolean allowStaticNat =
-                    (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
-
-                boolean allowVpnPf =
-                        (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
-
-                boolean allowVpnLb =
-                        (rule.getPurpose() == Purpose.LoadBalancing && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
-
-                if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall || allowVpnPf || allowVpnLb)) {
-                    throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() +
-                        ", conflicts with rule " + rule.getId() + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
-                }
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing rules");
-        }
-    }
-
-    @Override
-    public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type,
-        Long networkId, FirewallRule.TrafficType trafficType) {
-        if (portStart != null && !NetUtils.isValidPort(portStart)) {
-            throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
-        }
-        if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
-            throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
-        }
-
-        // start port can't be bigger than end port
-        if (portStart != null && portEnd != null && portStart > portEnd) {
-            throw new InvalidParameterValueException("Start port can't be bigger than end port");
-        }
-
-        if (ipAddress == null && type == FirewallRuleType.System) {
-            return;
-        }
-
-        if (ipAddress != null) {
-            if (ipAddress.getAssociatedWithNetworkId() == null) {
-                    throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
-            } else {
-                networkId = ipAddress.getAssociatedWithNetworkId();
-            }
-
-            // Validate ip address
-            _accountMgr.checkAccess(caller, null, true, ipAddress);
-        }
-
-        //network id either has to be passed explicitly, or implicitly as a part of ipAddress object
-        if (networkId == null) {
-            throw new InvalidParameterValueException("Unable to retrieve network id to validate the rule");
-        }
-
-        Network network = _networkModel.getNetwork(networkId);
-        assert network != null : "Can't create rule as network associated with public ip address is null?";
-
-        if (trafficType == FirewallRule.TrafficType.Egress) {
-            _accountMgr.checkAccess(caller, null, true, network);
-        }
-
-        // Verify that the network guru supports the protocol specified
-        Map<Network.Capability, String> caps = null;
-
-        if (purpose == Purpose.LoadBalancing) {
-            if (!_elbEnabled) {
-                caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
-            }
-        } else if (purpose == Purpose.PortForwarding) {
-            caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
-        } else if (purpose == Purpose.Firewall) {
-            caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
-        }
-
-        if (caps != null) {
-            String supportedProtocols;
-            String supportedTrafficTypes = null;
-            if (purpose == FirewallRule.Purpose.Firewall) {
-                supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase();
-            }
-
-            if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) {
-                supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase();
-            } else {
-                supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
-            }
-
-            if (!supportedProtocols.contains(proto.toLowerCase())) {
-                throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
-            } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
-                throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
-            } else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
-                throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId);
-            }
-        }
-
-    }
-
-    @Override
-    public boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException {
-        boolean success = true;
-        if (rules == null || rules.size() == 0) {
-            s_logger.debug("There are no rules to forward to the network elements");
-            return true;
-        }
-        Purpose purpose = rules.get(0).getPurpose();
-        if (!_ipAddrMgr.applyRules(rules, purpose, this, continueOnError)) {
-            s_logger.warn("Rules are not completely applied");
-            return false;
-        } else {
-            if (updateRulesInDB) {
-                for (FirewallRule rule : rules) {
-                    if (rule.getState() == FirewallRule.State.Revoke) {
-                        FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(rule.getId());
-                        if (relatedRule != null) {
-                            s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + " as it has related firewall rule id=" + relatedRule.getId() +
-                                "; leaving it in Revoke state");
-                            success = false;
-                        } else {
-                            removeRule(rule);
-                            if (rule.getSourceIpAddressId() != null) {
-                                //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
-                                IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
-                                _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), rule.getNetworkId());
-                            }
-                        }
-                    } else if (rule.getState() == FirewallRule.State.Add) {
-                        FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
-                        ruleVO.setState(FirewallRule.State.Active);
-                        _firewallDao.update(ruleVO.getId(), ruleVO);
-                    }
-                }
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    public boolean applyRules(Network network, Purpose purpose, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
-        boolean handled = false;
-        switch (purpose) {
-        /* StaticNatRule would be applied by Firewall provider, since the incompatible of two object */
-        case StaticNat:
-        case Firewall:
-                for (FirewallServiceProvider fwElement : _firewallElements) {
-                Network.Provider provider = fwElement.getProvider();
-                boolean  isFwProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider);
-                if (!isFwProvider) {
-                    continue;
-                }
-                handled = fwElement.applyFWRules(network, rules);
-                if (handled)
-                    break;
-            }
-            break;
-        case PortForwarding:
-                for (PortForwardingServiceProvider element : _pfElements) {
-                Network.Provider provider = element.getProvider();
-                boolean  isPfProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.PortForwarding, provider);
-                if (!isPfProvider) {
-                    continue;
-                }
-                    handled = element.applyPFRules(network, (List<PortForwardingRule>)rules);
-                if (handled)
-                    break;
-            }
-            break;
-            /*        case NetworkACL:
-            for (NetworkACLServiceProvider element: _networkAclElements) {
-                Network.Provider provider = element.getProvider();
-                boolean  isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
-                if (!isAclProvider) {
-                    continue;
-                }
-                handled = element.applyNetworkACLs(network, rules);
-                if (handled)
-                    break;
-            }
-            break;*/
-        default:
-                assert (false) : "Unexpected fall through in applying rules to the network elements";
-            s_logger.error("FirewallManager cannot process rules of type " + purpose);
-            throw new CloudRuntimeException("FirewallManager cannot process rules of type " + purpose);
-        }
-        return handled;
-    }
-
-    @Override
-    public void removeRule(FirewallRule rule) {
-
-        //remove the rule
-        _firewallDao.remove(rule.getId());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", async = true)
-    public boolean applyIngressFwRules(long ipId, Account caller) throws ResourceUnavailableException {
-        return applyIngressFirewallRules(ipId, caller);
-    }
-
-    @Override
-    public boolean applyIngressFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
-        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
-        return applyFirewallRules(rules, false, caller);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule", async = true)
-    public boolean applyEgressFirewallRules(FirewallRule rule, Account caller) throws ResourceUnavailableException {
-                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
-                return applyFirewallRules(rules, false, caller);
-    }
-
-    @Override
-    public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
-
-        if (rules.size() == 0) {
-            s_logger.debug("There are no firewall rules to apply");
-            return true;
-        }
-
-        for (FirewallRuleVO rule : rules) {
-            // load cidrs if any
-            rule.setSourceCidrList(_firewallCidrsDao.getSourceCidrs(rule.getId()));
-            rule.setDestinationCidrsList(_firewallDcidrsDao.getDestCidrs(rule.getId()));
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, rules.toArray(new FirewallRuleVO[rules.size()]));
-        }
-
-        try {
-            if (!applyRules(rules, continueOnError, true)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply firewall rules due to : "+ ex.getMessage());
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyDefaultEgressFirewallRule(Long networkId, boolean defaultPolicy, boolean add) throws ResourceUnavailableException {
-
-        s_logger.debug("applying default firewall egress rules ");
-
-        NetworkVO network = _networkDao.findById(networkId);
-        List<String> sourceCidr = new ArrayList<String>();
-        List<String> destCidr = new ArrayList<String>();
-
-
-        sourceCidr.add(network.getCidr());
-        destCidr.add(NetUtils.ALL_IP4_CIDRS);
-
-        FirewallRuleVO ruleVO =
-            new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr, destCidr, null, null, null,
-                FirewallRule.TrafficType.Egress, FirewallRuleType.System);
-        ruleVO.setState(add ? State.Add : State.Revoke);
-        List<FirewallRuleVO> rules = new ArrayList<FirewallRuleVO>();
-        rules.add(ruleVO);
-
-        try {
-            //this is not required to store in db because we don't to add this rule along with the normal rules
-            if (!applyRules(rules, false, false)) {
-                return  false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply default egress rules for guest network due to ", ex);
-            return false;
-        }
-        return true;
-    }
-
-    protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {
-
-        FirewallRuleVO rule = _firewallDao.findById(ruleId);
-        if (rule == null || rule.getPurpose() != Purpose.Firewall) {
-            throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
-        }
-
-        if (rule.getType() == FirewallRuleType.System && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new InvalidParameterValueException("Only root admin can delete the system wide firewall rule");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        revokeRule(rule, caller, userId, false);
-
-        boolean success = false;
-        Long networkId = rule.getNetworkId();
-
-        if (apply) {
-            // ingress firewall rule
-            if (rule.getSourceIpAddressId() != null) {
-                //feteches ingress firewall, ingress firewall rules associated with the ip
-            List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
-            return applyFirewallRules(rules, false, caller);
-                //egress firewall rule
-            } else if (networkId != null) {
-                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
-                return applyFirewallRules(rules, false, caller);
-            }
-        } else {
-            success = true;
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
-    public boolean revokeIngressFwRule(long ruleId, boolean apply) {
-        return revokeIngressFirewallRule(ruleId, apply);
-    }
-
-
-    @Override
-    public boolean revokeIngressFirewallRule(long ruleId, boolean apply) {
-        Account caller = CallContext.current().getCallingAccount();
-        long userId = CallContext.current().getCallingUserId();
-        return revokeFirewallRule(ruleId, apply, caller, userId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_CLOSE, eventDescription = "revoking egress firewall rule", async = true)
-    public boolean revokeEgressFirewallRule(long ruleId, boolean apply) {
-        Account caller = CallContext.current().getCallingAccount();
-        long userId = CallContext.current().getCallingUserId();
-        return revokeFirewallRule(ruleId, apply, caller, userId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_UPDATE, eventDescription = "updating firewall rule", async = true)
-    public FirewallRule updateIngressFirewallRule(long ruleId, String customId, Boolean forDisplay) {
-        Account caller = CallContext.current().getCallingAccount();
-        return updateFirewallRule(ruleId, customId, caller, forDisplay);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_UPDATE, eventDescription = "updating egress firewall rule", async = true)
-    public FirewallRule updateEgressFirewallRule(long ruleId, String customId, Boolean forDisplay) {
-        Account caller = CallContext.current().getCallingAccount();
-        return updateFirewallRule(ruleId, customId, caller, forDisplay);
-    }
-
-    protected FirewallRule updateFirewallRule(long ruleId, String customId, Account caller, Boolean forDisplay) {
-        FirewallRuleVO rule = _firewallDao.findById(ruleId);
-        if (rule == null || rule.getPurpose() != Purpose.Firewall) {
-            throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
-        }
-
-        if (rule.getType() == FirewallRuleType.System && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            throw new InvalidParameterValueException("Only root admin can update the system wide firewall rule");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        if (customId != null) {
-            rule.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            rule.setDisplay(forDisplay);
-        }
-
-        _firewallDao.update(ruleId, rule);
-
-        return _firewallDao.findById(ruleId);
-    }
-
-    @Override
-    @DB
-    public void revokeRule(final FirewallRuleVO rule, Account caller, long userId, final boolean needUsageEvent) {
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, rule);
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-        boolean generateUsageEvent = false;
-
-        if (rule.getState() == State.Staged) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule);
-            }
-            removeRule(rule);
-            generateUsageEvent = true;
-        } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
-            rule.setState(State.Revoke);
-            _firewallDao.update(rule.getId(), rule);
-            generateUsageEvent = true;
-        }
-
-        if (generateUsageEvent && needUsageEvent) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), null, rule.getClass().getName(),
-                        rule.getUuid());
-        }
-            }
-        });
-    }
-
-    @Override
-    public FirewallRule getFirewallRule(long ruleId) {
-        return _firewallDao.findById(ruleId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
-    public boolean revokeFirewallRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
-        List<FirewallRule> rules = new ArrayList<FirewallRule>();
-
-        List<FirewallRuleVO> fwRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + fwRules.size() + " firewall rules for ip id=" + ipId);
-        }
-
-        for (FirewallRuleVO rule : fwRules) {
-            // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
-            // need to send them one by one
-            revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
-        }
-
-        // now send everything to the backend
-        List<FirewallRuleVO> rulesToApply = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
-        //apply rules
-        if (!applyFirewallRules(rulesToApply, rulesContinueOnErrFlag, caller)) {
-            if (!rulesContinueOnErrFlag) {
-                return false;
-            }
-        }
-        // Now we check again in case more rules have been inserted.
-        rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall));
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully released firewall rules for ip id=" + ipId + " and # of rules now = " + rules.size());
-        }
-
-        return rules.size() == 0;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
-    public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType,
-        Long relatedRuleId, long networkId) throws NetworkRuleConflictException {
-
-        // If firwallRule for this port range already exists, return it
-        List<FirewallRuleVO> rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, protocol, Purpose.Firewall);
-        if (!rules.isEmpty()) {
-            return rules.get(0);
-        }
-
-        List<String> oneCidr = new ArrayList<String>();
-        oneCidr.add(NetUtils.ALL_IP4_CIDRS);
-        return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, null, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User,
-            networkId, FirewallRule.TrafficType.Ingress, true);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
-    public boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
-        List<FirewallRule> rules = new ArrayList<FirewallRule>();
-
-        List<FirewallRuleVO> fwRules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + fwRules.size() + " firewall rules for network id=" + networkId);
-        }
-
-        for (FirewallRuleVO rule : fwRules) {
-            // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
-            // need to send them one by one
-            revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
-        }
-
-        // now send everything to the backend
-        List<FirewallRuleVO> rulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
-        boolean success = applyFirewallRules(rulesToApply, true, caller);
-
-        // Now we check again in case more rules have been inserted.
-        rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall));
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully released firewall rules for network id=" + networkId + " and # of rules now = " + rules.size());
-        }
-
-        return success && rules.size() == 0;
-    }
-
-    @Override
-    public boolean revokeRelatedFirewallRule(long ruleId, boolean apply) {
-        FirewallRule fwRule = _firewallDao.findByRelatedId(ruleId);
-
-        if (fwRule == null) {
-            s_logger.trace("No related firewall rule exists for rule id=" + ruleId + " so returning true here");
-            return true;
-        }
-
-        s_logger.debug("Revoking Firewall rule id=" + fwRule.getId() + " as a part of rule delete id=" + ruleId + " with apply=" + apply);
-        return revokeIngressFirewallRule(fwRule.getId(), apply);
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
-    public boolean revokeFirewallRulesForVm(long vmId) {
-        boolean success = true;
-        UserVmVO vm = _vmDao.findByIdIncludingRemoved(vmId);
-        if (vm == null) {
-            return false;
-        }
-
-        List<PortForwardingRuleVO> pfRules = _pfRulesDao.listByVm(vmId);
-        List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(vm.getId());
-        List<FirewallRuleVO> firewallRules = new ArrayList<FirewallRuleVO>();
-
-        // Make a list of firewall rules to reprogram
-        for (PortForwardingRuleVO pfRule : pfRules) {
-            FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(pfRule.getId());
-            if (relatedRule != null) {
-                firewallRules.add(relatedRule);
-            }
-        }
-
-        for (FirewallRuleVO staticNatRule : staticNatRules) {
-            FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(staticNatRule.getId());
-            if (relatedRule != null) {
-                firewallRules.add(relatedRule);
-            }
-        }
-
-        Set<Long> ipsToReprogram = new HashSet<Long>();
-
-        if (firewallRules.isEmpty()) {
-            s_logger.debug("No firewall rules are found for vm id=" + vmId);
-            return true;
-        } else {
-            s_logger.debug("Found " + firewallRules.size() + " to cleanup for vm id=" + vmId);
-        }
-
-        for (FirewallRuleVO rule : firewallRules) {
-            // Mark firewall rules as Revoked, but don't revoke it yet (apply=false)
-            revokeFirewallRule(rule.getId(), false, _accountMgr.getSystemAccount(), Account.ACCOUNT_ID_SYSTEM);
-            ipsToReprogram.add(rule.getSourceIpAddressId());
-        }
-
-        // apply rules for all ip addresses
-        for (Long ipId : ipsToReprogram) {
-            s_logger.debug("Applying firewall rules for ip address id=" + ipId + " as a part of vm expunge");
-            try {
-                success = success && applyIngressFirewallRules(ipId, _accountMgr.getSystemAccount());
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId);
-                success = false;
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
-    public boolean addSystemFirewallRules(IPAddressVO ip, Account acct) {
-        List<FirewallRuleVO> systemRules = _firewallDao.listSystemRules();
-        for (FirewallRuleVO rule : systemRules) {
-            try {
-                if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
-                    _firewallDao.loadSourceCidrs(rule);
-                }
-                createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(),null,
-                        rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getTrafficType(), true);
-            } catch (Exception e) {
-                s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
-            }
-        }
-        return true;
-    }
-
-    public List<FirewallServiceProvider> getFirewallElements() {
-        return _firewallElements;
-    }
-
-    @Inject
-    public void setFirewallElements(List<FirewallServiceProvider> firewallElements) {
-        _firewallElements = firewallElements;
-    }
-
-    public List<PortForwardingServiceProvider> getPfElements() {
-        return _pfElements;
-    }
-
-    @Inject
-    public void setPfElements(List<PortForwardingServiceProvider> pfElements) {
-        _pfElements = pfElements;
-    }
-
-    public List<StaticNatServiceProvider> getStaticNatElements() {
-        return _staticNatElements;
-    }
-
-    @Inject
-    public void setStaticNatElements(List<StaticNatServiceProvider> staticNatElements) {
-        _staticNatElements = staticNatElements;
-    }
-
-    public List<NetworkACLServiceProvider> getNetworkAclElements() {
-        return _networkAclElements;
-    }
-
-    @Inject
-    public void setNetworkAclElements(List<NetworkACLServiceProvider> networkAclElements) {
-        _networkAclElements = networkAclElements;
-    }
-
-}
diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java
deleted file mode 100644
index e3aabc1..0000000
--- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(ControlNetworkGuru.class);
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    NetworkModel _networkMgr;
-    String _cidr;
-    String _gateway;
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Control};
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    protected boolean canHandle(NetworkOffering offering) {
-        if (offering.isSystemOnly() && isMyTrafficType(offering.getTrafficType())) {
-            return true;
-        } else {
-            s_logger.trace("We only care about System only Control network");
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network specifiedConfig, Account owner) {
-        if (!canHandle(offering)) {
-            return null;
-        }
-
-        NetworkVO config =
-            new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.LinkLocal, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
-                plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        config.setCidr(_cidr);
-        config.setGateway(_gateway);
-
-        return config;
-    }
-
-    protected ControlNetworkGuru() {
-        super();
-    }
-
-    @Override
-    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-
-        if (vm.getHypervisorType() == HypervisorType.VMware && !isRouterVm(vm)) {
-            NicProfile nicProf = new NicProfile(Nic.ReservationStrategy.Create, null, null, null, null);
-            String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
-            nicProf.setMacAddress(mac);
-            return nicProf;
-        }
-
-        if (nic != null) {
-            throw new CloudRuntimeException("Does not support nic specification at this time: " + nic);
-        }
-
-        return new NicProfile(Nic.ReservationStrategy.Start, null, null, null, null);
-    }
-
-    @Override
-    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        assert nic.getTrafficType() == TrafficType.Control;
-
-        // we have to get management/private ip for the control nic for vmware/hyperv due ssh issues.
-        HypervisorType hType = vm.getHypervisorType();
-        if (((hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv)) && isRouterVm(vm)) {
-            if (dest.getDataCenter().getNetworkType() != NetworkType.Basic) {
-                super.reserve(nic, config, vm, dest, context);
-
-                String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
-                nic.setMacAddress(mac);
-                return;
-            } else {
-                // in basic mode and in VMware case, control network will be shared with guest network
-                String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
-                nic.setMacAddress(mac);
-                nic.setIPv4Address("0.0.0.0");
-                nic.setIPv4Netmask("0.0.0.0");
-                nic.setFormat(AddressFormat.Ip4);
-                nic.setIPv4Gateway("0.0.0.0");
-                return;
-            }
-        }
-
-        String ip = _dcDao.allocateLinkLocalIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId());
-        if (ip == null) {
-            throw new InsufficientAddressCapacityException("Insufficient link local address capacity", DataCenter.class, dest.getDataCenter().getId());
-        }
-        nic.setIPv4Address(ip);
-        nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40)));
-        nic.setIPv4Netmask("255.255.0.0");
-        nic.setFormat(AddressFormat.Ip4);
-        nic.setIPv4Gateway(NetUtils.getLinkLocalGateway());
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        assert nic.getTrafficType() == TrafficType.Control;
-        HypervisorType hType = vm.getHypervisorType();
-        if ( ( (hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv) )&& isRouterVm(vm)) {
-            long dcId = vm.getVirtualMachine().getDataCenterId();
-            DataCenterVO dcVo = _dcDao.findById(dcId);
-            if (dcVo.getNetworkType() != NetworkType.Basic) {
-                super.release(nic, vm, reservationId);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Released nic: " + nic);
-                }
-                return true;
-            } else {
-                nic.deallocate();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Released nic: " + nic);
-                }
-                return true;
-            }
-        }
-
-        _dcDao.releaseLinkLocalIpAddress(nic.getId(), reservationId);
-
-        nic.deallocate();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Released nic: " + nic);
-        }
-
-        return true;
-    }
-
-    protected boolean isRouterVm(VirtualMachineProfile vm) {
-        return vm.getType() == VirtualMachine.Type.DomainRouter || vm.getType() == VirtualMachine.Type.InternalLoadBalancerVm;
-    }
-
-    @Override
-    public Network implement(Network config, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        assert config.getTrafficType() == TrafficType.Control : "Why are you sending this configuration to me " + config;
-        return config;
-    }
-
-    @Override
-    public void shutdown(NetworkProfile config, NetworkOffering offering) {
-        assert false : "Destroying a link local...Either you're out of your mind or something has changed.";
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        Map<String, String> dbParams = _configDao.getConfiguration(params);
-
-        _cidr = dbParams.get(Config.ControlCidr.toString());
-        if (_cidr == null) {
-            _cidr = "169.254.0.0/16";
-        }
-
-        _gateway = dbParams.get(Config.ControlGateway.toString());
-        if (_gateway == null) {
-            _gateway = NetUtils.getLinkLocalGateway();
-        }
-
-        s_logger.info("Control network setup: cidr=" + _cidr + "; gateway = " + _gateway);
-
-        return true;
-    }
-
-    @Override
-    public boolean trash(Network config, NetworkOffering offering) {
-        return true;
-    }
-
-}
diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java
deleted file mode 100644
index c8d3eec..0000000
--- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java
+++ /dev/null
@@ -1,408 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Ipv6AddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.user.Account;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.vm.Nic;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-
-
-public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(DirectNetworkGuru.class);
-
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    UserIpv6AddressDao _ipv6Dao;
-    @Inject
-    Ipv6AddressManager _ipv6Mgr;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-    @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
-    protected IsolationMethod[] _isolationMethods;
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Return true if the physical network isolation method contains the expected isolation method for this guru
-     */
-    protected boolean isMyIsolationMethod(PhysicalNetwork physicalNetwork) {
-        for (IsolationMethod m : _isolationMethods) {
-            List<String> isolationMethods = physicalNetwork.getIsolationMethods();
-            if (CollectionUtils.isNotEmpty(isolationMethods)) {
-                for (String method : isolationMethods) {
-                    if (method.equalsIgnoreCase(m.toString())) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    /**
-     * True for Advanced zones, with VXLAN isolation method and Security Groups enabled
-     */
-    private boolean isMyIsolationMethodVxlanWithSecurityGroups(NetworkOffering offering, DataCenter dc, PhysicalNetwork physnet) {
-        return dc.getNetworkType().equals(NetworkType.Advanced) &&
-                _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup) &&
-                physnet.getIsolationMethods().contains("VXLAN");
-    }
-
-    protected boolean canHandle(NetworkOffering offering, DataCenter dc, PhysicalNetwork physnet) {
-        // this guru handles only Guest networks in Advance zone with source nat service disabled
-        boolean vxlanWithSecurityGroups = isMyIsolationMethodVxlanWithSecurityGroups(offering, dc, physnet);
-        if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) &&
-                (isMyIsolationMethod(physnet) || vxlanWithSecurityGroups) && offering.getGuestType() == GuestType.Shared
-                && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp)
-                && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NiciraNvp)) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of Guest networks of type " + GuestType.Shared);
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
-
-        if (!canHandle(offering, dc, physnet)) {
-            return null;
-        }
-
-        State state = State.Allocated;
-        if (dc.getNetworkType() == NetworkType.Basic) {
-            state = State.Setup;
-        }
-
-        NetworkVO config =
-            new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), state, plan.getDataCenterId(),
-                    plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-
-        if (userSpecified != null) {
-            if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
-                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
-            }
-
-            if ((userSpecified.getIp6Cidr() == null && userSpecified.getIp6Gateway() != null) ||
-                (userSpecified.getIp6Cidr() != null && userSpecified.getIp6Gateway() == null)) {
-                throw new InvalidParameterValueException("cidrv6 and gatewayv6 must be specified together.");
-            }
-
-            if (userSpecified.getCidr() != null) {
-                config.setCidr(userSpecified.getCidr());
-                config.setGateway(userSpecified.getGateway());
-            }
-
-            if (userSpecified.getIp6Cidr() != null) {
-                config.setIp6Cidr(userSpecified.getIp6Cidr());
-                config.setIp6Gateway(userSpecified.getIp6Gateway());
-            }
-
-            if (userSpecified.getBroadcastUri() != null) {
-                config.setBroadcastUri(userSpecified.getBroadcastUri());
-                config.setState(State.Setup);
-            }
-
-            if (userSpecified.getBroadcastDomainType() != null) {
-                config.setBroadcastDomainType(userSpecified.getBroadcastDomainType());
-            }
-        }
-
-        boolean isSecurityGroupEnabled = _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup);
-        if (isSecurityGroupEnabled) {
-            if (userSpecified.getIp6Cidr() != null) {
-                throw new InvalidParameterValueException("Didn't support security group with IPv6");
-            }
-            config.setName("SecurityGroupEnabledNetwork");
-            config.setDisplayText("SecurityGroupEnabledNetwork");
-        }
-
-        return config;
-    }
-
-    protected DirectNetworkGuru() {
-        super();
-        _isolationMethods = new IsolationMethod[] { new IsolationMethod("VLAN") };
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        if (profile != null) {
-            profile.setIPv4Dns1(dc.getDns1());
-            profile.setIPv4Dns2(dc.getDns2());
-            profile.setIPv6Dns1(dc.getIp6Dns1());
-            profile.setIPv6Dns2(dc.getIp6Dns2());
-        }
-    }
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-
-        if (nic == null) {
-            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
-        } else if (nic.getIPv4Address() == null && nic.getIPv6Address() == null) {
-            nic.setReservationStrategy(ReservationStrategy.Start);
-        } else {
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-
-        allocateDirectIp(nic, network, vm, dc, nic.getRequestedIPv4(), nic.getRequestedIPv6());
-        nic.setReservationStrategy(ReservationStrategy.Create);
-
-        if (nic.getMacAddress() == null) {
-            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
-            if (nic.getMacAddress() == null) {
-                throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
-            }
-        }
-
-        return nic;
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-        if (nic.getIPv4Address() == null && nic.getIPv6Address() == null) {
-            allocateDirectIp(nic, network, vm, dest.getDataCenter(), null, null);
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-    }
-
-    @DB
-    protected void allocateDirectIp(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DataCenter dc, final String requestedIp4Addr,
-        final String requestedIp6Addr) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-
-        try {
-            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientVirtualNetworkCapacityException,
-                        InsufficientAddressCapacityException {
-                    if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                        _ipAddrMgr.allocateNicValues(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr);
-                    } else {
-                        _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr);
-                        //save the placeholder nic if the vm is the Virtual router
-                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
-                            if (placeholderNic == null) {
-                                s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIPv4Address() + " and ipv6 address " + nic.getIPv6Address() +
-                                        " for the network " + network);
-                                _networkMgr.savePlaceholderNic(network, nic.getIPv4Address(), nic.getIPv6Address(), VirtualMachine.Type.DomainRouter);
-                            }
-                        }
-                    }
-                }
-            });
-        } catch (InsufficientCapacityException e) {
-            ExceptionUtil.rethrow(e, InsufficientVirtualNetworkCapacityException.class);
-            ExceptionUtil.rethrow(e, InsufficientAddressCapacityException.class);
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        return true;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        return network;
-    }
-
-    @Override
-    @DB
-    public void deallocate(final Network network, final NicProfile nic, VirtualMachineProfile vm) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
-        }
-
-        if (nic.getIPv4Address() != null) {
-            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
-            if (ip != null) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        // if the ip address a part of placeholder, don't release it
-                        Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
-                        if (placeholderNic != null && placeholderNic.getIPv4Address().equalsIgnoreCase(ip.getAddress().addr())) {
-                            s_logger.debug("Not releasing direct ip " + ip.getId() + " yet as its ip is saved in the placeholder");
-                        } else {
-                            _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                            _ipAddressDao.unassignIpAddress(ip.getId());
-                        }
-
-                        //unassign nic secondary ip address
-                        s_logger.debug("remove nic " + nic.getId() + " secondary ip ");
-                        List<String> nicSecIps = null;
-                        nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId());
-                        for (String secIp : nicSecIps) {
-                            IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp);
-                            _ipAddrMgr.markIpAsUnavailable(pubIp.getId());
-                            _ipAddressDao.unassignIpAddress(pubIp.getId());
-                        }
-                    }
-                });
-            }
-        }
-
-        if (nic.getIPv6Address() != null) {
-            _ipv6Mgr.revokeDirectIpv6Address(nic.getNetworkId(), nic.getIPv6Address());
-        }
-        nic.deallocate();
-    }
-
-    @Override
-    public void shutdown(NetworkProfile network, NetworkOffering offering) {
-    }
-
-    @Override
-    @DB
-    public boolean trash(Network network, NetworkOffering offering) {
-        //Have to remove all placeholder nics
-        try {
-            long id = network.getId();
-            final List<NicVO> nics = _nicDao.listPlaceholderNicsByNetworkId(id);
-            if (nics != null) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        for (Nic nic : nics) {
-                            if (nic.getIPv4Address() != null) {
-                                s_logger.debug("Releasing ip " + nic.getIPv4Address() + " of placeholder nic " + nic);
-                                IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
-                                if (ip != null) {
-                                    _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                                    _ipAddressDao.unassignIpAddress(ip.getId());
-                                    s_logger.debug("Removing placeholder nic " + nic);
-                                    _nicDao.remove(nic.getId());
-                                }
-                            }
-                        }
-                    }
-                });
-            }
-            return true;
-        }catch (Exception e) {
-            s_logger.error("trash. Exception:" + e.getMessage());
-            throw new CloudRuntimeException("trash. Exception:" + e.getMessage(),e);
-        }
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-        DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
-        networkProfile.setDns1(dc.getDns1());
-        networkProfile.setDns2(dc.getDns2());
-    }
-}
diff --git a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java
deleted file mode 100644
index a797b24..0000000
--- a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java
+++ /dev/null
@@ -1,252 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.googlecode.ipv6.IPv6Address;
-
-public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(DirectPodBasedNetworkGuru.class);
-
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    PodVlanMapDao _podVlanDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-
-    @Override
-    protected boolean canHandle(NetworkOffering offering, DataCenter dc, PhysicalNetwork physnet) {
-        // this guru handles system Direct pod based network in Basic zones only (no isolation type specified)
-        if (dc.getNetworkType() == NetworkType.Basic && isMyTrafficType(offering.getTrafficType())) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of Guest Direct Pod based networks");
-            return false;
-        }
-    }
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        DataCenterVO dc = _dcDao.findById(network.getDataCenterId());
-        ReservationStrategy rsStrategy = ReservationStrategy.Start;
-        _dcDao.loadDetails(dc);
-        String dhcpStrategy = dc.getDetail(ZoneConfig.DhcpStrategy.key());
-        if ("external".equalsIgnoreCase(dhcpStrategy)) {
-            rsStrategy = ReservationStrategy.Create;
-        }
-
-        if (nic != null && nic.getRequestedIPv4() != null) {
-            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
-        }
-
-        if (nic == null) {
-            nic = new NicProfile(rsStrategy, null, null, null, null);
-        } else if (nic.getIPv4Address() == null) {
-            nic.setReservationStrategy(ReservationStrategy.Start);
-        } else {
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-
-        if (rsStrategy == ReservationStrategy.Create) {
-            String mac = _networkModel.getNextAvailableMacAddressInNetwork(network.getId());
-            nic.setMacAddress(mac);
-        }
-        return nic;
-    }
-
-    @Override
-    @DB
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        String oldIp = nic.getIPv4Address();
-        boolean getNewIp = false;
-
-        if (oldIp == null) {
-            getNewIp = true;
-        } else {
-            // we need to get a new ip address if we try to deploy a vm in a different pod
-            final IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp);
-            if (ipVO != null) {
-                PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId());
-                if (mapVO.getPodId() != dest.getPod().getId()) {
-                    Transaction.execute(new TransactionCallbackNoReturn() {
-                        @Override
-                        public void doInTransactionWithoutResult(TransactionStatus status) {
-                            //release the old ip here
-                            _ipAddrMgr.markIpAsUnavailable(ipVO.getId());
-                            _ipAddressDao.unassignIpAddress(ipVO.getId());
-                        }
-                    });
-
-                    nic.setIPv4Address(null);
-                    getNewIp = true;
-                }
-            }
-        }
-
-        if (getNewIp) {
-            //we don't set reservationStrategy to Create because we need this method to be called again for the case when vm fails to deploy in Pod1, and we try to redeploy it in Pod2
-            getIp(nic, dest.getPod(), vm, network);
-        }
-
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        nic.setIPv4Dns1(dc.getDns1());
-        nic.setIPv4Dns2(dc.getDns2());
-    }
-
-    @DB
-    protected void getIp(final NicProfile nic, final Pod pod, final VirtualMachineProfile vm, final Network network) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-        final DataCenter dc = _dcDao.findById(pod.getDataCenterId());
-            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
-                    PublicIp ip = null;
-                    List<PodVlanMapVO> podRefs = _podVlanDao.listPodVlanMapsByPod(pod.getId());
-                    VlanVO vlan = _vlanDao.findById(podRefs.get(0).getVlanDbId());
-
-                    if (nic.getIPv4Address() == null) {
-                        String podRangeGateway = null;
-                        if (!podRefs.isEmpty()) {
-                            podRangeGateway = vlan.getVlanGateway();
-                        }
-                        //Get ip address from the placeholder and don't allocate a new one
-                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId());
-                            if (placeholderNic != null) {
-                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address());
-                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                                s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network +
-                                    " and gateway " + podRangeGateway);
-                            }
-                        }
-
-                        if (ip == null) {
-                            ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false, false);
-                        }
-
-                        nic.setIPv4Address(ip.getAddress().toString());
-                        nic.setFormat(AddressFormat.Ip4);
-                        nic.setIPv4Gateway(ip.getGateway());
-                        nic.setIPv4Netmask(ip.getNetmask());
-                        if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) {
-                            nic.setIsolationUri(IsolationType.Ec2.toUri(Vlan.UNTAGGED));
-                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED));
-                            nic.setBroadcastType(BroadcastDomainType.Native);
-                        }
-                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
-                        nic.setMacAddress(ip.getMacAddress());
-
-                        //save the placeholder nic if the vm is the Virtual router
-                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
-                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId());
-                            if (placeholderNic == null) {
-                                s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIPv4Address() + " for the network " + network);
-                                _networkMgr.savePlaceholderNic(network, nic.getIPv4Address(), null, VirtualMachine.Type.DomainRouter);
-                            }
-                        }
-                }
-
-                /**
-                 * Calculate the IPv6 Address the Instance will obtain using SLAAC and IPv6 EUI-64
-                 *
-                 * Linux, FreeBSD and Windows all calculate the same IPv6 address when configured properly.
-                 *
-                 * Using Router Advertisements the routers in the network should announce the IPv6 CIDR which is configured
-                 * in in the vlan table in the database.
-                 *
-                 * This way the NIC will be populated with a IPv6 address on which the Instance is reachable.
-                 */
-                if (vlan.getIp6Cidr() != null) {
-                    if (nic.getIPv6Address() == null) {
-                        s_logger.debug("Found IPv6 CIDR " + vlan.getIp6Cidr() + " for VLAN " + vlan.getId());
-                        nic.setIPv6Cidr(vlan.getIp6Cidr());
-                        nic.setIPv6Gateway(vlan.getIp6Gateway());
-
-                        IPv6Address ipv6addr = NetUtils.EUI64Address(vlan.getIp6Cidr(), nic.getMacAddress());
-                        s_logger.info("Calculated IPv6 address " + ipv6addr + " using EUI-64 for NIC " + nic.getUuid());
-                        nic.setIPv6Address(ipv6addr.toString());
-                    }
-                } else {
-                    s_logger.debug("No IPv6 CIDR configured for VLAN " + vlan.getId());
-                }
-            }
-        });
-
-        nic.setIPv4Dns1(dc.getDns1());
-        nic.setIPv4Dns2(dc.getDns2());
-    }
-
-}
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
deleted file mode 100644
index 6908a10..0000000
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ /dev/null
@@ -1,332 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.State;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.FirewallRulesCidrsDao;
-import com.cloud.network.dao.FirewallRulesCidrsVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.util.List;
-
-public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(ExternalGuestNetworkGuru.class);
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    DataCenterDao _zoneDao;
-    @Inject
-    PortForwardingRulesDao _pfRulesDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    FirewallRulesDao _fwRulesDao;
-    @Inject
-    FirewallRulesCidrsDao _fwRulesCidrDao;
-
-    public ExternalGuestNetworkGuru() {
-        super();
-        _isolationMethods = new IsolationMethod[] {new IsolationMethod("GRE"), new IsolationMethod("L3"), new IsolationMethod("VLAN")};
-    }
-
-    @Override
-    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
-        // This guru handles only Guest Isolated network that supports Source
-        // nat service
-        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType())
-                && (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == GuestType.L2)
-                && isMyIsolationMethod(physicalNetwork) && !offering.isSystemOnly()) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-
-        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.Connectivity)) {
-            return null;
-        }
-
-        NetworkVO config = (NetworkVO)super.design(offering, plan, userSpecified, owner);
-        if (config == null) {
-            return null;
-        } else if (_networkModel.networkIsConfiguredForExternalNetworking(plan.getDataCenterId(), config.getId())) {
-            /* In order to revert userSpecified network setup */
-            config.setState(State.Allocated);
-        }
-
-        return config;
-    }
-
-    @Override
-    public Network implement(Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        assert (config.getState() == State.Implementing) : "Why are we implementing " + config;
-
-        if (_networkModel.areServicesSupportedInNetwork(config.getId(), Network.Service.Connectivity)) {
-            return null;
-        }
-
-        if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
-            return super.implement(config, offering, dest, context);
-        }
-
-        DataCenter zone = dest.getDataCenter();
-        NetworkVO implemented =
-            new NetworkVO(config.getTrafficType(), config.getMode(), config.getBroadcastDomainType(), config.getNetworkOfferingId(), State.Allocated,
-                config.getDataCenterId(), config.getPhysicalNetworkId(), offering.getRedundantRouter());
-
-        // Get a vlan tag
-        int vlanTag;
-        if (config.getBroadcastUri() == null) {
-            String vnet =
-                _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), context.getReservationId(),
-                    UseSystemGuestVlans.valueIn(config.getAccountId()));
-
-            try {
-                // when supporting more types of networks this need to become
-//              int vlantag = Integer.parseInt(BroadcastDomainType.getValue(vnet));
-                vlanTag = Integer.parseInt(vnet);
-            } catch (NumberFormatException e) {
-                throw new CloudRuntimeException("Obtained an invalid guest vlan tag. Exception: " + e.getMessage());
-            }
-
-            implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanTag));
-            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), config.getAccountId(), EventVO.LEVEL_INFO,
-                EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + config.getId(), 0);
-        } else {
-            vlanTag = Integer.parseInt(BroadcastDomainType.getValue(config.getBroadcastUri()));
-            implemented.setBroadcastUri(config.getBroadcastUri());
-        }
-
-        // Determine the new gateway and CIDR
-        String[] oldCidr = config.getCidr().split("/");
-        String oldCidrAddress = oldCidr[0];
-        int cidrSize = Integer.parseInt(oldCidr[1]);
-        long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress));
-        // if the implementing network is for vpc, no need to generate newcidr, use the cidr that came from super cidr
-        if (config.getVpcId() != null) {
-            implemented.setGateway(config.getGateway());
-            implemented.setCidr(config.getCidr());
-            implemented.setState(State.Implemented);
-        } else {
-            // Determine the offset from the lowest vlan tag
-            int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag);
-            cidrSize = getGloballyConfiguredCidrSize();
-            // If the offset has more bits than there is room for, return null
-            long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset);
-            if (bitsInOffset > (cidrSize - 8)) {
-                throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with.");
-            }
-            newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize));
-            implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1));
-            implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize);
-            implemented.setState(State.Implemented);
-        }
-
-        // Mask the Ipv4 address of all nics that use this network with the new guest VLAN offset
-        List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(config.getId());
-        for (NicVO nic : nicsInNetwork) {
-            if (nic.getIPv4Address() != null) {
-                long ipMask = getIpMask(nic.getIPv4Address(), cidrSize);
-                nic.setIPv4Address(NetUtils.long2Ip(newCidrAddress | ipMask));
-                _nicDao.persist(nic);
-            }
-        }
-
-        // Mask the destination address of all port forwarding rules in this network with the new guest VLAN offset
-        List<PortForwardingRuleVO> pfRulesInNetwork = _pfRulesDao.listByNetwork(config.getId());
-        for (PortForwardingRuleVO pfRule : pfRulesInNetwork) {
-            if (pfRule.getDestinationIpAddress() != null) {
-                long ipMask = getIpMask(pfRule.getDestinationIpAddress().addr(), cidrSize);
-                String maskedDestinationIpAddress = NetUtils.long2Ip(newCidrAddress | ipMask);
-                pfRule.setDestinationIpAddress(new Ip(maskedDestinationIpAddress));
-                _pfRulesDao.update(pfRule.getId(), pfRule);
-            }
-        }
-        // Mask the destination address of all static nat rules in this network with the new guest VLAN offset
-        // Here the private ip of the nic get updated. When secondary ip are present the gc will not triggered
-        List<IPAddressVO> ipAddrsOfNw = _ipAddressDao.listStaticNatPublicIps(config.getId());
-        for (IPAddressVO ip : ipAddrsOfNw) {
-            if (ip.getVmIp() != null) {
-                long ipMask = getIpMask(ip.getVmIp(), cidrSize);
-                String maskedVmIp = NetUtils.long2Ip(newCidrAddress | ipMask);
-                ip.setVmIp(maskedVmIp);
-                _ipAddressDao.update(ip.getId(), ip);
-            }
-        }
-
-        //Egress rules cidr is subset of guest nework cidr, we need to change
-        List <FirewallRuleVO> fwEgressRules = _fwRulesDao.listByNetworkPurposeTrafficType(config.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress);
-
-        for (FirewallRuleVO rule: fwEgressRules) {
-            //get the cidr list for this rule
-            List<FirewallRulesCidrsVO>  fwRuleCidrsVo = _fwRulesCidrDao.listByFirewallRuleId(rule.getId());
-
-            for (FirewallRulesCidrsVO ruleCidrvo: fwRuleCidrsVo) {
-                String cidr = ruleCidrvo.getCidr();
-                String cidrAddr =  cidr.split("/")[0];
-                String size = cidr.split("/")[1];
-
-                long ipMask = getIpMask(cidrAddr, cidrSize);
-                String newIp = NetUtils.long2Ip(newCidrAddress | ipMask);
-                String updatedCidr = newIp+"/"+size;
-
-                ruleCidrvo.setSourceCidrList(updatedCidr);
-                _fwRulesCidrDao.update(ruleCidrvo.getId(), ruleCidrvo);
-            }
-
-        }
-
-
-        return implemented;
-    }
-
-    @Override
-    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-
-        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId()) && nic != null && nic.getRequestedIPv4() != null) {
-            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
-        }
-
-        NicProfile profile = super.allocate(config, nic, vm);
-
-        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
-            profile.setReservationStrategy(ReservationStrategy.Start);
-            /* We won't clear IP address, because router may set gateway as it IP, and it would be updated properly later */
-            //profile.setIp4Address(null);
-            profile.setIPv4Gateway(null);
-            profile.setIPv4Netmask(null);
-        }
-
-        return profile;
-    }
-
-    @Override
-    @DB
-    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
-        super.deallocate(config, nic, vm);
-
-        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
-            nic.setIPv4Address(null);
-            nic.setIPv4Gateway(null);
-            nic.setIPv4Netmask(null);
-            nic.setBroadcastUri(null);
-            nic.setIsolationUri(null);
-        }
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? ";
-
-        DataCenter dc = _dcDao.findById(config.getDataCenterId());
-
-        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
-            nic.setBroadcastUri(config.getBroadcastUri());
-            nic.setIsolationUri(config.getBroadcastUri());
-            nic.setIPv4Dns1(dc.getDns1());
-            nic.setIPv4Dns2(dc.getDns2());
-            nic.setIPv4Netmask(NetUtils.cidr2Netmask(config.getCidr()));
-            long cidrAddress = NetUtils.ip2Long(config.getCidr().split("/")[0]);
-            int cidrSize = getGloballyConfiguredCidrSize();
-            nic.setIPv4Gateway(config.getGateway());
-
-            if (nic.getIPv4Address() == null) {
-                if (!_networkModel.listNetworkOfferingServices(config.getNetworkOfferingId()).isEmpty()) {
-                    String guestIp = _ipAddrMgr.acquireGuestIpAddress(config, null);
-                    if (guestIp == null) {
-                        throw new InsufficientVirtualNetworkCapacityException("Unable to acquire guest IP address for network " + config, DataCenter.class, dc.getId());
-                    }
-
-                    nic.setIPv4Address(guestIp);
-                }
-            } else {
-                long ipMask = NetUtils.ip2Long(nic.getIPv4Address()) & ~(0xffffffffffffffffl << (32 - cidrSize));
-                nic.setIPv4Address(NetUtils.long2Ip(cidrAddress | ipMask));
-            }
-        } else {
-            super.reserve(nic, config, vm, dest, context);
-        }
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-
-        NetworkVO network = _networkDao.findById(nic.getNetworkId());
-
-        if (network != null && _networkModel.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
-            return true;
-        } else {
-            return super.release(nic, vm, reservationId);
-        }
-    }
-
-    private long getIpMask(String ipAddress, long cidrSize) {
-        return NetUtils.ip2Long(ipAddress) & ~(0xffffffffffffffffl << (32 - cidrSize));
-    }
-
-}
diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
deleted file mode 100644
index 3f6562e..0000000
--- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
+++ /dev/null
@@ -1,465 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import javax.inject.Inject;
-
-import com.cloud.network.Network.GuestType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetwork.IsolationMethod;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.user.Account;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicDao;
-
-public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGuru, Configurable {
-    private static final Logger s_logger = Logger.getLogger(GuestNetworkGuru.class);
-
-    @Inject
-    protected VpcDao _vpcDao;
-    @Inject
-    protected NetworkOrchestrationService _networkMgr;
-    @Inject
-    protected NetworkModel _networkModel;
-    @Inject
-    protected DataCenterDao _dcDao;
-    @Inject
-    protected VlanDao _vlanDao;
-    @Inject
-    protected NicDao _nicDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    protected NetworkDao _networkDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    protected PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    ConfigurationServer _configServer;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    Random _rand = new Random(System.currentTimeMillis());
-
-    static final ConfigKey<Boolean> UseSystemGuestVlans =
-            new ConfigKey<Boolean>(
-                    "Advanced",
-                    Boolean.class,
-                    "use.system.guest.vlans",
-                    "true",
-                    "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool",
-                    false, ConfigKey.Scope.Account);
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
-
-    // Currently set to anything except STT for the Nicira integration.
-    protected IsolationMethod[] _isolationMethods;
-
-    String _defaultGateway;
-    String _defaultCidr;
-
-    protected GuestNetworkGuru() {
-        super();
-        _isolationMethods = null;
-    }
-
-    @Override
-    public boolean isMyTrafficType(final TrafficType type) {
-        for (final TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    public boolean isMyIsolationMethod(final PhysicalNetwork physicalNetwork) {
-        if (physicalNetwork == null) {
-            // Can't tell if there is no physical network
-            return false;
-        }
-
-        List<String> methods = new ArrayList<String>();
-        for (final String method : physicalNetwork.getIsolationMethods()) {
-            methods.add(method.toLowerCase());
-        }
-        if (methods.isEmpty()) {
-            // The empty isolation method is assumed to be VLAN
-            s_logger.debug("Empty physical isolation type for physical network " + physicalNetwork.getUuid());
-            methods = new ArrayList<String>(1);
-            methods.add("VLAN".toLowerCase());
-        }
-
-        for (final IsolationMethod m : _isolationMethods) {
-            if (methods.contains(m.toString().toLowerCase())) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public IsolationMethod[] getIsolationMethods() {
-        return _isolationMethods;
-    }
-
-    protected abstract boolean canHandle(NetworkOffering offering, final NetworkType networkType, PhysicalNetwork physicalNetwork);
-
-    @Override
-    public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) {
-        final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-        final PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
-
-        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
-            return null;
-        }
-
-        final NetworkVO network =
-                new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(),
-                        plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        if (userSpecified != null) {
-            if (userSpecified.getCidr() == null && userSpecified.getGateway() != null || userSpecified.getCidr() != null && userSpecified.getGateway() == null) {
-                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
-            }
-
-            if (userSpecified.getCidr() != null) {
-                network.setCidr(userSpecified.getCidr());
-                network.setGateway(userSpecified.getGateway());
-            } else if (offering.getGuestType() != GuestType.L2 && (offering.getGuestType() == GuestType.Shared || !_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty())) {
-                final String guestNetworkCidr = dc.getGuestNetworkCidr();
-                if (guestNetworkCidr != null) {
-                    final String[] cidrTuple = guestNetworkCidr.split("\\/");
-                    network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
-                    network.setCidr(guestNetworkCidr);
-                } else if (dc.getNetworkType() == NetworkType.Advanced) {
-                    throw new CloudRuntimeException("Can't design network " + network + "; guest CIDR is not configured per zone " + dc);
-                }
-            }
-
-            if (offering.getSpecifyVlan()) {
-                network.setBroadcastUri(userSpecified.getBroadcastUri());
-                network.setState(State.Setup);
-            }
-        } else {
-            final String guestNetworkCidr = dc.getGuestNetworkCidr();
-            if (guestNetworkCidr == null && dc.getNetworkType() == NetworkType.Advanced) {
-                throw new CloudRuntimeException("Can't design network " + network + "; guest CIDR is not configured per zone " + dc);
-            }
-            final String[] cidrTuple = guestNetworkCidr.split("\\/");
-            network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
-            network.setCidr(guestNetworkCidr);
-        }
-
-        return network;
-    }
-
-    @Override
-    @DB
-    public void deallocate(final Network network, final NicProfile nic, final VirtualMachineProfile vm) {
-        if (network.getSpecifyIpRanges()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
-            }
-
-            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
-            if (ip != null) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                        _ipAddressDao.unassignIpAddress(ip.getId());
-                    }
-                });
-            }
-            nic.deallocate();
-        }
-    }
-
-    public int getVlanOffset(final long physicalNetworkId, final int vlanTag) {
-        final PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (pNetwork == null) {
-            throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
-        }
-
-        if (pNetwork.getVnet() == null) {
-            throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
-        }
-        Integer lowestVlanTag = null;
-        final List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
-        //finding the vlanrange in which the vlanTag lies.
-        for (final Pair<Integer, Integer> vnet : vnetList) {
-            if (vlanTag >= vnet.first() && vlanTag <= vnet.second()) {
-                lowestVlanTag = vnet.first();
-            }
-        }
-        if (lowestVlanTag == null) {
-            throw new InvalidParameterValueException("The vlan tag does not belong to any of the existing vlan ranges");
-        }
-        return vlanTag - lowestVlanTag;
-    }
-
-    public int getGloballyConfiguredCidrSize() {
-        try {
-            final String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
-            return 8 + Integer.parseInt(globalVlanBits);
-        } catch (final Exception e) {
-            throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
-        }
-    }
-
-    protected void allocateVnet(final Network network, final NetworkVO implemented, final long dcId, final long physicalNetworkId, final String reservationId)
-            throws InsufficientVirtualNetworkCapacityException {
-        if (network.getBroadcastUri() == null) {
-            final String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, UseSystemGuestVlans.valueIn(network.getAccountId()));
-            if (vnet == null) {
-                throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class,
-                        dcId);
-            }
-            implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet));
-            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO,
-                    EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0);
-        } else {
-            implemented.setBroadcastUri(network.getBroadcastUri());
-        }
-    }
-
-    @Override
-    public Network implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context)
-            throws InsufficientVirtualNetworkCapacityException {
-        assert network.getState() == State.Implementing : "Why are we implementing " + network;
-
-        final long dcId = dest.getDataCenter().getId();
-
-        //get physical network id
-        Long physicalNetworkId = network.getPhysicalNetworkId();
-
-        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
-        if (physicalNetworkId == null) {
-            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
-        }
-
-        final NetworkVO implemented =
-                new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
-                        network.getDataCenterId(), physicalNetworkId, offering.getRedundantRouter());
-
-        allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
-
-        if (network.getGateway() != null) {
-            implemented.setGateway(network.getGateway());
-        }
-
-        if (network.getCidr() != null) {
-            implemented.setCidr(network.getCidr());
-        }
-        return implemented;
-    }
-
-    @Override
-    public NicProfile allocate(final Network network, NicProfile nic, final VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-    InsufficientAddressCapacityException {
-
-        assert network.getTrafficType() == TrafficType.Guest : "Look at my name!  Why are you calling" + " me when the traffic type is : " + network.getTrafficType();
-
-        if (nic == null) {
-            nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);
-        }
-
-        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
-
-        if (nic.getIPv4Address() == null) {
-            nic.setBroadcastUri(network.getBroadcastUri());
-            nic.setIsolationUri(network.getBroadcastUri());
-            nic.setIPv4Gateway(network.getGateway());
-
-            String guestIp = null;
-            if (network.getSpecifyIpRanges()) {
-                _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIPv4(), null);
-            } else {
-                //if Vm is router vm and source nat is enabled in the network, set ip4 to the network gateway
-                boolean isGateway = false;
-                if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
-                    if (network.getVpcId() != null) {
-                        final Vpc vpc = _vpcDao.findById(network.getVpcId());
-                        // Redundant Networks need a guest IP that is not the same as the gateway IP.
-                        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VPCVirtualRouter) && !vpc.isRedundant()) {
-                            isGateway = true;
-                        }
-                    } else {
-                        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VirtualRouter)) {
-                            isGateway = true;
-                        }
-                    }
-                }
-
-                if (isGateway) {
-                    guestIp = network.getGateway();
-                } else {
-                    guestIp = _ipAddrMgr.acquireGuestIpAddress(network, nic.getRequestedIPv4());
-                    if (guestIp == null && network.getGuestType() != GuestType.L2 && !_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
-                        throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class,
-                                dc.getId());
-                    }
-                }
-
-                nic.setIPv4Address(guestIp);
-                if (network.getCidr() != null) {
-                    nic.setIPv4Netmask(NetUtils.cidr2Netmask(_networkModel.getValidNetworkCidr(network)));
-                }
-
-                nic.setIPv4Dns1(dc.getDns1());
-                nic.setIPv4Dns2(dc.getDns2());
-                nic.setFormat(AddressFormat.Ip4);
-            }
-        }
-
-        nic.setReservationStrategy(ReservationStrategy.Start);
-
-        if (nic.getMacAddress() == null) {
-            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
-            if (nic.getMacAddress() == null) {
-                throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
-            }
-        }
-
-        return nic;
-    }
-
-    @Override
-    public void updateNicProfile(final NicProfile profile, final Network network) {
-        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        if (profile != null) {
-            profile.setIPv4Dns1(dc.getDns1());
-            profile.setIPv4Dns2(dc.getDns2());
-        }
-    }
-
-    @Override
-    public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
-            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        assert nic.getReservationStrategy() == ReservationStrategy.Start : "What can I do for nics that are not allocated at start? ";
-
-        nic.setBroadcastUri(network.getBroadcastUri());
-        nic.setIsolationUri(network.getBroadcastUri());
-    }
-
-    @Override
-    public boolean release(final NicProfile nic, final VirtualMachineProfile vm, final String reservationId) {
-        nic.setBroadcastUri(null);
-        nic.setIsolationUri(null);
-        return true;
-    }
-
-    @Override
-    public void shutdown(final NetworkProfile profile, final NetworkOffering offering) {
-        if (profile.getBroadcastUri() == null) {
-            return; // Nothing to do here if the uri is null already
-        }
-
-        if ((profile.getBroadcastDomainType() == BroadcastDomainType.Vlan || profile.getBroadcastDomainType() == BroadcastDomainType.Vxlan) && !offering.getSpecifyVlan()) {
-            s_logger.debug("Releasing vnet for the network id=" + profile.getId());
-            _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(),
-                    profile.getReservationId());
-            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE,
-                    "Released Zone Vnet: " + BroadcastDomainType.getValue(profile.getBroadcastUri()) + " for Network: " + profile.getId(), 0);
-        }
-
-        profile.setBroadcastUri(null);
-    }
-
-    @Override
-    public boolean trash(final Network network, final NetworkOffering offering) {
-        return true;
-    }
-
-    @Override
-    public void updateNetworkProfile(final NetworkProfile networkProfile) {
-        final DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
-        networkProfile.setDns1(dc.getDns1());
-        networkProfile.setDns2(dc.getDns2());
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return GuestNetworkGuru.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {UseSystemGuestVlans};
-    }
-}
diff --git a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java
deleted file mode 100644
index eb80c12..0000000
--- a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java
+++ /dev/null
@@ -1,182 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import com.cloud.dc.dao.DataCenterDao.PrivateAllocationData;
-import com.cloud.vm.VirtualMachine;
-import java.util.Random;
-
-import javax.inject.Inject;
-
-import com.cloud.network.NetworkModel;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.Pod;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.StorageNetworkManager;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(PodBasedNetworkGuru.class);
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    StorageNetworkManager _sNwMgr;
-
-    Random _rand = new Random(System.currentTimeMillis());
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Management};
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        TrafficType type = offering.getTrafficType();
-
-        if (!isMyTrafficType(type)) {
-            return null;
-        }
-
-        NetworkVO config =
-            new NetworkVO(type, Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
-                    plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        return config;
-    }
-
-    protected PodBasedNetworkGuru() {
-        super();
-    }
-
-    @Override
-    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
-    }
-
-    @Override
-    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-        TrafficType trafficType = config.getTrafficType();
-        assert trafficType == TrafficType.Management || trafficType == TrafficType.Storage : "Well, I can't take care of this config now can I? " + config;
-
-        if (nic != null) {
-            if (nic.getRequestedIPv4() != null) {
-                throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
-            }
-            nic.setReservationStrategy(nic.getIPv4Address() != null ? ReservationStrategy.Create : ReservationStrategy.Start);
-        } else {
-            nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);
-        }
-
-        return nic;
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        Pod pod = dest.getPod();
-
-        boolean forSystemVms = vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm);
-        PrivateAllocationData result = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId(), forSystemVms);
-        if (result == null) {
-            throw new InsufficientAddressCapacityException("Unable to get a management ip address", Pod.class, pod.getId());
-        }
-        Integer vlan = result.getVlan();
-
-        nic.setIPv4Address(result.getIpAddress());
-        nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(result.getMacAddress(), NetworkModel.MACIdentifier.value())));
-        nic.setIPv4Gateway(pod.getGateway());
-        nic.setFormat(AddressFormat.Ip4);
-        String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
-        nic.setIPv4Netmask(netmask);
-        nic.setBroadcastType(BroadcastDomainType.Native);
-        if (vlan != null) {
-            nic.setBroadcastUri(BroadcastDomainType.Native.toUri(vlan));
-        } else {
-            nic.setBroadcastUri(null);
-        }
-        nic.setIsolationUri(null);
-
-        s_logger.debug("Allocated a nic " + nic + " for " + vm);
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        _dcDao.releasePrivateIpAddress(nic.getId(), nic.getReservationId());
-
-        nic.deallocate();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Released nic: " + nic);
-        }
-
-        return true;
-    }
-
-    @Override
-    public Network implement(Network config, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        return config;
-    }
-
-    @Override
-    public void shutdown(NetworkProfile config, NetworkOffering offering) {
-    }
-
-    @Override
-    public boolean trash(Network config, NetworkOffering offering) {
-        return true;
-    }
-}
diff --git a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java
deleted file mode 100644
index 0cf2637..0000000
--- a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java
+++ /dev/null
@@ -1,245 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.vpc.PrivateIpAddress;
-import com.cloud.network.vpc.PrivateIpVO;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(PrivateNetworkGuru.class);
-    @Inject
-    protected ConfigurationManager _configMgr;
-    @Inject
-    protected PrivateIpDao _privateIpDao;
-    @Inject
-    protected NetworkModel _networkMgr;
-    @Inject
-    EntityManager _entityMgr;
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
-
-    protected PrivateNetworkGuru() {
-        super();
-    }
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    protected boolean canHandle(NetworkOffering offering, DataCenter dc) {
-        // This guru handles only system Guest network
-        if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated &&
-            offering.isSystemOnly()) {
-            return true;
-        } else {
-            s_logger.trace("We only take care of system Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        DataCenter dc = _entityMgr.findById(DataCenter.class, plan.getDataCenterId());
-        if (!canHandle(offering, dc)) {
-            return null;
-        }
-
-        BroadcastDomainType broadcastType;
-        if (userSpecified != null) {
-            broadcastType = userSpecified.getBroadcastDomainType();
-        } else {
-            broadcastType = BroadcastDomainType.Vlan;
-        }
-        NetworkVO network =
-            new NetworkVO(offering.getTrafficType(), Mode.Static, broadcastType, offering.getId(), State.Allocated, plan.getDataCenterId(),
-                    plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        if (userSpecified != null) {
-            if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
-                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
-            }
-
-            if (userSpecified.getCidr() != null) {
-                network.setCidr(userSpecified.getCidr());
-                network.setGateway(userSpecified.getGateway());
-            } else {
-                throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in");
-            }
-
-            if (offering.getSpecifyVlan()) {
-                network.setBroadcastUri(userSpecified.getBroadcastUri());
-                network.setState(State.Setup);
-            }
-        } else {
-            throw new CloudRuntimeException("Can't design network " + network + "; netmask/gateway must be passed in");
-
-        }
-
-        return network;
-    }
-
-    @Override
-    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
-        }
-
-        PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
-        if (ip != null) {
-            _privateIpDao.releaseIpAddress(nic.getIPv4Address(), nic.getNetworkId());
-        }
-        nic.deallocate();
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-
-        return network;
-    }
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-        DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-        if (!canHandle(offering, dc)) {
-            return null;
-        }
-
-        if (nic == null) {
-            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
-        }
-
-        getIp(nic, dc, network);
-
-        if (nic.getIPv4Address() == null) {
-            nic.setReservationStrategy(ReservationStrategy.Start);
-        } else {
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-
-        return nic;
-    }
-
-    protected void getIp(NicProfile nic, DataCenter dc, Network network) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        if (nic.getIPv4Address() == null) {
-            PrivateIpVO ipVO = _privateIpDao.allocateIpAddress(network.getDataCenterId(), network.getId(), null);
-            String vlanTag = BroadcastDomainType.getValue(network.getBroadcastUri());
-            String netmask = NetUtils.getCidrNetmask(network.getCidr());
-            PrivateIpAddress ip =
-                new PrivateIpAddress(ipVO, vlanTag, network.getGateway(), netmask, NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress(), NetworkModel.MACIdentifier.value())));
-
-            nic.setIPv4Address(ip.getIpAddress());
-            nic.setIPv4Gateway(ip.getGateway());
-            nic.setIPv4Netmask(ip.getNetmask());
-            nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getBroadcastUri()));
-            nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getBroadcastUri()));
-            nic.setBroadcastType(BroadcastDomainType.Vlan);
-            nic.setFormat(AddressFormat.Ip4);
-            nic.setReservationId(String.valueOf(ip.getBroadcastUri()));
-            nic.setMacAddress(ip.getMacAddress());
-        }
-
-        nic.setIPv4Dns1(dc.getDns1());
-        nic.setIPv4Dns2(dc.getDns2());
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-        DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
-        if (profile != null) {
-            profile.setIPv4Dns1(dc.getDns1());
-            profile.setIPv4Dns2(dc.getDns2());
-        }
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        if (nic.getIPv4Address() == null) {
-            getIp(nic, _entityMgr.findById(DataCenter.class, network.getDataCenterId()), network);
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        return true;
-    }
-
-    @Override
-    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
-
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        return true;
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-        DataCenter dc = _entityMgr.findById(DataCenter.class, networkProfile.getDataCenterId());
-        networkProfile.setDns1(dc.getDns1());
-        networkProfile.setDns2(dc.getDns2());
-    }
-}
diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java
deleted file mode 100644
index 96146f0..0000000
--- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java
+++ /dev/null
@@ -1,239 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.State;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(PublicNetworkGuru.class);
-
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Public};
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    protected boolean canHandle(NetworkOffering offering) {
-        return isMyTrafficType(offering.getTrafficType()) && offering.isSystemOnly();
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network network, Account owner) {
-        if (!canHandle(offering)) {
-            return null;
-        }
-
-        if (offering.getTrafficType() == TrafficType.Public) {
-            NetworkVO ntwk =
-                new NetworkVO(offering.getTrafficType(), Mode.Static, network.getBroadcastDomainType(), offering.getId(), State.Setup, plan.getDataCenterId(),
-                    plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-            return ntwk;
-        } else {
-            return null;
-        }
-    }
-
-    protected PublicNetworkGuru() {
-        super();
-    }
-
-    protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-        if (nic.getIPv4Address() == null) {
-            boolean forSystemVms = false;
-            if (vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) {
-                forSystemVms = true;
-            }
-            PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null, null, false, forSystemVms);
-            nic.setIPv4Address(ip.getAddress().toString());
-            nic.setIPv4Gateway(ip.getGateway());
-            nic.setIPv4Netmask(ip.getNetmask());
-            if (network.getBroadcastDomainType() == BroadcastDomainType.Vxlan) {
-                nic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag()));
-                nic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag()));
-                nic.setBroadcastType(BroadcastDomainType.Vxlan);
-            } else {
-                nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
-                nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
-                nic.setBroadcastType(BroadcastDomainType.Vlan);
-            }
-            nic.setFormat(AddressFormat.Ip4);
-            nic.setReservationId(String.valueOf(ip.getVlanTag()));
-            nic.setMacAddress(ip.getMacAddress());
-        }
-
-        nic.setIPv4Dns1(dc.getDns1());
-        nic.setIPv4Dns2(dc.getDns2());
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        if (profile != null) {
-            profile.setIPv4Dns1(dc.getDns1());
-            profile.setIPv4Dns2(dc.getDns2());
-        }
-    }
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-
-        if (nic != null && nic.getRequestedIPv4() != null) {
-            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
-        }
-
-        if (nic == null) {
-            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
-        }
-
-        getIp(nic, dc, vm, network);
-
-        if (nic.getIPv4Address() == null) {
-            nic.setReservationStrategy(ReservationStrategy.Start);
-        } else if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
-            nic.setReservationStrategy(ReservationStrategy.Managed);
-        } else {
-            nic.setReservationStrategy(ReservationStrategy.Create);
-        }
-
-        return nic;
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-        if (nic.getIPv4Address() == null) {
-            getIp(nic, dest.getDataCenter(), vm, network);
-        }
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        return true;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        return network;
-    }
-
-    @Override
-    @DB
-    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("public network deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
-        }
-
-        final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
-        if (ip != null && nic.getReservationStrategy() != ReservationStrategy.Managed) {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                    _ipAddressDao.unassignIpAddress(ip.getId());
-                }
-            });
-        }
-        nic.deallocate();
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deallocated nic: " + nic);
-        }
-    }
-
-    @Override
-    public void shutdown(NetworkProfile network, NetworkOffering offering) {
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        return true;
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-        DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
-        networkProfile.setDns1(dc.getDns1());
-        networkProfile.setDns2(dc.getDns2());
-    }
-
-}
diff --git a/server/src/com/cloud/network/guru/StorageNetworkGuru.java b/server/src/com/cloud/network/guru/StorageNetworkGuru.java
deleted file mode 100644
index 2a51a82..0000000
--- a/server/src/com/cloud/network/guru/StorageNetworkGuru.java
+++ /dev/null
@@ -1,192 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import javax.inject.Inject;
-
-import com.cloud.network.NetworkModel;
-import org.apache.log4j.Logger;
-
-import com.cloud.dc.Pod;
-import com.cloud.dc.StorageNetworkIpAddressVO;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.StorageNetworkManager;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.user.Account;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic.ReservationStrategy;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachineProfile;
-
-public class StorageNetworkGuru extends PodBasedNetworkGuru implements NetworkGuru {
-    private static final Logger s_logger = Logger.getLogger(StorageNetworkGuru.class);
-    @Inject
-    StorageNetworkManager _sNwMgr;
-    @Inject
-    NetworkDao _nwDao;
-
-    protected StorageNetworkGuru() {
-        super();
-    }
-
-    private static final TrafficType[] TrafficTypes = {TrafficType.Storage};
-
-    @Override
-    public boolean isMyTrafficType(TrafficType type) {
-        for (TrafficType t : TrafficTypes) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficType[] getSupportedTrafficType() {
-        return TrafficTypes;
-    }
-
-    protected boolean canHandle(NetworkOffering offering) {
-        if (isMyTrafficType(offering.getTrafficType()) && offering.isSystemOnly()) {
-            return true;
-        } else {
-            s_logger.trace("It's not storage network offering, skip it.");
-            return false;
-        }
-    }
-
-    @Override
-    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
-        if (!canHandle(offering)) {
-            return null;
-        }
-
-        NetworkVO config =
-            new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
-                plan.getPhysicalNetworkId(), offering.getRedundantRouter());
-        return config;
-    }
-
-    @Override
-    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException {
-        assert network.getTrafficType() == TrafficType.Storage : "Why are you sending this configuration to me " + network;
-        if (!_sNwMgr.isStorageIpRangeAvailable(destination.getDataCenter().getId())) {
-            return super.implement(network, offering, destination, context);
-        }
-        return network;
-    }
-
-    @Override
-    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
-        InsufficientAddressCapacityException {
-        assert network.getTrafficType() == TrafficType.Storage : "Well, I can't take care of this config now can I? " + network;
-        if (!_sNwMgr.isStorageIpRangeAvailable(network.getDataCenterId())) {
-            return super.allocate(network, nic, vm);
-        }
-
-        return new NicProfile(ReservationStrategy.Start, null, null, null, null);
-    }
-
-    @Override
-    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
-        if (!_sNwMgr.isStorageIpRangeAvailable(dest.getDataCenter().getId())) {
-            super.reserve(nic, network, vm, dest, context);
-            return;
-        }
-
-        Pod pod = dest.getPod();
-        Integer vlan = null;
-
-        StorageNetworkIpAddressVO ip = _sNwMgr.acquireIpAddress(pod.getId());
-        if (ip == null) {
-            throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId());
-        }
-
-        vlan = ip.getVlan();
-        nic.setIPv4Address(ip.getIpAddress());
-        nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.getMac(), NetworkModel.MACIdentifier.value())));
-        nic.setFormat(AddressFormat.Ip4);
-        nic.setIPv4Netmask(ip.getNetmask());
-        nic.setBroadcastType(BroadcastDomainType.Storage);
-        nic.setIPv4Gateway(ip.getGateway());
-        if (vlan != null) {
-            nic.setBroadcastUri(BroadcastDomainType.Storage.toUri(vlan));
-        } else {
-            nic.setBroadcastUri(null);
-        }
-        nic.setIsolationUri(null);
-        s_logger.debug("Allocated a storage nic " + nic + " for " + vm);
-    }
-
-    @Override
-    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
-        Network nw = _nwDao.findById(nic.getNetworkId());
-        if (!_sNwMgr.isStorageIpRangeAvailable(nw.getDataCenterId())) {
-            return super.release(nic, vm, reservationId);
-        }
-
-        _sNwMgr.releaseIpAddress(nic.getIPv4Address());
-        s_logger.debug("Release an storage ip " + nic.getIPv4Address());
-        nic.deallocate();
-        return true;
-    }
-
-    @Override
-    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void updateNicProfile(NicProfile profile, Network network) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void shutdown(NetworkProfile network, NetworkOffering offering) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean trash(Network network, NetworkOffering offering) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void updateNetworkProfile(NetworkProfile networkProfile) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
deleted file mode 100644
index 9b7cf9b..0000000
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ /dev/null
@@ -1,2598 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.lb;
-
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.response.ServiceResponse;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
-import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.ExternalDeviceUsageManager;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.LBHealthCheckPolicyVO;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.as.AutoScalePolicy;
-import com.cloud.network.as.AutoScalePolicyConditionMapVO;
-import com.cloud.network.as.AutoScaleVmGroup;
-import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO;
-import com.cloud.network.as.AutoScaleVmGroupVO;
-import com.cloud.network.as.AutoScaleVmProfile;
-import com.cloud.network.as.Condition;
-import com.cloud.network.as.Counter;
-import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
-import com.cloud.network.as.dao.AutoScalePolicyDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
-import com.cloud.network.as.dao.AutoScaleVmProfileDao;
-import com.cloud.network.as.dao.ConditionDao;
-import com.cloud.network.as.dao.CounterDao;
-import com.cloud.network.dao.FirewallRulesCidrsDao;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LBHealthCheckPolicyDao;
-import com.cloud.network.dao.LBStickinessPolicyDao;
-import com.cloud.network.dao.LBStickinessPolicyVO;
-import com.cloud.network.dao.LoadBalancerCertMapDao;
-import com.cloud.network.dao.LoadBalancerCertMapVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.LoadBalancerVMMapVO;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.SslCertVO;
-import com.cloud.network.element.LoadBalancingServiceProvider;
-import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy;
-import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup;
-import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile;
-import com.cloud.network.lb.LoadBalancingRule.LbCondition;
-import com.cloud.network.lb.LoadBalancingRule.LbDestination;
-import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
-import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
-import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.FirewallRuleType;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.HealthCheckPolicy;
-import com.cloud.network.rules.LbStickinessMethod;
-import com.cloud.network.rules.LbStickinessMethod.LbStickinessMethodParam;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.StickinessPolicy;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainService;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
-public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService {
-    private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class);
-
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    RulesManager _rulesMgr;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    LoadBalancerDao _lbDao;
-    @Inject
-    VlanDao _vlanDao;
-    @Inject
-    EventDao _eventDao;
-    @Inject
-    LoadBalancerVMMapDao _lb2VmMapDao;
-    @Inject
-    LBStickinessPolicyDao _lb2stickinesspoliciesDao;
-    @Inject
-    LBHealthCheckPolicyDao _lb2healthcheckDao;
-    @Inject
-    UserVmDao _vmDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    UsageEventDao _usageEventDao;
-    @Inject
-    FirewallRulesCidrsDao _firewallCidrsDao;
-    @Inject
-    FirewallManager _firewallMgr;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    DomainService _domainMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-
-    @Inject
-    ExternalDeviceUsageManager _externalDeviceUsageMgr;
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    VMTemplateDao _templateDao;
-    @Inject
-    ServiceOfferingDao _offeringsDao;
-    @Inject
-    CounterDao _counterDao;
-    @Inject
-    ConditionDao _conditionDao;
-    @Inject
-    AutoScaleVmProfileDao _autoScaleVmProfileDao;
-    @Inject
-    AutoScalePolicyDao _autoScalePolicyDao;
-    @Inject
-    AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao;
-    @Inject
-    AutoScaleVmGroupDao _autoScaleVmGroupDao;
-    @Inject
-    AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    UserDao _userDao;
-    List<LoadBalancingServiceProvider> _lbProviders;
-    @Inject
-    ApplicationLoadBalancerRuleDao _appLbRuleDao;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    LoadBalancerCertMapDao _lbCertMapDao;
-
-    @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;
-
-    // Will return a string. For LB Stickiness this will be a json, for
-    // autoscale this will be "," separated values
-    @Override
-    public String getLBCapability(long networkid, String capabilityName) {
-        Map<Service, Map<Capability, String>> serviceCapabilitiesMap = _networkModel.getNetworkCapabilities(networkid);
-        if (serviceCapabilitiesMap != null) {
-            for (Service service : serviceCapabilitiesMap.keySet()) {
-                ServiceResponse serviceResponse = new ServiceResponse();
-                serviceResponse.setName(service.getName());
-                if ("Lb".equalsIgnoreCase(service.getName())) {
-                    Map<Capability, String> serviceCapabilities = serviceCapabilitiesMap.get(service);
-                    if (serviceCapabilities != null) {
-                        for (Capability capability : serviceCapabilities.keySet()) {
-                            if (capabilityName.equals(capability.getName())) {
-                                return serviceCapabilities.get(capability);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    private LbAutoScaleVmGroup getLbAutoScaleVmGroup(AutoScaleVmGroupVO vmGroup, String currentState, LoadBalancerVO lb) {
-        long lbNetworkId = lb.getNetworkId();
-        String lbName = lb.getName();
-        List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyMapList = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(vmGroup.getId());
-        List<LbAutoScalePolicy> autoScalePolicies = new ArrayList<LbAutoScalePolicy>();
-        for (AutoScaleVmGroupPolicyMapVO vmGroupPolicyMap : vmGroupPolicyMapList) {
-            AutoScalePolicy autoScalePolicy = _autoScalePolicyDao.findById(vmGroupPolicyMap.getPolicyId());
-            List<AutoScalePolicyConditionMapVO> autoScalePolicyConditionMapList = _autoScalePolicyConditionMapDao.listByAll(autoScalePolicy.getId(), null);
-            List<LbCondition> lbConditions = new ArrayList<LbCondition>();
-            for (AutoScalePolicyConditionMapVO autoScalePolicyConditionMap : autoScalePolicyConditionMapList) {
-                Condition condition = _conditionDao.findById(autoScalePolicyConditionMap.getConditionId());
-                Counter counter = _counterDao.findById(condition.getCounterid());
-                lbConditions.add(new LbCondition(counter, condition));
-            }
-            autoScalePolicies.add(new LbAutoScalePolicy(autoScalePolicy, lbConditions));
-        }
-        AutoScaleVmProfile autoScaleVmProfile = _autoScaleVmProfileDao.findById(vmGroup.getProfileId());
-        Long autoscaleUserId = autoScaleVmProfile.getAutoScaleUserId();
-        User user = _userDao.findByIdIncludingRemoved(autoscaleUserId);
-        String apiKey = user.getApiKey();
-        String secretKey = user.getSecretKey();
-        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
-        String zoneId = _dcDao.findById(autoScaleVmProfile.getZoneId()).getUuid();
-        String domainId = _domainDao.findById(autoScaleVmProfile.getDomainId()).getUuid();
-        String serviceOfferingId = _offeringsDao.findById(autoScaleVmProfile.getServiceOfferingId()).getUuid();
-        String templateId = _templateDao.findById(autoScaleVmProfile.getTemplateId()).getUuid();
-        String vmName = "AutoScale-LB-" + lbName;
-        String lbNetworkUuid = null;
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, vmGroup.getZoneId());
-        if (zone == null) {
-            // This should never happen, but still a cautious check
-            s_logger.warn("Unable to find zone while packaging AutoScale Vm Group, zoneid: " + vmGroup.getZoneId());
-            throw new InvalidParameterValueException("Unable to find zone");
-        } else {
-            if (zone.getNetworkType() == NetworkType.Advanced) {
-                NetworkVO lbNetwork = _networkDao.findById(lbNetworkId);
-                lbNetworkUuid = lbNetwork.getUuid();
-            }
-        }
-
-        if (apiKey == null) {
-            throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it");
-        }
-
-        if (secretKey == null) {
-            throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it");
-        }
-
-        if (csUrl == null || csUrl.contains("localhost")) {
-            throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
-        }
-
-        LbAutoScaleVmProfile lbAutoScaleVmProfile =
-            new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, csUrl, zoneId, domainId, serviceOfferingId, templateId, vmName, lbNetworkUuid);
-        return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, lbAutoScaleVmProfile, currentState);
-    }
-
-    private boolean applyAutoScaleConfig(LoadBalancerVO lb, AutoScaleVmGroupVO vmGroup, String currentState) throws ResourceUnavailableException {
-        LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup, currentState, lb);
-        /*
-         * Regular config like destinations need not be packed for applying
-         * autoscale config as of today.
-         */
-        List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
-        Ip sourceIp = getSourceIp(lb);
-        LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null, sourceIp, null, lb.getLbProtocol());
-        rule.setAutoScaleVmGroup(lbAutoScaleVmGroup);
-
-        if (!isRollBackAllowedForProvider(lb)) {
-            // this is for Netscaler type of devices. if their is failure the db
-            // entries will be rollbacked.
-            return false;
-        }
-
-        List<LoadBalancingRule> rules = Arrays.asList(rule);
-
-        if (!applyLbRules(rules, false)) {
-            s_logger.debug("LB rules' autoscale config are not completely applied");
-            return false;
-        }
-
-        return true;
-    }
-
-    private Ip getSourceIp(LoadBalancer lb) {
-        Ip sourceIp = null;
-        if (lb.getScheme() == Scheme.Public) {
-            sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
-        } else if (lb.getScheme() == Scheme.Internal) {
-            ApplicationLoadBalancerRuleVO appLbRule = _appLbRuleDao.findById(lb.getId());
-            sourceIp = appLbRule.getSourceIp();
-        }
-        return sourceIp;
-    }
-
-    @Override
-    @DB
-    public boolean configureLbAutoScaleVmGroup(final long vmGroupid, String currentState) throws ResourceUnavailableException {
-        final AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
-        boolean success = false;
-
-        final LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId());
-
-        FirewallRule.State backupState = loadBalancer.getState();
-
-        if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) {
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-        } else if (loadBalancer.getState() == FirewallRule.State.Active && vmGroup.getState().equals(AutoScaleVmGroup.State_Revoke)) {
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-        }
-
-        try {
-            success = applyAutoScaleConfig(loadBalancer, vmGroup, currentState);
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to configure AutoScaleVmGroup to the lb rule: " + loadBalancer.getId() + " because resource is unavaliable:", e);
-            if (isRollBackAllowedForProvider(loadBalancer)) {
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating AutoscaleVmGroup");
-            }
-            throw e;
-        } finally {
-            if (!success) {
-                s_logger.warn("Failed to configure LB Auto Scale Vm Group with Id:" + vmGroupid);
-            }
-        }
-
-        if (success) {
-            if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        loadBalancer.setState(FirewallRule.State.Active);
-                        s_logger.debug("LB rule " + loadBalancer.getId() + " state is set to Active");
-                        _lbDao.persist(loadBalancer);
-                        vmGroup.setState(AutoScaleVmGroup.State_Enabled);
-                        _autoScaleVmGroupDao.persist(vmGroup);
-                        s_logger.debug("LB Auto Scale Vm Group with Id: " + vmGroupid + " is set to Enabled state.");
-                    }
-                });
-            }
-            s_logger.info("Successfully configured LB Autoscale Vm Group with Id: " + vmGroupid);
-        }
-        return success;
-    }
-
-    private boolean validateHealthCheck(CreateLBHealthCheckPolicyCmd cmd) {
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.HealthCheckPolicy.getName());
-        if (capability != null) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean genericValidator(CreateLBStickinessPolicyCmd cmd) throws InvalidParameterValueException {
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        /* Validation : check for valid Method name and params */
-        List<LbStickinessMethod> stickinessMethodList = getStickinessMethods(loadBalancer.getNetworkId());
-        boolean methodMatch = false;
-
-        if (stickinessMethodList == null) {
-            throw new InvalidParameterValueException("Failed:  No Stickiness method available for LB rule:" + cmd.getLbRuleId());
-        }
-        for (LbStickinessMethod method : stickinessMethodList) {
-            if (method.getMethodName().equalsIgnoreCase(cmd.getStickinessMethodName())) {
-                methodMatch = true;
-                Map apiParamList = cmd.getparamList();
-                List<LbStickinessMethodParam> methodParamList = method.getParamList();
-                Map<String, String> tempParamList = new HashMap<String, String>();
-
-                /*
-                 * validation-1: check for any extra params that are not
-                 * required by the policymethod(capability), FIXME: make the
-                 * below loop simple without using raw data type
-                 */
-                if (apiParamList != null) {
-                    Collection userGroupCollection = apiParamList.values();
-                    Iterator iter = userGroupCollection.iterator();
-                    while (iter.hasNext()) {
-                        HashMap<String, String> paramKVpair = (HashMap)iter.next();
-                        String paramName = paramKVpair.get("name");
-                        String paramValue = paramKVpair.get("value");
-
-                        tempParamList.put(paramName, paramValue);
-                        Boolean found = false;
-                        for (LbStickinessMethodParam param : methodParamList) {
-                            if (param.getParamName().equalsIgnoreCase(paramName)) {
-                                if ((param.getIsflag() == false) && (paramValue == null)) {
-                                    throw new InvalidParameterValueException("Failed : Value expected for the Param :" + param.getParamName());
-                                }
-                                found = true;
-                                break;
-                            }
-                        }
-                        if (!found) {
-                            throw new InvalidParameterValueException("Failed : Stickiness policy does not support param name :" + paramName);
-                        }
-                    }
-                }
-
-                /* validation-2: check for mandatory params */
-                for (LbStickinessMethodParam param : methodParamList) {
-                    if (param.getRequired()) {
-                        if (tempParamList.get(param.getParamName()) == null) {
-                            throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + param.getParamName());
-                        }
-                    }
-                }
-                /* Successfully completed the Validation */
-                break;
-            }
-        }
-        if (methodMatch == false) {
-            throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule:" + cmd.getLbRuleId());
-        }
-
-        /* Validation : check for the multiple policies to the rule id */
-        List<LBStickinessPolicyVO> stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
-        if (stickinessPolicies.size() > 1) {
-            throw new InvalidParameterValueException("Failed to create Stickiness policy: Already two policies attached " + cmd.getLbRuleId());
-        }
-        return true;
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "create lb stickinesspolicy to load balancer", create = true)
-    public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException {
-        CallContext caller = CallContext.current();
-
-        /* Validation : check corresponding load balancer rule exist */
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        if (loadBalancer == null) {
-            throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " not present ");
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-        if (loadBalancer.getState() == FirewallRule.State.Revoke) {
-            throw new InvalidParameterValueException("Failed:  LB rule id: " + cmd.getLbRuleId() + " is in deleting state: ");
-        }
-
-        /* Generic validations */
-        if (!genericValidator(cmd)) {
-            throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId());
-        }
-
-        /*
-         * Specific validations using network element validator for specific
-         * validations
-         */
-        LBStickinessPolicyVO lbpolicy =
-            new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription());
-        List<LbStickinessPolicy> policyList = new ArrayList<LbStickinessPolicy>();
-        policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams()));
-        Ip sourceIp = getSourceIp(loadBalancer);
-        LoadBalancingRule lbRule =
-            new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), policyList, null, sourceIp, null, loadBalancer.getLbProtocol());
-        if (!validateLbRule(lbRule)) {
-            throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId());
-        }
-
-        /* Finally Insert into DB */
-        LBStickinessPolicyVO policy =
-            new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription());
-        Boolean forDisplay = cmd.getDisplay();
-        if (forDisplay != null) {
-            policy.setDisplay(forDisplay);
-        }
-        policy = _lb2stickinesspoliciesDao.persist(policy);
-
-        return policy;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE, eventDescription = "create load balancer health check to load balancer", create = true)
-    public HealthCheckPolicy createLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) {
-        CallContext caller = CallContext.current();
-
-        /*
-         * Validation of cmd Monitor interval must be greater than response
-         * timeout
-         */
-        Map<String, String> paramMap = cmd.getFullUrlParams();
-
-        if (paramMap.containsKey(ApiConstants.HEALTHCHECK_RESPONSE_TIMEOUT) && paramMap.containsKey(ApiConstants.HEALTHCHECK_INTERVAL_TIME)) {
-            if (cmd.getResponsTimeOut() > cmd.getHealthCheckInterval())
-                throw new InvalidParameterValueException("Failed to create HealthCheck policy : Monitor interval must be greater than response timeout");
-        }
-        /* Validation : check corresponding load balancer rule exist */
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        if (loadBalancer == null) {
-            throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " not present ");
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        if (loadBalancer.getState() == FirewallRule.State.Revoke) {
-            throw new InvalidParameterValueException("Failed:  LB rule id: " + cmd.getLbRuleId() + " is in deleting state: ");
-        }
-
-        /*
-         * Validate Whether LB Provider has the capabilities to support Health
-         * Checks
-         */
-        if (!validateHealthCheck(cmd)) {
-            throw new InvalidParameterValueException(
-                "Failed to create HealthCheck policy: Validation Failed (HealthCheck Policy is not supported by LB Provider for the LB rule id :" + cmd.getLbRuleId() + ")");
-        }
-
-        /* Validation : check for the multiple hc policies to the rule id */
-        List<LBHealthCheckPolicyVO> hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
-        if (hcPolicies.size() > 0) {
-            throw new InvalidParameterValueException("Failed to create HealthCheck policy: Already policy attached  for the LB Rule id :" + cmd.getLbRuleId());
-        }
-        /*
-         * Specific validations using network element validator for specific
-         * validations
-         */
-        LBHealthCheckPolicyVO hcpolicy =
-            new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(),
-                cmd.getHealthyThreshold(), cmd.getUnhealthyThreshold());
-
-        List<LbHealthCheckPolicy> hcPolicyList = new ArrayList<LbHealthCheckPolicy>();
-        hcPolicyList.add(new LbHealthCheckPolicy(hcpolicy.getpingpath(), hcpolicy.getDescription(), hcpolicy.getResponseTime(), hcpolicy.getHealthcheckInterval(),
-            hcpolicy.getHealthcheckThresshold(), hcpolicy.getUnhealthThresshold()));
-
-        // Finally Insert into DB
-        LBHealthCheckPolicyVO policy =
-            new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(),
-                cmd.getHealthyThreshold(), cmd.getUnhealthyThreshold());
-
-        Boolean forDisplay = cmd.getDisplay();
-        if (forDisplay != null) {
-            policy.setDisplay(forDisplay);
-        }
-
-        policy = _lb2healthcheckDao.persist(policy);
-        return policy;
-    }
-
-    @Override
-    public boolean validateLbRule(LoadBalancingRule lbRule) {
-        Network network = _networkDao.findById(lbRule.getNetworkId());
-        Purpose purpose = lbRule.getPurpose();
-        if (purpose != Purpose.LoadBalancing) {
-            s_logger.debug("Unable to validate network rules for purpose: " + purpose.toString());
-            return false;
-        }
-        for (LoadBalancingServiceProvider ne : _lbProviders) {
-            boolean validated = ne.validateLBRule(network, lbRule);
-            if (!validated)
-                return false;
-        }
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "Apply Stickinesspolicy to load balancer ", async = true)
-    public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) {
-        boolean success = true;
-        FirewallRule.State backupState = null;
-        long oldStickinessPolicyId = 0;
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId());
-        }
-        List<LBStickinessPolicyVO> stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
-        for (LBStickinessPolicyVO stickinessPolicy : stickinessPolicies) {
-            if (stickinessPolicy.getId() == cmd.getEntityId()) {
-                backupState = loadBalancer.getState();
-                loadBalancer.setState(FirewallRule.State.Add);
-                _lbDao.persist(loadBalancer);
-            } else {
-                oldStickinessPolicyId = stickinessPolicy.getId();
-                stickinessPolicy.setRevoke(true);
-                _lb2stickinesspoliciesDao.persist(stickinessPolicy);
-            }
-        }
-        try {
-            applyLoadBalancerConfig(cmd.getLbRuleId());
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to apply Stickiness policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e);
-            if (isRollBackAllowedForProvider(loadBalancer)) {
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                deleteLBStickinessPolicy(cmd.getEntityId(), false);
-                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating sticky policy");
-            } else {
-                deleteLBStickinessPolicy(cmd.getEntityId(), false);
-                if (oldStickinessPolicyId != 0) {
-                    LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(oldStickinessPolicyId);
-                    stickinessPolicy.setRevoke(false);
-                    _lb2stickinesspoliciesDao.persist(stickinessPolicy);
-                    try {
-                        if (backupState.equals(FirewallRule.State.Active))
-                            applyLoadBalancerConfig(cmd.getLbRuleId());
-                    } catch (ResourceUnavailableException e1) {
-                        s_logger.info("[ignored] applying load balancer config.", e1);
-                    } finally {
-                        loadBalancer.setState(backupState);
-                        _lbDao.persist(loadBalancer);
-                    }
-                }
-            }
-            success = false;
-        }
-
-        return success;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE, eventDescription = "Apply HealthCheckPolicy to load balancer ", async = true)
-    public boolean applyLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) {
-        boolean success = true;
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId());
-        }
-        FirewallRule.State backupState = loadBalancer.getState();
-        loadBalancer.setState(FirewallRule.State.Add);
-        _lbDao.persist(loadBalancer);
-        try {
-            applyLoadBalancerConfig(cmd.getLbRuleId());
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to apply healthcheck policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e);
-            if (isRollBackAllowedForProvider(loadBalancer)) {
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating healthcheck policy");
-            }
-            deleteLBHealthCheckPolicy(cmd.getEntityId(), false);
-            success = false;
-        }
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_DELETE, eventDescription = "revoking LB Stickiness policy ", async = true)
-    public boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply) {
-        boolean success = true;
-
-        CallContext caller = CallContext.current();
-        LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId);
-
-        if (stickinessPolicy == null) {
-            throw new InvalidParameterException("Invalid Stickiness policy id value: " + stickinessPolicyId);
-        }
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(stickinessPolicy.getLoadBalancerId()));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer : " + stickinessPolicy.getLoadBalancerId() + " for Stickiness policy id: " + stickinessPolicyId);
-        }
-        long loadBalancerId = loadBalancer.getId();
-        FirewallRule.State backupState = loadBalancer.getState();
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        if (apply) {
-            if (loadBalancer.getState() == FirewallRule.State.Active) {
-                loadBalancer.setState(FirewallRule.State.Add);
-                _lbDao.persist(loadBalancer);
-            }
-
-            boolean backupStickyState = stickinessPolicy.isRevoke();
-            stickinessPolicy.setRevoke(true);
-            _lb2stickinesspoliciesDao.persist(stickinessPolicy);
-            s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", stickinesspolicyID " + stickinessPolicyId);
-
-            try {
-                if (!applyLoadBalancerConfig(loadBalancerId)) {
-                    s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId);
-                    throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId);
-                }
-            } catch (ResourceUnavailableException e) {
-                if (isRollBackAllowedForProvider(loadBalancer)) {
-                    stickinessPolicy.setRevoke(backupStickyState);
-                    _lb2stickinesspoliciesDao.persist(stickinessPolicy);
-                    loadBalancer.setState(backupState);
-                    _lbDao.persist(loadBalancer);
-                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while deleting sticky policy: " + stickinessPolicyId);
-                }
-                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-                success = false;
-            }
-        } else {
-            _lb2stickinesspoliciesDao.expunge(stickinessPolicyId);
-        }
-        return success;
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_DELETE, eventDescription = "revoking LB HealthCheck policy ", async = true)
-    public boolean deleteLBHealthCheckPolicy(long healthCheckPolicyId, boolean apply) {
-        boolean success = true;
-
-        CallContext caller = CallContext.current();
-        LBHealthCheckPolicyVO healthCheckPolicy = _lb2healthcheckDao.findById(healthCheckPolicyId);
-
-        if (healthCheckPolicy == null) {
-            throw new InvalidParameterException("Invalid HealthCheck policy id value: " + healthCheckPolicyId);
-        }
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(healthCheckPolicy.getLoadBalancerId()));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer : " + healthCheckPolicy.getLoadBalancerId() + " for HealthCheck policy id: " + healthCheckPolicyId);
-        }
-        final long loadBalancerId = loadBalancer.getId();
-        FirewallRule.State backupState = loadBalancer.getState();
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        if (apply) {
-            if (loadBalancer.getState() == FirewallRule.State.Active) {
-                loadBalancer.setState(FirewallRule.State.Add);
-                _lbDao.persist(loadBalancer);
-            }
-
-            boolean backupStickyState = healthCheckPolicy.isRevoke();
-            healthCheckPolicy.setRevoke(true);
-            _lb2healthcheckDao.persist(healthCheckPolicy);
-            s_logger.debug("Set health check policy to revoke for loadbalancing rule id : " + loadBalancerId + ", healthCheckpolicyID " + healthCheckPolicyId);
-
-            // removing the state of services set by the monitor.
-            final List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
-            if (maps != null) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        s_logger.debug("Resetting health state policy for services in loadbalancing rule id : " + loadBalancerId);
-                        for (LoadBalancerVMMapVO map : maps) {
-                            map.setState(null);
-                            _lb2VmMapDao.persist(map);
-                        }
-                    }
-                });
-            }
-
-            try {
-                if (!applyLoadBalancerConfig(loadBalancerId)) {
-                    s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for healthCheckpolicyID " + healthCheckPolicyId);
-                    throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for healthCheckpolicyID " + healthCheckPolicyId);
-                }
-            } catch (ResourceUnavailableException e) {
-                if (isRollBackAllowedForProvider(loadBalancer)) {
-                    healthCheckPolicy.setRevoke(backupStickyState);
-                    _lb2healthcheckDao.persist(healthCheckPolicy);
-                    loadBalancer.setState(backupState);
-                    _lbDao.persist(loadBalancer);
-                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while deleting healthcheck policy: " + healthCheckPolicyId);
-                }
-                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-                success = false;
-            }
-        } else {
-            _lb2healthcheckDao.remove(healthCheckPolicy.getLoadBalancerId());
-        }
-        return success;
-    }
-
-    // This method will check the status of services which has monitors created
-    // by CloudStack and update them in lbvmmap table
-    @DB
-    @Override
-    public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableException {
-        List<LoadBalancerVO> rules = _lbDao.listAll();
-        List<NetworkVO> networks = _networkDao.listAll();
-        List<LoadBalancerTO> stateRules = null;
-        boolean isHandled = false;
-        for (NetworkVO ntwk : networks) {
-            Network network = _networkDao.findById(ntwk.getId());
-            String capability = getLBCapability(network.getId(), Capability.HealthCheckPolicy.getName());
-
-            if (capability != null && capability.equalsIgnoreCase("true")) {
-                /*
-                 * s_logger.debug(
-                 * "HealthCheck Manager :: LB Provider in the Network has the Healthcheck policy capability :: "
-                 * + provider.get(0).getName());
-                 */
-                rules = _lbDao.listByNetworkIdAndScheme(network.getId(), scheme);
-                if (rules != null && rules.size() > 0) {
-                    List<LoadBalancingRule> lbrules = new ArrayList<LoadBalancingRule>();
-                    for (LoadBalancerVO lb : rules) {
-                        List<LbDestination> dstList = getExistingDestinations(lb.getId());
-                        List<LbHealthCheckPolicy> hcPolicyList = getHealthCheckPolicies(lb.getId());
-                        // Now retrive the status of services from NS even there are no policies. because there is default monitor
-                        Ip sourceIp = getSourceIp(lb);
-                        LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol());
-                        lbrules.add(loadBalancing);
-                    }
-                    if (lbrules.size() > 0) {
-                        isHandled = false;
-                        for (LoadBalancingServiceProvider lbElement : _lbProviders) {
-                            stateRules = lbElement.updateHealthChecks(network, lbrules);
-                            if (stateRules != null && stateRules.size() > 0) {
-                                for (LoadBalancerTO lbto : stateRules) {
-                                    LoadBalancerVO ulb = _lbDao.findByUuid(lbto.getUuid());
-                                    List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(ulb.getId());
-                                    for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
-                                        UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
-                                        Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(ulb.getNetworkId(), vm.getId());
-                                        String dstIp = lbVmMap.getInstanceIp() == null ? nic.getIPv4Address(): lbVmMap.getInstanceIp();
-
-                                        for (int i = 0; i < lbto.getDestinations().length; i++) {
-                                            LoadBalancerTO.DestinationTO des = lbto.getDestinations()[i];
-                                            if (dstIp.equalsIgnoreCase(lbto.getDestinations()[i].getDestIp())) {
-                                                lbVmMap.setState(des.getMonitorState());
-                                                _lb2VmMapDao.persist(lbVmMap);
-                                                s_logger.debug("Updating the LB VM Map table with the service state");
-                                            }
-                                        }
-                                    }
-                                }
-                                isHandled = true;
-                            }
-                            if (isHandled) {
-                                break;
-                            }
-                        }
-                    }
-                }
-            } else {
-                // s_logger.debug("HealthCheck Manager :: LB Provider in the Network DNOT the Healthcheck policy capability ");
-            }
-        }
-    }
-
-    private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) {
-        Network network = _networkDao.findById(loadBalancer.getNetworkId());
-        List<Provider> provider = _networkMgr.getProvidersForServiceInNetwork(network, Service.Lb);
-        if (provider == null || provider.size() == 0) {
-            return false;
-        }
-        if (provider.get(0) == Provider.Netscaler || provider.get(0) == Provider.F5BigIp ||
-            provider.get(0) == Provider.VirtualRouter) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true)
-    public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds, Map<Long, List<String>> vmIdIpMap) {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        final LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
-        if (loadBalancer == null) {
-            throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found.");
-        }
-
-
-        if (instanceIds == null && vmIdIpMap.isEmpty()) {
-            throw new InvalidParameterValueException("Both instanceids and vmidipmap  can't be null");
-        }
-
-        // instanceIds and vmIdipmap is passed
-        if (instanceIds != null && !vmIdIpMap.isEmpty()) {
-            for(long instanceId: instanceIds) {
-                if (!vmIdIpMap.containsKey(instanceId)) {
-                    vmIdIpMap.put(instanceId, null);
-                }
-            }
-        }
-
-        //only instanceids list passed
-        if (instanceIds != null && vmIdIpMap.isEmpty()){
-            vmIdIpMap = new HashMap<Long, List<String>>();
-            for (long instanceId: instanceIds){
-                vmIdIpMap.put(instanceId, null);
-            }
-        }
-
-        List<LoadBalancerVMMapVO> mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false);
-        Set<Long> mappedInstanceIds = new HashSet<Long>();
-        for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
-            mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId()));
-        }
-
-        Map<Long, List<String>> existingVmIdIps = new HashMap<Long, List<String>>();
-        // now get the ips of vm and add it to map
-        for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
-
-            List<String> ipsList = null;
-            if (existingVmIdIps.containsKey(mappedInstance.getInstanceId())) {
-                ipsList = existingVmIdIps.get(mappedInstance.getInstanceId());
-            } else {
-                ipsList = new ArrayList<String>();
-            }
-            ipsList.add(mappedInstance.getInstanceIp());
-            existingVmIdIps.put(mappedInstance.getInstanceId(), ipsList);
-        }
-
-        final List<UserVm> vmsToAdd = new ArrayList<UserVm>();
-
-        // check for conflict
-        Set<Long> passedInstanceIds = vmIdIpMap.keySet();
-        for (Long instanceId : passedInstanceIds) {
-            UserVm vm = _vmDao.findById(instanceId);
-            if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified");
-                if (vm == null) {
-                    ex.addProxyObject(instanceId.toString(), "instanceId");
-                } else {
-                    ex.addProxyObject(vm.getUuid(), "instanceId");
-                }
-                throw ex;
-            }
-
-            _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller);
-
-            if (vm.getAccountId() != loadBalancer.getAccountId()) {
-                throw new PermissionDeniedException("Cannot add virtual machines that do not belong to the same owner.");
-            }
-
-            // Let's check to make sure the vm has a nic in the same network as
-            // the load balancing rule.
-            List<? extends Nic> nics = _networkModel.getNics(vm.getId());
-            Nic nicInSameNetwork = null;
-            for (Nic nic : nics) {
-                if (nic.getNetworkId() == loadBalancer.getNetworkId()) {
-                    nicInSameNetwork = nic;
-                    break;
-                }
-            }
-
-            if (nicInSameNetwork == null) {
-                InvalidParameterValueException ex =
-                        new InvalidParameterValueException("VM with id specified cannot be added because it doesn't belong in the same network.");
-                ex.addProxyObject(vm.getUuid(), "instanceId");
-                throw ex;
-            }
-
-            String priIp = nicInSameNetwork.getIPv4Address();
-
-            if (existingVmIdIps.containsKey(instanceId)) {
-                // now check for ip address
-                List<String> mappedIps = existingVmIdIps.get(instanceId);
-                List<String> newIps = vmIdIpMap.get(instanceId);
-
-                if (newIps == null) {
-                    newIps = new ArrayList<String>();
-                    newIps.add(priIp);
-                }
-
-                for (String newIp: newIps) {
-                    if (mappedIps.contains(newIp)) {
-                        throw new InvalidParameterValueException("VM " + instanceId + " with " + newIp +" is already mapped to load balancer.");
-                    }
-                }
-            }
-
-            List<String> vmIpsList = vmIdIpMap.get(instanceId);
-            String vmLbIp = null;
-
-            if (vmIpsList != null) {
-
-                //check if the ips belongs to nic secondary ip
-                for (String ip: vmIpsList) {
-                    // skip the primary ip from vm secondary ip comparisions
-                    if (ip.equals(priIp)) {
-                        continue;
-                    }
-                    if(_nicSecondaryIpDao.findByIp4AddressAndNicId(ip,nicInSameNetwork.getId()) == null) {
-                        throw new InvalidParameterValueException("VM ip "+ ip + " specified does not belong to " +
-                                "nic in network " + nicInSameNetwork.getNetworkId());
-                    }
-                }
-            } else {
-                vmIpsList = new ArrayList<String>();
-                vmIpsList.add(priIp);
-            }
-
-            // when vm id is passed in instance ids and in vmidipmap
-            // assign for primary ip and ip passed in vmidipmap
-            if (instanceIds != null ) {
-                if (instanceIds.contains(instanceId)) {
-                    vmIpsList.add(priIp);
-                }
-            }
-
-            vmIdIpMap.put(instanceId, vmIpsList);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Adding " + vm + " to the load balancer pool");
-            }
-            vmsToAdd.add(vm);
-        }
-
-        final Set<Long> vmIds = vmIdIpMap.keySet();
-        final Map<Long, List<String>> newMap = vmIdIpMap;
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-
-                for (Long vmId : vmIds) {
-                    final Set<String> lbVmIps = new HashSet<String>(newMap.get(vmId));
-                    for (String vmIp: lbVmIps) {
-                        LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vmId, vmIp, false);
-                        map = _lb2VmMapDao.persist(map);
-                    }
-                }
-            }
-        });
-
-        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) {
-            // For autoscaled loadbalancer, the rules need not be applied,
-            // meaning the call need not reach the resource layer.
-            // We can consider the job done.
-            return true;
-        }
-        boolean success = false;
-        FirewallRule.State backupState = loadBalancer.getState();
-        try {
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-            applyLoadBalancerConfig(loadBalancerId);
-            success = true;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-            success = false;
-        } finally {
-            if (!success) {
-                final List<Long> vmInstanceIds = new ArrayList<Long>();
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        for (Long vmId : vmIds) {
-                            vmInstanceIds.add(vmId);
-                        }
-                    }
-                });
-                if (!vmInstanceIds.isEmpty()) {
-                    _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null);
-                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while attaching VM: " + vmInstanceIds);
-                }
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms "
-                    + vmInstanceIds);
-                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
-                // TBD: Also pack in the instanceIds in the exception using the
-                // right VO object or table name.
-                throw ex;
-            }
-
-        }
-
-        return success;
-    }
-
-    @Override
-    public boolean assignSSLCertToLoadBalancerRule(Long lbId, String certName, String publicCert, String privateKey) {
-        s_logger.error("Calling the manager for LB");
-        LoadBalancerVO loadBalancer = _lbDao.findById(lbId);
-
-        return false;  //TODO
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true)
-    public boolean removeFromLoadBalancer(long loadBalancerId, List<Long> instanceIds, Map<Long, List<String>> vmIdIpsMap) {
-        return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true, vmIdIpsMap);
-    }
-
-    @Override
-    public LbSslCert getLbSslCert(long lbRuleId) {
-        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
-
-        if (lbCertMap == null)
-            return null;
-
-        SslCertVO certVO = _entityMgr.findById(SslCertVO.class, lbCertMap.getCertId());
-        if (certVO == null) {
-            s_logger.warn("Cert rule with cert ID " + lbCertMap.getCertId() + " but Cert is not found");
-            return null;
-        }
-
-        return new LbSslCert(certVO.getCertificate(), certVO.getKey(), certVO.getPassword(), certVO.getChain(), certVO.getFingerPrint(), lbCertMap.isRevoke());
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_CERT_ASSIGN, eventDescription = "assigning certificate to load balancer", async = true)
-    public boolean assignCertToLoadBalancer(long lbRuleId, Long certId) {
-        CallContext caller = CallContext.current();
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(lbRuleId));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid load balancer id: " + lbRuleId);
-        }
-
-        SslCertVO certVO = _entityMgr.findById(SslCertVO.class, certId);
-        if (certVO == null) {
-            throw new InvalidParameterException("Invalid certificate id: " + certId);
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        // check if LB and Cert belong to the same account
-        if (loadBalancer.getAccountId() != certVO.getAccountId()) {
-            throw new InvalidParameterValueException("Access denied for account " + certVO.getAccountId());
-        }
-
-        String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.SslTermination.getName());
-        if (capability == null) {
-            throw new InvalidParameterValueException("Ssl termination not supported by the loadbalancer");
-        }
-
-        //check if the lb is already bound
-        LoadBalancerCertMapVO certMapRule = _lbCertMapDao.findByLbRuleId(loadBalancer.getId());
-        if (certMapRule != null)
-            throw new InvalidParameterValueException("Another certificate is already bound to the LB");
-
-        //check for correct port
-        if (loadBalancer.getLbProtocol() == null || !(loadBalancer.getLbProtocol().equals(NetUtils.SSL_PROTO)))
-            throw new InvalidParameterValueException("Bad LB protocol: Expected ssl got " + loadBalancer.getLbProtocol());
-
-        boolean success = false;
-        FirewallRule.State backupState = loadBalancer.getState();
-
-        try {
-
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-            LoadBalancerCertMapVO certMap = new LoadBalancerCertMapVO(lbRuleId, certId, false);
-            _lbCertMapDao.persist(certMap);
-            applyLoadBalancerConfig(loadBalancer.getId());
-            success = true;
-        } catch (ResourceUnavailableException e) {
-            if (isRollBackAllowedForProvider(loadBalancer)) {
-
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                LoadBalancerCertMapVO certMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
-                _lbCertMapDao.remove(certMap.getId());
-                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while adding cert");
-            }
-            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-        }
-        return success;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_LB_CERT_REMOVE, eventDescription = "removing certificate from load balancer", async = true)
-    public boolean removeCertFromLoadBalancer(long lbRuleId) {
-        CallContext caller = CallContext.current();
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
-        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
-
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid load balancer value: " + lbRuleId);
-        }
-
-        if (lbCertMap == null) {
-            throw new InvalidParameterException("No certificate is bound to lb with id: " + lbRuleId);
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        boolean success = false;
-        FirewallRule.State backupState = loadBalancer.getState();
-        try {
-
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-            lbCertMap.setRevoke(true);
-            _lbCertMapDao.persist(lbCertMap);
-
-            if (!applyLoadBalancerConfig(lbRuleId)) {
-                s_logger.warn("Failed to remove cert from load balancer rule id " + lbRuleId);
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove certificate load balancer rule id " + lbRuleId);
-                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
-                throw ex;
-            }
-            success = true;
-        } catch (ResourceUnavailableException e) {
-            if (isRollBackAllowedForProvider(loadBalancer)) {
-                lbCertMap.setRevoke(false);
-                _lbCertMapDao.persist(lbCertMap);
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                s_logger.debug("Rolled back certificate removal lb id " + lbRuleId);
-            }
-            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-            if (!success) {
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove certificate from load balancer rule id " + lbRuleId);
-                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
-                throw ex;
-            }
-        }
-        return success;
-    }
-
-    private boolean removeFromLoadBalancerInternal(long loadBalancerId, List<Long> instanceIds, boolean rollBack, Map<Long, List<String>> vmIdIpMap) {
-        CallContext caller = CallContext.current();
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(loadBalancerId));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid load balancer value: " + loadBalancerId);
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
-
-        if (instanceIds == null && vmIdIpMap.isEmpty()) {
-            throw new InvalidParameterValueException("Both instanceids and vmidipmap  can't be null");
-        }
-
-        // instanceIds and vmIdipmap is passed
-        if (instanceIds != null && !vmIdIpMap.isEmpty()) {
-            for(long instanceId: instanceIds) {
-                if (!vmIdIpMap.containsKey(instanceId)) {
-                    vmIdIpMap.put(instanceId, null);
-                }
-            }
-        }
-
-        //only instanceids list passed
-        if (instanceIds != null && vmIdIpMap.isEmpty()){
-            vmIdIpMap = new HashMap<Long, List<String>>();
-            for (long instanceId: instanceIds){
-                vmIdIpMap.put(instanceId, null);
-            }
-        }
-
-
-
-        boolean success = false;
-        FirewallRule.State backupState = loadBalancer.getState();
-        Set<Long> vmIds = vmIdIpMap.keySet();
-        try {
-            loadBalancer.setState(FirewallRule.State.Add);
-            _lbDao.persist(loadBalancer);
-
-            for (long instanceId : vmIds) {
-                List<String> lbVmIps = vmIdIpMap.get(instanceId);
-
-                if (lbVmIps == null || lbVmIps.isEmpty()) {
-                    List<LoadBalancerVMMapVO> lbVms = _lb2VmMapDao.listByLoadBalancerIdAndVmId(loadBalancerId, instanceId);
-                    if (lbVms == null) {
-                        throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured "
-                                + " for LB rule id " + loadBalancerId);
-                    }
-
-                    for (LoadBalancerVMMapVO lbvm: lbVms) {
-                        lbvm.setRevoke(true);
-                        _lb2VmMapDao.persist(lbvm);
-                    }
-                    s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId);
-
-                } else {
-                    for (String vmIp: lbVmIps) {
-                        LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp);
-                        if (map == null) {
-                            throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured "
-                                    + " for LB rule id " + loadBalancerId);
-                        }
-                        map.setRevoke(true);
-                        _lb2VmMapDao.persist(map);
-                        s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " +
-                                instanceId + ", vmip " + vmIp);
-                    }
-                }
-            }
-
-            if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) {
-                // For autoscaled loadbalancer, the rules need not be applied,
-                // meaning the call need not reach the resource layer.
-                // We can consider the job done and only need to remove the
-                // rules in DB
-                _lb2VmMapDao.remove(loadBalancer.getId(), instanceIds, null);
-                return true;
-            }
-
-            if (!applyLoadBalancerConfig(loadBalancerId)) {
-                s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds);
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds);
-                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
-                throw ex;
-            }
-            success = true;
-        } catch (ResourceUnavailableException e) {
-            if (rollBack && isRollBackAllowedForProvider(loadBalancer)) {
-
-                for (long instanceId : vmIds) {
-                    List<String> lbVmIps = vmIdIpMap.get(instanceId);
-
-                    if (lbVmIps == null || lbVmIps.isEmpty()) {
-                        LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId);
-                        map.setRevoke(false);
-                        _lb2VmMapDao.persist(map);
-                        s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + instanceId);
-                    }else {
-                        for (String vmIp: lbVmIps) {
-                            LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp);
-                            map.setRevoke(true);
-                            _lb2VmMapDao.persist(map);
-                            s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " +
-                                    instanceId + ", vmip " + vmIp);
-                        }
-                    }
-                }
-
-                loadBalancer.setState(backupState);
-                _lbDao.persist(loadBalancer);
-                s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while removing vm instances");
-            }
-            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-        }
-        if (!success) {
-            CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + vmIds);
-            ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
-            throw ex;
-        }
-        return success;
-    }
-
-    @Override
-    public boolean removeVmFromLoadBalancers(long instanceId) {
-        boolean success = true;
-        List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByInstanceId(instanceId);
-        if (maps == null || maps.isEmpty()) {
-            return true;
-        }
-
-        Map<Long, List<Long>> lbsToReconfigure = new HashMap<Long, List<Long>>();
-
-        // first set all existing lb mappings with Revoke state
-        for (LoadBalancerVMMapVO map : maps) {
-            long lbId = map.getLoadBalancerId();
-            List<Long> instances = lbsToReconfigure.get(lbId);
-            if (instances == null) {
-                instances = new ArrayList<Long>();
-            }
-            instances.add(map.getInstanceId());
-            lbsToReconfigure.put(lbId, instances);
-
-            map.setRevoke(true);
-            _lb2VmMapDao.persist(map);
-            s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + instanceId);
-        }
-
-        // Reapply all lbs that had the vm assigned
-        if (lbsToReconfigure != null) {
-            for (Map.Entry<Long, List<Long>> lb : lbsToReconfigure.entrySet()) {
-                if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false, new HashMap<Long, List<String>>())) {
-                    success = false;
-                }
-            }
-        }
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_DELETE, eventDescription = "deleting load balancer", async = true)
-    public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply) {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        LoadBalancerVO rule = _lbDao.findById(loadBalancerId);
-
-        if (rule == null) {
-            throw new InvalidParameterValueException("Unable to find load balancer rule " + loadBalancerId);
-        }
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        boolean result = deleteLoadBalancerRule(loadBalancerId, apply, caller, ctx.getCallingUserId(), true);
-        if (!result) {
-            throw new CloudRuntimeException("Unable to remove load balancer rule " + loadBalancerId);
-        }
-        return result;
-    }
-
-    @DB
-    public boolean deleteLoadBalancerRule(final long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) {
-        final LoadBalancerVO lb = _lbDao.findById(loadBalancerId);
-        FirewallRule.State backupState = lb.getState();
-
-        // remove any ssl certs associated with this LB rule before trying to delete it.
-        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(loadBalancerId);
-        if (lbCertMap != null) {
-            boolean removeResult = removeCertFromLoadBalancer(loadBalancerId);
-            if (!removeResult) {
-                throw new CloudRuntimeException("Unable to remove certificate from load balancer rule " + loadBalancerId);
-            }
-        }
-
-        List<LoadBalancerVMMapVO> backupMaps = Transaction.execute(new TransactionCallback<List<LoadBalancerVMMapVO>>() {
-            @Override
-            public List<LoadBalancerVMMapVO> doInTransaction(TransactionStatus status) {
-                boolean generateUsageEvent = false;
-
-                if (lb.getState() == FirewallRule.State.Staged) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb);
-                    }
-                    generateUsageEvent = true;
-                } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) {
-                    lb.setState(FirewallRule.State.Revoke);
-                    _lbDao.persist(lb);
-                    generateUsageEvent = true;
-                }
-                List<LoadBalancerVMMapVO> backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
-                List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
-                if (maps != null) {
-                    for (LoadBalancerVMMapVO map : maps) {
-                        map.setRevoke(true);
-                        _lb2VmMapDao.persist(map);
-                        s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + map.getInstanceId());
-                    }
-                }
-
-                List<LBHealthCheckPolicyVO> hcPolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, null);
-                for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) {
-                    lbHealthCheck.setRevoke(true);
-                    _lb2healthcheckDao.persist(lbHealthCheck);
-                }
-
-                if (generateUsageEvent) {
-                    // Generate usage event right after all rules were marked for revoke
-                    Network network = _networkModel.getNetwork(lb.getNetworkId());
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), network.getDataCenterId(), lb.getId(),
-                            null, LoadBalancingRule.class.getName(), lb.getUuid());
-                }
-
-                return backupMaps;
-            }
-        });
-
-        // gather external network usage stats for this lb rule
-        NetworkVO network = _networkDao.findById(lb.getNetworkId());
-        if (network != null) {
-            if (_networkModel.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
-                _externalDeviceUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
-            }
-        }
-
-        if (apply) {
-            try {
-                if (!applyLoadBalancerConfig(loadBalancerId)) {
-                    s_logger.warn("Unable to apply the load balancer config");
-                    return false;
-                }
-            } catch (ResourceUnavailableException e) {
-                if (rollBack && isRollBackAllowedForProvider(lb)) {
-                    if (backupMaps != null) {
-                        for (LoadBalancerVMMapVO map : backupMaps) {
-                            _lb2VmMapDao.persist(map);
-                            s_logger.debug("LB Rollback rule id: " + loadBalancerId + ", vmId " + map.getInstanceId());
-                        }
-                    }
-                    lb.setState(backupState);
-                    _lbDao.persist(lb);
-                    s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while deleting LB rule.");
-                } else {
-                    s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-                }
-                return false;
-            }
-        }
-
-        FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(lb.getId());
-        if (relatedRule != null) {
-            s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() +
-                "; leaving it in Revoke state");
-            return false;
-        } else {
-            _firewallMgr.removeRule(lb);
-        }
-
-        // FIXME: breaking the dependency on ELB manager. This breaks
-        // functionality of ELB using virtual router
-        // Bug CS-15411 opened to document this
-        // _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller);
-
-        s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully");
-
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer")
-    public LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description, int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd,
-        Long ipAddrId, String protocol, String algorithm, long networkId, long lbOwnerId, boolean openFirewall, String lbProtocol, Boolean forDisplay) throws NetworkRuleConflictException,
-        InsufficientAddressCapacityException {
-        Account lbOwner = _accountMgr.getAccount(lbOwnerId);
-
-        if (srcPortStart != srcPortEnd) {
-            throw new InvalidParameterValueException("Port ranges are not supported by the load balancer");
-        }
-
-        IPAddressVO ipVO = null;
-        if (ipAddrId != null) {
-            ipVO = _ipAddressDao.findById(ipAddrId);
-        }
-
-        Network network = _networkModel.getNetwork(networkId);
-
-        // FIXME: breaking the dependency on ELB manager. This breaks
-        // functionality of ELB using virtual router
-        // Bug CS-15411 opened to document this
-        // LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb,
-        // lbOwner, lb.getNetworkId());
-        LoadBalancer result = null;
-        if (result == null) {
-            IpAddress systemIp = null;
-            NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-            if (off.getElasticLb() && ipVO == null && network.getVpcId() == null) {
-                systemIp = _ipAddrMgr.assignSystemIp(networkId, lbOwner, true, false);
-                if (systemIp != null) {
-                    ipVO = _ipAddressDao.findById(systemIp.getId());
-                }
-            }
-
-            // Validate ip address
-            if (ipVO == null) {
-                throw new InvalidParameterValueException("Unable to create load balance rule; can't find/allocate source IP");
-            } else if (ipVO.isOneToOneNat()) {
-                throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipVO.getAddress());
-            }
-
-            boolean performedIpAssoc = false;
-            try {
-                if (ipVO.getAssociatedWithNetworkId() == null) {
-                    boolean assignToVpcNtwk = network.getVpcId() != null && ipVO.getVpcId() != null && ipVO.getVpcId().longValue() == network.getVpcId();
-                    if (assignToVpcNtwk) {
-                        // set networkId just for verification purposes
-                        _networkModel.checkIpForService(ipVO, Service.Lb, networkId);
-
-                        s_logger.debug("The ip is not associated with the VPC network id=" + networkId + " so assigning");
-                        ipVO = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
-                        performedIpAssoc = true;
-                    }
-                } else {
-                    _networkModel.checkIpForService(ipVO, Service.Lb, null);
-                }
-
-                if (ipVO.getAssociatedWithNetworkId() == null) {
-                    throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + network);
-                }
-
-                result = createPublicLoadBalancer(xId, name, description, srcPortStart, defPortStart, ipVO.getId(), protocol, algorithm, openFirewall, CallContext.current(),
-                        lbProtocol, forDisplay);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to create load balancer due to ", ex);
-                if (ex instanceof NetworkRuleConflictException) {
-                    throw (NetworkRuleConflictException)ex;
-                }
-
-                if (ex instanceof InvalidParameterValueException) {
-                    throw (InvalidParameterValueException)ex;
-                }
-
-            } finally {
-                if (result == null && systemIp != null) {
-                    s_logger.debug("Releasing system IP address " + systemIp + " as corresponding lb rule failed to create");
-                    _ipAddrMgr.handleSystemIpRelease(systemIp);
-                }
-                // release ip address if ipassoc was perfored
-                if (performedIpAssoc) {
-                    ipVO = _ipAddressDao.findById(ipVO.getId());
-                    _vpcMgr.unassignIPFromVpcNetwork(ipVO.getId(), networkId);
-                }
-            }
-        }
-
-        if (result == null) {
-            throw new CloudRuntimeException("Failed to create load balancer rule: " + name);
-        }
-
-        return result;
-    }
-
-    @DB
-    @Override
-    public LoadBalancer createPublicLoadBalancer(final String xId, final String name, final String description, final int srcPort, final int destPort,
- final long sourceIpId,
-            final String protocol, final String algorithm, final boolean openFirewall, final CallContext caller, final String lbProtocol, final Boolean forDisplay)
-            throws NetworkRuleConflictException {
-
-        if (!NetUtils.isValidPort(destPort)) {
-            throw new InvalidParameterValueException("privatePort is an invalid value: " + destPort);
-        }
-
-        if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
-            throw new InvalidParameterValueException("Invalid algorithm: " + algorithm);
-        }
-
-        final IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId);
-        // make sure ip address exists
-        if (ipAddr == null || !ipAddr.readyToUse()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified");
-            if (ipAddr == null) {
-                ex.addProxyObject(String.valueOf(sourceIpId), "sourceIpId");
-            } else {
-                ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
-            }
-            throw ex;
-        } else if (ipAddr.isOneToOneNat()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled");
-            ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
-            throw ex;
-        }
-
-        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, ipAddr);
-
-        final Long networkId = ipAddr.getAssociatedWithNetworkId();
-        if (networkId == null) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network");
-            ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
-            throw ex;
-        }
-
-        // verify that lb service is supported by the network
-        isLbServiceSupportedInNetwork(networkId, Scheme.Public);
-
-        _firewallMgr.validateFirewallRule(caller.getCallingAccount(), ipAddr, srcPort, srcPort, protocol, Purpose.LoadBalancing, FirewallRuleType.User, networkId, null);
-
-        LoadBalancerVO newRule =
-            new LoadBalancerVO(xId, name, description, sourceIpId, srcPort, destPort, algorithm, networkId, ipAddr.getAllocatedToAccountId(),
-                ipAddr.getAllocatedInDomainId(), lbProtocol);
-
-        // verify rule is supported by Lb provider of the network
-        Ip sourceIp = getSourceIp(newRule);
-        LoadBalancingRule loadBalancing =
-            new LoadBalancingRule(newRule, new ArrayList<LbDestination>(), new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp, null,
-                lbProtocol);
-        if (!validateLbRule(loadBalancing)) {
-            throw new InvalidParameterValueException("LB service provider cannot support this rule");
-        }
-
-        return Transaction.execute(new TransactionCallbackWithException<LoadBalancerVO, NetworkRuleConflictException>() {
-            @Override
-            public LoadBalancerVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
-                LoadBalancerVO newRule =
-                    new LoadBalancerVO(xId, name, description, sourceIpId, srcPort, destPort, algorithm, networkId, ipAddr.getAllocatedToAccountId(),
-                        ipAddr.getAllocatedInDomainId(), lbProtocol);
-
-                if (forDisplay != null) {
-                    newRule.setDisplay(forDisplay);
-                }
-
-                // verify rule is supported by Lb provider of the network
-                Ip sourceIp = getSourceIp(newRule);
-                LoadBalancingRule loadBalancing =
-                    new LoadBalancingRule(newRule, new ArrayList<LbDestination>(), new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp,
-                        null, lbProtocol);
-                if (!validateLbRule(loadBalancing)) {
-                    throw new InvalidParameterValueException("LB service provider cannot support this rule");
-                }
-
-                newRule = _lbDao.persist(newRule);
-
-                //create rule for all CIDRs
-                if (openFirewall) {
-                    _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCallingAccount(), srcPort, srcPort, protocol, null, null, newRule.getId(), networkId);
-                }
-
-                boolean success = true;
-
-                try {
-                    _firewallMgr.detectRulesConflict(newRule);
-                    if (!_firewallDao.setStateToAdd(newRule)) {
-                        throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
-                    }
-                    s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + srcPort + ", private port " + destPort +
-                        " is added successfully.");
-                    CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId());
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(),
-                        null, LoadBalancingRule.class.getName(), newRule.getUuid());
-
-                    return newRule;
-                } catch (Exception e) {
-                    success = false;
-                    if (e instanceof NetworkRuleConflictException) {
-                        throw (NetworkRuleConflictException)e;
-                    }
-                    throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e);
-                } finally {
-                    if (!success && newRule != null) {
-                        _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                        removeLBRule(newRule);
-                    }
-                }
-            }
-        });
-
-    }
-
-    @Override
-    public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException {
-        LoadBalancerVO lb = _lbDao.findById(lbRuleId);
-        List<LoadBalancerVO> lbs;
-        if (isRollBackAllowedForProvider(lb)) {
-            // this is for Netscalar type of devices. if their is failure the db
-            // entries will be rollbacked.
-            lbs = Arrays.asList(lb);
-        } else {
-            boolean onlyRulesInTransitionState = true;
-            for (LoadBalancingServiceProvider lbElement : _lbProviders) {
-                Provider provider = lbElement.getProvider();
-                boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, provider);
-                if (!isLbProvider) {
-                    continue;
-                }
-                onlyRulesInTransitionState = lbElement.handlesOnlyRulesInTransitionState();
-                break;
-            }
-
-            // get all rules in transition state
-            if (onlyRulesInTransitionState) {
-                lbs = _lbDao.listInTransitionStateByNetworkIdAndScheme(lb.getNetworkId(), lb.getScheme());
-            } else {
-                lbs = _lbDao.listByNetworkIdAndScheme(lb.getNetworkId(), lb.getScheme());
-            }
-
-        }
-        return applyLoadBalancerRules(lbs, true);
-    }
-
-    @Override
-    public boolean revokeLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException {
-        List<LoadBalancerVO> lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Revoking " + lbs.size() + " " + scheme + " load balancing rules for network id=" + networkId);
-        }
-        if (lbs != null) {
-            for (LoadBalancerVO lb : lbs) { // called during restart, not persisting state in db
-                lb.setState(FirewallRule.State.Revoke);
-            }
-            return applyLoadBalancerRules(lbs, false); // called during restart, not persisting state in db
-        } else {
-            s_logger.info("Network id=" + networkId + " doesn't have load balancer rules, nothing to revoke");
-            return true;
-        }
-    }
-
-    @Override
-    public boolean applyLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException {
-        List<LoadBalancerVO> lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme);
-        if (lbs != null) {
-            s_logger.debug("Applying load balancer rules of scheme " + scheme + " in network id=" + networkId);
-            return applyLoadBalancerRules(lbs, true);
-        } else {
-            s_logger.info("Network id=" + networkId + " doesn't have load balancer rules of scheme " + scheme + ", nothing to apply");
-            return true;
-        }
-    }
-
-    protected boolean applyLbRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
-        boolean handled = false;
-        for (LoadBalancingServiceProvider lbElement : _lbProviders) {
-            Provider provider = lbElement.getProvider();
-            boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider);
-            if (!isLbProvider) {
-                continue;
-            }
-            handled = lbElement.applyLBRules(network, rules);
-            if (handled)
-                break;
-        }
-        return handled;
-    }
-
-    private LoadBalancingRule getLoadBalancerRuleToApply(LoadBalancerVO lb) {
-
-        List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
-        Ip sourceIp = getSourceIp(lb);
-        LbSslCert sslCert = getLbSslCert(lb.getId());
-        LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null, sourceIp, sslCert, lb.getLbProtocol());
-
-        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(lb.getId())) {
-            // Get the associated VmGroup
-            AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.listByAll(lb.getId(), null).get(0);
-            LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup, vmGroup.getState(), lb);
-            loadBalancing.setAutoScaleVmGroup(lbAutoScaleVmGroup);
-        } else {
-            List<LbDestination> dstList = getExistingDestinations(lb.getId());
-            loadBalancing.setDestinations(dstList);
-            List<LbHealthCheckPolicy> hcPolicyList = getHealthCheckPolicies(lb.getId());
-            loadBalancing.setHealthCheckPolicies(hcPolicyList);
-        }
-
-        return loadBalancing;
-    }
-
-    @DB
-    protected boolean applyLoadBalancerRules(List<LoadBalancerVO> lbs, boolean updateRulesInDB) throws ResourceUnavailableException {
-        List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
-        for (LoadBalancerVO lb : lbs) {
-            rules.add(getLoadBalancerRuleToApply(lb));
-        }
-
-        if (!applyLbRules(rules, false)) {
-            s_logger.debug("LB rules are not completely applied");
-            return false;
-        }
-
-        if (updateRulesInDB) {
-            for (final LoadBalancerVO lb : lbs) {
-                boolean checkForReleaseElasticIp = Transaction.execute(new TransactionCallback<Boolean>() {
-                    @Override
-                    public Boolean doInTransaction(TransactionStatus status) {
-                        boolean checkForReleaseElasticIp = false;
-
-                        if (lb.getState() == FirewallRule.State.Revoke) {
-                            removeLBRule(lb);
-                            s_logger.debug("LB " + lb.getId() + " is successfully removed");
-                            checkForReleaseElasticIp = true;
-                        } else if (lb.getState() == FirewallRule.State.Add) {
-                            lb.setState(FirewallRule.State.Active);
-                            s_logger.debug("LB rule " + lb.getId() + " state is set to Active");
-                            _lbDao.persist(lb);
-                        }
-
-                        // remove LB-Vm mappings that were state to revoke
-                        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true);
-                        List<Long> instanceIds = new ArrayList<Long>();
-
-                        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
-                            instanceIds.add(lbVmMap.getInstanceId());
-                            _lb2VmMapDao.remove(lb.getId(), lbVmMap.getInstanceId(), lbVmMap.getInstanceIp(), null);
-                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vm " +
-                                    lbVmMap.getInstanceId() + " instance ip " + lbVmMap.getInstanceIp());
-                        }
-
-
-                        if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) {
-                            lb.setState(FirewallRule.State.Add);
-                            _lbDao.persist(lb);
-                            s_logger.debug("LB rule " + lb.getId() + " state is set to Add as there are no more active LB-VM mappings");
-                        }
-
-                        // remove LB-Stickiness policy mapping that were state to revoke
-                        List<LBStickinessPolicyVO> stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lb.getId(), true);
-                        if (!stickinesspolicies.isEmpty()) {
-                            _lb2stickinesspoliciesDao.remove(lb.getId(), true);
-                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies");
-                        }
-
-                        // remove LB-HealthCheck policy mapping that were state to
-                        // revoke
-                        List<LBHealthCheckPolicyVO> healthCheckpolicies = _lb2healthcheckDao.listByLoadBalancerId(lb.getId(), true);
-                        if (!healthCheckpolicies.isEmpty()) {
-                            _lb2healthcheckDao.remove(lb.getId(), true);
-                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies");
-                        }
-
-                        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lb.getId());
-                        if (lbCertMap != null && lbCertMap.isRevoke()) {
-                            _lbCertMapDao.remove(lbCertMap.getId());
-                            s_logger.debug("Load balancer rule id " + lb.getId() + " removed certificate mapping");
-                        }
-
-                        return checkForReleaseElasticIp;
-                    }
-                });
-
-                if (checkForReleaseElasticIp && lb.getSourceIpAddressId() != null) {
-                    boolean success = true;
-                    long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId());
-                    if (count == 0) {
-                        try {
-                            success = handleSystemLBIpRelease(lb);
-                        } catch (Exception ex) {
-                            s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion due to exception ", ex);
-                            success = false;
-                        } finally {
-                            if (!success) {
-                                s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion");
-                            }
-                        }
-                    }
-                }
-                // if the rule is the last one for the ip address assigned to
-                // VPC, unassign it from the network
-                if (lb.getSourceIpAddressId() != null) {
-                    IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId());
-                    _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), lb.getNetworkId());
-                }
-            }
-        }
-
-        return true;
-    }
-
-    protected boolean handleSystemLBIpRelease(LoadBalancerVO lb) {
-        IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId());
-        boolean success = true;
-        if (ip.getSystem()) {
-            s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule");
-            if (!_ipAddrMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), CallContext.current().getCallingUserId(), CallContext.current().getCallingAccount())) {
-                s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
-                success = false;
-            } else {
-                s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
-            }
-        }
-        return success;
-    }
-
-    @Override
-    public boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId) {
-
-        //Included revoked rules to remove the rules of ips which are in revoke state
-        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.LoadBalancing);
-
-        if (rules != null) {
-            s_logger.debug("Found " + rules.size() + " lb rules to cleanup");
-            for (FirewallRule rule : rules) {
-                boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false);
-                if (result == false) {
-                    s_logger.warn("Unable to remove load balancer rule " + rule.getId());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId) {
-        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing);
-        if (rules != null) {
-            s_logger.debug("Found " + rules.size() + " lb rules to cleanup");
-            for (FirewallRule rule : rules) {
-                boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false);
-                if (result == false) {
-                    s_logger.warn("Unable to remove load balancer rule " + rule.getId());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public List<LbStickinessPolicy> getStickinessPolicies(long lbId) {
-        List<LbStickinessPolicy> stickinessPolicies = new ArrayList<LbStickinessPolicy>();
-        List<LBStickinessPolicyVO> sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lbId, false);
-
-        for (LBStickinessPolicyVO sDbPolicy : sDbpolicies) {
-            LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), sDbPolicy.isRevoke());
-            stickinessPolicies.add(sPolicy);
-        }
-        return stickinessPolicies;
-    }
-
-    @Override
-    public List<LbHealthCheckPolicy> getHealthCheckPolicies(long lbId) {
-        List<LbHealthCheckPolicy> healthCheckPolicies = new ArrayList<LbHealthCheckPolicy>();
-        List<LBHealthCheckPolicyVO> hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(lbId, null);
-
-        for (LBHealthCheckPolicyVO policy : hcDbpolicies) {
-            String pingpath = policy.getpingpath();
-            LbHealthCheckPolicy hDbPolicy =
-                new LbHealthCheckPolicy(pingpath, policy.getDescription(), policy.getResponseTime(), policy.getHealthcheckInterval(), policy.getHealthcheckThresshold(),
-                    policy.getUnhealthThresshold(), policy.isRevoke());
-            healthCheckPolicies.add(hDbPolicy);
-        }
-        return healthCheckPolicies;
-    }
-
-    @Override
-    public List<LbDestination> getExistingDestinations(long lbId) {
-        List<LbDestination> dstList = new ArrayList<LbDestination>();
-        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId);
-        LoadBalancerVO lb = _lbDao.findById(lbId);
-
-        String dstIp = null;
-        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
-            UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
-            Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId());
-            dstIp = lbVmMap.getInstanceIp() == null ? nic.getIPv4Address(): lbVmMap.getInstanceIp();
-            LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke());
-            dstList.add(lbDst);
-        }
-        return dstList;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_UPDATE, eventDescription = "updating load balancer", async = true)
-    public LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long lbRuleId = cmd.getId();
-        String name = cmd.getLoadBalancerName();
-        String description = cmd.getDescription();
-        String algorithm = cmd.getAlgorithm();
-        LoadBalancerVO lb = _lbDao.findById(lbRuleId);
-        LoadBalancerVO lbBackup = _lbDao.findById(lbRuleId);
-        String customId = cmd.getCustomId();
-        Boolean forDisplay = cmd.getDisplay();
-
-        if (lb == null) {
-            throw new InvalidParameterValueException("Unable to find lb rule by id=" + lbRuleId);
-        }
-
-        // check permissions
-        _accountMgr.checkAccess(caller, null, true, lb);
-
-        if (name != null) {
-            lb.setName(name);
-        }
-
-        if (description != null) {
-            lb.setDescription(description);
-        }
-
-        if (algorithm != null) {
-            lb.setAlgorithm(algorithm);
-        }
-
-        if (customId != null) {
-            lb.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            lb.setDisplay(forDisplay);
-        }
-
-        // Validate rule in LB provider
-        LoadBalancingRule rule = getLoadBalancerRuleToApply(lb);
-        if (!validateLbRule(rule)) {
-            throw new InvalidParameterValueException("Modifications in lb rule " + lbRuleId + " are not supported.");
-        }
-
-        LoadBalancerVO tmplbVo = _lbDao.findById(lbRuleId);
-        boolean success = _lbDao.update(lbRuleId, lb);
-
-        // If algorithm is changed, have to reapply the lb config
-        if ((algorithm != null) && (tmplbVo.getAlgorithm().compareTo(algorithm) != 0)){
-            try {
-                lb.setState(FirewallRule.State.Add);
-                _lbDao.persist(lb);
-                applyLoadBalancerConfig(lbRuleId);
-            } catch (ResourceUnavailableException e) {
-                if (isRollBackAllowedForProvider(lb)) {
-                    /*
-                     * NOTE : We use lb object to update db instead of lbBackup
-                     * object since db layer will fail to update if there is no
-                     * change in the object.
-                     */
-                    if (lbBackup.getName() != null) {
-                        lb.setName(lbBackup.getName());
-                    }
-                    if (lbBackup.getDescription() != null) {
-                        lb.setDescription(lbBackup.getDescription());
-                    }
-                    if (lbBackup.getAlgorithm() != null) {
-                        lb.setAlgorithm(lbBackup.getAlgorithm());
-                    }
-                    lb.setState(lbBackup.getState());
-                    _lbDao.update(lb.getId(), lb);
-                    _lbDao.persist(lb);
-
-                    s_logger.debug("LB Rollback rule id: " + lbRuleId + " while updating LB rule.");
-                }
-                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
-                success = false;
-            }
-        }
-
-        if (!success) {
-            throw new CloudRuntimeException("Failed to update load balancer rule: " + lbRuleId);
-        }
-
-        return lb;
-    }
-
-    @Override
-    public Pair<List<? extends UserVm>, List<String>> listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) throws PermissionDeniedException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long loadBalancerId = cmd.getId();
-        Boolean applied = cmd.isApplied();
-
-        if (applied == null) {
-            applied = Boolean.TRUE;
-        }
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
-        if (loadBalancer == null) {
-            return null;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, loadBalancer);
-
-        List<UserVmVO> loadBalancerInstances = new ArrayList<UserVmVO>();
-        List<String> serviceStates = new ArrayList<String>();
-        List<LoadBalancerVMMapVO> vmLoadBalancerMappings = null;
-        vmLoadBalancerMappings = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
-        if(vmLoadBalancerMappings == null) {
-            String msg = "no VM Loadbalancer Mapping found";
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        Map<Long, String> vmServiceState = new HashMap<Long, String>(vmLoadBalancerMappings.size());
-        List<Long> appliedInstanceIdList = new ArrayList<Long>();
-
-        if ((vmLoadBalancerMappings != null) && !vmLoadBalancerMappings.isEmpty()) {
-            for (LoadBalancerVMMapVO vmLoadBalancerMapping : vmLoadBalancerMappings) {
-                appliedInstanceIdList.add(vmLoadBalancerMapping.getInstanceId());
-                vmServiceState.put(vmLoadBalancerMapping.getInstanceId(), vmLoadBalancerMapping.getState());
-            }
-        }
-
-        List<UserVmVO> userVms = _vmDao.listVirtualNetworkInstancesByAcctAndNetwork(loadBalancer.getAccountId(), loadBalancer.getNetworkId());
-
-        for (UserVmVO userVm : userVms) {
-            // if the VM is destroyed, being expunged, in an error state, or in
-            // an unknown state, skip it
-            switch (userVm.getState()) {
-            case Destroyed:
-            case Expunging:
-            case Error:
-            case Unknown:
-                continue;
-            }
-
-            boolean isApplied = appliedInstanceIdList.contains(userVm.getId());
-            if ((isApplied && applied) || (!isApplied && !applied)) {
-                loadBalancerInstances.add(userVm);
-                serviceStates.add(vmServiceState.get(userVm.getId()));
-            }
-        }
-        return new Pair<List<? extends UserVm>, List<String>>(loadBalancerInstances, serviceStates);
-    }
-
-    @Override
-    public List<String> listLbVmIpAddress (long id, long vmId) {
-
-        List <LoadBalancerVMMapVO> listLbvmMapVo = _lb2VmMapDao.listByLoadBalancerIdAndVmId(id, vmId);
-
-        List <String> vmIps = new ArrayList<String>();
-        for (LoadBalancerVMMapVO lbVmVo : listLbvmMapVo) {
-            vmIps.add(lbVmVo.getInstanceIp());
-        }
-        return vmIps;
-    }
-
-    @Override
-    public List<LbStickinessMethod> getStickinessMethods(long networkid) {
-        String capability = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName());
-        if (capability == null) {
-            return null;
-        }
-        Gson gson = new Gson();
-        java.lang.reflect.Type listType = new TypeToken<List<LbStickinessMethod>>() {
-        }.getType();
-        List<LbStickinessMethod> result = gson.fromJson(capability, listType);
-        return result;
-    }
-
-    @Override
-    public List<LBStickinessPolicyVO> searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long loadBalancerId = cmd.getLbRuleId();
-        Long stickinessId = cmd.getId();
-
-        boolean forDisplay = cmd.getDisplay();
-        LoadBalancerVO loadBalancer = null;
-
-        if (loadBalancerId == null) {
-            loadBalancer = findLbByStickinessId(stickinessId);
-        } else {
-            loadBalancer = _lbDao.findById(loadBalancerId);
-        }
-
-        if (loadBalancer == null) {
-            return null;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, loadBalancer);
-
-        List<LBStickinessPolicyVO> sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerIdAndDisplayFlag(loadBalancer.getId(), forDisplay);
-
-        return sDbpolicies;
-    }
-
-    @Override
-    public List<LBHealthCheckPolicyVO> searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd cmd) throws PermissionDeniedException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long loadBalancerId = cmd.getLbRuleId();
-        Long policyId = cmd.getId();
-        boolean forDisplay = cmd.getDisplay();
-        if(loadBalancerId == null) {
-            loadBalancerId = findLBIdByHealtCheckPolicyId(policyId);
-        }
-        LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
-        if (loadBalancer == null) {
-            return null;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, loadBalancer);
-        List<LBHealthCheckPolicyVO> hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, forDisplay);
-
-        return hcDbpolicies;
-    }
-
-    @Override
-    public Pair<List<? extends LoadBalancer>, Integer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) {
-        Long ipId = cmd.getPublicIpId();
-        Long zoneId = cmd.getZoneId();
-        Long id = cmd.getId();
-        String name = cmd.getLoadBalancerRuleName();
-        String keyword = cmd.getKeyword();
-        Long instanceId = cmd.getVirtualMachineId();
-        Long networkId = cmd.getNetworkId();
-        Map<String, String> tags = cmd.getTags();
-        Boolean forDisplay = cmd.getDisplay();
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
-                cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
-                domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
-        sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        sb.and("scheme", sb.entity().getScheme(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
-
-        if (instanceId != null) {
-            SearchBuilder<LoadBalancerVMMapVO> lbVMSearch = _lb2VmMapDao.createSearchBuilder();
-            lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
-            sb.join("lbVMSearch", lbVMSearch, sb.entity().getId(), lbVMSearch.entity().getLoadBalancerId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (zoneId != null) {
-            SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
-            ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-            sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<LoadBalancerVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            SearchCriteria<LoadBalancerVO> ssc = _lbDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (ipId != null) {
-            sc.setParameters("sourceIpAddress", ipId);
-        }
-
-        if (instanceId != null) {
-            sc.setJoinParameters("lbVMSearch", "instanceId", instanceId);
-        }
-
-        if (zoneId != null) {
-            sc.setJoinParameters("ipSearch", "zoneId", zoneId);
-        }
-
-        if (networkId != null) {
-            sc.setParameters("networkId", networkId);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.LoadBalancer.toString());
-            for (String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        if (forDisplay != null) {
-            sc.setParameters("display", forDisplay);
-        }
-
-        //list only Public load balancers using this command
-        sc.setParameters("scheme", Scheme.Public);
-
-        Pair<List<LoadBalancerVO>, Integer> result = _lbDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends LoadBalancer>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public LoadBalancerVO findById(long lbId) {
-        return _lbDao.findById(lbId);
-    }
-
-    @Override
-    public LoadBalancerVO findLbByStickinessId(long stickinessPolicyId) {
-        LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId);
-
-        if (stickinessPolicy == null) {
-            return null;
-        }
-        return _lbDao.findById(stickinessPolicy.getLoadBalancerId());
-    }
-
-    @Override
-    public void removeLBRule(LoadBalancer rule) {
-        // remove the rule
-        _lbDao.remove(rule.getId());
-    }
-
-    public boolean applyLbRules(List<LoadBalancingRule> rules, boolean continueOnError) throws ResourceUnavailableException {
-        if (rules == null || rules.size() == 0) {
-            s_logger.debug("There are no Load Balancing Rules to forward to the network elements");
-            return true;
-        }
-
-        boolean success = true;
-        Network network = _networkModel.getNetwork(rules.get(0).getNetworkId());
-        List<PublicIp> publicIps = new ArrayList<PublicIp>();
-
-        // get the list of public ip's owned by the network
-        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
-        if (userIps != null && !userIps.isEmpty()) {
-            for (IPAddressVO userIp : userIps) {
-                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                publicIps.add(publicIp);
-            }
-        }
-
-        // rules can not programmed unless IP is associated with network
-        // service provider, so run IP assoication for
-        // the network so as to ensure IP is associated before applying
-        // rules (in add state)
-        _ipAddrMgr.applyIpAssociations(network, false, continueOnError, publicIps);
-
-        try {
-            applyLbRules(network, rules);
-        } catch (ResourceUnavailableException e) {
-            if (!continueOnError) {
-                throw e;
-            }
-            s_logger.warn("Problems with applying load balancing rules but pushing on", e);
-            success = false;
-        }
-
-        // if all the rules configured on public IP are revoked then
-        // dis-associate IP with network service provider
-        _ipAddrMgr.applyIpAssociations(network, true, continueOnError, publicIps);
-
-        return success;
-    }
-
-    @Override
-    public Map<Ip, UserVm> getLbInstances(long lbId) {
-        Map<Ip, UserVm> dstList = new HashMap<Ip, UserVm>();
-        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId);
-        LoadBalancerVO lb = _lbDao.findById(lbId);
-
-        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
-            UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
-            Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId());
-            Ip ip = new Ip(nic.getIPv4Address());
-            dstList.put(ip, vm);
-        }
-        return dstList;
-    }
-
-    @Override
-    public boolean isLbRuleMappedToVmGuestIp(String vmSecondaryIp) {
-        List<LoadBalancerVMMapVO> lbVmMap = _lb2VmMapDao.listByInstanceIp(vmSecondaryIp);
-        if (lbVmMap == null || lbVmMap.isEmpty()) {
-            return  false;
-        }
-        return true;
-    }
-
-    @Override
-    public void isLbServiceSupportedInNetwork(long networkId, Scheme scheme) {
-        Network network = _networkDao.findById(networkId);
-
-        //1) Check if the LB service is supported
-        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id");
-            ex.addProxyObject(network.getUuid(), "networkId");
-            throw ex;
-        }
-
-        //2) Check if the Scheme is supported\
-        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-        if (scheme == Scheme.Public) {
-            if (!off.getPublicLb()) {
-                throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off);
-            }
-        } else {
-            if (!off.getInternalLb()) {
-                throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off);
-            }
-        }
-
-        //3) Check if the provider supports the scheme
-        LoadBalancingServiceProvider lbProvider = _networkMgr.getLoadBalancingProviderForNetwork(network, scheme);
-        if (lbProvider == null) {
-            throw new InvalidParameterValueException("Lb rule with scheme " + scheme.toString() + " is not supported by lb providers in network " + network);
-        }
-    }
-
-    public List<LoadBalancingServiceProvider> getLbProviders() {
-        return _lbProviders;
-    }
-
-    @Inject
-    public void setLbProviders(List<LoadBalancingServiceProvider> lbProviders) {
-        this._lbProviders = lbProviders;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_UPDATE, eventDescription = "updating lb stickiness policy", async = true)
-    public StickinessPolicy updateLBStickinessPolicy(long id, String customId, Boolean forDisplay) {
-        LBStickinessPolicyVO policy = _lb2stickinesspoliciesDao.findById(id);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Fail to find stickiness policy with " + id);
-        }
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId()));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id);
-        }
-
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer);
-
-        if (customId != null) {
-            policy.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            policy.setDisplay(forDisplay);
-        }
-
-        _lb2stickinesspoliciesDao.update(id, policy);
-        return _lb2stickinesspoliciesDao.findById(id);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_UPDATE, eventDescription = "updating lb healthcheck policy", async = true)
-    public HealthCheckPolicy updateLBHealthCheckPolicy(long id, String customId, Boolean forDisplay) {
-        LBHealthCheckPolicyVO policy = _lb2healthcheckDao.findById(id);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Fail to find stickiness policy with " + id);
-        }
-
-        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId()));
-        if (loadBalancer == null) {
-            throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id);
-        }
-
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer);
-
-        if (customId != null) {
-            policy.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            policy.setDisplay(forDisplay);
-        }
-
-        _lb2healthcheckDao.update(id, policy);
-        return _lb2healthcheckDao.findById(id);
-    }
-
-    @Override
-    public Long findLBIdByHealtCheckPolicyId(long lbHealthCheckPolicy) {
-        LBHealthCheckPolicyVO policy= _lb2healthcheckDao.findById(lbHealthCheckPolicy);
-        if(policy != null) {
-            return policy.getLoadBalancerId();
-        }
-        return null;
-    }
-
-}
diff --git a/server/src/com/cloud/network/router/CommandSetupHelper.java b/server/src/com/cloud/network/router/CommandSetupHelper.java
deleted file mode 100644
index fe231c3..0000000
--- a/server/src/com/cloud/network/router/CommandSetupHelper.java
+++ /dev/null
@@ -1,1104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.router;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.routing.CreateIpAliasCommand;
-import com.cloud.agent.api.routing.DeleteIpAliasCommand;
-import com.cloud.agent.api.routing.DhcpEntryCommand;
-import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SavePasswordCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SetStaticRouteCommand;
-import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.VmDataCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.to.DhcpTO;
-import com.cloud.agent.api.to.FirewallRuleTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.NetworkACLTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.configuration.Config;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.VpnUser;
-import com.cloud.network.VpnUserVO;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
-import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
-import com.cloud.network.dao.Site2SiteVpnGatewayDao;
-import com.cloud.network.dao.Site2SiteVpnGatewayVO;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRule.LbDestination;
-import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.PrivateIpAddress;
-import com.cloud.network.vpc.StaticRouteProfile;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcGateway;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.user.Account;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicIpAlias;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicIpAliasVO;
-import com.cloud.vm.dao.UserVmDao;
-
-public class CommandSetupHelper {
-
-    private static final Logger s_logger = Logger.getLogger(CommandSetupHelper.class);
-
-    @Inject
-    private EntityManager _entityMgr;
-
-    @Inject
-    private NicDao _nicDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private DomainRouterDao _routerDao;
-    @Inject
-    private NetworkModel _networkModel;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private NicIpAliasDao _nicIpAliasDao;
-    @Inject
-    private FirewallRulesDao _rulesDao;
-    @Inject
-    private NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private VpnUserDao _vpnUsersDao;
-    @Inject
-    private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
-    @Inject
-    private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
-    @Inject
-    private VpcDao _vpcDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private IPAddressDao _ipAddressDao;
-
-    @Inject
-    private RouterControlHelper _routerControlHelper;
-
-    @Autowired
-    @Qualifier("networkHelper")
-    protected NetworkHelper _networkHelper;
-
-    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();
-        cmds.addCommand(
-                "vmdata",
-                generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIPv4Address(), vm.getHostName(), vm.getInstanceName(),
-                        vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId()));
-    }
-
-    public void createApplyVpnUsersCommand(final List<? extends VpnUser> users, final VirtualRouter router, final Commands cmds) {
-        final List<VpnUser> addUsers = new ArrayList<VpnUser>();
-        final List<VpnUser> removeUsers = new ArrayList<VpnUser>();
-        for (final VpnUser user : users) {
-            if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) {
-                addUsers.add(user);
-            } else if (user.getState() == VpnUser.State.Revoke) {
-                removeUsers.add(user);
-            }
-        }
-
-        final VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers);
-        cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("users", cmd);
-    }
-
-    public void createDhcpEntryCommand(final VirtualRouter router, final UserVm vm, final NicVO nic, boolean remove, final Commands cmds) {
-        final DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIPv4Address(), vm.getHostName(), nic.getIPv6Address(),
-                _networkModel.getExecuteInSeqNtwkElmtCmd());
-
-        String gatewayIp = nic.getIPv4Gateway();
-
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-
-        dhcpCommand.setDefaultRouter(gatewayIp);
-        dhcpCommand.setIp6Gateway(nic.getIPv6Gateway());
-        String ipaddress = null;
-        final NicVO domrDefaultNic = findDefaultDnsIp(vm.getId());
-        if (domrDefaultNic != null) {
-            ipaddress = domrDefaultNic.getIPv4Address();
-        }
-        dhcpCommand.setDefaultDns(ipaddress);
-        dhcpCommand.setDuid(NetUtils.getDuidLL(nic.getMacAddress()));
-        dhcpCommand.setDefault(nic.isDefaultNic());
-        dhcpCommand.setRemove(remove);
-
-        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId()));
-        dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("dhcp", dhcpCommand);
-    }
-
-    public void createIpAlias(final VirtualRouter router, final List<IpAliasTO> ipAliasTOs, final Long networkid, final Commands cmds) {
-
-        final String routerip = _routerControlHelper.getRouterIpInNetwork(networkid, router.getId());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        final CreateIpAliasCommand ipaliasCmd = new CreateIpAliasCommand(routerip, ipAliasTOs);
-        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerip);
-        ipaliasCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("ipalias", ipaliasCmd);
-    }
-
-    public void configDnsMasq(final VirtualRouter router, final Network network, final Commands cmds) {
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        final List<NicIpAliasVO> ipAliasVOList = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.active);
-        final List<DhcpTO> ipList = new ArrayList<DhcpTO>();
-
-        final NicVO router_guest_nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId());
-        final String cidr = NetUtils.getCidrFromGatewayAndNetmask(router_guest_nic.getIPv4Gateway(), router_guest_nic.getIPv4Netmask());
-        final String[] cidrPair = cidr.split("\\/");
-        final String cidrAddress = cidrPair[0];
-        final long cidrSize = Long.parseLong(cidrPair[1]);
-        final String startIpOfSubnet = NetUtils.getIpRangeStartIpFromCidr(cidrAddress, cidrSize);
-
-        ipList.add(new DhcpTO(router_guest_nic.getIPv4Address(), router_guest_nic.getIPv4Gateway(), router_guest_nic.getIPv4Netmask(), startIpOfSubnet));
-        for (final NicIpAliasVO ipAliasVO : ipAliasVOList) {
-            final DhcpTO DhcpTO = new DhcpTO(ipAliasVO.getIp4Address(), ipAliasVO.getGateway(), ipAliasVO.getNetmask(), ipAliasVO.getStartIpOfSubnet());
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("configDnsMasq : adding ip {" + DhcpTO.getGateway() + ", " + DhcpTO.getNetmask() + ", " + DhcpTO.getRouterIp() + ", " + DhcpTO.getStartIpOfSubnet()
-                        + "}");
-            }
-            ipList.add(DhcpTO);
-            ipAliasVO.setVmId(router.getId());
-        }
-        _dcDao.findById(router.getDataCenterId());
-        final DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(ipList);
-        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId()));
-        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand("dnsMasqConfig", dnsMasqConfigCmd);
-    }
-
-    public void createApplyLoadBalancingRulesCommands(final List<LoadBalancingRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()];
-        int i = 0;
-        // We don't support VR to be inline currently
-        final boolean inline = false;
-        for (final LoadBalancingRule rule : rules) {
-            final boolean revoked = rule.getState().equals(FirewallRule.State.Revoke);
-            final String protocol = rule.getProtocol();
-            final String lb_protocol = rule.getLbProtocol();
-            final String algorithm = rule.getAlgorithm();
-            final String uuid = rule.getUuid();
-
-            final String srcIp = rule.getSourceIp().addr();
-            final int srcPort = rule.getSourcePortStart();
-            final List<LbDestination> destinations = rule.getDestinations();
-            final List<LbStickinessPolicy> stickinessPolicies = rule.getStickinessPolicies();
-            final LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies);
-            lb.setLbProtocol(lb_protocol);
-            lbs[i++] = lb;
-        }
-        String routerPublicIp = null;
-
-        if (router instanceof DomainRouterVO) {
-            final DomainRouterVO domr = _routerDao.findById(router.getId());
-            routerPublicIp = domr.getPublicIpAddress();
-            if (routerPublicIp == null) {
-                routerPublicIp = router.getPublicIpAddress();
-            }
-        }
-
-        final Network guestNetwork = _networkModel.getNetwork(guestNetworkId);
-        final Nic nic = _nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), router.getId());
-        final NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(guestNetwork.getId(),
-                router.getId()), _networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), _networkModel.getNetworkTag(router.getHypervisorType(), guestNetwork));
-        final NetworkOffering offering = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId());
-        String maxconn = null;
-        if (offering.getConcurrentConnections() == null) {
-            maxconn = _configDao.getValue(Config.NetworkLBHaproxyMaxConn.key());
-        } else {
-            maxconn = offering.getConcurrentConnections().toString();
-        }
-
-        final LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, routerPublicIp, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()),
-                router.getPrivateIpAddress(), _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled());
-
-        cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key());
-        cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key());
-        cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key());
-        cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key());
-
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand(cmd);
-    }
-
-    public void createApplyPortForwardingRulesCommands(final List<? extends PortForwardingRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final List<PortForwardingRuleTO> rulesTO = new ArrayList<PortForwardingRuleTO>();
-        if (rules != null) {
-            for (final PortForwardingRule rule : rules) {
-                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                final PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, sourceIp.getAddress().addr());
-                rulesTO.add(ruleTO);
-            }
-        }
-
-        SetPortForwardingRulesCommand cmd = null;
-
-        if (router.getVpcId() != null) {
-            cmd = new SetPortForwardingRulesVpcCommand(rulesTO);
-        } else {
-            cmd = new SetPortForwardingRulesCommand(rulesTO);
-        }
-
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand(cmd);
-    }
-
-    public void createApplyStaticNatRulesCommands(final List<? extends StaticNatRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
-        if (rules != null) {
-            for (final StaticNatRule rule : rules) {
-                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                final StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getDestIpAddress());
-                rulesTO.add(ruleTO);
-            }
-        }
-
-        final SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId());
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand(cmd);
-    }
-
-    public void createApplyFirewallRulesCommands(final List<? extends FirewallRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
-        String systemRule = null;
-        Boolean defaultEgressPolicy = false;
-        if (rules != null) {
-            if (rules.size() > 0) {
-                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System) {
-                    systemRule = String.valueOf(FirewallRule.FirewallRuleType.System);
-                }
-            }
-            for (final FirewallRule rule : rules) {
-                _rulesDao.loadSourceCidrs((FirewallRuleVO) rule);
-                final FirewallRule.TrafficType traffictype = rule.getTrafficType();
-                if (traffictype == FirewallRule.TrafficType.Ingress) {
-                    final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype);
-                    rulesTO.add(ruleTO);
-                } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
-                    final NetworkVO network = _networkDao.findById(guestNetworkId);
-                    final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-                    defaultEgressPolicy = offering.getEgressDefaultPolicy();
-                    assert rule.getSourceIpAddressId() == null : "ipAddressId should be null for egress firewall rule. ";
-                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, "", Purpose.Firewall, traffictype, defaultEgressPolicy);
-                    rulesTO.add(ruleTO);
-                }
-            }
-        }
-
-        final SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        if (systemRule != null) {
-            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, systemRule);
-        } else {
-            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, String.valueOf(defaultEgressPolicy));
-        }
-
-        cmds.addCommand(cmd);
-    }
-
-    public void createFirewallRulesCommands(final List<? extends FirewallRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
-        String systemRule = null;
-        Boolean defaultEgressPolicy = false;
-        if (rules != null) {
-            if (rules.size() > 0) {
-                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System) {
-                    systemRule = String.valueOf(FirewallRule.FirewallRuleType.System);
-                }
-            }
-            for (final FirewallRule rule : rules) {
-                _rulesDao.loadSourceCidrs((FirewallRuleVO) rule);
-                _rulesDao.loadDestinationCidrs((FirewallRuleVO)rule);
-                final FirewallRule.TrafficType traffictype = rule.getTrafficType();
-                if (traffictype == FirewallRule.TrafficType.Ingress) {
-                    final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype);
-                    rulesTO.add(ruleTO);
-                } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
-                    final NetworkVO network = _networkDao.findById(guestNetworkId);
-                    final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-                    defaultEgressPolicy = offering.getEgressDefaultPolicy();
-                    assert rule.getSourceIpAddressId() == null : "ipAddressId should be null for egress firewall rule. ";
-                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, "", Purpose.Firewall, traffictype, defaultEgressPolicy);
-                    rulesTO.add(ruleTO);
-                }
-            }
-        }
-
-        final SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        if (systemRule != null) {
-            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, systemRule);
-        } else {
-            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, String.valueOf(defaultEgressPolicy));
-        }
-
-        cmds.addCommand(cmd);
-    }
-
-    public void createAssociateIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds, final long vmId) {
-        final String ipAssocCommand = "IPAssocCommand";
-        createRedundantAssociateIPCommands(router, ips, cmds, ipAssocCommand, false);
-    }
-
-    public void createNetworkACLsCommands(final List<? extends NetworkACLItem> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId,
-            final boolean privateGateway) {
-        final List<NetworkACLTO> rulesTO = new ArrayList<NetworkACLTO>();
-        String guestVlan = null;
-        final Network guestNtwk = _networkDao.findById(guestNetworkId);
-        final URI uri = guestNtwk.getBroadcastUri();
-        if (uri != null) {
-            guestVlan = BroadcastDomainType.getValue(uri);
-        }
-
-        if (rules != null) {
-            for (final NetworkACLItem rule : rules) {
-                final NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType());
-                rulesTO.add(ruleTO);
-            }
-        }
-
-        NicTO nicTO = _networkHelper.getNicTO(router, guestNetworkId, null);
-        final SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, nicTO);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        if (privateGateway) {
-            cmd.setAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY, String.valueOf(VpcGateway.Type.Private));
-        }
-
-        cmds.addCommand(cmd);
-    }
-
-    public void createPasswordCommand(final VirtualRouter router, final VirtualMachineProfile profile, final NicVO nic, final Commands cmds) {
-        final String password = (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword);
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-
-        // password should be set only on default network element
-        if (password != null && nic.isDefaultNic()) {
-            final SavePasswordCommand cmd = new SavePasswordCommand(password, nic.getIPv4Address(), profile.getVirtualMachine().getHostName(),
-                    _networkModel.getExecuteInSeqNtwkElmtCmd());
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-            cmds.addCommand("password", cmd);
-        }
-
-    }
-
-    public void createApplyStaticNatCommands(final List<? extends StaticNat> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
-        final List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
-        if (rules != null) {
-            for (final StaticNat rule : rules) {
-                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                final StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(),
-                        false);
-                rulesTO.add(ruleTO);
-            }
-        }
-
-        final SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId());
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand(cmd);
-    }
-
-    public void createStaticRouteCommands(final List<StaticRouteProfile> staticRoutes, final VirtualRouter router, final Commands cmds) {
-        final SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand(cmd);
-    }
-
-    public void createApplyVpnCommands(final boolean isCreate, final RemoteAccessVpn vpn, final VirtualRouter router, final Commands cmds) {
-        final List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
-
-        createApplyVpnUsersCommand(vpnUsers, router, cmds);
-
-        final IpAddress ip = _networkModel.getIp(vpn.getServerAddressId());
-
-        // This block is needed due to the line 206 of the
-        // RemoteAccessVpnManagenerImpl:
-        // TODO: assumes one virtual network / domr per account per zone
-        final String cidr;
-        final Network network = _networkDao.findById(vpn.getNetworkId());
-        if (network == null) {
-            final Vpc vpc = _vpcDao.findById(vpn.getVpcId());
-            cidr = vpc.getCidr();
-        } else {
-            cidr = network.getCidr();
-        }
-
-        final RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(isCreate, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(),
-                vpn.getIpsecPresharedKey(), vpn.getVpcId() != null);
-        startVpnCmd.setLocalCidr(cidr);
-        startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("startVpn", startVpnCmd);
-    }
-
-    public void createVmDataCommandForVMs(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());
-        for (final UserVmVO vm : vms) {
-            boolean createVmData = true;
-            if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()) {
-                createVmData = false;
-            }
-
-            if (createVmData) {
-                final NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId());
-                if (nic != null) {
-                    s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router);
-
-                    _userVmDao.loadDetails(vm);
-                    createVmDataCommand(router, vm, nic, vm.getDetail("SSH.PublicKey"), cmds);
-                }
-            }
-        }
-    }
-
-    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) {
-            if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()
-                    && dnsBasicZoneUpdates.equalsIgnoreCase("pod")) {
-                continue;
-            }
-
-            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, false, cmds);
-            }
-        }
-    }
-
-    public void createDeleteIpAliasCommand(final DomainRouterVO router, final List<IpAliasTO> deleteIpAliasTOs, final List<IpAliasTO> createIpAliasTos, final long networkId,
-            final Commands cmds) {
-        final String routerip = _routerControlHelper.getRouterIpInNetwork(networkId, router.getId());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        final DeleteIpAliasCommand deleteIpaliasCmd = new DeleteIpAliasCommand(routerip, deleteIpAliasTOs, createIpAliasTos);
-        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerip);
-        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("deleteIpalias", deleteIpaliasCmd);
-    }
-
-    public void createVpcAssociatePublicIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds,
-            final Map<String, String> vlanMacAddress) {
-
-        final String ipAssocCommand = "IPAssocVpcCommand";
-        if (router.getIsRedundantRouter()) {
-            createRedundantAssociateIPCommands(router, ips, cmds, ipAssocCommand, true);
-            return;
-        }
-
-        Pair<IpAddressTO, Long> sourceNatIpAdd = null;
-        Boolean addSourceNat = null;
-        // Ensure that in multiple vlans case we first send all ip addresses of
-        // vlan1, then all ip addresses of vlan2, etc..
-        final Map<String, ArrayList<PublicIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PublicIpAddress>>();
-        for (final PublicIpAddress ipAddress : ips) {
-            final String vlanTag = ipAddress.getVlanTag();
-            ArrayList<PublicIpAddress> ipList = vlanIpMap.get(vlanTag);
-            if (ipList == null) {
-                ipList = new ArrayList<PublicIpAddress>();
-            }
-            // VR doesn't support release for sourceNat IP address; so reset the
-            // state
-            if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) {
-                ipAddress.setState(IpAddress.State.Allocated);
-            }
-            ipList.add(ipAddress);
-            vlanIpMap.put(vlanTag, ipList);
-        }
-
-        for (final Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
-            final List<PublicIpAddress> ipAddrList = vlanAndIp.getValue();
-
-            // Source nat ip address should always be sent first
-            Collections.sort(ipAddrList, new Comparator<PublicIpAddress>() {
-                @Override
-                public int compare(final PublicIpAddress o1, final PublicIpAddress o2) {
-                    final boolean s1 = o1.isSourceNat();
-                    final boolean s2 = o2.isSourceNat();
-                    return s1 ^ s2 ? s1 ^ true ? 1 : -1 : 0;
-                }
-            });
-
-
-            // Get network rate - required for IpAssoc
-            final Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId());
-            final Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId());
-
-            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
-            int i = 0;
-            boolean firstIP = true;
-
-            for (final PublicIpAddress ipAddr : ipAddrList) {
-                final boolean add = ipAddr.getState() == IpAddress.State.Releasing ? false : true;
-                boolean sourceNat = ipAddr.isSourceNat();
-                /* enable sourceNAT for the first ip of the public interface
-                * For additional public subnet source nat rule needs to be added for vm to reach ips in that subnet
-                */
-                if (firstIP) {
-                    sourceNat = true;
-                }
-
-                final String macAddress = vlanMacAddress.get(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag())));
-
-                final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(),
-                        ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat());
-
-                ip.setTrafficType(network.getTrafficType());
-                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
-                ipsToSend[i++] = ip;
-                if (ipAddr.isSourceNat()) {
-                    sourceNatIpAdd = new Pair<IpAddressTO, Long>(ip, ipAddr.getNetworkId());
-                    addSourceNat = add;
-                }
-
-                //for additional public subnet on delete it is not sure which ip is set to first ip. So on delete we
-                //want to set sourcenat to true for all ips to delete source nat rules.
-                if (!firstIP || add) {
-                    firstIP = false;
-                }
-            }
-            final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend);
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-            cmds.addCommand(ipAssocCommand, cmd);
-        }
-
-        // set source nat ip
-        if (sourceNatIpAdd != null) {
-            final IpAddressTO sourceNatIp = sourceNatIpAdd.first();
-            final SetSourceNatCommand cmd = new SetSourceNatCommand(sourceNatIp, addSourceNat);
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-            cmds.addCommand("SetSourceNatCommand", cmd);
-        }
-    }
-
-    public void createRedundantAssociateIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds, final String ipAssocCommand, final boolean isVPC) {
-
-        // Ensure that in multiple vlans case we first send all ip addresses of
-        // vlan1, then all ip addresses of vlan2, etc..
-        final Map<String, ArrayList<PublicIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PublicIpAddress>>();
-        for (final PublicIpAddress ipAddress : ips) {
-            final String vlanTag = ipAddress.getVlanTag();
-            ArrayList<PublicIpAddress> ipList = vlanIpMap.get(vlanTag);
-            if (ipList == null) {
-                ipList = new ArrayList<PublicIpAddress>();
-            }
-            // domR doesn't support release for sourceNat IP address; so reset
-            // the state
-            if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) {
-                ipAddress.setState(IpAddress.State.Allocated);
-            }
-            ipList.add(ipAddress);
-            vlanIpMap.put(vlanTag, ipList);
-        }
-
-        final List<NicVO> nics = _nicDao.listByVmId(router.getId());
-        String baseMac = null;
-        for (final NicVO nic : nics) {
-            final NetworkVO nw = _networkDao.findById(nic.getNetworkId());
-            if (nw.getTrafficType() == TrafficType.Public) {
-                baseMac = nic.getMacAddress();
-                break;
-            }
-        }
-
-        for (final Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
-            final List<PublicIpAddress> ipAddrList = vlanAndIp.getValue();
-            // Source nat ip address should always be sent first
-            Collections.sort(ipAddrList, new Comparator<PublicIpAddress>() {
-                @Override
-                public int compare(final PublicIpAddress o1, final PublicIpAddress o2) {
-                    final boolean s1 = o1.isSourceNat();
-                    final boolean s2 = o2.isSourceNat();
-                    return s1 ^ s2 ? s1 ^ true ? 1 : -1 : 0;
-                }
-            });
-
-            // Get network rate - required for IpAssoc
-            final Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId());
-            final Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId());
-
-            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
-            int i = 0;
-            boolean firstIP = true;
-
-            for (final PublicIpAddress ipAddr : ipAddrList) {
-
-                final boolean add = ipAddr.getState() == IpAddress.State.Releasing ? false : true;
-                boolean sourceNat = ipAddr.isSourceNat();
-                /* enable sourceNAT for the first ip of the public interface */
-                if (firstIP) {
-                    sourceNat = true;
-                }
-                final String vlanId = ipAddr.getVlanTag();
-                final String vlanGateway = ipAddr.getGateway();
-                final String vlanNetmask = ipAddr.getNetmask();
-                String vifMacAddress = null;
-                // For non-source nat IP, set the mac to be something based on
-                // first public nic's MAC
-                // We cannot depend on first ip because we need to deal with
-                // first ip of other nics
-                if (router.getVpcId() != null) {
-                    //vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId());
-                    vifMacAddress = ipAddr.getMacAddress();
-                } else {
-                    if (!sourceNat && ipAddr.getVlanId() != 0) {
-                        vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId());
-                    } else {
-                        vifMacAddress = ipAddr.getMacAddress();
-                    }
-                }
-
-                final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask,
-                        vifMacAddress, networkRate, ipAddr.isOneToOneNat());
-
-                ip.setTrafficType(network.getTrafficType());
-                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
-                ipsToSend[i++] = ip;
-                /*
-                 * send the firstIP = true for the first Add, this is to create
-                 * primary on interface
-                 */
-                if (!firstIP || add) {
-                    firstIP = false;
-                }
-            }
-
-            Long associatedWithNetworkId = ipAddrList.get(0).getAssociatedWithNetworkId();
-            if (associatedWithNetworkId == null || associatedWithNetworkId == 0) {
-                associatedWithNetworkId = ipAddrList.get(0).getNetworkId();
-            }
-
-            // for network if the ips does not have any rules, then only last ip
-            final List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(associatedWithNetworkId, null);
-            boolean hasSourceNat = false;
-            if (isVPC && userIps.size() > 0 && userIps.get(0) != null) {
-                // All ips should belong to a VPC
-                final Long vpcId = userIps.get(0).getVpcId();
-                final List<IPAddressVO> sourceNatIps = _ipAddressDao.listByAssociatedVpc(vpcId, true);
-                if (sourceNatIps != null && sourceNatIps.size() > 0) {
-                    hasSourceNat = true;
-                }
-            }
-
-            int ipsWithrules = 0;
-            int ipsStaticNat = 0;
-            for (IPAddressVO ip : userIps) {
-                if ( _rulesDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active) > 0){
-                    ipsWithrules++;
-                }
-
-                // check onetoonenat and also check if the ip "add":false. If there are 2 PF rules remove and
-                // 1 static nat rule add
-                if (ip.isOneToOneNat() && ip.getRuleState() == null) {
-                    ipsStaticNat++;
-                }
-            }
-
-            final IpAssocCommand cmd = new IpAssocCommand(ipsToSend);
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(associatedWithNetworkId, router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-            // if there is 1 static nat then it will be checked for remove at the resource
-            if (ipsWithrules == 0 && ipsStaticNat == 0 && !hasSourceNat) {
-                // there is only one ip address for the network.
-                cmd.setAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP, "true");
-            } else {
-                cmd.setAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP, "false");
-            }
-
-            cmds.addCommand(ipAssocCommand, cmd);
-        }
-    }
-
-    public void createStaticRouteCommands(final List<StaticRouteProfile> staticRoutes, final DomainRouterVO router, final Commands cmds) {
-        final SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand(cmd);
-    }
-
-    public void createSite2SiteVpnCfgCommands(final Site2SiteVpnConnection conn, final boolean isCreate, final VirtualRouter router, final Commands cmds) {
-        final Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
-        final Site2SiteVpnGatewayVO vpnGw = _s2sVpnGatewayDao.findById(conn.getVpnGatewayId());
-        final IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId());
-        final Vpc vpc = _vpcDao.findById(ip.getVpcId());
-        final String localPublicIp = ip.getAddress().toString();
-        final String localGuestCidr = vpc.getCidr();
-        final String localPublicGateway = _vlanDao.findById(ip.getVlanId()).getVlanGateway();
-        final String peerGatewayIp = gw.getGatewayIp();
-        final String peerGuestCidrList = gw.getGuestCidrList();
-        final String ipsecPsk = gw.getIpsecPsk();
-        final String ikePolicy = gw.getIkePolicy();
-        final String espPolicy = gw.getEspPolicy();
-        final Long ikeLifetime = gw.getIkeLifetime();
-        final Long espLifetime = gw.getEspLifetime();
-        final Boolean dpd = gw.getDpd();
-        final Boolean encap = gw.getEncap();
-
-        final Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, peerGatewayIp, peerGuestCidrList, ikePolicy,
-                espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive(), encap);
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-        cmds.addCommand("applyS2SVpn", cmd);
-    }
-
-    public void createVpcAssociatePrivateIPCommands(final VirtualRouter router, final List<PrivateIpAddress> ips, final Commands cmds, final boolean add) {
-
-        // Ensure that in multiple vlans case we first send all ip addresses of
-        // vlan1, then all ip addresses of vlan2, etc..
-        final Map<String, ArrayList<PrivateIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PrivateIpAddress>>();
-        for (final PrivateIpAddress ipAddress : ips) {
-            final String vlanTag = ipAddress.getBroadcastUri();
-            ArrayList<PrivateIpAddress> ipList = vlanIpMap.get(vlanTag);
-            if (ipList == null) {
-                ipList = new ArrayList<PrivateIpAddress>();
-            }
-
-            ipList.add(ipAddress);
-            vlanIpMap.put(vlanTag, ipList);
-        }
-
-        for (final Map.Entry<String, ArrayList<PrivateIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
-            final List<PrivateIpAddress> ipAddrList = vlanAndIp.getValue();
-            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
-            int i = 0;
-
-            for (final PrivateIpAddress ipAddr : ipAddrList) {
-                final Network network = _networkModel.getNetwork(ipAddr.getNetworkId());
-                final IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false, ipAddr.getSourceNat(), ipAddr.getBroadcastUri(),
-                        ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(), null, false);
-
-                ip.setTrafficType(network.getTrafficType());
-                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
-                ipsToSend[i++] = ip;
-
-            }
-            final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend);
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId()));
-            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-            cmds.addCommand("IPAssocVpcCommand", cmd);
-        }
-    }
-
-    public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRouterVO router, final boolean add, final NicProfile guestNic) {
-        final Network network = _networkModel.getNetwork(guestNic.getNetworkId());
-
-        String defaultDns1 = null;
-        String defaultDns2 = null;
-
-        final boolean dnsProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter);
-        final boolean dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VPCVirtualRouter);
-
-        final boolean setupDns = dnsProvided || dhcpProvided;
-
-        if (setupDns) {
-            defaultDns1 = guestNic.getIPv4Dns1();
-            defaultDns2 = guestNic.getIPv4Dns2();
-        }
-
-        final Nic nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId());
-        final String networkDomain = network.getNetworkDomain();
-        final String dhcpRange = getGuestDhcpRange(guestNic, network, _entityMgr.findById(DataCenter.class, network.getDataCenterId()));
-
-        final NicProfile nicProfile = _networkModel.getNicProfile(router, nic.getNetworkId(), null);
-
-        final SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, router.getIsRedundantRouter(), defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile,
-                router.getHypervisorType()));
-
-        final String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIPv4Address()) | ~NetUtils.ip2Long(guestNic.getIPv4Netmask()));
-        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId()));
-
-        setupCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, network.getGateway());
-        setupCmd.setAccessDetail(NetworkElementCommand.GUEST_BRIDGE, brd);
-        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-
-        if (network.getBroadcastDomainType() == BroadcastDomainType.Vlan) {
-            final long guestVlanTag = Long.parseLong(BroadcastDomainType.Vlan.getValueFrom(network.getBroadcastUri()));
-            setupCmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
-        }
-
-        return setupCmd;
-    }
-
-    private VmDataCommand generateVmDataCommand(final VirtualRouter router, final String vmPrivateIpAddress, final String userData, final String serviceOffering,
-            final String zoneName, final String guestIpAddress, final String vmName, final String vmInstanceName, final long vmId, final String vmUuid, final String publicKey,
-            final long guestNetworkId) {
-        final VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd());
-
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
-        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmd.addVmData("userdata", "user-data", userData);
-        cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
-        cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
-        cmd.addVmData("metadata", "local-ipv4", guestIpAddress);
-        cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vmName));
-        if (dcVo.getNetworkType() == NetworkType.Basic) {
-            cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
-            cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName));
-        } else {
-            if (router.getPublicIpAddress() == null) {
-                cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
-            } else {
-                cmd.addVmData("metadata", "public-ipv4", router.getPublicIpAddress());
-            }
-            cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress());
-        }
-        if (vmUuid == null) {
-            cmd.addVmData("metadata", "instance-id", vmInstanceName);
-            cmd.addVmData("metadata", "vm-id", String.valueOf(vmId));
-        } else {
-            cmd.addVmData("metadata", "instance-id", vmUuid);
-            cmd.addVmData("metadata", "vm-id", vmUuid);
-        }
-        cmd.addVmData("metadata", "public-keys", publicKey);
-
-        String cloudIdentifier = _configDao.getValue("cloud.identifier");
-        if (cloudIdentifier == null) {
-            cloudIdentifier = "";
-        } else {
-            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
-        }
-        cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);
-
-        return cmd;
-    }
-
-    private NicVO findGatewayIp(final long userVmId) {
-        final NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId);
-        return defaultNic;
-    }
-
-    private NicVO findDefaultDnsIp(final long userVmId) {
-        final NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId);
-
-        // check if DNS provider is the domR
-        if (!_networkModel.isProviderSupportServiceInNetwork(defaultNic.getNetworkId(), Service.Dns, Provider.VirtualRouter)) {
-            return null;
-        }
-
-        final NetworkOffering offering = _networkOfferingDao.findById(_networkDao.findById(defaultNic.getNetworkId()).getNetworkOfferingId());
-        if (offering.getRedundantRouter()) {
-            return findGatewayIp(userVmId);
-        }
-
-        final DataCenter dc = _dcDao.findById(_networkModel.getNetwork(defaultNic.getNetworkId()).getDataCenterId());
-        final boolean isZoneBasic = dc.getNetworkType() == NetworkType.Basic;
-
-        // find domR's nic in the network
-        NicVO domrDefaultNic;
-        if (isZoneBasic) {
-            domrDefaultNic = _nicDao.findByNetworkIdTypeAndGateway(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter, defaultNic.getIPv4Gateway());
-        } else {
-            domrDefaultNic = _nicDao.findByNetworkIdAndType(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter);
-        }
-        return domrDefaultNic;
-    }
-
-    protected String getGuestDhcpRange(final NicProfile guestNic, final Network guestNetwork, final DataCenter dc) {
-        String dhcpRange = null;
-        // setup dhcp range
-        if (dc.getNetworkType() == NetworkType.Basic) {
-            final long cidrSize = NetUtils.getCidrSize(guestNic.getIPv4Netmask());
-            final String cidr = NetUtils.getCidrSubNet(guestNic.getIPv4Gateway(), cidrSize);
-            if (cidr != null) {
-                dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
-            }
-        } else if (dc.getNetworkType() == NetworkType.Advanced) {
-            final String cidr = guestNetwork.getCidr();
-            if (cidr != null) {
-                dhcpRange = NetUtils.getDhcpRange(cidr);
-            }
-        }
-        return dhcpRange;
-    }
-}
diff --git a/server/src/com/cloud/network/router/NetworkHelperImpl.java b/server/src/com/cloud/network/router/NetworkHelperImpl.java
deleted file mode 100644
index 1262158..0000000
--- a/server/src/com/cloud/network/router/NetworkHelperImpl.java
+++ /dev/null
@@ -1,885 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.router;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.log4j.Logger;
-import org.cloud.network.router.deployment.RouterDeploymentDefinition;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.Config;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.Pod;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientServerCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.maint.Version;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.router.VirtualRouter.RedundantState;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.network.rules.LbStickinessMethod;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.resource.ResourceManager;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile.Param;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-
-public class NetworkHelperImpl implements NetworkHelper {
-
-    private static final Logger s_logger = Logger.getLogger(NetworkHelperImpl.class);
-
-    protected static Account s_systemAccount;
-    protected static String s_vmInstanceName;
-
-    @Inject
-    protected NicDao _nicDao;
-    @Inject
-    protected NetworkDao _networkDao;
-    @Inject
-    protected DomainRouterDao _routerDao;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private AlertManager _alertMgr;
-    @Inject
-    protected NetworkModel _networkModel;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private Site2SiteVpnManager _s2sVpnMgr;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    protected IPAddressDao _ipAddressDao;
-    @Inject
-    private UserIpv6AddressDao _ipv6Dao;
-    @Inject
-    protected NetworkOrchestrationService _networkMgr;
-    @Inject
-    private UserDao _userDao;
-    @Inject
-    protected ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    protected VirtualMachineManager _itMgr;
-    @Inject
-    protected IpAddressManager _ipAddrMgr;
-    @Inject
-    ConfigurationDao _configDao;
-
-    protected final Map<HypervisorType, ConfigKey<String>> hypervisorsMap = new HashMap<>();
-
-    @PostConstruct
-    protected void setupHypervisorsMap() {
-        hypervisorsMap.put(HypervisorType.XenServer, VirtualNetworkApplianceManager.RouterTemplateXen);
-        hypervisorsMap.put(HypervisorType.KVM, VirtualNetworkApplianceManager.RouterTemplateKvm);
-        hypervisorsMap.put(HypervisorType.VMware, VirtualNetworkApplianceManager.RouterTemplateVmware);
-        hypervisorsMap.put(HypervisorType.Hyperv, VirtualNetworkApplianceManager.RouterTemplateHyperV);
-        hypervisorsMap.put(HypervisorType.LXC, VirtualNetworkApplianceManager.RouterTemplateLxc);
-        hypervisorsMap.put(HypervisorType.Ovm3, VirtualNetworkApplianceManager.RouterTemplateOvm3);
-    }
-
-    @Override
-    public boolean sendCommandsToRouter(final VirtualRouter router, final Commands cmds) throws AgentUnavailableException, ResourceUnavailableException {
-        if (!checkRouterVersion(router)) {
-            s_logger.debug("Router requires upgrade. Unable to send command to router:" + router.getId() + ", router template version : " + router.getTemplateVersion()
-                    + ", minimal required version : " + NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId()));
-            throw new ResourceUnavailableException("Unable to send command. Router requires upgrade", VirtualRouter.class, router.getId());
-        }
-        Answer[] answers = null;
-        try {
-            answers = _agentMgr.send(router.getHostId(), cmds);
-        } catch (final OperationTimedoutException e) {
-            s_logger.warn("Timed Out", e);
-            throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
-        }
-
-        if (answers == null || answers.length != cmds.size()) {
-            return false;
-        }
-
-        // FIXME: Have to return state for individual command in the future
-        boolean result = true;
-        for (final Answer answer : answers) {
-            if (!answer.getResult()) {
-                result = false;
-                break;
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public void handleSingleWorkingRedundantRouter(final List<? extends VirtualRouter> connectedRouters, final List<? extends VirtualRouter> disconnectedRouters,
-            final String reason) throws ResourceUnavailableException {
-        if (connectedRouters.isEmpty() || disconnectedRouters.isEmpty()) {
-            return;
-        }
-
-        for (final VirtualRouter virtualRouter : connectedRouters) {
-            if (!virtualRouter.getIsRedundantRouter()) {
-                throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId());
-            }
-        }
-
-        for (final VirtualRouter virtualRouter : disconnectedRouters) {
-            if (!virtualRouter.getIsRedundantRouter()) {
-                throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId());
-            }
-        }
-
-        final DomainRouterVO connectedRouter = (DomainRouterVO) connectedRouters.get(0);
-        DomainRouterVO disconnectedRouter = (DomainRouterVO) disconnectedRouters.get(0);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("About to stop the router " + disconnectedRouter.getInstanceName() + " due to: " + reason);
-        }
-        final String title = "Virtual router " + disconnectedRouter.getInstanceName() + " would be stopped after connecting back, due to " + reason;
-        final String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId()
-                + ") would be stopped after connecting back, due to: " + reason;
-        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, disconnectedRouter.getDataCenterId(), disconnectedRouter.getPodIdToDeployIn(), title, context);
-        disconnectedRouter.setStopPending(true);
-        disconnectedRouter = _routerDao.persist(disconnectedRouter);
-    }
-
-    @Override
-    public NicTO getNicTO(final VirtualRouter router, final Long networkId, final String broadcastUri) {
-        final NicProfile nicProfile = _networkModel.getNicProfile(router, networkId, broadcastUri);
-
-        return _itMgr.toNicTO(nicProfile, router.getHypervisorType());
-    }
-
-    @Override
-    public VirtualRouter destroyRouter(final long routerId, final Account caller, final Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Attempting to destroy router " + routerId);
-        }
-
-        final DomainRouterVO router = _routerDao.findById(routerId);
-        if (router == null) {
-            return null;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, router);
-
-        _itMgr.expunge(router.getUuid());
-        _routerDao.remove(router.getId());
-        return router;
-    }
-
-    @Override
-    public boolean checkRouterVersion(final VirtualRouter router) {
-        if (!VirtualNetworkApplianceManagerImpl.routerVersionCheckEnabled.value()) {
-            // Router version check is disabled.
-            return true;
-        }
-        if (router.getTemplateVersion() == null) {
-            return false;
-        }
-        final long dcid = router.getDataCenterId();
-        final String trimmedVersion = Version.trimRouterVersion(router.getTemplateVersion());
-        return Version.compare(trimmedVersion, NetworkOrchestrationService.MinVRVersion.valueIn(dcid)) >= 0;
-    }
-
-    protected DomainRouterVO start(DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params, final DeploymentPlan planToDeploy)
-            throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-        s_logger.debug("Starting router " + router);
-        try {
-            _itMgr.advanceStart(router.getUuid(), params, planToDeploy, null);
-        } catch (final OperationTimedoutException e) {
-            throw new ResourceUnavailableException("Starting router " + router + " failed! " + e.toString(), DataCenter.class, router.getDataCenterId());
-        }
-        if (router.isStopPending()) {
-            s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after start router successfully!");
-            router.setStopPending(false);
-            router = _routerDao.persist(router);
-        }
-        // We don't want the failure of VPN Connection affect the status of
-        // router, so we try to make connection
-        // only after router start successfully
-        final Long vpcId = router.getVpcId();
-        if (vpcId != null) {
-            _s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId);
-        }
-        return _routerDao.findById(router.getId());
-    }
-
-    protected DomainRouterVO waitRouter(final DomainRouterVO router) {
-        DomainRouterVO vm = _routerDao.findById(router.getId());
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Router " + router.getInstanceName() + " is not fully up yet, we will wait");
-        }
-        while (vm.getState() == State.Starting) {
-            try {
-                Thread.sleep(1000);
-            } catch (final InterruptedException e) {
-            }
-
-            // reload to get the latest state info
-            vm = _routerDao.findById(router.getId());
-        }
-
-        if (vm.getState() == State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Router " + router.getInstanceName() + " is now fully up");
-            }
-
-            return router;
-        }
-
-        s_logger.warn("Router " + router.getInstanceName() + " failed to start. current state: " + vm.getState());
-        return null;
-    }
-
-    @Override
-    public List<DomainRouterVO> startRouters(final RouterDeploymentDefinition routerDeploymentDefinition) throws StorageUnavailableException, InsufficientCapacityException,
-    ConcurrentOperationException, ResourceUnavailableException {
-
-        final List<DomainRouterVO> runningRouters = new ArrayList<DomainRouterVO>();
-
-        for (DomainRouterVO router : routerDeploymentDefinition.getRouters()) {
-            boolean skip = false;
-            final State state = router.getState();
-            if (router.getHostId() != null && state != State.Running) {
-                final HostVO host = _hostDao.findById(router.getHostId());
-                if (host == null || host.getState() != Status.Up) {
-                    skip = true;
-                }
-            }
-            if (!skip) {
-                if (state != State.Running) {
-                    router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams());
-                }
-                if (router != null) {
-                    runningRouters.add(router);
-                }
-            }
-        }
-        return runningRouters;
-    }
-
-    @Override
-    public DomainRouterVO startVirtualRouter(final DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params)
-            throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-
-        if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) {
-            return start(router, user, caller, params, null);
-        }
-
-        if (router.getState() == State.Running) {
-            s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!");
-            return router;
-        }
-
-        //
-        // If another thread has already requested a VR start, there is a
-        // transition period for VR to transit from
-        // Starting to Running, there exist a race conditioning window here
-        // We will wait until VR is up or fail
-        if (router.getState() == State.Starting) {
-            return waitRouter(router);
-        }
-
-        final DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null);
-        DomainRouterVO result = null;
-        assert router.getIsRedundantRouter();
-        final List<Long> networkIds = _routerDao.getRouterNetworks(router.getId());
-
-        DomainRouterVO routerToBeAvoid = null;
-        List<DomainRouterVO> routerList = null;
-        if (networkIds.size() != 0) {
-            routerList = _routerDao.findByNetwork(networkIds.get(0));
-        } else if (router.getVpcId() != null) {
-            routerList = _routerDao.listByVpcId(router.getVpcId());
-        }
-        if (routerList != null) {
-            for (final DomainRouterVO rrouter : routerList) {
-                if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) {
-                    if (routerToBeAvoid != null) {
-                        throw new ResourceUnavailableException("Try to start router " + router.getInstanceName() + "(" + router.getId() + ")"
-                                + ", but there are already two redundant routers with IP " + router.getPublicIpAddress() + ", they are " + rrouter.getInstanceName() + "("
-                                + rrouter.getId() + ") and " + routerToBeAvoid.getInstanceName() + "(" + routerToBeAvoid.getId() + ")", DataCenter.class,
-                                rrouter.getDataCenterId());
-                    }
-                    routerToBeAvoid = rrouter;
-                }
-            }
-        }
-        if (routerToBeAvoid == null) {
-            return start(router, user, caller, params, null);
-        }
-        // We would try best to deploy the router to another place
-        final int retryIndex = 5;
-        final ExcludeList[] avoids = new ExcludeList[5];
-        avoids[0] = new ExcludeList();
-        avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn());
-        avoids[1] = new ExcludeList();
-        avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId());
-        avoids[2] = new ExcludeList();
-        final List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT);
-        if (volumes != null && volumes.size() != 0) {
-            avoids[2].addPool(volumes.get(0).getPoolId());
-        }
-        avoids[2].addHost(routerToBeAvoid.getHostId());
-        avoids[3] = new ExcludeList();
-        avoids[3].addHost(routerToBeAvoid.getHostId());
-        avoids[4] = new ExcludeList();
-
-        for (int i = 0; i < retryIndex; i++) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Try to deploy redundant virtual router:" + router.getHostName() + ", for " + i + " time");
-            }
-            plan.setAvoids(avoids[i]);
-            try {
-                result = start(router, user, caller, params, plan);
-            } catch (final InsufficientServerCapacityException ex) {
-                result = null;
-            }
-            if (result != null) {
-                break;
-            }
-        }
-        return result;
-    }
-
-    protected String retrieveTemplateName(final HypervisorType hType, final long datacenterId) {
-        String templateName = null;
-
-        if (hType == HypervisorType.BareMetal) {
-            final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(HypervisorType.VMware);
-            templateName = hypervisorConfigKey.valueIn(datacenterId);
-        } else {
-            // Returning NULL is fine because the simulator will need it when
-            // being used instead of a real hypervisor.
-            // The hypervisorsMap contains only real hypervisors.
-            final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(hType);
-
-            if (hypervisorConfigKey != null) {
-                templateName = hypervisorConfigKey.valueIn(datacenterId);
-            }
-        }
-
-        return templateName;
-    }
-
-    @Override
-    public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
-            throws InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {
-
-        final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
-        final Account owner = routerDeploymentDefinition.getOwner();
-
-        // Router is the network element, we don't know the hypervisor type yet.
-        // Try to allocate the domR twice using diff hypervisors, and when
-        // failed both times, throw the exception up
-        final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);
-
-        int allocateRetry = 0;
-        int startRetry = 0;
-        DomainRouterVO router = null;
-        for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
-            final HypervisorType hType = iter.next();
-            try {
-                final long id = _routerDao.getNextInSequence(Long.class, "id");
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(String.format("Allocating the VR with id=%s in datacenter %s with the hypervisor type %s", id, routerDeploymentDefinition.getDest()
-                            .getDataCenter(), hType));
-                }
-
-                final String templateName = retrieveTemplateName(hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
-                final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);
-
-                if (template == null) {
-                    s_logger.debug(hType + " won't support system vm, skip it");
-                    continue;
-                }
-
-                final boolean offerHA = routerOffering.getOfferHA();
-
-                // routerDeploymentDefinition.getVpc().getId() ==> do not use
-                // VPC because it is not a VPC offering.
-                final Long vpcId = routerDeploymentDefinition.getVpc() != null ? routerDeploymentDefinition.getVpc().getId() : null;
-
-                long userId = CallContext.current().getCallingUserId();
-                if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
-                    final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
-                    if (!userVOs.isEmpty()) {
-                        userId =  userVOs.get(0).getId();
-                    }
-                }
-
-                router = new DomainRouterVO(id, routerOffering.getId(), routerDeploymentDefinition.getVirtualProvider().getId(), VirtualMachineName.getRouterName(id,
-                        s_vmInstanceName), template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(),
-                        userId, routerDeploymentDefinition.isRedundant(), RedundantState.UNKNOWN, offerHA, false, vpcId);
-
-                router.setDynamicallyScalable(template.isDynamicallyScalable());
-                router.setRole(Role.VIRTUAL_ROUTER);
-                router = _routerDao.persist(router);
-
-                reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
-                router = _routerDao.findById(router.getId());
-            } catch (final InsufficientCapacityException ex) {
-                if (allocateRetry < 2 && iter.hasNext()) {
-                    s_logger.debug("Failed to allocate the VR with hypervisor type " + hType + ", retrying one more time");
-                    continue;
-                } else {
-                    throw ex;
-                }
-            } finally {
-                allocateRetry++;
-            }
-
-            if (startRouter) {
-                try {
-                    router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams());
-                    break;
-                } catch (final InsufficientCapacityException ex) {
-                    if (startRetry < 2 && iter.hasNext()) {
-                        s_logger.debug("Failed to start the VR  " + router + " with hypervisor type " + hType + ", " + "destroying it and recreating one more time");
-                        // destroy the router
-                        destroyRouter(router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
-                        continue;
-                    } else {
-                        throw ex;
-                    }
-                } finally {
-                    startRetry++;
-                }
-            } else {
-                // return stopped router
-                return router;
-            }
-        }
-
-        return router;
-    }
-
-    protected void filterSupportedHypervisors(final List<HypervisorType> hypervisors) {
-        // For non vpc we keep them all assuming all types in the list are
-        // supported
-    }
-
-    protected String getNoHypervisorsErrMsgDetails() {
-        return "";
-    }
-
-    protected List<HypervisorType> getHypervisors(final RouterDeploymentDefinition routerDeploymentDefinition) throws InsufficientServerCapacityException {
-        final DeployDestination dest = routerDeploymentDefinition.getDest();
-        List<HypervisorType> hypervisors = new ArrayList<HypervisorType>();
-        if (dest.getCluster() != null) {
-            if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) {
-                hypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId()));
-            } else {
-                hypervisors.add(dest.getCluster().getHypervisorType());
-            }
-        } else {
-            final HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId());
-            if (defaults != HypervisorType.None) {
-                hypervisors.add(defaults);
-            } else {
-                // if there is no default hypervisor, get it from the cluster
-                hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, routerDeploymentDefinition.getPlan().getPodId());
-            }
-        }
-
-        filterSupportedHypervisors(hypervisors);
-
-        if (hypervisors.isEmpty()) {
-            if (routerDeploymentDefinition.getPodId() != null) {
-                throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the pod." + getNoHypervisorsErrMsgDetails(), Pod.class,
-                        routerDeploymentDefinition.getPodId());
-            }
-            throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone." + getNoHypervisorsErrMsgDetails(),
-                    DataCenter.class, dest.getDataCenter().getId());
-        }
-        return hypervisors;
-    }
-
-    /*
-     * Ovm won't support any system. So we have to choose a partner cluster in
-     * the same pod to start domain router for us
-     */
-    protected HypervisorType getClusterToStartDomainRouterForOvm(final long podId) {
-        final List<ClusterVO> clusters = _clusterDao.listByPodId(podId);
-        for (final ClusterVO cv : clusters) {
-            if (cv.getHypervisorType() == HypervisorType.Ovm || cv.getHypervisorType() == HypervisorType.BareMetal) {
-                continue;
-            }
-
-            final List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cv.getId());
-            if (hosts == null || hosts.isEmpty()) {
-                continue;
-            }
-
-            for (final HostVO h : hosts) {
-                if (h.getState() == Status.Up) {
-                    s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router for OVM");
-                    return h.getHypervisorType();
-                }
-            }
-        }
-
-        final String errMsg = new StringBuilder("Cannot find an available cluster in Pod ").append(podId)
-                .append(" to start domain router for Ovm. \n Ovm won't support any system vm including domain router, ")
-                .append("please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod")
-                .append(" with Ovm cluster. And there is at least one host in UP status in that cluster.").toString();
-        throw new CloudRuntimeException(errMsg);
-    }
-
-    protected LinkedHashMap<Network, List<? extends NicProfile>> configureControlNic(final RouterDeploymentDefinition routerDeploymentDefinition) {
-        final LinkedHashMap<Network, List<? extends NicProfile>> controlConfig = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
-
-        s_logger.debug("Adding nic for Virtual Router in Control network ");
-        final List<? extends NetworkOffering> offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
-        final NetworkOffering controlOffering = offerings.get(0);
-        final Network controlNic = _networkMgr.setupNetwork(s_systemAccount, controlOffering, routerDeploymentDefinition.getPlan(), null, null, false).get(0);
-
-        controlConfig.put(controlNic, new ArrayList<NicProfile>());
-
-        return controlConfig;
-    }
-
-    protected LinkedHashMap<Network, List<? extends NicProfile>> configurePublicNic(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean hasGuestNic) {
-        final LinkedHashMap<Network, List<? extends NicProfile>> publicConfig = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
-
-        if (routerDeploymentDefinition.isPublicNetwork()) {
-            s_logger.debug("Adding nic for Virtual Router in Public network ");
-            // if source nat service is supported by the network, get the source
-            // nat ip address
-            final NicProfile defaultNic = new NicProfile();
-            defaultNic.setDefaultNic(true);
-            final PublicIp sourceNatIp = routerDeploymentDefinition.getSourceNatIP();
-            defaultNic.setIPv4Address(sourceNatIp.getAddress().addr());
-            defaultNic.setIPv4Gateway(sourceNatIp.getGateway());
-            defaultNic.setIPv4Netmask(sourceNatIp.getNetmask());
-            defaultNic.setMacAddress(sourceNatIp.getMacAddress());
-            // get broadcast from public network
-            final Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId());
-            if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) {
-                defaultNic.setBroadcastType(BroadcastDomainType.Vxlan);
-                defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
-                defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
-            } else {
-                defaultNic.setBroadcastType(BroadcastDomainType.Vlan);
-                defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag()));
-                defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag()));
-            }
-
-            //If guest nic has already been added we will have 2 devices in the list.
-            if (hasGuestNic) {
-                defaultNic.setDeviceId(2);
-            }
-
-            final NetworkOffering publicOffering = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0);
-            final List<? extends Network> publicNetworks = _networkMgr.setupNetwork(s_systemAccount, publicOffering, routerDeploymentDefinition.getPlan(), null, null, false);
-            final String publicIp = defaultNic.getIPv4Address();
-            // We want to use the identical MAC address for RvR on public
-            // interface if possible
-            final NicVO peerNic = _nicDao.findByIp4AddressAndNetworkId(publicIp, publicNetworks.get(0).getId());
-            if (peerNic != null) {
-                s_logger.info("Use same MAC as previous RvR, the MAC is " + peerNic.getMacAddress());
-                defaultNic.setMacAddress(peerNic.getMacAddress());
-            }
-            publicConfig.put(publicNetworks.get(0), new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
-        }
-
-        return publicConfig;
-    }
-
-    @Override
-    public LinkedHashMap<Network, List<? extends NicProfile>> configureDefaultNics(final RouterDeploymentDefinition routerDeploymentDefinition) throws ConcurrentOperationException, InsufficientAddressCapacityException {
-
-        final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
-
-        // 1) Guest Network
-        final LinkedHashMap<Network, List<? extends NicProfile>> guestNic = configureGuestNic(routerDeploymentDefinition);
-        networks.putAll(guestNic);
-
-        // 2) Control network
-        final LinkedHashMap<Network, List<? extends NicProfile>> controlNic = configureControlNic(routerDeploymentDefinition);
-        networks.putAll(controlNic);
-
-        // 3) Public network
-        final LinkedHashMap<Network, List<? extends NicProfile>> publicNic = configurePublicNic(routerDeploymentDefinition, networks.size() > 1);
-        networks.putAll(publicNic);
-
-        return networks;
-    }
-
-    @Override
-    public LinkedHashMap<Network, List<? extends NicProfile>> configureGuestNic(final RouterDeploymentDefinition routerDeploymentDefinition)
-            throws ConcurrentOperationException, InsufficientAddressCapacityException {
-
-        // Form networks
-        final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
-        // 1) Guest network
-        final Network guestNetwork = routerDeploymentDefinition.getGuestNetwork();
-
-        if (guestNetwork != null) {
-            s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork);
-            String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null;
-            if (!routerDeploymentDefinition.isPublicNetwork()) {
-                final Nic placeholder = _networkModel.getPlaceholderNicForRouter(guestNetwork, routerDeploymentDefinition.getPodId());
-                if (guestNetwork.getCidr() != null) {
-                    if (placeholder != null && placeholder.getIPv4Address() != null) {
-                        s_logger.debug("Requesting ipv4 address " + placeholder.getIPv4Address() + " stored in placeholder nic for the network "
-                                + guestNetwork);
-                        defaultNetworkStartIp = placeholder.getIPv4Address();
-                    } else {
-                        final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
-                        if (startIp != null
-                                && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
-                            defaultNetworkStartIp = startIp;
-                        } else if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId()
-                                    + " is already allocated, can't use it for domain router; will get random ip address from the range");
-                        }
-                    }
-                }
-
-                if (guestNetwork.getIp6Cidr() != null) {
-                    if (placeholder != null && placeholder.getIPv6Address() != null) {
-                        s_logger.debug("Requesting ipv6 address " + placeholder.getIPv6Address() + " stored in placeholder nic for the network "
-                                + guestNetwork);
-                        defaultNetworkStartIpv6 = placeholder.getIPv6Address();
-                    } else {
-                        final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
-                        if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
-                            defaultNetworkStartIpv6 = startIpv6;
-                        } else if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId()
-                                    + " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
-                        }
-                    }
-                }
-            }
-
-            final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
-            if (routerDeploymentDefinition.isPublicNetwork()) {
-                if (routerDeploymentDefinition.isRedundant()) {
-                    gatewayNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
-                } else {
-                    gatewayNic.setIPv4Address(guestNetwork.getGateway());
-                }
-                gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri());
-                gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
-                gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri());
-                gatewayNic.setMode(guestNetwork.getMode());
-                final String gatewayCidr = _networkModel.getValidNetworkCidr(guestNetwork);
-                gatewayNic.setIPv4Netmask(NetUtils.getCidrNetmask(gatewayCidr));
-            } else {
-                gatewayNic.setDefaultNic(true);
-            }
-
-            networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(gatewayNic)));
-        }
-        return networks;
-    }
-
-    @Override
-    public void reallocateRouterNetworks(final RouterDeploymentDefinition routerDeploymentDefinition, final VirtualRouter router, final VMTemplateVO template, final HypervisorType hType)
-            throws ConcurrentOperationException, InsufficientCapacityException {
-        final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
-
-        final LinkedHashMap<Network, List<? extends NicProfile>> networks = configureDefaultNics(routerDeploymentDefinition);
-
-        _itMgr.allocate(router.getInstanceName(), template, routerOffering, networks, routerDeploymentDefinition.getPlan(), hType);
-    }
-
-    public static void setSystemAccount(final Account systemAccount) {
-        s_systemAccount = systemAccount;
-    }
-
-    public static void setVMInstanceName(final String vmInstanceName) {
-        s_vmInstanceName = vmInstanceName;
-    }
-    @Override
-    public boolean validateHAProxyLBRule(final LoadBalancingRule rule) {
-        final String timeEndChar = "dhms";
-        int haproxy_stats_port = Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()));
-        if (rule.getSourcePortStart() == haproxy_stats_port) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Can't create LB on port "+ haproxy_stats_port +", haproxy is listening for  LB stats on this port");
-            }
-            return false;
-        }
-
-        for (final LoadBalancingRule.LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) {
-            final List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
-
-            if (LbStickinessMethod.StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-
-            } else if (LbStickinessMethod.StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                String tablesize = "200k"; // optional
-                String expire = "30m"; // optional
-
-                /* overwrite default values with the stick parameters */
-                for (final Pair<String, String> paramKV : paramsList) {
-                    final String key = paramKV.first();
-                    final String value = paramKV.second();
-                    if ("tablesize".equalsIgnoreCase(key)) {
-                        tablesize = value;
-                    }
-                    if ("expire".equalsIgnoreCase(key)) {
-                        expire = value;
-                    }
-                }
-                if (expire != null && !containsOnlyNumbers(expire, timeEndChar)) {
-                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: expire is not in timeformat: " + expire);
-                }
-                if (tablesize != null && !containsOnlyNumbers(tablesize, "kmg")) {
-                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: tablesize is not in size format: " + tablesize);
-
-                }
-            } else if (LbStickinessMethod.StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                String length = null; // optional
-                String holdTime = null; // optional
-
-                for (final Pair<String, String> paramKV : paramsList) {
-                    final String key = paramKV.first();
-                    final String value = paramKV.second();
-                    if ("length".equalsIgnoreCase(key)) {
-                        length = value;
-                    }
-                    if ("holdtime".equalsIgnoreCase(key)) {
-                        holdTime = value;
-                    }
-                }
-
-                if (length != null && !containsOnlyNumbers(length, null)) {
-                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: length is not a number: " + length);
-                }
-                if (holdTime != null && !containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null)) {
-                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: holdtime is not in timeformat: " + holdTime);
-                }
-            }
-        }
-        return true;
-    }
-
-    /*
-     * This function detects numbers like 12 ,32h ,42m .. etc,. 1) plain number
-     * like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here last
-     * character is non-digit but from known characters .
-     */
-    private static boolean containsOnlyNumbers(final String str, final String endChar) {
-        if (str == null) {
-            return false;
-        }
-
-        String number = str;
-        if (endChar != null) {
-            boolean matchedEndChar = false;
-            if (str.length() < 2) {
-                return false; // at least one numeric and one char. example:
-            }
-            // 3h
-            final char strEnd = str.toCharArray()[str.length() - 1];
-            for (final char c : endChar.toCharArray()) {
-                if (strEnd == c) {
-                    number = str.substring(0, str.length() - 1);
-                    matchedEndChar = true;
-                    break;
-                }
-            }
-            if (!matchedEndChar) {
-                return false;
-            }
-        }
-        try {
-            Integer.parseInt(number);
-        } catch (final NumberFormatException e) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
deleted file mode 100644
index 1985dea..0000000
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ /dev/null
@@ -1,2677 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.router;
-
-import java.math.BigInteger;
-import java.nio.charset.Charset;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-
-import org.apache.cloudstack.alert.AlertService;
-import org.apache.cloudstack.alert.AlertService.AlertType;
-import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.network.topology.NetworkTopology;
-import org.apache.cloudstack.network.topology.NetworkTopologyContext;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.cloudstack.utils.usage.UsageUtils;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.Listener;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.AgentControlCommand;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckRouterAnswer;
-import com.cloud.agent.api.CheckRouterCommand;
-import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
-import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetDomRVersionAnswer;
-import com.cloud.agent.api.GetDomRVersionCmd;
-import com.cloud.agent.api.GetRouterAlertsAnswer;
-import com.cloud.agent.api.NetworkUsageAnswer;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand.Action;
-import com.cloud.agent.api.routing.GetRouterAlertsCommand;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.SetMonitorServiceCommand;
-import com.cloud.agent.api.to.MonitorServiceTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiAsyncJobDispatcher;
-import com.cloud.api.ApiGsonHelper;
-import com.cloud.cluster.ManagementServerHostVO;
-import com.cloud.cluster.dao.ManagementServerHostDao;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.MonitoringService;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkService;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteCustomerGateway;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.SshKeysDistriMonitor;
-import com.cloud.network.VirtualNetworkApplianceService;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.MonitoringServiceDao;
-import com.cloud.network.dao.MonitoringServiceVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.OpRouterMonitorServiceDao;
-import com.cloud.network.dao.OpRouterMonitorServiceVO;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
-import com.cloud.network.dao.Site2SiteVpnConnectionDao;
-import com.cloud.network.dao.Site2SiteVpnConnectionVO;
-import com.cloud.network.dao.Site2SiteVpnGatewayDao;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.lb.LoadBalancingRule.LbDestination;
-import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
-import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
-import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.VirtualRouter.RedundantState;
-import com.cloud.network.router.VirtualRouter.Role;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StaticNatImpl;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.User;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.user.UserStatsLogVO;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.UserDao;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.user.dao.UserStatsLogDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.MacAddress;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicIpAlias;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineGuru;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.VirtualMachineProfile.Param;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.NicIpAliasVO;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-/**
- * VirtualNetworkApplianceManagerImpl manages the different types of virtual
- * network appliances available in the Cloud Stack.
- */
-public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, VirtualMachineGuru, Listener,
-Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
-    private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class);
-
-    @Inject private EntityManager _entityMgr;
-    @Inject private DataCenterDao _dcDao;
-    @Inject protected VlanDao _vlanDao;
-    @Inject private FirewallRulesDao _rulesDao;
-    @Inject private LoadBalancerDao _loadBalancerDao;
-    @Inject private LoadBalancerVMMapDao _loadBalancerVMMapDao;
-    @Inject protected IPAddressDao _ipAddressDao;
-    @Inject private VMTemplateDao _templateDao;
-    @Inject protected DomainRouterDao _routerDao;
-    @Inject private UserDao _userDao;
-    @Inject protected UserStatisticsDao _userStatsDao;
-    @Inject private HostDao _hostDao;
-    @Inject private ConfigurationDao _configDao;
-    @Inject private HostPodDao _podDao;
-    @Inject private UserStatsLogDao _userStatsLogDao;
-    @Inject protected AgentManager _agentMgr;
-    @Inject private AlertManager _alertMgr;
-    @Inject private AccountManager _accountMgr;
-    @Inject private ConfigurationManager _configMgr;
-    @Inject private ConfigurationServer _configServer;
-    @Inject private ServiceOfferingDao _serviceOfferingDao;
-    @Inject private UserVmDao _userVmDao;
-    @Inject private VMInstanceDao _vmDao;
-    @Inject private NetworkOfferingDao _networkOfferingDao;
-    @Inject private GuestOSDao _guestOSDao;
-    @Inject private NetworkOrchestrationService _networkMgr;
-    @Inject protected NetworkModel _networkModel;
-    @Inject protected VirtualMachineManager _itMgr;
-    @Inject private VpnUserDao _vpnUsersDao;
-    @Inject private RulesManager _rulesMgr;
-    @Inject protected NetworkDao _networkDao;
-    @Inject private LoadBalancingRulesManager _lbMgr;
-    @Inject private PortForwardingRulesDao _pfRulesDao;
-    @Inject protected RemoteAccessVpnDao _vpnDao;
-    @Inject protected NicDao _nicDao;
-    @Inject private NicIpAliasDao _nicIpAliasDao;
-    @Inject private VolumeDao _volumeDao;
-    @Inject private UserVmDetailsDao _vmDetailsDao;
-    @Inject private ClusterDao _clusterDao;
-    @Inject private ResourceManager _resourceMgr;
-    @Inject private PhysicalNetworkServiceProviderDao _physicalProviderDao;
-    @Inject protected VirtualRouterProviderDao _vrProviderDao;
-    @Inject private ManagementServerHostDao _msHostDao;
-    @Inject private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
-    @Inject private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
-    @Inject private Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
-    @Inject private Site2SiteVpnManager _s2sVpnMgr;
-    @Inject private UserIpv6AddressDao _ipv6Dao;
-    @Inject private NetworkService _networkSvc;
-    @Inject private IpAddressManager _ipAddrMgr;
-    @Inject private ConfigDepot _configDepot;
-    @Inject private MonitoringServiceDao _monitorServiceDao;
-    @Inject private AsyncJobManager _asyncMgr;
-    @Inject protected VpcDao _vpcDao;
-    @Inject protected ApiAsyncJobDispatcher _asyncDispatcher;
-    @Inject private OpRouterMonitorServiceDao _opRouterMonitorServiceDao;
-
-    @Inject protected NetworkTopologyContext _networkTopologyContext;
-
-    @Autowired
-    @Qualifier("networkHelper")
-    protected NetworkHelper _nwHelper;
-
-    @Inject protected RouterControlHelper _routerControlHelper;
-
-    @Inject protected CommandSetupHelper _commandSetupHelper;
-    @Inject protected RouterDeploymentDefinitionBuilder _routerDeploymentManagerBuilder;
-
-    private int _routerRamSize;
-    private int _routerCpuMHz;
-    private String _mgmtCidr;
-
-    private int _routerStatsInterval = 300;
-    private int _routerCheckInterval = 30;
-    private int _rvrStatusUpdatePoolSize = 10;
-    private String _dnsBasicZoneUpdates = "all";
-    private final Set<String> _guestOSNeedGatewayOnNonDefaultNetwork = new HashSet<>();
-
-    private boolean _disableRpFilter = false;
-    private int _routerExtraPublicNics = 2;
-    private int _usageAggregationRange = 1440;
-    private String _usageTimeZone = "GMT";
-    private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
-    private boolean _dailyOrHourly = false;
-
-    private ScheduledExecutorService _executor;
-    private ScheduledExecutorService _checkExecutor;
-    private ScheduledExecutorService _networkStatsUpdateExecutor;
-    private ExecutorService _rvrStatusUpdateExecutor;
-
-    private BlockingQueue<Long> _vrUpdateQueue;
-
-    @Override
-    public VirtualRouter destroyRouter(final long routerId, final Account caller, final Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
-        return _nwHelper.destroyRouter(routerId, caller, callerUserId);
-    }
-
-    @Override
-    @DB
-    public VirtualRouter upgradeRouter(final UpgradeRouterCmd cmd) {
-        final Long routerId = cmd.getId();
-        final Long serviceOfferingId = cmd.getServiceOfferingId();
-        final Account caller = CallContext.current().getCallingAccount();
-
-        final DomainRouterVO router = _routerDao.findById(routerId);
-        if (router == null) {
-            throw new InvalidParameterValueException("Unable to find router with id " + routerId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, router);
-
-        if (router.getServiceOfferingId() == serviceOfferingId) {
-            s_logger.debug("Router: " + routerId + "already has service offering: " + serviceOfferingId);
-            return _routerDao.findById(routerId);
-        }
-
-        final ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (newServiceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId);
-        }
-
-        // check if it is a system service offering, if yes return with error as
-        // it cannot be used for user vms
-        if (!newServiceOffering.getSystemUse()) {
-            throw new InvalidParameterValueException("Cannot upgrade router vm to a non system service offering " + serviceOfferingId);
-        }
-
-        // Check that the router is stopped
-        if (!router.getState().equals(VirtualMachine.State.Stopped)) {
-            s_logger.warn("Unable to upgrade router " + router.toString() + " in state " + router.getState());
-            throw new InvalidParameterValueException("Unable to upgrade router " + router.toString() + " in state " + router.getState()
-                    + "; make sure the router is stopped and not in an error state before upgrading.");
-        }
-
-        final ServiceOfferingVO currentServiceOffering = _serviceOfferingDao.findById(router.getServiceOfferingId());
-
-        // Check that the service offering being upgraded to has the same
-        // storage pool preference as the VM's current service
-        // offering
-        if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) {
-            throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.getUseLocalStorage() + " is different from "
-                    + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage());
-        }
-
-        router.setServiceOfferingId(serviceOfferingId);
-        if (_routerDao.update(routerId, router)) {
-            return _routerDao.findById(routerId);
-        } else {
-            throw new CloudRuntimeException("Unable to upgrade router " + routerId);
-        }
-
-    }
-
-    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true)
-    @Override
-    public VirtualRouter stopRouter(final long routerId, final boolean forced) throws ResourceUnavailableException, ConcurrentOperationException {
-        final CallContext context = CallContext.current();
-        final Account account = context.getCallingAccount();
-
-        // verify parameters
-        final DomainRouterVO router = _routerDao.findById(routerId);
-        if (router == null) {
-            throw new InvalidParameterValueException("Unable to find router by id " + routerId + ".");
-        }
-
-        _accountMgr.checkAccess(account, null, true, router);
-
-        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
-
-        final VirtualRouter virtualRouter = stop(router, forced, user, account);
-        if (virtualRouter == null) {
-            throw new CloudRuntimeException("Failed to stop router with id " + routerId);
-        }
-
-        // Clear stop pending flag after stopped successfully
-        if (router.isStopPending()) {
-            s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after stop router successfully");
-            router.setStopPending(false);
-            _routerDao.persist(router);
-            virtualRouter.setStopPending(false);
-        }
-        return virtualRouter;
-    }
-
-    @DB
-    public void processStopOrRebootAnswer(final DomainRouterVO router, final Answer answer) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                // FIXME!!! - UserStats command should grab bytesSent/Received
-                // for all guest interfaces of the VR
-                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
-                for (final Long guestNtwkId : routerGuestNtwkIds) {
-                    final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), guestNtwkId, null, router.getId(), router.getType()
-                            .toString());
-                    if (userStats != null) {
-                        final long currentBytesRcvd = userStats.getCurrentBytesReceived();
-                        userStats.setCurrentBytesReceived(0);
-                        userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd);
-
-                        final long currentBytesSent = userStats.getCurrentBytesSent();
-                        userStats.setCurrentBytesSent(0);
-                        userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent);
-                        _userStatsDao.update(userStats.getId(), userStats);
-                        s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop");
-                    } else {
-                        s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterId());
-                    }
-                }
-            }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true)
-    public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-        final Account caller = CallContext.current().getCallingAccount();
-
-        // verify parameters
-        final DomainRouterVO router = _routerDao.findById(routerId);
-        if (router == null) {
-            throw new InvalidParameterValueException("Unable to find domain router with id " + routerId + ".");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, router);
-
-        // Can reboot domain router only in Running state
-        if (router == null || router.getState() != VirtualMachine.State.Running) {
-            s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState());
-            throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterId());
-        }
-
-        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
-        s_logger.debug("Stopping and starting router " + router + " as a part of router reboot");
-
-        if (stop(router, false, user, caller) != null) {
-            return startRouter(routerId, reprogramNetwork);
-        } else {
-            throw new CloudRuntimeException("Failed to reboot router " + router);
-        }
-    }
-
-    static final ConfigKey<Boolean> UseExternalDnsServers = new ConfigKey<Boolean>(Boolean.class, "use.external.dns", "Advanced", "false",
-            "Bypass internal dns, use external dns1 and dns2", true, ConfigKey.Scope.Zone, null);
-
-    static final ConfigKey<Boolean> routerVersionCheckEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "router.version.check", "true",
-            "If true, router minimum required version is checked before sending command", false);
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterMonitor"));
-        _checkExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterStatusMonitor"));
-        _networkStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NetworkStatsUpdater"));
-
-        VirtualMachine.State.getStateMachine().registerListener(this);
-
-        final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
-
-        _routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE);
-        _routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ);
-
-        _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
-
-        final String guestOSString = configs.get("network.dhcp.nondefaultnetwork.setgateway.guestos");
-        if (guestOSString != null) {
-            final String[] guestOSList = guestOSString.split(",");
-            for (final String os : guestOSList) {
-                _guestOSNeedGatewayOnNonDefaultNetwork.add(os);
-            }
-        }
-
-        String value = configs.get("router.stats.interval");
-        _routerStatsInterval = NumbersUtil.parseInt(value, 300);
-
-        value = configs.get("router.check.interval");
-        _routerCheckInterval = NumbersUtil.parseInt(value, 30);
-
-        value = configs.get("router.check.poolsize");
-        _rvrStatusUpdatePoolSize = NumbersUtil.parseInt(value, 10);
-
-        /*
-         * We assume that one thread can handle 20 requests in 1 minute in
-         * normal situation, so here we give the queue size up to 50 minutes.
-         * It's mostly for buffer, since each time CheckRouterTask running, it
-         * would add all the redundant networks in the queue immediately
-         */
-        _vrUpdateQueue = new LinkedBlockingQueue<Long>(_rvrStatusUpdatePoolSize * 1000);
-
-        _rvrStatusUpdateExecutor = Executors.newFixedThreadPool(_rvrStatusUpdatePoolSize, new NamedThreadFactory("RedundantRouterStatusMonitor"));
-
-        String instance = configs.get("instance.name");
-        if (instance == null) {
-            instance = "DEFAULT";
-        }
-
-        NetworkHelperImpl.setVMInstanceName(instance);
-
-        final String rpValue = configs.get("network.disable.rpfilter");
-        if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
-            _disableRpFilter = true;
-        }
-
-        _dnsBasicZoneUpdates = String.valueOf(_configDao.getValue(Config.DnsBasicZoneUpdates.key()));
-
-        s_logger.info("Router configurations: " + "ramsize=" + _routerRamSize);
-
-        _agentMgr.registerForHostEvents(new SshKeysDistriMonitor(_agentMgr, _hostDao, _configDao), true, false, false);
-
-        final List<ServiceOfferingVO> offerings = _serviceOfferingDao.createSystemServiceOfferings("System Offering For Software Router",
-                ServiceOffering.routerDefaultOffUniqueName, 1, _routerRamSize, _routerCpuMHz, null,
-                null, true, null, ProvisioningType.THIN, true, null, true, VirtualMachine.Type.DomainRouter, true);
-        // this can sometimes happen, if DB is manually or programmatically manipulated
-        if (offerings == null || offerings.size() < 2) {
-            final String msg = "Data integrity problem : System Offering For Software router VM has been removed?";
-            s_logger.error(msg);
-            throw new ConfigurationException(msg);
-        }
-
-        NetworkHelperImpl.setSystemAccount(_accountMgr.getSystemAccount());
-
-        final String aggregationRange = configs.get("usage.stats.job.aggregation.range");
-        _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
-        _usageTimeZone = configs.get("usage.aggregation.timezone");
-        if (_usageTimeZone == null) {
-            _usageTimeZone = "GMT";
-        }
-
-        _agentMgr.registerForHostEvents(this, true, false, false);
-
-        s_logger.info("DomainRouterManager is configured.");
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        if (_routerStatsInterval > 0) {
-            _executor.scheduleAtFixedRate(new NetworkUsageTask(), _routerStatsInterval, _routerStatsInterval, TimeUnit.SECONDS);
-        } else {
-            s_logger.debug("router.stats.interval - " + _routerStatsInterval + " so not scheduling the router stats thread");
-        }
-
-        //Schedule Network stats update task
-        //Network stats aggregation should align with aggregation range
-        //For daily aggregation, update stats at the end of the day
-        //For hourly aggregation, update stats at the end of the hour
-        final TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone);
-        final Calendar cal = Calendar.getInstance(usageTimezone);
-        cal.setTime(new Date());
-        //aggDate is the time in millis when the aggregation should happen
-        long aggDate = 0;
-        final int HOURLY_TIME = 60;
-        final int DAILY_TIME = 60 * 24;
-        if (_usageAggregationRange == DAILY_TIME) {
-            cal.set(Calendar.HOUR_OF_DAY, 0);
-            cal.set(Calendar.MINUTE, 0);
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MILLISECOND, 0);
-            cal.roll(Calendar.DAY_OF_YEAR, true);
-            cal.add(Calendar.MILLISECOND, -1);
-            aggDate = cal.getTime().getTime();
-            _dailyOrHourly = true;
-        } else if (_usageAggregationRange == HOURLY_TIME) {
-            cal.set(Calendar.MINUTE, 0);
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MILLISECOND, 0);
-            cal.roll(Calendar.HOUR_OF_DAY, true);
-            cal.add(Calendar.MILLISECOND, -1);
-            aggDate = cal.getTime().getTime();
-            _dailyOrHourly = true;
-        } else {
-            aggDate = cal.getTime().getTime();
-            _dailyOrHourly = false;
-        }
-
-        if (_usageAggregationRange < UsageUtils.USAGE_AGGREGATION_RANGE_MIN) {
-            s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + UsageUtils.USAGE_AGGREGATION_RANGE_MIN);
-            _usageAggregationRange = UsageUtils.USAGE_AGGREGATION_RANGE_MIN;
-        }
-
-        // We cannot schedule a job at specific time. Provide initial delay instead, from current time, so that the job runs at desired time
-        final long initialDelay = aggDate - System.currentTimeMillis();
-
-        if( initialDelay < 0){
-            s_logger.warn("Initial delay for network usage stats update task is incorrect. Stats update task will run immediately");
-        }
-
-        _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), initialDelay, _usageAggregationRange * 60 * 1000,
-                TimeUnit.MILLISECONDS);
-
-        if (_routerCheckInterval > 0) {
-            _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS);
-            for (int i = 0; i < _rvrStatusUpdatePoolSize; i++) {
-                _rvrStatusUpdateExecutor.execute(new RvRStatusUpdateTask());
-            }
-        } else {
-            s_logger.debug("router.check.interval - " + _routerCheckInterval + " so not scheduling the redundant router checking thread");
-        }
-
-        final int routerAlertsCheckInterval = RouterAlertsCheckInterval.value();
-        if (routerAlertsCheckInterval > 0) {
-            _checkExecutor.scheduleAtFixedRate(new CheckRouterAlertsTask(), routerAlertsCheckInterval, routerAlertsCheckInterval, TimeUnit.SECONDS);
-        } else {
-            s_logger.debug("router.alerts.check.interval - " + routerAlertsCheckInterval + " so not scheduling the router alerts checking thread");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    protected VirtualNetworkApplianceManagerImpl() {
-    }
-
-    protected class NetworkUsageTask extends ManagedContextRunnable {
-
-        public NetworkUsageTask() {
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                final List<DomainRouterVO> routers = _routerDao.listByStateAndNetworkType(VirtualMachine.State.Running, GuestType.Isolated, mgmtSrvrId);
-                s_logger.debug("Found " + routers.size() + " running routers. ");
-
-                for (final DomainRouterVO router : routers) {
-                    final String privateIP = router.getPrivateIpAddress();
-
-                    if (privateIP != null) {
-                        final boolean forVpc = router.getVpcId() != null;
-                        final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
-                        for (final Nic routerNic : routerNics) {
-                            final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
-                            // Send network usage command for public nic in VPC VR
-                            // Send network usage command for isolated guest nic of non) VPC VR
-
-                            //[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues
-                            if (network == null) {
-                                s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!");
-                                continue;
-                            }
-                            if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
-                                    && network.getGuestType() == Network.GuestType.Isolated) {
-                                final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());
-                                final String routerType = router.getType().toString();
-                                final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(),
-                                        forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
-                                NetworkUsageAnswer answer = null;
-                                try {
-                                    answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
-                                } catch (final Exception e) {
-                                    s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e);
-                                    continue;
-                                }
-
-                                if (answer != null) {
-                                    if (!answer.getResult()) {
-                                        s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId()
-                                                + "; details: " + answer.getDetails());
-                                        continue;
-                                    }
-                                    try {
-                                        if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) {
-                                            s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
-                                            continue;
-                                        }
-                                        final NetworkUsageAnswer answerFinal = answer;
-                                        Transaction.execute(new TransactionCallbackNoReturn() {
-                                            @Override
-                                            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                                                final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(),
-                                                        forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
-                                                if (stats == null) {
-                                                    s_logger.warn("unable to find stats for account: " + router.getAccountId());
-                                                    return;
-                                                }
-
-                                                if (previousStats != null
-                                                        && (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats
-                                                        .getCurrentBytesSent())) {
-                                                    s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: "
-                                                            + answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent());
-                                                    return;
-                                                }
-
-                                                if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) {
-                                                    if (s_logger.isDebugEnabled()) {
-                                                        s_logger.debug("Received # of bytes that's less than the last one.  "
-                                                                + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
-                                                                + answerFinal.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived());
-                                                    }
-                                                    stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
-                                                }
-                                                stats.setCurrentBytesReceived(answerFinal.getBytesReceived());
-                                                if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) {
-                                                    if (s_logger.isDebugEnabled()) {
-                                                        s_logger.debug("Received # of bytes that's less than the last one.  "
-                                                                + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
-                                                                + answerFinal.getBytesSent() + " Stored: " + stats.getCurrentBytesSent());
-                                                    }
-                                                    stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
-                                                }
-                                                stats.setCurrentBytesSent(answerFinal.getBytesSent());
-                                                if (!_dailyOrHourly) {
-                                                    // update agg bytes
-                                                    stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
-                                                    stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
-                                                }
-                                                _userStatsDao.update(stats.getId(), stats);
-                                            }
-                                        });
-
-                                    } catch (final Exception e) {
-                                        s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: "
-                                                + answer.getBytesSent());
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            } catch (final Exception e) {
-                s_logger.warn("Error while collecting network stats", e);
-            }
-        }
-    }
-
-    protected class NetworkStatsUpdateTask extends ManagedContextRunnable {
-
-        public NetworkStatsUpdateTask() {
-        }
-
-        @Override
-        protected void runInContext() {
-            final GlobalLock scanLock = GlobalLock.getInternLock("network.stats");
-            try {
-                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    // Check for ownership
-                    // msHost in UP state with min id should run the job
-                    final ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", false, 0L, 1L));
-                    if (msHost == null || msHost.getMsid() != mgmtSrvrId) {
-                        s_logger.debug("Skipping aggregate network stats update");
-                        scanLock.unlock();
-                        return;
-                    }
-                    try {
-                        Transaction.execute(new TransactionCallbackNoReturn() {
-                            @Override
-                            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                                // get all stats with delta > 0
-                                final List<UserStatisticsVO> updatedStats = _userStatsDao.listUpdatedStats();
-                                final Date updatedTime = new Date();
-                                for (final UserStatisticsVO stat : updatedStats) {
-                                    // update agg bytes
-                                    stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived());
-                                    stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent());
-                                    _userStatsDao.update(stat.getId(), stat);
-                                    // insert into op_user_stats_log
-                                    final UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat
-                                            .getCurrentBytesReceived(), stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime);
-                                    _userStatsLogDao.persist(statsLog);
-                                }
-                                s_logger.debug("Successfully updated aggregate network stats");
-                            }
-                        });
-                    } catch (final Exception e) {
-                        s_logger.debug("Failed to update aggregate network stats", e);
-                    } finally {
-                        scanLock.unlock();
-                    }
-                }
-            } catch (final Exception e) {
-                s_logger.debug("Exception while trying to acquire network stats lock", e);
-            } finally {
-                scanLock.releaseRef();
-            }
-        }
-    }
-
-    @DB
-    protected void updateSite2SiteVpnConnectionState(final List<DomainRouterVO> routers) {
-        for (final DomainRouterVO router : routers) {
-            final List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
-            if (conns == null || conns.isEmpty()) {
-                continue;
-            }
-            if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER){
-                continue;
-            }
-            if (router.getState() != VirtualMachine.State.Running) {
-                for (final Site2SiteVpnConnectionVO conn : conns) {
-                    if (conn.getState() != Site2SiteVpnConnection.State.Error) {
-                        conn.setState(Site2SiteVpnConnection.State.Disconnected);
-                        _s2sVpnConnectionDao.persist(conn);
-                    }
-                }
-                continue;
-            }
-            final List<String> ipList = new ArrayList<String>();
-            for (final Site2SiteVpnConnectionVO conn : conns) {
-                if (conn.getState() != Site2SiteVpnConnection.State.Connected && conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
-                    continue;
-                }
-                final Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
-                ipList.add(gw.getGatewayIp());
-            }
-            final String privateIP = router.getPrivateIpAddress();
-            final HostVO host = _hostDao.findById(router.getHostId());
-            if (host == null || host.getState() != Status.Up) {
-                continue;
-            } else if (host.getManagementServerId() != ManagementServerNode.getManagementServerId()) {
-                /* Only cover hosts managed by this management server */
-                continue;
-            } else if (privateIP != null) {
-                final CheckS2SVpnConnectionsCommand command = new CheckS2SVpnConnectionsCommand(ipList);
-                command.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-                command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-                command.setWait(30);
-                final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
-                CheckS2SVpnConnectionsAnswer answer = null;
-                if (origAnswer instanceof CheckS2SVpnConnectionsAnswer) {
-                    answer = (CheckS2SVpnConnectionsAnswer) origAnswer;
-                } else {
-                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
-                    continue;
-                }
-                if (!answer.getResult()) {
-                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
-                    continue;
-                }
-                for (final Site2SiteVpnConnectionVO conn : conns) {
-                    final Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId());
-                    if (lock == null) {
-                        throw new CloudRuntimeException("Unable to acquire lock for site to site vpn connection id " + conn.getId());
-                    }
-                    try {
-                        if (conn.getState() != Site2SiteVpnConnection.State.Connected && conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
-                            continue;
-                        }
-                        final Site2SiteVpnConnection.State oldState = conn.getState();
-                        final Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
-
-                        if (answer.isIPPresent(gw.getGatewayIp())) {
-                            if (answer.isConnected(gw.getGatewayIp())) {
-                                conn.setState(Site2SiteVpnConnection.State.Connected);
-                            } else {
-                                conn.setState(Site2SiteVpnConnection.State.Disconnected);
-                            }
-                            _s2sVpnConnectionDao.persist(conn);
-                            if (oldState != conn.getState()) {
-                                final String title = "Site-to-site Vpn Connection to " + gw.getName() + " just switched from " + oldState + " to " + conn.getState();
-                                final String context =
-                                        "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() + "(id: " + router.getId() + ") " +
-                                                " just switched from " + oldState + " to " + conn.getState();
-                                s_logger.info(context);
-                                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
-                            }
-                        }
-                    } finally {
-                        _s2sVpnConnectionDao.releaseFromLockTable(lock.getId());
-                    }
-                }
-            }
-        }
-    }
-
-    protected void updateRoutersRedundantState(final List<DomainRouterVO> routers) {
-        boolean updated;
-        for (final DomainRouterVO router : routers) {
-            updated = false;
-            if (!router.getIsRedundantRouter()) {
-                continue;
-            }
-            final RedundantState prevState = router.getRedundantState();
-            if (router.getState() != VirtualMachine.State.Running) {
-                router.setRedundantState(RedundantState.UNKNOWN);
-                updated = true;
-            } else {
-                final String privateIP = router.getPrivateIpAddress();
-                final HostVO host = _hostDao.findById(router.getHostId());
-                if (host == null || host.getState() != Status.Up) {
-                    router.setRedundantState(RedundantState.UNKNOWN);
-                    updated = true;
-                } else if (privateIP != null) {
-                    final CheckRouterCommand command = new CheckRouterCommand();
-                    command.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
-                    command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-                    command.setWait(30);
-                    final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
-                    CheckRouterAnswer answer = null;
-                    if (origAnswer instanceof CheckRouterAnswer) {
-                        answer = (CheckRouterAnswer) origAnswer;
-                    } else {
-                        s_logger.warn("Unable to update router " + router.getHostName() + "'s status");
-                    }
-                    RedundantState state = RedundantState.UNKNOWN;
-                    if (answer != null) {
-                        if (answer.getResult()) {
-                            state = answer.getState();
-                        } else {
-                            s_logger.info("Agent response doesn't seem to be correct ==> " + answer.getResult());
-                        }
-                    }
-                    router.setRedundantState(state);
-                    updated = true;
-                }
-            }
-            if (updated) {
-                _routerDao.update(router.getId(), router);
-            }
-            final RedundantState currState = router.getRedundantState();
-            if (prevState != currState) {
-                final String title = "Redundant virtual router " + router.getInstanceName() + " just switch from " + prevState + " to " + currState;
-                final String context = "Redundant virtual router (name: " + router.getHostName() + ", id: " + router.getId() + ") " + " just switch from " + prevState + " to "
-                        + currState;
-                s_logger.info(context);
-                if (currState == RedundantState.MASTER) {
-                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
-                }
-            }
-        }
-    }
-
-    // Ensure router status is update to date before execute this function. The
-    // function would try best to recover all routers except MASTER
-    protected void recoverRedundantNetwork(final DomainRouterVO masterRouter, final DomainRouterVO backupRouter) {
-        if (masterRouter.getState() == VirtualMachine.State.Running && backupRouter.getState() == VirtualMachine.State.Running) {
-            final HostVO masterHost = _hostDao.findById(masterRouter.getHostId());
-            final HostVO backupHost = _hostDao.findById(backupRouter.getHostId());
-            if (masterHost.getState() == Status.Up && backupHost.getState() == Status.Up) {
-                final String title = "Reboot " + backupRouter.getInstanceName() + " to ensure redundant virtual routers work";
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(title);
-                }
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, backupRouter.getDataCenterId(), backupRouter.getPodIdToDeployIn(), title, title);
-                try {
-                    rebootRouter(backupRouter.getId(), true);
-                } catch (final ConcurrentOperationException e) {
-                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
-                } catch (final ResourceUnavailableException e) {
-                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
-                } catch (final InsufficientCapacityException e) {
-                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
-                }
-            }
-        }
-    }
-
-    protected class RvRStatusUpdateTask extends ManagedContextRunnable {
-
-        /*
-         * In order to make fail-over works well at any time, we have to ensure:
-         * 1. Backup router's priority = Master's priority - DELTA + 1
-         */
-        private void checkSanity(final List<DomainRouterVO> routers) {
-            final Set<Long> checkedNetwork = new HashSet<Long>();
-            for (final DomainRouterVO router : routers) {
-                if (!router.getIsRedundantRouter()) {
-                    continue;
-                }
-
-                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
-
-                for (final Long routerGuestNtwkId : routerGuestNtwkIds) {
-                    if (checkedNetwork.contains(routerGuestNtwkId)) {
-                        continue;
-                    }
-                    checkedNetwork.add(routerGuestNtwkId);
-
-                    final List<DomainRouterVO> checkingRouters;
-                    final Long vpcId = router.getVpcId();
-                    if (vpcId != null) {
-                        checkingRouters = _routerDao.listByVpcId(vpcId);
-                    } else {
-                        checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER);
-                    }
-
-                    if (checkingRouters.size() != 2) {
-                        continue;
-                    }
-
-                    DomainRouterVO masterRouter = null;
-                    DomainRouterVO backupRouter = null;
-                    for (final DomainRouterVO r : checkingRouters) {
-                        if (r.getRedundantState() == RedundantState.MASTER) {
-                            if (masterRouter == null) {
-                                masterRouter = r;
-                            } else {
-                                // Wilder Rodrigues (wrodrigues@schubergphilis.com
-                                // Force a restart in order to fix the conflict
-                                // recoverRedundantNetwork(masterRouter, r);
-                                break;
-                            }
-                        } else if (r.getRedundantState() == RedundantState.BACKUP) {
-                            if (backupRouter == null) {
-                                backupRouter = r;
-                            } else {
-                                // Wilder Rodrigues (wrodrigues@schubergphilis.com
-                                // Do we have 2 routers in Backup state? Perhaps a restart of 1 router is needed.
-                                // recoverRedundantNetwork(backupRouter, r);
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private void checkDuplicateMaster(final List<DomainRouterVO> routers) {
-            final Map<Long, DomainRouterVO> networkRouterMaps = new HashMap<Long, DomainRouterVO>();
-            for (final DomainRouterVO router : routers) {
-                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
-
-                for (final Long routerGuestNtwkId : routerGuestNtwkIds) {
-                    if (router.getRedundantState() == RedundantState.MASTER) {
-                        if (networkRouterMaps.containsKey(routerGuestNtwkId)) {
-                            final DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId);
-                            final String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router "
-                                    + dupRouter.getHostName();
-                            final String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + dupRouter.getHostName()
-                                    + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. ";
-                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
-                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterId(), dupRouter.getPodIdToDeployIn(), title, context);
-                            s_logger.warn(context);
-                        } else {
-                            networkRouterMaps.put(routerGuestNtwkId, router);
-                        }
-                    }
-                }
-            }
-        }
-
-        @Override
-        protected void runInContext() {
-            while (true) {
-                try {
-                    final Long networkId = _vrUpdateQueue.take(); // This is a blocking call so this thread won't run all the time if no work item in queue.
-
-                    final NetworkVO network = _networkDao.findById(networkId);
-                    final Long vpcId = network.getVpcId();
-
-                    final List<DomainRouterVO> routers;
-                    if (vpcId != null) {
-                        routers = _routerDao.listByVpcId(vpcId);
-                    } else {
-                        routers = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER);
-                    }
-
-                    if (routers.size() != 2) {
-                        continue;
-                    }
-                    /*
-                     * We update the router pair which the lower id router owned
-                     * by this mgmt server, in order to prevent duplicate update
-                     * of router status from cluster mgmt servers
-                     */
-                    final DomainRouterVO router0 = routers.get(0);
-                    final DomainRouterVO router1 = routers.get(1);
-
-                    if (router0.getState() != VirtualMachine.State.Running || router1.getState() != VirtualMachine.State.Running) {
-                        updateRoutersRedundantState(routers);
-                        // Wilder Rodrigues (wrodrigues@schubergphilis.com) - One of the routers is not running,
-                        // so we don't have to continue here since the host will be null any way. Also, there is no need
-                        // To check either for sanity of duplicate master. Thus, just update the state and get lost.
-                        continue;
-                    }
-
-                    DomainRouterVO router = router0;
-                    if (router0.getId() < router1.getId()) {
-                        router = router0;
-                    } else {
-                        router = router1;
-                    }
-                    // && router.getState() == VirtualMachine.State.Stopped
-                    if (router.getHostId() == null && router.getState() == VirtualMachine.State.Running) {
-                        s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to can't find host");
-                        continue;
-                    }
-                    final HostVO host = _hostDao.findById(router.getHostId());
-                    if (host == null || host.getManagementServerId() == null || host.getManagementServerId() != ManagementServerNode.getManagementServerId()) {
-                        s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to not belong to this mgmt server");
-                        continue;
-                    }
-                    updateRoutersRedundantState(routers);
-                    checkDuplicateMaster(routers);
-                    checkSanity(routers);
-                } catch (final Exception ex) {
-                    s_logger.error("Fail to complete the RvRStatusUpdateTask! ", ex);
-                }
-            }
-        }
-    }
-
-    protected class CheckRouterTask extends ManagedContextRunnable {
-
-        public CheckRouterTask() {
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(null);
-                s_logger.debug("Found " + routers.size() + " routers to update status. ");
-
-                updateSite2SiteVpnConnectionState(routers);
-
-                List<NetworkVO> networks = _networkDao.listVpcNetworks();
-                s_logger.debug("Found " + networks.size() + " VPC networks to update Redundant State. ");
-                pushToUpdateQueue(networks);
-
-                networks = _networkDao.listRedundantNetworks();
-                s_logger.debug("Found " + networks.size() + " networks to update RvR status. ");
-                pushToUpdateQueue(networks);
-            } catch (final Exception ex) {
-                s_logger.error("Fail to complete the CheckRouterTask! ", ex);
-            }
-        }
-
-        protected void pushToUpdateQueue(final List<NetworkVO> networks) throws InterruptedException {
-            for (final NetworkVO network : networks) {
-                if (!_vrUpdateQueue.offer(network.getId(), 500, TimeUnit.MILLISECONDS)) {
-                    s_logger.warn("Cannot insert into virtual router update queue! Adjustment of router.check.interval and router.check.poolsize maybe needed.");
-                    break;
-                }
-            }
-        }
-    }
-
-    protected class CheckRouterAlertsTask extends ManagedContextRunnable {
-        public CheckRouterAlertsTask() {
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                getRouterAlerts();
-            } catch (final Exception ex) {
-                s_logger.error("Fail to complete the CheckRouterAlertsTask! ", ex);
-            }
-        }
-    }
-
-    protected void getRouterAlerts() {
-        try {
-            final List<DomainRouterVO> routers = _routerDao.listByStateAndManagementServer(VirtualMachine.State.Running, mgmtSrvrId);
-
-            s_logger.debug("Found " + routers.size() + " running routers. ");
-
-            for (final DomainRouterVO router : routers) {
-                final String serviceMonitoringFlag = SetServiceMonitor.valueIn(router.getDataCenterId());
-                // Skip the routers in VPC network or skip the routers where
-                // Monitor service is not enabled in the corresponding Zone
-                if (!Boolean.parseBoolean(serviceMonitoringFlag) || router.getVpcId() != null) {
-                    continue;
-                }
-                String controlIP = getRouterControlIP(router);
-
-                if (controlIP != null && !controlIP.equals("0.0.0.0")) {
-                    OpRouterMonitorServiceVO opRouterMonitorServiceVO = _opRouterMonitorServiceDao.findById(router.getId());
-
-                    GetRouterAlertsCommand command = null;
-                    if (opRouterMonitorServiceVO == null) {
-                        command = new GetRouterAlertsCommand(new String("1970-01-01 00:00:00")); // To
-                        // avoid
-                        // sending
-                        // null
-                        // value
-                    } else {
-                        command = new GetRouterAlertsCommand(opRouterMonitorServiceVO.getLastAlertTimestamp());
-                    }
-
-                    command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlIP);
-
-                    try {
-                        final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
-                        GetRouterAlertsAnswer answer = null;
-
-                        if (origAnswer == null) {
-                            s_logger.warn("Unable to get alerts from router " + router.getHostName());
-                            continue;
-                        }
-                        if (origAnswer instanceof GetRouterAlertsAnswer) {
-                            answer = (GetRouterAlertsAnswer) origAnswer;
-                        } else {
-                            s_logger.warn("Unable to get alerts from router " + router.getHostName());
-                            continue;
-                        }
-                        if (!answer.getResult()) {
-                            s_logger.warn("Unable to get alerts from router " + router.getHostName() + " " + answer.getDetails());
-                            continue;
-                        }
-
-                        final String alerts[] = answer.getAlerts();
-                        if (alerts != null) {
-                            final String lastAlertTimeStamp = answer.getTimeStamp();
-                            final SimpleDateFormat sdfrmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
-                            sdfrmt.setLenient(false);
-                            try {
-                                sdfrmt.parse(lastAlertTimeStamp);
-                            } catch (final ParseException e) {
-                                s_logger.warn("Invalid last alert timestamp received while collecting alerts from router: " + router.getInstanceName());
-                                continue;
-                            }
-                            for (final String alert : alerts) {
-                                _alertMgr.sendAlert(AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), "Monitoring Service on VR "
-                                        + router.getInstanceName(), alert);
-                            }
-                            if (opRouterMonitorServiceVO == null) {
-                                opRouterMonitorServiceVO = new OpRouterMonitorServiceVO(router.getId(), router.getHostName(), lastAlertTimeStamp);
-                                _opRouterMonitorServiceDao.persist(opRouterMonitorServiceVO);
-                            } else {
-                                opRouterMonitorServiceVO.setLastAlertTimestamp(lastAlertTimeStamp);
-                                _opRouterMonitorServiceDao.update(opRouterMonitorServiceVO.getId(), opRouterMonitorServiceVO);
-                            }
-                        }
-                    } catch (final Exception e) {
-                        s_logger.warn("Error while collecting alerts from router: " + router.getInstanceName(), e);
-                        continue;
-                    }
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.warn("Error while collecting alerts from router", e);
-        }
-    }
-
-    private String getRouterControlIP(DomainRouterVO router){
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        String controlIP = null;
-
-        if(router.getHypervisorType() == HypervisorType.VMware  && dcVo.getNetworkType() == NetworkType.Basic ){
-
-            final List<NicVO> nics = _nicDao.listByVmId(router.getId());
-            for (final NicVO nic : nics) {
-                final NetworkVO nc = _networkDao.findById(nic.getNetworkId());
-                if (nc.getTrafficType() == TrafficType.Guest && nic.getIPv4Address() != null) {
-                    controlIP = nic.getIPv4Address();
-                    break;
-                }
-            }
-            s_logger.debug("Vmware with Basic network selected Guest NIC ip as control IP " + controlIP );
-        }else{
-            controlIP = _routerControlHelper.getRouterControlIp(router.getId());
-        }
-
-        s_logger.debug("IP of control NIC " + controlIP );
-        return controlIP;
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) {
-
-        boolean dnsProvided = true;
-        boolean dhcpProvided = true;
-        boolean publicNetwork = false;
-        final DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
-        _dcDao.loadDetails(dc);
-
-        // 1) Set router details
-        final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId());
-        final Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(router.getId());
-        router.setDetails(details);
-
-        // 2) Prepare boot loader elements related with Control network
-
-        final StringBuilder buf = profile.getBootArgsBuilder();
-        buf.append(" template=domP");
-        buf.append(" name=").append(profile.getHostName());
-
-        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
-            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
-        }
-
-        NicProfile controlNic = null;
-        String defaultDns1 = null;
-        String defaultDns2 = null;
-        String defaultIp6Dns1 = null;
-        String defaultIp6Dns2 = null;
-        for (final NicProfile nic : profile.getNics()) {
-            final int deviceId = nic.getDeviceId();
-            boolean ipv4 = false, ipv6 = false;
-            if (nic.getIPv4Address() != null) {
-                ipv4 = true;
-                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
-                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
-            }
-            if (nic.getIPv6Address() != null) {
-                ipv6 = true;
-                buf.append(" eth").append(deviceId).append("ip6=").append(nic.getIPv6Address());
-                buf.append(" eth").append(deviceId).append("ip6prelen=").append(NetUtils.getIp6CidrSize(nic.getIPv6Cidr()));
-            }
-
-            if (nic.isDefaultNic()) {
-                if (ipv4) {
-                    buf.append(" gateway=").append(nic.getIPv4Gateway());
-                }
-                if (ipv6) {
-                    buf.append(" ip6gateway=").append(nic.getIPv6Gateway());
-                }
-                defaultDns1 = nic.getIPv4Dns1();
-                defaultDns2 = nic.getIPv4Dns2();
-                defaultIp6Dns1 = nic.getIPv6Dns1();
-                defaultIp6Dns2 = nic.getIPv6Dns2();
-            }
-
-            if (nic.getTrafficType() == TrafficType.Management) {
-                buf.append(" localgw=").append(dest.getPod().getGateway());
-            } else if (nic.getTrafficType() == TrafficType.Control) {
-                controlNic = nic;
-                buf.append(createRedundantRouterArgs(controlNic, router));
-
-                // DOMR control command is sent over management server in VMware
-                if (dest.getHost().getHypervisorType() == HypervisorType.VMware || dest.getHost().getHypervisorType() == HypervisorType.Hyperv) {
-                    s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + dest.getPod().getCidrAddress() + "/"
-                            + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: "
-                            + ApiServiceConfiguration.ManagementServerAddresses.value());
-
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Add management server explicit route to DomR.");
-                    }
-
-                    // always add management explicit route, for basic
-                    // networking setup, DomR may have two interfaces while both
-                    // are on the same subnet
-                    _mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key());
-                    if (NetUtils.isValidIp4Cidr(_mgmtCidr)) {
-                        buf.append(" mgmtcidr=").append(_mgmtCidr);
-                        buf.append(" localgw=").append(dest.getPod().getGateway());
-                    }
-
-                    if (dc.getNetworkType() == NetworkType.Basic) {
-                        // ask domR to setup SSH on guest network
-                        buf.append(" sshonguest=true");
-                    }
-
-                }
-            } else if (nic.getTrafficType() == TrafficType.Guest) {
-                dnsProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter);
-                dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter);
-                // build bootloader parameter for the guest
-                buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router));
-            } else if (nic.getTrafficType() == TrafficType.Public) {
-                publicNetwork = true;
-            }
-        }
-
-        if (controlNic == null) {
-            throw new CloudRuntimeException("Didn't start a control port");
-        }
-
-        final String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key());
-        if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
-            _disableRpFilter = true;
-        } else {
-            _disableRpFilter = false;
-        }
-
-        String rpFilter = " ";
-        String type = null;
-        if (router.getVpcId() != null) {
-            type = "vpcrouter";
-            if (_disableRpFilter) {
-                rpFilter = " disable_rp_filter=true";
-            }
-        } else if (!publicNetwork) {
-            type = "dhcpsrvr";
-        } else {
-            type = "router";
-            if (_disableRpFilter) {
-                rpFilter = " disable_rp_filter=true";
-            }
-        }
-
-        if (_disableRpFilter) {
-            rpFilter = " disable_rp_filter=true";
-        }
-
-        buf.append(" type=" + type + rpFilter);
-
-        final String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName());
-        if (domain_suffix != null) {
-            buf.append(" dnssearchorder=").append(domain_suffix);
-        }
-
-        if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) {
-            buf.append(" extra_pubnics=" + _routerExtraPublicNics);
-        }
-
-        /*
-         * If virtual router didn't provide DNS service but provide DHCP
-         * service, we need to override the DHCP response to return DNS server
-         * rather than virtual router itself.
-         */
-        if (dnsProvided || dhcpProvided) {
-            if (defaultDns1 != null) {
-                buf.append(" dns1=").append(defaultDns1);
-            }
-            if (defaultDns2 != null) {
-                buf.append(" dns2=").append(defaultDns2);
-            }
-            if (defaultIp6Dns1 != null) {
-                buf.append(" ip6dns1=").append(defaultIp6Dns1);
-            }
-            if (defaultIp6Dns2 != null) {
-                buf.append(" ip6dns2=").append(defaultIp6Dns2);
-            }
-
-            boolean useExtDns = !dnsProvided;
-            /* For backward compatibility */
-            useExtDns = useExtDns || UseExternalDnsServers.valueIn(dc.getId());
-
-            if (useExtDns) {
-                buf.append(" useextdns=true");
-            }
-        }
-
-        if (Boolean.valueOf(_configDao.getValue(Config.BaremetalProvisionDoneNotificationEnabled.key()))) {
-            final QueryBuilder<UserVO> acntq = QueryBuilder.create(UserVO.class);
-            acntq.and(acntq.entity().getUsername(), SearchCriteria.Op.EQ, "baremetal-system-account");
-            final UserVO user = acntq.find();
-            if (user == null) {
-                s_logger.warn(String
-                        .format("global setting[baremetal.provision.done.notification] is enabled but user baremetal-system-account is not found. Baremetal provision done notification will not be enabled"));
-            } else {
-                buf.append(String.format(" baremetalnotificationsecuritykey=%s", user.getSecretKey()));
-                buf.append(String.format(" baremetalnotificationapikey=%s", user.getApiKey()));
-                buf.append(" host=").append(ApiServiceConfiguration.ManagementServerAddresses.value());
-                buf.append(" port=").append(_configDao.getValue(Config.BaremetalProvisionDoneNotificationPort.key()));
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
-        }
-
-        return true;
-    }
-
-    protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) {
-        final long guestNetworkId = guestNic.getNetworkId();
-        final NetworkVO guestNetwork = _networkDao.findById(guestNetworkId);
-        String dhcpRange = null;
-        final DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId());
-
-        final StringBuilder buf = new StringBuilder();
-
-        final boolean isRedundant = router.getIsRedundantRouter();
-        if (isRedundant) {
-            buf.append(createRedundantRouterArgs(guestNic, router));
-            final Network net = _networkModel.getNetwork(guestNic.getNetworkId());
-            buf.append(" guestgw=").append(net.getGateway());
-            final String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIPv4Address()) | ~NetUtils.ip2Long(guestNic.getIPv4Netmask()));
-            buf.append(" guestbrd=").append(brd);
-            buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getIPv4Netmask()));
-
-            final int advertInt = NumbersUtil.parseInt(_configDao.getValue(Config.RedundantRouterVrrpInterval.key()), 1);
-            buf.append(" advert_int=").append(advertInt);
-        }
-
-        // setup network domain
-        final String domain = guestNetwork.getNetworkDomain();
-        if (domain != null) {
-            buf.append(" domain=" + domain);
-        }
-
-        long cidrSize = 0;
-
-        // setup dhcp range
-        if (dc.getNetworkType() == NetworkType.Basic) {
-            if (guestNic.isDefaultNic()) {
-                cidrSize = NetUtils.getCidrSize(guestNic.getIPv4Netmask());
-                final String cidr = NetUtils.getCidrSubNet(guestNic.getIPv4Gateway(), cidrSize);
-                if (cidr != null) {
-                    dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
-                }
-            }
-        } else if (dc.getNetworkType() == NetworkType.Advanced) {
-            final String cidr = _networkModel.getValidNetworkCidr(guestNetwork);
-            if (cidr != null) {
-                cidrSize = NetUtils.getCidrSize(NetUtils.getCidrNetmask(cidr));
-                dhcpRange = NetUtils.getDhcpRange(cidr);
-            }
-        }
-
-        if (dhcpRange != null) {
-            // To limit DNS to the cidr range
-            buf.append(" cidrsize=" + String.valueOf(cidrSize));
-            buf.append(" dhcprange=" + dhcpRange);
-        }
-
-        return buf;
-    }
-
-    protected StringBuilder createRedundantRouterArgs(final NicProfile nic, final DomainRouterVO router) {
-        final StringBuilder buf = new StringBuilder();
-
-        final boolean isRedundant = router.getIsRedundantRouter();
-        if (isRedundant) {
-            buf.append(" redundant_router=1");
-
-            final int advertInt = NumbersUtil.parseInt(_configDao.getValue(Config.RedundantRouterVrrpInterval.key()), 1);
-            buf.append(" advert_int=").append(advertInt);
-
-            final Long vpcId = router.getVpcId();
-            final List<DomainRouterVO> routers;
-            if (vpcId != null) {
-                routers = _routerDao.listByVpcId(vpcId);
-                // For a redundant VPC router, both shall have the same router id. It will be used by the VRRP virtural_router_id attribute.
-                // So we use the VPC id to avoid group problems.
-                buf.append(" router_id=").append(vpcId);
-
-                // Will build the routers password based on the VPC ID and UUID.
-                final Vpc vpc = _vpcDao.findById(vpcId);
-
-                try {
-                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
-                    final byte [] rawDigest = vpc.getUuid().getBytes(Charset.defaultCharset());
-                    digest.update(rawDigest);
-
-                    final BigInteger password = new BigInteger(1, digest.digest());
-                    buf.append(" router_password=").append(password);
-
-                } catch (final NoSuchAlgorithmException e) {
-                    s_logger.error("Failed to pssword! Will use the plan B instead.");
-                    buf.append(" router_password=").append(vpc.getUuid());
-                }
-
-            } else {
-                routers = _routerDao.listByNetworkAndRole(nic.getNetworkId(), Role.VIRTUAL_ROUTER);
-            }
-
-            String redundantState = RedundantState.BACKUP.toString();
-            router.setRedundantState(RedundantState.BACKUP);
-            if (routers.size() == 0) {
-                redundantState = RedundantState.MASTER.toString();
-                router.setRedundantState(RedundantState.MASTER);
-            } else {
-                final DomainRouterVO router0 = routers.get(0);
-                if (router.getId() == router0.getId()) {
-                    redundantState = RedundantState.MASTER.toString();
-                    router.setRedundantState(RedundantState.MASTER);
-                }
-            }
-
-            buf.append(" redundant_state=").append(redundantState);
-        }
-
-        return buf;
-    }
-
-    @Override
-    public boolean finalizeDeployment(final Commands cmds, final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context)
-            throws ResourceUnavailableException {
-        final DomainRouterVO router = _routerDao.findById(profile.getId());
-
-        final List<NicProfile> nics = profile.getNics();
-        for (final NicProfile nic : nics) {
-            if (nic.getTrafficType() == TrafficType.Public) {
-                router.setPublicIpAddress(nic.getIPv4Address());
-                router.setPublicNetmask(nic.getIPv4Netmask());
-                router.setPublicMacAddress(nic.getMacAddress());
-            } else if (nic.getTrafficType() == TrafficType.Control) {
-                router.setPrivateIpAddress(nic.getIPv4Address());
-                router.setPrivateMacAddress(nic.getMacAddress());
-            }
-        }
-        _routerDao.update(router.getId(), router);
-
-        finalizeCommandsOnStart(cmds, profile);
-        return true;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachineProfile profile) {
-        final DomainRouterVO router = _routerDao.findById(profile.getId());
-        final NicProfile controlNic = getControlNic(profile);
-
-        if (controlNic == null) {
-            s_logger.error("Control network doesn't exist for the router " + router);
-            return false;
-        }
-
-        finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic);
-
-        // restart network if restartNetwork = false is not specified in profile
-        // parameters
-        boolean reprogramGuestNtwks = true;
-        if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
-            reprogramGuestNtwks = false;
-        }
-
-        final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
-        if (vrProvider == null) {
-            throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
-        }
-        final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
-        if (provider == null) {
-            throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
-        }
-
-        final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
-        for (final Long guestNetworkId : routerGuestNtwkIds) {
-            final AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, router.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
-                    guestNetworkId, router.getId()));
-            cmds.addCommand(startCmd);
-
-            if (reprogramGuestNtwks) {
-                finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId, null);
-                finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId);
-
-                final NetworkOffering offering = _networkOfferingDao.findById(_networkDao.findById(guestNetworkId).getNetworkOfferingId());
-                // service monitoring is currently not added in RVR
-                if (!offering.getRedundantRouter()) {
-                    final String serviceMonitringSet = _configDao.getValue(Config.EnableServiceMonitoring.key());
-
-                    if (serviceMonitringSet != null && serviceMonitringSet.equalsIgnoreCase("true")) {
-                        finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, true);
-                    } else {
-                        finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, false);
-                    }
-                }
-
-            }
-
-            finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
-
-            final AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, router.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
-                    guestNetworkId, router.getId()));
-            cmds.addCommand(finishCmd);
-        }
-
-        return true;
-    }
-
-    private void finalizeMonitorServiceOnStrat(final Commands cmds, final VirtualMachineProfile profile, final DomainRouterVO router, final Provider provider,
-            final long networkId, final Boolean add) {
-
-        final NetworkVO network = _networkDao.findById(networkId);
-
-        s_logger.debug("Creating  monitoring services on " + router + " start...");
-
-        // get the list of sevices for this network to monitor
-        final List<MonitoringServiceVO> services = new ArrayList<MonitoringServiceVO>();
-        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter)
-                || _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter)) {
-            final MonitoringServiceVO dhcpService = _monitorServiceDao.getServiceByName(MonitoringService.Service.Dhcp.toString());
-            if (dhcpService != null) {
-                services.add(dhcpService);
-            }
-        }
-
-        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, Provider.VirtualRouter)) {
-            final MonitoringServiceVO lbService = _monitorServiceDao.getServiceByName(MonitoringService.Service.LoadBalancing.toString());
-            if (lbService != null) {
-                services.add(lbService);
-            }
-        }
-        final List<MonitoringServiceVO> defaultServices = _monitorServiceDao.listDefaultServices(true);
-        services.addAll(defaultServices);
-
-        final List<MonitorServiceTO> servicesTO = new ArrayList<MonitorServiceTO>();
-        for (final MonitoringServiceVO service : services) {
-            final MonitorServiceTO serviceTO = new MonitorServiceTO(service.getService(), service.getProcessName(), service.getServiceName(), service.getServicePath(),
-                    service.getServicePidFile(), service.isDefaultService());
-            servicesTO.add(serviceTO);
-        }
-
-        // TODO : This is a hacking fix
-        // at VR startup time, information in VirtualMachineProfile may not
-        // updated to DB yet,
-        // getRouterControlIp() may give wrong IP under basic network mode in
-        // VMware environment
-        final NicProfile controlNic = getControlNic(profile);
-        if (controlNic == null) {
-            throw new CloudRuntimeException("VirtualMachine " + profile.getInstanceName() + " doesn't have a control interface");
-        }
-        final SetMonitorServiceCommand command = new SetMonitorServiceCommand(servicesTO);
-        command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIPv4Address());
-        command.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(networkId, router.getId()));
-        command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-
-        if (!add) {
-            command.setAccessDetail(NetworkElementCommand.ROUTER_MONITORING_ENABLE, add.toString());
-        }
-        cmds.addCommand("monitor", command);
-    }
-
-    protected NicProfile getControlNic(final VirtualMachineProfile profile) {
-        final DomainRouterVO router = _routerDao.findById(profile.getId());
-        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
-        NicProfile controlNic = null;
-        if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) {
-            // TODO this is a ugly to test hypervisor type here
-            // for basic network mode, we will use the guest NIC for control NIC
-            for (final NicProfile nic : profile.getNics()) {
-                if (nic.getTrafficType() == TrafficType.Guest && nic.getIPv4Address() != null) {
-                    controlNic = nic;
-                }
-            }
-        } else {
-            for (final NicProfile nic : profile.getNics()) {
-                if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
-                    controlNic = nic;
-                }
-            }
-        }
-        return controlNic;
-    }
-
-    protected void finalizeSshAndVersionAndNetworkUsageOnStart(final Commands cmds, final VirtualMachineProfile profile, final DomainRouterVO router, final NicProfile controlNic) {
-        final DomainRouterVO vr = _routerDao.findById(profile.getId());
-        cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922));
-
-        // Update router template/scripts version
-        final GetDomRVersionCmd command = new GetDomRVersionCmd();
-        command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIPv4Address());
-        command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        cmds.addCommand("getDomRVersion", command);
-
-        // Network usage command to create iptables rules
-        final boolean forVpc = vr.getVpcId() != null;
-        if (!forVpc) {
-            cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIPv4Address(), router.getHostName(), "create", forVpc));
-        }
-    }
-
-    protected void finalizeUserDataAndDhcpOnStart(final Commands cmds, final DomainRouterVO router, final Provider provider, final Long guestNetworkId) {
-        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)
-                || _networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dns, provider)) {
-            // Resend dhcp
-            s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start...");
-            _commandSetupHelper.createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId);
-        }
-
-        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) {
-            // Resend user data
-            s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start...");
-            _commandSetupHelper.createVmDataCommandForVMs(router, cmds, guestNetworkId);
-        }
-    }
-
-    protected void finalizeNetworkRulesForNetwork(final Commands cmds, final DomainRouterVO router, final Provider provider, final Long guestNetworkId) {
-        s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
-
-        final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
-        final List<FirewallRule> firewallRulesEgress = new ArrayList<FirewallRule>();
-
-        // Fetch firewall Egress rules.
-        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
-            firewallRulesEgress.addAll(_rulesDao.listByNetworkPurposeTrafficType(guestNetworkId, Purpose.Firewall, FirewallRule.TrafficType.Egress));
-            if (firewallRulesEgress.isEmpty()) {
-                //create egress default rule for VR
-                createDefaultEgressFirewallRule(firewallRulesEgress, guestNetworkId);
-            }
-        }
-
-        // Re-apply firewall Egress rules
-        s_logger.debug("Found " + firewallRulesEgress.size() + " firewall Egress rule(s) to apply as a part of domR " + router + " start.");
-        if (!firewallRulesEgress.isEmpty()) {
-            _commandSetupHelper.createFirewallRulesCommands(firewallRulesEgress, router, cmds, guestNetworkId);
-        }
-
-        if (publicIps != null && !publicIps.isEmpty()) {
-            final List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
-            final List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
-            final List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
-            final List<StaticNat> staticNats = new ArrayList<StaticNat>();
-            final List<FirewallRule> firewallRulesIngress = new ArrayList<FirewallRule>();
-
-            // Get information about all the rules (StaticNats and
-            // StaticNatRules; PFVPN to reapply on domR start)
-            for (final PublicIpAddress ip : publicIps) {
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) {
-                    pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
-                }
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
-                    staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
-                }
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
-                    firewallRulesIngress.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
-                }
-
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) {
-                    final RemoteAccessVpn vpn = _vpnDao.findByPublicIpAddress(ip.getId());
-                    if (vpn != null) {
-                        vpns.add(vpn);
-                    }
-                }
-
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
-                    if (ip.isOneToOneNat()) {
-
-                        boolean revoke = false;
-                        if (ip.getState() == IpAddress.State.Releasing ) {
-                            // for ips got struck in releasing state we need to delete the rule not add.
-                            s_logger.debug("Rule revoke set to true for the ip " + ip.getAddress() +" becasue it is in releasing state");
-                            revoke = true;
-                        }
-                        final StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), ip.getVmIp(), revoke);
-
-                        staticNats.add(staticNat);
-                    }
-                }
-            }
-
-            // Re-apply static nats
-            s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
-            if (!staticNats.isEmpty()) {
-                _commandSetupHelper.createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId);
-            }
-
-            // Re-apply firewall Ingress rules
-            s_logger.debug("Found " + firewallRulesIngress.size() + " firewall Ingress rule(s) to apply as a part of domR " + router + " start.");
-            if (!firewallRulesIngress.isEmpty()) {
-                _commandSetupHelper.createFirewallRulesCommands(firewallRulesIngress, router, cmds, guestNetworkId);
-            }
-
-            // Re-apply port forwarding rules
-            s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start.");
-            if (!pfRules.isEmpty()) {
-                _commandSetupHelper.createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId);
-            }
-
-            // Re-apply static nat rules
-            s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start.");
-            if (!staticNatFirewallRules.isEmpty()) {
-                final List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
-                for (final FirewallRule rule : staticNatFirewallRules) {
-                    staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false));
-                }
-                _commandSetupHelper.createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId);
-            }
-
-            // Re-apply vpn rules
-            s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start.");
-            if (!vpns.isEmpty()) {
-                for (final RemoteAccessVpn vpn : vpns) {
-                    _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
-                }
-            }
-
-            final List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkIdAndScheme(guestNetworkId, Scheme.Public);
-            final List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
-            if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) {
-                // Re-apply load balancing rules
-                for (final LoadBalancerVO lb : lbs) {
-                    final List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
-                    final List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
-                    final List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
-                    final Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
-                    final LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
-                    final LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
-                    lbRules.add(loadBalancing);
-                }
-            }
-
-            s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start.");
-            if (!lbRules.isEmpty()) {
-                _commandSetupHelper.createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId);
-            }
-        }
-        // Reapply dhcp and dns configuration.
-        final Network guestNetwork = _networkDao.findById(guestNetworkId);
-        if (guestNetwork.getGuestType() == GuestType.Shared && _networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) {
-            final Map<Network.Capability, String> dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(
-                    _networkOfferingDao.findById(_networkDao.findById(guestNetworkId).getNetworkOfferingId()), Service.Dhcp);
-            final String supportsMultipleSubnets = dhcpCapabilities.get(Network.Capability.DhcpAccrossMultipleSubnets);
-            if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) {
-                final List<NicIpAliasVO> revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(guestNetworkId, NicIpAlias.State.revoked);
-                s_logger.debug("Found" + revokedIpAliasVOs.size() + "ip Aliases to revoke on the router as a part of dhcp configuration");
-                removeRevokedIpAliasFromDb(revokedIpAliasVOs);
-
-                final List<NicIpAliasVO> aliasVOs = _nicIpAliasDao.listByNetworkIdAndState(guestNetworkId, NicIpAlias.State.active);
-                s_logger.debug("Found" + aliasVOs.size() + "ip Aliases to apply on the router as a part of dhcp configuration");
-                final List<IpAliasTO> activeIpAliasTOs = new ArrayList<IpAliasTO>();
-                for (final NicIpAliasVO aliasVO : aliasVOs) {
-                    activeIpAliasTOs.add(new IpAliasTO(aliasVO.getIp4Address(), aliasVO.getNetmask(), aliasVO.getAliasCount().toString()));
-                }
-                if (activeIpAliasTOs.size() != 0) {
-                    _commandSetupHelper.createIpAlias(router, activeIpAliasTOs, guestNetworkId, cmds);
-                    _commandSetupHelper.configDnsMasq(router, _networkDao.findById(guestNetworkId), cmds);
-                }
-            }
-        }
-    }
-
-    private void createDefaultEgressFirewallRule(final List<FirewallRule> rules, final long networkId) {
-        final NetworkVO network = _networkDao.findById(networkId);
-        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        final Boolean defaultEgressPolicy = offering.getEgressDefaultPolicy();
-
-        // The default on the router is set to Deny all. So, if the default configuration in the offering is set to true (Allow), we change the Egress here
-        if (defaultEgressPolicy) {
-            final List<String> sourceCidr = new ArrayList<String>();
-            final List<String> destCidr = new ArrayList<String>();
-
-            sourceCidr.add(network.getCidr());
-            destCidr.add(NetUtils.ALL_IP4_CIDRS);
-
-            final FirewallRule rule = new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr,
-                    destCidr, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.System);
-
-            rules.add(rule);
-        } else {
-            s_logger.debug("Egress policy for the Network " + networkId + " is already defined as Deny. So, no need to default the rule to Allow. ");
-        }
-    }
-
-    private void removeRevokedIpAliasFromDb(final List<NicIpAliasVO> revokedIpAliasVOs) {
-        for (final NicIpAliasVO ipalias : revokedIpAliasVOs) {
-            _nicIpAliasDao.expunge(ipalias.getId());
-        }
-    }
-
-    protected void finalizeIpAssocForNetwork(final Commands cmds, final VirtualRouter router, final Provider provider, final Long guestNetworkId,
-            final Map<String, String> vlanMacAddress) {
-
-        final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
-
-        if (publicIps != null && !publicIps.isEmpty()) {
-            s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start.");
-            // Re-apply public ip addresses - should come before PF/LB/VPN
-            if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
-                _commandSetupHelper.createAssociateIPCommands(router, publicIps, cmds, 0);
-            }
-        }
-    }
-
-    protected ArrayList<? extends PublicIpAddress> getPublicIpsToApply(final VirtualRouter router, final Provider provider, final Long guestNetworkId,
-            final com.cloud.network.IpAddress.State... skipInStates) {
-        final long ownerId = router.getAccountId();
-        final List<? extends IpAddress> userIps;
-
-        final Network guestNetwork = _networkDao.findById(guestNetworkId);
-        if (guestNetwork.getGuestType() == GuestType.Shared) {
-            // ignore the account id for the shared network
-            userIps = _networkModel.listPublicIpsAssignedToGuestNtwk(guestNetworkId, null);
-        } else {
-            userIps = _networkModel.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null);
-        }
-
-        final List<PublicIp> allPublicIps = new ArrayList<PublicIp>();
-        if (userIps != null && !userIps.isEmpty()) {
-            boolean addIp = true;
-            for (final IpAddress userIp : userIps) {
-                if (skipInStates != null) {
-                    for (final IpAddress.State stateToSkip : skipInStates) {
-                        if (userIp.getState() == stateToSkip) {
-                            s_logger.debug("Skipping ip address " + userIp + " in state " + userIp.getState());
-                            addIp = false;
-                            break;
-                        }
-                    }
-                }
-
-                if (addIp) {
-                    final IPAddressVO ipVO = _ipAddressDao.findById(userIp.getId());
-                    final PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipVO, _vlanDao.findById(userIp.getVlanId()));
-                    allPublicIps.add(publicIp);
-                }
-            }
-        }
-
-        // Get public Ips that should be handled by router
-        final Network network = _networkDao.findById(guestNetworkId);
-        final Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(allPublicIps, false, true);
-        final Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = _networkModel.getProviderToIpList(network, ipToServices);
-        // Only cover virtual router for now, if ELB use it this need to be
-        // modified
-
-        final ArrayList<PublicIpAddress> publicIps = providerToIpList.get(provider);
-        return publicIps;
-    }
-
-    @Override
-    public boolean finalizeStart(final VirtualMachineProfile profile, final long hostId, final Commands cmds, final ReservationContext context) {
-        final DomainRouterVO router = _routerDao.findById(profile.getId());
-
-        // process all the answers
-        for (final Answer answer : cmds.getAnswers()) {
-            // handle any command failures
-            if (!answer.getResult()) {
-                final String cmdClassName = answer.getClass().getCanonicalName().replace("Answer", "Command");
-                final String errorMessage = "Command: " + cmdClassName + " failed while starting virtual router";
-                final String errorDetails = "Details: " + answer.getDetails() + " " + answer.toString();
-                // add alerts for the failed commands
-                _alertMgr.sendAlert(AlertService.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), errorMessage, errorDetails);
-                s_logger.error(answer.getDetails());
-                s_logger.warn(errorMessage);
-                // Stop the router if any of the commands failed
-                return false;
-            }
-        }
-
-        // at this point, all the router command are successful.
-        boolean result = true;
-        // Get guest networks info
-        final List<Network> guestNetworks = new ArrayList<Network>();
-
-        final List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
-        for (final Nic nic : routerNics) {
-            final Network network = _networkModel.getNetwork(nic.getNetworkId());
-
-            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-
-            if (network.getTrafficType() == TrafficType.Guest) {
-                guestNetworks.add(network);
-                if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
-                    final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
-
-                    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-                    try {
-                        result = networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nicProfile);
-                    } catch (final ResourceUnavailableException e) {
-                        s_logger.debug("ERROR in finalizeStart: ", e);
-                    }
-                }
-            }
-        }
-        if (result) {
-            final GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer) cmds.getAnswer("getDomRVersion");
-            router.setTemplateVersion(versionAnswer.getTemplateVersion());
-            router.setScriptsVersion(versionAnswer.getScriptsVersion());
-            _routerDao.persist(router, guestNetworks);
-        }
-
-        return result;
-    }
-
-    @Override
-    public void finalizeStop(final VirtualMachineProfile profile, final Answer answer) {
-        if (answer != null) {
-            final VirtualMachine vm = profile.getVirtualMachine();
-            final DomainRouterVO domR = _routerDao.findById(vm.getId());
-            processStopOrRebootAnswer(domR, answer);
-            final List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
-            for (final Nic nic : routerNics) {
-                final Network network = _networkModel.getNetwork(nic.getNetworkId());
-                final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
-
-                if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) {
-                    final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
-
-                    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
-                    try {
-                        networkTopology.setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile);
-                    } catch (final ResourceUnavailableException e) {
-                        s_logger.debug("ERROR in finalizeStop: ", e);
-                    }
-                }
-            }
-
-        }
-    }
-
-    @Override
-    public void finalizeExpunge(final VirtualMachine vm) {
-    }
-
-    @Override
-    public boolean startRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
-        if (routers == null || routers.isEmpty()) {
-            s_logger.warn("Failed to start remote access VPN: no router found for account and zone");
-            throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", DataCenter.class, network.getDataCenterId());
-        }
-
-        for (final VirtualRouter router : routers) {
-            if (router.getState() != VirtualMachine.State.Running) {
-                s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState());
-                throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + router.getState(), DataCenter.class,
-                        network.getDataCenterId());
-            }
-
-            final Commands cmds = new Commands(Command.OnError.Stop);
-            _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
-
-            if (!_nwHelper.sendCommandsToRouter(router, cmds)) {
-                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId());
-            }
-
-            Answer answer = cmds.getAnswer("users");
-            if (!answer.getResult()) {
-                s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
-                        + router.getInstanceName() + " due to " + answer.getDetails());
-                throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account "
-                        + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
-            }
-            answer = cmds.getAnswer("startVpn");
-            if (!answer.getResult()) {
-                s_logger.error("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName()
-                        + " due to " + answer.getDetails());
-                throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
-                        + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
-            }
-
-        }
-        return true;
-    }
-
-    @Override
-    public boolean deleteRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
-        if (routers == null || routers.isEmpty()) {
-            s_logger.warn("Failed to delete remote access VPN: no router found for account and zone");
-            throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId());
-        }
-
-        boolean result = true;
-        for (final VirtualRouter router : routers) {
-            if (router.getState() == VirtualMachine.State.Running) {
-                final Commands cmds = new Commands(Command.OnError.Continue);
-                _commandSetupHelper.createApplyVpnCommands(false, vpn, router, cmds);
-                result = result && _nwHelper.sendCommandsToRouter(router, cmds);
-            } else if (router.getState() == VirtualMachine.State.Stopped) {
-                s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it");
-                continue;
-            } else {
-                s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState());
-                throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class,
-                        network.getDataCenterId());
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public DomainRouterVO stop(final VirtualRouter router, final boolean forced, final User user, final Account caller) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        s_logger.debug("Stopping router " + router);
-        try {
-            _itMgr.advanceStop(router.getUuid(), forced);
-            return _routerDao.findById(router.getId());
-        } catch (final OperationTimedoutException e) {
-            throw new CloudRuntimeException("Unable to stop " + router, e);
-        }
-    }
-
-    @Override
-    public boolean removeDhcpSupportForSubnet(final Network network, final List<DomainRouterVO> routers) throws ResourceUnavailableException {
-        if (routers == null || routers.isEmpty()) {
-            s_logger.warn("Failed to add/remove VPN users: no router found for account and zone");
-            throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId());
-        }
-
-        for (final DomainRouterVO router : routers) {
-            if (router.getState() != VirtualMachine.State.Running) {
-                s_logger.warn("Failed to add/remove VPN users: router not in running state");
-                throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class,
-                        network.getDataCenterId());
-            }
-
-            final Commands cmds = new Commands(Command.OnError.Continue);
-            final List<NicIpAliasVO> revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.revoked);
-            s_logger.debug("Found" + revokedIpAliasVOs.size() + "ip Aliases to revoke on the router as a part of dhcp configuration");
-            final List<IpAliasTO> revokedIpAliasTOs = new ArrayList<IpAliasTO>();
-            for (final NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) {
-                revokedIpAliasTOs.add(new IpAliasTO(revokedAliasVO.getIp4Address(), revokedAliasVO.getNetmask(), revokedAliasVO.getAliasCount().toString()));
-            }
-            final List<NicIpAliasVO> aliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.active);
-            s_logger.debug("Found" + aliasVOs.size() + "ip Aliases to apply on the router as a part of dhcp configuration");
-            final List<IpAliasTO> activeIpAliasTOs = new ArrayList<IpAliasTO>();
-            for (final NicIpAliasVO aliasVO : aliasVOs) {
-                activeIpAliasTOs.add(new IpAliasTO(aliasVO.getIp4Address(), aliasVO.getNetmask(), aliasVO.getAliasCount().toString()));
-            }
-            _commandSetupHelper.createDeleteIpAliasCommand(router, revokedIpAliasTOs, activeIpAliasTOs, network.getId(), cmds);
-            _commandSetupHelper.configDnsMasq(router, network, cmds);
-            final boolean result = _nwHelper.sendCommandsToRouter(router, cmds);
-            if (result) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(final TransactionStatus status) {
-                        for (final NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) {
-                            _nicIpAliasDao.expunge(revokedAliasVO.getId());
-                        }
-                    }
-                });
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "starting router Vm", async = true)
-    public VirtualRouter startRouter(final long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
-        return startRouter(id, true);
-    }
-
-    @Override
-    public VirtualRouter startRouter(final long routerId, final boolean reprogramNetwork) throws ResourceUnavailableException, InsufficientCapacityException,
-    ConcurrentOperationException {
-        final Account caller = CallContext.current().getCallingAccount();
-        final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-
-        // verify parameters
-        DomainRouterVO router = _routerDao.findById(routerId);
-        //clean up the update_state feild
-        if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_FAILED){
-            router.setUpdateState(null);
-            _routerDao.update(router.getId(),router);
-        }
-        if (router == null) {
-            throw new InvalidParameterValueException("Unable to find router by id " + routerId + ".");
-        }
-        _accountMgr.checkAccess(caller, null, true, router);
-
-        final Account owner = _accountMgr.getAccount(router.getAccountId());
-
-        // Check if all networks are implemented for the domR; if not -
-        // implement them
-        final DataCenter dc = _dcDao.findById(router.getDataCenterId());
-        HostPodVO pod = null;
-        if (router.getPodIdToDeployIn() != null) {
-            pod = _podDao.findById(router.getPodIdToDeployIn());
-        }
-        final DeployDestination dest = new DeployDestination(dc, pod, null, null);
-
-        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
-
-        final List<NicVO> nics = _nicDao.listByVmId(routerId);
-
-        for (final NicVO nic : nics) {
-            if (!_networkMgr.startNetwork(nic.getNetworkId(), dest, context)) {
-                s_logger.warn("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start");
-                throw new CloudRuntimeException("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start");
-            }
-        }
-
-        // After start network, check if it's already running
-        router = _routerDao.findById(routerId);
-        if (router.getState() == VirtualMachine.State.Running) {
-            return router;
-        }
-
-        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
-        final Map<Param, Object> params = new HashMap<Param, Object>();
-        if (reprogramNetwork) {
-            params.put(Param.ReProgramGuestNetworks, true);
-        } else {
-            params.put(Param.ReProgramGuestNetworks, false);
-        }
-        final VirtualRouter virtualRouter = _nwHelper.startVirtualRouter(router, user, caller, params);
-        if (virtualRouter == null) {
-            throw new CloudRuntimeException("Failed to start router with id " + routerId);
-        }
-        return virtualRouter;
-    }
-
-    @Override
-    public List<VirtualRouter> getRoutersForNetwork(final long networkId) {
-        final List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
-        final List<VirtualRouter> vrs = new ArrayList<VirtualRouter>(routers.size());
-        for (final DomainRouterVO router : routers) {
-            vrs.add(router);
-        }
-        return vrs;
-    }
-
-    @Override
-    public String getDnsBasicZoneUpdate() {
-        return _dnsBasicZoneUpdates;
-    }
-
-    @Override
-    public int getTimeout() {
-        return -1;
-    }
-
-    @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 void processHostAdded(long hostId) {
-    }
-
-    @Override
-    public void processConnect(final Host host, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
-        final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(host.getId());
-        for (DomainRouterVO router : routers) {
-            if (router.isStopPending()) {
-                s_logger.info("Stopping router " + router.getInstanceName() + " due to stop pending flag found!");
-                final VirtualMachine.State state = router.getState();
-                if (state != VirtualMachine.State.Stopped && state != VirtualMachine.State.Destroyed) {
-                    try {
-                        stopRouter(router.getId(), false);
-                    } catch (final ResourceUnavailableException e) {
-                        s_logger.warn("Fail to stop router " + router.getInstanceName(), e);
-                        throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName());
-                    } catch (final ConcurrentOperationException e) {
-                        s_logger.warn("Fail to stop router " + router.getInstanceName(), e);
-                        throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName());
-                    }
-                }
-                router.setStopPending(false);
-                router = _routerDao.persist(router);
-            }
-        }
-    }
-
-    @Override
-    public AgentControlAnswer processControlCommand(final long agentId, final AgentControlCommand cmd) {
-        return null;
-    }
-
-    @Override
-    public boolean processDisconnect(final long agentId, final Status state) {
-        return false;
-    }
-
-    @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 void prepareStop(final VirtualMachineProfile profile) {
-        // Collect network usage before stopping Vm
-
-        final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId());
-        if (router == null) {
-            return;
-        }
-
-        final String privateIP = router.getPrivateIpAddress();
-
-        if (privateIP != null) {
-            final boolean forVpc = router.getVpcId() != null;
-            final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
-            for (final Nic routerNic : routerNics) {
-                final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
-                // Send network usage command for public nic in VPC VR
-                // Send network usage command for isolated guest nic of non VPC
-                // VR
-                if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
-                        && network.getGuestType() == Network.GuestType.Isolated) {
-                    final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());
-                    final String routerType = router.getType().toString();
-                    final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(),
-                            forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
-                    NetworkUsageAnswer answer = null;
-                    try {
-                        answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
-                    } catch (final Exception e) {
-                        s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e);
-                        continue;
-                    }
-
-                    if (answer != null) {
-                        if (!answer.getResult()) {
-                            s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() + "; details: "
-                                    + answer.getDetails());
-                            continue;
-                        }
-                        try {
-                            if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) {
-                                s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
-                                continue;
-                            }
-
-                            final NetworkUsageAnswer answerFinal = answer;
-                            Transaction.execute(new TransactionCallbackNoReturn() {
-                                @Override
-                                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                                    final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(),
-                                            forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
-                                    if (stats == null) {
-                                        s_logger.warn("unable to find stats for account: " + router.getAccountId());
-                                        return;
-                                    }
-
-                                    if (previousStats != null
-                                            && (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats
-                                            .getCurrentBytesSent())) {
-                                        s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: "
-                                                + answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent());
-                                        return;
-                                    }
-
-                                    if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Received # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Router: "
-                                                    + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived());
-                                        }
-                                        stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
-                                    }
-                                    stats.setCurrentBytesReceived(answerFinal.getBytesReceived());
-                                    if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Received # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Router: "
-                                                    + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesSent() + " Stored: " + stats.getCurrentBytesSent());
-                                        }
-                                        stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
-                                    }
-                                    stats.setCurrentBytesSent(answerFinal.getBytesSent());
-                                    if (!_dailyOrHourly) {
-                                        // update agg bytes
-                                        stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
-                                        stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
-                                    }
-                                    _userStatsDao.update(stats.getId(), stats);
-                                }
-                            });
-                        } catch (final Exception e) {
-                            s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: "
-                                    + answer.getBytesSent());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public VirtualRouter findRouter(final long routerId) {
-        return _routerDao.findById(routerId);
-    }
-
-    @Override
-    public List<Long> upgradeRouterTemplate(final UpgradeRouterTemplateCmd cmd) {
-
-        List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>();
-        int params = 0;
-
-        final Long routerId = cmd.getId();
-        if (routerId != null) {
-            params++;
-            final DomainRouterVO router = _routerDao.findById(routerId);
-            if (router != null) {
-                routers.add(router);
-            }
-        }
-
-        final Long domainId = cmd.getDomainId();
-        if (domainId != null) {
-            final String accountName = cmd.getAccount();
-            // List by account, if account Name is specified along with domainId
-            if (accountName != null) {
-                final Account account = _accountMgr.getActiveAccountByName(accountName, domainId);
-                if (account == null) {
-                    throw new InvalidParameterValueException("Account :" + accountName + " does not exist in domain: " + domainId);
-                }
-                routers = _routerDao.listRunningByAccountId(account.getId());
-            } else {
-                // List by domainId, account name not specified
-                routers = _routerDao.listRunningByDomain(domainId);
-            }
-            params++;
-        }
-
-        final Long clusterId = cmd.getClusterId();
-        if (clusterId != null) {
-            params++;
-            routers = _routerDao.listRunningByClusterId(clusterId);
-        }
-
-        final Long podId = cmd.getPodId();
-        if (podId != null) {
-            params++;
-            routers = _routerDao.listRunningByPodId(podId);
-        }
-
-        final Long zoneId = cmd.getZoneId();
-        if (zoneId != null) {
-            params++;
-            routers = _routerDao.listRunningByDataCenter(zoneId);
-        }
-
-        if (params > 1) {
-            throw new InvalidParameterValueException("Multiple parameters not supported. Specify only one among routerId/zoneId/podId/clusterId/accountId/domainId");
-        }
-
-        if (routers != null) {
-            return rebootRouters(routers);
-        }
-
-        return null;
-    }
-
-    private List<Long> rebootRouters(final List<DomainRouterVO> routers) {
-        final List<Long> jobIds = new ArrayList<Long>();
-        for (final DomainRouterVO router : routers) {
-            if (!_nwHelper.checkRouterVersion(router)) {
-                s_logger.debug("Upgrading template for router: " + router.getId());
-                final Map<String, String> params = new HashMap<String, String>();
-                params.put("ctxUserId", "1");
-                params.put("ctxAccountId", "" + router.getAccountId());
-
-                final RebootRouterCmd cmd = new RebootRouterCmd();
-                ComponentContext.inject(cmd);
-                params.put("id", "" + router.getId());
-                params.put("ctxStartEventId", "1");
-                final AsyncJobVO job = new AsyncJobVO("", User.UID_SYSTEM, router.getAccountId(), RebootRouterCmd.class.getName(), ApiGsonHelper.getBuilder().create().toJson(params),
-                        router.getId(), cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null, null);
-                job.setDispatcher(_asyncDispatcher.getName());
-                final long jobId = _asyncMgr.submitAsyncJob(job);
-                jobIds.add(jobId);
-            } else {
-                s_logger.debug("Router: " + router.getId() + " is already at the latest version. No upgrade required");
-            }
-        }
-        return jobIds;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return VirtualNetworkApplianceManagerImpl.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] { UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor, RouterAlertsCheckInterval };
-    }
-
-    @Override
-    public boolean preStateTransitionEvent(final VirtualMachine.State oldState, final VirtualMachine.Event event, final VirtualMachine.State newState, final VirtualMachine vo, final boolean status,
-            final Object opaque) {
-        return true;
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(final StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, final VirtualMachine vo, final boolean status, final Object opaque) {
-        final VirtualMachine.State newState = transition.getToState();
-        final VirtualMachine.Event event = transition.getEvent();
-        if (vo.getType() == VirtualMachine.Type.DomainRouter &&
-                event == VirtualMachine.Event.FollowAgentPowerOnReport &&
-                newState == VirtualMachine.State.Running &&
-                isOutOfBandMigrated(opaque)) {
-            s_logger.debug("Virtual router " + vo.getInstanceName() + " is powered-on out-of-band");
-        }
-
-        return true;
-    }
-
-    private boolean isOutOfBandMigrated(final Object opaque) {
-        // opaque -> <hostId, powerHostId>
-        if (opaque != null && opaque instanceof Pair<?, ?>) {
-            final Pair<?, ?> pair = (Pair<?, ?>)opaque;
-            final Object first = pair.first();
-            final Object second = pair.second();
-            // powerHostId cannot be null in case of out-of-band VM movement
-            if (second != null && second instanceof Long) {
-                final Long powerHostId = (Long)second;
-                Long hostId = null;
-                if (first != null && first instanceof Long) {
-                    hostId = (Long)first;
-                }
-                // The following scenarios are due to out-of-band VM movement
-                // 1. If VM is in stopped state in CS due to 'PowerMissing' report from old host (hostId is null) and then there is a 'PowerOn' report from new host
-                // 2. If VM is in running state in CS and there is a 'PowerOn' report from new host
-                if (hostId == null || hostId.longValue() != powerHostId.longValue()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    protected boolean aggregationExecution(final AggregationControlCommand.Action action, final Network network, final List<DomainRouterVO> routers)
-            throws AgentUnavailableException, ResourceUnavailableException {
-
-        int errors = 0;
-
-        for (final DomainRouterVO router : routers) {
-
-            final String routerControlIp = _routerControlHelper.getRouterControlIp(router.getId());
-            final String routerIpInNetwork = _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId());
-
-            if (routerIpInNetwork == null) {
-                // Nic hasn't been created in this router yet. Try to configure the next one.
-                s_logger.warn("The Network is not configured in the router " + router.getHostName() + " yet. Try the next router!");
-                errors++;
-                continue;
-            }
-
-            final AggregationControlCommand cmd = new AggregationControlCommand(action, router.getInstanceName(), routerControlIp, routerIpInNetwork);
-            final Commands cmds = new Commands(cmd);
-            if (!_nwHelper.sendCommandsToRouter(router, cmds)) {
-                return false;
-            }
-        }
-        if (errors == routers.size()) {
-            s_logger.error("aggregationExecution() on " + getClass().getName() + " failed! Network is not configured in any router.");
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean prepareAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException, ResourceUnavailableException {
-        return aggregationExecution(Action.Start, network, routers);
-    }
-
-    @Override
-    public boolean completeAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException, ResourceUnavailableException {
-        return aggregationExecution(Action.Finish, network, routers);
-    }
-}
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
deleted file mode 100644
index fefd972..0000000
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ /dev/null
@@ -1,784 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.router;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.Command.OnError;
-import com.cloud.agent.api.NetworkUsageCommand;
-import com.cloud.agent.api.PlugNicCommand;
-import com.cloud.agent.api.SetupGuestNetworkCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand;
-import com.cloud.agent.api.routing.AggregationControlCommand.Action;
-import com.cloud.agent.manager.Commands;
-import com.cloud.dc.DataCenter;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.VirtualRouterProvider;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.RemoteAccessVpnVO;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.network.vpc.NetworkACLManager;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.PrivateIpAddress;
-import com.cloud.network.vpc.PrivateIpVO;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.StaticRouteProfile;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcGateway;
-import com.cloud.network.vpc.VpcGatewayVO;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.network.vpc.dao.StaticRouteDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-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;
-
-@Component
-public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager {
-    private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
-
-    @Inject
-    private NetworkACLManager _networkACLMgr;
-    @Inject
-    private VMInstanceDao _vmDao;
-    @Inject
-    private StaticRouteDao _staticRouteDao;
-    @Inject
-    private VpcManager _vpcMgr;
-    @Inject
-    private PrivateIpDao _privateIpDao;
-    @Inject
-    private Site2SiteVpnManager _s2sVpnMgr;
-    @Inject
-    private VpcGatewayDao _vpcGatewayDao;
-    @Inject
-    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 {
-        _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this);
-        return super.configure(name, params);
-    }
-
-    @Override
-    public boolean addVpcRouterToGuestNetwork(final VirtualRouter router, final Network network, final Map<VirtualMachineProfile.Param, Object> params)
-            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
-            return false;
-        }
-
-        // Add router to the Guest network
-        boolean result = true;
-        try {
-
-            // 1) add nic to the router
-            _routerDao.addRouterToGuestNetwork(router, network);
-
-            final NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null);
-            // 2) setup guest network
-            if (guestNic != null) {
-                result = setupVpcGuestNetwork(network, router, true, guestNic);
-            } else {
-                s_logger.warn("Failed to add router " + router + " to guest network " + network);
-                result = false;
-            }
-            // 3) apply networking rules
-            if (result && params.get(Param.ReProgramGuestNetworks) != null && (Boolean) params.get(Param.ReProgramGuestNetworks) == true) {
-                sendNetworkRulesToRouter(router.getId(), network.getId());
-            }
-        } catch (final Exception ex) {
-            s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex);
-            result = false;
-        } finally {
-            if (!result) {
-                s_logger.debug("Removing the router " + router + " from network " + network + " as a part of cleanup");
-                if (removeVpcRouterFromGuestNetwork(router, network)) {
-                    s_logger.debug("Removed the router " + router + " from network " + network + " as a part of cleanup");
-                } else {
-                    s_logger.warn("Failed to remove the router " + router + " from network " + network + " as a part of cleanup");
-                }
-            } else {
-                s_logger.debug("Succesfully added router " + router + " to guest network " + network);
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public boolean removeVpcRouterFromGuestNetwork(final VirtualRouter router, final Network network) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        if (network.getTrafficType() != TrafficType.Guest) {
-            s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
-            return false;
-        }
-
-        boolean result = true;
-        try {
-            // Check if router is a part of the Guest network
-            if (!_networkModel.isVmPartOfNetwork(router.getId(), network.getId())) {
-                s_logger.debug("Router " + router + " is not a part of the Guest network " + network);
-                return result;
-            }
-
-            result = setupVpcGuestNetwork(network, router, false, _networkModel.getNicProfile(router, network.getId(), null));
-            if (!result) {
-                s_logger.warn("Failed to destroy guest network config " + network + " on router " + router);
-                return false;
-            }
-
-            result = result && _itMgr.removeVmFromNetwork(router, network, null);
-        } finally {
-            if (result) {
-                _routerDao.removeRouterFromGuestNetwork(router.getId(), network.getId());
-            }
-        }
-
-        return result;
-    }
-
-    protected boolean setupVpcGuestNetwork(final Network network, final VirtualRouter router, final boolean add, final NicProfile guestNic) throws ConcurrentOperationException,
-    ResourceUnavailableException {
-
-        boolean result = true;
-        if (router.getState() == State.Running) {
-            final SetupGuestNetworkCommand setupCmd = _commandSetupHelper.createSetupGuestNetworkCommand((DomainRouterVO) router, add, guestNic);
-
-            final Commands cmds = new Commands(Command.OnError.Stop);
-            cmds.addCommand("setupguestnetwork", setupCmd);
-            _nwHelper.sendCommandsToRouter(router, cmds);
-
-            final Answer setupAnswer = cmds.getAnswer("setupguestnetwork");
-            final String setup = add ? "set" : "destroy";
-            if (!(setupAnswer != null && setupAnswer.getResult())) {
-                s_logger.warn("Unable to " + setup + " guest network on router " + router);
-                result = false;
-            }
-            return result;
-        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
-            s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending setup guest network command to the backend");
-            return true;
-        } else {
-            s_logger.warn("Unable to setup guest network on virtual router " + router + " is not in the right state " + router.getState());
-            throw new ResourceUnavailableException("Unable to setup guest network on the backend," + " virtual router " + router + " is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) {
-        final DomainRouterVO domainRouterVO = _routerDao.findById(profile.getId());
-
-        final Long vpcId = domainRouterVO.getVpcId();
-
-        if (vpcId != null) {
-            if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
-                String defaultDns1 = null;
-                String defaultDns2 = null;
-                // remove public and guest nics as we will plug them later
-                final Iterator<NicProfile> it = profile.getNics().iterator();
-                while (it.hasNext()) {
-                    final NicProfile nic = it.next();
-                    if (nic.getTrafficType() == TrafficType.Public || nic.getTrafficType() == TrafficType.Guest) {
-                        // save dns information
-                        if (nic.getTrafficType() == TrafficType.Public) {
-                            defaultDns1 = nic.getIPv4Dns1();
-                            defaultDns2 = nic.getIPv4Dns2();
-                        }
-                        s_logger.debug("Removing nic " + nic + " of type " + nic.getTrafficType() + " from the nics passed on vm start. " + "The nic will be plugged later");
-                        it.remove();
-                    }
-                }
-
-                // add vpc cidr/dns/networkdomain to the boot load args
-                final StringBuilder buf = profile.getBootArgsBuilder();
-                final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
-                buf.append(" vpccidr=" + vpc.getCidr() + " domain=" + vpc.getNetworkDomain());
-
-                buf.append(" dns1=").append(defaultDns1);
-                if (defaultDns2 != null) {
-                    buf.append(" dns2=").append(defaultDns2);
-                }
-
-                VpcGatewayVO privateGatewayForVpc = _vpcGatewayDao.getPrivateGatewayForVpc(domainRouterVO.getVpcId());
-                if (privateGatewayForVpc != null) {
-                    String ip4Address = privateGatewayForVpc.getIp4Address();
-                    buf.append(" privategateway=").append(ip4Address);
-                    s_logger.debug("Set privategateway field in cmd_line.json to " + ip4Address);
-                } else {
-                    buf.append(" privategateway=None");
-                }
-            }
-        }
-
-        return super.finalizeVirtualMachineProfile(profile, dest, context);
-    }
-
-    @Override
-    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);
-        }
-
-        if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
-            // 1) FORM SSH CHECK COMMAND
-            final NicProfile controlNic = getControlNic(profile);
-            if (controlNic == null) {
-                s_logger.error("Control network doesn't exist for the router " + domainRouterVO);
-                return false;
-            }
-
-            finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, domainRouterVO, controlNic);
-
-            // 2) FORM PLUG NIC COMMANDS
-            final List<Pair<Nic, Network>> guestNics = new ArrayList<Pair<Nic, Network>>();
-            final List<Pair<Nic, Network>> publicNics = new ArrayList<Pair<Nic, Network>>();
-            final Map<String, String> vlanMacAddress = new HashMap<String, String>();
-
-            final List<? extends Nic> routerNics = _nicDao.listByVmIdOrderByDeviceId(profile.getId());
-            for (final Nic routerNic : routerNics) {
-                final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
-                if (network.getTrafficType() == TrafficType.Guest) {
-                    final Pair<Nic, Network> guestNic = new Pair<Nic, Network>(routerNic, network);
-                    guestNics.add(guestNic);
-                } else if (network.getTrafficType() == TrafficType.Public) {
-                    final Pair<Nic, Network> publicNic = new Pair<Nic, Network>(routerNic, network);
-                    publicNics.add(publicNic);
-                    final String vlanTag = BroadcastDomainType.getValue(routerNic.getBroadcastUri());
-                    vlanMacAddress.put(vlanTag, routerNic.getMacAddress());
-                }
-            }
-
-            final List<Command> usageCmds = new ArrayList<Command>();
-
-            // 3) PREPARE PLUG NIC COMMANDS
-            try {
-                // add VPC router to public networks
-                final List<PublicIp> sourceNat = new ArrayList<PublicIp>(1);
-                for (final Pair<Nic, Network> nicNtwk : publicNics) {
-                    final Nic publicNic = nicNtwk.first();
-                    final Network publicNtwk = nicNtwk.second();
-                    final IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), publicNic.getIPv4Address());
-
-                    if (userIp.isSourceNat()) {
-                        final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
-                        sourceNat.add(publicIp);
-
-                        if (domainRouterVO.getPublicIpAddress() == null) {
-                            final DomainRouterVO routerVO = _routerDao.findById(domainRouterVO.getId());
-                            routerVO.setPublicIpAddress(publicNic.getIPv4Address());
-                            routerVO.setPublicNetmask(publicNic.getIPv4Netmask());
-                            routerVO.setPublicMacAddress(publicNic.getMacAddress());
-                            _routerDao.update(routerVO.getId(), routerVO);
-                        }
-                    }
-                    final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, publicNic.getNetworkId(), publicNic.getBroadcastUri().toString()),
-                            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());
-                    usageCmds.add(netUsageCmd);
-                    UserStatisticsVO stats = _userStatsDao.findBy(domainRouterVO.getAccountId(), domainRouterVO.getDataCenterId(), publicNtwk.getId(), publicNic.getIPv4Address(), domainRouterVO.getId(),
-                            domainRouterVO.getType().toString());
-                    if (stats == null) {
-                        stats = new UserStatisticsVO(domainRouterVO.getAccountId(), domainRouterVO.getDataCenterId(), publicNic.getIPv4Address(), domainRouterVO.getId(), domainRouterVO.getType().toString(),
-                                publicNtwk.getId());
-                        _userStatsDao.persist(stats);
-                    }
-                }
-
-                // create ip assoc for source nat
-                if (!sourceNat.isEmpty()) {
-                    _commandSetupHelper.createVpcAssociatePublicIPCommands(domainRouterVO, sourceNat, cmds, vlanMacAddress);
-                }
-
-                // add VPC router to guest networks
-                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(), details);
-                    cmds.addCommand(plugNicCmd);
-                    if (!_networkModel.isPrivateGateway(guestNic.getNetworkId())) {
-                        // set guest network
-                        final VirtualMachine vm = _vmDao.findById(domainRouterVO.getId());
-                        final NicProfile nicProfile = _networkModel.getNicProfile(vm, guestNic.getNetworkId(), null);
-                        final SetupGuestNetworkCommand setupCmd = _commandSetupHelper.createSetupGuestNetworkCommand(domainRouterVO, true, nicProfile);
-                        cmds.addCommand(setupCmd);
-                    } else {
-
-                        // set private network
-                        final PrivateIpVO ipVO = _privateIpDao.findByIpAndSourceNetworkId(guestNic.getNetworkId(), guestNic.getIPv4Address());
-                        final Network network = _networkDao.findById(guestNic.getNetworkId());
-                        BroadcastDomainType.getValue(network.getBroadcastUri());
-                        final String netmask = NetUtils.getCidrNetmask(network.getCidr());
-                        final PrivateIpAddress ip = new PrivateIpAddress(ipVO, network.getBroadcastUri().toString(), network.getGateway(), netmask, guestNic.getMacAddress());
-
-                        final List<PrivateIpAddress> privateIps = new ArrayList<PrivateIpAddress>(1);
-                        privateIps.add(ip);
-                        _commandSetupHelper.createVpcAssociatePrivateIPCommands(domainRouterVO, privateIps, cmds, true);
-
-                        final Long privateGwAclId = _vpcGatewayDao.getNetworkAclIdForPrivateIp(ipVO.getVpcId(), ipVO.getNetworkId(), ipVO.getIpAddress());
-
-                        if (privateGwAclId != null) {
-                            // set network acl on private gateway
-                            final List<NetworkACLItemVO> networkACLs = _networkACLItemDao.listByACL(privateGwAclId);
-                            s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + domainRouterVO + " start for private gateway ip = "
-                                    + ipVO.getIpAddress());
-
-                            _commandSetupHelper.createNetworkACLsCommands(networkACLs, domainRouterVO, cmds, ipVO.getNetworkId(), true);
-                        }
-                    }
-                }
-            } catch (final Exception ex) {
-                s_logger.warn("Failed to add router " + domainRouterVO + " to network due to exception ", ex);
-                return false;
-            }
-
-            // 4) RE-APPLY ALL STATIC ROUTE RULES
-            final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(domainRouterVO.getVpcId());
-            final List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
-            final Map<Long, VpcGateway> gatewayMap = new HashMap<Long, VpcGateway>();
-            for (final StaticRoute route : routes) {
-                VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId());
-                if (gateway == null) {
-                    gateway = _entityMgr.findById(VpcGateway.class, route.getVpcGatewayId());
-                    gatewayMap.put(gateway.getId(), gateway);
-                }
-                staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
-            }
-
-            s_logger.debug("Found " + staticRouteProfiles.size() + " static routes to apply as a part of vpc route " + domainRouterVO + " start");
-            if (!staticRouteProfiles.isEmpty()) {
-                _commandSetupHelper.createStaticRouteCommands(staticRouteProfiles, domainRouterVO, cmds);
-            }
-
-            // 5) RE-APPLY ALL REMOTE ACCESS VPNs
-            final RemoteAccessVpnVO vpn = _vpnDao.findByAccountAndVpc(domainRouterVO.getAccountId(), domainRouterVO.getVpcId());
-            if (vpn != null) {
-                _commandSetupHelper.createApplyVpnCommands(true, vpn, domainRouterVO, cmds);
-            }
-
-            // 6) REPROGRAM GUEST NETWORK
-            boolean reprogramGuestNtwks = true;
-            if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
-                reprogramGuestNtwks = false;
-            }
-
-            final VirtualRouterProvider vrProvider = _vrProviderDao.findById(domainRouterVO.getElementId());
-            if (vrProvider == null) {
-                throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + domainRouterVO.getHostName());
-            }
-            final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
-            if (provider == null) {
-                throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
-            }
-
-            for (final Pair<Nic, Network> nicNtwk : guestNics) {
-                final Nic guestNic = nicNtwk.first();
-                final AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, domainRouterVO.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
-                        guestNic.getNetworkId(), domainRouterVO.getId()));
-                cmds.addCommand(startCmd);
-                if (reprogramGuestNtwks) {
-                    finalizeIpAssocForNetwork(cmds, domainRouterVO, provider, guestNic.getNetworkId(), vlanMacAddress);
-                    finalizeNetworkRulesForNetwork(cmds, domainRouterVO, provider, guestNic.getNetworkId());
-                }
-
-                finalizeUserDataAndDhcpOnStart(cmds, domainRouterVO, provider, guestNic.getNetworkId());
-                final AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, domainRouterVO.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
-                        guestNic.getNetworkId(), domainRouterVO.getId()));
-                cmds.addCommand(finishCmd);
-            }
-
-            // Add network usage commands
-            cmds.addCommands(usageCmds);
-        }
-        return true;
-    }
-
-    @Override
-    protected void finalizeNetworkRulesForNetwork(final Commands cmds, final DomainRouterVO domainRouterVO, final Provider provider, final Long guestNetworkId) {
-
-        super.finalizeNetworkRulesForNetwork(cmds, domainRouterVO, provider, guestNetworkId);
-
-        if (domainRouterVO.getVpcId() != null) {
-
-            if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
-                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.NetworkACL, Provider.VPCVirtualRouter)) {
-                    final List<NetworkACLItemVO> networkACLs = _networkACLMgr.listNetworkACLItems(guestNetworkId);
-                    if (networkACLs != null && !networkACLs.isEmpty()) {
-                        s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + domainRouterVO + " start for guest network id=" + guestNetworkId);
-                        _commandSetupHelper.createNetworkACLsCommands(networkACLs, domainRouterVO, cmds, guestNetworkId, false);
-                    }
-                }
-            }
-        }
-    }
-
-    protected boolean sendNetworkRulesToRouter(final long routerId, final long networkId) throws ResourceUnavailableException {
-        final DomainRouterVO router = _routerDao.findById(routerId);
-        final Commands cmds = new Commands(OnError.Continue);
-
-        final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
-        if (vrProvider == null) {
-            throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
-        }
-        final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
-        if (provider == null) {
-            throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
-        }
-
-        finalizeNetworkRulesForNetwork(cmds, router, provider, networkId);
-        return _nwHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    /**
-     * @param router
-     * @param add
-     * @param privateNic
-     * @return
-     * @throws ResourceUnavailableException
-     */
-    protected boolean setupVpcPrivateNetwork(final VirtualRouter router, final boolean add, final NicProfile privateNic) throws ResourceUnavailableException {
-
-        if (router.getState() == State.Running) {
-            final PrivateIpVO ipVO = _privateIpDao.findByIpAndSourceNetworkId(privateNic.getNetworkId(), privateNic.getIPv4Address());
-            final Network network = _networkDao.findById(privateNic.getNetworkId());
-            final String netmask = NetUtils.getCidrNetmask(network.getCidr());
-            final PrivateIpAddress ip = new PrivateIpAddress(ipVO, network.getBroadcastUri().toString(), network.getGateway(), netmask, privateNic.getMacAddress());
-
-            final List<PrivateIpAddress> privateIps = new ArrayList<PrivateIpAddress>(1);
-            privateIps.add(ip);
-            final Commands cmds = new Commands(Command.OnError.Stop);
-            _commandSetupHelper.createVpcAssociatePrivateIPCommands(router, privateIps, cmds, add);
-
-            try {
-                if (_nwHelper.sendCommandsToRouter(router, cmds)) {
-                    s_logger.debug("Successfully applied ip association for ip " + ip + " in vpc network " + network);
-                    return true;
-                } else {
-                    s_logger.warn("Failed to associate ip address " + ip + " in vpc network " + network);
-                    return false;
-                }
-            } catch (final Exception ex) {
-                s_logger.warn("Failed to send  " + (add ? "add " : "delete ") + " private network " + network + " commands to rotuer ");
-                return false;
-            }
-        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
-            s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending setup private network command to the backend");
-        } else {
-            s_logger.warn("Unable to setup private gateway, virtual router " + router + " is not in the right state " + router.getState());
-
-            throw new ResourceUnavailableException("Unable to setup Private gateway on the backend," + " virtual router " + router + " is not in the right state",
-                    DataCenter.class, router.getDataCenterId());
-        }
-        return true;
-    }
-
-    @Override
-    public boolean destroyPrivateGateway(final PrivateGateway gateway, final VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
-        boolean result = true;
-
-        if (!_networkModel.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) {
-            s_logger.debug("Router doesn't have nic for gateway " + gateway + " so no need to removed it");
-            return result;
-        }
-
-        final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());
-        final NicProfile nicProfile = _networkModel.getNicProfile(router, privateNetwork.getId(), null);
-
-        s_logger.debug("Releasing private ip for gateway " + gateway + " from " + router);
-        result = setupVpcPrivateNetwork(router, false, nicProfile);
-        if (!result) {
-            s_logger.warn("Failed to release private ip for gateway " + gateway + " on router " + router);
-            return false;
-        }
-
-        // revoke network acl on the private gateway.
-        if (!_networkACLMgr.revokeACLItemsForPrivateGw(gateway)) {
-            s_logger.debug("Failed to delete network acl items on " + gateway + " from router " + router);
-            return false;
-        }
-
-        s_logger.debug("Removing router " + router + " from private network " + privateNetwork + " as a part of delete private gateway");
-        result = result && _itMgr.removeVmFromNetwork(router, privateNetwork, null);
-        s_logger.debug("Private gateawy " + gateway + " is removed from router " + router);
-        return result;
-    }
-
-    @Override
-    protected void finalizeIpAssocForNetwork(final Commands cmds, final VirtualRouter domainRouterVO, final Provider provider, final Long guestNetworkId,
-            final Map<String, String> vlanMacAddress) {
-
-        if (domainRouterVO.getVpcId() == null) {
-            super.finalizeIpAssocForNetwork(cmds, domainRouterVO, provider, guestNetworkId, vlanMacAddress);
-            return;
-        }
-
-        if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
-            final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(domainRouterVO, provider, guestNetworkId, IpAddress.State.Releasing);
-
-            if (publicIps != null && !publicIps.isEmpty()) {
-                s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + domainRouterVO + " start.");
-                // Re-apply public ip addresses - should come before PF/LB/VPN
-                _commandSetupHelper.createVpcAssociatePublicIPCommands(domainRouterVO, publicIps, cmds, vlanMacAddress);
-            }
-        }
-    }
-
-    @Override
-    public boolean startSite2SiteVpn(final Site2SiteVpnConnection conn, final VirtualRouter router) throws ResourceUnavailableException {
-        if (router.getState() != State.Running) {
-            s_logger.warn("Unable to apply site-to-site VPN configuration, virtual router is not in the right state " + router.getState());
-            throw new ResourceUnavailableException("Unable to apply site 2 site VPN configuration," + " virtual router is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-
-        return applySite2SiteVpn(true, router, conn);
-    }
-
-    @Override
-    public boolean stopSite2SiteVpn(final Site2SiteVpnConnection conn, final VirtualRouter router) throws ResourceUnavailableException {
-        if (router.getState() != State.Running) {
-            s_logger.warn("Unable to apply site-to-site VPN configuration, virtual router is not in the right state " + router.getState());
-            throw new ResourceUnavailableException("Unable to apply site 2 site VPN configuration," + " virtual router is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-
-        return applySite2SiteVpn(false, router, conn);
-    }
-
-    protected boolean applySite2SiteVpn(final boolean isCreate, final VirtualRouter router, final Site2SiteVpnConnection conn) throws ResourceUnavailableException {
-        final Commands cmds = new Commands(Command.OnError.Continue);
-        _commandSetupHelper.createSite2SiteVpnCfgCommands(conn, isCreate, router, cmds);
-        return _nwHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    protected Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> getNicsToChangeOnRouter(final List<? extends PublicIpAddress> publicIps, final VirtualRouter router) {
-        // 1) check which nics need to be plugged/unplugged and plug/unplug them
-
-        final Map<String, PublicIpAddress> nicsToPlug = new HashMap<String, PublicIpAddress>();
-        final Map<String, PublicIpAddress> nicsToUnplug = new HashMap<String, PublicIpAddress>();
-
-        // find out nics to unplug
-        for (final PublicIpAddress ip : publicIps) {
-            final long publicNtwkId = ip.getNetworkId();
-
-            // if ip is not associated to any network, and there are no firewall
-            // rules, release it on the backend
-            if (!_vpcMgr.isIpAllocatedToVpc(ip)) {
-                ip.setState(IpAddress.State.Releasing);
-            }
-
-            if (ip.getState() == IpAddress.State.Releasing) {
-                final Nic nic = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), ip.getAddress().addr());
-                if (nic != null) {
-                    nicsToUnplug.put(ip.getVlanTag(), ip);
-                    s_logger.debug("Need to unplug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId);
-                }
-            }
-        }
-
-        // find out nics to plug
-        for (final PublicIpAddress ip : publicIps) {
-            final URI broadcastUri = BroadcastDomainType.Vlan.toUri(ip.getVlanTag());
-            final long publicNtwkId = ip.getNetworkId();
-
-            // if ip is not associated to any network, and there are no firewall
-            // rules, release it on the backend
-            if (!_vpcMgr.isIpAllocatedToVpc(ip)) {
-                ip.setState(IpAddress.State.Releasing);
-            }
-
-            if (ip.getState() == IpAddress.State.Allocated || ip.getState() == IpAddress.State.Allocating) {
-                // nic has to be plugged only when there are no nics for this
-                // vlan tag exist on VR
-                final Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(publicNtwkId, router.getId(), broadcastUri.toString());
-
-                if (nic == null && nicsToPlug.get(ip.getVlanTag()) == null) {
-                    nicsToPlug.put(ip.getVlanTag(), ip);
-                    s_logger.debug("Need to plug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId);
-                } else {
-                    final PublicIpAddress nicToUnplug = nicsToUnplug.get(ip.getVlanTag());
-                    if (nicToUnplug != null) {
-                        final NicVO nicVO = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), nicToUnplug.getAddress().addr());
-                        nicVO.setIPv4Address(ip.getAddress().addr());
-                        _nicDao.update(nicVO.getId(), nicVO);
-                        s_logger.debug("Updated the nic " + nicVO + " with the new ip address " + ip.getAddress().addr());
-                        nicsToUnplug.remove(ip.getVlanTag());
-                    }
-                }
-            }
-        }
-
-        final Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> nicsToChange = new Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>>(nicsToPlug,
-                nicsToUnplug);
-        return nicsToChange;
-    }
-
-    @Override
-    public void finalizeStop(final VirtualMachineProfile profile, final Answer answer) {
-        super.finalizeStop(profile, answer);
-        // Mark VPN connections as Disconnected
-        final DomainRouterVO router = _routerDao.findById(profile.getId());
-        final Long vpcId = router.getVpcId();
-        if (vpcId != null) {
-            _s2sVpnMgr.markDisconnectVpnConnByVpc(vpcId);
-        }
-    }
-
-    @Override
-    public List<DomainRouterVO> getVpcRouters(final long vpcId) {
-        return _routerDao.listByVpcId(vpcId);
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public boolean startRemoteAccessVpn(final RemoteAccessVpn vpn, final VirtualRouter router) throws ResourceUnavailableException {
-        if (router.getState() != State.Running) {
-            s_logger.warn("Unable to apply remote access VPN configuration, virtual router is not in the right state " + router.getState());
-            throw new ResourceUnavailableException("Unable to apply remote access VPN configuration," + " virtual router is not in the right state", DataCenter.class,
-                    router.getDataCenterId());
-        }
-
-        final Commands cmds = new Commands(Command.OnError.Stop);
-        _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
-
-        try {
-            _agentMgr.send(router.getHostId(), cmds);
-        } catch (final OperationTimedoutException e) {
-            s_logger.debug("Failed to start remote access VPN: ", e);
-            throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
-        }
-        Answer answer = cmds.getAnswer("users");
-        if (!answer.getResult()) {
-            s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
-                    + router.getInstanceName() + " due to " + answer.getDetails());
-            throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
-            + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
-        }
-        answer = cmds.getAnswer("startVpn");
-        if (!answer.getResult()) {
-            s_logger.error("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to "
-                    + answer.getDetails());
-            throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
-                    + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stopRemoteAccessVpn(final RemoteAccessVpn vpn, final VirtualRouter router) throws ResourceUnavailableException {
-        boolean result = true;
-
-        if (router.getState() == State.Running) {
-            final Commands cmds = new Commands(Command.OnError.Continue);
-            _commandSetupHelper.createApplyVpnCommands(false, vpn, router, cmds);
-            result = result && _nwHelper.sendCommandsToRouter(router, cmds);
-        } else if (router.getState() == State.Stopped) {
-            s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it");
-        } else {
-            s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState());
-            throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class,
-                    router.getDataCenterId());
-        }
-        return true;
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(final StateMachine2.Transition<State, VirtualMachine.Event> transition, final VirtualMachine vo, final boolean status, final Object opaque) {
-        // Without this VirtualNetworkApplianceManagerImpl.postStateTransitionEvent() gets called twice as part of listeners -
-        // once from VpcVirtualNetworkApplianceManagerImpl and once from VirtualNetworkApplianceManagerImpl itself
-        return true;
-    }
-}
diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java
deleted file mode 100644
index 37a9ad9..0000000
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ /dev/null
@@ -1,1630 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.rules;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.FirewallRulesCidrsDao;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.LoadBalancerVMMapVO;
-import com.cloud.network.rules.FirewallRule.FirewallRuleType;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRule.State;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcService;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicSecondaryIpDao;
-import com.cloud.vm.dao.NicSecondaryIpVO;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class RulesManagerImpl extends ManagerBase implements RulesManager, RulesService {
-    private static final Logger s_logger = Logger.getLogger(RulesManagerImpl.class);
-
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    PortForwardingRulesDao _portForwardingDao;
-    @Inject
-    FirewallRulesCidrsDao _firewallCidrsDao;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    UserVmDao _vmDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkOrchestrationService _networkMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    EventDao _eventDao;
-    @Inject
-    UsageEventDao _usageEventDao;
-    @Inject
-    DomainDao _domainDao;
-    @Inject
-    FirewallManager _firewallMgr;
-    @Inject
-    DomainManager _domainMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    NicDao _nicDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    NicSecondaryIpDao _nicSecondaryDao;
-    @Inject
-    LoadBalancerVMMapDao _loadBalancerVMMapDao;
-    @Inject
-    VpcService _vpcSvc;
-
-    protected void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller, Boolean ignoreVmState) {
-        if (ipAddress == null || ipAddress.getAllocatedTime() == null || ipAddress.getAllocatedToAccountId() == null) {
-            throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified.");
-        }
-
-        if (userVm == null) {
-            return;
-        }
-
-        if (userVm.getState() == VirtualMachine.State.Destroyed || userVm.getState() == VirtualMachine.State.Expunging) {
-            if (!ignoreVmState) {
-                throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
-            }
-        }
-
-        _accountMgr.checkAccess(caller, null, true, ipAddress, userVm);
-
-        // validate that IP address and userVM belong to the same account
-        if (ipAddress.getAllocatedToAccountId().longValue() != userVm.getAccountId()) {
-            throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress +
-                " owner is not the same as owner of virtual machine " + userVm.toString());
-        }
-
-        // validate that userVM is in the same availability zone as the IP address
-        if (ipAddress.getDataCenterId() != userVm.getDataCenterId()) {
-            //make an exception for portable IP
-            if (!ipAddress.isPortable()) {
-                throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress +
-                    " is not in the same availability zone as virtual machine " + userVm.toString());
-            }
-        }
-
-    }
-
-    @Override
-    public void checkRuleAndUserVm(FirewallRule rule, UserVm userVm, Account caller) {
-        if (userVm == null || rule == null) {
-            return;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, rule, userVm);
-
-        if (userVm.getState() == VirtualMachine.State.Destroyed || userVm.getState() == VirtualMachine.State.Expunging) {
-            throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
-        }
-
-        // This same owner check is actually not needed, since multiple entities OperateEntry trick guarantee that
-        if (rule.getAccountId() != userVm.getAccountId()) {
-            throw new InvalidParameterValueException("New rule " + rule + " and vm id=" + userVm.getId() + " belong to different accounts");
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
-    public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule, final Long vmId, Ip vmIp, final boolean openFirewall, final Boolean forDisplay)
-            throws NetworkRuleConflictException {
-        CallContext ctx = CallContext.current();
-        final Account caller = ctx.getCallingAccount();
-
-        final Long ipAddrId = rule.getSourceIpAddressId();
-
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
-
-        // Validate ip address
-        if (ipAddress == null) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
-        } else if (ipAddress.isOneToOneNat()) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
-        }
-
-        final Long networkId = rule.getNetworkId();
-        Network network = _networkModel.getNetwork(networkId);
-        //associate ip address to network (if needed)
-        boolean performedIpAssoc = false;
-        Nic guestNic;
-        if (ipAddress.getAssociatedWithNetworkId() == null) {
-            boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
-            if (assignToVpcNtwk) {
-                _networkModel.checkIpForService(ipAddress, Service.PortForwarding, networkId);
-
-                s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
-                try {
-                    ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
-                    performedIpAssoc = true;
-                } catch (Exception ex) {
-                    throw new CloudRuntimeException("Failed to associate ip to VPC network as " + "a part of port forwarding rule creation");
-                }
-            }
-        } else {
-            _networkModel.checkIpForService(ipAddress, Service.PortForwarding, null);
-        }
-
-        if (ipAddress.getAssociatedWithNetworkId() == null) {
-            throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
-        }
-
-        try {
-            _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding,
-                FirewallRuleType.User, networkId, rule.getTrafficType());
-
-            final Long accountId = ipAddress.getAllocatedToAccountId();
-            final Long domainId = ipAddress.getAllocatedInDomainId();
-
-            // start port can't be bigger than end port
-            if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
-                throw new InvalidParameterValueException("Start port can't be bigger than end port");
-            }
-
-            // check that the port ranges are of equal size
-            if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
-                throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
-            }
-
-            // validate user VM exists
-            UserVm vm = _vmDao.findById(vmId);
-            if (vm == null) {
-                throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" +
-                    vmId + ").");
-            } else if (vm.getState() == VirtualMachine.State.Destroyed || vm.getState() == VirtualMachine.State.Expunging) {
-                throw new InvalidParameterValueException("Invalid user vm: " + vm.getId());
-            }
-
-            // Verify that vm has nic in the network
-            Ip dstIp = rule.getDestinationIpAddress();
-            guestNic = _networkModel.getNicInNetwork(vmId, networkId);
-            if (guestNic == null || guestNic.getIPv4Address() == null) {
-                throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
-            } else {
-                dstIp = new Ip(guestNic.getIPv4Address());
-            }
-
-            if (vmIp != null) {
-                //vm ip is passed so it can be primary or secondary ip addreess.
-                if (!dstIp.equals(vmIp)) {
-                    //the vm ip is secondary ip to the nic.
-                    // is vmIp is secondary ip or not
-                    NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmIp.toString(), guestNic.getId());
-                    if (secondaryIp == null) {
-                        throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
-                    }
-                    dstIp = vmIp;
-                }
-            }
-
-            //if start port and end port are passed in, and they are not equal to each other, perform the validation
-            boolean validatePortRange = false;
-            if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue() || rule.getDestinationPortStart() != rule.getDestinationPortEnd()) {
-                validatePortRange = true;
-            }
-
-            if (validatePortRange) {
-                //source start port and source dest port should be the same. The same applies to dest ports
-                if (rule.getSourcePortStart().intValue() != rule.getDestinationPortStart()) {
-                    throw new InvalidParameterValueException("Private port start should be equal to public port start");
-                }
-
-                if (rule.getSourcePortEnd().intValue() != rule.getDestinationPortEnd()) {
-                    throw new InvalidParameterValueException("Private port end should be equal to public port end");
-                }
-            }
-
-            final Ip dstIpFinal = dstIp;
-            final IPAddressVO ipAddressFinal = ipAddress;
-            return Transaction.execute(new TransactionCallbackWithException<PortForwardingRuleVO, NetworkRuleConflictException>() {
-                @Override
-                public PortForwardingRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
-                    PortForwardingRuleVO newRule =
-                        new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIpFinal,
-                            rule.getDestinationPortStart(), rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
-
-                    if (forDisplay != null) {
-                        newRule.setDisplay(forDisplay);
-                    }
-                    newRule = _portForwardingDao.persist(newRule);
-
-                    // create firewallRule for 0.0.0.0/0 cidr
-                    if (openFirewall) {
-                        _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null,
-                            newRule.getId(), networkId);
-                    }
-
-                    try {
-                        _firewallMgr.detectRulesConflict(newRule);
-                        if (!_firewallDao.setStateToAdd(newRule)) {
-                            throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
-                        }
-                        CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), ipAddressFinal.getDataCenterId(), newRule.getId(), null,
-                            PortForwardingRule.class.getName(), newRule.getUuid());
-                        return newRule;
-                    } catch (Exception e) {
-                        if (newRule != null) {
-                            // no need to apply the rule as it wasn't programmed on the backend yet
-                            _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                            removePFRule(newRule);
-                        }
-
-                        if (e instanceof NetworkRuleConflictException) {
-                            throw (NetworkRuleConflictException)e;
-                        }
-
-                        throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
-                    }
-                }
-            });
-
-        } finally {
-            // release ip address if ipassoc was perfored
-            if (performedIpAssoc) {
-                //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
-                IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
-                _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
-            }
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true)
-    public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean openFirewall) throws NetworkRuleConflictException {
-        final Account caller = CallContext.current().getCallingAccount();
-
-        final Long ipAddrId = rule.getSourceIpAddressId();
-
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
-
-        // Validate ip address
-        if (ipAddress == null) {
-            throw new InvalidParameterValueException("Unable to create static nat rule; ip id=" + ipAddrId + " doesn't exist in the system");
-        } else if (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getAssociatedWithVmId() == null) {
-            throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
-        }
-
-        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat,
-            FirewallRuleType.User, null, rule.getTrafficType());
-
-        final Long networkId = ipAddress.getAssociatedWithNetworkId();
-        final Long accountId = ipAddress.getAllocatedToAccountId();
-        final Long domainId = ipAddress.getAllocatedInDomainId();
-
-        _networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
-
-        Network network = _networkModel.getNetwork(networkId);
-        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-        if (off.getElasticIp()) {
-            throw new InvalidParameterValueException("Can't create ip forwarding rules for the network where elasticIP service is enabled");
-        }
-
-        //String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
-        final String dstIp = ipAddress.getVmIp();
-        return Transaction.execute(new TransactionCallbackWithException<StaticNatRule, NetworkRuleConflictException>() {
-            @Override
-            public StaticNatRule doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
-
-                FirewallRuleVO newRule =
-                    new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(),
-                        networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null);
-
-                newRule = _firewallDao.persist(newRule);
-
-                // create firewallRule for 0.0.0.0/0 cidr
-                if (openFirewall) {
-                    _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null,
-                        newRule.getId(), networkId);
-                }
-
-                try {
-                    _firewallMgr.detectRulesConflict(newRule);
-                    if (!_firewallDao.setStateToAdd(newRule)) {
-                        throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
-                    }
-                    CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null, FirewallRule.class.getName(),
-                        newRule.getUuid());
-
-                    StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp);
-
-                    return staticNatRule;
-                } catch (Exception e) {
-                    if (newRule != null) {
-                        // no need to apply the rule as it wasn't programmed on the backend yet
-                        _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
-                        _firewallMgr.removeRule(newRule);
-                    }
-
-                    if (e instanceof NetworkRuleConflictException) {
-                        throw (NetworkRuleConflictException)e;
-                    }
-                    throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e);
-                }
-            }
-        });
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ENABLE_STATIC_NAT, eventDescription = "enabling static nat")
-    public boolean enableStaticNat(long ipId, long vmId, long networkId, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException {
-        return enableStaticNat(ipId, vmId, networkId, false, vmGuestIp);
-    }
-
-    private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp) throws NetworkRuleConflictException,
-        ResourceUnavailableException {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-        CallContext.current().setEventDetails("Ip Id: " + ipId);
-
-        // Verify input parameters
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
-        if (ipAddress == null) {
-            throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
-        }
-
-        // Verify input parameters
-        boolean performedIpAssoc = false;
-        boolean isOneToOneNat = ipAddress.isOneToOneNat();
-        Long associatedWithVmId = ipAddress.getAssociatedWithVmId();
-        Nic guestNic;
-        NicSecondaryIpVO nicSecIp = null;
-        String dstIp = null;
-
-        try {
-            Network network = _networkModel.getNetwork(networkId);
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find network by id");
-            }
-
-            // Check that vm has a nic in the network
-            guestNic = _networkModel.getNicInNetwork(vmId, networkId);
-            if (guestNic == null) {
-                throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
-            }
-            dstIp = guestNic.getIPv4Address();
-
-            if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
-                throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " + "supported in network with specified id");
-            }
-
-            if (!isSystemVm) {
-                UserVmVO vm = _vmDao.findById(vmId);
-                if (vm == null) {
-                    throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + ", invalid virtual machine id specified (" + vmId +
-                        ").");
-                }
-                //associate ip address to network (if needed)
-                if (ipAddress.getAssociatedWithNetworkId() == null) {
-                    boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
-                    if (assignToVpcNtwk) {
-                        _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
-
-                        s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
-                        try {
-                            ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, false);
-                        } catch (Exception ex) {
-                            s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " + "a part of enable static nat");
-                            return false;
-                        }
-                    }  else if (ipAddress.isPortable()) {
-                        s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network yet " + " so associate IP with the network " +
-                            networkId);
-                        try {
-                            // check if StaticNat service is enabled in the network
-                            _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
-
-                            // associate portable IP to vpc, if network is part of VPC
-                            if (network.getVpcId() != null) {
-                                _vpcSvc.associateIPToVpc(ipId, network.getVpcId());
-                            }
-
-                            // associate portable IP with guest network
-                            ipAddress = _ipAddrMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
-                        } catch (Exception e) {
-                            s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + "a part of enable static nat");
-                            return false;
-                        }
-                    }
-                } else  if (ipAddress.getAssociatedWithNetworkId() != networkId) {
-                    if (ipAddress.isPortable()) {
-                        // check if destination network has StaticNat service enabled
-                        _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
-
-                        // check if portable IP can be transferred across the networks
-                        if (_ipAddrMgr.isPortableIpTransferableFromNetwork(ipId, ipAddress.getAssociatedWithNetworkId())) {
-                            try {
-                                // transfer the portable IP and refresh IP details
-                                _ipAddrMgr.transferPortableIP(ipId, ipAddress.getAssociatedWithNetworkId(), networkId);
-                                ipAddress = _ipAddressDao.findById(ipId);
-                            } catch (Exception e) {
-                                s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + "a part of enable static nat");
-                                return false;
-                            }
-                        } else {
-                            throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services " + "in network " +
-                                ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " + " network " + networkId);
-                        }
-                    } else {
-                        throw new InvalidParameterValueException("Invalid network Id=" + networkId + ". IP is associated with" +
-                            " a different network than passed network id");
-                    }
-                } else {
-                    _networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
-                }
-
-                if (ipAddress.getAssociatedWithNetworkId() == null) {
-                    throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
-                }
-
-                // Check permissions
-                if (ipAddress.getSystem()) {
-                    // when system is enabling static NAT on system IP's (for EIP) ignore VM state
-                    checkIpAndUserVm(ipAddress, vm, caller, true);
-                } else {
-                    checkIpAndUserVm(ipAddress, vm, caller, false);
-                }
-
-                //is static nat is for vm secondary ip
-                //dstIp = guestNic.getIp4Address();
-                if (vmGuestIp != null) {
-                    //dstIp = guestNic.getIp4Address();
-
-                    if (!dstIp.equals(vmGuestIp)) {
-                        //check whether the secondary ip set to the vm or not
-                        boolean secondaryIpSet = _networkMgr.isSecondaryIpSetForNic(guestNic.getId());
-                        if (!secondaryIpSet) {
-                            throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
-                        }
-                        //check the ip belongs to the vm or not
-                        nicSecIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmGuestIp, guestNic.getId());
-                        if (nicSecIp == null) {
-                            throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
-                        }
-                        dstIp = nicSecIp.getIp4Address();
-                         // Set public ip column with the vm ip
-                    }
-                }
-
-                // Verify ip address parameter
-                // checking vm id is not sufficient, check for the vm ip
-                isIpReadyForStaticNat(vmId, ipAddress, dstIp, caller, ctx.getCallingUserId());
-            }
-
-            ipAddress.setOneToOneNat(true);
-            ipAddress.setAssociatedWithVmId(vmId);
-
-            ipAddress.setVmIp(dstIp);
-            if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
-                // enable static nat on the backend
-                s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
-                if (applyStaticNatForIp(ipId, false, caller, false)) {
-                    performedIpAssoc = false; // ignor unassignIPFromVpcNetwork in finally block
-                    return true;
-                } else {
-                    s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
-                    ipAddress.setOneToOneNat(isOneToOneNat);
-                    ipAddress.setAssociatedWithVmId(associatedWithVmId);
-                    ipAddress.setVmIp(null);
-                    _ipAddressDao.update(ipAddress.getId(), ipAddress);
-                }
-            } else {
-                s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
-
-            }
-        } finally {
-                if (performedIpAssoc) {
-                    //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
-                    IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
-                    _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
-            }
-        }
-        return false;
-    }
-
-    protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, String vmIp, Account caller, long callerUserId) throws NetworkRuleConflictException,
-        ResourceUnavailableException {
-        if (ipAddress.isSourceNat()) {
-            throw new InvalidParameterValueException("Can't enable static, ip address " + ipAddress + " is a sourceNat ip address");
-        }
-
-        if (!ipAddress.isOneToOneNat()) { // Dont allow to enable static nat if PF/LB rules exist for the IP
-            List<FirewallRuleVO> portForwardingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipAddress.getId(), Purpose.PortForwarding);
-            if (portForwardingRules != null && !portForwardingRules.isEmpty()) {
-                throw new NetworkRuleConflictException("Failed to enable static nat for the ip address " + ipAddress + " as it already has PortForwarding rules assigned");
-            }
-
-            List<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipAddress.getId(), Purpose.LoadBalancing);
-            if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
-                throw new NetworkRuleConflictException("Failed to enable static nat for the ip address " + ipAddress + " as it already has LoadBalancing rules assigned");
-            }
-        } else if (ipAddress.getAssociatedWithVmId() != null && ipAddress.getAssociatedWithVmId().longValue() != vmId) {
-            throw new NetworkRuleConflictException("Failed to enable static for the ip address " + ipAddress + " and vm id=" + vmId +
-                " as it's already assigned to antoher vm");
-        }
-
-        //check wether the vm ip is alreday associated with any public ip address
-        IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmIdAndVmIp(vmId, vmIp);
-
-        if (oldIP != null) {
-            // If elasticIP functionality is supported in the network, we always have to disable static nat on the old
-            // ip in order to re-enable it on the new one
-            Long networkId = oldIP.getAssociatedWithNetworkId();
-            VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-            boolean reassignStaticNat = false;
-            if (networkId != null) {
-                Network guestNetwork = _networkModel.getNetwork(networkId);
-                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-                if (offering.getElasticIp()) {
-                    reassignStaticNat = true;
-                }
-            }
-
-            // If there is public ip address already associated with the vm, throw an exception
-            if (!reassignStaticNat) {
-                throw new InvalidParameterValueException("Failed to enable static nat on the  ip " +
-                          ipAddress.getAddress()+" with Id " +ipAddress.getUuid()+" as the vm " +vm.getInstanceName() + " with Id " +
-                        vm.getUuid() +" is already associated with another public ip " + oldIP.getAddress() +" with id "+
-                        oldIP.getUuid());
-            }
-        // unassign old static nat rule
-        s_logger.debug("Disassociating static nat for ip " + oldIP);
-        if (!disableStaticNat(oldIP.getId(), caller, callerUserId, true)) {
-                throw new CloudRuntimeException("Failed to disable old static nat rule for vm "+ vm.getInstanceName() +
-                        " with id "+vm.getUuid() +"  and public ip " + oldIP);
-            }
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_DELETE, eventDescription = "revoking forwarding rule", async = true)
-    public boolean revokePortForwardingRule(long ruleId, boolean apply) {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        PortForwardingRuleVO rule = _portForwardingDao.findById(ruleId);
-        if (rule == null) {
-            throw new InvalidParameterValueException("Unable to find " + ruleId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        if (!revokePortForwardingRuleInternal(ruleId, caller, ctx.getCallingUserId(), apply)) {
-            throw new CloudRuntimeException("Failed to delete port forwarding rule");
-        }
-        return true;
-    }
-
-    private boolean revokePortForwardingRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
-        PortForwardingRuleVO rule = _portForwardingDao.findById(ruleId);
-
-        _firewallMgr.revokeRule(rule, caller, userId, true);
-
-        boolean success = false;
-
-        if (apply) {
-            success = applyPortForwardingRules(rule.getSourceIpAddressId(), _ipAddrMgr.RulesContinueOnError.value(), caller);
-        } else {
-            success = true;
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_DELETE, eventDescription = "revoking forwarding rule", async = true)
-    public boolean revokeStaticNatRule(long ruleId, boolean apply) {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        FirewallRuleVO rule = _firewallDao.findById(ruleId);
-        if (rule == null) {
-            throw new InvalidParameterValueException("Unable to find " + ruleId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        if (!revokeStaticNatRuleInternal(ruleId, caller, ctx.getCallingUserId(), apply)) {
-            throw new CloudRuntimeException("Failed to revoke forwarding rule");
-        }
-        return true;
-    }
-
-    private boolean revokeStaticNatRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
-        FirewallRuleVO rule = _firewallDao.findById(ruleId);
-
-        _firewallMgr.revokeRule(rule, caller, userId, true);
-
-        boolean success = false;
-
-        if (apply) {
-            success = applyStaticNatRulesForIp(rule.getSourceIpAddressId(),  _ipAddrMgr.RulesContinueOnError.value(), caller, true);
-        } else {
-            success = true;
-        }
-
-        return success;
-    }
-
-    @Override
-    public boolean revokePortForwardingRulesForVm(long vmId) {
-        boolean success = true;
-        UserVmVO vm = _vmDao.findByIdIncludingRemoved(vmId);
-        if (vm == null) {
-            return false;
-        }
-
-        List<PortForwardingRuleVO> rules = _portForwardingDao.listByVm(vmId);
-        Set<Long> ipsToReprogram = new HashSet<Long>();
-
-        if (rules == null || rules.isEmpty()) {
-            s_logger.debug("No port forwarding rules are found for vm id=" + vmId);
-            return true;
-        }
-
-        for (PortForwardingRuleVO rule : rules) {
-            // Mark port forwarding rule as Revoked, but don't revoke it yet (apply=false)
-            revokePortForwardingRuleInternal(rule.getId(), _accountMgr.getSystemAccount(), Account.ACCOUNT_ID_SYSTEM, false);
-            ipsToReprogram.add(rule.getSourceIpAddressId());
-        }
-
-        // apply rules for all ip addresses
-        for (Long ipId : ipsToReprogram) {
-            s_logger.debug("Applying port forwarding rules for ip address id=" + ipId + " as a part of vm expunge");
-            if (!applyPortForwardingRules(ipId,  _ipAddrMgr.RulesContinueOnError.value(), _accountMgr.getSystemAccount())) {
-                s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId);
-                success = false;
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    public Pair<List<? extends PortForwardingRule>, Integer> listPortForwardingRules(ListPortForwardingRulesCmd cmd) {
-        Long ipId = cmd.getIpAddressId();
-        Long id = cmd.getId();
-        Map<String, String> tags = cmd.getTags();
-        Long networkId = cmd.getNetworkId();
-        Boolean display = cmd.getDisplay();
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        if (ipId != null) {
-            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
-            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
-                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for port forwarding rules yet");
-            }
-            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
-        }
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
-        Long domainId = domainIdRecursiveListProject.first();
-        Boolean isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        SearchBuilder<PortForwardingRuleVO> sb = _portForwardingDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
-        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
-        sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), Op.EQ);
-
-        if (tags != null && !tags.isEmpty()) {
-            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<PortForwardingRuleVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PortForwardingRule.toString());
-            for (String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        if (ipId != null) {
-            sc.setParameters("ip", ipId);
-        }
-
-        if (networkId != null) {
-            sc.setParameters("networkId", networkId);
-        }
-
-        sc.setParameters("purpose", Purpose.PortForwarding);
-
-        Pair<List<PortForwardingRuleVO>, Integer> result = _portForwardingDao.searchAndCount(sc, filter);
-        return new Pair<List<? extends PortForwardingRule>, Integer>(result.first(), result.second());
-    }
-
-    protected boolean applyPortForwardingRules(long ipId, boolean continueOnError, Account caller) {
-        List<PortForwardingRuleVO> rules = _portForwardingDao.listForApplication(ipId);
-
-        if (rules.size() == 0) {
-            s_logger.debug("There are no port forwarding rules to apply for ip id=" + ipId);
-            return true;
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, rules.toArray(new PortForwardingRuleVO[rules.size()]));
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(rules, continueOnError, true)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply port forwarding rules for ip due to ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    protected boolean applyStaticNatRulesForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
-        List<? extends FirewallRule> rules = _firewallDao.listByIpAndPurpose(sourceIpId, Purpose.StaticNat);
-        List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
-
-        if (rules.size() == 0) {
-            s_logger.debug("There are no static nat rules to apply for ip id=" + sourceIpId);
-            return true;
-        }
-
-        for (FirewallRule rule : rules) {
-            staticNatRules.add(buildStaticNatRule(rule, forRevoke));
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, staticNatRules.toArray(new StaticNatRule[staticNatRules.size()]));
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(staticNatRules, continueOnError, true)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply static nat rules for ip due to ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyPortForwardingRulesForNetwork(long networkId, boolean continueOnError, Account caller) {
-        List<PortForwardingRuleVO> rules = listByNetworkId(networkId);
-        if (rules.size() == 0) {
-            s_logger.debug("There are no port forwarding rules to apply for network id=" + networkId);
-            return true;
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, rules.toArray(new PortForwardingRuleVO[rules.size()]));
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(rules, continueOnError, true)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply port forwarding rules for network due to ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyStaticNatRulesForNetwork(long networkId, boolean continueOnError, Account caller) {
-        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
-        List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
-
-        if (rules.size() == 0) {
-            s_logger.debug("There are no static nat rules to apply for network id=" + networkId);
-            return true;
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, rules.toArray(new FirewallRule[rules.size()]));
-        }
-
-        for (FirewallRuleVO rule : rules) {
-            staticNatRules.add(buildStaticNatRule(rule, false));
-        }
-
-        try {
-            if (!_firewallMgr.applyRules(staticNatRules, continueOnError, true)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to apply static nat rules for network due to ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller) {
-        List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(networkId);
-        if (ips.isEmpty()) {
-            s_logger.debug("There are no static nat to apply for network id=" + networkId);
-            return true;
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, ips.toArray(new IPAddressVO[ips.size()]));
-        }
-
-        List<StaticNat> staticNats = new ArrayList<StaticNat>();
-        for (IPAddressVO ip : ips) {
-            // Get nic IP4 address
-            //String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
-            StaticNatImpl staticNat = new StaticNatImpl(ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), networkId, ip.getId(), ip.getVmIp(), false);
-            staticNats.add(staticNat);
-        }
-
-        try {
-            if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, false)) {
-                return false;
-            }
-        } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to create static nat for network due to ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public Pair<List<? extends FirewallRule>, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId,
-        Long projectId, boolean isRecursive, boolean listAll) {
-        Account caller = CallContext.current().getCallingAccount();
-        List<Long> permittedAccounts = new ArrayList<Long>();
-
-        if (ipId != null) {
-            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
-            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
-                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for port forwarding rules yet");
-            }
-            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
-        }
-
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
-        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        domainId = domainIdRecursiveListProject.first();
-        isRecursive = domainIdRecursiveListProject.second();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, start, size);
-        SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
-        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
-        sb.and("id", sb.entity().getId(), Op.EQ);
-
-        if (vmId != null) {
-            SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
-            ipSearch.and("associatedWithVmId", ipSearch.entity().getAssociatedWithVmId(), Op.EQ);
-            sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-        SearchCriteria<FirewallRuleVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        sc.setParameters("purpose", Purpose.StaticNat);
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (ipId != null) {
-            sc.setParameters("ip", ipId);
-        }
-
-        if (vmId != null) {
-            sc.setJoinParameters("ipSearch", "associatedWithVmId", vmId);
-        }
-
-        Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
-        return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "applying port forwarding rule", async = true)
-    public boolean applyPortForwardingRules(long ipId, Account caller) throws ResourceUnavailableException {
-        if (!applyPortForwardingRules(ipId, false, caller)) {
-            throw new CloudRuntimeException("Failed to apply port forwarding rule");
-        }
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "applying static nat rule", async = true)
-    public boolean applyStaticNatRules(long ipId, Account caller) throws ResourceUnavailableException {
-        if (!applyStaticNatRulesForIp(ipId, false, caller, false)) {
-            throw new CloudRuntimeException("Failed to apply static nat rule");
-        }
-        return true;
-    }
-
-    @Override
-    public boolean revokeAllPFAndStaticNatRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
-        List<FirewallRule> rules = new ArrayList<FirewallRule>();
-
-        List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByIpAndNotRevoked(ipId);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for ip id=" + ipId);
-        }
-
-        for (PortForwardingRuleVO rule : pfRules) {
-            // Mark all PF rules as Revoke, but don't revoke them yet
-            revokePortForwardingRuleInternal(rule.getId(), caller, userId, false);
-        }
-
-        List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.StaticNat);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + staticNatRules.size() + " static nat rules for ip id=" + ipId);
-        }
-
-        for (FirewallRuleVO rule : staticNatRules) {
-            // Mark all static nat rules as Revoke, but don't revoke them yet
-            revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
-        }
-
-        boolean success = true;
-
-        // revoke all port forwarding rules
-        success = success && applyPortForwardingRules(ipId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
-
-        // revoke all all static nat rules
-        success = success && applyStaticNatRulesForIp(ipId,  _ipAddrMgr.RulesContinueOnError.value(), caller, true);
-
-        // revoke static nat for the ip address
-        success = success && applyStaticNatForIp(ipId, false, caller, true);
-
-        // Now we check again in case more rules have been inserted.
-        rules.addAll(_portForwardingDao.listByIpAndNotRevoked(ipId));
-        rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.StaticNat));
-
-        if (s_logger.isDebugEnabled() && success) {
-            s_logger.debug("Successfully released rules for ip id=" + ipId + " and # of rules now = " + rules.size());
-        }
-
-        return (rules.size() == 0 && success);
-    }
-
-    @Override
-    public boolean revokeAllPFStaticNatRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
-        List<FirewallRule> rules = new ArrayList<FirewallRule>();
-
-        List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByNetwork(networkId);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for network id=" + networkId);
-        }
-
-        List<FirewallRuleVO> staticNatRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + staticNatRules.size() + " static nat rules for network id=" + networkId);
-        }
-
-        // Mark all pf rules (Active and non-Active) to be revoked, but don't revoke it yet - pass apply=false
-        for (PortForwardingRuleVO rule : pfRules) {
-            revokePortForwardingRuleInternal(rule.getId(), caller, userId, false);
-        }
-
-        // Mark all static nat rules (Active and non-Active) to be revoked, but don't revoke it yet - pass apply=false
-        for (FirewallRuleVO rule : staticNatRules) {
-            revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
-        }
-
-        boolean success = true;
-        // revoke all PF rules for the network
-        success = success && applyPortForwardingRulesForNetwork(networkId, true, caller);
-        success = success && applyPortForwardingRulesForNetwork(networkId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
-
-        // revoke all all static nat rules for the network
-        success = success && applyStaticNatRulesForNetwork(networkId, true, caller);
-        success = success && applyStaticNatRulesForNetwork(networkId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
-
-        // Now we check again in case more rules have been inserted.
-        rules.addAll(_portForwardingDao.listByNetworkAndNotRevoked(networkId));
-        rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.StaticNat));
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully released rules for network id=" + networkId + " and # of rules now = " + rules.size());
-        }
-
-        return success && rules.size() == 0;
-    }
-
-    @Override
-    @DB
-    public FirewallRuleVO[] reservePorts(final IpAddress ip, final String protocol, final FirewallRule.Purpose purpose, final boolean openFirewall, final Account caller,
-        final int... ports) throws NetworkRuleConflictException {
-        final FirewallRuleVO[] rules = new FirewallRuleVO[ports.length];
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<NetworkRuleConflictException>() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) throws NetworkRuleConflictException {
-                for (int i = 0; i < ports.length; i++) {
-
-                    rules[i] =
-                        new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(),
-                            ip.getAllocatedInDomainId(), purpose, null, null, null, null);
-                    rules[i] = _firewallDao.persist(rules[i]);
-
-                    if (openFirewall) {
-                        _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, rules[i].getId(),
-                            ip.getAssociatedWithNetworkId());
-                    }
-                }
-            }
-        });
-
-        boolean success = false;
-        try {
-            for (FirewallRuleVO newRule : rules) {
-                _firewallMgr.detectRulesConflict(newRule);
-            }
-            success = true;
-            return rules;
-        } finally {
-            if (!success) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        for (FirewallRuleVO newRule : rules) {
-                            _firewallMgr.removeRule(newRule);
-                        }
-                    }
-                });
-            }
-        }
-    }
-
-    private List<PortForwardingRuleVO> listByNetworkId(long networkId) {
-        return _portForwardingDao.listByNetwork(networkId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_DISABLE_STATIC_NAT, eventDescription = "disabling static nat", async = true)
-    public boolean disableStaticNat(long ipId) throws ResourceUnavailableException, NetworkRuleConflictException, InsufficientAddressCapacityException {
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
-        checkIpAndUserVm(ipAddress, null, caller, false);
-
-        if (ipAddress.getSystem()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Can't disable static nat for system IP address with specified id");
-            ex.addProxyObject(ipAddress.getUuid(), "ipId");
-            throw ex;
-        }
-
-        Long vmId = ipAddress.getAssociatedWithVmId();
-        if (vmId == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Specified IP address id is not associated with any vm Id");
-            ex.addProxyObject(ipAddress.getUuid(), "ipId");
-            throw ex;
-        }
-
-        // if network has elastic IP functionality supported, we first have to disable static nat on old ip in order to
-        // re-enable it on the new one enable static nat takes care of that
-        Network guestNetwork = _networkModel.getNetwork(ipAddress.getAssociatedWithNetworkId());
-        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-        if (offering.getElasticIp()) {
-            if (offering.getAssociatePublicIP()) {
-                getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true);
-                return true;
-            }
-        }
-
-        return disableStaticNat(ipId, caller, ctx.getCallingUserId(), false);
-    }
-
-    @Override
-    public boolean disableStaticNat(long ipId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException {
-        boolean success = true;
-
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
-        checkIpAndUserVm(ipAddress, null, caller, false);
-        long networkId = ipAddress.getAssociatedWithNetworkId();
-
-        if (!ipAddress.isOneToOneNat()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("One to one nat is not enabled for the specified ip id");
-            ex.addProxyObject(ipAddress.getUuid(), "ipId");
-            throw ex;
-        }
-
-        ipAddress.setRuleState(IpAddress.State.Releasing);
-        _ipAddressDao.update(ipAddress.getId(), ipAddress);
-        ipAddress = _ipAddressDao.findById(ipId);
-
-        // Revoke all firewall rules for the ip
-        try {
-            s_logger.debug("Revoking all " + Purpose.Firewall + "rules as a part of disabling static nat for public IP id=" + ipId);
-            if (!_firewallMgr.revokeFirewallRulesForIp(ipId, callerUserId, caller)) {
-                s_logger.warn("Unable to revoke all the firewall rules for ip id=" + ipId + " as a part of disable statis nat");
-                success = false;
-            }
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to revoke all firewall rules for ip id=" + ipId + " as a part of ip release", e);
-            success = false;
-        }
-
-        if (!revokeAllPFAndStaticNatRulesForIp(ipId, callerUserId, caller)) {
-            s_logger.warn("Unable to revoke all static nat rules for ip " + ipAddress);
-            success = false;
-        }
-
-        if (success) {
-            boolean isIpSystem = ipAddress.getSystem();
-            ipAddress.setOneToOneNat(false);
-            ipAddress.setAssociatedWithVmId(null);
-            ipAddress.setRuleState(null);
-            ipAddress.setVmIp(null);
-            if (isIpSystem && !releaseIpIfElastic) {
-                ipAddress.setSystem(false);
-            }
-            _ipAddressDao.update(ipAddress.getId(), ipAddress);
-            _vpcMgr.unassignIPFromVpcNetwork(ipAddress.getId(), networkId);
-
-            if (isIpSystem && releaseIpIfElastic && !_ipAddrMgr.handleSystemIpRelease(ipAddress)) {
-                s_logger.warn("Failed to release system ip address " + ipAddress);
-                success = false;
-            }
-
-            return true;
-        } else {
-            s_logger.warn("Failed to disable one to one nat for the ip address id" + ipId);
-            ipAddress = _ipAddressDao.findById(ipId);
-            ipAddress.setRuleState(null);
-            _ipAddressDao.update(ipAddress.getId(), ipAddress);
-            return false;
-        }
-    }
-
-    @Override
-    public StaticNatRule buildStaticNatRule(FirewallRule rule, boolean forRevoke) {
-        IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
-        FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
-
-        if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Source ip address of the specified firewall rule id is not static nat enabled");
-            ex.addProxyObject(ruleVO.getUuid(), "ruleId");
-            throw ex;
-        }
-
-        String dstIp = ip.getVmIp();
-        if (dstIp == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("VM ip address of the specified public ip is not set ");
-            ex.addProxyObject(ruleVO.getUuid(), "ruleId");
-            throw ex;
-        }
-
-        return new StaticNatRuleImpl(ruleVO, dstIp);
-    }
-
-    protected boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
-        IpAddress sourceIp = _ipAddressDao.findById(sourceIpId);
-
-        List<StaticNat> staticNats = createStaticNatForIp(sourceIp, caller, forRevoke);
-
-        if (staticNats != null && !staticNats.isEmpty()) {
-            try {
-                if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, forRevoke)) {
-                    return false;
-                }
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to create static nat rule due to ", ex);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke) {
-        List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkId);
-
-        List<StaticNat> staticNats = new ArrayList<StaticNat>();
-        for (IpAddress staticNatIp : staticNatIps) {
-            staticNats.addAll(createStaticNatForIp(staticNatIp, caller, forRevoke));
-        }
-
-        if (staticNats != null && !staticNats.isEmpty()) {
-            if (forRevoke) {
-                s_logger.debug("Found " + staticNats.size() + " static nats to disable for network id " + networkId);
-            }
-            try {
-                if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, forRevoke)) {
-                    return false;
-                }
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to create static nat rule due to ", ex);
-                return false;
-            }
-        } else {
-            s_logger.debug("Found 0 static nat rules to apply for network id " + networkId);
-        }
-
-        return true;
-    }
-
-    protected List<StaticNat> createStaticNatForIp(IpAddress sourceIp, Account caller, boolean forRevoke) {
-        List<StaticNat> staticNats = new ArrayList<StaticNat>();
-        if (!sourceIp.isOneToOneNat()) {
-            s_logger.debug("Source ip id=" + sourceIp + " is not one to one nat");
-            return staticNats;
-        }
-
-        Long networkId = sourceIp.getAssociatedWithNetworkId();
-        if (networkId == null) {
-            throw new CloudRuntimeException("Ip address is not associated with any network");
-        }
-
-        VMInstanceVO vm = _vmInstanceDao.findByIdIncludingRemoved(sourceIp.getAssociatedWithVmId());
-        Network network = _networkModel.getNetwork(networkId);
-        if (network == null) {
-            CloudRuntimeException ex = new CloudRuntimeException("Unable to find an ip address to map to specified vm id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, true, sourceIp);
-        }
-
-        // create new static nat rule
-        // Get nic IP4 address
-        Nic guestNic = _networkModel.getNicInNetworkIncludingRemoved(vm.getId(), networkId);
-        if (guestNic == null) {
-            throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
-        }
-
-        String dstIp;
-
-        dstIp = sourceIp.getVmIp();
-        if (dstIp == null) {
-            throw new InvalidParameterValueException("Vm ip is not set as dnat ip for this public ip");
-        }
-
-        String srcMac = null;
-        try {
-            srcMac = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
-        } catch (InsufficientAddressCapacityException e) {
-            throw new CloudRuntimeException("Insufficient MAC address for static NAT instantiation.");
-        }
-
-        StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, srcMac, forRevoke);
-        staticNats.add(staticNat);
-        return staticNats;
-    }
-
-    @Override
-    public void getSystemIpAndEnableStaticNatForVm(VirtualMachine vm, boolean getNewIp) throws InsufficientAddressCapacityException {
-        boolean success = true;
-
-        // enable static nat if eIp capability is supported
-        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
-        for (Nic nic : nics) {
-            Network guestNetwork = _networkModel.getNetwork(nic.getNetworkId());
-            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-            if (offering.getElasticIp()) {
-                boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm);
-                // for user VM's associate public IP only if offering is marked to associate a public IP by default on start of VM
-                if (!isSystemVM && !offering.getAssociatePublicIP()) {
-                    continue;
-                }
-                // check if there is already static nat enabled
-                if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null && !getNewIp) {
-                    s_logger.debug("Vm " + vm + " already has ip associated with it in guest network " + guestNetwork);
-                    continue;
-                }
-
-                s_logger.debug("Allocating system ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork);
-                IpAddress ip = _ipAddrMgr.assignSystemIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true);
-                if (ip == null) {
-                    throw new CloudRuntimeException("Failed to allocate system ip for vm " + vm + " in guest network " + guestNetwork);
-                }
-
-                s_logger.debug("Allocated system ip " + ip + ", now enabling static nat on it for vm " + vm);
-
-                try {
-                    success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM, null);
-                } catch (NetworkRuleConflictException ex) {
-                    s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork +
-                        " due to exception ", ex);
-                    success = false;
-                } catch (ResourceUnavailableException ex) {
-                    s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork +
-                        " due to exception ", ex);
-                    success = false;
-                }
-
-                if (!success) {
-                    s_logger.warn("Failed to enable static nat on system ip " + ip + " for the vm " + vm + ", releasing the ip...");
-                    _ipAddrMgr.handleSystemIpRelease(ip);
-                    throw new CloudRuntimeException("Failed to enable static nat on system ip for the vm " + vm);
-                } else {
-                    s_logger.warn("Succesfully enabled static nat on system ip " + ip + " for the vm " + vm);
-                }
-            }
-        }
-    }
-
-    protected void removePFRule(PortForwardingRuleVO rule) {
-        _portForwardingDao.remove(rule.getId());
-    }
-
-    @Override
-    public List<FirewallRuleVO> listAssociatedRulesForGuestNic(Nic nic) {
-        s_logger.debug("Checking if PF/StaticNat/LoadBalancer rules are configured for nic " + nic.getId());
-        List<FirewallRuleVO> result = new ArrayList<FirewallRuleVO>();
-        // add PF rules
-        result.addAll(_portForwardingDao.listByNetworkAndDestIpAddr(nic.getIPv4Address(), nic.getNetworkId()));
-        if(result.size() > 0) {
-            s_logger.debug("Found " + result.size() + " portforwarding rule configured for the nic in the network " + nic.getNetworkId());
-        }
-        // add static NAT rules
-        List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(nic.getInstanceId());
-        for (FirewallRuleVO rule : staticNatRules) {
-            if (rule.getNetworkId() == nic.getNetworkId()) {
-                result.add(rule);
-                s_logger.debug("Found rule " + rule.getId() + " " + rule.getPurpose() + " configured");
-            }
-        }
-        List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(nic.getNetworkId());
-        for (IpAddress ip : staticNatIps) {
-            if (ip.getVmIp() != null && ip.getVmIp().equals(nic.getIPv4Address())) {
-                VMInstanceVO vm = _vmInstanceDao.findById(nic.getInstanceId());
-                // generate a static Nat rule on the fly because staticNATrule does not persist into db anymore
-                // FIX ME
-                FirewallRuleVO staticNatRule =
-                        new FirewallRuleVO(null, ip.getId(), 0, 65535, NetUtils.ALL_PROTO.toString(), nic.getNetworkId(), vm.getAccountId(), vm.getDomainId(),
-                                Purpose.StaticNat, null, null, null, null, null);
-                result.add(staticNatRule);
-                s_logger.debug("Found rule " + staticNatRule.getId() + " " + staticNatRule.getPurpose() + " configured");
-            }
-        }
-        // add LB rules
-        List<LoadBalancerVMMapVO> lbMapList = _loadBalancerVMMapDao.listByInstanceId(nic.getInstanceId());
-        for (LoadBalancerVMMapVO lb : lbMapList) {
-            FirewallRuleVO lbRule = _firewallDao.findById(lb.getLoadBalancerId());
-            if (lbRule.getNetworkId() == nic.getNetworkId()) {
-                result.add(lbRule);
-                s_logger.debug("Found rule " + lbRule.getId() + " " + lbRule.getPurpose() + " configured");
-            }
-        }
-        return result;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_MODIFY, eventDescription = "updating forwarding rule", async = true)
-    public PortForwardingRule updatePortForwardingRule(long id, Integer privatePort, Integer privateEndPort, Long virtualMachineId, Ip vmGuestIp, String customId, Boolean forDisplay) {
-        Account caller = CallContext.current().getCallingAccount();
-        PortForwardingRuleVO rule = _portForwardingDao.findById(id);
-        if (rule == null) {
-            throw new InvalidParameterValueException("Unable to find " + id);
-        }
-        _accountMgr.checkAccess(caller, null, true, rule);
-
-        if (customId != null) {
-            rule.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            rule.setDisplay(forDisplay);
-        }
-
-        if (privatePort != null && !NetUtils.isValidPort(privatePort)) {
-            throw new InvalidParameterValueException("privatePort is an invalid value: " + privatePort);
-        }
-        if (privateEndPort != null && !NetUtils.isValidPort(privateEndPort)) {
-            throw new InvalidParameterValueException("PrivateEndPort has an invalid value: " + privateEndPort);
-        }
-
-        if (privatePort != null && privateEndPort != null && ((privateEndPort - privatePort) != (rule.getSourcePortEnd() - rule.getSourcePortStart())))
-        {
-            throw new InvalidParameterValueException("Unable to update the private port range of port forwarding rule as  " +
-                    "the provided port range is not consistent with the port range : " + rule.getSourcePortStart() + " to " + rule.getSourcePortEnd());
-        }
-
-        //in case of port range
-        if (!rule.getSourcePortStart().equals(rule.getSourcePortEnd())) {
-             if ((privatePort == null || privateEndPort == null) && !(privatePort == null && privateEndPort == null)) {
-                throw new InvalidParameterValueException("Unable to update the private port range of port forwarding rule as  " +
-                        "the provided port range is not consistent with the port range : " + rule.getSourcePortStart() + " to " + rule.getSourcePortEnd());
-            }
-        }
-
-
-
-        if (virtualMachineId == null && vmGuestIp != null) {
-            throw new InvalidParameterValueException("vmguestip should be set along with virtualmachineid");
-        }
-        Ip dstIp = rule.getDestinationIpAddress();
-        if (virtualMachineId != null) {
-            // Verify that vm has nic in the network
-            Nic guestNic = _networkModel.getNicInNetwork(virtualMachineId, rule.getNetworkId());
-            if (guestNic == null || guestNic.getIPv4Address() == null) {
-                throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
-            } else {
-                dstIp = new Ip(guestNic.getIPv4Address());
-            }
-
-            if (vmGuestIp != null) {
-                //vm ip is passed so it can be primary or secondary ip addreess.
-                if (!dstIp.equals(vmGuestIp)) {
-                    //the vm ip is secondary ip to the nic.
-                    // is vmIp is secondary ip or not
-                    NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmGuestIp.toString(), guestNic.getId());
-                    if (secondaryIp == null) {
-                        throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
-                    }
-                    dstIp = vmGuestIp;
-                }
-            }
-        }
-
-        // revoke old rules at first
-        List<PortForwardingRuleVO> rules = new ArrayList<PortForwardingRuleVO>();
-        rule.setState(State.Revoke);
-        _portForwardingDao.update(id, rule);
-        rules.add(rule);
-        try {
-            if (!_firewallMgr.applyRules(rules, true, false)) {
-                throw new CloudRuntimeException("Failed to revoke the existing port forwarding rule:" + id);
-            }
-        } catch (ResourceUnavailableException ex) {
-            throw new CloudRuntimeException("Failed to revoke the existing port forwarding rule:" + id + " due to ", ex);
-        }
-
-        rule = _portForwardingDao.findById(id);
-        rule.setState(State.Add);
-        if (privatePort != null) {
-            rule.setDestinationPortStart(privatePort.intValue());
-            rule.setDestinationPortEnd((privateEndPort == null) ? privatePort.intValue() : privateEndPort.intValue());
-        } else if (privateEndPort != null) {
-            rule.setDestinationPortStart(privateEndPort.intValue());
-            rule.setDestinationPortEnd(privateEndPort);
-        }
-
-        if (virtualMachineId != null) {
-            rule.setVirtualMachineId(virtualMachineId);
-            rule.setDestinationIpAddress(dstIp);
-        }
-        _portForwardingDao.update(id, rule);
-
-        //apply new rules
-        if (!applyPortForwardingRules(rule.getSourceIpAddressId(), false, caller)) {
-            throw new CloudRuntimeException("Failed to apply the new port forwarding rule:" + id);
-        }
-
-        return _portForwardingDao.findById(id);
-    }
-}
diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
deleted file mode 100644
index c64a36b..0000000
--- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
+++ /dev/null
@@ -1,514 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.NetworkACLServiceProvider;
-import com.cloud.network.element.VpcProvider;
-import com.cloud.network.vpc.NetworkACLItem.State;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.log4j.Logger;
-
-public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLManager {
-    private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkModel _networkMgr;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    List<NetworkACLServiceProvider> _networkAclElements;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    VpcGatewayDao _vpcGatewayDao;
-    @Inject
-    NetworkModel _ntwkModel;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    VpcService _vpcSvc;
-    @Inject
-    MessageBus _messageBus;
-
-    @Override
-    public NetworkACL createNetworkACL(final String name, final String description, final long vpcId, final Boolean forDisplay) {
-        final NetworkACLVO acl = new NetworkACLVO(name, description, vpcId);
-        if (forDisplay != null) {
-            acl.setDisplay(forDisplay);
-        }
-        return _networkACLDao.persist(acl);
-    }
-
-    @Override
-    public boolean applyNetworkACL(final long aclId) throws ResourceUnavailableException {
-        boolean handled = true;
-        boolean aclApplyStatus = true;
-
-        final List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(aclId);
-        //Find all networks using this ACL and apply the ACL
-        final List<NetworkVO> networks = _networkDao.listByAclId(aclId);
-        for (final NetworkVO network : networks) {
-            if (!applyACLItemsToNetwork(network.getId(), rules)) {
-                handled = false;
-                break;
-            }
-        }
-
-        final List<VpcGatewayVO> vpcGateways = _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
-        for (final VpcGatewayVO vpcGateway : vpcGateways) {
-            final PrivateGateway privateGateway = _vpcSvc.getVpcPrivateGateway(vpcGateway.getId());
-
-            if (!applyACLToPrivateGw(privateGateway)) {
-                aclApplyStatus = false;
-                s_logger.debug("failed to apply network acl item on private gateway " + privateGateway.getId() + "acl id " + aclId);
-                break;
-            }
-        }
-
-        if (handled && aclApplyStatus) {
-            for (final NetworkACLItem rule : rules) {
-                if (rule.getState() == NetworkACLItem.State.Revoke) {
-                    removeRule(rule);
-                } else if (rule.getState() == NetworkACLItem.State.Add) {
-                    final NetworkACLItemVO ruleVO = _networkACLItemDao.findById(rule.getId());
-                    ruleVO.setState(NetworkACLItem.State.Active);
-                    _networkACLItemDao.update(ruleVO.getId(), ruleVO);
-                }
-            }
-        }
-        return handled && aclApplyStatus;
-    }
-
-    @Override
-    public NetworkACL getNetworkACL(final long id) {
-        return _networkACLDao.findById(id);
-    }
-
-    @Override
-    public boolean deleteNetworkACL(final NetworkACL acl) {
-        final long aclId = acl.getId();
-        final List<NetworkVO> networks = _networkDao.listByAclId(aclId);
-        if (networks != null && networks.size() > 0) {
-            throw new CloudRuntimeException("ACL is still associated with " + networks.size() + " tier(s). Cannot delete network ACL: " + acl.getUuid());
-        }
-
-        final List<VpcGatewayVO> pvtGateways = _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
-
-        if (pvtGateways != null && pvtGateways.size() > 0) {
-            throw new CloudRuntimeException("ACL is still associated with " + pvtGateways.size() + " private gateway(s). Cannot delete network ACL: " + acl.getUuid());
-        }
-
-        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(aclId);
-        for (final NetworkACLItemVO networkACLItem : aclItems) {
-            revokeNetworkACLItem(networkACLItem.getId());
-        }
-
-        return _networkACLDao.remove(aclId);
-    }
-
-    @Override
-    public boolean replaceNetworkACLForPrivateGw(final NetworkACL acl, final PrivateGateway gateway) throws ResourceUnavailableException {
-        final VpcGatewayVO vpcGatewayVo = _vpcGatewayDao.findById(gateway.getId());
-        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
-        if (aclItems == null || aclItems.isEmpty()) {
-            //Revoke ACL Items of the existing ACL if the new network acl is empty
-            //Other wise existing rules will not be removed on the router elelment
-            s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
-            if (!revokeACLItemsForPrivateGw(gateway)) {
-                throw new CloudRuntimeException("Failed to replace network ACL. Error while removing existing ACL " + "items for privatewa gateway: " + gateway.getId());
-            }
-        }
-
-        vpcGatewayVo.setNetworkACLId(acl.getId());
-        if (_vpcGatewayDao.update(vpcGatewayVo.getId(), vpcGatewayVo)) {
-            return applyACLToPrivateGw(gateway);
-
-        }
-        return false;
-    }
-
-    @Override
-    public boolean replaceNetworkACL(final NetworkACL acl, final NetworkVO network) throws ResourceUnavailableException {
-
-        final NetworkOffering guestNtwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-
-        if (guestNtwkOff == null) {
-            throw new InvalidParameterValueException("Can't find network offering associated with network: " + network.getUuid());
-        }
-
-        //verify that ACLProvider is supported by network offering
-        if (!_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.NetworkACL)) {
-            throw new InvalidParameterValueException("Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
-        }
-
-        if (network.getNetworkACLId() != null) {
-            //Revoke ACL Items of the existing ACL if the new ACL is empty
-            //Existing rules won't be removed otherwise
-            final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
-            if (aclItems == null || aclItems.isEmpty()) {
-                s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
-                if (!revokeACLItemsForNetwork(network.getId())) {
-                    throw new CloudRuntimeException("Failed to replace network ACL. Error while removing existing ACL items for network: " + network.getId());
-                }
-            }
-        }
-
-        network.setNetworkACLId(acl.getId());
-        //Update Network ACL
-        if (_networkDao.update(network.getId(), network)) {
-            s_logger.debug("Updated network: " + network.getId() + " with Network ACL Id: " + acl.getId() + ", Applying ACL items");
-            //Apply ACL to network
-            final Boolean result = applyACLToNetwork(network.getId());
-            if (result) {
-                // public message on message bus, so that network elements implementing distributed routing capability
-                // can act on the event
-                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
-            }
-            return result;
-        }
-        return false;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "creating network ACL Item", create = true)
-    public NetworkACLItem createNetworkACLItem(final Integer portStart, final Integer portEnd, final String protocol, final List<String> sourceCidrList, final Integer icmpCode,
-            final Integer icmpType, final NetworkACLItem.TrafficType trafficType, final Long aclId, final String action, Integer number, final Boolean forDisplay) {
-        // If number is null, set it to currentMax + 1 (for backward compatibility)
-        if (number == null) {
-            number = _networkACLItemDao.getMaxNumberByACL(aclId) + 1;
-        }
-
-        final Integer numberFinal = number;
-        final NetworkACLItemVO newRule = Transaction.execute(new TransactionCallback<NetworkACLItemVO>() {
-            @Override
-            public NetworkACLItemVO doInTransaction(final TransactionStatus status) {
-                NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow;
-                if ("deny".equalsIgnoreCase(action)) {
-                    ruleAction = NetworkACLItem.Action.Deny;
-                }
-
-                NetworkACLItemVO newRule =
-                        new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(), aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, numberFinal);
-
-                if (forDisplay != null) {
-                    newRule.setDisplay(forDisplay);
-                }
-
-                newRule = _networkACLItemDao.persist(newRule);
-
-                if (!_networkACLItemDao.setStateToAdd(newRule)) {
-                    throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
-                }
-                CallContext.current().setEventDetails("ACL Item Id: " + newRule.getId());
-
-                return newRule;
-            }
-        });
-
-        return getNetworkACLItem(newRule.getId());
-    }
-
-    @Override
-    public NetworkACLItem getNetworkACLItem(final long ruleId) {
-        return _networkACLItemDao.findById(ruleId);
-    }
-
-    @Override
-    public boolean revokeNetworkACLItem(final long ruleId) {
-
-        final NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId);
-
-        revokeRule(rule);
-
-        boolean success = false;
-
-        try {
-            applyNetworkACL(rule.getAclId());
-            success = true;
-        } catch (final ResourceUnavailableException e) {
-            return false;
-        }
-
-        return success;
-    }
-
-    @DB
-    private void revokeRule(final NetworkACLItemVO rule) {
-        if (rule.getState() == State.Staged) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule);
-            }
-            _networkACLItemDao.remove(rule.getId());
-        } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
-            rule.setState(State.Revoke);
-            _networkACLItemDao.update(rule.getId(), rule);
-        }
-    }
-
-    @Override
-    public boolean revokeACLItemsForNetwork(final long networkId) throws ResourceUnavailableException {
-        final Network network = _networkDao.findById(networkId);
-        if (network.getNetworkACLId() == null) {
-            return true;
-        }
-        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(network.getNetworkACLId());
-        if (aclItems.isEmpty()) {
-            s_logger.debug("Found no network ACL Items for network id=" + networkId);
-            return true;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + aclItems.size() + " Network ACL Items for network id=" + networkId);
-        }
-
-        for (final NetworkACLItemVO aclItem : aclItems) {
-            // Mark all Network ACLs rules as Revoke, but don't update in DB
-            if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) {
-                aclItem.setState(State.Revoke);
-            }
-        }
-
-        final boolean success = applyACLItemsToNetwork(network.getId(), aclItems);
-
-        if (s_logger.isDebugEnabled() && success) {
-            s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " + aclItems.size());
-        }
-
-        return success;
-    }
-
-    @Override
-    public boolean revokeACLItemsForPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
-        final long networkACLId = gateway.getNetworkACLId();
-        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(networkACLId);
-        if (aclItems.isEmpty()) {
-            s_logger.debug("Found no network ACL Items for private gateway 'id=" + gateway.getId() + "'");
-            return true;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + aclItems.size() + " Network ACL Items for private gateway  id=" + gateway.getId());
-        }
-
-        for (final NetworkACLItemVO aclItem : aclItems) {
-            // Mark all Network ACLs rules as Revoke, but don't update in DB
-            if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) {
-                aclItem.setState(State.Revoke);
-            }
-        }
-
-        final boolean success = applyACLToPrivateGw(gateway, aclItems);
-
-        if (s_logger.isDebugEnabled() && success) {
-            s_logger.debug("Successfully released Network ACLs for private gateway id=" + gateway.getId() + " and # of rules now = " + aclItems.size());
-        }
-
-        return success;
-    }
-
-    @Override
-    public List<NetworkACLItemVO> listNetworkACLItems(final long guestNtwkId) {
-        final Network network = _networkMgr.getNetwork(guestNtwkId);
-        if (network.getNetworkACLId() == null) {
-            return null;
-        }
-        return _networkACLItemDao.listByACL(network.getNetworkACLId());
-    }
-
-    private void removeRule(final NetworkACLItem rule) {
-        //remove the rule
-        _networkACLItemDao.remove(rule.getId());
-    }
-
-    @Override
-    public boolean applyACLToPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
-        final VpcGatewayVO vpcGatewayVO = _vpcGatewayDao.findById(gateway.getId());
-        final List<? extends NetworkACLItem> rules = _networkACLItemDao.listByACL(vpcGatewayVO.getNetworkACLId());
-        return applyACLToPrivateGw(gateway, rules);
-    }
-
-    private boolean applyACLToPrivateGw(final PrivateGateway gateway, final List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
-        List<VpcProvider> vpcElements = null;
-        vpcElements = new ArrayList<VpcProvider>();
-        vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()));
-
-        if (vpcElements == null) {
-            throw new CloudRuntimeException("Failed to initialize vpc elements");
-        }
-
-        try{
-            for (final VpcProvider provider : vpcElements) {
-                return provider.applyACLItemsToPrivateGw(gateway, rules);
-            }
-        } catch(final Exception ex) {
-            s_logger.debug("Failed to apply acl to private gateway " + gateway);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean applyACLToNetwork(final long networkId) throws ResourceUnavailableException {
-        final Network network = _networkDao.findById(networkId);
-        if (network.getNetworkACLId() == null) {
-            return true;
-        }
-        final List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(network.getNetworkACLId());
-        return applyACLItemsToNetwork(networkId, rules);
-    }
-
-    @Override
-    public NetworkACLItem updateNetworkACLItem(final Long id, final String protocol, final List<String> sourceCidrList, final NetworkACLItem.TrafficType trafficType, final String action,
-            final Integer number, final Integer sourcePortStart, final Integer sourcePortEnd, final Integer icmpCode, final Integer icmpType, final String customId, final Boolean forDisplay) throws ResourceUnavailableException {
-        final NetworkACLItemVO aclItem = _networkACLItemDao.findById(id);
-        aclItem.setState(State.Add);
-
-        if (protocol != null) {
-            aclItem.setProtocol(protocol);
-        }
-
-        if (sourceCidrList != null) {
-            aclItem.setSourceCidrList(sourceCidrList);
-        }
-
-        if (trafficType != null) {
-            aclItem.setTrafficType(trafficType);
-        }
-
-        if (action != null) {
-            NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow;
-            if ("deny".equalsIgnoreCase(action)) {
-                ruleAction = NetworkACLItem.Action.Deny;
-            }
-            aclItem.setAction(ruleAction);
-        }
-
-        if (number != null) {
-            aclItem.setNumber(number);
-        }
-
-        if (sourcePortStart != null) {
-            aclItem.setSourcePortStart(sourcePortStart);
-        }
-
-        if (sourcePortEnd != null) {
-            aclItem.setSourcePortEnd(sourcePortEnd);
-        }
-
-        if (icmpCode != null) {
-            aclItem.setIcmpCode(icmpCode);
-        }
-
-        if (icmpType != null) {
-            aclItem.setIcmpType(icmpType);
-        }
-
-        if (customId != null) {
-            aclItem.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            aclItem.setDisplay(forDisplay);
-        }
-
-        if (_networkACLItemDao.update(id, aclItem)) {
-            if (applyNetworkACL(aclItem.getAclId())) {
-                return aclItem;
-            } else {
-                throw new CloudRuntimeException("Failed to apply Network ACL Item: " + aclItem.getUuid());
-            }
-        }
-        return null;
-    }
-
-    public boolean applyACLItemsToNetwork(final long networkId, final List<NetworkACLItemVO> rules) throws ResourceUnavailableException {
-        final Network network = _networkDao.findById(networkId);
-        boolean handled = false;
-        boolean foundProvider = false;
-        for (final NetworkACLServiceProvider element : _networkAclElements) {
-            final Network.Provider provider = element.getProvider();
-            final boolean isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
-            if (!isAclProvider) {
-                continue;
-            }
-            foundProvider = true;
-            s_logger.debug("Applying NetworkACL for network: " + network.getId() + " with Network ACL service provider");
-            handled = element.applyNetworkACLs(network, rules);
-            if (handled) {
-                // publish message on message bus, so that network elements implementing distributed routing
-                // capability can act on the event
-                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
-                break;
-            }
-        }
-        if (!foundProvider) {
-            s_logger.debug("Unable to find NetworkACL service provider for network: " + network.getId());
-        }
-        return handled;
-    }
-
-    public List<NetworkACLServiceProvider> getNetworkAclElements() {
-        return _networkAclElements;
-    }
-
-    @Inject
-    public void setNetworkAclElements(final List<NetworkACLServiceProvider> networkAclElements) {
-        _networkAclElements = networkAclElements;
-    }
-
-}
diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java
deleted file mode 100644
index 1743f5c..0000000
--- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java
+++ /dev/null
@@ -1,683 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-
-@Component
-public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLService {
-    private static final Logger s_logger = Logger.getLogger(NetworkACLServiceImpl.class);
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkModel _networkMgr;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    NetworkACLManager _networkAclMgr;
-    @Inject
-    VpcGatewayDao _vpcGatewayDao;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    VpcService _vpcSvc;
-
-    @Override
-    public NetworkACL createNetworkACL(final String name, final String description, final long vpcId, final Boolean forDisplay) {
-        final Account caller = CallContext.current().getCallingAccount();
-        final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Unable to find VPC");
-        }
-        _accountMgr.checkAccess(caller, null, true, vpc);
-        return _networkAclMgr.createNetworkACL(name, description, vpcId, forDisplay);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_CREATE, eventDescription = "creating network acl list", async = true)
-    public NetworkACL getNetworkACL(final long id) {
-        return _networkAclMgr.getNetworkACL(id);
-    }
-
-    @Override
-    public Pair<List<? extends NetworkACL>, Integer> listNetworkACLs(final ListNetworkACLListsCmd cmd) {
-        final Long id = cmd.getId();
-        final String name = cmd.getName();
-        final Long networkId = cmd.getNetworkId();
-        final Long vpcId = cmd.getVpcId();
-        final String keyword = cmd.getKeyword();
-        final Boolean display = cmd.getDisplay();
-
-        final SearchBuilder<NetworkACLVO> sb = _networkACLDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("name", sb.entity().getName(), Op.EQ);
-        sb.and("vpcId", sb.entity().getVpcId(), Op.IN);
-        sb.and("display", sb.entity().isDisplay(), Op.EQ);
-
-        final Account caller = CallContext.current().getCallingAccount();
-
-        if (networkId != null) {
-            final SearchBuilder<NetworkVO> network = _networkDao.createSearchBuilder();
-            network.and("networkId", network.entity().getId(), Op.EQ);
-            sb.join("networkJoin", network, sb.entity().getId(), network.entity().getNetworkACLId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<NetworkACLVO> sc = sb.create();
-
-        if (keyword != null) {
-            final SearchCriteria<NetworkACLVO> ssc = _networkACLDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        if(id != null){
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", name);
-        }
-
-        if (vpcId != null) {
-            final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
-            if (vpc == null) {
-                throw new InvalidParameterValueException("Unable to find VPC");
-            }
-            _accountMgr.checkAccess(caller, null, true, vpc);
-            //Include vpcId 0 to list default ACLs
-            sc.setParameters("vpcId", vpcId, 0);
-        } else {
-            //ToDo: Add accountId to network_acl table for permission check
-
-            // VpcId is not specified. Find permitted VPCs for the caller
-            // and list ACLs belonging to the permitted VPCs
-            final List<Long> permittedAccounts = new ArrayList<Long>();
-            Long domainId = cmd.getDomainId();
-            boolean isRecursive = cmd.isRecursive();
-            final String accountName = cmd.getAccountName();
-            final Long projectId = cmd.getProjectId();
-            final boolean listAll = cmd.listAll();
-            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
-                    ListProjectResourcesCriteria>(domainId, isRecursive, null);
-            _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject,
-                    listAll, false);
-            domainId = domainIdRecursiveListProject.first();
-            isRecursive = domainIdRecursiveListProject.second();
-            final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-            final SearchBuilder<VpcVO> sbVpc = _vpcDao.createSearchBuilder();
-            _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            final SearchCriteria<VpcVO> scVpc = sbVpc.create();
-            _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            final List<VpcVO> vpcs = _vpcDao.search(scVpc, null);
-            final List<Long> vpcIds = new ArrayList<Long>();
-            for (final VpcVO vpc : vpcs) {
-                vpcIds.add(vpc.getId());
-            }
-            //Add vpc_id 0 to list default ACLs
-            vpcIds.add(0L);
-            sc.setParameters("vpcId", vpcIds.toArray());
-        }
-
-        if (networkId != null) {
-            sc.setJoinParameters("networkJoin", "networkId", networkId);
-        }
-
-        final Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null);
-        final Pair<List<NetworkACLVO>, Integer> acls =  _networkACLDao.searchAndCount(sc, filter);
-        return new Pair<List<? extends NetworkACL>, Integer>(acls.first(), acls.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "Deleting Network ACL List", async = true)
-    public boolean deleteNetworkACL(final long id) {
-        final Account caller = CallContext.current().getCallingAccount();
-        final NetworkACL acl = _networkACLDao.findById(id);
-        if (acl == null) {
-            throw new InvalidParameterValueException("Unable to find specified ACL");
-        }
-
-        //Do not allow deletion of default ACLs
-        if (acl.getId() == NetworkACL.DEFAULT_ALLOW || acl.getId() == NetworkACL.DEFAULT_DENY) {
-            throw new InvalidParameterValueException("Default ACL cannot be removed");
-        }
-
-        final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Unable to find specified VPC associated with the ACL");
-        }
-        _accountMgr.checkAccess(caller, null, true, vpc);
-        return _networkAclMgr.deleteNetworkACL(acl);
-    }
-
-    @Override
-    public boolean replaceNetworkACLonPrivateGw(final long aclId, final long privateGatewayId) throws ResourceUnavailableException {
-        final Account caller = CallContext.current().getCallingAccount();
-        final VpcGateway gateway = _vpcGatewayDao.findById(privateGatewayId);
-        if (gateway == null) {
-            throw new InvalidParameterValueException("Unable to find specified private gateway");
-        }
-
-        final VpcGatewayVO vo = _vpcGatewayDao.findById(privateGatewayId);
-        if (vo.getState() != VpcGateway.State.Ready) {
-            throw new InvalidParameterValueException("Gateway is not in Ready state");
-        }
-
-        final NetworkACL acl = _networkACLDao.findById(aclId);
-        if (acl == null) {
-            throw new InvalidParameterValueException("Unable to find specified NetworkACL");
-        }
-
-        if (gateway.getVpcId() == null) {
-            throw new InvalidParameterValueException("Unable to find specified vpc id");
-        }
-
-        if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
-            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-            if (vpc == null) {
-                throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
-            }
-            _accountMgr.checkAccess(caller, null, true, vpc);
-            if (!gateway.getVpcId().equals(acl.getVpcId())) {
-                throw new InvalidParameterValueException("private gateway: " + privateGatewayId + " and ACL: " + aclId + " do not belong to the same VPC");
-            }
-        }
-
-        final PrivateGateway privateGateway = _vpcSvc.getVpcPrivateGateway(gateway.getId());
-        _accountMgr.checkAccess(caller, null, true, privateGateway);
-
-        return  _networkAclMgr.replaceNetworkACLForPrivateGw(acl, privateGateway);
-
-    }
-
-    @Override
-    public boolean replaceNetworkACL(final long aclId, final long networkId) throws ResourceUnavailableException {
-        final Account caller = CallContext.current().getCallingAccount();
-
-        final NetworkVO network = _networkDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Unable to find specified Network");
-        }
-
-        final NetworkACL acl = _networkACLDao.findById(aclId);
-        if (acl == null) {
-            throw new InvalidParameterValueException("Unable to find specified NetworkACL");
-        }
-
-        if (network.getVpcId() == null) {
-            throw new InvalidParameterValueException("Network is not part of a VPC: " + network.getUuid());
-        }
-
-        if (network.getTrafficType() != Networks.TrafficType.Guest) {
-            throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest);
-        }
-
-        if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
-            //ACL is not default DENY/ALLOW
-            // ACL should be associated with a VPC
-            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-            if (vpc == null) {
-                throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
-            }
-
-            _accountMgr.checkAccess(caller, null, true, vpc);
-            if (!network.getVpcId().equals(acl.getVpcId())) {
-                throw new InvalidParameterValueException("Network: " + networkId + " and ACL: " + aclId + " do not belong to the same VPC");
-            }
-        }
-
-        return _networkAclMgr.replaceNetworkACL(acl, network);
-    }
-
-    @Override
-    public NetworkACLItem createNetworkACLItem(final CreateNetworkACLCmd aclItemCmd) {
-        final Account caller = CallContext.current().getCallingAccount();
-        Long aclId = aclItemCmd.getACLId();
-        if (aclId == null) {
-            //ACL id is not specified. Get the ACL details from network
-            if (aclItemCmd.getNetworkId() == null) {
-                throw new InvalidParameterValueException("Cannot create Network ACL Item. ACL Id or network Id is required");
-            }
-            final Network network = _networkMgr.getNetwork(aclItemCmd.getNetworkId());
-            if (network.getVpcId() == null) {
-                throw new InvalidParameterValueException("Network: " + network.getUuid() + " does not belong to VPC");
-            }
-            aclId = network.getNetworkACLId();
-
-            if (aclId == null) {
-                //Network is not associated with any ACL. Create a new ACL and add aclItem in it for backward compatibility
-                s_logger.debug("Network " + network.getId() + " is not associated with any ACL. Creating an ACL before adding acl item");
-
-                //verify that ACLProvider is supported by network offering
-                if (!_networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.NetworkACL)) {
-                    throw new InvalidParameterValueException("Network Offering does not support NetworkACL service");
-                }
-
-                final Vpc vpc = _entityMgr.findById(Vpc.class, network.getVpcId());
-                if (vpc == null) {
-                    throw new InvalidParameterValueException("Unable to find Vpc associated with the Network");
-                }
-
-                //Create new ACL
-                final String aclName = "VPC_" + vpc.getName() + "_Tier_" + network.getName() + "_ACL_" + network.getUuid();
-                final String description = "ACL for " + aclName;
-                final NetworkACL acl = _networkAclMgr.createNetworkACL(aclName, description, network.getVpcId(), aclItemCmd.getDisplay());
-                if (acl == null) {
-                    throw new CloudRuntimeException("Error while create ACL before adding ACL Item for network " + network.getId());
-                }
-                s_logger.debug("Created ACL: " + aclName + " for network " + network.getId());
-                aclId = acl.getId();
-                //Apply acl to network
-                try {
-                    if (!_networkAclMgr.replaceNetworkACL(acl, (NetworkVO)network)) {
-                        throw new CloudRuntimeException("Unable to apply auto created ACL to network " + network.getId());
-                    }
-                    s_logger.debug("Created ACL is applied to network " + network.getId());
-                } catch (final ResourceUnavailableException e) {
-                    throw new CloudRuntimeException("Unable to apply auto created ACL to network " + network.getId(), e);
-                }
-            }
-        }
-
-        final NetworkACL acl = _networkAclMgr.getNetworkACL(aclId);
-        if (acl == null) {
-            throw new InvalidParameterValueException("Unable to find specified ACL");
-        }
-
-        if (aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW) {
-            throw new InvalidParameterValueException("Default ACL cannot be modified");
-        }
-
-        final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
-        }
-        _accountMgr.checkAccess(caller, null, true, vpc);
-
-        //Ensure that number is unique within the ACL
-        if (aclItemCmd.getNumber() != null) {
-            if (_networkACLItemDao.findByAclAndNumber(aclId, aclItemCmd.getNumber()) != null) {
-                throw new InvalidParameterValueException("ACL item with number " + aclItemCmd.getNumber() + " already exists in ACL: " + acl.getUuid());
-            }
-        }
-
-        validateNetworkACLItem(aclItemCmd.getSourcePortStart(), aclItemCmd.getSourcePortEnd(), aclItemCmd.getSourceCidrList(), aclItemCmd.getProtocol(),
-                aclItemCmd.getIcmpCode(), aclItemCmd.getIcmpType(), aclItemCmd.getAction(), aclItemCmd.getNumber());
-
-        return _networkAclMgr.createNetworkACLItem(aclItemCmd.getSourcePortStart(), aclItemCmd.getSourcePortEnd(), aclItemCmd.getProtocol(),
-                aclItemCmd.getSourceCidrList(), aclItemCmd.getIcmpCode(), aclItemCmd.getIcmpType(), aclItemCmd.getTrafficType(), aclId, aclItemCmd.getAction(),
-                aclItemCmd.getNumber(), aclItemCmd.getDisplay());
-    }
-
-    private void validateNetworkACLItem(final Integer portStart, final Integer portEnd, final List<String> sourceCidrList, final String protocol, final Integer icmpCode, final Integer icmpType,
-            final String action, final Integer number) {
-
-        if (portStart != null && !NetUtils.isValidPort(portStart)) {
-            throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
-        }
-        if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
-            throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
-        }
-
-        // start port can't be bigger than end port
-        if (portStart != null && portEnd != null && portStart > portEnd) {
-            throw new InvalidParameterValueException("Start port can't be bigger than end port");
-        }
-
-        // start port and end port must be null for protocol = 'all'
-        if ((portStart != null || portEnd != null) && protocol != null && protocol.equalsIgnoreCase("all")) {
-            throw new InvalidParameterValueException("start port and end port must be null if protocol = 'all'");
-        }
-
-        if (sourceCidrList != null) {
-            for (final String cidr : sourceCidrList) {
-                if (!NetUtils.isValidIp4Cidr(cidr)) {
-                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr);
-                }
-            }
-        }
-
-        //Validate Protocol
-        if (protocol != null) {
-            //Check if protocol is a number
-            if (StringUtils.isNumeric(protocol)) {
-                final int protoNumber = Integer.parseInt(protocol);
-                if (protoNumber < 0 || protoNumber > 255) {
-                    throw new InvalidParameterValueException("Invalid protocol number: " + protoNumber);
-                }
-            } else {
-                //Protocol is not number
-                //Check for valid protocol strings
-                final String supportedProtocols = "tcp,udp,icmp,all";
-                if (!supportedProtocols.contains(protocol.toLowerCase())) {
-                    throw new InvalidParameterValueException("Invalid protocol: " + protocol);
-                }
-            }
-
-            // icmp code and icmp type can't be passed in for any other protocol rather than icmp
-            if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
-                throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
-            }
-
-            if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
-                throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
-            }
-        }
-
-        //validate icmp code and type
-        if (icmpType != null) {
-            if (icmpType.longValue() != -1 && !NetUtils.validateIcmpType(icmpType.longValue())) {
-                throw new InvalidParameterValueException("Invalid icmp type; should belong to [0-255] range");
-            }
-            if (icmpCode != null) {
-                if (icmpCode.longValue() != -1 && !NetUtils.validateIcmpCode(icmpCode.longValue())) {
-                    throw new InvalidParameterValueException("Invalid icmp code; should belong to [0-15] range and can"
-                            + " be defined when icmpType belongs to [0-40] range");
-                }
-            }
-        }
-
-        //Check ofr valid action Allow/Deny
-        if (action != null) {
-            if (!("Allow".equalsIgnoreCase(action) || "Deny".equalsIgnoreCase(action))) {
-                throw new InvalidParameterValueException("Invalid action. Allowed actions are Allow and Deny");
-            }
-        }
-
-        //Check for valid number
-        if (number != null && number < 1) {
-            throw new InvalidParameterValueException("Invalid number. Number cannot be < 1");
-        }
-    }
-
-    @Override
-    public NetworkACLItem getNetworkACLItem(final long ruleId) {
-        return _networkAclMgr.getNetworkACLItem(ruleId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "Applying Network ACL Item", async = true)
-    public boolean applyNetworkACL(final long aclId) throws ResourceUnavailableException {
-        return _networkAclMgr.applyNetworkACL(aclId);
-    }
-
-    @Override
-    public Pair<List<? extends NetworkACLItem>, Integer> listNetworkACLItems(final ListNetworkACLsCmd cmd) {
-        final Long networkId = cmd.getNetworkId();
-        final Long id = cmd.getId();
-        Long aclId = cmd.getAclId();
-        final String trafficType = cmd.getTrafficType();
-        final String protocol = cmd.getProtocol();
-        final String action = cmd.getAction();
-        final Map<String, String> tags = cmd.getTags();
-        final Account caller = CallContext.current().getCallingAccount();
-
-        final Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchBuilder<NetworkACLItemVO> sb = _networkACLItemDao.createSearchBuilder();
-
-        sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("aclId", sb.entity().getAclId(), Op.EQ);
-        sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
-        sb.and("protocol", sb.entity().getProtocol(), Op.EQ);
-        sb.and("action", sb.entity().getAction(), Op.EQ);
-
-        if (tags != null && !tags.isEmpty()) {
-            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (aclId == null) {
-            //Join with network_acl table when aclId is not specified to list acl_items within permitted VPCs
-            final SearchBuilder<NetworkACLVO> vpcSearch = _networkACLDao.createSearchBuilder();
-            vpcSearch.and("vpcId", vpcSearch.entity().getVpcId(), Op.IN);
-            sb.join("vpcSearch", vpcSearch, sb.entity().getAclId(), vpcSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<NetworkACLItemVO> sc = sb.create();
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (networkId != null) {
-            final Network network = _networkDao.findById(networkId);
-            aclId = network.getNetworkACLId();
-            if( aclId == null){
-                // No aclId associated with the network.
-                //Return empty list
-                return new Pair(new ArrayList<NetworkACLItem>(), 0);
-            }
-        }
-
-        if (trafficType != null) {
-            sc.setParameters("trafficType", trafficType);
-        }
-
-        if (aclId != null) {
-            // Get VPC and check access
-            final NetworkACL acl = _networkACLDao.findById(aclId);
-            if (acl.getVpcId() != 0) {
-                final Vpc vpc = _vpcDao.findById(acl.getVpcId());
-                if (vpc == null) {
-                    throw new InvalidParameterValueException("Unable to find VPC associated with acl");
-                }
-                _accountMgr.checkAccess(caller, null, true, vpc);
-            }
-            sc.setParameters("aclId", aclId);
-        } else {
-            //ToDo: Add accountId to network_acl_item table for permission check
-
-
-            // aclId is not specified
-            // List permitted VPCs and filter aclItems
-            final List<Long> permittedAccounts = new ArrayList<Long>();
-            Long domainId = cmd.getDomainId();
-            boolean isRecursive = cmd.isRecursive();
-            final String accountName = cmd.getAccountName();
-            final Long projectId = cmd.getProjectId();
-            final boolean listAll = cmd.listAll();
-            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
-                    ListProjectResourcesCriteria>(domainId, isRecursive, null);
-            _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject,
-                    listAll, false);
-            domainId = domainIdRecursiveListProject.first();
-            isRecursive = domainIdRecursiveListProject.second();
-            final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-            final SearchBuilder<VpcVO> sbVpc = _vpcDao.createSearchBuilder();
-            _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            final SearchCriteria<VpcVO> scVpc = sbVpc.create();
-            _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-            final List<VpcVO> vpcs = _vpcDao.search(scVpc, null);
-            final List<Long> vpcIds = new ArrayList<Long>();
-            for (final VpcVO vpc : vpcs) {
-                vpcIds.add(vpc.getId());
-            }
-            //Add vpc_id 0 to list acl_items in default ACL
-            vpcIds.add(0L);
-            sc.setJoinParameters("vpcSearch", "vpcId", vpcIds.toArray());
-        }
-
-        if (protocol != null) {
-            sc.setParameters("protocol", protocol);
-        }
-
-        if (action != null) {
-            sc.setParameters("action", action);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.NetworkACL.toString());
-            for (final String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        final Pair<List<NetworkACLItemVO>, Integer> result = _networkACLItemDao.searchAndCount(sc, filter);
-        final List<NetworkACLItemVO> aclItemVOs = result.first();
-        for (final NetworkACLItemVO item: aclItemVOs) {
-            _networkACLItemDao.loadCidrs(item);
-        }
-        return new Pair<List<? extends NetworkACLItem>, Integer>(aclItemVOs, result.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_DELETE, eventDescription = "Deleting Network ACL Item", async = true)
-    public boolean revokeNetworkACLItem(final long ruleId) {
-        final NetworkACLItemVO aclItem = _networkACLItemDao.findById(ruleId);
-        if(aclItem != null){
-            final NetworkACL acl = _networkAclMgr.getNetworkACL(aclItem.getAclId());
-
-            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-
-            if(aclItem.getAclId() == NetworkACL.DEFAULT_ALLOW || aclItem.getAclId() == NetworkACL.DEFAULT_DENY){
-                throw new InvalidParameterValueException("ACL Items in default ACL cannot be deleted");
-            }
-
-            final Account caller = CallContext.current().getCallingAccount();
-
-            _accountMgr.checkAccess(caller, null, true, vpc);
-
-        }
-        return _networkAclMgr.revokeNetworkACLItem(ruleId);
-    }
-
-    @Override
-    public NetworkACLItem updateNetworkACLItem(final Long id, final String protocol, final List<String> sourceCidrList, final NetworkACLItem.TrafficType trafficType, final String action,
-            final Integer number, final Integer sourcePortStart, final Integer sourcePortEnd, final Integer icmpCode, final Integer icmpType, final String newUUID, final Boolean forDisplay) throws ResourceUnavailableException {
-        final NetworkACLItemVO aclItem = _networkACLItemDao.findById(id);
-        if (aclItem == null) {
-            throw new InvalidParameterValueException("Unable to find ACL Item cannot be found");
-        }
-
-        if (aclItem.getAclId() == NetworkACL.DEFAULT_ALLOW || aclItem.getAclId() == NetworkACL.DEFAULT_DENY) {
-            throw new InvalidParameterValueException("Default ACL Items cannot be updated");
-        }
-
-        final NetworkACL acl = _networkAclMgr.getNetworkACL(aclItem.getAclId());
-
-        final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-
-        final Account caller = CallContext.current().getCallingAccount();
-
-        _accountMgr.checkAccess(caller, null, true, vpc);
-
-        if (number != null) {
-            //Check if ACL Item with specified number already exists
-            final NetworkACLItemVO aclNumber = _networkACLItemDao.findByAclAndNumber(acl.getId(), number);
-            if (aclNumber != null && aclNumber.getId() != id) {
-                throw new InvalidParameterValueException("ACL item with number " + number + " already exists in ACL: " + acl.getUuid());
-            }
-        }
-
-        validateNetworkACLItem(sourcePortStart == null ? aclItem.getSourcePortStart() : sourcePortStart, sourcePortEnd == null ? aclItem.getSourcePortEnd()
-                : sourcePortEnd, sourceCidrList, protocol, icmpCode, icmpType == null ? aclItem.getIcmpType() : icmpType, action, number);
-
-        return _networkAclMgr.updateNetworkACLItem(id, protocol, sourceCidrList, trafficType, action, number, sourcePortStart, sourcePortEnd, icmpCode, icmpType, newUUID, forDisplay);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_UPDATE, eventDescription = "updating network acl", async = true)
-    public NetworkACL updateNetworkACL(final Long id, final String customId, final Boolean forDisplay) {
-        final NetworkACLVO acl = _networkACLDao.findById(id);
-        final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
-        final Account caller = CallContext.current().getCallingAccount();
-        _accountMgr.checkAccess(caller, null, true, vpc);
-
-        if (customId != null) {
-            acl.setUuid(customId);
-        }
-
-        if (forDisplay != null) {
-            acl.setDisplay(forDisplay);
-        }
-
-        _networkACLDao.update(id, acl);
-        return _networkACLDao.findById(id);
-    }
-
-}
\ No newline at end of file
diff --git a/server/src/com/cloud/network/vpc/PrivateIpAddress.java b/server/src/com/cloud/network/vpc/PrivateIpAddress.java
deleted file mode 100644
index 8164428..0000000
--- a/server/src/com/cloud/network/vpc/PrivateIpAddress.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-public class PrivateIpAddress implements PrivateIp {
-    String broadcastUri;
-    String gateway;
-    String netmask;
-    String ipAddress;
-    String macAddress;
-    long networkId;
-    boolean sourceNat;
-
-    /**
-     * @param privateIp
-     * @param broadcastUri
-     * @param gateway
-     * @param netmask
-     * @param macAddress TODO
-     * @param physicalNetworkId TODO
-     */
-    public PrivateIpAddress(PrivateIpVO privateIp, String broadcastUri, String gateway, String netmask, String macAddress) {
-        super();
-        this.ipAddress = privateIp.getIpAddress();
-        this.broadcastUri = broadcastUri;
-        this.gateway = gateway;
-        this.netmask = netmask;
-        this.macAddress = macAddress;
-        this.networkId = privateIp.getNetworkId();
-        this.sourceNat = privateIp.getSourceNat();
-    }
-
-    @Override
-    public String getBroadcastUri() {
-        return broadcastUri;
-    }
-
-    @Override
-    public String getGateway() {
-        return gateway;
-    }
-
-    @Override
-    public String getNetmask() {
-        return netmask;
-    }
-
-    @Override
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    @Override
-    public String getMacAddress() {
-        return macAddress;
-    }
-
-    @Override
-    public long getNetworkId() {
-        return networkId;
-    }
-
-    @Override
-    public boolean getSourceNat() {
-        return sourceNat;
-    }
-}
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
deleted file mode 100644
index 548fb4d..0000000
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ /dev/null
@@ -1,2506 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpc;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
-import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkService;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.addr.PublicIp;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.element.VpcProvider;
-import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
-import com.cloud.network.vpc.VpcOffering.State;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.network.vpc.dao.StaticRouteDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.network.vpc.dao.VpcOfferingDao;
-import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
-import com.cloud.network.vpc.dao.VpcServiceMapDao;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.org.Grouping;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExceptionUtil;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.dao.DomainRouterDao;
-
-public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvisioningService, VpcService {
-    private static final Logger s_logger = Logger.getLogger(VpcManagerImpl.class);
-
-    public static final String SERVICE = "service";
-    public static final String CAPABILITYTYPE = "capabilitytype";
-    public static final String CAPABILITYVALUE = "capabilityvalue";
-    public static final String TRUE_VALUE = "true";
-    public static final String FALSE_VALUE = "false";
-
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    VpcOfferingDao _vpcOffDao;
-    @Inject
-    VpcOfferingServiceMapDao _vpcOffSvcMapDao;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    NetworkDao _ntwkDao;
-    @Inject
-    NetworkOrchestrationService _ntwkMgr;
-    @Inject
-    NetworkModel _ntwkModel;
-    @Inject
-    NetworkService _ntwkSvc;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    VpcGatewayDao _vpcGatewayDao;
-    @Inject
-    PrivateIpDao _privateIpDao;
-    @Inject
-    StaticRouteDao _staticRouteDao;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOffServiceDao;
-    @Inject
-    VpcOfferingServiceMapDao _vpcOffServiceDao;
-    @Inject
-    ResourceTagDao _resourceTagDao;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
-    Site2SiteVpnManager _s2sVpnMgr;
-    @Inject
-    VlanDao _vlanDao = null;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    VpcServiceMapDao _vpcSrvcDao;
-    @Inject
-    DataCenterDao _dcDao;
-    @Inject
-    NetworkACLDao _networkAclDao;
-    @Inject
-    NetworkACLManager _networkAclMgr;
-    @Inject
-    IpAddressManager _ipAddrMgr;
-    @Inject
-    VpcVirtualNetworkApplianceManager _routerService;
-    @Inject
-    DomainRouterDao _routerDao;
-
-    @Inject
-    private VpcPrivateGatewayTransactionCallable vpcTxCallable;
-
-    private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
-    private List<VpcProvider> vpcElements = null;
-    private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
-    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler,
-            Provider.JuniperContrailVpcRouter, Provider.Ovs, Provider.NuageVsp, Provider.BigSwitchBcf, Provider.ConfigDrive);
-
-    int _cleanupInterval;
-    int _maxNetworks;
-    SearchBuilder<IPAddressVO> IpAddressSearch;
-
-    protected final List<HypervisorType> hTypes = new ArrayList<HypervisorType>();
-
-    @PostConstruct
-    protected void setupSupportedVpcHypervisorsList() {
-        hTypes.add(HypervisorType.XenServer);
-        hTypes.add(HypervisorType.VMware);
-        hTypes.add(HypervisorType.KVM);
-        hTypes.add(HypervisorType.Simulator);
-        hTypes.add(HypervisorType.LXC);
-        hTypes.add(HypervisorType.Hyperv);
-        hTypes.add(HypervisorType.Ovm3);
-    }
-
-    @Override
-    @DB
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        // configure default vpc offering
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-
-                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
-                    s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
-
-                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
-                    final Set<Provider> defaultProviders = new HashSet<Provider>();
-                    defaultProviders.add(Provider.VPCVirtualRouter);
-                    for (final Service svc : getSupportedServices()) {
-                        if (svc == Service.Lb) {
-                            final Set<Provider> lbProviders = new HashSet<Provider>();
-                            lbProviders.add(Provider.VPCVirtualRouter);
-                            lbProviders.add(Provider.InternalLbVm);
-                            svcProviderMap.put(svc, lbProviders);
-                        } else {
-                            svcProviderMap.put(svc, defaultProviders);
-                        }
-                    }
-                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, false);
-                }
-
-                // configure default vpc offering with Netscaler as LB Provider
-                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName) == null) {
-                    s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
-                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
-                    final Set<Provider> defaultProviders = new HashSet<Provider>();
-                    defaultProviders.add(Provider.VPCVirtualRouter);
-                    for (final Service svc : getSupportedServices()) {
-                        if (svc == Service.Lb) {
-                            final Set<Provider> lbProviders = new HashSet<Provider>();
-                            lbProviders.add(Provider.Netscaler);
-                            lbProviders.add(Provider.InternalLbVm);
-                            svcProviderMap.put(svc, lbProviders);
-                        } else {
-                            svcProviderMap.put(svc, defaultProviders);
-                        }
-                    }
-                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false, false, false);
-
-                }
-
-                if (_vpcOffDao.findByUniqueName(VpcOffering.redundantVPCOfferingName) == null) {
-                    s_logger.debug("Creating Redundant VPC offering " + VpcOffering.redundantVPCOfferingName);
-
-                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
-                    final Set<Provider> defaultProviders = new HashSet<Provider>();
-                    defaultProviders.add(Provider.VPCVirtualRouter);
-                    for (final Service svc : getSupportedServices()) {
-                        if (svc == Service.Lb) {
-                            final Set<Provider> lbProviders = new HashSet<Provider>();
-                            lbProviders.add(Provider.VPCVirtualRouter);
-                            lbProviders.add(Provider.InternalLbVm);
-                            svcProviderMap.put(svc, lbProviders);
-                        } else {
-                            svcProviderMap.put(svc, defaultProviders);
-                        }
-                    }
-                    createVpcOffering(VpcOffering.redundantVPCOfferingName, VpcOffering.redundantVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, true);
-                }
-            }
-        });
-
-        final Map<String, String> configs = _configDao.getConfiguration(params);
-        final String value = configs.get(Config.VpcCleanupInterval.key());
-        _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60); // 1 hour
-
-        final String maxNtwks = configs.get(Config.VpcMaxNetworks.key());
-        _maxNetworks = NumbersUtil.parseInt(maxNtwks, 3); // max=3 is default
-
-        IpAddressSearch = _ipAddressDao.createSearchBuilder();
-        IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
-        IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
-        IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ);
-        IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ);
-        final SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
-        virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
-        IpAddressSearch
-        .join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
-        IpAddressSearch.done();
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        _executor.scheduleAtFixedRate(new VpcCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public List<? extends Network> getVpcNetworks(final long vpcId) {
-        return _ntwkDao.listByVpc(vpcId);
-    }
-
-    @Override
-    public VpcOffering getVpcOffering(final long vpcOffId) {
-        return _vpcOffDao.findById(vpcOffId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true)
-    public VpcOffering createVpcOffering(final String name, final String displayText, final List<String> supportedServices, final Map<String, List<String>> serviceProviders,
-            final Map serviceCapabilitystList, final Long serviceOfferingId) {
-
-        final Map<Network.Service, Set<Network.Provider>> svcProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
-        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
-        defaultProviders.add(Provider.VPCVirtualRouter);
-        // Just here for 4.1, replaced by commit 836ce6c1 in newer versions
-        final Set<Network.Provider> sdnProviders = new HashSet<Network.Provider>();
-        sdnProviders.add(Provider.NiciraNvp);
-        sdnProviders.add(Provider.JuniperContrailVpcRouter);
-        sdnProviders.add(Provider.NuageVsp);
-
-        boolean sourceNatSvc = false;
-        boolean firewallSvs = false;
-        // populate the services first
-        for (final String serviceName : supportedServices) {
-            // validate if the service is supported
-            final Service service = Network.Service.getService(serviceName);
-            if (service == null || nonSupportedServices.contains(service)) {
-                throw new InvalidParameterValueException("Service " + serviceName + " is not supported in VPC");
-            }
-
-            if (service == Service.Connectivity) {
-                s_logger.debug("Applying Connectivity workaround, setting provider to NiciraNvp");
-                svcProviderMap.put(service, sdnProviders);
-            } else {
-                svcProviderMap.put(service, defaultProviders);
-            }
-            if (service == Service.NetworkACL) {
-                firewallSvs = true;
-            }
-
-            if (service == Service.SourceNat) {
-                sourceNatSvc = true;
-            }
-        }
-
-        if (!sourceNatSvc) {
-            s_logger.debug("Automatically adding source nat service to the list of VPC services");
-            svcProviderMap.put(Service.SourceNat, defaultProviders);
-        }
-
-        if (!firewallSvs) {
-            s_logger.debug("Automatically adding network ACL service to the list of VPC services");
-            svcProviderMap.put(Service.NetworkACL, defaultProviders);
-        }
-
-        if (serviceProviders != null) {
-            for (final Entry<String, List<String>> serviceEntry : serviceProviders.entrySet()) {
-                final Network.Service service = Network.Service.getService(serviceEntry.getKey());
-                if (svcProviderMap.containsKey(service)) {
-                    final Set<Provider> providers = new HashSet<Provider>();
-                    for (final String prvNameStr : serviceEntry.getValue()) {
-                        // check if provider is supported
-                        final Network.Provider provider = Network.Provider.getProvider(prvNameStr);
-                        if (provider == null) {
-                            throw new InvalidParameterValueException("Invalid service provider: " + prvNameStr);
-                        }
-
-                        providers.add(provider);
-                    }
-                    svcProviderMap.put(service, providers);
-                } else {
-                    throw new InvalidParameterValueException("Service " + serviceEntry.getKey() + " is not enabled for the network " + "offering, can't add a provider to it");
-                }
-            }
-        }
-
-        // add gateway provider (if sourceNat provider is enabled)
-        final Set<Provider> sourceNatServiceProviders = svcProviderMap.get(Service.SourceNat);
-        if (CollectionUtils.isNotEmpty(sourceNatServiceProviders)) {
-            svcProviderMap.put(Service.Gateway, sourceNatServiceProviders);
-        }
-
-        validateConnectivtyServiceCapabilities(svcProviderMap.get(Service.Connectivity), serviceCapabilitystList);
-
-        final boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
-        final boolean offersRegionLevelVPC = isVpcOfferingForRegionLevelVpc(serviceCapabilitystList);
-        final boolean redundantRouter = isVpcOfferingRedundantRouter(serviceCapabilitystList);
-        final VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null, serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC,
-                redundantRouter);
-        CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
-
-        return offering;
-    }
-
-    @DB
-    protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
-            final boolean isDefault, final State state, final Long serviceOfferingId, final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC,
-            final boolean redundantRouter) {
-
-        return Transaction.execute(new TransactionCallback<VpcOffering>() {
-            @Override
-            public VpcOffering doInTransaction(final TransactionStatus status) {
-                // create vpc offering object
-                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC, redundantRouter);
-
-                if (state != null) {
-                    offering.setState(state);
-                }
-                s_logger.debug("Adding vpc offering " + offering);
-                offering = _vpcOffDao.persist(offering);
-                // populate services and providers
-                if (svcProviderMap != null) {
-                    for (final Network.Service service : svcProviderMap.keySet()) {
-                        final Set<Provider> providers = svcProviderMap.get(service);
-                        if (providers != null && !providers.isEmpty()) {
-                            for (final Network.Provider provider : providers) {
-                                final VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
-                                _vpcOffSvcMapDao.persist(offService);
-                                s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
-                            }
-                        } else {
-                            throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
-                        }
-                    }
-                }
-
-                return offering;
-            }
-        });
-    }
-
-    protected void checkCapabilityPerServiceProvider(final Set<Provider> providers, final Capability capability, final Service service) {
-        // TODO Shouldn't it fail it there are no providers?
-        if (providers != null) {
-            for (final Provider provider : providers) {
-                final NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
-                final Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
-                if (capabilities != null && !capabilities.isEmpty()) {
-                    final Map<Capability, String> connectivityCapabilities = capabilities.get(service);
-                    if (connectivityCapabilities == null || connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(capability)) {
-                        throw new InvalidParameterValueException(String.format("Provider %s does not support %s  capability.", provider.getName(), capability.getName()));
-                    }
-                }
-            }
-        }
-    }
-
-    private void validateConnectivtyServiceCapabilities(final Set<Provider> providers, final Map serviceCapabilitystList) {
-        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
-            final Collection serviceCapabilityCollection = serviceCapabilitystList.values();
-            final Iterator iter = serviceCapabilityCollection.iterator();
-
-            while (iter.hasNext()) {
-                final HashMap<String, String> svcCapabilityMap = (HashMap<String, String>) iter.next();
-                Capability capability = null;
-                final String svc = svcCapabilityMap.get(SERVICE);
-                final String capabilityName = svcCapabilityMap.get(CAPABILITYTYPE);
-                final String capabilityValue = svcCapabilityMap.get(CAPABILITYVALUE);
-                if (capabilityName != null) {
-                    capability = Capability.getCapability(capabilityName);
-                }
-
-                if (capability == null || capabilityValue == null) {
-                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
-                }
-                final Service usedService = Service.getService(svc);
-
-                checkCapabilityPerServiceProvider(providers, capability, usedService);
-
-                if (!capabilityValue.equalsIgnoreCase(TRUE_VALUE) && !capabilityValue.equalsIgnoreCase(FALSE_VALUE)) {
-                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
-                }
-            }
-        }
-    }
-
-    private boolean findCapabilityForService(final Map serviceCapabilitystList, final Capability capability, final Service service) {
-        boolean foundCapability = false;
-        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
-            final Iterator iter = serviceCapabilitystList.values().iterator();
-            while (iter.hasNext()) {
-                final HashMap<String, String> currentCapabilityMap = (HashMap<String, String>) iter.next();
-                final String currentCapabilityService = currentCapabilityMap.get(SERVICE);
-                final String currentCapabilityName = currentCapabilityMap.get(CAPABILITYTYPE);
-                final String currentCapabilityValue = currentCapabilityMap.get(CAPABILITYVALUE);
-
-                if (currentCapabilityName == null || currentCapabilityService == null || currentCapabilityValue == null) {
-                    throw new InvalidParameterValueException(String.format("Invalid capability with name %s, value %s and service %s", currentCapabilityName,
-                            currentCapabilityValue, currentCapabilityService));
-                }
-
-                if (currentCapabilityName.equalsIgnoreCase(capability.getName())) {
-                    foundCapability = currentCapabilityValue.equalsIgnoreCase(TRUE_VALUE);
-
-                    if (!currentCapabilityService.equalsIgnoreCase(service.getName())) {
-                        throw new InvalidParameterValueException(String.format("Invalid Service: %s specified. Capability %s can be specified only for service %s",
-                                currentCapabilityService, service.getName(), currentCapabilityName));
-                    }
-
-                    break;
-                }
-            }
-        }
-        return foundCapability;
-    }
-
-    private boolean isVpcOfferingForRegionLevelVpc(final Map serviceCapabilitystList) {
-        return findCapabilityForService(serviceCapabilitystList, Capability.RegionLevelVpc, Service.Connectivity);
-    }
-
-    private boolean isVpcOfferingSupportsDistributedRouter(final Map serviceCapabilitystList) {
-        return findCapabilityForService(serviceCapabilitystList, Capability.DistributedRouter, Service.Connectivity);
-    }
-
-    private boolean isVpcOfferingRedundantRouter(final Map serviceCapabilitystList) {
-        return findCapabilityForService(serviceCapabilitystList, Capability.RedundantRouter, Service.SourceNat);
-    }
-
-    @Override
-    public Vpc getActiveVpc(final long vpcId) {
-        return _vpcDao.getActiveVpcById(vpcId);
-    }
-
-    @Override
-    public Map<Service, Set<Provider>> getVpcOffSvcProvidersMap(final long vpcOffId) {
-        final Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
-        final List<VpcOfferingServiceMapVO> map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId);
-
-        for (final VpcOfferingServiceMapVO instance : map) {
-            final Service service = Service.getService(instance.getService());
-            Set<Provider> providers;
-            providers = serviceProviderMap.get(service);
-            if (providers == null) {
-                providers = new HashSet<Provider>();
-            }
-            providers.add(Provider.getProvider(instance.getProvider()));
-            serviceProviderMap.put(service, providers);
-        }
-
-        return serviceProviderMap;
-    }
-
-    @Override
-    public Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(final Long id, final String name, final String displayText, final List<String> supportedServicesStr,
-            final Boolean isDefault, final String keyword, final String state, final Long startIndex, final Long pageSizeVal) {
-        final Filter searchFilter = new Filter(VpcOfferingVO.class, "created", false, null, null);
-        final SearchCriteria<VpcOfferingVO> sc = _vpcOffDao.createSearchCriteria();
-
-        if (keyword != null) {
-            final SearchCriteria<VpcOfferingVO> ssc = _vpcOffDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-        }
-
-        if (displayText != null) {
-            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
-        }
-
-        if (isDefault != null) {
-            sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", SearchCriteria.Op.EQ, state);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        final List<VpcOfferingVO> offerings = _vpcOffDao.search(sc, searchFilter);
-
-        // filter by supported services
-        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty();
-
-        if (listBySupportedServices) {
-            final List<VpcOfferingVO> supportedOfferings = new ArrayList<VpcOfferingVO>();
-            Service[] supportedServices = null;
-
-            if (listBySupportedServices) {
-                supportedServices = new Service[supportedServicesStr.size()];
-                int i = 0;
-                for (final String supportedServiceStr : supportedServicesStr) {
-                    final Service service = Service.getService(supportedServiceStr);
-                    if (service == null) {
-                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
-                    } else {
-                        supportedServices[i] = service;
-                    }
-                    i++;
-                }
-            }
-
-            for (final VpcOfferingVO offering : offerings) {
-                if (areServicesSupportedByVpcOffering(offering.getId(), supportedServices)) {
-                    supportedOfferings.add(offering);
-                }
-            }
-
-            final List<? extends VpcOffering> wPagination = StringUtils.applyPagination(supportedOfferings, startIndex, pageSizeVal);
-            if (wPagination != null) {
-                final Pair<List<? extends VpcOffering>, Integer> listWPagination = new Pair<List<? extends VpcOffering>, Integer>(wPagination, supportedOfferings.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends VpcOffering>, Integer>(supportedOfferings, supportedOfferings.size());
-        } else {
-            final List<? extends VpcOffering> wPagination = StringUtils.applyPagination(offerings, startIndex, pageSizeVal);
-            if (wPagination != null) {
-                final Pair<List<? extends VpcOffering>, Integer> listWPagination = new Pair<List<? extends VpcOffering>, Integer>(wPagination, offerings.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends VpcOffering>, Integer>(offerings, offerings.size());
-        }
-    }
-
-    protected boolean areServicesSupportedByVpcOffering(final long vpcOffId, final Service... services) {
-        return _vpcOffSvcMapDao.areServicesSupportedByNetworkOffering(vpcOffId, services);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_DELETE, eventDescription = "deleting vpc offering")
-    public boolean deleteVpcOffering(final long offId) {
-        CallContext.current().setEventDetails(" Id: " + offId);
-
-        // Verify vpc offering id
-        final VpcOfferingVO offering = _vpcOffDao.findById(offId);
-        if (offering == null) {
-            throw new InvalidParameterValueException("unable to find vpc offering " + offId);
-        }
-
-        // Don't allow to delete default vpc offerings
-        if (offering.isDefault() == true) {
-            throw new InvalidParameterValueException("Default network offering can't be deleted");
-        }
-
-        // don't allow to delete vpc offering if it's in use by existing vpcs
-        // (the offering can be disabled though)
-        final int vpcCount = _vpcDao.getVpcCountByOfferingId(offId);
-        if (vpcCount > 0) {
-            throw new InvalidParameterValueException("Can't delete vpc offering " + offId + " as its used by " + vpcCount + " vpcs. "
-                    + "To make the network offering unavaiable, disable it");
-        }
-
-        if (_vpcOffDao.remove(offId)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_UPDATE, eventDescription = "updating vpc offering")
-    public VpcOffering updateVpcOffering(final long vpcOffId, final String vpcOfferingName, final String displayText, final String state) {
-        CallContext.current().setEventDetails(" Id: " + vpcOffId);
-
-        // Verify input parameters
-        final VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId);
-        if (offeringToUpdate == null) {
-            throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId);
-        }
-
-        final VpcOfferingVO offering = _vpcOffDao.createForUpdate(vpcOffId);
-
-        if (vpcOfferingName != null) {
-            offering.setName(vpcOfferingName);
-        }
-
-        if (displayText != null) {
-            offering.setDisplayText(displayText);
-        }
-
-        if (state != null) {
-            boolean validState = false;
-            for (final VpcOffering.State st : VpcOffering.State.values()) {
-                if (st.name().equalsIgnoreCase(state)) {
-                    validState = true;
-                    offering.setState(st);
-                }
-            }
-            if (!validState) {
-                throw new InvalidParameterValueException("Incorrect state value: " + state);
-            }
-        }
-
-        if (_vpcOffDao.update(vpcOffId, offering)) {
-            s_logger.debug("Updated VPC offeirng id=" + vpcOffId);
-            return _vpcOffDao.findById(vpcOffId);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create = true)
-    public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwnerId, final String vpcName, final String displayText, final String cidr, String networkDomain,
-            final Boolean displayVpc) throws ResourceAllocationException {
-        final Account caller = CallContext.current().getCallingAccount();
-        final Account owner = _accountMgr.getAccount(vpcOwnerId);
-
-        // Verify that caller can perform actions in behalf of vpc owner
-        _accountMgr.checkAccess(caller, null, false, owner);
-
-        // check resource limit
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.vpc);
-
-        // Validate vpc offering
-        final VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId);
-        if (vpcOff == null || vpcOff.getState() != State.Enabled) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find vpc offering in " + State.Enabled + " state by specified id");
-            if (vpcOff == null) {
-                ex.addProxyObject(String.valueOf(vpcOffId), "vpcOfferingId");
-            } else {
-                ex.addProxyObject(vpcOff.getUuid(), "vpcOfferingId");
-            }
-            throw ex;
-        }
-
-        final boolean isRegionLevelVpcOff = vpcOff.offersRegionLevelVPC();
-        if (isRegionLevelVpcOff && networkDomain == null) {
-            throw new InvalidParameterValueException("Network domain must be specified for region level VPC");
-        }
-
-        // Validate zone
-        final DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id specified");
-        }
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            // See DataCenterVO.java
-            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "zoneId");
-            throw ex;
-        }
-
-        if (networkDomain == null) {
-            // 1) Get networkDomain from the corresponding account
-            networkDomain = _ntwkModel.getAccountNetworkDomain(owner.getId(), zoneId);
-
-            // 2) If null, generate networkDomain using domain suffix from the
-            // global config variables
-            if (networkDomain == null) {
-                networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
-            }
-        }
-
-        final boolean useDistributedRouter = vpcOff.supportsDistributedRouter();
-        final VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, owner.getId(), owner.getDomainId(), vpcOffId, cidr, networkDomain, useDistributedRouter, isRegionLevelVpcOff,
-                vpcOff.getRedundantRouter());
-
-        return createVpc(displayVpc, vpc);
-    }
-
-    @DB
-    protected Vpc createVpc(final Boolean displayVpc, final VpcVO vpc) {
-        final String cidr = vpc.getCidr();
-        // Validate CIDR
-        if (!NetUtils.isValidIp4Cidr(cidr)) {
-            throw new InvalidParameterValueException("Invalid CIDR specified " + cidr);
-        }
-
-        // cidr has to be RFC 1918 complient
-        if (!NetUtils.validateGuestCidr(cidr)) {
-            throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant");
-        }
-
-        // validate network domain
-        if (!NetUtils.verifyDomainName(vpc.getNetworkDomain())) {
-            throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
-                    + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', " + "the digits '0' through '9', "
-                    + "and the hyphen ('-'); can't start or end with \"-\"");
-        }
-
-        return Transaction.execute(new TransactionCallback<VpcVO>() {
-            @Override
-            public VpcVO doInTransaction(final TransactionStatus status) {
-                if (displayVpc != null) {
-                    vpc.setDisplay(displayVpc);
-                }
-
-                final VpcVO persistedVpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(vpc.getZoneId(), vpc.getVpcOfferingId()));
-                _resourceLimitMgr.incrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
-                s_logger.debug("Created VPC " + persistedVpc);
-
-                return persistedVpc;
-            }
-        });
-    }
-
-    private Map<String, List<String>> finalizeServicesAndProvidersForVpc(final long zoneId, final long offeringId) {
-        final Map<String, List<String>> svcProviders = new HashMap<>();
-        final List<VpcOfferingServiceMapVO> servicesMap = _vpcOffSvcMapDao.listByVpcOffId(offeringId);
-
-        for (final VpcOfferingServiceMapVO serviceMap : servicesMap) {
-            final String service = serviceMap.getService();
-            String provider = serviceMap.getProvider();
-
-            if (provider == null) {
-                // Default to VPCVirtualRouter
-                provider = Provider.VPCVirtualRouter.getName();
-            }
-
-            if (!_ntwkModel.isProviderEnabledInZone(zoneId, provider)) {
-                throw new InvalidParameterValueException("Provider " + provider + " should be enabled in at least one physical network of the zone specified");
-            }
-
-            List<String> providers = null;
-            if (svcProviders.get(service) == null) {
-                providers = new ArrayList<String>();
-            } else {
-                providers = svcProviders.get(service);
-            }
-            providers.add(provider);
-            svcProviders.put(service, providers);
-        }
-
-        return svcProviders;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC")
-    public boolean deleteVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException {
-        CallContext.current().setEventDetails(" Id: " + vpcId);
-        final CallContext ctx = CallContext.current();
-
-        // Verify vpc id
-        final Vpc vpc = _vpcDao.findById(vpcId);
-        if (vpc == null) {
-            throw new InvalidParameterValueException("unable to find VPC id=" + vpcId);
-        }
-
-        // verify permissions
-        _accountMgr.checkAccess(ctx.getCallingAccount(), null, false, vpc);
-        _resourceTagDao.removeByIdAndType(vpcId, ResourceObjectType.Vpc);
-
-        return destroyVpc(vpc, ctx.getCallingAccount(), ctx.getCallingUserId());
-    }
-
-    @Override
-    @DB
-    public boolean destroyVpc(final Vpc vpc, final Account caller, final Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
-        s_logger.debug("Destroying vpc " + vpc);
-
-        // don't allow to delete vpc if it's in use by existing non system
-        // networks (system networks are networks of a private gateway of the
-        // VPC,
-        // and they will get removed as a part of VPC cleanup
-        final int networksCount = _ntwkDao.getNonSystemNetworkCountByVpcId(vpc.getId());
-        if (networksCount > 0) {
-            throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks");
-        }
-
-        // mark VPC as inactive
-        if (vpc.getState() != Vpc.State.Inactive) {
-            s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
-            final VpcVO vpcVO = _vpcDao.findById(vpc.getId());
-            vpcVO.setState(Vpc.State.Inactive);
-
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    _vpcDao.update(vpc.getId(), vpcVO);
-
-                    // decrement resource count
-                    _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
-                }
-            });
-        }
-
-        // shutdown VPC
-        if (!shutdownVpc(vpc.getId())) {
-            s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process");
-            return false;
-        }
-
-        // cleanup vpc resources
-        if (!cleanupVpcResources(vpc.getId(), caller, callerUserId)) {
-            s_logger.warn("Failed to cleanup resources for vpc " + vpc);
-            return false;
-        }
-
-        // update the instance with removed flag only when the cleanup is
-        // executed successfully
-        if (_vpcDao.remove(vpc.getId())) {
-            s_logger.debug("Vpc " + vpc + " is destroyed succesfully");
-            return true;
-        } else {
-            s_logger.warn("Vpc " + vpc + " failed to destroy");
-            return false;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc")
-    public Vpc updateVpc(final long vpcId, final String vpcName, final String displayText, final String customId, final Boolean displayVpc) {
-        CallContext.current().setEventDetails(" Id: " + vpcId);
-        final Account caller = CallContext.current().getCallingAccount();
-
-        // Verify input parameters
-        final VpcVO vpcToUpdate = _vpcDao.findById(vpcId);
-        if (vpcToUpdate == null) {
-            throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
-        }
-
-        _accountMgr.checkAccess(caller, null, false, vpcToUpdate);
-
-        final VpcVO vpc = _vpcDao.createForUpdate(vpcId);
-
-        if (vpcName != null) {
-            vpc.setName(vpcName);
-        }
-
-        if (displayText != null) {
-            vpc.setDisplayText(displayText);
-        }
-
-        if (customId != null) {
-            vpc.setUuid(customId);
-        }
-
-        if (displayVpc != null) {
-            vpc.setDisplay(displayVpc);
-        }
-
-        if (_vpcDao.update(vpcId, vpc)) {
-            s_logger.debug("Updated VPC id=" + vpcId);
-            return _vpcDao.findById(vpcId);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public Pair<List<? extends Vpc>, Integer> listVpcs(final Long id, final String vpcName, final String displayText, final List<String> supportedServicesStr, final String cidr,
-            final Long vpcOffId, final String state, final String accountName, Long domainId, final String keyword, final Long startIndex, final Long pageSizeVal,
-            final Long zoneId, Boolean isRecursive, final Boolean listAll, final Boolean restartRequired, final Map<String, String> tags, final Long projectId,
-            final Boolean display) {
-        final Account caller = CallContext.current().getCallingAccount();
-        final List<Long> permittedAccounts = new ArrayList<Long>();
-        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
-                null);
-        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        domainId = domainIdRecursiveListProject.first();
-        isRecursive = domainIdRecursiveListProject.second();
-        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        final Filter searchFilter = new Filter(VpcVO.class, "created", false, null, null);
-
-        final SearchBuilder<VpcVO> sb = _vpcDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("displayText", sb.entity().getDisplayText(), SearchCriteria.Op.LIKE);
-        sb.and("vpcOfferingId", sb.entity().getVpcOfferingId(), SearchCriteria.Op.EQ);
-        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ);
-        sb.and("cidr", sb.entity().getCidr(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
-
-        if (tags != null && !tags.isEmpty()) {
-            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        // now set the SC criteria...
-        final SearchCriteria<VpcVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (keyword != null) {
-            final SearchCriteria<VpcVO> ssc = _vpcDao.createSearchCriteria();
-            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (vpcName != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + vpcName + "%");
-        }
-
-        if (displayText != null) {
-            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Vpc.toString());
-            for (final Map.Entry<String, String> entry : tags.entrySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
-                count++;
-            }
-        }
-
-        if (display != null) {
-            sc.setParameters("display", display);
-        }
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (vpcOffId != null) {
-            sc.addAnd("vpcOfferingId", SearchCriteria.Op.EQ, vpcOffId);
-        }
-
-        if (zoneId != null) {
-            sc.addAnd("zoneId", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", SearchCriteria.Op.EQ, state);
-        }
-
-        if (cidr != null) {
-            sc.addAnd("cidr", SearchCriteria.Op.EQ, cidr);
-        }
-
-        if (restartRequired != null) {
-            sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
-        }
-
-        final List<VpcVO> vpcs = _vpcDao.search(sc, searchFilter);
-
-        // filter by supported services
-        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !vpcs.isEmpty();
-
-        if (listBySupportedServices) {
-            final List<VpcVO> supportedVpcs = new ArrayList<VpcVO>();
-            Service[] supportedServices = null;
-
-            if (listBySupportedServices) {
-                supportedServices = new Service[supportedServicesStr.size()];
-                int i = 0;
-                for (final String supportedServiceStr : supportedServicesStr) {
-                    final Service service = Service.getService(supportedServiceStr);
-                    if (service == null) {
-                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
-                    } else {
-                        supportedServices[i] = service;
-                    }
-                    i++;
-                }
-            }
-
-            for (final VpcVO vpc : vpcs) {
-                if (areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), supportedServices)) {
-                    supportedVpcs.add(vpc);
-                }
-            }
-
-            final List<? extends Vpc> wPagination = StringUtils.applyPagination(supportedVpcs, startIndex, pageSizeVal);
-            if (wPagination != null) {
-                final Pair<List<? extends Vpc>, Integer> listWPagination = new Pair<List<? extends Vpc>, Integer>(wPagination, supportedVpcs.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends Vpc>, Integer>(supportedVpcs, supportedVpcs.size());
-        } else {
-            final List<? extends Vpc> wPagination = StringUtils.applyPagination(vpcs, startIndex, pageSizeVal);
-            if (wPagination != null) {
-                final Pair<List<? extends Vpc>, Integer> listWPagination = new Pair<List<? extends Vpc>, Integer>(wPagination, vpcs.size());
-                return listWPagination;
-            }
-            return new Pair<List<? extends Vpc>, Integer>(vpcs, vpcs.size());
-        }
-    }
-
-    protected List<Service> getSupportedServices() {
-        final List<Service> services = new ArrayList<Service>();
-        services.add(Network.Service.Dhcp);
-        services.add(Network.Service.Dns);
-        services.add(Network.Service.UserData);
-        services.add(Network.Service.NetworkACL);
-        services.add(Network.Service.PortForwarding);
-        services.add(Network.Service.Lb);
-        services.add(Network.Service.SourceNat);
-        services.add(Network.Service.StaticNat);
-        services.add(Network.Service.Gateway);
-        services.add(Network.Service.Vpn);
-        return services;
-    }
-
-    @Override
-    public boolean startVpc(final long vpcId, final boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        final CallContext ctx = CallContext.current();
-        final Account caller = ctx.getCallingAccount();
-        final User callerUser = _accountMgr.getActiveUser(ctx.getCallingUserId());
-
-        // check if vpc exists
-        final Vpc vpc = getActiveVpc(vpcId);
-        if (vpc == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
-            ex.addProxyObject(String.valueOf(vpcId), "VPC");
-            throw ex;
-        }
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, false, vpc);
-
-        final DataCenter dc = _entityMgr.findById(DataCenter.class, vpc.getZoneId());
-
-        final DeployDestination dest = new DeployDestination(dc, null, null, null);
-        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, _accountMgr.getAccount(vpc.getAccountId()));
-
-        boolean result = true;
-        try {
-            if (!startVpc(vpc, dest, context)) {
-                s_logger.warn("Failed to start vpc " + vpc);
-                result = false;
-            }
-        } catch (final Exception ex) {
-            s_logger.warn("Failed to start vpc " + vpc + " due to ", ex);
-            result = false;
-        } finally {
-            // do cleanup
-            if (!result && destroyOnFailure) {
-                s_logger.debug("Destroying vpc " + vpc + " that failed to start");
-                if (destroyVpc(vpc, caller, callerUser.getId())) {
-                    s_logger.warn("Successfully destroyed vpc " + vpc + " that failed to start");
-                } else {
-                    s_logger.warn("Failed to destroy vpc " + vpc + " that failed to start");
-                }
-            }
-        }
-        return result;
-    }
-
-    protected boolean startVpc(final Vpc vpc, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-        // deploy provider
-        boolean success = true;
-        final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
-        for (final VpcProvider element : getVpcElements()) {
-            if (providersToImplement.contains(element.getProvider())) {
-                if (element.implementVpc(vpc, dest, context)) {
-                    s_logger.debug("Vpc " + vpc + " has started successfully");
-                } else {
-                    s_logger.warn("Vpc " + vpc + " failed to start");
-                    success = false;
-                }
-            }
-        }
-        return success;
-    }
-
-    @Override
-    public boolean shutdownVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException {
-        final CallContext ctx = CallContext.current();
-        final Account caller = ctx.getCallingAccount();
-
-        // check if vpc exists
-        final Vpc vpc = _vpcDao.findById(vpcId);
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
-        }
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, false, vpc);
-
-        // shutdown provider
-        s_logger.debug("Shutting down vpc " + vpc);
-        // TODO - shutdown all vpc resources here (ACLs, gateways, etc)
-
-        boolean success = true;
-        final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
-        final ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(ctx.getCallingUserId()), caller);
-        for (final VpcProvider element : getVpcElements()) {
-            if (providersToImplement.contains(element.getProvider())) {
-                if (element.shutdownVpc(vpc, context)) {
-                    s_logger.debug("Vpc " + vpc + " has been shutdown succesfully");
-                } else {
-                    s_logger.warn("Vpc " + vpc + " failed to shutdown");
-                    success = false;
-                }
-            }
-        }
-
-        return success;
-    }
-
-    @DB
-    @Override
-    public void validateNtwkOffForNtwkInVpc(final Long networkId, final long newNtwkOffId, final String newCidr, final String newNetworkDomain, final Vpc vpc,
-            final String gateway, final Account networkOwner, final Long aclId) {
-
-        final NetworkOffering guestNtwkOff = _entityMgr.findById(NetworkOffering.class, newNtwkOffId);
-
-        if (guestNtwkOff == null) {
-            throw new InvalidParameterValueException("Can't find network offering by id specified");
-        }
-
-        if (networkId == null) {
-            // 1) Validate attributes that has to be passed in when create new
-            // guest network
-            validateNewVpcGuestNetwork(newCidr, gateway, networkOwner, vpc, newNetworkDomain);
-        }
-
-        // 2) validate network offering attributes
-        final List<Service> svcs = _ntwkModel.listNetworkOfferingServices(guestNtwkOff.getId());
-        validateNtwkOffForVpc(guestNtwkOff, svcs);
-
-        // 3) Check services/providers against VPC providers
-        final List<NetworkOfferingServiceMapVO> networkProviders = _ntwkOffServiceDao.listByNetworkOfferingId(guestNtwkOff.getId());
-
-        for (final NetworkOfferingServiceMapVO nSvcVO : networkProviders) {
-            final String pr = nSvcVO.getProvider();
-            final String service = nSvcVO.getService();
-            if (_vpcOffServiceDao.findByServiceProviderAndOfferingId(service, pr, vpc.getVpcOfferingId()) == null) {
-                throw new InvalidParameterValueException("Service/provider combination " + service + "/" + pr + " is not supported by VPC " + vpc);
-            }
-        }
-
-        // 4) Only one network in the VPC can support public LB inside the VPC.
-        // Internal LB can be supported on multiple VPC tiers
-        if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb) && guestNtwkOff.getPublicLb()) {
-            final List<? extends Network> networks = getVpcNetworks(vpc.getId());
-            for (final Network network : networks) {
-                if (networkId != null && network.getId() == networkId.longValue()) {
-                    // skip my own network
-                    continue;
-                } else {
-                    final NetworkOffering otherOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-                    // throw only if networks have different offerings with
-                    // public lb support
-                    if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb) && otherOff.getPublicLb() && guestNtwkOff.getId() != otherOff.getId()) {
-                        throw new InvalidParameterValueException("Public LB service is already supported " + "by network " + network + " in VPC " + vpc);
-                    }
-                }
-            }
-        }
-
-        // 5) When aclId is provided, verify that ACLProvider is supported by
-        // network offering
-        if (aclId != null && !_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.NetworkACL)) {
-            throw new InvalidParameterValueException("Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
-        }
-
-    }
-
-    @Override
-    public void validateNtwkOffForVpc(final NetworkOffering guestNtwkOff, final List<Service> supportedSvcs) {
-        // 1) in current release, only vpc provider is supported by Vpc offering
-        final List<Provider> providers = _ntwkModel.getNtwkOffDistinctProviders(guestNtwkOff.getId());
-        for (final Provider provider : providers) {
-            if (!supportedProviders.contains(provider)) {
-                throw new InvalidParameterValueException("Provider of type " + provider.getName() + " is not supported for network offerings that can be used in VPC");
-            }
-        }
-
-        // 2) Only Isolated networks with Source nat service enabled can be
-        // added to vpc
-        if (!(guestNtwkOff.getGuestType() == GuestType.Isolated && supportedSvcs.contains(Service.SourceNat))) {
-
-            throw new InvalidParameterValueException("Only network offerings of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName()
-                    + " are valid for vpc ");
-        }
-
-        // 3) No redundant router support
-        /*
-         * TODO This should have never been hardcoded like this in the first
-         * place if (guestNtwkOff.getRedundantRouter()) { throw new
-         * InvalidParameterValueException
-         * ("No redunant router support when network belnogs to VPC"); }
-         */
-
-        // 4) Conserve mode should be off
-        if (guestNtwkOff.isConserveMode()) {
-            throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC");
-        }
-
-        // 5) If Netscaler is LB provider make sure it is in dedicated mode
-        if (providers.contains(Provider.Netscaler) && !guestNtwkOff.getDedicatedLB()) {
-            throw new InvalidParameterValueException("Netscaler only with Dedicated LB can belong to VPC");
-        }
-        return;
-    }
-
-    @DB
-    protected void validateNewVpcGuestNetwork(final String cidr, final String gateway, final Account networkOwner, final Vpc vpc, final String networkDomain) {
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                final Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
-                if (locked == null) {
-                    throw new CloudRuntimeException("Unable to acquire lock on " + vpc);
-                }
-
-                try {
-                    // check number of active networks in vpc
-                    if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) {
-                        throw new CloudRuntimeException("Number of networks per VPC can't extend " + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks);
-                    }
-
-                    // 1) CIDR is required
-                    if (cidr == null) {
-                        throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC");
-                    }
-
-                    // 2) Network cidr should be within vpcCidr
-                    if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) {
-                        throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr");
-                    }
-
-                    // 3) Network cidr shouldn't cross the cidr of other vpc
-                    // network cidrs
-                    final List<? extends Network> ntwks = _ntwkDao.listByVpc(vpc.getId());
-                    for (final Network ntwk : ntwks) {
-                        assert cidr != null : "Why the network cidr is null when it belongs to vpc?";
-
-                        if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr) || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) {
-                            throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + " belonging to the same vpc " + vpc);
-                        }
-                    }
-
-                    // 4) vpc and network should belong to the same owner
-                    if (vpc.getAccountId() != networkOwner.getId()) {
-                        throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + networkOwner);
-                    }
-
-                    // 5) network domain should be the same as VPC's
-                    if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) {
-                        throw new InvalidParameterValueException("Network domain of the new network should match network" + " domain of vpc " + vpc);
-                    }
-
-                    // 6) gateway should never be equal to the cidr subnet
-                    if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) {
-                        throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value");
-                    }
-                } finally {
-                    s_logger.debug("Releasing lock for " + locked);
-                    _vpcDao.releaseFromLockTable(locked.getId());
-                }
-            }
-        });
-    }
-
-    public List<VpcProvider> getVpcElements() {
-        if (vpcElements == null) {
-            vpcElements = new ArrayList<VpcProvider>();
-            vpcElements.add((VpcProvider) _ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName()));
-            vpcElements.add((VpcProvider) _ntwkModel.getElementImplementingProvider(Provider.JuniperContrailVpcRouter.getName()));
-        }
-
-        if (vpcElements == null) {
-            throw new CloudRuntimeException("Failed to initialize vpc elements");
-        }
-
-        return vpcElements;
-    }
-
-    @Override
-    public List<? extends Vpc> getVpcsForAccount(final long accountId) {
-        final List<Vpc> vpcs = new ArrayList<Vpc>();
-        vpcs.addAll(_vpcDao.listByAccountId(accountId));
-        return vpcs;
-    }
-
-    public boolean cleanupVpcResources(final long vpcId, final Account caller, final long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
-        s_logger.debug("Cleaning up resources for vpc id=" + vpcId);
-        boolean success = true;
-
-        // 1) Remove VPN connections and VPN gateway
-        s_logger.debug("Cleaning up existed site to site VPN connections");
-        _s2sVpnMgr.cleanupVpnConnectionByVpc(vpcId);
-        s_logger.debug("Cleaning up existed site to site VPN gateways");
-        _s2sVpnMgr.cleanupVpnGatewayByVpc(vpcId);
-
-        // 2) release all ip addresses
-        final List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null);
-        s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup");
-        for (final IPAddressVO ipToRelease : ipsToRelease) {
-            if (ipToRelease.isPortable()) {
-                // portable IP address are associated with owner, until
-                // explicitly requested to be disassociated.
-                // so as part of VPC clean up just break IP association with VPC
-                ipToRelease.setVpcId(null);
-                ipToRelease.setAssociatedWithNetworkId(null);
-                _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
-                s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any VPC");
-            } else {
-                success = success && _ipAddrMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
-                if (!success) {
-                    s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup");
-                }
-            }
-        }
-
-        if (success) {
-            s_logger.debug("Released ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
-        } else {
-            s_logger.warn("Failed to release ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
-            // although it failed, proceed to the next cleanup step as it
-            // doesn't depend on the public ip release
-        }
-
-        // 3) Delete all static route rules
-        if (!revokeStaticRoutesForVpc(vpcId, caller)) {
-            s_logger.warn("Failed to revoke static routes for vpc " + vpcId + " as a part of cleanup vpc process");
-            return false;
-        }
-
-        // 4) Delete private gateways
-        final List<PrivateGateway> gateways = getVpcPrivateGateways(vpcId);
-        if (gateways != null) {
-            for (final PrivateGateway gateway : gateways) {
-                if (gateway != null) {
-                    s_logger.debug("Deleting private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
-                    if (!deleteVpcPrivateGateway(gateway.getId())) {
-                        success = false;
-                        s_logger.debug("Failed to delete private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
-                    } else {
-                        s_logger.debug("Deleted private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
-                    }
-                }
-            }
-        }
-
-        //5) Delete ACLs
-        final SearchBuilder<NetworkACLVO> searchBuilder = _networkAclDao.createSearchBuilder();
-
-        searchBuilder.and("vpcId", searchBuilder.entity().getVpcId(), Op.IN);
-        final SearchCriteria<NetworkACLVO> searchCriteria = searchBuilder.create();
-        searchCriteria.setParameters("vpcId", vpcId, 0);
-
-        final Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null);
-        final Pair<List<NetworkACLVO>, Integer> aclsCountPair =  _networkAclDao.searchAndCount(searchCriteria, filter);
-
-        final List<NetworkACLVO> acls = aclsCountPair.first();
-        for (final NetworkACLVO networkAcl : acls) {
-            if (networkAcl.getId() != NetworkACL.DEFAULT_ALLOW && networkAcl.getId() != NetworkACL.DEFAULT_DENY) {
-                _networkAclMgr.deleteNetworkACL(networkAcl);
-            }
-        }
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc")
-    public boolean restartVpc(final long vpcId, final boolean cleanUp, final boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
-    InsufficientCapacityException {
-
-        final Account callerAccount = CallContext.current().getCallingAccount();
-        final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
-
-        // Verify input parameters
-        Vpc vpc = getActiveVpc(vpcId);
-        if (vpc == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
-            ex.addProxyObject(String.valueOf(vpcId), "VPC");
-            throw ex;
-        }
-
-        _accountMgr.checkAccess(callerAccount, null, false, vpc);
-
-        s_logger.debug("Restarting VPC " + vpc);
-        boolean restartRequired = false;
-        try {
-            boolean forceCleanup = cleanUp;
-            if (!vpc.isRedundant() && makeRedundant) {
-                final VpcOfferingVO redundantOffering = _vpcOffDao.findByUniqueName(VpcOffering.redundantVPCOfferingName);
-
-                final VpcVO entity = _vpcDao.findById(vpcId);
-                entity.setRedundant(true);
-                entity.setVpcOfferingId(redundantOffering.getId());
-
-                // Change the VPC in order to get it updated after the end of
-                // the restart procedure.
-                if (_vpcDao.update(vpc.getId(), entity)) {
-                    vpc = entity;
-                }
-
-                // If the offering and redundant column are changing, force the
-                // clean up.
-                forceCleanup = true;
-            }
-
-            if (forceCleanup) {
-                if (!rollingRestartVpc(vpc, context)) {
-                    s_logger.warn("Failed to execute a rolling restart as a part of VPC " + vpc + " restart process");
-                    restartRequired = true;
-                    return false;
-                }
-                return true;
-            }
-
-            s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process without cleanup");
-            if (!startVpc(vpcId, false)) {
-                s_logger.warn("Failed to start vpc as a part of VPC " + vpc + " restart process");
-                restartRequired = true;
-                return false;
-            }
-            s_logger.debug("VPC " + vpc + " was restarted successfully");
-            return true;
-        } finally {
-            s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired);
-            final VpcVO vo = _vpcDao.findById(vpcId);
-            vo.setRestartRequired(restartRequired);
-            _vpcDao.update(vpc.getId(), vo);
-        }
-    }
-
-    @Override
-    public List<PrivateGateway> getVpcPrivateGateways(final long vpcId) {
-        final List<VpcGatewayVO> gateways = _vpcGatewayDao.listByVpcIdAndType(vpcId, VpcGateway.Type.Private);
-
-        if (gateways != null) {
-            final List<PrivateGateway> pvtGateway = new ArrayList<PrivateGateway>();
-            for (final VpcGatewayVO gateway : gateways) {
-                pvtGateway.add(getPrivateGatewayProfile(gateway));
-            }
-            return pvtGateway;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public PrivateGateway getVpcPrivateGateway(final long id) {
-        final VpcGateway gateway = _vpcGatewayDao.findById(id);
-
-        if (gateway == null || gateway.getType() != VpcGateway.Type.Private) {
-            return null;
-        }
-        return getPrivateGatewayProfile(gateway);
-    }
-
-    protected PrivateGateway getPrivateGatewayProfile(final VpcGateway gateway) {
-        final Network network = _ntwkModel.getNetwork(gateway.getNetworkId());
-        return new PrivateGatewayProfile(gateway, network.getPhysicalNetworkId());
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating VPC private gateway", create = true)
-    public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway,
-            final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId) throws ResourceAllocationException,
-            ConcurrentOperationException, InsufficientCapacityException {
-
-        // Validate parameters
-        final Vpc vpc = getActiveVpc(vpcId);
-        if (vpc == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
-            ex.addProxyObject(String.valueOf(vpcId), "VPC");
-            throw ex;
-        }
-
-        PhysicalNetwork physNet = null;
-        // Validate physical network
-        if (physicalNetworkId == null) {
-            final List<? extends PhysicalNetwork> pNtwks = _ntwkModel.getPhysicalNtwksSupportingTrafficType(vpc.getZoneId(), TrafficType.Guest);
-            if (pNtwks.isEmpty() || pNtwks.size() != 1) {
-                throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id");
-            }
-            physNet = pNtwks.get(0);
-            physicalNetworkId = physNet.getId();
-        }
-
-        if (physNet == null) {
-            physNet = _entityMgr.findById(PhysicalNetwork.class, physicalNetworkId);
-        }
-        final Long dcId = physNet.getDataCenterId();
-
-        final Long physicalNetworkIdFinal = physicalNetworkId;
-        final PhysicalNetwork physNetFinal = physNet;
-        VpcGatewayVO gatewayVO = null;
-        try {
-            gatewayVO = Transaction.execute(new TransactionCallbackWithException<VpcGatewayVO, Exception>() {
-                @Override
-                public VpcGatewayVO doInTransaction(final TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException,
-                InsufficientCapacityException {
-                    s_logger.debug("Creating Private gateway for VPC " + vpc);
-                    // 1) create private network unless it is existing and
-                    // lswitch'd
-                    Network privateNtwk = null;
-                    if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
-                        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
-                        privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, gatewayOwnerId, dcId, networkOfferingId);
-                        // if the dcid is different we get no network so next we
-                        // try to create it
-                    }
-                    if (privateNtwk == null) {
-                        s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
-                        final String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
-                        privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, broadcastUri, ipAddress, null, gateway, netmask,
-                                gatewayOwnerId, vpcId, isSourceNat, networkOfferingId);
-                    } else { // create the nic/ip as createPrivateNetwork
-                        // doesn''t do that work for us now
-                        s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
-                        final DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
-
-                        // add entry to private_ip_address table
-                        PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
-                        if (privateIp != null) {
-                            throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + " in zone "
-                                    + _entityMgr.findById(DataCenter.class, dcId).getName());
-                        }
-
-                        final Long mac = dc.getMacAddress();
-                        final Long nextMac = mac + 1;
-                        dc.setMacAddress(nextMac);
-
-                        s_logger.info("creating private ip address for vpc (" + ipAddress + ", " + privateNtwk.getId() + ", " + nextMac + ", " + vpcId + ", " + isSourceNat + ")");
-                        privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, isSourceNat);
-                        _privateIpDao.persist(privateIp);
-
-                        _dcDao.update(dc.getId(), dc);
-                    }
-
-                    long networkAclId = NetworkACL.DEFAULT_DENY;
-                    if (aclId != null) {
-                        final NetworkACLVO aclVO = _networkAclDao.findById(aclId);
-                        if (aclVO == null) {
-                            throw new InvalidParameterValueException("Invalid network acl id passed ");
-                        }
-                        if (aclVO.getVpcId() != vpcId && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
-                            throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
-                        }
-
-                        networkAclId = aclId;
-                    }
-
-                    { // experimental block, this is a hack
-                        // set vpc id in network to null
-                        // might be needed for all types of broadcast domains
-                        // the ugly hack is that vpc gateway nets are created as
-                        // guest network
-                        // while they are not.
-                        // A more permanent solution would be to define a type of
-                        // 'gatewaynetwork'
-                        // so that handling code is not mixed between the two
-                        final NetworkVO gatewaynet = _ntwkDao.findById(privateNtwk.getId());
-                        gatewaynet.setVpcId(null);
-                        _ntwkDao.persist(gatewaynet);
-                    }
-
-                    // 2) create gateway entry
-                    final VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), privateNtwk.getId(), broadcastUri,
-                            gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
-                    _vpcGatewayDao.persist(gatewayVO);
-
-                    s_logger.debug("Created vpc gateway entry " + gatewayVO);
-
-                    return gatewayVO;
-                }
-            });
-        } catch (final Exception e) {
-            ExceptionUtil.rethrowRuntime(e);
-            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
-            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
-            throw new IllegalStateException(e);
-        }
-
-        CallContext.current().setEventDetails("Private Gateway Id: " + gatewayVO.getId());
-        return getVpcPrivateGateway(gatewayVO.getId());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "Applying VPC private gateway", async = true)
-    public PrivateGateway applyVpcPrivateGateway(final long gatewayId, final boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException {
-        final VpcGatewayVO vo = _vpcGatewayDao.findById(gatewayId);
-
-        boolean success = true;
-        try {
-            final List<Provider> providersToImplement = getVpcProviders(vo.getVpcId());
-
-            final PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
-            for (final VpcProvider provider : getVpcElements()) {
-                if (providersToImplement.contains(provider.getProvider())) {
-                    if (!provider.createPrivateGateway(gateway)) {
-                        success = false;
-                    }
-                }
-            }
-            if (success) {
-                s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
-                if (vo.getState() != VpcGateway.State.Ready) {
-                    vo.setState(VpcGateway.State.Ready);
-                    _vpcGatewayDao.update(vo.getId(), vo);
-                    s_logger.debug("Marke gateway " + gateway + " with state " + VpcGateway.State.Ready);
-                }
-                CallContext.current().setEventDetails("Private Gateway Id: " + gatewayId);
-                return getVpcPrivateGateway(gatewayId);
-            } else {
-                s_logger.warn("Private gateway " + gateway + " failed to apply on the backend");
-                return null;
-            }
-        } finally {
-            // do cleanup
-            if (!success) {
-                if (destroyOnFailure) {
-                    s_logger.debug("Destroying private gateway " + vo + " that failed to start");
-                    // calling deleting from db because on createprivategateway
-                    // fail, destroyPrivateGateway is already called
-                    if (deletePrivateGatewayFromTheDB(getVpcPrivateGateway(gatewayId))) {
-                        s_logger.warn("Successfully destroyed vpc " + vo + " that failed to start");
-                    } else {
-                        s_logger.warn("Failed to destroy vpc " + vo + " that failed to start");
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway")
-    @DB
-    public boolean deleteVpcPrivateGateway(final long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException {
-        final VpcGatewayVO gatewayToBeDeleted = _vpcGatewayDao.findById(gatewayId);
-        if (gatewayToBeDeleted == null) {
-            s_logger.debug("VPC gateway is already deleted for id=" + gatewayId);
-            return true;
-        }
-
-        final VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
-        if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) {
-            throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId);
-        }
-
-        try {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    // don't allow to remove gateway when there are static
-                    // routes associated with it
-                    final long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
-                    if (routeCount > 0) {
-                        throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount
-                                + " static routes applied. Remove the routes first");
-                    }
-
-                    gatewayVO.setState(VpcGateway.State.Deleting);
-                    _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
-                    s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
-                }
-            });
-
-            // 1) delete the gateway on the backend
-            final List<Provider> providersToImplement = getVpcProviders(gatewayVO.getVpcId());
-            final PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
-            for (final VpcProvider provider : getVpcElements()) {
-                if (providersToImplement.contains(provider.getProvider())) {
-                    if (provider.deletePrivateGateway(gateway)) {
-                        s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
-                    } else {
-                        s_logger.warn("Private gateway " + gateway + " failed to apply on the backend");
-                        gatewayVO.setState(VpcGateway.State.Ready);
-                        _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
-                        s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Ready);
-
-                        return false;
-                    }
-                }
-            }
-
-            // 2) Delete private gateway from the DB
-            return deletePrivateGatewayFromTheDB(gateway);
-
-        } finally {
-            if (gatewayVO != null) {
-                _vpcGatewayDao.releaseFromLockTable(gatewayId);
-            }
-        }
-    }
-
-    @DB
-    protected boolean deletePrivateGatewayFromTheDB(final PrivateGateway gateway) {
-        // check if there are ips allocted in the network
-        final long networkId = gateway.getNetworkId();
-
-        vpcTxCallable.setGateway(gateway);
-
-        final ExecutorService txExecutor = Executors.newSingleThreadExecutor();
-        final Future<Boolean> futureResult = txExecutor.submit(vpcTxCallable);
-
-        boolean deleteNetworkFinal;
-        try {
-            deleteNetworkFinal = futureResult.get();
-            if (deleteNetworkFinal) {
-                final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-                final Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
-                final ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
-                _ntwkMgr.destroyNetwork(networkId, context, false);
-                s_logger.debug("Deleted private network id=" + networkId);
-            }
-        } catch (final InterruptedException e) {
-            s_logger.error("deletePrivateGatewayFromTheDB failed to delete network id " + networkId + "due to => ", e);
-        } catch (final ExecutionException e) {
-            s_logger.error("deletePrivateGatewayFromTheDB failed to delete network id " + networkId + "due to => ", e);
-        }
-
-        return true;
-    }
-
-    @Override
-    public Pair<List<PrivateGateway>, Integer> listPrivateGateway(final ListPrivateGatewaysCmd cmd) {
-        final String ipAddress = cmd.getIpAddress();
-        final String vlan = cmd.getVlan();
-        final Long vpcId = cmd.getVpcId();
-        final Long id = cmd.getId();
-        Boolean isRecursive = cmd.isRecursive();
-        final Boolean listAll = cmd.listAll();
-        Long domainId = cmd.getDomainId();
-        final String accountName = cmd.getAccountName();
-        final Account caller = CallContext.current().getCallingAccount();
-        final List<Long> permittedAccounts = new ArrayList<Long>();
-        final String state = cmd.getState();
-        final Long projectId = cmd.getProjectId();
-
-        final Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
-                null);
-        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        domainId = domainIdRecursiveListProject.first();
-        isRecursive = domainIdRecursiveListProject.second();
-        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
-        final SearchBuilder<VpcGatewayVO> sb = _vpcGatewayDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        if (vlan != null) {
-            final SearchBuilder<NetworkVO> ntwkSearch = _ntwkDao.createSearchBuilder();
-            ntwkSearch.and("vlan", ntwkSearch.entity().getBroadcastUri(), SearchCriteria.Op.EQ);
-            sb.join("networkSearch", ntwkSearch, sb.entity().getNetworkId(), ntwkSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<VpcGatewayVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        if (id != null) {
-            sc.addAnd("id", Op.EQ, id);
-        }
-
-        if (ipAddress != null) {
-            sc.addAnd("ip4Address", Op.EQ, ipAddress);
-        }
-
-        if (state != null) {
-            sc.addAnd("state", Op.EQ, state);
-        }
-
-        if (vpcId != null) {
-            sc.addAnd("vpcId", Op.EQ, vpcId);
-        }
-
-        if (vlan != null) {
-            sc.setJoinParameters("networkSearch", "vlan", BroadcastDomainType.Vlan.toUri(vlan));
-        }
-
-        final Pair<List<VpcGatewayVO>, Integer> vos = _vpcGatewayDao.searchAndCount(sc, searchFilter);
-        final List<PrivateGateway> privateGtws = new ArrayList<PrivateGateway>(vos.first().size());
-        for (final VpcGateway vo : vos.first()) {
-            privateGtws.add(getPrivateGatewayProfile(vo));
-        }
-
-        return new Pair<List<PrivateGateway>, Integer>(privateGtws, vos.second());
-    }
-
-    @Override
-    public StaticRoute getStaticRoute(final long routeId) {
-        return _staticRouteDao.findById(routeId);
-    }
-
-    @Override
-    public boolean applyStaticRoutesForVpc(final long vpcId) throws ResourceUnavailableException {
-        final Account caller = CallContext.current().getCallingAccount();
-        final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(vpcId);
-        return applyStaticRoutes(routes, caller, true);
-    }
-
-    protected boolean applyStaticRoutes(final List<? extends StaticRoute> routes, final Account caller, final boolean updateRoutesInDB) throws ResourceUnavailableException {
-        final boolean success = true;
-        final List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
-        final Map<Long, VpcGateway> gatewayMap = new HashMap<Long, VpcGateway>();
-        for (final StaticRoute route : routes) {
-            VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId());
-            if (gateway == null) {
-                gateway = _vpcGatewayDao.findById(route.getVpcGatewayId());
-                gatewayMap.put(gateway.getId(), gateway);
-            }
-            staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
-        }
-        if (!applyStaticRoutes(staticRouteProfiles)) {
-            s_logger.warn("Routes are not completely applied");
-            return false;
-        } else {
-            if (updateRoutesInDB) {
-                for (final StaticRoute route : routes) {
-                    if (route.getState() == StaticRoute.State.Revoke) {
-                        _staticRouteDao.remove(route.getId());
-                        s_logger.debug("Removed route " + route + " from the DB");
-                    } else if (route.getState() == StaticRoute.State.Add) {
-                        final StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId());
-                        ruleVO.setState(StaticRoute.State.Active);
-                        _staticRouteDao.update(ruleVO.getId(), ruleVO);
-                        s_logger.debug("Marked route " + route + " with state " + StaticRoute.State.Active);
-                    }
-                }
-            }
-        }
-
-        return success;
-    }
-
-    protected boolean applyStaticRoutes(final List<StaticRouteProfile> routes) throws ResourceUnavailableException {
-        if (routes.isEmpty()) {
-            s_logger.debug("No static routes to apply");
-            return true;
-        }
-        final Vpc vpc = _vpcDao.findById(routes.get(0).getVpcId());
-
-        s_logger.debug("Applying static routes for vpc " + vpc);
-        final String staticNatProvider = _vpcSrvcDao.getProviderForServiceInVpc(vpc.getId(), Service.StaticNat);
-
-        for (final VpcProvider provider : getVpcElements()) {
-            if (!(provider instanceof StaticNatServiceProvider && provider.getName().equalsIgnoreCase(staticNatProvider))) {
-                continue;
-            }
-
-            if (provider.applyStaticRoutes(vpc, routes)) {
-                s_logger.debug("Applied static routes for vpc " + vpc);
-            } else {
-                s_logger.warn("Failed to apply static routes for vpc " + vpc);
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_DELETE, eventDescription = "deleting static route")
-    public boolean revokeStaticRoute(final long routeId) throws ResourceUnavailableException {
-        final Account caller = CallContext.current().getCallingAccount();
-
-        final StaticRouteVO route = _staticRouteDao.findById(routeId);
-        if (route == null) {
-            throw new InvalidParameterValueException("Unable to find static route by id");
-        }
-
-        _accountMgr.checkAccess(caller, null, false, route);
-
-        markStaticRouteForRevoke(route, caller);
-
-        return applyStaticRoutesForVpc(route.getVpcId());
-    }
-
-    @DB
-    protected boolean revokeStaticRoutesForVpc(final long vpcId, final Account caller) throws ResourceUnavailableException {
-        // get all static routes for the vpc
-        final List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
-        s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId);
-        if (!routes.isEmpty()) {
-            // mark all of them as revoke
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    for (final StaticRouteVO route : routes) {
-                        markStaticRouteForRevoke(route, caller);
-                    }
-                }
-            });
-            return applyStaticRoutesForVpc(vpcId);
-        }
-
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create = true)
-    public StaticRoute createStaticRoute(final long gatewayId, final String cidr) throws NetworkRuleConflictException {
-        final Account caller = CallContext.current().getCallingAccount();
-
-        // parameters validation
-        final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
-        if (gateway == null) {
-            throw new InvalidParameterValueException("Invalid gateway id is given");
-        }
-
-        if (gateway.getState() != VpcGateway.State.Ready) {
-            throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState());
-        }
-
-        final Vpc vpc = getActiveVpc(gateway.getVpcId());
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
-        }
-        _accountMgr.checkAccess(caller, null, false, vpc);
-
-        if (!NetUtils.isValidIp4Cidr(cidr)) {
-            throw new InvalidParameterValueException("Invalid format for cidr " + cidr);
-        }
-
-        // validate the cidr
-        // 1) CIDR should be outside of VPC cidr for guest networks
-        if (NetUtils.isNetworksOverlap(vpc.getCidr(), cidr)) {
-            throw new InvalidParameterValueException("CIDR should be outside of VPC cidr " + vpc.getCidr());
-        }
-
-        // 2) CIDR should be outside of link-local cidr
-        if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
-            throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR());
-        }
-
-        // 3) Verify against blacklisted routes
-        if (isCidrBlacklisted(cidr, vpc.getZoneId())) {
-            throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
-        }
-
-        return Transaction.execute(new TransactionCallbackWithException<StaticRouteVO, NetworkRuleConflictException>() {
-            @Override
-            public StaticRouteVO doInTransaction(final TransactionStatus status) throws NetworkRuleConflictException {
-                StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
-                s_logger.debug("Adding static route " + newRoute);
-                newRoute = _staticRouteDao.persist(newRoute);
-
-                detectRoutesConflict(newRoute);
-
-                if (!_staticRouteDao.setStateToAdd(newRoute)) {
-                    throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
-                }
-                CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
-
-                return newRoute;
-            }
-        });
-    }
-
-    protected boolean isCidrBlacklisted(final String cidr, final long zoneId) {
-        final String routesStr = NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
-        if (routesStr != null && !routesStr.isEmpty()) {
-            final String[] cidrBlackList = routesStr.split(",");
-
-            if (cidrBlackList != null && cidrBlackList.length > 0) {
-                for (final String blackListedRoute : cidrBlackList) {
-                    if (NetUtils.isNetworksOverlap(blackListedRoute, cidr)) {
-                        return true;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(final ListStaticRoutesCmd cmd) {
-        final Long id = cmd.getId();
-        final Long gatewayId = cmd.getGatewayId();
-        final Long vpcId = cmd.getVpcId();
-        Long domainId = cmd.getDomainId();
-        Boolean isRecursive = cmd.isRecursive();
-        final Boolean listAll = cmd.listAll();
-        final String accountName = cmd.getAccountName();
-        final Account caller = CallContext.current().getCallingAccount();
-        final List<Long> permittedAccounts = new ArrayList<Long>();
-        final Map<String, String> tags = cmd.getTags();
-        final Long projectId = cmd.getProjectId();
-
-        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
-                null);
-        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
-        domainId = domainIdRecursiveListProject.first();
-        isRecursive = domainIdRecursiveListProject.second();
-        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        final Filter searchFilter = new Filter(StaticRouteVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        final SearchBuilder<StaticRouteVO> sb = _staticRouteDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
-        sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ);
-
-        if (tags != null && !tags.isEmpty()) {
-            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<StaticRouteVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        if (id != null) {
-            sc.addAnd("id", Op.EQ, id);
-        }
-
-        if (vpcId != null) {
-            sc.addAnd("vpcId", Op.EQ, vpcId);
-        }
-
-        if (gatewayId != null) {
-            sc.addAnd("vpcGatewayId", Op.EQ, gatewayId);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.StaticRoute.toString());
-            for (final String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        final Pair<List<StaticRouteVO>, Integer> result = _staticRouteDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends StaticRoute>, Integer>(result.first(), result.second());
-    }
-
-    protected void detectRoutesConflict(final StaticRoute newRoute) throws NetworkRuleConflictException {
-        // Multiple private gateways can exist within Vpc. Check for conflicts
-        // for all static routes in Vpc
-        // and not just the gateway
-        final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcIdAndNotRevoked(newRoute.getVpcId());
-        assert routes.size() >= 1 : "For static routes, we now always first persist the route and then check for "
-                + "network conflicts so we should at least have one rule at this point.";
-
-        for (final StaticRoute route : routes) {
-            if (route.getId() == newRoute.getId()) {
-                continue; // Skips my own route.
-            }
-
-            if (NetUtils.isNetworksOverlap(route.getCidr(), newRoute.getCidr())) {
-                throw new NetworkRuleConflictException("New static route cidr conflicts with existing route " + route);
-            }
-        }
-    }
-
-    protected void markStaticRouteForRevoke(final StaticRouteVO route, final Account caller) {
-        s_logger.debug("Revoking static route " + route);
-        if (caller != null) {
-            _accountMgr.checkAccess(caller, null, false, route);
-        }
-
-        if (route.getState() == StaticRoute.State.Staged) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found a static route that is still in stage state so just removing it: " + route);
-            }
-            _staticRouteDao.remove(route.getId());
-        } else if (route.getState() == StaticRoute.State.Add || route.getState() == StaticRoute.State.Active) {
-            route.setState(StaticRoute.State.Revoke);
-            _staticRouteDao.update(route.getId(), route);
-            s_logger.debug("Marked static route " + route + " with state " + StaticRoute.State.Revoke);
-        }
-    }
-
-    protected class VpcCleanupTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                final GlobalLock lock = GlobalLock.getInternLock("VpcCleanup");
-                if (lock == null) {
-                    s_logger.debug("Couldn't get the global lock");
-                    return;
-                }
-
-                if (!lock.lock(30)) {
-                    s_logger.debug("Couldn't lock the db");
-                    return;
-                }
-
-                try {
-                    // Cleanup inactive VPCs
-                    final List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
-                    if (inactiveVpcs != null) {
-                        s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
-                        for (final VpcVO vpc : inactiveVpcs) {
-                            s_logger.debug("Cleaning up " + vpc);
-                            destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
-                        }
-                    }
-                } catch (final Exception e) {
-                    s_logger.error("Exception ", e);
-                } finally {
-                    lock.unlock();
-                }
-            } catch (final Exception e) {
-                s_logger.error("Exception ", e);
-            }
-        }
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
-    public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException,
-    ConcurrentOperationException {
-        final Account caller = CallContext.current().getCallingAccount();
-        Account owner = null;
-
-        final IpAddress ipToAssoc = _ntwkModel.getIp(ipId);
-        if (ipToAssoc != null) {
-            _accountMgr.checkAccess(caller, null, true, ipToAssoc);
-            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
-        } else {
-            s_logger.debug("Unable to find ip address by id: " + ipId);
-            return null;
-        }
-
-        final Vpc vpc = _vpcDao.findById(vpcId);
-        if (vpc == null) {
-            throw new InvalidParameterValueException("Invalid VPC id provided");
-        }
-
-        // check permissions
-        _accountMgr.checkAccess(caller, null, true, owner, vpc);
-
-        s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc);
-
-        final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(owner.getId(), vpcId) == null;
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                final IPAddressVO ip = _ipAddressDao.findById(ipId);
-                // update ip address with networkId
-                ip.setVpcId(vpcId);
-                ip.setSourceNat(isSourceNatFinal);
-
-                _ipAddressDao.update(ipId, ip);
-
-                // mark ip as allocated
-                _ipAddrMgr.markPublicIpAsAllocated(ip);
-            }
-        });
-
-        s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc);
-
-        return _ipAddressDao.findById(ipId);
-    }
-
-    @Override
-    public void unassignIPFromVpcNetwork(final long ipId, final long networkId) {
-        final IPAddressVO ip = _ipAddressDao.findById(ipId);
-        if (isIpAllocatedToVpc(ip)) {
-            return;
-        }
-
-        if (ip == null || ip.getVpcId() == null) {
-            return;
-        }
-
-        s_logger.debug("Releasing VPC ip address " + ip + " from vpc network id=" + networkId);
-
-        final long vpcId = ip.getVpcId();
-        boolean success = false;
-        try {
-            // unassign ip from the VPC router
-            success = _ipAddrMgr.applyIpAssociations(_ntwkModel.getNetwork(networkId), true);
-        } catch (final ResourceUnavailableException ex) {
-            throw new CloudRuntimeException("Failed to apply ip associations for network id=" + networkId + " as a part of unassigning ip " + ipId + " from vpc", ex);
-        }
-
-        if (success) {
-            ip.setAssociatedWithNetworkId(null);
-            _ipAddressDao.update(ipId, ip);
-            s_logger.debug("IP address " + ip + " is no longer associated with the network inside vpc id=" + vpcId);
-        } else {
-            throw new CloudRuntimeException("Failed to apply ip associations for network id=" + networkId + " as a part of unassigning ip " + ipId + " from vpc");
-        }
-        s_logger.debug("Successfully released VPC ip address " + ip + " back to VPC pool ");
-    }
-
-    @Override
-    public boolean isIpAllocatedToVpc(final IpAddress ip) {
-        return ip != null && ip.getVpcId() != null && (ip.isOneToOneNat() || !_firewallDao.listByIp(ip.getId()).isEmpty());
-    }
-
-    @DB
-    @Override
-    public Network createVpcGuestNetwork(final long ntwkOffId, final String name, final String displayText, final String gateway, final String cidr, final String vlanId,
-            String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, final Boolean subdomainAccess,
-            final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
-            ResourceAllocationException {
-
-        final Vpc vpc = getActiveVpc(vpcId);
-
-        if (vpc == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC ");
-            ex.addProxyObject(String.valueOf(vpcId), "VPC");
-            throw ex;
-        }
-        _accountMgr.checkAccess(caller, null, false, vpc);
-
-        if (networkDomain == null) {
-            networkDomain = vpc.getNetworkDomain();
-        }
-
-        if (!vpc.isRegionLevelVpc() && vpc.getZoneId() != zoneId) {
-            throw new InvalidParameterValueException("New network doesn't belong to vpc zone");
-        }
-
-        // 1) Validate if network can be created for VPC
-        validateNtwkOffForNtwkInVpc(null, ntwkOffId, cidr, networkDomain, vpc, gateway, owner, aclId);
-
-        // 2) Create network
-        final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
-                                                                 subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null, externalId);
-
-        if (guestNetwork != null) {
-            guestNetwork.setNetworkACLId(aclId);
-            _ntwkDao.update(guestNetwork.getId(), (NetworkVO) guestNetwork);
-        }
-        return guestNetwork;
-    }
-
-    protected IPAddressVO getExistingSourceNatInVpc(final long ownerId, final long vpcId) {
-
-        final List<IPAddressVO> addrs = listPublicIpsAssignedToVpc(ownerId, true, vpcId);
-
-        IPAddressVO sourceNatIp = null;
-        if (addrs.isEmpty()) {
-            return null;
-        } else {
-            // Account already has ip addresses
-            for (final IPAddressVO addr : addrs) {
-                if (addr.isSourceNat()) {
-                    sourceNatIp = addr;
-                    return sourceNatIp;
-                }
-            }
-
-            assert sourceNatIp != null : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; vpcId=" + vpcId;
-        }
-
-        return sourceNatIp;
-    }
-
-    protected List<IPAddressVO> listPublicIpsAssignedToVpc(final long accountId, final Boolean sourceNat, final long vpcId) {
-        final SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("vpcId", vpcId);
-
-        if (sourceNat != null) {
-            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
-        }
-        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
-
-        return _ipAddressDao.search(sc, null);
-    }
-
-    @Override
-    public PublicIp assignSourceNatIpAddressToVpc(final Account owner, final Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException {
-        final long dcId = vpc.getZoneId();
-
-        final IPAddressVO sourceNatIp = getExistingSourceNatInVpc(owner.getId(), vpc.getId());
-
-        PublicIp ipToReturn = null;
-
-        if (sourceNatIp != null) {
-            ipToReturn = PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
-        } else {
-            ipToReturn = _ipAddrMgr.assignDedicateIpAddress(owner, null, vpc.getId(), dcId, true);
-        }
-
-        return ipToReturn;
-    }
-
-    @Override
-    public List<HypervisorType> getSupportedVpcHypervisors() {
-        return Collections.unmodifiableList(hTypes);
-    }
-
-    private List<Provider> getVpcProviders(final long vpcId) {
-        final List<String> providerNames = _vpcSrvcDao.getDistinctProviders(vpcId);
-        final Map<String, Provider> providers = new HashMap<String, Provider>();
-        for (final String providerName : providerNames) {
-            if (!providers.containsKey(providerName)) {
-                providers.put(providerName, Network.Provider.getProvider(providerName));
-            }
-        }
-
-        return new ArrayList<Provider>(providers.values());
-    }
-
-    @Inject
-    public void setVpcElements(final List<VpcProvider> vpcElements) {
-        this.vpcElements = vpcElements;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "Applying static route", async = true)
-    public boolean applyStaticRoute(final long routeId) throws ResourceUnavailableException {
-        final StaticRoute route = _staticRouteDao.findById(routeId);
-        return applyStaticRoutesForVpc(route.getVpcId());
-    }
-
-    @Override
-    public boolean isSrcNatIpRequired(long vpcOfferingId) {
-        final Map<Network.Service, Set<Network.Provider>> vpcOffSvcProvidersMap = getVpcOffSvcProvidersMap(vpcOfferingId);
-        return vpcOffSvcProvidersMap.get(Network.Service.SourceNat).contains(Network.Provider.VPCVirtualRouter);
-    }
-
-    /**
-     * rollingRestartVpc performs restart of routers of a VPC by first
-     * deploying a new VR and then destroying old VRs in rolling fashion. For
-     * non-redundant VPC, it will re-program the new router as final step
-     * otherwise deploys a backup router for the VPC.
-     * @param vpc vpc to be restarted
-     * @param context reservation context
-     * @return returns true when the rolling restart succeeds
-     * @throws ResourceUnavailableException
-     * @throws ConcurrentOperationException
-     * @throws InsufficientCapacityException
-     */
-    private boolean rollingRestartVpc(final Vpc vpc, final ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
-        if (!NetworkOrchestrationService.RollingRestartEnabled.value()) {
-            if (shutdownVpc(vpc.getId())) {
-                return startVpc(vpc.getId(), false);
-            }
-            s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process");
-            return false;
-        }
-        s_logger.debug("Performing rolling restart of routers of VPC " + vpc);
-        _ntwkMgr.destroyExpendableRouters(_routerDao.listByVpcId(vpc.getId()), context);
-
-        final DeployDestination dest = new DeployDestination(_dcDao.findById(vpc.getZoneId()), null, null, null);
-        final List<DomainRouterVO> oldRouters = _routerDao.listByVpcId(vpc.getId());
-
-        // Create a new router
-        if (oldRouters.size() > 0) {
-            vpc.setRollingRestart(true);
-        }
-        startVpc(vpc, dest, context);
-        if (oldRouters.size() > 0) {
-            vpc.setRollingRestart(false);
-        }
-
-        // For redundant vpc wait for 3*advert_int+skew_seconds for VRRP to kick in
-        if (vpc.isRedundant() || (oldRouters.size() == 1 && oldRouters.get(0).getIsRedundantRouter())) {
-            try {
-                Thread.sleep(NetworkOrchestrationService.RVRHandoverTime);
-            } catch (final InterruptedException ignored) {
-            }
-        }
-
-        // Destroy old routers
-        for (final DomainRouterVO oldRouter : oldRouters) {
-            _routerService.stopRouter(oldRouter.getId(), true);
-            _routerService.destroyRouter(oldRouter.getId(), context.getAccount(), context.getCaller().getId());
-        }
-
-        // Re-program VPC VR or add a new backup router for redundant VPC
-        if (!startVpc(vpc, dest, context)) {
-            s_logger.debug("Failed to re-program VPC router or deploy a new backup router for VPC" + vpc);
-            return false;
-        }
-
-        return _ntwkMgr.areRoutersRunning(_routerDao.listByVpcId(vpc.getId()));
-    }
-
-}
diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java
deleted file mode 100644
index a8dd225..0000000
--- a/server/src/com/cloud/projects/ProjectManagerImpl.java
+++ /dev/null
@@ -1,1055 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.projects;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Random;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.mail.Authenticator;
-import javax.mail.Message.RecipientType;
-import javax.mail.MessagingException;
-import javax.mail.PasswordAuthentication;
-import javax.mail.Session;
-import javax.mail.URLName;
-import javax.mail.internet.InternetAddress;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.sun.mail.smtp.SMTPMessage;
-import com.sun.mail.smtp.SMTPSSLTransport;
-import com.sun.mail.smtp.SMTPTransport;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.dao.ProjectAccountJoinDao;
-import com.cloud.api.query.dao.ProjectInvitationJoinDao;
-import com.cloud.api.query.dao.ProjectJoinDao;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.projects.Project.State;
-import com.cloud.projects.ProjectAccount.Role;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.projects.dao.ProjectDao;
-import com.cloud.projects.dao.ProjectInvitationDao;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.DomainManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-@Component
-public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
-    public static final Logger s_logger = Logger.getLogger(ProjectManagerImpl.class);
-    private EmailInvite _emailInvite;
-
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private ProjectDao _projectDao;
-    @Inject
-    private ProjectJoinDao _projectJoinDao;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    DomainManager _domainMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    private ProjectAccountDao _projectAccountDao;
-    @Inject
-    private ProjectAccountJoinDao _projectAccountJoinDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private ProjectInvitationDao _projectInvitationDao;
-    @Inject
-    private ProjectInvitationJoinDao _projectInvitationJoinDao;
-    @Inject
-    protected ResourceTagDao _resourceTagDao;
-
-    protected boolean _invitationRequired = false;
-    protected long _invitationTimeOut = 86400000;
-    protected boolean _allowUserToCreateProject = true;
-    protected ScheduledExecutorService _executor;
-    protected int _projectCleanupExpInvInterval = 60; //Interval defining how often project invitation cleanup thread is running
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        Map<String, String> configs = _configDao.getConfiguration(params);
-        _invitationRequired = Boolean.valueOf(configs.get(Config.ProjectInviteRequired.key()));
-
-        String value = configs.get(Config.ProjectInvitationExpirationTime.key());
-        _invitationTimeOut = Long.parseLong(value != null ? value : "86400") * 1000;
-        _allowUserToCreateProject = Boolean.valueOf(configs.get(Config.AllowUserToCreateProject.key()));
-
-        // set up the email system for project invitations
-
-        String smtpHost = configs.get("project.smtp.host");
-        int smtpPort = NumbersUtil.parseInt(configs.get("project.smtp.port"), 25);
-        String useAuthStr = configs.get("project.smtp.useAuth");
-        boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
-        String smtpUsername = configs.get("project.smtp.username");
-        String smtpPassword = configs.get("project.smtp.password");
-        String emailSender = configs.get("project.email.sender");
-        String smtpDebugStr = configs.get("project.smtp.debug");
-        boolean smtpDebug = false;
-        if (smtpDebugStr != null) {
-            smtpDebug = Boolean.parseBoolean(smtpDebugStr);
-        }
-
-        _emailInvite = new EmailInvite(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
-        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Project-ExpireInvitations"));
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        _executor.scheduleWithFixedDelay(new ExpiredInvitationsCleanup(), _projectCleanupExpInvInterval, _projectCleanupExpInvInterval, TimeUnit.SECONDS);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create = true)
-    @DB
-    public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = caller;
-
-        //check if the user authorized to create the project
-        if (_accountMgr.isNormalUser(caller.getId()) && !_allowUserToCreateProject) {
-            throw new PermissionDeniedException("Regular user is not permitted to create a project");
-        }
-
-        //Verify request parameters
-        if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
-            throw new InvalidParameterValueException("Account name and domain id must be specified together");
-        }
-
-        if (accountName != null) {
-            owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
-        }
-
-        //don't allow 2 projects with the same name inside the same domain
-        if (_projectDao.findByNameAndDomain(name, owner.getDomainId()) != null) {
-            throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId());
-        }
-
-        //do resource limit check
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
-
-        final Account ownerFinal = owner;
-        return Transaction.execute(new TransactionCallback<Project>() {
-            @Override
-            public Project doInTransaction(TransactionStatus status) {
-
-        //Create an account associated with the project
-        StringBuilder acctNm = new StringBuilder("PrjAcct-");
-                acctNm.append(name).append("-").append(ownerFinal.getDomainId());
-
-        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, null, domainId, null, null, UUID.randomUUID().toString());
-
-                Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
-
-        //assign owner to the project
-                assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
-
-        if (project != null) {
-            CallContext.current().setEventDetails("Project id=" + project.getId());
-            CallContext.current().putContextParameter(Project.class, project.getUuid());
-        }
-
-        //Increment resource count
-                _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
-
-        return project;
-    }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async = true)
-    @DB
-    public Project enableProject(long projectId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        ProjectVO project = getProject(projectId);
-        //verify input parameters
-        if (project == null) {
-            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        //at this point enabling project doesn't require anything, so just update the state
-        project.setState(State.Active);
-        _projectDao.update(projectId, project);
-
-        return project;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
-    public boolean deleteProject(long projectId) {
-        CallContext ctx = CallContext.current();
-
-        ProjectVO project = getProject(projectId);
-        //verify input parameters
-        if (project == null) {
-            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-        }
-
-        _accountMgr.checkAccess(ctx.getCallingAccount(), AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
-    }
-
-    @DB
-    @Override
-    public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) {
-        //mark project as inactive first, so you can't add resources to it
-        boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-        s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
-        project.setState(State.Disabled);
-        boolean updateResult = _projectDao.update(project.getId(), project);
-        //owner can be already removed at this point, so adding the conditional check
-        Account projectOwner = getProjectOwner(project.getId());
-        if (projectOwner != null) {
-            _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
-        }
-
-                return updateResult;
-            }
-        });
-
-        if (updateResult) {
-            //pass system caller when clenaup projects account
-            if (!cleanupProject(project, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM)) {
-                s_logger.warn("Failed to cleanup project's id=" + project.getId() + " resources, not removing the project yet");
-                return false;
-            } else {
-                return _projectDao.remove(project.getId());
-            }
-        } else {
-            s_logger.warn("Failed to mark the project id=" + project.getId() + " with state " + State.Disabled);
-            return false;
-        }
-    }
-
-    @DB
-    private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) {
-        boolean result = true;
-        //Delete project's account
-        AccountVO account = _accountDao.findById(project.getProjectAccountId());
-        s_logger.debug("Deleting projects " + project + " internal account id=" + account.getId() + " as a part of project cleanup...");
-
-        result = result && _accountMgr.deleteAccount(account, callerUserId, caller);
-
-        if (result) {
-            //Unassign all users from the project
-            result = Transaction.execute(new TransactionCallback<Boolean>() {
-                @Override
-                public Boolean doInTransaction(TransactionStatus status) {
-                    boolean result = true;
-            s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
-            List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
-            for (ProjectAccount projectAccount : projectAccounts) {
-                result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
-            }
-
-            s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
-            _projectInvitationDao.cleanupInvitations(project.getId());
-
-                    return result;
-                }
-            });
-            if (result) {
-                s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
-            }
-        } else {
-            s_logger.warn("Failed to cleanup project's internal account");
-        }
-
-        return result;
-    }
-
-    @Override
-    public boolean unassignAccountFromProject(long projectId, long accountId) {
-        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
-        if (projectAccount == null) {
-            s_logger.debug("Account id=" + accountId + " is not assigned to project id=" + projectId + " so no need to unassign");
-            return true;
-        }
-
-        if (_projectAccountDao.remove(projectAccount.getId())) {
-            return true;
-        } else {
-            s_logger.warn("Failed to unassign account id=" + accountId + " from the project id=" + projectId);
-            return false;
-        }
-    }
-
-    @Override
-    public ProjectVO getProject(long projectId) {
-        return _projectDao.findById(projectId);
-    }
-
-    @Override
-    public long getInvitationTimeout() {
-        return _invitationTimeOut;
-    }
-
-    @Override
-    public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole) {
-        return _projectAccountDao.persist(new ProjectAccountVO(project, accountId, accountRole));
-    }
-
-    @Override
-    @DB
-    public boolean deleteAccountFromProject(final long projectId, final long accountId) {
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-        boolean success = true;
-
-        //remove account
-        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
-        success = _projectAccountDao.remove(projectAccount.getId());
-
-        //remove all invitations for account
-        if (success) {
-            s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
-            ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
-            if (invite != null) {
-                success = success && _projectInvitationDao.remove(invite.getId());
-            }
-        }
-
-        return success;
-    }
-        });
-    }
-
-    @Override
-    public Account getProjectOwner(long projectId) {
-        ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId);
-        if (prAcct != null) {
-            return _accountMgr.getAccount(prAcct.getAccountId());
-        }
-
-        return null;
-    }
-
-    @Override
-    public ProjectVO findByProjectAccountId(long projectAccountId) {
-        return _projectDao.findByProjectAccountId(projectAccountId);
-    }
-
-    @Override
-    public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) {
-        return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId);
-    }
-
-    @Override
-    public Project findByNameAndDomainId(String name, long domainId) {
-        return _projectDao.findByNameAndDomain(name, domainId);
-    }
-
-    @Override
-    public boolean canAccessProjectAccount(Account caller, long accountId) {
-        //ROOT admin always can access the project
-        if (_accountMgr.isRootAdmin(caller.getId())) {
-            return true;
-        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
-            Account owner = _accountMgr.getAccount(accountId);
-            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
-            return true;
-        }
-
-        return _projectAccountDao.canAccessProjectAccount(caller.getId(), accountId);
-    }
-
-    @Override
-    public boolean canModifyProjectAccount(Account caller, long accountId) {
-        //ROOT admin always can access the project
-        if (_accountMgr.isRootAdmin(caller.getId())) {
-            return true;
-        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
-            Account owner = _accountMgr.getAccount(accountId);
-            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
-            return true;
-        }
-        return _projectAccountDao.canModifyProjectAccount(caller.getId(), accountId);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
-    public Project updateProject(final long projectId, final String displayText, final String newOwnerName) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check that the project exists
-        final ProjectVO project = getProject(projectId);
-
-        if (project == null) {
-            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
-        }
-
-        //verify permissions
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
-        if (displayText != null) {
-            project.setDisplayText(displayText);
-            _projectDao.update(projectId, project);
-        }
-
-        if (newOwnerName != null) {
-            //check that the new owner exists
-            Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
-            if (futureOwnerAccount == null) {
-                throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
-            }
-            Account currentOwnerAccount = getProjectOwner(projectId);
-            if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
-                ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
-                if (futureOwner == null) {
-                            throw new InvalidParameterValueException("Account " + newOwnerName +
-                                " doesn't belong to the project. Add it to the project first and then change the project's ownership");
-                }
-
-                //do resource limit check
-                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
-
-                //unset the role for the old owner
-                ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
-                currentOwner.setAccountRole(Role.Regular);
-                _projectAccountDao.update(currentOwner.getId(), currentOwner);
-                _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
-
-                //set new owner
-                futureOwner.setAccountRole(Role.Admin);
-                _projectAccountDao.update(futureOwner.getId(), futureOwner);
-                _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
-
-            } else {
-                s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
-            }
-        }
-            }
-        });
-
-        return _projectDao.findById(projectId);
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true)
-    public boolean addAccountToProject(long projectId, String accountName, String email) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check that the project exists
-        Project project = getProject(projectId);
-
-        if (project == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
-            ex.addProxyObject(String.valueOf(projectId), "projectId");
-            throw ex;
-        }
-
-        //User can be added to Active project only
-        if (project.getState() != Project.State.Active) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active");
-            ex.addProxyObject(project.getUuid(), "projectId");
-            throw ex;
-        }
-
-        //check that account-to-add exists
-        Account account = null;
-        if (accountName != null) {
-            account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
-            if (account == null) {
-                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id");
-                DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
-                String domainUuid = String.valueOf(project.getDomainId());
-                if (domain != null) {
-                    domainUuid = domain.getUuid();
-                }
-                ex.addProxyObject(domainUuid, "domainId");
-                throw ex;
-            }
-
-            //verify permissions - only project owner can assign
-            _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-            //Check if the account already added to the project
-            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
-            if (projectAccount != null) {
-                s_logger.debug("Account " + accountName + " already added to the project id=" + projectId);
-                return true;
-            }
-        }
-
-        if (_invitationRequired) {
-            return inviteAccountToProject(project, account, email);
-        } else {
-            if (account == null) {
-                throw new InvalidParameterValueException("Account information is required for assigning account to the project");
-            }
-            if (assignAccountToProject(project, account.getId(), ProjectAccount.Role.Regular) != null) {
-                return true;
-            } else {
-                s_logger.warn("Failed to add account " + accountName + " to project id=" + projectId);
-                return false;
-            }
-        }
-    }
-
-    private boolean inviteAccountToProject(Project project, Account account, String email) {
-        if (account != null) {
-            if (createAccountInvitation(project, account.getId()) != null) {
-                return true;
-            } else {
-                s_logger.warn("Failed to generate invitation for account " + account.getAccountName() + " to project id=" + project);
-                return false;
-            }
-        }
-
-        if (email != null) {
-            //generate the token
-            String token = generateToken(10);
-            if (generateTokenBasedInvitation(project, email, token) != null) {
-                return true;
-            } else {
-                s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project);
-                return false;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async = true)
-    public boolean deleteAccountFromProject(long projectId, String accountName) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check that the project exists
-        Project project = getProject(projectId);
-
-        if (project == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
-            ex.addProxyObject(String.valueOf(projectId), "projectId");
-            throw ex;
-        }
-
-        //check that account-to-remove exists
-        Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
-        if (account == null) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
-            DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
-            String domainUuid = String.valueOf(project.getDomainId());
-            if (domain != null) {
-                domainUuid = domain.getUuid();
-            }
-            ex.addProxyObject(domainUuid, "domainId");
-            throw ex;
-        }
-
-        //verify permissions
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        //Check if the account exists in the project
-        ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
-        if (projectAccount == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id");
-            // Use the projectVO object and not the projectAccount object to inject the projectId.
-            ex.addProxyObject(project.getUuid(), "projectId");
-            throw ex;
-        }
-
-        //can't remove the owner of the project
-        if (projectAccount.getAccountRole() == Role.Admin) {
-            InvalidParameterValueException ex =
-                new InvalidParameterValueException("Unable to delete account " + accountName +
-                    " from the project with specified id as the account is the owner of the project");
-            ex.addProxyObject(project.getUuid(), "projectId");
-            throw ex;
-        }
-
-        return deleteAccountFromProject(projectId, account.getId());
-    }
-
-    public ProjectInvitation createAccountInvitation(Project project, Long accountId) {
-        if (activeInviteExists(project, accountId, null)) {
-            throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project);
-        }
-
-        ProjectInvitation invitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null));
-
-        return invitation;
-    }
-
-    @DB
-    public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-        //verify if the invitation was already generated
-        ProjectInvitationVO invite = null;
-        if (accountId != null) {
-            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
-        } else if (email != null) {
-            invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
-        }
-
-        if (invite != null) {
-            if (invite.getState() == ProjectInvitation.State.Completed ||
-                    (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
-                return true;
-            } else {
-                if (invite.getState() == ProjectInvitation.State.Pending) {
-                    expireInvitation(invite);
-                }
-                //remove the expired/declined invitation
-                if (accountId != null) {
-                    s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
-                } else if (email != null) {
-                    s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
-                }
-
-                _projectInvitationDao.expunge(invite.getId());
-            }
-        }
-
-        return false;
-    }
-        });
-    }
-
-    public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
-        //verify if the invitation was already generated
-        if (activeInviteExists(project, null, email)) {
-            throw new InvalidParameterValueException("There is already a pending invitation for email " + email + " to the project id=" + project);
-        }
-
-        ProjectInvitation projectInvitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token));
-        try {
-            _emailInvite.sendInvite(token, email, project.getId());
-        } catch (Exception ex) {
-            s_logger.warn("Failed to send project id=" + project + " invitation to the email " + email + "; removing the invitation record from the db", ex);
-            _projectInvitationDao.remove(projectInvitation.getId());
-            return null;
-        }
-
-        return projectInvitation;
-    }
-
-    private boolean expireInvitation(ProjectInvitationVO invite) {
-        s_logger.debug("Expiring invitation id=" + invite.getId());
-        invite.setState(ProjectInvitation.State.Expired);
-        return _projectInvitationDao.update(invite.getId(), invite);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async = true)
-    public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long accountId = null;
-        boolean result = true;
-
-        //if accountname and token are null, default accountname to caller's account name
-        if (accountName == null && token == null) {
-            accountName = caller.getAccountName();
-        }
-
-        //check that the project exists
-        final Project project = getProject(projectId);
-
-        if (project == null) {
-            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
-        }
-
-        if (accountName != null) {
-            //check that account-to-remove exists
-            Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
-            if (account == null) {
-                throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
-            }
-
-            //verify permissions
-            _accountMgr.checkAccess(caller, null, true, account);
-
-            accountId = account.getId();
-        } else {
-            accountId = caller.getId();
-        }
-
-        //check that invitation exists
-        ProjectInvitationVO invite = null;
-        if (token == null) {
-            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId, ProjectInvitation.State.Pending);
-        } else {
-            invite = _projectInvitationDao.findPendingByTokenAndProjectId(token, projectId, ProjectInvitation.State.Pending);
-        }
-
-        if (invite != null) {
-            if (!_projectInvitationDao.isActive(invite.getId(), _invitationTimeOut) && accept) {
-                expireInvitation(invite);
-                throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
-            } else {
-
-                final ProjectInvitationVO inviteFinal = invite;
-                final Long accountIdFinal = accountId;
-                final String accountNameFinal = accountName;
-                result = Transaction.execute(new TransactionCallback<Boolean>() {
-                    @Override
-                    public Boolean doInTransaction(TransactionStatus status) {
-                        boolean result = true;
-
-                ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
-
-                //update invitation
-                        s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
-                        inviteFinal.setState(newState);
-                        result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
-
-                if (result && accept) {
-                    //check if account already exists for the project (was added before invitation got accepted)
-                            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
-                    if (projectAccount != null) {
-                                s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
-                    } else {
-                                assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular);
-                    }
-                } else {
-                            s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
-                }
-
-                        return result;
-                    }
-                });
-            }
-        } else {
-            throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
-        }
-
-        return result;
-    }
-
-    @Override
-    public List<Long> listPermittedProjectAccounts(long accountId) {
-        return _projectAccountDao.listPermittedAccountIds(accountId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project")
-    @DB
-    public Project activateProject(final long projectId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check that the project exists
-        final ProjectVO project = getProject(projectId);
-
-        if (project == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
-            ex.addProxyObject(String.valueOf(projectId), "projectId");
-            throw ex;
-        }
-
-        //verify permissions
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        //allow project activation only when it's in Suspended state
-        Project.State currentState = project.getState();
-
-        if (currentState == State.Active) {
-            s_logger.debug("The project id=" + projectId + " is already active, no need to activate it again");
-            return project;
-        }
-
-        if (currentState != State.Suspended) {
-            throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-        project.setState(Project.State.Active);
-        _projectDao.update(projectId, project);
-
-        _accountMgr.enableAccount(project.getProjectAccountId());
-            }
-        });
-
-        return _projectDao.findById(projectId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_SUSPEND, eventDescription = "suspending project", async = true)
-    public Project suspendProject(long projectId) throws ConcurrentOperationException, ResourceUnavailableException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        ProjectVO project = getProject(projectId);
-        //verify input parameters
-        if (project == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
-            ex.addProxyObject(String.valueOf(projectId), "projectId");
-            throw ex;
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        if (suspendProject(project)) {
-            s_logger.debug("Successfully suspended project id=" + projectId);
-            return _projectDao.findById(projectId);
-        } else {
-            CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id");
-            ex.addProxyObject(project.getUuid(), "projectId");
-            throw ex;
-        }
-
-    }
-
-    private boolean suspendProject(ProjectVO project) throws ConcurrentOperationException, ResourceUnavailableException {
-
-        s_logger.debug("Marking project " + project + " with state " + State.Suspended + " as a part of project suspend...");
-        project.setState(State.Suspended);
-        boolean updateResult = _projectDao.update(project.getId(), project);
-
-        if (updateResult) {
-            long projectAccountId = project.getProjectAccountId();
-            if (!_accountMgr.disableAccount(projectAccountId)) {
-                s_logger.warn("Failed to suspend all project's " + project + " resources; the resources will be suspended later by background thread");
-            }
-        } else {
-            throw new CloudRuntimeException("Failed to mark the project " + project + " with state " + State.Suspended);
-        }
-        return true;
-    }
-
-    public static String generateToken(int length) {
-        String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-        Random rand = new Random(System.currentTimeMillis());
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < length; i++) {
-            int pos = rand.nextInt(charset.length());
-            sb.append(charset.charAt(pos));
-        }
-        return sb.toString();
-    }
-
-    class EmailInvite {
-        private Session _smtpSession;
-        private final String _smtpHost;
-        private int _smtpPort = -1;
-        private boolean _smtpUseAuth = false;
-        private final String _smtpUsername;
-        private final String _smtpPassword;
-        private final String _emailSender;
-
-        public EmailInvite(String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) {
-            _smtpHost = smtpHost;
-            _smtpPort = smtpPort;
-            _smtpUseAuth = smtpUseAuth;
-            _smtpUsername = smtpUsername;
-            _smtpPassword = smtpPassword;
-            _emailSender = emailSender;
-
-            if (_smtpHost != null) {
-                Properties smtpProps = new Properties();
-                smtpProps.put("mail.smtp.host", smtpHost);
-                smtpProps.put("mail.smtp.port", smtpPort);
-                smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
-                if (smtpUsername != null) {
-                    smtpProps.put("mail.smtp.user", smtpUsername);
-                }
-
-                smtpProps.put("mail.smtps.host", smtpHost);
-                smtpProps.put("mail.smtps.port", smtpPort);
-                smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
-                if (smtpUsername != null) {
-                    smtpProps.put("mail.smtps.user", smtpUsername);
-                }
-
-                if ((smtpUsername != null) && (smtpPassword != null)) {
-                    _smtpSession = Session.getInstance(smtpProps, new Authenticator() {
-                        @Override
-                        protected PasswordAuthentication getPasswordAuthentication() {
-                            return new PasswordAuthentication(smtpUsername, smtpPassword);
-                        }
-                    });
-                } else {
-                    _smtpSession = Session.getInstance(smtpProps);
-                }
-                _smtpSession.setDebug(smtpDebug);
-            } else {
-                _smtpSession = null;
-            }
-        }
-
-        public void sendInvite(String token, String email, long projectId) throws MessagingException, UnsupportedEncodingException {
-            if (_smtpSession != null) {
-                InternetAddress address = null;
-                if (email != null) {
-                    try {
-                        address = new InternetAddress(email, email);
-                    } catch (Exception ex) {
-                        s_logger.error("Exception creating address for: " + email, ex);
-                    }
-                }
-
-                String content = "You've been invited to join the CloudStack project id=" + projectId + ". Please use token " + token + " to complete registration";
-
-                SMTPMessage msg = new SMTPMessage(_smtpSession);
-                msg.setSender(new InternetAddress(_emailSender, _emailSender));
-                msg.setFrom(new InternetAddress(_emailSender, _emailSender));
-                msg.addRecipient(RecipientType.TO, address);
-                msg.setSubject("You are invited to join the cloud stack project id=" + projectId);
-                msg.setSentDate(new Date(DateUtil.currentGMTTime().getTime() >> 10));
-                msg.setContent(content, "text/plain");
-                msg.saveChanges();
-
-                SMTPTransport smtpTrans = null;
-                if (_smtpUseAuth) {
-                    smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
-                } else {
-                    smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
-                }
-                smtpTrans.connect();
-                smtpTrans.sendMessage(msg, msg.getAllRecipients());
-                smtpTrans.close();
-            } else {
-                throw new CloudRuntimeException("Unable to send email invitation; smtp ses");
-            }
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_REMOVE, eventDescription = "removing project invitation", async = true)
-    public boolean deleteProjectInvitation(long id) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        ProjectInvitation invitation = _projectInvitationDao.findById(id);
-        if (invitation == null) {
-            throw new InvalidParameterValueException("Unable to find project invitation by id " + id);
-        }
-
-        //check that the project exists
-        Project project = getProject(invitation.getProjectId());
-
-        //check permissions - only project owner can remove the invitations
-        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
-
-        if (_projectInvitationDao.remove(id)) {
-            s_logger.debug("Project Invitation id=" + id + " is removed");
-            return true;
-        } else {
-            s_logger.debug("Failed to remove project invitation id=" + id);
-            return false;
-        }
-    }
-
-    public class ExpiredInvitationsCleanup extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                TimeZone.getDefault();
-                List<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut);
-                if (!invitationsToExpire.isEmpty()) {
-                    s_logger.debug("Found " + invitationsToExpire.size() + " projects to expire");
-                    for (ProjectInvitationVO invitationToExpire : invitationsToExpire) {
-                        invitationToExpire.setState(ProjectInvitation.State.Expired);
-                        _projectInvitationDao.update(invitationToExpire.getId(), invitationToExpire);
-                        s_logger.trace("Expired project invitation id=" + invitationToExpire.getId());
-                    }
-                }
-            } catch (Exception ex) {
-                s_logger.warn("Exception while running expired invitations cleanup", ex);
-            }
-        }
-    }
-
-    @Override
-    public boolean projectInviteRequired() {
-        return _invitationRequired;
-    }
-
-    @Override
-    public boolean allowUserToCreateProject() {
-        return _allowUserToCreateProject;
-    }
-
-}
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
deleted file mode 100755
index 34a5196..0000000
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ /dev/null
@@ -1,3000 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.resource;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.utils.Pair;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
-import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
-import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
-import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
-import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.collections.CollectionUtils;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.GetVncPortAnswer;
-import com.cloud.agent.api.GetGPUStatsAnswer;
-import com.cloud.agent.api.GetGPUStatsCommand;
-import com.cloud.agent.api.GetHostStatsAnswer;
-import com.cloud.agent.api.GetHostStatsCommand;
-import com.cloud.agent.api.MaintainAnswer;
-import com.cloud.agent.api.MaintainCommand;
-import com.cloud.agent.api.PropagateResourceEventCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.UnsupportedAnswer;
-import com.cloud.agent.api.UpdateHostPasswordCommand;
-import com.cloud.agent.api.VgpuTypesInfo;
-import com.cloud.agent.api.to.GPUDeviceTO;
-import com.cloud.agent.transport.Request;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.CapacityState;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterIpAddressVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.PodCluster;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.ClusterVSMMapDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterIpAddressDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.PlannerHostReservationVO;
-import com.cloud.deploy.dao.PlannerHostReservationDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.gpu.GPU;
-import com.cloud.gpu.HostGpuGroupsVO;
-import com.cloud.gpu.VGPUTypesVO;
-import com.cloud.gpu.dao.HostGpuGroupsDao;
-import com.cloud.gpu.dao.VGPUTypesDao;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.ha.HighAvailabilityManager.WorkType;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostStats;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Status.Event;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.host.dao.HostTagsDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.org.Cluster;
-import com.cloud.org.Grouping;
-import com.cloud.org.Managed;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.GuestOSCategoryVO;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.StorageService;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.net.Ip;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.ssh.SSHCmdHelper;
-import com.cloud.utils.ssh.SshException;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.google.gson.Gson;
-
-@Component
-public class ResourceManagerImpl extends ManagerBase implements ResourceManager, ResourceService, Manager {
-    private static final Logger s_logger = Logger.getLogger(ResourceManagerImpl.class);
-
-    Gson _gson;
-
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private StorageManager _storageMgr;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private HostPodDao _podDao;
-    @Inject
-    private ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private CapacityDao _capacityDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private HostDetailsDao _hostDetailsDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private HostTagsDao _hostTagsDao;
-    @Inject
-    private GuestOSCategoryDao _guestOSCategoryDao;
-    @Inject
-    protected HostGpuGroupsDao _hostGpuGroupsDao;
-    @Inject
-    protected VGPUTypesDao _vgpuTypesDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private DataCenterIpAddressDao _privateIPAddressDao;
-    @Inject
-    private IPAddressDao _publicIPAddressDao;
-    @Inject
-    private VirtualMachineManager _vmMgr;
-    @Inject
-    private VMInstanceDao _vmDao;
-    @Inject
-    private HighAvailabilityManager _haMgr;
-    @Inject
-    private StorageService _storageSvr;
-    @Inject
-    PlannerHostReservationDao _plannerHostReserveDao;
-    @Inject
-    private DedicatedResourceDao _dedicatedDao;
-    @Inject
-    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-
-    private List<? extends Discoverer> _discoverers;
-
-    public List<? extends Discoverer> getDiscoverers() {
-        return _discoverers;
-    }
-
-    public void setDiscoverers(final List<? extends Discoverer> discoverers) {
-        _discoverers = discoverers;
-    }
-
-    @Inject
-    private ClusterManager _clusterMgr;
-    @Inject
-    private StoragePoolHostDao _storagePoolHostDao;
-
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private ConfigurationManager _configMgr;
-    @Inject
-    private ClusterVSMMapDao _clusterVSMMapDao;
-    @Inject
-    private UserVmDetailsDao userVmDetailsDao;
-
-    private final long _nodeId = ManagementServerNode.getManagementServerId();
-
-    private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
-
-    private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
-    private HypervisorType _defaultSystemVMHypervisor;
-
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds
-
-    private GenericSearchBuilder<HostVO, String> _hypervisorsInDC;
-
-    private SearchBuilder<HostGpuGroupsVO> _gpuAvailability;
-
-    private Map<Long,Integer> retryHostMaintenance = new ConcurrentHashMap<>();
-
-    private void insertListener(final Integer event, final ResourceListener listener) {
-        List<ResourceListener> lst = _lifeCycleListeners.get(event);
-        if (lst == null) {
-            lst = new ArrayList<ResourceListener>();
-            _lifeCycleListeners.put(event, lst);
-        }
-
-        if (lst.contains(listener)) {
-            throw new CloudRuntimeException("Duplicate resource lisener:" + listener.getClass().getSimpleName());
-        }
-
-        lst.add(listener);
-    }
-
-    @Override
-    public void registerResourceEvent(final Integer event, final ResourceListener listener) {
-        synchronized (_lifeCycleListeners) {
-            if ((event & ResourceListener.EVENT_DISCOVER_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_DISCOVER_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_DISCOVER_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_DISCOVER_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_DELETE_HOST_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_DELETE_HOST_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_DELETE_HOST_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_DELETE_HOST_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, listener);
-            }
-            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) != 0) {
-                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, listener);
-            }
-            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) != 0) {
-                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, listener);
-            }
-        }
-    }
-
-    @Override
-    public void unregisterResourceEvent(final ResourceListener listener) {
-        synchronized (_lifeCycleListeners) {
-            final Iterator it = _lifeCycleListeners.entrySet().iterator();
-            while (it.hasNext()) {
-                final Map.Entry<Integer, List<ResourceListener>> items = (Map.Entry<Integer, List<ResourceListener>>)it.next();
-                final List<ResourceListener> lst = items.getValue();
-                lst.remove(listener);
-            }
-        }
-    }
-
-    protected void processResourceEvent(final Integer event, final Object... params) {
-        final List<ResourceListener> lst = _lifeCycleListeners.get(event);
-        if (lst == null || lst.size() == 0) {
-            return;
-        }
-
-        String eventName;
-        for (final ResourceListener l : lst) {
-            if (event.equals(ResourceListener.EVENT_DISCOVER_BEFORE)) {
-                l.processDiscoverEventBefore((Long)params[0], (Long)params[1], (Long)params[2], (URI)params[3], (String)params[4], (String)params[5],
-                        (List<String>)params[6]);
-                eventName = "EVENT_DISCOVER_BEFORE";
-            } else if (event.equals(ResourceListener.EVENT_DISCOVER_AFTER)) {
-                l.processDiscoverEventAfter((Map<? extends ServerResource, Map<String, String>>)params[0]);
-                eventName = "EVENT_DISCOVER_AFTER";
-            } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_BEFORE)) {
-                l.processDeleteHostEventBefore((HostVO)params[0]);
-                eventName = "EVENT_DELETE_HOST_BEFORE";
-            } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_AFTER)) {
-                l.processDeletHostEventAfter((HostVO)params[0]);
-                eventName = "EVENT_DELETE_HOST_AFTER";
-            } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE)) {
-                l.processCancelMaintenaceEventBefore((Long)params[0]);
-                eventName = "EVENT_CANCEL_MAINTENANCE_BEFORE";
-            } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER)) {
-                l.processCancelMaintenaceEventAfter((Long)params[0]);
-                eventName = "EVENT_CANCEL_MAINTENANCE_AFTER";
-            } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE)) {
-                l.processPrepareMaintenaceEventBefore((Long)params[0]);
-                eventName = "EVENT_PREPARE_MAINTENANCE_BEFORE";
-            } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER)) {
-                l.processPrepareMaintenaceEventAfter((Long)params[0]);
-                eventName = "EVENT_PREPARE_MAINTENANCE_AFTER";
-            } else {
-                throw new CloudRuntimeException("Unknown resource event:" + event);
-            }
-            s_logger.debug("Sent resource event " + eventName + " to listener " + l.getClass().getSimpleName());
-        }
-
-    }
-
-    @DB
-    @Override
-    public List<? extends Cluster> discoverCluster(final AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException {
-        final long dcId = cmd.getZoneId();
-        final long podId = cmd.getPodId();
-        final String clusterName = cmd.getClusterName();
-        String url = cmd.getUrl();
-        final String username = cmd.getUsername();
-        final String password = cmd.getPassword();
-
-        if (url != null) {
-            url = URLDecoder.decode(url);
-        }
-
-        URI uri = null;
-
-        // Check if the zone exists in the system
-        final DataCenterVO zone = _dcDao.findById(dcId);
-        if (zone == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified");
-            ex.addProxyObject(String.valueOf(dcId), "dcId");
-            throw ex;
-        }
-
-        final Account account = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
-            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "dcId");
-            throw ex;
-        }
-
-        final HostPodVO pod = _podDao.findById(podId);
-        if (pod == null) {
-            throw new InvalidParameterValueException("Can't find pod with specified podId " + podId);
-        }
-
-        // Check if the pod exists in the system
-        if (_podDao.findById(podId) == null) {
-            throw new InvalidParameterValueException("Can't find pod by id " + podId);
-        }
-        // check if pod belongs to the zone
-        if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId);
-            ex.addProxyObject(pod.getUuid(), "podId");
-            ex.addProxyObject(zone.getUuid(), "dcId");
-            throw ex;
-        }
-
-        // Verify cluster information and create a new cluster if needed
-        if (clusterName == null || clusterName.isEmpty()) {
-            throw new InvalidParameterValueException("Please specify cluster name");
-        }
-
-        if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
-            throw new InvalidParameterValueException("Please specify a hypervisor");
-        }
-
-        final Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
-        if (hypervisorType == null) {
-            s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
-            throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
-        }
-
-        if (zone.isSecurityGroupEnabled() && zone.getNetworkType().equals(NetworkType.Advanced)) {
-            if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer
-                    && hypervisorType != HypervisorType.LXC && hypervisorType != HypervisorType.Simulator) {
-                throw new InvalidParameterValueException("Don't support hypervisor type " + hypervisorType + " in advanced security enabled zone");
-            }
-        }
-
-        Cluster.ClusterType clusterType = null;
-        if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
-            clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
-        }
-        if (clusterType == null) {
-            clusterType = Cluster.ClusterType.CloudManaged;
-        }
-
-        Grouping.AllocationState allocationState = null;
-        if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) {
-            try {
-                allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState());
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state");
-            }
-        }
-        if (allocationState == null) {
-            allocationState = Grouping.AllocationState.Enabled;
-        }
-
-        final Discoverer discoverer = getMatchingDiscover(hypervisorType);
-        if (discoverer == null) {
-
-            throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor());
-        }
-
-        if (hypervisorType == HypervisorType.VMware) {
-            final Map<String, String> allParams = cmd.getFullUrlParams();
-            discoverer.putParam(allParams);
-        }
-
-        final List<ClusterVO> result = new ArrayList<ClusterVO>();
-
-        ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
-        cluster.setHypervisorType(hypervisorType.toString());
-
-        cluster.setClusterType(clusterType);
-        cluster.setAllocationState(allocationState);
-        try {
-            cluster = _clusterDao.persist(cluster);
-        } catch (final Exception e) {
-            // no longer tolerate exception during the cluster creation phase
-            final CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod and data center with specified ids", e);
-            // Get the pod VO object's table name.
-            ex.addProxyObject(pod.getUuid(), "podId");
-            ex.addProxyObject(zone.getUuid(), "dcId");
-            throw ex;
-        }
-        result.add(cluster);
-
-        if (clusterType == Cluster.ClusterType.CloudManaged) {
-            final Map<String, String> details = new HashMap<String, String>();
-            // should do this nicer perhaps ?
-            if (hypervisorType == HypervisorType.Ovm3) {
-                final Map<String, String> allParams = cmd.getFullUrlParams();
-                details.put("ovm3vip", allParams.get("ovm3vip"));
-                details.put("ovm3pool", allParams.get("ovm3pool"));
-                details.put("ovm3cluster", allParams.get("ovm3cluster"));
-            }
-            details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
-            details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
-            _clusterDetailsDao.persist(cluster.getId(), details);
-            return result;
-        }
-
-        // save cluster details for later cluster/host cross-checking
-        final Map<String, String> details = new HashMap<String, String>();
-        details.put("url", url);
-        details.put("username", username);
-        details.put("password", password);
-        details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
-        details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
-        _clusterDetailsDao.persist(cluster.getId(), details);
-
-        boolean success = false;
-        try {
-            try {
-                uri = new URI(UriUtils.encodeURIComponent(url));
-                if (uri.getScheme() == null) {
-                    throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix");
-                } else if (uri.getScheme().equalsIgnoreCase("http")) {
-                    if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
-                        throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format http://hostname/path");
-                    }
-                }
-            } catch (final URISyntaxException e) {
-                throw new InvalidParameterValueException(url + " is not a valid uri");
-            }
-
-            final List<HostVO> hosts = new ArrayList<HostVO>();
-            Map<? extends ServerResource, Map<String, String>> resources = null;
-            resources = discoverer.find(dcId, podId, cluster.getId(), uri, username, password, null);
-
-            if (resources != null) {
-                for (final Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
-                    final ServerResource resource = entry.getKey();
-
-                    final HostVO host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, null, false);
-                    if (host != null) {
-                        hosts.add(host);
-                    }
-                    discoverer.postDiscovery(hosts, _nodeId);
-                }
-                s_logger.info("External cluster has been successfully discovered by " + discoverer.getName());
-                success = true;
-                return result;
-            }
-
-            s_logger.warn("Unable to find the server resources at " + url);
-            throw new DiscoveryException("Unable to add the external cluster");
-        } finally {
-            if (!success) {
-                _clusterDetailsDao.deleteDetails(cluster.getId());
-                _clusterDao.remove(cluster.getId());
-            }
-        }
-    }
-
-    @Override
-    public Discoverer getMatchingDiscover(final Hypervisor.HypervisorType hypervisorType) {
-        for (final Discoverer discoverer : _discoverers) {
-            if (discoverer.getHypervisorType() == hypervisorType) {
-                return discoverer;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<? extends Host> discoverHosts(final AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        Long dcId = cmd.getZoneId();
-        final Long podId = cmd.getPodId();
-        final Long clusterId = cmd.getClusterId();
-        String clusterName = cmd.getClusterName();
-        final String url = cmd.getUrl();
-        final String username = cmd.getUsername();
-        final String password = cmd.getPassword();
-        final List<String> hostTags = cmd.getHostTags();
-
-        dcId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), dcId);
-
-        // this is for standalone option
-        if (clusterName == null && clusterId == null) {
-            clusterName = "Standalone-" + url;
-        }
-
-        if (clusterId != null) {
-            final ClusterVO cluster = _clusterDao.findById(clusterId);
-            if (cluster == null) {
-                final InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster for specified clusterId");
-                ex.addProxyObject(clusterId.toString(), "clusterId");
-                throw ex;
-            } else {
-                if (cluster.getGuid() == null) {
-                    final List<HostVO> hosts = listAllHostsInCluster(clusterId);
-                    if (!hosts.isEmpty()) {
-                        final CloudRuntimeException ex =
-                                new CloudRuntimeException("Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up");
-                        ex.addProxyObject(cluster.getUuid(), "clusterId");
-                        throw ex;
-                    }
-                }
-            }
-        }
-
-        return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), false);
-    }
-
-    @Override
-    public List<? extends Host> discoverHosts(final AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        final Long dcId = cmd.getZoneId();
-        final String url = cmd.getUrl();
-        return discoverHostsFull(dcId, null, null, null, url, null, null, "SecondaryStorage", null, null, false);
-    }
-
-    private List<HostVO> discoverHostsFull(final Long dcId, final Long podId, Long clusterId, final String clusterName, String url, String username, String password,
-            final String hypervisorType, final List<String> hostTags, final Map<String, String> params, final boolean deferAgentCreation) throws IllegalArgumentException, DiscoveryException,
-            InvalidParameterValueException {
-        URI uri = null;
-
-        // Check if the zone exists in the system
-        final DataCenterVO zone = _dcDao.findById(dcId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id " + dcId);
-        }
-
-        final Account account = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
-            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "dcId");
-            throw ex;
-        }
-
-        // Check if the pod exists in the system
-        if (podId != null) {
-            final HostPodVO pod = _podDao.findById(podId);
-            if (pod == null) {
-                throw new InvalidParameterValueException("Can't find pod by id " + podId);
-            }
-            // check if pod belongs to the zone
-            if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
-                final InvalidParameterValueException ex =
-                        new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId);
-                ex.addProxyObject(pod.getUuid(), "podId");
-                ex.addProxyObject(zone.getUuid(), "dcId");
-                throw ex;
-            }
-        }
-
-        // Verify cluster information and create a new cluster if needed
-        if (clusterName != null && clusterId != null) {
-            throw new InvalidParameterValueException("Can't specify cluster by both id and name");
-        }
-
-        if (hypervisorType == null || hypervisorType.isEmpty()) {
-            throw new InvalidParameterValueException("Need to specify Hypervisor Type");
-        }
-
-        if ((clusterName != null || clusterId != null) && podId == null) {
-            throw new InvalidParameterValueException("Can't specify cluster without specifying the pod");
-        }
-
-        if (clusterId != null) {
-            if (_clusterDao.findById(clusterId) == null) {
-                throw new InvalidParameterValueException("Can't find cluster by id " + clusterId);
-            }
-
-            if (hypervisorType.equalsIgnoreCase(HypervisorType.VMware.toString())) {
-                // VMware only allows adding host to an existing cluster, as we
-                // already have a lot of information
-                // in cluster object, to simplify user input, we will construct
-                // neccessary information here
-                final Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
-                username = clusterDetails.get("username");
-                assert username != null;
-
-                password = clusterDetails.get("password");
-                assert password != null;
-
-                try {
-                    uri = new URI(UriUtils.encodeURIComponent(url));
-
-                    url = clusterDetails.get("url") + "/" + uri.getHost();
-                } catch (final URISyntaxException e) {
-                    throw new InvalidParameterValueException(url + " is not a valid uri");
-                }
-            }
-        }
-
-        if ((hypervisorType.equalsIgnoreCase(HypervisorType.BareMetal.toString()))) {
-            if (hostTags.isEmpty()) {
-                throw new InvalidParameterValueException("hosttag is mandatory while adding host of type Baremetal");
-            }
-        }
-
-        if (clusterName != null) {
-            final HostPodVO pod = _podDao.findById(podId);
-            if (pod == null) {
-                throw new InvalidParameterValueException("Can't find pod by id " + podId);
-            }
-            ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
-            cluster.setHypervisorType(hypervisorType);
-            try {
-                cluster = _clusterDao.persist(cluster);
-            } catch (final Exception e) {
-                cluster = _clusterDao.findBy(clusterName, podId);
-                if (cluster == null) {
-                    final CloudRuntimeException ex =
-                            new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod with specified podId and data center with specified dcID", e);
-                    ex.addProxyObject(pod.getUuid(), "podId");
-                    ex.addProxyObject(zone.getUuid(), "dcId");
-                    throw ex;
-                }
-            }
-            clusterId = cluster.getId();
-            if (_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio") == null) {
-                final ClusterDetailsVO cluster_cpu_detail = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", "1");
-                final ClusterDetailsVO cluster_memory_detail = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", "1");
-                _clusterDetailsDao.persist(cluster_cpu_detail);
-                _clusterDetailsDao.persist(cluster_memory_detail);
-            }
-
-        }
-
-        try {
-            uri = new URI(UriUtils.encodeURIComponent(url));
-            if (uri.getScheme() == null) {
-                throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// (or cifs://) as a prefix");
-            } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
-                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
-                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format nfs://hostname/path");
-                }
-            } else if (uri.getScheme().equalsIgnoreCase("cifs")) {
-                // Don't validate against a URI encoded URI.
-                final URI cifsUri = new URI(url);
-                final String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
-                if (warnMsg != null) {
-                    throw new InvalidParameterValueException(warnMsg);
-                }
-            }
-        } catch (final URISyntaxException e) {
-            throw new InvalidParameterValueException(url + " is not a valid uri");
-        }
-
-        final List<HostVO> hosts = new ArrayList<HostVO>();
-        s_logger.info("Trying to add a new host at " + url + " in data center " + dcId);
-        boolean isHypervisorTypeSupported = false;
-        for (final Discoverer discoverer : _discoverers) {
-            if (params != null) {
-                discoverer.putParam(params);
-            }
-
-            if (!discoverer.matchHypervisor(hypervisorType)) {
-                continue;
-            }
-            isHypervisorTypeSupported = true;
-            Map<? extends ServerResource, Map<String, String>> resources = null;
-
-            processResourceEvent(ResourceListener.EVENT_DISCOVER_BEFORE, dcId, podId, clusterId, uri, username, password, hostTags);
-            try {
-                resources = discoverer.find(dcId, podId, clusterId, uri, username, password, hostTags);
-            } catch (final DiscoveryException e) {
-                throw e;
-            } catch (final Exception e) {
-                s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any");
-            }
-            processResourceEvent(ResourceListener.EVENT_DISCOVER_AFTER, resources);
-
-            if (resources != null) {
-                for (final Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
-                    final ServerResource resource = entry.getKey();
-                    /*
-                     * For KVM, if we go to here, that means kvm agent is
-                     * already connected to mgt svr.
-                     */
-                    if (resource instanceof KvmDummyResourceBase) {
-                        final Map<String, String> details = entry.getValue();
-                        final String guid = details.get("guid");
-                        final List<HostVO> kvmHosts = listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId);
-                        for (final HostVO host : kvmHosts) {
-                            if (host.getGuid().equalsIgnoreCase(guid)) {
-                                if (hostTags != null) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("Adding Host Tags for KVM host, tags:  :" + hostTags);
-                                    }
-                                    _hostTagsDao.persist(host.getId(), hostTags);
-                                }
-                                hosts.add(host);
-
-                                _agentMgr.notifyMonitorsOfNewlyAddedHost(host.getId());
-
-                                return hosts;
-                            }
-                        }
-                        return null;
-                    }
-
-                    HostVO host = null;
-                    if (deferAgentCreation) {
-                        host = (HostVO)createHostAndAgentDeferred(resource, entry.getValue(), true, hostTags, false);
-                    } else {
-                        host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, hostTags, false);
-                    }
-                    if (host != null) {
-                        hosts.add(host);
-                    }
-                    discoverer.postDiscovery(hosts, _nodeId);
-
-                }
-                s_logger.info("server resources successfully discovered by " + discoverer.getName());
-                return hosts;
-            }
-        }
-        if (!isHypervisorTypeSupported) {
-            final String msg = "Do not support HypervisorType " + hypervisorType + " for " + url;
-            s_logger.warn(msg);
-            throw new DiscoveryException(msg);
-        }
-        s_logger.warn("Unable to find the server resources at " + url);
-        throw new DiscoveryException("Unable to add the host");
-    }
-
-    @Override
-    public Host getHost(final long hostId) {
-        return _hostDao.findById(hostId);
-    }
-
-    @DB
-    protected boolean doDeleteHost(final long hostId, final boolean isForced, final boolean isForceDeleteStorage) {
-        _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-        // Verify that host exists
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
-        }
-        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), host.getDataCenterId());
-
-        if (!isForced && host.getResourceState() != ResourceState.Maintenance) {
-            throw new CloudRuntimeException("Host " + host.getUuid() +
-                    " cannot be deleted as it is not in maintenance mode. Either put the host into maintenance or perform a forced deletion.");
-        }
-        // Get storage pool host mappings here because they can be removed as a
-        // part of handleDisconnect later
-        // TODO: find out the bad boy, what's a buggy logic!
-        final List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
-
-        final ResourceStateAdapter.DeleteHostAnswer answer =
-                (ResourceStateAdapter.DeleteHostAnswer)dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host, isForced,
-                        isForceDeleteStorage);
-
-        if (answer == null) {
-            throw new CloudRuntimeException("No resource adapter respond to DELETE_HOST event for " + host.getName() + " id = " + hostId + ", hypervisorType is " +
-                    host.getHypervisorType() + ", host type is " + host.getType());
-        }
-
-        if (answer.getIsException()) {
-            return false;
-        }
-
-        if (!answer.getIsContinue()) {
-            return true;
-        }
-
-        Long clusterId = host.getClusterId();
-
-        _agentMgr.notifyMonitorsOfHostAboutToBeRemoved(host.getId());
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
-                _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
-
-                // delete host details
-                _hostDetailsDao.deleteDetails(hostId);
-
-                // if host is GPU enabled, delete GPU entries
-                _hostGpuGroupsDao.deleteGpuEntries(hostId);
-
-                // delete host tags
-                _hostTagsDao.deleteTags(hostId);
-
-                host.setGuid(null);
-                final Long clusterId = host.getClusterId();
-                host.setClusterId(null);
-                _hostDao.update(host.getId(), host);
-
-                _hostDao.remove(hostId);
-                if (clusterId != null) {
-                    final List<HostVO> hosts = listAllHostsInCluster(clusterId);
-                    if (hosts.size() == 0) {
-                        final ClusterVO cluster = _clusterDao.findById(clusterId);
-                        cluster.setGuid(null);
-                        _clusterDao.update(clusterId, cluster);
-                    }
-                }
-
-                try {
-                    resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
-                } catch (final NoTransitionException e) {
-                    s_logger.debug("Cannot transmit host " + host.getId() + " to Enabled state", e);
-                }
-
-                // Delete the associated entries in host ref table
-                _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
-
-                // Make sure any VMs that were marked as being on this host are cleaned up
-                final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
-                for (final VMInstanceVO vm : vms) {
-                    // this is how VirtualMachineManagerImpl does it when it syncs VM states
-                    vm.setState(State.Stopped);
-                    vm.setHostId(null);
-                    _vmDao.persist(vm);
-                }
-
-                // For pool ids you got, delete local storage host entries in pool table
-                // where
-                for (final StoragePoolHostVO pool : pools) {
-                    final Long poolId = pool.getPoolId();
-                    final StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
-                    if (storagePool.isLocal() && isForceDeleteStorage) {
-                        storagePool.setUuid(null);
-                        storagePool.setClusterId(null);
-                        _storagePoolDao.update(poolId, storagePool);
-                        _storagePoolDao.remove(poolId);
-                        s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
-                    }
-                }
-
-                // delete the op_host_capacity entry
-                final Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
-                final SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
-                hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
-                hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
-                _capacityDao.remove(hostCapacitySC);
-                // remove from dedicated resources
-                final DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
-                if (dr != null) {
-                    _dedicatedDao.remove(dr.getId());
-                }
-            }
-        });
-
-        if (clusterId != null) {
-            _agentMgr.notifyMonitorsOfRemovedHost(host.getId(), clusterId);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean deleteHost(final long hostId, final boolean isForced, final boolean isForceDeleteStorage) {
-        try {
-            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.DeleteHost);
-            if (result != null) {
-                return result;
-            }
-        } catch (final AgentUnavailableException e) {
-            return false;
-        }
-
-        return doDeleteHost(hostId, isForced, isForceDeleteStorage);
-    }
-
-    @Override
-    @DB
-    public boolean deleteCluster(final DeleteClusterCmd cmd) {
-        try {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(final TransactionStatus status) {
-                    final ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
-                    if (cluster == null) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
-                        }
-                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
-                    }
-
-                    final Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
-
-                    final List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
-                    if (hosts.size() > 0) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
-                        }
-                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
-                    }
-
-                    // don't allow to remove the cluster if it has non-removed storage
-                    // pools
-                    final List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
-                    if (storagePools.size() > 0) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
-                        }
-                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
-                    }
-
-                    if (_clusterDao.remove(cmd.getId())) {
-                        _capacityDao.removeBy(null, null, null, cluster.getId(), null);
-                        // If this cluster is of type vmware, and if the nexus vswitch
-                        // global parameter setting is turned
-                        // on, remove the row in cluster_vsm_map for this cluster id.
-                        if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
-                            _clusterVSMMapDao.removeByClusterId(cmd.getId());
-                        }
-                        // remove from dedicated resources
-                        final DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
-                        if (dr != null) {
-                            _dedicatedDao.remove(dr.getId());
-                        }
-                    }
-
-                }
-            });
-            return true;
-        } catch (final CloudRuntimeException e) {
-            throw e;
-        } catch (final Throwable t) {
-            s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    public Cluster updateCluster(final Cluster clusterToUpdate, final String clusterType, final String hypervisor, final String allocationState, final String managedstate) {
-
-        final ClusterVO cluster = (ClusterVO)clusterToUpdate;
-        // Verify cluster information and update the cluster if needed
-        boolean doUpdate = false;
-
-        if (hypervisor != null && !hypervisor.isEmpty()) {
-            final Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor);
-            if (hypervisorType == null) {
-                s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type");
-                throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type");
-            } else {
-                cluster.setHypervisorType(hypervisor);
-                doUpdate = true;
-            }
-        }
-
-        Cluster.ClusterType newClusterType = null;
-        if (clusterType != null && !clusterType.isEmpty()) {
-            try {
-                newClusterType = Cluster.ClusterType.valueOf(clusterType);
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
-            }
-            if (newClusterType == null) {
-                s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type");
-                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
-            } else {
-                cluster.setClusterType(newClusterType);
-                doUpdate = true;
-            }
-        }
-
-        Grouping.AllocationState newAllocationState = null;
-        if (allocationState != null && !allocationState.isEmpty()) {
-            try {
-                newAllocationState = Grouping.AllocationState.valueOf(allocationState);
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state");
-            }
-            if (newAllocationState == null) {
-                s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State");
-                throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state");
-            } else {
-                cluster.setAllocationState(newAllocationState);
-                doUpdate = true;
-            }
-        }
-
-        Managed.ManagedState newManagedState = null;
-        final Managed.ManagedState oldManagedState = cluster.getManagedState();
-        if (managedstate != null && !managedstate.isEmpty()) {
-            try {
-                newManagedState = Managed.ManagedState.valueOf(managedstate);
-            } catch (final IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-            }
-            if (newManagedState == null) {
-                s_logger.error("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
-            } else {
-                doUpdate = true;
-            }
-        }
-
-        if (doUpdate) {
-            _clusterDao.update(cluster.getId(), cluster);
-        }
-
-        if (newManagedState != null && !newManagedState.equals(oldManagedState)) {
-            if (newManagedState.equals(Managed.ManagedState.Unmanaged)) {
-                boolean success = false;
-                try {
-                    cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
-                    _clusterDao.update(cluster.getId(), cluster);
-                    List<HostVO> hosts = listAllHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
-                    for (final HostVO host : hosts) {
-                        if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) &&
-                                !host.getStatus().equals(Status.Up) && !host.getStatus().equals(Status.Alert)) {
-                            final String msg = "host " + host.getPrivateIpAddress() + " should not be in " + host.getStatus().toString() + " status";
-                            throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg);
-                        }
-                    }
-
-                    for (final HostVO host : hosts) {
-                        if (host.getStatus().equals(Status.Up)) {
-                            umanageHost(host.getId());
-                        }
-                    }
-                    final int retry = 40;
-                    boolean lsuccess = true;
-                    for (int i = 0; i < retry; i++) {
-                        lsuccess = true;
-                        try {
-                            Thread.sleep(5 * 1000);
-                        } catch (final Exception e) {
-                        }
-                        hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
-                        for (final HostVO host : hosts) {
-                            if (!host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) && !host.getStatus().equals(Status.Alert)) {
-                                lsuccess = false;
-                                break;
-                            }
-                        }
-                        if (lsuccess == true) {
-                            success = true;
-                            break;
-                        }
-                    }
-                    if (success == false) {
-                        throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
-                    }
-                } finally {
-                    cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError);
-                    _clusterDao.update(cluster.getId(), cluster);
-                }
-            } else if (newManagedState.equals(Managed.ManagedState.Managed)) {
-                cluster.setManagedState(Managed.ManagedState.Managed);
-                _clusterDao.update(cluster.getId(), cluster);
-            }
-
-        }
-
-        return cluster;
-    }
-
-    @Override
-    public Host cancelMaintenance(final CancelMaintenanceCmd cmd) {
-        final Long hostId = cmd.getId();
-
-        // verify input parameters
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null || host.getRemoved() != null) {
-            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
-        }
-
-        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, hostId);
-        final boolean success = cancelMaintenance(hostId);
-        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, hostId);
-        if (!success) {
-            throw new CloudRuntimeException("Internal error cancelling maintenance.");
-        }
-        return host;
-    }
-
-    @Override
-    public Host reconnectHost(final ReconnectHostCmd cmd) {
-        final Long hostId = cmd.getId();
-
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
-        }
-
-        return _agentMgr.reconnect(hostId) ? host : null;
-    }
-
-    @Override
-    public boolean resourceStateTransitTo(final Host host, final ResourceState.Event event, final long msId) throws NoTransitionException {
-        final ResourceState currentState = host.getResourceState();
-        final ResourceState nextState = currentState.getNextState(event);
-        if (nextState == null) {
-            throw new NoTransitionException("No next resource state found for current state = " + currentState + " event = " + event);
-        }
-
-        // TO DO - Make it more granular and have better conversion into capacity type
-        if(host.getType() == Type.Routing){
-            final CapacityState capacityState =  nextState == ResourceState.Enabled ? CapacityState.Enabled : CapacityState.Disabled;
-            final short[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
-            _capacityDao.updateCapacityState(null, null, null, host.getId(), capacityState.toString(), capacityTypes);
-
-            final StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host.getId());
-
-            if(storagePool != null){
-                final short[] capacityTypesLocalStorage = {Capacity.CAPACITY_TYPE_LOCAL_STORAGE};
-                _capacityDao.updateCapacityState(null, null, null, storagePool.getId(), capacityState.toString(), capacityTypesLocalStorage);
-            }
-        }
-        return _hostDao.updateResourceState(currentState, event, nextState, host);
-    }
-
-    private boolean doMaintain(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        final MaintainAnswer answer = (MaintainAnswer)_agentMgr.easySend(hostId, new MaintainCommand());
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to send MaintainCommand to host: " + hostId);
-            return false;
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.AdminAskMaintenace, _nodeId);
-        } catch (final NoTransitionException e) {
-            final String err = "Cannot transmit resource state of host " + host.getId() + " to " + ResourceState.Maintenance;
-            s_logger.debug(err, e);
-            throw new CloudRuntimeException(err + e.getMessage());
-        }
-
-        ActionEventUtils.onStartedActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(), EventTypes.EVENT_MAINTENANCE_PREPARE, "starting maintenance for host " + hostId, true, 0);
-        _agentMgr.pullAgentToMaintenance(hostId);
-        setHostMaintenanceRetries(host);
-
-        /* TODO: move below to listener */
-        if (host.getType() == Host.Type.Routing) {
-
-            final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
-            if (vms.size() == 0) {
-                return true;
-            }
-
-            final List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
-            for (final VMInstanceVO vm : vms) {
-                if (hosts == null || hosts.isEmpty() || !answer.getMigrate()
-                        || _serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.vgpuType.toString()) != null) {
-                    // Migration is not supported for VGPU Vms so stop them.
-                    // for the last host in this cluster, stop all the VMs
-                    _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
-                } else if (HypervisorType.LXC.equals(host.getHypervisorType()) && VirtualMachine.Type.User.equals(vm.getType())){
-                    //Migration is not supported for LXC Vms. Schedule restart instead.
-                    _haMgr.scheduleRestart(vm, false);
-                } else {
-                    _haMgr.scheduleMigration(vm);
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Set retries for transiting the host into Maintenance
-     */
-    protected void setHostMaintenanceRetries(HostVO host) {
-        Integer retries = HostMaintenanceRetries.valueIn(host.getClusterId());
-        retryHostMaintenance.put(host.getId(), retries);
-        s_logger.debug(String.format("Setting the host %s (%s) retries for Maintenance mode: %s",
-                host.getId(), host.getName(), retries));
-    }
-
-    @Override
-    public boolean maintain(final long hostId) throws AgentUnavailableException {
-        final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
-        if (result != null) {
-            return result;
-        }
-
-        return doMaintain(hostId);
-    }
-
-    @Override
-    public Host maintain(final PrepareForMaintenanceCmd cmd) {
-        final Long hostId = cmd.getId();
-        final HostVO host = _hostDao.findById(hostId);
-
-        if (host == null) {
-            s_logger.debug("Unable to find host " + hostId);
-            throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID.");
-        }
-
-        if (_hostDao.countBy(host.getClusterId(), ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance) > 0) {
-            throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId());
-        }
-
-        if (_storageMgr.isLocalStorageActiveOnHost(host.getId())) {
-            throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage.");
-        }
-
-        try {
-            processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId);
-            if (maintain(hostId)) {
-                processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, hostId);
-                return _hostDao.findById(hostId);
-            } else {
-                throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
-            }
-        } catch (final AgentUnavailableException e) {
-            throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
-        }
-    }
-
-    /**
-     * Add VNC details as user VM details for each VM in 'vms' (KVM hosts only)
-     */
-    protected void setKVMVncAccess(long hostId, List<VMInstanceVO> vms) {
-        for (VMInstanceVO vm : vms) {
-            GetVncPortAnswer vmVncPortAnswer = (GetVncPortAnswer) _agentMgr.easySend(hostId, new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
-            if (vmVncPortAnswer != null) {
-                userVmDetailsDao.addDetail(vm.getId(), "kvm.vnc.address", vmVncPortAnswer.getAddress(), true);
-                userVmDetailsDao.addDetail(vm.getId(), "kvm.vnc.port", String.valueOf(vmVncPortAnswer.getPort()), true);
-            }
-        }
-    }
-
-    /**
-     * Configure VNC access for host VMs which have failed migrating to another host while trying to enter Maintenance mode
-     */
-    protected void configureVncAccessForKVMHostFailedMigrations(HostVO host, List<VMInstanceVO> failedMigrations) {
-        if (host.getHypervisorType().equals(HypervisorType.KVM)) {
-            _agentMgr.pullAgentOutMaintenance(host.getId());
-            setKVMVncAccess(host.getId(), failedMigrations);
-            _agentMgr.pullAgentToMaintenance(host.getId());
-        }
-    }
-
-    /**
-     * Set host into ErrorInMaintenance state, as errors occurred during VM migrations. Do the following:
-     * - Cancel scheduled migrations for those which have already failed
-     * - Configure VNC access for VMs (KVM hosts only)
-     */
-    protected boolean setHostIntoErrorInMaintenance(HostVO host, List<VMInstanceVO> failedMigrations) throws NoTransitionException {
-        s_logger.debug("Unable to migrate " + failedMigrations.size() + " VM(s) from host " + host.getUuid());
-        _haMgr.cancelScheduledMigrations(host);
-        configureVncAccessForKVMHostFailedMigrations(host, failedMigrations);
-        resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId);
-        return false;
-    }
-
-    /**
-     * Safely transit host into Maintenance mode
-     */
-    protected boolean setHostIntoMaintenance(HostVO host) throws NoTransitionException {
-        s_logger.debug("Host " + host.getUuid() + " entering in Maintenance");
-        resourceStateTransitTo(host, ResourceState.Event.InternalEnterMaintenance, _nodeId);
-        ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(),
-                EventVO.LEVEL_INFO, EventTypes.EVENT_MAINTENANCE_PREPARE,
-                "completed maintenance for host " + host.getId(), 0);
-        return true;
-    }
-
-    /**
-     * Return true if host goes into Maintenance mode, only when:
-     * - No Running, Migrating or Failed migrations (host_id = last_host_id) for the host
-     */
-    protected boolean isHostInMaintenance(HostVO host, List<VMInstanceVO> runningVms, List<VMInstanceVO> migratingVms, List<VMInstanceVO> failedMigrations) throws NoTransitionException {
-        if (CollectionUtils.isEmpty(runningVms) && CollectionUtils.isEmpty(migratingVms)) {
-            return CollectionUtils.isEmpty(failedMigrations) ?
-                    setHostIntoMaintenance(host) :
-                    setHostIntoErrorInMaintenance(host, failedMigrations);
-        } else if (retryHostMaintenance.containsKey(host.getId())) {
-            Integer retriesLeft = retryHostMaintenance.get(host.getId());
-            if (retriesLeft != null) {
-                if (retriesLeft <= 0) {
-                    retryHostMaintenance.remove(host.getId());
-                    s_logger.debug(String.format("No retries left while preparing KVM host %s (%s) for Maintenance, " +
-                                    "please investigate this connection.",
-                            host.getId(), host.getName()));
-                    return setHostIntoErrorInMaintenance(host, failedMigrations);
-                }
-                retriesLeft--;
-                retryHostMaintenance.put(host.getId(), retriesLeft);
-                s_logger.debug(String.format("Retries left preparing KVM host %s (%s) for Maintenance: %s",
-                        host.getId(), host.getName(), retriesLeft));
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public boolean checkAndMaintain(final long hostId) {
-        boolean hostInMaintenance = false;
-        final HostVO host = _hostDao.findById(hostId);
-
-        try {
-            if (host.getType() != Host.Type.Storage) {
-                final List<VMInstanceVO> vos = _vmDao.listByHostId(hostId);
-                final List<VMInstanceVO> vosMigrating = _vmDao.listVmsMigratingFromHost(hostId);
-                final List<VMInstanceVO> failedVmMigrations = _vmDao.listNonMigratingVmsByHostEqualsLastHost(hostId);
-
-                hostInMaintenance = isHostInMaintenance(host, vos, vosMigrating, failedVmMigrations);
-            }
-        } catch (final NoTransitionException e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + "to Maintenance state", e);
-        }
-        return hostInMaintenance;
-    }
-
-    @Override
-    public Host updateHost(final UpdateHostCmd cmd) throws NoTransitionException {
-        final Long hostId = cmd.getId();
-        final Long guestOSCategoryId = cmd.getOsCategoryId();
-
-        // Verify that the host exists
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
-        }
-
-        if (cmd.getAllocationState() != null) {
-            final ResourceState.Event resourceEvent = ResourceState.Event.toEvent(cmd.getAllocationState());
-            if (resourceEvent != ResourceState.Event.Enable && resourceEvent != ResourceState.Event.Disable) {
-                throw new CloudRuntimeException("Invalid allocation state:" + cmd.getAllocationState() + ", only Enable/Disable are allowed");
-            }
-
-            resourceStateTransitTo(host, resourceEvent, _nodeId);
-        }
-
-        if (guestOSCategoryId != null) {
-            // Verify that the guest OS Category exists
-            if (!(guestOSCategoryId > 0) || _guestOSCategoryDao.findById(guestOSCategoryId) == null) {
-                throw new InvalidParameterValueException("Please specify a valid guest OS category.");
-            }
-
-            final GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
-            final DetailVO guestOSDetail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
-
-            if (guestOSCategory != null && !GuestOSCategoryVO.CATEGORY_NONE.equalsIgnoreCase(guestOSCategory.getName())) {
-                // Create/Update an entry for guest.os.category.id
-                if (guestOSDetail != null) {
-                    guestOSDetail.setValue(String.valueOf(guestOSCategory.getId()));
-                    _hostDetailsDao.update(guestOSDetail.getId(), guestOSDetail);
-                } else {
-                    final Map<String, String> detail = new HashMap<String, String>();
-                    detail.put("guest.os.category.id", String.valueOf(guestOSCategory.getId()));
-                    _hostDetailsDao.persist(hostId, detail);
-                }
-            } else {
-                // Delete any existing entry for guest.os.category.id
-                if (guestOSDetail != null) {
-                    _hostDetailsDao.remove(guestOSDetail.getId());
-                }
-            }
-        }
-
-        final List<String> hostTags = cmd.getHostTags();
-        if (hostTags != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Updating Host Tags to :" + hostTags);
-            }
-            _hostTagsDao.persist(hostId, hostTags);
-        }
-
-        final String url = cmd.getUrl();
-        if (url != null) {
-            _storageMgr.updateSecondaryStorage(cmd.getId(), cmd.getUrl());
-        }
-
-        final HostVO updatedHost = _hostDao.findById(hostId);
-        return updatedHost;
-    }
-
-    @Override
-    public Cluster getCluster(final Long clusterId) {
-        return _clusterDao.findById(clusterId);
-    }
-
-    @Override
-    public DataCenter getZone(Long zoneId) {
-        return _dcDao.findById(zoneId);
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _defaultSystemVMHypervisor = HypervisorType.getType(_configDao.getValue(Config.SystemVMDefaultHypervisor.toString()));
-        _gson = GsonHelper.getGson();
-
-        _hypervisorsInDC = _hostDao.createSearchBuilder(String.class);
-        _hypervisorsInDC.select(null, Func.DISTINCT, _hypervisorsInDC.entity().getHypervisorType());
-        _hypervisorsInDC.and("hypervisorType", _hypervisorsInDC.entity().getHypervisorType(), SearchCriteria.Op.NNULL);
-        _hypervisorsInDC.and("dataCenter", _hypervisorsInDC.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        _hypervisorsInDC.and("id", _hypervisorsInDC.entity().getId(), SearchCriteria.Op.NEQ);
-        _hypervisorsInDC.and("type", _hypervisorsInDC.entity().getType(), SearchCriteria.Op.EQ);
-        _hypervisorsInDC.done();
-
-        _gpuAvailability = _hostGpuGroupsDao.createSearchBuilder();
-        _gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ);
-        _gpuAvailability.and("groupName", _gpuAvailability.entity().getGroupName(), Op.EQ);
-        final SearchBuilder<VGPUTypesVO> join1 = _vgpuTypesDao.createSearchBuilder();
-        join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ);
-        join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT);
-        _gpuAvailability.join("groupId", join1, _gpuAvailability.entity().getId(), join1.entity().getGpuGroupId(), JoinBuilder.JoinType.INNER);
-        _gpuAvailability.done();
-
-        return true;
-    }
-
-    @Override
-    public List<HypervisorType> getSupportedHypervisorTypes(final long zoneId, final boolean forVirtualRouter, final Long podId) {
-        final List<HypervisorType> hypervisorTypes = new ArrayList<HypervisorType>();
-
-        List<ClusterVO> clustersForZone = new ArrayList<ClusterVO>();
-        if (podId != null) {
-            clustersForZone = _clusterDao.listByPodId(podId);
-        } else {
-            clustersForZone = _clusterDao.listByZoneId(zoneId);
-        }
-
-        for (final ClusterVO cluster : clustersForZone) {
-            final HypervisorType hType = cluster.getHypervisorType();
-            if (!forVirtualRouter || forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm) {
-                hypervisorTypes.add(hType);
-            }
-        }
-
-        return hypervisorTypes;
-    }
-
-    @Override
-    public HypervisorType getDefaultHypervisor(final long zoneId) {
-        HypervisorType defaultHyper = HypervisorType.None;
-        if (_defaultSystemVMHypervisor != HypervisorType.None) {
-            defaultHyper = _defaultSystemVMHypervisor;
-        }
-
-        final DataCenterVO dc = _dcDao.findById(zoneId);
-        if (dc == null) {
-            return HypervisorType.None;
-        }
-        _dcDao.loadDetails(dc);
-        final String defaultHypervisorInZone = dc.getDetail("defaultSystemVMHypervisorType");
-        if (defaultHypervisorInZone != null) {
-            defaultHyper = HypervisorType.getType(defaultHypervisorInZone);
-        }
-
-        final List<VMTemplateVO> systemTemplates = _templateDao.listAllSystemVMTemplates();
-        boolean isValid = false;
-        for (final VMTemplateVO template : systemTemplates) {
-            if (template.getHypervisorType() == defaultHyper) {
-                isValid = true;
-                break;
-            }
-        }
-
-        if (isValid) {
-            final List<ClusterVO> clusters = _clusterDao.listByDcHyType(zoneId, defaultHyper.toString());
-            if (clusters.size() <= 0) {
-                isValid = false;
-            }
-        }
-
-        if (isValid) {
-            return defaultHyper;
-        } else {
-            return HypervisorType.None;
-        }
-    }
-
-    @Override
-    public HypervisorType getAvailableHypervisor(final long zoneId) {
-        HypervisorType defaultHype = getDefaultHypervisor(zoneId);
-        if (defaultHype == HypervisorType.None) {
-            final List<HypervisorType> supportedHypes = getSupportedHypervisorTypes(zoneId, false, null);
-            if (supportedHypes.size() > 0) {
-                Collections.shuffle(supportedHypes);
-                defaultHype = supportedHypes.get(0);
-            }
-        }
-
-        if (defaultHype == HypervisorType.None) {
-            defaultHype = HypervisorType.Any;
-        }
-        return defaultHype;
-    }
-
-    @Override
-    public void registerResourceStateAdapter(final String name, final ResourceStateAdapter adapter) {
-        synchronized (_resourceStateAdapters) {
-            if (_resourceStateAdapters.get(name) != null) {
-                throw new CloudRuntimeException(name + " has registered");
-            }
-            _resourceStateAdapters.put(name, adapter);
-        }
-    }
-
-    @Override
-    public void unregisterResourceStateAdapter(final String name) {
-        synchronized (_resourceStateAdapters) {
-            _resourceStateAdapters.remove(name);
-        }
-    }
-
-    private Object dispatchToStateAdapters(final ResourceStateAdapter.Event event, final boolean singleTaker, final Object... args) {
-        synchronized (_resourceStateAdapters) {
-            final Iterator<Map.Entry<String, ResourceStateAdapter>> it = _resourceStateAdapters.entrySet().iterator();
-            Object result = null;
-            while (it.hasNext()) {
-                final Map.Entry<String, ResourceStateAdapter> item = it.next();
-                final ResourceStateAdapter adapter = item.getValue();
-
-                final String msg = "Dispatching resource state event " + event + " to " + item.getKey();
-                s_logger.debug(msg);
-
-                if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) {
-                    result = adapter.createHostVOForConnectedAgent((HostVO)args[0], (StartupCommand[])args[1]);
-                    if (result != null && singleTaker) {
-                        break;
-                    }
-                } else if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT) {
-                    result =
-                            adapter.createHostVOForDirectConnectAgent((HostVO)args[0], (StartupCommand[])args[1], (ServerResource)args[2], (Map<String, String>)args[3],
-                                    (List<String>)args[4]);
-                    if (result != null && singleTaker) {
-                        break;
-                    }
-                } else if (event == ResourceStateAdapter.Event.DELETE_HOST) {
-                    try {
-                        result = adapter.deleteHost((HostVO)args[0], (Boolean)args[1], (Boolean)args[2]);
-                        if (result != null) {
-                            break;
-                        }
-                    } catch (final UnableDeleteHostException e) {
-                        s_logger.debug("Adapter " + adapter.getName() + " says unable to delete host", e);
-                        result = new ResourceStateAdapter.DeleteHostAnswer(false, true);
-                    }
-                } else {
-                    throw new CloudRuntimeException("Unknown resource state event:" + event);
-                }
-            }
-
-            return result;
-        }
-    }
-
-    @Override
-    public void checkCIDR(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPrivateNetmask) throws IllegalArgumentException {
-        if (serverPrivateIP == null) {
-            return;
-        }
-        // Get the CIDR address and CIDR size
-        final String cidrAddress = pod.getCidrAddress();
-        final long cidrSize = pod.getCidrSize();
-
-        // If the server's private IP address is not in the same subnet as the
-        // pod's CIDR, return false
-        final String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
-        final String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
-        if (!cidrSubnet.equals(serverSubnet)) {
-            s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " +
-                    dc.getName());
-            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() +
-                    " and zone: " + dc.getName());
-        }
-
-        // If the server's private netmask is less inclusive than the pod's CIDR
-        // netmask, return false
-        final String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
-        final long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
-        final long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
-        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
-            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() +
-                    " and zone: " + dc.getName());
-        }
-
-    }
-
-    private boolean checkCIDR(final HostPodVO pod, final String serverPrivateIP, final String serverPrivateNetmask) {
-        if (serverPrivateIP == null) {
-            return true;
-        }
-        // Get the CIDR address and CIDR size
-        final String cidrAddress = pod.getCidrAddress();
-        final long cidrSize = pod.getCidrSize();
-
-        // If the server's private IP address is not in the same subnet as the
-        // pod's CIDR, return false
-        final String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
-        final String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
-        if (!cidrSubnet.equals(serverSubnet)) {
-            return false;
-        }
-
-        // If the server's private netmask is less inclusive than the pod's CIDR
-        // netmask, return false
-        final String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
-        final long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
-        final long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
-        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
-            return false;
-        }
-        return true;
-    }
-
-    private HostVO getNewHost(StartupCommand[] startupCommands) {
-        StartupCommand startupCommand = startupCommands[0];
-
-        HostVO host = findHostByGuid(startupCommand.getGuid());
-
-        if (host != null) {
-            return host;
-        }
-
-        host = findHostByGuid(startupCommand.getGuidWithoutResource());
-
-        if (host != null) {
-            return host;
-        }
-
-        return null;
-    }
-
-    protected HostVO createHostVO(final StartupCommand[] cmds, final ServerResource resource, final Map<String, String> details, List<String> hostTags,
-            final ResourceStateAdapter.Event stateEvent) {
-        boolean newHost = false;
-        StartupCommand startup = cmds[0];
-
-        HostVO host = getNewHost(cmds);
-
-        if (host == null) {
-            host = new HostVO(startup.getGuid());
-
-            newHost = true;
-        }
-
-        String dataCenter = startup.getDataCenter();
-        String pod = startup.getPod();
-        final String cluster = startup.getCluster();
-
-        if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) {
-            final List<HostPodVO> pods = _podDao.listAllIncludingRemoved();
-            for (final HostPodVO hpv : pods) {
-                if (checkCIDR(hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
-                    pod = hpv.getName();
-                    dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName();
-                    break;
-                }
-            }
-        }
-
-        long dcId = -1;
-        DataCenterVO dc = _dcDao.findByName(dataCenter);
-        if (dc == null) {
-            try {
-                dcId = Long.parseLong(dataCenter);
-                dc = _dcDao.findById(dcId);
-            } catch (final NumberFormatException e) {
-                s_logger.debug("Cannot parse " + dataCenter + " into Long.");
-            }
-        }
-        if (dc == null) {
-            throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
-        }
-        dcId = dc.getId();
-
-        HostPodVO p = _podDao.findByName(pod, dcId);
-        if (p == null) {
-            try {
-                final long podId = Long.parseLong(pod);
-                p = _podDao.findById(podId);
-            } catch (final NumberFormatException e) {
-                s_logger.debug("Cannot parse " + pod + " into Long.");
-            }
-        }
-        /*
-         * ResourceStateAdapter is responsible for throwing Exception if Pod is
-         * null and non-null is required. for example, XcpServerDiscoever.
-         * Others, like PxeServer, ExternalFireware don't require Pod
-         */
-        final Long podId = p == null ? null : p.getId();
-
-        Long clusterId = null;
-        if (cluster != null) {
-            try {
-                clusterId = Long.valueOf(cluster);
-            } catch (final NumberFormatException e) {
-                if (podId != null) {
-                    ClusterVO c = _clusterDao.findBy(cluster, podId.longValue());
-                    if (c == null) {
-                        c = new ClusterVO(dcId, podId.longValue(), cluster);
-                        c = _clusterDao.persist(c);
-                    }
-                    clusterId = c.getId();
-                }
-            }
-        }
-
-        if (startup instanceof StartupRoutingCommand) {
-            final StartupRoutingCommand ssCmd = (StartupRoutingCommand)startup;
-            final List<String> implicitHostTags = ssCmd.getHostTags();
-            if (!implicitHostTags.isEmpty()) {
-                if (hostTags == null) {
-                    hostTags = _hostTagsDao.gethostTags(host.getId());
-                }
-                if (hostTags != null) {
-                    implicitHostTags.removeAll(hostTags);
-                    hostTags.addAll(implicitHostTags);
-                } else {
-                    hostTags = implicitHostTags;
-                }
-            }
-        }
-
-        host.setDataCenterId(dc.getId());
-        host.setPodId(podId);
-        host.setClusterId(clusterId);
-        host.setPrivateIpAddress(startup.getPrivateIpAddress());
-        host.setPrivateNetmask(startup.getPrivateNetmask());
-        host.setPrivateMacAddress(startup.getPrivateMacAddress());
-        host.setPublicIpAddress(startup.getPublicIpAddress());
-        host.setPublicMacAddress(startup.getPublicMacAddress());
-        host.setPublicNetmask(startup.getPublicNetmask());
-        host.setStorageIpAddress(startup.getStorageIpAddress());
-        host.setStorageMacAddress(startup.getStorageMacAddress());
-        host.setStorageNetmask(startup.getStorageNetmask());
-        host.setVersion(startup.getVersion());
-        host.setName(startup.getName());
-        host.setManagementServerId(_nodeId);
-        host.setStorageUrl(startup.getIqn());
-        host.setLastPinged(System.currentTimeMillis() >> 10);
-        host.setHostTags(hostTags);
-        host.setDetails(details);
-        if (startup.getStorageIpAddressDeux() != null) {
-            host.setStorageIpAddressDeux(startup.getStorageIpAddressDeux());
-            host.setStorageMacAddressDeux(startup.getStorageMacAddressDeux());
-            host.setStorageNetmaskDeux(startup.getStorageNetmaskDeux());
-        }
-        if (resource != null) {
-            /* null when agent is connected agent */
-            host.setResource(resource.getClass().getName());
-        }
-
-        host = (HostVO)dispatchToStateAdapters(stateEvent, true, host, cmds, resource, details, hostTags);
-        if (host == null) {
-            throw new CloudRuntimeException("No resource state adapter response");
-        }
-
-        if (newHost) {
-            host = _hostDao.persist(host);
-        } else {
-            _hostDao.update(host.getId(), host);
-        }
-
-        if (startup instanceof StartupRoutingCommand) {
-            final StartupRoutingCommand ssCmd = (StartupRoutingCommand)startup;
-
-            updateSupportsClonedVolumes(host, ssCmd.getSupportsClonedVolumes());
-        }
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.InternalCreated, _nodeId);
-            /* Agent goes to Connecting status */
-            _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId);
-        } catch (final Exception e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + " to Creating state", e);
-            _agentMgr.agentStatusTransitTo(host, Status.Event.Error, _nodeId);
-            try {
-                resourceStateTransitTo(host, ResourceState.Event.Error, _nodeId);
-            } catch (final NoTransitionException e1) {
-                s_logger.debug("Cannot transmit host " + host.getId() + "to Error state", e);
-            }
-        }
-
-        return host;
-    }
-
-    private void updateSupportsClonedVolumes(HostVO host, boolean supportsClonedVolumes) {
-        final String name = "supportsResign";
-
-        DetailVO hostDetail = _hostDetailsDao.findDetail(host.getId(), name);
-
-        if (hostDetail != null) {
-            if (supportsClonedVolumes) {
-                hostDetail.setValue(Boolean.TRUE.toString());
-
-                _hostDetailsDao.update(hostDetail.getId(), hostDetail);
-            }
-            else {
-                _hostDetailsDao.remove(hostDetail.getId());
-            }
-        }
-        else {
-            if (supportsClonedVolumes) {
-                hostDetail = new DetailVO(host.getId(), name, Boolean.TRUE.toString());
-
-                _hostDetailsDao.persist(hostDetail);
-            }
-        }
-
-        boolean clusterSupportsResigning = true;
-
-        List<HostVO> hostVOs = _hostDao.findByClusterId(host.getClusterId());
-
-        for (HostVO hostVO : hostVOs) {
-            DetailVO hostDetailVO = _hostDetailsDao.findDetail(hostVO.getId(), name);
-
-            if (hostDetailVO == null || Boolean.parseBoolean(hostDetailVO.getValue()) == false) {
-                clusterSupportsResigning = false;
-
-                break;
-            }
-        }
-
-        ClusterDetailsVO clusterDetailsVO = _clusterDetailsDao.findDetail(host.getClusterId(), name);
-
-        if (clusterDetailsVO != null) {
-            if (clusterSupportsResigning) {
-                clusterDetailsVO.setValue(Boolean.TRUE.toString());
-
-                _clusterDetailsDao.update(clusterDetailsVO.getId(), clusterDetailsVO);
-            }
-            else {
-                _clusterDetailsDao.remove(clusterDetailsVO.getId());
-            }
-        }
-        else {
-            if (clusterSupportsResigning) {
-                clusterDetailsVO = new ClusterDetailsVO(host.getClusterId(), name, Boolean.TRUE.toString());
-
-                _clusterDetailsDao.persist(clusterDetailsVO);
-            }
-        }
-    }
-
-    private boolean isFirstHostInCluster(final HostVO host) {
-        boolean isFirstHost = true;
-        if (host.getClusterId() != null) {
-            final SearchBuilder<HostVO> sb = _hostDao.createSearchBuilder();
-            sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.NULL);
-            sb.and("cluster", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
-            sb.done();
-            final SearchCriteria<HostVO> sc = sb.create();
-            sc.setParameters("cluster", host.getClusterId());
-
-            final List<HostVO> hosts = _hostDao.search(sc, null);
-            if (hosts != null && hosts.size() > 1) {
-                isFirstHost = false;
-            }
-        }
-        return isFirstHost;
-    }
-
-    private void markHostAsDisconnected(HostVO host, final StartupCommand[] cmds) {
-        if (host == null) { // in case host is null due to some errors, try
-            // reloading the host from db
-            if (cmds != null) {
-                final StartupCommand firstCmd = cmds[0];
-                host = findHostByGuid(firstCmd.getGuid());
-                if (host == null) {
-                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
-                }
-            }
-        }
-
-        if (host != null) {
-            // Change agent status to Alert, so that host is considered for
-            // reconnection next time
-            _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId);
-        }
-    }
-
-    private Host createHostAndAgent(final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
-        HostVO host = null;
-        StartupCommand[] cmds = null;
-        boolean hostExists = false;
-        boolean created = false;
-
-        try {
-            cmds = resource.initialize();
-            if (cmds == null) {
-                s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned");
-                return null;
-            }
-
-            /* Generate a random version in a dev setup situation */
-            if (this.getClass().getPackage().getImplementationVersion() == null) {
-                for (final StartupCommand cmd : cmds) {
-                    if (cmd.getVersion() == null) {
-                        cmd.setVersion(Long.toString(System.currentTimeMillis()));
-                    }
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
-            }
-
-            if (old) {
-                final StartupCommand firstCmd = cmds[0];
-                host = findHostByGuid(firstCmd.getGuid());
-                if (host == null) {
-                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
-                }
-                if (host != null && host.getRemoved() == null) { // host already added, no need to add again
-                    s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new");
-                    hostExists = true; // ensures that host status is left unchanged in case of adding same one again
-                    return null;
-                }
-            }
-
-            // find out if the host we want to connect to is new (so we can send an event)
-            boolean newHost = getNewHost(cmds) == null;
-
-            host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT);
-
-            if (host != null) {
-                created = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance, newHost);
-                /* reload myself from database */
-                host = _hostDao.findById(host.getId());
-            }
-        } catch (final Exception e) {
-            s_logger.warn("Unable to connect due to ", e);
-        } finally {
-            if (hostExists) {
-                if (cmds != null) {
-                    resource.disconnected();
-                }
-            } else {
-                if (!created) {
-                    if (cmds != null) {
-                        resource.disconnected();
-                    }
-                    markHostAsDisconnected(host, cmds);
-                }
-            }
-        }
-
-        return host;
-    }
-
-    private Host createHostAndAgentDeferred(final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
-        HostVO host = null;
-        StartupCommand[] cmds = null;
-        boolean hostExists = false;
-        boolean deferAgentCreation = true;
-        boolean created = false;
-
-        try {
-            cmds = resource.initialize();
-            if (cmds == null) {
-                s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned");
-                return null;
-            }
-
-            /* Generate a random version in a dev setup situation */
-            if (this.getClass().getPackage().getImplementationVersion() == null) {
-                for (final StartupCommand cmd : cmds) {
-                    if (cmd.getVersion() == null) {
-                        cmd.setVersion(Long.toString(System.currentTimeMillis()));
-                    }
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
-            }
-
-            if (old) {
-                final StartupCommand firstCmd = cmds[0];
-                host = findHostByGuid(firstCmd.getGuid());
-                if (host == null) {
-                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
-                }
-                if (host != null && host.getRemoved() == null) { // host already
-                    // added, no
-                    // need to add
-                    // again
-                    s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new");
-                    hostExists = true; // ensures that host status is left
-                    // unchanged in case of adding same one
-                    // again
-                    return null;
-                }
-            }
-
-            host = null;
-            boolean newHost = false;
-
-            final GlobalLock addHostLock = GlobalLock.getInternLock("AddHostLock");
-
-            try {
-                if (addHostLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    // to safely determine first host in cluster in multi-MS scenario
-                    try {
-                        // find out if the host we want to connect to is new (so we can send an event)
-                        newHost = getNewHost(cmds) == null;
-
-                        host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT);
-
-                        if (host != null) {
-                            // if first host in cluster no need to defer agent creation
-                            deferAgentCreation = !isFirstHostInCluster(host);
-                        }
-                    } finally {
-                        addHostLock.unlock();
-                    }
-                }
-            } finally {
-                addHostLock.releaseRef();
-            }
-
-            if (host != null) {
-                if (!deferAgentCreation) { // if first host in cluster then
-                    created = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance, newHost);
-                    host = _hostDao.findById(host.getId()); // reload
-                } else {
-                    host = _hostDao.findById(host.getId()); // reload
-                    // force host status to 'Alert' so that it is loaded for
-                    // connection during next scan task
-                    _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId);
-
-                    host = _hostDao.findById(host.getId()); // reload
-                    host.setLastPinged(0); // so that scan task can pick it up
-                    _hostDao.update(host.getId(), host);
-
-                }
-            }
-        } catch (final Exception e) {
-            s_logger.warn("Unable to connect due to ", e);
-        } finally {
-            if (hostExists) {
-                if (cmds != null) {
-                    resource.disconnected();
-                }
-            } else {
-                if (!deferAgentCreation && !created) {
-                    if (cmds != null) {
-                        resource.disconnected();
-                    }
-                    markHostAsDisconnected(host, cmds);
-                }
-            }
-        }
-
-        return host;
-    }
-
-    @Override
-    public Host createHostAndAgent(final Long hostId, final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
-        final Host host = createHostAndAgent(resource, details, old, hostTags, forRebalance);
-        return host;
-    }
-
-    @Override
-    public Host addHost(final long zoneId, final ServerResource resource, final Type hostType, final Map<String, String> hostDetails) {
-        // Check if the zone exists in the system
-        if (_dcDao.findById(zoneId) == null) {
-            throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
-        }
-
-        final Map<String, String> details = hostDetails;
-        final String guid = details.get("guid");
-        final List<HostVO> currentHosts = listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId);
-        for (final HostVO currentHost : currentHosts) {
-            if (currentHost.getGuid().equals(guid)) {
-                return currentHost;
-            }
-        }
-
-        return createHostAndAgent(resource, hostDetails, true, null, false);
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(final StartupCommand[] cmds) {
-        return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED);
-    }
-
-    private void checkIPConflicts(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPrivateNetmask, final String serverPublicIP, final String serverPublicNetmask) {
-        // If the server's private IP is the same as is public IP, this host has
-        // a host-only private network. Don't check for conflicts with the
-        // private IP address table.
-        if (!ObjectUtils.equals(serverPrivateIP, serverPublicIP)) {
-            if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
-                // If the server's private IP address is already in the
-                // database, return false
-                final List<DataCenterIpAddressVO> existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
-
-                assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
-                if (existingPrivateIPs.size() > 1) {
-                    throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() +
-                            " and zone: " + dc.getName());
-                }
-                if (existingPrivateIPs.size() == 1) {
-                    final DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
-                    if (vo.getInstanceId() != null) {
-                        throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() +
-                                " and zone: " + dc.getName());
-                    }
-                }
-            }
-        }
-
-        if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
-            // If the server's public IP address is already in the database,
-            // return false
-            final List<IPAddressVO> existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
-            if (existingPublicIPs.size() > 0) {
-                throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
-            }
-        }
-    }
-
-    @Override
-    public HostVO fillRoutingHostVO(final HostVO host, final StartupRoutingCommand ssCmd, final HypervisorType hyType, Map<String, String> details, final List<String> hostTags) {
-        if (host.getPodId() == null) {
-            s_logger.error("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
-            throw new IllegalArgumentException("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
-        }
-
-        final ClusterVO clusterVO = _clusterDao.findById(host.getClusterId());
-        if (clusterVO.getHypervisorType() != hyType) {
-            throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + hyType + " into cluster: " + clusterVO.getId() +
-                    " whose hypervisor type is: " + clusterVO.getHypervisorType());
-        }
-
-        final Map<String, String> hostDetails = ssCmd.getHostDetails();
-        if (hostDetails != null) {
-            if (details != null) {
-                details.putAll(hostDetails);
-            } else {
-                details = hostDetails;
-            }
-        }
-
-        final HostPodVO pod = _podDao.findById(host.getPodId());
-        final DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
-        checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask());
-        host.setType(com.cloud.host.Host.Type.Routing);
-        host.setDetails(details);
-        host.setCaps(ssCmd.getCapabilities());
-        host.setCpuSockets(ssCmd.getCpuSockets());
-        host.setCpus(ssCmd.getCpus());
-        host.setTotalMemory(ssCmd.getMemory());
-        host.setSpeed(ssCmd.getSpeed());
-        host.setHypervisorType(hyType);
-        host.setHypervisorVersion(ssCmd.getHypervisorVersion());
-        host.setGpuGroups(ssCmd.getGpuGroupDetails());
-        return host;
-    }
-
-    @Override
-    public void deleteRoutingHost(final HostVO host, final boolean isForced, final boolean forceDestroyStorage) throws UnableDeleteHostException {
-        if (host.getType() != Host.Type.Routing) {
-            throw new CloudRuntimeException("Non-Routing host gets in deleteRoutingHost, id is " + host.getId());
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Deleting Host: " + host.getId() + " Guid:" + host.getGuid());
-        }
-
-        if (forceDestroyStorage) {
-            // put local storage into mainenance mode, will set all the VMs on
-            // this local storage into stopped state
-            final StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host.getId());
-            if (storagePool != null) {
-                if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) {
-                    try {
-                        final StoragePool pool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId());
-                        if (pool == null) {
-                            s_logger.debug("Failed to set primary storage into maintenance mode");
-
-                            throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode");
-                        }
-                    } catch (final Exception e) {
-                        s_logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString());
-                        throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString());
-                    }
-                }
-
-                final List<VMInstanceVO> vmsOnLocalStorage = _storageMgr.listByStoragePool(storagePool.getId());
-                for (final VMInstanceVO vm : vmsOnLocalStorage) {
-                    try {
-                        _vmMgr.destroy(vm.getUuid(), false);
-                    } catch (final Exception e) {
-                        final String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                        s_logger.debug(errorMsg, e);
-                        throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
-                    }
-                }
-            }
-        } else {
-            // Check if there are vms running/starting/stopping on this host
-            final List<VMInstanceVO> vms = _vmDao.listByHostId(host.getId());
-            if (!vms.isEmpty()) {
-                if (isForced) {
-                    // Stop HA disabled vms and HA enabled vms in Stopping state
-                    // Restart HA enabled vms
-                    for (final VMInstanceVO vm : vms) {
-                        if (!vm.isHaEnabled() || vm.getState() == State.Stopping) {
-                            s_logger.debug("Stopping vm: " + vm + " as a part of deleteHost id=" + host.getId());
-                            try {
-                                _vmMgr.advanceStop(vm.getUuid(), false);
-                            } catch (final Exception e) {
-                                final String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId();
-                                s_logger.debug(errorMsg, e);
-                                throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
-                            }
-                        } else if (vm.isHaEnabled() && (vm.getState() == State.Running || vm.getState() == State.Starting)) {
-                            s_logger.debug("Scheduling restart for vm: " + vm + " " + vm.getState() + " on the host id=" + host.getId());
-                            _haMgr.scheduleRestart(vm, false);
-                        }
-                    }
-                } else {
-                    throw new UnableDeleteHostException("Unable to delete the host as there are vms in " + vms.get(0).getState() +
-                            " state using this host and isForced=false specified");
-                }
-            }
-        }
-    }
-
-    private boolean doCancelMaintenance(final long hostId) {
-        HostVO host;
-        host = _hostDao.findById(hostId);
-        if (host == null || host.getRemoved() != null) {
-            s_logger.warn("Unable to find host " + hostId);
-            return true;
-        }
-
-        /*
-         * TODO: think twice about returning true or throwing out exception, I
-         * really prefer to exception that always exposes bugs
-         */
-        if (host.getResourceState() != ResourceState.PrepareForMaintenance && host.getResourceState() != ResourceState.Maintenance &&
-                host.getResourceState() != ResourceState.ErrorInMaintenance) {
-            throw new CloudRuntimeException("Cannot perform cancelMaintenance when resource state is " + host.getResourceState() + ", hostId = " + hostId);
-        }
-
-        /* TODO: move to listener */
-        _haMgr.cancelScheduledMigrations(host);
-
-        boolean vms_migrating = false;
-        final List<VMInstanceVO> vms = _haMgr.findTakenMigrationWork();
-        for (final VMInstanceVO vm : vms) {
-            if (vm.getHostId() != null && vm.getHostId() == hostId) {
-                s_logger.warn("Unable to cancel migration because the vm is being migrated: " + vm + ", hostId = " + hostId);
-                vms_migrating = true;
-            }
-        }
-
-        handleAgentIfNotConnected(host, vms_migrating);
-
-        try {
-            resourceStateTransitTo(host, ResourceState.Event.AdminCancelMaintenance, _nodeId);
-            _agentMgr.pullAgentOutMaintenance(hostId);
-            retryHostMaintenance.remove(hostId);
-        } catch (final NoTransitionException e) {
-            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
-            return false;
-        }
-
-        return true;
-
-    }
-
-    /**
-     * Handle agent (if available) if its not connected before cancelling maintenance.
-     * Agent must be connected before cancelling maintenance.
-     * If the host status is not Up:
-     * - If kvm.ssh.to.agent is true, then SSH into the host and restart the agent.
-     * - If kvm.shh.to.agent is false, then fail cancelling maintenance
-     */
-    protected void handleAgentIfNotConnected(HostVO host, boolean vmsMigrating) {
-        final boolean isAgentOnHost = host.getHypervisorType() == HypervisorType.KVM ||
-                host.getHypervisorType() == HypervisorType.LXC;
-        if (!isAgentOnHost || vmsMigrating || host.getStatus() == Status.Up) {
-            return;
-        }
-        final boolean sshToAgent = Boolean.parseBoolean(_configDao.getValue(KvmSshToAgentEnabled.key()));
-        if (sshToAgent) {
-            Pair<String, String> credentials = getHostCredentials(host);
-            connectAndRestartAgentOnHost(host, credentials.first(), credentials.second());
-        } else {
-            throw new CloudRuntimeException("SSH access is disabled, cannot cancel maintenance mode as " +
-                    "host agent is not connected");
-        }
-    }
-
-    /**
-     * Get host credentials
-     * @throws CloudRuntimeException if username or password are not found
-     */
-    protected Pair<String, String> getHostCredentials(HostVO host) {
-        _hostDao.loadDetails(host);
-        final String password = host.getDetail("password");
-        final String username = host.getDetail("username");
-        if (password == null || username == null) {
-            throw new CloudRuntimeException("SSH to agent is enabled, but username/password credentials are not found");
-        }
-        return new Pair<>(username, password);
-    }
-
-    /**
-     * True if agent is restarted via SSH. Assumes kvm.ssh.to.agent = true and host status is not Up
-     */
-    protected void connectAndRestartAgentOnHost(HostVO host, String username, String password) {
-        final com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(
-                host.getPrivateIpAddress(), 22, username, password);
-        if (connection == null) {
-            throw new CloudRuntimeException("SSH to agent is enabled, but failed to connect to host: " + host.getPrivateIpAddress());
-        }
-        try {
-            SSHCmdHelper.SSHCmdResult result = SSHCmdHelper.sshExecuteCmdOneShot(
-                    connection, "service cloudstack-agent restart");
-            if (result.getReturnCode() != 0) {
-                throw new CloudRuntimeException("Could not restart agent on host " + host.getId() + " due to: " + result.getStdErr());
-            }
-            s_logger.debug("cloudstack-agent restart result: " + result.toString());
-        } catch (final SshException e) {
-            throw new CloudRuntimeException("SSH to agent is enabled, but agent restart failed", e);
-        }
-    }
-
-    private boolean cancelMaintenance(final long hostId) {
-        try {
-            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.AdminCancelMaintenance);
-
-            if (result != null) {
-                return result;
-            }
-        } catch (final AgentUnavailableException e) {
-            return false;
-        }
-
-        return doCancelMaintenance(hostId);
-    }
-
-    @Override
-    public boolean executeUserRequest(final long hostId, final ResourceState.Event event) throws AgentUnavailableException {
-        if (event == ResourceState.Event.AdminAskMaintenace) {
-            return doMaintain(hostId);
-        } else if (event == ResourceState.Event.AdminCancelMaintenance) {
-            return doCancelMaintenance(hostId);
-        } else if (event == ResourceState.Event.DeleteHost) {
-            /* TODO: Ask alex why we assume the last two parameters are false */
-            return doDeleteHost(hostId, false, false);
-        } else if (event == ResourceState.Event.Unmanaged) {
-            return doUmanageHost(hostId);
-        } else if (event == ResourceState.Event.UpdatePassword) {
-            return doUpdateHostPassword(hostId);
-        } else {
-            throw new CloudRuntimeException("Received an resource event we are not handling now, " + event);
-        }
-    }
-
-    private boolean doUmanageHost(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            s_logger.debug("Cannot find host " + hostId + ", assuming it has been deleted, skip umanage");
-            return true;
-        }
-
-        if (host.getHypervisorType() == HypervisorType.KVM || host.getHypervisorType() == HypervisorType.LXC) {
-            final MaintainAnswer answer = (MaintainAnswer)_agentMgr.easySend(hostId, new MaintainCommand());
-        }
-
-        _agentMgr.disconnectWithoutInvestigation(hostId, Event.ShutdownRequested);
-        return true;
-    }
-
-    @Override
-    public boolean umanageHost(final long hostId) {
-        try {
-            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.Unmanaged);
-
-            if (result != null) {
-                return result;
-            }
-        } catch (final AgentUnavailableException e) {
-            return false;
-        }
-
-        return doUmanageHost(hostId);
-    }
-
-    private boolean doUpdateHostPassword(final long hostId) {
-        if (!_agentMgr.isAgentAttached(hostId)) {
-            return false;
-        }
-
-        DetailVO nv = _hostDetailsDao.findDetail(hostId, ApiConstants.USERNAME);
-        final String username = nv.getValue();
-        nv = _hostDetailsDao.findDetail(hostId, ApiConstants.PASSWORD);
-        final String password = nv.getValue();
-
-
-        final HostVO host = _hostDao.findById(hostId);
-        final String hostIpAddress = host.getPrivateIpAddress();
-
-        final UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(username, password, hostIpAddress);
-        final Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        s_logger.info("Result returned from update host password ==> " + answer.getDetails());
-        return answer.getResult();
-    }
-
-    @Override
-    public boolean updateClusterPassword(final UpdateHostPasswordCmd command) {
-        final boolean shouldUpdateHostPasswd = command.getUpdatePasswdOnHost();
-        // get agents for the cluster
-        final List<HostVO> hosts = listAllHostsInCluster(command.getClusterId());
-        for (final HostVO host : hosts) {
-            try {
-                /*
-                 * FIXME: this is a buggy logic, check with alex. Shouldn't
-                 * return if propagation return non null
-                 */
-                final Boolean result = propagateResourceEvent(host.getId(), ResourceState.Event.UpdatePassword);
-                if (result != null) {
-                    return result;
-                }
-            } catch (final AgentUnavailableException e) {
-                s_logger.error("Agent is not availbale!", e);
-            }
-
-            if (shouldUpdateHostPasswd) {
-                final boolean isUpdated = doUpdateHostPassword(host.getId());
-                if (!isUpdated) {
-                    throw new CloudRuntimeException("CloudStack failed to update the password of the Host with UUID / ID ==> " + host.getUuid() + " / " + host.getId() + ". Please make sure you are still able to connect to your hosts.");
-                }
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean updateHostPassword(final UpdateHostPasswordCmd command) {
-        // update agent attache password
-        try {
-            final Boolean result = propagateResourceEvent(command.getHostId(), ResourceState.Event.UpdatePassword);
-            if (result != null) {
-                return result;
-            }
-        } catch (final AgentUnavailableException e) {
-            s_logger.error("Agent is not availbale!", e);
-        }
-
-        final boolean shouldUpdateHostPasswd = command.getUpdatePasswdOnHost();
-        // If shouldUpdateHostPasswd has been set to false, the method doUpdateHostPassword() won't be called.
-        return shouldUpdateHostPasswd && doUpdateHostPassword(command.getHostId());
-    }
-
-    public String getPeerName(final long agentHostId) {
-
-        final HostVO host = _hostDao.findById(agentHostId);
-        if (host != null && host.getManagementServerId() != null) {
-            if (_clusterMgr.getSelfPeerName().equals(Long.toString(host.getManagementServerId()))) {
-                return null;
-            }
-
-            return Long.toString(host.getManagementServerId());
-        }
-        return null;
-    }
-
-    public Boolean propagateResourceEvent(final long agentId, final ResourceState.Event event) throws AgentUnavailableException {
-        final String msPeer = getPeerName(agentId);
-        if (msPeer == null) {
-            return null;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Propagating agent change request event:" + event.toString() + " to agent:" + agentId);
-        }
-        final Command[] cmds = new Command[1];
-        cmds[0] = new PropagateResourceEventCommand(agentId, event);
-
-        final String AnsStr = _clusterMgr.execute(msPeer, agentId, _gson.toJson(cmds), true);
-        if (AnsStr == null) {
-            throw new AgentUnavailableException(agentId);
-        }
-
-        final Answer[] answers = _gson.fromJson(AnsStr, Answer[].class);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Result for agent change is " + answers[0].getResult());
-        }
-
-        return answers[0].getResult();
-    }
-
-    @Override
-    public boolean maintenanceFailed(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Cant not find host " + hostId);
-            }
-            return false;
-        } else {
-            try {
-                return resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId);
-            } catch (final NoTransitionException e) {
-                s_logger.debug("No next resource state for host " + host.getId() + " while current state is " + host.getResourceState() + " with event " +
-                        ResourceState.Event.UnableToMigrate, e);
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public List<HostVO> findDirectlyConnectedHosts() {
-        /* The resource column is not null for direct connected resource */
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getResource(), Op.NNULL);
-        sc.and(sc.entity().getResourceState(), Op.NIN, ResourceState.Disabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (type != null) {
-            sc.and(sc.entity().getType(), Op.EQ, type);
-        }
-        if (clusterId != null) {
-            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
-        }
-        if (podId != null) {
-            sc.and(sc.entity().getPodId(), Op.EQ, podId);
-        }
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (type != null) {
-            sc.and(sc.entity().getType(), Op.EQ, type);
-        }
-        if (clusterId != null) {
-            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
-        }
-        if (podId != null) {
-            sc.and(sc.entity().getPodId(), Op.EQ, podId);
-        }
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpHosts(Type type, Long clusterId, Long podId, long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (type != null) {
-            sc.and(sc.entity().getType(), Op.EQ, type);
-        }
-        if (clusterId != null) {
-            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
-        }
-        if (podId != null) {
-            sc.and(sc.entity().getPodId(), Op.EQ, podId);
-        }
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledNonHAHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
-        final String haTag = _haMgr.getHaTag();
-        return _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, haTag);
-    }
-
-    @Override
-    public List<HostVO> findHostByGuid(final long dcId, final String guid) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getGuid(), Op.EQ, guid);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllHostsInCluster(final long clusterId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listHostsInClusterByStatus(final long clusterId, final Status status) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
-        sc.and(sc.entity().getStatus(), Op.EQ, status);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledHostsInOneZoneByType(final Type type, final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, type);
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllNotInMaintenanceHostsInOneZone(final Type type, final Long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (dcId != null) {
-            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        }
-        sc.and(sc.entity().getType(), Op.EQ, type);
-        sc.and(sc.entity().getResourceState(), Op.NIN, ResourceState.Maintenance, ResourceState.ErrorInMaintenance, ResourceState.PrepareForMaintenance,
-                ResourceState.Error);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllHostsInOneZoneByType(final Type type, final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, type);
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllHostsInAllZonesByType(final Type type) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, type);
-        return sc.list();
-    }
-
-    @Override
-    public List<HypervisorType> listAvailHypervisorInZone(final Long hostId, final Long zoneId) {
-        final SearchCriteria<String> sc = _hypervisorsInDC.create();
-        if (zoneId != null) {
-            sc.setParameters("dataCenter", zoneId);
-        }
-        if (hostId != null) {
-            // exclude the given host, since we want to check what hypervisor is already handled
-            // in adding this new host
-            sc.setParameters("id", hostId);
-        }
-        sc.setParameters("type", Host.Type.Routing);
-
-        // The search is not able to return list of enums, so getting
-        // list of hypervisors as strings and then converting them to enum
-        final List<String> hvs = _hostDao.customSearch(sc, null);
-        final List<HypervisorType> hypervisors = new ArrayList<HypervisorType>();
-        for (final String hv : hvs) {
-            hypervisors.add(HypervisorType.getType(hv));
-        }
-        return hypervisors;
-    }
-
-    @Override
-    public HostVO findHostByGuid(final String guid) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getGuid(), Op.EQ, guid);
-        return sc.find();
-    }
-
-    @Override
-    public HostVO findHostByName(final String name) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getName(), Op.EQ, name);
-        return sc.find();
-    }
-
-    @Override
-    public HostStats getHostStatistics(final long hostId) {
-        final Answer answer = _agentMgr.easySend(hostId, new GetHostStatsCommand(_hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId).getName(), hostId));
-
-        if (answer != null && answer instanceof UnsupportedAnswer) {
-            return null;
-        }
-
-        if (answer == null || !answer.getResult()) {
-            final String msg = "Unable to obtain host " + hostId + " statistics. ";
-            s_logger.warn(msg);
-            return null;
-        } else {
-
-            // now construct the result object
-            if (answer instanceof GetHostStatsAnswer) {
-                return ((GetHostStatsAnswer)answer).getHostStats();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Long getGuestOSCategoryId(final long hostId) {
-        final HostVO host = _hostDao.findById(hostId);
-        if (host == null) {
-            return null;
-        } else {
-            _hostDao.loadDetails(host);
-            final DetailVO detail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
-            if (detail == null) {
-                return null;
-            } else {
-                return Long.parseLong(detail.getValue());
-            }
-        }
-    }
-
-    @Override
-    public String getHostTags(final long hostId) {
-        final List<String> hostTags = _hostTagsDao.gethostTags(hostId);
-        if (hostTags == null) {
-            return null;
-        } else {
-            return StringUtils.listToCsvTags(hostTags);
-        }
-    }
-
-    @Override
-    public List<PodCluster> listByDataCenter(final long dcId) {
-        final List<HostPodVO> pods = _podDao.listByDataCenterId(dcId);
-        final ArrayList<PodCluster> pcs = new ArrayList<PodCluster>();
-        for (final HostPodVO pod : pods) {
-            final List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
-            if (clusters.size() == 0) {
-                pcs.add(new PodCluster(pod, null));
-            } else {
-                for (final ClusterVO cluster : clusters) {
-                    pcs.add(new PodCluster(pod, cluster));
-                }
-            }
-        }
-        return pcs;
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledHostsInOneZoneByHypervisor(final HypervisorType type, final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getHypervisorType(), Op.EQ, type);
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
-        return sc.list();
-    }
-
-    @Override
-    public List<HostVO> listAllUpAndEnabledHostsInOneZone(final long dcId) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-
-        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
-
-        return sc.list();
-    }
-
-    @Override
-    public boolean isHostGpuEnabled(final long hostId) {
-        final SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
-        sc.setParameters("hostId", hostId);
-        return _hostGpuGroupsDao.customSearch(sc, null).size() > 0 ? true : false;
-    }
-
-    @Override
-    public List<HostGpuGroupsVO> listAvailableGPUDevice(final long hostId, final String groupName, final String vgpuType) {
-        final Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null);
-        final SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
-        sc.setParameters("hostId", hostId);
-        sc.setParameters("groupName", groupName);
-        sc.setJoinParameters("groupId", "vgpuType", vgpuType);
-        sc.setJoinParameters("groupId", "remainingCapacity", 0);
-        return _hostGpuGroupsDao.customSearch(sc, searchFilter);
-    }
-
-    @Override
-    public boolean isGPUDeviceAvailable(final long hostId, final String groupName, final String vgpuType) {
-        if(!listAvailableGPUDevice(hostId, groupName, vgpuType).isEmpty()) {
-            return true;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host ID: "+ hostId +" does not have GPU device available");
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public GPUDeviceTO getGPUDevice(final long hostId, final String groupName, final String vgpuType) {
-        final List<HostGpuGroupsVO> gpuDeviceList = listAvailableGPUDevice(hostId, groupName, vgpuType);
-
-        if (CollectionUtils.isEmpty(gpuDeviceList)) {
-            final String errorMsg = "Host " + hostId + " does not have required GPU device or out of capacity. GPU group: " + groupName + ", vGPU Type: " + vgpuType;
-            s_logger.error(errorMsg);
-            throw new CloudRuntimeException(errorMsg);
-        }
-
-        return new GPUDeviceTO(gpuDeviceList.get(0).getGroupName(), vgpuType, null);
-    }
-
-    @Override
-    public void updateGPUDetails(final long hostId, final HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails) {
-        // Update GPU group capacity
-        final TransactionLegacy txn = TransactionLegacy.currentTxn();
-        txn.start();
-        _hostGpuGroupsDao.persist(hostId, new ArrayList<String>(groupDetails.keySet()));
-        _vgpuTypesDao.persist(hostId, groupDetails);
-        txn.commit();
-    }
-
-    @Override
-    public HashMap<String, HashMap<String, VgpuTypesInfo>> getGPUStatistics(final HostVO host) {
-        final Answer answer = _agentMgr.easySend(host.getId(), new GetGPUStatsCommand(host.getGuid(), host.getName()));
-        if (answer != null && answer instanceof UnsupportedAnswer) {
-            return null;
-        }
-        if (answer == null || !answer.getResult()) {
-            final String msg = "Unable to obtain GPU stats for host " + host.getName();
-            s_logger.warn(msg);
-            return null;
-        } else {
-            // now construct the result object
-            if (answer instanceof GetGPUStatsAnswer) {
-                return ((GetGPUStatsAnswer)answer).getGroupDetails();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public HostVO findOneRandomRunningHostByHypervisor(HypervisorType type) {
-        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getHypervisorType(), Op.EQ, type);
-        sc.and(sc.entity().getType(),Op.EQ, Type.Routing);
-        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
-        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
-        sc.and(sc.entity().getRemoved(), Op.NULL);
-        List<HostVO> hosts = sc.list();
-        if (CollectionUtils.isEmpty(hosts)) {
-            return null;
-        } else {
-            Collections.shuffle(hosts, new Random(System.currentTimeMillis()));
-            return hosts.get(0);
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
-    public boolean releaseHostReservation(final Long hostId) {
-        try {
-            return Transaction.execute(new TransactionCallback<Boolean>() {
-                @Override
-                public Boolean doInTransaction(final TransactionStatus status) {
-                    final PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
-                    if (reservationEntry != null) {
-                        final long id = reservationEntry.getId();
-                        final PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
-                        if (hostReservation == null) {
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
-                            }
-                            return false;
-                        }
-                        hostReservation.setResourceUsage(null);
-                        _plannerHostReserveDao.persist(hostReservation);
-                        return true;
-                    }
-
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
-                    }
-
-                    return false;
-                }
-            });
-        } catch (final CloudRuntimeException e) {
-            throw e;
-        } catch (final Throwable t) {
-            s_logger.error("Unable to release host reservation for host: " + hostId, t);
-            return false;
-        }
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return super.start();
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ResourceManagerImpl.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {HostMaintenanceRetries};
-    }
-}
diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
deleted file mode 100644
index f4f5f89..0000000
--- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ /dev/null
@@ -1,1091 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.resourcelimit;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.alert.AlertManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource;
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.configuration.ResourceCount;
-import com.cloud.configuration.ResourceCountVO;
-import com.cloud.configuration.ResourceLimitVO;
-import com.cloud.configuration.dao.ResourceCountDao;
-import com.cloud.configuration.dao.ResourceLimitDao;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectAccount.Role;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.projects.dao.ProjectDao;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDaoImpl.SumCount;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable {
-    public static final Logger s_logger = Logger.getLogger(ResourceLimitManagerImpl.class);
-
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private AlertManager _alertMgr;
-    @Inject
-    private ResourceCountDao _resourceCountDao;
-    @Inject
-    private ResourceLimitDao _resourceLimitDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private IPAddressDao _ipAddressDao;
-    @Inject
-    private VMInstanceDao _vmDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private EntityManager _entityMgr;
-    @Inject
-    private ProjectDao _projectDao;
-    @Inject
-    private ProjectAccountDao _projectAccountDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private VpcDao _vpcDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private TemplateDataStoreDao _vmTemplateStoreDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private SnapshotDataStoreDao _snapshotDataStoreDao;
-
-    protected GenericSearchBuilder<TemplateDataStoreVO, SumCount> templateSizeSearch;
-    protected GenericSearchBuilder<SnapshotDataStoreVO, SumCount> snapshotSizeSearch;
-
-    protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
-    ScheduledExecutorService _rcExecutor;
-    long _resourceCountCheckInterval = 0;
-    Map<ResourceType, Long> accountResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
-    Map<ResourceType, Long> domainResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
-    Map<ResourceType, Long> projectResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
-
-    @Override
-    public boolean start() {
-        if (_resourceCountCheckInterval > 0) {
-            _rcExecutor.scheduleAtFixedRate(new ResourceCountCheckTask(), _resourceCountCheckInterval, _resourceCountCheckInterval, TimeUnit.SECONDS);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        ResourceCountSearch = _resourceCountDao.createSearchBuilder();
-        ResourceCountSearch.and("id", ResourceCountSearch.entity().getId(), SearchCriteria.Op.IN);
-        ResourceCountSearch.and("accountId", ResourceCountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-        ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
-        ResourceCountSearch.done();
-
-        templateSizeSearch = _vmTemplateStoreDao.createSearchBuilder(SumCount.class);
-        templateSizeSearch.select("sum", Func.SUM, templateSizeSearch.entity().getSize());
-        templateSizeSearch.and("downloadState", templateSizeSearch.entity().getDownloadState(), Op.EQ);
-        templateSizeSearch.and("destroyed", templateSizeSearch.entity().getDestroyed(), Op.EQ);
-        SearchBuilder<VMTemplateVO> join1 = _vmTemplateDao.createSearchBuilder();
-        join1.and("accountId", join1.entity().getAccountId(), Op.EQ);
-        templateSizeSearch.join("templates", join1, templateSizeSearch.entity().getTemplateId(), join1.entity().getId(), JoinBuilder.JoinType.INNER);
-        templateSizeSearch.done();
-
-        snapshotSizeSearch = _snapshotDataStoreDao.createSearchBuilder(SumCount.class);
-        snapshotSizeSearch.select("sum", Func.SUM, snapshotSizeSearch.entity().getPhysicalSize());
-        snapshotSizeSearch.and("state", snapshotSizeSearch.entity().getState(), Op.EQ);
-        snapshotSizeSearch.and("storeRole", snapshotSizeSearch.entity().getRole(), Op.EQ);
-        SearchBuilder<SnapshotVO> join2 = _snapshotDao.createSearchBuilder();
-        join2.and("accountId", join2.entity().getAccountId(), Op.EQ);
-        snapshotSizeSearch.join("snapshots", join2, snapshotSizeSearch.entity().getSnapshotId(), join2.entity().getId(), JoinBuilder.JoinType.INNER);
-        snapshotSizeSearch.done();
-
-        _resourceCountCheckInterval = ResourceCountCheckInterval.value();
-        if (_resourceCountCheckInterval > 0) {
-            _rcExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ResourceCountChecker"));
-        }
-
-        try {
-            projectResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPublicIPs.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSnapshots.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectTemplates.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectUserVms.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectNetworks.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVpcs.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectCpus.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectMemory.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPrimaryStorage.key())));
-            projectResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSecondaryStorage.key())));
-
-            accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountNetworks.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVpcs.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountCpus.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPrimaryStorage.key())));
-            accountResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key())));
-
-            domainResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPublicIPs.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSnapshots.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainTemplates.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainUserVms.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVolumes.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainNetworks.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVpcs.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainCpus.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainMemory.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPrimaryStorage.key())));
-            domainResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSecondaryStorage.key())));
-        } catch (NumberFormatException e) {
-            s_logger.error("NumberFormatException during configuration", e);
-            throw new ConfigurationException("Configuration failed due to NumberFormatException, see log for the stacktrace");
-        }
-
-        return true;
-    }
-
-    @Override
-    public void incrementResourceCount(long accountId, ResourceType type, Long... delta) {
-        // don't upgrade resource count for system account
-        if (accountId == Account.ACCOUNT_ID_SYSTEM) {
-            s_logger.trace("Not incrementing resource count for system accounts, returning");
-            return;
-        }
-
-        long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue();
-
-        if (!updateResourceCountForAccount(accountId, type, true, numToIncrement)) {
-            // we should fail the operation (resource creation) when failed to update the resource count
-            throw new CloudRuntimeException("Failed to increment resource count of type " + type + " for account id=" + accountId);
-        }
-    }
-
-    @Override
-    public void decrementResourceCount(long accountId, ResourceType type, Long... delta) {
-        // don't upgrade resource count for system account
-        if (accountId == Account.ACCOUNT_ID_SYSTEM) {
-            s_logger.trace("Not decrementing resource count for system accounts, returning");
-            return;
-        }
-        long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue();
-
-        if (!updateResourceCountForAccount(accountId, type, false, numToDecrement)) {
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type +
-                " for account id=" +
-                accountId, "Failed to decrement resource count of type " + type + " for account id=" + accountId +
-                "; use updateResourceCount API to recalculate/fix the problem");
-        }
-    }
-
-    @Override
-    public long findCorrectResourceLimitForAccount(Account account, ResourceType type) {
-
-        long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited
-
-        // No limits for Root Admin accounts
-        if (_accountMgr.isRootAdmin(account.getId())) {
-            return max;
-        }
-
-        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(account.getId(), ResourceOwnerType.Account, type);
-
-        // Check if limit is configured for account
-        if (limit != null) {
-            max = limit.getMax().longValue();
-        } else {
-            // If the account has an no limit set, then return global default account limits
-            Long value = null;
-            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                value = projectResourceLimitMap.get(type);
-            } else {
-                value = accountResourceLimitMap.get(type);
-            }
-            if (value != null) {
-                if (value < 0) { // return unlimit if value is set to negative
-                    return max;
-                }
-                // convert the value from GiB to bytes in case of primary or secondary storage.
-                if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
-                    value = value * ResourceType.bytesToGiB;
-                }
-                return value;
-            }
-        }
-
-        return max;
-    }
-
-    @Override
-    public long findCorrectResourceLimitForAccount(long accountId, Long limit, ResourceType type) {
-
-        long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited
-
-        // No limits for Root Admin accounts
-        if (_accountMgr.isRootAdmin(accountId)) {
-            return max;
-        }
-
-        Account account = _accountDao.findById(accountId);
-        if (account == null) {
-            return max;
-        }
-
-        // Check if limit is configured for account
-        if (limit != null) {
-            max = limit.longValue();
-        } else {
-            // If the account has an no limit set, then return global default account limits
-            Long value = null;
-            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                value = projectResourceLimitMap.get(type);
-            } else {
-                value = accountResourceLimitMap.get(type);
-            }
-            if (value != null) {
-                if (value < 0) { // return unlimit if value is set to negative
-                    return max;
-                }
-                if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
-                    value = value * ResourceType.bytesToGiB;
-                }
-                return value;
-            }
-        }
-
-        return max;
-    }
-
-    @Override
-    public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type) {
-        long max = Resource.RESOURCE_UNLIMITED;
-
-        // no limits on ROOT domain
-        if (domain.getId() == Domain.ROOT_DOMAIN) {
-            return Resource.RESOURCE_UNLIMITED;
-        }
-        // Check account
-        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(domain.getId(), ResourceOwnerType.Domain, type);
-
-        if (limit != null) {
-            max = limit.getMax().longValue();
-        } else {
-            // check domain hierarchy
-            Long domainId = domain.getParent();
-            while ((domainId != null) && (limit == null)) {
-                if (domainId == Domain.ROOT_DOMAIN) {
-                    break;
-                }
-                limit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
-                DomainVO tmpDomain = _domainDao.findById(domainId);
-                domainId = tmpDomain.getParent();
-            }
-
-            if (limit != null) {
-                max = limit.getMax().longValue();
-            } else {
-                Long value = null;
-                value = domainResourceLimitMap.get(type);
-                if (value != null) {
-                    if (value < 0) { // return unlimit if value is set to negative
-                        return max;
-                    }
-                    if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
-                        value = value * ResourceType.bytesToGiB;
-                    }
-                    return value;
-                }
-            }
-        }
-
-        return max;
-    }
-
-    private void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, long numResources) throws ResourceAllocationException {
-        // check all domains in the account's domain hierarchy
-        Long domainId = null;
-        if (project != null) {
-            domainId = project.getDomainId();
-        } else {
-            domainId = account.getDomainId();
-        }
-
-        while (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            // no limit check if it is ROOT domain
-            if (domainId != Domain.ROOT_DOMAIN) {
-                long domainResourceLimit = findCorrectResourceLimitForDomain(domain, type);
-                long currentDomainResourceCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
-                long requestedDomainResourceCount = currentDomainResourceCount + numResources;
-                String messageSuffix = " domain resource limits of Type '" + type + "'" +
-                    " for Domain Id = " + domainId +
-                    " is exceeded: Domain Resource Limit = " + domainResourceLimit +
-                    ", Current Domain Resource Amount = " + currentDomainResourceCount +
-                    ", Requested Resource Amount = " + numResources + ".";
-
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug("Checking if" + messageSuffix);
-                }
-
-                if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
-                    String message = "Maximum" + messageSuffix;
-                    ResourceAllocationException e = new ResourceAllocationException(message, type);
-                    s_logger.error(message, e);
-                    throw e;
-                }
-            }
-            domainId = domain.getParent();
-        }
-    }
-
-    private void checkAccountResourceLimit(final Account account, final Project project, final ResourceType type, long numResources) throws ResourceAllocationException {
-        // Check account limits
-        long accountResourceLimit = findCorrectResourceLimitForAccount(account, type);
-        long currentResourceCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);
-        long requestedResourceCount = currentResourceCount + numResources;
-        String messageSuffix = " amount of resources of Type = '" + type + "' for " +
-            (project == null ? "Account Name = " + account.getAccountName() : "Project Name = " + project.getName()) +
-            " in Domain Id = " + account.getDomainId() +
-            " is exceeded: Account Resource Limit = " + accountResourceLimit +
-            ", Current Account Resource Amount = " + currentResourceCount +
-            ", Requested Resource Amount = " + numResources + ".";
-
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Checking if" + messageSuffix);
-        }
-
-        if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
-            String message = "Maximum" + messageSuffix;
-            ResourceAllocationException e = new ResourceAllocationException(message, type);
-            s_logger.error(message, e);
-            throw e;
-        }
-    }
-
-    private List<ResourceCountVO> lockAccountAndOwnerDomainRows(long accountId, final ResourceType type) {
-        Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
-        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-        sc.setParameters("id", rowIdsToLock.toArray());
-        return _resourceCountDao.lockRows(sc, null, true);
-    }
-
-    private List<ResourceCountVO> lockDomainRows(long domainId, final ResourceType type) {
-        Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
-        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
-        sc.setParameters("id", rowIdsToLock.toArray());
-        return _resourceCountDao.lockRows(sc, null, true);
-    }
-
-    public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
-        Long resourceLimit = null;
-        resourceLimit = domainResourceLimitMap.get(resourceType);
-        if (resourceLimit != null && (resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage)) {
-            resourceLimit = resourceLimit * ResourceType.bytesToGiB;
-        } else {
-            resourceLimit = Long.valueOf(Resource.RESOURCE_UNLIMITED);
-        }
-        return resourceLimit;
-    }
-
-    @Override
-    @DB
-    public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {
-        final long numResources = ((count.length == 0) ? 1 : count[0]);
-        Project project = null;
-
-        // Don't place any limits on system or root admin accounts
-        if (_accountMgr.isRootAdmin(account.getId())) {
-            return;
-        }
-
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            project = _projectDao.findByProjectAccountId(account.getId());
-        }
-
-        final Project projectFinal = project;
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
-                // Lock all rows first so nobody else can read it
-                lockAccountAndOwnerDomainRows(account.getId(), type);
-                // Check account limits
-                checkAccountResourceLimit(account, projectFinal, type, numResources);
-                // check all domains in the account's domain hierarchy
-                checkDomainResourceLimit(account, projectFinal, type, numResources);
-            }
-            });
-    }
-
-    @Override
-    public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, Long startIndex, Long pageSizeVal) {
-        Account caller = CallContext.current().getCallingAccount();
-        List<ResourceLimitVO> limits = new ArrayList<ResourceLimitVO>();
-        boolean isAccount = true;
-
-        if (!_accountMgr.isAdmin(caller.getId())) {
-            accountId = caller.getId();
-            domainId = null;
-        } else {
-            if (domainId != null) {
-                // verify domain information and permissions
-                Domain domain = _domainDao.findById(domainId);
-                if (domain == null) {
-                    // return empty set
-                    return limits;
-                }
-
-                _accountMgr.checkAccess(caller, domain);
-
-                if (accountId != null) {
-                    // Verify account information and permissions
-                    Account account = _accountDao.findById(accountId);
-                    if (account == null) {
-                        // return empty set
-                        return limits;
-                    }
-
-                    _accountMgr.checkAccess(caller, null, true, account);
-                    domainId = null;
-                }
-            }
-        }
-
-        // If id is passed in, get the record and return it if permission check has passed
-        if (id != null) {
-            ResourceLimitVO vo = _resourceLimitDao.findById(id);
-            if (vo.getAccountId() != null) {
-                _accountMgr.checkAccess(caller, null, true, _accountDao.findById(vo.getAccountId()));
-                limits.add(vo);
-            } else if (vo.getDomainId() != null) {
-                _accountMgr.checkAccess(caller, _domainDao.findById(vo.getDomainId()));
-                limits.add(vo);
-            }
-
-            return limits;
-        }
-
-        // If account is not specified, default it to caller account
-        if (accountId == null) {
-            if (domainId == null) {
-                accountId = caller.getId();
-                isAccount = true;
-            } else {
-                isAccount = false;
-            }
-        } else {
-            isAccount = true;
-        }
-
-        SearchBuilder<ResourceLimitVO> sb = _resourceLimitDao.createSearchBuilder();
-        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
-        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<ResourceLimitVO> sc = sb.create();
-        Filter filter = new Filter(ResourceLimitVO.class, "id", true, startIndex, pageSizeVal);
-
-        if (accountId != null) {
-            sc.setParameters("accountId", accountId);
-        }
-
-        if (domainId != null) {
-            sc.setParameters("domainId", domainId);
-            sc.setParameters("accountId", (Object[])null);
-        }
-
-        if (resourceType != null) {
-            sc.setParameters("type", resourceType);
-        }
-
-        List<ResourceLimitVO> foundLimits = _resourceLimitDao.search(sc, filter);
-
-        if (resourceType != null) {
-            if (foundLimits.isEmpty()) {
-                if (isAccount) {
-                    limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForAccount(_accountMgr.getAccount(accountId), resourceType), accountId,
-                        ResourceOwnerType.Account));
-                } else {
-                    limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), resourceType), domainId,
-                        ResourceOwnerType.Domain));
-                }
-            } else {
-                limits.addAll(foundLimits);
-            }
-        } else {
-            limits.addAll(foundLimits);
-
-            // see if any limits are missing from the table, and if yes - get it from the config table and add
-            ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
-            if (foundLimits.size() != resourceTypes.length) {
-                List<String> accountLimitStr = new ArrayList<String>();
-                List<String> domainLimitStr = new ArrayList<String>();
-                for (ResourceLimitVO foundLimit : foundLimits) {
-                    if (foundLimit.getAccountId() != null) {
-                        accountLimitStr.add(foundLimit.getType().toString());
-                    } else {
-                        domainLimitStr.add(foundLimit.getType().toString());
-                    }
-                }
-
-                // get default from config values
-                if (isAccount) {
-                    if (accountLimitStr.size() < resourceTypes.length) {
-                        for (ResourceType rt : resourceTypes) {
-                            if (!accountLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Account)) {
-                                limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForAccount(_accountMgr.getAccount(accountId), rt), accountId,
-                                    ResourceOwnerType.Account));
-                            }
-                        }
-                    }
-
-                } else {
-                    if (domainLimitStr.size() < resourceTypes.length) {
-                        for (ResourceType rt : resourceTypes) {
-                            if (!domainLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Domain)) {
-                                limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), rt), domainId,
-                                    ResourceOwnerType.Domain));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return limits;
-    }
-
-    @Override
-    public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Integer typeId, Long max) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        if (max == null) {
-            max = new Long(Resource.RESOURCE_UNLIMITED);
-        } else if (max.longValue() < Resource.RESOURCE_UNLIMITED) {
-            throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'.");
-        }
-
-        // Map resource type
-        ResourceType resourceType = null;
-        if (typeId != null) {
-            for (ResourceType type : Resource.ResourceType.values()) {
-                if (type.getOrdinal() == typeId.intValue()) {
-                    resourceType = type;
-                }
-            }
-            if (resourceType == null) {
-                throw new InvalidParameterValueException("Please specify valid resource type");
-            }
-        }
-
-        //Convert max storage size from GiB to bytes
-        if ((resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage) && max >= 0) {
-            max *= ResourceType.bytesToGiB;
-        }
-
-        ResourceOwnerType ownerType = null;
-        Long ownerId = null;
-
-        if (accountId != null) {
-            Account account = _entityMgr.findById(Account.class, accountId);
-            if (account == null) {
-                throw new InvalidParameterValueException("Unable to find account " + accountId);
-            }
-            if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-                throw new InvalidParameterValueException("Can't update system account");
-            }
-
-            //only Unlimited value is accepted if account is  Root Admin
-            if (_accountMgr.isRootAdmin(account.getId()) && max.shortValue() != Resource.RESOURCE_UNLIMITED) {
-                throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts");
-            }
-
-            if ((caller.getAccountId() == accountId.longValue()) &&
-                (_accountMgr.isDomainAdmin(caller.getId()) ||
-                caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) {
-                // If the admin is trying to update his own account, disallow.
-                throw new PermissionDeniedException("Unable to update resource limit for his own account " + accountId + ", permission denied");
-            }
-
-            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, account);
-            } else {
-                _accountMgr.checkAccess(caller, null, true, account);
-            }
-
-            ownerType = ResourceOwnerType.Account;
-            ownerId = accountId;
-        } else if (domainId != null) {
-            Domain domain = _entityMgr.findById(Domain.class, domainId);
-
-            _accountMgr.checkAccess(caller, domain);
-
-            if (Domain.ROOT_DOMAIN == domainId.longValue()) {
-                // no one can add limits on ROOT domain, disallow...
-                throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied");
-            }
-
-            if ((caller.getDomainId() == domainId.longValue()) && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN ||
-                caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-                // if the admin is trying to update their own domain, disallow...
-                throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied");
-            }
-            Long parentDomainId = domain.getParent();
-            if (parentDomainId != null) {
-                DomainVO parentDomain = _domainDao.findById(parentDomainId);
-                long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType);
-                if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) {
-                    throw new InvalidParameterValueException("Domain " + domain.getName() + "(id: " + parentDomain.getId() + ") has maximum allowed resource limit " +
-                        parentMaximum + " for " + resourceType + ", please specify a value less that or equal to " + parentMaximum);
-                }
-            }
-            ownerType = ResourceOwnerType.Domain;
-            ownerId = domainId;
-        }
-
-        if (ownerId == null) {
-            throw new InvalidParameterValueException("AccountId or domainId have to be specified in order to update resource limit");
-        }
-
-        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(ownerId, ownerType, resourceType);
-        if (limit != null) {
-            // Update the existing limit
-            _resourceLimitDao.update(limit.getId(), max);
-            return _resourceLimitDao.findById(limit.getId());
-        } else {
-            return _resourceLimitDao.persist(new ResourceLimitVO(resourceType, max, ownerId, ownerType));
-        }
-    }
-
-    @Override
-    public List<ResourceCountVO> recalculateResourceCount(Long accountId, Long domainId, Integer typeId) throws InvalidParameterValueException, CloudRuntimeException,
-        PermissionDeniedException {
-        Account callerAccount = CallContext.current().getCallingAccount();
-        long count = 0;
-        List<ResourceCountVO> counts = new ArrayList<ResourceCountVO>();
-        List<ResourceType> resourceTypes = new ArrayList<ResourceType>();
-
-        ResourceType resourceType = null;
-
-        if (typeId != null) {
-            for (ResourceType type : Resource.ResourceType.values()) {
-                if (type.getOrdinal() == typeId.intValue()) {
-                    resourceType = type;
-                }
-            }
-            if (resourceType == null) {
-                throw new InvalidParameterValueException("Please specify valid resource type");
-            }
-        }
-
-        DomainVO domain = _domainDao.findById(domainId);
-        if (domain == null) {
-            throw new InvalidParameterValueException("Please specify a valid domain ID.");
-        }
-        _accountMgr.checkAccess(callerAccount, domain);
-
-        if (resourceType != null) {
-            resourceTypes.add(resourceType);
-        } else {
-            resourceTypes = Arrays.asList(Resource.ResourceType.values());
-        }
-
-        for (ResourceType type : resourceTypes) {
-            if (accountId != null) {
-                if (type.supportsOwner(ResourceOwnerType.Account)) {
-                    count = recalculateAccountResourceCount(accountId, type);
-                    counts.add(new ResourceCountVO(type, count, accountId, ResourceOwnerType.Account));
-                }
-
-            } else {
-                if (type.supportsOwner(ResourceOwnerType.Domain)) {
-                    count = recalculateDomainResourceCount(domainId, type);
-                    counts.add(new ResourceCountVO(type, count, domainId, ResourceOwnerType.Domain));
-                }
-            }
-        }
-
-        return counts;
-    }
-
-    @DB
-    protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) {
-        if(s_logger.isDebugEnabled()) {
-            s_logger.debug("Updating resource Type = " + type + " count for Account = " + accountId +
-                           " Operation = " + (increment ? "increasing" : "decreasing") + " Amount = " + delta);
-        }
-        try {
-            return Transaction.execute(new TransactionCallback<Boolean>() {
-                    @Override
-                    public Boolean doInTransaction(TransactionStatus status) {
-                        boolean result = true;
-                        List<ResourceCountVO> rowsToUpdate = lockAccountAndOwnerDomainRows(accountId, type);
-                        for (ResourceCountVO rowToUpdate : rowsToUpdate) {
-                            if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
-                                s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
-                                result = false;
-                            }
-                        }
-                        return result;
-                    }
-                });
-        } catch (Exception ex) {
-            s_logger.error("Failed to update resource count for account id=" + accountId);
-            return false;
-        }
-    }
-
-    @DB
-    protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) {
-        return Transaction.execute(new TransactionCallback<Long>() {
-                @Override
-                public Long doInTransaction(TransactionStatus status) {
-                    long newResourceCount = 0;
-                    lockDomainRows(domainId, type);
-                    ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
-                    long oldResourceCount = domainRC.getCount();
-
-                    List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
-                    // for each child domain update the resource count
-                    if (type.supportsOwner(ResourceOwnerType.Domain)) {
-
-                        // calculate project count here
-                        if (type == ResourceType.project) {
-                            newResourceCount += _projectDao.countProjectsForDomain(domainId);
-                        }
-
-                        for (DomainVO childDomain : domainChildren) {
-                            long childDomainResourceCount = recalculateDomainResourceCount(childDomain.getId(), type);
-                            newResourceCount += childDomainResourceCount; // add the child domain count to parent domain count
-                        }
-                    }
-
-                    if (type.supportsOwner(ResourceOwnerType.Account)) {
-                        List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
-                        for (AccountVO account : accounts) {
-                            long accountResourceCount = recalculateAccountResourceCount(account.getId(), type);
-                            newResourceCount += accountResourceCount; // add account's resource count to parent domain count
-                        }
-                    }
-                    _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newResourceCount);
-
-                    if (oldResourceCount != newResourceCount) {
-                        s_logger.warn("Discrepency in the resource count has been detected " + "(original count = " + oldResourceCount +
-                                      " correct count = " + newResourceCount + ") for Type = " + type +
-                                      " for Domain ID = " + domainId + " is fixed during resource count recalculation.");
-                    }
-
-                    return newResourceCount;
-                }
-            });
-    }
-
-    @DB
-    protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
-        final Long newCount;
-        if (type == Resource.ResourceType.user_vm) {
-            newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
-        } else if (type == Resource.ResourceType.volume) {
-            long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
-            newCount = _volumeDao.countAllocatedVolumesForAccount(accountId) - virtualRouterCount; // don't count the volumes of virtual router
-        } else if (type == Resource.ResourceType.snapshot) {
-            newCount = _snapshotDao.countSnapshotsForAccount(accountId);
-        } else if (type == Resource.ResourceType.public_ip) {
-            newCount = calculatePublicIpForAccount(accountId);
-        } else if (type == Resource.ResourceType.template) {
-            newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
-        } else if (type == Resource.ResourceType.project) {
-            newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
-        } else if (type == Resource.ResourceType.network) {
-            newCount = _networkDao.countNetworksUserCanCreate(accountId);
-        } else if (type == Resource.ResourceType.vpc) {
-            newCount = _vpcDao.countByAccountId(accountId);
-        } else if (type == Resource.ResourceType.cpu) {
-            newCount = countCpusForAccount(accountId);
-        } else if (type == Resource.ResourceType.memory) {
-            newCount = calculateMemoryForAccount(accountId);
-        } else if (type == Resource.ResourceType.primary_storage) {
-            List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
-            newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
-        } else if (type == Resource.ResourceType.secondary_storage) {
-            newCount = calculateSecondaryStorageForAccount(accountId);
-        } else {
-            throw new InvalidParameterValueException("Unsupported resource type " + type);
-        }
-
-        long oldCount = 0;
-        final ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
-        if (accountRC != null) {
-            oldCount = accountRC.getCount();
-        }
-
-        if (newCount == null || !newCount.equals(oldCount)) {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    lockAccountAndOwnerDomainRows(accountId, type);
-                    _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount);
-                }
-            });
-        }
-
-        // No need to log message for primary and secondary storage because both are recalculating the
-        // resource count which will not lead to any discrepancy.
-        if (newCount != null && !newCount.equals(oldCount) &&
-                type != Resource.ResourceType.primary_storage && type != Resource.ResourceType.secondary_storage) {
-            s_logger.warn("Discrepancy in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type +
-                    " for account ID " + accountId + " is fixed during resource count recalculation.");
-        }
-
-        return (newCount == null) ? 0 : newCount;
-    }
-
-    public long countCpusForAccount(long accountId) {
-        return _resourceCountDao.countCpuNumberAllocatedToAccount(accountId);
-    }
-
-    public long calculateMemoryForAccount(long accountId) {
-        return _resourceCountDao.countMemoryAllocatedToAccount(accountId);
-    }
-
-    public long calculateSecondaryStorageForAccount(long accountId) {
-        long totalVolumesSize = _volumeDao.secondaryStorageUsedForAccount(accountId);
-        long totalSnapshotsSize = 0;
-        long totalTemplatesSize = 0;
-
-        SearchCriteria<SumCount> sc = templateSizeSearch.create();
-        sc.setParameters("downloadState", Status.DOWNLOADED);
-        sc.setParameters("destroyed", false);
-        sc.setJoinParameters("templates", "accountId", accountId);
-        List<SumCount> templates = _vmTemplateStoreDao.customSearch(sc, null);
-        if (templates != null) {
-            totalTemplatesSize = templates.get(0).sum;
-        }
-
-        SearchCriteria<SumCount> sc2 = snapshotSizeSearch.create();
-        sc2.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
-        sc2.setParameters("storeRole", DataStoreRole.Image);
-        sc2.setJoinParameters("snapshots", "accountId", accountId);
-        List<SumCount> snapshots = _snapshotDataStoreDao.customSearch(sc2, null);
-        if (snapshots != null) {
-            totalSnapshotsSize = snapshots.get(0).sum;
-        }
-        return totalVolumesSize + totalSnapshotsSize + totalTemplatesSize;
-    }
-
-    private long calculatePublicIpForAccount(long accountId) {
-        Long dedicatedCount = 0L;
-        Long allocatedCount = 0L;
-
-        List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId);
-        for (VlanVO dedicatedVlan : dedicatedVlans) {
-            List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId());
-            dedicatedCount += new Long(ips.size());
-        }
-        allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
-        if (dedicatedCount > allocatedCount) {
-            return dedicatedCount;
-        } else {
-            return allocatedCount;
-        }
-    }
-
-    @Override
-    public long getResourceCount(Account account, ResourceType type) {
-        return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);
-    }
-
-    private boolean isDisplayFlagOn(Boolean displayResource){
-
-        // 1. If its null assume displayResource = 1
-        // 2. If its not null then send true if displayResource = 1
-        return (displayResource == null) || (displayResource != null && displayResource);
-    }
-
-    @Override
-    public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException {
-
-        if (isDisplayFlagOn(displayResource)) {
-            checkResourceLimit(account, type, count);
-        }
-    }
-
-    @Override
-    public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
-
-        if (isDisplayFlagOn(displayResource)) {
-            incrementResourceCount(accountId, type, delta);
-        }
-    }
-
-    @Override
-    public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
-
-        if (isDisplayFlagOn(displayResource)) {
-            decrementResourceCount(accountId, type, delta);
-        }
-    }
-
-    @Override
-    public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
-
-        // meaning that the display flag is not changed so neither increment or decrement
-        if (displayResource == null) {
-            return;
-        }
-
-        // Increment because the display is turned on.
-        if (displayResource) {
-            incrementResourceCount(accountId, type, delta);
-        } else {
-            decrementResourceCount(accountId, type, delta);
-        }
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ResourceLimitManagerImpl.class.getName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {ResourceCountCheckInterval};
-    }
-
-    protected class ResourceCountCheckTask extends ManagedContextRunnable {
-        public ResourceCountCheckTask() {
-
-        }
-
-        @Override
-        protected void runInContext() {
-            s_logger.info("Started resource counters recalculation periodic task.");
-            List<DomainVO> domains = _domainDao.findImmediateChildrenForParent(Domain.ROOT_DOMAIN);
-
-            // recalculateDomainResourceCount will take care of re-calculation of resource counts for sub-domains
-            // and accounts of the sub-domains also. so just loop through immediate children of root domain
-            for (Domain domain : domains) {
-                for (ResourceType type : ResourceCount.ResourceType.values()) {
-                    if (type.supportsOwner(ResourceOwnerType.Domain)) {
-                        recalculateDomainResourceCount(domain.getId(), type);
-                    }
-                }
-            }
-
-            // run through the accounts in the root domain
-            List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(Domain.ROOT_DOMAIN);
-            for (AccountVO account : accounts) {
-                for (ResourceType type : ResourceCount.ResourceType.values()) {
-                    if (type.supportsOwner(ResourceOwnerType.Account)) {
-                        recalculateAccountResourceCount(account.getId(), type);
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java
deleted file mode 100644
index df54873..0000000
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ /dev/null
@@ -1,1375 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.security.NoSuchAlgorithmException;
-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 java.util.Properties;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource;
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.configuration.ResourceCountVO;
-import com.cloud.configuration.dao.ResourceCountDao;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.Network;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Network.State;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.Networks.Mode;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.guru.ControlNetworkGuru;
-import com.cloud.network.guru.DirectPodBasedNetworkGuru;
-import com.cloud.network.guru.PodBasedNetworkGuru;
-import com.cloud.network.guru.PublicNetworkGuru;
-import com.cloud.network.guru.StorageNetworkGuru;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offerings.NetworkOfferingServiceMapVO;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.test.IPRangeConfig;
-import com.cloud.user.Account;
-import com.cloud.user.AccountVO;
-import com.cloud.user.User;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.PasswordGenerator;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.Script;
-
-public class ConfigurationServerImpl extends ManagerBase implements ConfigurationServer {
-    public static final Logger s_logger = Logger.getLogger(ConfigurationServerImpl.class);
-
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private DataCenterDao _zoneDao;
-    @Inject
-    private HostPodDao _podDao;
-    @Inject
-    private DiskOfferingDao _diskOfferingDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    private DataCenterDao _dataCenterDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private ResourceCountDao _resourceCountDao;
-    @Inject
-    private NetworkOfferingServiceMapDao _ntwkOfferingServiceMapDao;
-    @Inject
-    protected ConfigDepotAdmin _configDepotAdmin;
-    @Inject
-    protected ConfigDepot _configDepot;
-    @Inject
-    protected ConfigurationManager _configMgr;
-    @Inject
-    protected ManagementService _mgrService;
-
-
-    public ConfigurationServerImpl() {
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        try {
-            persistDefaultValues();
-            _configDepotAdmin.populateConfigurations();
-        } catch (InternalErrorException e) {
-            throw new RuntimeException("Unhandled configuration exception", e);
-        }
-        return true;
-    }
-
-    @Override
-    public void persistDefaultValues() throws InternalErrorException {
-
-        // Create system user and admin user
-        saveUser();
-
-        // Get init
-        String init = _configDao.getValue("init");
-
-        if (init == null || init.equals("false")) {
-            s_logger.debug("ConfigurationServer is saving default values to the database.");
-
-            // Save default Configuration Table values
-            List<String> categories = Config.getCategories();
-            for (String category : categories) {
-                // If this is not a premium environment, don't insert premium configuration values
-                if (!_configDao.isPremium() && category.equals("Premium")) {
-                    continue;
-                }
-
-                List<Config> configs = Config.getConfigs(category);
-                for (Config c : configs) {
-                    String name = c.key();
-
-                    // if the config value already present in the db, don't insert it again
-                    if (_configDao.findByName(name) != null) {
-                        continue;
-                    }
-
-                    String instance = "DEFAULT";
-                    String component = c.getComponent();
-                    String value = c.getDefaultValue();
-                    String description = c.getDescription();
-                    ConfigurationVO configVO = new ConfigurationVO(category, instance, component, name, value, description);
-                    configVO.setDefaultValue(value);
-                    _configDao.persist(configVO);
-                }
-            }
-
-            _configDao.update(Config.UseSecondaryStorageVm.key(), Config.UseSecondaryStorageVm.getCategory(), "true");
-            s_logger.debug("ConfigurationServer made secondary storage vm required.");
-
-            _configDao.update(Config.SecStorageEncryptCopy.key(), Config.SecStorageEncryptCopy.getCategory(), "false");
-            s_logger.debug("ConfigurationServer made secondary storage copy encrypt set to false.");
-
-            _configDao.update("secstorage.secure.copy.cert", "realhostip");
-            s_logger.debug("ConfigurationServer made secondary storage copy use realhostip.");
-
-            _configDao.update("user.password.encoders.exclude", "MD5,LDAP,PLAINTEXT");
-            s_logger.debug("Configuration server excluded insecure encoders");
-
-            _configDao.update("user.authenticators.exclude", "PLAINTEXT");
-            s_logger.debug("Configuration server excluded plaintext authenticator");
-
-            // Save default service offerings
-            createServiceOffering(User.UID_SYSTEM, "Small Instance", 1, 512, 500, "Small Instance", ProvisioningType.THIN, false, false, null);
-            createServiceOffering(User.UID_SYSTEM, "Medium Instance", 1, 1024, 1000, "Medium Instance", ProvisioningType.THIN, false, false, null);
-            // Save default disk offerings
-            createdefaultDiskOffering(null, "Small", "Small Disk, 5 GB", ProvisioningType.THIN, 5, null, false, false);
-            createdefaultDiskOffering(null, "Medium", "Medium Disk, 20 GB", ProvisioningType.THIN, 20, null, false, false);
-            createdefaultDiskOffering(null, "Large", "Large Disk, 100 GB", ProvisioningType.THIN, 100, null, false, false);
-            createdefaultDiskOffering(null, "Large", "Large Disk, 100 GB", ProvisioningType.THIN, 100, null, false, false);
-            createdefaultDiskOffering(null, "Custom", "Custom Disk", ProvisioningType.THIN, 0, null, true, false);
-
-            // Save the mount parent to the configuration table
-            String mountParent = getMountParent();
-            if (mountParent != null) {
-                _configDao.update(Config.MountParent.key(), Config.MountParent.getCategory(), mountParent);
-                s_logger.debug("ConfigurationServer saved \"" + mountParent + "\" as mount.parent.");
-            } else {
-                s_logger.debug("ConfigurationServer could not detect mount.parent.");
-            }
-
-            String hostIpAdr = NetUtils.getDefaultHostIp();
-            boolean needUpdateHostIp = true;
-            if (hostIpAdr != null) {
-                Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
-                if (devel) {
-                    String value = _configDao.getValue(ApiServiceConfiguration.ManagementServerAddresses.key());
-                    if (value != null && !value.equals("localhost")) {
-                        needUpdateHostIp = false;
-                    }
-                }
-
-                if (needUpdateHostIp) {
-                    _configDepot.createOrUpdateConfigObject(ApiServiceConfiguration.class.getSimpleName(), ApiServiceConfiguration.ManagementServerAddresses, hostIpAdr);
-                    s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host.");
-                }
-            }
-
-            // generate a single sign-on key
-            updateSSOKey();
-
-            // Create default network offerings
-            createDefaultNetworkOfferings();
-
-            // Create default networks
-            createDefaultNetworks();
-
-            // Create userIpAddress ranges
-
-            // Update existing vlans with networkId
-            List<VlanVO> vlans = _vlanDao.listAll();
-            if (vlans != null && !vlans.isEmpty()) {
-                for (final VlanVO vlan : vlans) {
-                    if (vlan.getNetworkId().longValue() == 0) {
-                        updateVlanWithNetworkId(vlan);
-                    }
-
-                    // Create vlan user_ip_address range
-                    String ipPange = vlan.getIpRange();
-                    String[] range = ipPange.split("-");
-                    final String startIp = range[0];
-                    final String endIp = range[1];
-
-                    Transaction.execute(new TransactionCallbackNoReturn() {
-                        @Override
-                        public void doInTransactionWithoutResult(TransactionStatus status) {
-                            IPRangeConfig config = new IPRangeConfig();
-                            long startIPLong = NetUtils.ip2Long(startIp);
-                            long endIPLong = NetUtils.ip2Long(endIp);
-                            config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(),
-                                    vlan.getPhysicalNetworkId(), false);
-                        }
-                    });
-
-                }
-            }
-        }
-        // Update resource count if needed
-        updateResourceCount();
-
-        // store the public and private keys in the database
-        updateKeyPairs();
-
-        // generate a PSK to communicate with SSVM
-        updateSecondaryStorageVMSharedKey();
-
-        // generate a random password for system vm
-        updateSystemvmPassword();
-
-        // generate a random password used to authenticate zone-to-zone copy
-        generateSecStorageVmCopyPassword();
-
-        // Update the cloud identifier
-        updateCloudIdentifier();
-
-        _configDepotAdmin.populateConfigurations();
-        // setup XenServer default PV driver version
-        initiateXenServerPVDriverVersion();
-
-        // We should not update seed data UUID column here since this will be invoked in upgrade case as well.
-        //updateUuids();
-        // Set init to true
-        _configDao.update("init", "Hidden", "true");
-
-        // invalidate cache in DAO as we have changed DB status
-        _configDao.invalidateCache();
-    }
-
-    private void templateDetailsInitIfNotExist(long id, String name, String value) {
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        PreparedStatement stmt = null;
-        PreparedStatement stmtInsert = null;
-        boolean insert = false;
-        try {
-            txn.start();
-            stmt = txn.prepareAutoCloseStatement("SELECT id FROM vm_template_details WHERE template_id=? and name=?");
-            stmt.setLong(1, id);
-            stmt.setString(2, name);
-            ResultSet rs = stmt.executeQuery();
-            if (rs == null || !rs.next()) {
-                insert = true;
-            }
-            stmt.close();
-
-            if (insert) {
-                stmtInsert = txn.prepareAutoCloseStatement("INSERT INTO vm_template_details(template_id, name, value) VALUES(?, ?, ?)");
-                stmtInsert.setLong(1, id);
-                stmtInsert.setString(2, name);
-                stmtInsert.setString(3, value);
-                if (stmtInsert.executeUpdate() < 1) {
-                    throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name);
-                }
-            }
-            txn.commit();
-        } catch (Exception e) {
-            s_logger.warn("Unable to init template " + id + " datails: " + name, e);
-            throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name);
-        }
-    }
-
-    private void initiateXenServerPVDriverVersion() {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                TransactionLegacy txn = TransactionLegacy.currentTxn();
-                String pvdriverversion = Config.XenServerPVdriverVersion.getDefaultValue();
-                PreparedStatement pstmt = null;
-                ResultSet rs1 = null;
-                ResultSet rs2 = null;
-                try {
-                    String oldValue = _configDao.getValue(Config.XenServerPVdriverVersion.key());
-                    if (oldValue == null) {
-                        String sql = "select resource from host where hypervisor_type='XenServer' and removed is null and status not in ('Error', 'Removed') group by resource";
-                        pstmt = txn.prepareAutoCloseStatement(sql);
-                        rs1 = pstmt.executeQuery();
-                        while (rs1.next()) {
-                            String resouce = rs1.getString(1); //resource column
-                            if (resouce == null)
-                                continue;
-                            if (resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56Resource")
-                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource")
-                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56SP2Resource")
-                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer600Resource")
-                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer602Resource")) {
-                                pvdriverversion = "xenserver56";
-                                break;
-                            }
-                        }
-                        _configDao.getValueAndInitIfNotExist(Config.XenServerPVdriverVersion.key(), Config.XenServerPVdriverVersion.getCategory(), pvdriverversion,
-                                Config.XenServerPVdriverVersion.getDescription());
-                        sql = "select id from vm_template where hypervisor_type='XenServer'  and format!='ISO' and removed is null";
-                        pstmt = txn.prepareAutoCloseStatement(sql);
-                        rs2 = pstmt.executeQuery();
-                        List<Long> tmpl_ids = new ArrayList<Long>();
-                        while (rs2.next()) {
-                            tmpl_ids.add(rs2.getLong(1));
-                        }
-                        for (Long tmpl_id : tmpl_ids) {
-                            templateDetailsInitIfNotExist(tmpl_id, "hypervisortoolsversion", pvdriverversion);
-                        }
-                    }
-                } catch (Exception e) {
-                    s_logger.debug("initiateXenServerPVDriverVersion failed due to " + e.toString());
-                    // ignore
-                }
-            }
-        });
-    }
-
-    private String getMountParent() {
-        return getEnvironmentProperty("mount.parent");
-    }
-
-    private String getEnvironmentProperty(String name) {
-        try {
-            final File propsFile = PropertiesUtil.findConfigFile("environment.properties");
-
-            if (propsFile == null) {
-                return null;
-            } else {
-                final Properties props = new Properties();
-                try(final FileInputStream finputstream = new FileInputStream(propsFile);) {
-                    props.load(finputstream);
-                }catch (IOException e) {
-                    s_logger.error("getEnvironmentProperty:Exception:" + e.getMessage());
-                }
-                return props.getProperty("mount.parent");
-            }
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    @DB
-    public void saveUser() {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                TransactionLegacy txn = TransactionLegacy.currentTxn();
-                // insert system account
-                String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (1, UUID(), 'system', '1', '1', '1', 1)";
-
-                try {
-                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
-                    stmt.executeUpdate();
-                } catch (SQLException ex) {
-                    s_logger.debug("Looks like system account already exists");
-                }
-                // insert system user
-                insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)"
-                        + " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), 1)";
-
-                try {
-                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
-                    stmt.executeUpdate();
-                } catch (SQLException ex) {
-                    s_logger.debug("Looks like system user already exists");
-                }
-
-                // insert admin user, but leave the account disabled until we set a
-                // password with the user authenticator
-                long id = 2;
-                String username = "admin";
-                String firstname = "admin";
-                String lastname = "cloud";
-
-                // create an account for the admin user first
-                insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username
-                        + "', '1', '1', '1', 1)";
-                try {
-                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
-                    stmt.executeUpdate();
-                } catch (SQLException ex) {
-                    s_logger.debug("Looks like admin account already exists");
-                }
-
-                // now insert the user
-                insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, user.default) " + "VALUES (" + id
-                        + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled', 1)";
-
-                try {
-                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
-                    stmt.executeUpdate();
-                } catch (SQLException ex) {
-                    s_logger.debug("Looks like admin user already exists");
-                }
-
-                try {
-                    String tableName = "security_group";
-                    try {
-                        String checkSql = "SELECT * from network_group";
-                        PreparedStatement stmt = txn.prepareAutoCloseStatement(checkSql);
-                        stmt.executeQuery();
-                        tableName = "network_group";
-                    } catch (Exception ex) {
-                        // Ignore in case of exception, table must not exist
-                    }
-
-                    insertSql = "SELECT * FROM " + tableName + " where account_id=2 and name='default'";
-                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
-                    ResultSet rs = stmt.executeQuery();
-                    if (!rs.next()) {
-                        // save default security group
-                        if (tableName.equals("security_group")) {
-                            insertSql = "INSERT INTO " + tableName + " (uuid, name, description, account_id, domain_id) "
-                                    + "VALUES (UUID(), 'default', 'Default Security Group', 2, 1)";
-                        } else {
-                            insertSql = "INSERT INTO " + tableName + " (name, description, account_id, domain_id, account_name) "
-                                    + "VALUES ('default', 'Default Security Group', 2, 1, 'admin')";
-                        }
-
-                        try {
-                            stmt = txn.prepareAutoCloseStatement(insertSql);
-                            stmt.executeUpdate();
-                        } catch (SQLException ex) {
-                            s_logger.warn("Failed to create default security group for default admin account due to ", ex);
-                        }
-                    }
-                    rs.close();
-                } catch (Exception ex) {
-                    s_logger.warn("Failed to create default security group for default admin account due to ", ex);
-                }
-            }
-        });
-    }
-
-    protected void updateCloudIdentifier() {
-        // Creates and saves a UUID as the cloud identifier
-        String currentCloudIdentifier = _configDao.getValue("cloud.identifier");
-        if (currentCloudIdentifier == null || currentCloudIdentifier.isEmpty()) {
-            String uuid = UUID.randomUUID().toString();
-            _configDao.update(Config.CloudIdentifier.key(), Config.CloudIdentifier.getCategory(), uuid);
-        }
-    }
-
-    @DB
-    protected void updateSystemvmPassword() {
-        String userid = System.getProperty("user.name");
-        if (!userid.startsWith("cloud")) {
-            return;
-        }
-
-        if (!Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
-            return;
-        }
-
-        String already = _configDao.getValue("system.vm.password");
-        if (already == null) {
-            TransactionLegacy txn = TransactionLegacy.currentTxn();
-            try {
-                String rpassword = _mgrService.generateRandomPassword();
-                String wSql = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) "
-                + "VALUES ('Secure','DEFAULT', 'management-server','system.vm.password', ?,'randmon password generated each management server starts for system vm')";
-                PreparedStatement stmt = txn.prepareAutoCloseStatement(wSql);
-                stmt.setString(1, DBEncryptionUtil.encrypt(rpassword));
-                stmt.executeUpdate();
-                s_logger.info("Updated systemvm password in database");
-            } catch (SQLException e) {
-                s_logger.error("Cannot retrieve systemvm password", e);
-            }
-        }
-
-    }
-
-    @Override
-    @DB
-    public void updateKeyPairs() {
-        // Grab the SSH key pair and insert it into the database, if it is not present
-
-        String username = System.getProperty("user.name");
-        Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
-        if (!username.equalsIgnoreCase("cloud") && !devel) {
-            s_logger.warn("Systemvm keypairs could not be set. Management server should be run as cloud user, or in development mode.");
-            return;
-        }
-        String already = _configDao.getValue("ssh.privatekey");
-        String homeDir = System.getProperty("user.home");
-        if (homeDir == null) {
-            throw new CloudRuntimeException("Cannot get home directory for account: " + username);
-        }
-
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Processing updateKeyPairs");
-        }
-
-        if (homeDir != null && homeDir.startsWith("~")) {
-            s_logger.error("No home directory was detected for the user '" + username + "'. Please check the profile of this user.");
-            throw new CloudRuntimeException("No home directory was detected for the user '" + username + "'. Please check the profile of this user.");
-        }
-
-        // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server
-        File privkeyfile = null;
-        File pubkeyfile = null;
-        if (devel) {
-            privkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud");
-            pubkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud.pub");
-        } else {
-            privkeyfile = new File(homeDir + "/.ssh/id_rsa");
-            pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub");
-        }
-
-        if (already == null || already.isEmpty()) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Systemvm keypairs not found in database. Need to store them in the database");
-            }
-            // FIXME: take a global database lock here for safety.
-            boolean onWindows = isOnWindows();
-            if(!onWindows) {
-                Script.runSimpleBashScript("if [ -f " + privkeyfile + " ]; then rm -f " + privkeyfile + "; fi; ssh-keygen -t rsa -m PEM -N '' -f " + privkeyfile + " -q 2>/dev/null || ssh-keygen -t rsa -N '' -f " + privkeyfile + " -q");
-            }
-
-            final String privateKey;
-            final String publicKey;
-            try {
-                privateKey = new String(Files.readAllBytes(privkeyfile.toPath()));
-            } catch (IOException e) {
-                s_logger.error("Cannot read the private key file", e);
-                throw new CloudRuntimeException("Cannot read the private key file");
-            }
-            try {
-                publicKey = new String(Files.readAllBytes(pubkeyfile.toPath()));
-            } catch (IOException e) {
-                s_logger.error("Cannot read the public key file", e);
-                throw new CloudRuntimeException("Cannot read the public key file");
-            }
-
-            final String insertSql1 =
-                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
-                            "VALUES ('Hidden','DEFAULT', 'management-server','ssh.privatekey', '" + DBEncryptionUtil.encrypt(privateKey) +
-                            "','Private key for the entire CloudStack')";
-            final String insertSql2 =
-                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
-                            "VALUES ('Hidden','DEFAULT', 'management-server','ssh.publickey', '" + DBEncryptionUtil.encrypt(publicKey) +
-                            "','Public key for the entire CloudStack')";
-
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-
-                    TransactionLegacy txn = TransactionLegacy.currentTxn();
-                    try {
-                        PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1);
-                        stmt1.executeUpdate();
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Private key inserted into database");
-                        }
-                    } catch (SQLException ex) {
-                        s_logger.error("SQL of the private key failed", ex);
-                        throw new CloudRuntimeException("SQL of the private key failed");
-                    }
-
-                    try {
-                        PreparedStatement stmt2 = txn.prepareAutoCloseStatement(insertSql2);
-                        stmt2.executeUpdate();
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Public key inserted into database");
-                        }
-                    } catch (SQLException ex) {
-                        s_logger.error("SQL of the public key failed", ex);
-                        throw new CloudRuntimeException("SQL of the public key failed");
-                    }
-                }
-            });
-
-        } else {
-            s_logger.info("Keypairs already in database, updating local copy");
-            updateKeyPairsOnDisk(homeDir);
-        }
-        s_logger.info("Going to update systemvm iso with generated keypairs if needed");
-        try {
-            injectSshKeysIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath(), privkeyfile.getAbsolutePath());
-        } catch (CloudRuntimeException e) {
-            if (!devel) {
-                throw new CloudRuntimeException(e.getMessage());
-            }
-        }
-    }
-
-    @Override
-    public List<ConfigurationVO> getConfigListByScope(String scope, Long resourceId) {
-
-        // Getting the list of parameters defined at the scope
-        Set<ConfigKey<?>> configList = _configDepot.getConfigListByScope(scope);
-        List<ConfigurationVO> configVOList = new ArrayList<ConfigurationVO>();
-        for (ConfigKey<?> param : configList) {
-            ConfigurationVO configVo = _configDao.findByName(param.toString());
-            configVo.setValue(_configDepot.get(param.toString()).valueIn(resourceId).toString());
-            configVOList.add(configVo);
-        }
-        return configVOList;
-    }
-
-    private void writeKeyToDisk(String key, String keyPath) {
-        File keyfile = new File(keyPath);
-        if (!keyfile.exists()) {
-            try {
-                keyfile.createNewFile();
-            } catch (IOException e) {
-                s_logger.warn("Failed to create file: " + e.toString());
-                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot create  key file " + keyPath);
-            }
-        }
-
-        if (keyfile.exists()) {
-            try (FileOutputStream kStream = new FileOutputStream(keyfile);){
-                if (kStream != null) {
-                    kStream.write(key.getBytes());
-                }
-            } catch (FileNotFoundException e) {
-                s_logger.warn("Failed to write  key to " + keyfile.getAbsolutePath());
-                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot find  key file " + keyPath);
-            } catch (IOException e) {
-                s_logger.warn("Failed to write  key to " + keyfile.getAbsolutePath());
-                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot write to  key file " + keyPath);
-            }
-        }
-
-    }
-
-    private void updateKeyPairsOnDisk(String homeDir) {
-        File keyDir = new File(homeDir + "/.ssh");
-        Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
-        if (!keyDir.isDirectory()) {
-            s_logger.warn("Failed to create " + homeDir + "/.ssh for storing the SSH keypars");
-            keyDir.mkdir();
-        }
-        String pubKey = _configDao.getValue("ssh.publickey");
-        String prvKey = _configDao.getValue("ssh.privatekey");
-
-        // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server
-        if (devel) {
-            writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa.cloud");
-            writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.cloud.pub");
-        } else {
-            writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa");
-            writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.pub");
-        }
-    }
-
-    protected void injectSshKeysIntoSystemVmIsoPatch(String publicKeyPath, String privKeyPath) {
-        s_logger.info("Trying to inject public and private keys into systemvm iso");
-        String injectScript = getInjectScript();
-        String scriptPath = Script.findScript("", injectScript);
-        String systemVmIsoPath = Script.findScript("", "vms/systemvm.iso");
-        if (scriptPath == null) {
-            throw new CloudRuntimeException("Unable to find key inject script " + injectScript);
-        }
-        if (systemVmIsoPath == null) {
-            throw new CloudRuntimeException("Unable to find systemvm iso vms/systemvm.iso");
-        }
-        Script command = null;
-        if(isOnWindows()) {
-            command = new Script("python", s_logger);
-        } else {
-            command = new Script("/bin/bash", s_logger);
-        }
-        if (isOnWindows()) {
-            scriptPath = scriptPath.replaceAll("\\\\" ,"/" );
-            systemVmIsoPath = systemVmIsoPath.replaceAll("\\\\" ,"/" );
-            publicKeyPath = publicKeyPath.replaceAll("\\\\" ,"/" );
-            privKeyPath = privKeyPath.replaceAll("\\\\" ,"/" );
-        }
-        command.add(scriptPath);
-        command.add(publicKeyPath);
-        command.add(privKeyPath);
-        command.add(systemVmIsoPath);
-
-        final String result = command.execute();
-        s_logger.info("Injected public and private keys into systemvm iso with result : " + result);
-        if (result != null) {
-            s_logger.warn("Failed to inject generated public key into systemvm iso " + result);
-            throw new CloudRuntimeException("Failed to inject generated public key into systemvm iso " + result);
-        }
-    }
-
-    protected String getInjectScript() {
-        String injectScript = null;
-        boolean onWindows = isOnWindows();
-        if(onWindows) {
-            injectScript = "scripts/vm/systemvm/injectkeys.py";
-        } else {
-            injectScript = "scripts/vm/systemvm/injectkeys.sh";
-        }
-        return injectScript;
-    }
-
-    protected boolean isOnWindows() {
-        String os = System.getProperty("os.name", "generic").toLowerCase();
-        boolean onWindows = (os != null && os.startsWith("windows"));
-        return onWindows;
-    }
-
-    @DB
-    protected void generateSecStorageVmCopyPassword() {
-        String already = _configDao.getValue("secstorage.copy.password");
-
-        if (already == null) {
-
-            s_logger.info("Need to store secondary storage vm copy password in the database");
-            String password = PasswordGenerator.generateRandomPassword(12);
-
-            final String insertSql1 =
-                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
-                            "VALUES ('Hidden','DEFAULT', 'management-server','secstorage.copy.password', '" + DBEncryptionUtil.encrypt(password) +
-                            "','Password used to authenticate zone-to-zone template copy requests')";
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-
-                    TransactionLegacy txn = TransactionLegacy.currentTxn();
-                    try {
-                        PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1);
-                        stmt1.executeUpdate();
-                        s_logger.debug("secondary storage vm copy password inserted into database");
-                    } catch (SQLException ex) {
-                        s_logger.warn("Failed to insert secondary storage vm copy password", ex);
-                    }
-                }
-            });
-        }
-    }
-
-    private void updateSSOKey() {
-        try {
-            _configDao.update(Config.SSOKey.key(), Config.SSOKey.getCategory(), getPrivateKey());
-        } catch (NoSuchAlgorithmException ex) {
-            s_logger.error("error generating sso key", ex);
-        }
-    }
-
-    /**
-     * preshared key to be used by management server to communicate with SSVM during volume/template upload
-     */
-    private void updateSecondaryStorageVMSharedKey() {
-        try {
-            ConfigurationVO configInDB = _configDao.findByName(Config.SSVMPSK.key());
-            if(configInDB == null) {
-                ConfigurationVO configVO = new ConfigurationVO(Config.SSVMPSK.getCategory(), "DEFAULT", Config.SSVMPSK.getComponent(), Config.SSVMPSK.key(), getPrivateKey(),
-                        Config.SSVMPSK.getDescription());
-                s_logger.info("generating a new SSVM PSK. This goes to SSVM on Start");
-                _configDao.persist(configVO);
-            } else if (StringUtils.isEmpty(configInDB.getValue())) {
-                s_logger.info("updating the SSVM PSK with new value. This goes to SSVM on Start");
-                _configDao.update(Config.SSVMPSK.key(), Config.SSVMPSK.getCategory(), getPrivateKey());
-            }
-        } catch (NoSuchAlgorithmException ex) {
-            s_logger.error("error generating ssvm psk", ex);
-        }
-    }
-
-    private String getPrivateKey() throws NoSuchAlgorithmException {
-        String encodedKey = null;
-        // Algorithm for generating Key is SHA1, should this be configurable?
-        KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
-        SecretKey key = generator.generateKey();
-        encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
-        return encodedKey;
-
-    }
-
-
-    @DB
-    protected HostPodVO createPod(long userId, String podName, final long zoneId, String gateway, String cidr, final String startIp, String endIp)
-            throws InternalErrorException {
-        String[] cidrPair = cidr.split("\\/");
-        String cidrAddress = cidrPair[0];
-        int cidrSize = Integer.parseInt(cidrPair[1]);
-
-        if (startIp != null) {
-            if (endIp == null) {
-                endIp = NetUtils.getIpRangeEndIpFromCidr(cidrAddress, cidrSize);
-            }
-        }
-
-        // Create the new pod in the database
-        String ipRange;
-        if (startIp != null) {
-            ipRange = startIp + "-";
-            if (endIp != null) {
-                ipRange += endIp;
-            }
-        } else {
-            ipRange = "";
-        }
-
-        final HostPodVO pod = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange);
-        try {
-            final String endIpFinal = endIp;
-            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InternalErrorException>() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) throws InternalErrorException {
-                    if (_podDao.persist(pod) == null) {
-                        throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support.");
-                    }
-
-                    if (startIp != null) {
-                        _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, false, null);
-                    }
-
-                    String ipNums = _configDao.getValue("linkLocalIp.nums");
-                    int nums = Integer.parseInt(ipNums);
-                    if (nums > 16 || nums <= 0) {
-                        throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
-                    }
-                    /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
-                    String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(nums);
-                    if (linkLocalIpRanges == null) {
-                        throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
-                    } else {
-                        _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
-                    }
-                }
-            });
-        } catch (Exception e) {
-            s_logger.error("Unable to create new pod due to " + e.getMessage(), e);
-            throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support.");
-        }
-
-        return pod;
-    }
-
-    private DiskOfferingVO createdefaultDiskOffering(Long domainId, String name, String description, ProvisioningType provisioningType,
-            int numGibibytes, String tags, boolean isCustomized, boolean isSystemUse) {
-        long diskSize = numGibibytes;
-        diskSize = diskSize * 1024 * 1024 * 1024;
-        tags = cleanupTags(tags);
-
-        DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, provisioningType, diskSize, tags, isCustomized, null, null, null);
-        newDiskOffering.setUniqueName("Cloud.Com-" + name);
-        // leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
-        newDiskOffering.setSystemUse(isSystemUse);
-        newDiskOffering = _diskOfferingDao.persistDeafultDiskOffering(newDiskOffering);
-        return newDiskOffering;
-    }
-
-    private ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText,
-            ProvisioningType provisioningType, boolean localStorageRequired, boolean offerHA, String tags) {
-        tags = cleanupTags(tags);
-        ServiceOfferingVO offering =
-                new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, provisioningType, localStorageRequired, false, tags, false, null, false);
-        offering.setUniqueName("Cloud.Com-" + name);
-        // leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
-        offering = _serviceOfferingDao.persistSystemServiceOffering(offering);
-        return offering;
-    }
-
-    private String cleanupTags(String tags) {
-        if (tags != null) {
-            String[] tokens = tags.split(",");
-            StringBuilder t = new StringBuilder();
-            for (int i = 0; i < tokens.length; i++) {
-                t.append(tokens[i].trim()).append(",");
-            }
-            t.delete(t.length() - 1, t.length());
-            tags = t.toString();
-        }
-
-        return tags;
-    }
-
-    @DB
-    protected void createDefaultNetworkOfferings() {
-
-        NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPublicNetwork, TrafficType.Public, true);
-        publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering);
-        NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemManagementNetwork, TrafficType.Management, false);
-        managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering);
-        NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemControlNetwork, TrafficType.Control, false);
-        controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
-        NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
-        storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
-        NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
-        privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
-
-        //populate providers
-        final Map<Network.Service, Network.Provider> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
-        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
-        defaultSharedNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
-        defaultSharedNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
-
-        final Map<Network.Service, Network.Provider> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
-
-        final Map<Network.Service, Network.Provider> defaultSharedSGNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
-        defaultSharedSGNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
-        defaultSharedSGNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
-        defaultSharedSGNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
-        defaultSharedSGNetworkOfferingProviders.put(Service.SecurityGroup, Provider.SecurityGroupProvider);
-
-        final Map<Network.Service, Network.Provider> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, Provider.VirtualRouter);
-        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, Provider.VirtualRouter);
-
-        final Map<Network.Service, Network.Provider> netscalerServiceProviders = new HashMap<Network.Service, Network.Provider>();
-        netscalerServiceProviders.put(Service.Dhcp, Provider.VirtualRouter);
-        netscalerServiceProviders.put(Service.Dns, Provider.VirtualRouter);
-        netscalerServiceProviders.put(Service.UserData, Provider.VirtualRouter);
-        netscalerServiceProviders.put(Service.SecurityGroup, Provider.SecurityGroupProvider);
-        netscalerServiceProviders.put(Service.StaticNat, Provider.Netscaler);
-        netscalerServiceProviders.put(Service.Lb, Provider.Netscaler);
-
-        // The only one diff between 1 and 2 network offerings is that the first one has SG enabled. In Basic zone only
-        // first network offering has to be enabled, in Advance zone - the second one
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // Offering #1
-                NetworkOfferingVO defaultSharedSGNetworkOffering =
-                        new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
-                                TrafficType.Guest, false, true, null, null, true, Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false, false);
-
-                defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled);
-                defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering);
-
-                for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #2
-                NetworkOfferingVO defaultSharedNetworkOffering =
-                        new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, false, true, null, null, true,
-                                Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false, false);
-
-                defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled);
-                defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering);
-
-                for (Service service : defaultSharedNetworkOfferingProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #3
-                NetworkOfferingVO defaultIsolatedSourceNatEnabledNetworkOffering =
-                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
-                                "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Required, null,
-                                Network.GuestType.Isolated, true, false, false, false, true, false);
-
-                defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
-                defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering);
-
-                for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service,
-                                    defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #4
-                NetworkOfferingVO defaultIsolatedEnabledNetworkOffering =
-                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest,
-                                false, true, null, null, true, Availability.Optional, null, Network.GuestType.Isolated, true, true, false, false, false, false);
-
-                defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
-                defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering);
-
-                for (Service service : defaultIsolatedNetworkOfferingProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #5
-                NetworkOfferingVO defaultNetscalerNetworkOffering =
-                        new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
-                                "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true,
-                                Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false, false, false);
-
-                defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled);
-                defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering);
-
-                for (Service service : netscalerServiceProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #6
-                NetworkOfferingVO defaultNetworkOfferingForVpcNetworks =
-                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
-                                "Offering for Isolated Vpc networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional,
-                                null, Network.GuestType.Isolated, false, false, false, false, true, true);
-
-                defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled);
-                defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks);
-
-                Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
-                defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter);
-
-                for (Map.Entry<Service,Provider> entry : defaultVpcNetworkOfferingProviders.entrySet()) {
-                     NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), entry.getKey(), entry.getValue());
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                // Offering #7
-                NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB =
-                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
-                                "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", TrafficType.Guest, false, false, null, null, true,
-                                Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false, true);
-
-                defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled);
-                defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB);
-
-                Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProvidersNoLB = new HashMap<Network.Service, Network.Provider>();
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dhcp, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dns, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.UserData, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.NetworkACL, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Gateway, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.SourceNat, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.StaticNat, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.PortForwarding, Provider.VPCVirtualRouter);
-                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Vpn, Provider.VPCVirtualRouter);
-
-                for (Map.Entry<Service,Provider> entry : defaultVpcNetworkOfferingProvidersNoLB.entrySet()) {
-                    NetworkOfferingServiceMapVO offService =
-                            new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworksNoLB.getId(), entry.getKey(), entry.getValue());
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                //offering #8 - network offering with internal lb service
-                NetworkOfferingVO internalLbOff =
-                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
-                                "Offering for Isolated Vpc networks with Internal LB support", TrafficType.Guest, false, false, null, null, true, Availability.Optional, null,
-                                Network.GuestType.Isolated, false, false, false, true, false, true);
-
-                internalLbOff.setState(NetworkOffering.State.Enabled);
-                internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff);
-
-                Map<Network.Service, Network.Provider> internalLbOffProviders = new HashMap<Network.Service, Network.Provider>();
-                internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter);
-                internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter);
-                internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter);
-                internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter);
-                internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter);
-                internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm);
-                internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter);
-
-                for (Service service : internalLbOffProviders.keySet()) {
-                    NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(internalLbOff.getId(), service, internalLbOffProviders.get(service));
-                    _ntwkOfferingServiceMapDao.persist(offService);
-                    s_logger.trace("Added service for the network offering: " + offService);
-                }
-
-                _networkOfferingDao.persistDefaultL2NetworkOfferings();
-            }
-        });
-    }
-
-    private void createDefaultNetworks() {
-        List<DataCenterVO> zones = _dataCenterDao.listAll();
-        long id = 1;
-
-        HashMap<TrafficType, String> guruNames = new HashMap<TrafficType, String>();
-        guruNames.put(TrafficType.Public, PublicNetworkGuru.class.getSimpleName());
-        guruNames.put(TrafficType.Management, PodBasedNetworkGuru.class.getSimpleName());
-        guruNames.put(TrafficType.Control, ControlNetworkGuru.class.getSimpleName());
-        guruNames.put(TrafficType.Storage, StorageNetworkGuru.class.getSimpleName());
-        guruNames.put(TrafficType.Guest, DirectPodBasedNetworkGuru.class.getSimpleName());
-
-        for (DataCenterVO zone : zones) {
-            long zoneId = zone.getId();
-            long accountId = 1L;
-            Long domainId = zone.getDomainId();
-
-            if (domainId == null) {
-                domainId = 1L;
-            }
-            // Create default networks - system only
-            List<NetworkOfferingVO> ntwkOff = _networkOfferingDao.listSystemNetworkOfferings();
-
-            for (NetworkOfferingVO offering : ntwkOff) {
-                if (offering.isSystemOnly()) {
-                    long related = id;
-                    long networkOfferingId = offering.getId();
-                    Mode mode = Mode.Static;
-                    String networkDomain = null;
-
-                    BroadcastDomainType broadcastDomainType = null;
-                    TrafficType trafficType = offering.getTrafficType();
-
-                    boolean specifyIpRanges = false;
-
-                    if (trafficType == TrafficType.Management) {
-                        broadcastDomainType = BroadcastDomainType.Native;
-                    } else if (trafficType == TrafficType.Storage) {
-                        broadcastDomainType = BroadcastDomainType.Native;
-                        specifyIpRanges = true;
-                    } else if (trafficType == TrafficType.Control) {
-                        broadcastDomainType = BroadcastDomainType.LinkLocal;
-                    } else if (offering.getTrafficType() == TrafficType.Public) {
-                        if ((zone.getNetworkType() == NetworkType.Advanced && !zone.isSecurityGroupEnabled()) || zone.getNetworkType() == NetworkType.Basic) {
-                            specifyIpRanges = true;
-                            broadcastDomainType = BroadcastDomainType.Vlan;
-                        } else {
-                            continue;
-                        }
-                    }
-
-                    if (broadcastDomainType != null) {
-                        NetworkVO network =
-                                new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain,
-                                        Network.GuestType.Shared, zoneId, null, null, specifyIpRanges, null, offering.getRedundantRouter());
-                        network.setGuruName(guruNames.get(network.getTrafficType()));
-                        network.setDns1(zone.getDns1());
-                        network.setDns2(zone.getDns2());
-                        network.setState(State.Implemented);
-                        _networkDao.persist(network, false, getServicesAndProvidersForNetwork(networkOfferingId));
-                        id++;
-                    }
-                }
-            }
-        }
-    }
-
-    private void updateVlanWithNetworkId(VlanVO vlan) {
-        long zoneId = vlan.getDataCenterId();
-        long networkId = 0L;
-        DataCenterVO zone = _zoneDao.findById(zoneId);
-
-        if (zone.getNetworkType() == NetworkType.Advanced) {
-            networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Public);
-        } else {
-            networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Guest);
-        }
-
-        vlan.setNetworkId(networkId);
-        _vlanDao.update(vlan.getId(), vlan);
-    }
-
-    private long getSystemNetworkIdByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // find system public network offering
-        Long networkOfferingId = null;
-        List<NetworkOfferingVO> offerings = _networkOfferingDao.listSystemNetworkOfferings();
-        for (NetworkOfferingVO offering : offerings) {
-            if (offering.getTrafficType() == trafficType) {
-                networkOfferingId = offering.getId();
-                break;
-            }
-        }
-
-        if (networkOfferingId == null) {
-            throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType);
-        }
-
-        List<NetworkVO> networks = _networkDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId);
-        if (networks == null || networks.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId);
-        }
-        return networks.get(0).getId();
-    }
-
-    @DB
-    public void updateResourceCount() {
-        ResourceType[] resourceTypes = Resource.ResourceType.values();
-        List<AccountVO> accounts = _accountDao.listAll();
-        List<DomainVO> domains = _domainDao.listAll();
-        List<ResourceCountVO> domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain);
-        List<ResourceCountVO> accountResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Account);
-
-        final List<ResourceType> accountSupportedResourceTypes = new ArrayList<ResourceType>();
-        final List<ResourceType> domainSupportedResourceTypes = new ArrayList<ResourceType>();
-
-        for (ResourceType resourceType : resourceTypes) {
-            if (resourceType.supportsOwner(ResourceOwnerType.Account)) {
-                accountSupportedResourceTypes.add(resourceType);
-            }
-            if (resourceType.supportsOwner(ResourceOwnerType.Domain)) {
-                domainSupportedResourceTypes.add(resourceType);
-            }
-        }
-
-        final int accountExpectedCount = accountSupportedResourceTypes.size();
-        final int domainExpectedCount = domainSupportedResourceTypes.size();
-
-        if ((domainResourceCount.size() < domainExpectedCount * domains.size())) {
-            s_logger.debug("resource_count table has records missing for some domains...going to insert them");
-            for (final DomainVO domain : domains) {
-                // Lock domain
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        _domainDao.lockRow(domain.getId(), true);
-                        List<ResourceCountVO> domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain);
-                        List<String> domainCountStr = new ArrayList<String>();
-                        for (ResourceCountVO domainCount : domainCounts) {
-                            domainCountStr.add(domainCount.getType().toString());
-                        }
-
-                        if (domainCountStr.size() < domainExpectedCount) {
-                            for (ResourceType resourceType : domainSupportedResourceTypes) {
-                                if (!domainCountStr.contains(resourceType.toString())) {
-                                    ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain);
-                                    s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId());
-                                    _resourceCountDao.persist(resourceCountVO);
-                                }
-                            }
-                        }
-                    }
-                });
-
-            }
-        }
-
-        if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) {
-            s_logger.debug("resource_count table has records missing for some accounts...going to insert them");
-            for (final AccountVO account : accounts) {
-                // lock account
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        _accountDao.lockRow(account.getId(), true);
-                        List<ResourceCountVO> accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account);
-                        List<String> accountCountStr = new ArrayList<String>();
-                        for (ResourceCountVO accountCount : accountCounts) {
-                            accountCountStr.add(accountCount.getType().toString());
-                        }
-
-                        if (accountCountStr.size() < accountExpectedCount) {
-                            for (ResourceType resourceType : accountSupportedResourceTypes) {
-                                if (!accountCountStr.contains(resourceType.toString())) {
-                                    ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account);
-                                    s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId());
-                                    _resourceCountDao.persist(resourceCountVO);
-                                }
-                            }
-                        }
-                    }
-                });
-            }
-        }
-    }
-
-    public Map<String, String> getServicesAndProvidersForNetwork(long networkOfferingId) {
-        Map<String, String> svcProviders = new HashMap<String, String>();
-        List<NetworkOfferingServiceMapVO> servicesMap = _ntwkOfferingServiceMapDao.listByNetworkOfferingId(networkOfferingId);
-
-        for (NetworkOfferingServiceMapVO serviceMap : servicesMap) {
-            if (svcProviders.containsKey(serviceMap.getService())) {
-                continue;
-            }
-            svcProviders.put(serviceMap.getService(), serviceMap.getProvider());
-        }
-
-        return svcProviders;
-    }
-
-}
diff --git a/server/src/com/cloud/server/LockMasterListener.java b/server/src/com/cloud/server/LockMasterListener.java
deleted file mode 100644
index 8c8ff91..0000000
--- a/server/src/com/cloud/server/LockMasterListener.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server;
-
-import java.util.List;
-
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.utils.db.Merovingian2;
-
-/**
- * when a management server is down.
- *
- */
-public class LockMasterListener implements ClusterManagerListener {
-    Merovingian2 _lockMaster;
-
-    public LockMasterListener(long msId) {
-        _lockMaster = Merovingian2.createLockMaster(msId);
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (ManagementServerHost node : nodeList) {
-            _lockMaster.cleanupForServer(node.getMsid());
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-}
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
deleted file mode 100644
index 872f9fd..0000000
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ /dev/null
@@ -1,4106 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.affinity.AffinityGroupProcessor;
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd;
-import org.apache.cloudstack.api.command.admin.account.DeleteAccountCmd;
-import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd;
-import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd;
-import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.account.LockAccountCmd;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.address.AcquirePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.address.AssociateIPAddrCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.address.ListPublicIpAddressesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.affinitygroup.UpdateVMAffinityGroupCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.alert.GenerateAlertCmd;
-import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
-import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
-import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
-import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
-import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
-import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd;
-import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
-import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd;
-import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd;
-import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
-import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
-import org.apache.cloudstack.api.command.admin.direct.download.UploadTemplateDirectDownloadCertificateCmd;
-import org.apache.cloudstack.api.command.admin.domain.CreateDomainCmd;
-import org.apache.cloudstack.api.command.admin.domain.DeleteDomainCmd;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
-import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
-import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
-import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
-import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
-import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
-import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCmd;
-import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
-import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
-import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
-import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.DeleteHostCmd;
-import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd;
-import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
-import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
-import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
-import org.apache.cloudstack.api.command.admin.host.ReleaseHostReservationCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
-import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
-import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
-import org.apache.cloudstack.api.command.admin.internallb.StartInternalLBVMCmd;
-import org.apache.cloudstack.api.command.admin.internallb.StopInternalLBVMCmd;
-import org.apache.cloudstack.api.command.admin.iso.AttachIsoCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.iso.CopyIsoCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.iso.DetachIsoCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.iso.ListIsoPermissionsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.iso.RegisterIsoCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.loadbalancer.ListLoadBalancerRuleInstancesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.AddNetworkDeviceCmd;
-import org.apache.cloudstack.api.command.admin.network.AddNetworkServiceProviderCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.network.CreatePhysicalNetworkCmd;
-import org.apache.cloudstack.api.command.admin.network.CreateStorageNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteNetworkDeviceCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteNetworkServiceProviderCmd;
-import org.apache.cloudstack.api.command.admin.network.DeletePhysicalNetworkCmd;
-import org.apache.cloudstack.api.command.admin.network.DeleteStorageNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
-import org.apache.cloudstack.api.command.admin.network.ListNetworkDeviceCmd;
-import org.apache.cloudstack.api.command.admin.network.ListNetworkIsolationMethodsCmd;
-import org.apache.cloudstack.api.command.admin.network.ListNetworkServiceProvidersCmd;
-import org.apache.cloudstack.api.command.admin.network.ListNetworksCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.ListPhysicalNetworksCmd;
-import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListSupportedNetworkServicesCmd;
-import org.apache.cloudstack.api.command.admin.network.MigrateNetworkCmd;
-import org.apache.cloudstack.api.command.admin.network.MigrateVPCCmd;
-import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.UpdateNetworkCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
-import org.apache.cloudstack.api.command.admin.network.UpdateNetworkServiceProviderCmd;
-import org.apache.cloudstack.api.command.admin.network.UpdatePhysicalNetworkCmd;
-import org.apache.cloudstack.api.command.admin.network.UpdateStorageNetworkIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
-import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForClusterCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForHostCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForZoneCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForClusterCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForHostCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForZoneCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.ConfigureOutOfBandManagementCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.IssueOutOfBandManagementPowerActionCmd;
-import org.apache.cloudstack.api.command.admin.outofbandmanagement.ChangeOutOfBandManagementPasswordCmd;
-import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
-import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
-import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
-import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
-import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
-import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
-import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd;
-import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd;
-import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
-import org.apache.cloudstack.api.command.admin.resource.CleanVMReservationsCmd;
-import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
-import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
-import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
-import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
-import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
-import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.DestroyRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
-import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
-import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
-import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.StartRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.StopRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
-import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.AddImageStoreS3CMD;
-import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.FindStoragePoolsForMigrationCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
-import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
-import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
-import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
-import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.DestroySystemVmCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.ListSystemVMsCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.MigrateSystemVMCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.RebootSystemVmCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.ScaleSystemVMCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.StartSystemVMCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.StopSystemVmCmd;
-import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd;
-import org.apache.cloudstack.api.command.admin.template.CopyTemplateCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.template.CreateTemplateCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.template.ListTemplatePermissionsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd;
-import org.apache.cloudstack.api.command.admin.template.RegisterTemplateCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.usage.AddTrafficMonitorCmd;
-import org.apache.cloudstack.api.command.admin.usage.AddTrafficTypeCmd;
-import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficMonitorCmd;
-import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficTypeCmd;
-import org.apache.cloudstack.api.command.admin.usage.GenerateUsageRecordsCmd;
-import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficMonitorsCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypesCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListUsageTypesCmd;
-import org.apache.cloudstack.api.command.admin.usage.RemoveRawUsageRecordsCmd;
-import org.apache.cloudstack.api.command.admin.usage.UpdateTrafficTypeCmd;
-import org.apache.cloudstack.api.command.admin.user.CreateUserCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.DisableUserCmd;
-import org.apache.cloudstack.api.command.admin.user.EnableUserCmd;
-import org.apache.cloudstack.api.command.admin.user.GetUserCmd;
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
-import org.apache.cloudstack.api.command.admin.user.LockUserCmd;
-import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
-import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
-import org.apache.cloudstack.api.command.admin.vm.AddNicToVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
-import org.apache.cloudstack.api.command.admin.vm.DeployVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.DestroyVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd;
-import org.apache.cloudstack.api.command.admin.vm.GetVMUserDataCmd;
-import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
-import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd;
-import org.apache.cloudstack.api.command.admin.vm.RebootVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
-import org.apache.cloudstack.api.command.admin.vm.RemoveNicFromVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.ResetVMPasswordCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.ResetVMSSHKeyCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.RestoreVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.ScaleVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.StartVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.StopVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.UpdateDefaultNicForVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.UpdateVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vm.UpgradeVMCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vmsnapshot.RevertToVMSnapshotCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.AttachVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.CreateVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.DetachVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.ResizeVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.UpdateVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.volume.UploadVolumeCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd;
-import org.apache.cloudstack.api.command.admin.vpc.CreateVPCCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
-import org.apache.cloudstack.api.command.admin.vpc.DeletePrivateGatewayCmd;
-import org.apache.cloudstack.api.command.admin.vpc.DeleteVPCOfferingCmd;
-import org.apache.cloudstack.api.command.admin.vpc.ListVPCsCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
-import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
-import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd;
-import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
-import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd;
-import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd;
-import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
-import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
-import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
-import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd;
-import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
-import org.apache.cloudstack.api.command.user.address.UpdateIPAddrCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.DeleteAffinityGroupCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupTypesCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
-import org.apache.cloudstack.api.command.user.affinitygroup.UpdateVMAffinityGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmProfileCmd;
-import org.apache.cloudstack.api.command.user.autoscale.CreateConditionCmd;
-import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScalePolicyCmd;
-import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmProfileCmd;
-import org.apache.cloudstack.api.command.user.autoscale.DeleteConditionCmd;
-import org.apache.cloudstack.api.command.user.autoscale.DisableAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.EnableAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScalePoliciesCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmGroupsCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmProfilesCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListConditionsCmd;
-import org.apache.cloudstack.api.command.user.autoscale.ListCountersCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
-import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
-import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
-import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
-import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd;
-import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
-import org.apache.cloudstack.api.command.user.firewall.CreateEgressFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.CreatePortForwardingRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.DeleteEgressFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.DeleteFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.DeletePortForwardingRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd;
-import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
-import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
-import org.apache.cloudstack.api.command.user.firewall.UpdateEgressFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.UpdateFirewallRuleCmd;
-import org.apache.cloudstack.api.command.user.firewall.UpdatePortForwardingRuleCmd;
-import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd;
-import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd;
-import org.apache.cloudstack.api.command.user.iso.AttachIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.CopyIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.DetachIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
-import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.AssignCertToLoadBalancerCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateApplicationLoadBalancerCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.DeleteApplicationLoadBalancerCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBHealthCheckPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBStickinessPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.RemoveCertFromLoadBalancerCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.RemoveFromLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UpdateApplicationLoadBalancerCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBHealthCheckPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBStickinessPolicyCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
-import org.apache.cloudstack.api.command.user.nat.CreateIpForwardingRuleCmd;
-import org.apache.cloudstack.api.command.user.nat.DeleteIpForwardingRuleCmd;
-import org.apache.cloudstack.api.command.user.nat.DisableStaticNatCmd;
-import org.apache.cloudstack.api.command.user.nat.EnableStaticNatCmd;
-import org.apache.cloudstack.api.command.user.nat.ListIpForwardingRulesCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLCmd;
-import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLListCmd;
-import org.apache.cloudstack.api.command.user.network.DeleteNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.ReplaceNetworkACLListCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
-import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
-import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
-import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
-import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
-import org.apache.cloudstack.api.command.user.project.ActivateProjectCmd;
-import org.apache.cloudstack.api.command.user.project.CreateProjectCmd;
-import org.apache.cloudstack.api.command.user.project.DeleteProjectCmd;
-import org.apache.cloudstack.api.command.user.project.DeleteProjectInvitationCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
-import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
-import org.apache.cloudstack.api.command.user.project.SuspendProjectCmd;
-import org.apache.cloudstack.api.command.user.project.UpdateProjectCmd;
-import org.apache.cloudstack.api.command.user.project.UpdateProjectInvitationCmd;
-import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.ListGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.RemoveFromGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.UpdateGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.resource.GetCloudIdentifierCmd;
-import org.apache.cloudstack.api.command.user.resource.ListHypervisorsCmd;
-import org.apache.cloudstack.api.command.user.resource.ListResourceLimitsCmd;
-import org.apache.cloudstack.api.command.user.resource.UpdateResourceCountCmd;
-import org.apache.cloudstack.api.command.user.resource.UpdateResourceLimitCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd;
-import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd;
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotFromVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
-import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotCmd;
-import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
-import org.apache.cloudstack.api.command.user.snapshot.RevertSnapshotCmd;
-import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
-import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd;
-import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
-import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
-import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
-import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd;
-import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd;
-import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
-import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
-import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
-import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
-import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
-import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
-import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
-import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
-import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
-import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
-import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
-import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd;
-import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
-import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
-import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
-import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
-import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
-import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
-import org.apache.cloudstack.api.command.user.vm.StopVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
-import org.apache.cloudstack.api.command.user.volume.AddResourceDetailCmd;
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
-import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
-import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.RemoveResourceDetailCmd;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
-import org.apache.cloudstack.api.command.user.vpc.CreateStaticRouteCmd;
-import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
-import org.apache.cloudstack.api.command.user.vpc.DeleteStaticRouteCmd;
-import org.apache.cloudstack.api.command.user.vpc.DeleteVPCCmd;
-import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
-import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
-import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
-import org.apache.cloudstack.api.command.user.vpc.ListVPCsCmd;
-import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd;
-import org.apache.cloudstack.api.command.user.vpc.UpdateVPCCmd;
-import org.apache.cloudstack.api.command.user.vpn.AddVpnUserCmd;
-import org.apache.cloudstack.api.command.user.vpn.CreateRemoteAccessVpnCmd;
-import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
-import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd;
-import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd;
-import org.apache.cloudstack.api.command.user.vpn.DeleteRemoteAccessVpnCmd;
-import org.apache.cloudstack.api.command.user.vpn.DeleteVpnConnectionCmd;
-import org.apache.cloudstack.api.command.user.vpn.DeleteVpnCustomerGatewayCmd;
-import org.apache.cloudstack.api.command.user.vpn.DeleteVpnGatewayCmd;
-import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd;
-import org.apache.cloudstack.api.command.user.vpn.ListVpnConnectionsCmd;
-import org.apache.cloudstack.api.command.user.vpn.ListVpnCustomerGatewaysCmd;
-import org.apache.cloudstack.api.command.user.vpn.ListVpnGatewaysCmd;
-import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd;
-import org.apache.cloudstack.api.command.user.vpn.RemoveVpnUserCmd;
-import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd;
-import org.apache.cloudstack.api.command.user.vpn.UpdateRemoteAccessVpnCmd;
-import org.apache.cloudstack.api.command.user.vpn.UpdateVpnConnectionCmd;
-import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
-import org.apache.cloudstack.api.command.user.vpn.UpdateVpnGatewayCmd;
-import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
-import org.apache.cloudstack.config.Configuration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.resourcedetail.dao.GuestOsDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.GetVncPortAnswer;
-import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.manager.allocator.HostAllocator;
-import com.cloud.alert.Alert;
-import com.cloud.alert.AlertManager;
-import com.cloud.alert.AlertVO;
-import com.cloud.alert.dao.AlertDao;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.QueryManagerImpl;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.consoleproxy.ConsoleProxyManagementState;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dc.AccountVlanMapVO;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.PodVlanMapVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.AccountVlanMapDao;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.PodVlanMapDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.deploy.DeploymentPlanningManager;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventVO;
-import com.cloud.event.dao.EventDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.gpu.GPU;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.host.DetailVO;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.host.HostTagVO;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.host.dao.HostDetailsDao;
-import com.cloud.host.dao.HostTagsDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorCapabilities;
-import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.info.ConsoleProxyInfo;
-import com.cloud.network.IpAddress;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.org.Cluster;
-import com.cloud.org.Grouping.AllocationState;
-import com.cloud.projects.Project;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.projects.ProjectManager;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ResourceTag.ResourceObjectType;
-import com.cloud.server.auth.UserAuthenticator;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.GuestOS;
-import com.cloud.storage.GuestOSCategoryVO;
-import com.cloud.storage.GuestOSHypervisor;
-import com.cloud.storage.GuestOSHypervisorVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.GuestOsCategory;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.GuestOSHypervisorDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.tags.ResourceTagVO;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.SSHKeyPair;
-import com.cloud.user.SSHKeyPairVO;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.SSHKeyPairDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.PasswordGenerator;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ComponentLifecycle;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.MacAddress;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.ssh.SSHKeysHelper;
-import com.cloud.vm.ConsoleProxyVO;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.InstanceGroupVO;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.VirtualMachineProfileImpl;
-import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.InstanceGroupDao;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-public class ManagementServerImpl extends ManagerBase implements ManagementServer, Configurable {
-    public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
-
-    static final ConfigKey<Integer> vmPasswordLength = new ConfigKey<Integer>("Advanced", Integer.class, "vm.password.length", "6",
-                                                                                      "Specifies the length of a randomly generated password", false);
-    static final ConfigKey<Integer> sshKeyLength = new ConfigKey<Integer>("Advanced", Integer.class, "ssh.key.length",
-            "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global);
-    @Inject
-    public AccountManager _accountMgr;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private AlertManager _alertMgr;
-    @Inject
-    private IPAddressDao _publicIpAddressDao;
-    @Inject
-    private ConsoleProxyDao _consoleProxyDao;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
-    public EventDao _eventDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private AccountVlanMapDao _accountVlanMapDao;
-    @Inject
-    private PodVlanMapDao _podVlanMapDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private HostDetailsDao _detailsDao;
-    @Inject
-    private UserDao _userDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private ConsoleProxyManager _consoleProxyMgr;
-    @Inject
-    private SecondaryStorageVmManager _secStorageVmMgr;
-    @Inject
-    private DiskOfferingDao _diskOfferingDao;
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    public AlertDao _alertDao;
-    @Inject
-    private CapacityDao _capacityDao;
-    @Inject
-    private GuestOSDao _guestOSDao;
-    @Inject
-    private GuestOSCategoryDao _guestOSCategoryDao;
-    @Inject
-    private GuestOSHypervisorDao _guestOSHypervisorDao;
-    @Inject
-    private PrimaryDataStoreDao _poolDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private StorageManager _storageMgr;
-    @Inject
-    private VolumeOrchestrationService _volumeMgr;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private HostPodDao _hostPodDao;
-    @Inject
-    private VMInstanceDao _vmInstanceDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    private int _purgeDelay;
-    private int _alertPurgeDelay;
-    @Inject
-    private InstanceGroupDao _vmGroupDao;
-    @Inject
-    protected SSHKeyPairDao _sshKeyPairDao;
-    @Inject
-    private LoadBalancerDao _loadbalancerDao;
-    @Inject
-    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    private List<HostAllocator> hostAllocators;
-    private List<StoragePoolAllocator> _storagePoolAllocators;
-    @Inject
-    private ResourceTagDao _resourceTagDao;
-    @Inject
-    private ImageStoreDao _imgStoreDao;
-    @Inject
-    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-    @Inject
-    private ProjectManager _projectMgr;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private HighAvailabilityManager _haMgr;
-    @Inject
-    private DataStoreManager dataStoreMgr;
-    @Inject
-    private HostTagsDao _hostTagsDao;
-    @Inject
-    private ConfigDepot _configDepot;
-    @Inject
-    private UserVmManager _userVmMgr;
-    @Inject
-    private AccountService _accountService;
-    @Inject
-    private ServiceOfferingDao _offeringDao;
-    @Inject
-    private DeploymentPlanningManager _dpMgr;
-    @Inject
-    private GuestOsDetailsDao _guestOsDetailsDao;
-
-    private LockMasterListener _lockMasterListener;
-    private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
-    private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));
-    @Inject
-    private KeystoreManager _ksMgr;
-
-    private Map<String, String> _configs;
-
-    private Map<String, Boolean> _availableIdsMap;
-
-    private List<UserAuthenticator> _userAuthenticators;
-    private List<UserAuthenticator> _userPasswordEncoders;
-    protected boolean _executeInSequence;
-
-    protected List<DeploymentPlanner> _planners;
-
-    private final List<HypervisorType> supportedHypervisors = new ArrayList<Hypervisor.HypervisorType>();
-
-    public List<DeploymentPlanner> getPlanners() {
-        return _planners;
-    }
-
-    public void setPlanners(final List<DeploymentPlanner> planners) {
-        _planners = planners;
-    }
-
-    @Inject
-    ClusterManager _clusterMgr;
-
-    @Inject
-    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
-
-    protected List<AffinityGroupProcessor> _affinityProcessors;
-
-    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
-        return _affinityProcessors;
-    }
-
-    public void setAffinityGroupProcessors(final List<AffinityGroupProcessor> affinityProcessors) {
-        _affinityProcessors = affinityProcessors;
-    }
-
-    public ManagementServerImpl() {
-        setRunLevel(ComponentLifecycle.RUN_LEVEL_APPLICATION_MAINLOOP);
-    }
-
-    public List<UserAuthenticator> getUserAuthenticators() {
-        return _userAuthenticators;
-    }
-
-    public void setUserAuthenticators(final List<UserAuthenticator> authenticators) {
-        _userAuthenticators = authenticators;
-    }
-
-    public List<UserAuthenticator> getUserPasswordEncoders() {
-        return _userPasswordEncoders;
-    }
-
-    public void setUserPasswordEncoders(final List<UserAuthenticator> encoders) {
-        _userPasswordEncoders = encoders;
-    }
-
-    public List<HostAllocator> getHostAllocators() {
-        return hostAllocators;
-    }
-
-    public void setHostAllocators(final List<HostAllocator> hostAllocators) {
-        this.hostAllocators = hostAllocators;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        _configs = _configDao.getConfiguration();
-
-        final String value = _configs.get("event.purge.interval");
-        final int cleanup = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
-
-        _purgeDelay = NumbersUtil.parseInt(_configs.get("event.purge.delay"), 0);
-        if (_purgeDelay != 0) {
-            _eventExecutor.scheduleAtFixedRate(new EventPurgeTask(), cleanup, cleanup, TimeUnit.SECONDS);
-        }
-
-        //Alerts purge configurations
-        final int alertPurgeInterval = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeInterval.key()), 60 * 60 * 24); // 1 day.
-        _alertPurgeDelay = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeDelay.key()), 0);
-        if (_alertPurgeDelay != 0) {
-            _alertExecutor.scheduleAtFixedRate(new AlertPurgeTask(), alertPurgeInterval, alertPurgeInterval, TimeUnit.SECONDS);
-        }
-
-        final String[] availableIds = TimeZone.getAvailableIDs();
-        _availableIdsMap = new HashMap<String, Boolean>(availableIds.length);
-        for (final String id : availableIds) {
-            _availableIdsMap.put(id, true);
-        }
-
-        supportedHypervisors.add(HypervisorType.KVM);
-        supportedHypervisors.add(HypervisorType.XenServer);
-
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        s_logger.info("Startup CloudStack management server...");
-
-        if (_lockMasterListener == null) {
-            _lockMasterListener = new LockMasterListener(ManagementServerNode.getManagementServerId());
-        }
-
-        _clusterMgr.registerListener(_lockMasterListener);
-
-        enableAdminUser("password");
-        return true;
-    }
-
-    protected Map<String, String> getConfigs() {
-        return _configs;
-    }
-
-    @Override
-    public String generateRandomPassword() {
-        final Integer passwordLength = vmPasswordLength.value();
-        return PasswordGenerator.generateRandomPassword(passwordLength);
-    }
-
-    @Override
-    public HostVO getHostBy(final long hostId) {
-        return _hostDao.findById(hostId);
-    }
-
-    @Override
-    public DetailVO findDetail(final long hostId, final String name) {
-        return _detailsDao.findDetail(hostId, name);
-    }
-
-    @Override
-    public long getId() {
-        return MacAddress.getMacAddress().toLong();
-    }
-
-    protected void checkPortParameters(final String publicPort, final String privatePort, final String privateIp, final String proto) {
-
-        if (!NetUtils.isValidPort(publicPort)) {
-            throw new InvalidParameterValueException("publicPort is an invalid value");
-        }
-        if (!NetUtils.isValidPort(privatePort)) {
-            throw new InvalidParameterValueException("privatePort is an invalid value");
-        }
-
-        // s_logger.debug("Checking if " + privateIp +
-        // " is a valid private IP address. Guest IP address is: " +
-        // _configs.get("guest.ip.network"));
-        //
-        // if (!NetUtils.isValidPrivateIp(privateIp,
-        // _configs.get("guest.ip.network"))) {
-        // throw new
-        // InvalidParameterValueException("Invalid private ip address");
-        // }
-        if (!NetUtils.isValidProto(proto)) {
-            throw new InvalidParameterValueException("Invalid protocol");
-        }
-    }
-
-    @Override
-    public boolean archiveEvents(final ArchiveEventsCmd cmd) {
-        final Account caller = getCaller();
-        final List<Long> ids = cmd.getIds();
-        boolean result = true;
-        List<Long> permittedAccountIds = new ArrayList<Long>();
-
-        if (_accountService.isNormalUser(caller.getId()) || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            permittedAccountIds.add(caller.getId());
-        } else {
-            final DomainVO domain = _domainDao.findById(caller.getDomainId());
-            final List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
-            permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
-        }
-
-        final List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds);
-        final ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents);
-
-        if (ids != null && events.size() < ids.size()) {
-            result = false;
-            return result;
-        }
-        _eventDao.archiveEvents(events);
-        return result;
-    }
-
-    @Override
-    public boolean deleteEvents(final DeleteEventsCmd cmd) {
-        final Account caller = getCaller();
-        final List<Long> ids = cmd.getIds();
-        boolean result = true;
-        List<Long> permittedAccountIds = new ArrayList<Long>();
-
-        if (_accountMgr.isNormalUser(caller.getId()) || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            permittedAccountIds.add(caller.getId());
-        } else {
-            final DomainVO domain = _domainDao.findById(caller.getDomainId());
-            final List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
-            permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
-        }
-
-        final List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds);
-        final ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents);
-
-        if (ids != null && events.size() < ids.size()) {
-            result = false;
-            return result;
-        }
-        for (final EventVO event : events) {
-            _eventDao.remove(event.getId());
-        }
-        return result;
-    }
-
-    @Override
-    public List<? extends Cluster> searchForClusters(long zoneId, final Long startIndex, final Long pageSizeVal, final String hypervisorType) {
-        final Filter searchFilter = new Filter(ClusterVO.class, "id", true, startIndex, pageSizeVal);
-        final SearchCriteria<ClusterVO> sc = _clusterDao.createSearchCriteria();
-
-        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
-
-        sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisorType);
-
-        return _clusterDao.search(sc, searchFilter);
-    }
-
-    @Override
-    public Pair<List<? extends Cluster>, Integer> searchForClusters(final ListClustersCmd cmd) {
-        final Object id = cmd.getId();
-        final Object name = cmd.getClusterName();
-        final Object podId = cmd.getPodId();
-        Long zoneId = cmd.getZoneId();
-        final Object hypervisorType = cmd.getHypervisorType();
-        final Object clusterType = cmd.getClusterType();
-        final Object allocationState = cmd.getAllocationState();
-        final String keyword = cmd.getKeyword();
-        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
-
-        final Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        final SearchBuilder<ClusterVO> sb = _clusterDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ);
-        sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ);
-
-        final SearchCriteria<ClusterVO> sc = sb.create();
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-
-        if (podId != null) {
-            sc.setParameters("podId", podId);
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-
-        if (hypervisorType != null) {
-            sc.setParameters("hypervisorType", hypervisorType);
-        }
-
-        if (clusterType != null) {
-            sc.setParameters("clusterType", clusterType);
-        }
-
-        if (allocationState != null) {
-            sc.setParameters("allocationState", allocationState);
-        }
-
-        if (keyword != null) {
-            final SearchCriteria<ClusterVO> ssc = _clusterDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("hypervisorType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        final Pair<List<ClusterVO>, Integer> result = _clusterDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends Cluster>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends Host>, Integer> searchForServers(final ListHostsCmd cmd) {
-
-        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        final Object name = cmd.getHostName();
-        final Object type = cmd.getType();
-        final Object state = cmd.getState();
-        final Object pod = cmd.getPodId();
-        final Object cluster = cmd.getClusterId();
-        final Object id = cmd.getId();
-        final Object keyword = cmd.getKeyword();
-        final Object resourceState = cmd.getResourceState();
-        final Object haHosts = cmd.getHaHost();
-
-        final Pair<List<HostVO>, Integer> result = searchForServers(cmd.getStartIndex(), cmd.getPageSizeVal(), name, type, state, zoneId, pod, cluster, id, keyword, resourceState,
-                haHosts, null, null);
-        return new Pair<List<? extends Host>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>
-                            listHostsForMigrationOfVM(final Long vmId,
-                                                      final Long startIndex,
-                                                      final Long pageSize, final String keyword) {
-        final Account caller = getCaller();
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
-            }
-            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
-        }
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the VM with given id");
-            throw ex;
-        }
-
-        if (vm.getState() != State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not running, cannot migrate the vm" + vm);
-            }
-            final InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, cannot " + "migrate the vm with specified id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        if(_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
-            s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName()+ " is not supported");
-            // Return empty list.
-            return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(new Pair<List <? extends Host>,
-                    Integer>(new ArrayList<HostVO>(), new Integer(0)), new ArrayList<Host>(), new HashMap<Host, Boolean>());
-        }
-
-        if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
-                && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.LXC)
-                && !vm.getHypervisorType().equals(HypervisorType.Simulator) && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
-            }
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
-        }
-
-        if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
-        }
-
-        final long srcHostId = vm.getHostId();
-        final Host srcHost = _hostDao.findById(srcHostId);
-        if (srcHost == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find the host with id: " + srcHostId + " of this VM:" + vm);
-            }
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the host (with specified id) of VM with specified id");
-            ex.addProxyObject(String.valueOf(srcHostId), "hostId");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        // Check if the vm can be migrated with storage.
-        boolean canMigrateWithStorage = false;
-
-        if (vm.getType() == VirtualMachine.Type.User) {
-            final HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
-            if (capabilities != null) {
-                canMigrateWithStorage = capabilities.isStorageMotionSupported();
-            }
-        }
-
-        // Check if the vm is using any disks on local storage.
-        final VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null);
-        final List<VolumeVO> volumes = _volumeDao.findCreatedByInstance(vmProfile.getId());
-        boolean usesLocal = false;
-        for (final VolumeVO volume : volumes) {
-            final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-            final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType());
-            if (diskProfile.useLocalStorage()) {
-                usesLocal = true;
-                break;
-            }
-        }
-
-        if (!canMigrateWithStorage && usesLocal) {
-            throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate");
-        }
-
-        final Type hostType = srcHost.getType();
-        Pair<List<HostVO>, Integer> allHostsPair = null;
-        List<HostVO> allHosts = null;
-        final Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, Boolean>();
-        DataCenterDeployment plan = null;
-        if (canMigrateWithStorage) {
-            allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), null, null, null, keyword, null, null,
-                    srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
-            allHosts = allHostsPair.first();
-            allHosts.remove(srcHost);
-
-            for (final VolumeVO volume : volumes) {
-                final StoragePool storagePool = _poolDao.findById(volume.getPoolId());
-                final Long volClusterId = storagePool.getClusterId();
-
-                for (final Iterator<HostVO> iterator = allHosts.iterator(); iterator.hasNext();) {
-                    final Host host = iterator.next();
-
-                    if (volClusterId != null) {
-                        if (!host.getClusterId().equals(volClusterId) || usesLocal) {
-                            if (storagePool.isManaged()) {
-                                // At the time being, we do not support storage migration of a volume from managed storage unless the managed storage
-                                // is at the zone level and the source and target storage pool is the same.
-                                // If the source and target storage pool is the same and it is managed, then we still have to perform a storage migration
-                                // because we need to create a new target volume and copy the contents of the source volume into it before deleting the
-                                // source volume.
-                                iterator.remove();
-                            }
-                            else {
-                                if (hasSuitablePoolsForVolume(volume, host, vmProfile)) {
-                                    requiresStorageMotion.put(host, true);
-                                } else {
-                                    iterator.remove();
-                                }
-                            }
-                        }
-                    }
-                    else {
-                        if (storagePool.isManaged()) {
-                            if (srcHost.getClusterId() != host.getClusterId()) {
-                                // If the volume's storage pool is managed and at the zone level, then we still have to perform a storage migration
-                                // because we need to create a new target volume and copy the contents of the source volume into it before deleting
-                                // the source volume.
-                                requiresStorageMotion.put(host, true);
-                            }
-                        }
-                    }
-                }
-            }
-
-            plan = new DataCenterDeployment(srcHost.getDataCenterId(), null, null, null, null, null);
-        } else {
-            final Long cluster = srcHost.getClusterId();
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Searching for all hosts in cluster " + cluster + " for migrating VM " + vm);
-            }
-            allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, null, null, cluster, null, keyword, null, null, null, null);
-            // Filter out the current host.
-            allHosts = allHostsPair.first();
-            allHosts.remove(srcHost);
-            plan = new DataCenterDeployment(srcHost.getDataCenterId(), srcHost.getPodId(), srcHost.getClusterId(), null, null, null);
-        }
-
-        final Pair<List<? extends Host>, Integer> otherHosts = new Pair<List<? extends Host>, Integer>(allHosts, new Integer(allHosts.size()));
-        List<Host> suitableHosts = new ArrayList<Host>();
-        final ExcludeList excludes = new ExcludeList();
-        excludes.addHost(srcHostId);
-
-        // call affinitygroup chain
-        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
-
-        if (vmGroupCount > 0) {
-            for (final AffinityGroupProcessor processor : _affinityProcessors) {
-                processor.process(vmProfile, plan, excludes);
-            }
-        }
-
-        for (final HostAllocator allocator : hostAllocators) {
-            if (canMigrateWithStorage) {
-                suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, allHosts, HostAllocator.RETURN_UPTO_ALL, false);
-            } else {
-                suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
-            }
-
-            if (suitableHosts != null && !suitableHosts.isEmpty()) {
-                break;
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            if (suitableHosts.isEmpty()) {
-                s_logger.debug("No suitable hosts found");
-            } else {
-                s_logger.debug("Hosts having capacity and suitable for migration: " + suitableHosts);
-            }
-        }
-
-        return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(otherHosts, suitableHosts, requiresStorageMotion);
-    }
-
-    private boolean hasSuitablePoolsForVolume(final VolumeVO volume, final Host host, final VirtualMachineProfile vmProfile) {
-        final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-        final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType());
-        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null);
-        final ExcludeList avoid = new ExcludeList();
-
-        for (final StoragePoolAllocator allocator : _storagePoolAllocators) {
-            final List<StoragePool> poolList = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, 1);
-            if (poolList != null && !poolList.isEmpty()) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
-        final Account caller = getCaller();
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Caller is not a root admin, permission denied to migrate the volume");
-            }
-            throw new PermissionDeniedException("No permission to migrate volume, only root admin can migrate a volume");
-        }
-
-        final VolumeVO volume = _volumeDao.findById(volumeId);
-        if (volume == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with" + " specified id.");
-            ex.addProxyObject(volumeId.toString(), "volumeId");
-            throw ex;
-        }
-
-        // Volume must be attached to an instance for live migration.
-        final List<StoragePool> allPools = new ArrayList<StoragePool>();
-        final List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        // Volume must be in Ready state to be migrated.
-        if (!Volume.State.Ready.equals(volume.getState())) {
-            s_logger.info("Volume " + volume + " must be in ready state for migration.");
-            return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
-        }
-
-        if (!_volumeMgr.volumeOnSharedStoragePool(volume)) {
-            s_logger.info("Volume " + volume + " is on local storage. It cannot be migrated to another pool.");
-            return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
-        }
-
-        final Long instanceId = volume.getInstanceId();
-        VMInstanceVO vm = null;
-        if (instanceId != null) {
-            vm = _vmInstanceDao.findById(instanceId);
-        }
-
-        if (vm == null) {
-            s_logger.info("Volume " + volume + " isn't attached to any vm. Looking for storage pools in the " + "zone to which this volumes can be migrated.");
-        } else if (vm.getState() != State.Running) {
-            s_logger.info("Volume " + volume + " isn't attached to any running vm. Looking for storage pools in the " + "cluster to which this volumes can be migrated.");
-        } else {
-            s_logger.info("Volume " + volume + " is attached to any running vm. Looking for storage pools in the " + "cluster to which this volumes can be migrated.");
-            boolean storageMotionSupported = false;
-            // Check if the underlying hypervisor supports storage motion.
-            final Long hostId = vm.getHostId();
-            if (hostId != null) {
-                final HostVO host = _hostDao.findById(hostId);
-                HypervisorCapabilitiesVO capabilities = null;
-                if (host != null) {
-                    capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(host.getHypervisorType(), host.getHypervisorVersion());
-                } else {
-                    s_logger.error("Details of the host on which the vm " + vm + ", to which volume " + volume + " is " + "attached, couldn't be retrieved.");
-                }
-
-                if (capabilities != null) {
-                    storageMotionSupported = capabilities.isStorageMotionSupported();
-                } else {
-                    s_logger.error("Capabilities for host " + host + " couldn't be retrieved.");
-                }
-            }
-
-            if (!storageMotionSupported) {
-                s_logger.info("Volume " + volume + " is attached to a running vm and the hypervisor doesn't support" + " storage motion.");
-                return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
-            }
-        }
-
-        // Source pool of the volume.
-        final StoragePoolVO srcVolumePool = _poolDao.findById(volume.getPoolId());
-        // Get all the pools available. Only shared pools are considered because only a volume on a shared pools
-        // can be live migrated while the virtual machine stays on the same host.
-
-        List<StoragePoolVO> storagePools;
-
-        if (srcVolumePool.getClusterId() != null) {
-            storagePools = _poolDao.findPoolsByTags(volume.getDataCenterId(), srcVolumePool.getPodId(), srcVolumePool.getClusterId(), null);
-        }
-        else {
-            storagePools = new ArrayList<>();
-        }
-
-        List<StoragePoolVO> zoneWideStoragePools = _poolDao.findZoneWideStoragePoolsByTags(volume.getDataCenterId(), null);
-
-        storagePools.addAll(zoneWideStoragePools);
-
-        storagePools.remove(srcVolumePool);
-        for (final StoragePoolVO pool : storagePools) {
-            if (pool.isShared()) {
-                allPools.add((StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId()));
-            }
-        }
-
-        // Get all the suitable pools.
-        // Exclude the current pool from the list of pools to which the volume can be migrated.
-        final ExcludeList avoid = new ExcludeList();
-        avoid.addPool(srcVolumePool.getId());
-
-        // Volume stays in the same cluster after migration.
-        final DataCenterDeployment plan = new DataCenterDeployment(volume.getDataCenterId(), srcVolumePool.getPodId(), srcVolumePool.getClusterId(), null, null, null);
-        final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-
-        final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-        final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, profile.getHypervisorType());
-
-        // Call the storage pool allocator to find the list of storage pools.
-        for (final StoragePoolAllocator allocator : _storagePoolAllocators) {
-            final List<StoragePool> pools = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
-            if (pools != null && !pools.isEmpty()) {
-                suitablePools.addAll(pools);
-                break;
-            }
-        }
-
-        return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
-    }
-
-    private Pair<List<HostVO>, Integer> searchForServers(final Long startIndex, final Long pageSize, final Object name, final Object type, final Object state, final Object zone, final Object pod, final Object cluster,
-            final Object id, final Object keyword, final Object resourceState, final Object haHosts, final Object hypervisorType, final Object hypervisorVersion) {
-        final Filter searchFilter = new Filter(HostVO.class, "id", Boolean.TRUE, startIndex, pageSize);
-
-        final SearchBuilder<HostVO> sb = _hostDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
-        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
-        sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
-        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        sb.and("hypervisorVersion", sb.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ);
-
-        final String haTag = _haMgr.getHaTag();
-        SearchBuilder<HostTagVO> hostTagSearch = null;
-        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
-            hostTagSearch = _hostTagsDao.createSearchBuilder();
-            if ((Boolean)haHosts) {
-                hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.EQ);
-            } else {
-                hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
-                hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
-            }
-
-            hostTagSearch.cp();
-            sb.join("hostTagSearch", hostTagSearch, sb.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
-        }
-
-        final SearchCriteria<HostVO> sc = sb.create();
-
-        if (keyword != null) {
-            final SearchCriteria<HostVO> ssc = _hostDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("name", "%" + name + "%");
-        }
-        if (type != null) {
-            sc.setParameters("type", "%" + type);
-        }
-        if (state != null) {
-            sc.setParameters("status", state);
-        }
-        if (zone != null) {
-            sc.setParameters("dataCenterId", zone);
-        }
-        if (pod != null) {
-            sc.setParameters("podId", pod);
-        }
-        if (cluster != null) {
-            sc.setParameters("clusterId", cluster);
-        }
-        if (hypervisorType != null) {
-            sc.setParameters("hypervisorType", hypervisorType);
-        }
-        if (hypervisorVersion != null) {
-            sc.setParameters("hypervisorVersion", hypervisorVersion);
-        }
-
-        if (resourceState != null) {
-            sc.setParameters("resourceState", resourceState);
-        }
-
-        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
-            sc.setJoinParameters("hostTagSearch", "tag", haTag);
-        }
-
-        return _hostDao.searchAndCount(sc, searchFilter);
-    }
-
-    @Override
-    public Pair<List<? extends Pod>, Integer> searchForPods(final ListPodsByCmd cmd) {
-        final String podName = cmd.getPodName();
-        final Long id = cmd.getId();
-        Long zoneId = cmd.getZoneId();
-        final Object keyword = cmd.getKeyword();
-        final Object allocationState = cmd.getAllocationState();
-        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
-
-        final Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchBuilder<HostPodVO> sb = _hostPodDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ);
-
-        final SearchCriteria<HostPodVO> sc = sb.create();
-        if (keyword != null) {
-            final SearchCriteria<HostPodVO> ssc = _hostPodDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (podName != null) {
-            sc.setParameters("name", "%" + podName + "%");
-        }
-
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-
-        if (allocationState != null) {
-            sc.setParameters("allocationState", allocationState);
-        }
-
-        final Pair<List<HostPodVO>, Integer> result = _hostPodDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends Pod>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends Vlan>, Integer> searchForVlans(final ListVlanIpRangesCmd cmd) {
-        // If an account name and domain ID are specified, look up the account
-        final String accountName = cmd.getAccountName();
-        final Long domainId = cmd.getDomainId();
-        Long accountId = null;
-        final Long networkId = cmd.getNetworkId();
-        final Boolean forVirtual = cmd.getForVirtualNetwork();
-        String vlanType = null;
-        final Long projectId = cmd.getProjectId();
-        final Long physicalNetworkId = cmd.getPhysicalNetworkId();
-
-        if (accountName != null && domainId != null) {
-            if (projectId != null) {
-                throw new InvalidParameterValueException("Account and projectId can't be specified together");
-            }
-            final Account account = _accountDao.findActiveAccount(accountName, domainId);
-            if (account == null) {
-                final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain");
-                // Since we don't have a DomainVO object here, we directly set
-                // tablename to "domain".
-                final DomainVO domain = ApiDBUtils.findDomainById(domainId);
-                String domainUuid = domainId.toString();
-                if (domain != null) {
-                    domainUuid = domain.getUuid();
-                }
-                ex.addProxyObject(domainUuid, "domainId");
-                throw ex;
-            } else {
-                accountId = account.getId();
-            }
-        }
-
-        if (forVirtual != null) {
-            if (forVirtual) {
-                vlanType = VlanType.VirtualNetwork.toString();
-            } else {
-                vlanType = VlanType.DirectAttached.toString();
-            }
-        }
-
-        // set project information
-        if (projectId != null) {
-            final Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by id " + projectId);
-                ex.addProxyObject(projectId.toString(), "projectId");
-                throw ex;
-            }
-            accountId = project.getProjectAccountId();
-        }
-
-        final Filter searchFilter = new Filter(VlanVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        final Object id = cmd.getId();
-        final Object vlan = cmd.getVlan();
-        final Object dataCenterId = cmd.getZoneId();
-        final Object podId = cmd.getPodId();
-        final Object keyword = cmd.getKeyword();
-
-        final SearchBuilder<VlanVO> sb = _vlanDao.createSearchBuilder();
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("vlan", sb.entity().getVlanTag(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("vlan", sb.entity().getVlanTag(), SearchCriteria.Op.EQ);
-        sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
-        sb.and("vlanType", sb.entity().getVlanType(), SearchCriteria.Op.EQ);
-        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
-
-        if (accountId != null) {
-            final SearchBuilder<AccountVlanMapVO> accountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
-            accountVlanMapSearch.and("accountId", accountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
-            sb.join("accountVlanMapSearch", accountVlanMapSearch, sb.entity().getId(), accountVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.INNER);
-        }
-
-        if (podId != null) {
-            final SearchBuilder<PodVlanMapVO> podVlanMapSearch = _podVlanMapDao.createSearchBuilder();
-            podVlanMapSearch.and("podId", podVlanMapSearch.entity().getPodId(), SearchCriteria.Op.EQ);
-            sb.join("podVlanMapSearch", podVlanMapSearch, sb.entity().getId(), podVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<VlanVO> sc = sb.create();
-        if (keyword != null) {
-            final SearchCriteria<VlanVO> ssc = _vlanDao.createSearchCriteria();
-            ssc.addOr("vlanTag", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("ipRange", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("vlanTag", SearchCriteria.Op.SC, ssc);
-        } else {
-            if (id != null) {
-                sc.setParameters("id", id);
-            }
-
-            if (vlan != null) {
-                sc.setParameters("vlan", vlan);
-            }
-
-            if (dataCenterId != null) {
-                sc.setParameters("dataCenterId", dataCenterId);
-            }
-
-            if (networkId != null) {
-                sc.setParameters("networkId", networkId);
-            }
-
-            if (accountId != null) {
-                sc.setJoinParameters("accountVlanMapSearch", "accountId", accountId);
-            }
-
-            if (podId != null) {
-                sc.setJoinParameters("podVlanMapSearch", "podId", podId);
-            }
-            if (vlanType != null) {
-                sc.setParameters("vlanType", vlanType);
-            }
-
-            if (physicalNetworkId != null) {
-                sc.setParameters("physicalNetworkId", physicalNetworkId);
-            }
-        }
-
-        final Pair<List<VlanVO>, Integer> result = _vlanDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends Vlan>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends Configuration>, Integer> searchForConfigurations(final ListCfgsByCmd cmd) {
-        final Filter searchFilter = new Filter(ConfigurationVO.class, "name", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchCriteria<ConfigurationVO> sc = _configDao.createSearchCriteria();
-
-        final Object name = cmd.getConfigName();
-        final Object category = cmd.getCategory();
-        final Object keyword = cmd.getKeyword();
-        final Long zoneId = cmd.getZoneId();
-        final Long clusterId = cmd.getClusterId();
-        final Long storagepoolId = cmd.getStoragepoolId();
-        final Long accountId = cmd.getAccountId();
-        final Long domainId = cmd.getDomainId();
-        final Long imageStoreId = cmd.getImageStoreId();
-        String scope = null;
-        Long id = null;
-        int paramCountCheck = 0;
-
-        if (zoneId != null) {
-            scope = ConfigKey.Scope.Zone.toString();
-            id = zoneId;
-            paramCountCheck++;
-        }
-        if (clusterId != null) {
-            scope = ConfigKey.Scope.Cluster.toString();
-            id = clusterId;
-            paramCountCheck++;
-        }
-        if (accountId != null) {
-            scope = ConfigKey.Scope.Account.toString();
-            id = accountId;
-            paramCountCheck++;
-        }
-        if (domainId != null) {
-            scope = ConfigKey.Scope.Domain.toString();
-            id = domainId;
-            paramCountCheck++;
-        }
-        if (storagepoolId != null) {
-            scope = ConfigKey.Scope.StoragePool.toString();
-            id = storagepoolId;
-            paramCountCheck++;
-        }
-        if (imageStoreId != null) {
-            scope = ConfigKey.Scope.ImageStore.toString();
-            id = imageStoreId;
-            paramCountCheck++;
-        }
-
-        if (paramCountCheck > 1) {
-            throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
-        }
-
-        if (keyword != null) {
-            final SearchCriteria<ConfigurationVO> ssc = _configDao.createSearchCriteria();
-            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("instance", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("component", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("category", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("value", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-        }
-
-        if (category != null) {
-            sc.addAnd("category", SearchCriteria.Op.EQ, category);
-        }
-
-        // hidden configurations are not displayed using the search API
-        sc.addAnd("category", SearchCriteria.Op.NEQ, "Hidden");
-
-        if (scope != null && !scope.isEmpty()) {
-            // getting the list of parameters at requested scope
-            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
-        }
-
-        final Pair<List<ConfigurationVO>, Integer> result = _configDao.searchAndCount(sc, searchFilter);
-
-        if (scope != null && !scope.isEmpty()) {
-            // Populate values corresponding the resource id
-            final List<ConfigurationVO> configVOList = new ArrayList<ConfigurationVO>();
-            for (final ConfigurationVO param : result.first()) {
-                final ConfigurationVO configVo = _configDao.findByName(param.getName());
-                if (configVo != null) {
-                    final ConfigKey<?> key = _configDepot.get(param.getName());
-                    if (key != null) {
-                        configVo.setValue(key.valueIn(id) == null ? null : key.valueIn(id).toString());
-                        configVOList.add(configVo);
-                    } else {
-                        s_logger.warn("ConfigDepot could not find parameter " + param.getName() + " for scope " + scope);
-                    }
-                } else {
-                    s_logger.warn("Configuration item  " + param.getName() + " not found in " + scope);
-                }
-            }
-
-            return new Pair<List<? extends Configuration>, Integer>(configVOList, configVOList.size());
-        }
-
-        return new Pair<List<? extends Configuration>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends IpAddress>, Integer> searchForIPAddresses(final ListPublicIpAddressesCmd cmd) {
-        final Object keyword = cmd.getKeyword();
-        final Long physicalNetworkId = cmd.getPhysicalNetworkId();
-        final Long associatedNetworkId = cmd.getAssociatedNetworkId();
-        final Long zone = cmd.getZoneId();
-        final String address = cmd.getIpAddress();
-        final Long vlan = cmd.getVlanId();
-        final Boolean forVirtualNetwork = cmd.isForVirtualNetwork();
-        final Boolean forLoadBalancing = cmd.isForLoadBalancing();
-        final Long ipId = cmd.getId();
-        final Boolean sourceNat = cmd.getIsSourceNat();
-        final Boolean staticNat = cmd.getIsStaticNat();
-        final Long vpcId = cmd.getVpcId();
-        final Boolean forDisplay = cmd.getDisplay();
-        final Map<String, String> tags = cmd.getTags();
-
-        final String state = cmd.getState();
-        Boolean isAllocated = cmd.isAllocatedOnly();
-        if (isAllocated == null) {
-            isAllocated = Boolean.TRUE;
-
-            if (state != null) {
-                isAllocated = Boolean.FALSE;
-            }
-        }
-
-        final Filter searchFilter = new Filter(IPAddressVO.class, "address", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchBuilder<IPAddressVO> sb = _publicIpAddressDao.createSearchBuilder();
-        Long domainId = null;
-        Boolean isRecursive = null;
-        final List<Long> permittedAccounts = new ArrayList<Long>();
-        ListProjectResourcesCriteria listProjectResourcesCriteria = null;
-        if (isAllocated) {
-            final Account caller = getCaller();
-
-            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
-                    cmd.getDomainId(), cmd.isRecursive(), null);
-            _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
-                    domainIdRecursiveListProject, cmd.listAll(), false);
-            domainId = domainIdRecursiveListProject.first();
-            isRecursive = domainIdRecursiveListProject.second();
-            listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-            _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        }
-
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("address", sb.entity().getAddress(), SearchCriteria.Op.EQ);
-        sb.and("vlanDbId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
-        sb.and("associatedNetworkIdEq", sb.entity().getAssociatedWithNetworkId(), SearchCriteria.Op.EQ);
-        sb.and("isSourceNat", sb.entity().isSourceNat(), SearchCriteria.Op.EQ);
-        sb.and("isStaticNat", sb.entity().isOneToOneNat(), SearchCriteria.Op.EQ);
-        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
-
-        if (forLoadBalancing != null && forLoadBalancing) {
-            final SearchBuilder<LoadBalancerVO> lbSearch = _loadbalancerDao.createSearchBuilder();
-            sb.join("lbSearch", lbSearch, sb.entity().getId(), lbSearch.entity().getSourceIpAddressId(), JoinType.INNER);
-            sb.groupBy(sb.entity().getId());
-        }
-
-        if (keyword != null && address == null) {
-            sb.and("addressLIKE", sb.entity().getAddress(), SearchCriteria.Op.LIKE);
-        }
-
-        if (tags != null && !tags.isEmpty()) {
-            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
-            for (int count = 0; count < tags.size(); count++) {
-                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
-                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
-                tagSearch.cp();
-            }
-            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
-            sb.groupBy(sb.entity().getId());
-            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
-        vlanSearch.and("vlanType", vlanSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
-        sb.join("vlanSearch", vlanSearch, sb.entity().getVlanId(), vlanSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-
-        boolean allocatedOnly = false;
-        if (isAllocated != null && isAllocated == true) {
-            sb.and("allocated", sb.entity().getAllocatedTime(), SearchCriteria.Op.NNULL);
-            allocatedOnly = true;
-        }
-
-        VlanType vlanType = null;
-        if (forVirtualNetwork != null) {
-            vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached;
-        } else {
-            vlanType = VlanType.VirtualNetwork;
-        }
-
-        final SearchCriteria<IPAddressVO> sc = sb.create();
-        if (isAllocated) {
-            _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        }
-
-        sc.setJoinParameters("vlanSearch", "vlanType", vlanType);
-
-        if (tags != null && !tags.isEmpty()) {
-            int count = 0;
-            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PublicIpAddress.toString());
-            for (final String key : tags.keySet()) {
-                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
-                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
-                count++;
-            }
-        }
-
-        if (zone != null) {
-            sc.setParameters("dataCenterId", zone);
-        }
-
-        if (vpcId != null) {
-            sc.setParameters("vpcId", vpcId);
-        }
-
-        if (ipId != null) {
-            sc.setParameters("id", ipId);
-        }
-
-        if (sourceNat != null) {
-            sc.setParameters("isSourceNat", sourceNat);
-        }
-
-        if (staticNat != null) {
-            sc.setParameters("isStaticNat", staticNat);
-        }
-
-        if (address == null && keyword != null) {
-            sc.setParameters("addressLIKE", "%" + keyword + "%");
-        }
-
-        if (address != null) {
-            sc.setParameters("address", address);
-        }
-
-        if (vlan != null) {
-            sc.setParameters("vlanDbId", vlan);
-        }
-
-        if (physicalNetworkId != null) {
-            sc.setParameters("physicalNetworkId", physicalNetworkId);
-        }
-
-        if (associatedNetworkId != null) {
-            sc.setParameters("associatedNetworkIdEq", associatedNetworkId);
-        }
-
-        if (forDisplay != null) {
-            sc.setParameters("display", forDisplay);
-        }
-
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-
-        final Pair<List<IPAddressVO>, Integer> result = _publicIpAddressDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends IpAddress>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(final ListGuestOsCmd cmd) {
-        final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final Long id = cmd.getId();
-        final Long osCategoryId = cmd.getOsCategoryId();
-        final String description = cmd.getDescription();
-        final String keyword = cmd.getKeyword();
-
-        final SearchCriteria<GuestOSVO> sc = _guestOSDao.createSearchCriteria();
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (osCategoryId != null) {
-            sc.addAnd("categoryId", SearchCriteria.Op.EQ, osCategoryId);
-        }
-
-        if (description != null) {
-            sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + description + "%");
-        }
-
-        if (keyword != null) {
-            sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-        }
-
-        final Pair<List<GuestOSVO>, Integer> result = _guestOSDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends GuestOS>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends GuestOsCategory>, Integer> listGuestOSCategoriesByCriteria(final ListGuestOsCategoriesCmd cmd) {
-        final Filter searchFilter = new Filter(GuestOSCategoryVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final Long id = cmd.getId();
-        final String name = cmd.getName();
-        final String keyword = cmd.getKeyword();
-
-        final SearchCriteria<GuestOSCategoryVO> sc = _guestOSCategoryDao.createSearchCriteria();
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
-        }
-
-        if (keyword != null) {
-            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-        }
-
-        final Pair<List<GuestOSCategoryVO>, Integer> result = _guestOSCategoryDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends GuestOsCategory>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public Pair<List<? extends GuestOSHypervisor>, Integer> listGuestOSMappingByCriteria(final ListGuestOsMappingCmd cmd) {
-        final Filter searchFilter = new Filter(GuestOSHypervisorVO.class, "hypervisorType", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final Long id = cmd.getId();
-        final Long osTypeId = cmd.getOsTypeId();
-        final String hypervisor = cmd.getHypervisor();
-        final String hypervisorVersion = cmd.getHypervisorVersion();
-
-        //throw exception if hypervisor name is not passed, but version is
-        if (hypervisorVersion != null && (hypervisor == null || hypervisor.isEmpty())) {
-            throw new InvalidParameterValueException("Hypervisor version parameter cannot be used without specifying a hypervisor : XenServer, KVM or VMware");
-        }
-
-        final SearchCriteria<GuestOSHypervisorVO> sc = _guestOSHypervisorDao.createSearchCriteria();
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (osTypeId != null) {
-            sc.addAnd("guestOsId", SearchCriteria.Op.EQ, osTypeId);
-        }
-
-        if (hypervisor != null) {
-            sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisor);
-        }
-
-        if (hypervisorVersion != null) {
-            sc.addAnd("hypervisorVersion", SearchCriteria.Op.EQ, hypervisorVersion);
-        }
-
-        final Pair<List<GuestOSHypervisorVO>, Integer> result = _guestOSHypervisorDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends GuestOSHypervisor>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding new guest OS to hypervisor name mapping", create = true)
-    public GuestOSHypervisor addGuestOsMapping(final AddGuestOsMappingCmd cmd) {
-        final Long osTypeId = cmd.getOsTypeId();
-        final String osStdName = cmd.getOsStdName();
-        final String hypervisor = cmd.getHypervisor();
-        final String hypervisorVersion = cmd.getHypervisorVersion();
-        final String osNameForHypervisor = cmd.getOsNameForHypervisor();
-        GuestOS guestOs = null;
-
-        if (osTypeId == null && (osStdName == null || osStdName.isEmpty())) {
-            throw new InvalidParameterValueException("Please specify either a guest OS name or UUID");
-        }
-
-        final HypervisorType hypervisorType = HypervisorType.getType(hypervisor);
-
-        if (!(hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.XenServer || hypervisorType == HypervisorType.VMware)) {
-            throw new InvalidParameterValueException("Please specify a valid hypervisor : XenServer, KVM or VMware");
-        }
-
-        final HypervisorCapabilitiesVO hypervisorCapabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
-        if (hypervisorCapabilities == null) {
-            throw new InvalidParameterValueException("Please specify a valid hypervisor and supported version");
-        }
-
-        //by this point either osTypeId or osStdType is non-empty. Find by either of them. ID takes preference if both are specified
-        if (osTypeId != null) {
-            guestOs = ApiDBUtils.findGuestOSById(osTypeId);
-        }
-        else if (osStdName != null) {
-            guestOs = ApiDBUtils.findGuestOSByDisplayName(osStdName);
-        }
-
-        if (guestOs == null) {
-            throw new InvalidParameterValueException("Unable to find the guest OS by name or UUID");
-        }
-        //check for duplicates
-        final GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisorAndUserDefined(guestOs.getId(), hypervisorType.toString(), hypervisorVersion, true);
-
-        if (duplicate != null) {
-            throw new InvalidParameterValueException("Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : "
-                    + guestOs.getDisplayName() + " already exists!");
-        }
-        final GuestOSHypervisorVO guestOsMapping = new GuestOSHypervisorVO();
-        guestOsMapping.setGuestOsId(guestOs.getId());
-        guestOsMapping.setGuestOsName(osNameForHypervisor);
-        guestOsMapping.setHypervisorType(hypervisorType.toString());
-        guestOsMapping.setHypervisorVersion(hypervisorVersion);
-        guestOsMapping.setIsUserDefined(true);
-        return _guestOSHypervisorDao.persist(guestOsMapping);
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding a new guest OS to hypervisor name mapping", async = true)
-    public GuestOSHypervisor getAddedGuestOsMapping(final Long guestOsMappingId) {
-        return getGuestOsHypervisor(guestOsMappingId);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding new guest OS type", create = true)
-    public GuestOS addGuestOs(final AddGuestOsCmd cmd) {
-        final Long categoryId = cmd.getOsCategoryId();
-        final String displayName = cmd.getOsDisplayName();
-        final String name = cmd.getOsName();
-
-        final GuestOSCategoryVO guestOsCategory = ApiDBUtils.findGuestOsCategoryById(categoryId);
-        if (guestOsCategory == null) {
-            throw new InvalidParameterValueException("Guest OS category not found. Please specify a valid Guest OS category");
-        }
-
-        final GuestOS guestOs = ApiDBUtils.findGuestOSByDisplayName(displayName);
-        if (guestOs != null) {
-            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique name");
-        }
-
-        s_logger.debug("GuestOSDetails");
-        final GuestOSVO guestOsVo = new GuestOSVO();
-        guestOsVo.setCategoryId(categoryId.longValue());
-        guestOsVo.setDisplayName(displayName);
-        guestOsVo.setName(name);
-        guestOsVo.setIsUserDefined(true);
-        final GuestOS guestOsPersisted = _guestOSDao.persist(guestOsVo);
-
-        if(cmd.getDetails() != null && !cmd.getDetails().isEmpty()){
-            Map<String, String> detailsMap = cmd.getDetails();
-            for(Object key: detailsMap.keySet()){
-                _guestOsDetailsDao.addDetail(guestOsPersisted.getId(),(String) key,detailsMap.get((String) key), false);
-            }
-        }
-
-        return guestOsPersisted;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding a new guest OS type", async = true)
-    public GuestOS getAddedGuestOs(final Long guestOsId) {
-        return getGuestOs(guestOsId);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_UPDATE, eventDescription = "updating guest OS type", async = true)
-    public GuestOS updateGuestOs(final UpdateGuestOsCmd cmd) {
-        final Long id = cmd.getId();
-        final String displayName = cmd.getOsDisplayName();
-
-        //check if guest OS exists
-        final GuestOS guestOsHandle = ApiDBUtils.findGuestOSById(id);
-        if (guestOsHandle == null) {
-            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
-        }
-
-        if (!guestOsHandle.getIsUserDefined()) {
-            throw new InvalidParameterValueException("Unable to modify system defined guest OS");
-        }
-
-        if(cmd.getDetails() != null && !cmd.getDetails().isEmpty()){
-            Map<String, String> detailsMap = cmd.getDetails();
-            for(Object key: detailsMap.keySet()){
-                _guestOsDetailsDao.addDetail(id,(String) key,detailsMap.get((String) key), false);
-            }
-        }
-
-        //Check if update is needed
-        if (displayName.equals(guestOsHandle.getDisplayName())) {
-            return guestOsHandle;
-        }
-
-        //Check if another Guest OS by same name exists
-        final GuestOS duplicate = ApiDBUtils.findGuestOSByDisplayName(displayName);
-        if(duplicate != null) {
-            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique guest OS name");
-        }
-        final GuestOSVO guestOs = _guestOSDao.createForUpdate(id);
-        guestOs.setDisplayName(displayName);
-        if (_guestOSDao.update(id, guestOs)) {
-            return _guestOSDao.findById(id);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_REMOVE, eventDescription = "removing guest OS type", async = true)
-    public boolean removeGuestOs(final RemoveGuestOsCmd cmd) {
-        final Long id = cmd.getId();
-
-        //check if guest OS exists
-        final GuestOS guestOs = ApiDBUtils.findGuestOSById(id);
-        if (guestOs == null) {
-            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
-        }
-
-        if (!guestOs.getIsUserDefined()) {
-            throw new InvalidParameterValueException("Unable to remove system defined guest OS");
-        }
-
-        return _guestOSDao.remove(id);
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_UPDATE, eventDescription = "updating guest OS mapping", async = true)
-    public GuestOSHypervisor updateGuestOsMapping(final UpdateGuestOsMappingCmd cmd) {
-        final Long id = cmd.getId();
-        final String osNameForHypervisor = cmd.getOsNameForHypervisor();
-
-        //check if mapping exists
-        final GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
-        if (guestOsHypervisorHandle == null) {
-            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
-        }
-
-        if (!guestOsHypervisorHandle.getIsUserDefined()) {
-            throw new InvalidParameterValueException("Unable to modify system defined Guest OS mapping");
-        }
-
-        final GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(id);
-        guestOsHypervisor.setGuestOsName(osNameForHypervisor);
-        if (_guestOSHypervisorDao.update(id, guestOsHypervisor)) {
-            return _guestOSHypervisorDao.findById(id);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_REMOVE, eventDescription = "removing guest OS mapping", async = true)
-    public boolean removeGuestOsMapping(final RemoveGuestOsMappingCmd cmd) {
-        final Long id = cmd.getId();
-
-        //check if mapping exists
-        final GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
-        if (guestOsHypervisorHandle == null) {
-            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
-        }
-
-        if (!guestOsHypervisorHandle.getIsUserDefined()) {
-            throw new InvalidParameterValueException("Unable to remove system defined Guest OS mapping");
-        }
-
-        return _guestOSHypervisorDao.removeGuestOsMapping(id);
-
-    }
-
-    protected ConsoleProxyInfo getConsoleProxyForVm(final long dataCenterId, final long userVmId) {
-        return _consoleProxyMgr.assignProxy(dataCenterId, userVmId);
-    }
-
-    private ConsoleProxyVO startConsoleProxy(final long instanceId) {
-        return _consoleProxyMgr.startProxy(instanceId, true);
-    }
-
-    private ConsoleProxyVO stopConsoleProxy(final VMInstanceVO systemVm, final boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
-
-        _itMgr.advanceStop(systemVm.getUuid(), isForced);
-        return _consoleProxyDao.findById(systemVm.getId());
-    }
-
-    private ConsoleProxyVO rebootConsoleProxy(final long instanceId) {
-        _consoleProxyMgr.rebootProxy(instanceId);
-        return _consoleProxyDao.findById(instanceId);
-    }
-
-    protected ConsoleProxyVO destroyConsoleProxy(final long instanceId) {
-        final ConsoleProxyVO proxy = _consoleProxyDao.findById(instanceId);
-
-        if (_consoleProxyMgr.destroyProxy(instanceId)) {
-            return proxy;
-        }
-        return null;
-    }
-
-    @Override
-    public String getConsoleAccessUrlRoot(final long vmId) {
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm != null) {
-            final ConsoleProxyInfo proxy = getConsoleProxyForVm(vm.getDataCenterId(), vmId);
-            if (proxy != null) {
-                return proxy.getProxyImageUrl();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Pair<String, Integer> getVncPort(final VirtualMachine vm) {
-        if (vm.getHostId() == null) {
-            s_logger.warn("VM " + vm.getHostName() + " does not have host, return -1 for its VNC port");
-            return new Pair<String, Integer>(null, -1);
-        }
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Trying to retrieve VNC port from agent about VM " + vm.getHostName());
-        }
-
-        final GetVncPortAnswer answer = (GetVncPortAnswer)_agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
-        if (answer != null && answer.getResult()) {
-            return new Pair<String, Integer>(answer.getAddress(), answer.getPort());
-        }
-
-        return new Pair<String, Integer>(null, -1);
-    }
-
-    private String getUpdatedDomainPath(final String oldPath, final String newName) {
-        final String[] tokenizedPath = oldPath.split("/");
-        tokenizedPath[tokenizedPath.length - 1] = newName;
-        final StringBuilder finalPath = new StringBuilder();
-        for (final String token : tokenizedPath) {
-            finalPath.append(token);
-            finalPath.append("/");
-        }
-        return finalPath.toString();
-    }
-
-    private void updateDomainChildren(final DomainVO domain, final String updatedDomainPrefix) {
-        final List<DomainVO> domainChildren = _domainDao.findAllChildren(domain.getPath(), domain.getId());
-        // for each child, update the path
-        for (final DomainVO dom : domainChildren) {
-            dom.setPath(dom.getPath().replaceFirst(domain.getPath(), updatedDomainPrefix));
-            _domainDao.update(dom.getId(), dom);
-        }
-    }
-
-    @Override
-    public Pair<List<? extends Alert>, Integer> searchForAlerts(final ListAlertsCmd cmd) {
-        final Filter searchFilter = new Filter(AlertVO.class, "lastSent", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchCriteria<AlertVO> sc = _alertDao.createSearchCriteria();
-
-        final Object id = cmd.getId();
-        final Object type = cmd.getType();
-        final Object keyword = cmd.getKeyword();
-        final Object name = cmd.getName();
-
-        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-        if (zoneId != null) {
-            sc.addAnd("data_center_id", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        if (keyword != null) {
-            final SearchCriteria<AlertVO> ssc = _alertDao.createSearchCriteria();
-            ssc.addOr("subject", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("subject", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (type != null) {
-            sc.addAnd("type", SearchCriteria.Op.EQ, type);
-        }
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        }
-
-        sc.addAnd("archived", SearchCriteria.Op.EQ, false);
-        final Pair<List<AlertVO>, Integer> result = _alertDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends Alert>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public boolean archiveAlerts(final ArchiveAlertsCmd cmd) {
-        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
-        final boolean result = _alertDao.archiveAlert(cmd.getIds(), cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), zoneId);
-        return result;
-    }
-
-    @Override
-    public boolean deleteAlerts(final DeleteAlertsCmd cmd) {
-        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
-        final boolean result = _alertDao.deleteAlert(cmd.getIds(), cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), zoneId);
-        return result;
-    }
-
-    @Override
-    public List<CapacityVO> listTopConsumedResources(final ListCapacityCmd cmd) {
-
-        final Integer capacityType = cmd.getType();
-        Long zoneId = cmd.getZoneId();
-        final Long podId = cmd.getPodId();
-        final Long clusterId = cmd.getClusterId();
-        final Boolean fetchLatest = cmd.getFetchLatest();
-
-        if (clusterId != null) {
-            throw new InvalidParameterValueException("Currently clusterId param is not suppoerted");
-        }
-        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
-
-        if (fetchLatest != null && fetchLatest) {
-            _alertMgr.recalculateCapacity();
-        }
-        List<SummedCapacity> summedCapacities = new ArrayList<SummedCapacity>();
-
-        if (zoneId == null && podId == null) {// Group by Zone, capacity type
-            final List<SummedCapacity> summedCapacitiesAtZone = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 1, cmd.getPageSizeVal());
-            if (summedCapacitiesAtZone != null) {
-                summedCapacities.addAll(summedCapacitiesAtZone);
-            }
-        } else if (podId == null) {// Group by Pod, capacity type
-            final List<SummedCapacity> summedCapacitiesAtPod = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 2, cmd.getPageSizeVal());
-            if (summedCapacitiesAtPod != null) {
-                summedCapacities.addAll(summedCapacitiesAtPod);
-            }
-        } else { // Group by Cluster, capacity type
-            final List<SummedCapacity> summedCapacitiesAtCluster = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 3, cmd.getPageSizeVal());
-            if (summedCapacitiesAtCluster != null) {
-                summedCapacities.addAll(summedCapacitiesAtCluster);
-            }
-        }
-
-        List<SummedCapacity> summedCapacitiesForSecStorage = getStorageUsed(clusterId, podId, zoneId, capacityType);
-        if (summedCapacitiesForSecStorage != null) {
-            summedCapacities.addAll(summedCapacitiesForSecStorage);
-        }
-
-        // Sort Capacities
-        Collections.sort(summedCapacities, new Comparator<SummedCapacity>() {
-            @Override
-            public int compare(final SummedCapacity arg0, final SummedCapacity arg1) {
-                if (arg0.getPercentUsed() < arg1.getPercentUsed()) {
-                    return 1;
-                } else if (arg0.getPercentUsed().equals(arg1.getPercentUsed())) {
-                    return 0;
-                }
-                return -1;
-            }
-        });
-
-        final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
-
-        Integer pageSize = null;
-        try {
-            pageSize = Integer.valueOf(cmd.getPageSizeVal().toString());
-        } catch (final IllegalArgumentException e) {
-            throw new InvalidParameterValueException("pageSize " + cmd.getPageSizeVal() + " is out of Integer range is not supported for this call");
-        }
-
-        summedCapacities = summedCapacities.subList(0, summedCapacities.size() < cmd.getPageSizeVal() ? summedCapacities.size() : pageSize);
-        for (final SummedCapacity summedCapacity : summedCapacities) {
-            final CapacityVO capacity = new CapacityVO(summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getCapacityType(),
-                    summedCapacity.getPercentUsed());
-            capacity.setUsedCapacity(summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity());
-            capacity.setTotalCapacity(summedCapacity.getTotalCapacity());
-            capacities.add(capacity);
-        }
-        return capacities;
-    }
-
-    List<SummedCapacity> getStorageUsed(Long clusterId, Long podId, Long zoneId, Integer capacityType) {
-        if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
-            final List<SummedCapacity> list = new ArrayList<SummedCapacity>();
-            if (zoneId != null) {
-                final DataCenterVO zone = ApiDBUtils.findZoneById(zoneId);
-                if (zone == null || zone.getAllocationState() == AllocationState.Disabled) {
-                    return null;
-                }
-                List<CapacityVO> capacities=new ArrayList<CapacityVO>();
-                capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
-                capacities.add(_storageMgr.getStoragePoolUsedStats(null,clusterId, podId, zoneId));
-                for (CapacityVO capacity : capacities) {
-                    if (capacity.getTotalCapacity() != 0) {
-                        capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
-                    } else {
-                        capacity.setUsedPercentage(0);
-                    }
-                    final SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(),
-                            capacity.getCapacityType(), capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
-                    list.add(summedCapacity);
-                }
-            } else {
-                List<DataCenterVO> dcList = _dcDao.listEnabledZones();
-                for (DataCenterVO dc : dcList) {
-                    List<CapacityVO> capacities=new ArrayList<CapacityVO>();
-                    capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, dc.getId()));
-                    capacities.add(_storageMgr.getStoragePoolUsedStats(null, null, null, dc.getId()));
-                    for (CapacityVO capacity : capacities) {
-                        if (capacity.getTotalCapacity() != 0) {
-                            capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
-                        } else {
-                            capacity.setUsedPercentage(0);
-                        }
-                        SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(),
-                                capacity.getCapacityType(), capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
-                        list.add(summedCapacity);
-                    }
-                }// End of for
-            }
-            return list;
-        }
-        return null;
-    }
-
-    @Override
-    public List<CapacityVO> listCapacities(final ListCapacityCmd cmd) {
-
-        final Integer capacityType = cmd.getType();
-        Long zoneId = cmd.getZoneId();
-        final Long podId = cmd.getPodId();
-        final Long clusterId = cmd.getClusterId();
-        final Boolean fetchLatest = cmd.getFetchLatest();
-
-        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
-        if (fetchLatest != null && fetchLatest) {
-            _alertMgr.recalculateCapacity();
-        }
-
-        final List<SummedCapacity> summedCapacities = _capacityDao.findCapacityBy(capacityType, zoneId, podId, clusterId);
-        final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
-
-        for (final SummedCapacity summedCapacity : summedCapacities) {
-            final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(),summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getUsedCapacity()
-                    + summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType());
-            capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity());
-            capacities.add(capacity);
-        }
-
-        // op_host_Capacity contains only allocated stats and the real time
-        // stats are stored "in memory".
-        // Show Sec. Storage only when the api is invoked for the zone layer.
-        List<DataCenterVO> dcList = new ArrayList<DataCenterVO>();
-        if (zoneId == null && podId == null && clusterId == null) {
-            dcList = ApiDBUtils.listZones();
-        } else if (zoneId != null) {
-            dcList.add(ApiDBUtils.findZoneById(zoneId));
-        } else {
-            if (clusterId != null) {
-                zoneId = ApiDBUtils.findClusterById(clusterId).getDataCenterId();
-            } else {
-                zoneId = ApiDBUtils.findPodById(podId).getDataCenterId();
-            }
-            if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
-                capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
-            }
-        }
-
-        for (final DataCenterVO zone : dcList) {
-            zoneId = zone.getId();
-            if ((capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) && podId == null && clusterId == null) {
-                capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
-            }
-            if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
-                capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
-            }
-        }
-        return capacities;
-    }
-
-    @Override
-    public long getMemoryOrCpuCapacityByHost(final Long hostId, final short capacityType) {
-
-        final CapacityVO capacity = _capacityDao.findByHostIdType(hostId, capacityType);
-        return capacity == null ? 0 : capacity.getReservedCapacity() + capacity.getUsedCapacity();
-
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(CreateAccountCmd.class);
-        cmdList.add(DeleteAccountCmd.class);
-        cmdList.add(DisableAccountCmd.class);
-        cmdList.add(EnableAccountCmd.class);
-        cmdList.add(LockAccountCmd.class);
-        cmdList.add(UpdateAccountCmd.class);
-        cmdList.add(CreateCounterCmd.class);
-        cmdList.add(DeleteCounterCmd.class);
-        cmdList.add(AddClusterCmd.class);
-        cmdList.add(DeleteClusterCmd.class);
-        cmdList.add(ListClustersCmd.class);
-        cmdList.add(UpdateClusterCmd.class);
-        cmdList.add(ListCfgsByCmd.class);
-        cmdList.add(ListHypervisorCapabilitiesCmd.class);
-        cmdList.add(UpdateCfgCmd.class);
-        cmdList.add(UpdateHypervisorCapabilitiesCmd.class);
-        cmdList.add(CreateDomainCmd.class);
-        cmdList.add(DeleteDomainCmd.class);
-        cmdList.add(ListDomainChildrenCmd.class);
-        cmdList.add(ListDomainsCmd.class);
-        cmdList.add(ListDomainsCmdByAdmin.class);
-        cmdList.add(UpdateDomainCmd.class);
-        cmdList.add(AddHostCmd.class);
-        cmdList.add(AddSecondaryStorageCmd.class);
-        cmdList.add(CancelMaintenanceCmd.class);
-        cmdList.add(DeleteHostCmd.class);
-        cmdList.add(ListHostsCmd.class);
-        cmdList.add(ListHostTagsCmd.class);
-        cmdList.add(FindHostsForMigrationCmd.class);
-        cmdList.add(PrepareForMaintenanceCmd.class);
-        cmdList.add(ReconnectHostCmd.class);
-        cmdList.add(UpdateHostCmd.class);
-        cmdList.add(UpdateHostPasswordCmd.class);
-        cmdList.add(AddNetworkDeviceCmd.class);
-        cmdList.add(AddNetworkServiceProviderCmd.class);
-        cmdList.add(CreateNetworkOfferingCmd.class);
-        cmdList.add(CreatePhysicalNetworkCmd.class);
-        cmdList.add(CreateStorageNetworkIpRangeCmd.class);
-        cmdList.add(DeleteNetworkDeviceCmd.class);
-        cmdList.add(DeleteNetworkOfferingCmd.class);
-        cmdList.add(DeleteNetworkServiceProviderCmd.class);
-        cmdList.add(DeletePhysicalNetworkCmd.class);
-        cmdList.add(DeleteStorageNetworkIpRangeCmd.class);
-        cmdList.add(ListNetworkDeviceCmd.class);
-        cmdList.add(ListNetworkServiceProvidersCmd.class);
-        cmdList.add(ListPhysicalNetworksCmd.class);
-        cmdList.add(ListStorageNetworkIpRangeCmd.class);
-        cmdList.add(ListSupportedNetworkServicesCmd.class);
-        cmdList.add(UpdateNetworkOfferingCmd.class);
-        cmdList.add(UpdateNetworkServiceProviderCmd.class);
-        cmdList.add(UpdatePhysicalNetworkCmd.class);
-        cmdList.add(UpdateStorageNetworkIpRangeCmd.class);
-        cmdList.add(DedicateGuestVlanRangeCmd.class);
-        cmdList.add(ListDedicatedGuestVlanRangesCmd.class);
-        cmdList.add(ReleaseDedicatedGuestVlanRangeCmd.class);
-        cmdList.add(CreateDiskOfferingCmd.class);
-        cmdList.add(CreateServiceOfferingCmd.class);
-        cmdList.add(DeleteDiskOfferingCmd.class);
-        cmdList.add(DeleteServiceOfferingCmd.class);
-        cmdList.add(UpdateDiskOfferingCmd.class);
-        cmdList.add(UpdateServiceOfferingCmd.class);
-        cmdList.add(CreatePodCmd.class);
-        cmdList.add(DeletePodCmd.class);
-        cmdList.add(ListPodsByCmd.class);
-        cmdList.add(UpdatePodCmd.class);
-        cmdList.add(AddRegionCmd.class);
-        cmdList.add(RemoveRegionCmd.class);
-        cmdList.add(UpdateRegionCmd.class);
-        cmdList.add(ListAlertsCmd.class);
-        cmdList.add(ListCapacityCmd.class);
-        cmdList.add(UploadCustomCertificateCmd.class);
-        cmdList.add(ConfigureVirtualRouterElementCmd.class);
-        cmdList.add(CreateVirtualRouterElementCmd.class);
-        cmdList.add(DestroyRouterCmd.class);
-        cmdList.add(ListRoutersCmd.class);
-        cmdList.add(ListVirtualRouterElementsCmd.class);
-        cmdList.add(RebootRouterCmd.class);
-        cmdList.add(StartRouterCmd.class);
-        cmdList.add(StopRouterCmd.class);
-        cmdList.add(UpgradeRouterCmd.class);
-        cmdList.add(AddSwiftCmd.class);
-        cmdList.add(CancelPrimaryStorageMaintenanceCmd.class);
-        cmdList.add(CreateStoragePoolCmd.class);
-        cmdList.add(DeletePoolCmd.class);
-        cmdList.add(ListSwiftsCmd.class);
-        cmdList.add(ListStoragePoolsCmd.class);
-        cmdList.add(ListStorageTagsCmd.class);
-        cmdList.add(FindStoragePoolsForMigrationCmd.class);
-        cmdList.add(PreparePrimaryStorageForMaintenanceCmd.class);
-        cmdList.add(UpdateStoragePoolCmd.class);
-        cmdList.add(DestroySystemVmCmd.class);
-        cmdList.add(ListSystemVMsCmd.class);
-        cmdList.add(MigrateSystemVMCmd.class);
-        cmdList.add(RebootSystemVmCmd.class);
-        cmdList.add(StartSystemVMCmd.class);
-        cmdList.add(StopSystemVmCmd.class);
-        cmdList.add(UpgradeSystemVMCmd.class);
-        cmdList.add(PrepareTemplateCmd.class);
-        cmdList.add(AddTrafficMonitorCmd.class);
-        cmdList.add(AddTrafficTypeCmd.class);
-        cmdList.add(DeleteTrafficMonitorCmd.class);
-        cmdList.add(DeleteTrafficTypeCmd.class);
-        cmdList.add(GenerateUsageRecordsCmd.class);
-        cmdList.add(GetUsageRecordsCmd.class);
-        cmdList.add(RemoveRawUsageRecordsCmd.class);
-        cmdList.add(ListTrafficMonitorsCmd.class);
-        cmdList.add(ListTrafficTypeImplementorsCmd.class);
-        cmdList.add(ListTrafficTypesCmd.class);
-        cmdList.add(ListUsageTypesCmd.class);
-        cmdList.add(UpdateTrafficTypeCmd.class);
-        cmdList.add(CreateUserCmd.class);
-        cmdList.add(DeleteUserCmd.class);
-        cmdList.add(DisableUserCmd.class);
-        cmdList.add(EnableUserCmd.class);
-        cmdList.add(GetUserCmd.class);
-        cmdList.add(ListUsersCmd.class);
-        cmdList.add(LockUserCmd.class);
-        cmdList.add(MoveUserCmd.class);
-        cmdList.add(RegisterCmd.class);
-        cmdList.add(UpdateUserCmd.class);
-        cmdList.add(CreateVlanIpRangeCmd.class);
-        cmdList.add(DeleteVlanIpRangeCmd.class);
-        cmdList.add(ListVlanIpRangesCmd.class);
-        cmdList.add(DedicatePublicIpRangeCmd.class);
-        cmdList.add(ReleasePublicIpRangeCmd.class);
-        cmdList.add(AssignVMCmd.class);
-        cmdList.add(MigrateVMCmd.class);
-        cmdList.add(MigrateVirtualMachineWithVolumeCmd.class);
-        cmdList.add(RecoverVMCmd.class);
-        cmdList.add(CreatePrivateGatewayCmd.class);
-        cmdList.add(CreateVPCOfferingCmd.class);
-        cmdList.add(DeletePrivateGatewayCmd.class);
-        cmdList.add(DeleteVPCOfferingCmd.class);
-        cmdList.add(UpdateVPCOfferingCmd.class);
-        cmdList.add(CreateZoneCmd.class);
-        cmdList.add(DeleteZoneCmd.class);
-        cmdList.add(MarkDefaultZoneForAccountCmd.class);
-        cmdList.add(UpdateZoneCmd.class);
-        cmdList.add(AddAccountToProjectCmd.class);
-        cmdList.add(DeleteAccountFromProjectCmd.class);
-        cmdList.add(ListAccountsCmd.class);
-        cmdList.add(ListProjectAccountsCmd.class);
-        cmdList.add(AssociateIPAddrCmd.class);
-        cmdList.add(DisassociateIPAddrCmd.class);
-        cmdList.add(ListPublicIpAddressesCmd.class);
-        cmdList.add(CreateAutoScalePolicyCmd.class);
-        cmdList.add(CreateAutoScaleVmGroupCmd.class);
-        cmdList.add(CreateAutoScaleVmProfileCmd.class);
-        cmdList.add(CreateConditionCmd.class);
-        cmdList.add(DeleteAutoScalePolicyCmd.class);
-        cmdList.add(DeleteAutoScaleVmGroupCmd.class);
-        cmdList.add(DeleteAutoScaleVmProfileCmd.class);
-        cmdList.add(DeleteConditionCmd.class);
-        cmdList.add(DisableAutoScaleVmGroupCmd.class);
-        cmdList.add(EnableAutoScaleVmGroupCmd.class);
-        cmdList.add(ListAutoScalePoliciesCmd.class);
-        cmdList.add(ListAutoScaleVmGroupsCmd.class);
-        cmdList.add(ListAutoScaleVmProfilesCmd.class);
-        cmdList.add(ListConditionsCmd.class);
-        cmdList.add(ListCountersCmd.class);
-        cmdList.add(UpdateAutoScalePolicyCmd.class);
-        cmdList.add(UpdateAutoScaleVmGroupCmd.class);
-        cmdList.add(UpdateAutoScaleVmProfileCmd.class);
-        cmdList.add(ListCapabilitiesCmd.class);
-        cmdList.add(ListEventsCmd.class);
-        cmdList.add(ListEventTypesCmd.class);
-        cmdList.add(CreateEgressFirewallRuleCmd.class);
-        cmdList.add(CreateFirewallRuleCmd.class);
-        cmdList.add(CreatePortForwardingRuleCmd.class);
-        cmdList.add(DeleteEgressFirewallRuleCmd.class);
-        cmdList.add(DeleteFirewallRuleCmd.class);
-        cmdList.add(DeletePortForwardingRuleCmd.class);
-        cmdList.add(ListEgressFirewallRulesCmd.class);
-        cmdList.add(ListFirewallRulesCmd.class);
-        cmdList.add(ListPortForwardingRulesCmd.class);
-        cmdList.add(UpdatePortForwardingRuleCmd.class);
-        cmdList.add(ListGuestOsCategoriesCmd.class);
-        cmdList.add(ListGuestOsCmd.class);
-        cmdList.add(ListGuestOsMappingCmd.class);
-        cmdList.add(AddGuestOsCmd.class);
-        cmdList.add(AddGuestOsMappingCmd.class);
-        cmdList.add(UpdateGuestOsCmd.class);
-        cmdList.add(UpdateGuestOsMappingCmd.class);
-        cmdList.add(RemoveGuestOsCmd.class);
-        cmdList.add(RemoveGuestOsMappingCmd.class);
-        cmdList.add(AttachIsoCmd.class);
-        cmdList.add(CopyIsoCmd.class);
-        cmdList.add(DeleteIsoCmd.class);
-        cmdList.add(DetachIsoCmd.class);
-        cmdList.add(ExtractIsoCmd.class);
-        cmdList.add(ListIsoPermissionsCmd.class);
-        cmdList.add(ListIsosCmd.class);
-        cmdList.add(RegisterIsoCmd.class);
-        cmdList.add(UpdateIsoCmd.class);
-        cmdList.add(UpdateIsoPermissionsCmd.class);
-        cmdList.add(ListAsyncJobsCmd.class);
-        cmdList.add(QueryAsyncJobResultCmd.class);
-        cmdList.add(AssignToLoadBalancerRuleCmd.class);
-        cmdList.add(CreateLBStickinessPolicyCmd.class);
-        cmdList.add(CreateLBHealthCheckPolicyCmd.class);
-        cmdList.add(CreateLoadBalancerRuleCmd.class);
-        cmdList.add(DeleteLBStickinessPolicyCmd.class);
-        cmdList.add(DeleteLBHealthCheckPolicyCmd.class);
-        cmdList.add(DeleteLoadBalancerRuleCmd.class);
-        cmdList.add(ListLBStickinessPoliciesCmd.class);
-        cmdList.add(ListLBHealthCheckPoliciesCmd.class);
-        cmdList.add(ListLoadBalancerRuleInstancesCmd.class);
-        cmdList.add(ListLoadBalancerRulesCmd.class);
-        cmdList.add(RemoveFromLoadBalancerRuleCmd.class);
-        cmdList.add(UpdateLoadBalancerRuleCmd.class);
-        cmdList.add(CreateIpForwardingRuleCmd.class);
-        cmdList.add(DeleteIpForwardingRuleCmd.class);
-        cmdList.add(DisableStaticNatCmd.class);
-        cmdList.add(EnableStaticNatCmd.class);
-        cmdList.add(ListIpForwardingRulesCmd.class);
-        cmdList.add(CreateNetworkACLCmd.class);
-        cmdList.add(CreateNetworkCmd.class);
-        cmdList.add(DeleteNetworkACLCmd.class);
-        cmdList.add(DeleteNetworkCmd.class);
-        cmdList.add(ListNetworkACLsCmd.class);
-        cmdList.add(ListNetworkOfferingsCmd.class);
-        cmdList.add(ListNetworksCmd.class);
-        cmdList.add(RestartNetworkCmd.class);
-        cmdList.add(UpdateNetworkCmd.class);
-        cmdList.add(ListDiskOfferingsCmd.class);
-        cmdList.add(ListServiceOfferingsCmd.class);
-        cmdList.add(ActivateProjectCmd.class);
-        cmdList.add(CreateProjectCmd.class);
-        cmdList.add(DeleteProjectCmd.class);
-        cmdList.add(DeleteProjectInvitationCmd.class);
-        cmdList.add(ListProjectInvitationsCmd.class);
-        cmdList.add(ListProjectsCmd.class);
-        cmdList.add(SuspendProjectCmd.class);
-        cmdList.add(UpdateProjectCmd.class);
-        cmdList.add(UpdateProjectInvitationCmd.class);
-        cmdList.add(ListRegionsCmd.class);
-        cmdList.add(GetCloudIdentifierCmd.class);
-        cmdList.add(ListHypervisorsCmd.class);
-        cmdList.add(ListResourceLimitsCmd.class);
-        cmdList.add(UpdateResourceCountCmd.class);
-        cmdList.add(UpdateResourceLimitCmd.class);
-        cmdList.add(AuthorizeSecurityGroupEgressCmd.class);
-        cmdList.add(AuthorizeSecurityGroupIngressCmd.class);
-        cmdList.add(CreateSecurityGroupCmd.class);
-        cmdList.add(DeleteSecurityGroupCmd.class);
-        cmdList.add(ListSecurityGroupsCmd.class);
-        cmdList.add(RevokeSecurityGroupEgressCmd.class);
-        cmdList.add(RevokeSecurityGroupIngressCmd.class);
-        cmdList.add(CreateSnapshotCmd.class);
-        cmdList.add(CreateSnapshotFromVMSnapshotCmd.class);
-        cmdList.add(DeleteSnapshotCmd.class);
-        cmdList.add(CreateSnapshotPolicyCmd.class);
-        cmdList.add(UpdateSnapshotPolicyCmd.class);
-        cmdList.add(DeleteSnapshotPoliciesCmd.class);
-        cmdList.add(ListSnapshotPoliciesCmd.class);
-        cmdList.add(ListSnapshotsCmd.class);
-        cmdList.add(RevertSnapshotCmd.class);
-        cmdList.add(CreateSSHKeyPairCmd.class);
-        cmdList.add(DeleteSSHKeyPairCmd.class);
-        cmdList.add(ListSSHKeyPairsCmd.class);
-        cmdList.add(RegisterSSHKeyPairCmd.class);
-        cmdList.add(CreateTagsCmd.class);
-        cmdList.add(DeleteTagsCmd.class);
-        cmdList.add(ListTagsCmd.class);
-        cmdList.add(CopyTemplateCmd.class);
-        cmdList.add(CreateTemplateCmd.class);
-        cmdList.add(DeleteTemplateCmd.class);
-        cmdList.add(ExtractTemplateCmd.class);
-        cmdList.add(ListTemplatePermissionsCmd.class);
-        cmdList.add(ListTemplatesCmd.class);
-        cmdList.add(RegisterTemplateCmd.class);
-        cmdList.add(UpdateTemplateCmd.class);
-        cmdList.add(UpdateTemplatePermissionsCmd.class);
-        cmdList.add(AddNicToVMCmd.class);
-        cmdList.add(DeployVMCmd.class);
-        cmdList.add(DestroyVMCmd.class);
-        cmdList.add(ExpungeVMCmd.class);
-        cmdList.add(GetVMPasswordCmd.class);
-        cmdList.add(ListVMsCmd.class);
-        cmdList.add(ScaleVMCmd.class);
-        cmdList.add(RebootVMCmd.class);
-        cmdList.add(RemoveNicFromVMCmd.class);
-        cmdList.add(ResetVMPasswordCmd.class);
-        cmdList.add(ResetVMSSHKeyCmd.class);
-        cmdList.add(RestoreVMCmd.class);
-        cmdList.add(StartVMCmd.class);
-        cmdList.add(StopVMCmd.class);
-        cmdList.add(UpdateDefaultNicForVMCmd.class);
-        cmdList.add(UpdateVMCmd.class);
-        cmdList.add(UpgradeVMCmd.class);
-        cmdList.add(CreateVMGroupCmd.class);
-        cmdList.add(DeleteVMGroupCmd.class);
-        cmdList.add(ListVMGroupsCmd.class);
-        cmdList.add(UpdateVMGroupCmd.class);
-        cmdList.add(AttachVolumeCmd.class);
-        cmdList.add(CreateVolumeCmd.class);
-        cmdList.add(DeleteVolumeCmd.class);
-        cmdList.add(UpdateVolumeCmd.class);
-        cmdList.add(DetachVolumeCmd.class);
-        cmdList.add(ExtractVolumeCmd.class);
-        cmdList.add(ListVolumesCmd.class);
-        cmdList.add(MigrateVolumeCmd.class);
-        cmdList.add(ResizeVolumeCmd.class);
-        cmdList.add(UploadVolumeCmd.class);
-        cmdList.add(CreateStaticRouteCmd.class);
-        cmdList.add(CreateVPCCmd.class);
-        cmdList.add(DeleteStaticRouteCmd.class);
-        cmdList.add(DeleteVPCCmd.class);
-        cmdList.add(ListPrivateGatewaysCmd.class);
-        cmdList.add(ListStaticRoutesCmd.class);
-        cmdList.add(ListVPCOfferingsCmd.class);
-        cmdList.add(ListVPCsCmd.class);
-        cmdList.add(RestartVPCCmd.class);
-        cmdList.add(UpdateVPCCmd.class);
-        cmdList.add(AddVpnUserCmd.class);
-        cmdList.add(CreateRemoteAccessVpnCmd.class);
-        cmdList.add(CreateVpnConnectionCmd.class);
-        cmdList.add(CreateVpnCustomerGatewayCmd.class);
-        cmdList.add(CreateVpnGatewayCmd.class);
-        cmdList.add(DeleteRemoteAccessVpnCmd.class);
-        cmdList.add(DeleteVpnConnectionCmd.class);
-        cmdList.add(DeleteVpnCustomerGatewayCmd.class);
-        cmdList.add(DeleteVpnGatewayCmd.class);
-        cmdList.add(ListRemoteAccessVpnsCmd.class);
-        cmdList.add(ListVpnConnectionsCmd.class);
-        cmdList.add(ListVpnCustomerGatewaysCmd.class);
-        cmdList.add(ListVpnGatewaysCmd.class);
-        cmdList.add(ListVpnUsersCmd.class);
-        cmdList.add(RemoveVpnUserCmd.class);
-        cmdList.add(ResetVpnConnectionCmd.class);
-        cmdList.add(UpdateVpnCustomerGatewayCmd.class);
-        cmdList.add(ListZonesCmd.class);
-        cmdList.add(ListVMSnapshotCmd.class);
-        cmdList.add(CreateVMSnapshotCmd.class);
-        cmdList.add(RevertToVMSnapshotCmd.class);
-        cmdList.add(DeleteVMSnapshotCmd.class);
-        cmdList.add(AddIpToVmNicCmd.class);
-        cmdList.add(RemoveIpFromVmNicCmd.class);
-        cmdList.add(UpdateVmNicIpCmd.class);
-        cmdList.add(ListNicsCmd.class);
-        cmdList.add(ArchiveAlertsCmd.class);
-        cmdList.add(DeleteAlertsCmd.class);
-        cmdList.add(ArchiveEventsCmd.class);
-        cmdList.add(DeleteEventsCmd.class);
-        cmdList.add(CreateGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(DeleteGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(ListGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(UpdateGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(AssignToGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(RemoveFromGlobalLoadBalancerRuleCmd.class);
-        cmdList.add(ListStorageProvidersCmd.class);
-        cmdList.add(AddImageStoreCmd.class);
-        cmdList.add(AddImageStoreS3CMD.class);
-        cmdList.add(ListImageStoresCmd.class);
-        cmdList.add(DeleteImageStoreCmd.class);
-        cmdList.add(CreateSecondaryStagingStoreCmd.class);
-        cmdList.add(ListSecondaryStagingStoresCmd.class);
-        cmdList.add(DeleteSecondaryStagingStoreCmd.class);
-        cmdList.add(UpdateCloudToUseObjectStoreCmd.class);
-        cmdList.add(CreateApplicationLoadBalancerCmd.class);
-        cmdList.add(ListApplicationLoadBalancersCmd.class);
-        cmdList.add(DeleteApplicationLoadBalancerCmd.class);
-        cmdList.add(ConfigureInternalLoadBalancerElementCmd.class);
-        cmdList.add(CreateInternalLoadBalancerElementCmd.class);
-        cmdList.add(ListInternalLoadBalancerElementsCmd.class);
-        cmdList.add(CreateAffinityGroupCmd.class);
-        cmdList.add(DeleteAffinityGroupCmd.class);
-        cmdList.add(ListAffinityGroupsCmd.class);
-        cmdList.add(UpdateVMAffinityGroupCmd.class);
-        cmdList.add(ListAffinityGroupTypesCmd.class);
-        cmdList.add(CreatePortableIpRangeCmd.class);
-        cmdList.add(DeletePortableIpRangeCmd.class);
-        cmdList.add(ListPortableIpRangesCmd.class);
-        cmdList.add(ListDeploymentPlannersCmd.class);
-        cmdList.add(ReleaseHostReservationCmd.class);
-        cmdList.add(ScaleSystemVMCmd.class);
-        cmdList.add(AddResourceDetailCmd.class);
-        cmdList.add(RemoveResourceDetailCmd.class);
-        cmdList.add(ListResourceDetailsCmd.class);
-        cmdList.add(StopInternalLBVMCmd.class);
-        cmdList.add(StartInternalLBVMCmd.class);
-        cmdList.add(ListInternalLBVMsCmd.class);
-        cmdList.add(ListNetworkIsolationMethodsCmd.class);
-        cmdList.add(ListNetworkIsolationMethodsCmd.class);
-        cmdList.add(CreateNetworkACLListCmd.class);
-        cmdList.add(DeleteNetworkACLListCmd.class);
-        cmdList.add(ListNetworkACLListsCmd.class);
-        cmdList.add(ReplaceNetworkACLListCmd.class);
-        cmdList.add(UpdateNetworkACLItemCmd.class);
-        cmdList.add(CleanVMReservationsCmd.class);
-        cmdList.add(UpgradeRouterTemplateCmd.class);
-        cmdList.add(UploadSslCertCmd.class);
-        cmdList.add(DeleteSslCertCmd.class);
-        cmdList.add(ListSslCertsCmd.class);
-        cmdList.add(AssignCertToLoadBalancerCmd.class);
-        cmdList.add(RemoveCertFromLoadBalancerCmd.class);
-        cmdList.add(GenerateAlertCmd.class);
-        cmdList.add(ListOvsElementsCmd.class);
-        cmdList.add(ConfigureOvsElementCmd.class);
-        cmdList.add(GetVMUserDataCmd.class);
-        cmdList.add(UpdateEgressFirewallRuleCmd.class);
-        cmdList.add(UpdateFirewallRuleCmd.class);
-        cmdList.add(UpdateNetworkACLListCmd.class);
-        cmdList.add(UpdateApplicationLoadBalancerCmd.class);
-        cmdList.add(UpdateIPAddrCmd.class);
-        cmdList.add(UpdateRemoteAccessVpnCmd.class);
-        cmdList.add(UpdateVpnConnectionCmd.class);
-        cmdList.add(UpdateVpnGatewayCmd.class);
-        // separated admin commands
-        cmdList.add(ListAccountsCmdByAdmin.class);
-        cmdList.add(ListZonesCmdByAdmin.class);
-        cmdList.add(ListTemplatesCmdByAdmin.class);
-        cmdList.add(CreateTemplateCmdByAdmin.class);
-        cmdList.add(CopyTemplateCmdByAdmin.class);
-        cmdList.add(RegisterTemplateCmdByAdmin.class);
-        cmdList.add(ListTemplatePermissionsCmdByAdmin.class);
-        cmdList.add(RegisterIsoCmdByAdmin.class);
-        cmdList.add(CopyIsoCmdByAdmin.class);
-        cmdList.add(ListIsosCmdByAdmin.class);
-        cmdList.add(AttachIsoCmdByAdmin.class);
-        cmdList.add(DetachIsoCmdByAdmin.class);
-        cmdList.add(ListIsoPermissionsCmdByAdmin.class);
-        cmdList.add(UpdateVMAffinityGroupCmdByAdmin.class);
-        cmdList.add(AddNicToVMCmdByAdmin.class);
-        cmdList.add(RemoveNicFromVMCmdByAdmin.class);
-        cmdList.add(UpdateDefaultNicForVMCmdByAdmin.class);
-        cmdList.add(ListLoadBalancerRuleInstancesCmdByAdmin.class);
-        cmdList.add(DeployVMCmdByAdmin.class);
-        cmdList.add(DestroyVMCmdByAdmin.class);
-        cmdList.add(RebootVMCmdByAdmin.class);
-        cmdList.add(ResetVMPasswordCmdByAdmin.class);
-        cmdList.add(ResetVMSSHKeyCmdByAdmin.class);
-        cmdList.add(RestoreVMCmdByAdmin.class);
-        cmdList.add(ScaleVMCmdByAdmin.class);
-        cmdList.add(StartVMCmdByAdmin.class);
-        cmdList.add(StopVMCmdByAdmin.class);
-        cmdList.add(UpdateVMCmdByAdmin.class);
-        cmdList.add(UpgradeVMCmdByAdmin.class);
-        cmdList.add(RevertToVMSnapshotCmdByAdmin.class);
-        cmdList.add(ListVMsCmdByAdmin.class);
-        cmdList.add(AttachVolumeCmdByAdmin.class);
-        cmdList.add(CreateVolumeCmdByAdmin.class);
-        cmdList.add(DetachVolumeCmdByAdmin.class);
-        cmdList.add(MigrateVolumeCmdByAdmin.class);
-        cmdList.add(ResizeVolumeCmdByAdmin.class);
-        cmdList.add(UpdateVolumeCmdByAdmin.class);
-        cmdList.add(UploadVolumeCmdByAdmin.class);
-        cmdList.add(ListVolumesCmdByAdmin.class);
-        cmdList.add(AssociateIPAddrCmdByAdmin.class);
-        cmdList.add(ListPublicIpAddressesCmdByAdmin.class);
-        cmdList.add(CreateNetworkCmdByAdmin.class);
-        cmdList.add(UpdateNetworkCmdByAdmin.class);
-        cmdList.add(ListNetworksCmdByAdmin.class);
-        cmdList.add(CreateVPCCmdByAdmin.class);
-        cmdList.add(ListVPCsCmdByAdmin.class);
-        cmdList.add(UpdateVPCCmdByAdmin.class);
-        cmdList.add(UpdateLBStickinessPolicyCmd.class);
-        cmdList.add(UpdateLBHealthCheckPolicyCmd.class);
-        cmdList.add(GetUploadParamsForTemplateCmd.class);
-        cmdList.add(GetUploadParamsForVolumeCmd.class);
-        cmdList.add(MigrateNetworkCmd.class);
-        cmdList.add(MigrateVPCCmd.class);
-        cmdList.add(AcquirePodIpCmdByAdmin.class);
-        cmdList.add(ReleasePodIpCmdByAdmin.class);
-        cmdList.add(CreateManagementNetworkIpRangeCmd.class);
-        cmdList.add(DeleteManagementNetworkIpRangeCmd.class);
-        cmdList.add(UploadTemplateDirectDownloadCertificateCmd.class);
-
-        // Out-of-band management APIs for admins
-        cmdList.add(EnableOutOfBandManagementForHostCmd.class);
-        cmdList.add(DisableOutOfBandManagementForHostCmd.class);
-        cmdList.add(EnableOutOfBandManagementForClusterCmd.class);
-        cmdList.add(DisableOutOfBandManagementForClusterCmd.class);
-        cmdList.add(EnableOutOfBandManagementForZoneCmd.class);
-        cmdList.add(DisableOutOfBandManagementForZoneCmd.class);
-        cmdList.add(ConfigureOutOfBandManagementCmd.class);
-        cmdList.add(IssueOutOfBandManagementPowerActionCmd.class);
-        cmdList.add(ChangeOutOfBandManagementPasswordCmd.class);
-        cmdList.add(GetUserKeysCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return ManagementServer.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {vmPasswordLength, sshKeyLength};
-    }
-
-    protected class EventPurgeTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                final GlobalLock lock = GlobalLock.getInternLock("EventPurge");
-                if (lock == null) {
-                    s_logger.debug("Couldn't get the global lock");
-                    return;
-                }
-                if (!lock.lock(30)) {
-                    s_logger.debug("Couldn't lock the db");
-                    return;
-                }
-                try {
-                    final Calendar purgeCal = Calendar.getInstance();
-                    purgeCal.add(Calendar.DAY_OF_YEAR, -_purgeDelay);
-                    final Date purgeTime = purgeCal.getTime();
-                    s_logger.debug("Deleting events older than: " + purgeTime.toString());
-                    final List<EventVO> oldEvents = _eventDao.listOlderEvents(purgeTime);
-                    s_logger.debug("Found " + oldEvents.size() + " events to be purged");
-                    for (final EventVO event : oldEvents) {
-                        _eventDao.expunge(event.getId());
-                    }
-                } catch (final Exception e) {
-                    s_logger.error("Exception ", e);
-                } finally {
-                    lock.unlock();
-                }
-            } catch (final Exception e) {
-                s_logger.error("Exception ", e);
-            }
-        }
-    }
-
-    protected class AlertPurgeTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                final GlobalLock lock = GlobalLock.getInternLock("AlertPurge");
-                if (lock == null) {
-                    s_logger.debug("Couldn't get the global lock");
-                    return;
-                }
-                if (!lock.lock(30)) {
-                    s_logger.debug("Couldn't lock the db");
-                    return;
-                }
-                try {
-                    final Calendar purgeCal = Calendar.getInstance();
-                    purgeCal.add(Calendar.DAY_OF_YEAR, -_alertPurgeDelay);
-                    final Date purgeTime = purgeCal.getTime();
-                    s_logger.debug("Deleting alerts older than: " + purgeTime.toString());
-                    final List<AlertVO> oldAlerts = _alertDao.listOlderAlerts(purgeTime);
-                    s_logger.debug("Found " + oldAlerts.size() + " events to be purged");
-                    for (final AlertVO alert : oldAlerts) {
-                        _alertDao.expunge(alert.getId());
-                    }
-                } catch (final Exception e) {
-                    s_logger.error("Exception ", e);
-                } finally {
-                    lock.unlock();
-                }
-            } catch (final Exception e) {
-                s_logger.error("Exception ", e);
-            }
-        }
-    }
-
-    private SecondaryStorageVmVO startSecondaryStorageVm(final long instanceId) {
-        return _secStorageVmMgr.startSecStorageVm(instanceId);
-    }
-
-    private SecondaryStorageVmVO stopSecondaryStorageVm(final VMInstanceVO systemVm, final boolean isForced) throws ResourceUnavailableException, OperationTimedoutException,
-    ConcurrentOperationException {
-
-        _itMgr.advanceStop(systemVm.getUuid(), isForced);
-        return _secStorageVmDao.findById(systemVm.getId());
-    }
-
-    public SecondaryStorageVmVO rebootSecondaryStorageVm(final long instanceId) {
-        _secStorageVmMgr.rebootSecStorageVm(instanceId);
-        return _secStorageVmDao.findById(instanceId);
-    }
-
-    protected SecondaryStorageVmVO destroySecondaryStorageVm(final long instanceId) {
-        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(instanceId);
-        if (_secStorageVmMgr.destroySecStorageVm(instanceId)) {
-            return secStorageVm;
-        }
-        return null;
-    }
-
-    @Override
-    public Pair<List<? extends VirtualMachine>, Integer> searchForSystemVm(final ListSystemVMsCmd cmd) {
-        final String type = cmd.getSystemVmType();
-        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
-        final Long id = cmd.getId();
-        final String name = cmd.getSystemVmName();
-        final String state = cmd.getState();
-        final String keyword = cmd.getKeyword();
-        final Long podId = cmd.getPodId();
-        final Long hostId = cmd.getHostId();
-        final Long storageId = cmd.getStorageId();
-
-        final Filter searchFilter = new Filter(VMInstanceVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        final SearchBuilder<VMInstanceVO> sb = _vmInstanceDao.createSearchBuilder();
-
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-        sb.and("hostName", sb.entity().getHostName(), SearchCriteria.Op.LIKE);
-        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
-        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
-        sb.and("podId", sb.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
-        sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ);
-        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
-        sb.and("nulltype", sb.entity().getType(), SearchCriteria.Op.IN);
-
-        if (storageId != null) {
-            final SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
-            volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
-            sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
-        }
-
-        final SearchCriteria<VMInstanceVO> sc = sb.create();
-
-        if (keyword != null) {
-            final SearchCriteria<VMInstanceVO> ssc = _vmInstanceDao.createSearchCriteria();
-            ssc.addOr("hostName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-
-            sc.addAnd("hostName", SearchCriteria.Op.SC, ssc);
-        }
-
-        if (id != null) {
-            sc.setParameters("id", id);
-        }
-
-        if (name != null) {
-            sc.setParameters("hostName", name);
-        }
-        if (state != null) {
-            sc.setParameters("state", state);
-        }
-        if (zoneId != null) {
-            sc.setParameters("dataCenterId", zoneId);
-        }
-        if (podId != null) {
-            sc.setParameters("podId", podId);
-        }
-        if (hostId != null) {
-            sc.setParameters("hostId", hostId);
-        }
-
-        if (type != null) {
-            sc.setParameters("type", type);
-        } else {
-            sc.setParameters("nulltype", VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy);
-        }
-
-        if (storageId != null) {
-            sc.setJoinParameters("volumeSearch", "poolId", storageId);
-        }
-
-        final Pair<List<VMInstanceVO>, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends VirtualMachine>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public VirtualMachine.Type findSystemVMTypeById(final long instanceId) {
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(instanceId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-        if (systemVm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm of specified instanceId");
-            ex.addProxyObject(String.valueOf(instanceId), "instanceId");
-            throw ex;
-        }
-        return systemVm.getType();
-    }
-
-    @Override
-    @ActionEvent(eventType = "", eventDescription = "", async = true)
-    public VirtualMachine startSystemVM(final long vmId) {
-
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-        if (systemVm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-        if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_START, "starting console proxy Vm");
-            return startConsoleProxy(vmId);
-        } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_START, "starting secondary storage Vm");
-            return startSecondaryStorageVm(vmId);
-        } else {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm with specified vmId");
-            ex.addProxyObject(systemVm.getUuid(), "vmId");
-            throw ex;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = "", eventDescription = "", async = true)
-    public VMInstanceVO stopSystemVM(final StopSystemVmCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
-        final Long id = cmd.getId();
-
-        // verify parameters
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-        if (systemVm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
-            ex.addProxyObject(id.toString(), "vmId");
-            throw ex;
-        }
-
-        try {
-            if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) {
-                ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_STOP, "stopping console proxy Vm");
-                return stopConsoleProxy(systemVm, cmd.isForced());
-            } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
-                ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_STOP, "stopping secondary storage Vm");
-                return stopSecondaryStorageVm(systemVm, cmd.isForced());
-            }
-            return null;
-        } catch (final OperationTimedoutException e) {
-            throw new CloudRuntimeException("Unable to stop " + systemVm, e);
-        }
-    }
-
-    @Override
-    public VMInstanceVO rebootSystemVM(final RebootSystemVmCmd cmd) {
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-
-        if (systemVm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
-            ex.addProxyObject(cmd.getId().toString(), "vmId");
-            throw ex;
-        }
-
-        if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy Vm");
-            return rebootConsoleProxy(cmd.getId());
-        } else {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_REBOOT, "rebooting secondary storage Vm");
-            return rebootSecondaryStorageVm(cmd.getId());
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = "", eventDescription = "", async = true)
-    public VMInstanceVO destroySystemVM(final DestroySystemVmCmd cmd) {
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-
-        if (systemVm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
-            ex.addProxyObject(cmd.getId().toString(), "vmId");
-            throw ex;
-        }
-
-        if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_DESTROY, "destroying console proxy Vm");
-            return destroyConsoleProxy(cmd.getId());
-        } else {
-            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_DESTROY, "destroying secondary storage Vm");
-            return destroySecondaryStorageVm(cmd.getId());
-        }
-    }
-
-    private String signRequest(final String request, final String key) {
-        try {
-            s_logger.info("Request: " + request);
-            s_logger.info("Key: " + key);
-
-            if (key != null && request != null) {
-                final Mac mac = Mac.getInstance("HmacSHA1");
-                final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
-                mac.init(keySpec);
-                mac.update(request.getBytes());
-                final byte[] encryptedBytes = mac.doFinal();
-                return new String(Base64.encodeBase64(encryptedBytes));
-            }
-        } catch (final Exception ex) {
-            s_logger.error("unable to sign request", ex);
-        }
-        return null;
-    }
-
-    @Override
-    public ArrayList<String> getCloudIdentifierResponse(final long userId) {
-        final Account caller = getCaller();
-
-        // verify that user exists
-        User user = _accountMgr.getUserIncludingRemoved(userId);
-        if (user == null || user.getRemoved() != null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find active user of specified id");
-            ex.addProxyObject(String.valueOf(userId), "userId");
-            throw ex;
-        }
-
-        // check permissions
-        _accountMgr.checkAccess(caller, null, true, _accountMgr.getAccount(user.getAccountId()));
-
-        String cloudIdentifier = _configDao.getValue("cloud.identifier");
-        if (cloudIdentifier == null) {
-            cloudIdentifier = "";
-        }
-
-        String signature = "";
-        try {
-            // get the user obj to get his secret key
-            user = _accountMgr.getActiveUser(userId);
-            final String secretKey = user.getSecretKey();
-            final String input = cloudIdentifier;
-            signature = signRequest(input, secretKey);
-        } catch (final Exception e) {
-            s_logger.warn("Exception whilst creating a signature:" + e);
-        }
-
-        final ArrayList<String> cloudParams = new ArrayList<String>();
-        cloudParams.add(cloudIdentifier);
-        cloudParams.add(signature);
-
-        return cloudParams;
-    }
-
-    @Override
-    public Map<String, Object> listCapabilities(final ListCapabilitiesCmd cmd) {
-        final Map<String, Object> capabilities = new HashMap<String, Object>();
-
-        final Account caller = getCaller();
-        boolean securityGroupsEnabled = false;
-        boolean elasticLoadBalancerEnabled = false;
-        boolean KVMSnapshotEnabled = false;
-        String supportELB = "false";
-        final List<NetworkVO> networks = _networkDao.listSecurityGroupEnabledNetworks();
-        if (networks != null && !networks.isEmpty()) {
-            securityGroupsEnabled = true;
-            final String elbEnabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
-            elasticLoadBalancerEnabled = elbEnabled == null ? false : Boolean.parseBoolean(elbEnabled);
-            if (elasticLoadBalancerEnabled) {
-                final String networkType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key());
-                if (networkType != null) {
-                    supportELB = networkType;
-                }
-            }
-        }
-
-        final long diskOffMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
-        final long diskOffMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
-        KVMSnapshotEnabled = Boolean.parseBoolean(_configDao.getValue("KVM.snapshot.enabled"));
-
-        final boolean userPublicTemplateEnabled = TemplateManager.AllowPublicUserTemplates.valueIn(caller.getId());
-
-        // add some parameters UI needs to handle API throttling
-        final boolean apiLimitEnabled = Boolean.parseBoolean(_configDao.getValue(Config.ApiLimitEnabled.key()));
-        final Integer apiLimitInterval = Integer.valueOf(_configDao.getValue(Config.ApiLimitInterval.key()));
-        final Integer apiLimitMax = Integer.valueOf(_configDao.getValue(Config.ApiLimitMax.key()));
-
-        final boolean allowUserViewDestroyedVM = (QueryManagerImpl.AllowUserViewDestroyedVM.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));
-        final boolean allowUserExpungeRecoverVM = (UserVmManager.AllowUserExpungeRecoverVm.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));
-
-        // check if region-wide secondary storage is used
-        boolean regionSecondaryEnabled = false;
-        final List<ImageStoreVO> imgStores = _imgStoreDao.findRegionImageStores();
-        if (imgStores != null && imgStores.size() > 0) {
-            regionSecondaryEnabled = true;
-        }
-
-        capabilities.put("securityGroupsEnabled", securityGroupsEnabled);
-        capabilities.put("userPublicTemplateEnabled", userPublicTemplateEnabled);
-        capabilities.put("cloudStackVersion", getVersion());
-        capabilities.put("supportELB", supportELB);
-        capabilities.put("projectInviteRequired", _projectMgr.projectInviteRequired());
-        capabilities.put("allowusercreateprojects", _projectMgr.allowUserToCreateProject());
-        capabilities.put("customDiskOffMinSize", diskOffMinSize);
-        capabilities.put("customDiskOffMaxSize", diskOffMaxSize);
-        capabilities.put("regionSecondaryEnabled", regionSecondaryEnabled);
-        capabilities.put("KVMSnapshotEnabled", KVMSnapshotEnabled);
-        capabilities.put("allowUserViewDestroyedVM", allowUserViewDestroyedVM);
-        capabilities.put("allowUserExpungeRecoverVM", allowUserExpungeRecoverVM);
-        if (apiLimitEnabled) {
-            capabilities.put("apiLimitInterval", apiLimitInterval);
-            capabilities.put("apiLimitMax", apiLimitMax);
-        }
-
-        return capabilities;
-    }
-
-    @Override
-    public GuestOSVO getGuestOs(final Long guestOsId) {
-        return _guestOSDao.findById(guestOsId);
-    }
-
-    @Override
-    public GuestOSHypervisorVO getGuestOsHypervisor(final Long guestOsHypervisorId) {
-        return _guestOSHypervisorDao.findById(guestOsHypervisorId);
-    }
-
-    @Override
-    public InstanceGroupVO updateVmGroup(final UpdateVMGroupCmd cmd) {
-        final Account caller = getCaller();
-        final Long groupId = cmd.getId();
-        final String groupName = cmd.getGroupName();
-
-        // Verify input parameters
-        final InstanceGroupVO group = _vmGroupDao.findById(groupId.longValue());
-        if (group == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a vm group with specified groupId");
-            ex.addProxyObject(groupId.toString(), "groupId");
-            throw ex;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, group);
-
-        // Check if name is already in use by this account (exclude this group)
-        final boolean isNameInUse = _vmGroupDao.isNameInUse(group.getAccountId(), groupName);
-
-        if (isNameInUse && !group.getName().equals(groupName)) {
-            throw new InvalidParameterValueException("Unable to update vm group, a group with name " + groupName + " already exists for account");
-        }
-
-        if (groupName != null) {
-            _vmGroupDao.updateVmGroup(groupId, groupName);
-        }
-
-        return _vmGroupDao.findById(groupId);
-    }
-
-    @Override
-    public String getVersion() {
-        final Class<?> c = ManagementServer.class;
-        final String fullVersion = c.getPackage().getImplementationVersion();
-        if (fullVersion != null && fullVersion.length() > 0) {
-            return fullVersion;
-        }
-
-        return "unknown";
-    }
-
-    @Override
-    @DB
-    public String uploadCertificate(final UploadCustomCertificateCmd cmd) {
-        if (cmd.getPrivateKey() != null && cmd.getAlias() != null) {
-            throw new InvalidParameterValueException("Can't change the alias for private key certification");
-        }
-
-        if (cmd.getPrivateKey() == null) {
-            if (cmd.getAlias() == null) {
-                throw new InvalidParameterValueException("alias can't be empty, if it's a certification chain");
-            }
-
-            if (cmd.getCertIndex() == null) {
-                throw new InvalidParameterValueException("index can't be empty, if it's a certifciation chain");
-            }
-        }
-
-        final String certificate = cmd.getCertificate();
-        final String key = cmd.getPrivateKey();
-
-        if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) {
-            throw new InvalidParameterValueException("Failed to pass certificate validation check");
-        }
-
-        if (cmd.getPrivateKey() != null) {
-            _ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, cmd.getDomainSuffix());
-
-            // Reboot ssvm here since private key is present - meaning server cert being passed
-            final List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting);
-            for (final SecondaryStorageVmVO ssVmVm : alreadyRunning) {
-                _secStorageVmMgr.rebootSecStorageVm(ssVmVm.getId());
-            }
-        } else {
-            _ksMgr.saveCertificate(cmd.getAlias(), certificate, cmd.getCertIndex(), cmd.getDomainSuffix());
-        }
-
-        _consoleProxyMgr.setManagementState(ConsoleProxyManagementState.ResetSuspending);
-        return "Certificate has been successfully updated, if its the server certificate we would reboot all " +
-        "running console proxy VMs and secondary storage VMs to propagate the new certificate, " +
-        "please give a few minutes for console access and storage services service to be up and working again";
-    }
-
-    @Override
-    public List<String> getHypervisors(final Long zoneId) {
-        final List<String> result = new ArrayList<String>();
-        final String hypers = _configDao.getValue(Config.HypervisorList.key());
-        final String[] hypervisors = hypers.split(",");
-
-        if (zoneId != null) {
-            if (zoneId.longValue() == -1L) {
-                final List<DataCenterVO> zones = _dcDao.listAll();
-
-                for (final String hypervisor : hypervisors) {
-                    int hyperCount = 0;
-                    for (final DataCenterVO zone : zones) {
-                        final List<ClusterVO> clusters = _clusterDao.listByDcHyType(zone.getId(), hypervisor);
-                        if (!clusters.isEmpty()) {
-                            hyperCount++;
-                        }
-                    }
-                    if (hyperCount == zones.size()) {
-                        result.add(hypervisor);
-                    }
-                }
-            } else {
-                final List<ClusterVO> clustersForZone = _clusterDao.listByZoneId(zoneId);
-                for (final ClusterVO cluster : clustersForZone) {
-                    result.add(cluster.getHypervisorType().toString());
-                }
-            }
-
-        } else {
-            return Arrays.asList(hypervisors);
-        }
-        return result;
-    }
-
-    @Override
-    public SSHKeyPair createSSHKeyPair(final CreateSSHKeyPairCmd cmd) {
-        final Account caller = getCaller();
-        final String accountName = cmd.getAccountName();
-        final Long domainId = cmd.getDomainId();
-        final Long projectId = cmd.getProjectId();
-
-        final Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
-
-        final SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
-        if (s != null) {
-            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists.");
-        }
-
-        final SSHKeysHelper keys = new SSHKeysHelper(sshKeyLength.value());
-
-        final String name = cmd.getName();
-        final String publicKey = keys.getPublicKey();
-        final String fingerprint = keys.getPublicKeyFingerPrint();
-        final String privateKey = keys.getPrivateKey();
-
-        return createAndSaveSSHKeyPair(name, fingerprint, publicKey, privateKey, owner);
-    }
-
-    @Override
-    public boolean deleteSSHKeyPair(final DeleteSSHKeyPairCmd cmd) {
-        final Account caller = getCaller();
-        final String accountName = cmd.getAccountName();
-        final Long domainId = cmd.getDomainId();
-        final Long projectId = cmd.getProjectId();
-
-        Account owner = null;
-        try {
-            owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
-        } catch (InvalidParameterValueException ex) {
-            if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && accountName != null && domainId != null) {
-                owner = _accountDao.findAccountIncludingRemoved(accountName, domainId);
-            }
-            if (owner == null) {
-                throw ex;
-            }
-        }
-
-        final SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
-        if (s == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account "
-                    + owner.getAccountName() + " in specified domain id");
-            final DomainVO domain = ApiDBUtils.findDomainById(owner.getDomainId());
-            String domainUuid = String.valueOf(owner.getDomainId());
-            if (domain != null) {
-                domainUuid = domain.getUuid();
-            }
-            ex.addProxyObject(domainUuid, "domainId");
-            throw ex;
-        }
-
-        return _sshKeyPairDao.deleteByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
-    }
-
-    @Override
-    public Pair<List<? extends SSHKeyPair>, Integer> listSSHKeyPairs(final ListSSHKeyPairsCmd cmd) {
-        final String name = cmd.getName();
-        final String fingerPrint = cmd.getFingerprint();
-        final String keyword = cmd.getKeyword();
-
-        final Account caller = getCaller();
-        final List<Long> permittedAccounts = new ArrayList<Long>();
-
-        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
-                cmd.getDomainId(), cmd.isRecursive(), null);
-        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject,
-                cmd.listAll(), false);
-        final Long domainId = domainIdRecursiveListProject.first();
-        final Boolean isRecursive = domainIdRecursiveListProject.second();
-        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-        final SearchBuilder<SSHKeyPairVO> sb = _sshKeyPairDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-        final Filter searchFilter = new Filter(SSHKeyPairVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-
-        final SearchCriteria<SSHKeyPairVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
-        if (name != null) {
-            sc.addAnd("name", SearchCriteria.Op.EQ, name);
-        }
-
-        if (fingerPrint != null) {
-            sc.addAnd("fingerprint", SearchCriteria.Op.EQ, fingerPrint);
-        }
-
-        if (keyword != null) {
-            sc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addOr("fingerprint", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-        }
-
-        final Pair<List<SSHKeyPairVO>, Integer> result = _sshKeyPairDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends SSHKeyPair>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_SSH_KEYPAIR, eventDescription = "registering ssh keypair", async = true)
-    public SSHKeyPair registerSSHKeyPair(final RegisterSSHKeyPairCmd cmd) {
-        final Account owner = getOwner(cmd);
-        checkForKeyByName(cmd, owner);
-        checkForKeyByPublicKey(cmd, owner);
-
-        final String name = cmd.getName();
-        String key = cmd.getPublicKey();
-
-        final String publicKey = getPublicKeyFromKeyKeyMaterial(key);
-        final String fingerprint = getFingerprint(publicKey);
-
-        return createAndSaveSSHKeyPair(name, fingerprint, publicKey, null, owner);
-    }
-
-    /**
-     * @param cmd
-     * @param owner
-     * @throws InvalidParameterValueException
-     */
-    private void checkForKeyByPublicKey(final RegisterSSHKeyPairCmd cmd, final Account owner) throws InvalidParameterValueException {
-        final SSHKeyPairVO existingPair = _sshKeyPairDao.findByPublicKey(owner.getAccountId(), owner.getDomainId(), getPublicKeyFromKeyKeyMaterial(cmd.getPublicKey()));
-        if (existingPair != null) {
-            throw new InvalidParameterValueException("A key pair with key '" + cmd.getPublicKey() + "' already exists for this account.");
-        }
-    }
-
-    /**
-     * @param cmd
-     * @param owner
-     * @throws InvalidParameterValueException
-     */
-    protected void checkForKeyByName(final RegisterSSHKeyPairCmd cmd, final Account owner) throws InvalidParameterValueException {
-        final SSHKeyPairVO existingPair = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
-        if (existingPair != null) {
-            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists for this account.");
-        }
-    }
-
-    /**
-     * @param publicKey
-     * @return
-     */
-    private String getFingerprint(final String publicKey) {
-        final String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(publicKey);
-        return fingerprint;
-    }
-
-    /**
-     * @param key
-     * @return
-     * @throws InvalidParameterValueException
-     */
-    protected String getPublicKeyFromKeyKeyMaterial(final String key) throws InvalidParameterValueException {
-        final String publicKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(key);
-
-        if (publicKey == null) {
-            throw new InvalidParameterValueException("Public key is invalid");
-        }
-        return publicKey;
-    }
-
-    /**
-     * @param cmd
-     * @return
-     */
-    protected Account getOwner(final RegisterSSHKeyPairCmd cmd) {
-        final Account caller = getCaller();
-
-        final Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
-        return owner;
-    }
-
-    /**
-     * @return
-     */
-    protected Account getCaller() {
-        final Account caller = CallContext.current().getCallingAccount();
-        return caller;
-    }
-
-    private SSHKeyPair createAndSaveSSHKeyPair(final String name, final String fingerprint, final String publicKey, final String privateKey, final Account owner) {
-        final SSHKeyPairVO newPair = new SSHKeyPairVO();
-
-        newPair.setAccountId(owner.getAccountId());
-        newPair.setDomainId(owner.getDomainId());
-        newPair.setName(name);
-        newPair.setFingerprint(fingerprint);
-        newPair.setPublicKey(publicKey);
-        newPair.setPrivateKey(privateKey); // transient; not saved.
-
-        _sshKeyPairDao.persist(newPair);
-
-        return newPair;
-    }
-
-    @Override
-    public String getVMPassword(final GetVMPasswordCmd cmd) {
-        final Account caller = getCaller();
-
-        final UserVmVO vm = _userVmDao.findById(cmd.getId());
-        if (vm == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("No VM with specified id found.");
-            ex.addProxyObject(cmd.getId().toString(), "vmId");
-            throw ex;
-        }
-
-        // make permission check
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        _userVmDao.loadDetails(vm);
-        final String password = vm.getDetail("Encrypted.Password");
-        if (password == null || password.equals("")) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("No password for VM with specified id found. "
-                    + "If VM is created from password enabled template and SSH keypair is assigned to VM then only password can be retrieved.");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        return password;
-    }
-
-    private boolean updateHostsInCluster(final UpdateHostPasswordCmd command) {
-        // get all the hosts in this cluster
-        final List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(command.getClusterId());
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                for (final HostVO h : hosts) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Changing password for host name = " + h.getName());
-                    }
-                    // update password for this host
-                    final DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME);
-                    if (nv.getValue().equals(command.getUsername())) {
-                        final DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.PASSWORD);
-                        nvp.setValue(DBEncryptionUtil.encrypt(command.getPassword()));
-                        _detailsDao.persist(nvp);
-                    } else {
-                        // if one host in the cluster has diff username then
-                        // rollback to maintain consistency
-                        throw new InvalidParameterValueException("The username is not same for all hosts, please modify passwords for individual hosts.");
-                    }
-                }
-            }
-        });
-        return true;
-    }
-
-    /**
-     * This method updates the password of all hosts in a given cluster.
-     */
-    @Override
-    @DB
-    public boolean updateClusterPassword(final UpdateHostPasswordCmd command) {
-        if (command.getClusterId() == null) {
-            throw new InvalidParameterValueException("You should provide a cluster id.");
-        }
-
-        final ClusterVO cluster = ApiDBUtils.findClusterById(command.getClusterId());
-        if (cluster == null || !supportedHypervisors.contains(cluster.getHypervisorType())) {
-            throw new InvalidParameterValueException("This operation is not supported for this hypervisor type");
-        }
-        return updateHostsInCluster(command);
-    }
-
-    @Override
-    @DB
-    public boolean updateHostPassword(final UpdateHostPasswordCmd cmd) {
-        if (cmd.getHostId() == null) {
-            throw new InvalidParameterValueException("You should provide an host id.");
-        }
-
-        final HostVO host = _hostDao.findById(cmd.getHostId());
-
-        if (host.getHypervisorType() == HypervisorType.XenServer) {
-            throw new InvalidParameterValueException("Single host update is not supported by XenServer hypervisors. Please try again informing the Cluster ID.");
-        }
-
-        if (!supportedHypervisors.contains(host.getHypervisorType())) {
-            throw new InvalidParameterValueException("This operation is not supported for this hypervisor type");
-        }
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(final TransactionStatus status) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Changing password for host name = " + host.getName());
-                }
-                // update password for this host
-                final DetailVO nv = _detailsDao.findDetail(host.getId(), ApiConstants.USERNAME);
-                if (nv.getValue().equals(cmd.getUsername())) {
-                    final DetailVO nvp = _detailsDao.findDetail(host.getId(), ApiConstants.PASSWORD);
-                    nvp.setValue(DBEncryptionUtil.encrypt(cmd.getPassword()));
-                    _detailsDao.persist(nvp);
-                } else {
-                    // if one host in the cluster has diff username then
-                    // rollback to maintain consistency
-                    throw new InvalidParameterValueException("The username is not same for the hosts..");
-                }
-            }
-        });
-        return true;
-    }
-
-    @Override
-    public String[] listEventTypes() {
-        final Object eventObj = new EventTypes();
-        final Class<EventTypes> c = EventTypes.class;
-        final Field[] fields = c.getFields();
-        final String[] eventTypes = new String[fields.length];
-        try {
-            int i = 0;
-            for (final Field field : fields) {
-                eventTypes[i++] = field.get(eventObj).toString();
-            }
-            return eventTypes;
-        } catch (final IllegalArgumentException e) {
-            s_logger.error("Error while listing Event Types", e);
-        } catch (final IllegalAccessException e) {
-            s_logger.error("Error while listing Event Types", e);
-        }
-        return null;
-    }
-
-    @Override
-    public Pair<List<? extends HypervisorCapabilities>, Integer> listHypervisorCapabilities(final Long id, final HypervisorType hypervisorType, final String keyword, final Long startIndex,
-            final Long pageSizeVal) {
-        final Filter searchFilter = new Filter(HypervisorCapabilitiesVO.class, "id", true, startIndex, pageSizeVal);
-        final SearchCriteria<HypervisorCapabilitiesVO> sc = _hypervisorCapabilitiesDao.createSearchCriteria();
-
-        if (id != null) {
-            sc.addAnd("id", SearchCriteria.Op.EQ, id);
-        }
-
-        if (hypervisorType != null) {
-            sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisorType);
-        }
-
-        if (keyword != null) {
-            final SearchCriteria<HypervisorCapabilitiesVO> ssc = _hypervisorCapabilitiesDao.createSearchCriteria();
-            ssc.addOr("hypervisorType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
-            sc.addAnd("hypervisorType", SearchCriteria.Op.SC, ssc);
-        }
-
-        final Pair<List<HypervisorCapabilitiesVO>, Integer> result = _hypervisorCapabilitiesDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<? extends HypervisorCapabilities>, Integer>(result.first(), result.second());
-    }
-
-    @Override
-    public HypervisorCapabilities updateHypervisorCapabilities(final Long id, final Long maxGuestsLimit, final Boolean securityGroupEnabled) {
-        HypervisorCapabilitiesVO hpvCapabilities = _hypervisorCapabilitiesDao.findById(id, true);
-
-        if (hpvCapabilities == null) {
-            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find the hypervisor capabilities for specified id");
-            ex.addProxyObject(id.toString(), "Id");
-            throw ex;
-        }
-
-        final boolean updateNeeded = maxGuestsLimit != null || securityGroupEnabled != null;
-        if (!updateNeeded) {
-            return hpvCapabilities;
-        }
-
-        hpvCapabilities = _hypervisorCapabilitiesDao.createForUpdate(id);
-
-        if (maxGuestsLimit != null) {
-            hpvCapabilities.setMaxGuestsLimit(maxGuestsLimit);
-        }
-
-        if (securityGroupEnabled != null) {
-            hpvCapabilities.setSecurityGroupEnabled(securityGroupEnabled);
-        }
-
-        if (_hypervisorCapabilitiesDao.update(id, hpvCapabilities)) {
-            hpvCapabilities = _hypervisorCapabilitiesDao.findById(id);
-            CallContext.current().setEventDetails("Hypervisor Capabilities id=" + hpvCapabilities.getId());
-            return hpvCapabilities;
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "Upgrading system VM", async = true)
-    public VirtualMachine upgradeSystemVM(final ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException,
-    ConcurrentOperationException {
-
-        final VMInstanceVO vmInstance = _vmInstanceDao.findById(cmd.getId());
-        if (vmInstance.getHypervisorType() == HypervisorType.XenServer && vmInstance.getState().equals(State.Running)) {
-            throw new InvalidParameterValueException("Dynamic Scaling operation is not permitted for this hypervisor on system vm");
-        }
-        final boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId(), cmd.getDetails());
-        if (result) {
-            final VirtualMachine vm = _vmInstanceDao.findById(cmd.getId());
-            return vm;
-        } else {
-            throw new CloudRuntimeException("Failed to upgrade System VM");
-        }
-    }
-
-    @Override
-    public VirtualMachine upgradeSystemVM(final UpgradeSystemVMCmd cmd) {
-        final Long systemVmId = cmd.getId();
-        final Long serviceOfferingId = cmd.getServiceOfferingId();
-        return upgradeStoppedSystemVm(systemVmId, serviceOfferingId, cmd.getDetails());
-
-    }
-
-    private VirtualMachine upgradeStoppedSystemVm(final Long systemVmId, final Long serviceOfferingId, final Map<String, String> customparameters) {
-        final Account caller = getCaller();
-
-        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(systemVmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
-        if (systemVm == null) {
-            throw new InvalidParameterValueException("Unable to find SystemVm with id " + systemVmId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, systemVm);
-
-        // Check that the specified service offering ID is valid
-        ServiceOfferingVO newServiceOffering = _offeringDao.findById(serviceOfferingId);
-        final ServiceOfferingVO currentServiceOffering = _offeringDao.findById(systemVmId, systemVm.getServiceOfferingId());
-        if (newServiceOffering.isDynamic()) {
-            newServiceOffering.setDynamicFlag(true);
-            _userVmMgr.validateCustomParameters(newServiceOffering, customparameters);
-            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customparameters);
-        }
-        _itMgr.checkIfCanUpgrade(systemVm, newServiceOffering);
-
-        final boolean result = _itMgr.upgradeVmDb(systemVmId, serviceOfferingId);
-
-        if (newServiceOffering.isDynamic()) {
-            //save the custom values to the database.
-            _userVmMgr.saveCustomOfferingDetails(systemVmId, newServiceOffering);
-        }
-        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
-            _userVmMgr.removeCustomOfferingDetails(systemVmId);
-        }
-
-        if (result) {
-            return _vmInstanceDao.findById(systemVmId);
-        } else {
-            throw new CloudRuntimeException("Unable to upgrade system vm " + systemVm);
-        }
-
-    }
-
-    private void enableAdminUser(final String password) {
-        String encodedPassword = null;
-
-        final UserVO adminUser = _userDao.getUser(2);
-        if (adminUser  == null) {
-            final String msg = "CANNOT find admin user";
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        if (adminUser.getState() == Account.State.disabled) {
-            // This means its a new account, set the password using the
-            // authenticator
-
-            for (final UserAuthenticator authenticator : _userPasswordEncoders) {
-                encodedPassword = authenticator.encode(password);
-                if (encodedPassword != null) {
-                    break;
-                }
-            }
-
-            adminUser.setPassword(encodedPassword);
-            adminUser.setState(Account.State.enabled);
-            _userDao.persist(adminUser);
-            s_logger.info("Admin user enabled");
-        }
-
-    }
-
-    @Override
-    public List<String> listDeploymentPlanners() {
-        final List<String> plannersAvailable = new ArrayList<String>();
-        for (final DeploymentPlanner planner : _planners) {
-            plannersAvailable.add(planner.getName());
-        }
-
-        return plannersAvailable;
-    }
-
-    @Override
-    public void cleanupVMReservations() {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Processing cleanupVMReservations");
-        }
-
-        _dpMgr.cleanupVMReservations();
-    }
-
-    public List<StoragePoolAllocator> getStoragePoolAllocators() {
-        return _storagePoolAllocators;
-    }
-
-    @Inject
-    public void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators) {
-        _storagePoolAllocators = storagePoolAllocators;
-    }
-
-    public LockMasterListener getLockMasterListener() {
-        return _lockMasterListener;
-    }
-
-    public void setLockMasterListener(final LockMasterListener lockMasterListener) {
-        _lockMasterListener = lockMasterListener;
-    }
-
-}
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
deleted file mode 100644
index b66fa5f..0000000
--- a/server/src/com/cloud/server/StatsCollector.java
+++ /dev/null
@@ -1,1339 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.utils.graphite.GraphiteClient;
-import org.apache.cloudstack.utils.graphite.GraphiteException;
-import org.apache.cloudstack.utils.usage.UsageUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.HostStatsEntry;
-import com.cloud.agent.api.PerformanceMonitorCommand;
-import com.cloud.agent.api.VgpuTypesInfo;
-import com.cloud.agent.api.VmDiskStatsEntry;
-import com.cloud.agent.api.VmNetworkStatsEntry;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.VolumeStatsEntry;
-import com.cloud.cluster.ManagementServerHostVO;
-import com.cloud.cluster.dao.ManagementServerHostDao;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.gpu.dao.HostGpuGroupsDao;
-import com.cloud.host.Host;
-import com.cloud.host.HostStats;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.as.AutoScaleManager;
-import com.cloud.network.as.AutoScalePolicyConditionMapVO;
-import com.cloud.network.as.AutoScalePolicyVO;
-import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO;
-import com.cloud.network.as.AutoScaleVmGroupVO;
-import com.cloud.network.as.AutoScaleVmGroupVmMapVO;
-import com.cloud.network.as.AutoScaleVmProfileVO;
-import com.cloud.network.as.Condition.Operator;
-import com.cloud.network.as.ConditionVO;
-import com.cloud.network.as.Counter;
-import com.cloud.network.as.CounterVO;
-import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
-import com.cloud.network.as.dao.AutoScalePolicyDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
-import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
-import com.cloud.network.as.dao.AutoScaleVmProfileDao;
-import com.cloud.network.as.dao.ConditionDao;
-import com.cloud.network.as.dao.CounterDao;
-import com.cloud.org.Cluster;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.ImageStoreDetailsUtil;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StorageStats;
-import com.cloud.storage.VolumeStats;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.user.VmDiskStatisticsVO;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.user.dao.VmDiskStatisticsDao;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ComponentMethodInterceptable;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.net.MacAddress;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VmStats;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-/**
- * Provides real time stats for various agent resources up to x seconds
- *
- */
-@Component
-public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable, Configurable {
-
-    public static enum ExternalStatsProtocol {
-        NONE("none"), GRAPHITE("graphite");
-        String _type;
-
-        ExternalStatsProtocol(String type) {
-            _type = type;
-        }
-
-        @Override
-        public String toString() {
-            return _type;
-        }
-    }
-
-    public static final Logger s_logger = Logger.getLogger(StatsCollector.class.getName());
-
-    static final ConfigKey<Integer> vmDiskStatsInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.disk.stats.interval", "0",
-            "Interval (in seconds) to report vm disk statistics. Vm disk statistics will be disabled if this is set to 0 or less than 0.", false);
-    static final ConfigKey<Integer> vmDiskStatsIntervalMin = new ConfigKey<Integer>("Advanced", Integer.class, "vm.disk.stats.interval.min", "300",
-            "Minimal interval (in seconds) to report vm disk statistics. If vm.disk.stats.interval is smaller than this, use this to report vm disk statistics.", false);
-    static final ConfigKey<Integer> vmNetworkStatsInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.network.stats.interval", "0",
-            "Interval (in seconds) to report vm network statistics (for Shared networks). Vm network statistics will be disabled if this is set to 0 or less than 0.", false);
-    static final ConfigKey<Integer> vmNetworkStatsIntervalMin = new ConfigKey<Integer>("Advanced", Integer.class, "vm.network.stats.interval.min", "300",
-            "Minimal Interval (in seconds) to report vm network statistics (for Shared networks). If vm.network.stats.interval is smaller than this, use this to report vm network statistics.", false);
-    static final ConfigKey<Integer> StatsTimeout = new ConfigKey<Integer>("Advanced", Integer.class, "stats.timeout", "60000",
-            "The timeout for stats call in milli seconds.", true, ConfigKey.Scope.Cluster);
-
-    private static StatsCollector s_instance = null;
-
-    private ScheduledExecutorService _executor = null;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private UserVmManager _userVmMgr;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private VolumeDao _volsDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private StorageManager _storageManager;
-    @Inject
-    private DataStoreManager _dataStoreMgr;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private EndPointSelector _epSelector;
-    @Inject
-    private VmDiskStatisticsDao _vmDiskStatsDao;
-    @Inject
-    private ManagementServerHostDao _msHostDao;
-    @Inject
-    private UserStatisticsDao _userStatsDao;
-    @Inject
-    private NicDao _nicDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private AutoScaleVmGroupDao _asGroupDao;
-    @Inject
-    private AutoScaleVmGroupVmMapDao _asGroupVmDao;
-    @Inject
-    private AutoScaleManager _asManager;
-    @Inject
-    private VMInstanceDao _vmInstance;
-    @Inject
-    private AutoScaleVmGroupPolicyMapDao _asGroupPolicyDao;
-    @Inject
-    private AutoScalePolicyDao _asPolicyDao;
-    @Inject
-    private AutoScalePolicyConditionMapDao _asConditionMapDao;
-    @Inject
-    private ConditionDao _asConditionDao;
-    @Inject
-    private CounterDao _asCounterDao;
-    @Inject
-    private AutoScaleVmProfileDao _asProfileDao;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private HostGpuGroupsDao _hostGpuGroupsDao;
-    @Inject
-    private ImageStoreDetailsUtil imageStoreDetailsUtil;
-
-    private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
-    private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
-    private final Map<String, VolumeStats> _volumeStats = new ConcurrentHashMap<String, VolumeStats>();
-    private ConcurrentHashMap<Long, StorageStats> _storageStats = new ConcurrentHashMap<Long, StorageStats>();
-    private ConcurrentHashMap<Long, StorageStats> _storagePoolStats = new ConcurrentHashMap<Long, StorageStats>();
-
-    long hostStatsInterval = -1L;
-    long hostAndVmStatsInterval = -1L;
-    long storageStatsInterval = -1L;
-    long volumeStatsInterval = -1L;
-    long autoScaleStatsInterval = -1L;
-
-    List<Long> hostIds = null;
-    private double _imageStoreCapacityThreshold = 0.90;
-
-    String externalStatsPrefix = "";
-    String externalStatsHost = null;
-    int externalStatsPort = -1;
-    boolean externalStatsEnabled = false;
-    ExternalStatsProtocol externalStatsType = ExternalStatsProtocol.NONE;
-
-    private ScheduledExecutorService _diskStatsUpdateExecutor;
-    private int _usageAggregationRange = 1440;
-    private String _usageTimeZone = "GMT";
-    private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5;    // 5 seconds
-    private boolean _dailyOrHourly = false;
-
-    //private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
-
-    public static StatsCollector getInstance() {
-        return s_instance;
-    }
-
-    public static StatsCollector getInstance(Map<String, String> configs) {
-        s_instance.init(configs);
-        return s_instance;
-    }
-
-    public StatsCollector() {
-        s_instance = this;
-    }
-
-    @Override
-    public boolean start() {
-        init(_configDao.getConfiguration());
-        return true;
-    }
-
-    private void init(Map<String, String> configs) {
-        _executor = Executors.newScheduledThreadPool(6, new NamedThreadFactory("StatsCollector"));
-
-        hostStatsInterval = NumbersUtil.parseLong(configs.get("host.stats.interval"), 60000L);
-        hostAndVmStatsInterval = NumbersUtil.parseLong(configs.get("vm.stats.interval"), 60000L);
-        storageStatsInterval = NumbersUtil.parseLong(configs.get("storage.stats.interval"), 60000L);
-        volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), 600000L);
-        autoScaleStatsInterval = NumbersUtil.parseLong(configs.get("autoscale.stats.interval"), 60000L);
-
-        /* URI to send statistics to. Currently only Graphite is supported */
-        String externalStatsUri = configs.get("stats.output.uri");
-        if (externalStatsUri != null && !externalStatsUri.equals("")) {
-            try {
-                URI uri = new URI(externalStatsUri);
-                String scheme = uri.getScheme();
-
-                try {
-                    externalStatsType = ExternalStatsProtocol.valueOf(scheme.toUpperCase());
-                } catch (IllegalArgumentException e) {
-                    s_logger.info(scheme + " is not a valid protocol for external statistics. No statistics will be send.");
-                }
-
-                if (!StringUtils.isEmpty(uri.getHost())) {
-                    externalStatsHost = uri.getHost();
-                }
-
-                externalStatsPort = uri.getPort();
-
-                if (!StringUtils.isEmpty(uri.getPath())) {
-                    externalStatsPrefix = uri.getPath().substring(1);
-                }
-
-                /* Append a dot (.) to the prefix if it is set */
-                if (!StringUtils.isEmpty(externalStatsPrefix)) {
-                    externalStatsPrefix += ".";
-                } else {
-                    externalStatsPrefix = "";
-                }
-
-                externalStatsEnabled = true;
-            } catch (URISyntaxException e) {
-                s_logger.debug("Failed to parse external statistics URI: " + e.getMessage());
-            }
-        }
-
-        if (hostStatsInterval > 0) {
-            _executor.scheduleWithFixedDelay(new HostCollector(), 15000L, hostStatsInterval, TimeUnit.MILLISECONDS);
-        }
-
-        if (hostAndVmStatsInterval > 0) {
-            _executor.scheduleWithFixedDelay(new VmStatsCollector(), 15000L, hostAndVmStatsInterval, TimeUnit.MILLISECONDS);
-        }
-
-        if (storageStatsInterval > 0) {
-            _executor.scheduleWithFixedDelay(new StorageCollector(), 15000L, storageStatsInterval, TimeUnit.MILLISECONDS);
-        }
-
-        if (autoScaleStatsInterval > 0) {
-            _executor.scheduleWithFixedDelay(new AutoScaleMonitor(), 15000L, autoScaleStatsInterval, TimeUnit.MILLISECONDS);
-        }
-
-        if (vmDiskStatsInterval.value() > 0) {
-            if (vmDiskStatsInterval.value() < vmDiskStatsIntervalMin.value()) {
-                s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is smaller than vm.disk.stats.interval.min - " + vmDiskStatsIntervalMin.value() + ", so use vm.disk.stats.interval.min");
-                _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsIntervalMin.value(), vmDiskStatsIntervalMin.value(), TimeUnit.SECONDS);
-            } else {
-                _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval.value(), vmDiskStatsInterval.value(), TimeUnit.SECONDS);
-            }
-        } else {
-            s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm disk stats thread");
-        }
-
-        if (vmNetworkStatsInterval.value() > 0) {
-            if (vmNetworkStatsInterval.value() < vmNetworkStatsIntervalMin.value()) {
-                s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is smaller than vm.network.stats.interval.min - " + vmNetworkStatsIntervalMin.value() + ", so use vm.network.stats.interval.min");
-                _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsIntervalMin.value(), vmNetworkStatsIntervalMin.value(), TimeUnit.SECONDS);
-            } else {
-                _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsInterval.value(), vmNetworkStatsInterval.value(), TimeUnit.SECONDS);
-            }
-        } else {
-            s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm network stats thread");
-        }
-
-        if (volumeStatsInterval > 0) {
-            _executor.scheduleAtFixedRate(new VolumeStatsTask(), 15000L, volumeStatsInterval, TimeUnit.MILLISECONDS);
-        }
-
-        //Schedule disk stats update task
-        _diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater"));
-
-        String aggregationRange = configs.get("usage.stats.job.aggregation.range");
-        _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
-        _usageTimeZone = configs.get("usage.aggregation.timezone");
-        if (_usageTimeZone == null) {
-            _usageTimeZone = "GMT";
-        }
-        TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone);
-        Calendar cal = Calendar.getInstance(usageTimezone);
-        cal.setTime(new Date());
-        long endDate = 0;
-        int HOURLY_TIME = 60;
-        final int DAILY_TIME = 60 * 24;
-        if (_usageAggregationRange == DAILY_TIME) {
-            cal.set(Calendar.HOUR_OF_DAY, 0);
-            cal.set(Calendar.MINUTE, 0);
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MILLISECOND, 0);
-            cal.roll(Calendar.DAY_OF_YEAR, true);
-            cal.add(Calendar.MILLISECOND, -1);
-            endDate = cal.getTime().getTime();
-            _dailyOrHourly = true;
-        } else if (_usageAggregationRange == HOURLY_TIME) {
-            cal.set(Calendar.MINUTE, 0);
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MILLISECOND, 0);
-            cal.roll(Calendar.HOUR_OF_DAY, true);
-            cal.add(Calendar.MILLISECOND, -1);
-            endDate = cal.getTime().getTime();
-            _dailyOrHourly = true;
-        } else {
-            endDate = cal.getTime().getTime();
-            _dailyOrHourly = false;
-        }
-        if (_usageAggregationRange < UsageUtils.USAGE_AGGREGATION_RANGE_MIN) {
-            s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + UsageUtils.USAGE_AGGREGATION_RANGE_MIN);
-            _usageAggregationRange = UsageUtils.USAGE_AGGREGATION_RANGE_MIN;
-        }
-        _diskStatsUpdateExecutor.scheduleAtFixedRate(new VmDiskStatsUpdaterTask(), (endDate - System.currentTimeMillis()), (_usageAggregationRange * 60 * 1000),
-                TimeUnit.MILLISECONDS);
-
-    }
-
-    class HostCollector extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                s_logger.debug("HostStatsCollector is running...");
-
-                SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-                sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
-                sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.Storage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ConsoleProxy.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.LocalSecondaryStorage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.TrafficMonitor.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorageVM.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ExternalFirewall.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ExternalLoadBalancer.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.NetScalerControlCenter.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.L2Networking.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.BaremetalDhcp.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.BaremetalPxe.toString());
-                ConcurrentHashMap<Long, HostStats> hostStats = new ConcurrentHashMap<Long, HostStats>();
-                List<HostVO> hosts = _hostDao.search(sc, null);
-                for (HostVO host : hosts) {
-                    HostStatsEntry stats = (HostStatsEntry)_resourceMgr.getHostStatistics(host.getId());
-                    if (stats != null) {
-                        hostStats.put(host.getId(), stats);
-                    } else {
-                        s_logger.warn("Received invalid host stats for host: " + host.getId());
-                    }
-                }
-                _hostStats = hostStats;
-                // Get a subset of hosts with GPU support from the list of "hosts"
-                List<HostVO> gpuEnabledHosts = new ArrayList<HostVO>();
-                if (hostIds != null) {
-                    for (HostVO host : hosts) {
-                        if (hostIds.contains(host.getId())) {
-                            gpuEnabledHosts.add(host);
-                        }
-                    }
-                } else {
-                    // Check for all the hosts managed by CloudStack.
-                    gpuEnabledHosts = hosts;
-                }
-                for (HostVO host : gpuEnabledHosts) {
-                    HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = _resourceMgr.getGPUStatistics(host);
-                    if (groupDetails != null) {
-                        _resourceMgr.updateGPUDetails(host.getId(), groupDetails);
-                    }
-                }
-                hostIds = _hostGpuGroupsDao.listHostIds();
-            } catch (Throwable t) {
-                s_logger.error("Error trying to retrieve host stats", t);
-            }
-        }
-    }
-
-    class VmStatsCollector extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                s_logger.trace("VmStatsCollector is running...");
-
-                SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-                sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
-                sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.Storage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ConsoleProxy.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.LocalSecondaryStorage.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.TrafficMonitor.toString());
-                sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorageVM.toString());
-                List<HostVO> hosts = _hostDao.search(sc, null);
-
-                /* HashMap for metrics to be send to Graphite */
-                HashMap metrics = new HashMap<String, Integer>();
-
-                for (HostVO host : hosts) {
-                    List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
-                    List<Long> vmIds = new ArrayList<Long>();
-
-                    for (UserVmVO vm : vms) {
-                        vmIds.add(vm.getId());
-                    }
-
-                    try {
-                        HashMap<Long, VmStatsEntry> vmStatsById = _userVmMgr.getVirtualMachineStatistics(host.getId(), host.getName(), vmIds);
-
-                        if (vmStatsById != null) {
-                            VmStatsEntry statsInMemory = null;
-
-                            Set<Long> vmIdSet = vmStatsById.keySet();
-                            for (Long vmId : vmIdSet) {
-                                VmStatsEntry statsForCurrentIteration = vmStatsById.get(vmId);
-                                statsInMemory = (VmStatsEntry)_VmStats.get(vmId);
-
-                                if (statsInMemory == null) {
-                                    //no stats exist for this vm, directly persist
-                                    _VmStats.put(vmId, statsForCurrentIteration);
-                                } else {
-                                    //update each field
-                                    statsInMemory.setCPUUtilization(statsForCurrentIteration.getCPUUtilization());
-                                    statsInMemory.setNumCPUs(statsForCurrentIteration.getNumCPUs());
-                                    statsInMemory.setNetworkReadKBs(statsInMemory.getNetworkReadKBs() + statsForCurrentIteration.getNetworkReadKBs());
-                                    statsInMemory.setNetworkWriteKBs(statsInMemory.getNetworkWriteKBs() + statsForCurrentIteration.getNetworkWriteKBs());
-                                    statsInMemory.setDiskWriteKBs(statsInMemory.getDiskWriteKBs() + statsForCurrentIteration.getDiskWriteKBs());
-                                    statsInMemory.setDiskReadIOs(statsInMemory.getDiskReadIOs() + statsForCurrentIteration.getDiskReadIOs());
-                                    statsInMemory.setDiskWriteIOs(statsInMemory.getDiskWriteIOs() + statsForCurrentIteration.getDiskWriteIOs());
-                                    statsInMemory.setDiskReadKBs(statsInMemory.getDiskReadKBs() + statsForCurrentIteration.getDiskReadKBs());
-                                    statsInMemory.setMemoryKBs(statsForCurrentIteration.getMemoryKBs());
-                                    statsInMemory.setIntFreeMemoryKBs(statsForCurrentIteration.getIntFreeMemoryKBs());
-                                    statsInMemory.setTargetMemoryKBs(statsForCurrentIteration.getTargetMemoryKBs());
-
-                                    _VmStats.put(vmId, statsInMemory);
-                                }
-
-                                /**
-                                 * Add statistics to HashMap only when they should be send to a external stats collector
-                                 * Performance wise it seems best to only append to the HashMap when needed
-                                 */
-                                if (externalStatsEnabled) {
-                                    VMInstanceVO vmVO = _vmInstance.findById(vmId);
-                                    String vmName = vmVO.getUuid();
-
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".cpu.num", statsForCurrentIteration.getNumCPUs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".cpu.utilization", statsForCurrentIteration.getCPUUtilization());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".network.read_kbs", statsForCurrentIteration.getNetworkReadKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".network.write_kbs", statsForCurrentIteration.getNetworkWriteKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_kbs", statsForCurrentIteration.getDiskWriteKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_kbs", statsForCurrentIteration.getDiskReadKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_iops", statsForCurrentIteration.getDiskWriteIOs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_iops", statsForCurrentIteration.getDiskReadIOs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.total_kbs", statsForCurrentIteration.getMemoryKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.internalfree_kbs", statsForCurrentIteration.getIntFreeMemoryKBs());
-                                    metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.target_kbs", statsForCurrentIteration.getTargetMemoryKBs());
-
-                                }
-
-                            }
-
-                            /**
-                             * Send the metrics to a external stats collector
-                             * We send it on a per-host basis to prevent that we flood the host
-                             * Currently only Graphite is supported
-                             */
-                            if (!metrics.isEmpty()) {
-                                if (externalStatsType != null && externalStatsType == ExternalStatsProtocol.GRAPHITE) {
-
-                                    if (externalStatsPort == -1) {
-                                        externalStatsPort = 2003;
-                                    }
-
-                                    s_logger.debug("Sending VmStats of host " + host.getId() + " to Graphite host " + externalStatsHost + ":" + externalStatsPort);
-
-                                    try {
-                                        GraphiteClient g = new GraphiteClient(externalStatsHost, externalStatsPort);
-                                        g.sendMetrics(metrics);
-                                    } catch (GraphiteException e) {
-                                        s_logger.debug("Failed sending VmStats to Graphite host " + externalStatsHost + ":" + externalStatsPort + ": " + e.getMessage());
-                                    }
-
-                                    metrics.clear();
-                                }
-                            }
-                        }
-
-                    } catch (Exception e) {
-                        s_logger.debug("Failed to get VM stats for host with ID: " + host.getId());
-                        continue;
-                    }
-                }
-
-            } catch (Throwable t) {
-                s_logger.error("Error trying to retrieve VM stats", t);
-            }
-        }
-    }
-
-    public VmStats getVmStats(long id) {
-        return _VmStats.get(id);
-    }
-
-    class VmDiskStatsUpdaterTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            GlobalLock scanLock = GlobalLock.getInternLock("vm.disk.stats");
-            try {
-                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    //Check for ownership
-                    //msHost in UP state with min id should run the job
-                    ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
-                    if (msHost == null || (msHost.getMsid() != mgmtSrvrId)) {
-                        s_logger.debug("Skipping aggregate disk stats update");
-                        scanLock.unlock();
-                        return;
-                    }
-                    try {
-                        Transaction.execute(new TransactionCallbackNoReturn() {
-                            @Override
-                            public void doInTransactionWithoutResult(TransactionStatus status) {
-                                //get all stats with delta > 0
-                                List<VmDiskStatisticsVO> updatedVmNetStats = _vmDiskStatsDao.listUpdatedStats();
-                                for (VmDiskStatisticsVO stat : updatedVmNetStats) {
-                                    if (_dailyOrHourly) {
-                                        //update agg bytes
-                                        stat.setAggBytesRead(stat.getCurrentBytesRead() + stat.getNetBytesRead());
-                                        stat.setAggBytesWrite(stat.getCurrentBytesWrite() + stat.getNetBytesWrite());
-                                        stat.setAggIORead(stat.getCurrentIORead() + stat.getNetIORead());
-                                        stat.setAggIOWrite(stat.getCurrentIOWrite() + stat.getNetIOWrite());
-                                        _vmDiskStatsDao.update(stat.getId(), stat);
-                                    }
-                                }
-                                s_logger.debug("Successfully updated aggregate vm disk stats");
-                            }
-                        });
-                    } catch (Exception e) {
-                        s_logger.debug("Failed to update aggregate disk stats", e);
-                    } finally {
-                        scanLock.unlock();
-                    }
-                }
-            } catch (Exception e) {
-                s_logger.debug("Exception while trying to acquire disk stats lock", e);
-            } finally {
-                scanLock.releaseRef();
-            }
-        }
-    }
-
-    class VmDiskStatsTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            //Check for ownership
-            //msHost in UP state with min id should run the job
-            ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
-            if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){
-                s_logger.debug("Skipping collect vm disk stats from hosts");
-                return;
-            }
-            // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03.
-            s_logger.trace("Running VM disk stats ...");
-            try {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        s_logger.debug("VmDiskStatsTask is running...");
-
-                        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-                        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
-                        sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance,
-                                ResourceState.ErrorInMaintenance);
-                        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString());
-                        sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, HypervisorType.KVM); // support KVM only util 2013.06.25
-                        List<HostVO> hosts = _hostDao.search(sc, null);
-
-                        for (HostVO host : hosts) {
-                            List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
-                            List<Long> vmIds = new ArrayList<Long>();
-
-                            for (UserVmVO vm : vms) {
-                                if (vm.getType() == VirtualMachine.Type.User) // user vm
-                                    vmIds.add(vm.getId());
-                            }
-
-                            HashMap<Long, List<VmDiskStatsEntry>> vmDiskStatsById = _userVmMgr.getVmDiskStatistics(host.getId(), host.getName(), vmIds);
-                            if (vmDiskStatsById == null)
-                                continue;
-
-                            Set<Long> vmIdSet = vmDiskStatsById.keySet();
-                            for (Long vmId : vmIdSet) {
-                                List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsById.get(vmId);
-                                if (vmDiskStats == null)
-                                    continue;
-                                UserVmVO userVm = _userVmDao.findById(vmId);
-                                for (VmDiskStatsEntry vmDiskStat : vmDiskStats) {
-                                    SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
-                                    sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
-                                    List<VolumeVO> volumes = _volsDao.search(sc_volume, null);
-                                    if ((volumes == null) || (volumes.size() == 0))
-                                        break;
-                                    VolumeVO volume = volumes.get(0);
-                                    VmDiskStatisticsVO previousVmDiskStats =
-                                            _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
-                                    VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
-
-                                    if ((vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0) && (vmDiskStat.getIORead() == 0) &&
-                                            (vmDiskStat.getIOWrite() == 0)) {
-                                        s_logger.debug("IO/bytes read and write are all 0. Not updating vm_disk_statistics");
-                                        continue;
-                                    }
-
-                                    if (vmDiskStat_lock == null) {
-                                        s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId() +
-                                                " and volumeId:" + volume.getId());
-                                        continue;
-                                    }
-
-                                    if (previousVmDiskStats != null &&
-                                            ((previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) ||
-                                                    (previousVmDiskStats.getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite()) ||
-                                                    (previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) || (previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock.getCurrentIOWrite()))) {
-                                        s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + "Ignoring current answer. Host: " +
-                                                host.getName() + " . VM: " + vmDiskStat.getVmName() + " Read(Bytes): " + vmDiskStat.getBytesRead() + " write(Bytes): " +
-                                                vmDiskStat.getBytesWrite() + " Read(IO): " + vmDiskStat.getIORead() + " write(IO): " + vmDiskStat.getIOWrite());
-                                        continue;
-                                    }
-
-                                    if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Read # of bytes that's less than the last one.  " +
-                                                    "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
-                                                    " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
-                                        }
-                                        vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
-                                    }
-                                    vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
-                                    if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Write # of bytes that's less than the last one.  " +
-                                                    "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmDiskStat.getVmName() +
-                                                    " Reported: " + vmDiskStat.getBytesWrite() + " Stored: " + vmDiskStat_lock.getCurrentBytesWrite());
-                                        }
-                                        vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
-                                    }
-                                    vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
-                                    if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Read # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " +
-                                                    host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIORead() + " Stored: " +
-                                                    vmDiskStat_lock.getCurrentIORead());
-                                        }
-                                        vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
-                                    }
-                                    vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
-                                    if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Write # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " +
-                                                    host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIOWrite() + " Stored: " +
-                                                    vmDiskStat_lock.getCurrentIOWrite());
-                                        }
-                                        vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
-                                    }
-                                    vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
-
-                                    if (!_dailyOrHourly) {
-                                        //update agg bytes
-                                        vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
-                                        vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
-                                        vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
-                                        vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
-                                    }
-
-                                    _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
-                                }
-                            }
-                        }
-                    }
-                });
-            } catch (Exception e) {
-                s_logger.warn("Error while collecting vm disk stats from hosts", e);
-            }
-        }
-    }
-
-    class VmNetworkStatsTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            //Check for ownership
-            //msHost in UP state with min id should run the job
-            ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
-            if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){
-                s_logger.debug("Skipping collect vm network stats from hosts");
-                return;
-            }
-            // collect the vm network statistics(total) from hypervisor
-            try {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        s_logger.debug("VmNetworkStatsTask is running...");
-
-                        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-                        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
-                        sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
-                        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString());
-                        List<HostVO> hosts = _hostDao.search(sc, null);
-
-                        for (HostVO host : hosts)
-                        {
-                            List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
-                            List<Long> vmIds = new ArrayList<Long>();
-
-                            for (UserVmVO vm : vms) {
-                                if (vm.getType() == VirtualMachine.Type.User) // user vm
-                                    vmIds.add(vm.getId());
-                            }
-
-                            HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = _userVmMgr.getVmNetworkStatistics(host.getId(), host.getName(), vmIds);
-                            if (vmNetworkStatsById == null)
-                                continue;
-
-                            Set<Long> vmIdSet = vmNetworkStatsById.keySet();
-                            for(Long vmId : vmIdSet)
-                            {
-                                List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsById.get(vmId);
-                                if (vmNetworkStats == null)
-                                    continue;
-                                UserVmVO userVm = _userVmDao.findById(vmId);
-                                if (userVm == null) {
-                                    s_logger.debug("Cannot find uservm with id: " + vmId + " , continue");
-                                    continue;
-                                }
-                                s_logger.debug("Now we are updating the user_statistics table for VM: " + userVm.getInstanceName() + " after collecting vm network statistics from host: " + host.getName());
-                                for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
-                                    SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
-                                    sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
-                                    NicVO nic = _nicDao.search(sc_nic, null).get(0);
-                                    List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
-                                    if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
-                                        continue; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
-                                    UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm");
-                                    if (previousvmNetworkStats == null) {
-                                        previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), vmId, "UserVm", nic.getNetworkId());
-                                        _userStatsDao.persist(previousvmNetworkStats);
-                                    }
-                                    UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm");
-
-                                    if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
-                                        s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
-                                        continue;
-                                    }
-
-                                    if (vmNetworkStat_lock == null) {
-                                        s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId());
-                                        continue;
-                                    }
-
-                                    if (previousvmNetworkStats != null
-                                            && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
-                                            || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
-                                        s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " +
-                                                "Ignoring current answer. Host: " + host.getName()  + " . VM: " + vmNetworkStat.getVmName() +
-                                                " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived());
-                                        continue;
-                                    }
-
-                                    if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Sent # of bytes that's less than the last one.  " +
-                                                    "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
-                                                    " Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent());
-                                        }
-                                        vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
-                                    }
-                                    vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
-
-                                    if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
-                                        if (s_logger.isDebugEnabled()) {
-                                            s_logger.debug("Received # of bytes that's less than the last one.  " +
-                                                    "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
-                                                    " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived());
-                                        }
-                                        vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
-                                    }
-                                    vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
-
-                                    if (! _dailyOrHourly) {
-                                        //update agg bytes
-                                        vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
-                                        vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
-                                    }
-
-                                    _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
-                                }
-                            }
-                        }
-                    }
-                });
-            } catch (Exception e) {
-                s_logger.warn("Error while collecting vm network stats from hosts", e);
-            }
-        }
-    }
-
-
-    class VolumeStatsTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                List<StoragePoolVO> pools = _storagePoolDao.listAll();
-
-                for (StoragePoolVO pool : pools) {
-                    List<VolumeVO> volumes = _volsDao.findByPoolId(pool.getId(), null);
-                    List<String> volumeLocators = new ArrayList<String>();
-                    for (VolumeVO volume: volumes){
-                        if (volume.getFormat() == ImageFormat.QCOW2) {
-                            volumeLocators.add(volume.getUuid());
-                        }
-                        else if (volume.getFormat() == ImageFormat.VHD){
-                            volumeLocators.add(volume.getPath());
-                        }
-                        else if (volume.getFormat() == ImageFormat.OVA){
-                            volumeLocators.add(volume.getChainInfo());
-                        }
-                        else {
-                            s_logger.warn("Volume stats not implemented for this format type " + volume.getFormat() );
-                            break;
-                        }
-                    }
-                    try {
-                        Map<String, VolumeStatsEntry> volumeStatsByUuid;
-                        if (pool.getScope() == ScopeType.ZONE) {
-                            volumeStatsByUuid = new HashMap<>();
-                            for (final Cluster cluster: _clusterDao.listByZoneId(pool.getDataCenterId())) {
-                                final Map<String, VolumeStatsEntry> volumeStatsForCluster = _userVmMgr.getVolumeStatistics(cluster.getId(), pool.getUuid(), pool.getPoolType(), volumeLocators, StatsTimeout.value());
-                                if (volumeStatsForCluster != null) {
-                                    volumeStatsByUuid.putAll(volumeStatsForCluster);
-                                }
-                            }
-                        } else {
-                            volumeStatsByUuid = _userVmMgr.getVolumeStatistics(pool.getClusterId(), pool.getUuid(), pool.getPoolType(), volumeLocators, StatsTimeout.value());
-                        }
-                        if (volumeStatsByUuid != null){
-                            for (final Map.Entry<String, VolumeStatsEntry> entry : volumeStatsByUuid.entrySet()) {
-                                if (entry == null || entry.getKey() == null || entry.getValue() == null) {
-                                    continue;
-                                }
-                                _volumeStats.put(entry.getKey(), entry.getValue());
-                            }
-                        }
-                    } catch (Exception e) {
-                        s_logger.warn("Failed to get volume stats for cluster with ID: " + pool.getClusterId(), e);
-                        continue;
-                    }
-                }
-            } catch (Throwable t) {
-                s_logger.error("Error trying to retrieve volume stats", t);
-            }
-        }
-    }
-
-    public VolumeStats getVolumeStats(String volumeLocator) {
-        if (volumeLocator != null && _volumeStats.containsKey(volumeLocator)) {
-            return _volumeStats.get(volumeLocator);
-        }
-        return null;
-    }
-
-    class StorageCollector extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("StorageCollector is running...");
-                }
-
-                List<DataStore> stores = _dataStoreMgr.listImageStores();
-                ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<Long, StorageStats>();
-                for (DataStore store : stores) {
-                    if (store.getUri() == null) {
-                        continue;
-                    }
-
-                    Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
-                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), nfsVersion);
-                    EndPoint ssAhost = _epSelector.select(store);
-                    if (ssAhost == null) {
-                        s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName());
-                        continue;
-                    }
-                    long storeId = store.getId();
-                    Answer answer = ssAhost.sendMessage(command);
-                    if (answer != null && answer.getResult()) {
-                        storageStats.put(storeId, (StorageStats)answer);
-                        s_logger.trace("HostId: " + storeId + " Used: " + ((StorageStats)answer).getByteUsed() + " Total Available: " +
-                                ((StorageStats)answer).getCapacityBytes());
-                    }
-                }
-                _storageStats = storageStats;
-                ConcurrentHashMap<Long, StorageStats> storagePoolStats = new ConcurrentHashMap<Long, StorageStats>();
-
-                List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
-                for (StoragePoolVO pool : storagePools) {
-                    // check if the pool has enabled hosts
-                    List<Long> hostIds = _storageManager.getUpHostsInPool(pool.getId());
-                    if (hostIds == null || hostIds.isEmpty())
-                        continue;
-                    GetStorageStatsCommand command = new GetStorageStatsCommand(pool.getUuid(), pool.getPoolType(), pool.getPath());
-                    long poolId = pool.getId();
-                    try {
-                        Answer answer = _storageManager.sendToPool(pool, command);
-                        if (answer != null && answer.getResult()) {
-                            storagePoolStats.put(pool.getId(), (StorageStats)answer);
-
-                            // Seems like we have dynamically updated the pool size since the prev. size and the current do not match
-                            if (_storagePoolStats.get(poolId) != null && _storagePoolStats.get(poolId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()) {
-                                pool.setCapacityBytes(((StorageStats)answer).getCapacityBytes());
-                                _storagePoolDao.update(pool.getId(), pool);
-                            }
-                        }
-                    } catch (StorageUnavailableException e) {
-                        s_logger.info("Unable to reach " + pool, e);
-                    } catch (Exception e) {
-                        s_logger.warn("Unable to get stats for " + pool, e);
-                    }
-                }
-                _storagePoolStats = storagePoolStats;
-            } catch (Throwable t) {
-                s_logger.error("Error trying to retrieve storage stats", t);
-            }
-        }
-
-    }
-
-    class AutoScaleMonitor extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("AutoScaling Monitor is running...");
-                }
-                // list all AS VMGroups
-                List<AutoScaleVmGroupVO> asGroups = _asGroupDao.listAll();
-                for (AutoScaleVmGroupVO asGroup : asGroups) {
-                    // check group state
-                    if ((asGroup.getState().equals("enabled")) && (is_native(asGroup.getId()))) {
-                        // check minimum vm of group
-                        Integer currentVM = _asGroupVmDao.countByGroup(asGroup.getId());
-                        if (currentVM < asGroup.getMinMembers()) {
-                            _asManager.doScaleUp(asGroup.getId(), asGroup.getMinMembers() - currentVM);
-                            continue;
-                        }
-
-                        //check interval
-                        long now = (new Date()).getTime();
-                        if (asGroup.getLastInterval() != null)
-                            if ((now - asGroup.getLastInterval().getTime()) < asGroup
-                                    .getInterval()) {
-                                continue;
-                            }
-
-                        // update last_interval
-                        asGroup.setLastInterval(new Date());
-                        _asGroupDao.persist(asGroup);
-
-                        // collect RRDs data for this group
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("[AutoScale] Collecting RRDs data...");
-                        }
-                        Map<String, String> params = new HashMap<String, String>();
-                        List<AutoScaleVmGroupVmMapVO> asGroupVmVOs = _asGroupVmDao.listByGroup(asGroup.getId());
-                        params.put("total_vm", String.valueOf(asGroupVmVOs.size()));
-                        for (int i = 0; i < asGroupVmVOs.size(); i++) {
-                            long vmId = asGroupVmVOs.get(i).getInstanceId();
-                            VMInstanceVO vmVO = _vmInstance.findById(vmId);
-                            //xe vm-list | grep vmname -B 1 | head -n 1 | awk -F':' '{print $2}'
-                            params.put("vmname" + String.valueOf(i + 1), vmVO.getInstanceName());
-                            params.put("vmid" + String.valueOf(i + 1), String.valueOf(vmVO.getId()));
-
-                        }
-                        // get random hostid because all vms are in a cluster
-                        long vmId = asGroupVmVOs.get(0).getInstanceId();
-                        VMInstanceVO vmVO = _vmInstance.findById(vmId);
-                        Long receiveHost = vmVO.getHostId();
-
-                        // setup parameters phase: duration and counter
-                        // list pair [counter, duration]
-                        List<Pair<String, Integer>> lstPair = getPairofCounternameAndDuration(asGroup.getId());
-                        int total_counter = 0;
-                        String[] lstCounter = new String[lstPair.size()];
-                        for (int i = 0; i < lstPair.size(); i++) {
-                            Pair<String, Integer> pair = lstPair.get(i);
-                            String strCounterNames = pair.first();
-                            Integer duration = pair.second();
-
-                            lstCounter[i] = strCounterNames.split(",")[0];
-                            total_counter++;
-                            params.put("duration" + String.valueOf(total_counter), duration.toString());
-                            params.put("counter" + String.valueOf(total_counter), lstCounter[i]);
-                            params.put("con" + String.valueOf(total_counter), strCounterNames.split(",")[1]);
-                        }
-                        params.put("total_counter", String.valueOf(total_counter));
-
-                        PerformanceMonitorCommand perfMon = new PerformanceMonitorCommand(params, 20);
-
-                        try {
-                            Answer answer = _agentMgr.send(receiveHost, perfMon);
-                            if (answer == null || !answer.getResult()) {
-                                s_logger.debug("Failed to send data to node !");
-                            } else {
-                                String result = answer.getDetails();
-                                s_logger.debug("[AutoScale] RRDs collection answer: " + result);
-                                HashMap<Long, Double> avgCounter = new HashMap<Long, Double>();
-
-                                // extract data
-                                String[] counterElements = result.split(",");
-                                if ((counterElements != null) && (counterElements.length > 0)) {
-                                    for (String string : counterElements) {
-                                        try {
-                                            String[] counterVals = string.split(":");
-                                            String[] counter_vm = counterVals[0].split("\\.");
-
-                                            Long counterId = Long.parseLong(counter_vm[1]);
-                                            Long conditionId = Long.parseLong(params.get("con" + counter_vm[1]));
-                                            Double coVal = Double.parseDouble(counterVals[1]);
-
-                                            // Summary of all counter by counterId key
-                                            if (avgCounter.get(counterId) == null) {
-                                                /* initialize if data is not set */
-                                                avgCounter.put(counterId, new Double(0));
-                                            }
-
-                                            String counterName = getCounternamebyCondition(conditionId.longValue());
-                                            if (Counter.Source.memory.toString().equals(counterName)) {
-                                                // calculate memory in percent
-                                                Long profileId = asGroup.getProfileId();
-                                                AutoScaleVmProfileVO profileVo = _asProfileDao.findById(profileId);
-                                                ServiceOfferingVO serviceOff = _serviceOfferingDao.findById(profileVo.getServiceOfferingId());
-                                                int maxRAM = serviceOff.getRamSize();
-
-                                                // get current RAM percent
-                                                coVal = coVal / maxRAM;
-                                            } else {
-                                                // cpu
-                                                coVal = coVal * 100;
-                                            }
-
-                                            // update data entry
-                                            avgCounter.put(counterId, avgCounter.get(counterId) + coVal);
-
-                                        } catch (Exception e) {
-                                            e.printStackTrace();
-                                        }
-                                    }
-
-                                    String scaleAction = getAutoscaleAction(avgCounter, asGroup.getId(), currentVM, params);
-                                    if (scaleAction != null) {
-                                        s_logger.debug("[AutoScale] Doing scale action: " + scaleAction + " for group " + asGroup.getId());
-                                        if (scaleAction.equals("scaleup")) {
-                                            _asManager.doScaleUp(asGroup.getId(), 1);
-                                        } else {
-                                            _asManager.doScaleDown(asGroup.getId());
-                                        }
-                                    }
-                                }
-                            }
-
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-
-                    }
-                }
-
-            } catch (Throwable t) {
-                s_logger.error("Error trying to monitor autoscaling", t);
-            }
-
-        }
-
-        private boolean is_native(long groupId) {
-            List<AutoScaleVmGroupPolicyMapVO> vos = _asGroupPolicyDao.listByVmGroupId(groupId);
-            for (AutoScaleVmGroupPolicyMapVO vo : vos) {
-                List<AutoScalePolicyConditionMapVO> ConditionPolicies = _asConditionMapDao.findByPolicyId(vo.getPolicyId());
-                for (AutoScalePolicyConditionMapVO ConditionPolicy : ConditionPolicies) {
-                    ConditionVO condition = _asConditionDao.findById(ConditionPolicy.getConditionId());
-                    CounterVO counter = _asCounterDao.findById(condition.getCounterid());
-                    if (counter.getSource() == Counter.Source.cpu || counter.getSource() == Counter.Source.memory)
-                        return true;
-                }
-            }
-            return false;
-        }
-
-        private String getAutoscaleAction(HashMap<Long, Double> avgCounter, long groupId, long currentVM, Map<String, String> params) {
-
-            List<AutoScaleVmGroupPolicyMapVO> listMap = _asGroupPolicyDao.listByVmGroupId(groupId);
-            if ((listMap == null) || (listMap.size() == 0))
-                return null;
-            for (AutoScaleVmGroupPolicyMapVO asVmgPmap : listMap) {
-                AutoScalePolicyVO policyVO = _asPolicyDao.findById(asVmgPmap.getPolicyId());
-                if (policyVO != null) {
-                    Integer quitetime = policyVO.getQuietTime();
-                    Date quitetimeDate = policyVO.getLastQuiteTime();
-                    long last_quitetime = 0L;
-                    if (quitetimeDate != null) {
-                        last_quitetime = policyVO.getLastQuiteTime().getTime();
-                    }
-                    long current_time = (new Date()).getTime();
-
-                    // check quite time for this policy
-                    if ((current_time - last_quitetime) >= (long)quitetime) {
-
-                        // list all condition of this policy
-                        boolean bValid = true;
-                        List<ConditionVO> lstConditions = getConditionsbyPolicyId(policyVO.getId());
-                        if ((lstConditions != null) && (lstConditions.size() > 0)) {
-                            // check whole conditions of this policy
-                            for (ConditionVO conditionVO : lstConditions) {
-                                long thresholdValue = conditionVO.getThreshold();
-                                Double thresholdPercent = (double)thresholdValue / 100;
-                                CounterVO counterVO = _asCounterDao.findById(conditionVO.getCounterid());
-//Double sum = avgCounter.get(conditionVO.getCounterid());
-                                long counter_count = 1;
-                                do {
-                                    String counter_param = params.get("counter" + String.valueOf(counter_count));
-                                    Counter.Source counter_source = counterVO.getSource();
-                                    if (counter_param.equals(counter_source.toString()))
-                                        break;
-                                    counter_count++;
-                                } while (1 == 1);
-
-                                Double sum = avgCounter.get(counter_count);
-                                Double avg = sum / currentVM;
-                                Operator op = conditionVO.getRelationalOperator();
-                                boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent.equals(avg)))
-                                        || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg.doubleValue() >= thresholdPercent.doubleValue()))
-                                        || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg.doubleValue() > thresholdPercent.doubleValue()))
-                                        || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg.doubleValue() <= thresholdPercent.doubleValue()))
-                                        || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg.doubleValue() < thresholdPercent.doubleValue()));
-
-                                if (!bConditionCheck) {
-                                    bValid = false;
-                                    break;
-                                }
-                            }
-                            if (bValid) {
-                                return policyVO.getAction();
-                            }
-                        }
-                    }
-                }
-            }
-            return null;
-        }
-
-        private List<ConditionVO> getConditionsbyPolicyId(long policyId) {
-            List<AutoScalePolicyConditionMapVO> conditionMap = _asConditionMapDao.findByPolicyId(policyId);
-            if ((conditionMap == null) || (conditionMap.size() == 0))
-                return null;
-
-            List<ConditionVO> lstResult = new ArrayList<ConditionVO>();
-            for (AutoScalePolicyConditionMapVO asPCmap : conditionMap) {
-                lstResult.add(_asConditionDao.findById(asPCmap.getConditionId()));
-            }
-
-            return lstResult;
-        }
-
-        public List<Pair<String, Integer>> getPairofCounternameAndDuration(
-                long groupId) {
-            AutoScaleVmGroupVO groupVo = _asGroupDao.findById(groupId);
-            if (groupVo == null)
-                return null;
-            List<Pair<String, Integer>> result = new ArrayList<Pair<String, Integer>>();
-            //list policy map
-            List<AutoScaleVmGroupPolicyMapVO> groupPolicymap = _asGroupPolicyDao.listByVmGroupId(groupVo.getId());
-            if (groupPolicymap == null)
-                return null;
-            for (AutoScaleVmGroupPolicyMapVO gpMap : groupPolicymap) {
-                //get duration
-                AutoScalePolicyVO policyVo = _asPolicyDao.findById(gpMap.getPolicyId());
-                Integer duration = policyVo.getDuration();
-                //get collection of counter name
-
-                StringBuffer buff = new StringBuffer();
-                List<AutoScalePolicyConditionMapVO> lstPCmap = _asConditionMapDao.findByPolicyId(policyVo.getId());
-                for (AutoScalePolicyConditionMapVO pcMap : lstPCmap) {
-                    String counterName = getCounternamebyCondition(pcMap.getConditionId());
-                    buff.append(counterName);
-                    buff.append(",");
-                    buff.append(pcMap.getConditionId());
-                }
-                // add to result
-                Pair<String, Integer> pair = new Pair<String, Integer>(buff.toString(), duration);
-                result.add(pair);
-            }
-
-            return result;
-        }
-
-        public String getCounternamebyCondition(long conditionId) {
-
-            ConditionVO condition = _asConditionDao.findById(conditionId);
-            if (condition == null)
-                return "";
-
-            long counterId = condition.getCounterid();
-            CounterVO counter = _asCounterDao.findById(counterId);
-            if (counter == null)
-                return "";
-
-            return counter.getSource().toString();
-        }
-    }
-
-    public boolean imageStoreHasEnoughCapacity(DataStore imageStore) {
-        StorageStats imageStoreStats = _storageStats.get(imageStore.getId());
-        if (imageStoreStats != null && (imageStoreStats.getByteUsed()/(imageStoreStats.getCapacityBytes()*1.0)) <= _imageStoreCapacityThreshold) {
-            return true;
-        }
-        return false;
-    }
-
-    public StorageStats getStorageStats(long id) {
-        return _storageStats.get(id);
-    }
-
-    public HostStats getHostStats(long hostId) {
-        return _hostStats.get(hostId);
-    }
-
-    public StorageStats getStoragePoolStats(long id) {
-        return _storagePoolStats.get(id);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return StatsCollector.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] { vmDiskStatsInterval, vmDiskStatsIntervalMin, vmNetworkStatsInterval, vmNetworkStatsIntervalMin, StatsTimeout };
-    }
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/AssociateLunCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/AssociateLunCmdResponse.java
deleted file mode 100644
index 254dc18..0000000
--- a/server/src/com/cloud/server/api/response/netapp/AssociateLunCmdResponse.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class AssociateLunCmdResponse extends BaseResponse {
-
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the LUN id")
-    private String lun;
-
-    @SerializedName(ApiConstants.IP_ADDRESS)
-    @Param(description = "the IP address of ")
-    private String ipAddress;
-
-    @SerializedName(ApiConstants.TARGET_IQN)
-    @Param(description = "the target IQN")
-    private String targetIQN;
-
-    public String getLun() {
-        return lun;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public String getTargetIQN() {
-        return targetIQN;
-    }
-
-    public void setLun(String lun) {
-        this.lun = lun;
-    }
-
-    public void setIpAddress(String ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-
-    public void setTargetIQN(String targetIQN) {
-        this.targetIQN = targetIQN;
-    }
-
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/CreateLunCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/CreateLunCmdResponse.java
deleted file mode 100644
index 06be87b..0000000
--- a/server/src/com/cloud/server/api/response/netapp/CreateLunCmdResponse.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class CreateLunCmdResponse extends BaseResponse {
-
-    @SerializedName(ApiConstants.PATH)
-    @Param(description = "pool path")
-    private String path;
-
-    @SerializedName(ApiConstants.IQN)
-    @Param(description = "iqn")
-    private String iqn;
-
-    @SerializedName(ApiConstants.IP_ADDRESS)
-    @Param(description = "ip address")
-    private String ipAddress;
-
-    public String getPath() {
-        return path;
-    }
-
-    public String getIqn() {
-        return iqn;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    public void setIqn(String iqn) {
-        this.iqn = iqn;
-    }
-
-    public void setIpAddress(String ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/CreateVolumeOnFilerCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/CreateVolumeOnFilerCmdResponse.java
deleted file mode 100644
index f01eb43..0000000
--- a/server/src/com/cloud/server/api/response/netapp/CreateVolumeOnFilerCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class CreateVolumeOnFilerCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/CreateVolumePoolCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/CreateVolumePoolCmdResponse.java
deleted file mode 100644
index cf2e5ea..0000000
--- a/server/src/com/cloud/server/api/response/netapp/CreateVolumePoolCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class CreateVolumePoolCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/DeleteLUNCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/DeleteLUNCmdResponse.java
deleted file mode 100644
index be9d03c..0000000
--- a/server/src/com/cloud/server/api/response/netapp/DeleteLUNCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class DeleteLUNCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/DeleteVolumeOnFilerCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/DeleteVolumeOnFilerCmdResponse.java
deleted file mode 100644
index 40083ec..0000000
--- a/server/src/com/cloud/server/api/response/netapp/DeleteVolumeOnFilerCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class DeleteVolumeOnFilerCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/DeleteVolumePoolCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/DeleteVolumePoolCmdResponse.java
deleted file mode 100644
index d3a0875..0000000
--- a/server/src/com/cloud/server/api/response/netapp/DeleteVolumePoolCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class DeleteVolumePoolCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/DissociateLunCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/DissociateLunCmdResponse.java
deleted file mode 100644
index e88fae0..0000000
--- a/server/src/com/cloud/server/api/response/netapp/DissociateLunCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class DissociateLunCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/ListLunsCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/ListLunsCmdResponse.java
deleted file mode 100644
index 480d5cc..0000000
--- a/server/src/com/cloud/server/api/response/netapp/ListLunsCmdResponse.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class ListLunsCmdResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "lun id")
-    private Long id;
-
-    @SerializedName(ApiConstants.IQN)
-    @Param(description = "lun iqn")
-    private String iqn;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "lun name")
-    private String name;
-
-    @SerializedName(ApiConstants.VOLUME_ID)
-    @Param(description = "volume id")
-    private Long volumeId;
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getIqn() {
-        return iqn;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Long getVolumeId() {
-        return volumeId;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public void setIqn(String iqn) {
-        this.iqn = iqn;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setVolumeId(Long id) {
-        this.volumeId = id;
-    }
-}
\ No newline at end of file
diff --git a/server/src/com/cloud/server/api/response/netapp/ListVolumePoolsCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/ListVolumePoolsCmdResponse.java
deleted file mode 100644
index 5167260..0000000
--- a/server/src/com/cloud/server/api/response/netapp/ListVolumePoolsCmdResponse.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class ListVolumePoolsCmdResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "pool id")
-    private Long id;
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "pool name")
-    private String name;
-
-    @SerializedName(ApiConstants.ALGORITHM)
-    @Param(description = "pool algorithm")
-    private String algorithm;
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setAlgorithm(String algorithm) {
-        this.algorithm = algorithm;
-    }
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/ListVolumesOnFilerCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/ListVolumesOnFilerCmdResponse.java
deleted file mode 100644
index 1a1b607..0000000
--- a/server/src/com/cloud/server/api/response/netapp/ListVolumesOnFilerCmdResponse.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-
-import com.cloud.serializer.Param;
-
-public class ListVolumesOnFilerCmdResponse extends BaseResponse {
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "volume id")
-    private Long id;
-
-    @SerializedName(ApiConstants.POOL_NAME)
-    @Param(description = "pool name")
-    private String poolName;
-
-    @SerializedName(ApiConstants.IP_ADDRESS)
-    @Param(description = "ip address")
-    private String ipAddress;
-
-    @SerializedName(ApiConstants.AGGREGATE_NAME)
-    @Param(description = "Aggregate name")
-    private String aggrName;
-
-    @SerializedName(ApiConstants.VOLUME_NAME)
-    @Param(description = "Volume name")
-    private String volumeName;
-
-    @SerializedName(ApiConstants.SNAPSHOT_POLICY)
-    @Param(description = "snapshot policy")
-    private String snapshotPolicy;
-
-    @SerializedName(ApiConstants.SNAPSHOT_RESERVATION)
-    @Param(description = "snapshot reservation")
-    private Integer snapshotReservation;
-
-    @SerializedName(ApiConstants.SIZE)
-    @Param(description = "volume size")
-    private String volumeSize;
-
-    public Long getId() {
-        return id;
-    }
-
-    public String getPoolName() {
-        return poolName;
-    }
-
-    public String getIpAddress() {
-        return ipAddress;
-    }
-
-    public String getAggrName() {
-        return aggrName;
-    }
-
-    public String getVolumeName() {
-        return volumeName;
-    }
-
-    public String getSnapshotPolicy() {
-        return snapshotPolicy;
-    }
-
-    public Integer getSnapshotReservation() {
-        return snapshotReservation;
-    }
-
-    public String getVolumeSize() {
-        return volumeSize;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public void setPoolName(String poolName) {
-        this.poolName = poolName;
-    }
-
-    public void setIpAddress(String ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-
-    public void setAggrName(String aggrName) {
-        this.aggrName = aggrName;
-    }
-
-    public void setVolumeName(String volumeName) {
-        this.volumeName = volumeName;
-    }
-
-    public void setSnapshotPolicy(String snapshotPolicy) {
-        this.snapshotPolicy = snapshotPolicy;
-    }
-
-    public void setSnapshotReservation(Integer snapshotReservation) {
-        this.snapshotReservation = snapshotReservation;
-    }
-
-    public void setVolumeSize(String size) {
-        this.volumeSize = size;
-    }
-
-}
diff --git a/server/src/com/cloud/server/api/response/netapp/ModifyVolumePoolCmdResponse.java b/server/src/com/cloud/server/api/response/netapp/ModifyVolumePoolCmdResponse.java
deleted file mode 100644
index fa0c069..0000000
--- a/server/src/com/cloud/server/api/response/netapp/ModifyVolumePoolCmdResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.server.api.response.netapp;
-
-import org.apache.cloudstack.api.BaseResponse;
-
-public class ModifyVolumePoolCmdResponse extends BaseResponse {
-}
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
deleted file mode 100644
index 44c8189..0000000
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ /dev/null
@@ -1,2519 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.math.BigDecimal;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
-import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
-import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.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.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.DeleteStoragePoolCommand;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.dao.TemplateJoinDao;
-import com.cloud.api.query.vo.TemplateJoinVO;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.CapacityState;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.ConfigurationManagerImpl;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageConflictException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.org.Grouping;
-import com.cloud.org.Grouping.AllocationState;
-import com.cloud.resource.ResourceState;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.server.ManagementServer;
-import com.cloud.server.StatsCollector;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Volume.Type;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolTagsDao;
-import com.cloud.storage.dao.StoragePoolWorkDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.listener.StoragePoolMonitor;
-import com.cloud.storage.listener.VolumeStateListener;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.VMInstanceDao;
-
-@Component
-public class StorageManagerImpl extends ManagerBase implements StorageManager, ClusterManagerListener, Configurable {
-    private static final Logger s_logger = Logger.getLogger(StorageManagerImpl.class);
-
-    protected String _name;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    protected TemplateManager _tmpltMgr;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected ConfigurationManager _configMgr;
-    @Inject
-    protected VolumeDao _volsDao;
-    @Inject
-    private VolumeDataStoreDao _volumeDataStoreDao;
-    @Inject
-    protected HostDao _hostDao;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected StoragePoolHostDao _storagePoolHostDao;
-    @Inject
-    protected VMTemplatePoolDao _vmTemplatePoolDao = null;
-    @Inject
-    protected VMTemplateZoneDao _vmTemplateZoneDao;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao = null;
-    @Inject
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao = null;
-    @Inject
-    protected StoragePoolDetailsDao _storagePoolDetailsDao;
-    @Inject
-    protected ImageStoreDao _imageStoreDao = null;
-    @Inject
-    protected ImageStoreDetailsDao _imageStoreDetailsDao = null;
-    @Inject
-    protected SnapshotDataStoreDao _snapshotStoreDao = null;
-    @Inject
-    protected TemplateDataStoreDao _templateStoreDao = null;
-    @Inject
-    protected TemplateJoinDao _templateViewDao = null;
-    @Inject
-    protected VolumeDataStoreDao _volumeStoreDao = null;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    protected DataCenterDao _dcDao = null;
-    @Inject
-    protected VMTemplateDao _templateDao;
-    @Inject
-    protected UserDao _userDao;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    protected StoragePoolWorkDao _storagePoolWorkDao;
-    @Inject
-    protected HypervisorGuruManager _hvGuruMgr;
-    @Inject
-    protected VolumeDao _volumeDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ManagementServer _msServer;
-    @Inject
-    VolumeService volService;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    TemplateDataFactory tmplFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    ConfigurationServer _configServer;
-    @Inject
-    DataStoreManager _dataStoreMgr;
-    @Inject
-    DataStoreProviderManager _dataStoreProviderMgr;
-    @Inject
-    private TemplateService _imageSrv;
-    @Inject
-    EndPointSelector _epSelector;
-    @Inject
-    private DiskOfferingDao _diskOfferingDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    SnapshotService _snapshotService;
-    @Inject
-    StoragePoolTagsDao _storagePoolTagsDao;
-
-    protected List<StoragePoolDiscoverer> _discoverers;
-
-    public List<StoragePoolDiscoverer> getDiscoverers() {
-        return _discoverers;
-    }
-
-    public void setDiscoverers(List<StoragePoolDiscoverer> discoverers) {
-        _discoverers = discoverers;
-    }
-
-    protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
-    protected GenericSearchBuilder<StoragePoolHostVO, Long> UpHostsInPoolSearch;
-    protected SearchBuilder<VMInstanceVO> StoragePoolSearch;
-    protected SearchBuilder<StoragePoolVO> LocalStorageSearch;
-
-    ScheduledExecutorService _executor = null;
-    int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes
-    int _downloadUrlCleanupInterval;
-    int _downloadUrlExpirationInterval;
-    // protected BigDecimal _overProvisioningFactor = new BigDecimal(1);
-    private long _serverId;
-
-    private final Map<String, HypervisorHostListener> hostListeners = new HashMap<String, HypervisorHostListener>();
-
-    public boolean share(VMInstanceVO vm, List<VolumeVO> vols, HostVO host, boolean cancelPreviousShare) throws StorageUnavailableException {
-
-        // if pool is in maintenance and it is the ONLY pool available; reject
-        List<VolumeVO> rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), Type.ROOT);
-        if (rootVolForGivenVm != null && rootVolForGivenVm.size() > 0) {
-            boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId());
-            if (!isPoolAvailable) {
-                throw new StorageUnavailableException("Can not share " + vm, rootVolForGivenVm.get(0).getPoolId());
-            }
-        }
-
-        // this check is done for maintenance mode for primary storage
-        // if any one of the volume is unusable, we return false
-        // if we return false, the allocator will try to switch to another PS if
-        // available
-        for (VolumeVO vol : vols) {
-            if (vol.getRemoved() != null) {
-                s_logger.warn("Volume id:" + vol.getId() + " is removed, cannot share on this instance");
-                // not ok to share
-                return false;
-            }
-        }
-
-        // ok to share
-        return true;
-    }
-
-    private boolean isPoolAvailable(Long poolId) {
-        // get list of all pools
-        List<StoragePoolVO> pools = _storagePoolDao.listAll();
-
-        // if no pools or 1 pool which is in maintenance
-        if (pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(StoragePoolStatus.Maintenance))) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type) {
-        List<StoragePoolVO> pools = _storagePoolDao.listByDataCenterId(datacenterId);
-        List<StoragePoolVO> retPools = new ArrayList<StoragePoolVO>();
-        for (StoragePoolVO pool : pools) {
-            if (pool.getStatus() != StoragePoolStatus.Up) {
-                continue;
-            }
-            if (pool.getScope() == ScopeType.ZONE) {
-                if (pool.getHypervisor() != null && pool.getHypervisor() == type) {
-                    retPools.add(pool);
-                }
-            } else {
-                ClusterVO cluster = _clusterDao.findById(pool.getClusterId());
-                if (type == cluster.getHypervisorType()) {
-                    retPools.add(pool);
-                }
-            }
-        }
-        Collections.shuffle(retPools);
-        return retPools;
-    }
-
-    @Override
-    public boolean isLocalStorageActiveOnHost(Long hostId) {
-        List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId);
-        for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) {
-            StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(storagePoolHostRef.getPoolId());
-            if (PrimaryDataStoreVO.getPoolType() == StoragePoolType.LVM || PrimaryDataStoreVO.getPoolType() == StoragePoolType.EXT) {
-                SearchBuilder<VolumeVO> volumeSB = _volsDao.createSearchBuilder();
-                volumeSB.and("poolId", volumeSB.entity().getPoolId(), SearchCriteria.Op.EQ);
-                volumeSB.and("removed", volumeSB.entity().getRemoved(), SearchCriteria.Op.NULL);
-                volumeSB.and("state", volumeSB.entity().getState(), SearchCriteria.Op.NIN);
-
-                SearchBuilder<VMInstanceVO> activeVmSB = _vmInstanceDao.createSearchBuilder();
-                activeVmSB.and("state", activeVmSB.entity().getState(), SearchCriteria.Op.IN);
-                volumeSB.join("activeVmSB", activeVmSB, volumeSB.entity().getInstanceId(), activeVmSB.entity().getId(), JoinBuilder.JoinType.INNER);
-
-                SearchCriteria<VolumeVO> volumeSC = volumeSB.create();
-                volumeSC.setParameters("poolId", PrimaryDataStoreVO.getId());
-                volumeSC.setParameters("state", Volume.State.Expunging, Volume.State.Destroy);
-                volumeSC.setJoinParameters("activeVmSB", "state", State.Starting, State.Running, State.Stopping, State.Migrating);
-
-                List<VolumeVO> volumes = _volsDao.search(volumeSC, null);
-                if (volumes.size() > 0) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException {
-        return sendToPool(pool, null, null, cmds).second();
-    }
-
-    @Override
-    public Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException {
-        Answer[] answers = sendToPool(pool, hostIdsToTryFirst, null, new Commands(cmd)).second();
-        if (answers == null) {
-            return null;
-        }
-        return answers[0];
-    }
-
-    @Override
-    public Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException {
-        Answer[] answers = sendToPool(pool, new Commands(cmd));
-        if (answers == null) {
-            return null;
-        }
-        return answers[0];
-    }
-
-    public Long chooseHostForStoragePool(StoragePoolVO poolVO, List<Long> avoidHosts, boolean sendToVmResidesOn, Long vmId) {
-        if (sendToVmResidesOn) {
-            if (vmId != null) {
-                VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-                if (vmInstance != null) {
-                    Long hostId = vmInstance.getHostId();
-                    if (hostId != null && !avoidHosts.contains(vmInstance.getHostId())) {
-                        return hostId;
-                    }
-                }
-            }
-            /*
-             * Can't find the vm where host resides on(vm is destroyed? or
-             * volume is detached from vm), randomly choose a host to send the
-             * cmd
-             */
-        }
-        List<StoragePoolHostVO> poolHosts = _storagePoolHostDao.listByHostStatus(poolVO.getId(), Status.Up);
-        Collections.shuffle(poolHosts);
-        if (poolHosts != null && poolHosts.size() > 0) {
-            for (StoragePoolHostVO sphvo : poolHosts) {
-                if (!avoidHosts.contains(sphvo.getHostId())) {
-                    return sphvo.getHostId();
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) {
-
-        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
-        _storagePoolAcquisitionWaitSeconds = NumbersUtil.parseInt(configs.get("pool.acquisition.wait.seconds"), 1800);
-        s_logger.info("pool.acquisition.wait.seconds is configured as " + _storagePoolAcquisitionWaitSeconds + " seconds");
-
-        _agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
-
-        s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value()
-        + ", template cleanup enabled: " + TemplateCleanupEnabled.value());
-
-        String cleanupInterval = configs.get("extract.url.cleanup.interval");
-        _downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
-
-        String urlExpirationInterval = configs.get("extract.url.expiration.interval");
-        _downloadUrlExpirationInterval = NumbersUtil.parseInt(urlExpirationInterval, 14400);
-
-        String workers = configs.get("expunge.workers");
-        int wrks = NumbersUtil.parseInt(workers, 10);
-        _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("StorageManager-Scavenger"));
-
-        _agentMgr.registerForHostEvents(ComponentContext.inject(LocalStoragePoolListener.class), true, false, false);
-
-        _serverId = _msServer.getId();
-
-        UpHostsInPoolSearch = _storagePoolHostDao.createSearchBuilder(Long.class);
-        UpHostsInPoolSearch.selectFields(UpHostsInPoolSearch.entity().getHostId());
-        SearchBuilder<HostVO> hostSearch = _hostDao.createSearchBuilder();
-        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
-        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), Op.EQ);
-        UpHostsInPoolSearch.join("hosts", hostSearch, hostSearch.entity().getId(), UpHostsInPoolSearch.entity().getHostId(), JoinType.INNER);
-        UpHostsInPoolSearch.and("pool", UpHostsInPoolSearch.entity().getPoolId(), Op.EQ);
-        UpHostsInPoolSearch.done();
-
-        StoragePoolSearch = _vmInstanceDao.createSearchBuilder();
-
-        SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
-        volumeSearch.and("volumeType", volumeSearch.entity().getVolumeType(), SearchCriteria.Op.EQ);
-        volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
-        volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
-        StoragePoolSearch.join("vmVolume", volumeSearch, volumeSearch.entity().getInstanceId(), StoragePoolSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        StoragePoolSearch.done();
-
-        LocalStorageSearch = _storagePoolDao.createSearchBuilder();
-        SearchBuilder<StoragePoolHostVO> storageHostSearch = _storagePoolHostDao.createSearchBuilder();
-        storageHostSearch.and("hostId", storageHostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
-        LocalStorageSearch.join("poolHost", storageHostSearch, storageHostSearch.entity().getPoolId(), LocalStorageSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-        LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN);
-        LocalStorageSearch.done();
-
-        Volume.State.getStateMachine().registerListener(new VolumeStateListener(_configDao, _vmInstanceDao));
-
-        return true;
-    }
-
-    @Override
-    public String getStoragePoolTags(long poolId) {
-        return com.cloud.utils.StringUtils.listToCsvTags(_storagePoolDao.searchForStoragePoolTags(poolId));
-    }
-
-    @Override
-    public boolean start() {
-        if (StorageCleanupEnabled.value()) {
-            Random generator = new Random();
-            int initialDelay = generator.nextInt(StorageCleanupInterval.value());
-            _executor.scheduleWithFixedDelay(new StorageGarbageCollector(), initialDelay, StorageCleanupInterval.value(), TimeUnit.SECONDS);
-        } else {
-            s_logger.debug("Storage cleanup is not enabled, so the storage cleanup thread is not being scheduled.");
-        }
-
-        _executor.scheduleWithFixedDelay(new DownloadURLGarbageCollector(), _downloadUrlCleanupInterval, _downloadUrlCleanupInterval, TimeUnit.SECONDS);
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        if (StorageCleanupEnabled.value()) {
-            _executor.shutdown();
-        }
-        return true;
-    }
-
-    @DB
-    @Override
-    public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException {
-        DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
-        if (dc == null) {
-            return null;
-        }
-        boolean useLocalStorageForSystemVM = false;
-        Boolean isLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dc.getId());
-        if (isLocal != null) {
-            useLocalStorageForSystemVM = isLocal.booleanValue();
-        }
-        if (!(dc.isLocalStorageEnabled() || useLocalStorageForSystemVM)) {
-            return null;
-        }
-        DataStore store;
-        try {
-            String hostAddress = pInfo.getHost();
-            if (host.getHypervisorType() == Hypervisor.HypervisorType.VMware) {
-                hostAddress = "VMFS datastore: " + pInfo.getHostPath();
-            }
-            StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, pInfo.getHostPath(), pInfo.getUuid());
-            if (pool == null && host.getHypervisorType() == HypervisorType.VMware) {
-                // perform run-time upgrade. In versions prior to 2.2.12, there
-                // is a bug that we don't save local datastore info (host path
-                // is empty), this will cause us
-                // not able to distinguish multiple local datastores that may be
-                // available on the host, to support smooth migration, we
-                // need to perform runtime upgrade here
-                if (pInfo.getHostPath().length() > 0) {
-                    pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, "", pInfo.getUuid());
-                }
-            }
-            if (pool == null) {
-                //the path can be different, but if they have the same uuid, assume they are the same storage
-                pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, null, pInfo.getUuid());
-                if (pool != null) {
-                    s_logger.debug("Found a storage pool: " + pInfo.getUuid() + ", but with different hostpath " + pInfo.getHostPath() + ", still treat it as the same pool");
-                }
-            }
-
-            DataStoreProvider provider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
-            DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-            if (pool == null) {
-                Map<String, Object> params = new HashMap<String, Object>();
-                String name = (host.getName() + " Local Storage");
-                params.put("zoneId", host.getDataCenterId());
-                params.put("clusterId", host.getClusterId());
-                params.put("podId", host.getPodId());
-                params.put("url", pInfo.getPoolType().toString() + "://" + pInfo.getHost() + "/" + pInfo.getHostPath());
-                params.put("name", name);
-                params.put("localStorage", true);
-                params.put("details", pInfo.getDetails());
-                params.put("uuid", pInfo.getUuid());
-                params.put("providerName", provider.getName());
-
-                store = lifeCycle.initialize(params);
-            } else {
-                store = _dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-            }
-
-            pool = _storagePoolDao.findById(store.getId());
-            if (pool.getStatus() != StoragePoolStatus.Maintenance && pool.getStatus() != StoragePoolStatus.Removed) {
-                HostScope scope = new HostScope(host.getId(), host.getClusterId(), host.getDataCenterId());
-                lifeCycle.attachHost(store, scope, pInfo);
-            }
-
-        } catch (Exception e) {
-            s_logger.warn("Unable to setup the local storage pool for " + host, e);
-            throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e);
-        }
-
-        return _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
-    }
-
-    @Override
-    public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException {
-        String providerName = cmd.getStorageProviderName();
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
-
-        if (storeProvider == null) {
-            storeProvider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
-            if (storeProvider == null) {
-                throw new InvalidParameterValueException("can't find storage provider: " + providerName);
-            }
-        }
-
-        Long clusterId = cmd.getClusterId();
-        Long podId = cmd.getPodId();
-        Long zoneId = cmd.getZoneId();
-
-        ScopeType scopeType = ScopeType.CLUSTER;
-        String scope = cmd.getScope();
-        if (scope != null) {
-            try {
-                scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
-            } catch (Exception e) {
-                throw new InvalidParameterValueException("invalid scope for pool " + scope);
-            }
-        }
-
-        if (scopeType == ScopeType.CLUSTER && clusterId == null) {
-            throw new InvalidParameterValueException("cluster id can't be null, if scope is cluster");
-        } else if (scopeType == ScopeType.ZONE && zoneId == null) {
-            throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
-        }
-
-        HypervisorType hypervisorType = HypervisorType.KVM;
-        if (scopeType == ScopeType.ZONE) {
-            // ignore passed clusterId and podId
-            clusterId = null;
-            podId = null;
-            String hypervisor = cmd.getHypervisor();
-            if (hypervisor != null) {
-                try {
-                    hypervisorType = HypervisorType.getType(hypervisor);
-                } catch (Exception e) {
-                    throw new InvalidParameterValueException("invalid hypervisor type " + hypervisor);
-                }
-            } else {
-                throw new InvalidParameterValueException("Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage.");
-            }
-            if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Hyperv && hypervisorType != HypervisorType.LXC
-                    && hypervisorType != HypervisorType.Any) {
-                throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor);
-            }
-        }
-
-        Map<String, String> details = extractApiParamAsMap(cmd.getDetails());
-        DataCenterVO zone = _dcDao.findById(cmd.getZoneId());
-        if (zone == null) {
-            throw new InvalidParameterValueException("unable to find zone by id " + zoneId);
-        }
-        // Check if zone is disabled
-        Account account = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-        }
-
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.put("zoneId", zone.getId());
-        params.put("clusterId", clusterId);
-        params.put("podId", podId);
-        params.put("url", cmd.getUrl());
-        params.put("tags", cmd.getTags());
-        params.put("name", cmd.getStoragePoolName());
-        params.put("details", details);
-        params.put("providerName", storeProvider.getName());
-        params.put("managed", cmd.isManaged());
-        params.put("capacityBytes", cmd.getCapacityBytes());
-        params.put("capacityIops", cmd.getCapacityIops());
-
-        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
-        DataStore store = null;
-        try {
-            store = lifeCycle.initialize(params);
-            if (scopeType == ScopeType.CLUSTER) {
-                ClusterScope clusterScope = new ClusterScope(clusterId, podId, zoneId);
-                lifeCycle.attachCluster(store, clusterScope);
-            } else if (scopeType == ScopeType.ZONE) {
-                ZoneScope zoneScope = new ZoneScope(zoneId);
-                lifeCycle.attachZone(store, zoneScope, hypervisorType);
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to add data store: " + e.getMessage(), e);
-            try {
-                // clean up the db, just absorb the exception thrown in deletion with error logged, so that user can get error for adding data store
-                // not deleting data store.
-                if (store != null) {
-                    lifeCycle.deleteDataStore(store);
-                }
-            } catch (Exception ex) {
-                s_logger.debug("Failed to clean up storage pool: " + ex.getMessage());
-            }
-            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
-        }
-
-        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
-    }
-
-    private Map<String, String> extractApiParamAsMap(Map ds) {
-        Map<String, String> details = new HashMap<String, String>();
-        if (ds != null) {
-            Collection detailsCollection = ds.values();
-            Iterator it = detailsCollection.iterator();
-            while (it.hasNext()) {
-                HashMap d = (HashMap)it.next();
-                Iterator it2 = d.entrySet().iterator();
-                while (it2.hasNext()) {
-                    Map.Entry entry = (Map.Entry)it2.next();
-                    details.put((String)entry.getKey(), (String)entry.getValue());
-                }
-            }
-        }
-        return details;
-    }
-
-    @ActionEvent(eventType = EventTypes.EVENT_DISABLE_PRIMARY_STORAGE, eventDescription = "disable storage pool")
-    private void disablePrimaryStoragePool(StoragePoolVO primaryStorage) {
-        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up)) {
-            throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be disabled. Storage pool state : " + primaryStorage.getStatus().toString());
-        }
-
-        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
-        DataStoreLifeCycle dataStoreLifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-        ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).disableStoragePool(store);
-    }
-
-    @ActionEvent(eventType = EventTypes.EVENT_ENABLE_PRIMARY_STORAGE, eventDescription = "enable storage pool")
-    private void enablePrimaryStoragePool(StoragePoolVO primaryStorage) {
-        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Disabled)) {
-            throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be enabled. Storage pool state : " + primaryStorage.getStatus().toString());
-        }
-
-        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
-        DataStoreLifeCycle dataStoreLifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-        ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).enableStoragePool(store);
-    }
-
-    @Override
-    public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException {
-        // Input validation
-        Long id = cmd.getId();
-
-        StoragePoolVO pool = _storagePoolDao.findById(id);
-        if (pool == null) {
-            throw new IllegalArgumentException("Unable to find storage pool with ID: " + id);
-        }
-
-        final List<String> storagePoolTags = cmd.getTags();
-        if (storagePoolTags != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Updating Storage Pool Tags to :" + storagePoolTags);
-            }
-            _storagePoolTagsDao.persist(pool.getId(), storagePoolTags);
-        }
-
-        Long updatedCapacityBytes = null;
-        Long capacityBytes = cmd.getCapacityBytes();
-
-        if (capacityBytes != null) {
-            if (capacityBytes != pool.getCapacityBytes()) {
-                updatedCapacityBytes = capacityBytes;
-            }
-        }
-
-        Long updatedCapacityIops = null;
-        Long capacityIops = cmd.getCapacityIops();
-
-        if (capacityIops != null) {
-            if (!capacityIops.equals(pool.getCapacityIops())) {
-                updatedCapacityIops = capacityIops;
-            }
-        }
-
-        if (updatedCapacityBytes != null || updatedCapacityIops != null) {
-            StoragePoolVO storagePool = _storagePoolDao.findById(id);
-            DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName());
-            DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle();
-
-            if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) {
-                Map<String, String> details = new HashMap<String, String>();
-
-                details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, updatedCapacityBytes != null ? String.valueOf(updatedCapacityBytes) : null);
-                details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, updatedCapacityIops != null ? String.valueOf(updatedCapacityIops) : null);
-
-                ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(storagePool, details);
-            }
-        }
-
-        Boolean enabled = cmd.getEnabled();
-        if (enabled != null) {
-            if (enabled) {
-                enablePrimaryStoragePool(pool);
-            } else {
-                disablePrimaryStoragePool(pool);
-            }
-        }
-
-        if (updatedCapacityBytes != null) {
-            _storagePoolDao.updateCapacityBytes(id, capacityBytes);
-        }
-
-        if (updatedCapacityIops != null) {
-            _storagePoolDao.updateCapacityIops(id, capacityIops);
-        }
-
-        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-    }
-
-    @Override
-    public void removeStoragePoolFromCluster(long hostId, String iScsiName, StoragePool storagePool) {
-        final Map<String, String> details = new HashMap<>();
-
-        details.put(DeleteStoragePoolCommand.DATASTORE_NAME, iScsiName);
-        details.put(DeleteStoragePoolCommand.IQN, iScsiName);
-        details.put(DeleteStoragePoolCommand.STORAGE_HOST, storagePool.getHostAddress());
-        details.put(DeleteStoragePoolCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
-
-        final DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand();
-
-        cmd.setDetails(details);
-        cmd.setRemoveDatastore(true);
-
-        final Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null || !answer.getResult()) {
-            String errMsg = "Error interacting with host (related to DeleteStoragePoolCommand)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : "");
-
-            s_logger.error(errMsg);
-
-            throw new CloudRuntimeException(errMsg);
-        }
-    }
-
-    @Override
-    @DB
-    public boolean deletePool(DeletePoolCmd cmd) {
-        Long id = cmd.getId();
-        boolean forced = cmd.isForced();
-
-        StoragePoolVO sPool = _storagePoolDao.findById(id);
-        if (sPool == null) {
-            s_logger.warn("Unable to find pool:" + id);
-            throw new InvalidParameterValueException("Unable to find pool by id " + id);
-        }
-        if (sPool.getStatus() != StoragePoolStatus.Maintenance) {
-            s_logger.warn("Unable to delete storage id: " + id + " due to it is not in Maintenance state");
-            throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
-        }
-
-        Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(id);
-        if (forced) {
-            if (vlms.first() > 0) {
-                Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(id);
-                if (nonDstrdVlms.first() > 0) {
-                    throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
-                }
-                // force expunge non-destroyed volumes
-                List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed();
-                for (VolumeVO vol : vols) {
-                    AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));
-                    try {
-                        future.get();
-                    } catch (InterruptedException e) {
-                        s_logger.debug("expunge volume failed:" + vol.getId(), e);
-                    } catch (ExecutionException e) {
-                        s_logger.debug("expunge volume failed:" + vol.getId(), e);
-                    }
-                }
-            }
-        } else {
-            // Check if the pool has associated volumes in the volumes table
-            // If it does , then you cannot delete the pool
-            if (vlms.first() > 0) {
-                throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated volumes for this pool");
-            }
-        }
-
-        // First get the host_id from storage_pool_host_ref for given pool id
-        StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId());
-
-        if (lock == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to acquire lock when deleting PrimaryDataStoreVO with ID: " + sPool.getId());
-            }
-            return false;
-        }
-
-        _storagePoolDao.releaseFromLockTable(lock.getId());
-        s_logger.trace("Released lock for storage pool " + id);
-
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
-        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
-        DataStore store = _dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary);
-        return lifeCycle.deleteDataStore(store);
-    }
-
-    @Override
-    public void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException {
-        StoragePool pool = (StoragePool)_dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
-        assert (pool.isShared()) : "Now, did you actually read the name of this method?";
-        s_logger.debug("Adding pool " + pool.getName() + " to  host " + hostId);
-
-        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
-        HypervisorHostListener listener = hostListeners.get(provider.getName());
-        listener.hostConnect(hostId, pool.getId());
-    }
-
-    @Override
-    public BigDecimal getStorageOverProvisioningFactor(Long poolId) {
-        return new BigDecimal(CapacityManager.StorageOverprovisioningFactor.valueIn(poolId));
-    }
-
-    @Override
-    public void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated) {
-        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
-        capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, storagePool.getId());
-        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, storagePool.getDataCenterId());
-        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
-
-        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
-
-        long totalOverProvCapacity;
-        if (storagePool.getPoolType().supportsOverProvisioning()) {
-            // All this is for the inaccuracy of floats for big number multiplication.
-            BigDecimal overProvFactor = getStorageOverProvisioningFactor(storagePool.getId());
-            totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();
-            s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString() + " with overprovisioning factor " + overProvFactor.toString());
-            s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + storagePool.getCapacityBytes());
-        } else {
-            s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString());
-            totalOverProvCapacity = storagePool.getCapacityBytes();
-        }
-
-        s_logger.debug("Total over provisioned capacity of the pool " + storagePool.getName() + " id: " + storagePool.getId() + " is " + totalOverProvCapacity);
-        CapacityState capacityState = CapacityState.Enabled;
-        if (storagePool.getScope() == ScopeType.ZONE) {
-            DataCenterVO dc = ApiDBUtils.findZoneById(storagePool.getDataCenterId());
-            AllocationState allocationState = dc.getAllocationState();
-            capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
-        } else {
-            if (storagePool.getClusterId() != null) {
-                ClusterVO cluster = ApiDBUtils.findClusterById(storagePool.getClusterId());
-                if (cluster != null) {
-                    AllocationState allocationState = _configMgr.findClusterAllocationState(cluster);
-                    capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
-                }
-            }
-        }
-
-        if (storagePool.getScope() == ScopeType.HOST) {
-            List<StoragePoolHostVO> stoargePoolHostVO = _storagePoolHostDao.listByPoolId(storagePool.getId());
-
-            if (stoargePoolHostVO != null && !stoargePoolHostVO.isEmpty()) {
-                HostVO host = _hostDao.findById(stoargePoolHostVO.get(0).getHostId());
-
-                if (host != null) {
-                    capacityState = (host.getResourceState() == ResourceState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
-                }
-            }
-        }
-
-        if (capacities.size() == 0) {
-            CapacityVO capacity = new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), storagePool.getClusterId(), allocated, totalOverProvCapacity,
-                    capacityType);
-            capacity.setCapacityState(capacityState);
-            _capacityDao.persist(capacity);
-        } else {
-            CapacityVO capacity = capacities.get(0);
-            if (capacity.getTotalCapacity() != totalOverProvCapacity || allocated != capacity.getUsedCapacity() || capacity.getCapacityState() != capacityState) {
-                capacity.setTotalCapacity(totalOverProvCapacity);
-                capacity.setUsedCapacity(allocated);
-                capacity.setCapacityState(capacityState);
-                _capacityDao.update(capacity.getId(), capacity);
-            }
-        }
-        s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - " + storagePool.getDataCenterId() + ", HostOrPoolId - "
-                + storagePool.getId() + ", PodId " + storagePool.getPodId());
-    }
-
-    @Override
-    public List<Long> getUpHostsInPool(long poolId) {
-        SearchCriteria<Long> sc = UpHostsInPoolSearch.create();
-        sc.setParameters("pool", poolId);
-        sc.setJoinParameters("hosts", "status", Status.Up);
-        sc.setJoinParameters("hosts", "resourceState", ResourceState.Enabled);
-        return _storagePoolHostDao.customSearch(sc, null);
-    }
-
-    @Override
-    public Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException {
-        List<Long> hostIds = getUpHostsInPool(pool.getId());
-        Collections.shuffle(hostIds);
-        if (hostIdsToTryFirst != null) {
-            for (int i = hostIdsToTryFirst.length - 1; i >= 0; i--) {
-                if (hostIds.remove(hostIdsToTryFirst[i])) {
-                    hostIds.add(0, hostIdsToTryFirst[i]);
-                }
-            }
-        }
-
-        if (hostIdsToAvoid != null) {
-            hostIds.removeAll(hostIdsToAvoid);
-        }
-        if (hostIds == null || hostIds.isEmpty()) {
-            throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + " due to there is no enabled hosts up in this cluster", pool.getId());
-        }
-        for (Long hostId : hostIds) {
-            try {
-                List<Answer> answers = new ArrayList<Answer>();
-                Command[] cmdArray = cmds.toCommands();
-                for (Command cmd : cmdArray) {
-                    long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
-                    answers.add(_agentMgr.send(targetHostId, cmd));
-                }
-                return new Pair<Long, Answer[]>(hostId, answers.toArray(new Answer[answers.size()]));
-            } catch (AgentUnavailableException e) {
-                s_logger.debug("Unable to send storage pool command to " + pool + " via " + hostId, e);
-            } catch (OperationTimedoutException e) {
-                s_logger.debug("Unable to send storage pool command to " + pool + " via " + hostId, e);
-            }
-        }
-
-        throw new StorageUnavailableException("Unable to send command to the pool ", pool.getId());
-    }
-
-    @Override
-    public Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException {
-        Commands cmds = new Commands(cmd);
-        Pair<Long, Answer[]> result = sendToPool(pool, hostIdsToTryFirst, hostIdsToAvoid, cmds);
-        return new Pair<Long, Answer>(result.first(), result.second()[0]);
-    }
-
-    @Override
-    public void cleanupStorage(boolean recurring) {
-        GlobalLock scanLock = GlobalLock.getInternLock("storagemgr.cleanup");
-
-        try {
-            if (scanLock.lock(3)) {
-                try {
-                    // Cleanup primary storage pools
-                    if (TemplateCleanupEnabled.value()) {
-                        List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
-                        for (StoragePoolVO pool : storagePools) {
-                            try {
-
-                                List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
-                                s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
-                                for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
-                                    if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                                        s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
-                                        + " because it is not completely downloaded.");
-                                        continue;
-                                    }
-
-                                    if (!templatePoolVO.getMarkedForGC()) {
-                                        templatePoolVO.setMarkedForGC(true);
-                                        _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
-                                        s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
-                                        + " for garbage collection.");
-                                        continue;
-                                    }
-
-                                    _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
-                                }
-                            } catch (Exception e) {
-                                s_logger.warn("Problem cleaning up primary storage pool " + pool, e);
-                            }
-                        }
-                    }
-
-                    //destroy snapshots in destroying state in snapshot_store_ref
-                    List<SnapshotDataStoreVO> ssSnapshots = _snapshotStoreDao.listByState(ObjectInDataStoreStateMachine.State.Destroying);
-                    for (SnapshotDataStoreVO ssSnapshotVO : ssSnapshots) {
-                        try {
-                            _snapshotService.deleteSnapshot(snapshotFactory.getSnapshot(ssSnapshotVO.getSnapshotId(), DataStoreRole.Image));
-                        } catch (Exception e) {
-                            s_logger.debug("Failed to delete snapshot: " + ssSnapshotVO.getId() + " from storage");
-                        }
-                    }
-
-                    cleanupSecondaryStorage(recurring);
-
-                    List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long)StorageCleanupDelay.value() << 10)));
-                    for (VolumeVO vol : vols) {
-                        try {
-                            // If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
-                            // system, but not necessary.
-                            handleManagedStorage(vol);
-                        } catch (Exception e) {
-                            s_logger.warn("Unable to destroy host-side clustered file system " + vol.getUuid(), e);
-                        }
-
-                        try {
-                            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
-                            if (volumeInfo != null) {
-                                volService.expungeVolumeAsync(volumeInfo);
-                            } else {
-                                s_logger.debug("Volume " + vol.getUuid() + " is already destroyed");
-                            }
-                        } catch (Exception e) {
-                            s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
-                        }
-                    }
-
-                    // remove snapshots in Error state
-                    List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
-                    for (SnapshotVO snapshotVO : snapshots) {
-                        try {
-                            List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
-                            for (SnapshotDataStoreVO ref : storeRefs) {
-                                _snapshotStoreDao.expunge(ref.getId());
-                            }
-                            _snapshotDao.expunge(snapshotVO.getId());
-                        } catch (Exception e) {
-                            s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
-                        }
-                    }
-
-                    // destroy uploaded volumes in abandoned/error state
-                    List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
-                    for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
-                        VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
-                        if (volume == null) {
-                            s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
-                            continue;
-                        }
-                        try {
-                            DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
-                            EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
-                            if (ep == null) {
-                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
-                                continue;
-                            }
-                            Host host = _hostDao.findById(ep.getId());
-                            if (host != null && host.getManagementServerId() != null) {
-                                if (_serverId == host.getManagementServerId().longValue()) {
-                                    volService.destroyVolume(volume.getId());
-                                    // decrement volume resource count
-                                    _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
-                                    // expunge volume from secondary if volume is on image store
-                                    VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
-                                    if (volOnSecondary != null) {
-                                        s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
-                                        AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
-                                        VolumeApiResult result = future.get();
-                                        if (!result.isSuccess()) {
-                                            s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
-                                        }
-                                    }
-                                }
-                            }
-                        } catch (Throwable th) {
-                            s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
-                        }
-                    }
-
-                    // destroy uploaded templates in abandoned/error state
-                    List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
-                    for (TemplateDataStoreVO templateDataStore : templateDataStores) {
-                        VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
-                        if (template == null) {
-                            s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
-                            continue;
-                        }
-                        try {
-                            DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
-                            EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
-                            if (ep == null) {
-                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
-                                continue;
-                            }
-                            Host host = _hostDao.findById(ep.getId());
-                            if (host != null && host.getManagementServerId() != null) {
-                                if (_serverId == host.getManagementServerId().longValue()) {
-                                    AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
-                                    TemplateApiResult result = future.get();
-                                    if (!result.isSuccess()) {
-                                        s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
-                                        continue;
-                                    }
-                                    // remove from template_zone_ref
-                                    List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity)dataStore).getDataCenterId(), template.getId());
-                                    if (templateZones != null) {
-                                        for (VMTemplateZoneVO templateZone : templateZones) {
-                                            _vmTemplateZoneDao.remove(templateZone.getId());
-                                        }
-                                    }
-                                    // mark all the occurrences of this template in the given store as destroyed
-                                    _templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
-                                    // find all eligible image stores for this template
-                                    List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
-                                    if (imageStores == null || imageStores.size() == 0) {
-                                        template.setState(VirtualMachineTemplate.State.Inactive);
-                                        _templateDao.update(template.getId(), template);
-
-                                        // decrement template resource count
-                                        _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
-                                    }
-                                }
-                            }
-                        } catch (Throwable th) {
-                            s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
-                        }
-                    }
-                } finally {
-                    scanLock.unlock();
-                }
-            }
-        } finally {
-            scanLock.releaseRef();
-        }
-    }
-
-    /**
-     * This method only applies for managed storage.
-     *
-     * For XenServer and vSphere, see if we need to remove an SR or a datastore, then remove the underlying volume
-     * from any applicable access control list (before other code attempts to delete the volume that supports it).
-     *
-     * For KVM, just tell the underlying storage plug-in to remove the volume from any applicable access control list
-     * (before other code attempts to delete the volume that supports it).
-     */
-    private void handleManagedStorage(Volume volume) {
-        Long instanceId = volume.getInstanceId();
-
-        if (instanceId != null) {
-            StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
-
-            if (storagePool != null && storagePool.isManaged()) {
-                VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
-
-                Long lastHostId = vmInstanceVO.getLastHostId();
-
-                if (lastHostId != null) {
-                    HostVO host = _hostDao.findById(lastHostId);
-                    ClusterVO cluster = _clusterDao.findById(host.getClusterId());
-                    VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
-
-                    if (cluster.getHypervisorType() == HypervisorType.KVM) {
-                        volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
-                    } else {
-                        DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
-                        DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
-
-                        DettachCommand cmd = new DettachCommand(disk, null);
-
-                        cmd.setManaged(true);
-
-                        cmd.setStorageHost(storagePool.getHostAddress());
-                        cmd.setStoragePort(storagePool.getPort());
-
-                        cmd.set_iScsiName(volume.get_iScsiName());
-
-                        Answer answer = _agentMgr.easySend(lastHostId, cmd);
-
-                        if (answer != null && answer.getResult()) {
-                            volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
-                        } else {
-                            s_logger.warn("Unable to remove host-side clustered file system for the following volume: " + volume.getUuid());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @DB
-    List<Long> findAllVolumeIdInSnapshotTable(Long storeId) {
-        String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE snapshots.id = snapshot_store_ref.snapshot_id and store_id=? GROUP BY volume_id";
-        List<Long> list = new ArrayList<Long>();
-        try {
-            TransactionLegacy txn = TransactionLegacy.currentTxn();
-            ResultSet rs = null;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, storeId);
-            rs = pstmt.executeQuery();
-            while (rs.next()) {
-                list.add(rs.getLong(1));
-            }
-            return list;
-        } catch (Exception e) {
-            s_logger.debug("failed to get all volumes who has snapshots in secondary storage " + storeId + " due to " + e.getMessage());
-            return null;
-        }
-
-    }
-
-    List<String> findAllSnapshotForVolume(Long volumeId) {
-        String sql = "SELECT backup_snap_id FROM snapshots WHERE volume_id=? and backup_snap_id is not NULL";
-        try {
-            TransactionLegacy txn = TransactionLegacy.currentTxn();
-            ResultSet rs = null;
-            PreparedStatement pstmt = null;
-            pstmt = txn.prepareAutoCloseStatement(sql);
-            pstmt.setLong(1, volumeId);
-            rs = pstmt.executeQuery();
-            List<String> list = new ArrayList<String>();
-            while (rs.next()) {
-                list.add(rs.getString(1));
-            }
-            return list;
-        } catch (Exception e) {
-            s_logger.debug("failed to get all snapshots for a volume " + volumeId + " due to " + e.getMessage());
-            return null;
-        }
-    }
-
-    @Override
-    @DB
-    public void cleanupSecondaryStorage(boolean recurring) {
-        // NOTE that object_store refactor will immediately delete the object from secondary storage when deleteTemplate etc api is issued.
-        // so here we don't need to issue DeleteCommand to resource anymore, only need to remove db entry.
-        try {
-            // Cleanup templates in template_store_ref
-            List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
-            for (DataStore store : imageStores) {
-                try {
-                    long storeId = store.getId();
-                    List<TemplateDataStoreVO> destroyedTemplateStoreVOs = _templateStoreDao.listDestroyed(storeId);
-                    s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() + " templates to cleanup on template_store_ref for store: " + store.getName());
-                    for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Deleting template store DB entry: " + destroyedTemplateStoreVO);
-                        }
-                        _templateStoreDao.remove(destroyedTemplateStoreVO.getId());
-                    }
-                } catch (Exception e) {
-                    s_logger.warn("problem cleaning up templates in template_store_ref for store: " + store.getName(), e);
-                }
-            }
-
-            // CleanUp snapshots on snapshot_store_ref
-            for (DataStore store : imageStores) {
-                try {
-                    List<SnapshotDataStoreVO> destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId());
-                    s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size() + " snapshots to cleanup on snapshot_store_ref for store: " + store.getName());
-                    for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) {
-                        // check if this snapshot has child
-                        SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store);
-                        if (snap.getChild() != null) {
-                            s_logger.debug("Skip snapshot on store: " + destroyedSnapshotStoreVO + " , because it has child");
-                            continue;
-                        }
-
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Deleting snapshot store DB entry: " + destroyedSnapshotStoreVO);
-                        }
-
-                        _snapshotDao.remove(destroyedSnapshotStoreVO.getSnapshotId());
-                        SnapshotDataStoreVO snapshotOnPrimary = _snapshotStoreDao.findBySnapshot(destroyedSnapshotStoreVO.getSnapshotId(), DataStoreRole.Primary);
-                        if (snapshotOnPrimary != null) {
-                            _snapshotStoreDao.remove(snapshotOnPrimary.getId());
-                        }
-                        _snapshotStoreDao.remove(destroyedSnapshotStoreVO.getId());
-                    }
-
-                } catch (Exception e2) {
-                    s_logger.warn("problem cleaning up snapshots in snapshot_store_ref for store: " + store.getName(), e2);
-                }
-
-            }
-
-            // CleanUp volumes on volume_store_ref
-            for (DataStore store : imageStores) {
-                try {
-                    List<VolumeDataStoreVO> destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId());
-                    s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size() + " volumes to cleanup on volume_store_ref for store: " + store.getName());
-                    for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Deleting volume store DB entry: " + destroyedStoreVO);
-                        }
-                        _volumeStoreDao.remove(destroyedStoreVO.getId());
-                    }
-
-                } catch (Exception e2) {
-                    s_logger.warn("problem cleaning up volumes in volume_store_ref for store: " + store.getName(), e2);
-                }
-            }
-        } catch (Exception e3) {
-            s_logger.warn("problem cleaning up secondary storage DB entries. ", e3);
-        }
-    }
-
-    @Override
-    public String getPrimaryStorageNameLabel(VolumeVO volume) {
-        Long poolId = volume.getPoolId();
-
-        // poolId is null only if volume is destroyed, which has been checked
-        // before.
-        assert poolId != null;
-        StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(poolId);
-        assert PrimaryDataStoreVO != null;
-        return PrimaryDataStoreVO.getUuid();
-    }
-
-    @Override
-    @DB
-    public PrimaryDataStoreInfo preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException {
-        StoragePoolVO primaryStorage = null;
-        primaryStorage = _storagePoolDao.findById(primaryStorageId);
-
-        if (primaryStorage == null) {
-            String msg = "Unable to obtain lock on the storage pool record in preparePrimaryStorageForMaintenance()";
-            s_logger.error(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-
-        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) {
-            throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
-        }
-
-        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
-        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-        lifeCycle.maintain(store);
-
-        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-    }
-
-    @Override
-    @DB
-    public PrimaryDataStoreInfo cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException {
-        Long primaryStorageId = cmd.getId();
-        StoragePoolVO primaryStorage = null;
-
-        primaryStorage = _storagePoolDao.findById(primaryStorageId);
-
-        if (primaryStorage == null) {
-            String msg = "Unable to obtain lock on the storage pool in cancelPrimaryStorageForMaintenance()";
-            s_logger.error(msg);
-            throw new InvalidParameterValueException(msg);
-        }
-
-        if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) {
-            throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString(),
-                    primaryStorageId);
-        }
-
-        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
-        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-        lifeCycle.cancelMaintain(store);
-
-        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-    }
-
-    protected class StorageGarbageCollector extends ManagedContextRunnable {
-
-        public StorageGarbageCollector() {
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                s_logger.trace("Storage Garbage Collection Thread is running.");
-
-                cleanupStorage(true);
-
-            } catch (Exception e) {
-                s_logger.error("Caught the following Exception", e);
-            }
-        }
-    }
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-        for (ManagementServerHost vo : nodeList) {
-            if (vo.getMsid() == _serverId) {
-                s_logger.info("Cleaning up storage maintenance jobs associated with Management server: " + vo.getMsid());
-                List<Long> poolIds = _storagePoolWorkDao.searchForPoolIdsForPendingWorkJobs(vo.getMsid());
-                if (poolIds.size() > 0) {
-                    for (Long poolId : poolIds) {
-                        StoragePoolVO pool = _storagePoolDao.findById(poolId);
-                        // check if pool is in an inconsistent state
-                        if (pool != null && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)
-                                || pool.getStatus().equals(StoragePoolStatus.CancelMaintenance))) {
-                            _storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId);
-                            pool.setStatus(StoragePoolStatus.ErrorInMaintenance);
-                            _storagePoolDao.update(poolId, pool);
-                        }
-
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    @Override
-    public CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId) {
-        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-        if (zoneId != null) {
-            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        List<Long> hosts = new ArrayList<Long>();
-        if (hostId != null) {
-            hosts.add(hostId);
-        } else {
-            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
-            if (stores != null) {
-                for (DataStore store : stores) {
-                    hosts.add(store.getId());
-                }
-            }
-        }
-
-        CapacityVO capacity = new CapacityVO(hostId, zoneId, null, null, 0, 0, Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
-        for (Long id : hosts) {
-            StorageStats stats = ApiDBUtils.getSecondaryStorageStatistics(id);
-            if (stats == null) {
-                continue;
-            }
-            capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity());
-            capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
-        }
-
-        return capacity;
-    }
-
-    @Override
-    public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId) {
-        SearchCriteria<StoragePoolVO> sc = _storagePoolDao.createSearchCriteria();
-        List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
-
-        if (zoneId != null) {
-            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
-        }
-
-        if (podId != null) {
-            sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
-        }
-
-        if (clusterId != null) {
-            sc.addAnd("clusterId", SearchCriteria.Op.EQ, clusterId);
-        }
-
-        if (poolId != null) {
-            sc.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, poolId);
-        }
-        if (poolId != null) {
-            pools.add(_storagePoolDao.findById(poolId));
-        } else {
-            pools = _storagePoolDao.search(sc, null);
-        }
-
-        CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, Capacity.CAPACITY_TYPE_STORAGE);
-        for (StoragePoolVO PrimaryDataStoreVO : pools) {
-            StorageStats stats = ApiDBUtils.getStoragePoolStatistics(PrimaryDataStoreVO.getId());
-            if (stats == null) {
-                continue;
-            }
-            capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity());
-            capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
-        }
-        return capacity;
-    }
-
-    @Override
-    public PrimaryDataStoreInfo getStoragePool(long id) {
-        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(id, DataStoreRole.Primary);
-    }
-
-    @Override
-    @DB
-    public List<VMInstanceVO> listByStoragePool(long storagePoolId) {
-        SearchCriteria<VMInstanceVO> sc = StoragePoolSearch.create();
-        sc.setJoinParameters("vmVolume", "volumeType", Volume.Type.ROOT);
-        sc.setJoinParameters("vmVolume", "poolId", storagePoolId);
-        sc.setJoinParameters("vmVolume", "state", Volume.State.Ready);
-        return _vmInstanceDao.search(sc, null);
-    }
-
-    @Override
-    @DB
-    public StoragePoolVO findLocalStorageOnHost(long hostId) {
-        SearchCriteria<StoragePoolVO> sc = LocalStorageSearch.create();
-        sc.setParameters("type", new Object[] {StoragePoolType.Filesystem, StoragePoolType.LVM});
-        sc.setJoinParameters("poolHost", "hostId", hostId);
-        List<StoragePoolVO> storagePools = _storagePoolDao.search(sc, null);
-        if (!storagePools.isEmpty()) {
-            return storagePools.get(0);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public Host updateSecondaryStorage(long secStorageId, String newUrl) {
-        HostVO secHost = _hostDao.findById(secStorageId);
-        if (secHost == null) {
-            throw new InvalidParameterValueException("Can not find out the secondary storage id: " + secStorageId);
-        }
-
-        if (secHost.getType() != Host.Type.SecondaryStorage) {
-            throw new InvalidParameterValueException("host: " + secStorageId + " is not a secondary storage");
-        }
-
-        URI uri = null;
-        try {
-            uri = new URI(UriUtils.encodeURIComponent(newUrl));
-            if (uri.getScheme() == null) {
-                throw new InvalidParameterValueException("uri.scheme is null " + newUrl + ", add nfs:// (or cifs://) as a prefix");
-            } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
-                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
-                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format nfs://hostname/path");
-                }
-            } else if (uri.getScheme().equalsIgnoreCase("cifs")) {
-                // Don't validate against a URI encoded URI.
-                URI cifsUri = new URI(newUrl);
-                String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
-                if (warnMsg != null) {
-                    throw new InvalidParameterValueException(warnMsg);
-                }
-            }
-        } catch (URISyntaxException e) {
-            throw new InvalidParameterValueException(newUrl + " is not a valid uri");
-        }
-
-        String oldUrl = secHost.getStorageUrl();
-
-        URI oldUri = null;
-        try {
-            oldUri = new URI(UriUtils.encodeURIComponent(oldUrl));
-            if (!oldUri.getScheme().equalsIgnoreCase(uri.getScheme())) {
-                throw new InvalidParameterValueException("can not change old scheme:" + oldUri.getScheme() + " to " + uri.getScheme());
-            }
-        } catch (URISyntaxException e) {
-            s_logger.debug("Failed to get uri from " + oldUrl);
-        }
-
-        secHost.setStorageUrl(newUrl);
-        secHost.setGuid(newUrl);
-        secHost.setName(newUrl);
-        _hostDao.update(secHost.getId(), secHost);
-        return secHost;
-    }
-
-    @Override
-    public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) {
-
-        if (format == null) {
-            return HypervisorType.None;
-        }
-
-        if (format == ImageFormat.VHD) {
-            return HypervisorType.XenServer;
-        } else if (format == ImageFormat.OVA) {
-            return HypervisorType.VMware;
-        } else if (format == ImageFormat.QCOW2) {
-            return HypervisorType.KVM;
-        } else if (format == ImageFormat.RAW) {
-            return HypervisorType.Ovm;
-        } else if (format == ImageFormat.VHDX) {
-            return HypervisorType.Hyperv;
-        } else {
-            return HypervisorType.None;
-        }
-    }
-
-    private boolean checkUsagedSpace(StoragePool pool) {
-        // Managed storage does not currently deal with accounting for physically used space (only provisioned space). Just return true if "pool" is managed.
-        if (pool.isManaged()) {
-            return true;
-        }
-
-        StatsCollector sc = StatsCollector.getInstance();
-        double storageUsedThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(pool.getDataCenterId());
-        if (sc != null) {
-            long totalSize = pool.getCapacityBytes();
-            StorageStats stats = sc.getStoragePoolStats(pool.getId());
-            if (stats == null) {
-                stats = sc.getStorageStats(pool.getId());
-            }
-            if (stats != null) {
-                double usedPercentage = ((double)stats.getByteUsed() / (double)totalSize);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Checking pool " + pool.getId() + " for storage, totalSize: " + pool.getCapacityBytes() + ", usedBytes: " + stats.getByteUsed() + ", usedPct: " + usedPercentage
-                            + ", disable threshold: " + storageUsedThreshold);
-                }
-                if (usedPercentage >= storageUsedThreshold) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Insufficient space on pool: " + pool.getId() + " since its usage percentage: " + usedPercentage + " has crossed the pool.storage.capacity.disablethreshold: "
-                                + storageUsedThreshold);
-                    }
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean storagePoolHasEnoughIops(List<Volume> requestedVolumes, StoragePool pool) {
-        if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
-            return false;
-        }
-
-        // Only IOPS-guaranteed primary storage like SolidFire is using/setting IOPS.
-        // This check returns true for storage that does not specify IOPS.
-        if (pool.getCapacityIops() == null) {
-            s_logger.info("Storage pool " + pool.getName() + " (" + pool.getId() + ") does not supply IOPS capacity, assuming enough capacity");
-
-            return true;
-        }
-
-        StoragePoolVO storagePoolVo = _storagePoolDao.findById(pool.getId());
-        long currentIops = _capacityMgr.getUsedIops(storagePoolVo);
-
-        long requestedIops = 0;
-
-        for (Volume requestedVolume : requestedVolumes) {
-            Long minIops = requestedVolume.getMinIops();
-
-            if (minIops != null && minIops > 0) {
-                requestedIops += minIops;
-            }
-        }
-
-        long futureIops = currentIops + requestedIops;
-
-        return futureIops <= pool.getCapacityIops();
-    }
-
-    @Override
-    public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool) {
-        return storagePoolHasEnoughSpace(volumes, pool, null);
-    }
-
-    @Override
-    public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool, Long clusterId) {
-        if (volumes == null || volumes.isEmpty()) {
-            return false;
-        }
-
-        if (!checkUsagedSpace(pool)) {
-            return false;
-        }
-
-        // allocated space includes templates
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Destination pool id: " + pool.getId());
-        }
-        // allocated space includes templates
-        final StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
-        long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
-        long totalAskingSize = 0;
-
-        for (Volume volume : volumes) {
-            // refreshing the volume from the DB to get latest hv_ss_reserve (hypervisor snapshot reserve) field
-            // I could have just assigned this to "volume", but decided to make a new variable for it so that it
-            // might be clearer that this "volume" in "volumes" still might have an old value for hv_ss_reverse.
-            VolumeVO volumeVO = _volumeDao.findById(volume.getId());
-
-            if (volumeVO.getHypervisorSnapshotReserve() == null) {
-                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
-                volService.updateHypervisorSnapshotReserveForVolume(getDiskOfferingVO(volumeVO), volumeVO.getId(), getHypervisorType(volumeVO));
-
-                // hv_ss_reserve field might have been updated; refresh from DB to make use of it in getDataObjectSizeIncludingHypervisorSnapshotReserve
-                volumeVO = _volumeDao.findById(volume.getId());
-            }
-
-            // this if statement should resolve to true at most once per execution of the for loop its contained within (for a root disk that is
-            // to leverage a template)
-            if (volume.getTemplateId() != null) {
-                VMTemplateVO tmpl = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
-
-                if (tmpl != null && !ImageFormat.ISO.equals(tmpl.getFormat())) {
-                    allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, tmpl);
-                }
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Pool ID for the volume with ID " + volumeVO.getId() + " is " + volumeVO.getPoolId());
-            }
-
-            // 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 ((volumeVO.getState() != Volume.State.Ready) || (volumeVO.getPoolId() != pool.getId())) {
-                totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeVO, poolVO);
-
-                totalAskingSize += getAskingSizeForTemplateBasedOnClusterAndStoragePool(volumeVO.getTemplateId(), clusterId, poolVO);
-            }
-        }
-
-        return checkPoolforSpace(pool, allocatedSizeWithTemplate, totalAskingSize);
-    }
-
-    @Override
-    public boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSiz) {
-        if (!checkUsagedSpace(pool)) {
-            return false;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Destination pool id: " + pool.getId());
-        }
-        long totalAskingSize = newSiz - currentSize;
-
-        if (totalAskingSize <= 0) {
-            return true;
-        } else {
-            final StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
-            final long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
-            return checkPoolforSpace(pool, allocatedSizeWithTemplate, totalAskingSize);
-        }
-    }
-
-    private boolean checkPoolforSpace(StoragePool pool, long allocatedSizeWithTemplate, long totalAskingSize) {
-        // allocated space includes templates
-        StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
-
-        long totalOverProvCapacity;
-
-        if (pool.getPoolType().supportsOverProvisioning()) {
-            BigDecimal overProvFactor = getStorageOverProvisioningFactor(pool.getId());
-            totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(pool.getCapacityBytes())).longValue();
-            s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString() + " with overprovisioning factor " + overProvFactor.toString());
-            s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + pool.getCapacityBytes());
-        } else {
-            totalOverProvCapacity = pool.getCapacityBytes();
-
-            s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString());
-        }
-
-        s_logger.debug("Total capacity of the pool " + poolVO.getName() + " with ID " + pool.getId() + " is " + totalOverProvCapacity);
-
-        double storageAllocatedThreshold = CapacityManager.StorageAllocatedCapacityDisableThreshold.valueIn(pool.getDataCenterId());
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Checking pool: " + pool.getId() + " for storage allocation , maxSize : " + totalOverProvCapacity + ", totalAllocatedSize : " + allocatedSizeWithTemplate
-                    + ", askingSize : " + totalAskingSize + ", allocated disable threshold: " + storageAllocatedThreshold);
-        }
-
-        double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize) / (double)(totalOverProvCapacity);
-
-        if (usedPercentage > storageAllocatedThreshold) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for storage allocation since its allocated percentage: " + usedPercentage
-                        + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " + storageAllocatedThreshold + ", skipping this pool");
-            }
-            return false;
-        }
-
-        if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for storage allocation, not enough storage, maxSize : " + totalOverProvCapacity
-                        + ", totalAllocatedSize : " + allocatedSizeWithTemplate + ", askingSize : " + totalAskingSize);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Storage plug-ins for managed storage can be designed in such a way as to store a template on the primary storage once and
-     * make use of it via storage-side cloning.
-     *
-     * This method determines how many more bytes it will need for the template (if the template is already stored on the primary storage,
-     * then the answer is 0).
-     */
-    private long getAskingSizeForTemplateBasedOnClusterAndStoragePool(Long templateId, Long clusterId, StoragePoolVO storagePoolVO) {
-        if (templateId == null || clusterId == null || storagePoolVO == null || !storagePoolVO.isManaged()) {
-            return 0;
-        }
-
-        VMTemplateVO tmpl = _templateDao.findByIdIncludingRemoved(templateId);
-
-        if (tmpl == null || ImageFormat.ISO.equals(tmpl.getFormat())) {
-            return 0;
-        }
-
-        HypervisorType hypervisorType = tmpl.getHypervisorType();
-
-        // The getSupportsResigning method is applicable for XenServer as a UUID-resigning patch may or may not be installed on those hypervisor hosts.
-        if (_clusterDao.getSupportsResigning(clusterId) || HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
-            return getBytesRequiredForTemplate(tmpl, storagePoolVO);
-        }
-
-        return 0;
-    }
-
-    private long getDataObjectSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
-        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
-
-        if (storeDriver instanceof PrimaryDataStoreDriver) {
-            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
-
-            VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
-
-            return primaryStoreDriver.getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, pool);
-        }
-
-        return volume.getSize();
-    }
-
-    private DiskOfferingVO getDiskOfferingVO(Volume volume) {
-        Long diskOfferingId = volume.getDiskOfferingId();
-
-        return _diskOfferingDao.findById(diskOfferingId);
-    }
-
-    private HypervisorType getHypervisorType(Volume volume) {
-        Long instanceId = volume.getInstanceId();
-
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId);
-
-        if (vmInstance != null) {
-            return vmInstance.getHypervisorType();
-        }
-
-        return null;
-    }
-
-    private long getBytesRequiredForTemplate(VMTemplateVO tmpl, StoragePool pool) {
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
-        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
-
-        if (storeDriver instanceof PrimaryDataStoreDriver) {
-            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
-
-            TemplateInfo templateInfo = tmplFactory.getReadyTemplateOnImageStore(tmpl.getId(), pool.getDataCenterId());
-
-            return primaryStoreDriver.getBytesRequiredForTemplate(templateInfo, pool);
-        }
-
-        return tmpl.getSize();
-    }
-
-    @Override
-    public void createCapacityEntry(long poolId) {
-        StoragePoolVO storage = _storagePoolDao.findById(poolId);
-        createCapacityEntry(storage, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, 0);
-    }
-
-    @Override
-    public synchronized boolean registerHostListener(String providerName, HypervisorHostListener listener) {
-        hostListeners.put(providerName, listener);
-        return true;
-    }
-
-    @Override
-    public Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
-
-        if (storeProvider == null) {
-            storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider();
-            if (storeProvider == null) {
-                throw new InvalidParameterValueException("can't find image store provider: " + providerName);
-            }
-            providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name
-        }
-
-        ScopeType scopeType = ScopeType.ZONE;
-        if (zoneId == null) {
-            scopeType = ScopeType.REGION;
-        }
-
-        if (name == null) {
-            name = url;
-        }
-
-        ImageStoreVO imageStore = _imageStoreDao.findByName(name);
-        if (imageStore != null) {
-            throw new InvalidParameterValueException("The image store with name " + name + " already exists, try creating with another name");
-        }
-
-        // check if scope is supported by store provider
-        if (!((ImageStoreProvider)storeProvider).isScopeSupported(scopeType)) {
-            throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType);
-        }
-
-        // check if we have already image stores from other different providers,
-        // we currently are not supporting image stores from different
-        // providers co-existing
-        List<ImageStoreVO> imageStores = _imageStoreDao.listImageStores();
-        for (ImageStoreVO store : imageStores) {
-            if (!store.getProviderName().equalsIgnoreCase(providerName)) {
-                throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added");
-            }
-        }
-
-        if (zoneId != null) {
-            // Check if the zone exists in the system
-            DataCenterVO zone = _dcDao.findById(zoneId);
-            if (zone == null) {
-                throw new InvalidParameterValueException("Can't find zone by id " + zoneId);
-            }
-
-            Account account = CallContext.current().getCallingAccount();
-            if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
-                PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-                ex.addProxyObject(zone.getUuid(), "dcId");
-                throw ex;
-            }
-        }
-
-        Map<String, Object> params = new HashMap();
-        params.put("zoneId", zoneId);
-        params.put("url", url);
-        params.put("name", name);
-        params.put("details", details);
-        params.put("scope", scopeType);
-        params.put("providerName", storeProvider.getName());
-        params.put("role", DataStoreRole.Image);
-
-        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
-
-        DataStore store;
-        try {
-            store = lifeCycle.initialize(params);
-        } catch (Exception e) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Failed to add data store: " + e.getMessage(), e);
-            }
-            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
-        }
-
-        if (((ImageStoreProvider)storeProvider).needDownloadSysTemplate()) {
-            // trigger system vm template download
-            _imageSrv.downloadBootstrapSysTemplate(store);
-        } else {
-            // populate template_store_ref table
-            _imageSrv.addSystemVMTemplatesToSecondary(store);
-        }
-
-        // associate builtin template with zones associated with this image store
-        associateCrosszoneTemplatesToZone(zoneId);
-
-        // duplicate cache store records to region wide storage
-        if (scopeType == ScopeType.REGION) {
-            duplicateCacheStoreRecordsToRegionStore(store.getId());
-        }
-
-        return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
-    }
-
-    @Override
-    public ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
-        // check if current cloud is ready to migrate, we only support cloud with only NFS secondary storages
-        List<ImageStoreVO> imgStores = _imageStoreDao.listImageStores();
-        List<ImageStoreVO> nfsStores = new ArrayList<ImageStoreVO>();
-        if (imgStores != null && imgStores.size() > 0) {
-            for (ImageStoreVO store : imgStores) {
-                if (!store.getProviderName().equals(DataStoreProvider.NFS_IMAGE)) {
-                    throw new InvalidParameterValueException("We only support migrate NFS secondary storage to use object store!");
-                } else {
-                    nfsStores.add(store);
-                }
-            }
-        }
-        // convert all NFS secondary storage to staging store
-        if (nfsStores != null && nfsStores.size() > 0) {
-            for (ImageStoreVO store : nfsStores) {
-                long storeId = store.getId();
-
-                _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
-
-                DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(store.getProviderName());
-                DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
-                DataStore secStore = _dataStoreMgr.getDataStore(storeId, DataStoreRole.Image);
-                lifeCycle.migrateToObjectStore(secStore);
-                // update store_role in template_store_ref and snapshot_store_ref to ImageCache
-                _templateStoreDao.updateStoreRoleToCachce(storeId);
-                _snapshotStoreDao.updateStoreRoleToCache(storeId);
-            }
-        }
-        // add object store
-        return discoverImageStore(name, url, providerName, null, details);
-    }
-
-    private void duplicateCacheStoreRecordsToRegionStore(long storeId) {
-        _templateStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
-        _snapshotStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
-        _volumeStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
-    }
-
-    private void associateCrosszoneTemplatesToZone(Long zoneId) {
-        VMTemplateZoneVO tmpltZone;
-
-        List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
-        List<Long> dcIds = new ArrayList<Long>();
-        if (zoneId != null) {
-            dcIds.add(zoneId);
-        } else {
-            List<DataCenterVO> dcs = _dcDao.listAll();
-            if (dcs != null) {
-                for (DataCenterVO dc : dcs) {
-                    dcIds.add(dc.getId());
-                }
-            }
-        }
-
-        for (VMTemplateVO vt : allTemplates) {
-            if (vt.isCrossZones()) {
-                for (Long dcId : dcIds) {
-                    tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
-                    if (tmpltZone == null) {
-                        VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
-                        _vmTemplateZoneDao.persist(vmTemplateZone);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean deleteImageStore(DeleteImageStoreCmd cmd) {
-        final long storeId = cmd.getId();
-        // Verify that image store exists
-        ImageStoreVO store = _imageStoreDao.findById(storeId);
-        if (store == null) {
-            throw new InvalidParameterValueException("Image store with id " + storeId + " doesn't exist");
-        }
-        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
-
-        // Verify that there are no live snapshot, template, volume on the image
-        // store to be deleted
-        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listByStoreId(storeId, DataStoreRole.Image);
-        if (snapshots != null && snapshots.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete image store with active snapshots backup!");
-        }
-        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listByStoreId(storeId);
-        if (volumes != null && volumes.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete image store with active volumes backup!");
-        }
-
-        // search if there are user templates stored on this image store, excluding system, builtin templates
-        List<TemplateJoinVO> templates = _templateViewDao.listActiveTemplates(storeId);
-        if (templates != null && templates.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete image store with active templates backup!");
-        }
-
-        // ready to delete
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // first delete from image_store_details table, we need to do that since
-                // we are not actually deleting record from main
-                // image_data_store table, so delete cascade will not work
-                _imageStoreDetailsDao.deleteDetails(storeId);
-                _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.Image);
-                _volumeStoreDao.deletePrimaryRecordsForStore(storeId);
-                _templateStoreDao.deletePrimaryRecordsForStore(storeId);
-                _imageStoreDao.remove(storeId);
-            }
-        });
-
-        return true;
-    }
-
-    @Override
-    public ImageStore createSecondaryStagingStore(CreateSecondaryStagingStoreCmd cmd) {
-        String providerName = cmd.getProviderName();
-        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
-
-        if (storeProvider == null) {
-            storeProvider = _dataStoreProviderMgr.getDefaultCacheDataStoreProvider();
-            if (storeProvider == null) {
-                throw new InvalidParameterValueException("can't find cache store provider: " + providerName);
-            }
-        }
-
-        Long dcId = cmd.getZoneId();
-
-        ScopeType scopeType = null;
-        String scope = cmd.getScope();
-        if (scope != null) {
-            try {
-                scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
-
-            } catch (Exception e) {
-                throw new InvalidParameterValueException("invalid scope for cache store " + scope);
-            }
-
-            if (scopeType != ScopeType.ZONE) {
-                throw new InvalidParameterValueException("Only zone wide cache storage is supported");
-            }
-        }
-
-        if (scopeType == ScopeType.ZONE && dcId == null) {
-            throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
-        }
-
-        // Check if the zone exists in the system
-        DataCenterVO zone = _dcDao.findById(dcId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id " + dcId);
-        }
-
-        Account account = CallContext.current().getCallingAccount();
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
-            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
-            ex.addProxyObject(zone.getUuid(), "dcId");
-            throw ex;
-        }
-
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.put("zoneId", dcId);
-        params.put("url", cmd.getUrl());
-        params.put("name", cmd.getUrl());
-        params.put("details", cmd.getDetails());
-        params.put("scope", scopeType);
-        params.put("providerName", storeProvider.getName());
-        params.put("role", DataStoreRole.ImageCache);
-
-        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
-        DataStore store = null;
-        try {
-            store = lifeCycle.initialize(params);
-        } catch (Exception e) {
-            s_logger.debug("Failed to add data store: " + e.getMessage(), e);
-            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
-        }
-
-        return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);
-    }
-
-    @Override
-    public boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd) {
-        final long storeId = cmd.getId();
-        // Verify that cache store exists
-        ImageStoreVO store = _imageStoreDao.findById(storeId);
-        if (store == null) {
-            throw new InvalidParameterValueException("Cache store with id " + storeId + " doesn't exist");
-        }
-        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
-
-        // Verify that there are no live snapshot, template, volume on the cache
-        // store that is currently referenced
-        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listActiveOnCache(storeId);
-        if (snapshots != null && snapshots.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete cache store with staging snapshots currently in use!");
-        }
-        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listActiveOnCache(storeId);
-        if (volumes != null && volumes.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete cache store with staging volumes currently in use!");
-        }
-
-        List<TemplateDataStoreVO> templates = _templateStoreDao.listActiveOnCache(storeId);
-        if (templates != null && templates.size() > 0) {
-            throw new InvalidParameterValueException("Cannot delete cache store with staging templates currently in use!");
-        }
-
-        // ready to delete
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // first delete from image_store_details table, we need to do that since
-                // we are not actually deleting record from main
-                // image_data_store table, so delete cascade will not work
-                _imageStoreDetailsDao.deleteDetails(storeId);
-                _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.ImageCache);
-                _volumeStoreDao.deletePrimaryRecordsForStore(storeId);
-                _templateStoreDao.deletePrimaryRecordsForStore(storeId);
-                _imageStoreDao.remove(storeId);
-            }
-        });
-
-        return true;
-    }
-
-    protected class DownloadURLGarbageCollector implements Runnable {
-
-        public DownloadURLGarbageCollector() {
-        }
-
-        @Override
-        public void run() {
-            try {
-                s_logger.trace("Download URL Garbage Collection Thread is running.");
-
-                cleanupDownloadUrls();
-
-            } catch (Exception e) {
-                s_logger.error("Caught the following Exception", e);
-            }
-        }
-    }
-
-    @Override
-    public void cleanupDownloadUrls() {
-
-        // Cleanup expired volume URLs
-        List<VolumeDataStoreVO> volumesOnImageStoreList = _volumeStoreDao.listVolumeDownloadUrls();
-        HashSet<Long> expiredVolumeIds = new HashSet<Long>();
-        HashSet<Long> activeVolumeIds = new HashSet<Long>();
-        for (VolumeDataStoreVO volumeOnImageStore : volumesOnImageStoreList) {
-
-            long volumeId = volumeOnImageStore.getVolumeId();
-            try {
-                long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), volumeOnImageStore.getExtractUrlCreated());
-                if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) {  // URL hasnt expired yet
-                    activeVolumeIds.add(volumeId);
-                    continue;
-                }
-                expiredVolumeIds.add(volumeId);
-                s_logger.debug("Removing download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeId);
-
-                // Remove it from image store
-                ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(volumeOnImageStore.getDataStoreId(), DataStoreRole.Image);
-                secStore.deleteExtractUrl(volumeOnImageStore.getInstallPath(), volumeOnImageStore.getExtractUrl(), Upload.Type.VOLUME);
-
-                // Now expunge it from DB since this entry was created only for download purpose
-                _volumeStoreDao.expunge(volumeOnImageStore.getId());
-            } catch (Throwable th) {
-                s_logger.warn("Caught exception while deleting download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeOnImageStore.getVolumeId(), th);
-            }
-        }
-        for (Long volumeId : expiredVolumeIds) {
-            if (activeVolumeIds.contains(volumeId)) {
-                continue;
-            }
-            Volume volume = _volumeDao.findById(volumeId);
-            if (volume != null && volume.getState() == Volume.State.Expunged) {
-                _volumeDao.remove(volumeId);
-            }
-        }
-
-        // Cleanup expired template URLs
-        List<TemplateDataStoreVO> templatesOnImageStoreList = _templateStoreDao.listTemplateDownloadUrls();
-        for (TemplateDataStoreVO templateOnImageStore : templatesOnImageStoreList) {
-
-            try {
-                long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), templateOnImageStore.getExtractUrlCreated());
-                if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) {  // URL hasnt expired yet
-                    continue;
-                }
-
-                s_logger.debug("Removing download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId());
-
-                // Remove it from image store
-                ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(templateOnImageStore.getDataStoreId(), DataStoreRole.Image);
-                secStore.deleteExtractUrl(templateOnImageStore.getInstallPath(), templateOnImageStore.getExtractUrl(), Upload.Type.TEMPLATE);
-
-                // Now remove download details from DB.
-                templateOnImageStore.setExtractUrl(null);
-                templateOnImageStore.setExtractUrlCreated(null);
-                _templateStoreDao.update(templateOnImageStore.getId(), templateOnImageStore);
-            } catch (Throwable th) {
-                s_logger.warn("caught exception while deleting download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId(), th);
-            }
-        }
-    }
-
-    // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate
-    @Override
-    public Long getDiskBytesReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
-        if ((offering != null) && (offering.getBytesReadRate() != null) && (offering.getBytesReadRate() > 0)) {
-            return offering.getBytesReadRate();
-        } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) {
-            return diskOffering.getBytesReadRate();
-        } else {
-            Long bytesReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesReadRate.key()));
-            if ((bytesReadRate > 0) && ((offering == null) || (!offering.getSystemUse()))) {
-                return bytesReadRate;
-            }
-        }
-        return 0L;
-    }
-
-    // get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate
-    @Override
-    public Long getDiskBytesWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
-        if ((offering != null) && (offering.getBytesWriteRate() != null) && (offering.getBytesWriteRate() > 0)) {
-            return offering.getBytesWriteRate();
-        } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) {
-            return diskOffering.getBytesWriteRate();
-        } else {
-            Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key()));
-            if ((bytesWriteRate > 0) && ((offering == null) || (!offering.getSystemUse()))) {
-                return bytesWriteRate;
-            }
-        }
-        return 0L;
-    }
-
-    // get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate
-    @Override
-    public Long getDiskIopsReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
-        if ((offering != null) && (offering.getIopsReadRate() != null) && (offering.getIopsReadRate() > 0)) {
-            return offering.getIopsReadRate();
-        } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) {
-            return diskOffering.getIopsReadRate();
-        } else {
-            Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key()));
-            if ((iopsReadRate > 0) && ((offering == null) || (!offering.getSystemUse()))) {
-                return iopsReadRate;
-            }
-        }
-        return 0L;
-    }
-
-    // get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate
-    @Override
-    public Long getDiskIopsWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
-        if ((offering != null) && (offering.getIopsWriteRate() != null) && (offering.getIopsWriteRate() > 0)) {
-            return offering.getIopsWriteRate();
-        } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) {
-            return diskOffering.getIopsWriteRate();
-        } else {
-            Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key()));
-            if ((iopsWriteRate > 0) && ((offering == null) || (!offering.getSystemUse()))) {
-                return iopsWriteRate;
-            }
-        }
-        return 0L;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return StorageManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled, TemplateCleanupEnabled};
-    }
-
-    @Override
-    public void setDiskProfileThrottling(DiskProfile dskCh, final ServiceOffering offering, final DiskOffering diskOffering) {
-        dskCh.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
-        dskCh.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
-        dskCh.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
-        dskCh.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
-    }
-
-    @Override
-    public DiskTO getDiskWithThrottling(final DataTO volTO, final Volume.Type volumeType, final long deviceId, final String path, final long offeringId, final long diskOfferingId) {
-        DiskTO disk = null;
-        if (volTO != null && volTO instanceof VolumeObjectTO) {
-            VolumeObjectTO volumeTO = (VolumeObjectTO)volTO;
-            ServiceOffering offering = _entityMgr.findById(ServiceOffering.class, offeringId);
-            DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
-            if (volumeType == Volume.Type.ROOT) {
-                setVolumeObjectTOThrottling(volumeTO, offering, diskOffering);
-            } else {
-                setVolumeObjectTOThrottling(volumeTO, null, diskOffering);
-            }
-            disk = new DiskTO(volumeTO, deviceId, path, volumeType);
-        } else {
-            disk = new DiskTO(volTO, deviceId, path, volumeType);
-        }
-        return disk;
-    }
-
-    private void setVolumeObjectTOThrottling(VolumeObjectTO volumeTO, final ServiceOffering offering, final DiskOffering diskOffering) {
-        volumeTO.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
-        volumeTO.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
-        volumeTO.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
-        volumeTO.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
-    }
-
-}
diff --git a/server/src/com/cloud/storage/TemplateProfile.java b/server/src/com/cloud/storage/TemplateProfile.java
deleted file mode 100644
index 410b519..0000000
--- a/server/src/com/cloud/storage/TemplateProfile.java
+++ /dev/null
@@ -1,334 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-
-public class TemplateProfile {
-    Long userId;
-    String name;
-    String displayText;
-    Integer bits;
-    Boolean passwordEnabled;
-    Boolean sshKeyEnbaled;
-    Boolean requiresHvm;
-    String url;
-    Boolean isPublic;
-    Boolean featured;
-    Boolean isExtractable;
-    ImageFormat format;
-    Long guestOsId;
-    List<Long> zoneIdList;
-    HypervisorType hypervisorType;
-    String accountName;
-    Long domainId;
-    Long accountId;
-    String chksum;
-    Boolean bootable;
-    Long templateId;
-    VMTemplateVO template;
-    String templateTag;
-    Map details;
-    Boolean isDynamicallyScalable;
-    TemplateType templateType;
-    Boolean directDownload;
-    Long size;
-
-    public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url,
-                           Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, List<Long> zoneIdList, HypervisorType hypervisorType,
-                           String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, Boolean sshKeyEnabled) {
-        this.templateId = templateId;
-        this.userId = userId;
-        this.name = name;
-        this.displayText = displayText;
-        this.bits = bits;
-        this.passwordEnabled = passwordEnabled;
-        this.requiresHvm = requiresHvm;
-        this.url = url;
-        this.isPublic = isPublic;
-        this.featured = featured;
-        this.isExtractable = isExtractable;
-        this.format = format;
-        this.guestOsId = guestOsId;
-        this.zoneIdList = zoneIdList;
-        this.hypervisorType = hypervisorType;
-        this.accountName = accountName;
-        this.domainId = domainId;
-        this.accountId = accountId;
-        this.chksum = chksum;
-        this.bootable = bootable;
-        this.details = details;
-        this.sshKeyEnbaled = sshKeyEnabled;
-    }
-
-    public TemplateProfile(Long userId, VMTemplateVO template, Long zoneId) {
-        this.userId = userId;
-        this.template = template;
-        if (zoneId != null) {
-            this.zoneIdList = new ArrayList<>();
-            this.zoneIdList.add(zoneId);
-        }
-        else this.zoneIdList = null;
-    }
-
-    public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url,
-            Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, List<Long> zoneId,
-
-            HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details,
-            Boolean sshKeyEnabled, Long imageStoreId, Boolean isDynamicallyScalable, TemplateType templateType, Boolean directDownload) {
-        this(templateId,
-            userId,
-            name,
-            displayText,
-            bits,
-            passwordEnabled,
-            requiresHvm,
-            url,
-            isPublic,
-            featured,
-            isExtractable,
-            format,
-            guestOsId,
-            zoneId,
-            hypervisorType,
-            accountName,
-            domainId,
-            accountId,
-            chksum,
-            bootable,
-            details,
-            sshKeyEnabled);
-        this.templateTag = templateTag;
-        this.isDynamicallyScalable = isDynamicallyScalable;
-        this.templateType = templateType;
-        this.directDownload = directDownload;
-    }
-
-    public Long getTemplateId() {
-        return templateId;
-    }
-
-    public void setTemplateId(Long id) {
-        this.templateId = id;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getDisplayText() {
-        return displayText;
-    }
-
-    public void setDisplayText(String text) {
-        this.displayText = text;
-    }
-
-    public Integer getBits() {
-        return bits;
-    }
-
-    public void setBits(Integer bits) {
-        this.bits = bits;
-    }
-
-    public Boolean getPasswordEnabled() {
-        return passwordEnabled;
-    }
-
-    public void setPasswordEnabled(Boolean enabled) {
-        this.passwordEnabled = enabled;
-    }
-
-    public Boolean getRequiresHVM() {
-        return requiresHvm;
-    }
-
-    public void setRequiresHVM(Boolean hvm) {
-        this.requiresHvm = hvm;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    public Boolean getIsPublic() {
-        return isPublic;
-    }
-
-    public void setIsPublic(Boolean is) {
-        this.isPublic = is;
-    }
-
-    public Boolean getFeatured() {
-        return featured;
-    }
-
-    public void setFeatured(Boolean featured) {
-        this.featured = featured;
-    }
-
-    public Boolean getIsExtractable() {
-        return isExtractable;
-    }
-
-    public void setIsExtractable(Boolean is) {
-        this.isExtractable = is;
-    }
-
-    public ImageFormat getFormat() {
-        return format;
-    }
-
-    public void setFormat(ImageFormat format) {
-        this.format = format;
-    }
-
-    public Long getGuestOsId() {
-        return guestOsId;
-    }
-
-    public void setGuestOsId(Long id) {
-        this.guestOsId = id;
-    }
-
-    public List<Long> getZoneIdList() {
-        return zoneIdList;
-    }
-
-    public HypervisorType getHypervisorType() {
-        return hypervisorType;
-    }
-
-    public void setHypervisorType(HypervisorType type) {
-        this.hypervisorType = type;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public void setDomainId(Long id) {
-        this.domainId = id;
-    }
-
-    public Long getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(Long id) {
-        this.accountId = id;
-    }
-
-    public String getCheckSum() {
-        return chksum;
-    }
-
-    public void setCheckSum(String chksum) {
-        this.chksum = chksum;
-    }
-
-    public Boolean getBootable() {
-        return this.bootable;
-    }
-
-    public void setBootable(Boolean bootable) {
-        this.bootable = bootable;
-    }
-
-    public VMTemplateVO getTemplate() {
-        return template;
-    }
-
-    public void setTemplate(VMTemplateVO template) {
-        this.template = template;
-    }
-
-    public String getTemplateTag() {
-        return templateTag;
-    }
-
-    public void setTemplateTag(String templateTag) {
-        this.templateTag = templateTag;
-    }
-
-    public Map getDetails() {
-        return this.details;
-    }
-
-    public void setDetails(Map details) {
-        this.details = details;
-    }
-
-    public void setSshKeyEnabled(Boolean enabled) {
-        this.sshKeyEnbaled = enabled;
-    }
-
-    public Boolean getSshKeyEnabled() {
-        return this.sshKeyEnbaled;
-    }
-
-    public Boolean IsDynamicallyScalable() {
-        return this.isDynamicallyScalable;
-    }
-
-    public void setScalabe(Boolean isDynamicallyScalabe) {
-        this.isDynamicallyScalable = isDynamicallyScalabe;
-    }
-
-    public TemplateType getTemplateType() {
-        return templateType;
-    }
-
-    public void setTemplateType(TemplateType templateType) {
-        this.templateType = templateType;
-    }
-
-    public boolean isDirectDownload() {
-        return directDownload == null ? false : directDownload;
-    }
-
-    public Long getSize() {
-        return size;
-    }
-
-    public void setSize(Long size) {
-        this.size = size;
-    }
-}
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
deleted file mode 100644
index 085c699..0000000
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ /dev/null
@@ -1,3216 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
-import org.apache.cloudstack.api.response.GetUploadParamsResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.Outcome;
-import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
-import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
-import org.apache.cloudstack.jobs.JobInfo;
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
-import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.domain.Domain;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.gpu.GPU;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.org.Grouping;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.storage.snapshot.SnapshotApiService;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.VmDiskStatisticsVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.VmDiskStatisticsDao;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.EncryptionUtil;
-import com.cloud.utils.EnumUtils;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Predicate;
-import com.cloud.utils.ReflectionUse;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.db.UUIDManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmService;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VmDetailConstants;
-import com.cloud.vm.VmWork;
-import com.cloud.vm.VmWorkAttachVolume;
-import com.cloud.vm.VmWorkConstants;
-import com.cloud.vm.VmWorkDetachVolume;
-import com.cloud.vm.VmWorkExtractVolume;
-import com.cloud.vm.VmWorkJobHandler;
-import com.cloud.vm.VmWorkJobHandlerProxy;
-import com.cloud.vm.VmWorkMigrateVolume;
-import com.cloud.vm.VmWorkResizeVolume;
-import com.cloud.vm.VmWorkSerializer;
-import com.cloud.vm.VmWorkTakeVolumeSnapshot;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import com.google.common.base.Strings;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonParseException;
-
-public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler {
-    private final static Logger s_logger = Logger.getLogger(VolumeApiServiceImpl.class);
-    public static final String VM_WORK_JOB_HANDLER = VolumeApiServiceImpl.class.getSimpleName();
-
-    @Inject
-    private UserVmManager _userVmMgr;
-    @Inject
-    VolumeOrchestrationService _volumeMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    AgentManager _agentMgr;
-    @Inject
-    TemplateManager _tmpltMgr;
-    @Inject
-    SnapshotManager _snapshotMgr;
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    VolumeDao _volsDao;
-    @Inject
-    VolumeDetailsDao _volDetailDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    SnapshotDao _snapshotDao;
-    @Inject
-    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-    @Inject
-    StoragePoolDetailsDao storagePoolDetailsDao;
-    @Inject
-    UserVmDao _userVmDao;
-    @Inject
-    UserVmService _userVmService;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    VMInstanceDao _vmInstanceDao;
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    DiskOfferingDao _diskOfferingDao;
-    @Inject
-    AccountDao _accountDao;
-    @Inject
-    DataCenterDao _dcDao = null;
-    @Inject
-    VMTemplateDao _templateDao;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    VmDiskStatisticsDao _vmDiskStatsDao;
-    @Inject
-    VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    VolumeService volService;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    SnapshotApiService snapshotMgr;
-    @Inject
-    UUIDManager _uuidMgr;
-    @Inject
-    HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject
-    AsyncJobManager _jobMgr;
-    @Inject
-    VmWorkJobDao _workJobDao;
-    @Inject
-    ClusterDetailsDao _clusterDetailsDao;
-    @Inject
-    StorageManager storageMgr;
-
-    protected Gson _gson;
-
-    private List<StoragePoolAllocator> _storagePoolAllocators;
-
-    VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
-
-    static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.job.check.interval", "3000", "Interval in milliseconds to check if the job is complete", false);
-
-    static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
-            "Check the url for a volume before downloading it from the management server. Set to false when you managment has no internet access.", true);
-
-    private long _maxVolumeSizeInGb;
-    private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
-
-    protected VolumeApiServiceImpl() {
-        _volStateMachine = Volume.State.getStateMachine();
-        _gson = GsonHelper.getGsonLogger();
-    }
-
-    /*
-     * Upload the volume to secondary storage.
-     */
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true)
-    public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-        long ownerId = cmd.getEntityOwnerId();
-        Account owner = _entityMgr.findById(Account.class, ownerId);
-        Long zoneId = cmd.getZoneId();
-        String volumeName = cmd.getVolumeName();
-        String url = cmd.getUrl();
-        String format = cmd.getFormat();
-        Long diskOfferingId = cmd.getDiskOfferingId();
-        String imageStoreUuid = cmd.getImageStoreUuid();
-        DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
-
-        validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId);
-
-        VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat(), diskOfferingId, Volume.State.Allocated);
-
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-
-        RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(), cmd.getFormat());
-        vol.addPayload(payload);
-
-        volService.registerVolume(vol, store);
-        return volume;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true)
-    public GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException {
-        Account caller = CallContext.current().getCallingAccount();
-        long ownerId = cmd.getEntityOwnerId();
-        final Account owner = _entityMgr.findById(Account.class, ownerId);
-        final Long zoneId = cmd.getZoneId();
-        final String volumeName = cmd.getName();
-        String format = cmd.getFormat();
-        final Long diskOfferingId = cmd.getDiskOfferingId();
-        String imageStoreUuid = cmd.getImageStoreUuid();
-        final DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
-
-        validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId);
-
-        return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
-            @Override
-            public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws MalformedURLException {
-
-                VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, cmd.getFormat(), diskOfferingId, Volume.State.NotUploaded);
-
-                VolumeInfo vol = volFactory.getVolume(volume.getId());
-
-                RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), cmd.getFormat());
-                vol.addPayload(payload);
-
-                Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
-                EndPoint ep = pair.first();
-                DataObject dataObject = pair.second();
-
-                GetUploadParamsResponse response = new GetUploadParamsResponse();
-
-                String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
-
-                String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid());
-                response.setPostURL(new URL(url));
-
-                // set the post url, this is used in the monitoring thread to determine the SSVM
-                VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
-                assert (volumeStore != null) : "sincle volume is registered, volumestore cannot be null at this stage";
-                volumeStore.setExtractUrl(url);
-                _volumeStoreDao.persist(volumeStore);
-
-                response.setId(UUID.fromString(vol.getUuid()));
-
-                int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
-                DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
-                String expires = currentDateTime.plusMinutes(timeout).toString();
-                response.setTimeout(expires);
-
-                String key = _configDao.getValue(Config.SSVMPSK.key());
-                /*
-                 * encoded metadata using the post upload config key
-                 */
-                TemplateOrVolumePostUploadCommand command = new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(),
-                        vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString());
-                command.setLocalPath(volumeStore.getLocalDownloadPath());
-                //using the existing max upload size configuration
-                command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
-                command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
-                command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
-                command.setAccountId(vol.getAccountId());
-                Gson gson = new GsonBuilder().create();
-                String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
-                response.setMetadata(metadata);
-
-                /*
-                 * signature calculated on the url, expiry, metadata.
-                 */
-                response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
-                return response;
-            }
-        });
-    }
-
-    private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format, Long diskOfferingId) throws ResourceAllocationException {
-
-        // permission check
-        Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
-        _accountMgr.checkAccess(caller, null, true, volumeOwner);
-
-        // Check that the resource limit for volumes won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(volumeOwner, ResourceType.volume);
-
-        // Verify that zone exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        }
-
-        // Check if zone is disabled
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-        }
-
-        //validating the url only when url is not null. url can be null incase of form based post upload
-        if (url != null) {
-            if (url.toLowerCase().contains("file://")) {
-                throw new InvalidParameterValueException("File:// type urls are currently unsupported");
-            }
-            UriUtils.validateUrl(format, url);
-            if (VolumeUrlCheck.value()) { // global setting that can be set when their MS does not have internet access
-                s_logger.debug("Checking url: " + url);
-                UriUtils.checkUrlExistence(url);
-            }
-            // Check that the resource limit for secondary storage won't be exceeded
-            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
-        } else {
-            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage);
-        }
-
-        try {
-            ImageFormat.valueOf(format.toUpperCase());
-        } catch (IllegalArgumentException e) {
-            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
-            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
-        }
-
-        // Check that the the disk offering specified is valid
-        if (diskOfferingId != null) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
-                throw new InvalidParameterValueException("Please specify a valid disk offering.");
-            }
-            if (!diskOffering.isCustomized()) {
-                throw new InvalidParameterValueException("Please specify a custom sized disk offering.");
-            }
-
-            if (diskOffering.getDomainId() == null) {
-                // do nothing as offering is public
-            } else {
-                _configMgr.checkDiskOfferingAccess(volumeOwner, diskOffering);
-            }
-        }
-
-        return false;
-    }
-
-    public String getRandomVolumeName() {
-        return UUID.randomUUID().toString();
-    }
-
-    @DB
-    protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, final String format, final Long diskOfferingId, final Volume.State state) {
-        return Transaction.execute(new TransactionCallback<VolumeVO>() {
-            @Override
-            public VolumeVO doInTransaction(TransactionStatus status) {
-                VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, new Long(-1), null, null, Storage.ProvisioningType.THIN, 0, Volume.Type.DATADISK);
-                volume.setPoolId(null);
-                volume.setDataCenterId(zoneId);
-                volume.setPodId(null);
-                volume.setState(state); // initialize the state
-                // to prevent a null pointer deref I put the system account id here when no owner is given.
-                // TODO Decide if this is valid or whether  throwing a CloudRuntimeException is more appropriate
-                volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId());
-                volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
-
-                if (diskOfferingId == null) {
-                    DiskOfferingVO diskOfferingVO = _diskOfferingDao.findByUniqueName("Cloud.com-Custom");
-                    if (diskOfferingVO != null) {
-                        long defaultDiskOfferingId = diskOfferingVO.getId();
-                        volume.setDiskOfferingId(defaultDiskOfferingId);
-                    }
-                } else {
-                    volume.setDiskOfferingId(diskOfferingId);
-
-                    DiskOfferingVO diskOfferingVO = _diskOfferingDao.findById(diskOfferingId);
-
-                    Boolean isCustomizedIops = diskOfferingVO != null && diskOfferingVO.isCustomizedIops() != null ? diskOfferingVO.isCustomizedIops() : false;
-
-                    if (isCustomizedIops == null || !isCustomizedIops) {
-                        volume.setMinIops(diskOfferingVO.getMinIops());
-                        volume.setMaxIops(diskOfferingVO.getMaxIops());
-                    }
-                }
-
-                // volume.setSize(size);
-                volume.setInstanceId(null);
-                volume.setUpdated(new Date());
-                volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
-                volume.setFormat(ImageFormat.valueOf(format));
-                volume = _volsDao.persist(volume);
-                CallContext.current().setEventDetails("Volume Id: " + volume.getId());
-
-                // Increment resource count during allocation; if actual creation fails,
-                // decrement it
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume);
-                //url can be null incase of postupload
-                if (url != null) {
-                    _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
-                }
-
-                return volume;
-            }
-        });
-    }
-
-    /**
-     * Retrieves the volume name from CreateVolumeCmd object.
-     *
-     * If the retrieved volume name is null, empty or blank, then A random name
-     * will be generated using getRandomVolumeName method.
-     *
-     * @param cmd
-     * @return Either the retrieved name or a random name.
-     */
-    public String getVolumeNameFromCommand(CreateVolumeCmd cmd) {
-        String userSpecifiedName = cmd.getVolumeName();
-
-        if (org.apache.commons.lang.StringUtils.isBlank(userSpecifiedName)) {
-            userSpecifiedName = getRandomVolumeName();
-        }
-
-        return userSpecifiedName;
-    }
-
-    /*
-     * Just allocate a volume in the database, don't send the createvolume cmd
-     * to hypervisor. The volume will be finally created only when it's attached
-     * to a VM.
-     */
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
-    public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException {
-        // FIXME: some of the scheduled event stuff might be missing here...
-        Account caller = CallContext.current().getCallingAccount();
-
-        long ownerId = cmd.getEntityOwnerId();
-        Account owner = _accountMgr.getActiveAccountById(ownerId);
-        Boolean displayVolume = cmd.getDisplayVolume();
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId));
-
-        if (displayVolume == null) {
-            displayVolume = true;
-        } else {
-            if (!_accountMgr.isRootAdmin(caller.getId())) {
-                throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted ");
-            }
-        }
-
-        // Check that the resource limit for volumes won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, displayVolume);
-
-        Long zoneId = cmd.getZoneId();
-        Long diskOfferingId = null;
-        DiskOfferingVO diskOffering = null;
-        Storage.ProvisioningType provisioningType;
-        Long size = null;
-        Long minIops = null;
-        Long maxIops = null;
-        // Volume VO used for extracting the source template id
-        VolumeVO parentVolume = null;
-
-        // validate input parameters before creating the volume
-        if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) || (cmd.getSnapshotId() != null && cmd.getDiskOfferingId() != null)) {
-            throw new InvalidParameterValueException("Either disk Offering Id or snapshot Id must be passed whilst creating volume");
-        }
-
-        if (cmd.getSnapshotId() == null) {// create a new volume
-
-            diskOfferingId = cmd.getDiskOfferingId();
-            size = cmd.getSize();
-            Long sizeInGB = size;
-            if (size != null) {
-                if (size > 0) {
-                    size = size * 1024 * 1024 * 1024; // user specify size in GB
-                } else {
-                    throw new InvalidParameterValueException("Disk size must be larger than 0");
-                }
-            }
-
-            // Check that the the disk offering is specified
-            diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
-                throw new InvalidParameterValueException("Please specify a valid disk offering.");
-            }
-
-            if (diskOffering.isCustomized()) {
-                if (size == null) {
-                    throw new InvalidParameterValueException("This disk offering requires a custom size specified");
-                }
-                Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
-                Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
-
-                if ((sizeInGB < customDiskOfferingMinSize) || (sizeInGB > customDiskOfferingMaxSize)) {
-                    throw new InvalidParameterValueException("Volume size: " + sizeInGB + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize + " Min:" + customDiskOfferingMinSize);
-                }
-            }
-
-            if (!diskOffering.isCustomized() && size != null) {
-                throw new InvalidParameterValueException("This disk offering does not allow custom size");
-            }
-
-            if (diskOffering.getDomainId() == null) {
-                // do nothing as offering is public
-            } else {
-                _configMgr.checkDiskOfferingAccess(caller, diskOffering);
-            }
-
-            if (diskOffering.getDiskSize() > 0) {
-                size = diskOffering.getDiskSize();
-            }
-
-            Boolean isCustomizedIops = diskOffering.isCustomizedIops();
-
-            if (isCustomizedIops != null) {
-                if (isCustomizedIops) {
-                    minIops = cmd.getMinIops();
-                    maxIops = cmd.getMaxIops();
-
-                    if (minIops == null && maxIops == null) {
-                        minIops = 0L;
-                        maxIops = 0L;
-                    } else {
-                        if (minIops == null || minIops <= 0) {
-                            throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
-                        }
-
-                        if (maxIops == null) {
-                            maxIops = 0L;
-                        }
-
-                        if (minIops > maxIops) {
-                            throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
-                        }
-                    }
-                } else {
-                    minIops = diskOffering.getMinIops();
-                    maxIops = diskOffering.getMaxIops();
-                }
-            }
-
-            provisioningType = diskOffering.getProvisioningType();
-
-            if (!validateVolumeSizeRange(size)) {// convert size from mb to gb
-                // for validation
-                throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb);
-            }
-        } else { // create volume from snapshot
-            Long snapshotId = cmd.getSnapshotId();
-            SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
-            if (snapshotCheck == null) {
-                throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
-            }
-
-            if (snapshotCheck.getState() != Snapshot.State.BackedUp) {
-                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation");
-            }
-            parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId());
-
-            diskOfferingId = snapshotCheck.getDiskOfferingId();
-            diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            if (zoneId == null) {
-                // if zoneId is not provided, we default to create volume in the same zone as the snapshot zone.
-                zoneId = snapshotCheck.getDataCenterId();
-            }
-            size = snapshotCheck.getSize(); // ; disk offering is used for tags
-            // purposes
-
-            minIops = snapshotCheck.getMinIops();
-            maxIops = snapshotCheck.getMaxIops();
-
-            provisioningType = diskOffering.getProvisioningType();
-            // check snapshot permissions
-            _accountMgr.checkAccess(caller, null, true, snapshotCheck);
-
-            // one step operation - create volume in VM's cluster and attach it
-            // to the VM
-            Long vmId = cmd.getVirtualMachineId();
-            if (vmId != null) {
-                // Check that the virtual machine ID is valid and it's a user vm
-                UserVmVO vm = _userVmDao.findById(vmId);
-                if (vm == null || vm.getType() != VirtualMachine.Type.User) {
-                    throw new InvalidParameterValueException("Please specify a valid User VM.");
-                }
-
-                // Check that the VM is in the correct state
-                if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
-                    throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
-                }
-
-                // permission check
-                _accountMgr.checkAccess(caller, null, false, vm);
-            }
-
-        }
-
-        // Check that the resource limit for primary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, displayVolume, new Long(size));
-
-        // Verify that zone exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
-        }
-
-        // Check if zone is disabled
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-        }
-
-        // If local storage is disabled then creation of volume with local disk
-        // offering not allowed
-        if (!zone.isLocalStorageEnabled() && diskOffering.getUseLocalStorage()) {
-            throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
-        }
-
-        String userSpecifiedName = getVolumeNameFromCommand(cmd);
-
-        VolumeVO volume = commitVolume(cmd, caller, owner, displayVolume, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, userSpecifiedName,
-                _uuidMgr.generateUuid(Volume.class, cmd.getCustomId()));
-
-        return volume;
-    }
-
-    private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId,
-            final Storage.ProvisioningType provisioningType, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName, final String uuid) {
-        return Transaction.execute(new TransactionCallback<VolumeVO>() {
-            @Override
-            public VolumeVO doInTransaction(TransactionStatus status) {
-                VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, provisioningType, 0, Volume.Type.DATADISK);
-                volume.setPoolId(null);
-                volume.setUuid(uuid);
-                volume.setDataCenterId(zoneId);
-                volume.setPodId(null);
-                volume.setAccountId(owner.getId());
-                volume.setDomainId(owner.getDomainId());
-                volume.setDiskOfferingId(diskOfferingId);
-                volume.setSize(size);
-                volume.setMinIops(minIops);
-                volume.setMaxIops(maxIops);
-                volume.setInstanceId(null);
-                volume.setUpdated(new Date());
-                volume.setDisplayVolume(displayVolume);
-                if (parentVolume != null) {
-                    volume.setTemplateId(parentVolume.getTemplateId());
-                    volume.setFormat(parentVolume.getFormat());
-                } else {
-                    volume.setTemplateId(null);
-                }
-
-                volume = _volsDao.persist(volume);
-                if (cmd.getSnapshotId() == null && displayVolume) {
-                    // for volume created from snapshot, create usage event after volume creation
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size,
-                            Volume.class.getName(), volume.getUuid(), displayVolume);
-                }
-
-                CallContext.current().setEventDetails("Volume Id: " + volume.getId());
-
-                // Increment resource count during allocation; if actual creation fails,
-                // decrement it
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
-                return volume;
-            }
-        });
-    }
-
-    public boolean validateVolumeSizeRange(long size) {
-        if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
-            throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
-        } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) {
-            throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB.");
-        }
-
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true)
-    public VolumeVO createVolume(CreateVolumeCmd cmd) {
-        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
-        boolean created = true;
-
-        try {
-            if (cmd.getSnapshotId() != null) {
-                volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId(), cmd.getVirtualMachineId());
-                if (volume.getState() != Volume.State.Ready) {
-                    created = false;
-                }
-
-                // if VM Id is provided, attach the volume to the VM
-                if (cmd.getVirtualMachineId() != null) {
-                    try {
-                        attachVolumeToVM(cmd.getVirtualMachineId(), volume.getId(), volume.getDeviceId());
-                    } catch (Exception ex) {
-                        StringBuilder message = new StringBuilder("Volume: ");
-                        message.append(volume.getUuid());
-                        message.append(" created successfully, but failed to attach the newly created volume to VM: ");
-                        message.append(cmd.getVirtualMachineId());
-                        message.append(" due to error: ");
-                        message.append(ex.getMessage());
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug(message, ex);
-                        }
-                        throw new CloudRuntimeException(message.toString());
-                    }
-                }
-            }
-            return volume;
-        } catch (Exception e) {
-            created = false;
-            VolumeInfo vol = volFactory.getVolume(cmd.getEntityId());
-            vol.stateTransit(Volume.Event.DestroyRequested);
-            throw new CloudRuntimeException("Failed to create volume: " + volume.getId(), e);
-        } finally {
-            if (!created) {
-                s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume());
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize()));
-            }
-        }
-    }
-
-    protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Long vmId) throws StorageUnavailableException {
-        VolumeInfo createdVolume = null;
-        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
-        snapshot.getVolumeId();
-
-        UserVmVO vm = null;
-        if (vmId != null) {
-            vm = _userVmDao.findById(vmId);
-        }
-
-        // sync old snapshots to region store if necessary
-
-        createdVolume = _volumeMgr.createVolumeFromSnapshot(volume, snapshot, vm);
-        VolumeVO volumeVo = _volsDao.findById(createdVolume.getId());
-        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(),
-                createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid(), volumeVo.isDisplayVolume());
-
-        return volumeVo;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
-    public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException {
-        Long newSize;
-        Long newMinIops;
-        Long newMaxIops;
-        Integer newHypervisorSnapshotReserve;
-        boolean shrinkOk = cmd.getShrinkOk();
-
-        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("No such volume");
-        }
-
-        // checking if there are any ongoing snapshots on the volume which is to be resized
-        List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(cmd.getId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
-        if (ongoingSnapshots.size() > 0) {
-            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on this volume, resize volume is not permitted, please try again later.");
-        }
-
-        /* Does the caller have authority to act on this volume? */
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
-
-        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
-        DiskOfferingVO newDiskOffering = null;
-
-        if (cmd.getNewDiskOfferingId() != null && volume.getDiskOfferingId() != cmd.getNewDiskOfferingId()) {
-            newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
-        }
-
-        /* Only works for KVM/XenServer/VMware (or "Any") for now, and volumes with 'None' since they're just allocated in DB */
-
-        HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
-
-        if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any
-                && hypervisorType != HypervisorType.None) {
-            throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support  rootdisksize override");
-        }
-
-        if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) {
-            throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. Volume " + volume.getUuid() + " is in state " + volume.getState() + ".");
-        }
-
-        // if we are to use the existing disk offering
-        if (newDiskOffering == null) {
-            newSize = cmd.getSize();
-            newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
-
-            // if the caller is looking to change the size of the volume
-            if (newSize != null) {
-                if (!diskOffering.isCustomized() && !volume.getVolumeType().equals(Volume.Type.ROOT)) {
-                    throw new InvalidParameterValueException("To change a volume's size without providing a new disk offering, its current disk offering must be "
-                            + "customizable or it must be a root volume (if providing a disk offering, make sure it is different from the current disk offering).");
-                }
-
-                // convert from bytes to GiB
-                newSize = newSize << 30;
-            } else {
-                // no parameter provided; just use the original size of the volume
-                newSize = volume.getSize();
-            }
-
-            newMinIops = cmd.getMinIops();
-
-            if (newMinIops != null) {
-                if (!volume.getVolumeType().equals(Volume.Type.ROOT) && (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops())) {
-                    throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Min IOPS' parameter.");
-                }
-            } else {
-                // no parameter provided; just use the original min IOPS of the volume
-                newMinIops = volume.getMinIops();
-            }
-
-            newMaxIops = cmd.getMaxIops();
-
-            if (newMaxIops != null) {
-                if (!volume.getVolumeType().equals(Volume.Type.ROOT) && (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops())) {
-                    throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Max IOPS' parameter.");
-                }
-            } else {
-                // no parameter provided; just use the original max IOPS of the volume
-                newMaxIops = volume.getMaxIops();
-            }
-
-            validateIops(newMinIops, newMaxIops);
-        } else {
-            if (newDiskOffering.getRemoved() != null) {
-                throw new InvalidParameterValueException("Requested disk offering has been removed.");
-            }
-
-            if (!DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) {
-                throw new InvalidParameterValueException("Requested disk offering type is invalid.");
-            }
-
-            if (diskOffering.getTags() != null) {
-                if (!StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) {
-                    throw new InvalidParameterValueException("The tags on the new and old disk offerings must match.");
-                }
-            } else if (newDiskOffering.getTags() != null) {
-                throw new InvalidParameterValueException("There are no tags on the current disk offering. The new disk offering needs to have no tags, as well.");
-            }
-
-            if (newDiskOffering.getDomainId() != null) {
-                // not a public offering; check access
-                _configMgr.checkDiskOfferingAccess(CallContext.current().getCallingAccount(), newDiskOffering);
-            }
-
-            if (newDiskOffering.isCustomized()) {
-                newSize = cmd.getSize();
-
-                if (newSize == null) {
-                    throw new InvalidParameterValueException("The new disk offering requires that a size be specified.");
-                }
-
-                // convert from GiB to bytes
-                newSize = newSize << 30;
-            } else {
-                if (cmd.getSize() != null) {
-                    throw new InvalidParameterValueException("You cannnot pass in a custom disk size to a non-custom disk offering.");
-                }
-
-                newSize = newDiskOffering.getDiskSize();
-            }
-
-            if (!volume.getSize().equals(newSize) && !volume.getVolumeType().equals(Volume.Type.DATADISK)) {
-                throw new InvalidParameterValueException("Only data volumes can be resized via a new disk offering.");
-            }
-
-            if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
-                newMinIops = cmd.getMinIops() != null ? cmd.getMinIops() : volume.getMinIops();
-                newMaxIops = cmd.getMaxIops() != null ? cmd.getMaxIops() : volume.getMaxIops();
-
-                validateIops(newMinIops, newMaxIops);
-            } else {
-                newMinIops = newDiskOffering.getMinIops();
-                newMaxIops = newDiskOffering.getMaxIops();
-            }
-
-            // if the hypervisor snapshot reserve value is null, it must remain null (currently only KVM uses null and null is all KVM uses for a value here)
-            newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve() != null ? newDiskOffering.getHypervisorSnapshotReserve() : null;
-        }
-
-        long currentSize = volume.getSize();
-
-        // if the caller is looking to change the size of the volume
-        if (currentSize != newSize) {
-            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("A volume that is attached to a VM with any VM snapshots cannot be resized.");
-                }
-            }
-
-            if (!validateVolumeSizeRange(newSize)) {
-                throw new InvalidParameterValueException("Requested size out of range");
-            }
-
-            Long storagePoolId = volume.getPoolId();
-
-            if (storagePoolId != null) {
-                StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
-
-                if (storagePoolVO.isManaged()) {
-                    Long instanceId = volume.getInstanceId();
-
-                    if (instanceId != null) {
-                        VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
-
-                        if (vmInstanceVO.getHypervisorType() == HypervisorType.KVM && vmInstanceVO.getState() != State.Stopped) {
-                            throw new CloudRuntimeException("This kind of KVM disk cannot be resized while it is connected to a VM that's not in the Stopped state.");
-                        }
-                    }
-                }
-            }
-
-            /*
-             * Let's make certain they (think they) know what they're doing if they
-             * want to shrink by forcing them to provide the shrinkok parameter.
-             * This will be checked again at the hypervisor level where we can see
-             * the actual disk size.
-             */
-            if (currentSize > newSize && !shrinkOk) {
-                throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume."
-                        + "Need to sign off by supplying the shrinkok parameter with value of true.");
-            }
-
-            if (newSize > currentSize) {
-                /* Check resource limit for this account on primary storage resource */
-                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(),
-                        new Long(newSize - currentSize).longValue());
-            }
-        }
-
-        // Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
-        // the requested change
-
-        /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
-        if (volume.getState() == Volume.State.Allocated) {
-            s_logger.debug("Volume is in the allocated state, but has never been created. Simply updating database with new size and IOPS.");
-
-            volume.setSize(newSize);
-            volume.setMinIops(newMinIops);
-            volume.setMaxIops(newMaxIops);
-            volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
-
-            if (newDiskOffering != null) {
-                volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
-            }
-
-            _volsDao.update(volume.getId(), volume);
-
-            return volume;
-        }
-
-        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
-
-        if (userVm != null) {
-            if (volume.getVolumeType().equals(Volume.Type.ROOT) && userVm.getPowerState() != VirtualMachine.PowerState.PowerOff && hypervisorType == HypervisorType.VMware) {
-                s_logger.error(" For ROOT volume resize VM should be in Power Off state.");
-                throw new InvalidParameterValueException("VM current state is : " + userVm.getPowerState() + ". But VM should be in " + VirtualMachine.PowerState.PowerOff + " state.");
-            }
-            // serialize VM operation
-            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
-            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-                // avoid re-entrance
-
-                VmWorkJobVO placeHolder = null;
-
-                placeHolder = createPlaceHolderWork(userVm.getId());
-
-                try {
-                    return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
-                            newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
-                } finally {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-            } else {
-                Outcome<Volume> outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
-                        newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
-
-                try {
-                    outcome.get();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Operation was interrupted", e);
-                } catch (java.util.concurrent.ExecutionException e) {
-                    throw new RuntimeException("Execution exception", e);
-                }
-
-                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-
-                if (jobResult != null) {
-                    if (jobResult instanceof ConcurrentOperationException) {
-                        throw (ConcurrentOperationException)jobResult;
-                    } else if (jobResult instanceof ResourceAllocationException) {
-                        throw (ResourceAllocationException)jobResult;
-                    } else if (jobResult instanceof RuntimeException) {
-                        throw (RuntimeException)jobResult;
-                    } else if (jobResult instanceof Throwable) {
-                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                    } else if (jobResult instanceof Long) {
-                        return _volsDao.findById((Long)jobResult);
-                    }
-                }
-
-                return volume;
-            }
-        }
-
-        return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null,
-                shrinkOk);
-    }
-
-    private void validateIops(Long minIops, Long maxIops) {
-        if ((minIops == null && maxIops != null) || (minIops != null && maxIops == null)) {
-            throw new InvalidParameterValueException("Either 'miniops' and 'maxiops' must both be provided or neither must be provided.");
-        }
-
-        if (minIops != null && maxIops != null) {
-            if (minIops > maxIops) {
-                throw new InvalidParameterValueException("The 'miniops' parameter must be less than or equal to the 'maxiops' parameter.");
-            }
-        }
-    }
-
-    private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId,
-            boolean shrinkOk) {
-        VolumeVO volume = _volsDao.findById(volumeId);
-        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
-        StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
-        boolean isManaged = storagePool.isManaged();
-
-        if (!storageMgr.storagePoolHasEnoughSpaceForResize(storagePool, currentSize, newSize)) {
-            throw new CloudRuntimeException("Storage pool " + storagePool.getName() + " does not have enough space to resize volume " + volume.getName());
-        }
-        /*
-         * get a list of hosts to send the commands to, try the system the
-         * associated vm is running on first, then the last known place it ran.
-         * If not attached to a userVm, we pass 'none' and resizevolume.sh is ok
-         * with that since it only needs the vm name to live resize
-         */
-        long[] hosts = null;
-        String instanceName = "none";
-        if (userVm != null) {
-            instanceName = userVm.getInstanceName();
-            if (userVm.getHostId() != null) {
-                hosts = new long[] {userVm.getHostId()};
-            } else if (userVm.getLastHostId() != null) {
-                hosts = new long[] {userVm.getLastHostId()};
-            }
-
-            final String errorMsg = "The VM must be stopped or the disk detached in order to resize with the XenServer Hypervisor.";
-
-            if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
-                HostVO host = _hostDao.findById(hosts[0]);
-
-                if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
-                    throw new InvalidParameterValueException(errorMsg);
-                }
-            }
-
-            /* Xen only works offline, SR does not support VDI.resizeOnline */
-            if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
-                throw new InvalidParameterValueException(errorMsg);
-            }
-        }
-
-        ResizeVolumePayload payload = new ResizeVolumePayload(newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk, instanceName, hosts, isManaged);
-
-        try {
-            VolumeInfo vol = volFactory.getVolume(volume.getId());
-            vol.addPayload(payload);
-
-            // this call to resize has a different impact depending on whether the
-            // underlying primary storage is managed or not
-            // if managed, this is the chance for the plug-in to change the size and/or IOPS values
-            // if not managed, this is the chance for the plug-in to talk to the hypervisor layer
-            // to change the size of the disk
-            AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
-            VolumeApiResult result = future.get();
-
-            if (result.isFailed()) {
-                s_logger.warn("Failed to resize the volume " + volume);
-                String details = "";
-                if (result.getResult() != null && !result.getResult().isEmpty()) {
-                    details = result.getResult();
-                }
-                throw new CloudRuntimeException(details);
-            }
-
-            // managed storage is designed in such a way that the storage plug-in does not
-            // talk to the hypervisor layer; as such, if the storage is managed and the
-            // current and new sizes are different, then CloudStack (i.e. not a storage plug-in)
-            // needs to tell the hypervisor to resize the disk
-            if (storagePool.isManaged() && currentSize != newSize) {
-                if (hosts != null && hosts.length > 0) {
-                    HostVO hostVO = _hostDao.findById(hosts[0]);
-
-                    if (hostVO.getHypervisorType() != HypervisorType.KVM) {
-                        volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
-                    }
-                }
-
-                volume.setSize(newSize);
-
-                _volsDao.update(volume.getId(), volume);
-            }
-
-            volume = _volsDao.findById(volume.getId());
-
-            if (newDiskOfferingId != null) {
-                volume.setDiskOfferingId(newDiskOfferingId);
-            }
-
-            if (currentSize != newSize) {
-                volume.setSize(newSize);
-            }
-
-            _volsDao.update(volume.getId(), volume);
-
-            /* Update resource count for the account on primary storage resource */
-            if (!shrinkOk) {
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize));
-            } else {
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize));
-            }
-            return volume;
-        } catch (InterruptedException e) {
-            s_logger.warn("failed get resize volume result", e);
-            throw new CloudRuntimeException(e.getMessage());
-        } catch (ExecutionException e) {
-            s_logger.warn("failed get resize volume result", e);
-            throw new CloudRuntimeException(e.getMessage());
-        } catch (Exception e) {
-            s_logger.warn("failed get resize volume result", e);
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume")
-    /**
-     * Executes the removal of the volume. If the volume is only allocated we do not try to remove it from primary and secondary storage.
-     * Otherwise, after the removal in the database, we will try to remove the volume from both primary and secondary storage.
-     */
-    public boolean deleteVolume(long volumeId, Account caller) {
-        VolumeVO volume = retrieveAndValidateVolume(volumeId, caller);
-        try {
-            destroyVolumeIfPossible(volume);
-            // Mark volume as removed if volume has not been created on primary or secondary
-            if (volume.getState() == Volume.State.Allocated) {
-                _volsDao.remove(volumeId);
-                stateTransitTo(volume, Volume.Event.DestroyRequested);
-                return true;
-            }
-            expungeVolumesInPrimaryStorageIfNeeded(volume);
-            expungeVolumesInSecondaryStorageIfNeeded(volume);
-            cleanVolumesCache(volume);
-            return true;
-        } catch (InterruptedException | ExecutionException | NoTransitionException e) {
-            s_logger.warn("Failed to expunge volume: " + volume.getUuid(), e);
-            return false;
-        }
-    }
-
-    /**
-     * Clean volumes cache entries (if they exist).
-     */
-    protected void cleanVolumesCache(VolumeVO volume) {
-        List<VolumeInfo> cacheVols = volFactory.listVolumeOnCache(volume.getId());
-        if (CollectionUtils.isEmpty(cacheVols)) {
-            return;
-        }
-        for (VolumeInfo volOnCache : cacheVols) {
-            s_logger.info("Delete volume from image cache store: " + volOnCache.getDataStore().getName());
-            volOnCache.delete();
-        }
-    }
-
-    /**
-     * We will check if the given volume is in the secondary storage. If the volume is not in the primary storage, we do nothing here.
-     * If it is, we will execute an asynchronous call to delete it there. Then, we decrement the {@link ResourceType#secondary_storage} for the account that owns the volume.
-     */
-    protected void expungeVolumesInSecondaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException {
-        VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
-        if (volOnSecondary != null) {
-            s_logger.info("Expunging volume " + volume.getId() + " from secondary data store");
-            AsyncCallFuture<VolumeApiResult> future2 = volService.expungeVolumeAsync(volOnSecondary);
-            future2.get();
-
-            _resourceLimitMgr.decrementResourceCount(volOnSecondary.getAccountId(), ResourceType.secondary_storage, volOnSecondary.getSize());
-        }
-    }
-
-    /**
-     * We will check if the given volume is in the primary storage. If it is, we will execute an asynchronous call to delete it there.
-     * If the volume is not in the primary storage, we do nothing here.
-     */
-    protected void expungeVolumesInPrimaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException {
-        VolumeInfo volOnPrimary = volFactory.getVolume(volume.getId(), DataStoreRole.Primary);
-        if (volOnPrimary != null) {
-            s_logger.info("Expunging volume " + volume.getId() + " from primary data store");
-            AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnPrimary);
-            future.get();
-        }
-    }
-
-    /**
-     * Destroy the volume if possible and then decrement the following resource types.
-     * <ul>
-     *  <li> {@link ResourceType#volume};
-     *  <li> {@link ResourceType#primary_storage}
-     * </ul>
-     *
-     * A volume can be destroyed if it is not in any of the following states.
-     * <ul>
-     *  <li> {@value Volume.State#Destroy};
-     *  <li> {@value Volume.State#Expunging};
-     *  <li> {@value Volume.State#Expunged}.
-     * </ul>
-     *
-     * The volume is destroyed via {@link VolumeService#destroyVolume(long)} method.
-     */
-    protected void destroyVolumeIfPossible(VolumeVO volume) {
-        if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunged) {
-            volService.destroyVolume(volume.getId());
-
-            // Decrement the resource count for volumes and primary storage belonging user VM's only
-            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
-            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), volume.getSize());
-        }
-    }
-
-    /**
-     *  Retrieves and validates the volume for the {@link #deleteVolume(long, Account)} method. The following validation are executed.
-     *  <ul>
-     *      <li> if no volume is found in the database, we throw an {@link InvalidParameterValueException};
-     *      <li> if there are snapshots operation on the volume we cannot delete it. Therefore, an {@link InvalidParameterValueException} is thrown;
-     *      <li> if the volume is still attached to a VM we throw an {@link InvalidParameterValueException};
-     *      <li> if volume state is in {@link Volume.State#UploadOp}, we check the {@link VolumeDataStoreVO}. Then, if the {@link VolumeDataStoreVO} for the given volume has download status of {@link VMTemplateStorageResourceAssoc.Status#DOWNLOAD_IN_PROGRESS}, an exception is throw;
-     *      <li> if the volume state is in {@link Volume.State#NotUploaded} or if the state is {@link Volume.State#UploadInProgress}, an {@link InvalidParameterValueException} is thrown;
-     *      <li> we also check if the user has access to the given volume using {@link AccountManager#checkAccess(Account, org.apache.cloudstack.acl.SecurityChecker.AccessType, boolean, String)}.
-     *  </ul>
-     *
-     *  After all validations we return the volume object.
-     */
-    protected VolumeVO retrieveAndValidateVolume(long volumeId, Account caller) {
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
-        }
-        if (!_snapshotMgr.canOperateOnVolume(volume)) {
-            throw new InvalidParameterValueException("There are snapshot operations in progress on the volume, unable to delete it");
-        }
-        if (volume.getInstanceId() != null) {
-            throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
-        }
-        if (volume.getState() == Volume.State.UploadOp) {
-            VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                throw new InvalidParameterValueException("Please specify a volume that is not uploading");
-            }
-        }
-        if (volume.getState() == Volume.State.NotUploaded || volume.getState() == Volume.State.UploadInProgress) {
-            throw new InvalidParameterValueException("The volume is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
-        }
-        _accountMgr.checkAccess(caller, null, true, volume);
-        return volume;
-    }
-
-    protected boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException {
-        return _volStateMachine.transitTo(vol, event, null, _volsDao);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
-    public Volume attachVolumeToVM(AttachVolumeCmd command) {
-        return attachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId());
-    }
-
-    private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
-        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
-
-        if (volumeToAttach.isAttachedVM()) {
-            throw new CloudRuntimeException("This volume is already attached to a VM.");
-        }
-
-        UserVmVO vm = _userVmDao.findById(vmId);
-        VolumeVO exstingVolumeOfVm = null;
-        List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
-        if (rootVolumesOfVm.size() > 1) {
-            throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
-        } else {
-            if (!rootVolumesOfVm.isEmpty()) {
-                exstingVolumeOfVm = rootVolumesOfVm.get(0);
-            } else {
-                // locate data volume of the vm
-                List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
-                for (VolumeVO diskVolume : diskVolumesOfVm) {
-                    if (diskVolume.getState() != Volume.State.Allocated) {
-                        exstingVolumeOfVm = diskVolume;
-                        break;
-                    }
-                }
-            }
-        }
-
-        HypervisorType rootDiskHyperType = vm.getHypervisorType();
-        HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
-
-        VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
-
-        //don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
-        StoragePoolVO destPrimaryStorage = null;
-        if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
-            destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
-        }
-
-        boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;
-
-        if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) {
-            try {
-                newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage);
-            } catch (NoTransitionException e) {
-                s_logger.debug("Failed to create volume on primary storage", e);
-                throw new CloudRuntimeException("Failed to create volume on primary storage", e);
-            }
-        }
-
-        // reload the volume from db
-        newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
-        boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage);
-
-        if (moveVolumeNeeded) {
-            PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)newVolumeOnPrimaryStorage.getDataStore();
-            if (primaryStore.isLocal()) {
-                throw new CloudRuntimeException(
-                        "Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() + " as migration of local data volume is not allowed");
-            }
-            StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
-
-            try {
-                newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(),
-                        volumeToAttachHyperType);
-            } catch (ConcurrentOperationException e) {
-                s_logger.debug("move volume failed", e);
-                throw new CloudRuntimeException("move volume failed", e);
-            } catch (StorageUnavailableException e) {
-                s_logger.debug("move volume failed", e);
-                throw new CloudRuntimeException("move volume failed", e);
-            }
-        }
-        VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
-        // Getting the fresh vm object in case of volume migration to check the current state of VM
-        if (moveVolumeNeeded || volumeOnSecondary) {
-            vm = _userVmDao.findById(vmId);
-            if (vm == null) {
-                throw new InvalidParameterValueException("VM not found.");
-            }
-        }
-        newVol = sendAttachVolumeCommand(vm, newVol, deviceId);
-        return newVol;
-    }
-
-    public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Check that the volume ID is valid
-        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
-        // Check that the volume is a data volume
-        if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
-            throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
-        }
-
-        // Check that the volume is not currently attached to any VM
-        if (volumeToAttach.getInstanceId() != null) {
-            throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
-        }
-
-        // Check that the volume is not destroyed
-        if (volumeToAttach.getState() == Volume.State.Destroy) {
-            throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
-        }
-
-        // Check that the virtual machine ID is valid and it's a user vm
-        UserVmVO vm = _userVmDao.findById(vmId);
-        if (vm == null || vm.getType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("Please specify a valid User VM.");
-        }
-
-        // Check that the VM is in the correct state
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
-            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
-        }
-
-        // Check that the VM and the volume are in the same zone
-        if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
-            throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
-        }
-
-        // Check that the device ID is valid
-        if (deviceId != null) {
-            // validate ROOT volume type
-            if (deviceId.longValue() == 0) {
-                validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
-                // vm shouldn't have any volume with deviceId 0
-                if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
-                    throw new InvalidParameterValueException("Vm already has root volume attached to it");
-                }
-                // volume can't be in Uploaded state
-                if (volumeToAttach.getState() == Volume.State.Uploaded) {
-                    throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
-                }
-            }
-        }
-
-        // Check that the number of data volumes attached to VM is less than
-        // that supported by hypervisor
-        if (deviceId == null || deviceId.longValue() != 0) {
-            List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
-            int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
-            if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
-                throw new InvalidParameterValueException(
-                        "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
-            }
-        }
-
-        // If local storage is disabled then attaching a volume with local disk
-        // offering not allowed
-        DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
-        if (!dataCenter.isLocalStorageEnabled()) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
-            if (diskOffering.getUseLocalStorage()) {
-                throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
-            }
-        }
-
-        // if target VM has associated VM snapshots
-        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
-        if (vmSnapshots.size() > 0) {
-            throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
-        }
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
-
-        if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
-            throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
-        }
-
-        Account owner = _accountDao.findById(volumeToAttach.getAccountId());
-
-        if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
-            try {
-                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
-            } catch (ResourceAllocationException e) {
-                s_logger.error("primary storage resource limit check failed", e);
-                throw new InvalidParameterValueException(e.getMessage());
-            }
-        }
-
-        HypervisorType rootDiskHyperType = vm.getHypervisorType();
-        HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
-
-        StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
-
-        // managed storage can be used for different types of hypervisors
-        // only perform this check if the volume's storage pool is not null and not managed
-        if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
-            if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
-                throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
-            }
-        }
-
-        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-
-        if (asyncExecutionContext != null) {
-            AsyncJob job = asyncExecutionContext.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
-            }
-
-            _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
-        }
-
-        AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-
-            VmWorkJobVO placeHolder = null;
-            placeHolder = createPlaceHolderWork(vmId);
-            try {
-                return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
-            } finally {
-                _workJobDao.expunge(placeHolder.getId());
-            }
-
-        } else {
-            Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
-
-            Volume vol = null;
-            try {
-                outcome.get();
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof InvalidParameterValueException) {
-                    throw (InvalidParameterValueException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                } else if (jobResult instanceof Long) {
-                    vol = _volsDao.findById((Long)jobResult);
-                }
-            }
-            return vol;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
-    public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId, String chainInfo) {
-
-        VolumeVO volume = _volsDao.findById(volumeId);
-
-        if (volume == null) {
-            throw new InvalidParameterValueException("The volume id doesn't exist");
-        }
-
-        if (path != null) {
-            volume.setPath(path);
-        }
-
-        if (chainInfo != null) {
-            volume.setChainInfo(chainInfo);
-        }
-
-        if (state != null) {
-            try {
-                Volume.State volumeState = Volume.State.valueOf(state);
-                volume.setState(volumeState);
-            } catch (IllegalArgumentException ex) {
-                throw new InvalidParameterValueException("Invalid volume state specified");
-            }
-        }
-
-        if (storageId != null) {
-            StoragePool pool = _storagePoolDao.findById(storageId);
-            if (pool.getDataCenterId() != volume.getDataCenterId()) {
-                throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
-            }
-            volume.setPoolId(pool.getId());
-        }
-
-        if (customId != null) {
-            volume.setUuid(customId);
-        }
-
-        updateDisplay(volume, displayVolume);
-
-        _volsDao.update(volumeId, volume);
-
-        return volume;
-    }
-
-    @Override
-    public void updateDisplay(Volume volume, Boolean displayVolume) {
-        // 1. Resource limit changes
-        updateResourceCount(volume, displayVolume);
-
-        // 2. generate usage event if not in destroyed state
-        saveUsageEvent(volume, displayVolume);
-
-        // 3. Set the flag
-        if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
-            // FIXME - Confused - typecast for now.
-            ((VolumeVO)volume).setDisplayVolume(displayVolume);
-            _volsDao.update(volume.getId(), (VolumeVO)volume);
-        }
-
-    }
-
-    private void updateResourceCount(Volume volume, Boolean displayVolume) {
-        // Update only when the flag has changed.
-        if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
-            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
-            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
-        }
-    }
-
-    private void saveUsageEvent(Volume volume, Boolean displayVolume) {
-
-        // Update only when the flag has changed  &&  only when volume in a non-destroyed state.
-        if ((displayVolume != null && displayVolume != volume.isDisplayVolume()) && !isVolumeDestroyed(volume)) {
-            if (displayVolume) {
-                // flag turned 1 equivalent to freshly created volume
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(),
-                        volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
-            } else {
-                // flag turned 0 equivalent to deleting a volume
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
-                        volume.getUuid());
-            }
-        }
-    }
-
-    private boolean isVolumeDestroyed(Volume volume) {
-        if (volume.getState() == Volume.State.Destroy || volume.getState() == Volume.State.Expunging && volume.getState() == Volume.State.Expunged) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
-    public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null) || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null))
-                || (cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null))) {
-            throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)");
-        }
-
-        Long volumeId = cmmd.getId();
-        VolumeVO volume = null;
-
-        if (volumeId != null) {
-            volume = _volsDao.findById(volumeId);
-        } else {
-            volume = _volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0);
-        }
-
-        // Check that the volume ID is valid
-        if (volume == null) {
-            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
-        }
-
-        Long vmId = null;
-
-        if (cmmd.getVirtualMachineId() == null) {
-            vmId = volume.getInstanceId();
-        } else {
-            vmId = cmmd.getVirtualMachineId();
-        }
-
-        // Permissions check
-        _accountMgr.checkAccess(caller, null, true, volume);
-
-        // Check that the volume is currently attached to a VM
-        if (vmId == null) {
-            throw new InvalidParameterValueException("The specified volume is not attached to a VM.");
-        }
-
-        // Check that the VM is in the correct state
-        UserVmVO vm = _userVmDao.findById(vmId);
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) {
-            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
-        }
-
-        // Check that the volume is a data/root volume
-        if (!(volume.getVolumeType() == Volume.Type.ROOT || volume.getVolumeType() == Volume.Type.DATADISK)) {
-            throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK.toString() + " or " + Volume.Type.ROOT.toString());
-        }
-
-        // Root volume detach is allowed for following hypervisors: Xen/KVM/VmWare
-        if (volume.getVolumeType() == Volume.Type.ROOT) {
-            validateRootVolumeDetachAttach(volume, vm);
-        }
-
-        // Don't allow detach if target VM has associated VM snapshots
-        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
-        if (vmSnapshots.size() > 0) {
-            throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
-        }
-
-        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (asyncExecutionContext != null) {
-            AsyncJob job = asyncExecutionContext.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
-            }
-
-            _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
-        }
-
-        AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-            // avoid re-entrance
-            VmWorkJobVO placeHolder = null;
-            placeHolder = createPlaceHolderWork(vmId);
-            try {
-                return orchestrateDetachVolumeFromVM(vmId, volumeId);
-            } finally {
-                _workJobDao.expunge(placeHolder.getId());
-            }
-        } else {
-            Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId);
-
-            Volume vol = null;
-            try {
-                outcome.get();
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Operation is interrupted", e);
-            } catch (java.util.concurrent.ExecutionException e) {
-                throw new RuntimeException("Execution excetion", e);
-            }
-
-            Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-            if (jobResult != null) {
-                if (jobResult instanceof ConcurrentOperationException) {
-                    throw (ConcurrentOperationException)jobResult;
-                } else if (jobResult instanceof RuntimeException) {
-                    throw (RuntimeException)jobResult;
-                } else if (jobResult instanceof Throwable) {
-                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                } else if (jobResult instanceof Long) {
-                    vol = _volsDao.findById((Long)jobResult);
-                }
-            }
-            return vol;
-        }
-    }
-
-    private void validateRootVolumeDetachAttach(VolumeVO volume, UserVmVO vm) {
-        if (!(vm.getHypervisorType() == HypervisorType.XenServer || vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.KVM
-                || vm.getHypervisorType() == HypervisorType.Simulator)) {
-            throw new InvalidParameterValueException("Root volume detach is not supported for hypervisor type " + vm.getHypervisorType());
-        }
-        if (!(vm.getState() == State.Stopped) || (vm.getState() == State.Destroyed)) {
-            throw new InvalidParameterValueException("Root volume detach can happen only when vm is in states: " + State.Stopped.toString() + " or " + State.Destroyed.toString());
-        }
-
-        if (volume.getPoolId() != null) {
-            StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId());
-            if (pool.isManaged()) {
-                throw new InvalidParameterValueException("Root volume detach is not supported for Managed DataStores");
-            }
-        }
-    }
-
-    private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) {
-
-        Volume volume = _volsDao.findById(volumeId);
-        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        String errorMsg = "Failed to detach volume " + volume.getName() + " from VM " + vm.getHostName();
-        boolean sendCommand = vm.getState() == State.Running;
-
-        Long hostId = vm.getHostId();
-
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-
-            HostVO host = _hostDao.findById(hostId);
-
-            if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
-                sendCommand = true;
-            }
-        }
-
-        HostVO host = null;
-        StoragePoolVO volumePool = _storagePoolDao.findByIdIncludingRemoved(volume.getPoolId());
-
-        if (hostId != null) {
-            host = _hostDao.findById(hostId);
-
-            if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumePool != null && volumePool.isManaged()) {
-                sendCommand = true;
-            }
-        }
-
-        if (volumePool == null) {
-            sendCommand = false;
-        }
-
-        Answer answer = null;
-
-        if (sendCommand) {
-            // collect vm disk statistics before detach a volume
-            UserVmVO userVm = _userVmDao.findById(vmId);
-            if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
-                _userVmService.collectVmDiskStatistics(userVm);
-            }
-
-            DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
-            DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
-
-            DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
-
-            cmd.setManaged(volumePool.isManaged());
-
-            cmd.setStorageHost(volumePool.getHostAddress());
-            cmd.setStoragePort(volumePool.getPort());
-
-            cmd.set_iScsiName(volume.get_iScsiName());
-
-            try {
-                answer = _agentMgr.send(hostId, cmd);
-            } catch (Exception e) {
-                throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
-            }
-        }
-
-        if (!sendCommand || (answer != null && answer.getResult())) {
-            // Mark the volume as detached
-            _volsDao.detachVolume(volume.getId());
-
-            // volume.getPoolId() should be null if the VM we are detaching the disk from has never been started before
-            if (volume.getPoolId() != null) {
-                DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary);
-                volService.revokeAccess(volFactory.getVolume(volume.getId()), host, dataStore);
-            }
-            if (volumePool != null && hostId != null) {
-                handleTargetsForVMware(hostId, volumePool.getHostAddress(), volumePool.getPort(), volume.get_iScsiName());
-            }
-            return _volsDao.findById(volumeId);
-        } else {
-
-            if (answer != null) {
-                String details = answer.getDetails();
-                if (details != null && !details.isEmpty()) {
-                    errorMsg += "; " + details;
-                }
-            }
-
-            throw new CloudRuntimeException(errorMsg);
-        }
-    }
-
-    public void updateMissingRootDiskController(final VMInstanceVO vm, final String rootVolChainInfo) {
-        if (vm == null || !VirtualMachine.Type.User.equals(vm.getType()) || Strings.isNullOrEmpty(rootVolChainInfo)) {
-            return;
-        }
-        String rootDiskController = null;
-        try {
-            final VirtualMachineDiskInfo infoInChain = _gson.fromJson(rootVolChainInfo, VirtualMachineDiskInfo.class);
-            if (infoInChain != null) {
-                rootDiskController = infoInChain.getControllerFromDeviceBusName();
-            }
-            final UserVmVO userVmVo = _userVmDao.findById(vm.getId());
-            if ((rootDiskController != null) && (!rootDiskController.isEmpty())) {
-                _userVmDao.loadDetails(userVmVo);
-                _userVmMgr.persistDeviceBusInfo(userVmVo, rootDiskController);
-            }
-        } catch (JsonParseException e) {
-            s_logger.debug("Error parsing chain info json: " + e.getMessage());
-        }
-    }
-
-    private void handleTargetsForVMware(long hostId, String storageAddress, int storagePort, String iScsiName) {
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host.getHypervisorType() == HypervisorType.VMware) {
-            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-            List<Map<String, String>> targets = new ArrayList<>();
-
-            Map<String, String> target = new HashMap<>();
-
-            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
-            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
-            target.put(ModifyTargetsCommand.IQN, iScsiName);
-
-            targets.add(target);
-
-            cmd.setTargets(targets);
-            cmd.setApplyToAllHostsInCluster(true);
-            cmd.setAdd(false);
-            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-
-            sendModifyTargetsCommand(cmd, hostId);
-        }
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            String msg = "Unable to get an answer to the modify targets command";
-
-            s_logger.warn(msg);
-        } else if (!answer.getResult()) {
-            String msg = "Unable to modify target on the following host: " + hostId;
-
-            s_logger.warn(msg);
-        }
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true)
-    public Volume migrateVolume(MigrateVolumeCmd cmd) {
-        Long volumeId = cmd.getVolumeId();
-        Long storagePoolId = cmd.getStoragePoolId();
-
-        VolumeVO vol = _volsDao.findById(volumeId);
-        if (vol == null) {
-            throw new InvalidParameterValueException("Failed to find the volume id: " + volumeId);
-        }
-
-        if (vol.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("Volume must be in ready state");
-        }
-
-        boolean liveMigrateVolume = false;
-        Long instanceId = vol.getInstanceId();
-        Long srcClusterId = null;
-        VMInstanceVO vm = null;
-        if (instanceId != null) {
-            vm = _vmInstanceDao.findById(instanceId);
-        }
-
-        // Check that Vm to which this volume is attached does not have VM Snapshots
-        if (vm != null && _vmSnapshotDao.findByVm(vm.getId()).size() > 0) {
-            throw new InvalidParameterValueException("Volume cannot be migrated, please remove all VM snapshots for VM to which this volume is attached");
-        }
-
-        if (vm != null && vm.getState() == State.Running) {
-            // Check if the VM is GPU enabled.
-            if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
-                throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
-            }
-            // Check if the underlying hypervisor supports storage motion.
-            Long hostId = vm.getHostId();
-            if (hostId != null) {
-                HostVO host = _hostDao.findById(hostId);
-                HypervisorCapabilitiesVO capabilities = null;
-                if (host != null) {
-                    capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(host.getHypervisorType(), host.getHypervisorVersion());
-                    srcClusterId = host.getClusterId();
-                }
-
-                if (capabilities != null) {
-                    liveMigrateVolume = capabilities.isStorageMotionSupported();
-                }
-            }
-
-            // If vm is running, and hypervisor doesn't support live migration, then return error
-            if (!liveMigrateVolume) {
-                throw new InvalidParameterValueException("Volume needs to be detached from VM");
-            }
-        }
-
-        if (liveMigrateVolume && !cmd.isLiveMigrate()) {
-            throw new InvalidParameterValueException("The volume " + vol + "is attached to a vm and for migrating it " + "the parameter livemigrate should be specified");
-        }
-
-        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-        if (destPool == null) {
-            throw new InvalidParameterValueException("Failed to find the destination storage pool: " + storagePoolId);
-        } else if (destPool.isInMaintenance()) {
-            throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode.");
-        }
-
-        if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) {
-            throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName());
-        }
-
-        if (_volumeMgr.volumeOnSharedStoragePool(vol)) {
-            if (destPool.isLocal()) {
-                throw new InvalidParameterValueException("Migration of volume from shared to local storage pool is not supported");
-            } else {
-                // If the volume is attached to a running vm and the volume is on a shared storage pool, check
-                // to make sure that the destination storage pool is in the same cluster as the vm.
-                if (liveMigrateVolume && destPool.getClusterId() != null && srcClusterId != null) {
-                    if (!srcClusterId.equals(destPool.getClusterId())) {
-                        throw new InvalidParameterValueException("Cannot migrate a volume of a virtual machine to a storage pool in a different cluster");
-                    }
-                }
-                // In case of VMware, if ROOT volume is being cold-migrated, then ensure destination storage pool is in the same Datacenter as the VM.
-                if (vm != null && vm.getHypervisorType().equals(HypervisorType.VMware)) {
-                    if (!liveMigrateVolume && vol.volumeType.equals(Volume.Type.ROOT)) {
-                        Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
-                        HostVO host = _hostDao.findById(hostId);
-                        if (host != null) {
-                            srcClusterId = host.getClusterId();
-                        }
-                        if (srcClusterId != null && destPool.getClusterId() != null && !srcClusterId.equals(destPool.getClusterId())) {
-                            String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
-                            String destDcName = _clusterDetailsDao.getVmwareDcName(destPool.getClusterId());
-                            if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
-                                throw new InvalidParameterValueException("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter");
-                            }
-                        }
-                        updateMissingRootDiskController(vm, vol.getChainInfo());
-                    }
-                }
-            }
-        } else {
-            throw new InvalidParameterValueException("Migration of volume from local storage pool is not supported");
-        }
-
-        if (vm != null) {
-            // serialize VM operation
-            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-                // avoid re-entrance
-
-                VmWorkJobVO placeHolder = null;
-                placeHolder = createPlaceHolderWork(vm.getId());
-                try {
-                    return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume);
-                } finally {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-
-            } else {
-                Outcome<Volume> outcome = migrateVolumeThroughJobQueue(vm.getId(), vol.getId(), destPool.getId(), liveMigrateVolume);
-
-                try {
-                    outcome.get();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Operation is interrupted", e);
-                } catch (java.util.concurrent.ExecutionException e) {
-                    throw new RuntimeException("Execution excetion", e);
-                }
-
-                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-                if (jobResult != null) {
-                    if (jobResult instanceof ConcurrentOperationException) {
-                        throw (ConcurrentOperationException)jobResult;
-                    } else if (jobResult instanceof RuntimeException) {
-                        throw (RuntimeException)jobResult;
-                    } else if (jobResult instanceof Throwable) {
-                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                    }
-                }
-
-                // retrieve the migrated new volume from job result
-                if (jobResult != null && jobResult instanceof Long) {
-                    return _entityMgr.findById(VolumeVO.class, ((Long)jobResult));
-                }
-                return null;
-            }
-        }
-
-        return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume);
-    }
-
-    private Volume orchestrateMigrateVolume(long volumeId, long destPoolId, boolean liveMigrateVolume) {
-        VolumeVO vol = _volsDao.findById(volumeId);
-        assert (vol != null);
-        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destPoolId, DataStoreRole.Primary);
-        assert (destPool != null);
-
-        Volume newVol = null;
-        try {
-            if (liveMigrateVolume) {
-                newVol = liveMigrateVolume(vol, destPool);
-            } else {
-                newVol = _volumeMgr.migrateVolume(vol, destPool);
-            }
-        } catch (StorageUnavailableException e) {
-            s_logger.debug("Failed to migrate volume", e);
-            throw new CloudRuntimeException(e.getMessage());
-        } catch (Exception e) {
-            s_logger.debug("Failed to migrate volume", e);
-            throw new CloudRuntimeException(e.getMessage());
-        }
-        return newVol;
-    }
-
-    @DB
-    protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-        AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore)destPool);
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("migrate volume failed:" + result.getResult());
-                throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("migrate volume failed", e);
-            throw new CloudRuntimeException(e.getMessage());
-        } catch (ExecutionException e) {
-            s_logger.debug("migrate volume failed", e);
-            throw new CloudRuntimeException(e.getMessage());
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true)
-    public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
-            throws ResourceAllocationException {
-        VolumeInfo volume = volFactory.getVolume(volumeId);
-        if (volume == null) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
-        }
-
-        if (volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
-        }
-
-        StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
-
-        if (storagePoolVO.isManaged() && locationType == null) {
-            locationType = Snapshot.LocationType.PRIMARY;
-        }
-
-        VMInstanceVO vm = null;
-        if (volume.getInstanceId() != null) {
-            vm = _vmInstanceDao.findById(volume.getInstanceId());
-        }
-
-        if (vm != null) {
-            // serialize VM operation
-            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-                // avoid re-entrance
-
-                VmWorkJobVO placeHolder = null;
-                placeHolder = createPlaceHolderWork(vm.getId());
-                try {
-                    return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm, locationType, asyncBackup);
-                } finally {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-
-            } else {
-                Outcome<Snapshot> outcome = takeVolumeSnapshotThroughJobQueue(vm.getId(), volumeId, policyId, snapshotId, account.getId(), quiescevm, locationType, asyncBackup);
-
-                try {
-                    outcome.get();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Operation is interrupted", e);
-                } catch (java.util.concurrent.ExecutionException e) {
-                    throw new RuntimeException("Execution excetion", e);
-                }
-
-                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-                if (jobResult != null) {
-                    if (jobResult instanceof ConcurrentOperationException) {
-                        throw (ConcurrentOperationException)jobResult;
-                    } else if (jobResult instanceof ResourceAllocationException) {
-                        throw (ResourceAllocationException)jobResult;
-                    } else if (jobResult instanceof Throwable) {
-                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                    }
-                }
-
-                return _snapshotDao.findById(snapshotId);
-            }
-        } else {
-            CreateSnapshotPayload payload = new CreateSnapshotPayload();
-            payload.setSnapshotId(snapshotId);
-            payload.setSnapshotPolicyId(policyId);
-            payload.setAccount(account);
-            payload.setQuiescevm(quiescevm);
-            payload.setAsyncBackup(asyncBackup);
-            volume.addPayload(payload);
-            return volService.takeSnapshot(volume);
-        }
-    }
-
-    private Snapshot orchestrateTakeVolumeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
-            throws ResourceAllocationException {
-
-        VolumeInfo volume = volFactory.getVolume(volumeId);
-
-        if (volume == null) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
-        }
-
-        if (volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
-        }
-
-        CreateSnapshotPayload payload = new CreateSnapshotPayload();
-
-        payload.setSnapshotId(snapshotId);
-        payload.setSnapshotPolicyId(policyId);
-        payload.setAccount(account);
-        payload.setQuiescevm(quiescevm);
-        payload.setLocationType(locationType);
-        payload.setAsyncBackup(asyncBackup);
-        volume.addPayload(payload);
-
-        return volService.takeSnapshot(volume);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true)
-    public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        VolumeInfo volume = volFactory.getVolume(volumeId);
-        if (volume == null) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
-        }
-        DataCenter zone = _dcDao.findById(volume.getDataCenterId());
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
-        }
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
-        }
-
-        if (volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
-        }
-
-        if (ImageFormat.DIR.equals(volume.getFormat())) {
-            throw new InvalidParameterValueException("Snapshot not supported for volume:" + volumeId);
-        }
-
-        if (volume.getTemplateId() != null) {
-            VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
-            if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
-                throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
-            }
-        }
-
-        StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
-
-        if (!storagePoolVO.isManaged() && locationType != null) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " LocationType is supported only for managed storage");
-        }
-
-        if (storagePoolVO.isManaged() && locationType == null) {
-            locationType = Snapshot.LocationType.PRIMARY;
-        }
-
-        StoragePool storagePool = (StoragePool)volume.getDataStore();
-        if (storagePool == null) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
-        }
-
-        return snapshotMgr.allocSnapshot(volumeId, policyId, snapshotName, locationType);
-    }
-
-    @Override
-    public Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
-        }
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        VolumeInfo volume = volFactory.getVolume(volumeId);
-        if (volume == null) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
-        }
-        _accountMgr.checkAccess(caller, null, true, volume);
-        VirtualMachine attachVM = volume.getAttachedVM();
-        if (attachVM == null || attachVM.getId() != vm.getId()) {
-            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't attach to vm :" + vm);
-        }
-
-        DataCenter zone = _dcDao.findById(volume.getDataCenterId());
-        if (zone == null) {
-            throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
-        }
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
-        }
-
-        if (volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
-        }
-
-        if (volume.getTemplateId() != null) {
-            VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
-            if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
-                throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
-            }
-        }
-
-        StoragePool storagePool = (StoragePool)volume.getDataStore();
-        if (storagePool == null) {
-            throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
-        }
-
-        return snapshotMgr.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshotName, null);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true)
-    public String extractVolume(ExtractVolumeCmd cmd) {
-        Long volumeId = cmd.getId();
-        Long zoneId = cmd.getZoneId();
-        String mode = cmd.getMode();
-        Account account = CallContext.current().getCallingAccount();
-
-        if (!_accountMgr.isRootAdmin(account.getId()) && ApiDBUtils.isExtractionDisabled()) {
-            throw new PermissionDeniedException("Extraction has been disabled by admin");
-        }
-
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId");
-            ex.addProxyObject(volumeId.toString(), "volumeId");
-            throw ex;
-        }
-
-        // perform permission check
-        _accountMgr.checkAccess(account, null, true, volume);
-
-        if (_dcDao.findById(zoneId) == null) {
-            throw new InvalidParameterValueException("Please specify a valid zone.");
-        }
-        if (volume.getPoolId() == null) {
-            throw new InvalidParameterValueException("The volume doesn't belong to a storage pool so can't extract it");
-        }
-        // Extract activity only for detached volumes or for volumes whose
-        // instance is stopped
-        if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) {
-            s_logger.debug("Invalid state of the volume with ID: " + volumeId + ". It should be either detached or the VM should be in stopped state.");
-            PermissionDeniedException ex = new PermissionDeniedException("Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state.");
-            ex.addProxyObject(volume.getUuid(), "volumeId");
-            throw ex;
-        }
-
-        if (volume.getVolumeType() != Volume.Type.DATADISK) {
-            // Datadisk dont have any template dependence.
-
-            VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
-            if (template != null) { // For ISO based volumes template = null and
-                // we allow extraction of all ISO based
-                // volumes
-                boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
-                if (!isExtractable && account != null && !_accountMgr.isRootAdmin(account.getId())) {
-                    // Global admins are always allowed to extract
-                    PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted");
-                    ex.addProxyObject(volume.getUuid(), "volumeId");
-                    throw ex;
-                }
-            }
-        }
-
-        if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) {
-            throw new InvalidParameterValueException("Please specify a valid extract Mode ");
-        }
-
-        // Check if the url already exists
-        VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
-        if (volumeStoreRef != null && volumeStoreRef.getExtractUrl() != null) {
-            return volumeStoreRef.getExtractUrl();
-        }
-
-        VMInstanceVO vm = null;
-        if (volume.getInstanceId() != null) {
-            vm = _vmInstanceDao.findById(volume.getInstanceId());
-        }
-
-        if (vm != null) {
-            // serialize VM operation
-            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
-                // avoid re-entrance
-
-                VmWorkJobVO placeHolder = null;
-                placeHolder = createPlaceHolderWork(vm.getId());
-                try {
-                    return orchestrateExtractVolume(volume.getId(), zoneId);
-                } finally {
-                    _workJobDao.expunge(placeHolder.getId());
-                }
-
-            } else {
-                Outcome<String> outcome = extractVolumeThroughJobQueue(vm.getId(), volume.getId(), zoneId);
-
-                try {
-                    outcome.get();
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Operation is interrupted", e);
-                } catch (java.util.concurrent.ExecutionException e) {
-                    throw new RuntimeException("Execution excetion", e);
-                }
-
-                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
-                if (jobResult != null) {
-                    if (jobResult instanceof ConcurrentOperationException) {
-                        throw (ConcurrentOperationException)jobResult;
-                    } else if (jobResult instanceof RuntimeException) {
-                        throw (RuntimeException)jobResult;
-                    } else if (jobResult instanceof Throwable) {
-                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
-                    }
-                }
-
-                // retrieve the entity url from job result
-                if (jobResult != null && jobResult instanceof String) {
-                    return (String)jobResult;
-                }
-                return null;
-            }
-        }
-
-        return orchestrateExtractVolume(volume.getId(), zoneId);
-    }
-
-    private String orchestrateExtractVolume(long volumeId, long zoneId) {
-        // get latest volume state to make sure that it is not updated by other parallel operations
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume == null || volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException("Volume to be extracted has been removed or not in right state!");
-        }
-        // perform extraction
-        ImageStoreEntity secStore = (ImageStoreEntity)dataStoreMgr.getImageStore(zoneId);
-        String value = _configDao.getValue(Config.CopyVolumeWait.toString());
-        NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
-
-        // Copy volume from primary to secondary storage
-        VolumeInfo srcVol = volFactory.getVolume(volumeId);
-        AsyncCallFuture<VolumeApiResult> cvAnswer = volService.copyVolume(srcVol, secStore);
-        // Check if you got a valid answer.
-        VolumeApiResult cvResult = null;
-        try {
-            cvResult = cvAnswer.get();
-        } catch (InterruptedException e1) {
-            s_logger.debug("failed copy volume", e1);
-            throw new CloudRuntimeException("Failed to copy volume", e1);
-        } catch (ExecutionException e1) {
-            s_logger.debug("failed copy volume", e1);
-            throw new CloudRuntimeException("Failed to copy volume", e1);
-        }
-        if (cvResult == null || cvResult.isFailed()) {
-            String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage.";
-            throw new CloudRuntimeException(errorString);
-        }
-
-        VolumeInfo vol = cvResult.getVolume();
-
-        String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat(), vol);
-        VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
-
-        volumeStoreRef.setExtractUrl(extractUrl);
-        volumeStoreRef.setExtractUrlCreated(DateUtil.now());
-        volumeStoreRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        volumeStoreRef.setDownloadPercent(100);
-        volumeStoreRef.setZoneId(zoneId);
-
-        _volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef);
-
-        return extractUrl;
-    }
-
-    @Override
-    public boolean isDisplayResourceEnabled(Long id) {
-        Volume volume = _volsDao.findById(id);
-        if (volume == null) {
-            return true; // bad id given, default to true
-        }
-        return volume.isDisplayVolume();
-    }
-
-    private String getFormatForPool(StoragePool pool) {
-        ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId());
-
-        if (cluster.getHypervisorType() == HypervisorType.XenServer) {
-            return "vhd";
-        } else if (cluster.getHypervisorType() == HypervisorType.KVM) {
-            return "qcow2";
-        } else if (cluster.getHypervisorType() == HypervisorType.Hyperv) {
-            return "vhdx";
-        } else if (cluster.getHypervisorType() == HypervisorType.VMware) {
-            return "ova";
-        } else if (cluster.getHypervisorType() == HypervisorType.Ovm) {
-            return "raw";
-        } else {
-            return null;
-        }
-    }
-
-    private boolean needMoveVolume(VolumeVO existingVolume, VolumeInfo newVolume) {
-        if (existingVolume == null || existingVolume.getPoolId() == null || newVolume.getPoolId() == null) {
-            return false;
-        }
-
-        DataStore storeForExistingVol = dataStoreMgr.getPrimaryDataStore(existingVolume.getPoolId());
-        DataStore storeForNewVol = dataStoreMgr.getPrimaryDataStore(newVolume.getPoolId());
-
-        Scope storeForExistingStoreScope = storeForExistingVol.getScope();
-        if (storeForExistingStoreScope == null) {
-            throw new CloudRuntimeException("Can't get scope of data store: " + storeForExistingVol.getId());
-        }
-
-        Scope storeForNewStoreScope = storeForNewVol.getScope();
-        if (storeForNewStoreScope == null) {
-            throw new CloudRuntimeException("Can't get scope of data store: " + storeForNewVol.getId());
-        }
-
-        if (storeForNewStoreScope.getScopeType() == ScopeType.ZONE) {
-            return false;
-        }
-
-        if (storeForExistingStoreScope.getScopeType() != storeForNewStoreScope.getScopeType()) {
-            if (storeForNewStoreScope.getScopeType() == ScopeType.CLUSTER) {
-                Long vmClusterId = null;
-                if (storeForExistingStoreScope.getScopeType() == ScopeType.HOST) {
-                    HostScope hs = (HostScope)storeForExistingStoreScope;
-                    vmClusterId = hs.getClusterId();
-                } else if (storeForExistingStoreScope.getScopeType() == ScopeType.ZONE) {
-                    Long hostId = _vmInstanceDao.findById(existingVolume.getInstanceId()).getHostId();
-                    if (hostId != null) {
-                        HostVO host = _hostDao.findById(hostId);
-                        vmClusterId = host.getClusterId();
-                    }
-                }
-                if (storeForNewStoreScope.getScopeId().equals(vmClusterId)) {
-                    return false;
-                } else {
-                    return true;
-                }
-            } else if (storeForNewStoreScope.getScopeType() == ScopeType.HOST
-                    && (storeForExistingStoreScope.getScopeType() == ScopeType.CLUSTER || storeForExistingStoreScope.getScopeType() == ScopeType.ZONE)) {
-                Long hostId = _vmInstanceDao.findById(existingVolume.getInstanceId()).getHostId();
-                if (storeForNewStoreScope.getScopeId().equals(hostId)) {
-                    return false;
-                }
-            }
-            throw new InvalidParameterValueException("Can't move volume between scope: " + storeForNewStoreScope.getScopeType() + " and " + storeForExistingStoreScope.getScopeType());
-        }
-
-        return !storeForExistingStoreScope.isSameScope(storeForNewStoreScope);
-    }
-
-    private synchronized void checkAndSetAttaching(Long volumeId) {
-        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
-
-        if (volumeToAttach.isAttachedVM()) {
-            throw new CloudRuntimeException("volume: " + volumeToAttach.getName() + " is already attached to a VM: " + volumeToAttach.getAttachedVmName());
-        }
-
-        if (Volume.State.Allocated.equals(volumeToAttach.getState())) {
-            return;
-        }
-
-        if (Volume.State.Ready.equals(volumeToAttach.getState())) {
-            volumeToAttach.stateTransit(Volume.Event.AttachRequested);
-            return;
-        }
-
-        final String error = "Volume: " + volumeToAttach.getName() + " is in " + volumeToAttach.getState() + ". It should be in Ready or Allocated state";
-        s_logger.error(error);
-        throw new CloudRuntimeException(error);
-    }
-
-    private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
-        String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName();
-        boolean sendCommand = vm.getState() == State.Running;
-        AttachAnswer answer = null;
-        Long hostId = vm.getHostId();
-
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-
-            HostVO host = _hostDao.findById(hostId);
-
-            if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
-                sendCommand = true;
-            }
-        }
-
-        HostVO host = null;
-        StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
-
-        if (hostId != null) {
-            host = _hostDao.findById(hostId);
-
-            if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged()) {
-                sendCommand = true;
-            }
-        }
-
-        // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
-        DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
-
-        checkAndSetAttaching(volumeToAttach.getId());
-
-        boolean attached = false;
-        try {
-            // if we don't have a host, the VM we are attaching the disk to has never been started before
-            if (host != null) {
-                try {
-                    volService.grantAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
-                } catch (Exception e) {
-                    volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
-
-                    throw new CloudRuntimeException(e.getMessage());
-                }
-            }
-
-            if (sendCommand) {
-                if (host != null && host.getHypervisorType() == HypervisorType.KVM && volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
-                    volumeToAttach.setPath(volumeToAttach.get_iScsiName());
-
-                    _volsDao.update(volumeToAttach.getId(), volumeToAttach);
-                }
-
-                DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
-
-                deviceId = getDeviceId(vm, deviceId);
-
-                DiskTO disk = storageMgr.getDiskWithThrottling(volTO, volumeToAttach.getVolumeType(), deviceId, volumeToAttach.getPath(), vm.getServiceOfferingId(),
-                        volumeToAttach.getDiskOfferingId());
-
-                AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
-
-                ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore);
-
-                Map<String, String> details = new HashMap<String, String>();
-
-                disk.setDetails(details);
-
-                details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
-                details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
-                details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
-                details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
-                details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
-                details.put(DiskTO.MOUNT_POINT, volumeToAttach.get_iScsiName());
-                details.put(DiskTO.PROTOCOL_TYPE, (volumeToAttach.getPoolType() != null) ? volumeToAttach.getPoolType().toString() : null);
-
-                if (chapInfo != null) {
-                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
-                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
-                    details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
-                    details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
-                }
-                _userVmDao.loadDetails(vm);
-                Map<String, String> controllerInfo = new HashMap<String, String>();
-                controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
-                controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
-                cmd.setControllerInfo(controllerInfo);
-                s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);
-
-                try {
-                    answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
-                } catch (Exception e) {
-                    if (host != null) {
-                        volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
-                    }
-                    throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
-                }
-            }
-
-            if (!sendCommand || (answer != null && answer.getResult())) {
-                // Mark the volume as attached
-                if (sendCommand) {
-                    DiskTO disk = answer.getDisk();
-
-                    _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), disk.getDiskSeq());
-
-                    volumeToAttach = _volsDao.findById(volumeToAttach.getId());
-
-                    if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
-                        volumeToAttach.setPath(answer.getDisk().getPath());
-
-                        _volsDao.update(volumeToAttach.getId(), volumeToAttach);
-                    }
-                } else {
-                    deviceId = getDeviceId(vm, deviceId);
-
-                    _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
-
-                    volumeToAttach = _volsDao.findById(volumeToAttach.getId());
-
-                    if (vm.getHypervisorType() == HypervisorType.KVM &&
-                            volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged() &&
-                            volumeToAttach.getPath() == null && volumeToAttach.get_iScsiName() != null) {
-                        volumeToAttach.setPath(volumeToAttach.get_iScsiName());
-                        _volsDao.update(volumeToAttach.getId(), volumeToAttach);
-                    }
-                }
-
-                // insert record for disk I/O statistics
-                VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
-                if (diskstats == null) {
-                    diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
-                    _vmDiskStatsDao.persist(diskstats);
-                }
-
-                attached = true;
-            } else {
-                if (answer != null) {
-                    String details = answer.getDetails();
-                    if (details != null && !details.isEmpty()) {
-                        errorMsg += "; " + details;
-                    }
-                }
-                if (host != null) {
-                    volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
-                }
-                throw new CloudRuntimeException(errorMsg);
-            }
-        } finally {
-            Volume.Event ev = Volume.Event.OperationFailed;
-            VolumeInfo volInfo = volFactory.getVolume(volumeToAttach.getId());
-            if (attached) {
-                ev = Volume.Event.OperationSucceeded;
-                s_logger.debug("Volume: " + volInfo.getName() + " successfully attached to VM: " + volInfo.getAttachedVmName());
-            } else {
-                s_logger.debug("Volume: " + volInfo.getName() + " failed to attach to VM: " + volInfo.getAttachedVmName());
-            }
-            volInfo.stateTransit(ev);
-        }
-        return _volsDao.findById(volumeToAttach.getId());
-    }
-
-    private int getMaxDataVolumesSupported(UserVmVO vm) {
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-        }
-        HostVO host = _hostDao.findById(hostId);
-        Integer maxDataVolumesSupported = null;
-        if (host != null) {
-            _hostDao.loadDetails(host);
-            maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version"));
-        }
-        if (maxDataVolumesSupported == null || maxDataVolumesSupported.intValue() <= 0) {
-            maxDataVolumesSupported = 6; // 6 data disks by default if nothing
-            // is specified in
-            // 'hypervisor_capabilities' table
-        }
-
-        return maxDataVolumesSupported.intValue();
-    }
-
-    private Long getDeviceId(UserVmVO vm, Long deviceId) {
-        // allocate deviceId
-        int maxDevices = getMaxDataVolumesSupported(vm) + 2; // add 2 to consider devices root volume and cdrom
-        int maxDeviceId = maxDevices - 1;
-        List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
-        if (deviceId != null) {
-            if (deviceId.longValue() < 0 || deviceId.longValue() > maxDeviceId || deviceId.longValue() == 3) {
-                throw new RuntimeException("deviceId should be 0,1,2,4-" + maxDeviceId);
-            }
-            for (VolumeVO vol : vols) {
-                if (vol.getDeviceId().equals(deviceId)) {
-                    throw new RuntimeException("deviceId " + deviceId + " is used by vm " + vm.getId());
-                }
-            }
-        } else {
-            // allocate deviceId here
-            List<String> devIds = new ArrayList<String>();
-            for (int i = 1; i <= maxDeviceId; i++) {
-                devIds.add(String.valueOf(i));
-            }
-            devIds.remove("3");
-            for (VolumeVO vol : vols) {
-                devIds.remove(vol.getDeviceId().toString().trim());
-            }
-            if (devIds.isEmpty()) {
-                throw new RuntimeException("All device Ids are used by vm " + vm.getId());
-            }
-            deviceId = Long.parseLong(devIds.iterator().next());
-        }
-
-        return deviceId;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) {
-        String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
-        _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
-        return true;
-    }
-
-    public List<StoragePoolAllocator> getStoragePoolAllocators() {
-        return _storagePoolAllocators;
-    }
-
-    @Inject
-    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
-        _storagePoolAllocators = storagePoolAllocators;
-    }
-
-    public class VmJobVolumeUrlOutcome extends OutcomeImpl<String> {
-
-        public VmJobVolumeUrlOutcome(final AsyncJob job) {
-            super(String.class, job, VmJobCheckInterval.value(), new Predicate() {
-                @Override
-                public boolean checkCondition() {
-                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
-                    assert (jobVo != null);
-                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                        return true;
-                    }
-
-                    return false;
-                }
-            }, AsyncJob.Topics.JOB_STATE);
-        }
-    }
-
-    public class VmJobVolumeOutcome extends OutcomeImpl<Volume> {
-        private long _volumeId;
-
-        public VmJobVolumeOutcome(final AsyncJob job, final long volumeId) {
-            super(Volume.class, job, VmJobCheckInterval.value(), new Predicate() {
-                @Override
-                public boolean checkCondition() {
-                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
-                    assert (jobVo != null);
-                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                        return true;
-                    }
-
-                    return false;
-                }
-            }, AsyncJob.Topics.JOB_STATE);
-            _volumeId = volumeId;
-        }
-
-        @Override
-        protected Volume retrieve() {
-            return _volsDao.findById(_volumeId);
-        }
-    }
-
-    public class VmJobSnapshotOutcome extends OutcomeImpl<Snapshot> {
-        private long _snapshotId;
-
-        public VmJobSnapshotOutcome(final AsyncJob job, final long snapshotId) {
-            super(Snapshot.class, job, VmJobCheckInterval.value(), new Predicate() {
-                @Override
-                public boolean checkCondition() {
-                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
-                    assert (jobVo != null);
-                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
-                        return true;
-                    }
-
-                    return false;
-                }
-            }, AsyncJob.Topics.JOB_STATE);
-            _snapshotId = snapshotId;
-        }
-
-        @Override
-        protected Snapshot retrieve() {
-            return _snapshotDao.findById(_snapshotId);
-        }
-    }
-
-    public Outcome<Volume> attachVolumeToVmThroughJobQueue(final Long vmId, final Long volumeId, final Long deviceId) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkAttachVolume.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, deviceId);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId());
-        s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVolumeOutcome(workJob, volumeId);
-    }
-
-    public Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkDetachVolume.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVolumeOutcome(workJob, volumeId);
-    }
-
-    public Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId, final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops,
-            final Integer newHypervisorSnapshotReserve, final Long newServiceOfferingId, final boolean shrinkOk) {
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkResizeVolume.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize,
-                newMinIops, newMaxIops, newHypervisorSnapshotReserve, newServiceOfferingId, shrinkOk);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVolumeOutcome(workJob, volumeId);
-    }
-
-    public Outcome<String> extractVolumeThroughJobQueue(final Long vmId, final long volumeId, final long zoneId) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkExtractVolume.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkExtractVolume workInfo = new VmWorkExtractVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, zoneId);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVolumeUrlOutcome(workJob);
-    }
-
-    public Outcome<Volume> migrateVolumeThroughJobQueue(final Long vmId, final long volumeId, final long destPoolId, final boolean liveMigrate) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkMigrateVolume.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, destPoolId, liveMigrate);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobVolumeOutcome(workJob, volumeId);
-    }
-
-    public Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId, final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm,
-            final Snapshot.LocationType locationType, final boolean asyncBackup) {
-
-        final CallContext context = CallContext.current();
-        final User callingUser = context.getCallingUser();
-        final Account callingAccount = context.getCallingAccount();
-
-        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
-        workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName());
-
-        workJob.setAccountId(callingAccount.getId());
-        workJob.setUserId(callingUser.getId());
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(vm.getId());
-        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
-
-        // save work context info (there are some duplications)
-        VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot(callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(),
-                VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm, locationType, asyncBackup);
-        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
-
-        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
-
-        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
-
-        return new VmJobSnapshotOutcome(workJob, snapshotId);
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateExtractVolume(VmWorkExtractVolume work) throws Exception {
-        String volUrl = orchestrateExtractVolume(work.getVolumeId(), work.getZoneId());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(volUrl));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateAttachVolumeToVM(VmWorkAttachVolume work) throws Exception {
-        Volume vol = orchestrateAttachVolumeToVM(work.getVmId(), work.getVolumeId(), work.getDeviceId());
-
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateDetachVolumeFromVM(VmWorkDetachVolume work) throws Exception {
-        Volume vol = orchestrateDetachVolumeFromVM(work.getVmId(), work.getVolumeId());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateResizeVolume(VmWorkResizeVolume work) throws Exception {
-        Volume vol = orchestrateResizeVolume(work.getVolumeId(), work.getCurrentSize(), work.getNewSize(), work.getNewMinIops(), work.getNewMaxIops(), work.getNewHypervisorSnapshotReserve(),
-                work.getNewServiceOfferingId(), work.isShrinkOk());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateMigrateVolume(VmWorkMigrateVolume work) throws Exception {
-        Volume newVol = orchestrateMigrateVolume(work.getVolumeId(), work.getDestPoolId(), work.isLiveMigrate());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(newVol.getId())));
-    }
-
-    @ReflectionUse
-    private Pair<JobInfo.Status, String> orchestrateTakeVolumeSnapshot(VmWorkTakeVolumeSnapshot work) throws Exception {
-        Account account = _accountDao.findById(work.getAccountId());
-        orchestrateTakeVolumeSnapshot(work.getVolumeId(), work.getPolicyId(), work.getSnapshotId(), account, work.isQuiesceVm(), work.getLocationType(), work.isAsyncBackup());
-        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(work.getSnapshotId()));
-    }
-
-    @Override
-    public Pair<JobInfo.Status, String> handleVmWorkJob(VmWork work) throws Exception {
-        return _jobHandlerProxy.handleVmWorkJob(work);
-    }
-
-    private VmWorkJobVO createPlaceHolderWork(long instanceId) {
-        VmWorkJobVO workJob = new VmWorkJobVO("");
-
-        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
-        workJob.setCmd("");
-        workJob.setCmdInfo("");
-
-        workJob.setAccountId(0);
-        workJob.setUserId(0);
-        workJob.setStep(VmWorkJobVO.Step.Starting);
-        workJob.setVmType(VirtualMachine.Type.Instance);
-        workJob.setVmInstanceId(instanceId);
-        workJob.setInitMsid(ManagementServerNode.getManagementServerId());
-
-        _workJobDao.persist(workJob);
-
-        return workJob;
-    }
-
-}
diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java
deleted file mode 100644
index e7f21b1..0000000
--- a/server/src/com/cloud/template/TemplateAdapterBase.java
+++ /dev/null
@@ -1,481 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.template;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Grouping;
-import com.cloud.projects.ProjectManager;
-import com.cloud.server.ConfigurationServer;
-import com.cloud.storage.GuestOS;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.TemplateProfile;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.GuestOSHypervisorDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.EnumUtils;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.dao.UserVmDao;
-
-public abstract class TemplateAdapterBase extends AdapterBase implements TemplateAdapter {
-    private final static Logger s_logger = Logger.getLogger(TemplateAdapterBase.class);
-    protected @Inject
-    DomainDao _domainDao;
-    protected @Inject
-    AccountDao _accountDao;
-    protected @Inject
-    ConfigurationDao _configDao;
-    protected @Inject
-    UserDao _userDao;
-    protected @Inject
-    AccountManager _accountMgr;
-    protected @Inject
-    DataCenterDao _dcDao;
-    protected @Inject
-    VMTemplateDao _tmpltDao;
-    protected @Inject
-    TemplateDataStoreDao _tmpltStoreDao;
-    protected @Inject
-    VMTemplateZoneDao _tmpltZoneDao;
-    protected @Inject
-    UsageEventDao _usageEventDao;
-    protected @Inject
-    HostDao _hostDao;
-    protected @Inject
-    UserVmDao _userVmDao;
-    protected @Inject
-    GuestOSHypervisorDao _osHyperDao;
-    protected @Inject
-    ResourceLimitService _resourceLimitMgr;
-    protected @Inject
-    ImageStoreDao _imgStoreDao;
-    @Inject
-    TemplateManager templateMgr;
-    @Inject
-    ConfigurationServer _configServer;
-    @Inject
-    ProjectManager _projectMgr;
-    @Inject
-    private TemplateDataStoreDao templateDataStoreDao;
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
-        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String accountName,
-        Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload) throws ResourceAllocationException {
-        return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId,
-            hypervisorType, chksum, bootable, null, null, details, false, null, false, TemplateType.USER, directDownload);
-    }
-
-    @Override
-    public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
-        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneIdList, HypervisorType hypervisorType, String chksum,
-        Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable,
-        TemplateType templateType, boolean directDownload) throws ResourceAllocationException {
-        //Long accountId = null;
-        // parameters verification
-
-        if (isPublic == null) {
-            isPublic = Boolean.FALSE;
-        }
-
-        if (isIso) {
-            if (bootable == null) {
-                bootable = Boolean.TRUE;
-            }
-            GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
-            if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true) {
-                throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
-            }
-            if (bootable == false) {
-                guestOSId = noneGuestOs.getId(); //Guest os id of None.
-            }
-        } else {
-            if (bits == null) {
-                bits = Integer.valueOf(64);
-            }
-            if (passwordEnabled == null) {
-                passwordEnabled = false;
-            }
-            if (requiresHVM == null) {
-                requiresHVM = true;
-            }
-        }
-
-        if (isExtractable == null) {
-            isExtractable = Boolean.FALSE;
-        }
-        if (sshkeyEnabled == null) {
-            sshkeyEnabled = Boolean.FALSE;
-        }
-
-        boolean isAdmin = _accountMgr.isRootAdmin(templateOwner.getId());
-        boolean isRegionStore = false;
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (stores != null && stores.size() > 0) {
-            isRegionStore = true;
-        }
-
-        if (!isAdmin && zoneIdList == null && !isRegionStore ) {
-            // domain admin and user should also be able to register template on a region store
-            throw new InvalidParameterValueException("Please specify a valid zone Id. Only admins can create templates in all zones.");
-        }
-
-        // check for the url format only when url is not null. url can be null incase of form based upload
-        if (url != null && url.toLowerCase().contains("file://")) {
-            throw new InvalidParameterValueException("File:// type urls are currently unsupported");
-        }
-
-        // check whether owner can create public templates
-        boolean allowPublicUserTemplates = TemplateManager.AllowPublicUserTemplates.valueIn(templateOwner.getId());
-        if (!isAdmin && !allowPublicUserTemplates && isPublic) {
-            throw new InvalidParameterValueException("Only private templates/ISO can be created.");
-        }
-
-        if (!isAdmin || featured == null) {
-            featured = Boolean.FALSE;
-        }
-
-        ImageFormat imgfmt;
-        try {
-            imgfmt = ImageFormat.valueOf(format.toUpperCase());
-        } catch (IllegalArgumentException e) {
-            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
-            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
-        }
-
-        // Check that the resource limit for templates/ISOs won't be exceeded
-        UserVO user = _userDao.findById(userId);
-        if (user == null) {
-            throw new IllegalArgumentException("Unable to find user with id " + userId);
-        }
-
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
-
-        // If a zoneId is specified, make sure it is valid
-        if (zoneIdList != null) {
-            for (Long zoneId :zoneIdList) {
-                DataCenterVO zone = _dcDao.findById(zoneId);
-                if (zone == null) {
-                    throw new IllegalArgumentException("Please specify a valid zone.");
-                }
-                Account caller = CallContext.current().getCallingAccount();
-                if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
-                    throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
-                }
-            }
-        }
-
-        List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
-        for (VMTemplateVO template : systemvmTmplts) {
-            if (template.getName().equalsIgnoreCase(name) || template.getDisplayText().equalsIgnoreCase(displayText)) {
-                throw new IllegalArgumentException("Cannot use reserved names for templates");
-            }
-        }
-
-        if (hypervisorType.equals(Hypervisor.HypervisorType.XenServer)) {
-            if (details == null || !details.containsKey("hypervisortoolsversion") || details.get("hypervisortoolsversion") == null ||
-                ((String)details.get("hypervisortoolsversion")).equalsIgnoreCase("none")) {
-                String hpvs = _configDao.getValue(Config.XenServerPVdriverVersion.key());
-                if (hpvs != null) {
-                    if (details == null) {
-                        details = new HashMap<String, String>();
-                    }
-                    details.put("hypervisortoolsversion", hpvs);
-                }
-            }
-        }
-
-        Long id = _tmpltDao.getNextInSequence(Long.class, "id");
-        CallContext.current().setEventDetails("Id: " + id + " name: " + name);
-        return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, imgfmt, guestOSId, zoneIdList,
-            hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details,
-            sshkeyEnabled, null, isDynamicallyScalable, templateType, directDownload);
-
-    }
-
-    @Override
-    public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
-        //check if the caller can operate with the template owner
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType();
-
-        List<Long> zoneId = cmd.getZoneIds();
-        // ignore passed zoneId if we are using region wide image store
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (stores != null && stores.size() > 0) {
-            zoneId = null;
-        }
-
-        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
-        if(hypervisorType == HypervisorType.None) {
-            throw new InvalidParameterValueException("Hypervisor Type: " + cmd.getHypervisor() + " is invalid. Supported Hypervisor types are "
-                    + EnumUtils.listValues(HypervisorType.values()).replace("None, ", ""));
-        }
-
-        return prepare(false, CallContext.current().getCallingUserId(), cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(),
-                cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneId, hypervisorType, cmd.getChecksum(), true,
-                cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER, cmd.isDirectDownload());
-
-    }
-
-    @Override
-    public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException {
-        //check if the caller can operate with the template owner
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType();
-
-        List<Long> zoneList = null;
-        Long zoneId = cmd.getZoneId();
-        // ignore passed zoneId if we are using region wide image store
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (!(stores != null && stores.size() > 0)) {
-            zoneList = new ArrayList<>();
-            zoneList.add(zoneId);
-        }
-
-        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
-        if(hypervisorType == HypervisorType.None) {
-            throw new InvalidParameterValueException("Hypervisor Type: " + cmd.getHypervisor() + " is invalid. Supported Hypervisor types are "
-                                                         + EnumUtils.listValues(HypervisorType.values()).replace("None, ", ""));
-        }
-
-        return prepare(false, CallContext.current().getCallingUserId(), cmd.getName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(),
-                       cmd.getRequiresHvm(), null, cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneList,
-                       hypervisorType, cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null,
-                       cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER, false);
-
-    }
-
-    @Override
-    public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
-        //check if the caller can operate with the template owner
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        List<Long> zoneList = null;
-        Long zoneId = cmd.getZoneId();
-        // ignore passed zoneId if we are using region wide image store
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (CollectionUtils.isEmpty(stores) && zoneId != null && zoneId > 0L) {
-            zoneList = new ArrayList<>();
-            zoneList.add(zoneId);
-        }
-
-        return prepare(true, CallContext.current().getCallingUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false, true, cmd.getUrl(), cmd.isPublic(),
-            cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), zoneList, HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null,
-            owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(), TemplateType.USER, cmd.isDirectDownload());
-    }
-
-    protected VMTemplateVO persistTemplate(TemplateProfile profile, VirtualMachineTemplate.State initialState) {
-        List<Long> zoneIdList = profile.getZoneIdList();
-        VMTemplateVO template =
-            new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(), profile.getFeatured(), profile.getIsExtractable(),
-                profile.getTemplateType(), profile.getUrl(), profile.getRequiresHVM(), profile.getBits(), profile.getAccountId(), profile.getCheckSum(),
-                profile.getDisplayText(), profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(),
-                profile.getTemplateTag(), profile.getDetails(), profile.getSshKeyEnabled(), profile.IsDynamicallyScalable(), profile.isDirectDownload());
-        template.setState(initialState);
-
-        if (profile.isDirectDownload()) {
-            template.setSize(profile.getSize());
-        }
-
-        if (zoneIdList == null) {
-            List<DataCenterVO> dcs = _dcDao.listAll();
-
-            if (dcs.isEmpty()) {
-                throw new CloudRuntimeException("No zones are present in the system, can't add template");
-            }
-
-            template.setCrossZones(true);
-            for (DataCenterVO dc : dcs) {
-                _tmpltDao.addTemplateToZone(template, dc.getId());
-            }
-
-        } else {
-            for (Long zoneId: zoneIdList) {
-                _tmpltDao.addTemplateToZone(template, zoneId);
-            }
-        }
-        return _tmpltDao.findById(template.getId());
-    }
-
-    private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg) throws PermissionDeniedException {
-
-        if (account != null) {
-            if (!_accountMgr.isAdmin(account.getId())) {
-                if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) {
-                    throw new PermissionDeniedException(msg + ". Permission denied.");
-                }
-
-                if ((template != null) &&
-                    (!template.isPublicTemplate() && (account.getId() != template.getAccountId()) && (template.getTemplateType() != TemplateType.PERHOST))) {
-                    //special handling for the project case
-                    Account owner = _accountMgr.getAccount(template.getAccountId());
-                    if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-                        if (!_projectMgr.canAccessProjectAccount(account, owner.getId())) {
-                            throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's template");
-                        }
-                    } else {
-                        throw new PermissionDeniedException(msg + ". Permission denied.");
-                    }
-                }
-            } else {
-                if ((vmInstanceCheck != null) && !_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
-                    throw new PermissionDeniedException(msg + ". Permission denied.");
-                }
-                // FIXME: if template/ISO owner is null we probably need to
-                // throw some kind of exception
-
-                if (template != null) {
-                    Account templateOwner = _accountDao.findById(template.getAccountId());
-                    if ((templateOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), templateOwner.getDomainId())) {
-                        throw new PermissionDeniedException(msg + ". Permission denied.");
-                    }
-                }
-            }
-        }
-
-        return userId;
-    }
-
-    @Override
-    public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
-        Long templateId = cmd.getId();
-        Long userId = CallContext.current().getCallingUserId();
-        Account account = CallContext.current().getCallingAccount();
-        Long zoneId = cmd.getZoneId();
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
-        }
-
-        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete template ");
-
-        UserVO user = _userDao.findById(userId);
-        if (user == null) {
-            throw new InvalidParameterValueException("Please specify a valid user.");
-        }
-
-        if (template.getFormat() == ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
-        }
-
-        return new TemplateProfile(userId, template, zoneId);
-    }
-
-    @Override
-    public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd) {
-        Long templateId = cmd.getId();
-        Long userId = CallContext.current().getCallingUserId();
-        Long zoneId = cmd.getZoneId();
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
-        }
-        return new TemplateProfile(userId, template, zoneId);
-    }
-
-    @Override
-    public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
-        Long templateId = cmd.getId();
-        Long userId = CallContext.current().getCallingUserId();
-        Account account = CallContext.current().getCallingAccount();
-        Long zoneId = cmd.getZoneId();
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
-        }
-
-        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso ");
-
-        UserVO user = _userDao.findById(userId);
-        if (user == null) {
-            throw new InvalidParameterValueException("Please specify a valid user.");
-        }
-
-        if (template.getFormat() != ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid iso.");
-        }
-
-        return new TemplateProfile(userId, template, zoneId);
-    }
-
-    @Override
-    abstract public VMTemplateVO create(TemplateProfile profile);
-
-    @Override
-    abstract public boolean delete(TemplateProfile profile);
-}
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
deleted file mode 100755
index 48cc6f4..0000000
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ /dev/null
@@ -1,2175 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.template;
-
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.deploy.DeployDestination;
-import com.cloud.storage.ImageStoreUploadMonitorImpl;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.EncryptionUtil;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.EnumUtils;
-import com.google.common.base.Joiner;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
-import org.apache.log4j.Logger;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
-import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
-import org.apache.cloudstack.api.response.GetUploadParamsResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
-import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-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;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ComputeChecksumCommand;
-import com.cloud.agent.api.storage.DestroyCommand;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.ApiResponseHelper;
-import com.cloud.api.query.dao.UserVmJoinDao;
-import com.cloud.api.query.vo.UserVmJoinVO;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.UsageEventVO;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.projects.Project;
-import com.cloud.projects.ProjectManager;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.LaunchPermissionVO;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.TemplateProfile;
-import com.cloud.storage.Upload;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.LaunchPermissionDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateDetailsDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.template.TemplateAdapter.TemplateAdapterType;
-import com.cloud.template.VirtualMachineTemplate.BootloaderType;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
-public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService, Configurable {
-    private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
-
-    @Inject
-    private VMTemplateDao _tmpltDao;
-    @Inject
-    private TemplateDataStoreDao _tmplStoreDao;
-    @Inject
-    private VMTemplatePoolDao _tmpltPoolDao;
-    @Inject
-    private VMTemplateZoneDao _tmpltZoneDao;
-    @Inject
-    private VMInstanceDao _vmInstanceDao;
-    @Inject
-    private PrimaryDataStoreDao _poolDao;
-    @Inject
-    private StoragePoolHostDao _poolHostDao;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private SnapshotDao _snapshotDao;
-    @Inject
-    private ConfigurationDao _configDao;
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private GuestOSDao _guestOSDao;
-    @Inject
-    private StorageManager _storageMgr;
-    @Inject
-    private UsageEventDao _usageEventDao;
-    @Inject
-    private AccountService _accountService;
-    @Inject
-    private ResourceLimitService _resourceLimitMgr;
-    @Inject
-    private LaunchPermissionDao _launchPermissionDao;
-    @Inject
-    private ProjectManager _projectMgr;
-    @Inject
-    private VolumeDataFactory _volFactory;
-    @Inject
-    private TemplateDataFactory _tmplFactory;
-    @Inject
-    private SnapshotDataFactory _snapshotFactory;
-    @Inject
-    StorageStrategyFactory _storageStrategyFactory;
-    @Inject
-    private TemplateService _tmpltSvr;
-    @Inject
-    private DataStoreManager _dataStoreMgr;
-    @Inject
-    private VolumeOrchestrationService _volumeMgr;
-    @Inject
-    private EndPointSelector _epSelector;
-    @Inject
-    private UserVmJoinDao _userVmJoinDao;
-    @Inject
-    private SnapshotDataStoreDao _snapshotStoreDao;
-    @Inject
-    private ImageStoreDao _imgStoreDao;
-    @Inject
-    MessageBus _messageBus;
-    @Inject
-    private VMTemplateDetailsDao _tmpltDetailsDao;
-
-    private boolean _disableExtraction = false;
-    private List<TemplateAdapter> _adapters;
-
-    ExecutorService _preloadExecutor;
-
-    @Inject
-    private StorageCacheManager cacheMgr;
-    @Inject
-    private EndPointSelector selector;
-
-
-    private TemplateAdapter getAdapter(HypervisorType type) {
-        TemplateAdapter adapter = null;
-        if (type == HypervisorType.BareMetal) {
-            adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName());
-        } else {
-            // see HypervisorTemplateAdapter
-            adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
-        }
-
-        if (adapter == null) {
-            throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
-        }
-
-        return adapter;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
-    public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException {
-        TemplateAdapter adapter = getAdapter(HypervisorType.None);
-        TemplateProfile profile = adapter.prepare(cmd);
-        VMTemplateVO template = adapter.create(profile);
-
-        if (template != null) {
-            return template;
-        } else {
-            throw new CloudRuntimeException("Failed to create ISO");
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template")
-    public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException {
-        Account account = CallContext.current().getCallingAccount();
-        if (cmd.getTemplateTag() != null) {
-            if (!_accountService.isRootAdmin(account.getId())) {
-                throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
-            }
-        }
-        if (cmd.isRoutingType() != null) {
-            if (!_accountService.isRootAdmin(account.getId())) {
-                throw new PermissionDeniedException("Parameter isrouting can only be specified by a Root Admin, permission denied");
-            }
-        }
-
-        TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
-        TemplateProfile profile = adapter.prepare(cmd);
-        VMTemplateVO template = adapter.create(profile);
-
-        if (template != null) {
-            return template;
-        } else {
-            throw new CloudRuntimeException("Failed to create a template");
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating post upload template")
-    public GetUploadParamsResponse registerTemplateForPostUpload(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException, MalformedURLException {
-        TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
-        TemplateProfile profile = adapter.prepare(cmd);
-        List<TemplateOrVolumePostUploadCommand> payload = adapter.createTemplateForPostUpload(profile);
-
-        if(CollectionUtils.isNotEmpty(payload)) {
-            GetUploadParamsResponse response = new GetUploadParamsResponse();
-
-            /*
-             * There can be one or more commands depending on the number of secondary stores the template needs to go to. Taking the first one to do the url upload. The
-             * template will be propagated to the rest through copy by management server commands.
-             */
-            TemplateOrVolumePostUploadCommand firstCommand = payload.get(0);
-
-            String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
-
-            String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, firstCommand.getRemoteEndPoint(), firstCommand.getEntityUUID());
-            response.setPostURL(new URL(url));
-
-            // set the post url, this is used in the monitoring thread to determine the SSVM
-            TemplateDataStoreVO templateStore = _tmplStoreDao.findByTemplate(firstCommand.getEntityId(), DataStoreRole.getRole(firstCommand.getDataToRole()));
-            if (templateStore != null) {
-                templateStore.setExtractUrl(url);
-                _tmplStoreDao.persist(templateStore);
-            }
-
-            response.setId(UUID.fromString(firstCommand.getEntityUUID()));
-
-            int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
-            DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
-            String expires = currentDateTime.plusMinutes(timeout).toString();
-            response.setTimeout(expires);
-
-            String key = _configDao.getValue(Config.SSVMPSK.key());
-            /*
-             * encoded metadata using the post upload config ssh key
-             */
-            Gson gson = new GsonBuilder().create();
-            String metadata = EncryptionUtil.encodeData(gson.toJson(firstCommand), key);
-            response.setMetadata(metadata);
-
-            /*
-             * signature calculated on the url, expiry, metadata.
-             */
-            response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
-
-            return response;
-        } else {
-            throw new CloudRuntimeException("Unable to register template.");
-        }
-    }
-
-
-    @Override
-    public DataStore getImageStore(String storeUuid, Long zoneId) {
-        DataStore imageStore = null;
-        if (storeUuid != null) {
-            imageStore = _dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
-        } else {
-            imageStore = _dataStoreMgr.getImageStore(zoneId);
-            if (imageStore == null) {
-                throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
-            }
-        }
-
-        return imageStore;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
-    public String extract(ExtractIsoCmd cmd) {
-        Account account = CallContext.current().getCallingAccount();
-        Long templateId = cmd.getId();
-        Long zoneId = cmd.getZoneId();
-        String url = cmd.getUrl();
-        String mode = cmd.getMode();
-        Long eventId = cmd.getStartEventId();
-
-        return extract(account, templateId, url, zoneId, mode, eventId, true);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
-    public String extract(ExtractTemplateCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long templateId = cmd.getId();
-        Long zoneId = cmd.getZoneId();
-        String url = cmd.getUrl();
-        String mode = cmd.getMode();
-        Long eventId = cmd.getStartEventId();
-
-        VirtualMachineTemplate template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
-        }
-
-        return extract(caller, templateId, url, zoneId, mode, eventId, false);
-    }
-
-    @Override
-    public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId, Long storageId) {
-
-        VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
-        if (vmTemplate == null) {
-            throw new InvalidParameterValueException("Unable to find template id=" + templateId);
-        }
-
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, vmTemplate);
-
-        if (storageId != null) {
-            StoragePoolVO pool = _poolDao.findById(storageId);
-            if (pool != null) {
-                if (pool.getStatus() == StoragePoolStatus.Up && pool.getDataCenterId() == zoneId) {
-                    prepareTemplateInOneStoragePool(vmTemplate, pool);
-                } else {
-                    s_logger.warn("Skip loading template " + vmTemplate.getId() + " into primary storage " + pool.getId() + " as either the pool zone "
-                            + pool.getDataCenterId() + " is different from the requested zone " + zoneId + " or the pool is currently not available.");
-                }
-            }
-        } else {
-            prepareTemplateInAllStoragePools(vmTemplate, zoneId);
-        }
-        return vmTemplate;
-    }
-
-    private String extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO) {
-        String desc = Upload.Type.TEMPLATE.toString();
-        if (isISO) {
-            desc = Upload.Type.ISO.toString();
-        }
-        if (!_accountMgr.isRootAdmin(caller.getId()) && _disableExtraction) {
-            throw new PermissionDeniedException("Extraction has been disabled by admin");
-        }
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null || template.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find " + desc + " with id " + templateId);
-        }
-
-        if (template.getTemplateType() == Storage.TemplateType.SYSTEM) {
-            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
-        } else if (template.getTemplateType() == Storage.TemplateType.PERHOST) {
-            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
-        }
-
-        if (isISO) {
-            if (template.getFormat() != ImageFormat.ISO) {
-                throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
-            }
-        } else {
-            if (template.getFormat() == ImageFormat.ISO) {
-                throw new InvalidParameterValueException("Unsupported format, could not extract the template");
-            }
-        }
-
-        if (zoneId != null && _dcDao.findById(zoneId) == null) {
-            throw new IllegalArgumentException("Please specify a valid zone.");
-        }
-
-        if (!_accountMgr.isRootAdmin(caller.getId()) && !template.isExtractable()) {
-            throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
-
-        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
-
-        TemplateDataStoreVO tmpltStoreRef = null;
-        ImageStoreEntity tmpltStore = null;
-        if (ssStores != null) {
-            for (DataStore store : ssStores) {
-                tmpltStoreRef = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
-                if (tmpltStoreRef != null) {
-                    if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                        tmpltStore = (ImageStoreEntity)store;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (tmpltStore == null) {
-            throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
-        }
-
-        // Check if the url already exists
-        if(tmpltStoreRef.getExtractUrl() != null){
-            return tmpltStoreRef.getExtractUrl();
-        }
-
-        // Handle NFS to S3 object store migration case, we trigger template sync from NFS to S3 during extract template or copy template
-        _tmpltSvr.syncTemplateToRegionStore(templateId, tmpltStore);
-
-        TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, tmpltStore);
-        String extractUrl = tmpltStore.createEntityExtractUrl(templateObject.getInstallPath(), template.getFormat(), templateObject);
-        tmpltStoreRef.setExtractUrl(extractUrl);
-        tmpltStoreRef.setExtractUrlCreated(DateUtil.now());
-        _tmplStoreDao.update(tmpltStoreRef.getId(), tmpltStoreRef);
-        return extractUrl;
-    }
-
-    @Override
-    public void prepareIsoForVmProfile(VirtualMachineProfile profile, DeployDestination dest) {
-        UserVmVO vm = _userVmDao.findById(profile.getId());
-        if (vm.getIsoId() != null) {
-            Map<Volume, StoragePool> storageForDisks = dest.getStorageForDisks();
-            Long poolId = null;
-            if (MapUtils.isNotEmpty(storageForDisks)) {
-                for (StoragePool storagePool : storageForDisks.values()) {
-                    if (poolId != null && storagePool.getId() != poolId) {
-                        throw new CloudRuntimeException("Cannot determine where to download iso");
-                    }
-                    poolId = storagePool.getId();
-                }
-            }
-            TemplateInfo template = prepareIso(vm.getIsoId(), vm.getDataCenterId(), dest.getHost().getId(), poolId);
-            if (template == null){
-                s_logger.error("Failed to prepare ISO on secondary or cache storage");
-                throw new CloudRuntimeException("Failed to prepare ISO on secondary or cache storage");
-            }
-            if (template.isBootable()) {
-                profile.setBootLoaderType(BootloaderType.CD);
-            }
-
-            GuestOSVO guestOS = _guestOSDao.findById(template.getGuestOSId());
-            String displayName = null;
-            if (guestOS != null) {
-                displayName = guestOS.getDisplayName();
-            }
-
-            TemplateObjectTO iso = (TemplateObjectTO)template.getTO();
-            iso.setDirectDownload(template.isDirectDownload());
-            iso.setGuestOsType(displayName);
-            DiskTO disk = new DiskTO(iso, 3L, null, Volume.Type.ISO);
-            profile.addDisk(disk);
-        } else {
-            TemplateObjectTO iso = new TemplateObjectTO();
-            iso.setFormat(ImageFormat.ISO);
-            DiskTO disk = new DiskTO(iso, 3L, null, Volume.Type.ISO);
-            profile.addDisk(disk);
-        }
-    }
-
-    private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) {
-        s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
-        _preloadExecutor.execute(new ManagedContextRunnable() {
-            @Override
-            protected void runInContext() {
-                try {
-                    reallyRun();
-                } catch (Throwable e) {
-                    s_logger.warn("Unexpected exception ", e);
-                }
-            }
-
-            private void reallyRun() {
-                s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
-                StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId());
-                prepareTemplateForCreate(template, pol);
-                s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
-            }
-        });
-    }
-
-    public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
-        List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
-        for (final StoragePoolVO pool : pools) {
-            if (pool.getDataCenterId() == zoneId) {
-                prepareTemplateInOneStoragePool(template, pool);
-            } else {
-                s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() +
-                        " is different from the requested zone " + zoneId);
-            }
-        }
-    }
-
-    @Override
-    @DB
-    public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
-        VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
-
-        long poolId = pool.getId();
-        long templateId = template.getId();
-        VMTemplateStoragePoolVO templateStoragePoolRef = null;
-        TemplateDataStoreVO templateStoreRef = null;
-
-        templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
-        if (templateStoragePoolRef != null) {
-            templateStoragePoolRef.setMarkedForGC(false);
-            _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
-
-            if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
-                }
-
-                return templateStoragePoolRef;
-            }
-        }
-
-        templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        if (templateStoreRef == null) {
-            s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
-            return null;
-        }
-
-        List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
-        if (vos == null || vos.isEmpty()) {
-            throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
-        }
-
-        if (templateStoragePoolRef == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
-            }
-            DataStore srcSecStore = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
-            TemplateInfo srcTemplate = _tmplFactory.getTemplate(templateId, srcSecStore);
-
-            AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool);
-            try {
-                TemplateApiResult result = future.get();
-                if (result.isFailed()) {
-                    s_logger.debug("prepare template failed:" + result.getResult());
-                    return null;
-                }
-
-                return _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
-            } catch (Exception ex) {
-                s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage");
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public String getChecksum(DataStore store, String templatePath, String algorithm) {
-        EndPoint ep = _epSelector.select(store);
-        ComputeChecksumCommand cmd = new ComputeChecksumCommand(store.getTO(), templatePath, algorithm);
-        Answer answer = null;
-        if (ep == null) {
-            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            s_logger.error(errMsg);
-            answer = new Answer(cmd, false, errMsg);
-        } else {
-            answer = ep.sendMessage(cmd);
-        }
-        if (answer != null && answer.getResult()) {
-            return answer.getDetails();
-        }
-        return null;
-    }
-
-    @Override
-    @DB
-    public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) {
-        // have to use the same lock that prepareTemplateForCreate use to
-        // maintain state consistency
-        VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200);
-
-        if (templateStoragePoolRef == null) {
-            s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId);
-            return false;
-        }
-
-        try {
-            templateStoragePoolRef.setTemplateSize(0);
-            templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
-
-            _tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef);
-        } finally {
-            _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
-        }
-
-        return true;
-    }
-
-    @Override
-    @DB
-    public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
-        long tmpltId = template.getId();
-        long dstZoneId = dstZone.getId();
-        // find all eligible image stores for the destination zone
-        List<DataStore> dstSecStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId));
-        if (dstSecStores == null || dstSecStores.isEmpty()) {
-            throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId());
-        }
-        AccountVO account = _accountDao.findById(template.getAccountId());
-        // find the size of the template to be copied
-        TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
-
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()).longValue());
-
-        // Event details
-        String copyEventType;
-        if (template.getFormat().equals(ImageFormat.ISO)) {
-            copyEventType = EventTypes.EVENT_ISO_COPY;
-        } else {
-            copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
-        }
-
-        TemplateInfo srcTemplate = _tmplFactory.getTemplate(template.getId(), srcSecStore);
-        // Copy will just find one eligible image store for the destination zone
-        // and copy template there, not propagate to all image stores
-        // for that zone
-        for (DataStore dstSecStore : dstSecStores) {
-            TemplateDataStoreVO dstTmpltStore = _tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId);
-            if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
-                return true; // already downloaded on this image store
-            }
-            if (dstTmpltStore != null && dstTmpltStore.getDownloadState() != Status.DOWNLOAD_IN_PROGRESS) {
-                _tmplStoreDao.removeByTemplateStore(tmpltId, dstSecStore.getId());
-            }
-
-            AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
-            try {
-                TemplateApiResult result = future.get();
-                if (result.isFailed()) {
-                    s_logger.debug("copy template failed for image store " + dstSecStore.getName() + ":" + result.getResult());
-                    continue; // try next image store
-                }
-
-                _tmpltDao.addTemplateToZone(template, dstZoneId);
-
-                if (account.getId() != Account.ACCOUNT_ID_SYSTEM) {
-                    UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getPhysicalSize(),
-                            srcTmpltStore.getSize(), template.getClass().getName(), template.getUuid());
-                }
-
-                // Copy every Datadisk template that belongs to the template to Destination zone
-                List<VMTemplateVO> dataDiskTemplates = _tmpltDao.listByParentTemplatetId(template.getId());
-                if (dataDiskTemplates != null && !dataDiskTemplates.isEmpty()) {
-                    for (VMTemplateVO dataDiskTemplate : dataDiskTemplates) {
-                        s_logger.debug("Copying " + dataDiskTemplates.size() + " for source template " + template.getId() + ". Copy all Datadisk templates to destination datastore " + dstSecStore.getName());
-                        TemplateInfo srcDataDiskTemplate = _tmplFactory.getTemplate(dataDiskTemplate.getId(), srcSecStore);
-                        AsyncCallFuture<TemplateApiResult> dataDiskCopyFuture = _tmpltSvr.copyTemplate(srcDataDiskTemplate, dstSecStore);
-                        try {
-                            TemplateApiResult dataDiskCopyResult = dataDiskCopyFuture.get();
-                            if (dataDiskCopyResult.isFailed()) {
-                                s_logger.error("Copy of datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName()
-                                        + " failed with error: " + dataDiskCopyResult.getResult() + " , will try copying the next one");
-                                continue; // Continue to copy next Datadisk template
-                            }
-                            _tmpltDao.addTemplateToZone(dataDiskTemplate, dstZoneId);
-                            _resourceLimitMgr.incrementResourceCount(dataDiskTemplate.getAccountId(), ResourceType.secondary_storage, dataDiskTemplate.getSize());
-                        } catch (Exception ex) {
-                            s_logger.error("Failed to copy datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName()
-                                    + " , will try copying the next one");
-                        }
-                    }
-                }
-            } catch (Exception ex) {
-                s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one");
-            }
-        }
-        return true;
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
-    public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
-        Long templateId = cmd.getId();
-        Long userId = CallContext.current().getCallingUserId();
-        Long sourceZoneId = cmd.getSourceZoneId();
-        List<Long> destZoneIds = cmd.getDestinationZoneIds();
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Verify parameters
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null || template.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find template with id");
-        }
-
-        // Verify template is not Datadisk template
-        if (template.getTemplateType().equals(TemplateType.DATADISK)) {
-            throw new InvalidParameterValueException("Template " + template.getId() + " is of type Datadisk. Cannot copy Datadisk templates.");
-        }
-
-        if (sourceZoneId != null) {
-            if (destZoneIds!= null && destZoneIds.contains(sourceZoneId)) {
-                throw new InvalidParameterValueException("Please specify different source and destination zones.");
-            }
-
-            DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
-            if (sourceZone == null) {
-                throw new InvalidParameterValueException("Please specify a valid source zone.");
-            }
-        }
-
-        Map<Long, DataCenterVO> dataCenterVOs = new HashMap();
-
-        for (Long destZoneId: destZoneIds) {
-            DataCenterVO dstZone = _dcDao.findById(destZoneId);
-            if (dstZone == null) {
-                throw new InvalidParameterValueException("Please specify a valid destination zone.");
-            }
-            dataCenterVOs.put(destZoneId, dstZone);
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
-
-        List<String> failedZones = new ArrayList<>();
-
-        boolean success = false;
-        if (template.getHypervisorType() == HypervisorType.BareMetal) {
-            if (template.isCrossZones()) {
-                s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
-                return template;
-            }
-            for (Long destZoneId: destZoneIds) {
-                if (!addTemplateToZone(template, destZoneId, sourceZoneId)) {
-                    failedZones.add(dataCenterVOs.get(destZoneId).getName());
-                }
-            }
-        } else {
-            DataStore srcSecStore = null;
-            if (sourceZoneId != null) {
-                // template is on zone-wide secondary storage
-                srcSecStore = getImageStore(sourceZoneId, templateId);
-            } else {
-                // template is on region store
-                srcSecStore = getImageStore(templateId);
-            }
-
-            if (srcSecStore == null) {
-                throw new InvalidParameterValueException("There is no template " + templateId + " ready on image store.");
-            }
-
-            if (template.isCrossZones()) {
-                // sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
-                _tmpltSvr.syncTemplateToRegionStore(templateId, srcSecStore);
-                s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
-                return template;
-            }
-            for (Long destZoneId : destZoneIds) {
-                DataStore dstSecStore = getImageStore(destZoneId, templateId);
-                if (dstSecStore != null) {
-                    s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() +
-                            " in zone " + destZoneId + " , don't need to copy");
-                    continue;
-                }
-                if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
-                    failedZones.add(dataCenterVOs.get(destZoneId).getName());
-                }
-                else{
-                    if (template.getSize() != null) {
-                        // increase resource count
-                        long accountId = template.getAccountId();
-                        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize());
-                    }
-                }
-            }
-
-
-        }
-
-        if ((destZoneIds != null) && (destZoneIds.size() > failedZones.size())){
-            if (!failedZones.isEmpty()) {
-                s_logger.debug("There were failures when copying template to zones: " +
-                        StringUtils.listToCsvTags(failedZones));
-            }
-            return template;
-        } else {
-            throw new CloudRuntimeException("Failed to copy template");
-        }
-    }
-
-    private boolean addTemplateToZone(VMTemplateVO template, long dstZoneId, long sourceZoneid) throws ResourceAllocationException{
-        long tmpltId = template.getId();
-        DataCenterVO dstZone = _dcDao.findById(dstZoneId);
-        DataCenterVO sourceZone = _dcDao.findById(sourceZoneid);
-
-        AccountVO account = _accountDao.findById(template.getAccountId());
-
-
-        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
-
-        try {
-            _tmpltDao.addTemplateToZone(template, dstZoneId);
-            return true;
-        } catch (Exception ex) {
-            s_logger.debug("failed to copy template from Zone: " + sourceZone.getUuid() + " to Zone: " + dstZone.getUuid());
-        }
-        return false;
-    }
-
-    @Override
-    public boolean delete(long userId, long templateId, Long zoneId) {
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null || template.getRemoved() != null) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
-        }
-
-        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
-        return adapter.delete(new TemplateProfile(userId, template, zoneId));
-    }
-
-    @Override
-    public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool) {
-        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = new ArrayList<VMTemplateStoragePoolVO>();
-        List<VMTemplateStoragePoolVO> allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId());
-
-        for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) {
-            VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
-
-            // If this is a routing template, consider it in use
-            if (template.getTemplateType() == TemplateType.SYSTEM) {
-                continue;
-            }
-
-            // If the template is not yet downloaded to the pool, consider it in
-            // use
-            if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) {
-                continue;
-            }
-
-            if (template.getFormat() != ImageFormat.ISO && !_volumeDao.isAnyVolumeActivelyUsingTemplateOnPool(template.getId(), pool.getId())) {
-                unusedTemplatesInPool.add(templatePoolVO);
-            }
-        }
-
-        return unusedTemplatesInPool;
-    }
-
-    @Override
-    @DB
-    public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
-        // Need to hold the lock; otherwise, another thread may create a volume from the template at the same time.
-        // Assumption here is that we will hold the same lock during create volume from template.
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
-
-        if (templatePoolRef == null) {
-            s_logger.debug("Can't aquire the lock for template pool ref: " + templatePoolVO.getId());
-
-            return;
-        }
-
-        PrimaryDataStore pool = (PrimaryDataStore)_dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
-        TemplateInfo template = _tmplFactory.getTemplate(templatePoolRef.getTemplateId(), pool);
-
-        try {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Evicting " + templatePoolVO);
-            }
-
-            if (pool.isManaged()) {
-                // For managed store, just delete the template volume.
-                AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.deleteTemplateOnPrimary(template, pool);
-                TemplateApiResult result = future.get();
-
-                if (result.isFailed()) {
-                    s_logger.debug("Failed to delete template " + template.getId() + " from storage pool " + pool.getId());
-                } else {
-                    // Remove the templatePoolVO.
-                    if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
-                        s_logger.debug("Successfully evicted template " + template.getName() + " from storage pool " + pool.getName());
-                    }
-                }
-            } else {
-                DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
-                Answer answer = _storageMgr.sendToPool(pool, cmd);
-
-                if (answer != null && answer.getResult()) {
-                    // Remove the templatePoolVO.
-                    if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
-                        s_logger.debug("Successfully evicted template " + template.getName() + " from storage pool " + pool.getName());
-                    }
-                } else {
-                    s_logger.info("Will retry evict template " + template.getName() + " from storage pool " + pool.getName());
-                }
-            }
-        } catch (StorageUnavailableException | InterruptedException | ExecutionException e) {
-            s_logger.info("Storage is unavailable currently. Will retry evicte template " + template.getName() + " from storage pool " + pool.getName());
-        } finally {
-            _tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
-        }
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-
-        String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString());
-        _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction);
-
-        _preloadExecutor = Executors.newFixedThreadPool(TemplatePreloaderPoolSize.value(), new NamedThreadFactory("Template-Preloader"));
-
-        return true;
-    }
-
-    protected TemplateManagerImpl() {
-    }
-
-    @Override
-    public boolean templateIsDeleteable(VMTemplateHostVO templateHostRef) {
-        VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateHostRef.getTemplateId());
-        long templateId = template.getId();
-        HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
-        long zoneId = secondaryStorageHost.getDataCenterId();
-        DataCenterVO zone = _dcDao.findById(zoneId);
-
-        // Check if there are VMs running in the template host ref's zone that
-        // use the template
-        List<VMInstanceVO> nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId);
-
-        if (!nonExpungedVms.isEmpty()) {
-            s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() +
-                    " is not deleteable because there are non-expunged VMs deployed from this template.");
-            return false;
-        }
-        List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
-        // check if there is any VM using this ISO.
-        if (!userVmUsingIso.isEmpty()) {
-            s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
-            return false;
-        }
-        // Check if there are any snapshots for the template in the template
-        // host ref's zone
-        List<VolumeVO> volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId);
-        for (VolumeVO volume : volumes) {
-            List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1");
-            if (!snapshots.isEmpty()) {
-                s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() +
-                        " is not deleteable because there are 2.1 snapshots using this template.");
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean templateIsDeleteable(long templateId) {
-        List<UserVmJoinVO> userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId);
-        // check if there is any Vm using this ISO. We only need to check the
-        // case where templateId is an ISO since
-        // VM can be launched from ISO in secondary storage, while template will
-        // always be copied to
-        // primary storage before deploying VM.
-        if (!userVmUsingIso.isEmpty()) {
-            s_logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true)
-    public boolean detachIso(long vmId) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long userId = CallContext.current().getCallingUserId();
-
-        // Verify input parameters
-        UserVmVO vmInstanceCheck = _userVmDao.findById(vmId);
-        if (vmInstanceCheck == null) {
-            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
-        }
-
-        UserVm userVM = _userVmDao.findById(vmId);
-        if (userVM == null) {
-            throw new InvalidParameterValueException("Please specify a valid VM.");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, userVM);
-
-        Long isoId = userVM.getIsoId();
-        if (isoId == null) {
-            throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
-        }
-        CallContext.current().setEventDetails("Vm Id: " + vmId + " ISO Id: " + isoId);
-
-        State vmState = userVM.getState();
-        if (vmState != State.Running && vmState != State.Stopped) {
-            throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
-        }
-
-        boolean result = attachISOToVM(vmId, userId, isoId, false); // attach=false
-        // => detach
-        if (result) {
-            return result;
-        } else {
-            throw new CloudRuntimeException("Failed to detach iso");
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true)
-    public boolean attachIso(long isoId, long vmId) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long userId = CallContext.current().getCallingUserId();
-
-        // Verify input parameters
-        UserVmVO vm = _userVmDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
-        }
-
-        VMTemplateVO iso = _tmpltDao.findById(isoId);
-        if (iso == null || iso.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId);
-        }
-
-        // check permissions
-        // check if caller has access to VM and ISO
-        // and also check if the VM's owner has access to the ISO.
-
-        _accountMgr.checkAccess(caller, null, false, iso, vm);
-
-        Account vmOwner = _accountDao.findById(vm.getAccountId());
-        _accountMgr.checkAccess(vmOwner, null, false, iso, vm);
-
-        State vmState = vm.getState();
-        if (vmState != State.Running && vmState != State.Stopped) {
-            throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
-        }
-
-        if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer) {
-            throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType());
-        }
-
-        if ("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
-            throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType());
-        }
-        boolean result = attachISOToVM(vmId, userId, isoId, true);
-        if (result) {
-            return result;
-        } else {
-            throw new CloudRuntimeException("Failed to attach iso");
-        }
-    }
-
-    // for ISO, we need to consider whether to copy to cache storage or not if it is not on NFS, since our hypervisor resource always assumes that they are in NFS
-    @Override
-    public TemplateInfo prepareIso(long isoId, long dcId, Long hostId, Long poolId) {
-        TemplateInfo tmplt;
-        boolean bypassed = false;
-        if (_tmplFactory.isTemplateMarkedForDirectDownload(isoId)) {
-            tmplt = _tmplFactory.getReadyBypassedTemplateOnPrimaryStore(isoId, poolId, hostId);
-            bypassed = true;
-        } else {
-            tmplt = _tmplFactory.getTemplate(isoId, DataStoreRole.Image, dcId);
-        }
-
-        if (tmplt == null || tmplt.getFormat() != ImageFormat.ISO) {
-            s_logger.warn("ISO: " + isoId + " does not exist in vm_template table");
-            return null;
-        }
-
-        if (!bypassed && tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) {
-            // if it is s3, need to download into cache storage first
-            Scope destScope = new ZoneScope(dcId);
-            TemplateInfo cacheData = (TemplateInfo)cacheMgr.createCacheObject(tmplt, destScope);
-            if (cacheData == null) {
-                s_logger.error("Failed in copy iso from S3 to cache storage");
-                return null;
-            }
-            return cacheData;
-        } else {
-            return tmplt;
-        }
-    }
-
-    private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
-        UserVmVO vm = _userVmDao.findById(vmId);
-
-        if (vm == null) {
-            return false;
-        } else if (vm.getState() != State.Running) {
-            return true;
-        }
-
-        // prepare ISO ready to mount on hypervisor resource level
-        TemplateInfo tmplt = prepareIso(isoId, vm.getDataCenterId(), vm.getHostId(), null);
-
-        String vmName = vm.getInstanceName();
-
-        HostVO host = _hostDao.findById(vm.getHostId());
-        if (host == null) {
-            s_logger.warn("Host: " + vm.getHostId() + " does not exist");
-            return false;
-        }
-
-        DataTO isoTO = tmplt.getTO();
-        DiskTO disk = new DiskTO(isoTO, null, null, Volume.Type.ISO);
-        Command cmd = null;
-        if (attach) {
-            cmd = new AttachCommand(disk, vmName);
-        } else {
-            cmd = new DettachCommand(disk, vmName);
-        }
-        Answer a = _agentMgr.easySend(vm.getHostId(), cmd);
-        return (a != null && a.getResult());
-    }
-
-    private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) {
-        UserVmVO vm = _userVmDao.findById(vmId);
-        VMTemplateVO iso = _tmpltDao.findById(isoId);
-
-        boolean success = attachISOToVM(vmId, isoId, attach);
-        if (success && attach) {
-            vm.setIsoId(iso.getId());
-            _userVmDao.update(vmId, vm);
-        }
-        if (success && !attach) {
-            vm.setIsoId(null);
-            _userVmDao.update(vmId, vm);
-        }
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
-    public boolean deleteTemplate(DeleteTemplateCmd cmd) {
-        Long templateId = cmd.getId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find template with id " + templateId);
-        }
-
-        List<VMInstanceVO> vmInstanceVOList;
-        if(cmd.getZoneId() != null) {
-            vmInstanceVOList = _vmInstanceDao.listNonExpungedByZoneAndTemplate(cmd.getZoneId(), templateId);
-        }
-        else {
-            vmInstanceVOList = _vmInstanceDao.listNonExpungedByTemplate(templateId);
-        }
-        if(!cmd.isForced() && CollectionUtils.isNotEmpty(vmInstanceVOList)) {
-            final String message = String.format("Unable to delete template with id: %1$s because VM instances: [%2$s] are using it.",  templateId, Joiner.on(",").join(vmInstanceVOList));
-            s_logger.warn(message);
-            throw new InvalidParameterValueException(message);
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
-
-        if (template.getFormat() == ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid template.");
-        }
-
-        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
-        TemplateProfile profile = adapter.prepareDelete(cmd);
-        return adapter.delete(profile);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
-    public boolean deleteIso(DeleteIsoCmd cmd) {
-        Long templateId = cmd.getId();
-        Account caller = CallContext.current().getCallingAccount();
-        Long zoneId = cmd.getZoneId();
-
-        VMTemplateVO template = _tmpltDao.findById(templateId);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
-        }
-
-        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
-
-        if (template.getFormat() != ImageFormat.ISO) {
-            throw new InvalidParameterValueException("Please specify a valid iso.");
-        }
-
-        // check if there is any VM using this ISO.
-        if (!templateIsDeleteable(templateId)) {
-            throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms");
-        }
-
-        if (zoneId != null && (_dataStoreMgr.getImageStore(zoneId) == null)) {
-            throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone.");
-        }
-
-        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
-        TemplateProfile profile = adapter.prepareDelete(cmd);
-        boolean result = adapter.delete(profile);
-        if (result) {
-            return true;
-        } else {
-            throw new CloudRuntimeException("Failed to delete ISO");
-        }
-    }
-
-    @Override
-    public List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long id = cmd.getId();
-
-        if (id.equals(Long.valueOf(1))) {
-            throw new PermissionDeniedException("unable to list permissions for " + cmd.getMediaType() + " with id " + id);
-        }
-
-        VirtualMachineTemplate template = _tmpltDao.findById(id);
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id);
-        }
-
-        if (cmd instanceof ListTemplatePermissionsCmd) {
-            if (template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid template");
-            }
-        } else if (cmd instanceof ListIsoPermissionsCmd) {
-            if (!template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid iso");
-            }
-        }
-
-        if (!template.isPublicTemplate()) {
-            _accountMgr.checkAccess(caller, null, true, template);
-        }
-
-        List<String> accountNames = new ArrayList<String>();
-        List<LaunchPermissionVO> permissions = _launchPermissionDao.findByTemplate(id);
-        if ((permissions != null) && !permissions.isEmpty()) {
-            for (LaunchPermissionVO permission : permissions) {
-                Account acct = _accountDao.findById(permission.getAccountId());
-                accountNames.add(acct.getAccountName());
-            }
-        }
-
-        // also add the owner if not public
-        if (!template.isPublicTemplate()) {
-            Account templateOwner = _accountDao.findById(template.getAccountId());
-            accountNames.add(templateOwner.getAccountName());
-        }
-
-        return accountNames;
-    }
-
-    @DB
-    @Override
-    public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) {
-        // Input validation
-        final Long id = cmd.getId();
-        final Account caller = CallContext.current().getCallingAccount();
-        List<String> accountNames = cmd.getAccountNames();
-        List<Long> projectIds = cmd.getProjectIds();
-        Boolean isFeatured = cmd.isFeatured();
-        Boolean isPublic = cmd.isPublic();
-        Boolean isExtractable = cmd.isExtractable();
-        String operation = cmd.getOperation();
-        String mediaType = "";
-
-        VMTemplateVO template = _tmpltDao.findById(id);
-
-        if (template == null) {
-            throw new InvalidParameterValueException("unable to find " + mediaType + " with id " + id);
-        }
-
-        if (cmd instanceof UpdateTemplatePermissionsCmd) {
-            mediaType = "template";
-            if (template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid template");
-            }
-        }
-        if (cmd instanceof UpdateIsoPermissionsCmd) {
-            mediaType = "iso";
-            if (!template.getFormat().equals(ImageFormat.ISO)) {
-                throw new InvalidParameterValueException("Please provide a valid iso");
-            }
-        }
-
-        // convert projectIds to accountNames
-        if (projectIds != null) {
-            // CS-17842, initialize accountNames list
-            if (accountNames == null) {
-                accountNames = new ArrayList<String>();
-            }
-            for (Long projectId : projectIds) {
-                Project project = _projectMgr.getProject(projectId);
-                if (project == null) {
-                    throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-                }
-
-                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
-                    throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
-                }
-                accountNames.add(_accountMgr.getAccount(project.getProjectAccountId()).getAccountName());
-            }
-        }
-
-        //_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
-        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template); //TODO: should we replace all ModifyEntry as OperateEntry?
-
-        // If the template is removed throw an error.
-        if (template.getRemoved() != null) {
-            s_logger.error("unable to update permissions for " + mediaType + " with id " + id + " as it is removed  ");
-            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id + " as it is removed ");
-        }
-
-        if (id.equals(Long.valueOf(1))) {
-            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id);
-        }
-
-        boolean isAdmin = _accountMgr.isAdmin(caller.getId());
-        // check configuration parameter(allow.public.user.templates) value for
-        // the template owner
-        boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(template.getAccountId());
-        if (!isAdmin && !allowPublicUserTemplates && isPublic != null && isPublic) {
-            throw new InvalidParameterValueException("Only private " + mediaType + "s can be created.");
-        }
-
-        if (accountNames != null) {
-            if ((operation == null) || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) {
-                throw new InvalidParameterValueException(
-                    "Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." + "  Given operation is: '" +
-                        operation + "'");
-            }
-        }
-
-        Long ownerId = template.getAccountId();
-        if (ownerId == null) {
-            // if there is no owner of the template then it's probably already a
-            // public template (or domain private template) so
-            // publishing to individual users is irrelevant
-            throw new InvalidParameterValueException("Update template permissions is an invalid operation on template " + template.getName());
-        }
-
-        //Only admin or owner of the template should be able to change its permissions
-        if (caller.getId() != ownerId && !isAdmin) {
-            throw new InvalidParameterValueException("Unable to grant permission to account " + caller.getAccountName() + " as it is neither admin nor owner or the template");
-        }
-
-        VMTemplateVO updatedTemplate = _tmpltDao.createForUpdate();
-
-        if (isPublic != null) {
-            updatedTemplate.setPublicTemplate(isPublic.booleanValue());
-        }
-
-        if (isFeatured != null) {
-            updatedTemplate.setFeatured(isFeatured.booleanValue());
-        }
-
-        if (isExtractable != null) {
-            // Only Root admins allowed to change it for templates
-            if (!template.getFormat().equals(ImageFormat.ISO) && !_accountMgr.isRootAdmin(caller.getId())) {
-                throw new InvalidParameterValueException("Only ROOT admins are allowed to modify isExtractable attribute.");
-            } else {
-                // For Isos normal user can change it, as their are no derivatives.
-                updatedTemplate.setExtractable(isExtractable.booleanValue());
-            }
-        }
-
-        _tmpltDao.update(template.getId(), updatedTemplate);
-
-        //when operation is add/remove, accountNames can not be null
-        if (("add".equalsIgnoreCase(operation) || "remove".equalsIgnoreCase(operation)) && accountNames == null) {
-            throw new InvalidParameterValueException("Operation " + operation + " requires accounts or projectIds to be passed in");
-        }
-
-        //Derive the domain id from the template owner as updateTemplatePermissions is not cross domain operation
-        Account owner = _accountMgr.getAccount(ownerId);
-        final Domain domain = _domainDao.findById(owner.getDomainId());
-        if ("add".equalsIgnoreCase(operation)) {
-            final List<String> accountNamesFinal = accountNames;
-            final List<Long> accountIds = new ArrayList<Long>();
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    for (String accountName : accountNamesFinal) {
-                        Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId());
-                        if (permittedAccount != null) {
-                            if (permittedAccount.getId() == caller.getId()) {
-                                continue; // don't grant permission to the template
-                                // owner, they implicitly have permission
-                            }
-                            accountIds.add(permittedAccount.getId());
-                            LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId());
-                            if (existingPermission == null) {
-                                LaunchPermissionVO launchPermission = new LaunchPermissionVO(id, permittedAccount.getId());
-                                _launchPermissionDao.persist(launchPermission);
-                            }
-                        } else {
-                            throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + " in domain id=" +
-                                domain.getUuid() + ", account not found.  " + "No permissions updated, please verify the account names and retry.");
-                }
-            }
-                }
-            });
-
-            // add ACL permission in IAM
-            Map<String, Object> permit = new HashMap<String, Object>();
-            permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class);
-            permit.put(ApiConstants.ENTITY_ID, id);
-            permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry);
-            permit.put(ApiConstants.IAM_ACTION, "listTemplates");
-            permit.put(ApiConstants.ACCOUNTS, accountIds);
-            _messageBus.publish(_name, EntityManager.MESSAGE_GRANT_ENTITY_EVENT, PublishScope.LOCAL, permit);
-        } else if ("remove".equalsIgnoreCase(operation)) {
-            List<Long> accountIds = new ArrayList<Long>();
-            for (String accountName : accountNames) {
-                Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId());
-                if (permittedAccount != null) {
-                    accountIds.add(permittedAccount.getId());
-                }
-            }
-            _launchPermissionDao.removePermissions(id, accountIds);
-            // remove ACL permission in IAM
-            Map<String, Object> permit = new HashMap<String, Object>();
-            permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class);
-            permit.put(ApiConstants.ENTITY_ID, id);
-            permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry);
-            permit.put(ApiConstants.IAM_ACTION, "listTemplates");
-            permit.put(ApiConstants.ACCOUNTS, accountIds);
-            _messageBus.publish(_name, EntityManager.MESSAGE_REVOKE_ENTITY_EVENT, PublishScope.LOCAL, permit);
-        } else if ("reset".equalsIgnoreCase(operation)) {
-            // do we care whether the owning account is an admin? if the
-            // owner is an admin, will we still set public to false?
-            updatedTemplate = _tmpltDao.createForUpdate();
-            updatedTemplate.setPublicTemplate(false);
-            updatedTemplate.setFeatured(false);
-            _tmpltDao.update(template.getId(), updatedTemplate);
-            _launchPermissionDao.removeAllPermissions(id);
-            _messageBus.publish(_name, TemplateManager.MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT, PublishScope.LOCAL, template.getId());
-        }
-        return true;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
-    public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException {
-        final long templateId = command.getEntityId();
-        Long volumeId = command.getVolumeId();
-        Long snapshotId = command.getSnapshotId();
-        VMTemplateVO privateTemplate = null;
-        final Long accountId = CallContext.current().getCallingAccountId();
-        SnapshotVO snapshot = null;
-        VolumeVO volume = null;
-
-        try {
-            TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
-            long zoneId = 0;
-            if (snapshotId != null) {
-                snapshot = _snapshotDao.findById(snapshotId);
-                zoneId = snapshot.getDataCenterId();
-            } else if (volumeId != null) {
-                volume = _volumeDao.findById(volumeId);
-                zoneId = volume.getDataCenterId();
-            }
-            DataStore store = _dataStoreMgr.getImageStore(zoneId);
-            if (store == null) {
-                throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
-            }
-            AsyncCallFuture<TemplateApiResult> future = null;
-
-            if (snapshotId != null) {
-                DataStoreRole dataStoreRole = ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
-
-                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) {
-                        store = snapStore; // pick snapshot image store to create template
-                    }
-                }
-
-                future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
-            } else if (volumeId != null) {
-                VolumeInfo volInfo = _volFactory.getVolume(volumeId);
-
-                future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
-            } else {
-                throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
-            }
-
-            CommandResult result = null;
-
-            try {
-                result = future.get();
-
-                if (result.isFailed()) {
-                    privateTemplate = null;
-                    s_logger.debug("Failed to create template" + result.getResult());
-                    throw new CloudRuntimeException("Failed to create template" + result.getResult());
-                }
-
-                // create entries in template_zone_ref table
-                if (_dataStoreMgr.isRegionStore(store)) {
-                    // template created on region store
-                    _tmpltSvr.associateTemplateToZone(templateId, null);
-                } else {
-                    VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
-                    _tmpltZoneDao.persist(templateZone);
-                }
-
-                privateTemplate = _tmpltDao.findById(templateId);
-                TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
-                UsageEventVO usageEvent =
-                        new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId, privateTemplate.getId(), privateTemplate.getName(), null,
-                                privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
-                _usageEventDao.persist(usageEvent);
-            } catch (InterruptedException e) {
-                s_logger.debug("Failed to create template", e);
-                throw new CloudRuntimeException("Failed to create template", e);
-            } catch (ExecutionException e) {
-                s_logger.debug("Failed to create template", e);
-                throw new CloudRuntimeException("Failed to create template", e);
-            }
-
-        } finally {
-            if (privateTemplate == null) {
-                final VolumeVO volumeFinal = volume;
-                final SnapshotVO snapshotFinal = snapshot;
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        // template_store_ref entries should have been removed using our
-                        // DataObject.processEvent command in case of failure, but clean
-                        // it up here to avoid
-                        // some leftovers which will cause removing template from
-                        // vm_template table fail.
-                        _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
-                        // Remove the template_zone_ref record
-                        _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
-                        // Remove the template record
-                        _tmpltDao.expunge(templateId);
-
-                        // decrement resource count
-                        if (accountId != null) {
-                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
-                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize()
-                                    : snapshotFinal.getSize()));
-                        }
-                    }
-                });
-
-            }
-        }
-
-        if (privateTemplate != null) {
-            return privateTemplate;
-        } else {
-            throw new CloudRuntimeException("Failed to create a template");
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true)
-    public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-        boolean isAdmin = (_accountMgr.isAdmin(caller.getId()));
-
-        _accountMgr.checkAccess(caller, null, true, templateOwner);
-
-        String name = cmd.getTemplateName();
-        if ((name == null) || (name.length() > 32)) {
-            throw new InvalidParameterValueException("Template name cannot be null and should be less than 32 characters");
-        }
-
-        if (cmd.getTemplateTag() != null) {
-            if (!_accountService.isRootAdmin(caller.getId())) {
-                throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
-            }
-        }
-
-        // do some parameter defaulting
-        Integer bits = cmd.getBits();
-        Boolean requiresHvm = cmd.getRequiresHvm();
-        Boolean passwordEnabled = cmd.isPasswordEnabled();
-        Boolean isPublic = cmd.isPublic();
-        Boolean featured = cmd.isFeatured();
-        int bitsValue = ((bits == null) ? 64 : bits.intValue());
-        boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm.booleanValue());
-        boolean passwordEnabledValue = ((passwordEnabled == null) ? false : passwordEnabled.booleanValue());
-        if (isPublic == null) {
-            isPublic = Boolean.FALSE;
-        }
-        boolean isDynamicScalingEnabled = cmd.isDynamicallyScalable();
-        // check whether template owner can create public templates
-        boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(templateOwner.getId());
-        if (!isAdmin && !allowPublicUserTemplates && isPublic) {
-            throw new PermissionDeniedException("Failed to create template " + name + ", only private templates can be created.");
-        }
-
-        Long volumeId = cmd.getVolumeId();
-        Long snapshotId = cmd.getSnapshotId();
-        if ((volumeId == null) && (snapshotId == null)) {
-            throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified.");
-        }
-        if ((volumeId != null) && (snapshotId != null)) {
-            throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
-                    ") and snapshot ID (" + snapshotId + ")");
-        }
-
-        HypervisorType hyperType;
-        VolumeVO volume = null;
-        SnapshotVO snapshot = null;
-        VMTemplateVO privateTemplate = null;
-        if (volumeId != null) { // create template from volume
-            volume = _volumeDao.findById(volumeId);
-            if (volume == null) {
-                throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId);
-            }
-            // check permissions
-            _accountMgr.checkAccess(caller, null, true, volume);
-
-            // If private template is created from Volume, check that the volume
-            // will not be active when the private template is
-            // created
-            if (!_volumeMgr.volumeInactive(volume)) {
-                String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first";
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info(msg);
-                }
-                throw new CloudRuntimeException(msg);
-            }
-
-            hyperType = _volumeDao.getHypervisorType(volumeId);
-            if (HypervisorType.LXC.equals(hyperType)) {
-                throw new InvalidParameterValueException("Template creation is not supported for LXC volume: " + volumeId);
-            }
-        } else { // create template from snapshot
-            snapshot = _snapshotDao.findById(snapshotId);
-            if (snapshot == null) {
-                throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
-            }
-            // Volume could be removed so find including removed to record source template id.
-            volume = _volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId());
-
-            // check permissions
-            _accountMgr.checkAccess(caller, null, true, snapshot);
-
-            if (snapshot.getState() != Snapshot.State.BackedUp) {
-                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp +
-                        " state yet and can't be used for template creation");
-            }
-
-            /*
-             * // bug #11428. Operation not supported if vmware and snapshots
-             * parent volume = ROOT if(snapshot.getHypervisorType() ==
-             * HypervisorType.VMware && snapshotVolume.getVolumeType() ==
-             * Type.DATADISK){ throw new UnsupportedServiceException(
-             * "operation not supported, snapshot with id " + snapshotId +
-             * " is created from Data Disk"); }
-             */
-
-            hyperType = snapshot.getHypervisorType();
-        }
-
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
-        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage, new Long(volume != null ? volume.getSize() : snapshot.getSize()).longValue());
-
-        if (!isAdmin || featured == null) {
-            featured = Boolean.FALSE;
-        }
-        Long guestOSId = cmd.getOsTypeId();
-        GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
-        if (guestOS == null) {
-            throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
-        }
-
-        Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id");
-        String description = cmd.getDisplayText();
-        boolean isExtractable = false;
-        Long sourceTemplateId = null;
-        if (volume != null) {
-            VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
-            isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
-            if (volume.getIsoId() != null && volume.getIsoId() != 0) {
-                sourceTemplateId = volume.getIsoId();
-            } else if (volume.getTemplateId() != null) {
-                sourceTemplateId = volume.getTemplateId();
-            }
-        }
-        String templateTag = cmd.getTemplateTag();
-        if (templateTag != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Adding template tag: " + templateTag);
-            }
-        }
-        privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable,
-                TemplateType.USER, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description,
-                passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), false, isDynamicScalingEnabled, false);
-
-        if (sourceTemplateId != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("This template is getting created from other template, setting source template Id to: " + sourceTemplateId);
-            }
-        }
-
-
-        // for region wide storage, set cross zones flag
-        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
-        if (!CollectionUtils.isEmpty(stores)) {
-            privateTemplate.setCrossZones(true);
-        }
-
-        privateTemplate.setSourceTemplateId(sourceTemplateId);
-
-        VMTemplateVO template = _tmpltDao.persist(privateTemplate);
-        // Increment the number of templates
-        if (template != null) {
-            Map<String, String> details = new HashMap<String, String>();
-
-            if (sourceTemplateId != null) {
-                VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId);
-                if (sourceTemplate != null && sourceTemplate.getDetails() != null) {
-                    details.putAll(sourceTemplate.getDetails());
-                }
-            }
-
-            if (volume != null) {
-                Long vmId = volume.getInstanceId();
-                if (vmId != null) {
-                    UserVmVO userVm = _userVmDao.findById(vmId);
-                    if (userVm != null) {
-                        _userVmDao.loadDetails(userVm);
-                        details.putAll(userVm.getDetails());
-                    }
-                }
-            }
-            if (cmd.getDetails() != null) {
-                details.remove("Encrypted.Password"); // new password will be generated during vm deployment from password enabled template
-                details.putAll(cmd.getDetails());
-            }
-            if (!details.isEmpty()) {
-                privateTemplate.setDetails(details);
-                _tmpltDao.saveDetails(privateTemplate);
-            }
-
-            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
-            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage,
-                    new Long(volume != null ? volume.getSize() : snapshot.getSize()));
-        }
-
-        if (template != null) {
-            return template;
-        } else {
-            throw new CloudRuntimeException("Failed to create a template");
-        }
-
-    }
-
-    @Override
-    public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId) {
-        TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        if (templateStoreRef == null) {
-            throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId);
-        }
-        DataStore store = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
-        String isoPath = store.getUri() + "/" + templateStoreRef.getInstallPath();
-        return new Pair<String, String>(isoPath, store.getUri());
-    }
-
-    @Override
-    public String getSecondaryStorageURL(long zoneId) {
-        DataStore secStore = _dataStoreMgr.getImageStore(zoneId);
-        if (secStore == null) {
-            return null;
-        }
-
-        return secStore.getUri();
-    }
-
-    // get the image store where a template in a given zone is downloaded to,
-    // just pick one is enough.
-    @Override
-    public DataStore getImageStore(long zoneId, long tmpltId) {
-        TemplateDataStoreVO tmpltStore = _tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        if (tmpltStore != null) {
-            return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
-        }
-
-        return null;
-    }
-
-    // get the region wide image store where a template is READY on,
-    // just pick one is enough.
-    @Override
-    public DataStore getImageStore(long tmpltId) {
-        TemplateDataStoreVO tmpltStore = _tmplStoreDao.findReadyByTemplate(tmpltId, DataStoreRole.Image);
-        if (tmpltStore != null) {
-            return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
-        }
-
-        return null;
-    }
-
-    @Override
-    public Long getTemplateSize(long templateId, long zoneId) {
-        if (_tmplStoreDao.isTemplateMarkedForDirectDownload(templateId)) {
-            // check if template is marked for direct download
-            return _tmplStoreDao.getReadyBypassedTemplate(templateId).getSize();
-        }
-        TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-        if (templateStoreRef == null) {
-            // check if it is ready on image cache stores
-            templateStoreRef = _tmplStoreDao.findByTemplateZoneStagingDownloadStatus(templateId, zoneId,
-                    VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-            if (templateStoreRef == null) {
-                throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + zoneId);
-            }
-        }
-        return templateStoreRef.getSize();
-
-    }
-
-    // find image store where this template is located
-    @Override
-    public List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId) {
-        // find all eligible image stores for this zone scope
-        List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
-        if (imageStores == null || imageStores.size() == 0) {
-            return null;
-        }
-        List<DataStore> stores = new ArrayList<DataStore>();
-        for (DataStore store : imageStores) {
-            // check if the template is stored there
-            List<TemplateDataStoreVO> storeTmpl = _tmplStoreDao.listByTemplateStore(templateId, store.getId());
-            if (storeTmpl != null && storeTmpl.size() > 0) {
-                stores.add(store);
-            }
-        }
-        return stores;
-    }
-
-    @Override
-    public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) {
-        return updateTemplateOrIso(cmd);
-    }
-
-    @Override
-    public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) {
-        return updateTemplateOrIso(cmd);
-    }
-
-    private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
-        Long id = cmd.getId();
-        String name = cmd.getTemplateName();
-        String displayText = cmd.getDisplayText();
-        String format = cmd.getFormat();
-        Long guestOSId = cmd.getOsTypeId();
-        Boolean passwordEnabled = cmd.getPasswordEnabled();
-        Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
-        Boolean isRoutingTemplate = cmd.isRoutingType();
-        Boolean bootable = cmd.getBootable();
-        Boolean requiresHvm = cmd.getRequiresHvm();
-        Integer sortKey = cmd.getSortKey();
-        Map details = cmd.getDetails();
-        Account account = CallContext.current().getCallingAccount();
-        boolean cleanupDetails = cmd.isCleanupDetails();
-
-        // verify that template exists
-        VMTemplateVO template = _tmpltDao.findById(id);
-        if (template == null || template.getRemoved() != null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id");
-            ex.addProxyObject(String.valueOf(id), "templateId");
-            throw ex;
-        }
-
-        verifyTemplateId(id);
-
-        // do a permission check
-        _accountMgr.checkAccess(account, AccessType.OperateEntry, true, template);
-        if (cmd.isRoutingType() != null) {
-            if (!_accountService.isRootAdmin(account.getId())) {
-                throw new PermissionDeniedException("Parameter isrouting can only be specified by a Root Admin, permission denied");
-            }
-        }
-
-        // update is needed if any of the fields below got filled by the user
-        boolean updateNeeded =
-                !(name == null &&
-                  displayText == null &&
-                  format == null &&
-                  guestOSId == null &&
-                  passwordEnabled == null &&
-                  bootable == null &&
-                  requiresHvm == null &&
-                  sortKey == null &&
-                  isDynamicallyScalable == null &&
-                  isRoutingTemplate == null &&
-                  (! cleanupDetails && details == null) //update details in every case except this one
-                  );
-        if (!updateNeeded) {
-            return template;
-        }
-
-        template = _tmpltDao.createForUpdate(id);
-
-        if (name != null) {
-            template.setName(name);
-        }
-
-        if (displayText != null) {
-            template.setDisplayText(displayText);
-        }
-
-        if (sortKey != null) {
-            template.setSortKey(sortKey);
-        }
-
-        ImageFormat imageFormat = null;
-        if (format != null) {
-            try {
-                imageFormat = ImageFormat.valueOf(format.toUpperCase());
-            } catch (IllegalArgumentException e) {
-                throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
-            }
-
-            template.setFormat(imageFormat);
-        }
-
-        if (guestOSId != null) {
-            long oldGuestOSId = template.getGuestOSId();
-            GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
-
-            if (guestOS == null) {
-                throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
-            } else {
-                template.setGuestOSId(guestOSId);
-            }
-
-            if (guestOSId != oldGuestOSId) { // vm guest os type need to be updated if template guest os id changes.
-                SearchCriteria<VMInstanceVO> sc = _vmInstanceDao.createSearchCriteria();
-                sc.addAnd("templateId", SearchCriteria.Op.EQ, id);
-                sc.addAnd("state", SearchCriteria.Op.NEQ, State.Expunging);
-                List<VMInstanceVO> vms = _vmInstanceDao.search(sc, null);
-                if (vms != null && !vms.isEmpty()) {
-                    for (VMInstanceVO vm: vms) {
-                        vm.setGuestOSId(guestOSId);
-                        _vmInstanceDao.update(vm.getId(), vm);
-                    }
-                }
-            }
-        }
-
-        if (passwordEnabled != null) {
-            template.setEnablePassword(passwordEnabled);
-        }
-
-        if (bootable != null) {
-            template.setBootable(bootable);
-        }
-
-        if (requiresHvm != null) {
-            template.setRequiresHvm(requiresHvm);
-        }
-
-        if (isDynamicallyScalable != null) {
-            template.setDynamicallyScalable(isDynamicallyScalable);
-        }
-
-        if (isRoutingTemplate != null) {
-            if (isRoutingTemplate) {
-                template.setTemplateType(TemplateType.ROUTING);
-            } else {
-                template.setTemplateType(TemplateType.USER);
-            }
-        }
-
-        if (cleanupDetails) {
-            template.setDetails(null);
-            _tmpltDetailsDao.removeDetails(id);
-        }
-        else if (details != null && !details.isEmpty()) {
-            template.setDetails(details);
-            _tmpltDao.saveDetails(template);
-        }
-
-        _tmpltDao.update(id, template);
-
-        return _tmpltDao.findById(id);
-    }
-
-    void verifyTemplateId(Long id) {
-        // Don't allow to modify system template
-        if (id.equals(Long.valueOf(1))) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id");
-            ex.addProxyObject(String.valueOf(id), "templateId");
-            throw ex;
-        }
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return TemplateManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize};
-    }
-
-    public List<TemplateAdapter> getTemplateAdapters() {
-        return _adapters;
-    }
-
-    @Inject
-    public void setTemplateAdapters(List<TemplateAdapter> adapters) {
-        _adapters = adapters;
-    }
-}
diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java
deleted file mode 100644
index c55178f..0000000
--- a/server/src/com/cloud/test/PodZoneConfig.java
+++ /dev/null
@@ -1,570 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.test;
-
-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.Vector;
-
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.net.NetUtils;
-
-public class PodZoneConfig {
-
-    public static void main(String[] args) {
-        PodZoneConfig config = ComponentContext.inject(PodZoneConfig.class);
-        //config.run(args);
-        System.exit(0);
-    }
-
-    public void savePod(boolean printOutput, long id, String name, long dcId, String gateway, String cidr, int vlanStart, int vlanEnd) {
-        // Check that the cidr was valid
-        if (!IPRangeConfig.validCIDR(cidr))
-            printError("Please enter a valid CIDR for pod: " + name);
-
-        // Get the individual cidrAddress and cidrSize values
-        String[] cidrPair = cidr.split("\\/");
-        String cidrAddress = cidrPair[0];
-        String cidrSize = cidrPair[1];
-
-        String sql = null;
-        if (id != -1)
-            sql =
-                "INSERT INTO `cloud`.`host_pod_ref` (id, name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + id + "','" + name + "','" + dcId +
-                    "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')";
-        else
-            sql =
-                "INSERT INTO `cloud`.`host_pod_ref` (name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + name + "','" + dcId + "','" + gateway +
-                    "','" + cidrAddress + "','" + cidrSize + "')";
-
-        DatabaseConfig.saveSQL(sql, "Failed to save pod due to exception. Please contact Cloud Support.");
-
-        if (printOutput)
-            System.out.println("Successfuly saved pod.");
-    }
-
-    public void checkAllPodCidrSubnets() {
-        Vector<Long> allZoneIDs = getAllZoneIDs();
-        for (Long dcId : allZoneIDs) {
-            HashMap<Long, Vector<Object>> currentPodCidrSubnets = getCurrentPodCidrSubnets(dcId.longValue());
-            String result = checkPodCidrSubnets(dcId.longValue(), currentPodCidrSubnets);
-            if (!result.equals("success"))
-                printError(result);
-        }
-    }
-
-    private String checkPodCidrSubnets(long dcId, HashMap<Long, Vector<Object>> currentPodCidrSubnets) {
-
-//        DataCenterDao _dcDao = null;
-//        final ComponentLocator locator = ComponentLocator.getLocator("management-server");
-
-//        _dcDao = locator.getDao(DataCenterDao.class);
-        // For each pod, return an error if any of the following is true:
-        // 1. The pod's CIDR subnet conflicts with the guest network subnet
-        // 2. The pod's CIDR subnet conflicts with the CIDR subnet of any other pod
-
-        String zoneName = PodZoneConfig.getZoneName(dcId);
-
-        //get the guest network cidr and guest netmask from the zone
-//        DataCenterVO dcVo = _dcDao.findById(dcId);
-
-        String guestNetworkCidr = IPRangeConfig.getGuestNetworkCidr(dcId);
-
-        if (guestNetworkCidr == null || guestNetworkCidr.isEmpty())
-            return "Please specify a valid guest cidr";
-        String[] cidrTuple = guestNetworkCidr.split("\\/");
-
-        String guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]));
-        long guestCidrSize = Long.parseLong(cidrTuple[1]);
-
-        // Iterate through all pods in this zone
-        for (Long podId : currentPodCidrSubnets.keySet()) {
-            String podName;
-            if (podId.longValue() == -1)
-                podName = "newPod";
-            else
-                podName = PodZoneConfig.getPodName(podId.longValue(), dcId);
-
-            Vector<Object> cidrPair = currentPodCidrSubnets.get(podId);
-            String cidrAddress = (String)cidrPair.get(0);
-            long cidrSize = ((Long)cidrPair.get(1)).longValue();
-
-            long cidrSizeToUse = -1;
-            if (cidrSize < guestCidrSize)
-                cidrSizeToUse = cidrSize;
-            else
-                cidrSizeToUse = guestCidrSize;
-
-            String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
-            String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse);
-
-            // Check that cidrSubnet does not equal guestSubnet
-            if (cidrSubnet.equals(guestSubnet)) {
-                if (podName.equals("newPod")) {
-                    return "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR.";
-                } else {
-                    return "Warning: The subnet of pod " + podName + " in zone " + zoneName +
-                        " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management.";
-                }
-            }
-
-            // Iterate through the rest of the pods
-            for (Long otherPodId : currentPodCidrSubnets.keySet()) {
-                if (podId.equals(otherPodId))
-                    continue;
-
-                // Check that cidrSubnet does not equal otherCidrSubnet
-                Vector<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId);
-                String otherCidrAddress = (String)otherCidrPair.get(0);
-                long otherCidrSize = ((Long)otherCidrPair.get(1)).longValue();
-
-                if (cidrSize < otherCidrSize)
-                    cidrSizeToUse = cidrSize;
-                else
-                    cidrSizeToUse = otherCidrSize;
-
-                cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
-                String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse);
-
-                if (cidrSubnet.equals(otherCidrSubnet)) {
-                    String otherPodName = PodZoneConfig.getPodName(otherPodId.longValue(), dcId);
-                    if (podName.equals("newPod")) {
-                        return "The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName +
-                            ". Please specify a different CIDR.";
-                    } else {
-                        return "Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName +
-                            " have conflicting CIDR subnets. Please change the CIDR of one of these pods.";
-                    }
-                }
-            }
-        }
-
-        return "success";
-    }
-
-    @DB
-    protected HashMap<Long, Vector<Object>> getCurrentPodCidrSubnets(long dcId) {
-        HashMap<Long, Vector<Object>> currentPodCidrSubnets = new HashMap<Long, Vector<Object>>();
-
-        String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + dcId;
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
-            ResultSet rs = stmt.executeQuery();
-            while (rs.next()) {
-                Long podId = rs.getLong("id");
-                String cidrAddress = rs.getString("cidr_address");
-                long cidrSize = rs.getLong("cidr_size");
-                Vector<Object> cidrPair = new Vector<Object>();
-                cidrPair.add(0, cidrAddress);
-                cidrPair.add(1, new Long(cidrSize));
-                currentPodCidrSubnets.put(podId, cidrPair);
-            }
-        } catch (SQLException ex) {
-            System.out.println(ex.getMessage());
-            printError("There was an issue with reading currently saved pod CIDR subnets. Please contact Cloud Support.");
-            return null;
-        }
-
-        return currentPodCidrSubnets;
-    }
-
-    public void deletePod(String name, long dcId) {
-        String sql = "DELETE FROM `cloud`.`host_pod_ref` WHERE name=\"" + name + "\" AND data_center_id=\"" + dcId + "\"";
-        DatabaseConfig.saveSQL(sql, "Failed to delete pod due to exception. Please contact Cloud Support.");
-    }
-
-    public long getVlanDbId(String zone, String vlanId) {
-        long zoneId = getZoneId(zone);
-
-        return DatabaseConfig.getDatabaseValueLong("SELECT * FROM `cloud`.`vlan` WHERE data_center_id=\"" + zoneId + "\" AND vlan_id =\"" + vlanId + "\"", "id",
-            "Unable to start DB connection to read vlan DB id. Please contact Cloud Support.");
-    }
-
-    public List<String> modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange,
-        long networkId, long physicalNetworkId) {
-        // Check if the zone is valid
-        long zoneId = getZoneId(zone);
-        if (zoneId == -1)
-            return genReturnList("false", "Please specify a valid zone.");
-
-        //check if physical network is valid
-        long physicalNetworkDbId = checkPhysicalNetwork(physicalNetworkId);
-        if (physicalNetworkId == -1)
-            return genReturnList("false", "Please specify a valid physical network.");
-
-        Long podId = pod != null ? getPodId(pod, zone) : null;
-        if (podId != null && podId == -1)
-            return genReturnList("false", "Please specify a valid pod.");
-
-        if (add) {
-
-            // Make sure the gateway is valid
-            if (!NetUtils.isValidIp4(vlanGateway))
-                return genReturnList("false", "Please specify a valid gateway.");
-
-            // Make sure the netmask is valid
-            if (!NetUtils.isValidIp4(vlanNetmask))
-                return genReturnList("false", "Please specify a valid netmask.");
-
-            // Check if a vlan with the same vlanId already exists in the specified zone
-            if (getVlanDbId(zone, vlanId) != -1)
-                return genReturnList("false", "A VLAN with the specified VLAN ID already exists in zone " + zone + ".");
-
-            /*
-            // Check if another vlan in the same zone has the same subnet
-            String newVlanSubnet = NetUtils.getSubNet(vlanGateway, vlanNetmask);
-            List<VlanVO> vlans = _vlanDao.findByZone(zoneId);
-            for (VlanVO vlan : vlans) {
-                String currentVlanSubnet = NetUtils.getSubNet(vlan.getVlanGateway(), vlan.getVlanNetmask());
-                if (newVlanSubnet.equals(currentVlanSubnet))
-                    return genReturnList("false", "The VLAN with ID " + vlan.getVlanId() + " in zone " + zone + " has the same subnet. Please specify a different gateway/netmask.");
-            }
-             */
-
-            // Everything was fine, so persist the VLAN
-            saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange, networkId, physicalNetworkDbId);
-            if (podId != null) {
-                long vlanDbId = getVlanDbId(zone, vlanId);
-                String sql = "INSERT INTO `cloud`.`pod_vlan_map` (pod_id, vlan_db_id) " + "VALUES (?,?)";
-                String errorMsg =  "Failed to save pod_vlan_map due to exception vlanDbId=" + vlanDbId + ", podId=" + podId + ". Please contact Cloud Support.";
-                TransactionLegacy txn = TransactionLegacy.open("saveSQL");
-                try ( PreparedStatement stmt = txn.prepareAutoCloseStatement(sql); ) {
-                        stmt.setString(1, podId.toString());
-                        stmt.setString(2, String.valueOf(vlanDbId));
-                        stmt.executeUpdate();
-                    } catch (SQLException ex) {
-                        System.out.println("SQL Exception: " + ex.getMessage());
-                        printError(errorMsg);
-                    }
-            }
-
-            return genReturnList("true", "Successfully added VLAN.");
-
-        } else {
-            return genReturnList("false", "That operation is not suppored.");
-        }
-
-        /*
-        else {
-
-            // Check if a VLAN actually exists in the specified zone
-            long vlanDbId = getVlanDbId(zone, vlanId);
-            if (vlanDbId == -1)
-                return genReturnList("false", "A VLAN with ID " + vlanId + " does not exist in zone " + zone);
-
-            // Check if there are any public IPs that are in the specified vlan.
-            List<IPAddressVO> ips = _publicIpAddressDao.listByVlanDbId(vlanDbId);
-            if (ips.size() != 0)
-                return genReturnList("false", "Please delete all IP addresses that are in VLAN " + vlanId + " before deleting the VLAN.");
-
-            // Delete the vlan
-            _vlanDao.delete(vlanDbId);
-
-            return genReturnList("true", "Successfully deleted VLAN.");
-        }
-         */
-    }
-
-    @DB
-    public void saveZone(boolean printOutput, long id, String name, String dns1, String dns2, String dns3, String dns4, String guestNetworkCidr, String networkType) {
-
-        if (printOutput)
-            System.out.println("Saving zone, please wait...");
-
-        String columns = null;
-        String values = null;
-
-        if (id != -1) {
-            columns = "(id, name";
-            values = "('" + id + "','" + name + "'";
-        } else {
-            columns = "(name";
-            values = "('" + name + "'";
-        }
-
-        if (dns1 != null) {
-            columns += ", dns1";
-            values += ",'" + dns1 + "'";
-        }
-
-        if (dns2 != null) {
-            columns += ", dns2";
-            values += ",'" + dns2 + "'";
-        }
-
-        if (dns3 != null) {
-            columns += ", internal_dns1";
-            values += ",'" + dns3 + "'";
-        }
-
-        if (dns4 != null) {
-            columns += ", internal_dns2";
-            values += ",'" + dns4 + "'";
-        }
-
-        if (guestNetworkCidr != null) {
-            columns += ", guest_network_cidr";
-            values += ",'" + guestNetworkCidr + "'";
-        }
-
-        if (networkType != null) {
-            columns += ", networktype";
-            values += ",'" + networkType + "'";
-        }
-
-        columns += ", uuid";
-        values += ", UUID()";
-
-        columns += ")";
-        values += ")";
-
-        String sql = "INSERT INTO `cloud`.`data_center` " + columns + " VALUES " + values;
-
-        DatabaseConfig.saveSQL(sql, "Failed to save zone due to exception. Please contact Cloud Support.");
-
-        if (printOutput)
-            System.out.println("Successfully saved zone.");
-    }
-
-    @DB
-    public void savePhysicalNetwork(boolean printOutput, long id, long dcId, int vnetStart, int vnetEnd) {
-
-        if (printOutput)
-            System.out.println("Saving physical network, please wait...");
-
-        String columns = null;
-        String values = null;
-
-        columns = "(id ";
-        values = "('" + id + "'";
-
-        columns += ", name ";
-        values += ",'physical network'";
-
-        columns += ", data_center_id ";
-        values += ",'" + dcId + "'";
-
-        //save vnet information
-        columns += ", vnet";
-        values += ",'" + vnetStart + "-" + vnetEnd + "'";
-
-        columns += ", state";
-        values += ", 'Enabled'";
-
-        columns += ", uuid";
-        values += ", UUID()";
-
-        columns += ")";
-        values += ")";
-
-        String sql = "INSERT INTO `cloud`.`physical_network` " + columns + " VALUES " + values;
-
-        DatabaseConfig.saveSQL(sql, "Failed to save physical network due to exception. Please contact Cloud Support.");
-
-        // Hardcode the vnet range to be the full range
-        int begin = 0x64;
-        int end = 64000;
-
-        // If vnet arguments were passed in, use them
-        if (vnetStart != -1 && vnetEnd != -1) {
-            begin = vnetStart;
-            end = vnetEnd;
-        }
-
-        String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_id) VALUES ( ?, ?, ?)";
-
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet);
-            for (int i = begin; i <= end; i++) {
-                stmt.setString(1, Integer.toString(i));
-                stmt.setLong(2, dcId);
-                stmt.setLong(3, id);
-                stmt.addBatch();
-            }
-            stmt.executeBatch();
-        } catch (SQLException ex) {
-            printError("Error creating vnet for the physical network. Please contact Cloud Support.");
-        }
-
-        //add default traffic types
-
-        //get default Xen network labels
-        String defaultXenPrivateNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Management);
-        String defaultXenPublicNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Public);
-        String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage);
-        String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest);
-
-        String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` " + "(physical_network_id, traffic_type, xenserver_network_label) VALUES ( ?, ?, ?)";
-
-        try {
-            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType);
-            for (TrafficType traffic : TrafficType.values()) {
-                if (traffic.equals(TrafficType.Control) || traffic.equals(TrafficType.Vpn) || traffic.equals(TrafficType.None)) {
-                    continue;
-                }
-                stmt.setLong(1, id);
-                stmt.setString(2, traffic.toString());
-                if (traffic.equals(TrafficType.Public)) {
-                    stmt.setString(3, defaultXenPublicNetworkLabel);
-                } else if (traffic.equals(TrafficType.Management)) {
-                    stmt.setString(3, defaultXenPrivateNetworkLabel);
-                } else if (traffic.equals(TrafficType.Storage)) {
-                    stmt.setString(3, defaultXenStorageNetworkLabel);
-                } else if (traffic.equals(TrafficType.Guest)) {
-                    stmt.setString(3, defaultXenGuestNetworkLabel);
-                }
-
-                stmt.addBatch();
-            }
-            stmt.executeBatch();
-        } catch (SQLException ex) {
-            printError("Error adding default traffic types for the physical network. Please contact Cloud Support.");
-        }
-
-        if (printOutput)
-            System.out.println("Successfully saved physical network.");
-    }
-
-    private String getDefaultXenNetworkLabel(TrafficType trafficType) {
-        String xenLabel = null;
-        String configName = null;
-        switch (trafficType) {
-            case Public:
-                configName = "xenserver.public.network.device";
-                break;
-            case Guest:
-                configName = "xenserver.guest.network.device";
-                break;
-            case Storage:
-                configName = "xenserver.storage.network.device1";
-                break;
-            case Management:
-                configName = "xenserver.private.network.device";
-                break;
-        }
-
-        if (configName != null) {
-            xenLabel = getConfiguredValue(configName);
-        }
-        return xenLabel;
-    }
-
-    public static String getConfiguredValue(String configName) {
-        return DatabaseConfig.getDatabaseValueString("SELECT value FROM `cloud`.`configuration` where name = \"" + configName + "\"", "value",
-            "Unable to start DB connection to read configuration. Please contact Cloud Support.");
-    }
-
-    public void deleteZone(String name) {
-        String sql = "DELETE FROM `cloud`.`data_center` WHERE name=\"" + name + "\"";
-        DatabaseConfig.saveSQL(sql, "Failed to delete zone due to exception. Please contact Cloud Support.");
-    }
-
-    public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange, long networkId,
-        long physicalNetworkId) {
-        String sql =
-            "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description, network_id, physical_network_id) " + "VALUES ('" +
-                vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange + "','" + networkId + "','" + physicalNetworkId +
-                "')";
-        DatabaseConfig.saveSQL(sql, "Failed to save vlan due to exception. Please contact Cloud Support.");
-    }
-
-    public static long getPodId(String pod, String zone) {
-        long dcId = getZoneId(zone);
-        String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
-        String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
-        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
-    }
-
-    public static long getPodId(String pod, long dcId) {
-        String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
-        String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
-        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
-    }
-
-    public static long getZoneId(String zone) {
-        String selectSql = "SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\"";
-        String errorMsg = "Could not read zone ID from database. Please contact Cloud Support.";
-        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
-    }
-
-    public static long checkPhysicalNetwork(long physicalNetworkId) {
-        String selectSql = "SELECT * FROM `cloud`.`physical_network` WHERE id = \"" + physicalNetworkId + "\"";
-        String errorMsg = "Could not read physicalNetwork ID from database. Please contact Cloud Support.";
-        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
-    }
-
-    @DB
-    public Vector<Long> getAllZoneIDs() {
-        Vector<Long> allZoneIDs = new Vector<Long>();
-
-        String selectSql = "SELECT id FROM data_center";
-        TransactionLegacy txn = TransactionLegacy.currentTxn();
-        try {
-            PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
-            ResultSet rs = stmt.executeQuery();
-            while (rs.next()) {
-                Long dcId = rs.getLong("id");
-                allZoneIDs.add(dcId);
-            }
-        } catch (SQLException ex) {
-            System.out.println(ex.getMessage());
-            printError("There was an issue with reading zone IDs. Please contact Cloud Support.");
-            return null;
-        }
-
-        return allZoneIDs;
-    }
-
-    public static boolean validPod(String pod, String zone) {
-        return (getPodId(pod, zone) != -1);
-    }
-
-    public static boolean validZone(String zone) {
-        return (getZoneId(zone) != -1);
-    }
-
-    public static String getPodName(long podId, long dcId) {
-        return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`host_pod_ref` WHERE id=" + podId + " AND data_center_id=" + dcId, "name",
-            "Unable to start DB connection to read pod name. Please contact Cloud Support.");
-    }
-
-    public static String getZoneName(long dcId) {
-        return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE id=" + dcId, "name",
-            "Unable to start DB connection to read zone name. Please contact Cloud Support.");
-    }
-
-    private static void printError(String message) {
-        DatabaseConfig.printError(message);
-    }
-
-    private List<String> genReturnList(String success, String message) {
-        List<String> returnList = new ArrayList<String>();
-        returnList.add(0, success);
-        returnList.add(1, message);
-        return returnList;
-    }
-
-}
diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java
deleted file mode 100644
index e708b04..0000000
--- a/server/src/com/cloud/user/AccountManager.java
+++ /dev/null
@@ -1,220 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.util.List;
-import java.util.Map;
-import java.net.InetAddress;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-
-import com.cloud.api.query.vo.ControlledViewEntity;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-
-/**
- * AccountManager includes logic that deals with accounts, domains, and users.
- *
- */
-public interface AccountManager extends AccountService, Configurable{
-    /**
-     * Disables an account by accountId
-     * @param accountId
-     * @return true if disable was successful, false otherwise
-     */
-    boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
-
-    boolean deleteAccount(AccountVO account, long callerUserId, Account caller);
-
-    Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId);
-
-    Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid);
-
-    /**
-     * Logs out a user
-     * @param userId
-     */
-    void logoutUser(long userId);
-
-    /**
-      * Authenticates a user when s/he logs in.
-      *
-      * @param username
-      *            required username for authentication
-      * @param password
-      *            password to use for authentication, can be null for single sign-on case
-      * @param domainId
-      *            id of domain where user with username resides
-      * @param requestParameters
-      *            the request parameters of the login request, which should contain timestamp of when the request signature is
-      *            made, and the signature itself in the single sign-on case
-      * @return a user object, null if the user failed to authenticate
-      */
-    UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters);
-
-    /**
-     * Locate a user by their apiKey
-     *
-     * @param apiKey
-     *            that was created for a particular user
-     * @return the user/account pair if one exact match was found, null otherwise
-     */
-    Pair<User, Account> findUserByApiKey(String apiKey);
-
-    boolean enableAccount(long accountId);
-
-
-    void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId,
-            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
-
-    void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
-            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
-
-    void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc,
-            Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
-
-    void buildACLSearchParameters(Account caller, Long id,
-            String accountName, Long projectId, List<Long> permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll,
-            boolean forProjectInvitation);
-
-    void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc,
-            Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
-
-
-    /**
-     * Deletes a user by userId
-     *
-     * @param accountId
-     *            - id of the account do delete
-     *
-     * @return true if delete was successful, false otherwise
-     */
-    boolean deleteUserAccount(long accountId);
-
-    /**
-     * Updates an account
-     *
-     * @param cmd
-     *            - the parameter containing accountId or account nameand domainId
-     * @return updated account object
-     */
-    Account updateAccount(UpdateAccountCmd cmd);
-
-    /**
-     * Disables an account by accountName and domainId
-     *
-     * @param accountName
-     * @param domainId
-     * @param accountId
-     * @param disabled
-     *            account if success
-     * @return true if disable was successful, false otherwise
-     */
-    Account disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
-
-    /**
-     * Enables an account by accountId
-     *
-     * @param accountName
-     *            - the enableAccount command defining the accountId to be deleted.
-     * @param domainId
-     *            TODO
-     * @param accountId
-     * @return account object
-     */
-    Account enableAccount(String accountName, Long domainId, Long accountId);
-
-    /**
-     * Deletes user by Id
-     * @param deleteUserCmd
-     * @return
-     */
-    boolean deleteUser(DeleteUserCmd deleteUserCmd);
-
-    /**
-     * moves a user to another account within the same domain
-     * @param moveUserCmd
-     * @return true if the user was successfully moved
-     */
-    boolean moveUser(MoveUserCmd moveUserCmd);
-
-    /**
-     * Update a user by userId
-     *
-     * @param cmd
-     * @return UserAccount object
-     */
-    UserAccount updateUser(UpdateUserCmd cmd);
-
-    /**
-     * Disables a user by userId
-     *
-     * @param userId
-     *            - the userId
-     * @return UserAccount object
-     */
-    UserAccount disableUser(long userId);
-
-    /**
-     * Enables a user
-     *
-     * @param userId
-     *            - the userId
-     * @return UserAccount object
-     */
-    UserAccount enableUser(long userId);
-
-    /**
-     * Locks an account by accountId. A locked account cannot access the API, but will still have running VMs/IP
-     * addresses
-     * allocated/etc.
-     *
-     * @param accountName
-     *            - the LockAccount command defining the accountId to be locked.
-     * @param domainId
-     *            TODO
-     * @param accountId
-     * @return account object
-     */
-    Account lockAccount(String accountName, Long domainId, Long accountId);
-
-    List<String> listAclGroupsByAccount(Long accountId);
-
-    public static final String MESSAGE_ADD_ACCOUNT_EVENT = "Message.AddAccount.Event";
-
-    public static final String MESSAGE_REMOVE_ACCOUNT_EVENT = "Message.RemoveAccount.Event";
-    public static final ConfigKey<Boolean> UseSecretKeyInResponse = new ConfigKey<Boolean>(
-            "Advanced",
-            Boolean.class,
-            "use.secret.key.in.response",
-            "false",
-            "This parameter allows the users to enable or disable of showing secret key as a part of response for various APIs. By default it is set to false.",
-            true);
-
-    boolean moveUser(long id, Long domainId, long accountId);
-}
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
deleted file mode 100644
index 9129976..0000000
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ /dev/null
@@ -1,2783 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.net.InetAddress;
-import java.net.URLEncoder;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.QuerySelector;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.PublishScope;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
-import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
-
-import com.cloud.api.ApiDBUtils;
-import com.cloud.api.query.vo.ControlledViewEntity;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceOwnerType;
-import com.cloud.configuration.ResourceCountVO;
-import com.cloud.configuration.ResourceLimit;
-import com.cloud.configuration.dao.ResourceCountDao;
-import com.cloud.configuration.dao.ResourceLimitDao;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterVnetDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.ActionEvents;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.CloudAuthenticationException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.VpnUserVO;
-import com.cloud.network.as.AutoScaleManager;
-import com.cloud.network.dao.AccountGuestVlanMapDao;
-import com.cloud.network.dao.AccountGuestVlanMapVO;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.RemoteAccessVpnVO;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.security.SecurityGroupManager;
-import com.cloud.network.security.dao.SecurityGroupDao;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpn.RemoteAccessVpnService;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.projects.Project;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.projects.ProjectInvitationVO;
-import com.cloud.projects.ProjectManager;
-import com.cloud.projects.ProjectVO;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.projects.dao.ProjectDao;
-import com.cloud.server.auth.UserAuthenticator;
-import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeApiService;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account.State;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.SSHKeyPairDao;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.utils.ConstantTimeComparator;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.InstanceGroupVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.dao.InstanceGroupDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshot;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-
-
-public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager {
-    public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class);
-
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    private ResourceCountDao _resourceCountDao;
-    @Inject
-    private UserDao _userDao;
-    @Inject
-    private InstanceGroupDao _vmGroupDao;
-    @Inject
-    private UserAccountDao _userAccountDao;
-    @Inject
-    private VolumeDao _volumeDao;
-    @Inject
-    private UserVmDao _userVmDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private SecurityGroupDao _securityGroupDao;
-    @Inject
-    private VMInstanceDao _vmDao;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao;
-    @Inject
-    private SecurityGroupManager _networkGroupMgr;
-    @Inject
-    private NetworkOrchestrationService _networkMgr;
-    @Inject
-    private SnapshotManager _snapMgr;
-    @Inject
-    private VMSnapshotManager _vmSnapshotMgr;
-    @Inject
-    private VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    private UserVmManager _vmMgr;
-    @Inject
-    private TemplateManager _tmpltMgr;
-    @Inject
-    private ConfigurationManager _configMgr;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private RemoteAccessVpnDao _remoteAccessVpnDao;
-    @Inject
-    private RemoteAccessVpnService _remoteAccessVpnMgr;
-    @Inject
-    private VpnUserDao _vpnUser;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private DomainManager _domainMgr;
-    @Inject
-    private ProjectManager _projectMgr;
-    @Inject
-    private ProjectDao _projectDao;
-    @Inject
-    private AccountDetailsDao _accountDetailsDao;
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private ProjectAccountDao _projectAccountDao;
-    @Inject
-    private IPAddressDao _ipAddressDao;
-    @Inject
-    private VpcManager _vpcMgr;
-    @Inject
-    Site2SiteVpnManager _vpnMgr;
-    @Inject
-    private AutoScaleManager _autoscaleMgr;
-    @Inject
-    VolumeApiService volumeService;
-    @Inject
-    private AffinityGroupDao _affinityGroupDao;
-    @Inject
-    private AccountGuestVlanMapDao _accountGuestVlanMapDao;
-    @Inject
-    private DataCenterVnetDao _dataCenterVnetDao;
-    @Inject
-    private ResourceLimitService _resourceLimitMgr;
-    @Inject
-    private ResourceLimitDao _resourceLimitDao;
-    @Inject
-    private DedicatedResourceDao _dedicatedDao;
-    @Inject
-    private GlobalLoadBalancerRuleDao _gslbRuleDao;
-    @Inject
-    private SSHKeyPairDao _sshKeyPairDao;
-
-    List<QuerySelector> _querySelectors;
-
-    @Inject
-    MessageBus _messageBus;
-
-    @Inject
-    public com.cloud.region.ha.GlobalLoadBalancingRulesService _gslbService;
-
-    private List<UserAuthenticator> _userAuthenticators;
-    List<UserAuthenticator> _userPasswordEncoders;
-
-    @Inject
-    protected IpAddressManager _ipAddrMgr;
-
-    private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
-
-    int _allowedLoginAttempts;
-
-    UserVO _systemUser;
-    AccountVO _systemAccount;
-
-    List<SecurityChecker> _securityCheckers;
-    int _cleanupInterval;
-
-    public List<UserAuthenticator> getUserAuthenticators() {
-        return _userAuthenticators;
-    }
-
-    public void setUserAuthenticators(List<UserAuthenticator> authenticators) {
-        _userAuthenticators = authenticators;
-    }
-
-    public List<UserAuthenticator> getUserPasswordEncoders() {
-        return _userPasswordEncoders;
-    }
-
-    public void setUserPasswordEncoders(List<UserAuthenticator> encoders) {
-        _userPasswordEncoders = encoders;
-    }
-
-    public List<SecurityChecker> getSecurityCheckers() {
-        return _securityCheckers;
-    }
-
-    public void setSecurityCheckers(List<SecurityChecker> securityCheckers) {
-        _securityCheckers = securityCheckers;
-    }
-
-    public List<QuerySelector> getQuerySelectors() {
-        return _querySelectors;
-    }
-
-    public void setQuerySelectors(List<QuerySelector> querySelectors) {
-        _querySelectors = querySelectors;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
-        if (_systemAccount == null) {
-            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
-        }
-
-        _systemUser = _userDao.findById(User.UID_SYSTEM);
-        if (_systemUser == null) {
-            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration(params);
-
-        String loginAttempts = configs.get(Config.IncorrectLoginAttemptsAllowed.key());
-        _allowedLoginAttempts = NumbersUtil.parseInt(loginAttempts, 5);
-
-        String value = configs.get(Config.AccountCleanupInterval.key());
-        _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
-
-        return true;
-    }
-
-    @Override
-    public UserVO getSystemUser() {
-        if (_systemUser == null) {
-            _systemUser = _userDao.findById(User.UID_SYSTEM);
-        }
-        return _systemUser;
-    }
-
-    @Override
-    public boolean start() {
-        _executor.scheduleAtFixedRate(new AccountCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public AccountVO getSystemAccount() {
-        if (_systemAccount == null) {
-            _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
-        }
-        return _systemAccount;
-    }
-
-    @Override
-    public boolean isAdmin(Long accountId) {
-        if (accountId != null) {
-            AccountVO acct = _accountDao.findById(accountId);
-            if (acct == null) {
-                return false;  //account is deleted or does not exist
-            }
-            if ((isRootAdmin(accountId)) || (isDomainAdmin(accountId)) || (isResourceDomainAdmin(accountId))) {
-                return true;
-            } else if (acct.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) {
-                return true;
-            }
-
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isRootAdmin(Long accountId) {
-        if (accountId != null) {
-            AccountVO acct = _accountDao.findById(accountId);
-            if (acct == null) {
-                return false;  //account is deleted or does not exist
-            }
-            for (SecurityChecker checker : _securityCheckers) {
-                try {
-                    if (checker.checkAccess(acct, null, null, "SystemCapability")) {
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("Root Access granted to " + acct + " by " + checker.getName());
-                        }
-                        return true;
-                    }
-                } catch (PermissionDeniedException ex) {
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isDomainAdmin(Long accountId) {
-        if (accountId != null) {
-            AccountVO acct = _accountDao.findById(accountId);
-            if (acct == null) {
-                return false;  //account is deleted or does not exist
-            }
-            for (SecurityChecker checker : _securityCheckers) {
-                try {
-                    if (checker.checkAccess(acct, null, null, "DomainCapability")) {
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("DomainAdmin Access granted to " + acct + " by " + checker.getName());
-                        }
-                        return true;
-                    }
-                } catch (PermissionDeniedException ex) {
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isNormalUser(long accountId) {
-        AccountVO acct = _accountDao.findById(accountId);
-        if (acct != null && acct.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-            return true;
-        }
-        return false;
-    }
-
-    public boolean isResourceDomainAdmin(Long accountId) {
-        if (accountId != null) {
-            AccountVO acct = _accountDao.findById(accountId);
-            if (acct == null) {
-                return false;  //account is deleted or does not exist
-            }
-            for (SecurityChecker checker : _securityCheckers) {
-                try {
-                    if (checker.checkAccess(acct, null, null, "DomainResourceCapability")) {
-                        if (s_logger.isTraceEnabled()) {
-                            s_logger.trace("ResourceDomainAdmin Access granted to " + acct + " by " + checker.getName());
-                        }
-                        return true;
-                    }
-                } catch (PermissionDeniedException ex) {
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-
-    public boolean isInternalAccount(long accountId) {
-        Account account = _accountDao.findById(accountId);
-        if (account == null) {
-            return false;  //account is deleted or does not exist
-        }
-        if (isRootAdmin(accountId) || (account.getType() == Account.ACCOUNT_ID_SYSTEM)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void checkAccess(Account caller, Domain domain) throws PermissionDeniedException {
-        for (SecurityChecker checker : _securityCheckers) {
-            if (checker.checkAccess(caller, domain)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + caller + " to " + domain + " by " + checker.getName());
-                }
-                return;
-            }
-        }
-
-        assert false : "How can all of the security checkers pass on checking this caller?";
-        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + domain);
-    }
-
-    @Override
-    public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) {
-        checkAccess(caller, accessType, sameOwner, null, entities);
-    }
-
-    @Override
-    public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) {
-
-        //check for the same owner
-        Long ownerId = null;
-        ControlledEntity prevEntity = null;
-        if (sameOwner) {
-            for (ControlledEntity entity : entities) {
-                if (sameOwner) {
-                    if (ownerId == null) {
-                        ownerId = entity.getAccountId();
-                    } else if (ownerId.longValue() != entity.getAccountId()) {
-                        throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts");
-                    }
-                    prevEntity = entity;
-                }
-            }
-        }
-
-        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(caller.getId())) {
-            // no need to make permission checks if the system/root admin makes the call
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("No need to make permission check for System/RootAdmin account, returning true");
-            }
-            return;
-        }
-
-        HashMap<Long, List<ControlledEntity>> domains = new HashMap<Long, List<ControlledEntity>>();
-
-        for (ControlledEntity entity : entities) {
-            long domainId = entity.getDomainId();
-            if (entity.getAccountId() != -1 && domainId == -1) { // If account exists domainId should too so calculate
-                // it. This condition might be hit for templates or entities which miss domainId in their tables
-                Account account = ApiDBUtils.findAccountById(entity.getAccountId());
-                domainId = account != null ? account.getDomainId() : -1;
-            }
-            if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate)
-                    && !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry) && !(entity instanceof AffinityGroup)) {
-                List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
-                // for templates, we don't have to do cross domains check
-                if (toBeChecked == null) {
-                    toBeChecked = new ArrayList<ControlledEntity>();
-                    domains.put(domainId, toBeChecked);
-                }
-                toBeChecked.add(entity);
-            }
-            boolean granted = false;
-            for (SecurityChecker checker : _securityCheckers) {
-                if (checker.checkAccess(caller, entity, accessType, apiName)) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
-                    }
-                    granted = true;
-                    break;
-                }
-            }
-
-            if (!granted) {
-                assert false : "How can all of the security checkers pass on checking this check: " + entity;
-                throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
-            }
-        }
-
-        for (Map.Entry<Long, List<ControlledEntity>> domain : domains.entrySet()) {
-            for (SecurityChecker checker : _securityCheckers) {
-                Domain d = _domainMgr.getDomain(domain.getKey());
-                if (d == null || d.getRemoved() != null) {
-                    throw new PermissionDeniedException("Domain is not found.", caller, domain.getValue());
-                }
-                try {
-                    checker.checkAccess(caller, d);
-                } catch (PermissionDeniedException e) {
-                    e.addDetails(caller, domain.getValue());
-                    throw e;
-                }
-            }
-        }
-
-        // check that resources belong to the same account
-
-    }
-
-    @Override
-    public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
-        // We just care for resource domain admin for now. He should be permitted to see only his zone.
-        if (isResourceDomainAdmin(caller.getAccountId())) {
-            if (zoneId == null)
-                return getZoneIdForAccount(caller);
-            else if (zoneId.compareTo(getZoneIdForAccount(caller)) != 0)
-                throw new PermissionDeniedException("Caller " + caller + "is not allowed to access the zone " + zoneId);
-            else
-                return zoneId;
-        }
-
-        else
-            return zoneId;
-    }
-
-    private Long getZoneIdForAccount(Account account) {
-
-        // Currently just for resource domain admin
-        List<DataCenterVO> dcList = _dcDao.findZonesByDomainId(account.getDomainId());
-        if (dcList != null && dcList.size() != 0)
-            return dcList.get(0).getId();
-        else
-            throw new CloudRuntimeException("Failed to find any private zone for Resource domain admin.");
-
-    }
-
-    @DB
-    public void updateLoginAttempts(final Long id, final int attempts, final boolean toDisable) {
-        try {
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    UserAccountVO user = null;
-                    user = _userAccountDao.lockRow(id, true);
-                    user.setLoginAttempts(attempts);
-                    if (toDisable) {
-                        user.setState(State.disabled.toString());
-                    }
-                    _userAccountDao.update(id, user);
-                }
-            });
-        } catch (Exception e) {
-            s_logger.error("Failed to update login attempts for user with id " + id);
-        }
-    }
-
-    private boolean doSetUserStatus(long userId, State state) {
-        UserVO userForUpdate = _userDao.createForUpdate();
-        userForUpdate.setState(state);
-        return _userDao.update(Long.valueOf(userId), userForUpdate);
-    }
-
-    @Override
-    public boolean enableAccount(long accountId) {
-        boolean success = false;
-        AccountVO acctForUpdate = _accountDao.createForUpdate();
-        acctForUpdate.setState(State.enabled);
-        acctForUpdate.setNeedsCleanup(false);
-        success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
-        return success;
-    }
-
-    protected boolean lockAccount(long accountId) {
-        boolean success = false;
-        Account account = _accountDao.findById(accountId);
-        if (account != null) {
-            if (account.getState().equals(State.locked)) {
-                return true; // already locked, no-op
-            } else if (account.getState().equals(State.enabled)) {
-                AccountVO acctForUpdate = _accountDao.createForUpdate();
-                acctForUpdate.setState(State.locked);
-                success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Attempting to lock a non-enabled account, current state is " + account.getState() + " (accountId: " + accountId + "), locking failed.");
-                }
-            }
-        } else {
-            s_logger.warn("Failed to lock account " + accountId + ", account not found.");
-        }
-        return success;
-    }
-
-    @Override
-    public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) {
-        long accountId = account.getId();
-
-        // delete the account record
-        if (!_accountDao.remove(accountId)) {
-            s_logger.error("Unable to delete account " + accountId);
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Removed account " + accountId);
-        }
-
-        return cleanupAccount(account, callerUserId, caller);
-    }
-
-    protected boolean cleanupAccount(AccountVO account, long callerUserId, Account caller) {
-        long accountId = account.getId();
-        boolean accountCleanupNeeded = false;
-
-        try {
-            // cleanup the users from the account
-            List<UserVO> users = _userDao.listByAccount(accountId);
-            for (UserVO user : users) {
-                if (!_userDao.remove(user.getId())) {
-                    s_logger.error("Unable to delete user: " + user + " as a part of account " + account + " cleanup");
-                    accountCleanupNeeded = true;
-                }
-            }
-
-            // delete global load balancer rules for the account.
-            List<org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(accountId);
-            if (gslbRules != null && !gslbRules.isEmpty()) {
-                _gslbService.revokeAllGslbRulesForAccount(caller, accountId);
-            }
-
-            // delete the account from project accounts
-            _projectAccountDao.removeAccountFromProjects(accountId);
-
-            if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
-                // delete the account from group
-                _messageBus.publish(_name, MESSAGE_REMOVE_ACCOUNT_EVENT, PublishScope.LOCAL, accountId);
-            }
-
-            // delete all vm groups belonging to accont
-            List<InstanceGroupVO> groups = _vmGroupDao.listByAccountId(accountId);
-            for (InstanceGroupVO group : groups) {
-                if (!_vmMgr.deleteVmGroup(group.getId())) {
-                    s_logger.error("Unable to delete group: " + group.getId());
-                    accountCleanupNeeded = true;
-                }
-            }
-
-            // Delete the snapshots dir for the account. Have to do this before destroying the VMs.
-            boolean success = _snapMgr.deleteSnapshotDirsForAccount(accountId);
-            if (success) {
-                s_logger.debug("Successfully deleted snapshots directories for all volumes under account " + accountId + " across all zones");
-            }
-
-            // clean up templates
-            List<VMTemplateVO> userTemplates = _templateDao.listByAccountId(accountId);
-            boolean allTemplatesDeleted = true;
-            for (VMTemplateVO template : userTemplates) {
-                if (template.getRemoved() == null) {
-                    try {
-                        allTemplatesDeleted = _tmpltMgr.delete(callerUserId, template.getId(), null);
-                    } catch (Exception e) {
-                        s_logger.warn("Failed to delete template while removing account: " + template.getName() + " due to: ", e);
-                        allTemplatesDeleted = false;
-                    }
-                }
-            }
-
-            if (!allTemplatesDeleted) {
-                s_logger.warn("Failed to delete templates while removing account id=" + accountId);
-                accountCleanupNeeded = true;
-            }
-
-            // Destroy VM Snapshots
-            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(Long.valueOf(accountId));
-            for (VMSnapshot vmSnapshot : vmSnapshots) {
-                try {
-                    _vmSnapshotMgr.deleteVMSnapshot(vmSnapshot.getId());
-                } catch (Exception e) {
-                    s_logger.debug("Failed to cleanup vm snapshot " + vmSnapshot.getId() + " due to " + e.toString());
-                }
-            }
-
-            // Destroy the account's VMs
-            List<UserVmVO> vms = _userVmDao.listByAccountId(accountId);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Expunging # of vms (accountId=" + accountId + "): " + vms.size());
-            }
-
-            for (UserVmVO vm : vms) {
-                if (vm.getState() != VirtualMachine.State.Destroyed && vm.getState() != VirtualMachine.State.Expunging) {
-                    try {
-                        _vmMgr.destroyVm(vm.getId(), false);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                        s_logger.warn("Failed destroying instance " + vm.getUuid() + " as part of account deletion.");
-                    }
-                }
-                // no need to catch exception at this place as expunging vm
-                // should pass in order to perform further cleanup
-                if (!_vmMgr.expunge(vm, callerUserId, caller)) {
-                    s_logger.error("Unable to expunge vm: " + vm.getId());
-                    accountCleanupNeeded = true;
-                }
-            }
-
-            // Mark the account's volumes as destroyed
-            List<VolumeVO> volumes = _volumeDao.findDetachedByAccount(accountId);
-            for (VolumeVO volume : volumes) {
-                if (!volume.getState().equals(Volume.State.Destroy)) {
-                    try {
-                        volumeService.deleteVolume(volume.getId(), caller);
-                    } catch (Exception ex) {
-                        s_logger.warn("Failed to cleanup volumes as a part of account id=" + accountId + " cleanup due to Exception: ", ex);
-                        accountCleanupNeeded = true;
-                    }
-                }
-            }
-
-            // delete remote access vpns and associated users
-            List<RemoteAccessVpnVO> remoteAccessVpns = _remoteAccessVpnDao.findByAccount(accountId);
-            List<VpnUserVO> vpnUsers = _vpnUser.listByAccount(accountId);
-
-            for (VpnUserVO vpnUser : vpnUsers) {
-                _remoteAccessVpnMgr.removeVpnUser(accountId, vpnUser.getUsername(), caller);
-            }
-
-            try {
-                for (RemoteAccessVpnVO vpn : remoteAccessVpns) {
-                    _remoteAccessVpnMgr.destroyRemoteAccessVpnForIp(vpn.getServerAddressId(), caller, false);
-                }
-            } catch (ResourceUnavailableException ex) {
-                s_logger.warn("Failed to cleanup remote access vpn resources as a part of account id=" + accountId + " cleanup due to Exception: ", ex);
-                accountCleanupNeeded = true;
-            }
-
-            // Cleanup security groups
-            int numRemoved = _securityGroupDao.removeByAccountId(accountId);
-            s_logger.info("deleteAccount: Deleted " + numRemoved + " network groups for account " + accountId);
-
-            // Cleanup affinity groups
-            int numAGRemoved = _affinityGroupDao.removeByAccountId(accountId);
-            s_logger.info("deleteAccount: Deleted " + numAGRemoved + " affinity groups for account " + accountId);
-
-            // Delete all the networks
-            boolean networksDeleted = true;
-            s_logger.debug("Deleting networks for account " + account.getId());
-            List<NetworkVO> networks = _networkDao.listByOwner(accountId);
-            if (networks != null) {
-                for (NetworkVO network : networks) {
-
-                    ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller);
-
-                    if (!_networkMgr.destroyNetwork(network.getId(), context, false)) {
-                        s_logger.warn("Unable to destroy network " + network + " as a part of account id=" + accountId + " cleanup.");
-                        accountCleanupNeeded = true;
-                        networksDeleted = false;
-                    } else {
-                        s_logger.debug("Network " + network.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup.");
-                    }
-                }
-            }
-
-            // Delete all VPCs
-            boolean vpcsDeleted = true;
-            s_logger.debug("Deleting vpcs for account " + account.getId());
-            List<? extends Vpc> vpcs = _vpcMgr.getVpcsForAccount(account.getId());
-            for (Vpc vpc : vpcs) {
-
-                if (!_vpcMgr.destroyVpc(vpc, caller, callerUserId)) {
-                    s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup.");
-                    accountCleanupNeeded = true;
-                    vpcsDeleted = false;
-                } else {
-                    s_logger.debug("VPC " + vpc.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup.");
-                }
-            }
-
-            if (networksDeleted && vpcsDeleted) {
-                // release ip addresses belonging to the account
-                List<? extends IpAddress> ipsToRelease = _ipAddressDao.listByAccount(accountId);
-                for (IpAddress ip : ipsToRelease) {
-                    s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup");
-                    if (!_ipAddrMgr.disassociatePublicIpAddress(ip.getId(), callerUserId, caller)) {
-                        s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup");
-                        accountCleanupNeeded = true;
-                    }
-                }
-            }
-
-            // Delete Site 2 Site VPN customer gateway
-            s_logger.debug("Deleting site-to-site VPN customer gateways for account " + accountId);
-            if (!_vpnMgr.deleteCustomerGatewayByAccount(accountId)) {
-                s_logger.warn("Fail to delete site-to-site VPN customer gateways for account " + accountId);
-            }
-
-            // Delete autoscale resources if any
-            try {
-                _autoscaleMgr.cleanUpAutoScaleResources(accountId);
-            } catch (CloudRuntimeException ex) {
-                s_logger.warn("Failed to cleanup AutoScale resources as a part of account id=" + accountId + " cleanup due to exception:", ex);
-                accountCleanupNeeded = true;
-            }
-
-            // release account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned
-            // up successfully
-            if (networksDeleted) {
-                if (!_configMgr.releaseAccountSpecificVirtualRanges(accountId)) {
-                    accountCleanupNeeded = true;
-                } else {
-                    s_logger.debug("Account specific Virtual IP ranges " + " are successfully released as a part of account id=" + accountId + " cleanup.");
-                }
-            }
-
-            // release account specific guest vlans
-            List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId);
-            for (AccountGuestVlanMapVO map : maps) {
-                _dataCenterVnetDao.releaseDedicatedGuestVlans(map.getId());
-            }
-            int vlansReleased = _accountGuestVlanMapDao.removeByAccountId(accountId);
-            s_logger.info("deleteAccount: Released " + vlansReleased + " dedicated guest vlan ranges from account " + accountId);
-
-            // release account specific acquired portable IP's. Since all the portable IP's must have been already
-            // disassociated with VPC/guest network (due to deletion), so just mark portable IP as free.
-            List<? extends IpAddress> ipsToRelease = _ipAddressDao.listByAccount(accountId);
-            for (IpAddress ip : ipsToRelease) {
-                if (ip.isPortable()) {
-                    s_logger.debug("Releasing portable ip " + ip + " as a part of account id=" + accountId + " cleanup");
-                    _ipAddrMgr.releasePortableIpAddress(ip.getId());
-                }
-            }
-
-            // release dedication if any
-            List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByAccountId(accountId);
-            if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
-                s_logger.debug("Releasing dedicated resources for account " + accountId);
-                for (DedicatedResourceVO dr : dedicatedResources) {
-                    if (!_dedicatedDao.remove(dr.getId())) {
-                        s_logger.warn("Fail to release dedicated resources for account " + accountId);
-                    }
-                }
-            }
-
-            // Updating and deleting the resourceLimit and resourceCount should be the last step in cleanupAccount
-// process.
-            // Update resource count for this account and for parent domains.
-            List<ResourceCountVO> resourceCounts = _resourceCountDao.listByOwnerId(accountId, ResourceOwnerType.Account);
-            for (ResourceCountVO resourceCount : resourceCounts) {
-                _resourceLimitMgr.decrementResourceCount(accountId, resourceCount.getType(), resourceCount.getCount());
-            }
-
-            // Delete resource count and resource limits entries set for this account (if there are any).
-            _resourceCountDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
-            _resourceLimitDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
-
-            // Delete ssh keypairs
-            List<SSHKeyPairVO> sshkeypairs = _sshKeyPairDao.listKeyPairs(accountId, account.getDomainId());
-            for (SSHKeyPairVO keypair : sshkeypairs) {
-                _sshKeyPairDao.remove(keypair.getId());
-            }
-            return true;
-        } catch (Exception ex) {
-            s_logger.warn("Failed to cleanup account " + account + " due to ", ex);
-            accountCleanupNeeded = true;
-            return true;
-        } finally {
-            s_logger.info("Cleanup for account " + account.getId() + (accountCleanupNeeded ? " is needed." : " is not needed."));
-            if (accountCleanupNeeded) {
-                _accountDao.markForCleanup(accountId);
-            } else {
-                account.setNeedsCleanup(false);
-                _accountDao.update(accountId, account);
-            }
-        }
-    }
-
-    @Override
-    public boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
-        boolean success = false;
-        if (accountId <= 2) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("disableAccount -- invalid account id: " + accountId);
-            }
-            return false;
-        }
-
-        AccountVO account = _accountDao.findById(accountId);
-        if ((account == null) || (account.getState().equals(State.disabled) && !account.getNeedsCleanup())) {
-            success = true;
-        } else {
-            AccountVO acctForUpdate = _accountDao.createForUpdate();
-            acctForUpdate.setState(State.disabled);
-            success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
-
-            if (success) {
-                boolean disableAccountResult = false;
-                try {
-                    disableAccountResult = doDisableAccount(accountId);
-                } finally {
-                    if (!disableAccountResult) {
-                        s_logger.warn("Failed to disable account " + account + " resources as a part of disableAccount call, marking the account for cleanup");
-                        _accountDao.markForCleanup(accountId);
-                    } else {
-                        acctForUpdate = _accountDao.createForUpdate();
-                        account.setNeedsCleanup(false);
-                        _accountDao.update(accountId, account);
-                    }
-                }
-            }
-        }
-        return success;
-    }
-
-    private boolean doDisableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
-        List<VMInstanceVO> vms = _vmDao.listByAccountId(accountId);
-        boolean success = true;
-        for (VMInstanceVO vm : vms) {
-            try {
-                try {
-                    _itMgr.advanceStop(vm.getUuid(), false);
-                } catch (OperationTimedoutException ote) {
-                    s_logger.warn("Operation for stopping vm timed out, unable to stop vm " + vm.getHostName(), ote);
-                    success = false;
-                }
-            } catch (AgentUnavailableException aue) {
-                s_logger.warn("Agent running on host " + vm.getHostId() + " is unavailable, unable to stop vm " + vm.getHostName(), aue);
-                success = false;
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
-            @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
-    public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone,
-            String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID,
-            final String userUUID) {
-
-        return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, roleId, domainId, networkDomain, details, accountUUID,
-                userUUID, User.Source.UNKNOWN);
-    }
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API commands /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    @DB
-    @ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
-            @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
-    public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone,
-            String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID,
-            final String userUUID, final User.Source source) {
-
-        if (accountName == null) {
-            accountName = userName;
-        }
-        if (domainId == null) {
-            domainId = Domain.ROOT_DOMAIN;
-        }
-
-        if (StringUtils.isEmpty(userName)) {
-            throw new InvalidParameterValueException("Username is empty");
-        }
-
-        if (StringUtils.isEmpty(firstName)) {
-            throw new InvalidParameterValueException("Firstname is empty");
-        }
-
-        if (StringUtils.isEmpty(lastName)) {
-            throw new InvalidParameterValueException("Lastname is empty");
-        }
-
-        // Validate domain
-        Domain domain = _domainMgr.getDomain(domainId);
-        if (domain == null) {
-            throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account");
-        }
-
-        // Check permissions
-        checkAccess(CallContext.current().getCallingAccount(), domain);
-
-        if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
-            throw new InvalidParameterValueException("The user " + userName + " already exists in domain " + domainId);
-        }
-
-        if (networkDomain != null && networkDomain.length() > 0) {
-            if (!NetUtils.verifyDomainName(networkDomain)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-        }
-
-        final String accountNameFinal = accountName;
-        final Long domainIdFinal = domainId;
-        final String accountUUIDFinal = accountUUID;
-        Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<Pair<Long, Account>>() {
-            @Override
-            public Pair<Long, Account> doInTransaction(TransactionStatus status) {
-                // create account
-                String accountUUID = accountUUIDFinal;
-                if (accountUUID == null) {
-                    accountUUID = UUID.randomUUID().toString();
-                }
-                AccountVO account = createAccount(accountNameFinal, accountType, roleId, domainIdFinal, networkDomain, details, accountUUID);
-                long accountId = account.getId();
-
-                // create the first user for the account
-                UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID, source);
-
-                if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-                    // set registration token
-                    byte[] bytes = (domainIdFinal + accountNameFinal + userName + System.currentTimeMillis()).getBytes();
-                    String registrationToken = UUID.nameUUIDFromBytes(bytes).toString();
-                    user.setRegistrationToken(registrationToken);
-                }
-
-                return new Pair<Long, Account>(user.getId(), account);
-            }
-        });
-
-        long userId = pair.first();
-        Account account = pair.second();
-
-        // create correct account and group association based on accountType
-        if (accountType != Account.ACCOUNT_TYPE_PROJECT) {
-            Map<Long, Long> accountGroupMap = new HashMap<Long, Long>();
-            accountGroupMap.put(account.getId(), new Long(accountType + 1));
-            _messageBus.publish(_name, MESSAGE_ADD_ACCOUNT_EVENT, PublishScope.LOCAL, accountGroupMap);
-        }
-
-        CallContext.current().putContextParameter(Account.class, account.getUuid());
-
-        // check success
-        return _userAccountDao.findById(userId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
-    public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
-            User.Source source) {
-        // default domain to ROOT if not specified
-        if (domainId == null) {
-            domainId = Domain.ROOT_DOMAIN;
-        }
-
-        Domain domain = _domainMgr.getDomain(domainId);
-        if (domain == null) {
-            throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user");
-        } else if (domain.getState().equals(Domain.State.Inactive)) {
-            throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted");
-        }
-
-        checkAccess(CallContext.current().getCallingAccount(), domain);
-
-        Account account = _accountDao.findEnabledAccount(accountName, domainId);
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user");
-        }
-
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("Account id : " + account.getId() + " is a system account, can't add a user to it");
-        }
-
-        if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
-            throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId);
-        }
-        UserVO user = null;
-        user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source);
-        return user;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
-    public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
-            String userUUID) {
-
-        return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "updating User")
-    public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
-            String timeZone) {
-        // Input validation
-        UserVO user = _userDao.getUser(userId);
-
-        if (user == null) {
-            throw new InvalidParameterValueException("unable to find user by id");
-        }
-
-        if ((apiKey == null && secretKey != null) || (apiKey != null && secretKey == null)) {
-            throw new InvalidParameterValueException("Please provide an userApiKey/userSecretKey pair");
-        }
-
-        // If the account is an admin type, return an error. We do not allow this
-        Account account = _accountDao.findById(user.getAccountId());
-        if (account == null) {
-            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
-        }
-
-        // don't allow updating project account
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("unable to find user by id");
-        }
-
-        // don't allow updating system account
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("user id : " + userId + " is system account, update is not allowed");
-        }
-
-        checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
-
-        if (firstName != null) {
-            if (firstName.isEmpty()) {
-                throw new InvalidParameterValueException("Firstname is empty");
-            }
-
-            user.setFirstname(firstName);
-        }
-        if (lastName != null) {
-            if (lastName.isEmpty()) {
-                throw new InvalidParameterValueException("Lastname is empty");
-            }
-
-            user.setLastname(lastName);
-        }
-        if (userName != null) {
-            if (userName.isEmpty()) {
-                throw new InvalidParameterValueException("Username is empty");
-            }
-
-            // don't allow to have same user names in the same domain
-            List<UserVO> duplicatedUsers = _userDao.findUsersByName(userName);
-            for (UserVO duplicatedUser : duplicatedUsers) {
-                if (duplicatedUser.getId() != user.getId()) {
-                    Account duplicatedUserAccount = _accountDao.findById(duplicatedUser.getAccountId());
-                    if (duplicatedUserAccount.getDomainId() == account.getDomainId()) {
-                        throw new InvalidParameterValueException("User with name " + userName + " already exists in domain " + duplicatedUserAccount.getDomainId());
-                    }
-                }
-            }
-
-            user.setUsername(userName);
-        }
-
-        if (password != null) {
-            if (password.isEmpty()) {
-                throw new InvalidParameterValueException("Password cannot be empty");
-            }
-            String encodedPassword = null;
-            for (Iterator<UserAuthenticator> en = _userPasswordEncoders.iterator(); en.hasNext();) {
-                UserAuthenticator authenticator = en.next();
-                encodedPassword = authenticator.encode(password);
-                if (encodedPassword != null) {
-                    break;
-                }
-            }
-            if (encodedPassword == null) {
-                throw new CloudRuntimeException("Failed to encode password");
-            }
-            user.setPassword(encodedPassword);
-        }
-        if (email != null) {
-            user.setEmail(email);
-        }
-        if (timeZone != null) {
-            user.setTimezone(timeZone);
-        }
-        if (apiKey != null) {
-            user.setApiKey(apiKey);
-        }
-        if (secretKey != null) {
-            user.setSecretKey(secretKey);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("updating user with id: " + userId);
-        }
-        try {
-            // check if the apiKey and secretKey are globally unique
-            if (apiKey != null && secretKey != null) {
-                Pair<User, Account> apiKeyOwner = _accountDao.findUserAccountByApiKey(apiKey);
-
-                if (apiKeyOwner != null) {
-                    User usr = apiKeyOwner.first();
-                    if (usr.getId() != userId) {
-                        throw new InvalidParameterValueException("The api key:" + apiKey + " exists in the system for user id:" + userId + " ,please provide a unique key");
-                    } else {
-                        // allow the updation to take place
-                    }
-                }
-            }
-
-            _userDao.update(userId, user);
-        } catch (Throwable th) {
-            s_logger.error("error updating user", th);
-            throw new CloudRuntimeException("Unable to update user " + userId);
-        }
-
-        CallContext.current().putContextParameter(User.class, user.getUuid());
-
-        return _userAccountDao.findById(userId);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "updating User")
-    public UserAccount updateUser(UpdateUserCmd cmd) {
-        Long id = cmd.getId();
-        String apiKey = cmd.getApiKey();
-        String firstName = cmd.getFirstname();
-        String email = cmd.getEmail();
-        String lastName = cmd.getLastname();
-        String password = cmd.getPassword();
-        String secretKey = cmd.getSecretKey();
-        String timeZone = cmd.getTimezone();
-        String userName = cmd.getUsername();
-
-        return updateUser(id, firstName, lastName, email, userName, password, apiKey, secretKey, timeZone);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_DISABLE, eventDescription = "disabling User", async = true)
-    public UserAccount disableUser(long userId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Check if user exists in the system
-        User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-
-        Account account = _accountDao.findById(user.getAccountId());
-        if (account == null) {
-            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
-        }
-
-        // don't allow disabling user belonging to project's account
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-
-        // If the user is a System user, return an error
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new InvalidParameterValueException("User id : " + userId + " is a system user, disabling is not allowed");
-        }
-
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        boolean success = doSetUserStatus(userId, State.disabled);
-        if (success) {
-
-            CallContext.current().putContextParameter(User.class, user.getUuid());
-
-            // user successfully disabled
-            return _userAccountDao.findById(userId);
-        } else {
-            throw new CloudRuntimeException("Unable to disable user " + userId);
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User")
-    public UserAccount enableUser(final long userId) {
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Check if user exists in the system
-        final User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-
-        Account account = _accountDao.findById(user.getAccountId());
-        if (account == null) {
-            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
-        }
-
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
-        }
-
-        // If the user is a System user, return an error
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new InvalidParameterValueException("User id : " + userId + " is a system user, enabling is not allowed");
-        }
-
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        boolean success = Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                boolean success = doSetUserStatus(userId, State.enabled);
-
-                // make sure the account is enabled too
-                success = success && enableAccount(user.getAccountId());
-
-                return success;
-            }
-        });
-
-        if (success) {
-            // whenever the user is successfully enabled, reset the login attempts to zero
-            updateLoginAttempts(userId, 0, false);
-
-            CallContext.current().putContextParameter(User.class, user.getUuid());
-
-            return _userAccountDao.findById(userId);
-        } else {
-            throw new CloudRuntimeException("Unable to enable user " + userId);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_LOCK, eventDescription = "locking User")
-    public UserAccount lockUser(long userId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Check if user with id exists in the system
-        User user = _userDao.findById(userId);
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("Unable to find user by id");
-        }
-
-        Account account = _accountDao.findById(user.getAccountId());
-        if (account == null) {
-            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
-        }
-
-        // don't allow to lock user of the account of type Project
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find user by id");
-        }
-
-        // If the user is a System user, return an error. We do not allow this
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("user id : " + userId + " is a system user, locking is not allowed");
-        }
-
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        // make sure the account is enabled too
-        // if the user is either locked already or disabled already, don't change state...only lock currently enabled
-// users
-        boolean success = true;
-        if (user.getState().equals(State.locked)) {
-            // already locked...no-op
-            return _userAccountDao.findById(userId);
-        } else if (user.getState().equals(State.enabled)) {
-            success = doSetUserStatus(user.getId(), State.locked);
-
-            boolean lockAccount = true;
-            List<UserVO> allUsersByAccount = _userDao.listByAccount(user.getAccountId());
-            for (UserVO oneUser : allUsersByAccount) {
-                if (oneUser.getState().equals(State.enabled)) {
-                    lockAccount = false;
-                    break;
-                }
-            }
-
-            if (lockAccount) {
-                success = (success && lockAccount(user.getAccountId()));
-            }
-        } else {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Attempting to lock a non-enabled user, current state is " + user.getState() + " (userId: " + user.getId() + "), locking failed.");
-            }
-            success = false;
-        }
-
-        if (success) {
-
-            CallContext.current().putContextParameter(User.class, user.getUuid());
-
-            return _userAccountDao.findById(userId);
-        } else {
-            throw new CloudRuntimeException("Unable to lock user " + userId);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true)
-    // This method deletes the account
-    public boolean deleteUserAccount(long accountId) {
-
-        CallContext ctx = CallContext.current();
-        long callerUserId = ctx.getCallingUserId();
-        Account caller = ctx.getCallingAccount();
-
-        // If the user is a System user, return an error. We do not allow this
-        AccountVO account = _accountDao.findById(accountId);
-
-        if (account == null || account.getRemoved() != null) {
-            if (account != null) {
-                s_logger.info("The account:" + account.getAccountName() + " is already removed");
-            }
-            return true;
-        }
-
-        // don't allow removing Project account
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("The specified account does not exist in the system");
-        }
-
-        checkAccess(caller, null, true, account);
-
-        // don't allow to delete default account (system and admin)
-        if (account.isDefault()) {
-            throw new InvalidParameterValueException("The account is default and can't be removed");
-        }
-
-        // Account that manages project(s) can't be removed
-        List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
-        if (!managedProjectIds.isEmpty()) {
-            StringBuilder projectIds = new StringBuilder();
-            for (Long projectId : managedProjectIds) {
-                projectIds.append(projectId + ", ");
-            }
-
-            throw new InvalidParameterValueException("The account id=" + accountId + " manages project(s) with ids " + projectIds + "and can't be removed");
-        }
-
-        CallContext.current().putContextParameter(Account.class, account.getUuid());
-
-        return deleteAccount(account, callerUserId, caller);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_ENABLE, eventDescription = "enabling account", async = true)
-    public AccountVO enableAccount(String accountName, Long domainId, Long accountId) {
-
-        // Check if account exists
-        Account account = null;
-        if (accountId != null) {
-            account = _accountDao.findById(accountId);
-        } else {
-            account = _accountDao.findActiveAccount(accountName, domainId);
-        }
-
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, enable is not allowed");
-        }
-
-        // Check if user performing the action is allowed to modify this account
-        Account caller = CallContext.current().getCallingAccount();
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        boolean success = enableAccount(account.getId());
-        if (success) {
-
-            CallContext.current().putContextParameter(Account.class, account.getUuid());
-
-            return _accountDao.findById(account.getId());
-        } else {
-            throw new CloudRuntimeException("Unable to enable account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "locking account", async = true)
-    public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
-        Account caller = CallContext.current().getCallingAccount();
-
-        Account account = null;
-        if (accountId != null) {
-            account = _accountDao.findById(accountId);
-        } else {
-            account = _accountDao.findActiveAccount(accountName, domainId);
-        }
-
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, lock is not allowed");
-        }
-
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        if (lockAccount(account.getId())) {
-            CallContext.current().putContextParameter(Account.class, account.getUuid());
-            return _accountDao.findById(account.getId());
-        } else {
-            throw new CloudRuntimeException("Unable to lock account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "disabling account", async = true)
-    public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        Account account = null;
-        if (accountId != null) {
-            account = _accountDao.findById(accountId);
-        } else {
-            account = _accountDao.findActiveAccount(accountName, domainId);
-        }
-
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, disable is not allowed");
-        }
-
-        checkAccess(caller, AccessType.OperateEntry, true, account);
-
-        if (disableAccount(account.getId())) {
-            CallContext.current().putContextParameter(Account.class, account.getUuid());
-            return _accountDao.findById(account.getId());
-        } else {
-            throw new CloudRuntimeException("Unable to update account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_UPDATE, eventDescription = "updating account", async = true)
-    public AccountVO updateAccount(UpdateAccountCmd cmd) {
-        Long accountId = cmd.getId();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        String newAccountName = cmd.getNewName();
-        String networkDomain = cmd.getNetworkDomain();
-        final Map<String, String> details = cmd.getDetails();
-
-        boolean success = false;
-        Account account = null;
-        if (accountId != null) {
-            account = _accountDao.findById(accountId);
-        } else {
-            account = _accountDao.findEnabledAccount(accountName, domainId);
-        }
-
-        // Check if account exists
-        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-
-        // Don't allow to modify system account
-        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
-            throw new InvalidParameterValueException("Can not modify system account");
-        }
-
-        // Check if user performing the action is allowed to modify this account
-        checkAccess(CallContext.current().getCallingAccount(), _domainMgr.getDomain(account.getDomainId()));
-
-        // check if the given account name is unique in this domain for updating
-        Account duplicateAcccount = _accountDao.findActiveAccount(newAccountName, domainId);
-        if (duplicateAcccount != null && duplicateAcccount.getId() != account.getId()) {// allow
-                                                                                        // same
-                                                                                        // account
-                                                                                        // to
-                                                                                        // update
-                                                                                        // itself
-            throw new InvalidParameterValueException(
-                    "There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + " with existing account id:" + duplicateAcccount.getId());
-        }
-
-        if (networkDomain != null && !networkDomain.isEmpty()) {
-            if (!NetUtils.verifyDomainName(networkDomain)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-        }
-
-        final AccountVO acctForUpdate = _accountDao.findById(account.getId());
-        acctForUpdate.setAccountName(newAccountName);
-
-        if (networkDomain != null) {
-            if (networkDomain.isEmpty()) {
-                acctForUpdate.setNetworkDomain(null);
-            } else {
-                acctForUpdate.setNetworkDomain(networkDomain);
-            }
-        }
-
-        final Account accountFinal = account;
-        success = Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                boolean success = _accountDao.update(accountFinal.getId(), acctForUpdate);
-
-                if (details != null && success) {
-                    _accountDetailsDao.update(accountFinal.getId(), details);
-                }
-
-                return success;
-            }
-        });
-
-        if (success) {
-            CallContext.current().putContextParameter(Account.class, account.getUuid());
-            return _accountDao.findById(account.getId());
-        } else {
-            throw new CloudRuntimeException("Unable to update account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_USER_DELETE, eventDescription = "deleting User")
-    public boolean deleteUser(DeleteUserCmd deleteUserCmd) {
-        UserVO user = getValidUserVO(deleteUserCmd.getId());
-
-        Account account = _accountDao.findById(user.getAccountId());
-
-        // don't allow to delete the user from the account of type Project
-        checkAccountAndAccess(user, account);
-        return _userDao.remove(deleteUserCmd.getId());
-    }
-
-    @ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
-    public boolean moveUser(MoveUserCmd cmd) {
-        final Long id = cmd.getId();
-        UserVO user = getValidUserVO(id);
-        Account oldAccount = _accountDao.findById(user.getAccountId());
-        checkAccountAndAccess(user, oldAccount);
-        long domainId = oldAccount.getDomainId();
-
-        long newAccountId = getNewAccountId(domainId, cmd.getAccountName(), cmd.getAccountId());
-
-        return moveUser(user, newAccountId);
-    }
-
-    public boolean moveUser(long id, Long domainId, long accountId) {
-        UserVO user = getValidUserVO(id);
-        Account oldAccount = _accountDao.findById(user.getAccountId());
-        checkAccountAndAccess(user, oldAccount);
-        Account newAccount = _accountDao.findById(accountId);
-        checkIfNotMovingAcrossDomains(domainId, newAccount);
-        return moveUser(user , accountId);
-    }
-
-    private boolean moveUser(UserVO user, long newAccountId) {
-        if(newAccountId == user.getAccountId()) {
-            // could do a not silent fail but the objective of the user is reached
-            return true; // no need to create a new user object for this user
-        }
-
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                UserVO newUser = new UserVO(user);
-                user.setExternalEntity(user.getUuid());
-                user.setUuid(UUID.randomUUID().toString());
-                user.setApiKey(null);
-                user.setSecretKey(null);
-                _userDao.update(user.getId(),user);
-                newUser.setAccountId(newAccountId);
-                boolean success = _userDao.remove(user.getId());
-                UserVO persisted = _userDao.persist(newUser);
-                return success && persisted.getUuid().equals(user.getExternalEntity());
-            }
-        });
-    }
-
-    private long getNewAccountId(long domainId, String accountName, Long accountId) {
-        Account newAccount = null;
-        if (StringUtils.isNotBlank(accountName)) {
-            if(s_logger.isDebugEnabled()) {
-                s_logger.debug("Getting id for account by name '" + accountName + "' in domain " + domainId);
-            }
-            newAccount = _accountDao.findEnabledAccount(accountName, domainId);
-        }
-        if (newAccount == null && accountId != null) {
-            newAccount = _accountDao.findById(accountId);
-        }
-        if (newAccount == null) {
-            throw new CloudRuntimeException("no account name or account id. this should have been caught before this point");
-        }
-
-        checkIfNotMovingAcrossDomains(domainId, newAccount);
-        return newAccount.getAccountId();
-    }
-
-    private void checkIfNotMovingAcrossDomains(long domainId, Account newAccount) {
-        if(newAccount.getDomainId() != domainId) {
-            // not in scope
-            throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
-        }
-    }
-
-    private void checkAccountAndAccess(UserVO user, Account account) {
-        // don't allow to delete the user from the account of type Project
-        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            throw new InvalidParameterValueException("Project users cannot be deleted or moved.");
-        }
-
-        checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
-        CallContext.current().putContextParameter(User.class, user.getUuid());
-    }
-
-    private UserVO getValidUserVO(long id) {
-        UserVO user = _userDao.findById(id);
-
-        if (user == null || user.getRemoved() != null) {
-            throw new InvalidParameterValueException("The specified user doesn't exist in the system");
-        }
-
-        // don't allow to delete default user (system and admin users)
-        if (user.isDefault()) {
-            throw new InvalidParameterValueException("The user is default and can't be (re)moved");
-        }
-
-        return user;
-    }
-
-    protected class AccountCleanupTask extends ManagedContextRunnable {
-        @Override
-        protected void runInContext() {
-            try {
-                GlobalLock lock = GlobalLock.getInternLock("AccountCleanup");
-                if (lock == null) {
-                    s_logger.debug("Couldn't get the global lock");
-                    return;
-                }
-
-                if (!lock.lock(30)) {
-                    s_logger.debug("Couldn't lock the db");
-                    return;
-                }
-
-                try {
-                    // Cleanup removed accounts
-                    List<AccountVO> removedAccounts = _accountDao.findCleanupsForRemovedAccounts(null);
-                    s_logger.info("Found " + removedAccounts.size() + " removed accounts to cleanup");
-                    for (AccountVO account : removedAccounts) {
-                        s_logger.debug("Cleaning up " + account.getId());
-                        cleanupAccount(account, getSystemUser().getId(), getSystemAccount());
-                    }
-
-                    // cleanup disabled accounts
-                    List<AccountVO> disabledAccounts = _accountDao.findCleanupsForDisabledAccounts();
-                    s_logger.info("Found " + disabledAccounts.size() + " disabled accounts to cleanup");
-                    for (AccountVO account : disabledAccounts) {
-                        s_logger.debug("Disabling account " + account.getId());
-                        try {
-                            disableAccount(account.getId());
-                        } catch (Exception e) {
-                            s_logger.error("Skipping due to error on account " + account.getId(), e);
-                        }
-                    }
-
-                    // cleanup inactive domains
-                    List<? extends Domain> inactiveDomains = _domainMgr.findInactiveDomains();
-                    s_logger.info("Found " + inactiveDomains.size() + " inactive domains to cleanup");
-                    for (Domain inactiveDomain : inactiveDomains) {
-                        long domainId = inactiveDomain.getId();
-                        try {
-                            List<AccountVO> accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId);
-                            if (accountsForCleanupInDomain.isEmpty()) {
-                                // release dedication if any, before deleting the domain
-                                List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByDomainId(domainId);
-                                if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
-                                    s_logger.debug("Releasing dedicated resources for domain" + domainId);
-                                    for (DedicatedResourceVO dr : dedicatedResources) {
-                                        if (!_dedicatedDao.remove(dr.getId())) {
-                                            s_logger.warn("Fail to release dedicated resources for domain " + domainId);
-                                        }
-                                    }
-                                }
-                                s_logger.debug("Removing inactive domain id=" + domainId);
-                                _domainMgr.removeDomain(domainId);
-                            } else {
-                                s_logger.debug("Can't remove inactive domain id=" + domainId + " as it has accounts that need cleanup");
-                            }
-                        } catch (Exception e) {
-                            s_logger.error("Skipping due to error on domain " + domainId, e);
-                        }
-                    }
-
-                    // cleanup inactive projects
-                    List<ProjectVO> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
-                    s_logger.info("Found " + inactiveProjects.size() + " disabled projects to cleanup");
-                    for (ProjectVO project : inactiveProjects) {
-                        try {
-                            Account projectAccount = getAccount(project.getProjectAccountId());
-                            if (projectAccount == null) {
-                                s_logger.debug("Removing inactive project id=" + project.getId());
-                                _projectMgr.deleteProject(CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId(), project);
-                            } else {
-                                s_logger.debug("Can't remove disabled project " + project + " as it has non removed account id=" + project.getId());
-                            }
-                        } catch (Exception e) {
-                            s_logger.error("Skipping due to error on project " + project, e);
-                        }
-                    }
-
-                } catch (Exception e) {
-                    s_logger.error("Exception ", e);
-                } finally {
-                    lock.unlock();
-                }
-            } catch (Exception e) {
-                s_logger.error("Exception ", e);
-            }
-        }
-    }
-
-    @Override
-    public Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId) {
-        // don't default the owner to the system account
-        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM && ((accountName == null || domainId == null) && projectId == null)) {
-            throw new InvalidParameterValueException("Account and domainId are needed for resource creation");
-        }
-
-        // projectId and account/domainId can't be specified together
-        if ((accountName != null && domainId != null) && projectId != null) {
-            throw new InvalidParameterValueException("ProjectId and account/domainId can't be specified together");
-        }
-
-        if (projectId != null) {
-            Project project = _projectMgr.getProject(projectId);
-            if (project == null) {
-                throw new InvalidParameterValueException("Unable to find project by id=" + projectId);
-            }
-
-            if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
-                throw new PermissionDeniedException("Account " + caller + " is unauthorised to use project id=" + projectId);
-            }
-
-            return getAccount(project.getProjectAccountId());
-        }
-
-        if (isAdmin(caller.getId()) && accountName != null && domainId != null) {
-            Domain domain = _domainMgr.getDomain(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId);
-            }
-
-            Account owner = _accountDao.findActiveAccount(accountName, domainId);
-            if (owner == null) {
-                throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
-            }
-            checkAccess(caller, domain);
-
-            return owner;
-        } else if (!isAdmin(caller.getId()) && accountName != null && domainId != null) {
-            if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) {
-                throw new PermissionDeniedException("Can't create/list resources for account " + accountName + " in domain " + domainId + ", permission denied");
-            } else {
-                return caller;
-            }
-        } else {
-            if ((accountName == null && domainId != null) || (accountName != null && domainId == null)) {
-                throw new InvalidParameterValueException("AccountName and domainId must be specified together");
-            }
-            // regular user can't create/list resources for other people
-            return caller;
-        }
-    }
-
-    @Override
-    public Account getActiveAccountByName(String accountName, Long domainId) {
-        if (accountName == null || domainId == null) {
-            throw new InvalidParameterValueException("Both accountName and domainId are required for finding active account in the system");
-        } else {
-            return _accountDao.findActiveAccount(accountName, domainId);
-        }
-    }
-
-    @Override
-    public UserAccount getActiveUserAccount(String username, Long domainId) {
-        return _userAccountDao.getUserAccount(username, domainId);
-    }
-
-    @Override
-    public Account getActiveAccountById(long accountId) {
-        return _accountDao.findById(accountId);
-    }
-
-    @Override
-    public Account getAccount(long accountId) {
-        return _accountDao.findByIdIncludingRemoved(accountId);
-    }
-
-    @Override
-    public RoleType getRoleType(Account account) {
-        if (account == null) {
-            return RoleType.Unknown;
-        }
-        return RoleType.getByAccountType(account.getType());
-    }
-
-    @Override
-    public User getActiveUser(long userId) {
-        return _userDao.findById(userId);
-    }
-
-    @Override
-    public User getUserIncludingRemoved(long userId) {
-        return _userDao.findByIdIncludingRemoved(userId);
-    }
-
-    @Override
-    public User getActiveUserByRegistrationToken(String registrationToken) {
-        return _userDao.findUserByRegistrationToken(registrationToken);
-    }
-
-    @Override
-    public void markUserRegistered(long userId) {
-        UserVO userForUpdate = _userDao.createForUpdate();
-        userForUpdate.setRegistered(true);
-        _userDao.update(Long.valueOf(userId), userForUpdate);
-    }
-
-    @Override
-    @DB
-    public AccountVO createAccount(final String accountName, final short accountType, final Long roleId, final Long domainId, final String networkDomain,
-            final Map<String, String> details, final String uuid) {
-        // Validate domain
-        Domain domain = _domainMgr.getDomain(domainId);
-        if (domain == null) {
-            throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account");
-        }
-
-        if (domain.getState().equals(Domain.State.Inactive)) {
-            throw new CloudRuntimeException("The account cannot be created as domain " + domain.getName() + " is being deleted");
-        }
-
-        if ((domainId != Domain.ROOT_DOMAIN) && (accountType == Account.ACCOUNT_TYPE_ADMIN)) {
-            throw new InvalidParameterValueException(
-                    "Invalid account type " + accountType + " given for an account in domain " + domainId + "; unable to create user of admin role type in non-ROOT domain.");
-        }
-
-        // Validate account/user/domain settings
-        if (_accountDao.findActiveAccount(accountName, domainId) != null) {
-            throw new InvalidParameterValueException("The specified account: " + accountName + " already exists");
-        }
-
-        if (networkDomain != null) {
-            if (!NetUtils.verifyDomainName(networkDomain)) {
-                throw new InvalidParameterValueException(
-                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                                + "and the hyphen ('-'); can't start or end with \"-\"");
-            }
-        }
-
-        // Verify account type
-        if ((accountType < Account.ACCOUNT_TYPE_NORMAL) || (accountType > Account.ACCOUNT_TYPE_PROJECT)) {
-            throw new InvalidParameterValueException("Invalid account type " + accountType + " given; unable to create user");
-        }
-
-        if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
-            List<DataCenterVO> dc = _dcDao.findZonesByDomainId(domainId);
-            if (dc.isEmpty()) {
-                throw new InvalidParameterValueException("The account cannot be created as domain " + domain.getName() + " is not associated with any private Zone");
-            }
-        }
-
-        // Create the account
-        return Transaction.execute(new TransactionCallback<AccountVO>() {
-            @Override
-            public AccountVO doInTransaction(TransactionStatus status) {
-                AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid));
-
-                if (account == null) {
-                    throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId);
-                }
-
-                Long accountId = account.getId();
-
-                if (details != null) {
-                    _accountDetailsDao.persist(accountId, details);
-                }
-
-                // Create resource count records for the account
-                _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account);
-
-                // Create default security group
-                _networkGroupMgr.createDefaultSecurityGroup(accountId);
-
-                return account;
-            }
-        });
-    }
-
-    protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID,
-            User.Source source) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
-        }
-
-        String encodedPassword = null;
-        for (UserAuthenticator authenticator : _userPasswordEncoders) {
-            encodedPassword = authenticator.encode(password);
-            if (encodedPassword != null) {
-                break;
-            }
-        }
-        if (encodedPassword == null) {
-            throw new CloudRuntimeException("Failed to encode password");
-        }
-
-        if (userUUID == null) {
-            userUUID = UUID.randomUUID().toString();
-        }
-        UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, userUUID, source));
-        CallContext.current().putContextParameter(User.class, user.getUuid());
-        return user;
-    }
-
-    @Override
-    public void logoutUser(long userId) {
-        UserAccount userAcct = _userAccountDao.findById(userId);
-        if (userAcct != null) {
-            ActionEventUtils.onActionEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out");
-        } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted...
-    }
-
-    @Override
-    public UserAccount authenticateUser(final String username, final String password, final Long domainId, final InetAddress loginIpAddress, final Map<String, Object[]>
-            requestParameters) {
-        UserAccount user = null;
-        if (password != null && !password.isEmpty()) {
-            user = getUserAccount(username, password, domainId, requestParameters);
-        } else {
-            String key = _configDao.getValue("security.singlesignon.key");
-            if (key == null) {
-                // the SSO key is gone, don't authenticate
-                return null;
-            }
-
-            String singleSignOnTolerance = _configDao.getValue("security.singlesignon.tolerance.millis");
-            if (singleSignOnTolerance == null) {
-                // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be
-                // valid),
-                // don't authenticate
-                return null;
-            }
-
-            long tolerance = Long.parseLong(singleSignOnTolerance);
-            String signature = null;
-            long timestamp = 0L;
-            String unsignedRequest = null;
-            StringBuffer unsignedRequestBuffer = new StringBuffer();
-
-            // - build a request string with sorted params, make sure it's all lowercase
-            // - sign the request, verify the signature is the same
-            List<String> parameterNames = new ArrayList<String>();
-
-            for (Object paramNameObj : requestParameters.keySet()) {
-                parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
-            }
-
-            Collections.sort(parameterNames);
-
-            try {
-                for (String paramName : parameterNames) {
-                    // parameters come as name/value pairs in the form String/String[]
-                    String paramValue = ((String[])requestParameters.get(paramName))[0];
-
-                    if ("signature".equalsIgnoreCase(paramName)) {
-                        signature = paramValue;
-                    } else {
-                        if ("timestamp".equalsIgnoreCase(paramName)) {
-                            String timestampStr = paramValue;
-                            try {
-                                // If the timestamp is in a valid range according to our tolerance, verify the request
-                                // signature, otherwise return null to indicate authentication failure
-                                timestamp = Long.parseLong(timestampStr);
-                                long currentTime = System.currentTimeMillis();
-                                if (Math.abs(currentTime - timestamp) > tolerance) {
-                                    if (s_logger.isDebugEnabled()) {
-                                        s_logger.debug("Expired timestamp passed in to login, current time = " + currentTime + ", timestamp = " + timestamp);
-                                    }
-                                    return null;
-                                }
-                            } catch (NumberFormatException nfe) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Invalid timestamp passed in to login: " + timestampStr);
-                                }
-                                return null;
-                            }
-                        }
-
-                        if (unsignedRequestBuffer.length() != 0) {
-                            unsignedRequestBuffer.append("&");
-                        }
-                        unsignedRequestBuffer.append(paramName).append("=").append(URLEncoder.encode(paramValue, "UTF-8"));
-                    }
-                }
-
-                if ((signature == null) || (timestamp == 0L)) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Missing parameters in login request, signature = " + signature + ", timestamp = " + timestamp);
-                    }
-                    return null;
-                }
-
-                unsignedRequest = unsignedRequestBuffer.toString().toLowerCase().replaceAll("\\+", "%20");
-
-                Mac mac = Mac.getInstance("HmacSHA1");
-                SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
-                mac.init(keySpec);
-                mac.update(unsignedRequest.getBytes());
-                byte[] encryptedBytes = mac.doFinal();
-                String computedSignature = new String(Base64.encodeBase64(encryptedBytes));
-                boolean equalSig = ConstantTimeComparator.compareStrings(signature, computedSignature);
-                if (!equalSig) {
-                    s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
-                } else {
-                    user = _userAccountDao.getUserAccount(username, domainId);
-                }
-            } catch (Exception ex) {
-                s_logger.error("Exception authenticating user", ex);
-                return null;
-            }
-        }
-
-        if (user != null) {
-            // don't allow to authenticate system user
-            if (user.getId() == User.UID_SYSTEM) {
-                s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId);
-                return null;
-            }
-            // don't allow baremetal system user
-            if (BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME.equals(user.getUsername())) {
-                s_logger.error("Won't authenticate user: " + username + " in domain " + domainId);
-                return null;
-            }
-
-            // We authenticated successfully by now, let's check if we are allowed to login from the ip address the reqest comes from
-            final Account account = _accountMgr.getAccount(user.getAccountId());
-            final DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId());
-
-            // Get the CIDRs from where this account is allowed to make calls
-            final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s","");
-            final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
-
-            if (ApiSourceCidrChecksEnabled) {
-                s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs);
-
-                // Block when is not in the list of allowed IPs
-                if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) {
-                    s_logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replaceAll("/","")
-                            + " does not match " + accessAllowedCidrs);
-                    throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip "
-                            + loginIpAddress.toString().replaceAll("/","") + "; please provide valid credentials");
-                }
-            }
-
-            // Here all is fine!
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
-            }
-
-            ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
-                    "user has logged in from IP Address " + loginIpAddress);
-
-            return user;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("User: " + username + " in domain " + domainId + " has failed to log in");
-            }
-            return null;
-        }
-    }
-
-    private UserAccount getUserAccount(String username, String password, Long domainId, Map<String, Object[]> requestParameters) {
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Attempting to log in user: " + username + " in domain " + domainId);
-        }
-        UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
-
-        boolean authenticated = false;
-        HashSet<ActionOnFailedAuthentication> actionsOnFailedAuthenticaion = new HashSet<ActionOnFailedAuthentication>();
-        User.Source userSource = userAccount != null ? userAccount.getSource() : User.Source.UNKNOWN;
-        for (UserAuthenticator authenticator : _userAuthenticators) {
-            if (userSource != User.Source.UNKNOWN) {
-                if (!authenticator.getName().equalsIgnoreCase(userSource.name())) {
-                    continue;
-                }
-            }
-            Pair<Boolean, ActionOnFailedAuthentication> result = authenticator.authenticate(username, password, domainId, requestParameters);
-            if (result.first()) {
-                authenticated = true;
-                break;
-            } else if (result.second() != null) {
-                actionsOnFailedAuthenticaion.add(result.second());
-            }
-        }
-
-        boolean updateIncorrectLoginCount = actionsOnFailedAuthenticaion.contains(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
-
-        if (authenticated) {
-
-            Domain domain = _domainMgr.getDomain(domainId);
-            String domainName = null;
-            if (domain != null) {
-                domainName = domain.getName();
-            }
-            userAccount = _userAccountDao.getUserAccount(username, domainId);
-
-            if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
-                }
-                throw new CloudAuthenticationException(
-                        "User " + username + " (or their account) in domain " + domainName + " is disabled/locked. Please contact the administrator.");
-            }
-            // Whenever the user is able to log in successfully, reset the login attempts to zero
-            if (!isInternalAccount(userAccount.getId()))
-                updateLoginAttempts(userAccount.getId(), 0, false);
-
-            return userAccount;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to authenticate user with username " + username + " in domain " + domainId);
-            }
-
-            if (userAccount == null) {
-                s_logger.warn("Unable to find an user with username " + username + " in domain " + domainId);
-                return null;
-            }
-
-            if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) {
-                if (!isInternalAccount(userAccount.getId())) {
-                    // Internal accounts are not disabled
-                    int attemptsMade = userAccount.getLoginAttempts() + 1;
-                    if (updateIncorrectLoginCount) {
-                        if (attemptsMade < _allowedLoginAttempts) {
-                            updateLoginAttempts(userAccount.getId(), attemptsMade, false);
-                            s_logger.warn("Login attempt failed. You have " + (_allowedLoginAttempts - attemptsMade) + " attempt(s) remaining");
-                        } else {
-                            updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts, true);
-                            s_logger.warn("User " + userAccount.getUsername() + " has been disabled due to multiple failed login attempts." + " Please contact admin.");
-                        }
-                    }
-                }
-            } else {
-                s_logger.info("User " + userAccount.getUsername() + " is disabled/locked");
-            }
-            return null;
-        }
-    }
-
-    @Override
-    public Pair<User, Account> findUserByApiKey(String apiKey) {
-        return _accountDao.findUserAccountByApiKey(apiKey);
-    }
-
-    @Override
-    public Map<String, String> getKeys(GetUserKeysCmd cmd) {
-        final long userId = cmd.getID();
-
-        User user = getActiveUser(userId);
-        if (user == null) {
-            throw new InvalidParameterValueException("Unable to find user by id");
-        }
-        final ControlledEntity account = getAccount(getUserAccountById(userId).getAccountId()); //Extracting the Account from the userID of the requested user.
-        checkAccess(CallContext.current().getCallingUser(), account);
-
-        Map<String, String> keys = new HashMap<String, String>();
-        keys.put("apikey", user.getApiKey());
-        keys.put("secretkey", user.getSecretKey());
-
-        return keys;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
-    public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        final Long userId = cmd.getId();
-
-        User user = getUserIncludingRemoved(userId);
-        if (user == null) {
-            throw new InvalidParameterValueException("unable to find user by id");
-        }
-
-        Account account = _accountDao.findById(user.getAccountId());
-        checkAccess(caller, null, true, account);
-
-        // don't allow updating system user
-        if (user.getId() == User.UID_SYSTEM) {
-            throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed");
-        }
-        // don't allow baremetal system user
-        if (BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME.equals(user.getUsername())) {
-            throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed");
-        }
-
-        // generate both an api key and a secret key, update the user table with the keys, return the keys to the user
-        final String[] keys = new String[2];
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                keys[0] = createUserApiKey(userId);
-                keys[1] = createUserSecretKey(userId);
-            }
-        });
-
-        return keys;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
-    public String[] createApiKeyAndSecretKey(final long userId) {
-        User user = getUserIncludingRemoved(userId);
-        if (user == null) {
-            throw new InvalidParameterValueException("Unable to find user by id");
-        }
-        final String[] keys = new String[2];
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                keys[0] = AccountManagerImpl.this.createUserApiKey(userId);
-                keys[1] = AccountManagerImpl.this.createUserSecretKey(userId);
-            }
-        });
-        return keys;
-    }
-
-    private String createUserApiKey(long userId) {
-        try {
-            UserVO updatedUser = _userDao.createForUpdate();
-
-            String encodedKey = null;
-            Pair<User, Account> userAcct = null;
-            int retryLimit = 10;
-            do {
-                // FIXME: what algorithm should we use for API keys?
-                KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
-                SecretKey key = generator.generateKey();
-                encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
-                userAcct = _accountDao.findUserAccountByApiKey(encodedKey);
-                retryLimit--;
-            } while ((userAcct != null) && (retryLimit >= 0));
-
-            if (userAcct != null) {
-                return null;
-            }
-            updatedUser.setApiKey(encodedKey);
-            _userDao.update(userId, updatedUser);
-            return encodedKey;
-        } catch (NoSuchAlgorithmException ex) {
-            s_logger.error("error generating secret key for user id=" + userId, ex);
-        }
-        return null;
-    }
-
-    private String createUserSecretKey(long userId) {
-        try {
-            UserVO updatedUser = _userDao.createForUpdate();
-            String encodedKey = null;
-            int retryLimit = 10;
-            UserVO userBySecretKey = null;
-            do {
-                KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
-                SecretKey key = generator.generateKey();
-                encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
-                userBySecretKey = _userDao.findUserBySecretKey(encodedKey);
-                retryLimit--;
-            } while ((userBySecretKey != null) && (retryLimit >= 0));
-
-            if (userBySecretKey != null) {
-                return null;
-            }
-
-            updatedUser.setSecretKey(encodedKey);
-            _userDao.update(userId, updatedUser);
-            return encodedKey;
-        } catch (NoSuchAlgorithmException ex) {
-            s_logger.error("error generating secret key for user id=" + userId, ex);
-        }
-        return null;
-    }
-
-    @Override
-    public void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-
-        if (sb.entity() instanceof IPAddressVO) {
-            sb.and("accountIdIN", ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN);
-            sb.and("domainId", ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.EQ);
-        } else if (sb.entity() instanceof ProjectInvitationVO) {
-            sb.and("accountIdIN", ((ProjectInvitationVO)sb.entity()).getForAccountId(), SearchCriteria.Op.IN);
-            sb.and("domainId", ((ProjectInvitationVO)sb.entity()).getInDomainId(), SearchCriteria.Op.EQ);
-        } else {
-            sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
-            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-        }
-
-        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
-            // if accountId isn't specified, we can do a domain match for the admin case if isRecursive is true
-            SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
-            domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
-
-            if (sb.entity() instanceof IPAddressVO) {
-                sb.join("domainSearch", domainSearch, ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            } else if (sb.entity() instanceof ProjectInvitationVO) {
-                sb.join("domainSearch", domainSearch, ((ProjectInvitationVO)sb.entity()).getInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            } else {
-                sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            }
-
-        }
-        if (listProjectResourcesCriteria != null) {
-            SearchBuilder<AccountVO> accountSearch = _accountDao.createSearchBuilder();
-            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
-                accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.EQ);
-            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
-                accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.NEQ);
-            }
-
-            if (sb.entity() instanceof IPAddressVO) {
-                sb.join("accountSearch", accountSearch, ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            } else if (sb.entity() instanceof ProjectInvitationVO) {
-                sb.join("accountSearch", accountSearch, ((ProjectInvitationVO)sb.entity()).getForAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            } else {
-                sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
-            }
-        }
-    }
-
-    @Override
-    public void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-
-        if (listProjectResourcesCriteria != null) {
-            sc.setJoinParameters("accountSearch", "type", Account.ACCOUNT_TYPE_PROJECT);
-        }
-
-        if (!permittedAccounts.isEmpty()) {
-            sc.setParameters("accountIdIN", permittedAccounts.toArray());
-        } else if (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            if (isRecursive) {
-                sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
-            } else {
-                sc.setParameters("domainId", domainId);
-            }
-        }
-    }
-
-    //TODO: deprecate this to use the new buildACLSearchParameters with permittedDomains, permittedAccounts, and permittedResources as return
-    @Override
-    public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts,
-            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) {
-        Long domainId = domainIdRecursiveListProject.first();
-        if (domainId != null) {
-            Domain domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
-            }
-            // check permissions
-            checkAccess(caller, domain);
-        }
-
-        if (accountName != null) {
-            if (projectId != null) {
-                throw new InvalidParameterValueException("Account and projectId can't be specified together");
-            }
-
-            Account userAccount = null;
-            Domain domain = null;
-            if (domainId != null) {
-                userAccount = _accountDao.findActiveAccount(accountName, domainId);
-                domain = _domainDao.findById(domainId);
-            } else {
-                userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId());
-                domain = _domainDao.findById(caller.getDomainId());
-            }
-
-            if (userAccount != null) {
-                checkAccess(caller, null, false, userAccount);
-                // check permissions
-                permittedAccounts.add(userAccount.getId());
-            } else {
-                throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid());
-            }
-        }
-
-        // set project information
-        if (projectId != null) {
-            if (!forProjectInvitation) {
-                if (projectId.longValue() == -1) {
-                    if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                        permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
-
-                        //permittedAccounts can be empty when the caller is not a part of any project (a domain account)
-                        if (permittedAccounts.isEmpty()) {
-                            permittedAccounts.add(caller.getId());
-                        }
-                    } else {
-                        domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly);
-                    }
-                } else {
-                    Project project = _projectMgr.getProject(projectId);
-                    if (project == null) {
-                        throw new InvalidParameterValueException("Unable to find project by id " + projectId);
-                    }
-                    if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
-                        throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId);
-                    }
-                    permittedAccounts.add(project.getProjectAccountId());
-                }
-            }
-        } else {
-            if (id == null) {
-                domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
-            }
-            if (permittedAccounts.isEmpty() && domainId == null) {
-                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                    permittedAccounts.add(caller.getId());
-                } else if (!listAll) {
-                    if (id == null) {
-                        permittedAccounts.add(caller.getId());
-                    } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-                        domainIdRecursiveListProject.first(caller.getDomainId());
-                        domainIdRecursiveListProject.second(true);
-                    }
-                } else if (domainId == null) {
-                    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
-                        domainIdRecursiveListProject.first(caller.getDomainId());
-                        domainIdRecursiveListProject.second(true);
-                    }
-                }
-            } else if (domainId != null) {
-                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
-                    permittedAccounts.add(caller.getId());
-                }
-            }
-
-        }
-
-    }
-
-    @Override
-    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-
-        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
-        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
-
-        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
-            // if accountId isn't specified, we can do a domain match for the
-            // admin case if isRecursive is true
-            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
-        }
-
-        if (listProjectResourcesCriteria != null) {
-            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
-                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
-            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
-                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
-            }
-        }
-
-    }
-
-    @Override
-    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        if (listProjectResourcesCriteria != null) {
-            sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT);
-        }
-
-        if (!permittedAccounts.isEmpty()) {
-            sc.setParameters("accountIdIN", permittedAccounts.toArray());
-        } else if (domainId != null) {
-            DomainVO domain = _domainDao.findById(domainId);
-            if (isRecursive) {
-                sc.setParameters("domainPath", domain.getPath() + "%");
-            } else {
-                sc.setParameters("domainId", domainId);
-            }
-        }
-
-    }
-
-    @Override
-    public UserAccount getUserByApiKey(String apiKey) {
-        return _userAccountDao.getUserByApiKey(apiKey);
-    }
-
-    @Override
-    public List<String> listAclGroupsByAccount(Long accountId) {
-        if (_querySelectors == null || _querySelectors.size() == 0)
-            return new ArrayList<String>();
-
-        QuerySelector qs = _querySelectors.get(0);
-        return qs.listAclGroupsByAccount(accountId);
-    }
-
-    @Override
-    public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
-        if (accountName != null) {
-            if (domainId == null) {
-                throw new InvalidParameterValueException("Account must be specified with domainId parameter");
-            }
-
-            final Domain domain = _domainMgr.getDomain(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Unable to find domain by id");
-            }
-
-            final Account account = getActiveAccountByName(accountName, domainId);
-            if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
-                if (!enabledOnly || account.getState() == Account.State.enabled) {
-                    return account.getId();
-                } else {
-                    throw new PermissionDeniedException(
-                            "Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active");
-                }
-            } else {
-                // idList is not used anywhere, so removed it now
-                // List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
-                // idList.add(new IdentityProxy("domain", domainId, "domainId"));
-                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id");
-            }
-        }
-
-        if (projectId != null) {
-            final Project project = _projectMgr.getProject(projectId);
-            if (project != null) {
-                if (!enabledOnly || project.getState() == Project.State.Active) {
-                    return project.getProjectAccountId();
-                } else {
-                    final PermissionDeniedException ex = new PermissionDeniedException(
-                            "Can't add resources to the project with specified projectId in state=" + project.getState() + " as it's no longer active");
-                    ex.addProxyObject(project.getUuid(), "projectId");
-                    throw ex;
-                }
-            } else {
-                throw new InvalidParameterValueException("Unable to find project by id");
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public UserAccount getUserAccountById(Long userId) {
-        return _userAccountDao.findById(userId);
-    }
-
-    @Override
-    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
-        for (SecurityChecker checker : _securityCheckers) {
-            if (checker.checkAccess(account, so)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + account + " to " + so + " by " + checker.getName());
-                }
-                return;
-            }
-        }
-
-        assert false : "How can all of the security checkers pass on checking this caller?";
-        throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + so);
-    }
-
-    @Override
-    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
-        for (SecurityChecker checker : _securityCheckers) {
-            if (checker.checkAccess(account, dof)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + account + " to " + dof + " by " + checker.getName());
-                }
-                return;
-            }
-        }
-
-        assert false : "How can all of the security checkers pass on checking this caller?";
-        throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + dof);
-    }
-
-    @Override
-    public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
-        for (SecurityChecker checker : _securityCheckers) {
-            if (checker.checkAccess(user, entity)) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Access granted to " + user + "to " + entity + "by " + checker.getName());
-                }
-                return;
-            }
-        }
-        throw new PermissionDeniedException("There's no way to confirm " + user + " has access to " + entity);
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return AccountManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {UseSecretKeyInResponse};
-    }
-}
diff --git a/server/src/com/cloud/uuididentity/UUIDManagerImpl.java b/server/src/com/cloud/uuididentity/UUIDManagerImpl.java
deleted file mode 100644
index 5a6275f..0000000
--- a/server/src/com/cloud/uuididentity/UUIDManagerImpl.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.uuididentity;
-
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.UUIDManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class UUIDManagerImpl implements UUIDManager {
-
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    AccountManager _accountMgr;
-    //TODO - Make this configurable.
-    private static final int UUID_RETRY = 3;
-
-    @Override
-    public <T> void checkUuid(String uuid, Class<T> entityType) {
-
-        if (uuid == null) {
-            return;
-        }
-
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Only admin and system allowed to do this
-        if (!(caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId()))) {
-            throw new PermissionDeniedException("Please check your permissions, you are not allowed to create/update custom id");
-        }
-
-        checkUuidSimple(uuid, entityType);
-    }
-
-    @Override
-    public <T> void checkUuidSimple(String uuid, Class<T> entityType) {
-
-        if (uuid == null) {
-            return;
-        }
-
-        // check format
-        if (!IsUuidFormat(uuid)) {
-            throw new InvalidParameterValueException("UUID: " + uuid + " doesn't follow the UUID format");
-        }
-
-        // check unique
-        if (!IsUuidUnique(entityType, uuid)) {
-            throw new InvalidParameterValueException("UUID: " + uuid + " already exists so can't create/update with custom id");
-        }
-
-    }
-
-    public boolean IsUuidFormat(String uuid) {
-
-        // Match against UUID regex to check if input is uuid string
-        boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
-        return isUuid;
-    }
-
-    public <T> boolean IsUuidUnique(Class<T> entityType, String uuid) {
-
-        T obj = _entityMgr.findByUuid(entityType, uuid);
-        if (obj != null) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    @Override
-    public <T> String generateUuid(Class<T> entityType, String customId) {
-
-        if (customId == null) { // if no customid is passed then generate it.
-            int retry = UUID_RETRY;
-            while (retry-- != 0) {  // there might be collision so retry
-                String uuid = UUID.randomUUID().toString();
-                if (IsUuidUnique(entityType, uuid)) {
-                    return uuid;
-                }
-            }
-
-            throw new CloudRuntimeException("Unable to generate a unique uuid, please try again");
-        } else {
-            checkUuid(customId, entityType);
-            return customId;
-        }
-    }
-
-}
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
deleted file mode 100644
index 5e0bb1b..0000000
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ /dev/null
@@ -1,6461 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vm;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.affinity.AffinityGroupService;
-import org.apache.cloudstack.affinity.AffinityGroupVO;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
-import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
-import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
-import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
-import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
-import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
-import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
-import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
-import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
-import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
-import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
-import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
-import org.apache.cloudstack.api.command.user.vm.SecurityGroupAction;
-import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
-import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
-import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
-import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
-import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
-import org.apache.cloudstack.engine.service.api.OrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.GetVmDiskStatsAnswer;
-import com.cloud.agent.api.GetVmDiskStatsCommand;
-import com.cloud.agent.api.GetVmIpAddressCommand;
-import com.cloud.agent.api.GetVmNetworkStatsAnswer;
-import com.cloud.agent.api.GetVmNetworkStatsCommand;
-import com.cloud.agent.api.GetVmStatsAnswer;
-import com.cloud.agent.api.GetVmStatsCommand;
-import com.cloud.agent.api.GetVolumeStatsAnswer;
-import com.cloud.agent.api.GetVolumeStatsCommand;
-import com.cloud.agent.api.ModifyTargetsCommand;
-import com.cloud.agent.api.PvlanSetupCommand;
-import com.cloud.agent.api.RestoreVMSnapshotAnswer;
-import com.cloud.agent.api.RestoreVMSnapshotCommand;
-import com.cloud.agent.api.StartAnswer;
-import com.cloud.agent.api.VmDiskStatsEntry;
-import com.cloud.agent.api.VmNetworkStatsEntry;
-import com.cloud.agent.api.VmStatsEntry;
-import com.cloud.agent.api.VolumeStatsEntry;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.Capacity;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.DedicatedResourceVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Vlan;
-import com.cloud.dc.Vlan.VlanType;
-import com.cloud.dc.VlanVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlanner;
-import com.cloud.deploy.DeploymentPlanner.ExcludeList;
-import com.cloud.deploy.DeploymentPlanningManager;
-import com.cloud.deploy.PlannerHostReservationVO;
-import com.cloud.deploy.dao.PlannerHostReservationDao;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.UsageEventVO;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.CloudException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ManagementServerException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.exception.VirtualMachineMigrationException;
-import com.cloud.gpu.GPU;
-import com.cloud.ha.HighAvailabilityManager;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.LoadBalancerVMMapVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.network.rules.PortForwardingRuleVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.network.security.SecurityGroup;
-import com.cloud.network.security.SecurityGroupManager;
-import com.cloud.network.security.dao.SecurityGroupDao;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.org.Cluster;
-import com.cloud.org.Grouping;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceState;
-import com.cloud.server.ManagementService;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.GuestOSCategoryVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeApiService;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.template.TemplateApiService;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.SSHKeyPair;
-import com.cloud.user.SSHKeyPairVO;
-import com.cloud.user.User;
-import com.cloud.user.UserStatisticsVO;
-import com.cloud.user.UserVO;
-import com.cloud.user.VmDiskStatisticsVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.SSHKeyPairDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.user.dao.VmDiskStatisticsDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.Journal;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.crypt.RSAHelper;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithException;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.db.UUIDManager;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.exception.ExecutionException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.InstanceGroupDao;
-import com.cloud.vm.dao.InstanceGroupVMMapDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicExtraDhcpOptionDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import com.google.common.base.Strings;
-
-
-public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable {
-    private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
-
-    /**
-     * The number of seconds to wait before timing out when trying to acquire a global lock.
-     */
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3;
-
-    private static final long GiB_TO_BYTES = 1024 * 1024 * 1024;
-
-    @Inject
-    private EntityManager _entityMgr;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private ServiceOfferingDao _offeringDao;
-    @Inject
-    private DiskOfferingDao _diskOfferingDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private VMTemplateZoneDao _templateZoneDao;
-    @Inject
-    private TemplateDataStoreDao _templateStoreDao;
-    @Inject
-    private DomainDao _domainDao;
-    @Inject
-    private UserVmDao _vmDao;
-    @Inject
-    private VolumeDao _volsDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private FirewallRulesDao _rulesDao;
-    @Inject
-    private LoadBalancerVMMapDao _loadBalancerVMMapDao;
-    @Inject
-    private PortForwardingRulesDao _portForwardingDao;
-    @Inject
-    private IPAddressDao _ipAddressDao;
-    @Inject
-    private HostPodDao _podDao;
-    @Inject
-    private NetworkModel _networkModel;
-    @Inject
-    private NetworkOrchestrationService _networkMgr;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    private ConfigurationManager _configMgr;
-    @Inject
-    private AccountDao _accountDao;
-    @Inject
-    private UserDao _userDao;
-    @Inject
-    private SnapshotDao _snapshotDao;
-    @Inject
-    private GuestOSDao _guestOSDao;
-    @Inject
-    private HighAvailabilityManager _haMgr;
-    @Inject
-    private AlertManager _alertMgr;
-    @Inject
-    private AccountManager _accountMgr;
-    @Inject
-    private AccountService _accountService;
-    @Inject
-    private ClusterDao _clusterDao;
-    @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-    @Inject
-    private SecurityGroupManager _securityGroupMgr;
-    @Inject
-    private ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    private NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    private InstanceGroupDao _vmGroupDao;
-    @Inject
-    private InstanceGroupVMMapDao _groupVMMapDao;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    private NetworkDao _networkDao;
-    @Inject
-    private NicDao _nicDao;
-    @Inject
-    private RulesManager _rulesMgr;
-    @Inject
-    private LoadBalancingRulesManager _lbMgr;
-    @Inject
-    private SSHKeyPairDao _sshKeyPairDao;
-    @Inject
-    private UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject
-    private SecurityGroupDao _securityGroupDao;
-    @Inject
-    private CapacityManager _capacityMgr;
-    @Inject
-    private VMInstanceDao _vmInstanceDao;
-    @Inject
-    private ResourceLimitService _resourceLimitMgr;
-    @Inject
-    private FirewallManager _firewallMgr;
-    @Inject
-    private ResourceManager _resourceMgr;
-    @Inject
-    private NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    private PhysicalNetworkDao _physicalNetworkDao;
-    @Inject
-    private VpcManager _vpcMgr;
-    @Inject
-    private TemplateManager _templateMgr;
-    @Inject
-    private GuestOSCategoryDao _guestOSCategoryDao;
-    @Inject
-    private UsageEventDao _usageEventDao;
-    @Inject
-    private VmDiskStatisticsDao _vmDiskStatsDao;
-    @Inject
-    private VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    private VMSnapshotManager _vmSnapshotMgr;
-    @Inject
-    private AffinityGroupVMMapDao _affinityGroupVMMapDao;
-    @Inject
-    private AffinityGroupDao _affinityGroupDao;
-    @Inject
-    private DedicatedResourceDao _dedicatedDao;
-    @Inject
-    private AffinityGroupService _affinityGroupService;
-    @Inject
-    private PlannerHostReservationDao _plannerHostReservationDao;
-    @Inject
-    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
-    @Inject
-    private UserStatisticsDao _userStatsDao;
-    @Inject
-    private VlanDao _vlanDao;
-    @Inject
-    private VolumeService _volService;
-    @Inject
-    private VolumeDataFactory volFactory;
-    @Inject
-    private UserVmDetailsDao _uservmDetailsDao;
-    @Inject
-    private UUIDManager _uuidMgr;
-    @Inject
-    private DeploymentPlanningManager _planningMgr;
-    @Inject
-    private VolumeApiService _volumeService;
-    @Inject
-    private DataStoreManager _dataStoreMgr;
-    @Inject
-    private VpcVirtualNetworkApplianceManager _virtualNetAppliance;
-    @Inject
-    private DomainRouterDao _routerDao;
-    @Inject
-    private VMNetworkMapDao _vmNetworkMapDao;
-    @Inject
-    private IpAddressManager _ipAddrMgr;
-    @Inject
-    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
-    @Inject
-    private TemplateApiService _tmplService;
-    @Inject
-    private ConfigurationDao _configDao;
-
-    private ScheduledExecutorService _executor = null;
-    private ScheduledExecutorService _vmIpFetchExecutor = null;
-    private int _expungeInterval;
-    private int _expungeDelay;
-    private boolean _dailyOrHourly = false;
-    private int capacityReleaseInterval;
-    private ExecutorService _vmIpFetchThreadExecutor;
-
-
-    private String _instance;
-    private boolean _instanceNameFlag;
-    private int _scaleRetry;
-    private Map<Long, VmAndCountDetails> vmIdCountMap = new ConcurrentHashMap<>();
-
-    private static final int MAX_HTTP_GET_LENGTH = 2 * MAX_USER_DATA_LENGTH_BYTES;
-    private static final int MAX_HTTP_POST_LENGTH = 16 * MAX_USER_DATA_LENGTH_BYTES;
-
-    @Inject
-    private OrchestrationService _orchSrvc;
-
-    @Inject
-    private VolumeOrchestrationService volumeMgr;
-
-    @Inject
-    private ManagementService _mgr;
-
-    private static final ConfigKey<Integer> VmIpFetchWaitInterval = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.retrieval.interval", "180",
-            "Wait Interval (in seconds) for shared network vm dhcp ip addr fetch for next iteration ", true);
-
-    private static final ConfigKey<Integer> VmIpFetchTrialMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.max.retry", "10",
-            "The max number of retrieval times for shared entwork vm dhcp ip fetch, in case of failures", true);
-
-    private static final ConfigKey<Integer> VmIpFetchThreadPoolMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipFetch.threadPool.max", "10",
-            "number of threads for fetching vms ip address", true);
-
-    private static final ConfigKey<Integer> VmIpFetchTaskWorkers = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipfetchtask.workers", "10",
-            "number of worker threads for vm ip fetch task ", true);
-
-    private static final ConfigKey<Boolean> AllowDeployVmIfGivenHostFails = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.deploy.vm.if.deploy.on.given.host.fails", "false",
-            "allow vm to deploy on different host if vm fails to deploy on the given host ", true);
-
-
-    @Override
-    public UserVmVO getVirtualMachine(long vmId) {
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public List<? extends UserVm> getVirtualMachines(long hostId) {
-        return _vmDao.listByHostId(hostId);
-    }
-
-    private void resourceLimitCheck(Account owner, Boolean displayVm, Long cpu, Long memory) throws ResourceAllocationException {
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm, displayVm);
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, displayVm, cpu);
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, displayVm, memory);
-    }
-
-    private void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
-        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
-        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
-        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
-    }
-
-    private void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
-        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
-        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
-        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
-    }
-
-    public class VmAndCountDetails {
-        long vmId;
-        int  retrievalCount = VmIpFetchTrialMax.value();
-
-
-        public VmAndCountDetails() {
-        }
-
-        public VmAndCountDetails (long vmId, int retrievalCount) {
-            this.vmId = vmId;
-            this.retrievalCount = retrievalCount;
-        }
-
-        public VmAndCountDetails (long vmId) {
-            this.vmId = vmId;
-        }
-
-        public int getRetrievalCount() {
-            return retrievalCount;
-        }
-
-        public void setRetrievalCount(int retrievalCount) {
-            this.retrievalCount = retrievalCount;
-        }
-
-        public long getVmId() {
-            return vmId;
-        }
-
-        public void setVmId(long vmId) {
-            this.vmId = vmId;
-        }
-
-        public void decrementCount() {
-            this.retrievalCount--;
-
-        }
-    }
-
-    private class VmIpAddrFetchThread extends ManagedContextRunnable {
-
-
-        long nicId;
-        long vmId;
-        String vmName;
-        boolean isWindows;
-        Long hostId;
-        String networkCidr;
-
-        public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
-            this.vmId = vmId;
-            this.nicId = nicId;
-            this.vmName = instanceName;
-            this.isWindows = windows;
-            this.hostId = hostId;
-            this.networkCidr = networkCidr;
-        }
-
-        @Override
-        protected void runInContext() {
-            GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
-            boolean decrementCount = true;
-
-            try {
-                s_logger.debug("Trying for vm "+ vmId +" nic Id "+nicId +" ip retrieval ...");
-                Answer answer = _agentMgr.send(hostId, cmd);
-                NicVO nic = _nicDao.findById(nicId);
-                if (answer.getResult()) {
-                    String vmIp = answer.getDetails();
-
-                    if (NetUtils.isValidIp4(vmIp)) {
-                        // set this vm ip addr in vm nic.
-                        if (nic != null) {
-                            nic.setIPv4Address(vmIp);
-                            _nicDao.update(nicId, nic);
-                            s_logger.debug("Vm "+ vmId +" IP "+vmIp +" got retrieved successfully");
-                            vmIdCountMap.remove(nicId);
-                            decrementCount = false;
-                            ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
-                                    Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
-                                    "VM " + vmId + " nic id " + nicId + " ip address " + vmIp + " got fetched successfully");
-                        }
-                    }
-                } else {
-                    //previously vm has ip and nic table has ip address. After vm restart or stop/start
-                    //if vm doesnot get the ip then set the ip in nic table to null
-                    if (nic.getIPv4Address() != null) {
-                        nic.setIPv4Address(null);
-                        _nicDao.update(nicId, nic);
-                    }
-                    if (answer.getDetails() != null) {
-                        s_logger.debug("Failed to get vm ip for Vm "+ vmId + answer.getDetails());
-                    }
-                }
-            } catch (OperationTimedoutException e) {
-                s_logger.warn("Timed Out", e);
-            } catch (AgentUnavailableException e) {
-                s_logger.warn("Agent Unavailable ", e);
-            } finally {
-                if (decrementCount) {
-                    VmAndCountDetails vmAndCount = vmIdCountMap.get(nicId);
-                    vmAndCount.decrementCount();
-                    s_logger.debug("Ip is not retrieved for VM " + vmId +" nic "+nicId + " ... decremented count to "+vmAndCount.getRetrievalCount());
-                    vmIdCountMap.put(nicId, vmAndCount);
-                }
-            }
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_RESETPASSWORD, eventDescription = "resetting Vm password", async = true)
-    public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long vmId = cmd.getId();
-        UserVmVO userVm = _vmDao.findById(cmd.getId());
-
-        // Do parameters input validation
-        if (userVm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + cmd.getId());
-        }
-
-        _vmDao.loadDetails(userVm);
-
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
-        if (template == null || !template.getEnablePassword()) {
-            throw new InvalidParameterValueException("Fail to reset password for the virtual machine, the template is not password enabled");
-        }
-
-        if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
-            s_logger.error("vm is not in the right state: " + vmId);
-            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
-        }
-
-        if (userVm.getState() != State.Stopped) {
-            s_logger.error("vm is not in the right state: " + vmId);
-            throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do password reset");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, userVm);
-
-        boolean result = resetVMPasswordInternal(vmId, password);
-
-        if (result) {
-            userVm.setPassword(password);
-        } else {
-            throw new CloudRuntimeException("Failed to reset password for the virtual machine ");
-        }
-
-        return userVm;
-    }
-
-    private boolean resetVMPasswordInternal(Long vmId, String password) throws ResourceUnavailableException, InsufficientCapacityException {
-        Long userId = CallContext.current().getCallingUserId();
-        VMInstanceVO vmInstance = _vmDao.findById(vmId);
-
-        if (password == null || password.equals("")) {
-            return false;
-        }
-
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
-        if (template.getEnablePassword()) {
-            Nic defaultNic = _networkModel.getDefaultNic(vmId);
-            if (defaultNic == null) {
-                s_logger.error("Unable to reset password for vm " + vmInstance + " as the instance doesn't have default nic");
-                return false;
-            }
-
-            Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
-            NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork),
-                    _networkModel.getNetworkTag(template.getHypervisorType(), defaultNetwork));
-            VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
-            vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
-
-            UserDataServiceProvider element = _networkMgr.getPasswordResetProvider(defaultNetwork);
-            if (element == null) {
-                throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for password reset");
-            }
-
-            boolean result = element.savePassword(defaultNetwork, defaultNicProfile, vmProfile);
-
-            // Need to reboot the virtual machine so that the password gets
-            // redownloaded from the DomR, and reset on the VM
-            if (!result) {
-                s_logger.debug("Failed to reset password for the virtual machine; no need to reboot the vm");
-                return false;
-            } else {
-                final UserVmVO userVm = _vmDao.findById(vmId);
-                _vmDao.loadDetails(userVm);
-                // update the password in vm_details table too
-                // Check if an SSH key pair was selected for the instance and if so
-                // use it to encrypt & save the vm password
-                encryptAndStorePassword(userVm, password);
-
-                if (vmInstance.getState() == State.Stopped) {
-                    s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of password reset");
-                    return true;
-                }
-
-                if (rebootVirtualMachine(userId, vmId) == null) {
-                    s_logger.warn("Failed to reboot the vm " + vmInstance);
-                    return false;
-                } else {
-                    s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of password reset");
-                    return true;
-                }
-            }
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Reset password called for a vm that is not using a password enabled template");
-            }
-            return false;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_RESETSSHKEY, eventDescription = "resetting Vm SSHKey", async = true)
-    public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
-        Long vmId = cmd.getId();
-
-        UserVmVO userVm = _vmDao.findById(cmd.getId());
-        if (userVm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine by id" + cmd.getId());
-        }
-
-        _vmDao.loadDetails(userVm);
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
-
-        // Do parameters input validation
-
-        if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
-            s_logger.error("vm is not in the right state: " + vmId);
-            throw new InvalidParameterValueException("Vm with specified id is not in the right state");
-        }
-        if (userVm.getState() != State.Stopped) {
-            s_logger.error("vm is not in the right state: " + vmId);
-            throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do SSH Key reset");
-        }
-
-        SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
-        if (s == null) {
-            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName()
-            + " in specified domain id");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, userVm);
-        String password = null;
-        String sshPublicKey = s.getPublicKey();
-        if (template != null && template.getEnablePassword()) {
-            password = _mgr.generateRandomPassword();
-        }
-
-        boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password);
-
-        if (!result) {
-            throw new CloudRuntimeException("Failed to reset SSH Key for the virtual machine ");
-        }
-        return userVm;
-    }
-
-    private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String password) throws ResourceUnavailableException, InsufficientCapacityException {
-        Long userId = CallContext.current().getCallingUserId();
-        VMInstanceVO vmInstance = _vmDao.findById(vmId);
-
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
-        Nic defaultNic = _networkModel.getDefaultNic(vmId);
-        if (defaultNic == null) {
-            s_logger.error("Unable to reset SSH Key for vm " + vmInstance + " as the instance doesn't have default nic");
-            return false;
-        }
-
-        Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
-        NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork),
-                _networkModel.getNetworkTag(template.getHypervisorType(), defaultNetwork));
-
-        VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
-
-        if (template.getEnablePassword()) {
-            vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
-        }
-
-        UserDataServiceProvider element = _networkMgr.getSSHKeyResetProvider(defaultNetwork);
-        if (element == null) {
-            throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for SSH Key reset");
-        }
-        boolean result = element.saveSSHKey(defaultNetwork, defaultNicProfile, vmProfile, sshPublicKey);
-
-        // Need to reboot the virtual machine so that the password gets redownloaded from the DomR, and reset on the VM
-        if (!result) {
-            s_logger.debug("Failed to reset SSH Key for the virtual machine; no need to reboot the vm");
-            return false;
-        } else {
-            final UserVmVO userVm = _vmDao.findById(vmId);
-            _vmDao.loadDetails(userVm);
-            userVm.setDetail("SSH.PublicKey", sshPublicKey);
-            if (template.getEnablePassword()) {
-                userVm.setPassword(password);
-                //update the encrypted password in vm_details table too
-                encryptAndStorePassword(userVm, password);
-            } else {
-                _vmDao.saveDetails(userVm);
-            }
-
-            if (vmInstance.getState() == State.Stopped) {
-                s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of SSH Key reset");
-                return true;
-            }
-            if (rebootVirtualMachine(userId, vmId) == null) {
-                s_logger.warn("Failed to reboot the vm " + vmInstance);
-                return false;
-            } else {
-                s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of SSH Key reset");
-                return true;
-            }
-        }
-    }
-
-    @Override
-    public boolean stopVirtualMachine(long userId, long vmId) {
-        boolean status = false;
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Stopping vm=" + vmId);
-        }
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null || vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is either removed or deleted.");
-            }
-            return true;
-        }
-
-        _userDao.findById(userId);
-        try {
-            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
-            status = vmEntity.stop(Long.toString(userId));
-        } catch (ResourceUnavailableException e) {
-            s_logger.debug("Unable to stop due to ", e);
-            status = false;
-        } catch (CloudException e) {
-            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
-        }
-        return status;
-    }
-
-    private UserVm rebootVirtualMachine(long userId, long vmId) throws InsufficientCapacityException, ResourceUnavailableException {
-        UserVmVO vm = _vmDao.findById(vmId);
-
-        if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
-            s_logger.warn("Vm id=" + vmId + " doesn't exist");
-            return null;
-        }
-
-        if (vm.getState() == State.Running && vm.getHostId() != null) {
-            collectVmDiskStatistics(vm);
-            collectVmNetworkStatistics(vm);
-            DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
-            try {
-                if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
-                    //List all networks of vm
-                    List<Long> vmNetworks = _vmNetworkMapDao.getNetworks(vmId);
-                    List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>();
-                    //List the stopped routers
-                    for(long vmNetworkId : vmNetworks) {
-                        List<DomainRouterVO> router = _routerDao.listStopped(vmNetworkId);
-                        routers.addAll(router);
-                    }
-                    //A vm may not have many nics attached and even fewer routers might be stopped (only in exceptional cases)
-                    //Safe to start the stopped router serially, this is consistent with the way how multiple networks are added to vm during deploy
-                    //and routers are started serially ,may revisit to make this process parallel
-                    for(DomainRouterVO routerToStart : routers) {
-                        s_logger.warn("Trying to start router " + routerToStart.getInstanceName() + " as part of vm: " + vm.getInstanceName() + " reboot");
-                        _virtualNetAppliance.startRouter(routerToStart.getId(),true);
-                    }
-                }
-            } catch (ConcurrentOperationException e) {
-                throw new CloudRuntimeException("Concurrent operations on starting router. " + e);
-            } catch (Exception ex){
-                throw new CloudRuntimeException("Router start failed due to" + ex);
-            }finally {
-                s_logger.info("Rebooting vm " + vm.getInstanceName());
-                _itMgr.reboot(vm.getUuid(), null);
-            }
-            return _vmDao.findById(vmId);
-        } else {
-            s_logger.error("Vm id=" + vmId + " is not in Running state, failed to reboot");
-            return null;
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "upgrading Vm")
-    /*
-     * TODO: cleanup eventually - Refactored API call
-     */
-    // This method will be deprecated as we use ScaleVMCmd for both stopped VMs and running VMs
-    public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException {
-        Long vmId = cmd.getId();
-        Long svcOffId = cmd.getServiceOfferingId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Verify input parameters
-        //UserVmVO vmInstance = _vmDao.findById(vmId);
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        } else if (!(vmInstance.getState().equals(State.Stopped))) {
-            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState()
-            + "; make sure the virtual machine is stopped");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Check resource limits for CPU and Memory.
-        Map<String, String> customParameters = cmd.getDetails();
-        ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
-        if (newServiceOffering.isDynamic()) {
-            newServiceOffering.setDynamicFlag(true);
-            validateCustomParameters(newServiceOffering, cmd.getDetails());
-            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
-        }
-        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
-
-        int newCpu = newServiceOffering.getCpu();
-        int newMemory = newServiceOffering.getRamSize();
-        int currentCpu = currentServiceOffering.getCpu();
-        int currentMemory = currentServiceOffering.getRamSize();
-
-        if (newCpu > currentCpu) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
-        }
-        if (newMemory > currentMemory) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
-        }
-
-        // Check that the specified service offering ID is valid
-        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
-
-        _itMgr.upgradeVmDb(vmId, svcOffId);
-        if (newServiceOffering.isDynamic()) {
-            //save the custom values to the database.
-            saveCustomOfferingDetails(vmId, newServiceOffering);
-        }
-        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
-            removeCustomOfferingDetails(vmId);
-        }
-
-        // Increment or decrement CPU and Memory count accordingly.
-        if (newCpu > currentCpu) {
-            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
-        } else if (currentCpu > newCpu) {
-            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
-        }
-        if (newMemory > currentMemory) {
-            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
-        } else if (currentMemory > newMemory) {
-            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
-        }
-
-        // Generate usage event for VM upgrade
-        UserVmVO userVm = _vmDao.findById(vmId);
-        generateUsageEvent( userVm, userVm.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
-
-        return userVm;
-    }
-
-    @Override
-    public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
-        if (customParameters.size() != 0) {
-            if (serviceOffering.getCpu() == null) {
-                String cpuNumber = customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name());
-                if ((cpuNumber == null) || (NumbersUtil.parseInt(cpuNumber, -1) <= 0)) {
-                    throw new InvalidParameterValueException("Invalid cpu cores value, specify a value between 1 and " + Integer.MAX_VALUE);
-                }
-            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
-                throw new InvalidParameterValueException("The cpu cores of this offering id:" + serviceOffering.getId()
-                + " is not customizable. This is predefined in the template.");
-            }
-
-            if (serviceOffering.getSpeed() == null) {
-                String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name());
-                if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) {
-                    throw new InvalidParameterValueException("Invalid cpu speed value, specify a value between 1 and " + Integer.MAX_VALUE);
-                }
-            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
-                throw new InvalidParameterValueException("The cpu speed of this offering id:" + serviceOffering.getId()
-                + " is not customizable. This is predefined in the template.");
-            }
-
-            if (serviceOffering.getRamSize() == null) {
-                String memory = customParameters.get(UsageEventVO.DynamicParameters.memory.name());
-                if (memory == null || (NumbersUtil.parseInt(memory, -1) < 32)) {
-                    throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and " + Integer.MAX_VALUE + " MB");
-                }
-            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
-                throw new InvalidParameterValueException("The memory of this offering id:" + serviceOffering.getId() + " is not customizable. This is predefined in the template.");
-            }
-        } else {
-            throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering");
-        }
-    }
-
-    private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map<String, String> customParameters) throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Verify input parameters
-        //UserVmVO vmInstance = _vmDao.findById(vmId);
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Check resource limits for CPU and Memory.
-        ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
-        if (newServiceOffering.isDynamic()) {
-            newServiceOffering.setDynamicFlag(true);
-            validateCustomParameters(newServiceOffering, customParameters);
-            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
-        }
-        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
-
-        int newCpu = newServiceOffering.getCpu();
-        int newMemory = newServiceOffering.getRamSize();
-        int currentCpu = currentServiceOffering.getCpu();
-        int currentMemory = currentServiceOffering.getRamSize();
-
-        if (newCpu > currentCpu) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
-        }
-        if (newMemory > currentMemory) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
-        }
-
-        // Check that the specified service offering ID is valid
-        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
-
-        DiskOfferingVO newROOTDiskOffering = _diskOfferingDao.findById(newServiceOffering.getId());
-
-        List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vmInstance.getId());
-
-        for (final VolumeVO rootVolumeOfVm : vols) {
-            rootVolumeOfVm.setDiskOfferingId(newROOTDiskOffering.getId());
-
-            _volsDao.update(rootVolumeOfVm.getId(), rootVolumeOfVm);
-
-            ResizeVolumeCmd resizeVolumeCmd = new ResizeVolumeCmd(rootVolumeOfVm.getId(), newROOTDiskOffering.getMinIops(), newROOTDiskOffering.getMaxIops());
-
-            _volumeService.resizeVolume(resizeVolumeCmd);
-        }
-
-        // Check if the new service offering can be applied to vm instance
-        ServiceOffering newSvcOffering = _offeringDao.findById(svcOffId);
-        Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
-        _accountMgr.checkAccess(owner, newSvcOffering);
-
-        _itMgr.upgradeVmDb(vmId, svcOffId);
-        if (newServiceOffering.isDynamic()) {
-            //save the custom values to the database.
-            saveCustomOfferingDetails(vmId, newServiceOffering);
-        }
-        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
-            removeCustomOfferingDetails(vmId);
-        }
-
-        // Increment or decrement CPU and Memory count accordingly.
-        if (newCpu > currentCpu) {
-            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
-        } else if (currentCpu > newCpu) {
-            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
-        }
-        if (newMemory > currentMemory) {
-            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
-        } else if (currentMemory > newMemory) {
-            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
-        }
-
-        return _vmDao.findById(vmInstance.getId());
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_CREATE, eventDescription = "Creating Nic", async = true)
-    public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
-        Long vmId = cmd.getVmId();
-        Long networkId = cmd.getNetworkId();
-        String ipAddress = cmd.getIpAddress();
-        String macAddress = cmd.getMacAddress();
-        Account caller = CallContext.current().getCallingAccount();
-
-        UserVmVO vmInstance = _vmDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("NIC cannot be added to VM with VM Snapshots");
-        }
-
-        NetworkVO network = _networkDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("unable to find a network with id " + networkId);
-        }
-
-        if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-            if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain)
-                    && !(network.getAclType() == ACLType.Account && network.getAccountId() == vmInstance.getAccountId())) {
-                throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vmId: " + vmId);
-            }
-        }
-
-        List<NicVO> allNics = _nicDao.listByVmId(vmInstance.getId());
-        for (NicVO nic : allNics) {
-            if (nic.getNetworkId() == network.getId()) {
-                throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid());
-            }
-        }
-
-        macAddress = validateOrReplaceMacAddress(macAddress, network.getId());
-
-        if(_nicDao.findByNetworkIdAndMacAddress(networkId, macAddress) != null) {
-            throw new CloudRuntimeException("A NIC with this MAC address exists for network: " + network.getUuid());
-        }
-
-        NicProfile profile = new NicProfile(ipAddress, null, macAddress);
-        if (ipAddress != null) {
-            if (!(NetUtils.isValidIp4(ipAddress) || NetUtils.isValidIp6(ipAddress))) {
-                throw new InvalidParameterValueException("Invalid format for IP address parameter: " + ipAddress);
-            }
-        }
-
-        // Perform permission check on VM
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Verify that zone is not Basic
-        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
-        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
-            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't add a new NIC to a VM on a Basic Network");
-        }
-
-        // Perform account permission check on network
-        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
-
-        //ensure network belongs in zone
-        if (network.getDataCenterId() != vmInstance.getDataCenterId()) {
-            throw new CloudRuntimeException(vmInstance + " is in zone:" + vmInstance.getDataCenterId() + " but " + network + " is in zone:" + network.getDataCenterId());
-        }
-
-        // Get all vms hostNames in the network
-        List<String> hostNames = _vmInstanceDao.listDistinctHostNames(network.getId());
-        // verify that there are no duplicates, listDistictHostNames could return hostNames even if the NIC
-        //in the network is removed, so also check if the NIC is present and then throw an exception.
-        //This will also check if there are multiple nics of same vm in the network
-        if (hostNames.contains(vmInstance.getHostName())) {
-            for (String hostName : hostNames) {
-                VMInstanceVO vm = _vmInstanceDao.findVMByHostName(hostName);
-                if (_networkModel.getNicInNetwork(vm.getId(), network.getId()) != null && vm.getHostName().equals(vmInstance.getHostName())) {
-                    throw new CloudRuntimeException(network + " already has a vm with host name: " + vmInstance.getHostName());
-                }
-            }
-        }
-
-        NicProfile guestNic = null;
-        boolean cleanUp = true;
-
-        try {
-            guestNic = _itMgr.addVmToNetwork(vmInstance, network, profile);
-            saveExtraDhcpOptions(guestNic.getId(), cmd.getDhcpOptionsMap());
-            _networkMgr.configureExtraDhcpOptions(network, guestNic.getId(), cmd.getDhcpOptionsMap());
-            cleanUp = false;
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + ": " + e);
-        } catch (InsufficientCapacityException e) {
-            throw new CloudRuntimeException("Insufficient capacity when adding NIC to " + vmInstance + ": " + e);
-        } catch (ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Concurrent operations on adding NIC to " + vmInstance + ": " + e);
-        } finally {
-            if(cleanUp) {
-                try {
-                    _itMgr.removeVmFromNetwork(vmInstance, network, null);
-                } catch (ResourceUnavailableException e) {
-                    throw new CloudRuntimeException("Error while cleaning up NIC " + e);
-                }
-            }
-        }
-        CallContext.current().putContextParameter(Nic.class, guestNic.getUuid());
-        s_logger.debug("Successful addition of " + network + " from " + vmInstance);
-        return _vmDao.findById(vmInstance.getId());
-    }
-
-    /**
-     * If the given MAC address is invalid it replaces the given MAC with the next available MAC address
-     */
-    protected String validateOrReplaceMacAddress(String macAddress, long networkId) {
-        if (!NetUtils.isValidMac(macAddress)) {
-            try {
-                macAddress = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
-            } catch (InsufficientAddressCapacityException e) {
-                throw new CloudRuntimeException(String.format("A MAC address cannot be generated for this NIC in the network [id=%s] ", networkId));
-            }
-        }
-        return macAddress;
-    }
-
-    private void saveExtraDhcpOptions(long nicId, Map<Integer, String> dhcpOptions) {
-        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOList = dhcpOptions
-                .entrySet()
-                .stream()
-                .map(entry -> new NicExtraDhcpOptionVO(nicId, entry.getKey(), entry.getValue()))
-                .collect(Collectors.toList());
-
-        _nicExtraDhcpOptionDao.saveExtraDhcpOptions(nicExtraDhcpOptionVOList);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_DELETE, eventDescription = "Removing Nic", async = true)
-    public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
-        Long vmId = cmd.getVmId();
-        Long nicId = cmd.getNicId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        UserVmVO vmInstance = _vmDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
-        }
-
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("NIC cannot be removed from VM with VM Snapshots");
-        }
-
-        NicVO nic = _nicDao.findById(nicId);
-        if (nic == null) {
-            throw new InvalidParameterValueException("Unable to find a nic with id " + nicId);
-        }
-
-        NetworkVO network = _networkDao.findById(nic.getNetworkId());
-        if (network == null) {
-            throw new InvalidParameterValueException("Unable to find a network with id " + nic.getNetworkId());
-        }
-
-        // Perform permission check on VM
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Verify that zone is not Basic
-        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
-        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
-            throw new InvalidParameterValueException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't remove a NIC from a VM on a Basic Network");
-        }
-
-        // check to see if nic is attached to VM
-        if (nic.getInstanceId() != vmId) {
-            throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance);
-        }
-
-        // Perform account permission check on network
-        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
-
-        // don't delete default NIC on a user VM
-        if (nic.isDefaultNic() && vmInstance.getType() == VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("Unable to remove nic from " + vmInstance + " in " + network + ", nic is default.");
-        }
-
-        // if specified nic is associated with PF/LB/Static NAT
-        if (_rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0) {
-            throw new InvalidParameterValueException("Unable to remove nic from " + vmInstance + " in " + network + ", nic has associated Port forwarding or Load balancer or Static NAT rules.");
-        }
-
-        boolean nicremoved = false;
-        try {
-            nicremoved = _itMgr.removeNicFromVm(vmInstance, nic);
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance + ": " + e);
-
-        } catch (ConcurrentOperationException e) {
-            throw new CloudRuntimeException("Concurrent operations on removing " + network + " from " + vmInstance + ": " + e);
-        }
-
-        if (!nicremoved) {
-            throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance);
-        }
-
-        s_logger.debug("Successful removal of " + network + " from " + vmInstance);
-        return _vmDao.findById(vmInstance.getId());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_NIC_UPDATE, eventDescription = "Creating Nic", async = true)
-    public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) throws InvalidParameterValueException, CloudRuntimeException {
-        Long vmId = cmd.getVmId();
-        Long nicId = cmd.getNicId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        UserVmVO vmInstance = _vmDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("NIC cannot be updated for VM with VM Snapshots");
-        }
-
-        NicVO nic = _nicDao.findById(nicId);
-        if (nic == null) {
-            throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
-        }
-        NetworkVO network = _networkDao.findById(nic.getNetworkId());
-        if (network == null) {
-            throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId());
-        }
-
-        // Perform permission check on VM
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        // Verify that zone is not Basic
-        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
-        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
-            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't change default NIC on a Basic Network");
-        }
-
-        // no need to check permissions for network, we'll enumerate the ones they already have access to
-        Network existingdefaultnet = _networkModel.getDefaultNetworkForVm(vmId);
-
-        //check to see if nic is attached to VM
-        if (nic.getInstanceId() != vmId) {
-            throw new InvalidParameterValueException(nic + " is not a nic on  " + vmInstance);
-        }
-        // if current default equals chosen new default, Throw an exception
-        if (nic.isDefaultNic()) {
-            throw new CloudRuntimeException("refusing to set default nic because chosen nic is already the default");
-        }
-
-        //make sure the VM is Running or Stopped
-        if ((vmInstance.getState() != State.Running) && (vmInstance.getState() != State.Stopped)) {
-            throw new CloudRuntimeException("refusing to set default " + vmInstance + " is not Running or Stopped");
-        }
-
-        NicProfile existing = null;
-        List<NicProfile> nicProfiles = _networkMgr.getNicProfiles(vmInstance);
-        for (NicProfile nicProfile : nicProfiles) {
-            if (nicProfile.isDefaultNic() && existingdefaultnet != null && nicProfile.getNetworkId() == existingdefaultnet.getId()) {
-                existing = nicProfile;
-            }
-        }
-
-        if (existing == null) {
-            s_logger.warn("Failed to update default nic, no nic profile found for existing default network");
-            throw new CloudRuntimeException("Failed to find a nic profile for the existing default network. This is bad and probably means some sort of configuration corruption");
-        }
-
-        Network oldDefaultNetwork = null;
-        oldDefaultNetwork = _networkModel.getDefaultNetworkForVm(vmId);
-        String oldNicIdString = Long.toString(_networkModel.getDefaultNic(vmId).getId());
-        long oldNetworkOfferingId = -1L;
-
-        if (oldDefaultNetwork != null) {
-            oldNetworkOfferingId = oldDefaultNetwork.getNetworkOfferingId();
-        }
-        NicVO existingVO = _nicDao.findById(existing.id);
-        Integer chosenID = nic.getDeviceId();
-        Integer existingID = existing.getDeviceId();
-
-        nic.setDefaultNic(true);
-        nic.setDeviceId(existingID);
-        existingVO.setDefaultNic(false);
-        existingVO.setDeviceId(chosenID);
-
-        nic = _nicDao.persist(nic);
-        existingVO = _nicDao.persist(existingVO);
-
-        Network newdefault = null;
-        newdefault = _networkModel.getDefaultNetworkForVm(vmId);
-
-        if (newdefault == null) {
-            nic.setDefaultNic(false);
-            nic.setDeviceId(chosenID);
-            existingVO.setDefaultNic(true);
-            existingVO.setDeviceId(existingID);
-
-            nic = _nicDao.persist(nic);
-            _nicDao.persist(existingVO);
-
-            newdefault = _networkModel.getDefaultNetworkForVm(vmId);
-            if (newdefault.getId() == existingdefaultnet.getId()) {
-                throw new CloudRuntimeException("Setting a default nic failed, and we had no default nic, but we were able to set it back to the original");
-            }
-            throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default");
-        } else if (newdefault.getId() == nic.getNetworkId()) {
-            s_logger.debug("successfully set default network to " + network + " for " + vmInstance);
-            String nicIdString = Long.toString(nic.getId());
-            long newNetworkOfferingId = network.getNetworkOfferingId();
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(),
-                    oldNicIdString, oldNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), nicIdString,
-                    newNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), nicIdString,
-                    newNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(),
-                    oldNicIdString, oldNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
-
-            if (vmInstance.getState() != State.Stopped) {
-                try {
-                    VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
-                    User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-                    ReservationContext context = new ReservationContextImpl(null, null, callerUser, caller);
-                    DeployDestination dest = new DeployDestination(dc, null, null, null);
-                    _networkMgr.prepare(vmProfile, dest, context);
-                } catch (final Exception e) {
-                    s_logger.info("Got exception: ", e);
-                }
-            }
-
-            return _vmDao.findById(vmInstance.getId());
-        }
-
-        throw new CloudRuntimeException("something strange happened, new default network(" + newdefault.getId() + ") is not null, and is not equal to the network("
-                + nic.getNetworkId() + ") of the chosen nic");
-    }
-
-    @Override
-    public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) {
-        Long nicId = cmd.getNicId();
-        String ipaddr = cmd.getIpaddress();
-        Account caller = CallContext.current().getCallingAccount();
-
-        //check whether the nic belongs to user vm.
-        NicVO nicVO = _nicDao.findById(nicId);
-        if (nicVO == null) {
-            throw new InvalidParameterValueException("There is no nic for the " + nicId);
-        }
-
-        if (nicVO.getVmType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("The nic is not belongs to user vm");
-        }
-
-        UserVm vm = _vmDao.findById(nicVO.getInstanceId());
-        if (vm == null) {
-            throw new InvalidParameterValueException("There is no vm with the nic");
-        }
-
-        Network network = _networkDao.findById(nicVO.getNetworkId());
-        if (network == null) {
-            throw new InvalidParameterValueException("There is no network with the nic");
-        }
-        // Don't allow to update vm nic ip if network is not in Implemented/Setup/Allocated state
-        if (!(network.getState() == Network.State.Allocated || network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) {
-            throw new InvalidParameterValueException("Network is not in the right state to update vm nic ip. Correct states are: " + Network.State.Allocated + ", " + Network.State.Implemented + ", "
-                    + Network.State.Setup);
-        }
-
-        NetworkOfferingVO offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
-        if (offering == null) {
-            throw new InvalidParameterValueException("There is no network offering with the network");
-        }
-        if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && vm.getState() != State.Stopped) {
-            InvalidParameterValueException ex = new InvalidParameterValueException(
-                    "VM is not Stopped, unable to update the vm nic having the specified id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        // verify permissions
-        _accountMgr.checkAccess(caller, null, true, vm);
-        Account ipOwner = _accountDao.findByIdIncludingRemoved(vm.getAccountId());
-
-        // verify ip address
-        s_logger.debug("Calling the ip allocation ...");
-        DataCenter dc = _dcDao.findById(network.getDataCenterId());
-        if (dc == null) {
-            throw new InvalidParameterValueException("There is no dc with the nic");
-        }
-        if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
-            try {
-                ipaddr = _ipAddrMgr.allocateGuestIP(network, ipaddr);
-            } catch (InsufficientAddressCapacityException e) {
-                throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
-            }
-            if (ipaddr == null) {
-                throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
-            }
-
-            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
-                IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmId(vm.getId());
-                if (oldIP != null) {
-                    oldIP.setVmIp(ipaddr);
-                    _ipAddressDao.persist(oldIP);
-                }
-            }
-            // implementing the network elements and resources as a part of vm nic ip update if network has services and it is in Implemented state
-            if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && network.getState() == Network.State.Implemented) {
-                User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
-                ReservationContext context = new ReservationContextImpl(null, null, callerUser, caller);
-                DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
-
-                s_logger.debug("Implementing the network " + network + " elements and resources as a part of vm nic ip update");
-                try {
-                    // implement the network elements and rules again
-                    _networkMgr.implementNetworkElementsAndResources(dest, context, network, offering);
-                } catch (Exception ex) {
-                    s_logger.warn("Failed to implement network " + network + " elements and resources as a part of vm nic ip update due to ", ex);
-                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of vm nic ip update");
-                    e.addProxyObject(network.getUuid(), "networkId");
-                    // restore to old ip address
-                    if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
-                        IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmId(vm.getId());
-                        if (oldIP != null) {
-                            oldIP.setVmIp(nicVO.getIPv4Address());
-                            _ipAddressDao.persist(oldIP);
-                        }
-                    }
-                    throw e;
-                }
-            }
-        } else if (dc.getNetworkType() == NetworkType.Basic || network.getGuestType()  == Network.GuestType.Shared) {
-            //handle the basic networks here
-            //for basic zone, need to provide the podId to ensure proper ip alloation
-            Long podId = null;
-            if (dc.getNetworkType() == NetworkType.Basic) {
-                podId = vm.getPodIdToDeployIn();
-                if (podId == null) {
-                    throw new InvalidParameterValueException("vm pod id is null in Basic zone; can't decide the range for ip allocation");
-                }
-            }
-
-            try {
-                ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, ipaddr);
-                if (ipaddr == null) {
-                    throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
-                }
-
-                final IPAddressVO newIp = _ipAddressDao.findByIpAndDcId(dc.getId(), ipaddr);
-                final Vlan vlan = _vlanDao.findById(newIp.getVlanId());
-                nicVO.setIPv4Gateway(vlan.getVlanGateway());
-                nicVO.setIPv4Netmask(vlan.getVlanNetmask());
-
-                final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nicVO.getNetworkId(), nicVO.getIPv4Address());
-                if (ip != null) {
-                    Transaction.execute(new TransactionCallbackNoReturn() {
-                        @Override
-                        public void doInTransactionWithoutResult(TransactionStatus status) {
-                            _ipAddrMgr.markIpAsUnavailable(ip.getId());
-                            _ipAddressDao.unassignIpAddress(ip.getId());
-                        }
-                    });
-                }
-            } catch (InsufficientAddressCapacityException e) {
-                s_logger.error("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
-                return null;
-            }
-        } else {
-            s_logger.error("UpdateVmNicIpCmd is not supported in this network...");
-            return null;
-        }
-
-        s_logger.debug("Updating IPv4 address of NIC " + nicVO + " to " + ipaddr + "/" + nicVO.getIPv4Netmask() + " with gateway " + nicVO.getIPv4Gateway());
-        nicVO.setIPv4Address(ipaddr);
-        _nicDao.persist(nicVO);
-
-        return vm;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "Upgrading VM", async = true)
-    public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException {
-
-        Long vmId = cmd.getId();
-        Long newServiceOfferingId = cmd.getServiceOfferingId();
-        CallContext.current().setEventDetails("Vm Id: " + vmId);
-
-        boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmd.getDetails());
-        if (result) {
-            UserVmVO vmInstance = _vmDao.findById(vmId);
-            if (vmInstance.getState().equals(State.Stopped)) {
-                // Generate usage event for VM upgrade
-                generateUsageEvent(vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
-            }
-            if (vmInstance.getState().equals(State.Running)) {
-                // Generate usage event for Dynamic scaling of VM
-                generateUsageEvent( vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_DYNAMIC_SCALE);
-            }
-            return vmInstance;
-        } else {
-            throw new CloudRuntimeException("Failed to scale the VM");
-        }
-    }
-
-    @Override
-    public HashMap<Long, List<VmDiskStatsEntry>> getVmDiskStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
-        HashMap<Long, List<VmDiskStatsEntry>> vmDiskStatsById = new HashMap<Long, List<VmDiskStatsEntry>>();
-
-        if (vmIds.isEmpty()) {
-            return vmDiskStatsById;
-        }
-
-        List<String> vmNames = new ArrayList<String>();
-
-        for (Long vmId : vmIds) {
-            UserVmVO vm = _vmDao.findById(vmId);
-            vmNames.add(vm.getInstanceName());
-        }
-
-        Answer answer = _agentMgr.easySend(hostId, new GetVmDiskStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to obtain VM disk statistics.");
-            return null;
-        } else {
-            HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = ((GetVmDiskStatsAnswer)answer).getVmDiskStatsMap();
-
-            if (vmDiskStatsByName == null) {
-                s_logger.warn("Unable to obtain VM disk statistics.");
-                return null;
-            }
-
-            for (Map.Entry<String, List<VmDiskStatsEntry>> entry: vmDiskStatsByName.entrySet()) {
-                vmDiskStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue());
-            }
-        }
-
-        return vmDiskStatsById;
-    }
-
-    @Override
-    public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
-    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
-
-        // Verify input parameters
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-
-        if (vmInstance != null) {
-            if (vmInstance.getState().equals(State.Stopped)) {
-                upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters);
-                return true;
-            }
-            if (vmInstance.getState().equals(State.Running)) {
-                return upgradeRunningVirtualMachine(vmId, newServiceOfferingId, customParameters);
-            }
-        }
-        return false;
-    }
-
-    private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
-    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-        if (vmInstance.getHypervisorType() != HypervisorType.XenServer && vmInstance.getHypervisorType() != HypervisorType.VMware && vmInstance.getHypervisorType() != HypervisorType.Simulator) {
-            s_logger.info("Scaling the VM dynamically is not supported for VMs running on Hypervisor "+vmInstance.getHypervisorType());
-            throw new InvalidParameterValueException("Scaling the VM dynamically is not supported for VMs running on Hypervisor "+vmInstance.getHypervisorType());
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        //Check if its a scale "up"
-        ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId);
-        if (newServiceOffering.isDynamic()) {
-            newServiceOffering.setDynamicFlag(true);
-            validateCustomParameters(newServiceOffering, customParameters);
-            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
-        }
-
-        // Check that the specified service offering ID is valid
-        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
-
-        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
-        int newCpu = newServiceOffering.getCpu();
-        int newMemory = newServiceOffering.getRamSize();
-        int newSpeed = newServiceOffering.getSpeed();
-        int currentCpu = currentServiceOffering.getCpu();
-        int currentMemory = currentServiceOffering.getRamSize();
-        int currentSpeed = currentServiceOffering.getSpeed();
-        int memoryDiff = newMemory - currentMemory;
-        int cpuDiff = newCpu * newSpeed - currentCpu * currentSpeed;
-
-        // Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same)
-        if ((newSpeed < currentSpeed || newMemory < currentMemory || newCpu < currentCpu) || (newSpeed == currentSpeed && newMemory == currentMemory && newCpu == currentCpu)) {
-            throw new InvalidParameterValueException("Only scaling up the vm is supported, new service offering(speed=" + newSpeed + ",cpu=" + newCpu + ",memory=," + newMemory
-                    + ")" + " should have at least one value(cpu/ram) greater than old value and no resource value less than older(speed=" + currentSpeed + ",cpu=" + currentCpu
-                    + ",memory=," + currentMemory + ")");
-        }
-
-        _offeringDao.loadDetails(currentServiceOffering);
-        _offeringDao.loadDetails(newServiceOffering);
-
-        Map<String, String> currentDetails = currentServiceOffering.getDetails();
-        Map<String, String> newDetails = newServiceOffering.getDetails();
-        String currentVgpuType = currentDetails.get("vgpuType");
-        String newVgpuType = newDetails.get("vgpuType");
-        if(currentVgpuType != null) {
-            if(newVgpuType == null || !newVgpuType.equalsIgnoreCase(currentVgpuType)) {
-                throw new InvalidParameterValueException("Dynamic scaling of vGPU type is not supported. VM has vGPU Type: " + currentVgpuType);
-            }
-        }
-
-        // Check resource limits
-        if (newCpu > currentCpu) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
-        }
-        if (newMemory > currentMemory) {
-            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
-        }
-
-        // Dynamically upgrade the running vms
-        boolean success = false;
-        if (vmInstance.getState().equals(State.Running)) {
-            int retry = _scaleRetry;
-            ExcludeList excludes = new ExcludeList();
-
-            // Check zone wide flag
-            boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
-            if (!enableDynamicallyScaleVm) {
-                throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
-            }
-
-            // Check vm flag
-            if (!vmInstance.isDynamicallyScalable()) {
-                throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
-            }
-
-            // Check disable threshold for cluster is not crossed
-            HostVO host = _hostDao.findById(vmInstance.getHostId());
-            if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) {
-                throw new CloudRuntimeException("Unable to scale vm: " + vmInstance.getUuid() + " due to insufficient resources");
-            }
-
-            while (retry-- != 0) { // It's != so that it can match -1.
-                try {
-                    boolean existingHostHasCapacity = false;
-
-                    // Increment CPU and Memory count accordingly.
-                    if (newCpu > currentCpu) {
-                        _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
-                    }
-
-                    if (memoryDiff > 0) {
-                        _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
-                    }
-
-                    // #1 Check existing host has capacity
-                    if (!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId()))) {
-                        existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu, newSpeed)
-                                && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff, (memoryDiff) * 1024L * 1024L, false,
-                                        _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_CPU),
-                                        _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_MEMORY), false);
-                        excludes.addHost(vmInstance.getHostId());
-                    }
-
-                    // #2 migrate the vm if host doesn't have capacity or is in avoid set
-                    if (!existingHostHasCapacity) {
-                        _itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, excludes);
-                    }
-
-                    // #3 scale the vm now
-                    _itMgr.upgradeVmDb(vmId, newServiceOfferingId);
-                    if (newServiceOffering.isDynamic()) {
-                        //save the custom values to the database.
-                        saveCustomOfferingDetails(vmId, newServiceOffering);
-                    }
-                    vmInstance = _vmInstanceDao.findById(vmId);
-                    _itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity);
-                    success = true;
-                    if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
-                        removeCustomOfferingDetails(vmId);
-                    }
-                    return success;
-                } catch (InsufficientCapacityException e) {
-                    s_logger.warn("Received exception while scaling ", e);
-                } catch (ResourceUnavailableException e) {
-                    s_logger.warn("Received exception while scaling ", e);
-                } catch (ConcurrentOperationException e) {
-                    s_logger.warn("Received exception while scaling ", e);
-                } catch (Exception e) {
-                    s_logger.warn("Received exception while scaling ", e);
-                } finally {
-                    if (!success) {
-                        _itMgr.upgradeVmDb(vmId, currentServiceOffering.getId()); // rollback
-
-                        // Decrement CPU and Memory count accordingly.
-                        if (newCpu > currentCpu) {
-                            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
-                        }
-                        //restoring old service offering will take care of removing new SO.
-                        if(currentServiceOffering.isDynamic()){
-                            saveCustomOfferingDetails(vmId, currentServiceOffering);
-                        }
-
-                        if (memoryDiff > 0) {
-                            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
-                        }
-                    }
-                }
-            }
-        }
-        return success;
-    }
-
-    @Override
-    public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) {
-        //save the custom values to the database.
-        Map<String, String> details = _uservmDetailsDao.listDetailsKeyPairs(vmId);
-        details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
-        details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
-        details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
-        List<UserVmDetailVO> detailList = new ArrayList<UserVmDetailVO>();
-        for (Map.Entry<String, String> entry: details.entrySet()) {
-            UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true);
-            detailList.add(detailVO);
-        }
-        _uservmDetailsDao.saveDetails(detailList);
-    }
-
-    @Override
-    public void removeCustomOfferingDetails(long vmId) {
-        Map<String, String> details = _uservmDetailsDao.listDetailsKeyPairs(vmId);
-        details.remove(UsageEventVO.DynamicParameters.cpuNumber.name());
-        details.remove(UsageEventVO.DynamicParameters.cpuSpeed.name());
-        details.remove(UsageEventVO.DynamicParameters.memory.name());
-        List<UserVmDetailVO> detailList = new ArrayList<UserVmDetailVO>();
-        for(Map.Entry<String, String> entry: details.entrySet()) {
-            UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true);
-            detailList.add(detailVO);
-        }
-        _uservmDetailsDao.saveDetails(detailList);
-    }
-
-    @Override
-    public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
-        HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<Long, VmStatsEntry>();
-
-        if (vmIds.isEmpty()) {
-            return vmStatsById;
-        }
-
-        List<String> vmNames = new ArrayList<String>();
-
-        for (Long vmId : vmIds) {
-            UserVmVO vm = _vmDao.findById(vmId);
-            vmNames.add(vm.getInstanceName());
-        }
-
-        Answer answer = _agentMgr.easySend(hostId, new GetVmStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to obtain VM statistics.");
-            return null;
-        } else {
-            HashMap<String, VmStatsEntry> vmStatsByName = ((GetVmStatsAnswer)answer).getVmStatsMap();
-
-            if (vmStatsByName == null) {
-                s_logger.warn("Unable to obtain VM statistics.");
-                return null;
-            }
-
-            for (Map.Entry<String, VmStatsEntry> entry : vmStatsByName.entrySet()) {
-                vmStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue());
-            }
-        }
-
-        return vmStatsById;
-    }
-
-    @Override
-    public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocator, int timeout) {
-        List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up);
-        for (HostVO neighbor : neighbors) {
-            GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocator);
-            if (timeout > 0) {
-                cmd.setWait(timeout/1000);
-            }
-            Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
-            if (answer instanceof GetVolumeStatsAnswer){
-                GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer)answer;
-                return volstats.getVolumeStats();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    @DB
-    public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {
-
-        final Long vmId = cmd.getId();
-        Account caller = CallContext.current().getCallingAccount();
-        final Long userId = caller.getAccountId();
-
-        // Verify input parameters
-        final UserVmVO vm = _vmDao.findById(vmId);
-
-        if (vm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
-        if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
-            throw new PermissionDeniedException("Recovering a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
-        }
-
-        if (vm.getRemoved() != null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to find vm or vm is removed: " + vmId);
-            }
-            throw new InvalidParameterValueException("Unable to find vm by id " + vmId);
-        }
-
-        if (vm.getState() != State.Destroyed) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("vm is not in the right state: " + vmId);
-            }
-            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Recovering vm " + vmId);
-        }
-
-        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
-            @Override public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
-
-                Account account = _accountDao.lockRow(vm.getAccountId(), true);
-
-                // if the account is deleted, throw error
-                if (account.getRemoved() != null) {
-                    throw new CloudRuntimeException("Unable to recover VM as the account is deleted");
-                }
-
-                // Get serviceOffering for Virtual Machine
-                ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-
-                // First check that the maximum number of UserVMs, CPU and Memory limit for the given
-                // accountId will not be exceeded
-                resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
-
-                _haMgr.cancelDestroy(vm, vm.getHostId());
-
-                try {
-                    if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
-                        s_logger.debug("Unable to recover the vm because it is not in the correct state: " + vmId);
-                        throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
-                    }
-                } catch (NoTransitionException e) {
-                    throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
-                }
-
-                // Recover the VM's disks
-                List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
-                for (VolumeVO volume : volumes) {
-                    if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
-                        // Create an event
-                        Long templateId = volume.getTemplateId();
-                        Long diskOfferingId = volume.getDiskOfferingId();
-                        Long offeringId = null;
-                        if (diskOfferingId != null) {
-                            DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
-                            if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
-                                offeringId = offering.getId();
-                            }
-                        }
-                        UsageEventUtils
-                        .publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId,
-                                templateId, volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
-                    }
-                }
-
-                //Update Resource Count for the given account
-                resourceCountIncrement(account.getId(), vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
-            }
-        });
-
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        if (_configDao == null) {
-            throw new ConfigurationException("Unable to get the configuration dao.");
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
-
-        _instance = configs.get("instance.name");
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-
-        String workers = configs.get("expunge.workers");
-        int wrks = NumbersUtil.parseInt(workers, 10);
-        capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
-
-        String time = configs.get("expunge.interval");
-        _expungeInterval = NumbersUtil.parseInt(time, 86400);
-        time = configs.get("expunge.delay");
-        _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval);
-
-        _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
-
-        String vmIpWorkers = configs.get(VmIpFetchTaskWorkers.value());
-        int vmipwrks = NumbersUtil.parseInt(vmIpWorkers, 10);
-
-        _vmIpFetchExecutor =   Executors.newScheduledThreadPool(vmipwrks, new NamedThreadFactory("UserVm-ipfetch"));
-
-        String aggregationRange = configs.get("usage.stats.job.aggregation.range");
-        int _usageAggregationRange  = NumbersUtil.parseInt(aggregationRange, 1440);
-        int HOURLY_TIME = 60;
-        final int DAILY_TIME = 60 * 24;
-        if (_usageAggregationRange == DAILY_TIME) {
-            _dailyOrHourly = true;
-        } else if (_usageAggregationRange == HOURLY_TIME) {
-            _dailyOrHourly = true;
-        } else {
-            _dailyOrHourly = false;
-        }
-
-        _itMgr.registerGuru(VirtualMachine.Type.User, this);
-
-        VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao, _vmDao, this, _configDao));
-
-        String value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
-        _instanceNameFlag = (value == null) ? false : Boolean.parseBoolean(value);
-
-        _scaleRetry = NumbersUtil.parseInt(configs.get(Config.ScaleRetry.key()), 2);
-
-        _vmIpFetchThreadExecutor = Executors.newFixedThreadPool(VmIpFetchThreadPoolMax.value(), new NamedThreadFactory("vmIpFetchThread"));
-
-        s_logger.info("User VM Manager is configured.");
-
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        _executor.scheduleWithFixedDelay(new ExpungeTask(), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
-        _vmIpFetchExecutor.scheduleWithFixedDelay(new VmIpFetchTask(), VmIpFetchWaitInterval.value(), VmIpFetchWaitInterval.value(), TimeUnit.SECONDS);
-        loadVmDetailsInMapForExternalDhcpIp();
-        return true;
-    }
-
-    private void loadVmDetailsInMapForExternalDhcpIp() {
-
-        List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
-
-        for (NetworkVO network: networks) {
-            if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
-
-                for (NicVO nic : nics) {
-
-                    if (nic.getIPv4Address() == null) {
-                        long nicId = nic.getId();
-                        long vmId = nic.getInstanceId();
-                        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-
-                        // only load running vms. For stopped vms get loaded on starting
-                        if (vmInstance.getState() == State.Running) {
-                            VmAndCountDetails vmAndCount = new VmAndCountDetails(vmId, VmIpFetchTrialMax.value());
-                            vmIdCountMap.put(nicId, vmAndCount);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean stop() {
-        _executor.shutdown();
-        _vmIpFetchExecutor.shutdown();
-        return true;
-    }
-
-    public String getRandomPrivateTemplateName() {
-        return UUID.randomUUID().toString();
-    }
-
-    @Override
-    public boolean expunge(UserVmVO vm, long callerUserId, Account caller) {
-        vm = _vmDao.acquireInLockTable(vm.getId());
-        if (vm == null) {
-            return false;
-        }
-        try {
-
-            releaseNetworkResourcesOnExpunge(vm.getId());
-
-            List<VolumeVO> rootVol = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
-            // expunge the vm
-            _itMgr.advanceExpunge(vm.getUuid());
-            // Update Resource count
-            if (vm.getAccountId() != Account.ACCOUNT_ID_SYSTEM && !rootVol.isEmpty()) {
-                _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume);
-                _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(rootVol.get(0).getSize()));
-            }
-
-            // Only if vm is not expunged already, cleanup it's resources
-            if (vm.getRemoved() == null) {
-                // Cleanup vm resources - all the PF/LB/StaticNat rules
-                // associated with vm
-                s_logger.debug("Starting cleaning up vm " + vm + " resources...");
-                if (cleanupVmResources(vm.getId())) {
-                    s_logger.debug("Successfully cleaned up vm " + vm + " resources as a part of expunge process");
-                } else {
-                    s_logger.warn("Failed to cleanup resources as a part of vm " + vm + " expunge");
-                    return false;
-                }
-
-                _vmDao.remove(vm.getId());
-            }
-
-            return true;
-
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to expunge  " + vm, e);
-            return false;
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Operation time out on expunging " + vm, e);
-            return false;
-        } catch (ConcurrentOperationException e) {
-            s_logger.warn("Concurrent operations on expunging " + vm, e);
-            return false;
-        } finally {
-            _vmDao.releaseFromLockTable(vm.getId());
-        }
-    }
-
-    /**
-     * Release network resources, it was done on vm stop previously.
-     * @param id vm id
-     * @throws ConcurrentOperationException
-     * @throws ResourceUnavailableException
-     */
-    private void releaseNetworkResourcesOnExpunge(long id) throws ConcurrentOperationException, ResourceUnavailableException {
-        final VMInstanceVO vmInstance = _vmDao.findById(id);
-        if (vmInstance != null){
-            final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vmInstance);
-            _networkMgr.release(profile, false);
-        }
-        else {
-            s_logger.error("Couldn't find vm with id = " + id + ", unable to release network resources");
-        }
-    }
-
-    private boolean cleanupVmResources(long vmId) {
-        boolean success = true;
-        // Remove vm from security groups
-        _securityGroupMgr.removeInstanceFromGroups(vmId);
-
-        // Remove vm from instance group
-        removeInstanceFromInstanceGroup(vmId);
-
-        // cleanup firewall rules
-        if (_firewallMgr.revokeFirewallRulesForVm(vmId)) {
-            s_logger.debug("Firewall rules are removed successfully as a part of vm id=" + vmId + " expunge");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove firewall rules as a part of vm id=" + vmId + " expunge");
-        }
-
-        // cleanup port forwarding rules
-        if (_rulesMgr.revokePortForwardingRulesForVm(vmId)) {
-            s_logger.debug("Port forwarding rules are removed successfully as a part of vm id=" + vmId + " expunge");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove port forwarding rules as a part of vm id=" + vmId + " expunge");
-        }
-
-        // cleanup load balancer rules
-        if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
-            s_logger.debug("Removed vm id=" + vmId + " from all load balancers as a part of expunge process");
-        } else {
-            success = false;
-            s_logger.warn("Fail to remove vm id=" + vmId + " from load balancers as a part of expunge process");
-        }
-
-        // If vm is assigned to static nat, disable static nat for the ip
-        // address and disassociate ip if elasticIP is enabled
-        List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(vmId);
-
-        for (IPAddressVO ip : ips) {
-            try {
-                if (_rulesMgr.disableStaticNat(ip.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM, true)) {
-                    s_logger.debug("Disabled 1-1 nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
-                } else {
-                    s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
-                    success = false;
-                }
-            } catch (ResourceUnavailableException e) {
-                success = false;
-                s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge because resource is unavailable", e);
-            }
-        }
-
-        return success;
-    }
-
-    @Override
-    public void deletePrivateTemplateRecord(Long templateId) {
-        if (templateId != null) {
-            _templateDao.remove(templateId);
-        }
-    }
-
-    // used for vm transitioning to error state
-    private void updateVmStateForFailedVmCreation(Long vmId, Long hostId) {
-
-        UserVmVO vm = _vmDao.findById(vmId);
-
-        if (vm != null) {
-            if (vm.getState().equals(State.Stopped)) {
-                s_logger.debug("Destroying vm " + vm + " as it failed to create on Host with Id:" + hostId);
-                try {
-                    _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationFailedToError, null);
-                } catch (NoTransitionException e1) {
-                    s_logger.warn(e1.getMessage());
-                }
-                // destroy associated volumes for vm in error state
-                // get all volumes in non destroyed state
-                List<VolumeVO> volumesForThisVm = _volsDao.findUsableVolumesForInstance(vm.getId());
-                for (VolumeVO volume : volumesForThisVm) {
-                    if (volume.getState() != Volume.State.Destroy) {
-                        volumeMgr.destroyVolume(volume);
-                    }
-                }
-                String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId;
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-
-                // Get serviceOffering for Virtual Machine
-                ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-
-                // Update Resource Count for the given account
-                resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
-            }
-        }
-    }
-
-
-
-    private class VmIpFetchTask extends ManagedContextRunnable {
-
-        @Override
-        protected void runInContext() {
-            GlobalLock scanLock = GlobalLock.getInternLock("vmIpFetch");
-            try {
-                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    try {
-
-                        for (Entry<Long, VmAndCountDetails> entry:   vmIdCountMap.entrySet()) {
-                            long nicId = entry.getKey();
-                            VmAndCountDetails vmIdAndCount = entry.getValue();
-                            long vmId = vmIdAndCount.getVmId();
-
-                            if (vmIdAndCount.getRetrievalCount() <= 0) {
-                                vmIdCountMap.remove(nicId);
-                                s_logger.debug("Vm " + vmId +" nic "+nicId + " count is zero .. removing vm nic from map ");
-
-                                ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
-                                        Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
-                                        "VM " + vmId + " nic id "+ nicId + " ip addr fetch failed ");
-
-                                continue;
-                            }
-
-
-                            UserVm userVm = _vmDao.findById(vmId);
-                            VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-                            NicVO nicVo = _nicDao.findById(nicId);
-                            NetworkVO network = _networkDao.findById(nicVo.getNetworkId());
-
-                            VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(userVm);
-                            VirtualMachine vm = vmProfile.getVirtualMachine();
-                            boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-
-                            _vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
-                                    isWindows, vm.getHostId(), network.getCidr()));
-
-                        }
-                    } catch (Exception e) {
-                        s_logger.error("Caught the Exception in VmIpFetchTask", e);
-                    } finally {
-                        scanLock.unlock();
-                    }
-                }
-            } finally {
-                scanLock.releaseRef();
-            }
-
-        }
-    }
-
-
-    private class ExpungeTask extends ManagedContextRunnable {
-        public ExpungeTask() {
-        }
-
-        @Override
-        protected void runInContext() {
-            GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
-            try {
-                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
-                    try {
-                        List<UserVmVO> vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long)_expungeDelay << 10)));
-                        if (s_logger.isInfoEnabled()) {
-                            if (vms.size() == 0) {
-                                s_logger.trace("Found " + vms.size() + " vms to expunge.");
-                            } else {
-                                s_logger.info("Found " + vms.size() + " vms to expunge.");
-                            }
-                        }
-                        for (UserVmVO vm : vms) {
-                            try {
-                                expungeVm(vm.getId());
-                            } catch (Exception e) {
-                                s_logger.warn("Unable to expunge " + vm, e);
-                            }
-                        }
-                    } catch (Exception e) {
-                        s_logger.error("Caught the following Exception", e);
-                    } finally {
-                        scanLock.unlock();
-                    }
-                }
-            } finally {
-                scanLock.releaseRef();
-            }
-        }
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_UPDATE, eventDescription = "updating Vm")
-    public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException {
-        validateInputsAndPermissionForUpdateVirtualMachineCommand(cmd);
-
-        String displayName = cmd.getDisplayName();
-        String group = cmd.getGroup();
-        Boolean ha = cmd.getHaEnable();
-        Boolean isDisplayVm = cmd.getDisplayVm();
-        Long id = cmd.getId();
-        Long osTypeId = cmd.getOsTypeId();
-        String userData = cmd.getUserData();
-        Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
-        String hostName = cmd.getHostName();
-        Map<String,String> details = cmd.getDetails();
-        List<Long> securityGroupIdList = getSecurityGroupIdList(cmd);
-        boolean cleanupDetails = cmd.isCleanupDetails();
-
-        UserVmVO vmInstance = _vmDao.findById(cmd.getId());
-
-        if (isDisplayVm != null && isDisplayVm != vmInstance.isDisplay()) {
-            updateDisplayVmFlag(isDisplayVm, id, vmInstance);
-        }
-        if (cleanupDetails){
-            _vmDetailsDao.removeDetails(id);
-        }
-        else if (MapUtils.isNotEmpty(details)) {
-            vmInstance.setDetails(details);
-            _vmDao.saveDetails(vmInstance);
-        }
-        return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable,
-                cmd.getHttpMethod(), cmd.getCustomId(), hostName, cmd.getInstanceName(), securityGroupIdList, cmd.getDhcpOptionsMap());
-    }
-
-    protected void updateDisplayVmFlag(Boolean isDisplayVm, Long id, UserVmVO vmInstance) {
-        vmInstance.setDisplayVm(isDisplayVm);
-
-        // Resource limit changes
-        ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
-        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm);
-        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu()));
-        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize()));
-
-        // Usage
-        saveUsageEvent(vmInstance);
-
-        // take care of the root volume as well.
-        List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(id, Volume.Type.ROOT);
-        if (!rootVols.isEmpty()) {
-            _volumeService.updateDisplay(rootVols.get(0), isDisplayVm);
-        }
-
-        // take care of the data volumes as well.
-        List<VolumeVO> dataVols = _volsDao.findByInstanceAndType(id, Volume.Type.DATADISK);
-        for (Volume dataVol : dataVols) {
-            _volumeService.updateDisplay(dataVol, isDisplayVm);
-        }
-    }
-
-    protected void validateInputsAndPermissionForUpdateVirtualMachineCommand(UpdateVMCmd cmd) {
-        UserVmVO vmInstance = _vmDao.findById(cmd.getId());
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find virtual machine with id: " + cmd.getId());
-        }
-        validateGuestOsIdForUpdateVirtualMachineCommand(cmd);
-        Account caller = CallContext.current().getCallingAccount();
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-    }
-
-    protected void validateGuestOsIdForUpdateVirtualMachineCommand(UpdateVMCmd cmd) {
-        Long osTypeId = cmd.getOsTypeId();
-        if (osTypeId != null) {
-            GuestOSVO guestOS = _guestOSDao.findById(osTypeId);
-            if (guestOS == null) {
-                throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
-            }
-        }
-    }
-
-    private void saveUsageEvent(UserVmVO vm) {
-
-        // If vm not destroyed
-        if( vm.getState() != State.Destroyed && vm.getState() != State.Expunging && vm.getState() != State.Error){
-
-            if(vm.isDisplayVm()){
-                //1. Allocated VM Usage Event
-                generateUsageEvent(vm, true, EventTypes.EVENT_VM_CREATE);
-
-                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
-                    //2. Running VM Usage Event
-                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_START);
-
-                    // 3. Network offering usage
-                    generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_ASSIGN);
-                }
-
-            }else {
-                //1. Allocated VM Usage Event
-                generateUsageEvent(vm, true, EventTypes.EVENT_VM_DESTROY);
-
-                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
-                    //2. Running VM Usage Event
-                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_STOP);
-
-                    // 3. Network offering usage
-                    generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_REMOVE);
-                }
-            }
-        }
-
-    }
-
-    private void generateNetworkUsageForVm(VirtualMachine vm, boolean isDisplay, String eventType){
-
-        List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        for (NicVO nic : nics) {
-            NetworkVO network = _networkDao.findById(nic.getNetworkId());
-            long isDefault = (nic.isDefaultNic()) ? 1 : 0;
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                    Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, vm.getClass().getName(), vm.getUuid(), isDisplay);
-        }
-
-    }
-
-    @Override
-    public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
-            Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List<Long> securityGroupIdList, Map<String, Map<Integer, String>> extraDhcpOptionsMap)
-                    throws ResourceUnavailableException, InsufficientCapacityException {
-        UserVmVO vm = _vmDao.findById(id);
-        if (vm == null) {
-            throw new CloudRuntimeException("Unable to find virtual machine with id " + id);
-        }
-
-        if(instanceName != null){
-            VMInstanceVO vmInstance = _vmInstanceDao.findVMByInstanceName(instanceName);
-            if(vmInstance != null && vmInstance.getId() != id){
-                throw new CloudRuntimeException("Instance name : " + instanceName + " is not unique");
-            }
-        }
-
-        if (vm.getState() == State.Error || vm.getState() == State.Expunging) {
-            s_logger.error("vm is not in the right state: " + id);
-            throw new InvalidParameterValueException("Vm with id " + id + " is not in the right state");
-        }
-
-        if (displayName == null) {
-            displayName = vm.getDisplayName();
-        }
-
-        if (ha == null) {
-            ha = vm.isHaEnabled();
-        }
-
-        ServiceOffering offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-        if (!offering.getOfferHA() && ha) {
-            throw new InvalidParameterValueException("Can't enable ha for the vm as it's created from the Service offering having HA disabled");
-        }
-
-        if (isDisplayVmEnabled == null) {
-            isDisplayVmEnabled = vm.isDisplayVm();
-        }
-
-        boolean updateUserdata = false;
-        if (userData != null) {
-            // check and replace newlines
-            userData = userData.replace("\\n", "");
-            userData = validateUserData(userData, httpMethod);
-            // update userData on domain router.
-            updateUserdata = true;
-        } else {
-            userData = vm.getUserData();
-        }
-
-        if (isDynamicallyScalable == null) {
-            isDynamicallyScalable = vm.isDynamicallyScalable();
-        }
-
-        if (osTypeId == null) {
-            osTypeId = vm.getGuestOSId();
-        }
-
-        if (group != null) {
-            addInstanceToGroup(id, group);
-        }
-
-        if (isDynamicallyScalable == null) {
-            isDynamicallyScalable = vm.isDynamicallyScalable();
-        }
-
-        boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware);
-
-        if (securityGroupIdList != null && isVMware) {
-            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-        } else {
-            // Get default guest network in Basic zone
-            Network defaultNetwork = null;
-            try {
-                DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
-
-                if (zone.getNetworkType() == NetworkType.Basic) {
-                    // Get default guest network in Basic zone
-                    defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
-                } else if (zone.isSecurityGroupEnabled()) {
-                    NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId());
-                    if (defaultNic != null) {
-                        defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
-                    }
-                }
-            } catch (InvalidParameterValueException e) {
-                if(s_logger.isDebugEnabled()) {
-                    s_logger.debug(e.getMessage(),e);
-                }
-                defaultNetwork = _networkModel.getDefaultNetworkForVm(id);
-            }
-
-            if (securityGroupIdList != null && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
-                if (vm.getState() == State.Stopped) {
-                    // Remove instance from security groups
-                    _securityGroupMgr.removeInstanceFromGroups(id);
-                    // Add instance in provided groups
-                    _securityGroupMgr.addInstanceToGroups(id, securityGroupIdList);
-                } else {
-                    throw new InvalidParameterValueException("Virtual machine must be stopped prior to update security groups ");
-                }
-            }
-        }
-        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
-        if (hostName != null) {
-            // Check is hostName is RFC compliant
-            checkNameForRFCCompliance(hostName);
-
-            if (vm.getHostName().equalsIgnoreCase(hostName)) {
-                s_logger.debug("Vm " + vm + " is already set with the hostName specified: " + hostName);
-                hostName = null;
-            }
-
-            // Verify that vm's hostName is unique
-
-            List<NetworkVO> vmNtwks = new ArrayList<NetworkVO>(nics.size());
-            for (Nic nic : nics) {
-                vmNtwks.add(_networkDao.findById(nic.getNetworkId()));
-            }
-            checkIfHostNameUniqueInNtwkDomain(hostName, vmNtwks);
-        }
-
-        List<NetworkVO> networks = nics.stream()
-                .map(nic -> _networkDao.findById(nic.getNetworkId()))
-                .collect(Collectors.toList());
-
-        verifyExtraDhcpOptionsNetwork(extraDhcpOptionsMap, networks);
-        for (Nic nic : nics) {
-            _networkMgr.saveExtraDhcpOptions(networks.stream()
-                    .filter(network -> network.getId() == nic.getNetworkId())
-                    .findFirst()
-                    .get()
-                    .getUuid(), nic.getId(), extraDhcpOptionsMap);
-        }
-
-        _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId, hostName, instanceName);
-
-        if (updateUserdata) {
-            boolean result = updateUserDataInternal(_vmDao.findById(id));
-            if (result) {
-                s_logger.debug("User data successfully updated for vm id=" + id);
-            } else {
-                throw new CloudRuntimeException("Failed to reset userdata for the virtual machine ");
-            }
-        }
-
-        return _vmDao.findById(id);
-    }
-
-    private boolean updateUserDataInternal(UserVm vm) throws ResourceUnavailableException, InsufficientCapacityException {
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
-
-        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
-        if (nics == null || nics.isEmpty()) {
-            s_logger.error("unable to find any nics for vm " + vm.getUuid());
-            return false;
-        }
-
-        boolean userDataApplied = false;
-        for (Nic nic : nics) {
-            userDataApplied |= applyUserData(template.getHypervisorType(), vm, nic);
-        }
-        return userDataApplied;
-    }
-
-    protected boolean applyUserData(HypervisorType hyperVisorType, UserVm vm, Nic nic) throws ResourceUnavailableException, InsufficientCapacityException {
-        Network network = _networkDao.findById(nic.getNetworkId());
-        NicProfile nicProfile = new NicProfile(nic, network, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(
-                hyperVisorType, network));
-        VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm);
-
-        if (_networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.UserData)) {
-            UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network);
-            if (element == null) {
-                throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update");
-            }
-            boolean result = element.saveUserData(network, nicProfile, vmProfile);
-            if (!result) {
-                s_logger.error("Failed to update userdata for vm " + vm + " and nic " + nic);
-            } else {
-                return true;
-            }
-        } else {
-            s_logger.debug("Not applying userdata for nic id=" + nic.getId() + " in vm id=" + vmProfile.getId() + " because it is not supported in network id=" + network.getId());
-        }
-        return false;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
-    public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        return startVirtualMachine(cmd.getId(), cmd.getHostId(), null, cmd.getDeploymentPlanner()).first();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
-    public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long vmId = cmd.getId();
-
-        // Verify input parameters
-        UserVmVO vmInstance = _vmDao.findById(vmId);
-        if (vmInstance == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vmInstance);
-
-        checkIfHostOfVMIsInPrepareForMaintenanceState(vmInstance.getHostId(), vmId, "Reboot");
-
-        // If the VM is Volatile in nature, on reboot discard the VM's root disk and create a new root disk for it: by calling restoreVM
-        long serviceOfferingId = vmInstance.getServiceOfferingId();
-        ServiceOfferingVO offering = _serviceOfferingDao.findById(vmInstance.getId(), serviceOfferingId);
-        if (offering != null && offering.getRemoved() == null) {
-            if (offering.getVolatileVm()) {
-                return restoreVMInternal(caller, vmInstance, null);
-            }
-        } else {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the vm");
-        }
-
-        UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId);
-        if (userVm != null ) {
-            // update the vmIdCountMap if the vm is in advanced shared network with out services
-            final List<NicVO> nics = _nicDao.listByVmId(vmId);
-            for (NicVO nic : nics) {
-                Network network = _networkModel.getNetwork(nic.getNetworkId());
-                if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                    s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
-                            "reboot for vm ip fetch ");
-                    vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
-                }
-            }
-            return  userVm;
-        }
-        return  null;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_DESTROY, eventDescription = "destroying Vm", async = true)
-    public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
-        CallContext ctx = CallContext.current();
-        long vmId = cmd.getId();
-        boolean expunge = cmd.getExpunge();
-
-        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
-        if (expunge && !_accountMgr.isAdmin(ctx.getCallingAccount().getId()) && !AllowUserExpungeRecoverVm.valueIn(cmd.getEntityOwnerId())) {
-            throw new PermissionDeniedException("Parameter " + ApiConstants.EXPUNGE + " can be passed by Admin only. Or when the allow.user.expunge.recover.vm key is set.");
-        }
-        // check if VM exists
-        UserVmVO vm = _vmDao.findById(vmId);
-
-        if (vm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        // check if there are active volume snapshots tasks
-        s_logger.debug("Checking if there are any ongoing snapshots on the ROOT volumes associated with VM with ID " + vmId);
-        if (checkStatusOfVolumeSnapshots(vmId, Volume.Type.ROOT)) {
-            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on ROOT volume, vm destroy is not permitted, please try again later.");
-        }
-        s_logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm with id " + vmId);
-
-        UserVm destroyedVm = destroyVm(vmId, expunge);
-        if (expunge) {
-            if (!expunge(vm, ctx.getCallingUserId(), ctx.getCallingAccount())) {
-                throw new CloudRuntimeException("Failed to expunge vm " + destroyedVm);
-            }
-        }
-
-        return destroyedVm;
-    }
-
-    @Override
-    @DB
-    public InstanceGroupVO createVmGroup(CreateVMGroupCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long domainId = cmd.getDomainId();
-        String accountName = cmd.getAccountName();
-        String groupName = cmd.getGroupName();
-        Long projectId = cmd.getProjectId();
-
-        Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
-        long accountId = owner.getId();
-
-        // Check if name is already in use by this account
-        boolean isNameInUse = _vmGroupDao.isNameInUse(accountId, groupName);
-
-        if (isNameInUse) {
-            throw new InvalidParameterValueException("Unable to create vm group, a group with name " + groupName + " already exists for account " + accountId);
-        }
-
-        return createVmGroup(groupName, accountId);
-    }
-
-    @DB
-    private InstanceGroupVO createVmGroup(String groupName, long accountId) {
-        Account account = null;
-        try {
-            account = _accountDao.acquireInLockTable(accountId); // to ensure
-            // duplicate
-            // vm group
-            // names are
-            // not
-            // created.
-            if (account == null) {
-                s_logger.warn("Failed to acquire lock on account");
-                return null;
-            }
-            InstanceGroupVO group = _vmGroupDao.findByAccountAndName(accountId, groupName);
-            if (group == null) {
-                group = new InstanceGroupVO(groupName, accountId);
-                group = _vmGroupDao.persist(group);
-            }
-            return group;
-        } finally {
-            if (account != null) {
-                _accountDao.releaseFromLockTable(accountId);
-            }
-        }
-    }
-
-    @Override
-    public boolean deleteVmGroup(DeleteVMGroupCmd cmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        Long groupId = cmd.getId();
-
-        // Verify input parameters
-        InstanceGroupVO group = _vmGroupDao.findById(groupId);
-        if ((group == null) || (group.getRemoved() != null)) {
-            throw new InvalidParameterValueException("unable to find a vm group with id " + groupId);
-        }
-
-        _accountMgr.checkAccess(caller, null, true, group);
-
-        return deleteVmGroup(groupId);
-    }
-
-    @Override
-    public boolean deleteVmGroup(long groupId) {
-        // delete all the mappings from group_vm_map table
-        List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByGroupId(groupId);
-        for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-            SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-            sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-            _groupVMMapDao.expunge(sc);
-        }
-
-        if (_vmGroupDao.remove(groupId)) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    @DB
-    public boolean addInstanceToGroup(final long userVmId, String groupName) {
-        UserVmVO vm = _vmDao.findById(userVmId);
-
-        InstanceGroupVO group = _vmGroupDao.findByAccountAndName(vm.getAccountId(), groupName);
-        // Create vm group if the group doesn't exist for this account
-        if (group == null) {
-            group = createVmGroup(groupName, vm.getAccountId());
-        }
-
-        if (group != null) {
-            UserVm userVm = _vmDao.acquireInLockTable(userVmId);
-            if (userVm == null) {
-                s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
-            }
-            try {
-                final InstanceGroupVO groupFinal = group;
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        // don't let the group be deleted when we are assigning vm to
-                        // it.
-                        InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(groupFinal.getId(), false);
-                        if (ngrpLock == null) {
-                            s_logger.warn("Failed to acquire lock on vm group id=" + groupFinal.getId() + " name=" + groupFinal.getName());
-                            throw new CloudRuntimeException("Failed to acquire lock on vm group id=" + groupFinal.getId() + " name=" + groupFinal.getName());
-                        }
-
-                        // Currently don't allow to assign a vm to more than one group
-                        if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
-                            // Delete all mappings from group_vm_map table
-                            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(userVmId);
-                            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-                                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-                                sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-                                _groupVMMapDao.expunge(sc);
-                            }
-                        }
-                        InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(groupFinal.getId(), userVmId);
-                        _groupVMMapDao.persist(groupVmMapVO);
-
-                    }
-                });
-
-                return true;
-            } finally {
-                if (userVm != null) {
-                    _vmDao.releaseFromLockTable(userVmId);
-                }
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public InstanceGroupVO getGroupForVm(long vmId) {
-        // TODO - in future releases vm can be assigned to multiple groups; but
-        // currently return just one group per vm
-        try {
-            List<InstanceGroupVMMapVO> groupsToVmMap = _groupVMMapDao.listByInstanceId(vmId);
-
-            if (groupsToVmMap != null && groupsToVmMap.size() != 0) {
-                InstanceGroupVO group = _vmGroupDao.findById(groupsToVmMap.get(0).getGroupId());
-                return group;
-            } else {
-                return null;
-            }
-        } catch (Exception e) {
-            s_logger.warn("Error trying to get group for a vm: ", e);
-            return null;
-        }
-    }
-
-    @Override
-    public void removeInstanceFromInstanceGroup(long vmId) {
-        try {
-            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(vmId);
-            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
-                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
-                sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
-                _groupVMMapDao.expunge(sc);
-            }
-        } catch (Exception e) {
-            s_logger.warn("Error trying to remove vm from group: ", e);
-        }
-    }
-
-    private boolean validPassword(String password) {
-        if (password == null || password.length() == 0) {
-            return false;
-        }
-        for (int i = 0; i < password.length(); i++) {
-            if (password.charAt(i) == ' ') {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
-    public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
-            Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
-            String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
-            Map<String, String> customParametes, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
-    StorageUnavailableException, ResourceAllocationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-
-        // Verify that caller can perform actions in behalf of vm owner
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        // Verify that owner can use the service offering
-        _accountMgr.checkAccess(owner, serviceOffering);
-        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
-
-        // Get default guest network in Basic zone
-        Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
-
-        if (defaultNetwork == null) {
-            throw new InvalidParameterValueException("Unable to find a default network to start a vm");
-        } else {
-            networkList.add(_networkDao.findById(defaultNetwork.getId()));
-        }
-
-        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
-
-        if (securityGroupIdList != null && isVmWare) {
-            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-        } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
-            //add the default securityGroup only if no security group is specified
-            if (securityGroupIdList == null || securityGroupIdList.isEmpty()) {
-                if (securityGroupIdList == null) {
-                    securityGroupIdList = new ArrayList<Long>();
-                }
-                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(owner.getId());
-                if (defaultGroup != null) {
-                    securityGroupIdList.add(defaultGroup.getId());
-                } else {
-                    // create default security group for the account
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Couldn't find default security group for the account " + owner + " so creating a new one");
-                    }
-                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
-                            owner.getDomainId(), owner.getId(), owner.getAccountName());
-                    securityGroupIdList.add(defaultGroup.getId());
-                }
-            }
-        }
-
-        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
-                userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
-
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
-    public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
-            List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
-            HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
-            List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException,
-    ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-        boolean isSecurityGroupEnabledNetworkUsed = false;
-        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
-
-        // Verify that caller can perform actions in behalf of vm owner
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        // Verify that owner can use the service offering
-        _accountMgr.checkAccess(owner, serviceOffering);
-        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
-
-        // If no network is specified, find system security group enabled network
-        if (networkIdList == null || networkIdList.isEmpty()) {
-            Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId());
-            if (networkWithSecurityGroup == null) {
-                throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid());
-            }
-
-            networkList.add(_networkDao.findById(networkWithSecurityGroup.getId()));
-            isSecurityGroupEnabledNetworkUsed = true;
-
-        } else if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
-            if (isVmWare) {
-                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-            }
-            // Only one network can be specified, and it should be security group enabled
-            if (networkIdList.size() > 1) {
-                throw new InvalidParameterValueException("Only support one network per VM if security group enabled");
-            }
-
-            NetworkVO network = _networkDao.findById(networkIdList.get(0));
-
-            if (network == null) {
-                throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
-            }
-
-            if (!_networkModel.isSecurityGroupSupportedInNetwork(network)) {
-                throw new InvalidParameterValueException("Network is not security group enabled: " + network.getId());
-            }
-
-            networkList.add(network);
-            isSecurityGroupEnabledNetworkUsed = true;
-
-        } else {
-            // Verify that all the networks are Shared/Guest; can't create combination of SG enabled and disabled networks
-            for (Long networkId : networkIdList) {
-                NetworkVO network = _networkDao.findById(networkId);
-
-                if (network == null) {
-                    throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
-                }
-
-                boolean isSecurityGroupEnabled = _networkModel.isSecurityGroupSupportedInNetwork(network);
-                if (isSecurityGroupEnabled) {
-                    if (networkIdList.size() > 1) {
-                        throw new InvalidParameterValueException("Can't create a vm with multiple networks one of" + " which is Security Group enabled");
-                    }
-
-                    isSecurityGroupEnabledNetworkUsed = true;
-                }
-
-                if (!(network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared)) {
-                    throw new InvalidParameterValueException("Can specify only Shared Guest networks when" + " deploy vm in Advance Security Group enabled zone");
-                }
-
-                // Perform account permission check
-                if (network.getAclType() == ACLType.Account) {
-                    _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
-                }
-                networkList.add(network);
-            }
-        }
-
-        // if network is security group enabled, and no security group is specified, then add the default security group automatically
-        if (isSecurityGroupEnabledNetworkUsed && !isVmWare && _networkModel.canAddDefaultSecurityGroup()) {
-
-            //add the default securityGroup only if no security group is specified
-            if (securityGroupIdList == null || securityGroupIdList.isEmpty()) {
-                if (securityGroupIdList == null) {
-                    securityGroupIdList = new ArrayList<Long>();
-                }
-
-                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(owner.getId());
-                if (defaultGroup != null) {
-                    securityGroupIdList.add(defaultGroup.getId());
-                } else {
-                    // create default security group for the account
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Couldn't find default security group for the account " + owner + " so creating a new one");
-                    }
-                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
-                            owner.getDomainId(), owner.getId(), owner.getAccountName());
-                    securityGroupIdList.add(defaultGroup.getId());
-                }
-            }
-        }
-
-        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
-                userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
-    public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
-            String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
-            String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List<Long> affinityGroupIdList,
-            Map<String, String> customParametrs, String customId, Map<String, Map<Integer, String>> dhcpOptionsMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
-    StorageUnavailableException, ResourceAllocationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-
-        // Verify that caller can perform actions in behalf of vm owner
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        // Verify that owner can use the service offering
-        _accountMgr.checkAccess(owner, serviceOffering);
-        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
-
-        List<HypervisorType> vpcSupportedHTypes = _vpcMgr.getSupportedVpcHypervisors();
-        if (networkIdList == null || networkIdList.isEmpty()) {
-            NetworkVO defaultNetwork = null;
-
-            // if no network is passed in
-            // Check if default virtual network offering has
-            // Availability=Required. If it's true, search for corresponding
-            // network
-            // * if network is found, use it. If more than 1 virtual network is
-            // found, throw an error
-            // * if network is not found, create a new one and use it
-
-            List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-            if (requiredOfferings.size() < 1) {
-                throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
-                        + " to automatically create the network as a part of vm creation");
-            }
-
-            if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
-                // get Virtual networks
-                List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated);
-                if (virtualNetworks == null) {
-                    throw new InvalidParameterValueException("No (virtual) networks are found for account " + owner);
-                }
-                if (virtualNetworks.isEmpty()) {
-                    long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
-                    // Validate physical network
-                    PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-                    if (physicalNetwork == null) {
-                        throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
-                                + requiredOfferings.get(0).getTags());
-                    }
-                    s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
-                    Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
-                            null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null,
-                            null);
-                    if (newNetwork != null) {
-                        defaultNetwork = _networkDao.findById(newNetwork.getId());
-                    }
-                } else if (virtualNetworks.size() > 1) {
-                    throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds");
-                } else {
-                    defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
-                }
-            } else {
-                throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
-            }
-
-            if (defaultNetwork != null) {
-                networkList.add(defaultNetwork);
-            }
-
-        } else {
-            for (Long networkId : networkIdList) {
-                NetworkVO network = _networkDao.findById(networkId);
-                if (network == null) {
-                    throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
-                }
-                if (network.getVpcId() != null) {
-                    // Only ISOs, XenServer, KVM, and VmWare template types are
-                    // supported for vpc networks
-                    if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) {
-                        throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + template.getHypervisorType() + " in vpc network " + network);
-                    } else if (template.getFormat() == ImageFormat.ISO && !vpcSupportedHTypes.contains(hypervisor)) {
-                        // Only XenServer, KVM, and VMware hypervisors are supported
-                        // for vpc networks
-                        throw new InvalidParameterValueException("Can't create vm of hypervisor type " + hypervisor + " in vpc network");
-
-                    }
-                }
-
-                _networkModel.checkNetworkPermissions(owner, network);
-
-                // don't allow to use system networks
-                NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-                if (networkOffering.isSystemOnly()) {
-                    throw new InvalidParameterValueException("Network id=" + networkId + " is system only and can't be used for vm deployment");
-                }
-                networkList.add(network);
-            }
-        }
-        verifyExtraDhcpOptionsNetwork(dhcpOptionsMap, networkList);
-
-        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData,
-                sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, dhcpOptionsMap, dataDiskTemplateToDiskOfferingMap);
-    }
-
-    private void verifyExtraDhcpOptionsNetwork(Map<String, Map<Integer, String>> dhcpOptionsMap, List<NetworkVO> networkList) throws InvalidParameterValueException {
-        if (dhcpOptionsMap != null) {
-            for (String networkUuid : dhcpOptionsMap.keySet()) {
-                boolean networkFound = false;
-                for (NetworkVO network : networkList) {
-                    if (network.getUuid().equals(networkUuid)) {
-                        networkFound = true;
-                        break;
-                    }
-                }
-
-                if (!networkFound) {
-                    throw new InvalidParameterValueException("VM does not has a nic in the Network (" + networkUuid + ") that is specified in the extra dhcp options.");
-                }
-            }
-        }
-    }
-
-    public void checkNameForRFCCompliance(String name) {
-        if (!NetUtils.verifyDomainNameLabel(name, true)) {
-            throw new InvalidParameterValueException("Invalid name. Vm name can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
-                    + "and the hyphen ('-'), must be between 1 and 63 characters long, and can't start or end with \"-\" and can't start with digit");
-        }
-    }
-
-    @DB
-    private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner,
-            Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod, String userData,
-            String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard,
-            List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ResourceUnavailableException,
-    ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
-
-        _accountMgr.checkAccess(caller, null, true, owner);
-
-        if (owner.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of vm to deploy is disabled: " + owner);
-        }
-        VMTemplateVO template = _templateDao.findById(tmplt.getId());
-        if (template != null) {
-            _templateDao.loadDetails(template);
-        }
-
-        HypervisorType hypervisorType = null;
-        if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) {
-            if (hypervisor == null || hypervisor == HypervisorType.None) {
-                throw new InvalidParameterValueException("hypervisor parameter is needed to deploy VM or the hypervisor parameter value passed is invalid");
-            }
-            hypervisorType = hypervisor;
-        } else {
-            if (hypervisor != null && hypervisor != HypervisorType.None && hypervisor != template.getHypervisorType()) {
-                throw new InvalidParameterValueException("Hypervisor passed to the deployVm call, is different from the hypervisor type of the template");
-            }
-            hypervisorType = template.getHypervisorType();
-        }
-
-        long accountId = owner.getId();
-
-        assert !(requestedIps != null && (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null)) : "requestedIp list and defaultNetworkIp should never be specified together";
-
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
-                && !_accountMgr.isRootAdmin(caller.getId())) {
-            throw new PermissionDeniedException(
-                    "Cannot perform this operation, Zone is currently disabled: "
-                            + zone.getId());
-        }
-
-        // check if zone is dedicated
-        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zone.getId());
-        if (dedicatedZone != null) {
-            DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId());
-            if (domain == null) {
-                throw new CloudRuntimeException("Unable to find the domain " + zone.getDomainId() + " for the zone: " + zone);
-            }
-            // check that caller can operate with domain
-            _configMgr.checkZoneAccess(caller, zone);
-            // check that vm owner can create vm in the domain
-            _configMgr.checkZoneAccess(owner, zone);
-        }
-
-        ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId());
-        if (offering.isDynamic()) {
-            offering.setDynamicFlag(true);
-            validateCustomParameters(offering, customParameters);
-            offering = _offeringDao.getcomputeOffering(offering, customParameters);
-        }
-        // check if account/domain is with in resource limits to create a new vm
-        boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
-        long size = 0;
-        // custom root disk size, resizes base template to larger size
-        if (customParameters.containsKey("rootdisksize")) {
-            // only KVM, XenServer and VMware supports rootdisksize override
-            if (!(hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.XenServer || hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.Simulator)) {
-                throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support rootdisksize override");
-            }
-
-            Long rootDiskSize = NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1);
-            if (rootDiskSize <= 0) {
-                throw new InvalidParameterValueException("Root disk size should be a positive number.");
-            }
-            size = rootDiskSize * GiB_TO_BYTES;
-        } else {
-            // For baremetal, size can be null
-            Long templateSize = _templateDao.findById(template.getId()).getSize();
-            if (templateSize != null) {
-                size = templateSize;
-            }
-        }
-        if (diskOfferingId != null) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            if (diskOffering != null && diskOffering.isCustomized()) {
-                if (diskSize == null) {
-                    throw new InvalidParameterValueException("This disk offering requires a custom size specified");
-                }
-                Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
-                Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
-                if ((diskSize < customDiskOfferingMinSize) || (diskSize > customDiskOfferingMaxSize)) {
-                    throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize
-                            + " Min:" + customDiskOfferingMinSize);
-                }
-                size += diskSize * GiB_TO_BYTES;
-            }
-            size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
-        }
-        resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
-
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2));
-        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size);
-
-        // verify security group ids
-        if (securityGroupIdList != null) {
-            for (Long securityGroupId : securityGroupIdList) {
-                SecurityGroup sg = _securityGroupDao.findById(securityGroupId);
-                if (sg == null) {
-                    throw new InvalidParameterValueException("Unable to find security group by id " + securityGroupId);
-                } else {
-                    // verify permissions
-                    _accountMgr.checkAccess(caller, null, true, owner, sg);
-                }
-            }
-        }
-
-        if (datadiskTemplateToDiskOfferringMap != null && !datadiskTemplateToDiskOfferringMap.isEmpty()) {
-            for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : datadiskTemplateToDiskOfferringMap.entrySet()) {
-                VMTemplateVO dataDiskTemplate = _templateDao.findById(datadiskTemplateToDiskOffering.getKey());
-                DiskOffering dataDiskOffering = datadiskTemplateToDiskOffering.getValue();
-
-                if (dataDiskTemplate == null
-                        || (!dataDiskTemplate.getTemplateType().equals(TemplateType.DATADISK)) && (dataDiskTemplate.getState().equals(VirtualMachineTemplate.State.Active))) {
-                    throw new InvalidParameterValueException("Invalid template id specified for Datadisk template" + datadiskTemplateToDiskOffering.getKey());
-                }
-                long dataDiskTemplateId = datadiskTemplateToDiskOffering.getKey();
-                if (!dataDiskTemplate.getParentTemplateId().equals(template.getId())) {
-                    throw new InvalidParameterValueException("Invalid Datadisk template. Specified Datadisk template" + dataDiskTemplateId
-                            + " doesn't belong to template " + template.getId());
-                }
-                if (dataDiskOffering == null) {
-                    throw new InvalidParameterValueException("Invalid disk offering id " + datadiskTemplateToDiskOffering.getValue().getId() +
-                            " specified for datadisk template " + dataDiskTemplateId);
-                }
-                if (dataDiskOffering.isCustomized()) {
-                    throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
-                            dataDiskTemplateId + ". Custom Disk offerings are not supported for Datadisk templates");
-                }
-                if (dataDiskOffering.getDiskSize() < dataDiskTemplate.getSize()) {
-                    throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
-                            dataDiskTemplateId + ". Disk offering size should be greater than or equal to the template size");
-                }
-                _templateDao.loadDetails(dataDiskTemplate);
-                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, 1);
-                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, dataDiskOffering.getDiskSize());
-            }
-        }
-
-        // check that the affinity groups exist
-        if (affinityGroupIdList != null) {
-            for (Long affinityGroupId : affinityGroupIdList) {
-                AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
-                if (ag == null) {
-                    throw new InvalidParameterValueException("Unable to find affinity group " + ag);
-                } else if (!_affinityGroupService.isAffinityGroupProcessorAvailable(ag.getType())) {
-                    throw new InvalidParameterValueException("Affinity group type is not supported for group: " + ag + " ,type: " + ag.getType()
-                    + " , Please try again after removing the affinity group");
-                } else {
-                    // verify permissions
-                    if (ag.getAclType() == ACLType.Domain) {
-                        _accountMgr.checkAccess(caller, null, false, owner, ag);
-                        // Root admin has access to both VM and AG by default,
-                        // but
-                        // make sure the owner of these entities is same
-                        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
-                            if (!_affinityGroupService.isAffinityGroupAvailableInDomain(ag.getId(), owner.getDomainId())) {
-                                throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's domain");
-                            }
-                        }
-                    } else {
-                        _accountMgr.checkAccess(caller, null, true, owner, ag);
-                        // Root admin has access to both VM and AG by default,
-                        // but
-                        // make sure the owner of these entities is same
-                        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
-                            if (ag.getAccountId() != owner.getAccountId()) {
-                                throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's account");
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (hypervisorType != HypervisorType.BareMetal) {
-            // check if we have available pools for vm deployment
-            long availablePools = _storagePoolDao.countPoolsByStatus(StoragePoolStatus.Up);
-            if (availablePools < 1) {
-                throw new StorageUnavailableException("There are no available pools in the UP state for vm deployment", -1);
-            }
-        }
-
-        if (template.getTemplateType().equals(TemplateType.SYSTEM)) {
-            throw new InvalidParameterValueException("Unable to use system template " + template.getId() + " to deploy a user vm");
-        }
-        List<VMTemplateZoneVO> listZoneTemplate = _templateZoneDao.listByZoneTemplate(zone.getId(), template.getId());
-        if (listZoneTemplate == null || listZoneTemplate.isEmpty()) {
-            throw new InvalidParameterValueException("The template " + template.getId() + " is not available for use");
-        }
-
-        if (isIso && !template.isBootable()) {
-            throw new InvalidParameterValueException("Installing from ISO requires an ISO that is bootable: " + template.getId());
-        }
-
-        // Check templates permissions
-        _accountMgr.checkAccess(owner, AccessType.UseEntry, false, template);
-
-        // check if the user data is correct
-        userData = validateUserData(userData, httpmethod);
-
-        // Find an SSH public key corresponding to the key pair name, if one is
-        // given
-        String sshPublicKey = null;
-        if (sshKeyPair != null && !sshKeyPair.equals("")) {
-            SSHKeyPair pair = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), sshKeyPair);
-            if (pair == null) {
-                throw new InvalidParameterValueException("A key pair with name '" + sshKeyPair + "' was not found.");
-            }
-
-            sshPublicKey = pair.getPublicKey();
-        }
-
-        List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
-
-        LinkedHashMap<String, NicProfile> networkNicMap = new LinkedHashMap<String, NicProfile>();
-
-        short defaultNetworkNumber = 0;
-        boolean securityGroupEnabled = false;
-        boolean vpcNetwork = false;
-        for (NetworkVO network : networkList) {
-            if ((network.getDataCenterId() != zone.getId())) {
-                if (!network.isStrechedL2Network()) {
-                    throw new InvalidParameterValueException("Network id=" + network.getId() +
-                            " doesn't belong to zone " + zone.getId());
-                }
-
-                NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-                Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType());
-
-                String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity);
-                if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
-                    throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" +
-                            " streched to the zone, as we could not find a valid physical network");
-                }
-            }
-
-            //relax the check if the caller is admin account
-            if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
-                if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain)
-                        && !(network.getAclType() == ACLType.Account && network.getAccountId() == accountId)) {
-                    throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vm");
-                }
-            }
-
-            IpAddresses requestedIpPair = null;
-            if (requestedIps != null && !requestedIps.isEmpty()) {
-                requestedIpPair = requestedIps.get(network.getId());
-            }
-
-            if (requestedIpPair == null) {
-                requestedIpPair = new IpAddresses(null, null);
-            } else {
-                _networkModel.checkRequestedIpAddresses(network.getId(), requestedIpPair);
-            }
-
-            NicProfile profile = new NicProfile(requestedIpPair.getIp4Address(), requestedIpPair.getIp6Address(), requestedIpPair.getMacAddress());
-
-            if (defaultNetworkNumber == 0) {
-                defaultNetworkNumber++;
-                // if user requested specific ip for default network, add it
-                if (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null) {
-                    _networkModel.checkRequestedIpAddresses(network.getId(), defaultIps);
-                    profile = new NicProfile(defaultIps.getIp4Address(), defaultIps.getIp6Address());
-                } else if (defaultIps.getMacAddress() != null) {
-                    profile = new NicProfile(null, null, defaultIps.getMacAddress());
-                }
-
-                profile.setDefaultNic(true);
-                if (!_networkModel.areServicesSupportedInNetwork(network.getId(), new Service[]{Service.UserData})) {
-                    if ((userData != null) && (!userData.isEmpty())) {
-                        throw new InvalidParameterValueException("Unable to deploy VM as UserData is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
-                    }
-
-                    if ((sshPublicKey != null) && (!sshPublicKey.isEmpty())) {
-                        throw new InvalidParameterValueException("Unable to deploy VM as SSH keypair is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
-                    }
-
-                    if (template.getEnablePassword()) {
-                        throw new InvalidParameterValueException("Unable to deploy VM as template " + template.getId() + " is password enabled, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
-                    }
-                }
-            }
-
-            networks.add(new Pair<NetworkVO, NicProfile>(network, profile));
-
-            if (_networkModel.isSecurityGroupSupportedInNetwork(network)) {
-                securityGroupEnabled = true;
-            }
-
-            // vm can't be a part of more than 1 VPC network
-            if (network.getVpcId() != null) {
-                if (vpcNetwork) {
-                    throw new InvalidParameterValueException("Vm can't be a part of more than 1 VPC network");
-                }
-                vpcNetwork = true;
-            }
-
-            networkNicMap.put(network.getUuid(), profile);
-        }
-
-        if (securityGroupIdList != null && !securityGroupIdList.isEmpty() && !securityGroupEnabled) {
-            throw new InvalidParameterValueException("Unable to deploy vm with security groups as SecurityGroup service is not enabled for the vm's network");
-        }
-
-        // Verify network information - network default network has to be set;
-        // and vm can't have more than one default network
-        // This is a part of business logic because default network is required
-        // by Agent Manager in order to configure default
-        // gateway for the vm
-        if (defaultNetworkNumber == 0) {
-            throw new InvalidParameterValueException("At least 1 default network has to be specified for the vm");
-        } else if (defaultNetworkNumber > 1) {
-            throw new InvalidParameterValueException("Only 1 default network per vm is supported");
-        }
-
-        long id = _vmDao.getNextInSequence(Long.class, "id");
-
-        if (hostName != null) {
-            // Check is hostName is RFC compliant
-            checkNameForRFCCompliance(hostName);
-        }
-
-        String instanceName = null;
-        String uuidName = _uuidMgr.generateUuid(UserVm.class, customId);
-        if (_instanceNameFlag && hypervisor.equals(HypervisorType.VMware)) {
-            if (hostName == null) {
-                if (displayName != null) {
-                    hostName = displayName;
-                } else {
-                    hostName = generateHostName(uuidName);
-                }
-            }
-            // If global config vm.instancename.flag is set to true, then CS will set guest VM's name as it appears on the hypervisor, to its hostname.
-            // In case of VMware since VM name must be unique within a DC, check if VM with the same hostname already exists in the zone.
-            VMInstanceVO vmByHostName = _vmInstanceDao.findVMByHostNameInZone(hostName, zone.getId());
-            if (vmByHostName != null && vmByHostName.getState() != VirtualMachine.State.Expunging) {
-                throw new InvalidParameterValueException("There already exists a VM by the name: " + hostName + ".");
-            }
-        } else {
-            if (hostName == null) {
-                //Generate name using uuid and instance.name global config
-                hostName = generateHostName(uuidName);
-            }
-        }
-
-        if (hostName != null) {
-            // Check is hostName is RFC compliant
-            checkNameForRFCCompliance(hostName);
-        }
-        instanceName = VirtualMachineName.getVmName(id, owner.getId(), _instance);
-
-        // Check if VM with instanceName already exists.
-        VMInstanceVO vmObj = _vmInstanceDao.findVMByInstanceName(instanceName);
-        if (vmObj != null && vmObj.getState() != VirtualMachine.State.Expunging) {
-            throw new InvalidParameterValueException("There already exists a VM by the display name supplied");
-        }
-
-        checkIfHostNameUniqueInNtwkDomain(hostName, networkList);
-
-        long userId = CallContext.current().getCallingUserId();
-        if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
-            List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
-            if (!userVOs.isEmpty()) {
-                userId =  userVOs.get(0).getId();
-            }
-        }
-
-        UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering,
-                isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dhcpOptionMap, datadiskTemplateToDiskOfferringMap);
-
-        // Assign instance to the group
-        try {
-            if (group != null) {
-                boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group);
-                if (!addToGroup) {
-                    throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
-                }
-            }
-        } catch (Exception ex) {
-            throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
-        }
-
-        _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
-
-        if (affinityGroupIdList != null && !affinityGroupIdList.isEmpty()) {
-            _affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
-        }
-
-        CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
-        return vm;
-    }
-
-    private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
-        // Check that hostName is unique in the network domain
-        Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
-        for (Network network : networkList) {
-            String ntwkDomain = network.getNetworkDomain();
-            if (!ntwkDomains.containsKey(ntwkDomain)) {
-                List<Long> ntwkIds = new ArrayList<Long>();
-                ntwkIds.add(network.getId());
-                ntwkDomains.put(ntwkDomain, ntwkIds);
-            } else {
-                List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
-                ntwkIds.add(network.getId());
-                ntwkDomains.put(ntwkDomain, ntwkIds);
-            }
-        }
-
-        for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
-            for (Long ntwkId : ntwkDomain.getValue()) {
-                // * get all vms hostNames in the network
-                List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
-                // * verify that there are no duplicates
-                if (hostNames.contains(hostName)) {
-                    throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
-                            + _networkModel.getNetwork(ntwkId));
-                }
-            }
-        }
-    }
-
-    private String generateHostName(String uuidName) {
-        return _instance + "-" + uuidName;
-    }
-
-    private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplate template, final String hostName, final String displayName, final Account owner,
-            final Long diskOfferingId, final Long diskSize, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
-            final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, NicProfile> networkNicMap,
-            final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters, final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException {
-        return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
-            @Override
-            public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
-                UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.getOfferHA(),
-                        offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, hostName, diskOfferingId);
-                vm.setUuid(uuidName);
-                vm.setDynamicallyScalable(template.isDynamicallyScalable());
-
-                Map<String, String> details = template.getDetails();
-                if (details != null && !details.isEmpty()) {
-                    vm.details.putAll(details);
-                }
-
-                if (sshPublicKey != null) {
-                    vm.setDetail("SSH.PublicKey", sshPublicKey);
-                }
-
-                if (keyboard != null && !keyboard.isEmpty()) {
-                    vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
-                }
-
-                if (isIso) {
-                    vm.setIsoId(template.getId());
-                }
-                Long rootDiskSize = null;
-                // custom root disk size, resizes base template to larger size
-                if (customParameters.containsKey("rootdisksize")) {
-                    // already verified for positive number
-                    rootDiskSize = Long.parseLong(customParameters.get("rootdisksize"));
-
-                    VMTemplateVO templateVO = _templateDao.findById(template.getId());
-                    if (templateVO == null) {
-                        throw new InvalidParameterValueException("Unable to look up template by id " + template.getId());
-                    }
-
-                    validateRootDiskResize(hypervisorType, rootDiskSize, templateVO, vm, customParameters);
-                }
-
-                if (isDisplayVm != null) {
-                    vm.setDisplayVm(isDisplayVm);
-                } else {
-                    vm.setDisplayVm(true);
-                }
-
-                long guestOSId = template.getGuestOSId();
-                GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
-                long guestOSCategoryId = guestOS.getCategoryId();
-                GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
-
-                // If hypervisor is vSphere and OS is OS X, set special settings.
-                if (hypervisorType.equals(HypervisorType.VMware)) {
-                    if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")) {
-                        vm.setDetail("smc.present", "TRUE");
-                        vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
-                        vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
-                        vm.setDetail("firmware", "efi");
-                        s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
-                    } else {
-                        String controllerSetting = _configDao.getValue("vmware.root.disk.controller");
-                        // Don't override if VM already has root/data disk controller detail
-                        if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
-                            vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting);
-                        }
-                        if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
-                            if (controllerSetting.equalsIgnoreCase("scsi")) {
-                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
-                            } else {
-                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
-                            }
-                        }
-                    }
-                }
-
-                _vmDao.persist(vm);
-                for (String key : customParameters.keySet()) {
-                    if( key.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) ||
-                            key.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) ||
-                            key.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
-                        // handle double byte strings.
-                        vm.setDetail(key, Integer.toString(Integer.parseInt(customParameters.get(key))));
-                    } else {
-                        vm.setDetail(key, customParameters.get(key));
-                    }
-                }
-                vm.setDetail("deployvm", "true");
-                _vmDao.saveDetails(vm);
-
-                s_logger.debug("Allocating in the DB for vm");
-                DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
-
-                List<String> computeTags = new ArrayList<String>();
-                computeTags.add(offering.getHostTag());
-
-                List<String> rootDiskTags = new ArrayList<String>();
-                rootDiskTags.add(offering.getTags());
-
-                if (isIso) {
-                    _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
-                            hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
-                            networkNicMap, plan, extraDhcpOptionMap);
-                } else {
-                    _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
-                            offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully allocated DB entry for " + vm);
-                }
-                CallContext.current().setEventDetails("Vm Id: " + vm.getId());
-
-                if (!offering.isDynamic()) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
-                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
-                } else {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
-                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm());
-                }
-
-                //Update Resource Count for the given account
-                resourceCountIncrement(accountId, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
-                return vm;
-            }
-        });
-    }
-
-    public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map<String, String> customParameters) throws InvalidParameterValueException
-    {
-        // rootdisksize must be larger than template.
-        if ((rootDiskSize << 30) < templateVO.getSize()) {
-            Long templateVOSizeGB = templateVO.getSize() / GiB_TO_BYTES;
-            String error = "Unsupported: rootdisksize override is smaller than template size " + templateVO.getSize() + "B (" + templateVOSizeGB + "GB)";
-            s_logger.error(error);
-            throw new InvalidParameterValueException(error);
-        } else if ((rootDiskSize << 30) > templateVO.getSize()) {
-            if (hypervisorType == HypervisorType.VMware && (vm.getDetails() == null || vm.getDetails().get("rootDiskController") == null)) {
-                s_logger.warn("If Root disk controller parameter is not overridden, then Root disk resize may fail because current Root disk controller value is NULL.");
-            } else if (hypervisorType == HypervisorType.VMware && !vm.getDetails().get("rootDiskController").toLowerCase().contains("scsi")) {
-                String error = "Found unsupported root disk controller: " + vm.getDetails().get("rootDiskController");
-                s_logger.error(error);
-                throw new InvalidParameterValueException(error);
-            } else {
-                s_logger.debug("Rootdisksize override validation successful. Template root disk size " + (templateVO.getSize() / GiB_TO_BYTES) + "GB Root disk size specified " + rootDiskSize + "GB");
-            }
-        } else {
-            s_logger.debug("Root disk size specified is " + (rootDiskSize << 30) + "B and Template root disk size is " + templateVO.getSize() + "B. Both are equal so no need to override");
-            customParameters.remove("rootdisksize");
-        }
-    }
-
-
-    @Override
-    public void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType){
-        ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
-        if (!serviceOffering.isDynamic()) {
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
-                    VirtualMachine.class.getName(), vm.getUuid(), isDisplay);
-        }
-        else {
-            Map<String, String> customParameters = new HashMap<String, String>();
-            customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
-            customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
-            customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
-                    VirtualMachine.class.getName(), vm.getUuid(), customParameters, isDisplay);
-        }
-    }
-
-    @Override
-    public HashMap<Long, List<VmNetworkStatsEntry>> getVmNetworkStatistics(long hostId, String hostName, List<Long> vmIds) {
-        HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = new HashMap<Long, List<VmNetworkStatsEntry>>();
-
-        if (vmIds.isEmpty()) {
-            return vmNetworkStatsById;
-        }
-
-        List<String> vmNames = new ArrayList<String>();
-
-        for (Long vmId : vmIds) {
-            UserVmVO vm = _vmDao.findById(vmId);
-            vmNames.add(vm.getInstanceName());
-        }
-
-        Answer answer = _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
-        if (answer == null || !answer.getResult()) {
-            s_logger.warn("Unable to obtain VM network statistics.");
-            return null;
-        } else {
-            HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = ((GetVmNetworkStatsAnswer)answer).getVmNetworkStatsMap();
-
-            if (vmNetworkStatsByName == null) {
-                s_logger.warn("Unable to obtain VM network statistics.");
-                return null;
-            }
-
-            for (String vmName : vmNetworkStatsByName.keySet()) {
-                vmNetworkStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmNetworkStatsByName.get(vmName));
-            }
-        }
-
-        return vmNetworkStatsById;
-    }
-
-    @Override
-    public void collectVmNetworkStatistics (final UserVm userVm) {
-        if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) {
-            return;
-        }
-        s_logger.debug("Collect vm network statistics from host before stopping Vm");
-        long hostId = userVm.getHostId();
-        List<String> vmNames = new ArrayList<String>();
-        vmNames.add(userVm.getInstanceName());
-        final HostVO host = _hostDao.findById(hostId);
-
-        GetVmNetworkStatsAnswer networkStatsAnswer = null;
-        try {
-            networkStatsAnswer = (GetVmNetworkStatsAnswer) _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, host.getGuid(), host.getName()));
-        } catch (Exception e) {
-            s_logger.warn("Error while collecting network stats for vm: " + userVm.getHostName() + " from host: " + host.getName(), e);
-            return;
-        }
-        if (networkStatsAnswer != null) {
-            if (!networkStatsAnswer.getResult()) {
-                s_logger.warn("Error while collecting network stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + networkStatsAnswer.getDetails());
-                return;
-            }
-            try {
-                final GetVmNetworkStatsAnswer networkStatsAnswerFinal = networkStatsAnswer;
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = networkStatsAnswerFinal.getVmNetworkStatsMap();
-                        if (vmNetworkStatsByName == null) {
-                            return;
-                        }
-                        List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsByName.get(userVm.getInstanceName());
-                        if (vmNetworkStats == null) {
-                            return;
-                        }
-
-                        for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
-                            SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
-                            sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
-                            NicVO nic = _nicDao.search(sc_nic, null).get(0);
-                            List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
-                            if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
-                            {
-                                break; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
-                            }
-                            UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
-                            if (previousvmNetworkStats == null) {
-                                previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), userVm.getId(), "UserVm", nic.getNetworkId());
-                                _userStatsDao.persist(previousvmNetworkStats);
-                            }
-                            UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
-
-                            if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
-                                s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
-                                continue;
-                            }
-
-                            if (vmNetworkStat_lock == null) {
-                                s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId());
-                                continue;
-                            }
-
-                            if (previousvmNetworkStats != null
-                                    && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
-                                            || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
-                                s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " +
-                                        "Ignoring current answer. Host: " + host.getName()  + " . VM: " + vmNetworkStat.getVmName() +
-                                        " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived());
-                                continue;
-                            }
-
-                            if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Sent # of bytes that's less than the last one.  " +
-                                            "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
-                                            " Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent());
-                                }
-                                vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
-                            }
-                            vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
-
-                            if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Received # of bytes that's less than the last one.  " +
-                                            "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
-                                            " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived());
-                                }
-                                vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
-                            }
-                            vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
-
-                            if (! _dailyOrHourly) {
-                                //update agg bytes
-                                vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
-                                vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
-                            }
-
-                            _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
-                        }
-                    }
-                });
-            } catch (Exception e) {
-                s_logger.warn("Unable to update vm network statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
-            }
-        }
-    }
-
-    protected String validateUserData(String userData, HTTPMethod httpmethod) {
-        byte[] decodedUserData = null;
-        if (userData != null) {
-
-            if (userData.contains("%")) {
-                try {
-                    userData = URLDecoder.decode(userData, "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                    throw new InvalidParameterValueException("Url decoding of userdata failed.");
-                }
-            }
-
-            if (!Base64.isBase64(userData)) {
-                throw new InvalidParameterValueException("User data is not base64 encoded");
-            }
-            // If GET, use 4K. If POST, support upto 32K.
-            if (httpmethod.equals(HTTPMethod.GET)) {
-                if (userData.length() >= MAX_HTTP_GET_LENGTH) {
-                    throw new InvalidParameterValueException("User data is too long for an http GET request");
-                }
-                decodedUserData = Base64.decodeBase64(userData.getBytes());
-                if (decodedUserData.length > MAX_HTTP_GET_LENGTH) {
-                    throw new InvalidParameterValueException("User data is too long for GET request");
-                }
-            } else if (httpmethod.equals(HTTPMethod.POST)) {
-                if (userData.length() >= MAX_HTTP_POST_LENGTH) {
-                    throw new InvalidParameterValueException("User data is too long for an http POST request");
-                }
-                decodedUserData = Base64.decodeBase64(userData.getBytes());
-                if (decodedUserData.length > MAX_HTTP_POST_LENGTH) {
-                    throw new InvalidParameterValueException("User data is too long for POST request");
-                }
-            }
-
-            if (decodedUserData == null || decodedUserData.length < 1) {
-                throw new InvalidParameterValueException("User data is too short");
-            }
-            // Re-encode so that the '=' paddings are added if necessary since 'isBase64' does not require it, but python does on the VR.
-            return Base64.encodeBase64String(decodedUserData);
-        }
-        return null;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "starting Vm", async = true)
-    public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
-        return startVirtualMachine(cmd, null, cmd.getDeploymentPlanner());
-    }
-
-    private UserVm startVirtualMachine(DeployVMCmd cmd, Map<VirtualMachineProfile.Param, Object> additonalParams, String deploymentPlannerToUse)
-            throws ResourceUnavailableException,
-            InsufficientCapacityException, ConcurrentOperationException {
-
-        long vmId = cmd.getEntityId();
-        Long hostId = cmd.getHostId();
-        UserVmVO vm = _vmDao.findById(vmId);
-
-        Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = null;
-        try {
-            vmParamPair = startVirtualMachine(vmId, hostId, additonalParams, deploymentPlannerToUse);
-            vm = vmParamPair.first();
-
-            // At this point VM should be in "Running" state
-            UserVmVO tmpVm = _vmDao.findById(vm.getId());
-            if (!tmpVm.getState().equals(State.Running)) {
-                // Some other thread changed state of VM, possibly vmsync
-                s_logger.error("VM " + tmpVm + " unexpectedly went to " + tmpVm.getState() + " state");
-                throw new ConcurrentOperationException("Failed to deploy VM "+vm);
-            }
-
-            try {
-                if (!cmd.getDataDiskTemplateToDiskOfferingMap().isEmpty()) {
-                    List<VolumeVO> vols = _volsDao.findByInstance(tmpVm.getId());
-                    for (VolumeVO vol : vols) {
-                        if (vol.getVolumeType() == Volume.Type.DATADISK) {
-                            DiskOffering doff =  _entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
-                            _volService.resizeVolumeOnHypervisor(vol.getId(), doff.getDiskSize(), tmpVm.getHostId(), vm.getInstanceName());
-                        }
-                    }
-                }
-            }
-            catch (Exception e) {
-                s_logger.fatal("Unable to resize the data disk for vm " + vm.getDisplayName() + " due to " + e.getMessage(), e);
-            }
-
-        } finally {
-            updateVmStateForFailedVmCreation(vm.getId(), hostId);
-        }
-
-        // Check that the password was passed in and is valid
-        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
-        if (template.getEnablePassword()) {
-            // this value is not being sent to the backend; need only for api
-            // display purposes
-            vm.setPassword((String)vmParamPair.second().get(VirtualMachineProfile.Param.VmPassword));
-        }
-
-        return vm;
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-        UserVmVO vm = _vmDao.findById(profile.getId());
-        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
-        vm.setDetails(details);
-
-
-        // add userdata info into vm profile
-        Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
-        if(defaultNic != null) {
-            Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
-            if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
-                boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-
-                List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
-                        vm.getUuid(), defaultNic.getIPv4Address(), vm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
-                String vmName = vm.getInstanceName();
-                String configDriveIsoRootFolder = "/tmp";
-                String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
-                profile.setVmData(vmData);
-                profile.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value());
-                profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder);
-                profile.setConfigDriveIsoFile(isoFile);
-            }
-        }
-
-        _templateMgr.prepareIsoForVmProfile(profile, dest);
-        return true;
-    }
-
-    @Override
-    public boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic) {
-        if (!nic.getBroadCastUri().getScheme().equals("pvlan")) {
-            return false;
-        }
-        String op = "add";
-        if (!add) {
-            // "delete" would remove all the rules(if using ovs) related to this vm
-            op = "delete";
-        }
-        Network network = _networkDao.findById(nic.getNetworkId());
-        Host host = _hostDao.findById(hostId);
-        String networkTag = _networkModel.getNetworkTag(host.getHypervisorType(), network);
-        PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadCastUri(), networkTag, nic.getMacAddress());
-        Answer answer = null;
-        try {
-            answer = _agentMgr.send(hostId, cmd);
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Timed Out", e);
-            return false;
-        } catch (AgentUnavailableException e) {
-            s_logger.warn("Agent Unavailable ", e);
-            return false;
-        }
-
-        boolean result = true;
-        if (answer == null || !answer.getResult()) {
-            result = false;
-        }
-        return result;
-    }
-
-    @Override
-    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-        UserVmVO userVm = _vmDao.findById(profile.getId());
-        List<NicVO> nics = _nicDao.listByVmId(userVm.getId());
-        for (NicVO nic : nics) {
-            NetworkVO network = _networkDao.findById(nic.getNetworkId());
-            if (network.getTrafficType() == TrafficType.Guest || network.getTrafficType() == TrafficType.Public) {
-                userVm.setPrivateIpAddress(nic.getIPv4Address());
-                userVm.setPrivateMacAddress(nic.getMacAddress());
-                _vmDao.update(userVm.getId(), userVm);
-            }
-        }
-
-        List<VolumeVO> volumes = _volsDao.findByInstance(userVm.getId());
-        VmDiskStatisticsVO diskstats = null;
-        for (VolumeVO volume : volumes) {
-            diskstats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
-            if (diskstats == null) {
-                diskstats = new VmDiskStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
-                _vmDiskStatsDao.persist(diskstats);
-            }
-        }
-
-        finalizeCommandsOnStart(cmds, profile);
-        return true;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-        UserVmVO vm = _vmDao.findById(profile.getId());
-        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vm.getId());
-        RestoreVMSnapshotCommand command = _vmSnapshotMgr.createRestoreCommand(vm, vmSnapshots);
-        if (command != null) {
-            cmds.addCommand("restoreVMSnapshot", command);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean  finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
-        UserVmVO vm = _vmDao.findById(profile.getId());
-
-        Answer[] answersToCmds = cmds.getAnswers();
-        if (answersToCmds == null) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Returning from finalizeStart() since there are no answers to read");
-            }
-            return true;
-        }
-        Answer startAnswer = cmds.getAnswer(StartAnswer.class);
-        String returnedIp = null;
-        String originalIp = null;
-        if (startAnswer != null) {
-            StartAnswer startAns = (StartAnswer)startAnswer;
-            VirtualMachineTO vmTO = startAns.getVirtualMachine();
-            for (NicTO nicTO : vmTO.getNics()) {
-                if (nicTO.getType() == TrafficType.Guest) {
-                    returnedIp = nicTO.getIp();
-                }
-            }
-        }
-
-        List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        NicVO guestNic = null;
-        NetworkVO guestNetwork = null;
-        for (NicVO nic : nics) {
-            NetworkVO network = _networkDao.findById(nic.getNetworkId());
-            long isDefault = (nic.isDefaultNic()) ? 1 : 0;
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), Long.toString(nic.getId()),
-                    network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
-            if (network.getTrafficType() == TrafficType.Guest) {
-                originalIp = nic.getIPv4Address();
-                guestNic = nic;
-                guestNetwork = network;
-                // In vmware, we will be effecting pvlan settings in portgroups in StartCommand.
-                if (profile.getHypervisorType() != HypervisorType.VMware) {
-                    if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
-                        NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
-                        if (!setupVmForPvlan(true, hostId, nicProfile)) {
-                            return false;
-                        }
-                    }
-                }
-            }
-        }
-        boolean ipChanged = false;
-        if (originalIp != null && !originalIp.equalsIgnoreCase(returnedIp)) {
-            if (returnedIp != null && guestNic != null) {
-                guestNic.setIPv4Address(returnedIp);
-                ipChanged = true;
-            }
-        }
-        if (returnedIp != null && !returnedIp.equalsIgnoreCase(originalIp)) {
-            if (guestNic != null) {
-                guestNic.setIPv4Address(returnedIp);
-                ipChanged = true;
-            }
-        }
-        if (ipChanged) {
-            _dcDao.findById(vm.getDataCenterId());
-            UserVmVO userVm = _vmDao.findById(profile.getId());
-            // dc.getDhcpProvider().equalsIgnoreCase(Provider.ExternalDhcpServer.getName())
-            if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestNetwork.getId(), Service.Dhcp, Provider.ExternalDhcpServer)) {
-                _nicDao.update(guestNic.getId(), guestNic);
-                userVm.setPrivateIpAddress(guestNic.getIPv4Address());
-                _vmDao.update(userVm.getId(), userVm);
-
-                s_logger.info("Detected that ip changed in the answer, updated nic in the db with new ip " + returnedIp);
-            }
-        }
-
-        // get system ip and create static nat rule for the vm
-        try {
-            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
-        } catch (Exception ex) {
-            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
-            return false;
-        }
-
-        Answer answer = cmds.getAnswer("restoreVMSnapshot");
-        if (answer != null && answer instanceof RestoreVMSnapshotAnswer) {
-            RestoreVMSnapshotAnswer restoreVMSnapshotAnswer = (RestoreVMSnapshotAnswer) answer;
-            if (restoreVMSnapshotAnswer == null || !restoreVMSnapshotAnswer.getResult()) {
-                s_logger.warn("Unable to restore the vm snapshot from image file to the VM: " + restoreVMSnapshotAnswer.getDetails());
-            }
-        }
-
-        final VirtualMachineProfile vmProfile = profile;
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                final UserVmVO vm = _vmDao.findById(vmProfile.getId());
-                final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-                for (NicVO nic : nics) {
-                    Network network = _networkModel.getNetwork(nic.getNetworkId());
-                    if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
-                        vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
-                    }
-                }
-            }
-        });
-
-        return true;
-    }
-
-    @Override
-    public void finalizeExpunge(VirtualMachine vm) {
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_STOP, eventDescription = "stopping Vm", async = true)
-    public UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException {
-        // Input validation
-        Account caller = CallContext.current().getCallingAccount();
-        Long userId = CallContext.current().getCallingUserId();
-
-        // if account is removed, return error
-        if (caller != null && caller.getRemoved() != null) {
-            throw new PermissionDeniedException("The account " + caller.getUuid() + " is removed");
-        }
-
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _userDao.findById(userId);
-        boolean status = false;
-        try {
-            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
-
-            if(forced) {
-                status = vmEntity.stopForced(Long.toString(userId));
-            } else {
-                status = vmEntity.stop(Long.toString(userId));
-            }
-            if (status) {
-                return _vmDao.findById(vmId);
-            } else {
-                return null;
-            }
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
-        } catch (CloudException e) {
-            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
-        }
-    }
-
-    @Override
-    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
-        VirtualMachine vm = profile.getVirtualMachine();
-        // release elastic IP here
-        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
-        if (ip != null && ip.getSystem()) {
-            CallContext ctx = CallContext.current();
-            try {
-                long networkId = ip.getAssociatedWithNetworkId();
-                Network guestNetwork = _networkDao.findById(networkId);
-                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
-                assert (offering.getAssociatePublicIP() == true) : "User VM should not have system owned public IP associated with it when offering configured not to associate public IP.";
-                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ", ex);
-            }
-        }
-
-        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
-        for (final NicVO nic : nics) {
-            final NetworkVO network = _networkDao.findById(nic.getNetworkId());
-            if (network != null && network.getTrafficType() == TrafficType.Guest) {
-                final String nicIp = Strings.isNullOrEmpty(nic.getIPv4Address()) ? nic.getIPv6Address() : nic.getIPv4Address();
-                if (!Strings.isNullOrEmpty(nicIp)) {
-                    NicProfile nicProfile = new NicProfile(nic.getIPv4Address(), nic.getIPv6Address(), nic.getMacAddress());
-                    nicProfile.setId(nic.getId());
-                    _networkMgr.cleanupNicDhcpDnsEntry(network, profile, nicProfile);
-                }
-                if (nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) {
-                    NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
-                    setupVmForPvlan(false, vm.getHostId(), nicProfile);
-                }
-            }
-        }
-    }
-
-    @Override
-    public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
-            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        // Input validation
-        Account callerAccount = CallContext.current().getCallingAccount();
-        UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
-
-        // if account is removed, return error
-        if (callerAccount != null && callerAccount.getRemoved() != null) {
-            throw new InvalidParameterValueException("The account " + callerAccount.getId() + " is removed");
-        }
-
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(callerAccount, null, true, vm);
-
-        Account owner = _accountDao.findById(vm.getAccountId());
-
-        if (owner == null) {
-            throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
-        }
-
-        if (owner.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
-        }
-
-        Host destinationHost = null;
-        if (hostId != null) {
-            Account account = CallContext.current().getCallingAccount();
-            if (!_accountService.isRootAdmin(account.getId())) {
-                throw new PermissionDeniedException(
-                        "Parameter hostid can only be specified by a Root Admin, permission denied");
-            }
-            destinationHost = _hostDao.findById(hostId);
-            if (destinationHost == null) {
-                throw new InvalidParameterValueException("Unable to find the host to deploy the VM, host id=" + hostId);
-            }
-        }
-
-        // check if vm is security group enabled
-        if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty()
-                && !_securityGroupMgr.isVmMappedToDefaultSecurityGroup(vmId) && _networkModel.canAddDefaultSecurityGroup()) {
-            // if vm is not mapped to security group, create a mapping
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Vm " + vm + " is security group enabled, but not mapped to default security group; creating the mapping automatically");
-            }
-
-            SecurityGroup defaultSecurityGroup = _securityGroupMgr.getDefaultSecurityGroup(vm.getAccountId());
-            if (defaultSecurityGroup != null) {
-                List<Long> groupList = new ArrayList<Long>();
-                groupList.add(defaultSecurityGroup.getId());
-                _securityGroupMgr.addInstanceToGroups(vmId, groupList);
-            }
-        }
-
-        DataCenterDeployment plan = null;
-        boolean deployOnGivenHost = false;
-        if (destinationHost != null) {
-            s_logger.debug("Destination Host to deploy the VM is specified, specifying a deployment plan to deploy the VM");
-            plan = new DataCenterDeployment(vm.getDataCenterId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null, null);
-            if (!AllowDeployVmIfGivenHostFails.value()) {
-                deployOnGivenHost = true;
-            }
-        }
-
-        // Set parameters
-        Map<VirtualMachineProfile.Param, Object> params = null;
-        VMTemplateVO template = null;
-        if (vm.isUpdateParameters()) {
-            _vmDao.loadDetails(vm);
-            // Check that the password was passed in and is valid
-            template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
-
-            String password = "saved_password";
-            if (template.getEnablePassword()) {
-                if (vm.getDetail("password") != null) {
-                    password = DBEncryptionUtil.decrypt(vm.getDetail("password"));
-                } else {
-                    password = _mgr.generateRandomPassword();
-                    vm.setPassword(password);
-                }
-            }
-
-            if (!validPassword(password)) {
-                throw new InvalidParameterValueException("A valid password for this virtual machine was not provided.");
-            }
-
-            // Check if an SSH key pair was selected for the instance and if so
-            // use it to encrypt & save the vm password
-            encryptAndStorePassword(vm, password);
-
-            params = new HashMap<VirtualMachineProfile.Param, Object>();
-            if (additionalParams != null) {
-                params.putAll(additionalParams);
-            }
-            params.put(VirtualMachineProfile.Param.VmPassword, password);
-        }
-
-        VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
-
-        DeploymentPlanner planner = null;
-        if (deploymentPlannerToUse != null) {
-            // if set to null, the deployment planner would be later figured out either from global config var, or from
-            // the service offering
-            planner = _planningMgr.getDeploymentPlannerByName(deploymentPlannerToUse);
-            if (planner == null) {
-                throw new InvalidParameterValueException("Can't find a planner by name " + deploymentPlannerToUse);
-            }
-        }
-
-        String reservationId = vmEntity.reserve(planner, plan, new ExcludeList(), Long.toString(callerUser.getId()));
-        vmEntity.deploy(reservationId, Long.toString(callerUser.getId()), params, deployOnGivenHost);
-
-        Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = new Pair(vm, params);
-        if (vm != null && vm.isUpdateParameters()) {
-            // this value is not being sent to the backend; need only for api
-            // display purposes
-            if (template.getEnablePassword()) {
-                if (vm.getDetail("password") != null) {
-                    _vmDetailsDao.removeDetail(vm.getId(), "password");
-                }
-                vm.setUpdateParameters(false);
-                _vmDao.update(vm.getId(), vm);
-            }
-        }
-
-        return vmParamPair;
-    }
-
-    @Override
-    public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableException, ConcurrentOperationException {
-        // Account caller = CallContext.current().getCallingAccount();
-        // Long userId = CallContext.current().getCallingUserId();
-        Long userId = 2L;
-
-        // Verify input parameters
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null || vm.getRemoved() != null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId");
-            throw ex;
-        }
-
-        if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
-            s_logger.trace("Vm id=" + vmId + " is already destroyed");
-            return vm;
-        }
-
-        boolean status;
-        State vmState = vm.getState();
-
-        try {
-            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
-            status = vmEntity.destroy(Long.toString(userId), expunge);
-        } catch (CloudException e) {
-            CloudRuntimeException ex = new CloudRuntimeException("Unable to destroy with specified vmId", e);
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        if (status) {
-            // Mark the account's volumes as destroyed
-            List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
-            for (VolumeVO volume : volumes) {
-                if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
-                }
-            }
-
-            if (vmState != State.Error) {
-                // Get serviceOffering for Virtual Machine
-                ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
-
-                //Update Resource Count for the given account
-                resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
-            }
-            return _vmDao.findById(vmId);
-        } else {
-            CloudRuntimeException ex = new CloudRuntimeException("Failed to destroy vm with specified vmId");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-    }
-
-    @Override
-    public void collectVmDiskStatistics(final UserVm userVm) {
-        // support KVM only util 2013.06.25
-        if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) {
-            return;
-        }
-        s_logger.debug("Collect vm disk statistics from host before stopping Vm");
-        long hostId = userVm.getHostId();
-        List<String> vmNames = new ArrayList<String>();
-        vmNames.add(userVm.getInstanceName());
-        final HostVO host = _hostDao.findById(hostId);
-
-        GetVmDiskStatsAnswer diskStatsAnswer = null;
-        try {
-            diskStatsAnswer = (GetVmDiskStatsAnswer)_agentMgr.easySend(hostId, new GetVmDiskStatsCommand(vmNames, host.getGuid(), host.getName()));
-        } catch (Exception e) {
-            s_logger.warn("Error while collecting disk stats for vm: " + userVm.getInstanceName() + " from host: " + host.getName(), e);
-            return;
-        }
-        if (diskStatsAnswer != null) {
-            if (!diskStatsAnswer.getResult()) {
-                s_logger.warn("Error while collecting disk stats vm: " + userVm.getInstanceName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails());
-                return;
-            }
-            try {
-                final GetVmDiskStatsAnswer diskStatsAnswerFinal = diskStatsAnswer;
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = diskStatsAnswerFinal.getVmDiskStatsMap();
-                        if (vmDiskStatsByName == null) {
-                            return;
-                        }
-                        List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName());
-                        if (vmDiskStats == null) {
-                            return;
-                        }
-
-                        for (VmDiskStatsEntry vmDiskStat : vmDiskStats) {
-                            SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
-                            sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
-                            List<VolumeVO> volumes = _volsDao.search(sc_volume, null);
-                            if ((volumes == null) || (volumes.size() == 0)) {
-                                break;
-                            }
-                            VolumeVO volume = volumes.get(0);
-                            VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
-                            VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
-
-                            if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) {
-                                s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics");
-                                continue;
-                            }
-
-                            if (vmDiskStat_lock == null) {
-                                s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId() + " and volumeId:"
-                                        + volume.getId());
-                                continue;
-                            }
-
-                            if (previousVmDiskStats != null
-                                    && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock
-                                    .getCurrentIOWrite())
-                                            || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) || (previousVmDiskStats
-                                                    .getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) {
-                                s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + "Ignoring current answer. Host: " + host.getName()
-                                + " . VM: " + vmDiskStat.getVmName() + " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() + " Bytes Read: "
-                                + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite());
-                                continue;
-                            }
-
-                            if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Read # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
-                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead());
-                                }
-                                vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
-                            }
-                            vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
-                            if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Write # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
-                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite());
-                                }
-                                vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
-                            }
-                            vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
-                            if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Read # of Bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
-                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
-                                }
-                                vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
-                            }
-                            vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
-                            if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Write # of Bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
-                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesWrite() + " Stored: "
-                                    + vmDiskStat_lock.getCurrentBytesWrite());
-                                }
-                                vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
-                            }
-                            vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
-
-                            if (!_dailyOrHourly) {
-                                //update agg bytes
-                                vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
-                                vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
-                                vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
-                                vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
-                            }
-
-                            _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
-                        }
-                    }
-                });
-            } catch (Exception e) {
-                s_logger.warn("Unable to update vm disk statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
-            }
-        }
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true)
-    public UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException {
-        Account caller = CallContext.current().getCallingAccount();
-        Long userId = caller.getId();
-
-        // Verify input parameters
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId");
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-        if (vm.getRemoved() != null) {
-            s_logger.trace("Vm id=" + vmId + " is already expunged");
-            return vm;
-        }
-
-        if (!(vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getState() == State.Error)) {
-            CloudRuntimeException ex = new CloudRuntimeException("Please destroy vm with specified vmId before expunge");
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
-        if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
-            throw new PermissionDeniedException("Expunging a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
-        }
-
-        _vmSnapshotMgr.deleteVMSnapshotsFromDB(vmId);
-
-        boolean status;
-
-        status = expunge(vm, userId, caller);
-        if (status) {
-            return _vmDao.findByIdIncludingRemoved(vmId);
-        } else {
-            CloudRuntimeException ex = new CloudRuntimeException("Failed to expunge vm with specified vmId");
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-    }
-
-    @Override
-    public HypervisorType getHypervisorTypeOfUserVM(long vmId) {
-        UserVmVO userVm = _vmDao.findById(vmId);
-        if (userVm == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-        return userVm.getHypervisorType();
-    }
-
-    @Override
-    public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
-    StorageUnavailableException, ResourceAllocationException {
-        //Verify that all objects exist before passing them to the service
-        Account owner = _accountService.getActiveAccountById(cmd.getEntityOwnerId());
-
-        verifyDetails(cmd.getDetails());
-
-        Long zoneId = cmd.getZoneId();
-
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId);
-        }
-
-        Long serviceOfferingId = cmd.getServiceOfferingId();
-
-        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
-        if (serviceOffering == null) {
-            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
-        }
-
-        Long templateId = cmd.getTemplateId();
-
-        if (!serviceOffering.isDynamic()) {
-            for(String detail: cmd.getDetails().keySet()) {
-                if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
-                    throw new InvalidParameterValueException("cpuNumber or cpuSpeed or memory should not be specified for static service offering");
-                }
-            }
-        }
-
-        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
-        // Make sure a valid template ID was specified
-        if (template == null) {
-            throw new InvalidParameterValueException("Unable to use template " + templateId);
-        }
-
-        Long diskOfferingId = cmd.getDiskOfferingId();
-        DiskOffering diskOffering = null;
-        if (diskOfferingId != null) {
-            diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
-            if (diskOffering == null) {
-                throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
-            }
-        }
-
-        if (!zone.isLocalStorageEnabled()) {
-            if (serviceOffering.getUseLocalStorage()) {
-                throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
-            }
-            if (diskOffering != null && diskOffering.getUseLocalStorage()) {
-                throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it");
-            }
-        }
-
-        String ipAddress = cmd.getIpAddress();
-        String ip6Address = cmd.getIp6Address();
-        String macAddress = cmd.getMacAddress();
-        String name = cmd.getName();
-        String displayName = cmd.getDisplayName();
-        UserVm vm = null;
-        IpAddresses addrs = new IpAddresses(ipAddress, ip6Address, macAddress);
-        Long size = cmd.getSize();
-        String group = cmd.getGroup();
-        String userData = cmd.getUserData();
-        String sshKeyPairName = cmd.getSSHKeyPairName();
-        Boolean displayVm = cmd.getDisplayVm();
-        String keyboard = cmd.getKeyboard();
-        Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = cmd.getDataDiskTemplateToDiskOfferingMap();
-        if (zone.getNetworkType() == NetworkType.Basic) {
-            if (cmd.getNetworkIds() != null) {
-                throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
-            } else {
-                vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId,
-                        size , group , cmd.getHypervisor(), cmd.getHttpMethod(), userData , sshKeyPairName , cmd.getIpToNetworkMap(), addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(),
-                        cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
-            }
-        } else {
-            if (zone.isSecurityGroupEnabled())  {
-                vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), getSecurityGroupIdList(cmd), owner, name,
-                        displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
-                        cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
-
-            } else {
-                if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
-                    throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
-                }
-                vm = createAdvancedVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), owner, name, displayName, diskOfferingId, size, group,
-                        cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(),
-                        cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
-            }
-        }
-        // check if this templateId has a child ISO
-        List<VMTemplateVO> child_templates = _templateDao.listByParentTemplatetId(templateId);
-        for (VMTemplateVO tmpl: child_templates){
-            if (tmpl.getFormat() == Storage.ImageFormat.ISO){
-                s_logger.info("MDOV trying to attach disk to the VM " + tmpl.getId() + " vmid=" + vm.getId());
-                _tmplService.attachIso(tmpl.getId(), vm.getId());
-            }
-        }
-        return vm;
-    }
-
-    protected List<Long> getSecurityGroupIdList(SecurityGroupAction cmd) {
-        if (cmd.getSecurityGroupNameList() != null && cmd.getSecurityGroupIdList() != null) {
-            throw new InvalidParameterValueException("securitygroupids parameter is mutually exclusive with securitygroupnames parameter");
-        }
-
-        //transform group names to ids here
-        if (cmd.getSecurityGroupNameList() != null) {
-            List<Long> securityGroupIds = new ArrayList<Long>();
-            for (String groupName : cmd.getSecurityGroupNameList()) {
-                SecurityGroup sg = _securityGroupMgr.getSecurityGroup(groupName, cmd.getEntityOwnerId());
-                if (sg == null) {
-                    throw new InvalidParameterValueException("Unable to find group by name " + groupName);
-                } else {
-                    securityGroupIds.add(sg.getId());
-                }
-            }
-            return securityGroupIds;
-        } else {
-            return cmd.getSecurityGroupIdList();
-        }
-    }
-
-    // this is an opportunity to verify that parameters that came in via the Details Map are OK
-    // for example, minIops and maxIops should either both be specified or neither be specified and,
-    // if specified, minIops should be <= maxIops
-    private void verifyDetails(Map<String,String> details) {
-        if (details != null) {
-            String minIops = details.get("minIops");
-            String maxIops = details.get("maxIops");
-
-            verifyMinAndMaxIops(minIops, maxIops);
-
-            minIops = details.get("minIopsDo");
-            maxIops = details.get("maxIopsDo");
-
-            verifyMinAndMaxIops(minIops, maxIops);
-        }
-    }
-
-    private void verifyMinAndMaxIops(String minIops, String maxIops) {
-        if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) {
-            throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified.");
-        }
-
-        long lMinIops;
-
-        try {
-            if (minIops != null) {
-                lMinIops = Long.parseLong(minIops);
-            }
-            else {
-                lMinIops = 0;
-            }
-        }
-        catch (NumberFormatException ex) {
-            throw new InvalidParameterValueException("'Min IOPS' must be a whole number.");
-        }
-
-        long lMaxIops;
-
-        try {
-            if (maxIops != null) {
-                lMaxIops = Long.parseLong(maxIops);
-            }
-            else {
-                lMaxIops = 0;
-            }
-        }
-        catch (NumberFormatException ex) {
-            throw new InvalidParameterValueException("'Max IOPS' must be a whole number.");
-        }
-
-        if (lMinIops > lMaxIops) {
-            throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'.");
-        }
-    }
-
-    @Override
-    public UserVm getUserVm(long vmId) {
-        return _vmDao.findById(vmId);
-    }
-
-    @Override
-    public VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool) {
-        // access check - only root admin can migrate VM
-        Account caller = CallContext.current().getCallingAccount();
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
-            }
-            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
-        }
-
-        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId);
-        }
-
-        if (vm.getState() != State.Stopped) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm having the specified id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        if (vm.getType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException("can only do storage migration on user vm");
-        }
-
-        List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
-        if (vols.size() > 1) {
-            throw new InvalidParameterValueException("Data disks attached to the vm, can not migrate. Need to detach data disks first");
-        }
-
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("VM's disk cannot be migrated, please remove all the VM Snapshots for this VM");
-        }
-
-        HypervisorType destHypervisorType = destPool.getHypervisor();
-        if (destHypervisorType == null) {
-            destHypervisorType = _clusterDao.findById(
-                    destPool.getClusterId()).getHypervisorType();
-        }
-
-        if (vm.getHypervisorType() != destHypervisorType && destHypervisorType != HypervisorType.Any) {
-            throw new InvalidParameterValueException("hypervisor is not compatible: dest: " + destHypervisorType.toString() + ", vm: " + vm.getHypervisorType().toString());
-        }
-        _itMgr.storageMigration(vm.getUuid(), destPool);
-        return _vmDao.findById(vm.getId());
-
-    }
-
-    private boolean isVMUsingLocalStorage(VMInstanceVO vm) {
-        boolean usesLocalStorage = false;
-        ServiceOfferingVO svcOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
-        if (svcOffering.getUseLocalStorage()) {
-            usesLocalStorage = true;
-        } else {
-            List<VolumeVO> volumes = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.DATADISK);
-            for (VolumeVO vol : volumes) {
-                DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
-                if (diskOffering.getUseLocalStorage()) {
-                    usesLocalStorage = true;
-                    break;
-                }
-            }
-        }
-        return usesLocalStorage;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
-    public VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
-    VirtualMachineMigrationException {
-        // access check - only root admin can migrate VM
-        Account caller = CallContext.current().getCallingAccount();
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
-            }
-            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
-        }
-
-        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId);
-        }
-        // business logic
-        if (vm.getState() != State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
-            }
-            InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        checkIfHostOfVMIsInPrepareForMaintenanceState(vm.getHostId(), vmId, "Migrate");
-
-        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
-            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
-        }
-
-        if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
-                && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)
-                && !vm.getHypervisorType().equals(HypervisorType.LXC) && !vm.getHypervisorType().equals(HypervisorType.Simulator)
-                && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv, cannot migrate this VM.");
-            }
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
-        }
-
-        if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
-        }
-
-        if (isVMUsingLocalStorage(vm)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(vm + " is using Local Storage, cannot migrate this VM.");
-            }
-            throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate");
-        }
-
-        // check if migrating to same host
-        long srcHostId = vm.getHostId();
-        if (destinationHost.getId() == srcHostId) {
-            throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please specify valid destination host to migrate the VM");
-        }
-
-        // check if host is UP
-        if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) {
-            throw new InvalidParameterValueException("Cannot migrate VM, destination host is not in correct state, has status: " + destinationHost.getState() + ", state: "
-                    + destinationHost.getResourceState());
-        }
-
-        if (vm.getType() != VirtualMachine.Type.User) {
-            // for System VMs check that the destination host is within the same
-            // cluster
-            HostVO srcHost = _hostDao.findById(srcHostId);
-            if (srcHost != null && srcHost.getClusterId() != null && destinationHost.getClusterId() != null) {
-                if (srcHost.getClusterId().longValue() != destinationHost.getClusterId().longValue()) {
-                    throw new InvalidParameterValueException("Cannot migrate the VM, destination host is not in the same cluster as current host of the VM");
-                }
-            }
-        }
-
-        checkHostsDedication(vm, srcHostId, destinationHost.getId());
-
-        // call to core process
-        DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId());
-        HostPodVO pod = _podDao.findById(destinationHost.getPodId());
-        Cluster cluster = _clusterDao.findById(destinationHost.getClusterId());
-        DeployDestination dest = new DeployDestination(dcVO, pod, cluster, destinationHost);
-
-        // check max guest vm limit for the destinationHost
-        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
-        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Host name: " + destinationHost.getName() + ", hostId: " + destinationHost.getId()
-                + " already has max Running VMs(count includes system VMs), cannot migrate to this host");
-            }
-            throw new VirtualMachineMigrationException("Destination host, hostId: " + destinationHost.getId()
-            + " already has max Running VMs(count includes system VMs), cannot migrate to this host");
-        }
-        //check if there are any ongoing volume snapshots on the volumes associated with the VM.
-        s_logger.debug("Checking if there are any ongoing snapshots volumes associated with VM with ID " + vmId);
-        if (checkStatusOfVolumeSnapshots(vmId, null)) {
-            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on volume(s) attached to this VM, VM Migration is not permitted, please try again later.");
-        }
-        s_logger.debug("Found no ongoing snapshots on volumes associated with the vm with id " + vmId);
-
-        UserVmVO uservm = _vmDao.findById(vmId);
-        if (uservm != null) {
-            collectVmDiskStatistics(uservm);
-            collectVmNetworkStatistics(uservm);
-        }
-        _itMgr.migrate(vm.getUuid(), srcHostId, dest);
-        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
-        if (vmInstance.getType().equals(VirtualMachine.Type.User)) {
-            return _vmDao.findById(vmId);
-        } else {
-            return vmInstance;
-        }
-    }
-
-    private boolean checkIfHostIsDedicated(HostVO host) {
-        long hostId = host.getId();
-        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
-        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
-        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
-        if (dedicatedHost != null || dedicatedClusterOfHost != null || dedicatedPodOfHost != null) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private void checkIfHostOfVMIsInPrepareForMaintenanceState(Long hostId, Long vmId, String operation) {
-        HostVO host = _hostDao.findById(hostId);
-        if (host.getResourceState() != ResourceState.PrepareForMaintenance) {
-            return;
-        }
-
-        s_logger.debug("Host is in PrepareForMaintenance state - " + operation + " VM operation on the VM id: " + vmId + " is not allowed");
-        throw new InvalidParameterValueException(operation + " VM operation on the VM id: " + vmId + " is not allowed as host is preparing for maintenance mode");
-    }
-
-    private Long accountOfDedicatedHost(HostVO host) {
-        long hostId = host.getId();
-        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
-        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
-        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
-        if (dedicatedHost != null) {
-            return dedicatedHost.getAccountId();
-        }
-        if (dedicatedClusterOfHost != null) {
-            return dedicatedClusterOfHost.getAccountId();
-        }
-        if (dedicatedPodOfHost != null) {
-            return dedicatedPodOfHost.getAccountId();
-        }
-        return null;
-    }
-
-    private Long domainOfDedicatedHost(HostVO host) {
-        long hostId = host.getId();
-        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
-        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
-        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
-        if (dedicatedHost != null) {
-            return dedicatedHost.getDomainId();
-        }
-        if (dedicatedClusterOfHost != null) {
-            return dedicatedClusterOfHost.getDomainId();
-        }
-        if (dedicatedPodOfHost != null) {
-            return dedicatedPodOfHost.getDomainId();
-        }
-        return null;
-    }
-
-    public void checkHostsDedication(VMInstanceVO vm, long srcHostId, long destHostId) {
-        HostVO srcHost = _hostDao.findById(srcHostId);
-        HostVO destHost = _hostDao.findById(destHostId);
-        boolean srcExplDedicated = checkIfHostIsDedicated(srcHost);
-        boolean destExplDedicated = checkIfHostIsDedicated(destHost);
-        //if srcHost is explicitly dedicated and destination Host is not
-        if (srcExplDedicated && !destExplDedicated) {
-            //raise an alert
-            String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() + " to non-dedicated host " + destHost.getName();
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-            s_logger.warn(msg);
-        }
-        //if srcHost is non dedicated but destination Host is explicitly dedicated
-        if (!srcExplDedicated && destExplDedicated) {
-            //raise an alert
-            String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host " + destHost.getName();
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-            s_logger.warn(msg);
-        }
-
-        //if hosts are dedicated to different account/domains, raise an alert
-        if (srcExplDedicated && destExplDedicated) {
-            if (!((accountOfDedicatedHost(srcHost) == null) || (accountOfDedicatedHost(srcHost).equals(accountOfDedicatedHost(destHost))))) {
-                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host "
-                        + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost);
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-                s_logger.warn(msg);
-            }
-            if (!((domainOfDedicatedHost(srcHost) == null) || (domainOfDedicatedHost(srcHost).equals(domainOfDedicatedHost(destHost))))) {
-                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host "
-                        + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost);
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-                s_logger.warn(msg);
-            }
-        }
-
-        // Checks for implicitly dedicated hosts
-        ServiceOfferingVO deployPlanner = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
-        if (deployPlanner.getDeploymentPlanner() != null && deployPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) {
-            //VM is deployed using implicit planner
-            long accountOfVm = vm.getAccountId();
-            String msg = "VM of account " + accountOfVm + " with implicit deployment planner being migrated to host " + destHost.getName();
-            //Get all vms on destination host
-            boolean emptyDestination = false;
-            List<VMInstanceVO> vmsOnDest = getVmsOnHost(destHostId);
-            if (vmsOnDest == null || vmsOnDest.isEmpty()) {
-                emptyDestination = true;
-            }
-
-            if (!emptyDestination) {
-                //Check if vm is deployed using strict implicit planner
-                if (!isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
-                    //Check if all vms on destination host are created using strict implicit mode
-                    if (!checkIfAllVmsCreatedInStrictMode(accountOfVm, vmsOnDest)) {
-                        msg = "VM of account " + accountOfVm + " with strict implicit deployment planner being migrated to host " + destHost.getName()
-                        + " not having all vms strict implicitly dedicated to account " + accountOfVm;
-                    }
-                } else {
-                    //If vm is deployed using preferred implicit planner, check if all vms on destination host must be
-                    //using implicit planner and must belong to same account
-                    for (VMInstanceVO vmsDest : vmsOnDest) {
-                        ServiceOfferingVO destPlanner = _offeringDao.findById(vm.getId(), vmsDest.getServiceOfferingId());
-                        if (!((destPlanner.getDeploymentPlanner() != null && destPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) && vmsDest.getAccountId() == accountOfVm)) {
-                            msg = "VM of account " + accountOfVm + " with preffered implicit deployment planner being migrated to host " + destHost.getName()
-                            + " not having all vms implicitly dedicated to account " + accountOfVm;
-                        }
-                    }
-                }
-            }
-            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-            s_logger.warn(msg);
-
-        } else {
-            //VM is not deployed using implicit planner, check if it migrated between dedicated hosts
-            List<PlannerHostReservationVO> reservedHosts = _plannerHostReservationDao.listAllDedicatedHosts();
-            boolean srcImplDedicated = false;
-            boolean destImplDedicated = false;
-            String msg = null;
-            for (PlannerHostReservationVO reservedHost : reservedHosts) {
-                if (reservedHost.getHostId() == srcHostId) {
-                    srcImplDedicated = true;
-                }
-                if (reservedHost.getHostId() == destHostId) {
-                    destImplDedicated = true;
-                }
-            }
-            if (srcImplDedicated) {
-                if (destImplDedicated) {
-                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to another implicitly dedicated host " + destHost.getName();
-                } else {
-                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName();
-                }
-                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-                s_logger.warn(msg);
-            } else {
-                if (destImplDedicated) {
-                    msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName();
-                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
-                    s_logger.warn(msg);
-                }
-            }
-        }
-    }
-
-    private List<VMInstanceVO> getVmsOnHost(long hostId) {
-        List<VMInstanceVO> vms =  _vmInstanceDao.listUpByHostId(hostId);
-        List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
-        if (vmsByLastHostId.size() > 0) {
-            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
-            for (VMInstanceVO stoppedVM : vmsByLastHostId) {
-                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
-                if (secondsSinceLastUpdate < capacityReleaseInterval) {
-                    vms.add(stoppedVM);
-                }
-            }
-        }
-
-        return vms;
-    }
-
-    private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
-        boolean preferred = false;
-        Map<String, String> details = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOfferingId);
-        if (details != null && !details.isEmpty()) {
-            String preferredAttribute = details.get("ImplicitDedicationMode");
-            if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
-                preferred = true;
-            }
-        }
-        return preferred;
-    }
-
-    private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
-        boolean createdByImplicitStrict = true;
-        if (allVmsOnHost.isEmpty()) {
-            return false;
-        }
-        for (VMInstanceVO vm : allVmsOnHost) {
-            if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId()) || vm.getAccountId() != accountId) {
-                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" + " than implicit, or running vms of other account");
-                createdByImplicitStrict = false;
-                break;
-            } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId()) || vm.getAccountId() != accountId) {
-                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" + " in preferred mode, or running vms of other account");
-                createdByImplicitStrict = false;
-                break;
-            }
-        }
-        return createdByImplicitStrict;
-    }
-
-    private boolean isImplicitPlannerUsedByOffering(long offeringId) {
-        boolean implicitPlannerUsed = false;
-        ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(offeringId);
-        if (offering == null) {
-            s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
-        } else {
-            String plannerName = offering.getDeploymentPlanner();
-            if (plannerName != null) {
-                if (plannerName.equals("ImplicitDedicationPlanner")) {
-                    implicitPlannerUsed = true;
-                }
-            }
-        }
-
-        return implicitPlannerUsed;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
-    public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, Map<String, String> volumeToPool) throws ResourceUnavailableException,
-    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
-        // Access check - only root administrator can migrate VM.
-        Account caller = CallContext.current().getCallingAccount();
-        if (!_accountMgr.isRootAdmin(caller.getId())) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
-            }
-            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
-        }
-
-        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find the vm by id " + vmId);
-        }
-
-        if (vm.getState() != State.Running) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
-            }
-            CloudRuntimeException ex = new CloudRuntimeException("VM is not Running, unable to migrate the vm with" + " specified id");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
-            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
-        }
-
-        if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
-                && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)
-                && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
-            throw new InvalidParameterValueException("Unsupported hypervisor type for vm migration, we support" + " XenServer/VMware/KVM only");
-        }
-
-        long srcHostId = vm.getHostId();
-        Host srcHost = _resourceMgr.getHost(srcHostId);
-
-        if(srcHost == null ){
-            throw new InvalidParameterValueException("Cannot migrate VM, there is not Host with id: " + srcHostId);
-        }
-
-        // Check if src and destination hosts are valid and migrating to same host
-        if (destinationHost.getId() == srcHostId) {
-            throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please" + " specify valid destination host to migrate the VM");
-        }
-
-        // Check if the source and destination hosts are of the same type and support storage motion.
-        if (!srcHost.getHypervisorType().equals(destinationHost.getHypervisorType())) {
-            throw new CloudRuntimeException("The source and destination hosts are not of the same type and version. Source hypervisor type and version: " +
-                    srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " +
-                    destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
-        }
-
-        String srcHostVersion = srcHost.getHypervisorVersion();
-        String destinationHostVersion = destinationHost.getHypervisorVersion();
-
-        if (HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
-            if (srcHostVersion == null) {
-                srcHostVersion = "";
-            }
-
-            if (destinationHostVersion == null) {
-                destinationHostVersion = "";
-            }
-        }
-
-        if (!srcHostVersion.equals(destinationHostVersion)) {
-            throw new CloudRuntimeException("The source and destination hosts are not of the same type and version. Source hypervisor type and version: " +
-                    srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " +
-                    destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
-        }
-
-        HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
-
-        if (capabilities == null && HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
-            List<HypervisorCapabilitiesVO> lstHypervisorCapabilities = _hypervisorCapabilitiesDao.listAllByHypervisorType(HypervisorType.KVM);
-
-            if (lstHypervisorCapabilities != null) {
-                for (HypervisorCapabilitiesVO hypervisorCapabilities : lstHypervisorCapabilities) {
-                    if (hypervisorCapabilities.isStorageMotionSupported()) {
-                        capabilities = hypervisorCapabilities;
-
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (!capabilities.isStorageMotionSupported()) {
-            throw new CloudRuntimeException("Migration with storage isn't supported on hypervisor " + srcHost.getHypervisorType() + " of version " + srcHost.getHypervisorVersion());
-        }
-
-        // Check if destination host is up.
-        if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) {
-            throw new CloudRuntimeException("Cannot migrate VM, destination host is not in correct state, has " + "status: " + destinationHost.getState() + ", state: "
-                    + destinationHost.getResourceState());
-        }
-
-        // Check that Vm does not have VM Snapshots
-        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
-            throw new InvalidParameterValueException("VM with VM Snapshots cannot be migrated with storage, please remove all VM snapshots");
-        }
-
-        List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
-        Map<Long, Long> volToPoolObjectMap = new HashMap<Long, Long>();
-        if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
-            if (volumeToPool.isEmpty()) {
-                // If the destination host is in the same cluster and volumes do not have to be migrated across pools
-                // then fail the call. migrateVirtualMachine api should have been used.
-                throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destinationHost
-                        + " doesn't involve migrating the volumes.");
-            }
-        }
-
-        if (!volumeToPool.isEmpty()) {
-            // Check if all the volumes and pools passed as parameters are valid.
-            for (Map.Entry<String, String> entry : volumeToPool.entrySet()) {
-                VolumeVO volume = _volsDao.findByUuid(entry.getKey());
-                StoragePoolVO pool = _storagePoolDao.findByUuid(entry.getValue());
-                if (volume == null) {
-                    throw new InvalidParameterValueException("There is no volume present with the given id " + entry.getKey());
-                } else if (pool == null) {
-                    throw new InvalidParameterValueException("There is no storage pool present with the given id " + entry.getValue());
-                } else if (pool.isInMaintenance()) {
-                    throw new InvalidParameterValueException("Cannot migrate volume " + volume + "to the destination storage pool " + pool.getName() +
-                            " as the storage pool is in maintenance mode.");
-                } else {
-                    // Verify the volume given belongs to the vm.
-                    if (!vmVolumes.contains(volume)) {
-                        throw new InvalidParameterValueException("There volume " + volume + " doesn't belong to " + "the virtual machine " + vm + " that has to be migrated");
-                    }
-                    volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId()));
-                }
-            }
-        }
-
-        // Check if all the volumes are in the correct state.
-        for (VolumeVO volume : vmVolumes) {
-            if (volume.getState() != Volume.State.Ready) {
-                throw new CloudRuntimeException("Volume " + volume + " of the VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
-            }
-        }
-
-        // Check max guest vm limit for the destinationHost.
-        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
-        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
-            throw new VirtualMachineMigrationException("Host name: " + destinationHost.getName() + ", hostId: " + destinationHost.getId()
-            + " already has max running vms (count includes system VMs). Cannot" + " migrate to this host");
-        }
-
-        checkHostsDedication(vm, srcHostId, destinationHost.getId());
-
-        _itMgr.migrateWithStorage(vm.getUuid(), srcHostId, destinationHost.getId(), volToPoolObjectMap);
-        return _vmDao.findById(vm.getId());
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
-    public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        // VERIFICATIONS and VALIDATIONS
-
-        // VV 1: verify the two users
-        Account caller = CallContext.current().getCallingAccount();
-        if (!_accountMgr.isRootAdmin(caller.getId())
-                && !_accountMgr.isDomainAdmin(caller.getId())) { // only
-            // root
-            // admin
-            // can
-            // assign
-            // VMs
-            throw new InvalidParameterValueException("Only domain admins are allowed to assign VMs and not " + caller.getType());
-        }
-
-        // get and check the valid VM
-        final UserVmVO vm = _vmDao.findById(cmd.getVmId());
-        if (vm == null) {
-            throw new InvalidParameterValueException("There is no vm by that id " + cmd.getVmId());
-        } else if (vm.getState() == State.Running) { // VV 3: check if vm is
-            // running
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("VM is Running, unable to move the vm " + vm);
-            }
-            InvalidParameterValueException ex = new InvalidParameterValueException("VM is Running, unable to move the vm with specified vmId");
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-
-        final Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId());
-        if (oldAccount == null) {
-            throw new InvalidParameterValueException("Invalid account for VM " + vm.getAccountId() + " in domain.");
-        }
-        final Account newAccount = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
-        if (newAccount == null) {
-            throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountName() + " in domain " + cmd.getDomainId());
-        }
-
-        if (newAccount.getState() == Account.State.disabled) {
-            throw new InvalidParameterValueException("The new account owner " + cmd.getAccountName() + " is disabled.");
-        }
-
-        //check caller has access to both the old and new account
-        _accountMgr.checkAccess(caller, null, true, oldAccount);
-        _accountMgr.checkAccess(caller, null, true, newAccount);
-
-        // make sure the accounts are not same
-        if (oldAccount.getAccountId() == newAccount.getAccountId()) {
-            throw new InvalidParameterValueException("The new account is the same as the old account. Account id =" + oldAccount.getAccountId());
-        }
-
-        // don't allow to move the vm if there are existing PF/LB/Static Nat
-        // rules, or vm is assigned to static Nat ip
-        List<PortForwardingRuleVO> pfrules = _portForwardingDao.listByVm(cmd.getVmId());
-        if (pfrules != null && pfrules.size() > 0) {
-            throw new InvalidParameterValueException("Remove the Port forwarding rules for this VM before assigning to another user.");
-        }
-        List<FirewallRuleVO> snrules = _rulesDao.listStaticNatByVmId(vm.getId());
-        if (snrules != null && snrules.size() > 0) {
-            throw new InvalidParameterValueException("Remove the StaticNat rules for this VM before assigning to another user.");
-        }
-        List<LoadBalancerVMMapVO> maps = _loadBalancerVMMapDao.listByInstanceId(vm.getId());
-        if (maps != null && maps.size() > 0) {
-            throw new InvalidParameterValueException("Remove the load balancing rules for this VM before assigning to another user.");
-        }
-        // check for one on one nat
-        List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(cmd.getVmId());
-        for (IPAddressVO ip : ips) {
-            if (ip.isOneToOneNat()) {
-                throw new InvalidParameterValueException("Remove the one to one nat rule for this VM for ip " + ip.toString());
-            }
-        }
-
-        final List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
-
-        for (VolumeVO volume : volumes) {
-            List<SnapshotVO> snapshots = _snapshotDao.listByStatusNotIn(volume.getId(), Snapshot.State.Destroyed,Snapshot.State.Error);
-            if (snapshots != null && snapshots.size() > 0) {
-                throw new InvalidParameterValueException(
-                        "Snapshots exists for volume: "+ volume.getName()+ ", Detach volume or remove snapshots for volume before assigning VM to another user.");
-            }
-        }
-
-        DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
-
-        // Get serviceOffering and Volumes for Virtual Machine
-        final ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
-
-        //Remove vm from instance group
-        removeInstanceFromInstanceGroup(cmd.getVmId());
-
-        // VV 2: check if account/domain is with in resource limits to create a new vm
-        resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
-
-        // VV 3: check if volumes and primary storage space are with in resource limits
-        _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
-        Long totalVolumesSize = (long)0;
-        for (VolumeVO volume : volumes) {
-            totalVolumesSize += volume.getSize();
-        }
-        _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
-
-        // VV 4: Check if new owner can use the vm template
-        VirtualMachineTemplate template = _templateDao.findById(vm.getTemplateId());
-        if (!template.isPublicTemplate()) {
-            Account templateOwner = _accountMgr.getAccount(template.getAccountId());
-            _accountMgr.checkAccess(newAccount, null, true, templateOwner);
-        }
-
-        // VV 5: check the new account can create vm in the domain
-        DomainVO domain = _domainDao.findById(cmd.getDomainId());
-        _accountMgr.checkAccess(newAccount, domain);
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                //generate destroy vm event for usage
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(),
-                        vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
-                        vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
-                // update resource counts for old account
-                resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
-
-                // OWNERSHIP STEP 1: update the vm owner
-                vm.setAccountId(newAccount.getAccountId());
-                vm.setDomainId(cmd.getDomainId());
-                _vmDao.persist(vm);
-
-                // OS 2: update volume
-                for (VolumeVO volume : volumes) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
-                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
-                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
-                    volume.setAccountId(newAccount.getAccountId());
-                    volume.setDomainId(newAccount.getDomainId());
-                    _volsDao.persist(volume);
-                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
-                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
-                            volume.getUuid(), volume.isDisplayVolume());
-                }
-
-                //update resource count of new account
-                resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
-
-                //generate usage events to account for this change
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                        vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
-                        VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
-            }
-        });
-
-        VirtualMachine vmoi = _itMgr.findById(vm.getId());
-        VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi);
-
-        // OS 3: update the network
-        List<Long> networkIdList = cmd.getNetworkIds();
-        List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
-
-        if (zone.getNetworkType() == NetworkType.Basic) {
-            if (networkIdList != null && !networkIdList.isEmpty()) {
-                throw new InvalidParameterValueException("Can't move vm with network Ids; this is a basic zone VM");
-            }
-            // cleanup the old security groups
-            _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
-            // cleanup the network for the oldOwner
-            _networkMgr.cleanupNics(vmOldProfile);
-            _networkMgr.expungeNics(vmOldProfile);
-            // security groups will be recreated for the new account, when the
-            // VM is started
-            List<NetworkVO> networkList = new ArrayList<NetworkVO>();
-
-            // Get default guest network in Basic zone
-            Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
-
-            if (defaultNetwork == null) {
-                throw new InvalidParameterValueException("Unable to find a default network to start a vm");
-            } else {
-                networkList.add(_networkDao.findById(defaultNetwork.getId()));
-            }
-
-            boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
-
-            if (securityGroupIdList != null && isVmWare) {
-                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-            } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
-                if (securityGroupIdList == null) {
-                    securityGroupIdList = new ArrayList<Long>();
-                }
-                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
-                if (defaultGroup != null) {
-                    // check if security group id list already contains Default
-                    // security group, and if not - add it
-                    boolean defaultGroupPresent = false;
-                    for (Long securityGroupId : securityGroupIdList) {
-                        if (securityGroupId.longValue() == defaultGroup.getId()) {
-                            defaultGroupPresent = true;
-                            break;
-                        }
-                    }
-
-                    if (!defaultGroupPresent) {
-                        securityGroupIdList.add(defaultGroup.getId());
-                    }
-
-                } else {
-                    // create default security group for the account
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
-                    }
-                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
-                            newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
-                    securityGroupIdList.add(defaultGroup.getId());
-                }
-            }
-
-            LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
-            NicProfile profile = new NicProfile();
-            profile.setDefaultNic(true);
-            networks.put(networkList.get(0), new ArrayList<NicProfile>(Arrays.asList(profile)));
-
-            VirtualMachine vmi = _itMgr.findById(vm.getId());
-            VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
-            _networkMgr.allocate(vmProfile, networks, null);
-
-            _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
-
-            s_logger.debug("AssignVM: Basic zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
-        } else {
-            if (zone.isSecurityGroupEnabled())  { // advanced zone with security groups
-                // cleanup the old security groups
-                _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
-
-                Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
-                String requestedIPv4ForDefaultNic = null;
-                String requestedIPv6ForDefaultNic = null;
-                // if networkIdList is null and the first network of vm is shared network, then keep it if possible
-                if (networkIdList == null || networkIdList.isEmpty()) {
-                    NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
-                    if (defaultNicOld != null) {
-                        NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
-                        if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
-                            try {
-                                _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
-                                applicableNetworks.add(defaultNetworkOld);
-                                requestedIPv4ForDefaultNic = defaultNicOld.getIPv4Address();
-                                requestedIPv6ForDefaultNic = defaultNicOld.getIPv6Address();
-                                s_logger.debug("AssignVM: use old shared network " + defaultNetworkOld.getName() + " with old ip " + requestedIPv4ForDefaultNic + " on default nic of vm:" + vm.getInstanceName());
-                            } catch (PermissionDeniedException e) {
-                                s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
-                            }
-                        }
-                    }
-                }
-                // cleanup the network for the oldOwner
-                _networkMgr.cleanupNics(vmOldProfile);
-                _networkMgr.expungeNics(vmOldProfile);
-
-                if (networkIdList != null && !networkIdList.isEmpty()) {
-                    // add any additional networks
-                    for (Long networkId : networkIdList) {
-                        NetworkVO network = _networkDao.findById(networkId);
-                        if (network == null) {
-                            InvalidParameterValueException ex = new InvalidParameterValueException(
-                                    "Unable to find specified network id");
-                            ex.addProxyObject(networkId.toString(), "networkId");
-                            throw ex;
-                        }
-
-                        _networkModel.checkNetworkPermissions(newAccount, network);
-
-                        // don't allow to use system networks
-                        NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-                        if (networkOffering.isSystemOnly()) {
-                            InvalidParameterValueException ex = new InvalidParameterValueException(
-                                    "Specified Network id is system only and can't be used for vm deployment");
-                            ex.addProxyObject(network.getUuid(), "networkId");
-                            throw ex;
-                        }
-                        applicableNetworks.add(network);
-                    }
-                }
-
-                // add the new nics
-                LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
-                int toggle = 0;
-                NetworkVO defaultNetwork = null;
-                for (NetworkVO appNet : applicableNetworks) {
-                    NicProfile defaultNic = new NicProfile();
-                    if (toggle == 0) {
-                        defaultNic.setDefaultNic(true);
-                        defaultNic.setRequestedIPv4(requestedIPv4ForDefaultNic);
-                        defaultNic.setRequestedIPv6(requestedIPv6ForDefaultNic);
-                        defaultNetwork = appNet;
-                        toggle++;
-                    }
-                    networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
-
-                }
-
-                boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
-                if (securityGroupIdList != null && isVmWare) {
-                    throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
-                } else if (!isVmWare && (defaultNetwork == null || _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork)) && _networkModel.canAddDefaultSecurityGroup()) {
-                    if (securityGroupIdList == null) {
-                        securityGroupIdList = new ArrayList<Long>();
-                    }
-                    SecurityGroup defaultGroup = _securityGroupMgr
-                            .getDefaultSecurityGroup(newAccount.getId());
-                    if (defaultGroup != null) {
-                        // check if security group id list already contains Default
-                        // security group, and if not - add it
-                        boolean defaultGroupPresent = false;
-                        for (Long securityGroupId : securityGroupIdList) {
-                            if (securityGroupId.longValue() == defaultGroup.getId()) {
-                                defaultGroupPresent = true;
-                                break;
-                            }
-                        }
-
-                        if (!defaultGroupPresent) {
-                            securityGroupIdList.add(defaultGroup.getId());
-                        }
-
-                    } else {
-                        // create default security group for the account
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("Couldn't find default security group for the account "
-                                    + newAccount + " so creating a new one");
-                        }
-                        defaultGroup = _securityGroupMgr.createSecurityGroup(
-                                SecurityGroupManager.DEFAULT_GROUP_NAME,
-                                SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
-                                newAccount.getDomainId(), newAccount.getId(),
-                                newAccount.getAccountName());
-                        securityGroupIdList.add(defaultGroup.getId());
-                    }
-                }
-
-                VirtualMachine vmi = _itMgr.findById(vm.getId());
-                VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
-
-                if (applicableNetworks.isEmpty()) {
-                    throw new InvalidParameterValueException("No network is specified, please specify one when you move the vm. For now, please add a network to VM on NICs tab.");
-                } else {
-                    _networkMgr.allocate(vmProfile, networks, null);
-                }
-
-                _securityGroupMgr.addInstanceToGroups(vm.getId(),
-                        securityGroupIdList);
-                s_logger.debug("AssignVM: Advanced zone, adding security groups no "
-                        + securityGroupIdList.size() + " to "
-                        + vm.getInstanceName());
-
-            } else {
-                if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
-                    throw new InvalidParameterValueException("Can't move vm with security groups; security group feature is not enabled in this zone");
-                }
-                Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
-                // if networkIdList is null and the first network of vm is shared network, then keep it if possible
-                if (networkIdList == null || networkIdList.isEmpty()) {
-                    NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
-                    if (defaultNicOld != null) {
-                        NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
-                        if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
-                            try {
-                                _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
-                                applicableNetworks.add(defaultNetworkOld);
-                            } catch (PermissionDeniedException e) {
-                                s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
-                            }
-                        }
-                    }
-                }
-
-                // cleanup the network for the oldOwner
-                _networkMgr.cleanupNics(vmOldProfile);
-                _networkMgr.expungeNics(vmOldProfile);
-
-                if (networkIdList != null && !networkIdList.isEmpty()) {
-                    // add any additional networks
-                    for (Long networkId : networkIdList) {
-                        NetworkVO network = _networkDao.findById(networkId);
-                        if (network == null) {
-                            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
-                            ex.addProxyObject(networkId.toString(), "networkId");
-                            throw ex;
-                        }
-
-                        _networkModel.checkNetworkPermissions(newAccount, network);
-
-                        // don't allow to use system networks
-                        NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-                        if (networkOffering.isSystemOnly()) {
-                            InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
-                            ex.addProxyObject(network.getUuid(), "networkId");
-                            throw ex;
-                        }
-                        applicableNetworks.add(network);
-                    }
-                } else if (applicableNetworks.isEmpty()) {
-                    NetworkVO defaultNetwork = null;
-                    List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-                    if (requiredOfferings.size() < 1) {
-                        throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
-                                + " to automatically create the network as a part of vm creation");
-                    }
-                    if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
-                        // get Virtual networks
-                        List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated);
-                        if (virtualNetworks.isEmpty()) {
-                            long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0)
-                                    .getTrafficType());
-                            // Validate physical network
-                            PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-                            if (physicalNetwork == null) {
-                                throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
-                                        + requiredOfferings.get(0).getTags());
-                            }
-                            s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId()
-                                    + " as a part of deployVM process");
-                            Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
-                                    newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
-                                    null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
-                                    null, null, true, null, null);
-                            // if the network offering has persistent set to true, implement the network
-                            if (requiredOfferings.get(0).getIsPersistent()) {
-                                DeployDestination dest = new DeployDestination(zone, null, null, null);
-                                UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
-                                Journal journal = new Journal.LogJournal("Implementing " + newNetwork, s_logger);
-                                ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
-                                s_logger.debug("Implementing the network for account" + newNetwork + " as a part of" + " network provision for persistent networks");
-                                try {
-                                    Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(newNetwork.getId(), dest, context);
-                                    if (implementedNetwork == null || implementedNetwork.first() == null) {
-                                        s_logger.warn("Failed to implement the network " + newNetwork);
-                                    }
-                                    newNetwork = implementedNetwork.second();
-                                } catch (Exception ex) {
-                                    s_logger.warn("Failed to implement network " + newNetwork + " elements and"
-                                            + " resources as a part of network provision for persistent network due to ", ex);
-                                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network"
-                                            + " (with specified id) elements and resources as a part of network provision");
-                                    e.addProxyObject(newNetwork.getUuid(), "networkId");
-                                    throw e;
-                                }
-                            }
-                            defaultNetwork = _networkDao.findById(newNetwork.getId());
-                        } else if (virtualNetworks.size() > 1) {
-                            throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + "for account " + newAccount
-                                    + "; please specify networkIds");
-                        } else {
-                            defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
-                        }
-                    } else {
-                        throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
-                    }
-
-                    applicableNetworks.add(defaultNetwork);
-                }
-
-                // add the new nics
-                LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
-                int toggle = 0;
-                for (NetworkVO appNet : applicableNetworks) {
-                    NicProfile defaultNic = new NicProfile();
-                    if (toggle == 0) {
-                        defaultNic.setDefaultNic(true);
-                        toggle++;
-                    }
-                    networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
-                }
-                VirtualMachine vmi = _itMgr.findById(vm.getId());
-                VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
-                _networkMgr.allocate(vmProfile, networks, null);
-                s_logger.debug("AssignVM: Advance virtual, adding networks no " + networks.size() + " to " + vm.getInstanceName());
-            } // END IF NON SEC GRP ENABLED
-        } // END IF ADVANCED
-        s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + newAccount.getAccountName());
-        return vm;
-    }
-
-    @Override
-    public UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
-        // Input validation
-        Account caller = CallContext.current().getCallingAccount();
-
-        long vmId = cmd.getVmId();
-        Long newTemplateId = cmd.getTemplateId();
-
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find VM with ID " + vmId);
-            ex.addProxyObject(String.valueOf(vmId), "vmId");
-            throw ex;
-        }
-
-        _accountMgr.checkAccess(caller, null, true, vm);
-
-        //check if there are any active snapshots on volumes associated with the VM
-        s_logger.debug("Checking if there are any ongoing snapshots on the ROOT volumes associated with VM with ID " + vmId);
-        if (checkStatusOfVolumeSnapshots(vmId, Volume.Type.ROOT)) {
-            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on ROOT volume, Re-install VM is not permitted, please try again later.");
-        }
-        s_logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm with id " + vmId);
-        return restoreVMInternal(caller, vm, newTemplateId);
-    }
-
-    public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
-
-        Long userId = caller.getId();
-        Account owner = _accountDao.findById(vm.getAccountId());
-        _userDao.findById(userId);
-        long vmId = vm.getId();
-        boolean needRestart = false;
-
-        // Input validation
-        if (owner == null) {
-            throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
-        }
-
-        if (owner.getState() == Account.State.disabled) {
-            throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
-        }
-
-        if (vm.getState() != VirtualMachine.State.Running && vm.getState() != VirtualMachine.State.Stopped) {
-            throw new CloudRuntimeException("Vm " + vm.getUuid() + " currently in " + vm.getState() + " state, restore vm can only execute when VM in Running or Stopped");
-        }
-
-        if (vm.getState() == VirtualMachine.State.Running) {
-            needRestart = true;
-        }
-
-        List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
-        if (rootVols.isEmpty()) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid());
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-        if (rootVols.size() > 1) {
-            InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid());
-            ex.addProxyObject(vm.getUuid(), "vmId");
-            throw ex;
-        }
-        VolumeVO root = rootVols.get(0);
-        if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
-            Long templateId = root.getTemplateId();
-            boolean isISO = false;
-            if (templateId == null) {
-                // Assuming that for a vm deployed using ISO, template ID is set to NULL
-                isISO = true;
-                templateId = vm.getIsoId();
-            }
-
-            // If target VM has associated VM snapshots then don't allow restore of VM
-            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
-            if (vmSnapshots.size() > 0) {
-                throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
-            }
-
-            VMTemplateVO template = null;
-            //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
-            if (newTemplateId != null) {
-                template = _templateDao.findById(newTemplateId);
-                _accountMgr.checkAccess(caller, null, true, template);
-                if (isISO) {
-                    if (!template.getFormat().equals(ImageFormat.ISO)) {
-                        throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
-                    }
-                } else {
-                    if (template.getFormat().equals(ImageFormat.ISO)) {
-                        throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
-                    }
-                }
-            } else {
-                if (isISO && templateId == null) {
-                    throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
-                }
-                template = _templateDao.findById(templateId);
-                if (template == null) {
-                    InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
-                    ex.addProxyObject(vm.getUuid(), "vmId");
-                    ex.addProxyObject(root.getUuid(), "volumeId");
-                    throw ex;
-                }
-            }
-
-            checkRestoreVmFromTemplate(vm, template);
-
-            if (needRestart) {
-                try {
-                    _itMgr.stop(vm.getUuid());
-                } catch (ResourceUnavailableException e) {
-                    s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
-                    CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
-                    ex.addProxyObject(vm.getUuid(), "vmId");
-                    throw ex;
-                }
-            }
-
-            /* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
-            Volume newVol = null;
-            if (newTemplateId != null) {
-                if (isISO) {
-                    newVol = volumeMgr.allocateDuplicateVolume(root, null);
-                    vm.setIsoId(newTemplateId);
-                    vm.setGuestOSId(template.getGuestOSId());
-                    vm.setTemplateId(newTemplateId);
-                    _vmDao.update(vmId, vm);
-                } else {
-                    newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
-                    vm.setGuestOSId(template.getGuestOSId());
-                    vm.setTemplateId(newTemplateId);
-                    _vmDao.update(vmId, vm);
-                }
-            } else {
-                newVol = volumeMgr.allocateDuplicateVolume(root, null);
-            }
-
-            // 1. Save usage event and update resource count for user vm volumes
-            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
-            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
-            // 2. Create Usage event for the newly created volume
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
-            _usageEventDao.persist(usageEvent);
-
-            handleManagedStorage(vm, root);
-
-            _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
-
-            // Detach, destroy and create the usage event for the old root volume.
-            _volsDao.detachVolume(root.getId());
-            volumeMgr.destroyVolume(root);
-
-            // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
-            if (vm.getHypervisorType() == HypervisorType.VMware) {
-                VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
-                if (volumeInStorage != null) {
-                    s_logger.info("Expunging volume " + root.getId() + " from primary data store");
-                    AsyncCallFuture<VolumeApiResult> future = _volService.expungeVolumeAsync(volFactory.getVolume(root.getId()));
-                    try {
-                        future.get();
-                    } catch (Exception e) {
-                        s_logger.debug("Failed to expunge volume:" + root.getId(), e);
-                    }
-                }
-            }
-
-            Map<VirtualMachineProfile.Param, Object> params = null;
-            String password = null;
-
-            if (template.getEnablePassword()) {
-                password = _mgr.generateRandomPassword();
-                boolean result = resetVMPasswordInternal(vmId, password);
-                if (!result) {
-                    throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
-                }
-            }
-
-            if (needRestart) {
-                try {
-                    if (vm.getDetail("password") != null) {
-                        params = new HashMap<VirtualMachineProfile.Param, Object>();
-                        params.put(VirtualMachineProfile.Param.VmPassword, password);
-                    }
-                    _itMgr.start(vm.getUuid(), params);
-                    vm = _vmDao.findById(vmId);
-                    if (template.getEnablePassword()) {
-                        // this value is not being sent to the backend; need only for api
-                        // display purposes
-                        vm.setPassword(password);
-                        if (vm.isUpdateParameters()) {
-                            vm.setUpdateParameters(false);
-                            _vmDao.loadDetails(vm);
-                            if (vm.getDetail("password") != null) {
-                                _vmDetailsDao.removeDetail(vm.getId(), "password");
-                            }
-                            _vmDao.update(vm.getId(), vm);
-                        }
-                    }
-                } catch (Exception e) {
-                    s_logger.debug("Unable to start VM " + vm.getUuid(), e);
-                    CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
-                    ex.addProxyObject(vm.getUuid(), "vmId");
-                    throw ex;
-                }
-            }
-        }
-
-        s_logger.debug("Restore VM " + vmId + " done successfully");
-        return vm;
-
-    }
-
-    /**
-     * Perform basic checkings to make sure restore is possible. If not, #InvalidParameterValueException is thrown.
-     *
-     * @param vm vm
-     * @param template template
-     * @throws InvalidParameterValueException if restore is not possible
-     */
-    private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template) {
-        TemplateDataStoreVO tmplStore;
-        if (!template.isDirectDownload()) {
-            tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
-            if (tmplStore == null) {
-                throw new InvalidParameterValueException("Cannot restore the vm as the template " + template.getUuid() + " isn't available in the zone");
-            }
-        } else {
-            tmplStore = _templateStoreDao.findByTemplate(template.getId(), DataStoreRole.Image);
-            if (tmplStore == null || (tmplStore != null && !tmplStore.getDownloadState().equals(VMTemplateStorageResourceAssoc.Status.BYPASSED))) {
-                throw new InvalidParameterValueException("Cannot restore the vm as the bypassed template " + template.getUuid() + " isn't available in the zone");
-            }
-        }
-    }
-
-    private void handleManagedStorage(UserVmVO vm, VolumeVO root) {
-        if (Volume.State.Allocated.equals(root.getState())) {
-            return;
-        }
-
-        StoragePoolVO storagePool = _storagePoolDao.findById(root.getPoolId());
-
-        if (storagePool != null && storagePool.isManaged()) {
-            Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
-
-            if (hostId != null) {
-                VolumeInfo volumeInfo = volFactory.getVolume(root.getId());
-                Host host = _hostDao.findById(hostId);
-
-                final Command cmd;
-
-                if (host.getHypervisorType() == HypervisorType.XenServer) {
-                    DiskTO disk = new DiskTO(volumeInfo.getTO(), root.getDeviceId(), root.getPath(), root.getVolumeType());
-
-                    // it's OK in this case to send a detach command to the host for a root volume as this
-                    // will simply lead to the SR that supports the root volume being removed
-                    cmd = new DettachCommand(disk, vm.getInstanceName());
-
-                    DettachCommand detachCommand = (DettachCommand)cmd;
-
-                    detachCommand.setManaged(true);
-
-                    detachCommand.setStorageHost(storagePool.getHostAddress());
-                    detachCommand.setStoragePort(storagePool.getPort());
-
-                    detachCommand.set_iScsiName(root.get_iScsiName());
-                }
-                else if (host.getHypervisorType() == HypervisorType.VMware) {
-                    PrimaryDataStore primaryDataStore = (PrimaryDataStore)volumeInfo.getDataStore();
-                    Map<String, String> details = primaryDataStore.getDetails();
-
-                    if (details == null) {
-                        details = new HashMap<>();
-
-                        primaryDataStore.setDetails(details);
-                    }
-
-                    details.put(DiskTO.MANAGED, Boolean.TRUE.toString());
-
-                    cmd = new DeleteCommand(volumeInfo.getTO());
-                }
-                else if (host.getHypervisorType() == HypervisorType.KVM) {
-                    cmd = null;
-                }
-                else {
-                    throw new CloudRuntimeException("This hypervisor type is not supported on managed storage for this command.");
-                }
-
-                if (cmd != null) {
-                    Commands cmds = new Commands(Command.OnError.Stop);
-
-                    cmds.addCommand(cmd);
-
-                    try {
-                        _agentMgr.send(hostId, cmds);
-                    } catch (Exception ex) {
-                        throw new CloudRuntimeException(ex.getMessage());
-                    }
-
-                    if (!cmds.isSuccessful()) {
-                        for (Answer answer : cmds.getAnswers()) {
-                            if (!answer.getResult()) {
-                                s_logger.warn("Failed to reset vm due to: " + answer.getDetails());
-
-                                throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails());
-                            }
-                        }
-                    }
-                }
-
-                // root.getPoolId() should be null if the VM we are detaching the disk from has never been started before
-                DataStore dataStore = root.getPoolId() != null ? _dataStoreMgr.getDataStore(root.getPoolId(), DataStoreRole.Primary) : null;
-
-                volumeMgr.revokeAccess(volFactory.getVolume(root.getId()), host, dataStore);
-
-                if (dataStore != null) {
-                    handleTargetsForVMware(host.getId(), storagePool.getHostAddress(), storagePool.getPort(), root.get_iScsiName());
-                }
-            }
-        }
-    }
-
-    private void handleTargetsForVMware(long hostId, String storageAddress, int storagePort, String iScsiName) {
-        HostVO host = _hostDao.findById(hostId);
-
-        if (host.getHypervisorType() == HypervisorType.VMware) {
-            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
-
-            List<Map<String, String>> targets = new ArrayList<>();
-
-            Map<String, String> target = new HashMap<>();
-
-            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
-            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
-            target.put(ModifyTargetsCommand.IQN, iScsiName);
-
-            targets.add(target);
-
-            cmd.setTargets(targets);
-            cmd.setApplyToAllHostsInCluster(true);
-            cmd.setAdd(false);
-            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
-
-            sendModifyTargetsCommand(cmd, hostId);
-        }
-    }
-
-    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
-        Answer answer = _agentMgr.easySend(hostId, cmd);
-
-        if (answer == null) {
-            String msg = "Unable to get an answer to the modify targets command";
-
-            s_logger.warn(msg);
-        }
-        else if (!answer.getResult()) {
-            String msg = "Unable to modify target on the following host: " + hostId;
-
-            s_logger.warn(msg);
-        }
-    }
-
-    @Override
-    public void prepareStop(VirtualMachineProfile profile) {
-        UserVmVO vm = _vmDao.findById(profile.getId());
-        if (vm != null && vm.getState() == State.Stopping) {
-            collectVmDiskStatistics(vm);
-            collectVmNetworkStatistics(vm);
-        }
-    }
-
-    private void encryptAndStorePassword(UserVmVO vm, String password) {
-        String sshPublicKey = vm.getDetail("SSH.PublicKey");
-        if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
-            if (!sshPublicKey.startsWith("ssh-rsa")) {
-                s_logger.warn("Only RSA public keys can be used to encrypt a vm password.");
-                return;
-            }
-            String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
-            if (encryptedPasswd == null) {
-                throw new CloudRuntimeException("Error encrypting password");
-            }
-
-            vm.setDetail("Encrypted.Password", encryptedPasswd);
-            _vmDao.saveDetails(vm);
-        }
-    }
-
-    @Override
-    public void persistDeviceBusInfo(UserVmVO vm, String rootDiskController) {
-        String existingVmRootDiskController = vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER);
-        if (StringUtils.isEmpty(existingVmRootDiskController) && !StringUtils.isEmpty(rootDiskController)) {
-            vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskController);
-            _vmDao.saveDetails(vm);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Persisted device bus information rootDiskController=" + rootDiskController + " for vm: " + vm.getDisplayName());
-            }
-        }
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return UserVmManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax,
-            VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails};
-    }
-
-    @Override
-    public String getVmUserData(long vmId) {
-        UserVmVO vm = _vmDao.findById(vmId);
-        if (vm == null) {
-            throw new InvalidParameterValueException("Unable to find virual machine with id " + vmId);
-        }
-
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
-        return vm.getUserData();
-    }
-
-    @Override
-    public boolean isDisplayResourceEnabled(Long vmId) {
-        UserVm vm = _vmDao.findById(vmId);
-        if (vm != null) {
-            return vm.isDisplayVm();
-        }
-
-        return true;
-    }
-
-    private boolean checkStatusOfVolumeSnapshots(long vmId, Volume.Type type) {
-        List<VolumeVO> listVolumes = null;
-        if (type == Volume.Type.ROOT) {
-            listVolumes = _volsDao.findByInstanceAndType(vmId, type);
-        } else if (type == Volume.Type.DATADISK) {
-            listVolumes = _volsDao.findByInstanceAndType(vmId, type);
-        } else {
-            listVolumes = _volsDao.findByInstance(vmId);
-        }
-        s_logger.debug("Found "+listVolumes.size()+" no. of volumes of type "+type+" for vm with VM ID "+vmId);
-        for (VolumeVO volume : listVolumes) {
-            Long volumeId = volume.getId();
-            s_logger.debug("Checking status of snapshots for Volume with Volume Id: "+volumeId);
-            List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(volumeId, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
-            int ongoingSnapshotsCount = ongoingSnapshots.size();
-            s_logger.debug("The count of ongoing Snapshots for VM with ID "+vmId+" and disk type "+type+" is "+ongoingSnapshotsCount);
-            if (ongoingSnapshotsCount > 0) {
-                s_logger.debug("Found "+ongoingSnapshotsCount+" no. of snapshots, on volume of type "+type+", which snapshots are not yet backed up");
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/server/src/com/cloud/account/SecurityManager.java b/server/src/main/java/com/cloud/account/SecurityManager.java
similarity index 100%
rename from server/src/com/cloud/account/SecurityManager.java
rename to server/src/main/java/com/cloud/account/SecurityManager.java
diff --git a/server/src/com/cloud/acl/AffinityGroupAccessChecker.java b/server/src/main/java/com/cloud/acl/AffinityGroupAccessChecker.java
similarity index 100%
rename from server/src/com/cloud/acl/AffinityGroupAccessChecker.java
rename to server/src/main/java/com/cloud/acl/AffinityGroupAccessChecker.java
diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/main/java/com/cloud/acl/DomainChecker.java
similarity index 100%
rename from server/src/com/cloud/acl/DomainChecker.java
rename to server/src/main/java/com/cloud/acl/DomainChecker.java
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
rename to server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitRoutingAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitRoutingAllocator.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/allocator/impl/FirstFitRoutingAllocator.java
rename to server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitRoutingAllocator.java
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java
rename to server/src/main/java/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/TestingAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/TestingAllocator.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/allocator/impl/TestingAllocator.java
rename to server/src/main/java/com/cloud/agent/manager/allocator/impl/TestingAllocator.java
diff --git a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java
rename to server/src/main/java/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java
diff --git a/server/src/com/cloud/agent/manager/authn/AgentAuthnException.java b/server/src/main/java/com/cloud/agent/manager/authn/AgentAuthnException.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/authn/AgentAuthnException.java
rename to server/src/main/java/com/cloud/agent/manager/authn/AgentAuthnException.java
diff --git a/server/src/com/cloud/agent/manager/authn/AgentAuthorizer.java b/server/src/main/java/com/cloud/agent/manager/authn/AgentAuthorizer.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/authn/AgentAuthorizer.java
rename to server/src/main/java/com/cloud/agent/manager/authn/AgentAuthorizer.java
diff --git a/server/src/com/cloud/agent/manager/authn/impl/BasicAgentAuthManager.java b/server/src/main/java/com/cloud/agent/manager/authn/impl/BasicAgentAuthManager.java
similarity index 100%
rename from server/src/com/cloud/agent/manager/authn/impl/BasicAgentAuthManager.java
rename to server/src/main/java/com/cloud/agent/manager/authn/impl/BasicAgentAuthManager.java
diff --git a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
new file mode 100644
index 0000000..5a7a8b4
--- /dev/null
+++ b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
@@ -0,0 +1,867 @@
+// 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.alert;
+
+import java.io.UnsupportedEncodingException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.inject.Inject;
+import javax.mail.Authenticator;
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.SendFailedException;
+import javax.mail.Session;
+import javax.mail.URLName;
+import javax.mail.internet.InternetAddress;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+
+import com.cloud.alert.dao.AlertDao;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.CapacityState;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.AlertGenerator;
+import com.cloud.event.EventTypes;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.StorageManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.SearchCriteria;
+import com.sun.mail.smtp.SMTPMessage;
+import com.sun.mail.smtp.SMTPSSLTransport;
+import com.sun.mail.smtp.SMTPTransport;
+
+public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
+    private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName());
+
+    private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.
+
+    private static final DecimalFormat DfPct = new DecimalFormat("###.##");
+    private static final DecimalFormat DfWhole = new DecimalFormat("########");
+
+    private EmailAlert _emailAlert;
+    @Inject
+    private AlertDao _alertDao;
+    @Inject
+    protected StorageManager _storageMgr;
+    @Inject
+    protected CapacityManager _capacityMgr;
+    @Inject
+    private CapacityDao _capacityDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private IPAddressDao _publicIPAddressDao;
+    @Inject
+    private DataCenterIpAddressDao _privateIPAddressDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ConfigurationManager _configMgr;
+    @Inject
+    protected ConfigDepot _configDepot;
+
+    private Timer _timer = null;
+    private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default.
+    private double _publicIPCapacityThreshold = 0.75;
+    private double _privateIPCapacityThreshold = 0.75;
+    private double _secondaryStorageCapacityThreshold = 0.75;
+    private double _vlanCapacityThreshold = 0.75;
+    private double _directNetworkPublicIpCapacityThreshold = 0.75;
+    private double _localStorageCapacityThreshold = 0.75;
+    Map<Short, Double> _capacityTypeThresholdMap = new HashMap<Short, Double>();
+
+    private final ExecutorService _executor;
+
+    public AlertManagerImpl() {
+        _executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender"));
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+        // set up the email system for alerts
+        String emailAddressList = configs.get("alert.email.addresses");
+        String[] emailAddresses = null;
+        if (emailAddressList != null) {
+            emailAddresses = emailAddressList.split(",");
+        }
+
+        String smtpHost = configs.get("alert.smtp.host");
+        int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25);
+        String useAuthStr = configs.get("alert.smtp.useAuth");
+        boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
+        String smtpUsername = configs.get("alert.smtp.username");
+        String smtpPassword = configs.get("alert.smtp.password");
+        String emailSender = configs.get("alert.email.sender");
+        String smtpDebugStr = configs.get("alert.smtp.debug");
+        int smtpTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.timeout"), 30000);
+        int smtpConnectionTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.connectiontimeout"), 30000);
+        boolean smtpDebug = false;
+        if (smtpDebugStr != null) {
+            smtpDebug = Boolean.parseBoolean(smtpDebugStr);
+        }
+
+        _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, smtpConnectionTimeout, smtpTimeout, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
+
+        String publicIPCapacityThreshold = _configDao.getValue(Config.PublicIpCapacityThreshold.key());
+        String privateIPCapacityThreshold = _configDao.getValue(Config.PrivateIpCapacityThreshold.key());
+        String secondaryStorageCapacityThreshold = _configDao.getValue(Config.SecondaryStorageCapacityThreshold.key());
+        String vlanCapacityThreshold = _configDao.getValue(Config.VlanCapacityThreshold.key());
+        String directNetworkPublicIpCapacityThreshold = _configDao.getValue(Config.DirectNetworkPublicIpCapacityThreshold.key());
+        String localStorageCapacityThreshold = _configDao.getValue(Config.LocalStorageCapacityThreshold.key());
+
+        if (publicIPCapacityThreshold != null) {
+            _publicIPCapacityThreshold = Double.parseDouble(publicIPCapacityThreshold);
+        }
+        if (privateIPCapacityThreshold != null) {
+            _privateIPCapacityThreshold = Double.parseDouble(privateIPCapacityThreshold);
+        }
+        if (secondaryStorageCapacityThreshold != null) {
+            _secondaryStorageCapacityThreshold = Double.parseDouble(secondaryStorageCapacityThreshold);
+        }
+        if (vlanCapacityThreshold != null) {
+            _vlanCapacityThreshold = Double.parseDouble(vlanCapacityThreshold);
+        }
+        if (directNetworkPublicIpCapacityThreshold != null) {
+            _directNetworkPublicIpCapacityThreshold = Double.parseDouble(directNetworkPublicIpCapacityThreshold);
+        }
+        if (localStorageCapacityThreshold != null) {
+            _localStorageCapacityThreshold = Double.parseDouble(localStorageCapacityThreshold);
+        }
+
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, _publicIPCapacityThreshold);
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_PRIVATE_IP, _privateIPCapacityThreshold);
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, _secondaryStorageCapacityThreshold);
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VLAN, _vlanCapacityThreshold);
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, _directNetworkPublicIpCapacityThreshold);
+        _capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_LOCAL_STORAGE, _localStorageCapacityThreshold);
+
+        String capacityCheckPeriodStr = configs.get("capacity.check.period");
+        if (capacityCheckPeriodStr != null) {
+            _capacityCheckPeriod = Long.parseLong(capacityCheckPeriodStr);
+            if (_capacityCheckPeriod <= 0) {
+                _capacityCheckPeriod = Long.parseLong(Config.CapacityCheckPeriod.getDefaultValue());
+            }
+        }
+
+        _timer = new Timer("CapacityChecker");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        _timer.schedule(new CapacityChecker(), INITIAL_CAPACITY_CHECK_DELAY, _capacityCheckPeriod);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _timer.cancel();
+        return true;
+    }
+
+    @Override
+    public void clearAlert(AlertType alertType, long dataCenterId, long podId) {
+        try {
+            if (_emailAlert != null) {
+                _emailAlert.clearAlert(alertType.getType(), dataCenterId, podId);
+            }
+        } catch (Exception ex) {
+            s_logger.error("Problem clearing email alert", ex);
+        }
+    }
+
+    @Override
+    public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) {
+
+        // publish alert
+        AlertGenerator.publishAlertOnEventBus(alertType.getName(), dataCenterId, podId, subject, body);
+
+        // TODO:  queue up these messages and send them as one set of issues once a certain number of issues is reached?  If that's the case,
+        //         shouldn't we have a type/severity as part of the API so that severe errors get sent right away?
+        try {
+            if (_emailAlert != null) {
+                _emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body);
+            } else {
+                s_logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
+                        " | message:: " + subject + " | body:: " + body);
+            }
+        } catch (Exception ex) {
+            s_logger.error("Problem sending email alert", ex);
+        }
+    }
+
+    @Override
+    public void recalculateCapacity() {
+        // FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener)
+        //        for the vm sync state.  The listener model has connects/disconnects to keep things in sync much better
+        //        than this model right now, so when a VM is started, we update the amount allocated, and when a VM
+        //        is stopped we updated the amount allocated, and when VM sync reports a changed state, we update
+        //        the amount allocated.  Hopefully it's limited to 3 entry points and will keep the amount allocated
+        //        per host accurate.
+
+        try {
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("recalculating system capacity");
+                s_logger.debug("Executing cpu/ram capacity update");
+            }
+
+            // Calculate CPU and RAM capacities
+            //     get all hosts...even if they are not in 'UP' state
+            List<HostVO> hosts = _resourceMgr.listAllNotInMaintenanceHostsInOneZone(Host.Type.Routing, null);
+            if (hosts != null) {
+                for (HostVO host : hosts) {
+                    _capacityMgr.updateCapacityForHost(host);
+                }
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Done executing cpu/ram capacity update");
+                s_logger.debug("Executing storage capacity update");
+            }
+            // Calculate storage pool capacity
+            List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
+            for (StoragePoolVO pool : storagePools) {
+                long disk = _capacityMgr.getAllocatedPoolCapacity(pool, null);
+                if (pool.isShared()) {
+                    _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, disk);
+                } else {
+                    _storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, disk);
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Done executing storage capacity update");
+                s_logger.debug("Executing capacity updates for public ip and Vlans");
+            }
+
+            List<DataCenterVO> datacenters = _dcDao.listAll();
+            for (DataCenterVO datacenter : datacenters) {
+                long dcId = datacenter.getId();
+
+                //NOTE
+                //What happens if we have multiple vlans? Dashboard currently shows stats
+                //with no filter based on a vlan
+                //ideal way would be to remove out the vlan param, and filter only on dcId
+                //implementing the same
+
+                // Calculate new Public IP capacity for Virtual Network
+                if (datacenter.getNetworkType() == NetworkType.Advanced) {
+                    createOrUpdateIpCapacity(dcId, null, Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, datacenter.getAllocationState());
+                }
+
+                // Calculate new Public IP capacity for Direct Attached Network
+                createOrUpdateIpCapacity(dcId, null, Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, datacenter.getAllocationState());
+
+                if (datacenter.getNetworkType() == NetworkType.Advanced) {
+                    //Calculate VLAN's capacity
+                    createOrUpdateVlanCapacity(dcId, datacenter.getAllocationState());
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Done capacity updates for public ip and Vlans");
+                s_logger.debug("Executing capacity updates for private ip");
+            }
+
+            // Calculate new Private IP capacity
+            List<HostPodVO> pods = _podDao.listAll();
+            for (HostPodVO pod : pods) {
+                long podId = pod.getId();
+                long dcId = pod.getDataCenterId();
+
+                createOrUpdateIpCapacity(dcId, podId, Capacity.CAPACITY_TYPE_PRIVATE_IP, _configMgr.findPodAllocationState(pod));
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Done executing capacity updates for private ip");
+                s_logger.debug("Done recalculating system capacity");
+            }
+
+        } catch (Throwable t) {
+            s_logger.error("Caught exception in recalculating capacity", t);
+        }
+    }
+
+    private void createOrUpdateVlanCapacity(long dcId, AllocationState capacityState) {
+
+        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
+
+        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
+        capacitySC = _capacityDao.createSearchCriteria();
+        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
+        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_VLAN);
+        capacities = _capacityDao.search(capacitySC, null);
+
+        int totalVlans = _dcDao.countZoneVlans(dcId, false);
+        int allocatedVlans = _dcDao.countZoneVlans(dcId, true);
+
+        CapacityState vlanCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
+        if (capacities.size() == 0) {
+            CapacityVO newVlanCapacity = new CapacityVO(null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN);
+            newVlanCapacity.setCapacityState(vlanCapacityState);
+            _capacityDao.persist(newVlanCapacity);
+        } else if (!(capacities.get(0).getUsedCapacity() == allocatedVlans && capacities.get(0).getTotalCapacity() == totalVlans
+                && capacities.get(0).getCapacityState() == vlanCapacityState)) {
+            CapacityVO capacity = capacities.get(0);
+            capacity.setUsedCapacity(allocatedVlans);
+            capacity.setTotalCapacity(totalVlans);
+            capacity.setCapacityState(vlanCapacityState);
+            _capacityDao.update(capacity.getId(), capacity);
+        }
+
+    }
+
+    public void createOrUpdateIpCapacity(Long dcId, Long podId, short capacityType, AllocationState capacityState) {
+        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
+
+        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
+        capacitySC = _capacityDao.createSearchCriteria();
+        capacitySC.addAnd("podId", SearchCriteria.Op.EQ, podId);
+        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
+        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
+
+        int totalIPs;
+        int allocatedIPs;
+        capacities = _capacityDao.search(capacitySC, null);
+        if (capacityType == Capacity.CAPACITY_TYPE_PRIVATE_IP) {
+            totalIPs = _privateIPAddressDao.countIPs(podId, dcId, false);
+            allocatedIPs = _privateIPAddressDao.countIPs(podId, dcId, true);
+        } else if (capacityType == Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP) {
+            totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.VirtualNetwork);
+            allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.VirtualNetwork);
+        } else {
+            totalIPs = _publicIPAddressDao.countIPsForNetwork(dcId, false, VlanType.DirectAttached);
+            allocatedIPs = _publicIPAddressDao.countIPsForNetwork(dcId, true, VlanType.DirectAttached);
+        }
+
+        CapacityState ipCapacityState = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
+        if (capacities.size() == 0) {
+            CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType);
+            newPublicIPCapacity.setCapacityState(ipCapacityState);
+            _capacityDao.persist(newPublicIPCapacity);
+        } else if (!(capacities.get(0).getUsedCapacity() == allocatedIPs && capacities.get(0).getTotalCapacity() == totalIPs
+                && capacities.get(0).getCapacityState() == ipCapacityState)) {
+            CapacityVO capacity = capacities.get(0);
+            capacity.setUsedCapacity(allocatedIPs);
+            capacity.setTotalCapacity(totalIPs);
+            capacity.setCapacityState(ipCapacityState);
+            _capacityDao.update(capacity.getId(), capacity);
+        }
+    }
+
+    class CapacityChecker extends ManagedContextTimerTask {
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.debug("Running Capacity Checker ... ");
+                checkForAlerts();
+                s_logger.debug("Done running Capacity Checker ... ");
+            } catch (Throwable t) {
+                s_logger.error("Exception in CapacityChecker", t);
+            }
+        }
+    }
+
+    public void checkForAlerts() {
+
+        recalculateCapacity();
+
+        // abort if we can't possibly send an alert...
+        if (_emailAlert == null) {
+            return;
+        }
+
+        //Get all datacenters, pods and clusters in the system.
+        List<DataCenterVO> dataCenterList = _dcDao.listAll();
+        List<ClusterVO> clusterList = _clusterDao.listAll();
+        List<HostPodVO> podList = _podDao.listAll();
+        //Get capacity types at different levels
+        List<Short> dataCenterCapacityTypes = getCapacityTypesAtZoneLevel();
+        List<Short> podCapacityTypes = getCapacityTypesAtPodLevel();
+        List<Short> clusterCapacityTypes = getCapacityTypesAtClusterLevel();
+
+        // Generate Alerts for Zone Level capacities
+        for (DataCenterVO dc : dataCenterList) {
+            for (Short capacityType : dataCenterCapacityTypes) {
+                List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
+                capacity = _capacityDao.findCapacityBy(capacityType.intValue(), dc.getId(), null, null);
+
+                if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
+                    capacity.add(getUsedStats(capacityType, dc.getId(), null, null));
+                }
+                if (capacity == null || capacity.size() == 0) {
+                    continue;
+                }
+                double totalCapacity = capacity.get(0).getTotalCapacity();
+                double usedCapacity = capacity.get(0).getUsedCapacity();
+                if (totalCapacity != 0 && usedCapacity / totalCapacity > _capacityTypeThresholdMap.get(capacityType)) {
+                    generateEmailAlert(dc, null, null, totalCapacity, usedCapacity, capacityType);
+                }
+            }
+        }
+
+        // Generate Alerts for Pod Level capacities
+        for (HostPodVO pod : podList) {
+            for (Short capacityType : podCapacityTypes) {
+                List<SummedCapacity> capacity = _capacityDao.findCapacityBy(capacityType.intValue(), pod.getDataCenterId(), pod.getId(), null);
+                if (capacity == null || capacity.size() == 0) {
+                    continue;
+                }
+                double totalCapacity = capacity.get(0).getTotalCapacity();
+                double usedCapacity = capacity.get(0).getUsedCapacity();
+                if (totalCapacity != 0 && usedCapacity / totalCapacity > _capacityTypeThresholdMap.get(capacityType)) {
+                    generateEmailAlert(ApiDBUtils.findZoneById(pod.getDataCenterId()), pod, null, totalCapacity, usedCapacity, capacityType);
+                }
+            }
+        }
+
+        // Generate Alerts for Cluster Level capacities
+        for (ClusterVO cluster : clusterList) {
+            for (Short capacityType : clusterCapacityTypes) {
+                List<SummedCapacity> capacity = new ArrayList<SummedCapacity>();
+                capacity = _capacityDao.findCapacityBy(capacityType.intValue(), cluster.getDataCenterId(), null, cluster.getId());
+
+                // cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level
+                double threshold = 0;
+                switch (capacityType) {
+                case Capacity.CAPACITY_TYPE_STORAGE:
+                    capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId()));
+                    threshold = StorageCapacityThreshold.valueIn(cluster.getId());
+                    break;
+                case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED:
+                    threshold = StorageAllocatedCapacityThreshold.valueIn(cluster.getId());
+                    break;
+                case Capacity.CAPACITY_TYPE_CPU:
+                    threshold = CPUCapacityThreshold.valueIn(cluster.getId());
+                    break;
+                case Capacity.CAPACITY_TYPE_MEMORY:
+                    threshold = MemoryCapacityThreshold.valueIn(cluster.getId());
+                    break;
+                default:
+                    threshold = _capacityTypeThresholdMap.get(capacityType);
+                }
+                if (capacity == null || capacity.size() == 0) {
+                    continue;
+                }
+
+                double totalCapacity = capacity.get(0).getTotalCapacity();
+                double usedCapacity = capacity.get(0).getUsedCapacity() + capacity.get(0).getReservedCapacity();
+                if (totalCapacity != 0 && usedCapacity / totalCapacity > threshold) {
+                    generateEmailAlert(ApiDBUtils.findZoneById(cluster.getDataCenterId()), ApiDBUtils.findPodById(cluster.getPodId()), cluster, totalCapacity,
+                            usedCapacity, capacityType);
+                }
+            }
+        }
+
+    }
+
+    private SummedCapacity getUsedStats(short capacityType, long zoneId, Long podId, Long clusterId) {
+        CapacityVO capacity;
+        if (capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
+            capacity = _storageMgr.getSecondaryStorageUsedStats(null, zoneId);
+        } else {
+            capacity = _storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId);
+        }
+        if (capacity != null) {
+            return new SummedCapacity(capacity.getUsedCapacity(), 0, capacity.getTotalCapacity(), capacityType, clusterId, podId);
+        } else {
+            return null;
+        }
+
+    }
+
+    private void generateEmailAlert(DataCenterVO dc, HostPodVO pod, ClusterVO cluster, double totalCapacity, double usedCapacity, short capacityType) {
+
+        String msgSubject = null;
+        String msgContent = null;
+        String totalStr;
+        String usedStr;
+        String pctStr = formatPercent(usedCapacity / totalCapacity);
+        AlertType alertType = null;
+        Long podId = pod == null ? null : pod.getId();
+        Long clusterId = cluster == null ? null : cluster.getId();
+
+        switch (capacityType) {
+
+        //Cluster Level
+        case Capacity.CAPACITY_TYPE_MEMORY:
+            msgSubject = "System Alert: Low Available Memory in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
+            totalStr = formatBytesToMegabytes(totalCapacity);
+            usedStr = formatBytesToMegabytes(usedCapacity);
+            msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_MEMORY;
+            break;
+        case Capacity.CAPACITY_TYPE_CPU:
+            msgSubject = "System Alert: Low Unallocated CPU in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
+            totalStr = DfWhole.format(totalCapacity);
+            usedStr = DfWhole.format(usedCapacity);
+            msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_CPU;
+            break;
+        case Capacity.CAPACITY_TYPE_STORAGE:
+            msgSubject = "System Alert: Low Available Storage in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName();
+            totalStr = formatBytesToMegabytes(totalCapacity);
+            usedStr = formatBytesToMegabytes(usedCapacity);
+            msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE;
+            break;
+        case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED:
+            msgSubject = "System Alert: Remaining unallocated Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " +
+                    dc.getName();
+            totalStr = formatBytesToMegabytes(totalCapacity);
+            usedStr = formatBytesToMegabytes(usedCapacity);
+            msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE_ALLOCATED;
+            break;
+        case Capacity.CAPACITY_TYPE_LOCAL_STORAGE:
+            msgSubject = "System Alert: Remaining unallocated Local Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " +
+                    dc.getName();
+            totalStr = formatBytesToMegabytes(totalCapacity);
+            usedStr = formatBytesToMegabytes(usedCapacity);
+            msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_LOCAL_STORAGE;
+            break;
+
+            //Pod Level
+        case Capacity.CAPACITY_TYPE_PRIVATE_IP:
+            msgSubject = "System Alert: Number of unallocated private IPs is low in pod " + pod.getName() + " of availability zone " + dc.getName();
+            totalStr = Double.toString(totalCapacity);
+            usedStr = Double.toString(usedCapacity);
+            msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_PRIVATE_IP;
+            break;
+
+            //Zone Level
+        case Capacity.CAPACITY_TYPE_SECONDARY_STORAGE:
+            msgSubject = "System Alert: Low Available Secondary Storage in availability zone " + dc.getName();
+            totalStr = formatBytesToMegabytes(totalCapacity);
+            usedStr = formatBytesToMegabytes(usedCapacity);
+            msgContent = "Available secondary storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_SECONDARY_STORAGE;
+            break;
+        case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP:
+            msgSubject = "System Alert: Number of unallocated virtual network public IPs is low in availability zone " + dc.getName();
+            totalStr = Double.toString(totalCapacity);
+            usedStr = Double.toString(usedCapacity);
+            msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP;
+            break;
+        case Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP:
+            msgSubject = "System Alert: Number of unallocated shared network IPs is low in availability zone " + dc.getName();
+            totalStr = Double.toString(totalCapacity);
+            usedStr = Double.toString(usedCapacity);
+            msgContent = "Number of unallocated shared network IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP;
+            break;
+        case Capacity.CAPACITY_TYPE_VLAN:
+            msgSubject = "System Alert: Number of unallocated VLANs is low in availability zone " + dc.getName();
+            totalStr = Double.toString(totalCapacity);
+            usedStr = Double.toString(usedCapacity);
+            msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
+            alertType = AlertManager.AlertType.ALERT_TYPE_VLAN;
+            break;
+        }
+
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(msgSubject);
+                s_logger.debug(msgContent);
+            }
+            _emailAlert.sendAlert(alertType, dc.getId(), podId, clusterId, msgSubject, msgContent);
+        } catch (Exception ex) {
+            s_logger.error("Exception in CapacityChecker", ex);
+        }
+    }
+
+    private List<Short> getCapacityTypesAtZoneLevel() {
+
+        List<Short> dataCenterCapacityTypes = new ArrayList<Short>();
+        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP);
+        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP);
+        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
+        dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VLAN);
+        return dataCenterCapacityTypes;
+
+    }
+
+    private List<Short> getCapacityTypesAtPodLevel() {
+
+        List<Short> podCapacityTypes = new ArrayList<Short>();
+        podCapacityTypes.add(Capacity.CAPACITY_TYPE_PRIVATE_IP);
+        return podCapacityTypes;
+
+    }
+
+    private List<Short> getCapacityTypesAtClusterLevel() {
+
+        List<Short> clusterCapacityTypes = new ArrayList<Short>();
+        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_CPU);
+        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_MEMORY);
+        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE);
+        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED);
+        clusterCapacityTypes.add(Capacity.CAPACITY_TYPE_LOCAL_STORAGE);
+        return clusterCapacityTypes;
+
+    }
+
+    class EmailAlert {
+        private Session _smtpSession;
+        private InternetAddress[] _recipientList;
+        private final String _smtpHost;
+        private int _smtpPort = -1;
+        private boolean _smtpUseAuth = false;
+        private final String _smtpUsername;
+        private final String _smtpPassword;
+        private final String _emailSender;
+        private int _smtpTimeout;
+        private int _smtpConnectionTimeout;
+
+        public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, int smtpConnectionTimeout, int smtpTimeout, boolean smtpUseAuth,
+                final String smtpUsername,
+                final String smtpPassword, String emailSender, boolean smtpDebug) {
+            if (recipientList != null) {
+                _recipientList = new InternetAddress[recipientList.length];
+                for (int i = 0; i < recipientList.length; i++) {
+                    try {
+                        _recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]);
+                    } catch (Exception ex) {
+                        s_logger.error("Exception creating address for: " + recipientList[i], ex);
+                    }
+                }
+            }
+
+            _smtpHost = smtpHost;
+            _smtpPort = smtpPort;
+            _smtpUseAuth = smtpUseAuth;
+            _smtpUsername = smtpUsername;
+            _smtpPassword = smtpPassword;
+            _emailSender = emailSender;
+            _smtpTimeout = smtpTimeout;
+            _smtpConnectionTimeout = smtpConnectionTimeout;
+
+            if (_smtpHost != null) {
+                Properties smtpProps = new Properties();
+                smtpProps.put("mail.smtp.host", smtpHost);
+                smtpProps.put("mail.smtp.port", smtpPort);
+                smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
+                smtpProps.put("mail.smtp.timeout", _smtpTimeout);
+                smtpProps.put("mail.smtp.connectiontimeout", _smtpConnectionTimeout);
+
+                if (smtpUsername != null) {
+                    smtpProps.put("mail.smtp.user", smtpUsername);
+                }
+
+                smtpProps.put("mail.smtps.host", smtpHost);
+                smtpProps.put("mail.smtps.port", smtpPort);
+                smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
+                smtpProps.put("mail.smtps.timeout", _smtpTimeout);
+                smtpProps.put("mail.smtps.connectiontimeout", _smtpConnectionTimeout);
+
+                if (smtpUsername != null) {
+                    smtpProps.put("mail.smtps.user", smtpUsername);
+                }
+
+                if ((smtpUsername != null) && (smtpPassword != null)) {
+                    _smtpSession = Session.getInstance(smtpProps, new Authenticator() {
+                        @Override
+                        protected PasswordAuthentication getPasswordAuthentication() {
+                            return new PasswordAuthentication(smtpUsername, smtpPassword);
+                        }
+                    });
+                } else {
+                    _smtpSession = Session.getInstance(smtpProps);
+                }
+                _smtpSession.setDebug(smtpDebug);
+            } else {
+                _smtpSession = null;
+            }
+        }
+
+        // TODO:  make sure this handles SSL transport (useAuth is true) and regular
+        public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException,
+        UnsupportedEncodingException {
+            s_logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " +
+                    podId + " | clusterId:: " + clusterId + " | message:: " + subject);
+            AlertVO alert = null;
+            if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) &&
+                    (alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT)) {
+                alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
+            }
+
+            if (alert == null) {
+                // set up a new alert
+                AlertVO newAlert = new AlertVO();
+                newAlert.setType(alertType.getType());
+                newAlert.setSubject(subject);
+                newAlert.setContent(content);
+                newAlert.setClusterId(clusterId);
+                newAlert.setPodId(podId);
+                newAlert.setDataCenterId(dataCenterId);
+                newAlert.setSentCount(1); // Initialize sent count to 1 since we are now sending an alert.
+                newAlert.setLastSent(new Date());
+                newAlert.setName(alertType.getName());
+                _alertDao.persist(newAlert);
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
+                }
+                return;
+            }
+
+            if (_smtpSession != null) {
+                SMTPMessage msg = new SMTPMessage(_smtpSession);
+                msg.setSender(new InternetAddress(_emailSender, _emailSender));
+                msg.setFrom(new InternetAddress(_emailSender, _emailSender));
+                for (InternetAddress address : _recipientList) {
+                    msg.addRecipient(RecipientType.TO, address);
+                }
+                msg.setSubject(subject);
+                msg.setSentDate(new Date());
+                msg.setContent(content, "text/plain");
+                msg.saveChanges();
+
+                SMTPTransport smtpTrans = null;
+                if (_smtpUseAuth) {
+                    smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
+                } else {
+                    smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
+                }
+                sendMessage(smtpTrans, msg);
+            }
+        }
+
+        private void sendMessage(final SMTPTransport smtpTrans, final SMTPMessage msg) {
+            _executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        smtpTrans.connect();
+                        smtpTrans.sendMessage(msg, msg.getAllRecipients());
+                        smtpTrans.close();
+                    } catch (SendFailedException e) {
+                        s_logger.error(" Failed to send email alert " + e);
+                    } catch (MessagingException e) {
+                        s_logger.error(" Failed to send email alert " + e);
+                    }
+                }
+            });
+        }
+
+        public void clearAlert(short alertType, long dataCenterId, Long podId) {
+            if (alertType != -1) {
+                AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, null);
+                if (alert != null) {
+                    AlertVO updatedAlert = _alertDao.createForUpdate();
+                    updatedAlert.setResolved(new Date());
+                    _alertDao.update(alert.getId(), updatedAlert);
+                }
+            }
+        }
+    }
+
+    private static String formatPercent(double percentage) {
+        return DfPct.format(percentage * 100);
+    }
+
+    private static String formatBytesToMegabytes(double bytes) {
+        double megaBytes = (bytes / (1024 * 1024));
+        return DfWhole.format(megaBytes);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return AlertManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold};
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.ALERT_GENERATE, eventDescription = "generating alert", async = true)
+    public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId, String msg) {
+        try {
+            sendAlert(alertType, dataCenterId, podId, msg, msg);
+            return true;
+        } catch (Exception ex) {
+            s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg);
+            return false;
+        }
+    }
+}
diff --git a/server/src/com/cloud/alert/ClusterAlertAdapter.java b/server/src/main/java/com/cloud/alert/ClusterAlertAdapter.java
similarity index 100%
rename from server/src/com/cloud/alert/ClusterAlertAdapter.java
rename to server/src/main/java/com/cloud/alert/ClusterAlertAdapter.java
diff --git a/server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java b/server/src/main/java/com/cloud/alert/ConsoleProxyAlertAdapter.java
similarity index 100%
rename from server/src/com/cloud/alert/ConsoleProxyAlertAdapter.java
rename to server/src/main/java/com/cloud/alert/ConsoleProxyAlertAdapter.java
diff --git a/server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java b/server/src/main/java/com/cloud/alert/SecondaryStorageVmAlertAdapter.java
similarity index 100%
rename from server/src/com/cloud/alert/SecondaryStorageVmAlertAdapter.java
rename to server/src/main/java/com/cloud/alert/SecondaryStorageVmAlertAdapter.java
diff --git a/server/src/com/cloud/api/ApiAsyncJobDispatcher.java b/server/src/main/java/com/cloud/api/ApiAsyncJobDispatcher.java
similarity index 100%
rename from server/src/com/cloud/api/ApiAsyncJobDispatcher.java
rename to server/src/main/java/com/cloud/api/ApiAsyncJobDispatcher.java
diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/main/java/com/cloud/api/ApiDBUtils.java
similarity index 100%
rename from server/src/com/cloud/api/ApiDBUtils.java
rename to server/src/main/java/com/cloud/api/ApiDBUtils.java
diff --git a/server/src/main/java/com/cloud/api/ApiDispatcher.java b/server/src/main/java/com/cloud/api/ApiDispatcher.java
new file mode 100644
index 0000000..11615ea
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/ApiDispatcher.java
@@ -0,0 +1,159 @@
+// 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.api;
+
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import com.cloud.projects.Project;
+import com.cloud.utils.db.EntityManager;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCustomIdCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+
+import com.cloud.api.dispatch.DispatchChain;
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+
+public class ApiDispatcher {
+    private static final Logger s_logger = Logger.getLogger(ApiDispatcher.class.getName());
+
+    Long _createSnapshotQueueSizeLimit;
+    Long migrateQueueSizeLimit;
+
+    @Inject
+    AsyncJobManager _asyncMgr;
+
+    @Inject
+    AccountManager _accountMgr;
+
+    @Inject
+    EntityManager _entityMgr;
+
+    @Inject()
+    protected DispatchChainFactory dispatchChainFactory;
+
+    protected DispatchChain standardDispatchChain;
+
+    protected DispatchChain asyncCreationDispatchChain;
+
+    public ApiDispatcher() {
+    }
+
+    @PostConstruct
+    public void setup() {
+        standardDispatchChain = dispatchChainFactory.getStandardDispatchChain();
+        asyncCreationDispatchChain = dispatchChainFactory.getAsyncCreationDispatchChain();
+    }
+
+    public void setCreateSnapshotQueueSizeLimit(final Long snapshotLimit) {
+        _createSnapshotQueueSizeLimit = snapshotLimit;
+    }
+
+    public void setMigrateQueueSizeLimit(final Long migrateLimit) {
+        migrateQueueSizeLimit = migrateLimit;
+    }
+
+    public void dispatchCreateCmd(final BaseAsyncCreateCmd cmd, final Map<String, String> params) throws Exception {
+        asyncCreationDispatchChain.dispatch(new DispatchTask(cmd, params));
+    }
+
+    private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class);
+        String apiName = commandAnnotation != null ? commandAnnotation.name() : null;
+
+        if (!entitiesToAccess.isEmpty()) {
+            for (Object entity : entitiesToAccess.keySet()) {
+                if (entity instanceof ControlledEntity) {
+                    _accountMgr.checkAccess(caller, entitiesToAccess.get(entity), false, apiName, (ControlledEntity) entity);
+                } else if (entity instanceof InfrastructureEntity) {
+                    //FIXME: Move this code in adapter, remove code from Account manager
+                }
+            }
+        }
+    }
+
+    public void dispatch(final BaseCmd cmd, final Map<String, String> params, final boolean execute) throws Exception {
+        // Let the chain of responsibility dispatch gradually
+        standardDispatchChain.dispatch(new DispatchTask(cmd, params));
+
+        final CallContext ctx = CallContext.current();
+        ctx.setEventDisplayEnabled(cmd.isDisplay());
+        if(params.get(ApiConstants.PROJECT_ID) != null) {
+            Project project = _entityMgr.findByUuidIncludingRemoved(Project.class, params.get(ApiConstants.PROJECT_ID));
+            ctx.setProject(project);
+        }
+
+        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
+        if (cmd instanceof BaseAsyncCmd) {
+
+            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
+            final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
+            ctx.setStartEventId(Long.parseLong(startEventId));
+
+            // Synchronise job on the object if needed
+            if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {
+                Long queueSizeLimit = null;
+                if (asyncCmd.getSyncObjType() != null && asyncCmd.getSyncObjType().equalsIgnoreCase(BaseAsyncCmd.snapshotHostSyncObject)) {
+                        queueSizeLimit = _createSnapshotQueueSizeLimit;
+                } else if (asyncCmd.getSyncObjType() != null && asyncCmd.getSyncObjType().equalsIgnoreCase(BaseAsyncCmd.migrationSyncObject)) {
+                        queueSizeLimit = migrateQueueSizeLimit;
+                } else {
+                    queueSizeLimit = 1L;
+                }
+
+                if (queueSizeLimit != null) {
+                    if (!execute) {
+                        // if we are not within async-execution context, enqueue the command
+                        _asyncMgr.syncAsyncJobExecution((AsyncJob)asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue(), queueSizeLimit);
+                        return;
+                    }
+                } else {
+                    s_logger.trace("The queue size is unlimited, skipping the synchronizing");
+                }
+            }
+        }
+
+        // TODO This if shouldn't be here. Use polymorphism and move it to validateSpecificParameters
+        if (cmd instanceof BaseAsyncCustomIdCmd) {
+            ((BaseAsyncCustomIdCmd)cmd).checkUuid();
+        } else if (cmd instanceof BaseCustomIdCmd) {
+            ((BaseCustomIdCmd)cmd).checkUuid();
+        }
+
+        cmd.execute();
+    }
+
+}
diff --git a/server/src/com/cloud/api/ApiGsonHelper.java b/server/src/main/java/com/cloud/api/ApiGsonHelper.java
similarity index 100%
rename from server/src/com/cloud/api/ApiGsonHelper.java
rename to server/src/main/java/com/cloud/api/ApiGsonHelper.java
diff --git a/server/src/com/cloud/api/ApiResponseGsonHelper.java b/server/src/main/java/com/cloud/api/ApiResponseGsonHelper.java
similarity index 100%
rename from server/src/com/cloud/api/ApiResponseGsonHelper.java
rename to server/src/main/java/com/cloud/api/ApiResponseGsonHelper.java
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
new file mode 100644
index 0000000..0b310c0
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -0,0 +1,3988 @@
+// 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.api;
+
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.agent.api.VgpuTypesInfo;
+import com.cloud.api.query.ViewResponseHelper;
+import com.cloud.api.query.vo.AccountJoinVO;
+import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.api.query.vo.DataCenterJoinVO;
+import com.cloud.api.query.vo.DiskOfferingJoinVO;
+import com.cloud.api.query.vo.DomainRouterJoinVO;
+import com.cloud.api.query.vo.EventJoinVO;
+import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.ImageStoreJoinVO;
+import com.cloud.api.query.vo.InstanceGroupJoinVO;
+import com.cloud.api.query.vo.ProjectAccountJoinVO;
+import com.cloud.api.query.vo.ProjectInvitationJoinVO;
+import com.cloud.api.query.vo.ProjectJoinVO;
+import com.cloud.api.query.vo.ResourceTagJoinVO;
+import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
+import com.cloud.api.query.vo.StoragePoolJoinVO;
+import com.cloud.api.query.vo.TemplateJoinVO;
+import com.cloud.api.query.vo.UserAccountJoinVO;
+import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.ResourceCount;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.StorageNetworkIpRange;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.event.Event;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.gpu.GPU;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.HypervisorCapabilities;
+import com.cloud.network.GuestVlan;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.OvsProvider;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteCustomerGateway;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnGateway;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.VpnUser;
+import com.cloud.network.VpnUserVO;
+import com.cloud.network.as.AutoScalePolicy;
+import com.cloud.network.as.AutoScaleVmGroup;
+import com.cloud.network.as.AutoScaleVmProfile;
+import com.cloud.network.as.AutoScaleVmProfileVO;
+import com.cloud.network.as.Condition;
+import com.cloud.network.as.ConditionVO;
+import com.cloud.network.as.Counter;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.HealthCheckPolicy;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.StickinessPolicy;
+import com.cloud.network.security.SecurityGroup;
+import com.cloud.network.security.SecurityGroupVO;
+import com.cloud.network.security.SecurityRule;
+import com.cloud.network.security.SecurityRule.SecurityRuleType;
+import com.cloud.network.vpc.NetworkACL;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcOffering;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.org.Cluster;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectAccount;
+import com.cloud.projects.ProjectInvitation;
+import com.cloud.region.ha.GlobalLoadBalancerRule;
+import com.cloud.server.ResourceTag;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.ImageStore;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Upload;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotPolicy;
+import com.cloud.storage.snapshot.SnapshotSchedule;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.SSHKeyPair;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.ConsoleProxyVO;
+import com.cloud.vm.InstanceGroup;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicExtraDhcpOptionVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.dao.NicExtraDhcpOptionDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.snapshot.VMSnapshot;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.ApiConstants.HostDetails;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ResponseGenerator;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.ApplicationLoadBalancerInstanceResponse;
+import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
+import org.apache.cloudstack.api.response.ApplicationLoadBalancerRuleResponse;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
+import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
+import org.apache.cloudstack.api.response.CapabilityResponse;
+import org.apache.cloudstack.api.response.CapacityResponse;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.ConditionResponse;
+import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.ControlledEntityResponse;
+import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
+import org.apache.cloudstack.api.response.CounterResponse;
+import org.apache.cloudstack.api.response.CreateCmdResponse;
+import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.EventResponse;
+import org.apache.cloudstack.api.response.ExtractResponse;
+import org.apache.cloudstack.api.response.FirewallResponse;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
+import org.apache.cloudstack.api.response.HostForMigrationResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
+import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
+import org.apache.cloudstack.api.response.IsolationMethodResponse;
+import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse;
+import org.apache.cloudstack.api.response.LBHealthCheckResponse;
+import org.apache.cloudstack.api.response.LBStickinessPolicyResponse;
+import org.apache.cloudstack.api.response.LBStickinessResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.LoadBalancerResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
+import org.apache.cloudstack.api.response.NetworkACLItemResponse;
+import org.apache.cloudstack.api.response.NetworkACLResponse;
+import org.apache.cloudstack.api.response.NetworkOfferingResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.OvsProviderResponse;
+import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.PortableIpRangeResponse;
+import org.apache.cloudstack.api.response.PortableIpResponse;
+import org.apache.cloudstack.api.response.PrivateGatewayResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import org.apache.cloudstack.api.response.ProjectInvitationResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ProviderResponse;
+import org.apache.cloudstack.api.response.RegionResponse;
+import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
+import org.apache.cloudstack.api.response.ResourceCountResponse;
+import org.apache.cloudstack.api.response.ResourceLimitResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
+import org.apache.cloudstack.api.response.SSHKeyPairResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.ServiceResponse;
+import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
+import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
+import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
+import org.apache.cloudstack.api.response.StaticRouteResponse;
+import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.TrafficMonitorResponse;
+import org.apache.cloudstack.api.response.TrafficTypeResponse;
+import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
+import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VMSnapshotResponse;
+import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
+import org.apache.cloudstack.api.response.VlanIpRangeResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.VpcOfferingResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.VpnUsersResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpRange;
+import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.usage.Usage;
+import org.apache.cloudstack.usage.UsageService;
+import org.apache.cloudstack.usage.UsageTypes;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.stream.Collectors;
+
+public class ApiResponseHelper implements ResponseGenerator {
+
+    private static final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
+    private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##");
+
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private UsageService _usageSvc;
+    @Inject
+    NetworkModel _ntwkModel;
+    @Inject
+    protected AccountManager _accountMgr;
+    @Inject
+    protected AsyncJobManager _jobMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    SnapshotDataFactory snapshotfactory;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private DataStoreManager _dataStoreMgr;
+    @Inject
+    private SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private ResourceTagDao _resourceTagDao;
+    @Inject
+    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
+    @Inject
+    private IPAddressDao userIpAddressDao;
+
+    @Override
+    public UserResponse createUserResponse(User user) {
+        UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
+        return ApiDBUtils.newUserResponse(vUser);
+    }
+
+    // this method is used for response generation via createAccount (which
+    // creates an account + user)
+    @Override
+    public AccountResponse createUserAccountResponse(ResponseView view, UserAccount user) {
+        return ApiDBUtils.newAccountResponse(view, ApiDBUtils.findAccountViewById(user.getAccountId()));
+    }
+
+    @Override
+    public AccountResponse createAccountResponse(ResponseView view, Account account) {
+        AccountJoinVO vUser = ApiDBUtils.newAccountView(account);
+        return ApiDBUtils.newAccountResponse(view, vUser);
+    }
+
+    @Override
+    public UserResponse createUserResponse(UserAccount user) {
+        UserAccountJoinVO vUser = ApiDBUtils.newUserView(user);
+        return ApiDBUtils.newUserResponse(vUser);
+    }
+
+    @Override
+    public DomainResponse createDomainResponse(Domain domain) {
+        DomainResponse domainResponse = new DomainResponse();
+        domainResponse.setDomainName(domain.getName());
+        domainResponse.setId(domain.getUuid());
+        domainResponse.setLevel(domain.getLevel());
+        domainResponse.setNetworkDomain(domain.getNetworkDomain());
+        Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent());
+        if (parentDomain != null) {
+            domainResponse.setParentDomainId(parentDomain.getUuid());
+        }
+        StringBuilder domainPath = new StringBuilder("ROOT");
+        (domainPath.append(domain.getPath())).deleteCharAt(domainPath.length() - 1);
+        domainResponse.setPath(domainPath.toString());
+        if (domain.getParent() != null) {
+            domainResponse.setParentDomainName(ApiDBUtils.findDomainById(domain.getParent()).getName());
+        }
+        if (domain.getChildCount() > 0) {
+            domainResponse.setHasChild(true);
+        }
+        domainResponse.setObjectName("domain");
+        return domainResponse;
+    }
+
+    @Override
+    public DiskOfferingResponse createDiskOfferingResponse(DiskOffering offering) {
+        DiskOfferingJoinVO vOffering = ApiDBUtils.newDiskOfferingView(offering);
+        return ApiDBUtils.newDiskOfferingResponse(vOffering);
+    }
+
+    @Override
+    public ResourceLimitResponse createResourceLimitResponse(ResourceLimit limit) {
+        ResourceLimitResponse resourceLimitResponse = new ResourceLimitResponse();
+        if (limit.getResourceOwnerType() == ResourceOwnerType.Domain) {
+            populateDomain(resourceLimitResponse, limit.getOwnerId());
+        } else if (limit.getResourceOwnerType() == ResourceOwnerType.Account) {
+            Account accountTemp = ApiDBUtils.findAccountById(limit.getOwnerId());
+            populateAccount(resourceLimitResponse, limit.getOwnerId());
+            populateDomain(resourceLimitResponse, accountTemp.getDomainId());
+        }
+        resourceLimitResponse.setResourceType(limit.getType());
+
+        if ((limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) && limit.getMax() >= 0) {
+            resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB));
+        } else {
+            resourceLimitResponse.setMax(limit.getMax());
+        }
+        resourceLimitResponse.setObjectName("resourcelimit");
+
+        return resourceLimitResponse;
+    }
+
+    @Override
+    public ResourceCountResponse createResourceCountResponse(ResourceCount resourceCount) {
+        ResourceCountResponse resourceCountResponse = new ResourceCountResponse();
+
+        if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Account) {
+            Account accountTemp = ApiDBUtils.findAccountById(resourceCount.getOwnerId());
+            if (accountTemp != null) {
+                populateAccount(resourceCountResponse, accountTemp.getId());
+                populateDomain(resourceCountResponse, accountTemp.getDomainId());
+            }
+        } else if (resourceCount.getResourceOwnerType() == ResourceOwnerType.Domain) {
+            populateDomain(resourceCountResponse, resourceCount.getOwnerId());
+        }
+
+        resourceCountResponse.setResourceType(resourceCount.getType());
+        resourceCountResponse.setResourceCount(resourceCount.getCount());
+        resourceCountResponse.setObjectName("resourcecount");
+        return resourceCountResponse;
+    }
+
+    @Override
+    public ServiceOfferingResponse createServiceOfferingResponse(ServiceOffering offering) {
+        ServiceOfferingJoinVO vOffering = ApiDBUtils.newServiceOfferingView(offering);
+        return ApiDBUtils.newServiceOfferingResponse(vOffering);
+    }
+
+    @Override
+    public ConfigurationResponse createConfigurationResponse(Configuration cfg) {
+        ConfigurationResponse cfgResponse = new ConfigurationResponse();
+        cfgResponse.setCategory(cfg.getCategory());
+        cfgResponse.setDescription(cfg.getDescription());
+        cfgResponse.setName(cfg.getName());
+        if (cfg.isEncrypted()) {
+            cfgResponse.setValue(DBEncryptionUtil.encrypt(cfg.getValue()));
+        } else {
+            cfgResponse.setValue(cfg.getValue());
+        }
+        cfgResponse.setObjectName("configuration");
+
+        return cfgResponse;
+    }
+
+    @Override
+    public SnapshotResponse createSnapshotResponse(Snapshot snapshot) {
+        SnapshotResponse snapshotResponse = new SnapshotResponse();
+        snapshotResponse.setId(snapshot.getUuid());
+
+        populateOwner(snapshotResponse, snapshot);
+
+        VolumeVO volume = findVolumeById(snapshot.getVolumeId());
+        String snapshotTypeStr = snapshot.getRecurringType().name();
+        snapshotResponse.setSnapshotType(snapshotTypeStr);
+        if (volume != null) {
+            snapshotResponse.setVolumeId(volume.getUuid());
+            snapshotResponse.setVolumeName(volume.getName());
+            snapshotResponse.setVolumeType(volume.getVolumeType().name());
+            snapshotResponse.setVirtualSize(volume.getSize());
+            DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId());
+            if (zone != null) {
+                snapshotResponse.setZoneId(zone.getUuid());
+            }
+
+            if (volume.getVolumeType() == Volume.Type.ROOT && volume.getInstanceId() != null) {
+                //TODO combine lines and 489 into a join in the volume dao
+                VMInstanceVO instance = ApiDBUtils.findVMInstanceById(volume.getInstanceId());
+                if (instance != null) {
+                    GuestOS guestOs = ApiDBUtils.findGuestOSById(instance.getGuestOSId());
+                    if (guestOs != null) {
+                        snapshotResponse.setOsTypeId(guestOs.getUuid());
+                        snapshotResponse.setOsDisplayName(guestOs.getDisplayName());
+                    }
+                }
+            }
+        }
+        snapshotResponse.setCreated(snapshot.getCreated());
+        snapshotResponse.setName(snapshot.getName());
+        snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId()));
+        snapshotResponse.setState(snapshot.getState());
+        snapshotResponse.setLocationType(ApiDBUtils.getSnapshotLocationType(snapshot.getId()));
+
+        SnapshotInfo snapshotInfo = null;
+
+        if (snapshot instanceof SnapshotInfo) {
+            snapshotInfo = (SnapshotInfo)snapshot;
+        } else {
+            DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
+
+            snapshotInfo = snapshotfactory.getSnapshot(snapshot.getId(), dataStoreRole);
+        }
+
+        if (snapshotInfo == null) {
+            s_logger.debug("Unable to find info for image store snapshot with uuid " + snapshot.getUuid());
+            snapshotResponse.setRevertable(false);
+        } else {
+        snapshotResponse.setRevertable(snapshotInfo.isRevertable());
+        snapshotResponse.setPhysicaSize(snapshotInfo.getPhysicalSize());
+        }
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Snapshot, snapshot.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        snapshotResponse.setTags(tagResponses);
+
+        snapshotResponse.setObjectName("snapshot");
+        return snapshotResponse;
+    }
+
+    public static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
+        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+        if (snapshotStore == null) {
+            return DataStoreRole.Image;
+        }
+
+        long storagePoolId = snapshotStore.getDataStoreId();
+        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        if (dataStore == null) {
+            return DataStoreRole.Image;
+        }
+
+        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
+
+        if (mapCapabilities != null) {
+            String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
+            Boolean supportsStorageSystemSnapshots = new Boolean(value);
+
+            if (supportsStorageSystemSnapshots) {
+                return DataStoreRole.Primary;
+            }
+        }
+
+        return DataStoreRole.Image;
+    }
+
+    @Override
+    public VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot) {
+        VMSnapshotResponse vmSnapshotResponse = new VMSnapshotResponse();
+        vmSnapshotResponse.setId(vmSnapshot.getUuid());
+        vmSnapshotResponse.setName(vmSnapshot.getName());
+        vmSnapshotResponse.setState(vmSnapshot.getState());
+        vmSnapshotResponse.setCreated(vmSnapshot.getCreated());
+        vmSnapshotResponse.setDescription(vmSnapshot.getDescription());
+        vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName());
+        UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId());
+        if (vm != null) {
+            vmSnapshotResponse.setVirtualMachineid(vm.getUuid());
+            DataCenterVO datacenter = ApiDBUtils.findZoneById(vm.getDataCenterId());
+            if (datacenter != null) {
+                vmSnapshotResponse.setZoneId(datacenter.getUuid());
+            }
+        }
+        if (vmSnapshot.getParent() != null) {
+            VMSnapshot vmSnapshotParent = ApiDBUtils.getVMSnapshotById(vmSnapshot.getParent());
+            if (vmSnapshotParent != null) {
+                vmSnapshotResponse.setParent(vmSnapshotParent.getUuid());
+                vmSnapshotResponse.setParentName(vmSnapshotParent.getDisplayName());
+            }
+        }
+        populateOwner(vmSnapshotResponse, vmSnapshot);
+        Project project = ApiDBUtils.findProjectByProjectAccountId(vmSnapshot.getAccountId());
+        if (project != null) {
+            vmSnapshotResponse.setProjectId(project.getUuid());
+            vmSnapshotResponse.setProjectName(project.getName());
+        }
+        Account account = ApiDBUtils.findAccountById(vmSnapshot.getAccountId());
+        if (account != null) {
+            vmSnapshotResponse.setAccountName(account.getAccountName());
+        }
+        DomainVO domain = ApiDBUtils.findDomainById(vmSnapshot.getDomainId());
+        if (domain != null) {
+            vmSnapshotResponse.setDomainId(domain.getUuid());
+            vmSnapshotResponse.setDomainName(domain.getName());
+        }
+
+        vmSnapshotResponse.setCurrent(vmSnapshot.getCurrent());
+        vmSnapshotResponse.setType(vmSnapshot.getType().toString());
+        vmSnapshotResponse.setObjectName("vmsnapshot");
+        return vmSnapshotResponse;
+    }
+
+    @Override
+    public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) {
+        SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse();
+        policyResponse.setId(policy.getUuid());
+        Volume vol = ApiDBUtils.findVolumeById(policy.getVolumeId());
+        if (vol != null) {
+            policyResponse.setVolumeId(vol.getUuid());
+        }
+        policyResponse.setSchedule(policy.getSchedule());
+        policyResponse.setIntervalType(policy.getInterval());
+        policyResponse.setMaxSnaps(policy.getMaxSnaps());
+        policyResponse.setTimezone(policy.getTimezone());
+        policyResponse.setForDisplay(policy.isDisplay());
+        policyResponse.setObjectName("snapshotpolicy");
+
+        return policyResponse;
+    }
+
+    @Override
+    public HostResponse createHostResponse(Host host) {
+        return createHostResponse(host, EnumSet.of(HostDetails.all));
+    }
+
+    @Override
+    public HostResponse createHostResponse(Host host, EnumSet<HostDetails> details) {
+        List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
+        List<HostResponse> listHosts = ViewResponseHelper.createHostResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
+        assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
+        return listHosts.get(0);
+    }
+
+    @Override
+    public HostForMigrationResponse createHostForMigrationResponse(Host host) {
+        return createHostForMigrationResponse(host, EnumSet.of(HostDetails.all));
+    }
+
+    @Override
+    public HostForMigrationResponse createHostForMigrationResponse(Host host, EnumSet<HostDetails> details) {
+        List<HostJoinVO> viewHosts = ApiDBUtils.newHostView(host);
+        List<HostForMigrationResponse> listHosts = ViewResponseHelper.createHostForMigrationResponse(details, viewHosts.toArray(new HostJoinVO[viewHosts.size()]));
+        assert listHosts != null && listHosts.size() == 1 : "There should be one host returned";
+        return listHosts.get(0);
+    }
+
+    @Override
+    public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) {
+        return createVlanIpRangeResponse(VlanIpRangeResponse.class, vlan);
+    }
+
+    @Override
+    public VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan) {
+        try {
+            Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId());
+
+            VlanIpRangeResponse vlanResponse = subClass.newInstance();
+            vlanResponse.setId(vlan.getUuid());
+            if (vlan.getVlanType() != null) {
+                vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork));
+            }
+            vlanResponse.setVlan(vlan.getVlanTag());
+            DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId());
+            if (zone != null) {
+                vlanResponse.setZoneId(zone.getUuid());
+            }
+
+            if (podId != null) {
+                HostPodVO pod = ApiDBUtils.findPodById(podId);
+                if (pod != null) {
+                    vlanResponse.setPodId(pod.getUuid());
+                    vlanResponse.setPodName(pod.getName());
+                }
+            }
+
+            vlanResponse.setGateway(vlan.getVlanGateway());
+            vlanResponse.setNetmask(vlan.getVlanNetmask());
+
+            // get start ip and end ip of corresponding vlan
+            String ipRange = vlan.getIpRange();
+            if (ipRange != null) {
+                String[] range = ipRange.split("-");
+                vlanResponse.setStartIp(range[0]);
+                vlanResponse.setEndIp(range[1]);
+            }
+
+            vlanResponse.setIp6Gateway(vlan.getIp6Gateway());
+            vlanResponse.setIp6Cidr(vlan.getIp6Cidr());
+
+            String ip6Range = vlan.getIp6Range();
+            if (ip6Range != null) {
+                String[] range = ip6Range.split("-");
+                vlanResponse.setStartIpv6(range[0]);
+                vlanResponse.setEndIpv6(range[1]);
+            }
+
+            if (vlan.getNetworkId() != null) {
+                Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId());
+                if (nw != null) {
+                    vlanResponse.setNetworkId(nw.getUuid());
+                }
+            }
+            Account owner = ApiDBUtils.getVlanAccount(vlan.getId());
+            if (owner != null) {
+                populateAccount(vlanResponse, owner.getId());
+                populateDomain(vlanResponse, owner.getDomainId());
+            } else {
+                Domain domain = ApiDBUtils.getVlanDomain(vlan.getId());
+                if (domain != null) {
+                    populateDomain(vlanResponse, domain.getId());
+                } else {
+                    Long networkId = vlan.getNetworkId();
+                    if (networkId != null) {
+                        Network network = _ntwkModel.getNetwork(networkId);
+                        if (network != null) {
+                            Long accountId = network.getAccountId();
+                            populateAccount(vlanResponse, accountId);
+                            populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId());
+                        }
+                    }
+                }
+            }
+
+            if (vlan.getPhysicalNetworkId() != null) {
+                PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
+                if (pnw != null) {
+                    vlanResponse.setPhysicalNetworkId(pnw.getUuid());
+                }
+            }
+            vlanResponse.setForSystemVms(isForSystemVms(vlan.getId()));
+            vlanResponse.setObjectName("vlan");
+            return vlanResponse;
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new CloudRuntimeException("Failed to create Vlan IP Range response", e);
+        }
+    }
+
+    /**
+     * Return true if vlan IP range is dedicated for system vms (SSVM and CPVM), false if not
+     * @param vlanId vlan id
+     * @return true if VLAN IP range is dedicated to system vms
+     */
+    private boolean isForSystemVms(long vlanId){
+        SearchBuilder<IPAddressVO> sb = userIpAddressDao.createSearchBuilder();
+        sb.and("vlanId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
+        SearchCriteria<IPAddressVO> sc = sb.create();
+        sc.setParameters("vlanId", vlanId);
+        IPAddressVO userIpAddresVO = userIpAddressDao.findOneBy(sc);
+        return userIpAddresVO.isForSystemVms();
+    }
+
+    @Override
+    public IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddr) {
+        VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId());
+        boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork);
+        long zoneId = ipAddr.getDataCenterId();
+
+        IPAddressResponse ipResponse = new IPAddressResponse();
+        ipResponse.setId(ipAddr.getUuid());
+        ipResponse.setIpAddress(ipAddr.getAddress().toString());
+        if (ipAddr.getAllocatedTime() != null) {
+            ipResponse.setAllocated(ipAddr.getAllocatedTime());
+        }
+        DataCenter zone = ApiDBUtils.findZoneById(ipAddr.getDataCenterId());
+        if (zone != null) {
+            ipResponse.setZoneId(zone.getUuid());
+            ipResponse.setZoneName(zone.getName());
+        }
+        ipResponse.setSourceNat(ipAddr.isSourceNat());
+        ipResponse.setIsSystem(ipAddr.getSystem());
+
+        // get account information
+        if (ipAddr.getAllocatedToAccountId() != null) {
+            populateOwner(ipResponse, ipAddr);
+        }
+
+        ipResponse.setForVirtualNetwork(forVirtualNetworks);
+        ipResponse.setStaticNat(ipAddr.isOneToOneNat());
+
+        if (ipAddr.getAssociatedWithVmId() != null) {
+            UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId());
+            if (vm != null) {
+                ipResponse.setVirtualMachineId(vm.getUuid());
+                ipResponse.setVirtualMachineName(vm.getHostName());
+                if (vm.getDisplayName() != null) {
+                    ipResponse.setVirtualMachineDisplayName(vm.getDisplayName());
+                } else {
+                    ipResponse.setVirtualMachineDisplayName(vm.getHostName());
+                }
+            }
+        }
+        if (ipAddr.getVmIp() != null) {
+            ipResponse.setVirtualMachineIp(ipAddr.getVmIp());
+        }
+
+        if (ipAddr.getAssociatedWithNetworkId() != null) {
+            Network ntwk = ApiDBUtils.findNetworkById(ipAddr.getAssociatedWithNetworkId());
+            if (ntwk != null) {
+                ipResponse.setAssociatedNetworkId(ntwk.getUuid());
+                ipResponse.setAssociatedNetworkName(ntwk.getName());
+            }
+        }
+
+        if (ipAddr.getVpcId() != null) {
+            Vpc vpc = ApiDBUtils.findVpcById(ipAddr.getVpcId());
+            if (vpc != null) {
+                ipResponse.setVpcId(vpc.getUuid());
+            }
+        }
+
+        // Network id the ip is associated with (if associated networkId is
+        // null, try to get this information from vlan)
+        Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId());
+
+        // Network id the ip belongs to
+        Long networkId;
+        if (vlanNetworkId != null) {
+            networkId = vlanNetworkId;
+        } else {
+            networkId = ApiDBUtils.getPublicNetworkIdByZone(zoneId);
+        }
+
+        if (networkId != null) {
+            NetworkVO nw = ApiDBUtils.findNetworkById(networkId);
+            if (nw != null) {
+                ipResponse.setNetworkId(nw.getUuid());
+            }
+        }
+        ipResponse.setState(ipAddr.getState().toString());
+
+        if (ipAddr.getPhysicalNetworkId() != null) {
+            PhysicalNetworkVO pnw = ApiDBUtils.findPhysicalNetworkById(ipAddr.getPhysicalNetworkId());
+            if (pnw != null) {
+                ipResponse.setPhysicalNetworkId(pnw.getUuid());
+            }
+        }
+
+        // show this info to full view only
+        if (view == ResponseView.Full) {
+            VlanVO vl = ApiDBUtils.findVlanById(ipAddr.getVlanId());
+            if (vl != null) {
+                ipResponse.setVlanId(vl.getUuid());
+                ipResponse.setVlanName(vl.getVlanTag());
+            }
+        }
+
+        if (ipAddr.getSystem()) {
+            if (ipAddr.isOneToOneNat()) {
+                ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString());
+            } else {
+                ipResponse.setPurpose(IpAddress.Purpose.Lb.toString());
+            }
+        }
+
+        ipResponse.setForDisplay(ipAddr.isDisplay());
+
+        ipResponse.setPortable(ipAddr.isPortable());
+
+        //set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PublicIpAddress, ipAddr.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        ipResponse.setTags(tagResponses);
+
+        ipResponse.setObjectName("ipaddress");
+        return ipResponse;
+    }
+
+    @Override
+    public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer) {
+        LoadBalancerResponse lbResponse = new LoadBalancerResponse();
+        lbResponse.setId(loadBalancer.getUuid());
+        lbResponse.setName(loadBalancer.getName());
+        lbResponse.setDescription(loadBalancer.getDescription());
+        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(loadBalancer.getId());
+        lbResponse.setCidrList(StringUtils.join(cidrs, ","));
+
+        IPAddressVO publicIp = ApiDBUtils.findIpAddressById(loadBalancer.getSourceIpAddressId());
+        lbResponse.setPublicIpId(publicIp.getUuid());
+        lbResponse.setPublicIp(publicIp.getAddress().addr());
+        lbResponse.setPublicPort(Integer.toString(loadBalancer.getSourcePortStart()));
+        lbResponse.setPrivatePort(Integer.toString(loadBalancer.getDefaultPortStart()));
+        lbResponse.setAlgorithm(loadBalancer.getAlgorithm());
+        lbResponse.setLbProtocol(loadBalancer.getLbProtocol());
+        lbResponse.setForDisplay(loadBalancer.isDisplay());
+        FirewallRule.State state = loadBalancer.getState();
+        String stateToSet = state.toString();
+        if (state.equals(FirewallRule.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+        lbResponse.setState(stateToSet);
+        populateOwner(lbResponse, loadBalancer);
+        DataCenter zone = ApiDBUtils.findZoneById(publicIp.getDataCenterId());
+        if (zone != null) {
+            lbResponse.setZoneId(zone.getUuid());
+            lbResponse.setZoneName(zone.getName());
+        }
+
+        //set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, loadBalancer.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        lbResponse.setTags(tagResponses);
+
+        Network ntwk = ApiDBUtils.findNetworkById(loadBalancer.getNetworkId());
+        lbResponse.setNetworkId(ntwk.getUuid());
+
+        lbResponse.setObjectName("loadbalancer");
+        return lbResponse;
+    }
+
+    @Override
+    public GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule) {
+        GlobalLoadBalancerResponse response = new GlobalLoadBalancerResponse();
+        response.setAlgorithm(globalLoadBalancerRule.getAlgorithm());
+        response.setStickyMethod(globalLoadBalancerRule.getPersistence());
+        response.setServiceType(globalLoadBalancerRule.getServiceType());
+        response.setServiceDomainName(globalLoadBalancerRule.getGslbDomain() + "." + ApiDBUtils.getDnsNameConfiguredForGslb());
+        response.setName(globalLoadBalancerRule.getName());
+        response.setDescription(globalLoadBalancerRule.getDescription());
+        response.setRegionIdId(globalLoadBalancerRule.getRegion());
+        response.setId(globalLoadBalancerRule.getUuid());
+        populateOwner(response, globalLoadBalancerRule);
+        response.setObjectName("globalloadbalancer");
+
+        List<LoadBalancerResponse> siteLbResponses = new ArrayList<LoadBalancerResponse>();
+        List<? extends LoadBalancer> siteLoadBalaners = ApiDBUtils.listSiteLoadBalancers(globalLoadBalancerRule.getId());
+        for (LoadBalancer siteLb : siteLoadBalaners) {
+            LoadBalancerResponse siteLbResponse = createLoadBalancerResponse(siteLb);
+            siteLbResponses.add(siteLbResponse);
+        }
+        response.setSiteLoadBalancers(siteLbResponses);
+        return response;
+    }
+
+    @Override
+    public PodResponse createPodResponse(Pod pod, Boolean showCapacities) {
+        String[] ipRange = new String[2];
+        List<String> startIp = new ArrayList<String>();
+        List<String> endIp = new ArrayList<String>();
+        List<String> forSystemVms = new ArrayList<String>();
+        List<String> vlanIds = new ArrayList<String>();
+
+        if (pod.getDescription() != null && pod.getDescription().length() > 0) {
+            final String[] existingPodIpRanges = pod.getDescription().split(",");
+
+            for(String podIpRange: existingPodIpRanges) {
+                final String[] existingPodIpRange = podIpRange.split("-");
+
+                startIp.add(((existingPodIpRange.length > 0) && (existingPodIpRange[0] != null)) ? existingPodIpRange[0] : "");
+                endIp.add(((existingPodIpRange.length > 1) && (existingPodIpRange[1] != null)) ? existingPodIpRange[1] : "");
+                forSystemVms.add((existingPodIpRange.length > 2) && (existingPodIpRange[2] != null) ? existingPodIpRange[2] : "0");
+                vlanIds.add((existingPodIpRange.length > 3) &&
+                        (existingPodIpRange[3] != null && !existingPodIpRange[3].equals("untagged")) ?
+                        BroadcastDomainType.Vlan.toUri(existingPodIpRange[3]).toString() :
+                        BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString());
+            }
+        }
+
+        PodResponse podResponse = new PodResponse();
+        podResponse.setId(pod.getUuid());
+        podResponse.setName(pod.getName());
+        DataCenter zone = ApiDBUtils.findZoneById(pod.getDataCenterId());
+        if (zone != null) {
+            podResponse.setZoneId(zone.getUuid());
+            podResponse.setZoneName(zone.getName());
+        }
+        podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize()));
+        podResponse.setStartIp(startIp);
+        podResponse.setEndIp(endIp);
+        podResponse.setForSystemVms(forSystemVms);
+        podResponse.setVlanId(vlanIds);
+        podResponse.setGateway(pod.getGateway());
+        podResponse.setAllocationState(pod.getAllocationState().toString());
+        if (showCapacities != null && showCapacities) {
+            List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, pod.getId(), null);
+            Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
+            for (SummedCapacity capacity : capacities) {
+                CapacityResponse capacityResponse = new CapacityResponse();
+                capacityResponse.setCapacityType(capacity.getCapacityType());
+                capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
+                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
+                if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
+                    List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null);
+                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
+                    capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
+                } else {
+                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
+                }
+                if (capacityResponse.getCapacityTotal() != 0) {
+                    capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
+                } else {
+                    capacityResponse.setPercentUsed(s_percentFormat.format(0L));
+                }
+                capacityResponses.add(capacityResponse);
+            }
+            // Do it for stats as well.
+            capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId()));
+            podResponse.setCapacitites(new ArrayList<CapacityResponse>(capacityResponses));
+        }
+        podResponse.setObjectName("pod");
+        return podResponse;
+    }
+
+    @Override
+    public ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities) {
+        DataCenterJoinVO vOffering = ApiDBUtils.newDataCenterView(dataCenter);
+        return ApiDBUtils.newDataCenterResponse(view, vOffering, showCapacities);
+    }
+
+    public static List<CapacityResponse> getDataCenterCapacityResponse(Long zoneId) {
+        List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null);
+        Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
+
+        for (SummedCapacity capacity : capacities) {
+            CapacityResponse capacityResponse = new CapacityResponse();
+            capacityResponse.setCapacityType(capacity.getCapacityType());
+            capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
+            capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
+            if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
+                List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null);
+                capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
+                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
+            } else {
+                capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
+            }
+            if (capacityResponse.getCapacityTotal() != 0) {
+                capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
+            } else {
+                capacityResponse.setPercentUsed(s_percentFormat.format(0L));
+            }
+            capacityResponses.add(capacityResponse);
+        }
+        // Do it for stats as well.
+        capacityResponses.addAll(getStatsCapacityresponse(null, null, null, zoneId));
+
+        return new ArrayList<CapacityResponse>(capacityResponses);
+    }
+
+    private static List<CapacityResponse> getStatsCapacityresponse(Long poolId, Long clusterId, Long podId, Long zoneId) {
+        List<CapacityVO> capacities = new ArrayList<CapacityVO>();
+        capacities.add(ApiDBUtils.getStoragePoolUsedStats(poolId, clusterId, podId, zoneId));
+        if (clusterId == null && podId == null) {
+            capacities.add(ApiDBUtils.getSecondaryStorageUsedStats(poolId, zoneId));
+        }
+
+        List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
+        for (CapacityVO capacity : capacities) {
+            CapacityResponse capacityResponse = new CapacityResponse();
+            capacityResponse.setCapacityType(capacity.getCapacityType());
+            capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
+            capacityResponse.setCapacityUsed(capacity.getUsedCapacity());
+            capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
+            if (capacityResponse.getCapacityTotal() != 0) {
+                capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
+            } else {
+                capacityResponse.setPercentUsed(s_percentFormat.format(0L));
+            }
+            capacityResponses.add(capacityResponse);
+        }
+
+        return capacityResponses;
+    }
+
+    @Override
+    public VolumeResponse createVolumeResponse(ResponseView view, Volume volume) {
+        List<VolumeJoinVO> viewVrs = ApiDBUtils.newVolumeView(volume);
+        List<VolumeResponse> listVrs = ViewResponseHelper.createVolumeResponse(view, viewVrs.toArray(new VolumeJoinVO[viewVrs.size()]));
+        assert listVrs != null && listVrs.size() == 1 : "There should be one volume returned";
+        return listVrs.get(0);
+    }
+
+    @Override
+    public InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group) {
+        InstanceGroupJoinVO vgroup = ApiDBUtils.newInstanceGroupView(group);
+        return ApiDBUtils.newInstanceGroupResponse(vgroup);
+
+    }
+
+    @Override
+    public StoragePoolResponse createStoragePoolResponse(StoragePool pool) {
+        List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
+        List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
+        assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
+        return listPools.get(0);
+    }
+
+    @Override
+    public ImageStoreResponse createImageStoreResponse(ImageStore os) {
+        List<ImageStoreJoinVO> viewStores = ApiDBUtils.newImageStoreView(os);
+        List<ImageStoreResponse> listStores = ViewResponseHelper.createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()]));
+        assert listStores != null && listStores.size() == 1 : "There should be one image data store returned";
+        return listStores.get(0);
+    }
+
+    @Override
+    public StoragePoolResponse createStoragePoolForMigrationResponse(StoragePool pool) {
+        List<StoragePoolJoinVO> viewPools = ApiDBUtils.newStoragePoolView(pool);
+        List<StoragePoolResponse> listPools = ViewResponseHelper.createStoragePoolForMigrationResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()]));
+        assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned";
+        return listPools.get(0);
+    }
+
+    @Override
+    public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) {
+        ClusterResponse clusterResponse = new ClusterResponse();
+        clusterResponse.setId(cluster.getUuid());
+        clusterResponse.setName(cluster.getName());
+        HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
+        if (pod != null) {
+            clusterResponse.setPodId(pod.getUuid());
+            clusterResponse.setPodName(pod.getName());
+        }
+        DataCenter dc = ApiDBUtils.findZoneById(cluster.getDataCenterId());
+        if (dc != null) {
+            clusterResponse.setZoneId(dc.getUuid());
+            clusterResponse.setZoneName(dc.getName());
+        }
+        clusterResponse.setHypervisorType(cluster.getHypervisorType().toString());
+        clusterResponse.setClusterType(cluster.getClusterType().toString());
+        clusterResponse.setAllocationState(cluster.getAllocationState().toString());
+        clusterResponse.setManagedState(cluster.getManagedState().toString());
+        String cpuOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "cpuOvercommitRatio");
+        String memoryOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "memoryOvercommitRatio");
+        clusterResponse.setCpuOvercommitRatio(cpuOvercommitRatio);
+        clusterResponse.setMemoryOvercommitRatio(memoryOvercommitRatio);
+        clusterResponse.setResourceDetails(_clusterDetailsDao.findDetails(cluster.getId()));
+
+        if (showCapacities != null && showCapacities) {
+            List<SummedCapacity> capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId());
+            Set<CapacityResponse> capacityResponses = new HashSet<CapacityResponse>();
+
+            for (SummedCapacity capacity : capacities) {
+                CapacityResponse capacityResponse = new CapacityResponse();
+                capacityResponse.setCapacityType(capacity.getCapacityType());
+                capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType()));
+                capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity());
+
+                if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) {
+                    List<SummedCapacity> c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId());
+                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity());
+                    capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity());
+                } else {
+                    capacityResponse.setCapacityTotal(capacity.getTotalCapacity());
+                }
+                if (capacityResponse.getCapacityTotal() != 0) {
+                    capacityResponse.setPercentUsed(s_percentFormat.format((float)capacityResponse.getCapacityUsed() / (float)capacityResponse.getCapacityTotal() * 100f));
+                } else {
+                    capacityResponse.setPercentUsed(s_percentFormat.format(0L));
+                }
+                capacityResponses.add(capacityResponse);
+            }
+            // Do it for stats as well.
+            capacityResponses.addAll(getStatsCapacityresponse(null, cluster.getId(), pod.getId(), pod.getDataCenterId()));
+            clusterResponse.setCapacitites(new ArrayList<CapacityResponse>(capacityResponses));
+        }
+        clusterResponse.setObjectName("cluster");
+        return clusterResponse;
+    }
+
+    @Override
+    public FirewallRuleResponse createPortForwardingRuleResponse(PortForwardingRule fwRule) {
+        FirewallRuleResponse response = new FirewallRuleResponse();
+        response.setId(fwRule.getUuid());
+        response.setPrivateStartPort(Integer.toString(fwRule.getDestinationPortStart()));
+        response.setPrivateEndPort(Integer.toString(fwRule.getDestinationPortEnd()));
+        response.setProtocol(fwRule.getProtocol());
+        response.setPublicStartPort(Integer.toString(fwRule.getSourcePortStart()));
+        response.setPublicEndPort(Integer.toString(fwRule.getSourcePortEnd()));
+        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
+        response.setCidrList(StringUtils.join(cidrs, ","));
+
+        Network guestNtwk = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
+        response.setNetworkId(guestNtwk.getUuid());
+
+
+        IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
+
+        if (ip != null)
+        {
+            response.setPublicIpAddressId(ip.getUuid());
+            response.setPublicIpAddress(ip.getAddress().addr());
+            if (fwRule.getDestinationIpAddress() != null)
+            {
+                response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString());
+                UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId());
+                if (vm != null) {
+                    response.setVirtualMachineId(vm.getUuid());
+                    response.setVirtualMachineName(vm.getHostName());
+
+                    if (vm.getDisplayName() != null) {
+                        response.setVirtualMachineDisplayName(vm.getDisplayName());
+                    } else {
+                        response.setVirtualMachineDisplayName(vm.getHostName());
+                    }
+                }
+            }
+        }
+        FirewallRule.State state = fwRule.getState();
+        String stateToSet = state.toString();
+        if (state.equals(FirewallRule.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.PortForwardingRule, fwRule.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        response.setTags(tagResponses);
+
+        response.setState(stateToSet);
+        response.setForDisplay(fwRule.isDisplay());
+        response.setObjectName("portforwardingrule");
+        return response;
+    }
+
+    @Override
+    public IpForwardingRuleResponse createIpForwardingRuleResponse(StaticNatRule fwRule) {
+        IpForwardingRuleResponse response = new IpForwardingRuleResponse();
+        response.setId(fwRule.getUuid());
+        response.setProtocol(fwRule.getProtocol());
+
+        IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
+
+        if (ip != null) {
+            response.setPublicIpAddressId(ip.getId());
+            response.setPublicIpAddress(ip.getAddress().addr());
+            if (fwRule.getDestIpAddress() != null) {
+                UserVm vm = ApiDBUtils.findUserVmById(ip.getAssociatedWithVmId());
+                if (vm != null) {// vm might be destroyed
+                    response.setVirtualMachineId(vm.getUuid());
+                    response.setVirtualMachineName(vm.getHostName());
+                    if (vm.getDisplayName() != null) {
+                        response.setVirtualMachineDisplayName(vm.getDisplayName());
+                    } else {
+                        response.setVirtualMachineDisplayName(vm.getHostName());
+                    }
+                }
+            }
+        }
+        FirewallRule.State state = fwRule.getState();
+        String stateToSet = state.toString();
+        if (state.equals(FirewallRule.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+
+        response.setStartPort(fwRule.getSourcePortStart());
+        response.setEndPort(fwRule.getSourcePortEnd());
+        response.setProtocol(fwRule.getProtocol());
+        response.setState(stateToSet);
+        response.setObjectName("ipforwardingrule");
+        return response;
+    }
+
+    /*
+    @Override
+    public List<UserVmResponse> createUserVmResponse(String objectName, UserVm... userVms) {
+        return createUserVmResponse(null, objectName, userVms);
+    }
+
+    @Override
+    public List<UserVmResponse> createUserVmResponse(String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
+        return createUserVmResponse(null, objectName, userVms);
+    }
+    */
+
+    @Override
+    public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, EnumSet<VMDetails> details, UserVm... userVms) {
+        List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
+        return ViewResponseHelper.createUserVmResponse(view, objectName, details, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
+
+    }
+
+    @Override
+    public List<UserVmResponse> createUserVmResponse(ResponseView view, String objectName, UserVm... userVms) {
+        List<UserVmJoinVO> viewVms = ApiDBUtils.newUserVmView(userVms);
+        return ViewResponseHelper.createUserVmResponse(view, objectName, viewVms.toArray(new UserVmJoinVO[viewVms.size()]));
+    }
+
+    @Override
+    public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) {
+        List<DomainRouterJoinVO> viewVrs = ApiDBUtils.newDomainRouterView(router);
+        List<DomainRouterResponse> listVrs = ViewResponseHelper.createDomainRouterResponse(viewVrs.toArray(new DomainRouterJoinVO[viewVrs.size()]));
+        assert listVrs != null && listVrs.size() == 1 : "There should be one virtual router returned";
+        return listVrs.get(0);
+    }
+
+    @Override
+    public SystemVmResponse createSystemVmResponse(VirtualMachine vm) {
+        SystemVmResponse vmResponse = new SystemVmResponse();
+        if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter || vm.getType() == Type.NetScalerVm) {
+            vmResponse.setId(vm.getUuid());
+            vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
+            vmResponse.setName(vm.getHostName());
+
+            if (vm.getPodIdToDeployIn() != null) {
+                HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn());
+                if (pod != null) {
+                    vmResponse.setPodId(pod.getUuid());
+                }
+            }
+            VMTemplateVO template = ApiDBUtils.findTemplateById(vm.getTemplateId());
+            if (template != null) {
+                vmResponse.setTemplateId(template.getUuid());
+            }
+            vmResponse.setCreated(vm.getCreated());
+
+            if (vm.getHostId() != null) {
+                Host host = ApiDBUtils.findHostById(vm.getHostId());
+                if (host != null) {
+                    vmResponse.setHostId(host.getUuid());
+                    vmResponse.setHostName(host.getName());
+                    vmResponse.setHypervisor(host.getHypervisorType().toString());
+                }
+            }
+
+            if (vm.getState() != null) {
+                vmResponse.setState(vm.getState().toString());
+            }
+
+            // for console proxies, add the active sessions
+            if (vm.getType() == Type.ConsoleProxy) {
+                ConsoleProxyVO proxy = ApiDBUtils.findConsoleProxy(vm.getId());
+                // proxy can be already destroyed
+                if (proxy != null) {
+                    vmResponse.setActiveViewerSessions(proxy.getActiveSession());
+                }
+            }
+
+            DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterId());
+            if (zone != null) {
+                vmResponse.setZoneId(zone.getUuid());
+                vmResponse.setZoneName(zone.getName());
+                vmResponse.setDns1(zone.getDns1());
+                vmResponse.setDns2(zone.getDns2());
+            }
+
+            List<NicProfile> nicProfiles = ApiDBUtils.getNics(vm);
+            for (NicProfile singleNicProfile : nicProfiles) {
+                Network network = ApiDBUtils.findNetworkById(singleNicProfile.getNetworkId());
+                if (network != null) {
+                    if (network.getTrafficType() == TrafficType.Management) {
+                        vmResponse.setPrivateIp(singleNicProfile.getIPv4Address());
+                        vmResponse.setPrivateMacAddress(singleNicProfile.getMacAddress());
+                        vmResponse.setPrivateNetmask(singleNicProfile.getIPv4Netmask());
+                    } else if (network.getTrafficType() == TrafficType.Control) {
+                        vmResponse.setLinkLocalIp(singleNicProfile.getIPv4Address());
+                        vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress());
+                        vmResponse.setLinkLocalNetmask(singleNicProfile.getIPv4Netmask());
+                    } else if (network.getTrafficType() == TrafficType.Public) {
+                        vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
+                        vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
+                        vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
+                        vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
+                    } else if (network.getTrafficType() == TrafficType.Guest) {
+                        /*
+                          * In basic zone, public ip has TrafficType.Guest in case EIP service is not enabled.
+                          * When EIP service is enabled in the basic zone, system VM by default get the public
+                          * IP allocated for EIP. So return the guest/public IP accordingly.
+                          * */
+                        NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
+                        if (networkOffering.isElasticIp()) {
+                            IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(vm.getId());
+                            if (ip != null) {
+                                Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId());
+                                vmResponse.setPublicIp(ip.getAddress().addr());
+                                vmResponse.setPublicNetmask(vlan.getVlanNetmask());
+                                vmResponse.setGateway(vlan.getVlanGateway());
+                            }
+                        } else {
+                            vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
+                            vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
+                            vmResponse.setPublicNetmask(singleNicProfile.getIPv4Netmask());
+                            vmResponse.setGateway(singleNicProfile.getIPv4Gateway());
+                        }
+                    }
+                }
+            }
+        }
+        vmResponse.setObjectName("systemvm");
+        return vmResponse;
+    }
+
+    @Override
+    public Host findHostById(Long hostId) {
+        return ApiDBUtils.findHostById(hostId);
+    }
+
+    @Override
+    public User findUserById(Long userId) {
+        return ApiDBUtils.findUserById(userId);
+    }
+
+    @Override
+    public UserVm findUserVmById(Long vmId) {
+        return ApiDBUtils.findUserVmById(vmId);
+
+    }
+
+    @Override
+    public VolumeVO findVolumeById(Long volumeId) {
+        return ApiDBUtils.findVolumeById(volumeId);
+    }
+
+
+    @Override
+    public Account findAccountByNameDomain(String accountName, Long domainId) {
+        return ApiDBUtils.findAccountByNameDomain(accountName, domainId);
+    }
+
+    @Override
+    public VirtualMachineTemplate findTemplateById(Long templateId) {
+        return ApiDBUtils.findTemplateById(templateId);
+    }
+
+    @Override
+    public DiskOfferingVO findDiskOfferingById(Long diskOfferingId) {
+        return ApiDBUtils.findDiskOfferingById(diskOfferingId);
+    }
+
+    @Override
+    public VpnUsersResponse createVpnUserResponse(VpnUser vpnUser) {
+        VpnUsersResponse vpnResponse = new VpnUsersResponse();
+        vpnResponse.setId(vpnUser.getUuid());
+        vpnResponse.setUserName(vpnUser.getUsername());
+        vpnResponse.setState(vpnUser.getState().toString());
+
+        populateOwner(vpnResponse, vpnUser);
+
+        vpnResponse.setObjectName("vpnuser");
+        return vpnResponse;
+    }
+
+    @Override
+    public RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn) {
+        RemoteAccessVpnResponse vpnResponse = new RemoteAccessVpnResponse();
+        IpAddress ip = ApiDBUtils.findIpAddressById(vpn.getServerAddressId());
+        if (ip != null) {
+            vpnResponse.setPublicIpId(ip.getUuid());
+            vpnResponse.setPublicIp(ip.getAddress().addr());
+        }
+        vpnResponse.setIpRange(vpn.getIpRange());
+        vpnResponse.setPresharedKey(vpn.getIpsecPresharedKey());
+        populateOwner(vpnResponse, vpn);
+        vpnResponse.setState(vpn.getState().toString());
+        vpnResponse.setId(vpn.getUuid());
+        vpnResponse.setForDisplay(vpn.isDisplay());
+        vpnResponse.setObjectName("remoteaccessvpn");
+
+        return vpnResponse;
+    }
+
+    @Override
+    public TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result) {
+        List<TemplateJoinVO> tvo = ApiDBUtils.newTemplateView(result);
+        List<TemplateResponse> listVrs = ViewResponseHelper.createTemplateUpdateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+        assert listVrs != null && listVrs.size() == 1 : "There should be one template returned";
+        return listVrs.get(0);
+    }
+
+    @Override
+    public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
+        List<TemplateJoinVO> tvo = null;
+        if (zoneId == null || zoneId == -1 || result.isCrossZones()) {
+            tvo = ApiDBUtils.newTemplateView(result);
+        } else {
+            tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
+
+        }
+        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+    }
+
+    @Override
+    public List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
+                                                          List<Long> zoneIds, boolean readyOnly) {
+        List<TemplateJoinVO> tvo = null;
+        if (zoneIds == null) {
+            return createTemplateResponses(view, result, (Long)null, readyOnly);
+        } else {
+            for (Long zoneId: zoneIds){
+                if (tvo == null)
+                    tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
+                else
+                    tvo.addAll(ApiDBUtils.newTemplateView(result, zoneId, readyOnly));
+            }
+        }
+        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+    }
+
+    @Override
+    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly) {
+        VirtualMachineTemplate template = findTemplateById(templateId);
+        return createTemplateResponses(view, template, zoneId, readyOnly);
+    }
+
+    @Override
+    public List<TemplateResponse> createIsoResponses(ResponseView view, VirtualMachineTemplate result, Long zoneId, boolean readyOnly) {
+        List<TemplateJoinVO> tvo = null;
+        if (zoneId == null || zoneId == -1) {
+            tvo = ApiDBUtils.newTemplateView(result);
+        } else {
+            tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
+        }
+
+        return ViewResponseHelper.createIsoResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+    }
+
+    @Override
+    public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) {
+        List<SecurityGroupJoinVO> viewSgs = ApiDBUtils.newSecurityGroupView(group);
+        List<SecurityGroupResponse> listSgs = ViewResponseHelper.createSecurityGroupResponses(viewSgs);
+        assert listSgs != null && listSgs.size() == 1 : "There should be one security group returned";
+        return listSgs.get(0);
+    }
+
+    //TODO: we need to deprecate uploadVO, since extract is done in a synchronous fashion
+    @Override
+    public ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) {
+
+        ExtractResponse response = new ExtractResponse();
+        response.setObjectName("template");
+        VMTemplateVO template = ApiDBUtils.findTemplateById(id);
+        response.setId(template.getUuid());
+        response.setName(template.getName());
+        if (zoneId != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(zoneId);
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+        response.setMode(mode);
+        response.setUrl(url);
+        response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
+        Account account = ApiDBUtils.findAccountById(accountId);
+        response.setAccountId(account.getUuid());
+
+        return response;
+    }
+
+    @Override
+    public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) {
+
+        ExtractResponse response = new ExtractResponse();
+        response.setObjectName("template");
+        VMTemplateVO template = ApiDBUtils.findTemplateById(id);
+        response.setId(template.getUuid());
+        response.setName(template.getName());
+        if (zoneId != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(zoneId);
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+        response.setMode(mode);
+        if (uploadId == null) {
+            // region-wide image store
+            response.setUrl(url);
+            response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString());
+        } else {
+            UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId);
+            response.setUploadId(uploadInfo.getUuid());
+            response.setState(uploadInfo.getUploadState().toString());
+            response.setUrl(uploadInfo.getUploadUrl());
+        }
+        Account account = ApiDBUtils.findAccountById(accountId);
+        response.setAccountId(account.getUuid());
+
+        return response;
+
+    }
+
+    @Override
+    public String toSerializedString(CreateCmdResponse response, String responseType) {
+        return ApiResponseSerializer.toSerializedString(response, responseType);
+    }
+
+    @Override
+    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly) {
+        Long zoneId = null;
+
+        if (snapshotId != null) {
+            Snapshot snapshot = ApiDBUtils.findSnapshotById(snapshotId);
+            VolumeVO volume = findVolumeById(snapshot.getVolumeId());
+
+            // it seems that the volume can actually be removed from the DB at some point if it's deleted
+            // if volume comes back null, use another technique to try to discover the zone
+            if (volume == null) {
+                SnapshotDataStoreVO snapshotStore = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+                if (snapshotStore != null) {
+                    long storagePoolId = snapshotStore.getDataStoreId();
+
+                    StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
+
+                    if (storagePool != null) {
+                        zoneId = storagePool.getDataCenterId();
+                    }
+                }
+            }
+            else {
+                zoneId = volume.getDataCenterId();
+            }
+        } else {
+            VolumeVO volume = findVolumeById(volumeId);
+
+            zoneId = volume.getDataCenterId();
+        }
+
+        if (zoneId == null) {
+            throw new CloudRuntimeException("Unable to determine the zone ID");
+        }
+
+        return createTemplateResponses(view, templateId, zoneId, readyOnly);
+    }
+
+    @Override
+    public List<TemplateResponse> createTemplateResponses(ResponseView view, long templateId, Long vmId) {
+        UserVm vm = findUserVmById(vmId);
+        Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId());
+        Host host = findHostById(hostId);
+        return createTemplateResponses(view, templateId, host.getDataCenterId(), true);
+    }
+
+    @Override
+    public EventResponse createEventResponse(Event event) {
+        EventJoinVO vEvent = ApiDBUtils.newEventView(event);
+        return ApiDBUtils.newEventResponse(vEvent);
+    }
+
+    @Override
+    public List<CapacityResponse> createCapacityResponse(List<? extends Capacity> result, DecimalFormat format) {
+        List<CapacityResponse> capacityResponses = new ArrayList<CapacityResponse>();
+
+        for (Capacity summedCapacity : result) {
+            CapacityResponse capacityResponse = new CapacityResponse();
+            capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity());
+            if (summedCapacity.getAllocatedCapacity() != null) {
+                capacityResponse.setCapacityAllocated(summedCapacity.getAllocatedCapacity());
+            }
+            capacityResponse.setCapacityType(summedCapacity.getCapacityType());
+            capacityResponse.setCapacityName(CapacityVO.getCapacityName(summedCapacity.getCapacityType()));
+            capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity());
+            if (summedCapacity.getPodId() != null) {
+                capacityResponse.setPodId(ApiDBUtils.findPodById(summedCapacity.getPodId()).getUuid());
+                HostPodVO pod = ApiDBUtils.findPodById(summedCapacity.getPodId());
+                if (pod != null) {
+                    capacityResponse.setPodId(pod.getUuid());
+                    capacityResponse.setPodName(pod.getName());
+                }
+            }
+            if (summedCapacity.getClusterId() != null) {
+                ClusterVO cluster = ApiDBUtils.findClusterById(summedCapacity.getClusterId());
+                if (cluster != null) {
+                    capacityResponse.setClusterId(cluster.getUuid());
+                    capacityResponse.setClusterName(cluster.getName());
+                    if (summedCapacity.getPodId() == null) {
+                        HostPodVO pod = ApiDBUtils.findPodById(cluster.getPodId());
+                        capacityResponse.setPodId(pod.getUuid());
+                        capacityResponse.setPodName(pod.getName());
+                    }
+                }
+            }
+            DataCenter zone = ApiDBUtils.findZoneById(summedCapacity.getDataCenterId());
+            if (zone != null) {
+                capacityResponse.setZoneId(zone.getUuid());
+                capacityResponse.setZoneName(zone.getName());
+            }
+            if (summedCapacity.getUsedPercentage() != null) {
+                capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f));
+            } else if (summedCapacity.getTotalCapacity() != 0) {
+                capacityResponse.setPercentUsed(format.format((float)summedCapacity.getUsedCapacity() / (float)summedCapacity.getTotalCapacity() * 100f));
+            } else {
+                capacityResponse.setPercentUsed(format.format(0L));
+            }
+
+            capacityResponse.setObjectName("capacity");
+            capacityResponses.add(capacityResponse);
+        }
+
+        List<VgpuTypesInfo> gpuCapacities;
+        if (result.size() > 1 && (gpuCapacities = ApiDBUtils.getGpuCapacites(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId())) != null) {
+            HashMap<String, Long> vgpuVMs = ApiDBUtils.getVgpuVmsCount(result.get(0).getDataCenterId(), result.get(0).getPodId(), result.get(0).getClusterId());
+
+            float capacityUsed = 0;
+            long capacityMax = 0;
+            for (VgpuTypesInfo capacity : gpuCapacities) {
+                if (vgpuVMs.containsKey(capacity.getGroupName().concat(capacity.getModelName()))) {
+                    capacityUsed += (float)vgpuVMs.get(capacity.getGroupName().concat(capacity.getModelName())) / capacity.getMaxVpuPerGpu();
+                }
+                if (capacity.getModelName().equals(GPU.GPUType.passthrough.toString())) {
+                    capacityMax += capacity.getMaxCapacity();
+                }
+            }
+
+            DataCenter zone = ApiDBUtils.findZoneById(result.get(0).getDataCenterId());
+            CapacityResponse capacityResponse = new CapacityResponse();
+            if (zone != null) {
+                capacityResponse.setZoneId(zone.getUuid());
+                capacityResponse.setZoneName(zone.getName());
+            }
+            if (result.get(0).getPodId() != null) {
+                HostPodVO pod = ApiDBUtils.findPodById(result.get(0).getPodId());
+                capacityResponse.setPodId(pod.getUuid());
+                capacityResponse.setPodName(pod.getName());
+            }
+            if (result.get(0).getClusterId() != null) {
+                ClusterVO cluster = ApiDBUtils.findClusterById(result.get(0).getClusterId());
+                capacityResponse.setClusterId(cluster.getUuid());
+                capacityResponse.setClusterName(cluster.getName());
+            }
+            capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU);
+            capacityResponse.setCapacityName(CapacityVO.getCapacityName(Capacity.CAPACITY_TYPE_GPU));
+            capacityResponse.setCapacityUsed((long)Math.ceil(capacityUsed));
+            capacityResponse.setCapacityTotal(capacityMax);
+            if (capacityMax > 0) {
+                capacityResponse.setPercentUsed(format.format(capacityUsed / capacityMax * 100f));
+            } else {
+                capacityResponse.setPercentUsed(format.format(0));
+            }
+            capacityResponse.setObjectName("capacity");
+            capacityResponses.add(capacityResponse);
+        }
+        return capacityResponses;
+    }
+
+    @Override
+    public TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List<String> accountNames, Long id) {
+        Long templateOwnerDomain = null;
+        VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id);
+        Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId());
+        if (view == ResponseView.Full) {
+            // FIXME: we have just template id and need to get template owner
+            // from that
+            if (templateOwner != null) {
+                templateOwnerDomain = templateOwner.getDomainId();
+            }
+        }
+
+        TemplatePermissionsResponse response = new TemplatePermissionsResponse();
+        response.setId(template.getUuid());
+        response.setPublicTemplate(template.isPublicTemplate());
+        if ((view == ResponseView.Full) && (templateOwnerDomain != null)) {
+            Domain domain = ApiDBUtils.findDomainById(templateOwnerDomain);
+            if (domain != null) {
+                response.setDomainId(domain.getUuid());
+            }
+        }
+
+        // Set accounts
+        List<String> projectIds = new ArrayList<String>();
+        List<String> regularAccounts = new ArrayList<String>();
+        for (String accountName : accountNames) {
+            Account account = ApiDBUtils.findAccountByNameDomain(accountName, templateOwner.getDomainId());
+            if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
+                regularAccounts.add(accountName);
+            } else {
+                // convert account to projectIds
+                Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
+
+                if (project.getUuid() != null && !project.getUuid().isEmpty()) {
+                    projectIds.add(project.getUuid());
+                } else {
+                    projectIds.add(String.valueOf(project.getId()));
+                }
+            }
+        }
+
+        if (!projectIds.isEmpty()) {
+            response.setProjectIds(projectIds);
+        }
+
+        if (!regularAccounts.isEmpty()) {
+            response.setAccountNames(regularAccounts);
+        }
+
+        response.setObjectName("templatepermission");
+        return response;
+    }
+
+    @Override
+    public AsyncJobResponse queryJobResult(final QueryAsyncJobResultCmd cmd) {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final AsyncJob job = _entityMgr.findByIdIncludingRemoved(AsyncJob.class, cmd.getId());
+        if (job == null) {
+            throw new InvalidParameterValueException("Unable to find a job by id " + cmd.getId());
+        }
+
+        final User userJobOwner = _accountMgr.getUserIncludingRemoved(job.getUserId());
+        final Account jobOwner = _accountMgr.getAccount(userJobOwner.getAccountId());
+
+        //check permissions
+        if (_accountMgr.isNormalUser(caller.getId())) {
+            //regular user can see only jobs he owns
+            if (caller.getId() != jobOwner.getId()) {
+                throw new PermissionDeniedException("Account " + caller + " is not authorized to see job id=" + job.getId());
+            }
+        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
+            _accountMgr.checkAccess(caller, null, true, jobOwner);
+        }
+
+        return createAsyncJobResponse(_jobMgr.queryJob(cmd.getId(), true));
+    }
+
+    public AsyncJobResponse createAsyncJobResponse(AsyncJob job) {
+        AsyncJobJoinVO vJob = ApiDBUtils.newAsyncJobView(job);
+        return ApiDBUtils.newAsyncJobResponse(vJob);
+    }
+
+    @Override
+    public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List<? extends SecurityRule> securityRules) {
+        SecurityGroupResponse response = new SecurityGroupResponse();
+        Map<Long, Account> securiytGroupAccounts = new HashMap<Long, Account>();
+
+        if ((securityRules != null) && !securityRules.isEmpty()) {
+            SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0);
+            response.setId(securityGroup.getUuid());
+            response.setName(securityGroup.getName());
+            response.setDescription(securityGroup.getDescription());
+
+            Account account = securiytGroupAccounts.get(securityGroup.getAccountId());
+
+            if (securityGroup.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
+                response.setProjectId(securityGroup.getProjectUuid());
+                response.setProjectName(securityGroup.getProjectName());
+            } else {
+                response.setAccountName(securityGroup.getAccountName());
+            }
+
+            response.setDomainId(securityGroup.getDomainUuid());
+            response.setDomainName(securityGroup.getDomainName());
+
+            for (SecurityRule securityRule : securityRules) {
+                SecurityGroupRuleResponse securityGroupData = new SecurityGroupRuleResponse();
+
+                securityGroupData.setRuleId(securityRule.getUuid());
+                securityGroupData.setProtocol(securityRule.getProtocol());
+                if ("icmp".equalsIgnoreCase(securityRule.getProtocol())) {
+                    securityGroupData.setIcmpType(securityRule.getStartPort());
+                    securityGroupData.setIcmpCode(securityRule.getEndPort());
+                } else {
+                    securityGroupData.setStartPort(securityRule.getStartPort());
+                    securityGroupData.setEndPort(securityRule.getEndPort());
+                }
+
+                Long allowedSecurityGroupId = securityRule.getAllowedNetworkId();
+                if (allowedSecurityGroupId != null) {
+                    List<SecurityGroupJoinVO> sgs = ApiDBUtils.findSecurityGroupViewById(allowedSecurityGroupId);
+                    if (sgs != null && sgs.size() > 0) {
+                        SecurityGroupJoinVO sg = sgs.get(0);
+                        securityGroupData.setSecurityGroupName(sg.getName());
+                        securityGroupData.setAccountName(sg.getAccountName());
+                    }
+                } else {
+                    securityGroupData.setCidr(securityRule.getAllowedSourceIpCidr());
+                }
+                if (securityRule.getRuleType() == SecurityRuleType.IngressRule) {
+                    securityGroupData.setObjectName("ingressrule");
+                    response.addSecurityGroupIngressRule(securityGroupData);
+                } else {
+                    securityGroupData.setObjectName("egressrule");
+                    response.addSecurityGroupEgressRule(securityGroupData);
+                }
+
+            }
+            response.setObjectName("securitygroup");
+
+        }
+        return response;
+    }
+
+    @Override
+    public NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering) {
+        NetworkOfferingResponse response = new NetworkOfferingResponse();
+        response.setId(offering.getUuid());
+        response.setName(offering.getName());
+        response.setDisplayText(offering.getDisplayText());
+        response.setTags(offering.getTags());
+        response.setTrafficType(offering.getTrafficType().toString());
+        response.setIsDefault(offering.isDefault());
+        response.setSpecifyVlan(offering.isSpecifyVlan());
+        response.setConserveMode(offering.isConserveMode());
+        response.setSpecifyIpRanges(offering.isSpecifyIpRanges());
+        response.setAvailability(offering.getAvailability().toString());
+        response.setIsPersistent(offering.isPersistent());
+        response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
+        response.setEgressDefaultPolicy(offering.isEgressDefaultPolicy());
+        response.setConcurrentConnections(offering.getConcurrentConnections());
+        response.setSupportsStrechedL2Subnet(offering.isSupportingStrechedL2());
+        response.setSupportsPublicAccess(offering.isSupportingPublicAccess());
+        Long so = null;
+        if (offering.getServiceOfferingId() != null) {
+            so = offering.getServiceOfferingId();
+        } else {
+            so = ApiDBUtils.findDefaultRouterServiceOffering();
+        }
+        if (so != null) {
+            ServiceOffering soffering = ApiDBUtils.findServiceOfferingById(so);
+            if (soffering != null) {
+                response.setServiceOfferingId(soffering.getUuid());
+            }
+        }
+
+        if (offering.getGuestType() != null) {
+            response.setGuestIpType(offering.getGuestType().toString());
+        }
+
+        response.setState(offering.getState().name());
+
+        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(offering.getId());
+        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
+        for (Map.Entry<Service,Set<Provider>> entry : serviceProviderMap.entrySet()) {
+            Service service = entry.getKey();
+            Set<Provider> srvc_providers = entry.getValue();
+            ServiceResponse svcRsp = new ServiceResponse();
+            // skip gateway service
+            if (service == Service.Gateway) {
+                continue;
+            }
+            svcRsp.setName(service.getName());
+            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
+            for (Provider provider : srvc_providers) {
+                if (provider != null) {
+                    ProviderResponse providerRsp = new ProviderResponse();
+                    providerRsp.setName(provider.getName());
+                    providers.add(providerRsp);
+                }
+            }
+            svcRsp.setProviders(providers);
+
+            if (Service.Lb == service) {
+                List<CapabilityResponse> lbCapResponse = new ArrayList<CapabilityResponse>();
+
+                CapabilityResponse lbIsoaltion = new CapabilityResponse();
+                lbIsoaltion.setName(Capability.SupportedLBIsolation.getName());
+                lbIsoaltion.setValue(offering.isDedicatedLB() ? "dedicated" : "shared");
+                lbCapResponse.add(lbIsoaltion);
+
+                CapabilityResponse eLb = new CapabilityResponse();
+                eLb.setName(Capability.ElasticLb.getName());
+                eLb.setValue(offering.isElasticLb() ? "true" : "false");
+                lbCapResponse.add(eLb);
+
+                CapabilityResponse inline = new CapabilityResponse();
+                inline.setName(Capability.InlineMode.getName());
+                inline.setValue(offering.isInline() ? "true" : "false");
+                lbCapResponse.add(inline);
+
+                svcRsp.setCapabilities(lbCapResponse);
+            } else if (Service.SourceNat == service) {
+                List<CapabilityResponse> capabilities = new ArrayList<CapabilityResponse>();
+                CapabilityResponse sharedSourceNat = new CapabilityResponse();
+                sharedSourceNat.setName(Capability.SupportedSourceNatTypes.getName());
+                sharedSourceNat.setValue(offering.isSharedSourceNat() ? "perzone" : "peraccount");
+                capabilities.add(sharedSourceNat);
+
+                CapabilityResponse redundantRouter = new CapabilityResponse();
+                redundantRouter.setName(Capability.RedundantRouter.getName());
+                redundantRouter.setValue(offering.isRedundantRouter() ? "true" : "false");
+                capabilities.add(redundantRouter);
+
+                svcRsp.setCapabilities(capabilities);
+            } else if (service == Service.StaticNat) {
+                List<CapabilityResponse> staticNatCapResponse = new ArrayList<CapabilityResponse>();
+
+                CapabilityResponse eIp = new CapabilityResponse();
+                eIp.setName(Capability.ElasticIp.getName());
+                eIp.setValue(offering.isElasticIp() ? "true" : "false");
+                staticNatCapResponse.add(eIp);
+
+                CapabilityResponse associatePublicIp = new CapabilityResponse();
+                associatePublicIp.setName(Capability.AssociatePublicIP.getName());
+                associatePublicIp.setValue(offering.isAssociatePublicIP() ? "true" : "false");
+                staticNatCapResponse.add(associatePublicIp);
+
+                svcRsp.setCapabilities(staticNatCapResponse);
+            }
+
+            serviceResponses.add(svcRsp);
+        }
+        response.setForVpc(_configMgr.isOfferingForVpc(offering));
+
+        response.setServices(serviceResponses);
+
+        //set network offering details
+        Map<Detail, String> details = _ntwkModel.getNtwkOffDetails(offering.getId());
+        if (details != null && !details.isEmpty()) {
+            response.setDetails(details);
+        }
+
+        response.setObjectName("networkoffering");
+        return response;
+    }
+
+    @Override
+    public NetworkResponse createNetworkResponse(ResponseView view, Network network) {
+        // need to get network profile in order to retrieve dns information from
+        // there
+        NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId());
+        NetworkResponse response = new NetworkResponse();
+        response.setId(network.getUuid());
+        response.setName(network.getName());
+        response.setDisplaytext(network.getDisplayText());
+        if (network.getBroadcastDomainType() != null) {
+            response.setBroadcastDomainType(network.getBroadcastDomainType().toString());
+        }
+
+        if (network.getTrafficType() != null) {
+            response.setTrafficType(network.getTrafficType().name());
+        }
+
+        if (network.getGuestType() != null) {
+            response.setType(network.getGuestType().toString());
+        }
+
+        response.setGateway(network.getGateway());
+
+        // FIXME - either set netmask or cidr
+        response.setCidr(network.getCidr());
+        if (network.getNetworkCidr() != null) {
+            response.setNetworkCidr((network.getNetworkCidr()));
+        }
+        // If network has reservation its entire network cidr is defined by
+        // getNetworkCidr()
+        // if no reservation is present then getCidr() will define the entire
+        // network cidr
+        if (network.getNetworkCidr() != null) {
+            response.setNetmask(NetUtils.cidr2Netmask(network.getNetworkCidr()));
+        }
+        if (((network.getCidr()) != null) && (network.getNetworkCidr() == null)) {
+            response.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
+        }
+
+        response.setIp6Gateway(network.getIp6Gateway());
+        response.setIp6Cidr(network.getIp6Cidr());
+
+        // create response for reserved IP ranges that can be used for
+        // non-cloudstack purposes
+        String reservation = null;
+        if ((network.getCidr() != null) && (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr()))) {
+            String[] guestVmCidrPair = network.getCidr().split("\\/");
+            String[] guestCidrPair = network.getNetworkCidr().split("\\/");
+
+            Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]);
+            Long guestCidrSize = Long.valueOf(guestCidrPair[1]);
+
+            String[] guestVmIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], guestVmCidrSize);
+            String[] guestIpRange = NetUtils.getIpRangeFromCidr(guestCidrPair[0], guestCidrSize);
+            long startGuestIp = NetUtils.ip2Long(guestIpRange[0]);
+            long endGuestIp = NetUtils.ip2Long(guestIpRange[1]);
+            long startVmIp = NetUtils.ip2Long(guestVmIpRange[0]);
+            long endVmIp = NetUtils.ip2Long(guestVmIpRange[1]);
+
+            if (startVmIp == startGuestIp && endVmIp < endGuestIp - 1) {
+                reservation = (NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
+            }
+            if (endVmIp == endGuestIp && startVmIp > startGuestIp + 1) {
+                reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1));
+            }
+            if (startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) {
+                reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " ,  " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp));
+            }
+        }
+        response.setReservedIpRange(reservation);
+
+        // return vlan information only to Root admin
+        if (network.getBroadcastUri() != null && view == ResponseView.Full) {
+            String broadcastUri = network.getBroadcastUri().toString();
+            response.setBroadcastUri(broadcastUri);
+            String vlan = "N/A";
+            switch (BroadcastDomainType.getSchemeValue(network.getBroadcastUri())) {
+            case Vlan:
+            case Vxlan:
+                vlan = BroadcastDomainType.getValue(network.getBroadcastUri());
+                break;
+            }
+            // return vlan information only to Root admin
+            response.setVlan(vlan);
+        }
+
+        DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId());
+        if (zone != null) {
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+        if (network.getPhysicalNetworkId() != null) {
+            PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId());
+            response.setPhysicalNetworkId(pnet.getUuid());
+        }
+
+        // populate network offering information
+        NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
+        if (networkOffering != null) {
+            response.setNetworkOfferingId(networkOffering.getUuid());
+            response.setNetworkOfferingName(networkOffering.getName());
+            response.setNetworkOfferingDisplayText(networkOffering.getDisplayText());
+            response.setNetworkOfferingConserveMode(networkOffering.isConserveMode());
+            response.setIsSystem(networkOffering.isSystemOnly());
+            response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString());
+            response.setIsPersistent(networkOffering.isPersistent());
+        }
+
+        if (network.getAclType() != null) {
+            response.setAclType(network.getAclType().toString());
+        }
+        response.setDisplayNetwork(network.getDisplayNetwork());
+        response.setState(network.getState().toString());
+        response.setRestartRequired(network.isRestartRequired());
+        NetworkVO nw = ApiDBUtils.findNetworkById(network.getRelated());
+        if (nw != null) {
+            response.setRelated(nw.getUuid());
+        }
+        response.setNetworkDomain(network.getNetworkDomain());
+
+        response.setDns1(profile.getDns1());
+        response.setDns2(profile.getDns2());
+        // populate capability
+        Map<Service, Map<Capability, String>> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId());
+        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
+        if (serviceCapabilitiesMap != null) {
+            for (Map.Entry<Service, Map<Capability, String>>entry : serviceCapabilitiesMap.entrySet()) {
+                Service service = entry.getKey();
+                ServiceResponse serviceResponse = new ServiceResponse();
+                // skip gateway service
+                if (service == Service.Gateway) {
+                    continue;
+                }
+                serviceResponse.setName(service.getName());
+
+                // set list of capabilities for the service
+                List<CapabilityResponse> capabilityResponses = new ArrayList<CapabilityResponse>();
+                Map<Capability, String> serviceCapabilities = entry.getValue();
+                if (serviceCapabilities != null) {
+                    for (Map.Entry<Capability,String> ser_cap_entries : serviceCapabilities.entrySet()) {
+                        Capability capability = ser_cap_entries.getKey();
+                        CapabilityResponse capabilityResponse = new CapabilityResponse();
+                        String capabilityValue = ser_cap_entries.getValue();
+                        capabilityResponse.setName(capability.getName());
+                        capabilityResponse.setValue(capabilityValue);
+                        capabilityResponse.setObjectName("capability");
+                        capabilityResponses.add(capabilityResponse);
+                    }
+                    serviceResponse.setCapabilities(capabilityResponses);
+                }
+
+                serviceResponse.setObjectName("service");
+                serviceResponses.add(serviceResponse);
+            }
+        }
+        response.setServices(serviceResponses);
+
+        if (network.getAclType() == null || network.getAclType() == ACLType.Account) {
+            populateOwner(response, network);
+        } else {
+            // get domain from network_domain table
+            Pair<Long, Boolean> domainNetworkDetails = ApiDBUtils.getDomainNetworkDetails(network.getId());
+            if (domainNetworkDetails.first() != null) {
+                Domain domain = ApiDBUtils.findDomainById(domainNetworkDetails.first());
+                if (domain != null) {
+                    response.setDomainId(domain.getUuid());
+                }
+            }
+            response.setSubdomainAccess(domainNetworkDetails.second());
+        }
+
+        Long dedicatedDomainId = ApiDBUtils.getDedicatedNetworkDomain(network.getId());
+        if (dedicatedDomainId != null) {
+            Domain domain = ApiDBUtils.findDomainById(dedicatedDomainId);
+            if (domain != null) {
+                response.setDomainId(domain.getUuid());
+                response.setDomainName(domain.getName());
+            }
+
+        }
+
+        response.setSpecifyIpRanges(network.getSpecifyIpRanges());
+        if (network.getVpcId() != null) {
+            Vpc vpc = ApiDBUtils.findVpcById(network.getVpcId());
+            if (vpc != null) {
+                response.setVpcId(vpc.getUuid());
+            }
+        }
+        response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network));
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Network, network.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        response.setTags(tagResponses);
+
+        if (network.getNetworkACLId() != null) {
+            NetworkACL acl = ApiDBUtils.findByNetworkACLId(network.getNetworkACLId());
+            if (acl != null) {
+                response.setAclId(acl.getUuid());
+            }
+        }
+
+        response.setStrechedL2Subnet(network.isStrechedL2Network());
+        if (network.isStrechedL2Network()) {
+            Set<String> networkSpannedZones = new  HashSet<String>();
+            List<VMInstanceVO> vmInstances = new ArrayList<VMInstanceVO>();
+            vmInstances.addAll(ApiDBUtils.listUserVMsByNetworkId(network.getId()));
+            vmInstances.addAll(ApiDBUtils.listDomainRoutersByNetworkId(network.getId()));
+            for (VirtualMachine vm : vmInstances) {
+                DataCenter vmZone = ApiDBUtils.findZoneById(vm.getDataCenterId());
+                networkSpannedZones.add(vmZone.getUuid());
+            }
+            response.setNetworkSpannedZones(networkSpannedZones);
+        }
+        response.setExternalId(network.getExternalId());
+        response.setRedundantRouter(network.isRedundant());
+        response.setObjectName("network");
+        return response;
+    }
+
+    @Override
+    public Long getSecurityGroupId(String groupName, long accountId) {
+        SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId);
+        if (sg == null) {
+            return null;
+        } else {
+            return sg.getId();
+        }
+    }
+
+    @Override
+    public ProjectResponse createProjectResponse(Project project) {
+        List<ProjectJoinVO> viewPrjs = ApiDBUtils.newProjectView(project);
+        List<ProjectResponse> listPrjs = ViewResponseHelper.createProjectResponse(viewPrjs.toArray(new ProjectJoinVO[viewPrjs.size()]));
+        assert listPrjs != null && listPrjs.size() == 1 : "There should be one project  returned";
+        return listPrjs.get(0);
+    }
+
+    @Override
+    public FirewallResponse createFirewallResponse(FirewallRule fwRule) {
+        FirewallResponse response = new FirewallResponse();
+
+        response.setId(fwRule.getUuid());
+        response.setProtocol(fwRule.getProtocol());
+        if (fwRule.getSourcePortStart() != null) {
+            response.setStartPort(fwRule.getSourcePortStart());
+        }
+
+        if (fwRule.getSourcePortEnd() != null) {
+            response.setEndPort(fwRule.getSourcePortEnd());
+        }
+
+        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
+        response.setCidrList(StringUtils.join(cidrs, ","));
+
+        if(fwRule.getTrafficType() == FirewallRule.TrafficType.Egress){
+            List<String> destCidrs = ApiDBUtils.findFirewallDestCidrs(fwRule.getId());
+            response.setDestCidr(StringUtils.join(destCidrs,","));
+        }
+
+        if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) {
+            IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
+            response.setPublicIpAddressId(ip.getUuid());
+            response.setPublicIpAddress(ip.getAddress().addr());
+        }
+
+            Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
+            response.setNetworkId(network.getUuid());
+
+        FirewallRule.State state = fwRule.getState();
+        String stateToSet = state.toString();
+        if (state.equals(FirewallRule.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+
+        response.setIcmpCode(fwRule.getIcmpCode());
+        response.setIcmpType(fwRule.getIcmpType());
+        response.setForDisplay(fwRule.isDisplay());
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        response.setTags(tagResponses);
+
+        response.setState(stateToSet);
+        response.setObjectName("firewallrule");
+        return response;
+    }
+
+    @Override
+    public NetworkACLItemResponse createNetworkACLItemResponse(NetworkACLItem aclItem) {
+        NetworkACLItemResponse response = new NetworkACLItemResponse();
+
+        response.setId(aclItem.getUuid());
+        response.setProtocol(aclItem.getProtocol());
+        if (aclItem.getSourcePortStart() != null) {
+            response.setStartPort(Integer.toString(aclItem.getSourcePortStart()));
+        }
+
+        if (aclItem.getSourcePortEnd() != null) {
+            response.setEndPort(Integer.toString(aclItem.getSourcePortEnd()));
+        }
+
+        response.setCidrList(StringUtils.join(aclItem.getSourceCidrList(), ","));
+
+        response.setTrafficType(aclItem.getTrafficType().toString());
+
+        NetworkACLItem.State state = aclItem.getState();
+        String stateToSet = state.toString();
+        if (state.equals(NetworkACLItem.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+
+        response.setIcmpCode(aclItem.getIcmpCode());
+        response.setIcmpType(aclItem.getIcmpType());
+
+        response.setState(stateToSet);
+        response.setNumber(aclItem.getNumber());
+        response.setAction(aclItem.getAction().toString());
+        response.setForDisplay(aclItem.isDisplay());
+
+        NetworkACL acl = ApiDBUtils.findByNetworkACLId(aclItem.getAclId());
+        if (acl != null) {
+            response.setAclId(acl.getUuid());
+        }
+
+        //set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.NetworkACL, aclItem.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        response.setTags(tagResponses);
+        response.setReason(aclItem.getReason());
+        response.setObjectName("networkacl");
+        return response;
+    }
+
+    @Override
+    public HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities) {
+        HypervisorCapabilitiesResponse hpvCapabilitiesResponse = new HypervisorCapabilitiesResponse();
+        hpvCapabilitiesResponse.setId(hpvCapabilities.getUuid());
+        hpvCapabilitiesResponse.setHypervisor(hpvCapabilities.getHypervisorType());
+        hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion());
+        hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled());
+        hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit());
+        hpvCapabilitiesResponse.setMaxDataVolumesLimit(hpvCapabilities.getMaxDataVolumesLimit());
+        hpvCapabilitiesResponse.setMaxHostsPerCluster(hpvCapabilities.getMaxHostsPerCluster());
+        hpvCapabilitiesResponse.setIsStorageMotionSupported(hpvCapabilities.isStorageMotionSupported());
+        return hpvCapabilitiesResponse;
+    }
+
+    // TODO: we may need to refactor once ControlledEntityResponse and
+    // ControlledEntity id to uuid conversion are all done.
+    // currently code is scattered in
+    private void populateOwner(ControlledEntityResponse response, ControlledEntity object) {
+        Account account = ApiDBUtils.findAccountById(object.getAccountId());
+
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            // find the project
+            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
+            response.setProjectId(project.getUuid());
+            response.setProjectName(project.getName());
+        } else {
+            response.setAccountName(account.getAccountName());
+        }
+
+        Domain domain = ApiDBUtils.findDomainById(object.getDomainId());
+        response.setDomainId(domain.getUuid());
+        response.setDomainName(domain.getName());
+    }
+
+    public static void populateOwner(ControlledViewEntityResponse response, ControlledViewEntity object) {
+
+        if (object.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
+            response.setProjectId(object.getProjectUuid());
+            response.setProjectName(object.getProjectName());
+        } else {
+            response.setAccountName(object.getAccountName());
+        }
+
+        response.setDomainId(object.getDomainUuid());
+        response.setDomainName(object.getDomainName());
+    }
+
+    private void populateAccount(ControlledEntityResponse response, long accountId) {
+        Account account = ApiDBUtils.findAccountById(accountId);
+        if (account == null) {
+            s_logger.debug("Unable to find account with id: " + accountId);
+        } else if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            // find the project
+            Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
+            if (project != null) {
+                response.setProjectId(project.getUuid());
+                response.setProjectName(project.getName());
+                response.setAccountName(account.getAccountName());
+            } else {
+                s_logger.debug("Unable to find project with id: " + account.getId());
+            }
+        } else {
+            response.setAccountName(account.getAccountName());
+        }
+    }
+
+    private void populateDomain(ControlledEntityResponse response, long domainId) {
+        Domain domain = ApiDBUtils.findDomainById(domainId);
+
+        response.setDomainId(domain.getUuid());
+        response.setDomainName(domain.getName());
+    }
+
+    @Override
+    public ProjectAccountResponse createProjectAccountResponse(ProjectAccount projectAccount) {
+        ProjectAccountJoinVO vProj = ApiDBUtils.newProjectAccountView(projectAccount);
+        List<ProjectAccountResponse> listProjs = ViewResponseHelper.createProjectAccountResponse(vProj);
+        assert listProjs != null && listProjs.size() == 1 : "There should be one project account returned";
+        return listProjs.get(0);
+    }
+
+    @Override
+    public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) {
+        ProjectInvitationJoinVO vInvite = ApiDBUtils.newProjectInvitationView(invite);
+        return ApiDBUtils.newProjectInvitationResponse(vInvite);
+    }
+
+    @Override
+    public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) {
+        SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse();
+        vmResponse.setId(vm.getUuid());
+        vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
+        vmResponse.setName(vm.getHostName());
+        if (vm.getHostId() != null) {
+            Host host = ApiDBUtils.findHostById(vm.getHostId());
+            if (host != null) {
+                vmResponse.setHostId(host.getUuid());
+            }
+        }
+        if (vm.getState() != null) {
+            vmResponse.setState(vm.getState().toString());
+        }
+        if (vm.getType() == Type.DomainRouter) {
+            VirtualRouter router = (VirtualRouter)vm;
+            if (router.getRole() != null) {
+                vmResponse.setRole(router.getRole().toString());
+            }
+        }
+        vmResponse.setObjectName("systemvminstance");
+        return vmResponse;
+    }
+
+    @Override
+    public PhysicalNetworkResponse createPhysicalNetworkResponse(PhysicalNetwork result) {
+        PhysicalNetworkResponse response = new PhysicalNetworkResponse();
+
+        DataCenter zone = ApiDBUtils.findZoneById(result.getDataCenterId());
+        if (zone != null) {
+            response.setZoneId(zone.getUuid());
+        }
+        response.setNetworkSpeed(result.getSpeed());
+        response.setVlan(result.getVnetString());
+        if (result.getDomainId() != null) {
+            Domain domain = ApiDBUtils.findDomainById(result.getDomainId());
+            if (domain != null) {
+                response.setDomainId(domain.getUuid());
+            }
+        }
+        response.setId(result.getUuid());
+        if (result.getBroadcastDomainRange() != null) {
+            response.setBroadcastDomainRange(result.getBroadcastDomainRange().toString());
+        }
+        response.setIsolationMethods(result.getIsolationMethods());
+        response.setTags(result.getTags());
+        if (result.getState() != null) {
+            response.setState(result.getState().toString());
+        }
+
+        response.setName(result.getName());
+
+        response.setObjectName("physicalnetwork");
+        return response;
+    }
+
+    @Override
+    public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan vlan) {
+        GuestVlanRangeResponse guestVlanRangeResponse = new GuestVlanRangeResponse();
+
+        guestVlanRangeResponse.setId(vlan.getUuid());
+        Long accountId = ApiDBUtils.getAccountIdForGuestVlan(vlan.getId());
+        Account owner = ApiDBUtils.findAccountById(accountId);
+        if (owner != null) {
+            populateAccount(guestVlanRangeResponse, owner.getId());
+            populateDomain(guestVlanRangeResponse, owner.getDomainId());
+        }
+        guestVlanRangeResponse.setGuestVlanRange(vlan.getGuestVlanRange());
+        guestVlanRangeResponse.setPhysicalNetworkId(vlan.getPhysicalNetworkId());
+        PhysicalNetworkVO physicalNetwork = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
+        guestVlanRangeResponse.setZoneId(physicalNetwork.getDataCenterId());
+
+        return guestVlanRangeResponse;
+    }
+
+    @Override
+    public ServiceResponse createNetworkServiceResponse(Service service) {
+        ServiceResponse response = new ServiceResponse();
+        response.setName(service.getName());
+
+        // set list of capabilities required for the service
+        List<CapabilityResponse> capabilityResponses = new ArrayList<CapabilityResponse>();
+        Capability[] capabilities = service.getCapabilities();
+        for (Capability cap : capabilities) {
+            CapabilityResponse capabilityResponse = new CapabilityResponse();
+            capabilityResponse.setName(cap.getName());
+            capabilityResponse.setObjectName("capability");
+            if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName())
+                    || cap.getName().equals(Capability.RedundantRouter.getName())) {
+                capabilityResponse.setCanChoose(true);
+            } else {
+                capabilityResponse.setCanChoose(false);
+            }
+            capabilityResponses.add(capabilityResponse);
+        }
+        response.setCapabilities(capabilityResponses);
+
+        // set list of providers providing this service
+        List<? extends Network.Provider> serviceProviders = ApiDBUtils.getProvidersForService(service);
+        List<ProviderResponse> serviceProvidersResponses = new ArrayList<ProviderResponse>();
+        for (Network.Provider serviceProvider : serviceProviders) {
+            // return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
+            if (service == Service.Firewall
+                    && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp || serviceProvider == Provider.BigSwitchBcf)) {
+                continue;
+            }
+
+            ProviderResponse serviceProviderResponse = createServiceProviderResponse(serviceProvider);
+            serviceProvidersResponses.add(serviceProviderResponse);
+        }
+        response.setProviders(serviceProvidersResponses);
+
+        response.setObjectName("networkservice");
+        return response;
+
+    }
+
+    private ProviderResponse createServiceProviderResponse(Provider serviceProvider) {
+        ProviderResponse response = new ProviderResponse();
+        response.setName(serviceProvider.getName());
+        boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
+        response.setCanEnableIndividualServices(canEnableIndividualServices);
+        return response;
+    }
+
+    @Override
+    public ProviderResponse createNetworkServiceProviderResponse(PhysicalNetworkServiceProvider result) {
+        ProviderResponse response = new ProviderResponse();
+        response.setId(result.getUuid());
+        response.setName(result.getProviderName());
+        PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
+        if (pnw != null) {
+            response.setPhysicalNetworkId(pnw.getUuid());
+        }
+        PhysicalNetwork dnw = ApiDBUtils.findPhysicalNetworkById(result.getDestinationPhysicalNetworkId());
+        if (dnw != null) {
+            response.setDestinationPhysicalNetworkId(dnw.getUuid());
+        }
+        response.setState(result.getState().toString());
+
+        // set enabled services
+        List<String> services = new ArrayList<String>();
+        for (Service service : result.getEnabledServices()) {
+            services.add(service.getName());
+        }
+        response.setServices(services);
+
+        Provider serviceProvider = Provider.getProvider(result.getProviderName());
+        boolean canEnableIndividualServices = ApiDBUtils.canElementEnableIndividualServices(serviceProvider);
+        response.setCanEnableIndividualServices(canEnableIndividualServices);
+
+        response.setObjectName("networkserviceprovider");
+        return response;
+    }
+
+    @Override
+    public TrafficTypeResponse createTrafficTypeResponse(PhysicalNetworkTrafficType result) {
+        TrafficTypeResponse response = new TrafficTypeResponse();
+        response.setId(result.getUuid());
+        PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
+        if (pnet != null) {
+            response.setPhysicalNetworkId(pnet.getUuid());
+        }
+        if (result.getTrafficType() != null) {
+            response.setTrafficType(result.getTrafficType().toString());
+        }
+
+        response.setXenLabel(result.getXenNetworkLabel());
+        response.setKvmLabel(result.getKvmNetworkLabel());
+        response.setVmwareLabel(result.getVmwareNetworkLabel());
+        response.setHypervLabel(result.getHypervNetworkLabel());
+        response.setOvm3Label(result.getOvm3NetworkLabel());
+
+        response.setObjectName("traffictype");
+        return response;
+    }
+
+    @Override
+    public VirtualRouterProviderResponse createVirtualRouterProviderResponse(VirtualRouterProvider result) {
+        //generate only response of the VR/VPCVR provider type
+        if (!(result.getType() == VirtualRouterProvider.Type.VirtualRouter || result.getType() == VirtualRouterProvider.Type.VPCVirtualRouter)) {
+            return null;
+        }
+        VirtualRouterProviderResponse response = new VirtualRouterProviderResponse();
+        response.setId(result.getUuid());
+        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
+        if (nsp != null) {
+            response.setNspId(nsp.getUuid());
+        }
+        response.setEnabled(result.isEnabled());
+
+        response.setObjectName("virtualrouterelement");
+        return response;
+    }
+
+    @Override
+    public OvsProviderResponse createOvsProviderResponse(OvsProvider result) {
+
+        OvsProviderResponse response = new OvsProviderResponse();
+        response.setId(result.getUuid());
+        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
+        if (nsp != null) {
+            response.setNspId(nsp.getUuid());
+        }
+        response.setEnabled(result.isEnabled());
+
+        response.setObjectName("ovselement");
+        return response;
+    }
+
+    @Override
+    public LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb) {
+        LBStickinessResponse spResponse = new LBStickinessResponse();
+
+        spResponse.setlbRuleId(lb.getUuid());
+        Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
+        if (accountTemp != null) {
+            spResponse.setAccountName(accountTemp.getAccountName());
+            Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
+            if (domain != null) {
+                spResponse.setDomainId(domain.getUuid());
+                spResponse.setDomainName(domain.getName());
+            }
+        }
+
+        List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
+        LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
+        responses.add(ruleResponse);
+
+        spResponse.setRules(responses);
+
+        spResponse.setObjectName("stickinesspolicies");
+        return spResponse;
+    }
+
+    @Override
+    public LBStickinessResponse createLBStickinessPolicyResponse(List<? extends StickinessPolicy> stickinessPolicies, LoadBalancer lb) {
+        LBStickinessResponse spResponse = new LBStickinessResponse();
+
+        if (lb == null) {
+            return spResponse;
+        }
+        spResponse.setlbRuleId(lb.getUuid());
+        Account account = ApiDBUtils.findAccountById(lb.getAccountId());
+        if (account != null) {
+            spResponse.setAccountName(account.getAccountName());
+            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
+            if (domain != null) {
+                spResponse.setDomainId(domain.getUuid());
+                spResponse.setDomainName(domain.getName());
+            }
+        }
+
+        List<LBStickinessPolicyResponse> responses = new ArrayList<LBStickinessPolicyResponse>();
+        for (StickinessPolicy stickinessPolicy : stickinessPolicies) {
+            LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy);
+            responses.add(ruleResponse);
+        }
+        spResponse.setRules(responses);
+
+        spResponse.setObjectName("stickinesspolicies");
+        return spResponse;
+    }
+
+    @Override
+    public LBHealthCheckResponse createLBHealthCheckPolicyResponse(List<? extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb) {
+        LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
+
+        if (lb == null) {
+            return hcResponse;
+        }
+        hcResponse.setlbRuleId(lb.getUuid());
+        Account account = ApiDBUtils.findAccountById(lb.getAccountId());
+        if (account != null) {
+            hcResponse.setAccountName(account.getAccountName());
+            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
+            if (domain != null) {
+                hcResponse.setDomainId(domain.getUuid());
+                hcResponse.setDomainName(domain.getName());
+            }
+        }
+
+        List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
+        for (HealthCheckPolicy healthcheckPolicy : healthcheckPolicies) {
+            LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
+            responses.add(ruleResponse);
+        }
+        hcResponse.setRules(responses);
+
+        hcResponse.setObjectName("healthcheckpolicies");
+        return hcResponse;
+    }
+
+    @Override
+    public LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb) {
+        LBHealthCheckResponse hcResponse = new LBHealthCheckResponse();
+
+        hcResponse.setlbRuleId(lb.getUuid());
+        Account accountTemp = ApiDBUtils.findAccountById(lb.getAccountId());
+        if (accountTemp != null) {
+            hcResponse.setAccountName(accountTemp.getAccountName());
+            Domain domain = ApiDBUtils.findDomainById(accountTemp.getDomainId());
+            if (domain != null) {
+                hcResponse.setDomainId(domain.getUuid());
+                hcResponse.setDomainName(domain.getName());
+            }
+        }
+
+        List<LBHealthCheckPolicyResponse> responses = new ArrayList<LBHealthCheckPolicyResponse>();
+        LBHealthCheckPolicyResponse ruleResponse = new LBHealthCheckPolicyResponse(healthcheckPolicy);
+        responses.add(ruleResponse);
+        hcResponse.setRules(responses);
+        hcResponse.setObjectName("healthcheckpolicies");
+        return hcResponse;
+    }
+
+    @Override
+    public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
+        StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
+        response.setUuid(result.getUuid());
+        response.setVlan(result.getVlan());
+        response.setEndIp(result.getEndIp());
+        response.setStartIp(result.getStartIp());
+        response.setPodUuid(result.getPodUuid());
+        response.setZoneUuid(result.getZoneUuid());
+        response.setNetworkUuid(result.getNetworkUuid());
+        response.setNetmask(result.getNetmask());
+        response.setGateway(result.getGateway());
+        response.setObjectName("storagenetworkiprange");
+        return response;
+    }
+
+    @Override
+    public RegionResponse createRegionResponse(Region region) {
+        RegionResponse response = new RegionResponse();
+        response.setId(region.getId());
+        response.setName(region.getName());
+        response.setEndPoint(region.getEndPoint());
+        response.setObjectName("region");
+        response.setGslbServiceEnabled(region.checkIfServiceEnabled(Region.Service.Gslb));
+        response.setPortableipServiceEnabled(region.checkIfServiceEnabled(Region.Service.PortableIp));
+        return response;
+    }
+
+    @Override
+    public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) {
+        ResourceTagJoinVO rto = ApiDBUtils.newResourceTagView(resourceTag);
+        if(rto == null)
+            return null;
+        return ApiDBUtils.newResourceTagResponse(rto, keyValueOnly);
+    }
+
+    @Override
+    public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) {
+        VpcOfferingResponse response = new VpcOfferingResponse();
+        response.setId(offering.getUuid());
+        response.setName(offering.getName());
+        response.setDisplayText(offering.getDisplayText());
+        response.setIsDefault(offering.isDefault());
+        response.setState(offering.getState().name());
+        response.setSupportsDistributedRouter(offering.supportsDistributedRouter());
+        response.setSupportsRegionLevelVpc(offering.offersRegionLevelVPC());
+
+        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
+        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
+        for (Map.Entry<Service, Set<Provider>> entry : serviceProviderMap.entrySet()) {
+            Service service = entry.getKey();
+            Set<Provider> srvc_providers = entry.getValue();
+
+            ServiceResponse svcRsp = new ServiceResponse();
+            // skip gateway service
+            if (service == Service.Gateway) {
+                continue;
+            }
+            svcRsp.setName(service.getName());
+            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
+            for (Provider provider : srvc_providers) {
+                if (provider != null) {
+                    ProviderResponse providerRsp = new ProviderResponse();
+                    providerRsp.setName(provider.getName());
+                    providers.add(providerRsp);
+                }
+            }
+            svcRsp.setProviders(providers);
+
+            serviceResponses.add(svcRsp);
+        }
+        response.setServices(serviceResponses);
+        response.setObjectName("vpcoffering");
+        return response;
+    }
+
+    @Override
+    public VpcResponse createVpcResponse(ResponseView view, Vpc vpc) {
+        VpcResponse response = new VpcResponse();
+        response.setId(vpc.getUuid());
+        response.setName(vpc.getName());
+        response.setDisplayText(vpc.getDisplayText());
+        response.setState(vpc.getState().name());
+        VpcOffering voff = ApiDBUtils.findVpcOfferingById(vpc.getVpcOfferingId());
+        if (voff != null) {
+            response.setVpcOfferingId(voff.getUuid());
+        }
+        response.setCidr(vpc.getCidr());
+        response.setRestartRequired(vpc.isRestartRequired());
+        response.setNetworkDomain(vpc.getNetworkDomain());
+        response.setForDisplay(vpc.isDisplay());
+        response.setUsesDistributedRouter(vpc.usesDistributedRouter());
+        response.setRedundantRouter(vpc.isRedundant());
+        response.setRegionLevelVpc(vpc.isRegionLevelVpc());
+
+        Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
+        List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
+        for (Map.Entry<Service,Set<Provider>>entry : serviceProviderMap.entrySet()) {
+            Service service = entry.getKey();
+            Set<Provider> serviceProviders = entry.getValue();
+            ServiceResponse svcRsp = new ServiceResponse();
+            // skip gateway service
+            if (service == Service.Gateway) {
+                continue;
+            }
+            svcRsp.setName(service.getName());
+            List<ProviderResponse> providers = new ArrayList<ProviderResponse>();
+            for (Provider provider : serviceProviders) {
+                if (provider != null) {
+                    ProviderResponse providerRsp = new ProviderResponse();
+                    providerRsp.setName(provider.getName());
+                    providers.add(providerRsp);
+                }
+            }
+            svcRsp.setProviders(providers);
+
+            serviceResponses.add(svcRsp);
+        }
+
+        List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
+        List<? extends Network> networks = ApiDBUtils.listVpcNetworks(vpc.getId());
+        for (Network network : networks) {
+            NetworkResponse ntwkRsp = createNetworkResponse(view, network);
+            networkResponses.add(ntwkRsp);
+        }
+
+        DataCenter zone = ApiDBUtils.findZoneById(vpc.getZoneId());
+        if (zone != null) {
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+
+        response.setNetworks(networkResponses);
+        response.setServices(serviceResponses);
+        populateOwner(response, vpc);
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.Vpc, vpc.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
+        }
+        response.setTags(tagResponses);
+        response.setObjectName("vpc");
+        return response;
+    }
+
+    @Override
+    public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) {
+        PrivateGatewayResponse response = new PrivateGatewayResponse();
+        response.setId(result.getUuid());
+        response.setBroadcastUri(result.getBroadcastUri());
+        response.setGateway(result.getGateway());
+        response.setNetmask(result.getNetmask());
+        if (result.getVpcId() != null) {
+            Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
+            response.setVpcId(vpc.getUuid());
+        }
+
+        DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId());
+        if (zone != null) {
+            response.setZoneId(zone.getUuid());
+            response.setZoneName(zone.getName());
+        }
+        response.setAddress(result.getIp4Address());
+        PhysicalNetwork pnet = ApiDBUtils.findPhysicalNetworkById(result.getPhysicalNetworkId());
+        if (pnet != null) {
+            response.setPhysicalNetworkId(pnet.getUuid());
+        }
+
+        populateAccount(response, result.getAccountId());
+        populateDomain(response, result.getDomainId());
+        response.setState(result.getState().toString());
+        response.setSourceNat(result.getSourceNat());
+
+        NetworkACL acl =  ApiDBUtils.findByNetworkACLId(result.getNetworkACLId());
+        if (acl != null) {
+            response.setAclId(acl.getUuid());
+        }
+
+        response.setObjectName("privategateway");
+
+        return response;
+    }
+
+    @Override
+    public CounterResponse createCounterResponse(Counter counter) {
+        CounterResponse response = new CounterResponse();
+        response.setId(counter.getUuid());
+        response.setSource(counter.getSource().toString());
+        response.setName(counter.getName());
+        response.setValue(counter.getValue());
+        response.setObjectName("counter");
+        return response;
+    }
+
+    @Override
+    public ConditionResponse createConditionResponse(Condition condition) {
+        ConditionResponse response = new ConditionResponse();
+        response.setId(condition.getUuid());
+        List<CounterResponse> counterResponseList = new ArrayList<CounterResponse>();
+        counterResponseList.add(createCounterResponse(ApiDBUtils.getCounter(condition.getCounterid())));
+        response.setCounterResponse(counterResponseList);
+        response.setRelationalOperator(condition.getRelationalOperator().toString());
+        response.setThreshold(condition.getThreshold());
+        response.setObjectName("condition");
+        populateOwner(response, condition);
+        return response;
+    }
+
+    @Override
+    public AutoScaleVmProfileResponse createAutoScaleVmProfileResponse(AutoScaleVmProfile profile) {
+        AutoScaleVmProfileResponse response = new AutoScaleVmProfileResponse();
+        response.setId(profile.getUuid());
+        if (profile.getZoneId() != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(profile.getZoneId());
+            if (zone != null) {
+                response.setZoneId(zone.getUuid());
+            }
+        }
+        if (profile.getServiceOfferingId() != null) {
+            ServiceOffering so = ApiDBUtils.findServiceOfferingById(profile.getServiceOfferingId());
+            if (so != null) {
+                response.setServiceOfferingId(so.getUuid());
+            }
+        }
+        if (profile.getTemplateId() != null) {
+            VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId());
+            if (template != null) {
+                response.setTemplateId(template.getUuid());
+            }
+        }
+        response.setOtherDeployParams(profile.getOtherDeployParams());
+        response.setCounterParams(profile.getCounterParams());
+        response.setDestroyVmGraceperiod(profile.getDestroyVmGraceperiod());
+        User user = ApiDBUtils.findUserById(profile.getAutoScaleUserId());
+        if (user != null) {
+            response.setAutoscaleUserId(user.getUuid());
+        }
+        response.setObjectName("autoscalevmprofile");
+
+        // Populates the account information in the response
+        populateOwner(response, profile);
+        return response;
+    }
+
+    @Override
+    public AutoScalePolicyResponse createAutoScalePolicyResponse(AutoScalePolicy policy) {
+        AutoScalePolicyResponse response = new AutoScalePolicyResponse();
+        response.setId(policy.getUuid());
+        response.setDuration(policy.getDuration());
+        response.setQuietTime(policy.getQuietTime());
+        response.setAction(policy.getAction());
+        List<ConditionVO> vos = ApiDBUtils.getAutoScalePolicyConditions(policy.getId());
+        ArrayList<ConditionResponse> conditions = new ArrayList<ConditionResponse>(vos.size());
+        for (ConditionVO vo : vos) {
+            conditions.add(createConditionResponse(vo));
+        }
+        response.setConditions(conditions);
+        response.setObjectName("autoscalepolicy");
+
+        // Populates the account information in the response
+        populateOwner(response, policy);
+
+        return response;
+    }
+
+    @Override
+    public AutoScaleVmGroupResponse createAutoScaleVmGroupResponse(AutoScaleVmGroup vmGroup) {
+        AutoScaleVmGroupResponse response = new AutoScaleVmGroupResponse();
+        response.setId(vmGroup.getUuid());
+        response.setMinMembers(vmGroup.getMinMembers());
+        response.setMaxMembers(vmGroup.getMaxMembers());
+        response.setState(vmGroup.getState());
+        response.setInterval(vmGroup.getInterval());
+        response.setForDisplay(vmGroup.isDisplay());
+        AutoScaleVmProfileVO profile = ApiDBUtils.findAutoScaleVmProfileById(vmGroup.getProfileId());
+        if (profile != null) {
+            response.setProfileId(profile.getUuid());
+        }
+        FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getLoadBalancerId());
+        if (fw != null) {
+            response.setLoadBalancerId(fw.getUuid());
+        }
+
+        List<AutoScalePolicyResponse> scaleUpPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
+        List<AutoScalePolicyResponse> scaleDownPoliciesResponse = new ArrayList<AutoScalePolicyResponse>();
+        response.setScaleUpPolicies(scaleUpPoliciesResponse);
+        response.setScaleDownPolicies(scaleDownPoliciesResponse);
+        response.setObjectName("autoscalevmgroup");
+
+        // Fetch policies for vmgroup
+        List<AutoScalePolicy> scaleUpPolicies = new ArrayList<AutoScalePolicy>();
+        List<AutoScalePolicy> scaleDownPolicies = new ArrayList<AutoScalePolicy>();
+        ApiDBUtils.getAutoScaleVmGroupPolicies(vmGroup.getId(), scaleUpPolicies, scaleDownPolicies);
+        // populate policies
+        for (AutoScalePolicy autoScalePolicy : scaleUpPolicies) {
+            scaleUpPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
+        }
+        for (AutoScalePolicy autoScalePolicy : scaleDownPolicies) {
+            scaleDownPoliciesResponse.add(createAutoScalePolicyResponse(autoScalePolicy));
+        }
+
+        return response;
+    }
+
+    @Override
+    public StaticRouteResponse createStaticRouteResponse(StaticRoute result) {
+        StaticRouteResponse response = new StaticRouteResponse();
+        response.setId(result.getUuid());
+        if (result.getVpcId() != null) {
+            Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
+            if (vpc != null) {
+                response.setVpcId(vpc.getUuid());
+            }
+        }
+        response.setCidr(result.getCidr());
+
+        StaticRoute.State state = result.getState();
+        if (state.equals(StaticRoute.State.Revoke)) {
+            state = StaticRoute.State.Deleting;
+        }
+        response.setState(state.toString());
+        populateAccount(response, result.getAccountId());
+        populateDomain(response, result.getDomainId());
+
+        // set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.StaticRoute, result.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
+        }
+        response.setTags(tagResponses);
+        response.setObjectName("staticroute");
+
+        return response;
+    }
+
+    @Override
+    public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) {
+        Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse();
+        response.setId(result.getUuid());
+        response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString());
+        Vpc vpc = ApiDBUtils.findVpcById(result.getVpcId());
+        if (vpc != null) {
+            response.setVpcId(vpc.getUuid());
+        }
+        response.setRemoved(result.getRemoved());
+        response.setForDisplay(result.isDisplay());
+        response.setObjectName("vpngateway");
+
+        populateAccount(response, result.getAccountId());
+        populateDomain(response, result.getDomainId());
+        return response;
+    }
+
+    @Override
+    public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) {
+        Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse();
+        response.setId(result.getUuid());
+        response.setName(result.getName());
+        response.setGatewayIp(result.getGatewayIp());
+        response.setGuestCidrList(result.getGuestCidrList());
+        response.setIpsecPsk(result.getIpsecPsk());
+        response.setIkePolicy(result.getIkePolicy());
+        response.setEspPolicy(result.getEspPolicy());
+        response.setIkeLifetime(result.getIkeLifetime());
+        response.setEspLifetime(result.getEspLifetime());
+        response.setDpd(result.getDpd());
+        response.setEncap(result.getEncap());
+        response.setRemoved(result.getRemoved());
+        response.setObjectName("vpncustomergateway");
+
+        populateAccount(response, result.getAccountId());
+        populateDomain(response, result.getDomainId());
+
+        return response;
+    }
+
+    @Override
+    public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) {
+        Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse();
+        response.setId(result.getUuid());
+        response.setPassive(result.isPassive());
+
+        Long vpnGatewayId = result.getVpnGatewayId();
+        if (vpnGatewayId != null) {
+            Site2SiteVpnGateway vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId);
+            if (vpnGateway != null) {
+                response.setVpnGatewayId(vpnGateway.getUuid());
+                long ipId = vpnGateway.getAddrId();
+                IPAddressVO ipObj = ApiDBUtils.findIpAddressById(ipId);
+                response.setIp(ipObj.getAddress().addr());
+            }
+        }
+
+        Long customerGatewayId = result.getCustomerGatewayId();
+        if (customerGatewayId != null) {
+            Site2SiteCustomerGateway customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId);
+            if (customerGateway != null) {
+                response.setCustomerGatewayId(customerGateway.getUuid());
+                response.setGatewayIp(customerGateway.getGatewayIp());
+                response.setGuestCidrList(customerGateway.getGuestCidrList());
+                response.setIpsecPsk(customerGateway.getIpsecPsk());
+                response.setIkePolicy(customerGateway.getIkePolicy());
+                response.setEspPolicy(customerGateway.getEspPolicy());
+                response.setIkeLifetime(customerGateway.getIkeLifetime());
+                response.setEspLifetime(customerGateway.getEspLifetime());
+                response.setDpd(customerGateway.getDpd());
+                response.setEncap(customerGateway.getEncap());
+            }
+        }
+
+        populateAccount(response, result.getAccountId());
+        populateDomain(response, result.getDomainId());
+
+        response.setState(result.getState().toString());
+        response.setCreated(result.getCreated());
+        response.setRemoved(result.getRemoved());
+        response.setForDisplay(result.isDisplay());
+        response.setObjectName("vpnconnection");
+        return response;
+    }
+
+    @Override
+    public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
+        GuestOSResponse response = new GuestOSResponse();
+        response.setDescription(guestOS.getDisplayName());
+        response.setId(guestOS.getUuid());
+        response.setIsUserDefined(guestOS.isUserDefined());
+        GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId());
+        if (category != null) {
+            response.setOsCategoryId(category.getUuid());
+        }
+
+        response.setObjectName("ostype");
+        return response;
+    }
+
+    @Override
+    public GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor guestOSHypervisor) {
+        GuestOsMappingResponse response = new GuestOsMappingResponse();
+        response.setId(guestOSHypervisor.getUuid());
+        response.setHypervisor(guestOSHypervisor.getHypervisorType());
+        response.setHypervisorVersion(guestOSHypervisor.getHypervisorVersion());
+        response.setOsNameForHypervisor((guestOSHypervisor.getGuestOsName()));
+        response.setIsUserDefined(Boolean.valueOf(guestOSHypervisor.getIsUserDefined()).toString());
+        GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOSHypervisor.getGuestOsId());
+        if (guestOs != null) {
+            response.setOsStdName(guestOs.getDisplayName());
+            response.setOsTypeId(guestOs.getUuid());
+        }
+
+        response.setObjectName("guestosmapping");
+        return response;
+    }
+
+    @Override
+    public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
+        SnapshotScheduleResponse response = new SnapshotScheduleResponse();
+        response.setId(snapshotSchedule.getUuid());
+        if (snapshotSchedule.getVolumeId() != null) {
+            Volume vol = ApiDBUtils.findVolumeById(snapshotSchedule.getVolumeId());
+            if (vol != null) {
+                response.setVolumeId(vol.getUuid());
+            }
+        }
+        if (snapshotSchedule.getPolicyId() != null) {
+            SnapshotPolicy policy = ApiDBUtils.findSnapshotPolicyById(snapshotSchedule.getPolicyId());
+            if (policy != null) {
+                response.setSnapshotPolicyId(policy.getUuid());
+            }
+        }
+        response.setScheduled(snapshotSchedule.getScheduledTimestamp());
+
+        response.setObjectName("snapshot");
+        return response;
+    }
+
+    @Override
+    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags()
+    {
+        try {
+            return _resourceTagDao.listTags();
+        } catch(Exception ex) {
+            s_logger.warn("Failed to get resource details for Usage data due to exception : ", ex);
+        }
+        return null;
+    }
+
+    @Override
+    public UsageRecordResponse createUsageResponse(Usage usageRecord) {
+        return createUsageResponse(usageRecord, null);
+    }
+
+    @Override
+    public UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>> resourceTagResponseMap) {
+        UsageRecordResponse usageRecResponse = new UsageRecordResponse();
+        Account account = ApiDBUtils.findAccountById(usageRecord.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            //find the project
+            Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId());
+            if (project != null) {
+                usageRecResponse.setProjectId(project.getUuid());
+                usageRecResponse.setProjectName(project.getName());
+            }
+        } else {
+            usageRecResponse.setAccountId(account.getUuid());
+            usageRecResponse.setAccountName(account.getAccountName());
+        }
+
+        Domain domain = ApiDBUtils.findDomainById(usageRecord.getDomainId());
+        if (domain != null) {
+            usageRecResponse.setDomainId(domain.getUuid());
+            usageRecResponse.setDomainName(domain.getName());
+        }
+
+        if (usageRecord.getZoneId() != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId());
+            if (zone != null) {
+                usageRecResponse.setZoneId(zone.getUuid());
+            }
+        }
+        usageRecResponse.setDescription(usageRecord.getDescription());
+        usageRecResponse.setUsage(usageRecord.getUsageDisplay());
+        usageRecResponse.setUsageType(usageRecord.getUsageType());
+        if (usageRecord.getVmInstanceId() != null) {
+            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId());
+            if (vm != null) {
+                usageRecResponse.setVirtualMachineId(vm.getUuid());
+            }
+        }
+        usageRecResponse.setVmName(usageRecord.getVmName());
+        if (usageRecord.getTemplateId() != null) {
+            VMTemplateVO template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId());
+            if (template != null) {
+                usageRecResponse.setTemplateId(template.getUuid());
+            }
+        }
+
+        ResourceTag.ResourceObjectType resourceType = null;
+        Long resourceId = null;
+        if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) {
+            ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString());
+            //Service Offering Id
+            if(svcOffering != null) {
+                usageRecResponse.setOfferingId(svcOffering.getUuid());
+            }
+            //VM Instance ID
+            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
+            if (vm != null) {
+                resourceType = ResourceTag.ResourceObjectType.UserVm;
+                usageRecResponse.setUsageId(vm.getUuid());
+                resourceId = vm.getId();
+            }
+            //Hypervisor Type
+            usageRecResponse.setType(usageRecord.getType());
+            //Dynamic compute offerings details
+            if(usageRecord.getCpuCores() != null) {
+                usageRecResponse.setCpuNumber(usageRecord.getCpuCores());
+            } else if (svcOffering.getCpu() != null){
+                usageRecResponse.setCpuNumber(svcOffering.getCpu().longValue());
+            }
+            if(usageRecord.getCpuSpeed() != null) {
+                usageRecResponse.setCpuSpeed(usageRecord.getCpuSpeed());
+            } else if(svcOffering.getSpeed() != null){
+                usageRecResponse.setCpuSpeed(svcOffering.getSpeed().longValue());
+            }
+            if(usageRecord.getMemory() != null) {
+                usageRecResponse.setMemory(usageRecord.getMemory());
+            } else if(svcOffering.getRamSize() != null) {
+                usageRecResponse.setMemory(svcOffering.getRamSize().longValue());
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) {
+            //isSourceNAT
+            usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ? true : false);
+            //isSystem
+            usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true : false);
+            //IP Address ID
+            IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString());
+            if (ip != null) {
+                resourceType = ResourceObjectType.PublicIpAddress;
+                resourceId = ip.getId();
+                usageRecResponse.setUsageId(ip.getUuid());
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
+            //Device Type
+            resourceType = ResourceObjectType.UserVm;
+            usageRecResponse.setType(usageRecord.getType());
+            if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) {
+                //Domain Router Id
+                VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
+                if (vm != null) {
+                    resourceId = vm.getId();
+                    usageRecResponse.setUsageId(vm.getUuid());
+                }
+            } else {
+                //External Device Host Id
+                HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString());
+                if (host != null) {
+                    usageRecResponse.setUsageId(host.getUuid());
+                }
+            }
+            //Network ID
+            if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId() != 0)) {
+                NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString());
+                if (network != null) {
+                    resourceType = ResourceObjectType.Network;
+                    resourceId = network.getId();
+                    usageRecResponse.setNetworkId(network.getUuid());
+                }
+            }
+        } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_WRITE
+                || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_WRITE) {
+            //Device Type
+            usageRecResponse.setType(usageRecord.getType());
+            resourceType = ResourceObjectType.Volume;
+            //VM Instance Id
+            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
+            if (vm != null) {
+                usageRecResponse.setVirtualMachineId(vm.getUuid());
+            }
+            //Volume ID
+            VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
+            if (volume != null) {
+                usageRecResponse.setUsageId(volume.getUuid());
+                resourceId = volume.getId();
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) {
+            //Volume ID
+            VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.Volume;
+            if (volume != null) {
+                usageRecResponse.setUsageId(volume.getUuid());
+                resourceId = volume.getId();
+            }
+            //Volume Size
+            usageRecResponse.setSize(usageRecord.getSize());
+            //Disk Offering Id
+            if (usageRecord.getOfferingId() != null) {
+                DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString());
+                usageRecResponse.setOfferingId(diskOff.getUuid());
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) {
+            //Template/ISO ID
+            VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString());
+            if (tmpl != null) {
+                usageRecResponse.setUsageId(tmpl.getUuid());
+                resourceId = tmpl.getId();
+            }
+            //Template/ISO Size
+            usageRecResponse.setSize(usageRecord.getSize());
+            if (usageRecord.getUsageType() == UsageTypes.ISO) {
+                usageRecResponse.setVirtualSize(usageRecord.getSize());
+                resourceType = ResourceObjectType.ISO;
+            } else {
+                usageRecResponse.setVirtualSize(usageRecord.getVirtualSize());
+                resourceType = ResourceObjectType.Template;
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) {
+            //Snapshot ID
+            SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.Snapshot;
+            if (snap != null) {
+                usageRecResponse.setUsageId(snap.getUuid());
+                resourceId = snap.getId();
+            }
+            //Snapshot Size
+            usageRecResponse.setSize(usageRecord.getSize());
+
+        } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) {
+            //Load Balancer Policy ID
+            LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.LoadBalancer;
+            if (lb != null) {
+                usageRecResponse.setUsageId(lb.getUuid());
+                resourceId = lb.getId();
+            }
+        } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) {
+            //Port Forwarding Rule ID
+            PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.PortForwardingRule;
+            if (pf != null) {
+                usageRecResponse.setUsageId(pf.getUuid());
+                resourceId = pf.getId();
+            }
+
+        } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) {
+            //Network Offering Id
+            NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString());
+            usageRecResponse.setOfferingId(netOff.getUuid());
+            //is Default
+            usageRecResponse.setDefault((usageRecord.getUsageId() == 1) ? true : false);
+
+        } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) {
+            //VPN User ID
+            VpnUserVO vpnUser = _entityMgr.findByIdIncludingRemoved(VpnUserVO.class, usageRecord.getUsageId().toString());
+            if (vpnUser != null) {
+                usageRecResponse.setUsageId(vpnUser.getUuid());
+            }
+        } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) {
+            //Security Group Id
+            SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.SecurityGroup;
+            if (sg != null) {
+                resourceId = sg.getId();
+                usageRecResponse.setUsageId(sg.getUuid());
+            }
+        } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
+            VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
+            resourceType = ResourceObjectType.UserVm;
+            if (vm != null) {
+                resourceId = vm.getId();
+                usageRecResponse.setVmName(vm.getInstanceName());
+                usageRecResponse.setUsageId(vm.getUuid());
+            }
+            usageRecResponse.setSize(usageRecord.getSize());
+            if (usageRecord.getOfferingId() != null) {
+                usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString());
+            }
+        }
+
+        if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId + ":" + resourceType) != null) {
+             usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
+        }
+
+        if (usageRecord.getRawUsage() != null) {
+            DecimalFormat decimalFormat = new DecimalFormat("###########.######");
+            usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));
+        }
+
+        if (usageRecord.getStartDate() != null) {
+            usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate()));
+        }
+        if (usageRecord.getEndDate() != null) {
+            usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate()));
+        }
+
+        return usageRecResponse;
+    }
+
+    public String getDateStringInternal(Date inputDate) {
+        if (inputDate == null) {
+            return null;
+        }
+
+        TimeZone tz = _usageSvc.getUsageTimezone();
+        Calendar cal = Calendar.getInstance(tz);
+        cal.setTime(inputDate);
+
+        StringBuilder sb = new StringBuilder(32);
+        sb.append(cal.get(Calendar.YEAR)).append('-');
+
+        int month = cal.get(Calendar.MONTH) + 1;
+        if (month < 10) {
+            sb.append('0');
+        }
+        sb.append(month).append('-');
+
+        int day = cal.get(Calendar.DAY_OF_MONTH);
+        if (day < 10) {
+            sb.append('0');
+        }
+        sb.append(day);
+
+        sb.append("'T'");
+
+        int hour = cal.get(Calendar.HOUR_OF_DAY);
+        if (hour < 10) {
+            sb.append('0');
+        }
+        sb.append(hour).append(':');
+
+        int minute = cal.get(Calendar.MINUTE);
+        if (minute < 10) {
+            sb.append('0');
+        }
+        sb.append(minute).append(':');
+
+        int seconds = cal.get(Calendar.SECOND);
+        if (seconds < 10) {
+            sb.append('0');
+        }
+        sb.append(seconds);
+
+        double offset = cal.get(Calendar.ZONE_OFFSET);
+        if (tz.inDaylightTime(inputDate)) {
+            offset += (1.0 * tz.getDSTSavings()); // add the timezone's DST
+            // value (typically 1 hour
+            // expressed in milliseconds)
+        }
+
+        offset = offset / (1000d * 60d * 60d);
+        int hourOffset = (int)offset;
+        double decimalVal = Math.abs(offset) - Math.abs(hourOffset);
+        int minuteOffset = (int)(decimalVal * 60);
+
+        if (hourOffset < 0) {
+            if (hourOffset > -10) {
+                sb.append("-0");
+            } else {
+                sb.append('-');
+            }
+            sb.append(Math.abs(hourOffset));
+        } else {
+            if (hourOffset < 10) {
+                sb.append("+0");
+            } else {
+                sb.append("+");
+            }
+            sb.append(hourOffset);
+        }
+
+        sb.append(':');
+
+        if (minuteOffset == 0) {
+            sb.append("00");
+        } else if (minuteOffset < 10) {
+            sb.append('0').append(minuteOffset);
+        } else {
+            sb.append(minuteOffset);
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor) {
+        Map<String, String> tmDetails = ApiDBUtils.findHostDetailsById(trafficMonitor.getId());
+        TrafficMonitorResponse response = new TrafficMonitorResponse();
+        response.setId(trafficMonitor.getUuid());
+        response.setIpAddress(trafficMonitor.getPrivateIpAddress());
+        response.setNumRetries(tmDetails.get("numRetries"));
+        response.setTimeout(tmDetails.get("timeout"));
+        return response;
+    }
+
+    @Override
+    public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) {
+        NicSecondaryIpResponse response = new NicSecondaryIpResponse();
+        NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId());
+        NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
+        response.setId(result.getUuid());
+        setResponseIpAddress(result, response);
+        response.setNicId(nic.getUuid());
+        response.setNwId(network.getUuid());
+        response.setObjectName("nicsecondaryip");
+        return response;
+    }
+
+    /**
+     * Set the NicSecondaryIpResponse object with the IP address that is not null (IPv4 or IPv6)
+     */
+    public static void setResponseIpAddress(NicSecondaryIp result, NicSecondaryIpResponse response) {
+        if (result.getIp4Address() != null) {
+            response.setIpAddr(result.getIp4Address());
+        } else if (result.getIp6Address() != null) {
+            response.setIpAddr(result.getIp6Address());
+        }
+    }
+
+    /**
+     * The resulting Response attempts to be in line with what is returned from
+     * @see com.cloud.api.query.dao.UserVmJoinDaoImpl#setUserVmResponse(ResponseView, UserVmResponse, UserVmJoinVO)
+     */
+    @Override
+    public NicResponse createNicResponse(Nic result) {
+        NicResponse response = new NicResponse();
+        NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId());
+        VMInstanceVO vm = _entityMgr.findById(VMInstanceVO.class, result.getInstanceId());
+        UserVmJoinVO userVm = _entityMgr.findById(UserVmJoinVO.class, result.getInstanceId());
+        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOs = _nicExtraDhcpOptionDao.listByNicId(result.getId());
+
+        // The numbered comments are to keep track of the data returned from here and UserVmJoinDaoImpl.setUserVmResponse()
+        // the data can't be identical but some tidying up/unifying might be possible
+        /*1: nicUuid*/
+        response.setId(result.getUuid());
+        /*2: networkUuid*/
+        response.setNetworkid(network.getUuid());
+        /*3: vmId*/
+        if (vm != null) {
+            response.setVmId(vm.getUuid());
+        }
+
+        if (userVm != null){
+            if (userVm.getTrafficType() != null) {
+                /*4: trafficType*/
+                response.setTrafficType(userVm.getTrafficType().toString());
+            }
+            if (userVm.getGuestType() != null) {
+                /*5: guestType*/
+                response.setType(userVm.getGuestType().toString());
+            }
+        }
+        /*6: ipAddress*/
+        response.setIpaddress(result.getIPv4Address());
+        /*7: gateway*/
+        response.setGateway(result.getIPv4Gateway());
+        /*8: netmask*/
+        response.setNetmask(result.getIPv4Netmask());
+        /*9: networkName*/
+        if(userVm != null && userVm.getNetworkName() != null) {
+            response.setNetworkName(userVm.getNetworkName());
+        }
+        /*10: macAddress*/
+        response.setMacAddress(result.getMacAddress());
+        /*11: IPv6Address*/
+        if (result.getIPv6Address() != null) {
+            response.setIp6Address(result.getIPv6Address());
+        }
+        /*12: IPv6Gateway*/
+        if (result.getIPv6Gateway() != null) {
+            response.setIp6Gateway(result.getIPv6Gateway());
+        }
+        /*13: IPv6Cidr*/
+        if (result.getIPv6Cidr() != null) {
+            response.setIp6Cidr(result.getIPv6Cidr());
+        }
+        /*14: deviceId*/
+        response.setDeviceId(String.valueOf(result.getDeviceId()));
+        /*15: broadcastURI*/
+        if (result.getBroadcastUri() != null) {
+            response.setBroadcastUri(result.getBroadcastUri().toString());
+        }
+        /*16: isolationURI*/
+        if (result.getIsolationUri() != null) {
+            response.setIsolationUri(result.getIsolationUri().toString());
+        }
+        /*17: default*/
+        response.setIsDefault(result.isDefaultNic());
+        if (result.getSecondaryIp()) {
+            List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(result.getId());
+            if (secondaryIps != null) {
+                List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
+                for (NicSecondaryIpVO ip : secondaryIps) {
+                    NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
+                    ipRes.setId(ip.getUuid());
+                    setResponseIpAddress(ip, ipRes);
+                    ipList.add(ipRes);
+                }
+                response.setSecondaryIps(ipList);
+            }
+        }
+        /*18: extra dhcp options */
+        List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = nicExtraDhcpOptionVOs
+                .stream()
+                .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
+                .collect(Collectors.toList());
+
+        response.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
+
+        if (result instanceof NicVO){
+            if (((NicVO)result).getNsxLogicalSwitchUuid() != null){
+                response.setNsxLogicalSwitch(((NicVO)result).getNsxLogicalSwitchUuid());
+            }
+            if (((NicVO)result).getNsxLogicalSwitchPortUuid() != null){
+                response.setNsxLogicalSwitchPort(((NicVO)result).getNsxLogicalSwitchPortUuid());
+            }
+        }
+        return response;
+    }
+
+    @Override
+    public ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map<Ip, UserVm> lbInstances) {
+
+        ApplicationLoadBalancerResponse lbResponse = new ApplicationLoadBalancerResponse();
+        lbResponse.setId(lb.getUuid());
+        lbResponse.setName(lb.getName());
+        lbResponse.setDescription(lb.getDescription());
+        lbResponse.setAlgorithm(lb.getAlgorithm());
+        lbResponse.setForDisplay(lb.isDisplay());
+        Network nw = ApiDBUtils.findNetworkById(lb.getNetworkId());
+        lbResponse.setNetworkId(nw.getUuid());
+        populateOwner(lbResponse, lb);
+
+        if (lb.getScheme() == Scheme.Internal) {
+            lbResponse.setSourceIp(lb.getSourceIp().addr());
+            //TODO - create the view for the load balancer rule to reflect the network uuid
+            Network network = ApiDBUtils.findNetworkById(lb.getNetworkId());
+            lbResponse.setSourceIpNetworkId(network.getUuid());
+        } else {
+            //for public, populate the ip information from the ip address
+            IpAddress publicIp = ApiDBUtils.findIpAddressById(lb.getSourceIpAddressId());
+            lbResponse.setSourceIp(publicIp.getAddress().addr());
+            Network ntwk = ApiDBUtils.findNetworkById(publicIp.getNetworkId());
+            lbResponse.setSourceIpNetworkId(ntwk.getUuid());
+        }
+
+        //set load balancer rules information (only one rule per load balancer in this release)
+        List<ApplicationLoadBalancerRuleResponse> ruleResponses = new ArrayList<ApplicationLoadBalancerRuleResponse>();
+        ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse();
+        ruleResponse.setInstancePort(lb.getDefaultPortStart());
+        ruleResponse.setSourcePort(lb.getSourcePortStart());
+        FirewallRule.State stateToSet = lb.getState();
+        if (stateToSet.equals(FirewallRule.State.Revoke)) {
+            stateToSet = FirewallRule.State.Deleting;
+        }
+        ruleResponse.setState(stateToSet.toString());
+        ruleResponse.setObjectName("loadbalancerrule");
+        ruleResponses.add(ruleResponse);
+        lbResponse.setLbRules(ruleResponses);
+
+        //set Lb instances information
+        List<ApplicationLoadBalancerInstanceResponse> instanceResponses = new ArrayList<ApplicationLoadBalancerInstanceResponse>();
+        for (Map.Entry<Ip,UserVm> entry : lbInstances.entrySet()) {
+            Ip ip = entry.getKey();
+            UserVm vm = entry.getValue();
+            ApplicationLoadBalancerInstanceResponse instanceResponse = new ApplicationLoadBalancerInstanceResponse();
+            instanceResponse.setIpAddress(ip.addr());
+            instanceResponse.setId(vm.getUuid());
+            instanceResponse.setName(vm.getInstanceName());
+            instanceResponse.setObjectName("loadbalancerinstance");
+            instanceResponses.add(instanceResponse);
+        }
+
+        lbResponse.setLbInstances(instanceResponses);
+
+        //set tag information
+        List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.LoadBalancer, lb.getId());
+        List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
+        for (ResourceTag tag : tags) {
+            ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
+            CollectionUtils.addIgnoreNull(tagResponses,tagResponse);
+        }
+        lbResponse.setTags(tagResponses);
+
+        lbResponse.setObjectName("loadbalancer");
+        return lbResponse;
+    }
+
+    @Override
+    public AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group) {
+
+        AffinityGroupResponse response = new AffinityGroupResponse();
+
+        Account account = ApiDBUtils.findAccountById(group.getAccountId());
+        response.setId(group.getUuid());
+        response.setAccountName(account.getAccountName());
+        response.setName(group.getName());
+        response.setType(group.getType());
+        response.setDescription(group.getDescription());
+        Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
+        if (domain != null) {
+            response.setDomainId(domain.getUuid());
+            response.setDomainName(domain.getName());
+        }
+
+        response.setObjectName("affinitygroup");
+        return response;
+    }
+
+    @Override
+    public Long getAffinityGroupId(String groupName, long accountId) {
+        AffinityGroup ag = ApiDBUtils.getAffinityGroup(groupName, accountId);
+        if (ag == null) {
+            return null;
+        } else {
+            return ag.getId();
+        }
+    }
+
+
+    @Override
+    public PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange ipRange) {
+        PortableIpRangeResponse response = new PortableIpRangeResponse();
+        response.setId(ipRange.getUuid());
+        String ipRangeStr = ipRange.getIpRange();
+        if (ipRangeStr != null) {
+            String[] range = ipRangeStr.split("-");
+            response.setStartIp(range[0]);
+            response.setEndIp(range[1]);
+        }
+        response.setVlan(ipRange.getVlanTag());
+        response.setGateway(ipRange.getGateway());
+        response.setNetmask(ipRange.getNetmask());
+        response.setRegionId(ipRange.getRegionId());
+        response.setObjectName("portableiprange");
+        return response;
+    }
+
+    @Override
+    public PortableIpResponse createPortableIPResponse(PortableIp portableIp) {
+        PortableIpResponse response = new PortableIpResponse();
+        response.setAddress(portableIp.getAddress());
+        Long accountId =  portableIp.getAllocatedInDomainId();
+        if (accountId != null) {
+            Account account = ApiDBUtils.findAccountById(accountId);
+            response.setAllocatedToAccountId(account.getAccountName());
+            Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
+            response.setAllocatedInDomainId(domain.getUuid());
+        }
+
+        response.setAllocatedTime(portableIp.getAllocatedTime());
+
+        if (portableIp.getAssociatedDataCenterId() != null) {
+            DataCenter zone = ApiDBUtils.findZoneById(portableIp.getAssociatedDataCenterId());
+            if (zone != null) {
+                response.setAssociatedDataCenterId(zone.getUuid());
+            }
+        }
+
+        if (portableIp.getPhysicalNetworkId() != null) {
+            PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(portableIp.getPhysicalNetworkId());
+            if (pnw != null) {
+                response.setPhysicalNetworkId(pnw.getUuid());
+            }
+        }
+
+        if (portableIp.getAssociatedWithNetworkId() != null) {
+            Network ntwk = ApiDBUtils.findNetworkById(portableIp.getAssociatedWithNetworkId());
+            if (ntwk != null) {
+                response.setAssociatedWithNetworkId(ntwk.getUuid());
+            }
+        }
+
+        if (portableIp.getAssociatedWithVpcId() != null) {
+            Vpc vpc = ApiDBUtils.findVpcById(portableIp.getAssociatedWithVpcId());
+            if (vpc != null) {
+                response.setAssociatedWithVpcId(vpc.getUuid());
+            }
+        }
+
+        response.setState(portableIp.getState().name());
+        response.setObjectName("portableip");
+        return response;
+    }
+
+    @Override
+    public InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result) {
+        if (result.getType() != VirtualRouterProvider.Type.InternalLbVm) {
+            return null;
+        }
+        InternalLoadBalancerElementResponse response = new InternalLoadBalancerElementResponse();
+        response.setId(result.getUuid());
+        PhysicalNetworkServiceProvider nsp = ApiDBUtils.findPhysicalNetworkServiceProviderById(result.getNspId());
+        if (nsp != null) {
+            response.setNspId(nsp.getUuid());
+        }
+        response.setEnabled(result.isEnabled());
+
+        response.setObjectName("internalloadbalancerelement");
+        return response;
+    }
+
+    @Override
+    public IsolationMethodResponse createIsolationMethodResponse(IsolationType method) {
+        IsolationMethodResponse response = new IsolationMethodResponse();
+        response.setIsolationMethodName(method.toString());
+        response.setObjectName("isolationmethod");
+        return response;
+    }
+
+    @Override
+    public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
+        NetworkACLResponse response = new NetworkACLResponse();
+        response.setId(networkACL.getUuid());
+        response.setName(networkACL.getName());
+        response.setDescription(networkACL.getDescription());
+        response.setForDisplay(networkACL.isDisplay());
+        Vpc vpc = ApiDBUtils.findVpcById(networkACL.getVpcId());
+        if (vpc != null) {
+            response.setVpcId(vpc.getUuid());
+        }
+        response.setObjectName("networkacllist");
+        return response;
+    }
+
+    @Override
+    public ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds) {
+        ListResponse<UpgradeRouterTemplateResponse> response = new ListResponse<UpgradeRouterTemplateResponse>();
+        List<UpgradeRouterTemplateResponse> responses = new ArrayList<UpgradeRouterTemplateResponse>();
+        for (Long jobId : jobIds) {
+            UpgradeRouterTemplateResponse routerResponse = new UpgradeRouterTemplateResponse();
+            AsyncJob job = _entityMgr.findById(AsyncJob.class, jobId);
+            routerResponse.setAsyncJobId((job.getUuid()));
+            routerResponse.setObjectName("asyncjobs");
+            responses.add(routerResponse);
+        }
+        response.setResponses(responses);
+        return response;
+    }
+
+    @Override
+    public SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey) {
+        SSHKeyPairResponse response = new SSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint());
+        if (privatekey) {
+            response = new CreateSSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint(), sshkeyPair.getPrivateKey());
+        }
+        Account account = ApiDBUtils.findAccountById(sshkeyPair.getAccountId());
+        response.setAccountName(account.getAccountName());
+        Domain domain = ApiDBUtils.findDomainById(sshkeyPair.getDomainId());
+        response.setDomainId(domain.getUuid());
+        response.setDomainName(domain.getName());
+        return response;
+    }
+    public ManagementServerResponse createManagementResponse(ManagementServerHost mgmt) {
+        ManagementServerResponse response = new ManagementServerResponse();
+        response.setId(mgmt.getUuid());
+        response.setName(mgmt.getName());
+        response.setVersion(mgmt.getVersion());
+        response.setState(mgmt.getState());
+        return response;
+    }
+}
diff --git a/server/src/com/cloud/api/ApiSerializerHelper.java b/server/src/main/java/com/cloud/api/ApiSerializerHelper.java
similarity index 100%
rename from server/src/com/cloud/api/ApiSerializerHelper.java
rename to server/src/main/java/com/cloud/api/ApiSerializerHelper.java
diff --git a/server/src/main/java/com/cloud/api/ApiServer.java b/server/src/main/java/com/cloud/api/ApiServer.java
new file mode 100644
index 0000000..a8ab7b0
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/ApiServer.java
@@ -0,0 +1,1453 @@
+// 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.api;
+
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
+import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventCategory;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AccountLimitException;
+import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.RequestLimitException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnavailableCommandException;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import com.cloud.user.UserVO;
+import com.cloud.utils.ConstantTimeComparator;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.HttpUtils;
+import com.cloud.utils.Pair;
+import com.cloud.utils.ReflectUtil;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UUIDManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionProxyObject;
+import com.google.gson.reflect.TypeToken;
+import org.apache.cloudstack.acl.APIChecker;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ApiServerService;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.auth.APIAuthenticationManager;
+import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
+import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
+import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.CreateCmdResponse;
+import org.apache.cloudstack.api.response.ExceptionResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.LoginCmdResponse;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.events.EventBus;
+import org.apache.cloudstack.framework.events.EventBusException;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
+import org.apache.cloudstack.framework.messagebus.MessageHandler;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.ConnectionClosedException;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpServerConnection;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.entity.BasicHttpEntity;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.DefaultHttpServerConnection;
+import org.apache.http.impl.NoConnectionReuseStrategy;
+import org.apache.http.impl.SocketHttpServerConnection;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.HttpRequestHandlerRegistry;
+import org.apache.http.protocol.HttpService;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
+import org.apache.log4j.Logger;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.lang.reflect.Type;
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Component
+public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService, Configurable {
+    private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName());
+    private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName());
+
+    private static boolean encodeApiResponse = false;
+
+    /**
+     * Non-printable ASCII characters - numbers 0 to 31 and 127 decimal
+     */
+    private static final String CONTROL_CHARACTERS = "[\000-\011\013-\014\016-\037\177]";
+
+    @Inject
+    private ApiDispatcher dispatcher;
+    @Inject
+    private DispatchChainFactory dispatchChainFactory;
+    @Inject
+    private AccountManager accountMgr;
+    @Inject
+    private DomainManager domainMgr;
+    @Inject
+    private DomainDao domainDao;
+    @Inject
+    private UUIDManager uuidMgr;
+    @Inject
+    private AsyncJobManager asyncMgr;
+    @Inject
+    private EntityManager entityMgr;
+    @Inject
+    private APIAuthenticationManager authManager;
+
+    private List<PluggableService> pluggableServices;
+
+    private List<APIChecker> apiAccessCheckers;
+
+    @Inject
+    private ApiAsyncJobDispatcher asyncDispatcher;
+
+    private static int s_workerCount = 0;
+    private static Map<String, List<Class<?>>> s_apiNameCmdClassMap = new HashMap<String, List<Class<?>>>();
+
+    private static ExecutorService s_executor = new ThreadPoolExecutor(10, 150, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory(
+            "ApiServer"));
+
+    @Inject
+    private MessageBus messageBus;
+
+    private static final ConfigKey<Integer> IntegrationAPIPort = new ConfigKey<Integer>("Advanced"
+            , Integer.class
+            , "integration.api.port"
+            , "8096"
+            , "Default API port"
+            , false
+            , ConfigKey.Scope.Global);
+    private static final ConfigKey<Long> ConcurrentSnapshotsThresholdPerHost = new ConfigKey<Long>("Advanced"
+            , Long.class
+            , "concurrent.snapshots.threshold.perhost"
+            , null
+            , "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited"
+            , true // not sure if this is to be dynamic
+            , ConfigKey.Scope.Global);
+    private static final ConfigKey<Boolean> EncodeApiResponse = new ConfigKey<Boolean>("Advanced"
+            , Boolean.class
+            , "encode.api.response"
+            , "false"
+            , "Do URL encoding for the api response, false by default"
+            , false
+            , ConfigKey.Scope.Global);
+    static final ConfigKey<String> JSONcontentType = new ConfigKey<String>( "Advanced"
+            , String.class
+            , "json.content.type"
+            , "application/json; charset=UTF-8"
+            , "Http response content type for .js files (default is text/javascript)"
+            , false
+            , ConfigKey.Scope.Global);
+    static final ConfigKey<Boolean> EnableSecureSessionCookie = new ConfigKey<Boolean>("Advanced"
+            , Boolean.class
+            , "enable.secure.session.cookie"
+            , "false"
+            , "Session cookie is marked as secure if this is enabled. Secure cookies only work when HTTPS is used."
+            , false
+            , ConfigKey.Scope.Global);
+    private static final ConfigKey<String> JSONDefaultContentType = new ConfigKey<String> ("Advanced"
+            , String.class
+            , "json.content.type"
+            , "application/json; charset=UTF-8"
+            , "Http response content type for JSON"
+            , false
+            , ConfigKey.Scope.Global);
+
+    private static final ConfigKey<Boolean> UseEventAccountInfo = new ConfigKey<Boolean>( "advanced"
+            , Boolean.class
+            , "event.accountinfo"
+            , "false"
+            , "use account info in event logging"
+            , true
+            , ConfigKey.Scope.Global);
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        messageBus.subscribe(AsyncJob.Topics.JOB_EVENT_PUBLISH, MessageDispatcher.getDispatcher(this));
+        return true;
+    }
+
+    @MessageHandler(topic = AsyncJob.Topics.JOB_EVENT_PUBLISH)
+    public void handleAsyncJobPublishEvent(String subject, String senderAddress, Object args) {
+        assert (args != null);
+
+        @SuppressWarnings("unchecked")
+        Pair<AsyncJob, String> eventInfo = (Pair<AsyncJob, String>)args;
+        AsyncJob job = eventInfo.first();
+        String jobEvent = eventInfo.second();
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("Handle asyjob publish event " + jobEvent);
+
+        EventBus eventBus = null;
+        try {
+            eventBus = ComponentContext.getComponent(EventBus.class);
+        } catch (NoSuchBeanDefinitionException nbe) {
+            return; // no provider is configured to provide events bus, so just return
+        }
+
+        if (!job.getDispatcher().equalsIgnoreCase("ApiAsyncJobDispatcher")) {
+            return;
+        }
+
+        User userJobOwner = accountMgr.getUserIncludingRemoved(job.getUserId());
+        Account jobOwner = accountMgr.getAccount(userJobOwner.getAccountId());
+
+        // Get the event type from the cmdInfo json string
+        String info = job.getCmdInfo();
+        String cmdEventType = "unknown";
+        if (info != null) {
+            Type type = new TypeToken<Map<String, String>>(){}.getType();
+            Map<String, String> cmdInfo = ApiGsonHelper.getBuilder().create().fromJson(info, type);
+            String eventTypeObj = cmdInfo.get("cmdEventType");
+            if (eventTypeObj != null) {
+                cmdEventType = eventTypeObj;
+
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("Retrieved cmdEventType from job info: " + cmdEventType);
+            } else {
+                if (s_logger.isDebugEnabled())
+                    s_logger.debug("Unable to locate cmdEventType marker in job info. publish as unknown event");
+            }
+        }
+        // For some reason, the instanceType / instanceId are not abstract, which means we may get null values.
+        String instanceType = job.getInstanceType() != null ? job.getInstanceType() : "unknown";
+        String instanceUuid = job.getInstanceId() != null ? ApiDBUtils.findJobInstanceUuid(job) : "";
+        org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event("management-server", EventCategory.ASYNC_JOB_CHANGE_EVENT.getName(),
+                jobEvent, instanceType, instanceUuid);
+
+        Map<String, String> eventDescription = new HashMap<String, String>();
+        eventDescription.put("command", job.getCmd());
+        eventDescription.put("user", userJobOwner.getUuid());
+        eventDescription.put("account", jobOwner.getUuid());
+        eventDescription.put("processStatus", "" + job.getProcessStatus());
+        eventDescription.put("resultCode", "" + job.getResultCode());
+        eventDescription.put("instanceUuid", instanceUuid);
+        eventDescription.put("instanceType", instanceType);
+        eventDescription.put("commandEventType", cmdEventType);
+        eventDescription.put("jobId", job.getUuid());
+        eventDescription.put("jobResult", job.getResult());
+        eventDescription.put("cmdInfo", job.getCmdInfo());
+        eventDescription.put("status", "" + job.getStatus() );
+        // If the event.accountinfo boolean value is set, get the human readable value for the username / domainname
+        if (UseEventAccountInfo.value()) {
+            DomainVO domain = domainDao.findById(jobOwner.getDomainId());
+            eventDescription.put("username", userJobOwner.getUsername());
+            eventDescription.put("accountname", jobOwner.getAccountName());
+            eventDescription.put("domainname", domain.getName());
+        }
+        event.setDescription(eventDescription);
+
+        try {
+            eventBus.publish(event);
+        } catch (EventBusException evx) {
+            String errMsg = "Failed to publish async job event on the the event bus.";
+            s_logger.warn(errMsg, evx);
+        }
+    }
+
+    @Override
+    public boolean start() {
+        Security.addProvider(new BouncyCastleProvider());
+        Integer apiPort = IntegrationAPIPort.value(); // api port, null by default
+
+        final Long snapshotLimit = ConcurrentSnapshotsThresholdPerHost.value();
+        if (snapshotLimit == null || snapshotLimit.longValue() <= 0) {
+            s_logger.debug("Global concurrent snapshot config parameter " + ConcurrentSnapshotsThresholdPerHost.value() + " is less or equal 0; defaulting to unlimited");
+        } else {
+            dispatcher.setCreateSnapshotQueueSizeLimit(snapshotLimit);
+        }
+
+        final Long migrationLimit = VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value();
+        if (migrationLimit == null || migrationLimit.longValue() <= 0) {
+            s_logger.debug("Global concurrent migration config parameter " + VolumeApiService.ConcurrentMigrationsThresholdPerDatastore.value() + " is less or equal 0; defaulting to unlimited");
+        } else {
+            dispatcher.setMigrateQueueSizeLimit(migrationLimit);
+        }
+
+        final Set<Class<?>> cmdClasses = new HashSet<Class<?>>();
+        for (final PluggableService pluggableService : pluggableServices) {
+            cmdClasses.addAll(pluggableService.getCommands());
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Discovered plugin " + pluggableService.getClass().getSimpleName());
+            }
+        }
+
+        for (final Class<?> cmdClass : cmdClasses) {
+            final APICommand at = cmdClass.getAnnotation(APICommand.class);
+            if (at == null) {
+                throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName()));
+            }
+
+            String apiName = at.name();
+            List<Class<?>> apiCmdList = s_apiNameCmdClassMap.get(apiName);
+            if (apiCmdList == null) {
+                apiCmdList = new ArrayList<Class<?>>();
+                s_apiNameCmdClassMap.put(apiName, apiCmdList);
+            }
+            apiCmdList.add(cmdClass);
+
+        }
+
+        setEncodeApiResponse(EncodeApiResponse.value());
+
+        if (apiPort != null) {
+            final ListenerThread listenerThread = new ListenerThread(this, apiPort);
+            listenerThread.start();
+        }
+
+        return true;
+    }
+
+    // NOTE: handle() only handles over the wire (OTW) requests from integration.api.port 8096
+    // If integration api port is not configured, actual OTW requests will be received by ApiServlet
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Override
+    public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException {
+
+        // Create StringBuffer to log information in access log
+        final StringBuilder sb = new StringBuilder();
+        final HttpServerConnection connObj = (HttpServerConnection)context.getAttribute("http.connection");
+        if (connObj instanceof SocketHttpServerConnection) {
+            final InetAddress remoteAddr = ((SocketHttpServerConnection)connObj).getRemoteAddress();
+            sb.append(remoteAddr.toString() + " -- ");
+        }
+        sb.append(StringUtils.cleanString(request.getRequestLine().toString()));
+
+        try {
+            List<NameValuePair> paramList = null;
+            try {
+                paramList = URLEncodedUtils.parse(new URI(request.getRequestLine().getUri()), HttpUtils.UTF_8);
+            } catch (final URISyntaxException e) {
+                s_logger.error("Error parsing url request", e);
+            }
+
+            // Use Multimap as the parameter map should be in the form (name=String, value=String[])
+            // So parameter values are stored in a list for the same name key
+            // APITODO: Use Guava's (import com.google.common.collect.Multimap;)
+            // (Immutable)Multimap<String, String> paramMultiMap = HashMultimap.create();
+            // Map<String, Collection<String>> parameterMap = paramMultiMap.asMap();
+            final Map parameterMap = new HashMap<String, String[]>();
+            String responseType = HttpUtils.RESPONSE_TYPE_XML;
+            if(paramList != null) {
+                for (final NameValuePair param : paramList) {
+                    if (param.getName().equalsIgnoreCase("response")) {
+                        responseType = param.getValue();
+                        continue;
+                    }
+                    parameterMap.put(param.getName(), new String[]{param.getValue()});
+                }
+            }
+
+            // Get the type of http method being used.
+            parameterMap.put("httpmethod", new String[] {request.getRequestLine().getMethod()});
+
+            // Check responseType, if not among valid types, fallback to JSON
+            if (!(responseType.equals(HttpUtils.RESPONSE_TYPE_JSON) || responseType.equals(HttpUtils.RESPONSE_TYPE_XML))) {
+                responseType = HttpUtils.RESPONSE_TYPE_XML;
+            }
+            try {
+                //verify that parameter is legit for passing via admin port
+                String[] command = (String[]) parameterMap.get("command");
+                if (command != null) {
+                    Class<?> cmdClass = getCmdClass(command[0]);
+                    if (cmdClass != null) {
+                        List<Field> fields = ReflectUtil.getAllFieldsForClass(cmdClass, BaseCmd.class);
+                        for (Field field : fields) {
+                            Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+                            if ((parameterAnnotation == null) || !parameterAnnotation.expose()) {
+                                continue;
+                            }
+                            Object paramObj = parameterMap.get(parameterAnnotation.name());
+                            if (paramObj != null) {
+                                if (!parameterAnnotation.acceptedOnAdminPort()) {
+                                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, "Parameter " + parameterAnnotation.name() + " can't be passed through the API integration port");
+                                }
+                            }
+                        }
+                    }
+                }
+                // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM
+                CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount());
+                sb.insert(0, "(userId=" + User.UID_SYSTEM + " accountId=" + Account.ACCOUNT_ID_SYSTEM + " sessionId=" + null + ") ");
+                final String responseText = handleRequest(parameterMap, responseType, sb);
+                sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length()));
+
+                writeResponse(response, responseText, HttpStatus.SC_OK, responseType, null);
+            } catch (final ServerApiException se) {
+                final String responseText = getSerializedApiError(se, parameterMap, responseType);
+                writeResponse(response, responseText, se.getErrorCode().getHttpCode(), responseType, se.getDescription());
+                sb.append(" " + se.getErrorCode() + " " + se.getDescription());
+            } catch (final RuntimeException e) {
+                // log runtime exception like NullPointerException to help identify the source easier
+                s_logger.error("Unhandled exception, ", e);
+                throw e;
+            }
+        } finally {
+            s_accessLogger.info(sb.toString());
+            CallContext.unregister();
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void checkCharacterInkParams(final Map params) {
+        final Map<String, String> stringMap = new HashMap<String, String>();
+        final Set keys = params.keySet();
+        final Iterator keysIter = keys.iterator();
+        while (keysIter.hasNext()) {
+            final String key = (String)keysIter.next();
+            final String[] value = (String[])params.get(key);
+            // fail if parameter value contains ASCII control (non-printable) characters
+            if (value[0] != null) {
+                final Pattern pattern = Pattern.compile(CONTROL_CHARACTERS);
+                final Matcher matcher = pattern.matcher(value[0]);
+                if (matcher.find()) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Received value containing illegal ASCII non-printable characters for parameter " + key);
+                }
+            }
+            stringMap.put(key, value[0]);
+        }
+    }
+
+    @Override
+    @SuppressWarnings("rawtypes")
+    public String handleRequest(final Map params, final String responseType, final StringBuilder auditTrailSb) throws ServerApiException {
+        checkCharacterInkParams(params);
+
+        String response = null;
+        String[] command = null;
+
+        try {
+            command = (String[])params.get("command");
+            if (command == null) {
+                s_logger.error("invalid request, no command sent");
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("dumping request parameters");
+                    for (final  Object key : params.keySet()) {
+                        final String keyStr = (String)key;
+                        final String[] value = (String[])params.get(key);
+                        s_logger.trace("   key: " + keyStr + ", value: " + ((value == null) ? "'null'" : value[0]));
+                    }
+                }
+                throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "Invalid request, no command sent");
+            } else {
+                // Don't allow Login/Logout APIs to go past this point
+                if (authManager.getAPIAuthenticator(command[0]) != null) {
+                    return null;
+                }
+                final Map<String, String> paramMap = new HashMap<String, String>();
+                final Set keys = params.keySet();
+                final Iterator keysIter = keys.iterator();
+                while (keysIter.hasNext()) {
+                    final String key = (String)keysIter.next();
+                    if ("command".equalsIgnoreCase(key)) {
+                        continue;
+                    }
+                    final String[] value = (String[])params.get(key);
+                    paramMap.put(key, value[0]);
+                }
+
+                Class<?> cmdClass = getCmdClass(command[0]);
+                if (cmdClass != null) {
+                    APICommand annotation = cmdClass.getAnnotation(APICommand.class);
+                    if (annotation == null) {
+                        s_logger.error("No APICommand annotation found for class " + cmdClass.getCanonicalName());
+                        throw new CloudRuntimeException("No APICommand annotation found for class " + cmdClass.getCanonicalName());
+                    }
+
+                    BaseCmd cmdObj = (BaseCmd)cmdClass.newInstance();
+                    cmdObj = ComponentContext.inject(cmdObj);
+                    cmdObj.configure();
+                    cmdObj.setFullUrlParams(paramMap);
+                    cmdObj.setResponseType(responseType);
+                    cmdObj.setHttpMethod(paramMap.get(ApiConstants.HTTPMETHOD).toString());
+
+                    // This is where the command is either serialized, or directly dispatched
+                    StringBuilder log = new StringBuilder();
+                    response = queueCommand(cmdObj, paramMap, log);
+                    buildAuditTrail(auditTrailSb, command[0], log.toString());
+                } else {
+                    final String errorString = "Unknown API command: " + command[0];
+                    s_logger.warn(errorString);
+                    auditTrailSb.append(" " + errorString);
+                    throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString);
+                }
+            }
+        } catch (final InvalidParameterValueException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
+        } catch (final IllegalArgumentException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage(), ex);
+        } catch (final PermissionDeniedException ex) {
+            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
+            if (idList != null) {
+                final StringBuffer buf = new StringBuffer();
+                for (final ExceptionProxyObject obj : idList) {
+                    buf.append(obj.getDescription());
+                    buf.append(":");
+                    buf.append(obj.getUuid());
+                    buf.append(" ");
+                }
+                s_logger.info("PermissionDenied: " + ex.getMessage() + " on objs: [" + buf.toString() + "]");
+            } else {
+                s_logger.info("PermissionDenied: " + ex.getMessage());
+            }
+            throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, ex.getMessage(), ex);
+        } catch (final AccountLimitException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.ACCOUNT_RESOURCE_LIMIT_ERROR, ex.getMessage(), ex);
+        } catch (final InsufficientCapacityException ex) {
+            s_logger.info(ex.getMessage());
+            String errorMsg = ex.getMessage();
+            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
+                // hide internal details to non-admin user for security reason
+                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
+            }
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, errorMsg, ex);
+        } catch (final ResourceAllocationException ex) {
+            s_logger.info(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage(), ex);
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.info(ex.getMessage());
+            String errorMsg = ex.getMessage();
+            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
+                // hide internal details to non-admin user for security reason
+                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
+            }
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, errorMsg, ex);
+        } catch (final ServerApiException ex) {
+            s_logger.info(ex.getDescription());
+            throw ex;
+        } catch (final Exception ex) {
+            s_logger.error("unhandled exception executing api command: " + ((command == null) ? "null" : command), ex);
+            String errorMsg = ex.getMessage();
+            if (!accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
+                // hide internal details to non-admin user for security reason
+                errorMsg = BaseCmd.USER_ERROR_MESSAGE;
+            }
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg, ex);
+        }
+
+        return response;
+    }
+
+    private String getBaseAsyncResponse(final long jobId, final BaseAsyncCmd cmd) {
+        final AsyncJobResponse response = new AsyncJobResponse();
+
+        final AsyncJob job = entityMgr.findById(AsyncJob.class, jobId);
+        response.setJobId(job.getUuid());
+        response.setResponseName(cmd.getCommandName());
+        return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
+    }
+
+    private String getBaseAsyncCreateResponse(final long jobId, final BaseAsyncCreateCmd cmd, final String objectUuid) {
+        final CreateCmdResponse response = new CreateCmdResponse();
+        final AsyncJob job = entityMgr.findById(AsyncJob.class, jobId);
+        response.setJobId(job.getUuid());
+        response.setId(objectUuid);
+        response.setResponseName(cmd.getCommandName());
+        return ApiResponseSerializer.toSerializedString(response, cmd.getResponseType());
+    }
+
+    private String queueCommand(final BaseCmd cmdObj, final Map<String, String> params, StringBuilder log) throws Exception {
+        final CallContext ctx = CallContext.current();
+        final Long callerUserId = ctx.getCallingUserId();
+        final Account caller = ctx.getCallingAccount();
+
+        // Queue command based on Cmd super class:
+        // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
+        // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as BaseAsyncCmd.
+        // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized and returned.
+        if (cmdObj instanceof BaseAsyncCmd) {
+            Long objectId = null;
+            String objectUuid = null;
+            if (cmdObj instanceof BaseAsyncCreateCmd) {
+                final BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd)cmdObj;
+                dispatcher.dispatchCreateCmd(createCmd, params);
+                objectId = createCmd.getEntityId();
+                objectUuid = createCmd.getEntityUuid();
+                params.put("id", objectId.toString());
+                Class entityClass = EventTypes.getEntityClassForEvent(createCmd.getEventType());
+                if (entityClass != null)
+                    ctx.putContextParameter(entityClass, objectUuid);
+            } else {
+                // Extract the uuid before params are processed and id reflects internal db id
+                objectUuid = params.get(ApiConstants.ID);
+                dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
+            }
+
+            final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmdObj;
+
+            if (callerUserId != null) {
+                params.put("ctxUserId", callerUserId.toString());
+            }
+            if (caller != null) {
+                params.put("ctxAccountId", String.valueOf(caller.getId()));
+            }
+            if (objectUuid != null) {
+                params.put("uuid", objectUuid);
+            }
+
+            long startEventId = ctx.getStartEventId();
+            asyncCmd.setStartEventId(startEventId);
+
+            // save the scheduled event
+            final Long eventId =
+                    ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? (Long)User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
+                            asyncCmd.getEventDescription(), asyncCmd.isDisplay(), startEventId);
+            if (startEventId == 0) {
+                // There was no create event before, set current event id as start eventId
+                startEventId = eventId;
+            }
+
+            params.put("ctxStartEventId", String.valueOf(startEventId));
+            params.put("cmdEventType", asyncCmd.getEventType().toString());
+            params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters()));
+
+            Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
+
+            // users can provide the job id they want to use, so log as it is a uuid and is unique
+            String injectedJobId = asyncCmd.getInjectedJobId();
+            uuidMgr.checkUuidSimple(injectedJobId, AsyncJob.class);
+
+            AsyncJobVO job = new AsyncJobVO("", callerUserId, caller.getId(), cmdObj.getClass().getName(),
+                    ApiGsonHelper.getBuilder().create().toJson(params), instanceId,
+                    asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null,
+                            injectedJobId);
+            job.setDispatcher(asyncDispatcher.getName());
+
+            final long jobId = asyncMgr.submitAsyncJob(job);
+
+            if (jobId == 0L) {
+                final String errorMsg = "Unable to schedule async job for command " + job.getCmd();
+                s_logger.warn(errorMsg);
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
+            }
+            final String response;
+            if (objectId != null) {
+                final String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid;
+                response = getBaseAsyncCreateResponse(jobId, (BaseAsyncCreateCmd)asyncCmd, objUuid);
+            } else {
+                SerializationContext.current().setUuidTranslation(true);
+                response = getBaseAsyncResponse(jobId, asyncCmd);
+            }
+            // Always log response for async for now, I don't think any sensitive data will be in here.
+            // It might be nice to send this through scrubbing similar to how
+            // ApiResponseSerializer.toSerializedStringWithSecureLogs works. For now, this gets jobid's
+            // in the api logs.
+            log.append(response);
+            return response;
+
+        } else {
+            dispatcher.dispatch(cmdObj, params, false);
+
+            // if the command is of the listXXXCommand, we will need to also return the
+            // the job id and status if possible
+            // For those listXXXCommand which we have already created DB views, this step is not needed since async job is joined in their db views.
+            if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd)
+                    && !(cmdObj instanceof ListSecurityGroupsCmd) &&
+                    !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) &&
+                    !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) &&
+                    !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd)
+                    && !(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) &&
+                    !(cmdObj instanceof ListZonesCmd)) {
+                buildAsyncListResponse((BaseListCmd)cmdObj, caller);
+            }
+
+            SerializationContext.current().setUuidTranslation(true);
+            return ApiResponseSerializer.toSerializedStringWithSecureLogs((ResponseObject)cmdObj.getResponseObject(), cmdObj.getResponseType(), log);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void buildAsyncListResponse(final BaseListCmd command, final Account account) {
+        final List<ResponseObject> responses = ((ListResponse)command.getResponseObject()).getResponses();
+        if (responses != null && responses.size() > 0) {
+            List<? extends AsyncJob> jobs = null;
+
+            // list all jobs for ROOT admin
+            if (accountMgr.isRootAdmin(account.getId())) {
+                jobs = asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), null);
+            } else {
+                jobs = asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType().toString(), account.getId());
+            }
+
+            if (jobs.size() == 0) {
+                return;
+            }
+
+            final Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>();
+            for (final AsyncJob job : jobs) {
+                if (job.getInstanceId() == null) {
+                    continue;
+                }
+                final String instanceUuid = ApiDBUtils.findJobInstanceUuid(job);
+                objectJobMap.put(instanceUuid, job);
+            }
+
+            for (final ResponseObject response : responses) {
+                if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) {
+                    final AsyncJob job = objectJobMap.get(response.getObjectId());
+                    response.setJobId(job.getUuid());
+                    response.setJobStatus(job.getStatus().ordinal());
+                }
+            }
+        }
+    }
+
+    private void buildAuditTrail(final StringBuilder auditTrailSb, final String command, final String result) {
+        if (result == null) {
+            return;
+        }
+        auditTrailSb.append(" " + HttpServletResponse.SC_OK + " ");
+        if (command.equals("createSSHKeyPair")) {
+            auditTrailSb.append("This result was not logged because it contains sensitive data.");
+        } else {
+            auditTrailSb.append(result);
+        }
+    }
+
+    @Override
+    public boolean verifyRequest(final Map<String, Object[]> requestParameters, final Long userId, InetAddress remoteAddress) throws ServerApiException {
+        try {
+            String apiKey = null;
+            String secretKey = null;
+            String signature = null;
+            String unsignedRequest = null;
+
+            final String[] command = (String[])requestParameters.get(ApiConstants.COMMAND);
+            if (command == null) {
+                s_logger.info("missing command, ignoring request...");
+                return false;
+            }
+
+            final String commandName = command[0];
+
+            // if userId not null, that mean that user is logged in
+            if (userId != null) {
+                final User user = ApiDBUtils.findUserById(userId);
+
+                if (!commandAvailable(remoteAddress, commandName, user)) {
+                    return false;
+                }
+
+                return true;
+            } else {
+                // check against every available command to see if the command exists or not
+                if (!s_apiNameCmdClassMap.containsKey(commandName) && !commandName.equals("login") && !commandName.equals("logout")) {
+                    final String errorMessage = "The given command " + commandName + " either does not exist, is not available" +
+                            " for user, or not available from ip address '" + remoteAddress.getHostAddress() + "'.";
+                    s_logger.debug(errorMessage);
+                    return false;
+                }
+            }
+
+            // - build a request string with sorted params, make sure it's all lowercase
+            // - sign the request, verify the signature is the same
+            final List<String> parameterNames = new ArrayList<String>();
+
+            for (final Object paramNameObj : requestParameters.keySet()) {
+                parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
+            }
+
+            Collections.sort(parameterNames);
+
+            String signatureVersion = null;
+            String expires = null;
+
+            for (final String paramName : parameterNames) {
+                // parameters come as name/value pairs in the form String/String[]
+                final String paramValue = ((String[])requestParameters.get(paramName))[0];
+
+                if (ApiConstants.SIGNATURE.equalsIgnoreCase(paramName)) {
+                    signature = paramValue;
+                } else {
+                    if (ApiConstants.API_KEY.equalsIgnoreCase(paramName)) {
+                        apiKey = paramValue;
+                    } else if (ApiConstants.SIGNATURE_VERSION.equalsIgnoreCase(paramName)) {
+                        signatureVersion = paramValue;
+                    } else if (ApiConstants.EXPIRES.equalsIgnoreCase(paramName)) {
+                        expires = paramValue;
+                    }
+
+                    if (unsignedRequest == null) {
+                        unsignedRequest = paramName + "=" + URLEncoder.encode(paramValue, HttpUtils.UTF_8).replaceAll("\\+", "%20");
+                    } else {
+                        unsignedRequest = unsignedRequest + "&" + paramName + "=" + URLEncoder.encode(paramValue, HttpUtils.UTF_8).replaceAll("\\+", "%20");
+                    }
+                }
+            }
+
+            // if api/secret key are passed to the parameters
+            if ((signature == null) || (apiKey == null)) {
+                s_logger.debug("Expired session, missing signature, or missing apiKey -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey);
+                return false; // no signature, bad request
+            }
+
+            Date expiresTS = null;
+            // FIXME: Hard coded signature, why not have an enum
+            if ("3".equals(signatureVersion)) {
+                // New signature authentication. Check for expire parameter and its validity
+                if (expires == null) {
+                    s_logger.debug("Missing Expires parameter -- ignoring request. Signature: " + signature + ", apiKey: " + apiKey);
+                    return false;
+                }
+
+                try {
+                    expiresTS = DateUtil.parseTZDateString(expires);
+                } catch (final ParseException pe) {
+                    s_logger.debug("Incorrect date format for Expires parameter", pe);
+                    return false;
+                }
+
+                final Date now = new Date(System.currentTimeMillis());
+                if (expiresTS.before(now)) {
+                    s_logger.debug("Request expired -- ignoring ...sig: " + signature + ", apiKey: " + apiKey);
+                    return false;
+                }
+            }
+
+            final TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
+            txn.close();
+            User user = null;
+            // verify there is a user with this api key
+            final Pair<User, Account> userAcctPair = accountMgr.findUserByApiKey(apiKey);
+            if (userAcctPair == null) {
+                s_logger.debug("apiKey does not map to a valid user -- ignoring request, apiKey: " + apiKey);
+                return false;
+            }
+
+            user = userAcctPair.first();
+            final Account account = userAcctPair.second();
+
+            if (user.getState() != Account.State.enabled || !account.getState().equals(Account.State.enabled)) {
+                s_logger.info("disabled or locked user accessing the api, userid = " + user.getId() + "; name = " + user.getUsername() + "; state: " + user.getState() +
+                        "; accountState: " + account.getState());
+                return false;
+            }
+
+            if (!commandAvailable(remoteAddress, commandName, user)) {
+                return false;
+            }
+
+            // verify secret key exists
+            secretKey = user.getSecretKey();
+            if (secretKey == null) {
+                s_logger.info("User does not have a secret key associated with the account -- ignoring request, username: " + user.getUsername());
+                return false;
+            }
+
+            unsignedRequest = unsignedRequest.toLowerCase();
+
+            final Mac mac = Mac.getInstance("HmacSHA1");
+            final SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
+            mac.init(keySpec);
+            mac.update(unsignedRequest.getBytes());
+
+            final byte[] encryptedBytes = mac.doFinal();
+            final String computedSignature = Base64.encodeBase64String(encryptedBytes);
+            final boolean equalSig = ConstantTimeComparator.compareStrings(signature, computedSignature);
+
+            if (!equalSig) {
+                s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
+            } else {
+                CallContext.register(user, account);
+            }
+            return equalSig;
+        } catch (final ServerApiException ex) {
+            throw ex;
+        } catch (final Exception ex) {
+            s_logger.error("unable to verify request signature");
+        }
+        return false;
+    }
+
+    private boolean commandAvailable(final InetAddress remoteAddress, final String commandName, final User user) {
+        try {
+            checkCommandAvailable(user, commandName, remoteAddress);
+        } catch (final RequestLimitException ex) {
+            s_logger.debug(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage());
+        }  catch (final UnavailableCommandException ex) {
+            s_logger.debug(ex.getMessage());
+            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, ex.getMessage());
+        } catch (final PermissionDeniedException ex) {
+            final String errorMessage = "The given command '" + commandName + "' either does not exist, is not available" +
+                    " for user, or not available from ip address '" + remoteAddress + "'.";
+            s_logger.debug(errorMessage);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Long fetchDomainId(final String domainUUID) {
+        final Domain domain = domainMgr.getDomain(domainUUID);
+        if (domain != null)
+            return domain.getId();
+        else
+            return null;
+    }
+
+    private ResponseObject createLoginResponse(HttpSession session) {
+        LoginCmdResponse response = new LoginCmdResponse();
+        response.setTimeout(session.getMaxInactiveInterval());
+
+        final String user_UUID = (String)session.getAttribute("user_UUID");
+        response.setUserId(user_UUID);
+
+        final String domain_UUID = (String)session.getAttribute("domain_UUID");
+        response.setDomainId(domain_UUID);
+
+        synchronized (session) {
+            session.removeAttribute("user_UUID");
+            session.removeAttribute("domain_UUID");
+        }
+
+        final Enumeration attrNames = session.getAttributeNames();
+        if (attrNames != null) {
+            while (attrNames.hasMoreElements()) {
+                final String attrName = (String) attrNames.nextElement();
+                final Object attrObj = session.getAttribute(attrName);
+                if (ApiConstants.USERNAME.equalsIgnoreCase(attrName)) {
+                    response.setUsername(attrObj.toString());
+                }
+                if (ApiConstants.ACCOUNT.equalsIgnoreCase(attrName)) {
+                    response.setAccount(attrObj.toString());
+                }
+                if (ApiConstants.FIRSTNAME.equalsIgnoreCase(attrName)) {
+                    response.setFirstName(attrObj.toString());
+                }
+                if (ApiConstants.LASTNAME.equalsIgnoreCase(attrName)) {
+                    response.setLastName(attrObj.toString());
+                }
+                if (ApiConstants.TYPE.equalsIgnoreCase(attrName)) {
+                    response.setType((attrObj.toString()));
+                }
+                if (ApiConstants.TIMEZONE.equalsIgnoreCase(attrName)) {
+                    response.setTimeZone(attrObj.toString());
+                }
+                if (ApiConstants.TIMEZONEOFFSET.equalsIgnoreCase(attrName)) {
+                    response.setTimeZoneOffset(attrObj.toString());
+                }
+                if (ApiConstants.REGISTERED.equalsIgnoreCase(attrName)) {
+                    response.setRegistered(attrObj.toString());
+                }
+                if (ApiConstants.SESSIONKEY.equalsIgnoreCase(attrName)) {
+                    response.setSessionKey(attrObj.toString());
+                }
+            }
+        }
+        response.setResponseName("loginresponse");
+        return response;
+    }
+
+    @Override
+    public ResponseObject loginUser(final HttpSession session, final String username, final String password, Long domainId, final String domainPath, final InetAddress loginIpAddress,
+            final Map<String, Object[]> requestParameters) throws CloudAuthenticationException {
+        // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist
+        // we will default to ROOT
+        final Domain userDomain = domainMgr.findDomainByIdOrPath(domainId, domainPath);
+        if (userDomain == null || userDomain.getId() < 1L) {
+            throw new CloudAuthenticationException("Unable to find the domain from the path " + domainPath);
+        } else {
+            domainId = userDomain.getId();
+        }
+
+        final UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
+        if (userAcct != null) {
+            final String timezone = userAcct.getTimezone();
+            float offsetInHrs = 0f;
+            if (timezone != null) {
+                final TimeZone t = TimeZone.getTimeZone(timezone);
+                s_logger.info("Current user logged in under " + timezone + " timezone");
+
+                final java.util.Date date = new java.util.Date();
+                final long longDate = date.getTime();
+                final float offsetInMs = (t.getOffset(longDate));
+                offsetInHrs = offsetInMs / (1000 * 60 * 60);
+                s_logger.info("Timezone offset from UTC is: " + offsetInHrs);
+            }
+
+            final Account account = accountMgr.getAccount(userAcct.getAccountId());
+
+            // set the userId and account object for everyone
+            session.setAttribute("userid", userAcct.getId());
+            final UserVO user = (UserVO)accountMgr.getActiveUser(userAcct.getId());
+            if (user.getUuid() != null) {
+                session.setAttribute("user_UUID", user.getUuid());
+            }
+
+            session.setAttribute("username", userAcct.getUsername());
+            session.setAttribute("firstname", userAcct.getFirstname());
+            session.setAttribute("lastname", userAcct.getLastname());
+            session.setAttribute("accountobj", account);
+            session.setAttribute("account", account.getAccountName());
+
+            session.setAttribute("domainid", account.getDomainId());
+            final DomainVO domain = (DomainVO)domainMgr.getDomain(account.getDomainId());
+            if (domain.getUuid() != null) {
+                session.setAttribute("domain_UUID", domain.getUuid());
+            }
+
+            session.setAttribute("type", Short.valueOf(account.getType()).toString());
+            session.setAttribute("registrationtoken", userAcct.getRegistrationToken());
+            session.setAttribute("registered", Boolean.toString(userAcct.isRegistered()));
+
+            if (timezone != null) {
+                session.setAttribute("timezone", timezone);
+                session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString());
+            }
+
+            // (bug 5483) generate a session key that the user must submit on every request to prevent CSRF, add that
+            // to the login response so that session-based authenticators know to send the key back
+            final SecureRandom sesssionKeyRandom = new SecureRandom();
+            final byte sessionKeyBytes[] = new byte[20];
+            sesssionKeyRandom.nextBytes(sessionKeyBytes);
+            final String sessionKey = Base64.encodeBase64URLSafeString(sessionKeyBytes);
+            session.setAttribute(ApiConstants.SESSIONKEY, sessionKey);
+
+            return createLoginResponse(session);
+        }
+        throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials");
+    }
+
+    @Override
+    public void logoutUser(final long userId) {
+        accountMgr.logoutUser(userId);
+        return;
+    }
+
+    @Override
+    public boolean verifyUser(final Long userId) {
+        final User user = accountMgr.getUserIncludingRemoved(userId);
+        Account account = null;
+        if (user != null) {
+            account = accountMgr.getAccount(user.getAccountId());
+        }
+
+        if ((user == null) || (user.getRemoved() != null) || !user.getState().equals(Account.State.enabled) || (account == null) ||
+                !account.getState().equals(Account.State.enabled)) {
+            s_logger.warn("Deleted/Disabled/Locked user with id=" + userId + " attempting to access public API");
+            return false;
+        }
+        return true;
+    }
+
+    private void checkCommandAvailable(final User user, final String commandName, final InetAddress remoteAddress) throws PermissionDeniedException {
+        if (user == null) {
+            throw new PermissionDeniedException("User is null for role based API access check for command" + commandName);
+        }
+
+        final Account account = accountMgr.getAccount(user.getAccountId());
+        final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s","");
+        final Boolean apiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
+
+        if (apiSourceCidrChecksEnabled) {
+            s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs);
+            if (!NetUtils.isIpInCidrList(remoteAddress, accessAllowedCidrs.split(","))) {
+                s_logger.warn("Request by account '" + account.toString() + "' was denied since " + remoteAddress + " does not match " + accessAllowedCidrs);
+                throw new PermissionDeniedException("Calls for domain '" + account.getAccountName() + "' are not allowed from ip address '" + remoteAddress.getHostAddress());
+                }
+        }
+
+
+        for (final APIChecker apiChecker : apiAccessCheckers) {
+            apiChecker.checkAccess(user, commandName);
+        }
+    }
+
+    @Override
+    public Class<?> getCmdClass(String cmdName) {
+        List<Class<?>> cmdList = s_apiNameCmdClassMap.get(cmdName);
+        if (cmdList == null || cmdList.size() == 0)
+            return null;
+        else if (cmdList.size() == 1)
+            return cmdList.get(0);
+        else {
+            // determine the cmd class based on calling context
+            ResponseView view = ResponseView.Restricted;
+            if (CallContext.current() != null
+                    && accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())) {
+                view = ResponseView.Full;
+            }
+            for (Class<?> cmdClass : cmdList) {
+                APICommand at = cmdClass.getAnnotation(APICommand.class);
+                if (at == null) {
+                    throw new CloudRuntimeException(String.format("%s is claimed as a API command, but it doesn't have @APICommand annotation", cmdClass.getName()));
+                }
+                if (at.responseView() == null) {
+                    throw new CloudRuntimeException(String.format(
+                            "%s @APICommand annotation should specify responseView attribute to distinguish multiple command classes for a single api name", cmdClass.getName()));
+                } else if (at.responseView() == view) {
+                    return cmdClass;
+                }
+            }
+            return null;
+        }
+    }
+
+    // FIXME: rather than isError, we might was to pass in the status code to give more flexibility
+    private void writeResponse(final HttpResponse resp, final String responseText, final int statusCode, final String responseType, final String reasonPhrase) {
+        try {
+            resp.setStatusCode(statusCode);
+            resp.setReasonPhrase(reasonPhrase);
+
+            final BasicHttpEntity body = new BasicHttpEntity();
+            if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
+                // JSON response
+                body.setContentType(JSONcontentType.value());
+                if (responseText == null) {
+                    body.setContent(new ByteArrayInputStream("{ \"error\" : { \"description\" : \"Internal Server Error\" } }".getBytes(HttpUtils.UTF_8)));
+                }
+            } else {
+                body.setContentType("text/xml");
+                if (responseText == null) {
+                    body.setContent(new ByteArrayInputStream("<error>Internal Server Error</error>".getBytes(HttpUtils.UTF_8)));
+                }
+            }
+
+            if (responseText != null) {
+                body.setContent(new ByteArrayInputStream(responseText.getBytes(HttpUtils.UTF_8)));
+            }
+            resp.setEntity(body);
+        } catch (final Exception ex) {
+            s_logger.error("error!", ex);
+        }
+    }
+
+    // FIXME: the following two threads are copied from
+    // http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpServer.java
+    // we have to cite a license if we are using this code directly, so we need to add the appropriate citation or
+    // modify the
+    // code to be very specific to our needs
+    static class ListenerThread extends Thread {
+        private HttpService _httpService = null;
+        private ServerSocket _serverSocket = null;
+        private HttpParams _params = null;
+
+        public ListenerThread(final ApiServer requestHandler, final int port) {
+            try {
+                _serverSocket = new ServerSocket(port);
+            } catch (final IOException ioex) {
+                s_logger.error("error initializing api server", ioex);
+                return;
+            }
+
+            _params = new BasicHttpParams();
+            _params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
+            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
+            .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
+            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
+            .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
+
+            // Set up the HTTP protocol processor
+            final BasicHttpProcessor httpproc = new BasicHttpProcessor();
+            httpproc.addInterceptor(new ResponseDate());
+            httpproc.addInterceptor(new ResponseServer());
+            httpproc.addInterceptor(new ResponseContent());
+            httpproc.addInterceptor(new ResponseConnControl());
+
+            // Set up request handlers
+            final HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+            reqistry.register("*", requestHandler);
+
+            // Set up the HTTP service
+            _httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory());
+            _httpService.setParams(_params);
+            _httpService.setHandlerResolver(reqistry);
+        }
+
+        @Override
+        public void run() {
+            s_logger.info("ApiServer listening on port " + _serverSocket.getLocalPort());
+            while (!Thread.interrupted()) {
+                try {
+                    // Set up HTTP connection
+                    final Socket socket = _serverSocket.accept();
+                    final DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
+                    conn.bind(socket, _params);
+
+                    // Execute a new worker task to handle the request
+                    s_executor.execute(new WorkerTask(_httpService, conn, s_workerCount++));
+                } catch (final InterruptedIOException ex) {
+                    break;
+                } catch (final IOException e) {
+                    s_logger.error("I/O error initializing connection thread", e);
+                    break;
+                }
+            }
+        }
+    }
+
+    static class WorkerTask extends ManagedContextRunnable {
+        private final HttpService _httpService;
+        private final HttpServerConnection _conn;
+
+        public WorkerTask(final HttpService httpService, final HttpServerConnection conn, final int count) {
+            _httpService = httpService;
+            _conn = conn;
+        }
+
+        @Override
+        protected void runInContext() {
+            final HttpContext context = new BasicHttpContext(null);
+            try {
+                while (!Thread.interrupted() && _conn.isOpen()) {
+                    _httpService.handleRequest(_conn, context);
+                    _conn.close();
+                }
+            } catch (final ConnectionClosedException ex) {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("ApiServer:  Client closed connection");
+                }
+            } catch (final IOException ex) {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("ApiServer:  IOException - " + ex);
+                }
+            } catch (final HttpException ex) {
+                s_logger.warn("ApiServer:  Unrecoverable HTTP protocol violation" + ex);
+            } finally {
+                try {
+                    _conn.shutdown();
+                } catch (final IOException ignore) {
+                }
+            }
+        }
+    }
+
+    @Override
+    public String getSerializedApiError(final int errorCode, final String errorText, final Map<String, Object[]> apiCommandParams, final String responseType) {
+        String responseName = null;
+        Class<?> cmdClass = null;
+        String responseText = null;
+
+        try {
+            if (apiCommandParams == null || apiCommandParams.isEmpty()) {
+                responseName = "errorresponse";
+            } else {
+                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
+                // cmd name can be null when "command" parameter is missing in the request
+                if (cmdObj != null) {
+                    final String cmdName = ((String[])cmdObj)[0];
+                    cmdClass = getCmdClass(cmdName);
+                    if (cmdClass != null) {
+                        responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
+                    } else {
+                        responseName = "errorresponse";
+                    }
+                }
+            }
+            final ExceptionResponse apiResponse = new ExceptionResponse();
+            apiResponse.setErrorCode(errorCode);
+            apiResponse.setErrorText(errorText);
+            apiResponse.setResponseName(responseName);
+            SerializationContext.current().setUuidTranslation(true);
+            responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
+
+        } catch (final Exception e) {
+            s_logger.error("Exception responding to http request", e);
+        }
+        return responseText;
+    }
+
+    @Override
+    public String getSerializedApiError(final ServerApiException ex, final Map<String, Object[]> apiCommandParams, final String responseType) {
+        String responseName = null;
+        Class<?> cmdClass = null;
+        String responseText = null;
+
+        if (ex == null) {
+            // this call should not be invoked with null exception
+            return getSerializedApiError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Some internal error happened", apiCommandParams, responseType);
+        }
+        try {
+            if (ex.getErrorCode() == ApiErrorCode.UNSUPPORTED_ACTION_ERROR || apiCommandParams == null || apiCommandParams.isEmpty()) {
+                responseName = "errorresponse";
+            } else {
+                final Object cmdObj = apiCommandParams.get(ApiConstants.COMMAND);
+                // cmd name can be null when "command" parameter is missing in
+                // the request
+                if (cmdObj != null) {
+                    final String cmdName = ((String[])cmdObj)[0];
+                    cmdClass = getCmdClass(cmdName);
+                    if (cmdClass != null) {
+                        responseName = ((BaseCmd)cmdClass.newInstance()).getCommandName();
+                    } else {
+                        responseName = "errorresponse";
+                    }
+                }
+            }
+            final ExceptionResponse apiResponse = new ExceptionResponse();
+            apiResponse.setErrorCode(ex.getErrorCode().getHttpCode());
+            apiResponse.setErrorText(ex.getDescription());
+            apiResponse.setResponseName(responseName);
+            final ArrayList<ExceptionProxyObject> idList = ex.getIdProxyList();
+            if (idList != null) {
+                for (int i = 0; i < idList.size(); i++) {
+                    apiResponse.addProxyObject(idList.get(i));
+                }
+            }
+            // Also copy over the cserror code and the function/layer in which
+            // it was thrown.
+            apiResponse.setCSErrorCode(ex.getCSErrorCode());
+
+            SerializationContext.current().setUuidTranslation(true);
+            responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType);
+
+        } catch (final Exception e) {
+            s_logger.error("Exception responding to http request", e);
+        }
+        return responseText;
+    }
+
+    @Inject
+    public void setPluggableServices(final List<PluggableService> pluggableServices) {
+        this.pluggableServices = pluggableServices;
+    }
+
+    @Inject
+    public void setApiAccessCheckers(final List<APIChecker> apiAccessCheckers) {
+        this.apiAccessCheckers = apiAccessCheckers;
+    }
+
+    public static boolean isEncodeApiResponse() {
+        return ApiServer.encodeApiResponse;
+    }
+
+    private static void setEncodeApiResponse(final boolean encodeApiResponse) {
+        ApiServer.encodeApiResponse = encodeApiResponse;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ApiServer.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {
+                IntegrationAPIPort,
+                ConcurrentSnapshotsThresholdPerHost,
+                EncodeApiResponse,
+                EnableSecureSessionCookie,
+                JSONDefaultContentType
+        };
+    }
+}
diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/main/java/com/cloud/api/ApiServlet.java
similarity index 100%
rename from server/src/com/cloud/api/ApiServlet.java
rename to server/src/main/java/com/cloud/api/ApiServlet.java
diff --git a/server/src/com/cloud/api/EncodedStringTypeAdapter.java b/server/src/main/java/com/cloud/api/EncodedStringTypeAdapter.java
similarity index 100%
rename from server/src/com/cloud/api/EncodedStringTypeAdapter.java
rename to server/src/main/java/com/cloud/api/EncodedStringTypeAdapter.java
diff --git a/server/src/com/cloud/api/ResponseObjectTypeAdapter.java b/server/src/main/java/com/cloud/api/ResponseObjectTypeAdapter.java
similarity index 100%
rename from server/src/com/cloud/api/ResponseObjectTypeAdapter.java
rename to server/src/main/java/com/cloud/api/ResponseObjectTypeAdapter.java
diff --git a/server/src/com/cloud/api/SerializationContext.java b/server/src/main/java/com/cloud/api/SerializationContext.java
similarity index 100%
rename from server/src/com/cloud/api/SerializationContext.java
rename to server/src/main/java/com/cloud/api/SerializationContext.java
diff --git a/server/src/com/cloud/api/StringMapTypeAdapter.java b/server/src/main/java/com/cloud/api/StringMapTypeAdapter.java
similarity index 100%
rename from server/src/com/cloud/api/StringMapTypeAdapter.java
rename to server/src/main/java/com/cloud/api/StringMapTypeAdapter.java
diff --git a/server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java b/server/src/main/java/com/cloud/api/auth/APIAuthenticationManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/api/auth/APIAuthenticationManagerImpl.java
rename to server/src/main/java/com/cloud/api/auth/APIAuthenticationManagerImpl.java
diff --git a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java b/server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
similarity index 100%
rename from server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
rename to server/src/main/java/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
diff --git a/server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java b/server/src/main/java/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
similarity index 100%
rename from server/src/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
rename to server/src/main/java/com/cloud/api/auth/DefaultLogoutAPIAuthenticatorCmd.java
diff --git a/server/src/com/cloud/api/dispatch/CommandCreationWorker.java b/server/src/main/java/com/cloud/api/dispatch/CommandCreationWorker.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/CommandCreationWorker.java
rename to server/src/main/java/com/cloud/api/dispatch/CommandCreationWorker.java
diff --git a/server/src/com/cloud/api/dispatch/DispatchChain.java b/server/src/main/java/com/cloud/api/dispatch/DispatchChain.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/DispatchChain.java
rename to server/src/main/java/com/cloud/api/dispatch/DispatchChain.java
diff --git a/server/src/com/cloud/api/dispatch/DispatchChainFactory.java b/server/src/main/java/com/cloud/api/dispatch/DispatchChainFactory.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/DispatchChainFactory.java
rename to server/src/main/java/com/cloud/api/dispatch/DispatchChainFactory.java
diff --git a/server/src/com/cloud/api/dispatch/DispatchTask.java b/server/src/main/java/com/cloud/api/dispatch/DispatchTask.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/DispatchTask.java
rename to server/src/main/java/com/cloud/api/dispatch/DispatchTask.java
diff --git a/server/src/com/cloud/api/dispatch/DispatchWorker.java b/server/src/main/java/com/cloud/api/dispatch/DispatchWorker.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/DispatchWorker.java
rename to server/src/main/java/com/cloud/api/dispatch/DispatchWorker.java
diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamGenericValidationWorker.java
new file mode 100644
index 0000000..45d4ed7
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/dispatch/ParamGenericValidationWorker.java
@@ -0,0 +1,117 @@
+// 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.api.dispatch;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.log4j.Logger;
+
+/**
+ * This worker validates parameters in a generic way, by using annotated
+ * restrictions without involving the {@Link BaseCmd}. This worker doesn't
+ * know or care about the meaning of the parameters and that's why we can
+ * have it out of the {@Link BaseCmd}
+ *
+ * @author afornie
+ */
+public class ParamGenericValidationWorker implements DispatchWorker {
+
+    static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
+
+    protected static final List<String> defaultParamNames = new ArrayList<String>();
+
+    static {
+        defaultParamNames.add(ApiConstants.ACCOUNT_ID);
+        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
+        defaultParamNames.add(ApiConstants.COMMAND);
+        defaultParamNames.add(ApiConstants.CMD_EVENT_TYPE);
+        defaultParamNames.add(ApiConstants.USERNAME);
+        defaultParamNames.add(ApiConstants.USER_ID);
+        defaultParamNames.add(ApiConstants.PASSWORD);
+        defaultParamNames.add(ApiConstants.DOMAIN);
+        defaultParamNames.add(ApiConstants.DOMAIN_ID);
+        defaultParamNames.add(ApiConstants.DOMAIN__ID);
+        defaultParamNames.add(ApiConstants.SESSIONKEY);
+        defaultParamNames.add(ApiConstants.RESPONSE);
+        defaultParamNames.add(ApiConstants.PAGE);
+        defaultParamNames.add(ApiConstants.USER_API_KEY);
+        defaultParamNames.add(ApiConstants.API_KEY);
+        defaultParamNames.add(ApiConstants.PAGE_SIZE);
+        defaultParamNames.add(ApiConstants.HTTPMETHOD);
+        defaultParamNames.add(ApiConstants.SIGNATURE);
+        defaultParamNames.add(ApiConstants.CTX_ACCOUNT_ID);
+        defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
+        defaultParamNames.add(ApiConstants.CTX_USER_ID);
+        defaultParamNames.add(ApiConstants.CTX_DETAILS);
+        defaultParamNames.add(ApiConstants.UUID);
+        defaultParamNames.add(ApiConstants.ID);
+        defaultParamNames.add(ApiConstants.SIGNATURE_VERSION);
+        defaultParamNames.add(ApiConstants.EXPIRES);
+        defaultParamNames.add("_");
+    }
+
+    protected static final String ERROR_MSG_PREFIX = "Unknown parameters :";
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public void handle(final DispatchTask task) {
+        final BaseCmd cmd = task.getCmd();
+        final Map params = task.getParams();
+
+        final List<String> expectedParamNames = getParamNamesForCommand(cmd);
+
+        final StringBuilder errorMsg = new StringBuilder(ERROR_MSG_PREFIX);
+        boolean foundUnknownParam = false;
+        for (final Object actualParamName : params.keySet()) {
+            // If none of the expected params matches, we have an unknown param
+            boolean matchedCurrentParam = false;
+            for (final String expectedName : expectedParamNames) {
+                if (expectedName.equalsIgnoreCase((String) actualParamName)) {
+                    matchedCurrentParam = true;
+                    break;
+                }
+            }
+            if (!matchedCurrentParam && !((String)actualParamName).equalsIgnoreCase("expires") && !((String)actualParamName).equalsIgnoreCase("signatureversion")) {
+                errorMsg.append(" ").append(actualParamName);
+                foundUnknownParam= true;
+            }
+        }
+
+        if (foundUnknownParam) {
+            s_logger.warn(String.format("Received unknown parameters for command %s. %s", cmd.getActualCommandName(), errorMsg));
+        }
+    }
+
+    protected List<String> getParamNamesForCommand(final BaseCmd cmd) {
+        final List<String> paramNames = new ArrayList<String>();
+        // The expected param names are all the specific for the current command class ...
+        for (final Field field : cmd.getParamFields()) {
+            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+            paramNames.add(parameterAnnotation.name());
+        }
+        // ... plus the default ones
+        paramNames.addAll(defaultParamNames);
+        return paramNames;
+    }
+}
diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java
new file mode 100644
index 0000000..970e62f
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java
@@ -0,0 +1,508 @@
+// 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.api.dispatch;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.InfrastructureEntity;
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.ApiArgValidator;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.EntityReference;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
+import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
+import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
+import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.base.Strings;
+
+public class ParamProcessWorker implements DispatchWorker {
+
+    private static final Logger s_logger = Logger.getLogger(ParamProcessWorker.class.getName());
+    public final DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
+    public final DateFormat newInputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @Inject
+    protected AccountManager _accountMgr;
+
+    @Inject
+    protected EntityManager _entityMgr;
+
+    List<SecurityChecker> _secChecker;
+
+    public List<SecurityChecker> getSecChecker() {
+        return _secChecker;
+    }
+
+    @Inject
+    public void setSecChecker(List<SecurityChecker> secChecker) {
+        _secChecker = secChecker;
+    }
+
+    @Override
+    public void handle(final DispatchTask task) {
+        processParameters(task.getCmd(), task.getParams());
+    }
+
+    private void validateNonEmptyString(final Object param, final String argName) {
+        if (param == null || Strings.isNullOrEmpty(param.toString())) {
+            throw new InvalidParameterValueException(String.format("Empty or null value provided for API arg: %s", argName));
+        }
+    }
+
+    private void validateNaturalNumber(final Object param, final String argName) {
+        Long value = null;
+        if (param != null && param instanceof Long) {
+            value = (Long) param;
+        } else if (param != null) {
+            value = Long.valueOf(param.toString());
+        }
+        if (value == null || value < 1L) {
+            throw new InvalidParameterValueException(String.format("Invalid value provided for API arg: %s", argName));
+        }
+    }
+
+    private void validateField(final Object paramObj, final Parameter annotation) throws ServerApiException {
+        if (annotation == null) {
+            return;
+        }
+        final String argName = annotation.name();
+        for (final ApiArgValidator validator : annotation.validations()) {
+            if (validator == null) {
+                continue;
+            }
+            switch (validator) {
+                case NotNullOrEmpty:
+                    switch (annotation.type()) {
+                        case UUID:
+                        case STRING:
+                            validateNonEmptyString(paramObj, argName);
+                            break;
+                    }
+                    break;
+                case PositiveNumber:
+                    switch (annotation.type()) {
+                        case SHORT:
+                        case INTEGER:
+                        case LONG:
+                            validateNaturalNumber(paramObj, argName);
+                            break;
+                    }
+                    break;
+            }
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public void processParameters(final BaseCmd cmd, final Map params) {
+        final Map<Object, AccessType> entitiesToAccess = new HashMap<Object, AccessType>();
+
+        final List<Field> cmdFields = cmd.getParamFields();
+
+        for (final Field field : cmdFields) {
+            final Parameter parameterAnnotation = field.getAnnotation(Parameter.class);
+            final Object paramObj = params.get(parameterAnnotation.name());
+            if (paramObj == null) {
+                if (parameterAnnotation.required()) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                            cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) +
+                            " due to missing parameter " + parameterAnnotation.name());
+                }
+                continue;
+            }
+
+            // marshall the parameter into the correct type and set the field value
+            try {
+                validateField(paramObj, parameterAnnotation);
+                setFieldValue(field, cmd, paramObj, parameterAnnotation);
+            } catch (final IllegalArgumentException argEx) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Unable to execute API command " + cmd.getCommandName() + " due to invalid value " + paramObj + " for parameter " +
+                            parameterAnnotation.name());
+                }
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value " + paramObj + " for parameter " +
+                        parameterAnnotation.name());
+            } catch (final ParseException parseEx) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Invalid date parameter " + paramObj + " passed to command " + cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+                }
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to parse date " + paramObj + " for command " +
+                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + ", please pass dates in the format mentioned in the api documentation");
+            } catch (final InvalidParameterValueException invEx) {
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to execute API command " +
+                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8) + " due to invalid value. " + invEx.getMessage());
+            } catch (final CloudRuntimeException cloudEx) {
+                s_logger.error("CloudRuntimeException", cloudEx);
+                // FIXME: Better error message? This only happens if the API command is not executable, which typically
+                //means
+                // there was
+                // and IllegalAccessException setting one of the parameters.
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Internal error executing API command " +
+                        cmd.getCommandName().substring(0, cmd.getCommandName().length() - 8));
+            }
+
+            //check access on the resource this field points to
+            try {
+                final ACL checkAccess = field.getAnnotation(ACL.class);
+                final CommandType fieldType = parameterAnnotation.type();
+
+                if (checkAccess != null) {
+                    // Verify that caller can perform actions in behalf of vm
+                    // owner acumulate all Controlled Entities together.
+                    // parse the array of resource types and in case of map
+                    // check access on key or value or both as specified in @acl
+                    // implement external dao for classes that need findByName
+                    // for maps, specify access to be checkd on key or value.
+                    // Find the controlled entity DBid by uuid
+
+                    if (parameterAnnotation.entityType() != null && parameterAnnotation.entityType().length > 0
+                            && parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class) != null) {
+                        final Class<?>[] entityList = parameterAnnotation.entityType()[0].getAnnotation(EntityReference.class).value();
+
+                        // Check if the parameter type is a single
+                        // Id or list of id's/name's
+                        switch (fieldType) {
+                        case LIST:
+                            final CommandType listType = parameterAnnotation.collectionType();
+                            switch (listType) {
+                            case LONG:
+                            case UUID:
+                                final List<Long> listParam = (List<Long>) field.get(cmd);
+                                for (final Long entityId : listParam) {
+                                    for (final Class entity : entityList) {
+                                        final Object entityObj = _entityMgr.findById(entity, entityId);
+                                        if(entityObj != null){
+                                            entitiesToAccess.put(entityObj, checkAccess.accessType());
+                                            break;
+                                        }
+                                    }
+                                }
+                                break;
+                                /*
+                                 * case STRING: List<String> listParam = new
+                                 * ArrayList<String>(); listParam =
+                                 * (List)field.get(cmd); for(String entityName:
+                                 * listParam){ ControlledEntity entityObj =
+                                 * (ControlledEntity )daoClassInstance(entityId);
+                                 * entitiesToAccess.add(entityObj); } break;
+                                 */
+                            default:
+                                break;
+                            }
+                            break;
+                        case LONG:
+                        case UUID:
+                            for (final Class entity : entityList) {
+                                final Object entityObj = _entityMgr.findById(entity, (Long) field.get(cmd));
+                                if(entityObj != null){
+                                    entitiesToAccess.put(entityObj, checkAccess.accessType());
+                                    break;
+                                }
+                            }
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                }
+
+            } catch (final IllegalArgumentException e) {
+                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+                        " is not accessible]", e);
+            } catch (final IllegalAccessException e) {
+                throw new CloudRuntimeException("Internal error initializing parameters for command " + cmd.getCommandName() + " [field " + field.getName() +
+                        " is not accessible]", e);
+            }
+
+        }
+
+        doAccessChecks(cmd, entitiesToAccess);
+    }
+
+
+    private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
+        Account caller = CallContext.current().getCallingAccount();
+        // due to deleteAccount design flaw CLOUDSTACK-6588, we should still include those removed account as well to clean up leftover resources from that account
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+
+        if (cmd instanceof BaseAsyncCreateCmd) {
+            // check that caller can access the owner account.
+            _accountMgr.checkAccess(caller, null, false, owner);
+        }
+
+        if (!entitiesToAccess.isEmpty()) {
+            // check that caller can access the owner account.
+            _accountMgr.checkAccess(caller, null, false, owner);
+            for (Map.Entry<Object,AccessType>entry : entitiesToAccess.entrySet()) {
+                Object entity = entry.getKey();
+                if (entity instanceof ControlledEntity) {
+                    _accountMgr.checkAccess(caller, entry.getValue(), true, (ControlledEntity) entity);
+                } else if (entity instanceof InfrastructureEntity) {
+                    // FIXME: Move this code in adapter, remove code from
+                    // Account manager
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private void setFieldValue(final Field field, final BaseCmd cmdObj, final Object paramObj, final Parameter annotation) throws IllegalArgumentException, ParseException {
+        try {
+            field.setAccessible(true);
+            final CommandType fieldType = annotation.type();
+            switch (fieldType) {
+            case BOOLEAN:
+                field.set(cmdObj, Boolean.valueOf(paramObj.toString()));
+                break;
+            case DATE:
+                // This piece of code is for maintaining backward compatibility
+                // and support both the date formats(Bug 9724)
+                if (cmdObj instanceof ListEventsCmd || cmdObj instanceof DeleteEventsCmd || cmdObj instanceof ArchiveEventsCmd ||
+                        cmdObj instanceof ArchiveAlertsCmd || cmdObj instanceof DeleteAlertsCmd || cmdObj instanceof GetUsageRecordsCmd) {
+                    final boolean isObjInNewDateFormat = isObjInNewDateFormat(paramObj.toString());
+                    if (isObjInNewDateFormat) {
+                        final DateFormat newFormat = newInputFormat;
+                        synchronized (newFormat) {
+                            field.set(cmdObj, newFormat.parse(paramObj.toString()));
+                        }
+                    } else {
+                        final DateFormat format = inputFormat;
+                        synchronized (format) {
+                            Date date = format.parse(paramObj.toString());
+                            if (field.getName().equals("startDate")) {
+                                date = messageDate(date, 0, 0, 0);
+                            } else if (field.getName().equals("endDate")) {
+                                date = messageDate(date, 23, 59, 59);
+                            }
+                            field.set(cmdObj, date);
+                        }
+                    }
+                } else {
+                    final DateFormat format = inputFormat;
+                    synchronized (format) {
+                        format.setLenient(false);
+                        field.set(cmdObj, format.parse(paramObj.toString()));
+                    }
+                }
+                break;
+            case FLOAT:
+                // Assuming that the parameters have been checked for required before now,
+                // we ignore blank or null values and defer to the command to set a default
+                // value for optional parameters ...
+                if (paramObj != null && isNotBlank(paramObj.toString())) {
+                    field.set(cmdObj, Float.valueOf(paramObj.toString()));
+                }
+                break;
+            case DOUBLE:
+                // Assuming that the parameters have been checked for required before now,
+                // we ignore blank or null values and defer to the command to set a default
+                // value for optional parameters ...
+                if (paramObj != null && isNotBlank(paramObj.toString())) {
+                    field.set(cmdObj, Double.valueOf(paramObj.toString()));
+                }
+                break;
+            case INTEGER:
+                // Assuming that the parameters have been checked for required before now,
+                // we ignore blank or null values and defer to the command to set a default
+                // value for optional parameters ...
+                if (paramObj != null && isNotBlank(paramObj.toString())) {
+                    field.set(cmdObj, Integer.valueOf(paramObj.toString()));
+                }
+                break;
+            case LIST:
+                final List listParam = new ArrayList();
+                final StringTokenizer st = new StringTokenizer(paramObj.toString(), ",");
+                while (st.hasMoreTokens()) {
+                    final String token = st.nextToken();
+                    final CommandType listType = annotation.collectionType();
+                    switch (listType) {
+                    case INTEGER:
+                        listParam.add(Integer.valueOf(token));
+                        break;
+                    case UUID:
+                        if (token.isEmpty())
+                            break;
+                        final Long internalId = translateUuidToInternalId(token, annotation);
+                        listParam.add(internalId);
+                        break;
+                    case LONG: {
+                        listParam.add(Long.valueOf(token));
+                    }
+                    break;
+                    case SHORT:
+                        listParam.add(Short.valueOf(token));
+                        break;
+                    case STRING:
+                        listParam.add(token);
+                        break;
+                    }
+                }
+                field.set(cmdObj, listParam);
+                break;
+            case UUID:
+                final Long internalId = translateUuidToInternalId(paramObj.toString(), annotation);
+                field.set(cmdObj, internalId);
+                break;
+            case LONG:
+                field.set(cmdObj, Long.valueOf(paramObj.toString()));
+                break;
+            case SHORT:
+                field.set(cmdObj, Short.valueOf(paramObj.toString()));
+                break;
+            case STRING:
+                if ((paramObj != null)) {
+                    if (paramObj.toString().length() > annotation.length()) {
+                        s_logger.error("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+                        throw new InvalidParameterValueException("Value greater than max allowed length " + annotation.length() + " for param: " + field.getName());
+                    } else {
+                        field.set(cmdObj, paramObj.toString());
+                    }
+                }
+                break;
+            case TZDATE:
+                field.set(cmdObj, DateUtil.parseTZDateString(paramObj.toString()));
+                break;
+            case MAP:
+            default:
+                field.set(cmdObj, paramObj);
+                break;
+            }
+        } catch (final IllegalAccessException ex) {
+            s_logger.error("Error initializing command " + cmdObj.getCommandName() + ", field " + field.getName() + " is not accessible.");
+            throw new CloudRuntimeException("Internal error initializing parameters for command " + cmdObj.getCommandName() + " [field " + field.getName() +
+                    " is not accessible]");
+        }
+    }
+
+    private boolean isObjInNewDateFormat(final String string) {
+        final Matcher matcher = BaseCmd.newInputDateFormat.matcher(string);
+        return matcher.matches();
+    }
+
+    private Date messageDate(final Date date, final int hourOfDay, final int minute, final int second) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+        return cal.getTime();
+    }
+
+    private Long translateUuidToInternalId(final String uuid, final Parameter annotation) {
+        if (uuid.equals("-1")) {
+            // FIXME: This is to handle a lot of hardcoded special cases where -1 is sent
+            // APITODO: Find and get rid of all hardcoded params in API Cmds and service layer
+            return -1L;
+        }
+        Long internalId = null;
+        // If annotation's empty, the cmd existed before 3.x try conversion to long
+        final boolean isPre3x = annotation.since().isEmpty();
+        // Match against Java's UUID regex to check if input is uuid string
+        final boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
+        // Enforce that it's uuid for newly added apis from version 3.x
+        if (!isPre3x && !isUuid)
+            return null;
+
+        // There may be multiple entities defined on the @EntityReference of a Response.class
+        // UUID CommandType would expect only one entityType, so use the first entityType
+        final Class<?>[] entities = annotation.entityType()[0].getAnnotation(EntityReference.class).value();
+
+        // Allow both uuid and internal id for pre3x apis
+        if (isPre3x && !isUuid) {
+            try {
+                internalId = Long.parseLong(uuid);
+            } catch (final NumberFormatException e) {
+                internalId = null;
+            }
+            if (internalId != null){
+                // Populate CallContext for each of the entity.
+                for (final Class<?> entity : entities) {
+                    CallContext.current().putContextParameter(entity, internalId);
+                }
+                validateNaturalNumber(internalId, annotation.name());
+                return internalId;
+            }
+        }
+
+        // Go through each entity which is an interface to a VO class and get a VO object
+        // Try to getId() for the object using reflection, break on first non-null value
+        for (final Class<?> entity : entities) {
+            // For backward compatibility, we search within removed entities and let service layer deal
+            // with removed ones, return empty response or error
+            final Object objVO = _entityMgr.findByUuidIncludingRemoved(entity, uuid);
+            if (objVO == null) {
+                continue;
+            }
+            // Invoke the getId method, get the internal long ID
+            // If that fails hide exceptions as the uuid may not exist                                         s
+            try {
+                internalId = ((InternalIdentity)objVO).getId();
+            } catch (final IllegalArgumentException e) {
+            } catch (final NullPointerException e) {
+            }
+            // Return on first non-null Id for the uuid entity
+            if (internalId != null){
+                CallContext.current().putContextParameter(entity, uuid);
+                break;
+            }
+        }
+        if (internalId == null) {
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("Object entity uuid = " + uuid + " does not exist in the database.");
+            throw new InvalidParameterValueException("Invalid parameter " + annotation.name() + " value=" + uuid +
+                    " due to incorrect long value format, or entity does not exist or due to incorrect parameter annotation for the field in api cmd class.");
+        }
+        validateNaturalNumber(internalId, annotation.name());
+        return internalId;
+    }
+}
diff --git a/server/src/com/cloud/api/dispatch/ParamUnpackWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamUnpackWorker.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/ParamUnpackWorker.java
rename to server/src/main/java/com/cloud/api/dispatch/ParamUnpackWorker.java
diff --git a/server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java b/server/src/main/java/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
similarity index 100%
rename from server/src/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
rename to server/src/main/java/com/cloud/api/dispatch/SpecificCmdValidationWorker.java
diff --git a/server/src/com/cloud/api/doc/Alert.java b/server/src/main/java/com/cloud/api/doc/Alert.java
similarity index 100%
rename from server/src/com/cloud/api/doc/Alert.java
rename to server/src/main/java/com/cloud/api/doc/Alert.java
diff --git a/server/src/com/cloud/api/doc/ApiXmlDocReader.java b/server/src/main/java/com/cloud/api/doc/ApiXmlDocReader.java
similarity index 100%
rename from server/src/com/cloud/api/doc/ApiXmlDocReader.java
rename to server/src/main/java/com/cloud/api/doc/ApiXmlDocReader.java
diff --git a/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java
new file mode 100644
index 0000000..916c78f
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java
@@ -0,0 +1,439 @@
+// 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.api.doc;
+
+import com.cloud.alert.AlertManager;
+import com.cloud.serializer.Param;
+import com.cloud.utils.IteratorUtil;
+import com.cloud.utils.ReflectUtil;
+import com.google.gson.annotations.SerializedName;
+import com.thoughtworks.xstream.XStream;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.IPAddressResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.SnapshotResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ApiXmlDocWriter {
+    public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName());
+
+    private static String s_dirName = "";
+    private static Map<String, Class<?>> s_apiNameCmdClassMap = new HashMap<String, Class<?>>();
+    private static LinkedHashMap<Object, String> s_allApiCommands = new LinkedHashMap<Object, String>();
+    private static TreeMap<Object, String> s_allApiCommandsSorted = new TreeMap<Object, String>();
+    private static final List<String> AsyncResponses = setAsyncResponses();
+
+    private static List<String> setAsyncResponses() {
+        List<String> asyncResponses = new ArrayList<String>();
+        asyncResponses.add(TemplateResponse.class.getName());
+        asyncResponses.add(VolumeResponse.class.getName());
+        //asyncResponses.add(LoadBalancerResponse.class.getName());
+        asyncResponses.add(HostResponse.class.getName());
+        asyncResponses.add(IPAddressResponse.class.getName());
+        asyncResponses.add(StoragePoolResponse.class.getName());
+        asyncResponses.add(UserVmResponse.class.getName());
+        asyncResponses.add(SecurityGroupResponse.class.getName());
+        //asyncResponses.add(ExternalLoadBalancerResponse.class.getName());
+        asyncResponses.add(SnapshotResponse.class.getName());
+
+        return asyncResponses;
+    }
+
+    public static void main(String[] args) {
+        Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[] {"org.apache.cloudstack.api", "com.cloud.api",
+                "com.cloud.api.commands", "com.globo.globodns.cloudstack.api", "org.apache.cloudstack.network.opendaylight.api",
+                "org.apache.cloudstack.api.command.admin.zone", "org.apache.cloudstack.network.contrail.api.command"});
+
+        for (Class<?> cmdClass : cmdClasses) {
+            if(cmdClass.getAnnotation(APICommand.class)==null){
+               System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has no APICommand annotation ");
+               continue;
+            }
+            String apiName = cmdClass.getAnnotation(APICommand.class).name();
+            if (s_apiNameCmdClassMap.containsKey(apiName)) {
+                // handle API cmd separation into admin cmd and user cmd with the common api name
+                Class<?> curCmd = s_apiNameCmdClassMap.get(apiName);
+                if (curCmd.isAssignableFrom(cmdClass)) {
+                    // api_cmd map always keep the admin cmd class to get full response and parameters
+                    s_apiNameCmdClassMap.put(apiName, cmdClass);
+                } else if (cmdClass.isAssignableFrom(curCmd)) {
+                    // just skip this one without warning
+                    continue;
+                } else {
+                    System.out.println("Warning, API Cmd class " + cmdClass.getName() + " has non-unique apiname " + apiName);
+                    continue;
+                }
+            } else {
+                s_apiNameCmdClassMap.put(apiName, cmdClass);
+            }
+        }
+        System.out.printf("Scanned and found %d APIs\n", s_apiNameCmdClassMap.size());
+        List<String> argsList = Arrays.asList(args);
+        Iterator<String> iter = argsList.iterator();
+        while (iter.hasNext()) {
+            String arg = iter.next();
+            if (arg.equals("-d")) {
+                s_dirName = iter.next();
+            }
+        }
+
+        for (Map.Entry<String, Class<?>> entry: s_apiNameCmdClassMap.entrySet()) {
+            Class<?> cls = entry.getValue();
+            s_allApiCommands.put(entry.getKey(), cls.getName());
+        }
+
+        s_allApiCommandsSorted.putAll(s_allApiCommands);
+
+        try {
+            // Create object writer
+            XStream xs = new XStream();
+            xs.alias("command", Command.class);
+            xs.alias("arg", Argument.class);
+            String xmlDocDir = s_dirName + "/xmldoc";
+            String rootAdminDirName = xmlDocDir + "/apis";
+            (new File(rootAdminDirName)).mkdirs();
+
+            ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(s_dirName + "/commands.xml"), "commands");
+            ObjectOutputStream rootAdmin = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "apiSummary.xml"), "commands");
+            ObjectOutputStream rootAdminSorted = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "apiSummarySorted.xml"), "commands");
+
+            Iterator<?> it = s_allApiCommands.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String)it.next();
+                // Write admin commands
+                writeCommand(out, key);
+                writeCommand(rootAdmin, key);
+                // Write single commands to separate xml files
+                ObjectOutputStream singleRootAdminCommandOs = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + key + ".xml"), "command");
+                writeCommand(singleRootAdminCommandOs, key);
+                singleRootAdminCommandOs.close();
+            }
+
+            // Write sorted commands
+            it = s_allApiCommandsSorted.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String)it.next();
+                writeCommand(rootAdminSorted, key);
+            }
+
+            out.close();
+            rootAdmin.close();
+            rootAdminSorted.close();
+
+            // write alerttypes to xml
+            writeAlertTypes(xmlDocDir);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(2);
+        }
+    }
+
+    private static void writeCommand(ObjectOutputStream out, String command) throws ClassNotFoundException, IOException {
+        Class<?> clas = Class.forName(s_allApiCommands.get(command));
+        ArrayList<Argument> request = new ArrayList<Argument>();
+        ArrayList<Argument> response = new ArrayList<Argument>();
+
+        // Create a new command, set name/description/usage
+        Command apiCommand = new Command();
+        apiCommand.setName(command);
+
+        APICommand impl = clas.getAnnotation(APICommand.class);
+        if (impl == null) {
+            impl = clas.getSuperclass().getAnnotation(APICommand.class);
+        }
+
+        if (impl == null) {
+            throw new IllegalStateException(String.format("An %1$s annotation is required for class %2$s.", APICommand.class.getCanonicalName(), clas.getCanonicalName()));
+        }
+
+        if (impl.includeInApiDoc()) {
+            String commandDescription = impl.description();
+            if (commandDescription != null && !commandDescription.isEmpty()) {
+                apiCommand.setDescription(commandDescription);
+            } else {
+                System.out.println("Command " + apiCommand.getName() + " misses description");
+            }
+
+            String commandUsage = impl.usage();
+            if (commandUsage != null && !commandUsage.isEmpty()) {
+                apiCommand.setUsage(commandUsage);
+            }
+
+            //Set version when the API is added
+            if (!impl.since().isEmpty()) {
+                apiCommand.setSinceVersion(impl.since());
+            }
+
+            boolean isAsync = ReflectUtil.isCmdClassAsync(clas, new Class<?>[] {BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
+
+            apiCommand.setAsync(isAsync);
+
+            Set<Field> fields = ReflectUtil.getAllFieldsForClass(clas, new Class<?>[] {BaseCmd.class, BaseAsyncCmd.class, BaseAsyncCreateCmd.class});
+
+            request = setRequestFields(fields);
+
+            // Get response parameters
+            Class<?> responseClas = impl.responseObject();
+            Field[] responseFields = responseClas.getDeclaredFields();
+            response = setResponseFields(responseFields, responseClas);
+
+            apiCommand.setRequest(request);
+            apiCommand.setResponse(response);
+
+            out.writeObject(apiCommand);
+        } else {
+            s_logger.debug("Command " + command + " is not exposed in api doc");
+        }
+    }
+
+    private static ArrayList<Argument> setRequestFields(Set<Field> fields) {
+        ArrayList<Argument> arguments = new ArrayList<Argument>();
+        Set<Argument> requiredArguments = new HashSet<Argument>();
+        Set<Argument> optionalArguments = new HashSet<Argument>();
+        Argument id = null;
+        for (Field f : fields) {
+            Parameter parameterAnnotation = f.getAnnotation(Parameter.class);
+            if (parameterAnnotation != null && parameterAnnotation.expose() && parameterAnnotation.includeInApiDoc()) {
+                Argument reqArg = new Argument(parameterAnnotation.name());
+                reqArg.setRequired(parameterAnnotation.required());
+                if (!parameterAnnotation.description().isEmpty()) {
+                    reqArg.setDescription(parameterAnnotation.description());
+                }
+
+                if (parameterAnnotation.type() == BaseCmd.CommandType.LIST || parameterAnnotation.type() == BaseCmd.CommandType.MAP) {
+                    reqArg.setType(parameterAnnotation.type().toString().toLowerCase());
+                }
+
+                reqArg.setDataType(parameterAnnotation.type().toString().toLowerCase());
+
+                if (!parameterAnnotation.since().isEmpty()) {
+                    reqArg.setSinceVersion(parameterAnnotation.since());
+                }
+
+                if (reqArg.isRequired()) {
+                    if (parameterAnnotation.name().equals("id")) {
+                        id = reqArg;
+                    } else {
+                        requiredArguments.add(reqArg);
+                    }
+                } else {
+                    optionalArguments.add(reqArg);
+                }
+            }
+        }
+
+        // sort required and optional arguments here
+        if (id != null) {
+            arguments.add(id);
+        }
+        arguments.addAll(IteratorUtil.asSortedList(requiredArguments));
+        arguments.addAll(IteratorUtil.asSortedList(optionalArguments));
+
+        return arguments;
+    }
+
+    private static ArrayList<Argument> setResponseFields(Field[] responseFields, Class<?> responseClas) {
+        ArrayList<Argument> arguments = new ArrayList<Argument>();
+        ArrayList<Argument> sortedChildlessArguments = new ArrayList<Argument>();
+        ArrayList<Argument> sortedArguments = new ArrayList<Argument>();
+
+        Argument id = null;
+
+        for (Field responseField : responseFields) {
+            SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class);
+            if (nameAnnotation != null) {
+                Param paramAnnotation = responseField.getAnnotation(Param.class);
+                Argument respArg = new Argument(nameAnnotation.value());
+
+                boolean hasChildren = false;
+                if (paramAnnotation != null && paramAnnotation.includeInApiDoc()) {
+                    String description = paramAnnotation.description();
+                    Class fieldClass = paramAnnotation.responseObject();
+                    if (description != null && !description.isEmpty()) {
+                        respArg.setDescription(description);
+                    }
+
+                    respArg.setDataType(responseField.getType().getSimpleName().toLowerCase());
+
+                    if (!paramAnnotation.since().isEmpty()) {
+                        respArg.setSinceVersion(paramAnnotation.since());
+                    }
+
+                    if (fieldClass != null) {
+                        Class<?> superClass = fieldClass.getSuperclass();
+                        if (superClass != null) {
+                            String superName = superClass.getName();
+                            if (superName.equals(BaseResponse.class.getName())) {
+                                ArrayList<Argument> fieldArguments = new ArrayList<Argument>();
+                                Field[] fields = fieldClass.getDeclaredFields();
+                                fieldArguments = setResponseFields(fields, fieldClass);
+                                respArg.setArguments(fieldArguments);
+                                hasChildren = true;
+                            }
+                        }
+                    }
+                }
+
+                if (paramAnnotation != null && paramAnnotation.includeInApiDoc()) {
+                    if (nameAnnotation.value().equals("id")) {
+                        id = respArg;
+                    } else {
+                        if (hasChildren) {
+                            respArg.setName(nameAnnotation.value() + "(*)");
+                            sortedArguments.add(respArg);
+                        } else {
+                            sortedChildlessArguments.add(respArg);
+                        }
+                    }
+                }
+            }
+        }
+
+        Collections.sort(sortedArguments);
+        Collections.sort(sortedChildlessArguments);
+
+        if (id != null) {
+            arguments.add(id);
+        }
+        arguments.addAll(sortedChildlessArguments);
+        arguments.addAll(sortedArguments);
+
+        if (responseClas.getName().equalsIgnoreCase(AsyncJobResponse.class.getName())) {
+            Argument jobIdArg = new Argument("jobid", "the ID of the async job");
+            arguments.add(jobIdArg);
+        } else if (AsyncResponses.contains(responseClas.getName())) {
+            Argument jobIdArg = new Argument("jobid", "the ID of the latest async job acting on this object");
+            Argument jobStatusArg = new Argument("jobstatus", "the current status of the latest async job acting on this object");
+            arguments.add(jobIdArg);
+            arguments.add(jobStatusArg);
+        }
+
+        return arguments;
+    }
+
+    private static void zipDir(String zipFileName, String dir) throws Exception {
+        File dirObj = new File(dir);
+        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
+        addDir(dirObj, out);
+        out.close();
+    }
+
+    static void addDir(File dirObj, ZipOutputStream out) throws IOException {
+        File[] files = dirObj.listFiles();
+        byte[] tmpBuf = new byte[1024];
+        String pathToDir = s_dirName;
+
+        for (int i = 0; i < files.length; i++) {
+            if (files[i].isDirectory()) {
+                addDir(files[i], out);
+                continue;
+            }
+            try(FileInputStream in = new FileInputStream(files[i].getPath());) {
+                out.putNextEntry(new ZipEntry(files[i].getPath().substring(pathToDir.length())));
+                int len;
+                while ((len = in.read(tmpBuf)) > 0) {
+                    out.write(tmpBuf, 0, len);
+                }
+                out.closeEntry();
+            }catch(IOException ex)
+            {
+                s_logger.error("addDir:Exception:"+ ex.getMessage(),ex);
+            }
+        }
+    }
+
+    private static void deleteDir(File dir) {
+        if (dir.isDirectory()) {
+            String[] children = dir.list();
+            if (children != null) {
+                for (int i = 0; i < children.length; i++) {
+                    deleteDir(new File(dir, children[i]));
+                }
+            }
+        }
+        dir.delete();
+    }
+
+    private static void writeAlertTypes(String dirName) {
+        XStream xs = new XStream();
+        xs.alias("alert", Alert.class);
+        try(ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/alert_types.xml"), "alerts");) {
+            for (Field f : AlertManager.class.getFields()) {
+                if (f.getClass().isAssignableFrom(Number.class)) {
+                    String name = f.getName().substring(11);
+                    Alert alert = new Alert(name, f.getInt(null));
+                    out.writeObject(alert);
+                }
+            }
+        } catch (IOException e) {
+            s_logger.error("Failed to create output stream to write an alert types ", e);
+        } catch (IllegalAccessException e) {
+            s_logger.error("Failed to read alert fields ", e);
+        }
+    }
+
+    private static class LinkedProperties extends Properties {
+        private final LinkedList<Object> keys = new LinkedList<Object>();
+
+        @Override
+        public Enumeration<Object> keys() {
+            return Collections.<Object> enumeration(keys);
+        }
+
+        @Override
+        public Object put(Object key, Object value) {
+            // System.out.println("Adding key" + key);
+            keys.add(key);
+            return super.put(key, value);
+        }
+    }
+}
diff --git a/server/src/com/cloud/api/doc/Argument.java b/server/src/main/java/com/cloud/api/doc/Argument.java
similarity index 100%
rename from server/src/com/cloud/api/doc/Argument.java
rename to server/src/main/java/com/cloud/api/doc/Argument.java
diff --git a/server/src/com/cloud/api/doc/Command.java b/server/src/main/java/com/cloud/api/doc/Command.java
similarity index 100%
rename from server/src/com/cloud/api/doc/Command.java
rename to server/src/main/java/com/cloud/api/doc/Command.java
diff --git a/server/src/com/cloud/api/query/MutualExclusiveIdsManagerBase.java b/server/src/main/java/com/cloud/api/query/MutualExclusiveIdsManagerBase.java
similarity index 100%
rename from server/src/com/cloud/api/query/MutualExclusiveIdsManagerBase.java
rename to server/src/main/java/com/cloud/api/query/MutualExclusiveIdsManagerBase.java
diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
new file mode 100644
index 0000000..91e0466
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
@@ -0,0 +1,3719 @@
+// 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.api.query;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
+import org.apache.cloudstack.api.ResourceDetail;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
+import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.management.ListMgmtsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
+import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
+import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
+import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
+import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
+import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
+import org.apache.cloudstack.api.response.AccountResponse;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.EventResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.HostTagResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import org.apache.cloudstack.api.response.ProjectInvitationResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ResourceDetailResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.StorageTagResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserResponse;
+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.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.query.QueryService;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.api.query.dao.AccountJoinDao;
+import com.cloud.api.query.dao.AffinityGroupJoinDao;
+import com.cloud.api.query.dao.AsyncJobJoinDao;
+import com.cloud.api.query.dao.DataCenterJoinDao;
+import com.cloud.api.query.dao.DiskOfferingJoinDao;
+import com.cloud.api.query.dao.DomainJoinDao;
+import com.cloud.api.query.dao.DomainRouterJoinDao;
+import com.cloud.api.query.dao.HostJoinDao;
+import com.cloud.api.query.dao.HostTagDao;
+import com.cloud.api.query.dao.ImageStoreJoinDao;
+import com.cloud.api.query.dao.InstanceGroupJoinDao;
+import com.cloud.api.query.dao.ProjectAccountJoinDao;
+import com.cloud.api.query.dao.ProjectInvitationJoinDao;
+import com.cloud.api.query.dao.ProjectJoinDao;
+import com.cloud.api.query.dao.ResourceTagJoinDao;
+import com.cloud.api.query.dao.SecurityGroupJoinDao;
+import com.cloud.api.query.dao.ServiceOfferingJoinDao;
+import com.cloud.api.query.dao.StoragePoolJoinDao;
+import com.cloud.api.query.dao.TemplateJoinDao;
+import com.cloud.api.query.dao.UserAccountJoinDao;
+import com.cloud.api.query.dao.UserVmJoinDao;
+import com.cloud.api.query.dao.VolumeJoinDao;
+import com.cloud.api.query.vo.AccountJoinVO;
+import com.cloud.api.query.vo.AffinityGroupJoinVO;
+import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.api.query.vo.DataCenterJoinVO;
+import com.cloud.api.query.vo.DiskOfferingJoinVO;
+import com.cloud.api.query.vo.DomainJoinVO;
+import com.cloud.api.query.vo.DomainRouterJoinVO;
+import com.cloud.api.query.vo.EventJoinVO;
+import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.api.query.vo.HostTagVO;
+import com.cloud.api.query.vo.ImageStoreJoinVO;
+import com.cloud.api.query.vo.InstanceGroupJoinVO;
+import com.cloud.api.query.vo.ProjectAccountJoinVO;
+import com.cloud.api.query.vo.ProjectInvitationJoinVO;
+import com.cloud.api.query.vo.ProjectJoinVO;
+import com.cloud.api.query.vo.ResourceTagJoinVO;
+import com.cloud.api.query.vo.SecurityGroupJoinVO;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
+import com.cloud.api.query.vo.StoragePoolJoinVO;
+import com.cloud.api.query.vo.TemplateJoinVO;
+import com.cloud.api.query.vo.UserAccountJoinVO;
+import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.api.query.vo.VolumeJoinVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.dao.EventJoinDao;
+import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.security.SecurityGroupVMMapVO;
+import com.cloud.network.security.dao.SecurityGroupVMMapDao;
+import com.cloud.org.Grouping;
+import com.cloud.projects.Project;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.projects.ProjectInvitation;
+import com.cloud.projects.ProjectManager;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ResourceMetaDataService;
+import com.cloud.server.ResourceTag;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.server.TaggedResourceService;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePoolTagVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.dao.StoragePoolTagsDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.template.VirtualMachineTemplate.State;
+import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements QueryService, Configurable {
+
+    public static final Logger s_logger = Logger.getLogger(QueryManagerImpl.class);
+
+    private static final String ID_FIELD = "id";
+
+    @Inject
+    private AccountManager _accountMgr;
+
+    @Inject
+    private ProjectManager _projectMgr;
+
+    @Inject
+    private DomainDao _domainDao;
+
+    @Inject
+    private DomainJoinDao _domainJoinDao;
+
+    @Inject
+    private UserAccountJoinDao _userAccountJoinDao;
+
+    @Inject
+    private EventJoinDao _eventJoinDao;
+
+    @Inject
+    private ResourceTagJoinDao _resourceTagJoinDao;
+
+    @Inject
+    private InstanceGroupJoinDao _vmGroupJoinDao;
+
+    @Inject
+    private UserVmJoinDao _userVmJoinDao;
+
+    @Inject
+    private UserVmDao _userVmDao;
+
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+
+    @Inject
+    private SecurityGroupJoinDao _securityGroupJoinDao;
+
+    @Inject
+    private SecurityGroupVMMapDao _securityGroupVMMapDao;
+
+    @Inject
+    private DomainRouterJoinDao _routerJoinDao;
+
+    @Inject
+    private ProjectInvitationJoinDao _projectInvitationJoinDao;
+
+    @Inject
+    private ProjectJoinDao _projectJoinDao;
+
+    @Inject
+    private ProjectDao _projectDao;
+
+    @Inject
+    private ProjectAccountDao _projectAccountDao;
+
+    @Inject
+    private ProjectAccountJoinDao _projectAccountJoinDao;
+
+    @Inject
+    private HostJoinDao _hostJoinDao;
+
+    @Inject
+    private VolumeJoinDao _volumeJoinDao;
+
+    @Inject
+    private AccountDao _accountDao;
+
+    @Inject
+    private ConfigurationDao _configDao;
+
+    @Inject
+    private AccountJoinDao _accountJoinDao;
+
+    @Inject
+    private AsyncJobJoinDao _jobJoinDao;
+
+    @Inject
+    private StoragePoolJoinDao _poolJoinDao;
+
+    @Inject
+    private StoragePoolTagsDao _storageTagDao;
+
+    @Inject
+    private HostTagDao _hostTagDao;
+
+    @Inject
+    private ImageStoreJoinDao _imageStoreJoinDao;
+
+    @Inject
+    private DiskOfferingJoinDao _diskOfferingJoinDao;
+
+    @Inject
+    private ServiceOfferingJoinDao _srvOfferingJoinDao;
+
+    @Inject
+    private ServiceOfferingDao _srvOfferingDao;
+
+    @Inject
+    private DataCenterJoinDao _dcJoinDao;
+
+    @Inject
+    private DomainRouterDao _routerDao;
+
+    @Inject
+    private UserVmDetailsDao _userVmDetailDao;
+
+    @Inject
+    private HighAvailabilityManager _haMgr;
+
+    @Inject
+    private VMTemplateDao _templateDao;
+
+    @Inject
+    private TemplateJoinDao _templateJoinDao;
+
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ResourceMetaDataService _resourceMetaDataMgr;
+
+    @Inject
+    private TaggedResourceService _taggedResourceMgr;
+
+    @Inject
+    private AffinityGroupVMMapDao _affinityGroupVMMapDao;
+
+    @Inject
+    private AffinityGroupJoinDao _affinityGroupJoinDao;
+
+    @Inject
+    private DedicatedResourceDao _dedicatedDao;
+
+    @Inject
+    private DomainManager _domainMgr;
+
+    @Inject
+    private AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
+
+    @Inject
+    private NetworkDetailsDao _networkDetailsDao;
+
+    @Inject
+    private ResourceTagDao _resourceTagDao;
+
+    @Inject
+    private DataStoreManager dataStoreManager;
+
+    @Inject
+    private EntityManager _entityMgr;
+
+    @Inject
+    ManagementServerHostDao managementServerHostDao;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack
+     * .api.command.admin.user.ListUsersCmd)
+     */
+    @Override
+    public ListResponse<UserResponse> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
+        Pair<List<UserAccountJoinVO>, Integer> result = searchForUsersInternal(cmd);
+        ListResponse<UserResponse> response = new ListResponse<UserResponse>();
+        List<UserResponse> userResponses = ViewResponseHelper.createUserResponse(CallContext.current().getCallingAccount().getDomainId(),
+                result.first().toArray(new UserAccountJoinVO[result.first().size()]));
+        response.setResponses(userResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<UserAccountJoinVO>, Integer> searchForUsersInternal(ListUsersCmd cmd) throws PermissionDeniedException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        boolean listAll = cmd.listAll();
+        Long id = cmd.getId();
+        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+            long currentId = CallContext.current().getCallingUser().getId();
+            if (id != null && currentId != id.longValue()) {
+                throw new PermissionDeniedException("Calling user is not authorized to see the user requested by id");
+            }
+            id = currentId;
+        }
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(UserAccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        Object username = cmd.getUsername();
+        Object type = cmd.getAccountType();
+        Object accountName = cmd.getAccountName();
+        Object state = cmd.getState();
+        Object keyword = cmd.getKeyword();
+
+        SearchBuilder<UserAccountJoinVO> sb = _userAccountJoinDao.createSearchBuilder();
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.LIKE);
+        if (id != null && id == 1) {
+            // system user should NOT be searchable
+            List<UserAccountJoinVO> emptyList = new ArrayList<UserAccountJoinVO>();
+            return new Pair<List<UserAccountJoinVO>, Integer>(emptyList, 0);
+        } else if (id != null) {
+            sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        } else {
+            // this condition is used to exclude system user from the search
+            // results
+            sb.and("id", sb.entity().getId(), SearchCriteria.Op.NEQ);
+        }
+
+        sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+        sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+
+        if ((accountName == null) && (domainId != null)) {
+            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        SearchCriteria<UserAccountJoinVO> sc = sb.create();
+
+        // building ACL condition
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            SearchCriteria<UserAccountJoinVO> ssc = _userAccountJoinDao.createSearchCriteria();
+            ssc.addOr("username", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("firstname", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("lastname", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("email", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("accountType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("username", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (username != null) {
+            sc.setParameters("username", username);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        } else {
+            // Don't return system user, search builder with NEQ
+            sc.setParameters("id", 1);
+        }
+
+        if (type != null) {
+            sc.setParameters("type", type);
+        }
+
+        if (accountName != null) {
+            sc.setParameters("accountName", accountName);
+            if (domainId != null) {
+                sc.setParameters("domainId", domainId);
+            }
+        } else if (domainId != null) {
+            DomainVO domainVO = _domainDao.findById(domainId);
+            sc.setParameters("domainPath", domainVO.getPath() + "%");
+        }
+
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+
+        return _userAccountJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd) {
+        Pair<List<EventJoinVO>, Integer> result = searchForEventsInternal(cmd);
+        ListResponse<EventResponse> response = new ListResponse<EventResponse>();
+        List<EventResponse> eventResponses = ViewResponseHelper.createEventResponse(result.first().toArray(new EventJoinVO[result.first().size()]));
+        response.setResponses(eventResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<EventJoinVO>, Integer> searchForEventsInternal(ListEventsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Long id = cmd.getId();
+        String type = cmd.getType();
+        String level = cmd.getLevel();
+        Date startDate = cmd.getStartDate();
+        Date endDate = cmd.getEndDate();
+        String keyword = cmd.getKeyword();
+        Integer entryTime = cmd.getEntryTime();
+        Integer duration = cmd.getDuration();
+        Long startId = cmd.getStartId();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(EventJoinVO.class, "createDate", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<EventJoinVO> sb = _eventJoinDao.createSearchBuilder();
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("levelL", sb.entity().getLevel(), SearchCriteria.Op.LIKE);
+        sb.and("levelEQ", sb.entity().getLevel(), SearchCriteria.Op.EQ);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
+        sb.and("createDateB", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
+        sb.and("createDateG", sb.entity().getCreateDate(), SearchCriteria.Op.GTEQ);
+        sb.and("createDateL", sb.entity().getCreateDate(), SearchCriteria.Op.LTEQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
+        sb.or("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ);
+        sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
+        sb.and("displayEvent", sb.entity().getDisplay(), SearchCriteria.Op.EQ);
+        sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<EventJoinVO> sc = sb.create();
+        // building ACL condition
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        // For end users display only enabled events
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            sc.setParameters("displayEvent", true);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (startId != null) {
+            sc.setParameters("startId", startId);
+            if (id == null) {
+                sc.setParameters("id", startId);
+            }
+        }
+
+        if (keyword != null) {
+            SearchCriteria<EventJoinVO> ssc = _eventJoinDao.createSearchCriteria();
+            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("level", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("level", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (level != null) {
+            sc.setParameters("levelEQ", level);
+        }
+
+        if (type != null) {
+            sc.setParameters("type", type);
+        }
+
+        if (startDate != null && endDate != null) {
+            sc.setParameters("createDateB", startDate, endDate);
+        } else if (startDate != null) {
+            sc.setParameters("createDateG", startDate);
+        } else if (endDate != null) {
+            sc.setParameters("createDateL", endDate);
+        }
+
+        sc.setParameters("archived", false);
+
+        Pair<List<EventJoinVO>, Integer> eventPair = null;
+        // event_view will not have duplicate rows for each event, so
+        // searchAndCount should be good enough.
+        if ((entryTime != null) && (duration != null)) {
+            // TODO: waiting for response from dev list, logic is mystery to
+            // me!!
+            /*
+             * if (entryTime <= duration) { throw new
+             * InvalidParameterValueException
+             * ("Entry time must be greater than duration"); } Calendar calMin =
+             * Calendar.getInstance(); Calendar calMax = Calendar.getInstance();
+             * calMin.add(Calendar.SECOND, -entryTime);
+             * calMax.add(Calendar.SECOND, -duration); Date minTime =
+             * calMin.getTime(); Date maxTime = calMax.getTime();
+             *
+             * sc.setParameters("state", com.cloud.event.Event.State.Completed);
+             * sc.setParameters("startId", 0); sc.setParameters("createDate",
+             * minTime, maxTime); List<EventJoinVO> startedEvents =
+             * _eventJoinDao.searchAllEvents(sc, searchFilter);
+             * List<EventJoinVO> pendingEvents = new ArrayList<EventJoinVO>();
+             * for (EventVO event : startedEvents) { EventVO completedEvent =
+             * _eventDao.findCompletedEvent(event.getId()); if (completedEvent
+             * == null) { pendingEvents.add(event); } } return pendingEvents;
+             */
+        } else {
+            eventPair = _eventJoinDao.searchAndCount(sc, searchFilter);
+        }
+        return eventPair;
+
+    }
+
+    @Override
+    public ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd) {
+        Pair<List<ResourceTagJoinVO>, Integer> tags = listTagsInternal(cmd);
+        ListResponse<ResourceTagResponse> response = new ListResponse<ResourceTagResponse>();
+        List<ResourceTagResponse> tagResponses = ViewResponseHelper.createResourceTagResponse(false, tags.first().toArray(new ResourceTagJoinVO[tags.first().size()]));
+        response.setResponses(tagResponses, tags.second());
+        return response;
+    }
+
+    private Pair<List<ResourceTagJoinVO>, Integer> listTagsInternal(ListTagsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+        String key = cmd.getKey();
+        String value = cmd.getValue();
+        String resourceId = cmd.getResourceId();
+        String resourceType = cmd.getResourceType();
+        String customerName = cmd.getCustomer();
+        boolean listAll = cmd.listAll();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+
+        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        Filter searchFilter = new Filter(ResourceTagJoinVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        SearchBuilder<ResourceTagJoinVO> sb = _resourceTagJoinDao.createSearchBuilder();
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ);
+        sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ);
+
+        if (resourceId != null) {
+            sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
+            sb.and("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ);
+        }
+
+        sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
+        sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ);
+
+        // now set the SC criteria...
+        SearchCriteria<ResourceTagJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (key != null) {
+            sc.setParameters("key", key);
+        }
+
+        if (value != null) {
+            sc.setParameters("value", value);
+        }
+
+        if (resourceId != null) {
+            try {
+                long rid = Long.parseLong(resourceId);
+                sc.setParameters("resourceId", rid);
+            } catch (NumberFormatException ex) {
+                // internal id instead of resource id is passed
+                sc.setParameters("resourceUuid", resourceId);
+            }
+        }
+
+        if (resourceType != null) {
+            sc.setParameters("resourceType", resourceType);
+        }
+
+        if (customerName != null) {
+            sc.setParameters("customer", customerName);
+        }
+
+        Pair<List<ResourceTagJoinVO>, Integer> result = _resourceTagJoinDao.searchAndCount(sc, searchFilter);
+        return result;
+    }
+
+    @Override
+    public ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd) {
+        Pair<List<InstanceGroupJoinVO>, Integer> groups = searchForVmGroupsInternal(cmd);
+        ListResponse<InstanceGroupResponse> response = new ListResponse<InstanceGroupResponse>();
+        List<InstanceGroupResponse> grpResponses = ViewResponseHelper.createInstanceGroupResponse(groups.first().toArray(new InstanceGroupJoinVO[groups.first().size()]));
+        response.setResponses(grpResponses, groups.second());
+        return response;
+    }
+
+    private Pair<List<InstanceGroupJoinVO>, Integer> searchForVmGroupsInternal(ListVMGroupsCmd cmd) {
+        Long id = cmd.getId();
+        String name = cmd.getGroupName();
+        String keyword = cmd.getKeyword();
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(InstanceGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        SearchBuilder<InstanceGroupJoinVO> sb = _vmGroupJoinDao.createSearchBuilder();
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+
+        SearchCriteria<InstanceGroupJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            SearchCriteria<InstanceGroupJoinVO> ssc = _vmGroupJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        return _vmGroupJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<UserVmResponse> searchForUserVMs(ListVMsCmd cmd) {
+        Pair<List<UserVmJoinVO>, Integer> result = searchForUserVMsInternal(cmd);
+        ListResponse<UserVmResponse> response = new ListResponse<UserVmResponse>();
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListVMsCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+        List<UserVmResponse> vmResponses = ViewResponseHelper.createUserVmResponse(respView, "virtualmachine", cmd.getDetails(), result.first().toArray(new UserVmJoinVO[result.first().size()]));
+
+        response.setResponses(vmResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<UserVmJoinVO>, Integer> searchForUserVMsInternal(ListVMsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        boolean listAll = cmd.listAll();
+        Long id = cmd.getId();
+        Long userId = cmd.getUserId();
+        Map<String, String> tags = cmd.getTags();
+        Boolean display = cmd.getDisplay();
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(UserVmJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        List<Long> ids = null;
+        if (cmd.getId() != null) {
+            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
+                throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
+            }
+            ids = new ArrayList<Long>();
+            ids.add(cmd.getId());
+        } else {
+            ids = cmd.getIds();
+        }
+
+        // first search distinct vm id by using query criteria and pagination
+        SearchBuilder<UserVmJoinVO> sb = _userVmJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids
+
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        String hypervisor = cmd.getHypervisor();
+        Object name = cmd.getName();
+        String state = cmd.getState();
+        Object zoneId = cmd.getZoneId();
+        Object keyword = cmd.getKeyword();
+        boolean isAdmin = false;
+        boolean isRootAdmin = false;
+        if (_accountMgr.isAdmin(caller.getId())) {
+            isAdmin = true;
+        }
+        if (_accountMgr.isRootAdmin(caller.getId())) {
+            isRootAdmin = true;
+        }
+
+        Object groupId = cmd.getGroupId();
+        Object networkId = cmd.getNetworkId();
+        if (HypervisorType.getType(hypervisor) == HypervisorType.None && hypervisor != null) {
+            // invalid hypervisor type input
+            throw new InvalidParameterValueException("Invalid HypervisorType " + hypervisor);
+        }
+        Object templateId = cmd.getTemplateId();
+        Object isoId = cmd.getIsoId();
+        Object vpcId = cmd.getVpcId();
+        Object affinityGroupId = cmd.getAffinityGroupId();
+        Object keyPairName = cmd.getKeyPairName();
+        Object serviceOffId = cmd.getServiceOfferingId();
+        Object pod = null;
+        Object hostId = null;
+        Object storageId = null;
+        if (cmd instanceof ListVMsCmdByAdmin) {
+            ListVMsCmdByAdmin adCmd = (ListVMsCmdByAdmin)cmd;
+            pod = adCmd.getPodId();
+            hostId = adCmd.getHostId();
+            storageId = adCmd.getStorageId();
+        }
+
+        sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
+        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
+        sb.and("stateNIN", sb.entity().getState(), SearchCriteria.Op.NIN);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        sb.and("hostIdEQ", sb.entity().getHostId(), SearchCriteria.Op.EQ);
+        sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        sb.and("isoId", sb.entity().getIsoId(), SearchCriteria.Op.EQ);
+        sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
+
+        if (serviceOffId != null) {
+            sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ);
+        }
+        if (display != null) {
+            sb.and("display", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ);
+        }
+        if (groupId != null && (Long)groupId != -1) {
+            sb.and("instanceGroupId", sb.entity().getInstanceGroupId(), SearchCriteria.Op.EQ);
+        }
+
+        if (userId != null) {
+            sb.and("userId", sb.entity().getUserId(), SearchCriteria.Op.EQ);
+        }
+
+        if (networkId != null) {
+            sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        }
+
+        if (vpcId != null && networkId == null) {
+            sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
+        }
+
+        if (storageId != null) {
+            sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.EQ);
+        }
+
+        if (affinityGroupId != null) {
+            sb.and("affinityGroupId", sb.entity().getAffinityGroupId(), SearchCriteria.Op.EQ);
+        }
+
+        if (keyPairName != null) {
+            sb.and("keyPairName", sb.entity().getKeypairName(), SearchCriteria.Op.EQ);
+        }
+
+        if (!isRootAdmin) {
+            sb.and("displayVm", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ);
+        }
+
+        // populate the search criteria with the values passed in
+        SearchCriteria<UserVmJoinVO> sc = sb.create();
+
+        // building ACL condition
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchCriteria<UserVmJoinVO> tagSc = _userVmJoinDao.createSearchCriteria();
+            for (Map.Entry<String, String> entry : tags.entrySet()) {
+                SearchCriteria<UserVmJoinVO> tsc = _userVmJoinDao.createSearchCriteria();
+                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, entry.getKey());
+                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, entry.getValue());
+                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
+            }
+            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
+        }
+
+        if (groupId != null && (Long)groupId != -1) {
+            sc.setParameters("instanceGroupId", groupId);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<UserVmJoinVO> ssc = _userVmJoinDao.createSearchCriteria();
+            ssc.addOr("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("state", SearchCriteria.Op.EQ, keyword);
+            sc.addAnd("displayName", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (serviceOffId != null) {
+            sc.setParameters("serviceOfferingId", serviceOffId);
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        if (ids != null && !ids.isEmpty()) {
+            sc.setParameters("idIN", ids.toArray());
+        }
+
+        if (templateId != null) {
+            sc.setParameters("templateId", templateId);
+        }
+
+        if (isoId != null) {
+            sc.setParameters("isoId", isoId);
+        }
+
+        if (userId != null) {
+            sc.setParameters("userId", userId);
+        }
+
+        if (networkId != null) {
+            sc.setParameters("networkId", networkId);
+        }
+
+        if (vpcId != null && networkId == null) {
+            sc.setParameters("vpcId", vpcId);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        if (state != null) {
+            if (state.equalsIgnoreCase("present")) {
+                sc.setParameters("stateNIN", "Destroyed", "Expunging");
+            } else {
+                sc.setParameters("stateEQ", state);
+            }
+        }
+
+        if (hypervisor != null) {
+            sc.setParameters("hypervisorType", hypervisor);
+        }
+
+        // Don't show Destroyed and Expunging vms to the end user if the AllowUserViewDestroyedVM flag is not set.
+        if (!isAdmin && !AllowUserViewDestroyedVM.valueIn(caller.getAccountId())) {
+            sc.setParameters("stateNIN", "Destroyed", "Expunging");
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+
+        if (affinityGroupId != null) {
+            sc.setParameters("affinityGroupId", affinityGroupId);
+        }
+
+        if (keyPairName != null) {
+            sc.setParameters("keyPairName", keyPairName);
+        }
+
+        if (cmd instanceof ListVMsCmdByAdmin) {
+            ListVMsCmdByAdmin aCmd = (ListVMsCmdByAdmin)cmd;
+            if (aCmd.getPodId() != null) {
+                sc.setParameters("podId", pod);
+
+                if (state == null) {
+                    sc.setParameters("stateNEQ", "Destroyed");
+                }
+            }
+
+            if (hostId != null) {
+                sc.setParameters("hostIdEQ", hostId);
+            }
+
+            if (storageId != null) {
+                sc.setParameters("poolId", storageId);
+            }
+        }
+
+        if (!isRootAdmin) {
+            sc.setParameters("displayVm", 1);
+        }
+        // search vm details by ids
+        Pair<List<UserVmJoinVO>, Integer> uniqueVmPair = _userVmJoinDao.searchAndDistinctCount(sc, searchFilter);
+        Integer count = uniqueVmPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return uniqueVmPair;
+        }
+        List<UserVmJoinVO> uniqueVms = uniqueVmPair.first();
+        Long[] vmIds = new Long[uniqueVms.size()];
+        int i = 0;
+        for (UserVmJoinVO v : uniqueVms) {
+            vmIds[i++] = v.getId();
+        }
+        List<UserVmJoinVO> vms = _userVmJoinDao.searchByIds(vmIds);
+        return new Pair<List<UserVmJoinVO>, Integer>(vms, count);
+    }
+
+    @Override
+    public ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd) {
+        Pair<List<SecurityGroupJoinVO>, Integer> result = searchForSecurityGroupsInternal(cmd);
+        ListResponse<SecurityGroupResponse> response = new ListResponse<SecurityGroupResponse>();
+        List<SecurityGroupResponse> routerResponses = ViewResponseHelper.createSecurityGroupResponses(result.first());
+        response.setResponses(routerResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<SecurityGroupJoinVO>, Integer> searchForSecurityGroupsInternal(ListSecurityGroupsCmd cmd) throws PermissionDeniedException, InvalidParameterValueException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long instanceId = cmd.getVirtualMachineId();
+        String securityGroup = cmd.getSecurityGroupName();
+        Long id = cmd.getId();
+        Object keyword = cmd.getKeyword();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+        Map<String, String> tags = cmd.getTags();
+
+        if (instanceId != null) {
+            UserVmVO userVM = _userVmDao.findById(instanceId);
+            if (userVM == null) {
+                throw new InvalidParameterValueException("Unable to list network groups for virtual machine instance " + instanceId + "; instance not found.");
+            }
+            _accountMgr.checkAccess(caller, null, true, userVM);
+            return listSecurityGroupRulesByVM(instanceId.longValue(), cmd.getStartIndex(), cmd.getPageSizeVal());
+        }
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(SecurityGroupJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<SecurityGroupJoinVO> sb = _securityGroupJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<SecurityGroupJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchCriteria<SecurityGroupJoinVO> tagSc = _securityGroupJoinDao.createSearchCriteria();
+            for (String key : tags.keySet()) {
+                SearchCriteria<SecurityGroupJoinVO> tsc = _securityGroupJoinDao.createSearchCriteria();
+                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, key);
+                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key));
+                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
+            }
+            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
+        }
+
+        if (securityGroup != null) {
+            sc.setParameters("name", securityGroup);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<SecurityGroupJoinVO> ssc = _securityGroupJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        // search security group together with rules
+        Pair<List<SecurityGroupJoinVO>, Integer> uniqueSgPair = _securityGroupJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueSgPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return uniqueSgPair;
+        }
+
+        List<SecurityGroupJoinVO> uniqueSgs = uniqueSgPair.first();
+        Long[] sgIds = new Long[uniqueSgs.size()];
+        int i = 0;
+        for (SecurityGroupJoinVO v : uniqueSgs) {
+            sgIds[i++] = v.getId();
+        }
+        List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
+        return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
+    }
+
+    private Pair<List<SecurityGroupJoinVO>, Integer> listSecurityGroupRulesByVM(long vmId, long pageInd, long pageSize) {
+        Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize);
+        Pair<List<SecurityGroupVMMapVO>, Integer> sgVmMappingPair = _securityGroupVMMapDao.listByInstanceId(vmId, sf);
+        Integer count = sgVmMappingPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return new Pair<List<SecurityGroupJoinVO>, Integer>(new ArrayList<SecurityGroupJoinVO>(), count);
+        }
+        List<SecurityGroupVMMapVO> sgVmMappings = sgVmMappingPair.first();
+        Long[] sgIds = new Long[sgVmMappings.size()];
+        int i = 0;
+        for (SecurityGroupVMMapVO sgVm : sgVmMappings) {
+            sgIds[i++] = sgVm.getSecurityGroupId();
+        }
+        List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
+        return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
+    }
+
+    @Override
+    public ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd) {
+        Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getClusterId(),
+                cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion());
+        ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
+
+        List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
+        response.setResponses(routerResponses, result.second());
+        return response;
+    }
+
+    @Override
+    public ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd) {
+        Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), null, cmd.getHostId(),
+                cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null);
+        ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
+
+        List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
+        response.setResponses(routerResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<DomainRouterJoinVO>, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, String name, String state, Long zoneId, Long podId, Long clusterId,
+            Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version) {
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        Filter searchFilter = new Filter(DomainRouterJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        SearchBuilder<DomainRouterJoinVO> sb = _routerJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids to get
+        // number of
+        // records with
+        // pagination
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("name", sb.entity().getInstanceName(), SearchCriteria.Op.LIKE);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+        sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ);
+        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
+        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
+        sb.and("version", sb.entity().getTemplateVersion(), SearchCriteria.Op.LIKE);
+
+        if (forVpc != null) {
+            if (forVpc) {
+                sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NNULL);
+            } else {
+                sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NULL);
+            }
+        }
+
+        if (networkId != null) {
+            sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        }
+
+        SearchCriteria<DomainRouterJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            SearchCriteria<DomainRouterJoinVO> ssc = _routerJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("instanceName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("networkName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("vpcName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("instanceName", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+
+        if (podId != null) {
+            sc.setParameters("podId", podId);
+        }
+
+        if (clusterId != null) {
+            sc.setParameters("clusterId", clusterId);
+        }
+
+        if (hostId != null) {
+            sc.setParameters("hostId", hostId);
+        }
+
+        if (networkId != null) {
+            sc.setParameters("networkId", networkId);
+        }
+
+        if (vpcId != null) {
+            sc.setParameters("vpcId", vpcId);
+        }
+
+        if (role != null) {
+            sc.setParameters("role", role);
+        }
+
+        if (version != null) {
+            sc.setParameters("version", "Cloudstack Release " + version + "%");
+        }
+
+        // search VR details by ids
+        Pair<List<DomainRouterJoinVO>, Integer> uniqueVrPair = _routerJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueVrPair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniqueVrPair;
+        }
+        List<DomainRouterJoinVO> uniqueVrs = uniqueVrPair.first();
+        Long[] vrIds = new Long[uniqueVrs.size()];
+        int i = 0;
+        for (DomainRouterJoinVO v : uniqueVrs) {
+            vrIds[i++] = v.getId();
+        }
+        List<DomainRouterJoinVO> vrs = _routerJoinDao.searchByIds(vrIds);
+        return new Pair<List<DomainRouterJoinVO>, Integer>(vrs, count);
+    }
+
+    @Override
+    public ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd) {
+        Pair<List<ProjectJoinVO>, Integer> projects = listProjectsInternal(cmd);
+        ListResponse<ProjectResponse> response = new ListResponse<ProjectResponse>();
+        List<ProjectResponse> projectResponses = ViewResponseHelper.createProjectResponse(projects.first().toArray(new ProjectJoinVO[projects.first().size()]));
+        response.setResponses(projectResponses, projects.second());
+        return response;
+    }
+
+    private Pair<List<ProjectJoinVO>, Integer> listProjectsInternal(ListProjectsCmd cmd) {
+
+        Long id = cmd.getId();
+        String name = cmd.getName();
+        String displayText = cmd.getDisplayText();
+        String state = cmd.getState();
+        String accountName = cmd.getAccountName();
+        Long domainId = cmd.getDomainId();
+        String keyword = cmd.getKeyword();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+        boolean listAll = cmd.listAll();
+        boolean isRecursive = cmd.isRecursive();
+        cmd.getTags();
+
+        Account caller = CallContext.current().getCallingAccount();
+        Long accountId = null;
+        String path = null;
+
+        Filter searchFilter = new Filter(ProjectJoinVO.class, "id", false, startIndex, pageSize);
+        SearchBuilder<ProjectJoinVO> sb = _projectJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+
+        if (_accountMgr.isAdmin(caller.getId())) {
+            if (domainId != null) {
+                DomainVO domain = _domainDao.findById(domainId);
+                if (domain == null) {
+                    throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist in the system");
+                }
+
+                _accountMgr.checkAccess(caller, domain);
+
+                if (accountName != null) {
+                    Account owner = _accountMgr.getActiveAccountByName(accountName, domainId);
+                    if (owner == null) {
+                        throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
+                    }
+                    accountId = owner.getId();
+                }
+            } else { // domainId == null
+                if (accountName != null) {
+                    throw new InvalidParameterValueException("could not find account " + accountName + " because domain is not specified");
+                }
+
+            }
+        } else {
+            if (accountName != null && !accountName.equals(caller.getAccountName())) {
+                throw new PermissionDeniedException("Can't list account " + accountName + " projects; unauthorized");
+            }
+
+            if (domainId != null && !domainId.equals(caller.getDomainId())) {
+                throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized");
+            }
+
+            accountId = caller.getId();
+        }
+
+        if (domainId == null && accountId == null && (_accountMgr.isNormalUser(caller.getId()) || !listAll)) {
+            accountId = caller.getId();
+        } else if (_accountMgr.isDomainAdmin(caller.getId()) || (isRecursive && !listAll)) {
+            DomainVO domain = _domainDao.findById(caller.getDomainId());
+            path = domain.getPath();
+        }
+
+        if (path != null) {
+            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        if (accountId != null) {
+            sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+        }
+
+        SearchCriteria<ProjectJoinVO> sc = sb.create();
+
+        if (id != null) {
+            sc.addAnd("id", Op.EQ, id);
+        }
+
+        if (domainId != null && !isRecursive) {
+            sc.addAnd("domainId", Op.EQ, domainId);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", Op.EQ, name);
+        }
+
+        if (displayText != null) {
+            sc.addAnd("displayText", Op.EQ, displayText);
+        }
+
+        if (accountId != null) {
+            sc.setParameters("accountId", accountId);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", Op.EQ, state);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<ProjectJoinVO> ssc = _projectJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (path != null) {
+            sc.setParameters("domainPath", path);
+        }
+
+        // search distinct projects to get count
+        Pair<List<ProjectJoinVO>, Integer> uniquePrjPair = _projectJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniquePrjPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return uniquePrjPair;
+        }
+        List<ProjectJoinVO> uniquePrjs = uniquePrjPair.first();
+        Long[] prjIds = new Long[uniquePrjs.size()];
+        int i = 0;
+        for (ProjectJoinVO v : uniquePrjs) {
+            prjIds[i++] = v.getId();
+        }
+        List<ProjectJoinVO> prjs = _projectJoinDao.searchByIds(prjIds);
+        return new Pair<List<ProjectJoinVO>, Integer>(prjs, count);
+    }
+
+    @Override
+    public ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd) {
+        Pair<List<ProjectInvitationJoinVO>, Integer> invites = listProjectInvitationsInternal(cmd);
+        ListResponse<ProjectInvitationResponse> response = new ListResponse<ProjectInvitationResponse>();
+        List<ProjectInvitationResponse> projectInvitationResponses = ViewResponseHelper.createProjectInvitationResponse(invites.first().toArray(new ProjectInvitationJoinVO[invites.first().size()]));
+
+        response.setResponses(projectInvitationResponses, invites.second());
+        return response;
+    }
+
+    public Pair<List<ProjectInvitationJoinVO>, Integer> listProjectInvitationsInternal(ListProjectInvitationsCmd cmd) {
+        Long id = cmd.getId();
+        Long projectId = cmd.getProjectId();
+        String accountName = cmd.getAccountName();
+        Long domainId = cmd.getDomainId();
+        String state = cmd.getState();
+        boolean activeOnly = cmd.isActiveOnly();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSizeVal = cmd.getPageSizeVal();
+        boolean isRecursive = cmd.isRecursive();
+        boolean listAll = cmd.listAll();
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
+        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, true);
+        domainId = domainIdRecursiveListProject.first();
+        isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(ProjectInvitationJoinVO.class, "id", true, startIndex, pageSizeVal);
+        SearchBuilder<ProjectInvitationJoinVO> sb = _projectInvitationJoinDao.createSearchBuilder();
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("projectId", sb.entity().getProjectId(), SearchCriteria.Op.EQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("created", sb.entity().getCreated(), SearchCriteria.Op.GT);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<ProjectInvitationJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (projectId != null) {
+            sc.setParameters("projectId", projectId);
+        }
+
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (activeOnly) {
+            sc.setParameters("state", ProjectInvitation.State.Pending);
+            sc.setParameters("created", new Date((DateUtil.currentGMTTime().getTime()) - _projectMgr.getInvitationTimeout()));
+        }
+
+        return _projectInvitationJoinDao.searchAndCount(sc, searchFilter);
+
+    }
+
+    @Override
+    public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd) {
+        Pair<List<ProjectAccountJoinVO>, Integer> projectAccounts = listProjectAccountsInternal(cmd);
+        ListResponse<ProjectAccountResponse> response = new ListResponse<ProjectAccountResponse>();
+        List<ProjectAccountResponse> projectResponses = ViewResponseHelper.createProjectAccountResponse(projectAccounts.first().toArray(new ProjectAccountJoinVO[projectAccounts.first().size()]));
+        response.setResponses(projectResponses, projectAccounts.second());
+        return response;
+    }
+
+    public Pair<List<ProjectAccountJoinVO>, Integer> listProjectAccountsInternal(ListProjectAccountsCmd cmd) {
+        long projectId = cmd.getProjectId();
+        String accountName = cmd.getAccountName();
+        String role = cmd.getRole();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSizeVal = cmd.getPageSizeVal();
+
+        // long projectId, String accountName, String role, Long startIndex,
+        // Long pageSizeVal) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        // check that the project exists
+        Project project = _projectDao.findById(projectId);
+
+        if (project == null) {
+            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
+        }
+
+        // verify permissions - only accounts belonging to the project can list
+        // project's account
+        if (!_accountMgr.isAdmin(caller.getId()) && _projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) {
+            throw new PermissionDeniedException("Account " + caller + " is not authorized to list users of the project id=" + projectId);
+        }
+
+        Filter searchFilter = new Filter(ProjectAccountJoinVO.class, "id", false, startIndex, pageSizeVal);
+        SearchBuilder<ProjectAccountJoinVO> sb = _projectAccountJoinDao.createSearchBuilder();
+        sb.and("accountRole", sb.entity().getAccountRole(), Op.EQ);
+        sb.and("projectId", sb.entity().getProjectId(), Op.EQ);
+
+        if (accountName != null) {
+            sb.and("accountName", sb.entity().getAccountName(), Op.EQ);
+        }
+
+        SearchCriteria<ProjectAccountJoinVO> sc = sb.create();
+
+        sc.setParameters("projectId", projectId);
+
+        if (role != null) {
+            sc.setParameters("accountRole", role);
+        }
+
+        if (accountName != null) {
+            sc.setParameters("accountName", accountName);
+        }
+
+        return _projectAccountJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd) {
+        // FIXME: do we need to support list hosts with VmId, maybe we should
+        // create another command just for this
+        // Right now it is handled separately outside this QueryService
+        s_logger.debug(">>>Searching for hosts>>>");
+        Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(cmd);
+        ListResponse<HostResponse> response = new ListResponse<HostResponse>();
+        s_logger.debug(">>>Generating Response>>>");
+        List<HostResponse> hostResponses = ViewResponseHelper.createHostResponse(cmd.getDetails(), hosts.first().toArray(new HostJoinVO[hosts.first().size()]));
+        response.setResponses(hostResponses, hosts.second());
+        return response;
+    }
+
+    public Pair<List<HostJoinVO>, Integer> searchForServersInternal(ListHostsCmd cmd) {
+
+        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        Object name = cmd.getHostName();
+        Object type = cmd.getType();
+        Object state = cmd.getState();
+        Object pod = cmd.getPodId();
+        Object cluster = cmd.getClusterId();
+        Object id = cmd.getId();
+        Object keyword = cmd.getKeyword();
+        Object outOfBandManagementEnabled = cmd.isOutOfBandManagementEnabled();
+        Object powerState = cmd.getHostOutOfBandManagementPowerState();
+        Object resourceState = cmd.getResourceState();
+        Object haHosts = cmd.getHaHost();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+        Hypervisor.HypervisorType hypervisorType = cmd.getHypervisor();
+
+        Filter searchFilter = new Filter(HostJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+        SearchBuilder<HostJoinVO> sb = _hostJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
+        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+        sb.and("oobmEnabled", sb.entity().isOutOfBandManagementEnabled(), SearchCriteria.Op.EQ);
+        sb.and("powerState", sb.entity().getOutOfBandManagementPowerState(), SearchCriteria.Op.EQ);
+        sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
+        sb.and("hypervisor_type", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+
+        String haTag = _haMgr.getHaTag();
+        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
+            if ((Boolean)haHosts) {
+                sb.and("tag", sb.entity().getTag(), SearchCriteria.Op.EQ);
+            } else {
+                sb.and().op("tag", sb.entity().getTag(), SearchCriteria.Op.NEQ);
+                sb.or("tagNull", sb.entity().getTag(), SearchCriteria.Op.NULL);
+                sb.cp();
+            }
+
+        }
+
+        SearchCriteria<HostJoinVO> sc = sb.create();
+
+        if (keyword != null) {
+            SearchCriteria<HostJoinVO> ssc = _hostJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+        if (type != null) {
+            sc.setParameters("type", "%" + type);
+        }
+        if (state != null) {
+            sc.setParameters("status", state);
+        }
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (pod != null) {
+            sc.setParameters("podId", pod);
+        }
+        if (cluster != null) {
+            sc.setParameters("clusterId", cluster);
+        }
+
+        if (outOfBandManagementEnabled != null) {
+            sc.setParameters("oobmEnabled", outOfBandManagementEnabled);
+        }
+
+        if (powerState != null) {
+            sc.setParameters("powerState", powerState);
+        }
+
+        if (resourceState != null) {
+            sc.setParameters("resourceState", resourceState);
+        }
+
+        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
+            sc.setParameters("tag", haTag);
+        }
+
+        if (hypervisorType != HypervisorType.None && hypervisorType != HypervisorType.Any) {
+            sc.setParameters("hypervisor_type", hypervisorType);
+        }
+        // search host details by ids
+        Pair<List<HostJoinVO>, Integer> uniqueHostPair = _hostJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueHostPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return uniqueHostPair;
+        }
+        List<HostJoinVO> uniqueHosts = uniqueHostPair.first();
+        Long[] hostIds = new Long[uniqueHosts.size()];
+        int i = 0;
+        for (HostJoinVO v : uniqueHosts) {
+            hostIds[i++] = v.getId();
+        }
+        List<HostJoinVO> hosts = _hostJoinDao.searchByIds(hostIds);
+        return new Pair<List<HostJoinVO>, Integer>(hosts, count);
+
+    }
+
+    @Override
+    public ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd) {
+        Pair<List<VolumeJoinVO>, Integer> result = searchForVolumesInternal(cmd);
+        ListResponse<VolumeResponse> response = new ListResponse<VolumeResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListVolumesCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<VolumeResponse> volumeResponses = ViewResponseHelper.createVolumeResponse(respView, result.first().toArray(new VolumeJoinVO[result.first().size()]));
+
+        for (VolumeResponse vr : volumeResponses) {
+            String poolId = vr.getStoragePoolId();
+            if (poolId == null) {
+                continue;
+            }
+
+            DataStore store = dataStoreManager.getPrimaryDataStore(poolId);
+            if (store == null) {
+                continue;
+            }
+
+            DataStoreDriver driver = store.getDriver();
+            if (driver == null) {
+                continue;
+            }
+
+            Map<String, String> caps = driver.getCapabilities();
+            if (caps != null) {
+                boolean quiescevm = Boolean.parseBoolean(caps.get(DataStoreCapabilities.VOLUME_SNAPSHOT_QUIESCEVM.toString()));
+                vr.setNeedQuiescevm(quiescevm);
+            }
+        }
+        response.setResponses(volumeResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<VolumeJoinVO>, Integer> searchForVolumesInternal(ListVolumesCmd cmd) {
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Long id = cmd.getId();
+        Long vmInstanceId = cmd.getVirtualMachineId();
+        String name = cmd.getVolumeName();
+        String keyword = cmd.getKeyword();
+        String type = cmd.getType();
+        Map<String, String> tags = cmd.getTags();
+        String storageId = cmd.getStorageId();
+        Long clusterId = cmd.getClusterId();
+        Long diskOffId = cmd.getDiskOfferingId();
+        Boolean display = cmd.getDisplay();
+
+        Long zoneId = cmd.getZoneId();
+        Long podId = cmd.getPodId();
+
+        List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        Filter searchFilter = new Filter(VolumeJoinVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        // hack for now, this should be done better but due to needing a join I
+        // opted to
+        // do this quickly and worry about making it pretty later
+        SearchBuilder<VolumeJoinVO> sb = _volumeJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids to get
+        // number of
+        // records with
+        // pagination
+        _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
+        sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE);
+        sb.and("uuid", sb.entity().getUuid(), SearchCriteria.Op.NNULL);
+        sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.EQ);
+        sb.and("diskOfferingId", sb.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
+        // Only return volumes that are not destroyed
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
+        sb.and("systemUse", sb.entity().isSystemUse(), SearchCriteria.Op.NEQ);
+        // display UserVM volumes only
+        sb.and().op("type", sb.entity().getVmType(), SearchCriteria.Op.NIN);
+        sb.or("nulltype", sb.entity().getVmType(), SearchCriteria.Op.NULL);
+        sb.cp();
+
+        // now set the SC criteria...
+        SearchCriteria<VolumeJoinVO> sc = sb.create();
+        _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            SearchCriteria<VolumeJoinVO> ssc = _volumeJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", name);
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        setIdsListToSearchCriteria(sc, ids);
+
+        sc.setParameters("systemUse", 1);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchCriteria<VolumeJoinVO> tagSc = _volumeJoinDao.createSearchCriteria();
+            for (String key : tags.keySet()) {
+                SearchCriteria<VolumeJoinVO> tsc = _volumeJoinDao.createSearchCriteria();
+                tsc.addAnd("tagKey", SearchCriteria.Op.EQ, key);
+                tsc.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key));
+                tagSc.addOr("tagKey", SearchCriteria.Op.SC, tsc);
+            }
+            sc.addAnd("tagKey", SearchCriteria.Op.SC, tagSc);
+        }
+
+        if (diskOffId != null) {
+            sc.setParameters("diskOfferingId", diskOffId);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (type != null) {
+            sc.setParameters("volumeType", "%" + type + "%");
+        }
+        if (vmInstanceId != null) {
+            sc.setParameters("instanceId", vmInstanceId);
+        }
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (podId != null) {
+            sc.setParameters("podId", podId);
+        }
+
+        if (storageId != null) {
+            sc.setParameters("storageId", storageId);
+        }
+
+        if (clusterId != null) {
+            sc.setParameters("clusterId", clusterId);
+        }
+        // Don't return DomR and ConsoleProxy volumes
+        sc.setParameters("type", VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.DomainRouter);
+
+        // Only return volumes that are not destroyed
+        sc.setParameters("state", Volume.State.Destroy);
+
+        // search Volume details by ids
+        Pair<List<VolumeJoinVO>, Integer> uniqueVolPair = _volumeJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueVolPair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniqueVolPair;
+        }
+        List<VolumeJoinVO> uniqueVols = uniqueVolPair.first();
+        Long[] vrIds = new Long[uniqueVols.size()];
+        int i = 0;
+        for (VolumeJoinVO v : uniqueVols) {
+            vrIds[i++] = v.getId();
+        }
+        List<VolumeJoinVO> vrs = _volumeJoinDao.searchByIds(vrIds);
+        return new Pair<List<VolumeJoinVO>, Integer>(vrs, count);
+    }
+
+    @Override
+    public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd) {
+        Pair<List<DomainJoinVO>, Integer> result = searchForDomainsInternal(cmd);
+        ListResponse<DomainResponse> response = new ListResponse<DomainResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListDomainsCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<DomainResponse> domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first());
+        response.setResponses(domainResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<DomainJoinVO>, Integer> searchForDomainsInternal(ListDomainsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long domainId = cmd.getId();
+        boolean listAll = cmd.listAll();
+        boolean isRecursive = false;
+        Domain domain = null;
+
+        if (domainId != null) {
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
+            }
+            _accountMgr.checkAccess(caller, domain);
+        } else {
+            if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+                domainId = caller.getDomainId();
+            }
+            if (listAll) {
+                isRecursive = true;
+            }
+        }
+
+        Filter searchFilter = new Filter(DomainJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        String domainName = cmd.getDomainName();
+        Integer level = cmd.getLevel();
+        Object keyword = cmd.getKeyword();
+
+        SearchBuilder<DomainJoinVO> sb = _domainJoinDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ);
+        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<DomainJoinVO> sc = sb.create();
+
+        if (keyword != null) {
+            SearchCriteria<DomainJoinVO> ssc = _domainJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (domainName != null) {
+            sc.setParameters("name", domainName);
+        }
+
+        if (level != null) {
+            sc.setParameters("level", level);
+        }
+
+        if (domainId != null) {
+            if (isRecursive) {
+                if (domain == null) {
+                    domain = _domainDao.findById(domainId);
+                }
+                sc.setParameters("path", domain.getPath() + "%");
+            } else {
+                sc.setParameters("id", domainId);
+            }
+        }
+
+        // return only Active domains to the API
+        sc.setParameters("state", Domain.State.Active);
+
+        return _domainJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd) {
+        Pair<List<AccountJoinVO>, Integer> result = searchForAccountsInternal(cmd);
+        ListResponse<AccountResponse> response = new ListResponse<AccountResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListAccountsCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<AccountResponse> accountResponses = ViewResponseHelper.createAccountResponse(respView, result.first().toArray(new AccountJoinVO[result.first().size()]));
+        response.setResponses(accountResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<AccountJoinVO>, Integer> searchForAccountsInternal(ListAccountsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long domainId = cmd.getDomainId();
+        Long accountId = cmd.getId();
+        String accountName = cmd.getSearchName();
+        boolean isRecursive = cmd.isRecursive();
+        boolean listAll = cmd.listAll();
+        boolean callerIsAdmin = _accountMgr.isAdmin(caller.getId());
+        Account account;
+        Domain domain = null;
+
+        // if "domainid" specified, perform validation
+        if (domainId != null) {
+            // ensure existence...
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
+            }
+            // ... and check access rights.
+            _accountMgr.checkAccess(caller, domain);
+        }
+
+        // if no "id" specified...
+        if (accountId == null) {
+            // listall only has significance if they are an admin
+            if (listAll && callerIsAdmin) {
+                // if no domain id specified, use caller's domain
+                if (domainId == null) {
+                    domainId = caller.getDomainId();
+                }
+                // mark recursive
+                isRecursive = true;
+            } else if (!callerIsAdmin || domainId == null) {
+                accountId = caller.getAccountId();
+            }
+        } else if (domainId != null && accountName != null) {
+            // if they're looking for an account by name
+            account = _accountDao.findActiveAccount(accountName, domainId);
+            if (account == null || account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain " + domainId);
+            }
+            _accountMgr.checkAccess(caller, null, true, account);
+        } else {
+            // if they specified an "id"...
+            if (domainId == null) {
+                account = _accountDao.findById(accountId);
+            } else {
+                account = _accountDao.findActiveAccountById(accountId, domainId);
+            }
+            if (account == null || account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+                throw new InvalidParameterValueException("Unable to find account by id " + accountId + (domainId == null ? "" : " in domain " + domainId));
+            }
+            _accountMgr.checkAccess(caller, null, true, account);
+        }
+
+        Filter searchFilter = new Filter(AccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        Object type = cmd.getAccountType();
+        Object state = cmd.getState();
+        Object isCleanupRequired = cmd.isCleanupRequired();
+        Object keyword = cmd.getKeyword();
+
+        SearchBuilder<AccountJoinVO> sb = _accountJoinDao.createSearchBuilder();
+        sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("needsCleanup", sb.entity().isNeedsCleanup(), SearchCriteria.Op.EQ);
+        sb.and("typeNEQ", sb.entity().getType(), SearchCriteria.Op.NEQ);
+        sb.and("idNEQ", sb.entity().getId(), SearchCriteria.Op.NEQ);
+
+        if (domainId != null && isRecursive) {
+            sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        SearchCriteria<AccountJoinVO> sc = sb.create();
+
+        // don't return account of type project to the end user
+        sc.setParameters("typeNEQ", Account.ACCOUNT_TYPE_PROJECT);
+        // don't return system account...
+        sc.setParameters("idNEQ", Account.ACCOUNT_ID_SYSTEM);
+
+        if (keyword != null) {
+            SearchCriteria<AccountJoinVO> ssc = _accountJoinDao.createSearchCriteria();
+            ssc.addOr("accountName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("accountName", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (type != null) {
+            sc.setParameters("type", type);
+        }
+
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+
+        if (isCleanupRequired != null) {
+            sc.setParameters("needsCleanup", isCleanupRequired);
+        }
+
+        if (accountName != null) {
+            sc.setParameters("accountName", accountName);
+        }
+
+        if (accountId != null) {
+            sc.setParameters("id", accountId);
+        }
+
+        if (domainId != null) {
+            if (isRecursive) {
+                // will happen if no "domainid" was specified in the request...
+                if (domain == null) {
+                    domain = _domainDao.findById(domainId);
+                }
+                sc.setParameters("path", domain.getPath() + "%");
+            } else {
+                sc.setParameters("domainId", domainId);
+            }
+        }
+
+        return _accountJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<AsyncJobResponse> searchForAsyncJobs(ListAsyncJobsCmd cmd) {
+        Pair<List<AsyncJobJoinVO>, Integer> result = searchForAsyncJobsInternal(cmd);
+        ListResponse<AsyncJobResponse> response = new ListResponse<AsyncJobResponse>();
+        List<AsyncJobResponse> jobResponses = ViewResponseHelper.createAsyncJobResponse(result.first().toArray(new AsyncJobJoinVO[result.first().size()]));
+        response.setResponses(jobResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<AsyncJobJoinVO>, Integer> searchForAsyncJobsInternal(ListAsyncJobsCmd cmd) {
+
+        Account caller = CallContext.current().getCallingAccount();
+
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(AsyncJobJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<AsyncJobJoinVO> sb = _jobJoinDao.createSearchBuilder();
+        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+        boolean accountJoinIsDone = false;
+        if (permittedAccounts.isEmpty() && domainId != null) {
+            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+            sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+            accountJoinIsDone = true;
+        }
+
+        if (listProjectResourcesCriteria != null) {
+
+            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
+                sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
+            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
+                sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
+            }
+
+            if (!accountJoinIsDone) {
+                sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+                sb.and("path", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+            }
+        }
+
+        Object keyword = cmd.getKeyword();
+        Object startDate = cmd.getStartDate();
+
+        SearchCriteria<AsyncJobJoinVO> sc = sb.create();
+        if (listProjectResourcesCriteria != null) {
+            sc.setParameters("type", Account.ACCOUNT_TYPE_PROJECT);
+        }
+
+        if (!permittedAccounts.isEmpty()) {
+            sc.setParameters("accountIdIN", permittedAccounts.toArray());
+        } else if (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            if (isRecursive) {
+                sc.setParameters("path", domain.getPath() + "%");
+            } else {
+                sc.setParameters("domainId", domainId);
+            }
+        }
+
+        if (keyword != null) {
+            sc.addAnd("cmd", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+        }
+
+        if (startDate != null) {
+            sc.addAnd("created", SearchCriteria.Op.GTEQ, startDate);
+        }
+
+        return _jobJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public ListResponse<StoragePoolResponse> searchForStoragePools(ListStoragePoolsCmd cmd) {
+        Pair<List<StoragePoolJoinVO>, Integer> result = searchForStoragePoolsInternal(cmd);
+        ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
+
+        List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(result.first().toArray(new StoragePoolJoinVO[result.first().size()]));
+        for (StoragePoolResponse poolResponse : poolResponses) {
+            DataStore store = dataStoreManager.getPrimaryDataStore(poolResponse.getId());
+            if (store != null) {
+                DataStoreDriver driver = store.getDriver();
+                if (driver != null && driver.getCapabilities() != null) {
+                    poolResponse.setCaps(driver.getCapabilities());
+                }
+            }
+        }
+
+        response.setResponses(poolResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<StoragePoolJoinVO>, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) {
+        ScopeType scopeType = null;
+        if (cmd.getScope() != null) {
+            try {
+                scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase());
+            } catch (Exception e) {
+                throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope());
+            }
+        }
+
+        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        Object id = cmd.getId();
+        Object name = cmd.getStoragePoolName();
+        Object path = cmd.getPath();
+        Object pod = cmd.getPodId();
+        Object cluster = cmd.getClusterId();
+        Object address = cmd.getIpAddress();
+        Object keyword = cmd.getKeyword();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        Filter searchFilter = new Filter(StoragePoolJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+        SearchBuilder<StoragePoolJoinVO> sb = _poolJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+        sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
+        sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<StoragePoolJoinVO> sc = sb.create();
+
+        if (keyword != null) {
+            SearchCriteria<StoragePoolJoinVO> ssc = _poolJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", name);
+        }
+
+        if (path != null) {
+            sc.setParameters("path", path);
+        }
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (pod != null) {
+            sc.setParameters("podId", pod);
+        }
+        if (address != null) {
+            sc.setParameters("hostAddress", address);
+        }
+        if (cluster != null) {
+            sc.setParameters("clusterId", cluster);
+        }
+        if (scopeType != null) {
+            sc.setParameters("scope", scopeType.toString());
+        }
+
+        // search Pool details by ids
+        Pair<List<StoragePoolJoinVO>, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniquePoolPair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniquePoolPair;
+        }
+        List<StoragePoolJoinVO> uniquePools = uniquePoolPair.first();
+        Long[] vrIds = new Long[uniquePools.size()];
+        int i = 0;
+        for (StoragePoolJoinVO v : uniquePools) {
+            vrIds[i++] = v.getId();
+        }
+        List<StoragePoolJoinVO> vrs = _poolJoinDao.searchByIds(vrIds);
+        return new Pair<List<StoragePoolJoinVO>, Integer>(vrs, count);
+
+    }
+
+    @Override
+    public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd) {
+        Pair<List<StoragePoolTagVO>, Integer> result = searchForStorageTagsInternal(cmd);
+        ListResponse<StorageTagResponse> response = new ListResponse<StorageTagResponse>();
+        List<StorageTagResponse> tagResponses = ViewResponseHelper.createStorageTagResponse(result.first().toArray(new StoragePoolTagVO[result.first().size()]));
+
+        response.setResponses(tagResponses, result.second());
+
+        return response;
+    }
+
+    private Pair<List<StoragePoolTagVO>, Integer> searchForStorageTagsInternal(ListStorageTagsCmd cmd) {
+        Filter searchFilter = new Filter(StoragePoolTagVO.class, "id", Boolean.TRUE, null, null);
+
+        SearchBuilder<StoragePoolTagVO> sb = _storageTagDao.createSearchBuilder();
+
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+
+        SearchCriteria<StoragePoolTagVO> sc = sb.create();
+
+        // search storage tag details by ids
+        Pair<List<StoragePoolTagVO>, Integer> uniqueTagPair = _storageTagDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueTagPair.second();
+
+        if (count.intValue() == 0) {
+            return uniqueTagPair;
+        }
+
+        List<StoragePoolTagVO> uniqueTags = uniqueTagPair.first();
+        Long[] vrIds = new Long[uniqueTags.size()];
+        int i = 0;
+
+        for (StoragePoolTagVO v : uniqueTags) {
+            vrIds[i++] = v.getId();
+        }
+
+        List<StoragePoolTagVO> vrs = _storageTagDao.searchByIds(vrIds);
+
+        return new Pair<List<StoragePoolTagVO>, Integer>(vrs, count);
+    }
+
+    @Override
+    public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
+        Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
+        ListResponse<HostTagResponse> response = new ListResponse<HostTagResponse>();
+        List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
+
+        response.setResponses(tagResponses, result.second());
+
+        return response;
+    }
+
+    private Pair<List<HostTagVO>, Integer> searchForHostTagsInternal(ListHostTagsCmd cmd) {
+        Filter searchFilter = new Filter(HostTagVO.class, "id", Boolean.TRUE, null, null);
+
+        SearchBuilder<HostTagVO> sb = _hostTagDao.createSearchBuilder();
+
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+
+        SearchCriteria<HostTagVO> sc = sb.create();
+
+        // search host tag details by ids
+        Pair<List<HostTagVO>, Integer> uniqueTagPair = _hostTagDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueTagPair.second();
+
+        if (count.intValue() == 0) {
+            return uniqueTagPair;
+        }
+
+        List<HostTagVO> uniqueTags = uniqueTagPair.first();
+        Long[] vrIds = new Long[uniqueTags.size()];
+        int i = 0;
+
+        for (HostTagVO v : uniqueTags) {
+            vrIds[i++] = v.getId();
+        }
+
+        List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
+
+        return new Pair<List<HostTagVO>, Integer>(vrs, count);
+    }
+
+    @Override
+    public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
+        Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);
+        ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
+
+        List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
+        response.setResponses(poolResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<ImageStoreJoinVO>, Integer> searchForImageStoresInternal(ListImageStoresCmd cmd) {
+
+        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        Object id = cmd.getId();
+        Object name = cmd.getStoreName();
+        String provider = cmd.getProvider();
+        String protocol = cmd.getProtocol();
+        Object keyword = cmd.getKeyword();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+        SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ);
+        sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
+        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<ImageStoreJoinVO> sc = sb.create();
+        sc.setParameters("role", DataStoreRole.Image);
+
+        if (keyword != null) {
+            SearchCriteria<ImageStoreJoinVO> ssc = _imageStoreJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("providerName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", name);
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (provider != null) {
+            sc.setParameters("provider", provider);
+        }
+        if (protocol != null) {
+            sc.setParameters("protocol", protocol);
+        }
+
+        // search Store details by ids
+        Pair<List<ImageStoreJoinVO>, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueStorePair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniqueStorePair;
+        }
+        List<ImageStoreJoinVO> uniqueStores = uniqueStorePair.first();
+        Long[] vrIds = new Long[uniqueStores.size()];
+        int i = 0;
+        for (ImageStoreJoinVO v : uniqueStores) {
+            vrIds[i++] = v.getId();
+        }
+        List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
+        return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
+
+    }
+
+    @Override
+    public ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd) {
+        Pair<List<ImageStoreJoinVO>, Integer> result = searchForCacheStoresInternal(cmd);
+        ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
+
+        List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
+        response.setResponses(poolResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<ImageStoreJoinVO>, Integer> searchForCacheStoresInternal(ListSecondaryStagingStoresCmd cmd) {
+
+        Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        Object id = cmd.getId();
+        Object name = cmd.getStoreName();
+        String provider = cmd.getProvider();
+        String protocol = cmd.getProtocol();
+        Object keyword = cmd.getKeyword();
+        Long startIndex = cmd.getStartIndex();
+        Long pageSize = cmd.getPageSizeVal();
+
+        Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+        SearchBuilder<ImageStoreJoinVO> sb = _imageStoreJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct
+        // ids
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ);
+        sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
+        sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<ImageStoreJoinVO> sc = sb.create();
+        sc.setParameters("role", DataStoreRole.ImageCache);
+
+        if (keyword != null) {
+            SearchCriteria<ImageStoreJoinVO> ssc = _imageStoreJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("provider", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", name);
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (provider != null) {
+            sc.setParameters("provider", provider);
+        }
+        if (protocol != null) {
+            sc.setParameters("protocol", protocol);
+        }
+
+        // search Store details by ids
+        Pair<List<ImageStoreJoinVO>, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter);
+        Integer count = uniqueStorePair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniqueStorePair;
+        }
+        List<ImageStoreJoinVO> uniqueStores = uniqueStorePair.first();
+        Long[] vrIds = new Long[uniqueStores.size()];
+        int i = 0;
+        for (ImageStoreJoinVO v : uniqueStores) {
+            vrIds[i++] = v.getId();
+        }
+        List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
+        return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
+
+    }
+
+    @Override
+    public ListResponse<DiskOfferingResponse> searchForDiskOfferings(ListDiskOfferingsCmd cmd) {
+        Pair<List<DiskOfferingJoinVO>, Integer> result = searchForDiskOfferingsInternal(cmd);
+        ListResponse<DiskOfferingResponse> response = new ListResponse<DiskOfferingResponse>();
+        List<DiskOfferingResponse> offeringResponses = ViewResponseHelper.createDiskOfferingResponse(result.first().toArray(new DiskOfferingJoinVO[result.first().size()]));
+        response.setResponses(offeringResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<DiskOfferingJoinVO>, Integer> searchForDiskOfferingsInternal(ListDiskOfferingsCmd cmd) {
+        // Note
+        // The list method for offerings is being modified in accordance with
+        // discussion with Will/Kevin
+        // For now, we will be listing the following based on the usertype
+        // 1. For root, we will list all offerings
+        // 2. For domainAdmin and regular users, we will list everything in
+        // their domains+parent domains ... all the way
+        // till
+        // root
+
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = (isAscending == null ? true : isAscending);
+        Filter searchFilter = new Filter(DiskOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchCriteria<DiskOfferingJoinVO> sc = _diskOfferingJoinDao.createSearchCriteria();
+        sc.addAnd("type", Op.EQ, DiskOfferingVO.Type.Disk);
+
+        Account account = CallContext.current().getCallingAccount();
+        Object name = cmd.getDiskOfferingName();
+        Object id = cmd.getId();
+        Object keyword = cmd.getKeyword();
+        Long domainId = cmd.getDomainId();
+        Boolean isRootAdmin = _accountMgr.isRootAdmin(account.getAccountId());
+        Boolean isRecursive = cmd.isRecursive();
+        // Keeping this logic consistent with domain specific zones
+        // if a domainId is provided, we just return the disk offering
+        // associated with this domain
+        if (domainId != null) {
+            if (_accountMgr.isRootAdmin(account.getId()) || isPermissible(account.getDomainId(), domainId)) {
+                // check if the user's domain == do's domain || user's domain is
+                // a child of so's domain for non-root users
+                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+                if (!isRootAdmin) {
+                    sc.addAnd("displayOffering", SearchCriteria.Op.EQ, 1);
+                }
+                return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
+            } else {
+                throw new PermissionDeniedException("The account:" + account.getAccountName() + " does not fall in the same domain hierarchy as the disk offering");
+            }
+        }
+
+        List<Long> domainIds = null;
+        // For non-root users, only return all offerings for the user's domain,
+        // and everything above till root
+        if ((_accountMgr.isNormalUser(account.getId()) || _accountMgr.isDomainAdmin(account.getId())) || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+            if (isRecursive) { // domain + all sub-domains
+                if (account.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                    throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list disk offerings with isrecursive=true");
+                }
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domainRecord.getPath() + "%");
+            } else { // domain + all ancestors
+                // find all domain Id up to root domain for this account
+                domainIds = new ArrayList<Long>();
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                if (domainRecord == null) {
+                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
+                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
+                }
+                domainIds.add(domainRecord.getId());
+                while (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+
+                SearchCriteria<DiskOfferingJoinVO> spc = _diskOfferingJoinDao.createSearchCriteria();
+
+                spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
+                spc.addOr("domainId", SearchCriteria.Op.NULL); // include public offering as where
+                sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
+                sc.addAnd("systemUse", SearchCriteria.Op.EQ, false); // non-root users should not see system offering at all
+            }
+
+        }
+
+        if (keyword != null) {
+            SearchCriteria<DiskOfferingJoinVO> ssc = _diskOfferingJoinDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+
+        // FIXME: disk offerings should search back up the hierarchy for
+        // available disk offerings...
+        /*
+         * sb.addAnd("domainId", sb.entity().getDomainId(),
+         * SearchCriteria.Op.EQ); if (domainId != null) {
+         * SearchBuilder<DomainVO> domainSearch =
+         * _domainDao.createSearchBuilder(); domainSearch.addAnd("path",
+         * domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
+         * sb.join("domainSearch", domainSearch, sb.entity().getDomainId(),
+         * domainSearch.entity().getId()); }
+         */
+
+        // FIXME: disk offerings should search back up the hierarchy for
+        // available disk offerings...
+        /*
+         * if (domainId != null) { sc.setParameters("domainId", domainId); //
+         * //DomainVO domain = _domainDao.findById((Long)domainId); // // I want
+         * to join on user_vm.domain_id = domain.id where domain.path like
+         * 'foo%' //sc.setJoinParameters("domainSearch", "path",
+         * domain.getPath() + "%"); // }
+         */
+
+        return _diskOfferingJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    private List<ServiceOfferingJoinVO> filterOfferingsOnCurrentTags(List<ServiceOfferingJoinVO> offerings, ServiceOfferingVO currentVmOffering) {
+        if (currentVmOffering == null) {
+            return offerings;
+        }
+        List<String> currentTagsList = StringUtils.csvTagsToList(currentVmOffering.getTags());
+
+        // New service offering should have all the tags of the current service offering.
+        List<ServiceOfferingJoinVO> filteredOfferings = new ArrayList<>();
+        for (ServiceOfferingJoinVO offering : offerings) {
+            List<String> newTagsList = StringUtils.csvTagsToList(offering.getTags());
+            if (newTagsList.containsAll(currentTagsList)) {
+                filteredOfferings.add(offering);
+            }
+        }
+        return filteredOfferings;
+    }
+
+    @Override
+    public ListResponse<ServiceOfferingResponse> searchForServiceOfferings(ListServiceOfferingsCmd cmd) {
+        Pair<List<ServiceOfferingJoinVO>, Integer> result = searchForServiceOfferingsInternal(cmd);
+        result.first();
+        ListResponse<ServiceOfferingResponse> response = new ListResponse<ServiceOfferingResponse>();
+        List<ServiceOfferingResponse> offeringResponses = ViewResponseHelper.createServiceOfferingResponse(result.first().toArray(new ServiceOfferingJoinVO[result.first().size()]));
+        response.setResponses(offeringResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<ServiceOfferingJoinVO>, Integer> searchForServiceOfferingsInternal(ListServiceOfferingsCmd cmd) {
+        // Note
+        // The filteredOfferings method for offerings is being modified in accordance with
+        // discussion with Will/Kevin
+        // For now, we will be listing the following based on the usertype
+        // 1. For root, we will filteredOfferings all offerings
+        // 2. For domainAdmin and regular users, we will filteredOfferings everything in
+        // their domains+parent domains ... all the way
+        // till
+        // root
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = (isAscending == null ? true : isAscending);
+        Filter searchFilter = new Filter(ServiceOfferingJoinVO.class, "sortKey", isAscending, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        Account caller = CallContext.current().getCallingAccount();
+        Object name = cmd.getServiceOfferingName();
+        Object id = cmd.getId();
+        Object keyword = cmd.getKeyword();
+        Long vmId = cmd.getVirtualMachineId();
+        Long domainId = cmd.getDomainId();
+        Boolean isSystem = cmd.getIsSystem();
+        String vmTypeStr = cmd.getSystemVmType();
+        ServiceOfferingVO currentVmOffering = null;
+        Boolean isRecursive = cmd.isRecursive();
+
+        SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
+        if (!_accountMgr.isRootAdmin(caller.getId()) && isSystem) {
+            throw new InvalidParameterValueException("Only ROOT admins can access system's offering");
+        }
+
+        // Keeping this logic consistent with domain specific zones
+        // if a domainId is provided, we just return the so associated with this
+        // domain
+        if (domainId != null && !_accountMgr.isRootAdmin(caller.getId())) {
+            // check if the user's domain == so's domain || user's domain is a
+            // child of so's domain
+            if (!isPermissible(caller.getDomainId(), domainId)) {
+                throw new PermissionDeniedException("The account:" + caller.getAccountName() + " does not fall in the same domain hierarchy as the service offering");
+            }
+        }
+
+        if (vmId != null) {
+            VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+            if ((vmInstance == null) || (vmInstance.getRemoved() != null)) {
+                InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
+                ex.addProxyObject(vmId.toString(), "vmId");
+                throw ex;
+            }
+
+            _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+            currentVmOffering = _srvOfferingDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+            sc.addAnd("id", SearchCriteria.Op.NEQ, currentVmOffering.getId());
+
+            // 1. Only return offerings with the same storage type
+            sc.addAnd("useLocalStorage", SearchCriteria.Op.EQ, currentVmOffering.isUseLocalStorage());
+
+            // 2.In case vm is running return only offerings greater than equal to current offering compute.
+            if (vmInstance.getState() == VirtualMachine.State.Running) {
+                sc.addAnd("cpu", Op.GTEQ, currentVmOffering.getCpu());
+                sc.addAnd("speed", Op.GTEQ, currentVmOffering.getSpeed());
+                sc.addAnd("ramSize", Op.GTEQ, currentVmOffering.getRamSize());
+            }
+        }
+
+        // boolean includePublicOfferings = false;
+        if ((_accountMgr.isNormalUser(caller.getId()) || _accountMgr.isDomainAdmin(caller.getId())) || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+            // For non-root users.
+            if (isSystem) {
+                throw new InvalidParameterValueException("Only root admins can access system's offering");
+            }
+            if (isRecursive) { // domain + all sub-domains
+                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                    throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list service offerings with isrecursive=true");
+                }
+                DomainVO domainRecord = _domainDao.findById(caller.getDomainId());
+                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domainRecord.getPath() + "%");
+            } else { // domain + all ancestors
+                // find all domain Id up to root domain for this account
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord;
+                if (vmId != null) {
+                    UserVmVO vmInstance = _userVmDao.findById(vmId);
+                    domainRecord = _domainDao.findById(vmInstance.getDomainId());
+                    if (domainRecord == null) {
+                        s_logger.error("Could not find the domainId for vmId:" + vmId);
+                        throw new CloudAuthenticationException("Could not find the domainId for vmId:" + vmId);
+                    }
+                } else {
+                    domainRecord = _domainDao.findById(caller.getDomainId());
+                    if (domainRecord == null) {
+                        s_logger.error("Could not find the domainId for account:" + caller.getAccountName());
+                        throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName());
+                    }
+                }
+                domainIds.add(domainRecord.getId());
+                while (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+
+                SearchCriteria<ServiceOfferingJoinVO> spc = _srvOfferingJoinDao.createSearchCriteria();
+                spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
+                spc.addOr("domainId", SearchCriteria.Op.NULL); // include public offering as well
+                sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
+            }
+        } else {
+            // for root users
+            if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
+                throw new InvalidParameterValueException("Non ROOT admins cannot access system's offering");
+            }
+            if (domainId != null) {
+                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+            }
+        }
+
+        if (keyword != null) {
+            SearchCriteria<ServiceOfferingJoinVO> ssc = _srvOfferingJoinDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (isSystem != null) {
+            // note that for non-root users, isSystem is always false when
+            // control comes to here
+            sc.addAnd("systemUse", SearchCriteria.Op.EQ, isSystem);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+
+        if (vmTypeStr != null) {
+            sc.addAnd("vmType", SearchCriteria.Op.EQ, vmTypeStr);
+        }
+
+        Pair<List<ServiceOfferingJoinVO>, Integer> result = _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
+
+        //Couldn't figure out a smart way to filter offerings based on tags in sql so doing it in Java.
+        List<ServiceOfferingJoinVO> filteredOfferings = filterOfferingsOnCurrentTags(result.first(), currentVmOffering);
+        return new Pair<>(filteredOfferings, result.second());
+    }
+
+    @Override
+    public ListResponse<ZoneResponse> listDataCenters(ListZonesCmd cmd) {
+        Pair<List<DataCenterJoinVO>, Integer> result = listDataCentersInternal(cmd);
+        ListResponse<ZoneResponse> response = new ListResponse<ZoneResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListZonesCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<ZoneResponse> dcResponses = ViewResponseHelper.createDataCenterResponse(respView, cmd.getShowCapacities(), result.first().toArray(new DataCenterJoinVO[result.first().size()]));
+        response.setResponses(dcResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<DataCenterJoinVO>, Integer> listDataCentersInternal(ListZonesCmd cmd) {
+        Account account = CallContext.current().getCallingAccount();
+        Long domainId = cmd.getDomainId();
+        Long id = cmd.getId();
+        String keyword = cmd.getKeyword();
+        String name = cmd.getName();
+        String networkType = cmd.getNetworkType();
+        Map<String, String> resourceTags = cmd.getTags();
+
+        SearchBuilder<DataCenterJoinVO> sb = _dcJoinDao.createSearchBuilder();
+        if (resourceTags != null && !resourceTags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < resourceTags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchCriteria<DataCenterJoinVO> sc = sb.create();
+
+        if (networkType != null) {
+            sc.addAnd("networkType", SearchCriteria.Op.EQ, networkType);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        } else if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        } else {
+            if (keyword != null) {
+                SearchCriteria<DataCenterJoinVO> ssc = _dcJoinDao.createSearchCriteria();
+                ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+                ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+                sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+            }
+
+            /*
+             * List all resources due to Explicit Dedication except the
+             * dedicated resources of other account
+             */
+            if (domainId != null) { //
+                // for domainId != null // right now, we made the decision to
+                // only list zones associated // with this domain, private zone
+                sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
+
+                if (_accountMgr.isNormalUser(account.getId())) {
+                    // accountId == null (zones dedicated to a domain) or
+                    // accountId = caller
+                    SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
+                    sdc.addOr("accountId", SearchCriteria.Op.EQ, account.getId());
+                    sdc.addOr("accountId", SearchCriteria.Op.NULL);
+
+                    sc.addAnd("accountId", SearchCriteria.Op.SC, sdc);
+                }
+
+            } else if (_accountMgr.isNormalUser(account.getId())) {
+                // it was decided to return all zones for the user's domain, and
+                // everything above till root
+                // list all zones belonging to this domain, and all of its
+                // parents
+                // check the parent, if not null, add zones for that parent to
+                // list
+
+                // find all domain Id up to root domain for this account
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                if (domainRecord == null) {
+                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
+                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
+                }
+                domainIds.add(domainRecord.getId());
+                while (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+                // domainId == null (public zones) or domainId IN [all domain id
+                // up to root domain]
+                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
+                sdc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
+                sdc.addOr("domainId", SearchCriteria.Op.NULL);
+                sc.addAnd("domainId", SearchCriteria.Op.SC, sdc);
+
+                // remove disabled zones
+                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
+
+                // accountId == null (zones dedicated to a domain) or
+                // accountId = caller
+                SearchCriteria<DataCenterJoinVO> sdc2 = _dcJoinDao.createSearchCriteria();
+                sdc2.addOr("accountId", SearchCriteria.Op.EQ, account.getId());
+                sdc2.addOr("accountId", SearchCriteria.Op.NULL);
+
+                sc.addAnd("accountId", SearchCriteria.Op.SC, sdc2);
+
+                // remove Dedicated zones not dedicated to this domainId or
+                // subdomainId
+                List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
+                if (!dedicatedZoneIds.isEmpty()) {
+                    sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
+                }
+
+            } else if (_accountMgr.isDomainAdmin(account.getId()) || account.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                // it was decided to return all zones for the domain admin, and
+                // everything above till root, as well as zones till the domain
+                // leaf
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord = _domainDao.findById(account.getDomainId());
+                if (domainRecord == null) {
+                    s_logger.error("Could not find the domainId for account:" + account.getAccountName());
+                    throw new CloudAuthenticationException("Could not find the domainId for account:" + account.getAccountName());
+                }
+                domainIds.add(domainRecord.getId());
+                // find all domain Ids till leaf
+                List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainRecord.getPath(), domainRecord.getId());
+                for (DomainVO domain : allChildDomains) {
+                    domainIds.add(domain.getId());
+                }
+                // then find all domain Id up to root domain for this account
+                while (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+
+                // domainId == null (public zones) or domainId IN [all domain id
+                // up to root domain]
+                SearchCriteria<DataCenterJoinVO> sdc = _dcJoinDao.createSearchCriteria();
+                sdc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
+                sdc.addOr("domainId", SearchCriteria.Op.NULL);
+                sc.addAnd("domainId", SearchCriteria.Op.SC, sdc);
+
+                // remove disabled zones
+                sc.addAnd("allocationState", SearchCriteria.Op.NEQ, Grouping.AllocationState.Disabled);
+
+                // remove Dedicated zones not dedicated to this domainId or
+                // subdomainId
+                List<Long> dedicatedZoneIds = removeDedicatedZoneNotSuitabe(domainIds);
+                if (!dedicatedZoneIds.isEmpty()) {
+                    sdc.addAnd("id", SearchCriteria.Op.NIN, dedicatedZoneIds.toArray(new Object[dedicatedZoneIds.size()]));
+                }
+            }
+
+            // handle available=FALSE option, only return zones with at least
+            // one VM running there
+            Boolean available = cmd.isAvailable();
+            if (account != null) {
+                if ((available != null) && Boolean.FALSE.equals(available)) {
+                    Set<Long> dcIds = new HashSet<Long>(); // data centers with
+                    // at least one VM
+                    // running
+                    List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
+                    for (DomainRouterVO router : routers) {
+                        dcIds.add(router.getDataCenterId());
+                    }
+                    if (dcIds.size() == 0) {
+                        return new Pair<List<DataCenterJoinVO>, Integer>(new ArrayList<DataCenterJoinVO>(), 0);
+                    } else {
+                        sc.addAnd("id", SearchCriteria.Op.IN, dcIds.toArray());
+                    }
+
+                }
+            }
+        }
+
+        if (resourceTags != null && !resourceTags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Zone.toString());
+            for (Map.Entry<String, String> entry : resourceTags.entrySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
+                count++;
+            }
+        }
+
+        return _dcJoinDao.searchAndCount(sc, searchFilter);
+    }
+
+    private List<Long> removeDedicatedZoneNotSuitabe(List<Long> domainIds) {
+        // remove dedicated zone of other domain
+        List<Long> dedicatedZoneIds = new ArrayList<Long>();
+        List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listZonesNotInDomainIds(domainIds);
+        for (DedicatedResourceVO dr : dedicatedResources) {
+            if (dr != null) {
+                dedicatedZoneIds.add(dr.getDataCenterId());
+            }
+        }
+        return dedicatedZoneIds;
+    }
+
+    // This method is used for permissions check for both disk and service
+    // offerings
+    private boolean isPermissible(Long accountDomainId, Long offeringDomainId) {
+
+        if (accountDomainId.equals(offeringDomainId)) {
+            return true; // account and service offering in same domain
+        }
+
+        DomainVO domainRecord = _domainDao.findById(accountDomainId);
+
+        if (domainRecord != null) {
+            while (true) {
+                if (domainRecord.getId() == offeringDomainId) {
+                    return true;
+                }
+
+                // try and move on to the next domain
+                if (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                } else {
+                    break;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd) {
+        Pair<List<TemplateJoinVO>, Integer> result = searchForTemplatesInternal(cmd);
+        ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListTemplatesCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<TemplateResponse> templateResponses = ViewResponseHelper.createTemplateResponse(respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
+        response.setResponses(templateResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) {
+        TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter());
+        Long id = cmd.getId();
+        Map<String, String> tags = cmd.getTags();
+        boolean showRemovedTmpl = cmd.getShowRemoved();
+        Account caller = CallContext.current().getCallingAccount();
+        Long parentTemplateId = cmd.getParentTemplateId();
+
+        boolean listAll = false;
+        if (templateFilter != null && templateFilter == TemplateFilter.all) {
+            if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only");
+            }
+            listAll = true;
+        }
+
+        List<Long> permittedAccountIds = new ArrayList<Long>();
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false);
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        List<Account> permittedAccounts = new ArrayList<Account>();
+        for (Long accountId : permittedAccountIds) {
+            permittedAccounts.add(_accountMgr.getAccount(accountId));
+        }
+
+        boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured));
+        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
+
+        return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(), hypervisorType,
+                showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedTmpl, cmd.getIds(), parentTemplateId);
+    }
+
+    private Pair<List<TemplateJoinVO>, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize,
+            Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List<Account> permittedAccounts, Account caller,
+            ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags, boolean showRemovedTmpl, List<Long> ids, Long parentTemplateId) {
+
+        // check if zone is configured, if not, just return empty list
+        List<HypervisorType> hypers = null;
+        if (!isIso) {
+            hypers = _resourceMgr.listAvailHypervisorInZone(null, null);
+            if (hypers == null || hypers.isEmpty()) {
+                return new Pair<List<TemplateJoinVO>, Integer>(new ArrayList<TemplateJoinVO>(), 0);
+            }
+        }
+
+        VMTemplateVO template = null;
+
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = (isAscending == null ? Boolean.TRUE : isAscending);
+        Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize);
+        searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", isAscending);
+
+        SearchBuilder<TemplateJoinVO> sb = _templateJoinDao.createSearchBuilder();
+        sb.select(null, Func.DISTINCT, sb.entity().getTempZonePair()); // select distinct (templateId, zoneId) pair
+        if (ids != null && !ids.isEmpty()) {
+            sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
+        }
+        SearchCriteria<TemplateJoinVO> sc = sb.create();
+
+        // verify templateId parameter and specially handle it
+        if (templateId != null) {
+            template = _templateDao.findByIdIncludingRemoved(templateId); // Done for backward compatibility - Bug-5221
+            if (template == null) {
+                throw new InvalidParameterValueException("Please specify a valid template ID.");
+            }// If ISO requested then it should be ISO.
+            if (isIso && template.getFormat() != ImageFormat.ISO) {
+                s_logger.error("Template Id " + templateId + " is not an ISO");
+                InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO");
+                ex.addProxyObject(template.getUuid(), "templateId");
+                throw ex;
+            }// If ISO not requested then it shouldn't be an ISO.
+            if (!isIso && template.getFormat() == ImageFormat.ISO) {
+                s_logger.error("Incorrect format of the template id " + templateId);
+                InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() + " of the specified template id");
+                ex.addProxyObject(template.getUuid(), "templateId");
+                throw ex;
+            }
+            if (!template.isPublicTemplate() && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+                Account template_acc = _accountMgr.getAccount(template.getAccountId());
+                DomainVO domain = _domainDao.findById(template_acc.getDomainId());
+                _accountMgr.checkAccess(caller, domain);
+            }
+
+            // if template is not public, perform permission check here
+            else if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+                _accountMgr.checkAccess(caller, null, false, template);
+            }
+
+            // if templateId is specified, then we will just use the id to
+            // search and ignore other query parameters
+            sc.addAnd("id", SearchCriteria.Op.EQ, templateId);
+        } else {
+
+            DomainVO domain = null;
+            if (!permittedAccounts.isEmpty()) {
+                domain = _domainDao.findById(permittedAccounts.get(0).getDomainId());
+            } else {
+                domain = _domainDao.findById(Domain.ROOT_DOMAIN);
+            }
+
+            // List<HypervisorType> hypers = null;
+            // if (!isIso) {
+            // hypers = _resourceMgr.listAvailHypervisorInZone(null, null);
+            // }
+
+            setIdsListToSearchCriteria(sc, ids);
+
+            // add criteria for project or not
+            if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
+                sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT);
+            } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) {
+                sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT);
+            }
+
+            // add criteria for domain path in case of domain admin
+            if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable)
+                    && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) {
+                sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%");
+            }
+
+            List<Long> relatedDomainIds = new ArrayList<Long>();
+            List<Long> permittedAccountIds = new ArrayList<Long>();
+            if (!permittedAccounts.isEmpty()) {
+                for (Account account : permittedAccounts) {
+                    permittedAccountIds.add(account.getId());
+                    boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community);
+
+                    // get all parent domain ID's all the way till root domain
+                    DomainVO domainTreeNode = null;
+                    //if template filter is featured, or community, all child domains should be included in search
+                    if (publicTemplates) {
+                        domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN);
+
+                    } else {
+                        domainTreeNode = _domainDao.findById(account.getDomainId());
+                    }
+                    relatedDomainIds.add(domainTreeNode.getId());
+                    while (domainTreeNode.getParent() != null) {
+                        domainTreeNode = _domainDao.findById(domainTreeNode.getParent());
+                        relatedDomainIds.add(domainTreeNode.getId());
+                    }
+
+                    // get all child domain ID's
+                    if (_accountMgr.isAdmin(account.getId()) || publicTemplates) {
+                        List<DomainVO> allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId());
+                        for (DomainVO childDomain : allChildDomains) {
+                            relatedDomainIds.add(childDomain.getId());
+                        }
+                    }
+                }
+            }
+
+            if (!isIso) {
+                // add hypervisor criteria for template case
+                if (hypers != null && !hypers.isEmpty()) {
+                    String[] relatedHypers = new String[hypers.size()];
+                    for (int i = 0; i < hypers.size(); i++) {
+                        relatedHypers[i] = hypers.get(i).toString();
+                    }
+                    sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers);
+                }
+            }
+
+            // control different template filters
+            if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) {
+                sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true);
+                if (templateFilter == TemplateFilter.featured) {
+                    sc.addAnd("featured", SearchCriteria.Op.EQ, true);
+                } else {
+                    sc.addAnd("featured", SearchCriteria.Op.EQ, false);
+                }
+                if (!permittedAccounts.isEmpty()) {
+                    SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
+                    scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray());
+                    scc.addOr("domainId", SearchCriteria.Op.NULL);
+                    sc.addAnd("domainId", SearchCriteria.Op.SC, scc);
+                }
+            } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) {
+                if (!permittedAccounts.isEmpty()) {
+                    sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
+                }
+            } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) {
+                // only show templates shared by others
+                sc.addAnd("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
+            } else if (templateFilter == TemplateFilter.executable) {
+                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
+                scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true);
+                if (!permittedAccounts.isEmpty()) {
+                    scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
+                }
+                sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
+            } else if (templateFilter == TemplateFilter.all && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
+                scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true);
+
+                if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) {
+                    scc.addOr("domainPath", SearchCriteria.Op.LIKE, _domainDao.findById(caller.getDomainId()).getPath() + "%");
+                } else {
+                    if (!permittedAccounts.isEmpty()) {
+                        scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
+                        scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray());
+                    }
+                }
+                sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc);
+            }
+
+            // add tags criteria
+            if (tags != null && !tags.isEmpty()) {
+                SearchCriteria<TemplateJoinVO> scc = _templateJoinDao.createSearchCriteria();
+                for (Map.Entry<String, String> entry : tags.entrySet()) {
+                    SearchCriteria<TemplateJoinVO> scTag = _templateJoinDao.createSearchCriteria();
+                    scTag.addAnd("tagKey", SearchCriteria.Op.EQ, entry.getKey());
+                    scTag.addAnd("tagValue", SearchCriteria.Op.EQ, entry.getValue());
+                    if (isIso) {
+                        scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.ISO);
+                    } else {
+                        scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, ResourceObjectType.Template);
+                    }
+                    scc.addOr("tagKey", SearchCriteria.Op.SC, scTag);
+                }
+                sc.addAnd("tagKey", SearchCriteria.Op.SC, scc);
+            }
+
+            // other criteria
+
+            if (keyword != null) {
+                sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            } else if (name != null) {
+                sc.addAnd("name", SearchCriteria.Op.EQ, name);
+            }
+
+            if (isIso) {
+                sc.addAnd("format", SearchCriteria.Op.EQ, "ISO");
+
+            } else {
+                sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO");
+            }
+
+            if (!hyperType.equals(HypervisorType.None)) {
+                sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType);
+            }
+
+            if (bootable != null) {
+                sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable);
+            }
+
+            if (onlyReady) {
+                SearchCriteria<TemplateJoinVO> readySc = _templateJoinDao.createSearchCriteria();
+                readySc.addOr("state", SearchCriteria.Op.EQ, TemplateState.Ready);
+                readySc.addOr("format", SearchCriteria.Op.EQ, ImageFormat.BAREMETAL);
+                SearchCriteria<TemplateJoinVO> isoPerhostSc = _templateJoinDao.createSearchCriteria();
+                isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO);
+                isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST);
+                readySc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc);
+                sc.addAnd("state", SearchCriteria.Op.SC, readySc);
+            }
+
+            if (!showDomr) {
+                // excluding system template
+                sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM);
+            }
+        }
+
+        if (zoneId != null) {
+            SearchCriteria<TemplateJoinVO> zoneSc = _templateJoinDao.createSearchCriteria();
+            zoneSc.addOr("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+            zoneSc.addOr("dataStoreScope", SearchCriteria.Op.EQ, ScopeType.REGION);
+            // handle the case where xs-tools.iso and vmware-tools.iso do not
+            // have data_center information in template_view
+            SearchCriteria<TemplateJoinVO> isoPerhostSc = _templateJoinDao.createSearchCriteria();
+            isoPerhostSc.addAnd("format", SearchCriteria.Op.EQ, ImageFormat.ISO);
+            isoPerhostSc.addAnd("templateType", SearchCriteria.Op.EQ, TemplateType.PERHOST);
+            zoneSc.addOr("templateType", SearchCriteria.Op.SC, isoPerhostSc);
+            sc.addAnd("dataCenterId", SearchCriteria.Op.SC, zoneSc);
+        }
+
+        if (parentTemplateId != null) {
+            sc.addAnd("parentTemplateId", SearchCriteria.Op.EQ, parentTemplateId);
+        }
+
+        // don't return removed template, this should not be needed since we
+        // changed annotation for removed field in TemplateJoinVO.
+        // sc.addAnd("removed", SearchCriteria.Op.NULL);
+
+        // search unique templates and find details by Ids
+        Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair = null;
+        if (showRemovedTmpl) {
+            uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
+        } else {
+            sc.addAnd("templateState", SearchCriteria.Op.IN, new State[] {State.Active, State.UploadAbandoned, State.UploadError, State.NotUploaded, State.UploadInProgress});
+            final String[] distinctColumns = {"temp_zone_pair"};
+            uniqueTmplPair = _templateJoinDao.searchAndDistinctCount(sc, searchFilter, distinctColumns);
+        }
+
+        Integer count = uniqueTmplPair.second();
+        if (count.intValue() == 0) {
+            // empty result
+            return uniqueTmplPair;
+        }
+        List<TemplateJoinVO> uniqueTmpls = uniqueTmplPair.first();
+        String[] tzIds = new String[uniqueTmpls.size()];
+        int i = 0;
+        for (TemplateJoinVO v : uniqueTmpls) {
+            tzIds[i++] = v.getTempZonePair();
+        }
+        List<TemplateJoinVO> vrs = _templateJoinDao.searchByTemplateZonePair(showRemovedTmpl, tzIds);
+        return new Pair<List<TemplateJoinVO>, Integer>(vrs, count);
+
+        // TODO: revisit the special logic for iso search in
+        // VMTemplateDaoImpl.searchForTemplates and understand why we need to
+        // specially handle ISO. The original logic is very twisted and no idea
+        // about what the code was doing.
+
+    }
+
+    @Override
+    public ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd) {
+        Pair<List<TemplateJoinVO>, Integer> result = searchForIsosInternal(cmd);
+        ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
+
+        ResponseView respView = ResponseView.Restricted;
+        if (cmd instanceof ListIsosCmdByAdmin) {
+            respView = ResponseView.Full;
+        }
+
+        List<TemplateResponse> templateResponses = ViewResponseHelper.createIsoResponse(respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
+        response.setResponses(templateResponses, result.second());
+        return response;
+    }
+
+    private Pair<List<TemplateJoinVO>, Integer> searchForIsosInternal(ListIsosCmd cmd) {
+        TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter());
+        Long id = cmd.getId();
+        Map<String, String> tags = cmd.getTags();
+        boolean showRemovedISO = cmd.getShowRemoved();
+        Account caller = CallContext.current().getCallingAccount();
+
+        boolean listAll = false;
+        if (isoFilter != null && isoFilter == TemplateFilter.all) {
+            if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only");
+            }
+            listAll = true;
+        }
+
+        List<Long> permittedAccountIds = new ArrayList<Long>();
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false);
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        List<Account> permittedAccounts = new ArrayList<Account>();
+        for (Long accountId : permittedAccountIds) {
+            permittedAccounts.add(_accountMgr.getAccount(accountId));
+        }
+
+        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
+
+        return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), cmd.getStartIndex(), cmd.getZoneId(),
+                hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO, null, null);
+    }
+
+    @Override
+    public ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd) {
+        Pair<List<AffinityGroupJoinVO>, Integer> result = searchForAffinityGroupsInternal(cmd);
+        ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();
+        List<AffinityGroupResponse> agResponses = ViewResponseHelper.createAffinityGroupResponses(result.first());
+        response.setResponses(agResponses, result.second());
+        return response;
+    }
+
+    public Pair<List<AffinityGroupJoinVO>, Integer> searchForAffinityGroupsInternal(ListAffinityGroupsCmd cmd) {
+
+        final Long affinityGroupId = cmd.getId();
+        final String affinityGroupName = cmd.getAffinityGroupName();
+        final String affinityGroupType = cmd.getAffinityGroupType();
+        final Long vmId = cmd.getVirtualMachineId();
+        final String accountName = cmd.getAccountName();
+        Long domainId = cmd.getDomainId();
+        final Long projectId = cmd.getProjectId();
+        Boolean isRecursive = cmd.isRecursive();
+        final Boolean listAll = cmd.listAll();
+        final Long startIndex = cmd.getStartIndex();
+        final Long pageSize = cmd.getPageSizeVal();
+        final String keyword = cmd.getKeyword();
+
+        Account caller = CallContext.current().getCallingAccount();
+
+        if (vmId != null) {
+            UserVmVO userVM = _userVmDao.findById(vmId);
+            if (userVM == null) {
+                throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + vmId + "; instance not found.");
+            }
+            _accountMgr.checkAccess(caller, null, true, userVM);
+            return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
+        }
+
+        List<Long> permittedAccounts = new ArrayList<Long>();
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> ternary = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
+
+        _accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, projectId, permittedAccounts, ternary, listAll, false);
+
+        domainId = ternary.first();
+        isRecursive = ternary.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = ternary.third();
+
+        Filter searchFilter = new Filter(AffinityGroupJoinVO.class, ID_FIELD, true, startIndex, pageSize);
+
+        SearchCriteria<AffinityGroupJoinVO> sc = buildAffinityGroupSearchCriteria(domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
+                affinityGroupType, keyword);
+
+        Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
+
+        // search group details by ids
+        List<AffinityGroupJoinVO> affinityGroups = new ArrayList<AffinityGroupJoinVO>();
+
+        Integer count = uniqueGroupsPair.second();
+        if (count.intValue() != 0) {
+            List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
+            Long[] vrIds = new Long[uniqueGroups.size()];
+            int i = 0;
+            for (AffinityGroupJoinVO v : uniqueGroups) {
+                vrIds[i++] = v.getId();
+            }
+            affinityGroups = _affinityGroupJoinDao.searchByIds(vrIds);
+        }
+
+        if (!permittedAccounts.isEmpty()) {
+            // add domain level affinity groups
+            if (domainId != null) {
+                SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
+                        affinityGroupName, affinityGroupType, keyword);
+                affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
+            } else {
+
+                for (Long permAcctId : permittedAccounts) {
+                    Account permittedAcct = _accountDao.findById(permAcctId);
+                    SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
+                            affinityGroupName, affinityGroupType, keyword);
+
+                    affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId()));
+                }
+            }
+        } else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
+            // list all domain level affinity groups for the domain admin case
+            SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
+                    affinityGroupType, keyword);
+            affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
+        }
+
+        return new Pair<List<AffinityGroupJoinVO>, Integer>(affinityGroups, affinityGroups.size());
+
+    }
+
+    private void buildAffinityGroupViewSearchBuilder(SearchBuilder<AffinityGroupJoinVO> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+
+        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+
+        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
+            // if accountId isn't specified, we can do a domain match for the
+            // admin case if isRecursive is true
+            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        if (listProjectResourcesCriteria != null) {
+            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
+            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
+            }
+        }
+
+    }
+
+    private void buildAffinityGroupViewSearchCriteria(SearchCriteria<AffinityGroupJoinVO> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+
+        if (listProjectResourcesCriteria != null) {
+            sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT);
+        }
+
+        if (!permittedAccounts.isEmpty()) {
+            sc.setParameters("accountIdIN", permittedAccounts.toArray());
+        } else if (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            if (isRecursive) {
+                sc.setParameters("domainPath", domain.getPath() + "%");
+            } else {
+                sc.setParameters("domainId", domainId);
+            }
+        }
+    }
+
+    private SearchCriteria<AffinityGroupJoinVO> buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria, Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) {
+
+        SearchBuilder<AffinityGroupJoinVO> groupSearch = _affinityGroupJoinDao.createSearchBuilder();
+        buildAffinityGroupViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        groupSearch.select(null, Func.DISTINCT, groupSearch.entity().getId()); // select
+        // distinct
+
+        SearchCriteria<AffinityGroupJoinVO> sc = groupSearch.create();
+        buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (affinityGroupId != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
+        }
+
+        if (affinityGroupName != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName);
+        }
+
+        if (affinityGroupType != null) {
+            sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<AffinityGroupJoinVO> ssc = _affinityGroupJoinDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        return sc;
+    }
+
+    private Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsByVM(long vmId, long pageInd, long pageSize) {
+        Filter sf = new Filter(SecurityGroupVMMapVO.class, null, true, pageInd, pageSize);
+        Pair<List<AffinityGroupVMMapVO>, Integer> agVmMappingPair = _affinityGroupVMMapDao.listByInstanceId(vmId, sf);
+        Integer count = agVmMappingPair.second();
+        if (count.intValue() == 0) {
+            // handle empty result cases
+            return new Pair<List<AffinityGroupJoinVO>, Integer>(new ArrayList<AffinityGroupJoinVO>(), count);
+        }
+        List<AffinityGroupVMMapVO> agVmMappings = agVmMappingPair.first();
+        Long[] agIds = new Long[agVmMappings.size()];
+        int i = 0;
+        for (AffinityGroupVMMapVO agVm : agVmMappings) {
+            agIds[i++] = agVm.getAffinityGroupId();
+        }
+        List<AffinityGroupJoinVO> ags = _affinityGroupJoinDao.searchByIds(agIds);
+        return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
+    }
+
+    private List<AffinityGroupJoinVO> listDomainLevelAffinityGroups(SearchCriteria<AffinityGroupJoinVO> sc, Filter searchFilter, long domainId) {
+        List<Long> affinityGroupIds = new ArrayList<Long>();
+        Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
+        List<AffinityGroupDomainMapVO> maps = _affinityGroupDomainMapDao.listByDomain(allowedDomains.toArray());
+
+        for (AffinityGroupDomainMapVO map : maps) {
+            boolean subdomainAccess = map.isSubdomainAccess();
+            if (map.getDomainId() == domainId || subdomainAccess) {
+                affinityGroupIds.add(map.getAffinityGroupId());
+            }
+        }
+
+        if (!affinityGroupIds.isEmpty()) {
+            SearchCriteria<AffinityGroupJoinVO> domainSC = _affinityGroupJoinDao.createSearchCriteria();
+            domainSC.addAnd("id", SearchCriteria.Op.IN, affinityGroupIds.toArray());
+            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
+
+            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
+
+            Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
+            // search group by ids
+            Integer count = uniqueGroupsPair.second();
+            if (count.intValue() == 0) {
+                // empty result
+                return new ArrayList<AffinityGroupJoinVO>();
+            }
+            List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
+            Long[] vrIds = new Long[uniqueGroups.size()];
+            int i = 0;
+            for (AffinityGroupJoinVO v : uniqueGroups) {
+                vrIds[i++] = v.getId();
+            }
+            List<AffinityGroupJoinVO> vrs = _affinityGroupJoinDao.searchByIds(vrIds);
+            return vrs;
+        } else {
+            return new ArrayList<AffinityGroupJoinVO>();
+        }
+    }
+
+    @Override
+    public List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd) {
+        String key = cmd.getKey();
+        Boolean forDisplay = cmd.getDisplay();
+        ResourceTag.ResourceObjectType resourceType = cmd.getResourceType();
+        String resourceIdStr = cmd.getResourceId();
+        String value = cmd.getValue();
+        Long resourceId = null;
+
+        //Validation - 1.1 - resourceId and value cant be null.
+        if (resourceIdStr == null && value == null) {
+            throw new InvalidParameterValueException("Insufficient parameters passed for listing by resourceId OR key,value pair. Please check your params and try again.");
+        }
+
+        //Validation - 1.2 - Value has to be passed along with key.
+        if (value != null && key == null) {
+            throw new InvalidParameterValueException("Listing by (key, value) but key is null. Please check the params and try again");
+        }
+
+        //Validation - 1.3
+        if (resourceIdStr != null) {
+            resourceId = _taggedResourceMgr.getResourceId(resourceIdStr, resourceType);
+            if (resourceId == null) {
+                throw new InvalidParameterValueException("Cannot find resource with resourceId " + resourceIdStr + " and of resource type " + resourceType);
+            }
+        }
+
+        List<? extends ResourceDetail> detailList = new ArrayList<ResourceDetail>();
+        ResourceDetail requestedDetail = null;
+
+        if (key == null) {
+            detailList = _resourceMetaDataMgr.getDetailsList(resourceId, resourceType, forDisplay);
+        } else if (value == null) {
+            requestedDetail = _resourceMetaDataMgr.getDetail(resourceId, resourceType, key);
+            if (requestedDetail != null && forDisplay != null && requestedDetail.isDisplay() != forDisplay) {
+                requestedDetail = null;
+            }
+        } else {
+            detailList = _resourceMetaDataMgr.getDetails(resourceType, key, value, forDisplay);
+        }
+
+        List<ResourceDetailResponse> responseList = new ArrayList<ResourceDetailResponse>();
+        if (requestedDetail != null) {
+            ResourceDetailResponse detailResponse = createResourceDetailsResponse(requestedDetail, resourceType);
+            responseList.add(detailResponse);
+        } else {
+            for (ResourceDetail detail : detailList) {
+                ResourceDetailResponse detailResponse = createResourceDetailsResponse(detail, resourceType);
+                responseList.add(detailResponse);
+            }
+        }
+
+        return responseList;
+    }
+
+    protected ResourceDetailResponse createResourceDetailsResponse(ResourceDetail requestedDetail, ResourceTag.ResourceObjectType resourceType) {
+        ResourceDetailResponse resourceDetailResponse = new ResourceDetailResponse();
+        resourceDetailResponse.setResourceId(_taggedResourceMgr.getUuid(String.valueOf(requestedDetail.getResourceId()), resourceType));
+        resourceDetailResponse.setName(requestedDetail.getName());
+        resourceDetailResponse.setValue(requestedDetail.getValue());
+        resourceDetailResponse.setForDisplay(requestedDetail.isDisplay());
+        resourceDetailResponse.setResourceType(resourceType.toString().toString());
+        resourceDetailResponse.setObjectName("resourcedetail");
+        return resourceDetailResponse;
+    }
+
+    @Override
+    public ListResponse<ManagementServerResponse> listManagementServers(ListMgmtsCmd cmd) {
+        ListResponse<ManagementServerResponse> response = new ListResponse<>();
+        List<ManagementServerResponse> result = new ArrayList<>();
+        for (ManagementServerHostVO mgmt : managementServerHostDao.listAll()) {
+            ManagementServerResponse mgmtResponse = new ManagementServerResponse();
+            mgmtResponse.setId(mgmt.getUuid());
+            mgmtResponse.setName(mgmt.getName());
+            mgmtResponse.setState(mgmt.getState());
+            mgmtResponse.setVersion(mgmt.getVersion());
+            mgmtResponse.setObjectName("managementserver");
+            result.add(mgmtResponse);
+        }
+        response.setResponses(result);
+        return response;
+     }
+
+    @Override
+    public String getConfigComponentName() {
+        return QueryService.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {AllowUserViewDestroyedVM};
+    }
+}
diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
similarity index 100%
rename from server/src/com/cloud/api/query/ViewResponseHelper.java
rename to server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
diff --git a/server/src/com/cloud/api/query/dao/AccountJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/AccountJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/AccountJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/AccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/AccountJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/AffinityGroupJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/AffinityGroupJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/AffinityGroupJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/AffinityGroupJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/AsyncJobJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/AsyncJobJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/AsyncJobJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/AsyncJobJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java
new file mode 100644
index 0000000..bd11015
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/AsyncJobJoinDaoImpl.java
@@ -0,0 +1,102 @@
+// 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.api.query.dao;
+
+import java.util.Date;
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+
+import com.cloud.api.ApiSerializerHelper;
+import com.cloud.api.SerializationContext;
+import com.cloud.api.query.vo.AsyncJobJoinVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> implements AsyncJobJoinDao {
+    public static final Logger s_logger = Logger.getLogger(AsyncJobJoinDaoImpl.class);
+
+    private final SearchBuilder<AsyncJobJoinVO> jobIdSearch;
+
+    protected AsyncJobJoinDaoImpl() {
+
+        jobIdSearch = createSearchBuilder();
+        jobIdSearch.and("id", jobIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        jobIdSearch.done();
+
+        _count = "select count(distinct id) from async_job_view WHERE ";
+    }
+
+    @Override
+    public AsyncJobResponse newAsyncJobResponse(final AsyncJobJoinVO job) {
+        final AsyncJobResponse jobResponse = new AsyncJobResponse();
+        jobResponse.setAccountId(job.getAccountUuid());
+        jobResponse.setUserId(job.getUserUuid());
+        jobResponse.setCmd(job.getCmd());
+        jobResponse.setCreated(job.getCreated());
+        jobResponse.setRemoved(job.getRemoved());
+        jobResponse.setJobId(job.getUuid());
+        jobResponse.setJobStatus(job.getStatus());
+        jobResponse.setJobProcStatus(job.getProcessStatus());
+
+        if (job.getInstanceType() != null && job.getInstanceId() != null) {
+            jobResponse.setJobInstanceType(job.getInstanceType().toString());
+
+            jobResponse.setJobInstanceId(job.getInstanceUuid());
+
+        }
+        jobResponse.setJobResultCode(job.getResultCode());
+
+        final boolean savedValue = SerializationContext.current().getUuidTranslation();
+        SerializationContext.current().setUuidTranslation(false);
+
+        final Object resultObject = ApiSerializerHelper.fromSerializedString(job.getResult());
+        jobResponse.setJobResult((ResponseObject)resultObject);
+        SerializationContext.current().setUuidTranslation(savedValue);
+
+        if (resultObject != null) {
+            final Class<?> clz = resultObject.getClass();
+            if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) {
+                jobResponse.setJobResultType("text");
+            } else {
+                jobResponse.setJobResultType("object");
+            }
+        }
+
+        jobResponse.setObjectName("asyncjobs");
+        return jobResponse;
+    }
+
+    @Override
+    public AsyncJobJoinVO newAsyncJobView(AsyncJob job) {
+        SearchCriteria<AsyncJobJoinVO> sc = jobIdSearch.create();
+        sc.setParameters("id", job.getId());
+        List<AsyncJobJoinVO> accounts = searchIncludingRemoved(sc, null, null, false);
+        assert accounts != null && accounts.size() == 1 : "No async job found for job id " + job.getId();
+        return accounts.get(0);
+
+    }
+
+}
diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DataCenterJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DiskOfferingJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
new file mode 100644
index 0000000..b46fbd0
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.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 com.cloud.api.query.dao;
+
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+
+import com.cloud.api.query.vo.DiskOfferingJoinVO;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.utils.db.Attribute;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO, Long> implements DiskOfferingJoinDao {
+    public static final Logger s_logger = Logger.getLogger(DiskOfferingJoinDaoImpl.class);
+
+    private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch;
+    private final Attribute _typeAttr;
+
+    protected DiskOfferingJoinDaoImpl() {
+
+        dofIdSearch = createSearchBuilder();
+        dofIdSearch.and("id", dofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        dofIdSearch.done();
+
+        _typeAttr = _allAttributes.get("type");
+
+        _count = "select count(distinct id) from disk_offering_view WHERE ";
+    }
+
+    @Override
+    public DiskOfferingResponse newDiskOfferingResponse(DiskOfferingJoinVO offering) {
+
+        DiskOfferingResponse diskOfferingResponse = new DiskOfferingResponse();
+        diskOfferingResponse.setId(offering.getUuid());
+        diskOfferingResponse.setName(offering.getName());
+        diskOfferingResponse.setDisplayText(offering.getDisplayText());
+        diskOfferingResponse.setProvisioningType(offering.getProvisioningType().toString());
+        diskOfferingResponse.setCreated(offering.getCreated());
+        diskOfferingResponse.setDiskSize(offering.getDiskSize() / (1024 * 1024 * 1024));
+        diskOfferingResponse.setMinIops(offering.getMinIops());
+        diskOfferingResponse.setMaxIops(offering.getMaxIops());
+
+        diskOfferingResponse.setDomain(offering.getDomainName());
+        diskOfferingResponse.setDomainId(offering.getDomainUuid());
+        diskOfferingResponse.setDisplayOffering(offering.isDisplayOffering());
+
+        diskOfferingResponse.setTags(offering.getTags());
+        diskOfferingResponse.setCustomized(offering.isCustomized());
+        diskOfferingResponse.setCustomizedIops(offering.isCustomizedIops());
+        diskOfferingResponse.setHypervisorSnapshotReserve(offering.getHypervisorSnapshotReserve());
+        diskOfferingResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
+        diskOfferingResponse.setBytesReadRate(offering.getBytesReadRate());
+        diskOfferingResponse.setBytesReadRateMax(offering.getBytesReadRateMax());
+        diskOfferingResponse.setBytesReadRateMaxLength(offering.getBytesReadRateMaxLength());
+        diskOfferingResponse.setBytesWriteRate(offering.getBytesWriteRate());
+        diskOfferingResponse.setBytesWriteRateMax(offering.getBytesWriteRateMax());
+        diskOfferingResponse.setBytesWriteRateMaxLength(offering.getBytesWriteRateMaxLength());
+        diskOfferingResponse.setIopsReadRate(offering.getIopsReadRate());
+        diskOfferingResponse.setIopsReadRateMax(offering.getIopsReadRateMax());
+        diskOfferingResponse.setIopsReadRateMaxLength(offering.getIopsReadRateMaxLength());
+        diskOfferingResponse.setIopsWriteRate(offering.getIopsWriteRate());
+        diskOfferingResponse.setIopsWriteRateMax(offering.getIopsWriteRateMax());
+        diskOfferingResponse.setIopsWriteRateMaxLength(offering.getIopsWriteRateMaxLength());
+        diskOfferingResponse.setCacheMode(offering.getCacheMode());
+        diskOfferingResponse.setObjectName("diskoffering");
+
+        return diskOfferingResponse;
+    }
+
+    @Override
+    public DiskOfferingJoinVO newDiskOfferingView(DiskOffering offering) {
+        SearchCriteria<DiskOfferingJoinVO> sc = dofIdSearch.create();
+        sc.setParameters("id", offering.getId());
+        List<DiskOfferingJoinVO> offerings = searchIncludingRemoved(sc, null, null, false);
+        assert offerings != null && offerings.size() == 1 : "No disk offering found for offering id " + offering.getId();
+        return offerings.get(0);
+    }
+}
diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DomainJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/DomainJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/DomainRouterJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/DomainRouterJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
new file mode 100644
index 0000000..c67611a
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/DomainRouterJoinDaoImpl.java
@@ -0,0 +1,302 @@
+// 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.api.query.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.response.DomainRouterResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.utils.CloudStackVersion;
+
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.vo.DomainRouterJoinVO;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO, Long> implements DomainRouterJoinDao {
+    public static final Logger s_logger = Logger.getLogger(DomainRouterJoinDaoImpl.class);
+
+    @Inject
+    private ConfigurationDao  _configDao;
+    @Inject
+    public AccountManager _accountMgr;
+
+    private final SearchBuilder<DomainRouterJoinVO> vrSearch;
+
+    private final SearchBuilder<DomainRouterJoinVO> vrIdSearch;
+
+    protected DomainRouterJoinDaoImpl() {
+
+        vrSearch = createSearchBuilder();
+        vrSearch.and("idIN", vrSearch.entity().getId(), SearchCriteria.Op.IN);
+        vrSearch.done();
+
+        vrIdSearch = createSearchBuilder();
+        vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        vrIdSearch.done();
+
+        _count = "select count(distinct id) from domain_router_view WHERE ";
+    }
+
+    @Override
+    public DomainRouterResponse newDomainRouterResponse(DomainRouterJoinVO router, Account caller) {
+        DomainRouterResponse routerResponse = new DomainRouterResponse();
+        routerResponse.setId(router.getUuid());
+        routerResponse.setZoneId(router.getDataCenterUuid());
+        routerResponse.setName(router.getName());
+        routerResponse.setTemplateId(router.getTemplateUuid());
+        routerResponse.setCreated(router.getCreated());
+        routerResponse.setState(router.getState());
+        routerResponse.setIsRedundantRouter(router.isRedundantRouter());
+        if (router.getRedundantState() != null) {
+            routerResponse.setRedundantState(router.getRedundantState().toString());
+        }
+        if (router.getTemplateVersion() != null) {
+            String routerVersion = CloudStackVersion.trimRouterVersion(router.getTemplateVersion());
+            routerResponse.setVersion(routerVersion);
+            routerResponse.setRequiresUpgrade((CloudStackVersion.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId())) < 0));
+        } else {
+            routerResponse.setVersion("UNKNOWN");
+            routerResponse.setRequiresUpgrade(true);
+        }
+
+        if (caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN
+                || _accountMgr.isRootAdmin(caller.getId())) {
+            if (router.getHostId() != null) {
+                routerResponse.setHostId(router.getHostUuid());
+                routerResponse.setHostName(router.getHostName());
+                routerResponse.setHypervisor(router.getHypervisorType().toString());
+            }
+            routerResponse.setPodId(router.getPodUuid());
+            long nic_id = router.getNicId();
+            if (nic_id > 0) {
+                TrafficType ty = router.getTrafficType();
+                if (ty != null) {
+                    // legacy code, public/control/guest nic info is kept in
+                    // nics response object
+                    if (ty == TrafficType.Public) {
+                        routerResponse.setPublicIp(router.getIpAddress());
+                        routerResponse.setPublicMacAddress(router.getMacAddress());
+                        routerResponse.setPublicNetmask(router.getNetmask());
+                        routerResponse.setGateway(router.getGateway());
+                        routerResponse.setPublicNetworkId(router.getNetworkUuid());
+                    } else if (ty == TrafficType.Control) {
+                        routerResponse.setLinkLocalIp(router.getIpAddress());
+                        routerResponse.setLinkLocalMacAddress(router.getMacAddress());
+                        routerResponse.setLinkLocalNetmask(router.getNetmask());
+                        routerResponse.setLinkLocalNetworkId(router.getNetworkUuid());
+                    } else if (ty == TrafficType.Guest) {
+                        routerResponse.setGuestIpAddress(router.getIpAddress());
+                        routerResponse.setGuestMacAddress(router.getMacAddress());
+                        routerResponse.setGuestNetmask(router.getNetmask());
+                        routerResponse.setGuestNetworkId(router.getNetworkUuid());
+                        routerResponse.setGuestNetworkName(router.getNetworkName());
+                        routerResponse.setNetworkDomain(router.getNetworkDomain());
+                    }
+                }
+
+                NicResponse nicResponse = new NicResponse();
+                nicResponse.setId(router.getNicUuid());
+                nicResponse.setIpaddress(router.getIpAddress());
+                nicResponse.setGateway(router.getGateway());
+                nicResponse.setNetmask(router.getNetmask());
+                nicResponse.setNetworkid(router.getNetworkUuid());
+                nicResponse.setNetworkName(router.getNetworkName());
+                nicResponse.setMacAddress(router.getMacAddress());
+                nicResponse.setIp6Address(router.getIp6Address());
+                nicResponse.setIp6Gateway(router.getIp6Gateway());
+                nicResponse.setIp6Cidr(router.getIp6Cidr());
+                if (router.getBroadcastUri() != null) {
+                    nicResponse.setBroadcastUri(router.getBroadcastUri().toString());
+                }
+                if (router.getIsolationUri() != null) {
+                    nicResponse.setIsolationUri(router.getIsolationUri().toString());
+                }
+                if (router.getTrafficType() != null) {
+                    nicResponse.setTrafficType(router.getTrafficType().toString());
+                }
+                if (router.getGuestType() != null) {
+                    nicResponse.setType(router.getGuestType().toString());
+                }
+                nicResponse.setIsDefault(router.isDefaultNic());
+                nicResponse.setObjectName("nic");
+                routerResponse.addNic(nicResponse);
+            }
+        }
+
+        routerResponse.setServiceOfferingId(router.getServiceOfferingUuid());
+        routerResponse.setServiceOfferingName(router.getServiceOfferingName());
+
+        // populate owner.
+        ApiResponseHelper.populateOwner(routerResponse, router);
+
+        routerResponse.setDomainId(router.getDomainUuid());
+        routerResponse.setDomainName(router.getDomainName());
+
+        routerResponse.setZoneName(router.getDataCenterName());
+        routerResponse.setDns1(router.getDns1());
+        routerResponse.setDns2(router.getDns2());
+
+        routerResponse.setIp6Dns1(router.getIp6Dns1());
+        routerResponse.setIp6Dns2(router.getIp6Dns2());
+
+        routerResponse.setVpcId(router.getVpcUuid());
+        routerResponse.setVpcName(router.getVpcName());
+
+        routerResponse.setRole(router.getRole().toString());
+
+        // set async job
+        if (router.getJobId() != null) {
+            routerResponse.setJobId(router.getJobUuid());
+            routerResponse.setJobStatus(router.getJobStatus());
+        }
+
+        if (router.getRole() == Role.INTERNAL_LB_VM) {
+            routerResponse.setObjectName("internalloadbalancervm");
+        } else {
+            routerResponse.setObjectName("router");
+        }
+
+        return routerResponse;
+    }
+
+    @Override
+    public DomainRouterResponse setDomainRouterResponse(DomainRouterResponse vrData, DomainRouterJoinVO vr) {
+        long nic_id = vr.getNicId();
+        if (nic_id > 0) {
+            TrafficType ty = vr.getTrafficType();
+            if (ty != null) {
+                // legacy code, public/control/guest nic info is kept in
+                // nics response object
+                if (ty == TrafficType.Public) {
+                    vrData.setPublicIp(vr.getIpAddress());
+                    vrData.setPublicMacAddress(vr.getMacAddress());
+                    vrData.setPublicNetmask(vr.getNetmask());
+                    vrData.setGateway(vr.getGateway());
+                    vrData.setPublicNetworkId(vr.getNetworkUuid());
+                } else if (ty == TrafficType.Control) {
+                    vrData.setLinkLocalIp(vr.getIpAddress());
+                    vrData.setLinkLocalMacAddress(vr.getMacAddress());
+                    vrData.setLinkLocalNetmask(vr.getNetmask());
+                    vrData.setLinkLocalNetworkId(vr.getNetworkUuid());
+                } else if (ty == TrafficType.Guest) {
+                    vrData.setGuestIpAddress(vr.getIpAddress());
+                    vrData.setGuestMacAddress(vr.getMacAddress());
+                    vrData.setGuestNetmask(vr.getNetmask());
+                    vrData.setGuestNetworkId(vr.getNetworkUuid());
+                    vrData.setGuestNetworkName(vr.getNetworkName());
+                    vrData.setNetworkDomain(vr.getNetworkDomain());
+                }
+            }
+            NicResponse nicResponse = new NicResponse();
+            nicResponse.setId(vr.getNicUuid());
+            nicResponse.setIpaddress(vr.getIpAddress());
+            nicResponse.setGateway(vr.getGateway());
+            nicResponse.setNetmask(vr.getNetmask());
+            nicResponse.setNetworkid(vr.getNetworkUuid());
+            nicResponse.setNetworkName(vr.getNetworkName());
+            nicResponse.setMacAddress(vr.getMacAddress());
+            nicResponse.setIp6Address(vr.getIp6Address());
+            nicResponse.setIp6Gateway(vr.getIp6Gateway());
+            nicResponse.setIp6Cidr(vr.getIp6Cidr());
+            if (vr.getBroadcastUri() != null) {
+                nicResponse.setBroadcastUri(vr.getBroadcastUri().toString());
+            }
+            if (vr.getIsolationUri() != null) {
+                nicResponse.setIsolationUri(vr.getIsolationUri().toString());
+            }
+            if (vr.getTrafficType() != null) {
+                nicResponse.setTrafficType(vr.getTrafficType().toString());
+            }
+            if (vr.getGuestType() != null) {
+                nicResponse.setType(vr.getGuestType().toString());
+            }
+            nicResponse.setIsDefault(vr.isDefaultNic());
+            nicResponse.setObjectName("nic");
+            vrData.addNic(nicResponse);
+        }
+        return vrData;
+    }
+
+    @Override
+    public List<DomainRouterJoinVO> searchByIds(Long... vrIds) {
+        // set detail batch query size
+        int DETAILS_BATCH_SIZE = 2000;
+        String batchCfg = _configDao.getValue("detail.batch.query.size");
+        if (batchCfg != null) {
+            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+        }
+        // query details by batches
+        List<DomainRouterJoinVO> uvList = new ArrayList<DomainRouterJoinVO>();
+        // query details by batches
+        int curr_index = 0;
+        if (vrIds.length > DETAILS_BATCH_SIZE) {
+            while ((curr_index + DETAILS_BATCH_SIZE) <= vrIds.length) {
+                Long[] ids = new Long[DETAILS_BATCH_SIZE];
+                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+                    ids[k] = vrIds[j];
+                }
+                SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
+                sc.setParameters("idIN", ids);
+                List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
+                if (vms != null) {
+                    uvList.addAll(vms);
+                }
+                curr_index += DETAILS_BATCH_SIZE;
+            }
+        }
+        if (curr_index < vrIds.length) {
+            int batch_size = (vrIds.length - curr_index);
+            // set the ids value
+            Long[] ids = new Long[batch_size];
+            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+                ids[k] = vrIds[j];
+            }
+            SearchCriteria<DomainRouterJoinVO> sc = vrSearch.create();
+            sc.setParameters("idIN", ids);
+            List<DomainRouterJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
+            if (vms != null) {
+                uvList.addAll(vms);
+            }
+        }
+        return uvList;
+    }
+
+    @Override
+    public List<DomainRouterJoinVO> newDomainRouterView(VirtualRouter vr) {
+
+        SearchCriteria<DomainRouterJoinVO> sc = vrIdSearch.create();
+        sc.setParameters("id", vr.getId());
+        return searchIncludingRemoved(sc, null, null, false);
+    }
+
+}
diff --git a/server/src/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java b/server/src/main/java/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java
rename to server/src/main/java/com/cloud/api/query/dao/GenericDaoBaseWithTagInformation.java
diff --git a/server/src/com/cloud/api/query/dao/HostJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/HostJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/HostJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/HostJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/HostTagDao.java b/server/src/main/java/com/cloud/api/query/dao/HostTagDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/HostTagDao.java
rename to server/src/main/java/com/cloud/api/query/dao/HostTagDao.java
diff --git a/server/src/com/cloud/api/query/dao/HostTagDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/HostTagDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/HostTagDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/HostTagDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ImageStoreJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ImageStoreJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ImageStoreJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ImageStoreJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/InstanceGroupJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/InstanceGroupJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/InstanceGroupJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/InstanceGroupJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/InstanceGroupJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/InstanceGroupJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/InstanceGroupJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/InstanceGroupJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectAccountJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ProjectAccountJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectAccountJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectAccountJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectAccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ProjectAccountJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectAccountJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectAccountJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ProjectInvitationJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectInvitationJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectInvitationJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectInvitationJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ProjectJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/ProjectJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ProjectJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ProjectJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/ProjectJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ResourceTagJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ResourceTagJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ResourceTagJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/ResourceTagJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/SecurityGroupJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/SecurityGroupJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/SecurityGroupJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/SecurityGroupJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/SecurityGroupJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/SecurityGroupJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/SecurityGroupJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/SecurityGroupJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
new file mode 100644
index 0000000..f30bfad
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
@@ -0,0 +1,107 @@
+// 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.api.query.dao;
+
+import java.util.List;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.vo.ServiceOfferingJoinVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJoinVO, Long> implements ServiceOfferingJoinDao {
+    public static final Logger s_logger = Logger.getLogger(ServiceOfferingJoinDaoImpl.class);
+
+    private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
+
+    protected ServiceOfferingJoinDaoImpl() {
+
+        sofIdSearch = createSearchBuilder();
+        sofIdSearch.and("id", sofIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        sofIdSearch.done();
+
+        this._count = "select count(distinct service_offering_view.id) from service_offering_view WHERE ";
+    }
+
+    @Override
+    public ServiceOfferingResponse newServiceOfferingResponse(ServiceOfferingJoinVO offering) {
+
+        ServiceOfferingResponse offeringResponse = new ServiceOfferingResponse();
+        offeringResponse.setId(offering.getUuid());
+        offeringResponse.setName(offering.getName());
+        offeringResponse.setIsSystemOffering(offering.isSystemUse());
+        offeringResponse.setDefaultUse(offering.isDefaultUse());
+        offeringResponse.setSystemVmType(offering.getSystemVmType());
+        offeringResponse.setDisplayText(offering.getDisplayText());
+        offeringResponse.setProvisioningType(offering.getProvisioningType().toString());
+        offeringResponse.setCpuNumber(offering.getCpu());
+        offeringResponse.setCpuSpeed(offering.getSpeed());
+        offeringResponse.setMemory(offering.getRamSize());
+        offeringResponse.setCreated(offering.getCreated());
+        offeringResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
+        offeringResponse.setOfferHa(offering.isOfferHA());
+        offeringResponse.setLimitCpuUse(offering.isLimitCpuUse());
+        offeringResponse.setVolatileVm(offering.getVolatileVm());
+        offeringResponse.setTags(offering.getTags());
+        offeringResponse.setDomain(offering.getDomainName());
+        offeringResponse.setDomainId(offering.getDomainUuid());
+        offeringResponse.setNetworkRate(offering.getRateMbps());
+        offeringResponse.setHostTag(offering.getHostTag());
+        offeringResponse.setDeploymentPlanner(offering.getDeploymentPlanner());
+        offeringResponse.setCustomizedIops(offering.isCustomizedIops());
+        offeringResponse.setMinIops(offering.getMinIops());
+        offeringResponse.setMaxIops(offering.getMaxIops());
+        offeringResponse.setHypervisorSnapshotReserve(offering.getHypervisorSnapshotReserve());
+        offeringResponse.setBytesReadRate(offering.getBytesReadRate());
+        offeringResponse.setBytesReadRateMax(offering.getBytesReadRateMax());
+        offeringResponse.setBytesReadRateMaxLength(offering.getBytesReadRateMaxLength());
+        offeringResponse.setBytesWriteRate(offering.getBytesWriteRate());
+        offeringResponse.setBytesWriteRateMax(offering.getBytesWriteRateMax());
+        offeringResponse.setBytesWriteRateMaxLength(offering.getBytesWriteRateMaxLength());
+        offeringResponse.setIopsReadRate(offering.getIopsReadRate());
+        offeringResponse.setIopsReadRateMax(offering.getIopsReadRateMax());
+        offeringResponse.setIopsReadRateMaxLength(offering.getIopsReadRateMaxLength());
+        offeringResponse.setIopsWriteRate(offering.getIopsWriteRate());
+        offeringResponse.setIopsWriteRateMax(offering.getIopsWriteRateMax());
+        offeringResponse.setIopsWriteRateMaxLength(offering.getIopsWriteRateMaxLength());
+        offeringResponse.setDetails(ApiDBUtils.getResourceDetails(offering.getId(), ResourceObjectType.ServiceOffering));
+        offeringResponse.setObjectName("serviceoffering");
+        offeringResponse.setIscutomized(offering.isDynamic());
+
+        return offeringResponse;
+    }
+
+    @Override
+    public ServiceOfferingJoinVO newServiceOfferingView(ServiceOffering offering) {
+        SearchCriteria<ServiceOfferingJoinVO> sc = sofIdSearch.create();
+        sc.setParameters("id", offering.getId());
+        List<ServiceOfferingJoinVO> offerings = searchIncludingRemoved(sc, null, null, false);
+        assert offerings != null && offerings.size() == 1 : "No service offering found for offering id " + offering.getId();
+        return offerings.get(0);
+    }
+
+}
diff --git a/server/src/com/cloud/api/query/dao/StoragePoolJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/StoragePoolJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/TemplateJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
new file mode 100644
index 0000000..155fd14
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -0,0 +1,482 @@
+// 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.api.query.dao;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.utils.security.DigestHelper;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.response.ChildTemplateResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.vo.ResourceTagJoinVO;
+import com.cloud.api.query.vo.TemplateJoinVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+
+@Component
+public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<TemplateJoinVO, TemplateResponse> implements TemplateJoinDao {
+
+    public static final Logger s_logger = Logger.getLogger(TemplateJoinDaoImpl.class);
+
+    @Inject
+    private ConfigurationDao  _configDao;
+    @Inject
+    private AccountService _accountService;
+    @Inject
+    private VMTemplateDao _vmTemplateDao;
+
+    private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
+
+    private final SearchBuilder<TemplateJoinVO> tmpltIdSearch;
+
+    private final SearchBuilder<TemplateJoinVO> tmpltZoneSearch;
+
+    private final SearchBuilder<TemplateJoinVO> activeTmpltSearch;
+
+    protected TemplateJoinDaoImpl() {
+
+        tmpltIdPairSearch = createSearchBuilder();
+        tmpltIdPairSearch.and("templateState", tmpltIdPairSearch.entity().getTemplateState(), SearchCriteria.Op.IN);
+        tmpltIdPairSearch.and("tempZonePairIN", tmpltIdPairSearch.entity().getTempZonePair(), SearchCriteria.Op.IN);
+        tmpltIdPairSearch.done();
+
+        tmpltIdSearch = createSearchBuilder();
+        tmpltIdSearch.and("id", tmpltIdSearch.entity().getId(), SearchCriteria.Op.EQ);
+        tmpltIdSearch.done();
+
+        tmpltZoneSearch = createSearchBuilder();
+        tmpltZoneSearch.and("id", tmpltZoneSearch.entity().getId(), SearchCriteria.Op.EQ);
+        tmpltZoneSearch.and("dataCenterId", tmpltZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        tmpltZoneSearch.and("state", tmpltZoneSearch.entity().getState(), SearchCriteria.Op.EQ);
+        tmpltZoneSearch.done();
+
+        activeTmpltSearch = createSearchBuilder();
+        activeTmpltSearch.and("store_id", activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
+        activeTmpltSearch.and("type", activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
+        activeTmpltSearch.and("templateState", activeTmpltSearch.entity().getTemplateState(), SearchCriteria.Op.EQ);
+        activeTmpltSearch.done();
+
+        // select distinct pair (template_id, zone_id)
+        _count = "select count(distinct temp_zone_pair) from template_view WHERE ";
+    }
+
+    private String getTemplateStatus(TemplateJoinVO template) {
+        String templateStatus = null;
+        if (template.getDownloadState() != Status.DOWNLOADED) {
+            templateStatus = "Processing";
+            if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
+                if (template.getDownloadPercent() == 100) {
+                    templateStatus = "Installing Template";
+                } else {
+                    templateStatus = template.getDownloadPercent() + "% Downloaded";
+                }
+            } else if (template.getDownloadState() == Status.BYPASSED) {
+                templateStatus = "Bypassed Secondary Storage";
+            }else if (template.getErrorString()==null){
+                templateStatus = template.getTemplateState().toString();
+            }else {
+                templateStatus = template.getErrorString();
+            }
+        } else if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
+            templateStatus = "Download Complete";
+        } else {
+            templateStatus = "Successfully Installed";
+        }
+        return templateStatus;
+    }
+
+    @Override
+    public TemplateResponse newTemplateResponse(ResponseView view, TemplateJoinVO template) {
+        TemplateResponse templateResponse = new TemplateResponse();
+        templateResponse.setId(template.getUuid());
+        templateResponse.setName(template.getName());
+        templateResponse.setDisplayText(template.getDisplayText());
+        templateResponse.setPublic(template.isPublicTemplate());
+        templateResponse.setCreated(template.getCreatedOnStore());
+        if (template.getFormat() == Storage.ImageFormat.BAREMETAL) {
+            // for baremetal template, we didn't download, but is ready to use.
+            templateResponse.setReady(true);
+        } else {
+            templateResponse.setReady(template.getState() == ObjectInDataStoreStateMachine.State.Ready);
+        }
+        templateResponse.setFeatured(template.isFeatured());
+        templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM));
+        templateResponse.setPasswordEnabled(template.isEnablePassword());
+        templateResponse.setDynamicallyScalable(template.isDynamicallyScalable());
+        templateResponse.setSshKeyEnabled(template.isEnableSshKey());
+        templateResponse.setCrossZones(template.isCrossZones());
+        templateResponse.setFormat(template.getFormat());
+        if (template.getTemplateType() != null) {
+            templateResponse.setTemplateType(template.getTemplateType().toString());
+        }
+
+        templateResponse.setHypervisor(template.getHypervisorType().toString());
+
+        templateResponse.setOsTypeId(template.getGuestOSUuid());
+        templateResponse.setOsTypeName(template.getGuestOSName());
+
+        // populate owner.
+        ApiResponseHelper.populateOwner(templateResponse, template);
+
+        // populate domain
+        templateResponse.setDomainId(template.getDomainUuid());
+        templateResponse.setDomainName(template.getDomainName());
+
+        // If the user is an 'Admin' or 'the owner of template', add the template download status
+        if (view == ResponseView.Full ||  template.getAccountId() == CallContext.current().getCallingAccount().getId() ) {
+            String templateStatus = getTemplateStatus(template);
+            if (templateStatus != null) {
+                templateResponse.setStatus(templateStatus);
+            }
+        }
+
+        if (template.getDataCenterId() > 0) {
+            templateResponse.setZoneId(template.getDataCenterUuid());
+            templateResponse.setZoneName(template.getDataCenterName());
+        }
+
+        Long templateSize = template.getSize();
+        if (templateSize > 0) {
+            templateResponse.setSize(templateSize);
+        }
+
+        Long templatePhysicalSize = template.getPhysicalSize();
+        if (templatePhysicalSize > 0) {
+            templateResponse.setPhysicalSize(templatePhysicalSize);
+        }
+
+        templateResponse.setChecksum(DigestHelper.getHashValueFromChecksumValue(template.getChecksum()));
+        if (template.getSourceTemplateId() != null) {
+            templateResponse.setSourceTemplateId(template.getSourceTemplateUuid());
+        }
+        templateResponse.setTemplateTag(template.getTemplateTag());
+
+        if (template.getParentTemplateId() != null) {
+            templateResponse.setParentTemplateId(template.getParentTemplateUuid());
+        }
+
+        // set details map
+        if (template.getDetailName() != null) {
+            Map<String, String> details = new HashMap<>();
+            details.put(template.getDetailName(), template.getDetailValue());
+            templateResponse.setDetails(details);
+        }
+
+        // update tag information
+        long tag_id = template.getTagId();
+        if (tag_id > 0) {
+            addTagInformation(template, templateResponse);
+        }
+
+        templateResponse.setDirectDownload(template.isDirectDownload());
+        templateResponse.setRequiresHvm(template.isRequiresHvm());
+
+        //set template children disks
+        Set<ChildTemplateResponse> childTemplatesSet = new HashSet<ChildTemplateResponse>();
+        if (template.getHypervisorType() == HypervisorType.VMware) {
+            List<VMTemplateVO> childTemplates = _vmTemplateDao.listByParentTemplatetId(template.getId());
+            for (VMTemplateVO tmpl : childTemplates) {
+                if (tmpl.getTemplateType() != TemplateType.ISODISK) {
+                    ChildTemplateResponse childTempl = new ChildTemplateResponse();
+                    childTempl.setId(tmpl.getUuid());
+                    childTempl.setName(tmpl.getName());
+                    childTempl.setSize(Math.round(tmpl.getSize() / (1024 * 1024 * 1024)));
+                    childTemplatesSet.add(childTempl);
+                }
+            }
+            templateResponse.setChildTemplates(childTemplatesSet);
+        }
+
+        templateResponse.setObjectName("template");
+        return templateResponse;
+    }
+
+    //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse
+    // compared to listTemplates and listIsos.
+    @Override
+    public TemplateResponse newUpdateResponse(TemplateJoinVO result) {
+        TemplateResponse response = new TemplateResponse();
+        response.setId(result.getUuid());
+        response.setName(result.getName());
+        response.setDisplayText(result.getDisplayText());
+        response.setPublic(result.isPublicTemplate());
+        response.setCreated(result.getCreated());
+        response.setFormat(result.getFormat());
+        response.setOsTypeId(result.getGuestOSUuid());
+        response.setOsTypeName(result.getGuestOSName());
+        response.setBootable(result.isBootable());
+        response.setHypervisor(result.getHypervisorType().toString());
+        response.setDynamicallyScalable(result.isDynamicallyScalable());
+
+        // populate owner.
+        ApiResponseHelper.populateOwner(response, result);
+
+        // populate domain
+        response.setDomainId(result.getDomainUuid());
+        response.setDomainName(result.getDomainName());
+
+        // set details map
+        if (result.getDetailName() != null) {
+            Map<String, String> details = new HashMap<>();
+            details.put(result.getDetailName(), result.getDetailValue());
+            response.setDetails(details);
+        }
+
+        // update tag information
+        long tag_id = result.getTagId();
+        if (tag_id > 0) {
+            ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
+            if (vtag != null) {
+                response.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
+            }
+        }
+
+        response.setObjectName("iso");
+        return response;
+    }
+
+    @Override
+    public TemplateResponse setTemplateResponse(ResponseView view, TemplateResponse templateResponse, TemplateJoinVO template) {
+
+        // update details map
+        if (template.getDetailName() != null) {
+            Map<String, String> details = templateResponse.getDetails();
+            if (details == null) {
+                details = new HashMap<>();
+            }
+            details.put(template.getDetailName(), template.getDetailValue());
+            templateResponse.setDetails(details);
+        }
+
+        // update tag information
+        long tag_id = template.getTagId();
+        if (tag_id > 0) {
+            addTagInformation(template, templateResponse);
+        }
+
+        return templateResponse;
+    }
+
+    @Override
+    public TemplateResponse newIsoResponse(TemplateJoinVO iso) {
+
+        TemplateResponse isoResponse = new TemplateResponse();
+        isoResponse.setId(iso.getUuid());
+        isoResponse.setName(iso.getName());
+        isoResponse.setDisplayText(iso.getDisplayText());
+        isoResponse.setPublic(iso.isPublicTemplate());
+        isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST));
+        isoResponse.setCreated(iso.getCreatedOnStore());
+        isoResponse.setDynamicallyScalable(iso.isDynamicallyScalable());
+        if (iso.getTemplateType() == TemplateType.PERHOST) {
+            // for xs-tools.iso and vmware-tools.iso, we didn't download, but is ready to use.
+            isoResponse.setReady(true);
+        } else {
+            isoResponse.setReady(iso.getState() == ObjectInDataStoreStateMachine.State.Ready);
+        }
+        isoResponse.setBootable(iso.isBootable());
+        isoResponse.setFeatured(iso.isFeatured());
+        isoResponse.setCrossZones(iso.isCrossZones());
+        isoResponse.setPublic(iso.isPublicTemplate());
+        isoResponse.setChecksum(DigestHelper.getHashValueFromChecksumValue(iso.getChecksum()));
+
+        isoResponse.setOsTypeId(iso.getGuestOSUuid());
+        isoResponse.setOsTypeName(iso.getGuestOSName());
+        isoResponse.setBits(iso.getBits());
+        isoResponse.setPasswordEnabled(iso.isEnablePassword());
+
+        // populate owner.
+        ApiResponseHelper.populateOwner(isoResponse, iso);
+
+        // populate domain
+        isoResponse.setDomainId(iso.getDomainUuid());
+        isoResponse.setDomainName(iso.getDomainName());
+
+        Account caller = CallContext.current().getCallingAccount();
+        boolean isAdmin = false;
+        if ((caller == null) || _accountService.isAdmin(caller.getId())) {
+            isAdmin = true;
+        }
+
+        // If the user is an admin, add the template download status
+        if (isAdmin || caller.getId() == iso.getAccountId()) {
+            // add download status
+            if (iso.getDownloadState() != Status.DOWNLOADED) {
+                String isoStatus = "Processing";
+                if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) {
+                    isoStatus = "Download Complete";
+                } else if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) {
+                    if (iso.getDownloadPercent() == 100) {
+                        isoStatus = "Installing ISO";
+                    } else {
+                        isoStatus = iso.getDownloadPercent() + "% Downloaded";
+                    }
+                } else if (iso.getDownloadState() == Status.BYPASSED) {
+                    isoStatus = "Bypassed Secondary Storage";
+                } else {
+                    isoStatus = iso.getErrorString();
+                }
+                isoResponse.setStatus(isoStatus);
+            } else {
+                isoResponse.setStatus("Successfully Installed");
+            }
+        }
+
+        if (iso.getDataCenterId() > 0) {
+            isoResponse.setZoneId(iso.getDataCenterUuid());
+            isoResponse.setZoneName(iso.getDataCenterName());
+        }
+
+        Long isoSize = iso.getSize();
+        if (isoSize > 0) {
+            isoResponse.setSize(isoSize);
+        }
+
+        // update tag information
+        long tag_id = iso.getTagId();
+        if (tag_id > 0) {
+            ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id);
+            if (vtag != null) {
+                isoResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false));
+            }
+        }
+
+        isoResponse.setDirectDownload(iso.isDirectDownload());
+
+        isoResponse.setObjectName("iso");
+        return isoResponse;
+
+    }
+
+    @Override
+    public List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate template) {
+        SearchCriteria<TemplateJoinVO> sc = tmpltIdSearch.create();
+        sc.setParameters("id", template.getId());
+        return searchIncludingRemoved(sc, null, null, false);
+    }
+
+    @Override
+    public List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate template, long zoneId, boolean readyOnly) {
+        SearchCriteria<TemplateJoinVO> sc = tmpltZoneSearch.create();
+        sc.setParameters("id", template.getId());
+        sc.setParameters("dataCenterId", zoneId);
+        if (readyOnly) {
+            sc.setParameters("state", TemplateState.Ready);
+        }
+        return searchIncludingRemoved(sc, null, null, false);
+    }
+
+    @Override
+    public List<TemplateJoinVO> searchByTemplateZonePair(Boolean showRemoved, String... idPairs) {
+        // set detail batch query size
+        int DETAILS_BATCH_SIZE = 2000;
+        String batchCfg = _configDao.getValue("detail.batch.query.size");
+        if (batchCfg != null) {
+            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+        }
+        // query details by batches
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = (isAscending == null ? Boolean.TRUE : isAscending);
+        Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, null, null);
+        searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", isAscending);
+        List<TemplateJoinVO> uvList = new ArrayList<TemplateJoinVO>();
+        // query details by batches
+        int curr_index = 0;
+        if (idPairs.length > DETAILS_BATCH_SIZE) {
+            while ((curr_index + DETAILS_BATCH_SIZE) <= idPairs.length) {
+                String[] labels = new String[DETAILS_BATCH_SIZE];
+                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+                    labels[k] = idPairs[j];
+                }
+                SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
+                if (!showRemoved) {
+                    sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
+                }
+                sc.setParameters("tempZonePairIN", labels);
+                List<TemplateJoinVO> vms = searchIncludingRemoved(sc, searchFilter, null, false);
+                if (vms != null) {
+                    uvList.addAll(vms);
+                }
+                curr_index += DETAILS_BATCH_SIZE;
+            }
+        }
+        if (curr_index < idPairs.length) {
+            int batch_size = (idPairs.length - curr_index);
+            String[] labels = new String[batch_size];
+            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+                labels[k] = idPairs[j];
+            }
+            SearchCriteria<TemplateJoinVO> sc = tmpltIdPairSearch.create();
+            if (!showRemoved) {
+                sc.setParameters("templateState", VirtualMachineTemplate.State.Active, VirtualMachineTemplate.State.UploadAbandoned, VirtualMachineTemplate.State.UploadError ,VirtualMachineTemplate.State.NotUploaded, VirtualMachineTemplate.State.UploadInProgress);
+            }
+            sc.setParameters("tempZonePairIN", labels);
+            List<TemplateJoinVO> vms = searchIncludingRemoved(sc, searchFilter, null, false);
+            if (vms != null) {
+                uvList.addAll(vms);
+            }
+        }
+        return uvList;
+    }
+
+    @Override
+    public List<TemplateJoinVO> listActiveTemplates(long storeId) {
+        SearchCriteria<TemplateJoinVO> sc = activeTmpltSearch.create();
+        sc.setParameters("store_id", storeId);
+        sc.setParameters("type", TemplateType.USER);
+        sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
+        return searchIncludingRemoved(sc, null, null, false);
+    }
+
+    @Override
+    public Pair<List<TemplateJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<TemplateJoinVO> sc, final Filter filter) {
+        List<TemplateJoinVO> objects = searchIncludingRemoved(sc, filter, null, false);
+        Integer count = getCount(sc);
+        return new Pair<List<TemplateJoinVO>, Integer>(objects, count);
+    }
+
+}
diff --git a/server/src/com/cloud/api/query/dao/UserAccountJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/UserAccountJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/UserAccountJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/UserAccountJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/UserVmJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/UserVmJoinDao.java
diff --git a/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
new file mode 100644
index 0000000..58d5e49
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
@@ -0,0 +1,504 @@
+// 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.api.query.dao;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.affinity.AffinityGroupResponse;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.ResponseObject.ResponseView;
+import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.gpu.GPU;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.user.dao.UserDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.net.Dhcp;
+import com.cloud.vm.UserVmDetailVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VmStats;
+import com.cloud.vm.dao.NicExtraDhcpOptionDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.UserVmDetailsDao;
+
+@Component
+public class UserVmJoinDaoImpl extends GenericDaoBaseWithTagInformation<UserVmJoinVO, UserVmResponse> implements UserVmJoinDao {
+    public static final Logger s_logger = Logger.getLogger(UserVmJoinDaoImpl.class);
+
+    @Inject
+    private ConfigurationDao  _configDao;
+    @Inject
+    public AccountManager _accountMgr;
+    @Inject
+    private UserVmDetailsDao _userVmDetailsDao;
+    @Inject
+    private UserDao _userDao;
+    @Inject
+    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
+
+    private final SearchBuilder<UserVmJoinVO> VmDetailSearch;
+    private final SearchBuilder<UserVmJoinVO> activeVmByIsoSearch;
+
+    protected UserVmJoinDaoImpl() {
+
+        VmDetailSearch = createSearchBuilder();
+        VmDetailSearch.and("idIN", VmDetailSearch.entity().getId(), SearchCriteria.Op.IN);
+        VmDetailSearch.done();
+
+        _count = "select count(distinct id) from user_vm_view WHERE ";
+
+        activeVmByIsoSearch = createSearchBuilder();
+        activeVmByIsoSearch.and("isoId", activeVmByIsoSearch.entity().getIsoId(), SearchCriteria.Op.EQ);
+        activeVmByIsoSearch.and("stateNotIn", activeVmByIsoSearch.entity().getState(), SearchCriteria.Op.NIN);
+        activeVmByIsoSearch.done();
+    }
+
+    @Override
+    public List<UserVmJoinVO> listActiveByIsoId(Long isoId) {
+        SearchCriteria<UserVmJoinVO> sc = activeVmByIsoSearch.create();
+        sc.setParameters("isoId", isoId);
+        State[] states = new State[2];
+        states[0] = State.Error;
+        states[1] = State.Expunging;
+        return listBy(sc);
+    }
+
+    @Override
+    public UserVmResponse newUserVmResponse(ResponseView view, String objectName, UserVmJoinVO userVm, EnumSet<VMDetails> details, Account caller) {
+        UserVmResponse userVmResponse = new UserVmResponse();
+
+        if (userVm.getHypervisorType() != null) {
+            userVmResponse.setHypervisor(userVm.getHypervisorType().toString());
+        }
+        userVmResponse.setId(userVm.getUuid());
+        userVmResponse.setName(userVm.getName());
+
+        if (userVm.getDisplayName() != null) {
+        userVmResponse.setDisplayName(userVm.getDisplayName());
+        } else {
+            userVmResponse.setDisplayName(userVm.getName());
+        }
+
+        if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
+            userVmResponse.setProjectId(userVm.getProjectUuid());
+            userVmResponse.setProjectName(userVm.getProjectName());
+        } else {
+            userVmResponse.setAccountName(userVm.getAccountName());
+        }
+
+        User user = _userDao.getUser(userVm.getUserId());
+        if (user != null) {
+            userVmResponse.setUserId(user.getUuid());
+            userVmResponse.setUserName(user.getUsername());
+        }
+        userVmResponse.setDomainId(userVm.getDomainUuid());
+        userVmResponse.setDomainName(userVm.getDomainName());
+
+        userVmResponse.setCreated(userVm.getCreated());
+        userVmResponse.setDisplayVm(userVm.isDisplayVm());
+
+        if (userVm.getState() != null) {
+            userVmResponse.setState(userVm.getState().toString());
+        }
+        userVmResponse.setHaEnable(userVm.isHaEnabled());
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.group)) {
+            userVmResponse.setGroupId(userVm.getInstanceGroupUuid());
+            userVmResponse.setGroup(userVm.getInstanceGroupName());
+        }
+        userVmResponse.setZoneId(userVm.getDataCenterUuid());
+        userVmResponse.setZoneName(userVm.getDataCenterName());
+        if (view == ResponseView.Full) {
+            userVmResponse.setInstanceName(userVm.getInstanceName());
+            userVmResponse.setHostId(userVm.getHostUuid());
+            userVmResponse.setHostName(userVm.getHostName());
+        }
+
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.tmpl)) {
+            userVmResponse.setTemplateId(userVm.getTemplateUuid());
+            userVmResponse.setTemplateName(userVm.getTemplateName());
+            userVmResponse.setTemplateDisplayText(userVm.getTemplateDisplayText());
+            userVmResponse.setPasswordEnabled(userVm.isPasswordEnabled());
+        }
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.iso)) {
+            userVmResponse.setIsoId(userVm.getIsoUuid());
+            userVmResponse.setIsoName(userVm.getIsoName());
+            userVmResponse.setIsoDisplayText(userVm.getIsoDisplayText());
+        }
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) {
+            userVmResponse.setServiceOfferingId(userVm.getServiceOfferingUuid());
+            userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName());
+        }
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.diskoff)) {
+            userVmResponse.setDiskOfferingId(userVm.getDiskOfferingUuid());
+            userVmResponse.setDiskOfferingName(userVm.getDiskOfferingName());
+        }
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff) || details.contains(VMDetails.stats)) {
+            userVmResponse.setCpuNumber(userVm.getCpu());
+            userVmResponse.setCpuSpeed(userVm.getSpeed());
+            userVmResponse.setMemory(userVm.getRamSize());
+            ServiceOfferingDetailsVO serviceOfferingDetail = ApiDBUtils.findServiceOfferingDetail(userVm.getServiceOfferingId(), GPU.Keys.vgpuType.toString());
+            if (serviceOfferingDetail != null) {
+                userVmResponse.setVgpu(serviceOfferingDetail.getValue());
+            }
+        }
+        userVmResponse.setGuestOsId(userVm.getGuestOsUuid());
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.volume)) {
+            userVmResponse.setRootDeviceId(userVm.getVolumeDeviceId());
+            if (userVm.getVolumeType() != null) {
+                userVmResponse.setRootDeviceType(userVm.getVolumeType().toString());
+            }
+        }
+        userVmResponse.setPassword(userVm.getPassword());
+        if (userVm.getJobId() != null) {
+            userVmResponse.setJobId(userVm.getJobUuid());
+            userVmResponse.setJobStatus(userVm.getJobStatus());
+        }
+        //userVmResponse.setForVirtualNetwork(userVm.getForVirtualNetwork());
+
+        userVmResponse.setPublicIpId(userVm.getPublicIpUuid());
+        userVmResponse.setPublicIp(userVm.getPublicIpAddress());
+        userVmResponse.setKeyPairName(userVm.getKeypairName());
+        userVmResponse.setOsTypeId(userVm.getGuestOsUuid());
+
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.stats)) {
+            // stats calculation
+            VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId());
+            if (vmStats != null) {
+                userVmResponse.setCpuUsed(new DecimalFormat("#.##").format(vmStats.getCPUUtilization()) + "%");
+                userVmResponse.setNetworkKbsRead((long)vmStats.getNetworkReadKBs());
+                userVmResponse.setNetworkKbsWrite((long)vmStats.getNetworkWriteKBs());
+                userVmResponse.setDiskKbsRead((long)vmStats.getDiskReadKBs());
+                userVmResponse.setDiskKbsWrite((long)vmStats.getDiskWriteKBs());
+                userVmResponse.setDiskIORead((long)vmStats.getDiskReadIOs());
+                userVmResponse.setDiskIOWrite((long)vmStats.getDiskWriteIOs());
+                userVmResponse.setMemoryKBs((long)vmStats.getMemoryKBs());
+                userVmResponse.setMemoryIntFreeKBs((long)vmStats.getIntFreeMemoryKBs());
+                userVmResponse.setMemoryTargetKBs((long)vmStats.getTargetMemoryKBs());
+
+            }
+        }
+
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.secgrp)) {
+            Long securityGroupId = userVm.getSecurityGroupId();
+            if (securityGroupId != null && securityGroupId.longValue() != 0) {
+                SecurityGroupResponse resp = new SecurityGroupResponse();
+                resp.setId(userVm.getSecurityGroupUuid());
+                resp.setName(userVm.getSecurityGroupName());
+                resp.setDescription(userVm.getSecurityGroupDescription());
+                resp.setObjectName("securitygroup");
+                if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
+                    resp.setProjectId(userVm.getProjectUuid());
+                    resp.setProjectName(userVm.getProjectName());
+                } else {
+                    resp.setAccountName(userVm.getAccountName());
+                }
+                userVmResponse.addSecurityGroup(resp);
+            }
+        }
+
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.nics)) {
+            long nic_id = userVm.getNicId();
+            if (nic_id > 0) {
+                NicResponse nicResponse = new NicResponse();
+                nicResponse.setId(userVm.getNicUuid());
+                nicResponse.setIpaddress(userVm.getIpAddress());
+                nicResponse.setGateway(userVm.getGateway());
+                nicResponse.setNetmask(userVm.getNetmask());
+                nicResponse.setNetworkid(userVm.getNetworkUuid());
+                nicResponse.setNetworkName(userVm.getNetworkName());
+                nicResponse.setMacAddress(userVm.getMacAddress());
+                nicResponse.setIp6Address(userVm.getIp6Address());
+                nicResponse.setIp6Gateway(userVm.getIp6Gateway());
+                nicResponse.setIp6Cidr(userVm.getIp6Cidr());
+                if (userVm.getBroadcastUri() != null) {
+                    nicResponse.setBroadcastUri(userVm.getBroadcastUri().toString());
+                }
+                if (userVm.getIsolationUri() != null) {
+                    nicResponse.setIsolationUri(userVm.getIsolationUri().toString());
+                }
+                if (userVm.getTrafficType() != null) {
+                    nicResponse.setTrafficType(userVm.getTrafficType().toString());
+                }
+                if (userVm.getGuestType() != null) {
+                    nicResponse.setType(userVm.getGuestType().toString());
+                }
+                nicResponse.setIsDefault(userVm.isDefaultNic());
+                List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(userVm.getNicId());
+                if (secondaryIps != null) {
+                    List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
+                    for (NicSecondaryIpVO ip : secondaryIps) {
+                        NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
+                        ipRes.setId(ip.getUuid());
+                        ApiResponseHelper.setResponseIpAddress(ip, ipRes);
+                        ipList.add(ipRes);
+                    }
+                    nicResponse.setSecondaryIps(ipList);
+                }
+                nicResponse.setObjectName("nic");
+
+                List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id).stream()
+                        .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
+                        .collect(Collectors.toList());
+                nicResponse.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
+
+                userVmResponse.addNic(nicResponse);
+            }
+        }
+
+        // update tag information
+        long tag_id = userVm.getTagId();
+        if (tag_id > 0 && !userVmResponse.containTag(tag_id)) {
+            addTagInformation(userVm, userVmResponse);
+        }
+
+        if (details.contains(VMDetails.all) || details.contains(VMDetails.affgrp)) {
+            Long affinityGroupId = userVm.getAffinityGroupId();
+            if (affinityGroupId != null && affinityGroupId.longValue() != 0) {
+                AffinityGroupResponse resp = new AffinityGroupResponse();
+                resp.setId(userVm.getAffinityGroupUuid());
+                resp.setName(userVm.getAffinityGroupName());
+                resp.setDescription(userVm.getAffinityGroupDescription());
+                resp.setObjectName("affinitygroup");
+                resp.setAccountName(userVm.getAccountName());
+                userVmResponse.addAffinityGroup(resp);
+            }
+        }
+
+        // set resource details map
+        // Allow passing details to end user
+        List<UserVmDetailVO> vmDetails = _userVmDetailsDao.listDetails(userVm.getId());
+        if (vmDetails != null) {
+            Map<String, String> resourceDetails = new HashMap<String, String>();
+            for (UserVmDetailVO userVmDetailVO : vmDetails) {
+                resourceDetails.put(userVmDetailVO.getName(), userVmDetailVO.getValue());
+            }
+            userVmResponse.setDetails(resourceDetails);
+        }
+
+        userVmResponse.setObjectName(objectName);
+        if (userVm.isDynamicallyScalable() == null) {
+            userVmResponse.setDynamicallyScalable(false);
+        } else {
+            userVmResponse.setDynamicallyScalable(userVm.isDynamicallyScalable());
+        }
+
+        return userVmResponse;
+    }
+
+    /**
+     * The resulting Response attempts to be in line with what is returned from
+     * @see com.cloud.api.ApiResponseHelper#createNicResponse(Nic)
+     */
+    @Override
+    public UserVmResponse setUserVmResponse(ResponseView view, UserVmResponse userVmData, UserVmJoinVO uvo) {
+        Long securityGroupId = uvo.getSecurityGroupId();
+        if (securityGroupId != null && securityGroupId.longValue() != 0) {
+            SecurityGroupResponse resp = new SecurityGroupResponse();
+            resp.setId(uvo.getSecurityGroupUuid());
+            resp.setName(uvo.getSecurityGroupName());
+            resp.setDescription(uvo.getSecurityGroupDescription());
+            resp.setObjectName("securitygroup");
+            if (uvo.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) {
+                resp.setProjectId(uvo.getProjectUuid());
+                resp.setProjectName(uvo.getProjectName());
+            } else {
+                resp.setAccountName(uvo.getAccountName());
+            }
+            userVmData.addSecurityGroup(resp);
+        }
+
+        long nic_id = uvo.getNicId();
+        if (nic_id > 0) {
+            NicResponse nicResponse = new NicResponse();
+            // The numbered comments are to keep track of the data returned from here and ApiResponseHelper.createNicResponse()
+            // the data can't be identical but some tidying up/unifying might be possible
+            /*1: nicUuid*/
+            nicResponse.setId(uvo.getNicUuid());
+            /*2: networkUuid*/
+            nicResponse.setNetworkid(uvo.getNetworkUuid());
+            /*3: vmId makes no sense on a nested nic object so it is ommited here */
+
+            if (uvo.getTrafficType() != null) {
+            /*4: trafficType*/
+                nicResponse.setTrafficType(uvo.getTrafficType().toString());
+            }
+            if (uvo.getGuestType() != null) {
+                /*5: guestType*/
+                nicResponse.setType(uvo.getGuestType().toString());
+            }
+            /*6: ipAddress*/
+            nicResponse.setIpaddress(uvo.getIpAddress());
+            /*7: gateway*/
+            nicResponse.setGateway(uvo.getGateway());
+            /*8: netmask*/
+            nicResponse.setNetmask(uvo.getNetmask());
+            /*9: networkName*/
+            nicResponse.setNetworkName(uvo.getNetworkName());
+            /*10: macAddress*/
+            nicResponse.setMacAddress(uvo.getMacAddress());
+            /*11: IPv6Address*/
+            nicResponse.setIp6Address(uvo.getIp6Address());
+            /*12: IPv6Gateway*/
+            nicResponse.setIp6Gateway(uvo.getIp6Gateway());
+            /*13: IPv6Cidr*/
+            nicResponse.setIp6Cidr(uvo.getIp6Cidr());
+            /*14: deviceId*/
+// where do we find           nicResponse.setDeviceId(
+// this is probably not String.valueOf(uvo.getNicId())); as this is a db-id
+            /*15: broadcastURI*/
+            if (uvo.getBroadcastUri() != null) {
+                nicResponse.setBroadcastUri(uvo.getBroadcastUri().toString());
+            }
+            /*16: isolationURI*/
+            if (uvo.getIsolationUri() != null) {
+                nicResponse.setIsolationUri(uvo.getIsolationUri().toString());
+            }
+            /*17: default*/
+            nicResponse.setIsDefault(uvo.isDefaultNic());
+            List<NicSecondaryIpVO> secondaryIps = ApiDBUtils.findNicSecondaryIps(uvo.getNicId());
+            if (secondaryIps != null) {
+                List<NicSecondaryIpResponse> ipList = new ArrayList<NicSecondaryIpResponse>();
+                for (NicSecondaryIpVO ip : secondaryIps) {
+                    NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse();
+                    ipRes.setId(ip.getUuid());
+                    ApiResponseHelper.setResponseIpAddress(ip, ipRes);
+                    ipList.add(ipRes);
+                }
+                nicResponse.setSecondaryIps(ipList);
+            }
+
+            /* 18: extra dhcp options */
+            nicResponse.setObjectName("nic");
+            List<NicExtraDhcpOptionResponse> nicExtraDhcpOptionResponses = _nicExtraDhcpOptionDao.listByNicId(nic_id)
+                    .stream()
+                    .map(vo -> new NicExtraDhcpOptionResponse(Dhcp.DhcpOptionCode.valueOfInt(vo.getCode()).getName(), vo.getCode(), vo.getValue()))
+                    .collect(Collectors.toList());
+            nicResponse.setExtraDhcpOptions(nicExtraDhcpOptionResponses);
+            userVmData.addNic(nicResponse);
+        }
+
+        long tag_id = uvo.getTagId();
+        if (tag_id > 0 && !userVmData.containTag(tag_id)) {
+            addTagInformation(uvo, userVmData);
+        }
+
+        Long affinityGroupId = uvo.getAffinityGroupId();
+        if (affinityGroupId != null && affinityGroupId.longValue() != 0) {
+            AffinityGroupResponse resp = new AffinityGroupResponse();
+            resp.setId(uvo.getAffinityGroupUuid());
+            resp.setName(uvo.getAffinityGroupName());
+            resp.setDescription(uvo.getAffinityGroupDescription());
+            resp.setObjectName("affinitygroup");
+            resp.setAccountName(uvo.getAccountName());
+            userVmData.addAffinityGroup(resp);
+        }
+
+        return userVmData;
+    }
+
+    @Override
+    public List<UserVmJoinVO> searchByIds(Long... vmIds) {
+        // set detail batch query size
+        int DETAILS_BATCH_SIZE = 2000;
+        String batchCfg = _configDao.getValue("detail.batch.query.size");
+        if (batchCfg != null) {
+            DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg);
+        }
+        // query details by batches
+        List<UserVmJoinVO> uvList = new ArrayList<UserVmJoinVO>();
+        // query details by batches
+        int curr_index = 0;
+        if (vmIds.length > DETAILS_BATCH_SIZE) {
+            while ((curr_index + DETAILS_BATCH_SIZE) <= vmIds.length) {
+                Long[] ids = new Long[DETAILS_BATCH_SIZE];
+                for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) {
+                    ids[k] = vmIds[j];
+                }
+                SearchCriteria<UserVmJoinVO> sc = VmDetailSearch.create();
+                sc.setParameters("idIN", ids);
+                List<UserVmJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
+                if (vms != null) {
+                    uvList.addAll(vms);
+                }
+                curr_index += DETAILS_BATCH_SIZE;
+            }
+        }
+        if (curr_index < vmIds.length) {
+            int batch_size = (vmIds.length - curr_index);
+            // set the ids value
+            Long[] ids = new Long[batch_size];
+            for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) {
+                ids[k] = vmIds[j];
+            }
+            SearchCriteria<UserVmJoinVO> sc = VmDetailSearch.create();
+            sc.setParameters("idIN", ids);
+            List<UserVmJoinVO> vms = searchIncludingRemoved(sc, null, null, false);
+            if (vms != null) {
+                uvList.addAll(vms);
+            }
+        }
+        return uvList;
+    }
+
+    @Override
+    public List<UserVmJoinVO> newUserVmView(UserVm... userVms) {
+
+        Hashtable<Long, UserVm> userVmDataHash = new Hashtable<Long, UserVm>();
+        for (UserVm vm : userVms) {
+            if (!userVmDataHash.containsKey(vm.getId())) {
+                userVmDataHash.put(vm.getId(), vm);
+            }
+        }
+
+        Set<Long> vmIdSet = userVmDataHash.keySet();
+        List<UserVmJoinVO> uvms = searchByIds(vmIdSet.toArray(new Long[vmIdSet.size()]));
+        // populate transit password field from UserVm
+        if (uvms != null) {
+            for (UserVmJoinVO uvm : uvms) {
+                UserVm v = userVmDataHash.get(uvm.getId());
+                uvm.setPassword(v.getPassword());
+            }
+        }
+        return uvms;
+    }
+
+}
diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDao.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/VolumeJoinDao.java
rename to server/src/main/java/com/cloud/api/query/dao/VolumeJoinDao.java
diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
rename to server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
diff --git a/server/src/com/cloud/api/query/vo/AccountJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/AccountJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/AffinityGroupJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/AffinityGroupJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/AffinityGroupJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/AsyncJobJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/AsyncJobJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/AsyncJobJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/BaseViewVO.java b/server/src/main/java/com/cloud/api/query/vo/BaseViewVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/BaseViewVO.java
rename to server/src/main/java/com/cloud/api/query/vo/BaseViewVO.java
diff --git a/server/src/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java b/server/src/main/java/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java
rename to server/src/main/java/com/cloud/api/query/vo/BaseViewWithTagInformationVO.java
diff --git a/server/src/com/cloud/api/query/vo/ControlledViewEntity.java b/server/src/main/java/com/cloud/api/query/vo/ControlledViewEntity.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ControlledViewEntity.java
rename to server/src/main/java/com/cloud/api/query/vo/ControlledViewEntity.java
diff --git a/server/src/com/cloud/api/query/vo/DataCenterJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DataCenterJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/DataCenterJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/DataCenterJoinVO.java
diff --git a/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java
new file mode 100644
index 0000000..7651b19
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java
@@ -0,0 +1,282 @@
+// 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.api.query.vo;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.storage.Storage;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.offering.DiskOffering.Type;
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "disk_offering_view")
+public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, Identity {
+
+    @Id
+    @Column(name = "id", updatable = false, nullable = false)
+    private long id;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "display_text")
+    private String displayText;
+
+    @Column(name = "provisioning_type")
+    Storage.ProvisioningType provisioningType;
+
+    @Column(name = "disk_size")
+    long diskSize;
+
+    @Column(name = "tags", length = 4096)
+    String tags;
+
+    @Column(name = "use_local_storage")
+    private boolean useLocalStorage;
+
+    @Column(name = "system_use")
+    private boolean systemUse;
+
+    @Column(name = "customized")
+    private boolean customized;
+
+    @Column(name = "customized_iops")
+    private Boolean customizedIops;
+
+    @Column(name = "min_iops")
+    private Long minIops;
+
+    @Column(name = "max_iops")
+    private Long maxIops;
+
+    @Column(name = "hv_ss_reserve")
+    private Integer hypervisorSnapshotReserve;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "bytes_read_rate")
+    Long bytesReadRate;
+
+    @Column(name = "bytes_read_rate_max")
+    Long bytesReadRateMax;
+
+    @Column(name = "bytes_read_rate_max_length")
+    Long bytesReadRateMaxLength;
+
+    @Column(name = "bytes_write_rate")
+    Long bytesWriteRate;
+
+    @Column(name = "bytes_write_rate_max")
+    Long bytesWriteRateMax;
+
+    @Column(name = "bytes_write_rate_max_length")
+    Long bytesWriteRateMaxLength;
+
+    @Column(name = "iops_read_rate")
+    Long iopsReadRate;
+
+    @Column(name = "iops_read_rate_max")
+    Long iopsReadRateMax;
+
+    @Column(name = "iops_read_rate_max_length")
+    Long iopsReadRateMaxLength;
+
+    @Column(name = "iops_write_rate")
+    Long iopsWriteRate;
+
+    @Column(name = "iops_write_rate_max")
+    Long iopsWriteRateMax;
+
+    @Column(name = "iops_write_rate_max_length")
+    Long iopsWriteRateMaxLength;
+
+    @Column(name = "cache_mode")
+    String cacheMode;
+
+    @Column(name = "type")
+    Type type;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = "domain_id")
+    private long domainId;
+
+    @Column(name = "domain_uuid")
+    private String domainUuid;
+
+    @Column(name = "domain_name")
+    private String domainName = null;
+
+    @Column(name = "domain_path")
+    private String domainPath = null;
+
+    @Column(name = "display_offering")
+    boolean displayOffering;
+
+    public DiskOfferingJoinVO() {
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Storage.ProvisioningType getProvisioningType(){
+        return provisioningType;
+    }
+
+    public long getDiskSize() {
+        return diskSize;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public boolean isUseLocalStorage() {
+        return useLocalStorage;
+    }
+
+    public boolean isSystemUse() {
+        return systemUse;
+    }
+
+    public boolean isCustomized() {
+        return customized;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    public String getCacheMode() {
+        return cacheMode;
+    }
+
+    public void setCacheMode(String cacheMode) {
+        this.cacheMode = cacheMode;
+    }
+
+    public boolean isDisplayOffering() {
+        return displayOffering;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public long getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainUuid() {
+        return domainUuid;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getDomainPath() {
+        return domainPath;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public Long getBytesReadRateMax() { return bytesReadRateMax; }
+
+    public Long getBytesReadRateMaxLength() { return bytesReadRateMaxLength; }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public Long getBytesWriteRateMax() { return bytesWriteRateMax; }
+
+    public Long getBytesWriteRateMaxLength() { return bytesWriteRateMaxLength; }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public Long getIopsReadRateMax() { return iopsReadRateMax; }
+
+    public Long getIopsReadRateMaxLength() { return iopsReadRateMaxLength; }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public Long getIopsWriteRateMax() { return iopsWriteRateMax; }
+
+    public Long getIopsWriteRateMaxLength() { return iopsWriteRateMaxLength; }
+}
diff --git a/server/src/com/cloud/api/query/vo/DomainJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/DomainJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DomainRouterJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/DomainRouterJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/EventJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/EventJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/EventJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/HostJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/HostJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/HostJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/HostJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/HostTagVO.java b/server/src/main/java/com/cloud/api/query/vo/HostTagVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/HostTagVO.java
rename to server/src/main/java/com/cloud/api/query/vo/HostTagVO.java
diff --git a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ImageStoreJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/ImageStoreJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/InstanceGroupJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/InstanceGroupJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/InstanceGroupJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/ProjectAccountJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ProjectAccountJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ProjectAccountJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/ProjectAccountJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ProjectInvitationJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ProjectInvitationJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/ProjectInvitationJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/ProjectJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ProjectJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ProjectJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/ProjectJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ResourceTagJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/ResourceTagJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/ResourceTagJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/SecurityGroupJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/SecurityGroupJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/SecurityGroupJoinVO.java
diff --git a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
new file mode 100644
index 0000000..9ea2d9a
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
@@ -0,0 +1,332 @@
+// 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.api.query.vo;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.storage.Storage;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = "service_offering_view")
+public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentity, Identity {
+
+    @Id
+    @Column(name = "id", updatable = false, nullable = false)
+    private long id;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "display_text")
+    private String displayText;
+
+    @Column(name = "provisioning_type")
+    Storage.ProvisioningType provisioningType;
+
+    @Column(name = "tags", length = 4096)
+    String tags;
+
+    @Column(name = "use_local_storage")
+    private boolean useLocalStorage;
+
+    @Column(name = "system_use")
+    private boolean systemUse;
+
+    @Column(name = "cpu")
+    private Integer cpu;
+
+    @Column(name = "speed")
+    private Integer speed;
+
+    @Column(name = "ram_size")
+    private Integer ramSize;
+
+    @Column(name = "nw_rate")
+    private Integer rateMbps;
+
+    @Column(name = "mc_rate")
+    private Integer multicastRateMbps;
+
+    @Column(name = "ha_enabled")
+    private boolean offerHA;
+
+    @Column(name = "limit_cpu_use")
+    private boolean limitCpuUse;
+
+    @Column(name = "is_volatile")
+    private boolean volatileVm;
+
+    @Column(name = "host_tag")
+    private String hostTag;
+
+    @Column(name = "default_use")
+    private boolean defaultUse;
+
+    @Column(name = "vm_type")
+    private String vmType;
+
+    @Column(name = "customized_iops")
+    private Boolean customizedIops;
+
+    @Column(name = "min_iops")
+    private Long minIops;
+
+    @Column(name = "max_iops")
+    private Long maxIops;
+
+    @Column(name = "hv_ss_reserve")
+    private Integer hypervisorSnapshotReserve;
+
+    @Column(name = "sort_key")
+    int sortKey;
+
+    @Column(name = "bytes_read_rate")
+    Long bytesReadRate;
+
+    @Column(name = "bytes_read_rate_max")
+    Long bytesReadRateMax;
+
+    @Column(name = "bytes_read_rate_max_length")
+    Long bytesReadRateMaxLength;
+
+    @Column(name = "bytes_write_rate")
+    Long bytesWriteRate;
+
+    @Column(name = "bytes_write_rate_max")
+    Long bytesWriteRateMax;
+
+    @Column(name = "bytes_write_rate_max_length")
+    Long bytesWriteRateMaxLength;
+
+    @Column(name = "iops_read_rate")
+    Long iopsReadRate;
+
+    @Column(name = "iops_read_rate_max")
+    Long iopsReadRateMax;
+
+    @Column(name = "iops_read_rate_max_length")
+    Long iopsReadRateMaxLength;
+
+    @Column(name = "iops_write_rate")
+    Long iopsWriteRate;
+
+    @Column(name = "iops_write_rate_max")
+    Long iopsWriteRateMax;
+
+    @Column(name = "iops_write_rate_max_length")
+    Long iopsWriteRateMaxLength;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = "domain_id")
+    private long domainId;
+
+    @Column(name = "domain_uuid")
+    private String domainUuid;
+
+    @Column(name = "domain_name")
+    private String domainName = null;
+
+    @Column(name = "domain_path")
+    private String domainPath = null;
+
+    @Column(name = "deployment_planner")
+    private String deploymentPlanner;
+
+    public ServiceOfferingJoinVO() {
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public Storage.ProvisioningType getProvisioningType(){
+        return provisioningType;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public boolean isUseLocalStorage() {
+        return useLocalStorage;
+    }
+
+    public boolean isSystemUse() {
+        return systemUse;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public long getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainUuid() {
+        return domainUuid;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getDomainPath() {
+        return domainPath;
+    }
+
+    public Boolean isCustomizedIops() {
+        return customizedIops;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Integer getHypervisorSnapshotReserve() {
+        return hypervisorSnapshotReserve;
+    }
+
+    public int getSortKey() {
+        return sortKey;
+    }
+
+    public Integer getCpu() {
+        return cpu;
+    }
+
+    public Integer getSpeed() {
+        return speed;
+    }
+
+    public Integer getRamSize() {
+        return ramSize;
+    }
+
+    public Integer getRateMbps() {
+        return rateMbps;
+    }
+
+    public Integer getMulticastRateMbps() {
+        return multicastRateMbps;
+    }
+
+    public boolean isOfferHA() {
+        return offerHA;
+    }
+
+    public boolean isLimitCpuUse() {
+        return limitCpuUse;
+    }
+
+    public String getHostTag() {
+        return hostTag;
+    }
+
+    public boolean isDefaultUse() {
+        return defaultUse;
+    }
+
+    public String getSystemVmType() {
+        return vmType;
+    }
+
+    public String getDeploymentPlanner() {
+        return deploymentPlanner;
+    }
+
+    public boolean getVolatileVm() {
+        return volatileVm;
+    }
+
+    public Long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public Long getBytesReadRateMax() { return bytesReadRateMax; }
+
+    public Long getBytesReadRateMaxLength() { return bytesReadRateMaxLength; }
+
+    public Long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public Long getBytesWriteRateMax() { return bytesWriteRateMax; }
+
+    public Long getBytesWriteRateMaxLength() { return bytesWriteRateMaxLength; }
+
+    public Long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public Long getIopsReadRateMax() { return iopsReadRateMax; }
+
+    public Long getIopsReadRateMaxLength() { return iopsReadRateMaxLength; }
+
+    public Long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
+    public Long getIopsWriteRateMax() { return iopsWriteRateMax; }
+
+    public Long getIopsWriteRateMaxLength() { return iopsWriteRateMaxLength; }
+
+
+    public boolean isDynamic() {
+        return cpu == null || speed == null || ramSize == null;
+    }
+}
diff --git a/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/TemplateJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/UserAccountJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/UserAccountJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/UserAccountJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/UserAccountJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/UserVmJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/UserVmJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/UserVmJoinVO.java
diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/VolumeJoinVO.java
similarity index 100%
rename from server/src/com/cloud/api/query/vo/VolumeJoinVO.java
rename to server/src/main/java/com/cloud/api/query/vo/VolumeJoinVO.java
diff --git a/server/src/main/java/com/cloud/api/response/ApiResponseSerializer.java b/server/src/main/java/com/cloud/api/response/ApiResponseSerializer.java
new file mode 100644
index 0000000..c72f957
--- /dev/null
+++ b/server/src/main/java/com/cloud/api/response/ApiResponseSerializer.java
@@ -0,0 +1,380 @@
+// 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.api.response;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseGsonHelper;
+import com.cloud.api.ApiServer;
+import com.cloud.serializer.Param;
+import com.cloud.user.Account;
+import com.cloud.utils.HttpUtils;
+import com.cloud.utils.encoding.URLEncoder;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionProxyObject;
+import com.google.gson.Gson;
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.ResponseObject;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.AuthenticationCmdResponse;
+import org.apache.cloudstack.api.response.CreateCmdResponse;
+import org.apache.cloudstack.api.response.ExceptionResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ApiResponseSerializer {
+    private static final Logger s_logger = Logger.getLogger(ApiResponseSerializer.class.getName());
+
+    public static String toSerializedString(ResponseObject result, String responseType) {
+        s_logger.trace("===Serializing Response===");
+        if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
+            return toJSONSerializedString(result, new StringBuilder());
+        } else {
+            return toXMLSerializedString(result, new StringBuilder());
+        }
+    }
+
+    public static String toSerializedStringWithSecureLogs(ResponseObject result, String responseType, StringBuilder log) {
+        s_logger.trace("===Serializing Response===");
+        if (HttpUtils.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
+            return toJSONSerializedString(result, log);
+        } else {
+            return toXMLSerializedString(result, log);
+        }
+    }
+
+    private static final Pattern s_unicodeEscapePattern = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");
+
+    public static String unescape(String escaped) {
+        String str = escaped;
+        Matcher matcher = s_unicodeEscapePattern.matcher(str);
+        while (matcher.find()) {
+            str = str.replaceAll("\\" + matcher.group(0), Character.toString((char)Integer.parseInt(matcher.group(1), 16)));
+        }
+        return str;
+    }
+
+    public static String toJSONSerializedString(ResponseObject result, StringBuilder log) {
+        if (result != null && log != null) {
+            Gson responseBuilder = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
+            Gson logBuilder = ApiResponseGsonHelper.getLogBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create();
+
+            StringBuilder sb = new StringBuilder();
+
+            sb.append("{\"").append(result.getResponseName()).append("\":");
+            log.append("{\"").append(result.getResponseName()).append("\":");
+            if (result instanceof ListResponse) {
+                List<? extends ResponseObject> responses = ((ListResponse)result).getResponses();
+                Integer count = ((ListResponse)result).getCount();
+                boolean nonZeroCount = (count != null && count.longValue() != 0);
+                if (nonZeroCount) {
+                    sb.append("{\"").append(ApiConstants.COUNT).append("\":").append(count);
+                    log.append("{\"").append(ApiConstants.COUNT).append("\":").append(count);
+                }
+
+                if ((responses != null) && !responses.isEmpty()) {
+                    String jsonStr = responseBuilder.toJson(responses.get(0));
+                    jsonStr = unescape(jsonStr);
+                    String logStr = logBuilder.toJson(responses.get(0));
+                    logStr = unescape(logStr);
+
+                    if (nonZeroCount) {
+                        sb.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(jsonStr);
+                        log.append(",\"").append(responses.get(0).getObjectName()).append("\":[").append(logStr);
+                    }
+
+                    for (int i = 1; i < ((ListResponse)result).getResponses().size(); i++) {
+                        jsonStr = responseBuilder.toJson(responses.get(i));
+                        jsonStr = unescape(jsonStr);
+                        logStr = logBuilder.toJson(responses.get(i));
+                        logStr = unescape(logStr);
+                        sb.append(",").append(jsonStr);
+                        log.append(",").append(logStr);
+                    }
+                    sb.append("]}");
+                    log.append("]}");
+                } else  {
+                    if (!nonZeroCount) {
+                        sb.append("{");
+                        log.append("{");
+                    }
+
+                    sb.append("}");
+                    log.append("}");
+                }
+            } else if (result instanceof SuccessResponse || result instanceof ExceptionResponse) {
+                final String jsonErrorText = unescape(responseBuilder.toJson(result));
+                sb.append(jsonErrorText);
+                log.append(jsonErrorText);
+            } else {
+                String jsonStr = responseBuilder.toJson(result);
+                if (jsonStr != null && !jsonStr.isEmpty()) {
+                    jsonStr = unescape(jsonStr);
+                    if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) {
+                        sb.append(jsonStr);
+                    } else {
+                        sb.append("{\"").append(result.getObjectName()).append("\":").append(jsonStr).append("}");
+                    }
+                } else {
+                    sb.append("{}");
+                }
+                String logStr = logBuilder.toJson(result);
+                if (logStr != null && !logStr.isEmpty()) {
+                    logStr = unescape(logStr);
+                    if (result instanceof AsyncJobResponse || result instanceof CreateCmdResponse || result instanceof AuthenticationCmdResponse) {
+                        log.append(logStr);
+                    } else {
+                        log.append("{\"").append(result.getObjectName()).append("\":").append(logStr).append("}");
+                    }
+                } else {
+                    log.append("{}");
+                }
+            }
+            sb.append("}");
+            log.append("}");
+            return sb.toString();
+        }
+        return null;
+    }
+
+    private static String toXMLSerializedString(ResponseObject result, StringBuilder log) {
+        if (result != null && log != null) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+            sb.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
+            log.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+            log.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
+
+            if (result instanceof ListResponse) {
+                Integer count = ((ListResponse)result).getCount();
+
+                if (count != null && count != 0) {
+                    sb.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append("</").append(ApiConstants.COUNT).append(">");
+                    log.append("<").append(ApiConstants.COUNT).append(">").append(((ListResponse)result).getCount()).append("</").append(ApiConstants.COUNT).append(">");
+                }
+                List<? extends ResponseObject> responses = ((ListResponse)result).getResponses();
+                if ((responses != null) && !responses.isEmpty()) {
+                    for (ResponseObject obj : responses) {
+                        serializeResponseObjXML(sb, log, obj);
+                    }
+                }
+            } else {
+                if (result instanceof CreateCmdResponse || result instanceof AsyncJobResponse || result instanceof AuthenticationCmdResponse) {
+                    serializeResponseObjFieldsXML(sb, log, result);
+                } else {
+                    serializeResponseObjXML(sb, log, result);
+                }
+            }
+
+            sb.append("</").append(result.getResponseName()).append(">");
+            log.append("</").append(result.getResponseName()).append(">");
+            return sb.toString();
+        }
+        return null;
+    }
+
+    private static void serializeResponseObjXML(StringBuilder sb, StringBuilder log, ResponseObject obj) {
+        if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) {
+            sb.append("<").append(obj.getObjectName()).append(">");
+            log.append("<").append(obj.getObjectName()).append(">");
+        }
+        serializeResponseObjFieldsXML(sb, log, obj);
+        if (!(obj instanceof SuccessResponse) && !(obj instanceof ExceptionResponse)) {
+            sb.append("</").append(obj.getObjectName()).append(">");
+            log.append("</").append(obj.getObjectName()).append(">");
+        }
+    }
+
+    private static Field[] getFlattenFields(Class<?> clz) {
+        List<Field> fields = new ArrayList<Field>();
+        fields.addAll(Arrays.asList(clz.getDeclaredFields()));
+        if (clz.getSuperclass() != null) {
+            fields.addAll(Arrays.asList(getFlattenFields(clz.getSuperclass())));
+        }
+        return fields.toArray(new Field[] {});
+    }
+
+    private static void serializeResponseObjFieldsXML(StringBuilder sb, StringBuilder log, ResponseObject obj) {
+        boolean isAsync = false;
+        if (obj instanceof AsyncJobResponse)
+            isAsync = true;
+
+        Field[] fields = getFlattenFields(obj.getClass());
+        for (Field field : fields) {
+            if ((field.getModifiers() & Modifier.TRANSIENT) != 0) {
+                continue; // skip transient fields
+            }
+
+            SerializedName serializedName = field.getAnnotation(SerializedName.class);
+            if (serializedName == null) {
+                continue; // skip fields w/o serialized name
+            }
+
+            boolean logField = true;
+            Param param = field.getAnnotation(Param.class);
+            if (param != null) {
+                RoleType[] allowedRoles = param.authorized();
+                if (allowedRoles.length > 0) {
+                    boolean permittedParameter = false;
+                    Account caller = CallContext.current().getCallingAccount();
+                    for (RoleType allowedRole : allowedRoles) {
+                        if (allowedRole.getAccountType() == caller.getType()) {
+                            permittedParameter = true;
+                            break;
+                        }
+                    }
+                    if (!permittedParameter) {
+                        s_logger.trace("Ignoring parameter " + param.name() + " as the caller is not authorized to see it");
+                        continue;
+                    }
+                }
+                if (param.isSensitive()) {
+                    logField = false;
+                }
+            }
+
+            field.setAccessible(true);
+            Object fieldValue = null;
+            try {
+                fieldValue = field.get(obj);
+            } catch (IllegalArgumentException e) {
+                throw new CloudRuntimeException("how illegal is it?", e);
+            } catch (IllegalAccessException e) {
+                throw new CloudRuntimeException("come on...we set accessible already", e);
+            }
+            if (fieldValue != null) {
+                if (fieldValue instanceof ResponseObject) {
+                    ResponseObject subObj = (ResponseObject)fieldValue;
+                    if (isAsync) {
+                        sb.append("<jobresult>");
+                        log.append("<jobresult>");
+                    }
+                    serializeResponseObjXML(sb, log, subObj);
+                    if (isAsync) {
+                        sb.append("</jobresult>");
+                        log.append("</jobresult>");
+                    }
+                } else if (fieldValue instanceof Collection<?>) {
+                    Collection<?> subResponseList = (Collection<?>)fieldValue;
+                    boolean usedUuidList = false;
+                    for (Object value : subResponseList) {
+                        if (value instanceof ResponseObject) {
+                            ResponseObject subObj = (ResponseObject)value;
+                            if (serializedName != null) {
+                                subObj.setObjectName(serializedName.value());
+                            }
+                            serializeResponseObjXML(sb, log, subObj);
+                        } else if (value instanceof ExceptionProxyObject) {
+                            // Only exception reponses carry a list of
+                            // ExceptionProxyObject objects.
+                            ExceptionProxyObject idProxy = (ExceptionProxyObject)value;
+                            // If this is the first IdentityProxy field
+                            // encountered, put in a uuidList tag.
+                            if (!usedUuidList) {
+                                sb.append("<" + serializedName.value() + ">");
+                                log.append("<" + serializedName.value() + ">");
+                                usedUuidList = true;
+                            }
+                            sb.append("<" + "uuid" + ">" + idProxy.getUuid() + "</" + "uuid" + ">");
+                            log.append("<" + "uuid" + ">" + idProxy.getUuid() + "</" + "uuid" + ">");
+                            // Append the new descriptive property also.
+                            String idFieldName = idProxy.getDescription();
+                            if (idFieldName != null) {
+                                sb.append("<" + "uuidProperty" + ">" + idFieldName + "</" + "uuidProperty" + ">");
+                                log.append("<" + "uuidProperty" + ">" + idFieldName + "</" + "uuidProperty" + ">");
+                            }
+                        } else if (value instanceof String) {
+                            sb.append("<").append(serializedName.value()).append(">").append(value).append("</").append(serializedName.value()).append(">");
+                            if (logField) {
+                                log.append("<").append(serializedName.value()).append(">").append(value).append("</").append(serializedName.value()).append(">");
+                            }
+                        }
+                    }
+                    if (usedUuidList) {
+                        // close the uuidList.
+                        sb.append("</").append(serializedName.value()).append(">");
+                        log.append("</").append(serializedName.value()).append(">");
+                    }
+                } else if (fieldValue instanceof Date) {
+                    sb.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append("</").append(serializedName.value()).append(">");
+                    log.append("<").append(serializedName.value()).append(">").append(BaseCmd.getDateString((Date)fieldValue)).append("</").append(serializedName.value()).append(">");
+                } else {
+                    String resultString = escapeSpecialXmlChars(fieldValue.toString());
+                    if (!(obj instanceof ExceptionResponse)) {
+                        resultString = encodeParam(resultString);
+                    }
+
+                    sb.append("<").append(serializedName.value()).append(">").append(resultString).append("</").append(serializedName.value()).append(">");
+                    if (logField) {
+                        log.append("<").append(serializedName.value()).append(">").append(resultString).append("</").append(serializedName.value()).append(">");
+                    }
+                }
+            }
+        }
+    }
+
+    private static String escapeSpecialXmlChars(String originalString) {
+        char[] origChars = originalString.toCharArray();
+        StringBuilder resultString = new StringBuilder();
+
+        for (char singleChar : origChars) {
+            if (singleChar == '"') {
+                resultString.append("&quot;");
+            } else if (singleChar == '\'') {
+                resultString.append("&apos;");
+            } else if (singleChar == '<') {
+                resultString.append("&lt;");
+            } else if (singleChar == '>') {
+                resultString.append("&gt;");
+            } else if (singleChar == '&') {
+                resultString.append("&amp;");
+            } else {
+                resultString.append(singleChar);
+            }
+        }
+
+        return resultString.toString();
+    }
+
+    private static String encodeParam(String value) {
+        if (!ApiServer.isEncodeApiResponse()) {
+            return value;
+        }
+        try {
+            return new URLEncoder().encode(value).replaceAll("\\+", "%20");
+        } catch (Exception e) {
+            s_logger.warn("Unable to encode: " + value, e);
+        }
+        return value;
+    }
+
+}
diff --git a/server/src/com/cloud/api/response/EmptyFieldExclusionStrategy.java b/server/src/main/java/com/cloud/api/response/EmptyFieldExclusionStrategy.java
similarity index 100%
rename from server/src/com/cloud/api/response/EmptyFieldExclusionStrategy.java
rename to server/src/main/java/com/cloud/api/response/EmptyFieldExclusionStrategy.java
diff --git a/server/src/com/cloud/api/response/SecurityGroupResultObject.java b/server/src/main/java/com/cloud/api/response/SecurityGroupResultObject.java
similarity index 100%
rename from server/src/com/cloud/api/response/SecurityGroupResultObject.java
rename to server/src/main/java/com/cloud/api/response/SecurityGroupResultObject.java
diff --git a/server/src/com/cloud/api/response/SecurityGroupRuleResultObject.java b/server/src/main/java/com/cloud/api/response/SecurityGroupRuleResultObject.java
similarity index 100%
rename from server/src/com/cloud/api/response/SecurityGroupRuleResultObject.java
rename to server/src/main/java/com/cloud/api/response/SecurityGroupRuleResultObject.java
diff --git a/server/src/com/cloud/async/AsyncJobResult.java b/server/src/main/java/com/cloud/async/AsyncJobResult.java
similarity index 100%
rename from server/src/com/cloud/async/AsyncJobResult.java
rename to server/src/main/java/com/cloud/async/AsyncJobResult.java
diff --git a/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java
new file mode 100644
index 0000000..cc2d7a5
--- /dev/null
+++ b/server/src/main/java/com/cloud/capacity/CapacityManagerImpl.java
@@ -0,0 +1,1146 @@
+// 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.capacity;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.deploy.DeploymentClusterPlanner;
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.ConnectionException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.resource.ResourceListener;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ServerResource;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.UserVmDetailVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Event;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+public class CapacityManagerImpl extends ManagerBase implements CapacityManager, StateListener<State, VirtualMachine.Event, VirtualMachine>, Listener, ResourceListener,
+        Configurable {
+    private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class);
+    @Inject
+    CapacityDao _capacityDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ServiceOfferingDao _offeringsDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    VolumeDao _volumeDao;
+    @Inject
+    VMTemplatePoolDao _templatePoolDao;
+    @Inject
+    AgentManager _agentManager;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    StorageManager _storageMgr;
+    @Inject
+    HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
+    @Inject
+    protected VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    protected UserVmDao _userVMDao;
+    @Inject
+    protected UserVmDetailsDao _userVmDetailsDao;
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    DataStoreProviderManager _dataStoreProviderMgr;
+
+    @Inject
+    ClusterDetailsDao _clusterDetailsDao;
+    private int _vmCapacityReleaseInterval;
+    long _extraBytesPerVolume = 0;
+
+    @Inject
+    MessageBus _messageBus;
+
+    private static final String MESSAGE_RESERVED_CAPACITY_FREED_FLAG = "Message.ReservedCapacityFreed.Flag";
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+
+        VirtualMachine.State.getStateMachine().registerListener(this);
+        _agentManager.registerForHostEvents(new StorageCapacityListener(_capacityDao, _storageMgr), true, false, false);
+        _agentManager.registerForHostEvents(new ComputeCapacityListener(_capacityDao, this), true, false, false);
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        _resourceMgr.registerResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, this);
+        _resourceMgr.registerResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, this);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @DB
+    @Override
+    public boolean releaseVmCapacity(VirtualMachine vm, final boolean moveFromReserved, final boolean moveToReservered, final Long hostId) {
+        if (hostId == null) {
+            return true;
+        }
+
+        final ServiceOfferingVO svo = _offeringsDao.findById(vm.getId(), vm.getServiceOfferingId());
+        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
+        CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
+        Long clusterId = null;
+        if (hostId != null) {
+            HostVO host = _hostDao.findById(hostId);
+            if (host == null) {
+                s_logger.warn("Host " + hostId + " no long exist anymore!");
+                return true;
+            }
+
+            clusterId = host.getClusterId();
+        }
+        if (capacityCpu == null || capacityMemory == null || svo == null) {
+            return false;
+        }
+
+        try {
+            final Long clusterIdFinal = clusterId;
+            final long capacityCpuId = capacityCpu.getId();
+            final long capacityMemoryId = capacityMemory.getId();
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true);
+                    CapacityVO capacityMemory = _capacityDao.lockRow(capacityMemoryId, true);
+
+                    long usedCpu = capacityCpu.getUsedCapacity();
+                    long usedMem = capacityMemory.getUsedCapacity();
+                    long reservedCpu = capacityCpu.getReservedCapacity();
+                    long reservedMem = capacityMemory.getReservedCapacity();
+                    long actualTotalCpu = capacityCpu.getTotalCapacity();
+                    float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal, "cpuOvercommitRatio").getValue());
+                    float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterIdFinal, "memoryOvercommitRatio").getValue());
+                    int vmCPU = svo.getCpu() * svo.getSpeed();
+                    long vmMem = svo.getRamSize() * 1024L * 1024L;
+                    long actualTotalMem = capacityMemory.getTotalCapacity();
+                    long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
+                    long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
+                        s_logger.debug("Hosts's actual total RAM: " + actualTotalMem + " and RAM after applying overprovisioning: " + totalMem);
+                    }
+
+                    if (!moveFromReserved) {
+                        /* move resource from used */
+                        if (usedCpu >= vmCPU) {
+                            capacityCpu.setUsedCapacity(usedCpu - vmCPU);
+                        }
+                        if (usedMem >= vmMem) {
+                            capacityMemory.setUsedCapacity(usedMem - vmMem);
+                        }
+
+                        if (moveToReservered) {
+                            if (reservedCpu + vmCPU <= totalCpu) {
+                                capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
+                            }
+                            if (reservedMem + vmMem <= totalMem) {
+                                capacityMemory.setReservedCapacity(reservedMem + vmMem);
+                            }
+                        }
+                    } else {
+                        if (reservedCpu >= vmCPU) {
+                            capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
+                        }
+                        if (reservedMem >= vmMem) {
+                            capacityMemory.setReservedCapacity(reservedMem - vmMem);
+                        }
+                    }
+
+                    s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", actual total: " + actualTotalCpu +
+                        ", total with overprovisioning: " + totalCpu + "; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + capacityCpu.getReservedCapacity() +
+                        "; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
+
+                    s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem + "; new used: " +
+                        capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() + "; movedfromreserved: " + moveFromReserved +
+                        ",moveToReservered" + moveToReservered);
+
+                    _capacityDao.update(capacityCpu.getId(), capacityCpu);
+                    _capacityDao.update(capacityMemory.getId(), capacityMemory);
+                }
+            });
+
+            return true;
+        } catch (Exception e) {
+            s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
+            return false;
+        }
+    }
+
+    @DB
+    @Override
+    public void allocateVmCapacity(VirtualMachine vm, final boolean fromLastHost) {
+
+        final long hostId = vm.getHostId();
+        HostVO host = _hostDao.findById(hostId);
+        final long clusterId = host.getClusterId();
+        final float cpuOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio").getValue());
+        final float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(clusterId, "memoryOvercommitRatio").getValue());
+
+        final ServiceOfferingVO svo = _offeringsDao.findById(vm.getId(), vm.getServiceOfferingId());
+
+        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
+        CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
+
+        if (capacityCpu == null || capacityMem == null || svo == null) {
+            return;
+        }
+
+        final int cpu = svo.getCpu() * svo.getSpeed();
+        final long ram = svo.getRamSize() * 1024L * 1024L;
+
+        try {
+            final long capacityCpuId = capacityCpu.getId();
+            final long capacityMemId = capacityMem.getId();
+
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    CapacityVO capacityCpu = _capacityDao.lockRow(capacityCpuId, true);
+                    CapacityVO capacityMem = _capacityDao.lockRow(capacityMemId, true);
+
+                    long usedCpu = capacityCpu.getUsedCapacity();
+                    long usedMem = capacityMem.getUsedCapacity();
+                    long reservedCpu = capacityCpu.getReservedCapacity();
+                    long reservedMem = capacityMem.getReservedCapacity();
+                    long actualTotalCpu = capacityCpu.getTotalCapacity();
+                    long actualTotalMem = capacityMem.getTotalCapacity();
+                    long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
+                    long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
+                    }
+
+                    long freeCpu = totalCpu - (reservedCpu + usedCpu);
+                    long freeMem = totalMem - (reservedMem + usedMem);
+
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("We are allocating VM, increasing the used capacity of this host:" + hostId);
+                        s_logger.debug("Current Used CPU: " + usedCpu + " , Free CPU:" + freeCpu + " ,Requested CPU: " + cpu);
+                        s_logger.debug("Current Used RAM: " + usedMem + " , Free RAM:" + freeMem + " ,Requested RAM: " + ram);
+                    }
+                    capacityCpu.setUsedCapacity(usedCpu + cpu);
+                    capacityMem.setUsedCapacity(usedMem + ram);
+
+                    if (fromLastHost) {
+                        /* alloc from reserved */
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("We are allocating VM to the last host again, so adjusting the reserved capacity if it is not less than required");
+                            s_logger.debug("Reserved CPU: " + reservedCpu + " , Requested CPU: " + cpu);
+                            s_logger.debug("Reserved RAM: " + reservedMem + " , Requested RAM: " + ram);
+                        }
+                        if (reservedCpu >= cpu && reservedMem >= ram) {
+                            capacityCpu.setReservedCapacity(reservedCpu - cpu);
+                            capacityMem.setReservedCapacity(reservedMem - ram);
+                        }
+                    } else {
+                        /* alloc from free resource */
+                        if (!((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem))) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Host doesnt seem to have enough free capacity, but increasing the used capacity anyways, " +
+                                    "since the VM is already starting on this host ");
+                            }
+                        }
+                    }
+
+                    s_logger.debug("CPU STATS after allocation: for host: " + hostId + ", old used: " + usedCpu + ", old reserved: " + reservedCpu + ", actual total: " +
+                        actualTotalCpu + ", total with overprovisioning: " + totalCpu + "; new used:" + capacityCpu.getUsedCapacity() + ", reserved:" +
+                        capacityCpu.getReservedCapacity() + "; requested cpu:" + cpu + ",alloc_from_last:" + fromLastHost);
+
+                    s_logger.debug("RAM STATS after allocation: for host: " + hostId + ", old used: " + usedMem + ", old reserved: " + reservedMem + ", total: " +
+                        totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " + capacityMem.getReservedCapacity() + "; requested mem: " + ram +
+                        ",alloc_from_last:" + fromLastHost);
+
+                    _capacityDao.update(capacityCpu.getId(), capacityCpu);
+                    _capacityDao.update(capacityMem.getId(), capacityMem);
+                }
+            });
+        } catch (Exception e) {
+            s_logger.error("Exception allocating VM capacity", e);
+            return;
+        }
+    }
+
+    @Override
+    public boolean checkIfHostHasCpuCapability(long hostId, Integer cpuNum, Integer cpuSpeed) {
+
+        // Check host can support the Cpu Number and Speed.
+        Host host = _hostDao.findById(hostId);
+        boolean isCpuNumGood = host.getCpus().intValue() >= cpuNum;
+        boolean isCpuSpeedGood = host.getSpeed().intValue() >= cpuSpeed;
+        if (isCpuNumGood && isCpuSpeedGood) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host: " + hostId + " has cpu capability (cpu:" + host.getCpus() + ", speed:" + host.getSpeed() +
+                    ") to support requested CPU: " + cpuNum + " and requested speed: " + cpuSpeed);
+            }
+            return true;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host: " + hostId + " doesn't have cpu capability (cpu:" + host.getCpus() + ", speed:" + host.getSpeed() +
+                    ") to support requested CPU: " + cpuNum + " and requested speed: " + cpuSpeed);
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOvercommitRatio, float memoryOvercommitRatio,
+        boolean considerReservedCapacity) {
+        boolean hasCapacity = false;
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking if host: " + hostId + " has enough capacity for requested CPU: " + cpu + " and requested RAM: " + ram +
+                " , cpuOverprovisioningFactor: " + cpuOvercommitRatio);
+        }
+
+        CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_CPU);
+        CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, Capacity.CAPACITY_TYPE_MEMORY);
+
+        if (capacityCpu == null || capacityMem == null) {
+            if (capacityCpu == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for CPU not found in Db, for hostId: " + hostId);
+                }
+            }
+            if (capacityMem == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Cannot checkIfHostHasCapacity, Capacity entry for RAM not found in Db, for hostId: " + hostId);
+                }
+            }
+
+            return false;
+        }
+
+        long usedCpu = capacityCpu.getUsedCapacity();
+        long usedMem = capacityMem.getUsedCapacity();
+        long reservedCpu = capacityCpu.getReservedCapacity();
+        long reservedMem = capacityMem.getReservedCapacity();
+        long actualTotalCpu = capacityCpu.getTotalCapacity();
+        long actualTotalMem = capacityMem.getTotalCapacity();
+        long totalCpu = (long)(actualTotalCpu * cpuOvercommitRatio);
+        long totalMem = (long)(actualTotalMem * memoryOvercommitRatio);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Hosts's actual total CPU: " + actualTotalCpu + " and CPU after applying overprovisioning: " + totalCpu);
+        }
+
+        String failureReason = "";
+        if (checkFromReservedCapacity) {
+            long freeCpu = reservedCpu;
+            long freeMem = reservedMem;
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("We need to allocate to the last host again, so checking if there is enough reserved capacity");
+                s_logger.debug("Reserved CPU: " + freeCpu + " , Requested CPU: " + cpu);
+                s_logger.debug("Reserved RAM: " + freeMem + " , Requested RAM: " + ram);
+            }
+            /* alloc from reserved */
+            if (reservedCpu >= cpu) {
+                if (reservedMem >= ram) {
+                    hasCapacity = true;
+                } else {
+                    failureReason = "Host does not have enough reserved RAM available";
+                }
+            } else {
+                failureReason = "Host does not have enough reserved CPU available";
+            }
+        } else {
+
+            long reservedCpuValueToUse = reservedCpu;
+            long reservedMemValueToUse = reservedMem;
+
+            if (!considerReservedCapacity) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("considerReservedCapacity is" + considerReservedCapacity + " , not considering reserved capacity for calculating free capacity");
+                }
+                reservedCpuValueToUse = 0;
+                reservedMemValueToUse = 0;
+            }
+            long freeCpu = totalCpu - (reservedCpuValueToUse + usedCpu);
+            long freeMem = totalMem - (reservedMemValueToUse + usedMem);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Free CPU: " + freeCpu + " , Requested CPU: " + cpu);
+                s_logger.debug("Free RAM: " + freeMem + " , Requested RAM: " + ram);
+            }
+            /* alloc from free resource */
+            if ((reservedCpuValueToUse + usedCpu + cpu <= totalCpu)) {
+                if ((reservedMemValueToUse + usedMem + ram <= totalMem)) {
+                    hasCapacity = true;
+                } else {
+                    failureReason = "Host does not have enough RAM available";
+                }
+            } else {
+                failureReason = "Host does not have enough CPU available";
+            }
+        }
+
+        if (hasCapacity) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host has enough CPU and RAM available");
+            }
+
+            s_logger.debug("STATS: Can alloc CPU from host: " + hostId + ", used: " + usedCpu + ", reserved: " + reservedCpu + ", actual total: " + actualTotalCpu +
+                ", total with overprovisioning: " + totalCpu + "; requested cpu:" + cpu + ",alloc_from_last_host?:" + checkFromReservedCapacity +
+                " ,considerReservedCapacity?: " + considerReservedCapacity);
+
+            s_logger.debug("STATS: Can alloc MEM from host: " + hostId + ", used: " + usedMem + ", reserved: " + reservedMem + ", total: " + totalMem +
+                "; requested mem: " + ram + ",alloc_from_last_host?:" + checkFromReservedCapacity + " ,considerReservedCapacity?: " + considerReservedCapacity);
+        } else {
+
+            if (checkFromReservedCapacity) {
+                s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", requested cpu: " + cpu + ", reservedMem: " +
+                    reservedMem + ", requested mem: " + ram);
+            } else {
+                s_logger.debug("STATS: Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", used cpu: " + usedCpu + ", requested cpu: " +
+                    cpu + ", actual total cpu: " + actualTotalCpu + ", total cpu with overprovisioning: " + totalCpu + ", reservedMem: " + reservedMem + ", used Mem: " +
+                    usedMem + ", requested mem: " + ram + ", total Mem:" + totalMem + " ,considerReservedCapacity?: " + considerReservedCapacity);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(failureReason + ", cannot allocate to this host.");
+            }
+        }
+
+        return hasCapacity;
+
+    }
+
+    @Override
+    public long getUsedBytes(StoragePoolVO pool) {
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
+
+        if (storeDriver instanceof PrimaryDataStoreDriver) {
+            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
+
+            return primaryStoreDriver.getUsedBytes(pool);
+        }
+
+        throw new CloudRuntimeException("Storage driver in CapacityManagerImpl.getUsedBytes(StoragePoolVO) is not a PrimaryDataStoreDriver.");
+    }
+
+    @Override
+    public long getUsedIops(StoragePoolVO pool) {
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
+
+        if (storeDriver instanceof PrimaryDataStoreDriver) {
+            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
+
+            return primaryStoreDriver.getUsedIops(pool);
+        }
+
+        throw new CloudRuntimeException("Storage driver in CapacityManagerImpl.getUsedIops(StoragePoolVO) is not a PrimaryDataStoreDriver.");
+    }
+
+    @Override
+    public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation) {
+        long totalAllocatedSize = 0;
+
+        // if the storage pool is managed, the used bytes can be larger than the sum of the sizes of all of the non-destroyed volumes
+        // in this case, call getUsedBytes(StoragePoolVO)
+        if (pool.isManaged()) {
+            return getUsedBytes(pool);
+        }
+        else {
+            // Get size for all the non-destroyed volumes.
+            Pair<Long, Long> sizes = _volumeDao.getNonDestroyedCountAndTotalByPool(pool.getId());
+
+            totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
+        }
+
+        // Get size for VM Snapshots.
+        totalAllocatedSize += _volumeDao.getVMSnapshotSizeByPool(pool.getId());
+
+        boolean tmpInstalled = false;
+        // Iterate through all templates on this storage pool.
+        List<VMTemplateStoragePoolVO> templatePoolVOs = _templatePoolDao.listByPoolId(pool.getId());
+
+        for (VMTemplateStoragePoolVO templatePoolVO : templatePoolVOs) {
+            if ((templateForVmCreation != null) && !tmpInstalled && (templatePoolVO.getTemplateId() == templateForVmCreation.getId())) {
+                tmpInstalled = true;
+            }
+
+            long templateSize = templatePoolVO.getTemplateSize();
+
+            totalAllocatedSize += templateSize + _extraBytesPerVolume;
+        }
+
+        if ((templateForVmCreation != null) && !tmpInstalled) {
+            long templateForVmCreationSize = templateForVmCreation.getSize() != null ? templateForVmCreation.getSize() : 0;
+
+            totalAllocatedSize += templateForVmCreationSize + _extraBytesPerVolume;
+        }
+
+        return totalAllocatedSize;
+    }
+
+    @DB
+    @Override
+    public void updateCapacityForHost(final Host host) {
+        // prepare the service offerings
+        List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
+        Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
+        for (ServiceOfferingVO offering : offerings) {
+            offeringsMap.put(offering.getId(), offering);
+        }
+
+        long usedCpuCore = 0;
+        long reservedCpuCore = 0;
+        long usedCpu = 0;
+        long usedMemory = 0;
+        long reservedMemory = 0;
+        long reservedCpu = 0;
+        final CapacityState capacityState = (host.getResourceState() == ResourceState.Enabled) ? CapacityState.Enabled : CapacityState.Disabled;
+
+        List<VMInstanceVO> vms = _vmDao.listUpByHostId(host.getId());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Found " + vms.size() + " VMs on host " + host.getId());
+        }
+
+        ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+        ClusterDetailsVO clusterDetailCpu = _clusterDetailsDao.findDetail(cluster.getId(), "cpuOvercommitRatio");
+        ClusterDetailsVO clusterDetailRam = _clusterDetailsDao.findDetail(cluster.getId(), "memoryOvercommitRatio");
+        Float clusterCpuOvercommitRatio = Float.parseFloat(clusterDetailCpu.getValue());
+        Float clusterRamOvercommitRatio = Float.parseFloat(clusterDetailRam.getValue());
+        for (VMInstanceVO vm : vms) {
+            Float cpuOvercommitRatio = 1.0f;
+            Float ramOvercommitRatio = 1.0f;
+            Map<String, String> vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+            String vmDetailCpu = vmDetails.get("cpuOvercommitRatio");
+            String vmDetailRam = vmDetails.get("memoryOvercommitRatio");
+            if (vmDetailCpu != null) {
+                //if vmDetail_cpu is not null it means it is running in a overcommited cluster.
+                cpuOvercommitRatio = Float.parseFloat(vmDetailCpu);
+                ramOvercommitRatio = Float.parseFloat(vmDetailRam);
+            }
+            ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
+            if (so.isDynamic()) {
+                usedMemory +=
+                    ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L) / ramOvercommitRatio) *
+                        clusterRamOvercommitRatio;
+                usedCpu +=
+                    ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
+                        clusterCpuOvercommitRatio;
+                usedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
+            } else {
+                usedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
+                usedCpu += ((so.getCpu() * so.getSpeed()) / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
+                usedCpuCore += so.getCpu();
+            }
+        }
+
+        List<VMInstanceVO> vmsByLastHostId = _vmDao.listByLastHostId(host.getId());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Found " + vmsByLastHostId.size() + " VM, not running on host " + host.getId());
+        }
+        for (VMInstanceVO vm : vmsByLastHostId) {
+            Float cpuOvercommitRatio = 1.0f;
+            Float ramOvercommitRatio = 1.0f;
+            long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime()) / 1000;
+            if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
+                UserVmDetailVO vmDetailCpu = _userVmDetailsDao.findDetail(vm.getId(), "cpuOvercommitRatio");
+                UserVmDetailVO vmDetailRam = _userVmDetailsDao.findDetail(vm.getId(), "memoryOvercommitRatio");
+                if (vmDetailCpu != null) {
+                    //if vmDetail_cpu is not null it means it is running in a overcommited cluster.
+                    cpuOvercommitRatio = Float.parseFloat(vmDetailCpu.getValue());
+                    ramOvercommitRatio = Float.parseFloat(vmDetailRam.getValue());
+                }
+                ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
+                Map<String, String> vmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+                if (so.isDynamic()) {
+                    reservedMemory +=
+                        ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.memory.name())) * 1024L * 1024L) / ramOvercommitRatio) *
+                            clusterRamOvercommitRatio;
+                    reservedCpu +=
+                        ((Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name())) * Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuSpeed.name()))) / cpuOvercommitRatio) *
+                            clusterCpuOvercommitRatio;
+                    reservedCpuCore += Integer.parseInt(vmDetails.get(UsageEventVO.DynamicParameters.cpuNumber.name()));
+                } else {
+                    reservedMemory += ((so.getRamSize() * 1024L * 1024L) / ramOvercommitRatio) * clusterRamOvercommitRatio;
+                    reservedCpu += (so.getCpu() * so.getSpeed() / cpuOvercommitRatio) * clusterCpuOvercommitRatio;
+                    reservedCpuCore += so.getCpu();
+                }
+            } else {
+                // signal if not done already, that the VM has been stopped for skip.counting.hours,
+                // hence capacity will not be reserved anymore.
+                UserVmDetailVO messageSentFlag = _userVmDetailsDao.findDetail(vm.getId(), MESSAGE_RESERVED_CAPACITY_FREED_FLAG);
+                if (messageSentFlag == null || !Boolean.valueOf(messageSentFlag.getValue())) {
+                    _messageBus.publish(_name, "VM_ReservedCapacity_Free", PublishScope.LOCAL, vm);
+
+                    if (vm.getType() == VirtualMachine.Type.User) {
+                        UserVmVO userVM = _userVMDao.findById(vm.getId());
+                        _userVMDao.loadDetails(userVM);
+                        userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "true");
+                        _userVMDao.saveDetails(userVM);
+                    }
+                }
+            }
+        }
+
+        CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU);
+        CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
+        CapacityVO cpuCoreCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU_CORE);
+
+        if (cpuCoreCap != null) {
+            long hostTotalCpuCore = host.getCpus().longValue();
+
+            if (cpuCoreCap.getTotalCapacity() != hostTotalCpuCore) {
+                s_logger.debug("Calibrate total cpu for host: " + host.getId() + " old total CPU:"
+                        + cpuCoreCap.getTotalCapacity() + " new total CPU:" + hostTotalCpuCore);
+                cpuCoreCap.setTotalCapacity(hostTotalCpuCore);
+
+            }
+
+            if (cpuCoreCap.getUsedCapacity() == usedCpuCore && cpuCoreCap.getReservedCapacity() == reservedCpuCore) {
+                s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpuCore: " + cpuCoreCap.getUsedCapacity()
+                        + " reservedCpuCore: " + cpuCoreCap.getReservedCapacity());
+            } else {
+                if (cpuCoreCap.getReservedCapacity() != reservedCpuCore) {
+                    s_logger.debug("Calibrate reserved cpu core for host: " + host.getId() + " old reservedCpuCore:"
+                            + cpuCoreCap.getReservedCapacity() + " new reservedCpuCore:" + reservedCpuCore);
+                    cpuCoreCap.setReservedCapacity(reservedCpuCore);
+                }
+                if (cpuCoreCap.getUsedCapacity() != usedCpuCore) {
+                    s_logger.debug("Calibrate used cpu core for host: " + host.getId() + " old usedCpuCore:"
+                            + cpuCoreCap.getUsedCapacity() + " new usedCpuCore:" + usedCpuCore);
+                    cpuCoreCap.setUsedCapacity(usedCpuCore);
+                }
+            }
+            try {
+                _capacityDao.update(cpuCoreCap.getId(), cpuCoreCap);
+            } catch (Exception e) {
+                s_logger.error("Caught exception while updating cpucore capacity for the host " +host.getId(), e);
+            }
+        } else {
+            final long usedCpuCoreFinal = usedCpuCore;
+            final long reservedCpuCoreFinal = reservedCpuCore;
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    CapacityVO capacity = new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedCpuCoreFinal, host.getCpus().longValue(),
+                            CapacityVO.CAPACITY_TYPE_CPU_CORE);
+                    capacity.setReservedCapacity(reservedCpuCoreFinal);
+                    capacity.setCapacityState(capacityState);
+                    _capacityDao.persist(capacity);
+                }
+            });
+        }
+
+        if (cpuCap != null && memCap != null) {
+            if (host.getTotalMemory() != null) {
+                memCap.setTotalCapacity(host.getTotalMemory());
+            }
+            long hostTotalCpu = host.getCpus().longValue() * host.getSpeed().longValue();
+
+            if (cpuCap.getTotalCapacity() != hostTotalCpu) {
+                s_logger.debug("Calibrate total cpu for host: " + host.getId() + " old total CPU:" + cpuCap.getTotalCapacity() + " new total CPU:" + hostTotalCpu);
+                cpuCap.setTotalCapacity(hostTotalCpu);
+
+            }
+            // Set the capacity state as per the host allocation state.
+            if(capacityState != cpuCap.getCapacityState()){
+                s_logger.debug("Calibrate cpu capacity state for host: " + host.getId() + " old capacity state:" + cpuCap.getTotalCapacity() + " new capacity state:" + hostTotalCpu);
+                cpuCap.setCapacityState(capacityState);
+            }
+            memCap.setCapacityState(capacityState);
+
+            if (cpuCap.getUsedCapacity() == usedCpu && cpuCap.getReservedCapacity() == reservedCpu) {
+                s_logger.debug("No need to calibrate cpu capacity, host:" + host.getId() + " usedCpu: " + cpuCap.getUsedCapacity() + " reservedCpu: " +
+                    cpuCap.getReservedCapacity());
+            } else {
+                if (cpuCap.getReservedCapacity() != reservedCpu) {
+                    s_logger.debug("Calibrate reserved cpu for host: " + host.getId() + " old reservedCpu:" + cpuCap.getReservedCapacity() + " new reservedCpu:" +
+                        reservedCpu);
+                    cpuCap.setReservedCapacity(reservedCpu);
+                }
+                if (cpuCap.getUsedCapacity() != usedCpu) {
+                    s_logger.debug("Calibrate used cpu for host: " + host.getId() + " old usedCpu:" + cpuCap.getUsedCapacity() + " new usedCpu:" + usedCpu);
+                    cpuCap.setUsedCapacity(usedCpu);
+                }
+            }
+
+            if (memCap.getTotalCapacity() != host.getTotalMemory()) {
+                s_logger.debug("Calibrate total memory for host: " + host.getId() + " old total memory:" + memCap.getTotalCapacity() + " new total memory:" +
+                    host.getTotalMemory());
+                memCap.setTotalCapacity(host.getTotalMemory());
+
+            }
+            // Set the capacity state as per the host allocation state.
+            if(capacityState != memCap.getCapacityState()){
+                s_logger.debug("Calibrate memory capacity state for host: " + host.getId() + " old capacity state:" + memCap.getTotalCapacity() + " new capacity state:" + hostTotalCpu);
+                memCap.setCapacityState(capacityState);
+            }
+
+            if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) {
+                s_logger.debug("No need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " +
+                    memCap.getReservedCapacity());
+            } else {
+                if (memCap.getReservedCapacity() != reservedMemory) {
+                    s_logger.debug("Calibrate reserved memory for host: " + host.getId() + " old reservedMem:" + memCap.getReservedCapacity() + " new reservedMem:" +
+                        reservedMemory);
+                    memCap.setReservedCapacity(reservedMemory);
+                }
+                if (memCap.getUsedCapacity() != usedMemory) {
+                    /*
+                     * Didn't calibrate for used memory, because VMs can be in
+                     * state(starting/migrating) that I don't know on which host
+                     * they are allocated
+                     */
+                    s_logger.debug("Calibrate used memory for host: " + host.getId() + " old usedMem: " + memCap.getUsedCapacity() + " new usedMem: " + usedMemory);
+                    memCap.setUsedCapacity(usedMemory);
+                }
+            }
+
+            try {
+                _capacityDao.update(cpuCap.getId(), cpuCap);
+                _capacityDao.update(memCap.getId(), memCap);
+            } catch (Exception e) {
+                s_logger.error("Caught exception while updating cpu/memory capacity for the host " + host.getId(), e);
+            }
+        } else {
+            final long usedMemoryFinal = usedMemory;
+            final long reservedMemoryFinal = reservedMemory;
+            final long usedCpuFinal = usedCpu;
+            final long reservedCpuFinal = reservedCpu;
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    CapacityVO capacity =
+                        new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedMemoryFinal, host.getTotalMemory(),
+                            Capacity.CAPACITY_TYPE_MEMORY);
+                    capacity.setReservedCapacity(reservedMemoryFinal);
+                    capacity.setCapacityState(capacityState);
+                    _capacityDao.persist(capacity);
+
+                    capacity =
+                        new CapacityVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId(), usedCpuFinal, host.getCpus().longValue() *
+                            host.getSpeed().longValue(), Capacity.CAPACITY_TYPE_CPU);
+                    capacity.setReservedCapacity(reservedCpuFinal);
+                    capacity.setCapacityState(capacityState);
+                    _capacityDao.persist(capacity);
+                }
+            });
+
+        }
+
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean transitionStatus, Object opaque) {
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      @SuppressWarnings("unchecked")
+      Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
+      Long oldHostId = hosts.first();
+
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      Event event = transition.getEvent();
+      s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
+              " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
+
+      if (oldState == State.Starting) {
+        if (newState != State.Running) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      } else if (oldState == State.Running) {
+        if (event == Event.AgentReportStopped) {
+          releaseVmCapacity(vm, false, true, oldHostId);
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      } else if (oldState == State.Migrating) {
+        if (event == Event.AgentReportStopped) {
+                /* Release capacity from original host */
+          releaseVmCapacity(vm, false, false, vm.getLastHostId());
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.OperationFailed) {
+                /* Release from dest host */
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.OperationSucceeded) {
+          releaseVmCapacity(vm, false, false, vm.getLastHostId());
+        }
+      } else if (oldState == State.Stopping) {
+        if (event == Event.OperationSucceeded) {
+          releaseVmCapacity(vm, false, true, oldHostId);
+        } else if (event == Event.AgentReportStopped) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      } else if (oldState == State.Stopped) {
+        if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
+          releaseVmCapacity(vm, true, false, vm.getLastHostId());
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      }
+
+      if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
+        boolean fromLastHost = false;
+        if (vm.getHostId().equals(vm.getLastHostId())) {
+          s_logger.debug("VM starting again on the last host it was stopped on");
+          fromLastHost = true;
+        }
+        allocateVmCapacity(vm, fromLastHost);
+      }
+
+      if (newState == State.Stopped) {
+        if (vm.getType() == VirtualMachine.Type.User) {
+
+          UserVmVO userVM = _userVMDao.findById(vm.getId());
+          _userVMDao.loadDetails(userVM);
+          // free the message sent flag if it exists
+          userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
+          _userVMDao.saveDetails(userVM);
+
+        }
+      }
+
+      return true;
+    }
+
+  // TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
+    // create capacity entries if none exist for this server
+    private void createCapacityEntry(StartupCommand startup, HostVO server) {
+        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
+        capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
+        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
+        capacitySC.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
+
+        if (startup instanceof StartupRoutingCommand) {
+            SearchCriteria<CapacityVO> capacityCPU = _capacityDao.createSearchCriteria();
+            capacityCPU.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
+            capacityCPU.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
+            capacityCPU.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
+            capacityCPU.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_CPU);
+            List<CapacityVO> capacityVOCpus = _capacityDao.search(capacitySC, null);
+            Float cpuovercommitratio = Float.parseFloat(_clusterDetailsDao.findDetail(server.getClusterId(), "cpuOvercommitRatio").getValue());
+            Float memoryOvercommitRatio = Float.parseFloat(_clusterDetailsDao.findDetail(server.getClusterId(), "memoryOvercommitRatio").getValue());
+
+            if (capacityVOCpus != null && !capacityVOCpus.isEmpty()) {
+                CapacityVO CapacityVOCpu = capacityVOCpus.get(0);
+                long newTotalCpu = (long)(server.getCpus().longValue() * server.getSpeed().longValue() * cpuovercommitratio);
+                if ((CapacityVOCpu.getTotalCapacity() <= newTotalCpu) || ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity()) <= newTotalCpu)) {
+                    CapacityVOCpu.setTotalCapacity(newTotalCpu);
+                } else if ((CapacityVOCpu.getUsedCapacity() + CapacityVOCpu.getReservedCapacity() > newTotalCpu) && (CapacityVOCpu.getUsedCapacity() < newTotalCpu)) {
+                    CapacityVOCpu.setReservedCapacity(0);
+                    CapacityVOCpu.setTotalCapacity(newTotalCpu);
+                } else {
+                    s_logger.debug("What? new cpu is :" + newTotalCpu + ", old one is " + CapacityVOCpu.getUsedCapacity() + "," + CapacityVOCpu.getReservedCapacity() +
+                        "," + CapacityVOCpu.getTotalCapacity());
+                }
+                _capacityDao.update(CapacityVOCpu.getId(), CapacityVOCpu);
+            } else {
+                CapacityVO capacity =
+                    new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getCpus().longValue() *
+                        server.getSpeed().longValue(), Capacity.CAPACITY_TYPE_CPU);
+                _capacityDao.persist(capacity);
+            }
+
+            SearchCriteria<CapacityVO> capacityMem = _capacityDao.createSearchCriteria();
+            capacityMem.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, server.getId());
+            capacityMem.addAnd("dataCenterId", SearchCriteria.Op.EQ, server.getDataCenterId());
+            capacityMem.addAnd("podId", SearchCriteria.Op.EQ, server.getPodId());
+            capacityMem.addAnd("capacityType", SearchCriteria.Op.EQ, Capacity.CAPACITY_TYPE_MEMORY);
+            List<CapacityVO> capacityVOMems = _capacityDao.search(capacityMem, null);
+
+            if (capacityVOMems != null && !capacityVOMems.isEmpty()) {
+                CapacityVO CapacityVOMem = capacityVOMems.get(0);
+                long newTotalMem = (long)((server.getTotalMemory()) * memoryOvercommitRatio);
+                if (CapacityVOMem.getTotalCapacity() <= newTotalMem || (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() <= newTotalMem)) {
+                    CapacityVOMem.setTotalCapacity(newTotalMem);
+                } else if (CapacityVOMem.getUsedCapacity() + CapacityVOMem.getReservedCapacity() > newTotalMem && CapacityVOMem.getUsedCapacity() < newTotalMem) {
+                    CapacityVOMem.setReservedCapacity(0);
+                    CapacityVOMem.setTotalCapacity(newTotalMem);
+                } else {
+                    s_logger.debug("What? new cpu is :" + newTotalMem + ", old one is " + CapacityVOMem.getUsedCapacity() + "," + CapacityVOMem.getReservedCapacity() +
+                        "," + CapacityVOMem.getTotalCapacity());
+                }
+                _capacityDao.update(CapacityVOMem.getId(), CapacityVOMem);
+            } else {
+                CapacityVO capacity =
+                    new CapacityVO(server.getId(), server.getDataCenterId(), server.getPodId(), server.getClusterId(), 0L, server.getTotalMemory(),
+                        Capacity.CAPACITY_TYPE_MEMORY);
+                _capacityDao.persist(capacity);
+            }
+        }
+
+    }
+
+    @Override
+    public float getClusterOverProvisioningFactor(Long clusterId, short capacityType) {
+
+        String capacityOverProvisioningName = "";
+        if (capacityType == Capacity.CAPACITY_TYPE_CPU) {
+            capacityOverProvisioningName = "cpuOvercommitRatio";
+        } else if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) {
+            capacityOverProvisioningName = "memoryOvercommitRatio";
+        } else {
+            throw new CloudRuntimeException("Invalid capacityType - " + capacityType);
+        }
+
+        ClusterDetailsVO clusterDetailCpu = _clusterDetailsDao.findDetail(clusterId, capacityOverProvisioningName);
+        Float clusterOverProvisioningRatio = Float.parseFloat(clusterDetailCpu.getValue());
+        return clusterOverProvisioningRatio;
+
+    }
+
+    @Override
+    public boolean checkIfClusterCrossesThreshold(Long clusterId, Integer cpuRequested, long ramRequested) {
+
+        Float clusterCpuOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_CPU);
+        Float clusterMemoryOverProvisioning = getClusterOverProvisioningFactor(clusterId, Capacity.CAPACITY_TYPE_MEMORY);
+        Float clusterCpuCapacityDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
+        Float clusterMemoryCapacityDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
+
+        float cpuConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_CPU, cpuRequested);
+        if (cpuConsumption / clusterCpuOverProvisioning > clusterCpuCapacityDisableThreshold) {
+            s_logger.debug("Cluster: " + clusterId + " cpu consumption " + cpuConsumption / clusterCpuOverProvisioning
+                + " crosses disable threshold " + clusterCpuCapacityDisableThreshold);
+            return true;
+        }
+
+        float memoryConsumption = _capacityDao.findClusterConsumption(clusterId, Capacity.CAPACITY_TYPE_MEMORY, ramRequested);
+        if (memoryConsumption / clusterMemoryOverProvisioning > clusterMemoryCapacityDisableThreshold) {
+            s_logger.debug("Cluster: " + clusterId + " memory consumption " + memoryConsumption / clusterMemoryOverProvisioning
+                + " crosses disable threshold " + clusterMemoryCapacityDisableThreshold);
+            return true;
+        }
+
+        return false;
+
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void processHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void processHostRemoved(long hostId, long clusterId) {
+    }
+
+    @Override
+    public boolean isRecurring() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void processCancelMaintenaceEventAfter(Long hostId) {
+        updateCapacityForHost(_hostDao.findById(hostId));
+    }
+
+    @Override
+    public void processCancelMaintenaceEventBefore(Long hostId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void processDeletHostEventAfter(Host host) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void processDeleteHostEventBefore(Host host) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void processDiscoverEventAfter(Map<? extends ServerResource, Map<String, String>> resources) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void processDiscoverEventBefore(Long dcid, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void processPrepareMaintenaceEventAfter(Long hostId) {
+        _capacityDao.removeBy(Capacity.CAPACITY_TYPE_MEMORY, null, null, null, hostId);
+        _capacityDao.removeBy(Capacity.CAPACITY_TYPE_CPU, null, null, null, hostId);
+    }
+
+    @Override
+    public void processPrepareMaintenaceEventBefore(Long hostId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean checkIfHostReachMaxGuestLimit(Host host) {
+        Long vmCount = _vmDao.countActiveByHostId(host.getId());
+        HypervisorType hypervisorType = host.getHypervisorType();
+        String hypervisorVersion = host.getHypervisorVersion();
+        Long maxGuestLimit = _hypervisorCapabilitiesDao.getMaxGuestsLimit(hypervisorType, hypervisorVersion);
+        if (vmCount.longValue() >= maxGuestLimit.longValue()) {
+            s_logger.info("Host name: " + host.getName() + ", hostId: " + host.getId() + " already reached max Running VMs(count includes system VMs), limit: " +
+                maxGuestLimit + ", Running VM count: " + vmCount.longValue());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return CapacityManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor,
+            StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull, ImageStoreNFSVersion};
+    }
+}
diff --git a/server/src/com/cloud/capacity/ComputeCapacityListener.java b/server/src/main/java/com/cloud/capacity/ComputeCapacityListener.java
similarity index 100%
rename from server/src/com/cloud/capacity/ComputeCapacityListener.java
rename to server/src/main/java/com/cloud/capacity/ComputeCapacityListener.java
diff --git a/server/src/com/cloud/capacity/StorageCapacityListener.java b/server/src/main/java/com/cloud/capacity/StorageCapacityListener.java
similarity index 100%
rename from server/src/com/cloud/capacity/StorageCapacityListener.java
rename to server/src/main/java/com/cloud/capacity/StorageCapacityListener.java
diff --git a/server/src/main/java/com/cloud/configuration/Config.java b/server/src/main/java/com/cloud/configuration/Config.java
new file mode 100644
index 0000000..87cf779
--- /dev/null
+++ b/server/src/main/java/com/cloud/configuration/Config.java
@@ -0,0 +1,2010 @@
+// 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.configuration;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.server.ManagementServer;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+
+/**
+ * @deprecated use the more dynamic ConfigKey
+ */
+@Deprecated
+public enum Config {
+
+    // Alert
+
+    AlertEmailAddresses(
+            "Alert",
+            ManagementServer.class,
+            String.class,
+            "alert.email.addresses",
+            null,
+            "Comma separated list of email addresses used for sending alerts.",
+            null),
+    AlertEmailSender("Alert", ManagementServer.class, String.class, "alert.email.sender", null, "Sender of alert email (will be in the From header of the email).", null),
+    AlertSMTPHost("Alert", ManagementServer.class, String.class, "alert.smtp.host", null, "SMTP hostname used for sending out email alerts.", null),
+    AlertSMTPPassword(
+            "Secure",
+            ManagementServer.class,
+            String.class,
+            "alert.smtp.password",
+            null,
+            "Password for SMTP authentication (applies only if alert.smtp.useAuth is true).",
+            null),
+    AlertSMTPPort("Alert", ManagementServer.class, Integer.class, "alert.smtp.port", "465", "Port the SMTP server is listening on.", null),
+    AlertSMTPConnectionTimeout("Alert", ManagementServer.class, Integer.class, "alert.smtp.connectiontimeout", "30000",
+            "Socket connection timeout value in milliseconds. -1 for infinite timeout.", null),
+    AlertSMTPTimeout(
+            "Alert",
+            ManagementServer.class,
+            Integer.class,
+            "alert.smtp.timeout",
+            "30000",
+            "Socket I/O timeout value in milliseconds. -1 for infinite timeout.",
+            null),
+    AlertSMTPUseAuth("Alert", ManagementServer.class, String.class, "alert.smtp.useAuth", null, "If true, use SMTP authentication when sending emails.", null),
+    AlertSMTPUsername(
+            "Alert",
+            ManagementServer.class,
+            String.class,
+            "alert.smtp.username",
+            null,
+            "Username for SMTP authentication (applies only if alert.smtp.useAuth is true).",
+            null),
+    CapacityCheckPeriod("Alert", ManagementServer.class, Integer.class, "capacity.check.period", "300000", "The interval in milliseconds between capacity checks", null),
+    PublicIpCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "zone.virtualnetwork.publicip.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of public IP address space utilization above which alerts will be sent.",
+            null),
+    PrivateIpCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "pod.privateip.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of private IP address space utilization above which alerts will be sent.",
+            null),
+    SecondaryStorageCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "zone.secstorage.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of secondary storage utilization above which alerts will be sent about low storage available.",
+            null),
+    VlanCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "zone.vlan.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of Zone Vlan utilization above which alerts will be sent about low number of Zone Vlans.",
+            null),
+    DirectNetworkPublicIpCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "zone.directnetwork.publicip.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of Direct Network Public Ip Utilization above which alerts will be sent about low number of direct network public ips.",
+            null),
+    LocalStorageCapacityThreshold(
+            "Alert",
+            ManagementServer.class,
+            Float.class,
+            "cluster.localStorage.capacity.notificationthreshold",
+            "0.75",
+            "Percentage (as a value between 0 and 1) of local storage utilization above which alerts will be sent about low local storage available.",
+            null),
+
+    // Storage
+
+    StorageStatsInterval(
+            "Storage",
+            ManagementServer.class,
+            String.class,
+            "storage.stats.interval",
+            "60000",
+            "The interval (in milliseconds) when storage stats (per host) are retrieved from agents.",
+            null),
+    MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null),
+    StorageCacheReplacementLRUTimeInterval(
+            "Storage",
+            ManagementServer.class,
+            Integer.class,
+            "storage.cache.replacement.lru.interval",
+            "30",
+            "time interval for unused data on cache storage (in days).",
+            null),
+    StorageCacheReplacementEnabled(
+            "Storage",
+            ManagementServer.class,
+            Boolean.class,
+            "storage.cache.replacement.enabled",
+            "true",
+            "enable or disable cache storage replacement algorithm.",
+            null),
+    StorageCacheReplacementInterval(
+            "Storage",
+            ManagementServer.class,
+            Integer.class,
+            "storage.cache.replacement.interval",
+            "86400",
+            "time interval between cache replacement threads (in seconds).",
+            null),
+    MaxUploadVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.upload.size", "500", "The maximum size for a uploaded volume(in GB).", null),
+    TotalRetries(
+            "Storage",
+            AgentManager.class,
+            Integer.class,
+            "total.retries",
+            "4",
+            "The number of times each command sent to a host should be retried in case of failure.",
+            null),
+    StoragePoolMaxWaitSeconds(
+            "Storage",
+            ManagementServer.class,
+            Integer.class,
+            "storage.pool.max.waitseconds",
+            "3600",
+            "Timeout (in seconds) to synchronize storage pool operations.",
+            null),
+    CreateVolumeFromSnapshotWait(
+            "Storage",
+            StorageManager.class,
+            Integer.class,
+            "create.volume.from.snapshot.wait",
+            "10800",
+            "In second, timeout for creating volume from snapshot",
+            null),
+    CopyVolumeWait("Storage", StorageManager.class, Integer.class, "copy.volume.wait", "10800", "In second, timeout for copy volume command", null),
+    CreatePrivateTemplateFromVolumeWait(
+            "Storage",
+            UserVmManager.class,
+            Integer.class,
+            "create.private.template.from.volume.wait",
+            "10800",
+            "In second, timeout for CreatePrivateTemplateFromVolumeCommand",
+            null),
+    CreatePrivateTemplateFromSnapshotWait(
+            "Storage",
+            UserVmManager.class,
+            Integer.class,
+            "create.private.template.from.snapshot.wait",
+            "10800",
+            "In second, timeout for CreatePrivateTemplateFromSnapshotCommand",
+            null),
+    BackupSnapshotWait("Storage", StorageManager.class, Integer.class, "backup.snapshot.wait", "21600", "In second, timeout for BackupSnapshotCommand", null),
+    HAStorageMigration(
+            "Storage",
+            ManagementServer.class,
+            Boolean.class,
+            "enable.ha.storage.migration",
+            "true",
+            "Enable/disable storage migration across primary storage during HA",
+            null),
+
+    // Network
+    NetworkLBHaproxyStatsVisbility(
+            "Network",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.haproxy.stats.visibility",
+            "global",
+            "Load Balancer(haproxy) stats visibilty, the value can be one of the following six parameters : global,guest-network,link-local,disabled,all,default",
+            null),
+    NetworkLBHaproxyStatsUri(
+            "Network",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.haproxy.stats.uri",
+            "/admin?stats",
+            "Load Balancer(haproxy) uri.",
+            null),
+    NetworkLBHaproxyStatsAuth(
+            "Secure",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.haproxy.stats.auth",
+            "admin1:AdMiN123",
+            "Load Balancer(haproxy) authetication string in the format username:password",
+            null),
+    NetworkLBHaproxyStatsPort(
+            "Network",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.haproxy.stats.port",
+            "8081",
+            "Load Balancer(haproxy) stats port number.",
+            null),
+    NetworkLBHaproxyMaxConn(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.loadbalancer.haproxy.max.conn",
+            "4096",
+            "Load Balancer(haproxy) maximum number of concurrent connections(global max)",
+            null),
+    NetworkRouterRpFilter(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.disable.rpfilter",
+            "true",
+            "disable rp_filter on Domain Router VM public interfaces.",
+            null),
+
+    GuestVlanBits(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "guest.vlan.bits",
+            "12",
+            "The number of bits to reserve for the VLAN identifier in the guest subnet.",
+            null),
+    //MulticastThrottlingRate("Network", ManagementServer.class, Integer.class, "multicast.throttling.rate", "10", "Default multicast rate in megabits per second allowed.", null),
+    DirectNetworkNoDefaultRoute(
+            "Network",
+            ManagementServer.class,
+            Boolean.class,
+            "direct.network.no.default.route",
+            "false",
+            "Direct Network Dhcp Server should not send a default route",
+            "true/false"),
+    OvsTunnelNetworkDefaultLabel(
+            "Network",
+            ManagementServer.class,
+            String.class,
+            "sdn.ovs.controller.default.label",
+            "cloud-public",
+            "Default network label to be used when fetching interface for GRE endpoints",
+            null),
+    VmNetworkThrottlingRate(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "vm.network.throttling.rate",
+            "200",
+            "Default data transfer rate in megabits per second allowed in User vm's default network.",
+            null),
+
+    SecurityGroupWorkCleanupInterval(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.securitygroups.work.cleanup.interval",
+            "120",
+            "Time interval (seconds) in which finished work is cleaned up from the work table",
+            null),
+    SecurityGroupWorkerThreads(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.securitygroups.workers.pool.size",
+            "50",
+            "Number of worker threads processing the security group update work queue",
+            null),
+    SecurityGroupWorkGlobalLockTimeout(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.securitygroups.work.lock.timeout",
+            "300",
+            "Lock wait timeout (seconds) while updating the security group work queue",
+            null),
+    SecurityGroupWorkPerAgentMaxQueueSize(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.securitygroups.work.per.agent.queue.size",
+            "100",
+            "The number of outstanding security group work items that can be queued to a host. If exceeded, work items will get dropped to conserve memory. Security Group Sync will take care of ensuring that the host gets updated eventually",
+            null),
+
+    SecurityGroupDefaultAdding(
+            "Network",
+            ManagementServer.class,
+            Boolean.class,
+            "network.securitygroups.defaultadding",
+            "true",
+            "If true, the user VM would be added to the default security group by default",
+            null),
+
+    GuestOSNeedGatewayOnNonDefaultNetwork(
+            "Network",
+            NetworkOrchestrationService.class,
+            String.class,
+            "network.dhcp.nondefaultnetwork.setgateway.guestos",
+            "Windows",
+            "The guest OS's name start with this fields would result in DHCP server response gateway information even when the network it's on is not default network. Names are separated by comma.",
+            null),
+
+    //VPN
+    RemoteAccessVpnPskLength(
+            "Network",
+            AgentManager.class,
+            Integer.class,
+            "remote.access.vpn.psk.length",
+            "24",
+            "The length of the ipsec preshared key (minimum 8, maximum 256)",
+            null),
+    RemoteAccessVpnUserLimit(
+            "Network",
+            AgentManager.class,
+            String.class,
+            "remote.access.vpn.user.limit",
+            "8",
+            "The maximum number of VPN users that can be created per account",
+            null),
+    Site2SiteVpnConnectionPerVpnGatewayLimit(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "site2site.vpn.vpngateway.connection.limit",
+            "4",
+            "The maximum number of VPN connection per VPN gateway",
+            null),
+    Site2SiteVpnSubnetsPerCustomerGatewayLimit(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "site2site.vpn.customergateway.subnets.limit",
+            "10",
+            "The maximum number of subnets per customer gateway",
+            null),
+    MaxNumberOfSecondaryIPsPerNIC(
+            "Network", ManagementServer.class, Integer.class,
+            "vm.network.nic.max.secondary.ipaddresses", "256",
+            "Specify the number of secondary ip addresses per nic per vm. Default value 10 is used, if not specified.", null),
+
+    EnableServiceMonitoring(
+            "Network", ManagementServer.class, Boolean.class,
+            "network.router.enableserviceMonitoring", "false",
+            "service monitoring in router enable/disable option, default false", null),
+
+
+    // Console Proxy
+    ConsoleProxyCapacityStandby(
+            "Console Proxy",
+            AgentManager.class,
+            String.class,
+            "consoleproxy.capacity.standby",
+            "10",
+            "The minimal number of console proxy viewer sessions that system is able to serve immediately(standby capacity)",
+            null),
+    ConsoleProxyCapacityScanInterval(
+            "Console Proxy",
+            AgentManager.class,
+            String.class,
+            "consoleproxy.capacityscan.interval",
+            "30000",
+            "The time interval(in millisecond) to scan whether or not system needs more console proxy to ensure minimal standby capacity",
+            null),
+    ConsoleProxyCmdPort(
+            "Console Proxy",
+            AgentManager.class,
+            Integer.class,
+            "consoleproxy.cmd.port",
+            "8001",
+            "Console proxy command port that is used to communicate with management server",
+            null),
+    ConsoleProxyRestart("Console Proxy", AgentManager.class, Boolean.class, "consoleproxy.restart", "true", "Console proxy restart flag, defaulted to true", null),
+    ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "", "Console proxy url domain", "domainName"),
+    ConsoleProxySessionMax(
+            "Console Proxy",
+            AgentManager.class,
+            Integer.class,
+            "consoleproxy.session.max",
+            String.valueOf(ConsoleProxyManager.DEFAULT_PROXY_CAPACITY),
+            "The max number of viewer sessions console proxy is configured to serve for",
+            null),
+    ConsoleProxySessionTimeout(
+            "Console Proxy",
+            AgentManager.class,
+            Integer.class,
+            "consoleproxy.session.timeout",
+            "300000",
+            "Timeout(in milliseconds) that console proxy tries to maintain a viewer session before it times out the session for no activity",
+            null),
+    ConsoleProxyDisableRpFilter(
+            "Console Proxy",
+            AgentManager.class,
+            Integer.class,
+            "consoleproxy.disable.rpfilter",
+            "true",
+            "disable rp_filter on console proxy VM public interface",
+            null),
+    ConsoleProxyLaunchMax(
+            "Console Proxy",
+            AgentManager.class,
+            Integer.class,
+            "consoleproxy.launch.max",
+            "10",
+            "maximum number of console proxy instances per zone can be launched",
+            null),
+    ConsoleProxyManagementState(
+            "Console Proxy",
+            AgentManager.class,
+            String.class,
+            "consoleproxy.management.state",
+            com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
+            "console proxy service management state",
+            null),
+    ConsoleProxyManagementLastState(
+            "Console Proxy",
+            AgentManager.class,
+            String.class,
+            "consoleproxy.management.state.last",
+            com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
+            "last console proxy service management state",
+            null),
+
+    // Snapshots
+
+    SnapshotPollInterval(
+            "Snapshots",
+            SnapshotManager.class,
+            Integer.class,
+            "snapshot.poll.interval",
+            "300",
+            "The time interval in seconds when the management server polls for snapshots to be scheduled.",
+            null),
+    SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
+    KVMSnapshotEnabled("Hidden", SnapshotManager.class, Boolean.class, "kvm.snapshot.enabled", "false", "whether snapshot is enabled for KVM hosts", null),
+
+    // Advanced
+    EventPurgeInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "event.purge.interval",
+            "86400",
+            "The interval (in seconds) to wait before running the event purge thread",
+            null),
+    AccountCleanupInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "account.cleanup.interval",
+            "86400",
+            "The interval (in seconds) between cleanup for removed accounts",
+            null),
+    InstanceName("Advanced", AgentManager.class, String.class, "instance.name", "VM", "Name of the deployment instance.", "instanceName"),
+    ExpungeDelay(
+            "Advanced",
+            UserVmManager.class,
+            Integer.class,
+            "expunge.delay",
+            "86400",
+            "Determines how long (in seconds) to wait before actually expunging destroyed vm. The default value = the default value of expunge.interval",
+            null),
+    ExpungeInterval(
+            "Advanced",
+            UserVmManager.class,
+            Integer.class,
+            "expunge.interval",
+            "86400",
+            "The interval (in seconds) to wait before running the expunge thread.",
+            null),
+    ExpungeWorkers("Advanced", UserVmManager.class, Integer.class, "expunge.workers", "1", "Number of workers performing expunge ", null),
+    ExtractURLCleanUpInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "extract.url.cleanup.interval",
+            "7200",
+            "The interval (in seconds) to wait before cleaning up the extract URL's ",
+            null),
+    DisableExtraction(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "disable.extraction",
+            "false",
+            "Flag for disabling extraction of template, isos and volumes",
+            null),
+    ExtractURLExpirationInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "extract.url.expiration.interval",
+            "14400",
+            "The life of an extract URL after which it is deleted ",
+            null),
+    HostStatsInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "host.stats.interval",
+            "60000",
+            "The interval (in milliseconds) when host stats are retrieved from agents.",
+            null),
+    HostRetry("Advanced", AgentManager.class, Integer.class, "host.retry", "2", "Number of times to retry hosts for creating a volume", null),
+    InvestigateRetryInterval(
+            "Advanced",
+            HighAvailabilityManager.class,
+            Integer.class,
+            "investigate.retry.interval",
+            "60",
+            "Time (in seconds) between VM pings when agent is disconnected",
+            null),
+    MigrateRetryInterval("Advanced", HighAvailabilityManager.class, Integer.class, "migrate.retry.interval", "120", "Time (in seconds) between migration retries", null),
+    RouterCpuMHz(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.cpu.mhz",
+            String.valueOf(VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ),
+            "Default CPU speed (MHz) for router VM.",
+            null),
+    RestartRetryInterval(
+            "Advanced",
+            HighAvailabilityManager.class,
+            Integer.class,
+            "restart.retry.interval",
+            "600",
+            "Time (in seconds) between retries to restart a vm",
+            null),
+    RouterStatsInterval(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.stats.interval",
+            "300",
+            "Interval (in seconds) to report router statistics.",
+            null),
+    ExternalNetworkStatsInterval(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "external.network.stats.interval",
+            "300",
+            "Interval (in seconds) to report external network statistics.",
+            null),
+    RouterCheckInterval(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.check.interval",
+            "30",
+            "Interval (in seconds) to report redundant router status.",
+            null),
+    RouterCheckPoolSize(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.check.poolsize",
+            "10",
+            "Numbers of threads using to check redundant router status.",
+            null),
+    RouterExtraPublicNics(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.extra.public.nics",
+            "2",
+            "specify extra public nics used for virtual router(up to 5)",
+            "0-5"),
+    ScaleRetry("Advanced", ManagementServer.class, Integer.class, "scale.retry", "2", "Number of times to retry scaling up the vm", null),
+    StopRetryInterval(
+            "Advanced",
+            HighAvailabilityManager.class,
+            Integer.class,
+            "stop.retry.interval",
+            "600",
+            "Time in seconds between retries to stop or destroy a vm",
+            null),
+    UpdateWait("Advanced", AgentManager.class, Integer.class, "update.wait", "600", "Time to wait (in seconds) before alerting on a updating agent", null),
+    XapiWait("Advanced", AgentManager.class, Integer.class, "xapiwait", "60", "Time (in seconds) to wait for XAPI to return", null),
+    MigrateWait("Advanced", AgentManager.class, Integer.class, "migratewait", "3600", "Time (in seconds) to wait for VM migrate finish", null),
+    HAWorkers("Advanced", AgentManager.class, Integer.class, "ha.workers", "5", "Number of ha worker threads.", null),
+    MountParent(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "mount.parent",
+            "/var/cloudstack/mnt",
+            "The mount point on the Management Server for Secondary Storage.",
+            null),
+    SystemVMAutoReserveCapacity(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "system.vm.auto.reserve.capacity",
+            "true",
+            "Indicates whether or not to automatically reserver system VM standby capacity.",
+            null),
+    SystemVMDefaultHypervisor("Advanced",
+            ManagementServer.class,
+            String.class,
+            "system.vm.default.hypervisor",
+            null,
+            "Hypervisor type used to create system vm, valid values are: XenServer, KVM, VMware, Hyperv, VirtualBox, Parralels, BareMetal, Ovm, LXC, Any",
+            null),
+    SystemVMRandomPassword(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "system.vm.random.password",
+            "false",
+            "Randomize system vm password the first time management server starts",
+            null),
+    LinkLocalIpNums("Advanced", ManagementServer.class, Integer.class, "linkLocalIp.nums", "10", "The number of link local ip that needed by domR(in power of 2)", null),
+    HypervisorList(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "hypervisor.list",
+            HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," +
+                    HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
+                    "The list of hypervisors that this deployment will use.",
+            "hypervisorList"),
+    ManagementNetwork("Advanced", ManagementServer.class, String.class, "management.network.cidr", null, "The cidr of management server network", null),
+    EventPurgeDelay(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "event.purge.delay",
+            "15",
+            "Events older than specified number days will be purged. Set this value to 0 to never delete events",
+            null),
+    SecStorageVmMTUSize(
+            "Advanced",
+            AgentManager.class,
+            Integer.class,
+            "secstorage.vm.mtu.size",
+            String.valueOf(SecondaryStorageVmManager.DEFAULT_SS_VM_MTUSIZE),
+            "MTU size (in Byte) of storage network in secondary storage vms",
+            null),
+    MaxTemplateAndIsoSize(
+            "Advanced",
+            ManagementServer.class,
+            Long.class,
+            "max.template.iso.size",
+            "50",
+            "The maximum size for a downloaded template or ISO (in GB).",
+            null),
+    SecStorageAllowedInternalDownloadSites(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "secstorage.allowed.internal.sites",
+            null,
+            "Comma separated list of cidrs internal to the datacenter that can host template download servers, please note 0.0.0.0 is not a valid site",
+            null),
+    SecStorageEncryptCopy(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "secstorage.encrypt.copy",
+            "false",
+            "Use SSL method used to encrypt copy traffic between zones",
+            "true,false"),
+    SecStorageSecureCopyCert(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "secstorage.ssl.cert.domain",
+            "",
+            "SSL certificate used to encrypt copy traffic between zones",
+            "domainName"),
+    SecStorageCapacityStandby(
+            "Advanced",
+            AgentManager.class,
+            Integer.class,
+            "secstorage.capacity.standby",
+            "10",
+            "The minimal number of command execution sessions that system is able to serve immediately(standby capacity)",
+            null),
+    SecStorageSessionMax(
+            "Advanced",
+            AgentManager.class,
+            Integer.class,
+            "secstorage.session.max",
+            "50",
+            "The max number of command execution sessions that a SSVM can handle",
+            null),
+    SecStorageCmdExecutionTimeMax(
+            "Advanced",
+            AgentManager.class,
+            Integer.class,
+            "secstorage.cmd.execution.time.max",
+            "30",
+            "The max command execution time in minute",
+            null),
+    SecStorageProxy(
+            "Advanced",
+            AgentManager.class,
+            String.class,
+            "secstorage.proxy",
+            null,
+            "http proxy used by ssvm, in http://username:password@proxyserver:port format",
+            null),
+    AlertPurgeInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "alert.purge.interval",
+            "86400",
+            "The interval (in seconds) to wait before running the alert purge thread",
+            null),
+    AlertPurgeDelay(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "alert.purge.delay",
+            "0",
+            "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts",
+            null),
+    HostReservationReleasePeriod(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "host.reservation.release.period",
+            "300000",
+            "The interval in milliseconds between host reservation release checks",
+            null),
+    // LB HealthCheck Interval.
+    LBHealthCheck(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "healthcheck.update.interval",
+            "600",
+            "Time Interval to fetch the LB health check states (in sec)",
+            null),
+    NCCCmdTimeOut(
+            "Advanced",
+            ManagementServer.class,
+            Long.class,
+            "ncc.command.timeout",
+            "600000", // 10 minutes
+            "Command Timeout Interval (in millisec)",
+            null),
+    DirectAttachNetworkEnabled(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "direct.attach.network.externalIpAllocator.enabled",
+            "false",
+            "Direct-attach VMs using external DHCP server",
+            "true,false"),
+    DirectAttachNetworkExternalAPIURL(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "direct.attach.network.externalIpAllocator.url",
+            null,
+            "Direct-attach VMs using external DHCP server (API url)",
+            null),
+    CheckPodCIDRs(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "check.pod.cidrs",
+            "true",
+            "If true, different pods must belong to different CIDR subnets.",
+            "true,false"),
+    NetworkGcWait(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "network.gc.wait",
+            "600",
+            "Time (in seconds) to wait before shutting down a network that's not in used",
+            null),
+    NetworkGcInterval("Advanced", ManagementServer.class, Integer.class, "network.gc.interval", "600", "Seconds to wait before checking for networks to shutdown", null),
+    CapacitySkipcountingHours(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "capacity.skipcounting.hours",
+            "3600",
+            "Time (in seconds) to wait before release VM's cpu and memory when VM in stopped state",
+            null),
+    VmStatsInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.stats.interval",
+            "60000",
+            "The interval (in milliseconds) when vm stats are retrieved from agents.",
+            null),
+    VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null),
+    VolumeStatsInterval("Advanced", ManagementServer.class, Integer.class, "volume.stats.interval", "60000", "Interval (in seconds) to report volume statistics.", null),
+    VmTransitionWaitInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.tranisition.wait.interval",
+            "3600",
+            "Time (in seconds) to wait before taking over a VM in transition state",
+            null),
+    VmDiskThrottlingIopsReadRate(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.disk.throttling.iops_read_rate",
+            "0",
+            "Default disk I/O read rate in requests per second allowed in User vm's disk.",
+            null),
+    VmDiskThrottlingIopsWriteRate(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.disk.throttling.iops_write_rate",
+            "0",
+            "Default disk I/O writerate in requests per second allowed in User vm's disk.",
+            null),
+    VmDiskThrottlingBytesReadRate(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.disk.throttling.bytes_read_rate",
+            "0",
+            "Default disk I/O read rate in bytes per second allowed in User vm's disk.",
+            null),
+    VmDiskThrottlingBytesWriteRate(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vm.disk.throttling.bytes_write_rate",
+            "0",
+            "Default disk I/O writerate in bytes per second allowed in User vm's disk.",
+            null),
+    KvmAutoConvergence(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "kvm.auto.convergence",
+            "false",
+            "Setting this to 'true' allows KVM to use auto convergence to complete VM migration (libvirt version 1.2.3+ and QEMU version 1.6+)",
+            null),
+    ControlCidr(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "control.cidr",
+            "169.254.0.0/16",
+            "Changes the cidr for the control network traffic.  Defaults to using link local.  Must be unique within pods",
+            null),
+    ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null),
+    HostCapacityTypeToOrderClusters(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "host.capacityType.to.order.clusters",
+            "CPU",
+            "The host capacity type (CPU or RAM) is used by deployment planner to order clusters during VM resource allocation",
+            "CPU,RAM"),
+    ApplyAllocationAlgorithmToPods(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "apply.allocation.algorithm.to.pods",
+            "false",
+            "If true, deployment planner applies the allocation heuristics at pods first in the given datacenter during VM resource allocation",
+            "true,false"),
+    VmUserDispersionWeight(
+            "Advanced",
+            ManagementServer.class,
+            Float.class,
+            "vm.user.dispersion.weight",
+            "1",
+            "Weight for user dispersion heuristic (as a value between 0 and 1) applied to resource allocation during vm deployment. Weight for capacity heuristic will be (1 - weight of user dispersion)",
+            null),
+    VmAllocationAlgorithm(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vm.allocation.algorithm",
+            "random",
+            "'random', 'firstfit', 'userdispersing', 'userconcentratedpod_random', 'userconcentratedpod_firstfit', 'firstfitleastconsumed' : Order in which hosts within a cluster will be considered for VM/volume allocation.",
+            null),
+    VmDeploymentPlanner(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vm.deployment.planner",
+            "FirstFitPlanner",
+            "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.",
+            null),
+    ElasticLoadBalancerEnabled(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.basiczone.elb.enabled",
+            "false",
+            "Whether the load balancing service is enabled for basic zones",
+            "true,false"),
+    ElasticLoadBalancerNetwork(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "network.loadbalancer.basiczone.elb.network",
+            "guest",
+            "Whether the elastic load balancing service public ips are taken from the public or guest network",
+            "guest,public"),
+    ElasticLoadBalancerVmMemory(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "network.loadbalancer.basiczone.elb.vm.ram.size",
+            "128",
+            "Memory in MB for the elastic load balancer vm",
+            null),
+    ElasticLoadBalancerVmCpuMhz(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "network.loadbalancer.basiczone.elb.vm.cpu.mhz",
+            "128",
+            "CPU speed for the elastic load balancer vm",
+            null),
+    ElasticLoadBalancerVmNumVcpu(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "network.loadbalancer.basiczone.elb.vm.vcpu.num",
+            "1",
+            "Number of VCPU  for the elastic load balancer vm",
+            null),
+    ElasticLoadBalancerVmGcInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "network.loadbalancer.basiczone.elb.gc.interval.minutes",
+            "30",
+            "Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5",
+            null),
+    SortKeyAlgorithm(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "sortkey.algorithm",
+            "false",
+            "Sort algorithm for those who use sort key(template, disk offering, service offering, network offering), true means ascending sort while false means descending sort",
+            null),
+    EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false", "enable EC2 API on CloudStack", null),
+    EnableS3API("Advanced", ManagementServer.class, Boolean.class, "enable.s3.api", "false", "enable Amazon S3 API on CloudStack", null),
+    RecreateSystemVmEnabled(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "recreate.systemvm.enabled",
+            "false",
+            "If true, will recreate system vm root disk whenever starting system vm",
+            "true,false"),
+    SetVmInternalNameUsingDisplayName(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "vm.instancename.flag",
+            "false",
+            "If set to true, will set guest VM's name as it appears on the hypervisor, to its hostname. The flag is supported for VMware hypervisor only",
+            "true,false"),
+    IncorrectLoginAttemptsAllowed(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "incorrect.login.attempts.allowed",
+            "5",
+            "Incorrect login attempts allowed before the user is disabled",
+            null),
+    // Ovm
+    OvmPublicNetwork("Hidden", ManagementServer.class, String.class, "ovm.public.network.device", null, "Specify the public bridge on host for public network", null),
+    OvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm.private.network.device", null, "Specify the private bridge on host for private network", null),
+    OvmGuestNetwork("Hidden", ManagementServer.class, String.class, "ovm.guest.network.device", null, "Specify the private bridge on host for private network", null),
+
+    // Ovm3
+    Ovm3PublicNetwork("Hidden", ManagementServer.class, String.class, "ovm3.public.network.device", null, "Specify the public bridge on host for public network", null),
+    Ovm3PrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm3.private.network.device", null, "Specify the private bridge on host for private network", null),
+    Ovm3GuestNetwork("Hidden", ManagementServer.class, String.class, "ovm3.guest.network.device", null, "Specify the guest bridge on host for guest network", null),
+    Ovm3StorageNetwork("Hidden", ManagementServer.class, String.class, "ovm3.storage.network.device", null, "Specify the storage bridge on host for storage network", null),
+    Ovm3HeartBeatTimeout(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.timeout",
+            "120",
+            "timeout used for primary storage check, upon timeout a panic is triggered.",
+            null),
+    Ovm3HeartBeatInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.interval",
+            "1",
+            "interval used to check primary storage availability.",
+            null),
+
+
+    // XenServer
+    XenServerPublicNetwork(
+            "Hidden",
+            ManagementServer.class,
+            String.class,
+            "xenserver.public.network.device",
+            null,
+            "[ONLY IF THE PUBLIC NETWORK IS ON A DEDICATED NIC]:The network name label of the physical device dedicated to the public network on a XenServer host",
+            null),
+    XenServerStorageNetwork1("Hidden", ManagementServer.class, String.class, "xenserver.storage.network.device1", null, "Specify when there are storage networks", null),
+    XenServerStorageNetwork2("Hidden", ManagementServer.class, String.class, "xenserver.storage.network.device2", null, "Specify when there are storage networks", null),
+    XenServerPrivateNetwork("Hidden", ManagementServer.class, String.class, "xenserver.private.network.device", null, "Specify when the private network name is different", null),
+    NetworkGuestCidrLimit(
+            "Network",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "network.guest.cidr.limit",
+            "22",
+            "size limit for guest cidr; can't be less than this value",
+            null),
+    XenServerSetupMultipath("Advanced", ManagementServer.class, String.class, "xenserver.setup.multipath", "false", "Setup the host to do multipath", null),
+    XenServerBondStorageNic("Advanced", ManagementServer.class, String.class, "xenserver.bond.storage.nics", null, "Attempt to bond the two networks if found", null),
+    XenServerHeartBeatTimeout(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "xenserver.heartbeat.timeout",
+            "120",
+            "heartbeat timeout to use when implementing XenServer Self Fencing",
+            null),
+    XenServerHeartBeatInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "xenserver.heartbeat.interval",
+            "60",
+            "heartbeat interval to use when checking before XenServer Self Fencing",
+            null),
+    XenServerGuestNetwork("Hidden", ManagementServer.class, String.class, "xenserver.guest.network.device", null, "Specify for guest network name label", null),
+    XenServerMaxNics("Advanced", AgentManager.class, Integer.class, "xenserver.nics.max", "7", "Maximum allowed nics for Vms created on XenServer", null),
+    XenServerPVdriverVersion(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "xenserver.pvdriver.version",
+            "xenserver61",
+            "default Xen PV driver version for registered template, valid value:xenserver56,xenserver61 ",
+            "xenserver56,xenserver61"),
+    XenServerHotFix("Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "xenserver.hotfix.enabled",
+            "false",
+            "Enable/Disable XenServer hot fix",
+            null),
+
+    // VMware
+    VmwareUseNexusVSwitch(
+            "Network",
+            ManagementServer.class,
+            Boolean.class,
+            "vmware.use.nexus.vswitch",
+            "false",
+            "Enable/Disable Cisco Nexus 1000v vSwitch in VMware environment",
+            null),
+    VmwareUseDVSwitch(
+            "Network",
+            ManagementServer.class,
+            Boolean.class,
+            "vmware.use.dvswitch",
+            "false",
+            "Enable/Disable Nexus/Vmware dvSwitch in VMware environment",
+            null),
+    VmwareCreateFullClone(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "vmware.create.full.clone",
+            "true",
+            "If set to true, creates guest VMs as full clones on ESX",
+            null),
+    VmwareServiceConsole(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vmware.service.console",
+            "Service Console",
+            "Specify the service console network name(for ESX hosts)",
+            null),
+    VmwareManagementPortGroup(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vmware.management.portgroup",
+            "Management Network",
+            "Specify the management network name(for ESXi hosts)",
+            null),
+    VmwareAdditionalVncPortRangeStart(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vmware.additional.vnc.portrange.start",
+            "50000",
+            "Start port number of additional VNC port range",
+            null),
+    VmwareAdditionalVncPortRangeSize(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vmware.additional.vnc.portrange.size",
+            "1000",
+            "Start port number of additional VNC port range",
+            null),
+    //VmwareGuestNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.guest.nic.device.type", "E1000", "Ethernet card type used in guest VM, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null),
+    VmwareRootDiskControllerType(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vmware.root.disk.controller",
+            "ide",
+            "Specify the default disk controller for root volumes, valid values are scsi, ide, osdefault. Please check documentation for more details on each of these values.",
+            null),
+    VmwareSystemVmNicDeviceType(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "vmware.systemvm.nic.device.type",
+            "E1000",
+            "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3",
+            null),
+    VmwareRecycleHungWorker(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "vmware.recycle.hung.wokervm",
+            "false",
+            "Specify whether or not to recycle hung worker VMs",
+            null),
+    VmwareHungWorkerTimeout("Advanced", ManagementServer.class, Long.class, "vmware.hung.wokervm.timeout", "7200", "Worker VM timeout in seconds", null),
+    VmwareVcenterSessionTimeout("Advanced", ManagementServer.class, Long.class, "vmware.vcenter.session.timeout", "1200", "VMware client timeout in seconds", null),
+
+    // KVM
+    KvmPublicNetwork("Hidden", ManagementServer.class, String.class, "kvm.public.network.device", null, "Specify the public bridge on host for public network", null),
+    KvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "kvm.private.network.device", null, "Specify the private bridge on host for private network", null),
+    KvmGuestNetwork("Hidden", ManagementServer.class, String.class, "kvm.guest.network.device", null, "Specify the private bridge on host for private network", null),
+
+    // Hyperv
+    HypervPublicNetwork(
+            "Hidden",
+            ManagementServer.class,
+            String.class,
+            "hyperv.public.network.device",
+            null,
+            "Specify the public virtual switch on host for public network",
+            null),
+    HypervPrivateNetwork(
+            "Hidden",
+            ManagementServer.class,
+            String.class,
+            "hyperv.private.network.device",
+            null,
+            "Specify the virtual switch on host for private network",
+            null),
+    HypervGuestNetwork(
+            "Hidden",
+            ManagementServer.class,
+            String.class,
+            "hyperv.guest.network.device",
+            null,
+            "Specify the virtual switch on host for private network",
+            null),
+
+    // Usage
+    UsageExecutionTimezone("Usage", ManagementServer.class, String.class, "usage.execution.timezone", null, "The timezone to use for usage job execution time", null),
+    UsageStatsJobAggregationRange(
+            "Usage",
+            ManagementServer.class,
+            Integer.class,
+            "usage.stats.job.aggregation.range",
+            "1440",
+            "The range of time for aggregating the user statistics specified in minutes (e.g. 1440 for daily, 60 for hourly.",
+            null),
+    UsageStatsJobExecTime(
+            "Usage",
+            ManagementServer.class,
+            String.class,
+            "usage.stats.job.exec.time",
+            "00:15",
+            "The time at which the usage statistics aggregation job will run as an HH24:MM time, e.g. 00:30 to run at 12:30am.",
+            null),
+    EnableUsageServer("Usage", ManagementServer.class, Boolean.class, "enable.usage.server", "true", "Flag for enabling usage", null),
+    DirectNetworkStatsInterval(
+            "Usage",
+            ManagementServer.class,
+            Integer.class,
+            "direct.network.stats.interval",
+            "86400",
+            "Interval (in seconds) to collect stats from Traffic Monitor",
+            null),
+    UsageSanityCheckInterval(
+            "Usage",
+            ManagementServer.class,
+            Integer.class,
+            "usage.sanity.check.interval",
+            null,
+            "Interval (in days) to check sanity of usage data. To disable set it to 0 or negative.",
+            null),
+    UsageAggregationTimezone("Usage", ManagementServer.class, String.class, "usage.aggregation.timezone", "GMT", "The timezone to use for usage stats aggregation", null),
+    TrafficSentinelIncludeZones(
+            "Usage",
+            ManagementServer.class,
+            Integer.class,
+            "traffic.sentinel.include.zones",
+            "EXTERNAL",
+            "Traffic going into specified list of zones is metered. For metering all traffic leave this parameter empty",
+            null),
+    TrafficSentinelExcludeZones(
+            "Usage",
+            ManagementServer.class,
+            Integer.class,
+            "traffic.sentinel.exclude.zones",
+            "",
+            "Traffic going into specified list of zones is not metered.",
+            null),
+
+    // Hidden
+    UseSecondaryStorageVm(
+            "Hidden",
+            ManagementServer.class,
+            Boolean.class,
+            "secondary.storage.vm",
+            "false",
+            "Deploys a VM per zone to manage secondary storage if true, otherwise secondary storage is mounted on management server",
+            null),
+    CreatePoolsInPod(
+            "Hidden",
+            ManagementServer.class,
+            Boolean.class,
+            "xenserver.create.pools.in.pod",
+            "false",
+            "Should we automatically add XenServers into pools that are inside a Pod",
+            null),
+    CloudIdentifier("Hidden", ManagementServer.class, String.class, "cloud.identifier", null, "A unique identifier for the cloud.", null),
+    SSOKey("Secure", ManagementServer.class, String.class, "security.singlesignon.key", null, "A Single Sign-On key used for logging into the cloud", null),
+    SSOAuthTolerance(
+            "Advanced",
+            ManagementServer.class,
+            Long.class,
+            "security.singlesignon.tolerance.millis",
+            "300000",
+            "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.",
+            null),
+    //NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"),
+    RouterRamSize("Hidden", NetworkOrchestrationService.class, Integer.class, "router.ram.size", "256", "Default RAM for router VM (in MB).", null),
+
+    DefaultPageSize("Advanced", ManagementServer.class, Long.class, "default.page.size", "500", "Default page size for API list* commands", null),
+
+    TaskCleanupRetryInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "task.cleanup.retry.interval",
+            "600",
+            "Time (in seconds) to wait before retrying cleanup of tasks if the cleanup failed previously.  0 means to never retry.",
+            "Seconds"),
+
+    // Account Default Limits
+    DefaultMaxAccountUserVms(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.user.vms",
+            "20",
+            "The default maximum number of user VMs that can be deployed for an account",
+            null),
+    DefaultMaxAccountPublicIPs(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.public.ips",
+            "20",
+            "The default maximum number of public IPs that can be consumed by an account",
+            null),
+    DefaultMaxAccountTemplates(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.templates",
+            "20",
+            "The default maximum number of templates that can be deployed for an account",
+            null),
+    DefaultMaxAccountSnapshots(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.snapshots",
+            "20",
+            "The default maximum number of snapshots that can be created for an account",
+            null),
+    DefaultMaxAccountVolumes(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.volumes",
+            "20",
+            "The default maximum number of volumes that can be created for an account",
+            null),
+    DefaultMaxAccountNetworks(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.networks",
+            "20",
+            "The default maximum number of networks that can be created for an account",
+            null),
+    DefaultMaxAccountVpcs(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.vpcs",
+            "20",
+            "The default maximum number of vpcs that can be created for an account",
+            null),
+    DefaultMaxAccountCpus(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.cpus",
+            "40",
+            "The default maximum number of cpu cores that can be used for an account",
+            null),
+    DefaultMaxAccountMemory(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.memory",
+            "40960",
+            "The default maximum memory (in MB) that can be used for an account",
+            null),
+    DefaultMaxAccountPrimaryStorage(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.primary.storage",
+            "200",
+            "The default maximum primary storage space (in GiB) that can be used for an account",
+            null),
+    DefaultMaxAccountSecondaryStorage(
+            "Account Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.account.secondary.storage",
+            "400",
+            "The default maximum secondary storage space (in GiB) that can be used for an account",
+            null),
+
+    //disabling lb as cluster sync does not work with distributed cluster
+    SubDomainNetworkAccess(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Boolean.class,
+            "allow.subdomain.network.access",
+            "true",
+            "Allow subdomains to use networks dedicated to their parent domain(s)",
+            null),
+    DnsBasicZoneUpdates(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            String.class,
+            "network.dns.basiczone.updates",
+            "all",
+            "This parameter can take 2 values: all (default) and pod. It defines if DHCP/DNS requests have to be send to all dhcp servers in cloudstack, or only to the one in the same pod",
+            "all,pod"),
+
+    ClusterMessageTimeOutSeconds(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "cluster.message.timeout.seconds",
+            "300",
+            "Time (in seconds) to wait before a inter-management server message post times out.",
+            null),
+    AgentLoadThreshold(
+            "Advanced",
+            ManagementServer.class,
+            Float.class,
+            "agent.load.threshold",
+            "0.7",
+            "Percentage (as a value between 0 and 1) of connected agents after which agent load balancing will start happening",
+            null),
+
+    DefaultMaxDomainUserVms("Domain Defaults", ManagementServer.class, Long.class, "max.domain.user.vms", "40", "The default maximum number of user VMs that can be deployed for a domain", null),
+    DefaultMaxDomainPublicIPs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.public.ips", "40", "The default maximum number of public IPs that can be consumed by a domain", null),
+    DefaultMaxDomainTemplates("Domain Defaults", ManagementServer.class, Long.class, "max.domain.templates", "40", "The default maximum number of templates that can be deployed for a domain", null),
+    DefaultMaxDomainSnapshots("Domain Defaults", ManagementServer.class, Long.class, "max.domain.snapshots", "40", "The default maximum number of snapshots that can be created for a domain", null),
+    DefaultMaxDomainVolumes("Domain Defaults", ManagementServer.class, Long.class, "max.domain.volumes", "40", "The default maximum number of volumes that can be created for a domain", null),
+    DefaultMaxDomainNetworks("Domain Defaults", ManagementServer.class, Long.class, "max.domain.networks", "40", "The default maximum number of networks that can be created for a domain", null),
+    DefaultMaxDomainVpcs("Domain Defaults", ManagementServer.class, Long.class, "max.domain.vpcs", "40", "The default maximum number of vpcs that can be created for a domain", null),
+    DefaultMaxDomainCpus("Domain Defaults", ManagementServer.class, Long.class, "max.domain.cpus", "80", "The default maximum number of cpu cores that can be used for a domain", null),
+    DefaultMaxDomainMemory("Domain Defaults", ManagementServer.class, Long.class, "max.domain.memory", "81920", "The default maximum memory (in MB) that can be used for a domain", null),
+    DefaultMaxDomainPrimaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.primary.storage", "400", "The default maximum primary storage space (in GiB) that can be used for a domain", null),
+    DefaultMaxDomainSecondaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.secondary.storage", "800", "The default maximum secondary storage space (in GiB) that can be used for a domain", null),
+
+    DefaultMaxProjectUserVms(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.user.vms",
+            "20",
+            "The default maximum number of user VMs that can be deployed for a project",
+            null),
+    DefaultMaxProjectPublicIPs(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.public.ips",
+            "20",
+            "The default maximum number of public IPs that can be consumed by a project",
+            null),
+    DefaultMaxProjectTemplates(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.templates",
+            "20",
+            "The default maximum number of templates that can be deployed for a project",
+            null),
+    DefaultMaxProjectSnapshots(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.snapshots",
+            "20",
+            "The default maximum number of snapshots that can be created for a project",
+            null),
+    DefaultMaxProjectVolumes(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.volumes",
+            "20",
+            "The default maximum number of volumes that can be created for a project",
+            null),
+    DefaultMaxProjectNetworks(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.networks",
+            "20",
+            "The default maximum number of networks that can be created for a project",
+            null),
+    DefaultMaxProjectVpcs(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.vpcs",
+            "20",
+            "The default maximum number of vpcs that can be created for a project",
+            null),
+    DefaultMaxProjectCpus(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.cpus",
+            "40",
+            "The default maximum number of cpu cores that can be used for a project",
+            null),
+    DefaultMaxProjectMemory(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.memory",
+            "40960",
+            "The default maximum memory (in MB) that can be used for a project",
+            null),
+    DefaultMaxProjectPrimaryStorage(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.primary.storage",
+            "200",
+            "The default maximum primary storage space (in GiB) that can be used for an project",
+            null),
+    DefaultMaxProjectSecondaryStorage(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "max.project.secondary.storage",
+            "400",
+            "The default maximum secondary storage space (in GiB) that can be used for an project",
+            null),
+
+    ProjectInviteRequired(
+            "Project Defaults",
+            ManagementServer.class,
+            Boolean.class,
+            "project.invite.required",
+            "false",
+            "If invitation confirmation is required when add account to project. Default value is false",
+            null),
+    ProjectInvitationExpirationTime(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "project.invite.timeout",
+            "86400",
+            "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds",
+            null),
+    AllowUserToCreateProject(
+            "Project Defaults",
+            ManagementServer.class,
+            Long.class,
+            "allow.user.create.projects",
+            "true",
+            "If regular user can create a project; true by default",
+            null),
+
+    ProjectEmailSender(
+            "Project Defaults",
+            ManagementServer.class,
+            String.class,
+            "project.email.sender",
+            null,
+            "Sender of project invitation email (will be in the From header of the email)",
+            null),
+    ProjectSMTPHost(
+            "Project Defaults",
+            ManagementServer.class,
+            String.class,
+            "project.smtp.host",
+            null,
+            "SMTP hostname used for sending out email project invitations",
+            null),
+    ProjectSMTPPassword(
+            "Secure",
+            ManagementServer.class,
+            String.class,
+            "project.smtp.password",
+            null,
+            "Password for SMTP authentication (applies only if project.smtp.useAuth is true)",
+            null),
+    ProjectSMTPPort("Project Defaults", ManagementServer.class, Integer.class, "project.smtp.port", "465", "Port the SMTP server is listening on", null),
+    ProjectSMTPUseAuth(
+            "Project Defaults",
+            ManagementServer.class,
+            String.class,
+            "project.smtp.useAuth",
+            null,
+            "If true, use SMTP authentication when sending emails",
+            null),
+    ProjectSMTPUsername(
+            "Project Defaults",
+            ManagementServer.class,
+            String.class,
+            "project.smtp.username",
+            null,
+            "Username for SMTP authentication (applies only if project.smtp.useAuth is true)",
+            null),
+
+    DefaultExternalLoadBalancerCapacity(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "external.lb.default.capacity",
+            "50",
+            "default number of networks permitted per external load balancer device",
+            null),
+    DefaultExternalFirewallCapacity(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "external.firewall.default.capacity",
+            "50",
+            "default number of networks permitted per external load firewall device",
+            null),
+    EIPWithMultipleNetScalersEnabled(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "eip.use.multiple.netscalers",
+            "false",
+            "Should be set to true, if there will be multiple NetScaler devices providing EIP service in a zone",
+            null),
+    ConsoleProxyServiceOffering(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "consoleproxy.service.offering",
+            null,
+            "Uuid of the service offering used by console proxy; if NULL - system offering will be used",
+            null),
+    SecondaryStorageServiceOffering(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "secstorage.service.offering",
+            null,
+            "Uuid of the service offering used by secondary storage; if NULL - system offering will be used",
+            null),
+    HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null),
+    ImplicitHostTags(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "implicit.host.tags",
+            "GPU",
+            "Tag hosts at the time of host disovery based on the host properties/capabilities",
+            null),
+    VpcCleanupInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "vpc.cleanup.interval",
+            "3600",
+            "The interval (in seconds) between cleanup for Inactive VPCs",
+            null),
+    VpcMaxNetworks("Advanced", ManagementServer.class, Integer.class, "vpc.max.networks", "3", "Maximum number of networks per vpc", null),
+    DetailBatchQuerySize("Advanced", ManagementServer.class, Integer.class, "detail.batch.query.size", "2000", "Default entity detail batch query size for listing", null),
+    NetworkIPv6SearchRetryMax(
+            "Network",
+            ManagementServer.class,
+            Integer.class,
+            "network.ipv6.search.retry.max",
+            "10000",
+            "The maximum number of retrying times to search for an available IPv6 address in the table",
+            null),
+
+    BaremetalInternalStorageServer(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "baremetal.internal.storage.server.ip",
+            null,
+            "the ip address of server that stores kickstart file, kernel, initrd, ISO for advanced networking baremetal provisioning",
+            null),
+    BaremetalProvisionDoneNotificationEnabled(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "baremetal.provision.done.notification.enabled",
+            "true",
+            "whether to enable baremetal provison done notification",
+            null),
+    BaremetalProvisionDoneNotificationTimeout(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "baremetal.provision.done.notification.timeout",
+            "1800",
+            "the max time to wait before treating a baremetal provision as failure if no provision done notification is not received, in secs",
+            null),
+    BaremetalProvisionDoneNotificationPort(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "baremetal.provision.done.notification.port",
+            "8080",
+            "the port that listens baremetal provision done notification. Should be the same to port management server listening on for now. Please change it to management server port if it's not default 8080",
+            null),
+    ExternalBaremetalSystemUrl(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "external.baremetal.system.url",
+            null,
+            "url of external baremetal system that CloudStack will talk to",
+            null),
+    ExternalBaremetalResourceClassName(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "external.baremetal.resource.classname",
+            null,
+            "class name for handling external baremetal resource",
+            null),
+    EnableBaremetalSecurityGroupAgentEcho(
+            "Advanced",
+            ManagementServer.class,
+            Boolean.class,
+            "enable.baremetal.securitygroup.agent.echo",
+            "false",
+            "After starting provision process, periodcially echo security agent installed in the template. Treat provisioning as success only if echo successfully",
+            null),
+    IntervalToEchoBaremetalSecurityGroupAgent(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "interval.baremetal.securitygroup.agent.echo",
+            "10",
+            "Interval to echo baremetal security group agent, in seconds",
+            null),
+    TimeoutToEchoBaremetalSecurityGroupAgent(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "timeout.baremetal.securitygroup.agent.echo",
+            "3600",
+            "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure",
+            null),
+
+    BaremetalIpmiLanInterface(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "baremetal.ipmi.lan.interface",
+            "default",
+            "option specified in -I option of impitool. candidates are: open/bmc/lipmi/lan/lanplus/free/imb, see ipmitool man page for details. default valule 'default' means using default option of ipmitool",
+            null),
+
+    BaremetalIpmiRetryTimes("Advanced",
+            ManagementServer.class,
+            String.class,
+            "baremetal.ipmi.fail.retry",
+            "5",
+            "ipmi interface will be temporary out of order after power opertions(e.g. cycle, on), it leads following commands fail immediately. The value specifies retry times before accounting it as real failure",
+            null),
+
+    ApiLimitEnabled("Advanced", ManagementServer.class, Boolean.class, "api.throttling.enabled", "false", "Enable/disable Api rate limit", null),
+    ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null),
+    ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null),
+    ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null),
+
+    // object store
+    S3EnableRRS("Advanced", ManagementServer.class, Boolean.class, "s3.rrs.enabled", "false", "enable s3 reduced redundancy storage", null),
+    S3MaxSingleUploadSize(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "s3.singleupload.max.size",
+            "5",
+            "The maximum size limit for S3 single part upload API(in GB). If it is set to 0, then it means always use multi-part upload to upload object to S3. "
+                    + "If it is set to -1, then it means always use single-part upload to upload object to S3. ",
+                    null),
+
+    // VMSnapshots
+    VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
+    VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
+
+    CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", null, "DNS name of the cloud for the GSLB service", null),
+    InternalLbVmServiceOfferingId(
+            "Advanced",
+            ManagementServer.class,
+            String.class,
+            "internallbvm.service.offering",
+            null,
+            "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used",
+            null),
+    ExecuteInSequenceNetworkElementCommands(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Boolean.class,
+            "execute.in.sequence.network.element.commands",
+            "false",
+            "If set to true, DhcpEntryCommand, SavePasswordCommand, VmDataCommand will be synchronized on the agent side."
+                    + " If set to false, these commands become asynchronous. Default value is false.",
+                    null),
+
+    UCSSyncBladeInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ucs.sync.blade.interval",
+            "3600",
+            "the interval cloudstack sync with UCS manager for available blades in case user remove blades from chassis without notifying CloudStack",
+            null),
+
+    RedundantRouterVrrpInterval(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.redundant.vrrp.interval",
+            "1",
+            "seconds between VRRP broadcast. It would 3 times broadcast fail to trigger fail-over mechanism of redundant router",
+            null),
+
+    RouterAggregationCommandEachTimeout(
+            "Advanced",
+            NetworkOrchestrationService.class,
+            Integer.class,
+            "router.aggregation.command.each.timeout",
+            "600",
+            "timeout in seconds for each Virtual Router command being aggregated. The final aggregation command timeout would be determined by this timeout * commands counts ",
+            null),
+
+    ManagementServerVendor("Advanced", ManagementServer.class, String.class, "mgt.server.vendor", "ACS", "the vendor of management server", null),
+    PublishActionEvent("Advanced", ManagementServer.class, Boolean.class, "publish.action.events", "true", "enable or disable publishing of action events on the event bus", null),
+    PublishAlertEvent("Advanced", ManagementServer.class, Boolean.class, "publish.alert.events", "true", "enable or disable publishing of alert events on the event bus", null),
+    PublishResourceStateEvent("Advanced", ManagementServer.class, Boolean.class, "publish.resource.state.events", "true", "enable or disable publishing of alert events on the event bus", null),
+    PublishUsageEvent("Advanced", ManagementServer.class, Boolean.class, "publish.usage.events", "true", "enable or disable publishing of usage events on the event bus", null),
+    PublishAsynJobEvent("Advanced", ManagementServer.class, Boolean.class, "publish.async.job.events", "true", "enable or disable publishing of usage events on the event bus", null),
+
+    // StatsCollector
+    StatsOutPutGraphiteHost("Advanced", ManagementServer.class, String.class, "stats.output.uri", "", "URI to additionally send StatsCollector statistics to", null),
+
+    SSVMPSK("Hidden", ManagementServer.class, String.class, "upload.post.secret.key", "", "PSK with SSVM", null);
+
+    private final String _category;
+    private final Class<?> _componentClass;
+    private final Class<?> _type;
+    private final String _name;
+    private final String _defaultValue;
+    private final String _description;
+    private final String _range;
+    private final String _scope; // Parameter can be at different levels (Zone/cluster/pool/account), by default every parameter is at global
+
+    private static final HashMap<String, List<Config>> s_scopeLevelConfigsMap = new HashMap<String, List<Config>>();
+    static {
+        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Zone.toString(), new ArrayList<Config>());
+        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster.toString(), new ArrayList<Config>());
+        s_scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool.toString(), new ArrayList<Config>());
+        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Account.toString(), new ArrayList<Config>());
+        s_scopeLevelConfigsMap.put(ConfigKey.Scope.Global.toString(), new ArrayList<Config>());
+
+        for (Config c : Config.values()) {
+            //Creating group of parameters per each level (zone/cluster/pool/account)
+            StringTokenizer tokens = new StringTokenizer(c.getScope(), ",");
+            while (tokens.hasMoreTokens()) {
+                String scope = tokens.nextToken().trim();
+                List<Config> currentConfigs = s_scopeLevelConfigsMap.get(scope);
+                currentConfigs.add(c);
+                s_scopeLevelConfigsMap.put(scope, currentConfigs);
+            }
+        }
+    }
+
+    private static final HashMap<String, List<Config>> Configs = new HashMap<String, List<Config>>();
+    static {
+        // Add categories
+        Configs.put("Alert", new ArrayList<Config>());
+        Configs.put("Storage", new ArrayList<Config>());
+        Configs.put("Snapshots", new ArrayList<Config>());
+        Configs.put("Network", new ArrayList<Config>());
+        Configs.put("Usage", new ArrayList<Config>());
+        Configs.put("Console Proxy", new ArrayList<Config>());
+        Configs.put("Advanced", new ArrayList<Config>());
+        Configs.put("Usage", new ArrayList<Config>());
+        Configs.put("Developer", new ArrayList<Config>());
+        Configs.put("Hidden", new ArrayList<Config>());
+        Configs.put("Account Defaults", new ArrayList<Config>());
+        Configs.put("Domain Defaults", new ArrayList<Config>());
+        Configs.put("Project Defaults", new ArrayList<Config>());
+        Configs.put("Secure", new ArrayList<Config>());
+
+        // Add values into HashMap
+        for (Config c : Config.values()) {
+            String category = c.getCategory();
+            List<Config> currentConfigs = Configs.get(category);
+            currentConfigs.add(c);
+            Configs.put(category, currentConfigs);
+        }
+    }
+
+    private Config(String category, Class<?> componentClass, Class<?> type, String name, String defaultValue, String description, String range) {
+        _category = category;
+        _componentClass = componentClass;
+        _type = type;
+        _name = name;
+        _defaultValue = defaultValue;
+        _description = description;
+        _range = range;
+        _scope = ConfigKey.Scope.Global.toString();
+    }
+
+    public String getCategory() {
+        return _category;
+    }
+
+    public String key() {
+        return _name;
+    }
+
+    public String getDescription() {
+        return _description;
+    }
+
+    public String getDefaultValue() {
+        return _defaultValue;
+    }
+
+    public Class<?> getType() {
+        return _type;
+    }
+
+    public String getScope() {
+        return _scope;
+    }
+
+    public String getComponent() {
+        if (_componentClass == ManagementServer.class) {
+            return "management-server";
+        } else if (_componentClass == AgentManager.class) {
+            return "AgentManager";
+        } else if (_componentClass == UserVmManager.class) {
+            return "UserVmManager";
+        } else if (_componentClass == HighAvailabilityManager.class) {
+            return "HighAvailabilityManager";
+        } else if (_componentClass == StoragePoolAllocator.class) {
+            return "StorageAllocator";
+        } else if (_componentClass == NetworkOrchestrationService.class) {
+            return "NetworkManager";
+        } else if (_componentClass == StorageManager.class) {
+            return "StorageManager";
+        } else if (_componentClass == TemplateManager.class) {
+            return "TemplateManager";
+        } else if (_componentClass == VpcManager.class) {
+            return "VpcManager";
+        } else if (_componentClass == SnapshotManager.class) {
+            return "SnapshotManager";
+        } else if (_componentClass == VMSnapshotManager.class) {
+            return "VMSnapshotManager";
+        } else {
+            return "none";
+        }
+    }
+
+    public String getRange() {
+        return _range;
+    }
+
+    @Override
+    public String toString() {
+        return _name;
+    }
+
+    public static List<Config> getConfigs(String category) {
+        return Configs.get(category);
+    }
+
+    public static Config getConfig(String name) {
+        List<String> categories = getCategories();
+        for (String category : categories) {
+            List<Config> currentList = getConfigs(category);
+            for (Config c : currentList) {
+                if (c.key().equals(name)) {
+                    return c;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static List<String> getCategories() {
+        Object[] keys = Configs.keySet().toArray();
+        List<String> categories = new ArrayList<String>();
+        for (Object key : keys) {
+            categories.add((String)key);
+        }
+        return categories;
+    }
+}
diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
new file mode 100755
index 0000000..ae04fc3
--- /dev/null
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -0,0 +1,5744 @@
+// 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.configuration;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.google.common.collect.Sets;
+
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.AffinityGroupService;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
+import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
+import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpDao;
+import org.apache.cloudstack.region.PortableIpRange;
+import org.apache.cloudstack.region.PortableIpRangeDao;
+import org.apache.cloudstack.region.PortableIpRangeVO;
+import org.apache.cloudstack.region.PortableIpVO;
+import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.region.RegionVO;
+import org.apache.cloudstack.region.dao.RegionDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterIpAddressVO;
+import com.cloud.dc.DataCenterLinkLocalIpAddressVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.DomainVlanMapVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.AccountVlanMapDao;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterDetailsDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.DomainVlanMapDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeploymentClusterPlanner;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainDetailVO;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.domain.dao.DomainDetailsDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.gpu.GPU;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.org.Grouping;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectManager;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.server.ManagementService;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.test.IPRangeConfig;
+import com.cloud.user.Account;
+import com.cloud.user.AccountDetailVO;
+import com.cloud.user.AccountDetailsDao;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.NicIpAlias;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
+    public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
+
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ConfigDepot _configDepot;
+    @Inject
+    HostPodDao _podDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    VolumeDao _volumeDao;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    AccountVlanMapDao _accountVlanMapDao;
+    @Inject
+    DomainVlanMapDao _domainVlanMapDao;
+    @Inject
+    PodVlanMapDao _podVlanMapDao;
+    @Inject
+    DataCenterDao _zoneDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+    @Inject
+    DiskOfferingDao _diskOfferingDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    IPAddressDao _publicIpAddressDao;
+    @Inject
+    DataCenterIpAddressDao _privateIpAddressDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkService _networkSvc;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    AlertManager _alertMgr;
+    List<SecurityChecker> _secChecker;
+
+    @Inject
+    CapacityDao _capacityDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    ProjectManager _projectMgr;
+    @Inject
+    DataStoreManager _dataStoreMgr;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOffServiceMapDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _trafficTypeDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    UserDao _userDao;
+    @Inject
+    PortableIpRangeDao _portableIpRangeDao;
+    @Inject
+    RegionDao _regionDao;
+    @Inject
+    PortableIpDao _portableIpDao;
+    @Inject
+    ConfigurationServer _configServer;
+    @Inject
+    DataCenterDetailsDao _dcDetailsDao;
+    @Inject
+    ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    StoragePoolDetailsDao _storagePoolDetailsDao;
+    @Inject
+    AccountDetailsDao _accountDetailsDao;
+    @Inject
+    DomainDetailsDao _domainDetailsDao;
+    @Inject
+    PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    NicIpAliasDao _nicIpAliasDao;
+    @Inject
+    public ManagementService _mgr;
+    @Inject
+    DedicatedResourceDao _dedicatedDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    AffinityGroupDao _affinityGroupDao;
+    @Inject
+    AffinityGroupService _affinityGroupService;
+    @Inject
+    StorageManager _storageManager;
+    @Inject
+    ImageStoreDao _imageStoreDao;
+    @Inject
+    ImageStoreDetailsDao _imageStoreDetailsDao;
+    @Inject
+    MessageBus messageBus;
+
+
+    // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
+    @Inject
+    protected DataCenterLinkLocalIpAddressDao _linkLocalIpAllocDao;
+
+    private int _maxVolumeSizeInGb = Integer.parseInt(Config.MaxVolumeSize.getDefaultValue());
+    private long _defaultPageSize = Long.parseLong(Config.DefaultPageSize.getDefaultValue());
+    private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{1,63}$";
+    protected Set<String> configValuesForValidation;
+    private Set<String> weightBasedParametersForValidation;
+    private Set<String> overprovisioningFactorsForValidation;
+
+    public static final ConfigKey<Boolean> SystemVMUseLocalStorage = new ConfigKey<Boolean>(Boolean.class, "system.vm.use.local.storage", "Advanced", "false",
+            "Indicates whether to use local storage pools or shared storage pools for system VMs.", false, ConfigKey.Scope.Zone, null);
+
+    private static final String DefaultForSystemVmsForPodIpRange = "0";
+    private static final String DefaultVlanForPodIpRange = Vlan.UNTAGGED.toString();
+
+    private static final Set<Provider> VPC_ONLY_PROVIDERS = Sets.newHashSet(Provider.VPCVirtualRouter, Provider.JuniperContrailVpcRouter, Provider.InternalLbVm);
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        final String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key());
+        _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, Integer.parseInt(Config.MaxVolumeSize.getDefaultValue()));
+
+        final String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key());
+        _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue()));
+
+        populateConfigValuesForValidationSet();
+        weightBasedParametersForValidation();
+        overProvisioningFactorsForValidation();
+        return true;
+    }
+
+    private void populateConfigValuesForValidationSet() {
+        configValuesForValidation = new HashSet<String>();
+        configValuesForValidation.add("event.purge.interval");
+        configValuesForValidation.add("account.cleanup.interval");
+        configValuesForValidation.add("alert.wait");
+        configValuesForValidation.add("consoleproxy.capacityscan.interval");
+        configValuesForValidation.add("expunge.interval");
+        configValuesForValidation.add("host.stats.interval");
+        configValuesForValidation.add("investigate.retry.interval");
+        configValuesForValidation.add("migrate.retry.interval");
+        configValuesForValidation.add("network.gc.interval");
+        configValuesForValidation.add("ping.interval");
+        configValuesForValidation.add("snapshot.poll.interval");
+        configValuesForValidation.add("stop.retry.interval");
+        configValuesForValidation.add("storage.stats.interval");
+        configValuesForValidation.add("storage.cleanup.interval");
+        configValuesForValidation.add("wait");
+        configValuesForValidation.add("xenserver.heartbeat.interval");
+        configValuesForValidation.add("xenserver.heartbeat.timeout");
+        configValuesForValidation.add("ovm3.heartbeat.interval");
+        configValuesForValidation.add("ovm3.heartbeat.timeout");
+        configValuesForValidation.add("incorrect.login.attempts.allowed");
+        configValuesForValidation.add("vm.password.length");
+        configValuesForValidation.add("externaldhcp.vmip.retrieval.interval");
+        configValuesForValidation.add("externaldhcp.vmip.max.retry");
+        configValuesForValidation.add("externaldhcp.vmipFetch.threadPool.max");
+        configValuesForValidation.add("remote.access.vpn.psk.length");
+    }
+
+    private void weightBasedParametersForValidation() {
+        weightBasedParametersForValidation = new HashSet<String>();
+        weightBasedParametersForValidation.add(AlertManager.CPUCapacityThreshold.key());
+        weightBasedParametersForValidation.add(AlertManager.StorageAllocatedCapacityThreshold.key());
+        weightBasedParametersForValidation.add(AlertManager.StorageCapacityThreshold.key());
+        weightBasedParametersForValidation.add(AlertManager.MemoryCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.PublicIpCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.PrivateIpCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.SecondaryStorageCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.VlanCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.DirectNetworkPublicIpCapacityThreshold.key());
+        weightBasedParametersForValidation.add(Config.LocalStorageCapacityThreshold.key());
+        weightBasedParametersForValidation.add(CapacityManager.StorageAllocatedCapacityDisableThreshold.key());
+        weightBasedParametersForValidation.add(CapacityManager.StorageCapacityDisableThreshold.key());
+        weightBasedParametersForValidation.add(DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.key());
+        weightBasedParametersForValidation.add(DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.key());
+        weightBasedParametersForValidation.add(Config.AgentLoadThreshold.key());
+        weightBasedParametersForValidation.add(Config.VmUserDispersionWeight.key());
+
+    }
+
+    private void overProvisioningFactorsForValidation() {
+        overprovisioningFactorsForValidation = new HashSet<String>();
+        overprovisioningFactorsForValidation.add(CapacityManager.MemOverprovisioningFactor.key());
+        overprovisioningFactorsForValidation.add(CapacityManager.CpuOverprovisioningFactor.key());
+        overprovisioningFactorsForValidation.add(CapacityManager.StorageOverprovisioningFactor.key());
+    }
+
+    @Override
+    public boolean start() {
+
+        // TODO : this may not be a good place to do integrity check here, we
+        // put it here as we need _alertMgr to be properly
+        // configured
+        // before we can use it
+
+        // As it is so common for people to forget about configuring
+        // management.network.cidr,
+        final String mgtCidr = _configDao.getValue(Config.ManagementNetwork.key());
+        if (mgtCidr == null || mgtCidr.trim().isEmpty()) {
+            final String[] localCidrs = NetUtils.getLocalCidrs();
+            if (localCidrs != null && localCidrs.length > 0) {
+                s_logger.warn("Management network CIDR is not configured originally. Set it default to " + localCidrs[0]);
+
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to "
+                        + localCidrs[0], "");
+                _configDao.update(Config.ManagementNetwork.key(), Config.ManagementNetwork.getCategory(), localCidrs[0]);
+            } else {
+                s_logger.warn("Management network CIDR is not properly configured and we are not able to find a default setting");
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0),
+                        "Management network CIDR is not properly configured and we are not able to find a default setting", "");
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    @DB
+    public String updateConfiguration(final long userId, final String name, final String category, final String value, final String scope, final Long resourceId) {
+        final String validationMsg = validateConfigurationValue(name, value, scope);
+
+        if (validationMsg != null) {
+            s_logger.error("Invalid configuration option, name: " + name + ", value:" + value);
+            throw new InvalidParameterValueException(validationMsg);
+        }
+
+        // If scope of the parameter is given then it needs to be updated in the
+        // corresponding details table,
+        // if scope is mentioned as global or not mentioned then it is normal
+        // global parameter updation
+        if (scope != null && !scope.isEmpty() && !ConfigKey.Scope.Global.toString().equalsIgnoreCase(scope)) {
+            switch (ConfigKey.Scope.valueOf(scope)) {
+            case Zone:
+                final DataCenterVO zone = _zoneDao.findById(resourceId);
+                if (zone == null) {
+                    throw new InvalidParameterValueException("unable to find zone by id " + resourceId);
+                }
+                _dcDetailsDao.addDetail(resourceId, name, value, true);
+                break;
+            case Cluster:
+                final ClusterVO cluster = _clusterDao.findById(resourceId);
+                if (cluster == null) {
+                    throw new InvalidParameterValueException("unable to find cluster by id " + resourceId);
+                }
+                ClusterDetailsVO clusterDetailsVO = _clusterDetailsDao.findDetail(resourceId, name);
+                if (clusterDetailsVO == null) {
+                    clusterDetailsVO = new ClusterDetailsVO(resourceId, name, value);
+                    _clusterDetailsDao.persist(clusterDetailsVO);
+                } else {
+                    clusterDetailsVO.setValue(value);
+                    _clusterDetailsDao.update(clusterDetailsVO.getId(), clusterDetailsVO);
+                }
+                break;
+
+            case StoragePool:
+                final StoragePoolVO pool = _storagePoolDao.findById(resourceId);
+                if (pool == null) {
+                    throw new InvalidParameterValueException("unable to find storage pool by id " + resourceId);
+                }
+                if(name.equals(CapacityManager.StorageOverprovisioningFactor.key())) {
+                    if(!pool.getPoolType().supportsOverProvisioning() ) {
+                        throw new InvalidParameterValueException("Unable to update  storage pool with id " + resourceId + ". Overprovision not supported for " + pool.getPoolType());
+                    }
+                }
+
+                _storagePoolDetailsDao.addDetail(resourceId, name, value, true);
+
+                break;
+
+            case Account:
+                final AccountVO account = _accountDao.findById(resourceId);
+                if (account == null) {
+                    throw new InvalidParameterValueException("unable to find account by id " + resourceId);
+                }
+                AccountDetailVO accountDetailVO = _accountDetailsDao.findDetail(resourceId, name);
+                if (accountDetailVO == null) {
+                    accountDetailVO = new AccountDetailVO(resourceId, name, value);
+                    _accountDetailsDao.persist(accountDetailVO);
+                } else {
+                    accountDetailVO.setValue(value);
+                    _accountDetailsDao.update(accountDetailVO.getId(), accountDetailVO);
+                }
+                break;
+
+            case ImageStore:
+                final ImageStoreVO imgStore = _imageStoreDao.findById(resourceId);
+                Preconditions.checkState(imgStore != null);
+                _imageStoreDetailsDao.addDetail(resourceId, name, value, true);
+                break;
+
+            case Domain:
+                final DomainVO domain = _domainDao.findById(resourceId);
+                if (domain == null) {
+                    throw new InvalidParameterValueException("unable to find domain by id " + resourceId);
+                }
+                DomainDetailVO domainDetailVO = _domainDetailsDao.findDetail(resourceId, name);
+                if (domainDetailVO == null) {
+                    domainDetailVO = new DomainDetailVO(resourceId, name, value);
+                    _domainDetailsDao.persist(domainDetailVO);
+                } else {
+                    domainDetailVO.setValue(value);
+                    _domainDetailsDao.update(domainDetailVO.getId(), domainDetailVO);
+                }
+                break;
+
+            default:
+                throw new InvalidParameterValueException("Scope provided is invalid");
+            }
+            return value;
+        }
+
+        // Execute all updates in a single transaction
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+
+        if (!_configDao.update(name, category, value)) {
+            s_logger.error("Failed to update configuration option, name: " + name + ", value:" + value);
+            throw new CloudRuntimeException("Failed to update configuration value. Please contact Cloud Support.");
+        }
+
+        PreparedStatement pstmt = null;
+        if (Config.XenServerGuestNetwork.key().equalsIgnoreCase(name)) {
+            final String sql = "update host_details set value=? where name=?";
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setString(1, value);
+                pstmt.setString(2, "guest.network.device");
+
+                pstmt.executeUpdate();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to update guest.network.device in host_details due to exception ", e);
+            }
+        } else if (Config.XenServerPrivateNetwork.key().equalsIgnoreCase(name)) {
+            final String sql = "update host_details set value=? where name=?";
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setString(1, value);
+                pstmt.setString(2, "private.network.device");
+
+                pstmt.executeUpdate();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to update private.network.device in host_details due to exception ", e);
+            }
+        } else if (Config.XenServerPublicNetwork.key().equalsIgnoreCase(name)) {
+            final String sql = "update host_details set value=? where name=?";
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setString(1, value);
+                pstmt.setString(2, "public.network.device");
+
+                pstmt.executeUpdate();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to update public.network.device in host_details due to exception ", e);
+            }
+        } else if (Config.XenServerStorageNetwork1.key().equalsIgnoreCase(name)) {
+            final String sql = "update host_details set value=? where name=?";
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setString(1, value);
+                pstmt.setString(2, "storage.network.device1");
+
+                pstmt.executeUpdate();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to update storage.network.device1 in host_details due to exception ", e);
+            }
+        } else if (Config.XenServerStorageNetwork2.key().equals(name)) {
+            final String sql = "update host_details set value=? where name=?";
+            try {
+                pstmt = txn.prepareAutoCloseStatement(sql);
+                pstmt.setString(1, value);
+                pstmt.setString(2, "storage.network.device2");
+
+                pstmt.executeUpdate();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to update storage.network.device2 in host_details due to exception ", e);
+            }
+        } else if (Config.SecStorageSecureCopyCert.key().equalsIgnoreCase(name)) {
+            //FIXME - Ideally there should be a listener model to listen to global config changes and be able to take action gracefully.
+            //Expire the download urls
+            final String sqlTemplate = "update template_store_ref set download_url_created=?";
+            final String sqlVolume = "update volume_store_ref set download_url_created=?";
+            try {
+                // Change for templates
+                pstmt = txn.prepareAutoCloseStatement(sqlTemplate);
+                pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time.
+                pstmt.executeUpdate();
+                // Change for volumes
+                pstmt = txn.prepareAutoCloseStatement(sqlVolume);
+                pstmt.setDate(1, new Date(-1l));// Set the time before the epoch time.
+                pstmt.executeUpdate();
+                // Cleanup the download urls
+                _storageManager.cleanupDownloadUrls();
+            } catch (final Throwable e) {
+                throw new CloudRuntimeException("Failed to clean up download URLs in template_store_ref or volume_store_ref due to exception ", e);
+            }
+        }
+
+        txn.commit();
+        messageBus.publish(_name, EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, PublishScope.GLOBAL, name);
+        return _configDao.getValue(name);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, eventDescription = "updating configuration")
+    public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidParameterValueException {
+        final Long userId = CallContext.current().getCallingUserId();
+        final String name = cmd.getCfgName();
+        String value = cmd.getValue();
+        final Long zoneId = cmd.getZoneId();
+        final Long clusterId = cmd.getClusterId();
+        final Long storagepoolId = cmd.getStoragepoolId();
+        final Long accountId = cmd.getAccountId();
+        final Long imageStoreId = cmd.getImageStoreId();
+        final Long domainId = cmd.getDomainId();
+        CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : value == null ? "" : value));
+        // check if config value exists
+        final ConfigurationVO config = _configDao.findByName(name);
+        String catergory = null;
+
+        // FIX ME - All configuration parameters are not moved from config.java to configKey
+        if (config == null) {
+            if (_configDepot.get(name) == null) {
+                s_logger.warn("Probably the component manager where configuration variable " + name + " is defined needs to implement Configurable interface");
+                throw new InvalidParameterValueException("Config parameter with name " + name + " doesn't exist");
+            }
+            catergory = _configDepot.get(name).category();
+        } else {
+            catergory = config.getCategory();
+        }
+
+        if (value == null) {
+            return _configDao.findByName(name);
+        }
+
+        value = value.trim();
+
+        if (value.isEmpty() || value.equals("null")) {
+            value = null;
+        }
+
+        String scope = null;
+        Long id = null;
+        int paramCountCheck = 0;
+
+        if (zoneId != null) {
+            scope = ConfigKey.Scope.Zone.toString();
+            id = zoneId;
+            paramCountCheck++;
+        }
+        if (clusterId != null) {
+            scope = ConfigKey.Scope.Cluster.toString();
+            id = clusterId;
+            paramCountCheck++;
+        }
+        if (accountId != null) {
+            scope = ConfigKey.Scope.Account.toString();
+            id = accountId;
+            paramCountCheck++;
+        }
+        if (domainId != null) {
+            scope = ConfigKey.Scope.Domain.toString();
+            id = domainId;
+            paramCountCheck++;
+        }
+        if (storagepoolId != null) {
+            scope = ConfigKey.Scope.StoragePool.toString();
+            id = storagepoolId;
+            paramCountCheck++;
+        }
+        if (imageStoreId != null) {
+            scope = ConfigKey.Scope.ImageStore.toString();
+            id = imageStoreId;
+            paramCountCheck++;
+        }
+
+        if (paramCountCheck > 1) {
+            throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
+        }
+
+        final String updatedValue = updateConfiguration(userId, name, catergory, value, scope, id);
+        if (value == null && updatedValue == null || updatedValue.equalsIgnoreCase(value)) {
+            return _configDao.findByName(name);
+        } else {
+            throw new CloudRuntimeException("Unable to update configuration parameter " + name);
+        }
+    }
+
+    private String validateConfigurationValue(final String name, String value, final String scope) {
+
+        final ConfigurationVO cfg = _configDao.findByName(name);
+        if (cfg == null) {
+            s_logger.error("Missing configuration variable " + name + " in configuration table");
+            return "Invalid configuration variable.";
+        }
+
+        final String configScope = cfg.getScope();
+        if (scope != null) {
+            if (!configScope.contains(scope)) {
+                s_logger.error("Invalid scope id provided for the parameter " + name);
+                return "Invalid scope id provided for the parameter " + name;
+            }
+        }
+        Class<?> type = null;
+        final Config c = Config.getConfig(name);
+        if (c == null) {
+            s_logger.warn("Did not find configuration " + name + " in Config.java. Perhaps moved to ConfigDepot");
+            final ConfigKey<?> configKey = _configDepot.get(name);
+            if(configKey == null) {
+                s_logger.warn("Did not find configuration " + name + " in ConfigDepot too.");
+                return null;
+            }
+            type = configKey.type();
+        } else {
+            type = c.getType();
+        }
+        //no need to validate further if a
+        //config can have null value.
+        String errMsg = null;
+        try {
+            if (type.equals(Integer.class)) {
+                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid integer value for parameter " + name;
+                Integer.parseInt(value);
+            } else if (type.equals(Float.class)) {
+                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid float value for parameter " + name;
+                Float.parseFloat(value);
+            } else if (type.equals(Long.class)) {
+                errMsg = "There was error in trying to parse value: " + value + ". Please enter a valid long value for parameter " + name;
+                Long.parseLong(value);
+            }
+        } catch (final Exception e) {
+            // catching generic exception as some throws NullPointerException and some throws NumberFormatExcpeion
+            s_logger.error(errMsg);
+            return errMsg;
+        }
+
+        if (value == null) {
+            if (type.equals(Boolean.class)) {
+                return "Please enter either 'true' or 'false'.";
+            }
+            if (overprovisioningFactorsForValidation.contains(name)) {
+                final String msg = "value cannot be null for the parameter " + name;
+                s_logger.error(msg);
+                return msg;
+            }
+            return null;
+        }
+
+        value = value.trim();
+        try {
+            if (overprovisioningFactorsForValidation.contains(name) && Float.parseFloat(value) < 1f) {
+                final String msg = name + " should be greater than or equal to 1";
+                s_logger.error(msg);
+                throw new InvalidParameterValueException(msg);
+            }
+        } catch (final NumberFormatException e) {
+            final String msg = "There was an error trying to parse the float value for: " + name;
+            s_logger.error(msg);
+            throw new InvalidParameterValueException(msg);
+        }
+
+        if (type.equals(Boolean.class)) {
+            if (!(value.equals("true") || value.equals("false"))) {
+                s_logger.error("Configuration variable " + name + " is expecting true or false instead of " + value);
+                return "Please enter either 'true' or 'false'.";
+            }
+            return null;
+        }
+
+        if (type.equals(Integer.class) && NetworkModel.MACIdentifier.key().equalsIgnoreCase(name)) {
+            try {
+                final int val = Integer.parseInt(value);
+                //The value need to be between 0 to 255 because the mac generation needs a value of 8 bit
+                //0 value is considered as disable.
+                if(val < 0 || val > 255){
+                    throw new InvalidParameterValueException(name+" value should be between 0 and 255. 0 value will disable this feature");
+                }
+            } catch (final NumberFormatException e) {
+                s_logger.error("There was an error trying to parse the integer value for:" + name);
+                throw new InvalidParameterValueException("There was an error trying to parse the integer value for:" + name);
+            }
+        }
+
+        if (type.equals(Integer.class) && configValuesForValidation.contains(name)) {
+            try {
+                final int val = Integer.parseInt(value);
+                if (val <= 0) {
+                    throw new InvalidParameterValueException("Please enter a positive value for the configuration parameter:" + name);
+                }
+                if ("vm.password.length".equalsIgnoreCase(name) && val < 6) {
+                    throw new InvalidParameterValueException("Please enter a value greater than 5 for the configuration parameter:" + name);
+                }
+                if ("remote.access.vpn.psk.length".equalsIgnoreCase(name)) {
+                    if (val < 8) {
+                        throw new InvalidParameterValueException("Please enter a value greater than 7 for the configuration parameter:" + name);
+                    }
+                    if (val > 256) {
+                        throw new InvalidParameterValueException("Please enter a value less than 257 for the configuration parameter:" + name);
+                    }
+                }
+            } catch (final NumberFormatException e) {
+                s_logger.error("There was an error trying to parse the integer value for:" + name);
+                throw new InvalidParameterValueException("There was an error trying to parse the integer value for:" + name);
+            }
+        }
+
+        if (type.equals(Float.class)) {
+            try {
+                final Float val = Float.parseFloat(value);
+                if (weightBasedParametersForValidation.contains(name) && (val < 0f || val > 1f)) {
+                    throw new InvalidParameterValueException("Please enter a value between 0 and 1 for the configuration parameter: " + name);
+                }
+            } catch (final NumberFormatException e) {
+                s_logger.error("There was an error trying to parse the float value for:" + name);
+                throw new InvalidParameterValueException("There was an error trying to parse the float value for:" + name);
+            }
+        }
+
+        if(c == null ) {
+            //range validation has to be done per case basis, for now
+            //return in case of Configkey parameters
+            return null;
+        }
+
+        final String range = c.getRange();
+        if (range == null) {
+            return null;
+        }
+
+        if (type.equals(String.class)) {
+            if (range.equals("privateip")) {
+                try {
+                    if (!NetUtils.isSiteLocalAddress(value)) {
+                        s_logger.error("privateip range " + value + " is not a site local address for configuration variable " + name);
+                        return "Please enter a site local IP address.";
+                    }
+                } catch (final NullPointerException e) {
+                    s_logger.error("Error parsing ip address for " + name);
+                    throw new InvalidParameterValueException("Error parsing ip address");
+                }
+            } else if (range.equals("netmask")) {
+                if (!NetUtils.isValidIp4Netmask(value)) {
+                    s_logger.error("netmask " + value + " is not a valid net mask for configuration variable " + name);
+                    return "Please enter a valid netmask.";
+                }
+            } else if (range.equals("hypervisorList")) {
+                final String[] hypervisors = value.split(",");
+                if (hypervisors == null) {
+                    return "Please enter hypervisor list, separated by comma";
+                }
+                for (final String hypervisor : hypervisors) {
+                    if (HypervisorType.getType(hypervisor) == HypervisorType.Any || HypervisorType.getType(hypervisor) == HypervisorType.None) {
+                        return "Please enter a valid hypervisor type";
+                    }
+                }
+            } else if (range.equalsIgnoreCase("instanceName")) {
+                if (!NetUtils.verifyInstanceName(value)) {
+                    return "Instance name can not contain hyphen, space or plus sign";
+                }
+            } else if (range.equalsIgnoreCase("domainName")) {
+                String domainName = value;
+                if (value.startsWith("*")) {
+                    domainName = value.substring(2); //skip the "*."
+                }
+                //max length for FQDN is 253 + 2, code adds xxx-xxx-xxx-xxx to domain name when creating URL
+                if (domainName.length() >= 238 || !domainName.matches(DOMAIN_NAME_PATTERN)) {
+                    return "Please enter a valid string for domain name, prefixed with '*.' if applicable";
+                }
+            } else if (range.equals("routes")) {
+                final String[] routes = value.split(",");
+                for (final String route : routes) {
+                    if (route != null) {
+                        final String routeToVerify = route.trim();
+                        if (!NetUtils.isValidIp4Cidr(routeToVerify)) {
+                            throw new InvalidParameterValueException("Invalid value for blacklisted route: " + route + ". Valid format is list"
+                                    + " of cidrs separated by coma. Example: 10.1.1.0/24,192.168.0.0/24");
+                        }
+                    }
+                }
+            } else {
+                final String[] options = range.split(",");
+                for (final String option : options) {
+                    if (option.trim().equalsIgnoreCase(value)) {
+                        return null;
+                    }
+                }
+                s_logger.error("configuration value for " + name + " is invalid");
+                return "Please enter : " + range;
+
+            }
+        } else if (type.equals(Integer.class)) {
+            final String[] options = range.split("-");
+            if (options.length != 2) {
+                final String msg = "configuration range " + range + " for " + name + " is invalid";
+                s_logger.error(msg);
+                return msg;
+            }
+            final int min = Integer.parseInt(options[0]);
+            final int max = Integer.parseInt(options[1]);
+            final int val = Integer.parseInt(value);
+            if (val < min || val > max) {
+                s_logger.error("configuration value for " + name + " is invalid");
+                return "Please enter : " + range;
+            }
+        }
+        return null;
+    }
+
+    private boolean podHasAllocatedPrivateIPs(final long podId) {
+        final HostPodVO pod = _podDao.findById(podId);
+        final int count = _privateIpAddressDao.countIPs(podId, pod.getDataCenterId(), true);
+        return count > 0;
+    }
+
+    protected void checkIfPodIsDeletable(final long podId) {
+        final HostPodVO pod = _podDao.findById(podId);
+
+        final String errorMsg = "The pod cannot be deleted because ";
+
+        // Check if there are allocated private IP addresses in the pod
+        if (_privateIpAddressDao.countIPs(podId, pod.getDataCenterId(), true) != 0) {
+            throw new CloudRuntimeException(errorMsg + "there are private IP addresses allocated in this pod.");
+        }
+
+        // Check if there are any non-removed volumes in the pod.
+        if (!_volumeDao.findByPod(podId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are storage volumes in this pod.");
+        }
+
+        // Check if there are any non-removed hosts in the pod.
+        if (!_hostDao.findByPodId(podId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are servers in this pod.");
+        }
+
+        // Check if there are any non-removed vms in the pod.
+        if (!_vmInstanceDao.listByPodId(podId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are virtual machines in this pod.");
+        }
+
+        // Check if there are any non-removed clusters in the pod.
+        if (!_clusterDao.listByPodId(podId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are clusters in this pod.");
+        }
+    }
+
+    private void checkPodAttributes(final long podId, final String podName, final long zoneId, final String gateway, final String cidr, final String startIp, final String endIp, final String allocationStateStr,
+            final boolean checkForDuplicates, final boolean skipGatewayOverlapCheck) {
+        if (checkForDuplicates) {
+            // Check if the pod already exists
+            if (validPod(podName, zoneId)) {
+                throw new InvalidParameterValueException("A pod with name: " + podName + " already exists in zone " + zoneId + ". Please specify a different pod name. ");
+            }
+        }
+
+        String cidrAddress;
+        long cidrSize;
+        // Get the individual cidrAddress and cidrSize values, if the CIDR is
+        // valid. If it's not valid, return an error.
+        if (NetUtils.isValidIp4Cidr(cidr)) {
+            cidrAddress = getCidrAddress(cidr);
+            cidrSize = getCidrSize(cidr);
+        } else {
+            throw new InvalidParameterValueException("Please enter a valid CIDR for pod: " + podName);
+        }
+
+        // Check if the IP range is valid
+        checkIpRange(startIp, endIp, cidrAddress, cidrSize);
+
+        // Check if the IP range overlaps with the public ip
+        if(!Strings.isNullOrEmpty(startIp)) {
+            checkOverlapPublicIpRange(zoneId, startIp, endIp);
+        }
+
+        // Check if the gateway is a valid IP address
+        if (!NetUtils.isValidIp4(gateway)) {
+            throw new InvalidParameterValueException("The gateway is not a valid IP address.");
+        }
+
+        // Check if the gateway is in the CIDR subnet
+        if (!NetUtils.getCidrSubNet(gateway, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+            throw new InvalidParameterValueException("The gateway is not in the CIDR subnet.");
+        }
+
+        // Don't allow gateway to overlap with start/endIp
+        if (!skipGatewayOverlapCheck) {
+            if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
+                throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
+            }
+        }
+
+        final String checkPodCIDRs = _configDao.getValue("check.pod.cidrs");
+        if (checkPodCIDRs == null || checkPodCIDRs.trim().isEmpty() || Boolean.parseBoolean(checkPodCIDRs)) {
+            checkPodCidrSubnets(zoneId, podId, cidr);
+        }
+
+        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
+            try {
+                Grouping.AllocationState.valueOf(allocationStateStr);
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationStateStr + "' to a supported state");
+            }
+        }
+    }
+
+    @Override
+    @DB
+    public boolean deletePod(final DeletePodCmd cmd) {
+        final Long podId = cmd.getId();
+
+        // Make sure the pod exists
+        if (!validPod(podId)) {
+            throw new InvalidParameterValueException("A pod with ID: " + podId + " does not exist.");
+        }
+
+        checkIfPodIsDeletable(podId);
+
+        final HostPodVO pod = _podDao.findById(podId);
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                // Delete private ip addresses for the pod if there are any
+                final List<DataCenterIpAddressVO> privateIps = _privateIpAddressDao.listByPodIdDcId(podId, pod.getDataCenterId());
+                if (!privateIps.isEmpty()) {
+                    if (!_privateIpAddressDao.deleteIpAddressByPod(podId)) {
+                        throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
+                    }
+                }
+
+                // Delete link local ip addresses for the pod
+                final List<DataCenterLinkLocalIpAddressVO> localIps = _linkLocalIpAllocDao.listByPodIdDcId(podId, pod.getDataCenterId());
+                if (!localIps.isEmpty()) {
+                    if (!_linkLocalIpAllocDao.deleteIpAddressByPod(podId)) {
+                        throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
+                    }
+                }
+
+                // Delete vlans associated with the pod
+                final List<? extends Vlan> vlans = _networkModel.listPodVlans(podId);
+                if (vlans != null && !vlans.isEmpty()) {
+                    for (final Vlan vlan : vlans) {
+                        _vlanDao.remove(vlan.getId());
+                    }
+                }
+
+                // Delete corresponding capacity records
+                _capacityDao.removeBy(null, null, podId, null, null);
+
+                // Delete the pod
+                if (!_podDao.remove(podId)) {
+                    throw new CloudRuntimeException("Failed to delete pod " + podId);
+                }
+
+                // remove from dedicated resources
+                final DedicatedResourceVO dr = _dedicatedDao.findByPodId(podId);
+                if (dr != null) {
+                    _dedicatedDao.remove(dr.getId());
+                }
+            }
+        });
+
+        return true;
+    }
+
+    /**
+     * Get vlan number from vlan uri
+     * @param vlan
+     * @return
+     */
+    protected String getVlanNumberFromUri(String vlan) {
+        URI uri;
+        try {
+            uri = new URI(vlan);
+            String vlanId = BroadcastDomainType.getValue(uri);
+            if (vlanId == null || !uri.getScheme().equalsIgnoreCase("vlan")) {
+                throw new CloudRuntimeException("Vlan parameter : " + vlan + " is not in valid format");
+            }
+            return vlanId;
+        } catch (URISyntaxException e) {
+            throw new CloudRuntimeException("Invalid vlan parameter: " + vlan + " can't get vlan number from it due to: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @DB
+    public Pod createPodIpRange(final CreateManagementNetworkIpRangeCmd cmd) {
+
+        final Account account = CallContext.current().getCallingAccount();
+
+        if(!_accountMgr.isRootAdmin(account.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Calling account is not root admin: " + account.getId());
+        }
+
+        final long podId = cmd.getPodId();
+        final String gateway = cmd.getGateWay();
+        final String netmask = cmd.getNetmask();
+        final String startIp = cmd.getStartIp();
+        String endIp = cmd.getEndIp();
+        final boolean forSystemVms = cmd.isForSystemVms();
+        String vlan = cmd.getVlan();
+        if (!(Strings.isNullOrEmpty(vlan) || vlan.startsWith(BroadcastDomainType.Vlan.scheme()))) {
+            vlan = BroadcastDomainType.Vlan.toUri(vlan).toString();
+        }
+
+        String vlanNumberFromUri = getVlanNumberFromUri(vlan);
+        final Integer vlanId = vlanNumberFromUri.equals(Vlan.UNTAGGED.toString()) ? null : Integer.parseInt(vlanNumberFromUri);
+
+        final HostPodVO pod = _podDao.findById(podId);
+
+        if(pod == null) {
+            throw new InvalidParameterValueException("Unable to find pod by ID: " + podId);
+        }
+
+        final long zoneId = pod.getDataCenterId();
+
+        if(!NetUtils.isValidIp4(gateway)) {
+            throw new InvalidParameterValueException("The gateway IP address is invalid.");
+        }
+
+        if(!NetUtils.isValidIp4Netmask(netmask)) {
+            throw new InvalidParameterValueException("The netmask IP address is invalid.");
+        }
+
+        if(endIp == null) {
+            endIp = startIp;
+        }
+
+        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+
+        if(!NetUtils.isValidIp4Cidr(cidr)) {
+            throw new InvalidParameterValueException("The CIDR is invalid " + cidr);
+        }
+
+        final String cidrAddress = pod.getCidrAddress();
+        final long cidrSize = pod.getCidrSize();
+
+        // Because each pod has only one Gateway and Netmask.
+        if (!gateway.equals(pod.getGateway())) {
+            throw new InvalidParameterValueException("Multiple gateways for the POD: " + pod.getId() + " are not allowed. The Gateway should be same as the existing Gateway " + pod.getGateway());
+        }
+
+        if (!netmask.equals(NetUtils.getCidrNetmask(cidrSize))) {
+            throw new InvalidParameterValueException("Multiple subnets for the POD: " + pod.getId() + " are not allowed. The Netmask should be same as the existing Netmask " + NetUtils.getCidrNetmask(cidrSize));
+        }
+
+        // Check if the IP range is valid.
+        checkIpRange(startIp, endIp, cidrAddress, cidrSize);
+
+        // Check if the IP range overlaps with the public ip.
+        checkOverlapPublicIpRange(zoneId, startIp, endIp);
+
+        // Check if the gateway is in the CIDR subnet
+        if (!NetUtils.getCidrSubNet(gateway, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+            throw new InvalidParameterValueException("The gateway is not in the CIDR subnet.");
+        }
+
+        if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
+            throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
+        }
+
+        final String[] existingPodIpRanges = pod.getDescription().split(",");
+
+        for(String podIpRange: existingPodIpRanges) {
+            final String[] existingPodIpRange = podIpRange.split("-");
+
+            if (existingPodIpRange.length > 1) {
+                if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
+                    continue;
+                }
+                // Check if the range overlaps with any existing range.
+                if (NetUtils.ipRangesOverlap(startIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
+                    throw new InvalidParameterValueException("The new range overlaps with existing range. Please add a mutually exclusive range.");
+                }
+            }
+        }
+
+        try {
+            final String endIpFinal = endIp;
+
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    String ipRange = pod.getDescription();
+
+                    /*
+                     * POD Description is refactored to:
+                     * <START_IP>-<END_IP>-<FOR_SYSTEM_VMS>-<VLAN>,<START_IP>-<END_IP>-<FOR_SYSTEM_VMS>-<VLAN>,...
+                    */
+                    String range = startIp + "-" + endIpFinal + "-" + (forSystemVms ? "1" : "0") + "-" + (vlanId == null ? DefaultVlanForPodIpRange : vlanId);
+                    if(ipRange != null && !ipRange.isEmpty())
+                        ipRange += ("," + range);
+                    else
+                        ipRange = (range);
+
+                    pod.setDescription(ipRange);
+
+                    HostPodVO lock = null;
+                    try {
+                        lock = _podDao.acquireInLockTable(podId);
+
+                        if (lock == null) {
+                            String msg = "Unable to acquire lock on table to update the ip range of POD: " + pod.getName() + ", Creation failed.";
+                            s_logger.warn(msg);
+                            throw new CloudRuntimeException(msg);
+                        }
+
+                        _podDao.update(podId, pod);
+                    } finally {
+                        if (lock != null) {
+                            _podDao.releaseFromLockTable(podId);
+                        }
+                    }
+
+                    _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, forSystemVms, vlanId);
+                }
+            });
+        } catch (final Exception e) {
+            s_logger.error("Unable to create Pod IP range due to " + e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to create Pod IP range. Please contact Cloud Support.");
+        }
+
+        return pod;
+    }
+
+    @Override
+    @DB
+    public void deletePodIpRange(final DeleteManagementNetworkIpRangeCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
+        final long podId = cmd.getPodId();
+        final String startIp = cmd.getStartIp();
+        final String endIp = cmd.getEndIp();
+        String vlan = cmd.getVlan();
+        try {
+            vlan = BroadcastDomainType.getValue(vlan);
+        } catch (URISyntaxException e) {
+            throw new CloudRuntimeException("Incorrect vlan " + vlan);
+        }
+
+        final HostPodVO pod = _podDao.findById(podId);
+
+        if(pod == null) {
+            throw new InvalidParameterValueException("Unable to find pod by id " + podId);
+        }
+
+        if (startIp == null || !NetUtils.isValidIp4(startIp)) {
+            throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address.");
+        }
+
+        if (endIp == null || !NetUtils.isValidIp4(endIp)) {
+            throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address.");
+        }
+
+        if (NetUtils.ip2Long(startIp) > NetUtils.ip2Long(endIp)) {
+            throw new InvalidParameterValueException("The start IP address must have a lower value than the end IP address.");
+        }
+
+        for(long ipAddr = NetUtils.ip2Long(startIp); ipAddr <= NetUtils.ip2Long(endIp); ipAddr++) {
+            if(_privateIpAddressDao.countIpAddressUsage(NetUtils.long2Ip(ipAddr), podId, pod.getDataCenterId(), true) > 0) {
+                throw new CloudRuntimeException("Some IPs of the range has been allocated, so it cannot be deleted.");
+            }
+        }
+
+        final String[] existingPodIpRanges = pod.getDescription().split(",");
+
+        if(existingPodIpRanges.length == 0) {
+            throw new InvalidParameterValueException("The IP range cannot be found. As the existing IP range is empty.");
+        }
+
+        final String[] newPodIpRanges = new String[existingPodIpRanges.length-1];
+        int index = existingPodIpRanges.length-2;
+        boolean foundRange = false;
+
+        for(String podIpRange: existingPodIpRanges) {
+            final String[] existingPodIpRange = podIpRange.split("-");
+
+            if(existingPodIpRange.length > 1) {
+                if (startIp.equals(existingPodIpRange[0]) && endIp.equals(existingPodIpRange[1]) &&
+                        (existingPodIpRange.length > 3 ? vlan.equals(existingPodIpRange[3]) : vlan.equals(DefaultVlanForPodIpRange))) {
+                    foundRange = true;
+                } else if (index >= 0) {
+                    newPodIpRanges[index--] = (existingPodIpRange[0] + "-" + existingPodIpRange[1] + "-" +
+                            (existingPodIpRange.length > 2 ? existingPodIpRange[2] : DefaultForSystemVmsForPodIpRange) + "-" +
+                            (existingPodIpRange.length > 3 ? existingPodIpRange[3] : DefaultVlanForPodIpRange));
+                }
+            }
+        }
+
+        if(!foundRange) {
+            throw new InvalidParameterValueException("The input IP range: " + startIp + "-" + endIp + " of pod: " + podId + "is not present. Please input an existing range.");
+        }
+
+        final StringBuilder newPodIpRange = new StringBuilder();
+        boolean first = true;
+        for (String podIpRange : newPodIpRanges) {
+            if (first)
+                first = false;
+            else
+                newPodIpRange.append(",");
+
+            newPodIpRange.append(podIpRange);
+        }
+
+        try {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    pod.setDescription(newPodIpRange.toString());
+
+                    HostPodVO lock = null;
+                    try {
+                        lock = _podDao.acquireInLockTable(podId);
+
+                        if (lock == null) {
+                            String msg = "Unable to acquire lock on table to update the ip range of POD: " + pod.getName() + ", Deletion failed.";
+                            s_logger.warn(msg);
+                            throw new CloudRuntimeException(msg);
+                        }
+
+                        _podDao.update(podId, pod);
+                    } finally {
+                        if (lock != null) {
+                            _podDao.releaseFromLockTable(podId);
+                        }
+                    }
+
+                    for(long ipAddr = NetUtils.ip2Long(startIp); ipAddr <= NetUtils.ip2Long(endIp); ipAddr++) {
+                        if (!_privateIpAddressDao.deleteIpAddressByPodDc(NetUtils.long2Ip(ipAddr), podId, pod.getDataCenterId())) {
+                            throw new CloudRuntimeException("Failed to cleanup private ip address: " + NetUtils.long2Ip(ipAddr) + " of Pod: " + podId + " DC: " + pod.getDataCenterId());
+                        }
+                    }
+                }
+            });
+        } catch (final Exception e) {
+            s_logger.error("Unable to delete Pod " + podId + "IP range due to " + e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to delete Pod " + podId + "IP range. Please contact Cloud Support.");
+        }
+    }
+
+    @Override
+    public Pod editPod(final UpdatePodCmd cmd) {
+        return editPod(cmd.getId(), cmd.getPodName(), null, null, cmd.getGateway(), cmd.getNetmask(), cmd.getAllocationState());
+    }
+
+    @Override
+    @DB
+    public Pod editPod(final long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr) {
+
+        // verify parameters
+        final HostPodVO pod = _podDao.findById(id);
+
+        if (pod == null) {
+            throw new InvalidParameterValueException("Unable to find pod by id " + id);
+        }
+
+        // If the gateway, CIDR, private IP range is being changed, check if the
+        // pod has allocated private IP addresses
+        if (podHasAllocatedPrivateIPs(id)) {
+
+            if (!Strings.isNullOrEmpty(netmask)) {
+                final long newCidr = NetUtils.getCidrSize(netmask);
+                final long oldCidr = pod.getCidrSize();
+
+                if (newCidr > oldCidr) {
+                    throw new CloudRuntimeException("The specified pod has allocated private IP addresses, so its IP address range can be extended only");
+                }
+            }
+        }
+
+        if (gateway == null) {
+            gateway = pod.getGateway();
+        }
+
+        if (netmask == null) {
+            netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
+        }
+
+        final String oldPodName = pod.getName();
+        if (name == null) {
+            name = oldPodName;
+        }
+
+        if (allocationStateStr == null) {
+            allocationStateStr = pod.getAllocationState().toString();
+        }
+
+        // Verify pod's attributes
+        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+        final boolean checkForDuplicates = !oldPodName.equals(name);
+        checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, true);
+
+        // Valid check is already done in checkPodAttributes method.
+        final String cidrAddress = getCidrAddress(cidr);
+        final long cidrSize = getCidrSize(cidr);
+
+        // Check if start IP and end IP of all the ranges lie in the CIDR subnet.
+        final String[] existingPodIpRanges = pod.getDescription().split(",");
+
+        for(String podIpRange: existingPodIpRanges) {
+            final String[] existingPodIpRange = podIpRange.split("-");
+
+            if (existingPodIpRange.length > 1) {
+                if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
+                    continue;
+                }
+
+                if (!NetUtils.getCidrSubNet(existingPodIpRange[0], cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+                    throw new InvalidParameterValueException("The start address of the some IP range is not in the CIDR subnet.");
+                }
+
+                if (!NetUtils.getCidrSubNet(existingPodIpRange[1], cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+                    throw new InvalidParameterValueException("The end address of the some IP range is not in the CIDR subnet.");
+                }
+
+                if (NetUtils.ipRangesOverlap(existingPodIpRange[0], existingPodIpRange[1], gateway, gateway)) {
+                    throw new InvalidParameterValueException("The gateway shouldn't overlap some start/end ip addresses");
+                }
+            }
+        }
+
+        try {
+            final String allocationStateStrFinal = allocationStateStr;
+            final String nameFinal = name;
+            final String gatewayFinal = gateway;
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    final long zoneId = pod.getDataCenterId();
+
+                    pod.setName(nameFinal);
+                    pod.setDataCenterId(zoneId);
+                    pod.setGateway(gatewayFinal);
+                    pod.setCidrAddress(getCidrAddress(cidr));
+                    pod.setCidrSize(getCidrSize(cidr));
+
+                    Grouping.AllocationState allocationState = null;
+                    if (allocationStateStrFinal != null && !allocationStateStrFinal.isEmpty()) {
+                        allocationState = Grouping.AllocationState.valueOf(allocationStateStrFinal);
+                        pod.setAllocationState(allocationState);
+                    }
+
+                    _podDao.update(id, pod);
+                }
+            });
+        } catch (final Exception e) {
+            s_logger.error("Unable to edit pod due to " + e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to edit pod. Please contact Cloud Support.");
+        }
+
+        return pod;
+    }
+
+    @Override
+    public Pod createPod(final long zoneId, final String name, final String startIp, final String endIp, final String gateway, final String netmask, String allocationState) {
+        // Check if the gateway is a valid IP address
+        if (!NetUtils.isValidIp4(gateway)) {
+            throw new InvalidParameterValueException("The gateway is invalid");
+        }
+
+        if (!NetUtils.isValidIp4Netmask(netmask)) {
+            throw new InvalidParameterValueException("The netmask is invalid");
+        }
+
+        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+
+        final Long userId = CallContext.current().getCallingUserId();
+
+        if (allocationState == null) {
+            allocationState = Grouping.AllocationState.Enabled.toString();
+        }
+        return createPod(userId.longValue(), name, zoneId, gateway, cidr, startIp, endIp, allocationState, false);
+    }
+
+    @Override
+    @DB
+    public HostPodVO createPod(final long userId, final String podName, final long zoneId, final String gateway, final String cidr, final String startIp, String endIp, final String allocationStateStr,
+            final boolean skipGatewayOverlapCheck) {
+
+        // Check if the zone is valid
+        if (!validZone(zoneId)) {
+            throw new InvalidParameterValueException("Please specify a valid zone.");
+        }
+
+        // Check if zone is disabled
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        final Account account = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
+                && !_accountMgr.isRootAdmin(account.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+        }
+
+        final String cidrAddress = getCidrAddress(cidr);
+        final int cidrSize = getCidrSize(cidr);
+
+        // endIp is an optional parameter; if not specified - default it to the
+        // end ip of the pod's cidr
+        if (!Strings.isNullOrEmpty(startIp)) {
+            if (endIp == null) {
+                endIp = NetUtils.getIpRangeEndIpFromCidr(cidrAddress, cidrSize);
+            }
+        }
+
+        // Validate new pod settings
+        checkPodAttributes(-1, podName, zoneId, gateway, cidr, startIp, endIp, allocationStateStr, true, skipGatewayOverlapCheck);
+
+        // Create the new pod in the database
+        String ipRange;
+
+        if (!Strings.isNullOrEmpty(startIp)) {
+            ipRange = startIp + "-" + endIp + "-" + DefaultForSystemVmsForPodIpRange + "-" + DefaultVlanForPodIpRange;
+        } else {
+            throw new InvalidParameterValueException("Start ip is required parameter");
+        }
+
+        final HostPodVO podFinal = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange);
+
+        Grouping.AllocationState allocationState = null;
+        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
+            allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
+            podFinal.setAllocationState(allocationState);
+        }
+
+        final String endIpFinal = endIp;
+        return Transaction.execute(new TransactionCallback<HostPodVO>() {
+            @Override
+            public HostPodVO doInTransaction(final TransactionStatus status) {
+
+                final HostPodVO pod = _podDao.persist(podFinal);
+
+                if (!Strings.isNullOrEmpty(startIp)) {
+                    _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, false, null);
+                }
+
+                final String[] linkLocalIpRanges = getLinkLocalIPRange();
+                if (linkLocalIpRanges != null) {
+                    _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
+                }
+
+                return pod;
+            }
+        });
+    }
+
+    @DB
+    protected void checkIfZoneIsDeletable(final long zoneId) {
+        final String errorMsg = "The zone cannot be deleted because ";
+
+
+        // Check if there are any non-removed hosts in the zone.
+        if (!_hostDao.listByDataCenterId(zoneId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are servers in this zone.");
+        }
+
+        // Check if there are any non-removed pods in the zone.
+        if (!_podDao.listByDataCenterId(zoneId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are pods in this zone.");
+        }
+
+        // Check if there are allocated private IP addresses in the zone.
+        if (_privateIpAddressDao.countIPs(zoneId, true) != 0) {
+            throw new CloudRuntimeException(errorMsg + "there are private IP addresses allocated in this zone.");
+        }
+
+        // Check if there are allocated public IP addresses in the zone.
+        if (_publicIpAddressDao.countIPs(zoneId, true) != 0) {
+            throw new CloudRuntimeException(errorMsg + "there are public IP addresses allocated in this zone.");
+        }
+
+        // Check if there are any non-removed vms in the zone.
+        if (!_vmInstanceDao.listByZoneId(zoneId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are virtual machines in this zone.");
+        }
+
+        // Check if there are any non-removed volumes in the zone.
+        if (!_volumeDao.findByDc(zoneId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are storage volumes in this zone.");
+        }
+
+        // Check if there are any non-removed physical networks in the zone.
+        if (!_physicalNetworkDao.listByZone(zoneId).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are physical networks in this zone.");
+        }
+
+        //check if there are any secondary stores attached to the zone
+        if(!_imageStoreDao.findByScope(new ZoneScope(zoneId)).isEmpty()) {
+            throw new CloudRuntimeException(errorMsg + "there are Secondary storages in this zone");
+        }
+
+        // Check if there are any non-removed VMware datacenters in the zone.
+        //if (_vmwareDatacenterZoneMapDao.findByZoneId(zoneId) != null) {
+        //    throw new CloudRuntimeException(errorMsg + "there are VMware datacenters in this zone.");
+        //}
+    }
+
+    private void checkZoneParameters(final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final boolean checkForDuplicates, final Long domainId,
+            final String allocationStateStr, final String ip6Dns1, final String ip6Dns2) {
+        if (checkForDuplicates) {
+            // Check if a zone with the specified name already exists
+            if (validZone(zoneName)) {
+                throw new InvalidParameterValueException("A zone with that name already exists. Please specify a unique zone name.");
+            }
+        }
+
+        // check if valid domain
+        if (domainId != null) {
+            final DomainVO domain = _domainDao.findById(domainId);
+
+            if (domain == null) {
+                throw new InvalidParameterValueException("Please specify a valid domain id");
+            }
+        }
+
+        // Check IP validity for DNS addresses
+        // Empty strings is a valid input -- hence the length check
+        if (dns1 != null && dns1.length() > 0 && !NetUtils.isValidIp4(dns1)) {
+            throw new InvalidParameterValueException("Please enter a valid IP address for DNS1");
+        }
+
+        if (dns2 != null && dns2.length() > 0 && !NetUtils.isValidIp4(dns2)) {
+            throw new InvalidParameterValueException("Please enter a valid IP address for DNS2");
+        }
+
+        if (internalDns1 != null && internalDns1.length() > 0 && !NetUtils.isValidIp4(internalDns1)) {
+            throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS1");
+        }
+
+        if (internalDns2 != null && internalDns2.length() > 0 && !NetUtils.isValidIp4(internalDns2)) {
+            throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS2");
+        }
+
+        if (ip6Dns1 != null && ip6Dns1.length() > 0 && !NetUtils.isValidIp6(ip6Dns1)) {
+            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS1");
+        }
+
+        if (ip6Dns2 != null && ip6Dns2.length() > 0 && !NetUtils.isValidIp6(ip6Dns2)) {
+            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS2");
+        }
+
+        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
+            try {
+                Grouping.AllocationState.valueOf(allocationStateStr);
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationStateStr + "' to a supported state");
+            }
+        }
+    }
+
+    private void checkIpRange(final String startIp, final String endIp, final String cidrAddress, final long cidrSize) {
+        //Checking not null for start IP as well. Previously we assumed to be not null always.
+        //But the check is required for the change in updatePod API.
+        if (!Strings.isNullOrEmpty(startIp) && !NetUtils.isValidIp4(startIp)) {
+            throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address.");
+        }
+
+        if (!Strings.isNullOrEmpty(endIp) && !NetUtils.isValidIp4(endIp)) {
+            throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address.");
+        }
+
+        //Not null check is required for the change in updatePod API.
+        if (!Strings.isNullOrEmpty(startIp) && !NetUtils.getCidrSubNet(startIp, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+            throw new InvalidParameterValueException("The start address of the IP range is not in the CIDR subnet.");
+        }
+
+        if (!Strings.isNullOrEmpty(endIp) && !NetUtils.getCidrSubNet(endIp, cidrSize).equalsIgnoreCase(NetUtils.getCidrSubNet(cidrAddress, cidrSize))) {
+            throw new InvalidParameterValueException("The end address of the IP range is not in the CIDR subnet.");
+        }
+
+        if (!Strings.isNullOrEmpty(endIp) && NetUtils.ip2Long(startIp) > NetUtils.ip2Long(endIp)) {
+            throw new InvalidParameterValueException("The start IP address must have a lower value than the end IP address.");
+        }
+
+    }
+
+    private void checkOverlapPublicIpRange(final Long zoneId, final String startIp, final String endIp) {
+        final long privateStartIp = NetUtils.ip2Long(startIp);
+        final long privateEndIp = NetUtils.ip2Long(endIp);
+
+        final List<IPAddressVO> existingPublicIPs = _publicIpAddressDao.listByDcId(zoneId);
+        for (final IPAddressVO publicIPVO : existingPublicIPs) {
+            final long publicIP = NetUtils.ip2Long(publicIPVO.getAddress().addr());
+            if (publicIP >= privateStartIp && publicIP <= privateEndIp) {
+                throw new InvalidParameterValueException("The Start IP and endIP address range overlap with Public IP :" + publicIPVO.getAddress().addr());
+            }
+        }
+    }
+
+    private void checkOverlapPrivateIpRange(final Long zoneId, final String startIp, final String endIp) {
+
+        final List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
+        for (final HostPodVO hostPod : podsInZone) {
+            final String[] existingPodIpRanges = hostPod.getDescription().split(",");
+
+            for(String podIpRange: existingPodIpRanges) {
+                final String[] existingPodIpRange = podIpRange.split("-");
+
+                if (existingPodIpRange.length > 1) {
+                    if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) {
+                        continue;
+                    }
+
+                    if (NetUtils.ipRangesOverlap(startIp, endIp, existingPodIpRange[0], existingPodIpRange[1])) {
+                        throw new InvalidParameterValueException("The Start IP and EndIP address range overlap with private IP :" + existingPodIpRange[0] + ":" + existingPodIpRange[1]);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_ZONE_DELETE, eventDescription = "deleting zone", async = false)
+    public boolean deleteZone(final DeleteZoneCmd cmd) {
+
+        final Long zoneId = cmd.getId();
+
+        // Make sure the zone exists
+        if (!validZone(zoneId)) {
+            throw new InvalidParameterValueException("A zone with ID: " + zoneId + " does not exist.");
+        }
+
+        checkIfZoneIsDeletable(zoneId);
+
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(final TransactionStatus status) {
+                // delete vlans for this zone
+                final List<VlanVO> vlans = _vlanDao.listByZone(zoneId);
+                for (final VlanVO vlan : vlans) {
+                    _vlanDao.remove(vlan.getId());
+                }
+
+                final boolean success = _zoneDao.remove(zoneId);
+
+                if (success) {
+                    // delete all capacity records for the zone
+                    _capacityDao.removeBy(null, zoneId, null, null, null);
+                    // remove from dedicated resources
+                    final DedicatedResourceVO dr = _dedicatedDao.findByZoneId(zoneId);
+                    if (dr != null) {
+                        _dedicatedDao.remove(dr.getId());
+                        // find the group associated and check if there are any more
+                        // resources under that group
+                        final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(dr.getAffinityGroupId());
+                        if (resourcesInGroup.isEmpty()) {
+                            // delete the group
+                            _affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null, null);
+                        }
+                    }
+                }
+
+                return success;
+            }
+        });
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "editing zone", async = false)
+    public DataCenter editZone(final UpdateZoneCmd cmd) {
+        // Parameter validation as from execute() method in V1
+        final Long zoneId = cmd.getId();
+        String zoneName = cmd.getZoneName();
+        String dns1 = cmd.getDns1();
+        String dns2 = cmd.getDns2();
+        String ip6Dns1 = cmd.getIp6Dns1();
+        String ip6Dns2 = cmd.getIp6Dns2();
+        String internalDns1 = cmd.getInternalDns1();
+        String internalDns2 = cmd.getInternalDns2();
+        String guestCidr = cmd.getGuestCidrAddress();
+        final List<String> dnsSearchOrder = cmd.getDnsSearchOrder();
+        final Boolean isPublic = cmd.isPublic();
+        final String allocationStateStr = cmd.getAllocationState();
+        final String dhcpProvider = cmd.getDhcpProvider();
+        final Map<?, ?> detailsMap = cmd.getDetails();
+        final String networkDomain = cmd.getDomain();
+        final Boolean localStorageEnabled = cmd.getLocalStorageEnabled();
+
+        final Map<String, String> newDetails = new HashMap<String, String>();
+        if (detailsMap != null) {
+            final Collection<?> zoneDetailsCollection = detailsMap.values();
+            final Iterator<?> iter = zoneDetailsCollection.iterator();
+            while (iter.hasNext()) {
+                final HashMap<?, ?> detail = (HashMap<?, ?>)iter.next();
+                final String key = (String)detail.get("key");
+                final String value = (String)detail.get("value");
+                if (key == null || value == null) {
+                    throw new InvalidParameterValueException(
+                            "Invalid Zone Detail specified, fields 'key' and 'value' cannot be null, please specify details in the form:  details[0].key=XXX&details[0].value=YYY");
+                }
+                newDetails.put(key, value);
+            }
+        }
+
+        // add the domain prefix list to details if not null
+        if (dnsSearchOrder != null) {
+            for (final String dom : dnsSearchOrder) {
+                if (!NetUtils.verifyDomainName(dom)) {
+                    throw new InvalidParameterValueException(
+                            "Invalid network domain suffixes. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                    + "and the hyphen ('-'); can't start or end with \"-\"");
+                }
+            }
+            newDetails.put(ZoneConfig.DnsSearchOrder.getName(), StringUtils.join(dnsSearchOrder, ","));
+        }
+
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("unable to find zone by id " + zoneId);
+        }
+
+        if (zoneName == null) {
+            zoneName = zone.getName();
+        }
+
+        if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
+            throw new InvalidParameterValueException("Please enter a valid guest cidr");
+        }
+
+        // Make sure the zone exists
+        if (!validZone(zoneId)) {
+            throw new InvalidParameterValueException("A zone with ID: " + zoneId + " does not exist.");
+        }
+
+        final String oldZoneName = zone.getName();
+
+        if (zoneName == null) {
+            zoneName = oldZoneName;
+        }
+
+        if (dns1 == null) {
+            dns1 = zone.getDns1();
+        }
+
+        if (dns2 == null) {
+            dns2 = zone.getDns2();
+        }
+
+        if (ip6Dns1 == null) {
+            ip6Dns1 = zone.getIp6Dns1();
+        }
+
+        if (ip6Dns2 == null) {
+            ip6Dns2 = zone.getIp6Dns2();
+        }
+
+        if (internalDns1 == null) {
+            internalDns1 = zone.getInternalDns1();
+        }
+
+        if (internalDns2 == null) {
+            internalDns2 = zone.getInternalDns2();
+        }
+
+        if (guestCidr == null) {
+            guestCidr = zone.getGuestNetworkCidr();
+        }
+
+        // validate network domain
+        if (networkDomain != null && !networkDomain.isEmpty()) {
+            if (!NetUtils.verifyDomainName(networkDomain)) {
+                throw new InvalidParameterValueException(
+                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+            }
+        }
+
+        final boolean checkForDuplicates = !zoneName.equals(oldZoneName);
+        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, checkForDuplicates, null, allocationStateStr, ip6Dns1, ip6Dns2);// not allowing updating
+        // domain associated with
+        // a zone, once created
+
+        zone.setName(zoneName);
+        zone.setDns1(dns1);
+        zone.setDns2(dns2);
+        zone.setIp6Dns1(ip6Dns1);
+        zone.setIp6Dns2(ip6Dns2);
+        zone.setInternalDns1(internalDns1);
+        zone.setInternalDns2(internalDns2);
+        zone.setGuestNetworkCidr(guestCidr);
+        if (localStorageEnabled != null) {
+            zone.setLocalStorageEnabled(localStorageEnabled.booleanValue());
+        }
+
+        if (networkDomain != null) {
+            if (networkDomain.isEmpty()) {
+                zone.setDomain(null);
+            } else {
+                zone.setDomain(networkDomain);
+            }
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                final Map<String, String> updatedDetails = new HashMap<String, String>();
+                _zoneDao.loadDetails(zone);
+                if (zone.getDetails() != null) {
+                    updatedDetails.putAll(zone.getDetails());
+                }
+                updatedDetails.putAll(newDetails);
+                zone.setDetails(updatedDetails);
+
+                if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
+                    final Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
+
+                    if (allocationState == Grouping.AllocationState.Enabled) {
+                        // check if zone has necessary trafficTypes before enabling
+                        try {
+                            PhysicalNetwork mgmtPhyNetwork;
+                            // zone should have a physical network with management
+                            // traffiType
+                            mgmtPhyNetwork = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Management);
+                            if (NetworkType.Advanced == zone.getNetworkType() && !zone.isSecurityGroupEnabled()) {
+                                // advanced zone without SG should have a physical
+                                // network with public Thpe
+                                _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public);
+                            }
+
+                            try {
+                                _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage);
+                            } catch (final InvalidParameterValueException noStorage) {
+                                final PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
+                                _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(),
+                                        mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(),
+                                        mgmtTraffic.getHypervNetworkLabel(), mgmtTraffic.getOvm3NetworkLabel());
+                                s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId()
+                                        + " with same configure of management traffic type");
+                            }
+                        } catch (final InvalidParameterValueException ex) {
+                            throw new InvalidParameterValueException("Cannot enable this Zone since: " + ex.getMessage());
+                        }
+                    }
+                    zone.setAllocationState(allocationState);
+                }
+
+                if (dhcpProvider != null) {
+                    zone.setDhcpProvider(dhcpProvider);
+                }
+
+                // update a private zone to public; not vice versa
+                if (isPublic != null && isPublic) {
+                    zone.setDomainId(null);
+                    zone.setDomain(null);
+
+                    // release the dedication for this zone
+                    final DedicatedResourceVO resource = _dedicatedDao.findByZoneId(zoneId);
+                    Long resourceId = null;
+                    if (resource != null) {
+                        resourceId = resource.getId();
+                        if (!_dedicatedDao.remove(resourceId)) {
+                            throw new CloudRuntimeException("Failed to delete dedicated Zone Resource " + resourceId);
+                        }
+                        // find the group associated and check if there are any more
+                        // resources under that group
+                        final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
+                        if (resourcesInGroup.isEmpty()) {
+                            // delete the group
+                            _affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
+                        }
+                    }
+                }
+
+                if (!_zoneDao.update(zoneId, zone)) {
+                    throw new CloudRuntimeException("Failed to edit zone. Please contact Cloud Support.");
+                }
+            }
+        });
+
+        return zone;
+    }
+
+    @Override
+    @DB
+    public DataCenterVO createZone(final long userId, final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final String guestCidr, final String domain,
+            final Long domainId, final NetworkType zoneType, final String allocationStateStr, final String networkDomain, final boolean isSecurityGroupEnabled, final boolean isLocalStorageEnabled,
+            final String ip6Dns1, final String ip6Dns2) {
+
+        // checking the following params outside checkzoneparams method as we do
+        // not use these params for updatezone
+        // hence the method below is generic to check for common params
+        if (guestCidr != null && !NetUtils.validateGuestCidr(guestCidr)) {
+            throw new InvalidParameterValueException("Please enter a valid guest cidr");
+        }
+
+        // Validate network domain
+        if (networkDomain != null) {
+            if (!NetUtils.verifyDomainName(networkDomain)) {
+                throw new InvalidParameterValueException(
+                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+            }
+        }
+
+        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, true, domainId, allocationStateStr, ip6Dns1, ip6Dns2);
+
+        final byte[] bytes = (zoneName + System.currentTimeMillis()).getBytes();
+        final String zoneToken = UUID.nameUUIDFromBytes(bytes).toString();
+
+        // Create the new zone in the database
+        final DataCenterVO zoneFinal = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain,
+                isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
+        if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
+            final Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
+            zoneFinal.setAllocationState(allocationState);
+        } else {
+            // Zone will be disabled since 3.0. Admin should enable it after
+            // physical network and providers setup.
+            zoneFinal.setAllocationState(Grouping.AllocationState.Disabled);
+        }
+
+        return Transaction.execute(new TransactionCallback<DataCenterVO>() {
+            @Override
+            public DataCenterVO doInTransaction(final TransactionStatus status) {
+                final DataCenterVO zone = _zoneDao.persist(zoneFinal);
+                CallContext.current().putContextParameter(DataCenter.class, zone.getUuid());
+                if (domainId != null) {
+                    // zone is explicitly dedicated to this domain
+                    // create affinity group associated and dedicate the zone.
+                    final AffinityGroup group = createDedicatedAffinityGroup(null, domainId, null);
+                    final DedicatedResourceVO dedicatedResource = new DedicatedResourceVO(zone.getId(), null, null, null, domainId, null, group.getId());
+                    _dedicatedDao.persist(dedicatedResource);
+                }
+
+                // Create default system networks
+                createDefaultSystemNetworks(zone.getId());
+
+                return zone;
+            }
+        });
+    }
+
+    private AffinityGroup createDedicatedAffinityGroup(String affinityGroupName, final Long domainId, final Long accountId) {
+        if (affinityGroupName == null) {
+            // default to a groupname with account/domain information
+            affinityGroupName = "ZoneDedicatedGrp-domain-" + domainId + (accountId != null ? "-acct-" + accountId : "");
+        }
+
+        AffinityGroup group = null;
+        String accountName = null;
+
+        if (accountId != null) {
+            final AccountVO account = _accountDao.findById(accountId);
+            accountName = account.getAccountName();
+
+            group = _affinityGroupDao.findByAccountAndName(accountId, affinityGroupName);
+            if (group != null) {
+                return group;
+            }
+        } else {
+            // domain level group
+            group = _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName);
+            if (group != null) {
+                return group;
+            }
+        }
+
+        group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
+
+        return group;
+
+    }
+
+    @Override
+    public void createDefaultSystemNetworks(final long zoneId) throws ConcurrentOperationException {
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        final String networkDomain = null;
+        // Create public, management, control and storage networks as a part of
+        // the zone creation
+        if (zone != null) {
+            final List<NetworkOfferingVO> ntwkOff = _networkOfferingDao.listSystemNetworkOfferings();
+
+            for (final NetworkOfferingVO offering : ntwkOff) {
+                final DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null, null, null);
+                final NetworkVO userNetwork = new NetworkVO();
+
+                final Account systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
+
+                BroadcastDomainType broadcastDomainType = null;
+                if (offering.getTrafficType() == TrafficType.Management) {
+                    broadcastDomainType = BroadcastDomainType.Native;
+                } else if (offering.getTrafficType() == TrafficType.Control) {
+                    broadcastDomainType = BroadcastDomainType.LinkLocal;
+                } else if (offering.getTrafficType() == TrafficType.Public) {
+                    if (zone.getNetworkType() == NetworkType.Advanced && !zone.isSecurityGroupEnabled() || zone.getNetworkType() == NetworkType.Basic) {
+                        broadcastDomainType = BroadcastDomainType.Vlan;
+                    } else {
+                        continue; // so broadcastDomainType remains null! why have None/Undecided/UnKnown?
+                    }
+                } else if (offering.getTrafficType() == TrafficType.Guest) {
+                    continue;
+                }
+
+                userNetwork.setBroadcastDomainType(broadcastDomainType);
+                userNetwork.setNetworkDomain(networkDomain);
+                _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, Domain.ROOT_DOMAIN, null, null, null, true);
+            }
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ZONE_CREATE, eventDescription = "creating zone", async = false)
+    public DataCenter createZone(final CreateZoneCmd cmd) {
+        // grab parameters from the command
+        final Long userId = CallContext.current().getCallingUserId();
+        final String zoneName = cmd.getZoneName();
+        final String dns1 = cmd.getDns1();
+        final String dns2 = cmd.getDns2();
+        final String ip6Dns1 = cmd.getIp6Dns1();
+        final String ip6Dns2 = cmd.getIp6Dns2();
+        final String internalDns1 = cmd.getInternalDns1();
+        final String internalDns2 = cmd.getInternalDns2();
+        final String guestCidr = cmd.getGuestCidrAddress();
+        final Long domainId = cmd.getDomainId();
+        final String type = cmd.getNetworkType();
+        Boolean isBasic = false;
+        String allocationState = cmd.getAllocationState();
+        final String networkDomain = cmd.getDomain();
+        boolean isSecurityGroupEnabled = cmd.getSecuritygroupenabled();
+        final boolean isLocalStorageEnabled = cmd.getLocalStorageEnabled();
+
+        if (allocationState == null) {
+            allocationState = Grouping.AllocationState.Disabled.toString();
+        }
+
+        if (!type.equalsIgnoreCase(NetworkType.Basic.toString()) && !type.equalsIgnoreCase(NetworkType.Advanced.toString())) {
+            throw new InvalidParameterValueException("Invalid zone type; only Advanced and Basic values are supported");
+        } else if (type.equalsIgnoreCase(NetworkType.Basic.toString())) {
+            isBasic = true;
+        }
+
+        final NetworkType zoneType = isBasic ? NetworkType.Basic : NetworkType.Advanced;
+
+        // error out when the parameter specified for Basic zone
+        if (zoneType == NetworkType.Basic && guestCidr != null) {
+            throw new InvalidParameterValueException("guestCidrAddress parameter is not supported for Basic zone");
+        }
+
+        DomainVO domainVO = null;
+
+        if (domainId != null) {
+            domainVO = _domainDao.findById(domainId);
+        }
+
+        if (zoneType == NetworkType.Basic) {
+            isSecurityGroupEnabled = true;
+        }
+
+        return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, allocationState,
+                networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering")
+    public ServiceOffering createServiceOffering(final CreateServiceOfferingCmd cmd) {
+        final Long userId = CallContext.current().getCallingUserId();
+
+        final String name = cmd.getServiceOfferingName();
+        if (name == null || name.length() == 0) {
+            throw new InvalidParameterValueException("Failed to create service offering: specify the name that has non-zero length");
+        }
+
+        final String displayText = cmd.getDisplayText();
+        if (displayText == null || displayText.length() == 0) {
+            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the display text that has non-zero length");
+        }
+
+        final Integer cpuNumber = cmd.getCpuNumber();
+        final Integer cpuSpeed = cmd.getCpuSpeed();
+        final Integer memory = cmd.getMemory();
+
+        //restricting the createserviceoffering to allow setting all or none of the dynamic parameters to null
+        if (cpuNumber == null || cpuSpeed == null || memory == null) {
+            if (cpuNumber != null || cpuSpeed != null || memory != null) {
+                throw new InvalidParameterValueException("For creating a custom compute offering cpu, cpu speed and memory all should be null");
+            }
+        }
+
+        if (cpuNumber != null && (cpuNumber.intValue() <= 0 || cpuNumber.longValue() > Integer.MAX_VALUE)) {
+            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu number value between 1 and " + Integer.MAX_VALUE);
+        }
+        if (cpuSpeed != null && (cpuSpeed.intValue() < 0 || cpuSpeed.longValue() > Integer.MAX_VALUE)) {
+            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the cpu speed value between 0 and " + Integer.MAX_VALUE);
+        }
+        if (memory != null && (memory.intValue() < 32 || memory.longValue() > Integer.MAX_VALUE)) {
+            throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the memory value between 32 and " + Integer.MAX_VALUE + " MB");
+        }
+
+        // check if valid domain
+        if (cmd.getDomainId() != null && _domainDao.findById(cmd.getDomainId()) == null) {
+            throw new InvalidParameterValueException("Please specify a valid domain id");
+        }
+
+        final Boolean offerHA = cmd.isOfferHa();
+
+        boolean localStorageRequired = false;
+        final String storageType = cmd.getStorageType();
+        if (storageType != null) {
+            if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.local.toString())) {
+                if(offerHA) {
+                    throw new InvalidParameterValueException("HA offering with local storage is not supported. ");
+                }
+                localStorageRequired = true;
+            } else if (!storageType.equalsIgnoreCase(ServiceOffering.StorageType.shared.toString())) {
+                throw new InvalidParameterValueException("Invalid storage type " + storageType + " specified, valid types are: 'local' and 'shared'");
+            }
+        }
+
+        final Boolean limitCpuUse = cmd.isLimitCpuUse();
+        final Boolean volatileVm = cmd.isVolatileVm();
+
+        final String vmTypeString = cmd.getSystemVmType();
+        VirtualMachine.Type vmType = null;
+        boolean allowNetworkRate = false;
+
+        Boolean isCustomizedIops;
+
+        if (cmd.isSystem()) {
+            if (vmTypeString == null || VirtualMachine.Type.DomainRouter.toString().toLowerCase().equals(vmTypeString)) {
+                vmType = VirtualMachine.Type.DomainRouter;
+                allowNetworkRate = true;
+            } else if (VirtualMachine.Type.ConsoleProxy.toString().toLowerCase().equals(vmTypeString)) {
+                vmType = VirtualMachine.Type.ConsoleProxy;
+            } else if (VirtualMachine.Type.SecondaryStorageVm.toString().toLowerCase().equals(vmTypeString)) {
+                vmType = VirtualMachine.Type.SecondaryStorageVm;
+            } else if (VirtualMachine.Type.InternalLoadBalancerVm.toString().toLowerCase().equals(vmTypeString)) {
+                vmType = VirtualMachine.Type.InternalLoadBalancerVm;
+            } else {
+                throw new InvalidParameterValueException("Invalid systemVmType. Supported types are: " + VirtualMachine.Type.DomainRouter + ", " + VirtualMachine.Type.ConsoleProxy
+                        + ", " + VirtualMachine.Type.SecondaryStorageVm);
+            }
+
+            if (cmd.isCustomizedIops() != null) {
+                throw new InvalidParameterValueException("Customized IOPS is not a valid parameter for a system VM.");
+            }
+
+            isCustomizedIops = false;
+
+            if (cmd.getHypervisorSnapshotReserve() != null) {
+                throw new InvalidParameterValueException("Hypervisor snapshot reserve is not a valid parameter for a system VM.");
+            }
+        } else {
+            allowNetworkRate = true;
+            isCustomizedIops = cmd.isCustomizedIops();
+        }
+
+        if (cmd.getNetworkRate() != null) {
+            if(!allowNetworkRate) {
+                throw new InvalidParameterValueException("Network rate can be specified only for non-System offering and system offerings having \"domainrouter\" systemvmtype");
+            }
+            if(cmd.getNetworkRate().intValue() < 0) {
+                throw new InvalidParameterValueException("Failed to create service offering " + name + ": specify the network rate value more than 0");
+            }
+        }
+
+        if (cmd.getDeploymentPlanner() != null) {
+            final List<String> planners = _mgr.listDeploymentPlanners();
+            if (planners != null && !planners.isEmpty()) {
+                if (!planners.contains(cmd.getDeploymentPlanner())) {
+                    throw new InvalidParameterValueException("Invalid name for Deployment Planner specified, please use listDeploymentPlanners to get the valid set");
+                }
+            } else {
+                throw new InvalidParameterValueException("No deployment planners found");
+            }
+        }
+
+        return createServiceOffering(userId, cmd.isSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
+                cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), cmd.getHostTag(),
+                cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails(), isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
+                cmd.getBytesReadRate(), cmd.getBytesReadRateMax(), cmd.getBytesReadRateMaxLength(),
+                cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(),
+                cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(),
+                cmd.getIopsWriteRate(), cmd.getIopsWriteRateMax(), cmd.getIopsWriteRateMaxLength(),
+                cmd.getHypervisorSnapshotReserve());
+    }
+
+    protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
+            final String name, final Integer cpu, final Integer ramSize, final Integer speed, final String displayText, final String provisioningType, final boolean localStorageRequired,
+            final boolean offerHA, final boolean limitResourceUse, final boolean volatileVm,  String tags, final Long domainId, final String hostTag,
+            final Integer networkRate, final String deploymentPlanner, final Map<String, String> details, final Boolean isCustomizedIops, Long minIops, Long maxIops,
+            Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength,
+            Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
+            Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
+            Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
+            final Integer hypervisorSnapshotReserve) {
+
+        // Check if user exists in the system
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (domainId == null) {
+                throw new InvalidParameterValueException("Unable to create public service offering by id " + userId + " because it is domain-admin");
+            }
+            if (tags != null || hostTag != null) {
+                throw new InvalidParameterValueException("Unable to create service offering with storage tags or host tags by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), domainId)) {
+                throw new InvalidParameterValueException("Unable to create service offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to create service offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);
+
+        tags = StringUtils.cleanupTags(tags);
+
+        ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA,
+                limitResourceUse, volatileVm, displayText, typedProvisioningType, localStorageRequired, false, tags, isSystem, vmType,
+                domainId, hostTag, deploymentPlanner);
+
+        if (Boolean.TRUE.equals(isCustomizedIops)) {
+                minIops = null;
+                maxIops = null;
+        } else {
+            if (minIops == null && maxIops == null) {
+                minIops = 0L;
+                maxIops = 0L;
+            } else {
+                if (minIops == null || minIops <= 0) {
+                    throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
+                }
+
+                if (maxIops == null) {
+                    maxIops = 0L;
+                }
+
+                if (minIops > maxIops) {
+                    throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
+                }
+            }
+        }
+
+
+        offering.setCustomizedIops(isCustomizedIops);
+        offering.setMinIops(minIops);
+        offering.setMaxIops(maxIops);
+
+        if (bytesReadRate != null && bytesReadRate > 0) {
+            offering.setBytesReadRate(bytesReadRate);
+        }
+        if (bytesReadRateMax != null && bytesReadRateMax > 0) {
+            offering.setBytesReadRateMax(bytesReadRateMax);
+        }
+        if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) {
+            offering.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+        }
+        if (bytesWriteRate != null && bytesWriteRate > 0) {
+            offering.setBytesWriteRate(bytesWriteRate);
+        }
+        if (bytesWriteRateMax != null && bytesWriteRateMax > 0) {
+            offering.setBytesWriteRateMax(bytesWriteRateMax);
+        }
+        if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) {
+            offering.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+        }
+        if (iopsReadRate != null && iopsReadRate > 0) {
+            offering.setIopsReadRate(iopsReadRate);
+        }
+        if (iopsReadRateMax != null && iopsReadRateMax > 0) {
+            offering.setIopsReadRateMax(iopsReadRateMax);
+        }
+        if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) {
+            offering.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+        }
+        if (iopsWriteRate != null && iopsWriteRate > 0) {
+            offering.setIopsWriteRate(iopsWriteRate);
+        }
+        if (iopsWriteRateMax != null && iopsWriteRateMax > 0) {
+            offering.setIopsWriteRateMax(iopsWriteRateMax);
+        }
+        if (iopsWriteRateMaxLength != null && iopsWriteRateMaxLength > 0) {
+            offering.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
+        }
+
+        if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
+            throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
+        }
+
+        offering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
+
+        List<ServiceOfferingDetailsVO> detailsVO = null;
+        if (details != null) {
+            // To have correct input, either both gpu card name and VGPU type should be passed or nothing should be passed.
+            // Use XOR condition to verify that.
+            final boolean entry1 = details.containsKey(GPU.Keys.pciDevice.toString());
+            final boolean entry2 = details.containsKey(GPU.Keys.vgpuType.toString());
+            if ((entry1 || entry2) && !(entry1 && entry2)) {
+                throw new InvalidParameterValueException("Please specify the pciDevice and vgpuType correctly.");
+            }
+            detailsVO = new ArrayList<ServiceOfferingDetailsVO>();
+            for (final Entry<String, String> detailEntry : details.entrySet()) {
+                if (detailEntry.getKey().equals(GPU.Keys.pciDevice.toString())) {
+                    if (detailEntry.getValue() == null) {
+                        throw new InvalidParameterValueException("Please specify a GPU Card.");
+                    }
+                }
+                if (detailEntry.getKey().equals(GPU.Keys.vgpuType.toString())) {
+                    if (detailEntry.getValue() == null) {
+                        throw new InvalidParameterValueException("vGPUType value cannot be null");
+                    }
+                }
+                detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), detailEntry.getKey(), detailEntry.getValue(), true));
+            }
+        }
+
+        if ((offering = _serviceOfferingDao.persist(offering)) != null) {
+            if (detailsVO != null && !detailsVO.isEmpty()) {
+                for (int index = 0; index < detailsVO.size(); index++) {
+                    detailsVO.get(index).setResourceId(offering.getId());
+                }
+                _serviceOfferingDetailsDao.saveDetails(detailsVO);
+            }
+            CallContext.current().setEventDetails("Service offering id=" + offering.getId());
+            return offering;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_EDIT, eventDescription = "updating service offering")
+    public ServiceOffering updateServiceOffering(final UpdateServiceOfferingCmd cmd) {
+        final String displayText = cmd.getDisplayText();
+        final Long id = cmd.getId();
+        final String name = cmd.getServiceOfferingName();
+        final Integer sortKey = cmd.getSortKey();
+        Long userId = CallContext.current().getCallingUserId();
+
+        if (userId == null) {
+            userId = Long.valueOf(User.UID_SYSTEM);
+        }
+
+        // Verify input parameters
+        final ServiceOffering offeringHandle = _entityMgr.findById(ServiceOffering.class, id);
+
+        if (offeringHandle == null) {
+            throw new InvalidParameterValueException("unable to find service offering " + id);
+        }
+
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (offeringHandle.getDomainId() == null) {
+                throw new InvalidParameterValueException("Unable to update public service offering by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), offeringHandle.getDomainId() )) {
+                throw new InvalidParameterValueException("Unable to update service offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to update service offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        final boolean updateNeeded = name != null || displayText != null || sortKey != null;
+        if (!updateNeeded) {
+            return _serviceOfferingDao.findById(id);
+        }
+
+        ServiceOfferingVO offering = _serviceOfferingDao.createForUpdate(id);
+
+        if (name != null) {
+            offering.setName(name);
+        }
+
+        if (displayText != null) {
+            offering.setDisplayText(displayText);
+        }
+
+        if (sortKey != null) {
+            offering.setSortKey(sortKey);
+        }
+
+        // Note: tag editing commented out for now; keeping the code intact,
+        // might need to re-enable in next releases
+        // if (tags != null)
+        // {
+        // if (tags.trim().isEmpty() && offeringHandle.getTags() == null)
+        // {
+        // //no new tags; no existing tags
+        // offering.setTagsArray(csvTagsToList(null));
+        // }
+        // else if (!tags.trim().isEmpty() && offeringHandle.getTags() != null)
+        // {
+        // //new tags + existing tags
+        // List<String> oldTags = csvTagsToList(offeringHandle.getTags());
+        // List<String> newTags = csvTagsToList(tags);
+        // oldTags.addAll(newTags);
+        // offering.setTagsArray(oldTags);
+        // }
+        // else if(!tags.trim().isEmpty())
+        // {
+        // //new tags; NO existing tags
+        // offering.setTagsArray(csvTagsToList(tags));
+        // }
+        // }
+
+        if (_serviceOfferingDao.update(id, offering)) {
+            offering = _serviceOfferingDao.findById(id);
+            CallContext.current().setEventDetails("Service offering id=" + offering.getId());
+            return offering;
+        } else {
+            return null;
+        }
+    }
+
+    protected DiskOfferingVO createDiskOffering(final Long userId, final Long domainId, final String name, final String description, final String provisioningType,
+            final Long numGibibytes, String tags, boolean isCustomized, final boolean localStorageRequired,
+            final boolean isDisplayOfferingEnabled, final Boolean isCustomizedIops, Long minIops, Long maxIops,
+            Long bytesReadRate, Long bytesReadRateMax, Long bytesReadRateMaxLength,
+            Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
+            Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
+            Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
+            final Integer hypervisorSnapshotReserve) {
+        long diskSize = 0;// special case for custom disk offerings
+        if (numGibibytes != null && numGibibytes <= 0) {
+            throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
+        } else if (numGibibytes != null && numGibibytes > _maxVolumeSizeInGb) {
+            throw new InvalidParameterValueException("The maximum size for a disk is " + _maxVolumeSizeInGb + " Gb.");
+        }
+        final ProvisioningType typedProvisioningType = ProvisioningType.getProvisioningType(provisioningType);
+
+        if (numGibibytes != null) {
+            diskSize = numGibibytes * 1024 * 1024 * 1024;
+        }
+
+        if (diskSize == 0) {
+            isCustomized = true;
+        }
+
+        if (Boolean.TRUE.equals(isCustomizedIops)) {
+            minIops = null;
+            maxIops = null;
+        } else {
+            if (minIops == null && maxIops == null) {
+                minIops = 0L;
+                maxIops = 0L;
+            } else {
+                if (minIops == null || minIops <= 0) {
+                    throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
+                }
+
+                if (maxIops == null) {
+                    maxIops = 0L;
+                }
+
+                if (minIops > maxIops) {
+                    throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
+                }
+            }
+        }
+
+
+        // Check if user exists in the system
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (domainId == null) {
+                throw new InvalidParameterValueException("Unable to create public disk offering by id " + userId + " because it is domain-admin");
+            }
+            if (tags != null) {
+                throw new InvalidParameterValueException("Unable to create disk offering with storage tags by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), domainId)) {
+                throw new InvalidParameterValueException("Unable to create disk offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to create disk offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        tags = StringUtils.cleanupTags(tags);
+        final DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, typedProvisioningType, diskSize, tags, isCustomized,
+                isCustomizedIops, minIops, maxIops);
+        newDiskOffering.setUseLocalStorage(localStorageRequired);
+        newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled);
+
+        if (bytesReadRate != null && bytesReadRate > 0) {
+            newDiskOffering.setBytesReadRate(bytesReadRate);
+        }
+        if (bytesReadRateMax != null && bytesReadRateMax > 0) {
+            newDiskOffering.setBytesReadRateMax(bytesReadRateMax);
+        }
+        if (bytesReadRateMaxLength != null && bytesReadRateMaxLength > 0) {
+            newDiskOffering.setBytesReadRateMaxLength(bytesReadRateMaxLength);
+        }
+        if (bytesWriteRate != null && bytesWriteRate > 0) {
+            newDiskOffering.setBytesWriteRate(bytesWriteRate);
+        }
+        if (bytesWriteRateMax != null && bytesWriteRateMax > 0) {
+            newDiskOffering.setBytesWriteRateMax(bytesWriteRateMax);
+        }
+        if (bytesWriteRateMaxLength != null && bytesWriteRateMaxLength > 0) {
+            newDiskOffering.setBytesWriteRateMaxLength(bytesWriteRateMaxLength);
+        }
+        if (iopsReadRate != null && iopsReadRate > 0) {
+            newDiskOffering.setIopsReadRate(iopsReadRate);
+        }
+        if (iopsReadRateMax != null && iopsReadRateMax > 0) {
+            newDiskOffering.setIopsReadRateMax(iopsReadRateMax);
+        }
+        if (iopsReadRateMaxLength != null && iopsReadRateMaxLength > 0) {
+            newDiskOffering.setIopsReadRateMaxLength(iopsReadRateMaxLength);
+        }
+        if (iopsWriteRate != null && iopsWriteRate > 0) {
+            newDiskOffering.setIopsWriteRate(iopsWriteRate);
+        }
+        if (iopsWriteRateMax != null && iopsWriteRateMax > 0) {
+            newDiskOffering.setIopsWriteRateMax(iopsWriteRateMax);
+        }
+        if (iopsWriteRateMaxLength != null && iopsWriteRateMaxLength > 0) {
+            newDiskOffering.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
+        }
+
+        if (hypervisorSnapshotReserve != null && hypervisorSnapshotReserve < 0) {
+            throw new InvalidParameterValueException("If provided, Hypervisor Snapshot Reserve must be greater than or equal to 0.");
+        }
+
+        newDiskOffering.setHypervisorSnapshotReserve(hypervisorSnapshotReserve);
+
+        CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
+        final DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering);
+        if (offering != null) {
+            CallContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
+            return offering;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering")
+    public DiskOffering createDiskOffering(final CreateDiskOfferingCmd cmd) {
+        final String name = cmd.getOfferingName();
+        final String description = cmd.getDisplayText();
+        final String provisioningType = cmd.getProvisioningType();
+        final Long numGibibytes = cmd.getDiskSize();
+        final boolean isDisplayOfferingEnabled = cmd.getDisplayOffering() != null ? cmd.getDisplayOffering() : true;
+        final boolean isCustomized = cmd.isCustomized() != null ? cmd.isCustomized() : false; // false
+        // by
+        // default
+        final String tags = cmd.getTags();
+        // Long domainId = cmd.getDomainId() != null ? cmd.getDomainId() :
+        // Long.valueOf(DomainVO.ROOT_DOMAIN); // disk offering
+        // always gets created under the root domain.Bug # 6055 if not passed in
+        // cmd
+        final Long domainId = cmd.getDomainId();
+
+        if (!isCustomized && numGibibytes == null) {
+            throw new InvalidParameterValueException("Disksize is required for a non-customized disk offering");
+        }
+
+        if (isCustomized && numGibibytes != null) {
+            throw new InvalidParameterValueException("Disksize is not allowed for a customized disk offering");
+        }
+
+        boolean localStorageRequired = false;
+        final String storageType = cmd.getStorageType();
+        if (storageType != null) {
+            if (storageType.equalsIgnoreCase(ServiceOffering.StorageType.local.toString())) {
+                localStorageRequired = true;
+            } else if (!storageType.equalsIgnoreCase(ServiceOffering.StorageType.shared.toString())) {
+                throw new InvalidParameterValueException("Invalid storage type " + storageType + " specified, valid types are: 'local' and 'shared'");
+            }
+        }
+
+        final Boolean isCustomizedIops = cmd.isCustomizedIops();
+        final Long minIops = cmd.getMinIops();
+        final Long maxIops = cmd.getMaxIops();
+        final Long bytesReadRate = cmd.getBytesReadRate();
+        final Long bytesReadRateMax = cmd.getBytesReadRateMax();
+        final Long bytesReadRateMaxLength = cmd.getBytesReadRateMaxLength();
+        final Long bytesWriteRate = cmd.getBytesWriteRate();
+        final Long bytesWriteRateMax = cmd.getBytesWriteRateMax();
+        final Long bytesWriteRateMaxLength = cmd.getBytesWriteRateMaxLength();
+        final Long iopsReadRate = cmd.getIopsReadRate();
+        final Long iopsReadRateMax = cmd.getIopsReadRateMax();
+        final Long iopsReadRateMaxLength = cmd.getIopsReadRateMaxLength();
+        final Long iopsWriteRate = cmd.getIopsWriteRate();
+        final Long iopsWriteRateMax = cmd.getIopsWriteRateMax();
+        final Long iopsWriteRateMaxLength = cmd.getIopsWriteRateMaxLength();
+        final Integer hypervisorSnapshotReserve = cmd.getHypervisorSnapshotReserve();
+
+        final Long userId = CallContext.current().getCallingUserId();
+        return createDiskOffering(userId, domainId, name, description, provisioningType, numGibibytes, tags, isCustomized,
+                localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops,
+                maxIops, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength,
+                iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength,
+                hypervisorSnapshotReserve);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_EDIT, eventDescription = "updating disk offering")
+    public DiskOffering updateDiskOffering(final UpdateDiskOfferingCmd cmd) {
+        final Long diskOfferingId = cmd.getId();
+        final String name = cmd.getDiskOfferingName();
+        final String displayText = cmd.getDisplayText();
+        final Integer sortKey = cmd.getSortKey();
+        final Boolean displayDiskOffering = cmd.getDisplayOffering();
+
+        // Check if diskOffering exists
+        final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId);
+
+        if (diskOfferingHandle == null) {
+            throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId);
+        }
+
+        Long userId = CallContext.current().getCallingUserId();
+        if (userId == null) {
+            userId = Long.valueOf(User.UID_SYSTEM);
+        }
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (diskOfferingHandle.getDomainId() == null) {
+                throw new InvalidParameterValueException("Unable to update public disk offering by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), diskOfferingHandle.getDomainId() )) {
+                throw new InvalidParameterValueException("Unable to update disk offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to update disk offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        final boolean updateNeeded = name != null || displayText != null || sortKey != null || displayDiskOffering != null;
+        if (!updateNeeded) {
+            return _diskOfferingDao.findById(diskOfferingId);
+        }
+
+        final DiskOfferingVO diskOffering = _diskOfferingDao.createForUpdate(diskOfferingId);
+
+        if (name != null) {
+            diskOffering.setName(name);
+        }
+
+        if (displayText != null) {
+            diskOffering.setDisplayText(displayText);
+        }
+
+        if (sortKey != null) {
+            diskOffering.setSortKey(sortKey);
+        }
+
+        if (displayDiskOffering != null) {
+            diskOffering.setDisplayOffering(displayDiskOffering);
+        }
+
+        // Note: tag editing commented out for now;keeping the code intact,
+        // might need to re-enable in next releases
+        // if (tags != null)
+        // {
+        // if (tags.trim().isEmpty() && diskOfferingHandle.getTags() == null)
+        // {
+        // //no new tags; no existing tags
+        // diskOffering.setTagsArray(csvTagsToList(null));
+        // }
+        // else if (!tags.trim().isEmpty() && diskOfferingHandle.getTags() !=
+        // null)
+        // {
+        // //new tags + existing tags
+        // List<String> oldTags = csvTagsToList(diskOfferingHandle.getTags());
+        // List<String> newTags = csvTagsToList(tags);
+        // oldTags.addAll(newTags);
+        // diskOffering.setTagsArray(oldTags);
+        // }
+        // else if(!tags.trim().isEmpty())
+        // {
+        // //new tags; NO existing tags
+        // diskOffering.setTagsArray(csvTagsToList(tags));
+        // }
+        // }
+
+        if (_diskOfferingDao.update(diskOfferingId, diskOffering)) {
+            CallContext.current().setEventDetails("Disk offering id=" + diskOffering.getId());
+            return _diskOfferingDao.findById(diskOfferingId);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_DELETE, eventDescription = "deleting disk offering")
+    public boolean deleteDiskOffering(final DeleteDiskOfferingCmd cmd) {
+        final Long diskOfferingId = cmd.getId();
+
+        final DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
+
+        if (offering == null) {
+            throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId);
+        }
+
+        Long userId = CallContext.current().getCallingUserId();
+        if (userId == null) {
+            userId = Long.valueOf(User.UID_SYSTEM);
+        }
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (offering.getDomainId() == null) {
+                throw new InvalidParameterValueException("Unable to delete public disk offering by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), offering.getDomainId() )) {
+                throw new InvalidParameterValueException("Unable to delete disk offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to delete disk offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        offering.setState(DiskOffering.State.Inactive);
+        if (_diskOfferingDao.update(offering.getId(), offering)) {
+            CallContext.current().setEventDetails("Disk offering id=" + diskOfferingId);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_DELETE, eventDescription = "deleting service offering")
+    public boolean deleteServiceOffering(final DeleteServiceOfferingCmd cmd) {
+
+        final Long offeringId = cmd.getId();
+        Long userId = CallContext.current().getCallingUserId();
+
+        if (userId == null) {
+            userId = Long.valueOf(User.UID_SYSTEM);
+        }
+
+        // Verify service offering id
+        final ServiceOfferingVO offering = _serviceOfferingDao.findById(offeringId);
+        if (offering == null) {
+            throw new InvalidParameterValueException("unable to find service offering " + offeringId);
+        }
+
+        if (offering.getDefaultUse()) {
+            throw new InvalidParameterValueException("Default service offerings cannot be deleted");
+        }
+
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+        final Account account = _accountDao.findById(user.getAccountId());
+        if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+            if (offering.getDomainId() == null) {
+                throw new InvalidParameterValueException("Unable to delete public service offering by id " + userId + " because it is domain-admin");
+            }
+            if (! _domainDao.isChildDomain(account.getDomainId(), offering.getDomainId() )) {
+                throw new InvalidParameterValueException("Unable to delete service offering by another domain admin with id " + userId);
+            }
+        } else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Unable to delete service offering by id " + userId + " because it is not root-admin or domain-admin");
+        }
+
+        offering.setState(DiskOffering.State.Inactive);
+        if (_serviceOfferingDao.update(offeringId, offering)) {
+            CallContext.current().setEventDetails("Service offering id=" + offeringId);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_CREATE, eventDescription = "creating vlan ip range", async = false)
+    public Vlan createVlanAndPublicIpRange(final CreateVlanIpRangeCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
+    ResourceAllocationException {
+        Long zoneId = cmd.getZoneId();
+        final Long podId = cmd.getPodId();
+        final String startIP = cmd.getStartIp();
+        String endIP = cmd.getEndIp();
+        final String newVlanGateway = cmd.getGateway();
+        final String newVlanNetmask = cmd.getNetmask();
+        String vlanId = cmd.getVlan();
+        // TODO decide if we should be forgiving or demand a valid and complete URI
+        if (!(vlanId == null || "".equals(vlanId) || vlanId.startsWith(BroadcastDomainType.Vlan.scheme()))) {
+            vlanId = BroadcastDomainType.Vlan.toUri(vlanId).toString();
+        }
+        final Boolean forVirtualNetwork = cmd.isForVirtualNetwork();
+        Long networkId = cmd.getNetworkID();
+        Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        final String accountName = cmd.getAccountName();
+        final Long projectId = cmd.getProjectId();
+        final Long domainId = cmd.getDomainId();
+        final String startIPv6 = cmd.getStartIpv6();
+        String endIPv6 = cmd.getEndIpv6();
+        final String ip6Gateway = cmd.getIp6Gateway();
+        final String ip6Cidr = cmd.getIp6Cidr();
+        final Boolean forSystemVms = cmd.isForSystemVms();
+
+        Account vlanOwner = null;
+
+        if (forSystemVms && accountName != null) {
+            throw new InvalidParameterValueException("Account name should not be provided when ForSystemVMs is enabled");
+        }
+
+        final boolean ipv4 = startIP != null;
+        final boolean ipv6 = startIPv6 != null;
+
+        if (!ipv4 && !ipv6) {
+            throw new InvalidParameterValueException("StartIP or StartIPv6 is missing in the parameters!");
+        }
+
+        if (ipv4) {
+            // if end ip is not specified, default it to startIp
+            if (endIP == null && startIP != null) {
+                endIP = startIP;
+            }
+        }
+
+        if (ipv6) {
+            // if end ip is not specified, default it to startIp
+            if (endIPv6 == null && startIPv6 != null) {
+                endIPv6 = startIPv6;
+            }
+        }
+
+        if (projectId != null) {
+            if (accountName != null) {
+                throw new InvalidParameterValueException("Account and projectId are mutually exclusive");
+            }
+            final Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+            }
+
+            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
+            if (vlanOwner == null) {
+                throw new InvalidParameterValueException("Please specify a valid projectId");
+            }
+        }
+
+        Domain domain = null;
+        if (accountName != null && domainId != null) {
+            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
+            if (vlanOwner == null) {
+                throw new InvalidParameterValueException("Please specify a valid account.");
+            } else if (vlanOwner.getId() == Account.ACCOUNT_ID_SYSTEM) {
+                // by default vlan is dedicated to system account
+                vlanOwner = null;
+            }
+        } else if (domainId != null) {
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Please specify a valid domain id");
+            }
+        }
+
+        // Verify that network exists
+        Network network = null;
+        if (networkId != null) {
+            network = _networkDao.findById(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find network by id " + networkId);
+            } else {
+                zoneId = network.getDataCenterId();
+                physicalNetworkId = network.getPhysicalNetworkId();
+            }
+        } else if (ipv6) {
+            throw new InvalidParameterValueException("Only support IPv6 on extending existed network");
+        }
+
+        // Verify that zone exists
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+        }
+
+        if (ipv6) {
+            if (network.getGuestType() != GuestType.Shared || zone.isSecurityGroupEnabled()) {
+                throw new InvalidParameterValueException("Only support IPv6 on extending existed share network without SG");
+            }
+        }
+        // verify that physical network exists
+        PhysicalNetworkVO pNtwk = null;
+        if (physicalNetworkId != null) {
+            pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
+            if (pNtwk == null) {
+                throw new InvalidParameterValueException("Unable to find Physical Network with id=" + physicalNetworkId);
+            }
+            if (zoneId == null) {
+                zoneId = pNtwk.getDataCenterId();
+            }
+        } else {
+            if (zoneId == null) {
+                throw new InvalidParameterValueException("");
+            }
+            // deduce physicalNetworkFrom Zone or Network.
+            if (network != null && network.getPhysicalNetworkId() != null) {
+                physicalNetworkId = network.getPhysicalNetworkId();
+            } else {
+                if (forVirtualNetwork) {
+                    // default physical network with public traffic in the zone
+                    physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId();
+                } else {
+                    if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
+                        // default physical network with guest traffic in the
+                        // zone
+                        physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId();
+                    } else if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
+                        if (zone.isSecurityGroupEnabled()) {
+                            physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId();
+                        } else {
+                            throw new InvalidParameterValueException("Physical Network Id is null, please provide the Network id for Direct vlan creation ");
+                        }
+                    }
+                }
+            }
+        }
+
+        // Check if zone is enabled
+        final Account caller = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
+                && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+        }
+
+        if (zone.isSecurityGroupEnabled() && zone.getNetworkType() != DataCenter.NetworkType.Basic && forVirtualNetwork) {
+            throw new InvalidParameterValueException("Can't add virtual ip range into a zone with security group enabled");
+        }
+
+        // If networkId is not specified, and vlan is Virtual or Direct
+        // Untagged, try to locate default networks
+        if (forVirtualNetwork) {
+            if (network == null) {
+                // find default public network in the zone
+                networkId = _networkModel.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId();
+                network = _networkModel.getNetwork(networkId);
+            } else if (network.getGuestType() != null || network.getTrafficType() != TrafficType.Public) {
+                throw new InvalidParameterValueException("Can't find Public network by id=" + networkId);
+            }
+        } else {
+            if (network == null) {
+                if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
+                    networkId = _networkModel.getExclusiveGuestNetwork(zoneId).getId();
+                    network = _networkModel.getNetwork(networkId);
+                } else {
+                    network = _networkModel.getNetworkWithSecurityGroupEnabled(zoneId);
+                    if (network == null) {
+                        throw new InvalidParameterValueException("Nework id is required for Direct vlan creation ");
+                    }
+                    networkId = network.getId();
+                    zoneId = network.getDataCenterId();
+                }
+            } else if (network.getGuestType() == null ||
+                    network.getGuestType() == Network.GuestType.Isolated
+                    && _ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.SourceNat)) {
+                throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId + " with type: " + network.getGuestType());
+            }
+        }
+
+        Pair<Boolean, Pair<String, String>> sameSubnet = null;
+        // Can add vlan range only to the network which allows it
+        if (!network.getSpecifyIpRanges()) {
+            throw new InvalidParameterValueException("Network " + network + " doesn't support adding ip ranges");
+        }
+
+        if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
+            if (network.getTrafficType() == TrafficType.Guest) {
+                if (network.getGuestType() != GuestType.Shared) {
+                    throw new InvalidParameterValueException("Can execute createVLANIpRanges on shared guest network, but type of this guest network " + network.getId() + " is "
+                            + network.getGuestType());
+                }
+
+                final List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
+                if (vlans != null && vlans.size() > 0) {
+                    final VlanVO vlan = vlans.get(0);
+                    if (vlanId == null || vlanId.contains(Vlan.UNTAGGED)) {
+                        vlanId = vlan.getVlanTag();
+                    } else if (!NetUtils.isSameIsolationId(vlan.getVlanTag(), vlanId)) {
+                        throw new InvalidParameterValueException("there is already one vlan " + vlan.getVlanTag() + " on network :" + +network.getId()
+                                + ", only one vlan is allowed on guest network");
+                    }
+                }
+                sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
+
+            }
+
+        } else if (network.getTrafficType() == TrafficType.Management) {
+            throw new InvalidParameterValueException("Cannot execute createVLANIpRanges on management network");
+        } else if (zone.getNetworkType() == NetworkType.Basic) {
+            final List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
+            sameSubnet = validateIpRange(startIP, endIP, newVlanGateway, newVlanNetmask, vlans, ipv4, ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
+        }
+
+        if (zoneId == null || ipv6 && (ip6Gateway == null || ip6Cidr == null)) {
+            throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks");
+        }
+
+        if (forVirtualNetwork) {
+            if (vlanOwner != null) {
+
+                final long accountIpRange = NetUtils.ip2Long(endIP) - NetUtils.ip2Long(startIP) + 1;
+
+                // check resource limits
+                _resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountIpRange);
+            }
+        }
+        // Check if the IP range overlaps with the private ip
+        if (ipv4) {
+            checkOverlapPrivateIpRange(zoneId, startIP, endIP);
+        }
+
+        return commitVlan(zoneId, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId, forVirtualNetwork, forSystemVms, networkId, physicalNetworkId, startIPv6, endIPv6, ip6Gateway,
+                ip6Cidr, domain, vlanOwner, network, sameSubnet);
+    }
+
+    private Vlan commitVlan(final Long zoneId, final Long podId, final String startIP, final String endIP, final String newVlanGatewayFinal, final String newVlanNetmaskFinal,
+            final String vlanId, final Boolean forVirtualNetwork, final Boolean forSystemVms, final Long networkId, final Long physicalNetworkId, final String startIPv6, final String endIPv6,
+            final String ip6Gateway, final String ip6Cidr, final Domain domain, final Account vlanOwner, final Network network, final Pair<Boolean, Pair<String, String>> sameSubnet) {
+        final GlobalLock commitVlanLock = GlobalLock.getInternLock("CommitVlan");
+        commitVlanLock.lock(5);
+        s_logger.debug("Acquiring lock for committing vlan");
+        try {
+            return Transaction.execute(new TransactionCallback<Vlan>() {
+                @Override
+                public Vlan doInTransaction(final TransactionStatus status) {
+                    String newVlanNetmask = newVlanNetmaskFinal;
+                    String newVlanGateway = newVlanGatewayFinal;
+
+                    if ((sameSubnet == null || !sameSubnet.first()) && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared
+                            && _vlanDao.listVlansByNetworkId(networkId) != null) {
+                        final Map<Capability, String> dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()),
+                            Service.Dhcp);
+                        final String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets);
+                        if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) {
+                            throw new  InvalidParameterValueException("The dhcp service provider for this network does not support dhcp across multiple subnets");
+                        }
+                        s_logger.info("adding a new subnet to the network " + network.getId());
+                    } else if (sameSubnet != null) {
+                        // if it is same subnet the user might not send the vlan and the
+                        // netmask details. so we are
+                        // figuring out while validation and setting them here.
+                        newVlanGateway = sameSubnet.second().first();
+                        newVlanNetmask = sameSubnet.second().second();
+                    }
+                    final Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, forSystemVms, podId, startIP, endIP, newVlanGateway, newVlanNetmask, vlanId,
+                            false, domain, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
+                    // create an entry in the nic_secondary table. This will be the new
+                    // gateway that will be configured on the corresponding routervm.
+                    return vlan;
+                }
+            });
+        } finally {
+            commitVlanLock.unlock();
+        }
+    }
+
+    public NetUtils.SupersetOrSubset checkIfSubsetOrSuperset(String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, final String newStartIP, final String newEndIP) {
+        if (newVlanGateway == null && newVlanNetmask == null) {
+            newVlanGateway = vlanGateway;
+            newVlanNetmask = vlanNetmask;
+            // this means he is trying to add to the existing subnet.
+            if (NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) {
+                if (NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) {
+                    return NetUtils.SupersetOrSubset.sameSubnet;
+                }
+            }
+            return NetUtils.SupersetOrSubset.neitherSubetNorSuperset;
+        } else if (newVlanGateway == null || newVlanNetmask == null) {
+            throw new InvalidParameterValueException(
+                    "either both netmask and gateway should be passed or both should me omited.");
+        } else {
+            if (!NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) {
+                throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet");
+            }
+            if (!NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) {
+                throw new InvalidParameterValueException("The end ip and gateway do not belong to the same subnet");
+            }
+        }
+        final String cidrnew = NetUtils.getCidrFromGatewayAndNetmask(newVlanGateway, newVlanNetmask);
+        final String existing_cidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
+
+        return NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(cidrnew, existing_cidr);
+    }
+
+    public Pair<Boolean, Pair<String, String>> validateIpRange(final String startIP, final String endIP, final String newVlanGateway, final String newVlanNetmask, final List<VlanVO> vlans, final boolean ipv4,
+            final boolean ipv6, String ip6Gateway, String ip6Cidr, final String startIPv6, final String endIPv6, final Network network) {
+        String vlanGateway = null;
+        String vlanNetmask = null;
+        boolean sameSubnet = false;
+        if (CollectionUtils.isNotEmpty(vlans)) {
+            for (final VlanVO vlan : vlans) {
+                vlanGateway = vlan.getVlanGateway();
+                vlanNetmask = vlan.getVlanNetmask();
+                sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP,
+                        ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
+                if (sameSubnet) break;
+            }
+        } else if(network.getGateway() != null && network.getCidr() != null) {
+            vlanGateway = network.getGateway();
+            vlanNetmask = NetUtils.getCidrNetmask(network.getCidr());
+            sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP,
+                    ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network);
+        }
+        if (newVlanGateway == null && newVlanNetmask == null && !sameSubnet) {
+            throw new InvalidParameterValueException("The ip range dose not belong to any of the existing subnets, Provide the netmask and gateway if you want to add new subnet");
+        }
+        Pair<String, String> vlanDetails = null;
+
+        if (sameSubnet) {
+            vlanDetails = new Pair<String, String>(vlanGateway, vlanNetmask);
+        } else {
+            vlanDetails = new Pair<String, String>(newVlanGateway, newVlanNetmask);
+        }
+        // check if the gatewayip is the part of the ip range being added.
+        if (ipv4 && NetUtils.ipRangesOverlap(startIP, endIP, vlanDetails.first(), vlanDetails.first())) {
+            throw new InvalidParameterValueException("The gateway ip should not be the part of the ip range being added.");
+        }
+
+        return new Pair<Boolean, Pair<String, String>>(sameSubnet, vlanDetails);
+    }
+
+    public boolean hasSameSubnet(boolean ipv4, String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, String newStartIp, String newEndIp,
+                                  boolean ipv6, String newIp6Gateway, String newIp6Cidr, String newIp6StartIp, String newIp6EndIp, Network network) {
+        if (ipv4) {
+            // check if subset or super set or neither.
+            final NetUtils.SupersetOrSubset val = checkIfSubsetOrSuperset(vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, newStartIp, newEndIp);
+            if (val == NetUtils.SupersetOrSubset.isSuperset) {
+                // this means that new cidr is a superset of the
+                // existing subnet.
+                throw new InvalidParameterValueException("The subnet you are trying to add is a superset of the existing subnet having gateway " + vlanGateway
+                        + " and netmask " + vlanNetmask);
+            } else if (val == NetUtils.SupersetOrSubset.neitherSubetNorSuperset) {
+                // this implies the user is trying to add a new subnet
+                // which is not a superset or subset of this subnet.
+            } else if (val == NetUtils.SupersetOrSubset.isSubset) {
+                // this means he is trying to add to the same subnet.
+                throw new InvalidParameterValueException("The subnet you are trying to add is a subset of the existing subnet having gateway " + vlanGateway
+                        + " and netmask " + vlanNetmask);
+            } else if (val == NetUtils.SupersetOrSubset.sameSubnet) {
+                //check if the gateway provided by the user is same as that of the subnet.
+                if (newVlanGateway != null && !newVlanGateway.equals(vlanGateway)) {
+                    throw new InvalidParameterValueException("The gateway of the subnet should be unique. The subnet already has a gateway " + vlanGateway);
+                }
+                return true;
+            }
+        }
+        if (ipv6) {
+            if (newIp6Gateway != null && !newIp6Gateway.equals(network.getIp6Gateway())) {
+                throw new InvalidParameterValueException("The input gateway " + newIp6Gateway + " is not same as network gateway " + network.getIp6Gateway());
+            }
+            if (newIp6Cidr != null && !newIp6Cidr.equals(network.getIp6Cidr())) {
+                throw new InvalidParameterValueException("The input cidr " + newIp6Cidr + " is not same as network cidr " + network.getIp6Cidr());
+            }
+
+            newIp6Gateway = MoreObjects.firstNonNull(newIp6Gateway, network.getIp6Gateway());
+            newIp6Cidr = MoreObjects.firstNonNull(newIp6Cidr, network.getIp6Cidr());
+            _networkModel.checkIp6Parameters(newIp6StartIp, newIp6EndIp, newIp6Gateway, newIp6Cidr);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    @DB
+    public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final boolean forVirtualNetwork, final boolean forSystemVms, final Long podId, final String startIP, final String endIP,
+            final String vlanGateway, final String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, final Account vlanOwner, final String startIPv6, final String endIPv6, final String vlanIp6Gateway, final String vlanIp6Cidr) {
+        final Network network = _networkModel.getNetwork(networkId);
+
+        boolean ipv4 = false, ipv6 = false;
+
+        if (startIP != null) {
+            ipv4 = true;
+        }
+
+        if (startIPv6 != null) {
+            ipv6 = true;
+        }
+
+        if (!ipv4 && !ipv6) {
+            throw new InvalidParameterValueException("Please specify IPv4 or IPv6 address.");
+        }
+
+        // Validate the zone
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Please specify a valid zone.");
+        }
+
+        // ACL check
+        checkZoneAccess(CallContext.current().getCallingAccount(), zone);
+
+        // Validate the physical network
+        if (_physicalNetworkDao.findById(physicalNetworkId) == null) {
+            throw new InvalidParameterValueException("Please specify a valid physical network id");
+        }
+
+        // Validate the pod
+        if (podId != null) {
+            final Pod pod = _podDao.findById(podId);
+            if (pod == null) {
+                throw new InvalidParameterValueException("Please specify a valid pod.");
+            }
+            if (pod.getDataCenterId() != zoneId) {
+                throw new InvalidParameterValueException("Pod id=" + podId + " doesn't belong to zone id=" + zoneId);
+            }
+            // pod vlans can be created in basic zone only
+            if (zone.getNetworkType() != NetworkType.Basic || network.getTrafficType() != TrafficType.Guest) {
+                throw new InvalidParameterValueException("Pod id can be specified only for the networks of type " + TrafficType.Guest + " in zone of type " + NetworkType.Basic);
+            }
+        }
+
+
+        // 1) if vlan is specified for the guest network range, it should be the
+        // same as network's vlan
+        // 2) if vlan is missing, default it to the guest network's vlan
+        if (network.getTrafficType() == TrafficType.Guest) {
+            String networkVlanId = null;
+            boolean connectivityWithoutVlan = false;
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) {
+                Map<Capability, String> connectivityCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Connectivity);
+                connectivityWithoutVlan = MapUtils.isNotEmpty(connectivityCapabilities) && connectivityCapabilities.containsKey(Capability.NoVlan);
+            }
+
+            final URI uri = network.getBroadcastUri();
+            if (connectivityWithoutVlan) {
+                networkVlanId = network.getBroadcastDomainType().toUri(network.getUuid()).toString();
+            } else if (uri != null) {
+                // Do not search for the VLAN tag when the network doesn't support VLAN
+               if (uri.toString().startsWith("vlan")) {
+                    final String[] vlan = uri.toString().split("vlan:\\/\\/");
+                    networkVlanId = vlan[1];
+                    // For pvlan
+                    if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
+                        networkVlanId = networkVlanId.split("-")[0];
+                    }
+               }
+            }
+
+            if (vlanId != null && !connectivityWithoutVlan) {
+                // if vlan is specified, throw an error if it's not equal to
+                // network's vlanId
+                if (networkVlanId != null && !NetUtils.isSameIsolationId(networkVlanId, vlanId)) {
+                    throw new InvalidParameterValueException("Vlan doesn't match vlan of the network");
+                }
+            } else {
+                vlanId = networkVlanId;
+            }
+        } else if (network.getTrafficType() == TrafficType.Public && vlanId == null) {
+            throw new InvalidParameterValueException("Unable to determine vlan id or untagged vlan for public network");
+        }
+
+        if (vlanId == null) {
+            vlanId = Vlan.UNTAGGED;
+        }
+
+        final VlanType vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached;
+
+        if ((domain != null || vlanOwner != null) && zone.getNetworkType() != NetworkType.Advanced) {
+            throw new InvalidParameterValueException("Vlan owner can be defined only in the zone of type " + NetworkType.Advanced);
+        }
+
+        if (ipv4) {
+            // Make sure the gateway is valid
+            if (!NetUtils.isValidIp4(vlanGateway)) {
+                throw new InvalidParameterValueException("Please specify a valid gateway");
+            }
+
+            // Make sure the netmask is valid
+            if (!NetUtils.isValidIp4Netmask(vlanNetmask)) {
+                throw new InvalidParameterValueException("Please specify a valid netmask");
+            }
+        }
+
+        if (ipv6) {
+            if (!NetUtils.isValidIp6(vlanIp6Gateway)) {
+                throw new InvalidParameterValueException("Please specify a valid IPv6 gateway");
+            }
+            if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) {
+                throw new InvalidParameterValueException("Please specify a valid IPv6 CIDR");
+            }
+        }
+
+        if (ipv4) {
+            final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
+
+            //Make sure start and end ips are with in the range of cidr calculated for this gateway and netmask {
+            if (!NetUtils.isIpWithInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithInCidrRange(startIP, newCidr) || !NetUtils.isIpWithInCidrRange(endIP, newCidr)) {
+                throw new InvalidParameterValueException("Please specify a valid IP range or valid netmask or valid gateway");
+            }
+
+            // Check if the new VLAN's subnet conflicts with the guest network
+            // in
+            // the specified zone (guestCidr is null for basic zone)
+            // when adding shared network with same cidr of zone guest cidr,
+            // if the specified vlan is not present in zone, physical network, allow to create the network as the isolation is based on VLAN.
+            final String guestNetworkCidr = zone.getGuestNetworkCidr();
+            if (guestNetworkCidr != null && NetUtils.isNetworksOverlap(newCidr, guestNetworkCidr) && _zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).isEmpty() != true) {
+                throw new InvalidParameterValueException("The new IP range you have specified has  overlapped with the guest network in zone: " + zone.getName()
+                        + "along with existing Vlan also. Please specify a different gateway/netmask");
+            }
+
+            // Check if there are any errors with the IP range
+            checkPublicIpRangeErrors(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
+
+            checkConflictsWithPortableIpRange(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
+
+            // Throw an exception if this subnet overlaps with subnet on other VLAN,
+            // if this is ip range extension, gateway, network mask should be same and ip range should not overlap
+
+            final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
+            for (final VlanVO vlan : vlans) {
+                final String otherVlanGateway = vlan.getVlanGateway();
+                final String otherVlanNetmask = vlan.getVlanNetmask();
+                // Continue if it's not IPv4
+                if ( otherVlanGateway == null || otherVlanNetmask == null ) {
+                    continue;
+                }
+                if ( vlan.getNetworkId() == null ) {
+                    continue;
+                }
+                final String otherCidr = NetUtils.getCidrFromGatewayAndNetmask(otherVlanGateway, otherVlanNetmask);
+                if( !NetUtils.isNetworksOverlap(newCidr,  otherCidr)) {
+                    continue;
+                }
+                // from here, subnet overlaps
+                if (!UriUtils.checkVlanUriOverlap(
+                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
+                        BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
+                    boolean overlapped = false;
+                    if( network.getTrafficType() == TrafficType.Public ) {
+                        overlapped = true;
+                    } else {
+                        final Long nwId = vlan.getNetworkId();
+                        if ( nwId != null ) {
+                            final Network nw = _networkModel.getNetwork(nwId);
+                            if ( nw != null && nw.getTrafficType() == TrafficType.Public ) {
+                                overlapped = true;
+                            }
+                        }
+
+                    }
+                    if ( overlapped ) {
+                        throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag()
+                                + " in zone " + zone.getName()
+                                + " has overlapped with the subnet. Please specify a different gateway/netmask.");
+                    }
+                } else {
+
+                    final String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
+                    final String otherVlanStartIP = otherVlanIpRange[0];
+                    String otherVlanEndIP = null;
+                    if (otherVlanIpRange.length > 1) {
+                        otherVlanEndIP = otherVlanIpRange[1];
+                    }
+
+                    // extend IP range
+                    if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
+                        throw new InvalidParameterValueException("The IP range has already been added with gateway "
+                                + otherVlanGateway + " ,and netmask " + otherVlanNetmask
+                                + ", Please specify the gateway/netmask if you want to extend ip range" );
+                    }
+                    if (!NetUtils.is31PrefixCidr(newCidr)) {
+                        if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
+                            throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
+                                " Please specify a different start IP/end IP.");
+                        }
+                    }
+                }
+            }
+        }
+
+        String ipv6Range = null;
+        if (ipv6) {
+            ipv6Range = startIPv6;
+            if (endIPv6 != null) {
+                ipv6Range += "-" + endIPv6;
+            }
+
+            final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
+            for (final VlanVO vlan : vlans) {
+                if (vlan.getIp6Gateway() == null) {
+                    continue;
+                }
+                if (NetUtils.isSameIsolationId(vlanId, vlan.getVlanTag())) {
+                    if (NetUtils.isIp6RangeOverlap(ipv6Range, vlan.getIp6Range())) {
+                        throw new InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag()
+                                + " already has IPs that overlap with the new range. Please specify a different start IP/end IP.");
+                    }
+
+                    if (!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
+                        throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " has already been added with gateway " + vlan.getIp6Gateway()
+                                + ". Please specify a different tag.");
+                    }
+                }
+            }
+        }
+
+        // Check if the vlan is being used
+        if (!bypassVlanOverlapCheck && _zoneDao.findVnet(zoneId, physicalNetworkId, BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId))).size() > 0) {
+            throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+                    + zone.getName());
+        }
+
+        String ipRange = null;
+
+        if (ipv4) {
+            ipRange = startIP;
+            if (endIP != null) {
+                ipRange += "-" + endIP;
+            }
+        }
+
+        // Everything was fine, so persist the VLAN
+        final VlanVO vlan = commitVlanAndIpRange(zoneId, networkId, physicalNetworkId, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, domain, vlanOwner, vlanIp6Gateway, vlanIp6Cidr,
+                ipv4, zone, vlanType, ipv6Range, ipRange, forSystemVms);
+
+        return vlan;
+    }
+
+    private VlanVO commitVlanAndIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final Long podId, final String startIP, final String endIP,
+            final String vlanGateway, final String vlanNetmask, final String vlanId, final Domain domain, final Account vlanOwner, final String vlanIp6Gateway, final String vlanIp6Cidr,
+            final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, final String ipv6Range, final String ipRange, final boolean forSystemVms) {
+        return Transaction.execute(new TransactionCallback<VlanVO>() {
+            @Override
+            public VlanVO doInTransaction(final TransactionStatus status) {
+                VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, physicalNetworkId, vlanIp6Gateway, vlanIp6Cidr, ipv6Range);
+                s_logger.debug("Saving vlan range " + vlan);
+                vlan = _vlanDao.persist(vlan);
+
+                // IPv6 use a used ip map, is different from ipv4, no need to save
+                // public ip range
+                if (ipv4) {
+                    if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId, forSystemVms)) {
+                        throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support.");
+                    }
+                }
+
+                if (vlanOwner != null) {
+                    // This VLAN is account-specific, so create an AccountVlanMapVO
+                    // entry
+                    final AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId());
+                    _accountVlanMapDao.persist(accountVlanMapVO);
+
+                    // generate usage event for dedication of every ip address in the
+                    // range
+                    final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlan.getId());
+                    for (final IPAddressVO ip : ips) {
+                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(),
+                                ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
+                    }
+                    // increment resource count for dedicated public ip's
+                    _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size()));
+                } else if (domain != null && !forSystemVms) {
+                    // This VLAN is domain-wide, so create a DomainVlanMapVO entry
+                    final DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
+                    _domainVlanMapDao.persist(domainVlanMapVO);
+                } else if (podId != null) {
+                    // This VLAN is pod-wide, so create a PodVlanMapVO entry
+                    final PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId());
+                    _podVlanMapDao.persist(podVlanMapVO);
+                }
+                return vlan;
+            }
+        });
+
+    }
+
+    @Override
+    @DB
+    public boolean deleteVlanAndPublicIpRange(final long userId, final long vlanDbId, final Account caller) {
+        VlanVO vlanRange = _vlanDao.findById(vlanDbId);
+        if (vlanRange == null) {
+            throw new InvalidParameterValueException("Please specify a valid IP range id.");
+        }
+
+        boolean isAccountSpecific = false;
+        final List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanRange.getId());
+        // Check for account wide pool. It will have an entry for
+        // account_vlan_map.
+        if (acctVln != null && !acctVln.isEmpty()) {
+            isAccountSpecific = true;
+        }
+
+        boolean isDomainSpecific = false;
+        List<DomainVlanMapVO> domainVlan = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanRange.getId());
+        // Check for domain wide pool. It will have an entry for domain_vlan_map.
+        if (domainVlan != null && !domainVlan.isEmpty()) {
+            isDomainSpecific = true;
+        }
+
+        // Check if the VLAN has any allocated public IPs
+        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
+        if (isAccountSpecific) {
+            int resourceCountToBeDecrement = 0;
+            try {
+                vlanRange = _vlanDao.acquireInLockTable(vlanDbId, 30);
+                if (vlanRange == null) {
+                    throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("lock vlan " + vlanDbId + " is acquired");
+                }
+                for (final IPAddressVO ip : ips) {
+                    boolean success = true;
+                    if (ip.isOneToOneNat()) {
+                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
+                                + " belonging to the range is used for static nat purposes. Cleanup the rules first");
+                    }
+
+                    if (ip.isSourceNat()) {
+                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
+                                + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId()
+                                + ". IP range with the source nat ip address can be removed either as a part of Network, or account removal");
+                    }
+
+                    if (_firewallDao.countRulesByIpId(ip.getId()) > 0) {
+                        throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip
+                                + " belonging to the range has firewall rules applied. Cleanup the rules first");
+                    }
+                    if (ip.getAllocatedTime() != null) {// This means IP is allocated
+                        // release public ip address here
+                        success = _ipAddrMgr.disassociatePublicIpAddress(ip.getId(), userId, caller);
+                    }
+                    if (!success) {
+                        s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal");
+                    } else {
+                        resourceCountToBeDecrement++;
+                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getAccountId(), ip.getDataCenterId(), ip.getId(),
+                                ip.getAddress().toString(), ip.isSourceNat(), vlanRange.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
+                    }
+                }
+            } finally {
+                _vlanDao.releaseFromLockTable(vlanDbId);
+                if (resourceCountToBeDecrement > 0) {  //Making sure to decrement the count of only success operations above. For any reaason if disassociation fails then this number will vary from original range length.
+                    _resourceLimitMgr.decrementResourceCount(acctVln.get(0).getAccountId(), ResourceType.public_ip, new Long(resourceCountToBeDecrement));
+                }
+            }
+        } else {   // !isAccountSpecific
+            final NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(vlanRange.getVlanGateway(), vlanRange.getNetworkId(), NicIpAlias.State.active);
+            //check if the ipalias belongs to the vlan range being deleted.
+            if (ipAlias != null && vlanDbId == _publicIpAddressDao.findByIpAndSourceNetworkId(vlanRange.getNetworkId(), ipAlias.getIp4Address()).getVlanId()) {
+                throw new InvalidParameterValueException("Cannot delete vlan range " + vlanDbId + " as " + ipAlias.getIp4Address()
+                        + "is being used for providing dhcp service in this subnet. Delete all VMs in this subnet and try again");
+            }
+            final long allocIpCount = _publicIpAddressDao.countIPs(vlanRange.getDataCenterId(), vlanDbId, true);
+            if (allocIpCount > 0) {
+                throw new InvalidParameterValueException(allocIpCount + "  Ips are in use. Cannot delete this vlan");
+            }
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                _publicIpAddressDao.deletePublicIPRange(vlanDbId);
+                _vlanDao.remove(vlanDbId);
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DEDICATE, eventDescription = "dedicating vlan ip range", async = false)
+    public Vlan dedicatePublicIpRange(final DedicatePublicIpRangeCmd cmd) throws ResourceAllocationException {
+        final Long vlanDbId = cmd.getId();
+        final String accountName = cmd.getAccountName();
+        final Long domainId = cmd.getDomainId();
+        final Long projectId = cmd.getProjectId();
+
+        // Check if account is valid
+        Account vlanOwner = null;
+        if (projectId != null) {
+            if (accountName != null) {
+                throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
+            }
+            final Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+            }
+            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
+            if (vlanOwner == null) {
+                throw new InvalidParameterValueException("Please specify a valid projectId");
+            }
+        }
+
+        Domain domain = null;
+        if (accountName != null && domainId != null) {
+            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
+            if (vlanOwner == null) {
+                throw new InvalidParameterValueException("Unable to find account by name " + accountName);
+            } else if (vlanOwner.getId() == Account.ACCOUNT_ID_SYSTEM) {
+                throw new InvalidParameterValueException("Please specify a valid account. Cannot dedicate IP range to system account");
+            }
+        } else if (domainId != null) {
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Please specify a valid domain id");
+            }
+        }
+
+        // Check if range is valid
+        final VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if (vlan == null) {
+            throw new InvalidParameterValueException("Unable to find vlan by id " + vlanDbId);
+        }
+
+        // Check if range has already been dedicated
+        final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
+        if (maps != null && !maps.isEmpty()) {
+            throw new InvalidParameterValueException("Specified Public IP range has already been dedicated");
+        }
+
+        List<DomainVlanMapVO> domainmaps = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanDbId);
+        if (domainmaps != null && !domainmaps.isEmpty()) {
+            throw new InvalidParameterValueException("Specified Public IP range has already been dedicated to a domain");
+        }
+
+        // Verify that zone exists and is advanced
+        final Long zoneId = vlan.getDataCenterId();
+        final DataCenterVO zone = _zoneDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+        }
+        if (zone.getNetworkType() == NetworkType.Basic) {
+            throw new InvalidParameterValueException("Public IP range can be dedicated to an account only in the zone of type " + NetworkType.Advanced);
+        }
+
+        // Check Public IP resource limits
+        if (vlanOwner != null) {
+            final int accountPublicIpRange = _publicIpAddressDao.countIPs(zoneId, vlanDbId, false);
+            _resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountPublicIpRange);
+        }
+
+        // Check if any of the Public IP addresses is allocated to another
+        // account
+        boolean forSystemVms = false;
+        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
+        for (final IPAddressVO ip : ips) {
+            forSystemVms = ip.isForSystemVms();
+            final Long allocatedToAccountId = ip.getAllocatedToAccountId();
+            if (allocatedToAccountId != null) {
+                if (vlanOwner != null && allocatedToAccountId != vlanOwner.getId()) {
+                    throw new InvalidParameterValueException(ip.getAddress() + " Public IP address in range is allocated to another account ");
+                }
+                final Account accountAllocatedTo = _accountMgr.getActiveAccountById(allocatedToAccountId);
+                if (vlanOwner == null && domain != null && domain.getId() != accountAllocatedTo.getDomainId()){
+                    throw new InvalidParameterValueException(ip.getAddress()
+                            + " Public IP address in range is allocated to another domain/account ");
+                }
+            }
+        }
+
+        if (vlanOwner != null) {
+            // Create an AccountVlanMapVO entry
+            final AccountVlanMapVO accountVlanMapVO = new AccountVlanMapVO(vlanOwner.getId(), vlan.getId());
+            _accountVlanMapDao.persist(accountVlanMapVO);
+
+           // generate usage event for dedication of every ip address in the range
+            for (final IPAddressVO ip : ips) {
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, vlanOwner.getId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(),
+                        vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
+            }
+        } else if (domain != null && !forSystemVms) {
+            // Create an DomainVlanMapVO entry
+            DomainVlanMapVO domainVlanMapVO = new DomainVlanMapVO(domain.getId(), vlan.getId());
+            _domainVlanMapDao.persist(domainVlanMapVO);
+        }
+
+        // increment resource count for dedicated public ip's
+        if (vlanOwner != null) {
+            _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size()));
+        }
+
+        return vlan;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_RELEASE, eventDescription = "releasing a public ip range", async = false)
+    public boolean releasePublicIpRange(final ReleasePublicIpRangeCmd cmd) {
+        final Long vlanDbId = cmd.getId();
+
+        final VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if (vlan == null) {
+            throw new InvalidParameterValueException("Please specify a valid IP range id.");
+        }
+
+        return releasePublicIpRange(vlanDbId, CallContext.current().getCallingUserId(), CallContext.current().getCallingAccount());
+    }
+
+    @DB
+    public boolean releasePublicIpRange(final long vlanDbId, final long userId, final Account caller) {
+        VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if(vlan == null) {
+            s_logger.warn("VLAN information for Account '" + caller + "', User '" + userId + "' VLAN '" + vlanDbId + "' is null. This is NPE situation.");
+        }
+
+        // Verify range is dedicated
+        boolean isAccountSpecific = false;
+        final List<AccountVlanMapVO> acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanDbId);
+        // Verify range is dedicated
+        if (acctVln != null && !acctVln.isEmpty()) {
+            isAccountSpecific = true;
+        }
+
+        boolean isDomainSpecific = false;
+        final List<DomainVlanMapVO> domainVlan = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanDbId);
+        // Check for domain wide pool. It will have an entry for domain_vlan_map.
+        if (domainVlan != null && !domainVlan.isEmpty()) {
+            isDomainSpecific = true;
+        }
+
+        if (!isAccountSpecific && !isDomainSpecific) {
+            throw new InvalidParameterValueException("Can't release Public IP range " + vlanDbId
+                    + " as it not dedicated to any domain and any account");
+        }
+        // Check if range has any allocated public IPs
+        final long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true);
+        final List<IPAddressVO> ips = _publicIpAddressDao.listByVlanId(vlanDbId);
+        boolean success = true;
+        final List<IPAddressVO> ipsInUse = new ArrayList<IPAddressVO>();
+        if (allocIpCount > 0) {
+            try {
+                vlan = _vlanDao.acquireInLockTable(vlanDbId, 30);
+                if (vlan == null) {
+                    throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId);
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("lock vlan " + vlanDbId + " is acquired");
+                }
+                for (final IPAddressVO ip : ips) {
+                    // Disassociate allocated IP's that are not in use
+                    if (!ip.isOneToOneNat() && !ip.isSourceNat() && !(_firewallDao.countRulesByIpId(ip.getId()) > 0)) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Releasing Public IP addresses" + ip + " of vlan " + vlanDbId + " as part of Public IP" + " range release to the system pool");
+                        }
+                        success = success && _ipAddrMgr.disassociatePublicIpAddress(ip.getId(), userId, caller);
+                    } else {
+                        ipsInUse.add(ip);
+                    }
+                }
+                if (!success) {
+                    s_logger.warn("Some Public IP addresses that were not in use failed to be released as a part of" + " vlan " + vlanDbId + "release to the system pool");
+                }
+            } finally {
+                _vlanDao.releaseFromLockTable(vlanDbId);
+            }
+        }
+
+        // A Public IP range can only be dedicated to one account at a time
+        if (isAccountSpecific && _accountVlanMapDao.remove(acctVln.get(0).getId())) {
+            // generate usage events to remove dedication for every ip in the range that has been disassociated
+            for (final IPAddressVO ip : ips) {
+                if (!ipsInUse.contains(ip)) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getAccountId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(),
+                            ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid());
+                }
+            }
+            // decrement resource count for dedicated public ip's
+            _resourceLimitMgr.decrementResourceCount(acctVln.get(0).getAccountId(), ResourceType.public_ip, new Long(ips.size()));
+            return true;
+        } else if (isDomainSpecific && _domainVlanMapDao.remove(domainVlan.get(0).getId())) {
+            s_logger.debug("Remove the vlan from domain_vlan_map successfully.");
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @DB
+    protected boolean savePublicIPRange(final String startIP, final String endIP, final long zoneId, final long vlanDbId, final long sourceNetworkid, final long physicalNetworkId, final boolean forSystemVms) {
+        final long startIPLong = NetUtils.ip2Long(startIP);
+        final long endIPLong = NetUtils.ip2Long(endIP);
+
+        final List<String> problemIps = Transaction.execute(new TransactionCallback<List<String>>() {
+            @Override
+            public List<String> doInTransaction(final TransactionStatus status) {
+                final IPRangeConfig config = new IPRangeConfig();
+                return config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, zoneId, vlanDbId, sourceNetworkid, physicalNetworkId, forSystemVms);
+            }
+        });
+
+        return problemIps != null && problemIps.size() == 0;
+    }
+
+    private void checkPublicIpRangeErrors(final long zoneId, final String vlanId, final String vlanGateway, final String vlanNetmask, final String startIP, final String endIP) {
+        // Check that the start and end IPs are valid
+        if (!NetUtils.isValidIp4(startIP)) {
+            throw new InvalidParameterValueException("Please specify a valid start IP");
+        }
+
+        if (endIP != null && !NetUtils.isValidIp4(endIP)) {
+            throw new InvalidParameterValueException("Please specify a valid end IP");
+        }
+
+        if (endIP != null && !NetUtils.validIpRange(startIP, endIP)) {
+            throw new InvalidParameterValueException("Please specify a valid IP range.");
+        }
+
+        // Check that the IPs that are being added are compatible with the
+        // VLAN's gateway and netmask
+        if (vlanNetmask == null) {
+            throw new InvalidParameterValueException("Please ensure that your IP range's netmask is specified");
+        }
+
+        if (endIP != null && !NetUtils.sameSubnet(startIP, endIP, vlanNetmask)) {
+            throw new InvalidParameterValueException("Please ensure that your start IP and end IP are in the same subnet, as per the IP range's netmask.");
+        }
+
+        if (!NetUtils.sameSubnet(startIP, vlanGateway, vlanNetmask)) {
+            throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as your IP range's gateway, as per the IP range's netmask.");
+        }
+
+        if (endIP != null && !NetUtils.sameSubnet(endIP, vlanGateway, vlanNetmask)) {
+            throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as your IP range's gateway, as per the IP range's netmask.");
+        }
+        // check if the gatewayip is the part of the ip range being added.
+        // RFC 3021 - 31-Bit Prefixes on IPv4 Point-to-Point Links
+        //     GW              Netmask         Stat IP        End IP
+        // 192.168.24.0 - 255.255.255.254 - 192.168.24.0 - 192.168.24.1
+        // https://tools.ietf.org/html/rfc3021
+        // Added by Wilder Rodrigues
+        final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
+        if (!NetUtils.is31PrefixCidr(newCidr)) {
+            if (NetUtils.ipRangesOverlap(startIP, endIP, vlanGateway, vlanGateway)) {
+                throw new InvalidParameterValueException(
+                        "The gateway ip should not be the part of the ip range being added.");
+            }
+        }
+    }
+
+    private void checkConflictsWithPortableIpRange(final long zoneId, final String vlanId, final String vlanGateway, final String vlanNetmask, final String startIP, final String endIP) {
+        // check and throw exception if there is portable IP range that overlaps with public ip range being configured
+        if (checkOverlapPortableIpRange(_regionDao.getRegionId(), startIP, endIP)) {
+            throw new InvalidParameterValueException("Ip range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region "
+                    + _regionDao.getRegionId());
+        }
+
+        // verify and throw exception if the VLAN Id is used by any portable IP range
+        final List<PortableIpRangeVO> existingPortableIPRanges = _portableIpRangeDao.listByRegionId(_regionDao.getRegionId());
+        if (existingPortableIPRanges != null && !existingPortableIPRanges.isEmpty()) {
+            for (final PortableIpRangeVO portableIpRange : existingPortableIPRanges) {
+                if (NetUtils.isSameIsolationId(portableIpRange.getVlanTag(), vlanId)) {
+                    throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for portable ip range in this region");
+                }
+            }
+        }
+    }
+
+    private String getCidrAddress(final String cidr) {
+        final String[] cidrPair = cidr.split("\\/");
+        return cidrPair[0];
+    }
+
+    private int getCidrSize(final String cidr) {
+        final String[] cidrPair = cidr.split("\\/");
+        return Integer.parseInt(cidrPair[1]);
+    }
+
+    @Override
+    public void checkPodCidrSubnets(final long dcId, final Long podIdToBeSkipped, final String cidr) {
+        // For each pod, return an error if any of the following is true:
+        // The pod's CIDR subnet conflicts with the CIDR subnet of any other pod
+
+        // Check if the CIDR conflicts with the Guest Network or other pods
+        long skipPod = 0;
+        if (podIdToBeSkipped != null) {
+            skipPod = podIdToBeSkipped;
+        }
+        final HashMap<Long, List<Object>> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(dcId, skipPod);
+        final List<Object> newCidrPair = new ArrayList<Object>();
+        newCidrPair.add(0, getCidrAddress(cidr));
+        newCidrPair.add(1, (long)getCidrSize(cidr));
+        currentPodCidrSubnets.put(new Long(-1), newCidrPair);
+
+        final DataCenterVO dcVo = _zoneDao.findById(dcId);
+        final String guestNetworkCidr = dcVo.getGuestNetworkCidr();
+
+        // Guest cidr can be null for Basic zone
+        String guestIpNetwork = null;
+        Long guestCidrSize = null;
+        if (guestNetworkCidr != null) {
+            final String[] cidrTuple = guestNetworkCidr.split("\\/");
+            guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]));
+            guestCidrSize = Long.parseLong(cidrTuple[1]);
+        }
+
+        final String zoneName = getZoneName(dcId);
+
+        // Iterate through all pods in this zone
+        for (final Long podId : currentPodCidrSubnets.keySet()) {
+            String podName;
+            if (podId.longValue() == -1) {
+                podName = "newPod";
+            } else {
+                podName = getPodName(podId.longValue());
+            }
+
+            final List<Object> cidrPair = currentPodCidrSubnets.get(podId);
+            final String cidrAddress = (String)cidrPair.get(0);
+            final long cidrSize = ((Long)cidrPair.get(1)).longValue();
+
+            long cidrSizeToUse = -1;
+            if (guestCidrSize == null || cidrSize < guestCidrSize) {
+                cidrSizeToUse = cidrSize;
+            } else {
+                cidrSizeToUse = guestCidrSize;
+            }
+
+            String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
+
+            if (guestNetworkCidr != null) {
+                final String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse);
+                // Check that cidrSubnet does not equal guestSubnet
+                if (cidrSubnet.equals(guestSubnet)) {
+                    if (podName.equals("newPod")) {
+                        throw new InvalidParameterValueException(
+                                "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR.");
+                    } else {
+                        throw new InvalidParameterValueException(
+                                "Warning: The subnet of pod "
+                                        + podName
+                                        + " in zone "
+                                        + zoneName
+                                        + " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management.");
+                    }
+                }
+            }
+
+            // Iterate through the rest of the pods
+            for (final Long otherPodId : currentPodCidrSubnets.keySet()) {
+                if (podId.equals(otherPodId)) {
+                    continue;
+                }
+
+                // Check that cidrSubnet does not equal otherCidrSubnet
+                final List<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId);
+                final String otherCidrAddress = (String)otherCidrPair.get(0);
+                final long otherCidrSize = ((Long)otherCidrPair.get(1)).longValue();
+
+                if (cidrSize < otherCidrSize) {
+                    cidrSizeToUse = cidrSize;
+                } else {
+                    cidrSizeToUse = otherCidrSize;
+                }
+
+                cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
+                final String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse);
+
+                if (cidrSubnet.equals(otherCidrSubnet)) {
+                    final String otherPodName = getPodName(otherPodId.longValue());
+                    if (podName.equals("newPod")) {
+                        throw new InvalidParameterValueException("The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName
+                                + ". Please specify a different CIDR.");
+                    } else {
+                        throw new InvalidParameterValueException("Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName
+                                + " have conflicting CIDR subnets. Please change the CIDR of one of these pods.");
+                    }
+                }
+            }
+        }
+
+    }
+
+    private boolean validPod(final long podId) {
+        return _podDao.findById(podId) != null;
+    }
+
+    private boolean validPod(final String podName, final long zoneId) {
+        if (!validZone(zoneId)) {
+            return false;
+        }
+
+        return _podDao.findByName(podName, zoneId) != null;
+    }
+
+    private String getPodName(final long podId) {
+        return _podDao.findById(new Long(podId)).getName();
+    }
+
+    private boolean validZone(final String zoneName) {
+        return _zoneDao.findByName(zoneName) != null;
+    }
+
+    private boolean validZone(final long zoneId) {
+        return _zoneDao.findById(zoneId) != null;
+    }
+
+    private String getZoneName(final long zoneId) {
+        final DataCenterVO zone = _zoneDao.findById(new Long(zoneId));
+        if (zone != null) {
+            return zone.getName();
+        } else {
+            return null;
+        }
+    }
+
+    private String[] getLinkLocalIPRange() {
+        final String ipNums = _configDao.getValue("linkLocalIp.nums");
+        final int nums = Integer.parseInt(ipNums);
+        if (nums > 16 || nums <= 0) {
+            throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
+        }
+        /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
+        final String[] ipRanges = NetUtils.getLinkLocalIPRange(nums);
+        if (ipRanges == null) {
+            throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
+        }
+        return ipRanges;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VLAN_IP_RANGE_DELETE, eventDescription = "deleting vlan ip range", async = false)
+    public boolean deleteVlanIpRange(final DeleteVlanIpRangeCmd cmd) {
+        final Long vlanDbId = cmd.getId();
+
+        final VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if (vlan == null) {
+            throw new InvalidParameterValueException("Please specify a valid IP range id.");
+        }
+
+        return deleteVlanAndPublicIpRange(CallContext.current().getCallingUserId(), vlanDbId, CallContext.current().getCallingAccount());
+    }
+
+    @Override
+    public void checkDiskOfferingAccess(final Account caller, final DiskOffering dof) {
+        for (final SecurityChecker checker : _secChecker) {
+            if (checker.checkAccess(caller, dof)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + caller + " to disk offering:" + dof.getId() + " by " + checker.getName());
+                }
+                return;
+            } else {
+                throw new PermissionDeniedException("Access denied to " + caller + " by " + checker.getName());
+            }
+        }
+
+        assert false : "How can all of the security checkers pass on checking this caller?";
+        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to disk offering:" + dof.getId());
+    }
+
+    @Override
+    public void checkZoneAccess(final Account caller, final DataCenter zone) {
+        for (final SecurityChecker checker : _secChecker) {
+            if (checker.checkAccess(caller, zone)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + caller + " to zone:" + zone.getId() + " by " + checker.getName());
+                }
+                return;
+            } else {
+                throw new PermissionDeniedException("Access denied to " + caller + " by " + checker.getName() + " for zone " + zone.getId());
+            }
+        }
+
+        assert false : "How can all of the security checkers pass on checking this caller?";
+        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to zone:" + zone.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_CREATE, eventDescription = "creating network offering")
+    public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) {
+        final String name = cmd.getNetworkOfferingName();
+        final String displayText = cmd.getDisplayText();
+        final String tags = cmd.getTags();
+        final String trafficTypeString = cmd.getTraffictype();
+        final boolean specifyVlan = cmd.getSpecifyVlan();
+        final boolean conserveMode = cmd.getConserveMode();
+        final String availabilityStr = cmd.getAvailability();
+        Integer networkRate = cmd.getNetworkRate();
+        TrafficType trafficType = null;
+        Availability availability = null;
+        Network.GuestType guestType = null;
+        final boolean specifyIpRanges = cmd.getSpecifyIpRanges();
+        final boolean isPersistent = cmd.getIsPersistent();
+        final Map<String, String> detailsStr = cmd.getDetails();
+        final Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy();
+        Boolean forVpc = cmd.getForVpc();
+
+        Integer maxconn = null;
+        boolean enableKeepAlive = false;
+        String servicePackageuuid = cmd.getServicePackageId();
+        // Verify traffic type
+        for (final TrafficType tType : TrafficType.values()) {
+            if (tType.name().equalsIgnoreCase(trafficTypeString)) {
+                trafficType = tType;
+                break;
+            }
+        }
+        if (trafficType == null) {
+            throw new InvalidParameterValueException("Invalid value for traffictype. Supported traffic types: Public, Management, Control, Guest, Vlan or Storage");
+        }
+
+        // Only GUEST traffic type is supported in Acton
+        if (trafficType != TrafficType.Guest) {
+            throw new InvalidParameterValueException("Only traffic type " + TrafficType.Guest + " is supported in the current release");
+        }
+
+        // Verify offering type
+        for (final Network.GuestType offType : Network.GuestType.values()) {
+            if (offType.name().equalsIgnoreCase(cmd.getGuestIpType())) {
+                guestType = offType;
+                break;
+            }
+        }
+
+        if (guestType == null) {
+            throw new InvalidParameterValueException("Invalid \"type\" parameter is given; can have Shared and Isolated values");
+        }
+
+        // Verify availability
+        for (final Availability avlb : Availability.values()) {
+            if (avlb.name().equalsIgnoreCase(availabilityStr)) {
+                availability = avlb;
+            }
+        }
+
+        if (availability == null) {
+            throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
+        }
+
+        if (networkRate != null && networkRate < 0) {
+            networkRate = 0;
+        }
+
+        final Long serviceOfferingId = cmd.getServiceOfferingId();
+
+        if (serviceOfferingId != null) {
+            final ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOfferingId);
+            if (offering == null) {
+                throw new InvalidParameterValueException("Cannot find specified service offering: " + serviceOfferingId);
+            }
+            if (!VirtualMachine.Type.DomainRouter.toString().equalsIgnoreCase(offering.getSystemVmType())) {
+                throw new InvalidParameterValueException("The specified service offering " + serviceOfferingId + " cannot be used by virtual router!");
+            }
+        }
+
+        // configure service provider map
+        final Map<Network.Service, Set<Network.Provider>> serviceProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
+        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
+
+        // populate the services first
+        for (final String serviceName : cmd.getSupportedServices()) {
+            // validate if the service is supported
+            final Service service = Network.Service.getService(serviceName);
+            if (service == null || service == Service.Gateway) {
+                throw new InvalidParameterValueException("Invalid service " + serviceName);
+            }
+
+            if (forVpc == null) {
+                if (service == Service.SecurityGroup || service == Service.Firewall) {
+                    forVpc = false;
+                } else if (service == Service.NetworkACL) {
+                    forVpc = true;
+                }
+            }
+
+            if (service == Service.SecurityGroup) {
+                // allow security group service for Shared networks only
+                if (guestType != GuestType.Shared) {
+                    throw new InvalidParameterValueException("Secrity group service is supported for network offerings with guest ip type " + GuestType.Shared);
+                }
+                final Set<Network.Provider> sgProviders = new HashSet<Network.Provider>();
+                sgProviders.add(Provider.SecurityGroupProvider);
+                serviceProviderMap.put(Network.Service.SecurityGroup, sgProviders);
+                continue;
+            }
+
+            serviceProviderMap.put(service, defaultProviders);
+        }
+
+        // add gateway provider (if sourceNat provider is enabled)
+        final Set<Provider> sourceNatServiceProviders = serviceProviderMap.get(Service.SourceNat);
+        if (sourceNatServiceProviders != null && !sourceNatServiceProviders.isEmpty()) {
+            serviceProviderMap.put(Service.Gateway, sourceNatServiceProviders);
+        }
+
+        // populate providers
+        final Map<Provider, Set<Service>> providerCombinationToVerify = new HashMap<Provider, Set<Service>>();
+        final Map<String, List<String>> svcPrv = cmd.getServiceProviders();
+        Provider firewallProvider = null;
+        Provider dhcpProvider = null;
+        Boolean IsVrUserdataProvider = false;
+        if (svcPrv != null) {
+            for (final String serviceStr : svcPrv.keySet()) {
+                final Network.Service service = Network.Service.getService(serviceStr);
+                if (serviceProviderMap.containsKey(service)) {
+                    final Set<Provider> providers = new HashSet<Provider>();
+                    // Allow to specify more than 1 provider per service only if
+                    // the service is LB
+                    if (!serviceStr.equalsIgnoreCase(Service.Lb.getName()) && svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) {
+                        throw new InvalidParameterValueException("In the current release only one provider can be " + "specified for the service if the service is not LB");
+                    }
+                    for (final String prvNameStr : svcPrv.get(serviceStr)) {
+                        // check if provider is supported
+                        final Network.Provider provider = Network.Provider.getProvider(prvNameStr);
+                        if (provider == null) {
+                            throw new InvalidParameterValueException("Invalid service provider: " + prvNameStr);
+                        }
+
+                        if (provider == Provider.JuniperSRX || provider == Provider.CiscoVnmc) {
+                            firewallProvider = provider;
+                        }
+
+                        if (provider == Provider.PaloAlto) {
+                            firewallProvider = Provider.PaloAlto;
+                        }
+
+                        if ((service == Service.PortForwarding || service == Service.StaticNat) && provider == Provider.VirtualRouter) {
+                            firewallProvider = Provider.VirtualRouter;
+                        }
+
+                        if (forVpc == null && VPC_ONLY_PROVIDERS.contains(provider)) {
+                            forVpc = true;
+                        }
+
+                        if (service == Service.Dhcp) {
+                            dhcpProvider = provider;
+                        }
+
+                        if (service == Service.UserData && provider == Provider.VirtualRouter) {
+                            IsVrUserdataProvider = true;
+                        }
+
+                        providers.add(provider);
+
+                        Set<Service> serviceSet = null;
+                        if (providerCombinationToVerify.get(provider) == null) {
+                            serviceSet = new HashSet<Service>();
+                        } else {
+                            serviceSet = providerCombinationToVerify.get(provider);
+                        }
+                        serviceSet.add(service);
+                        providerCombinationToVerify.put(provider, serviceSet);
+
+                    }
+                    serviceProviderMap.put(service, providers);
+                } else {
+                    throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network " + "offering, can't add a provider to it");
+                }
+            }
+        }
+
+        // dhcp provider and userdata provider should be same because vm will be contacting dhcp server for user data.
+        if (dhcpProvider == null && IsVrUserdataProvider) {
+            s_logger.debug("User data provider VR can't be selected without VR as dhcp provider. In this case VM fails to contact the DHCP server for userdata");
+            throw new InvalidParameterValueException("Without VR as dhcp provider, User data can't selected for VR. Please select VR as DHCP provider ");
+        }
+
+        // validate providers combination here
+        _networkModel.canProviderSupportServices(providerCombinationToVerify);
+
+        // validate the LB service capabilities specified in the network
+        // offering
+        final Map<Capability, String> lbServiceCapabilityMap = cmd.getServiceCapabilities(Service.Lb);
+        if (!serviceProviderMap.containsKey(Service.Lb) && lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
+            throw new InvalidParameterValueException("Capabilities for LB service can be specifed only when LB service is enabled for network offering.");
+        }
+        validateLoadBalancerServiceCapabilities(lbServiceCapabilityMap);
+
+        if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
+            maxconn = cmd.getMaxconnections();
+            if (maxconn == null) {
+                maxconn = Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyMaxConn.key()));
+            }
+        }
+        if (cmd.getKeepAliveEnabled() != null && cmd.getKeepAliveEnabled()) {
+            enableKeepAlive = true;
+        }
+
+        // validate the Source NAT service capabilities specified in the network
+        // offering
+        final Map<Capability, String> sourceNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.SourceNat);
+        if (!serviceProviderMap.containsKey(Service.SourceNat) && sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
+            throw new InvalidParameterValueException("Capabilities for source NAT service can be specifed only when source NAT service is enabled for network offering.");
+        }
+        validateSourceNatServiceCapablities(sourceNatServiceCapabilityMap);
+
+        // validate the Static Nat service capabilities specified in the network
+        // offering
+        final Map<Capability, String> staticNatServiceCapabilityMap = cmd.getServiceCapabilities(Service.StaticNat);
+        if (!serviceProviderMap.containsKey(Service.StaticNat) && sourceNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
+            throw new InvalidParameterValueException("Capabilities for static NAT service can be specifed only when static NAT service is enabled for network offering.");
+        }
+        validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
+
+        // validate the 'Connectivity' service capabilities specified in the network offering, if 'Connectivity' service
+        // is in the supported services of network offering
+        final Map<Capability, String> connectivityServiceCapabilityMap = cmd.getServiceCapabilities(Service.Connectivity);
+        if (!serviceProviderMap.containsKey(Service.Connectivity) &&
+                connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty())  {
+            throw new InvalidParameterValueException("Capabilities for 'Connectivity' service can be specified " +
+                    "only when Connectivity service is enabled for network offering.");
+        }
+        validateConnectivityServiceCapablities(guestType, serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap);
+
+        final Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
+        serviceCapabilityMap.put(Service.Lb, lbServiceCapabilityMap);
+        serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap);
+        serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap);
+        serviceCapabilityMap.put(Service.Connectivity, connectivityServiceCapabilityMap);
+
+        // if Firewall service is missing, add Firewall service/provider
+        // combination
+        if (firewallProvider != null) {
+            s_logger.debug("Adding Firewall service with provider " + firewallProvider.getName());
+            final Set<Provider> firewallProviderSet = new HashSet<Provider>();
+            firewallProviderSet.add(firewallProvider);
+            serviceProviderMap.put(Service.Firewall, firewallProviderSet);
+            if (!(firewallProvider.getName().equals(Provider.JuniperSRX.getName()) || firewallProvider.getName().equals(Provider.PaloAlto.getName()) || firewallProvider.getName()
+                    .equals(Provider.VirtualRouter.getName())) && egressDefaultPolicy == false) {
+                throw new InvalidParameterValueException("Firewall egress with default policy " + egressDefaultPolicy + " is not supported by the provider "
+                        + firewallProvider.getName());
+            }
+        }
+
+        final Map<NetworkOffering.Detail, String> details = new HashMap<NetworkOffering.Detail, String>();
+        if (detailsStr != null) {
+            for (final String detailStr : detailsStr.keySet()) {
+                NetworkOffering.Detail offDetail = null;
+                for (final NetworkOffering.Detail supportedDetail : NetworkOffering.Detail.values()) {
+                    if (detailStr.equalsIgnoreCase(supportedDetail.toString())) {
+                        offDetail = supportedDetail;
+                        break;
+                    }
+                }
+                if (offDetail == null) {
+                    throw new InvalidParameterValueException("Unsupported detail " + detailStr);
+                }
+                details.put(offDetail, detailsStr.get(detailStr));
+            }
+        }
+
+        if (forVpc == null) {
+            forVpc = false;
+        }
+
+        final NetworkOffering offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false,
+                serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc);
+        CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
+        return offering;
+    }
+
+    void validateLoadBalancerServiceCapabilities(final Map<Capability, String> lbServiceCapabilityMap) {
+        if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
+            if (lbServiceCapabilityMap.keySet().size() > 3 || !lbServiceCapabilityMap.containsKey(Capability.SupportedLBIsolation)) {
+                throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", "
+                        + Capability.InlineMode.getName() + " capabilities can be sepcified for LB service");
+            }
+
+            for (final Capability cap : lbServiceCapabilityMap.keySet()) {
+                final String value = lbServiceCapabilityMap.get(cap);
+                if (cap == Capability.SupportedLBIsolation) {
+                    final boolean dedicatedLb = value.contains("dedicated");
+                    final boolean sharedLB = value.contains("shared");
+                    if (dedicatedLb && sharedLB || !dedicatedLb && !sharedLB) {
+                        throw new InvalidParameterValueException("Either dedicated or shared isolation can be specified for " + Capability.SupportedLBIsolation.getName());
+                    }
+                } else if (cap == Capability.ElasticLb) {
+                    final boolean enabled = value.contains("true");
+                    final boolean disabled = value.contains("false");
+                    if (!enabled && !disabled) {
+                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.ElasticLb.getName());
+                    }
+                } else if (cap == Capability.InlineMode) {
+                    final boolean enabled = value.contains("true");
+                    final boolean disabled = value.contains("false");
+                    if (!enabled && !disabled) {
+                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.InlineMode.getName());
+                    }
+                } else if (cap == Capability.LbSchemes) {
+                    final boolean internalLb = value.contains("internal");
+                    final boolean publicLb = value.contains("public");
+                    if (!internalLb && !publicLb) {
+                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.LbSchemes.getName());
+                    }
+                } else {
+                    throw new InvalidParameterValueException("Only " + Capability.SupportedLBIsolation.getName() + ", " + Capability.ElasticLb.getName() + ", "
+                            + Capability.InlineMode.getName() + ", " + Capability.LbSchemes.getName() + " capabilities can be sepcified for LB service");
+                }
+            }
+        }
+    }
+
+    void validateSourceNatServiceCapablities(final Map<Capability, String> sourceNatServiceCapabilityMap) {
+        if (sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
+            if (sourceNatServiceCapabilityMap.keySet().size() > 2) {
+                throw new InvalidParameterValueException("Only " + Capability.SupportedSourceNatTypes.getName() + " and " + Capability.RedundantRouter
+                        + " capabilities can be sepcified for source nat service");
+            }
+
+            for (final Map.Entry<Capability ,String> srcNatPair : sourceNatServiceCapabilityMap.entrySet()) {
+                final Capability capability = srcNatPair.getKey();
+                final String value = srcNatPair.getValue();
+                if (capability == Capability.SupportedSourceNatTypes) {
+                    final boolean perAccount = value.contains("peraccount");
+                    final boolean perZone = value.contains("perzone");
+                    if (perAccount && perZone || !perAccount && !perZone) {
+                        throw new InvalidParameterValueException("Either peraccount or perzone source NAT type can be specified for "
+                                + Capability.SupportedSourceNatTypes.getName());
+                    }
+                } else if (capability == Capability.RedundantRouter) {
+                    final boolean enabled = value.contains("true");
+                    final boolean disabled = value.contains("false");
+                    if (!enabled && !disabled) {
+                        throw new InvalidParameterValueException("Unknown specified value for " + Capability.RedundantRouter.getName());
+                    }
+                } else {
+                    throw new InvalidParameterValueException("Only " + Capability.SupportedSourceNatTypes.getName() + " and " + Capability.RedundantRouter
+                            + " capabilities can be sepcified for source nat service");
+                }
+            }
+        }
+    }
+
+    void validateStaticNatServiceCapablities(final Map<Capability, String> staticNatServiceCapabilityMap) {
+        if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
+            boolean eipEnabled = false;
+            boolean associatePublicIP = true;
+            for (final Capability capability : staticNatServiceCapabilityMap.keySet()) {
+                final String value = staticNatServiceCapabilityMap.get(capability).toLowerCase();
+                if (!(value.contains("true") ^ value.contains("false"))) {
+                    throw new InvalidParameterValueException("Unknown specified value (" + value + ") for " + capability);
+                }
+                if (capability == Capability.ElasticIp) {
+                    eipEnabled = value.contains("true");
+                } else if (capability == Capability.AssociatePublicIP) {
+                    associatePublicIP = value.contains("true");
+                } else {
+                    throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and " + Capability.AssociatePublicIP.getName()
+                            + " capabilitiy can be sepcified for static nat service");
+                }
+            }
+            if (!eipEnabled && associatePublicIP) {
+                throw new InvalidParameterValueException("Capability " + Capability.AssociatePublicIP.getName() + " can only be set when capability "
+                        + Capability.ElasticIp.getName() + " is true");
+            }
+        }
+    }
+
+    void validateConnectivityServiceCapablities(final Network.GuestType guestType, final Set<Provider> providers, final Map<Capability, String> connectivityServiceCapabilityMap) {
+        if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
+            for (final Map.Entry<Capability, String>entry: connectivityServiceCapabilityMap.entrySet()) {
+                final Capability capability = entry.getKey();
+                if (capability == Capability.StretchedL2Subnet || capability == Capability.PublicAccess) {
+                    final String value = entry.getValue().toLowerCase();
+                    if (!(value.contains("true") ^ value.contains("false"))) {
+                        throw new InvalidParameterValueException("Invalid value (" + value + ") for " + capability +
+                                " should be true/false");
+                    } else if (capability == Capability.PublicAccess && guestType != GuestType.Shared) {
+                        throw new InvalidParameterValueException("Capability " + capability.getName() + " can only be enabled for network offerings " +
+                                "with guest type Shared.");
+                    }
+                } else {
+                    throw new InvalidParameterValueException("Capability " + capability.getName() + " can not be "
+                            + " specified with connectivity service.");
+                }
+            }
+
+            // validate connectivity service provider actually supports specified capabilities
+            if (providers != null && !providers.isEmpty()) {
+                for (Capability capability : connectivityServiceCapabilityMap.keySet()) {
+                    _networkModel.providerSupportsCapability(providers, Service.Connectivity, capability);
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB
+    public NetworkOfferingVO createNetworkOffering(final String name, final String displayText, final TrafficType trafficType, String tags, final boolean specifyVlan,
+            final Availability availability,
+            final Integer networkRate, final Map<Service, Set<Provider>> serviceProviderMap, final boolean isDefault, final GuestType type, final boolean systemOnly,
+            final Long serviceOfferingId,
+            final boolean conserveMode, final Map<Service, Map<Capability, String>> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent,
+            final Map<Detail, String> details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive, Boolean forVpc) {
+
+        String servicePackageUuid;
+        String spDescription = null;
+        if (details == null) {
+            servicePackageUuid = null;
+        } else {
+            servicePackageUuid = details.get(NetworkOffering.Detail.servicepackageuuid);
+            spDescription = details.get(NetworkOffering.Detail.servicepackagedescription);
+        }
+
+
+        final String multicastRateStr = _configDao.getValue("multicast.throttling.rate");
+        final int multicastRate = multicastRateStr == null ? 10 : Integer.parseInt(multicastRateStr);
+        tags = StringUtils.cleanupTags(tags);
+
+        // specifyVlan should always be true for Shared network offerings
+        if (!specifyVlan && type == GuestType.Shared) {
+            Set<Provider> connectivityProviders = serviceProviderMap != null ? serviceProviderMap.get(Service.Connectivity) : null;
+            if (CollectionUtils.isEmpty(connectivityProviders) || !_networkModel.providerSupportsCapability(connectivityProviders, Service.Connectivity, Capability.NoVlan)) {
+                throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type);
+            }
+        }
+
+        // specifyIpRanges should always be true for Shared networks
+        // specifyIpRanges can only be true for Isolated networks with no Source
+        // Nat service
+        if (specifyIpRanges) {
+            if (type == GuestType.Isolated) {
+                if (serviceProviderMap.containsKey(Service.SourceNat)) {
+                    throw new InvalidParameterValueException("SpecifyIpRanges can only be true for Shared network offerings and Isolated with no SourceNat service");
+                }
+            }
+        } else {
+            if (type == GuestType.Shared) {
+                throw new InvalidParameterValueException("SpecifyIpRanges should always be true for Shared network offerings");
+            }
+        }
+
+        // isPersistent should always be false for Shared network Offerings
+        if (isPersistent && type == GuestType.Shared) {
+            throw new InvalidParameterValueException("isPersistent should be false if network offering's type is " + type);
+        }
+
+        // validate availability value
+        if (availability == NetworkOffering.Availability.Required) {
+            final boolean canOffBeRequired = type == GuestType.Isolated && serviceProviderMap.containsKey(Service.SourceNat);
+            if (!canOffBeRequired) {
+                throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
+                        + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
+            }
+
+            // only one network offering in the system can be Required
+            final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+            if (!offerings.isEmpty()) {
+                throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required);
+            }
+        }
+
+        boolean dedicatedLb = false;
+        boolean elasticLb = false;
+        boolean sharedSourceNat = false;
+        boolean redundantRouter = false;
+        boolean elasticIp = false;
+        boolean associatePublicIp = false;
+        boolean inline = false;
+        boolean publicLb = false;
+        boolean internalLb = false;
+        boolean strechedL2Subnet = false;
+        boolean publicAccess = false;
+
+        if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) {
+            final Map<Capability, String> lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb);
+
+            if (lbServiceCapabilityMap != null && !lbServiceCapabilityMap.isEmpty()) {
+                final String isolationCapability = lbServiceCapabilityMap.get(Capability.SupportedLBIsolation);
+                if (isolationCapability != null) {
+                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.SupportedLBIsolation, isolationCapability);
+                    dedicatedLb = isolationCapability.contains("dedicated");
+                } else {
+                    dedicatedLb = true;
+                }
+
+                final String param = lbServiceCapabilityMap.get(Capability.ElasticLb);
+                if (param != null) {
+                    elasticLb = param.contains("true");
+                }
+
+                final String inlineMode = lbServiceCapabilityMap.get(Capability.InlineMode);
+                if (inlineMode != null) {
+                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.InlineMode, inlineMode);
+                    inline = inlineMode.contains("true");
+                } else {
+                    inline = false;
+                }
+
+                final String publicLbStr = lbServiceCapabilityMap.get(Capability.LbSchemes);
+                if (serviceProviderMap.containsKey(Service.Lb)) {
+                    if (publicLbStr != null) {
+                        _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.LbSchemes, publicLbStr);
+                        internalLb = publicLbStr.contains("internal");
+                        publicLb = publicLbStr.contains("public");
+                    }
+                }
+            }
+
+            // in the current version of the code, publicLb and specificLb can't
+            // both be set to true for the same network offering
+            if (publicLb && internalLb) {
+                throw new InvalidParameterValueException("Public lb and internal lb can't be enabled at the same time on the offering");
+            }
+
+            final Map<Capability, String> sourceNatServiceCapabilityMap = serviceCapabilityMap.get(Service.SourceNat);
+            if (sourceNatServiceCapabilityMap != null && !sourceNatServiceCapabilityMap.isEmpty()) {
+                final String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes);
+                if (sourceNatType != null) {
+                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType);
+                    sharedSourceNat = sourceNatType.contains("perzone");
+                }
+
+                final String param = sourceNatServiceCapabilityMap.get(Capability.RedundantRouter);
+                if (param != null) {
+                    _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.RedundantRouter, param);
+                    redundantRouter = param.contains("true");
+                }
+            }
+
+            final Map<Capability, String> staticNatServiceCapabilityMap = serviceCapabilityMap.get(Service.StaticNat);
+            if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) {
+                final String param = staticNatServiceCapabilityMap.get(Capability.ElasticIp);
+                if (param != null) {
+                    elasticIp = param.contains("true");
+                    final String associatePublicIP = staticNatServiceCapabilityMap.get(Capability.AssociatePublicIP);
+                    if (associatePublicIP != null) {
+                        associatePublicIp = associatePublicIP.contains("true");
+                    }
+                }
+            }
+
+            final Map<Capability, String> connectivityServiceCapabilityMap = serviceCapabilityMap.get(Service.Connectivity);
+            if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
+                if (connectivityServiceCapabilityMap.containsKey(Capability.StretchedL2Subnet)) {
+                    final String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet);
+                    if ("true".equalsIgnoreCase(value)) {
+                        strechedL2Subnet = true;
+                    }
+                }
+
+                if (connectivityServiceCapabilityMap.containsKey(Capability.PublicAccess)) {
+                    final String value = connectivityServiceCapabilityMap.get(Capability.PublicAccess);
+                    if ("true".equalsIgnoreCase(value)) {
+                        publicAccess = true;
+                    }
+                }
+            }
+        }
+
+        if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) {
+            //if not specified, default public lb to true
+            publicLb = true;
+        }
+
+        final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability,
+                tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb,
+                internalLb, forVpc, egressDefaultPolicy, strechedL2Subnet, publicAccess);
+
+        if (serviceOfferingId != null) {
+            offeringFinal.setServiceOfferingId(serviceOfferingId);
+        }
+
+        //Set Service package id
+        offeringFinal.setServicePackage(servicePackageUuid);
+        // validate the details
+        if (details != null) {
+            validateNtwkOffDetails(details, serviceProviderMap);
+        }
+
+        boolean vpcOff = false;
+        boolean nsOff = false;
+
+        if (serviceProviderMap != null && spDescription != null) {
+            for (final Network.Service service : serviceProviderMap.keySet()) {
+                final Set<Provider> providers = serviceProviderMap.get(service);
+                if (providers != null && !providers.isEmpty()) {
+                    for (final Network.Provider provider : providers) {
+                        if (provider == Provider.VPCVirtualRouter) {
+                            vpcOff = true;
+                        }
+                        if (provider == Provider.Netscaler) {
+                            nsOff = true;
+                        }
+                    }
+                }
+            }
+            if(vpcOff && nsOff) {
+                if(!(spDescription.equalsIgnoreCase("A NetScalerVPX is dedicated per network.") || spDescription.contains("dedicated NetScaler"))) {
+                    throw new InvalidParameterValueException("Only NetScaler Service Package with Dedicated Device Mode is Supported in VPC Type Guest Network");
+                }
+            }
+        }
+
+        return Transaction.execute(new TransactionCallback<NetworkOfferingVO>() {
+            @Override
+            public NetworkOfferingVO doInTransaction(final TransactionStatus status) {
+                NetworkOfferingVO offering = offeringFinal;
+
+                // 1) create network offering object
+                s_logger.debug("Adding network offering " + offering);
+                offering.setConcurrentConnections(maxconn);
+                offering.setKeepAliveEnabled(enableKeepAlive);
+                offering = _networkOfferingDao.persist(offering, details);
+                // 2) populate services and providers
+                if (serviceProviderMap != null) {
+                    for (final Network.Service service : serviceProviderMap.keySet()) {
+                        final Set<Provider> providers = serviceProviderMap.get(service);
+                        if (providers != null && !providers.isEmpty()) {
+                            boolean vpcOff = false;
+                            for (final Network.Provider provider : providers) {
+                                if (provider == Provider.VPCVirtualRouter) {
+                                    vpcOff = true;
+                                }
+                                final NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, provider);
+                                _ntwkOffServiceMapDao.persist(offService);
+                                s_logger.trace("Added service for the network offering: " + offService + " with provider " + provider.getName());
+                            }
+
+                            if (vpcOff) {
+                                final List<Service> supportedSvcs = new ArrayList<Service>();
+                                supportedSvcs.addAll(serviceProviderMap.keySet());
+                                _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs);
+                            }
+                        } else {
+                            final NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(offering.getId(), service, null);
+                            _ntwkOffServiceMapDao.persist(offService);
+                            s_logger.trace("Added service for the network offering: " + offService + " with null provider");
+                        }
+                    }
+                }
+
+                return offering;
+            }
+        });
+    }
+
+    protected void validateNtwkOffDetails(final Map<Detail, String> details, final Map<Service, Set<Provider>> serviceProviderMap) {
+        for (final Detail detail : details.keySet()) {
+
+            Provider lbProvider = null;
+            if (detail == NetworkOffering.Detail.InternalLbProvider || detail == NetworkOffering.Detail.PublicLbProvider) {
+                // 1) Vaidate the detail values - have to match the lb provider
+                // name
+                final String providerStr = details.get(detail);
+                if (Network.Provider.getProvider(providerStr) == null) {
+                    throw new InvalidParameterValueException("Invalid value " + providerStr + " for the detail " + detail);
+                }
+                if (serviceProviderMap.get(Service.Lb) != null) {
+                    for (final Provider provider : serviceProviderMap.get(Service.Lb)) {
+                        if (provider.getName().equalsIgnoreCase(providerStr)) {
+                            lbProvider = provider;
+                            break;
+                        }
+                    }
+                }
+
+                if (lbProvider == null) {
+                    throw new InvalidParameterValueException("Invalid value " + details.get(detail) + " for the detail " + detail
+                            + ". The provider is not supported by the network offering");
+                }
+
+                // 2) validate if the provider supports the scheme
+                final Set<Provider> lbProviders = new HashSet<Provider>();
+                lbProviders.add(lbProvider);
+                if (detail == NetworkOffering.Detail.InternalLbProvider) {
+                    _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Internal.toString());
+                } else if (detail == NetworkOffering.Detail.PublicLbProvider) {
+                    _networkModel.checkCapabilityForProvider(lbProviders, Service.Lb, Capability.LbSchemes, Scheme.Public.toString());
+                }
+            }
+        }
+    }
+
+    @Override
+    public Pair<List<? extends NetworkOffering>, Integer> searchForNetworkOfferings(final ListNetworkOfferingsCmd cmd) {
+        Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm"));
+        isAscending = isAscending == null ? Boolean.TRUE : isAscending;
+        final Filter searchFilter = new Filter(NetworkOfferingVO.class, "sortKey", isAscending, null, null);
+        final Account caller = CallContext.current().getCallingAccount();
+        final SearchCriteria<NetworkOfferingVO> sc = _networkOfferingDao.createSearchCriteria();
+
+        final Long id = cmd.getId();
+        final Object name = cmd.getNetworkOfferingName();
+        final Object displayText = cmd.getDisplayText();
+        final Object trafficType = cmd.getTrafficType();
+        final Object isDefault = cmd.getIsDefault();
+        final Object specifyVlan = cmd.getSpecifyVlan();
+        final Object availability = cmd.getAvailability();
+        final Object state = cmd.getState();
+        final Long zoneId = cmd.getZoneId();
+        DataCenter zone = null;
+        final Long networkId = cmd.getNetworkId();
+        final String guestIpType = cmd.getGuestIpType();
+        final List<String> supportedServicesStr = cmd.getSupportedServices();
+        final Object specifyIpRanges = cmd.getSpecifyIpRanges();
+        final String tags = cmd.getTags();
+        final Boolean isTagged = cmd.isTagged();
+        final Boolean forVpc = cmd.getForVpc();
+
+        if (zoneId != null) {
+            zone = _entityMgr.findById(DataCenter.class, zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find the zone by id=" + zoneId);
+            }
+        }
+
+        final Object keyword = cmd.getKeyword();
+
+        if (keyword != null) {
+            final SearchCriteria<NetworkOfferingVO> ssc = _networkOfferingDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+
+        if (guestIpType != null) {
+            sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType);
+        }
+
+        if (displayText != null) {
+            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
+        }
+
+        if (trafficType != null) {
+            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
+        }
+
+        if (isDefault != null) {
+            sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault);
+        }
+
+        // only root admin can list network offering with specifyVlan = true
+        if (specifyVlan != null) {
+            sc.addAnd("specifyVlan", SearchCriteria.Op.EQ, specifyVlan);
+        }
+
+        if (availability != null) {
+            sc.addAnd("availability", SearchCriteria.Op.EQ, availability);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", SearchCriteria.Op.EQ, state);
+        }
+
+        if (specifyIpRanges != null) {
+            sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges);
+        }
+
+        if (zone != null) {
+            if (zone.getNetworkType() == NetworkType.Basic) {
+                // return empty list as we don't allow to create networks in
+                // basic zone, and shouldn't display networkOfferings
+                return new Pair<List<? extends NetworkOffering>, Integer>(new ArrayList<NetworkOffering>(), 0);
+            }
+        }
+
+        // Don't return system network offerings to the user
+        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, false);
+
+        // if networkId is specified, list offerings available for upgrade only
+        // (for this network)
+        Network network = null;
+        if (networkId != null) {
+            // check if network exists and the caller can operate with it
+            network = _networkModel.getNetwork(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find the network by id=" + networkId);
+            }
+            // Don't allow to update system network
+            final NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+            if (offering.isSystemOnly()) {
+                throw new InvalidParameterValueException("Can't update system networks");
+            }
+
+            _accountMgr.checkAccess(caller, null, true, network);
+
+            final List<Long> offeringIds = _networkModel.listNetworkOfferingsForUpgrade(networkId);
+
+            if (!offeringIds.isEmpty()) {
+                sc.addAnd("id", SearchCriteria.Op.IN, offeringIds.toArray());
+            } else {
+                return new Pair<List<? extends NetworkOffering>, Integer>(new ArrayList<NetworkOffering>(), 0);
+            }
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (tags != null) {
+            sc.addAnd("tags", SearchCriteria.Op.EQ, tags);
+        }
+
+        if (isTagged != null) {
+            if (isTagged) {
+                sc.addAnd("tags", SearchCriteria.Op.NNULL);
+            } else {
+                sc.addAnd("tags", SearchCriteria.Op.NULL);
+            }
+        }
+
+        final List<NetworkOfferingVO> offerings = _networkOfferingDao.search(sc, searchFilter);
+        final Boolean sourceNatSupported = cmd.getSourceNatSupported();
+        final List<String> pNtwkTags = new ArrayList<String>();
+        boolean checkForTags = false;
+        if (zone != null) {
+            final List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest);
+            if (pNtwks.size() > 1) {
+                checkForTags = true;
+                // go through tags
+                for (final PhysicalNetworkVO pNtwk : pNtwks) {
+                    final List<String> pNtwkTag = pNtwk.getTags();
+                    if (pNtwkTag == null || pNtwkTag.isEmpty()) {
+                        throw new CloudRuntimeException("Tags are not defined for physical network in the zone id=" + zoneId);
+                    }
+                    pNtwkTags.addAll(pNtwkTag);
+                }
+            }
+        }
+
+        // filter by supported services
+        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty();
+        final boolean checkIfProvidersAreEnabled = zoneId != null;
+        final boolean parseOfferings = listBySupportedServices || sourceNatSupported != null || checkIfProvidersAreEnabled || forVpc != null || network != null;
+
+        if (parseOfferings) {
+            final List<NetworkOfferingVO> supportedOfferings = new ArrayList<NetworkOfferingVO>();
+            Service[] supportedServices = null;
+
+            if (listBySupportedServices) {
+                supportedServices = new Service[supportedServicesStr.size()];
+                int i = 0;
+                for (final String supportedServiceStr : supportedServicesStr) {
+                    final Service service = Service.getService(supportedServiceStr);
+                    if (service == null) {
+                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
+                    } else {
+                        supportedServices[i] = service;
+                    }
+                    i++;
+                }
+            }
+
+            for (final NetworkOfferingVO offering : offerings) {
+                boolean addOffering = true;
+                List<Service> checkForProviders = new ArrayList<Service>();
+
+                if (checkForTags) {
+                    if (!pNtwkTags.contains(offering.getTags())) {
+                        continue;
+                    }
+                }
+
+                if (listBySupportedServices) {
+                    addOffering = addOffering && _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), supportedServices);
+                }
+
+                if (checkIfProvidersAreEnabled) {
+                    if (supportedServices != null && supportedServices.length > 0) {
+                        checkForProviders = Arrays.asList(supportedServices);
+                    } else {
+                        checkForProviders = _networkModel.listNetworkOfferingServices(offering.getId());
+                    }
+
+                    addOffering = addOffering && _networkModel.areServicesEnabledInZone(zoneId, offering, checkForProviders);
+                }
+
+                if (sourceNatSupported != null) {
+                    addOffering = addOffering && _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.SourceNat) == sourceNatSupported;
+                }
+
+                if (forVpc != null) {
+                    addOffering = addOffering && isOfferingForVpc(offering) == forVpc.booleanValue();
+                } else if (network != null) {
+                    addOffering = addOffering && isOfferingForVpc(offering) == (network.getVpcId() != null);
+                }
+
+                if (addOffering) {
+                    supportedOfferings.add(offering);
+                }
+
+            }
+
+            // Now apply pagination
+            final List<? extends NetworkOffering> wPagination = StringUtils.applyPagination(supportedOfferings, cmd.getStartIndex(), cmd.getPageSizeVal());
+            if (wPagination != null) {
+                final Pair<List<? extends NetworkOffering>, Integer> listWPagination = new Pair<List<? extends NetworkOffering>, Integer>(wPagination, supportedOfferings.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends NetworkOffering>, Integer>(supportedOfferings, supportedOfferings.size());
+        } else {
+            final List<? extends NetworkOffering> wPagination = StringUtils.applyPagination(offerings, cmd.getStartIndex(), cmd.getPageSizeVal());
+            if (wPagination != null) {
+                final Pair<List<? extends NetworkOffering>, Integer> listWPagination = new Pair<List<? extends NetworkOffering>, Integer>(wPagination, offerings.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends NetworkOffering>, Integer>(offerings, offerings.size());
+        }
+    }
+
+    @Override
+    public boolean isOfferingForVpc(final NetworkOffering offering) {
+        return offering.isForVpc();
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_DELETE, eventDescription = "deleting network offering")
+    public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) {
+        final Long offeringId = cmd.getId();
+        CallContext.current().setEventDetails(" Id: " + offeringId);
+
+        // Verify network offering id
+        final NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId);
+        if (offering == null) {
+            throw new InvalidParameterValueException("unable to find network offering " + offeringId);
+        } else if (offering.getRemoved() != null || offering.isSystemOnly()) {
+            throw new InvalidParameterValueException("unable to find network offering " + offeringId);
+        }
+
+        // Don't allow to delete default network offerings
+        if (offering.isDefault() == true) {
+            throw new InvalidParameterValueException("Default network offering can't be deleted");
+        }
+
+        // don't allow to delete network offering if it's in use by existing
+        // networks (the offering can be disabled
+        // though)
+        final int networkCount = _networkDao.getNetworkCountByNetworkOffId(offeringId);
+        if (networkCount > 0) {
+            throw new InvalidParameterValueException("Can't delete network offering " + offeringId + " as its used by " + networkCount + " networks. "
+                    + "To make the network offering unavaiable, disable it");
+        }
+
+        if (_networkOfferingDao.remove(offeringId)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_EDIT, eventDescription = "updating network offering")
+    public NetworkOffering updateNetworkOffering(final UpdateNetworkOfferingCmd cmd) {
+        final String displayText = cmd.getDisplayText();
+        final Long id = cmd.getId();
+        final String name = cmd.getNetworkOfferingName();
+        final String availabilityStr = cmd.getAvailability();
+        final Integer sortKey = cmd.getSortKey();
+        final Integer maxconn = cmd.getMaxconnections();
+        Availability availability = null;
+        final String state = cmd.getState();
+        final String tags = cmd.getTags();
+        CallContext.current().setEventDetails(" Id: " + id);
+
+        // Verify input parameters
+        final NetworkOfferingVO offeringToUpdate = _networkOfferingDao.findById(id);
+        if (offeringToUpdate == null) {
+            throw new InvalidParameterValueException("unable to find network offering " + id);
+        }
+
+        // Don't allow to update system network offering
+        if (offeringToUpdate.isSystemOnly()) {
+            throw new InvalidParameterValueException("Can't update system network offerings");
+        }
+
+        final NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id);
+
+        if (name != null) {
+            offering.setName(name);
+        }
+
+        if (displayText != null) {
+            offering.setDisplayText(displayText);
+        }
+
+        if (sortKey != null) {
+            offering.setSortKey(sortKey);
+        }
+
+        if (state != null) {
+            boolean validState = false;
+            for (final NetworkOffering.State st : NetworkOffering.State.values()) {
+                if (st.name().equalsIgnoreCase(state)) {
+                    validState = true;
+                    offering.setState(st);
+                }
+            }
+            if (!validState) {
+                throw new InvalidParameterValueException("Incorrect state value: " + state);
+            }
+        }
+
+        if (tags != null) {
+            List<DataCenterVO> dataCenters = _zoneDao.listAll();
+            TrafficType trafficType = offeringToUpdate.getTrafficType();
+            String oldTags = offeringToUpdate.getTags();
+
+            for (DataCenterVO dataCenter : dataCenters) {
+                long zoneId = dataCenter.getId();
+                long newPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, tags, trafficType);
+                if (oldTags != null) {
+                    long oldPhysicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, oldTags, trafficType);
+                    if (newPhysicalNetworkId != oldPhysicalNetworkId) {
+                        throw new InvalidParameterValueException("New tags: selects different physical network for zone " + zoneId);
+                    }
+                }
+            }
+
+            offering.setTags(tags);
+        }
+
+        // Verify availability
+        if (availabilityStr != null) {
+            for (final Availability avlb : Availability.values()) {
+                if (avlb.name().equalsIgnoreCase(availabilityStr)) {
+                    availability = avlb;
+                }
+            }
+            if (availability == null) {
+                throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional);
+            } else {
+                if (availability == NetworkOffering.Availability.Required) {
+                    final boolean canOffBeRequired = offeringToUpdate.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedByNetworkOffering(
+                            offeringToUpdate.getId(), Service.SourceNat);
+                    if (!canOffBeRequired) {
+                        throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type "
+                                + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled");
+                    }
+
+                    // only one network offering in the system can be Required
+                    final List<NetworkOfferingVO> offerings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+                    if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) {
+                        throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability "
+                                + Availability.Required);
+                    }
+                }
+                offering.setAvailability(availability);
+            }
+        }
+        if (_ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Lb)) {
+            if (maxconn != null) {
+                offering.setConcurrentConnections(maxconn);
+            }
+        }
+
+        if (_networkOfferingDao.update(id, offering)) {
+            return _networkOfferingDao.findById(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + "default zone", async = true)
+    public AccountVO markDefaultZone(final String accountName, final long domainId, final long defaultZoneId) {
+
+        // Check if the account exists
+        final Account account = _accountDao.findEnabledAccount(accountName, domainId);
+        if (account == null) {
+            s_logger.error("Unable to find account by name: " + accountName + " in domain " + domainId);
+            throw new InvalidParameterValueException("Account by name: " + accountName + " doesn't exist in domain " + domainId);
+        }
+
+        // Don't allow modification of system account
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new InvalidParameterValueException("Can not modify system account");
+        }
+
+        final AccountVO acctForUpdate = _accountDao.findById(account.getId());
+
+        acctForUpdate.setDefaultZoneId(defaultZoneId);
+
+        if (_accountDao.update(account.getId(), acctForUpdate)) {
+            CallContext.current().setEventDetails("Default zone id= " + defaultZoneId);
+            return _accountDao.findById(account.getId());
+        } else {
+            return null;
+        }
+    }
+
+    // Note: This method will be used for entity name validations in the coming
+    // releases (place holder for now)
+    @SuppressWarnings("unused")
+    private void validateEntityName(final String str) {
+        final String forbidden = "~!@#$%^&*()+=";
+        final char[] searchChars = forbidden.toCharArray();
+        if (str == null || str.length() == 0 || searchChars == null || searchChars.length == 0) {
+            return;
+        }
+        for (int i = 0; i < str.length(); i++) {
+            final char ch = str.charAt(i);
+            for (int j = 0; j < searchChars.length; j++) {
+                if (searchChars[j] == ch) {
+                    throw new InvalidParameterValueException("Name cannot contain any of the following special characters:" + forbidden);
+                }
+            }
+        }
+    }
+
+    @Override
+    public Integer getNetworkOfferingNetworkRate(final long networkOfferingId, final Long dataCenterId) {
+
+        // validate network offering information
+        final NetworkOffering no = _entityMgr.findById(NetworkOffering.class, networkOfferingId);
+        if (no == null) {
+            throw new InvalidParameterValueException("Unable to find network offering by id=" + networkOfferingId);
+        }
+
+        Integer networkRate;
+        if (no.getRateMbps() != null) {
+            networkRate = no.getRateMbps();
+        } else {
+            networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
+        }
+
+        // networkRate is unsigned int in netowrkOfferings table, and can't be
+        // set to -1
+        // so 0 means unlimited; we convert it to -1, so we are consistent with
+        // all our other resources where -1 means unlimited
+        if (networkRate == 0) {
+            networkRate = -1;
+        }
+
+        return networkRate;
+    }
+
+    @Override
+    public Account getVlanAccount(final long vlanId) {
+        final Vlan vlan = _vlanDao.findById(vlanId);
+
+        // if vlan is Virtual Account specific, get vlan information from the
+        // accountVlanMap; otherwise get account information
+        // from the network
+        if (vlan.getVlanType() == VlanType.VirtualNetwork) {
+            final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(vlanId);
+            if (maps != null && !maps.isEmpty()) {
+                return _accountMgr.getAccount(maps.get(0).getAccountId());
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public Domain getVlanDomain(long vlanId) {
+        Vlan vlan = _vlanDao.findById(vlanId);
+        Long domainId = null;
+
+        // if vlan is Virtual Domain specific, get vlan information from the
+        // accountVlanMap; otherwise get account information
+        // from the network
+        if (vlan.getVlanType() == VlanType.VirtualNetwork) {
+            List<DomainVlanMapVO> maps = _domainVlanMapDao.listDomainVlanMapsByVlan(vlanId);
+            if (maps != null && !maps.isEmpty()) {
+                return _domainDao.findById(maps.get(0).getDomainId());
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public List<? extends NetworkOffering> listNetworkOfferings(final TrafficType trafficType, final boolean systemOnly) {
+        final Filter searchFilter = new Filter(NetworkOfferingVO.class, "created", false, null, null);
+        final SearchCriteria<NetworkOfferingVO> sc = _networkOfferingDao.createSearchCriteria();
+        if (trafficType != null) {
+            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
+        }
+        sc.addAnd("systemOnly", SearchCriteria.Op.EQ, systemOnly);
+
+        return _networkOfferingDao.search(sc, searchFilter);
+    }
+
+     @Override
+     @DB
+     public boolean releaseDomainSpecificVirtualRanges(final long domainId) {
+        final List<DomainVlanMapVO> maps = _domainVlanMapDao.listDomainVlanMapsByDomain(domainId);
+        if (CollectionUtils.isNotEmpty(maps)) {
+            try {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        for (DomainVlanMapVO map : maps) {
+                            if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
+                                throw new CloudRuntimeException("Failed to release domain specific virtual ip ranges for domain id=" + domainId);
+                            }
+                        }
+                    }
+                });
+            } catch (final CloudRuntimeException e) {
+                s_logger.error(e);
+                return false;
+            }
+        } else {
+            s_logger.trace("Domain id=" + domainId + " has no domain specific virtual ip ranges, nothing to release");
+        }
+        return true;
+    }
+
+    @Override
+    @DB
+    public boolean releaseAccountSpecificVirtualRanges(final long accountId) {
+        final List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(accountId);
+        if (maps != null && !maps.isEmpty()) {
+            try {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        for (final AccountVlanMapVO map : maps) {
+                            if (!releasePublicIpRange(map.getVlanDbId(), _accountMgr.getSystemUser().getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) {
+                                throw new CloudRuntimeException("Failed to release account specific virtual ip ranges for account id=" + accountId);
+                            }
+                        }
+                    }
+                });
+            } catch (final CloudRuntimeException e) {
+                s_logger.error(e);
+                return false;
+            }
+        } else {
+            s_logger.trace("Account id=" + accountId + " has no account specific virtual ip ranges, nothing to release");
+        }
+        return true;
+    }
+
+    @Override
+    public AllocationState findClusterAllocationState(final ClusterVO cluster) {
+
+        if (cluster.getAllocationState() == AllocationState.Disabled) {
+            return AllocationState.Disabled;
+        } else if (ApiDBUtils.findPodById(cluster.getPodId()).getAllocationState() == AllocationState.Disabled) {
+            return AllocationState.Disabled;
+        } else {
+            final DataCenterVO zone = ApiDBUtils.findZoneById(cluster.getDataCenterId());
+            return zone.getAllocationState();
+        }
+    }
+
+    @Override
+    public AllocationState findPodAllocationState(final HostPodVO pod) {
+
+        if (pod.getAllocationState() == AllocationState.Disabled) {
+            return AllocationState.Disabled;
+        } else {
+            final DataCenterVO zone = ApiDBUtils.findZoneById(pod.getDataCenterId());
+            return zone.getAllocationState();
+        }
+    }
+
+    @Override
+    public Long getDefaultPageSize() {
+        return _defaultPageSize;
+    }
+
+    @Override
+    public Integer getServiceOfferingNetworkRate(final long serviceOfferingId, final Long dataCenterId) {
+
+        // validate network offering information
+        final ServiceOffering offering = _serviceOfferingDao.findById(serviceOfferingId);
+        if (offering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering by id=" + serviceOfferingId);
+        }
+
+        Integer networkRate;
+        if (offering.getRateMbps() != null) {
+            networkRate = offering.getRateMbps();
+        } else {
+            // for domain router service offering, get network rate from
+            if (offering.getSystemVmType() != null && offering.getSystemVmType().equalsIgnoreCase(VirtualMachine.Type.DomainRouter.toString())) {
+                networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(dataCenterId);
+            } else {
+                networkRate = Integer.parseInt(_configDao.getValue(Config.VmNetworkThrottlingRate.key()));
+            }
+        }
+
+        // networkRate is unsigned int in serviceOffering table, and can't be
+        // set to -1
+        // so 0 means unlimited; we convert it to -1, so we are consistent with
+        // all our other resources where -1 means unlimited
+        if (networkRate == 0) {
+            networkRate = -1;
+        }
+
+        return networkRate;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false)
+    public PortableIpRange createPortableIpRange(final CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
+        final Integer regionId = cmd.getRegionId();
+        final String startIP = cmd.getStartIp();
+        final String endIP = cmd.getEndIp();
+        final String gateway = cmd.getGateway();
+        final String netmask = cmd.getNetmask();
+        String vlanId = cmd.getVlan();
+
+        final RegionVO region = _regionDao.findById(regionId);
+        if (region == null) {
+            throw new InvalidParameterValueException("Invalid region ID: " + regionId);
+        }
+
+        if (!NetUtils.isValidIp4(startIP) || !NetUtils.isValidIp4(endIP) || !NetUtils.validIpRange(startIP, endIP)) {
+            throw new InvalidParameterValueException("Invalid portable ip  range: " + startIP + "-" + endIP);
+        }
+
+        if (!NetUtils.sameSubnet(startIP, gateway, netmask)) {
+            throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as "
+                    + "your portable IP range's gateway and as per the IP range's netmask.");
+        }
+
+        if (!NetUtils.sameSubnet(endIP, gateway, netmask)) {
+            throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as "
+                    + "your portable IP range's gateway and as per the IP range's netmask.");
+        }
+
+        if (checkOverlapPortableIpRange(regionId, startIP, endIP)) {
+            throw new InvalidParameterValueException("Ip  range: " + startIP + "-" + endIP + " overlaps with a portable" + " IP range already configured in the region " + regionId);
+        }
+
+        if (vlanId == null) {
+            vlanId = Vlan.UNTAGGED;
+        } else {
+            if (!NetUtils.isValidVlan(vlanId)) {
+                throw new InvalidParameterValueException("Invalid vlan id " + vlanId);
+            }
+
+            final List<DataCenterVO> zones = _zoneDao.listAllZones();
+            if (zones != null && !zones.isEmpty()) {
+                for (final DataCenterVO zone : zones) {
+                    // check if there is zone vlan with same id
+                    if (_vlanDao.findByZoneAndVlanId(zone.getId(), vlanId) != null) {
+                        throw new InvalidParameterValueException("Found a VLAN id " + vlanId + " already existing in" + " zone " + zone.getUuid()
+                                + " that conflicts with VLAN id of the portable ip range being configured");
+                    }
+                    //check if there is a public ip range that overlaps with portable ip range being created
+                    checkOverlapPublicIpRange(zone.getId(), startIP, endIP);
+                }
+            }
+
+        }
+        final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
+        portableIpLock.lock(5);
+        try {
+            final String vlanIdFinal = vlanId;
+            return Transaction.execute(new TransactionCallback<PortableIpRangeVO>() {
+                @Override
+                public PortableIpRangeVO doInTransaction(final TransactionStatus status) {
+                    PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanIdFinal, gateway, netmask, startIP, endIP);
+                    portableIpRange = _portableIpRangeDao.persist(portableIpRange);
+
+                    long startIpLong = NetUtils.ip2Long(startIP);
+                    final long endIpLong = NetUtils.ip2Long(endIP);
+                    while (startIpLong <= endIpLong) {
+                        final PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanIdFinal, gateway, netmask, NetUtils.long2Ip(startIpLong));
+                        _portableIpDao.persist(portableIP);
+                        startIpLong++;
+                    }
+
+                    // implicitly enable portable IP service for the region
+                    region.setPortableipEnabled(true);
+                    _regionDao.update(region.getId(), region);
+
+                    return portableIpRange;
+                }
+            });
+        } finally {
+            portableIpLock.unlock();
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_DELETE, eventDescription = "deleting portable ip range", async = false)
+    public boolean deletePortableIpRange(final DeletePortableIpRangeCmd cmd) {
+        final long rangeId = cmd.getId();
+
+        final PortableIpRangeVO portableIpRange = _portableIpRangeDao.findById(rangeId);
+        if (portableIpRange == null) {
+            throw new InvalidParameterValueException("Please specify a valid portable IP range id.");
+        }
+
+        final List<PortableIpVO> fullIpRange = _portableIpDao.listByRangeId(portableIpRange.getId());
+        final List<PortableIpVO> freeIpRange = _portableIpDao.listByRangeIdAndState(portableIpRange.getId(), PortableIp.State.Free);
+
+        if (fullIpRange != null && freeIpRange != null) {
+            if (fullIpRange.size() == freeIpRange.size()) {
+                _portableIpRangeDao.expunge(portableIpRange.getId());
+                final List<PortableIpRangeVO> pipranges = _portableIpRangeDao.listAll();
+                if (pipranges == null || pipranges.isEmpty()) {
+                    final RegionVO region = _regionDao.findById(portableIpRange.getRegionId());
+                    region.setPortableipEnabled(false);
+                    _regionDao.update(region.getId(), region);
+                }
+                return true;
+            } else {
+                throw new InvalidParameterValueException("Can't delete portable IP range as there are IP's assigned.");
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<? extends PortableIpRange> listPortableIpRanges(final ListPortableIpRangesCmd cmd) {
+        final Integer regionId = cmd.getRegionIdId();
+        final Long rangeId = cmd.getPortableIpRangeId();
+
+        final List<PortableIpRangeVO> ranges = new ArrayList<PortableIpRangeVO>();
+        if (regionId != null) {
+            final Region region = _regionDao.findById(regionId);
+            if (region == null) {
+                throw new InvalidParameterValueException("Invalid region ID: " + regionId);
+            }
+            return _portableIpRangeDao.listByRegionId(regionId);
+        }
+
+        if (rangeId != null) {
+            final PortableIpRangeVO range = _portableIpRangeDao.findById(rangeId);
+            if (range == null) {
+                throw new InvalidParameterValueException("Invalid portable IP range ID: " + regionId);
+            }
+            ranges.add(range);
+            return ranges;
+        }
+
+        return _portableIpRangeDao.listAll();
+    }
+
+    @Override
+    public List<? extends PortableIp> listPortableIps(final long id) {
+
+        final PortableIpRangeVO portableIpRange = _portableIpRangeDao.findById(id);
+        if (portableIpRange == null) {
+            throw new InvalidParameterValueException("Please specify a valid portable IP range id.");
+        }
+
+        return _portableIpDao.listByRangeId(portableIpRange.getId());
+    }
+
+    private boolean checkOverlapPortableIpRange(final int regionId, final String newStartIpStr, final String newEndIpStr) {
+        final long newStartIp = NetUtils.ip2Long(newStartIpStr);
+        final long newEndIp = NetUtils.ip2Long(newEndIpStr);
+
+        final List<PortableIpRangeVO> existingPortableIPRanges = _portableIpRangeDao.listByRegionId(regionId);
+
+        if (existingPortableIPRanges == null || existingPortableIPRanges.isEmpty()) {
+            return false;
+        }
+
+        for (final PortableIpRangeVO portableIpRange : existingPortableIPRanges) {
+            final String ipRangeStr = portableIpRange.getIpRange();
+            final String[] range = ipRangeStr.split("-");
+            final long startip = NetUtils.ip2Long(range[0]);
+            final long endIp = NetUtils.ip2Long(range[1]);
+
+            if (newStartIp >= startip && newStartIp <= endIp || newEndIp >= startip && newEndIp <= endIp) {
+                return true;
+            }
+
+            if (startip >= newStartIp && startip <= newEndIp || endIp >= newStartIp && endIp <= newEndIp) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<SecurityChecker> getSecChecker() {
+        return _secChecker;
+    }
+
+    @Inject
+    public void setSecChecker(final List<SecurityChecker> secChecker) {
+        _secChecker = secChecker;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ConfigurationManagerImpl.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {SystemVMUseLocalStorage};
+    }
+}
diff --git a/server/src/com/cloud/configuration/ZoneConfig.java b/server/src/main/java/com/cloud/configuration/ZoneConfig.java
similarity index 100%
rename from server/src/com/cloud/configuration/ZoneConfig.java
rename to server/src/main/java/com/cloud/configuration/ZoneConfig.java
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/main/java/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
rename to server/src/main/java/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java b/server/src/main/java/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java
rename to server/src/main/java/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java
diff --git a/server/src/com/cloud/consoleproxy/AgentHook.java b/server/src/main/java/com/cloud/consoleproxy/AgentHook.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/AgentHook.java
rename to server/src/main/java/com/cloud/consoleproxy/AgentHook.java
diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/main/java/com/cloud/consoleproxy/AgentHookBase.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/AgentHookBase.java
rename to server/src/main/java/com/cloud/consoleproxy/AgentHookBase.java
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyAlertEventArgs.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAlertEventArgs.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyAlertEventArgs.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAlertEventArgs.java
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyListener.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyListener.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyListener.java
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagementState.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagementState.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyManagementState.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagementState.java
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java
diff --git a/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
new file mode 100644
index 0000000..87dca70
--- /dev/null
+++ b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -0,0 +1,1737 @@
+// 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.consoleproxy;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.agent.lb.IndirectAgentLB;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.security.keys.KeysManager;
+import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.framework.security.keystore.KeystoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
+import com.cloud.agent.manager.Commands;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManagerImpl;
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.ConsoleProxyConnectionInfo;
+import com.cloud.info.ConsoleProxyInfo;
+import com.cloud.info.ConsoleProxyLoadInfo;
+import com.cloud.info.ConsoleProxyStatus;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.info.RunningHostInfoAgregator;
+import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.events.SubscriptionMgr;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.ConsoleProxyVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.SystemVmLoadScanHandler;
+import com.cloud.vm.SystemVmLoadScanner;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineGuru;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.ConsoleProxyDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+//
+// Possible console proxy state transition cases
+//        Stopped --> Starting -> Running
+//        HA -> Stopped -> Starting -> Running
+//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
+//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
+//        Running -> HA            (if agent lost connection)
+//        Stopped -> Destroyed
+//
+// Starting, HA, Migrating, Running state are all counted as "Open" for available capacity calculation
+// because sooner or later, it will be driven into Running state
+//
+public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
+    private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
+
+    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3 minutes
+
+    private static final int STARTUP_DELAY = 60000; // 60 seconds
+
+    private int _consoleProxyPort = ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT;
+
+    private int _mgmtPort = 8250;
+
+    private List<ConsoleProxyAllocator> _consoleProxyAllocators;
+
+    @Inject
+    private ConsoleProxyDao _consoleProxyDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private VMInstanceDao _instanceDao;
+    @Inject
+    private TemplateDataStoreDao _vmTemplateStoreDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private NetworkOrchestrationService _networkMgr;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private UserVmDetailsDao _vmDetailsDao;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private RulesManager _rulesMgr;
+    @Inject
+    private IPAddressDao _ipAddressDao;
+    @Inject
+    private KeysManager _keysMgr;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private IndirectAgentLB indirectAgentLB;
+
+    private ConsoleProxyListener _listener;
+
+    private ServiceOfferingVO _serviceOffering;
+
+    /*
+     * private final ExecutorService _requestHandlerScheduler = Executors.newCachedThreadPool(new
+     * NamedThreadFactory("Request-handler"));
+     */
+    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
+    private int _capacityPerProxy = ConsoleProxyManager.DEFAULT_PROXY_CAPACITY;
+    private int _standbyCapacity = ConsoleProxyManager.DEFAULT_STANDBY_CAPACITY;
+
+    private boolean _useStorageVm;
+    private boolean _disableRpFilter = false;
+    private String _instance;
+
+    private int _proxySessionTimeoutValue = DEFAULT_PROXY_SESSION_TIMEOUT;
+    private boolean _sslEnabled = false;
+    private String _consoleProxyUrlDomain;
+
+    // global load picture at zone basis
+    private SystemVmLoadScanner<Long> _loadScanner;
+    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
+    private Map<Long, ConsoleProxyLoadInfo> _zoneProxyCountMap; // map <zone id, info about proxy VMs count in zone>
+    private Map<Long, ConsoleProxyLoadInfo> _zoneVmCountMap; // map <zone id, info about running VMs count in zone>
+
+    private String _staticPublicIp;
+    private int _staticPort;
+
+    private final GlobalLock _allocProxyLock = GlobalLock.getInternLock(getAllocProxyLockName());
+
+    @Inject
+    private KeystoreDao _ksDao;
+    @Inject
+    private KeystoreManager _ksMgr;
+
+    public class VmBasedAgentHook extends AgentHookBase {
+
+        public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) {
+            super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr);
+        }
+
+        @Override
+        public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
+            if (cmd.getLoadInfo() == null) {
+                return;
+            }
+
+            ConsoleProxyStatus status = null;
+            try {
+                GsonBuilder gb = new GsonBuilder();
+                gb.setVersion(1.3);
+                Gson gson = gb.create();
+                status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
+            } catch (Throwable e) {
+                s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
+            }
+
+            if (status != null) {
+                int count = 0;
+                if (status.getConnections() != null) {
+                    count = status.getConnections().length;
+                }
+
+                byte[] details = null;
+                if (cmd.getLoadInfo() != null) {
+                    details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
+                }
+                _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
+            } else {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
+                }
+
+                _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
+            }
+        }
+
+        @Override
+        public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
+
+            if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
+                // be it either in alert or in disconnected state, the agent
+                // process
+                // may be gone in the VM,
+                // we will be reacting to stop the corresponding VM and let the
+                // scan
+                // process to
+                HostVO host = _hostDao.findById(agentId);
+                if (host.getType() == Type.ConsoleProxy) {
+                    String name = host.getName();
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Console proxy agent disconnected, proxy: " + name);
+                    }
+                    if (name != null && name.startsWith("v-")) {
+                        String[] tokens = name.split("-");
+                        long proxyVmId = 0;
+                        try {
+                            proxyVmId = Long.parseLong(tokens[1]);
+                        } catch (NumberFormatException e) {
+                            s_logger.error("Unexpected exception " + e.getMessage(), e);
+                            return;
+                        }
+
+                        final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+                        if (proxy != null) {
+
+                            // Disable this feature for now, as it conflicts
+                            // with
+                            // the case of allowing user to reboot console proxy
+                            // when rebooting happens, we will receive
+                            // disconnect
+                            // here and we can't enter into stopping process,
+                            // as when the rebooted one comes up, it will kick
+                            // off a
+                            // newly started one and trigger the process
+                            // continue on forever
+
+                            /*
+                             * _capacityScanScheduler.execute(new Runnable() {
+                             * public void run() { if(s_logger.isInfoEnabled())
+                             * s_logger.info("Stop console proxy " +
+                             * proxy.getName() +
+                             * " VM because of that the agent running inside it has disconnected"
+                             * ); stopProxy(proxy.getId()); } });
+                             */
+                        } else {
+                            if (s_logger.isInfoEnabled()) {
+                                s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: " + name);
+                            }
+                        }
+                    } else {
+                        assert (false) : "Invalid console proxy name: " + name;
+                    }
+                }
+            }
+
+        }
+
+        @Override
+        protected HostVO findConsoleProxyHost(StartupProxyCommand startupCmd) {
+            long proxyVmId = startupCmd.getProxyVmId();
+            ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
+            if (consoleProxy == null) {
+                s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
+                return null;
+            }
+
+            assert (consoleProxy != null);
+            return findConsoleProxyHostByName(consoleProxy.getHostName());
+        }
+
+    }
+
+    @Override
+    public ConsoleProxyInfo assignProxy(final long dataCenterId, final long vmId) {
+        ConsoleProxyVO proxy = doAssignProxy(dataCenterId, vmId);
+        if (proxy == null) {
+            return null;
+        }
+
+        if (proxy.getPublicIpAddress() == null) {
+            s_logger.warn("Assigned console proxy does not have a valid public IP address");
+            return null;
+        }
+
+        KeystoreVO ksVo = _ksDao.findByName(ConsoleProxyManager.CERTIFICATE_NAME);
+        if (proxy.isSslEnabled() && ksVo == null) {
+            s_logger.warn("SSL enabled for console proxy but no server certificate found in database");
+        }
+
+        if (_staticPublicIp == null) {
+            return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), _consoleProxyUrlDomain);
+        } else {
+            return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, _consoleProxyUrlDomain);
+        }
+    }
+
+    public ConsoleProxyVO doAssignProxy(long dataCenterId, long vmId) {
+        ConsoleProxyVO proxy = null;
+        VMInstanceVO vm = _instanceDao.findById(vmId);
+
+        if (vm == null) {
+            s_logger.warn("VM " + vmId + " no longer exists, return a null proxy for vm:" + vmId);
+            return null;
+        }
+
+        if (vm != null && vm.getState() != State.Starting && vm.getState() != State.Running) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Detected that vm : " + vmId + " is not currently in starting or running state, we will fail the proxy assignment for it");
+            }
+            return null;
+        }
+
+        if (_allocProxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+            try {
+                if (vm.getProxyId() != null) {
+                    proxy = _consoleProxyDao.findById(vm.getProxyId());
+
+                    if (proxy != null) {
+                        if (!isInAssignableState(proxy)) {
+                            if (s_logger.isInfoEnabled()) {
+                                s_logger.info("A previous assigned proxy is not assignable now, reassign console proxy for user vm : " + vmId);
+                            }
+                            proxy = null;
+                        } else {
+                            if (_consoleProxyDao.getProxyActiveLoad(proxy.getId()) < _capacityPerProxy || hasPreviousSession(proxy, vm)) {
+                                if (s_logger.isTraceEnabled()) {
+                                    s_logger.trace("Assign previous allocated console proxy for user vm : " + vmId);
+                                }
+
+                                if (proxy.getActiveSession() >= _capacityPerProxy) {
+                                    s_logger.warn("Assign overloaded proxy to user VM as previous session exists, user vm : " + vmId);
+                                }
+                            } else {
+                                proxy = null;
+                            }
+                        }
+                    }
+                }
+
+                if (proxy == null) {
+                    proxy = assignProxyFromRunningPool(dataCenterId);
+                }
+            } finally {
+                _allocProxyLock.unlock();
+            }
+        } else {
+            s_logger.error("Unable to acquire synchronization lock to get/allocate proxy resource for vm :" + vmId +
+                ". Previous console proxy allocation is taking too long");
+        }
+
+        if (proxy == null) {
+            s_logger.warn("Unable to find or allocate console proxy resource");
+            return null;
+        }
+
+        // if it is a new assignment or a changed assignment, update the record
+        if (vm.getProxyId() == null || vm.getProxyId().longValue() != proxy.getId()) {
+            _instanceDao.updateProxyId(vmId, proxy.getId(), DateUtil.currentGMTTime());
+        }
+
+        proxy.setSslEnabled(_sslEnabled);
+        if (_sslEnabled) {
+            proxy.setPort(443);
+        } else {
+            proxy.setPort(80);
+        }
+
+        return proxy;
+    }
+
+    private static boolean isInAssignableState(ConsoleProxyVO proxy) {
+        // console proxies that are in states of being able to serve user VM
+        State state = proxy.getState();
+        if (state == State.Running) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean hasPreviousSession(ConsoleProxyVO proxy, VMInstanceVO vm) {
+
+        ConsoleProxyStatus status = null;
+        try {
+            GsonBuilder gb = new GsonBuilder();
+            gb.setVersion(1.3);
+            Gson gson = gb.create();
+
+            byte[] details = proxy.getSessionDetails();
+            status = gson.fromJson(details != null ? new String(details, Charset.forName("US-ASCII")) : null, ConsoleProxyStatus.class);
+        } catch (Throwable e) {
+            s_logger.warn("Unable to parse proxy session details : " + Arrays.toString(proxy.getSessionDetails()));
+        }
+
+        if (status != null && status.getConnections() != null) {
+            ConsoleProxyConnectionInfo[] connections = status.getConnections();
+            for (int i = 0; i < connections.length; i++) {
+                long taggedVmId = 0;
+                if (connections[i].tag != null) {
+                    try {
+                        taggedVmId = Long.parseLong(connections[i].tag);
+                    } catch (NumberFormatException e) {
+                        s_logger.warn("Unable to parse console proxy connection info passed through tag: " + connections[i].tag, e);
+                    }
+                }
+                if (taggedVmId == vm.getId()) {
+                    return true;
+                }
+            }
+
+            //
+            // even if we are not in the list, it may because we haven't
+            // received load-update yet
+            // wait until session time
+            //
+            if (DateUtil.currentGMTTime().getTime() - vm.getProxyAssignTime().getTime() < _proxySessionTimeoutValue) {
+                return true;
+            }
+
+            return false;
+        } else {
+            s_logger.error("No proxy load info on an overloaded proxy ?");
+            return false;
+        }
+    }
+
+    @Override
+    public ConsoleProxyVO startProxy(long proxyVmId, boolean ignoreRestartSetting) {
+        try {
+            ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+            if (proxy.getState() == VirtualMachine.State.Running) {
+                return proxy;
+            }
+
+            String restart = _configDao.getValue(Config.ConsoleProxyRestart.key());
+            if (!ignoreRestartSetting && restart != null && restart.equalsIgnoreCase("false")) {
+                return null;
+            }
+
+            if (proxy.getState() == VirtualMachine.State.Stopped) {
+                _itMgr.advanceStart(proxy.getUuid(), null, null);
+                proxy = _consoleProxyDao.findById(proxy.getId());
+                return proxy;
+            }
+
+            // For VMs that are in Stopping, Starting, Migrating state, let client to wait by returning null
+            // as sooner or later, Starting/Migrating state will be transited to Running and Stopping will be transited
+            // to Stopped to allow Starting of it
+            s_logger.warn("Console proxy is not in correct state to be started: " + proxy.getState());
+            return null;
+        } catch (StorageUnavailableException e) {
+            s_logger.warn("Exception while trying to start console proxy", e);
+            return null;
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("Exception while trying to start console proxy", e);
+            return null;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Exception while trying to start console proxy", e);
+            return null;
+        } catch (ConcurrentOperationException e) {
+            s_logger.warn("Runtime Exception while trying to start console proxy", e);
+            return null;
+        } catch (CloudRuntimeException e) {
+            s_logger.warn("Runtime Exception while trying to start console proxy", e);
+            return null;
+        } catch (OperationTimedoutException e) {
+            s_logger.warn("Runtime Exception while trying to start console proxy", e);
+            return null;
+        }
+    }
+
+    public ConsoleProxyVO assignProxyFromRunningPool(long dataCenterId) {
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Assign console proxy from running pool for request from data center : " + dataCenterId);
+        }
+
+        ConsoleProxyAllocator allocator = getCurrentAllocator();
+        assert (allocator != null);
+        List<ConsoleProxyVO> runningList = _consoleProxyDao.getProxyListInStates(dataCenterId, State.Running);
+        if (runningList != null && runningList.size() > 0) {
+            Iterator<ConsoleProxyVO> it = runningList.iterator();
+            while (it.hasNext()) {
+                ConsoleProxyVO proxy = it.next();
+                if (proxy.getActiveSession() >= _capacityPerProxy) {
+                    it.remove();
+                }
+            }
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Running proxy pool size : " + runningList.size());
+                for (ConsoleProxyVO proxy : runningList) {
+                    s_logger.trace("Running proxy instance : " + proxy.getHostName());
+                }
+            }
+
+            List<Pair<Long, Integer>> l = _consoleProxyDao.getProxyLoadMatrix();
+            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
+            if (l != null) {
+                for (Pair<Long, Integer> p : l) {
+                    loadInfo.put(p.first(), p.second());
+
+                    if (s_logger.isTraceEnabled()) {
+                        s_logger.trace("Running proxy instance allocation load { proxy id : " + p.first() + ", load : " + p.second() + "}");
+                    }
+                }
+            }
+            Long allocated = allocator.allocProxy(runningList, loadInfo, dataCenterId);
+            if (allocated == null) {
+                s_logger.debug("Unable to find a console proxy ");
+                return null;
+            }
+            return _consoleProxyDao.findById(allocated);
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Empty running proxy pool for now in data center : " + dataCenterId);
+            }
+        }
+        return null;
+    }
+
+    public ConsoleProxyVO assignProxyFromStoppedPool(long dataCenterId) {
+
+        // practically treat all console proxy VM that is not in Running state but can be entering into Running state as
+        // candidates
+        // this is to prevent launching unneccessary console proxy VMs because of temporarily unavailable state
+        List<ConsoleProxyVO> l = _consoleProxyDao.getProxyListInStates(dataCenterId, State.Starting, State.Stopped, State.Migrating, State.Stopping);
+        if (l != null && l.size() > 0) {
+            return l.get(0);
+        }
+
+        return null;
+    }
+
+    public ConsoleProxyVO startNew(long dataCenterId) throws ConcurrentOperationException {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
+        }
+
+        if (!allowToLaunchNew(dataCenterId)) {
+            s_logger.warn("The number of launched console proxy on zone " + dataCenterId + " has reached to limit");
+            return null;
+        }
+
+        VMTemplateVO template = null;
+        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
+        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
+        if (template == null) {
+            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
+        }
+
+        Map<String, Object> context = createProxyInstance(dataCenterId, template);
+
+        long proxyVmId = (Long)context.get("proxyVmId");
+        if (proxyVmId == 0) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Creating proxy instance failed, data center id : " + dataCenterId);
+            }
+            return null;
+        }
+
+        ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+        if (proxy != null) {
+            SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
+                new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_CREATED, dataCenterId, proxy.getId(), proxy, null));
+            return proxy;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to allocate console proxy storage, remove the console proxy record from DB, proxy id: " + proxyVmId);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the default network for the console proxy VM, based on the zone it is in. Delegates to
+     * either {@link #getDefaultNetworkForZone(DataCenter)} or {@link #getDefaultNetworkForAdvancedSGZone(DataCenter)},
+     * depending on the zone network type and whether or not security groups are enabled in the zone.
+     * @param dc - The zone (DataCenter) of the console proxy VM.
+     * @return The default network for use with the console proxy VM.
+     */
+    protected NetworkVO getDefaultNetworkForCreation(DataCenter dc) {
+        if (dc.getNetworkType() == NetworkType.Advanced) {
+            return getDefaultNetworkForAdvancedZone(dc);
+        } else {
+            return getDefaultNetworkForBasicZone(dc);
+        }
+    }
+
+    /**
+     * Get default network for a console proxy VM starting up in an advanced zone. If the zone
+     * is security group-enabled, the first network found that supports SG services is returned.
+     * If the zone is not SG-enabled, the Public network is returned.
+     * @param dc - The zone.
+     * @return The selected default network.
+     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
+     */
+    protected NetworkVO getDefaultNetworkForAdvancedZone(DataCenter dc) {
+        if (dc.getNetworkType() != NetworkType.Advanced) {
+            throw new CloudRuntimeException("Zone " + dc + " is not advanced.");
+        }
+
+        if (dc.isSecurityGroupEnabled()) {
+            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dc.getId());
+            if (CollectionUtils.isEmpty(networks)) {
+                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+            }
+
+            return networks.get(0);
+        }
+        else {
+            TrafficType defaultTrafficType = TrafficType.Public;
+            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
+
+            // api should never allow this situation to happen
+            if (defaultNetworks.size() != 1) {
+                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+            }
+
+            return defaultNetworks.get(0);
+        }
+    }
+
+    /**
+     * Get default network for console proxy VM for starting up in a basic zone. Basic zones select
+     * the Guest network whether or not the zone is SG-enabled.
+     * @param dc - The zone.
+     * @return The default network according to the zone's network selection rules.
+     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
+     */
+    protected NetworkVO getDefaultNetworkForBasicZone(DataCenter dc) {
+        if (dc.getNetworkType() != NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + dc + "is not basic.");
+        }
+
+        TrafficType defaultTrafficType = TrafficType.Guest;
+        List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
+
+        // api should never allow this situation to happen
+        if (defaultNetworks.size() != 1) {
+            throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+        }
+
+        return defaultNetworks.get(0);
+    }
+
+    protected Map<String, Object> createProxyInstance(long dataCenterId, VMTemplateVO template) throws ConcurrentOperationException {
+
+        long id = _consoleProxyDao.getNextInSequence(Long.class, "id");
+        String name = VirtualMachineName.getConsoleProxyName(id, _instance);
+        DataCenterVO dc = _dcDao.findById(dataCenterId);
+        Account systemAcct = _accountMgr.getSystemAccount();
+
+        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
+
+        NetworkVO defaultNetwork = getDefaultNetworkForCreation(dc);
+
+        List<? extends NetworkOffering> offerings =
+            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork);
+        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(offerings.size() + 1);
+        NicProfile defaultNic = new NicProfile();
+        defaultNic.setDefaultNic(true);
+        defaultNic.setDeviceId(2);
+
+        networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
+                new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+
+        for (NetworkOffering offering : offerings) {
+            networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), new ArrayList<NicProfile>());
+        }
+
+        ServiceOfferingVO serviceOffering = _serviceOffering;
+        if (serviceOffering == null) {
+            serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
+        }
+        ConsoleProxyVO proxy =
+            new ConsoleProxyVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
+                systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), 0, serviceOffering.isOfferHA());
+        proxy.setDynamicallyScalable(template.isDynamicallyScalable());
+        proxy = _consoleProxyDao.persist(proxy);
+        try {
+            _itMgr.allocate(name, template, serviceOffering, networks, plan, null);
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("InsufficientCapacity", e);
+            throw new CloudRuntimeException("Insufficient capacity exception", e);
+        }
+
+        Map<String, Object> context = new HashMap<String, Object>();
+        context.put("dc", dc);
+        HostPodVO pod = _podDao.findById(proxy.getPodIdToDeployIn());
+        context.put("pod", pod);
+        context.put("proxyVmId", proxy.getId());
+
+        return context;
+    }
+
+    private ConsoleProxyAllocator getCurrentAllocator() {
+        // for now, only one adapter is supported
+        for (ConsoleProxyAllocator allocator : _consoleProxyAllocators) {
+            return allocator;
+        }
+
+        return null;
+    }
+
+    public void onLoadAnswer(ConsoleProxyLoadAnswer answer) {
+        if (answer.getDetails() == null) {
+            return;
+        }
+
+        ConsoleProxyStatus status = null;
+        try {
+            GsonBuilder gb = new GsonBuilder();
+            gb.setVersion(1.3);
+            Gson gson = gb.create();
+            status = gson.fromJson(answer.getDetails(), ConsoleProxyStatus.class);
+        } catch (Throwable e) {
+            s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + answer.getProxyVmId() + ", info : " + answer.getDetails());
+        }
+
+        if (status != null) {
+            int count = 0;
+            if (status.getConnections() != null) {
+                count = status.getConnections().length;
+            }
+
+            byte[] details = null;
+            if (answer.getDetails() != null) {
+                details = answer.getDetails().getBytes(Charset.forName("US-ASCII"));
+            }
+            _consoleProxyDao.update(answer.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Unable to get console proxy load info, id : " + answer.getProxyVmId());
+            }
+
+            _consoleProxyDao.update(answer.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
+            // TODO : something is wrong with the VM, restart it?
+        }
+    }
+
+    public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
+        if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
+            // be it either in alert or in disconnected state, the agent process
+            // may be gone in the VM,
+            // we will be reacting to stop the corresponding VM and let the scan
+            // process to
+            HostVO host = _hostDao.findById(agentId);
+            if (host.getType() == Type.ConsoleProxy) {
+                String name = host.getName();
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Console proxy agent disconnected, proxy: " + name);
+                }
+                if (name != null && name.startsWith("v-")) {
+                    String[] tokens = name.split("-");
+                    long proxyVmId = 0;
+                    try {
+                        proxyVmId = Long.parseLong(tokens[1]);
+                    } catch (NumberFormatException e) {
+                        s_logger.error("Unexpected exception " + e.getMessage(), e);
+                        return;
+                    }
+
+                    final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+                    if (proxy != null) {
+
+                        // Disable this feature for now, as it conflicts with
+                        // the case of allowing user to reboot console proxy
+                        // when rebooting happens, we will receive disconnect
+                        // here and we can't enter into stopping process,
+                        // as when the rebooted one comes up, it will kick off a
+                        // newly started one and trigger the process
+                        // continue on forever
+
+                        /*
+                         * _capacityScanScheduler.execute(new Runnable() { public void run() {
+                         * if(s_logger.isInfoEnabled())
+                         * s_logger.info("Stop console proxy " + proxy.getName() +
+                         * " VM because of that the agent running inside it has disconnected" );
+                         * stopProxy(proxy.getId()); } });
+                         */
+                    } else {
+                        if (s_logger.isInfoEnabled()) {
+                            s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: " + name);
+                        }
+                    }
+                } else {
+                    assert (false) : "Invalid console proxy name: " + name;
+                }
+            }
+        }
+    }
+
+    private boolean reserveStandbyCapacity() {
+        ConsoleProxyManagementState state = getManagementState();
+        if (state == null || state != ConsoleProxyManagementState.Auto) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isConsoleProxyVmRequired(long dcId) {
+        DataCenterVO dc = _dcDao.findById(dcId);
+        _dcDao.loadDetails(dc);
+        String cpvmReq = dc.getDetail(ZoneConfig.EnableConsoleProxyVm.key());
+        if (cpvmReq != null) {
+            return Boolean.parseBoolean(cpvmReq);
+        }
+        return true;
+    }
+
+    private boolean allowToLaunchNew(long dcId) {
+        if (!isConsoleProxyVmRequired(dcId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Console proxy vm not required in zone " + dcId + " not launching");
+            }
+            return false;
+        }
+        List<ConsoleProxyVO> l =
+            _consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping,
+                VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdowned, VirtualMachine.State.Unknown);
+
+        String value = _configDao.getValue(Config.ConsoleProxyLaunchMax.key());
+        int launchLimit = NumbersUtil.parseInt(value, 10);
+        return l.size() < launchLimit;
+    }
+
+    private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo) {
+
+        if (proxyCountInfo.getCount() * _capacityPerProxy - vmCountInfo.getCount() <= _standbyCapacity) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void allocCapacity(long dataCenterId) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Allocate console proxy standby capacity for data center : " + dataCenterId);
+        }
+
+        ConsoleProxyVO proxy = null;
+        String errorString = null;
+        try {
+            boolean consoleProxyVmFromStoppedPool = false;
+            proxy = assignProxyFromStoppedPool(dataCenterId);
+            if (proxy == null) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("No stopped console proxy is available, need to allocate a new console proxy");
+                }
+
+                if (_allocProxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                    try {
+                        proxy = startNew(dataCenterId);
+                    } catch (ConcurrentOperationException e) {
+                        s_logger.info("Concurrent operation exception caught " + e);
+                    } finally {
+                        _allocProxyLock.unlock();
+                    }
+                } else {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Unable to acquire synchronization lock for console proxy vm allocation, wait for next scan");
+                    }
+                }
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Found a stopped console proxy, starting it. Vm id : " + proxy.getId());
+                }
+                consoleProxyVmFromStoppedPool = true;
+            }
+
+            if (proxy != null) {
+                long proxyVmId = proxy.getId();
+                proxy = startProxy(proxyVmId, false);
+
+                if (proxy != null) {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Console proxy " + proxy.getHostName() + " is started");
+                    }
+                    SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
+                        new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_UP, dataCenterId, proxy.getId(), proxy, null));
+                } else {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Unable to start console proxy vm for standby capacity, vm id : " + proxyVmId + ", will recycle it and start a new one");
+                    }
+
+                    if (consoleProxyVmFromStoppedPool) {
+                        destroyProxy(proxyVmId);
+                    }
+                }
+            }
+        } catch (Exception e) {
+           errorString = e.getMessage();
+           throw e;
+        } finally {
+            // TODO - For now put all the alerts as creation failure. Distinguish between creation vs start failure in future.
+            // Also add failure reason since startvm masks some of them.
+            if (proxy == null || proxy.getState() != State.Running)
+                SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
+                    new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_CREATE_FAILURE, dataCenterId, 0l, null, errorString));
+        }
+    }
+
+    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
+        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
+        if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) {
+            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
+            if (template == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch console proxy vm");
+                }
+                return false;
+            }
+            TemplateDataStoreVO templateHostRef = _vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dataCenterId, Status.DOWNLOADED);
+
+            if (templateHostRef != null) {
+                boolean useLocalStorage = false;
+                Boolean useLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId);
+                if (useLocal != null) {
+                    useLocalStorage = useLocal.booleanValue();
+                }
+                List<Pair<Long, Integer>> l = _consoleProxyDao.getDatacenterStoragePoolHostInfo(dataCenterId, useLocalStorage);
+                if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
+                    return true;
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Primary storage is not ready, wait until it is ready to launch console proxy");
+                    }
+                }
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage.");
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isZoneHostReady(ZoneHostInfo zoneHostInfo) {
+        int expectedFlags = 0;
+        if (_useStorageVm) {
+            expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK;
+        } else {
+            expectedFlags = RunningHostInfoAgregator.ZoneHostInfo.ALL_HOST_MASK;
+        }
+
+        return (zoneHostInfo.getFlags() & expectedFlags) == expectedFlags;
+    }
+
+    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
+        Date cutTime = DateUtil.currentGMTTime();
+        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
+
+        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
+        if (l.size() > 0) {
+            for (RunningHostCountInfo countInfo : l) {
+                aggregator.aggregate(countInfo);
+            }
+        }
+
+        return aggregator.getZoneHostInfoMap();
+    }
+
+    @Override
+    public boolean start() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start console proxy manager");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Stop console proxy manager");
+        }
+
+        _loadScanner.stop();
+        _allocProxyLock.releaseRef();
+        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+        return true;
+    }
+
+    @Override
+    public boolean stopProxy(long proxyVmId) {
+        ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+        if (proxy == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Stopping console proxy failed: console proxy " + proxyVmId + " no longer exists");
+            }
+            return false;
+        }
+
+        try {
+            _itMgr.stop(proxy.getUuid());
+            return true;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Stopping console proxy " + proxy.getHostName() + " failed : exception ", e);
+            return false;
+        } catch (CloudRuntimeException e) {
+            s_logger.warn("Unable to stop proxy ", e);
+            return false;
+        }
+    }
+
+    @Override
+    @DB
+    public void setManagementState(final ConsoleProxyManagementState state) {
+        try {
+            final ConsoleProxyManagementState lastState = getManagementState();
+            if (lastState == null) {
+                return;
+            }
+
+            if (lastState != state) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        _configDao.update(Config.ConsoleProxyManagementLastState.key(), Config.ConsoleProxyManagementLastState.getCategory(), lastState.toString());
+                        _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), state.toString());
+                    }
+                });
+            }
+        } catch (Throwable e) {
+            s_logger.error("Failed to set managment state", e);
+        }
+    }
+
+    @Override
+    public ConsoleProxyManagementState getManagementState() {
+        String value = _configDao.getValue(Config.ConsoleProxyManagementState.key());
+        if (value != null) {
+            ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
+
+            if (state == null) {
+                s_logger.error("Invalid console proxy management state: " + value);
+            }
+            return state;
+        }
+
+        s_logger.error("Invalid console proxy management state: " + value);
+        return null;
+    }
+
+    @Override
+    @DB
+    public void resumeLastManagementState() {
+        try {
+            ConsoleProxyManagementState state = getManagementState();
+            ConsoleProxyManagementState lastState = getLastManagementState();
+            if (lastState == null) {
+                return;
+            }
+
+            if (lastState != state) {
+                _configDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), lastState.toString());
+            }
+        } catch (Throwable e) {
+            s_logger.error("Failed to resume last management state", e);
+        }
+    }
+
+    private ConsoleProxyManagementState getLastManagementState() {
+        String value = _configDao.getValue(Config.ConsoleProxyManagementLastState.key());
+        if (value != null) {
+            ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
+
+            if (state == null) {
+                s_logger.error("Invalid console proxy management state: " + value);
+            }
+            return state;
+        }
+
+        s_logger.error("Invalid console proxy management state: " + value);
+        return null;
+    }
+
+    @Override
+    public boolean rebootProxy(long proxyVmId) {
+        final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+
+        if (proxy == null || proxy.getState() == State.Destroyed) {
+            return false;
+        }
+
+        if (proxy.getState() == State.Running && proxy.getHostId() != null) {
+            final RebootCommand cmd = new RebootCommand(proxy.getInstanceName(), _itMgr.getExecuteInSequence(proxy.getHypervisorType()));
+            final Answer answer = _agentMgr.easySend(proxy.getHostId(), cmd);
+
+            if (answer != null && answer.getResult()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully reboot console proxy " + proxy.getHostName());
+                }
+
+                SubscriptionMgr.getInstance().notifySubscribers(ConsoleProxyManager.ALERT_SUBJECT, this,
+                    new ConsoleProxyAlertEventArgs(ConsoleProxyAlertEventArgs.PROXY_REBOOTED, proxy.getDataCenterId(), proxy.getId(), proxy, null));
+
+                return true;
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("failed to reboot console proxy : " + proxy.getHostName());
+                }
+
+                return false;
+            }
+        } else {
+            return startProxy(proxyVmId, false) != null;
+        }
+    }
+
+    @Override
+    public boolean destroyProxy(long vmId) {
+        ConsoleProxyVO proxy = _consoleProxyDao.findById(vmId);
+        try {
+            //expunge the vm
+            _itMgr.expunge(proxy.getUuid());
+            proxy.setPublicIpAddress(null);
+            proxy.setPublicMacAddress(null);
+            proxy.setPublicNetmask(null);
+            proxy.setPrivateMacAddress(null);
+            proxy.setPrivateIpAddress(null);
+            _consoleProxyDao.update(proxy.getId(), proxy);
+            _consoleProxyDao.remove(vmId);
+            HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Host.Type.ConsoleProxy);
+            if (host != null) {
+                s_logger.debug("Removing host entry for proxy id=" + vmId);
+                return _hostDao.remove(host.getId());
+            }
+
+            return true;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to expunge " + proxy, e);
+            return false;
+        }
+    }
+
+    private String getAllocProxyLockName() {
+        return "consoleproxy.alloc";
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start configuring console proxy manager : " + name);
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+        String value = configs.get("consoleproxy.sslEnabled");
+        if (value != null && value.equalsIgnoreCase("true")) {
+            _sslEnabled = true;
+        }
+
+        _consoleProxyUrlDomain = configs.get(Config.ConsoleProxyUrlDomain.key());
+        if( _sslEnabled && (_consoleProxyUrlDomain == null || _consoleProxyUrlDomain.isEmpty())) {
+            s_logger.warn("Empty console proxy domain, explicitly disabling SSL");
+            _sslEnabled = false;
+        }
+
+        value = configs.get(Config.ConsoleProxyCapacityScanInterval.key());
+        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
+
+        _capacityPerProxy = NumbersUtil.parseInt(configs.get("consoleproxy.session.max"), DEFAULT_PROXY_CAPACITY);
+        _standbyCapacity = NumbersUtil.parseInt(configs.get("consoleproxy.capacity.standby"), DEFAULT_STANDBY_CAPACITY);
+        _proxySessionTimeoutValue = NumbersUtil.parseInt(configs.get("consoleproxy.session.timeout"), DEFAULT_PROXY_SESSION_TIMEOUT);
+
+        value = configs.get("consoleproxy.port");
+        if (value != null) {
+            _consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
+        }
+
+        value = configs.get(Config.ConsoleProxyDisableRpFilter.key());
+        if (value != null && value.equalsIgnoreCase("true")) {
+            _disableRpFilter = true;
+        }
+
+        value = configs.get("secondary.storage.vm");
+        if (value != null && value.equalsIgnoreCase("true")) {
+            _useStorageVm = true;
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Console proxy max session soft limit : " + _capacityPerProxy);
+            s_logger.info("Console proxy standby capacity : " + _standbyCapacity);
+        }
+
+        _instance = configs.get("instance.name");
+        if (_instance == null) {
+            _instance = "DEFAULT";
+        }
+
+        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
+
+        value = agentMgrConfigs.get("port");
+        _mgmtPort = NumbersUtil.parseInt(value, 8250);
+
+        _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr));
+        _agentMgr.registerForHostEvents(_listener, true, true, false);
+
+        _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
+
+        //check if there is a default service offering configured
+        String cpvmSrvcOffIdStr = configs.get(Config.ConsoleProxyServiceOffering.key());
+        if (cpvmSrvcOffIdStr != null) {
+            _serviceOffering = _offeringDao.findByUuid(cpvmSrvcOffIdStr);
+            if (_serviceOffering == null) {
+                try {
+                    _serviceOffering = _offeringDao.findById(Long.parseLong(cpvmSrvcOffIdStr));
+                } catch (NumberFormatException ex) {
+                    s_logger.debug("The system service offering specified by global config is not id, but uuid=" + cpvmSrvcOffIdStr + " for console proxy vm");
+                }
+            }
+            if (_serviceOffering == null) {
+                s_logger.warn("Can't find system service offering specified by global config, uuid=" + cpvmSrvcOffIdStr + " for console proxy vm");
+            }
+        }
+
+        if (_serviceOffering == null || !_serviceOffering.isSystemUse()) {
+            int ramSize = NumbersUtil.parseInt(_configDao.getValue("console.ram.size"), DEFAULT_PROXY_VM_RAMSIZE);
+            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("console.cpu.mhz"), DEFAULT_PROXY_VM_CPUMHZ);
+            List<ServiceOfferingVO> offerings = _offeringDao.createSystemServiceOfferings("System Offering For Console Proxy",
+                    ServiceOffering.consoleProxyDefaultOffUniqueName, 1, ramSize, cpuFreq, 0, 0, false, null,
+                    Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.ConsoleProxy, true);
+            // this can sometimes happen, if DB is manually or programmatically manipulated
+            if (offerings == null || offerings.size() < 2) {
+                String msg = "Data integrity problem : System Offering For Console Proxy has been removed?";
+                s_logger.error(msg);
+                throw new ConfigurationException(msg);
+            }
+        }
+
+        _loadScanner = new SystemVmLoadScanner<Long>(this);
+        _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+
+        _staticPublicIp = _configDao.getValue("consoleproxy.static.publicIp");
+        if (_staticPublicIp != null) {
+            _staticPort = NumbersUtil.parseInt(_configDao.getValue("consoleproxy.static.port"), 8443);
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Console Proxy Manager is configured.");
+        }
+        return true;
+    }
+
+    protected ConsoleProxyManagerImpl() {
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+        ConsoleProxyVO vm = _consoleProxyDao.findById(profile.getId());
+        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
+        vm.setDetails(details);
+
+        StringBuilder buf = profile.getBootArgsBuilder();
+        buf.append(" template=domP type=consoleproxy");
+        buf.append(" host=").append(StringUtils.toCSVList(indirectAgentLB.getManagementServerList(dest.getHost().getId(), dest.getDataCenter().getId(), null)));
+        buf.append(" port=").append(_mgmtPort);
+        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
+        if (_sslEnabled) {
+            buf.append(" premium=true");
+        }
+        buf.append(" zone=").append(dest.getDataCenter().getId());
+        buf.append(" pod=").append(dest.getPod().getId());
+        buf.append(" guid=Proxy.").append(profile.getId());
+        buf.append(" proxy_vm=").append(profile.getId());
+        if (_disableRpFilter) {
+            buf.append(" disable_rp_filter=true");
+        }
+
+        boolean externalDhcp = false;
+        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
+        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
+            externalDhcp = true;
+        }
+
+        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
+        }
+
+        for (NicProfile nic : profile.getNics()) {
+            int deviceId = nic.getDeviceId();
+            if (nic.getIPv4Address() == null) {
+                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
+                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
+            } else {
+                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
+                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
+            }
+
+            if (nic.isDefaultNic()) {
+                buf.append(" gateway=").append(nic.getIPv4Gateway());
+            }
+
+            if (nic.getTrafficType() == TrafficType.Management) {
+                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
+                if (NetUtils.isValidIp4Cidr(mgmt_cidr)) {
+                    buf.append(" mgmtcidr=").append(mgmt_cidr);
+                }
+                buf.append(" localgw=").append(dest.getPod().getGateway());
+            }
+        }
+
+        /* External DHCP mode */
+        if (externalDhcp) {
+            buf.append(" bootproto=dhcp");
+        }
+        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
+        buf.append(" internaldns1=").append(dc.getInternalDns1());
+        if (dc.getInternalDns2() != null) {
+            buf.append(" internaldns2=").append(dc.getInternalDns2());
+        }
+        buf.append(" dns1=").append(dc.getDns1());
+        if (dc.getDns2() != null) {
+            buf.append(" dns2=").append(dc.getDns2());
+        }
+
+        String bootArgs = buf.toString();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+        finalizeCommandsOnStart(cmds, profile);
+
+        ConsoleProxyVO proxy = _consoleProxyDao.findById(profile.getId());
+        DataCenter dc = dest.getDataCenter();
+        List<NicProfile> nics = profile.getNics();
+        for (NicProfile nic : nics) {
+            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
+                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
+                proxy.setPublicIpAddress(nic.getIPv4Address());
+                proxy.setPublicNetmask(nic.getIPv4Netmask());
+                proxy.setPublicMacAddress(nic.getMacAddress());
+            } else if (nic.getTrafficType() == TrafficType.Management) {
+                proxy.setPrivateIpAddress(nic.getIPv4Address());
+                proxy.setPrivateMacAddress(nic.getMacAddress());
+            }
+        }
+        _consoleProxyDao.update(proxy.getId(), proxy);
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+
+        NicProfile managementNic = null;
+        NicProfile controlNic = null;
+        for (NicProfile nic : profile.getNics()) {
+            if (nic.getTrafficType() == TrafficType.Management) {
+                managementNic = nic;
+            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
+                controlNic = nic;
+            }
+        }
+
+        if (controlNic == null) {
+            if (managementNic == null) {
+                s_logger.error("Management network doesn't exist for the console proxy vm " + profile.getVirtualMachine());
+                return false;
+            }
+            controlNic = managementNic;
+        }
+
+        // verify ssh access on management nic for system vm running on HyperV
+        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
+            controlNic = managementNic;
+        }
+
+        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922);
+        cmds.addCommand("checkSsh", check);
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
+        if (answer == null || !answer.getResult()) {
+            if (answer != null) {
+                s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
+            } else {
+                s_logger.warn("Unable to ssh to the VM: null answer");
+            }
+            return false;
+        }
+
+        try {
+            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
+            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
+            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
+            if (ipaddr != null && ipaddr.getSystem()) {
+                ConsoleProxyVO consoleVm = _consoleProxyDao.findById(profile.getId());
+                // override CPVM guest IP with EIP, so that console url's will be prepared with EIP
+                consoleVm.setPublicIpAddress(ipaddr.getAddress().addr());
+                _consoleProxyDao.update(consoleVm.getId(), consoleVm);
+            }
+        } catch (Exception ex) {
+            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void finalizeExpunge(VirtualMachine vm) {
+        ConsoleProxyVO proxy = _consoleProxyDao.findById(vm.getId());
+        proxy.setPublicIpAddress(null);
+        proxy.setPublicMacAddress(null);
+        proxy.setPublicNetmask(null);
+        proxy.setPrivateMacAddress(null);
+        proxy.setPrivateIpAddress(null);
+        _consoleProxyDao.update(proxy.getId(), proxy);
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+        //release elastic IP here if assigned
+        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
+        if (ip != null && ip.getSystem()) {
+            CallContext ctx = CallContext.current();
+            try {
+                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
+            } catch (Exception ex) {
+                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
+                    ex);
+            }
+        }
+    }
+
+    @Override
+    public String getScanHandlerName() {
+        return "consoleproxy";
+    }
+
+    @Override
+    public void onScanStart() {
+        // to reduce possible number of DB queries for capacity scan, we run following aggregated queries in preparation
+        // stage
+        _zoneHostInfoMap = getZoneHostInfo();
+
+        _zoneProxyCountMap = new HashMap<Long, ConsoleProxyLoadInfo>();
+        List<ConsoleProxyLoadInfo> listProxyCounts = _consoleProxyDao.getDatacenterProxyLoadMatrix();
+        for (ConsoleProxyLoadInfo info : listProxyCounts) {
+            _zoneProxyCountMap.put(info.getId(), info);
+        }
+
+        _zoneVmCountMap = new HashMap<Long, ConsoleProxyLoadInfo>();
+        List<ConsoleProxyLoadInfo> listVmCounts = _consoleProxyDao.getDatacenterSessionLoadMatrix();
+        for (ConsoleProxyLoadInfo info : listVmCounts) {
+            _zoneVmCountMap.put(info.getId(), info);
+        }
+    }
+
+    private void scanManagementState() {
+        ConsoleProxyManagementState state = getManagementState();
+        if (state != null) {
+            switch (state) {
+                case Auto:
+                case Manual:
+                case Suspending:
+                    break;
+
+                case ResetSuspending:
+                    handleResetSuspending();
+                    break;
+
+                default:
+                    assert (false);
+            }
+        }
+    }
+
+    private void handleResetSuspending() {
+        List<ConsoleProxyVO> runningProxies = _consoleProxyDao.getProxyListInStates(State.Running);
+        for (ConsoleProxyVO proxy : runningProxies) {
+            s_logger.info("Stop console proxy " + proxy.getId() + " because of we are currently in ResetSuspending management mode");
+            stopProxy(proxy.getId());
+        }
+
+        // check if it is time to resume
+        List<ConsoleProxyVO> proxiesInTransition = _consoleProxyDao.getProxyListInStates(State.Running, State.Starting, State.Stopping);
+        if (proxiesInTransition.size() == 0) {
+            s_logger.info("All previous console proxy VMs in transition mode ceased the mode, we will now resume to last management state");
+            resumeLastManagementState();
+        }
+    }
+
+    @Override
+    public boolean canScan() {
+        // take the chance to do management-state management
+        scanManagementState();
+
+        if (!reserveStandbyCapacity()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Reserving standby capacity is disabled, skip capacity scan");
+            }
+            return false;
+        }
+
+        List<StoragePoolVO> upPools = _storagePoolDao.listByStatus(StoragePoolStatus.Up);
+        if (upPools == null || upPools.size() == 0) {
+            s_logger.debug("Skip capacity scan as there is no Primary Storage in 'Up' state");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public Long[] getScannablePools() {
+        List<DataCenterVO> zones = _dcDao.listEnabledZones();
+
+        Long[] dcIdList = new Long[zones.size()];
+        int i = 0;
+        for (DataCenterVO dc : zones) {
+            dcIdList[i++] = dc.getId();
+        }
+
+        return dcIdList;
+    }
+
+    @Override
+    public boolean isPoolReadyForScan(Long pool) {
+        // pool is at zone basis
+        long dataCenterId = pool.longValue();
+
+        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Zone " + dataCenterId + " is not ready to launch console proxy yet");
+            }
+            return false;
+        }
+
+        List<ConsoleProxyVO> l = _consoleProxyDao.getProxyListInStates(VirtualMachine.State.Starting, VirtualMachine.State.Stopping);
+        if (l.size() > 0) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Zone " + dataCenterId + " has " + l.size() + " console proxy VM(s) in transition state");
+            }
+
+            return false;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Zone " + dataCenterId + " is ready to launch console proxy");
+        }
+        return true;
+    }
+
+    @Override
+    public Pair<AfterScanAction, Object> scanPool(Long pool) {
+        long dataCenterId = pool.longValue();
+
+        ConsoleProxyLoadInfo proxyInfo = _zoneProxyCountMap.get(dataCenterId);
+        if (proxyInfo == null) {
+            return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+        }
+
+        ConsoleProxyLoadInfo vmInfo = _zoneVmCountMap.get(dataCenterId);
+        if (vmInfo == null) {
+            vmInfo = new ConsoleProxyLoadInfo();
+        }
+
+        if (!checkCapacity(proxyInfo, vmInfo)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Expand console proxy standby capacity for zone " + proxyInfo.getName());
+            }
+
+            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, null);
+        }
+
+        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+    }
+
+    @Override
+    public void expandPool(Long pool, Object actionArgs) {
+        long dataCenterId = pool.longValue();
+        allocCapacity(dataCenterId);
+    }
+
+    @Override
+    public void shrinkPool(Long pool, Object actionArgs) {
+    }
+
+    @Override
+    public void onScanEnd() {
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        if (!(cmd[0] instanceof StartupProxyCommand)) {
+            return null;
+        }
+
+        host.setType(com.cloud.host.Host.Type.ConsoleProxy);
+        return host;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        return null;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        return null;
+    }
+
+    protected HostVO findConsoleProxyHostByName(String name) {
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.ConsoleProxy);
+        sc.and(sc.entity().getName(), Op.EQ, name);
+        return sc.find();
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile profile) {
+    }
+
+    public List<ConsoleProxyAllocator> getConsoleProxyAllocators() {
+        return _consoleProxyAllocators;
+    }
+
+    @Inject
+    public void setConsoleProxyAllocators(List<ConsoleProxyAllocator> consoleProxyAllocators) {
+        _consoleProxyAllocators = consoleProxyAllocators;
+    }
+
+}
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyService.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/ConsoleProxyService.java
rename to server/src/main/java/com/cloud/consoleproxy/ConsoleProxyService.java
diff --git a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java b/server/src/main/java/com/cloud/consoleproxy/StaticConsoleProxyManager.java
similarity index 100%
rename from server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
rename to server/src/main/java/com/cloud/consoleproxy/StaticConsoleProxyManager.java
diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/main/java/com/cloud/dc/DedicatedResourceVO.java
similarity index 100%
rename from server/src/com/cloud/dc/DedicatedResourceVO.java
rename to server/src/main/java/com/cloud/dc/DedicatedResourceVO.java
diff --git a/server/src/com/cloud/dc/dao/DedicatedResourceDao.java b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java
similarity index 100%
rename from server/src/com/cloud/dc/dao/DedicatedResourceDao.java
rename to server/src/main/java/com/cloud/dc/dao/DedicatedResourceDao.java
diff --git a/server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java b/server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
rename to server/src/main/java/com/cloud/dc/dao/DedicatedResourceDaoImpl.java
diff --git a/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java
new file mode 100644
index 0000000..a95f4ef
--- /dev/null
+++ b/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -0,0 +1,1619 @@
+// 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.deploy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TreeSet;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.fsm.StateMachine2;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+import org.apache.cloudstack.affinity.AffinityGroupProcessor;
+import org.apache.cloudstack.affinity.AffinityGroupService;
+import org.apache.cloudstack.affinity.AffinityGroupVMMapVO;
+import org.apache.cloudstack.affinity.AffinityGroupVO;
+import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
+import org.apache.cloudstack.engine.cloud.entity.api.db.VMReservationVO;
+import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMReservationDao;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
+import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.manager.allocator.HostAllocator;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManagerImpl;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.DeploymentPlanner.PlannerResourceUsage;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
+import com.cloud.exception.AffinityConflictException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.gpu.GPU;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Event;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class DeploymentPlanningManagerImpl extends ManagerBase implements DeploymentPlanningManager, Manager, Listener,
+StateListener<State, VirtualMachine.Event, VirtualMachine> {
+
+    private static final Logger s_logger = Logger.getLogger(DeploymentPlanningManagerImpl.class);
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    protected UserVmDao _vmDao;
+    @Inject
+    protected VMInstanceDao _vmInstanceDao;
+    @Inject
+    protected AffinityGroupDao _affinityGroupDao;
+    @Inject
+    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
+    @Inject
+    protected AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
+    @Inject
+    AffinityGroupService _affinityGroupService;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    PlannerHostReservationDao _plannerHostReserveDao;
+    private int _vmCapacityReleaseInterval;
+    @Inject
+    MessageBus _messageBus;
+    private Timer _timer = null;
+    private long _hostReservationReleasePeriod = 60L * 60L * 1000L; // one hour by default
+    @Inject
+    protected VMReservationDao _reservationDao;
+
+    private static final long INITIAL_RESERVATION_RELEASE_CHECKER_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
+    protected long _nodeId = -1;
+
+    protected List<StoragePoolAllocator> _storagePoolAllocators;
+
+    public List<StoragePoolAllocator> getStoragePoolAllocators() {
+        return _storagePoolAllocators;
+    }
+
+    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
+        _storagePoolAllocators = storagePoolAllocators;
+    }
+
+    protected List<HostAllocator> _hostAllocators;
+
+    public List<HostAllocator> getHostAllocators() {
+        return _hostAllocators;
+    }
+
+    public void setHostAllocators(List<HostAllocator> hostAllocators) {
+        _hostAllocators = hostAllocators;
+    }
+
+    @Inject
+    protected HostDao _hostDao;
+    @Inject
+    protected HostPodDao _podDao;
+    @Inject
+    protected ClusterDao _clusterDao;
+    @Inject
+    protected DedicatedResourceDao _dedicatedDao;
+    @Inject
+    protected GuestOSDao _guestOSDao = null;
+    @Inject
+    protected GuestOSCategoryDao _guestOSCategoryDao = null;
+    @Inject
+    protected DiskOfferingDao _diskOfferingDao;
+    @Inject
+    protected StoragePoolHostDao _poolHostDao;
+
+    @Inject
+    protected VolumeDao _volsDao;
+    @Inject
+    protected CapacityManager _capacityMgr;
+    @Inject
+    protected ConfigurationDao _configDao;
+    @Inject
+    protected PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    protected CapacityDao _capacityDao;
+    @Inject
+    protected AccountManager _accountMgr;
+    @Inject
+    protected StorageManager _storageMgr;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    protected ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    protected ResourceManager _resourceMgr;
+    @Inject
+    protected ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+
+    protected List<DeploymentPlanner> _planners;
+
+    public List<DeploymentPlanner> getPlanners() {
+        return _planners;
+    }
+
+    public void setPlanners(List<DeploymentPlanner> planners) {
+        _planners = planners;
+    }
+
+    protected List<AffinityGroupProcessor> _affinityProcessors;
+
+    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
+        return _affinityProcessors;
+    }
+
+    public void setAffinityGroupProcessors(List<AffinityGroupProcessor> affinityProcessors) {
+        _affinityProcessors = affinityProcessors;
+    }
+
+    @Override
+    public DeployDestination planDeployment(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, DeploymentPlanner planner)
+            throws InsufficientServerCapacityException, AffinityConflictException {
+
+        ServiceOffering offering = vmProfile.getServiceOffering();
+        int cpu_requested = offering.getCpu() * offering.getSpeed();
+        long ram_requested = offering.getRamSize() * 1024L * 1024L;
+        VirtualMachine vm = vmProfile.getVirtualMachine();
+        DataCenter dc = _dcDao.findById(vm.getDataCenterId());
+
+
+        if (vm.getType() == VirtualMachine.Type.User || vm.getType() == VirtualMachine.Type.DomainRouter) {
+            checkForNonDedicatedResources(vmProfile, dc, avoids);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("DeploymentPlanner allocation algorithm: " + planner);
+
+            s_logger.debug("Trying to allocate a host and storage pools from dc:" + plan.getDataCenterId() + ", pod:" + plan.getPodId() + ",cluster:" +
+                    plan.getClusterId() + ", requested cpu: " + cpu_requested + ", requested ram: " + ram_requested);
+
+            s_logger.debug("Is ROOT volume READY (pool already allocated)?: " + (plan.getPoolId() != null ? "Yes" : "No"));
+        }
+
+        String haVmTag = (String)vmProfile.getParameter(VirtualMachineProfile.Param.HaTag);
+
+        if (plan.getHostId() != null && haVmTag == null) {
+            Long hostIdSpecified = plan.getHostId();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: " + hostIdSpecified);
+            }
+            HostVO host = _hostDao.findById(hostIdSpecified);
+            if (host == null) {
+                s_logger.debug("The specified host cannot be found");
+            } else if (avoids.shouldAvoid(host)) {
+                s_logger.debug("The specified host is in avoid set");
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(
+                            "Looking for suitable pools for this host under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId());
+                }
+
+                Pod pod = _podDao.findById(host.getPodId());
+                // check if the cluster or the pod is disabled
+                if (pod.getAllocationState() != Grouping.AllocationState.Enabled) {
+                    s_logger.warn("The Pod containing this host is in disabled state, PodId= " + pod.getId());
+                    return null;
+                }
+
+                Cluster cluster = _clusterDao.findById(host.getClusterId());
+                if (cluster.getAllocationState() != Grouping.AllocationState.Enabled) {
+                    s_logger.warn("The Cluster containing this host is in disabled state, PodId= " + cluster.getId());
+                    return null;
+                }
+
+                if (vm.getHypervisorType() == HypervisorType.BareMetal) {
+                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
+                    s_logger.debug("Returning Deployment Destination: " + dest);
+                    return dest;
+                }
+
+                // search for storage under the zone, pod, cluster of the host.
+                DataCenterDeployment lastPlan =
+                        new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), hostIdSpecified, plan.getPoolId(), null,
+                                plan.getReservationContext());
+
+                Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
+                Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
+                List<Volume> readyAndReusedVolumes = result.second();
+
+                // choose the potential pool for this VM for this host
+                if (!suitableVolumeStoragePools.isEmpty()) {
+                    List<Host> suitableHosts = new ArrayList<Host>();
+                    suitableHosts.add(host);
+                    Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
+                            suitableHosts, suitableVolumeStoragePools, avoids,
+                            getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
+                    if (potentialResources != null) {
+                        pod = _podDao.findById(host.getPodId());
+                        cluster = _clusterDao.findById(host.getClusterId());
+                        Map<Volume, StoragePool> storageVolMap = potentialResources.second();
+                        // remove the reused vol<->pool from destination, since
+                        // we don't have to prepare this volume.
+                        for (Volume vol : readyAndReusedVolumes) {
+                            storageVolMap.remove(vol);
+                        }
+                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
+                        s_logger.debug("Returning Deployment Destination: " + dest);
+                        return dest;
+                    }
+                }
+            }
+            s_logger.debug("Cannot deploy to specified host, returning.");
+            return null;
+        }
+
+        // call affinitygroup chain
+        long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
+
+        if (vmGroupCount > 0) {
+            for (AffinityGroupProcessor processor : _affinityProcessors) {
+                processor.process(vmProfile, plan, avoids);
+            }
+        }
+
+        if (vm.getType() == VirtualMachine.Type.User) {
+            checkForNonDedicatedResources(vmProfile, dc, avoids);
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deploy avoids pods: " + avoids.getPodsToAvoid() + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid());
+        }
+
+        // call planners
+        // DataCenter dc = _dcDao.findById(vm.getDataCenterId());
+        // check if datacenter is in avoid set
+        if (avoids.shouldAvoid(dc)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("DataCenter id = '" + dc.getId() + "' provided is in avoid set, DeploymentPlanner cannot allocate the VM, returning.");
+            }
+            return null;
+        }
+
+        if (planner == null) {
+            String plannerName = offering.getDeploymentPlanner();
+            if (plannerName == null) {
+                if (vm.getHypervisorType() == HypervisorType.BareMetal) {
+                    plannerName = "BareMetalPlanner";
+                } else {
+                    plannerName = _configDao.getValue(Config.VmDeploymentPlanner.key());
+                }
+            }
+            planner = getDeploymentPlannerByName(plannerName);
+        }
+
+        if (vm.getLastHostId() != null && haVmTag == null) {
+            s_logger.debug("This VM has last host_id specified, trying to choose the same host: " + vm.getLastHostId());
+
+            HostVO host = _hostDao.findById(vm.getLastHostId());
+            ServiceOfferingDetailsVO offeringDetails = null;
+            if (host == null) {
+                s_logger.debug("The last host of this VM cannot be found");
+            } else if (avoids.shouldAvoid(host)) {
+                s_logger.debug("The last host of this VM is in avoid set");
+            } else if (plan.getClusterId() != null && host.getClusterId() != null
+                    && !plan.getClusterId().equals(host.getClusterId())) {
+                s_logger.debug("The last host of this VM cannot be picked as the plan specifies different clusterId: "
+                        + plan.getClusterId());
+            } else if (_capacityMgr.checkIfHostReachMaxGuestLimit(host)) {
+                s_logger.debug("The last Host, hostId: " + host.getId() +
+                        " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts");
+            } else if ((offeringDetails  = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
+                ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
+                if(!_resourceMgr.isGPUDeviceAvailable(host.getId(), groupName.getValue(), offeringDetails.getValue())){
+                    s_logger.debug("The last host of this VM does not have required GPU devices available");
+                }
+            } else {
+                if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) {
+                    boolean hostTagsMatch = true;
+                    if(offering.getHostTag() != null){
+                        _hostDao.loadHostTags(host);
+                        if (!(host.getHostTags() != null && host.getHostTags().contains(offering.getHostTag()))) {
+                            hostTagsMatch = false;
+                        }
+                    }
+                    if (hostTagsMatch) {
+                        long cluster_id = host.getClusterId();
+                        ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id,
+                                "cpuOvercommitRatio");
+                        ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id,
+                                "memoryOvercommitRatio");
+                        Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue());
+                        Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue());
+
+                        boolean hostHasCpuCapability, hostHasCapacity = false;
+                        hostHasCpuCapability = _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed());
+
+                        if (hostHasCpuCapability) {
+                            // first check from reserved capacity
+                            hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOvercommitRatio, memoryOvercommitRatio, true);
+
+                            // if not reserved, check the free capacity
+                            if (!hostHasCapacity)
+                                hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, false, cpuOvercommitRatio, memoryOvercommitRatio, true);
+                        }
+
+                        if (hostHasCapacity
+                                && hostHasCpuCapability) {
+                            s_logger.debug("The last host of this VM is UP and has enough capacity");
+                            s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId()
+                                    + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId());
+
+                            Pod pod = _podDao.findById(host.getPodId());
+                            Cluster cluster = _clusterDao.findById(host.getClusterId());
+                            if (vm.getHypervisorType() == HypervisorType.BareMetal) {
+                                DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
+                                s_logger.debug("Returning Deployment Destination: " + dest);
+                                return dest;
+                            }
+
+                            // search for storage under the zone, pod, cluster
+                            // of
+                            // the last host.
+                            DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(),
+                                    host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null);
+                            Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(
+                                    vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL);
+                            Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
+                            List<Volume> readyAndReusedVolumes = result.second();
+
+                            // choose the potential pool for this VM for this
+                            // host
+                            if (!suitableVolumeStoragePools.isEmpty()) {
+                                List<Host> suitableHosts = new ArrayList<Host>();
+                                suitableHosts.add(host);
+                                Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
+                                        suitableHosts, suitableVolumeStoragePools, avoids,
+                                        getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
+                                if (potentialResources != null) {
+                                    Map<Volume, StoragePool> storageVolMap = potentialResources.second();
+                                    // remove the reused vol<->pool from
+                                    // destination, since we don't have to
+                                    // prepare
+                                    // this volume.
+                                    for (Volume vol : readyAndReusedVolumes) {
+                                        storageVolMap.remove(vol);
+                                    }
+                                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host,
+                                            storageVolMap);
+                                    s_logger.debug("Returning Deployment Destination: " + dest);
+                                    return dest;
+                                }
+                            }
+                        } else {
+                            s_logger.debug("The last host of this VM does not have enough capacity");
+                        }
+                    } else {
+                        s_logger.debug("Service Offering host tag does not match the last host of this VM");
+                    }
+                } else {
+                    s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " +
+                            host.getResourceState());
+                }
+            }
+            s_logger.debug("Cannot choose the last host to deploy this VM ");
+        }
+
+        DeployDestination dest = null;
+        List<Long> clusterList = null;
+
+        if (planner != null && planner.canHandle(vmProfile, plan, avoids)) {
+            while (true) {
+                if (planner instanceof DeploymentClusterPlanner) {
+
+                    ExcludeList plannerAvoidInput =
+                            new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
+                                    avoids.getPoolsToAvoid());
+
+                    clusterList = ((DeploymentClusterPlanner)planner).orderClusters(vmProfile, plan, avoids);
+
+                    if (clusterList != null && !clusterList.isEmpty()) {
+                        // planner refactoring. call allocators to list hosts
+                        ExcludeList plannerAvoidOutput =
+                                new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(),
+                                        avoids.getPoolsToAvoid());
+
+                        resetAvoidSet(plannerAvoidOutput, plannerAvoidInput);
+
+                        dest =
+                                checkClustersforDestination(clusterList, vmProfile, plan, avoids, dc, getPlannerUsage(planner, vmProfile, plan, avoids), plannerAvoidOutput);
+                        if (dest != null) {
+                            return dest;
+                        }
+                        // reset the avoid input to the planners
+                        resetAvoidSet(avoids, plannerAvoidOutput);
+
+                    } else {
+                        return null;
+                    }
+                } else {
+                    dest = planner.plan(vmProfile, plan, avoids);
+                    if (dest != null) {
+                        long hostId = dest.getHost().getId();
+                        avoids.addHost(dest.getHost().getId());
+
+                        if (checkIfHostFitsPlannerUsage(hostId, DeploymentPlanner.PlannerResourceUsage.Shared)) {
+                            // found destination
+                            return dest;
+                        } else {
+                            // find another host - seems some concurrent
+                            // deployment picked it up for dedicated access
+                            continue;
+                        }
+                    } else {
+                        return null;
+                    }
+                }
+            }
+        }
+
+        return dest;
+    }
+
+    @Override
+    public DeploymentPlanner getDeploymentPlannerByName(String plannerName) {
+        if (plannerName != null) {
+            for (DeploymentPlanner plannerInList : _planners) {
+                if (plannerName.equalsIgnoreCase(plannerInList.getName())) {
+                    return plannerInList;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private void checkForNonDedicatedResources(VirtualMachineProfile vmProfile, DataCenter dc, ExcludeList avoids) {
+        boolean isExplicit = false;
+        VirtualMachine vm = vmProfile.getVirtualMachine();
+
+        // check if zone is dedicated. if yes check if vm owner has access to it.
+        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(dc.getId());
+        if (dedicatedZone != null && !_accountMgr.isRootAdmin(vmProfile.getOwner().getId())) {
+            long accountDomainId = vmProfile.getOwner().getDomainId();
+            long accountId = vmProfile.getOwner().getAccountId();
+
+            // If a zone is dedicated to an account then all hosts in this zone
+            // will be explicitly dedicated to
+            // that account. So there won't be any shared hosts in the zone, the
+            // only way to deploy vms from that
+            // account will be to use explicit dedication affinity group.
+            if (dedicatedZone.getAccountId() != null) {
+                if (dedicatedZone.getAccountId().equals(accountId)) {
+                    return;
+                } else {
+                    throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user account " + vmProfile.getOwner());
+                }
+            }
+
+            // if zone is dedicated to a domain. Check owner's access to the
+            // domain level dedication group
+            if (!_affinityGroupService.isAffinityGroupAvailableInDomain(dedicatedZone.getAffinityGroupId(), accountDomainId)) {
+                throw new CloudRuntimeException("Failed to deploy VM, Zone " + dc.getName() + " not available for the user domain " + vmProfile.getOwner());
+            }
+
+        }
+
+        // check affinity group of type Explicit dedication exists. If No put
+        // dedicated pod/cluster/host in avoid list
+        List<AffinityGroupVMMapVO> vmGroupMappings = _affinityGroupVMMapDao.findByVmIdType(vm.getId(), "ExplicitDedication");
+
+        if (vmGroupMappings != null && !vmGroupMappings.isEmpty()) {
+            isExplicit = true;
+        }
+
+        List<Long> allPodsInDc = _podDao.listAllPods(dc.getId());
+        List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
+        allPodsInDc.retainAll(allDedicatedPods);
+
+        List<Long> allClustersInDc = _clusterDao.listAllClusters(dc.getId());
+        List<Long> allDedicatedClusters = _dedicatedDao.listAllClusters();
+        allClustersInDc.retainAll(allDedicatedClusters);
+
+        List<Long> allHostsInDc = _hostDao.listAllHosts(dc.getId());
+        List<Long> allDedicatedHosts = _dedicatedDao.listAllHosts();
+        allHostsInDc.retainAll(allDedicatedHosts);
+
+        //Only when the type is instance VM and not explicitly dedicated.
+        if (vm.getType() == VirtualMachine.Type.User && !isExplicit) {
+            //add explicitly dedicated resources in avoidList
+
+            avoids.addPodList(allPodsInDc);
+            avoids.addClusterList(allClustersInDc);
+            avoids.addHostList(allHostsInDc);
+        }
+
+        //Handle the Virtual Router Case
+        //No need to check the isExplicit. As both the cases are handled.
+        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+            long vmAccountId = vm.getAccountId();
+            long vmDomainId = vm.getDomainId();
+
+            //Lists all explicitly dedicated resources from vm account ID or domain ID.
+            List<Long> allPodsFromDedicatedID = new ArrayList<Long>();
+            List<Long> allClustersFromDedicatedID = new ArrayList<Long>();
+            List<Long> allHostsFromDedicatedID = new ArrayList<Long>();
+
+            //Whether the dedicated resources belong to Domain or not. If not, it may belongs to Account or no dedication.
+            List<AffinityGroupDomainMapVO> domainGroupMappings = _affinityGroupDomainMapDao.listByDomain(vmDomainId);
+
+            //For temporary storage and indexing.
+            List<DedicatedResourceVO> tempStorage;
+
+            if (domainGroupMappings == null || domainGroupMappings.isEmpty()) {
+                //The dedicated resource belongs to VM Account ID.
+
+                tempStorage = _dedicatedDao.searchDedicatedPods(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allPodsFromDedicatedID.add(vo.getPodId());
+                }
+
+                tempStorage.clear();
+                tempStorage = _dedicatedDao.searchDedicatedClusters(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allClustersFromDedicatedID.add(vo.getClusterId());
+                }
+
+                tempStorage.clear();
+                tempStorage = _dedicatedDao.searchDedicatedHosts(null, vmDomainId, vmAccountId, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allHostsFromDedicatedID.add(vo.getHostId());
+                }
+
+                //Remove the dedicated ones from main list
+                allPodsInDc.removeAll(allPodsFromDedicatedID);
+                allClustersInDc.removeAll(allClustersFromDedicatedID);
+                allHostsInDc.removeAll(allHostsFromDedicatedID);
+            }
+            else {
+                //The dedicated resource belongs to VM Domain ID or No dedication.
+
+                tempStorage = _dedicatedDao.searchDedicatedPods(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allPodsFromDedicatedID.add(vo.getPodId());
+                }
+
+                tempStorage.clear();
+                tempStorage = _dedicatedDao.searchDedicatedClusters(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allClustersFromDedicatedID.add(vo.getClusterId());
+                }
+
+                tempStorage.clear();
+                tempStorage = _dedicatedDao.searchDedicatedHosts(null, vmDomainId, null, null, new Filter(DedicatedResourceVO.class, "id", true, 0L, 1L)).first();
+
+                for(DedicatedResourceVO vo : tempStorage) {
+                    allHostsFromDedicatedID.add(vo.getHostId());
+                }
+
+                //Remove the dedicated ones from main list
+                allPodsInDc.removeAll(allPodsFromDedicatedID);
+                allClustersInDc.removeAll(allClustersFromDedicatedID);
+                allHostsInDc.removeAll(allHostsFromDedicatedID);
+            }
+
+            //Add in avoid list or no addition if no dedication
+            avoids.addPodList(allPodsInDc);
+            avoids.addClusterList(allClustersInDc);
+            avoids.addHostList(allHostsInDc);
+        }
+    }
+
+    private void resetAvoidSet(ExcludeList avoidSet, ExcludeList removeSet) {
+        if (avoidSet.getDataCentersToAvoid() != null && removeSet.getDataCentersToAvoid() != null) {
+            avoidSet.getDataCentersToAvoid().removeAll(removeSet.getDataCentersToAvoid());
+        }
+        if (avoidSet.getPodsToAvoid() != null && removeSet.getPodsToAvoid() != null) {
+            avoidSet.getPodsToAvoid().removeAll(removeSet.getPodsToAvoid());
+        }
+        if (avoidSet.getClustersToAvoid() != null && removeSet.getClustersToAvoid() != null) {
+            avoidSet.getClustersToAvoid().removeAll(removeSet.getClustersToAvoid());
+        }
+        if (avoidSet.getHostsToAvoid() != null && removeSet.getHostsToAvoid() != null) {
+            avoidSet.getHostsToAvoid().removeAll(removeSet.getHostsToAvoid());
+        }
+        if (avoidSet.getPoolsToAvoid() != null && removeSet.getPoolsToAvoid() != null) {
+            avoidSet.getPoolsToAvoid().removeAll(removeSet.getPoolsToAvoid());
+        }
+    }
+
+    private PlannerResourceUsage getPlannerUsage(DeploymentPlanner planner, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids)
+            throws InsufficientServerCapacityException {
+        if (planner != null && planner instanceof DeploymentClusterPlanner) {
+            return ((DeploymentClusterPlanner)planner).getResourceUsage(vmProfile, plan, avoids);
+        } else {
+            return DeploymentPlanner.PlannerResourceUsage.Shared;
+        }
+
+    }
+
+    @DB
+    private boolean checkIfHostFitsPlannerUsage(final long hostId, final PlannerResourceUsage resourceUsageRequired) {
+        // TODO Auto-generated method stub
+        // check if this host has been picked up by some other planner
+        // exclusively
+        // if planner can work with shared host, check if this host has
+        // been marked as 'shared'
+        // else if planner needs dedicated host,
+
+        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+        if (reservationEntry != null) {
+            final long id = reservationEntry.getId();
+            PlannerResourceUsage hostResourceType = reservationEntry.getResourceUsage();
+
+            if (hostResourceType != null) {
+                if (hostResourceType == resourceUsageRequired) {
+                    return true;
+                } else {
+                    s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " +
+                            hostResourceType);
+                    return false;
+                }
+            } else {
+                final PlannerResourceUsage hostResourceTypeFinal = hostResourceType;
+                // reserve the host for required resourceType
+                // let us lock the reservation entry before updating.
+                return Transaction.execute(new TransactionCallback<Boolean>() {
+                    @Override
+                    public Boolean doInTransaction(TransactionStatus status) {
+                        final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
+                        if (lockedEntry == null) {
+                            s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
+                            return false;
+                        }
+                        // check before updating
+                        if (lockedEntry.getResourceUsage() == null) {
+                            lockedEntry.setResourceUsage(resourceUsageRequired);
+                            _plannerHostReserveDao.persist(lockedEntry);
+                            return true;
+                        } else {
+                            // someone updated it earlier. check if we can still use it
+                            if (lockedEntry.getResourceUsage() == resourceUsageRequired) {
+                                return true;
+                            } else {
+                                s_logger.debug("Cannot use this host for usage: " + resourceUsageRequired + ", since this host has been reserved for planner usage : " +
+                                        hostResourceTypeFinal);
+                                return false;
+                            }
+                        }
+                    }
+                });
+
+            }
+
+        }
+
+        return false;
+    }
+
+    @DB
+    public boolean checkHostReservationRelease(final Long hostId) {
+
+        if (hostId != null) {
+            PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+            if (reservationEntry != null && reservationEntry.getResourceUsage() != null) {
+
+                // check if any VMs are starting or running on this host
+                List<VMInstanceVO> vms = _vmInstanceDao.listUpByHostId(hostId);
+                if (vms.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs Running on host " + hostId);
+                    }
+                    return false;
+                }
+
+                List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
+                if (vmsByLastHostId.size() > 0) {
+                    // check if any VMs are within skip.counting.hours, if yes
+                    // we
+                    // cannot release the host
+                    for (VMInstanceVO stoppedVM : vmsByLastHostId) {
+                        long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
+                        if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Cannot release reservation, Found VM: " + stoppedVM + " Stopped but reserved on host " + hostId);
+                            }
+                            return false;
+                        }
+                    }
+                }
+
+                // check if any VMs are stopping on or migrating to this host
+                List<VMInstanceVO> vmsStoppingMigratingByHostId = _vmInstanceDao.findByHostInStates(hostId, State.Stopping, State.Migrating, State.Starting);
+                if (vmsStoppingMigratingByHostId.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vmsStoppingMigratingByHostId.size() + " VMs stopping/migrating/starting on host " + hostId);
+                    }
+                    return false;
+                }
+
+                // check if any VMs are in starting state with no hostId set yet
+                // -
+                // just ignore host release to avoid race condition
+                List<VMInstanceVO> vmsStartingNoHost = _vmInstanceDao.listStartingWithNoHostId();
+
+                if (vmsStartingNoHost.size() > 0) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot release reservation, Found " + vms.size() + " VMs starting as of now and no hostId yet stored");
+                    }
+                    return false;
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Host has no VMs associated, releasing the planner reservation for host " + hostId);
+                }
+
+                final long id = reservationEntry.getId();
+
+                return Transaction.execute(new TransactionCallback<Boolean>() {
+                    @Override
+                    public Boolean doInTransaction(TransactionStatus status) {
+                        final PlannerHostReservationVO lockedEntry = _plannerHostReserveDao.lockRow(id, true);
+                        if (lockedEntry == null) {
+                            s_logger.error("Unable to lock the host entry for reservation, host: " + hostId);
+                            return false;
+                        }
+                        // check before updating
+                        if (lockedEntry.getResourceUsage() != null) {
+                            lockedEntry.setResourceUsage(null);
+                            _plannerHostReserveDao.persist(lockedEntry);
+                            return true;
+                        }
+
+                        return false;
+                    }
+                });
+            }
+
+        }
+        return false;
+    }
+
+    class HostReservationReleaseChecker extends ManagedContextTimerTask {
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.debug("Checking if any host reservation can be released ... ");
+                checkHostReservations();
+                s_logger.debug("Done running HostReservationReleaseChecker ... ");
+            } catch (Throwable t) {
+                s_logger.error("Exception in HostReservationReleaseChecker", t);
+            }
+        }
+    }
+
+    private void checkHostReservations() {
+        List<PlannerHostReservationVO> reservedHosts = _plannerHostReserveDao.listAllReservedHosts();
+
+        for (PlannerHostReservationVO hostReservation : reservedHosts) {
+            HostVO host = _hostDao.findById(hostReservation.getHostId());
+            if (host != null && host.getManagementServerId() != null && host.getManagementServerId() == _nodeId) {
+                checkHostReservationRelease(hostReservation.getHostId());
+            }
+        }
+
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+        if (!(cmd instanceof StartupRoutingCommand)) {
+            return;
+        }
+
+        PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(host.getId());
+        if (reservationEntry == null) {
+            // record the host in this table
+            PlannerHostReservationVO newHost = new PlannerHostReservationVO(host.getId(), host.getDataCenterId(), host.getPodId(), host.getClusterId());
+            _plannerHostReserveDao.persist(newHost);
+        }
+
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void processHostAboutToBeRemoved(long hostId) {
+    }
+
+    @Override
+    public void processHostRemoved(long hostId, long clusterId) {
+    }
+
+    @Override
+    public boolean isRecurring() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _agentMgr.registerForHostEvents(this, true, false, true);
+        VirtualMachine.State.getStateMachine().registerListener(this);
+        _messageBus.subscribe("VM_ReservedCapacity_Free", new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                VMInstanceVO vm = ((VMInstanceVO)obj);
+                s_logger.debug("MessageBus message: host reserved capacity released for VM: " + vm.getLastHostId() +
+                        ", checking if host reservation can be released for host:" + vm.getLastHostId());
+                Long hostId = vm.getLastHostId();
+                checkHostReservationRelease(hostId);
+            }
+        });
+
+        _vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+
+        String hostReservationReleasePeriod = _configDao.getValue(Config.HostReservationReleasePeriod.key());
+        if (hostReservationReleasePeriod != null) {
+            _hostReservationReleasePeriod = Long.parseLong(hostReservationReleasePeriod);
+            if (_hostReservationReleasePeriod <= 0)
+                _hostReservationReleasePeriod = Long.parseLong(Config.HostReservationReleasePeriod.getDefaultValue());
+        }
+
+        _timer = new Timer("HostReservationReleaseChecker");
+
+        _nodeId = ManagementServerNode.getManagementServerId();
+
+        return super.configure(name, params);
+    }
+
+    @Override
+    public boolean start() {
+        _timer.schedule(new HostReservationReleaseChecker(), INITIAL_RESERVATION_RELEASE_CHECKER_DELAY, _hostReservationReleasePeriod);
+        cleanupVMReservations();
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _timer.cancel();
+        return true;
+    }
+
+    @Override
+    public void cleanupVMReservations() {
+        List<VMReservationVO> reservations = _reservationDao.listAll();
+
+        for (VMReservationVO reserv : reservations) {
+            VMInstanceVO vm = _vmInstanceDao.findById(reserv.getVmId());
+            if (vm != null) {
+                if (vm.getState() == State.Starting || (vm.getState() == State.Stopped && vm.getLastHostId() == null)) {
+                    continue;
+                } else {
+                    // delete reservation
+                    _reservationDao.remove(reserv.getId());
+                }
+            } else {
+                // delete reservation
+                _reservationDao.remove(reserv.getId());
+            }
+        }
+    }
+
+    // /refactoring planner methods
+    private DeployDestination checkClustersforDestination(List<Long> clusterList, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, DataCenter dc,
+            DeploymentPlanner.PlannerResourceUsage resourceUsageRequired, ExcludeList plannerAvoidOutput) {
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("ClusterId List to consider: " + clusterList);
+        }
+
+        for (Long clusterId : clusterList) {
+            ClusterVO clusterVO = _clusterDao.findById(clusterId);
+
+            if (clusterVO.getAllocationState() == Grouping.AllocationState.Disabled) {
+                s_logger.debug("Cannot deploy in disabled cluster " + clusterId + ", skipping this cluster");
+                avoid.addCluster(clusterVO.getId());
+            }
+
+            if (clusterVO.getHypervisorType() != vmProfile.getHypervisorType()) {
+                s_logger.debug("Cluster: " + clusterId + " has HyperVisorType that does not match the VM, skipping this cluster");
+                avoid.addCluster(clusterVO.getId());
+                continue;
+            }
+
+            s_logger.debug("Checking resources in Cluster: " + clusterId + " under Pod: " + clusterVO.getPodId());
+            // search for resources(hosts and storage) under this zone, pod,
+            // cluster.
+            DataCenterDeployment potentialPlan =
+                    new DataCenterDeployment(plan.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null, plan.getPoolId(), null, plan.getReservationContext());
+
+            Pod pod = _podDao.findById(clusterVO.getPodId());
+            if (pod.getAllocationState() == Grouping.AllocationState.Enabled ) {
+                // find suitable hosts under this cluster, need as many hosts as we
+                // get.
+                List<Host> suitableHosts = findSuitableHosts(vmProfile, potentialPlan, avoid, HostAllocator.RETURN_UPTO_ALL);
+                // if found suitable hosts in this cluster, find suitable storage
+                // pools for each volume of the VM
+                if (suitableHosts != null && !suitableHosts.isEmpty()) {
+                    if (vmProfile.getHypervisorType() == HypervisorType.BareMetal) {
+                        DeployDestination dest = new DeployDestination(dc, pod, clusterVO, suitableHosts.get(0));
+                        return dest;
+                    }
+
+                    Pair<Map<Volume, List<StoragePool>>, List<Volume>> result = findSuitablePoolsForVolumes(vmProfile, potentialPlan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
+                    Map<Volume, List<StoragePool>> suitableVolumeStoragePools = result.first();
+                    List<Volume> readyAndReusedVolumes = result.second();
+
+                    // choose the potential host and pool for the VM
+                    if (!suitableVolumeStoragePools.isEmpty()) {
+                        Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(suitableHosts, suitableVolumeStoragePools, avoid,
+                                resourceUsageRequired, readyAndReusedVolumes, plan.getPreferredHosts());
+
+                        if (potentialResources != null) {
+                            Host host = _hostDao.findById(potentialResources.first().getId());
+                            Map<Volume, StoragePool> storageVolMap = potentialResources.second();
+                            // remove the reused vol<->pool from destination, since
+                            // we don't have to prepare this volume.
+                            for (Volume vol : readyAndReusedVolumes) {
+                                storageVolMap.remove(vol);
+                            }
+                            DeployDestination dest = new DeployDestination(dc, pod, clusterVO, host, storageVolMap);
+                            s_logger.debug("Returning Deployment Destination: " + dest);
+                            return dest;
+                        }
+                    } else {
+                        s_logger.debug("No suitable storagePools found under this Cluster: " + clusterId);
+                    }
+                } else {
+                    s_logger.debug("No suitable hosts found under this Cluster: " + clusterId);
+                }
+            }
+            else {
+                s_logger.debug("The cluster is in a disabled pod : " + pod.getId());
+            }
+
+            if (canAvoidCluster(clusterVO, avoid, plannerAvoidOutput, vmProfile)) {
+                avoid.addCluster(clusterVO.getId());
+            }
+        }
+        s_logger.debug("Could not find suitable Deployment Destination for this VM under any clusters, returning. ");
+        return null;
+    }
+
+    private boolean canAvoidCluster(Cluster clusterVO, ExcludeList avoids, ExcludeList plannerAvoidOutput, VirtualMachineProfile vmProfile) {
+
+        ExcludeList allocatorAvoidOutput =
+                new ExcludeList(avoids.getDataCentersToAvoid(), avoids.getPodsToAvoid(), avoids.getClustersToAvoid(), avoids.getHostsToAvoid(), avoids.getPoolsToAvoid());
+
+        // remove any hosts/pools that the planners might have added
+        // to get the list of hosts/pools that Allocators flagged as 'avoid'
+
+        resetAvoidSet(allocatorAvoidOutput, plannerAvoidOutput);
+
+        // if all hosts or all pools in the cluster are in avoid set after this
+        // pass, then put the cluster in avoid set.
+        boolean avoidAllHosts = true;
+        boolean avoidAllPools = true;
+        boolean avoidAllLocalPools = true;
+        boolean avoidAllSharedPools = true;
+
+        List<HostVO> allhostsInCluster =
+                _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, clusterVO.getId(), clusterVO.getPodId(), clusterVO.getDataCenterId(), null);
+        for (HostVO host : allhostsInCluster) {
+            if (!allocatorAvoidOutput.shouldAvoid(host)) {
+                // there's some host in the cluster that is not yet in avoid set
+                avoidAllHosts = false;
+                break;
+            }
+        }
+
+        // all hosts in avoid set, avoid the cluster. Otherwise check the pools
+        if (avoidAllHosts) {
+            return true;
+        }
+
+        // Cluster can be put in avoid set in following scenarios:
+        // 1. If storage allocators haven't put any pools in avoid set means either no pools in cluster
+        // or pools not suitable for the allocators to handle or there is no
+        // linkage of any suitable host to any of the pools in cluster
+        // 2. If all 'shared' or 'local' pools are in avoid set
+        if  (allocatorAvoidOutput.getPoolsToAvoid() != null && !allocatorAvoidOutput.getPoolsToAvoid().isEmpty()) {
+
+            Pair<Boolean, Boolean> storageRequirements = findVMStorageRequirements(vmProfile);
+            boolean vmRequiresSharedStorage = storageRequirements.first();
+            boolean vmRequiresLocalStorege = storageRequirements.second();
+
+            if (vmRequiresSharedStorage) {
+                // check shared pools
+                List<StoragePoolVO> allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null);
+                for (StoragePoolVO pool : allPoolsInCluster) {
+                    if (!allocatorAvoidOutput.shouldAvoid(pool)) {
+                        // there's some pool in the cluster that is not yet in avoid set
+                        avoidAllSharedPools = false;
+                        break;
+                    }
+                }
+            }
+
+            if (vmRequiresLocalStorege) {
+                // check local pools
+                List<StoragePoolVO> allLocalPoolsInCluster =
+                        _storagePoolDao.findLocalStoragePoolsByTags(clusterVO.getDataCenterId(), clusterVO.getPodId(), clusterVO.getId(), null);
+                for (StoragePoolVO pool : allLocalPoolsInCluster) {
+                    if (!allocatorAvoidOutput.shouldAvoid(pool)) {
+                        // there's some pool in the cluster that is not yet
+                        // in avoid set
+                        avoidAllLocalPools = false;
+                        break;
+                    }
+                }
+            }
+
+            if (vmRequiresSharedStorage && vmRequiresLocalStorege) {
+                avoidAllPools = (avoidAllLocalPools || avoidAllSharedPools) ? true : false;
+            } else if (vmRequiresSharedStorage) {
+                avoidAllPools = avoidAllSharedPools;
+            } else if (vmRequiresLocalStorege) {
+                avoidAllPools = avoidAllLocalPools;
+            }
+        }
+
+        if (avoidAllHosts || avoidAllPools) {
+            return true;
+        }
+        return false;
+    }
+
+    private Pair<Boolean, Boolean> findVMStorageRequirements(VirtualMachineProfile vmProfile) {
+
+        boolean requiresShared = false, requiresLocal = false;
+
+        List<VolumeVO> volumesTobeCreated = _volsDao.findUsableVolumesForInstance(vmProfile.getId());
+
+        // for each volume find whether shared or local pool is required
+        for (VolumeVO toBeCreated : volumesTobeCreated) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
+
+            if (diskOffering != null) {
+                if (diskOffering.isUseLocalStorage()) {
+                    requiresLocal = true;
+                } else {
+                    requiresShared = true;
+                }
+            }
+        }
+
+        return new Pair<Boolean, Boolean>(requiresShared, requiresLocal);
+    }
+
+    protected Pair<Host, Map<Volume, StoragePool>> findPotentialDeploymentResources(List<Host> suitableHosts, Map<Volume, List<StoragePool>> suitableVolumeStoragePools,
+            ExcludeList avoid, DeploymentPlanner.PlannerResourceUsage resourceUsageRequired, List<Volume> readyAndReusedVolumes, List<Long> preferredHosts) {
+        s_logger.debug("Trying to find a potenial host and associated storage pools from the suitable host/pool lists for this VM");
+
+        boolean hostCanAccessPool = false;
+        boolean haveEnoughSpace = false;
+        boolean hostAffinityCheck = false;
+
+        if (readyAndReusedVolumes == null) {
+            readyAndReusedVolumes = new ArrayList<Volume>();
+        }
+        Map<Volume, StoragePool> storage = new HashMap<Volume, StoragePool>();
+        TreeSet<Volume> volumesOrderBySizeDesc = new TreeSet<Volume>(new Comparator<Volume>() {
+            @Override
+            public int compare(Volume v1, Volume v2) {
+                if (v1.getSize() < v2.getSize())
+                    return 1;
+                else
+                    return -1;
+            }
+        });
+        volumesOrderBySizeDesc.addAll(suitableVolumeStoragePools.keySet());
+        boolean multipleVolume = volumesOrderBySizeDesc.size() > 1;
+        for (Host potentialHost : suitableHosts) {
+            Map<StoragePool, List<Volume>> volumeAllocationMap = new HashMap<StoragePool, List<Volume>>();
+            for (Volume vol : volumesOrderBySizeDesc) {
+                haveEnoughSpace = false;
+                s_logger.debug("Checking if host: " + potentialHost.getId() + " can access any suitable storage pool for volume: " + vol.getVolumeType());
+                List<StoragePool> volumePoolList = suitableVolumeStoragePools.get(vol);
+                hostCanAccessPool = false;
+                hostAffinityCheck = checkAffinity(potentialHost, preferredHosts);
+                for (StoragePool potentialSPool : volumePoolList) {
+                    if (hostCanAccessSPool(potentialHost, potentialSPool)) {
+                        hostCanAccessPool = true;
+                        if (multipleVolume && !readyAndReusedVolumes.contains(vol)) {
+                            List<Volume> requestVolumes = null;
+                            if (volumeAllocationMap.containsKey(potentialSPool))
+                                requestVolumes = volumeAllocationMap.get(potentialSPool);
+                            else
+                                requestVolumes = new ArrayList<Volume>();
+                            requestVolumes.add(vol);
+
+                            if (!_storageMgr.storagePoolHasEnoughIops(requestVolumes, potentialSPool) ||
+                                !_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool, potentialHost.getClusterId()))
+                                continue;
+                            volumeAllocationMap.put(potentialSPool, requestVolumes);
+                        }
+                        storage.put(vol, potentialSPool);
+                        haveEnoughSpace = true;
+                        break;
+                    }
+                }
+                if (!hostCanAccessPool) {
+                    break;
+                }
+                if (!haveEnoughSpace) {
+                    s_logger.warn("insufficient capacity to allocate all volumes");
+                    break;
+                }
+                if (!hostAffinityCheck) {
+                    s_logger.debug("Host affinity check failed");
+                    break;
+                }
+            }
+            if (hostCanAccessPool && haveEnoughSpace && hostAffinityCheck && checkIfHostFitsPlannerUsage(potentialHost.getId(), resourceUsageRequired)) {
+                s_logger.debug("Found a potential host " + "id: " + potentialHost.getId() + " name: " + potentialHost.getName() +
+                        " and associated storage pools for this VM");
+                return new Pair<Host, Map<Volume, StoragePool>>(potentialHost, storage);
+            } else {
+                avoid.addHost(potentialHost.getId());
+            }
+        }
+        s_logger.debug("Could not find a potential host that has associated storage pools from the suitable host/pool lists for this VM");
+        return null;
+    }
+
+    /**
+     * True if:
+     * - Affinity is not enabled (preferred host is empty)
+     * - Affinity is enabled and potential host is on the preferred hosts list
+     *
+     * False if not
+     */
+    @DB
+    public boolean checkAffinity(Host potentialHost, List<Long> preferredHosts) {
+        boolean hostAffinityEnabled = CollectionUtils.isNotEmpty(preferredHosts);
+        boolean hostAffinityMatches = hostAffinityEnabled && preferredHosts.contains(potentialHost.getId());
+        return !hostAffinityEnabled || hostAffinityMatches;
+    }
+
+    protected boolean hostCanAccessSPool(Host host, StoragePool pool) {
+        boolean hostCanAccessSPool = false;
+
+        StoragePoolHostVO hostPoolLinkage = _poolHostDao.findByPoolHost(pool.getId(), host.getId());
+        if (hostPoolLinkage != null) {
+            hostCanAccessSPool = true;
+        }
+
+        s_logger.debug("Host: " + host.getId() + (hostCanAccessSPool ? " can" : " cannot") + " access pool: " + pool.getId());
+        return hostCanAccessSPool;
+    }
+
+    protected List<Host> findSuitableHosts(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+        List<Host> suitableHosts = new ArrayList<Host>();
+        for (HostAllocator allocator : _hostAllocators) {
+            suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, avoid, returnUpTo);
+            if (suitableHosts != null && !suitableHosts.isEmpty()) {
+                break;
+            }
+        }
+
+        if (suitableHosts.isEmpty()) {
+            s_logger.debug("No suitable hosts found");
+        }
+        return suitableHosts;
+    }
+
+    protected Pair<Map<Volume, List<StoragePool>>, List<Volume>> findSuitablePoolsForVolumes(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid,
+            int returnUpTo) {
+        List<VolumeVO> volumesTobeCreated = _volsDao.findUsableVolumesForInstance(vmProfile.getId());
+        Map<Volume, List<StoragePool>> suitableVolumeStoragePools = new HashMap<Volume, List<StoragePool>>();
+        List<Volume> readyAndReusedVolumes = new ArrayList<Volume>();
+
+        // There should be atleast the ROOT volume of the VM in usable state
+        if (volumesTobeCreated.isEmpty()) {
+            // OfflineVmwareMigration: find out what is wrong with the id of the vm we try to start
+            throw new CloudRuntimeException("Unable to create deployment, no usable volumes found for the VM: " + vmProfile.getId());
+        }
+
+        // don't allow to start vm that doesn't have a root volume
+        if (_volsDao.findByInstanceAndType(vmProfile.getId(), Volume.Type.ROOT).isEmpty()) {
+            throw new CloudRuntimeException("Unable to prepare volumes for vm as ROOT volume is missing");
+        }
+
+        // for each volume find list of suitable storage pools by calling the
+        // allocators
+        Set<Long> originalAvoidPoolSet = avoid.getPoolsToAvoid();
+        if (originalAvoidPoolSet == null) {
+            originalAvoidPoolSet = new HashSet<Long>();
+        }
+        Set<Long> poolsToAvoidOutput = new HashSet<Long>(originalAvoidPoolSet);
+
+        for (VolumeVO toBeCreated : volumesTobeCreated) {
+            s_logger.debug("Checking suitable pools for volume (Id, Type): (" + toBeCreated.getId() + "," + toBeCreated.getVolumeType().name() + ")");
+
+            // If the plan specifies a poolId, it means that this VM's ROOT
+            // volume is ready and the pool should be reused.
+            // In this case, also check if rest of the volumes are ready and can
+            // be reused.
+            if (plan.getPoolId() != null || (toBeCreated.getVolumeType() == Volume.Type.DATADISK && toBeCreated.getPoolId() != null && toBeCreated.getState() == Volume.State.Ready)) {
+                s_logger.debug("Volume has pool already allocated, checking if pool can be reused, poolId: " + toBeCreated.getPoolId());
+                List<StoragePool> suitablePools = new ArrayList<StoragePool>();
+                StoragePool pool = null;
+                if (toBeCreated.getPoolId() != null) {
+                    pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId());
+                } else {
+                    pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId());
+                }
+
+                if (!pool.isInMaintenance()) {
+                    if (!avoid.shouldAvoid(pool)) {
+                        long exstPoolDcId = pool.getDataCenterId();
+                        long exstPoolPodId = pool.getPodId() != null ? pool.getPodId() : -1;
+                        long exstPoolClusterId = pool.getClusterId() != null ? pool.getClusterId() : -1;
+                        boolean canReusePool = false;
+                        if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) {
+                            canReusePool = true;
+                        } else if (plan.getDataCenterId() == exstPoolDcId) {
+                            DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId());
+                            if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) {
+                                canReusePool = true;
+                            }
+                        } else {
+                            s_logger.debug("Pool of the volume does not fit the specified plan, need to reallocate a pool for this volume");
+                            canReusePool = false;
+                        }
+
+                        if (canReusePool) {
+                            s_logger.debug("Planner need not allocate a pool for this volume since its READY");
+                            suitablePools.add(pool);
+                            suitableVolumeStoragePools.put(toBeCreated, suitablePools);
+                            if (!(toBeCreated.getState() == Volume.State.Allocated || toBeCreated.getState() == Volume.State.Creating)) {
+                                readyAndReusedVolumes.add(toBeCreated);
+                            }
+                            continue;
+                        }
+                    } else {
+                        s_logger.debug("Pool of the volume is in avoid set, need to reallocate a pool for this volume");
+                    }
+                } else {
+                    s_logger.debug("Pool of the volume is in maintenance, need to reallocate a pool for this volume");
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("We need to allocate new storagepool for this volume");
+            }
+            if (!isRootAdmin(vmProfile)) {
+                if (!isEnabledForAllocation(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId())) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Cannot allocate new storagepool for this volume in this cluster, allocation state is disabled");
+                        s_logger.debug("Cannot deploy to this specified plan, allocation state is disabled, returning.");
+                    }
+                    // Cannot find suitable storage pools under this cluster for
+                    // this volume since allocation_state is disabled.
+                    // - remove any suitable pools found for other volumes.
+                    // All volumes should get suitable pools under this cluster;
+                    // else we cant use this cluster.
+                    suitableVolumeStoragePools.clear();
+                    break;
+                }
+            }
+
+            s_logger.debug("Calling StoragePoolAllocators to find suitable pools");
+
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
+
+            if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) {
+                diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray()));
+            }
+
+            DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
+            boolean useLocalStorage = false;
+            if (vmProfile.getType() != VirtualMachine.Type.User) {
+                DataCenterVO zone = _dcDao.findById(plan.getDataCenterId());
+                assert (zone != null) : "Invalid zone in deployment plan";
+                Boolean useLocalStorageForSystemVM = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(zone.getId());
+                if (useLocalStorageForSystemVM != null) {
+                    useLocalStorage = useLocalStorageForSystemVM.booleanValue();
+                    s_logger.debug("System VMs will use " + (useLocalStorage ? "local" : "shared") + " storage for zone id=" + plan.getDataCenterId());
+                }
+            } else {
+                useLocalStorage = diskOffering.isUseLocalStorage();
+
+                // TODO: this is a hacking fix for the problem of deploy
+                // ISO-based VM on local storage
+                // when deploying VM based on ISO, we have a service offering
+                // and an additional disk offering, use-local storage flag is
+                // actually
+                // saved in service offering, override the flag from service
+                // offering when it is a ROOT disk
+                if (!useLocalStorage && vmProfile.getServiceOffering().isUseLocalStorage()) {
+                    if (toBeCreated.getVolumeType() == Volume.Type.ROOT) {
+                        useLocalStorage = true;
+                    }
+                }
+            }
+            diskProfile.setUseLocalStorage(useLocalStorage);
+
+            boolean foundPotentialPools = false;
+            for (StoragePoolAllocator allocator : _storagePoolAllocators) {
+                final List<StoragePool> suitablePools = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, returnUpTo);
+                if (suitablePools != null && !suitablePools.isEmpty()) {
+                    suitableVolumeStoragePools.put(toBeCreated, suitablePools);
+                    foundPotentialPools = true;
+                    break;
+                }
+            }
+
+            if (avoid.getPoolsToAvoid() != null) {
+                poolsToAvoidOutput.addAll(avoid.getPoolsToAvoid());
+                avoid.getPoolsToAvoid().retainAll(originalAvoidPoolSet);
+            }
+
+            if (!foundPotentialPools) {
+                s_logger.debug("No suitable pools found for volume: " + toBeCreated + " under cluster: " + plan.getClusterId());
+                // No suitable storage pools found under this cluster for this
+                // volume. - remove any suitable pools found for other volumes.
+                // All volumes should get suitable pools under this cluster;
+                // else we cant use this cluster.
+                suitableVolumeStoragePools.clear();
+                break;
+            }
+        }
+
+        HashSet<Long> toRemove = new HashSet<Long>();
+        for (List<StoragePool> lsp : suitableVolumeStoragePools.values()) {
+            for (StoragePool sp : lsp) {
+                toRemove.add(sp.getId());
+            }
+        }
+        poolsToAvoidOutput.removeAll(toRemove);
+
+        if (avoid.getPoolsToAvoid() != null) {
+            avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput);
+        }
+
+        if (suitableVolumeStoragePools.isEmpty()) {
+            s_logger.debug("No suitable pools found");
+        }
+
+        return new Pair<Map<Volume, List<StoragePool>>, List<Volume>>(suitableVolumeStoragePools, readyAndReusedVolumes);
+    }
+
+    private boolean isEnabledForAllocation(long zoneId, Long podId, Long clusterId) {
+        // Check if the zone exists in the system
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone != null && Grouping.AllocationState.Disabled == zone.getAllocationState()) {
+            s_logger.info("Zone is currently disabled, cannot allocate to this zone: " + zoneId);
+            return false;
+        }
+
+        Pod pod = _podDao.findById(podId);
+        if (pod != null && Grouping.AllocationState.Disabled == pod.getAllocationState()) {
+            s_logger.info("Pod is currently disabled, cannot allocate to this pod: " + podId);
+            return false;
+        }
+
+        Cluster cluster = _clusterDao.findById(clusterId);
+        if (cluster != null && Grouping.AllocationState.Disabled == cluster.getAllocationState()) {
+            s_logger.info("Cluster is currently disabled, cannot allocate to this cluster: " + clusterId);
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isRootAdmin(VirtualMachineProfile vmProfile) {
+        if (vmProfile != null) {
+            if (vmProfile.getOwner() != null) {
+                return _accountMgr.isRootAdmin(vmProfile.getOwner().getId());
+            } else {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    @DB
+    @Override
+    public String finalizeReservation(final DeployDestination plannedDestination, final VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoids, final DeploymentPlanner planner)
+            throws InsufficientServerCapacityException, AffinityConflictException {
+
+        final VirtualMachine vm = vmProfile.getVirtualMachine();
+        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
+
+        return Transaction.execute(new TransactionCallback<String>() {
+            @Override
+            public String doInTransaction(TransactionStatus status) {
+                boolean saveReservation = true;
+
+                if (vmGroupCount > 0) {
+                    List<Long> groupIds = _affinityGroupVMMapDao.listAffinityGroupIdsByVmId(vm.getId());
+                    SearchCriteria<AffinityGroupVO> criteria = _affinityGroupDao.createSearchCriteria();
+                    criteria.addAnd("id", SearchCriteria.Op.IN, groupIds.toArray(new Object[groupIds.size()]));
+                    _affinityGroupDao.lockRows(criteria, null, true);
+
+                    for (AffinityGroupProcessor processor : _affinityProcessors) {
+                        if (!processor.check(vmProfile, plannedDestination)) {
+                            saveReservation = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (saveReservation) {
+                    VMReservationVO vmReservation =
+                            new VMReservationVO(vm.getId(), plannedDestination.getDataCenter().getId(), plannedDestination.getPod().getId(), plannedDestination.getCluster()
+                                    .getId(), plannedDestination.getHost().getId());
+                    if (planner != null) {
+                        vmReservation.setDeploymentPlanner(planner.getName());
+                    }
+                    Map<Long, Long> volumeReservationMap = new HashMap<Long, Long>();
+
+                    if (vm.getHypervisorType() != HypervisorType.BareMetal) {
+                        for (Volume vo : plannedDestination.getStorageForDisks().keySet()) {
+                            volumeReservationMap.put(vo.getId(), plannedDestination.getStorageForDisks().get(vo).getId());
+                        }
+                        vmReservation.setVolumeReservation(volumeReservationMap);
+                    }
+                    _reservationDao.persist(vmReservation);
+                    return vmReservation.getUuid();
+                }
+
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      if ((oldState == State.Starting) && (newState != State.Starting)) {
+        // cleanup all VM reservation entries
+        SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
+        sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
+        _reservationDao.expunge(sc);
+      }
+      return true;
+    }
+}
diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/main/java/com/cloud/deploy/FirstFitPlanner.java
similarity index 100%
rename from server/src/com/cloud/deploy/FirstFitPlanner.java
rename to server/src/main/java/com/cloud/deploy/FirstFitPlanner.java
diff --git a/server/src/com/cloud/deploy/PlannerHostReservationVO.java b/server/src/main/java/com/cloud/deploy/PlannerHostReservationVO.java
similarity index 100%
rename from server/src/com/cloud/deploy/PlannerHostReservationVO.java
rename to server/src/main/java/com/cloud/deploy/PlannerHostReservationVO.java
diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java b/server/src/main/java/com/cloud/deploy/dao/PlannerHostReservationDao.java
similarity index 100%
rename from server/src/com/cloud/deploy/dao/PlannerHostReservationDao.java
rename to server/src/main/java/com/cloud/deploy/dao/PlannerHostReservationDao.java
diff --git a/server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java b/server/src/main/java/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
rename to server/src/main/java/com/cloud/deploy/dao/PlannerHostReservationDaoImpl.java
diff --git a/server/src/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java
similarity index 100%
rename from server/src/com/cloud/event/ActionEventInterceptor.java
rename to server/src/main/java/com/cloud/event/ActionEventInterceptor.java
diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/main/java/com/cloud/event/ActionEventUtils.java
similarity index 100%
rename from server/src/com/cloud/event/ActionEventUtils.java
rename to server/src/main/java/com/cloud/event/ActionEventUtils.java
diff --git a/server/src/com/cloud/event/AlertGenerator.java b/server/src/main/java/com/cloud/event/AlertGenerator.java
similarity index 100%
rename from server/src/com/cloud/event/AlertGenerator.java
rename to server/src/main/java/com/cloud/event/AlertGenerator.java
diff --git a/server/src/com/cloud/event/dao/EventJoinDao.java b/server/src/main/java/com/cloud/event/dao/EventJoinDao.java
similarity index 100%
rename from server/src/com/cloud/event/dao/EventJoinDao.java
rename to server/src/main/java/com/cloud/event/dao/EventJoinDao.java
diff --git a/server/src/com/cloud/event/dao/EventJoinDaoImpl.java b/server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/event/dao/EventJoinDaoImpl.java
rename to server/src/main/java/com/cloud/event/dao/EventJoinDaoImpl.java
diff --git a/server/src/com/cloud/ha/AbstractInvestigatorImpl.java b/server/src/main/java/com/cloud/ha/AbstractInvestigatorImpl.java
similarity index 100%
rename from server/src/com/cloud/ha/AbstractInvestigatorImpl.java
rename to server/src/main/java/com/cloud/ha/AbstractInvestigatorImpl.java
diff --git a/server/src/com/cloud/ha/CheckOnAgentInvestigator.java b/server/src/main/java/com/cloud/ha/CheckOnAgentInvestigator.java
similarity index 100%
rename from server/src/com/cloud/ha/CheckOnAgentInvestigator.java
rename to server/src/main/java/com/cloud/ha/CheckOnAgentInvestigator.java
diff --git a/server/src/com/cloud/ha/HaWorkVO.java b/server/src/main/java/com/cloud/ha/HaWorkVO.java
similarity index 100%
rename from server/src/com/cloud/ha/HaWorkVO.java
rename to server/src/main/java/com/cloud/ha/HaWorkVO.java
diff --git a/server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java b/server/src/main/java/com/cloud/ha/HighAvailabilityManagerExtImpl.java
similarity index 100%
rename from server/src/com/cloud/ha/HighAvailabilityManagerExtImpl.java
rename to server/src/main/java/com/cloud/ha/HighAvailabilityManagerExtImpl.java
diff --git a/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java b/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java
new file mode 100644
index 0000000..49211f5
--- /dev/null
+++ b/server/src/main/java/com/cloud/ha/HighAvailabilityManagerImpl.java
@@ -0,0 +1,1007 @@
+// 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.ha;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContext;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.alert.AlertManager;
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.HAPlanner;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.ha.Investigator.UnknownVM;
+import com.cloud.ha.dao.HighAvailabilityDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ManagementServer;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * HighAvailabilityManagerImpl coordinates the HA process. VMs are registered with the HA Manager for HA. The request is stored
+ * within a database backed work queue. HAManager has a number of workers that pick up these work items to perform HA on the
+ * VMs.
+ *
+ * The HA process goes as follows: 1. Check with the list of Investigators to determine that the VM is no longer running. If a
+ * Investigator finds the VM is still alive, the HA process is stopped and the state of the VM reverts back to its previous
+ * state. If a Investigator finds the VM is dead, then HA process is started on the VM, skipping step 2. 2. If the list of
+ * Investigators can not determine if the VM is dead or alive. The list of FenceBuilders is invoked to fence off the VM so that
+ * it won't do any damage to the storage and network. 3. The VM is marked as stopped. 4. The VM is started again via the normal
+ * process of starting VMs. Note that once the VM is marked as stopped, the user may have started the VM himself. 5. VMs that
+ * have re-started more than the configured number of times are marked as in Error state and the user is not allowed to restart
+ * the VM.
+ *
+ * @config {@table || Param Name | Description | Values | Default || || workers | number of worker threads to spin off to do the
+ *         processing | int | 1 || || time.to.sleep | Time to sleep if no work items are found | seconds | 60 || || max.retries
+ *         | number of times to retry start | int | 5 || || time.between.failure | Time elapsed between failures before we
+ *         consider it as another retry | seconds | 3600 || || time.between.cleanup | Time to wait before the cleanup thread
+ *         runs | seconds | 86400 || || force.ha | Force HA to happen even if the VM says no | boolean | false || ||
+ *         ha.retry.wait | time to wait before retrying the work item | seconds | 120 || || stop.retry.wait | time to wait
+ *         before retrying the stop | seconds | 120 || * }
+ **/
+public class HighAvailabilityManagerImpl extends ManagerBase implements HighAvailabilityManager, ClusterManagerListener {
+
+    protected static final Logger s_logger = Logger.getLogger(HighAvailabilityManagerImpl.class);
+    WorkerThread[] _workers;
+    boolean _stopped;
+    long _timeToSleep;
+    @Inject
+    HighAvailabilityDao _haDao;
+    @Inject
+    VMInstanceDao _instanceDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    HostPodDao _podDao;
+    @Inject
+    ClusterDetailsDao _clusterDetailsDao;
+
+    @Inject
+    ServiceOfferingDao _serviceOfferingDao;
+
+    long _serverId;
+
+    @Inject
+    ManagedContext _managedContext;
+
+    List<Investigator> investigators;
+
+    public List<Investigator> getInvestigators() {
+        return investigators;
+    }
+
+    public void setInvestigators(List<Investigator> investigators) {
+        this.investigators = investigators;
+    }
+
+    List<FenceBuilder> fenceBuilders;
+
+    public List<FenceBuilder> getFenceBuilders() {
+        return fenceBuilders;
+    }
+
+    public void setFenceBuilders(List<FenceBuilder> fenceBuilders) {
+        this.fenceBuilders = fenceBuilders;
+    }
+
+    List<HAPlanner> _haPlanners;
+    public List<HAPlanner> getHaPlanners() {
+        return _haPlanners;
+    }
+
+    public void setHaPlanners(List<HAPlanner> haPlanners) {
+        _haPlanners = haPlanners;
+    }
+
+
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    StorageManager _storageMgr;
+    @Inject
+    GuestOSDao _guestOSDao;
+    @Inject
+    GuestOSCategoryDao _guestOSCategoryDao;
+    @Inject
+    VirtualMachineManager _itMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    ManagementServer _msServer;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    VolumeOrchestrationService volumeMgr;
+
+    String _instance;
+    ScheduledExecutorService _executor;
+    int _stopRetryInterval;
+    int _investigateRetryInterval;
+    int _migrateRetryInterval;
+    int _restartRetryInterval;
+
+    int _maxRetries;
+    long _timeBetweenFailures;
+    long _timeBetweenCleanups;
+    boolean _forceHA;
+    String _haTag = null;
+
+    protected HighAvailabilityManagerImpl() {
+    }
+
+    @Override
+    public Status investigate(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            return Status.Alert;
+        }
+
+        Status hostState = null;
+        for (Investigator investigator : investigators) {
+            hostState = investigator.isAgentAlive(host);
+            if (hostState != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(investigator.getName() + " was able to determine host " + hostId + " is in " + hostState.toString());
+                }
+                return hostState;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(investigator.getName() + " unable to determine the state of the host.  Moving on.");
+            }
+        }
+
+        return hostState;
+    }
+
+    @Override
+    public void scheduleRestartForVmsOnHost(final HostVO host, boolean investigate) {
+
+        if (host.getType() != Host.Type.Routing) {
+            return;
+        }
+
+        if (host.getHypervisorType() == HypervisorType.VMware || host.getHypervisorType() == HypervisorType.Hyperv) {
+            s_logger.info("Don't restart VMs on host " + host.getId() + " as it is a " + host.getHypervisorType().toString() + " host");
+            return;
+        }
+
+        s_logger.warn("Scheduling restart for VMs on host " + host.getId() + "-" + host.getName());
+
+        final List<VMInstanceVO> vms = _instanceDao.listByHostId(host.getId());
+        final DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+
+        // send an email alert that the host is down
+        StringBuilder sb = null;
+        List<VMInstanceVO> reorderedVMList = new ArrayList<VMInstanceVO>();
+        if ((vms != null) && !vms.isEmpty()) {
+            sb = new StringBuilder();
+            sb.append("  Starting HA on the following VMs:");
+            // collect list of vm names for the alert email
+            for (int i = 0; i < vms.size(); i++) {
+                VMInstanceVO vm = vms.get(i);
+                if (vm.getType() == VirtualMachine.Type.User) {
+                    reorderedVMList.add(vm);
+                } else {
+                    reorderedVMList.add(0, vm);
+                }
+                if (vm.isHaEnabled()) {
+                    sb.append(" " + vm.getHostName());
+                }
+            }
+        }
+
+        // send an email alert that the host is down, include VMs
+        HostPodVO podVO = _podDao.findById(host.getPodId());
+        String hostDesc = "name: " + host.getName() + " (id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Host is down, " + hostDesc,
+                "Host [" + hostDesc + "] is down." + ((sb != null) ? sb.toString() : ""));
+
+        for (VMInstanceVO vm : reorderedVMList) {
+            ServiceOfferingVO vmOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
+            if (vmOffering.isUseLocalStorage()) {
+                if (s_logger.isDebugEnabled()){
+                    s_logger.debug("Skipping HA on vm " + vm + ", because it uses local storage. Its fate is tied to the host.");
+                }
+                continue;
+            }
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Notifying HA Mgr of to restart vm " + vm.getId() + "-" + vm.getInstanceName());
+            }
+            vm = _instanceDao.findByUuid(vm.getUuid());
+            Long hostId = vm.getHostId();
+            if (hostId != null && !hostId.equals(host.getId())) {
+                s_logger.debug("VM " + vm.getInstanceName() + " is not on down host " + host.getId() + " it is on other host "
+                        + hostId + " VM HA is done");
+                continue;
+            }
+            scheduleRestart(vm, investigate);
+        }
+    }
+
+    @Override
+    public void scheduleStop(VMInstanceVO vm, long hostId, WorkType type) {
+        assert (type == WorkType.CheckStop || type == WorkType.ForceStop || type == WorkType.Stop);
+
+        if (_haDao.hasBeenScheduled(vm.getId(), type)) {
+            s_logger.info("There's already a job scheduled to stop " + vm);
+            return;
+        }
+
+        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), type, Step.Scheduled, hostId, vm.getState(), 0, vm.getUpdated());
+        _haDao.persist(work);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Scheduled " + work);
+        }
+        wakeupWorkers();
+    }
+
+    protected void wakeupWorkers() {
+        for (WorkerThread worker : _workers) {
+            worker.wakup();
+        }
+    }
+
+    @Override
+    public boolean scheduleMigration(final VMInstanceVO vm) {
+        if (vm.getHostId() != null) {
+            final HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.Migration, Step.Scheduled, vm.getHostId(), vm.getState(), 0, vm.getUpdated());
+            _haDao.persist(work);
+            wakeupWorkers();
+        }
+        return true;
+    }
+
+    @Override
+    public void scheduleRestart(VMInstanceVO vm, boolean investigate) {
+        Long hostId = vm.getHostId();
+        if (hostId == null) {
+            try {
+                s_logger.debug("Found a vm that is scheduled to be restarted but has no host id: " + vm);
+                _itMgr.advanceStop(vm.getUuid(), true);
+            } catch (ResourceUnavailableException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            } catch (OperationTimedoutException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            } catch (ConcurrentOperationException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            }
+        }
+
+        if (vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.Hyperv) {
+            s_logger.info("Skip HA for VMware VM or Hyperv VM" + vm.getInstanceName());
+            return;
+        }
+
+        if (!investigate) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM does not require investigation so I'm marking it as Stopped: " + vm.toString());
+            }
+
+            AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM;
+            if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
+                alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER;
+            } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
+                alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY;
+            } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) {
+                alertType = AlertManager.AlertType.ALERT_TYPE_SSVM;
+            }
+
+            if (!(_forceHA || vm.isHaEnabled())) {
+                String hostDesc = "id:" + vm.getHostId() + ", availability zone id:" + vm.getDataCenterId() + ", pod id:" + vm.getPodIdToDeployIn();
+                _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "VM (name: " + vm.getHostName() + ", id: " + vm.getId() +
+                    ") stopped unexpectedly on host " + hostDesc, "Virtual Machine " + vm.getHostName() + " (id: " + vm.getId() + ") running on host [" + vm.getHostId() +
+                    "] stopped unexpectedly.");
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("VM is not HA enabled so we're done.");
+                }
+            }
+
+            try {
+                _itMgr.advanceStop(vm.getUuid(), true);
+                vm = _instanceDao.findByUuid(vm.getUuid());
+            } catch (ResourceUnavailableException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            } catch (OperationTimedoutException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            } catch (ConcurrentOperationException e) {
+                assert false : "How do we hit this when force is true?";
+                throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+            }
+        }
+
+        if (vm.getHypervisorType() == HypervisorType.VMware) {
+            s_logger.info("Skip HA for VMware VM " + vm.getInstanceName());
+            return;
+        }
+
+        List<HaWorkVO> items = _haDao.findPreviousHA(vm.getId());
+        int timesTried = 0;
+        for (HaWorkVO item : items) {
+            if (timesTried < item.getTimesTried() && !item.canScheduleNew(_timeBetweenFailures)) {
+                timesTried = item.getTimesTried();
+                break;
+            }
+        }
+
+        if (hostId == null) {
+            hostId = vm.getLastHostId();
+        }
+
+        HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.HA, investigate ? Step.Investigating : Step.Scheduled,
+                hostId != null ? hostId : 0L, vm.getState(), timesTried, vm.getUpdated());
+        _haDao.persist(work);
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Schedule vm for HA:  " + vm);
+        }
+
+        wakeupWorkers();
+
+    }
+
+    protected Long restart(final HaWorkVO work) {
+        List<HaWorkVO> items = _haDao.listFutureHaWorkForVm(work.getInstanceId(), work.getId());
+        if (items.size() > 0) {
+            StringBuilder str = new StringBuilder("Cancelling this work item because newer ones have been scheduled.  Work Ids = [");
+            for (HaWorkVO item : items) {
+                str.append(item.getId()).append(", ");
+            }
+            str.delete(str.length() - 2, str.length()).append("]");
+            s_logger.info(str.toString());
+            return null;
+        }
+
+        items = _haDao.listRunningHaWorkForVm(work.getInstanceId());
+        if (items.size() > 0) {
+            StringBuilder str = new StringBuilder("Waiting because there's HA work being executed on an item currently.  Work Ids =[");
+            for (HaWorkVO item : items) {
+                str.append(item.getId()).append(", ");
+            }
+            str.delete(str.length() - 2, str.length()).append("]");
+            s_logger.info(str.toString());
+            return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
+        }
+
+        long vmId = work.getInstanceId();
+
+        VirtualMachine vm = _itMgr.findById(work.getInstanceId());
+        if (vm == null) {
+            s_logger.info("Unable to find vm: " + vmId);
+            return null;
+        }
+
+        s_logger.info("HA on " + vm);
+        if (vm.getState() != work.getPreviousState() || vm.getUpdated() != work.getUpdateTime()) {
+            s_logger.info("VM " + vm + " has been changed.  Current State = " + vm.getState() + " Previous State = " + work.getPreviousState() + " last updated = " +
+                vm.getUpdated() + " previous updated = " + work.getUpdateTime());
+            return null;
+        }
+
+        AlertManager.AlertType alertType = AlertManager.AlertType.ALERT_TYPE_USERVM;
+        if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER;
+        } else if (VirtualMachine.Type.ConsoleProxy.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY;
+        } else if (VirtualMachine.Type.SecondaryStorageVm.equals(vm.getType())) {
+            alertType = AlertManager.AlertType.ALERT_TYPE_SSVM;
+        }
+
+        HostVO host = _hostDao.findById(work.getHostId());
+        boolean isHostRemoved = false;
+        if (host == null) {
+            host = _hostDao.findByIdIncludingRemoved(work.getHostId());
+            if (host != null) {
+                s_logger.debug("VM " + vm.toString() + " is now no longer on host " + work.getHostId() + " as the host is removed");
+                isHostRemoved = true;
+            }
+        }
+
+        DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());
+        HostPodVO podVO = _podDao.findById(host.getPodId());
+        String hostDesc = "name: " + host.getName() + "(id:" + host.getId() + "), availability zone: " + dcVO.getName() + ", pod: " + podVO.getName();
+
+        Boolean alive = null;
+        if (work.getStep() == Step.Investigating) {
+            if (!isHostRemoved) {
+                if (vm.getHostId() == null || vm.getHostId() != work.getHostId()) {
+                    s_logger.info("VM " + vm.toString() + " is now no longer on host " + work.getHostId());
+                    return null;
+                }
+
+                Investigator investigator = null;
+                for (Investigator it : investigators) {
+                    investigator = it;
+                    try
+                    {
+                        alive = investigator.isVmAlive(vm, host);
+                        s_logger.info(investigator.getName() + " found " + vm + " to be alive? " + alive);
+                        break;
+                    } catch (UnknownVM e) {
+                        s_logger.info(investigator.getName() + " could not find " + vm);
+                    }
+                }
+
+                boolean fenced = false;
+                if (alive == null) {
+                    s_logger.debug("Fencing off VM that we don't know the state of");
+                    for (FenceBuilder fb : fenceBuilders) {
+                        Boolean result = fb.fenceOff(vm, host);
+                        s_logger.info("Fencer " + fb.getName() + " returned " + result);
+                        if (result != null && result) {
+                            fenced = true;
+                            break;
+                        }
+                    }
+
+                } else if (!alive) {
+                    fenced = true;
+                } else {
+                    s_logger.debug("VM " + vm.getInstanceName() + " is found to be alive by " + investigator.getName());
+                    if (host.getStatus() == Status.Up) {
+                        s_logger.info(vm + " is alive and host is up. No need to restart it.");
+                        return null;
+                    } else {
+                        s_logger.debug("Rescheduling because the host is not up but the vm is alive");
+                        return (System.currentTimeMillis() >> 10) + _investigateRetryInterval;
+                    }
+                }
+
+                if (!fenced) {
+                    s_logger.debug("We were unable to fence off the VM " + vm);
+                    _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() +
+                        " which was running on host " + hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId +
+                        " which was running on host " + hostDesc);
+                    return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
+                }
+
+                try {
+                    _itMgr.advanceStop(vm.getUuid(), true);
+                } catch (ResourceUnavailableException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                } catch (OperationTimedoutException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                } catch (ConcurrentOperationException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                }
+
+                work.setStep(Step.Scheduled);
+                _haDao.update(work.getId(), work);
+            } else {
+                s_logger.debug("How come that HA step is Investigating and the host is removed? Calling forced Stop on Vm anyways");
+                try {
+                    _itMgr.advanceStop(vm.getUuid(), true);
+                } catch (ResourceUnavailableException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                } catch (OperationTimedoutException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                } catch (ConcurrentOperationException e) {
+                    assert false : "How do we hit this when force is true?";
+                    throw new CloudRuntimeException("Caught exception even though it should be handled.", e);
+                }
+            }
+        }
+
+        vm = _itMgr.findById(vm.getId());
+
+        if (!_forceHA && !vm.isHaEnabled()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not HA enabled so we're done.");
+            }
+            return null; // VM doesn't require HA
+        }
+
+        if ((host == null || host.getRemoved() != null || host.getState() != Status.Up)
+                 && !volumeMgr.canVmRestartOnAnotherServer(vm.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM can not restart on another server.");
+            }
+            return null;
+        }
+
+        try {
+            HashMap<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
+            if (_haTag != null) {
+                params.put(VirtualMachineProfile.Param.HaTag, _haTag);
+            }
+            WorkType wt = work.getWorkType();
+            if (wt.equals(WorkType.HA)) {
+                params.put(VirtualMachineProfile.Param.HaOperation, true);
+            }
+
+            try{
+                // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
+                _itMgr.advanceStart(vm.getUuid(), params, null);
+            }catch (InsufficientCapacityException e){
+                s_logger.warn("Failed to deploy vm " + vmId + " with original planner, sending HAPlanner");
+                _itMgr.advanceStart(vm.getUuid(), params, _haPlanners.get(0));
+            }
+
+            VMInstanceVO started = _instanceDao.findById(vm.getId());
+            if (started != null && started.getState() == VirtualMachine.State.Running) {
+                s_logger.info("VM is now restarted: " + vmId + " on " + started.getHostId());
+                return null;
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Rescheduling VM " + vm.toString() + " to try again in " + _restartRetryInterval);
+            }
+        } catch (final InsufficientCapacityException e) {
+            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
+                hostDesc, "Insufficient capacity to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+        } catch (final ResourceUnavailableException e) {
+            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
+                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+        } catch (ConcurrentOperationException e) {
+            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
+                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+        } catch (OperationTimedoutException e) {
+            s_logger.warn("Unable to restart " + vm.toString() + " due to " + e.getMessage());
+            _alertMgr.sendAlert(alertType, vm.getDataCenterId(), vm.getPodIdToDeployIn(), "Unable to restart " + vm.getHostName() + " which was running on host " +
+                hostDesc, "The Storage is unavailable for trying to restart VM, name: " + vm.getHostName() + ", id: " + vmId + " which was running on host " + hostDesc);
+        }
+        vm = _itMgr.findById(vm.getId());
+        work.setUpdateTime(vm.getUpdated());
+        work.setPreviousState(vm.getState());
+        return (System.currentTimeMillis() >> 10) + _restartRetryInterval;
+    }
+
+    public Long migrate(final HaWorkVO work) {
+        long vmId = work.getInstanceId();
+
+        long srcHostId = work.getHostId();
+        try {
+            work.setStep(Step.Migrating);
+            _haDao.update(work.getId(), work);
+
+            VMInstanceVO vm = _instanceDao.findById(vmId);
+            if (vm == null) {
+                return null;
+            }
+            // First try starting the vm with its original planner, if it doesn't succeed send HAPlanner as its an emergency.
+            _itMgr.migrateAway(vm.getUuid(), srcHostId);
+            return null;
+        } catch (InsufficientServerCapacityException e) {
+            s_logger.warn("Insufficient capacity for migrating a VM.");
+            _resourceMgr.maintenanceFailed(srcHostId);
+            return (System.currentTimeMillis() >> 10) + _migrateRetryInterval;
+        }
+    }
+
+    @Override
+    public void scheduleDestroy(VMInstanceVO vm, long hostId) {
+        final HaWorkVO work = new HaWorkVO(vm.getId(), vm.getType(), WorkType.Destroy, Step.Scheduled, hostId, vm.getState(), 0, vm.getUpdated());
+        _haDao.persist(work);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Scheduled " + work.toString());
+        }
+        wakeupWorkers();
+    }
+
+    @Override
+    public void cancelDestroy(VMInstanceVO vm, Long hostId) {
+        _haDao.delete(vm.getId(), WorkType.Destroy);
+    }
+
+    protected Long destroyVM(final HaWorkVO work) {
+        final VirtualMachine vm = _itMgr.findById(work.getInstanceId());
+        s_logger.info("Destroying " + vm.toString());
+        try {
+            if (vm.getState() != State.Destroyed) {
+                s_logger.info("VM is no longer in Destroyed state " + vm.toString());
+                return null;
+            }
+
+            if (vm.getHostId() != null) {
+                _itMgr.destroy(vm.getUuid(), false);
+                s_logger.info("Successfully destroy " + vm);
+                return null;
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(vm + " has already been stopped");
+                }
+                return null;
+            }
+        } catch (final AgentUnavailableException e) {
+            s_logger.debug("Agnet is not available" + e.getMessage());
+        } catch (OperationTimedoutException e) {
+            s_logger.debug("operation timed out: " + e.getMessage());
+        } catch (ConcurrentOperationException e) {
+            s_logger.debug("concurrent operation: " + e.getMessage());
+        }
+
+        return (System.currentTimeMillis() >> 10) + _stopRetryInterval;
+    }
+
+    protected Long stopVM(final HaWorkVO work) throws ConcurrentOperationException {
+        VirtualMachine vm = _itMgr.findById(work.getInstanceId());
+        if (vm == null) {
+            s_logger.info("No longer can find VM " + work.getInstanceId() + ". Throwing away " + work);
+            work.setStep(Step.Done);
+            return null;
+        }
+        s_logger.info("Stopping " + vm);
+        try {
+            if (work.getWorkType() == WorkType.Stop) {
+                _itMgr.advanceStop(vm.getUuid(), false);
+                s_logger.info("Successfully stopped " + vm);
+                return null;
+            } else if (work.getWorkType() == WorkType.CheckStop) {
+                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null ||
+                    vm.getHostId().longValue() != work.getHostId()) {
+                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " +
+                        (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
+                    return null;
+                }
+
+                _itMgr.advanceStop(vm.getUuid(), false);
+                s_logger.info("Stop for " + vm + " was successful");
+                return null;
+            } else if (work.getWorkType() == WorkType.ForceStop) {
+                if ((vm.getState() != work.getPreviousState()) || vm.getUpdated() != work.getUpdateTime() || vm.getHostId() == null ||
+                    vm.getHostId().longValue() != work.getHostId()) {
+                    s_logger.info(vm + " is different now.  Scheduled Host: " + work.getHostId() + " Current Host: " +
+                        (vm.getHostId() != null ? vm.getHostId() : "none") + " State: " + vm.getState());
+                    return null;
+                }
+
+                _itMgr.advanceStop(vm.getUuid(), true);
+                s_logger.info("Stop for " + vm + " was successful");
+                return null;
+            } else {
+                assert false : "Who decided there's other steps but didn't modify the guy who does the work?";
+            }
+        } catch (final ResourceUnavailableException e) {
+            s_logger.debug("Agnet is not available" + e.getMessage());
+        } catch (OperationTimedoutException e) {
+            s_logger.debug("operation timed out: " + e.getMessage());
+        }
+
+        return (System.currentTimeMillis() >> 10) + _stopRetryInterval;
+    }
+
+    @Override
+    public void cancelScheduledMigrations(final HostVO host) {
+        WorkType type = host.getType() == HostVO.Type.Storage ? WorkType.Stop : WorkType.Migration;
+
+        _haDao.deleteMigrationWorkItems(host.getId(), type, _serverId);
+    }
+
+    @Override
+    public List<VMInstanceVO> findTakenMigrationWork() {
+        List<HaWorkVO> works = _haDao.findTakenWorkItems(WorkType.Migration);
+        List<VMInstanceVO> vms = new ArrayList<VMInstanceVO>(works.size());
+        for (HaWorkVO work : works) {
+            VMInstanceVO vm = _instanceDao.findById(work.getInstanceId());
+            if (vm != null) {
+                vms.add(vm);
+            }
+        }
+        return vms;
+    }
+
+    private void rescheduleWork(final HaWorkVO work, final long nextTime) {
+        s_logger.info("Rescheduling work " + work + " to try again at " + new Date(nextTime << 10));
+        work.setTimeToTry(nextTime);
+        work.setTimesTried(work.getTimesTried() + 1);
+        work.setServerId(null);
+        work.setDateTaken(null);
+    }
+
+    private long getRescheduleTime(WorkType workType) {
+        switch (workType) {
+            case Migration:
+                return ((System.currentTimeMillis() >> 10) + _migrateRetryInterval);
+            case HA:
+                return ((System.currentTimeMillis() >> 10) + _restartRetryInterval);
+            case Stop:
+            case CheckStop:
+            case ForceStop:
+                return ((System.currentTimeMillis() >> 10) + _stopRetryInterval);
+            case Destroy:
+                return ((System.currentTimeMillis() >> 10) + _restartRetryInterval);
+        }
+        return 0;
+    }
+
+    private void processWork(final HaWorkVO work) {
+        final WorkType wt = work.getWorkType();
+        try {
+            Long nextTime = null;
+            if (wt == WorkType.Migration) {
+                nextTime = migrate(work);
+            } else if (wt == WorkType.HA) {
+                nextTime = restart(work);
+            } else if (wt == WorkType.Stop || wt == WorkType.CheckStop || wt == WorkType.ForceStop) {
+                nextTime = stopVM(work);
+            } else if (wt == WorkType.Destroy) {
+                nextTime = destroyVM(work);
+            } else {
+                assert false : "How did we get here with " + wt.toString();
+                return;
+            }
+
+            if (nextTime == null) {
+                s_logger.info("Completed work " + work);
+                work.setStep(Step.Done);
+            } else {
+                rescheduleWork(work, nextTime.longValue());
+            }
+        } catch (Exception e) {
+            s_logger.warn("Encountered unhandled exception during HA process, reschedule work", e);
+
+            long nextTime = getRescheduleTime(wt);
+            rescheduleWork(work, nextTime);
+
+            // if restart failed in the middle due to exception, VM state may has been changed
+            // recapture into the HA worker so that it can really continue in it next turn
+            VMInstanceVO vm = _instanceDao.findById(work.getInstanceId());
+            work.setUpdateTime(vm.getUpdated());
+            work.setPreviousState(vm.getState());
+        }
+        if (!Step.Done.equals(work.getStep()) && work.getTimesTried() >= _maxRetries) {
+            s_logger.warn("Giving up, retried max. times for work: " + work);
+            work.setStep(Step.Done);
+        }
+        _haDao.update(work.getId(), work);
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> xmlParams) throws ConfigurationException {
+        _serverId = _msServer.getId();
+
+        Map<String, String> params = new HashMap<String, String>();
+        params = _configDao.getConfiguration(Long.toHexString(_serverId), xmlParams);
+
+        String value = params.get(Config.HAWorkers.key());
+        final int count = NumbersUtil.parseInt(value, 1);
+        _workers = new WorkerThread[count];
+        for (int i = 0; i < _workers.length; i++) {
+            _workers[i] = new WorkerThread("HA-Worker-" + i);
+        }
+
+        value = params.get("force.ha");
+        _forceHA = Boolean.parseBoolean(value);
+
+        value = params.get("time.to.sleep");
+        _timeToSleep = (long)NumbersUtil.parseInt(value, 60) * 1000;
+
+        value = params.get("max.retries");
+        _maxRetries = NumbersUtil.parseInt(value, 5);
+
+        value = params.get("time.between.failures");
+        _timeBetweenFailures = NumbersUtil.parseLong(value, 3600) * 1000;
+
+        value = params.get("time.between.cleanup");
+        _timeBetweenCleanups = NumbersUtil.parseLong(value, 3600 * 24);
+
+        value = params.get("stop.retry.interval");
+        _stopRetryInterval = NumbersUtil.parseInt(value, 10 * 60);
+
+        value = params.get("restart.retry.interval");
+        _restartRetryInterval = NumbersUtil.parseInt(value, 10 * 60);
+
+        value = params.get("investigate.retry.interval");
+        _investigateRetryInterval = NumbersUtil.parseInt(value, 1 * 60);
+
+        value = params.get("migrate.retry.interval");
+        _migrateRetryInterval = NumbersUtil.parseInt(value, 2 * 60);
+
+        _instance = params.get("instance");
+        if (_instance == null) {
+            _instance = "VMOPS";
+        }
+
+        _haTag = params.get("ha.tag");
+
+        _haDao.releaseWorkItems(_serverId);
+
+        _stopped = true;
+
+        _executor = Executors.newScheduledThreadPool(count, new NamedThreadFactory("HA"));
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        _stopped = false;
+
+        for (final WorkerThread thread : _workers) {
+            thread.start();
+        }
+
+        _executor.scheduleAtFixedRate(new CleanupTask(), _timeBetweenCleanups, _timeBetweenCleanups, TimeUnit.SECONDS);
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _stopped = true;
+
+        wakeupWorkers();
+
+        _executor.shutdown();
+
+        return true;
+    }
+
+    protected class CleanupTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            s_logger.info("HA Cleanup Thread Running");
+
+            try {
+                _haDao.cleanup(System.currentTimeMillis() - _timeBetweenFailures);
+            } catch (Exception e) {
+                s_logger.warn("Error while cleaning up", e);
+            }
+        }
+    }
+
+    protected class WorkerThread extends Thread {
+        public WorkerThread(String name) {
+            super(name);
+        }
+
+        @Override
+        public void run() {
+            s_logger.info("Starting work");
+            while (!_stopped) {
+                _managedContext.runWithContext(new Runnable() {
+                    @Override
+                    public void run() {
+                        runWithContext();
+                    }
+                });
+            }
+            s_logger.info("Time to go home!");
+        }
+
+        private void runWithContext() {
+            HaWorkVO work = null;
+            try {
+                s_logger.trace("Checking the database for work");
+                work = _haDao.take(_serverId);
+                if (work == null) {
+                    try {
+                        synchronized (this) {
+                            wait(_timeToSleep);
+                        }
+                        return;
+                    } catch (final InterruptedException e) {
+                        s_logger.info("Interrupted");
+                        return;
+                    }
+                }
+
+                NDC.push("work-" + work.getId());
+                s_logger.info("Processing work " + work);
+                processWork(work);
+            } catch (final Throwable th) {
+                s_logger.error("Caught this throwable, ", th);
+            } finally {
+                if (work != null) {
+                    NDC.pop();
+                }
+            }
+        }
+
+        public synchronized void wakup() {
+            notifyAll();
+        }
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (ManagementServerHost node : nodeList) {
+            _haDao.releaseWorkItems(node.getMsid());
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public String getHaTag() {
+        return _haTag;
+    }
+
+    @Override
+    public DeploymentPlanner getHAPlanner() {
+        return _haPlanners.get(0);
+    }
+
+    @Override
+    public boolean hasPendingHaWork(long vmId) {
+        List<HaWorkVO> haWorks = _haDao.listPendingHaWorkForVm(vmId);
+        return haWorks.size() > 0;
+    }
+}
diff --git a/server/src/main/java/com/cloud/ha/KVMFencer.java b/server/src/main/java/com/cloud/ha/KVMFencer.java
new file mode 100644
index 0000000..e102bc2
--- /dev/null
+++ b/server/src/main/java/com/cloud/ha/KVMFencer.java
@@ -0,0 +1,123 @@
+// 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.ha;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.alert.AlertManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+public class KVMFencer extends AdapterBase implements FenceBuilder {
+    private static final Logger s_logger = Logger.getLogger(KVMFencer.class);
+
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public KVMFencer() {
+        super();
+    }
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.KVM && host.getHypervisorType() != HypervisorType.LXC) {
+            s_logger.warn("Don't know how to fence non kvm hosts " + host.getHypervisorType());
+            return null;
+        }
+
+        List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        int i = 0;
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() == HypervisorType.KVM || h.getHypervisorType() == HypervisorType.LXC) {
+                if (h.getStatus() != Status.Up) {
+                    continue;
+                }
+
+                i++;
+
+                if (h.getId() == host.getId()) {
+                    continue;
+                }
+                FenceAnswer answer;
+                try {
+                    answer = (FenceAnswer)_agentMgr.send(h.getId(), fence);
+                } catch (AgentUnavailableException e) {
+                    s_logger.info("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    continue;
+                } catch (OperationTimedoutException e) {
+                    s_logger.info("Moving on to the next host because " + h.toString() + " is unavailable", e);
+                    continue;
+                }
+                if (answer != null && answer.getResult()) {
+                    return true;
+                }
+            }
+        }
+
+        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(),
+                            "Unable to fence off host: " + host.getId(),
+                            "Fencing off host " + host.getId() + " did not succeed after asking " + i + " hosts. " +
+                            "Check Agent logs for more information.");
+
+        s_logger.error("Unable to fence off " + vm.toString() + " on " + host.toString());
+
+        return false;
+    }
+}
diff --git a/server/src/com/cloud/ha/ManagementIPSystemVMInvestigator.java b/server/src/main/java/com/cloud/ha/ManagementIPSystemVMInvestigator.java
similarity index 100%
rename from server/src/com/cloud/ha/ManagementIPSystemVMInvestigator.java
rename to server/src/main/java/com/cloud/ha/ManagementIPSystemVMInvestigator.java
diff --git a/server/src/com/cloud/ha/RecreatableFencer.java b/server/src/main/java/com/cloud/ha/RecreatableFencer.java
similarity index 100%
rename from server/src/com/cloud/ha/RecreatableFencer.java
rename to server/src/main/java/com/cloud/ha/RecreatableFencer.java
diff --git a/server/src/com/cloud/ha/UserVmDomRInvestigator.java b/server/src/main/java/com/cloud/ha/UserVmDomRInvestigator.java
similarity index 100%
rename from server/src/com/cloud/ha/UserVmDomRInvestigator.java
rename to server/src/main/java/com/cloud/ha/UserVmDomRInvestigator.java
diff --git a/server/src/com/cloud/ha/XenServerInvestigator.java b/server/src/main/java/com/cloud/ha/XenServerInvestigator.java
similarity index 100%
rename from server/src/com/cloud/ha/XenServerInvestigator.java
rename to server/src/main/java/com/cloud/ha/XenServerInvestigator.java
diff --git a/server/src/com/cloud/ha/dao/HighAvailabilityDao.java b/server/src/main/java/com/cloud/ha/dao/HighAvailabilityDao.java
similarity index 100%
rename from server/src/com/cloud/ha/dao/HighAvailabilityDao.java
rename to server/src/main/java/com/cloud/ha/dao/HighAvailabilityDao.java
diff --git a/server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java b/server/src/main/java/com/cloud/ha/dao/HighAvailabilityDaoImpl.java
similarity index 100%
rename from server/src/com/cloud/ha/dao/HighAvailabilityDaoImpl.java
rename to server/src/main/java/com/cloud/ha/dao/HighAvailabilityDaoImpl.java
diff --git a/server/src/main/java/com/cloud/hypervisor/CloudZonesStartupProcessor.java b/server/src/main/java/com/cloud/hypervisor/CloudZonesStartupProcessor.java
new file mode 100644
index 0000000..8d674a5
--- /dev/null
+++ b/server/src/main/java/com/cloud/hypervisor/CloudZonesStartupProcessor.java
@@ -0,0 +1,192 @@
+// 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;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.StartupCommandProcessor;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.manager.authn.AgentAuthnException;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.net.MacAddress;
+import com.cloud.utils.net.NetUtils;
+
+/**
+ * Creates a host record and supporting records such as pod and ip address
+ *
+ */
+@Component
+public class CloudZonesStartupProcessor extends AdapterBase implements StartupCommandProcessor {
+    private static final Logger s_logger = Logger.getLogger(CloudZonesStartupProcessor.class);
+    @Inject
+    private DataCenterDao _zoneDao = null;
+    @Inject
+    private HostPodDao _podDao = null;
+    @Inject
+    private AgentManager _agentManager = null;
+
+    private long _nodeId = -1;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _agentManager.registerForInitialConnects(this, false);
+        if (_nodeId == -1) {
+            // FIXME: We really should not do this like this. It should be done
+            // at config time and is stored as a config variable.
+            _nodeId = MacAddress.getMacAddress().toLong();
+        }
+        return true;
+    }
+
+    @Override
+    public boolean processInitialConnect(StartupCommand[] cmd) {
+        StartupCommand startup = cmd[0];
+        return startup instanceof StartupRoutingCommand || startup instanceof StartupStorageCommand;
+    }
+
+    private boolean checkCIDR(Host.Type type, HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) {
+        if (serverPrivateIP == null) {
+            return true;
+        }
+        // Get the CIDR address and CIDR size
+        String cidrAddress = pod.getCidrAddress();
+        long cidrSize = pod.getCidrSize();
+
+        // If the server's private IP address is not in the same subnet as the
+        // pod's CIDR, return false
+        String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
+        String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
+        if (!cidrSubnet.equals(serverSubnet)) {
+            return false;
+        }
+        return true;
+    }
+
+    private void updatePodNetmaskIfNeeded(HostPodVO pod, String agentNetmask) {
+        // If the server's private netmask is less inclusive than the pod's CIDR
+        // netmask, update cidrSize of the default POD
+        //(reason: we are maintaining pods only for internal accounting.)
+        long cidrSize = pod.getCidrSize();
+        String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
+        long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
+        long serverNetmaskNumeric = NetUtils.ip2Long(agentNetmask);//
+        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
+            //update pod's cidrsize
+            int newCidrSize = new Long(NetUtils.getCidrSize(agentNetmask)).intValue();
+            pod.setCidrSize(newCidrSize);
+            _podDao.update(pod.getId(), pod);
+        }
+    }
+
+    protected void updateSecondaryHost(final HostVO host, final StartupStorageCommand startup, final Host.Type type) throws AgentAuthnException {
+
+        String zoneToken = startup.getDataCenter();
+        if (zoneToken == null) {
+            s_logger.warn("No Zone Token passed in, cannot not find zone for the agent");
+            throw new AgentAuthnException("No Zone Token passed in, cannot not find zone for agent");
+        }
+
+        DataCenterVO zone = _zoneDao.findByToken(zoneToken);
+        if (zone == null) {
+            zone = _zoneDao.findByName(zoneToken);
+            if (zone == null) {
+                try {
+                    long zoneId = Long.parseLong(zoneToken);
+                    zone = _zoneDao.findById(zoneId);
+                    if (zone == null) {
+                        throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
+                    }
+                } catch (NumberFormatException nfe) {
+                    throw new AgentAuthnException("Could not find zone for agent with token " + zoneToken);
+                }
+            }
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Successfully loaded the DataCenter from the zone token passed in ");
+        }
+
+        HostPodVO pod = findPod(startup, zone.getId(), Host.Type.Routing); //yes, routing
+        Long podId = null;
+        if (pod != null) {
+            s_logger.debug("Found pod " + pod.getName() + " for the secondary storage host " + startup.getName());
+            podId = pod.getId();
+        }
+        host.setDataCenterId(zone.getId());
+        host.setPodId(podId);
+        host.setClusterId(null);
+        host.setPrivateIpAddress(startup.getPrivateIpAddress());
+        host.setPrivateNetmask(startup.getPrivateNetmask());
+        host.setPrivateMacAddress(startup.getPrivateMacAddress());
+        host.setPublicIpAddress(startup.getPublicIpAddress());
+        host.setPublicMacAddress(startup.getPublicMacAddress());
+        host.setPublicNetmask(startup.getPublicNetmask());
+        host.setStorageIpAddress(startup.getStorageIpAddress());
+        host.setStorageMacAddress(startup.getStorageMacAddress());
+        host.setStorageNetmask(startup.getStorageNetmask());
+        host.setVersion(startup.getVersion());
+        host.setName(startup.getName());
+        host.setType(type);
+        host.setStorageUrl(startup.getIqn());
+        host.setLastPinged(System.currentTimeMillis() >> 10);
+        host.setCaps(null);
+        host.setCpus(null);
+        host.setTotalMemory(0);
+        host.setSpeed(null);
+        host.setParent(startup.getParent());
+        host.setTotalSize(startup.getTotalSize());
+        host.setHypervisorType(HypervisorType.None);
+        if (startup.getNfsShare() != null) {
+            host.setStorageUrl(startup.getNfsShare());
+        }
+
+    }
+
+    private HostPodVO findPod(StartupCommand startup, long zoneId, Host.Type type) {
+        HostPodVO pod = null;
+        List<HostPodVO> podsInZone = _podDao.listByDataCenterId(zoneId);
+        for (HostPodVO hostPod : podsInZone) {
+            if (checkCIDR(type, hostPod, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
+                pod = hostPod;
+
+                //found the default POD having the same subnet.
+                updatePodNetmaskIfNeeded(pod, startup.getPrivateNetmask());
+
+                break;
+            }
+        }
+        return pod;
+
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
new file mode 100644
index 0000000..445997a
--- /dev/null
+++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -0,0 +1,233 @@
+// 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;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.gpu.GPU;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingDetailsVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.StoragePool;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
+    public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
+
+    @Inject
+    private NicDao _nicDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private NetworkOfferingDetailsDao networkOfferingDetailsDao;
+    @Inject
+    private VMInstanceDao _virtualMachineDao;
+    @Inject
+    private UserVmDetailsDao _userVmDetailsDao;
+    @Inject
+    private NicSecondaryIpDao _nicSecIpDao;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+
+    @Override
+    public NicTO toNicTO(NicProfile profile) {
+        NicTO to = new NicTO();
+        to.setDeviceId(profile.getDeviceId());
+        to.setBroadcastType(profile.getBroadcastType());
+        to.setType(profile.getTrafficType());
+        to.setIp(profile.getIPv4Address());
+        to.setNetmask(profile.getIPv4Netmask());
+        to.setMac(profile.getMacAddress());
+        to.setDns1(profile.getIPv4Dns1());
+        to.setDns2(profile.getIPv4Dns2());
+        to.setGateway(profile.getIPv4Gateway());
+        to.setDefaultNic(profile.isDefaultNic());
+        to.setBroadcastUri(profile.getBroadCastUri());
+        to.setIsolationuri(profile.getIsolationUri());
+        to.setNetworkRateMbps(profile.getNetworkRate());
+        to.setName(profile.getName());
+        to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
+        to.setIp6Address(profile.getIPv6Address());
+        to.setIp6Cidr(profile.getIPv6Cidr());
+
+        NetworkVO network = _networkDao.findById(profile.getNetworkId());
+        to.setNetworkUuid(network.getUuid());
+
+        // Workaround to make sure the TO has the UUID we need for Nicira integration
+        NicVO nicVO = _nicDao.findById(profile.getId());
+        if (nicVO != null) {
+            to.setUuid(nicVO.getUuid());
+            // disable pxe on system vm nics to speed up boot time
+            if (nicVO.getVmType() != VirtualMachine.Type.User) {
+                to.setPxeDisable(true);
+            }
+            List<String> secIps = null;
+            if (nicVO.getSecondaryIp()) {
+                secIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nicVO.getId());
+            }
+            to.setNicSecIps(secIps);
+        } else {
+            s_logger.warn("Unabled to load NicVO for NicProfile " + profile.getId());
+            //Workaround for dynamically created nics
+            //FixMe: uuid and secondary IPs can be made part of nic profile
+            to.setUuid(UUID.randomUUID().toString());
+        }
+
+        //check whether the this nic has secondary ip addresses set
+        //set nic secondary ip address in NicTO which are used for security group
+        // configuration. Use full when vm stop/start
+        return to;
+    }
+
+    protected VirtualMachineTO toVirtualMachineTO(VirtualMachineProfile vmProfile) {
+        ServiceOffering offering = _serviceOfferingDao.findById(vmProfile.getId(), vmProfile.getServiceOfferingId());
+        VirtualMachine vm = vmProfile.getVirtualMachine();
+        Long minMemory = (long)(offering.getRamSize() / vmProfile.getMemoryOvercommitRatio());
+        int minspeed = (int)(offering.getSpeed() / vmProfile.getCpuOvercommitRatio());
+        int maxspeed = (offering.getSpeed());
+        VirtualMachineTO to = new VirtualMachineTO(vm.getId(), vm.getInstanceName(), vm.getType(), offering.getCpu(), minspeed, maxspeed, minMemory * 1024l * 1024l,
+                offering.getRamSize() * 1024l * 1024l, null, null, vm.isHaEnabled(), vm.limitCpuUse(), vm.getVncPassword());
+        to.setBootArgs(vmProfile.getBootArgs());
+
+        List<NicProfile> nicProfiles = vmProfile.getNics();
+        NicTO[] nics = new NicTO[nicProfiles.size()];
+        int i = 0;
+        for (NicProfile nicProfile : nicProfiles) {
+            if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
+                nicProfile.setBroadcastType(BroadcastDomainType.Native);
+            }
+            NicTO nicTo = toNicTO(nicProfile);
+            final NetworkVO network = _networkDao.findByUuid(nicTo.getNetworkUuid());
+            if (network != null) {
+                final Map<NetworkOffering.Detail, String> details = networkOfferingDetailsDao.getNtwkOffDetails(network.getNetworkOfferingId());
+                if (details != null) {
+                    details.putIfAbsent(NetworkOffering.Detail.PromiscuousMode, NetworkOrchestrationService.PromiscuousMode.value().toString());
+                    details.putIfAbsent(NetworkOffering.Detail.MacAddressChanges, NetworkOrchestrationService.MacAddressChanges.value().toString());
+                    details.putIfAbsent(NetworkOffering.Detail.ForgedTransmits, NetworkOrchestrationService.ForgedTransmits.value().toString());
+                }
+                nicTo.setDetails(details);
+            }
+            nics[i++] = nicTo;
+        }
+
+        to.setNics(nics);
+        to.setDisks(vmProfile.getDisks().toArray(new DiskTO[vmProfile.getDisks().size()]));
+
+        if (vmProfile.getTemplate().getBits() == 32) {
+            to.setArch("i686");
+        } else {
+            to.setArch("x86_64");
+        }
+
+        Map<String, String> detailsInVm = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+        if (detailsInVm != null) {
+            to.setDetails(detailsInVm);
+        }
+
+        // Set GPU details
+        ServiceOfferingDetailsVO offeringDetail = null;
+        if ((offeringDetail = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.vgpuType.toString())) != null) {
+            ServiceOfferingDetailsVO groupName = _serviceOfferingDetailsDao.findDetail(offering.getId(), GPU.Keys.pciDevice.toString());
+            to.setGpuDevice(_resourceMgr.getGPUDevice(vm.getHostId(), groupName.getValue(), offeringDetail.getValue()));
+        }
+
+        // Workaround to make sure the TO has the UUID we need for Niciri integration
+        VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId());
+        // check if XStools/VMWare tools are present in the VM and dynamic scaling feature is enabled (per zone/global)
+        Boolean isDynamicallyScalable = vmInstance.isDynamicallyScalable() && UserVmManager.EnableDynamicallyScaleVm.valueIn(vm.getDataCenterId());
+        to.setEnableDynamicallyScaleVm(isDynamicallyScalable);
+        to.setUuid(vmInstance.getUuid());
+
+        to.setVmData(vmProfile.getVmData());
+        to.setConfigDriveLabel(vmProfile.getConfigDriveLabel());
+        to.setConfigDriveIsoRootFolder(vmProfile.getConfigDriveIsoRootFolder());
+        to.setConfigDriveIsoFile(vmProfile.getConfigDriveIsoFile());
+        to.setState(vm.getState());
+
+        return to;
+    }
+
+    @Override
+    /**
+     * The basic implementation assumes that the initial "host" defined to execute the command is the host that is in fact going to execute it.
+     * However, subclasses can extend this behavior, changing the host that is going to execute the command in runtime.
+     * The first element of the 'Pair' indicates if the hostId has been changed; this means, if you change the hostId, but you do not inform this action in the return 'Pair' object, we will use the original "hostId".
+     *
+     * Side note: it seems that the 'hostId' received here is normally the ID of the SSVM that has an entry at the host table. Therefore, this methods gives the opportunity to change from the SSVM to a real host to execute a command.
+     */
+    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
+        return new Pair<Boolean, Long>(Boolean.FALSE, new Long(hostId));
+    }
+
+    @Override
+    public List<Command> finalizeExpunge(VirtualMachine vm) {
+        return null;
+    }
+
+    @Override
+    public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
+        return null;
+    }
+
+    @Override
+    public List<Command> finalizeExpungeVolumes(VirtualMachine vm) {
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getClusterSettings(long vmId) {
+        return null;
+    }
+
+    @Override
+    public List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination) {
+        return null;
+    }
+}
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
rename to server/src/main/java/com/cloud/hypervisor/HypervisorGuruManagerImpl.java
diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/main/java/com/cloud/hypervisor/KVMGuru.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/KVMGuru.java
rename to server/src/main/java/com/cloud/hypervisor/KVMGuru.java
diff --git a/server/src/com/cloud/hypervisor/LXCGuru.java b/server/src/main/java/com/cloud/hypervisor/LXCGuru.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/LXCGuru.java
rename to server/src/main/java/com/cloud/hypervisor/LXCGuru.java
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmDummyResourceBase.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/KvmDummyResourceBase.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/kvm/discoverer/KvmDummyResourceBase.java
rename to server/src/main/java/com/cloud/hypervisor/kvm/discoverer/KvmDummyResourceBase.java
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
rename to server/src/main/java/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
rename to server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java b/server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
similarity index 100%
rename from server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
rename to server/src/main/java/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManager.java b/server/src/main/java/com/cloud/metadata/ResourceMetaDataManager.java
similarity index 100%
rename from server/src/com/cloud/metadata/ResourceMetaDataManager.java
rename to server/src/main/java/com/cloud/metadata/ResourceMetaDataManager.java
diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/main/java/com/cloud/metadata/ResourceMetaDataManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java
rename to server/src/main/java/com/cloud/metadata/ResourceMetaDataManagerImpl.java
diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManager.java b/server/src/main/java/com/cloud/network/ExternalDeviceUsageManager.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalDeviceUsageManager.java
rename to server/src/main/java/com/cloud/network/ExternalDeviceUsageManager.java
diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/main/java/com/cloud/network/ExternalDeviceUsageManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
rename to server/src/main/java/com/cloud/network/ExternalDeviceUsageManagerImpl.java
diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManager.java b/server/src/main/java/com/cloud/network/ExternalFirewallDeviceManager.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalFirewallDeviceManager.java
rename to server/src/main/java/com/cloud/network/ExternalFirewallDeviceManager.java
diff --git a/server/src/main/java/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/main/java/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
new file mode 100644
index 0000000..496359d
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/ExternalFirewallDeviceManagerImpl.java
@@ -0,0 +1,843 @@
+// 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.network;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.response.ExternalFirewallResponse;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalFirewallCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.ExternalFirewallDeviceDao;
+import com.cloud.network.dao.ExternalFirewallDeviceVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
+import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkExternalFirewallDao;
+import com.cloud.network.dao.NetworkExternalFirewallVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.net.UrlUtil;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase implements ExternalFirewallDeviceManager, ResourceStateAdapter {
+
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcProviderDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    UserStatisticsDao _userStatsDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    LoadBalancerDao _loadBalancerDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingRulesDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ExternalFirewallDeviceDao _externalFirewallDeviceDao;
+    @Inject
+    NetworkExternalFirewallDao _networkExternalFirewallDao;
+    @Inject
+    VpnUserDao _vpnUsersDao;
+    @Inject
+    HostDetailsDao _hostDetailDao;
+    @Inject
+    FirewallRulesDao _fwRulesDao;
+
+    private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalFirewallDeviceManagerImpl.class);
+    private long _defaultFwCapacity;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+        _defaultFwCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalFirewallCapacity.key()), 50);
+        return true;
+    }
+
+    @Override
+    @DB
+    public ExternalFirewallDeviceVO addExternalFirewall(long physicalNetworkId, String url, String username, String password, final String deviceName,
+        ServerResource resource) {
+        String guid;
+        PhysicalNetworkVO pNetwork = null;
+        NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName);
+        long zoneId;
+
+        if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) {
+            throw new InvalidParameterValueException("Atleast one of the required parameters (url, username, password,"
+                + " server resource, zone id/physical network id) is not specified or a valid parameter.");
+        }
+
+        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+        }
+        zoneId = pNetwork.getDataCenterId();
+
+        final PhysicalNetworkServiceProviderVO ntwkSvcProvider =
+            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
+        if (ntwkSvcProvider == null) {
+            throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: " +
+                physicalNetworkId + "to add this device");
+        } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+            throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() +
+                " is not added or in shutdown state in the physical network: " + physicalNetworkId + "to add this device");
+        }
+
+        URI uri;
+        try {
+            uri = new URI(url);
+        } catch (Exception e) {
+            s_logger.debug(e);
+            throw new InvalidParameterValueException(e.getMessage());
+        }
+
+        String ipAddress = uri.getHost();
+        Map hostDetails = new HashMap<String, String>();
+        guid = getExternalNetworkResourceGuid(pNetwork.getId(), deviceName, ipAddress);
+        hostDetails.put("name", guid);
+        hostDetails.put("guid", guid);
+        hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId()));
+        hostDetails.put("ip", ipAddress);
+        hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId()));
+        hostDetails.put("username", username);
+        hostDetails.put("password", password);
+        hostDetails.put("deviceName", deviceName);
+        final Map<String, String> configParams = new HashMap<String, String>();
+        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
+        hostDetails.putAll(configParams);
+
+        // let the server resource to do parameters validation
+        try {
+            resource.configure(guid, hostDetails);
+        } catch (ConfigurationException e) {
+            throw new CloudRuntimeException(e.getMessage());
+        }
+
+        final Host externalFirewall = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, hostDetails);
+        if (externalFirewall != null) {
+            final PhysicalNetworkVO pNetworkFinal = pNetwork;
+            return Transaction.execute(new TransactionCallback<ExternalFirewallDeviceVO>() {
+                @Override
+                public ExternalFirewallDeviceVO doInTransaction(TransactionStatus status) {
+                    boolean dedicatedUse =
+                        (configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.FIREWALL_DEVICE_DEDICATED))
+                            : false;
+                    long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.FIREWALL_DEVICE_CAPACITY), 0);
+                    if (capacity == 0) {
+                        capacity = _defaultFwCapacity;
+                    }
+
+                    ExternalFirewallDeviceVO fwDevice =
+                        new ExternalFirewallDeviceVO(externalFirewall.getId(), pNetworkFinal.getId(), ntwkSvcProvider.getProviderName(), deviceName, capacity,
+                            dedicatedUse);
+
+                    _externalFirewallDeviceDao.persist(fwDevice);
+
+                    DetailVO hostDetail = new DetailVO(externalFirewall.getId(), ApiConstants.FIREWALL_DEVICE_ID, String.valueOf(fwDevice.getId()));
+                    _hostDetailDao.persist(hostDetail);
+
+                    return fwDevice;
+                }
+            });
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean deleteExternalFirewall(Long hostId) {
+        HostVO externalFirewall = _hostDao.findById(hostId);
+        if (externalFirewall == null) {
+            throw new InvalidParameterValueException("Could not find an external firewall with ID: " + hostId);
+        }
+
+        DetailVO fwHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.FIREWALL_DEVICE_ID);
+        long fwDeviceId = Long.parseLong(fwHostDetails.getValue());
+
+        // check if any networks are using this balancer device
+        List<NetworkExternalFirewallVO> networks = _networkExternalFirewallDao.listByFirewallDeviceId(fwDeviceId);
+        if ((networks != null) && !networks.isEmpty()) {
+            throw new CloudRuntimeException("Delete can not be done as there are networks using the firewall device ");
+        }
+
+        try {
+            // put the host in maintenance state in order for it to be deleted
+            externalFirewall.setResourceState(ResourceState.Maintenance);
+            _hostDao.update(hostId, externalFirewall);
+            _resourceMgr.deleteHost(hostId, false, false);
+
+            // delete the external load balancer entry
+            _externalFirewallDeviceDao.remove(fwDeviceId);
+            return true;
+        } catch (Exception e) {
+            s_logger.debug("Failed to delete external firewall device due to " + e.getMessage());
+            return false;
+        }
+    }
+
+    @Override
+    public List<Host> listExternalFirewalls(long physicalNetworkId, String deviceName) {
+        List<Host> firewallHosts = new ArrayList<Host>();
+        NetworkDevice fwNetworkDevice = NetworkDevice.getNetworkDevice(deviceName);
+        PhysicalNetworkVO pNetwork = null;
+
+        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+        }
+
+        if ((pNetwork == null) || (fwNetworkDevice == null)) {
+            throw new InvalidParameterValueException("Atleast one of ther required parameter physical networkId, device name is missing or invalid.");
+        }
+
+        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
+            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), fwNetworkDevice.getNetworkServiceProvder());
+        if (ntwkSvcProvider == null) {
+            return null;
+        }
+
+        List<ExternalFirewallDeviceVO> fwDevices = _externalFirewallDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, ntwkSvcProvider.getProviderName());
+        for (ExternalFirewallDeviceVO fwDevice : fwDevices) {
+            firewallHosts.add(_hostDao.findById(fwDevice.getHostId()));
+        }
+        return firewallHosts;
+    }
+
+    @Override
+    public ExternalFirewallDeviceVO getExternalFirewallForNetwork(Network network) {
+        NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
+        if (fwDeviceForNetwork != null) {
+            long fwDeviceId = fwDeviceForNetwork.getExternalFirewallDeviceId();
+            ExternalFirewallDeviceVO fwDevice = _externalFirewallDeviceDao.findById(fwDeviceId);
+            assert (fwDevice != null);
+            return fwDevice;
+        }
+        return null;
+    }
+
+    public void setExternalFirewallForNetwork(Network network, long externalFWDeviceID) {
+        NetworkExternalFirewallVO fwDeviceForNetwork = new NetworkExternalFirewallVO(network.getId(), externalFWDeviceID);
+        _networkExternalFirewallDao.persist(fwDeviceForNetwork);
+    }
+
+    @Override
+    public ExternalFirewallDeviceVO findSuitableFirewallForNetwork(Network network) throws InsufficientCapacityException {
+        long physicalNetworkId = network.getPhysicalNetworkId();
+        List<ExternalFirewallDeviceVO> fwDevices = _externalFirewallDeviceDao.listByPhysicalNetwork(physicalNetworkId);
+
+        // loop through the firewall device in the physical network and pick the first-fit
+        for (ExternalFirewallDeviceVO fwDevice : fwDevices) {
+            // max number of guest networks that can be mapped to this device
+            long fullCapacity = fwDevice.getCapacity();
+            if (fullCapacity == 0) {
+                fullCapacity = _defaultFwCapacity; // if capacity not configured then use the default
+            }
+
+            // get the list of guest networks that are mapped to this load balancer
+            List<NetworkExternalFirewallVO> mappedNetworks = _networkExternalFirewallDao.listByFirewallDeviceId(fwDevice.getId());
+
+            long usedCapacity = (mappedNetworks == null) ? 0 : mappedNetworks.size();
+            if ((fullCapacity - usedCapacity) > 0) {
+                return fwDevice;
+            }
+        }
+        throw new InsufficientNetworkCapacityException("Unable to find a firewall provider with sufficient capcity " + " to implement the network", DataCenter.class,
+            network.getDataCenterId());
+    }
+
+    @DB
+    protected boolean freeFirewallForNetwork(Network network) {
+        GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
+        try {
+            if (deviceMapLock.lock(120)) {
+                try {
+                    NetworkExternalFirewallVO fwDeviceForNetwork = _networkExternalFirewallDao.findByNetworkId(network.getId());
+                    if (fwDeviceForNetwork != null) {
+                        _networkExternalFirewallDao.remove(fwDeviceForNetwork.getId());
+                    }
+                } catch (Exception exception) {
+                    s_logger.error("Failed to release firewall device for the network" + network.getId() + " due to " + exception.getMessage());
+                    return false;
+                } finally {
+                    deviceMapLock.unlock();
+                }
+            }
+        } finally {
+            deviceMapLock.releaseRef();
+        }
+        return true;
+    }
+
+    public String getExternalNetworkResourceGuid(long physicalNetworkId, String deviceName, String ip) {
+        return physicalNetworkId + "-" + deviceName + "-" + ip;
+    }
+
+    public ExternalFirewallResponse createExternalFirewallResponse(Host externalFirewall) {
+        Map<String, String> fwDetails = _hostDetailDao.findDetails(externalFirewall.getId());
+        ExternalFirewallResponse response = new ExternalFirewallResponse();
+        response.setId(externalFirewall.getUuid());
+        response.setIpAddress(externalFirewall.getPrivateIpAddress());
+        response.setUsername(fwDetails.get("username"));
+        response.setPublicInterface(fwDetails.get("publicInterface"));
+        response.setUsageInterface(fwDetails.get("usageInterface"));
+        response.setPrivateInterface(fwDetails.get("privateInterface"));
+        response.setPublicZone(fwDetails.get("publicZone"));
+        response.setPrivateZone(fwDetails.get("privateZone"));
+        response.setNumRetries(fwDetails.get("numRetries"));
+        response.setTimeout(fwDetails.get("timeout"));
+        return response;
+    }
+
+    @Override
+    public boolean manageGuestNetworkWithExternalFirewall(boolean add, Network network) throws ResourceUnavailableException, InsufficientCapacityException {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            s_logger.trace("External firewall can only be used for add/remove guest networks.");
+            return false;
+        }
+
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        HostVO externalFirewall = null;
+
+        if (add) {
+            GlobalLock deviceMapLock = GlobalLock.getInternLock("NetworkFirewallDeviceMap");
+            try {
+                if (deviceMapLock.lock(120)) {
+                    try {
+                        ExternalFirewallDeviceVO device = findSuitableFirewallForNetwork(network);
+                        long externalFirewallId = device.getId();
+
+                        NetworkExternalFirewallVO networkFW = new NetworkExternalFirewallVO(network.getId(), externalFirewallId);
+                        _networkExternalFirewallDao.persist(networkFW);
+
+                        externalFirewall = _hostDao.findById(device.getHostId());
+                    } finally {
+                        deviceMapLock.unlock();
+                    }
+                }
+            } finally {
+                deviceMapLock.releaseRef();
+            }
+        } else {
+            ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+            if (fwDeviceVO == null) {
+                s_logger.warn("Network shutdown requested on external firewall element, which did not implement the network."
+                    + " Either network implement failed half way through or already network shutdown is completed.");
+                return true;
+            }
+            externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+        }
+
+        Account account = _accountDao.findByIdIncludingRemoved(network.getAccountId());
+
+        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        boolean sharedSourceNat = offering.isSharedSourceNat();
+
+        IPAddressVO sourceNatIp = null;
+        if (!sharedSourceNat) {
+            // Get the source NAT IP address for this network
+            List<? extends IpAddress> sourceNatIps = _networkModel.listPublicIpsAssignedToAccount(network.getAccountId(), zoneId, true);
+
+            for (IpAddress ipAddress : sourceNatIps) {
+                if (ipAddress.getAssociatedWithNetworkId().longValue() == network.getId()) {
+                    sourceNatIp = _ipAddressDao.findById(ipAddress.getId());
+                    break;
+                }
+            }
+            if (sourceNatIp == null) {
+                String errorMsg = "External firewall was unable to find the source NAT IP address for network " + network.getName();
+                s_logger.error(errorMsg);
+                return true;
+            }
+        }
+
+        // Send a command to the external firewall to implement or shutdown the guest network
+        long guestVlanTag = Long.parseLong(BroadcastDomainType.getValue(network.getBroadcastUri()));
+        String guestVlanGateway = network.getGateway();
+        String guestVlanCidr = network.getCidr();
+        String sourceNatIpAddress = null;
+        String publicVlanTag = null;
+
+        if (sourceNatIp != null) {
+            sourceNatIpAddress = sourceNatIp.getAddress().addr();
+            VlanVO publicVlan = _vlanDao.findById(sourceNatIp.getVlanId());
+            publicVlanTag = publicVlan.getVlanTag();
+        }
+
+        // Get network rate
+        Integer networkRate = _networkModel.getNetworkRate(network.getId(), null);
+
+        IpAddressTO ip = new IpAddressTO(account.getAccountId(), sourceNatIpAddress, add, false, !sharedSourceNat, publicVlanTag, null, null, null, networkRate, false);
+        IpAddressTO[] ips = new IpAddressTO[1];
+        ips[0] = ip;
+        IpAssocCommand cmd = new IpAssocCommand(ips);
+        cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, guestVlanGateway);
+        cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, guestVlanCidr);
+        cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
+        Answer answer = _agentMgr.easySend(externalFirewall.getId(), cmd);
+
+        List<String> reservedIpAddressesForGuestNetwork = _nicDao.listIpAddressInNetwork(network.getId());
+
+        if (answer == null || !answer.getResult()) {
+            String action = add ? "implement" : "shutdown";
+            String answerDetails = (answer != null) ? answer.getDetails() : "answer was null";
+            String msg =
+                "External firewall was unable to " + action + " the guest network on the external firewall in zone " + zone.getName() + " due to " + answerDetails;
+            s_logger.error(msg);
+            if (!add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
+                // If we failed the implementation as well, then just return, no complain
+                s_logger.error("Skip the shutdown of guest network on SRX because it seems we didn't implement it as well");
+                return true;
+            }
+            throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
+        }
+
+        if (add && (!reservedIpAddressesForGuestNetwork.contains(network.getGateway()))) {
+            // Insert a new NIC for this guest network to reserve the gateway address
+            _networkMgr.savePlaceholderNic(network, network.getGateway(), null, null);
+        }
+
+        // Delete any mappings used for inline external load balancers in this network
+        List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(network.getId());
+        for (NicVO nic : nicsInNetwork) {
+            InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByNicId(nic.getId());
+
+            if (mapping != null) {
+                _nicDao.expunge(mapping.getNicId());
+                _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
+            }
+        }
+
+        // on network shutdown, delete placeHolder nics used for the firewall device
+        if (!add) {
+            List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
+            for (NicVO nic : nics) {
+                if (nic.getVmType() == null && nic.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && nic.getIPv4Address().equals(network.getGateway())) {
+                    s_logger.debug("Removing placeholder nic " + nic + " for the network " + network);
+                    _nicDao.remove(nic.getId());
+                }
+            }
+            freeFirewallForNetwork(network);
+        }
+
+        String action = add ? "implemented" : "shut down";
+        s_logger.debug("External firewall has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() +
+            ") with VLAN tag " + guestVlanTag);
+
+        return true;
+    }
+
+    @Override
+    public boolean applyFirewallRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
+        // Find the external firewall in this zone
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+        // During destroy, device reference may already been clean up, then we just return true
+        if (fwDeviceVO == null) {
+            return true;
+        }
+        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+
+        assert (externalFirewall != null);
+
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
+                "; this network is not implemented. Skipping backend commands.");
+            return true;
+        }
+
+        List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
+        NetworkVO networkVO = _networkDao.findById(network.getId());
+        NetworkOfferingVO offering = _networkOfferingDao.findById(networkVO.getNetworkOfferingId());
+        Boolean defaultEgressPolicy = offering.isEgressDefaultPolicy();
+
+        for (FirewallRule rule : rules) {
+            if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
+                _fwRulesDao.loadSourceCidrs((FirewallRuleVO)rule);
+            }
+            FirewallRuleTO ruleTO;
+            if (rule.getPurpose() == Purpose.Firewall && rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
+                String guestVlanTag = BroadcastDomainType.getValue(network.getBroadcastUri());
+                String guestCidr = network.getCidr();
+                ruleTO = new FirewallRuleTO(rule, guestVlanTag, rule.getTrafficType(), guestCidr, defaultEgressPolicy, rule.getType());
+            } else {
+                IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
+
+                ruleTO = new FirewallRuleTO(rule, vlan.getVlanTag(), sourceIp.getAddress().addr());
+            }
+            rulesTO.add(ruleTO);
+        }
+
+        //Firewall rules configured for staticNAT/PF
+        sendFirewallRules(rulesTO, zone, externalFirewall.getId());
+
+        return true;
+    }
+
+    public boolean applyStaticNatRules(Network network, List<? extends StaticNat> rules) throws ResourceUnavailableException {
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+
+        assert (externalFirewall != null);
+
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
+                "; this network is not implemented. Skipping backend commands.");
+            return true;
+        }
+
+        List<StaticNatRuleTO> staticNatRules = new ArrayList<StaticNatRuleTO>();
+
+        for (StaticNat rule : rules) {
+            IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+            Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
+
+            StaticNatRuleTO ruleTO =
+                new StaticNatRuleTO(0, vlan.getVlanTag(), sourceIp.getAddress().addr(), -1, -1, rule.getDestIpAddress(), -1, -1, "any", rule.isForRevoke(), false);
+            staticNatRules.add(ruleTO);
+        }
+
+        sendStaticNatRules(staticNatRules, zone, externalFirewall.getId());
+
+        return true;
+    }
+
+    protected void sendFirewallRules(List<FirewallRuleTO> firewallRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
+        if (!firewallRules.isEmpty()) {
+            SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(firewallRules);
+            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
+            if (answer == null || !answer.getResult()) {
+                String details = (answer != null) ? answer.getDetails() : "details unavailable";
+                String msg = "External firewall was unable to apply static nat rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
+                s_logger.error(msg);
+                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
+            }
+        }
+    }
+
+    protected void sendStaticNatRules(List<StaticNatRuleTO> staticNatRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
+        if (!staticNatRules.isEmpty()) {
+            SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null);
+            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
+            if (answer == null || !answer.getResult()) {
+                String details = (answer != null) ? answer.getDetails() : "details unavailable";
+                String msg = "External firewall was unable to apply static nat rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
+                s_logger.error(msg);
+                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
+            }
+        }
+    }
+
+    protected void sendPortForwardingRules(List<PortForwardingRuleTO> portForwardingRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException {
+        if (!portForwardingRules.isEmpty()) {
+            SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(portForwardingRules);
+            Answer answer = _agentMgr.easySend(externalFirewallId, cmd);
+            if (answer == null || !answer.getResult()) {
+                String details = (answer != null) ? answer.getDetails() : "details unavailable";
+                String msg = "External firewall was unable to apply port forwarding rules to the SRX appliance in zone " + zone.getName() + " due to: " + details + ".";
+                s_logger.error(msg);
+                throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
+            }
+        }
+    }
+
+    public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddresses) throws ResourceUnavailableException {
+        return true;
+    }
+
+    public boolean manageRemoteAccessVpn(boolean create, Network network, RemoteAccessVpn vpn) throws ResourceUnavailableException {
+        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+
+        if (externalFirewall == null) {
+            return false;
+        }
+
+        // Create/delete VPN
+        IpAddress ip = _networkModel.getIp(vpn.getServerAddressId());
+
+        // Mask the IP range with the network's VLAN tag
+        String[] ipRange = vpn.getIpRange().split("-");
+        DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
+        int vlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
+        int offset = getVlanOffset(network.getPhysicalNetworkId(), vlanTag);
+        int cidrSize = getGloballyConfiguredCidrSize();
+
+        for (int i = 0; i < 2; i++) {
+            ipRange[i] = NetUtils.long2Ip((NetUtils.ip2Long(ipRange[i]) & 0xff000000) | (offset << (32 - cidrSize)));
+        }
+
+        String maskedIpRange = ipRange[0] + "-" + ipRange[1];
+
+        RemoteAccessVpnCfgCommand createVpnCmd =
+            new RemoteAccessVpnCfgCommand(create, ip.getAddress().addr(), vpn.getLocalIp(), maskedIpRange, vpn.getIpsecPresharedKey(), false);
+        createVpnCmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(network.getAccountId()));
+        createVpnCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
+        Answer answer = _agentMgr.easySend(externalFirewall.getId(), createVpnCmd);
+        if (answer == null || !answer.getResult()) {
+            String details = (answer != null) ? answer.getDetails() : "details unavailable";
+            String msg = "External firewall was unable to create a remote access VPN in zone " + zone.getName() + " due to: " + details + ".";
+            s_logger.error(msg);
+            throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
+        }
+
+        // Add/delete users
+        List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
+        return manageRemoteAccessVpnUsers(network, vpn, vpnUsers);
+    }
+
+    public boolean manageRemoteAccessVpnUsers(Network network, RemoteAccessVpn vpn, List<? extends VpnUser> vpnUsers) throws ResourceUnavailableException {
+        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+
+        if (externalFirewall == null) {
+            return false;
+        }
+
+        List<VpnUser> addUsers = new ArrayList<VpnUser>();
+        List<VpnUser> removeUsers = new ArrayList<VpnUser>();
+        for (VpnUser user : vpnUsers) {
+            if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) {
+                addUsers.add(user);
+            } else if (user.getState() == VpnUser.State.Revoke) {
+                removeUsers.add(user);
+            }
+        }
+
+        VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers);
+        addUsersCmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(network.getAccountId()));
+        addUsersCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
+
+        Answer answer = _agentMgr.easySend(externalFirewall.getId(), addUsersCmd);
+        if (answer == null || !answer.getResult()) {
+            String details = (answer != null) ? answer.getDetails() : "details unavailable";
+            DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
+            String msg = "External firewall was unable to add remote access users in zone " + zone.getName() + " due to: " + details + ".";
+            s_logger.error(msg);
+            throw new ResourceUnavailableException(msg, DataCenter.class, zone.getId());
+        }
+
+        return true;
+    }
+
+    public int getVlanOffset(long physicalNetworkId, int vlanTag) {
+        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
+        }
+
+        if (pNetwork.getVnet() == null) {
+            throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
+        }
+        Integer lowestVlanTag = null;
+        List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
+        //finding the vlanrange in which the vlanTag lies.
+        for (Pair<Integer, Integer> vnet : vnetList) {
+            if (vlanTag >= vnet.first() && vlanTag <= vnet.second()) {
+                lowestVlanTag = vnet.first();
+            }
+        }
+        if (lowestVlanTag == null) {
+            throw new InvalidParameterValueException("The vlan tag does not belong to any of the existing vlan ranges");
+        }
+        return vlanTag - lowestVlanTag;
+    }
+
+    public int getGloballyConfiguredCidrSize() {
+        try {
+            String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
+            return 8 + Integer.parseInt(globalVlanBits);
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
+        }
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        if (!(startup[0] instanceof StartupExternalFirewallCommand)) {
+            return null;
+        }
+        host.setType(Host.Type.ExternalFirewall);
+        return host;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (host.getType() != com.cloud.host.Host.Type.ExternalFirewall) {
+            return null;
+        }
+        return new DeleteHostAnswer(true);
+    }
+
+    @Override
+    public boolean applyPortForwardingRules(Network network, List<? extends PortForwardingRule> rules) throws ResourceUnavailableException {
+        // Find the external firewall in this zone
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+        HostVO externalFirewall = _hostDao.findById(fwDeviceVO.getHostId());
+
+        assert (externalFirewall != null);
+
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() +
+                "; this network is not implemented. Skipping backend commands.");
+            return true;
+        }
+
+        List<PortForwardingRuleTO> pfRules = new ArrayList<PortForwardingRuleTO>();
+
+        for (PortForwardingRule rule : rules) {
+            IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+            Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
+
+            PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, vlan.getVlanTag(), sourceIp.getAddress().addr());
+            pfRules.add(ruleTO);
+        }
+
+        sendPortForwardingRules(pfRules, zone, externalFirewall.getId());
+        return true;
+    }
+}
diff --git a/server/src/com/cloud/network/ExternalIpAddressAllocator.java b/server/src/main/java/com/cloud/network/ExternalIpAddressAllocator.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalIpAddressAllocator.java
rename to server/src/main/java/com/cloud/network/ExternalIpAddressAllocator.java
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java b/server/src/main/java/com/cloud/network/ExternalLoadBalancerDeviceManager.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalLoadBalancerDeviceManager.java
rename to server/src/main/java/com/cloud/network/ExternalLoadBalancerDeviceManager.java
diff --git a/server/src/main/java/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/main/java/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
new file mode 100644
index 0000000..961d934
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -0,0 +1,1311 @@
+// 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.network;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.response.ExternalLoadBalancerResponse;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
+import com.cloud.agent.api.routing.CreateLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer;
+import com.cloud.agent.api.routing.HealthCheckLBConfigCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterIpAddressVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.ExternalFirewallDeviceDao;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceDao;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceAllocationState;
+import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.InlineLoadBalancerNicMapDao;
+import com.cloud.network.dao.InlineLoadBalancerNicMapVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkExternalFirewallDao;
+import com.cloud.network.dao.NetworkExternalLoadBalancerDao;
+import com.cloud.network.dao.NetworkExternalLoadBalancerVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRule.LbDestination;
+import com.cloud.network.resource.CreateLoadBalancerApplianceAnswer;
+import com.cloud.network.resource.DestroyLoadBalancerApplianceAnswer;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StaticNatImpl;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.net.UrlUtil;
+import com.cloud.vm.Nic;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter {
+
+    @Inject
+    NetworkExternalLoadBalancerDao _networkExternalLBDao;
+    @Inject
+    ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    InlineLoadBalancerNicMapDao _inlineLoadBalancerNicMapDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    UserStatisticsDao _userStatsDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    LoadBalancerDao _loadBalancerDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingRulesDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    HostDetailsDao _hostDetailDao;
+    @Inject
+    NetworkExternalLoadBalancerDao _networkLBDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcProviderDao;
+    @Inject
+    NetworkExternalFirewallDao _networkExternalFirewallDao;
+    @Inject
+    ExternalFirewallDeviceDao _externalFirewallDeviceDao;
+    @Inject
+    protected HostPodDao _podDao = null;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    protected
+    VirtualMachineManager _itMgr;
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    VMTemplateDao _templateDao;
+    @Inject
+    ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Inject
+    VirtualRouterProviderDao _vrProviderDao;
+
+    private long _defaultLbCapacity;
+    private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class);
+
+    @Override
+    @DB
+    public ExternalLoadBalancerDeviceVO addExternalLoadBalancer(long physicalNetworkId, String url, String username, String password, final String deviceName,
+        ServerResource resource, final boolean gslbProvider, final boolean exclusiveGslbProivider,
+        final String gslbSitePublicIp, final String gslbSitePrivateIp) {
+
+        PhysicalNetworkVO pNetwork = null;
+        final NetworkDevice ntwkDevice = NetworkDevice.getNetworkDevice(deviceName);
+        long zoneId;
+
+        if ((ntwkDevice == null) || (url == null) || (username == null) || (resource == null) || (password == null)) {
+            throw new InvalidParameterValueException("Atleast one of the required parameters (url, username, password,"
+                + " server resource, zone id/physical network id) is not specified or a valid parameter.");
+        }
+
+        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+        }
+
+        zoneId = pNetwork.getDataCenterId();
+        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
+            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
+
+        ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), ntwkDevice.getNetworkServiceProvder());
+        if (ntwkSvcProvider == null) {
+            throw new CloudRuntimeException("Network Service Provider: " + ntwkDevice.getNetworkServiceProvder() + " is not enabled in the physical network: " +
+                physicalNetworkId + "to add this device");
+        } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+            throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + " is in shutdown state in the physical network: " +
+                physicalNetworkId + "to add this device");
+        }
+
+        if (gslbProvider) {
+            ExternalLoadBalancerDeviceVO zoneGslbProvider =
+                _externalLoadBalancerDeviceDao.findGslbServiceProvider(physicalNetworkId, ntwkDevice.getNetworkServiceProvder());
+            if (zoneGslbProvider != null) {
+                throw new CloudRuntimeException("There is a GSLB service provider configured in the zone alredy.");
+            }
+        }
+
+        URI uri;
+        try {
+            uri = new URI(url);
+        } catch (Exception e) {
+            s_logger.debug(e);
+            throw new InvalidParameterValueException(e.getMessage());
+        }
+
+        String ipAddress = uri.getHost();
+        Map hostDetails = new HashMap<String, String>();
+        String hostName = getExternalLoadBalancerResourceGuid(pNetwork.getId(), deviceName, ipAddress);
+        hostDetails.put("name", hostName);
+        hostDetails.put("guid", UUID.randomUUID().toString());
+        hostDetails.put("zoneId", String.valueOf(pNetwork.getDataCenterId()));
+        hostDetails.put("ip", ipAddress);
+        hostDetails.put("physicalNetworkId", String.valueOf(pNetwork.getId()));
+        hostDetails.put("username", username);
+        hostDetails.put("password", password);
+        hostDetails.put("deviceName", deviceName);
+
+        // leave parameter validation to be part server resource configure
+        Map<String, String> configParams = new HashMap<String, String>();
+        UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams);
+        hostDetails.putAll(configParams);
+
+        try {
+            resource.configure(hostName, hostDetails);
+
+            final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalLoadBalancer, hostDetails);
+            if (host != null) {
+
+                final boolean dedicatedUse =
+                    (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED))
+                        : false;
+                long capacity = NumbersUtil.parseLong(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_CAPACITY), 0);
+                if (capacity == 0) {
+                    capacity = _defaultLbCapacity;
+                }
+
+                final long capacityFinal = capacity;
+                final PhysicalNetworkVO pNetworkFinal = pNetwork;
+                return Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {
+                    @Override
+                    public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
+                        ExternalLoadBalancerDeviceVO lbDeviceVO =
+                            new ExternalLoadBalancerDeviceVO(host.getId(), pNetworkFinal.getId(), ntwkDevice.getNetworkServiceProvder(), deviceName, capacityFinal,
+                                dedicatedUse, gslbProvider);
+                        if (gslbProvider) {
+                            lbDeviceVO.setGslbSitePublicIP(gslbSitePublicIp);
+                            lbDeviceVO.setGslbSitePrivateIP(gslbSitePrivateIp);
+                            lbDeviceVO.setExclusiveGslbProvider(exclusiveGslbProivider);
+                        }
+                        _externalLoadBalancerDeviceDao.persist(lbDeviceVO);
+                        DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.LOAD_BALANCER_DEVICE_ID, String.valueOf(lbDeviceVO.getId()));
+                        _hostDetailDao.persist(hostDetail);
+
+                        return lbDeviceVO;
+                    }
+                });
+            } else {
+                throw new CloudRuntimeException("Failed to add load balancer device due to internal error.");
+            }
+        } catch (ConfigurationException e) {
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @Override
+    public boolean deleteExternalLoadBalancer(long hostId) {
+        HostVO externalLoadBalancer = _hostDao.findById(hostId);
+        if (externalLoadBalancer == null) {
+            throw new InvalidParameterValueException("Could not find an external load balancer with ID: " + hostId);
+        }
+
+        DetailVO lbHostDetails = _hostDetailDao.findDetail(hostId, ApiConstants.LOAD_BALANCER_DEVICE_ID);
+        long lbDeviceId = Long.parseLong(lbHostDetails.getValue());
+
+        ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
+        if (lbDeviceVo.getAllocationState() == LBDeviceAllocationState.Provider) {
+            // check if cloudstack has provisioned any load balancer appliance on the device before deleting
+            List<ExternalLoadBalancerDeviceVO> lbDevices = _externalLoadBalancerDeviceDao.listAll();
+            if (lbDevices != null) {
+                for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) {
+                    if (lbDevice.getParentHostId() == hostId) {
+                        throw new CloudRuntimeException(
+                            "This load balancer device can not be deleted as there are one or more load balancers applainces provisioned by cloudstack on the device.");
+                    }
+                }
+            }
+        } else {
+            // check if any networks are using this load balancer device
+            List<NetworkExternalLoadBalancerVO> networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
+            if ((networks != null) && !networks.isEmpty()) {
+                throw new CloudRuntimeException("Delete can not be done as there are networks using this load balancer device ");
+            }
+        }
+
+        try {
+            // put the host in maintenance state in order for it to be deleted
+            externalLoadBalancer.setResourceState(ResourceState.Maintenance);
+            _hostDao.update(hostId, externalLoadBalancer);
+            _resourceMgr.deleteHost(hostId, false, false);
+
+            // delete the external load balancer entry
+            _externalLoadBalancerDeviceDao.remove(lbDeviceId);
+
+            return true;
+        } catch (Exception e) {
+            s_logger.debug(e);
+            return false;
+        }
+    }
+
+    @Override
+    public List<Host> listExternalLoadBalancers(long physicalNetworkId, String deviceName) {
+        List<Host> lbHosts = new ArrayList<Host>();
+        NetworkDevice lbNetworkDevice = NetworkDevice.getNetworkDevice(deviceName);
+        PhysicalNetworkVO pNetwork = null;
+
+        pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+
+        if ((pNetwork == null) || (lbNetworkDevice == null)) {
+            throw new InvalidParameterValueException("Atleast one of the required parameter physical networkId, device name is invalid.");
+        }
+
+        PhysicalNetworkServiceProviderVO ntwkSvcProvider =
+            _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), lbNetworkDevice.getNetworkServiceProvder());
+        // if provider not configured in to physical network, then there can be no instances
+        if (ntwkSvcProvider == null) {
+            return null;
+        }
+
+        List<ExternalLoadBalancerDeviceVO> lbDevices =
+            _externalLoadBalancerDeviceDao.listByPhysicalNetworkAndProvider(physicalNetworkId, ntwkSvcProvider.getProviderName());
+        for (ExternalLoadBalancerDeviceVO provderInstance : lbDevices) {
+            lbHosts.add(_hostDao.findById(provderInstance.getHostId()));
+        }
+        return lbHosts;
+    }
+
+    public ExternalLoadBalancerResponse createExternalLoadBalancerResponse(Host externalLoadBalancer) {
+        Map<String, String> lbDetails = _hostDetailDao.findDetails(externalLoadBalancer.getId());
+        ExternalLoadBalancerResponse response = new ExternalLoadBalancerResponse();
+        response.setId(externalLoadBalancer.getUuid());
+        response.setIpAddress(externalLoadBalancer.getPrivateIpAddress());
+        response.setUsername(lbDetails.get("username"));
+        response.setPublicInterface(lbDetails.get("publicInterface"));
+        response.setPrivateInterface(lbDetails.get("privateInterface"));
+        response.setNumRetries(lbDetails.get("numRetries"));
+        return response;
+    }
+
+    public String getExternalLoadBalancerResourceGuid(long physicalNetworkId, String deviceName, String ip) {
+        return physicalNetworkId + "-" + deviceName + "-" + ip;
+    }
+
+    @Override
+    public ExternalLoadBalancerDeviceVO getExternalLoadBalancerForNetwork(Network network) {
+        NetworkExternalLoadBalancerVO lbDeviceForNetwork = _networkExternalLBDao.findByNetworkId(network.getId());
+        if (lbDeviceForNetwork != null) {
+            long lbDeviceId = lbDeviceForNetwork.getExternalLBDeviceId();
+            ExternalLoadBalancerDeviceVO lbDeviceVo = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
+            assert (lbDeviceVo != null);
+            return lbDeviceVo;
+        }
+        return null;
+    }
+
+    public void setExternalLoadBalancerForNetwork(Network network, long externalLBDeviceID) {
+        NetworkExternalLoadBalancerVO lbDeviceForNetwork = new NetworkExternalLoadBalancerVO(network.getId(), externalLBDeviceID);
+        _networkExternalLBDao.persist(lbDeviceForNetwork);
+    }
+
+    @DB
+    protected ExternalLoadBalancerDeviceVO allocateLoadBalancerForNetwork(final Network guestConfig) throws InsufficientCapacityException {
+        boolean retry = true;
+        boolean tryLbProvisioning = false;
+        ExternalLoadBalancerDeviceVO lbDevice = null;
+        long physicalNetworkId = guestConfig.getPhysicalNetworkId();
+        NetworkOfferingVO offering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
+        String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(guestConfig.getId(), Service.Lb);
+
+        while (retry) {
+            GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
+            try {
+                if (deviceMapLock.lock(120)) {
+                    try {
+                        final boolean dedicatedLB = offering.isDedicatedLB(); // does network offering supports a dedicated load balancer?
+
+                        try {
+                            lbDevice = Transaction.execute(new TransactionCallbackWithException<ExternalLoadBalancerDeviceVO, InsufficientCapacityException>() {
+                                @Override
+                                public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
+                                    // FIXME: should the device allocation be done during network implement phase or do a
+                                    // lazy allocation when first rule for the network is configured??
+
+                                    // find a load balancer device for this network as per the network offering
+                                    ExternalLoadBalancerDeviceVO lbDevice = findSuitableLoadBalancerForNetwork(guestConfig, dedicatedLB);
+                                    long lbDeviceId = lbDevice.getId();
+
+                                    // persist the load balancer device id that will be used for this network. Once a network
+                                    // is implemented on a LB device then later on all rules will be programmed on to same device
+                                    NetworkExternalLoadBalancerVO networkLB = new NetworkExternalLoadBalancerVO(guestConfig.getId(), lbDeviceId);
+                                    _networkExternalLBDao.persist(networkLB);
+
+                                    // mark device to be either dedicated or shared use
+                                    lbDevice.setAllocationState(dedicatedLB ? LBDeviceAllocationState.Dedicated : LBDeviceAllocationState.Shared);
+                                    _externalLoadBalancerDeviceDao.update(lbDeviceId, lbDevice);
+                                    return lbDevice;
+                                }
+                            });
+
+                            // allocated load balancer for the network, so skip retry
+                            tryLbProvisioning = false;
+                            retry = false;
+                        } catch (InsufficientCapacityException exception) {
+                            // if already attempted to provision load balancer then throw out of capacity exception,
+                            if (tryLbProvisioning) {
+                                retry = false;
+                                // TODO: throwing warning instead of error for now as its possible another provider can service this network
+                                s_logger.warn("There are no load balancer device with the capacity for implementing this network");
+                                throw exception;
+                            } else {
+                                tryLbProvisioning = true; // if possible provision a LB appliance in to the physical network
+                            }
+                        }
+                    } finally {
+                        deviceMapLock.unlock();
+                    }
+                }
+            } finally {
+                deviceMapLock.releaseRef();
+            }
+
+            // there are no LB devices or there is no free capacity on the devices in the physical network so provision a new LB appliance
+            if (tryLbProvisioning) {
+                // check if LB appliance can be dynamically provisioned
+                List<ExternalLoadBalancerDeviceVO> providerLbDevices =
+                    _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Provider);
+                if ((providerLbDevices != null) && (!providerLbDevices.isEmpty())) {
+                    for (ExternalLoadBalancerDeviceVO lbProviderDevice : providerLbDevices) {
+                        if (lbProviderDevice.getState() == LBDeviceState.Enabled) {
+                            // acquire a private IP from the data center which will be used as management IP of provisioned LB appliance,
+                            DataCenterIpAddressVO dcPrivateIp = _dcDao.allocatePrivateIpAddress(guestConfig.getDataCenterId(), lbProviderDevice.getUuid());
+                            if (dcPrivateIp == null) {
+                                throw new InsufficientNetworkCapacityException("failed to acquire a priavate IP in the zone " + guestConfig.getDataCenterId() +
+                                    " needed for management IP of the load balancer appliance", DataCenter.class, guestConfig.getDataCenterId());
+                            }
+                            Pod pod = _podDao.findById(dcPrivateIp.getPodId());
+                            String lbIP = dcPrivateIp.getIpAddress();
+                            String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
+                            String gateway = pod.getGateway();
+
+                            // send CreateLoadBalancerApplianceCommand to the host capable of provisioning
+                            CreateLoadBalancerApplianceCommand lbProvisionCmd = new CreateLoadBalancerApplianceCommand(lbIP, netmask, gateway);
+                            CreateLoadBalancerApplianceAnswer createLbAnswer = null;
+                            try {
+                                createLbAnswer = (CreateLoadBalancerApplianceAnswer)_agentMgr.easySend(lbProviderDevice.getHostId(), lbProvisionCmd);
+                                if (createLbAnswer == null || !createLbAnswer.getResult()) {
+                                    s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId());
+                                    continue;
+                                }
+                            } catch (Exception agentException) {
+                                s_logger.error("Could not provision load balancer instance on the load balancer device " + lbProviderDevice.getId() + " due to " +
+                                    agentException.getMessage());
+                                continue;
+                            }
+
+                            String username = createLbAnswer.getUsername();
+                            String password = createLbAnswer.getPassword();
+                            String publicIf = createLbAnswer.getPublicInterface();
+                            String privateIf = createLbAnswer.getPrivateInterface();
+
+                            // we have provisioned load balancer so add the appliance as cloudstack provisioned external load balancer
+                            String dedicatedLb = offering.isDedicatedLB() ? "true" : "false";
+                            String capacity = Long.toString(lbProviderDevice.getCapacity());
+
+                            // acquire a public IP to associate with lb appliance (used as subnet IP to make the appliance part of private network)
+                            PublicIp publicIp =
+                                _ipAddrMgr.assignPublicIpAddress(guestConfig.getDataCenterId(), null, _accountMgr.getSystemAccount(), VlanType.VirtualNetwork, null,
+                                    null, false, false);
+                            String publicIPNetmask = publicIp.getVlanNetmask();
+                            String publicIPgateway = publicIp.getVlanGateway();
+                            String publicIP = publicIp.getAddress().toString();
+                            String publicIPVlanTag="";
+                            try {
+                                publicIPVlanTag = BroadcastDomainType.getValue(publicIp.getVlanTag());
+                            } catch (URISyntaxException e) {
+                                s_logger.error("Failed to parse public ip vlan tag" + e.getMessage());
+                            }
+
+                            String url =
+                                "https://" + lbIP + "?publicinterface=" + publicIf + "&privateinterface=" + privateIf + "&lbdevicededicated=" + dedicatedLb +
+                                    "&cloudmanaged=true" + "&publicip=" + publicIP + "&publicipnetmask=" + publicIPNetmask + "&lbdevicecapacity=" + capacity +
+                                    "&publicipvlan=" + publicIPVlanTag + "&publicipgateway=" + publicIPgateway;
+                            ExternalLoadBalancerDeviceVO lbAppliance = null;
+                            try {
+                                lbAppliance =
+                                    addExternalLoadBalancer(physicalNetworkId, url, username, password, createLbAnswer.getDeviceName(),
+                                        createLbAnswer.getServerResource(), false, false, null, null);
+                            } catch (Exception e) {
+                                s_logger.error("Failed to add load balancer appliance in to cloudstack due to " + e.getMessage() +
+                                    ". So provisioned load balancer appliance will be destroyed.");
+                            }
+
+                            if (lbAppliance != null) {
+                                // mark the load balancer as cloudstack managed and set parent host id on which lb appliance is provisioned
+                                ExternalLoadBalancerDeviceVO managedLb = _externalLoadBalancerDeviceDao.findById(lbAppliance.getId());
+                                managedLb.setIsManagedDevice(true);
+                                managedLb.setParentHostId(lbProviderDevice.getHostId());
+                                _externalLoadBalancerDeviceDao.update(lbAppliance.getId(), managedLb);
+                            } else {
+                                // failed to add the provisioned load balancer into cloudstack so destroy the appliance
+                                DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
+                                DestroyLoadBalancerApplianceAnswer answer = null;
+                                try {
+                                    answer = (DestroyLoadBalancerApplianceAnswer)_agentMgr.easySend(lbProviderDevice.getHostId(), lbDeleteCmd);
+                                    if (answer == null || !answer.getResult()) {
+                                        s_logger.warn("Failed to destroy load balancer appliance created");
+                                    } else {
+                                        // release the public & private IP back to dc pool, as the load balancer appliance is now destroyed
+                                        _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null);
+                                        _ipAddrMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
+                                    }
+                                } catch (Exception e) {
+                                    s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage());
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return lbDevice;
+    }
+
+    @Override
+    public ExternalLoadBalancerDeviceVO findSuitableLoadBalancerForNetwork(Network network, boolean dedicatedLb) throws InsufficientCapacityException {
+        long physicalNetworkId = network.getPhysicalNetworkId();
+        List<ExternalLoadBalancerDeviceVO> lbDevices = null;
+        String provider = _ntwkSrvcProviderDao.getProviderForServiceInNetwork(network.getId(), Service.Lb);
+        assert (provider != null);
+
+        if (dedicatedLb) {
+            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
+            if (lbDevices != null && !lbDevices.isEmpty()) {
+                // return first device that is free, fully configured and meant for dedicated use
+                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
+                    if (lbdevice.getState() == LBDeviceState.Enabled && lbdevice.getIsDedicatedDevice()) {
+                        return lbdevice;
+                    }
+                }
+            }
+        } else {
+            // get the LB devices that are already allocated for shared use
+            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Shared);
+
+            if (lbDevices != null) {
+
+                ExternalLoadBalancerDeviceVO maxFreeCapacityLbdevice = null;
+                long maxFreeCapacity = 0;
+
+                // loop through the LB device in the physical network and pick the one with maximum free capacity
+                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
+
+                    // skip if device is not enabled
+                    if (lbdevice.getState() != LBDeviceState.Enabled) {
+                        continue;
+                    }
+
+                    // get the used capacity from the list of guest networks that are mapped to this load balancer
+                    List<NetworkExternalLoadBalancerVO> mappedNetworks = _networkExternalLBDao.listByLoadBalancerDeviceId(lbdevice.getId());
+                    long usedCapacity = ((mappedNetworks == null) || (mappedNetworks.isEmpty())) ? 0 : mappedNetworks.size();
+
+                    // get the configured capacity for this device
+                    long fullCapacity = lbdevice.getCapacity();
+                    if (fullCapacity == 0) {
+                        fullCapacity = _defaultLbCapacity; // if capacity not configured then use the default
+                    }
+
+                    long freeCapacity = fullCapacity - usedCapacity;
+                    if (freeCapacity > 0) {
+                        if (maxFreeCapacityLbdevice == null) {
+                            maxFreeCapacityLbdevice = lbdevice;
+                            maxFreeCapacity = freeCapacity;
+                        } else if (freeCapacity > maxFreeCapacity) {
+                            maxFreeCapacityLbdevice = lbdevice;
+                            maxFreeCapacity = freeCapacity;
+                        }
+                    }
+                }
+
+                // return the device with maximum free capacity and is meant for shared use
+                if (maxFreeCapacityLbdevice != null) {
+                    return maxFreeCapacityLbdevice;
+                }
+            }
+
+            // if we are here then there are no existing LB devices in shared use or the devices in shared use has no
+// free capacity left
+            // so allocate a new load balancer configured for shared use from the pool of free LB devices
+            lbDevices = _externalLoadBalancerDeviceDao.listByProviderAndDeviceAllocationState(physicalNetworkId, provider, LBDeviceAllocationState.Free);
+            if (lbDevices != null && !lbDevices.isEmpty()) {
+                for (ExternalLoadBalancerDeviceVO lbdevice : lbDevices) {
+                    if (lbdevice.getState() == LBDeviceState.Enabled && !lbdevice.getIsDedicatedDevice()) {
+                        return lbdevice;
+                    }
+                }
+            }
+        }
+
+        // there are no devices which capacity
+        throw new InsufficientNetworkCapacityException("Unable to find a load balancing provider with sufficient capcity " + " to implement the network", Network.class,
+            network.getId());
+    }
+
+    @DB
+    protected boolean freeLoadBalancerForNetwork(final Network guestConfig) {
+        GlobalLock deviceMapLock = GlobalLock.getInternLock("LoadBalancerAllocLock");
+
+        try {
+            if (deviceMapLock.lock(120)) {
+                ExternalLoadBalancerDeviceVO lbDevice = Transaction.execute(new TransactionCallback<ExternalLoadBalancerDeviceVO>() {
+                    @Override
+                    public ExternalLoadBalancerDeviceVO doInTransaction(TransactionStatus status) {
+                        // since network is shutdown remove the network mapping to the load balancer device
+                        NetworkExternalLoadBalancerVO networkLBDevice = _networkExternalLBDao.findByNetworkId(guestConfig.getId());
+                        long lbDeviceId = networkLBDevice.getExternalLBDeviceId();
+                        _networkExternalLBDao.remove(networkLBDevice.getId());
+
+                        List<NetworkExternalLoadBalancerVO> ntwksMapped = _networkExternalLBDao.listByLoadBalancerDeviceId(networkLBDevice.getExternalLBDeviceId());
+                        ExternalLoadBalancerDeviceVO lbDevice = _externalLoadBalancerDeviceDao.findById(lbDeviceId);
+                        boolean lbInUse = !(ntwksMapped == null || ntwksMapped.isEmpty());
+                        boolean lbCloudManaged = lbDevice.getIsManagedDevice();
+
+                        if (!lbInUse && !lbCloudManaged) {
+                            // this is the last network mapped to the load balancer device so set device allocation state to be free
+                            lbDevice.setAllocationState(LBDeviceAllocationState.Free);
+                            _externalLoadBalancerDeviceDao.update(lbDevice.getId(), lbDevice);
+                        }
+
+                        // commit the changes before sending agent command to destroy cloudstack managed LB
+                        if (!lbInUse && lbCloudManaged) {
+                            return lbDevice;
+                        } else {
+                            return null;
+                        }
+                    }
+                });
+
+                if (lbDevice != null) {
+                    // send DestroyLoadBalancerApplianceCommand to the host where load balancer appliance is provisioned
+                    Host lbHost = _hostDao.findById(lbDevice.getHostId());
+                    String lbIP = lbHost.getPrivateIpAddress();
+                    DestroyLoadBalancerApplianceCommand lbDeleteCmd = new DestroyLoadBalancerApplianceCommand(lbIP);
+                    DestroyLoadBalancerApplianceAnswer answer = null;
+                    try {
+                        answer = (DestroyLoadBalancerApplianceAnswer)_agentMgr.easySend(lbDevice.getParentHostId(), lbDeleteCmd);
+                        if (answer == null || !answer.getResult()) {
+                            s_logger.warn("Failed to destoy load balancer appliance used by the network"
+                                    + guestConfig.getId() + " due to " + answer == null ? "communication error with agent"
+                                    : answer.getDetails());
+                        }
+                    } catch (Exception e) {
+                        s_logger.warn("Failed to destroy load balancer appliance used by the network" + guestConfig.getId() + " due to " + e.getMessage());
+                    }
+
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully destroyed load balancer appliance used for the network" + guestConfig.getId());
+                    }
+                    deviceMapLock.unlock();
+
+                    // remove the provisioned load balancer appliance from cloudstack
+                    deleteExternalLoadBalancer(lbHost.getId());
+
+                    // release the private IP back to dc pool, as the load balancer appliance is now destroyed
+                    _dcDao.releasePrivateIpAddress(lbHost.getPrivateIpAddress(), guestConfig.getDataCenterId(), null);
+
+                    // release the public IP allocated for this LB appliance
+                    DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip");
+                    IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString());
+                    _ipAddrMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
+                } else {
+                    deviceMapLock.unlock();
+                }
+
+                return true;
+            } else {
+                s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + "as failed to acquire lock ");
+                return false;
+            }
+        } catch (Exception exception) {
+            s_logger.error("Failed to release load balancer device for the network" + guestConfig.getId() + " due to " + exception.getMessage());
+        } finally {
+            deviceMapLock.releaseRef();
+        }
+
+        return false;
+    }
+
+    private void applyStaticNatRuleForInlineLBRule(DataCenterVO zone, Network network, boolean revoked, String publicIp, String privateIp)
+        throws ResourceUnavailableException {
+        List<StaticNat> staticNats = new ArrayList<StaticNat>();
+        IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0);
+        StaticNatImpl staticNat = new StaticNatImpl(ipVO.getAllocatedToAccountId(), ipVO.getAllocatedInDomainId(), network.getId(), ipVO.getId(), privateIp, revoked);
+        staticNats.add(staticNat);
+        StaticNatServiceProvider element = _networkMgr.getStaticNatProviderForNetwork(network);
+        element.applyStaticNats(network, staticNats);
+    }
+
+    private enum MappingState {
+        Create, Remove, Unchanged,
+    };
+
+    private class MappingNic {
+        private Nic nic;
+        private MappingState state;
+
+        public Nic getNic() {
+            return nic;
+        }
+
+        public void setNic(Nic nic) {
+            this.nic = nic;
+        }
+
+        public MappingState getState() {
+            return state;
+        }
+
+        public void setState(MappingState state) {
+            this.state = state;
+        }
+    };
+
+    private MappingNic getLoadBalancingIpNic(DataCenterVO zone, Network network, long sourceIpId, boolean revoked, String existedGuestIp)
+        throws ResourceUnavailableException {
+        String srcIp = _networkModel.getIp(sourceIpId).getAddress().addr();
+        InlineLoadBalancerNicMapVO mapping = _inlineLoadBalancerNicMapDao.findByPublicIpAddress(srcIp);
+        Nic loadBalancingIpNic = null;
+        MappingNic nic = new MappingNic();
+        nic.setState(MappingState.Unchanged);
+        if (!revoked) {
+            if (mapping == null) {
+                // Acquire a new guest IP address and save it as the load balancing IP address
+                String loadBalancingIpAddress = existedGuestIp;
+
+                if (loadBalancingIpAddress == null) {
+                    if (network.getGuestType() == Network.GuestType.Isolated) {
+                        loadBalancingIpAddress = _ipAddrMgr.acquireGuestIpAddress(network, null);
+                    } else if (network.getGuestType() == Network.GuestType.Shared) {
+                        try {
+                            PublicIp directIp =
+                                _ipAddrMgr.assignPublicIpAddress(network.getDataCenterId(), null, _accountDao.findById(network.getAccountId()), VlanType.DirectAttached,
+                                    network.getId(), null, true, false);
+                            loadBalancingIpAddress = directIp.getAddress().addr();
+                        } catch (InsufficientCapacityException capException) {
+                            String msg = "Ran out of guest IP addresses from the shared network.";
+                            s_logger.error(msg);
+                            throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+                        }
+                    }
+                }
+
+                if (loadBalancingIpAddress == null) {
+                    String msg = "Ran out of guest IP addresses.";
+                    s_logger.error(msg);
+                    throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+                }
+
+                // If a NIC doesn't exist for the load balancing IP address, create one
+                loadBalancingIpNic = _nicDao.findByIp4AddressAndNetworkId(loadBalancingIpAddress, network.getId());
+                if (loadBalancingIpNic == null) {
+                    loadBalancingIpNic = _networkMgr.savePlaceholderNic(network, loadBalancingIpAddress, null, null);
+                }
+
+                // Save a mapping between the source IP address and the load balancing IP address NIC
+                mapping = new InlineLoadBalancerNicMapVO(srcIp, loadBalancingIpNic.getId());
+                _inlineLoadBalancerNicMapDao.persist(mapping);
+
+                // On the firewall provider for the network, create a static NAT rule between the source IP
+                // address and the load balancing IP address
+                try {
+                    applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
+                } catch (ResourceUnavailableException ex) {
+                    // Rollback db operation
+                    _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
+                    _nicDao.expunge(loadBalancingIpNic.getId());
+                    throw ex;
+                }
+
+                s_logger.debug("Created static nat rule for inline load balancer");
+                nic.setState(MappingState.Create);
+            } else {
+                loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
+            }
+        } else {
+            if (mapping != null) {
+                // Find the NIC that the mapping refers to
+                loadBalancingIpNic = _nicDao.findById(mapping.getNicId());
+
+                int count = _ipAddrMgr.getRuleCountForIp(sourceIpId, Purpose.LoadBalancing, FirewallRule.State.Active);
+                if (count == 0) {
+                    // On the firewall provider for the network, delete the static NAT rule between the source IP
+                    // address and the load balancing IP address
+                    applyStaticNatRuleForInlineLBRule(zone, network, revoked, srcIp, loadBalancingIpNic.getIPv4Address());
+
+                    // Delete the mapping between the source IP address and the load balancing IP address
+                    _inlineLoadBalancerNicMapDao.expunge(mapping.getId());
+
+                    // Delete the NIC
+                    _nicDao.expunge(loadBalancingIpNic.getId());
+
+                    s_logger.debug("Revoked static nat rule for inline load balancer");
+                    nic.setState(MappingState.Remove);
+                }
+            } else {
+                s_logger.debug("Revoking a rule for an inline load balancer that has not been programmed yet.");
+                nic.setNic(null);
+                return nic;
+            }
+        }
+
+        nic.setNic(loadBalancingIpNic);
+        return nic;
+    }
+
+    public boolean isNccServiceProvider(Network network) {
+        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if(null!= networkOffering && networkOffering.getServicePackage() != null ) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) {
+        long zoneId = guestConfig.getDataCenterId();
+        return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter);
+    }
+
+    @Override
+    public boolean applyLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
+        // Find the external load balancer in this zone
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+
+        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
+            return true;
+        }
+
+        HostVO externalLoadBalancer = null;
+
+        if(isNccServiceProvider(network)) {
+            externalLoadBalancer  = getNetScalerControlCenterForNetwork(network);
+        } else {
+            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+            if (lbDeviceVO == null) {
+                s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
+                return true;
+            } else {
+                externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            }
+        }
+
+
+
+        boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network);
+
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() +
+                "; this network is not implemented. Skipping backend commands.");
+            return true;
+        }
+
+        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
+        List<MappingState> mappingStates = new ArrayList<MappingState>();
+        for (int i = 0; i < loadBalancingRules.size(); i++) {
+            LoadBalancingRule rule = loadBalancingRules.get(i);
+
+            boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke));
+            String protocol = rule.getProtocol();
+            String algorithm = rule.getAlgorithm();
+            String uuid = rule.getUuid();
+            String srcIp = rule.getSourceIp().addr();
+            String srcIpVlan = null;
+            String srcIpGateway = null;
+            String srcIpNetmask = null;
+            Long vlanid =  _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId();
+            if(vlanid != null ) {
+              VlanVO publicVlan =   _vlanDao.findById(vlanid);
+              srcIpVlan =  publicVlan.getVlanTag();
+              srcIpGateway = publicVlan.getVlanGateway();
+              srcIpNetmask = publicVlan.getVlanNetmask();
+            }
+            int srcPort = rule.getSourcePortStart();
+            List<LbDestination> destinations = rule.getDestinations();
+
+            if (externalLoadBalancerIsInline) {
+                long ipId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
+                MappingNic nic = getLoadBalancingIpNic(zone, network, ipId, revoked, null);
+                mappingStates.add(nic.getState());
+                Nic loadBalancingIpNic = nic.getNic();
+                if (loadBalancingIpNic == null) {
+                    continue;
+                }
+
+                // Change the source IP address for the load balancing rule to be the load balancing IP address
+                srcIp = loadBalancingIpNic.getIPv4Address();
+            }
+
+            if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) {
+                boolean inline = _networkMgr.isNetworkInlineMode(network);
+                LoadBalancerTO loadBalancer =
+                    new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(),
+                        rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
+                loadBalancer.setNetworkId(network.getId());
+                loadBalancer.setSrcIpVlan(srcIpVlan);
+                loadBalancer.setSrcIpNetmask(srcIpNetmask);
+                loadBalancer.setSrcIpGateway(srcIpGateway);
+                if (rule.isAutoScaleConfig()) {
+                    loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
+                }
+                loadBalancersToApply.add(loadBalancer);
+            }
+        }
+
+        try {
+            if (loadBalancersToApply.size() > 0) {
+                int numLoadBalancersForCommand = loadBalancersToApply.size();
+                LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
+                LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null);
+                long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
+                cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
+                Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+                if (answer == null || !answer.getResult()) {
+                    String details = (answer != null) ? answer.getDetails() : "details unavailable";
+                    String msg = "Unable to apply load balancer rules to the external load balancer appliance in zone " + zone.getName() + " due to: " + details + ".";
+                    s_logger.error(msg);
+                    throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+                }
+            }
+        } catch (Exception ex) {
+            if (externalLoadBalancerIsInline) {
+                s_logger.error("Rollbacking static nat operation of inline mode load balancing due to error on applying LB rules!");
+                String existedGuestIp = loadBalancersToApply.get(0).getSrcIp();
+                // Rollback static NAT operation in current session
+                for (int i = 0; i < loadBalancingRules.size(); i++) {
+                    LoadBalancingRule rule = loadBalancingRules.get(i);
+                    MappingState state = mappingStates.get(i);
+                    boolean revoke;
+                    if (state == MappingState.Create) {
+                        revoke = true;
+                    } else if (state == MappingState.Remove) {
+                        revoke = false;
+                    } else {
+                        continue;
+                    }
+                    long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
+                    getLoadBalancingIpNic(zone, network, sourceIpId, revoke, existedGuestIp);
+                }
+            }
+            throw new ResourceUnavailableException(ex.getMessage(), DataCenter.class, network.getDataCenterId());
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean manageGuestNetworkWithExternalLoadBalancer(boolean add, Network guestConfig) throws ResourceUnavailableException, InsufficientCapacityException {
+        if (guestConfig.getTrafficType() != TrafficType.Guest) {
+            s_logger.trace("External load balancer can only be used for guest networks.");
+            return false;
+        }
+
+        long zoneId = guestConfig.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        HostVO externalLoadBalancer = null;
+
+        if (add) {
+            ExternalLoadBalancerDeviceVO lbDeviceVO = null;
+            // on restart network, device could have been allocated already, skip allocation if a device is assigned
+            lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
+            if (lbDeviceVO == null) {
+                // allocate a load balancer device for the network
+                lbDeviceVO = allocateLoadBalancerForNetwork(guestConfig);
+                if (lbDeviceVO == null) {
+                    String msg = "failed to alloacate a external load balancer for the network " + guestConfig.getId();
+                    s_logger.error(msg);
+                    throw new InsufficientNetworkCapacityException(msg, DataCenter.class, guestConfig.getDataCenterId());
+                }
+            }
+            externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            s_logger.debug("Allocated external load balancer device:" + lbDeviceVO.getId() + " for the network: " + guestConfig.getId());
+        } else {
+            // find the load balancer device allocated for the network
+            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(guestConfig);
+            if (lbDeviceVO == null) {
+                s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network."
+                    + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
+                return true;
+            }
+
+            externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            assert (externalLoadBalancer != null) : "There is no device assigned to this network how did shutdown network ended up here??";
+        }
+
+        // Send a command to the external load balancer to implement or shutdown the guest network
+        String guestVlanTag = BroadcastDomainType.getValue(guestConfig.getBroadcastUri());
+        String selfIp = null;
+        String guestVlanNetmask = NetUtils.cidr2Netmask(guestConfig.getCidr());
+        Integer networkRate = _networkModel.getNetworkRate(guestConfig.getId(), null);
+
+        if (add) {
+            // on restart network, network could have already been implemented. If already implemented then return
+            Nic selfipNic = getPlaceholderNic(guestConfig);
+            if (selfipNic != null) {
+                return true;
+            }
+
+            // Acquire a self-ip address from the guest network IP address range
+            selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
+            if (selfIp == null) {
+                String msg = "failed to acquire guest IP address so not implementing the network on the external load balancer ";
+                s_logger.error(msg);
+                throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
+            }
+        } else {
+            // get the self-ip used by the load balancer
+            Nic selfipNic = getPlaceholderNic(guestConfig);
+            if (selfipNic == null) {
+                s_logger.warn("Network shutdwon requested on external load balancer element, which did not implement the network."
+                    + " Either network implement failed half way through or already network shutdown is completed. So just returning.");
+                return true;
+            }
+            selfIp = selfipNic.getIPv4Address();
+        }
+
+        // It's a hack, using isOneToOneNat field for indicate if it's inline or not
+        boolean inline = _networkMgr.isNetworkInlineMode(guestConfig);
+        IpAddressTO ip =
+            new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, guestVlanTag, selfIp, guestVlanNetmask, null, networkRate, inline);
+        IpAddressTO[] ips = new IpAddressTO[1];
+        ips[0] = ip;
+        IpAssocCommand cmd = new IpAssocCommand(ips);
+        Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+
+        if (answer == null || !answer.getResult()) {
+            String action = add ? "implement" : "shutdown";
+            String answerDetails = (answer != null) ? answer.getDetails() : null;
+            answerDetails = (answerDetails != null) ? " due to " + answerDetails : "";
+            String msg = "External load balancer was unable to " + action + " the guest network on the external load balancer in zone " + zone.getName() + answerDetails;
+            s_logger.error(msg);
+            throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId());
+        }
+
+        if (add) {
+            // Insert a new NIC for this guest network to reserve the self IP
+            _networkMgr.savePlaceholderNic(guestConfig, selfIp, null, null);
+        } else {
+            // release the self-ip obtained from guest network
+            Nic selfipNic = getPlaceholderNic(guestConfig);
+            _nicDao.remove(selfipNic.getId());
+
+            // release the load balancer allocated for the network
+            boolean releasedLB = freeLoadBalancerForNetwork(guestConfig);
+            if (!releasedLB) {
+                String msg = "Failed to release the external load balancer used for the network: " + guestConfig.getId();
+                s_logger.error(msg);
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            Account account = _accountDao.findByIdIncludingRemoved(guestConfig.getAccountId());
+            String action = add ? "implemented" : "shut down";
+            s_logger.debug("External load balancer has " + action + " the guest network for account " + account.getAccountName() + "(id = " + account.getAccountId() +
+                ") with VLAN tag " + guestVlanTag);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        _defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) {
+            return null;
+        }
+        if(host.getName().equalsIgnoreCase("NetScalerControlCenter")) {
+            host.setType(Host.Type.NetScalerControlCenter);
+        }
+        else {
+            host.setType(Host.Type.ExternalLoadBalancer);
+        }
+        return host;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        if (host.getType() != com.cloud.host.Host.Type.ExternalLoadBalancer) {
+            return null;
+        }
+        return new DeleteHostAnswer(true);
+    }
+
+    protected IpDeployer getIpDeployerForInlineMode(Network network) {
+        //We won't deploy IP, instead the firewall in front of us would do it
+        List<Provider> providers = _networkMgr.getProvidersForServiceInNetwork(network, Service.Firewall);
+        //Only support one provider now
+        if (providers == null) {
+            s_logger.error("Cannot find firewall provider for network " + network.getId());
+            return null;
+        }
+        if (providers.size() != 1) {
+            s_logger.error("Found " + providers.size() + " firewall provider for network " + network.getId());
+            return null;
+        }
+
+        NetworkElement element = _networkModel.getElementImplementingProvider(providers.get(0).getName());
+        if (!(element instanceof IpDeployer)) {
+            s_logger.error("The firewall provider for network " + network.getName() + " don't have ability to deploy IP address!");
+            return null;
+        }
+        s_logger.info("Let " + element.getName() + " handle ip association for " + getName() + " in network " + network.getId());
+        return (IpDeployer)element;
+    }
+
+    @Override
+    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
+
+        // Find the external load balancer in this zone
+        long zoneId = network.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+
+        if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
+            return null;
+        }
+
+        HostVO externalLoadBalancer = null;
+
+        if(isNccServiceProvider(network)) {
+            externalLoadBalancer  = getNetScalerControlCenterForNetwork(network);
+        } else {
+            ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
+            if (lbDeviceVO == null) {
+                s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning");
+                return null;
+            } else {
+                externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+            }
+        }
+
+        boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network);
+
+        if (network.getState() == Network.State.Allocated) {
+            s_logger.debug("External load balancer was asked to apply LB rules for network with ID " + network.getId() +
+                "; this network is not implemented. Skipping backend commands.");
+            return null;
+        }
+
+        List<LoadBalancerTO> loadBalancersToApply = new ArrayList<LoadBalancerTO>();
+        List<MappingState> mappingStates = new ArrayList<MappingState>();
+        for (final LoadBalancingRule rule : loadBalancingRules) {
+            boolean revoked = (FirewallRule.State.Revoke.equals(rule.getState()));
+            String protocol = rule.getProtocol();
+            String algorithm = rule.getAlgorithm();
+            String uuid = rule.getUuid();
+            String srcIp = rule.getSourceIp().addr();
+            int srcPort = rule.getSourcePortStart();
+            List<LbDestination> destinations = rule.getDestinations();
+
+            if (externalLoadBalancerIsInline) {
+                long sourceIpId = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getId();
+                MappingNic nic = getLoadBalancingIpNic(zone, network, sourceIpId, revoked, null);
+                mappingStates.add(nic.getState());
+                Nic loadBalancingIpNic = nic.getNic();
+                if (loadBalancingIpNic == null) {
+                    continue;
+                }
+
+                // Change the source IP address for the load balancing rule to
+                // be the load balancing IP address
+                srcIp = loadBalancingIpNic.getIPv4Address();
+            }
+
+            if ((destinations != null && !destinations.isEmpty()) || !rule.isAutoScaleConfig()) {
+                boolean inline = _networkMgr.isNetworkInlineMode(network);
+                LoadBalancerTO loadBalancer =
+                    new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(),
+                        rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol());
+                loadBalancersToApply.add(loadBalancer);
+            }
+        }
+
+        try {
+            if (loadBalancersToApply.size() > 0) {
+                int numLoadBalancersForCommand = loadBalancersToApply.size();
+                LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
+                HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
+                long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
+                cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
+
+                HealthCheckLBConfigAnswer answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
+                // easySend will return null on error
+                return answer == null ? null : answer.getLoadBalancers();
+            }
+        } catch (Exception ex) {
+            s_logger.error("Exception Occured ", ex);
+        }
+        //null return is handled by clients
+        return null;
+    }
+
+    private NicVO getPlaceholderNic(Network network) {
+        List<NicVO> guestIps = _nicDao.listByNetworkId(network.getId());
+        for (NicVO guestIp : guestIps) {
+            // only external firewall and external load balancer will create NicVO with PlaceHolder reservation strategy
+            if (guestIp.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && guestIp.getVmType() == null && guestIp.getReserver() == null &&
+                !guestIp.getIPv4Address().equals(network.getGateway())) {
+                return guestIp;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java b/server/src/main/java/com/cloud/network/ExternalNetworkDeviceManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/ExternalNetworkDeviceManagerImpl.java
rename to server/src/main/java/com/cloud/network/ExternalNetworkDeviceManagerImpl.java
diff --git a/server/src/com/cloud/network/IpAddrAllocator.java b/server/src/main/java/com/cloud/network/IpAddrAllocator.java
similarity index 100%
rename from server/src/com/cloud/network/IpAddrAllocator.java
rename to server/src/main/java/com/cloud/network/IpAddrAllocator.java
diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
new file mode 100644
index 0000000..c152034
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
@@ -0,0 +1,2172 @@
+// 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.network;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import com.cloud.dc.DomainVlanMapVO;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.region.PortableIp;
+import org.apache.cloudstack.region.PortableIpDao;
+import org.apache.cloudstack.region.PortableIpVO;
+import org.apache.cloudstack.region.Region;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterIpAddressVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.AccountVlanMapDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.DomainVlanMapDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.Domain;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.AccountLimitException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.NetworkAccountDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDomainDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.IpDeployingRequester;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.org.Grouping;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Journal;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class IpAddressManagerImpl extends ManagerBase implements IpAddressManager, Configurable {
+    private static final Logger s_logger = Logger.getLogger(IpAddressManagerImpl.class);
+
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    UserDao _userDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    AccountVlanMapDao _accountVlanMapDao;
+    @Inject
+    DomainVlanMapDao _domainVlanMapDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    NetworkDao _networksDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    RulesManager _rulesMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    RemoteAccessVpnService _vpnMgr;
+    @Inject
+    PodVlanMapDao _podVlanMapDao;
+    @Inject
+    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
+    @Inject
+    AccountGuestVlanMapDao _accountGuestVlanMapDao;
+    @Inject
+    DataCenterVnetDao _datacenterVnetDao;
+    @Inject
+    NetworkAccountDao _networkAccountDao;
+    @Inject
+    protected NicIpAliasDao _nicIpAliasDao;
+    @Inject
+    protected IPAddressDao _publicIpAddressDao;
+    @Inject
+    NetworkDomainDao _networkDomainDao;
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    FirewallManager _firewallMgr;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _pNSPDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingRulesDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    StorageNetworkManager _stnwMgr;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    PrivateIpDao _privateIpDao;
+    @Inject
+    NetworkACLManager _networkACLMgr;
+    @Inject
+    UsageEventDao _usageEventDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    UserIpv6AddressDao _ipv6Dao;
+    @Inject
+    Ipv6AddressManager _ipv6Mgr;
+    @Inject
+    PortableIpDao _portableIpDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    DataCenterIpAddressDao _privateIPAddressDao;
+    @Inject
+    HostPodDao _hpDao;
+
+    SearchBuilder<IPAddressVO> AssignIpAddressSearch;
+    SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
+    private static final Object allocatedLock = new Object();
+
+    static Boolean rulesContinueOnErrFlag = true;
+
+    private static final ConfigKey<Boolean> SystemVmPublicIpReservationModeStrictness = new ConfigKey<Boolean>("Advanced",
+            Boolean.class, "system.vm.public.ip.reservation.mode.strictness", "false",
+            "If enabled, the use of System VMs public IP reservation is strict, preferred if not.", false, ConfigKey.Scope.Global);
+
+    private Random rand = new Random(System.currentTimeMillis());
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) {
+        // populate providers
+        Map<Network.Service, Set<Network.Provider>> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
+
+        defaultProviders.add(Network.Provider.VirtualRouter);
+        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultSharedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+
+        Map<Network.Service, Set<Network.Provider>> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
+        defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+        defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+        Map<Network.Service, Set<Network.Provider>> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        Set<Provider> sgProviders = new HashSet<Provider>();
+        sgProviders.add(Provider.SecurityGroupProvider);
+        defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders);
+
+        Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultProviders.clear();
+        defaultProviders.add(Network.Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, defaultProviders);
+
+        Map<Network.Service, Set<Network.Provider>> defaultVPCOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        defaultProviders.clear();
+        defaultProviders.add(Network.Provider.VirtualRouter);
+        defaultVPCOffProviders.put(Service.Dhcp, defaultProviders);
+        defaultVPCOffProviders.put(Service.Dns, defaultProviders);
+        defaultVPCOffProviders.put(Service.UserData, defaultProviders);
+        defaultVPCOffProviders.put(Service.NetworkACL, defaultProviders);
+        defaultVPCOffProviders.put(Service.Gateway, defaultProviders);
+        defaultVPCOffProviders.put(Service.Lb, defaultProviders);
+        defaultVPCOffProviders.put(Service.SourceNat, defaultProviders);
+        defaultVPCOffProviders.put(Service.StaticNat, defaultProviders);
+        defaultVPCOffProviders.put(Service.PortForwarding, defaultProviders);
+        defaultVPCOffProviders.put(Service.Vpn, defaultProviders);
+
+        //#8 - network offering with internal lb service
+        Map<Network.Service, Set<Network.Provider>> internalLbOffProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        Set<Network.Provider> defaultVpcProvider = new HashSet<Network.Provider>();
+        defaultVpcProvider.add(Network.Provider.VPCVirtualRouter);
+
+        Set<Network.Provider> defaultInternalLbProvider = new HashSet<Network.Provider>();
+        defaultInternalLbProvider.add(Network.Provider.InternalLbVm);
+
+        internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider);
+        internalLbOffProviders.put(Service.Dns, defaultVpcProvider);
+        internalLbOffProviders.put(Service.UserData, defaultVpcProvider);
+        internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider);
+        internalLbOffProviders.put(Service.Gateway, defaultVpcProvider);
+        internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider);
+        internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider);
+
+        Map<Network.Service, Set<Network.Provider>> netscalerServiceProviders = new HashMap<Network.Service, Set<Network.Provider>>();
+        Set<Network.Provider> vrProvider = new HashSet<Network.Provider>();
+        vrProvider.add(Provider.VirtualRouter);
+        Set<Network.Provider> sgProvider = new HashSet<Network.Provider>();
+        sgProvider.add(Provider.SecurityGroupProvider);
+        Set<Network.Provider> nsProvider = new HashSet<Network.Provider>();
+        nsProvider.add(Provider.Netscaler);
+        netscalerServiceProviders.put(Service.Dhcp, vrProvider);
+        netscalerServiceProviders.put(Service.Dns, vrProvider);
+        netscalerServiceProviders.put(Service.UserData, vrProvider);
+        netscalerServiceProviders.put(Service.SecurityGroup, sgProvider);
+        netscalerServiceProviders.put(Service.StaticNat, nsProvider);
+        netscalerServiceProviders.put(Service.Lb, nsProvider);
+
+        Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
+        Map<Capability, String> elb = new HashMap<Capability, String>();
+        elb.put(Capability.ElasticLb, "true");
+        Map<Capability, String> eip = new HashMap<Capability, String>();
+        eip.put(Capability.ElasticIp, "true");
+        serviceCapabilityMap.put(Service.Lb, elb);
+        serviceCapabilityMap.put(Service.StaticNat, eip);
+
+        AssignIpAddressSearch = _ipAddressDao.createSearchBuilder();
+        AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ);
+        AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
+        AssignIpAddressSearch.and("vlanId", AssignIpAddressSearch.entity().getVlanId(), Op.IN);
+        if (SystemVmPublicIpReservationModeStrictness.value()) {
+            AssignIpAddressSearch.and("forSystemVms", AssignIpAddressSearch.entity().isForSystemVms(), Op.EQ);
+        }
+        SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
+        vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
+        vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
+        AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
+        AssignIpAddressSearch.done();
+
+        AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder();
+        AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ);
+        AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL);
+        AssignIpAddressFromPodVlanSearch.and("vlanId", AssignIpAddressFromPodVlanSearch.entity().getVlanId(), Op.IN);
+
+        SearchBuilder<VlanVO> podVlanSearch = _vlanDao.createSearchBuilder();
+        podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ);
+        podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ);
+        SearchBuilder<PodVlanMapVO> podVlanMapSB = _podVlanMapDao.createSearchBuilder();
+        podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ);
+        AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(),
+                JoinType.INNER);
+        AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
+        AssignIpAddressFromPodVlanSearch.done();
+
+        Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao));
+
+        if (RulesContinueOnError.value() != null) {
+            rulesContinueOnErrFlag = RulesContinueOnError.value();
+        }
+
+        s_logger.info("IPAddress Manager is configured.");
+
+        return true;
+    }
+
+    private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException,
+            ConcurrentOperationException {
+        Account caller = CallContext.current().getCallingAccount();
+        long callerUserId = CallContext.current().getCallingUserId();
+        // check permissions
+        _accountMgr.checkAccess(caller, null, false, ipOwner);
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+
+        return allocateIp(ipOwner, isSystem, caller, callerUserId, zone, null);
+    }
+
+    // An IP association is required in below cases
+    //  1.there is at least one public IP associated with the network on which first rule (PF/static NAT/LB) is being applied.
+    //  2.last rule (PF/static NAT/LB) on the public IP has been revoked. So the public IP should not be associated with any provider
+    boolean checkIfIpAssocRequired(Network network, boolean postApplyRules, List<PublicIp> publicIps) {
+
+        if (network.getState() == Network.State.Implementing) {
+            return true;
+        }
+
+        for (PublicIp ip : publicIps) {
+            if (ip.isSourceNat()) {
+                continue;
+            } else if (ip.isOneToOneNat()) {
+                continue;
+            } else {
+                Long totalCount = null;
+                Long revokeCount = null;
+                Long activeCount = null;
+                Long addCount = null;
+
+                totalCount = _firewallDao.countRulesByIpId(ip.getId());
+                if (postApplyRules) {
+                    revokeCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Revoke);
+                } else {
+                    activeCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active);
+                    addCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Add);
+                }
+
+                if (totalCount == null || totalCount.longValue() == 0L) {
+                    continue;
+                }
+
+                if (postApplyRules) {
+
+                    if (revokeCount != null && revokeCount.longValue() == totalCount.longValue()) {
+                        s_logger.trace("All rules are in Revoke state, have to dis-assiciate IP from the backend");
+                        return true;
+                    }
+                } else {
+                    if (activeCount != null && activeCount > 0) {
+                        if (network.getVpcId() != null) {
+                            // If there are more than one ip in the vpc tier network and services configured on it.
+                            // restart network with cleanup case, on network reprogramming this needs to be return true
+                            // because on the VR ips has removed. In VPC case restart tier network with cleanup will not
+                            // reboot the VR. So ipassoc is needed.
+                            return true;
+                        }
+                        continue;
+                    } else if (addCount != null && addCount.longValue() == totalCount.longValue()) {
+                        s_logger.trace("All rules are in Add state, have to assiciate IP with the backend");
+                        return true;
+                    } else {
+                        continue;
+                    }
+                }
+            }
+        }
+
+        // there are no IP's corresponding to this network that need to be associated with provider
+        return false;
+    }
+
+    @Override
+    public boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
+            throws ResourceUnavailableException {
+        if (rules == null || rules.size() == 0) {
+            s_logger.debug("There are no rules to forward to the network elements");
+            return true;
+        }
+
+        boolean success = true;
+        Network network = _networksDao.findById(rules.get(0).getNetworkId());
+        FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
+        List<PublicIp> publicIps = new ArrayList<PublicIp>();
+
+        if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
+            // get the list of public ip's owned by the network
+            List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
+            if (userIps != null && !userIps.isEmpty()) {
+                for (IPAddressVO userIp : userIps) {
+                    PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                    publicIps.add(publicIp);
+                }
+            }
+        }
+        // rules can not programmed unless IP is associated with network service provider, so run IP assoication for
+        // the network so as to ensure IP is associated before applying rules (in add state)
+        if (checkIfIpAssocRequired(network, false, publicIps)) {
+            applyIpAssociations(network, false, continueOnError, publicIps);
+        }
+
+        try {
+            applier.applyRules(network, purpose, rules);
+        } catch (ResourceUnavailableException e) {
+            if (!continueOnError) {
+                throw e;
+            }
+            s_logger.warn("Problems with applying " + purpose + " rules but pushing on", e);
+            success = false;
+        }
+
+        // if there are no active rules associated with a public IP, then public IP need not be associated with a provider.
+        // This IPAssoc ensures, public IP is dis-associated after last active rule is revoked.
+        if (checkIfIpAssocRequired(network, true, publicIps)) {
+            applyIpAssociations(network, true, continueOnError, publicIps);
+        }
+
+        return success;
+    }
+
+    protected boolean cleanupIpResources(long ipId, long userId, Account caller) {
+        boolean success = true;
+
+        // Revoke all firewall rules for the ip
+        try {
+            s_logger.debug("Revoking all " + Purpose.Firewall + "rules as a part of public IP id=" + ipId + " release...");
+            if (!_firewallMgr.revokeFirewallRulesForIp(ipId, userId, caller)) {
+                s_logger.warn("Unable to revoke all the firewall rules for ip id=" + ipId + " as a part of ip release");
+                success = false;
+            }
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to revoke all firewall rules for ip id=" + ipId + " as a part of ip release", e);
+            success = false;
+        }
+
+        // Revoke all PF/Static nat rules for the ip
+        try {
+            s_logger.debug("Revoking all " + Purpose.PortForwarding + "/" + Purpose.StaticNat + " rules as a part of public IP id=" + ipId + " release...");
+            if (!_rulesMgr.revokeAllPFAndStaticNatRulesForIp(ipId, userId, caller)) {
+                s_logger.warn("Unable to revoke all the port forwarding rules for ip id=" + ipId + " as a part of ip release");
+                success = false;
+            }
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to revoke all the port forwarding rules for ip id=" + ipId + " as a part of ip release", e);
+            success = false;
+        }
+
+        s_logger.debug("Revoking all " + Purpose.LoadBalancing + " rules as a part of public IP id=" + ipId + " release...");
+        if (!_lbMgr.removeAllLoadBalanacersForIp(ipId, caller, userId)) {
+            s_logger.warn("Unable to revoke all the load balancer rules for ip id=" + ipId + " as a part of ip release");
+            success = false;
+        }
+
+        // remote access vpn can be enabled only for static nat ip, so this part should never be executed under normal
+        // conditions
+        // only when ip address failed to be cleaned up as a part of account destroy and was marked as Releasing, this part of
+        // the code would be triggered
+        s_logger.debug("Cleaning up remote access vpns as a part of public IP id=" + ipId + " release...");
+        try {
+            _vpnMgr.destroyRemoteAccessVpnForIp(ipId, caller,false);
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to destroy remote access vpn for ip id=" + ipId + " as a part of ip release", e);
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    @DB
+    public boolean disassociatePublicIpAddress(long addrId, long userId, Account caller) {
+
+        boolean success = true;
+        // Cleanup all ip address resources - PF/LB/Static nat rules
+        if (!cleanupIpResources(addrId, userId, caller)) {
+            success = false;
+            s_logger.warn("Failed to release resources for ip address id=" + addrId);
+        }
+
+        IPAddressVO ip = markIpAsUnavailable(addrId);
+        if (ip == null) {
+            return true;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing ip id=" + addrId + "; sourceNat = " + ip.isSourceNat());
+        }
+
+        if (ip.getAssociatedWithNetworkId() != null) {
+            Network network = _networksDao.findById(ip.getAssociatedWithNetworkId());
+            try {
+                if (!applyIpAssociations(network, rulesContinueOnErrFlag)) {
+                    s_logger.warn("Unable to apply ip address associations for " + network);
+                    success = false;
+                }
+            } catch (ResourceUnavailableException e) {
+                throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e);
+            }
+        } else {
+            if (ip.getState() == IpAddress.State.Releasing) {
+                _ipAddressDao.unassignIpAddress(ip.getId());
+            }
+        }
+
+        if (success) {
+            if (ip.isPortable()) {
+                releasePortableIpAddress(addrId);
+            }
+            s_logger.debug("Released a public ip id=" + addrId);
+        }
+
+        return success;
+    }
+
+    @DB
+    @Override
+    public boolean releasePortableIpAddress(final long addrId) {
+        final GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
+
+        try {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    portableIpLock.lock(5);
+                    IPAddressVO ip = _ipAddressDao.findById(addrId);
+
+                    // unassign portable IP
+                    PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr());
+                    _portableIpDao.unassignIpAddress(portableIp.getId());
+
+                    // removed the provisioned vlan
+                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
+                    _vlanDao.remove(vlan.getId());
+
+                    // remove the provisioned public ip address
+                    _ipAddressDao.remove(ip.getId());
+
+                    return true;
+                }
+            });
+        } finally {
+            portableIpLock.releaseRef();
+        }
+    }
+
+    @Override
+    public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms)
+            throws InsufficientAddressCapacityException {
+        return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null, forSystemVms);
+    }
+
+    @Override
+    public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
+            throws InsufficientAddressCapacityException {
+        return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null, false);
+    }
+
+    @DB
+    public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List<Long> vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId,
+            final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms)
+                    throws InsufficientAddressCapacityException {
+        IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
+            @Override
+            public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                StringBuilder errorMessage = new StringBuilder("Unable to get ip address in ");
+                boolean fetchFromDedicatedRange = false;
+                List<Long> dedicatedVlanDbIds = new ArrayList<Long>();
+                List<Long> nonDedicatedVlanDbIds = new ArrayList<Long>();
+                DataCenter zone = _entityMgr.findById(DataCenter.class, dcId);
+
+                SearchCriteria<IPAddressVO> sc = null;
+                if (podId != null) {
+                    sc = AssignIpAddressFromPodVlanSearch.create();
+                    sc.setJoinParameters("podVlanMapSB", "podId", podId);
+                    errorMessage.append(" pod id=" + podId);
+                } else {
+                    sc = AssignIpAddressSearch.create();
+                    errorMessage.append(" zone id=" + dcId);
+                }
+
+                // If owner has dedicated Public IP ranges, fetch IP from the dedicated range
+                // Otherwise fetch IP from the system pool
+                Network network = _networksDao.findById(guestNetworkId);
+                //Checking if network is null in the case of system VM's. At the time of allocation of IP address to systemVm, no network is present.
+                if(network == null || !(network.getGuestType() == GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced)) {
+                    List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByAccount(owner.getId());
+                    for (AccountVlanMapVO map : maps) {
+                        if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
+                            dedicatedVlanDbIds.add(map.getVlanDbId());
+                    }
+                }
+                List<DomainVlanMapVO> domainMaps = _domainVlanMapDao.listDomainVlanMapsByDomain(owner.getDomainId());
+                for (DomainVlanMapVO map : domainMaps) {
+                    if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId()))
+                        dedicatedVlanDbIds.add(map.getVlanDbId());
+                }
+                List<VlanVO> nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId);
+                for (VlanVO nonDedicatedVlan : nonDedicatedVlans) {
+                    if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId()))
+                        nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId());
+                }
+                if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
+                    fetchFromDedicatedRange = true;
+                    sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
+                    errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
+                } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
+                    sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
+                    errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
+                } else {
+                    if (podId != null) {
+                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
+                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
+                        throw ex;
+                    }
+                    s_logger.warn(errorMessage.toString());
+                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
+                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
+                    throw ex;
+                }
+
+                sc.setParameters("dc", dcId);
+
+                // for direct network take ip addresses only from the vlans belonging to the network
+                if (vlanUse == VlanType.DirectAttached) {
+                    sc.setJoinParameters("vlan", "networkId", guestNetworkId);
+                    errorMessage.append(", network id=" + guestNetworkId);
+                }
+                sc.setJoinParameters("vlan", "type", vlanUse);
+
+                if (requestedIp != null) {
+                    sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
+                    errorMessage.append(": requested ip " + requestedIp + " is not available");
+                }
+
+                boolean ascOrder = ! forSystemVms;
+                Filter filter = new Filter(IPAddressVO.class, "forSystemVms", ascOrder, 0l, 1l);
+                if (SystemVmPublicIpReservationModeStrictness.value()) {
+                    sc.setParameters("forSystemVms", forSystemVms);
+                }
+
+                filter.addOrderBy(IPAddressVO.class,"vlanId", true);
+
+                List<IPAddressVO> addrs = _ipAddressDao.search(sc, filter, false);
+
+                // If all the dedicated IPs of the owner are in use fetch an IP from the system pool
+                if (addrs.size() == 0 && fetchFromDedicatedRange) {
+                    // Verify if account is allowed to acquire IPs from the system
+                    boolean useSystemIps = UseSystemPublicIps.valueIn(owner.getId());
+                    if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
+                        fetchFromDedicatedRange = false;
+                        sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
+                        errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
+                        addrs = _ipAddressDao.search(sc, filter, false);
+                    }
+                }
+
+                if (addrs.size() == 0) {
+                    if (podId != null) {
+                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
+                        // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object.
+                        ex.addProxyObject(ApiDBUtils.findPodById(podId).getUuid());
+                        throw ex;
+                    }
+                    s_logger.warn(errorMessage.toString());
+                    InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
+                    ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
+                    throw ex;
+                }
+
+                assert(addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
+
+                if (!fetchFromDedicatedRange && VlanType.VirtualNetwork.equals(vlanUse)) {
+                    // Check that the maximum number of public IPs for the given accountId will not be exceeded
+                    try {
+                        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip);
+                    } catch (ResourceAllocationException ex) {
+                        s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner);
+                        throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded.");
+                    }
+                }
+
+                IPAddressVO finalAddr = null;
+                for (final IPAddressVO possibleAddr: addrs) {
+                    if (possibleAddr.getState() != IpAddress.State.Free) {
+                        continue;
+                    }
+                    final IPAddressVO addr = possibleAddr;
+                    addr.setSourceNat(sourceNat);
+                    addr.setAllocatedTime(new Date());
+                    addr.setAllocatedInDomainId(owner.getDomainId());
+                    addr.setAllocatedToAccountId(owner.getId());
+                    addr.setSystem(isSystem);
+
+                    if (displayIp != null) {
+                        addr.setDisplay(displayIp);
+                    }
+
+                    if (vlanUse != VlanType.DirectAttached) {
+                        addr.setAssociatedWithNetworkId(guestNetworkId);
+                        addr.setVpcId(vpcId);
+                    }
+                    if (_ipAddressDao.lockRow(possibleAddr.getId(), true) != null) {
+                        final IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
+                        if (userIp.getState() == IpAddress.State.Free) {
+                            addr.setState(IpAddress.State.Allocating);
+                            if (_ipAddressDao.update(addr.getId(), addr)) {
+                                finalAddr = addr;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (finalAddr == null) {
+                    s_logger.error("Failed to fetch any free public IP address");
+                    throw new CloudRuntimeException("Failed to fetch any free public IP address");
+                }
+
+                if (assign) {
+                    markPublicIpAsAllocated(finalAddr);
+                }
+
+                final State expectedAddressState = assign ? State.Allocated : State.Allocating;
+                if (finalAddr.getState() != expectedAddressState) {
+                    s_logger.error("Failed to fetch new public IP and get in expected state=" + expectedAddressState);
+                    throw new CloudRuntimeException("Failed to fetch new public IP with expected state " + expectedAddressState);
+                }
+
+                return finalAddr;
+            }
+        });
+
+        if (vlanUse == VlanType.VirtualNetwork) {
+            _firewallMgr.addSystemFirewallRules(addr, owner);
+        }
+
+        return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
+    }
+
+    @DB
+    @Override
+    public void markPublicIpAsAllocated(final IPAddressVO addr) {
+        synchronized (allocatedLock) {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
+                    if (_ipAddressDao.lockRow(addr.getId(), true) != null) {
+                        final IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
+                        if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) {
+                            addr.setState(IpAddress.State.Allocated);
+                            if (_ipAddressDao.update(addr.getId(), addr)) {
+                                // Save usage event
+                                if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
+                                    VlanVO vlan = _vlanDao.findById(addr.getVlanId());
+                                    String guestType = vlan.getVlanType().toString();
+                                    if (!isIpDedicated(addr)) {
+                                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(),
+                                                addr.getAddress().toString(),
+                                                addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid());
+                                    }
+                                    if (updateIpResourceCount(addr)) {
+                                        _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
+                                    }
+                                }
+                            } else {
+                                s_logger.error("Failed to mark public IP as allocated with id=" + addr.getId() + " address=" + addr.getAddress());
+                            }
+                        }
+                    } else {
+                        s_logger.error("Failed to acquire row lock to mark public IP as allocated with id=" + addr.getId() + " address=" + addr.getAddress());
+                    }
+                }
+            });
+        }
+    }
+
+    private boolean isIpDedicated(IPAddressVO addr) {
+        List<AccountVlanMapVO> maps = _accountVlanMapDao.listAccountVlanMapsByVlan(addr.getVlanId());
+        if (maps != null && !maps.isEmpty())
+            return true;
+        return false;
+    }
+
+    @Override
+    public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException {
+        assert(guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network "
+                + "can't participate in source nat.  What do you have to say for yourself?";
+        long dcId = guestNetwork.getDataCenterId();
+
+        IPAddressVO sourceNatIp = getExistingSourceNatInNetwork(owner.getId(), guestNetwork.getId());
+
+        PublicIp ipToReturn = null;
+        if (sourceNatIp != null) {
+            ipToReturn = PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
+        } else {
+            ipToReturn = assignDedicateIpAddress(owner, guestNetwork.getId(), null, dcId, true);
+        }
+
+        return ipToReturn;
+    }
+
+    @DB
+    @Override
+    public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat)
+            throws ConcurrentOperationException, InsufficientAddressCapacityException {
+
+        final long ownerId = owner.getId();
+
+        PublicIp ip = null;
+        try {
+            ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
+                @Override
+                public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                    Account owner = _accountDao.acquireInLockTable(ownerId);
+
+                    if (owner == null) {
+                        // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class
+                        // to get the table name and field name that is queried to fill this ownerid.
+                        ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account");
+                        throw ex;
+                    }
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("lock account " + ownerId + " is acquired");
+                    }
+                    boolean displayIp = true;
+                    if (guestNtwkId != null) {
+                        Network ntwk = _networksDao.findById(guestNtwkId);
+                        displayIp = ntwk.getDisplayNetwork();
+                    } else if (vpcId != null) {
+                        VpcVO vpc = _vpcDao.findById(vpcId);
+                        displayIp = vpc.isDisplay();
+                    }
+                    return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, false, vpcId, displayIp, false);
+                }
+            });
+            if (ip.getState() != State.Allocated) {
+                s_logger.error("Failed to fetch new IP and allocate it for ip with id=" + ip.getId() + ", address=" + ip.getAddress());
+            }
+            return ip;
+        } finally {
+            if (owner != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Releasing lock account " + ownerId);
+                }
+
+                _accountDao.releaseFromLockTable(ownerId);
+            }
+            if (ip == null) {
+                s_logger.error("Unable to get source nat ip address for account " + ownerId);
+            }
+        }
+    }
+
+    @Override
+    public boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException {
+        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
+        boolean success = true;
+        // CloudStack will take a lazy approach to associate an acquired public IP to a network service provider as
+        // it will not know what service an acquired IP will be used for. An IP is actually associated with a provider when first
+        // rule is applied. Similarly when last rule on the acquired IP is revoked, IP is not associated with any provider
+        // but still be associated with the account. At this point just mark IP as allocated or released.
+        for (IPAddressVO addr : userIps) {
+            if (addr.getState() == IpAddress.State.Allocating) {
+                addr.setAssociatedWithNetworkId(network.getId());
+                markPublicIpAsAllocated(addr);
+            } else if (addr.getState() == IpAddress.State.Releasing) {
+                // Cleanup all the resources for ip address if there are any, and only then un-assign ip in the system
+                if (cleanupIpResources(addr.getId(), Account.ACCOUNT_ID_SYSTEM, _accountMgr.getSystemAccount())) {
+                    _ipAddressDao.unassignIpAddress(addr.getId());
+                } else {
+                    success = false;
+                    s_logger.warn("Failed to release resources for ip address id=" + addr.getId());
+                }
+            }
+        }
+        return success;
+    }
+
+    // CloudStack will take a lazy approach to associate an acquired public IP to a network service provider as
+    // it will not know what a acquired IP will be used for. An IP is actually associated with a provider when first
+    // rule is applied. Similarly when last rule on the acquired IP is revoked, IP is not associated with any provider
+    // but still be associated with the account. Its up to caller of this function to decide when to invoke IPAssociation
+    @Override
+    public boolean applyIpAssociations(Network network, boolean postApplyRules, boolean continueOnError, List<? extends PublicIpAddress> publicIps)
+            throws ResourceUnavailableException {
+        boolean success = true;
+
+        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(publicIps, postApplyRules, true);
+        Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = _networkModel.getProviderToIpList(network, ipToServices);
+
+        for (Provider provider : providerToIpList.keySet()) {
+            try {
+                ArrayList<PublicIpAddress> ips = providerToIpList.get(provider);
+                if (ips == null || ips.isEmpty()) {
+                    continue;
+                }
+                IpDeployer deployer = null;
+                NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
+                if (!(element instanceof IpDeployingRequester)) {
+                    throw new CloudRuntimeException("Element " + element + " is not a IpDeployingRequester!");
+                }
+                deployer = ((IpDeployingRequester)element).getIpDeployer(network);
+                if (deployer == null) {
+                    throw new CloudRuntimeException("Fail to get ip deployer for element: " + element);
+                }
+                Set<Service> services = new HashSet<Service>();
+                for (PublicIpAddress ip : ips) {
+                    if (!ipToServices.containsKey(ip)) {
+                        continue;
+                    }
+                    services.addAll(ipToServices.get(ip));
+                }
+                deployer.applyIps(network, ips, services);
+            } catch (ResourceUnavailableException e) {
+                success = false;
+                if (!continueOnError) {
+                    throw e;
+                } else {
+                    s_logger.debug("Resource is not available: " + provider.getName(), e);
+                }
+            }
+        }
+
+        return success;
+    }
+
+    @DB
+    @Override
+    public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException {
+
+        DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId);
+        Account caller = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            ResourceAllocationException ex = new ResourceAllocationException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + zone.getUuid(),
+                    ResourceType.network);
+            throw ex;
+        }
+
+        DataCenterIpAddressVO vo = null;
+        if (podId == null)
+            throw new ResourceAllocationException("Please do not provide NULL podId", ResourceType.network);
+        HostPodVO podvo = null;
+        podvo = _hpDao.findByUuid(podId);
+        if (podvo == null)
+            throw new ResourceAllocationException("No sush pod exists", ResourceType.network);
+
+        vo = _privateIPAddressDao.takeIpAddress(zone.getId(), podvo.getId(), 0, caller.getId() + "", false);
+        if(vo == null)
+            throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
+        if (vo.getIpAddress() == null)
+            throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
+
+        HostPodVO pod_vo = _hpDao.findById(vo.getPodId());
+        AcquirePodIpCmdResponse ret = new AcquirePodIpCmdResponse();
+        ret.setCidrAddress(pod_vo.getCidrAddress());
+        ret.setGateway(pod_vo.getGateway());
+        ret.setInstanceId(vo.getInstanceId());
+        ret.setIpAddress(vo.getIpAddress());
+        ret.setMacAddress(vo.getMacAddress());
+        ret.setPodId(vo.getPodId());
+        ret.setId(vo.getId());
+
+        return ret;
+    }
+
+    @DB
+    @Override
+    public void releasePodIp(Long id) throws CloudRuntimeException {
+
+        // Verify input parameters
+        DataCenterIpAddressVO ipVO = _privateIPAddressDao.findById(id);
+        if (ipVO == null) {
+            throw new CloudRuntimeException("Unable to find ip address by id:" + id);
+        }
+
+        if (ipVO.getTakenAt() == null) {
+            s_logger.debug("Ip Address with id= " + id + " is not allocated, so do nothing.");
+            throw new CloudRuntimeException("Ip Address  with id= " + id + " is not allocated, so do nothing.");
+        }
+        // Verify permission
+        DataCenter zone = _entityMgr.findById(DataCenter.class, ipVO.getDataCenterId());
+        Account caller = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new CloudRuntimeException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + ipVO.getDataCenterId());
+        }
+        try {
+            _privateIPAddressDao.releasePodIpAddress(id);
+        } catch (Exception e) {
+            new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @DB
+    @Override
+    public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone, final Boolean displayIp)
+            throws ConcurrentOperationException,
+            ResourceAllocationException, InsufficientAddressCapacityException {
+
+        final VlanType vlanType = VlanType.VirtualNetwork;
+        final boolean assign = false;
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            // zone is of type DataCenter. See DataCenterVO.java.
+            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, " + "Zone is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "zoneId");
+            throw ex;
+        }
+
+        PublicIp ip = null;
+
+        Account accountToLock = null;
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
+            }
+            accountToLock = _accountDao.acquireInLockTable(ipOwner.getId());
+            if (accountToLock == null) {
+                s_logger.warn("Unable to lock account: " + ipOwner.getId());
+                throw new ConcurrentOperationException("Unable to acquire account lock");
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Associate IP address lock acquired");
+            }
+
+            ip = Transaction.execute(new TransactionCallbackWithException<PublicIp, InsufficientAddressCapacityException>() {
+                @Override
+                public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                    PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp, false);
+
+                    if (ip == null) {
+                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone
+                                .getId());
+                        ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid());
+                        throw ex;
+
+                    }
+                    CallContext.current().setEventDetails("Ip Id: " + ip.getId());
+                    Ip ipAddress = ip.getAddress();
+
+                    s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
+
+                    return ip;
+                }
+            });
+
+        } finally {
+            if (accountToLock != null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Releasing lock account " + ipOwner);
+                }
+                _accountDao.releaseFromLockTable(ipOwner.getId());
+                s_logger.debug("Associate IP address lock released");
+            }
+        }
+        return ip;
+    }
+
+    @Override
+    @DB
+    public IpAddress allocatePortableIp(final Account ipOwner, Account caller, final long dcId, final Long networkId, final Long vpcID)
+            throws ConcurrentOperationException,
+            ResourceAllocationException, InsufficientAddressCapacityException {
+
+        GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange");
+        IPAddressVO ipaddr;
+
+        try {
+            portableIpLock.lock(5);
+
+            ipaddr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
+                @Override
+                public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
+                    PortableIpVO allocatedPortableIp;
+
+                    List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
+                    if (portableIpVOs == null || portableIpVOs.isEmpty()) {
+                        InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class,
+                                new Long(1));
+                        throw ex;
+                    }
+
+                    // allocate first portable IP to the user
+                    allocatedPortableIp = portableIpVOs.get(0);
+                    allocatedPortableIp.setAllocatedTime(new Date());
+                    allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId());
+                    allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId());
+                    allocatedPortableIp.setState(PortableIp.State.Allocated);
+                    _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp);
+
+                    // To make portable IP available as a zone level resource we need to emulate portable IP's (which are
+                    // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the
+                    // identity of a public IP in zone. Create entry for portable ip in these tables.
+
+                    // provision portable IP range VLAN into the zone
+                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId();
+                    Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
+                    String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress();
+                    VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, allocatedPortableIp.getVlan(), allocatedPortableIp.getGateway(), allocatedPortableIp.getNetmask(), dcId,
+                            range, network.getId(), physicalNetworkId, null, null, null);
+                    vlan = _vlanDao.persist(vlan);
+
+                    // provision the portable IP in to user_ip_address table
+                    IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true);
+                    ipaddr.setState(State.Allocated);
+                    ipaddr.setAllocatedTime(new Date());
+                    ipaddr.setAllocatedInDomainId(ipOwner.getDomainId());
+                    ipaddr.setAllocatedToAccountId(ipOwner.getId());
+                    ipaddr = _ipAddressDao.persist(ipaddr);
+
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, ipaddr.getId(), ipaddr.getDataCenterId(), ipaddr.getId(),
+                            ipaddr.getAddress().toString(), ipaddr.isSourceNat(), null, ipaddr.getSystem(), ipaddr.getClass().getName(), ipaddr.getUuid());
+
+                    return ipaddr;
+                }
+            });
+        } finally {
+            portableIpLock.unlock();
+        }
+
+        return ipaddr;
+    }
+
+    protected IPAddressVO getExistingSourceNatInNetwork(long ownerId, Long networkId) {
+        List<? extends IpAddress> addrs;
+        Network guestNetwork = _networksDao.findById(networkId);
+        if (guestNetwork.getGuestType() == GuestType.Shared) {
+            // ignore the account id for the shared network
+            addrs = _networkModel.listPublicIpsAssignedToGuestNtwk(networkId, true);
+        } else {
+            addrs = _networkModel.listPublicIpsAssignedToGuestNtwk(ownerId, networkId, true);
+        }
+
+        IPAddressVO sourceNatIp = null;
+        if (addrs.isEmpty()) {
+            return null;
+        } else {
+            // Account already has ip addresses
+            for (IpAddress addr : addrs) {
+                if (addr.isSourceNat()) {
+                    sourceNatIp = _ipAddressDao.findById(addr.getId());
+                    return sourceNatIp;
+                }
+            }
+
+            assert(sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; networkId=" + networkId;
+        }
+
+        return sourceNatIp;
+    }
+
+    @DB
+    @Override
+    public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException {
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = null;
+
+        IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId);
+        if (ipToAssoc != null) {
+            Network network = _networksDao.findById(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Invalid network id is given");
+            }
+
+            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+            if (zone.getNetworkType() == NetworkType.Advanced) {
+                if (network.getGuestType() == Network.GuestType.Shared) {
+                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+                        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false,
+                                network);
+                    } else {
+                        throw new InvalidParameterValueException("IP can be associated with guest network of 'shared' type only if "
+                                + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network");
+                    }
+                }
+            } else {
+                _accountMgr.checkAccess(caller, null, true, ipToAssoc);
+            }
+            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
+        } else {
+            s_logger.debug("Unable to find ip address by id: " + ipId);
+            return null;
+        }
+
+        if (ipToAssoc.getAssociatedWithNetworkId() != null) {
+            s_logger.debug("IP " + ipToAssoc + " is already assocaited with network id" + networkId);
+            return ipToAssoc;
+        }
+
+        Network network = _networksDao.findById(networkId);
+        if (network != null) {
+            _accountMgr.checkAccess(owner, AccessType.UseEntry, false, network);
+        } else {
+            s_logger.debug("Unable to find ip address by id: " + ipId);
+            return null;
+        }
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+
+        // allow associating IP addresses to guest network only
+        if (network.getTrafficType() != TrafficType.Guest) {
+            throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest);
+        }
+
+        // Check that network belongs to IP owner - skip this check
+        //     - if zone is basic zone as there is just one guest network,
+        //     - if shared network in Advanced zone
+        //     - and it belongs to the system
+        if (network.getAccountId() != owner.getId()) {
+            if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
+                throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
+            }
+        }
+
+        if (zone.getNetworkType() == NetworkType.Advanced) {
+            // In Advance zone allow to do IP assoc only for Isolated networks with source nat service enabled
+            if (network.getGuestType() == GuestType.Isolated && !(_networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) {
+                if (releaseOnFailure && ipToAssoc != null) {
+                    s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
+                    _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
+                }
+                throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated only to the network of guest type "
+                        + GuestType.Isolated + " with the " + Service.SourceNat.getName() + " enabled");
+            }
+
+            // In Advance zone allow to do IP assoc only for shared networks with source nat/static nat/lb/pf services enabled
+            if (network.getGuestType() == GuestType.Shared && !isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+                if (releaseOnFailure && ipToAssoc != null) {
+                    s_logger.warn("Failed to associate ip address, so unassigning ip from the database " + ipToAssoc);
+                    _ipAddressDao.unassignIpAddress(ipToAssoc.getId());
+                }
+                throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated with network of guest type " + GuestType.Shared
+                        + "only if at " + "least one of the services " + Service.SourceNat.getName() + "/" + Service.StaticNat.getName() + "/" + Service.Lb.getName() + "/"
+                        + Service.PortForwarding.getName() + " is enabled");
+            }
+        }
+
+        boolean isSourceNat = isSourceNatAvailableForNetwork(owner, ipToAssoc, network);
+
+        s_logger.debug("Associating ip " + ipToAssoc + " to network " + network);
+
+        IPAddressVO ip = _ipAddressDao.findById(ipId);
+        //update ip address with networkId
+        ip.setAssociatedWithNetworkId(networkId);
+        ip.setSourceNat(isSourceNat);
+        _ipAddressDao.update(ipId, ip);
+
+        boolean success = false;
+        try {
+            success = applyIpAssociations(network, false);
+            if (success) {
+                s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
+            } else {
+                s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
+            }
+            return ip;
+        } finally {
+            if (!success && releaseOnFailure) {
+                if (ip != null) {
+                    try {
+                        s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip);
+                        _ipAddressDao.markAsUnavailable(ip.getId());
+                        if (!applyIpAssociations(network, true)) {
+                            // if fail to apply ip assciations again, unassign ip address without updating resource
+                            // count and generating usage event as there is no need to keep it in the db
+                            _ipAddressDao.unassignIpAddress(ip.getId());
+                        }
+                    } catch (Exception e) {
+                        s_logger.warn("Unable to disassociate ip address for recovery", e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Prevents associating an IP address to an allocated (unimplemented network) network, throws an Exception otherwise
+     * @param owner Used to check if the user belongs to the Network
+     * @param ipToAssoc IP address to be associated to a Network, can only be associated to an implemented network for Source NAT
+     * @param network Network to which IP address is to be associated with, must not be in allocated state for Source NAT Network/IP association
+     * @return true if IP address can be successfully associated with Source NAT network
+     */
+    protected boolean isSourceNatAvailableForNetwork(Account owner, IPAddressVO ipToAssoc, Network network) {
+        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        boolean sharedSourceNat = offering.isSharedSourceNat();
+        boolean isSourceNat = false;
+        if (!sharedSourceNat) {
+            if (getExistingSourceNatInNetwork(owner.getId(), network.getId()) == null) {
+                if (network.getGuestType() == GuestType.Isolated && network.getVpcId() == null && !ipToAssoc.isPortable()) {
+                    if (network.getState() == Network.State.Allocated) {
+                        //prevent associating an ip address to an allocated (unimplemented network).
+                        //it will cause the ip to become source nat, and it can't be disassociated later on.
+                        String msg = String.format("Network with UUID:%s is in allocated and needs to be implemented first before acquiring an IP address", network.getUuid());
+                        throw new InvalidParameterValueException(msg);
+                    }
+                    isSourceNat = true;
+                }
+            }
+        }
+        return isSourceNat;
+    }
+
+    protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
+        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
+        if ((networkOffering.getGuestType() == Network.GuestType.Shared)
+                && (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
+                                networkOfferingId, Service.Lb))) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException {
+        return associateIPToGuestNetwork(ipAddrId, networkId, releaseOnFailure);
+    }
+
+    @DB
+    @Override
+    public IPAddressVO disassociatePortableIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = null;
+
+        Network network = _networksDao.findById(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId);
+        if (ipToAssoc != null) {
+
+            if (ipToAssoc.getAssociatedWithNetworkId() == null) {
+                throw new InvalidParameterValueException("IP " + ipToAssoc + " is not associated with any network");
+            }
+
+            if (ipToAssoc.getAssociatedWithNetworkId() != network.getId()) {
+                throw new InvalidParameterValueException("IP " + ipToAssoc + " is not associated with network id" + networkId);
+            }
+
+            DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+            if (zone.getNetworkType() == NetworkType.Advanced) {
+                if (network.getGuestType() == Network.GuestType.Shared) {
+                    assert(isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()));
+                    _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false,
+                            network);
+                }
+            } else {
+                _accountMgr.checkAccess(caller, null, true, ipToAssoc);
+            }
+            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
+        } else {
+            s_logger.debug("Unable to find ip address by id: " + ipId);
+            return null;
+        }
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+
+        // Check that network belongs to IP owner - skip this check
+        //     - if zone is basic zone as there is just one guest network,
+        //     - if shared network in Advanced zone
+        //     - and it belongs to the system
+        if (network.getAccountId() != owner.getId()) {
+            if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
+                throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
+            }
+        }
+
+        // Check if IP has any services (rules) associated in the network
+        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
+        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipToAssoc, _vlanDao.findById(ipToAssoc.getVlanId()));
+        ipList.add(publicIp);
+        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(ipList, false, true);
+        if (!ipToServices.isEmpty()) {
+            Set<Service> services = ipToServices.get(publicIp);
+            if (services != null && !services.isEmpty()) {
+                throw new InvalidParameterValueException("IP " + ipToAssoc + " has services and rules associated in the network " + networkId);
+            }
+        }
+
+        IPAddressVO ip = _ipAddressDao.findById(ipId);
+        ip.setAssociatedWithNetworkId(null);
+        _ipAddressDao.update(ipId, ip);
+
+        try {
+            boolean success = applyIpAssociations(network, false);
+            if (success) {
+                s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network);
+            } else {
+                s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network);
+            }
+            return ip;
+        } finally {
+
+        }
+    }
+
+    @Override
+    public boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId) {
+        Network network = _networksDao.findById(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        IPAddressVO ip = _ipAddressDao.findById(ipAddrId);
+        if (ip == null) {
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        // Check if IP has any services (rules) associated in the network
+        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
+        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId()));
+        ipList.add(publicIp);
+        Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(ipList, false, true);
+        if (!ipToServices.isEmpty()) {
+            Set<Service> ipServices = ipToServices.get(publicIp);
+            if (ipServices != null && !ipServices.isEmpty()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @DB
+    @Override
+    public void transferPortableIP(final long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
+            InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        Network srcNetwork = _networksDao.findById(currentNetworkId);
+        if (srcNetwork == null) {
+            throw new InvalidParameterValueException("Invalid source network id " + currentNetworkId + " is given");
+        }
+
+        final Network dstNetwork = _networksDao.findById(newNetworkId);
+        if (dstNetwork == null) {
+            throw new InvalidParameterValueException("Invalid source network id " + newNetworkId + " is given");
+        }
+
+        final IPAddressVO ip = _ipAddressDao.findById(ipAddrId);
+        if (ip == null) {
+            throw new InvalidParameterValueException("Invalid portable ip address id is given");
+        }
+
+        assert(isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId));
+
+        // disassociate portable IP with current network/VPC network
+        if (srcNetwork.getVpcId() != null) {
+            _vpcMgr.unassignIPFromVpcNetwork(ipAddrId, currentNetworkId);
+        } else {
+            disassociatePortableIPToGuestNetwork(ipAddrId, currentNetworkId);
+        }
+
+        // If portable IP need to be transferred across the zones, then mark the entry corresponding to portable ip
+        // in user_ip_address and vlan tables so as to emulate portable IP as provisioned in destination data center
+        if (srcNetwork.getDataCenterId() != dstNetwork.getDataCenterId()) {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
+                    long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId();
+
+                    ip.setDataCenterId(dstNetwork.getDataCenterId());
+                    ip.setPhysicalNetworkId(physicalNetworkId);
+                    ip.setSourceNetworkId(publicNetworkId);
+                    _ipAddressDao.update(ipAddrId, ip);
+
+                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
+                    vlan.setPhysicalNetworkId(physicalNetworkId);
+                    vlan.setNetworkId(publicNetworkId);
+                    vlan.setDataCenterId(dstNetwork.getDataCenterId());
+                    _vlanDao.update(ip.getVlanId(), vlan);
+                }
+            });
+        }
+
+        // associate portable IP with new network/VPC network
+        associatePortableIPToGuestNetwork(ipAddrId, newNetworkId, false);
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                if (dstNetwork.getVpcId() != null) {
+                    ip.setVpcId(dstNetwork.getVpcId());
+                } else {
+                    ip.setVpcId(null);
+                }
+
+                _ipAddressDao.update(ipAddrId, ip);
+            }
+
+        });
+
+        // trigger an action event for the transfer of portable IP across the networks, so that external entities
+        // monitoring for this event can initiate the route advertisement for the availability of IP from the zoe
+        ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, Domain.ROOT_DOMAIN, EventTypes.EVENT_PORTABLE_IP_TRANSFER,
+                "Portable IP associated is transferred from network " + currentNetworkId + " to " + newNetworkId);
+    }
+
+    protected List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
+
+        return _networksDao.listSourceNATEnabledNetworks(owner.getId(), zoneId, Network.GuestType.Isolated);
+    }
+
+    @Override
+    @DB
+    public boolean associateIpAddressListToAccount(long userId, final long accountId, final long zoneId, final Long vlanId, final Network guestNetworkFinal)
+            throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException {
+        final Account owner = _accountMgr.getActiveAccountById(accountId);
+
+        if (guestNetworkFinal != null && guestNetworkFinal.getTrafficType() != TrafficType.Guest) {
+            throw new InvalidParameterValueException("Network " + guestNetworkFinal + " is not of a type " + TrafficType.Guest);
+        }
+
+        Ternary<Boolean, List<NetworkOfferingVO>, Network> pair = null;
+        try {
+            pair = Transaction.execute(new TransactionCallbackWithException<Ternary<Boolean, List<NetworkOfferingVO>, Network>, Exception>() {
+                @Override
+                public Ternary<Boolean, List<NetworkOfferingVO>, Network> doInTransaction(TransactionStatus status) throws InsufficientCapacityException,
+                        ResourceAllocationException {
+                    boolean createNetwork = false;
+                    Network guestNetwork = guestNetworkFinal;
+
+                    if (guestNetwork == null) {
+                        List<? extends Network> networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner);
+                        if (networks.size() == 0) {
+                            createNetwork = true;
+                        } else if (networks.size() == 1) {
+                            guestNetwork = networks.get(0);
+                        } else {
+                            throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT "
+                                    + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID");
+                        }
+                    }
+
+                    // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist
+                    List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+                    if (requiredOfferings.size() < 1) {
+                        throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required
+                                + " to automatically create the network as part of createVlanIpRange");
+                    }
+                    if (createNetwork) {
+                        if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
+                            long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
+                            // Validate physical network
+                            PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+                            if (physicalNetwork == null) {
+                                throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+                                        + requiredOfferings.get(0).getTags());
+                            }
+
+                            s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
+                                    + " as a part of createVlanIpRange process");
+                            guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
+                                    + "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null);
+                            if (guestNetwork == null) {
+                                s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
+                                throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "
+                                        + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId);
+                            }
+                        } else {
+                            throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
+                        }
+                    }
+
+                    // Check if there is a source nat ip address for this account; if not - we have to allocate one
+                    boolean allocateSourceNat = false;
+                    List<IPAddressVO> sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true);
+                    if (sourceNat.isEmpty()) {
+                        allocateSourceNat = true;
+                    }
+
+                    // update all ips with a network id, mark them as allocated and update resourceCount/usage
+                    List<IPAddressVO> ips = _ipAddressDao.listByVlanId(vlanId);
+                    boolean isSourceNatAllocated = false;
+                    for (IPAddressVO addr : ips) {
+                        if (addr.getState() != State.Allocated) {
+                            if (!isSourceNatAllocated && allocateSourceNat) {
+                                addr.setSourceNat(true);
+                                isSourceNatAllocated = true;
+                            } else {
+                                addr.setSourceNat(false);
+                            }
+                            addr.setAssociatedWithNetworkId(guestNetwork.getId());
+                            addr.setVpcId(guestNetwork.getVpcId());
+                            addr.setAllocatedTime(new Date());
+                            addr.setAllocatedInDomainId(owner.getDomainId());
+                            addr.setAllocatedToAccountId(owner.getId());
+                            addr.setSystem(false);
+                            addr.setState(IpAddress.State.Allocating);
+                            markPublicIpAsAllocated(addr);
+                        }
+                    }
+                    return new Ternary<Boolean, List<NetworkOfferingVO>, Network>(createNetwork, requiredOfferings, guestNetwork);
+                }
+            });
+        } catch (Exception e1) {
+            ExceptionUtil.rethrowRuntime(e1);
+            ExceptionUtil.rethrow(e1, InsufficientCapacityException.class);
+            ExceptionUtil.rethrow(e1, ResourceAllocationException.class);
+            throw new IllegalStateException(e1);
+        }
+
+        boolean createNetwork = pair.first();
+        List<NetworkOfferingVO> requiredOfferings = pair.second();
+        Network guestNetwork = pair.third();
+
+        // if the network offering has persistent set to true, implement the network
+        if (createNetwork && requiredOfferings.get(0).isPersistent()) {
+            DataCenter zone = _dcDao.findById(zoneId);
+            DeployDestination dest = new DeployDestination(zone, null, null, null);
+            Account callerAccount = CallContext.current().getCallingAccount();
+            UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
+            Journal journal = new Journal.LogJournal("Implementing " + guestNetwork, s_logger);
+            ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, callerAccount);
+            s_logger.debug("Implementing network " + guestNetwork + " as a part of network provision for persistent network");
+            try {
+                Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(guestNetwork.getId(), dest, context);
+                if (implementedNetwork == null || implementedNetwork.first() == null) {
+                    s_logger.warn("Failed to implement the network " + guestNetwork);
+                }
+                if (implementedNetwork != null) {
+                    guestNetwork = implementedNetwork.second();
+                }
+            } catch (Exception ex) {
+                s_logger.warn("Failed to implement network " + guestNetwork + " elements and resources as a part of" + " network provision due to ", ex);
+                CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id)"
+                        + " elements and resources as a part of network provision for persistent network");
+                e.addProxyObject(guestNetwork.getUuid(), "networkId");
+                throw e;
+            }
+        }
+        return true;
+    }
+
+    @DB
+    @Override
+    public IPAddressVO markIpAsUnavailable(final long addrId) {
+        final IPAddressVO ip = _ipAddressDao.findById(addrId);
+
+        if (ip.getAllocatedToAccountId() == null && ip.getAllocatedTime() == null) {
+            s_logger.trace("Ip address id=" + addrId + " is already released");
+            return ip;
+        }
+
+        if (ip.getState() != State.Releasing) {
+            return Transaction.execute(new TransactionCallback<IPAddressVO>() {
+                @Override
+                public IPAddressVO doInTransaction(TransactionStatus status) {
+                    if (updateIpResourceCount(ip)) {
+                        _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip);
+                    }
+
+                    // Save usage event
+                    if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) {
+                        VlanVO vlan = _vlanDao.findById(ip.getVlanId());
+
+                        String guestType = vlan.getVlanType().toString();
+                        if (!isIpDedicated(ip)) {
+                            String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE;
+                            UsageEventUtils.publishUsageEvent(eventType, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(),
+                                    guestType, ip.getSystem(), ip.getClass().getName(), ip.getUuid());
+                        }
+                    }
+
+                    return _ipAddressDao.markAsUnavailable(addrId);
+                }
+            });
+        }
+
+        return ip;
+    }
+
+    protected boolean updateIpResourceCount(IPAddressVO ip) {
+        // don't increment resource count for direct and dedicated ip addresses
+        return (ip.getAssociatedWithNetworkId() != null || ip.getVpcId() != null) && !isIpDedicated(ip);
+    }
+
+    @Override
+    @DB
+    public String acquireGuestIpAddress(Network network, String requestedIp) {
+        if (requestedIp != null && requestedIp.equals(network.getGateway())) {
+            s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network);
+            return null;
+        }
+
+        if (_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty() && network.getCidr() == null) {
+            return null;
+        }
+
+        Set<Long> availableIps = _networkModel.getAvailableIps(network, requestedIp);
+
+        if (availableIps == null || availableIps.isEmpty()) {
+            s_logger.debug("There are no free ips in the  network " + network);
+            return null;
+        }
+
+        Long[] array = availableIps.toArray(new Long[availableIps.size()]);
+
+        if (requestedIp != null) {
+            // check that requested ip has the same cidr
+            String[] cidr = network.getCidr().split("/");
+            boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1]));
+            if (!isSameCidr) {
+                s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr");
+                return null;
+            } else if (NetUtils.IsIpEqualToNetworkOrBroadCastIp(requestedIp, cidr[0], Integer.parseInt(cidr[1]))) {
+                s_logger.warn("Requested ip address " + requestedIp + " is equal to the to the network/broadcast ip of the network" + network);
+                return null;
+            }
+            return requestedIp;
+        }
+
+        return NetUtils.long2Ip(array[rand.nextInt(array.length)]);
+    }
+
+    /**
+     * Get the list of public IPs that need to be applied for a static NAT enable/disable operation.
+     * Manipulating only these ips prevents concurrency issues when disabling static nat at the same time.
+     * @param staticNats
+     * @return The list of IPs that need to be applied for the static NAT to work.
+     */
+    public List<IPAddressVO> getStaticNatSourceIps(List<? extends StaticNat> staticNats) {
+        List<IPAddressVO> userIps = new ArrayList<>();
+
+        for (StaticNat snat : staticNats) {
+            userIps.add(_ipAddressDao.findById(snat.getSourceIpAddressId()));
+        }
+
+        return userIps;
+    }
+
+    @Override
+    public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException {
+        if (staticNats == null || staticNats.size() == 0) {
+            s_logger.debug("There are no static nat rules for the network elements");
+            return true;
+        }
+
+        Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
+        boolean success = true;
+
+        // Check if the StaticNat service is supported
+        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
+            s_logger.debug("StaticNat service is not supported in specified network id");
+            return true;
+        }
+
+        List<IPAddressVO> userIps = getStaticNatSourceIps(staticNats);
+
+        List<PublicIp> publicIps = new ArrayList<PublicIp>();
+        if (userIps != null && !userIps.isEmpty()) {
+            for (IPAddressVO userIp : userIps) {
+                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                publicIps.add(publicIp);
+            }
+        }
+
+        // static NAT rules can not programmed unless IP is associated with source NAT service provider, so run IP
+        // association for the network so as to ensure IP is associated before applying rules
+        if (checkStaticNatIPAssocRequired(network, false, forRevoke, publicIps)) {
+            applyIpAssociations(network, false, continueOnError, publicIps);
+        }
+
+        // get provider
+        StaticNatServiceProvider element = _networkMgr.getStaticNatProviderForNetwork(network);
+        try {
+            success = element.applyStaticNats(network, staticNats);
+        } catch (ResourceUnavailableException e) {
+            if (!continueOnError) {
+                throw e;
+            }
+            s_logger.warn("Problems with " + element.getName() + " but pushing on", e);
+            success = false;
+        }
+
+        // For revoked static nat IP, set the vm_id to null, indicate it should be revoked
+        for (StaticNat staticNat : staticNats) {
+            if (staticNat.isForRevoke()) {
+                for (PublicIp publicIp : publicIps) {
+                    if (publicIp.getId() == staticNat.getSourceIpAddressId()) {
+                        publicIps.remove(publicIp);
+                        IPAddressVO ip = _ipAddressDao.findByIdIncludingRemoved(staticNat.getSourceIpAddressId());
+                        // ip can't be null, otherwise something wrong happened
+                        ip.setAssociatedWithVmId(null);
+                        publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId()));
+                        publicIps.add(publicIp);
+                        break;
+                    }
+                }
+            }
+        }
+
+        // if the static NAT rules configured on public IP is revoked then, dis-associate IP with static NAT service provider
+        if (checkStaticNatIPAssocRequired(network, true, forRevoke, publicIps)) {
+            applyIpAssociations(network, true, continueOnError, publicIps);
+        }
+
+        return success;
+    }
+
+    // checks if there are any public IP assigned to network, that are marked for one-to-one NAT that
+    // needs to be associated/dis-associated with static-nat provider
+    boolean checkStaticNatIPAssocRequired(Network network, boolean postApplyRules, boolean forRevoke, List<PublicIp> publicIps) {
+        for (PublicIp ip : publicIps) {
+            if (ip.isOneToOneNat()) {
+                Long activeFwCount = null;
+                activeFwCount = _firewallDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active);
+
+                if (!postApplyRules && !forRevoke) {
+                    if (activeFwCount > 0) {
+                        continue;
+                    } else {
+                        return true;
+                    }
+                } else if (postApplyRules && forRevoke) {
+                    return true;
+                }
+            } else {
+                continue;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException {
+        Network guestNetwork = _networksDao.findById(networkId);
+        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+        IpAddress ip = null;
+        if ((off.isElasticLb() && forElasticLb) || (off.isElasticIp() && forElasticIp)) {
+
+            try {
+                s_logger.debug("Allocating system IP address for load balancer rule...");
+                // allocate ip
+                ip = allocateIP(owner, true, guestNetwork.getDataCenterId());
+                // apply ip associations
+                ip = associateIPToGuestNetwork(ip.getId(), networkId, true);
+                ;
+            } catch (ResourceAllocationException ex) {
+                throw new CloudRuntimeException("Failed to allocate system ip due to ", ex);
+            } catch (ConcurrentOperationException ex) {
+                throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
+            } catch (ResourceUnavailableException ex) {
+                throw new CloudRuntimeException("Failed to allocate system lb ip due to ", ex);
+            }
+
+            if (ip == null) {
+                throw new CloudRuntimeException("Failed to allocate system ip");
+            }
+        }
+
+        return ip;
+    }
+
+    @Override
+    public boolean handleSystemIpRelease(IpAddress ip) {
+        boolean success = true;
+        Long networkId = ip.getAssociatedWithNetworkId();
+        if (networkId != null) {
+            if (ip.getSystem()) {
+                CallContext ctx = CallContext.current();
+                if (!disassociatePublicIpAddress(ip.getId(), ctx.getCallingUserId(), ctx.getCallingAccount())) {
+                    s_logger.warn("Unable to release system ip address id=" + ip.getId());
+                    success = false;
+                } else {
+                    s_logger.warn("Successfully released system ip address id=" + ip.getId());
+                }
+            }
+        }
+        return success;
+    }
+
+    @Override
+    @DB
+    public void allocateDirectIp(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4,
+            final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
+                //This method allocates direct ip for the Shared network in Advance zones
+                boolean ipv4 = false;
+
+                if (network.getGateway() != null) {
+                    if (nic.getIPv4Address() == null) {
+                        PublicIp ip = null;
+
+                        //Get ip address from the placeholder and don't allocate a new one
+                        if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
+                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
+                            if (placeholderNic != null) {
+                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address());
+                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                                s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network);
+                            }
+                        }
+
+                        if (ip == null) {
+                            ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false, false);
+                        }
+
+                        nic.setIPv4Address(ip.getAddress().toString());
+                        nic.setIPv4Gateway(ip.getGateway());
+                        nic.setIPv4Netmask(ip.getNetmask());
+                        nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
+                        nic.setBroadcastType(network.getBroadcastDomainType());
+                        if (network.getBroadcastUri() != null)
+                            nic.setBroadcastUri(network.getBroadcastUri());
+                        else
+                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
+                        nic.setFormat(AddressFormat.Ip4);
+                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
+                        if(nic.getMacAddress() == null) {
+                            nic.setMacAddress(ip.getMacAddress());
+                        }
+                    }
+                    nic.setIPv4Dns1(dc.getDns1());
+                    nic.setIPv4Dns2(dc.getDns2());
+                }
+
+                _ipv6Mgr.setNicIp6Address(nic, dc, network);
+            }
+        });
+    }
+
+    @Override
+    @DB
+    public void allocateNicValues(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4,
+            final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
+                //This method allocates direct ip for the Shared network in Advance zones
+                boolean ipv4 = false;
+
+                if (network.getGateway() != null) {
+                    if (nic.getIPv4Address() == null) {
+                        ipv4 = true;
+                        // PublicIp ip = null;
+
+                        //Get ip address from the placeholder and don't allocate a new one
+                        if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
+                            s_logger.debug("There won't be nic assignment for VR id " + vm.getId() + "  in this network " + network);
+
+                        }
+
+                        // nic ip address is not set here. Because the DHCP is external to cloudstack
+                        nic.setIPv4Gateway(network.getGateway());
+                        nic.setIPv4Netmask(NetUtils.getCidrNetmask(network.getCidr()));
+
+                        List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(network.getId());
+
+                        //TODO: get vlan tag for the ntwork
+                        if (vlan != null && !vlan.isEmpty()) {
+                            nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.get(0).getVlanTag()));
+                        }
+
+                        nic.setBroadcastType(BroadcastDomainType.Vlan);
+                        nic.setBroadcastType(network.getBroadcastDomainType());
+
+                        nic.setBroadcastUri(network.getBroadcastUri());
+                        nic.setFormat(AddressFormat.Ip4);
+                        if(nic.getMacAddress() == null) {
+                            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
+                        }
+                    }
+                    nic.setIPv4Dns1(dc.getDns1());
+                    nic.setIPv4Dns2(dc.getDns2());
+                }
+
+                _ipv6Mgr.setNicIp6Address(nic, dc, network);
+            }
+        });
+    }
+
+    @Override
+    public int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state) {
+        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeWithState(addressId, purpose, state);
+        if (rules == null) {
+            return 0;
+        }
+        return rules.size();
+    }
+
+    @Override
+    public String allocatePublicIpForGuestNic(Network network, Long podId, Account owner, String requestedIp) throws InsufficientAddressCapacityException {
+        PublicIp ip = assignPublicIpAddress(network.getDataCenterId(), podId, owner, VlanType.DirectAttached, network.getId(), requestedIp, false, false);
+        if (ip == null) {
+            s_logger.debug("There is no free public ip address");
+            return null;
+        }
+        Ip ipAddr = ip.getAddress();
+        return ipAddr.addr();
+    }
+
+    @Override
+    public String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException {
+        return acquireGuestIpAddress(network, requestedIp);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return IpAddressManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError, SystemVmPublicIpReservationModeStrictness};
+    }
+
+    /**
+     * Returns true if the given IP address is equals the gateway or there is no network offerrings for the given network
+     */
+    @Override
+    public boolean isIpEqualsGatewayOrNetworkOfferingsEmpty(Network network, String requestedIp) {
+        if (requestedIp.equals(network.getGateway()) || requestedIp.equals(network.getIp6Gateway())) {
+            return true;
+        }
+        if (_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty() && network.getCidr() == null) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/Ipv6AddressManager.java b/server/src/main/java/com/cloud/network/Ipv6AddressManager.java
new file mode 100644
index 0000000..7dcba11
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/Ipv6AddressManager.java
@@ -0,0 +1,36 @@
+// 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.network;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.user.Account;
+import com.cloud.utils.component.Manager;
+import com.cloud.vm.NicProfile;
+
+public interface Ipv6AddressManager extends Manager {
+
+    public String allocateGuestIpv6(Network network, String requestedIpv6) throws InsufficientAddressCapacityException;
+
+    public String allocatePublicIp6ForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
+
+    public String acquireGuestIpv6Address(Network network, String requestedIpv6) throws InsufficientAddressCapacityException;
+
+    public void setNicIp6Address(final NicProfile nic, final DataCenter dc, final Network network);
+
+}
diff --git a/server/src/main/java/com/cloud/network/Ipv6AddressManagerImpl.java b/server/src/main/java/com/cloud/network/Ipv6AddressManagerImpl.java
new file mode 100644
index 0000000..adfc3d2
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/Ipv6AddressManagerImpl.java
@@ -0,0 +1,220 @@
+// 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.network;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.vm.NicProfile;
+import com.googlecode.ipv6.IPv6Address;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.user.Account;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+
+public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressManager {
+    public static final Logger s_logger = Logger.getLogger(Ipv6AddressManagerImpl.class.getName());
+
+    String _name = null;
+    int _ipv6RetryMax = 0;
+
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    UserIpv6AddressDao _ipv6Dao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    IpAddressManager ipAddressManager;
+    @Inject
+    NicSecondaryIpDao nicSecondaryIpDao;
+    @Inject
+    IPAddressDao ipAddressDao;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        Map<String, String> configs = _configDao.getConfiguration(params);
+        _ipv6RetryMax = NumbersUtil.parseInt(configs.get(Config.NetworkIPv6SearchRetryMax.key()), 10000);
+        return true;
+    }
+
+    /**
+     * Executes method {@link #acquireGuestIpv6Address(Network, String)} and returns the requested IPv6 (String) in case of successfully allocating the guest IPv6 address.
+     */
+    @Override
+    public String allocateGuestIpv6(Network network, String requestedIpv6) throws InsufficientAddressCapacityException {
+        return acquireGuestIpv6Address(network, requestedIpv6);
+    }
+
+    /**
+     * Allocates a guest IPv6 address for the guest NIC. It will throw exceptions in the following cases:
+     * <ul>
+     *    <li>there is no IPv6 address available in the network;</li>
+     *    <li>IPv6 address is equals to the Gateway;</li>
+     *    <li>the network offering is empty;</li>
+     *    <li>the IPv6 address is not in the network;</li>
+     *    <li>the requested IPv6 address is already in use in the network.</li>
+     * </ul>
+     */
+    @Override
+    @DB
+    public String acquireGuestIpv6Address(Network network, String requestedIpv6) throws InsufficientAddressCapacityException {
+        if (!_networkModel.areThereIPv6AddressAvailableInNetwork(network.getId())) {
+            throw new InsufficientAddressCapacityException(
+                    String.format("There is no IPv6 address available in the network [name=%s, network id=%s]", network.getName(), network.getId()), DataCenter.class,
+                    network.getDataCenterId());
+        }
+
+        if (NetUtils.isIPv6EUI64(requestedIpv6)) {
+            throw new InsufficientAddressCapacityException(String.format("Requested IPv6 address [%s] may not be a EUI-64 address", requestedIpv6), DataCenter.class,
+                    network.getDataCenterId());
+        }
+
+        checkIfCanAllocateIpv6Address(network, requestedIpv6);
+
+        IpAddresses requestedIpPair = new IpAddresses(null, requestedIpv6);
+        _networkModel.checkRequestedIpAddresses(network.getId(), requestedIpPair);
+
+        IPAddressVO ip = ipAddressDao.findByIpAndSourceNetworkId(network.getId(), requestedIpv6);
+        if (ip != null) {
+            State ipState = ip.getState();
+            if (ipState != State.Free) {
+                throw new InsufficientAddressCapacityException(String.format("Requested ip address [%s] is not free [ip state=%]", requestedIpv6, ipState), DataCenter.class,
+                        network.getDataCenterId());
+            }
+        }
+        return requestedIpv6;
+    }
+
+    /**
+     * Allocates a public IPv6 address for the guest NIC. It will throw exceptions in the following cases:
+     * <ul>
+     *    <li>the the requested IPv6 address is already in use in the network;</li>
+     *    <li>IPv6 address is equals to the Gateway;</li>
+     *    <li>the network offering is empty;</li>
+     *    <li>the IPv6 address is not in the network.</li>
+     * </ul>
+     */
+    @Override
+    public String allocatePublicIp6ForGuestNic(Network network, Long podId, Account owner, String requestedIpv6) throws InsufficientAddressCapacityException {
+        checkIfCanAllocateIpv6Address(network, requestedIpv6);
+
+        return requestedIpv6;
+    }
+
+    /**
+     * Performs some checks on the given IPv6 address. It will throw exceptions in the following cases:
+     * <ul>
+     *    <li>the the requested IPv6 address is already in use in the network;</li>
+     *    <li>IPv6 address is equals to the Gateway;</li>
+     *    <li>the network offering is empty;</li>
+     *    <li>the IPv6 address is not in the network.</li>
+     * </ul>
+     */
+    protected void checkIfCanAllocateIpv6Address(Network network, String ipv6) throws InsufficientAddressCapacityException {
+        if (isIp6Taken(network, ipv6)) {
+            throw new InsufficientAddressCapacityException(
+                    String.format("The IPv6 address [%s] is already in use in the network [id=%s, name=%s]", ipv6, network.getId(), network.getName()), Network.class,
+                    network.getId());
+        }
+
+        if (ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, ipv6)) {
+            throw new InvalidParameterValueException(
+                    String.format("The network [id=%s] offering is empty or the requested IP address [%s] is equals to the Gateway", network.getId(), ipv6));
+        }
+
+        String networkIp6Cidr = network.getIp6Cidr();
+        if (!NetUtils.isIp6InNetwork(ipv6, networkIp6Cidr)) {
+            throw new InvalidParameterValueException(
+                    String.format("The IPv6 address [%s] is not in the network [id=%s, name=%s, ipv6cidr=%s]", ipv6, network.getId(), network.getName(), network.getIp6Cidr()));
+        }
+    }
+
+    /**
+     * Returns false if the requested ipv6 address is taken by some VM, checking on the 'user_ipv6_address' table or 'nic_secondary_ips' table.
+     */
+    protected boolean isIp6Taken(Network network, String requestedIpv6) {
+        UserIpv6AddressVO ip6Vo = _ipv6Dao.findByNetworkIdAndIp(network.getId(), requestedIpv6);
+        NicSecondaryIpVO nicSecondaryIpVO = nicSecondaryIpDao.findByIp6AddressAndNetworkId(requestedIpv6, network.getId());
+        return ip6Vo != null || nicSecondaryIpVO != null;
+    }
+
+    /**
+     * Calculate the IPv6 Address the Instance will obtain using SLAAC and IPv6 EUI-64
+     *
+     * Linux, FreeBSD and Windows all calculate the same IPv6 address when configured properly. (SLAAC)
+     *
+     * Using Router Advertisements the routers in the network should announce the IPv6 CIDR which is configured
+     * for the network.
+     *
+     * It is up to the network administrator to make sure the IPv6 Routers in the network are sending out Router Advertisements
+     * with the correct IPv6 (Prefix, DNS, Lifetime) information.
+     *
+     * This way the NIC will be populated with a IPv6 address on which the Instance is reachable.
+     *
+     * This method calculates the IPv6 address the Instance will obtain and updates the Nic object with the correct
+     * address information.
+     */
+    @Override
+    public void setNicIp6Address(final NicProfile nic, final DataCenter dc, final Network network) {
+        if (network.getIp6Gateway() != null) {
+            if (nic.getIPv6Address() == null) {
+                s_logger.debug("Found IPv6 CIDR " + network.getIp6Cidr() + " for Network " + network);
+                nic.setIPv6Cidr(network.getIp6Cidr());
+                nic.setIPv6Gateway(network.getIp6Gateway());
+
+                IPv6Address ipv6addr = NetUtils.EUI64Address(network.getIp6Cidr(), nic.getMacAddress());
+                s_logger.info("Calculated IPv6 address " + ipv6addr + " using EUI-64 for NIC " + nic.getUuid());
+                nic.setIPv6Address(ipv6addr.toString());
+
+                if (nic.getIPv4Address() != null) {
+                    nic.setFormat(Networks.AddressFormat.DualStack);
+                } else {
+                    nic.setFormat(Networks.AddressFormat.Ip6);
+                }
+            }
+            nic.setIPv6Dns1(dc.getIp6Dns1());
+            nic.setIPv6Dns2(dc.getIp6Dns2());
+        }
+    }
+
+}
diff --git a/server/src/com/cloud/network/NetworkMigrationManager.java b/server/src/main/java/com/cloud/network/NetworkMigrationManager.java
similarity index 100%
rename from server/src/com/cloud/network/NetworkMigrationManager.java
rename to server/src/main/java/com/cloud/network/NetworkMigrationManager.java
diff --git a/server/src/com/cloud/network/NetworkMigrationManagerImpl.java b/server/src/main/java/com/cloud/network/NetworkMigrationManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/NetworkMigrationManagerImpl.java
rename to server/src/main/java/com/cloud/network/NetworkMigrationManagerImpl.java
diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java
new file mode 100644
index 0000000..03629cd
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java
@@ -0,0 +1,2479 @@
+// 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.network;
+
+import java.math.BigInteger;
+import java.security.InvalidParameterException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDomainDao;
+import com.cloud.network.dao.NetworkDomainVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkServiceMapVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.IpDeployingRequester;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable {
+    static final Logger s_logger = Logger.getLogger(NetworkModelImpl.class);
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    DataCenterDao _dcDao = null;
+    @Inject
+    VlanDao _vlanDao = null;
+    @Inject
+    IPAddressDao _ipAddressDao = null;
+    @Inject
+    AccountDao _accountDao = null;
+    @Inject
+    DomainDao _domainDao = null;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao = null;
+    @Inject
+    NetworkDao _networksDao = null;
+    @Inject
+    NicDao _nicDao = null;
+    @Inject
+    PodVlanMapDao _podVlanMapDao;
+
+    private List<NetworkElement> networkElements;
+
+    public List<NetworkElement> getNetworkElements() {
+        return networkElements;
+    }
+
+    public void setNetworkElements(List<NetworkElement> networkElements) {
+        this.networkElements = networkElements;
+    }
+
+    @Inject
+    NetworkDomainDao _networkDomainDao;
+    @Inject
+    VMInstanceDao _vmDao;
+
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    DomainManager _domainMgr;
+
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _pNSPDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingRulesDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    PrivateIpDao _privateIpDao;
+    @Inject
+    UserIpv6AddressDao _ipv6Dao;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    ApplicationLoadBalancerRuleDao _appLbRuleDao;
+    @Inject
+    private ProjectAccountDao _projectAccountDao;
+    @Inject
+    NetworkOfferingDetailsDao _ntwkOffDetailsDao;
+    @Inject
+    private NetworkService _networkService;
+
+    private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
+    static Long s_privateOfferingId = null;
+
+    SearchBuilder<IPAddressVO> IpAddressSearch;
+    SearchBuilder<NicVO> NicForTrafficTypeSearch;
+
+    private boolean _allowSubdomainNetworkAccess;
+
+    private Map<String, String> _configs;
+
+    protected boolean _executeInSequenceNtwkElmtCmd;
+
+    HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
+
+    static HashMap<Service, List<Provider>> s_serviceToImplementedProvidersMap = new HashMap<Service, List<Provider>>();
+    static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
+
+    /**
+     *
+     */
+    public NetworkModelImpl() {
+        super();
+    }
+
+    @Override
+    public NetworkElement getElementImplementingProvider(String providerName) {
+        String elementName = s_providerToNetworkElementMap.get(providerName);
+        NetworkElement element = AdapterBase.getAdapterByName(networkElements, elementName);
+        return element;
+    }
+
+    @Override
+    public List<Service> getElementServices(Provider provider) {
+        NetworkElement element = getElementImplementingProvider(provider.getName());
+        if (element == null) {
+            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
+        }
+        return new ArrayList<Service>(element.getCapabilities().keySet());
+    }
+
+    @Override
+    public boolean canElementEnableIndividualServices(Provider provider) {
+        NetworkElement element = getElementImplementingProvider(provider.getName());
+        if (element == null) {
+            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
+        }
+        return element.canEnableIndividualServices();
+    }
+
+    Set<Purpose> getPublicIpPurposeInRules(PublicIpAddress ip, boolean includeRevoked, boolean includingFirewall) {
+        Set<Purpose> result = new HashSet<Purpose>();
+        List<FirewallRuleVO> rules = null;
+        if (includeRevoked) {
+            rules = _firewallDao.listByIp(ip.getId());
+        } else {
+            rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
+        }
+
+        if (rules == null || rules.isEmpty()) {
+            return null;
+        }
+
+        for (FirewallRuleVO rule : rules) {
+            if (rule.getPurpose() != Purpose.Firewall || includingFirewall) {
+                result.add(rule.getPurpose());
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean postApplyRules, boolean includingFirewall) {
+        Map<PublicIpAddress, Set<Service>> ipToServices = new HashMap<PublicIpAddress, Set<Service>>();
+
+        if (publicIps != null && !publicIps.isEmpty()) {
+            Set<Long> networkSNAT = new HashSet<Long>();
+            for (PublicIpAddress ip : publicIps) {
+                Set<Service> services = ipToServices.get(ip);
+                if (services == null) {
+                    services = new HashSet<Service>();
+                }
+                if (ip.isSourceNat()) {
+                    if (!networkSNAT.contains(ip.getAssociatedWithNetworkId())) {
+                        services.add(Service.SourceNat);
+                        networkSNAT.add(ip.getAssociatedWithNetworkId());
+                    } else {
+                        CloudRuntimeException ex = new CloudRuntimeException("Multiple generic source NAT IPs provided for network");
+                        // see the IPAddressVO.java class.
+                        IPAddressVO ipAddr = ApiDBUtils.findIpAddressById(ip.getAssociatedWithNetworkId());
+                        String ipAddrUuid = ip.getAssociatedWithNetworkId().toString();
+                        if (ipAddr != null) {
+                            ipAddrUuid = ipAddr.getUuid();
+                        }
+                        ex.addProxyObject(ipAddrUuid, "networkId");
+                        throw ex;
+                    }
+                }
+                ipToServices.put(ip, services);
+
+                // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service
+                // provider
+                if (ip.getState() == State.Allocating) {
+                    continue;
+                }
+
+                // check if any active rules are applied on the public IP
+                Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false, includingFirewall);
+                // Firewall rules didn't cover static NAT
+                if (ip.isOneToOneNat() && ip.getAssociatedWithVmId() != null) {
+                    if (purposes == null) {
+                        purposes = new HashSet<Purpose>();
+                    }
+                    purposes.add(Purpose.StaticNat);
+                }
+                if (purposes == null || purposes.isEmpty()) {
+                    // since no active rules are there check if any rules are applied on the public IP but are in
+                    // revoking state
+
+                    purposes = getPublicIpPurposeInRules(ip, true, includingFirewall);
+                    if (ip.isOneToOneNat()) {
+                        if (purposes == null) {
+                            purposes = new HashSet<Purpose>();
+                        }
+                        purposes.add(Purpose.StaticNat);
+                    }
+                    if (purposes == null || purposes.isEmpty()) {
+                        // IP is not being used for any purpose so skip IPAssoc to network service provider
+                        continue;
+                    } else {
+                        if (postApplyRules) {
+                            // no active rules/revoked rules are associated with this public IP, so remove the
+                            // association with the provider
+                            if (ip.isSourceNat()) {
+                                s_logger.debug("Not releasing ip " + ip.getAddress().addr() + " as it is in use for SourceNat");
+                            } else {
+                                ip.setState(State.Releasing);
+                            }
+                        } else {
+                            if (ip.getState() == State.Releasing) {
+                                // rules are not revoked yet, so don't let the network service provider revoke the IP
+                                // association
+                                // mark IP is allocated so that IP association will not be removed from the provider
+                                ip.setState(State.Allocated);
+                            }
+                        }
+                    }
+                }
+                if (purposes.contains(Purpose.StaticNat)) {
+                    services.add(Service.StaticNat);
+                }
+                if (purposes.contains(Purpose.LoadBalancing)) {
+                    services.add(Service.Lb);
+                }
+                if (purposes.contains(Purpose.PortForwarding)) {
+                    services.add(Service.PortForwarding);
+                }
+                if (purposes.contains(Purpose.Vpn)) {
+                    services.add(Service.Vpn);
+                }
+                if (purposes.contains(Purpose.Firewall)) {
+                    services.add(Service.Firewall);
+                }
+                if (services.isEmpty()) {
+                    continue;
+                }
+                ipToServices.put(ip, services);
+            }
+        }
+        return ipToServices;
+    }
+
+    public boolean canIpUsedForNonConserveService(PublicIp ip, Service service) {
+        // If it's non-conserve mode, then the new ip should not be used by any other services
+        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
+        ipList.add(ip);
+        Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, false);
+        Set<Service> services = ipToServices.get(ip);
+        // Not used currently, safe
+        if (services == null || services.isEmpty()) {
+            return true;
+        }
+        // Since it's non-conserve mode, only one service should used for IP
+        if (services.size() != 1) {
+            throw new InvalidParameterException("There are multiple services used ip " + ip.getAddress() + ".");
+        }
+        if (service != null && !((Service)services.toArray()[0] == service || service.equals(Service.Firewall))) {
+            throw new InvalidParameterException("The IP " + ip.getAddress() + " is already used as " + ((Service)services.toArray()[0]).getName() + " rather than " +
+                service.getName());
+        }
+        return true;
+    }
+
+    Map<Service, Set<Provider>> getServiceProvidersMap(long networkId) {
+        Map<Service, Set<Provider>> map = new HashMap<Service, Set<Provider>>();
+        List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
+        for (NetworkServiceMapVO nsm : nsms) {
+            Set<Provider> providers = map.get(Service.getService(nsm.getService()));
+            if (providers == null) {
+                providers = new HashSet<Provider>();
+            }
+            providers.add(Provider.getProvider(nsm.getProvider()));
+            map.put(Service.getService(nsm.getService()), providers);
+        }
+        return map;
+    }
+
+    public boolean canIpUsedForService(PublicIp publicIp, Service service, Long networkId) {
+        List<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
+        ipList.add(publicIp);
+        Map<PublicIpAddress, Set<Service>> ipToServices = getIpToServices(ipList, false, true);
+        Set<Service> services = ipToServices.get(publicIp);
+        if (services == null || services.isEmpty()) {
+            return true;
+        }
+
+        if (networkId == null) {
+            networkId = publicIp.getAssociatedWithNetworkId();
+        }
+
+        // We only support one provider for one service now
+        Map<Service, Set<Provider>> serviceToProviders = getServiceProvidersMap(networkId);
+        // Since IP already has service to bind with, the oldProvider can't be null
+        Set<Provider> newProviders = serviceToProviders.get(service);
+        if (newProviders == null || newProviders.isEmpty()) {
+            throw new InvalidParameterException("There is no new provider for IP " + publicIp.getAddress() + " of service " + service.getName() + "!");
+        }
+        Provider newProvider = (Provider)newProviders.toArray()[0];
+        Set<Provider> oldProviders = serviceToProviders.get(services.toArray()[0]);
+        Provider oldProvider = (Provider)oldProviders.toArray()[0];
+        Network network = _networksDao.findById(networkId);
+        NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
+        NetworkElement newElement = getElementImplementingProvider(newProvider.getName());
+        if (oldElement instanceof IpDeployingRequester && newElement instanceof IpDeployingRequester) {
+            IpDeployer oldIpDeployer = ((IpDeployingRequester)oldElement).getIpDeployer(network);
+            IpDeployer newIpDeployer = ((IpDeployingRequester)newElement).getIpDeployer(network);
+            // FIXME: I ignored this check
+        } else {
+            throw new InvalidParameterException("Ip cannot be applied for new provider!");
+        }
+        return true;
+    }
+
+    Map<Provider, Set<Service>> getProviderServicesMap(long networkId) {
+        Map<Provider, Set<Service>> map = new HashMap<Provider, Set<Service>>();
+        List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
+        for (NetworkServiceMapVO nsm : nsms) {
+            Set<Service> services = map.get(Provider.getProvider(nsm.getProvider()));
+            if (services == null) {
+                services = new HashSet<Service>();
+            }
+            services.add(Service.getService(nsm.getService()));
+            map.put(Provider.getProvider(nsm.getProvider()), services);
+        }
+        return map;
+    }
+
+    @Override
+    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
+        NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if (!offering.isConserveMode()) {
+            for (PublicIpAddress ip : ipToServices.keySet()) {
+                Set<Service> services = new HashSet<Service>();
+                services.addAll(ipToServices.get(ip));
+                if (services != null && services.contains(Service.Firewall)) {
+                    services.remove(Service.Firewall);
+                }
+                if (services != null && services.size() > 1) {
+                    throw new CloudRuntimeException("Ip " + ip.getAddress() + " is used by multiple services!");
+                }
+            }
+        }
+        Map<Service, Set<PublicIpAddress>> serviceToIps = new HashMap<Service, Set<PublicIpAddress>>();
+        for (PublicIpAddress ip : ipToServices.keySet()) {
+            for (Service service : ipToServices.get(ip)) {
+                Set<PublicIpAddress> ips = serviceToIps.get(service);
+                if (ips == null) {
+                    ips = new HashSet<PublicIpAddress>();
+                }
+                ips.add(ip);
+                serviceToIps.put(service, ips);
+            }
+        }
+        // TODO Check different provider for same IP
+        Map<Provider, Set<Service>> providerToServices = getProviderServicesMap(network.getId());
+        Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = new HashMap<Provider, ArrayList<PublicIpAddress>>();
+        for (Provider provider : providerToServices.keySet()) {
+            if (!(getElementImplementingProvider(provider.getName()) instanceof IpDeployingRequester)) {
+                continue;
+            }
+            Set<Service> services = providerToServices.get(provider);
+            ArrayList<PublicIpAddress> ipList = new ArrayList<PublicIpAddress>();
+            Set<PublicIpAddress> ipSet = new HashSet<PublicIpAddress>();
+            for (Service service : services) {
+                Set<PublicIpAddress> serviceIps = serviceToIps.get(service);
+                if (serviceIps == null || serviceIps.isEmpty()) {
+                    continue;
+                }
+                ipSet.addAll(serviceIps);
+            }
+            Set<PublicIpAddress> sourceNatIps = serviceToIps.get(Service.SourceNat);
+            if (sourceNatIps != null && !sourceNatIps.isEmpty()) {
+                ipList.addAll(0, sourceNatIps);
+                ipSet.removeAll(sourceNatIps);
+            }
+            ipList.addAll(ipSet);
+            providerToIpList.put(provider, ipList);
+        }
+        return providerToIpList;
+    }
+
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
+        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("associatedWithNetworkId", associatedNetworkId);
+        if (sourceNat != null) {
+            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
+        }
+        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
+
+        return _ipAddressDao.search(sc, null);
+    }
+
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
+        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
+        sc.setParameters("associatedWithNetworkId", associatedNetworkId);
+
+        if (sourceNat != null) {
+            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
+        }
+        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
+
+        return _ipAddressDao.search(sc, null);
+    }
+
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
+        SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("dataCenterId", dcId);
+
+        if (sourceNat != null) {
+            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
+        }
+        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
+
+        return _ipAddressDao.search(sc, null);
+    }
+
+    @Override
+    public List<? extends Nic> getNics(long vmId) {
+        return _nicDao.listByVmId(vmId);
+    }
+
+    @Override
+    public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
+        NetworkVO network = _networksDao.findById(networkId);
+        String mac = _networksDao.getNextAvailableMacAddress(networkId, MACIdentifier.value());
+        if (mac == null) {
+            throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
+        }
+        return mac;
+    }
+
+    @Override
+    @DB
+    public Network getNetwork(long id) {
+        return _networksDao.findById(id);
+    }
+
+    @Override
+    public boolean canUseForDeploy(Network network) {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            return false;
+        }
+        if (network.getGuestType() == GuestType.L2 || listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
+            return true; // do not check free IPs if there is no service in the network
+        }
+        boolean hasFreeIps = true;
+        if (network.getGuestType() == GuestType.Shared) {
+            if (network.getGateway() != null) {
+                hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0;
+            }
+            if (!hasFreeIps) {
+                return false;
+            }
+            if (network.getIp6Gateway() != null) {
+                hasFreeIps = areThereIPv6AddressAvailableInNetwork(network.getId());
+            }
+        } else {
+            if (network.getCidr() == null) {
+                s_logger.debug("Network - " + network.getId() +  " has NULL CIDR.");
+                return false;
+            }
+            hasFreeIps = (getAvailableIps(network, null)).size() > 0;
+        }
+
+        return hasFreeIps;
+    }
+
+    @Override
+    public boolean areThereIPv6AddressAvailableInNetwork(long networkId) {
+        Network network = _networksDao.findById(networkId);
+        if (network == null) {
+            return false;
+        }
+        if (network.getIp6Gateway() == null) {
+            return false;
+        }
+        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
+        for (Vlan vlan : vlans) {
+            if (isIP6AddressAvailableInVlan(vlan.getId())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isIP6AddressAvailableInVlan(long vlanId) {
+        VlanVO vlan = _vlanDao.findById(vlanId);
+        if (vlan.getIp6Range() == null) {
+            return false;
+        }
+        long existedCount = _ipv6Dao.countExistedIpsInVlan(vlanId);
+        BigInteger existedInt = BigInteger.valueOf(existedCount);
+        BigInteger rangeInt = NetUtils.countIp6InRange(vlan.getIp6Range());
+        return (existedInt.compareTo(rangeInt) < 0);
+    }
+
+    @Override
+    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
+
+        Map<Service, Map<Capability, String>> networkCapabilities = new HashMap<Service, Map<Capability, String>>();
+
+        // list all services of this networkOffering
+        List<NetworkServiceMapVO> servicesMap = _ntwkSrvcDao.getServicesInNetwork(networkId);
+        for (NetworkServiceMapVO instance : servicesMap) {
+            Service service = Service.getService(instance.getService());
+            NetworkElement element = getElementImplementingProvider(instance.getProvider());
+            if (element != null) {
+                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+                if (elementCapabilities != null) {
+                    networkCapabilities.put(service, elementCapabilities.get(service));
+                }
+            }
+        }
+
+        return networkCapabilities;
+    }
+
+    @Override
+    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
+
+        if (!areServicesSupportedInNetwork(networkId, service)) {
+            // TBD: networkId to uuid. No VO object being passed. So we will need to call
+            // addProxyObject with hardcoded tablename. Or we should probably look up the correct dao proxy object.
+            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported in the network id=" + networkId);
+        }
+
+        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
+
+        // get the Provider for this Service for this offering
+        String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
+
+        NetworkElement element = getElementImplementingProvider(provider);
+        if (element != null) {
+            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+            ;
+
+            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
+                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
+                    " implementing Provider=" + provider);
+            }
+            serviceCapabilities = elementCapabilities.get(service);
+        }
+
+        return serviceCapabilities;
+    }
+
+    @Override
+    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
+
+        if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) {
+            // TBD: We should be sending networkOfferingId and not the offering object itself.
+            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering);
+        }
+
+        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
+
+        // get the Provider for this Service for this offering
+        List<String> providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
+        if (providers.isEmpty()) {
+            // TBD: We should be sending networkOfferingId and not the offering object itself.
+            throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering);
+        }
+
+        // FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so
+        // we have to calculate capabilities for all of them
+        String provider = providers.get(0);
+
+        // FIXME we return the capabilities of the first provider of the service - what if we have multiple providers
+        // for same Service?
+        NetworkElement element = getElementImplementingProvider(provider);
+        if (element != null) {
+            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+            ;
+
+            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
+                // TBD: We should be sending providerId and not the offering object itself.
+                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
+                    " implementing Provider=" + provider);
+            }
+            serviceCapabilities = elementCapabilities.get(service);
+        }
+
+        return serviceCapabilities;
+    }
+
+    @Override
+    public NetworkVO getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // find system public network offering
+        Long networkOfferingId = null;
+        List<NetworkOfferingVO> offerings = _networkOfferingDao.listSystemNetworkOfferings();
+        for (NetworkOfferingVO offering : offerings) {
+            if (offering.getTrafficType() == trafficType) {
+                networkOfferingId = offering.getId();
+                break;
+            }
+        }
+
+        if (networkOfferingId == null) {
+            throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType);
+        }
+
+        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId);
+        if (networks == null || networks.isEmpty()) {
+            // TBD: send uuid instead of zoneId. Hardcode tablename in call to addProxyObject().
+            throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId);
+        }
+        return networks.get(0);
+    }
+
+    @Override
+    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
+        List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
+        if (networks == null || networks.isEmpty()) {
+            return null;
+        }
+        NetworkVO ret_network = null;
+        for (NetworkVO nw : networks) {
+            List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(nw.getId());
+            for (VlanVO vlan : vlans) {
+                if (_ipAddressDao.countFreeIpsInVlan(vlan.getId()) > 0) {
+                    ret_network = nw;
+                    break;
+                }
+            }
+            if (ret_network != null) {
+                break;
+            }
+        }
+        if (ret_network == null) {
+            s_logger.debug("Can not find network with security group enabled with free IPs");
+        }
+        return ret_network;
+    }
+
+    @Override
+    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
+        List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
+        if (networks == null || networks.isEmpty()) {
+            return null;
+        }
+
+        if (networks.size() > 1) {
+            s_logger.debug("There are multiple network with security group enabled? select one of them...");
+        }
+        return networks.get(0);
+    }
+
+    @Override
+    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
+        IPAddressVO addr = _ipAddressDao.findById(ipAddressId);
+        if (addr == null) {
+            return null;
+        }
+
+        return PublicIp.createFromAddrAndVlan(addr, _vlanDao.findById(addr.getVlanId()));
+    }
+
+    @Override
+    public List<VlanVO> listPodVlans(long podId) {
+        List<VlanVO> vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached);
+        return vlans;
+    }
+
+    @Override
+    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
+        List<NetworkVO> networks = new ArrayList<NetworkVO>();
+
+        List<NicVO> nics = _nicDao.listByVmId(vmId);
+        if (nics != null) {
+            for (Nic nic : nics) {
+                NetworkVO network = _networksDao.findByIdIncludingRemoved(nic.getNetworkId());
+
+                if (isNetworkSystem(network) == isSystem) {
+                    networks.add(network);
+                }
+            }
+        }
+
+        return networks;
+    }
+
+    @Override
+    public Nic getNicInNetwork(long vmId, long networkId) {
+        return _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
+    }
+
+    @Override
+    public String getIpInNetwork(long vmId, long networkId) {
+        Nic guestNic = getNicInNetwork(vmId, networkId);
+        assert (guestNic != null && guestNic.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
+        return guestNic.getIPv4Address();
+    }
+
+    @Override
+    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
+        Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId);
+        assert (guestNic != null && guestNic.getIPv4Address() != null) : "Vm doesn't belong to network associated with " + "ipAddress or ip4 address is null";
+        return guestNic.getIPv4Address();
+    }
+
+    @Override
+    public List<NicVO> getNicsForTraffic(long vmId, TrafficType type) {
+        SearchCriteria<NicVO> sc = NicForTrafficTypeSearch.create();
+        sc.setParameters("instance", vmId);
+        sc.setJoinParameters("network", "traffictype", type);
+
+        return _nicDao.search(sc, null);
+    }
+
+    @Override
+    public IpAddress getIp(long ipAddressId) {
+        return _ipAddressDao.findById(ipAddressId);
+    }
+
+    @Override
+    public Network getDefaultNetworkForVm(long vmId) {
+        Nic defaultNic = getDefaultNic(vmId);
+        if (defaultNic == null) {
+            return null;
+        } else {
+            return _networksDao.findById(defaultNic.getNetworkId());
+        }
+    }
+
+    @Override
+    public Nic getDefaultNic(long vmId) {
+        List<NicVO> nics = _nicDao.listByVmId(vmId);
+        Nic defaultNic = null;
+        if (nics != null) {
+            for (Nic nic : nics) {
+                if (nic.isDefaultNic()) {
+                    defaultNic = nic;
+                    break;
+                }
+            }
+        } else {
+            s_logger.debug("Unable to find default network for the vm; vm doesn't have any nics");
+            return null;
+        }
+
+        if (defaultNic == null) {
+            s_logger.debug("Unable to find default network for the vm; vm doesn't have default nic");
+        }
+
+        return defaultNic;
+
+    }
+
+    @Override
+    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
+        String userDataProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
+
+        if (userDataProvider == null) {
+            s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
+            return null;
+        }
+
+        return (UserDataServiceProvider)getElementImplementingProvider(userDataProvider);
+    }
+
+    @Override
+    public  boolean isSharedNetworkWithoutServices (long networkId) {
+
+        Network network = _networksDao.findById(networkId);
+
+        if (network != null && network.getGuestType() != GuestType.Shared) {
+            return false;
+        }
+
+        List<Service> services = listNetworkOfferingServices(network.getNetworkOfferingId());
+
+        if (services == null || services.isEmpty()) {
+            return true;
+        }
+
+        return false;
+    }
+
+
+    @Override
+    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
+        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
+    }
+
+    @Override
+    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
+        return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services));
+    }
+
+    @Override
+    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
+
+        List<NetworkVO> virtualNetworks = _networksDao.listByZoneAndGuestType(accountId, dataCenterId, GuestType.Isolated, false);
+
+        if (virtualNetworks.isEmpty()) {
+            s_logger.trace("Unable to find default Virtual network account id=" + accountId);
+            return null;
+        }
+
+        NetworkVO virtualNetwork = virtualNetworks.get(0);
+
+        NicVO networkElementNic = _nicDao.findByNetworkIdAndType(virtualNetwork.getId(), Type.DomainRouter);
+
+        if (networkElementNic != null) {
+            return networkElementNic.getIPv4Address();
+        } else {
+            s_logger.warn("Unable to set find network element for the network id=" + virtualNetwork.getId());
+            return null;
+        }
+    }
+
+    @Override
+    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
+        List<NetworkVO> accountNetworks = new ArrayList<NetworkVO>();
+        List<NetworkVO> zoneNetworks = _networksDao.listByZone(zoneId);
+
+        for (NetworkVO network : zoneNetworks) {
+            if (!isNetworkSystem(network)) {
+                if (network.getGuestType() == GuestType.Shared || !_networksDao.listBy(accountId, network.getId()).isEmpty()) {
+                    if (type == null || type == network.getGuestType()) {
+                        accountNetworks.add(network);
+                    }
+                }
+            }
+        }
+        return accountNetworks;
+    }
+
+    @Override
+    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
+        List<NetworkVO> networks = new ArrayList<NetworkVO>();
+        for (NetworkVO network : _networksDao.listAll()) {
+            if (!isNetworkSystem(network)) {
+                networks.add(network);
+            }
+        }
+        return networks;
+    }
+
+    @Override
+    public Long getDedicatedNetworkDomain(long networkId) {
+        NetworkDomainVO networkMaps = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
+        if (networkMaps != null) {
+            return networkMaps.getDomainId();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Integer getNetworkRate(long networkId, Long vmId) {
+        VMInstanceVO vm = null;
+        if (vmId != null) {
+            vm = _vmDao.findById(vmId);
+        }
+        final Network network = getNetwork(networkId);
+        final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+
+        // For user VM: For default nic use network rate from the service/compute offering,
+        //              or on NULL from vm.network.throttling.rate global setting
+        // For router: Get network rate for guest and public networks from the guest network offering
+        //              or on NULL from network.throttling.rate
+        // For others: Use network rate from their network offering,
+        //              or on NULL from network.throttling.rate setting at zone > global level
+        // http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html#network-throttling
+        if (vm != null) {
+            if (vm.getType() == Type.User) {
+                final Nic nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vmId);
+                if (nic != null && nic.isDefaultNic()) {
+                    return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId(), network.getDataCenterId());
+                }
+            }
+            if (vm.getType() == Type.DomainRouter && (network.getTrafficType() == TrafficType.Public || network.getTrafficType() == TrafficType.Guest)) {
+                for (final Nic nic: _nicDao.listByVmId(vmId)) {
+                    final NetworkVO nw = _networksDao.findById(nic.getNetworkId());
+                    if (nw.getTrafficType() == TrafficType.Guest) {
+                        return _configMgr.getNetworkOfferingNetworkRate(nw.getNetworkOfferingId(), network.getDataCenterId());
+                    }
+                }
+            }
+            if (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm) {
+                return -1;
+            }
+        }
+        if (ntwkOff != null) {
+            return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId(), network.getDataCenterId());
+        }
+        final Integer networkRate = NetworkOrchestrationService.NetworkThrottlingRate.valueIn(network.getDataCenterId());
+        if (networkRate != null && networkRate > 0) {
+            return networkRate;
+        }
+        return -1;
+    }
+
+    @Override
+    public String getAccountNetworkDomain(long accountId, long zoneId) {
+        String networkDomain = _accountDao.findById(accountId).getNetworkDomain();
+
+        if (networkDomain == null) {
+            // get domain level network domain
+            return getDomainNetworkDomain(_accountDao.findById(accountId).getDomainId(), zoneId);
+        }
+
+        return networkDomain;
+    }
+
+    @Override
+    public String getStartIpAddress(long networkId) {
+        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
+        if (vlans.isEmpty()) {
+            return null;
+        }
+
+        String startIP = vlans.get(0).getIpRange().split("-")[0];
+
+        for (VlanVO vlan : vlans) {
+            String startIP1 = vlan.getIpRange().split("-")[0];
+            long startIPLong = NetUtils.ip2Long(startIP);
+            long startIPLong1 = NetUtils.ip2Long(startIP1);
+
+            if (startIPLong1 < startIPLong) {
+                startIP = startIP1;
+            }
+        }
+
+        return startIP;
+    }
+
+    @Override
+    public Long getPodIdForVlan(long vlanDbId) {
+        PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId);
+        if (podVlanMaps == null) {
+            return null;
+        } else {
+            return podVlanMaps.getPodId();
+        }
+    }
+
+    @Override
+    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
+        Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
+        List<NetworkOfferingServiceMapVO> map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId);
+
+        for (NetworkOfferingServiceMapVO instance : map) {
+            String service = instance.getService();
+            Set<Provider> providers;
+            providers = serviceProviderMap.get(Service.getService(service));
+            if (providers == null) {
+                providers = new HashSet<Provider>();
+            }
+            providers.add(Provider.getProvider(instance.getProvider()));
+            serviceProviderMap.put(Service.getService(service), providers);
+        }
+
+        return serviceProviderMap;
+    }
+
+    @Override
+    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
+        return _ntwkSrvcDao.canProviderSupportServiceInNetwork(networkId, service, provider);
+    }
+
+    @Override
+    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
+        Network.Service service = null;
+        if (serviceName != null) {
+            service = Network.Service.getService(serviceName);
+            if (service == null) {
+                throw new InvalidParameterValueException("Invalid Network Service=" + serviceName);
+            }
+        }
+
+        Set<Provider> supportedProviders = new HashSet<Provider>();
+
+        if (service != null) {
+            List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
+            if (providers != null && !providers.isEmpty()) {
+                supportedProviders.addAll(providers);
+            }
+        } else {
+            for (List<Provider> pList : s_serviceToImplementedProvidersMap.values()) {
+                supportedProviders.addAll(pList);
+            }
+        }
+
+        return new ArrayList<Provider>(supportedProviders);
+    }
+
+    @Override
+    public Provider getDefaultUniqueProviderForService(String serviceName) {
+        List<? extends Provider> providers = listSupportedNetworkServiceProviders(serviceName);
+        if (providers.isEmpty()) {
+            throw new CloudRuntimeException("No providers supporting service " + serviceName + " found in cloudStack");
+        }
+        if (providers.size() > 1) {
+            throw new CloudRuntimeException("More than 1 provider supporting service " + serviceName + " found in cloudStack");
+        }
+
+        return providers.get(0);
+    }
+
+    @Override
+    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
+        List<PhysicalNetworkVO> pNtwks = new ArrayList<PhysicalNetworkVO>();
+        if (trafficType != null) {
+            pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
+        } else {
+            pNtwks = _physicalNetworkDao.listByZone(zoneId);
+        }
+
+        if (pNtwks.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId);
+        }
+
+        if (pNtwks.size() > 1) {
+            if (tag == null) {
+                throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId +
+                    " and no tags are specified in order to make a choice");
+            }
+
+            Long pNtwkId = null;
+            for (PhysicalNetwork pNtwk : pNtwks) {
+                if (pNtwk.getTags().contains(tag)) {
+                    s_logger.debug("Found physical network id=" + pNtwk.getId() + " based on requested tags " + tag);
+                    pNtwkId = pNtwk.getId();
+                    break;
+                }
+            }
+            if (pNtwkId == null) {
+                throw new InvalidParameterValueException("Unable to find physical network which match the tags " + tag);
+            }
+            return pNtwkId;
+        } else {
+            return pNtwks.get(0).getId();
+        }
+    }
+
+    @Override
+    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
+        List<Long> offeringsToReturn = new ArrayList<Long>();
+        NetworkOffering originalOffering = _entityMgr.findById(NetworkOffering.class, getNetwork(networkId).getNetworkOfferingId());
+
+        boolean securityGroupSupportedByOriginalOff = areServicesSupportedByNetworkOffering(originalOffering.getId(), Service.SecurityGroup);
+
+        // security group supported property should be the same
+
+        List<Long> offerings = _networkOfferingDao.getOfferingIdsToUpgradeFrom(originalOffering);
+
+        for (Long offeringId : offerings) {
+            if (areServicesSupportedByNetworkOffering(offeringId, Service.SecurityGroup) == securityGroupSupportedByOriginalOff) {
+                offeringsToReturn.add(offeringId);
+            }
+        }
+
+        return offeringsToReturn;
+    }
+
+    @Override
+    public boolean isSecurityGroupSupportedInNetwork(Network network) {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            s_logger.trace("Security group can be enabled for Guest networks only; and network " + network + " has a diff traffic type");
+            return false;
+        }
+
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
+        if (physicalNetworkId == null) {
+            physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), null, null);
+        }
+
+        return isServiceEnabledInNetwork(physicalNetworkId, network.getId(), Service.SecurityGroup);
+    }
+
+    @Override
+    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+
+        List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
+        DataCenter dc = ApiDBUtils.findZoneById(zoneId);
+        String dcUuid = String.valueOf(zoneId);
+        if (dc != null) {
+            dcUuid = dc.getUuid();
+        }
+
+        if (networkList.isEmpty()) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in the specified zone id");
+            ex.addProxyObject(dcUuid, "zoneId");
+            throw ex;
+        }
+
+        if (networkList.size() > 1) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType);
+            ex.addProxyObject(dcUuid, "zoneId");
+            throw ex;
+        }
+
+        return networkList.get(0);
+    }
+
+    @Override
+    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        try {
+            PhysicalNetwork mgmtPhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Management);
+            PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
+            if (mgmtTraffic != null) {
+                String label = null;
+                switch (hypervisorType) {
+                    case XenServer:
+                        label = mgmtTraffic.getXenNetworkLabel();
+                        break;
+                    case KVM:
+                        label = mgmtTraffic.getKvmNetworkLabel();
+                        break;
+                    case VMware:
+                        label = mgmtTraffic.getVmwareNetworkLabel();
+                        break;
+                    case Hyperv:
+                        label = mgmtTraffic.getHypervNetworkLabel();
+                        break;
+                    case Ovm3:
+                        label = mgmtTraffic.getOvm3NetworkLabel();
+                        break;
+                }
+                return label;
+            }
+        } catch (Exception ex) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
+                    ex.getMessage());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        try {
+            PhysicalNetwork storagePhyNetwork = getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage);
+            PhysicalNetworkTrafficTypeVO storageTraffic = _pNTrafficTypeDao.findBy(storagePhyNetwork.getId(), TrafficType.Storage);
+            if (storageTraffic != null) {
+                String label = null;
+                switch (hypervisorType) {
+                    case XenServer:
+                        label = storageTraffic.getXenNetworkLabel();
+                        break;
+                    case KVM:
+                        label = storageTraffic.getKvmNetworkLabel();
+                        break;
+                    case VMware:
+                        label = storageTraffic.getVmwareNetworkLabel();
+                        break;
+                    case Hyperv:
+                        label = storageTraffic.getHypervNetworkLabel();
+                        break;
+                    case Ovm3:
+                        label = storageTraffic.getOvm3NetworkLabel();
+                        break;
+                }
+                return label;
+            }
+        } catch (Exception ex) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to retrive the default label for storage traffic:" + "zone: " + zoneId + " hypervisor: " + hypervisorType + " due to:" +
+                    ex.getMessage());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
+        List<PhysicalNetworkSetupInfo> networkInfoList = new ArrayList<PhysicalNetworkSetupInfo>();
+        List<PhysicalNetworkVO> physicalNtwkList = _physicalNetworkDao.listByZone(dcId);
+        for (PhysicalNetworkVO pNtwk : physicalNtwkList) {
+            String publicName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Public, hypervisorType);
+            String privateName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Management, hypervisorType);
+            String guestName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Guest, hypervisorType);
+            String storageName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Storage, hypervisorType);
+            // String controlName = _pNTrafficTypeDao.getNetworkTag(pNtwk.getId(), TrafficType.Control, hypervisorType);
+            PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo();
+            info.setPhysicalNetworkId(pNtwk.getId());
+            info.setGuestNetworkName(guestName);
+            info.setPrivateNetworkName(privateName);
+            info.setPublicNetworkName(publicName);
+            info.setStorageNetworkName(storageName);
+            PhysicalNetworkTrafficTypeVO mgmtTraffic = _pNTrafficTypeDao.findBy(pNtwk.getId(), TrafficType.Management);
+            if (mgmtTraffic != null) {
+                String vlan = mgmtTraffic.getVlan();
+                info.setMgmtVlan(vlan);
+            }
+            networkInfoList.add(info);
+        }
+        return networkInfoList;
+    }
+
+    @Override
+    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
+        PhysicalNetworkServiceProviderVO ntwkSvcProvider = _pNSPDao.findByServiceProvider(physicalNetowrkId, providerName);
+        if (ntwkSvcProvider == null) {
+            s_logger.warn("Unable to find provider " + providerName + " in physical network id=" + physicalNetowrkId);
+            return false;
+        }
+        return isProviderEnabled(ntwkSvcProvider);
+    }
+
+    @Override
+    public boolean isProviderEnabledInZone(long zoneId, String provider) {
+        //the provider has to be enabled at least in one network in the zone
+        for (PhysicalNetwork pNtwk : _physicalNetworkDao.listByZone(zoneId)) {
+            if (isProviderEnabledInPhysicalNetwork(pNtwk.getId(), provider)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public String getNetworkTag(HypervisorType hType, Network network) {
+        // no network tag for control traffic type
+        TrafficType effectiveTrafficType = network.getTrafficType();
+        if (hType == HypervisorType.VMware && effectiveTrafficType == TrafficType.Control)
+            effectiveTrafficType = TrafficType.Management;
+
+        if (effectiveTrafficType == TrafficType.Control) {
+            return null;
+        }
+
+        Long physicalNetworkId = null;
+        if (effectiveTrafficType != TrafficType.Guest) {
+            physicalNetworkId = getNonGuestNetworkPhysicalNetworkId(network, effectiveTrafficType);
+        } else {
+            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+            physicalNetworkId = network.getPhysicalNetworkId();
+            if (physicalNetworkId == null) {
+                physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
+            }
+        }
+
+        if (physicalNetworkId == null) {
+            assert (false) : "Can't get the physical network";
+            s_logger.warn("Can't get the physical network");
+            return null;
+        }
+
+        return _pNTrafficTypeDao.getNetworkTag(physicalNetworkId, effectiveTrafficType, hType);
+    }
+
+    @Override
+    public NetworkVO getExclusiveGuestNetwork(long zoneId) {
+        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, zoneId, GuestType.Shared, TrafficType.Guest);
+        if (networks == null || networks.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " +
+                zoneId);
+        }
+
+        if (networks.size() > 1) {
+            throw new InvalidParameterValueException("Found more than 1 network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared +
+                " in zone " + zoneId);
+
+        }
+
+        return networks.get(0);
+    }
+
+    @Override
+    public boolean isNetworkSystem(Network network) {
+        NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        if (no.isSystemOnly()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public Long getPhysicalNetworkId(Network network) {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            return getNonGuestNetworkPhysicalNetworkId(network);
+        }
+
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+        if (physicalNetworkId == null) {
+            physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), offering.getTags(), offering.getTrafficType());
+        }
+        return physicalNetworkId;
+    }
+
+    @Override
+    public boolean getAllowSubdomainAccessGlobal() {
+        return _allowSubdomainNetworkAccess;
+    }
+
+    @Override
+    public boolean isProviderForNetwork(Provider provider, long networkId) {
+        if (_ntwkSrvcDao.isProviderForNetwork(networkId, provider) != null) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
+        if (_ntwkOfferingSrvcDao.isProviderForNetworkOffering(networkOfferingId, provider)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
+        for (Provider provider : providersMap.keySet()) {
+            // check if services can be turned off
+            NetworkElement element = getElementImplementingProvider(provider.getName());
+            if (element == null) {
+                throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getName() + "'");
+            }
+
+            Set<Service> enabledServices = new HashSet<Service>();
+            enabledServices.addAll(providersMap.get(provider));
+
+            if (enabledServices != null && !enabledServices.isEmpty()) {
+                if (!element.canEnableIndividualServices()) {
+                    Set<Service> requiredServices = new HashSet<Service>();
+                    requiredServices.addAll(element.getCapabilities().keySet());
+
+                    if (requiredServices.contains(Network.Service.Gateway)) {
+                        requiredServices.remove(Network.Service.Gateway);
+                    }
+
+                    if (requiredServices.contains(Network.Service.Firewall)) {
+                        requiredServices.remove(Network.Service.Firewall);
+                    }
+
+                    if (enabledServices.contains(Network.Service.Firewall)) {
+                        enabledServices.remove(Network.Service.Firewall);
+                    }
+
+                    // exclude gateway service
+                    if (enabledServices.size() != requiredServices.size()) {
+                        StringBuilder servicesSet = new StringBuilder();
+
+                        for (Service requiredService : requiredServices) {
+                            // skip gateway service as we don't allow setting it via API
+                            if (requiredService == Service.Gateway) {
+                                continue;
+                            }
+                            servicesSet.append(requiredService.getName() + ", ");
+                        }
+                        servicesSet.delete(servicesSet.toString().length() - 2, servicesSet.toString().length());
+
+                        throw new InvalidParameterValueException("Cannot enable subset of Services, Please specify the complete list of Services: " +
+                            servicesSet.toString() + "  for Service Provider " + provider.getName());
+                    }
+                }
+                List<String> serviceList = new ArrayList<String>();
+                for (Service service : enabledServices) {
+                    // check if the service is provided by this Provider
+                    if (!element.getCapabilities().containsKey(service)) {
+                        throw new UnsupportedServiceException(provider.getName() + " Provider cannot provide service " + service.getName());
+                    }
+                    serviceList.add(service.getName());
+                }
+                if (!element.verifyServicesCombination(enabledServices)) {
+                    throw new UnsupportedServiceException("Provider " + provider.getName() + " doesn't support services combination: " + serviceList);
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean canAddDefaultSecurityGroup() {
+        String defaultAdding = _configDao.getValue(Config.SecurityGroupDefaultAdding.key());
+        return (defaultAdding != null && defaultAdding.equalsIgnoreCase("true"));
+    }
+
+    @Override
+    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
+        List<Service> services = new ArrayList<Service>();
+        List<String> servicesStr = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(networkOfferingId);
+        for (String serviceStr : servicesStr) {
+            services.add(Service.getService(serviceStr));
+        }
+
+        return services;
+    }
+
+    @Override
+    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
+        long physicalNtwkId = findPhysicalNetworkId(zoneId, offering.getTags(), offering.getTrafficType());
+        boolean result = true;
+        List<String> checkedProvider = new ArrayList<String>();
+        for (Service service : services) {
+            // get all the providers, and check if each provider is enabled
+            List<String> providerNames = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
+            for (String providerName : providerNames) {
+                if (!checkedProvider.contains(providerName)) {
+                    result = result && isProviderEnabledInPhysicalNetwork(physicalNtwkId, providerName);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean checkIpForService(IpAddress userIp, Service service, Long networkId) {
+        if (networkId == null) {
+            networkId = userIp.getAssociatedWithNetworkId();
+        }
+
+        NetworkVO network = _networksDao.findById(networkId);
+        NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if (offering.getGuestType() != GuestType.Isolated) {
+            return true;
+        }
+        IPAddressVO ipVO = _ipAddressDao.findById(userIp.getId());
+        PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipVO, _vlanDao.findById(userIp.getVlanId()));
+        if (!canIpUsedForService(publicIp, service, networkId)) {
+            return false;
+        }
+        if (!offering.isConserveMode()) {
+            return canIpUsedForNonConserveService(publicIp, service);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
+        for (Provider provider : providers) {
+            NetworkElement element = getElementImplementingProvider(provider.getName());
+            if (element != null) {
+                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+                if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
+                            " implementing Provider=" + provider.getName());
+                }
+                Map<Capability, String> serviceCapabilities = elementCapabilities.get(service);
+                if (serviceCapabilities == null || serviceCapabilities.isEmpty()) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilites for element=" + element.getName() +
+                            " implementing Provider=" + provider.getName());
+                }
+
+                if (serviceCapabilities.containsKey(cap)) {
+                    return true;
+                }
+            } else {
+                throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName());
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
+        for (Provider provider : providers) {
+            NetworkElement element = getElementImplementingProvider(provider.getName());
+            if (element != null) {
+                Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+                if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() +
+                        " implementing Provider=" + provider.getName());
+                }
+                Map<Capability, String> serviceCapabilities = elementCapabilities.get(service);
+                if (serviceCapabilities == null || serviceCapabilities.isEmpty()) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilities for element=" + element.getName() +
+                        " implementing Provider=" + provider.getName());
+                }
+
+                String value = serviceCapabilities.get(cap);
+                if (value == null || value.isEmpty()) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capability " + cap.getName() + " for element=" +
+                        element.getName() + " implementing Provider=" + provider.getName());
+                }
+
+                if (!value.toLowerCase().contains(capValue.toLowerCase())) {
+                    throw new UnsupportedServiceException("Service " + service.getName() + " doesn't support value " + capValue + " for capability " + cap.getName() +
+                        " for element=" + element.getName() + " implementing Provider=" + provider.getName());
+                }
+            } else {
+                throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName());
+            }
+        }
+    }
+
+    @Override
+    public void checkNetworkPermissions(Account owner, Network network) {
+        // dahn 20140310: I was thinking of making this an assert but
+        //                as we hardly ever test with asserts I think
+        //                we better make sure at runtime.
+        if (network == null) {
+            throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
+        }
+        // Perform account permission check
+        if ((network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) ||
+                (network.getGuestType() == GuestType.Shared && network.getAclType() == ACLType.Account)) {
+            AccountVO networkOwner = _accountDao.findById(network.getAccountId());
+            if (networkOwner == null)
+                throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
+                    ", network does not have an owner");
+            if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
+                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
+                        ", permission denied");
+                }
+            } else {
+                List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
+                if (networkMap == null || networkMap.isEmpty()) {
+                    throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
+                        ", permission denied");
+                }
+            }
+
+        } else {
+            if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) {
+                DomainVO ownerDomain = _domainDao.findById(owner.getDomainId());
+                if (ownerDomain == null) {
+                    throw new CloudRuntimeException("cannot check permission on account " + owner.getAccountName() + " whose domain does not exist");
+                }
+                throw new PermissionDeniedException("Shared network id=" + ((NetworkVO)network).getUuid() + " is not available in domain id=" +
+                        ownerDomain.getUuid());
+            }
+        }
+    }
+
+    @Override
+    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType hypervisorType) {
+        try {
+            PhysicalNetwork publicPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public);
+            PhysicalNetworkTrafficTypeVO publicTraffic = _pNTrafficTypeDao.findBy(publicPhyNetwork.getId(), TrafficType.Public);
+            if (publicTraffic != null) {
+                String label = null;
+                switch (hypervisorType) {
+                    case XenServer:
+                        label = publicTraffic.getXenNetworkLabel();
+                        break;
+                    case KVM:
+                        label = publicTraffic.getKvmNetworkLabel();
+                        break;
+                    case VMware:
+                        label = publicTraffic.getVmwareNetworkLabel();
+                        break;
+                    case Hyperv:
+                        label = publicTraffic.getHypervNetworkLabel();
+                        break;
+                    case Ovm3:
+                        label = publicTraffic.getOvm3NetworkLabel();
+                        break;
+                }
+                return label;
+            }
+        } catch (Exception ex) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to retrieve the default label for public traffic." + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to: " +
+                    ex.getMessage());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType hypervisorType) {
+        try {
+            PhysicalNetwork guestPhyNetwork = getOnePhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Guest);
+            PhysicalNetworkTrafficTypeVO guestTraffic = _pNTrafficTypeDao.findBy(guestPhyNetwork.getId(), TrafficType.Guest);
+            if (guestTraffic != null) {
+                String label = null;
+                switch (hypervisorType) {
+                    case XenServer:
+                        label = guestTraffic.getXenNetworkLabel();
+                        break;
+                    case KVM:
+                        label = guestTraffic.getKvmNetworkLabel();
+                        break;
+                    case VMware:
+                        label = guestTraffic.getVmwareNetworkLabel();
+                        break;
+                    case Hyperv:
+                        label = guestTraffic.getHypervNetworkLabel();
+                        break;
+                    case Ovm3:
+                        label = guestTraffic.getOvm3NetworkLabel();
+                        break;
+                }
+                return label;
+            }
+        } catch (Exception ex) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to retrive the default label for guest traffic:" + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to:" +
+                    ex.getMessage());
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<? extends Network> listNetworksByVpc(long vpcId) {
+        return _networksDao.listByVpc(vpcId);
+    }
+
+    @Override
+    public List<Provider> getNtwkOffDistinctProviders(long ntkwOffId) {
+        List<String> providerNames = _ntwkOfferingSrvcDao.getDistinctProviders(ntkwOffId);
+        List<Provider> providers = new ArrayList<Provider>();
+        for (String providerName : providerNames) {
+            providers.add(Network.Provider.getProvider(providerName));
+        }
+
+        return providers;
+    }
+
+    @Override
+    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
+        if (_nicDao.findNonReleasedByInstanceIdAndNetworkId(ntwkId, vmId) != null) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
+
+        List<? extends PhysicalNetwork> pNtwks = _physicalNetworkDao.listByZone(zoneId);
+
+        Iterator<? extends PhysicalNetwork> it = pNtwks.iterator();
+        while (it.hasNext()) {
+            PhysicalNetwork pNtwk = it.next();
+            if (!_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
+                it.remove();
+            }
+        }
+        return pNtwks;
+    }
+
+    @Override
+    public boolean isPrivateGateway(long ntwkId) {
+        Network network = getNetwork(ntwkId);
+        if (network.getTrafficType() != TrafficType.Guest || network.getNetworkOfferingId() != s_privateOfferingId.longValue()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
+        List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(offeringNames.length);
+        for (String offeringName : offeringNames) {
+            NetworkOfferingVO network = _systemNetworks.get(offeringName);
+            if (network == null) {
+                throw new CloudRuntimeException("Unable to find system network profile for " + offeringName);
+            }
+            offerings.add(network);
+        }
+        return offerings;
+    }
+
+    @Override
+    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
+        Long networkDomainId = null;
+        Network network = getNetwork(networkId);
+        if (network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) {
+            s_logger.trace("Network id=" + networkId + " is not shared or L2");
+            return false;
+        }
+
+        NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
+        if (networkDomainMap == null) {
+            s_logger.trace("Network id=" + networkId + " is shared or L2, but not domain specific");
+            return true;
+        } else {
+            networkDomainId = networkDomainMap.getDomainId();
+        }
+
+        if (domainId == networkDomainId.longValue()) {
+            return true;
+        }
+
+        if (networkDomainMap.subdomainAccess) {
+            Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
+
+            if (parentDomains.contains(networkDomainId)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public Set<Long> getAvailableIps(Network network, String requestedIp) {
+        if (network.getCidr() == null) {
+            return Collections.emptySet();
+        }
+        String[] cidr = network.getCidr().split("/");
+        List<String> ips = getUsedIpsInNetwork(network);
+        Set<Long> usedIps = new TreeSet<Long>();
+
+        for (String ip : ips) {
+            if (requestedIp != null && requestedIp.equals(ip)) {
+                s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
+                return null;
+            }
+
+            usedIps.add(NetUtils.ip2Long(ip));
+        }
+
+        Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
+
+        String gateway = network.getGateway();
+        if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))
+            allPossibleIps.remove(NetUtils.ip2Long(gateway));
+
+        return allPossibleIps;
+    }
+
+    @Override
+    public List<String> getUsedIpsInNetwork(Network network) {
+        //Get all ips used by vms nics
+        List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
+        //Get all secondary ips for nics
+        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
+        ips.addAll(secondaryIps);
+        //Get ips used by load balancers
+        List<String> lbIps = _appLbRuleDao.listLbIpsBySourceIpNetworkId(network.getId());
+        ips.addAll(lbIps);
+        return ips;
+    }
+
+    @Override
+    public String getDomainNetworkDomain(long domainId, long zoneId) {
+        String networkDomain = null;
+        Long searchDomainId = domainId;
+        while (searchDomainId != null) {
+            DomainVO domain = _domainDao.findById(searchDomainId);
+            if (domain.getNetworkDomain() != null) {
+                networkDomain = domain.getNetworkDomain();
+                break;
+            }
+            searchDomainId = domain.getParent();
+        }
+        if (networkDomain == null) {
+            return getZoneNetworkDomain(zoneId);
+        }
+        return networkDomain;
+    }
+
+    boolean isProviderEnabled(PhysicalNetworkServiceProvider provider) {
+        if (provider == null || provider.getState() != PhysicalNetworkServiceProvider.State.Enabled) { // TODO: check
+            // for other states: Shutdown?
+            return false;
+        }
+        return true;
+    }
+
+    boolean isServiceEnabledInNetwork(long physicalNetworkId, long networkId, Service service) {
+        // check if the service is supported in the network
+        if (!areServicesSupportedInNetwork(networkId, service)) {
+            s_logger.debug("Service " + service.getName() + " is not supported in the network id=" + networkId);
+            return false;
+        }
+
+        // get provider for the service and check if all of them are supported
+        String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(networkId, service);
+        if (!isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
+            s_logger.debug("Provider " + provider + " is not enabled in physical network id=" + physicalNetworkId);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
+        return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
+    }
+
+    String getZoneNetworkDomain(long zoneId) {
+        return _dcDao.findById(zoneId).getDomain();
+    }
+
+    PhysicalNetwork getOnePhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        List<PhysicalNetworkVO> networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
+
+        if (networkList.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in zone id=" + zoneId + ". ");
+        }
+
+        if (networkList.size() > 1) {
+            s_logger.info("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType + ". ");
+        }
+
+        return networkList.get(0);
+    }
+
+    protected Long getNonGuestNetworkPhysicalNetworkId(Network network, TrafficType trafficType) {
+        // VMware control network is management network
+        // we need to retrieve traffic label information through physical network
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        if (physicalNetworkId == null) {
+            List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
+            if (pNtwks.size() == 1) {
+                physicalNetworkId = pNtwks.get(0).getId();
+            } else {
+                // locate physicalNetwork with supported traffic type
+                // We can make this assumptions based on the fact that Public/Management/Control traffic types are
+                // supported only in one physical network in the zone in 3.0
+                for (PhysicalNetworkVO pNtwk : pNtwks) {
+                    if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) {
+                        physicalNetworkId = pNtwk.getId();
+                        break;
+                    }
+                }
+            }
+        }
+        return physicalNetworkId;
+    }
+
+    protected Long getNonGuestNetworkPhysicalNetworkId(Network network) {
+        // no physical network for control traffic type
+
+        // have to remove this sanity check as VMware control network is management network
+        // we need to retrieve traffic label information through physical network
+        /*
+                if (network.getTrafficType() == TrafficType.Control) {
+                    return null;
+                }
+        */
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        if (physicalNetworkId == null) {
+            List<PhysicalNetworkVO> pNtwks = _physicalNetworkDao.listByZone(network.getDataCenterId());
+            if (pNtwks.size() == 1) {
+                physicalNetworkId = pNtwks.get(0).getId();
+            } else {
+                // locate physicalNetwork with supported traffic type
+                // We can make this assumptions based on the fact that Public/Management/Control traffic types are
+                // supported only in one physical network in the zone in 3.0
+                for (PhysicalNetworkVO pNtwk : pNtwks) {
+                    if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), network.getTrafficType())) {
+                        physicalNetworkId = pNtwk.getId();
+                        break;
+                    }
+                }
+            }
+        }
+        return physicalNetworkId;
+    }
+
+    @Override
+    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
+        NicVO nic = null;
+        if (broadcastUri != null) {
+            nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(networkId, vm.getId(), broadcastUri);
+        } else {
+            nic = _nicDao.findByNtwkIdAndInstanceId(networkId, vm.getId());
+        }
+        if (nic == null) {
+            return null;
+        }
+        NetworkVO network = _networksDao.findById(networkId);
+        Integer networkRate = getNetworkRate(network.getId(), vm.getId());
+
+//        NetworkGuru guru = _networkGurus.get(network.getGuruName());
+        NicProfile profile =
+            new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(
+                vm.getHypervisorType(), network));
+//        guru.updateNicProfile(profile, network);
+        return profile;
+    }
+
+    @Override
+    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
+        List<Provider> networkProviders = getNetworkProviders(networkId);
+        for (Provider provider : networkProviders) {
+            if (provider.isExternal()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private List<Provider> getNetworkProviders(long networkId) {
+        List<String> providerNames = _ntwkSrvcDao.getDistinctProviders(networkId);
+        Map<String, Provider> providers = new HashMap<String, Provider>();
+        for (String providerName : providerNames) {
+            if (!providers.containsKey(providerName)) {
+                providers.put(providerName, Network.Provider.getProvider(providerName));
+            }
+        }
+
+        return new ArrayList<Provider>(providers.values());
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _configs = _configDao.getConfiguration("Network", params);
+        _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key()));
+        _executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key()));
+
+        NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPublicNetwork, TrafficType.Public, true);
+        publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering);
+        _systemNetworks.put(NetworkOffering.SystemPublicNetwork, publicNetworkOffering);
+        NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemManagementNetwork, TrafficType.Management, false);
+        managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering);
+        _systemNetworks.put(NetworkOffering.SystemManagementNetwork, managementNetworkOffering);
+        NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemControlNetwork, TrafficType.Control, false);
+        controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
+        _systemNetworks.put(NetworkOffering.SystemControlNetwork, controlNetworkOffering);
+        NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
+        storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
+        _systemNetworks.put(NetworkOffering.SystemStorageNetwork, storageNetworkOffering);
+        NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
+        privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
+        _systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering);
+        s_privateOfferingId = privateGatewayNetworkOffering.getId();
+
+        IpAddressSearch = _ipAddressDao.createSearchBuilder();
+        IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
+        IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
+        IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ);
+        IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ);
+        SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
+        virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
+        IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(),
+            JoinBuilder.JoinType.INNER);
+        IpAddressSearch.done();
+
+        NicForTrafficTypeSearch = _nicDao.createSearchBuilder();
+        SearchBuilder<NetworkVO> networkSearch = _networksDao.createSearchBuilder();
+        NicForTrafficTypeSearch.join("network", networkSearch, networkSearch.entity().getId(), NicForTrafficTypeSearch.entity().getNetworkId(), JoinType.INNER);
+        NicForTrafficTypeSearch.and("instance", NicForTrafficTypeSearch.entity().getInstanceId(), Op.EQ);
+        networkSearch.and("traffictype", networkSearch.entity().getTrafficType(), Op.EQ);
+        NicForTrafficTypeSearch.done();
+
+        s_logger.info("Network Model is configured.");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        // populate s_serviceToImplementedProvidersMap & s_providerToNetworkElementMap with current _networkElements
+        // Need to do this in start() since _networkElements are not completely configured until then.
+        for (NetworkElement element : networkElements) {
+            Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
+            Provider implementedProvider = element.getProvider();
+            if (implementedProvider != null) {
+                if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) {
+                    s_logger.error("Cannot start NetworkModel: Provider <-> NetworkElement must be a one-to-one map, " + "multiple NetworkElements found for Provider: " +
+                        implementedProvider.getName());
+                    continue;
+                }
+                s_logger.info("Add provider <-> element map entry. " + implementedProvider.getName() + "-" + element.getName() + "-" + element.getClass().getSimpleName());
+                s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName());
+            }
+            if (capabilities != null && implementedProvider != null) {
+                for (Service service : capabilities.keySet()) {
+                    if (s_serviceToImplementedProvidersMap.containsKey(service)) {
+                        List<Provider> providers = s_serviceToImplementedProvidersMap.get(service);
+                        providers.add(implementedProvider);
+                    } else {
+                        List<Provider> providers = new ArrayList<Provider>();
+                        providers.add(implementedProvider);
+                        s_serviceToImplementedProvidersMap.put(service, providers);
+                    }
+                }
+            }
+        }
+
+        //After network elements are configured correctly, verify ConfigDrive entries on enabled zones
+        verifyDisabledConfigDriveEntriesOnEnabledZones();
+
+        s_logger.info("Started Network Model");
+        return true;
+    }
+
+    /**
+     * Verifies ConfigDrive entries on a zone and adds disabled ConfigDrive provider if missing.
+     */
+    protected void addDisabledConfigDriveEntriesOnZone(DataCenterVO zone) {
+        if (zone.getNetworkType() == DataCenter.NetworkType.Advanced) {
+            List<PhysicalNetworkVO> physicalNetworks = _physicalNetworkDao.listByZoneAndTrafficType(
+                    zone.getId(), TrafficType.Guest);
+            for (PhysicalNetworkVO physicalNetworkVO : physicalNetworks) {
+                PhysicalNetworkServiceProviderVO provider = _pNSPDao.findByServiceProvider(
+                        physicalNetworkVO.getId(), Provider.ConfigDrive.getName());
+                if (provider == null) {
+                    _networkService.addProviderToPhysicalNetwork(
+                            physicalNetworkVO.getId(), Provider.ConfigDrive.getName(), null, null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Verifies ConfigDrive entries on enabled zones, adds disabled ConfigDrive provider if missing.
+     */
+    protected void verifyDisabledConfigDriveEntriesOnEnabledZones() {
+        List<DataCenterVO> zones = _dcDao.listEnabledZones();
+        if (CollectionUtils.isNotEmpty(zones)) {
+            for (DataCenterVO zone : zones) {
+                addDisabledConfigDriveEntriesOnZone(zone);
+            }
+        }
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
+        List<? extends IpAddress> addrs = listPublicIpsAssignedToGuestNtwk(owner.getId(), guestNetwork.getId(), true);
+
+        IPAddressVO sourceNatIp = null;
+        if (addrs.isEmpty()) {
+            return null;
+        } else {
+            for (IpAddress addr : addrs) {
+                if (addr.isSourceNat()) {
+                    sourceNatIp = _ipAddressDao.findById(addr.getId());
+                    return PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public boolean isNetworkInlineMode(Network network) {
+        NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        return offering.isInline();
+    }
+
+    @Override
+    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
+        if (!NetUtils.isValidIp6(startIPv6)) {
+            throw new InvalidParameterValueException("Invalid format for the startIPv6 parameter");
+        }
+        if (!NetUtils.isValidIp6(endIPv6)) {
+            throw new InvalidParameterValueException("Invalid format for the endIPv6 parameter");
+        }
+
+        if (!(ip6Gateway != null && ip6Cidr != null)) {
+            throw new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in");
+        }
+
+        if (!NetUtils.isValidIp6(ip6Gateway)) {
+            throw new InvalidParameterValueException("Invalid ip6Gateway");
+        }
+        if (!NetUtils.isValidIp6Cidr(ip6Cidr)) {
+            throw new InvalidParameterValueException("Invalid ip6cidr");
+        }
+        if (!NetUtils.isIp6InNetwork(startIPv6, ip6Cidr)) {
+            throw new InvalidParameterValueException("startIPv6 is not in ip6cidr indicated network!");
+        }
+        if (!NetUtils.isIp6InNetwork(endIPv6, ip6Cidr)) {
+            throw new InvalidParameterValueException("endIPv6 is not in ip6cidr indicated network!");
+        }
+        if (!NetUtils.isIp6InNetwork(ip6Gateway, ip6Cidr)) {
+            throw new InvalidParameterValueException("ip6Gateway is not in ip6cidr indicated network!");
+        }
+
+        int cidrSize = NetUtils.getIp6CidrSize(ip6Cidr);
+        // we only support cidr == 64
+        if (cidrSize != 64) {
+            throw new InvalidParameterValueException("The cidr size of IPv6 network must be 64 bits!");
+        }
+    }
+
+    @Override
+    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
+        String ip4 = ips.getIp4Address();
+        String ip6 = ips.getIp6Address();
+        String mac = ips.getMacAddress();
+        if (ip4 != null) {
+            if (!NetUtils.isValidIp4(ip4)) {
+                throw new InvalidParameterValueException("Invalid specified IPv4 address " + ip4);
+            }
+            //Other checks for ipv4 are done in assignPublicIpAddress()
+        }
+        if (ip6 != null) {
+            if (!NetUtils.isValidIp6(ip6)) {
+                throw new InvalidParameterValueException("Invalid specified IPv6 address " + ip6);
+            }
+            if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip6) != null) {
+                throw new InvalidParameterValueException("The requested IP is already taken!");
+            }
+            List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
+            if (vlans == null) {
+                throw new CloudRuntimeException("Cannot find related vlan attached to network " + networkId);
+            }
+            Vlan ipVlan = null;
+            for (Vlan vlan : vlans) {
+                if (NetUtils.isIp6InRange(ip6, vlan.getIp6Range())) {
+                    ipVlan = vlan;
+                    break;
+                }
+            }
+            if (ipVlan == null) {
+                throw new InvalidParameterValueException("Requested IPv6 is not in the predefined range!");
+            }
+        }
+        if (mac != null) {
+            if(!NetUtils.isValidMac(mac)) {
+                throw new InvalidParameterValueException("Invalid specified MAC address " + mac);
+            }
+            if (_nicDao.findByNetworkIdAndMacAddress(networkId, mac) != null) {
+                throw new InvalidParameterValueException("The requested Mac address is already taken! " + mac);
+            }
+
+        }
+    }
+
+    @Override
+    public String getStartIpv6Address(long networkId) {
+        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
+        if (vlans == null) {
+            return null;
+        }
+        String startIpv6 = null;
+        // Get the start ip of first create vlan(not the lowest, because if you add a lower vlan, lowest vlan would change)
+        for (Vlan vlan : vlans) {
+            if (vlan.getIp6Range() != null) {
+                startIpv6 = vlan.getIp6Range().split("-")[0];
+                break;
+            }
+        }
+        return startIpv6;
+    }
+
+    @Override
+    public NicVO getPlaceholderNicForRouter(Network network, Long podId) {
+        List<NicVO> nics = _nicDao.listPlaceholderNicsByNetworkIdAndVmType(network.getId(), VirtualMachine.Type.DomainRouter);
+        List<? extends Vlan> vlans = new ArrayList<VlanVO>();
+        if (podId != null) {
+            vlans = _vlanDao.listVlansForPod(podId);
+        }
+        for (NicVO nic : nics) {
+            if (nic.getReserver() == null && (nic.getIPv4Address() != null || nic.getIPv6Address() != null)) {
+                if (podId == null) {
+                    return nic;
+                } else {
+                    IpAddress ip = null;
+                    UserIpv6AddressVO ipv6 = null;
+
+                    if (nic.getIPv4Address() != null) {
+                        ip = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address());
+                    } else {
+                        ipv6 = _ipv6Dao.findByNetworkIdAndIp(network.getId(), nic.getIPv6Address());
+                    }
+                    //return nic only when its ip address belong to the pod range (for the Basic zone case)
+                    for (Vlan vlan : vlans) {
+                        if (ip != null && ip.getVlanId() == vlan.getId()) {
+                            return nic;
+                        } else if (ipv6 != null && ipv6.getVlanId() == vlan.getId()) {
+                            return nic;
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
+        List<? extends Network> networks = _networksDao.listByZoneAndTrafficType(zoneId, TrafficType.Public);
+        if (networks.isEmpty() || networks.size() > 1) {
+            throw new CloudRuntimeException("Can't find public network in the zone specified");
+        }
+
+        return _ipAddressDao.findByIpAndSourceNetworkId(networks.get(0).getId(), ipAddress);
+    }
+
+    @Override
+    public Map<Detail, String> getNtwkOffDetails(long offId) {
+        return _ntwkOffDetailsDao.getNtwkOffDetails(offId);
+    }
+
+    @Override
+    public Networks.IsolationType[] listNetworkIsolationMethods() {
+        return Networks.IsolationType.values();
+    }
+
+    @Override
+    public boolean getExecuteInSeqNtwkElmtCmd() {
+        return _executeInSequenceNtwkElmtCmd;
+    }
+
+    @Override
+    public boolean isNetworkReadyForGc(long networkId) {
+        Network network = getNetwork(networkId);
+        List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
+        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(networkId);
+        if (!networkIds.contains(networkId)) {
+            return false;
+        }
+
+        // add an exception for networks that use external networking devices and has secondary guest IP's allocated.
+        // On network GC, when network goes through implement phase a new vlan is allocated, based on the acquired VLAN
+        // id cidr of the network is decided in case of external networking case. While NIC uses reservation strategy 'Start'
+        // which ensures that new primary ip is allocated for the NiC from the new CIDR. Secondary IP's have hardcoded IP's in
+        // network rules. So prevent network GC.
+        if (secondaryIps != null && !secondaryIps.isEmpty() && networkIsConfiguredForExternalNetworking(network.getDataCenterId(), networkId)) {
+            return false;
+        }
+
+        //if the network has vms in Starting state (nics for those might not be allocated yet as Starting state also used when vm is being Created)
+        //don't GC
+        if (_nicDao.countNicsForStartingVms(networkId) > 0) {
+            s_logger.debug("Network id=" + networkId + " is not ready for GC as it has vms that are Starting at the moment");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
+        NetworkVO network = _networksDao.findById(networkId);
+
+        if (network != null) {
+            NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+            return offering.isEgressDefaultPolicy();
+        } else {
+            InvalidParameterValueException ex = new InvalidParameterValueException("network with network id does not exist");
+            throw ex;
+        }
+    }
+
+    @Override
+    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
+                                         String vmName, String vmHostName, long vmId, String vmUuid,
+                                         String guestIpAddress, String publicKey, String password, Boolean isWindows) {
+
+        DataCenterVO dcVo = _dcDao.findById(datacenterId);
+        final String zoneName = dcVo.getName();
+
+        IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId);
+
+        final List<String[]> vmData = new ArrayList<String[]>();
+
+        if (userData != null) {
+            vmData.add(new String[]{USERDATA_DIR, USERDATA_FILE, userData});
+        }
+        vmData.add(new String[]{METATDATA_DIR, SERVICE_OFFERING_FILE, StringUtils.unicodeEscape(serviceOffering)});
+        vmData.add(new String[]{METATDATA_DIR, AVAILABILITY_ZONE_FILE, StringUtils.unicodeEscape(zoneName)});
+        vmData.add(new String[]{METATDATA_DIR, LOCAL_HOSTNAME_FILE, StringUtils.unicodeEscape(vmHostName)});
+        vmData.add(new String[]{METATDATA_DIR, LOCAL_IPV4_FILE, guestIpAddress});
+
+        String publicIpAddress = guestIpAddress;
+        String publicHostName = StringUtils.unicodeEscape(vmHostName);
+
+        if (dcVo.getNetworkType() != DataCenter.NetworkType.Basic) {
+            if (publicIp != null) {
+                publicIpAddress = publicIp.getAddress().addr();
+                publicHostName = publicIp.getAddress().addr();
+            } else {
+                publicHostName = null;
+            }
+        }
+        vmData.add(new String[]{METATDATA_DIR, PUBLIC_IPV4_FILE, publicIpAddress});
+        vmData.add(new String[]{METATDATA_DIR, PUBLIC_HOSTNAME_FILE, publicHostName});
+
+        if (vmUuid == null) {
+            vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmName});
+            vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, String.valueOf(vmId)});
+        } else {
+            vmData.add(new String[]{METATDATA_DIR, INSTANCE_ID_FILE, vmUuid});
+            vmData.add(new String[]{METATDATA_DIR, VM_ID_FILE, vmUuid});
+        }
+
+        vmData.add(new String[]{METATDATA_DIR, PUBLIC_KEYS_FILE, publicKey});
+
+        String cloudIdentifier = _configDao.getValue("cloud.identifier");
+        if (cloudIdentifier == null) {
+            cloudIdentifier = "";
+        } else {
+            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
+        }
+        vmData.add(new String[]{METATDATA_DIR, CLOUD_IDENTIFIER_FILE, cloudIdentifier});
+
+        if (password != null && !password.isEmpty() && !password.equals("saved_password")) {
+
+            // Here we are calculating MD5 checksum to reduce the over head of calculating MD5 checksum
+            // in windows VM in password reset script.
+
+            if (isWindows) {
+                MessageDigest md5 = null;
+                try {
+                    md5 = MessageDigest.getInstance("MD5");
+                } catch (NoSuchAlgorithmException e) {
+                    s_logger.error("Unexpected exception " + e.getMessage(), e);
+                    throw new CloudRuntimeException("Unable to get MD5 MessageDigest", e);
+                }
+                md5.reset();
+                md5.update(password.getBytes(StringUtils.getPreferredCharset()));
+                byte[] digest = md5.digest();
+                BigInteger bigInt = new BigInteger(1, digest);
+                String hashtext = bigInt.toString(16);
+
+                vmData.add(new String[]{PASSWORD_DIR, PASSWORD_CHECKSUM_FILE, hashtext});
+            }
+
+            vmData.add(new String[]{PASSWORD_DIR, PASSWORD_FILE, password});
+        }
+
+        return vmData;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return NetworkModel.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {MACIdentifier};
+    }
+
+    @Override
+    public String getValidNetworkCidr(Network guestNetwork) {
+        String networkCidr = guestNetwork.getNetworkCidr();
+        return networkCidr == null ? guestNetwork.getCidr() : networkCidr;
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
new file mode 100644
index 0000000..76d5560
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java
@@ -0,0 +1,4497 @@
+// 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.network;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.security.InvalidParameterException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
+import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DataCenterVnetVO;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.UnsupportedServiceException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork.BroadcastDomainRange;
+import com.cloud.network.VirtualRouterProvider.Type;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.AccountGuestVlanMapVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailVO;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.NetworkDomainDao;
+import com.cloud.network.dao.NetworkDomainVO;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.OvsProviderDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.OvsProviderVO;
+import com.cloud.network.element.VirtualRouterElement;
+import com.cloud.network.element.VpcVirtualRouterElement;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.security.SecurityGroupService;
+import com.cloud.network.vpc.NetworkACL;
+import com.cloud.network.vpc.PrivateIpVO;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcOfferingDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.org.Grouping;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectManager;
+import com.cloud.server.ResourceTag;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Journal;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * NetworkServiceImpl implements NetworkService.
+ */
+public class NetworkServiceImpl extends ManagerBase implements NetworkService {
+    private static final Logger s_logger = Logger.getLogger(NetworkServiceImpl.class);
+
+    private static final long MIN_VLAN_ID = 0L;
+    private static final long MAX_VLAN_ID = 4095L; // 2^12 - 1
+    private static final long MIN_GRE_KEY = 0L;
+    private static final long MAX_GRE_KEY = 4294967295L; // 2^32 -1
+    private static final long MIN_VXLAN_VNI = 0L;
+    private static final long MAX_VXLAN_VNI = 16777214L; // 2^24 -2
+    // MAX_VXLAN_VNI should be 16777215L (2^24-1), but Linux vxlan interface doesn't accept VNI:2^24-1 now.
+    // It seems a bug.
+
+    @Inject
+    DataCenterDao _dcDao = null;
+    @Inject
+    VlanDao _vlanDao = null;
+    @Inject
+    IPAddressDao _ipAddressDao = null;
+    @Inject
+    AccountDao _accountDao = null;
+    @Inject
+    DomainDao _domainDao = null;
+    @Inject
+    UserDao _userDao = null;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    UserVmDao _userVmDao = null;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao = null;
+    @Inject
+    NetworkDao _networksDao = null;
+    @Inject
+    NicDao _nicDao = null;
+    @Inject
+    RulesManager _rulesMgr;
+    List<NetworkGuru> _networkGurus;
+    @Inject
+    NetworkDomainDao _networkDomainDao;
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    DomainManager _domainMgr;
+    @Inject
+    ProjectManager _projectMgr;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _pNSPDao;
+    @Inject
+    PhysicalNetworkTrafficTypeDao _pNTrafficTypeDao;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    StorageNetworkManager _stnwMgr;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    PrivateIpDao _privateIpDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    PortForwardingRulesDao _portForwardingDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    InternalLoadBalancerElementService _internalLbElementSvc;
+    @Inject
+    DataCenterVnetDao _datacneterVnet;
+    @Inject
+    AccountGuestVlanMapDao _accountGuestVlanMapDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    NetworkACLDao _networkACLDao;
+    @Inject
+    OvsProviderDao _ovsProviderDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    Ipv6AddressManager ipv6AddrMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    public SecurityGroupService _securityGroupService;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    NetworkDetailsDao _networkDetailsDao;
+    @Inject
+    LoadBalancerDao _loadBalancerDao;
+    @Inject
+    NetworkMigrationManager _networkMigrationManager;
+    @Inject
+    VpcOfferingDao _vpcOfferingDao;
+    @Inject
+    AccountService _accountService;
+
+    int _cidrLimit;
+    boolean _allowSubdomainNetworkAccess;
+
+    private Map<String, String> _configs;
+
+    /* Get a list of IPs, classify them by service */
+    protected Map<PublicIp, Set<Service>> getIpToServices(List<PublicIp> publicIps, boolean rulesRevoked, boolean includingFirewall) {
+        Map<PublicIp, Set<Service>> ipToServices = new HashMap<PublicIp, Set<Service>>();
+
+        if (publicIps != null && !publicIps.isEmpty()) {
+            Set<Long> networkSNAT = new HashSet<Long>();
+            for (PublicIp ip : publicIps) {
+                Set<Service> services = ipToServices.get(ip);
+                if (services == null) {
+                    services = new HashSet<Service>();
+                }
+                if (ip.isSourceNat()) {
+                    if (!networkSNAT.contains(ip.getAssociatedWithNetworkId())) {
+                        services.add(Service.SourceNat);
+                        networkSNAT.add(ip.getAssociatedWithNetworkId());
+                    } else {
+                        CloudRuntimeException ex = new CloudRuntimeException("Multiple generic source NAT IPs provided for network");
+                        // see the IPAddressVO.java class.
+                        IPAddressVO ipAddr = ApiDBUtils.findIpAddressById(ip.getAssociatedWithNetworkId());
+                        String ipAddrUuid = ip.getAssociatedWithNetworkId().toString();
+                        if (ipAddr != null) {
+                            ipAddrUuid = ipAddr.getUuid();
+                        }
+                        ex.addProxyObject(ipAddrUuid, "networkId");
+                        throw ex;
+                    }
+                }
+                ipToServices.put(ip, services);
+
+                // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service
+                // provider
+                if (ip.getState() == State.Allocating) {
+                    continue;
+                }
+
+                // check if any active rules are applied on the public IP
+                Set<Purpose> purposes = getPublicIpPurposeInRules(ip, false, includingFirewall);
+                // Firewall rules didn't cover static NAT
+                if (ip.isOneToOneNat() && ip.getAssociatedWithVmId() != null) {
+                    if (purposes == null) {
+                        purposes = new HashSet<Purpose>();
+                    }
+                    purposes.add(Purpose.StaticNat);
+                }
+                if (purposes == null || purposes.isEmpty()) {
+                    // since no active rules are there check if any rules are applied on the public IP but are in
+// revoking state
+
+                    purposes = getPublicIpPurposeInRules(ip, true, includingFirewall);
+                    if (ip.isOneToOneNat()) {
+                        if (purposes == null) {
+                            purposes = new HashSet<Purpose>();
+                        }
+                        purposes.add(Purpose.StaticNat);
+                    }
+                    if (purposes == null || purposes.isEmpty()) {
+                        // IP is not being used for any purpose so skip IPAssoc to network service provider
+                        continue;
+                    } else {
+                        if (rulesRevoked) {
+                            // no active rules/revoked rules are associated with this public IP, so remove the
+// association with the provider
+                            ip.setState(State.Releasing);
+                        } else {
+                            if (ip.getState() == State.Releasing) {
+                                // rules are not revoked yet, so don't let the network service provider revoke the IP
+// association
+                                // mark IP is allocated so that IP association will not be removed from the provider
+                                ip.setState(State.Allocated);
+                            }
+                        }
+                    }
+                }
+                if (purposes.contains(Purpose.StaticNat)) {
+                    services.add(Service.StaticNat);
+                }
+                if (purposes.contains(Purpose.LoadBalancing)) {
+                    services.add(Service.Lb);
+                }
+                if (purposes.contains(Purpose.PortForwarding)) {
+                    services.add(Service.PortForwarding);
+                }
+                if (purposes.contains(Purpose.Vpn)) {
+                    services.add(Service.Vpn);
+                }
+                if (purposes.contains(Purpose.Firewall)) {
+                    services.add(Service.Firewall);
+                }
+                if (services.isEmpty()) {
+                    continue;
+                }
+                ipToServices.put(ip, services);
+            }
+        }
+        return ipToServices;
+    }
+
+    protected boolean canIpUsedForNonConserveService(PublicIp ip, Service service) {
+        // If it's non-conserve mode, then the new ip should not be used by any other services
+        List<PublicIp> ipList = new ArrayList<PublicIp>();
+        ipList.add(ip);
+        Map<PublicIp, Set<Service>> ipToServices = getIpToServices(ipList, false, false);
+        Set<Service> services = ipToServices.get(ip);
+        // Not used currently, safe
+        if (services == null || services.isEmpty()) {
+            return true;
+        }
+        // Since it's non-conserve mode, only one service should used for IP
+        if (services.size() != 1) {
+            throw new InvalidParameterException("There are multiple services used ip " + ip.getAddress() + ".");
+        }
+        if (service != null && !((Service)services.toArray()[0] == service || service.equals(Service.Firewall))) {
+            throw new InvalidParameterException("The IP " + ip.getAddress() + " is already used as " + ((Service)services.toArray()[0]).getName() + " rather than " + service.getName());
+        }
+        return true;
+    }
+
+    protected boolean canIpsUsedForNonConserve(List<PublicIp> publicIps) {
+        boolean result = true;
+        for (PublicIp ip : publicIps) {
+            result = canIpUsedForNonConserveService(ip, null);
+            if (!result) {
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean canIpsUseOffering(List<PublicIp> publicIps, long offeringId) {
+        Map<PublicIp, Set<Service>> ipToServices = getIpToServices(publicIps, false, true);
+        Map<Service, Set<Provider>> serviceToProviders = _networkModel.getNetworkOfferingServiceProvidersMap(offeringId);
+        NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId);
+        //For inline mode checking, using firewall provider for LB instead, because public ip would apply on firewall provider
+        if (offering.isInline()) {
+            Provider firewallProvider = null;
+            if (serviceToProviders.containsKey(Service.Firewall)) {
+                firewallProvider = (Provider)serviceToProviders.get(Service.Firewall).toArray()[0];
+            }
+            Set<Provider> p = new HashSet<Provider>();
+            p.add(firewallProvider);
+            serviceToProviders.remove(Service.Lb);
+            serviceToProviders.put(Service.Lb, p);
+        }
+        for (PublicIp ip : ipToServices.keySet()) {
+            Set<Service> services = ipToServices.get(ip);
+            Provider provider = null;
+            for (Service service : services) {
+                Set<Provider> curProviders = serviceToProviders.get(service);
+                if (curProviders == null || curProviders.isEmpty()) {
+                    continue;
+                }
+                Provider curProvider = (Provider)curProviders.toArray()[0];
+                if (provider == null) {
+                    provider = curProvider;
+                    continue;
+                }
+                // We don't support multiple providers for one service now
+                if (!provider.equals(curProvider)) {
+                    throw new InvalidParameterException("There would be multiple providers for IP " + ip.getAddress() + " with the new network offering!");
+                }
+            }
+        }
+        return true;
+    }
+
+    private Set<Purpose> getPublicIpPurposeInRules(PublicIp ip, boolean includeRevoked, boolean includingFirewall) {
+        Set<Purpose> result = new HashSet<Purpose>();
+        List<FirewallRuleVO> rules = null;
+        if (includeRevoked) {
+            rules = _firewallDao.listByIp(ip.getId());
+        } else {
+            rules = _firewallDao.listByIpAndNotRevoked(ip.getId());
+        }
+
+        if (rules == null || rules.isEmpty()) {
+            return null;
+        }
+
+        for (FirewallRuleVO rule : rules) {
+            if (rule.getPurpose() != Purpose.Firewall || includingFirewall) {
+                result.add(rule.getPurpose());
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) {
+
+        return _networksDao.listByZoneAndGuestType(owner.getId(), zoneId, Network.GuestType.Isolated, false);
+    }
+
+    @Override
+    public List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
+
+        return _networksDao.listSourceNATEnabledNetworks(owner.getId(), zoneId, Network.GuestType.Isolated);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true)
+    public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp)
+            throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        long callerUserId = CallContext.current().getCallingUserId();
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+
+        if (networkId != null) {
+            Network network = _networksDao.findById(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Invalid network id is given");
+            }
+
+            if (network.getGuestType() == Network.GuestType.Shared) {
+                if (zone == null) {
+                    throw new InvalidParameterValueException("Invalid zone Id is given");
+                }
+                // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
+                if (zone.getNetworkType() == NetworkType.Advanced) {
+                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+                        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
+                        }
+                        return _ipAddrMgr.allocateIp(ipOwner, false, caller, callerUserId, zone, displayIp);
+                    } else {
+                        throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone"
+                                + " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
+                    }
+                }
+            }
+        } else {
+            _accountMgr.checkAccess(caller, null, false, ipOwner);
+        }
+
+        return _ipAddrMgr.allocateIp(ipOwner, false, caller, callerUserId, zone, displayIp);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_ASSIGN, eventDescription = "allocating portable public Ip", create = true)
+    public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId)
+            throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException {
+        Account caller = CallContext.current().getCallingAccount();
+        long callerUserId = CallContext.current().getCallingUserId();
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+
+        if ((networkId == null && vpcId == null) || (networkId != null && vpcId != null)) {
+            throw new InvalidParameterValueException("One of Network id or VPC is should be passed");
+        }
+
+        if (networkId != null) {
+            Network network = _networksDao.findById(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Invalid network id is given");
+            }
+
+            if (network.getGuestType() == Network.GuestType.Shared) {
+                if (zone == null) {
+                    throw new InvalidParameterValueException("Invalid zone Id is given");
+                }
+                // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
+                if (zone.getNetworkType() == NetworkType.Advanced) {
+                    if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) {
+                        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
+                        }
+                        return _ipAddrMgr.allocatePortableIp(ipOwner, caller, zoneId, networkId, null);
+                    } else {
+                        throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone"
+                                + " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled");
+                    }
+                }
+            }
+        }
+
+        if (vpcId != null) {
+            Vpc vpc = _vpcDao.findById(vpcId);
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Invalid vpc id is given");
+            }
+        }
+
+        _accountMgr.checkAccess(caller, null, false, ipOwner);
+
+        return _ipAddrMgr.allocatePortableIp(ipOwner, caller, zoneId, null, null);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RELEASE, eventDescription = "disassociating portable Ip", async = true)
+    public boolean releasePortableIpAddress(long ipAddressId) {
+        try {
+            return releaseIpAddressInternal(ipAddressId);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @Override
+    @DB
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _configs = _configDao.getConfiguration("Network", params);
+
+        _cidrLimit = NumbersUtil.parseInt(_configs.get(Config.NetworkGuestCidrLimit.key()), 22);
+
+        _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key()));
+
+        s_logger.info("Network Service is configured.");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    protected NetworkServiceImpl() {
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_CONFIGURE, eventDescription = "Configuring secondary ip " + "rules", async = true)
+    public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) {
+        boolean success = false;
+        String secondaryIp = secIp.getIp4Address();
+        if (secIp.getIp4Address() == null) {
+            secondaryIp = secIp.getIp6Address();
+        }
+
+        if (isZoneSgEnabled) {
+            success = _securityGroupService.securityGroupRulesForVmSecIp(secIp.getNicId(), secondaryIp, true);
+            s_logger.info("Associated ip address to NIC : " + secIp.getIp4Address());
+        } else {
+            success = true;
+        }
+        return success;
+    }
+
+    /**
+     * It allocates a secondary IP alias on the NIC. It can be either an Ipv4 or an Ipv6 or even both, according to the the given IpAddresses object.
+     */
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_ASSIGN, eventDescription = "assigning secondary ip to nic", create = true)
+    public NicSecondaryIp allocateSecondaryGuestIP(final long nicId, IpAddresses requestedIpPair) throws InsufficientAddressCapacityException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        String ipv4Address = requestedIpPair.getIp4Address();
+        String ipv6Address = requestedIpPair.getIp6Address();
+
+        //check whether the nic belongs to user vm.
+        NicVO nicVO = _nicDao.findById(nicId);
+        if (nicVO == null) {
+            throw new InvalidParameterValueException("There is no NIC with the ID:  " + nicId);
+        }
+
+        if (nicVO.getVmType() != VirtualMachine.Type.User) {
+            throw new InvalidParameterValueException(String.format("The NIC [%s] does not belong to a user VM", nicVO.getUuid()));
+        }
+
+        VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId());
+        if (vm == null) {
+            throw new InvalidParameterValueException(String.format("There is no VM with the NIC [%s]", nicVO.getUuid()));
+        }
+
+        final long networkId = nicVO.getNetworkId();
+        final Account ipOwner = _accountMgr.getAccount(vm.getAccountId());
+
+        // verify permissions
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        Network network = _networksDao.findById(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        int maxAllowedIpsPerNic = NumbersUtil.parseInt(_configDao.getValue(Config.MaxNumberOfSecondaryIPsPerNIC.key()), 10);
+        Long nicWiseIpCount = _nicSecondaryIpDao.countByNicId(nicId);
+        if (nicWiseIpCount.intValue() >= maxAllowedIpsPerNic) {
+            s_logger.error("Maximum Number of Ips \"vm.network.nic.max.secondary.ipaddresses = \"" + maxAllowedIpsPerNic + " per Nic has been crossed for the nic " + nicId + ".");
+            throw new InsufficientAddressCapacityException("Maximum Number of Ips per Nic has been crossed.", Nic.class, nicId);
+        }
+
+        s_logger.debug("Calling the ip allocation ...");
+        String ipaddr = null;
+        String ip6addr = null;
+        //Isolated network can exist in Basic zone only, so no need to verify the zone type
+        if (network.getGuestType() == Network.GuestType.Isolated) {
+            if ((ipv4Address != null || NetUtils.isIpv4(network.getGateway()) && org.apache.commons.lang3.StringUtils.isBlank(ipv6Address))) {
+                ipaddr = _ipAddrMgr.allocateGuestIP(network, ipv4Address);
+            }
+            if (ipv6Address != null) {
+                ip6addr = ipv6AddrMgr.allocateGuestIpv6(network, ipv6Address);
+            }
+        } else if (network.getGuestType() == Network.GuestType.Shared) {
+            //for basic zone, need to provide the podId to ensure proper ip alloation
+            Long podId = null;
+            DataCenter dc = _dcDao.findById(network.getDataCenterId());
+
+            if (dc.getNetworkType() == NetworkType.Basic) {
+                VMInstanceVO vmi = (VMInstanceVO)vm;
+                podId = vmi.getPodIdToDeployIn();
+                if (podId == null) {
+                    throw new InvalidParameterValueException("vm pod id is null in Basic zone; can't decide the range for ip allocation");
+                }
+            }
+
+            try {
+                if (ipv4Address != null) {
+                    ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, ipv4Address);
+                }
+                if (ipv6Address != null) {
+                    ip6addr = ipv6AddrMgr.allocatePublicIp6ForGuestNic(network, podId, ipOwner, ipv6Address);
+                }
+                if (ipaddr == null && ipv6Address == null) {
+                    throw new InvalidParameterValueException("Allocating ip to guest nic " + nicId + " failed");
+                }
+            } catch (InsufficientAddressCapacityException e) {
+                s_logger.error("Allocating ip to guest nic " + nicId + " failed");
+                return null;
+            }
+        } else {
+            s_logger.error("AddIpToVMNic is not supported in this network...");
+            return null;
+        }
+
+        if (ipaddr != null || ip6addr != null) {
+            // we got the ip addr so up the nics table and secodary ip
+            final String ip4AddrFinal = ipaddr;
+            final String ip6AddrFinal = ip6addr;
+            long id = Transaction.execute(new TransactionCallback<Long>() {
+                @Override
+                public Long doInTransaction(TransactionStatus status) {
+                    boolean nicSecondaryIpSet = nicVO.getSecondaryIp();
+                    if (!nicSecondaryIpSet) {
+                        nicVO.setSecondaryIp(true);
+                        // commit when previously set ??
+                        s_logger.debug("Setting nics table ...");
+                        _nicDao.update(nicId, nicVO);
+                    }
+
+                    s_logger.debug("Setting nic_secondary_ip table ...");
+                    Long vmId = nicVO.getInstanceId();
+                    NicSecondaryIpVO secondaryIpVO = new NicSecondaryIpVO(nicId, ip4AddrFinal, ip6AddrFinal, vmId, ipOwner.getId(), ipOwner.getDomainId(), networkId);
+                    _nicSecondaryIpDao.persist(secondaryIpVO);
+                    return secondaryIpVO.getId();
+                }
+            });
+
+            return getNicSecondaryIp(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_SECONDARY_IP_UNASSIGN, eventDescription = "Removing secondary IP from NIC", async = true)
+    public boolean releaseSecondaryIpFromNic(long ipAddressId) {
+        Account caller = CallContext.current().getCallingAccount();
+        boolean success = false;
+
+        // Verify input parameters
+        NicSecondaryIpVO secIpVO = _nicSecondaryIpDao.findById(ipAddressId);
+        if (secIpVO == null) {
+            throw new InvalidParameterValueException("Unable to find secondary ip address by id");
+        }
+
+        VirtualMachine vm = _userVmDao.findById(secIpVO.getVmId());
+        if (vm == null) {
+            throw new InvalidParameterValueException("There is no vm with the given secondary ip");
+        }
+        // verify permissions
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        Network network = _networksDao.findById(secIpVO.getNetworkId());
+
+        if (network == null) {
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        // Validate network offering
+        NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId());
+
+        Long nicId = secIpVO.getNicId();
+        s_logger.debug("ip id = " + ipAddressId + " nic id = " + nicId);
+        //check is this the last secondary ip for NIC
+        List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
+        boolean lastIp = false;
+        if (ipList.size() == 1) {
+            // this is the last secondary ip to nic
+            lastIp = true;
+        }
+
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        if (dc == null) {
+            throw new InvalidParameterValueException("Invalid zone Id is given");
+        }
+
+        s_logger.debug("Calling secondary ip " + secIpVO.getIp4Address() + " release ");
+        if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
+            //check PF or static NAT is configured on this ip address
+            String secondaryIp = secIpVO.getIp4Address();
+            List<FirewallRuleVO> fwRulesList = _firewallDao.listByNetworkAndPurpose(network.getId(), Purpose.PortForwarding);
+
+            if (fwRulesList.size() != 0) {
+                for (FirewallRuleVO rule : fwRulesList) {
+                    if (_portForwardingDao.findByIdAndIp(rule.getId(), secondaryIp) != null) {
+                        s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
+                        throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
+                    }
+                }
+            }
+            //check if the secondary ip associated with any static nat rule
+            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());
+            }
+
+            if (_loadBalancerDao.isLoadBalancerRulesMappedToVmGuestIp(vm.getId(), secondaryIp, network.getId())) {
+                s_logger.debug("VM nic IP " + secondaryIp + " is mapped to load balancing rule");
+                throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is mapped to load balancing rule");
+            }
+
+        } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) {
+            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address());
+            if (ip != null) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                        _ipAddressDao.unassignIpAddress(ip.getId());
+                    }
+                });
+            }
+        } else {
+            throw new InvalidParameterValueException("Not supported for this network now");
+        }
+
+        success = removeNicSecondaryIP(secIpVO, lastIp);
+        return success;
+    }
+
+    boolean removeNicSecondaryIP(final NicSecondaryIpVO ipVO, final boolean lastIp) {
+        final long nicId = ipVO.getNicId();
+        final NicVO nic = _nicDao.findById(nicId);
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                if (lastIp) {
+                    nic.setSecondaryIp(false);
+                    s_logger.debug("Setting nics secondary ip to false ...");
+                    _nicDao.update(nicId, nic);
+                }
+
+                s_logger.debug("Revoving nic secondary ip entry ...");
+                _nicSecondaryIpDao.remove(ipVO.getId());
+            }
+        });
+
+        return true;
+    }
+
+    NicSecondaryIp getNicSecondaryIp(long id) {
+        NicSecondaryIp nicSecIp = _nicSecondaryIpDao.findById(id);
+        if (nicSecIp == null) {
+            return null;
+        }
+        return nicSecIp;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true)
+    public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+        return releaseIpAddressInternal(ipAddressId);
+    }
+
+    @DB
+    private boolean releaseIpAddressInternal(long ipAddressId) throws InsufficientAddressCapacityException {
+        Long userId = CallContext.current().getCallingUserId();
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify input parameters
+        IPAddressVO ipVO = _ipAddressDao.findById(ipAddressId);
+        if (ipVO == null) {
+            throw new InvalidParameterValueException("Unable to find ip address by id");
+        }
+
+        if (ipVO.getAllocatedTime() == null) {
+            s_logger.debug("Ip Address id= " + ipAddressId + " is not allocated, so do nothing.");
+            return true;
+        }
+
+        // verify permissions
+        if (ipVO.getAllocatedToAccountId() != null) {
+            _accountMgr.checkAccess(caller, null, true, ipVO);
+        }
+
+        if (ipVO.isSourceNat()) {
+            throw new IllegalArgumentException("ip address is used for source nat purposes and can not be disassociated.");
+        }
+
+        VlanVO vlan = _vlanDao.findById(ipVO.getVlanId());
+        if (!vlan.getVlanType().equals(VlanType.VirtualNetwork)) {
+            throw new IllegalArgumentException("only ip addresses that belong to a virtual network may be disassociated.");
+        }
+
+        // don't allow releasing system ip address
+        if (ipVO.getSystem()) {
+            throwInvalidIdException("Can't release system IP address with specified id", ipVO.getUuid(), "systemIpAddrId");
+        }
+
+        boolean success = _ipAddrMgr.disassociatePublicIpAddress(ipAddressId, userId, caller);
+
+        if (success) {
+            Long networkId = ipVO.getAssociatedWithNetworkId();
+            if (networkId != null) {
+                Network guestNetwork = getNetwork(networkId);
+                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+                Long vmId = ipVO.getAssociatedWithVmId();
+                if (offering.isElasticIp() && vmId != null) {
+                    _rulesMgr.getSystemIpAndEnableStaticNatForVm(_userVmDao.findById(vmId), true);
+                    return true;
+                }
+            }
+        } else {
+            s_logger.warn("Failed to release public ip address id=" + ipAddressId);
+        }
+        return success;
+    }
+
+    @Override
+    @DB
+    public Network getNetwork(long id) {
+        return _networksDao.findById(id);
+    }
+
+    private void checkSharedNetworkCidrOverlap(Long zoneId, long physicalNetworkId, String cidr) {
+        if (zoneId == null || cidr == null) {
+            return;
+        }
+
+        DataCenter zone = _dcDao.findById(zoneId);
+        List<NetworkVO> networks = _networksDao.listByZone(zoneId);
+        Map<Long, String> networkToCidr = new HashMap<Long, String>();
+
+        // check for CIDR overlap with all possible CIDR for isolated guest networks
+        // in the zone when using external networking
+        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork.getVnet() != null) {
+            List<Pair<Integer, Integer>> vlanList = pNetwork.getVnet();
+            for (Pair<Integer, Integer> vlanRange : vlanList) {
+                Integer lowestVlanTag = vlanRange.first();
+                Integer highestVlanTag = vlanRange.second();
+                for (int vlan = lowestVlanTag; vlan <= highestVlanTag; ++vlan) {
+                    int offset = vlan - lowestVlanTag;
+                    String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
+                    int cidrSize = 8 + Integer.parseInt(globalVlanBits);
+                    String guestNetworkCidr = zone.getGuestNetworkCidr();
+                    String[] cidrTuple = guestNetworkCidr.split("\\/");
+                    long newCidrAddress = (NetUtils.ip2Long(cidrTuple[0]) & 0xff000000) | (offset << (32 - cidrSize));
+                    if (NetUtils.isNetworksOverlap(NetUtils.long2Ip(newCidrAddress), cidr)) {
+                        throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR that is reserved for zone vlan " + vlan);
+                    }
+                }
+            }
+        }
+
+        // check for CIDR overlap with all CIDR's of the shared networks in the zone
+        for (NetworkVO network : networks) {
+            if (network.getGuestType() == GuestType.Isolated) {
+                continue;
+            }
+            if (network.getCidr() != null) {
+                networkToCidr.put(network.getId(), network.getCidr());
+            }
+        }
+        if (networkToCidr != null && !networkToCidr.isEmpty()) {
+            for (long networkId : networkToCidr.keySet()) {
+                String ntwkCidr = networkToCidr.get(networkId);
+                if (NetUtils.isNetworksOverlap(ntwkCidr, cidr)) {
+                    throw new InvalidParameterValueException("Specified CIDR for shared network conflict with CIDR of a shared network in the zone.");
+                }
+            }
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
+    public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
+        Long networkOfferingId = cmd.getNetworkOfferingId();
+        String gateway = cmd.getGateway();
+        String startIP = cmd.getStartIp();
+        String endIP = cmd.getEndIp();
+        String netmask = cmd.getNetmask();
+        String networkDomain = cmd.getNetworkDomain();
+        String vlanId = null;
+        boolean bypassVlanOverlapCheck = false;
+        if (cmd instanceof CreateNetworkCmdByAdmin) {
+            vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
+        }
+        if (cmd instanceof CreateNetworkCmdByAdmin) {
+            bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
+        }
+
+        String name = cmd.getNetworkName();
+        String displayText = cmd.getDisplayText();
+        Account caller = CallContext.current().getCallingAccount();
+        Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        Long zoneId = cmd.getZoneId();
+        String aclTypeStr = cmd.getAclType();
+        Long domainId = cmd.getDomainId();
+        boolean isDomainSpecific = false;
+        Boolean subdomainAccess = cmd.getSubdomainAccess();
+        Long vpcId = cmd.getVpcId();
+        String startIPv6 = cmd.getStartIpv6();
+        String endIPv6 = cmd.getEndIpv6();
+        String ip6Gateway = cmd.getIp6Gateway();
+        String ip6Cidr = cmd.getIp6Cidr();
+        Boolean displayNetwork = cmd.getDisplayNetwork();
+        Long aclId = cmd.getAclId();
+        String isolatedPvlan = cmd.getIsolatedPvlan();
+        String externalId = cmd.getExternalId();
+
+        // Validate network offering
+        NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
+        if (ntwkOff == null || ntwkOff.isSystemOnly()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering by specified id");
+            if (ntwkOff != null) {
+                ex.addProxyObject(ntwkOff.getUuid(), "networkOfferingId");
+            }
+            throw ex;
+        }
+        // validate physical network and zone
+        // Check if physical network exists
+        PhysicalNetwork pNtwk = null;
+        if (physicalNetworkId != null) {
+            pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
+            if (pNtwk == null) {
+                throw new InvalidParameterValueException("Unable to find a physical network having the specified physical network id");
+            }
+        }
+
+        if (zoneId == null) {
+            zoneId = pNtwk.getDataCenterId();
+        }
+
+        if (displayNetwork == null) {
+            displayNetwork = true;
+        }
+
+        DataCenter zone = _dcDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Specified zone id was not found");
+        }
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            // See DataCenterVO.java
+            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "zoneId");
+            throw ex;
+        }
+
+        // Only domain and account ACL types are supported in Acton.
+        ACLType aclType = null;
+        if (aclTypeStr != null) {
+            if (aclTypeStr.equalsIgnoreCase(ACLType.Account.toString())) {
+                aclType = ACLType.Account;
+            } else if (aclTypeStr.equalsIgnoreCase(ACLType.Domain.toString())) {
+                aclType = ACLType.Domain;
+            } else {
+                throw new InvalidParameterValueException("Incorrect aclType specified. Check the API documentation for supported types");
+            }
+            // In 3.0 all Shared networks should have aclType == Domain, all Isolated networks aclType==Account
+            if (ntwkOff.getGuestType() == GuestType.Isolated) {
+                if (aclType != ACLType.Account) {
+                    throw new InvalidParameterValueException("AclType should be " + ACLType.Account + " for network of type " + Network.GuestType.Isolated);
+                }
+            } else if (ntwkOff.getGuestType() == GuestType.Shared) {
+                if (!(aclType == ACLType.Domain || aclType == ACLType.Account)) {
+                    throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + ACLType.Account + " for network of type " + Network.GuestType.Shared);
+                }
+            }
+        } else {
+            if (ntwkOff.getGuestType() == GuestType.Isolated || ntwkOff.getGuestType() == GuestType.L2) {
+                aclType = ACLType.Account;
+            } else if (ntwkOff.getGuestType() == GuestType.Shared) {
+                aclType = ACLType.Domain;
+            }
+        }
+
+        // Only Admin can create Shared networks
+        if ((ntwkOff.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
+            throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
+        }
+
+        // Check if the network is domain specific
+        if (aclType == ACLType.Domain) {
+            // only Admin can create domain with aclType=Domain
+            if (!_accountMgr.isAdmin(caller.getId())) {
+                throw new PermissionDeniedException("Only admin can create networks with aclType=Domain");
+            }
+
+            // only shared networks can be Domain specific
+            if (ntwkOff.getGuestType() != GuestType.Shared) {
+                throw new InvalidParameterValueException("Only " + GuestType.Shared + " networks can have aclType=" + ACLType.Domain);
+            }
+
+            if (domainId != null) {
+                if (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Shared) {
+                    throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + TrafficType.Guest + " and guest type " + Network.GuestType.Shared);
+                }
+
+                DomainVO domain = _domainDao.findById(domainId);
+                if (domain == null) {
+                    throw new InvalidParameterValueException("Unable to find domain by specified id");
+                }
+                _accountMgr.checkAccess(caller, domain);
+            }
+            isDomainSpecific = true;
+
+        } else if (subdomainAccess != null) {
+            throw new InvalidParameterValueException("Parameter subDomainAccess can be specified only with aclType=Domain");
+        }
+        Account owner = null;
+        if ((cmd.getAccountName() != null && domainId != null) || cmd.getProjectId() != null) {
+            owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), domainId, cmd.getProjectId());
+        } else {
+            owner = caller;
+        }
+
+        boolean ipv4 = true, ipv6 = false;
+        if (startIP != null) {
+            ipv4 = true;
+        }
+        if (startIPv6 != null) {
+            ipv6 = true;
+        }
+
+        if (gateway != null) {
+            try {
+                // getByName on a literal representation will only check validity of the address
+                // http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getByName(java.lang.String)
+                InetAddress gatewayAddress = InetAddress.getByName(gateway);
+                if (gatewayAddress instanceof Inet6Address) {
+                    ipv6 = true;
+                } else {
+                    ipv4 = true;
+                }
+            } catch (UnknownHostException e) {
+                s_logger.error("Unable to convert gateway IP to a InetAddress", e);
+                throw new InvalidParameterValueException("Gateway parameter is invalid");
+            }
+        }
+
+        String cidr = null;
+        if (ipv4) {
+            // if end ip is not specified, default it to startIp
+            if (startIP != null) {
+                if (!NetUtils.isValidIp4(startIP)) {
+                    throw new InvalidParameterValueException("Invalid format for the startIp parameter");
+                }
+                if (endIP == null) {
+                    endIP = startIP;
+                } else if (!NetUtils.isValidIp4(endIP)) {
+                    throw new InvalidParameterValueException("Invalid format for the endIp parameter");
+                }
+            }
+
+            if (startIP != null && endIP != null) {
+                if (!(gateway != null && netmask != null)) {
+                    throw new InvalidParameterValueException("gateway and netmask should be defined when startIP/endIP are passed in");
+                }
+            }
+
+            if (gateway != null && netmask != null) {
+                if (NetUtils.isNetworkorBroadcastIP(gateway, netmask)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("The gateway IP provided is " + gateway + " and netmask is " + netmask + ". The IP is either broadcast or network IP.");
+                    }
+                    throw new InvalidParameterValueException("Invalid gateway IP provided. Either the IP is broadcast or network IP.");
+                }
+
+                if (!NetUtils.isValidIp4(gateway)) {
+                    throw new InvalidParameterValueException("Invalid gateway");
+                }
+                if (!NetUtils.isValidIp4Netmask(netmask)) {
+                    throw new InvalidParameterValueException("Invalid netmask");
+                }
+
+                cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+            }
+
+        }
+
+        if (ipv6) {
+            if (endIPv6 == null) {
+                endIPv6 = startIPv6;
+            }
+            _networkModel.checkIp6Parameters(startIPv6, endIPv6, ip6Gateway, ip6Cidr);
+
+            if (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared) {
+                throw new InvalidParameterValueException("Can only support create IPv6 network with advance shared network!");
+            }
+        }
+
+        if (isolatedPvlan != null && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() != Network.GuestType.Shared)) {
+            throw new InvalidParameterValueException("Can only support create Private VLAN network with advance shared network!");
+        }
+
+        if (isolatedPvlan != null && ipv6) {
+            throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
+        }
+
+        // Regular user can create Guest Isolated Source Nat enabled network only
+        if (_accountMgr.isNormalUser(caller.getId()) && (ntwkOff.getTrafficType() != TrafficType.Guest
+                || ntwkOff.getGuestType() != Network.GuestType.Isolated && areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) {
+            throw new InvalidParameterValueException(
+                    String.format("Regular users can only create a network from network offerings having traffic type [%s] and network type [%s] with a service [%s] enabled.", TrafficType.Guest,
+                            Network.GuestType.Isolated, Service.SourceNat.getName()));
+        }
+
+        // Don't allow to specify vlan if the caller is not ROOT admin
+        if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.isSpecifyVlan() || vlanId != null || bypassVlanOverlapCheck)) {
+            throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
+        }
+
+        if (ipv4) {
+            // For non-root admins check cidr limit - if it's allowed by global config value
+            if (!_accountMgr.isRootAdmin(caller.getId()) && cidr != null) {
+
+                String[] cidrPair = cidr.split("\\/");
+                int cidrSize = Integer.parseInt(cidrPair[1]);
+
+                if (cidrSize < _cidrLimit) {
+                    throw new InvalidParameterValueException("Cidr size can't be less than " + _cidrLimit);
+                }
+            }
+        }
+
+        Collection<String> ntwkProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(ntwkOff, physicalNetworkId).values();
+        if (ipv6 && providersConfiguredForExternalNetworking(ntwkProviders)) {
+            throw new InvalidParameterValueException("Cannot support IPv6 on network offering with external devices!");
+        }
+
+        if (isolatedPvlan != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
+            throw new InvalidParameterValueException("Cannot support private vlan on network offering with external devices!");
+        }
+
+        if (cidr != null && providersConfiguredForExternalNetworking(ntwkProviders)) {
+            if (ntwkOff.getGuestType() == GuestType.Shared && (zone.getNetworkType() == NetworkType.Advanced) && isSharedNetworkOfferingWithServices(networkOfferingId)) {
+                // validate if CIDR specified overlaps with any of the CIDR's allocated for isolated networks and shared networks in the zone
+                checkSharedNetworkCidrOverlap(zoneId, pNtwk.getId(), cidr);
+            } else {
+                // if the guest network is for the VPC, if any External Provider are supported in VPC
+                // cidr will not be null as it is generated from the super cidr of vpc.
+                // if cidr is not null and network is not part of vpc then throw the exception
+                if (vpcId == null) {
+                    throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!");
+                }
+            }
+        }
+
+        // Vlan is created in 1 cases - works in Advance zone only:
+        // 1) GuestType is Shared
+        boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced && ((ntwkOff.getGuestType() == Network.GuestType.Shared)
+                || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))));
+
+        if (!createVlan) {
+            // Only support advance shared network in IPv6, which means createVlan is a must
+            if (ipv6) {
+                createVlan = true;
+            }
+        }
+
+        // Can add vlan range only to the network which allows it
+        if (createVlan && !ntwkOff.isSpecifyIpRanges()) {
+            throwInvalidIdException("Network offering with specified id doesn't support adding multiple ip ranges", ntwkOff.getUuid(), "networkOfferingId");
+        }
+
+        Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId,
+                domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
+                externalId);
+
+        // if the network offering has persistent set to true, implement the network
+        if (ntwkOff.isPersistent()) {
+            try {
+                if (network.getState() == Network.State.Setup) {
+                    s_logger.debug("Network id=" + network.getId() + " is already provisioned");
+                    return network;
+                }
+                DeployDestination dest = new DeployDestination(zone, null, null, null);
+                UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
+                Journal journal = new Journal.LogJournal("Implementing " + network, s_logger);
+                ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
+                s_logger.debug("Implementing network " + network + " as a part of network provision for persistent network");
+                Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(network.getId(), dest, context);
+                if (implementedNetwork == null || implementedNetwork.first() == null) {
+                    s_logger.warn("Failed to provision the network " + network);
+                }
+                network = implementedNetwork.second();
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
+                CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
+                e.addProxyObject(network.getUuid(), "networkId");
+                throw e;
+            }
+        }
+        return network;
+    }
+
+    private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain, final String vlanId,
+            final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
+            final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr,
+            final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, final Account ownerFinal,
+            final String cidr, final boolean createVlan, final String externalId) throws InsufficientCapacityException, ResourceAllocationException {
+        try {
+            Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
+                @Override
+                public Network doInTransaction(TransactionStatus status) throws InsufficientCapacityException, ResourceAllocationException {
+                    Account owner = ownerFinal;
+                    Boolean subdomainAccess = subdomainAccessFinal;
+
+                    Long sharedDomainId = null;
+                    if (isDomainSpecific) {
+                        if (domainId != null) {
+                            sharedDomainId = domainId;
+                        } else {
+                            sharedDomainId = _domainMgr.getDomain(Domain.ROOT_DOMAIN).getId();
+                            subdomainAccess = true;
+                        }
+                    }
+
+                    // default owner to system if network has aclType=Domain
+                    if (aclType == ACLType.Domain) {
+                        owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
+                    }
+
+                    // Create guest network
+                    Network network = null;
+                    if (vpcId != null) {
+                        if (!_configMgr.isOfferingForVpc(ntwkOff)) {
+                            throw new InvalidParameterValueException("Network offering can't be used for VPC networks");
+                        }
+
+                        if (aclId != null) {
+                            NetworkACL acl = _networkACLDao.findById(aclId);
+                            if (acl == null) {
+                                throw new InvalidParameterValueException("Unable to find specified NetworkACL");
+                            }
+
+                            if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
+                                // ACL is not default DENY/ALLOW
+                                // ACL should be associated with a VPC
+                                if (!vpcId.equals(acl.getVpcId())) {
+                                    throw new InvalidParameterValueException("ACL: " + aclId + " do not belong to the VPC");
+                                }
+                            }
+                        }
+                        network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType,
+                                subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId);
+                    } else {
+                        if (_configMgr.isOfferingForVpc(ntwkOff)) {
+                            throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
+                        }
+                        if (ntwkOff.isInternalLb()) {
+                            throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
+                        }
+
+                        network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk,
+                                zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, externalId);
+                    }
+
+                    if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
+                        // Create vlan ip range
+                        _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, false, null, startIP, endIP, gateway, netmask, vlanId,
+                                bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
+                    }
+                    return network;
+                }
+            });
+            if (domainId != null && aclType == ACLType.Domain) {
+                // send event for storing the domain wide resource access
+                Map<String, Object> params = new HashMap<String, Object>();
+                params.put(ApiConstants.ENTITY_TYPE, Network.class);
+                params.put(ApiConstants.ENTITY_ID, network.getId());
+                params.put(ApiConstants.DOMAIN_ID, domainId);
+                params.put(ApiConstants.SUBDOMAIN_ACCESS, subdomainAccessFinal == null ? Boolean.TRUE : subdomainAccessFinal);
+                _messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL, params);
+            }
+            return network;
+        } catch (Exception e) {
+            ExceptionUtil.rethrowRuntime(e);
+            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
+            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd) {
+        Long id = cmd.getId();
+        String keyword = cmd.getKeyword();
+        Long zoneId = cmd.getZoneId();
+        Account caller = CallContext.current().getCallingAccount();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        String guestIpType = cmd.getGuestIpType();
+        String trafficType = cmd.getTrafficType();
+        Boolean isSystem = cmd.getIsSystem();
+        String aclType = cmd.getAclType();
+        Long projectId = cmd.getProjectId();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+        String path = null;
+        Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        List<String> supportedServicesStr = cmd.getSupportedServices();
+        Boolean restartRequired = cmd.isRestartRequired();
+        boolean listAll = cmd.listAll();
+        boolean isRecursive = cmd.isRecursive();
+        Boolean specifyIpRanges = cmd.isSpecifyIpRanges();
+        Long vpcId = cmd.getVpcId();
+        Boolean canUseForDeploy = cmd.canUseForDeploy();
+        Map<String, String> tags = cmd.getTags();
+        Boolean forVpc = cmd.getForVpc();
+        Boolean display = cmd.getDisplay();
+
+        // 1) default is system to false if not specified
+        // 2) reset parameter to false if it's specified by the regular user
+        if ((isSystem == null || _accountMgr.isNormalUser(caller.getId())) && id == null) {
+            isSystem = false;
+        }
+
+        // Account/domainId parameters and isSystem are mutually exclusive
+        if (isSystem != null && isSystem && (accountName != null || domainId != null)) {
+            throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified");
+        }
+
+        if (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                // see DomainVO.java
+                throw new InvalidParameterValueException("Specified domain id doesn't exist in the system");
+            }
+
+            _accountMgr.checkAccess(caller, domain);
+            if (accountName != null) {
+                Account owner = _accountMgr.getActiveAccountByName(accountName, domainId);
+                if (owner == null) {
+                    // see DomainVO.java
+                    throw new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain");
+                }
+
+                _accountMgr.checkAccess(caller, null, true, owner);
+                permittedAccounts.add(owner.getId());
+            }
+        }
+
+        if (!_accountMgr.isAdmin(caller.getId()) || (projectId != null && projectId.longValue() != -1 && domainId == null)) {
+            permittedAccounts.add(caller.getId());
+            domainId = caller.getDomainId();
+        }
+
+        // set project information
+        boolean skipProjectNetworks = true;
+        if (projectId != null) {
+            if (projectId.longValue() == -1) {
+                if (!_accountMgr.isAdmin(caller.getId())) {
+                    permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
+                }
+            } else {
+                permittedAccounts.clear();
+                Project project = _projectMgr.getProject(projectId);
+                if (project == null) {
+                    throw new InvalidParameterValueException("Unable to find project by specified id");
+                }
+                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
+                    // getProject() returns type ProjectVO.
+                    throwInvalidIdException("Account " + caller + " cannot access specified project id", project.getUuid(), "projectId");
+                }
+
+                //add project account
+                permittedAccounts.add(project.getProjectAccountId());
+                //add caller account (if admin)
+                if (_accountMgr.isAdmin(caller.getId())) {
+                    permittedAccounts.add(caller.getId());
+                }
+            }
+            skipProjectNetworks = false;
+        }
+
+        if (domainId != null) {
+            path = _domainDao.findById(domainId).getPath();
+        } else {
+            path = _domainDao.findById(caller.getDomainId()).getPath();
+        }
+
+        if (listAll && domainId == null) {
+            isRecursive = true;
+        }
+
+        Filter searchFilter = new Filter(NetworkVO.class, "id", false, null, null);
+        SearchBuilder<NetworkVO> sb = _networksDao.createSearchBuilder();
+
+        if (forVpc != null) {
+            if (forVpc) {
+                sb.and("vpc", sb.entity().getVpcId(), Op.NNULL);
+            } else {
+                sb.and("vpc", sb.entity().getVpcId(), Op.NULL);
+            }
+        }
+
+        // Don't display networks created of system network offerings
+        SearchBuilder<NetworkOfferingVO> networkOfferingSearch = _networkOfferingDao.createSearchBuilder();
+        networkOfferingSearch.and("systemOnly", networkOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
+        if (isSystem != null && isSystem) {
+            networkOfferingSearch.and("trafficType", networkOfferingSearch.entity().getTrafficType(), SearchCriteria.Op.EQ);
+        }
+        sb.join("networkOfferingSearch", networkOfferingSearch, sb.entity().getNetworkOfferingId(), networkOfferingSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        SearchBuilder<DataCenterVO> zoneSearch = _dcDao.createSearchBuilder();
+        zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ);
+        sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        sb.and("removed", sb.entity().getRemoved(), Op.NULL);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (permittedAccounts.isEmpty()) {
+            SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
+            domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
+            sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchBuilder<AccountVO> accountSearch = _accountDao.createSearchBuilder();
+        accountSearch.and("typeNEQ", accountSearch.entity().getType(), SearchCriteria.Op.NEQ);
+        accountSearch.and("typeEQ", accountSearch.entity().getType(), SearchCriteria.Op.EQ);
+
+        sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        List<NetworkVO> networksToReturn = new ArrayList<NetworkVO>();
+
+        if (isSystem == null || !isSystem) {
+            if (!permittedAccounts.isEmpty()) {
+                //get account level networks
+                networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType,
+                        skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, permittedAccounts));
+                //get domain level networks
+                if (domainId != null) {
+                    networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true,
+                            restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, domainId, false));
+                }
+            } else {
+                //add account specific networks
+                networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType,
+                        skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
+                //add domain specific networks of domain + parent domains
+                networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType,
+                        skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
+                //add networks of subdomains
+                if (domainId == null) {
+                    networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, true,
+                            restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, caller.getDomainId(), true));
+                }
+            }
+        } else {
+            networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks,
+                    restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter);
+        }
+
+        if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) {
+            List<NetworkVO> supportedNetworks = new ArrayList<NetworkVO>();
+            Service[] suppportedServices = new Service[supportedServicesStr.size()];
+            int i = 0;
+            for (String supportedServiceStr : supportedServicesStr) {
+                Service service = Service.getService(supportedServiceStr);
+                if (service == null) {
+                    throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
+                } else {
+                    suppportedServices[i] = service;
+                }
+                i++;
+            }
+
+            for (NetworkVO network : networksToReturn) {
+                if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) {
+                    supportedNetworks.add(network);
+                }
+            }
+
+            networksToReturn = supportedNetworks;
+        }
+
+        if (canUseForDeploy != null) {
+            List<NetworkVO> networksForDeploy = new ArrayList<NetworkVO>();
+            for (NetworkVO network : networksToReturn) {
+                if (_networkModel.canUseForDeploy(network) == canUseForDeploy) {
+                    networksForDeploy.add(network);
+                }
+            }
+
+            networksToReturn = networksForDeploy;
+        }
+
+        //Now apply pagination
+        List<? extends Network> wPagination = StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal());
+        if (wPagination != null) {
+            Pair<List<? extends Network>, Integer> listWPagination = new Pair<List<? extends Network>, Integer>(wPagination, networksToReturn.size());
+            return listWPagination;
+        }
+
+        return new Pair<List<? extends Network>, Integer>(networksToReturn, networksToReturn.size());
+    }
+
+    private SearchCriteria<NetworkVO> buildNetworkSearchCriteria(SearchBuilder<NetworkVO> sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType,
+            Long physicalNetworkId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map<String, String> tags, Boolean display) {
+
+        SearchCriteria<NetworkVO> sc = sb.create();
+
+        if (isSystem != null) {
+            sc.setJoinParameters("networkOfferingSearch", "systemOnly", isSystem);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (display != null) {
+            sc.addAnd("displayNetwork", SearchCriteria.Op.EQ, display);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (zoneId != null) {
+            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        if (guestIpType != null) {
+            sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType);
+        }
+
+        if (trafficType != null) {
+            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
+        }
+
+        if (aclType != null) {
+            sc.addAnd("aclType", SearchCriteria.Op.EQ, aclType.toString());
+        }
+
+        if (physicalNetworkId != null) {
+            sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId);
+        }
+
+        if (skipProjectNetworks) {
+            sc.setJoinParameters("accountSearch", "typeNEQ", Account.ACCOUNT_TYPE_PROJECT);
+        } else {
+            sc.setJoinParameters("accountSearch", "typeEQ", Account.ACCOUNT_TYPE_PROJECT);
+        }
+
+        if (restartRequired != null) {
+            sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
+        }
+
+        if (specifyIpRanges != null) {
+            sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges);
+        }
+
+        if (vpcId != null) {
+            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Network.toString());
+            for (Map.Entry<String, String> entry : tags.entrySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
+                count++;
+            }
+        }
+
+        return sc;
+    }
+
+    private List<NetworkVO> listDomainLevelNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) {
+        List<Long> networkIds = new ArrayList<Long>();
+        Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
+        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
+
+        for (NetworkDomainVO map : maps) {
+            if (map.getDomainId() == domainId && parentDomainsOnly) {
+                continue;
+            }
+            boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : getAllowSubdomainAccessGlobal();
+            if (map.getDomainId() == domainId || subdomainAccess) {
+                networkIds.add(map.getNetworkId());
+            }
+        }
+
+        if (!networkIds.isEmpty()) {
+            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
+            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
+            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
+
+            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
+            return _networksDao.search(sc, searchFilter);
+        } else {
+            return new ArrayList<NetworkVO>();
+        }
+    }
+
+    private List<NetworkVO> listAccountSpecificNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, List<Long> permittedAccounts) {
+        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
+        if (!permittedAccounts.isEmpty()) {
+            accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray());
+        }
+
+        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
+
+        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
+        return _networksDao.search(sc, searchFilter);
+    }
+
+    private List<NetworkVO> listAccountSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
+        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
+        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
+
+        if (path != null) {
+            if (isRecursive) {
+                sc.setJoinParameters("domainSearch", "path", path + "%");
+            } else {
+                sc.setJoinParameters("domainSearch", "path", path);
+            }
+        }
+
+        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
+        return _networksDao.search(sc, searchFilter);
+    }
+
+    private List<NetworkVO> listDomainSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
+
+        Set<Long> allowedDomains = new HashSet<Long>();
+        if (path != null) {
+            if (isRecursive) {
+                allowedDomains = _domainMgr.getDomainChildrenIds(path);
+            } else {
+                Domain domain = _domainDao.findDomainByPath(path);
+                allowedDomains.add(domain.getId());
+            }
+        }
+
+        List<Long> networkIds = new ArrayList<Long>();
+
+        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
+
+        for (NetworkDomainVO map : maps) {
+            networkIds.add(map.getNetworkId());
+        }
+
+        if (!networkIds.isEmpty()) {
+            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
+            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
+            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
+
+            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
+            return _networksDao.search(sc, searchFilter);
+        } else {
+            return new ArrayList<NetworkVO>();
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_DELETE, eventDescription = "deleting network", async = true)
+    public boolean deleteNetwork(long networkId, boolean forced) {
+
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify network id
+        NetworkVO network = _networksDao.findById(networkId);
+        if (network == null) {
+            // see NetworkVO.java
+
+            throwInvalidIdException("unable to find network with specified id", String.valueOf(networkId), "networkId");
+        }
+
+        // don't allow to delete system network
+        if (isNetworkSystem(network)) {
+            throwInvalidIdException("Network with specified id is system and can't be removed", network.getUuid(), "networkId");
+        }
+
+        Account owner = _accountMgr.getAccount(network.getAccountId());
+
+        // Only Admin can delete Shared networks
+        if ((network.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
+            throw new InvalidParameterValueException("Only Admins can delete network with guest type " + network.getGuestType());
+        }
+
+        // Perform permission check
+        _accountMgr.checkAccess(caller, null, true, network);
+
+        if (forced && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new InvalidParameterValueException("Delete network with 'forced' option can only be called by root admins");
+        }
+
+        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+        ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
+
+        return _networkMgr.destroyNetwork(networkId, context, forced);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_RESTART, eventDescription = "restarting network", async = true)
+    public boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        // This method restarts all network elements belonging to the network and re-applies all the rules
+        Long networkId = cmd.getNetworkId();
+
+        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+        Account callerAccount = _accountMgr.getActiveAccountById(callerUser.getAccountId());
+
+        // Check if network exists
+        NetworkVO network = _networksDao.findById(networkId);
+        if (network == null) {
+            throwInvalidIdException("Network with specified id doesn't exist", networkId.toString(), "networkId");
+        }
+
+        // Don't allow to restart network if it's not in Implemented/Setup state
+        if (!(network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) {
+            throw new InvalidParameterValueException("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", " + Network.State.Setup);
+        }
+
+        if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch) {
+            /**
+             * Unable to restart these networks now.
+             * TODO Restarting a SDN based network requires updating the nics and the configuration
+             * in the controller. This requires a non-trivial rewrite of the restart procedure.
+             */
+            throw new InvalidParameterException("Unable to restart a running SDN network.");
+        }
+
+        _accountMgr.checkAccess(callerAccount, null, true, network);
+
+        if (!network.isRedundant() && makeRedundant) {
+            network.setRedundant(true);
+            if (!_networksDao.update(network.getId(), network)) {
+                throw new CloudRuntimeException("Failed to update network into a redundant one, please try again");
+            }
+            cleanup = true;
+        }
+
+        boolean success = _networkMgr.restartNetwork(networkId, callerAccount, callerUser, cleanup);
+
+        if (success) {
+            s_logger.debug("Network id=" + networkId + " is restarted successfully.");
+        } else {
+            s_logger.warn("Network id=" + networkId + " failed to restart.");
+        }
+
+        return success;
+    }
+
+    @Override
+    public int getActiveNicsInNetwork(long networkId) {
+        return _networksDao.getActiveNicsIn(networkId);
+    }
+
+    @Override
+    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
+
+        if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) {
+            // TBD: We should be sending networkOfferingId and not the offering object itself.
+            throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering);
+        }
+
+        Map<Capability, String> serviceCapabilities = new HashMap<Capability, String>();
+
+        // get the Provider for this Service for this offering
+        List<String> providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service);
+        if (providers.isEmpty()) {
+            // TBD: We should be sending networkOfferingId and not the offering object itself.
+            throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering);
+        }
+
+        // FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so
+        // we have to calculate capabilities for all of them
+        String provider = providers.get(0);
+
+        // FIXME we return the capabilities of the first provider of the service - what if we have multiple providers
+        // for same Service?
+        NetworkElement element = _networkModel.getElementImplementingProvider(provider);
+        if (element != null) {
+            Map<Service, Map<Capability, String>> elementCapabilities = element.getCapabilities();
+            ;
+
+            if (elementCapabilities == null || !elementCapabilities.containsKey(service)) {
+                // TBD: We should be sending providerId and not the offering object itself.
+                throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() + " implementing Provider=" + provider);
+            }
+            serviceCapabilities = elementCapabilities.get(service);
+        }
+
+        return serviceCapabilities;
+    }
+
+    @Override
+    public IpAddress getIp(long ipAddressId) {
+        return _ipAddressDao.findById(ipAddressId);
+    }
+
+    protected boolean providersConfiguredForExternalNetworking(Collection<String> providers) {
+        for (String providerStr : providers) {
+            Provider provider = Network.Provider.getProvider(providerStr);
+            if (provider.isExternal()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
+        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
+        if ((networkOffering.getGuestType() == Network.GuestType.Shared) && (areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
+                || areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat) || areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
+                || areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || areServicesSupportedByNetworkOffering(networkOfferingId, Service.Lb))) {
+            return true;
+        }
+        return false;
+    }
+
+    protected boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
+        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
+    }
+
+    protected boolean areServicesSupportedInNetwork(long networkId, Service... services) {
+        return (_ntwkSrvcDao.areServicesSupportedInNetwork(networkId, services));
+    }
+
+    private boolean checkForNonStoppedVmInNetwork(long networkId) {
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Migrating, VirtualMachine.State.Stopping);
+        return vms.isEmpty();
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true)
+    public Network updateGuestNetwork(final long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, final Long networkOfferingId,
+            Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String customId, boolean updateInSequence, boolean forced) {
+        boolean restartNetwork = false;
+
+        // verify input parameters
+        final NetworkVO network = _networksDao.findById(networkId);
+        if (network == null) {
+            // see NetworkVO.java
+            throwInvalidIdException("Specified network id doesn't exist in the system", String.valueOf(networkId), "networkId");
+        }
+
+        //perform below validation if the network is vpc network
+        if (network.getVpcId() != null && networkOfferingId != null) {
+            Vpc vpc = _entityMgr.findById(Vpc.class, network.getVpcId());
+            _vpcMgr.validateNtwkOffForNtwkInVpc(networkId, networkOfferingId, null, null, vpc, null, _accountMgr.getAccount(network.getAccountId()), network.getNetworkACLId());
+        }
+
+        // don't allow to update network in Destroy state
+        if (network.getState() == Network.State.Destroy) {
+            throw new InvalidParameterValueException("Don't allow to update network in state " + Network.State.Destroy);
+        }
+
+        // Don't allow to update system network
+        NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        if (offering.isSystemOnly()) {
+            throw new InvalidParameterValueException("Can't update system networks");
+        }
+
+        // allow to upgrade only Guest networks
+        if (network.getTrafficType() != Networks.TrafficType.Guest) {
+            throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
+        }
+
+        _accountMgr.checkAccess(callerAccount, null, true, network);
+
+        if (name != null) {
+            network.setName(name);
+        }
+
+        if (displayText != null) {
+            network.setDisplayText(displayText);
+        }
+
+        if (customId != null) {
+            network.setUuid(customId);
+        }
+
+        // display flag is not null and has changed
+        if (displayNetwork != null && displayNetwork != network.getDisplayNetwork()) {
+            // Update resource count if it needs to be updated
+            NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+            if (_networkMgr.resourceCountNeedsUpdate(networkOffering, network.getAclType())) {
+                _resourceLimitMgr.changeResourceCount(network.getAccountId(), Resource.ResourceType.network, displayNetwork);
+            }
+
+            network.setDisplayNetwork(displayNetwork);
+        }
+
+        // network offering and domain suffix can be updated for Isolated networks only in 3.0
+        if ((networkOfferingId != null || domainSuffix != null) && network.getGuestType() != GuestType.Isolated) {
+            throw new InvalidParameterValueException("NetworkOffering and domain suffix upgrade can be perfomed for Isolated networks only");
+        }
+
+        boolean networkOfferingChanged = false;
+
+        final long oldNetworkOfferingId = network.getNetworkOfferingId();
+        NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+        NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
+        if (networkOfferingId != null) {
+            if (networkOffering == null || networkOffering.isSystemOnly()) {
+                throwInvalidIdException("Unable to find network offering with specified id", networkOfferingId.toString(), "networkOfferingId");
+            }
+
+            // network offering should be in Enabled state
+            if (networkOffering.getState() != NetworkOffering.State.Enabled) {
+                throwInvalidIdException("Network offering with specified id is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it", networkOffering.getUuid(),
+                        "networkOfferingId");
+            }
+            //can't update from vpc to non-vpc network offering
+            boolean forVpcNew = _configMgr.isOfferingForVpc(networkOffering);
+            boolean vorVpcOriginal = _configMgr.isOfferingForVpc(_entityMgr.findById(NetworkOffering.class, oldNetworkOfferingId));
+            if (forVpcNew != vorVpcOriginal) {
+                String errMsg = forVpcNew ? "a vpc offering " : "not a vpc offering";
+                throw new InvalidParameterValueException("Can't update as the new offering is " + errMsg);
+            }
+
+            if (networkOfferingId != oldNetworkOfferingId) {
+                Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(networkOffering, network.getPhysicalNetworkId()).values();
+                Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values();
+
+                if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders) && !changeCidr) {
+                    throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
+                }
+                if (changeCidr) {
+                    if (!checkForNonStoppedVmInNetwork(network.getId())) {
+                        throwInvalidIdException("All user vm of network of specified id should be stopped before changing CIDR!", network.getUuid(), "networkId");
+                    }
+                }
+                // check if the network is upgradable
+                if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) {
+                    throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + networkOffering.getUuid() + "; check logs for more information");
+                }
+                restartNetwork = true;
+                networkOfferingChanged = true;
+
+                //Setting the new network's isReduntant to the new network offering's RedundantRouter.
+                network.setRedundant(_networkOfferingDao.findById(networkOfferingId).isRedundantRouter());
+            }
+        }
+
+        final Map<String, String> newSvcProviders = networkOfferingChanged
+                ? _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId())
+                        : new HashMap<String, String>();
+
+                // don't allow to modify network domain if the service is not supported
+                if (domainSuffix != null) {
+                    // validate network domain
+                    if (!NetUtils.verifyDomainName(domainSuffix)) {
+                        throw new InvalidParameterValueException(
+                                "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                        + "and the hyphen ('-'); can't start or end with \"-\"");
+                    }
+
+                    long offeringId = oldNetworkOfferingId;
+                    if (networkOfferingId != null) {
+                        offeringId = networkOfferingId;
+                    }
+
+                    Map<Network.Capability, String> dnsCapabilities = getNetworkOfferingServiceCapabilities(_entityMgr.findById(NetworkOffering.class, offeringId), Service.Dns);
+                    String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
+                    if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
+                        // TBD: use uuid instead of networkOfferingId. May need to hardcode tablename in call to addProxyObject().
+                        throw new InvalidParameterValueException("Domain name change is not supported by the network offering id=" + networkOfferingId);
+                    }
+
+                    network.setNetworkDomain(domainSuffix);
+                    // have to restart the network
+                    restartNetwork = true;
+                }
+
+                //IP reservation checks
+                // allow reservation only to Isolated Guest networks
+                DataCenter dc = _dcDao.findById(network.getDataCenterId());
+                String networkCidr = network.getNetworkCidr();
+
+                if (guestVmCidr != null) {
+                    if (dc.getNetworkType() == NetworkType.Basic) {
+                        throw new InvalidParameterValueException("Guest VM CIDR can't be specified for zone with " + NetworkType.Basic + " networking");
+                    }
+                    if (network.getGuestType() != GuestType.Isolated) {
+                        throw new InvalidParameterValueException("Can only allow IP Reservation in networks with guest type " + GuestType.Isolated);
+                    }
+                    if (networkOfferingChanged) {
+                        throw new InvalidParameterValueException("Cannot specify this nework offering change and guestVmCidr at same time. Specify only one.");
+                    }
+                    if (!(network.getState() == Network.State.Implemented)) {
+                        throw new InvalidParameterValueException("The network must be in " + Network.State.Implemented + " state. IP Reservation cannot be applied in " + network.getState() + " state");
+                    }
+                    if (!NetUtils.isValidIp4Cidr(guestVmCidr)) {
+                        throw new InvalidParameterValueException("Invalid format of Guest VM CIDR.");
+                    }
+                    if (!NetUtils.validateGuestCidr(guestVmCidr)) {
+                        throw new InvalidParameterValueException("Invalid format of Guest VM CIDR. Make sure it is RFC1918 compliant. ");
+                    }
+
+                    // If networkCidr is null it implies that there was no prior IP reservation, so the network cidr is network.getCidr()
+                    // But in case networkCidr is a non null value (IP reservation already exists), it implies network cidr is networkCidr
+                    if (networkCidr != null) {
+                        if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, networkCidr)) {
+                            throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR : " + networkCidr);
+                        }
+                    } else {
+                        if (!NetUtils.isNetworkAWithinNetworkB(guestVmCidr, network.getCidr())) {
+                            throw new InvalidParameterValueException("Invalid value of Guest VM CIDR. For IP Reservation, Guest VM CIDR  should be a subset of network CIDR :  " + network.getCidr());
+                        }
+                    }
+
+                    // This check makes sure there are no active IPs existing outside the guestVmCidr in the network
+                    String[] guestVmCidrPair = guestVmCidr.split("\\/");
+                    Long size = Long.valueOf(guestVmCidrPair[1]);
+                    List<NicVO> nicsPresent = _nicDao.listByNetworkId(networkId);
+
+                    String cidrIpRange[] = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], size);
+                    s_logger.info("The start IP of the specified guest vm cidr is: " + cidrIpRange[0] + " and end IP is: " + cidrIpRange[1]);
+                    long startIp = NetUtils.ip2Long(cidrIpRange[0]);
+                    long endIp = NetUtils.ip2Long(cidrIpRange[1]);
+                    long range = endIp - startIp + 1;
+                    s_logger.info("The specified guest vm cidr has " + range + " IPs");
+
+                    for (NicVO nic : nicsPresent) {
+                        long nicIp = NetUtils.ip2Long(nic.getIPv4Address());
+                        //check if nic IP is outside the guest vm cidr
+                        if ((nicIp < startIp || nicIp > endIp) && nic.getState() != Nic.State.Deallocating) {
+                            throw new InvalidParameterValueException("Active IPs like " + nic.getIPv4Address() + " exist outside the Guest VM CIDR. Cannot apply reservation ");
+                        }
+                    }
+
+                    // In some scenarios even though guesVmCidr and network CIDR do not appear similar but
+                    // the IP ranges exactly matches, in these special cases make sure no Reservation gets applied
+                    if (network.getNetworkCidr() == null) {
+                        if (NetUtils.isSameIpRange(guestVmCidr, network.getCidr()) && !guestVmCidr.equals(network.getCidr())) {
+                            throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and CIDR: " + network.getCidr() + " are same, "
+                                    + "even though both the cidrs appear to be different. As a precaution no IP Reservation will be applied.");
+                        }
+                    } else {
+                        if (NetUtils.isSameIpRange(guestVmCidr, network.getNetworkCidr()) && !guestVmCidr.equals(network.getNetworkCidr())) {
+                            throw new InvalidParameterValueException("The Start IP and End IP of guestvmcidr: " + guestVmCidr + " and Network CIDR: " + network.getNetworkCidr() + " are same, "
+                                    + "even though both the cidrs appear to be different. As a precaution IP Reservation will not be affected. If you want to reset IP Reservation, "
+                                    + "specify guestVmCidr to be: " + network.getNetworkCidr());
+                        }
+                    }
+
+                    // When reservation is applied for the first time, network_cidr will be null
+                    // Populate it with the actual network cidr
+                    if (network.getNetworkCidr() == null) {
+                        network.setNetworkCidr(network.getCidr());
+                    }
+
+                    // Condition for IP Reservation reset : guestVmCidr and network CIDR are same
+                    if (network.getNetworkCidr().equals(guestVmCidr)) {
+                        s_logger.warn("Guest VM CIDR and Network CIDR both are same, reservation will reset.");
+                        network.setNetworkCidr(null);
+                    }
+                    // Finally update "cidr" with the guestVmCidr
+                    // which becomes the effective address space for CloudStack guest VMs
+                    network.setCidr(guestVmCidr);
+                    _networksDao.update(networkId, network);
+                    s_logger.info("IP Reservation has been applied. The new CIDR for Guests Vms is " + guestVmCidr);
+                }
+
+                ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
+                // 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
+                // states - Shutdown and Implementing
+                int resourceCount = 1;
+                if (updateInSequence && restartNetwork && _networkOfferingDao.findById(network.getNetworkOfferingId()).isRedundantRouter()
+                        && (networkOfferingId == null || _networkOfferingDao.findById(networkOfferingId).isRedundantRouter()) && network.getVpcId() == null) {
+                    _networkMgr.canUpdateInSequence(network, forced);
+                    NetworkDetailVO networkDetail = new NetworkDetailVO(network.getId(), Network.updatingInSequence, "true", true);
+                    _networkDetailsDao.persist(networkDetail);
+                    _networkMgr.configureUpdateInSequence(network);
+                    resourceCount = _networkMgr.getResourceCount(network);
+                }
+                List<String> servicesNotInNewOffering = null;
+                if (networkOfferingId != null) {
+                    servicesNotInNewOffering = _networkMgr.getServicesNotSupportedInNewOffering(network, networkOfferingId);
+                }
+                if (!forced && servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
+                    NetworkOfferingVO newOffering = _networkOfferingDao.findById(networkOfferingId);
+                    throw new CloudRuntimeException("The new offering:" + newOffering.getUniqueName() + " will remove the following services " + servicesNotInNewOffering
+                            + "along with all the related configuration currently in use. will not proceed with the network update." + "set forced parameter to true for forcing an update.");
+                }
+                try {
+                    if (servicesNotInNewOffering != null && !servicesNotInNewOffering.isEmpty()) {
+                        _networkMgr.cleanupConfigForServicesInNetwork(servicesNotInNewOffering, network);
+                    }
+                } catch (Throwable e) {
+                    s_logger.debug("failed to cleanup config related to unused services error:" + e.getMessage());
+                }
+
+                boolean validStateToShutdown = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated);
+                try {
+
+                    do {
+                        if (restartNetwork) {
+                            if (validStateToShutdown) {
+                                if (!changeCidr) {
+                                    s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update");
+
+                                    if (!_networkMgr.shutdownNetworkElementsAndResources(context, true, network)) {
+                                        s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network);
+                                        CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id");
+                                        ex.addProxyObject(network.getUuid(), "networkId");
+                                        throw ex;
+                                    }
+                                } else {
+                                    // We need to shutdown the network, since we want to re-implement the network.
+                                    s_logger.debug("Shutting down network id=" + networkId + " as a part of network update");
+
+                                    //check if network has reservation
+                                    if (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr())) {
+                                        s_logger.warn(
+                                                "Existing IP reservation will become ineffective for the network with id =  " + networkId + " You need to reapply reservation after network reimplementation.");
+                                        //set cidr to the newtork cidr
+                                        network.setCidr(network.getNetworkCidr());
+                                        //set networkCidr to null to bring network back to no IP reservation state
+                                        network.setNetworkCidr(null);
+                                    }
+
+                                    if (!_networkMgr.shutdownNetwork(network.getId(), context, true)) {
+                                        s_logger.warn("Failed to shutdown the network as a part of update to network with specified id");
+                                        CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id");
+                                        ex.addProxyObject(network.getUuid(), "networkId");
+                                        throw ex;
+                                    }
+                                }
+                            } else {
+                                CloudRuntimeException ex = new CloudRuntimeException(
+                                        "Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState());
+                                ex.addProxyObject(network.getUuid(), "networkId");
+                                throw ex;
+                            }
+                        }
+
+                        // 2) Only after all the elements and rules are shutdown properly, update the network VO
+                        // get updated network
+                        Network.State networkState = _networksDao.findById(networkId).getState();
+                        boolean validStateToImplement = (networkState == Network.State.Implemented || networkState == Network.State.Setup || networkState == Network.State.Allocated);
+                        if (restartNetwork && !validStateToImplement) {
+                            CloudRuntimeException ex = new CloudRuntimeException(
+                                    "Failed to implement the network elements and resources as a part of update to network with specified id; network is in wrong state: " + networkState);
+                            ex.addProxyObject(network.getUuid(), "networkId");
+                            throw ex;
+                        }
+
+                        if (networkOfferingId != null) {
+                            if (networkOfferingChanged) {
+                                Transaction.execute(new TransactionCallbackNoReturn() {
+                                    @Override
+                                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                                        network.setNetworkOfferingId(networkOfferingId);
+                                        _networksDao.update(networkId, network, newSvcProviders);
+                                        // get all nics using this network
+                                        // log remove usage events for old offering
+                                        // log assign usage events for new offering
+                                        List<NicVO> nics = _nicDao.listByNetworkId(networkId);
+                                        for (NicVO nic : nics) {
+                                            long vmId = nic.getInstanceId();
+                                            VMInstanceVO vm = _vmDao.findById(vmId);
+                                            if (vm == null) {
+                                                s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId);
+                                                continue;
+                                            }
+                                            long isDefault = (nic.isDefaultNic()) ? 1 : 0;
+                                            String nicIdString = Long.toString(nic.getId());
+                                            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, oldNetworkOfferingId,
+                                                    null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
+                                            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), nicIdString, networkOfferingId,
+                                                    null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
+                                        }
+                                    }
+                                });
+                            } else {
+                                network.setNetworkOfferingId(networkOfferingId);
+                                _networksDao.update(networkId, network,
+                                        _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId()));
+                            }
+                        } else {
+                            _networksDao.update(networkId, network);
+                        }
+
+                        // 3) Implement the elements and rules again
+                        if (restartNetwork) {
+                            if (network.getState() != Network.State.Allocated) {
+                                DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
+                                s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
+                                try {
+                                    if (!changeCidr) {
+                                        _networkMgr.implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId()));
+                                    } else {
+                                        _networkMgr.implementNetwork(network.getId(), dest, context);
+                                    }
+                                } catch (Exception ex) {
+                                    s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
+                                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
+                                    e.addProxyObject(network.getUuid(), "networkId");
+                                    throw e;
+                                }
+                            }
+                        }
+
+                        // 4) if network has been upgraded from a non persistent ntwk offering to a persistent ntwk offering,
+                        // implement the network if its not already
+                        if (networkOfferingChanged && !oldNtwkOff.isPersistent() && networkOffering.isPersistent()) {
+                            if (network.getState() == Network.State.Allocated) {
+                                try {
+                                    DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
+                                    _networkMgr.implementNetwork(network.getId(), dest, context);
+                                } catch (Exception ex) {
+                                    s_logger.warn("Failed to implement network " + network + " elements and resources as a part o" + "f network update due to ", ex);
+                                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified" + " id) elements and resources as a part of network update");
+                                    e.addProxyObject(network.getUuid(), "networkId");
+                                    throw e;
+                                }
+                            }
+                        }
+                        resourceCount--;
+                    } while (updateInSequence && resourceCount > 0);
+                } catch (Exception exception) {
+                    if (updateInSequence) {
+                        _networkMgr.finalizeUpdateInSequence(network, false);
+                    }
+                    throw new CloudRuntimeException("failed to update network " + network.getUuid() + " due to " + exception.getMessage());
+                } finally {
+                    if (updateInSequence) {
+                        if (_networkDetailsDao.findDetail(networkId, Network.updatingInSequence) != null) {
+                            _networkDetailsDao.removeDetail(networkId, Network.updatingInSequence);
+                        }
+                    }
+                }
+                return getNetwork(network.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_MIGRATE, eventDescription = "migrating network", async = true)
+    public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
+        NetworkVO network = _networksDao.findById(networkId);
+        NetworkOffering newNtwkOff = _networkOfferingDao.findById(networkOfferingId);
+
+        //perform below validation if the network is vpc network
+        if (network.getVpcId() != null) {
+            s_logger.warn("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
+            throw new InvalidParameterValueException("Failed to migrate network as the specified network is a vpc tier. Use migrateVpc.");
+        }
+
+        if (_configMgr.isOfferingForVpc(newNtwkOff)) {
+            s_logger.warn("Failed to migrate network as the specified network offering is a VPC offering");
+            throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is a VPC offering");
+        }
+
+        verifyNetworkCanBeMigrated(callerAccount, network);
+
+        //Retrieve new Physical NetworkId
+        long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
+
+        final long oldNetworkOfferingId = network.getNetworkOfferingId();
+        NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+
+        if (!resume && network.getRelated() != network.getId()) {
+            s_logger.warn("Related network is not equal to network id. You might want to re-run migration with resume = true command.");
+            throw new CloudRuntimeException("Failed to migrate network as previous migration left this network in transient condition. Specify resume as true.");
+        }
+
+        if (networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff)) {
+            return migrateNetworkToPhysicalNetwork(network, oldNtwkOff, newNtwkOff, null, null, newPhysicalNetworkId, callerAccount, callerUser);
+        } else {
+            s_logger.info("Network does not need migration.");
+            return network;
+        }
+    }
+
+    private class NetworkCopy {
+        private Long networkIdInOldPhysicalNet;
+        private Network networkInNewPhysicalNet;
+
+        public NetworkCopy(Long networkIdInOldPhysicalNet, Network networkInNewPhysicalNet) {
+            this.networkIdInOldPhysicalNet = networkIdInOldPhysicalNet;
+            this.networkInNewPhysicalNet = networkInNewPhysicalNet;
+        }
+
+        public Long getNetworkIdInOldPhysicalNet() {
+            return networkIdInOldPhysicalNet;
+        }
+
+        public Network getNetworkInNewPhysicalNet() {
+            return networkInNewPhysicalNet;
+        }
+    }
+
+    private Network migrateNetworkToPhysicalNetwork(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId,
+            Account callerAccount, User callerUser) {
+        boolean resume = network.getRelated() != network.getId();
+
+        NetworkCopy networkCopy;
+
+        // Resume is only true when there is already a copy of the network created
+        if (resume) {
+            Network networkInNewPhysicalNet = network;
+            networkCopy = new NetworkCopy(network.getRelated(), networkInNewPhysicalNet);
+
+            //the new network could already be implemented, check if the already partially upgrade networks has the same network offering as before or check if it still has the original network offering
+            //the old network offering uuid should be the one of the already created copy
+            if (networkInNewPhysicalNet.getNetworkOfferingId() != newNtwkOff.getId()) {
+                throw new InvalidParameterValueException("Failed to resume migrating network as network offering does not match previously specified network offering (" + newNtwkOff.getUuid() + ")");
+            }
+        } else {
+            networkCopy = Transaction.execute((TransactionCallback<NetworkCopy>)(status) -> migrateNetworkInDb(network, oldNtwkOff, newNtwkOff, oldVpcId, newVpcId, newPhysicalNetworkId));
+        }
+
+        Long networkIdInOldPhysicalNet = networkCopy.getNetworkIdInOldPhysicalNet();
+        Network networkInNewPhysicalNet = networkCopy.getNetworkInNewPhysicalNet();
+
+        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
+        DataCenter zone = _dcDao.findById(network.getDataCenterId());
+        NetworkVO networkInOldPhysNet = _networksDao.findById(networkIdInOldPhysicalNet);
+
+        boolean shouldImplement = (newNtwkOff.isPersistent() || networkInOldPhysNet.getState() == Network.State.Implemented) && networkInNewPhysicalNet.getState() != Network.State.Implemented;
+
+        if (shouldImplement) {
+            DeployDestination dest = new DeployDestination(zone, null, null, null);
+            s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
+            try {
+                networkInNewPhysicalNet = _networkMgr.implementNetwork(networkInNewPhysicalNet.getId(), dest, context).second();
+            } catch (Exception ex) {
+                s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
+                CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
+                e.addProxyObject(network.getUuid(), "networkId");
+                throw e;
+            }
+        }
+
+        _networkMigrationManager.assignNicsToNewPhysicalNetwork(networkInOldPhysNet, networkInNewPhysicalNet);
+        //clean up the old copy of the network
+        _networkMigrationManager.deleteCopyOfNetwork(networkIdInOldPhysicalNet, networkInNewPhysicalNet.getId());
+
+        return getNetwork(network.getId());
+    }
+
+    private NetworkCopy migrateNetworkInDb(Network network, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff, Long oldVpcId, Long newVpcId, long newPhysicalNetworkId) {
+        //The copy will be the network in the old physical network
+        //And we will use it to store tmp data while we upgrade or original network to the new physical network
+        Long networkIdInOldPhysicalNet = _networkMigrationManager.makeCopyOfNetwork(network, oldNtwkOff, oldVpcId);
+        Network networkInNewPhysicalNet = _networkMigrationManager.upgradeNetworkToNewNetworkOffering(network.getId(), newPhysicalNetworkId, newNtwkOff.getId(), newVpcId);
+        return new NetworkCopy(networkIdInOldPhysicalNet, networkInNewPhysicalNet);
+    }
+
+    @Override
+    public Vpc migrateVpcNetwork(long vpcId, long vpcOfferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
+        //Check if a previous migration run failed and try to resume if resume = true
+        ResourceTag relatedVpc = _resourceTagDao.findByKey(vpcId, ResourceObjectType.Vpc, NetworkMigrationManager.MIGRATION);
+        long vpcCopyId = 0;
+
+        /*
+         * In the vpc migration process the newly created Vpc will be used as the new VPC (opposed to network tier migration).
+         * In case the copy of the vpc was already created. The uuid where already swapped and the id we receive here is the id of the Copy!
+         * The id stored in the resource tag table under the key "migration" is the id of the ORIGINAL vpc!
+         */
+        if (relatedVpc != null) {
+            if (resume) {
+                vpcCopyId = vpcId;
+                vpcId = Long.parseLong(relatedVpc.getValue());
+                //let's check if the user did not change the vpcoffering opposed to the last failed run.
+                verifyAlreadyMigratedTiers(vpcCopyId, vpcOfferingId, networkToOffering);
+            } else {
+                s_logger.warn("This vpc has a migration row in the resource details table. You might want to re-run migration with resume = true command.");
+                throw new CloudRuntimeException("Failed to migrate VPC as previous migration left this VPC in transient condition. Specify resume as true.");
+            }
+        }
+
+        Vpc vpc = _vpcDao.findById(vpcId);
+        _accountMgr.checkAccess(account, null, true, vpc);
+
+        if (vpc.getVpcOfferingId() == vpcOfferingId) {
+            return vpc;
+        }
+        //Try to fail fast, check networks in the VPC and if we can migrate them before proceeding.
+        List<NetworkVO> tiersInVpc = _networksDao.listByVpc(vpcId);
+        vpcTiersCanBeMigrated(tiersInVpc, account, networkToOffering, resume);
+
+        //In case this is the first time we try to migrate this vpc
+        if (relatedVpc == null) {
+            final long vpcIdFinal = vpcId;
+            vpcCopyId = Transaction.execute((TransactionCallback<Long>)(status) -> _networkMigrationManager.makeCopyOfVpc(vpcIdFinal, vpcOfferingId));
+        }
+
+        Vpc copyOfVpc = _vpcDao.findById(vpcCopyId);
+        _networkMigrationManager.startVpc(copyOfVpc);
+
+        for (Network tier : tiersInVpc) {
+            String networkOfferingUuid = networkToOffering.get(tier.getUuid());
+            //UUID may be swapped already with a new uuid due to previous migration failure.
+            //So we check the related network also in case we don't find the network offering
+            Long networkId = null;
+            if (resume && networkOfferingUuid == null) {
+                tier = _networksDao.findById(tier.getRelated());
+                networkOfferingUuid = networkToOffering.get(tier.getUuid());
+                //In this case the tier already exists so we need to get the id of the tier so we can validate correctly
+                networkId = tier.getId();
+            }
+            NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
+
+            Account networkAccount = _accountService.getActiveAccountById(tier.getAccountId());
+            try {
+                _vpcMgr.validateNtwkOffForNtwkInVpc(networkId, newNtwkOff.getId(), tier.getCidr(), tier.getNetworkDomain(), copyOfVpc, tier.getGateway(), networkAccount, tier.getNetworkACLId());
+            } catch (InvalidParameterValueException e) {
+                s_logger.error("Specified network offering can not be used in combination with specified vpc offering. Aborting migration. You can re-run with resume = true and the correct uuid.");
+                throw e;
+            }
+
+            long newPhysicalNetworkId = findPhysicalNetworkId(tier.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
+
+            final long oldNetworkOfferingId = tier.getNetworkOfferingId();
+            NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+
+            if (networkNeedsMigration(tier, newPhysicalNetworkId, oldNtwkOff, newNtwkOff) || (resume && tier.getRelated() != tier.getId())) {
+                migrateNetworkToPhysicalNetwork(tier, oldNtwkOff, newNtwkOff, vpcId, vpcCopyId, newPhysicalNetworkId, account, callerUser);
+            }
+        }
+        _networkMigrationManager.deleteCopyOfVpc(vpcId, vpcCopyId);
+        return _vpcDao.findById(vpcCopyId);
+    }
+
+    private void vpcTiersCanBeMigrated(List<? extends Network> tiersInVpc, Account account, Map<String, String> networkToOffering, boolean resume) {
+        for (Network network : tiersInVpc) {
+            String networkOfferingUuid = networkToOffering.get(network.getUuid());
+
+            //offering uuid can be a tier where the uuid is previously already swapped in a previous migration
+            if (resume && networkOfferingUuid == null) {
+                NetworkVO oldVPCtier = _networksDao.findById(network.getRelated());
+                networkOfferingUuid = networkToOffering.get(oldVPCtier.getUuid());
+            }
+
+            if (networkOfferingUuid == null) {
+                throwInvalidIdException("Failed to migrate VPC as the specified tierNetworkOfferings is not complete", String.valueOf(network.getUuid()), "networkUuid");
+            }
+
+            NetworkOfferingVO newNtwkOff = _networkOfferingDao.findByUuid(networkOfferingUuid);
+
+            if (newNtwkOff == null) {
+                throwInvalidIdException("Failed to migrate VPC as at least one network offering in tierNetworkOfferings does not exist", networkOfferingUuid, "networkOfferingUuid");
+            }
+
+            if (!_configMgr.isOfferingForVpc(newNtwkOff)) {
+                throw new InvalidParameterValueException(
+                        "Network offering " + newNtwkOff.getName() + " (" + newNtwkOff.getUuid() + ") can't be used for VPC networks for network " + network.getName() + "(" + network.getUuid() + ")");
+            }
+
+            verifyNetworkCanBeMigrated(account, network);
+            long newPhysicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), newNtwkOff.getTags(), newNtwkOff.getTrafficType());
+
+            final long oldNetworkOfferingId = network.getNetworkOfferingId();
+            NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+            networkNeedsMigration(network, newPhysicalNetworkId, oldNtwkOff, newNtwkOff);
+        }
+    }
+
+    private void verifyAlreadyMigratedTiers(long migratedVpcId, long vpcOfferingId, Map<String, String> networkToOffering) {
+        Vpc migratedVpc = _vpcDao.findById(migratedVpcId);
+        if (migratedVpc.getVpcOfferingId() != vpcOfferingId) {
+            s_logger.error("The vpc is already partially migrated in a previous run. The provided vpc offering is not the same as the one used during the first migration process.");
+            throw new InvalidParameterValueException("Failed to resume migrating VPC as VPC offering does not match previously specified VPC offering (" + migratedVpc.getVpcOfferingId() + ")");
+        }
+
+        List<NetworkVO> migratedTiers = _networksDao.listByVpc(migratedVpcId);
+        for (Network tier : migratedTiers) {
+            String tierNetworkOfferingUuid = networkToOffering.get(tier.getUuid());
+
+            if (!StringUtils.isNotBlank(tierNetworkOfferingUuid)) {
+                throwInvalidIdException("Failed to resume migrating VPC as the specified tierNetworkOfferings is not complete", String.valueOf(tier.getUuid()), "networkUuid");
+            }
+
+            NetworkOfferingVO newNetworkOffering = _networkOfferingDao.findByUuid(tierNetworkOfferingUuid);
+            if (newNetworkOffering == null) {
+                throw new InvalidParameterValueException("Failed to migrate VPC as at least one tier offering in tierNetworkOfferings does not exist.");
+            }
+
+            if (newNetworkOffering.getId() != tier.getNetworkOfferingId()) {
+                NetworkOfferingVO tierNetworkOffering = _networkOfferingDao.findById(tier.getNetworkOfferingId());
+                throw new InvalidParameterValueException(
+                        "Failed to resume migrating VPC as at least one network offering in tierNetworkOfferings does not match previously specified network offering (network uuid=" + tier.getUuid()
+                        + " was previously specified with offering uuid=" + tierNetworkOffering.getUuid() + ")");
+            }
+        }
+    }
+
+    private void throwInvalidIdException(String message, String uuid, String description) {
+        InvalidParameterValueException ex = new InvalidParameterValueException(message);
+        ex.addProxyObject(uuid, description);
+        throw ex;
+    }
+
+    private boolean networkNeedsMigration(Network network, long newPhysicalNetworkId, NetworkOffering oldNtwkOff, NetworkOffering newNtwkOff) {
+
+        if (newNtwkOff == null || newNtwkOff.isSystemOnly()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering.");
+            if (newNtwkOff != null) {
+                ex.addProxyObject(String.valueOf(newNtwkOff.getId()), "networkOfferingId");
+            }
+            throw ex;
+        }
+
+        if (newNtwkOff.getId() != oldNtwkOff.getId() || network.getId() != network.getRelated()) {
+            Collection<String> newProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(newNtwkOff, newPhysicalNetworkId).values();
+            Collection<String> oldProviders = _networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values();
+
+            if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders)) {
+                throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
+            }
+
+            // check if the network is moveable
+            if (!canMoveToPhysicalNetwork(network, oldNtwkOff.getId(), newNtwkOff.getId())) {
+                throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + newNtwkOff.getUuid() + "; check logs for more information");
+            }
+
+            List<VMInstanceVO> vmInstances = _vmDao.listNonRemovedVmsByTypeAndNetwork(network.getId(), null);
+            boolean vmStateIsNotTransitioning = vmInstances.stream().anyMatch(vm -> vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Running);
+            if (vmStateIsNotTransitioning) {
+                throw new CloudRuntimeException("Failed to migrate network as at least one VM is not in running or stopped state.");
+            }
+        } else {
+            return false;
+        }
+
+        // network offering should be in Enabled state
+        if (newNtwkOff.getState() != NetworkOffering.State.Enabled) {
+            throw new InvalidParameterValueException("Failed to migrate network as the specified network offering is not enabled.");
+        }
+        return true;
+    }
+
+    private void verifyNetworkCanBeMigrated(Account callerAccount, Network network) {
+        // Don't allow to update system network
+        NetworkOffering oldOffering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        if (oldOffering.isSystemOnly()) {
+            throw new InvalidParameterValueException("Failed to migrate network as the specified network is a system network.");
+        }
+
+        // allow to upgrade only Guest networks
+        if (network.getTrafficType() != TrafficType.Guest) {
+            throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
+        }
+
+        _accountMgr.checkAccess(callerAccount, null, true, network);
+
+        boolean validateNetworkReadyToMigrate = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated);
+        if (!validateNetworkReadyToMigrate) {
+            s_logger.error("Failed to migrate network as it is in invalid state.");
+            CloudRuntimeException ex = new CloudRuntimeException("Failed to migrate network as it is in invalid state.");
+            ex.addProxyObject(network.getUuid(), "networkId");
+            throw ex;
+        }
+    }
+
+    private boolean canMoveToPhysicalNetwork(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
+        NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+        NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
+
+        // can move only Isolated networks for now
+        if (oldNetworkOffering.getGuestType() != GuestType.Isolated) {
+            throw new InvalidParameterValueException("NetworkOfferingId can be upgraded only for the network of type " + GuestType.Isolated);
+        }
+
+        // Type of the network should be the same
+        if (oldNetworkOffering.getGuestType() != newNetworkOffering.getGuestType()) {
+            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " are of different types, can't upgrade");
+            return false;
+        }
+
+        // Traffic types should be the same
+        if (oldNetworkOffering.getTrafficType() != newNetworkOffering.getTrafficType()) {
+            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different traffic types, can't upgrade");
+            return false;
+        }
+
+        // specify ipRanges should be the same
+        if (oldNetworkOffering.isSpecifyIpRanges() != newNetworkOffering.isSpecifyIpRanges()) {
+            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyIpRangess, can't upgrade");
+            return false;
+        }
+
+        // Check all ips
+        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
+        List<PublicIp> publicIps = new ArrayList<PublicIp>();
+        if (userIps != null && !userIps.isEmpty()) {
+            for (IPAddressVO userIp : userIps) {
+                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                publicIps.add(publicIp);
+            }
+        }
+        if (oldNetworkOffering.isConserveMode() && !newNetworkOffering.isConserveMode()) {
+            if (!canIpsUsedForNonConserve(publicIps)) {
+                return false;
+            }
+        }
+
+        //can't update from internal LB to public LB
+        if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.Lb) && areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.Lb)) {
+            if (oldNetworkOffering.isPublicLb() != newNetworkOffering.isPublicLb() || oldNetworkOffering.isInternalLb() != newNetworkOffering.isInternalLb()) {
+                throw new InvalidParameterValueException("Original and new offerings support different types of LB - Internal vs Public," + " can't upgrade");
+            }
+        }
+
+        return canIpsUseOffering(publicIps, newNetworkOfferingId);
+    }
+
+    protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
+        NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+        NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
+
+        // security group service should be the same
+        if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.SecurityGroup) != areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.SecurityGroup)) {
+            s_logger.debug("Offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different securityGroupProperty, can't upgrade");
+            return false;
+        }
+
+        // tags should be the same
+        if (newNetworkOffering.getTags() != null) {
+            if (oldNetworkOffering.getTags() == null) {
+                s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade");
+                return false;
+            }
+
+            if (!StringUtils.areTagsEqual(oldNetworkOffering.getTags(), newNetworkOffering.getTags())) {
+                s_logger.debug("Network offerings " + newNetworkOffering.getUuid() + " and " + oldNetworkOffering.getUuid() + " have different tags, can't upgrade");
+                return false;
+            }
+        }
+
+        // specify vlan should be the same
+        if (oldNetworkOffering.isSpecifyVlan() != newNetworkOffering.isSpecifyVlan()) {
+            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyVlan, can't upgrade");
+            return false;
+        }
+
+        return canMoveToPhysicalNetwork(network, oldNetworkOfferingId, newNetworkOfferingId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true)
+    public PhysicalNetwork createPhysicalNetwork(final Long zoneId, final String vnetRange, final String networkSpeed, final List<String> isolationMethods, String broadcastDomainRangeStr,
+            final Long domainId, final List<String> tags, final String name) {
+
+        // Check if zone exists
+        if (zoneId == null) {
+            throw new InvalidParameterValueException("Please specify a valid zone.");
+        }
+
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Please specify a valid zone.");
+        }
+
+        if (Grouping.AllocationState.Enabled == zone.getAllocationState()) {
+            // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject().
+            throw new PermissionDeniedException("Cannot create PhysicalNetwork since the Zone is currently enabled, zone Id: " + zoneId);
+        }
+
+        NetworkType zoneType = zone.getNetworkType();
+
+        if (zoneType == NetworkType.Basic) {
+            if (!_physicalNetworkDao.listByZone(zoneId).isEmpty()) {
+                // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject().
+                throw new CloudRuntimeException("Cannot add the physical network to basic zone id: " + zoneId + ", there is a physical network already existing in this basic Zone");
+            }
+        }
+        if (tags != null && tags.size() > 1) {
+            throw new InvalidParameterException("Only one tag can be specified for a physical network at this time");
+        }
+
+        if (isolationMethods != null && isolationMethods.size() > 1) {
+            throw new InvalidParameterException("Only one isolationMethod can be specified for a physical network at this time");
+        }
+
+        if (vnetRange != null) {
+            // Verify zone type
+            if (zoneType == NetworkType.Basic || (zoneType == NetworkType.Advanced && zone.isSecurityGroupEnabled())) {
+                throw new InvalidParameterValueException(
+                        "Can't add vnet range to the physical network in the zone that supports " + zoneType + " network, Security Group enabled: " + zone.isSecurityGroupEnabled());
+            }
+        }
+
+        BroadcastDomainRange broadcastDomainRange = null;
+        if (broadcastDomainRangeStr != null && !broadcastDomainRangeStr.isEmpty()) {
+            try {
+                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.valueOf(broadcastDomainRangeStr.toUpperCase());
+            } catch (IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve broadcastDomainRange '" + broadcastDomainRangeStr + "' to a supported value {Pod or Zone}");
+            }
+
+            // in Acton release you can specify only Zone broadcastdomain type in Advance zone, and Pod in Basic
+            if (zoneType == NetworkType.Basic && broadcastDomainRange != null && broadcastDomainRange != BroadcastDomainRange.POD) {
+                throw new InvalidParameterValueException("Basic zone can have broadcast domain type of value " + BroadcastDomainRange.POD + " only");
+            } else if (zoneType == NetworkType.Advanced && broadcastDomainRange != null && broadcastDomainRange != BroadcastDomainRange.ZONE) {
+                throw new InvalidParameterValueException("Advance zone can have broadcast domain type of value " + BroadcastDomainRange.ZONE + " only");
+            }
+        }
+
+        if (broadcastDomainRange == null) {
+            if (zoneType == NetworkType.Basic) {
+                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.POD;
+            } else {
+                broadcastDomainRange = PhysicalNetwork.BroadcastDomainRange.ZONE;
+            }
+        }
+
+        try {
+            final BroadcastDomainRange broadcastDomainRangeFinal = broadcastDomainRange;
+            return Transaction.execute(new TransactionCallback<PhysicalNetworkVO>() {
+                @Override
+                public PhysicalNetworkVO doInTransaction(TransactionStatus status) {
+                    // Create the new physical network in the database
+                    long id = _physicalNetworkDao.getNextInSequence(Long.class, "id");
+                    PhysicalNetworkVO pNetwork = new PhysicalNetworkVO(id, zoneId, vnetRange, networkSpeed, domainId, broadcastDomainRangeFinal, name);
+                    pNetwork.setTags(tags);
+                    pNetwork.setIsolationMethods(isolationMethods);
+
+                    pNetwork = _physicalNetworkDao.persist(pNetwork);
+
+                    // Add vnet entries for the new zone if zone type is Advanced
+                    if (vnetRange != null) {
+                        addOrRemoveVnets(vnetRange.split(","), pNetwork);
+                    }
+
+                    // add VirtualRouter as the default network service provider
+                    addDefaultVirtualRouterToPhysicalNetwork(pNetwork.getId());
+
+                    if (pNetwork.getIsolationMethods().contains("GRE")) {
+                        addDefaultOvsToPhysicalNetwork(pNetwork.getId());
+                    }
+
+                    // add security group provider to the physical network
+                    addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId());
+
+                    // add VPCVirtualRouter as the defualt network service provider
+                    addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId());
+
+                    // add baremetal as the defualt network service provider
+                    addDefaultBaremetalProvidersToPhysicalNetwork(pNetwork.getId());
+
+                    //Add Internal Load Balancer element as a default network service provider
+                    addDefaultInternalLbProviderToPhysicalNetwork(pNetwork.getId());
+
+                    // Add the config drive provider
+                    addConfigDriveToPhysicalNetwork(pNetwork.getId());
+
+                    return pNetwork;
+                }
+            });
+        } catch (Exception ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new CloudRuntimeException("Fail to create a physical network");
+        }
+    }
+
+    @Override
+    public Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) {
+        Filter searchFilter = new Filter(PhysicalNetworkVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+        SearchCriteria<PhysicalNetworkVO> sc = _physicalNetworkDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (zoneId != null) {
+            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
+        }
+
+        Pair<List<PhysicalNetworkVO>, Integer> result = _physicalNetworkDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends PhysicalNetwork>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_UPDATE, eventDescription = "updating physical network", async = true)
+    public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRange, String state) {
+
+        // verify input parameters
+        PhysicalNetworkVO network = _physicalNetworkDao.findById(id);
+        if (network == null) {
+            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", id.toString(), "physicalNetworkId");
+        }
+
+        // if zone is of Basic type, don't allow to add vnet range
+        DataCenter zone = _dcDao.findById(network.getDataCenterId());
+        if (zone == null) {
+            throwInvalidIdException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system", String.valueOf(network.getDataCenterId()), "dataCenterId");
+        }
+        if (newVnetRange != null) {
+            if (zone.getNetworkType() == NetworkType.Basic || (zone.getNetworkType() == NetworkType.Advanced && zone.isSecurityGroupEnabled())) {
+                throw new InvalidParameterValueException(
+                        "Can't add vnet range to the physical network in the zone that supports " + zone.getNetworkType() + " network, Security Group enabled: " + zone.isSecurityGroupEnabled());
+            }
+        }
+
+        if (tags != null && tags.size() > 1) {
+            throw new InvalidParameterException("Unable to support more than one tag on network yet");
+        }
+
+        PhysicalNetwork.State networkState = null;
+        if (state != null && !state.isEmpty()) {
+            try {
+                networkState = PhysicalNetwork.State.valueOf(state);
+            } catch (IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve state '" + state + "' to a supported value {Enabled or Disabled}");
+            }
+        }
+
+        if (state != null) {
+            network.setState(networkState);
+        }
+
+        if (tags != null) {
+            network.setTags(tags);
+        }
+
+        if (networkSpeed != null) {
+            network.setSpeed(networkSpeed);
+        }
+
+        if (newVnetRange != null) {
+            String[] listOfRanges = newVnetRange.split(",");
+            addOrRemoveVnets(listOfRanges, network);
+        }
+        _physicalNetworkDao.update(id, network);
+        return network;
+
+    }
+
+    @DB
+    public void addOrRemoveVnets(String[] listOfRanges, final PhysicalNetworkVO network) {
+        List<String> addVnets = null;
+        List<String> removeVnets = null;
+        HashSet<String> tempVnets = new HashSet<String>();
+        HashSet<String> vnetsInDb = new HashSet<String>();
+        List<Pair<Integer, Integer>> vnetranges = null;
+        String comaSeperatedStingOfVnetRanges = null;
+        int i = 0;
+        if (listOfRanges.length != 0) {
+            _physicalNetworkDao.acquireInLockTable(network.getId(), 10);
+            vnetranges = validateVlanRange(network, listOfRanges);
+
+            //computing vnets to be removed.
+            removeVnets = getVnetsToremove(network, vnetranges);
+
+            //computing vnets to add
+            vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
+            tempVnets.addAll(vnetsInDb);
+            for (Pair<Integer, Integer> vlan : vnetranges) {
+                for (i = vlan.first(); i <= vlan.second(); i++) {
+                    tempVnets.add(Integer.toString(i));
+                }
+            }
+            tempVnets.removeAll(vnetsInDb);
+
+            //vnets to add in tempVnets.
+            //adding and removing vnets from vnetsInDb
+            if (removeVnets != null && removeVnets.size() != 0) {
+                vnetsInDb.removeAll(removeVnets);
+            }
+
+            if (tempVnets.size() != 0) {
+                addVnets = new ArrayList<String>();
+                addVnets.addAll(tempVnets);
+                vnetsInDb.addAll(tempVnets);
+            }
+
+            //sorting the vnets in Db to generate a coma seperated list of  the vnet string.
+            if (vnetsInDb.size() != 0) {
+                comaSeperatedStingOfVnetRanges = generateVnetString(new ArrayList<String>(vnetsInDb));
+            }
+            network.setVnet(comaSeperatedStingOfVnetRanges);
+
+            final List<String> addVnetsFinal = addVnets;
+            final List<String> removeVnetsFinal = removeVnets;
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    if (addVnetsFinal != null) {
+                        s_logger.debug("Adding vnet range " + addVnetsFinal.toString() + " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId()
+                        + " as a part of updatePhysicalNetwork call");
+                        //add vnet takes a list of strings to be added. each string is a vnet.
+                        _dcDao.addVnet(network.getDataCenterId(), network.getId(), addVnetsFinal);
+                    }
+                    if (removeVnetsFinal != null) {
+                        s_logger.debug("removing vnet range " + removeVnetsFinal.toString() + " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId()
+                        + " as a part of updatePhysicalNetwork call");
+                        //deleteVnets  takes a list of strings to be removed. each string is a vnet.
+                        _datacneterVnet.deleteVnets(TransactionLegacy.currentTxn(), network.getDataCenterId(), network.getId(), removeVnetsFinal);
+                    }
+                    _physicalNetworkDao.update(network.getId(), network);
+                }
+            });
+
+            _physicalNetworkDao.releaseFromLockTable(network.getId());
+        }
+    }
+
+    private List<Pair<Integer, Integer>> validateVlanRange(PhysicalNetworkVO network, String[] listOfRanges) {
+        Integer StartVnet;
+        Integer EndVnet;
+        List<Pair<Integer, Integer>> vlanTokens = new ArrayList<Pair<Integer, Integer>>();
+        for (String vlanRange : listOfRanges) {
+            String[] VnetRange = vlanRange.split("-");
+
+            // Init with [min,max] of VLAN. Actually 0x000 and 0xFFF are reserved by IEEE, shoudn't be used.
+            long minVnet = MIN_VLAN_ID;
+            long maxVnet = MAX_VLAN_ID;
+
+            // for GRE phynets allow up to 32bits
+            // TODO: Not happy about this test.
+            // What about guru-like objects for physical networs?
+            s_logger.debug("ISOLATION METHODS:" + network.getIsolationMethods());
+            // Java does not have unsigned types...
+            if (network.getIsolationMethods().contains("GRE")) {
+                minVnet = MIN_GRE_KEY;
+                maxVnet = MAX_GRE_KEY;
+            } else if (network.getIsolationMethods().contains("VXLAN")) {
+                minVnet = MIN_VXLAN_VNI;
+                maxVnet = MAX_VXLAN_VNI;
+                // fail if zone already contains VNI, need to be unique per zone.
+                // since adding a range adds each VNI to the database, need only check min/max
+                for (String vnet : VnetRange) {
+                    s_logger.debug("Looking to see if VNI " + vnet + " already exists on another network in zone " + network.getDataCenterId());
+                    List<DataCenterVnetVO> vnis = _datacneterVnet.findVnet(network.getDataCenterId(), vnet);
+                    if (vnis != null && !vnis.isEmpty()) {
+                        for (DataCenterVnetVO vni : vnis) {
+                            if (vni.getPhysicalNetworkId() != network.getId()) {
+                                s_logger.debug("VNI " + vnet + " already exists on another network in zone, please specify a unique range");
+                                throw new InvalidParameterValueException("VNI " + vnet + " already exists on another network in zone, please specify a unique range");
+                            }
+                        }
+                    }
+                }
+            }
+            String rangeMessage = " between " + minVnet + " and " + maxVnet;
+            if (VnetRange.length == 1 && VnetRange[0].equals("")) {
+                return vlanTokens;
+            }
+            if (VnetRange.length < 2) {
+                throw new InvalidParameterValueException("Please provide valid vnet range. vnet range should be a coma seperated list of vlan ranges. example 500-500,600-601" + rangeMessage);
+            }
+
+            if (VnetRange[0] == null || VnetRange[1] == null) {
+                throw new InvalidParameterValueException("Please provide valid vnet range" + rangeMessage);
+            }
+
+            try {
+                StartVnet = Integer.parseInt(VnetRange[0]);
+                EndVnet = Integer.parseInt(VnetRange[1]);
+            } catch (NumberFormatException e) {
+                s_logger.warn("Unable to parse vnet range:", e);
+                throw new InvalidParameterValueException("Please provide valid vnet range. The vnet range should be a coma seperated list example 2001-2012,3000-3005." + rangeMessage);
+            }
+            if (StartVnet < minVnet || EndVnet > maxVnet) {
+                throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage);
+            }
+
+            if (StartVnet > EndVnet) {
+                throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage + " and start range should be lesser than or equal to stop range");
+            }
+            vlanTokens.add(new Pair<Integer, Integer>(StartVnet, EndVnet));
+        }
+        return vlanTokens;
+
+    }
+
+    public String generateVnetString(List<String> vnetList) {
+        Collections.sort(vnetList, new Comparator<String>() {
+            @Override
+            public int compare(String s1, String s2) {
+                return Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
+            }
+        });
+        int i;
+        //build the vlan string form the sorted list.
+        String vnetRange = "";
+        String startvnet = vnetList.get(0);
+        String endvnet = "";
+        for (i = 0; i < vnetList.size() - 1; i++) {
+            if (Integer.parseInt(vnetList.get(i + 1)) - Integer.parseInt(vnetList.get(i)) > 1) {
+                endvnet = vnetList.get(i);
+                vnetRange = vnetRange + startvnet + "-" + endvnet + ",";
+                startvnet = vnetList.get(i + 1);
+            }
+        }
+        endvnet = vnetList.get(vnetList.size() - 1);
+        vnetRange = vnetRange + startvnet + "-" + endvnet + ",";
+        vnetRange = vnetRange.substring(0, vnetRange.length() - 1);
+        return vnetRange;
+    }
+
+    private List<String> getVnetsToremove(PhysicalNetworkVO network, List<Pair<Integer, Integer>> vnetRanges) {
+        int i;
+        List<String> removeVnets = new ArrayList<String>();
+        HashSet<String> vnetsInDb = new HashSet<String>();
+        vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
+        //remove all the vnets from vnets in db to check if there are any vnets that are not there in given list.
+        //remove all the vnets not in the list of vnets passed by the user.
+        if (vnetRanges.size() == 0) {
+            //this implies remove all vlans.
+            removeVnets.addAll(vnetsInDb);
+            int allocated_vnets = _datacneterVnet.countAllocatedVnets(network.getId());
+            if (allocated_vnets > 0) {
+                throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has " + allocated_vnets + " vnets in use");
+            }
+            return removeVnets;
+        }
+        for (Pair<Integer, Integer> vlan : vnetRanges) {
+            for (i = vlan.first(); i <= vlan.second(); i++) {
+                vnetsInDb.remove(Integer.toString(i));
+            }
+        }
+        String vnetRange = null;
+        if (vnetsInDb.size() != 0) {
+            removeVnets.addAll(vnetsInDb);
+            vnetRange = generateVnetString(removeVnets);
+        } else {
+            return removeVnets;
+        }
+
+        for (String vnet : vnetRange.split(",")) {
+            String[] range = vnet.split("-");
+            Integer start = Integer.parseInt(range[0]);
+            Integer end = Integer.parseInt(range[1]);
+            _datacneterVnet.lockRange(network.getDataCenterId(), network.getId(), start, end);
+            List<DataCenterVnetVO> result = _datacneterVnet.listAllocatedVnetsInRange(network.getDataCenterId(), network.getId(), start, end);
+            if (!result.isEmpty()) {
+                throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has allocated vnets in the range " + start + "-" + end);
+
+            }
+            // If the range is partially dedicated to an account fail the request
+            List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(network.getId());
+            for (AccountGuestVlanMapVO map : maps) {
+                String[] vlans = map.getGuestVlanRange().split("-");
+                Integer dedicatedStartVlan = Integer.parseInt(vlans[0]);
+                Integer dedicatedEndVlan = Integer.parseInt(vlans[1]);
+                if ((start >= dedicatedStartVlan && start <= dedicatedEndVlan) || (end >= dedicatedStartVlan && end <= dedicatedEndVlan)) {
+                    throw new InvalidParameterValueException("Vnet range " + map.getGuestVlanRange() + " is dedicated" + " to an account. The specified range " + start + "-" + end
+                            + " overlaps with the dedicated range " + " Please release the overlapping dedicated range before deleting the range");
+                }
+            }
+        }
+        return removeVnets;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_DELETE, eventDescription = "deleting physical network", async = true)
+    @DB
+    public boolean deletePhysicalNetwork(final Long physicalNetworkId) {
+
+        // verify input parameters
+        PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
+        }
+
+        checkIfPhysicalNetworkIsDeletable(physicalNetworkId);
+
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                // delete vlans for this zone
+                List<VlanVO> vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId);
+                for (VlanVO vlan : vlans) {
+                    _vlanDao.remove(vlan.getId());
+                }
+
+                // Delete networks
+                List<NetworkVO> networks = _networksDao.listByPhysicalNetwork(physicalNetworkId);
+                if (networks != null && !networks.isEmpty()) {
+                    for (NetworkVO network : networks) {
+                        _networksDao.remove(network.getId());
+                    }
+                }
+
+                // delete vnets
+                _dcDao.deleteVnet(physicalNetworkId);
+
+                // delete service providers
+                List<PhysicalNetworkServiceProviderVO> providers = _pNSPDao.listBy(physicalNetworkId);
+
+                for (PhysicalNetworkServiceProviderVO provider : providers) {
+                    try {
+                        deleteNetworkServiceProvider(provider.getId());
+                    } catch (ResourceUnavailableException e) {
+                        s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: " + provider.getId(), e);
+                        return false;
+                    } catch (ConcurrentOperationException e) {
+                        s_logger.warn("Unable to complete destroy of the physical network provider: " + provider.getProviderName() + ", id: " + provider.getId(), e);
+                        return false;
+                    }
+                }
+
+                // delete traffic types
+                _pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId);
+
+                return _physicalNetworkDao.remove(physicalNetworkId);
+            }
+        });
+    }
+
+    @DB
+    protected void checkIfPhysicalNetworkIsDeletable(Long physicalNetworkId) {
+        List<List<String>> tablesToCheck = new ArrayList<List<String>>();
+
+        List<String> vnet = new ArrayList<String>();
+        vnet.add(0, "op_dc_vnet_alloc");
+        vnet.add(1, "physical_network_id");
+        vnet.add(2, "there are allocated vnets for this physical network");
+        tablesToCheck.add(vnet);
+
+        List<String> networks = new ArrayList<String>();
+        networks.add(0, "networks");
+        networks.add(1, "physical_network_id");
+        networks.add(2, "there are networks associated to this physical network");
+        tablesToCheck.add(networks);
+
+        /*
+         * List<String> privateIP = new ArrayList<String>();
+         * privateIP.add(0, "op_dc_ip_address_alloc");
+         * privateIP.add(1, "data_center_id");
+         * privateIP.add(2, "there are private IP addresses allocated for this zone");
+         * tablesToCheck.add(privateIP);
+         */
+
+        List<String> publicIP = new ArrayList<String>();
+        publicIP.add(0, "user_ip_address");
+        publicIP.add(1, "physical_network_id");
+        publicIP.add(2, "there are public IP addresses allocated for this physical network");
+        tablesToCheck.add(publicIP);
+
+        for (List<String> table : tablesToCheck) {
+            String tableName = table.get(0);
+            String column = table.get(1);
+            String errorMsg = table.get(2);
+
+            String dbName = "cloud";
+
+            String selectSql = "SELECT * FROM `" + dbName + "`.`" + tableName + "` WHERE " + column + " = ?";
+
+            if (tableName.equals("networks")) {
+                selectSql += " AND removed is NULL";
+            }
+
+            if (tableName.equals("op_dc_vnet_alloc")) {
+                selectSql += " AND taken IS NOT NULL";
+            }
+
+            if (tableName.equals("user_ip_address")) {
+                selectSql += " AND state!='Free'";
+            }
+
+            if (tableName.equals("op_dc_ip_address_alloc")) {
+                selectSql += " AND taken IS NOT NULL";
+            }
+
+            TransactionLegacy txn = TransactionLegacy.currentTxn();
+            try {
+                PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
+                stmt.setLong(1, physicalNetworkId);
+                ResultSet rs = stmt.executeQuery();
+                if (rs != null && rs.next()) {
+                    throw new CloudRuntimeException("The Physical Network is not deletable because " + errorMsg);
+                }
+            } catch (SQLException ex) {
+                throw new CloudRuntimeException("The Management Server failed to detect if physical network is deletable. Please contact Cloud Support.");
+            }
+        }
+
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_VLAN_RANGE_DEDICATE, eventDescription = "dedicating guest vlan range", async = false)
+    public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
+        String vlan = cmd.getVlan();
+        String accountName = cmd.getAccountName();
+        Long domainId = cmd.getDomainId();
+        Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        Long projectId = cmd.getProjectId();
+
+        int startVlan, endVlan;
+        String updatedVlanRange = null;
+        long guestVlanMapId = 0;
+        long guestVlanMapAccountId = 0;
+        long vlanOwnerId = 0;
+
+        // Verify account is valid
+        Account vlanOwner = null;
+        if (projectId != null) {
+            if (accountName != null) {
+                throw new InvalidParameterValueException("accountName and projectId are mutually exclusive");
+            }
+            Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+            }
+            vlanOwner = _accountMgr.getAccount(project.getProjectAccountId());
+        }
+
+        if ((accountName != null) && (domainId != null)) {
+            vlanOwner = _accountDao.findActiveAccount(accountName, domainId);
+        }
+        if (vlanOwner == null) {
+            throw new InvalidParameterValueException("Unable to find account by name " + accountName);
+        }
+        vlanOwnerId = vlanOwner.getAccountId();
+
+        // Verify physical network isolation type is VLAN
+        PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (physicalNetwork == null) {
+            throw new InvalidParameterValueException("Unable to find physical network by id " + physicalNetworkId);
+        } else if (!physicalNetwork.getIsolationMethods().isEmpty() && !physicalNetwork.getIsolationMethods().contains("VLAN")) {
+            throw new InvalidParameterValueException("Cannot dedicate guest vlan range. " + "Physical isolation type of network " + physicalNetworkId + " is not VLAN");
+        }
+
+        // Get the start and end vlan
+        String[] vlanRange = vlan.split("-");
+        if (vlanRange.length != 2) {
+            throw new InvalidParameterValueException("Invalid format for parameter value vlan " + vlan + " .Vlan should be specified as 'startvlan-endvlan'");
+        }
+
+        try {
+            startVlan = Integer.parseInt(vlanRange[0]);
+            endVlan = Integer.parseInt(vlanRange[1]);
+        } catch (NumberFormatException e) {
+            s_logger.warn("Unable to parse guest vlan range:", e);
+            throw new InvalidParameterValueException("Please provide valid guest vlan range");
+        }
+
+        // Verify guest vlan range exists in the system
+        List<Pair<Integer, Integer>> existingRanges = physicalNetwork.getVnet();
+        Boolean exists = false;
+        if (!existingRanges.isEmpty()) {
+            for (int i = 0; i < existingRanges.size(); i++) {
+                int existingStartVlan = existingRanges.get(i).first();
+                int existingEndVlan = existingRanges.get(i).second();
+                if (startVlan <= endVlan && startVlan >= existingStartVlan && endVlan <= existingEndVlan) {
+                    exists = true;
+                    break;
+                }
+            }
+            if (!exists) {
+                throw new InvalidParameterValueException("Unable to find guest vlan by range " + vlan);
+            }
+        }
+
+        // Verify guest vlans in the range don't belong to a network of a different account
+        for (int i = startVlan; i <= endVlan; i++) {
+            List<DataCenterVnetVO> allocatedVlans = _datacneterVnet.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
+            if (allocatedVlans != null && !allocatedVlans.isEmpty()) {
+                for (DataCenterVnetVO allocatedVlan : allocatedVlans) {
+                    if (allocatedVlan.getAccountId() != vlanOwner.getAccountId()) {
+                        throw new InvalidParameterValueException("Guest vlan from this range " + allocatedVlan.getVnet() + " is allocated to a different account."
+                                + " Can only dedicate a range which has no allocated vlans or has vlans allocated to the same account ");
+                    }
+                }
+            }
+        }
+
+        List<AccountGuestVlanMapVO> guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId);
+        // Verify if vlan range is already dedicated
+        for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) {
+            List<Integer> vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange());
+            int dedicatedStartVlan = vlanTokens.get(0).intValue();
+            int dedicatedEndVlan = vlanTokens.get(1).intValue();
+            if ((startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan) || (startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan)) {
+                throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + " dedicate guest vlan range " + vlan);
+            }
+        }
+
+        // Sort the existing dedicated vlan ranges
+        Collections.sort(guestVlanMaps, new Comparator<AccountGuestVlanMapVO>() {
+            @Override
+            public int compare(AccountGuestVlanMapVO obj1, AccountGuestVlanMapVO obj2) {
+                List<Integer> vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange());
+                List<Integer> vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange());
+                return vlanTokens1.get(0).compareTo(vlanTokens2.get(0));
+            }
+        });
+
+        // Verify if vlan range extends an already dedicated range
+        for (int i = 0; i < guestVlanMaps.size(); i++) {
+            guestVlanMapId = guestVlanMaps.get(i).getId();
+            guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId();
+            List<Integer> vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange());
+            // Range extends a dedicated vlan range to the left
+            if (endVlan == (vlanTokens1.get(0).intValue() - 1)) {
+                if (guestVlanMapAccountId == vlanOwnerId) {
+                    updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue();
+                }
+                break;
+            }
+            // Range extends a dedicated vlan range to the right
+            if (startVlan == (vlanTokens1.get(1).intValue() + 1) & guestVlanMapAccountId == vlanOwnerId) {
+                if (i != (guestVlanMaps.size() - 1)) {
+                    List<Integer> vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i + 1).getGuestVlanRange());
+                    // Range extends 2 vlan ranges, both to the right and left
+                    if (endVlan == (vlanTokens2.get(0).intValue() - 1) && guestVlanMaps.get(i + 1).getAccountId() == vlanOwnerId) {
+                        _datacneterVnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i + 1).getId());
+                        _accountGuestVlanMapDao.remove(guestVlanMaps.get(i + 1).getId());
+                        updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue();
+                        break;
+                    }
+                }
+                updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan;
+                break;
+            }
+        }
+        // Dedicate vlan range
+        AccountGuestVlanMapVO accountGuestVlanMapVO;
+        if (updatedVlanRange != null) {
+            accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId);
+            accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange);
+            _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO);
+        } else {
+            accountGuestVlanMapVO = new AccountGuestVlanMapVO(vlanOwner.getAccountId(), physicalNetworkId);
+            accountGuestVlanMapVO.setGuestVlanRange(startVlan + "-" + endVlan);
+            _accountGuestVlanMapDao.persist(accountGuestVlanMapVO);
+        }
+        // For every guest vlan set the corresponding account guest vlan map id
+        List<Integer> finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange());
+        for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) {
+            List<DataCenterVnetVO> dataCenterVnet = _datacneterVnet.findVnet(physicalNetwork.getDataCenterId(), physicalNetworkId, Integer.toString(i));
+            dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId());
+            _datacneterVnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
+        }
+        return accountGuestVlanMapVO;
+    }
+
+    private List<Integer> getVlanFromRange(String vlanRange) {
+        // Get the start and end vlan
+        String[] vlanTokens = vlanRange.split("-");
+        List<Integer> tokens = new ArrayList<Integer>();
+        try {
+            int startVlan = Integer.parseInt(vlanTokens[0]);
+            int endVlan = Integer.parseInt(vlanTokens[1]);
+            tokens.add(startVlan);
+            tokens.add(endVlan);
+        } catch (NumberFormatException e) {
+            s_logger.warn("Unable to parse guest vlan range:", e);
+            throw new InvalidParameterValueException("Please provide valid guest vlan range");
+        }
+        return tokens;
+    }
+
+    @Override
+    public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
+        Long id = cmd.getId();
+        String accountName = cmd.getAccountName();
+        Long domainId = cmd.getDomainId();
+        Long projectId = cmd.getProjectId();
+        String guestVlanRange = cmd.getGuestVlanRange();
+        Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        Long zoneId = cmd.getZoneId();
+
+        Long accountId = null;
+        if (accountName != null && domainId != null) {
+            if (projectId != null) {
+                throw new InvalidParameterValueException("Account and projectId can't be specified together");
+            }
+            Account account = _accountDao.findActiveAccount(accountName, domainId);
+            if (account == null) {
+                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName);
+                DomainVO domain = ApiDBUtils.findDomainById(domainId);
+                String domainUuid = domainId.toString();
+                if (domain != null) {
+                    domainUuid = domain.getUuid();
+                }
+                ex.addProxyObject(domainUuid, "domainId");
+                throw ex;
+            } else {
+                accountId = account.getId();
+            }
+        }
+
+        // set project information
+        if (projectId != null) {
+            Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                throwInvalidIdException("Unable to find project by id " + projectId, projectId.toString(), "projectId");
+            }
+            accountId = project.getProjectAccountId();
+        }
+
+        SearchBuilder<AccountGuestVlanMapVO> sb = _accountGuestVlanMapDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+        sb.and("guestVlanRange", sb.entity().getGuestVlanRange(), SearchCriteria.Op.EQ);
+        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
+
+        if (zoneId != null) {
+            SearchBuilder<PhysicalNetworkVO> physicalnetworkSearch = _physicalNetworkDao.createSearchBuilder();
+            physicalnetworkSearch.and("zoneId", physicalnetworkSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+            sb.join("physicalnetworkSearch", physicalnetworkSearch, sb.entity().getPhysicalNetworkId(), physicalnetworkSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<AccountGuestVlanMapVO> sc = sb.create();
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (accountId != null) {
+            sc.setParameters("accountId", accountId);
+        }
+
+        if (guestVlanRange != null) {
+            sc.setParameters("guestVlanRange", guestVlanRange);
+        }
+
+        if (physicalNetworkId != null) {
+            sc.setParameters("physicalNetworkId", physicalNetworkId);
+        }
+
+        if (zoneId != null) {
+            sc.setJoinParameters("physicalnetworkSearch", "zoneId", zoneId);
+        }
+
+        Filter searchFilter = new Filter(AccountGuestVlanMapVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        Pair<List<AccountGuestVlanMapVO>, Integer> result = _accountGuestVlanMapDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends GuestVlan>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_DEDICATED_GUEST_VLAN_RANGE_RELEASE, eventDescription = "releasing" + " dedicated guest vlan range", async = true)
+    @DB
+    public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
+        // Verify dedicated range exists
+        AccountGuestVlanMapVO dedicatedGuestVlan = _accountGuestVlanMapDao.findById(dedicatedGuestVlanRangeId);
+        if (dedicatedGuestVlan == null) {
+            throw new InvalidParameterValueException("Dedicated guest vlan with specified" + " id doesn't exist in the system");
+        }
+
+        // Remove dedication for the guest vlan
+        _datacneterVnet.releaseDedicatedGuestVlans(dedicatedGuestVlan.getId());
+        if (_accountGuestVlanMapDao.remove(dedicatedGuestVlanRangeId)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public List<? extends Service> listNetworkServices(String providerName) {
+
+        Provider provider = null;
+        if (providerName != null) {
+            provider = Network.Provider.getProvider(providerName);
+            if (provider == null) {
+                throw new InvalidParameterValueException("Invalid Network Service Provider=" + providerName);
+            }
+        }
+
+        if (provider != null) {
+            NetworkElement element = _networkModel.getElementImplementingProvider(providerName);
+            if (element == null) {
+                throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + providerName + "'");
+            }
+            return new ArrayList<Service>(element.getCapabilities().keySet());
+        } else {
+            return Service.listAllServices();
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_CREATE, eventDescription = "Creating Physical Network ServiceProvider", create = true)
+    public PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId, List<String> enabledServices) {
+
+        // verify input parameters
+        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
+        if (network == null) {
+            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
+        }
+
+        // verify input parameters
+        if (destinationPhysicalNetworkId != null) {
+            PhysicalNetworkVO destNetwork = _physicalNetworkDao.findById(destinationPhysicalNetworkId);
+            if (destNetwork == null) {
+                throwInvalidIdException("Destination Physical Network with specified id doesn't exist in the system", destinationPhysicalNetworkId.toString(), "destinationPhysicalNetworkId");
+            }
+        }
+
+        if (providerName != null) {
+            Provider provider = Network.Provider.getProvider(providerName);
+            if (provider == null) {
+                throw new InvalidParameterValueException("Invalid Network Service Provider=" + providerName);
+            }
+        }
+
+        if (_pNSPDao.findByServiceProvider(physicalNetworkId, providerName) != null) {
+            // TBD: send uuid instead of physicalNetworkId.
+            throw new CloudRuntimeException("The '" + providerName + "' provider already exists on physical network : " + physicalNetworkId);
+        }
+
+        // check if services can be turned off
+        NetworkElement element = _networkModel.getElementImplementingProvider(providerName);
+        if (element == null) {
+            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + providerName + "'");
+        }
+        List<Service> services = new ArrayList<Service>();
+
+        if (enabledServices != null) {
+            if (!element.canEnableIndividualServices()) {
+                if (enabledServices.size() != element.getCapabilities().keySet().size()) {
+                    throw new InvalidParameterValueException("Cannot enable subset of Services, Please specify the complete list of Services for this Service Provider '" + providerName + "'");
+                }
+            }
+
+            // validate Services
+            boolean addGatewayService = false;
+            for (String serviceName : enabledServices) {
+                Network.Service service = Network.Service.getService(serviceName);
+                if (service == null || service == Service.Gateway) {
+                    throw new InvalidParameterValueException("Invalid Network Service specified=" + serviceName);
+                } else if (service == Service.SourceNat) {
+                    addGatewayService = true;
+                }
+
+                // check if the service is provided by this Provider
+                if (!element.getCapabilities().containsKey(service)) {
+                    throw new InvalidParameterValueException(providerName + " Provider cannot provide this Service specified=" + serviceName);
+                }
+                services.add(service);
+            }
+
+            if (addGatewayService) {
+                services.add(Service.Gateway);
+            }
+        } else {
+            // enable all the default services supported by this element.
+            services = new ArrayList<Service>(element.getCapabilities().keySet());
+        }
+
+        try {
+            // Create the new physical network in the database
+            PhysicalNetworkServiceProviderVO nsp = new PhysicalNetworkServiceProviderVO(physicalNetworkId, providerName);
+            // set enabled services
+            nsp.setEnabledServices(services);
+
+            if (destinationPhysicalNetworkId != null) {
+                nsp.setDestinationPhysicalNetworkId(destinationPhysicalNetworkId);
+            }
+            nsp = _pNSPDao.persist(nsp);
+
+            return nsp;
+        } catch (Exception ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new CloudRuntimeException("Fail to add a provider to physical network");
+        }
+
+    }
+
+    @Override
+    public Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) {
+
+        Filter searchFilter = new Filter(PhysicalNetworkServiceProviderVO.class, "id", false, startIndex, pageSize);
+        SearchBuilder<PhysicalNetworkServiceProviderVO> sb = _pNSPDao.createSearchBuilder();
+        SearchCriteria<PhysicalNetworkServiceProviderVO> sc = sb.create();
+
+        if (physicalNetworkId != null) {
+            sc.addAnd("physicalNetworkId", Op.EQ, physicalNetworkId);
+        }
+
+        if (name != null) {
+            sc.addAnd("providerName", Op.EQ, name);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", Op.EQ, state);
+        }
+
+        Pair<List<PhysicalNetworkServiceProviderVO>, Integer> result = _pNSPDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends PhysicalNetworkServiceProvider>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_UPDATE, eventDescription = "Updating physical network ServiceProvider", async = true)
+    public PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String stateStr, List<String> enabledServices) {
+
+        PhysicalNetworkServiceProviderVO provider = _pNSPDao.findById(id);
+        if (provider == null) {
+            throw new InvalidParameterValueException("Network Service Provider id=" + id + "doesn't exist in the system");
+        }
+
+        NetworkElement element = _networkModel.getElementImplementingProvider(provider.getProviderName());
+        if (element == null) {
+            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getProviderName() + "'");
+        }
+
+        PhysicalNetworkServiceProvider.State state = null;
+        if (stateStr != null && !stateStr.isEmpty()) {
+            try {
+                state = PhysicalNetworkServiceProvider.State.valueOf(stateStr);
+            } catch (IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve state '" + stateStr + "' to a supported value {Enabled or Disabled}");
+            }
+        }
+
+        boolean update = false;
+
+        if (state != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("trying to update the state of the service provider id=" + id + " on physical network: " + provider.getPhysicalNetworkId() + " to state: " + stateStr);
+            }
+            switch (state) {
+            case Enabled:
+                if (element != null && element.isReady(provider)) {
+                    provider.setState(PhysicalNetworkServiceProvider.State.Enabled);
+                    update = true;
+                } else {
+                    throw new CloudRuntimeException("Provider is not ready, cannot Enable the provider, please configure the provider first");
+                }
+                break;
+            case Disabled:
+                // do we need to do anything for the provider instances before disabling?
+                provider.setState(PhysicalNetworkServiceProvider.State.Disabled);
+                update = true;
+                break;
+            case Shutdown:
+                throw new InvalidParameterValueException("Updating the provider state to 'Shutdown' is not supported");
+            }
+        }
+
+        if (enabledServices != null) {
+            // check if services can be turned of
+            if (!element.canEnableIndividualServices()) {
+                throw new InvalidParameterValueException("Cannot update set of Services for this Service Provider '" + provider.getProviderName() + "'");
+            }
+
+            // validate Services
+            List<Service> services = new ArrayList<Service>();
+            for (String serviceName : enabledServices) {
+                Network.Service service = Network.Service.getService(serviceName);
+                if (service == null) {
+                    throw new InvalidParameterValueException("Invalid Network Service specified=" + serviceName);
+                }
+                services.add(service);
+            }
+            // set enabled services
+            provider.setEnabledServices(services);
+            update = true;
+        }
+
+        if (update) {
+            _pNSPDao.update(id, provider);
+        }
+        return provider;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_DELETE, eventDescription = "Deleting physical network ServiceProvider", async = true)
+    public boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException {
+        PhysicalNetworkServiceProviderVO provider = _pNSPDao.findById(id);
+
+        if (provider == null) {
+            throw new InvalidParameterValueException("Network Service Provider id=" + id + "doesn't exist in the system");
+        }
+
+        // check if there are networks using this provider
+        List<NetworkVO> networks = _networksDao.listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), provider.getProviderName());
+        if (networks != null && !networks.isEmpty()) {
+            throw new CloudRuntimeException("Provider is not deletable because there are active networks using this provider, please upgrade these networks to new network offerings");
+        }
+
+        User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+        Account callerAccount = _accountMgr.getActiveAccountById(callerUser.getAccountId());
+        // shutdown the provider instances
+        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Shutting down the service provider id=" + id + " on physical network: " + provider.getPhysicalNetworkId());
+        }
+        NetworkElement element = _networkModel.getElementImplementingProvider(provider.getProviderName());
+        if (element == null) {
+            throw new InvalidParameterValueException("Unable to find the Network Element implementing the Service Provider '" + provider.getProviderName() + "'");
+        }
+
+        if (element != null && element.shutdownProviderInstances(provider, context)) {
+            provider.setState(PhysicalNetworkServiceProvider.State.Shutdown);
+        }
+
+        return _pNSPDao.remove(id);
+    }
+
+    @Override
+    public PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId) {
+        return _physicalNetworkDao.findById(physicalNetworkId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", async = true)
+    public PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId) {
+        return getPhysicalNetwork(physicalNetworkId);
+    }
+
+    @Override
+    public PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId) {
+        return _pNSPDao.findById(providerId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SERVICE_PROVIDER_CREATE, eventDescription = "Creating Physical Network ServiceProvider", async = true)
+    public PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId) {
+        return getPhysicalNetworkServiceProvider(providerId);
+    }
+
+    @Override
+    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
+        List<PhysicalNetworkVO> pNtwks = new ArrayList<PhysicalNetworkVO>();
+        if (trafficType != null) {
+            pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType);
+        } else {
+            pNtwks = _physicalNetworkDao.listByZone(zoneId);
+        }
+
+        if (pNtwks.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find physical network in zone id=" + zoneId);
+        }
+
+        if (pNtwks.size() > 1) {
+            if (tag == null) {
+                throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " and no tags are specified in order to make a choice");
+            }
+
+            Long pNtwkId = null;
+            for (PhysicalNetwork pNtwk : pNtwks) {
+                if (pNtwk.getTags().contains(tag)) {
+                    s_logger.debug("Found physical network id=" + pNtwk.getId() + " based on requested tags " + tag);
+                    pNtwkId = pNtwk.getId();
+                    break;
+                }
+            }
+            if (pNtwkId == null) {
+                throw new InvalidParameterValueException("Unable to find physical network which match the tags " + tag);
+            }
+            return pNtwkId;
+        } else {
+            return pNtwks.get(0).getId();
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true)
+    public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
+            String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
+
+        // verify input parameters
+        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Physical Network id=" + physicalNetworkId + "doesn't exist in the system");
+        }
+
+        Networks.TrafficType trafficType = null;
+        if (trafficTypeStr != null && !trafficTypeStr.isEmpty()) {
+            try {
+                trafficType = Networks.TrafficType.valueOf(trafficTypeStr);
+            } catch (IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve trafficType '" + trafficTypeStr + "' to a supported value");
+            }
+        }
+
+        if (_pNTrafficTypeDao.isTrafficTypeSupported(physicalNetworkId, trafficType)) {
+            throw new CloudRuntimeException("This physical network already supports the traffic type: " + trafficType);
+        }
+        // For Storage, Control, Management, Public check if the zone has any other physical network with this
+        // traffictype already present
+        // If yes, we cant add these traffics to one more physical network in the zone.
+
+        if (TrafficType.isSystemNetwork(trafficType) || TrafficType.Public.equals(trafficType) || TrafficType.Storage.equals(trafficType)) {
+            if (!_physicalNetworkDao.listByZoneAndTrafficType(network.getDataCenterId(), trafficType).isEmpty()) {
+                throw new CloudRuntimeException("Fail to add the traffic type to physical network because Zone already has a physical network with this traffic type: " + trafficType);
+            }
+        }
+
+        if (TrafficType.Storage.equals(trafficType)) {
+            List<SecondaryStorageVmVO> ssvms = _stnwMgr.getSSVMWithNoStorageNetwork(network.getDataCenterId());
+            if (!ssvms.isEmpty()) {
+                StringBuilder sb = new StringBuilder("Cannot add " + trafficType
+                        + " traffic type as there are below secondary storage vm still running. Please stop them all and add Storage traffic type again, then destory them all to allow CloudStack recreate them with storage network(If you have added storage network ip range)");
+                sb.append("SSVMs:");
+                for (SecondaryStorageVmVO ssvm : ssvms) {
+                    sb.append(ssvm.getInstanceName()).append(":").append(ssvm.getState());
+                }
+                throw new CloudRuntimeException(sb.toString());
+            }
+        }
+
+        try {
+            // Create the new traffic type in the database
+            if (xenLabel == null) {
+                xenLabel = getDefaultXenNetworkLabel(trafficType);
+            }
+            PhysicalNetworkTrafficTypeVO pNetworktrafficType = new PhysicalNetworkTrafficTypeVO(physicalNetworkId, trafficType, xenLabel, kvmLabel, vmwareLabel, simulatorLabel, vlan, hypervLabel,
+                    ovm3Label);
+            pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType);
+
+            // For public traffic, get isolation method of physical network and update the public network accordingly
+            // each broadcast type will individually need to be qualified for support of public traffic
+            if (TrafficType.Public.equals(trafficType)) {
+                List<String> isolationMethods = network.getIsolationMethods();
+                if ((isolationMethods.size() == 1 && isolationMethods.get(0).toLowerCase().equals("vxlan"))
+                        || (isolationMethod != null && isolationMethods.contains(isolationMethod) && isolationMethod.toLowerCase().equals("vxlan"))) {
+                    // find row in networks table that is defined as 'Public', created when zone was deployed
+                    NetworkVO publicNetwork = _networksDao.listByZoneAndTrafficType(network.getDataCenterId(), TrafficType.Public).get(0);
+                    if (publicNetwork != null) {
+                        s_logger.debug("setting public network " + publicNetwork + " to broadcast type vxlan");
+                        publicNetwork.setBroadcastDomainType(BroadcastDomainType.Vxlan);
+                        _networksDao.persist(publicNetwork);
+                    }
+                }
+            }
+
+            return pNetworktrafficType;
+        } catch (Exception ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new CloudRuntimeException("Fail to add a traffic type to physical network");
+        }
+
+    }
+
+    private String getDefaultXenNetworkLabel(TrafficType trafficType) {
+        String xenLabel = null;
+        switch (trafficType) {
+        case Public:
+            xenLabel = _configDao.getValue(Config.XenServerPublicNetwork.key());
+            break;
+        case Guest:
+            xenLabel = _configDao.getValue(Config.XenServerGuestNetwork.key());
+            break;
+        case Storage:
+            xenLabel = _configDao.getValue(Config.XenServerStorageNetwork1.key());
+            break;
+        case Management:
+            xenLabel = _configDao.getValue(Config.XenServerPrivateNetwork.key());
+            break;
+        case Control:
+            xenLabel = "cloud_link_local_network";
+            break;
+        case Vpn:
+        case None:
+            break;
+        }
+        return xenLabel;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", async = true)
+    public PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id) {
+        return _pNTrafficTypeDao.findById(id);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_UPDATE, eventDescription = "Updating physical network TrafficType", async = true)
+    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
+
+        PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
+
+        if (trafficType == null) {
+            throw new InvalidParameterValueException("Traffic Type with id=" + id + "doesn't exist in the system");
+        }
+
+        if (xenLabel != null) {
+            if ("".equals(xenLabel)) {
+                xenLabel = null;
+            }
+            trafficType.setXenNetworkLabel(xenLabel);
+        }
+        if (kvmLabel != null) {
+            if ("".equals(kvmLabel)) {
+                kvmLabel = null;
+            }
+            trafficType.setKvmNetworkLabel(kvmLabel);
+        }
+        if (vmwareLabel != null) {
+            if ("".equals(vmwareLabel)) {
+                vmwareLabel = null;
+            }
+            trafficType.setVmwareNetworkLabel(vmwareLabel);
+        }
+
+        if (hypervLabel != null) {
+            if ("".equals(hypervLabel)) {
+                hypervLabel = null;
+            }
+            trafficType.setHypervNetworkLabel(hypervLabel);
+        }
+
+        if (ovm3Label != null) {
+            if ("".equals(ovm3Label)) {
+                ovm3Label = null;
+            }
+            trafficType.setOvm3NetworkLabel(ovm3Label);
+        }
+        _pNTrafficTypeDao.update(id, trafficType);
+        return trafficType;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_DELETE, eventDescription = "Deleting physical network TrafficType", async = true)
+    public boolean deletePhysicalNetworkTrafficType(Long id) {
+        PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
+
+        if (trafficType == null) {
+            throw new InvalidParameterValueException("Traffic Type with id=" + id + "doesn't exist in the system");
+        }
+
+        // check if there are any networks associated to this physical network with this traffic type
+        if (TrafficType.Guest.equals(trafficType.getTrafficType())) {
+            if (!_networksDao.listByPhysicalNetworkTrafficType(trafficType.getPhysicalNetworkId(), trafficType.getTrafficType()).isEmpty()) {
+                throw new CloudRuntimeException("The Traffic Type is not deletable because there are existing networks with this traffic type:" + trafficType.getTrafficType());
+            }
+        } else if (TrafficType.Storage.equals(trafficType.getTrafficType())) {
+            PhysicalNetworkVO pn = _physicalNetworkDao.findById(trafficType.getPhysicalNetworkId());
+            if (_stnwMgr.isAnyStorageIpInUseInZone(pn.getDataCenterId())) {
+                throw new CloudRuntimeException("The Traffic Type is not deletable because there are still some storage network ip addresses in use:" + trafficType.getTrafficType());
+            }
+        }
+        return _pNTrafficTypeDao.remove(id);
+    }
+
+    @Override
+    public Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId) {
+        PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
+        if (network == null) {
+            throwInvalidIdException("Physical Network with specified id doesn't exist in the system", physicalNetworkId.toString(), "physicalNetworkId");
+        }
+
+        Pair<List<PhysicalNetworkTrafficTypeVO>, Integer> result = _pNTrafficTypeDao.listAndCountBy(physicalNetworkId);
+        return new Pair<List<? extends PhysicalNetworkTrafficType>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    //TODO: duplicated in NetworkModel
+    public NetworkVO getExclusiveGuestNetwork(long zoneId) {
+        List<NetworkVO> networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, zoneId, GuestType.Shared, TrafficType.Guest);
+        if (networks == null || networks.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " + zoneId);
+        }
+
+        if (networks.size() > 1) {
+            throw new InvalidParameterValueException("Found more than 1 network with trafficType " + TrafficType.Guest + " and guestType " + GuestType.Shared + " in zone " + zoneId);
+
+        }
+
+        return networks.get(0);
+    }
+
+    protected PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) {
+
+        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName(), null, null);
+        // add instance of the provider
+        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.VirtualRouter.getName());
+        if (networkElement == null) {
+            throw new CloudRuntimeException("Unable to find the Network Element implementing the VirtualRouter Provider");
+        }
+
+        VirtualRouterElement element = (VirtualRouterElement)networkElement;
+        element.addElement(nsp.getId(), Type.VirtualRouter);
+
+        return nsp;
+    }
+
+    private PhysicalNetworkServiceProvider addDefaultOvsToPhysicalNetwork(long physicalNetworkId) {
+        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.Ovs.getName(), null, null);
+        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.Ovs.getName());
+        if (networkElement == null) {
+            throw new CloudRuntimeException("Unable to find the Network Element implementing the Ovs Provider");
+        }
+        OvsProviderVO element = _ovsProviderDao.findByNspId(nsp.getId());
+        if (element != null) {
+            s_logger.debug("There is already a Ovs element with service provider id " + nsp.getId());
+            return nsp;
+        }
+        element = new OvsProviderVO(nsp.getId());
+        _ovsProviderDao.persist(element);
+        return nsp;
+    }
+
+    protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) {
+
+        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName(), null, null);
+
+        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName());
+        if (networkElement == null) {
+            throw new CloudRuntimeException("Unable to find the Network Element implementing the VPCVirtualRouter Provider");
+        }
+
+        VpcVirtualRouterElement element = (VpcVirtualRouterElement)networkElement;
+        element.addElement(nsp.getId(), Type.VPCVirtualRouter);
+
+        return nsp;
+    }
+
+    protected PhysicalNetworkServiceProvider addDefaultInternalLbProviderToPhysicalNetwork(long physicalNetworkId) {
+
+        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.InternalLbVm.getName(), null, null);
+
+        NetworkElement networkElement = _networkModel.getElementImplementingProvider(Network.Provider.InternalLbVm.getName());
+        if (networkElement == null) {
+            throw new CloudRuntimeException("Unable to find the Network Element implementing the " + Network.Provider.InternalLbVm.getName() + " Provider");
+        }
+
+        _internalLbElementSvc.addInternalLoadBalancerElement(nsp.getId());
+
+        return nsp;
+    }
+
+    protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) {
+
+        PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.SecurityGroupProvider.getName(), null, null);
+
+        return nsp;
+    }
+
+    private PhysicalNetworkServiceProvider addDefaultBaremetalProvidersToPhysicalNetwork(long physicalNetworkId) {
+        PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId);
+        DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId());
+        if (dvo.getNetworkType() == NetworkType.Basic) {
+
+            Provider provider = Network.Provider.getProvider("BaremetalDhcpProvider");
+            if (provider == null) {
+                // baremetal is not loaded
+                return null;
+            }
+
+            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalDhcpProvider", null, null);
+            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
+            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalUserdataProvider", null, null);
+        } else if (dvo.getNetworkType() == NetworkType.Advanced) {
+            addProviderToPhysicalNetwork(physicalNetworkId, "BaremetalPxeProvider", null, null);
+            enableProvider("BaremetalPxeProvider");
+        }
+
+        return null;
+    }
+
+    private void enableProvider(String providerName) {
+        QueryBuilder<PhysicalNetworkServiceProviderVO> q = QueryBuilder.create(PhysicalNetworkServiceProviderVO.class);
+        q.and(q.entity().getProviderName(), SearchCriteria.Op.EQ, providerName);
+        PhysicalNetworkServiceProviderVO provider = q.find();
+        provider.setState(PhysicalNetworkServiceProvider.State.Enabled);
+        _pNSPDao.update(provider.getId(), provider);
+    }
+
+    private PhysicalNetworkServiceProvider addConfigDriveToPhysicalNetwork(long physicalNetworkId) {
+        PhysicalNetworkVO pvo = _physicalNetworkDao.findById(physicalNetworkId);
+        DataCenterVO dvo = _dcDao.findById(pvo.getDataCenterId());
+        if (dvo.getNetworkType() == NetworkType.Advanced) {
+
+            Provider provider = Network.Provider.getProvider("ConfigDrive");
+            if (provider == null) {
+                return null;
+            }
+
+            addProviderToPhysicalNetwork(physicalNetworkId, Provider.ConfigDrive.getName(), null, null);
+            enableProvider(Provider.ConfigDrive.getName());
+        }
+        return null;
+
+    }
+
+    protected boolean isNetworkSystem(Network network) {
+        NetworkOffering no = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        if (no.isSystemOnly()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean getAllowSubdomainAccessGlobal() {
+        return _allowSubdomainNetworkAccess;
+    }
+
+    @Override
+    public List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd) {
+        String type = cmd.getTrafficType();
+        List<Pair<TrafficType, String>> results = new ArrayList<Pair<TrafficType, String>>();
+        if (type != null) {
+            for (NetworkGuru guru : _networkGurus) {
+                if (guru.isMyTrafficType(TrafficType.getTrafficType(type))) {
+                    results.add(new Pair<TrafficType, String>(TrafficType.getTrafficType(type), guru.getName()));
+                    break;
+                }
+            }
+        } else {
+            for (NetworkGuru guru : _networkGurus) {
+                TrafficType[] allTypes = guru.getSupportedTrafficType();
+                for (TrafficType t : allTypes) {
+                    results.add(new Pair<TrafficType, String>(t, guru.getName()));
+                }
+            }
+        }
+
+        return results;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
+    public IpAddress associateIPToNetwork(long ipId, long networkId)
+            throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException {
+
+        Network network = _networksDao.findById(networkId);
+        if (network == null) {
+            // release the acquired IP addrress before throwing the exception
+            // else it will always be in allocating state
+            releaseIpAddress(ipId);
+            throw new InvalidParameterValueException("Invalid network id is given");
+        }
+
+        if (network.getVpcId() != null) {
+            // release the acquired IP addrress before throwing the exception
+            // else it will always be in allocating state
+            releaseIpAddress(ipId);
+            throw new InvalidParameterValueException("Can't assign ip to the network directly when network belongs" + " to VPC.Specify vpcId to associate ip address to VPC");
+        }
+        return _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, true);
+
+    }
+
+    @Override
+    @DB
+    public Network createPrivateNetwork(final String networkName, final String displayText, long physicalNetworkId, String broadcastUriString, final String startIp, String endIp, final String gateway,
+            String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId)
+                    throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
+
+        final Account owner = _accountMgr.getAccount(networkOwnerId);
+
+        // Get system network offering
+        NetworkOfferingVO ntwkOff = null;
+        if (networkOfferingId != null) {
+            ntwkOff = _networkOfferingDao.findById(networkOfferingId);
+        }
+        if (ntwkOff == null) {
+            ntwkOff = findSystemNetworkOffering(NetworkOffering.SystemPrivateGatewayNetworkOffering);
+        }
+
+        // Validate physical network
+        final PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNtwk == null) {
+            throwInvalidIdException("Unable to find a physical network" + " having the given id", String.valueOf(physicalNetworkId), "physicalNetworkId");
+        }
+
+        // VALIDATE IP INFO
+        // if end ip is not specified, default it to startIp
+        if (!NetUtils.isValidIp4(startIp)) {
+            throw new InvalidParameterValueException("Invalid format for the ip address parameter");
+        }
+        if (endIp == null) {
+            endIp = startIp;
+        } else if (!NetUtils.isValidIp4(endIp)) {
+            throw new InvalidParameterValueException("Invalid format for the endIp address parameter");
+        }
+
+        if (!NetUtils.isValidIp4(gateway)) {
+            throw new InvalidParameterValueException("Invalid gateway");
+        }
+        if (!NetUtils.isValidIp4Netmask(netmask)) {
+            throw new InvalidParameterValueException("Invalid netmask");
+        }
+
+        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+
+        URI uri = BroadcastDomainType.fromString(broadcastUriString);
+        final String uriString = uri.toString();
+        BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri);
+        // numeric vlan or vlan uri are ok for now
+        // TODO make a test for any supported scheme
+        if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) {
+            throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString);
+        }
+
+        final NetworkOfferingVO ntwkOffFinal = ntwkOff;
+        try {
+            return Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
+                @Override
+                public Network doInTransaction(TransactionStatus status) throws ResourceAllocationException, InsufficientCapacityException {
+                    //lock datacenter as we need to get mac address seq from there
+                    DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true);
+
+                    //check if we need to create guest network
+                    Network privateNetwork = _networksDao.getPrivateNetwork(uriString, cidr, networkOwnerId, pNtwk.getDataCenterId(), networkOfferingId);
+                    if (privateNetwork == null) {
+                        //create Guest network
+                        privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, false, null, owner, null, pNtwk,
+                                pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null, null);
+                        if (privateNetwork != null) {
+                            s_logger.debug("Successfully created guest network " + privateNetwork);
+                        } else {
+                            throw new CloudRuntimeException("Creating guest network failed");
+                        }
+                    } else {
+                        s_logger.debug("Private network already exists: " + privateNetwork);
+                        //Do not allow multiple private gateways with same Vlan within a VPC
+                        if (vpcId != null && vpcId.equals(privateNetwork.getVpcId())) {
+                            throw new InvalidParameterValueException("Private network for the vlan: " + uriString + " and cidr  " + cidr + "  already exists " + "for Vpc " + vpcId + " in zone "
+                                    + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
+                        }
+                    }
+                    if (vpcId != null) {
+                        //add entry to private_ip_address table
+                        PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId);
+                        if (privateIp != null) {
+                            throw new InvalidParameterValueException(
+                                    "Private ip address " + startIp + " already used for private gateway" + " in zone " + _entityMgr.findById(DataCenter.class, pNtwk.getDataCenterId()).getName());
+                        }
+                        Long mac = dc.getMacAddress();
+                        Long nextMac = mac + 1;
+                        dc.setMacAddress(nextMac);
+                        privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac, vpcId, sourceNat);
+                        _privateIpDao.persist(privateIp);
+                        _dcDao.update(dc.getId(), dc);
+                    }
+
+                    s_logger.debug("Private network " + privateNetwork + " is created");
+
+                    return privateNetwork;
+                }
+            });
+        } catch (Exception e) {
+            ExceptionUtil.rethrowRuntime(e);
+            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
+            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private NetworkOfferingVO findSystemNetworkOffering(String offeringName) {
+        List<NetworkOfferingVO> allOfferings = _networkOfferingDao.listSystemNetworkOfferings();
+        for (NetworkOfferingVO offer : allOfferings) {
+            if (offer.getName().equals(offeringName)) {
+                return offer;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Network getNetwork(String networkUuid) {
+        return _networksDao.findByUuid(networkUuid);
+    }
+
+    @Override
+    public List<? extends Nic> listNics(ListNicsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long nicId = cmd.getNicId();
+        long vmId = cmd.getVmId();
+        String keyword = cmd.getKeyword();
+        Long networkId = cmd.getNetworkId();
+        UserVmVO userVm = _userVmDao.findById(vmId);
+
+        if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
+            throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, userVm);
+        return _networkMgr.listVmNics(vmId, nicId, networkId, keyword);
+    }
+
+    @Override
+    public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long nicId = cmd.getNicId();
+        long vmId = cmd.getVmId();
+        String keyword = cmd.getKeyword();
+        UserVmVO userVm = _userVmDao.findById(vmId);
+
+        if (userVm == null || (!userVm.isDisplayVm() && caller.getType() == Account.ACCOUNT_TYPE_NORMAL)) {
+            throwInvalidIdException("Virtual machine id does not exist", Long.valueOf(vmId).toString(), "vmId");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, userVm);
+        return _nicSecondaryIpDao.listSecondaryIpUsingKeyword(nicId, keyword);
+    }
+
+    public List<NetworkGuru> getNetworkGurus() {
+        return _networkGurus;
+    }
+
+    @Inject
+    public void setNetworkGurus(List<NetworkGuru> networkGurus) {
+        _networkGurus = networkGurus;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_UPDATE, eventDescription = "updating public ip address", async = true)
+    public IpAddress updateIP(Long id, String customId, Boolean displayIp) {
+        Account caller = CallContext.current().getCallingAccount();
+        IPAddressVO ipVO = _ipAddressDao.findById(id);
+        if (ipVO == null) {
+            throw new InvalidParameterValueException("Unable to find ip address by id");
+        }
+
+        // verify permissions
+        if (ipVO.getAllocatedToAccountId() != null) {
+            _accountMgr.checkAccess(caller, null, true, ipVO);
+        } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new PermissionDeniedException("Only Root admin can update non-allocated ip addresses");
+        }
+
+        if (customId != null) {
+            ipVO.setUuid(customId);
+        }
+
+        if (displayIp != null) {
+            ipVO.setDisplay(displayIp);
+        }
+
+        _ipAddressDao.update(id, ipVO);
+        return _ipAddressDao.findById(id);
+    }
+
+    @Override
+    public AcquirePodIpCmdResponse allocatePodIp(Account ipOwner, String zoneId, String podId) throws ResourceAllocationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        long callerUserId = CallContext.current().getCallingUserId();
+        DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId);
+
+        if (zone == null) {
+            throw new InvalidParameterValueException("Invalid zone Id ");
+        }
+        if (_accountMgr.checkAccessAndSpecifyAuthority(caller, zone.getId()) != zone.getId()) {
+            throw new InvalidParameterValueException("Caller does not have permission for this Zone" + "(" + zoneId + ")");
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
+        }
+        return _ipAddrMgr.allocatePodIp(zoneId, podId);
+
+    }
+
+    @Override
+    public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
+        _ipAddrMgr.releasePodIp(ip.getId());
+        return true;
+    }
+
+}
diff --git a/server/src/com/cloud/network/NetworkUsageManager.java b/server/src/main/java/com/cloud/network/NetworkUsageManager.java
similarity index 100%
rename from server/src/com/cloud/network/NetworkUsageManager.java
rename to server/src/main/java/com/cloud/network/NetworkUsageManager.java
diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/main/java/com/cloud/network/NetworkUsageManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/NetworkUsageManagerImpl.java
rename to server/src/main/java/com/cloud/network/NetworkUsageManagerImpl.java
diff --git a/server/src/com/cloud/network/PortProfileManagerImpl.java b/server/src/main/java/com/cloud/network/PortProfileManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/PortProfileManagerImpl.java
rename to server/src/main/java/com/cloud/network/PortProfileManagerImpl.java
diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/main/java/com/cloud/network/SshKeysDistriMonitor.java
similarity index 100%
rename from server/src/com/cloud/network/SshKeysDistriMonitor.java
rename to server/src/main/java/com/cloud/network/SshKeysDistriMonitor.java
diff --git a/server/src/com/cloud/network/StorageNetworkManager.java b/server/src/main/java/com/cloud/network/StorageNetworkManager.java
similarity index 100%
rename from server/src/com/cloud/network/StorageNetworkManager.java
rename to server/src/main/java/com/cloud/network/StorageNetworkManager.java
diff --git a/server/src/com/cloud/network/StorageNetworkManagerImpl.java b/server/src/main/java/com/cloud/network/StorageNetworkManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/StorageNetworkManagerImpl.java
rename to server/src/main/java/com/cloud/network/StorageNetworkManagerImpl.java
diff --git a/server/src/com/cloud/network/as/AutoScaleManager.java b/server/src/main/java/com/cloud/network/as/AutoScaleManager.java
similarity index 100%
rename from server/src/com/cloud/network/as/AutoScaleManager.java
rename to server/src/main/java/com/cloud/network/as/AutoScaleManager.java
diff --git a/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java
new file mode 100644
index 0000000..f381ce0
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/as/AutoScaleManagerImpl.java
@@ -0,0 +1,1532 @@
+// 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.network.as;
+
+import java.security.InvalidParameterException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
+import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmProfileCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateConditionCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScalePoliciesCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmGroupsCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmProfilesCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListConditionsCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListCountersCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
+import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.dispatch.DispatchChainFactory;
+import com.cloud.api.dispatch.DispatchTask;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterParam;
+import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
+import com.cloud.network.as.dao.AutoScalePolicyDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
+import com.cloud.network.as.dao.AutoScaleVmProfileDao;
+import com.cloud.network.as.dao.ConditionDao;
+import com.cloud.network.as.dao.CounterDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.LoadBalancerVMMapVO;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.lb.LoadBalancingRulesService;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmService;
+
+public class AutoScaleManagerImpl<Type> extends ManagerBase implements AutoScaleManager, AutoScaleService {
+    private static final Logger s_logger = Logger.getLogger(AutoScaleManagerImpl.class);
+    private ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1);
+
+    @Inject
+    protected DispatchChainFactory dispatchChainFactory = null;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    TemplateManager _templateMgr;
+    @Inject
+    LoadBalancingRulesManager _lbRulesMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    CounterDao _counterDao;
+    @Inject
+    ConditionDao _conditionDao;
+    @Inject
+    LoadBalancerVMMapDao _lb2VmMapDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    AutoScaleVmProfileDao _autoScaleVmProfileDao;
+    @Inject
+    AutoScalePolicyDao _autoScalePolicyDao;
+    @Inject
+    AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao;
+    @Inject
+    AutoScaleVmGroupDao _autoScaleVmGroupDao;
+    @Inject
+    AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao;
+    @Inject
+    AutoScaleVmGroupVmMapDao _autoScaleVmGroupVmMapDao;
+    @Inject
+    DataCenterDao _dcDao = null;
+    @Inject
+    UserDao _userDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    AccountService _accountService;
+    @Inject
+    UserVmService _userVmService;
+    @Inject
+    UserVmManager _userVmManager;
+    @Inject
+    LoadBalancerVMMapDao _lbVmMapDao;
+    @Inject
+    LoadBalancingRulesService _loadBalancingRulesService;
+
+    public List<AutoScaleCounter> getSupportedAutoScaleCounters(long networkid) {
+        String capability = _lbRulesMgr.getLBCapability(networkid, Capability.AutoScaleCounters.getName());
+        if (capability == null) {
+            return null;
+        }
+        Gson gson = new Gson();
+        java.lang.reflect.Type listType = new TypeToken<List<AutoScaleCounter>>() {
+        }.getType();
+        List<AutoScaleCounter> result = gson.fromJson(capability, listType);
+        return result;
+    }
+
+    public void validateAutoScaleCounters(long networkid, List<Counter> counters, List<Pair<String, String>> counterParamPassed) {
+        List<AutoScaleCounter> supportedCounters = getSupportedAutoScaleCounters(networkid);
+        if (supportedCounters == null) {
+            throw new InvalidParameterException("AutoScale is not supported in the network");
+        }
+        for (Counter counter : counters) {
+            String counterName = counter.getSource().name().toString();
+            boolean isCounterSupported = false;
+            for (AutoScaleCounter autoScaleCounter : supportedCounters) {
+                if (autoScaleCounter.getName().equals(counterName)) {
+                    isCounterSupported = true;
+                    List<AutoScaleCounterParam> counterParams = autoScaleCounter.getParamList();
+                    for (AutoScaleCounterParam autoScaleCounterParam : counterParams) {
+                        boolean isRequiredParameter = autoScaleCounterParam.getRequired();
+                        if (isRequiredParameter) {
+                            boolean isRequiredParamPresent = false;
+                            for (Pair<String, String> pair : counterParamPassed) {
+                                if (pair.first().equals(autoScaleCounterParam.getParamName()))
+                                    isRequiredParamPresent = true;
+
+                            }
+                            if (!isRequiredParamPresent) {
+                                throw new InvalidParameterException("Parameter " + autoScaleCounterParam.getParamName() + " has to be set in AutoScaleVmProfile's " +
+                                    ApiConstants.COUNTERPARAM_LIST);
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+            if (!isCounterSupported) {
+                throw new InvalidParameterException("AutoScale counter with source='" + counter.getSource().name() + "' is not supported " + "in the network");
+            }
+        }
+    }
+
+    private <VO extends ControlledEntity> VO getEntityInDatabase(Account caller, String paramName, Long id, GenericDao<VO, Long> dao) {
+
+        VO vo = dao.findById(id);
+
+        if (vo == null) {
+            throw new InvalidParameterValueException("Unable to find " + paramName);
+        }
+
+        _accountMgr.checkAccess(caller, null, false, (ControlledEntity)vo);
+
+        return vo;
+    }
+
+    private boolean isAutoScaleScaleUpPolicy(AutoScalePolicy policyVO) {
+        return policyVO.getAction().equals("scaleup");
+    }
+
+    private List<AutoScalePolicyVO> getAutoScalePolicies(String paramName, List<Long> policyIds, List<Counter> counters, int interval, boolean scaleUpPolicies) {
+        SearchBuilder<AutoScalePolicyVO> policySearch = _autoScalePolicyDao.createSearchBuilder();
+        policySearch.and("ids", policySearch.entity().getId(), Op.IN);
+        policySearch.done();
+        SearchCriteria<AutoScalePolicyVO> sc = policySearch.create();
+
+        sc.setParameters("ids", policyIds.toArray(new Object[0]));
+        List<AutoScalePolicyVO> policies = _autoScalePolicyDao.search(sc, null);
+
+        int prevQuietTime = 0;
+
+        for (AutoScalePolicyVO policy : policies) {
+            int quietTime = policy.getQuietTime();
+            if (prevQuietTime == 0) {
+                prevQuietTime = quietTime;
+            }
+            int duration = policy.getDuration();
+            if (duration < interval) {
+                throw new InvalidParameterValueException("duration : " + duration + " specified in a policy cannot be less than vm group's interval : " + interval);
+            }
+
+            if (quietTime != prevQuietTime) {
+                throw new InvalidParameterValueException("quietTime should be same for all the policies specified in " + paramName);
+            }
+
+            if (scaleUpPolicies) {
+                if (!isAutoScaleScaleUpPolicy(policy)) {
+                    throw new InvalidParameterValueException("Only scaleup policies can be specified in scaleuppolicyids");
+                }
+            } else {
+                if (isAutoScaleScaleUpPolicy(policy)) {
+                    throw new InvalidParameterValueException("Only scaledown policies can be specified in scaledownpolicyids");
+                }
+            }
+            List<AutoScalePolicyConditionMapVO> policyConditionMapVOs = _autoScalePolicyConditionMapDao.listByAll(policy.getId(), null);
+            for (AutoScalePolicyConditionMapVO policyConditionMapVO : policyConditionMapVOs) {
+                long conditionid = policyConditionMapVO.getConditionId();
+                Condition condition = _conditionDao.findById(conditionid);
+                Counter counter = _counterDao.findById(condition.getCounterid());
+                counters.add(counter);
+            }
+        }
+        return policies;
+    }
+
+    @DB
+    protected AutoScaleVmProfileVO checkValidityAndPersist(AutoScaleVmProfileVO vmProfile) {
+        long templateId = vmProfile.getTemplateId();
+        long autoscaleUserId = vmProfile.getAutoScaleUserId();
+        int destroyVmGraceperiod = vmProfile.getDestroyVmGraceperiod();
+
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+        // Make sure a valid template ID was specified
+        if (template == null) {
+            throw new InvalidParameterValueException("Unable to use the given template.");
+        }
+
+        if (destroyVmGraceperiod < 0) {
+            throw new InvalidParameterValueException("Destroy Vm Grace Period cannot be less than 0.");
+        }
+
+        User user = _userDao.findById(autoscaleUserId);
+        if (user.getAccountId() != vmProfile.getAccountId()) {
+            throw new InvalidParameterValueException("AutoScale User id does not belong to the same account");
+        }
+
+        String apiKey = user.getApiKey();
+        String secretKey = user.getSecretKey();
+        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
+
+        if (apiKey == null) {
+            throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it");
+        }
+
+        if (secretKey == null) {
+            throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it");
+        }
+
+        if (csUrl == null || csUrl.contains("localhost")) {
+            throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
+        }
+
+        vmProfile = _autoScaleVmProfileDao.persist(vmProfile);
+
+        return vmProfile;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_CREATE, eventDescription = "creating autoscale vm profile", create = true)
+    public AutoScaleVmProfile createAutoScaleVmProfile(CreateAutoScaleVmProfileCmd cmd) {
+
+        Account owner = _accountDao.findById(cmd.getAccountId());
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        long zoneId = cmd.getZoneId();
+        long serviceOfferingId = cmd.getServiceOfferingId();
+        long autoscaleUserId = cmd.getAutoscaleUserId();
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id");
+        }
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering by id");
+        }
+
+        // validations
+        HashMap<String, String> deployParams = cmd.getDeployParamMap();
+        if (deployParams.containsKey("networks") && deployParams.get("networks").length() > 0) {
+            throw new InvalidParameterValueException(
+                "'networks' is not a valid parameter, network for an AutoScaled VM is chosen automatically. An autoscaled VM is deployed in the loadbalancer's network");
+        }
+        /*
+         * Just for making sure the values are right in other deploy params.
+         * For ex. if projectId is given as a string instead of an long value, this
+         * will be throwing an error.
+         */
+        dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(ComponentContext.inject(DeployVMCmd.class), deployParams));
+
+        AutoScaleVmProfileVO profileVO =
+            new AutoScaleVmProfileVO(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getServiceOfferingId(), cmd.getTemplateId(), cmd.getOtherDeployParams(),
+                cmd.getCounterParamList(), cmd.getDestroyVmGraceperiod(), autoscaleUserId);
+
+        if (cmd.getDisplay() != null) {
+            profileVO.setDisplay(cmd.getDisplay());
+        }
+
+        profileVO = checkValidityAndPersist(profileVO);
+        s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId());
+
+        return profileVO;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_UPDATE, eventDescription = "updating autoscale vm profile")
+    public AutoScaleVmProfile updateAutoScaleVmProfile(UpdateAutoScaleVmProfileCmd cmd) {
+        Long profileId = cmd.getId();
+        Long templateId = cmd.getTemplateId();
+        Long autoscaleUserId = cmd.getAutoscaleUserId();
+        Map counterParamList = cmd.getCounterParamList();
+
+        Integer destroyVmGraceperiod = cmd.getDestroyVmGraceperiod();
+
+        AutoScaleVmProfileVO vmProfile = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Vm Profile", profileId, _autoScaleVmProfileDao);
+
+        boolean physicalParameterUpdate = (templateId != null || autoscaleUserId != null || counterParamList != null || destroyVmGraceperiod != null);
+
+        if (templateId != null) {
+            vmProfile.setTemplateId(templateId);
+        }
+
+        if (autoscaleUserId != null) {
+            vmProfile.setAutoscaleUserId(autoscaleUserId);
+        }
+
+        if (counterParamList != null) {
+            vmProfile.setCounterParamsForUpdate(counterParamList);
+        }
+
+        if (destroyVmGraceperiod != null) {
+            vmProfile.setDestroyVmGraceperiod(destroyVmGraceperiod);
+        }
+
+        if (cmd.getCustomId() != null) {
+            vmProfile.setUuid(cmd.getCustomId());
+        }
+
+        if (cmd.getDisplay() != null) {
+            vmProfile.setDisplay(cmd.getDisplay());
+        }
+
+        List<AutoScaleVmGroupVO> vmGroupList = _autoScaleVmGroupDao.listByAll(null, profileId);
+        for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) {
+            if (physicalParameterUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
+                throw new InvalidParameterValueException("The AutoScale Vm Profile can be updated only if the Vm Group it is associated with is disabled in state");
+            }
+        }
+
+        vmProfile = checkValidityAndPersist(vmProfile);
+        s_logger.info("Updated Auto Scale Vm Profile id:" + vmProfile.getId());
+
+        return vmProfile;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMPROFILE_DELETE, eventDescription = "deleting autoscale vm profile")
+    public boolean deleteAutoScaleVmProfile(long id) {
+        /* Check if entity is in database */
+        getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Profile", id, _autoScaleVmProfileDao);
+        if (_autoScaleVmGroupDao.isProfileInUse(id)) {
+            throw new InvalidParameterValueException("Cannot delete AutoScale Vm Profile when it is in use by one more vm groups");
+        }
+        boolean success = _autoScaleVmProfileDao.remove(id);
+        if (success) {
+            s_logger.info("Successfully deleted AutoScale Vm Profile with Id: " + id);
+        }
+        return success;
+    }
+
+    @Override
+    public List<? extends AutoScaleVmProfile> listAutoScaleVmProfiles(ListAutoScaleVmProfilesCmd cmd) {
+        Long id = cmd.getId();
+        Long templateId = cmd.getTemplateId();
+        String otherDeployParams = cmd.getOtherDeployParams();
+        Long serviceOffId = cmd.getServiceOfferingId();
+        Long zoneId = cmd.getZoneId();
+        Boolean display = cmd.getDisplay();
+
+        SearchWrapper<AutoScaleVmProfileVO> searchWrapper = new SearchWrapper<AutoScaleVmProfileVO>(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId());
+        SearchBuilder<AutoScaleVmProfileVO> sb = searchWrapper.getSearchBuilder();
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ);
+        sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE);
+        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
+        SearchCriteria<AutoScaleVmProfileVO> sc = searchWrapper.buildSearchCriteria();
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+        if (templateId != null) {
+            sc.setParameters("templateId", templateId);
+        }
+        if (otherDeployParams != null) {
+            sc.addAnd("otherDeployParams", SearchCriteria.Op.LIKE, "%" + otherDeployParams + "%");
+        }
+
+        if (serviceOffId != null) {
+            sc.setParameters("serviceOfferingId", serviceOffId);
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("zoneId", zoneId);
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        return searchWrapper.search();
+    }
+
+    @DB
+    protected AutoScalePolicyVO checkValidityAndPersist(final AutoScalePolicyVO autoScalePolicyVOFinal, final List<Long> conditionIds) {
+        final int duration = autoScalePolicyVOFinal.getDuration();
+        final int quietTime = autoScalePolicyVOFinal.getQuietTime();
+
+        if (duration < 0) {
+            throw new InvalidParameterValueException("duration is an invalid value: " + duration);
+        }
+
+        if (quietTime < 0) {
+            throw new InvalidParameterValueException("quiettime is an invalid value: " + quietTime);
+        }
+
+        return Transaction.execute(new TransactionCallback<AutoScalePolicyVO>() {
+            @Override
+            public AutoScalePolicyVO doInTransaction(TransactionStatus status) {
+                AutoScalePolicyVO autoScalePolicyVO = _autoScalePolicyDao.persist(autoScalePolicyVOFinal);
+
+                if (conditionIds != null) {
+                    SearchBuilder<ConditionVO> conditionsSearch = _conditionDao.createSearchBuilder();
+                    conditionsSearch.and("ids", conditionsSearch.entity().getId(), Op.IN);
+                    conditionsSearch.done();
+                    SearchCriteria<ConditionVO> sc = conditionsSearch.create();
+
+                    sc.setParameters("ids", conditionIds.toArray(new Object[0]));
+                    List<ConditionVO> conditions = _conditionDao.search(sc, null);
+
+                    ControlledEntity[] sameOwnerEntities = conditions.toArray(new ControlledEntity[conditions.size() + 1]);
+                    sameOwnerEntities[sameOwnerEntities.length - 1] = autoScalePolicyVO;
+                    _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
+
+                    if (conditionIds.size() != conditions.size()) {
+                        // TODO report the condition id which could not be found
+                        throw new InvalidParameterValueException("Unable to find the condition specified");
+                    }
+
+                    ArrayList<Long> counterIds = new ArrayList<Long>();
+                    for (ConditionVO condition : conditions) {
+                        if (counterIds.contains(condition.getCounterid())) {
+                            throw new InvalidParameterValueException(
+                                "atleast two conditions in the conditionids have the same counter. It is not right to apply two different conditions for the same counter");
+                        }
+                        counterIds.add(condition.getCounterid());
+                    }
+
+                    /* For update case remove the existing mappings and create fresh ones */
+                    _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(autoScalePolicyVO.getId());
+
+                    for (Long conditionId : conditionIds) {
+                        AutoScalePolicyConditionMapVO policyConditionMapVO = new AutoScalePolicyConditionMapVO(autoScalePolicyVO.getId(), conditionId);
+                        _autoScalePolicyConditionMapDao.persist(policyConditionMapVO);
+                    }
+                }
+
+                return autoScalePolicyVO;
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_CREATE, eventDescription = "creating autoscale policy", create = true)
+    public AutoScalePolicy createAutoScalePolicy(CreateAutoScalePolicyCmd cmd) {
+
+        int duration = cmd.getDuration();
+        Integer quietTime = cmd.getQuietTime();
+        String action = cmd.getAction();
+
+        if (quietTime == null) {
+            quietTime = NetUtils.DEFAULT_AUTOSCALE_POLICY_QUIET_TIME;
+        }
+
+        action = action.toLowerCase();
+        if (!NetUtils.isValidAutoScaleAction(action)) {
+            throw new InvalidParameterValueException("action is invalid, only 'scaleup' and 'scaledown' is supported");
+        }
+
+        AutoScalePolicyVO policyVO = new AutoScalePolicyVO(cmd.getDomainId(), cmd.getAccountId(), duration, quietTime, null, action);
+
+        policyVO = checkValidityAndPersist(policyVO, cmd.getConditionIds());
+        s_logger.info("Successfully created AutoScale Policy with Id: " + policyVO.getId());
+        return policyVO;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_DELETE, eventDescription = "deleting autoscale policy")
+    public boolean deleteAutoScalePolicy(final long id) {
+        /* Check if entity is in database */
+        getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Policy", id, _autoScalePolicyDao);
+
+        if (_autoScaleVmGroupPolicyMapDao.isAutoScalePolicyInUse(id)) {
+            throw new InvalidParameterValueException("Cannot delete AutoScale Policy when it is in use by one or more AutoScale Vm Groups");
+        }
+
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                boolean success = true;
+                success = _autoScalePolicyDao.remove(id);
+                if (!success) {
+                    s_logger.warn("Failed to remove AutoScale Policy db object");
+                    return false;
+                }
+                success = _autoScalePolicyConditionMapDao.removeByAutoScalePolicyId(id);
+                if (!success) {
+                    s_logger.warn("Failed to remove AutoScale Policy Condition mappings");
+                    return false;
+                }
+                s_logger.info("Successfully deleted autoscale policy id : " + id);
+
+                return success;
+            }
+        });
+    }
+
+    public void checkCallerAccess(String accountName, Long domainId) {
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountDao.findActiveAccount(accountName, domainId);
+        if (owner == null) {
+            List<String> idList = new ArrayList<String>();
+            idList.add(ApiDBUtils.findDomainById(domainId).getUuid());
+            throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain with specifed domainId");
+        }
+        _accountMgr.checkAccess(caller, null, false, owner);
+    }
+
+    private class SearchWrapper<VO extends ControlledEntity> {
+        GenericDao<VO, Long> dao;
+        SearchBuilder<VO> searchBuilder;
+        SearchCriteria<VO> searchCriteria;
+        Long domainId;
+        boolean isRecursive;
+        List<Long> permittedAccounts = new ArrayList<Long>();
+        ListProjectResourcesCriteria listProjectResourcesCriteria;
+        Filter searchFilter;
+
+        public SearchWrapper(GenericDao<VO, Long> dao, Class<VO> entityClass, BaseListAccountResourcesCmd cmd, Long id)
+        {
+            this.dao = dao;
+            this.searchBuilder = dao.createSearchBuilder();
+            domainId = cmd.getDomainId();
+            String accountName = cmd.getAccountName();
+            isRecursive = cmd.isRecursive();
+            boolean listAll = cmd.listAll();
+            long startIndex = cmd.getStartIndex();
+            long pageSizeVal = cmd.getPageSizeVal();
+            Account caller = CallContext.current().getCallingAccount();
+
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
+                    ListProjectResourcesCriteria>(domainId, isRecursive, null);
+            _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject,
+                    listAll, false);
+            domainId = domainIdRecursiveListProject.first();
+            isRecursive = domainIdRecursiveListProject.second();
+            ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+            _accountMgr.buildACLSearchBuilder(searchBuilder, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            searchFilter = new Filter(entityClass, "id", false, startIndex, pageSizeVal);
+        }
+
+        public SearchBuilder<VO> getSearchBuilder() {
+            return searchBuilder;
+        }
+
+        public SearchCriteria<VO> buildSearchCriteria() {
+            searchCriteria = searchBuilder.create();
+            _accountMgr.buildACLSearchCriteria(searchCriteria, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            return searchCriteria;
+        }
+
+        public List<VO> search() {
+            return dao.search(searchCriteria, searchFilter);
+        }
+    }
+
+    @Override
+    public List<? extends AutoScalePolicy> listAutoScalePolicies(ListAutoScalePoliciesCmd cmd) {
+        SearchWrapper<AutoScalePolicyVO> searchWrapper = new SearchWrapper<AutoScalePolicyVO>(_autoScalePolicyDao, AutoScalePolicyVO.class, cmd, cmd.getId());
+        SearchBuilder<AutoScalePolicyVO> sb = searchWrapper.getSearchBuilder();
+        Long id = cmd.getId();
+        Long conditionId = cmd.getConditionId();
+        String action = cmd.getAction();
+        Long vmGroupId = cmd.getVmGroupId();
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("action", sb.entity().getAction(), SearchCriteria.Op.EQ);
+
+        if (conditionId != null) {
+            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
+            asPolicyConditionSearch.and("conditionId", asPolicyConditionSearch.entity().getConditionId(), SearchCriteria.Op.EQ);
+            sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (vmGroupId != null) {
+            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
+            asVmGroupPolicySearch.and("vmGroupId", asVmGroupPolicySearch.entity().getVmGroupId(), SearchCriteria.Op.EQ);
+            sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getPolicyId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<AutoScalePolicyVO> sc = searchWrapper.buildSearchCriteria();
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (action != null) {
+            sc.setParameters("action", action);
+        }
+
+        if (conditionId != null) {
+            sc.setJoinParameters("asPolicyConditionSearch", "conditionId", conditionId);
+        }
+
+        if (vmGroupId != null) {
+            sc.setJoinParameters("asVmGroupPolicySearch", "vmGroupId", vmGroupId);
+        }
+
+        return searchWrapper.search();
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEPOLICY_UPDATE, eventDescription = "updating autoscale policy")
+    public AutoScalePolicy updateAutoScalePolicy(UpdateAutoScalePolicyCmd cmd) {
+        Long policyId = cmd.getId();
+        Integer duration = cmd.getDuration();
+        Integer quietTime = cmd.getQuietTime();
+        List<Long> conditionIds = cmd.getConditionIds();
+        AutoScalePolicyVO policy = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Policy", policyId, _autoScalePolicyDao);
+
+        if (duration != null) {
+            policy.setDuration(duration);
+        }
+
+        if (quietTime != null) {
+            policy.setQuietTime(quietTime);
+        }
+
+        List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyList = _autoScaleVmGroupPolicyMapDao.listByPolicyId(policyId);
+        for (AutoScaleVmGroupPolicyMapVO vmGroupPolicy : vmGroupPolicyList) {
+            AutoScaleVmGroupVO vmGroupVO = _autoScaleVmGroupDao.findById(vmGroupPolicy.getVmGroupId());
+            if (vmGroupVO == null) {
+                s_logger.warn("Stale database entry! There is an entry in VmGroupPolicyMap but the vmGroup is missing:" + vmGroupPolicy.getVmGroupId());
+
+                continue;
+
+            }
+            if (!vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
+                throw new InvalidParameterValueException("The AutoScale Policy can be updated only if the Vm Group it is associated with is disabled in state");
+            }
+            if (policy.getDuration() < vmGroupVO.getInterval()) {
+                throw new InvalidParameterValueException("duration is less than the associated AutoScaleVmGroup's interval");
+            }
+        }
+
+        policy = checkValidityAndPersist(policy, conditionIds);
+        s_logger.info("Successfully updated Auto Scale Policy id:" + policyId);
+        return policy;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", create = true)
+    public AutoScaleVmGroup createAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) {
+        int minMembers = cmd.getMinMembers();
+        int maxMembers = cmd.getMaxMembers();
+        Integer interval = cmd.getInterval();
+        Boolean forDisplay = cmd.getDisplay();
+
+        if (interval == null) {
+            interval = NetUtils.DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME;
+        }
+
+        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, cmd.getLbRuleId(), _lbDao);
+
+        Long zoneId = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId()).getDataCenterId();
+
+        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancer.getId())) {
+            throw new InvalidParameterValueException("an AutoScaleVmGroup is already attached to the lb rule, the existing vm group has to be first deleted");
+        }
+
+        if (_lb2VmMapDao.isVmAttachedToLoadBalancer(loadBalancer.getId())) {
+            throw new InvalidParameterValueException(
+                "there are Vms already bound to the specified LoadBalancing Rule. User bound Vms and AutoScaled Vm Group cannot co-exist on a Load Balancing Rule");
+        }
+
+        AutoScaleVmGroupVO vmGroupVO = new AutoScaleVmGroupVO(cmd.getLbRuleId(), zoneId, loadBalancer.getDomainId(), loadBalancer.getAccountId(), minMembers, maxMembers,
+            loadBalancer.getDefaultPortStart(), interval, null, cmd.getProfileId(), AutoScaleVmGroup.State_New);
+
+        if (forDisplay != null) {
+            vmGroupVO.setDisplay(forDisplay);
+        }
+
+        vmGroupVO = checkValidityAndPersist(vmGroupVO, cmd.getScaleUpPolicyIds(), cmd.getScaleDownPolicyIds());
+        s_logger.info("Successfully created Autoscale Vm Group with Id: " + vmGroupVO.getId());
+
+        return vmGroupVO;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_CREATE, eventDescription = "creating autoscale vm group", async = true)
+    public boolean configureAutoScaleVmGroup(CreateAutoScaleVmGroupCmd cmd) throws ResourceUnavailableException {
+        return configureAutoScaleVmGroup(cmd.getEntityId(), AutoScaleVmGroup.State_New);
+    }
+
+    public boolean isLoadBalancerBasedAutoScaleVmGroup(AutoScaleVmGroup vmGroup) {
+        return vmGroup.getLoadBalancerId() != null;
+    }
+
+    private boolean configureAutoScaleVmGroup(long vmGroupid, String currentState) throws ResourceUnavailableException {
+        AutoScaleVmGroup vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
+
+        if (isLoadBalancerBasedAutoScaleVmGroup(vmGroup)) {
+            try {
+                return _lbRulesMgr.configureLbAutoScaleVmGroup(vmGroupid, currentState);
+            } catch (ResourceUnavailableException re) {
+                throw re;
+            } catch (Exception e) {
+                s_logger.warn("Exception during configureLbAutoScaleVmGroup in lb rules manager", e);
+                return false;
+            }
+        }
+
+        // This should never happen, because today loadbalancerruleid is manadatory for AutoScaleVmGroup.
+        throw new InvalidParameterValueException("Only LoadBalancer based AutoScale is supported");
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DELETE, eventDescription = "deleting autoscale vm group", async = true)
+    public boolean deleteAutoScaleVmGroup(final long id) {
+        AutoScaleVmGroupVO autoScaleVmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
+
+        if (autoScaleVmGroupVO.getState().equals(AutoScaleVmGroup.State_New)) {
+            /* This condition is for handling failures during creation command */
+            return _autoScaleVmGroupDao.remove(id);
+        }
+        String bakupState = autoScaleVmGroupVO.getState();
+        autoScaleVmGroupVO.setState(AutoScaleVmGroup.State_Revoke);
+        _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
+        boolean success = false;
+
+        try {
+            success = configureAutoScaleVmGroup(id, bakupState);
+        } catch (ResourceUnavailableException e) {
+            autoScaleVmGroupVO.setState(bakupState);
+            _autoScaleVmGroupDao.persist(autoScaleVmGroupVO);
+        } finally {
+            if (!success) {
+                s_logger.warn("Could not delete AutoScale Vm Group id : " + id);
+                return false;
+            }
+        }
+
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                boolean success = _autoScaleVmGroupDao.remove(id);
+
+                if (!success) {
+                    s_logger.warn("Failed to remove AutoScale Group db object");
+                    return false;
+                }
+
+                success = _autoScaleVmGroupPolicyMapDao.removeByGroupId(id);
+                if (!success) {
+                    s_logger.warn("Failed to remove AutoScale Group Policy mappings");
+                    return false;
+                }
+
+                s_logger.info("Successfully deleted autoscale vm group id : " + id);
+                return success; // Successfull
+            }
+        });
+
+    }
+
+    @Override
+    public List<? extends AutoScaleVmGroup> listAutoScaleVmGroups(ListAutoScaleVmGroupsCmd cmd) {
+        Long id = cmd.getId();
+        Long policyId = cmd.getPolicyId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        Long profileId = cmd.getProfileId();
+        Long zoneId = cmd.getZoneId();
+        Boolean forDisplay = cmd.getDisplay();
+
+        SearchWrapper<AutoScaleVmGroupVO> searchWrapper = new SearchWrapper<AutoScaleVmGroupVO>(_autoScaleVmGroupDao, AutoScaleVmGroupVO.class, cmd, cmd.getId());
+        SearchBuilder<AutoScaleVmGroupVO> sb = searchWrapper.getSearchBuilder();
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("loadBalancerId", sb.entity().getLoadBalancerId(), SearchCriteria.Op.EQ);
+        sb.and("profileId", sb.entity().getProfileId(), SearchCriteria.Op.EQ);
+        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
+
+        if (policyId != null) {
+            SearchBuilder<AutoScaleVmGroupPolicyMapVO> asVmGroupPolicySearch = _autoScaleVmGroupPolicyMapDao.createSearchBuilder();
+            asVmGroupPolicySearch.and("policyId", asVmGroupPolicySearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
+            sb.join("asVmGroupPolicySearch", asVmGroupPolicySearch, sb.entity().getId(), asVmGroupPolicySearch.entity().getVmGroupId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<AutoScaleVmGroupVO> sc = searchWrapper.buildSearchCriteria();
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+        if (loadBalancerId != null) {
+            sc.setParameters("loadBalancerId", loadBalancerId);
+        }
+        if (profileId != null) {
+            sc.setParameters("profileId", profileId);
+        }
+        if (zoneId != null) {
+            sc.setParameters("zoneId", zoneId);
+        }
+        if (policyId != null) {
+            sc.setJoinParameters("asVmGroupPolicySearch", "policyId", policyId);
+        }
+        if (forDisplay != null) {
+            sc.setParameters("display", forDisplay);
+        }
+        return searchWrapper.search();
+    }
+
+    @DB
+    protected AutoScaleVmGroupVO checkValidityAndPersist(final AutoScaleVmGroupVO vmGroup, final List<Long> passedScaleUpPolicyIds,
+        final List<Long> passedScaleDownPolicyIds) {
+        int minMembers = vmGroup.getMinMembers();
+        int maxMembers = vmGroup.getMaxMembers();
+        int interval = vmGroup.getInterval();
+        List<Counter> counters = new ArrayList<Counter>();
+        List<AutoScalePolicyVO> policies = new ArrayList<AutoScalePolicyVO>();
+        final List<Long> policyIds = new ArrayList<Long>();
+        List<Long> currentScaleUpPolicyIds = new ArrayList<Long>();
+        List<Long> currentScaleDownPolicyIds = new ArrayList<Long>();
+        if (vmGroup.getCreated() != null) {
+            ApiDBUtils.getAutoScaleVmGroupPolicyIds(vmGroup.getId(), currentScaleUpPolicyIds, currentScaleDownPolicyIds);
+        }
+
+        if (minMembers < 0) {
+            throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " is an invalid value: " + minMembers);
+        }
+
+        if (maxMembers < 0) {
+            throw new InvalidParameterValueException(ApiConstants.MAX_MEMBERS + " is an invalid value: " + maxMembers);
+        }
+
+        if (minMembers > maxMembers) {
+            throw new InvalidParameterValueException(ApiConstants.MIN_MEMBERS + " (" + minMembers + ")cannot be greater than " + ApiConstants.MAX_MEMBERS + " (" +
+                maxMembers + ")");
+        }
+
+        if (interval < 0) {
+            throw new InvalidParameterValueException("interval is an invalid value: " + interval);
+        }
+
+        if (passedScaleUpPolicyIds != null) {
+            policies.addAll(getAutoScalePolicies("scaleuppolicyid", passedScaleUpPolicyIds, counters, interval, true));
+            policyIds.addAll(passedScaleUpPolicyIds);
+        } else {
+            // Run the interval check for existing policies
+            getAutoScalePolicies("scaleuppolicyid", currentScaleUpPolicyIds, counters, interval, true);
+            policyIds.addAll(currentScaleUpPolicyIds);
+        }
+
+        if (passedScaleDownPolicyIds != null) {
+            policies.addAll(getAutoScalePolicies("scaledownpolicyid", passedScaleDownPolicyIds, counters, interval, false));
+            policyIds.addAll(passedScaleDownPolicyIds);
+        } else {
+            // Run the interval check for existing policies
+            getAutoScalePolicies("scaledownpolicyid", currentScaleDownPolicyIds, counters, interval, false);
+            policyIds.addAll(currentScaleDownPolicyIds);
+        }
+        AutoScaleVmProfileVO profileVO =
+            getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.VMPROFILE_ID, vmGroup.getProfileId(), _autoScaleVmProfileDao);
+
+        LoadBalancerVO loadBalancer = getEntityInDatabase(CallContext.current().getCallingAccount(), ApiConstants.LBID, vmGroup.getLoadBalancerId(), _lbDao);
+        validateAutoScaleCounters(loadBalancer.getNetworkId(), counters, profileVO.getCounterParams());
+
+        ControlledEntity[] sameOwnerEntities = policies.toArray(new ControlledEntity[policies.size() + 2]);
+        sameOwnerEntities[sameOwnerEntities.length - 2] = loadBalancer;
+        sameOwnerEntities[sameOwnerEntities.length - 1] = profileVO;
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEntities);
+
+        return Transaction.execute(new TransactionCallback<AutoScaleVmGroupVO>() {
+            @Override
+            public AutoScaleVmGroupVO doInTransaction(TransactionStatus status) {
+                AutoScaleVmGroupVO vmGroupNew = _autoScaleVmGroupDao.persist(vmGroup);
+
+                if (passedScaleUpPolicyIds != null || passedScaleDownPolicyIds != null) {
+                    _autoScaleVmGroupPolicyMapDao.removeByGroupId(vmGroupNew.getId());
+
+                    for (Long policyId : policyIds) {
+                        _autoScaleVmGroupPolicyMapDao.persist(new AutoScaleVmGroupPolicyMapVO(vmGroupNew.getId(), policyId));
+                    }
+                }
+
+                return vmGroupNew;
+            }
+        });
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_UPDATE, eventDescription = "updating autoscale vm group", async = true)
+    public AutoScaleVmGroup updateAutoScaleVmGroup(UpdateAutoScaleVmGroupCmd cmd) {
+        Long vmGroupId = cmd.getId();
+        Integer minMembers = cmd.getMinMembers();
+        Integer maxMembers = cmd.getMaxMembers();
+        Integer interval = cmd.getInterval();
+        Boolean forDisplay = cmd.getDisplay();
+
+        List<Long> scaleUpPolicyIds = cmd.getScaleUpPolicyIds();
+        List<Long> scaleDownPolicyIds = cmd.getScaleDownPolicyIds();
+
+        AutoScaleVmGroupVO vmGroupVO = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", vmGroupId, _autoScaleVmGroupDao);
+
+        boolean physicalParametersUpdate = (minMembers != null || maxMembers != null || interval != null);
+
+        if (physicalParametersUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State_Disabled)) {
+            throw new InvalidParameterValueException("An AutoScale Vm Group can be updated with minMembers/maxMembers/Interval only when it is in disabled state");
+        }
+
+        if (minMembers != null) {
+            vmGroupVO.setMinMembers(minMembers);
+        }
+
+        if (maxMembers != null) {
+            vmGroupVO.setMaxMembers(maxMembers);
+        }
+
+        if (maxMembers != null) {
+            vmGroupVO.setInterval(interval);
+        }
+
+        if (cmd.getCustomId() != null) {
+            vmGroupVO.setUuid(cmd.getCustomId());
+        }
+
+        if (forDisplay != null) {
+            vmGroupVO.setDisplay(forDisplay);
+        }
+
+        vmGroupVO = checkValidityAndPersist(vmGroupVO, scaleUpPolicyIds, scaleDownPolicyIds);
+        if (vmGroupVO != null) {
+            s_logger.debug("Updated Auto Scale VmGroup id:" + vmGroupId);
+            return vmGroupVO;
+        } else
+            return null;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_ENABLE, eventDescription = "enabling autoscale vm group", async = true)
+    public AutoScaleVmGroup enableAutoScaleVmGroup(Long id) {
+        AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
+        boolean success = false;
+        if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Disabled)) {
+            throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Disabled state can be enabled.");
+        }
+
+        try {
+            vmGroup.setState(AutoScaleVmGroup.State_Enabled);
+            vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
+            success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Disabled);
+        } catch (ResourceUnavailableException e) {
+            vmGroup.setState(AutoScaleVmGroup.State_Disabled);
+            _autoScaleVmGroupDao.persist(vmGroup);
+        } finally {
+            if (!success) {
+                s_logger.warn("Failed to enable AutoScale Vm Group id : " + id);
+                return null;
+            }
+            s_logger.info("Successfully enabled AutoScale Vm Group with Id:" + id);
+        }
+        return vmGroup;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_AUTOSCALEVMGROUP_DISABLE, eventDescription = "disabling autoscale vm group", async = true)
+    @DB
+    public AutoScaleVmGroup disableAutoScaleVmGroup(Long id) {
+        AutoScaleVmGroupVO vmGroup = getEntityInDatabase(CallContext.current().getCallingAccount(), "AutoScale Vm Group", id, _autoScaleVmGroupDao);
+        boolean success = false;
+        if (!vmGroup.getState().equals(AutoScaleVmGroup.State_Enabled)) {
+            throw new InvalidParameterValueException("Only a AutoScale Vm Group which is in Enabled state can be disabled.");
+        }
+
+        try {
+            vmGroup.setState(AutoScaleVmGroup.State_Disabled);
+            vmGroup = _autoScaleVmGroupDao.persist(vmGroup);
+            success = configureAutoScaleVmGroup(id, AutoScaleVmGroup.State_Enabled);
+        } catch (ResourceUnavailableException e) {
+            vmGroup.setState(AutoScaleVmGroup.State_Enabled);
+            _autoScaleVmGroupDao.persist(vmGroup);
+        } finally {
+            if (!success) {
+                s_logger.warn("Failed to disable AutoScale Vm Group id : " + id);
+                return null;
+            }
+            s_logger.info("Successfully disabled AutoScale Vm Group with Id:" + id);
+        }
+        return vmGroup;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_COUNTER_CREATE, eventDescription = "Counter", create = true)
+    @DB
+    public Counter createCounter(CreateCounterCmd cmd) {
+        String source = cmd.getSource().toLowerCase();
+        String name = cmd.getName();
+        Counter.Source src;
+        // Validate Source
+        try {
+            src = Counter.Source.valueOf(source);
+        } catch (Exception ex) {
+            throw new InvalidParameterValueException("The Source " + source + " does not exist; Unable to create Counter");
+        }
+
+        CounterVO counter = null;
+
+        s_logger.debug("Adding Counter " + name);
+        counter = _counterDao.persist(new CounterVO(src, name, cmd.getValue()));
+
+        CallContext.current().setEventDetails(" Id: " + counter.getId() + " Name: " + name);
+        return counter;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CONDITION_CREATE, eventDescription = "Condition", create = true)
+    public Condition createCondition(CreateConditionCmd cmd) {
+        checkCallerAccess(cmd.getAccountName(), cmd.getDomainId());
+        String opr = cmd.getRelationalOperator().toUpperCase();
+        long cid = cmd.getCounterId();
+        long threshold = cmd.getThreshold();
+        Condition.Operator op;
+        // Validate Relational Operator
+        try {
+            op = Condition.Operator.valueOf(opr);
+        } catch (IllegalArgumentException ex) {
+            throw new InvalidParameterValueException("The Operator " + opr + " does not exist; Unable to create Condition.");
+        }
+        // TODO - Validate threshold
+
+        CounterVO counter = _counterDao.findById(cid);
+
+        if (counter == null) {
+            throw new InvalidParameterValueException("Unable to find counter");
+        }
+        ConditionVO condition = null;
+
+        condition = _conditionDao.persist(new ConditionVO(cid, threshold, cmd.getEntityOwnerId(), cmd.getDomainId(), op));
+        s_logger.info("Successfully created condition with Id: " + condition.getId());
+
+        CallContext.current().setEventDetails(" Id: " + condition.getId());
+        return condition;
+    }
+
+    @Override
+    public List<? extends Counter> listCounters(ListCountersCmd cmd) {
+        String name = cmd.getName();
+        Long id = cmd.getId();
+        String source = cmd.getSource();
+        if (source != null)
+            source = source.toLowerCase();
+
+        Filter searchFilter = new Filter(CounterVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        List<CounterVO> counters = _counterDao.listCounters(id, name, source, cmd.getKeyword(), searchFilter);
+
+        return counters;
+    }
+
+    @Override
+    public List<? extends Condition> listConditions(ListConditionsCmd cmd) {
+        Long id = cmd.getId();
+        Long counterId = cmd.getCounterId();
+        Long policyId = cmd.getPolicyId();
+        SearchWrapper<ConditionVO> searchWrapper = new SearchWrapper<ConditionVO>(_conditionDao, ConditionVO.class, cmd, cmd.getId());
+        SearchBuilder<ConditionVO> sb = searchWrapper.getSearchBuilder();
+        if (policyId != null) {
+            SearchBuilder<AutoScalePolicyConditionMapVO> asPolicyConditionSearch = _autoScalePolicyConditionMapDao.createSearchBuilder();
+            asPolicyConditionSearch.and("policyId", asPolicyConditionSearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
+            sb.join("asPolicyConditionSearch", asPolicyConditionSearch, sb.entity().getId(), asPolicyConditionSearch.entity().getConditionId(),
+                JoinBuilder.JoinType.INNER);
+        }
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("counterId", sb.entity().getCounterid(), SearchCriteria.Op.EQ);
+
+        // now set the SC criteria...
+        SearchCriteria<ConditionVO> sc = searchWrapper.buildSearchCriteria();
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (counterId != null) {
+            sc.setParameters("counterId", counterId);
+        }
+
+        if (policyId != null) {
+            sc.setJoinParameters("asPolicyConditionSearch", "policyId", policyId);
+        }
+
+        return searchWrapper.search();
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_COUNTER_DELETE, eventDescription = "counter")
+    public boolean deleteCounter(long counterId) throws ResourceInUseException {
+        // Verify Counter id
+        CounterVO counter = _counterDao.findById(counterId);
+        if (counter == null) {
+            throw new InvalidParameterValueException("Unable to find Counter");
+        }
+
+        // Verify if it is used in any Condition
+
+        ConditionVO condition = _conditionDao.findByCounterId(counterId);
+        if (condition != null) {
+            s_logger.info("Cannot delete counter " + counter.getName() + " as it is being used in a condition.");
+            throw new ResourceInUseException("Counter is in use.");
+        }
+
+        boolean success = _counterDao.remove(counterId);
+        if (success) {
+            s_logger.info("Successfully deleted counter with Id: " + counterId);
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CONDITION_DELETE, eventDescription = "condition")
+    public boolean deleteCondition(long conditionId) throws ResourceInUseException {
+        /* Check if entity is in database */
+        ConditionVO condition = getEntityInDatabase(CallContext.current().getCallingAccount(), "Condition", conditionId, _conditionDao);
+        if (condition == null) {
+            throw new InvalidParameterValueException("Unable to find Condition");
+        }
+
+        // Verify if condition is used in any autoscale policy
+        if (_autoScalePolicyConditionMapDao.isConditionInUse(conditionId)) {
+            s_logger.info("Cannot delete condition " + conditionId + " as it is being used in a condition.");
+            throw new ResourceInUseException("Cannot delete Condition when it is in use by one or more AutoScale Policies.");
+        }
+        boolean success = _conditionDao.remove(conditionId);
+        if (success) {
+            s_logger.info("Successfully deleted condition " + condition.getId());
+        }
+        return success;
+    }
+
+    @Override
+    public void cleanUpAutoScaleResources(Long accountId) {
+        // cleans Autoscale VmProfiles, AutoScale Policies and Conditions belonging to an account
+        int count = 0;
+        count = _autoScaleVmProfileDao.removeByAccountId(accountId);
+        if (count > 0) {
+            s_logger.debug("Deleted " + count + " AutoScale Vm Profile for account Id: " + accountId);
+        }
+        count = _autoScalePolicyDao.removeByAccountId(accountId);
+        if (count > 0) {
+            s_logger.debug("Deleted " + count + " AutoScale Policies for account Id: " + accountId);
+        }
+        count = _conditionDao.removeByAccountId(accountId);
+        if (count > 0) {
+            s_logger.debug("Deleted " + count + " Conditions for account Id: " + accountId);
+        }
+    }
+
+    private boolean checkConditionUp(AutoScaleVmGroupVO asGroup, Integer numVm) {
+        // check maximum
+        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
+        Integer maxVm = asGroup.getMaxMembers();
+        if (currentVM + numVm > maxVm) {
+            s_logger.warn("number of VM will greater than the maximum in this group if scaling up, so do nothing more");
+            return false;
+        }
+        return true;
+    }
+
+    private boolean checkConditionDown(AutoScaleVmGroupVO asGroup) {
+        Integer currentVM = _autoScaleVmGroupVmMapDao.countByGroup(asGroup.getId());
+        Integer minVm = asGroup.getMinMembers();
+        if (currentVM - 1 < minVm) {
+            s_logger.warn("number of VM will less than the minimum in this group if scaling down, so do nothing more");
+            return false;
+        }
+        return true;
+    }
+
+    private long createNewVM(AutoScaleVmGroupVO asGroup) {
+        AutoScaleVmProfileVO profileVo = _autoScaleVmProfileDao.findById(asGroup.getProfileId());
+        long templateId = profileVo.getTemplateId();
+        long serviceOfferingId = profileVo.getServiceOfferingId();
+        if (templateId == -1) {
+            return -1;
+        }
+        // create new VM into DB
+        try {
+            //Verify that all objects exist before passing them to the service
+            Account owner = _accountService.getActiveAccountById(profileVo.getAccountId());
+
+            DataCenter zone = _entityMgr.findById(DataCenter.class, profileVo.getZoneId());
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find zone by id=" + profileVo.getZoneId());
+            }
+
+            ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+            if (serviceOffering == null) {
+                throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+            }
+
+            VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+            // Make sure a valid template ID was specified
+            if (template == null) {
+                throw new InvalidParameterValueException("Unable to use template " + templateId);
+            }
+
+            if (!zone.isLocalStorageEnabled()) {
+                if (serviceOffering.isUseLocalStorage()) {
+                    throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
+                }
+            }
+
+            UserVm vm = null;
+            IpAddresses addrs = new IpAddresses(null, null);
+            if (zone.getNetworkType() == NetworkType.Basic) {
+                vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
+                    getCurrentTimeStampString(),
+                    "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null,
+                    null, true, null, null, null, null, null, null);
+            } else {
+                if (zone.isSecurityGroupEnabled()) {
+                    vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, null, null,
+                        owner, "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
+                        "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(), null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null,
+                        null, null, true, null, null, null, null, null, null);
+
+                } else {
+                    vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, null, owner, "autoScaleVm-" + asGroup.getId() + "-" +
+                        getCurrentTimeStampString(), "autoScaleVm-" + asGroup.getId() + "-" + getCurrentTimeStampString(),
+                        null, null, null, HypervisorType.XenServer, HTTPMethod.GET, null, null, null, addrs, true, null, null, null, null, null, null);
+
+                }
+            }
+
+            if (vm != null) {
+                return vm.getId();
+            } else {
+                return -1;
+            }
+        } catch (InsufficientCapacityException ex) {
+            s_logger.info(ex);
+            s_logger.trace(ex.getMessage(), ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (ResourceAllocationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
+        }
+    }
+
+    private String getCurrentTimeStampString() {
+        Date current = new Date();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+        return sdf.format(current);
+    }
+
+    private boolean startNewVM(long vmId) {
+        try {
+            CallContext.current().setEventDetails("Vm Id: " + vmId);
+            _userVmManager.startVirtualMachine(vmId, null, null, null);
+        } catch (final ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        } catch (InsufficientCapacityException ex) {
+            StringBuilder message = new StringBuilder(ex.getMessage());
+            if (ex instanceof InsufficientServerCapacityException) {
+                if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
+                    message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
+                }
+            }
+            s_logger.info(ex);
+            s_logger.info(message.toString(), ex);
+            throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
+        }
+        return true;
+    }
+
+    private boolean assignLBruleToNewVm(long vmId, AutoScaleVmGroupVO asGroup) {
+        List<Long> lstVmId = new ArrayList<Long>();
+        long lbId = asGroup.getLoadBalancerId();
+
+        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
+        if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
+            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
+                long instanceId = LbVmMapVo.getInstanceId();
+                if (instanceId == vmId) {
+                    s_logger.warn("the new VM is already mapped to LB rule. What's wrong?");
+                    return true;
+                }
+            }
+        }
+        lstVmId.add(new Long(vmId));
+        return _loadBalancingRulesService.assignToLoadBalancer(lbId, lstVmId, new HashMap<Long, List<String>>());
+
+    }
+
+    private long removeLBrule(AutoScaleVmGroupVO asGroup) {
+        long lbId = asGroup.getLoadBalancerId();
+        long instanceId = -1;
+        List<LoadBalancerVMMapVO> LbVmMapVos = _lbVmMapDao.listByLoadBalancerId(lbId);
+        if ((LbVmMapVos != null) && (LbVmMapVos.size() > 0)) {
+            for (LoadBalancerVMMapVO LbVmMapVo : LbVmMapVos) {
+                instanceId = LbVmMapVo.getInstanceId();
+            }
+        }
+        // take last VM out of the list
+        List<Long> lstVmId = new ArrayList<Long>();
+        if (instanceId != -1)
+            lstVmId.add(instanceId);
+        if (_loadBalancingRulesService.removeFromLoadBalancer(lbId, lstVmId, new HashMap<Long, List<String>>()))
+            return instanceId;
+        else
+            return -1;
+    }
+
+    @Override
+    public void doScaleUp(long groupId, Integer numVm) {
+        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
+        if (asGroup == null) {
+            s_logger.error("Can not find the groupid " + groupId + " for scaling up");
+            return;
+        }
+        if (!checkConditionUp(asGroup, numVm)) {
+            return;
+        }
+        for (int i = 0; i < numVm; i++) {
+            long vmId = createNewVM(asGroup);
+            if (vmId == -1) {
+                s_logger.error("Can not deploy new VM for scaling up in the group "
+                    + asGroup.getId() + ". Waiting for next round");
+                break;
+            }
+            if (startNewVM(vmId)) {
+                if (assignLBruleToNewVm(vmId, asGroup)) {
+                    // persist to DB
+                    AutoScaleVmGroupVmMapVO GroupVmVO = new AutoScaleVmGroupVmMapVO(
+                        asGroup.getId(), vmId);
+                    _autoScaleVmGroupVmMapDao.persist(GroupVmVO);
+                    // update last_quiettime
+                    List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao
+                        .listByVmGroupId(groupId);
+                    for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
+                        AutoScalePolicyVO vo = _autoScalePolicyDao
+                            .findById(GroupPolicyVO.getPolicyId());
+                        if (vo.getAction().equals("scaleup")) {
+                            vo.setLastQuiteTime(new Date());
+                            _autoScalePolicyDao.persist(vo);
+                            break;
+                        }
+                    }
+                } else {
+                    s_logger.error("Can not assign LB rule for this new VM");
+                    break;
+                }
+            } else {
+                s_logger.error("Can not deploy new VM for scaling up in the group "
+                    + asGroup.getId() + ". Waiting for next round");
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void doScaleDown(final long groupId) {
+        AutoScaleVmGroupVO asGroup = _autoScaleVmGroupDao.findById(groupId);
+        if (asGroup == null) {
+            s_logger.error("Can not find the groupid " + groupId + " for scaling down");
+            return;
+        }
+        if (!checkConditionDown(asGroup)) {
+            return;
+        }
+        final long vmId = removeLBrule(asGroup);
+        if (vmId != -1) {
+            long profileId = asGroup.getProfileId();
+
+            // update group-vm mapping
+            _autoScaleVmGroupVmMapDao.remove(groupId, vmId);
+            // update last_quiettime
+            List<AutoScaleVmGroupPolicyMapVO> GroupPolicyVOs = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(groupId);
+            for (AutoScaleVmGroupPolicyMapVO GroupPolicyVO : GroupPolicyVOs) {
+                AutoScalePolicyVO vo = _autoScalePolicyDao.findById(GroupPolicyVO.getPolicyId());
+                if (vo.getAction().equals("scaledown")) {
+                    vo.setLastQuiteTime(new Date());
+                    _autoScalePolicyDao.persist(vo);
+                    break;
+                }
+            }
+
+            // get destroyvmgrace param
+            AutoScaleVmProfileVO asProfile = _autoScaleVmProfileDao.findById(profileId);
+            Integer destroyVmGracePeriod = asProfile.getDestroyVmGraceperiod();
+            if (destroyVmGracePeriod >= 0) {
+                _executor.schedule(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+
+                            _userVmManager.destroyVm(vmId, false);
+
+                        } catch (ResourceUnavailableException e) {
+                            e.printStackTrace();
+                        } catch (ConcurrentOperationException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }, destroyVmGracePeriod, TimeUnit.SECONDS);
+            }
+        } else {
+            s_logger.error("Can not remove LB rule for the VM being destroyed. Do nothing more.");
+        }
+    }
+
+}
diff --git a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java
similarity index 100%
rename from server/src/com/cloud/network/element/CloudZonesNetworkElement.java
rename to server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java
diff --git a/server/src/com/cloud/network/element/ConfigDriveNetworkElement.java b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
similarity index 100%
rename from server/src/com/cloud/network/element/ConfigDriveNetworkElement.java
rename to server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
diff --git a/server/src/com/cloud/network/element/SecurityGroupElement.java b/server/src/main/java/com/cloud/network/element/SecurityGroupElement.java
similarity index 100%
rename from server/src/com/cloud/network/element/SecurityGroupElement.java
rename to server/src/main/java/com/cloud/network/element/SecurityGroupElement.java
diff --git a/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java
new file mode 100644
index 0000000..b78dcfd
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java
@@ -0,0 +1,1344 @@
+// 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.network.element;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import com.google.gson.Gson;
+
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.network.topology.NetworkTopology;
+import org.apache.cloudstack.network.topology.NetworkTopologyContext;
+
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkMigrationResponder;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.OvsProvider;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.VirtualRouterProvider.Type;
+import com.cloud.network.VpnUser;
+import com.cloud.network.as.AutoScaleCounter;
+import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkDetailVO;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.dao.OvsProviderDao;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.NetworkHelper;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.LbStickinessMethod;
+import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
+import com.cloud.network.rules.LoadBalancerContainer;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+
+public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
+StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
+NetworkMigrationResponder, AggregatedCommandExecutor, RedundantResource, DnsServiceProvider {
+    private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
+    public static final AutoScaleCounterType AutoScaleCounterCpu = new AutoScaleCounterType("cpu");
+    public static final AutoScaleCounterType AutoScaleCounterMemory = new AutoScaleCounterType("memory");
+    protected static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
+
+    @Inject
+    NetworkDao _networksDao;
+    @Inject
+    NetworkModel _networkMdl;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+
+    @Inject
+    VpcVirtualNetworkApplianceManager _routerMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    RulesManager _rulesMgr;
+    @Inject
+    UserVmManager _userVmMgr;
+
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    DomainRouterDao _routerDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    VirtualRouterProviderDao _vrProviderDao;
+    @Inject
+    OvsProviderDao _ovsProviderDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    NetworkModel _networkModel;
+
+    @Inject
+    NetworkTopologyContext networkTopologyContext;
+
+    @Inject
+    NetworkDetailsDao _networkDetailsDao;
+
+    @Inject
+    protected RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder;
+
+    @Autowired
+    @Qualifier("networkHelper")
+    protected NetworkHelper _networkHelper;
+
+    protected boolean canHandle(final Network network, final Service service) {
+        final Long physicalNetworkId = _networkMdl.getPhysicalNetworkId(network);
+        if (physicalNetworkId == null) {
+            return false;
+        }
+
+        if (network.getVpcId() != null) {
+            return false;
+        }
+
+        if (!_networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())) {
+            return false;
+        }
+
+        if (service == null) {
+            if (!_networkMdl.isProviderForNetwork(getProvider(), network.getId())) {
+                s_logger.trace("Element " + getProvider().getName() + " is not a provider for the network " + network);
+                return false;
+            }
+        } else {
+            if (!_networkMdl.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
+                s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context)
+            throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+
+        if (offering.isSystemOnly()) {
+            return false;
+        }
+
+        final Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
+        params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
+
+        if (network.isRollingRestart()) {
+            params.put(VirtualMachineProfile.Param.RollingRestart, true);
+        }
+
+        final RouterDeploymentDefinition routerDeploymentDefinition =
+                routerDeploymentDefinitionBuilder.create()
+                .setGuestNetwork(network)
+                .setDeployDestination(dest)
+                .setAccountOwner(_accountMgr.getAccount(network.getAccountId()))
+                .setParams(params)
+                .build();
+
+        final List<DomainRouterVO> routers = routerDeploymentDefinition.deployVirtualRouter();
+
+        int expectedRouters = 1;
+        if (offering.isRedundantRouter() || network.isRollingRestart()) {
+            expectedRouters = 2;
+        }
+        if (routers == null || routers.size() < expectedRouters) {
+            //we might have a router which is already deployed and running.
+            //so check the no of routers in network currently.
+            List<DomainRouterVO> current_routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (current_routers.size() < 2) {
+                updateToFailedState(network);
+                throw new ResourceUnavailableException("Can't find all necessary running routers!", DataCenter.class, network.getDataCenterId());
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean prepare(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
+            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) {
+            return false;
+        }
+
+        if (!canHandle(network, null)) {
+            return false;
+        }
+
+        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if (offering.isSystemOnly()) {
+            return false;
+        }
+        if (!_networkMdl.isProviderEnabledInPhysicalNetwork(_networkMdl.getPhysicalNetworkId(network), getProvider().getName())) {
+            return false;
+        }
+
+        final RouterDeploymentDefinition routerDeploymentDefinition =
+                routerDeploymentDefinitionBuilder.create()
+                .setGuestNetwork(network)
+                .setDeployDestination(dest)
+                .setAccountOwner(_accountMgr.getAccount(network.getAccountId()))
+                .setParams(vm.getParameters())
+                .build();
+
+        final List<DomainRouterVO> routers = routerDeploymentDefinition.deployVirtualRouter();
+
+        if (routers == null || routers.size() == 0) {
+            throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean applyFWRules(final Network network, final List<? extends FirewallRule> rules) throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.Firewall)) {
+            final List<DomainRouterVO> routers = getRouters(network);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
+                return true;
+            }
+
+            if (rules != null && rules.size() == 1) {
+                // for VR no need to add default egress rule to ALLOW traffic
+                //The default allow rule is added from the router defalut iptables rules iptables-router
+                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System
+                        && _networkMdl.getNetworkEgressDefaultPolicy(network.getId())) {
+                    return true;
+                }
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean validateLBRule(final Network network, final LoadBalancingRule rule) {
+        final List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
+        rules.add(rule);
+        if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                return true;
+            }
+            return _networkHelper.validateHAProxyLBRule(rule);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules) throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.Lb)) {
+            if (!canHandleLbRules(rules)) {
+                return false;
+            }
+
+            final List<DomainRouterVO> routers = getRouters(network);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply lb rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String[] applyVpnUsers(final RemoteAccessVpn vpn, final List<? extends VpnUser> users) throws ResourceUnavailableException {
+        if (vpn.getNetworkId() == null) {
+            return null;
+        }
+
+        final Network network = _networksDao.findById(vpn.getNetworkId());
+        if (canHandle(network, Service.Vpn)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + " doesn't exist in the network " + network.getId());
+                return null;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            return networkTopology.applyVpnUsers(network, users, routers);
+        } else {
+            s_logger.debug("Element " + getName() + " doesn't handle applyVpnUsers command");
+            return null;
+        }
+    }
+
+    @Override
+    public boolean startVpn(final RemoteAccessVpn vpn) throws ResourceUnavailableException {
+        if (vpn.getNetworkId() == null) {
+            return false;
+        }
+
+        final Network network = _networksDao.findById(vpn.getNetworkId());
+        if (canHandle(network, Service.Vpn)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't" + " exist in the network " + network.getId());
+                return true;
+            }
+            return _routerMgr.startRemoteAccessVpn(network, vpn, routers);
+        } else {
+            s_logger.debug("Element " + getName() + " doesn't handle createVpn command");
+            return false;
+        }
+    }
+
+    @Override
+    public boolean stopVpn(final RemoteAccessVpn vpn) throws ResourceUnavailableException {
+        if (vpn.getNetworkId() == null) {
+            return false;
+        }
+
+        final Network network = _networksDao.findById(vpn.getNetworkId());
+        if (canHandle(network, Service.Vpn)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + "exist in the network " + network.getId());
+                return true;
+            }
+            return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers);
+        } else {
+            s_logger.debug("Element " + getName() + " doesn't handle removeVpn command");
+            return false;
+        }
+    }
+
+    @Override
+    public boolean applyIps(final Network network, final List<? extends PublicIpAddress> ipAddress, final Set<Service> services) throws ResourceUnavailableException {
+        boolean canHandle = true;
+        for (final Service service : services) {
+            if (!canHandle(network, service)) {
+                canHandle = false;
+                break;
+            }
+        }
+        boolean result = true;
+        if (canHandle) {
+            final List<DomainRouterVO> routers = getRouters(network);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + "router doesn't exist in the network " + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Provider getProvider() {
+        return Provider.VirtualRouter;
+    }
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        return capabilities;
+    }
+
+    public static String getHAProxyStickinessCapability() {
+        LbStickinessMethod method;
+        final List<LbStickinessMethod> methodList = new ArrayList<LbStickinessMethod>(1);
+
+        method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method.");
+        method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false);
+        method.addParam("mode", false, "Valid values: insert, rewrite, prefix. Default value: insert.  In the insert mode cookie will be created"
+                + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false);
+        method.addParam("nocache", false, "This option is recommended in conjunction with the insert mode when there is a cache between the client"
+                + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if  a cookie needs "
+                + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page"
+                + " for instance, then all customers will then fetch the page from an outer cache and will all share the "
+                + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + "insert and postonly options. ", true);
+        method.addParam("indirect", false, "When this option is specified in insert mode, cookies will only be added when the server was not reached"
+                + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm,"
+                + " or after a redispatch, then the cookie  will be inserted. If the client has all the required information"
+                + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the "
+                + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to "
+                + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true);
+        method.addParam("postonly", false, "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an"
+                + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the "
+                + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the"
+                + " first POST which generally is a login request, this is a very efficient method to optimize caching "
+                + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true);
+        method.addParam("domain", false, "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:"
+                + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host "
+                + "ending with that name. It is also possible to specify several domain names by invoking this option multiple"
+                + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. "
+                + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false);
+        methodList.add(method);
+
+        method = new LbStickinessMethod(StickinessMethodType.AppCookieBased,
+                "This is App session based sticky method. Define session stickiness on an existing application cookie. " + "It can be used only for a specific http traffic");
+        method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will "
+                + "have to learn for each new session. Default value: Auto geneared based on ip", false);
+        method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + "each cookie value. Default value:52", false);
+        method.addParam("holdtime", false, "This is the time after which the cookie will be removed from memory if unused. The value should be in "
+                + "the format Example : 20s or 30m  or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid,"
+                + " cannot use th combinations like 20h30m. Default value:3h ", false);
+        method.addParam(
+                "request-learn",
+                false,
+                "If this option is specified, then haproxy will be able to learn the cookie found in the request in case the server does not specify any in response. This is typically what happens with PHPSESSID cookies, or when haproxy's session expires before the application's session and the correct server is selected. It is recommended to specify this option to improve reliability",
+                true);
+        method.addParam(
+                "prefix",
+                false,
+                "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). "
+                        + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix  This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.",
+                        true);
+        method.addParam("mode", false, "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters "
+                + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), "
+                + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :"
+                + " In this mode, the parser will look for the appsession in the query string.", false);
+        methodList.add(method);
+
+        method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + "it can be used for any type of protocol.");
+        method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + " or 400g. Default value:200k", false);
+        method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ."
+                + " example: expire=30m 20s 50h 4d. Default value:3h", false);
+        methodList.add(method);
+
+        final Gson gson = new Gson();
+        final String capability = gson.toJson(methodList);
+        return capability;
+    }
+
+    private static Map<Service, Map<Capability, String>> setCapabilities() {
+        final Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+
+        // Set capabilities for LB service
+        final Map<Capability, String> lbCapabilities = new HashMap<Capability, String>();
+        lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,source");
+        lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated");
+        lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp, tcp-proxy");
+        lbCapabilities.put(Capability.SupportedStickinessMethods, getHAProxyStickinessCapability());
+        lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString());
+
+        // specifies that LB rules can support autoscaling and the list of
+        // counters it supports
+        AutoScaleCounter counter;
+        final List<AutoScaleCounter> counterList = new ArrayList<AutoScaleCounter>();
+        counter = new AutoScaleCounter(AutoScaleCounterCpu);
+        counterList.add(counter);
+        counter = new AutoScaleCounter(AutoScaleCounterMemory);
+        counterList.add(counter);
+        final Gson gson = new Gson();
+        final String autoScaleCounterList = gson.toJson(counterList);
+        lbCapabilities.put(Capability.AutoScaleCounters, autoScaleCounterList);
+        capabilities.put(Service.Lb, lbCapabilities);
+
+        // Set capabilities for Firewall service
+        final Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
+        firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
+        firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
+        firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all");
+        firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
+        firewallCapabilities.put(Capability.MultipleIps, "true");
+        capabilities.put(Service.Firewall, firewallCapabilities);
+
+        // Set capabilities for vpn
+        final Map<Capability, String> vpnCapabilities = new HashMap<Capability, String>();
+        vpnCapabilities.put(Capability.SupportedVpnProtocols, "pptp,l2tp,ipsec");
+        vpnCapabilities.put(Capability.VpnTypes, "removeaccessvpn");
+        capabilities.put(Service.Vpn, vpnCapabilities);
+
+        final Map<Capability, String> dnsCapabilities = new HashMap<Capability, String>();
+        dnsCapabilities.put(Capability.AllowDnsSuffixModification, "true");
+        capabilities.put(Service.Dns, dnsCapabilities);
+
+        capabilities.put(Service.UserData, null);
+
+        final Map<Capability, String> dhcpCapabilities = new HashMap<Capability, String>();
+        dhcpCapabilities.put(Capability.DhcpAccrossMultipleSubnets, "true");
+        capabilities.put(Service.Dhcp, dhcpCapabilities);
+
+        capabilities.put(Service.Gateway, null);
+
+        final Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
+        sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
+        sourceNatCapabilities.put(Capability.RedundantRouter, "true");
+        capabilities.put(Service.SourceNat, sourceNatCapabilities);
+
+        capabilities.put(Service.StaticNat, null);
+
+        final Map<Capability, String> portForwardingCapabilities = new HashMap<Capability, String>();
+        portForwardingCapabilities.put(Capability.SupportedProtocols, NetUtils.TCP_PROTO + "," + NetUtils.UDP_PROTO);
+        capabilities.put(Service.PortForwarding, portForwardingCapabilities);
+
+        return capabilities;
+    }
+
+    @Override
+    public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules) throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.StaticNat)) {
+            final List<DomainRouterVO> routers = getRouters(network);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + "router doesn't exist in the network " + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    public List<DomainRouterVO> getRouters(Network network){
+        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers !=null && routers.isEmpty()) {
+            return null;
+        }
+        NetworkDetailVO updateInSequence=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
+        if(network.isRedundant() && updateInSequence!=null && "true".equalsIgnoreCase(updateInSequence.getValue())){
+            List<DomainRouterVO> masterRouters=new ArrayList<DomainRouterVO>();
+            int noOfrouters=routers.size();
+            while (noOfrouters>0){
+                DomainRouterVO router = routers.get(0);
+                if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_IN_PROGRESS){
+                    ArrayList<DomainRouterVO> routerList = new ArrayList<DomainRouterVO>();
+                    routerList.add(router);
+                    return routerList;
+                }
+                if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_COMPLETE) {
+                    routers.remove(router);
+                    noOfrouters--;
+                    continue;
+                }
+                if(router.getRedundantState()!=VirtualRouter.RedundantState.BACKUP) {
+                    masterRouters.add(router);
+                    routers.remove(router);
+                }
+                noOfrouters--;
+            }
+            if(routers.size()==0 && masterRouters.size()==0){
+                return null;
+            }
+            if(routers.size()==0 && masterRouters.size()!=0){
+                routers=masterRouters;
+            }
+            routers=routers.subList(0,1);
+            routers.get(0).setUpdateState(VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
+            _routerDao.persist(routers.get(0));
+        }
+        return routers;
+    }
+
+    @Override
+    public boolean shutdown(final Network network, final ReservationContext context, final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+        final List<DomainRouterVO> routers = getRouters(network);
+        if (routers == null || routers.isEmpty()) {
+            return true;
+        }
+        boolean stopResult = true;
+        boolean destroyResult = true;
+        for (final DomainRouterVO router : routers) {
+            stopResult = stopResult && _routerMgr.stop(router, false, context.getCaller(), context.getAccount()) != null;
+            if (!stopResult) {
+                s_logger.warn("Failed to stop virtual router element " + router + ", but would try to process clean up anyway.");
+            }
+            if (cleanup) {
+                destroyResult = destroyResult && _routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null;
+                if (!destroyResult) {
+                    s_logger.warn("Failed to clean up virtual router element " + router);
+                }
+            }
+        }
+        return stopResult & destroyResult;
+    }
+
+    @Override
+    public boolean destroy(final Network config, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            return true;
+        }
+        boolean result = true;
+        // NOTE that we need to pass caller account to destroyRouter, otherwise
+        // it will fail permission check there. Context passed in from
+        // deleteNetwork is the network account,
+        // not caller account
+        final Account callerAccount = _accountMgr.getAccount(context.getCaller().getAccountId());
+        for (final DomainRouterVO router : routers) {
+            result = result && _routerMgr.destroyRouter(router.getId(), callerAccount, context.getCaller().getId()) != null;
+        }
+        return result;
+    }
+
+    @Override
+    public boolean savePassword(final Network network, final NicProfile nic, final VirtualMachineProfile vm) throws ResourceUnavailableException {
+        if (!canHandle(network, null)) {
+            return false;
+        }
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            s_logger.debug("Can't find virtual router element in network " + network.getId());
+            return true;
+        }
+
+        final VirtualMachineProfile uservm = vm;
+
+        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+        // If any router is running then send save password command otherwise
+        // save the password in DB
+        for (final VirtualRouter router : routers) {
+            if (router.getState() == State.Running) {
+                final boolean result = networkTopology.savePasswordToRouter(network, nic, uservm, router);
+                if (result) {
+                    // Explicit password reset, while VM hasn't generated a password yet.
+                    final UserVmVO userVmVO = _userVmDao.findById(vm.getId());
+                    userVmVO.setUpdateParameters(false);
+                    _userVmDao.update(userVmVO.getId(), userVmVO);
+                }
+                return result;
+            }
+        }
+        final String password = (String) uservm.getParameter(VirtualMachineProfile.Param.VmPassword);
+        final String password_encrypted = DBEncryptionUtil.encrypt(password);
+        final UserVmVO userVmVO = _userVmDao.findById(vm.getId());
+
+        _userVmDao.loadDetails(userVmVO);
+        userVmVO.setDetail("password", password_encrypted);
+        _userVmDao.saveDetails(userVmVO);
+
+        userVmVO.setUpdateParameters(true);
+        _userVmDao.update(userVmVO.getId(), userVmVO);
+
+        return true;
+    }
+
+    @Override
+    public boolean saveSSHKey(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final String sshPublicKey) throws ResourceUnavailableException {
+        if (!canHandle(network, null)) {
+            return false;
+        }
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            s_logger.debug("Can't find virtual router element in network " + network.getId());
+            return true;
+        }
+
+        final VirtualMachineProfile uservm = vm;
+
+        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+        boolean result = true;
+        for (final DomainRouterVO domainRouterVO : routers) {
+            result = result && networkTopology.saveSSHPublicKeyToRouter(network, nic, uservm, domainRouterVO, sshPublicKey);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean saveUserData(final Network network, final NicProfile nic, final VirtualMachineProfile vm) throws ResourceUnavailableException {
+        if (!canHandle(network, null)) {
+            return false;
+        }
+        final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+        if (routers == null || routers.isEmpty()) {
+            s_logger.debug("Can't find virtual router element in network " + network.getId());
+            return true;
+        }
+
+        final VirtualMachineProfile uservm = vm;
+
+        final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+        final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+        boolean result = true;
+        for (final DomainRouterVO domainRouterVO : routers) {
+            result = result && networkTopology.saveUserDataToRouter(network, nic, uservm, domainRouterVO);
+        }
+        return result;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateVirtualRouterElementCmd.class);
+        cmdList.add(ConfigureVirtualRouterElementCmd.class);
+        cmdList.add(ListVirtualRouterElementsCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    public VirtualRouterProvider configure(final ConfigureVirtualRouterElementCmd cmd) {
+        final VirtualRouterProviderVO element = _vrProviderDao.findById(cmd.getId());
+        if (element == null || !(element.getType() == Type.VirtualRouter || element.getType() == Type.VPCVirtualRouter)) {
+            s_logger.debug("Can't find Virtual Router element with network service provider id " + cmd.getId());
+            return null;
+        }
+
+        element.setEnabled(cmd.getEnabled());
+        _vrProviderDao.persist(element);
+
+        return element;
+    }
+
+    @Override
+    public OvsProvider configure(final ConfigureOvsElementCmd cmd) {
+        final OvsProviderVO element = _ovsProviderDao.findById(cmd.getId());
+        if (element == null) {
+            s_logger.debug("Can't find Ovs element with network service provider id " + cmd.getId());
+            return null;
+        }
+
+        element.setEnabled(cmd.getEnabled());
+        _ovsProviderDao.persist(element);
+
+        return element;
+    }
+
+    @Override
+    public VirtualRouterProvider addElement(final Long nspId, final Type providerType) {
+        if (!(providerType == Type.VirtualRouter || providerType == Type.VPCVirtualRouter)) {
+            throw new InvalidParameterValueException("Element " + getName() + " supports only providerTypes: " + Type.VirtualRouter.toString() + " and " + Type.VPCVirtualRouter);
+        }
+        VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType);
+        if (element != null) {
+            s_logger.debug("There is already a virtual router element with service provider id " + nspId);
+            return null;
+        }
+        element = new VirtualRouterProviderVO(nspId, providerType);
+        _vrProviderDao.persist(element);
+        return element;
+    }
+
+    @Override
+    public boolean applyPFRules(final Network network, final List<PortForwardingRule> rules) throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.PortForwarding)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + network.getId());
+                return true;
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyFirewallRules(network, rules, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean isReady(final PhysicalNetworkServiceProvider provider) {
+        final VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), getVirtualRouterProvider());
+        if (element == null) {
+            return false;
+        }
+        return element.isEnabled();
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(final PhysicalNetworkServiceProvider provider, final ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        final VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), getVirtualRouterProvider());
+        if (element == null) {
+            return true;
+        }
+        // Find domain routers
+        final long elementId = element.getId();
+        final List<DomainRouterVO> routers = _routerDao.listByElementId(elementId);
+        boolean result = true;
+        for (final DomainRouterVO router : routers) {
+            result = result && _routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null;
+        }
+        _vrProviderDao.remove(elementId);
+
+        return result;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        return true;
+    }
+
+    public Long getIdByNspId(final Long nspId) {
+        final VirtualRouterProviderVO vr = _vrProviderDao.findByNspIdAndType(nspId, Type.VirtualRouter);
+        return vr.getId();
+    }
+
+    @Override
+    public VirtualRouterProvider getCreatedElement(final long id) {
+        final VirtualRouterProvider provider = _vrProviderDao.findById(id);
+        if (!(provider.getType() == Type.VirtualRouter || provider.getType() == Type.VPCVirtualRouter)) {
+            throw new InvalidParameterValueException("Unable to find provider by id");
+        }
+        return provider;
+    }
+
+    @Override
+    public boolean release(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final ReservationContext context) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        removeDhcpEntry(network, nic, vm);
+        return true;
+    }
+
+
+    @Override
+    public boolean configDhcpSupportForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest,
+                                              final ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+            return configureDhcpSupport(network, nic, vm, dest, Service.Dhcp);
+    }
+
+    @Override
+    public boolean configDnsSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        // Ignore if virtual router is already dhcp provider
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
+            return true;
+        }
+        return configureDhcpSupport(network, nic, vm, dest, Service.Dns);
+    }
+
+    protected boolean configureDhcpSupport(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, Service service) throws ResourceUnavailableException {
+        if (canHandle(network, service)) {
+            if (vm.getType() != VirtualMachine.Type.User) {
+                return false;
+            }
+
+            final VirtualMachineProfile uservm = vm;
+
+            final List<DomainRouterVO> routers = getRouters(network, dest);
+
+            if (routers == null || routers.size() == 0) {
+                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            return networkTopology.configDhcpForSubnet(network, nic, uservm, dest, routers);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean removeDhcpSupportForSubnet(final Network network) throws ResourceUnavailableException {
+        return removeDhcpSupportForSubnet(network, Service.Dhcp);
+    }
+
+    @Override
+    public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
+        return false;
+    }
+
+    @Override
+    public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) throws ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.Dhcp)) {
+            if (vmProfile.getType() != VirtualMachine.Type.User) {
+                return false;
+            }
+
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
+
+            if (CollectionUtils.isEmpty(routers)) {
+                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                if (domainRouterVO.getState() != VirtualMachine.State.Running) {
+                    continue;
+                }
+
+                result = result && networkTopology.removeDhcpEntry(network, nic, vmProfile, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean removeDnsSupportForSubnet(Network network) throws ResourceUnavailableException {
+        // Ignore if virtual router is already dhcp provider
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
+            return true;
+        } else {
+            return removeDhcpSupportForSubnet(network, Service.Dns);
+        }
+    }
+
+    protected boolean removeDhcpSupportForSubnet(Network network, Network.Service service) throws ResourceUnavailableException {
+        if (canHandle(network, service)) {
+            final List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+
+            if (CollectionUtils.isEmpty(routers)) {
+                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+            }
+            try {
+                return _routerMgr.removeDhcpSupportForSubnet(network, routers);
+            } catch (final ResourceUnavailableException e) {
+                s_logger.info("Router resource unavailable ", e);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean addDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
+            throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        return applyDhcpEntries(network, nic, vm, dest, Service.Dhcp);
+    }
+
+    @Override
+    public boolean addDnsEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        // Ignore if virtual router is already dhcp provider
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, getProvider())) {
+            return true;
+        }
+
+        return applyDhcpEntries(network, nic, vm, dest, Service.Dns);
+    }
+
+    protected boolean applyDhcpEntries (final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest, final Network.Service service) throws ResourceUnavailableException {
+
+        boolean result = true;
+        if (canHandle(network, service)) {
+            if (vm.getType() != VirtualMachine.Type.User) {
+                return false;
+            }
+
+            final VirtualMachineProfile uservm = vm;
+            final List<DomainRouterVO> routers = getRouters(network, dest);
+
+            if (routers == null || routers.size() == 0) {
+                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyDhcpEntry(network, nic, uservm, dest, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean addPasswordAndUserdata(final Network network, final NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest,
+            final ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        boolean result = true;
+        if (canHandle(network, Service.UserData)) {
+            if (vm.getType() != VirtualMachine.Type.User) {
+                return false;
+            }
+
+            final VirtualMachineProfile uservm = vm;
+
+            final List<DomainRouterVO> routers = getRouters(network, dest);
+
+            if (routers == null || routers.size() == 0) {
+                throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+            }
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            for (final DomainRouterVO domainRouterVO : routers) {
+                result = result && networkTopology.applyUserData(network, nic, uservm, dest, domainRouterVO);
+            }
+        }
+        return result;
+    }
+
+    protected List<DomainRouterVO> getRouters(final Network network, final DeployDestination dest) {
+        boolean publicNetwork = false;
+        if (_networkMdl.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) {
+            publicNetwork = true;
+        }
+        final boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMdl.isSecurityGroupSupportedInNetwork(network))
+                && network.getTrafficType() == TrafficType.Guest;
+
+        List<DomainRouterVO> routers;
+
+        if (publicNetwork) {
+            routers = getRouters(network);
+        } else {
+            if (isPodBased && dest.getPod() != null) {
+                final Long podId = dest.getPod().getId();
+                routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER);
+            } else {
+                // With pod == null, it's network restart case, we would add all
+                // router to it
+                // Ignore DnsBasicZoneUpdate() parameter here
+                routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
+            }
+        }
+
+        // for Basic zone, add all Running routers - we have to send
+        // Dhcp/vmData/password info to them when
+        // network.dns.basiczone.updates is set to "all"
+        // With pod == null, it's network restart case, we already add all
+        // routers to it
+        if (isPodBased && dest.getPod() != null && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) {
+            final Long podId = dest.getPod().getId();
+            final List<DomainRouterVO> allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER);
+            routers.addAll(allRunningRoutersOutsideThePod);
+        }
+        return routers;
+    }
+
+    @Override
+    public List<? extends VirtualRouterProvider> searchForVirtualRouterElement(final ListVirtualRouterElementsCmd cmd) {
+        final Long id = cmd.getId();
+        final Long nspId = cmd.getNspId();
+        final Boolean enabled = cmd.getEnabled();
+
+        final QueryBuilder<VirtualRouterProviderVO> sc = QueryBuilder.create(VirtualRouterProviderVO.class);
+        if (id != null) {
+            sc.and(sc.entity().getId(), Op.EQ, id);
+        }
+        if (nspId != null) {
+            sc.and(sc.entity().getNspId(), Op.EQ, nspId);
+        }
+        if (enabled != null) {
+            sc.and(sc.entity().isEnabled(), Op.EQ, enabled);
+        }
+
+        // return only VR and VPC VR
+        sc.and(sc.entity().getType(), Op.IN, VirtualRouterProvider.Type.VPCVirtualRouter, VirtualRouterProvider.Type.VirtualRouter);
+
+        return sc.list();
+    }
+
+    @Override
+    public List<? extends OvsProvider> searchForOvsElement(final ListOvsElementsCmd cmd) {
+        final Long id = cmd.getId();
+        final Long nspId = cmd.getNspId();
+        final Boolean enabled = cmd.getEnabled();
+        final QueryBuilder<OvsProviderVO> sc = QueryBuilder.create(OvsProviderVO.class);
+
+        if (id != null) {
+            sc.and(sc.entity().getId(), Op.EQ, id);
+        }
+        if (nspId != null) {
+            sc.and(sc.entity().getNspId(), Op.EQ, nspId);
+        }
+        if (enabled != null) {
+            sc.and(sc.entity().isEnabled(), Op.EQ, enabled);
+        }
+
+        return sc.list();
+    }
+
+    @Override
+    public boolean verifyServicesCombination(final Set<Service> services) {
+        return true;
+    }
+
+    @Override
+    public IpDeployer getIpDeployer(final Network network) {
+        return this;
+    }
+
+    protected VirtualRouterProvider.Type getVirtualRouterProvider() {
+        return VirtualRouterProvider.Type.VirtualRouter;
+    }
+
+    @Override
+    public List<LoadBalancerTO> updateHealthChecks(final Network network, final List<LoadBalancingRule> lbrules) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean handlesOnlyRulesInTransitionState() {
+        return true;
+    }
+
+    private boolean canHandleLbRules(final List<LoadBalancingRule> rules) {
+        final Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb);
+        if (!lbCaps.isEmpty()) {
+            final String schemeCaps = lbCaps.get(Capability.LbSchemes);
+            if (schemeCaps != null) {
+                for (final LoadBalancingRule rule : rules) {
+                    if (!schemeCaps.contains(rule.getScheme().toString())) {
+                        s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + getName());
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepareMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) {
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+            return true;
+        }
+        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+            assert vm instanceof DomainRouterVO;
+            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            try {
+                networkTopology.setupDhcpForPvlan(false, router, router.getHostId(), nic);
+            } catch (final ResourceUnavailableException e) {
+                s_logger.warn("Timed Out", e);
+            }
+        } else if (vm.getType() == VirtualMachine.Type.User) {
+            assert vm instanceof UserVmVO;
+            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
+            _userVmMgr.setupVmForPvlan(false, userVm.getHostId(), nic);
+        }
+        return true;
+    }
+
+    @Override
+    public void rollbackMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+            return;
+        }
+        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+            assert vm instanceof DomainRouterVO;
+            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            try {
+                networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic);
+            } catch (final ResourceUnavailableException e) {
+                s_logger.warn("Timed Out", e);
+            }
+        } else if (vm.getType() == VirtualMachine.Type.User) {
+            assert vm instanceof UserVmVO;
+            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
+            _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
+        }
+    }
+
+    @Override
+    public void commitMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) {
+        if (nic.getBroadcastType() != Networks.BroadcastDomainType.Pvlan) {
+            return;
+        }
+        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+            assert vm instanceof DomainRouterVO;
+            final DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine();
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+            final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
+
+            try {
+                networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic);
+            } catch (final ResourceUnavailableException e) {
+                s_logger.warn("Timed Out", e);
+            }
+        } else if (vm.getType() == VirtualMachine.Type.User) {
+            assert vm instanceof UserVmVO;
+            final UserVmVO userVm = (UserVmVO) vm.getVirtualMachine();
+            _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
+        }
+    }
+
+    @Override
+    public boolean prepareAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
+        final List<DomainRouterVO> routers = getRouters(network, dest);
+
+        if (routers == null || routers.size() == 0) {
+            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+        }
+
+        return _routerMgr.prepareAggregatedExecution(network, routers);
+    }
+
+    @Override
+    public boolean completeAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
+        final List<DomainRouterVO> routers = getRouters(network, dest);
+
+        if (routers == null || routers.size() == 0) {
+            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+        }
+
+        NetworkDetailVO networkDetail=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
+        boolean updateInSequence= "true".equalsIgnoreCase((networkDetail!=null ? networkDetail.getValue() : null));
+        if(updateInSequence){
+            DomainRouterVO router=routers.get(0);
+            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_COMPLETE);
+            _routerDao.persist(router);
+        }
+        boolean result=false;
+        try{
+            result=_routerMgr.completeAggregatedExecution(network, routers);
+        } finally {
+            if(!result && updateInSequence) {
+                //fail the network update. even if one router fails we fail the network update.
+                updateToFailedState(network);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean cleanupAggregatedExecution(final Network network, final DeployDestination dest) throws ResourceUnavailableException {
+        // The VR code already cleansup in the Finish routine using finally,
+        // lets not waste another command
+        return true;
+    }
+
+    @Override
+    public void configureResource(Network network) {
+        NetworkDetailVO networkDetail=_networkDetailsDao.findDetail(network.getId(), Network.updatingInSequence);
+        if(networkDetail==null || !"true".equalsIgnoreCase(networkDetail.getValue()))
+            throw new CloudRuntimeException("failed to configure the resource, network update is not in progress.");
+        List<DomainRouterVO>routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
+        for(DomainRouterVO router : routers){
+            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
+            _routerDao.persist(router);
+        }
+    }
+
+    @Override
+    public int getResourceCount(Network network) {
+        return _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER).size();
+    }
+
+    @Override
+    public void finalize(Network network, boolean success) {
+        if(!success){
+            updateToFailedState(network);
+        }
+    }
+
+    private void updateToFailedState(Network network){
+        //fail the network update. even if one router fails we fail the network update.
+        List<DomainRouterVO> routerList = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
+        for (DomainRouterVO router : routerList) {
+            router.setUpdateState(VirtualRouter.UpdateState.UPDATE_FAILED);
+            _routerDao.persist(router);
+        }
+    }
+
+}
diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java
similarity index 100%
rename from server/src/com/cloud/network/element/VpcVirtualRouterElement.java
rename to server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java
diff --git a/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java
new file mode 100644
index 0000000..efab0e2
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/firewall/FirewallManagerImpl.java
@@ -0,0 +1,1068 @@
+// 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.network.firewall;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collections;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.network.dao.FirewallRulesDcidrsDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.command.user.firewall.IListFirewallRulesCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+
+import com.cloud.configuration.Config;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.dao.EventDao;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkRuleApplier;
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.FirewallServiceProvider;
+import com.cloud.network.element.NetworkACLServiceProvider;
+import com.cloud.network.element.PortForwardingServiceProvider;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.FirewallRuleType;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRule.State;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+
+@Component
+public class FirewallManagerImpl extends ManagerBase implements FirewallService, FirewallManager, NetworkRuleApplier {
+    private static final Logger s_logger = Logger.getLogger(FirewallManagerImpl.class);
+
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    EventDao _eventDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    FirewallRulesCidrsDao _firewallCidrsDao;
+    @Inject
+    FirewallRulesDcidrsDao _firewallDcidrsDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    UsageEventDao _usageEventDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    DomainManager _domainMgr;
+    @Inject
+    PortForwardingRulesDao _pfRulesDao;
+    @Inject
+    UserVmDao _vmDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcManager _vpcMgr;
+    List<FirewallServiceProvider> _firewallElements;
+
+    List<PortForwardingServiceProvider> _pfElements;
+
+    List<StaticNatServiceProvider> _staticNatElements;
+
+    List<NetworkACLServiceProvider> _networkAclElements;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+
+    private boolean _elbEnabled = false;
+    static Boolean rulesContinueOnErrFlag = true;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        String elbEnabledString = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
+        _elbEnabled = Boolean.parseBoolean(elbEnabledString);
+        if (_ipAddrMgr.RulesContinueOnError.value() != null) {
+            rulesContinueOnErrFlag = _ipAddrMgr.RulesContinueOnError.value();
+        }
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        s_logger.info("Firewall provider list is " + _firewallElements.iterator().next());
+        return super.start();
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule for network", create = true)
+    public FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        Network network = _networkDao.findById(rule.getNetworkId());
+        if (network.getGuestType() == Network.GuestType.Shared) {
+            throw new InvalidParameterValueException("Egress firewall rules are not supported for " + network.getGuestType() + "  networks");
+        }
+
+        List<String> sourceCidrs = rule.getSourceCidrList();
+        if (sourceCidrs != null && !sourceCidrs.isEmpty())
+        Collections.replaceAll(sourceCidrs, "0.0.0.0/0", network.getCidr());
+
+        return createFirewallRule(null, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), sourceCidrs, rule.getDestinationCidrList(),
+                rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
+    public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
+         Account caller = CallContext.current().getCallingAccount();
+        Long sourceIpAddressId = rule.getSourceIpAddressId();
+
+        return createFirewallRule(sourceIpAddressId, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(),
+            rule.getSourceCidrList(), null, rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
+    }
+    //Destination CIDR capability is currently implemented for egress rules only. For others, the field is passed as null.
+    @DB
+    protected FirewallRule createFirewallRule(final Long ipAddrId, Account caller, final String xId, final Integer portStart, final Integer portEnd,
+        final String protocol, final List<String> sourceCidrList, final List<String> destCidrList, final Integer icmpCode, final Integer icmpType, final Long relatedRuleId,
+ final FirewallRule.FirewallRuleType type,
+            final Long networkId, final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
+
+        IPAddressVO ipAddress = null;
+        if (ipAddrId != null) {
+            // this for ingress firewall rule, for egress id is null
+             ipAddress = _ipAddressDao.findById(ipAddrId);
+        // Validate ip address
+        if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
+                throw new InvalidParameterValueException("Unable to create firewall rule; " + "couldn't locate IP address by id in the system");
+        }
+        _networkModel.checkIpForService(ipAddress, Service.Firewall, null);
+        }
+
+        validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type, networkId, trafficType);
+
+        // icmp code and icmp type can't be passed in for any other protocol rather than icmp
+        if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
+            throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
+        }
+
+        if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
+            throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
+        }
+
+        Long accountId = null;
+        Long domainId = null;
+
+        if (ipAddress != null) {
+            //Ingress firewall rule
+            accountId = ipAddress.getAllocatedToAccountId();
+            domainId = ipAddress.getAllocatedInDomainId();
+        } else if (networkId != null) {
+            //egress firewall rule
+                Network network = _networkModel.getNetwork(networkId);
+                accountId = network.getAccountId();
+                domainId = network.getDomainId();
+        }
+
+        final Long accountIdFinal = accountId;
+        final Long domainIdFinal = domainId;
+        return Transaction.execute(new TransactionCallbackWithException<FirewallRuleVO, NetworkRuleConflictException>() {
+            @Override
+            public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+                FirewallRuleVO newRule =
+                        new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, accountIdFinal, domainIdFinal, Purpose.Firewall,
+                                sourceCidrList, destCidrList, icmpCode, icmpType, relatedRuleId, trafficType);
+                newRule.setType(type);
+                if (forDisplay != null) {
+                    newRule.setDisplay(forDisplay);
+                }
+                newRule = _firewallDao.persist(newRule);
+
+                if (type == FirewallRuleType.User)
+                    detectRulesConflict(newRule);
+
+                if (!_firewallDao.setStateToAdd(newRule)) {
+                    throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+                }
+                CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
+
+                return newRule;
+            }
+        });
+    }
+
+    @Override
+    public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(IListFirewallRulesCmd cmd) {
+        Long ipId = cmd.getIpAddressId();
+        Long id = cmd.getId();
+        Long networkId = cmd.getNetworkId();
+        Map<String, String> tags = cmd.getTags();
+        FirewallRule.TrafficType trafficType = cmd.getTrafficType();
+        Boolean display = cmd.getDisplay();
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        if (ipId != null) {
+            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
+            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
+                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for firewall rules yet");
+            }
+            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
+        }
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), Op.EQ);
+        sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
+            sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
+        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
+        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<FirewallRuleVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.FirewallRule.toString());
+            for (String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        if (ipId != null) {
+            sc.setParameters("ip", ipId);
+        }
+
+            if (networkId != null) {
+                sc.setParameters("networkId", networkId);
+            }
+
+        sc.setParameters("purpose", Purpose.Firewall);
+        sc.setParameters("trafficType", trafficType);
+
+        Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
+        return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
+    }
+
+    //Intermediate funciton used in detectRulesConflict to check for the conflicting cidrs in the rules already applied and the newRule being applied.
+    boolean detectConflictingCidrs(List<String> cidrList1, List<String> cidrList2){
+        if(cidrList1.isEmpty() && cidrList2.isEmpty()){
+            return true;
+        }
+
+        Collection<String> similar = new HashSet<String>(cidrList1);
+        similar.retainAll(cidrList2);
+        return (similar.size()>0);
+    }
+
+    @Override
+    public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
+        List<FirewallRuleVO> rules;
+        if (newRule.getSourceIpAddressId() != null) {
+             rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
+            assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for "
+                + "network conflicts so we should at least have one rule at this point.";
+        } else {
+            // fetches only firewall egress rules.
+            rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
+            assert (rules.size() >= 1);
+        }
+
+        for (FirewallRuleVO rule : rules) {
+            if (rule.getId() == newRule.getId()) {
+                continue; // Skips my own rule.
+            }
+
+            boolean oneOfRulesIsFirewall =
+                ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
+                            .equalsIgnoreCase(rule.getProtocol()))));
+
+            // if both rules are firewall and their cidrs are different, we can skip port ranges verification
+            boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
+            boolean duplicatedCidrs = false;
+            if (bothRulesFirewall) {
+                _firewallDao.loadSourceCidrs(rule);
+                _firewallDao.loadSourceCidrs((FirewallRuleVO)newRule);
+
+                _firewallDao.loadDestinationCidrs(rule);
+                _firewallDao.loadDestinationCidrs((FirewallRuleVO) newRule);
+
+                if (rule.getSourceCidrList() == null || newRule.getSourceCidrList() == null) {
+                    continue;
+                }
+                duplicatedCidrs = (detectConflictingCidrs(rule.getSourceCidrList(), newRule.getSourceCidrList()) && detectConflictingCidrs(rule.getDestinationCidrList(), newRule.getDestinationCidrList()));
+            }
+
+            if (!oneOfRulesIsFirewall) {
+                if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
+                    throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
+                } else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
+                    throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
+                }
+            }
+
+            // Checking if the rule applied is to the same network that is passed in the rule.
+            if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
+                throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
+            }
+
+            //Check for the ICMP protocol. This has to be done separately from other protocols as we need to check the ICMP codes and ICMP type also.
+            if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
+                if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() &&
+                    newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) {
+                    throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId());
+                }
+            }
+
+            boolean notNullPorts =
+                (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
+            boolean nullPorts =
+                (newRule.getSourcePortStart() == null && newRule.getSourcePortEnd() == null && rule.getSourcePortStart() == null && rule.getSourcePortEnd() == null);
+
+            // If ports are not specified and cidrs are same and protocol is also same(NOT ICMP as it is separately checked above)
+            if(nullPorts && duplicatedCidrs && (rule.getProtocol().equalsIgnoreCase(newRule.getProtocol())) && !newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+                throw new NetworkRuleConflictException("There is already a firewall rule specified with protocol = " +newRule.getProtocol()+ " and no ports");
+            }
+
+            if (!notNullPorts) {
+                continue;
+            } else if (!oneOfRulesIsFirewall &&
+                !(bothRulesFirewall && !duplicatedCidrs) &&
+                ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() &&
+                    rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) ||
+                    (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() &&
+                    rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) ||
+                    (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() &&
+                    newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) ||
+                (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() &&
+                newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
+                //Above else if conditions checks for the conflicting port ranges.
+
+                // we allow port forwarding rules with the same parameters but different protocols
+                boolean allowPf =
+                    (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(
+                        rule.getProtocol())) || (rule.getPurpose() == Purpose.Vpn && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(
+                            rule.getProtocol()));
+                boolean allowStaticNat =
+                    (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
+
+                boolean allowVpnPf =
+                        (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
+
+                boolean allowVpnLb =
+                        (rule.getPurpose() == Purpose.LoadBalancing && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
+
+                if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall || allowVpnPf || allowVpnLb)) {
+                    throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() +
+                        ", conflicts with rule " + rule.getId() + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
+                }
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing rules");
+        }
+    }
+
+    @Override
+    public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type,
+        Long networkId, FirewallRule.TrafficType trafficType) {
+        if (portStart != null && !NetUtils.isValidPort(portStart)) {
+            throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
+        }
+        if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
+            throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
+        }
+
+        // start port can't be bigger than end port
+        if (portStart != null && portEnd != null && portStart > portEnd) {
+            throw new InvalidParameterValueException("Start port can't be bigger than end port");
+        }
+
+        if (ipAddress == null && type == FirewallRuleType.System) {
+            return;
+        }
+
+        if (ipAddress != null) {
+            if (ipAddress.getAssociatedWithNetworkId() == null) {
+                    throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
+            } else {
+                networkId = ipAddress.getAssociatedWithNetworkId();
+            }
+
+            // Validate ip address
+            _accountMgr.checkAccess(caller, null, true, ipAddress);
+        }
+
+        //network id either has to be passed explicitly, or implicitly as a part of ipAddress object
+        if (networkId == null) {
+            throw new InvalidParameterValueException("Unable to retrieve network id to validate the rule");
+        }
+
+        Network network = _networkModel.getNetwork(networkId);
+        assert network != null : "Can't create rule as network associated with public ip address is null?";
+
+        if (trafficType == FirewallRule.TrafficType.Egress) {
+            _accountMgr.checkAccess(caller, null, true, network);
+        }
+
+        // Verify that the network guru supports the protocol specified
+        Map<Network.Capability, String> caps = null;
+
+        if (purpose == Purpose.LoadBalancing) {
+            if (!_elbEnabled) {
+                caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
+            }
+        } else if (purpose == Purpose.PortForwarding) {
+            caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
+        } else if (purpose == Purpose.Firewall) {
+            caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
+        }
+
+        if (caps != null) {
+            String supportedProtocols;
+            String supportedTrafficTypes = null;
+            if (purpose == FirewallRule.Purpose.Firewall) {
+                supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase();
+            }
+
+            if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) {
+                supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase();
+            } else {
+                supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
+            }
+
+            if (!supportedProtocols.contains(proto.toLowerCase())) {
+                throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
+            } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
+                throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
+            } else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
+                throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId);
+            }
+        }
+
+    }
+
+    @Override
+    public boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException {
+        boolean success = true;
+        if (rules == null || rules.size() == 0) {
+            s_logger.debug("There are no rules to forward to the network elements");
+            return true;
+        }
+        Purpose purpose = rules.get(0).getPurpose();
+        if (!_ipAddrMgr.applyRules(rules, purpose, this, continueOnError)) {
+            s_logger.warn("Rules are not completely applied");
+            return false;
+        } else {
+            if (updateRulesInDB) {
+                for (FirewallRule rule : rules) {
+                    if (rule.getState() == FirewallRule.State.Revoke) {
+                        FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(rule.getId());
+                        if (relatedRule != null) {
+                            s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + " as it has related firewall rule id=" + relatedRule.getId() +
+                                "; leaving it in Revoke state");
+                            success = false;
+                        } else {
+                            removeRule(rule);
+                            if (rule.getSourceIpAddressId() != null) {
+                                //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+                                IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
+                                _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), rule.getNetworkId());
+                            }
+                        }
+                    } else if (rule.getState() == FirewallRule.State.Add) {
+                        FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
+                        ruleVO.setState(FirewallRule.State.Active);
+                        _firewallDao.update(ruleVO.getId(), ruleVO);
+                    }
+                }
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean applyRules(Network network, Purpose purpose, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
+        boolean handled = false;
+        switch (purpose) {
+        /* StaticNatRule would be applied by Firewall provider, since the incompatible of two object */
+        case StaticNat:
+        case Firewall:
+                for (FirewallServiceProvider fwElement : _firewallElements) {
+                Network.Provider provider = fwElement.getProvider();
+                boolean  isFwProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider);
+                if (!isFwProvider) {
+                    continue;
+                }
+                handled = fwElement.applyFWRules(network, rules);
+                if (handled)
+                    break;
+            }
+            break;
+        case PortForwarding:
+                for (PortForwardingServiceProvider element : _pfElements) {
+                Network.Provider provider = element.getProvider();
+                boolean  isPfProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.PortForwarding, provider);
+                if (!isPfProvider) {
+                    continue;
+                }
+                    handled = element.applyPFRules(network, (List<PortForwardingRule>)rules);
+                if (handled)
+                    break;
+            }
+            break;
+            /*        case NetworkACL:
+            for (NetworkACLServiceProvider element: _networkAclElements) {
+                Network.Provider provider = element.getProvider();
+                boolean  isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
+                if (!isAclProvider) {
+                    continue;
+                }
+                handled = element.applyNetworkACLs(network, rules);
+                if (handled)
+                    break;
+            }
+            break;*/
+        default:
+                assert (false) : "Unexpected fall through in applying rules to the network elements";
+            s_logger.error("FirewallManager cannot process rules of type " + purpose);
+            throw new CloudRuntimeException("FirewallManager cannot process rules of type " + purpose);
+        }
+        return handled;
+    }
+
+    @Override
+    public void removeRule(FirewallRule rule) {
+
+        //remove the rule
+        _firewallDao.remove(rule.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", async = true)
+    public boolean applyIngressFwRules(long ipId, Account caller) throws ResourceUnavailableException {
+        return applyIngressFirewallRules(ipId, caller);
+    }
+
+    @Override
+    public boolean applyIngressFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
+        return applyFirewallRules(rules, false, caller);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_OPEN, eventDescription = "creating egress firewall rule", async = true)
+    public boolean applyEgressFirewallRules(FirewallRule rule, Account caller) throws ResourceUnavailableException {
+                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
+                return applyFirewallRules(rules, false, caller);
+    }
+
+    @Override
+    public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
+
+        if (rules.size() == 0) {
+            s_logger.debug("There are no firewall rules to apply");
+            return true;
+        }
+
+        for (FirewallRuleVO rule : rules) {
+            // load cidrs if any
+            rule.setSourceCidrList(_firewallCidrsDao.getSourceCidrs(rule.getId()));
+            rule.setDestinationCidrsList(_firewallDcidrsDao.getDestCidrs(rule.getId()));
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, rules.toArray(new FirewallRuleVO[rules.size()]));
+        }
+
+        try {
+            if (!applyRules(rules, continueOnError, true)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply firewall rules due to : "+ ex.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyDefaultEgressFirewallRule(Long networkId, boolean defaultPolicy, boolean add) throws ResourceUnavailableException {
+
+        s_logger.debug("applying default firewall egress rules ");
+
+        NetworkVO network = _networkDao.findById(networkId);
+        List<String> sourceCidr = new ArrayList<String>();
+        List<String> destCidr = new ArrayList<String>();
+
+
+        sourceCidr.add(network.getCidr());
+        destCidr.add(NetUtils.ALL_IP4_CIDRS);
+
+        FirewallRuleVO ruleVO =
+            new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr, destCidr, null, null, null,
+                FirewallRule.TrafficType.Egress, FirewallRuleType.System);
+        ruleVO.setState(add ? State.Add : State.Revoke);
+        List<FirewallRuleVO> rules = new ArrayList<FirewallRuleVO>();
+        rules.add(ruleVO);
+
+        try {
+            //this is not required to store in db because we don't to add this rule along with the normal rules
+            if (!applyRules(rules, false, false)) {
+                return  false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply default egress rules for guest network due to ", ex);
+            return false;
+        }
+        return true;
+    }
+
+    protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {
+
+        FirewallRuleVO rule = _firewallDao.findById(ruleId);
+        if (rule == null || rule.getPurpose() != Purpose.Firewall) {
+            throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
+        }
+
+        if (rule.getType() == FirewallRuleType.System && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new InvalidParameterValueException("Only root admin can delete the system wide firewall rule");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        revokeRule(rule, caller, userId, false);
+
+        boolean success = false;
+        Long networkId = rule.getNetworkId();
+
+        if (apply) {
+            // ingress firewall rule
+            if (rule.getSourceIpAddressId() != null) {
+                //feteches ingress firewall, ingress firewall rules associated with the ip
+            List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
+            return applyFirewallRules(rules, false, caller);
+                //egress firewall rule
+            } else if (networkId != null) {
+                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
+                return applyFirewallRules(rules, false, caller);
+            }
+        } else {
+            success = true;
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
+    public boolean revokeIngressFwRule(long ruleId, boolean apply) {
+        return revokeIngressFirewallRule(ruleId, apply);
+    }
+
+
+    @Override
+    public boolean revokeIngressFirewallRule(long ruleId, boolean apply) {
+        Account caller = CallContext.current().getCallingAccount();
+        long userId = CallContext.current().getCallingUserId();
+        return revokeFirewallRule(ruleId, apply, caller, userId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_CLOSE, eventDescription = "revoking egress firewall rule", async = true)
+    public boolean revokeEgressFirewallRule(long ruleId, boolean apply) {
+        Account caller = CallContext.current().getCallingAccount();
+        long userId = CallContext.current().getCallingUserId();
+        return revokeFirewallRule(ruleId, apply, caller, userId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_UPDATE, eventDescription = "updating firewall rule", async = true)
+    public FirewallRule updateIngressFirewallRule(long ruleId, String customId, Boolean forDisplay) {
+        Account caller = CallContext.current().getCallingAccount();
+        return updateFirewallRule(ruleId, customId, caller, forDisplay);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_EGRESS_UPDATE, eventDescription = "updating egress firewall rule", async = true)
+    public FirewallRule updateEgressFirewallRule(long ruleId, String customId, Boolean forDisplay) {
+        Account caller = CallContext.current().getCallingAccount();
+        return updateFirewallRule(ruleId, customId, caller, forDisplay);
+    }
+
+    protected FirewallRule updateFirewallRule(long ruleId, String customId, Account caller, Boolean forDisplay) {
+        FirewallRuleVO rule = _firewallDao.findById(ruleId);
+        if (rule == null || rule.getPurpose() != Purpose.Firewall) {
+            throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
+        }
+
+        if (rule.getType() == FirewallRuleType.System && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            throw new InvalidParameterValueException("Only root admin can update the system wide firewall rule");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        if (customId != null) {
+            rule.setUuid(customId);
+        }
+
+        if (forDisplay != null) {
+            rule.setDisplay(forDisplay);
+        }
+
+        _firewallDao.update(ruleId, rule);
+
+        return _firewallDao.findById(ruleId);
+    }
+
+    @Override
+    @DB
+    public void revokeRule(final FirewallRuleVO rule, Account caller, long userId, final boolean needUsageEvent) {
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, rule);
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+        boolean generateUsageEvent = false;
+
+        if (rule.getState() == State.Staged) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule);
+            }
+            removeRule(rule);
+            generateUsageEvent = true;
+        } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
+            rule.setState(State.Revoke);
+            _firewallDao.update(rule.getId(), rule);
+            generateUsageEvent = true;
+        }
+
+        if (generateUsageEvent && needUsageEvent) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), null, rule.getClass().getName(),
+                        rule.getUuid());
+        }
+            }
+        });
+    }
+
+    @Override
+    public FirewallRule getFirewallRule(long ruleId) {
+        return _firewallDao.findById(ruleId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
+    public boolean revokeFirewallRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRule> rules = new ArrayList<FirewallRule>();
+
+        List<FirewallRuleVO> fwRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + fwRules.size() + " firewall rules for ip id=" + ipId);
+        }
+
+        for (FirewallRuleVO rule : fwRules) {
+            // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
+            // need to send them one by one
+            revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        // now send everything to the backend
+        List<FirewallRuleVO> rulesToApply = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
+        //apply rules
+        if (!applyFirewallRules(rulesToApply, rulesContinueOnErrFlag, caller)) {
+            if (!rulesContinueOnErrFlag) {
+                return false;
+            }
+        }
+        // Now we check again in case more rules have been inserted.
+        rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall));
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Successfully released firewall rules for ip id=" + ipId + " and # of rules now = " + rules.size());
+        }
+
+        return rules.size() == 0;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
+    public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType,
+        Long relatedRuleId, long networkId) throws NetworkRuleConflictException {
+
+        // If firwallRule for this port range already exists, return it
+        List<FirewallRuleVO> rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, protocol, Purpose.Firewall);
+        if (!rules.isEmpty()) {
+            return rules.get(0);
+        }
+
+        List<String> oneCidr = new ArrayList<String>();
+        oneCidr.add(NetUtils.ALL_IP4_CIDRS);
+        return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, null, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User,
+            networkId, FirewallRule.TrafficType.Ingress, true);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
+    public boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRule> rules = new ArrayList<FirewallRule>();
+
+        List<FirewallRuleVO> fwRules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + fwRules.size() + " firewall rules for network id=" + networkId);
+        }
+
+        for (FirewallRuleVO rule : fwRules) {
+            // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
+            // need to send them one by one
+            revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        // now send everything to the backend
+        List<FirewallRuleVO> rulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
+        boolean success = applyFirewallRules(rulesToApply, true, caller);
+
+        // Now we check again in case more rules have been inserted.
+        rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall));
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Successfully released firewall rules for network id=" + networkId + " and # of rules now = " + rules.size());
+        }
+
+        return success && rules.size() == 0;
+    }
+
+    @Override
+    public boolean revokeRelatedFirewallRule(long ruleId, boolean apply) {
+        FirewallRule fwRule = _firewallDao.findByRelatedId(ruleId);
+
+        if (fwRule == null) {
+            s_logger.trace("No related firewall rule exists for rule id=" + ruleId + " so returning true here");
+            return true;
+        }
+
+        s_logger.debug("Revoking Firewall rule id=" + fwRule.getId() + " as a part of rule delete id=" + ruleId + " with apply=" + apply);
+        return revokeIngressFirewallRule(fwRule.getId(), apply);
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
+    public boolean revokeFirewallRulesForVm(long vmId) {
+        boolean success = true;
+        UserVmVO vm = _vmDao.findByIdIncludingRemoved(vmId);
+        if (vm == null) {
+            return false;
+        }
+
+        List<PortForwardingRuleVO> pfRules = _pfRulesDao.listByVm(vmId);
+        List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(vm.getId());
+        List<FirewallRuleVO> firewallRules = new ArrayList<FirewallRuleVO>();
+
+        // Make a list of firewall rules to reprogram
+        for (PortForwardingRuleVO pfRule : pfRules) {
+            FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(pfRule.getId());
+            if (relatedRule != null) {
+                firewallRules.add(relatedRule);
+            }
+        }
+
+        for (FirewallRuleVO staticNatRule : staticNatRules) {
+            FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(staticNatRule.getId());
+            if (relatedRule != null) {
+                firewallRules.add(relatedRule);
+            }
+        }
+
+        Set<Long> ipsToReprogram = new HashSet<Long>();
+
+        if (firewallRules.isEmpty()) {
+            s_logger.debug("No firewall rules are found for vm id=" + vmId);
+            return true;
+        } else {
+            s_logger.debug("Found " + firewallRules.size() + " to cleanup for vm id=" + vmId);
+        }
+
+        for (FirewallRuleVO rule : firewallRules) {
+            // Mark firewall rules as Revoked, but don't revoke it yet (apply=false)
+            revokeFirewallRule(rule.getId(), false, _accountMgr.getSystemAccount(), Account.ACCOUNT_ID_SYSTEM);
+            ipsToReprogram.add(rule.getSourceIpAddressId());
+        }
+
+        // apply rules for all ip addresses
+        for (Long ipId : ipsToReprogram) {
+            s_logger.debug("Applying firewall rules for ip address id=" + ipId + " as a part of vm expunge");
+            try {
+                success = success && applyIngressFirewallRules(ipId, _accountMgr.getSystemAccount());
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to apply firewall rules for ip id=" + ipId);
+                success = false;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
+    public boolean addSystemFirewallRules(IPAddressVO ip, Account acct) {
+        List<FirewallRuleVO> systemRules = _firewallDao.listSystemRules();
+        for (FirewallRuleVO rule : systemRules) {
+            try {
+                if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
+                    _firewallDao.loadSourceCidrs(rule);
+                }
+                createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(),null,
+                        rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getTrafficType(), true);
+            } catch (Exception e) {
+                s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
+            }
+        }
+        return true;
+    }
+
+    public List<FirewallServiceProvider> getFirewallElements() {
+        return _firewallElements;
+    }
+
+    @Inject
+    public void setFirewallElements(List<FirewallServiceProvider> firewallElements) {
+        _firewallElements = firewallElements;
+    }
+
+    public List<PortForwardingServiceProvider> getPfElements() {
+        return _pfElements;
+    }
+
+    @Inject
+    public void setPfElements(List<PortForwardingServiceProvider> pfElements) {
+        _pfElements = pfElements;
+    }
+
+    public List<StaticNatServiceProvider> getStaticNatElements() {
+        return _staticNatElements;
+    }
+
+    @Inject
+    public void setStaticNatElements(List<StaticNatServiceProvider> staticNatElements) {
+        _staticNatElements = staticNatElements;
+    }
+
+    public List<NetworkACLServiceProvider> getNetworkAclElements() {
+        return _networkAclElements;
+    }
+
+    @Inject
+    public void setNetworkAclElements(List<NetworkACLServiceProvider> networkAclElements) {
+        _networkAclElements = networkAclElements;
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java
new file mode 100644
index 0000000..87afb9f
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java
@@ -0,0 +1,244 @@
+// 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.network.guru;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(ControlNetworkGuru.class);
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    NetworkModel _networkMgr;
+    String _cidr;
+    String _gateway;
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Control};
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    protected boolean canHandle(NetworkOffering offering) {
+        if (offering.isSystemOnly() && isMyTrafficType(offering.getTrafficType())) {
+            return true;
+        } else {
+            s_logger.trace("We only care about System only Control network");
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network specifiedConfig, Account owner) {
+        if (!canHandle(offering)) {
+            return null;
+        }
+
+        NetworkVO config =
+            new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.LinkLocal, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
+                plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        config.setCidr(_cidr);
+        config.setGateway(_gateway);
+
+        return config;
+    }
+
+    protected ControlNetworkGuru() {
+        super();
+    }
+
+    @Override
+    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+
+        if (vm.getHypervisorType() == HypervisorType.VMware && !isRouterVm(vm)) {
+            NicProfile nicProf = new NicProfile(Nic.ReservationStrategy.Create, null, null, null, null);
+            String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
+            nicProf.setMacAddress(mac);
+            return nicProf;
+        }
+
+        if (nic != null) {
+            throw new CloudRuntimeException("Does not support nic specification at this time: " + nic);
+        }
+
+        return new NicProfile(Nic.ReservationStrategy.Start, null, null, null, null);
+    }
+
+    @Override
+    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        assert nic.getTrafficType() == TrafficType.Control;
+
+        // we have to get management/private ip for the control nic for vmware/hyperv due ssh issues.
+        HypervisorType hType = vm.getHypervisorType();
+        if (((hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv)) && isRouterVm(vm)) {
+            if (dest.getDataCenter().getNetworkType() != NetworkType.Basic) {
+                super.reserve(nic, config, vm, dest, context);
+
+                String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
+                nic.setMacAddress(mac);
+                return;
+            } else {
+                // in basic mode and in VMware case, control network will be shared with guest network
+                String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
+                nic.setMacAddress(mac);
+                nic.setIPv4Address("0.0.0.0");
+                nic.setIPv4Netmask("0.0.0.0");
+                nic.setFormat(AddressFormat.Ip4);
+                nic.setIPv4Gateway("0.0.0.0");
+                return;
+            }
+        }
+
+        String ip = _dcDao.allocateLinkLocalIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId());
+        if (ip == null) {
+            throw new InsufficientAddressCapacityException("Insufficient link local address capacity", DataCenter.class, dest.getDataCenter().getId());
+        }
+        nic.setIPv4Address(ip);
+        nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40)));
+        nic.setIPv4Netmask("255.255.0.0");
+        nic.setFormat(AddressFormat.Ip4);
+        nic.setIPv4Gateway(NetUtils.getLinkLocalGateway());
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        assert nic.getTrafficType() == TrafficType.Control;
+        HypervisorType hType = vm.getHypervisorType();
+        if ( ( (hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv) )&& isRouterVm(vm)) {
+            long dcId = vm.getVirtualMachine().getDataCenterId();
+            DataCenterVO dcVo = _dcDao.findById(dcId);
+            if (dcVo.getNetworkType() != NetworkType.Basic) {
+                super.release(nic, vm, reservationId);
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Released nic: " + nic);
+                }
+                return true;
+            } else {
+                nic.deallocate();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Released nic: " + nic);
+                }
+                return true;
+            }
+        }
+
+        _dcDao.releaseLinkLocalIpAddress(nic.getId(), reservationId);
+
+        nic.deallocate();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Released nic: " + nic);
+        }
+
+        return true;
+    }
+
+    protected boolean isRouterVm(VirtualMachineProfile vm) {
+        return vm.getType() == VirtualMachine.Type.DomainRouter || vm.getType() == VirtualMachine.Type.InternalLoadBalancerVm;
+    }
+
+    @Override
+    public Network implement(Network config, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        assert config.getTrafficType() == TrafficType.Control : "Why are you sending this configuration to me " + config;
+        return config;
+    }
+
+    @Override
+    public void shutdown(NetworkProfile config, NetworkOffering offering) {
+        assert false : "Destroying a link local...Either you're out of your mind or something has changed.";
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        Map<String, String> dbParams = _configDao.getConfiguration(params);
+
+        _cidr = dbParams.get(Config.ControlCidr.toString());
+        if (_cidr == null) {
+            _cidr = "169.254.0.0/16";
+        }
+
+        _gateway = dbParams.get(Config.ControlGateway.toString());
+        if (_gateway == null) {
+            _gateway = NetUtils.getLinkLocalGateway();
+        }
+
+        s_logger.info("Control network setup: cidr=" + _cidr + "; gateway = " + _gateway);
+
+        return true;
+    }
+
+    @Override
+    public boolean trash(Network config, NetworkOffering offering) {
+        return true;
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java
new file mode 100644
index 0000000..8bb5c9a
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java
@@ -0,0 +1,404 @@
+// 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.network.guru;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+
+
+public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(DirectNetworkGuru.class);
+
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    private NetworkService networkService;
+    @Inject
+    private NicSecondaryIpDao nicSecondaryIpDao;
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
+    protected IsolationMethod[] _isolationMethods;
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return true if the physical network isolation method contains the expected isolation method for this guru
+     */
+    protected boolean isMyIsolationMethod(PhysicalNetwork physicalNetwork) {
+        for (IsolationMethod m : this.getIsolationMethods()) {
+            List<String> isolationMethods = physicalNetwork.getIsolationMethods();
+            if (CollectionUtils.isNotEmpty(isolationMethods)) {
+                for (String method : isolationMethods) {
+                    s_logger.debug(method + ": " + m.toString());
+                    if (method.equalsIgnoreCase(m.toString())) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    protected boolean canHandle(NetworkOffering offering, DataCenter dc, PhysicalNetwork physnet) {
+        if (dc.getNetworkType() == NetworkType.Advanced
+                && isMyTrafficType(offering.getTrafficType())
+                && isMyIsolationMethod(physnet)
+                && offering.getGuestType() == GuestType.Shared
+                && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp)
+                && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NiciraNvp)) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest networks of type " + GuestType.Shared);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+
+        if (!canHandle(offering, dc, physnet)) {
+            s_logger.info("Refusing to design this network");
+            return null;
+        }
+
+        State state = State.Allocated;
+        if (dc.getNetworkType() == NetworkType.Basic) {
+            state = State.Setup;
+        }
+
+        NetworkVO config =
+            new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), state, plan.getDataCenterId(),
+                    plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+
+        if (userSpecified != null) {
+            if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
+                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
+            }
+
+            if ((userSpecified.getIp6Cidr() == null && userSpecified.getIp6Gateway() != null) ||
+                (userSpecified.getIp6Cidr() != null && userSpecified.getIp6Gateway() == null)) {
+                throw new InvalidParameterValueException("cidrv6 and gatewayv6 must be specified together.");
+            }
+
+            if (userSpecified.getCidr() != null) {
+                config.setCidr(userSpecified.getCidr());
+                config.setGateway(userSpecified.getGateway());
+            }
+
+            if (userSpecified.getIp6Cidr() != null) {
+                config.setIp6Cidr(userSpecified.getIp6Cidr());
+                config.setIp6Gateway(userSpecified.getIp6Gateway());
+            }
+
+            if (userSpecified.getBroadcastUri() != null) {
+                config.setBroadcastUri(userSpecified.getBroadcastUri());
+                config.setState(State.Setup);
+            }
+
+            if (userSpecified.getBroadcastDomainType() != null) {
+                config.setBroadcastDomainType(userSpecified.getBroadcastDomainType());
+            }
+        }
+
+        boolean isSecurityGroupEnabled = _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup);
+        if (isSecurityGroupEnabled) {
+            config.setName("SecurityGroupEnabledNetwork");
+            config.setDisplayText("SecurityGroupEnabledNetwork");
+        }
+
+        return config;
+    }
+
+    protected DirectNetworkGuru() {
+        super();
+        _isolationMethods = new IsolationMethod[] { new IsolationMethod("VLAN"), new IsolationMethod("VXLAN") };
+    }
+
+    public IsolationMethod[] getIsolationMethods() {
+        return _isolationMethods;
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        if (profile != null) {
+            profile.setIPv4Dns1(dc.getDns1());
+            profile.setIPv4Dns2(dc.getDns2());
+            profile.setIPv6Dns1(dc.getIp6Dns1());
+            profile.setIPv6Dns2(dc.getIp6Dns2());
+        }
+    }
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+
+        if (nic == null) {
+            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        } else if (nic.getIPv4Address() == null && nic.getIPv6Address() == null) {
+            nic.setReservationStrategy(ReservationStrategy.Start);
+        } else {
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+
+        allocateDirectIp(nic, network, vm, dc, nic.getRequestedIPv4(), nic.getRequestedIPv6());
+        nic.setReservationStrategy(ReservationStrategy.Create);
+
+        if (nic.getMacAddress() == null) {
+            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
+            if (nic.getMacAddress() == null) {
+                throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
+            }
+        }
+
+        return nic;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+        if (nic.getIPv4Address() == null && nic.getIPv6Address() == null) {
+            allocateDirectIp(nic, network, vm, dest.getDataCenter(), null, null);
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+    }
+
+    @DB
+    protected void allocateDirectIp(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DataCenter dc, final String requestedIp4Addr,
+        final String requestedIp6Addr) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+
+        try {
+            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientVirtualNetworkCapacityException,
+                        InsufficientAddressCapacityException {
+                    if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                        _ipAddrMgr.allocateNicValues(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr);
+                    } else {
+                        _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, requestedIp4Addr, requestedIp6Addr);
+                        //save the placeholder nic if the vm is the Virtual router
+                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
+                            if (placeholderNic == null) {
+                                s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIPv4Address() + " and ipv6 address " + nic.getIPv6Address() +
+                                        " for the network " + network);
+                                _networkMgr.savePlaceholderNic(network, nic.getIPv4Address(), nic.getIPv6Address(), VirtualMachine.Type.DomainRouter);
+                            }
+                        }
+                    }
+                }
+            });
+        } catch (InsufficientCapacityException e) {
+            ExceptionUtil.rethrow(e, InsufficientVirtualNetworkCapacityException.class);
+            ExceptionUtil.rethrow(e, InsufficientAddressCapacityException.class);
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        return true;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        return network;
+    }
+
+    @Override
+    @DB
+    public void deallocate(final Network network, final NicProfile nic, VirtualMachineProfile vm) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
+        }
+
+        if (nic.getIPv4Address() != null) {
+            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
+            if (ip != null) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        // if the ip address a part of placeholder, don't release it
+                        Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
+                        if (placeholderNic != null && placeholderNic.getIPv4Address().equalsIgnoreCase(ip.getAddress().addr())) {
+                            s_logger.debug("Not releasing direct ip " + ip.getId() + " yet as its ip is saved in the placeholder");
+                        } else {
+                            _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                            _ipAddressDao.unassignIpAddress(ip.getId());
+                        }
+
+                        //unassign nic secondary ip address
+                        s_logger.debug("remove nic " + nic.getId() + " secondary ip ");
+                        List<String> nicSecIps = null;
+                        nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId());
+                        for (String secIp : nicSecIps) {
+                            if (NetUtils.isValidIp4(secIp)) {
+                                IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp);
+                                _ipAddrMgr.markIpAsUnavailable(pubIp.getId());
+                                _ipAddressDao.unassignIpAddress(pubIp.getId());
+                            } else {
+                                NicSecondaryIpVO nicSecIp = nicSecondaryIpDao.findByIp6AddressAndNetworkId(secIp, nic.getNetworkId());
+                                if (nicSecIp != null) {
+                                    networkService.releaseSecondaryIpFromNic(nicSecIp.getId());
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+        }
+
+        nic.deallocate();
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering) {
+    }
+
+    @Override
+    @DB
+    public boolean trash(Network network, NetworkOffering offering) {
+        //Have to remove all placeholder nics
+        try {
+            long id = network.getId();
+            final List<NicVO> nics = _nicDao.listPlaceholderNicsByNetworkId(id);
+            if (nics != null) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        for (Nic nic : nics) {
+                            if (nic.getIPv4Address() != null) {
+                                s_logger.debug("Releasing ip " + nic.getIPv4Address() + " of placeholder nic " + nic);
+                                IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
+                                if (ip != null) {
+                                    _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                                    _ipAddressDao.unassignIpAddress(ip.getId());
+                                    s_logger.debug("Removing placeholder nic " + nic);
+                                    _nicDao.remove(nic.getId());
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+            return true;
+        }catch (Exception e) {
+            s_logger.error("trash. Exception:" + e.getMessage());
+            throw new CloudRuntimeException("trash. Exception:" + e.getMessage(),e);
+        }
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
+        networkProfile.setDns1(dc.getDns1());
+        networkProfile.setDns2(dc.getDns2());
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/guru/DirectPodBasedNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/DirectPodBasedNetworkGuru.java
new file mode 100644
index 0000000..01b3389
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/DirectPodBasedNetworkGuru.java
@@ -0,0 +1,247 @@
+// 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.network.guru;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.googlecode.ipv6.IPv6Address;
+
+public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(DirectPodBasedNetworkGuru.class);
+
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    PodVlanMapDao _podVlanDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering, DataCenter dc, PhysicalNetwork physnet) {
+        // this guru handles system Direct pod based network in Basic zones only (no isolation type specified)
+        if (dc.getNetworkType() == NetworkType.Basic && isMyTrafficType(offering.getTrafficType())) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest Direct Pod based networks");
+            return false;
+        }
+    }
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        DataCenterVO dc = _dcDao.findById(network.getDataCenterId());
+        ReservationStrategy rsStrategy = ReservationStrategy.Start;
+        _dcDao.loadDetails(dc);
+        String dhcpStrategy = dc.getDetail(ZoneConfig.DhcpStrategy.key());
+        if ("external".equalsIgnoreCase(dhcpStrategy)) {
+            rsStrategy = ReservationStrategy.Create;
+        }
+
+        if (nic == null) {
+            nic = new NicProfile(rsStrategy, null, null, null, null);
+        } else if (nic.getIPv4Address() == null) {
+            nic.setReservationStrategy(ReservationStrategy.Start);
+        } else {
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+
+        if (rsStrategy == ReservationStrategy.Create) {
+            String mac = _networkModel.getNextAvailableMacAddressInNetwork(network.getId());
+            nic.setMacAddress(mac);
+        }
+        return nic;
+    }
+
+    @Override
+    @DB
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        String oldIp = nic.getIPv4Address();
+        boolean getNewIp = false;
+
+        if (oldIp == null) {
+            getNewIp = true;
+        } else {
+            // we need to get a new ip address if we try to deploy a vm in a different pod
+            final IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp);
+            if (ipVO != null) {
+                PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId());
+                if (mapVO.getPodId() != dest.getPod().getId()) {
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            //release the old ip here
+                            _ipAddrMgr.markIpAsUnavailable(ipVO.getId());
+                            _ipAddressDao.unassignIpAddress(ipVO.getId());
+                        }
+                    });
+
+                    nic.setIPv4Address(null);
+                    getNewIp = true;
+                }
+            }
+        }
+
+        if (getNewIp) {
+            //we don't set reservationStrategy to Create because we need this method to be called again for the case when vm fails to deploy in Pod1, and we try to redeploy it in Pod2
+            getIp(nic, dest.getPod(), vm, network);
+        }
+
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        nic.setIPv4Dns1(dc.getDns1());
+        nic.setIPv4Dns2(dc.getDns2());
+    }
+
+    @DB
+    protected void getIp(final NicProfile nic, final Pod pod, final VirtualMachineProfile vm, final Network network) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+        final DataCenter dc = _dcDao.findById(pod.getDataCenterId());
+            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
+                    PublicIp ip = null;
+                    List<PodVlanMapVO> podRefs = _podVlanDao.listPodVlanMapsByPod(pod.getId());
+                    VlanVO vlan = _vlanDao.findById(podRefs.get(0).getVlanDbId());
+
+                    if (nic.getIPv4Address() == null) {
+                        String podRangeGateway = null;
+                        if (!podRefs.isEmpty()) {
+                            podRangeGateway = vlan.getVlanGateway();
+                        }
+                        //Get ip address from the placeholder and don't allocate a new one
+                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId());
+                            if (placeholderNic != null) {
+                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address());
+                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                                s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network +
+                                    " and gateway " + podRangeGateway);
+                            }
+                        }
+
+                        if (ip == null) {
+                            ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), null, false, false);
+                        }
+
+                        nic.setIPv4Address(ip.getAddress().toString());
+                        nic.setFormat(AddressFormat.Ip4);
+                        nic.setIPv4Gateway(ip.getGateway());
+                        nic.setIPv4Netmask(ip.getNetmask());
+                        if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) {
+                            nic.setIsolationUri(IsolationType.Ec2.toUri(Vlan.UNTAGGED));
+                            nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED));
+                            nic.setBroadcastType(BroadcastDomainType.Native);
+                        }
+                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
+                        nic.setMacAddress(ip.getMacAddress());
+
+                        //save the placeholder nic if the vm is the Virtual router
+                        if (vm.getType() == VirtualMachine.Type.DomainRouter) {
+                            Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, pod.getId());
+                            if (placeholderNic == null) {
+                                s_logger.debug("Saving placeholder nic with ip4 address " + nic.getIPv4Address() + " for the network " + network);
+                                _networkMgr.savePlaceholderNic(network, nic.getIPv4Address(), null, VirtualMachine.Type.DomainRouter);
+                            }
+                        }
+                }
+
+                /**
+                 * Calculate the IPv6 Address the Instance will obtain using SLAAC and IPv6 EUI-64
+                 *
+                 * Linux, FreeBSD and Windows all calculate the same IPv6 address when configured properly.
+                 *
+                 * Using Router Advertisements the routers in the network should announce the IPv6 CIDR which is configured
+                 * in in the vlan table in the database.
+                 *
+                 * This way the NIC will be populated with a IPv6 address on which the Instance is reachable.
+                 */
+                if (vlan.getIp6Cidr() != null) {
+                    if (nic.getIPv6Address() == null) {
+                        s_logger.debug("Found IPv6 CIDR " + vlan.getIp6Cidr() + " for VLAN " + vlan.getId());
+                        nic.setIPv6Cidr(vlan.getIp6Cidr());
+                        nic.setIPv6Gateway(vlan.getIp6Gateway());
+
+                        IPv6Address ipv6addr = NetUtils.EUI64Address(vlan.getIp6Cidr(), nic.getMacAddress());
+                        s_logger.info("Calculated IPv6 address " + ipv6addr + " using EUI-64 for NIC " + nic.getUuid());
+                        nic.setIPv6Address(ipv6addr.toString());
+                    }
+                } else {
+                    s_logger.debug("No IPv6 CIDR configured for VLAN " + vlan.getId());
+                }
+            }
+        });
+
+        nic.setIPv4Dns1(dc.getDns1());
+        nic.setIPv4Dns2(dc.getDns2());
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java
new file mode 100644
index 0000000..da5a545
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -0,0 +1,332 @@
+// 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.network.guru;
+
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.FirewallRulesCidrsVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+import java.util.List;
+
+public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(ExternalGuestNetworkGuru.class);
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    DataCenterDao _zoneDao;
+    @Inject
+    PortForwardingRulesDao _pfRulesDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    FirewallRulesDao _fwRulesDao;
+    @Inject
+    FirewallRulesCidrsDao _fwRulesCidrDao;
+
+    public ExternalGuestNetworkGuru() {
+        super();
+        _isolationMethods = new IsolationMethod[] {new IsolationMethod("GRE"), new IsolationMethod("L3"), new IsolationMethod("VLAN")};
+    }
+
+    @Override
+    protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+        // This guru handles only Guest Isolated network that supports Source
+        // nat service
+        if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType())
+                && (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == GuestType.L2)
+                && isMyIsolationMethod(physicalNetwork) && !offering.isSystemOnly()) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+
+        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.Connectivity)) {
+            return null;
+        }
+
+        NetworkVO config = (NetworkVO)super.design(offering, plan, userSpecified, owner);
+        if (config == null) {
+            return null;
+        } else if (_networkModel.networkIsConfiguredForExternalNetworking(plan.getDataCenterId(), config.getId())) {
+            /* In order to revert userSpecified network setup */
+            config.setState(State.Allocated);
+        }
+
+        return config;
+    }
+
+    @Override
+    public Network implement(Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        assert (config.getState() == State.Implementing) : "Why are we implementing " + config;
+
+        if (_networkModel.areServicesSupportedInNetwork(config.getId(), Network.Service.Connectivity)) {
+            return null;
+        }
+
+        if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
+            return super.implement(config, offering, dest, context);
+        }
+
+        DataCenter zone = dest.getDataCenter();
+        NetworkVO implemented =
+            new NetworkVO(config.getTrafficType(), config.getMode(), config.getBroadcastDomainType(), config.getNetworkOfferingId(), State.Allocated,
+                config.getDataCenterId(), config.getPhysicalNetworkId(), offering.isRedundantRouter());
+
+        // Get a vlan tag
+        int vlanTag;
+        if (config.getBroadcastUri() == null) {
+            String vnet =
+                _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), context.getReservationId(),
+                    UseSystemGuestVlans.valueIn(config.getAccountId()));
+
+            try {
+                // when supporting more types of networks this need to become
+//              int vlantag = Integer.parseInt(BroadcastDomainType.getValue(vnet));
+                vlanTag = Integer.parseInt(vnet);
+            } catch (NumberFormatException e) {
+                throw new CloudRuntimeException("Obtained an invalid guest vlan tag. Exception: " + e.getMessage());
+            }
+
+            implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanTag));
+            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), config.getAccountId(), EventVO.LEVEL_INFO,
+                EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + config.getId(), 0);
+        } else {
+            vlanTag = Integer.parseInt(BroadcastDomainType.getValue(config.getBroadcastUri()));
+            implemented.setBroadcastUri(config.getBroadcastUri());
+        }
+
+        // Determine the new gateway and CIDR
+        String[] oldCidr = config.getCidr().split("/");
+        String oldCidrAddress = oldCidr[0];
+        int cidrSize = Integer.parseInt(oldCidr[1]);
+        long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress));
+        // if the implementing network is for vpc, no need to generate newcidr, use the cidr that came from super cidr
+        if (config.getVpcId() != null) {
+            implemented.setGateway(config.getGateway());
+            implemented.setCidr(config.getCidr());
+            implemented.setState(State.Implemented);
+        } else {
+            // Determine the offset from the lowest vlan tag
+            int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag);
+            cidrSize = getGloballyConfiguredCidrSize();
+            // If the offset has more bits than there is room for, return null
+            long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset);
+            if (bitsInOffset > (cidrSize - 8)) {
+                throw new CloudRuntimeException("The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with.");
+            }
+            newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize));
+            implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1));
+            implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize);
+            implemented.setState(State.Implemented);
+        }
+
+        // Mask the Ipv4 address of all nics that use this network with the new guest VLAN offset
+        List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(config.getId());
+        for (NicVO nic : nicsInNetwork) {
+            if (nic.getIPv4Address() != null) {
+                long ipMask = getIpMask(nic.getIPv4Address(), cidrSize);
+                nic.setIPv4Address(NetUtils.long2Ip(newCidrAddress | ipMask));
+                _nicDao.persist(nic);
+            }
+        }
+
+        // Mask the destination address of all port forwarding rules in this network with the new guest VLAN offset
+        List<PortForwardingRuleVO> pfRulesInNetwork = _pfRulesDao.listByNetwork(config.getId());
+        for (PortForwardingRuleVO pfRule : pfRulesInNetwork) {
+            if (pfRule.getDestinationIpAddress() != null) {
+                long ipMask = getIpMask(pfRule.getDestinationIpAddress().addr(), cidrSize);
+                String maskedDestinationIpAddress = NetUtils.long2Ip(newCidrAddress | ipMask);
+                pfRule.setDestinationIpAddress(new Ip(maskedDestinationIpAddress));
+                _pfRulesDao.update(pfRule.getId(), pfRule);
+            }
+        }
+        // Mask the destination address of all static nat rules in this network with the new guest VLAN offset
+        // Here the private ip of the nic get updated. When secondary ip are present the gc will not triggered
+        List<IPAddressVO> ipAddrsOfNw = _ipAddressDao.listStaticNatPublicIps(config.getId());
+        for (IPAddressVO ip : ipAddrsOfNw) {
+            if (ip.getVmIp() != null) {
+                long ipMask = getIpMask(ip.getVmIp(), cidrSize);
+                String maskedVmIp = NetUtils.long2Ip(newCidrAddress | ipMask);
+                ip.setVmIp(maskedVmIp);
+                _ipAddressDao.update(ip.getId(), ip);
+            }
+        }
+
+        //Egress rules cidr is subset of guest nework cidr, we need to change
+        List <FirewallRuleVO> fwEgressRules = _fwRulesDao.listByNetworkPurposeTrafficType(config.getId(), FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress);
+
+        for (FirewallRuleVO rule: fwEgressRules) {
+            //get the cidr list for this rule
+            List<FirewallRulesCidrsVO>  fwRuleCidrsVo = _fwRulesCidrDao.listByFirewallRuleId(rule.getId());
+
+            for (FirewallRulesCidrsVO ruleCidrvo: fwRuleCidrsVo) {
+                String cidr = ruleCidrvo.getCidr();
+                String cidrAddr =  cidr.split("/")[0];
+                String size = cidr.split("/")[1];
+
+                long ipMask = getIpMask(cidrAddr, cidrSize);
+                String newIp = NetUtils.long2Ip(newCidrAddress | ipMask);
+                String updatedCidr = newIp+"/"+size;
+
+                ruleCidrvo.setSourceCidrList(updatedCidr);
+                _fwRulesCidrDao.update(ruleCidrvo.getId(), ruleCidrvo);
+            }
+
+        }
+
+
+        return implemented;
+    }
+
+    @Override
+    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+
+        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId()) && nic != null && nic.getRequestedIPv4() != null) {
+            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
+        }
+
+        NicProfile profile = super.allocate(config, nic, vm);
+
+        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
+            profile.setReservationStrategy(ReservationStrategy.Start);
+            /* We won't clear IP address, because router may set gateway as it IP, and it would be updated properly later */
+            //profile.setIp4Address(null);
+            profile.setIPv4Gateway(null);
+            profile.setIPv4Netmask(null);
+        }
+
+        return profile;
+    }
+
+    @Override
+    @DB
+    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
+        super.deallocate(config, nic, vm);
+
+        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
+            nic.setIPv4Address(null);
+            nic.setIPv4Gateway(null);
+            nic.setIPv4Netmask(null);
+            nic.setBroadcastUri(null);
+            nic.setIsolationUri(null);
+        }
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? ";
+
+        DataCenter dc = _dcDao.findById(config.getDataCenterId());
+
+        if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
+            nic.setBroadcastUri(config.getBroadcastUri());
+            nic.setIsolationUri(config.getBroadcastUri());
+            nic.setIPv4Dns1(dc.getDns1());
+            nic.setIPv4Dns2(dc.getDns2());
+            nic.setIPv4Netmask(NetUtils.cidr2Netmask(config.getCidr()));
+            long cidrAddress = NetUtils.ip2Long(config.getCidr().split("/")[0]);
+            int cidrSize = getGloballyConfiguredCidrSize();
+            nic.setIPv4Gateway(config.getGateway());
+
+            if (nic.getIPv4Address() == null) {
+                if (!_networkModel.listNetworkOfferingServices(config.getNetworkOfferingId()).isEmpty()) {
+                    String guestIp = _ipAddrMgr.acquireGuestIpAddress(config, null);
+                    if (guestIp == null) {
+                        throw new InsufficientVirtualNetworkCapacityException("Unable to acquire guest IP address for network " + config, DataCenter.class, dc.getId());
+                    }
+
+                    nic.setIPv4Address(guestIp);
+                }
+            } else {
+                long ipMask = NetUtils.ip2Long(nic.getIPv4Address()) & ~(0xffffffffffffffffl << (32 - cidrSize));
+                nic.setIPv4Address(NetUtils.long2Ip(cidrAddress | ipMask));
+            }
+        } else {
+            super.reserve(nic, config, vm, dest, context);
+        }
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+
+        NetworkVO network = _networkDao.findById(nic.getNetworkId());
+
+        if (network != null && _networkModel.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
+            return true;
+        } else {
+            return super.release(nic, vm, reservationId);
+        }
+    }
+
+    private long getIpMask(String ipAddress, long cidrSize) {
+        return NetUtils.ip2Long(ipAddress) & ~(0xffffffffffffffffl << (32 - cidrSize));
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java
new file mode 100644
index 0000000..9cd3374
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java
@@ -0,0 +1,465 @@
+// 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.network.guru;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.inject.Inject;
+
+import com.cloud.network.Network.GuestType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+
+public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGuru, Configurable {
+    private static final Logger s_logger = Logger.getLogger(GuestNetworkGuru.class);
+
+    @Inject
+    protected VpcDao _vpcDao;
+    @Inject
+    protected NetworkOrchestrationService _networkMgr;
+    @Inject
+    protected NetworkModel _networkModel;
+    @Inject
+    protected DataCenterDao _dcDao;
+    @Inject
+    protected VlanDao _vlanDao;
+    @Inject
+    protected NicDao _nicDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    protected NetworkDao _networkDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    protected PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    ConfigurationServer _configServer;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    Random _rand = new Random(System.currentTimeMillis());
+
+    static final ConfigKey<Boolean> UseSystemGuestVlans =
+            new ConfigKey<Boolean>(
+                    "Advanced",
+                    Boolean.class,
+                    "use.system.guest.vlans",
+                    "true",
+                    "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool",
+                    false, ConfigKey.Scope.Account);
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
+
+    // Currently set to anything except STT for the Nicira integration.
+    protected IsolationMethod[] _isolationMethods;
+
+    String _defaultGateway;
+    String _defaultCidr;
+
+    protected GuestNetworkGuru() {
+        super();
+        _isolationMethods = null;
+    }
+
+    @Override
+    public boolean isMyTrafficType(final TrafficType type) {
+        for (final TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    public boolean isMyIsolationMethod(final PhysicalNetwork physicalNetwork) {
+        if (physicalNetwork == null) {
+            // Can't tell if there is no physical network
+            return false;
+        }
+
+        List<String> methods = new ArrayList<String>();
+        for (final String method : physicalNetwork.getIsolationMethods()) {
+            methods.add(method.toLowerCase());
+        }
+        if (methods.isEmpty()) {
+            // The empty isolation method is assumed to be VLAN
+            s_logger.debug("Empty physical isolation type for physical network " + physicalNetwork.getUuid());
+            methods = new ArrayList<String>(1);
+            methods.add("VLAN".toLowerCase());
+        }
+
+        for (final IsolationMethod m : _isolationMethods) {
+            if (methods.contains(m.toString().toLowerCase())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public IsolationMethod[] getIsolationMethods() {
+        return _isolationMethods;
+    }
+
+    protected abstract boolean canHandle(NetworkOffering offering, final NetworkType networkType, PhysicalNetwork physicalNetwork);
+
+    @Override
+    public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) {
+        final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+        final PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+
+        if (!canHandle(offering, dc.getNetworkType(), physnet)) {
+            return null;
+        }
+
+        final NetworkVO network =
+                new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(),
+                        plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        if (userSpecified != null) {
+            if (userSpecified.getCidr() == null && userSpecified.getGateway() != null || userSpecified.getCidr() != null && userSpecified.getGateway() == null) {
+                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
+            }
+
+            if (userSpecified.getCidr() != null) {
+                network.setCidr(userSpecified.getCidr());
+                network.setGateway(userSpecified.getGateway());
+            } else if (offering.getGuestType() != GuestType.L2 && (offering.getGuestType() == GuestType.Shared || !_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty())) {
+                final String guestNetworkCidr = dc.getGuestNetworkCidr();
+                if (guestNetworkCidr != null) {
+                    final String[] cidrTuple = guestNetworkCidr.split("\\/");
+                    network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
+                    network.setCidr(guestNetworkCidr);
+                } else if (dc.getNetworkType() == NetworkType.Advanced) {
+                    throw new CloudRuntimeException("Can't design network " + network + "; guest CIDR is not configured per zone " + dc);
+                }
+            }
+
+            if (offering.isSpecifyVlan()) {
+                network.setBroadcastUri(userSpecified.getBroadcastUri());
+                network.setState(State.Setup);
+            }
+        } else {
+            final String guestNetworkCidr = dc.getGuestNetworkCidr();
+            if (guestNetworkCidr == null && dc.getNetworkType() == NetworkType.Advanced) {
+                throw new CloudRuntimeException("Can't design network " + network + "; guest CIDR is not configured per zone " + dc);
+            }
+            final String[] cidrTuple = guestNetworkCidr.split("\\/");
+            network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
+            network.setCidr(guestNetworkCidr);
+        }
+
+        return network;
+    }
+
+    @Override
+    @DB
+    public void deallocate(final Network network, final NicProfile nic, final VirtualMachineProfile vm) {
+        if (network.getSpecifyIpRanges()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
+            }
+
+            final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
+            if (ip != null) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                        _ipAddressDao.unassignIpAddress(ip.getId());
+                    }
+                });
+            }
+            nic.deallocate();
+        }
+    }
+
+    public int getVlanOffset(final long physicalNetworkId, final int vlanTag) {
+        final PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (pNetwork == null) {
+            throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
+        }
+
+        if (pNetwork.getVnet() == null) {
+            throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
+        }
+        Integer lowestVlanTag = null;
+        final List<Pair<Integer, Integer>> vnetList = pNetwork.getVnet();
+        //finding the vlanrange in which the vlanTag lies.
+        for (final Pair<Integer, Integer> vnet : vnetList) {
+            if (vlanTag >= vnet.first() && vlanTag <= vnet.second()) {
+                lowestVlanTag = vnet.first();
+            }
+        }
+        if (lowestVlanTag == null) {
+            throw new InvalidParameterValueException("The vlan tag does not belong to any of the existing vlan ranges");
+        }
+        return vlanTag - lowestVlanTag;
+    }
+
+    public int getGloballyConfiguredCidrSize() {
+        try {
+            final String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
+            return 8 + Integer.parseInt(globalVlanBits);
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
+        }
+    }
+
+    protected void allocateVnet(final Network network, final NetworkVO implemented, final long dcId, final long physicalNetworkId, final String reservationId)
+            throws InsufficientVirtualNetworkCapacityException {
+        if (network.getBroadcastUri() == null) {
+            final String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, UseSystemGuestVlans.valueIn(network.getAccountId()));
+            if (vnet == null) {
+                throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class,
+                        dcId);
+            }
+            implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet));
+            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO,
+                    EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0);
+        } else {
+            implemented.setBroadcastUri(network.getBroadcastUri());
+        }
+    }
+
+    @Override
+    public Network implement(final Network network, final NetworkOffering offering, final DeployDestination dest, final ReservationContext context)
+            throws InsufficientVirtualNetworkCapacityException {
+        assert network.getState() == State.Implementing : "Why are we implementing " + network;
+
+        final long dcId = dest.getDataCenter().getId();
+
+        //get physical network id
+        Long physicalNetworkId = network.getPhysicalNetworkId();
+
+        // physical network id can be null in Guest Network in Basic zone, so locate the physical network
+        if (physicalNetworkId == null) {
+            physicalNetworkId = _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
+        }
+
+        final NetworkVO implemented =
+                new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
+                        network.getDataCenterId(), physicalNetworkId, offering.isRedundantRouter());
+
+        allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
+
+        if (network.getGateway() != null) {
+            implemented.setGateway(network.getGateway());
+        }
+
+        if (network.getCidr() != null) {
+            implemented.setCidr(network.getCidr());
+        }
+        return implemented;
+    }
+
+    @Override
+    public NicProfile allocate(final Network network, NicProfile nic, final VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+    InsufficientAddressCapacityException {
+
+        assert network.getTrafficType() == TrafficType.Guest : "Look at my name!  Why are you calling" + " me when the traffic type is : " + network.getTrafficType();
+
+        if (nic == null) {
+            nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);
+        }
+
+        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
+
+        if (nic.getIPv4Address() == null) {
+            nic.setBroadcastUri(network.getBroadcastUri());
+            nic.setIsolationUri(network.getBroadcastUri());
+            nic.setIPv4Gateway(network.getGateway());
+
+            String guestIp = null;
+            if (network.getSpecifyIpRanges()) {
+                _ipAddrMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIPv4(), null);
+            } else {
+                //if Vm is router vm and source nat is enabled in the network, set ip4 to the network gateway
+                boolean isGateway = false;
+                if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
+                    if (network.getVpcId() != null) {
+                        final Vpc vpc = _vpcDao.findById(network.getVpcId());
+                        // Redundant Networks need a guest IP that is not the same as the gateway IP.
+                        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VPCVirtualRouter) && !vpc.isRedundant()) {
+                            isGateway = true;
+                        }
+                    } else {
+                        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VirtualRouter)) {
+                            isGateway = true;
+                        }
+                    }
+                }
+
+                if (isGateway) {
+                    guestIp = network.getGateway();
+                } else {
+                    guestIp = _ipAddrMgr.acquireGuestIpAddress(network, nic.getRequestedIPv4());
+                    if (guestIp == null && network.getGuestType() != GuestType.L2 && !_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
+                        throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class,
+                                dc.getId());
+                    }
+                }
+
+                nic.setIPv4Address(guestIp);
+                if (network.getCidr() != null) {
+                    nic.setIPv4Netmask(NetUtils.cidr2Netmask(_networkModel.getValidNetworkCidr(network)));
+                }
+
+                nic.setIPv4Dns1(dc.getDns1());
+                nic.setIPv4Dns2(dc.getDns2());
+                nic.setFormat(AddressFormat.Ip4);
+            }
+        }
+
+        nic.setReservationStrategy(ReservationStrategy.Start);
+
+        if (nic.getMacAddress() == null) {
+            nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
+            if (nic.getMacAddress() == null) {
+                throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
+            }
+        }
+
+        return nic;
+    }
+
+    @Override
+    public void updateNicProfile(final NicProfile profile, final Network network) {
+        final DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        if (profile != null) {
+            profile.setIPv4Dns1(dc.getDns1());
+            profile.setIPv4Dns2(dc.getDns2());
+        }
+    }
+
+    @Override
+    public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context)
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        assert nic.getReservationStrategy() == ReservationStrategy.Start : "What can I do for nics that are not allocated at start? ";
+
+        nic.setBroadcastUri(network.getBroadcastUri());
+        nic.setIsolationUri(network.getBroadcastUri());
+    }
+
+    @Override
+    public boolean release(final NicProfile nic, final VirtualMachineProfile vm, final String reservationId) {
+        nic.setBroadcastUri(null);
+        nic.setIsolationUri(null);
+        return true;
+    }
+
+    @Override
+    public void shutdown(final NetworkProfile profile, final NetworkOffering offering) {
+        if (profile.getBroadcastUri() == null) {
+            return; // Nothing to do here if the uri is null already
+        }
+
+        if ((profile.getBroadcastDomainType() == BroadcastDomainType.Vlan || profile.getBroadcastDomainType() == BroadcastDomainType.Vxlan) && !offering.isSpecifyVlan()) {
+            s_logger.debug("Releasing vnet for the network id=" + profile.getId());
+            _dcDao.releaseVnet(BroadcastDomainType.getValue(profile.getBroadcastUri()), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(),
+                    profile.getReservationId());
+            ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE,
+                    "Released Zone Vnet: " + BroadcastDomainType.getValue(profile.getBroadcastUri()) + " for Network: " + profile.getId(), 0);
+        }
+
+        profile.setBroadcastUri(null);
+    }
+
+    @Override
+    public boolean trash(final Network network, final NetworkOffering offering) {
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(final NetworkProfile networkProfile) {
+        final DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
+        networkProfile.setDns1(dc.getDns1());
+        networkProfile.setDns2(dc.getDns2());
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return GuestNetworkGuru.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {UseSystemGuestVlans};
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java
new file mode 100644
index 0000000..9f9771e
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java
@@ -0,0 +1,182 @@
+// 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.network.guru;
+
+import com.cloud.dc.dao.DataCenterDao.PrivateAllocationData;
+import com.cloud.vm.VirtualMachine;
+import java.util.Random;
+
+import javax.inject.Inject;
+
+import com.cloud.network.NetworkModel;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.Pod;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.StorageNetworkManager;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(PodBasedNetworkGuru.class);
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    StorageNetworkManager _sNwMgr;
+
+    Random _rand = new Random(System.currentTimeMillis());
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Management};
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        TrafficType type = offering.getTrafficType();
+
+        if (!isMyTrafficType(type)) {
+            return null;
+        }
+
+        NetworkVO config =
+            new NetworkVO(type, Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
+                    plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        return config;
+    }
+
+    protected PodBasedNetworkGuru() {
+        super();
+    }
+
+    @Override
+    public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
+    }
+
+    @Override
+    public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+        TrafficType trafficType = config.getTrafficType();
+        assert trafficType == TrafficType.Management || trafficType == TrafficType.Storage : "Well, I can't take care of this config now can I? " + config;
+
+        if (nic != null) {
+            if (nic.getRequestedIPv4() != null) {
+                throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
+            }
+            nic.setReservationStrategy(nic.getIPv4Address() != null ? ReservationStrategy.Create : ReservationStrategy.Start);
+        } else {
+            nic = new NicProfile(ReservationStrategy.Start, null, null, null, null);
+        }
+
+        return nic;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        Pod pod = dest.getPod();
+
+        boolean forSystemVms = vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm);
+        PrivateAllocationData result = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId(), forSystemVms);
+        if (result == null) {
+            throw new InsufficientAddressCapacityException("Unable to get a management ip address", Pod.class, pod.getId());
+        }
+        Integer vlan = result.getVlan();
+
+        nic.setIPv4Address(result.getIpAddress());
+        nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(result.getMacAddress(), NetworkModel.MACIdentifier.value())));
+        nic.setIPv4Gateway(pod.getGateway());
+        nic.setFormat(AddressFormat.Ip4);
+        String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
+        nic.setIPv4Netmask(netmask);
+        nic.setBroadcastType(BroadcastDomainType.Native);
+        if (vlan != null) {
+            nic.setBroadcastUri(BroadcastDomainType.Native.toUri(vlan));
+        } else {
+            nic.setBroadcastUri(null);
+        }
+        nic.setIsolationUri(null);
+
+        s_logger.debug("Allocated a nic " + nic + " for " + vm);
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        _dcDao.releasePrivateIpAddress(nic.getId(), nic.getReservationId());
+
+        nic.deallocate();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Released nic: " + nic);
+        }
+
+        return true;
+    }
+
+    @Override
+    public Network implement(Network config, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        return config;
+    }
+
+    @Override
+    public void shutdown(NetworkProfile config, NetworkOffering offering) {
+    }
+
+    @Override
+    public boolean trash(Network config, NetworkOffering offering) {
+        return true;
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java
new file mode 100644
index 0000000..3b3dabe1
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java
@@ -0,0 +1,245 @@
+// 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.network.guru;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.vpc.PrivateIpAddress;
+import com.cloud.network.vpc.PrivateIpVO;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(PrivateNetworkGuru.class);
+    @Inject
+    protected ConfigurationManager _configMgr;
+    @Inject
+    protected PrivateIpDao _privateIpDao;
+    @Inject
+    protected NetworkModel _networkMgr;
+    @Inject
+    EntityManager _entityMgr;
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Guest};
+
+    protected PrivateNetworkGuru() {
+        super();
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    protected boolean canHandle(NetworkOffering offering, DataCenter dc) {
+        // This guru handles only system Guest network
+        if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated &&
+            offering.isSystemOnly()) {
+            return true;
+        } else {
+            s_logger.trace("We only take care of system Guest networks of type   " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced);
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        DataCenter dc = _entityMgr.findById(DataCenter.class, plan.getDataCenterId());
+        if (!canHandle(offering, dc)) {
+            return null;
+        }
+
+        BroadcastDomainType broadcastType;
+        if (userSpecified != null) {
+            broadcastType = userSpecified.getBroadcastDomainType();
+        } else {
+            broadcastType = BroadcastDomainType.Vlan;
+        }
+        NetworkVO network =
+            new NetworkVO(offering.getTrafficType(), Mode.Static, broadcastType, offering.getId(), State.Allocated, plan.getDataCenterId(),
+                    plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        if (userSpecified != null) {
+            if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
+                throw new InvalidParameterValueException("cidr and gateway must be specified together.");
+            }
+
+            if (userSpecified.getCidr() != null) {
+                network.setCidr(userSpecified.getCidr());
+                network.setGateway(userSpecified.getGateway());
+            } else {
+                throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in");
+            }
+
+            if (offering.isSpecifyVlan()) {
+                network.setBroadcastUri(userSpecified.getBroadcastUri());
+                network.setState(State.Setup);
+            }
+        } else {
+            throw new CloudRuntimeException("Can't design network " + network + "; netmask/gateway must be passed in");
+
+        }
+
+        return network;
+    }
+
+    @Override
+    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
+        }
+
+        PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
+        if (ip != null) {
+            _privateIpDao.releaseIpAddress(nic.getIPv4Address(), nic.getNetworkId());
+        }
+        nic.deallocate();
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+
+        return network;
+    }
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+        DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+        if (!canHandle(offering, dc)) {
+            return null;
+        }
+
+        if (nic == null) {
+            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        }
+
+        getIp(nic, dc, network);
+
+        if (nic.getIPv4Address() == null) {
+            nic.setReservationStrategy(ReservationStrategy.Start);
+        } else {
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+
+        return nic;
+    }
+
+    protected void getIp(NicProfile nic, DataCenter dc, Network network) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        if (nic.getIPv4Address() == null) {
+            PrivateIpVO ipVO = _privateIpDao.allocateIpAddress(network.getDataCenterId(), network.getId(), null);
+            String vlanTag = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String netmask = NetUtils.getCidrNetmask(network.getCidr());
+            PrivateIpAddress ip =
+                new PrivateIpAddress(ipVO, vlanTag, network.getGateway(), netmask, NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress(), NetworkModel.MACIdentifier.value())));
+
+            nic.setIPv4Address(ip.getIpAddress());
+            nic.setIPv4Gateway(ip.getGateway());
+            nic.setIPv4Netmask(ip.getNetmask());
+            nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getBroadcastUri()));
+            nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getBroadcastUri()));
+            nic.setBroadcastType(BroadcastDomainType.Vlan);
+            nic.setFormat(AddressFormat.Ip4);
+            nic.setReservationId(String.valueOf(ip.getBroadcastUri()));
+            nic.setMacAddress(ip.getMacAddress());
+        }
+
+        nic.setIPv4Dns1(dc.getDns1());
+        nic.setIPv4Dns2(dc.getDns2());
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
+        if (profile != null) {
+            profile.setIPv4Dns1(dc.getDns1());
+            profile.setIPv4Dns2(dc.getDns2());
+        }
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        if (nic.getIPv4Address() == null) {
+            getIp(nic, _entityMgr.findById(DataCenter.class, network.getDataCenterId()), network);
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        return true;
+    }
+
+    @Override
+    public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        DataCenter dc = _entityMgr.findById(DataCenter.class, networkProfile.getDataCenterId());
+        networkProfile.setDns1(dc.getDns1());
+        networkProfile.setDns2(dc.getDns2());
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java
new file mode 100644
index 0000000..330a365
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java
@@ -0,0 +1,239 @@
+// 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.network.guru;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(PublicNetworkGuru.class);
+
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Public};
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    protected boolean canHandle(NetworkOffering offering) {
+        return isMyTrafficType(offering.getTrafficType()) && offering.isSystemOnly();
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network network, Account owner) {
+        if (!canHandle(offering)) {
+            return null;
+        }
+
+        if (offering.getTrafficType() == TrafficType.Public) {
+            NetworkVO ntwk =
+                new NetworkVO(offering.getTrafficType(), Mode.Static, network.getBroadcastDomainType(), offering.getId(), State.Setup, plan.getDataCenterId(),
+                    plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+            return ntwk;
+        } else {
+            return null;
+        }
+    }
+
+    protected PublicNetworkGuru() {
+        super();
+    }
+
+    protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+        if (nic.getIPv4Address() == null) {
+            boolean forSystemVms = false;
+            if (vm.getType().equals(VirtualMachine.Type.ConsoleProxy) || vm.getType().equals(VirtualMachine.Type.SecondaryStorageVm)) {
+                forSystemVms = true;
+            }
+            PublicIp ip = _ipAddrMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null, null, false, forSystemVms);
+            nic.setIPv4Address(ip.getAddress().toString());
+            nic.setIPv4Gateway(ip.getGateway());
+            nic.setIPv4Netmask(ip.getNetmask());
+            if (network.getBroadcastDomainType() == BroadcastDomainType.Vxlan) {
+                nic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag()));
+                nic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag()));
+                nic.setBroadcastType(BroadcastDomainType.Vxlan);
+            } else {
+                nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
+                nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
+                nic.setBroadcastType(BroadcastDomainType.Vlan);
+            }
+            nic.setFormat(AddressFormat.Ip4);
+            nic.setReservationId(String.valueOf(ip.getVlanTag()));
+            nic.setMacAddress(ip.getMacAddress());
+        }
+
+        nic.setIPv4Dns1(dc.getDns1());
+        nic.setIPv4Dns2(dc.getDns2());
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        if (profile != null) {
+            profile.setIPv4Dns1(dc.getDns1());
+            profile.setIPv4Dns2(dc.getDns2());
+        }
+    }
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+
+        if (nic != null && nic.getRequestedIPv4() != null) {
+            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic);
+        }
+
+        if (nic == null) {
+            nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        }
+
+        getIp(nic, dc, vm, network);
+
+        if (nic.getIPv4Address() == null) {
+            nic.setReservationStrategy(ReservationStrategy.Start);
+        } else if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
+            nic.setReservationStrategy(ReservationStrategy.Managed);
+        } else {
+            nic.setReservationStrategy(ReservationStrategy.Create);
+        }
+
+        return nic;
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+        if (nic.getIPv4Address() == null) {
+            getIp(nic, dest.getDataCenter(), vm, network);
+        }
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        return true;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        return network;
+    }
+
+    @Override
+    @DB
+    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("public network deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIPv4Address());
+        }
+
+        final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIPv4Address());
+        if (ip != null && nic.getReservationStrategy() != ReservationStrategy.Managed) {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                    _ipAddressDao.unassignIpAddress(ip.getId());
+                }
+            });
+        }
+        nic.deallocate();
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deallocated nic: " + nic);
+        }
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering) {
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
+        networkProfile.setDns1(dc.getDns1());
+        networkProfile.setDns2(dc.getDns2());
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/guru/StorageNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/StorageNetworkGuru.java
new file mode 100644
index 0000000..a26705e
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/guru/StorageNetworkGuru.java
@@ -0,0 +1,192 @@
+// 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.network.guru;
+
+import javax.inject.Inject;
+
+import com.cloud.network.NetworkModel;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.Pod;
+import com.cloud.dc.StorageNetworkIpAddressVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.StorageNetworkManager;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachineProfile;
+
+public class StorageNetworkGuru extends PodBasedNetworkGuru implements NetworkGuru {
+    private static final Logger s_logger = Logger.getLogger(StorageNetworkGuru.class);
+    @Inject
+    StorageNetworkManager _sNwMgr;
+    @Inject
+    NetworkDao _nwDao;
+
+    protected StorageNetworkGuru() {
+        super();
+    }
+
+    private static final TrafficType[] TrafficTypes = {TrafficType.Storage};
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : TrafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return TrafficTypes;
+    }
+
+    protected boolean canHandle(NetworkOffering offering) {
+        if (isMyTrafficType(offering.getTrafficType()) && offering.isSystemOnly()) {
+            return true;
+        } else {
+            s_logger.trace("It's not storage network offering, skip it.");
+            return false;
+        }
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
+        if (!canHandle(offering)) {
+            return null;
+        }
+
+        NetworkVO config =
+            new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(),
+                plan.getPhysicalNetworkId(), offering.isRedundantRouter());
+        return config;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException {
+        assert network.getTrafficType() == TrafficType.Storage : "Why are you sending this configuration to me " + network;
+        if (!_sNwMgr.isStorageIpRangeAvailable(destination.getDataCenter().getId())) {
+            return super.implement(network, offering, destination, context);
+        }
+        return network;
+    }
+
+    @Override
+    public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException,
+        InsufficientAddressCapacityException {
+        assert network.getTrafficType() == TrafficType.Storage : "Well, I can't take care of this config now can I? " + network;
+        if (!_sNwMgr.isStorageIpRangeAvailable(network.getDataCenterId())) {
+            return super.allocate(network, nic, vm);
+        }
+
+        return new NicProfile(ReservationStrategy.Start, null, null, null, null);
+    }
+
+    @Override
+    public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+        if (!_sNwMgr.isStorageIpRangeAvailable(dest.getDataCenter().getId())) {
+            super.reserve(nic, network, vm, dest, context);
+            return;
+        }
+
+        Pod pod = dest.getPod();
+        Integer vlan = null;
+
+        StorageNetworkIpAddressVO ip = _sNwMgr.acquireIpAddress(pod.getId());
+        if (ip == null) {
+            throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId());
+        }
+
+        vlan = ip.getVlan();
+        nic.setIPv4Address(ip.getIpAddress());
+        nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.getMac(), NetworkModel.MACIdentifier.value())));
+        nic.setFormat(AddressFormat.Ip4);
+        nic.setIPv4Netmask(ip.getNetmask());
+        nic.setBroadcastType(BroadcastDomainType.Storage);
+        nic.setIPv4Gateway(ip.getGateway());
+        if (vlan != null) {
+            nic.setBroadcastUri(BroadcastDomainType.Storage.toUri(vlan));
+        } else {
+            nic.setBroadcastUri(null);
+        }
+        nic.setIsolationUri(null);
+        s_logger.debug("Allocated a storage nic " + nic + " for " + vm);
+    }
+
+    @Override
+    public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
+        Network nw = _nwDao.findById(nic.getNetworkId());
+        if (!_sNwMgr.isStorageIpRangeAvailable(nw.getDataCenterId())) {
+            return super.release(nic, vm, reservationId);
+        }
+
+        _sNwMgr.releaseIpAddress(nic.getIPv4Address());
+        s_logger.debug("Release an storage ip " + nic.getIPv4Address());
+        nic.deallocate();
+        return true;
+    }
+
+    @Override
+    public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManager.java b/server/src/main/java/com/cloud/network/lb/LBHealthCheckManager.java
similarity index 100%
rename from server/src/com/cloud/network/lb/LBHealthCheckManager.java
rename to server/src/main/java/com/cloud/network/lb/LBHealthCheckManager.java
diff --git a/server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java b/server/src/main/java/com/cloud/network/lb/LBHealthCheckManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/lb/LBHealthCheckManagerImpl.java
rename to server/src/main/java/com/cloud/network/lb/LBHealthCheckManagerImpl.java
diff --git a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
new file mode 100644
index 0000000..d2b6305
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -0,0 +1,2598 @@
+// 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.network.lb;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.response.ServiceResponse;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO;
+import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.dao.EventDao;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.ExternalDeviceUsageManager;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.LBHealthCheckPolicyVO;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.as.AutoScalePolicy;
+import com.cloud.network.as.AutoScalePolicyConditionMapVO;
+import com.cloud.network.as.AutoScaleVmGroup;
+import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO;
+import com.cloud.network.as.AutoScaleVmGroupVO;
+import com.cloud.network.as.AutoScaleVmProfile;
+import com.cloud.network.as.Condition;
+import com.cloud.network.as.Counter;
+import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
+import com.cloud.network.as.dao.AutoScalePolicyDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
+import com.cloud.network.as.dao.AutoScaleVmProfileDao;
+import com.cloud.network.as.dao.ConditionDao;
+import com.cloud.network.as.dao.CounterDao;
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LBHealthCheckPolicyDao;
+import com.cloud.network.dao.LBStickinessPolicyDao;
+import com.cloud.network.dao.LBStickinessPolicyVO;
+import com.cloud.network.dao.LoadBalancerCertMapDao;
+import com.cloud.network.dao.LoadBalancerCertMapVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.LoadBalancerVMMapVO;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.SslCertVO;
+import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy;
+import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup;
+import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile;
+import com.cloud.network.lb.LoadBalancingRule.LbCondition;
+import com.cloud.network.lb.LoadBalancingRule.LbDestination;
+import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
+import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
+import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.FirewallRuleType;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.HealthCheckPolicy;
+import com.cloud.network.rules.LbStickinessMethod;
+import com.cloud.network.rules.LbStickinessMethod.LbStickinessMethodParam;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.StickinessPolicy;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService {
+    private static final Logger s_logger = Logger.getLogger(LoadBalancingRulesManagerImpl.class);
+
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    RulesManager _rulesMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    EventDao _eventDao;
+    @Inject
+    LoadBalancerVMMapDao _lb2VmMapDao;
+    @Inject
+    LBStickinessPolicyDao _lb2stickinesspoliciesDao;
+    @Inject
+    LBHealthCheckPolicyDao _lb2healthcheckDao;
+    @Inject
+    UserVmDao _vmDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    UsageEventDao _usageEventDao;
+    @Inject
+    FirewallRulesCidrsDao _firewallCidrsDao;
+    @Inject
+    FirewallManager _firewallMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    DomainService _domainMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+
+    @Inject
+    ExternalDeviceUsageManager _externalDeviceUsageMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    VMTemplateDao _templateDao;
+    @Inject
+    ServiceOfferingDao _offeringsDao;
+    @Inject
+    CounterDao _counterDao;
+    @Inject
+    ConditionDao _conditionDao;
+    @Inject
+    AutoScaleVmProfileDao _autoScaleVmProfileDao;
+    @Inject
+    AutoScalePolicyDao _autoScalePolicyDao;
+    @Inject
+    AutoScalePolicyConditionMapDao _autoScalePolicyConditionMapDao;
+    @Inject
+    AutoScaleVmGroupDao _autoScaleVmGroupDao;
+    @Inject
+    AutoScaleVmGroupPolicyMapDao _autoScaleVmGroupPolicyMapDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    DataCenterDao _dcDao = null;
+    @Inject
+    UserDao _userDao;
+    List<LoadBalancingServiceProvider> _lbProviders;
+    @Inject
+    ApplicationLoadBalancerRuleDao _appLbRuleDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    LoadBalancerCertMapDao _lbCertMapDao;
+
+    @Inject
+    NicSecondaryIpDao _nicSecondaryIpDao;
+
+    // Will return a string. For LB Stickiness this will be a json, for
+    // autoscale this will be "," separated values
+    @Override
+    public String getLBCapability(long networkid, String capabilityName) {
+        Map<Service, Map<Capability, String>> serviceCapabilitiesMap = _networkModel.getNetworkCapabilities(networkid);
+        if (serviceCapabilitiesMap != null) {
+            for (Service service : serviceCapabilitiesMap.keySet()) {
+                ServiceResponse serviceResponse = new ServiceResponse();
+                serviceResponse.setName(service.getName());
+                if ("Lb".equalsIgnoreCase(service.getName())) {
+                    Map<Capability, String> serviceCapabilities = serviceCapabilitiesMap.get(service);
+                    if (serviceCapabilities != null) {
+                        for (Capability capability : serviceCapabilities.keySet()) {
+                            if (capabilityName.equals(capability.getName())) {
+                                return serviceCapabilities.get(capability);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private LbAutoScaleVmGroup getLbAutoScaleVmGroup(AutoScaleVmGroupVO vmGroup, String currentState, LoadBalancerVO lb) {
+        long lbNetworkId = lb.getNetworkId();
+        String lbName = lb.getName();
+        List<AutoScaleVmGroupPolicyMapVO> vmGroupPolicyMapList = _autoScaleVmGroupPolicyMapDao.listByVmGroupId(vmGroup.getId());
+        List<LbAutoScalePolicy> autoScalePolicies = new ArrayList<LbAutoScalePolicy>();
+        for (AutoScaleVmGroupPolicyMapVO vmGroupPolicyMap : vmGroupPolicyMapList) {
+            AutoScalePolicy autoScalePolicy = _autoScalePolicyDao.findById(vmGroupPolicyMap.getPolicyId());
+            List<AutoScalePolicyConditionMapVO> autoScalePolicyConditionMapList = _autoScalePolicyConditionMapDao.listByAll(autoScalePolicy.getId(), null);
+            List<LbCondition> lbConditions = new ArrayList<LbCondition>();
+            for (AutoScalePolicyConditionMapVO autoScalePolicyConditionMap : autoScalePolicyConditionMapList) {
+                Condition condition = _conditionDao.findById(autoScalePolicyConditionMap.getConditionId());
+                Counter counter = _counterDao.findById(condition.getCounterid());
+                lbConditions.add(new LbCondition(counter, condition));
+            }
+            autoScalePolicies.add(new LbAutoScalePolicy(autoScalePolicy, lbConditions));
+        }
+        AutoScaleVmProfile autoScaleVmProfile = _autoScaleVmProfileDao.findById(vmGroup.getProfileId());
+        Long autoscaleUserId = autoScaleVmProfile.getAutoScaleUserId();
+        User user = _userDao.findByIdIncludingRemoved(autoscaleUserId);
+        String apiKey = user.getApiKey();
+        String secretKey = user.getSecretKey();
+        String csUrl = ApiServiceConfiguration.ApiServletPath.value();
+        String zoneId = _dcDao.findById(autoScaleVmProfile.getZoneId()).getUuid();
+        String domainId = _domainDao.findById(autoScaleVmProfile.getDomainId()).getUuid();
+        String serviceOfferingId = _offeringsDao.findById(autoScaleVmProfile.getServiceOfferingId()).getUuid();
+        String templateId = _templateDao.findById(autoScaleVmProfile.getTemplateId()).getUuid();
+        String vmName = "AutoScale-LB-" + lbName;
+        String lbNetworkUuid = null;
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, vmGroup.getZoneId());
+        if (zone == null) {
+            // This should never happen, but still a cautious check
+            s_logger.warn("Unable to find zone while packaging AutoScale Vm Group, zoneid: " + vmGroup.getZoneId());
+            throw new InvalidParameterValueException("Unable to find zone");
+        } else {
+            if (zone.getNetworkType() == NetworkType.Advanced) {
+                NetworkVO lbNetwork = _networkDao.findById(lbNetworkId);
+                lbNetworkUuid = lbNetwork.getUuid();
+            }
+        }
+
+        if (apiKey == null) {
+            throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it");
+        }
+
+        if (secretKey == null) {
+            throw new InvalidParameterValueException("secretKey for user: " + user.getUsername() + " is empty. Please generate it");
+        }
+
+        if (csUrl == null || csUrl.contains("localhost")) {
+            throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
+        }
+
+        LbAutoScaleVmProfile lbAutoScaleVmProfile =
+            new LbAutoScaleVmProfile(autoScaleVmProfile, apiKey, secretKey, csUrl, zoneId, domainId, serviceOfferingId, templateId, vmName, lbNetworkUuid);
+        return new LbAutoScaleVmGroup(vmGroup, autoScalePolicies, lbAutoScaleVmProfile, currentState);
+    }
+
+    private boolean applyAutoScaleConfig(LoadBalancerVO lb, AutoScaleVmGroupVO vmGroup, String currentState) throws ResourceUnavailableException {
+        LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup, currentState, lb);
+        /*
+         * Regular config like destinations need not be packed for applying
+         * autoscale config as of today.
+         */
+        List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
+        Ip sourceIp = getSourceIp(lb);
+        LoadBalancingRule rule = new LoadBalancingRule(lb, null, policyList, null, sourceIp, null, lb.getLbProtocol());
+        rule.setAutoScaleVmGroup(lbAutoScaleVmGroup);
+
+        if (!isRollBackAllowedForProvider(lb)) {
+            // this is for Netscaler type of devices. if their is failure the db
+            // entries will be rollbacked.
+            return false;
+        }
+
+        List<LoadBalancingRule> rules = Arrays.asList(rule);
+
+        if (!applyLbRules(rules, false)) {
+            s_logger.debug("LB rules' autoscale config are not completely applied");
+            return false;
+        }
+
+        return true;
+    }
+
+    private Ip getSourceIp(LoadBalancer lb) {
+        Ip sourceIp = null;
+        if (lb.getScheme() == Scheme.Public) {
+            sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
+        } else if (lb.getScheme() == Scheme.Internal) {
+            ApplicationLoadBalancerRuleVO appLbRule = _appLbRuleDao.findById(lb.getId());
+            sourceIp = appLbRule.getSourceIp();
+        }
+        return sourceIp;
+    }
+
+    @Override
+    @DB
+    public boolean configureLbAutoScaleVmGroup(final long vmGroupid, String currentState) throws ResourceUnavailableException {
+        final AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.findById(vmGroupid);
+        boolean success = false;
+
+        final LoadBalancerVO loadBalancer = _lbDao.findById(vmGroup.getLoadBalancerId());
+
+        FirewallRule.State backupState = loadBalancer.getState();
+
+        if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) {
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+        } else if (loadBalancer.getState() == FirewallRule.State.Active && vmGroup.getState().equals(AutoScaleVmGroup.State_Revoke)) {
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+        }
+
+        try {
+            success = applyAutoScaleConfig(loadBalancer, vmGroup, currentState);
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to configure AutoScaleVmGroup to the lb rule: " + loadBalancer.getId() + " because resource is unavaliable:", e);
+            if (isRollBackAllowedForProvider(loadBalancer)) {
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating AutoscaleVmGroup");
+            }
+            throw e;
+        } finally {
+            if (!success) {
+                s_logger.warn("Failed to configure LB Auto Scale Vm Group with Id:" + vmGroupid);
+            }
+        }
+
+        if (success) {
+            if (vmGroup.getState().equals(AutoScaleVmGroup.State_New)) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        loadBalancer.setState(FirewallRule.State.Active);
+                        s_logger.debug("LB rule " + loadBalancer.getId() + " state is set to Active");
+                        _lbDao.persist(loadBalancer);
+                        vmGroup.setState(AutoScaleVmGroup.State_Enabled);
+                        _autoScaleVmGroupDao.persist(vmGroup);
+                        s_logger.debug("LB Auto Scale Vm Group with Id: " + vmGroupid + " is set to Enabled state.");
+                    }
+                });
+            }
+            s_logger.info("Successfully configured LB Autoscale Vm Group with Id: " + vmGroupid);
+        }
+        return success;
+    }
+
+    private boolean validateHealthCheck(CreateLBHealthCheckPolicyCmd cmd) {
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.HealthCheckPolicy.getName());
+        if (capability != null) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean genericValidator(CreateLBStickinessPolicyCmd cmd) throws InvalidParameterValueException {
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        /* Validation : check for valid Method name and params */
+        List<LbStickinessMethod> stickinessMethodList = getStickinessMethods(loadBalancer.getNetworkId());
+        boolean methodMatch = false;
+
+        if (stickinessMethodList == null) {
+            throw new InvalidParameterValueException("Failed:  No Stickiness method available for LB rule:" + cmd.getLbRuleId());
+        }
+        for (LbStickinessMethod method : stickinessMethodList) {
+            if (method.getMethodName().equalsIgnoreCase(cmd.getStickinessMethodName())) {
+                methodMatch = true;
+                Map apiParamList = cmd.getparamList();
+                List<LbStickinessMethodParam> methodParamList = method.getParamList();
+                Map<String, String> tempParamList = new HashMap<String, String>();
+
+                /*
+                 * validation-1: check for any extra params that are not
+                 * required by the policymethod(capability), FIXME: make the
+                 * below loop simple without using raw data type
+                 */
+                if (apiParamList != null) {
+                    Collection userGroupCollection = apiParamList.values();
+                    Iterator iter = userGroupCollection.iterator();
+                    while (iter.hasNext()) {
+                        HashMap<String, String> paramKVpair = (HashMap)iter.next();
+                        String paramName = paramKVpair.get("name");
+                        String paramValue = paramKVpair.get("value");
+
+                        tempParamList.put(paramName, paramValue);
+                        Boolean found = false;
+                        for (LbStickinessMethodParam param : methodParamList) {
+                            if (param.getParamName().equalsIgnoreCase(paramName)) {
+                                if ((param.getIsflag() == false) && (paramValue == null)) {
+                                    throw new InvalidParameterValueException("Failed : Value expected for the Param :" + param.getParamName());
+                                }
+                                found = true;
+                                break;
+                            }
+                        }
+                        if (!found) {
+                            throw new InvalidParameterValueException("Failed : Stickiness policy does not support param name :" + paramName);
+                        }
+                    }
+                }
+
+                /* validation-2: check for mandatory params */
+                for (LbStickinessMethodParam param : methodParamList) {
+                    if (param.getRequired()) {
+                        if (tempParamList.get(param.getParamName()) == null) {
+                            throw new InvalidParameterValueException("Failed : Missing Manadatory Param :" + param.getParamName());
+                        }
+                    }
+                }
+                /* Successfully completed the Validation */
+                break;
+            }
+        }
+        if (methodMatch == false) {
+            throw new InvalidParameterValueException("Failed to match Stickiness method name for LB rule:" + cmd.getLbRuleId());
+        }
+
+        /* Validation : check for the multiple policies to the rule id */
+        List<LBStickinessPolicyVO> stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
+        if (stickinessPolicies.size() > 1) {
+            throw new InvalidParameterValueException("Failed to create Stickiness policy: Already two policies attached " + cmd.getLbRuleId());
+        }
+        return true;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "create lb stickinesspolicy to load balancer", create = true)
+    public StickinessPolicy createLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) throws NetworkRuleConflictException {
+        CallContext caller = CallContext.current();
+
+        /* Validation : check corresponding load balancer rule exist */
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        if (loadBalancer == null) {
+            throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " not present ");
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+        if (loadBalancer.getState() == FirewallRule.State.Revoke) {
+            throw new InvalidParameterValueException("Failed:  LB rule id: " + cmd.getLbRuleId() + " is in deleting state: ");
+        }
+
+        /* Generic validations */
+        if (!genericValidator(cmd)) {
+            throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId());
+        }
+
+        /*
+         * Specific validations using network element validator for specific
+         * validations
+         */
+        LBStickinessPolicyVO lbpolicy =
+            new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription());
+        List<LbStickinessPolicy> policyList = new ArrayList<LbStickinessPolicy>();
+        policyList.add(new LbStickinessPolicy(cmd.getStickinessMethodName(), lbpolicy.getParams()));
+        Ip sourceIp = getSourceIp(loadBalancer);
+        LoadBalancingRule lbRule =
+            new LoadBalancingRule(loadBalancer, getExistingDestinations(lbpolicy.getId()), policyList, null, sourceIp, null, loadBalancer.getLbProtocol());
+        if (!validateLbRule(lbRule)) {
+            throw new InvalidParameterValueException("Failed to create Stickiness policy: Validation Failed " + cmd.getLbRuleId());
+        }
+
+        /* Finally Insert into DB */
+        LBStickinessPolicyVO policy =
+            new LBStickinessPolicyVO(loadBalancer.getId(), cmd.getLBStickinessPolicyName(), cmd.getStickinessMethodName(), cmd.getparamList(), cmd.getDescription());
+        Boolean forDisplay = cmd.getDisplay();
+        if (forDisplay != null) {
+            policy.setDisplay(forDisplay);
+        }
+        policy = _lb2stickinesspoliciesDao.persist(policy);
+
+        return policy;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE, eventDescription = "create load balancer health check to load balancer", create = true)
+    public HealthCheckPolicy createLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) {
+        CallContext caller = CallContext.current();
+
+        /*
+         * Validation of cmd Monitor interval must be greater than response
+         * timeout
+         */
+        Map<String, String> paramMap = cmd.getFullUrlParams();
+
+        if (paramMap.containsKey(ApiConstants.HEALTHCHECK_RESPONSE_TIMEOUT) && paramMap.containsKey(ApiConstants.HEALTHCHECK_INTERVAL_TIME)) {
+            if (cmd.getResponsTimeOut() > cmd.getHealthCheckInterval())
+                throw new InvalidParameterValueException("Failed to create HealthCheck policy : Monitor interval must be greater than response timeout");
+        }
+        /* Validation : check corresponding load balancer rule exist */
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        if (loadBalancer == null) {
+            throw new InvalidParameterValueException("Failed: LB rule id: " + cmd.getLbRuleId() + " not present ");
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        if (loadBalancer.getState() == FirewallRule.State.Revoke) {
+            throw new InvalidParameterValueException("Failed:  LB rule id: " + cmd.getLbRuleId() + " is in deleting state: ");
+        }
+
+        /*
+         * Validate Whether LB Provider has the capabilities to support Health
+         * Checks
+         */
+        if (!validateHealthCheck(cmd)) {
+            throw new InvalidParameterValueException(
+                "Failed to create HealthCheck policy: Validation Failed (HealthCheck Policy is not supported by LB Provider for the LB rule id :" + cmd.getLbRuleId() + ")");
+        }
+
+        /* Validation : check for the multiple hc policies to the rule id */
+        List<LBHealthCheckPolicyVO> hcPolicies = _lb2healthcheckDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
+        if (hcPolicies.size() > 0) {
+            throw new InvalidParameterValueException("Failed to create HealthCheck policy: Already policy attached  for the LB Rule id :" + cmd.getLbRuleId());
+        }
+        /*
+         * Specific validations using network element validator for specific
+         * validations
+         */
+        LBHealthCheckPolicyVO hcpolicy =
+            new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(),
+                cmd.getHealthyThreshold(), cmd.getUnhealthyThreshold());
+
+        List<LbHealthCheckPolicy> hcPolicyList = new ArrayList<LbHealthCheckPolicy>();
+        hcPolicyList.add(new LbHealthCheckPolicy(hcpolicy.getpingpath(), hcpolicy.getDescription(), hcpolicy.getResponseTime(), hcpolicy.getHealthcheckInterval(),
+            hcpolicy.getHealthcheckThresshold(), hcpolicy.getUnhealthThresshold()));
+
+        // Finally Insert into DB
+        LBHealthCheckPolicyVO policy =
+            new LBHealthCheckPolicyVO(loadBalancer.getId(), cmd.getPingPath(), cmd.getDescription(), cmd.getResponsTimeOut(), cmd.getHealthCheckInterval(),
+                cmd.getHealthyThreshold(), cmd.getUnhealthyThreshold());
+
+        Boolean forDisplay = cmd.getDisplay();
+        if (forDisplay != null) {
+            policy.setDisplay(forDisplay);
+        }
+
+        policy = _lb2healthcheckDao.persist(policy);
+        return policy;
+    }
+
+    @Override
+    public boolean validateLbRule(LoadBalancingRule lbRule) {
+        Network network = _networkDao.findById(lbRule.getNetworkId());
+        Purpose purpose = lbRule.getPurpose();
+        if (purpose != Purpose.LoadBalancing) {
+            s_logger.debug("Unable to validate network rules for purpose: " + purpose.toString());
+            return false;
+        }
+        for (LoadBalancingServiceProvider ne : _lbProviders) {
+            boolean validated = ne.validateLBRule(network, lbRule);
+            if (!validated)
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_CREATE, eventDescription = "Apply Stickinesspolicy to load balancer ", async = true)
+    public boolean applyLBStickinessPolicy(CreateLBStickinessPolicyCmd cmd) {
+        boolean success = true;
+        FirewallRule.State backupState = null;
+        long oldStickinessPolicyId = 0;
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId());
+        }
+        List<LBStickinessPolicyVO> stickinessPolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(cmd.getLbRuleId(), false);
+        for (LBStickinessPolicyVO stickinessPolicy : stickinessPolicies) {
+            if (stickinessPolicy.getId() == cmd.getEntityId()) {
+                backupState = loadBalancer.getState();
+                loadBalancer.setState(FirewallRule.State.Add);
+                _lbDao.persist(loadBalancer);
+            } else {
+                oldStickinessPolicyId = stickinessPolicy.getId();
+                stickinessPolicy.setRevoke(true);
+                _lb2stickinesspoliciesDao.persist(stickinessPolicy);
+            }
+        }
+        try {
+            applyLoadBalancerConfig(cmd.getLbRuleId());
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to apply Stickiness policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e);
+            if (isRollBackAllowedForProvider(loadBalancer)) {
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                deleteLBStickinessPolicy(cmd.getEntityId(), false);
+                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating sticky policy");
+            } else {
+                deleteLBStickinessPolicy(cmd.getEntityId(), false);
+                if (oldStickinessPolicyId != 0) {
+                    LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(oldStickinessPolicyId);
+                    stickinessPolicy.setRevoke(false);
+                    _lb2stickinesspoliciesDao.persist(stickinessPolicy);
+                    try {
+                        if (backupState.equals(FirewallRule.State.Active))
+                            applyLoadBalancerConfig(cmd.getLbRuleId());
+                    } catch (ResourceUnavailableException e1) {
+                        s_logger.info("[ignored] applying load balancer config.", e1);
+                    } finally {
+                        loadBalancer.setState(backupState);
+                        _lbDao.persist(loadBalancer);
+                    }
+                }
+            }
+            success = false;
+        }
+
+        return success;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_CREATE, eventDescription = "Apply HealthCheckPolicy to load balancer ", async = true)
+    public boolean applyLBHealthCheckPolicy(CreateLBHealthCheckPolicyCmd cmd) {
+        boolean success = true;
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(cmd.getLbRuleId());
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer Id:" + cmd.getLbRuleId());
+        }
+        FirewallRule.State backupState = loadBalancer.getState();
+        loadBalancer.setState(FirewallRule.State.Add);
+        _lbDao.persist(loadBalancer);
+        try {
+            applyLoadBalancerConfig(cmd.getLbRuleId());
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to apply healthcheck policy to the lb rule: " + cmd.getLbRuleId() + " because resource is unavaliable:", e);
+            if (isRollBackAllowedForProvider(loadBalancer)) {
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " lb state rolback while creating healthcheck policy");
+            }
+            deleteLBHealthCheckPolicy(cmd.getEntityId(), false);
+            success = false;
+        }
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_DELETE, eventDescription = "revoking LB Stickiness policy ", async = true)
+    public boolean deleteLBStickinessPolicy(long stickinessPolicyId, boolean apply) {
+        boolean success = true;
+
+        CallContext caller = CallContext.current();
+        LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId);
+
+        if (stickinessPolicy == null) {
+            throw new InvalidParameterException("Invalid Stickiness policy id value: " + stickinessPolicyId);
+        }
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(stickinessPolicy.getLoadBalancerId()));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer : " + stickinessPolicy.getLoadBalancerId() + " for Stickiness policy id: " + stickinessPolicyId);
+        }
+        long loadBalancerId = loadBalancer.getId();
+        FirewallRule.State backupState = loadBalancer.getState();
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        if (apply) {
+            if (loadBalancer.getState() == FirewallRule.State.Active) {
+                loadBalancer.setState(FirewallRule.State.Add);
+                _lbDao.persist(loadBalancer);
+            }
+
+            boolean backupStickyState = stickinessPolicy.isRevoke();
+            stickinessPolicy.setRevoke(true);
+            _lb2stickinesspoliciesDao.persist(stickinessPolicy);
+            s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", stickinesspolicyID " + stickinessPolicyId);
+
+            try {
+                if (!applyLoadBalancerConfig(loadBalancerId)) {
+                    s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId);
+                    throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for stickinesspolicyID " + stickinessPolicyId);
+                }
+            } catch (ResourceUnavailableException e) {
+                if (isRollBackAllowedForProvider(loadBalancer)) {
+                    stickinessPolicy.setRevoke(backupStickyState);
+                    _lb2stickinesspoliciesDao.persist(stickinessPolicy);
+                    loadBalancer.setState(backupState);
+                    _lbDao.persist(loadBalancer);
+                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while deleting sticky policy: " + stickinessPolicyId);
+                }
+                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+                success = false;
+            }
+        } else {
+            _lb2stickinesspoliciesDao.expunge(stickinessPolicyId);
+        }
+        return success;
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_DELETE, eventDescription = "revoking LB HealthCheck policy ", async = true)
+    public boolean deleteLBHealthCheckPolicy(long healthCheckPolicyId, boolean apply) {
+        boolean success = true;
+
+        CallContext caller = CallContext.current();
+        LBHealthCheckPolicyVO healthCheckPolicy = _lb2healthcheckDao.findById(healthCheckPolicyId);
+
+        if (healthCheckPolicy == null) {
+            throw new InvalidParameterException("Invalid HealthCheck policy id value: " + healthCheckPolicyId);
+        }
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(healthCheckPolicy.getLoadBalancerId()));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer : " + healthCheckPolicy.getLoadBalancerId() + " for HealthCheck policy id: " + healthCheckPolicyId);
+        }
+        final long loadBalancerId = loadBalancer.getId();
+        FirewallRule.State backupState = loadBalancer.getState();
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        if (apply) {
+            if (loadBalancer.getState() == FirewallRule.State.Active) {
+                loadBalancer.setState(FirewallRule.State.Add);
+                _lbDao.persist(loadBalancer);
+            }
+
+            boolean backupStickyState = healthCheckPolicy.isRevoke();
+            healthCheckPolicy.setRevoke(true);
+            _lb2healthcheckDao.persist(healthCheckPolicy);
+            s_logger.debug("Set health check policy to revoke for loadbalancing rule id : " + loadBalancerId + ", healthCheckpolicyID " + healthCheckPolicyId);
+
+            // removing the state of services set by the monitor.
+            final List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
+            if (maps != null) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        s_logger.debug("Resetting health state policy for services in loadbalancing rule id : " + loadBalancerId);
+                        for (LoadBalancerVMMapVO map : maps) {
+                            map.setState(null);
+                            _lb2VmMapDao.persist(map);
+                        }
+                    }
+                });
+            }
+
+            try {
+                if (!applyLoadBalancerConfig(loadBalancerId)) {
+                    s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for healthCheckpolicyID " + healthCheckPolicyId);
+                    throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for healthCheckpolicyID " + healthCheckPolicyId);
+                }
+            } catch (ResourceUnavailableException e) {
+                if (isRollBackAllowedForProvider(loadBalancer)) {
+                    healthCheckPolicy.setRevoke(backupStickyState);
+                    _lb2healthcheckDao.persist(healthCheckPolicy);
+                    loadBalancer.setState(backupState);
+                    _lbDao.persist(loadBalancer);
+                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while deleting healthcheck policy: " + healthCheckPolicyId);
+                }
+                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+                success = false;
+            }
+        } else {
+            _lb2healthcheckDao.remove(healthCheckPolicy.getLoadBalancerId());
+        }
+        return success;
+    }
+
+    // This method will check the status of services which has monitors created
+    // by CloudStack and update them in lbvmmap table
+    @DB
+    @Override
+    public void updateLBHealthChecks(Scheme scheme) throws ResourceUnavailableException {
+        List<LoadBalancerVO> rules = _lbDao.listAll();
+        List<NetworkVO> networks = _networkDao.listAll();
+        List<LoadBalancerTO> stateRules = null;
+        boolean isHandled = false;
+        for (NetworkVO ntwk : networks) {
+            Network network = _networkDao.findById(ntwk.getId());
+            String capability = getLBCapability(network.getId(), Capability.HealthCheckPolicy.getName());
+
+            if (capability != null && capability.equalsIgnoreCase("true")) {
+                /*
+                 * s_logger.debug(
+                 * "HealthCheck Manager :: LB Provider in the Network has the Healthcheck policy capability :: "
+                 * + provider.get(0).getName());
+                 */
+                rules = _lbDao.listByNetworkIdAndScheme(network.getId(), scheme);
+                if (rules != null && rules.size() > 0) {
+                    List<LoadBalancingRule> lbrules = new ArrayList<LoadBalancingRule>();
+                    for (LoadBalancerVO lb : rules) {
+                        List<LbDestination> dstList = getExistingDestinations(lb.getId());
+                        List<LbHealthCheckPolicy> hcPolicyList = getHealthCheckPolicies(lb.getId());
+                        // Now retrive the status of services from NS even there are no policies. because there is default monitor
+                        Ip sourceIp = getSourceIp(lb);
+                        LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol());
+                        lbrules.add(loadBalancing);
+                    }
+                    if (lbrules.size() > 0) {
+                        isHandled = false;
+                        for (LoadBalancingServiceProvider lbElement : _lbProviders) {
+                            stateRules = lbElement.updateHealthChecks(network, lbrules);
+                            if (stateRules != null && stateRules.size() > 0) {
+                                for (LoadBalancerTO lbto : stateRules) {
+                                    LoadBalancerVO ulb = _lbDao.findByUuid(lbto.getUuid());
+                                    List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(ulb.getId());
+                                    for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
+                                        UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
+                                        Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(ulb.getNetworkId(), vm.getId());
+                                        String dstIp = lbVmMap.getInstanceIp() == null ? nic.getIPv4Address(): lbVmMap.getInstanceIp();
+
+                                        for (int i = 0; i < lbto.getDestinations().length; i++) {
+                                            LoadBalancerTO.DestinationTO des = lbto.getDestinations()[i];
+                                            if (dstIp.equalsIgnoreCase(lbto.getDestinations()[i].getDestIp())) {
+                                                lbVmMap.setState(des.getMonitorState());
+                                                _lb2VmMapDao.persist(lbVmMap);
+                                                s_logger.debug("Updating the LB VM Map table with the service state");
+                                            }
+                                        }
+                                    }
+                                }
+                                isHandled = true;
+                            }
+                            if (isHandled) {
+                                break;
+                            }
+                        }
+                    }
+                }
+            } else {
+                // s_logger.debug("HealthCheck Manager :: LB Provider in the Network DNOT the Healthcheck policy capability ");
+            }
+        }
+    }
+
+    private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) {
+        Network network = _networkDao.findById(loadBalancer.getNetworkId());
+        List<Provider> provider = _networkMgr.getProvidersForServiceInNetwork(network, Service.Lb);
+        if (provider == null || provider.size() == 0) {
+            return false;
+        }
+        if (provider.get(0) == Provider.Netscaler || provider.get(0) == Provider.F5BigIp ||
+            provider.get(0) == Provider.VirtualRouter) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true)
+    public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds, Map<Long, List<String>> vmIdIpMap) {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        final LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
+        if (loadBalancer == null) {
+            throw new InvalidParameterValueException("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found.");
+        }
+
+
+        if (instanceIds == null && vmIdIpMap.isEmpty()) {
+            throw new InvalidParameterValueException("Both instanceids and vmidipmap  can't be null");
+        }
+
+        // instanceIds and vmIdipmap is passed
+        if (instanceIds != null && !vmIdIpMap.isEmpty()) {
+            for(long instanceId: instanceIds) {
+                if (!vmIdIpMap.containsKey(instanceId)) {
+                    vmIdIpMap.put(instanceId, null);
+                }
+            }
+        }
+
+        //only instanceids list passed
+        if (instanceIds != null && vmIdIpMap.isEmpty()){
+            vmIdIpMap = new HashMap<Long, List<String>>();
+            for (long instanceId: instanceIds){
+                vmIdIpMap.put(instanceId, null);
+            }
+        }
+
+        List<LoadBalancerVMMapVO> mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false);
+        Set<Long> mappedInstanceIds = new HashSet<Long>();
+        for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
+            mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId()));
+        }
+
+        Map<Long, List<String>> existingVmIdIps = new HashMap<Long, List<String>>();
+        // now get the ips of vm and add it to map
+        for (LoadBalancerVMMapVO mappedInstance : mappedInstances) {
+
+            List<String> ipsList = null;
+            if (existingVmIdIps.containsKey(mappedInstance.getInstanceId())) {
+                ipsList = existingVmIdIps.get(mappedInstance.getInstanceId());
+            } else {
+                ipsList = new ArrayList<String>();
+            }
+            ipsList.add(mappedInstance.getInstanceIp());
+            existingVmIdIps.put(mappedInstance.getInstanceId(), ipsList);
+        }
+
+        final List<UserVm> vmsToAdd = new ArrayList<UserVm>();
+
+        // check for conflict
+        Set<Long> passedInstanceIds = vmIdIpMap.keySet();
+        for (Long instanceId : passedInstanceIds) {
+            UserVm vm = _vmDao.findById(instanceId);
+            if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
+                InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified");
+                if (vm == null) {
+                    ex.addProxyObject(instanceId.toString(), "instanceId");
+                } else {
+                    ex.addProxyObject(vm.getUuid(), "instanceId");
+                }
+                throw ex;
+            }
+
+            _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller);
+
+            if (vm.getAccountId() != loadBalancer.getAccountId()) {
+                throw new PermissionDeniedException("Cannot add virtual machines that do not belong to the same owner.");
+            }
+
+            // Let's check to make sure the vm has a nic in the same network as
+            // the load balancing rule.
+            List<? extends Nic> nics = _networkModel.getNics(vm.getId());
+            Nic nicInSameNetwork = null;
+            for (Nic nic : nics) {
+                if (nic.getNetworkId() == loadBalancer.getNetworkId()) {
+                    nicInSameNetwork = nic;
+                    break;
+                }
+            }
+
+            if (nicInSameNetwork == null) {
+                InvalidParameterValueException ex =
+                        new InvalidParameterValueException("VM with id specified cannot be added because it doesn't belong in the same network.");
+                ex.addProxyObject(vm.getUuid(), "instanceId");
+                throw ex;
+            }
+
+            String priIp = nicInSameNetwork.getIPv4Address();
+
+            if (existingVmIdIps.containsKey(instanceId)) {
+                // now check for ip address
+                List<String> mappedIps = existingVmIdIps.get(instanceId);
+                List<String> newIps = vmIdIpMap.get(instanceId);
+
+                if (newIps == null) {
+                    newIps = new ArrayList<String>();
+                    newIps.add(priIp);
+                }
+
+                for (String newIp: newIps) {
+                    if (mappedIps.contains(newIp)) {
+                        throw new InvalidParameterValueException("VM " + instanceId + " with " + newIp +" is already mapped to load balancer.");
+                    }
+                }
+            }
+
+            List<String> vmIpsList = vmIdIpMap.get(instanceId);
+            String vmLbIp = null;
+
+            if (vmIpsList != null) {
+
+                //check if the ips belongs to nic secondary ip
+                for (String ip: vmIpsList) {
+                    // skip the primary ip from vm secondary ip comparisions
+                    if (ip.equals(priIp)) {
+                        continue;
+                    }
+                    if(_nicSecondaryIpDao.findByIp4AddressAndNicId(ip,nicInSameNetwork.getId()) == null) {
+                        throw new InvalidParameterValueException("VM ip "+ ip + " specified does not belong to " +
+                                "nic in network " + nicInSameNetwork.getNetworkId());
+                    }
+                }
+            } else {
+                vmIpsList = new ArrayList<String>();
+                vmIpsList.add(priIp);
+            }
+
+            // when vm id is passed in instance ids and in vmidipmap
+            // assign for primary ip and ip passed in vmidipmap
+            if (instanceIds != null ) {
+                if (instanceIds.contains(instanceId)) {
+                    vmIpsList.add(priIp);
+                }
+            }
+
+            vmIdIpMap.put(instanceId, vmIpsList);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Adding " + vm + " to the load balancer pool");
+            }
+            vmsToAdd.add(vm);
+        }
+
+        final Set<Long> vmIds = vmIdIpMap.keySet();
+        final Map<Long, List<String>> newMap = vmIdIpMap;
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+
+                for (Long vmId : vmIds) {
+                    final Set<String> lbVmIps = new HashSet<String>(newMap.get(vmId));
+                    for (String vmIp: lbVmIps) {
+                        LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vmId, vmIp, false);
+                        map = _lb2VmMapDao.persist(map);
+                    }
+                }
+            }
+        });
+
+        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) {
+            // For autoscaled loadbalancer, the rules need not be applied,
+            // meaning the call need not reach the resource layer.
+            // We can consider the job done.
+            return true;
+        }
+        boolean success = false;
+        FirewallRule.State backupState = loadBalancer.getState();
+        try {
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+            applyLoadBalancerConfig(loadBalancerId);
+            success = true;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+            success = false;
+        } finally {
+            if (!success) {
+                final List<Long> vmInstanceIds = new ArrayList<Long>();
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        for (Long vmId : vmIds) {
+                            vmInstanceIds.add(vmId);
+                        }
+                    }
+                });
+                if (!vmInstanceIds.isEmpty()) {
+                    _lb2VmMapDao.remove(loadBalancer.getId(), vmInstanceIds, null);
+                    s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + "  while attaching VM: " + vmInstanceIds);
+                }
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms "
+                    + vmInstanceIds);
+                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
+                // TBD: Also pack in the instanceIds in the exception using the
+                // right VO object or table name.
+                throw ex;
+            }
+
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean assignSSLCertToLoadBalancerRule(Long lbId, String certName, String publicCert, String privateKey) {
+        s_logger.error("Calling the manager for LB");
+        LoadBalancerVO loadBalancer = _lbDao.findById(lbId);
+
+        return false;  //TODO
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, eventDescription = "removing from load balancer", async = true)
+    public boolean removeFromLoadBalancer(long loadBalancerId, List<Long> instanceIds, Map<Long, List<String>> vmIdIpsMap) {
+        return removeFromLoadBalancerInternal(loadBalancerId, instanceIds, true, vmIdIpsMap);
+    }
+
+    @Override
+    public LbSslCert getLbSslCert(long lbRuleId) {
+        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
+
+        if (lbCertMap == null)
+            return null;
+
+        SslCertVO certVO = _entityMgr.findById(SslCertVO.class, lbCertMap.getCertId());
+        if (certVO == null) {
+            s_logger.warn("Cert rule with cert ID " + lbCertMap.getCertId() + " but Cert is not found");
+            return null;
+        }
+
+        return new LbSslCert(certVO.getCertificate(), certVO.getKey(), certVO.getPassword(), certVO.getChain(), certVO.getFingerPrint(), lbCertMap.isRevoke());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_CERT_ASSIGN, eventDescription = "assigning certificate to load balancer", async = true)
+    public boolean assignCertToLoadBalancer(long lbRuleId, Long certId) {
+        CallContext caller = CallContext.current();
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(lbRuleId));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid load balancer id: " + lbRuleId);
+        }
+
+        SslCertVO certVO = _entityMgr.findById(SslCertVO.class, certId);
+        if (certVO == null) {
+            throw new InvalidParameterException("Invalid certificate id: " + certId);
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        // check if LB and Cert belong to the same account
+        if (loadBalancer.getAccountId() != certVO.getAccountId()) {
+            throw new InvalidParameterValueException("Access denied for account " + certVO.getAccountId());
+        }
+
+        String capability = getLBCapability(loadBalancer.getNetworkId(), Capability.SslTermination.getName());
+        if (capability == null) {
+            throw new InvalidParameterValueException("Ssl termination not supported by the loadbalancer");
+        }
+
+        //check if the lb is already bound
+        LoadBalancerCertMapVO certMapRule = _lbCertMapDao.findByLbRuleId(loadBalancer.getId());
+        if (certMapRule != null)
+            throw new InvalidParameterValueException("Another certificate is already bound to the LB");
+
+        //check for correct port
+        if (loadBalancer.getLbProtocol() == null || !(loadBalancer.getLbProtocol().equals(NetUtils.SSL_PROTO)))
+            throw new InvalidParameterValueException("Bad LB protocol: Expected ssl got " + loadBalancer.getLbProtocol());
+
+        boolean success = false;
+        FirewallRule.State backupState = loadBalancer.getState();
+
+        try {
+
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+            LoadBalancerCertMapVO certMap = new LoadBalancerCertMapVO(lbRuleId, certId, false);
+            _lbCertMapDao.persist(certMap);
+            applyLoadBalancerConfig(loadBalancer.getId());
+            success = true;
+        } catch (ResourceUnavailableException e) {
+            if (isRollBackAllowedForProvider(loadBalancer)) {
+
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                LoadBalancerCertMapVO certMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
+                _lbCertMapDao.remove(certMap.getId());
+                s_logger.debug("LB Rollback rule id: " + loadBalancer.getId() + " while adding cert");
+            }
+            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+        }
+        return success;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_LB_CERT_REMOVE, eventDescription = "removing certificate from load balancer", async = true)
+    public boolean removeCertFromLoadBalancer(long lbRuleId) {
+        CallContext caller = CallContext.current();
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
+        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lbRuleId);
+
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid load balancer value: " + lbRuleId);
+        }
+
+        if (lbCertMap == null) {
+            throw new InvalidParameterException("No certificate is bound to lb with id: " + lbRuleId);
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        boolean success = false;
+        FirewallRule.State backupState = loadBalancer.getState();
+        try {
+
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+            lbCertMap.setRevoke(true);
+            _lbCertMapDao.persist(lbCertMap);
+
+            if (!applyLoadBalancerConfig(lbRuleId)) {
+                s_logger.warn("Failed to remove cert from load balancer rule id " + lbRuleId);
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove certificate load balancer rule id " + lbRuleId);
+                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
+                throw ex;
+            }
+            success = true;
+        } catch (ResourceUnavailableException e) {
+            if (isRollBackAllowedForProvider(loadBalancer)) {
+                lbCertMap.setRevoke(false);
+                _lbCertMapDao.persist(lbCertMap);
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                s_logger.debug("Rolled back certificate removal lb id " + lbRuleId);
+            }
+            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+            if (!success) {
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove certificate from load balancer rule id " + lbRuleId);
+                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
+                throw ex;
+            }
+        }
+        return success;
+    }
+
+    private boolean removeFromLoadBalancerInternal(long loadBalancerId, List<Long> instanceIds, boolean rollBack, Map<Long, List<String>> vmIdIpMap) {
+        CallContext caller = CallContext.current();
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(loadBalancerId));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid load balancer value: " + loadBalancerId);
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, loadBalancer);
+
+        if (instanceIds == null && vmIdIpMap.isEmpty()) {
+            throw new InvalidParameterValueException("Both instanceids and vmidipmap  can't be null");
+        }
+
+        // instanceIds and vmIdipmap is passed
+        if (instanceIds != null && !vmIdIpMap.isEmpty()) {
+            for(long instanceId: instanceIds) {
+                if (!vmIdIpMap.containsKey(instanceId)) {
+                    vmIdIpMap.put(instanceId, null);
+                }
+            }
+        }
+
+        //only instanceids list passed
+        if (instanceIds != null && vmIdIpMap.isEmpty()){
+            vmIdIpMap = new HashMap<Long, List<String>>();
+            for (long instanceId: instanceIds){
+                vmIdIpMap.put(instanceId, null);
+            }
+        }
+
+
+
+        boolean success = false;
+        FirewallRule.State backupState = loadBalancer.getState();
+        Set<Long> vmIds = vmIdIpMap.keySet();
+        try {
+            loadBalancer.setState(FirewallRule.State.Add);
+            _lbDao.persist(loadBalancer);
+
+            for (long instanceId : vmIds) {
+                List<String> lbVmIps = vmIdIpMap.get(instanceId);
+
+                if (lbVmIps == null || lbVmIps.isEmpty()) {
+                    List<LoadBalancerVMMapVO> lbVms = _lb2VmMapDao.listByLoadBalancerIdAndVmId(loadBalancerId, instanceId);
+                    if (lbVms == null) {
+                        throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured "
+                                + " for LB rule id " + loadBalancerId);
+                    }
+
+                    for (LoadBalancerVMMapVO lbvm: lbVms) {
+                        lbvm.setRevoke(true);
+                        _lb2VmMapDao.persist(lbvm);
+                    }
+                    s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId);
+
+                } else {
+                    for (String vmIp: lbVmIps) {
+                        LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp);
+                        if (map == null) {
+                            throw new InvalidParameterValueException("The instance id: "+ instanceId +" is not configured "
+                                    + " for LB rule id " + loadBalancerId);
+                        }
+                        map.setRevoke(true);
+                        _lb2VmMapDao.persist(map);
+                        s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " +
+                                instanceId + ", vmip " + vmIp);
+                    }
+                }
+            }
+
+            if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(loadBalancerId)) {
+                // For autoscaled loadbalancer, the rules need not be applied,
+                // meaning the call need not reach the resource layer.
+                // We can consider the job done and only need to remove the
+                // rules in DB
+                _lb2VmMapDao.remove(loadBalancer.getId(), instanceIds, null);
+                return true;
+            }
+
+            if (!applyLoadBalancerConfig(loadBalancerId)) {
+                s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds);
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds);
+                ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
+                throw ex;
+            }
+            success = true;
+        } catch (ResourceUnavailableException e) {
+            if (rollBack && isRollBackAllowedForProvider(loadBalancer)) {
+
+                for (long instanceId : vmIds) {
+                    List<String> lbVmIps = vmIdIpMap.get(instanceId);
+
+                    if (lbVmIps == null || lbVmIps.isEmpty()) {
+                        LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId);
+                        map.setRevoke(false);
+                        _lb2VmMapDao.persist(map);
+                        s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " + instanceId);
+                    }else {
+                        for (String vmIp: lbVmIps) {
+                            LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmIdVmIp (loadBalancerId, instanceId, vmIp);
+                            map.setRevoke(true);
+                            _lb2VmMapDao.persist(map);
+                            s_logger.debug("LB Rollback rule id: " + loadBalancerId + ",while removing vmId " +
+                                    instanceId + ", vmip " + vmIp);
+                        }
+                    }
+                }
+
+                loadBalancer.setState(backupState);
+                _lbDao.persist(loadBalancer);
+                s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while removing vm instances");
+            }
+            s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+        }
+        if (!success) {
+            CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + vmIds);
+            ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
+            throw ex;
+        }
+        return success;
+    }
+
+    @Override
+    public boolean removeVmFromLoadBalancers(long instanceId) {
+        boolean success = true;
+        List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByInstanceId(instanceId);
+        if (maps == null || maps.isEmpty()) {
+            return true;
+        }
+
+        Map<Long, List<Long>> lbsToReconfigure = new HashMap<Long, List<Long>>();
+
+        // first set all existing lb mappings with Revoke state
+        for (LoadBalancerVMMapVO map : maps) {
+            long lbId = map.getLoadBalancerId();
+            List<Long> instances = lbsToReconfigure.get(lbId);
+            if (instances == null) {
+                instances = new ArrayList<Long>();
+            }
+            instances.add(map.getInstanceId());
+            lbsToReconfigure.put(lbId, instances);
+
+            map.setRevoke(true);
+            _lb2VmMapDao.persist(map);
+            s_logger.debug("Set load balancer rule for revoke: rule id " + map.getLoadBalancerId() + ", vmId " + instanceId);
+        }
+
+        // Reapply all lbs that had the vm assigned
+        if (lbsToReconfigure != null) {
+            for (Map.Entry<Long, List<Long>> lb : lbsToReconfigure.entrySet()) {
+                if (!removeFromLoadBalancerInternal(lb.getKey(), lb.getValue(), false, new HashMap<Long, List<String>>())) {
+                    success = false;
+                }
+            }
+        }
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_DELETE, eventDescription = "deleting load balancer", async = true)
+    public boolean deleteLoadBalancerRule(long loadBalancerId, boolean apply) {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        LoadBalancerVO rule = _lbDao.findById(loadBalancerId);
+
+        if (rule == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer rule " + loadBalancerId);
+        }
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        boolean result = deleteLoadBalancerRule(loadBalancerId, apply, caller, ctx.getCallingUserId(), true);
+        if (!result) {
+            throw new CloudRuntimeException("Unable to remove load balancer rule " + loadBalancerId);
+        }
+        return result;
+    }
+
+    @DB
+    public boolean deleteLoadBalancerRule(final long loadBalancerId, boolean apply, Account caller, long callerUserId, boolean rollBack) {
+        final LoadBalancerVO lb = _lbDao.findById(loadBalancerId);
+        FirewallRule.State backupState = lb.getState();
+
+        // remove any ssl certs associated with this LB rule before trying to delete it.
+        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(loadBalancerId);
+        if (lbCertMap != null) {
+            boolean removeResult = removeCertFromLoadBalancer(loadBalancerId);
+            if (!removeResult) {
+                throw new CloudRuntimeException("Unable to remove certificate from load balancer rule " + loadBalancerId);
+            }
+        }
+
+        List<LoadBalancerVMMapVO> backupMaps = Transaction.execute(new TransactionCallback<List<LoadBalancerVMMapVO>>() {
+            @Override
+            public List<LoadBalancerVMMapVO> doInTransaction(TransactionStatus status) {
+                boolean generateUsageEvent = false;
+
+                if (lb.getState() == FirewallRule.State.Staged) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Found a rule that is still in stage state so just removing it: " + lb);
+                    }
+                    generateUsageEvent = true;
+                } else if (lb.getState() == FirewallRule.State.Add || lb.getState() == FirewallRule.State.Active) {
+                    lb.setState(FirewallRule.State.Revoke);
+                    _lbDao.persist(lb);
+                    generateUsageEvent = true;
+                }
+                List<LoadBalancerVMMapVO> backupMaps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
+                List<LoadBalancerVMMapVO> maps = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
+                if (maps != null) {
+                    for (LoadBalancerVMMapVO map : maps) {
+                        map.setRevoke(true);
+                        _lb2VmMapDao.persist(map);
+                        s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + map.getInstanceId());
+                    }
+                }
+
+                List<LBHealthCheckPolicyVO> hcPolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, null);
+                for (LBHealthCheckPolicyVO lbHealthCheck : hcPolicies) {
+                    lbHealthCheck.setRevoke(true);
+                    _lb2healthcheckDao.persist(lbHealthCheck);
+                }
+
+                if (generateUsageEvent) {
+                    // Generate usage event right after all rules were marked for revoke
+                    Network network = _networkModel.getNetwork(lb.getNetworkId());
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), network.getDataCenterId(), lb.getId(),
+                            null, LoadBalancingRule.class.getName(), lb.getUuid());
+                }
+
+                return backupMaps;
+            }
+        });
+
+        // gather external network usage stats for this lb rule
+        NetworkVO network = _networkDao.findById(lb.getNetworkId());
+        if (network != null) {
+            if (_networkModel.networkIsConfiguredForExternalNetworking(network.getDataCenterId(), network.getId())) {
+                _externalDeviceUsageMgr.updateExternalLoadBalancerNetworkUsageStats(loadBalancerId);
+            }
+        }
+
+        if (apply) {
+            try {
+                if (!applyLoadBalancerConfig(loadBalancerId)) {
+                    s_logger.warn("Unable to apply the load balancer config");
+                    return false;
+                }
+            } catch (ResourceUnavailableException e) {
+                if (rollBack && isRollBackAllowedForProvider(lb)) {
+                    if (backupMaps != null) {
+                        for (LoadBalancerVMMapVO map : backupMaps) {
+                            _lb2VmMapDao.persist(map);
+                            s_logger.debug("LB Rollback rule id: " + loadBalancerId + ", vmId " + map.getInstanceId());
+                        }
+                    }
+                    lb.setState(backupState);
+                    _lbDao.persist(lb);
+                    s_logger.debug("LB Rollback rule id: " + loadBalancerId + " while deleting LB rule.");
+                } else {
+                    s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+                }
+                return false;
+            }
+        }
+
+        FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(lb.getId());
+        if (relatedRule != null) {
+            s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() +
+                "; leaving it in Revoke state");
+            return false;
+        } else {
+            _firewallMgr.removeRule(lb);
+        }
+
+        // FIXME: breaking the dependency on ELB manager. This breaks
+        // functionality of ELB using virtual router
+        // Bug CS-15411 opened to document this
+        // _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller);
+
+        s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully");
+
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating load balancer")
+    public LoadBalancer createPublicLoadBalancerRule(String xId, String name, String description, int srcPortStart, int srcPortEnd, int defPortStart, int defPortEnd,
+        Long ipAddrId, String protocol, String algorithm, long networkId, long lbOwnerId, boolean openFirewall, String lbProtocol, Boolean forDisplay) throws NetworkRuleConflictException,
+        InsufficientAddressCapacityException {
+        Account lbOwner = _accountMgr.getAccount(lbOwnerId);
+
+        if (srcPortStart != srcPortEnd) {
+            throw new InvalidParameterValueException("Port ranges are not supported by the load balancer");
+        }
+
+        IPAddressVO ipVO = null;
+        if (ipAddrId != null) {
+            ipVO = _ipAddressDao.findById(ipAddrId);
+        }
+
+        Network network = _networkModel.getNetwork(networkId);
+
+        // FIXME: breaking the dependency on ELB manager. This breaks
+        // functionality of ELB using virtual router
+        // Bug CS-15411 opened to document this
+        // LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb,
+        // lbOwner, lb.getNetworkId());
+        LoadBalancer result = null;
+        if (result == null) {
+            IpAddress systemIp = null;
+            NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+            if (off.isElasticLb() && ipVO == null && network.getVpcId() == null) {
+                systemIp = _ipAddrMgr.assignSystemIp(networkId, lbOwner, true, false);
+                if (systemIp != null) {
+                    ipVO = _ipAddressDao.findById(systemIp.getId());
+                }
+            }
+
+            // Validate ip address
+            if (ipVO == null) {
+                throw new InvalidParameterValueException("Unable to create load balance rule; can't find/allocate source IP");
+            } else if (ipVO.isOneToOneNat()) {
+                throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipVO.getAddress());
+            }
+
+            boolean performedIpAssoc = false;
+            try {
+                if (ipVO.getAssociatedWithNetworkId() == null) {
+                    boolean assignToVpcNtwk = network.getVpcId() != null && ipVO.getVpcId() != null && ipVO.getVpcId().longValue() == network.getVpcId();
+                    if (assignToVpcNtwk) {
+                        // set networkId just for verification purposes
+                        _networkModel.checkIpForService(ipVO, Service.Lb, networkId);
+
+                        s_logger.debug("The ip is not associated with the VPC network id=" + networkId + " so assigning");
+                        ipVO = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
+                        performedIpAssoc = true;
+                    }
+                } else {
+                    _networkModel.checkIpForService(ipVO, Service.Lb, null);
+                }
+
+                if (ipVO.getAssociatedWithNetworkId() == null) {
+                    throw new InvalidParameterValueException("Ip address " + ipVO + " is not assigned to the network " + network);
+                }
+
+                result = createPublicLoadBalancer(xId, name, description, srcPortStart, defPortStart, ipVO.getId(), protocol, algorithm, openFirewall, CallContext.current(),
+                        lbProtocol, forDisplay);
+            } catch (Exception ex) {
+                s_logger.warn("Failed to create load balancer due to ", ex);
+                if (ex instanceof NetworkRuleConflictException) {
+                    throw (NetworkRuleConflictException)ex;
+                }
+
+                if (ex instanceof InvalidParameterValueException) {
+                    throw (InvalidParameterValueException)ex;
+                }
+
+            } finally {
+                if (result == null && systemIp != null) {
+                    s_logger.debug("Releasing system IP address " + systemIp + " as corresponding lb rule failed to create");
+                    _ipAddrMgr.handleSystemIpRelease(systemIp);
+                }
+                // release ip address if ipassoc was perfored
+                if (performedIpAssoc) {
+                    ipVO = _ipAddressDao.findById(ipVO.getId());
+                    _vpcMgr.unassignIPFromVpcNetwork(ipVO.getId(), networkId);
+                }
+            }
+        }
+
+        if (result == null) {
+            throw new CloudRuntimeException("Failed to create load balancer rule: " + name);
+        }
+
+        return result;
+    }
+
+    @DB
+    @Override
+    public LoadBalancer createPublicLoadBalancer(final String xId, final String name, final String description, final int srcPort, final int destPort,
+ final long sourceIpId,
+            final String protocol, final String algorithm, final boolean openFirewall, final CallContext caller, final String lbProtocol, final Boolean forDisplay)
+            throws NetworkRuleConflictException {
+
+        if (!NetUtils.isValidPort(destPort)) {
+            throw new InvalidParameterValueException("privatePort is an invalid value: " + destPort);
+        }
+
+        if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
+            throw new InvalidParameterValueException("Invalid algorithm: " + algorithm);
+        }
+
+        final IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId);
+        // make sure ip address exists
+        if (ipAddr == null || !ipAddr.readyToUse()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified");
+            if (ipAddr == null) {
+                ex.addProxyObject(String.valueOf(sourceIpId), "sourceIpId");
+            } else {
+                ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
+            }
+            throw ex;
+        } else if (ipAddr.isOneToOneNat()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled");
+            ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
+            throw ex;
+        }
+
+        _accountMgr.checkAccess(caller.getCallingAccount(), null, true, ipAddr);
+
+        final Long networkId = ipAddr.getAssociatedWithNetworkId();
+        if (networkId == null) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network");
+            ex.addProxyObject(ipAddr.getUuid(), "sourceIpId");
+            throw ex;
+        }
+
+        // verify that lb service is supported by the network
+        isLbServiceSupportedInNetwork(networkId, Scheme.Public);
+
+        _firewallMgr.validateFirewallRule(caller.getCallingAccount(), ipAddr, srcPort, srcPort, protocol, Purpose.LoadBalancing, FirewallRuleType.User, networkId, null);
+
+        LoadBalancerVO newRule =
+            new LoadBalancerVO(xId, name, description, sourceIpId, srcPort, destPort, algorithm, networkId, ipAddr.getAllocatedToAccountId(),
+                ipAddr.getAllocatedInDomainId(), lbProtocol);
+
+        // verify rule is supported by Lb provider of the network
+        Ip sourceIp = getSourceIp(newRule);
+        LoadBalancingRule loadBalancing =
+            new LoadBalancingRule(newRule, new ArrayList<LbDestination>(), new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp, null,
+                lbProtocol);
+        if (!validateLbRule(loadBalancing)) {
+            throw new InvalidParameterValueException("LB service provider cannot support this rule");
+        }
+
+        return Transaction.execute(new TransactionCallbackWithException<LoadBalancerVO, NetworkRuleConflictException>() {
+            @Override
+            public LoadBalancerVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+                LoadBalancerVO newRule =
+                    new LoadBalancerVO(xId, name, description, sourceIpId, srcPort, destPort, algorithm, networkId, ipAddr.getAllocatedToAccountId(),
+                        ipAddr.getAllocatedInDomainId(), lbProtocol);
+
+                if (forDisplay != null) {
+                    newRule.setDisplay(forDisplay);
+                }
+
+                // verify rule is supported by Lb provider of the network
+                Ip sourceIp = getSourceIp(newRule);
+                LoadBalancingRule loadBalancing =
+                    new LoadBalancingRule(newRule, new ArrayList<LbDestination>(), new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(), sourceIp,
+                        null, lbProtocol);
+                if (!validateLbRule(loadBalancing)) {
+                    throw new InvalidParameterValueException("LB service provider cannot support this rule");
+                }
+
+                newRule = _lbDao.persist(newRule);
+
+                //create rule for all CIDRs
+                if (openFirewall) {
+                    _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCallingAccount(), srcPort, srcPort, protocol, null, null, newRule.getId(), networkId);
+                }
+
+                boolean success = true;
+
+                try {
+                    _firewallMgr.detectRulesConflict(newRule);
+                    if (!_firewallDao.setStateToAdd(newRule)) {
+                        throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+                    }
+                    s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + srcPort + ", private port " + destPort +
+                        " is added successfully.");
+                    CallContext.current().setEventDetails("Load balancer Id: " + newRule.getId());
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(),
+                        null, LoadBalancingRule.class.getName(), newRule.getUuid());
+
+                    return newRule;
+                } catch (Exception e) {
+                    success = false;
+                    if (e instanceof NetworkRuleConflictException) {
+                        throw (NetworkRuleConflictException)e;
+                    }
+                    throw new CloudRuntimeException("Unable to add rule for ip address id=" + newRule.getSourceIpAddressId(), e);
+                } finally {
+                    if (!success && newRule != null) {
+                        _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
+                        removeLBRule(newRule);
+                    }
+                }
+            }
+        });
+
+    }
+
+    @Override
+    public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException {
+        LoadBalancerVO lb = _lbDao.findById(lbRuleId);
+        List<LoadBalancerVO> lbs;
+        if (isRollBackAllowedForProvider(lb)) {
+            // this is for Netscalar type of devices. if their is failure the db
+            // entries will be rollbacked.
+            lbs = Arrays.asList(lb);
+        } else {
+            boolean onlyRulesInTransitionState = true;
+            for (LoadBalancingServiceProvider lbElement : _lbProviders) {
+                Provider provider = lbElement.getProvider();
+                boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(lb.getNetworkId(), Service.Lb, provider);
+                if (!isLbProvider) {
+                    continue;
+                }
+                onlyRulesInTransitionState = lbElement.handlesOnlyRulesInTransitionState();
+                break;
+            }
+
+            // get all rules in transition state
+            if (onlyRulesInTransitionState) {
+                lbs = _lbDao.listInTransitionStateByNetworkIdAndScheme(lb.getNetworkId(), lb.getScheme());
+            } else {
+                lbs = _lbDao.listByNetworkIdAndScheme(lb.getNetworkId(), lb.getScheme());
+            }
+
+        }
+        return applyLoadBalancerRules(lbs, true);
+    }
+
+    @Override
+    public boolean revokeLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException {
+        List<LoadBalancerVO> lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Revoking " + lbs.size() + " " + scheme + " load balancing rules for network id=" + networkId);
+        }
+        if (lbs != null) {
+            for (LoadBalancerVO lb : lbs) { // called during restart, not persisting state in db
+                lb.setState(FirewallRule.State.Revoke);
+            }
+            return applyLoadBalancerRules(lbs, false); // called during restart, not persisting state in db
+        } else {
+            s_logger.info("Network id=" + networkId + " doesn't have load balancer rules, nothing to revoke");
+            return true;
+        }
+    }
+
+    @Override
+    public boolean applyLoadBalancersForNetwork(long networkId, Scheme scheme) throws ResourceUnavailableException {
+        List<LoadBalancerVO> lbs = _lbDao.listByNetworkIdAndScheme(networkId, scheme);
+        if (lbs != null) {
+            s_logger.debug("Applying load balancer rules of scheme " + scheme + " in network id=" + networkId);
+            return applyLoadBalancerRules(lbs, true);
+        } else {
+            s_logger.info("Network id=" + networkId + " doesn't have load balancer rules of scheme " + scheme + ", nothing to apply");
+            return true;
+        }
+    }
+
+    protected boolean applyLbRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
+        boolean handled = false;
+        for (LoadBalancingServiceProvider lbElement : _lbProviders) {
+            Provider provider = lbElement.getProvider();
+            boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider);
+            if (!isLbProvider) {
+                continue;
+            }
+            handled = lbElement.applyLBRules(network, rules);
+            if (handled)
+                break;
+        }
+        return handled;
+    }
+
+    private LoadBalancingRule getLoadBalancerRuleToApply(LoadBalancerVO lb) {
+
+        List<LbStickinessPolicy> policyList = getStickinessPolicies(lb.getId());
+        Ip sourceIp = getSourceIp(lb);
+        LbSslCert sslCert = getLbSslCert(lb.getId());
+        LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, null, policyList, null, sourceIp, sslCert, lb.getLbProtocol());
+
+        if (_autoScaleVmGroupDao.isAutoScaleLoadBalancer(lb.getId())) {
+            // Get the associated VmGroup
+            AutoScaleVmGroupVO vmGroup = _autoScaleVmGroupDao.listByAll(lb.getId(), null).get(0);
+            LbAutoScaleVmGroup lbAutoScaleVmGroup = getLbAutoScaleVmGroup(vmGroup, vmGroup.getState(), lb);
+            loadBalancing.setAutoScaleVmGroup(lbAutoScaleVmGroup);
+        } else {
+            List<LbDestination> dstList = getExistingDestinations(lb.getId());
+            loadBalancing.setDestinations(dstList);
+            List<LbHealthCheckPolicy> hcPolicyList = getHealthCheckPolicies(lb.getId());
+            loadBalancing.setHealthCheckPolicies(hcPolicyList);
+        }
+
+        return loadBalancing;
+    }
+
+    @DB
+    protected boolean applyLoadBalancerRules(List<LoadBalancerVO> lbs, boolean updateRulesInDB) throws ResourceUnavailableException {
+        List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
+        for (LoadBalancerVO lb : lbs) {
+            rules.add(getLoadBalancerRuleToApply(lb));
+        }
+
+        if (!applyLbRules(rules, false)) {
+            s_logger.debug("LB rules are not completely applied");
+            return false;
+        }
+
+        if (updateRulesInDB) {
+            for (final LoadBalancerVO lb : lbs) {
+                boolean checkForReleaseElasticIp = Transaction.execute(new TransactionCallback<Boolean>() {
+                    @Override
+                    public Boolean doInTransaction(TransactionStatus status) {
+                        boolean checkForReleaseElasticIp = false;
+
+                        if (lb.getState() == FirewallRule.State.Revoke) {
+                            removeLBRule(lb);
+                            s_logger.debug("LB " + lb.getId() + " is successfully removed");
+                            checkForReleaseElasticIp = true;
+                        } else if (lb.getState() == FirewallRule.State.Add) {
+                            lb.setState(FirewallRule.State.Active);
+                            s_logger.debug("LB rule " + lb.getId() + " state is set to Active");
+                            _lbDao.persist(lb);
+                        }
+
+                        // remove LB-Vm mappings that were state to revoke
+                        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lb.getId(), true);
+                        List<Long> instanceIds = new ArrayList<Long>();
+
+                        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
+                            instanceIds.add(lbVmMap.getInstanceId());
+                            _lb2VmMapDao.remove(lb.getId(), lbVmMap.getInstanceId(), lbVmMap.getInstanceIp(), null);
+                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed for vm " +
+                                    lbVmMap.getInstanceId() + " instance ip " + lbVmMap.getInstanceIp());
+                        }
+
+
+                        if (_lb2VmMapDao.listByLoadBalancerId(lb.getId()).isEmpty()) {
+                            lb.setState(FirewallRule.State.Add);
+                            _lbDao.persist(lb);
+                            s_logger.debug("LB rule " + lb.getId() + " state is set to Add as there are no more active LB-VM mappings");
+                        }
+
+                        // remove LB-Stickiness policy mapping that were state to revoke
+                        List<LBStickinessPolicyVO> stickinesspolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lb.getId(), true);
+                        if (!stickinesspolicies.isEmpty()) {
+                            _lb2stickinesspoliciesDao.remove(lb.getId(), true);
+                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed stickiness policies");
+                        }
+
+                        // remove LB-HealthCheck policy mapping that were state to
+                        // revoke
+                        List<LBHealthCheckPolicyVO> healthCheckpolicies = _lb2healthcheckDao.listByLoadBalancerId(lb.getId(), true);
+                        if (!healthCheckpolicies.isEmpty()) {
+                            _lb2healthcheckDao.remove(lb.getId(), true);
+                            s_logger.debug("Load balancer rule id " + lb.getId() + " is removed health check monitors policies");
+                        }
+
+                        LoadBalancerCertMapVO lbCertMap = _lbCertMapDao.findByLbRuleId(lb.getId());
+                        if (lbCertMap != null && lbCertMap.isRevoke()) {
+                            _lbCertMapDao.remove(lbCertMap.getId());
+                            s_logger.debug("Load balancer rule id " + lb.getId() + " removed certificate mapping");
+                        }
+
+                        return checkForReleaseElasticIp;
+                    }
+                });
+
+                if (checkForReleaseElasticIp && lb.getSourceIpAddressId() != null) {
+                    boolean success = true;
+                    long count = _firewallDao.countRulesByIpId(lb.getSourceIpAddressId());
+                    if (count == 0) {
+                        try {
+                            success = handleSystemLBIpRelease(lb);
+                        } catch (Exception ex) {
+                            s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion due to exception ", ex);
+                            success = false;
+                        } finally {
+                            if (!success) {
+                                s_logger.warn("Failed to release system ip as a part of lb rule " + lb + " deletion");
+                            }
+                        }
+                    }
+                }
+                // if the rule is the last one for the ip address assigned to
+                // VPC, unassign it from the network
+                if (lb.getSourceIpAddressId() != null) {
+                    IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId());
+                    _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), lb.getNetworkId());
+                }
+            }
+        }
+
+        return true;
+    }
+
+    protected boolean handleSystemLBIpRelease(LoadBalancerVO lb) {
+        IpAddress ip = _ipAddressDao.findById(lb.getSourceIpAddressId());
+        boolean success = true;
+        if (ip.getSystem()) {
+            s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule");
+            if (!_ipAddrMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), CallContext.current().getCallingUserId(), CallContext.current().getCallingAccount())) {
+                s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
+                success = false;
+            } else {
+                s_logger.warn("Successfully released system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule");
+            }
+        }
+        return success;
+    }
+
+    @Override
+    public boolean removeAllLoadBalanacersForIp(long ipId, Account caller, long callerUserId) {
+
+        //Included revoked rules to remove the rules of ips which are in revoke state
+        List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.LoadBalancing);
+
+        if (rules != null) {
+            s_logger.debug("Found " + rules.size() + " lb rules to cleanup");
+            for (FirewallRule rule : rules) {
+                boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false);
+                if (result == false) {
+                    s_logger.warn("Unable to remove load balancer rule " + rule.getId());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeAllLoadBalanacersForNetwork(long networkId, Account caller, long callerUserId) {
+        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.LoadBalancing);
+        if (rules != null) {
+            s_logger.debug("Found " + rules.size() + " lb rules to cleanup");
+            for (FirewallRule rule : rules) {
+                boolean result = deleteLoadBalancerRule(rule.getId(), true, caller, callerUserId, false);
+                if (result == false) {
+                    s_logger.warn("Unable to remove load balancer rule " + rule.getId());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public List<LbStickinessPolicy> getStickinessPolicies(long lbId) {
+        List<LbStickinessPolicy> stickinessPolicies = new ArrayList<LbStickinessPolicy>();
+        List<LBStickinessPolicyVO> sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerId(lbId, false);
+
+        for (LBStickinessPolicyVO sDbPolicy : sDbpolicies) {
+            LbStickinessPolicy sPolicy = new LbStickinessPolicy(sDbPolicy.getMethodName(), sDbPolicy.getParams(), sDbPolicy.isRevoke());
+            stickinessPolicies.add(sPolicy);
+        }
+        return stickinessPolicies;
+    }
+
+    @Override
+    public List<LbHealthCheckPolicy> getHealthCheckPolicies(long lbId) {
+        List<LbHealthCheckPolicy> healthCheckPolicies = new ArrayList<LbHealthCheckPolicy>();
+        List<LBHealthCheckPolicyVO> hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(lbId, null);
+
+        for (LBHealthCheckPolicyVO policy : hcDbpolicies) {
+            String pingpath = policy.getpingpath();
+            LbHealthCheckPolicy hDbPolicy =
+                new LbHealthCheckPolicy(pingpath, policy.getDescription(), policy.getResponseTime(), policy.getHealthcheckInterval(), policy.getHealthcheckThresshold(),
+                    policy.getUnhealthThresshold(), policy.isRevoke());
+            healthCheckPolicies.add(hDbPolicy);
+        }
+        return healthCheckPolicies;
+    }
+
+    @Override
+    public List<LbDestination> getExistingDestinations(long lbId) {
+        List<LbDestination> dstList = new ArrayList<LbDestination>();
+        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId);
+        LoadBalancerVO lb = _lbDao.findById(lbId);
+
+        String dstIp = null;
+        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
+            UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
+            Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId());
+            dstIp = lbVmMap.getInstanceIp() == null ? nic.getIPv4Address(): lbVmMap.getInstanceIp();
+            LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke());
+            dstList.add(lbDst);
+        }
+        return dstList;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_UPDATE, eventDescription = "updating load balancer", async = true)
+    public LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long lbRuleId = cmd.getId();
+        String name = cmd.getLoadBalancerName();
+        String description = cmd.getDescription();
+        String algorithm = cmd.getAlgorithm();
+        LoadBalancerVO lb = _lbDao.findById(lbRuleId);
+        LoadBalancerVO lbBackup = _lbDao.findById(lbRuleId);
+        String customId = cmd.getCustomId();
+        Boolean forDisplay = cmd.getDisplay();
+
+        if (lb == null) {
+            throw new InvalidParameterValueException("Unable to find lb rule by id=" + lbRuleId);
+        }
+
+        // check permissions
+        _accountMgr.checkAccess(caller, null, true, lb);
+
+        if (name != null) {
+            lb.setName(name);
+        }
+
+        if (description != null) {
+            lb.setDescription(description);
+        }
+
+        if (algorithm != null) {
+            lb.setAlgorithm(algorithm);
+        }
+
+        if (customId != null) {
+            lb.setUuid(customId);
+        }
+
+        if (forDisplay != null) {
+            lb.setDisplay(forDisplay);
+        }
+
+        // Validate rule in LB provider
+        LoadBalancingRule rule = getLoadBalancerRuleToApply(lb);
+        if (!validateLbRule(rule)) {
+            throw new InvalidParameterValueException("Modifications in lb rule " + lbRuleId + " are not supported.");
+        }
+
+        LoadBalancerVO tmplbVo = _lbDao.findById(lbRuleId);
+        boolean success = _lbDao.update(lbRuleId, lb);
+
+        // If algorithm is changed, have to reapply the lb config
+        if ((algorithm != null) && (tmplbVo.getAlgorithm().compareTo(algorithm) != 0)){
+            try {
+                lb.setState(FirewallRule.State.Add);
+                _lbDao.persist(lb);
+                applyLoadBalancerConfig(lbRuleId);
+            } catch (ResourceUnavailableException e) {
+                if (isRollBackAllowedForProvider(lb)) {
+                    /*
+                     * NOTE : We use lb object to update db instead of lbBackup
+                     * object since db layer will fail to update if there is no
+                     * change in the object.
+                     */
+                    if (lbBackup.getName() != null) {
+                        lb.setName(lbBackup.getName());
+                    }
+                    if (lbBackup.getDescription() != null) {
+                        lb.setDescription(lbBackup.getDescription());
+                    }
+                    if (lbBackup.getAlgorithm() != null) {
+                        lb.setAlgorithm(lbBackup.getAlgorithm());
+                    }
+                    lb.setState(lbBackup.getState());
+                    _lbDao.update(lb.getId(), lb);
+                    _lbDao.persist(lb);
+
+                    s_logger.debug("LB Rollback rule id: " + lbRuleId + " while updating LB rule.");
+                }
+                s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e);
+                success = false;
+            }
+        }
+
+        if (!success) {
+            throw new CloudRuntimeException("Failed to update load balancer rule: " + lbRuleId);
+        }
+
+        return lb;
+    }
+
+    @Override
+    public Pair<List<? extends UserVm>, List<String>> listLoadBalancerInstances(ListLoadBalancerRuleInstancesCmd cmd) throws PermissionDeniedException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long loadBalancerId = cmd.getId();
+        Boolean applied = cmd.isApplied();
+
+        if (applied == null) {
+            applied = Boolean.TRUE;
+        }
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
+        if (loadBalancer == null) {
+            return null;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, loadBalancer);
+
+        List<UserVmVO> loadBalancerInstances = new ArrayList<UserVmVO>();
+        List<String> serviceStates = new ArrayList<String>();
+        List<LoadBalancerVMMapVO> vmLoadBalancerMappings = null;
+        vmLoadBalancerMappings = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId);
+        if(vmLoadBalancerMappings == null) {
+            String msg = "no VM Loadbalancer Mapping found";
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        Map<Long, String> vmServiceState = new HashMap<Long, String>(vmLoadBalancerMappings.size());
+        List<Long> appliedInstanceIdList = new ArrayList<Long>();
+
+        if ((vmLoadBalancerMappings != null) && !vmLoadBalancerMappings.isEmpty()) {
+            for (LoadBalancerVMMapVO vmLoadBalancerMapping : vmLoadBalancerMappings) {
+                appliedInstanceIdList.add(vmLoadBalancerMapping.getInstanceId());
+                vmServiceState.put(vmLoadBalancerMapping.getInstanceId(), vmLoadBalancerMapping.getState());
+            }
+        }
+
+        List<UserVmVO> userVms = _vmDao.listVirtualNetworkInstancesByAcctAndNetwork(loadBalancer.getAccountId(), loadBalancer.getNetworkId());
+
+        for (UserVmVO userVm : userVms) {
+            // if the VM is destroyed, being expunged, in an error state, or in
+            // an unknown state, skip it
+            switch (userVm.getState()) {
+            case Destroyed:
+            case Expunging:
+            case Error:
+            case Unknown:
+                continue;
+            }
+
+            boolean isApplied = appliedInstanceIdList.contains(userVm.getId());
+            if ((isApplied && applied) || (!isApplied && !applied)) {
+                loadBalancerInstances.add(userVm);
+                serviceStates.add(vmServiceState.get(userVm.getId()));
+            }
+        }
+        return new Pair<List<? extends UserVm>, List<String>>(loadBalancerInstances, serviceStates);
+    }
+
+    @Override
+    public List<String> listLbVmIpAddress (long id, long vmId) {
+
+        List <LoadBalancerVMMapVO> listLbvmMapVo = _lb2VmMapDao.listByLoadBalancerIdAndVmId(id, vmId);
+
+        List <String> vmIps = new ArrayList<String>();
+        for (LoadBalancerVMMapVO lbVmVo : listLbvmMapVo) {
+            vmIps.add(lbVmVo.getInstanceIp());
+        }
+        return vmIps;
+    }
+
+    @Override
+    public List<LbStickinessMethod> getStickinessMethods(long networkid) {
+        String capability = getLBCapability(networkid, Capability.SupportedStickinessMethods.getName());
+        if (capability == null) {
+            return null;
+        }
+        Gson gson = new Gson();
+        java.lang.reflect.Type listType = new TypeToken<List<LbStickinessMethod>>() {
+        }.getType();
+        List<LbStickinessMethod> result = gson.fromJson(capability, listType);
+        return result;
+    }
+
+    @Override
+    public List<LBStickinessPolicyVO> searchForLBStickinessPolicies(ListLBStickinessPoliciesCmd cmd) throws PermissionDeniedException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long loadBalancerId = cmd.getLbRuleId();
+        Long stickinessId = cmd.getId();
+
+        boolean forDisplay = cmd.getDisplay();
+        LoadBalancerVO loadBalancer = null;
+
+        if (loadBalancerId == null) {
+            loadBalancer = findLbByStickinessId(stickinessId);
+        } else {
+            loadBalancer = _lbDao.findById(loadBalancerId);
+        }
+
+        if (loadBalancer == null) {
+            return null;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, loadBalancer);
+
+        List<LBStickinessPolicyVO> sDbpolicies = _lb2stickinesspoliciesDao.listByLoadBalancerIdAndDisplayFlag(loadBalancer.getId(), forDisplay);
+
+        return sDbpolicies;
+    }
+
+    @Override
+    public List<LBHealthCheckPolicyVO> searchForLBHealthCheckPolicies(ListLBHealthCheckPoliciesCmd cmd) throws PermissionDeniedException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long loadBalancerId = cmd.getLbRuleId();
+        Long policyId = cmd.getId();
+        boolean forDisplay = cmd.getDisplay();
+        if(loadBalancerId == null) {
+            loadBalancerId = findLBIdByHealtCheckPolicyId(policyId);
+        }
+        LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId);
+        if (loadBalancer == null) {
+            return null;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, loadBalancer);
+        List<LBHealthCheckPolicyVO> hcDbpolicies = _lb2healthcheckDao.listByLoadBalancerIdAndDisplayFlag(loadBalancerId, forDisplay);
+
+        return hcDbpolicies;
+    }
+
+    @Override
+    public Pair<List<? extends LoadBalancer>, Integer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) {
+        Long ipId = cmd.getPublicIpId();
+        Long zoneId = cmd.getZoneId();
+        Long id = cmd.getId();
+        String name = cmd.getLoadBalancerRuleName();
+        String keyword = cmd.getKeyword();
+        Long instanceId = cmd.getVirtualMachineId();
+        Long networkId = cmd.getNetworkId();
+        Map<String, String> tags = cmd.getTags();
+        Boolean forDisplay = cmd.getDisplay();
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
+                cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts,
+                domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(LoadBalancerVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<LoadBalancerVO> sb = _lbDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("sourceIpAddress", sb.entity().getSourceIpAddressId(), SearchCriteria.Op.EQ);
+        sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        sb.and("scheme", sb.entity().getScheme(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
+
+        if (instanceId != null) {
+            SearchBuilder<LoadBalancerVMMapVO> lbVMSearch = _lb2VmMapDao.createSearchBuilder();
+            lbVMSearch.and("instanceId", lbVMSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
+            sb.join("lbVMSearch", lbVMSearch, sb.entity().getId(), lbVMSearch.entity().getLoadBalancerId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (zoneId != null) {
+            SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
+            ipSearch.and("zoneId", ipSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+            sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<LoadBalancerVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            SearchCriteria<LoadBalancerVO> ssc = _lbDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (ipId != null) {
+            sc.setParameters("sourceIpAddress", ipId);
+        }
+
+        if (instanceId != null) {
+            sc.setJoinParameters("lbVMSearch", "instanceId", instanceId);
+        }
+
+        if (zoneId != null) {
+            sc.setJoinParameters("ipSearch", "zoneId", zoneId);
+        }
+
+        if (networkId != null) {
+            sc.setParameters("networkId", networkId);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.LoadBalancer.toString());
+            for (String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        if (forDisplay != null) {
+            sc.setParameters("display", forDisplay);
+        }
+
+        //list only Public load balancers using this command
+        sc.setParameters("scheme", Scheme.Public);
+
+        Pair<List<LoadBalancerVO>, Integer> result = _lbDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends LoadBalancer>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public LoadBalancerVO findById(long lbId) {
+        return _lbDao.findById(lbId);
+    }
+
+    @Override
+    public LoadBalancerVO findLbByStickinessId(long stickinessPolicyId) {
+        LBStickinessPolicyVO stickinessPolicy = _lb2stickinesspoliciesDao.findById(stickinessPolicyId);
+
+        if (stickinessPolicy == null) {
+            return null;
+        }
+        return _lbDao.findById(stickinessPolicy.getLoadBalancerId());
+    }
+
+    @Override
+    public void removeLBRule(LoadBalancer rule) {
+        // remove the rule
+        _lbDao.remove(rule.getId());
+    }
+
+    public boolean applyLbRules(List<LoadBalancingRule> rules, boolean continueOnError) throws ResourceUnavailableException {
+        if (rules == null || rules.size() == 0) {
+            s_logger.debug("There are no Load Balancing Rules to forward to the network elements");
+            return true;
+        }
+
+        boolean success = true;
+        Network network = _networkModel.getNetwork(rules.get(0).getNetworkId());
+        List<PublicIp> publicIps = new ArrayList<PublicIp>();
+
+        // get the list of public ip's owned by the network
+        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
+        if (userIps != null && !userIps.isEmpty()) {
+            for (IPAddressVO userIp : userIps) {
+                PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                publicIps.add(publicIp);
+            }
+        }
+
+        // rules can not programmed unless IP is associated with network
+        // service provider, so run IP assoication for
+        // the network so as to ensure IP is associated before applying
+        // rules (in add state)
+        _ipAddrMgr.applyIpAssociations(network, false, continueOnError, publicIps);
+
+        try {
+            applyLbRules(network, rules);
+        } catch (ResourceUnavailableException e) {
+            if (!continueOnError) {
+                throw e;
+            }
+            s_logger.warn("Problems with applying load balancing rules but pushing on", e);
+            success = false;
+        }
+
+        // if all the rules configured on public IP are revoked then
+        // dis-associate IP with network service provider
+        _ipAddrMgr.applyIpAssociations(network, true, continueOnError, publicIps);
+
+        return success;
+    }
+
+    @Override
+    public Map<Ip, UserVm> getLbInstances(long lbId) {
+        Map<Ip, UserVm> dstList = new HashMap<Ip, UserVm>();
+        List<LoadBalancerVMMapVO> lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId);
+        LoadBalancerVO lb = _lbDao.findById(lbId);
+
+        for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) {
+            UserVm vm = _vmDao.findById(lbVmMap.getInstanceId());
+            Nic nic = _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(lb.getNetworkId(), vm.getId());
+            Ip ip = new Ip(nic.getIPv4Address());
+            dstList.put(ip, vm);
+        }
+        return dstList;
+    }
+
+    @Override
+    public boolean isLbRuleMappedToVmGuestIp(String vmSecondaryIp) {
+        List<LoadBalancerVMMapVO> lbVmMap = _lb2VmMapDao.listByInstanceIp(vmSecondaryIp);
+        if (lbVmMap == null || lbVmMap.isEmpty()) {
+            return  false;
+        }
+        return true;
+    }
+
+    @Override
+    public void isLbServiceSupportedInNetwork(long networkId, Scheme scheme) {
+        Network network = _networkDao.findById(networkId);
+
+        //1) Check if the LB service is supported
+        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id");
+            ex.addProxyObject(network.getUuid(), "networkId");
+            throw ex;
+        }
+
+        //2) Check if the Scheme is supported\
+        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+        if (scheme == Scheme.Public) {
+            if (!off.isPublicLb()) {
+                throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off);
+            }
+        } else {
+            if (!off.isInternalLb()) {
+                throw new InvalidParameterValueException("Scheme " + scheme + " is not supported by the network offering " + off);
+            }
+        }
+
+        //3) Check if the provider supports the scheme
+        LoadBalancingServiceProvider lbProvider = _networkMgr.getLoadBalancingProviderForNetwork(network, scheme);
+        if (lbProvider == null) {
+            throw new InvalidParameterValueException("Lb rule with scheme " + scheme.toString() + " is not supported by lb providers in network " + network);
+        }
+    }
+
+    public List<LoadBalancingServiceProvider> getLbProviders() {
+        return _lbProviders;
+    }
+
+    @Inject
+    public void setLbProviders(List<LoadBalancingServiceProvider> lbProviders) {
+        this._lbProviders = lbProviders;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LB_STICKINESSPOLICY_UPDATE, eventDescription = "updating lb stickiness policy", async = true)
+    public StickinessPolicy updateLBStickinessPolicy(long id, String customId, Boolean forDisplay) {
+        LBStickinessPolicyVO policy = _lb2stickinesspoliciesDao.findById(id);
+        if (policy == null) {
+            throw new InvalidParameterValueException("Fail to find stickiness policy with " + id);
+        }
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId()));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id);
+        }
+
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer);
+
+        if (customId != null) {
+            policy.setUuid(customId);
+        }
+
+        if (forDisplay != null) {
+            policy.setDisplay(forDisplay);
+        }
+
+        _lb2stickinesspoliciesDao.update(id, policy);
+        return _lb2stickinesspoliciesDao.findById(id);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_LB_HEALTHCHECKPOLICY_UPDATE, eventDescription = "updating lb healthcheck policy", async = true)
+    public HealthCheckPolicy updateLBHealthCheckPolicy(long id, String customId, Boolean forDisplay) {
+        LBHealthCheckPolicyVO policy = _lb2healthcheckDao.findById(id);
+        if (policy == null) {
+            throw new InvalidParameterValueException("Fail to find stickiness policy with " + id);
+        }
+
+        LoadBalancerVO loadBalancer = _lbDao.findById(Long.valueOf(policy.getLoadBalancerId()));
+        if (loadBalancer == null) {
+            throw new InvalidParameterException("Invalid Load balancer : " + policy.getLoadBalancerId() + " for Stickiness policy id: " + id);
+        }
+
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, loadBalancer);
+
+        if (customId != null) {
+            policy.setUuid(customId);
+        }
+
+        if (forDisplay != null) {
+            policy.setDisplay(forDisplay);
+        }
+
+        _lb2healthcheckDao.update(id, policy);
+        return _lb2healthcheckDao.findById(id);
+    }
+
+    @Override
+    public Long findLBIdByHealtCheckPolicyId(long lbHealthCheckPolicy) {
+        LBHealthCheckPolicyVO policy= _lb2healthcheckDao.findById(lbHealthCheckPolicy);
+        if(policy != null) {
+            return policy.getLoadBalancerId();
+        }
+        return null;
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
new file mode 100644
index 0000000..9ea2b98
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
@@ -0,0 +1,1104 @@
+// 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.network.router;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.CreateIpAliasCommand;
+import com.cloud.agent.api.routing.DeleteIpAliasCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.IpAliasTO;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.SetStaticRouteCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.DhcpTO;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.agent.api.to.NetworkACLTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.configuration.Config;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.VpnUser;
+import com.cloud.network.VpnUserVO;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
+import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
+import com.cloud.network.dao.Site2SiteVpnGatewayDao;
+import com.cloud.network.dao.Site2SiteVpnGatewayVO;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRule.LbDestination;
+import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateIpAddress;
+import com.cloud.network.vpc.StaticRouteProfile;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcGateway;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicIpAlias;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.UserVmDao;
+
+public class CommandSetupHelper {
+
+    private static final Logger s_logger = Logger.getLogger(CommandSetupHelper.class);
+
+    @Inject
+    private EntityManager _entityMgr;
+
+    @Inject
+    private NicDao _nicDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private DomainRouterDao _routerDao;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private NicIpAliasDao _nicIpAliasDao;
+    @Inject
+    private FirewallRulesDao _rulesDao;
+    @Inject
+    private NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private VpnUserDao _vpnUsersDao;
+    @Inject
+    private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
+    @Inject
+    private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
+    @Inject
+    private VpcDao _vpcDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private IPAddressDao _ipAddressDao;
+
+    @Inject
+    private RouterControlHelper _routerControlHelper;
+
+    @Autowired
+    @Qualifier("networkHelper")
+    protected NetworkHelper _networkHelper;
+
+    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();
+        cmds.addCommand(
+                "vmdata",
+                generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIPv4Address(), vm.getHostName(), vm.getInstanceName(),
+                        vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId()));
+    }
+
+    public void createApplyVpnUsersCommand(final List<? extends VpnUser> users, final VirtualRouter router, final Commands cmds) {
+        final List<VpnUser> addUsers = new ArrayList<VpnUser>();
+        final List<VpnUser> removeUsers = new ArrayList<VpnUser>();
+        for (final VpnUser user : users) {
+            if (user.getState() == VpnUser.State.Add || user.getState() == VpnUser.State.Active) {
+                addUsers.add(user);
+            } else if (user.getState() == VpnUser.State.Revoke) {
+                removeUsers.add(user);
+            }
+        }
+
+        final VpnUsersCfgCommand cmd = new VpnUsersCfgCommand(addUsers, removeUsers);
+        cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand("users", cmd);
+    }
+
+    public void createDhcpEntryCommand(final VirtualRouter router, final UserVm vm, final NicVO nic, boolean remove, final Commands cmds) {
+        final DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIPv4Address(), vm.getHostName(), nic.getIPv6Address(),
+                _networkModel.getExecuteInSeqNtwkElmtCmd());
+
+        String gatewayIp = nic.getIPv4Gateway();
+
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+
+        dhcpCommand.setDefaultRouter(gatewayIp);
+        dhcpCommand.setIp6Gateway(nic.getIPv6Gateway());
+        String ipaddress = null;
+        final NicVO domrDefaultNic = findDefaultDnsIp(vm.getId());
+        if (domrDefaultNic != null) {
+            ipaddress = domrDefaultNic.getIPv4Address();
+        }
+        dhcpCommand.setDefaultDns(ipaddress);
+        dhcpCommand.setDuid(NetUtils.getDuidLL(nic.getMacAddress()));
+        dhcpCommand.setDefault(nic.isDefaultNic());
+        dhcpCommand.setRemove(remove);
+
+        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId()));
+        dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand("dhcp", dhcpCommand);
+    }
+
+    public void createIpAlias(final VirtualRouter router, final List<IpAliasTO> ipAliasTOs, final Long networkid, final Commands cmds) {
+
+        final String routerip = _routerControlHelper.getRouterIpInNetwork(networkid, router.getId());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        final CreateIpAliasCommand ipaliasCmd = new CreateIpAliasCommand(routerip, ipAliasTOs);
+        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerip);
+        ipaliasCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand("ipalias", ipaliasCmd);
+    }
+
+    public void configDnsMasq(final VirtualRouter router, final Network network, final Commands cmds) {
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        final List<NicIpAliasVO> ipAliasVOList = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.active);
+        final List<DhcpTO> ipList = new ArrayList<DhcpTO>();
+
+        final NicVO router_guest_nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId());
+        final String cidr = NetUtils.getCidrFromGatewayAndNetmask(router_guest_nic.getIPv4Gateway(), router_guest_nic.getIPv4Netmask());
+        final String[] cidrPair = cidr.split("\\/");
+        final String cidrAddress = cidrPair[0];
+        final long cidrSize = Long.parseLong(cidrPair[1]);
+        final String startIpOfSubnet = NetUtils.getIpRangeStartIpFromCidr(cidrAddress, cidrSize);
+
+        ipList.add(new DhcpTO(router_guest_nic.getIPv4Address(), router_guest_nic.getIPv4Gateway(), router_guest_nic.getIPv4Netmask(), startIpOfSubnet));
+        for (final NicIpAliasVO ipAliasVO : ipAliasVOList) {
+            final DhcpTO DhcpTO = new DhcpTO(ipAliasVO.getIp4Address(), ipAliasVO.getGateway(), ipAliasVO.getNetmask(), ipAliasVO.getStartIpOfSubnet());
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("configDnsMasq : adding ip {" + DhcpTO.getGateway() + ", " + DhcpTO.getNetmask() + ", " + DhcpTO.getRouterIp() + ", " + DhcpTO.getStartIpOfSubnet()
+                        + "}");
+            }
+            ipList.add(DhcpTO);
+            ipAliasVO.setVmId(router.getId());
+        }
+        _dcDao.findById(router.getDataCenterId());
+        final DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(ipList);
+        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId()));
+        dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand("dnsMasqConfig", dnsMasqConfigCmd);
+    }
+
+    public void createApplyLoadBalancingRulesCommands(final List<LoadBalancingRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()];
+        int i = 0;
+        // We don't support VR to be inline currently
+        final boolean inline = false;
+        for (final LoadBalancingRule rule : rules) {
+            final boolean revoked = rule.getState().equals(FirewallRule.State.Revoke);
+            final String protocol = rule.getProtocol();
+            final String lb_protocol = rule.getLbProtocol();
+            final String algorithm = rule.getAlgorithm();
+            final String uuid = rule.getUuid();
+
+            final String srcIp = rule.getSourceIp().addr();
+            final int srcPort = rule.getSourcePortStart();
+            final List<LbDestination> destinations = rule.getDestinations();
+            final List<LbStickinessPolicy> stickinessPolicies = rule.getStickinessPolicies();
+            final LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies);
+            lb.setLbProtocol(lb_protocol);
+            lbs[i++] = lb;
+        }
+        String routerPublicIp = null;
+
+        if (router instanceof DomainRouterVO) {
+            final DomainRouterVO domr = _routerDao.findById(router.getId());
+            routerPublicIp = domr.getPublicIpAddress();
+            if (routerPublicIp == null) {
+                routerPublicIp = router.getPublicIpAddress();
+            }
+        }
+
+        final Network guestNetwork = _networkModel.getNetwork(guestNetworkId);
+        final Nic nic = _nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), router.getId());
+        final NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), _networkModel.getNetworkRate(guestNetwork.getId(),
+                router.getId()), _networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), _networkModel.getNetworkTag(router.getHypervisorType(), guestNetwork));
+        final NetworkOffering offering = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId());
+        String maxconn = null;
+        if (offering.getConcurrentConnections() == null) {
+            maxconn = _configDao.getValue(Config.NetworkLBHaproxyMaxConn.key());
+        } else {
+            maxconn = offering.getConcurrentConnections().toString();
+        }
+
+        final LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, routerPublicIp, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()),
+                router.getPrivateIpAddress(), _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled());
+
+        cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key());
+        cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key());
+        cmd.lbStatsAuth = _configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key());
+        cmd.lbStatsPort = _configDao.getValue(Config.NetworkLBHaproxyStatsPort.key());
+
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand(cmd);
+    }
+
+    public void createApplyPortForwardingRulesCommands(final List<? extends PortForwardingRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final List<PortForwardingRuleTO> rulesTO = new ArrayList<PortForwardingRuleTO>();
+        if (rules != null) {
+            for (final PortForwardingRule rule : rules) {
+                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                final PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, sourceIp.getAddress().addr());
+                rulesTO.add(ruleTO);
+            }
+        }
+
+        SetPortForwardingRulesCommand cmd = null;
+
+        if (router.getVpcId() != null) {
+            cmd = new SetPortForwardingRulesVpcCommand(rulesTO);
+        } else {
+            cmd = new SetPortForwardingRulesCommand(rulesTO);
+        }
+
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand(cmd);
+    }
+
+    public void createApplyStaticNatRulesCommands(final List<? extends StaticNatRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
+        if (rules != null) {
+            for (final StaticNatRule rule : rules) {
+                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                final StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getDestIpAddress());
+                rulesTO.add(ruleTO);
+            }
+        }
+
+        final SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand(cmd);
+    }
+
+    public void createApplyFirewallRulesCommands(final List<? extends FirewallRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
+        String systemRule = null;
+        Boolean defaultEgressPolicy = false;
+        if (rules != null) {
+            if (rules.size() > 0) {
+                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System) {
+                    systemRule = String.valueOf(FirewallRule.FirewallRuleType.System);
+                }
+            }
+            for (final FirewallRule rule : rules) {
+                _rulesDao.loadSourceCidrs((FirewallRuleVO) rule);
+                final FirewallRule.TrafficType traffictype = rule.getTrafficType();
+                if (traffictype == FirewallRule.TrafficType.Ingress) {
+                    final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype);
+                    rulesTO.add(ruleTO);
+                } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
+                    final NetworkVO network = _networkDao.findById(guestNetworkId);
+                    final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+                    defaultEgressPolicy = offering.isEgressDefaultPolicy();
+                    assert rule.getSourceIpAddressId() == null : "ipAddressId should be null for egress firewall rule. ";
+                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, "", Purpose.Firewall, traffictype, defaultEgressPolicy);
+                    rulesTO.add(ruleTO);
+                }
+            }
+        }
+
+        final SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        if (systemRule != null) {
+            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, systemRule);
+        } else {
+            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, String.valueOf(defaultEgressPolicy));
+        }
+
+        cmds.addCommand(cmd);
+    }
+
+    public void createFirewallRulesCommands(final List<? extends FirewallRule> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
+        String systemRule = null;
+        Boolean defaultEgressPolicy = false;
+        if (rules != null) {
+            if (rules.size() > 0) {
+                if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System) {
+                    systemRule = String.valueOf(FirewallRule.FirewallRuleType.System);
+                }
+            }
+            for (final FirewallRule rule : rules) {
+                _rulesDao.loadSourceCidrs((FirewallRuleVO) rule);
+                _rulesDao.loadDestinationCidrs((FirewallRuleVO)rule);
+                final FirewallRule.TrafficType traffictype = rule.getTrafficType();
+                if (traffictype == FirewallRule.TrafficType.Ingress) {
+                    final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype);
+                    rulesTO.add(ruleTO);
+                } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
+                    final NetworkVO network = _networkDao.findById(guestNetworkId);
+                    final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+                    defaultEgressPolicy = offering.isEgressDefaultPolicy();
+                    assert rule.getSourceIpAddressId() == null : "ipAddressId should be null for egress firewall rule. ";
+                    final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, "", Purpose.Firewall, traffictype, defaultEgressPolicy);
+                    rulesTO.add(ruleTO);
+                }
+            }
+        }
+
+        final SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        if (systemRule != null) {
+            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, systemRule);
+        } else {
+            cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, String.valueOf(defaultEgressPolicy));
+        }
+
+        cmds.addCommand(cmd);
+    }
+
+    public void createAssociateIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds, final long vmId) {
+        final String ipAssocCommand = "IPAssocCommand";
+        createRedundantAssociateIPCommands(router, ips, cmds, ipAssocCommand, false);
+    }
+
+    public void createNetworkACLsCommands(final List<? extends NetworkACLItem> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId,
+            final boolean privateGateway) {
+        final List<NetworkACLTO> rulesTO = new ArrayList<NetworkACLTO>();
+        String guestVlan = null;
+        final Network guestNtwk = _networkDao.findById(guestNetworkId);
+        final URI uri = guestNtwk.getBroadcastUri();
+        if (uri != null) {
+            guestVlan = BroadcastDomainType.getValue(uri);
+        }
+
+        if (rules != null) {
+            for (final NetworkACLItem rule : rules) {
+                final NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType());
+                rulesTO.add(ruleTO);
+            }
+        }
+
+        NicTO nicTO = _networkHelper.getNicTO(router, guestNetworkId, null);
+        final SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, nicTO);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        if (privateGateway) {
+            cmd.setAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY, String.valueOf(VpcGateway.Type.Private));
+        }
+
+        cmds.addCommand(cmd);
+    }
+
+    public void createPasswordCommand(final VirtualRouter router, final VirtualMachineProfile profile, final NicVO nic, final Commands cmds) {
+        final String password = (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword);
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+
+        // password should be set only on default network element
+        if (password != null && nic.isDefaultNic()) {
+            final SavePasswordCommand cmd = new SavePasswordCommand(password, nic.getIPv4Address(), profile.getVirtualMachine().getHostName(),
+                    _networkModel.getExecuteInSeqNtwkElmtCmd());
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+            cmds.addCommand("password", cmd);
+        }
+
+    }
+
+    public void createApplyStaticNatCommands(final List<? extends StaticNat> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) {
+        final List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
+        if (rules != null) {
+            for (final StaticNat rule : rules) {
+                final IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                final StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(),
+                        false);
+                rulesTO.add(ruleTO);
+            }
+        }
+
+        final SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand(cmd);
+    }
+
+    public void createStaticRouteCommands(final List<StaticRouteProfile> staticRoutes, final VirtualRouter router, final Commands cmds) {
+        final SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand(cmd);
+    }
+
+    public void createApplyVpnCommands(final boolean isCreate, final RemoteAccessVpn vpn, final VirtualRouter router, final Commands cmds) {
+        final List<VpnUserVO> vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId());
+
+        createApplyVpnUsersCommand(vpnUsers, router, cmds);
+
+        final IpAddress ip = _networkModel.getIp(vpn.getServerAddressId());
+
+        // This block is needed due to the line 206 of the
+        // RemoteAccessVpnManagenerImpl:
+        // TODO: assumes one virtual network / domr per account per zone
+        final String cidr;
+        final Network network = _networkDao.findById(vpn.getNetworkId());
+        if (network == null) {
+            final Vpc vpc = _vpcDao.findById(vpn.getVpcId());
+            cidr = vpc.getCidr();
+        } else {
+            cidr = network.getCidr();
+        }
+
+        final RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(isCreate, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(),
+                vpn.getIpsecPresharedKey(), vpn.getVpcId() != null);
+        startVpnCmd.setLocalCidr(cidr);
+        startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand("startVpn", startVpnCmd);
+    }
+
+    public void createVmDataCommandForVMs(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());
+        for (final UserVmVO vm : vms) {
+            boolean createVmData = true;
+            if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()) {
+                createVmData = false;
+            }
+
+            if (createVmData) {
+                final NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId());
+                if (nic != null) {
+                    s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router);
+
+                    _userVmDao.loadDetails(vm);
+                    createVmDataCommand(router, vm, nic, vm.getDetail("SSH.PublicKey"), cmds);
+                }
+            }
+        }
+    }
+
+    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) {
+            if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()
+                    && dnsBasicZoneUpdates.equalsIgnoreCase("pod")) {
+                continue;
+            }
+
+            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, false, cmds);
+            }
+        }
+    }
+
+    public void createDeleteIpAliasCommand(final DomainRouterVO router, final List<IpAliasTO> deleteIpAliasTOs, final List<IpAliasTO> createIpAliasTos, final long networkId,
+            final Commands cmds) {
+        final String routerip = _routerControlHelper.getRouterIpInNetwork(networkId, router.getId());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        final DeleteIpAliasCommand deleteIpaliasCmd = new DeleteIpAliasCommand(routerip, deleteIpAliasTOs, createIpAliasTos);
+        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerip);
+        deleteIpaliasCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmds.addCommand("deleteIpalias", deleteIpaliasCmd);
+    }
+
+    public void createVpcAssociatePublicIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds,
+            final Map<String, String> vlanMacAddress) {
+
+        final String ipAssocCommand = "IPAssocVpcCommand";
+        if (router.getIsRedundantRouter()) {
+            createRedundantAssociateIPCommands(router, ips, cmds, ipAssocCommand, true);
+            return;
+        }
+
+        Pair<IpAddressTO, Long> sourceNatIpAdd = null;
+        Boolean addSourceNat = null;
+        // Ensure that in multiple vlans case we first send all ip addresses of
+        // vlan1, then all ip addresses of vlan2, etc..
+        final Map<String, ArrayList<PublicIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PublicIpAddress>>();
+        for (final PublicIpAddress ipAddress : ips) {
+            final String vlanTag = ipAddress.getVlanTag();
+            ArrayList<PublicIpAddress> ipList = vlanIpMap.get(vlanTag);
+            if (ipList == null) {
+                ipList = new ArrayList<PublicIpAddress>();
+            }
+            // VR doesn't support release for sourceNat IP address; so reset the
+            // state
+            if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) {
+                ipAddress.setState(IpAddress.State.Allocated);
+            }
+            ipList.add(ipAddress);
+            vlanIpMap.put(vlanTag, ipList);
+        }
+
+        for (final Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
+            final List<PublicIpAddress> ipAddrList = vlanAndIp.getValue();
+
+            // Source nat ip address should always be sent first
+            Collections.sort(ipAddrList, new Comparator<PublicIpAddress>() {
+                @Override
+                public int compare(final PublicIpAddress o1, final PublicIpAddress o2) {
+                    final boolean s1 = o1.isSourceNat();
+                    final boolean s2 = o2.isSourceNat();
+                    return s1 ^ s2 ? s1 ^ true ? 1 : -1 : 0;
+                }
+            });
+
+
+            // Get network rate - required for IpAssoc
+            final Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId());
+            final Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId());
+
+            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
+            int i = 0;
+            boolean firstIP = true;
+
+            for (final PublicIpAddress ipAddr : ipAddrList) {
+                final boolean add = ipAddr.getState() == IpAddress.State.Releasing ? false : true;
+                boolean sourceNat = ipAddr.isSourceNat();
+                /* enable sourceNAT for the first ip of the public interface
+                * For additional public subnet source nat rule needs to be added for vm to reach ips in that subnet
+                */
+                if (firstIP) {
+                    sourceNat = true;
+                }
+
+                final String macAddress = vlanMacAddress.get(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag())));
+
+                final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(),
+                        ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat());
+
+                ip.setTrafficType(network.getTrafficType());
+                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
+                ipsToSend[i++] = ip;
+                if (ipAddr.isSourceNat()) {
+                    sourceNatIpAdd = new Pair<IpAddressTO, Long>(ip, ipAddr.getNetworkId());
+                    addSourceNat = add;
+                }
+
+                //for additional public subnet on delete it is not sure which ip is set to first ip. So on delete we
+                //want to set sourcenat to true for all ips to delete source nat rules.
+                if (!firstIP || add) {
+                    firstIP = false;
+                }
+            }
+            final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend);
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+            cmds.addCommand(ipAssocCommand, cmd);
+        }
+
+        // set source nat ip
+        if (sourceNatIpAdd != null) {
+            final IpAddressTO sourceNatIp = sourceNatIpAdd.first();
+            final SetSourceNatCommand cmd = new SetSourceNatCommand(sourceNatIp, addSourceNat);
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+            cmds.addCommand("SetSourceNatCommand", cmd);
+        }
+    }
+
+    public void createRedundantAssociateIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds, final String ipAssocCommand, final boolean isVPC) {
+
+        // Ensure that in multiple vlans case we first send all ip addresses of
+        // vlan1, then all ip addresses of vlan2, etc..
+        final Map<String, ArrayList<PublicIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PublicIpAddress>>();
+        for (final PublicIpAddress ipAddress : ips) {
+            final String vlanTag = ipAddress.getVlanTag();
+            ArrayList<PublicIpAddress> ipList = vlanIpMap.get(vlanTag);
+            if (ipList == null) {
+                ipList = new ArrayList<PublicIpAddress>();
+            }
+            // domR doesn't support release for sourceNat IP address; so reset
+            // the state
+            if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) {
+                ipAddress.setState(IpAddress.State.Allocated);
+            }
+            ipList.add(ipAddress);
+            vlanIpMap.put(vlanTag, ipList);
+        }
+
+        final List<NicVO> nics = _nicDao.listByVmId(router.getId());
+        String baseMac = null;
+        for (final NicVO nic : nics) {
+            final NetworkVO nw = _networkDao.findById(nic.getNetworkId());
+            if (nw.getTrafficType() == TrafficType.Public) {
+                baseMac = nic.getMacAddress();
+                break;
+            }
+        }
+
+        for (final Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
+            final List<PublicIpAddress> ipAddrList = vlanAndIp.getValue();
+            // Source nat ip address should always be sent first
+            Collections.sort(ipAddrList, new Comparator<PublicIpAddress>() {
+                @Override
+                public int compare(final PublicIpAddress o1, final PublicIpAddress o2) {
+                    final boolean s1 = o1.isSourceNat();
+                    final boolean s2 = o2.isSourceNat();
+                    return s1 ^ s2 ? s1 ^ true ? 1 : -1 : 0;
+                }
+            });
+
+            // Get network rate - required for IpAssoc
+            final Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId());
+            final Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId());
+
+            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
+            int i = 0;
+            boolean firstIP = true;
+
+            for (final PublicIpAddress ipAddr : ipAddrList) {
+
+                final boolean add = ipAddr.getState() == IpAddress.State.Releasing ? false : true;
+                boolean sourceNat = ipAddr.isSourceNat();
+                /* enable sourceNAT for the first ip of the public interface */
+                if (firstIP) {
+                    sourceNat = true;
+                }
+                final String vlanId = ipAddr.getVlanTag();
+                final String vlanGateway = ipAddr.getGateway();
+                final String vlanNetmask = ipAddr.getNetmask();
+                String vifMacAddress = null;
+                // For non-source nat IP, set the mac to be something based on
+                // first public nic's MAC
+                // We cannot depend on first ip because we need to deal with
+                // first ip of other nics
+                if (router.getVpcId() != null) {
+                    //vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId());
+                    vifMacAddress = ipAddr.getMacAddress();
+                } else {
+                    if (!sourceNat && ipAddr.getVlanId() != 0) {
+                        vifMacAddress = NetUtils.generateMacOnIncrease(baseMac, ipAddr.getVlanId());
+                    } else {
+                        vifMacAddress = ipAddr.getMacAddress();
+                    }
+                }
+
+                final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask,
+                        vifMacAddress, networkRate, ipAddr.isOneToOneNat());
+
+                ip.setTrafficType(network.getTrafficType());
+                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
+                ipsToSend[i++] = ip;
+                /*
+                 * send the firstIP = true for the first Add, this is to create
+                 * primary on interface
+                 */
+                if (!firstIP || add) {
+                    firstIP = false;
+                }
+            }
+
+            Long associatedWithNetworkId = ipAddrList.get(0).getAssociatedWithNetworkId();
+            if (associatedWithNetworkId == null || associatedWithNetworkId == 0) {
+                associatedWithNetworkId = ipAddrList.get(0).getNetworkId();
+            }
+
+            // for network if the ips does not have any rules, then only last ip
+            final List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(associatedWithNetworkId, null);
+            boolean hasSourceNat = false;
+            if (isVPC && userIps.size() > 0 && userIps.get(0) != null) {
+                // All ips should belong to a VPC
+                final Long vpcId = userIps.get(0).getVpcId();
+                final List<IPAddressVO> sourceNatIps = _ipAddressDao.listByAssociatedVpc(vpcId, true);
+                if (sourceNatIps != null && sourceNatIps.size() > 0) {
+                    hasSourceNat = true;
+                }
+            }
+
+            int ipsWithrules = 0;
+            int ipsStaticNat = 0;
+            for (IPAddressVO ip : userIps) {
+                if ( _rulesDao.countRulesByIpIdAndState(ip.getId(), FirewallRule.State.Active) > 0){
+                    ipsWithrules++;
+                }
+
+                // check onetoonenat and also check if the ip "add":false. If there are 2 PF rules remove and
+                // 1 static nat rule add
+                if (ip.isOneToOneNat() && ip.getRuleState() == null) {
+                    ipsStaticNat++;
+                }
+            }
+
+            final IpAssocCommand cmd = new IpAssocCommand(ipsToSend);
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(associatedWithNetworkId, router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+            // if there is 1 static nat then it will be checked for remove at the resource
+            if (ipsWithrules == 0 && ipsStaticNat == 0 && !hasSourceNat) {
+                // there is only one ip address for the network.
+                cmd.setAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP, "true");
+            } else {
+                cmd.setAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP, "false");
+            }
+
+            cmds.addCommand(ipAssocCommand, cmd);
+        }
+    }
+
+    public void createStaticRouteCommands(final List<StaticRouteProfile> staticRoutes, final DomainRouterVO router, final Commands cmds) {
+        final SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand(cmd);
+    }
+
+    public void createSite2SiteVpnCfgCommands(final Site2SiteVpnConnection conn, final boolean isCreate, final VirtualRouter router, final Commands cmds) {
+        final Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+        final Site2SiteVpnGatewayVO vpnGw = _s2sVpnGatewayDao.findById(conn.getVpnGatewayId());
+        final IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId());
+        final Vpc vpc = _vpcDao.findById(ip.getVpcId());
+        final String localPublicIp = ip.getAddress().toString();
+        final String localGuestCidr = vpc.getCidr();
+        final String localPublicGateway = _vlanDao.findById(ip.getVlanId()).getVlanGateway();
+        final String peerGatewayIp = gw.getGatewayIp();
+        final String peerGuestCidrList = gw.getGuestCidrList();
+        final String ipsecPsk = gw.getIpsecPsk();
+        final String ikePolicy = gw.getIkePolicy();
+        final String espPolicy = gw.getEspPolicy();
+        final Long ikeLifetime = gw.getIkeLifetime();
+        final Long espLifetime = gw.getEspLifetime();
+        final Boolean dpd = gw.getDpd();
+        final Boolean encap = gw.getEncap();
+
+        final Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, peerGatewayIp, peerGuestCidrList, ikePolicy,
+                espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive(), encap);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand("applyS2SVpn", cmd);
+    }
+
+    public void createVpcAssociatePrivateIPCommands(final VirtualRouter router, final List<PrivateIpAddress> ips, final Commands cmds, final boolean add) {
+
+        // Ensure that in multiple vlans case we first send all ip addresses of
+        // vlan1, then all ip addresses of vlan2, etc..
+        final Map<String, ArrayList<PrivateIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PrivateIpAddress>>();
+        for (final PrivateIpAddress ipAddress : ips) {
+            final String vlanTag = ipAddress.getBroadcastUri();
+            ArrayList<PrivateIpAddress> ipList = vlanIpMap.get(vlanTag);
+            if (ipList == null) {
+                ipList = new ArrayList<PrivateIpAddress>();
+            }
+
+            ipList.add(ipAddress);
+            vlanIpMap.put(vlanTag, ipList);
+        }
+
+        for (final Map.Entry<String, ArrayList<PrivateIpAddress>> vlanAndIp : vlanIpMap.entrySet()) {
+            final List<PrivateIpAddress> ipAddrList = vlanAndIp.getValue();
+            final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
+            int i = 0;
+
+            for (final PrivateIpAddress ipAddr : ipAddrList) {
+                final Network network = _networkModel.getNetwork(ipAddr.getNetworkId());
+                final IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false, ipAddr.getSourceNat(), ipAddr.getBroadcastUri(),
+                        ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(), null, false);
+
+                ip.setTrafficType(network.getTrafficType());
+                ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
+                ipsToSend[i++] = ip;
+
+            }
+            final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend);
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId()));
+            cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+            final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+            cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+            cmds.addCommand("IPAssocVpcCommand", cmd);
+        }
+    }
+
+    public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRouterVO router, final boolean add, final NicProfile guestNic) {
+        final Network network = _networkModel.getNetwork(guestNic.getNetworkId());
+
+        String defaultDns1 = null;
+        String defaultDns2 = null;
+
+        final boolean dnsProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter);
+        final boolean dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VPCVirtualRouter);
+
+        final boolean setupDns = dnsProvided || dhcpProvided;
+
+        if (setupDns) {
+            defaultDns1 = guestNic.getIPv4Dns1();
+            defaultDns2 = guestNic.getIPv4Dns2();
+        }
+
+        final Nic nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId());
+        final String networkDomain = network.getNetworkDomain();
+        final String dhcpRange = getGuestDhcpRange(guestNic, network, _entityMgr.findById(DataCenter.class, network.getDataCenterId()));
+
+        final NicProfile nicProfile = _networkModel.getNicProfile(router, nic.getNetworkId(), null);
+
+        final SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, router.getIsRedundantRouter(), defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile,
+                router.getHypervisorType()));
+
+        final String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIPv4Address()) | ~NetUtils.ip2Long(guestNic.getIPv4Netmask()));
+        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId()));
+
+        setupCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, network.getGateway());
+        setupCmd.setAccessDetail(NetworkElementCommand.GUEST_BRIDGE, brd);
+        setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+        if (network.getBroadcastDomainType() == BroadcastDomainType.Vlan) {
+            final long guestVlanTag = Long.parseLong(BroadcastDomainType.Vlan.getValueFrom(network.getBroadcastUri()));
+            setupCmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
+        }
+
+        return setupCmd;
+    }
+
+    private VmDataCommand generateVmDataCommand(final VirtualRouter router, final String vmPrivateIpAddress, final String userData, final String serviceOffering,
+            final String zoneName, final String guestIpAddress, final String vmName, final String vmInstanceName, final long vmId, final String vmUuid, final String publicKey,
+            final long guestNetworkId) {
+        final VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd());
+
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+
+        cmd.addVmData("userdata", "user-data", userData);
+        cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
+        cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
+        cmd.addVmData("metadata", "local-ipv4", guestIpAddress);
+        cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vmName));
+        if (dcVo.getNetworkType() == NetworkType.Basic) {
+            cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
+            cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName));
+        } else {
+            if (router.getPublicIpAddress() == null) {
+                cmd.addVmData("metadata", "public-ipv4", guestIpAddress);
+            } else {
+                cmd.addVmData("metadata", "public-ipv4", router.getPublicIpAddress());
+            }
+            cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress());
+        }
+        if (vmUuid == null) {
+            cmd.addVmData("metadata", "instance-id", vmInstanceName);
+            cmd.addVmData("metadata", "vm-id", String.valueOf(vmId));
+        } else {
+            cmd.addVmData("metadata", "instance-id", vmUuid);
+            cmd.addVmData("metadata", "vm-id", vmUuid);
+        }
+        cmd.addVmData("metadata", "public-keys", publicKey);
+
+        String cloudIdentifier = _configDao.getValue("cloud.identifier");
+        if (cloudIdentifier == null) {
+            cloudIdentifier = "";
+        } else {
+            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
+        }
+        cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);
+
+        return cmd;
+    }
+
+    private NicVO findGatewayIp(final long userVmId) {
+        final NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId);
+        return defaultNic;
+    }
+
+    private NicVO findDefaultDnsIp(final long userVmId) {
+        final NicVO defaultNic = _nicDao.findDefaultNicForVM(userVmId);
+
+        // check if DNS provider is the domR
+        if (!_networkModel.isProviderSupportServiceInNetwork(defaultNic.getNetworkId(), Service.Dns, Provider.VirtualRouter)) {
+            return null;
+        }
+
+        final NetworkOffering offering = _networkOfferingDao.findById(_networkDao.findById(defaultNic.getNetworkId()).getNetworkOfferingId());
+        if (offering.isRedundantRouter()) {
+            return findGatewayIp(userVmId);
+        }
+
+        final DataCenter dc = _dcDao.findById(_networkModel.getNetwork(defaultNic.getNetworkId()).getDataCenterId());
+        final boolean isZoneBasic = dc.getNetworkType() == NetworkType.Basic;
+
+        // find domR's nic in the network
+        NicVO domrDefaultNic;
+        if (isZoneBasic) {
+            domrDefaultNic = _nicDao.findByNetworkIdTypeAndGateway(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter, defaultNic.getIPv4Gateway());
+        } else {
+            domrDefaultNic = _nicDao.findByNetworkIdAndType(defaultNic.getNetworkId(), VirtualMachine.Type.DomainRouter);
+        }
+        return domrDefaultNic;
+    }
+
+    protected String getGuestDhcpRange(final NicProfile guestNic, final Network guestNetwork, final DataCenter dc) {
+        String dhcpRange = null;
+        // setup dhcp range
+        if (dc.getNetworkType() == NetworkType.Basic) {
+            final long cidrSize = NetUtils.getCidrSize(guestNic.getIPv4Netmask());
+            final String cidr = NetUtils.getCidrSubNet(guestNic.getIPv4Gateway(), cidrSize);
+            if (cidr != null) {
+                dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
+            }
+        } else if (dc.getNetworkType() == NetworkType.Advanced) {
+            final String cidr = guestNetwork.getCidr();
+            if (cidr != null) {
+                dhcpRange = NetUtils.getDhcpRange(cidr);
+            }
+        }
+        return dhcpRange;
+    }
+}
diff --git a/server/src/com/cloud/network/router/NetworkHelper.java b/server/src/main/java/com/cloud/network/router/NetworkHelper.java
similarity index 100%
rename from server/src/com/cloud/network/router/NetworkHelper.java
rename to server/src/main/java/com/cloud/network/router/NetworkHelper.java
diff --git a/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java b/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java
new file mode 100644
index 0000000..da07bb5
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/router/NetworkHelperImpl.java
@@ -0,0 +1,886 @@
+// 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.network.router;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.utils.CloudStackVersion;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.rules.LbStickinessMethod;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile.Param;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+public class NetworkHelperImpl implements NetworkHelper {
+
+    private static final Logger s_logger = Logger.getLogger(NetworkHelperImpl.class);
+
+    protected static Account s_systemAccount;
+    protected static String s_vmInstanceName;
+
+    @Inject
+    protected NicDao _nicDao;
+    @Inject
+    protected NetworkDao _networkDao;
+    @Inject
+    protected DomainRouterDao _routerDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    protected NetworkModel _networkModel;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private Site2SiteVpnManager _s2sVpnMgr;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    protected IPAddressDao _ipAddressDao;
+    @Inject
+    private UserIpv6AddressDao _ipv6Dao;
+    @Inject
+    protected NetworkOrchestrationService _networkMgr;
+    @Inject
+    private UserDao _userDao;
+    @Inject
+    protected ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    protected VirtualMachineManager _itMgr;
+    @Inject
+    protected IpAddressManager _ipAddrMgr;
+    @Inject
+    ConfigurationDao _configDao;
+
+    protected final Map<HypervisorType, ConfigKey<String>> hypervisorsMap = new HashMap<>();
+
+    @PostConstruct
+    protected void setupHypervisorsMap() {
+        hypervisorsMap.put(HypervisorType.XenServer, VirtualNetworkApplianceManager.RouterTemplateXen);
+        hypervisorsMap.put(HypervisorType.KVM, VirtualNetworkApplianceManager.RouterTemplateKvm);
+        hypervisorsMap.put(HypervisorType.VMware, VirtualNetworkApplianceManager.RouterTemplateVmware);
+        hypervisorsMap.put(HypervisorType.Hyperv, VirtualNetworkApplianceManager.RouterTemplateHyperV);
+        hypervisorsMap.put(HypervisorType.LXC, VirtualNetworkApplianceManager.RouterTemplateLxc);
+        hypervisorsMap.put(HypervisorType.Ovm3, VirtualNetworkApplianceManager.RouterTemplateOvm3);
+    }
+
+    @Override
+    public boolean sendCommandsToRouter(final VirtualRouter router, final Commands cmds) throws AgentUnavailableException, ResourceUnavailableException {
+        if (!checkRouterVersion(router)) {
+            s_logger.debug("Router requires upgrade. Unable to send command to router:" + router.getId() + ", router template version : " + router.getTemplateVersion()
+                    + ", minimal required version : " + NetworkOrchestrationService.MinVRVersion.valueIn(router.getDataCenterId()));
+            throw new ResourceUnavailableException("Unable to send command. Router requires upgrade", VirtualRouter.class, router.getId());
+        }
+        Answer[] answers = null;
+        try {
+            answers = _agentMgr.send(router.getHostId(), cmds);
+        } catch (final OperationTimedoutException e) {
+            s_logger.warn("Timed Out", e);
+            throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
+        }
+
+        if (answers == null || answers.length != cmds.size()) {
+            return false;
+        }
+
+        // FIXME: Have to return state for individual command in the future
+        boolean result = true;
+        for (final Answer answer : answers) {
+            if (!answer.getResult()) {
+                result = false;
+                break;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void handleSingleWorkingRedundantRouter(final List<? extends VirtualRouter> connectedRouters, final List<? extends VirtualRouter> disconnectedRouters,
+            final String reason) throws ResourceUnavailableException {
+        if (connectedRouters.isEmpty() || disconnectedRouters.isEmpty()) {
+            return;
+        }
+
+        for (final VirtualRouter virtualRouter : connectedRouters) {
+            if (!virtualRouter.getIsRedundantRouter()) {
+                throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId());
+            }
+        }
+
+        for (final VirtualRouter virtualRouter : disconnectedRouters) {
+            if (!virtualRouter.getIsRedundantRouter()) {
+                throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId());
+            }
+        }
+
+        final DomainRouterVO connectedRouter = (DomainRouterVO) connectedRouters.get(0);
+        DomainRouterVO disconnectedRouter = (DomainRouterVO) disconnectedRouters.get(0);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("About to stop the router " + disconnectedRouter.getInstanceName() + " due to: " + reason);
+        }
+        final String title = "Virtual router " + disconnectedRouter.getInstanceName() + " would be stopped after connecting back, due to " + reason;
+        final String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId()
+                + ") would be stopped after connecting back, due to: " + reason;
+        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, disconnectedRouter.getDataCenterId(), disconnectedRouter.getPodIdToDeployIn(), title, context);
+        disconnectedRouter.setStopPending(true);
+        disconnectedRouter = _routerDao.persist(disconnectedRouter);
+    }
+
+    @Override
+    public NicTO getNicTO(final VirtualRouter router, final Long networkId, final String broadcastUri) {
+        final NicProfile nicProfile = _networkModel.getNicProfile(router, networkId, broadcastUri);
+
+        return _itMgr.toNicTO(nicProfile, router.getHypervisorType());
+    }
+
+    @Override
+    public VirtualRouter destroyRouter(final long routerId, final Account caller, final Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Attempting to destroy router " + routerId);
+        }
+
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        if (router == null) {
+            return null;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, router);
+
+        _itMgr.expunge(router.getUuid());
+        _routerDao.remove(router.getId());
+        return router;
+    }
+
+    @Override
+    public boolean checkRouterVersion(final VirtualRouter router) {
+        if (!VirtualNetworkApplianceManagerImpl.routerVersionCheckEnabled.value()) {
+            // Router version check is disabled.
+            return true;
+        }
+        if (router.getTemplateVersion() == null) {
+            return false;
+        }
+        final long dcid = router.getDataCenterId();
+        String routerVersion = CloudStackVersion.trimRouterVersion(router.getTemplateVersion());
+        return CloudStackVersion.compare(routerVersion, NetworkOrchestrationService.MinVRVersion.valueIn(dcid)) >= 0;
+    }
+
+    protected DomainRouterVO start(DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params, final DeploymentPlan planToDeploy)
+            throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+        s_logger.debug("Starting router " + router);
+        try {
+            _itMgr.advanceStart(router.getUuid(), params, planToDeploy, null);
+        } catch (final OperationTimedoutException e) {
+            throw new ResourceUnavailableException("Starting router " + router + " failed! " + e.toString(), DataCenter.class, router.getDataCenterId());
+        }
+        if (router.isStopPending()) {
+            s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after start router successfully!");
+            router.setStopPending(false);
+            router = _routerDao.persist(router);
+        }
+        // We don't want the failure of VPN Connection affect the status of
+        // router, so we try to make connection
+        // only after router start successfully
+        final Long vpcId = router.getVpcId();
+        if (vpcId != null) {
+            _s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId);
+        }
+        return _routerDao.findById(router.getId());
+    }
+
+    protected DomainRouterVO waitRouter(final DomainRouterVO router) {
+        DomainRouterVO vm = _routerDao.findById(router.getId());
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Router " + router.getInstanceName() + " is not fully up yet, we will wait");
+        }
+        while (vm.getState() == State.Starting) {
+            try {
+                Thread.sleep(1000);
+            } catch (final InterruptedException e) {
+            }
+
+            // reload to get the latest state info
+            vm = _routerDao.findById(router.getId());
+        }
+
+        if (vm.getState() == State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Router " + router.getInstanceName() + " is now fully up");
+            }
+
+            return router;
+        }
+
+        s_logger.warn("Router " + router.getInstanceName() + " failed to start. current state: " + vm.getState());
+        return null;
+    }
+
+    @Override
+    public List<DomainRouterVO> startRouters(final RouterDeploymentDefinition routerDeploymentDefinition) throws StorageUnavailableException, InsufficientCapacityException,
+    ConcurrentOperationException, ResourceUnavailableException {
+
+        final List<DomainRouterVO> runningRouters = new ArrayList<DomainRouterVO>();
+
+        for (DomainRouterVO router : routerDeploymentDefinition.getRouters()) {
+            boolean skip = false;
+            final State state = router.getState();
+            if (router.getHostId() != null && state != State.Running) {
+                final HostVO host = _hostDao.findById(router.getHostId());
+                if (host == null || host.getState() != Status.Up) {
+                    skip = true;
+                }
+            }
+            if (!skip) {
+                if (state != State.Running) {
+                    router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams());
+                }
+                if (router != null) {
+                    runningRouters.add(router);
+                }
+            }
+        }
+        return runningRouters;
+    }
+
+    @Override
+    public DomainRouterVO startVirtualRouter(final DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params)
+            throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+
+        if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) {
+            return start(router, user, caller, params, null);
+        }
+
+        if (router.getState() == State.Running) {
+            s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!");
+            return router;
+        }
+
+        //
+        // If another thread has already requested a VR start, there is a
+        // transition period for VR to transit from
+        // Starting to Running, there exist a race conditioning window here
+        // We will wait until VR is up or fail
+        if (router.getState() == State.Starting) {
+            return waitRouter(router);
+        }
+
+        final DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null);
+        DomainRouterVO result = null;
+        assert router.getIsRedundantRouter();
+        final List<Long> networkIds = _routerDao.getRouterNetworks(router.getId());
+
+        DomainRouterVO routerToBeAvoid = null;
+        List<DomainRouterVO> routerList = null;
+        if (networkIds.size() != 0) {
+            routerList = _routerDao.findByNetwork(networkIds.get(0));
+        } else if (router.getVpcId() != null) {
+            routerList = _routerDao.listByVpcId(router.getVpcId());
+        }
+        if (routerList != null) {
+            for (final DomainRouterVO rrouter : routerList) {
+                if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) {
+                    if (routerToBeAvoid != null) {
+                        throw new ResourceUnavailableException("Try to start router " + router.getInstanceName() + "(" + router.getId() + ")"
+                                + ", but there are already two redundant routers with IP " + router.getPublicIpAddress() + ", they are " + rrouter.getInstanceName() + "("
+                                + rrouter.getId() + ") and " + routerToBeAvoid.getInstanceName() + "(" + routerToBeAvoid.getId() + ")", DataCenter.class,
+                                rrouter.getDataCenterId());
+                    }
+                    routerToBeAvoid = rrouter;
+                }
+            }
+        }
+        if (routerToBeAvoid == null) {
+            return start(router, user, caller, params, null);
+        }
+        // We would try best to deploy the router to another place
+        final int retryIndex = 5;
+        final ExcludeList[] avoids = new ExcludeList[5];
+        avoids[0] = new ExcludeList();
+        avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn());
+        avoids[1] = new ExcludeList();
+        avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId());
+        avoids[2] = new ExcludeList();
+        final List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT);
+        if (volumes != null && volumes.size() != 0) {
+            avoids[2].addPool(volumes.get(0).getPoolId());
+        }
+        avoids[2].addHost(routerToBeAvoid.getHostId());
+        avoids[3] = new ExcludeList();
+        avoids[3].addHost(routerToBeAvoid.getHostId());
+        avoids[4] = new ExcludeList();
+
+        for (int i = 0; i < retryIndex; i++) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Try to deploy redundant virtual router:" + router.getHostName() + ", for " + i + " time");
+            }
+            plan.setAvoids(avoids[i]);
+            try {
+                result = start(router, user, caller, params, plan);
+            } catch (final InsufficientServerCapacityException ex) {
+                result = null;
+            }
+            if (result != null) {
+                break;
+            }
+        }
+        return result;
+    }
+
+    protected String retrieveTemplateName(final HypervisorType hType, final long datacenterId) {
+        String templateName = null;
+
+        if (hType == HypervisorType.BareMetal) {
+            final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(HypervisorType.VMware);
+            templateName = hypervisorConfigKey.valueIn(datacenterId);
+        } else {
+            // Returning NULL is fine because the simulator will need it when
+            // being used instead of a real hypervisor.
+            // The hypervisorsMap contains only real hypervisors.
+            final ConfigKey<String> hypervisorConfigKey = hypervisorsMap.get(hType);
+
+            if (hypervisorConfigKey != null) {
+                templateName = hypervisorConfigKey.valueIn(datacenterId);
+            }
+        }
+
+        return templateName;
+    }
+
+    @Override
+    public DomainRouterVO deployRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean startRouter)
+            throws InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException {
+
+        final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
+        final Account owner = routerDeploymentDefinition.getOwner();
+
+        // Router is the network element, we don't know the hypervisor type yet.
+        // Try to allocate the domR twice using diff hypervisors, and when
+        // failed both times, throw the exception up
+        final List<HypervisorType> hypervisors = getHypervisors(routerDeploymentDefinition);
+
+        int allocateRetry = 0;
+        int startRetry = 0;
+        DomainRouterVO router = null;
+        for (final Iterator<HypervisorType> iter = hypervisors.iterator(); iter.hasNext();) {
+            final HypervisorType hType = iter.next();
+            try {
+                final long id = _routerDao.getNextInSequence(Long.class, "id");
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(String.format("Allocating the VR with id=%s in datacenter %s with the hypervisor type %s", id, routerDeploymentDefinition.getDest()
+                            .getDataCenter(), hType));
+                }
+
+                final String templateName = retrieveTemplateName(hType, routerDeploymentDefinition.getDest().getDataCenter().getId());
+                final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName);
+
+                if (template == null) {
+                    s_logger.debug(hType + " won't support system vm, skip it");
+                    continue;
+                }
+
+                final boolean offerHA = routerOffering.isOfferHA();
+
+                // routerDeploymentDefinition.getVpc().getId() ==> do not use
+                // VPC because it is not a VPC offering.
+                final Long vpcId = routerDeploymentDefinition.getVpc() != null ? routerDeploymentDefinition.getVpc().getId() : null;
+
+                long userId = CallContext.current().getCallingUserId();
+                if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
+                    final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
+                    if (!userVOs.isEmpty()) {
+                        userId =  userVOs.get(0).getId();
+                    }
+                }
+
+                router = new DomainRouterVO(id, routerOffering.getId(), routerDeploymentDefinition.getVirtualProvider().getId(), VirtualMachineName.getRouterName(id,
+                        s_vmInstanceName), template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(),
+                        userId, routerDeploymentDefinition.isRedundant(), RedundantState.UNKNOWN, offerHA, false, vpcId);
+
+                router.setDynamicallyScalable(template.isDynamicallyScalable());
+                router.setRole(Role.VIRTUAL_ROUTER);
+                router = _routerDao.persist(router);
+
+                reallocateRouterNetworks(routerDeploymentDefinition, router, template, null);
+                router = _routerDao.findById(router.getId());
+            } catch (final InsufficientCapacityException ex) {
+                if (allocateRetry < 2 && iter.hasNext()) {
+                    s_logger.debug("Failed to allocate the VR with hypervisor type " + hType + ", retrying one more time");
+                    continue;
+                } else {
+                    throw ex;
+                }
+            } finally {
+                allocateRetry++;
+            }
+
+            if (startRouter) {
+                try {
+                    router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams());
+                    break;
+                } catch (final InsufficientCapacityException ex) {
+                    if (startRetry < 2 && iter.hasNext()) {
+                        s_logger.debug("Failed to start the VR  " + router + " with hypervisor type " + hType + ", " + "destroying it and recreating one more time");
+                        // destroy the router
+                        destroyRouter(router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
+                        continue;
+                    } else {
+                        throw ex;
+                    }
+                } finally {
+                    startRetry++;
+                }
+            } else {
+                // return stopped router
+                return router;
+            }
+        }
+
+        return router;
+    }
+
+    protected void filterSupportedHypervisors(final List<HypervisorType> hypervisors) {
+        // For non vpc we keep them all assuming all types in the list are
+        // supported
+    }
+
+    protected String getNoHypervisorsErrMsgDetails() {
+        return "";
+    }
+
+    protected List<HypervisorType> getHypervisors(final RouterDeploymentDefinition routerDeploymentDefinition) throws InsufficientServerCapacityException {
+        final DeployDestination dest = routerDeploymentDefinition.getDest();
+        List<HypervisorType> hypervisors = new ArrayList<HypervisorType>();
+        if (dest.getCluster() != null) {
+            if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) {
+                hypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId()));
+            } else {
+                hypervisors.add(dest.getCluster().getHypervisorType());
+            }
+        } else {
+            final HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId());
+            if (defaults != HypervisorType.None) {
+                hypervisors.add(defaults);
+            } else {
+                // if there is no default hypervisor, get it from the cluster
+                hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, routerDeploymentDefinition.getPlan().getPodId());
+            }
+        }
+
+        filterSupportedHypervisors(hypervisors);
+
+        if (hypervisors.isEmpty()) {
+            if (routerDeploymentDefinition.getPodId() != null) {
+                throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the pod." + getNoHypervisorsErrMsgDetails(), Pod.class,
+                        routerDeploymentDefinition.getPodId());
+            }
+            throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone." + getNoHypervisorsErrMsgDetails(),
+                    DataCenter.class, dest.getDataCenter().getId());
+        }
+        return hypervisors;
+    }
+
+    /*
+     * Ovm won't support any system. So we have to choose a partner cluster in
+     * the same pod to start domain router for us
+     */
+    protected HypervisorType getClusterToStartDomainRouterForOvm(final long podId) {
+        final List<ClusterVO> clusters = _clusterDao.listByPodId(podId);
+        for (final ClusterVO cv : clusters) {
+            if (cv.getHypervisorType() == HypervisorType.Ovm || cv.getHypervisorType() == HypervisorType.BareMetal) {
+                continue;
+            }
+
+            final List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(cv.getId());
+            if (hosts == null || hosts.isEmpty()) {
+                continue;
+            }
+
+            for (final HostVO h : hosts) {
+                if (h.getState() == Status.Up) {
+                    s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router for OVM");
+                    return h.getHypervisorType();
+                }
+            }
+        }
+
+        final String errMsg = new StringBuilder("Cannot find an available cluster in Pod ").append(podId)
+                .append(" to start domain router for Ovm. \n Ovm won't support any system vm including domain router, ")
+                .append("please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod")
+                .append(" with Ovm cluster. And there is at least one host in UP status in that cluster.").toString();
+        throw new CloudRuntimeException(errMsg);
+    }
+
+    protected LinkedHashMap<Network, List<? extends NicProfile>> configureControlNic(final RouterDeploymentDefinition routerDeploymentDefinition) {
+        final LinkedHashMap<Network, List<? extends NicProfile>> controlConfig = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
+
+        s_logger.debug("Adding nic for Virtual Router in Control network ");
+        final List<? extends NetworkOffering> offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
+        final NetworkOffering controlOffering = offerings.get(0);
+        final Network controlNic = _networkMgr.setupNetwork(s_systemAccount, controlOffering, routerDeploymentDefinition.getPlan(), null, null, false).get(0);
+
+        controlConfig.put(controlNic, new ArrayList<NicProfile>());
+
+        return controlConfig;
+    }
+
+    protected LinkedHashMap<Network, List<? extends NicProfile>> configurePublicNic(final RouterDeploymentDefinition routerDeploymentDefinition, final boolean hasGuestNic) {
+        final LinkedHashMap<Network, List<? extends NicProfile>> publicConfig = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
+
+        if (routerDeploymentDefinition.isPublicNetwork()) {
+            s_logger.debug("Adding nic for Virtual Router in Public network ");
+            // if source nat service is supported by the network, get the source
+            // nat ip address
+            final NicProfile defaultNic = new NicProfile();
+            defaultNic.setDefaultNic(true);
+            final PublicIp sourceNatIp = routerDeploymentDefinition.getSourceNatIP();
+            defaultNic.setIPv4Address(sourceNatIp.getAddress().addr());
+            defaultNic.setIPv4Gateway(sourceNatIp.getGateway());
+            defaultNic.setIPv4Netmask(sourceNatIp.getNetmask());
+            defaultNic.setMacAddress(sourceNatIp.getMacAddress());
+            // get broadcast from public network
+            final Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId());
+            if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) {
+                defaultNic.setBroadcastType(BroadcastDomainType.Vxlan);
+                defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
+                defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
+            } else {
+                defaultNic.setBroadcastType(BroadcastDomainType.Vlan);
+                defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag()));
+                defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag()));
+            }
+
+            //If guest nic has already been added we will have 2 devices in the list.
+            if (hasGuestNic) {
+                defaultNic.setDeviceId(2);
+            }
+
+            final NetworkOffering publicOffering = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0);
+            final List<? extends Network> publicNetworks = _networkMgr.setupNetwork(s_systemAccount, publicOffering, routerDeploymentDefinition.getPlan(), null, null, false);
+            final String publicIp = defaultNic.getIPv4Address();
+            // We want to use the identical MAC address for RvR on public
+            // interface if possible
+            final NicVO peerNic = _nicDao.findByIp4AddressAndNetworkId(publicIp, publicNetworks.get(0).getId());
+            if (peerNic != null) {
+                s_logger.info("Use same MAC as previous RvR, the MAC is " + peerNic.getMacAddress());
+                defaultNic.setMacAddress(peerNic.getMacAddress());
+            }
+            publicConfig.put(publicNetworks.get(0), new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+        }
+
+        return publicConfig;
+    }
+
+    @Override
+    public LinkedHashMap<Network, List<? extends NicProfile>> configureDefaultNics(final RouterDeploymentDefinition routerDeploymentDefinition) throws ConcurrentOperationException, InsufficientAddressCapacityException {
+
+        final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
+
+        // 1) Guest Network
+        final LinkedHashMap<Network, List<? extends NicProfile>> guestNic = configureGuestNic(routerDeploymentDefinition);
+        networks.putAll(guestNic);
+
+        // 2) Control network
+        final LinkedHashMap<Network, List<? extends NicProfile>> controlNic = configureControlNic(routerDeploymentDefinition);
+        networks.putAll(controlNic);
+
+        // 3) Public network
+        final LinkedHashMap<Network, List<? extends NicProfile>> publicNic = configurePublicNic(routerDeploymentDefinition, networks.size() > 1);
+        networks.putAll(publicNic);
+
+        return networks;
+    }
+
+    @Override
+    public LinkedHashMap<Network, List<? extends NicProfile>> configureGuestNic(final RouterDeploymentDefinition routerDeploymentDefinition)
+            throws ConcurrentOperationException, InsufficientAddressCapacityException {
+
+        // Form networks
+        final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(3);
+        // 1) Guest network
+        final Network guestNetwork = routerDeploymentDefinition.getGuestNetwork();
+
+        if (guestNetwork != null) {
+            s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork);
+            String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null;
+            if (!routerDeploymentDefinition.isPublicNetwork()) {
+                final Nic placeholder = _networkModel.getPlaceholderNicForRouter(guestNetwork, routerDeploymentDefinition.getPodId());
+                if (guestNetwork.getCidr() != null) {
+                    if (placeholder != null && placeholder.getIPv4Address() != null) {
+                        s_logger.debug("Requesting ipv4 address " + placeholder.getIPv4Address() + " stored in placeholder nic for the network "
+                                + guestNetwork);
+                        defaultNetworkStartIp = placeholder.getIPv4Address();
+                    } else {
+                        final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
+                        if (startIp != null
+                                && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
+                            defaultNetworkStartIp = startIp;
+                        } else if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId()
+                                    + " is already allocated, can't use it for domain router; will get random ip address from the range");
+                        }
+                    }
+                }
+
+                if (guestNetwork.getIp6Cidr() != null) {
+                    if (placeholder != null && placeholder.getIPv6Address() != null) {
+                        s_logger.debug("Requesting ipv6 address " + placeholder.getIPv6Address() + " stored in placeholder nic for the network "
+                                + guestNetwork);
+                        defaultNetworkStartIpv6 = placeholder.getIPv6Address();
+                    } else {
+                        final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
+                        if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
+                            defaultNetworkStartIpv6 = startIpv6;
+                        } else if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId()
+                                    + " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
+                        }
+                    }
+                }
+            }
+
+            final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
+            if (routerDeploymentDefinition.isPublicNetwork()) {
+                if (routerDeploymentDefinition.isRedundant()) {
+                    gatewayNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
+                } else {
+                    gatewayNic.setIPv4Address(guestNetwork.getGateway());
+                }
+                gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri());
+                gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
+                gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri());
+                gatewayNic.setMode(guestNetwork.getMode());
+                final String gatewayCidr = _networkModel.getValidNetworkCidr(guestNetwork);
+                gatewayNic.setIPv4Netmask(NetUtils.getCidrNetmask(gatewayCidr));
+            } else {
+                gatewayNic.setDefaultNic(true);
+            }
+
+            networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(gatewayNic)));
+        }
+        return networks;
+    }
+
+    @Override
+    public void reallocateRouterNetworks(final RouterDeploymentDefinition routerDeploymentDefinition, final VirtualRouter router, final VMTemplateVO template, final HypervisorType hType)
+            throws ConcurrentOperationException, InsufficientCapacityException {
+        final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(routerDeploymentDefinition.getServiceOfferingId());
+
+        final LinkedHashMap<Network, List<? extends NicProfile>> networks = configureDefaultNics(routerDeploymentDefinition);
+
+        _itMgr.allocate(router.getInstanceName(), template, routerOffering, networks, routerDeploymentDefinition.getPlan(), hType);
+    }
+
+    public static void setSystemAccount(final Account systemAccount) {
+        s_systemAccount = systemAccount;
+    }
+
+    public static void setVMInstanceName(final String vmInstanceName) {
+        s_vmInstanceName = vmInstanceName;
+    }
+    @Override
+    public boolean validateHAProxyLBRule(final LoadBalancingRule rule) {
+        final String timeEndChar = "dhms";
+        int haproxy_stats_port = Integer.parseInt(_configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()));
+        if (rule.getSourcePortStart() == haproxy_stats_port) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Can't create LB on port "+ haproxy_stats_port +", haproxy is listening for  LB stats on this port");
+            }
+            return false;
+        }
+
+        for (final LoadBalancingRule.LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) {
+            final List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
+
+            if (LbStickinessMethod.StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+
+            } else if (LbStickinessMethod.StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                String tablesize = "200k"; // optional
+                String expire = "30m"; // optional
+
+                /* overwrite default values with the stick parameters */
+                for (final Pair<String, String> paramKV : paramsList) {
+                    final String key = paramKV.first();
+                    final String value = paramKV.second();
+                    if ("tablesize".equalsIgnoreCase(key)) {
+                        tablesize = value;
+                    }
+                    if ("expire".equalsIgnoreCase(key)) {
+                        expire = value;
+                    }
+                }
+                if (expire != null && !containsOnlyNumbers(expire, timeEndChar)) {
+                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: expire is not in timeformat: " + expire);
+                }
+                if (tablesize != null && !containsOnlyNumbers(tablesize, "kmg")) {
+                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: tablesize is not in size format: " + tablesize);
+
+                }
+            } else if (LbStickinessMethod.StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                String length = null; // optional
+                String holdTime = null; // optional
+
+                for (final Pair<String, String> paramKV : paramsList) {
+                    final String key = paramKV.first();
+                    final String value = paramKV.second();
+                    if ("length".equalsIgnoreCase(key)) {
+                        length = value;
+                    }
+                    if ("holdtime".equalsIgnoreCase(key)) {
+                        holdTime = value;
+                    }
+                }
+
+                if (length != null && !containsOnlyNumbers(length, null)) {
+                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: length is not a number: " + length);
+                }
+                if (holdTime != null && !containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null)) {
+                    throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: holdtime is not in timeformat: " + holdTime);
+                }
+            }
+        }
+        return true;
+    }
+
+    /*
+     * This function detects numbers like 12 ,32h ,42m .. etc,. 1) plain number
+     * like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here last
+     * character is non-digit but from known characters .
+     */
+    private static boolean containsOnlyNumbers(final String str, final String endChar) {
+        if (str == null) {
+            return false;
+        }
+
+        String number = str;
+        if (endChar != null) {
+            boolean matchedEndChar = false;
+            if (str.length() < 2) {
+                return false; // at least one numeric and one char. example:
+            }
+            // 3h
+            final char strEnd = str.toCharArray()[str.length() - 1];
+            for (final char c : endChar.toCharArray()) {
+                if (strEnd == c) {
+                    number = str.substring(0, str.length() - 1);
+                    matchedEndChar = true;
+                    break;
+                }
+            }
+            if (!matchedEndChar) {
+                return false;
+            }
+        }
+        try {
+            Integer.parseInt(number);
+        } catch (final NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/server/src/com/cloud/network/router/NicProfileHelper.java b/server/src/main/java/com/cloud/network/router/NicProfileHelper.java
similarity index 100%
rename from server/src/com/cloud/network/router/NicProfileHelper.java
rename to server/src/main/java/com/cloud/network/router/NicProfileHelper.java
diff --git a/server/src/com/cloud/network/router/NicProfileHelperImpl.java b/server/src/main/java/com/cloud/network/router/NicProfileHelperImpl.java
similarity index 100%
rename from server/src/com/cloud/network/router/NicProfileHelperImpl.java
rename to server/src/main/java/com/cloud/network/router/NicProfileHelperImpl.java
diff --git a/server/src/com/cloud/network/router/RouterControlHelper.java b/server/src/main/java/com/cloud/network/router/RouterControlHelper.java
similarity index 100%
rename from server/src/com/cloud/network/router/RouterControlHelper.java
rename to server/src/main/java/com/cloud/network/router/RouterControlHelper.java
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java
similarity index 100%
rename from server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
rename to server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java
diff --git a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
new file mode 100644
index 0000000..643ccbb
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -0,0 +1,2683 @@
+// 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.network.router;
+
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import org.apache.cloudstack.alert.AlertService;
+import org.apache.cloudstack.alert.AlertService.AlertType;
+import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.network.topology.NetworkTopology;
+import org.apache.cloudstack.network.topology.NetworkTopologyContext;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.cloudstack.utils.usage.UsageUtils;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckRouterAnswer;
+import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetRouterAlertsAnswer;
+import com.cloud.agent.api.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
+import com.cloud.agent.api.routing.GetRouterAlertsCommand;
+import com.cloud.agent.api.routing.IpAliasTO;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetMonitorServiceCommand;
+import com.cloud.agent.api.to.MonitorServiceTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiAsyncJobDispatcher;
+import com.cloud.api.ApiGsonHelper;
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.MonitoringService;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteCustomerGateway;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.SshKeysDistriMonitor;
+import com.cloud.network.VirtualNetworkApplianceService;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.MonitoringServiceDao;
+import com.cloud.network.dao.MonitoringServiceVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.OpRouterMonitorServiceDao;
+import com.cloud.network.dao.OpRouterMonitorServiceVO;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionVO;
+import com.cloud.network.dao.Site2SiteVpnGatewayDao;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.lb.LoadBalancingRule.LbDestination;
+import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
+import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
+import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StaticNatImpl;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.user.UserStatisticsVO;
+import com.cloud.user.UserStatsLogVO;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.user.dao.UserStatsLogDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.MacAddress;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicIpAlias;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineGuru;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachineProfile.Param;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * VirtualNetworkApplianceManagerImpl manages the different types of virtual
+ * network appliances available in the Cloud Stack.
+ */
+public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, VirtualMachineGuru, Listener,
+Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
+    private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class);
+
+    @Inject private EntityManager _entityMgr;
+    @Inject private DataCenterDao _dcDao;
+    @Inject protected VlanDao _vlanDao;
+    @Inject private FirewallRulesDao _rulesDao;
+    @Inject private LoadBalancerDao _loadBalancerDao;
+    @Inject private LoadBalancerVMMapDao _loadBalancerVMMapDao;
+    @Inject protected IPAddressDao _ipAddressDao;
+    @Inject private VMTemplateDao _templateDao;
+    @Inject protected DomainRouterDao _routerDao;
+    @Inject private UserDao _userDao;
+    @Inject protected UserStatisticsDao _userStatsDao;
+    @Inject private HostDao _hostDao;
+    @Inject private ConfigurationDao _configDao;
+    @Inject private HostPodDao _podDao;
+    @Inject private UserStatsLogDao _userStatsLogDao;
+    @Inject protected AgentManager _agentMgr;
+    @Inject private AlertManager _alertMgr;
+    @Inject private AccountManager _accountMgr;
+    @Inject private ConfigurationManager _configMgr;
+    @Inject private ConfigurationServer _configServer;
+    @Inject private ServiceOfferingDao _serviceOfferingDao;
+    @Inject private UserVmDao _userVmDao;
+    @Inject private VMInstanceDao _vmDao;
+    @Inject private NetworkOfferingDao _networkOfferingDao;
+    @Inject private GuestOSDao _guestOSDao;
+    @Inject private NetworkOrchestrationService _networkMgr;
+    @Inject protected NetworkModel _networkModel;
+    @Inject protected VirtualMachineManager _itMgr;
+    @Inject private VpnUserDao _vpnUsersDao;
+    @Inject private RulesManager _rulesMgr;
+    @Inject protected NetworkDao _networkDao;
+    @Inject private LoadBalancingRulesManager _lbMgr;
+    @Inject private PortForwardingRulesDao _pfRulesDao;
+    @Inject protected RemoteAccessVpnDao _vpnDao;
+    @Inject protected NicDao _nicDao;
+    @Inject private NicIpAliasDao _nicIpAliasDao;
+    @Inject private VolumeDao _volumeDao;
+    @Inject private UserVmDetailsDao _vmDetailsDao;
+    @Inject private ClusterDao _clusterDao;
+    @Inject private ResourceManager _resourceMgr;
+    @Inject private PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Inject protected VirtualRouterProviderDao _vrProviderDao;
+    @Inject private ManagementServerHostDao _msHostDao;
+    @Inject private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
+    @Inject private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
+    @Inject private Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
+    @Inject private Site2SiteVpnManager _s2sVpnMgr;
+    @Inject private UserIpv6AddressDao _ipv6Dao;
+    @Inject private NetworkService _networkSvc;
+    @Inject private IpAddressManager _ipAddrMgr;
+    @Inject private ConfigDepot _configDepot;
+    @Inject private MonitoringServiceDao _monitorServiceDao;
+    @Inject private AsyncJobManager _asyncMgr;
+    @Inject protected VpcDao _vpcDao;
+    @Inject protected ApiAsyncJobDispatcher _asyncDispatcher;
+    @Inject private OpRouterMonitorServiceDao _opRouterMonitorServiceDao;
+
+    @Inject protected NetworkTopologyContext _networkTopologyContext;
+
+    @Autowired
+    @Qualifier("networkHelper")
+    protected NetworkHelper _nwHelper;
+
+    @Inject protected RouterControlHelper _routerControlHelper;
+
+    @Inject protected CommandSetupHelper _commandSetupHelper;
+    @Inject protected RouterDeploymentDefinitionBuilder _routerDeploymentManagerBuilder;
+
+    private int _routerRamSize;
+    private int _routerCpuMHz;
+    private String _mgmtCidr;
+
+    private int _routerStatsInterval = 300;
+    private int _routerCheckInterval = 30;
+    private int _rvrStatusUpdatePoolSize = 10;
+    private String _dnsBasicZoneUpdates = "all";
+    private final Set<String> _guestOSNeedGatewayOnNonDefaultNetwork = new HashSet<>();
+
+    private boolean _disableRpFilter = false;
+    private int _routerExtraPublicNics = 2;
+    private int _usageAggregationRange = 1440;
+    private String _usageTimeZone = "GMT";
+    private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds
+    private boolean _dailyOrHourly = false;
+
+    private ScheduledExecutorService _executor;
+    private ScheduledExecutorService _checkExecutor;
+    private ScheduledExecutorService _networkStatsUpdateExecutor;
+    private ExecutorService _rvrStatusUpdateExecutor;
+
+    private BlockingQueue<Long> _vrUpdateQueue;
+
+    @Override
+    public VirtualRouter destroyRouter(final long routerId, final Account caller, final Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
+        return _nwHelper.destroyRouter(routerId, caller, callerUserId);
+    }
+
+    @Override
+    @DB
+    public VirtualRouter upgradeRouter(final UpgradeRouterCmd cmd) {
+        final Long routerId = cmd.getId();
+        final Long serviceOfferingId = cmd.getServiceOfferingId();
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        if (router == null) {
+            throw new InvalidParameterValueException("Unable to find router with id " + routerId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, router);
+
+        if (router.getServiceOfferingId() == serviceOfferingId) {
+            s_logger.debug("Router: " + routerId + "already has service offering: " + serviceOfferingId);
+            return _routerDao.findById(routerId);
+        }
+
+        final ServiceOffering newServiceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (newServiceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering with id " + serviceOfferingId);
+        }
+
+        // check if it is a system service offering, if yes return with error as
+        // it cannot be used for user vms
+        if (!newServiceOffering.isSystemUse()) {
+            throw new InvalidParameterValueException("Cannot upgrade router vm to a non system service offering " + serviceOfferingId);
+        }
+
+        // Check that the router is stopped
+        if (!router.getState().equals(VirtualMachine.State.Stopped)) {
+            s_logger.warn("Unable to upgrade router " + router.toString() + " in state " + router.getState());
+            throw new InvalidParameterValueException("Unable to upgrade router " + router.toString() + " in state " + router.getState()
+                    + "; make sure the router is stopped and not in an error state before upgrading.");
+        }
+
+        final ServiceOfferingVO currentServiceOffering = _serviceOfferingDao.findById(router.getServiceOfferingId());
+
+        // Check that the service offering being upgraded to has the same
+        // storage pool preference as the VM's current service
+        // offering
+        if (currentServiceOffering.isUseLocalStorage() != newServiceOffering.isUseLocalStorage()) {
+            throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.isUseLocalStorage() + " is different from "
+                    + "curruent local storage status: " + currentServiceOffering.isUseLocalStorage());
+        }
+
+        router.setServiceOfferingId(serviceOfferingId);
+        if (_routerDao.update(routerId, router)) {
+            return _routerDao.findById(routerId);
+        } else {
+            throw new CloudRuntimeException("Unable to upgrade router " + routerId);
+        }
+
+    }
+
+    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true)
+    @Override
+    public VirtualRouter stopRouter(final long routerId, final boolean forced) throws ResourceUnavailableException, ConcurrentOperationException {
+        final CallContext context = CallContext.current();
+        final Account account = context.getCallingAccount();
+
+        // verify parameters
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        if (router == null) {
+            throw new InvalidParameterValueException("Unable to find router by id " + routerId + ".");
+        }
+
+        _accountMgr.checkAccess(account, null, true, router);
+
+        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
+
+        final VirtualRouter virtualRouter = stop(router, forced, user, account);
+        if (virtualRouter == null) {
+            throw new CloudRuntimeException("Failed to stop router with id " + routerId);
+        }
+
+        // Clear stop pending flag after stopped successfully
+        if (router.isStopPending()) {
+            s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after stop router successfully");
+            router.setStopPending(false);
+            _routerDao.persist(router);
+            virtualRouter.setStopPending(false);
+        }
+        return virtualRouter;
+    }
+
+    @DB
+    public void processStopOrRebootAnswer(final DomainRouterVO router, final Answer answer) {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                // FIXME!!! - UserStats command should grab bytesSent/Received
+                // for all guest interfaces of the VR
+                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
+                for (final Long guestNtwkId : routerGuestNtwkIds) {
+                    final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), guestNtwkId, null, router.getId(), router.getType()
+                            .toString());
+                    if (userStats != null) {
+                        final long currentBytesRcvd = userStats.getCurrentBytesReceived();
+                        userStats.setCurrentBytesReceived(0);
+                        userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd);
+
+                        final long currentBytesSent = userStats.getCurrentBytesSent();
+                        userStats.setCurrentBytesSent(0);
+                        userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent);
+                        _userStatsDao.update(userStats.getId(), userStats);
+                        s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop");
+                    } else {
+                        s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterId());
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true)
+    public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        // verify parameters
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        if (router == null) {
+            throw new InvalidParameterValueException("Unable to find domain router with id " + routerId + ".");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, router);
+
+        // Can reboot domain router only in Running state
+        if (router == null || router.getState() != VirtualMachine.State.Running) {
+            s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState());
+            throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterId());
+        }
+
+        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
+        s_logger.debug("Stopping and starting router " + router + " as a part of router reboot");
+
+        if (stop(router, false, user, caller) != null) {
+            return startRouter(routerId, reprogramNetwork);
+        } else {
+            throw new CloudRuntimeException("Failed to reboot router " + router);
+        }
+    }
+
+    static final ConfigKey<Boolean> UseExternalDnsServers = new ConfigKey<Boolean>(Boolean.class, "use.external.dns", "Advanced", "false",
+            "Bypass internal dns, use external dns1 and dns2", true, ConfigKey.Scope.Zone, null);
+
+    static final ConfigKey<Boolean> routerVersionCheckEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "router.version.check", "true",
+            "If true, router minimum required version is checked before sending command", false);
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+
+        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterMonitor"));
+        _checkExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterStatusMonitor"));
+        _networkStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NetworkStatsUpdater"));
+
+        VirtualMachine.State.getStateMachine().registerListener(this);
+
+        final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
+
+        _routerRamSize = NumbersUtil.parseInt(configs.get("router.ram.size"), DEFAULT_ROUTER_VM_RAMSIZE);
+        _routerCpuMHz = NumbersUtil.parseInt(configs.get("router.cpu.mhz"), DEFAULT_ROUTER_CPU_MHZ);
+
+        _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
+
+        final String guestOSString = configs.get("network.dhcp.nondefaultnetwork.setgateway.guestos");
+        if (guestOSString != null) {
+            final String[] guestOSList = guestOSString.split(",");
+            for (final String os : guestOSList) {
+                _guestOSNeedGatewayOnNonDefaultNetwork.add(os);
+            }
+        }
+
+        String value = configs.get("router.stats.interval");
+        _routerStatsInterval = NumbersUtil.parseInt(value, 300);
+
+        value = configs.get("router.check.interval");
+        _routerCheckInterval = NumbersUtil.parseInt(value, 30);
+
+        value = configs.get("router.check.poolsize");
+        _rvrStatusUpdatePoolSize = NumbersUtil.parseInt(value, 10);
+
+        /*
+         * We assume that one thread can handle 20 requests in 1 minute in
+         * normal situation, so here we give the queue size up to 50 minutes.
+         * It's mostly for buffer, since each time CheckRouterTask running, it
+         * would add all the redundant networks in the queue immediately
+         */
+        _vrUpdateQueue = new LinkedBlockingQueue<Long>(_rvrStatusUpdatePoolSize * 1000);
+
+        _rvrStatusUpdateExecutor = Executors.newFixedThreadPool(_rvrStatusUpdatePoolSize, new NamedThreadFactory("RedundantRouterStatusMonitor"));
+
+        String instance = configs.get("instance.name");
+        if (instance == null) {
+            instance = "DEFAULT";
+        }
+
+        NetworkHelperImpl.setVMInstanceName(instance);
+
+        final String rpValue = configs.get("network.disable.rpfilter");
+        if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
+            _disableRpFilter = true;
+        }
+
+        _dnsBasicZoneUpdates = String.valueOf(_configDao.getValue(Config.DnsBasicZoneUpdates.key()));
+
+        s_logger.info("Router configurations: " + "ramsize=" + _routerRamSize);
+
+        _agentMgr.registerForHostEvents(new SshKeysDistriMonitor(_agentMgr, _hostDao, _configDao), true, false, false);
+
+        final List<ServiceOfferingVO> offerings = _serviceOfferingDao.createSystemServiceOfferings("System Offering For Software Router",
+                ServiceOffering.routerDefaultOffUniqueName, 1, _routerRamSize, _routerCpuMHz, null,
+                null, true, null, ProvisioningType.THIN, true, null, true, VirtualMachine.Type.DomainRouter, true);
+        // this can sometimes happen, if DB is manually or programmatically manipulated
+        if (offerings == null || offerings.size() < 2) {
+            final String msg = "Data integrity problem : System Offering For Software router VM has been removed?";
+            s_logger.error(msg);
+            throw new ConfigurationException(msg);
+        }
+
+        NetworkHelperImpl.setSystemAccount(_accountMgr.getSystemAccount());
+
+        final String aggregationRange = configs.get("usage.stats.job.aggregation.range");
+        _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
+        _usageTimeZone = configs.get("usage.aggregation.timezone");
+        if (_usageTimeZone == null) {
+            _usageTimeZone = "GMT";
+        }
+
+        _agentMgr.registerForHostEvents(this, true, false, false);
+
+        s_logger.info("DomainRouterManager is configured.");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        if (_routerStatsInterval > 0) {
+            _executor.scheduleAtFixedRate(new NetworkUsageTask(), _routerStatsInterval, _routerStatsInterval, TimeUnit.SECONDS);
+        } else {
+            s_logger.debug("router.stats.interval - " + _routerStatsInterval + " so not scheduling the router stats thread");
+        }
+
+        //Schedule Network stats update task
+        //Network stats aggregation should align with aggregation range
+        //For daily aggregation, update stats at the end of the day
+        //For hourly aggregation, update stats at the end of the hour
+        final TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone);
+        final Calendar cal = Calendar.getInstance(usageTimezone);
+        cal.setTime(new Date());
+        //aggDate is the time in millis when the aggregation should happen
+        long aggDate = 0;
+        final int HOURLY_TIME = 60;
+        final int DAILY_TIME = 60 * 24;
+        if (_usageAggregationRange == DAILY_TIME) {
+            cal.set(Calendar.HOUR_OF_DAY, 0);
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            cal.roll(Calendar.DAY_OF_YEAR, true);
+            cal.add(Calendar.MILLISECOND, -1);
+            aggDate = cal.getTime().getTime();
+            _dailyOrHourly = true;
+        } else if (_usageAggregationRange == HOURLY_TIME) {
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            cal.roll(Calendar.HOUR_OF_DAY, true);
+            cal.add(Calendar.MILLISECOND, -1);
+            aggDate = cal.getTime().getTime();
+            _dailyOrHourly = true;
+        } else {
+            aggDate = cal.getTime().getTime();
+            _dailyOrHourly = false;
+        }
+
+        if (_usageAggregationRange < UsageUtils.USAGE_AGGREGATION_RANGE_MIN) {
+            s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + UsageUtils.USAGE_AGGREGATION_RANGE_MIN);
+            _usageAggregationRange = UsageUtils.USAGE_AGGREGATION_RANGE_MIN;
+        }
+
+        // We cannot schedule a job at specific time. Provide initial delay instead, from current time, so that the job runs at desired time
+        final long initialDelay = aggDate - System.currentTimeMillis();
+
+        if( initialDelay < 0){
+            s_logger.warn("Initial delay for network usage stats update task is incorrect. Stats update task will run immediately");
+        }
+
+        _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), initialDelay, _usageAggregationRange * 60 * 1000,
+                TimeUnit.MILLISECONDS);
+
+        if (_routerCheckInterval > 0) {
+            _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS);
+            for (int i = 0; i < _rvrStatusUpdatePoolSize; i++) {
+                _rvrStatusUpdateExecutor.execute(new RvRStatusUpdateTask());
+            }
+        } else {
+            s_logger.debug("router.check.interval - " + _routerCheckInterval + " so not scheduling the redundant router checking thread");
+        }
+
+        final int routerAlertsCheckInterval = RouterAlertsCheckInterval.value();
+        if (routerAlertsCheckInterval > 0) {
+            _checkExecutor.scheduleAtFixedRate(new CheckRouterAlertsTask(), routerAlertsCheckInterval, routerAlertsCheckInterval, TimeUnit.SECONDS);
+        } else {
+            s_logger.debug("router.alerts.check.interval - " + routerAlertsCheckInterval + " so not scheduling the router alerts checking thread");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    protected VirtualNetworkApplianceManagerImpl() {
+    }
+
+    protected class NetworkUsageTask extends ManagedContextRunnable {
+
+        public NetworkUsageTask() {
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                final List<DomainRouterVO> routers = _routerDao.listByStateAndNetworkType(VirtualMachine.State.Running, GuestType.Isolated, mgmtSrvrId);
+                s_logger.debug("Found " + routers.size() + " running routers. ");
+
+                for (final DomainRouterVO router : routers) {
+                    final String privateIP = router.getPrivateIpAddress();
+
+                    if (privateIP != null) {
+                        final boolean forVpc = router.getVpcId() != null;
+                        final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
+                        for (final Nic routerNic : routerNics) {
+                            final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
+                            // Send network usage command for public nic in VPC VR
+                            // Send network usage command for isolated guest nic of non) VPC VR
+
+                            //[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues
+                            if (network == null) {
+                                s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!");
+                                continue;
+                            }
+                            if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
+                                    && network.getGuestType() == Network.GuestType.Isolated) {
+                                final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());
+                                final String routerType = router.getType().toString();
+                                final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(),
+                                        forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
+                                NetworkUsageAnswer answer = null;
+                                try {
+                                    answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
+                                } catch (final Exception e) {
+                                    s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e);
+                                    continue;
+                                }
+
+                                if (answer != null) {
+                                    if (!answer.getResult()) {
+                                        s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId()
+                                                + "; details: " + answer.getDetails());
+                                        continue;
+                                    }
+                                    try {
+                                        if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) {
+                                            s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
+                                            continue;
+                                        }
+                                        final NetworkUsageAnswer answerFinal = answer;
+                                        Transaction.execute(new TransactionCallbackNoReturn() {
+                                            @Override
+                                            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                                                final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(),
+                                                        forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
+                                                if (stats == null) {
+                                                    s_logger.warn("unable to find stats for account: " + router.getAccountId());
+                                                    return;
+                                                }
+
+                                                if (previousStats != null
+                                                        && (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats
+                                                        .getCurrentBytesSent())) {
+                                                    s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: "
+                                                            + answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent());
+                                                    return;
+                                                }
+
+                                                if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) {
+                                                    if (s_logger.isDebugEnabled()) {
+                                                        s_logger.debug("Received # of bytes that's less than the last one.  "
+                                                                + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
+                                                                + answerFinal.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived());
+                                                    }
+                                                    stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
+                                                }
+                                                stats.setCurrentBytesReceived(answerFinal.getBytesReceived());
+                                                if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) {
+                                                    if (s_logger.isDebugEnabled()) {
+                                                        s_logger.debug("Received # of bytes that's less than the last one.  "
+                                                                + "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
+                                                                + answerFinal.getBytesSent() + " Stored: " + stats.getCurrentBytesSent());
+                                                    }
+                                                    stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
+                                                }
+                                                stats.setCurrentBytesSent(answerFinal.getBytesSent());
+                                                if (!_dailyOrHourly) {
+                                                    // update agg bytes
+                                                    stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
+                                                    stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
+                                                }
+                                                _userStatsDao.update(stats.getId(), stats);
+                                            }
+                                        });
+
+                                    } catch (final Exception e) {
+                                        s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: "
+                                                + answer.getBytesSent());
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (final Exception e) {
+                s_logger.warn("Error while collecting network stats", e);
+            }
+        }
+    }
+
+    protected class NetworkStatsUpdateTask extends ManagedContextRunnable {
+
+        public NetworkStatsUpdateTask() {
+        }
+
+        @Override
+        protected void runInContext() {
+            final GlobalLock scanLock = GlobalLock.getInternLock("network.stats");
+            try {
+                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                    // Check for ownership
+                    // msHost in UP state with min id should run the job
+                    final ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", false, 0L, 1L));
+                    if (msHost == null || msHost.getMsid() != mgmtSrvrId) {
+                        s_logger.debug("Skipping aggregate network stats update");
+                        scanLock.unlock();
+                        return;
+                    }
+                    try {
+                        Transaction.execute(new TransactionCallbackNoReturn() {
+                            @Override
+                            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                                // get all stats with delta > 0
+                                final List<UserStatisticsVO> updatedStats = _userStatsDao.listUpdatedStats();
+                                final Date updatedTime = new Date();
+                                for (final UserStatisticsVO stat : updatedStats) {
+                                    // update agg bytes
+                                    stat.setAggBytesReceived(stat.getCurrentBytesReceived() + stat.getNetBytesReceived());
+                                    stat.setAggBytesSent(stat.getCurrentBytesSent() + stat.getNetBytesSent());
+                                    _userStatsDao.update(stat.getId(), stat);
+                                    // insert into op_user_stats_log
+                                    final UserStatsLogVO statsLog = new UserStatsLogVO(stat.getId(), stat.getNetBytesReceived(), stat.getNetBytesSent(), stat
+                                            .getCurrentBytesReceived(), stat.getCurrentBytesSent(), stat.getAggBytesReceived(), stat.getAggBytesSent(), updatedTime);
+                                    _userStatsLogDao.persist(statsLog);
+                                }
+                                s_logger.debug("Successfully updated aggregate network stats");
+                            }
+                        });
+                    } catch (final Exception e) {
+                        s_logger.debug("Failed to update aggregate network stats", e);
+                    } finally {
+                        scanLock.unlock();
+                    }
+                }
+            } catch (final Exception e) {
+                s_logger.debug("Exception while trying to acquire network stats lock", e);
+            } finally {
+                scanLock.releaseRef();
+            }
+        }
+    }
+
+    @DB
+    protected void updateSite2SiteVpnConnectionState(final List<DomainRouterVO> routers) {
+        for (final DomainRouterVO router : routers) {
+            final List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
+            if (conns == null || conns.isEmpty()) {
+                continue;
+            }
+            if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER){
+                continue;
+            }
+            if (router.getState() != VirtualMachine.State.Running) {
+                for (final Site2SiteVpnConnectionVO conn : conns) {
+                    if (conn.getState() != Site2SiteVpnConnection.State.Error) {
+                        conn.setState(Site2SiteVpnConnection.State.Disconnected);
+                        _s2sVpnConnectionDao.persist(conn);
+                    }
+                }
+                continue;
+            }
+            final List<String> ipList = new ArrayList<String>();
+            for (final Site2SiteVpnConnectionVO conn : conns) {
+                if (conn.getState() != Site2SiteVpnConnection.State.Connected && conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
+                    continue;
+                }
+                final Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+                ipList.add(gw.getGatewayIp());
+            }
+            final String privateIP = router.getPrivateIpAddress();
+            final HostVO host = _hostDao.findById(router.getHostId());
+            if (host == null || host.getState() != Status.Up) {
+                continue;
+            } else if (host.getManagementServerId() != ManagementServerNode.getManagementServerId()) {
+                /* Only cover hosts managed by this management server */
+                continue;
+            } else if (privateIP != null) {
+                final CheckS2SVpnConnectionsCommand command = new CheckS2SVpnConnectionsCommand(ipList);
+                command.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+                command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+                command.setWait(30);
+                final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
+                CheckS2SVpnConnectionsAnswer answer = null;
+                if (origAnswer instanceof CheckS2SVpnConnectionsAnswer) {
+                    answer = (CheckS2SVpnConnectionsAnswer) origAnswer;
+                } else {
+                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
+                    continue;
+                }
+                if (!answer.getResult()) {
+                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
+                    continue;
+                }
+                for (final Site2SiteVpnConnectionVO conn : conns) {
+                    final Site2SiteVpnConnectionVO lock = _s2sVpnConnectionDao.acquireInLockTable(conn.getId());
+                    if (lock == null) {
+                        throw new CloudRuntimeException("Unable to acquire lock for site to site vpn connection id " + conn.getId());
+                    }
+                    try {
+                        if (conn.getState() != Site2SiteVpnConnection.State.Connected && conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
+                            continue;
+                        }
+                        final Site2SiteVpnConnection.State oldState = conn.getState();
+                        final Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+
+                        if (answer.isIPPresent(gw.getGatewayIp())) {
+                            if (answer.isConnected(gw.getGatewayIp())) {
+                                conn.setState(Site2SiteVpnConnection.State.Connected);
+                            } else {
+                                conn.setState(Site2SiteVpnConnection.State.Disconnected);
+                            }
+                            _s2sVpnConnectionDao.persist(conn);
+                            if (oldState != conn.getState()) {
+                                final String title = "Site-to-site Vpn Connection to " + gw.getName() + " just switched from " + oldState + " to " + conn.getState();
+                                final String context =
+                                        "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() + "(id: " + router.getId() + ") " +
+                                                " just switched from " + oldState + " to " + conn.getState();
+                                s_logger.info(context);
+                                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
+                            }
+                        }
+                    } finally {
+                        _s2sVpnConnectionDao.releaseFromLockTable(lock.getId());
+                    }
+                }
+            }
+        }
+    }
+
+    protected void updateRoutersRedundantState(final List<DomainRouterVO> routers) {
+        boolean updated;
+        for (final DomainRouterVO router : routers) {
+            updated = false;
+            if (!router.getIsRedundantRouter()) {
+                continue;
+            }
+            final RedundantState prevState = router.getRedundantState();
+            if (router.getState() != VirtualMachine.State.Running) {
+                router.setRedundantState(RedundantState.UNKNOWN);
+                updated = true;
+            } else {
+                final String privateIP = router.getPrivateIpAddress();
+                final HostVO host = _hostDao.findById(router.getHostId());
+                if (host == null || host.getState() != Status.Up) {
+                    router.setRedundantState(RedundantState.UNKNOWN);
+                    updated = true;
+                } else if (privateIP != null) {
+                    final CheckRouterCommand command = new CheckRouterCommand();
+                    command.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
+                    command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+                    command.setWait(30);
+                    final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
+                    CheckRouterAnswer answer = null;
+                    if (origAnswer instanceof CheckRouterAnswer) {
+                        answer = (CheckRouterAnswer) origAnswer;
+                    } else {
+                        s_logger.warn("Unable to update router " + router.getHostName() + "'s status");
+                    }
+                    RedundantState state = RedundantState.UNKNOWN;
+                    if (answer != null) {
+                        if (answer.getResult()) {
+                            state = answer.getState();
+                        } else {
+                            s_logger.info("Agent response doesn't seem to be correct ==> " + answer.getResult());
+                        }
+                    }
+                    router.setRedundantState(state);
+                    updated = true;
+                }
+            }
+            if (updated) {
+                _routerDao.update(router.getId(), router);
+            }
+            final RedundantState currState = router.getRedundantState();
+            if (prevState != currState) {
+                final String title = "Redundant virtual router " + router.getInstanceName() + " just switch from " + prevState + " to " + currState;
+                final String context = "Redundant virtual router (name: " + router.getHostName() + ", id: " + router.getId() + ") " + " just switch from " + prevState + " to "
+                        + currState;
+                s_logger.info(context);
+                if (currState == RedundantState.MASTER) {
+                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
+                }
+            }
+        }
+    }
+
+    // Ensure router status is update to date before execute this function. The
+    // function would try best to recover all routers except MASTER
+    protected void recoverRedundantNetwork(final DomainRouterVO masterRouter, final DomainRouterVO backupRouter) {
+        if (masterRouter.getState() == VirtualMachine.State.Running && backupRouter.getState() == VirtualMachine.State.Running) {
+            final HostVO masterHost = _hostDao.findById(masterRouter.getHostId());
+            final HostVO backupHost = _hostDao.findById(backupRouter.getHostId());
+            if (masterHost.getState() == Status.Up && backupHost.getState() == Status.Up) {
+                final String title = "Reboot " + backupRouter.getInstanceName() + " to ensure redundant virtual routers work";
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(title);
+                }
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, backupRouter.getDataCenterId(), backupRouter.getPodIdToDeployIn(), title, title);
+                try {
+                    rebootRouter(backupRouter.getId(), true);
+                } catch (final ConcurrentOperationException e) {
+                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
+                } catch (final ResourceUnavailableException e) {
+                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
+                } catch (final InsufficientCapacityException e) {
+                    s_logger.warn("Fail to reboot " + backupRouter.getInstanceName(), e);
+                }
+            }
+        }
+    }
+
+    protected class RvRStatusUpdateTask extends ManagedContextRunnable {
+
+        /*
+         * In order to make fail-over works well at any time, we have to ensure:
+         * 1. Backup router's priority = Master's priority - DELTA + 1
+         */
+        private void checkSanity(final List<DomainRouterVO> routers) {
+            final Set<Long> checkedNetwork = new HashSet<Long>();
+            for (final DomainRouterVO router : routers) {
+                if (!router.getIsRedundantRouter()) {
+                    continue;
+                }
+
+                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
+
+                for (final Long routerGuestNtwkId : routerGuestNtwkIds) {
+                    if (checkedNetwork.contains(routerGuestNtwkId)) {
+                        continue;
+                    }
+                    checkedNetwork.add(routerGuestNtwkId);
+
+                    final List<DomainRouterVO> checkingRouters;
+                    final Long vpcId = router.getVpcId();
+                    if (vpcId != null) {
+                        checkingRouters = _routerDao.listByVpcId(vpcId);
+                    } else {
+                        checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER);
+                    }
+
+                    if (checkingRouters.size() != 2) {
+                        continue;
+                    }
+
+                    DomainRouterVO masterRouter = null;
+                    DomainRouterVO backupRouter = null;
+                    for (final DomainRouterVO r : checkingRouters) {
+                        if (r.getRedundantState() == RedundantState.MASTER) {
+                            if (masterRouter == null) {
+                                masterRouter = r;
+                            } else {
+                                // Wilder Rodrigues (wrodrigues@schubergphilis.com
+                                // Force a restart in order to fix the conflict
+                                // recoverRedundantNetwork(masterRouter, r);
+                                break;
+                            }
+                        } else if (r.getRedundantState() == RedundantState.BACKUP) {
+                            if (backupRouter == null) {
+                                backupRouter = r;
+                            } else {
+                                // Wilder Rodrigues (wrodrigues@schubergphilis.com
+                                // Do we have 2 routers in Backup state? Perhaps a restart of 1 router is needed.
+                                // recoverRedundantNetwork(backupRouter, r);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        private void checkDuplicateMaster(final List<DomainRouterVO> routers) {
+            final Map<Long, DomainRouterVO> networkRouterMaps = new HashMap<Long, DomainRouterVO>();
+            for (final DomainRouterVO router : routers) {
+                final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
+
+                for (final Long routerGuestNtwkId : routerGuestNtwkIds) {
+                    if (router.getRedundantState() == RedundantState.MASTER) {
+                        if (networkRouterMaps.containsKey(routerGuestNtwkId)) {
+                            final DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId);
+                            final String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router "
+                                    + dupRouter.getHostName();
+                            final String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + dupRouter.getHostName()
+                                    + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. ";
+                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), title, context);
+                            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterId(), dupRouter.getPodIdToDeployIn(), title, context);
+                            s_logger.warn(context);
+                        } else {
+                            networkRouterMaps.put(routerGuestNtwkId, router);
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        protected void runInContext() {
+            while (true) {
+                try {
+                    final Long networkId = _vrUpdateQueue.take(); // This is a blocking call so this thread won't run all the time if no work item in queue.
+
+                    final NetworkVO network = _networkDao.findById(networkId);
+                    final Long vpcId = network.getVpcId();
+
+                    final List<DomainRouterVO> routers;
+                    if (vpcId != null) {
+                        routers = _routerDao.listByVpcId(vpcId);
+                    } else {
+                        routers = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER);
+                    }
+
+                    if (routers.size() != 2) {
+                        continue;
+                    }
+                    /*
+                     * We update the router pair which the lower id router owned
+                     * by this mgmt server, in order to prevent duplicate update
+                     * of router status from cluster mgmt servers
+                     */
+                    final DomainRouterVO router0 = routers.get(0);
+                    final DomainRouterVO router1 = routers.get(1);
+
+                    if (router0.getState() != VirtualMachine.State.Running || router1.getState() != VirtualMachine.State.Running) {
+                        updateRoutersRedundantState(routers);
+                        // Wilder Rodrigues (wrodrigues@schubergphilis.com) - One of the routers is not running,
+                        // so we don't have to continue here since the host will be null any way. Also, there is no need
+                        // To check either for sanity of duplicate master. Thus, just update the state and get lost.
+                        continue;
+                    }
+
+                    DomainRouterVO router = router0;
+                    if (router0.getId() < router1.getId()) {
+                        router = router0;
+                    } else {
+                        router = router1;
+                    }
+                    // && router.getState() == VirtualMachine.State.Stopped
+                    if (router.getHostId() == null && router.getState() == VirtualMachine.State.Running) {
+                        s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to can't find host");
+                        continue;
+                    }
+                    final HostVO host = _hostDao.findById(router.getHostId());
+                    if (host == null || host.getManagementServerId() == null || host.getManagementServerId() != ManagementServerNode.getManagementServerId()) {
+                        s_logger.debug("Skip router pair (" + router0.getInstanceName() + "," + router1.getInstanceName() + ") due to not belong to this mgmt server");
+                        continue;
+                    }
+                    updateRoutersRedundantState(routers);
+                    checkDuplicateMaster(routers);
+                    checkSanity(routers);
+                } catch (final Exception ex) {
+                    s_logger.error("Fail to complete the RvRStatusUpdateTask! ", ex);
+                }
+            }
+        }
+    }
+
+    protected class CheckRouterTask extends ManagedContextRunnable {
+
+        public CheckRouterTask() {
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(null);
+                s_logger.debug("Found " + routers.size() + " routers to update status. ");
+
+                updateSite2SiteVpnConnectionState(routers);
+
+                List<NetworkVO> networks = _networkDao.listVpcNetworks();
+                s_logger.debug("Found " + networks.size() + " VPC networks to update Redundant State. ");
+                pushToUpdateQueue(networks);
+
+                networks = _networkDao.listRedundantNetworks();
+                s_logger.debug("Found " + networks.size() + " networks to update RvR status. ");
+                pushToUpdateQueue(networks);
+            } catch (final Exception ex) {
+                s_logger.error("Fail to complete the CheckRouterTask! ", ex);
+            }
+        }
+
+        protected void pushToUpdateQueue(final List<NetworkVO> networks) throws InterruptedException {
+            for (final NetworkVO network : networks) {
+                if (!_vrUpdateQueue.offer(network.getId(), 500, TimeUnit.MILLISECONDS)) {
+                    s_logger.warn("Cannot insert into virtual router update queue! Adjustment of router.check.interval and router.check.poolsize maybe needed.");
+                    break;
+                }
+            }
+        }
+    }
+
+    protected class CheckRouterAlertsTask extends ManagedContextRunnable {
+        public CheckRouterAlertsTask() {
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                getRouterAlerts();
+            } catch (final Exception ex) {
+                s_logger.error("Fail to complete the CheckRouterAlertsTask! ", ex);
+            }
+        }
+    }
+
+    protected void getRouterAlerts() {
+        try {
+            final List<DomainRouterVO> routers = _routerDao.listByStateAndManagementServer(VirtualMachine.State.Running, mgmtSrvrId);
+
+            s_logger.debug("Found " + routers.size() + " running routers. ");
+
+            for (final DomainRouterVO router : routers) {
+                final String serviceMonitoringFlag = SetServiceMonitor.valueIn(router.getDataCenterId());
+                // Skip the routers in VPC network or skip the routers where
+                // Monitor service is not enabled in the corresponding Zone
+                if (!Boolean.parseBoolean(serviceMonitoringFlag) || router.getVpcId() != null) {
+                    continue;
+                }
+                String controlIP = getRouterControlIP(router);
+
+                if (controlIP != null && !controlIP.equals("0.0.0.0")) {
+                    OpRouterMonitorServiceVO opRouterMonitorServiceVO = _opRouterMonitorServiceDao.findById(router.getId());
+
+                    GetRouterAlertsCommand command = null;
+                    if (opRouterMonitorServiceVO == null) {
+                        command = new GetRouterAlertsCommand(new String("1970-01-01 00:00:00")); // To
+                        // avoid
+                        // sending
+                        // null
+                        // value
+                    } else {
+                        command = new GetRouterAlertsCommand(opRouterMonitorServiceVO.getLastAlertTimestamp());
+                    }
+
+                    command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlIP);
+
+                    try {
+                        final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
+                        GetRouterAlertsAnswer answer = null;
+
+                        if (origAnswer == null) {
+                            s_logger.warn("Unable to get alerts from router " + router.getHostName());
+                            continue;
+                        }
+                        if (origAnswer instanceof GetRouterAlertsAnswer) {
+                            answer = (GetRouterAlertsAnswer) origAnswer;
+                        } else {
+                            s_logger.warn("Unable to get alerts from router " + router.getHostName());
+                            continue;
+                        }
+                        if (!answer.getResult()) {
+                            s_logger.warn("Unable to get alerts from router " + router.getHostName() + " " + answer.getDetails());
+                            continue;
+                        }
+
+                        final String alerts[] = answer.getAlerts();
+                        if (alerts != null) {
+                            final String lastAlertTimeStamp = answer.getTimeStamp();
+                            final SimpleDateFormat sdfrmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+                            sdfrmt.setLenient(false);
+                            try {
+                                sdfrmt.parse(lastAlertTimeStamp);
+                            } catch (final ParseException e) {
+                                s_logger.warn("Invalid last alert timestamp received while collecting alerts from router: " + router.getInstanceName());
+                                continue;
+                            }
+                            for (final String alert : alerts) {
+                                _alertMgr.sendAlert(AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), "Monitoring Service on VR "
+                                        + router.getInstanceName(), alert);
+                            }
+                            if (opRouterMonitorServiceVO == null) {
+                                opRouterMonitorServiceVO = new OpRouterMonitorServiceVO(router.getId(), router.getHostName(), lastAlertTimeStamp);
+                                _opRouterMonitorServiceDao.persist(opRouterMonitorServiceVO);
+                            } else {
+                                opRouterMonitorServiceVO.setLastAlertTimestamp(lastAlertTimeStamp);
+                                _opRouterMonitorServiceDao.update(opRouterMonitorServiceVO.getId(), opRouterMonitorServiceVO);
+                            }
+                        }
+                    } catch (final Exception e) {
+                        s_logger.warn("Error while collecting alerts from router: " + router.getInstanceName(), e);
+                        continue;
+                    }
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.warn("Error while collecting alerts from router", e);
+        }
+    }
+
+    private String getRouterControlIP(DomainRouterVO router){
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        String controlIP = null;
+
+        if(router.getHypervisorType() == HypervisorType.VMware  && dcVo.getNetworkType() == NetworkType.Basic ){
+
+            final List<NicVO> nics = _nicDao.listByVmId(router.getId());
+            for (final NicVO nic : nics) {
+                final NetworkVO nc = _networkDao.findById(nic.getNetworkId());
+                if (nc.getTrafficType() == TrafficType.Guest && nic.getIPv4Address() != null) {
+                    controlIP = nic.getIPv4Address();
+                    break;
+                }
+            }
+            s_logger.debug("Vmware with Basic network selected Guest NIC ip as control IP " + controlIP );
+        }else{
+            controlIP = _routerControlHelper.getRouterControlIp(router.getId());
+        }
+
+        s_logger.debug("IP of control NIC " + controlIP );
+        return controlIP;
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) {
+
+        boolean dnsProvided = true;
+        boolean dhcpProvided = true;
+        boolean publicNetwork = false;
+        final DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
+        _dcDao.loadDetails(dc);
+
+        // 1) Set router details
+        final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId());
+        final Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(router.getId());
+        router.setDetails(details);
+
+        // 2) Prepare boot loader elements related with Control network
+
+        final StringBuilder buf = profile.getBootArgsBuilder();
+        buf.append(" template=domP");
+        buf.append(" name=").append(profile.getHostName());
+
+        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
+        }
+
+        NicProfile controlNic = null;
+        String defaultDns1 = null;
+        String defaultDns2 = null;
+        String defaultIp6Dns1 = null;
+        String defaultIp6Dns2 = null;
+        for (final NicProfile nic : profile.getNics()) {
+            final int deviceId = nic.getDeviceId();
+            boolean ipv4 = false, ipv6 = false;
+            if (nic.getIPv4Address() != null) {
+                ipv4 = true;
+                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
+                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
+            }
+            if (nic.getIPv6Address() != null) {
+                ipv6 = true;
+                buf.append(" eth").append(deviceId).append("ip6=").append(nic.getIPv6Address());
+                buf.append(" eth").append(deviceId).append("ip6prelen=").append(NetUtils.getIp6CidrSize(nic.getIPv6Cidr()));
+            }
+
+            if (nic.isDefaultNic()) {
+                if (ipv4) {
+                    buf.append(" gateway=").append(nic.getIPv4Gateway());
+                }
+                if (ipv6) {
+                    buf.append(" ip6gateway=").append(nic.getIPv6Gateway());
+                }
+                defaultDns1 = nic.getIPv4Dns1();
+                defaultDns2 = nic.getIPv4Dns2();
+                defaultIp6Dns1 = nic.getIPv6Dns1();
+                defaultIp6Dns2 = nic.getIPv6Dns2();
+            }
+
+            if (nic.getTrafficType() == TrafficType.Management) {
+                buf.append(" localgw=").append(dest.getPod().getGateway());
+            } else if (nic.getTrafficType() == TrafficType.Control) {
+                controlNic = nic;
+                buf.append(createRedundantRouterArgs(controlNic, router));
+
+                // DOMR control command is sent over management server in VMware
+                if (dest.getHost().getHypervisorType() == HypervisorType.VMware || dest.getHost().getHypervisorType() == HypervisorType.Hyperv) {
+                    s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + dest.getPod().getCidrAddress() + "/"
+                            + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: "
+                            + ApiServiceConfiguration.ManagementServerAddresses.value());
+
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Add management server explicit route to DomR.");
+                    }
+
+                    // always add management explicit route, for basic
+                    // networking setup, DomR may have two interfaces while both
+                    // are on the same subnet
+                    _mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key());
+                    if (NetUtils.isValidIp4Cidr(_mgmtCidr)) {
+                        buf.append(" mgmtcidr=").append(_mgmtCidr);
+                        buf.append(" localgw=").append(dest.getPod().getGateway());
+                    }
+
+                    if (dc.getNetworkType() == NetworkType.Basic) {
+                        // ask domR to setup SSH on guest network
+                        buf.append(" sshonguest=true");
+                    }
+
+                }
+            } else if (nic.getTrafficType() == TrafficType.Guest) {
+                dnsProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter);
+                dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter);
+                // build bootloader parameter for the guest
+                buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router));
+            } else if (nic.getTrafficType() == TrafficType.Public) {
+                publicNetwork = true;
+            }
+        }
+
+        if (controlNic == null) {
+            throw new CloudRuntimeException("Didn't start a control port");
+        }
+
+        final String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key());
+        if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
+            _disableRpFilter = true;
+        } else {
+            _disableRpFilter = false;
+        }
+
+        String rpFilter = " ";
+        String type = null;
+        if (router.getVpcId() != null) {
+            type = "vpcrouter";
+            if (_disableRpFilter) {
+                rpFilter = " disable_rp_filter=true";
+            }
+        } else if (!publicNetwork) {
+            type = "dhcpsrvr";
+        } else {
+            type = "router";
+            if (_disableRpFilter) {
+                rpFilter = " disable_rp_filter=true";
+            }
+        }
+
+        if (_disableRpFilter) {
+            rpFilter = " disable_rp_filter=true";
+        }
+
+        buf.append(" type=" + type + rpFilter);
+
+        final String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName());
+        if (domain_suffix != null) {
+            buf.append(" dnssearchorder=").append(domain_suffix);
+        }
+
+        if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) {
+            buf.append(" extra_pubnics=" + _routerExtraPublicNics);
+        }
+
+        /*
+         * If virtual router didn't provide DNS service but provide DHCP
+         * service, we need to override the DHCP response to return DNS server
+         * rather than virtual router itself.
+         */
+        if (dnsProvided || dhcpProvided) {
+            if (defaultDns1 != null) {
+                buf.append(" dns1=").append(defaultDns1);
+            }
+            if (defaultDns2 != null) {
+                buf.append(" dns2=").append(defaultDns2);
+            }
+            if (defaultIp6Dns1 != null) {
+                buf.append(" ip6dns1=").append(defaultIp6Dns1);
+            }
+            if (defaultIp6Dns2 != null) {
+                buf.append(" ip6dns2=").append(defaultIp6Dns2);
+            }
+
+            boolean useExtDns = !dnsProvided;
+            /* For backward compatibility */
+            useExtDns = useExtDns || UseExternalDnsServers.valueIn(dc.getId());
+
+            if (useExtDns) {
+                buf.append(" useextdns=true");
+            }
+        }
+
+        if (Boolean.valueOf(_configDao.getValue(Config.BaremetalProvisionDoneNotificationEnabled.key()))) {
+            final QueryBuilder<UserVO> acntq = QueryBuilder.create(UserVO.class);
+            acntq.and(acntq.entity().getUsername(), SearchCriteria.Op.EQ, "baremetal-system-account");
+            final UserVO user = acntq.find();
+            if (user == null) {
+                s_logger.warn(String
+                        .format("global setting[baremetal.provision.done.notification] is enabled but user baremetal-system-account is not found. Baremetal provision done notification will not be enabled"));
+            } else {
+                buf.append(String.format(" baremetalnotificationsecuritykey=%s", user.getSecretKey()));
+                buf.append(String.format(" baremetalnotificationapikey=%s", user.getApiKey()));
+                buf.append(" host=").append(ApiServiceConfiguration.ManagementServerAddresses.value());
+                buf.append(" port=").append(_configDao.getValue(Config.BaremetalProvisionDoneNotificationPort.key()));
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
+        }
+
+        return true;
+    }
+
+    protected StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) {
+        final long guestNetworkId = guestNic.getNetworkId();
+        final NetworkVO guestNetwork = _networkDao.findById(guestNetworkId);
+        String dhcpRange = null;
+        final DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId());
+
+        final StringBuilder buf = new StringBuilder();
+
+        final boolean isRedundant = router.getIsRedundantRouter();
+        if (isRedundant) {
+            buf.append(createRedundantRouterArgs(guestNic, router));
+            final Network net = _networkModel.getNetwork(guestNic.getNetworkId());
+            buf.append(" guestgw=").append(net.getGateway());
+            final String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIPv4Address()) | ~NetUtils.ip2Long(guestNic.getIPv4Netmask()));
+            buf.append(" guestbrd=").append(brd);
+            buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getIPv4Netmask()));
+
+            final int advertInt = NumbersUtil.parseInt(_configDao.getValue(Config.RedundantRouterVrrpInterval.key()), 1);
+            buf.append(" advert_int=").append(advertInt);
+        }
+
+        // setup network domain
+        final String domain = guestNetwork.getNetworkDomain();
+        if (domain != null) {
+            buf.append(" domain=" + domain);
+        }
+
+        long cidrSize = 0;
+
+        // setup dhcp range
+        if (dc.getNetworkType() == NetworkType.Basic) {
+            if (guestNic.isDefaultNic()) {
+                cidrSize = NetUtils.getCidrSize(guestNic.getIPv4Netmask());
+                final String cidr = NetUtils.getCidrSubNet(guestNic.getIPv4Gateway(), cidrSize);
+                if (cidr != null) {
+                    dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
+                }
+            }
+        } else if (dc.getNetworkType() == NetworkType.Advanced) {
+            final String cidr = _networkModel.getValidNetworkCidr(guestNetwork);
+            if (cidr != null) {
+                cidrSize = NetUtils.getCidrSize(NetUtils.getCidrNetmask(cidr));
+                dhcpRange = NetUtils.getDhcpRange(cidr);
+            }
+        }
+
+        if (dhcpRange != null) {
+            // To limit DNS to the cidr range
+            buf.append(" cidrsize=" + String.valueOf(cidrSize));
+            buf.append(" dhcprange=" + dhcpRange);
+        }
+
+        return buf;
+    }
+
+    protected StringBuilder createRedundantRouterArgs(final NicProfile nic, final DomainRouterVO router) {
+        final StringBuilder buf = new StringBuilder();
+
+        final boolean isRedundant = router.getIsRedundantRouter();
+        if (isRedundant) {
+            buf.append(" redundant_router=1");
+
+            final int advertInt = NumbersUtil.parseInt(_configDao.getValue(Config.RedundantRouterVrrpInterval.key()), 1);
+            buf.append(" advert_int=").append(advertInt);
+
+            final Long vpcId = router.getVpcId();
+            final List<DomainRouterVO> routers;
+            if (vpcId != null) {
+                routers = _routerDao.listByVpcId(vpcId);
+                // For a redundant VPC router, both shall have the same router id. It will be used by the VRRP virtural_router_id attribute.
+                // So we use the VPC id to avoid group problems.
+                buf.append(" router_id=").append(vpcId);
+
+                // Will build the routers password based on the VPC ID and UUID.
+                final Vpc vpc = _vpcDao.findById(vpcId);
+
+                try {
+                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
+                    final byte [] rawDigest = vpc.getUuid().getBytes(Charset.defaultCharset());
+                    digest.update(rawDigest);
+
+                    final BigInteger password = new BigInteger(1, digest.digest());
+                    buf.append(" router_password=").append(password);
+
+                } catch (final NoSuchAlgorithmException e) {
+                    s_logger.error("Failed to pssword! Will use the plan B instead.");
+                    buf.append(" router_password=").append(vpc.getUuid());
+                }
+
+            } else {
+                routers = _routerDao.listByNetworkAndRole(nic.getNetworkId(), Role.VIRTUAL_ROUTER);
+            }
+
+            String redundantState = RedundantState.BACKUP.toString();
+            router.setRedundantState(RedundantState.BACKUP);
+            if (routers.size() == 0) {
+                redundantState = RedundantState.MASTER.toString();
+                router.setRedundantState(RedundantState.MASTER);
+            } else {
+                final DomainRouterVO router0 = routers.get(0);
+                if (router.getId() == router0.getId()) {
+                    redundantState = RedundantState.MASTER.toString();
+                    router.setRedundantState(RedundantState.MASTER);
+                }
+            }
+
+            buf.append(" redundant_state=").append(redundantState);
+        }
+
+        return buf;
+    }
+
+    @Override
+    public boolean finalizeDeployment(final Commands cmds, final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context)
+            throws ResourceUnavailableException {
+        final DomainRouterVO router = _routerDao.findById(profile.getId());
+
+        final List<NicProfile> nics = profile.getNics();
+        for (final NicProfile nic : nics) {
+            if (nic.getTrafficType() == TrafficType.Public) {
+                router.setPublicIpAddress(nic.getIPv4Address());
+                router.setPublicNetmask(nic.getIPv4Netmask());
+                router.setPublicMacAddress(nic.getMacAddress());
+            } else if (nic.getTrafficType() == TrafficType.Control) {
+                router.setPrivateIpAddress(nic.getIPv4Address());
+                router.setPrivateMacAddress(nic.getMacAddress());
+            }
+        }
+        _routerDao.update(router.getId(), router);
+
+        finalizeCommandsOnStart(cmds, profile);
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachineProfile profile) {
+        final DomainRouterVO router = _routerDao.findById(profile.getId());
+        final NicProfile controlNic = getControlNic(profile);
+
+        if (controlNic == null) {
+            s_logger.error("Control network doesn't exist for the router " + router);
+            return false;
+        }
+
+        finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic);
+
+        // restart network if restartNetwork = false is not specified in profile
+        // parameters
+        boolean reprogramGuestNtwks = true;
+        if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
+            reprogramGuestNtwks = false;
+        }
+
+        final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
+        if (vrProvider == null) {
+            throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
+        }
+        final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
+        if (provider == null) {
+            throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
+        }
+
+        final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
+        for (final Long guestNetworkId : routerGuestNtwkIds) {
+            final AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, router.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
+                    guestNetworkId, router.getId()));
+            cmds.addCommand(startCmd);
+
+            if (reprogramGuestNtwks) {
+                finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId, null);
+                finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId);
+
+                final NetworkOffering offering = _networkOfferingDao.findById(_networkDao.findById(guestNetworkId).getNetworkOfferingId());
+                // service monitoring is currently not added in RVR
+                if (!offering.isRedundantRouter()) {
+                    final String serviceMonitringSet = _configDao.getValue(Config.EnableServiceMonitoring.key());
+
+                    if (serviceMonitringSet != null && serviceMonitringSet.equalsIgnoreCase("true")) {
+                        finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, true);
+                    } else {
+                        finalizeMonitorServiceOnStrat(cmds, profile, router, provider, guestNetworkId, false);
+                    }
+                }
+
+            }
+
+            finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
+
+            final AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, router.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
+                    guestNetworkId, router.getId()));
+            cmds.addCommand(finishCmd);
+        }
+
+        return true;
+    }
+
+    private void finalizeMonitorServiceOnStrat(final Commands cmds, final VirtualMachineProfile profile, final DomainRouterVO router, final Provider provider,
+            final long networkId, final Boolean add) {
+
+        final NetworkVO network = _networkDao.findById(networkId);
+
+        s_logger.debug("Creating  monitoring services on " + router + " start...");
+
+        // get the list of sevices for this network to monitor
+        final List<MonitoringServiceVO> services = new ArrayList<MonitoringServiceVO>();
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter)
+                || _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter)) {
+            final MonitoringServiceVO dhcpService = _monitorServiceDao.getServiceByName(MonitoringService.Service.Dhcp.toString());
+            if (dhcpService != null) {
+                services.add(dhcpService);
+            }
+        }
+
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, Provider.VirtualRouter)) {
+            final MonitoringServiceVO lbService = _monitorServiceDao.getServiceByName(MonitoringService.Service.LoadBalancing.toString());
+            if (lbService != null) {
+                services.add(lbService);
+            }
+        }
+        final List<MonitoringServiceVO> defaultServices = _monitorServiceDao.listDefaultServices(true);
+        services.addAll(defaultServices);
+
+        final List<MonitorServiceTO> servicesTO = new ArrayList<MonitorServiceTO>();
+        for (final MonitoringServiceVO service : services) {
+            final MonitorServiceTO serviceTO = new MonitorServiceTO(service.getService(), service.getProcessName(), service.getServiceName(), service.getServicePath(),
+                    service.getServicePidFile(), service.isDefaultService());
+            servicesTO.add(serviceTO);
+        }
+
+        // TODO : This is a hacking fix
+        // at VR startup time, information in VirtualMachineProfile may not
+        // updated to DB yet,
+        // getRouterControlIp() may give wrong IP under basic network mode in
+        // VMware environment
+        final NicProfile controlNic = getControlNic(profile);
+        if (controlNic == null) {
+            throw new CloudRuntimeException("VirtualMachine " + profile.getInstanceName() + " doesn't have a control interface");
+        }
+        final SetMonitorServiceCommand command = new SetMonitorServiceCommand(servicesTO);
+        command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIPv4Address());
+        command.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(networkId, router.getId()));
+        command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+        if (!add) {
+            command.setAccessDetail(NetworkElementCommand.ROUTER_MONITORING_ENABLE, add.toString());
+        }
+        cmds.addCommand("monitor", command);
+    }
+
+    protected NicProfile getControlNic(final VirtualMachineProfile profile) {
+        final DomainRouterVO router = _routerDao.findById(profile.getId());
+        final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
+        NicProfile controlNic = null;
+        if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) {
+            // TODO this is a ugly to test hypervisor type here
+            // for basic network mode, we will use the guest NIC for control NIC
+            for (final NicProfile nic : profile.getNics()) {
+                if (nic.getTrafficType() == TrafficType.Guest && nic.getIPv4Address() != null) {
+                    controlNic = nic;
+                }
+            }
+        } else {
+            for (final NicProfile nic : profile.getNics()) {
+                if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
+                    controlNic = nic;
+                }
+            }
+        }
+        return controlNic;
+    }
+
+    protected void finalizeSshAndVersionAndNetworkUsageOnStart(final Commands cmds, final VirtualMachineProfile profile, final DomainRouterVO router, final NicProfile controlNic) {
+        final DomainRouterVO vr = _routerDao.findById(profile.getId());
+        cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922));
+
+        // Update router template/scripts version
+        final GetDomRVersionCmd command = new GetDomRVersionCmd();
+        command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIPv4Address());
+        command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        cmds.addCommand("getDomRVersion", command);
+
+        // Network usage command to create iptables rules
+        final boolean forVpc = vr.getVpcId() != null;
+        if (!forVpc) {
+            cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIPv4Address(), router.getHostName(), "create", forVpc));
+        }
+    }
+
+    protected void finalizeUserDataAndDhcpOnStart(final Commands cmds, final DomainRouterVO router, final Provider provider, final Long guestNetworkId) {
+        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)
+                || _networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dns, provider)) {
+            // Resend dhcp
+            s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start...");
+            _commandSetupHelper.createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId);
+        }
+
+        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) {
+            // Resend user data
+            s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start...");
+            _commandSetupHelper.createVmDataCommandForVMs(router, cmds, guestNetworkId);
+        }
+    }
+
+    protected void finalizeNetworkRulesForNetwork(final Commands cmds, final DomainRouterVO router, final Provider provider, final Long guestNetworkId) {
+        s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
+
+        final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
+        final List<FirewallRule> firewallRulesEgress = new ArrayList<FirewallRule>();
+
+        // Fetch firewall Egress rules.
+        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
+            firewallRulesEgress.addAll(_rulesDao.listByNetworkPurposeTrafficType(guestNetworkId, Purpose.Firewall, FirewallRule.TrafficType.Egress));
+            if (firewallRulesEgress.isEmpty()) {
+                //create egress default rule for VR
+                createDefaultEgressFirewallRule(firewallRulesEgress, guestNetworkId);
+            }
+        }
+
+        // Re-apply firewall Egress rules
+        s_logger.debug("Found " + firewallRulesEgress.size() + " firewall Egress rule(s) to apply as a part of domR " + router + " start.");
+        if (!firewallRulesEgress.isEmpty()) {
+            _commandSetupHelper.createFirewallRulesCommands(firewallRulesEgress, router, cmds, guestNetworkId);
+        }
+
+        if (publicIps != null && !publicIps.isEmpty()) {
+            final List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
+            final List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
+            final List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
+            final List<StaticNat> staticNats = new ArrayList<StaticNat>();
+            final List<FirewallRule> firewallRulesIngress = new ArrayList<FirewallRule>();
+
+            // Get information about all the rules (StaticNats and
+            // StaticNatRules; PFVPN to reapply on domR start)
+            for (final PublicIpAddress ip : publicIps) {
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) {
+                    pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
+                }
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
+                    staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
+                }
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
+                    firewallRulesIngress.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
+                }
+
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) {
+                    final RemoteAccessVpn vpn = _vpnDao.findByPublicIpAddress(ip.getId());
+                    if (vpn != null) {
+                        vpns.add(vpn);
+                    }
+                }
+
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
+                    if (ip.isOneToOneNat()) {
+
+                        boolean revoke = false;
+                        if (ip.getState() == IpAddress.State.Releasing ) {
+                            // for ips got struck in releasing state we need to delete the rule not add.
+                            s_logger.debug("Rule revoke set to true for the ip " + ip.getAddress() +" becasue it is in releasing state");
+                            revoke = true;
+                        }
+                        final StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), ip.getVmIp(), revoke);
+
+                        staticNats.add(staticNat);
+                    }
+                }
+            }
+
+            // Re-apply static nats
+            s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
+            if (!staticNats.isEmpty()) {
+                _commandSetupHelper.createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId);
+            }
+
+            // Re-apply firewall Ingress rules
+            s_logger.debug("Found " + firewallRulesIngress.size() + " firewall Ingress rule(s) to apply as a part of domR " + router + " start.");
+            if (!firewallRulesIngress.isEmpty()) {
+                _commandSetupHelper.createFirewallRulesCommands(firewallRulesIngress, router, cmds, guestNetworkId);
+            }
+
+            // Re-apply port forwarding rules
+            s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start.");
+            if (!pfRules.isEmpty()) {
+                _commandSetupHelper.createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId);
+            }
+
+            // Re-apply static nat rules
+            s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start.");
+            if (!staticNatFirewallRules.isEmpty()) {
+                final List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
+                for (final FirewallRule rule : staticNatFirewallRules) {
+                    staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false));
+                }
+                _commandSetupHelper.createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId);
+            }
+
+            // Re-apply vpn rules
+            s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start.");
+            if (!vpns.isEmpty()) {
+                for (final RemoteAccessVpn vpn : vpns) {
+                    _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
+                }
+            }
+
+            final List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkIdAndScheme(guestNetworkId, Scheme.Public);
+            final List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
+            if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) {
+                // Re-apply load balancing rules
+                for (final LoadBalancerVO lb : lbs) {
+                    final List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
+                    final List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
+                    final List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
+                    final Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress();
+                    final LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId());
+                    final LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol());
+                    lbRules.add(loadBalancing);
+                }
+            }
+
+            s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start.");
+            if (!lbRules.isEmpty()) {
+                _commandSetupHelper.createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId);
+            }
+        }
+        // Reapply dhcp and dns configuration.
+        final Network guestNetwork = _networkDao.findById(guestNetworkId);
+        if (guestNetwork.getGuestType() == GuestType.Shared && _networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) {
+            final Map<Network.Capability, String> dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(
+                    _networkOfferingDao.findById(_networkDao.findById(guestNetworkId).getNetworkOfferingId()), Service.Dhcp);
+            final String supportsMultipleSubnets = dhcpCapabilities.get(Network.Capability.DhcpAccrossMultipleSubnets);
+            if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) {
+                final List<NicIpAliasVO> revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(guestNetworkId, NicIpAlias.State.revoked);
+                s_logger.debug("Found" + revokedIpAliasVOs.size() + "ip Aliases to revoke on the router as a part of dhcp configuration");
+                removeRevokedIpAliasFromDb(revokedIpAliasVOs);
+
+                final List<NicIpAliasVO> aliasVOs = _nicIpAliasDao.listByNetworkIdAndState(guestNetworkId, NicIpAlias.State.active);
+                s_logger.debug("Found" + aliasVOs.size() + "ip Aliases to apply on the router as a part of dhcp configuration");
+                final List<IpAliasTO> activeIpAliasTOs = new ArrayList<IpAliasTO>();
+                for (final NicIpAliasVO aliasVO : aliasVOs) {
+                    activeIpAliasTOs.add(new IpAliasTO(aliasVO.getIp4Address(), aliasVO.getNetmask(), aliasVO.getAliasCount().toString()));
+                }
+                if (activeIpAliasTOs.size() != 0) {
+                    _commandSetupHelper.createIpAlias(router, activeIpAliasTOs, guestNetworkId, cmds);
+                    _commandSetupHelper.configDnsMasq(router, _networkDao.findById(guestNetworkId), cmds);
+                }
+            }
+        }
+    }
+
+    private void createDefaultEgressFirewallRule(final List<FirewallRule> rules, final long networkId) {
+        final NetworkVO network = _networkDao.findById(networkId);
+        final NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        final Boolean defaultEgressPolicy = offering.isEgressDefaultPolicy();
+
+        // The default on the router is set to Deny all. So, if the default configuration in the offering is set to true (Allow), we change the Egress here
+        if (defaultEgressPolicy) {
+            final List<String> sourceCidr = new ArrayList<String>();
+            final List<String> destCidr = new ArrayList<String>();
+
+            sourceCidr.add(network.getCidr());
+            destCidr.add(NetUtils.ALL_IP4_CIDRS);
+
+            final FirewallRule rule = new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr,
+                    destCidr, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.System);
+
+            rules.add(rule);
+        } else {
+            s_logger.debug("Egress policy for the Network " + networkId + " is already defined as Deny. So, no need to default the rule to Allow. ");
+        }
+    }
+
+    private void removeRevokedIpAliasFromDb(final List<NicIpAliasVO> revokedIpAliasVOs) {
+        for (final NicIpAliasVO ipalias : revokedIpAliasVOs) {
+            _nicIpAliasDao.expunge(ipalias.getId());
+        }
+    }
+
+    protected void finalizeIpAssocForNetwork(final Commands cmds, final VirtualRouter router, final Provider provider, final Long guestNetworkId,
+            final Map<String, String> vlanMacAddress) {
+
+        final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
+
+        if (publicIps != null && !publicIps.isEmpty()) {
+            s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start.");
+            // Re-apply public ip addresses - should come before PF/LB/VPN
+            if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
+                _commandSetupHelper.createAssociateIPCommands(router, publicIps, cmds, 0);
+            }
+        }
+    }
+
+    protected ArrayList<? extends PublicIpAddress> getPublicIpsToApply(final VirtualRouter router, final Provider provider, final Long guestNetworkId,
+            final com.cloud.network.IpAddress.State... skipInStates) {
+        final long ownerId = router.getAccountId();
+        final List<? extends IpAddress> userIps;
+
+        final Network guestNetwork = _networkDao.findById(guestNetworkId);
+        if (guestNetwork.getGuestType() == GuestType.Shared) {
+            // ignore the account id for the shared network
+            userIps = _networkModel.listPublicIpsAssignedToGuestNtwk(guestNetworkId, null);
+        } else {
+            userIps = _networkModel.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null);
+        }
+
+        final List<PublicIp> allPublicIps = new ArrayList<PublicIp>();
+        if (userIps != null && !userIps.isEmpty()) {
+            boolean addIp = true;
+            for (final IpAddress userIp : userIps) {
+                if (skipInStates != null) {
+                    for (final IpAddress.State stateToSkip : skipInStates) {
+                        if (userIp.getState() == stateToSkip) {
+                            s_logger.debug("Skipping ip address " + userIp + " in state " + userIp.getState());
+                            addIp = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (addIp) {
+                    final IPAddressVO ipVO = _ipAddressDao.findById(userIp.getId());
+                    final PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipVO, _vlanDao.findById(userIp.getVlanId()));
+                    allPublicIps.add(publicIp);
+                }
+            }
+        }
+
+        // Get public Ips that should be handled by router
+        final Network network = _networkDao.findById(guestNetworkId);
+        final Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(allPublicIps, false, true);
+        final Map<Provider, ArrayList<PublicIpAddress>> providerToIpList = _networkModel.getProviderToIpList(network, ipToServices);
+        // Only cover virtual router for now, if ELB use it this need to be
+        // modified
+
+        final ArrayList<PublicIpAddress> publicIps = providerToIpList.get(provider);
+        return publicIps;
+    }
+
+    @Override
+    public boolean finalizeStart(final VirtualMachineProfile profile, final long hostId, final Commands cmds, final ReservationContext context) {
+        final DomainRouterVO router = _routerDao.findById(profile.getId());
+
+        // process all the answers
+        for (final Answer answer : cmds.getAnswers()) {
+            // handle any command failures
+            if (!answer.getResult()) {
+                final String cmdClassName = answer.getClass().getCanonicalName().replace("Answer", "Command");
+                final String errorMessage = "Command: " + cmdClassName + " failed while starting virtual router";
+                final String errorDetails = "Details: " + answer.getDetails() + " " + answer.toString();
+                // add alerts for the failed commands
+                _alertMgr.sendAlert(AlertService.AlertType.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterId(), router.getPodIdToDeployIn(), errorMessage, errorDetails);
+                s_logger.error(answer.getDetails());
+                s_logger.warn(errorMessage);
+                // Stop the router if any of the commands failed
+                return false;
+            }
+        }
+
+        // at this point, all the router command are successful.
+        boolean result = true;
+        // Get guest networks info
+        final List<Network> guestNetworks = new ArrayList<Network>();
+
+        final List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
+        for (final Nic nic : routerNics) {
+            final Network network = _networkModel.getNetwork(nic.getNetworkId());
+
+            final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+
+            if (network.getTrafficType() == TrafficType.Guest) {
+                guestNetworks.add(network);
+                if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
+                    final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+
+                    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+                    try {
+                        result = networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nicProfile);
+                    } catch (final ResourceUnavailableException e) {
+                        s_logger.debug("ERROR in finalizeStart: ", e);
+                    }
+                }
+            }
+        }
+        if (result) {
+            final GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer) cmds.getAnswer("getDomRVersion");
+            router.setTemplateVersion(versionAnswer.getTemplateVersion());
+            router.setScriptsVersion(versionAnswer.getScriptsVersion());
+            _routerDao.persist(router, guestNetworks);
+        }
+
+        return result;
+    }
+
+    @Override
+    public void finalizeStop(final VirtualMachineProfile profile, final Answer answer) {
+        if (answer != null) {
+            final VirtualMachine vm = profile.getVirtualMachine();
+            final DomainRouterVO domR = _routerDao.findById(vm.getId());
+            processStopOrRebootAnswer(domR, answer);
+            final List<? extends Nic> routerNics = _nicDao.listByVmId(profile.getId());
+            for (final Nic nic : routerNics) {
+                final Network network = _networkModel.getNetwork(nic.getNetworkId());
+                final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
+
+                if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) {
+                    final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+
+                    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
+                    try {
+                        networkTopology.setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile);
+                    } catch (final ResourceUnavailableException e) {
+                        s_logger.debug("ERROR in finalizeStop: ", e);
+                    }
+                }
+            }
+
+        }
+    }
+
+    @Override
+    public void finalizeExpunge(final VirtualMachine vm) {
+    }
+
+    @Override
+    public boolean startRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
+        if (routers == null || routers.isEmpty()) {
+            s_logger.warn("Failed to start remote access VPN: no router found for account and zone");
+            throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", DataCenter.class, network.getDataCenterId());
+        }
+
+        for (final VirtualRouter router : routers) {
+            if (router.getState() != VirtualMachine.State.Running) {
+                s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState());
+                throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + router.getState(), DataCenter.class,
+                        network.getDataCenterId());
+            }
+
+            final Commands cmds = new Commands(Command.OnError.Stop);
+            _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
+
+            if (!_nwHelper.sendCommandsToRouter(router, cmds)) {
+                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId());
+            }
+
+            Answer answer = cmds.getAnswer("users");
+            if (answer == null) {
+                s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                        + router.getInstanceName() + " due to null answer");
+                throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                        + router.getInstanceName() + " due to null answer", DataCenter.class, router.getDataCenterId());
+            }
+            if (!answer.getResult()) {
+                s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                        + router.getInstanceName() + " due to " + answer.getDetails());
+                throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account "
+                        + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
+            }
+            answer = cmds.getAnswer("startVpn");
+            if (!answer.getResult()) {
+                s_logger.error("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName()
+                        + " due to " + answer.getDetails());
+                throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                        + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
+            }
+
+        }
+        return true;
+    }
+
+    @Override
+    public boolean deleteRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
+        if (routers == null || routers.isEmpty()) {
+            s_logger.warn("Failed to delete remote access VPN: no router found for account and zone");
+            throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId());
+        }
+
+        boolean result = true;
+        for (final VirtualRouter router : routers) {
+            if (router.getState() == VirtualMachine.State.Running) {
+                final Commands cmds = new Commands(Command.OnError.Continue);
+                _commandSetupHelper.createApplyVpnCommands(false, vpn, router, cmds);
+                result = result && _nwHelper.sendCommandsToRouter(router, cmds);
+            } else if (router.getState() == VirtualMachine.State.Stopped) {
+                s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it");
+                continue;
+            } else {
+                s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState());
+                throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class,
+                        network.getDataCenterId());
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public DomainRouterVO stop(final VirtualRouter router, final boolean forced, final User user, final Account caller) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        s_logger.debug("Stopping router " + router);
+        try {
+            _itMgr.advanceStop(router.getUuid(), forced);
+            return _routerDao.findById(router.getId());
+        } catch (final OperationTimedoutException e) {
+            throw new CloudRuntimeException("Unable to stop " + router, e);
+        }
+    }
+
+    @Override
+    public boolean removeDhcpSupportForSubnet(final Network network, final List<DomainRouterVO> routers) throws ResourceUnavailableException {
+        if (routers == null || routers.isEmpty()) {
+            s_logger.warn("Failed to add/remove VPN users: no router found for account and zone");
+            throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId());
+        }
+
+        for (final DomainRouterVO router : routers) {
+            if (router.getState() != VirtualMachine.State.Running) {
+                s_logger.warn("Failed to add/remove VPN users: router not in running state");
+                throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class,
+                        network.getDataCenterId());
+            }
+
+            final Commands cmds = new Commands(Command.OnError.Continue);
+            final List<NicIpAliasVO> revokedIpAliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.revoked);
+            s_logger.debug("Found" + revokedIpAliasVOs.size() + "ip Aliases to revoke on the router as a part of dhcp configuration");
+            final List<IpAliasTO> revokedIpAliasTOs = new ArrayList<IpAliasTO>();
+            for (final NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) {
+                revokedIpAliasTOs.add(new IpAliasTO(revokedAliasVO.getIp4Address(), revokedAliasVO.getNetmask(), revokedAliasVO.getAliasCount().toString()));
+            }
+            final List<NicIpAliasVO> aliasVOs = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.State.active);
+            s_logger.debug("Found" + aliasVOs.size() + "ip Aliases to apply on the router as a part of dhcp configuration");
+            final List<IpAliasTO> activeIpAliasTOs = new ArrayList<IpAliasTO>();
+            for (final NicIpAliasVO aliasVO : aliasVOs) {
+                activeIpAliasTOs.add(new IpAliasTO(aliasVO.getIp4Address(), aliasVO.getNetmask(), aliasVO.getAliasCount().toString()));
+            }
+            _commandSetupHelper.createDeleteIpAliasCommand(router, revokedIpAliasTOs, activeIpAliasTOs, network.getId(), cmds);
+            _commandSetupHelper.configDnsMasq(router, network, cmds);
+            final boolean result = _nwHelper.sendCommandsToRouter(router, cmds);
+            if (result) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(final TransactionStatus status) {
+                        for (final NicIpAliasVO revokedAliasVO : revokedIpAliasVOs) {
+                            _nicIpAliasDao.expunge(revokedAliasVO.getId());
+                        }
+                    }
+                });
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "starting router Vm", async = true)
+    public VirtualRouter startRouter(final long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
+        return startRouter(id, true);
+    }
+
+    @Override
+    public VirtualRouter startRouter(final long routerId, final boolean reprogramNetwork) throws ResourceUnavailableException, InsufficientCapacityException,
+    ConcurrentOperationException {
+        final Account caller = CallContext.current().getCallingAccount();
+        final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+
+        // verify parameters
+        DomainRouterVO router = _routerDao.findById(routerId);
+        //clean up the update_state feild
+        if(router.getUpdateState()== VirtualRouter.UpdateState.UPDATE_FAILED){
+            router.setUpdateState(null);
+            _routerDao.update(router.getId(),router);
+        }
+        if (router == null) {
+            throw new InvalidParameterValueException("Unable to find router by id " + routerId + ".");
+        }
+        _accountMgr.checkAccess(caller, null, true, router);
+
+        final Account owner = _accountMgr.getAccount(router.getAccountId());
+
+        // Check if all networks are implemented for the domR; if not -
+        // implement them
+        final DataCenter dc = _dcDao.findById(router.getDataCenterId());
+        HostPodVO pod = null;
+        if (router.getPodIdToDeployIn() != null) {
+            pod = _podDao.findById(router.getPodIdToDeployIn());
+        }
+        final DeployDestination dest = new DeployDestination(dc, pod, null, null);
+
+        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
+
+        final List<NicVO> nics = _nicDao.listByVmId(routerId);
+
+        for (final NicVO nic : nics) {
+            if (!_networkMgr.startNetwork(nic.getNetworkId(), dest, context)) {
+                s_logger.warn("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start");
+                throw new CloudRuntimeException("Failed to start network id=" + nic.getNetworkId() + " as a part of domR start");
+            }
+        }
+
+        // After start network, check if it's already running
+        router = _routerDao.findById(routerId);
+        if (router.getState() == VirtualMachine.State.Running) {
+            return router;
+        }
+
+        final UserVO user = _userDao.findById(CallContext.current().getCallingUserId());
+        final Map<Param, Object> params = new HashMap<Param, Object>();
+        if (reprogramNetwork) {
+            params.put(Param.ReProgramGuestNetworks, true);
+        } else {
+            params.put(Param.ReProgramGuestNetworks, false);
+        }
+        final VirtualRouter virtualRouter = _nwHelper.startVirtualRouter(router, user, caller, params);
+        if (virtualRouter == null) {
+            throw new CloudRuntimeException("Failed to start router with id " + routerId);
+        }
+        return virtualRouter;
+    }
+
+    @Override
+    public List<VirtualRouter> getRoutersForNetwork(final long networkId) {
+        final List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        final List<VirtualRouter> vrs = new ArrayList<VirtualRouter>(routers.size());
+        for (final DomainRouterVO router : routers) {
+            vrs.add(router);
+        }
+        return vrs;
+    }
+
+    @Override
+    public String getDnsBasicZoneUpdate() {
+        return _dnsBasicZoneUpdates;
+    }
+
+    @Override
+    public int getTimeout() {
+        return -1;
+    }
+
+    @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 void processHostAdded(long hostId) {
+    }
+
+    @Override
+    public void processConnect(final Host host, final StartupCommand cmd, final boolean forRebalance) throws ConnectionException {
+        final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(host.getId());
+        for (DomainRouterVO router : routers) {
+            if (router.isStopPending()) {
+                s_logger.info("Stopping router " + router.getInstanceName() + " due to stop pending flag found!");
+                final VirtualMachine.State state = router.getState();
+                if (state != VirtualMachine.State.Stopped && state != VirtualMachine.State.Destroyed) {
+                    try {
+                        stopRouter(router.getId(), false);
+                    } catch (final ResourceUnavailableException e) {
+                        s_logger.warn("Fail to stop router " + router.getInstanceName(), e);
+                        throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName());
+                    } catch (final ConcurrentOperationException e) {
+                        s_logger.warn("Fail to stop router " + router.getInstanceName(), e);
+                        throw new ConnectionException(false, "Fail to stop router " + router.getInstanceName());
+                    }
+                }
+                router.setStopPending(false);
+                router = _routerDao.persist(router);
+            }
+        }
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(final long agentId, final AgentControlCommand cmd) {
+        return null;
+    }
+
+    @Override
+    public boolean processDisconnect(final long agentId, final Status state) {
+        return false;
+    }
+
+    @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 void prepareStop(final VirtualMachineProfile profile) {
+        // Collect network usage before stopping Vm
+
+        final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId());
+        if (router == null) {
+            return;
+        }
+
+        final String privateIP = router.getPrivateIpAddress();
+
+        if (privateIP != null) {
+            final boolean forVpc = router.getVpcId() != null;
+            final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
+            for (final Nic routerNic : routerNics) {
+                final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
+                // Send network usage command for public nic in VPC VR
+                // Send network usage command for isolated guest nic of non VPC
+                // VR
+                if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
+                        && network.getGuestType() == Network.GuestType.Isolated) {
+                    final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());
+                    final String routerType = router.getType().toString();
+                    final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(),
+                            forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
+                    NetworkUsageAnswer answer = null;
+                    try {
+                        answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
+                    } catch (final Exception e) {
+                        s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e);
+                        continue;
+                    }
+
+                    if (answer != null) {
+                        if (!answer.getResult()) {
+                            s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() + "; details: "
+                                    + answer.getDetails());
+                            continue;
+                        }
+                        try {
+                            if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) {
+                                s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
+                                continue;
+                            }
+
+                            final NetworkUsageAnswer answerFinal = answer;
+                            Transaction.execute(new TransactionCallbackNoReturn() {
+                                @Override
+                                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                                    final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(),
+                                            forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
+                                    if (stats == null) {
+                                        s_logger.warn("unable to find stats for account: " + router.getAccountId());
+                                        return;
+                                    }
+
+                                    if (previousStats != null
+                                            && (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats
+                                            .getCurrentBytesSent())) {
+                                        s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: "
+                                                + answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent());
+                                        return;
+                                    }
+
+                                    if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Received # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Router: "
+                                                    + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived());
+                                        }
+                                        stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
+                                    }
+                                    stats.setCurrentBytesReceived(answerFinal.getBytesReceived());
+                                    if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Received # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Router: "
+                                                    + answerFinal.getRouterName() + " Reported: " + answerFinal.getBytesSent() + " Stored: " + stats.getCurrentBytesSent());
+                                        }
+                                        stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
+                                    }
+                                    stats.setCurrentBytesSent(answerFinal.getBytesSent());
+                                    if (!_dailyOrHourly) {
+                                        // update agg bytes
+                                        stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
+                                        stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
+                                    }
+                                    _userStatsDao.update(stats.getId(), stats);
+                                }
+                            });
+                        } catch (final Exception e) {
+                            s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: "
+                                    + answer.getBytesSent());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public VirtualRouter findRouter(final long routerId) {
+        return _routerDao.findById(routerId);
+    }
+
+    @Override
+    public List<Long> upgradeRouterTemplate(final UpgradeRouterTemplateCmd cmd) {
+
+        List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>();
+        int params = 0;
+
+        final Long routerId = cmd.getId();
+        if (routerId != null) {
+            params++;
+            final DomainRouterVO router = _routerDao.findById(routerId);
+            if (router != null) {
+                routers.add(router);
+            }
+        }
+
+        final Long domainId = cmd.getDomainId();
+        if (domainId != null) {
+            final String accountName = cmd.getAccount();
+            // List by account, if account Name is specified along with domainId
+            if (accountName != null) {
+                final Account account = _accountMgr.getActiveAccountByName(accountName, domainId);
+                if (account == null) {
+                    throw new InvalidParameterValueException("Account :" + accountName + " does not exist in domain: " + domainId);
+                }
+                routers = _routerDao.listRunningByAccountId(account.getId());
+            } else {
+                // List by domainId, account name not specified
+                routers = _routerDao.listRunningByDomain(domainId);
+            }
+            params++;
+        }
+
+        final Long clusterId = cmd.getClusterId();
+        if (clusterId != null) {
+            params++;
+            routers = _routerDao.listRunningByClusterId(clusterId);
+        }
+
+        final Long podId = cmd.getPodId();
+        if (podId != null) {
+            params++;
+            routers = _routerDao.listRunningByPodId(podId);
+        }
+
+        final Long zoneId = cmd.getZoneId();
+        if (zoneId != null) {
+            params++;
+            routers = _routerDao.listRunningByDataCenter(zoneId);
+        }
+
+        if (params > 1) {
+            throw new InvalidParameterValueException("Multiple parameters not supported. Specify only one among routerId/zoneId/podId/clusterId/accountId/domainId");
+        }
+
+        if (routers != null) {
+            return rebootRouters(routers);
+        }
+
+        return null;
+    }
+
+    private List<Long> rebootRouters(final List<DomainRouterVO> routers) {
+        final List<Long> jobIds = new ArrayList<Long>();
+        for (final DomainRouterVO router : routers) {
+            if (!_nwHelper.checkRouterVersion(router)) {
+                s_logger.debug("Upgrading template for router: " + router.getId());
+                final Map<String, String> params = new HashMap<String, String>();
+                params.put("ctxUserId", "1");
+                params.put("ctxAccountId", "" + router.getAccountId());
+
+                final RebootRouterCmd cmd = new RebootRouterCmd();
+                ComponentContext.inject(cmd);
+                params.put("id", "" + router.getId());
+                params.put("ctxStartEventId", "1");
+                final AsyncJobVO job = new AsyncJobVO("", User.UID_SYSTEM, router.getAccountId(), RebootRouterCmd.class.getName(), ApiGsonHelper.getBuilder().create().toJson(params),
+                        router.getId(), cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null, null);
+                job.setDispatcher(_asyncDispatcher.getName());
+                final long jobId = _asyncMgr.submitAsyncJob(job);
+                jobIds.add(jobId);
+            } else {
+                s_logger.debug("Router: " + router.getId() + " is already at the latest version. No upgrade required");
+            }
+        }
+        return jobIds;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VirtualNetworkApplianceManagerImpl.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] { UseExternalDnsServers, routerVersionCheckEnabled, SetServiceMonitor, RouterAlertsCheckInterval };
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(final VirtualMachine.State oldState, final VirtualMachine.Event event, final VirtualMachine.State newState, final VirtualMachine vo, final boolean status,
+            final Object opaque) {
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(final StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, final VirtualMachine vo, final boolean status, final Object opaque) {
+        final VirtualMachine.State newState = transition.getToState();
+        final VirtualMachine.Event event = transition.getEvent();
+        if (vo.getType() == VirtualMachine.Type.DomainRouter &&
+                event == VirtualMachine.Event.FollowAgentPowerOnReport &&
+                newState == VirtualMachine.State.Running &&
+                isOutOfBandMigrated(opaque)) {
+            s_logger.debug("Virtual router " + vo.getInstanceName() + " is powered-on out-of-band");
+        }
+
+        return true;
+    }
+
+    private boolean isOutOfBandMigrated(final Object opaque) {
+        // opaque -> <hostId, powerHostId>
+        if (opaque != null && opaque instanceof Pair<?, ?>) {
+            final Pair<?, ?> pair = (Pair<?, ?>)opaque;
+            final Object first = pair.first();
+            final Object second = pair.second();
+            // powerHostId cannot be null in case of out-of-band VM movement
+            if (second != null && second instanceof Long) {
+                final Long powerHostId = (Long)second;
+                Long hostId = null;
+                if (first != null && first instanceof Long) {
+                    hostId = (Long)first;
+                }
+                // The following scenarios are due to out-of-band VM movement
+                // 1. If VM is in stopped state in CS due to 'PowerMissing' report from old host (hostId is null) and then there is a 'PowerOn' report from new host
+                // 2. If VM is in running state in CS and there is a 'PowerOn' report from new host
+                if (hostId == null || hostId.longValue() != powerHostId.longValue()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    protected boolean aggregationExecution(final AggregationControlCommand.Action action, final Network network, final List<DomainRouterVO> routers)
+            throws AgentUnavailableException, ResourceUnavailableException {
+
+        int errors = 0;
+
+        for (final DomainRouterVO router : routers) {
+
+            final String routerControlIp = _routerControlHelper.getRouterControlIp(router.getId());
+            final String routerIpInNetwork = _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId());
+
+            if (routerIpInNetwork == null) {
+                // Nic hasn't been created in this router yet. Try to configure the next one.
+                s_logger.warn("The Network is not configured in the router " + router.getHostName() + " yet. Try the next router!");
+                errors++;
+                continue;
+            }
+
+            final AggregationControlCommand cmd = new AggregationControlCommand(action, router.getInstanceName(), routerControlIp, routerIpInNetwork);
+            final Commands cmds = new Commands(cmd);
+            if (!_nwHelper.sendCommandsToRouter(router, cmds)) {
+                return false;
+            }
+        }
+        if (errors == routers.size()) {
+            s_logger.error("aggregationExecution() on " + getClass().getName() + " failed! Network is not configured in any router.");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepareAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException, ResourceUnavailableException {
+        return aggregationExecution(Action.Start, network, routers);
+    }
+
+    @Override
+    public boolean completeAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException, ResourceUnavailableException {
+        return aggregationExecution(Action.Finish, network, routers);
+    }
+}
diff --git a/server/src/com/cloud/network/router/VpcNetworkHelperImpl.java b/server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java
similarity index 100%
rename from server/src/com/cloud/network/router/VpcNetworkHelperImpl.java
rename to server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
similarity index 100%
rename from server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
rename to server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
diff --git a/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
new file mode 100644
index 0000000..80b1797
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -0,0 +1,786 @@
+// 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.network.router;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.Command.OnError;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
+import com.cloud.agent.manager.Commands;
+import com.cloud.dc.DataCenter;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.RemoteAccessVpn;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.RemoteAccessVpnVO;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.PrivateIpAddress;
+import com.cloud.network.vpc.PrivateIpVO;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.StaticRouteProfile;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcGateway;
+import com.cloud.network.vpc.VpcGatewayVO;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpc.dao.StaticRouteDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.user.UserStatisticsVO;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+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;
+
+@Component
+public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager {
+    private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
+
+    @Inject
+    private NetworkACLManager _networkACLMgr;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private StaticRouteDao _staticRouteDao;
+    @Inject
+    private VpcManager _vpcMgr;
+    @Inject
+    private PrivateIpDao _privateIpDao;
+    @Inject
+    private Site2SiteVpnManager _s2sVpnMgr;
+    @Inject
+    private VpcGatewayDao _vpcGatewayDao;
+    @Inject
+    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 {
+        _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this);
+        return super.configure(name, params);
+    }
+
+    @Override
+    public boolean addVpcRouterToGuestNetwork(final VirtualRouter router, final Network network, final Map<VirtualMachineProfile.Param, Object> params)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
+            return false;
+        }
+
+        // Add router to the Guest network
+        boolean result = true;
+        try {
+
+            // 1) add nic to the router
+            _routerDao.addRouterToGuestNetwork(router, network);
+
+            final NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null);
+            // 2) setup guest network
+            if (guestNic != null) {
+                result = setupVpcGuestNetwork(network, router, true, guestNic);
+            } else {
+                s_logger.warn("Failed to add router " + router + " to guest network " + network);
+                result = false;
+            }
+            // 3) apply networking rules
+            if (result && params.get(Param.ReProgramGuestNetworks) != null && (Boolean) params.get(Param.ReProgramGuestNetworks) == true) {
+                sendNetworkRulesToRouter(router.getId(), network.getId());
+            }
+        } catch (final Exception ex) {
+            s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex);
+            result = false;
+        } finally {
+            if (!result) {
+                s_logger.debug("Removing the router " + router + " from network " + network + " as a part of cleanup");
+                if (removeVpcRouterFromGuestNetwork(router, network)) {
+                    s_logger.debug("Removed the router " + router + " from network " + network + " as a part of cleanup");
+                } else {
+                    s_logger.warn("Failed to remove the router " + router + " from network " + network + " as a part of cleanup");
+                }
+            } else {
+                s_logger.debug("Succesfully added router " + router + " to guest network " + network);
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean removeVpcRouterFromGuestNetwork(final VirtualRouter router, final Network network) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+        if (network.getTrafficType() != TrafficType.Guest) {
+            s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
+            return false;
+        }
+
+        boolean result = true;
+        try {
+            // Check if router is a part of the Guest network
+            if (!_networkModel.isVmPartOfNetwork(router.getId(), network.getId())) {
+                s_logger.debug("Router " + router + " is not a part of the Guest network " + network);
+                return result;
+            }
+
+            result = setupVpcGuestNetwork(network, router, false, _networkModel.getNicProfile(router, network.getId(), null));
+            if (!result) {
+                s_logger.warn("Failed to destroy guest network config " + network + " on router " + router);
+                return false;
+            }
+
+            result = result && _itMgr.removeVmFromNetwork(router, network, null);
+        } finally {
+            if (result) {
+                _routerDao.removeRouterFromGuestNetwork(router.getId(), network.getId());
+            }
+        }
+
+        return result;
+    }
+
+    protected boolean setupVpcGuestNetwork(final Network network, final VirtualRouter router, final boolean add, final NicProfile guestNic) throws ConcurrentOperationException,
+    ResourceUnavailableException {
+
+        boolean result = true;
+        if (router.getState() == State.Running) {
+            final SetupGuestNetworkCommand setupCmd = _commandSetupHelper.createSetupGuestNetworkCommand((DomainRouterVO) router, add, guestNic);
+
+            final Commands cmds = new Commands(Command.OnError.Stop);
+            cmds.addCommand("setupguestnetwork", setupCmd);
+            _nwHelper.sendCommandsToRouter(router, cmds);
+
+            final Answer setupAnswer = cmds.getAnswer("setupguestnetwork");
+            final String setup = add ? "set" : "destroy";
+            if (!(setupAnswer != null && setupAnswer.getResult())) {
+                s_logger.warn("Unable to " + setup + " guest network on router " + router);
+                result = false;
+            }
+            return result;
+        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
+            s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending setup guest network command to the backend");
+            return true;
+        } else {
+            s_logger.warn("Unable to setup guest network on virtual router " + router + " is not in the right state " + router.getState());
+            throw new ResourceUnavailableException("Unable to setup guest network on the backend," + " virtual router " + router + " is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) {
+        final DomainRouterVO domainRouterVO = _routerDao.findById(profile.getId());
+
+        final Long vpcId = domainRouterVO.getVpcId();
+
+        if (vpcId != null) {
+            if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
+                String defaultDns1 = null;
+                String defaultDns2 = null;
+                // remove public and guest nics as we will plug them later
+                final Iterator<NicProfile> it = profile.getNics().iterator();
+                while (it.hasNext()) {
+                    final NicProfile nic = it.next();
+                    if (nic.getTrafficType() == TrafficType.Public || nic.getTrafficType() == TrafficType.Guest) {
+                        // save dns information
+                        if (nic.getTrafficType() == TrafficType.Public) {
+                            defaultDns1 = nic.getIPv4Dns1();
+                            defaultDns2 = nic.getIPv4Dns2();
+                        }
+                        s_logger.debug("Removing nic " + nic + " of type " + nic.getTrafficType() + " from the nics passed on vm start. " + "The nic will be plugged later");
+                        it.remove();
+                    }
+                }
+
+                // add vpc cidr/dns/networkdomain to the boot load args
+                final StringBuilder buf = profile.getBootArgsBuilder();
+                final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+                buf.append(" vpccidr=" + vpc.getCidr() + " domain=" + vpc.getNetworkDomain());
+
+                buf.append(" dns1=").append(defaultDns1);
+                if (defaultDns2 != null) {
+                    buf.append(" dns2=").append(defaultDns2);
+                }
+
+                VpcGatewayVO privateGatewayForVpc = _vpcGatewayDao.getPrivateGatewayForVpc(domainRouterVO.getVpcId());
+                if (privateGatewayForVpc != null) {
+                    String ip4Address = privateGatewayForVpc.getIp4Address();
+                    buf.append(" privategateway=").append(ip4Address);
+                    s_logger.debug("Set privategateway field in cmd_line.json to " + ip4Address);
+                } else {
+                    buf.append(" privategateway=None");
+                }
+            }
+        }
+
+        return super.finalizeVirtualMachineProfile(profile, dest, context);
+    }
+
+    @Override
+    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);
+        }
+
+        if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
+            // 1) FORM SSH CHECK COMMAND
+            final NicProfile controlNic = getControlNic(profile);
+            if (controlNic == null) {
+                s_logger.error("Control network doesn't exist for the router " + domainRouterVO);
+                return false;
+            }
+
+            finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, domainRouterVO, controlNic);
+
+            // 2) FORM PLUG NIC COMMANDS
+            final List<Pair<Nic, Network>> guestNics = new ArrayList<Pair<Nic, Network>>();
+            final List<Pair<Nic, Network>> publicNics = new ArrayList<Pair<Nic, Network>>();
+            final Map<String, String> vlanMacAddress = new HashMap<String, String>();
+
+            final List<? extends Nic> routerNics = _nicDao.listByVmIdOrderByDeviceId(profile.getId());
+            for (final Nic routerNic : routerNics) {
+                final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
+                if (network.getTrafficType() == TrafficType.Guest) {
+                    final Pair<Nic, Network> guestNic = new Pair<Nic, Network>(routerNic, network);
+                    guestNics.add(guestNic);
+                } else if (network.getTrafficType() == TrafficType.Public) {
+                    final Pair<Nic, Network> publicNic = new Pair<Nic, Network>(routerNic, network);
+                    publicNics.add(publicNic);
+                    final String vlanTag = BroadcastDomainType.getValue(routerNic.getBroadcastUri());
+                    vlanMacAddress.put(vlanTag, routerNic.getMacAddress());
+                }
+            }
+
+            final List<Command> usageCmds = new ArrayList<Command>();
+
+            // 3) PREPARE PLUG NIC COMMANDS
+            try {
+                // add VPC router to public networks
+                final List<PublicIp> sourceNat = new ArrayList<PublicIp>(1);
+                for (final Pair<Nic, Network> nicNtwk : publicNics) {
+                    final Nic publicNic = nicNtwk.first();
+                    final Network publicNtwk = nicNtwk.second();
+                    final IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), publicNic.getIPv4Address());
+
+                    if (userIp.isSourceNat()) {
+                        final PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                        sourceNat.add(publicIp);
+
+                        if (domainRouterVO.getPublicIpAddress() == null) {
+                            final DomainRouterVO routerVO = _routerDao.findById(domainRouterVO.getId());
+                            routerVO.setPublicIpAddress(publicNic.getIPv4Address());
+                            routerVO.setPublicNetmask(publicNic.getIPv4Netmask());
+                            routerVO.setPublicMacAddress(publicNic.getMacAddress());
+                            _routerDao.update(routerVO.getId(), routerVO);
+                        }
+                    }
+                    final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, publicNic.getNetworkId(), publicNic.getBroadcastUri().toString()),
+                            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());
+                    usageCmds.add(netUsageCmd);
+                    UserStatisticsVO stats = _userStatsDao.findBy(domainRouterVO.getAccountId(), domainRouterVO.getDataCenterId(), publicNtwk.getId(), publicNic.getIPv4Address(), domainRouterVO.getId(),
+                            domainRouterVO.getType().toString());
+                    if (stats == null) {
+                        stats = new UserStatisticsVO(domainRouterVO.getAccountId(), domainRouterVO.getDataCenterId(), publicNic.getIPv4Address(), domainRouterVO.getId(), domainRouterVO.getType().toString(),
+                                publicNtwk.getId());
+                        _userStatsDao.persist(stats);
+                    }
+                }
+
+                // create ip assoc for source nat
+                if (!sourceNat.isEmpty()) {
+                    _commandSetupHelper.createVpcAssociatePublicIPCommands(domainRouterVO, sourceNat, cmds, vlanMacAddress);
+                }
+
+                // add VPC router to guest networks
+                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(), details);
+                    cmds.addCommand(plugNicCmd);
+                    if (!_networkModel.isPrivateGateway(guestNic.getNetworkId())) {
+                        // set guest network
+                        final VirtualMachine vm = _vmDao.findById(domainRouterVO.getId());
+                        final NicProfile nicProfile = _networkModel.getNicProfile(vm, guestNic.getNetworkId(), null);
+                        final SetupGuestNetworkCommand setupCmd = _commandSetupHelper.createSetupGuestNetworkCommand(domainRouterVO, true, nicProfile);
+                        cmds.addCommand(setupCmd);
+                    } else {
+
+                        // set private network
+                        final PrivateIpVO ipVO = _privateIpDao.findByIpAndSourceNetworkId(guestNic.getNetworkId(), guestNic.getIPv4Address());
+                        final Network network = _networkDao.findById(guestNic.getNetworkId());
+                        BroadcastDomainType.getValue(network.getBroadcastUri());
+                        final String netmask = NetUtils.getCidrNetmask(network.getCidr());
+                        final PrivateIpAddress ip = new PrivateIpAddress(ipVO, network.getBroadcastUri().toString(), network.getGateway(), netmask, guestNic.getMacAddress());
+
+                        final List<PrivateIpAddress> privateIps = new ArrayList<PrivateIpAddress>(1);
+                        privateIps.add(ip);
+                        _commandSetupHelper.createVpcAssociatePrivateIPCommands(domainRouterVO, privateIps, cmds, true);
+
+                        final Long privateGwAclId = _vpcGatewayDao.getNetworkAclIdForPrivateIp(ipVO.getVpcId(), ipVO.getNetworkId(), ipVO.getIpAddress());
+
+                        if (privateGwAclId != null) {
+                            // set network acl on private gateway
+                            final List<NetworkACLItemVO> networkACLs = _networkACLItemDao.listByACL(privateGwAclId);
+                            s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + domainRouterVO + " start for private gateway ip = "
+                                    + ipVO.getIpAddress());
+
+                            _commandSetupHelper.createNetworkACLsCommands(networkACLs, domainRouterVO, cmds, ipVO.getNetworkId(), true);
+                        }
+                    }
+                }
+            } catch (final Exception ex) {
+                s_logger.warn("Failed to add router " + domainRouterVO + " to network due to exception ", ex);
+                return false;
+            }
+
+            // 4) RE-APPLY ALL STATIC ROUTE RULES
+            final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(domainRouterVO.getVpcId());
+            final List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
+            final Map<Long, VpcGateway> gatewayMap = new HashMap<Long, VpcGateway>();
+            for (final StaticRoute route : routes) {
+                VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId());
+                if (gateway == null) {
+                    gateway = _entityMgr.findById(VpcGateway.class, route.getVpcGatewayId());
+                    gatewayMap.put(gateway.getId(), gateway);
+                }
+                staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
+            }
+
+            s_logger.debug("Found " + staticRouteProfiles.size() + " static routes to apply as a part of vpc route " + domainRouterVO + " start");
+            if (!staticRouteProfiles.isEmpty()) {
+                _commandSetupHelper.createStaticRouteCommands(staticRouteProfiles, domainRouterVO, cmds);
+            }
+
+            // 5) RE-APPLY ALL REMOTE ACCESS VPNs
+            final RemoteAccessVpnVO vpn = _vpnDao.findByAccountAndVpc(domainRouterVO.getAccountId(), domainRouterVO.getVpcId());
+            if (vpn != null) {
+                _commandSetupHelper.createApplyVpnCommands(true, vpn, domainRouterVO, cmds);
+            }
+
+            // 6) REPROGRAM GUEST NETWORK
+            boolean reprogramGuestNtwks = true;
+            if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
+                reprogramGuestNtwks = false;
+            }
+
+            final VirtualRouterProvider vrProvider = _vrProviderDao.findById(domainRouterVO.getElementId());
+            if (vrProvider == null) {
+                throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + domainRouterVO.getHostName());
+            }
+            final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
+            if (provider == null) {
+                throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
+            }
+
+            for (final Pair<Nic, Network> nicNtwk : guestNics) {
+                final Nic guestNic = nicNtwk.first();
+                final AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, domainRouterVO.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
+                        guestNic.getNetworkId(), domainRouterVO.getId()));
+                cmds.addCommand(startCmd);
+                if (reprogramGuestNtwks) {
+                    finalizeIpAssocForNetwork(cmds, domainRouterVO, provider, guestNic.getNetworkId(), vlanMacAddress);
+                    finalizeNetworkRulesForNetwork(cmds, domainRouterVO, provider, guestNic.getNetworkId());
+                }
+
+                finalizeUserDataAndDhcpOnStart(cmds, domainRouterVO, provider, guestNic.getNetworkId());
+                final AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, domainRouterVO.getInstanceName(), controlNic.getIPv4Address(), _routerControlHelper.getRouterIpInNetwork(
+                        guestNic.getNetworkId(), domainRouterVO.getId()));
+                cmds.addCommand(finishCmd);
+            }
+
+            // Add network usage commands
+            cmds.addCommands(usageCmds);
+        }
+        return true;
+    }
+
+    @Override
+    protected void finalizeNetworkRulesForNetwork(final Commands cmds, final DomainRouterVO domainRouterVO, final Provider provider, final Long guestNetworkId) {
+
+        super.finalizeNetworkRulesForNetwork(cmds, domainRouterVO, provider, guestNetworkId);
+
+        if (domainRouterVO.getVpcId() != null) {
+
+            if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
+                if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.NetworkACL, Provider.VPCVirtualRouter)) {
+                    final List<NetworkACLItemVO> networkACLs = _networkACLMgr.listNetworkACLItems(guestNetworkId);
+                    if (networkACLs != null && !networkACLs.isEmpty()) {
+                        s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + domainRouterVO + " start for guest network id=" + guestNetworkId);
+                        _commandSetupHelper.createNetworkACLsCommands(networkACLs, domainRouterVO, cmds, guestNetworkId, false);
+                    }
+                }
+            }
+        }
+    }
+
+    protected boolean sendNetworkRulesToRouter(final long routerId, final long networkId) throws ResourceUnavailableException {
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        final Commands cmds = new Commands(OnError.Continue);
+
+        final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
+        if (vrProvider == null) {
+            throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
+        }
+        final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
+        if (provider == null) {
+            throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
+        }
+
+        finalizeNetworkRulesForNetwork(cmds, router, provider, networkId);
+        return _nwHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    /**
+     * @param router
+     * @param add
+     * @param privateNic
+     * @return
+     * @throws ResourceUnavailableException
+     */
+    protected boolean setupVpcPrivateNetwork(final VirtualRouter router, final boolean add, final NicProfile privateNic) throws ResourceUnavailableException {
+
+        if (router.getState() == State.Running) {
+            final PrivateIpVO ipVO = _privateIpDao.findByIpAndSourceNetworkId(privateNic.getNetworkId(), privateNic.getIPv4Address());
+            final Network network = _networkDao.findById(privateNic.getNetworkId());
+            final String netmask = NetUtils.getCidrNetmask(network.getCidr());
+            final PrivateIpAddress ip = new PrivateIpAddress(ipVO, network.getBroadcastUri().toString(), network.getGateway(), netmask, privateNic.getMacAddress());
+
+            final List<PrivateIpAddress> privateIps = new ArrayList<PrivateIpAddress>(1);
+            privateIps.add(ip);
+            final Commands cmds = new Commands(Command.OnError.Stop);
+            _commandSetupHelper.createVpcAssociatePrivateIPCommands(router, privateIps, cmds, add);
+
+            try {
+                if (_nwHelper.sendCommandsToRouter(router, cmds)) {
+                    s_logger.debug("Successfully applied ip association for ip " + ip + " in vpc network " + network);
+                    return true;
+                } else {
+                    s_logger.warn("Failed to associate ip address " + ip + " in vpc network " + network);
+                    return false;
+                }
+            } catch (final Exception ex) {
+                s_logger.warn("Failed to send  " + (add ? "add " : "delete ") + " private network " + network + " commands to rotuer ");
+                return false;
+            }
+        } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) {
+            s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending setup private network command to the backend");
+        } else {
+            s_logger.warn("Unable to setup private gateway, virtual router " + router + " is not in the right state " + router.getState());
+
+            throw new ResourceUnavailableException("Unable to setup Private gateway on the backend," + " virtual router " + router + " is not in the right state",
+                    DataCenter.class, router.getDataCenterId());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean destroyPrivateGateway(final PrivateGateway gateway, final VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
+        boolean result = true;
+
+        if (!_networkModel.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) {
+            s_logger.debug("Router doesn't have nic for gateway " + gateway + " so no need to removed it");
+            return result;
+        }
+
+        final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());
+        final NicProfile nicProfile = _networkModel.getNicProfile(router, privateNetwork.getId(), null);
+
+        s_logger.debug("Releasing private ip for gateway " + gateway + " from " + router);
+        result = setupVpcPrivateNetwork(router, false, nicProfile);
+        if (!result) {
+            s_logger.warn("Failed to release private ip for gateway " + gateway + " on router " + router);
+            return false;
+        }
+
+        // revoke network acl on the private gateway.
+        if (!_networkACLMgr.revokeACLItemsForPrivateGw(gateway)) {
+            s_logger.debug("Failed to delete network acl items on " + gateway + " from router " + router);
+            return false;
+        }
+
+        s_logger.debug("Removing router " + router + " from private network " + privateNetwork + " as a part of delete private gateway");
+        result = result && _itMgr.removeVmFromNetwork(router, privateNetwork, null);
+        s_logger.debug("Private gateawy " + gateway + " is removed from router " + router);
+        return result;
+    }
+
+    @Override
+    protected void finalizeIpAssocForNetwork(final Commands cmds, final VirtualRouter domainRouterVO, final Provider provider, final Long guestNetworkId,
+            final Map<String, String> vlanMacAddress) {
+
+        if (domainRouterVO.getVpcId() == null) {
+            super.finalizeIpAssocForNetwork(cmds, domainRouterVO, provider, guestNetworkId, vlanMacAddress);
+            return;
+        }
+
+        if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
+            final ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(domainRouterVO, provider, guestNetworkId, IpAddress.State.Releasing);
+
+            if (publicIps != null && !publicIps.isEmpty()) {
+                s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + domainRouterVO + " start.");
+                // Re-apply public ip addresses - should come before PF/LB/VPN
+                _commandSetupHelper.createVpcAssociatePublicIPCommands(domainRouterVO, publicIps, cmds, vlanMacAddress);
+            }
+        }
+    }
+
+    @Override
+    public boolean startSite2SiteVpn(final Site2SiteVpnConnection conn, final VirtualRouter router) throws ResourceUnavailableException {
+        if (router.getState() != State.Running) {
+            s_logger.warn("Unable to apply site-to-site VPN configuration, virtual router is not in the right state " + router.getState());
+            throw new ResourceUnavailableException("Unable to apply site 2 site VPN configuration," + " virtual router is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        return applySite2SiteVpn(true, router, conn);
+    }
+
+    @Override
+    public boolean stopSite2SiteVpn(final Site2SiteVpnConnection conn, final VirtualRouter router) throws ResourceUnavailableException {
+        if (router.getState() != State.Running) {
+            s_logger.warn("Unable to apply site-to-site VPN configuration, virtual router is not in the right state " + router.getState());
+            throw new ResourceUnavailableException("Unable to apply site 2 site VPN configuration," + " virtual router is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        return applySite2SiteVpn(false, router, conn);
+    }
+
+    protected boolean applySite2SiteVpn(final boolean isCreate, final VirtualRouter router, final Site2SiteVpnConnection conn) throws ResourceUnavailableException {
+        final Commands cmds = new Commands(Command.OnError.Continue);
+        _commandSetupHelper.createSite2SiteVpnCfgCommands(conn, isCreate, router, cmds);
+        return _nwHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    protected Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> getNicsToChangeOnRouter(final List<? extends PublicIpAddress> publicIps, final VirtualRouter router) {
+        // 1) check which nics need to be plugged/unplugged and plug/unplug them
+
+        final Map<String, PublicIpAddress> nicsToPlug = new HashMap<String, PublicIpAddress>();
+        final Map<String, PublicIpAddress> nicsToUnplug = new HashMap<String, PublicIpAddress>();
+
+        // find out nics to unplug
+        for (final PublicIpAddress ip : publicIps) {
+            final long publicNtwkId = ip.getNetworkId();
+
+            // if ip is not associated to any network, and there are no firewall
+            // rules, release it on the backend
+            if (!_vpcMgr.isIpAllocatedToVpc(ip)) {
+                ip.setState(IpAddress.State.Releasing);
+            }
+
+            if (ip.getState() == IpAddress.State.Releasing) {
+                final Nic nic = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), ip.getAddress().addr());
+                if (nic != null) {
+                    nicsToUnplug.put(ip.getVlanTag(), ip);
+                    s_logger.debug("Need to unplug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId);
+                }
+            }
+        }
+
+        // find out nics to plug
+        for (final PublicIpAddress ip : publicIps) {
+            final URI broadcastUri = BroadcastDomainType.Vlan.toUri(ip.getVlanTag());
+            final long publicNtwkId = ip.getNetworkId();
+
+            // if ip is not associated to any network, and there are no firewall
+            // rules, release it on the backend
+            if (!_vpcMgr.isIpAllocatedToVpc(ip)) {
+                ip.setState(IpAddress.State.Releasing);
+            }
+
+            if (ip.getState() == IpAddress.State.Allocated || ip.getState() == IpAddress.State.Allocating) {
+                // nic has to be plugged only when there are no nics for this
+                // vlan tag exist on VR
+                final Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(publicNtwkId, router.getId(), broadcastUri.toString());
+
+                if (nic == null && nicsToPlug.get(ip.getVlanTag()) == null) {
+                    nicsToPlug.put(ip.getVlanTag(), ip);
+                    s_logger.debug("Need to plug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId);
+                } else {
+                    final PublicIpAddress nicToUnplug = nicsToUnplug.get(ip.getVlanTag());
+                    if (nicToUnplug != null) {
+                        final NicVO nicVO = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), nicToUnplug.getAddress().addr());
+                        nicVO.setIPv4Address(ip.getAddress().addr());
+                        _nicDao.update(nicVO.getId(), nicVO);
+                        s_logger.debug("Updated the nic " + nicVO + " with the new ip address " + ip.getAddress().addr());
+                        nicsToUnplug.remove(ip.getVlanTag());
+                    }
+                }
+            }
+        }
+
+        final Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> nicsToChange = new Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>>(nicsToPlug,
+                nicsToUnplug);
+        return nicsToChange;
+    }
+
+    @Override
+    public void finalizeStop(final VirtualMachineProfile profile, final Answer answer) {
+        super.finalizeStop(profile, answer);
+        // Mark VPN connections as Disconnected
+        final DomainRouterVO router = _routerDao.findById(profile.getId());
+        final Long vpcId = router.getVpcId();
+        if (vpcId != null) {
+            _s2sVpnMgr.markDisconnectVpnConnByVpc(vpcId);
+        }
+    }
+
+    @Override
+    public List<DomainRouterVO> getVpcRouters(final long vpcId) {
+        return _routerDao.listByVpcId(vpcId);
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public boolean startRemoteAccessVpn(final RemoteAccessVpn vpn, final VirtualRouter router) throws ResourceUnavailableException {
+        if (router.getState() != State.Running) {
+            s_logger.warn("Unable to apply remote access VPN configuration, virtual router is not in the right state " + router.getState());
+            throw new ResourceUnavailableException("Unable to apply remote access VPN configuration," + " virtual router is not in the right state", DataCenter.class,
+                    router.getDataCenterId());
+        }
+
+        final Commands cmds = new Commands(Command.OnError.Stop);
+        _commandSetupHelper.createApplyVpnCommands(true, vpn, router, cmds);
+
+        try {
+            _agentMgr.send(router.getHostId(), cmds);
+        } catch (final OperationTimedoutException e) {
+            s_logger.debug("Failed to start remote access VPN: ", e);
+            throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
+        }
+        Answer answer = cmds.getAnswer("users");
+        if (answer == null || !answer.getResult()) {
+            String errorMessage = (answer == null) ? "null answer object" : answer.getDetails();
+            s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                    + router.getInstanceName() + " due to " + errorMessage);
+            throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
+            + " on domR: " + router.getInstanceName() + " due to " + errorMessage, DataCenter.class, router.getDataCenterId());
+        }
+        answer = cmds.getAnswer("startVpn");
+        if (answer == null || !answer.getResult()) {
+            String errorMessage = (answer == null) ? "null answer object" : answer.getDetails();
+            s_logger.error("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to "
+                    + errorMessage);
+            throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
+                    + router.getInstanceName() + " due to " + errorMessage, DataCenter.class, router.getDataCenterId());
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stopRemoteAccessVpn(final RemoteAccessVpn vpn, final VirtualRouter router) throws ResourceUnavailableException {
+        boolean result = true;
+
+        if (router.getState() == State.Running) {
+            final Commands cmds = new Commands(Command.OnError.Continue);
+            _commandSetupHelper.createApplyVpnCommands(false, vpn, router, cmds);
+            result = result && _nwHelper.sendCommandsToRouter(router, cmds);
+        } else if (router.getState() == State.Stopped) {
+            s_logger.debug("Router " + router + " is in Stopped state, not sending deleteRemoteAccessVpn command to it");
+        } else {
+            s_logger.warn("Failed to stop remote access VPN: domR " + router + " is not in right state " + router.getState());
+            throw new ResourceUnavailableException("Failed to stop remote access VPN: domR is not in right state " + router.getState(), DataCenter.class,
+                    router.getDataCenterId());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(final StateMachine2.Transition<State, VirtualMachine.Event> transition, final VirtualMachine vo, final boolean status, final Object opaque) {
+        // Without this VirtualNetworkApplianceManagerImpl.postStateTransitionEvent() gets called twice as part of listeners -
+        // once from VpcVirtualNetworkApplianceManagerImpl and once from VirtualNetworkApplianceManagerImpl itself
+        return true;
+    }
+}
diff --git a/server/src/com/cloud/network/rules/AdvancedVpnRules.java b/server/src/main/java/com/cloud/network/rules/AdvancedVpnRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/AdvancedVpnRules.java
rename to server/src/main/java/com/cloud/network/rules/AdvancedVpnRules.java
diff --git a/server/src/com/cloud/network/rules/BasicVpnRules.java b/server/src/main/java/com/cloud/network/rules/BasicVpnRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/BasicVpnRules.java
rename to server/src/main/java/com/cloud/network/rules/BasicVpnRules.java
diff --git a/server/src/com/cloud/network/rules/DhcpEntryRules.java b/server/src/main/java/com/cloud/network/rules/DhcpEntryRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/DhcpEntryRules.java
rename to server/src/main/java/com/cloud/network/rules/DhcpEntryRules.java
diff --git a/server/src/com/cloud/network/rules/DhcpPvlanRules.java b/server/src/main/java/com/cloud/network/rules/DhcpPvlanRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/DhcpPvlanRules.java
rename to server/src/main/java/com/cloud/network/rules/DhcpPvlanRules.java
diff --git a/server/src/com/cloud/network/rules/DhcpSubNetRules.java b/server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/DhcpSubNetRules.java
rename to server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java
diff --git a/server/src/com/cloud/network/rules/FirewallRules.java b/server/src/main/java/com/cloud/network/rules/FirewallRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/FirewallRules.java
rename to server/src/main/java/com/cloud/network/rules/FirewallRules.java
diff --git a/server/src/com/cloud/network/rules/IpAssociationRules.java b/server/src/main/java/com/cloud/network/rules/IpAssociationRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/IpAssociationRules.java
rename to server/src/main/java/com/cloud/network/rules/IpAssociationRules.java
diff --git a/server/src/com/cloud/network/rules/LoadBalancingRules.java b/server/src/main/java/com/cloud/network/rules/LoadBalancingRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/LoadBalancingRules.java
rename to server/src/main/java/com/cloud/network/rules/LoadBalancingRules.java
diff --git a/server/src/com/cloud/network/rules/NetworkAclsRules.java b/server/src/main/java/com/cloud/network/rules/NetworkAclsRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/NetworkAclsRules.java
rename to server/src/main/java/com/cloud/network/rules/NetworkAclsRules.java
diff --git a/server/src/com/cloud/network/rules/NicPlugInOutRules.java b/server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/NicPlugInOutRules.java
rename to server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java
diff --git a/server/src/com/cloud/network/rules/PasswordToRouterRules.java b/server/src/main/java/com/cloud/network/rules/PasswordToRouterRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/PasswordToRouterRules.java
rename to server/src/main/java/com/cloud/network/rules/PasswordToRouterRules.java
diff --git a/server/src/com/cloud/network/rules/PrivateGatewayRules.java b/server/src/main/java/com/cloud/network/rules/PrivateGatewayRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/PrivateGatewayRules.java
rename to server/src/main/java/com/cloud/network/rules/PrivateGatewayRules.java
diff --git a/server/src/com/cloud/network/rules/RuleApplier.java b/server/src/main/java/com/cloud/network/rules/RuleApplier.java
similarity index 100%
rename from server/src/com/cloud/network/rules/RuleApplier.java
rename to server/src/main/java/com/cloud/network/rules/RuleApplier.java
diff --git a/server/src/com/cloud/network/rules/RuleApplierWrapper.java b/server/src/main/java/com/cloud/network/rules/RuleApplierWrapper.java
similarity index 100%
rename from server/src/com/cloud/network/rules/RuleApplierWrapper.java
rename to server/src/main/java/com/cloud/network/rules/RuleApplierWrapper.java
diff --git a/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
new file mode 100644
index 0000000..9dc7a3d
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/rules/RulesManagerImpl.java
@@ -0,0 +1,1630 @@
+// 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.network.rules;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.dao.EventDao;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.LoadBalancerVMMapVO;
+import com.cloud.network.rules.FirewallRule.FirewallRuleType;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRule.State;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcService;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicSecondaryIpDao;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class RulesManagerImpl extends ManagerBase implements RulesManager, RulesService {
+    private static final Logger s_logger = Logger.getLogger(RulesManagerImpl.class);
+
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    PortForwardingRulesDao _portForwardingDao;
+    @Inject
+    FirewallRulesCidrsDao _firewallCidrsDao;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    UserVmDao _vmDao;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    EventDao _eventDao;
+    @Inject
+    UsageEventDao _usageEventDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    FirewallManager _firewallMgr;
+    @Inject
+    DomainManager _domainMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    NicSecondaryIpDao _nicSecondaryDao;
+    @Inject
+    LoadBalancerVMMapDao _loadBalancerVMMapDao;
+    @Inject
+    VpcService _vpcSvc;
+
+    protected void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller, Boolean ignoreVmState) {
+        if (ipAddress == null || ipAddress.getAllocatedTime() == null || ipAddress.getAllocatedToAccountId() == null) {
+            throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified.");
+        }
+
+        if (userVm == null) {
+            return;
+        }
+
+        if (userVm.getState() == VirtualMachine.State.Destroyed || userVm.getState() == VirtualMachine.State.Expunging) {
+            if (!ignoreVmState) {
+                throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
+            }
+        }
+
+        _accountMgr.checkAccess(caller, null, true, ipAddress, userVm);
+
+        // validate that IP address and userVM belong to the same account
+        if (ipAddress.getAllocatedToAccountId().longValue() != userVm.getAccountId()) {
+            throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress +
+                " owner is not the same as owner of virtual machine " + userVm.toString());
+        }
+
+        // validate that userVM is in the same availability zone as the IP address
+        if (ipAddress.getDataCenterId() != userVm.getDataCenterId()) {
+            //make an exception for portable IP
+            if (!ipAddress.isPortable()) {
+                throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress +
+                    " is not in the same availability zone as virtual machine " + userVm.toString());
+            }
+        }
+
+    }
+
+    @Override
+    public void checkRuleAndUserVm(FirewallRule rule, UserVm userVm, Account caller) {
+        if (userVm == null || rule == null) {
+            return;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule, userVm);
+
+        if (userVm.getState() == VirtualMachine.State.Destroyed || userVm.getState() == VirtualMachine.State.Expunging) {
+            throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
+        }
+
+        // This same owner check is actually not needed, since multiple entities OperateEntry trick guarantee that
+        if (rule.getAccountId() != userVm.getAccountId()) {
+            throw new InvalidParameterValueException("New rule " + rule + " and vm id=" + userVm.getId() + " belong to different accounts");
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true)
+    public PortForwardingRule createPortForwardingRule(final PortForwardingRule rule, final Long vmId, Ip vmIp, final boolean openFirewall, final Boolean forDisplay)
+            throws NetworkRuleConflictException {
+        CallContext ctx = CallContext.current();
+        final Account caller = ctx.getCallingAccount();
+
+        final Long ipAddrId = rule.getSourceIpAddressId();
+
+        IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
+
+        // Validate ip address
+        if (ipAddress == null) {
+            throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system");
+        } else if (ipAddress.isOneToOneNat()) {
+            throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled");
+        }
+
+        final Long networkId = rule.getNetworkId();
+        Network network = _networkModel.getNetwork(networkId);
+        //associate ip address to network (if needed)
+        boolean performedIpAssoc = false;
+        Nic guestNic;
+        if (ipAddress.getAssociatedWithNetworkId() == null) {
+            boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
+            if (assignToVpcNtwk) {
+                _networkModel.checkIpForService(ipAddress, Service.PortForwarding, networkId);
+
+                s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
+                try {
+                    ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipAddrId, networkId, false);
+                    performedIpAssoc = true;
+                } catch (Exception ex) {
+                    throw new CloudRuntimeException("Failed to associate ip to VPC network as " + "a part of port forwarding rule creation");
+                }
+            }
+        } else {
+            _networkModel.checkIpForService(ipAddress, Service.PortForwarding, null);
+        }
+
+        if (ipAddress.getAssociatedWithNetworkId() == null) {
+            throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
+        }
+
+        try {
+            _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding,
+                FirewallRuleType.User, networkId, rule.getTrafficType());
+
+            final Long accountId = ipAddress.getAllocatedToAccountId();
+            final Long domainId = ipAddress.getAllocatedInDomainId();
+
+            // start port can't be bigger than end port
+            if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) {
+                throw new InvalidParameterValueException("Start port can't be bigger than end port");
+            }
+
+            // check that the port ranges are of equal size
+            if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) {
+                throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes.");
+            }
+
+            // validate user VM exists
+            UserVm vm = _vmDao.findById(vmId);
+            if (vm == null) {
+                throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" +
+                    vmId + ").");
+            } else if (vm.getState() == VirtualMachine.State.Destroyed || vm.getState() == VirtualMachine.State.Expunging) {
+                throw new InvalidParameterValueException("Invalid user vm: " + vm.getId());
+            }
+
+            // Verify that vm has nic in the network
+            Ip dstIp = rule.getDestinationIpAddress();
+            guestNic = _networkModel.getNicInNetwork(vmId, networkId);
+            if (guestNic == null || guestNic.getIPv4Address() == null) {
+                throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
+            } else {
+                dstIp = new Ip(guestNic.getIPv4Address());
+            }
+
+            if (vmIp != null) {
+                //vm ip is passed so it can be primary or secondary ip addreess.
+                if (!dstIp.equals(vmIp)) {
+                    //the vm ip is secondary ip to the nic.
+                    // is vmIp is secondary ip or not
+                    NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmIp.toString(), guestNic.getId());
+                    if (secondaryIp == null) {
+                        throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
+                    }
+                    dstIp = vmIp;
+                }
+            }
+
+            //if start port and end port are passed in, and they are not equal to each other, perform the validation
+            boolean validatePortRange = false;
+            if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue() || rule.getDestinationPortStart() != rule.getDestinationPortEnd()) {
+                validatePortRange = true;
+            }
+
+            if (validatePortRange) {
+                //source start port and source dest port should be the same. The same applies to dest ports
+                if (rule.getSourcePortStart().intValue() != rule.getDestinationPortStart()) {
+                    throw new InvalidParameterValueException("Private port start should be equal to public port start");
+                }
+
+                if (rule.getSourcePortEnd().intValue() != rule.getDestinationPortEnd()) {
+                    throw new InvalidParameterValueException("Private port end should be equal to public port end");
+                }
+            }
+
+            final Ip dstIpFinal = dstIp;
+            final IPAddressVO ipAddressFinal = ipAddress;
+            return Transaction.execute(new TransactionCallbackWithException<PortForwardingRuleVO, NetworkRuleConflictException>() {
+                @Override
+                public PortForwardingRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+                    PortForwardingRuleVO newRule =
+                        new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIpFinal,
+                            rule.getDestinationPortStart(), rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId);
+
+                    if (forDisplay != null) {
+                        newRule.setDisplay(forDisplay);
+                    }
+                    newRule = _portForwardingDao.persist(newRule);
+
+                    // create firewallRule for 0.0.0.0/0 cidr
+                    if (openFirewall) {
+                        _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null,
+                            newRule.getId(), networkId);
+                    }
+
+                    try {
+                        _firewallMgr.detectRulesConflict(newRule);
+                        if (!_firewallDao.setStateToAdd(newRule)) {
+                            throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+                        }
+                        CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
+                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), ipAddressFinal.getDataCenterId(), newRule.getId(), null,
+                            PortForwardingRule.class.getName(), newRule.getUuid());
+                        return newRule;
+                    } catch (Exception e) {
+                        if (newRule != null) {
+                            // no need to apply the rule as it wasn't programmed on the backend yet
+                            _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
+                            removePFRule(newRule);
+                        }
+
+                        if (e instanceof NetworkRuleConflictException) {
+                            throw (NetworkRuleConflictException)e;
+                        }
+
+                        throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e);
+                    }
+                }
+            });
+
+        } finally {
+            // release ip address if ipassoc was perfored
+            if (performedIpAssoc) {
+                //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+                IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
+                _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
+            }
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating static nat rule", create = true)
+    public StaticNatRule createStaticNatRule(final StaticNatRule rule, final boolean openFirewall) throws NetworkRuleConflictException {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final Long ipAddrId = rule.getSourceIpAddressId();
+
+        IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
+
+        // Validate ip address
+        if (ipAddress == null) {
+            throw new InvalidParameterValueException("Unable to create static nat rule; ip id=" + ipAddrId + " doesn't exist in the system");
+        } else if (ipAddress.isSourceNat() || !ipAddress.isOneToOneNat() || ipAddress.getAssociatedWithVmId() == null) {
+            throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
+        }
+
+        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat,
+            FirewallRuleType.User, null, rule.getTrafficType());
+
+        final Long networkId = ipAddress.getAssociatedWithNetworkId();
+        final Long accountId = ipAddress.getAllocatedToAccountId();
+        final Long domainId = ipAddress.getAllocatedInDomainId();
+
+        _networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
+
+        Network network = _networkModel.getNetwork(networkId);
+        NetworkOffering off = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+        if (off.isElasticIp()) {
+            throw new InvalidParameterValueException("Can't create ip forwarding rules for the network where elasticIP service is enabled");
+        }
+
+        //String dstIp = _networkModel.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId);
+        final String dstIp = ipAddress.getVmIp();
+        return Transaction.execute(new TransactionCallbackWithException<StaticNatRule, NetworkRuleConflictException>() {
+            @Override
+            public StaticNatRule doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
+
+                FirewallRuleVO newRule =
+                    new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(),
+                        networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null);
+
+                newRule = _firewallDao.persist(newRule);
+
+                // create firewallRule for 0.0.0.0/0 cidr
+                if (openFirewall) {
+                    _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null,
+                        newRule.getId(), networkId);
+                }
+
+                try {
+                    _firewallMgr.detectRulesConflict(newRule);
+                    if (!_firewallDao.setStateToAdd(newRule)) {
+                        throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+                    }
+                    CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null, FirewallRule.class.getName(),
+                        newRule.getUuid());
+
+                    StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp);
+
+                    return staticNatRule;
+                } catch (Exception e) {
+                    if (newRule != null) {
+                        // no need to apply the rule as it wasn't programmed on the backend yet
+                        _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false);
+                        _firewallMgr.removeRule(newRule);
+                    }
+
+                    if (e instanceof NetworkRuleConflictException) {
+                        throw (NetworkRuleConflictException)e;
+                    }
+                    throw new CloudRuntimeException("Unable to add static nat rule for the ip id=" + newRule.getSourceIpAddressId(), e);
+                }
+            }
+        });
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ENABLE_STATIC_NAT, eventDescription = "enabling static nat")
+    public boolean enableStaticNat(long ipId, long vmId, long networkId, String vmGuestIp) throws NetworkRuleConflictException, ResourceUnavailableException {
+        return enableStaticNat(ipId, vmId, networkId, false, vmGuestIp);
+    }
+
+    private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm, String vmGuestIp) throws NetworkRuleConflictException,
+        ResourceUnavailableException {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+        CallContext.current().setEventDetails("Ip Id: " + ipId);
+
+        // Verify input parameters
+        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
+        if (ipAddress == null) {
+            throw new InvalidParameterValueException("Unable to find ip address by id " + ipId);
+        }
+
+        // Verify input parameters
+        boolean performedIpAssoc = false;
+        boolean isOneToOneNat = ipAddress.isOneToOneNat();
+        Long associatedWithVmId = ipAddress.getAssociatedWithVmId();
+        Nic guestNic;
+        NicSecondaryIpVO nicSecIp = null;
+        String dstIp = null;
+
+        try {
+            Network network = _networkModel.getNetwork(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find network by id");
+            }
+
+            // Check that vm has a nic in the network
+            guestNic = _networkModel.getNicInNetwork(vmId, networkId);
+            if (guestNic == null) {
+                throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
+            }
+            dstIp = guestNic.getIPv4Address();
+
+            if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
+                throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " + "supported in network with specified id");
+            }
+
+            if (!isSystemVm) {
+                UserVmVO vm = _vmDao.findById(vmId);
+                if (vm == null) {
+                    throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + ", invalid virtual machine id specified (" + vmId +
+                        ").");
+                }
+                //associate ip address to network (if needed)
+                if (ipAddress.getAssociatedWithNetworkId() == null) {
+                    boolean assignToVpcNtwk = network.getVpcId() != null && ipAddress.getVpcId() != null && ipAddress.getVpcId().longValue() == network.getVpcId();
+                    if (assignToVpcNtwk) {
+                        _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
+
+                        s_logger.debug("The ip is not associated with the VPC network id=" + networkId + ", so assigning");
+                        try {
+                            ipAddress = _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, false);
+                        } catch (Exception ex) {
+                            s_logger.warn("Failed to associate ip id=" + ipId + " to VPC network id=" + networkId + " as " + "a part of enable static nat");
+                            return false;
+                        }
+                    }  else if (ipAddress.isPortable()) {
+                        s_logger.info("Portable IP " + ipAddress.getUuid() + " is not associated with the network yet " + " so associate IP with the network " +
+                            networkId);
+                        try {
+                            // check if StaticNat service is enabled in the network
+                            _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
+
+                            // associate portable IP to vpc, if network is part of VPC
+                            if (network.getVpcId() != null) {
+                                _vpcSvc.associateIPToVpc(ipId, network.getVpcId());
+                            }
+
+                            // associate portable IP with guest network
+                            ipAddress = _ipAddrMgr.associatePortableIPToGuestNetwork(ipId, networkId, false);
+                        } catch (Exception e) {
+                            s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + "a part of enable static nat");
+                            return false;
+                        }
+                    }
+                } else  if (ipAddress.getAssociatedWithNetworkId() != networkId) {
+                    if (ipAddress.isPortable()) {
+                        // check if destination network has StaticNat service enabled
+                        _networkModel.checkIpForService(ipAddress, Service.StaticNat, networkId);
+
+                        // check if portable IP can be transferred across the networks
+                        if (_ipAddrMgr.isPortableIpTransferableFromNetwork(ipId, ipAddress.getAssociatedWithNetworkId())) {
+                            try {
+                                // transfer the portable IP and refresh IP details
+                                _ipAddrMgr.transferPortableIP(ipId, ipAddress.getAssociatedWithNetworkId(), networkId);
+                                ipAddress = _ipAddressDao.findById(ipId);
+                            } catch (Exception e) {
+                                s_logger.warn("Failed to associate portable id=" + ipId + " to network id=" + networkId + " as " + "a part of enable static nat");
+                                return false;
+                            }
+                        } else {
+                            throw new InvalidParameterValueException("Portable IP: " + ipId + " has associated services " + "in network " +
+                                ipAddress.getAssociatedWithNetworkId() + " so can not be transferred to " + " network " + networkId);
+                        }
+                    } else {
+                        throw new InvalidParameterValueException("Invalid network Id=" + networkId + ". IP is associated with" +
+                            " a different network than passed network id");
+                    }
+                } else {
+                    _networkModel.checkIpForService(ipAddress, Service.StaticNat, null);
+                }
+
+                if (ipAddress.getAssociatedWithNetworkId() == null) {
+                    throw new InvalidParameterValueException("Ip address " + ipAddress + " is not assigned to the network " + network);
+                }
+
+                // Check permissions
+                if (ipAddress.getSystem()) {
+                    // when system is enabling static NAT on system IP's (for EIP) ignore VM state
+                    checkIpAndUserVm(ipAddress, vm, caller, true);
+                } else {
+                    checkIpAndUserVm(ipAddress, vm, caller, false);
+                }
+
+                //is static nat is for vm secondary ip
+                //dstIp = guestNic.getIp4Address();
+                if (vmGuestIp != null) {
+                    //dstIp = guestNic.getIp4Address();
+
+                    if (!dstIp.equals(vmGuestIp)) {
+                        //check whether the secondary ip set to the vm or not
+                        boolean secondaryIpSet = _networkMgr.isSecondaryIpSetForNic(guestNic.getId());
+                        if (!secondaryIpSet) {
+                            throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
+                        }
+                        //check the ip belongs to the vm or not
+                        nicSecIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmGuestIp, guestNic.getId());
+                        if (nicSecIp == null) {
+                            throw new InvalidParameterValueException("VM ip " + vmGuestIp + " address not belongs to the vm");
+                        }
+                        dstIp = nicSecIp.getIp4Address();
+                         // Set public ip column with the vm ip
+                    }
+                }
+
+                // Verify ip address parameter
+                // checking vm id is not sufficient, check for the vm ip
+                isIpReadyForStaticNat(vmId, ipAddress, dstIp, caller, ctx.getCallingUserId());
+            }
+
+            ipAddress.setOneToOneNat(true);
+            ipAddress.setAssociatedWithVmId(vmId);
+
+            ipAddress.setVmIp(dstIp);
+            if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) {
+                // enable static nat on the backend
+                s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
+                if (applyStaticNatForIp(ipId, false, caller, false)) {
+                    performedIpAssoc = false; // ignor unassignIPFromVpcNetwork in finally block
+                    return true;
+                } else {
+                    s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
+                    ipAddress.setOneToOneNat(isOneToOneNat);
+                    ipAddress.setAssociatedWithVmId(associatedWithVmId);
+                    ipAddress.setVmIp(null);
+                    _ipAddressDao.update(ipAddress.getId(), ipAddress);
+                }
+            } else {
+                s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
+
+            }
+        } finally {
+                if (performedIpAssoc) {
+                    //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
+                    IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
+                    _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
+            }
+        }
+        return false;
+    }
+
+    protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, String vmIp, Account caller, long callerUserId) throws NetworkRuleConflictException,
+        ResourceUnavailableException {
+        if (ipAddress.isSourceNat()) {
+            throw new InvalidParameterValueException("Can't enable static, ip address " + ipAddress + " is a sourceNat ip address");
+        }
+
+        if (!ipAddress.isOneToOneNat()) { // Dont allow to enable static nat if PF/LB rules exist for the IP
+            List<FirewallRuleVO> portForwardingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipAddress.getId(), Purpose.PortForwarding);
+            if (portForwardingRules != null && !portForwardingRules.isEmpty()) {
+                throw new NetworkRuleConflictException("Failed to enable static nat for the ip address " + ipAddress + " as it already has PortForwarding rules assigned");
+            }
+
+            List<FirewallRuleVO> loadBalancingRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipAddress.getId(), Purpose.LoadBalancing);
+            if (loadBalancingRules != null && !loadBalancingRules.isEmpty()) {
+                throw new NetworkRuleConflictException("Failed to enable static nat for the ip address " + ipAddress + " as it already has LoadBalancing rules assigned");
+            }
+        } else if (ipAddress.getAssociatedWithVmId() != null && ipAddress.getAssociatedWithVmId().longValue() != vmId) {
+            throw new NetworkRuleConflictException("Failed to enable static for the ip address " + ipAddress + " and vm id=" + vmId +
+                " as it's already assigned to antoher vm");
+        }
+
+        //check wether the vm ip is alreday associated with any public ip address
+        IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmIdAndVmIp(vmId, vmIp);
+
+        if (oldIP != null) {
+            // If elasticIP functionality is supported in the network, we always have to disable static nat on the old
+            // ip in order to re-enable it on the new one
+            Long networkId = oldIP.getAssociatedWithNetworkId();
+            VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+            boolean reassignStaticNat = false;
+            if (networkId != null) {
+                Network guestNetwork = _networkModel.getNetwork(networkId);
+                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+                if (offering.isElasticIp()) {
+                    reassignStaticNat = true;
+                }
+            }
+
+            // If there is public ip address already associated with the vm, throw an exception
+            if (!reassignStaticNat) {
+                throw new InvalidParameterValueException("Failed to enable static nat on the  ip " +
+                          ipAddress.getAddress()+" with Id " +ipAddress.getUuid()+" as the vm " +vm.getInstanceName() + " with Id " +
+                        vm.getUuid() +" is already associated with another public ip " + oldIP.getAddress() +" with id "+
+                        oldIP.getUuid());
+            }
+        // unassign old static nat rule
+        s_logger.debug("Disassociating static nat for ip " + oldIP);
+        if (!disableStaticNat(oldIP.getId(), caller, callerUserId, true)) {
+                throw new CloudRuntimeException("Failed to disable old static nat rule for vm "+ vm.getInstanceName() +
+                        " with id "+vm.getUuid() +"  and public ip " + oldIP);
+            }
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_DELETE, eventDescription = "revoking forwarding rule", async = true)
+    public boolean revokePortForwardingRule(long ruleId, boolean apply) {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        PortForwardingRuleVO rule = _portForwardingDao.findById(ruleId);
+        if (rule == null) {
+            throw new InvalidParameterValueException("Unable to find " + ruleId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        if (!revokePortForwardingRuleInternal(ruleId, caller, ctx.getCallingUserId(), apply)) {
+            throw new CloudRuntimeException("Failed to delete port forwarding rule");
+        }
+        return true;
+    }
+
+    private boolean revokePortForwardingRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
+        PortForwardingRuleVO rule = _portForwardingDao.findById(ruleId);
+
+        _firewallMgr.revokeRule(rule, caller, userId, true);
+
+        boolean success = false;
+
+        if (apply) {
+            success = applyPortForwardingRules(rule.getSourceIpAddressId(), _ipAddrMgr.RulesContinueOnError.value(), caller);
+        } else {
+            success = true;
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_DELETE, eventDescription = "revoking forwarding rule", async = true)
+    public boolean revokeStaticNatRule(long ruleId, boolean apply) {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        FirewallRuleVO rule = _firewallDao.findById(ruleId);
+        if (rule == null) {
+            throw new InvalidParameterValueException("Unable to find " + ruleId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        if (!revokeStaticNatRuleInternal(ruleId, caller, ctx.getCallingUserId(), apply)) {
+            throw new CloudRuntimeException("Failed to revoke forwarding rule");
+        }
+        return true;
+    }
+
+    private boolean revokeStaticNatRuleInternal(long ruleId, Account caller, long userId, boolean apply) {
+        FirewallRuleVO rule = _firewallDao.findById(ruleId);
+
+        _firewallMgr.revokeRule(rule, caller, userId, true);
+
+        boolean success = false;
+
+        if (apply) {
+            success = applyStaticNatRulesForIp(rule.getSourceIpAddressId(),  _ipAddrMgr.RulesContinueOnError.value(), caller, true);
+        } else {
+            success = true;
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean revokePortForwardingRulesForVm(long vmId) {
+        boolean success = true;
+        UserVmVO vm = _vmDao.findByIdIncludingRemoved(vmId);
+        if (vm == null) {
+            return false;
+        }
+
+        List<PortForwardingRuleVO> rules = _portForwardingDao.listByVm(vmId);
+        Set<Long> ipsToReprogram = new HashSet<Long>();
+
+        if (rules == null || rules.isEmpty()) {
+            s_logger.debug("No port forwarding rules are found for vm id=" + vmId);
+            return true;
+        }
+
+        for (PortForwardingRuleVO rule : rules) {
+            // Mark port forwarding rule as Revoked, but don't revoke it yet (apply=false)
+            revokePortForwardingRuleInternal(rule.getId(), _accountMgr.getSystemAccount(), Account.ACCOUNT_ID_SYSTEM, false);
+            ipsToReprogram.add(rule.getSourceIpAddressId());
+        }
+
+        // apply rules for all ip addresses
+        for (Long ipId : ipsToReprogram) {
+            s_logger.debug("Applying port forwarding rules for ip address id=" + ipId + " as a part of vm expunge");
+            if (!applyPortForwardingRules(ipId,  _ipAddrMgr.RulesContinueOnError.value(), _accountMgr.getSystemAccount())) {
+                s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId);
+                success = false;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public Pair<List<? extends PortForwardingRule>, Integer> listPortForwardingRules(ListPortForwardingRulesCmd cmd) {
+        Long ipId = cmd.getIpAddressId();
+        Long id = cmd.getId();
+        Map<String, String> tags = cmd.getTags();
+        Long networkId = cmd.getNetworkId();
+        Boolean display = cmd.getDisplay();
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        if (ipId != null) {
+            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
+            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
+                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for port forwarding rules yet");
+            }
+            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
+        }
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<PortForwardingRuleVO> sb = _portForwardingDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), Op.EQ);
+        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
+        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
+        sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<PortForwardingRuleVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PortForwardingRule.toString());
+            for (String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        if (ipId != null) {
+            sc.setParameters("ip", ipId);
+        }
+
+        if (networkId != null) {
+            sc.setParameters("networkId", networkId);
+        }
+
+        sc.setParameters("purpose", Purpose.PortForwarding);
+
+        Pair<List<PortForwardingRuleVO>, Integer> result = _portForwardingDao.searchAndCount(sc, filter);
+        return new Pair<List<? extends PortForwardingRule>, Integer>(result.first(), result.second());
+    }
+
+    protected boolean applyPortForwardingRules(long ipId, boolean continueOnError, Account caller) {
+        List<PortForwardingRuleVO> rules = _portForwardingDao.listForApplication(ipId);
+
+        if (rules.size() == 0) {
+            s_logger.debug("There are no port forwarding rules to apply for ip id=" + ipId);
+            return true;
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, rules.toArray(new PortForwardingRuleVO[rules.size()]));
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(rules, continueOnError, true)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply port forwarding rules for ip due to ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    protected boolean applyStaticNatRulesForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
+        List<? extends FirewallRule> rules = _firewallDao.listByIpAndPurpose(sourceIpId, Purpose.StaticNat);
+        List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
+
+        if (rules.size() == 0) {
+            s_logger.debug("There are no static nat rules to apply for ip id=" + sourceIpId);
+            return true;
+        }
+
+        for (FirewallRule rule : rules) {
+            staticNatRules.add(buildStaticNatRule(rule, forRevoke));
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, staticNatRules.toArray(new StaticNatRule[staticNatRules.size()]));
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(staticNatRules, continueOnError, true)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply static nat rules for ip due to ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyPortForwardingRulesForNetwork(long networkId, boolean continueOnError, Account caller) {
+        List<PortForwardingRuleVO> rules = listByNetworkId(networkId);
+        if (rules.size() == 0) {
+            s_logger.debug("There are no port forwarding rules to apply for network id=" + networkId);
+            return true;
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, rules.toArray(new PortForwardingRuleVO[rules.size()]));
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(rules, continueOnError, true)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply port forwarding rules for network due to ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNatRulesForNetwork(long networkId, boolean continueOnError, Account caller) {
+        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
+        List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
+
+        if (rules.size() == 0) {
+            s_logger.debug("There are no static nat rules to apply for network id=" + networkId);
+            return true;
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, rules.toArray(new FirewallRule[rules.size()]));
+        }
+
+        for (FirewallRuleVO rule : rules) {
+            staticNatRules.add(buildStaticNatRule(rule, false));
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(staticNatRules, continueOnError, true)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to apply static nat rules for network due to ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller) {
+        List<IPAddressVO> ips = _ipAddressDao.listStaticNatPublicIps(networkId);
+        if (ips.isEmpty()) {
+            s_logger.debug("There are no static nat to apply for network id=" + networkId);
+            return true;
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, ips.toArray(new IPAddressVO[ips.size()]));
+        }
+
+        List<StaticNat> staticNats = new ArrayList<StaticNat>();
+        for (IPAddressVO ip : ips) {
+            // Get nic IP4 address
+            //String dstIp = _networkModel.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
+            StaticNatImpl staticNat = new StaticNatImpl(ip.getAllocatedToAccountId(), ip.getAllocatedInDomainId(), networkId, ip.getId(), ip.getVmIp(), false);
+            staticNats.add(staticNat);
+        }
+
+        try {
+            if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, false)) {
+                return false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to create static nat for network due to ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public Pair<List<? extends FirewallRule>, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId,
+        Long projectId, boolean isRecursive, boolean listAll) {
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        if (ipId != null) {
+            IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId);
+            if (ipAddressVO == null || !ipAddressVO.readyToUse()) {
+                throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for port forwarding rules yet");
+            }
+            _accountMgr.checkAccess(caller, null, true, ipAddressVO);
+        }
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
+        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        domainId = domainIdRecursiveListProject.first();
+        isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, start, size);
+        SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
+        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
+        sb.and("id", sb.entity().getId(), Op.EQ);
+
+        if (vmId != null) {
+            SearchBuilder<IPAddressVO> ipSearch = _ipAddressDao.createSearchBuilder();
+            ipSearch.and("associatedWithVmId", ipSearch.entity().getAssociatedWithVmId(), Op.EQ);
+            sb.join("ipSearch", ipSearch, sb.entity().getSourceIpAddressId(), ipSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<FirewallRuleVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        sc.setParameters("purpose", Purpose.StaticNat);
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (ipId != null) {
+            sc.setParameters("ip", ipId);
+        }
+
+        if (vmId != null) {
+            sc.setJoinParameters("ipSearch", "associatedWithVmId", vmId);
+        }
+
+        Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
+        return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "applying port forwarding rule", async = true)
+    public boolean applyPortForwardingRules(long ipId, Account caller) throws ResourceUnavailableException {
+        if (!applyPortForwardingRules(ipId, false, caller)) {
+            throw new CloudRuntimeException("Failed to apply port forwarding rule");
+        }
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "applying static nat rule", async = true)
+    public boolean applyStaticNatRules(long ipId, Account caller) throws ResourceUnavailableException {
+        if (!applyStaticNatRulesForIp(ipId, false, caller, false)) {
+            throw new CloudRuntimeException("Failed to apply static nat rule");
+        }
+        return true;
+    }
+
+    @Override
+    public boolean revokeAllPFAndStaticNatRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRule> rules = new ArrayList<FirewallRule>();
+
+        List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByIpAndNotRevoked(ipId);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for ip id=" + ipId);
+        }
+
+        for (PortForwardingRuleVO rule : pfRules) {
+            // Mark all PF rules as Revoke, but don't revoke them yet
+            revokePortForwardingRuleInternal(rule.getId(), caller, userId, false);
+        }
+
+        List<FirewallRuleVO> staticNatRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.StaticNat);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + staticNatRules.size() + " static nat rules for ip id=" + ipId);
+        }
+
+        for (FirewallRuleVO rule : staticNatRules) {
+            // Mark all static nat rules as Revoke, but don't revoke them yet
+            revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
+        }
+
+        boolean success = true;
+
+        // revoke all port forwarding rules
+        success = success && applyPortForwardingRules(ipId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
+
+        // revoke all all static nat rules
+        success = success && applyStaticNatRulesForIp(ipId,  _ipAddrMgr.RulesContinueOnError.value(), caller, true);
+
+        // revoke static nat for the ip address
+        success = success && applyStaticNatForIp(ipId, false, caller, true);
+
+        // Now we check again in case more rules have been inserted.
+        rules.addAll(_portForwardingDao.listByIpAndNotRevoked(ipId));
+        rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.StaticNat));
+
+        if (s_logger.isDebugEnabled() && success) {
+            s_logger.debug("Successfully released rules for ip id=" + ipId + " and # of rules now = " + rules.size());
+        }
+
+        return (rules.size() == 0 && success);
+    }
+
+    @Override
+    public boolean revokeAllPFStaticNatRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRule> rules = new ArrayList<FirewallRule>();
+
+        List<PortForwardingRuleVO> pfRules = _portForwardingDao.listByNetwork(networkId);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + pfRules.size() + " port forwarding rules for network id=" + networkId);
+        }
+
+        List<FirewallRuleVO> staticNatRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.StaticNat);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + staticNatRules.size() + " static nat rules for network id=" + networkId);
+        }
+
+        // Mark all pf rules (Active and non-Active) to be revoked, but don't revoke it yet - pass apply=false
+        for (PortForwardingRuleVO rule : pfRules) {
+            revokePortForwardingRuleInternal(rule.getId(), caller, userId, false);
+        }
+
+        // Mark all static nat rules (Active and non-Active) to be revoked, but don't revoke it yet - pass apply=false
+        for (FirewallRuleVO rule : staticNatRules) {
+            revokeStaticNatRuleInternal(rule.getId(), caller, userId, false);
+        }
+
+        boolean success = true;
+        // revoke all PF rules for the network
+        success = success && applyPortForwardingRulesForNetwork(networkId, true, caller);
+        success = success && applyPortForwardingRulesForNetwork(networkId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
+
+        // revoke all all static nat rules for the network
+        success = success && applyStaticNatRulesForNetwork(networkId, true, caller);
+        success = success && applyStaticNatRulesForNetwork(networkId,  _ipAddrMgr.RulesContinueOnError.value(), caller);
+
+        // Now we check again in case more rules have been inserted.
+        rules.addAll(_portForwardingDao.listByNetworkAndNotRevoked(networkId));
+        rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.StaticNat));
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Successfully released rules for network id=" + networkId + " and # of rules now = " + rules.size());
+        }
+
+        return success && rules.size() == 0;
+    }
+
+    @Override
+    @DB
+    public FirewallRuleVO[] reservePorts(final IpAddress ip, final String protocol, final FirewallRule.Purpose purpose, final boolean openFirewall, final Account caller,
+        final int... ports) throws NetworkRuleConflictException {
+        final FirewallRuleVO[] rules = new FirewallRuleVO[ports.length];
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<NetworkRuleConflictException>() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) throws NetworkRuleConflictException {
+                for (int i = 0; i < ports.length; i++) {
+
+                    rules[i] =
+                        new FirewallRuleVO(null, ip.getId(), ports[i], protocol, ip.getAssociatedWithNetworkId(), ip.getAllocatedToAccountId(),
+                            ip.getAllocatedInDomainId(), purpose, null, null, null, null);
+                    rules[i] = _firewallDao.persist(rules[i]);
+
+                    if (openFirewall) {
+                        _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, rules[i].getId(),
+                            ip.getAssociatedWithNetworkId());
+                    }
+                }
+            }
+        });
+
+        boolean success = false;
+        try {
+            for (FirewallRuleVO newRule : rules) {
+                _firewallMgr.detectRulesConflict(newRule);
+            }
+            success = true;
+            return rules;
+        } finally {
+            if (!success) {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        for (FirewallRuleVO newRule : rules) {
+                            _firewallMgr.removeRule(newRule);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    private List<PortForwardingRuleVO> listByNetworkId(long networkId) {
+        return _portForwardingDao.listByNetwork(networkId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_DISABLE_STATIC_NAT, eventDescription = "disabling static nat", async = true)
+    public boolean disableStaticNat(long ipId) throws ResourceUnavailableException, NetworkRuleConflictException, InsufficientAddressCapacityException {
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
+        checkIpAndUserVm(ipAddress, null, caller, false);
+
+        if (ipAddress.getSystem()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Can't disable static nat for system IP address with specified id");
+            ex.addProxyObject(ipAddress.getUuid(), "ipId");
+            throw ex;
+        }
+
+        Long vmId = ipAddress.getAssociatedWithVmId();
+        if (vmId == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Specified IP address id is not associated with any vm Id");
+            ex.addProxyObject(ipAddress.getUuid(), "ipId");
+            throw ex;
+        }
+
+        // if network has elastic IP functionality supported, we first have to disable static nat on old ip in order to
+        // re-enable it on the new one enable static nat takes care of that
+        Network guestNetwork = _networkModel.getNetwork(ipAddress.getAssociatedWithNetworkId());
+        NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+        if (offering.isElasticIp()) {
+            if (offering.isAssociatePublicIP()) {
+                getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true);
+                return true;
+            }
+        }
+
+        return disableStaticNat(ipId, caller, ctx.getCallingUserId(), false);
+    }
+
+    @Override
+    public boolean disableStaticNat(long ipId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException {
+        boolean success = true;
+
+        IPAddressVO ipAddress = _ipAddressDao.findById(ipId);
+        checkIpAndUserVm(ipAddress, null, caller, false);
+        long networkId = ipAddress.getAssociatedWithNetworkId();
+
+        if (!ipAddress.isOneToOneNat()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("One to one nat is not enabled for the specified ip id");
+            ex.addProxyObject(ipAddress.getUuid(), "ipId");
+            throw ex;
+        }
+
+        ipAddress.setRuleState(IpAddress.State.Releasing);
+        _ipAddressDao.update(ipAddress.getId(), ipAddress);
+        ipAddress = _ipAddressDao.findById(ipId);
+
+        // Revoke all firewall rules for the ip
+        try {
+            s_logger.debug("Revoking all " + Purpose.Firewall + "rules as a part of disabling static nat for public IP id=" + ipId);
+            if (!_firewallMgr.revokeFirewallRulesForIp(ipId, callerUserId, caller)) {
+                s_logger.warn("Unable to revoke all the firewall rules for ip id=" + ipId + " as a part of disable statis nat");
+                success = false;
+            }
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to revoke all firewall rules for ip id=" + ipId + " as a part of ip release", e);
+            success = false;
+        }
+
+        if (!revokeAllPFAndStaticNatRulesForIp(ipId, callerUserId, caller)) {
+            s_logger.warn("Unable to revoke all static nat rules for ip " + ipAddress);
+            success = false;
+        }
+
+        if (success) {
+            boolean isIpSystem = ipAddress.getSystem();
+            ipAddress.setOneToOneNat(false);
+            ipAddress.setAssociatedWithVmId(null);
+            ipAddress.setRuleState(null);
+            ipAddress.setVmIp(null);
+            if (isIpSystem && !releaseIpIfElastic) {
+                ipAddress.setSystem(false);
+            }
+            _ipAddressDao.update(ipAddress.getId(), ipAddress);
+            _vpcMgr.unassignIPFromVpcNetwork(ipAddress.getId(), networkId);
+
+            if (isIpSystem && releaseIpIfElastic && !_ipAddrMgr.handleSystemIpRelease(ipAddress)) {
+                s_logger.warn("Failed to release system ip address " + ipAddress);
+                success = false;
+            }
+
+            return true;
+        } else {
+            s_logger.warn("Failed to disable one to one nat for the ip address id" + ipId);
+            ipAddress = _ipAddressDao.findById(ipId);
+            ipAddress.setRuleState(null);
+            _ipAddressDao.update(ipAddress.getId(), ipAddress);
+            return false;
+        }
+    }
+
+    @Override
+    public StaticNatRule buildStaticNatRule(FirewallRule rule, boolean forRevoke) {
+        IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
+        FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
+
+        if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Source ip address of the specified firewall rule id is not static nat enabled");
+            ex.addProxyObject(ruleVO.getUuid(), "ruleId");
+            throw ex;
+        }
+
+        String dstIp = ip.getVmIp();
+        if (dstIp == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("VM ip address of the specified public ip is not set ");
+            ex.addProxyObject(ruleVO.getUuid(), "ruleId");
+            throw ex;
+        }
+
+        return new StaticNatRuleImpl(ruleVO, dstIp);
+    }
+
+    protected boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
+        IpAddress sourceIp = _ipAddressDao.findById(sourceIpId);
+
+        List<StaticNat> staticNats = createStaticNatForIp(sourceIp, caller, forRevoke);
+
+        if (staticNats != null && !staticNats.isEmpty()) {
+            try {
+                if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, forRevoke)) {
+                    return false;
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to create static nat rule due to ", ex);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke) {
+        List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkId);
+
+        List<StaticNat> staticNats = new ArrayList<StaticNat>();
+        for (IpAddress staticNatIp : staticNatIps) {
+            staticNats.addAll(createStaticNatForIp(staticNatIp, caller, forRevoke));
+        }
+
+        if (staticNats != null && !staticNats.isEmpty()) {
+            if (forRevoke) {
+                s_logger.debug("Found " + staticNats.size() + " static nats to disable for network id " + networkId);
+            }
+            try {
+                if (!_ipAddrMgr.applyStaticNats(staticNats, continueOnError, forRevoke)) {
+                    return false;
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to create static nat rule due to ", ex);
+                return false;
+            }
+        } else {
+            s_logger.debug("Found 0 static nat rules to apply for network id " + networkId);
+        }
+
+        return true;
+    }
+
+    protected List<StaticNat> createStaticNatForIp(IpAddress sourceIp, Account caller, boolean forRevoke) {
+        List<StaticNat> staticNats = new ArrayList<StaticNat>();
+        if (!sourceIp.isOneToOneNat()) {
+            s_logger.debug("Source ip id=" + sourceIp + " is not one to one nat");
+            return staticNats;
+        }
+
+        Long networkId = sourceIp.getAssociatedWithNetworkId();
+        if (networkId == null) {
+            throw new CloudRuntimeException("Ip address is not associated with any network");
+        }
+
+        VMInstanceVO vm = _vmInstanceDao.findByIdIncludingRemoved(sourceIp.getAssociatedWithVmId());
+        Network network = _networkModel.getNetwork(networkId);
+        if (network == null) {
+            CloudRuntimeException ex = new CloudRuntimeException("Unable to find an ip address to map to specified vm id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, true, sourceIp);
+        }
+
+        // create new static nat rule
+        // Get nic IP4 address
+        Nic guestNic = _networkModel.getNicInNetworkIncludingRemoved(vm.getId(), networkId);
+        if (guestNic == null) {
+            throw new InvalidParameterValueException("Vm doesn't belong to the network with specified id");
+        }
+
+        String dstIp;
+
+        dstIp = sourceIp.getVmIp();
+        if (dstIp == null) {
+            throw new InvalidParameterValueException("Vm ip is not set as dnat ip for this public ip");
+        }
+
+        String srcMac = null;
+        try {
+            srcMac = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
+        } catch (InsufficientAddressCapacityException e) {
+            throw new CloudRuntimeException("Insufficient MAC address for static NAT instantiation.");
+        }
+
+        StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, srcMac, forRevoke);
+        staticNats.add(staticNat);
+        return staticNats;
+    }
+
+    @Override
+    public void getSystemIpAndEnableStaticNatForVm(VirtualMachine vm, boolean getNewIp) throws InsufficientAddressCapacityException {
+        boolean success = true;
+
+        // enable static nat if eIp capability is supported
+        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
+        for (Nic nic : nics) {
+            Network guestNetwork = _networkModel.getNetwork(nic.getNetworkId());
+            NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+            if (offering.isElasticIp()) {
+                boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm);
+                // for user VM's associate public IP only if offering is marked to associate a public IP by default on start of VM
+                if (!isSystemVM && !offering.isAssociatePublicIP()) {
+                    continue;
+                }
+                // check if there is already static nat enabled
+                if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null && !getNewIp) {
+                    s_logger.debug("Vm " + vm + " already has ip associated with it in guest network " + guestNetwork);
+                    continue;
+                }
+
+                s_logger.debug("Allocating system ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork);
+                IpAddress ip = _ipAddrMgr.assignSystemIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true);
+                if (ip == null) {
+                    throw new CloudRuntimeException("Failed to allocate system ip for vm " + vm + " in guest network " + guestNetwork);
+                }
+
+                s_logger.debug("Allocated system ip " + ip + ", now enabling static nat on it for vm " + vm);
+
+                try {
+                    success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM, null);
+                } catch (NetworkRuleConflictException ex) {
+                    s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork +
+                        " due to exception ", ex);
+                    success = false;
+                } catch (ResourceUnavailableException ex) {
+                    s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork +
+                        " due to exception ", ex);
+                    success = false;
+                }
+
+                if (!success) {
+                    s_logger.warn("Failed to enable static nat on system ip " + ip + " for the vm " + vm + ", releasing the ip...");
+                    _ipAddrMgr.handleSystemIpRelease(ip);
+                    throw new CloudRuntimeException("Failed to enable static nat on system ip for the vm " + vm);
+                } else {
+                    s_logger.warn("Succesfully enabled static nat on system ip " + ip + " for the vm " + vm);
+                }
+            }
+        }
+    }
+
+    protected void removePFRule(PortForwardingRuleVO rule) {
+        _portForwardingDao.remove(rule.getId());
+    }
+
+    @Override
+    public List<FirewallRuleVO> listAssociatedRulesForGuestNic(Nic nic) {
+        s_logger.debug("Checking if PF/StaticNat/LoadBalancer rules are configured for nic " + nic.getId());
+        List<FirewallRuleVO> result = new ArrayList<FirewallRuleVO>();
+        // add PF rules
+        result.addAll(_portForwardingDao.listByNetworkAndDestIpAddr(nic.getIPv4Address(), nic.getNetworkId()));
+        if(result.size() > 0) {
+            s_logger.debug("Found " + result.size() + " portforwarding rule configured for the nic in the network " + nic.getNetworkId());
+        }
+        // add static NAT rules
+        List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(nic.getInstanceId());
+        for (FirewallRuleVO rule : staticNatRules) {
+            if (rule.getNetworkId() == nic.getNetworkId()) {
+                result.add(rule);
+                s_logger.debug("Found rule " + rule.getId() + " " + rule.getPurpose() + " configured");
+            }
+        }
+        List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(nic.getNetworkId());
+        for (IpAddress ip : staticNatIps) {
+            if (ip.getVmIp() != null && ip.getVmIp().equals(nic.getIPv4Address())) {
+                VMInstanceVO vm = _vmInstanceDao.findById(nic.getInstanceId());
+                // generate a static Nat rule on the fly because staticNATrule does not persist into db anymore
+                // FIX ME
+                FirewallRuleVO staticNatRule =
+                        new FirewallRuleVO(null, ip.getId(), 0, 65535, NetUtils.ALL_PROTO.toString(), nic.getNetworkId(), vm.getAccountId(), vm.getDomainId(),
+                                Purpose.StaticNat, null, null, null, null, null);
+                result.add(staticNatRule);
+                s_logger.debug("Found rule " + staticNatRule.getId() + " " + staticNatRule.getPurpose() + " configured");
+            }
+        }
+        // add LB rules
+        List<LoadBalancerVMMapVO> lbMapList = _loadBalancerVMMapDao.listByInstanceId(nic.getInstanceId());
+        for (LoadBalancerVMMapVO lb : lbMapList) {
+            FirewallRuleVO lbRule = _firewallDao.findById(lb.getLoadBalancerId());
+            if (lbRule.getNetworkId() == nic.getNetworkId()) {
+                result.add(lbRule);
+                s_logger.debug("Found rule " + lbRule.getId() + " " + lbRule.getPurpose() + " configured");
+            }
+        }
+        return result;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_MODIFY, eventDescription = "updating forwarding rule", async = true)
+    public PortForwardingRule updatePortForwardingRule(long id, Integer privatePort, Integer privateEndPort, Long virtualMachineId, Ip vmGuestIp, String customId, Boolean forDisplay) {
+        Account caller = CallContext.current().getCallingAccount();
+        PortForwardingRuleVO rule = _portForwardingDao.findById(id);
+        if (rule == null) {
+            throw new InvalidParameterValueException("Unable to find " + id);
+        }
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        if (customId != null) {
+            rule.setUuid(customId);
+        }
+
+        if (forDisplay != null) {
+            rule.setDisplay(forDisplay);
+        }
+
+        if (privatePort != null && !NetUtils.isValidPort(privatePort)) {
+            throw new InvalidParameterValueException("privatePort is an invalid value: " + privatePort);
+        }
+        if (privateEndPort != null && !NetUtils.isValidPort(privateEndPort)) {
+            throw new InvalidParameterValueException("PrivateEndPort has an invalid value: " + privateEndPort);
+        }
+
+        if (privatePort != null && privateEndPort != null && ((privateEndPort - privatePort) != (rule.getSourcePortEnd() - rule.getSourcePortStart())))
+        {
+            throw new InvalidParameterValueException("Unable to update the private port range of port forwarding rule as  " +
+                    "the provided port range is not consistent with the port range : " + rule.getSourcePortStart() + " to " + rule.getSourcePortEnd());
+        }
+
+        //in case of port range
+        if (!rule.getSourcePortStart().equals(rule.getSourcePortEnd())) {
+             if ((privatePort == null || privateEndPort == null) && !(privatePort == null && privateEndPort == null)) {
+                throw new InvalidParameterValueException("Unable to update the private port range of port forwarding rule as  " +
+                        "the provided port range is not consistent with the port range : " + rule.getSourcePortStart() + " to " + rule.getSourcePortEnd());
+            }
+        }
+
+
+
+        if (virtualMachineId == null && vmGuestIp != null) {
+            throw new InvalidParameterValueException("vmguestip should be set along with virtualmachineid");
+        }
+        Ip dstIp = rule.getDestinationIpAddress();
+        if (virtualMachineId != null) {
+            // Verify that vm has nic in the network
+            Nic guestNic = _networkModel.getNicInNetwork(virtualMachineId, rule.getNetworkId());
+            if (guestNic == null || guestNic.getIPv4Address() == null) {
+                throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress");
+            } else {
+                dstIp = new Ip(guestNic.getIPv4Address());
+            }
+
+            if (vmGuestIp != null) {
+                //vm ip is passed so it can be primary or secondary ip addreess.
+                if (!dstIp.equals(vmGuestIp)) {
+                    //the vm ip is secondary ip to the nic.
+                    // is vmIp is secondary ip or not
+                    NicSecondaryIp secondaryIp = _nicSecondaryDao.findByIp4AddressAndNicId(vmGuestIp.toString(), guestNic.getId());
+                    if (secondaryIp == null) {
+                        throw new InvalidParameterValueException("IP Address is not in the VM nic's network ");
+                    }
+                    dstIp = vmGuestIp;
+                }
+            }
+        }
+
+        // revoke old rules at first
+        List<PortForwardingRuleVO> rules = new ArrayList<PortForwardingRuleVO>();
+        rule.setState(State.Revoke);
+        _portForwardingDao.update(id, rule);
+        rules.add(rule);
+        try {
+            if (!_firewallMgr.applyRules(rules, true, false)) {
+                throw new CloudRuntimeException("Failed to revoke the existing port forwarding rule:" + id);
+            }
+        } catch (ResourceUnavailableException ex) {
+            throw new CloudRuntimeException("Failed to revoke the existing port forwarding rule:" + id + " due to ", ex);
+        }
+
+        rule = _portForwardingDao.findById(id);
+        rule.setState(State.Add);
+        if (privatePort != null) {
+            rule.setDestinationPortStart(privatePort.intValue());
+            rule.setDestinationPortEnd((privateEndPort == null) ? privatePort.intValue() : privateEndPort.intValue());
+        } else if (privateEndPort != null) {
+            rule.setDestinationPortStart(privateEndPort.intValue());
+            rule.setDestinationPortEnd(privateEndPort);
+        }
+
+        if (virtualMachineId != null) {
+            rule.setVirtualMachineId(virtualMachineId);
+            rule.setDestinationIpAddress(dstIp);
+        }
+        _portForwardingDao.update(id, rule);
+
+        //apply new rules
+        if (!applyPortForwardingRules(rule.getSourceIpAddressId(), false, caller)) {
+            throw new CloudRuntimeException("Failed to apply the new port forwarding rule:" + id);
+        }
+
+        return _portForwardingDao.findById(id);
+    }
+}
diff --git a/server/src/com/cloud/network/rules/SshKeyToRouterRules.java b/server/src/main/java/com/cloud/network/rules/SshKeyToRouterRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/SshKeyToRouterRules.java
rename to server/src/main/java/com/cloud/network/rules/SshKeyToRouterRules.java
diff --git a/server/src/com/cloud/network/rules/StaticNatImpl.java b/server/src/main/java/com/cloud/network/rules/StaticNatImpl.java
similarity index 100%
rename from server/src/com/cloud/network/rules/StaticNatImpl.java
rename to server/src/main/java/com/cloud/network/rules/StaticNatImpl.java
diff --git a/server/src/com/cloud/network/rules/StaticNatRules.java b/server/src/main/java/com/cloud/network/rules/StaticNatRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/StaticNatRules.java
rename to server/src/main/java/com/cloud/network/rules/StaticNatRules.java
diff --git a/server/src/com/cloud/network/rules/StaticRoutesRules.java b/server/src/main/java/com/cloud/network/rules/StaticRoutesRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/StaticRoutesRules.java
rename to server/src/main/java/com/cloud/network/rules/StaticRoutesRules.java
diff --git a/server/src/com/cloud/network/rules/UserdataPwdRules.java b/server/src/main/java/com/cloud/network/rules/UserdataPwdRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/UserdataPwdRules.java
rename to server/src/main/java/com/cloud/network/rules/UserdataPwdRules.java
diff --git a/server/src/com/cloud/network/rules/UserdataToRouterRules.java b/server/src/main/java/com/cloud/network/rules/UserdataToRouterRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/UserdataToRouterRules.java
rename to server/src/main/java/com/cloud/network/rules/UserdataToRouterRules.java
diff --git a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
similarity index 100%
rename from server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
rename to server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
diff --git a/server/src/com/cloud/network/rules/VpcIpAssociationRules.java b/server/src/main/java/com/cloud/network/rules/VpcIpAssociationRules.java
similarity index 100%
rename from server/src/com/cloud/network/rules/VpcIpAssociationRules.java
rename to server/src/main/java/com/cloud/network/rules/VpcIpAssociationRules.java
diff --git a/server/src/com/cloud/network/security/LocalSecurityGroupWorkQueue.java b/server/src/main/java/com/cloud/network/security/LocalSecurityGroupWorkQueue.java
similarity index 100%
rename from server/src/com/cloud/network/security/LocalSecurityGroupWorkQueue.java
rename to server/src/main/java/com/cloud/network/security/LocalSecurityGroupWorkQueue.java
diff --git a/server/src/com/cloud/network/security/RuleUpdateLog.java b/server/src/main/java/com/cloud/network/security/RuleUpdateLog.java
similarity index 100%
rename from server/src/com/cloud/network/security/RuleUpdateLog.java
rename to server/src/main/java/com/cloud/network/security/RuleUpdateLog.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupListener.java b/server/src/main/java/com/cloud/network/security/SecurityGroupListener.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupListener.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupListener.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupManager.java b/server/src/main/java/com/cloud/network/security/SecurityGroupManager.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupManager.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupManager.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/main/java/com/cloud/network/security/SecurityGroupManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupManagerImpl.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupManagerImpl.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java b/server/src/main/java/com/cloud/network/security/SecurityGroupManagerImpl2.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupManagerImpl2.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupManagerImpl2.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerMBean.java b/server/src/main/java/com/cloud/network/security/SecurityGroupManagerMBean.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupManagerMBean.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupManagerMBean.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupWorkQueue.java b/server/src/main/java/com/cloud/network/security/SecurityGroupWorkQueue.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupWorkQueue.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupWorkQueue.java
diff --git a/server/src/com/cloud/network/security/SecurityGroupWorkTracker.java b/server/src/main/java/com/cloud/network/security/SecurityGroupWorkTracker.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityGroupWorkTracker.java
rename to server/src/main/java/com/cloud/network/security/SecurityGroupWorkTracker.java
diff --git a/server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java b/server/src/main/java/com/cloud/network/security/SecurityManagerMBeanImpl.java
similarity index 100%
rename from server/src/com/cloud/network/security/SecurityManagerMBeanImpl.java
rename to server/src/main/java/com/cloud/network/security/SecurityManagerMBeanImpl.java
diff --git a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java
new file mode 100644
index 0000000..d5f31d6
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java
@@ -0,0 +1,435 @@
+// 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.network.vpc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkACLServiceProvider;
+import com.cloud.network.element.VpcProvider;
+import com.cloud.network.vpc.NetworkACLItem.State;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLManager {
+    private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
+
+    @Inject
+    private NetworkModel _networkMgr;
+    @Inject
+    private NetworkACLDao _networkACLDao;
+    @Inject
+    private NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private VpcGatewayDao _vpcGatewayDao;
+    @Inject
+    private NetworkModel _ntwkModel;
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private VpcService _vpcSvc;
+    @Inject
+    private MessageBus _messageBus;
+
+    private List<NetworkACLServiceProvider> _networkAclElements;
+
+    @Override
+    public NetworkACL createNetworkACL(final String name, final String description, final long vpcId, final Boolean forDisplay) {
+        final NetworkACLVO acl = new NetworkACLVO(name, description, vpcId);
+        if (forDisplay != null) {
+            acl.setDisplay(forDisplay);
+        }
+        return _networkACLDao.persist(acl);
+    }
+
+    @Override
+    public boolean applyNetworkACL(final long aclId) throws ResourceUnavailableException {
+        boolean handled = true;
+        boolean aclApplyStatus = true;
+
+        final List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(aclId);
+        //Find all networks using this ACL and apply the ACL
+        final List<NetworkVO> networks = _networkDao.listByAclId(aclId);
+        for (final NetworkVO network : networks) {
+            if (!applyACLItemsToNetwork(network.getId(), rules)) {
+                handled = false;
+                break;
+            }
+        }
+
+        final List<VpcGatewayVO> vpcGateways = _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
+        for (final VpcGatewayVO vpcGateway : vpcGateways) {
+            final PrivateGateway privateGateway = _vpcSvc.getVpcPrivateGateway(vpcGateway.getId());
+
+            if (!applyACLToPrivateGw(privateGateway)) {
+                aclApplyStatus = false;
+                s_logger.debug("failed to apply network acl item on private gateway " + privateGateway.getId() + "acl id " + aclId);
+                break;
+            }
+        }
+
+        if (handled && aclApplyStatus) {
+            for (final NetworkACLItem rule : rules) {
+                if (rule.getState() == NetworkACLItem.State.Revoke) {
+                    removeRule(rule);
+                } else if (rule.getState() == NetworkACLItem.State.Add) {
+                    final NetworkACLItemVO ruleVO = _networkACLItemDao.findById(rule.getId());
+                    ruleVO.setState(NetworkACLItem.State.Active);
+                    _networkACLItemDao.update(ruleVO.getId(), ruleVO);
+                }
+            }
+        }
+        return handled && aclApplyStatus;
+    }
+
+    @Override
+    public NetworkACL getNetworkACL(final long id) {
+        return _networkACLDao.findById(id);
+    }
+
+    @Override
+    public boolean deleteNetworkACL(final NetworkACL acl) {
+        final long aclId = acl.getId();
+        final List<NetworkVO> networks = _networkDao.listByAclId(aclId);
+        if (networks != null && networks.size() > 0) {
+            throw new CloudRuntimeException("ACL is still associated with " + networks.size() + " tier(s). Cannot delete network ACL: " + acl.getUuid());
+        }
+
+        final List<VpcGatewayVO> pvtGateways = _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
+
+        if (pvtGateways != null && pvtGateways.size() > 0) {
+            throw new CloudRuntimeException("ACL is still associated with " + pvtGateways.size() + " private gateway(s). Cannot delete network ACL: " + acl.getUuid());
+        }
+
+        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(aclId);
+        for (final NetworkACLItemVO networkACLItem : aclItems) {
+            revokeNetworkACLItem(networkACLItem.getId());
+        }
+
+        return _networkACLDao.remove(aclId);
+    }
+
+    @Override
+    public boolean replaceNetworkACLForPrivateGw(final NetworkACL acl, final PrivateGateway gateway) throws ResourceUnavailableException {
+        final VpcGatewayVO vpcGatewayVo = _vpcGatewayDao.findById(gateway.getId());
+        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
+        if (aclItems == null || aclItems.isEmpty()) {
+            //Revoke ACL Items of the existing ACL if the new network acl is empty
+            //Other wise existing rules will not be removed on the router elelment
+            s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
+            if (!revokeACLItemsForPrivateGw(gateway)) {
+                throw new CloudRuntimeException("Failed to replace network ACL. Error while removing existing ACL " + "items for privatewa gateway: " + gateway.getId());
+            }
+        }
+
+        vpcGatewayVo.setNetworkACLId(acl.getId());
+        if (_vpcGatewayDao.update(vpcGatewayVo.getId(), vpcGatewayVo)) {
+            return applyACLToPrivateGw(gateway);
+
+        }
+        return false;
+    }
+
+    @Override
+    public boolean replaceNetworkACL(final NetworkACL acl, final NetworkVO network) throws ResourceUnavailableException {
+
+        final NetworkOffering guestNtwkOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+
+        if (guestNtwkOff == null) {
+            throw new InvalidParameterValueException("Can't find network offering associated with network: " + network.getUuid());
+        }
+
+        //verify that ACLProvider is supported by network offering
+        if (!_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.NetworkACL)) {
+            throw new InvalidParameterValueException("Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
+        }
+
+        if (network.getNetworkACLId() != null) {
+            //Revoke ACL Items of the existing ACL if the new ACL is empty
+            //Existing rules won't be removed otherwise
+            final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
+            if (aclItems == null || aclItems.isEmpty()) {
+                s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
+                if (!revokeACLItemsForNetwork(network.getId())) {
+                    throw new CloudRuntimeException("Failed to replace network ACL. Error while removing existing ACL items for network: " + network.getId());
+                }
+            }
+        }
+
+        network.setNetworkACLId(acl.getId());
+        //Update Network ACL
+        if (_networkDao.update(network.getId(), network)) {
+            s_logger.debug("Updated network: " + network.getId() + " with Network ACL Id: " + acl.getId() + ", Applying ACL items");
+            //Apply ACL to network
+            final Boolean result = applyACLToNetwork(network.getId());
+            if (result) {
+                // public message on message bus, so that network elements implementing distributed routing capability
+                // can act on the event
+                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
+            }
+            return result;
+        }
+        return false;
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "creating network ACL Item", create = true)
+    public NetworkACLItem createNetworkACLItem(NetworkACLItemVO networkACLItemVO) {
+        NetworkACLItemVO newRule = Transaction.execute(new TransactionCallback<NetworkACLItemVO>() {
+            @Override
+            public NetworkACLItemVO doInTransaction(final TransactionStatus status) {
+                NetworkACLItemVO networkACLItemVOFromDatabase = _networkACLItemDao.persist(networkACLItemVO);
+
+                if (!_networkACLItemDao.setStateToAdd(networkACLItemVOFromDatabase)) {
+                    throw new CloudRuntimeException("Unable to update the state to add for " + networkACLItemVOFromDatabase);
+                }
+                CallContext.current().setEventDetails("ACL Item Id: " + networkACLItemVOFromDatabase.getId());
+
+                return networkACLItemVOFromDatabase;
+            }
+        });
+
+        return getNetworkACLItem(newRule.getId());
+    }
+
+    @Override
+    public NetworkACLItem getNetworkACLItem(long ruleId) {
+        return _networkACLItemDao.findById(ruleId);
+    }
+
+    @Override
+    public boolean revokeNetworkACLItem(final long ruleId) {
+
+        final NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId);
+
+        revokeRule(rule);
+
+        boolean success = false;
+
+        try {
+            applyNetworkACL(rule.getAclId());
+            success = true;
+        } catch (final ResourceUnavailableException e) {
+            return false;
+        }
+
+        return success;
+    }
+
+    @DB
+    private void revokeRule(final NetworkACLItemVO rule) {
+        if (rule.getState() == State.Staged) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule);
+            }
+            _networkACLItemDao.remove(rule.getId());
+        } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
+            rule.setState(State.Revoke);
+            _networkACLItemDao.update(rule.getId(), rule);
+        }
+    }
+
+    @Override
+    public boolean revokeACLItemsForNetwork(final long networkId) throws ResourceUnavailableException {
+        final Network network = _networkDao.findById(networkId);
+        if (network.getNetworkACLId() == null) {
+            return true;
+        }
+        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(network.getNetworkACLId());
+        if (aclItems.isEmpty()) {
+            s_logger.debug("Found no network ACL Items for network id=" + networkId);
+            return true;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + aclItems.size() + " Network ACL Items for network id=" + networkId);
+        }
+
+        for (final NetworkACLItemVO aclItem : aclItems) {
+            // Mark all Network ACLs rules as Revoke, but don't update in DB
+            if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) {
+                aclItem.setState(State.Revoke);
+            }
+        }
+
+        final boolean success = applyACLItemsToNetwork(network.getId(), aclItems);
+
+        if (s_logger.isDebugEnabled() && success) {
+            s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " + aclItems.size());
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean revokeACLItemsForPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
+        final long networkACLId = gateway.getNetworkACLId();
+        final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(networkACLId);
+        if (aclItems.isEmpty()) {
+            s_logger.debug("Found no network ACL Items for private gateway 'id=" + gateway.getId() + "'");
+            return true;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + aclItems.size() + " Network ACL Items for private gateway  id=" + gateway.getId());
+        }
+
+        for (final NetworkACLItemVO aclItem : aclItems) {
+            // Mark all Network ACLs rules as Revoke, but don't update in DB
+            if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) {
+                aclItem.setState(State.Revoke);
+            }
+        }
+
+        final boolean success = applyACLToPrivateGw(gateway, aclItems);
+
+        if (s_logger.isDebugEnabled() && success) {
+            s_logger.debug("Successfully released Network ACLs for private gateway id=" + gateway.getId() + " and # of rules now = " + aclItems.size());
+        }
+
+        return success;
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listNetworkACLItems(final long guestNtwkId) {
+        final Network network = _networkMgr.getNetwork(guestNtwkId);
+        if (network.getNetworkACLId() == null) {
+            return null;
+        }
+        return _networkACLItemDao.listByACL(network.getNetworkACLId());
+    }
+
+    private void removeRule(final NetworkACLItem rule) {
+        _networkACLItemDao.remove(rule.getId());
+    }
+
+    @Override
+    public boolean applyACLToPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
+        final VpcGatewayVO vpcGatewayVO = _vpcGatewayDao.findById(gateway.getId());
+        final List<? extends NetworkACLItem> rules = _networkACLItemDao.listByACL(vpcGatewayVO.getNetworkACLId());
+        return applyACLToPrivateGw(gateway, rules);
+    }
+
+    private boolean applyACLToPrivateGw(final PrivateGateway gateway, final List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
+        List<VpcProvider> vpcElements = new ArrayList<VpcProvider>();
+        vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()));
+
+        try {
+            for (final VpcProvider provider : vpcElements) {
+                return provider.applyACLItemsToPrivateGw(gateway, rules);
+            }
+        } catch (final Exception ex) {
+            s_logger.debug("Failed to apply acl to private gateway " + gateway);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean applyACLToNetwork(final long networkId) throws ResourceUnavailableException {
+        final Network network = _networkDao.findById(networkId);
+        if (network.getNetworkACLId() == null) {
+            return true;
+        }
+        final List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(network.getNetworkACLId());
+        return applyACLItemsToNetwork(networkId, rules);
+    }
+
+    /**
+     * Updates and applies the network ACL rule ({@link NetworkACLItemVO}).
+     * We will first try to update the ACL rule in the database using {@link NetworkACLItemDao#update(Long, NetworkACLItemVO)}. If it does not work, a {@link CloudRuntimeException} is thrown.
+     * If we manage to update the ACL rule in the database, we proceed to apply it using {@link #applyNetworkACL(long)}. If this does not work we throw a {@link CloudRuntimeException}.
+     * If all is working we return the {@link NetworkACLItemVO} given as parameter. We wil set the state of the rule to {@link com.cloud.network.vpc.NetworkACLItem.State#Add}.
+     */
+    @Override
+    public NetworkACLItem updateNetworkACLItem(NetworkACLItemVO networkACLItemVO) throws ResourceUnavailableException {
+        networkACLItemVO.setState(State.Add);
+
+        if (_networkACLItemDao.update(networkACLItemVO.getId(), networkACLItemVO)) {
+            if (applyNetworkACL(networkACLItemVO.getAclId())) {
+                return networkACLItemVO;
+            } else {
+                throw new CloudRuntimeException("Failed to apply Network ACL rule: " + networkACLItemVO.getUuid());
+            }
+        }
+        throw new CloudRuntimeException(String.format("Network ACL rule [id=%s] acl rule list [id=%s] could not be updated.", networkACLItemVO.getUuid(), networkACLItemVO.getAclId()));
+    }
+
+    public boolean applyACLItemsToNetwork(final long networkId, final List<NetworkACLItemVO> rules) throws ResourceUnavailableException {
+        final Network network = _networkDao.findById(networkId);
+        boolean handled = false;
+        boolean foundProvider = false;
+        for (final NetworkACLServiceProvider element : _networkAclElements) {
+            final Network.Provider provider = element.getProvider();
+            final boolean isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
+            if (!isAclProvider) {
+                continue;
+            }
+            foundProvider = true;
+            s_logger.debug("Applying NetworkACL for network: " + network.getId() + " with Network ACL service provider");
+            handled = element.applyNetworkACLs(network, rules);
+            if (handled) {
+                // publish message on message bus, so that network elements implementing distributed routing
+                // capability can act on the event
+                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
+                break;
+            }
+        }
+        if (!foundProvider) {
+            s_logger.debug("Unable to find NetworkACL service provider for network: " + network.getId());
+        }
+        return handled;
+    }
+
+    public List<NetworkACLServiceProvider> getNetworkAclElements() {
+        return _networkAclElements;
+    }
+
+    @Inject
+    public void setNetworkAclElements(final List<NetworkACLServiceProvider> networkAclElements) {
+        _networkAclElements = networkAclElements;
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java
new file mode 100644
index 0000000..8734ec6
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java
@@ -0,0 +1,1151 @@
+// 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.network.vpc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
+import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.vpc.NetworkACLItem.Action;
+import com.cloud.network.vpc.NetworkACLItem.TrafficType;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+@Component
+public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLService {
+    private static final Logger s_logger = Logger.getLogger(NetworkACLServiceImpl.class);
+
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private ResourceTagDao _resourceTagDao;
+    @Inject
+    private NetworkACLDao _networkACLDao;
+    @Inject
+    private NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    private NetworkModel networkModel;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private NetworkACLManager _networkAclMgr;
+    @Inject
+    private VpcGatewayDao _vpcGatewayDao;
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private VpcDao _vpcDao;
+    @Inject
+    private VpcService _vpcSvc;
+
+    private String supportedProtocolsForAclRules = "tcp,udp,icmp,all";
+
+    @Override
+    public NetworkACL createNetworkACL(final String name, final String description, final long vpcId, final Boolean forDisplay) {
+        final Account caller = CallContext.current().getCallingAccount();
+        final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Unable to find VPC");
+        }
+        _accountMgr.checkAccess(caller, null, true, vpc);
+        return _networkAclMgr.createNetworkACL(name, description, vpcId, forDisplay);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_CREATE, eventDescription = "creating network acl list", async = true)
+    public NetworkACL getNetworkACL(final long id) {
+        return _networkAclMgr.getNetworkACL(id);
+    }
+
+    @Override
+    public Pair<List<? extends NetworkACL>, Integer> listNetworkACLs(final ListNetworkACLListsCmd cmd) {
+        final Long id = cmd.getId();
+        final String name = cmd.getName();
+        final Long networkId = cmd.getNetworkId();
+        final Long vpcId = cmd.getVpcId();
+        final String keyword = cmd.getKeyword();
+        final Boolean display = cmd.getDisplay();
+
+        final SearchBuilder<NetworkACLVO> sb = _networkACLDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), Op.EQ);
+        sb.and("name", sb.entity().getName(), Op.EQ);
+        sb.and("vpcId", sb.entity().getVpcId(), Op.IN);
+        sb.and("display", sb.entity().isDisplay(), Op.EQ);
+
+        final Account caller = CallContext.current().getCallingAccount();
+
+        if (networkId != null) {
+            final SearchBuilder<NetworkVO> network = _networkDao.createSearchBuilder();
+            network.and("networkId", network.entity().getId(), Op.EQ);
+            sb.join("networkJoin", network, sb.entity().getId(), network.entity().getNetworkACLId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<NetworkACLVO> sc = sb.create();
+
+        if (keyword != null) {
+            final SearchCriteria<NetworkACLVO> ssc = _networkACLDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", name);
+        }
+
+        if (vpcId != null) {
+            final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Unable to find VPC");
+            }
+            _accountMgr.checkAccess(caller, null, true, vpc);
+            //Include vpcId 0 to list default ACLs
+            sc.setParameters("vpcId", vpcId, 0);
+        } else {
+            //ToDo: Add accountId to network_acl table for permission check
+
+            // VpcId is not specified. Find permitted VPCs for the caller
+            // and list ACLs belonging to the permitted VPCs
+            final List<Long> permittedAccounts = new ArrayList<Long>();
+            Long domainId = cmd.getDomainId();
+            boolean isRecursive = cmd.isRecursive();
+            final String accountName = cmd.getAccountName();
+            final Long projectId = cmd.getProjectId();
+            final boolean listAll = cmd.listAll();
+            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
+            _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+            domainId = domainIdRecursiveListProject.first();
+            isRecursive = domainIdRecursiveListProject.second();
+            final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+            final SearchBuilder<VpcVO> sbVpc = _vpcDao.createSearchBuilder();
+            _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            final SearchCriteria<VpcVO> scVpc = sbVpc.create();
+            _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            final List<VpcVO> vpcs = _vpcDao.search(scVpc, null);
+            final List<Long> vpcIds = new ArrayList<Long>();
+            for (final VpcVO vpc : vpcs) {
+                vpcIds.add(vpc.getId());
+            }
+            //Add vpc_id 0 to list default ACLs
+            vpcIds.add(0L);
+            sc.setParameters("vpcId", vpcIds.toArray());
+        }
+
+        if (networkId != null) {
+            sc.setJoinParameters("networkJoin", "networkId", networkId);
+        }
+
+        final Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null);
+        final Pair<List<NetworkACLVO>, Integer> acls = _networkACLDao.searchAndCount(sc, filter);
+        return new Pair<List<? extends NetworkACL>, Integer>(acls.first(), acls.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "Deleting Network ACL List", async = true)
+    public boolean deleteNetworkACL(final long id) {
+        final Account caller = CallContext.current().getCallingAccount();
+        final NetworkACL acl = _networkACLDao.findById(id);
+        if (acl == null) {
+            throw new InvalidParameterValueException("Unable to find specified ACL");
+        }
+
+        //Do not allow deletion of default ACLs
+        if (acl.getId() == NetworkACL.DEFAULT_ALLOW || acl.getId() == NetworkACL.DEFAULT_DENY) {
+            throw new InvalidParameterValueException("Default ACL cannot be removed");
+        }
+
+        final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Unable to find specified VPC associated with the ACL");
+        }
+        _accountMgr.checkAccess(caller, null, true, vpc);
+        return _networkAclMgr.deleteNetworkACL(acl);
+    }
+
+    @Override
+    public boolean replaceNetworkACLonPrivateGw(final long aclId, final long privateGatewayId) throws ResourceUnavailableException {
+        final Account caller = CallContext.current().getCallingAccount();
+        final VpcGateway gateway = _vpcGatewayDao.findById(privateGatewayId);
+        if (gateway == null) {
+            throw new InvalidParameterValueException("Unable to find specified private gateway");
+        }
+
+        final VpcGatewayVO vo = _vpcGatewayDao.findById(privateGatewayId);
+        if (vo.getState() != VpcGateway.State.Ready) {
+            throw new InvalidParameterValueException("Gateway is not in Ready state");
+        }
+
+        final NetworkACL acl = _networkACLDao.findById(aclId);
+        if (acl == null) {
+            throw new InvalidParameterValueException("Unable to find specified NetworkACL");
+        }
+
+        if (gateway.getVpcId() == null) {
+            throw new InvalidParameterValueException("Unable to find specified vpc id");
+        }
+
+        if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
+            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
+            }
+            _accountMgr.checkAccess(caller, null, true, vpc);
+            if (!gateway.getVpcId().equals(acl.getVpcId())) {
+                throw new InvalidParameterValueException("private gateway: " + privateGatewayId + " and ACL: " + aclId + " do not belong to the same VPC");
+            }
+        }
+
+        final PrivateGateway privateGateway = _vpcSvc.getVpcPrivateGateway(gateway.getId());
+        _accountMgr.checkAccess(caller, null, true, privateGateway);
+
+        return _networkAclMgr.replaceNetworkACLForPrivateGw(acl, privateGateway);
+
+    }
+
+    @Override
+    public boolean replaceNetworkACL(final long aclId, final long networkId) throws ResourceUnavailableException {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final NetworkVO network = _networkDao.findById(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Unable to find specified Network");
+        }
+
+        final NetworkACL acl = _networkACLDao.findById(aclId);
+        if (acl == null) {
+            throw new InvalidParameterValueException("Unable to find specified NetworkACL");
+        }
+
+        if (network.getVpcId() == null) {
+            throw new InvalidParameterValueException("Network is not part of a VPC: " + network.getUuid());
+        }
+
+        if (network.getTrafficType() != Networks.TrafficType.Guest) {
+            throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest);
+        }
+
+        if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
+            //ACL is not default DENY/ALLOW
+            // ACL should be associated with a VPC
+            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
+            }
+
+            _accountMgr.checkAccess(caller, null, true, vpc);
+            if (!network.getVpcId().equals(acl.getVpcId())) {
+                throw new InvalidParameterValueException("Network: " + networkId + " and ACL: " + aclId + " do not belong to the same VPC");
+            }
+        }
+
+        return _networkAclMgr.replaceNetworkACL(acl, network);
+    }
+
+    /**
+     * Creates and persists a network ACL rule. The network ACL rule is persisted as a {@link NetworkACLItemVO}.
+     * If no ACL list ID is informed, we will create one. To check these details, please refer to {@link #createAclListIfNeeded(CreateNetworkACLCmd)}.
+     * All of the attributes will be validated accordingly using the following methods:
+     * <ul>
+     * <li> {@link #validateAclRuleNumber(CreateNetworkACLCmd, Long, NetworkACL)} to validate the provided ACL rule number;
+     * <li> {@link #validateNetworkAclList(Long, NetworkACL)} to check if the user has access to the informed ACL list ID and respective VPC;
+     * <li> {@link #validateAndCreateNetworkAclRuleAction(String)} to validate the ACL rule action;
+     * <li> {@link #validateNetworkACLItem(NetworkACLItemVO)} to validate general configurations relating to protocol, ports, and ICMP codes and types.
+     * </ul>
+     *
+     * Moreover, if not ACL rule number is provided we generate one based on the last ACL number used. We will increment +1 in the last ACL rule number used. After all of the validation the ACL rule is persisted using the method {@link NetworkACLManagerImpl#createNetworkACLItem(NetworkACLItemVO)}.
+     */
+    @Override
+    public NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd createNetworkACLCmd) {
+        Long aclId = createAclListIfNeeded(createNetworkACLCmd);
+
+        Integer sourcePortStart = createNetworkACLCmd.getSourcePortStart();
+        Integer sourcePortEnd = createNetworkACLCmd.getSourcePortEnd();
+        String protocol = createNetworkACLCmd.getProtocol();
+        List<String> sourceCidrList = createNetworkACLCmd.getSourceCidrList();
+        Integer icmpCode = createNetworkACLCmd.getIcmpCode();
+        Integer icmpType = createNetworkACLCmd.getIcmpType();
+        TrafficType trafficType = createNetworkACLCmd.getTrafficType();
+        String reason = createNetworkACLCmd.getReason();
+        String action = createNetworkACLCmd.getAction();
+
+        NetworkACL acl = _networkAclMgr.getNetworkACL(aclId);
+
+        validateNetworkAcl(acl);
+        validateAclRuleNumber(createNetworkACLCmd, acl);
+
+        NetworkACLItem.Action ruleAction = validateAndCreateNetworkAclRuleAction(action);
+        Integer number = createNetworkACLCmd.getNumber();
+        if (number == null) {
+            number = _networkACLItemDao.getMaxNumberByACL(aclId) + 1;
+        }
+        NetworkACLItemVO networkACLItemVO = new NetworkACLItemVO(sourcePortStart, sourcePortEnd, protocol, aclId, sourceCidrList, icmpCode, icmpType, trafficType, ruleAction, number, reason);
+        networkACLItemVO.setDisplay(createNetworkACLCmd.isDisplay());
+
+        validateNetworkACLItem(networkACLItemVO);
+        return _networkAclMgr.createNetworkACLItem(networkACLItemVO);
+    }
+
+    /**
+     *  We first validate the given ACL action as a string using {@link #validateNetworkAclRuleAction(String)}.
+     *  Afterwards, we convert this ACL to an object of {@link NetworkACLItem.Action}.
+     *  If the action as String matches the word 'deny' (ignoring case), we return an instance of {@link NetworkACLItem.Action#Deny}.
+     *  Otherwise, we return {@link NetworkACLItem.Action#Allow}.
+     */
+    protected NetworkACLItem.Action validateAndCreateNetworkAclRuleAction(String action) {
+        validateNetworkAclRuleAction(action);
+        NetworkACLItem.Action ruleAction = NetworkACLItem.Action.Allow;
+        if ("deny".equalsIgnoreCase(action)) {
+            ruleAction = NetworkACLItem.Action.Deny;
+        }
+        return ruleAction;
+    }
+
+    /**
+     * Validates the network ACL rule action given as a {@link String}.
+     * If the parameter is null, we do not perform any validations. Otherwise, we check if the parameter is equal to 'Allow' or 'Deny' (ignoring the case).
+     * If the parameter is an invalid action, we throw an {@link InvalidParameterValueException}.
+     */
+    protected void validateNetworkAclRuleAction(String action) {
+        if (action != null) {
+            if (!("Allow".equalsIgnoreCase(action) || "Deny".equalsIgnoreCase(action))) {
+                throw new InvalidParameterValueException(String.format("Invalid action [%s]. Permitted actions are Allow and Deny", action));
+            }
+        }
+    }
+
+    /**
+     * Validates the ACL rule number field. If the field is null, then we do not have anything to check here.
+     * If the number is not null, we perform the following checks:
+     * <ul>
+     *  <li>If number is less than one, than we throw an {@link InvalidParameterValueException};
+     *  <li>if there is already an ACL configured with the given number for the network, we also throw an {@link InvalidParameterValueException}. The check is performed using {@link NetworkACLItemDao#findByAclAndNumber(long, int)} method.
+     * </ul>
+     *
+     * At the end, if not exception is thrown, the number of the ACL rule is valid.
+     */
+    protected void validateAclRuleNumber(CreateNetworkACLCmd createNetworkAclCmd, NetworkACL acl) {
+        Integer number = createNetworkAclCmd.getNumber();
+        if (number != null) {
+            if (number < 1) {
+                throw new InvalidParameterValueException(String.format("Invalid number [%d]. Number cannot be < 1", number));
+            }
+            if (_networkACLItemDao.findByAclAndNumber(acl.getId(), createNetworkAclCmd.getNumber()) != null) {
+                throw new InvalidParameterValueException("ACL item with number " + number + " already exists in ACL: " + acl.getUuid());
+            }
+        }
+    }
+
+    /**
+     * Validates a given {@link NetworkACL}. The validations are the following:
+     * <ul>
+     *  <li>If the parameter is null, we return an  {@link InvalidParameterValueException};
+     *  <li>Default ACLs {@link NetworkACL#DEFAULT_ALLOW} and {@link NetworkACL#DEFAULT_DENY} cannot be modified. Therefore, if any of them is provided we throw a {@link InvalidParameterValueException};
+     *  <li>If the network does not have a VPC, we will throw an {@link InvalidParameterValueException}.
+     * </ul>
+     *
+     * After all validations, we check if the user has access to the given network ACL using {@link AccountManager#checkAccess(Account, org.apache.cloudstack.acl.SecurityChecker.AccessType, boolean, org.apache.cloudstack.acl.ControlledEntity...)}.
+     */
+    protected void validateNetworkAcl(NetworkACL acl) {
+        if (acl == null) {
+            throw new InvalidParameterValueException("Unable to find specified ACL.");
+        }
+
+        if (acl.getId() == NetworkACL.DEFAULT_DENY || acl.getId() == NetworkACL.DEFAULT_ALLOW) {
+            throw new InvalidParameterValueException("Default ACL cannot be modified");
+        }
+
+        Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+        if (vpc == null) {
+            throw new InvalidParameterValueException(String.format("Unable to find Vpc associated with the NetworkACL [%s]", acl.getUuid()));
+        }
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, vpc);
+    }
+
+    /**
+     * This methods will simply return the ACL rule list ID if it has been provided by the parameter 'createNetworkACLCmd'.
+     * If no ACL rule List ID has been provided the method behave as follows:
+     * <ul>
+     *  <li> If it has not been provided either, we will throw an {@link InvalidParameterValueException};
+     *  <li> if the network ID has been provided, we will check if the network has a VPC; if it does not have, we will throw an {@link InvalidParameterValueException};
+     *  <ul>
+     *      <li> If the VPC already has an ACL rule list, we will return it;
+     *      <li> otherwise, we will create one using {@link #createAclListForNetworkAndReturnAclListId(CreateNetworkACLCmd, Network)} method. This behavior is a legacy thing that has been maintained so far.
+     *  </ul>
+     * </ul>
+     *
+     * @return The network ACL list ID
+     */
+    protected Long createAclListIfNeeded(CreateNetworkACLCmd createNetworkACLCmd) {
+        Long aclId = createNetworkACLCmd.getACLId();
+        if (aclId != null) {
+            return aclId;
+        }
+        if (createNetworkACLCmd.getNetworkId() == null) {
+            throw new InvalidParameterValueException("Cannot create Network ACL Item. ACL Id or network Id is required");
+        }
+        Network network = networkModel.getNetwork(createNetworkACLCmd.getNetworkId());
+        if (network.getVpcId() == null) {
+            throw new InvalidParameterValueException("Network: " + network.getUuid() + " does not belong to VPC");
+        }
+        aclId = network.getNetworkACLId();
+
+        if (aclId == null) {
+            aclId = createAclListForNetworkAndReturnAclListId(createNetworkACLCmd, network);
+        }
+        return aclId;
+    }
+
+    /**
+     * This method will created a network ACL for the provided network. This method will behave as follows:
+     * <ul>
+     *  <li> If the network offering does not support ACLs ( {@link NetworkModel#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service...)} ), then it throws an {@link InvalidParameterValueException};
+     *  <li> If the network does not have any VPC, it throws an {@link InvalidParameterValueException};
+     *  <li> If everything is OK so far, we try to create the ACL using {@link NetworkACLManagerImpl#createNetworkACL(String, String, long, Boolean)} method.
+     *  <ul>
+     *      <li> If the ACL is not created we throw a {@link CloudRuntimeException};
+     *      <li> otherwise, the workflow continues.
+     *  </ul>
+     *  <li> With the ACL in our hands, we try to apply it. If it does not work we throw a {@link CloudRuntimeException}.
+     * </ul>
+     *
+     * @return the Id of the network ACL that is created.
+     */
+    protected Long createAclListForNetworkAndReturnAclListId(CreateNetworkACLCmd aclItemCmd, Network network) {
+        s_logger.debug("Network " + network.getId() + " is not associated with any ACL. Creating an ACL before adding acl item");
+
+        if (!networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.NetworkACL)) {
+            throw new InvalidParameterValueException("Network Offering does not support NetworkACL service");
+        }
+
+        Vpc vpc = _entityMgr.findById(Vpc.class, network.getVpcId());
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Unable to find Vpc associated with the Network");
+        }
+
+        String aclName = "VPC_" + vpc.getName() + "_Tier_" + network.getName() + "_ACL_" + network.getUuid();
+        String description = "ACL for " + aclName;
+        NetworkACL acl = _networkAclMgr.createNetworkACL(aclName, description, network.getVpcId(), aclItemCmd.isDisplay());
+        if (acl == null) {
+            throw new CloudRuntimeException("Error while create ACL before adding ACL Item for network " + network.getId());
+        }
+        s_logger.debug("Created ACL: " + aclName + " for network " + network.getId());
+        Long aclId = acl.getId();
+        //Apply acl to network
+        try {
+            if (!_networkAclMgr.replaceNetworkACL(acl, (NetworkVO)network)) {
+                throw new CloudRuntimeException("Unable to apply auto created ACL to network " + network.getId());
+            }
+            s_logger.debug("Created ACL is applied to network " + network.getId());
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Unable to apply auto created ACL to network " + network.getId(), e);
+        }
+        return aclId;
+    }
+
+    /**
+     *  Performs all of the validations for the {@link NetworkACLItem}.
+     *  First we validate the sources start and end ports using {@link #validateSourceStartAndEndPorts(NetworkACLItemVO)};
+     *  then, we validate the source CIDR list using {@link #validateSourceCidrList(NetworkACLItemVO)};
+     *  afterwards, it is validated the protocol entered in the {@link NetworkACLItemVO} using {@link #validateProtocol(NetworkACLItemVO)}.
+     */
+    protected void validateNetworkACLItem(NetworkACLItemVO networkACLItemVO) {
+        validateSourceStartAndEndPorts(networkACLItemVO);
+        validateSourceCidrList(networkACLItemVO);
+        validateProtocol(networkACLItemVO);
+    }
+
+    /**
+     * Validated ICMP type and code of {@link NetworkACLItemVO}. The behavior of this method is the following:
+     * <ul>
+     *  <li>If no ICMP type is provided, we do not perform validations;
+     *  <li>If the ICMP type is not '-1', we validate it using {@link NetUtils#validateIcmpType(long)};
+     *  <li>If the ICMP code is null, we do not perform validations;
+     *  <li>If the ICMP code is not '-1', we validate it using {@link NetUtils#validateIcmpCode(long)};
+     * </ul>
+     * Failing to meet the above conditions, we throw an {@link InvalidParameterValueException}.
+     */
+    protected void validateIcmpTypeAndCode(NetworkACLItemVO networkACLItemVO) {
+        Integer icmpType = networkACLItemVO.getIcmpType();
+        Integer icmpCode = networkACLItemVO.getIcmpCode();
+        if (icmpType == null) {
+            return;
+        }
+        if (icmpType.longValue() != -1 && !NetUtils.validateIcmpType(icmpType.longValue())) {
+            throw new InvalidParameterValueException(String.format("Invalid icmp type [%d]. It should belong to [0-255] range", icmpType));
+        }
+        if (icmpCode != null) {
+            if (icmpCode.longValue() != -1 && !NetUtils.validateIcmpCode(icmpCode.longValue())) {
+                throw new InvalidParameterValueException(String.format("Invalid icmp code [%d]. It should belong to [0-15] range and can be defined when icmpType belongs to [0-40] range", icmpCode));
+            }
+        }
+    }
+
+    /**
+     *   Validates the {@link NetworkACLItemVO} protocol. If the protocol is blank, we do not execute any validations. Otherwise, we perform the following checks:
+     *   <ul>
+     *      <li>If it is a numeric value, the protocol must be bigger or equal to 0 and smaller or equal to 255;
+     *      <li>if it is a {@link String}, it must be one of the following: {@link #supportedProtocolsForAclRules};
+     *   </ul>
+     *    Whenever the conditions enumerated above are not met, we throw an {@link InvalidParameterValueException}.
+     *
+     *    If the parameter passes the protocol type validations, we check the following:
+     *    <ul>
+     *      <li>If it is not an ICMP type protocol, it cannot have any value in {@link NetworkACLItemVO#getIcmpCode()} and {@link NetworkACLItemVO#getIcmpType()};
+     *      <li>If it is an ICMP type protocol, it cannot have any value in {@link NetworkACLItemVO#getSourcePortStart()} and {@link NetworkACLItemVO#getSourcePortEnd()}.
+     *    </ul>
+     *    Failing to meet the above conditions, we throw an {@link InvalidParameterValueException}.
+     *
+     *    The last check is performed via {@link #validateIcmpTypeAndCode(NetworkACLItemVO)} method.
+     */
+    protected void validateProtocol(NetworkACLItemVO networkACLItemVO) {
+        String protocol = networkACLItemVO.getProtocol();
+        if (StringUtils.isBlank(protocol)) {
+            return;
+        }
+        if (StringUtils.isNumeric(protocol)) {
+            int protoNumber = Integer.parseInt(protocol);
+            if (protoNumber < 0 || protoNumber > 255) {
+                throw new InvalidParameterValueException("Invalid protocol number: " + protoNumber);
+            }
+        } else {
+            if (!supportedProtocolsForAclRules.contains(protocol.toLowerCase())) {
+                throw new InvalidParameterValueException(String.format("Invalid protocol [%s]. Expected one of: [%s]", protocol, supportedProtocolsForAclRules));
+            }
+        }
+
+        Integer icmpCode = networkACLItemVO.getIcmpCode();
+        Integer icmpType = networkACLItemVO.getIcmpType();
+        // icmp code and icmp type can't be passed in for any other protocol rather than icmp
+        boolean isIcmpProtocol = protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO);
+        if (!isIcmpProtocol && (icmpCode != null || icmpType != null)) {
+            throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
+        }
+
+        Integer sourcePortStart = networkACLItemVO.getSourcePortStart();
+        Integer sourcePortEnd = networkACLItemVO.getSourcePortEnd();
+        if (isIcmpProtocol && (sourcePortStart != null || sourcePortEnd != null)) {
+            throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
+        }
+
+        validateIcmpTypeAndCode(networkACLItemVO);
+    }
+
+    /**
+     *  Validates all of the CIDRs in the {@link NetworkACLItemVO#getSourceCidrList()}.
+     *  If the list is empty we do not execute any validation. Otherwise, all of the CIDRs are validated using {@link NetUtils#isValidIp4Cidr(String)}.
+     */
+    protected void validateSourceCidrList(NetworkACLItemVO networkACLItemVO) {
+        List<String> sourceCidrList = networkACLItemVO.getSourceCidrList();
+        if (CollectionUtils.isNotEmpty(sourceCidrList)) {
+            for (String cidr : sourceCidrList) {
+                if (!NetUtils.isValidIp4Cidr(cidr)) {
+                    throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr);
+                }
+            }
+        }
+    }
+
+    /**
+     * Validates the source start and end ports for the given network ACL rule.
+     * If both ports (start and end) are null, we do not execute validations. Otherwise, we check the following:
+     * <ul>
+     *  <li> Check if start port is valid using {@link NetUtils#isValidPort(int)};
+     *  <li> Check if end port is valid using {@link NetUtils#isValidPort(int)};
+     *  <li> Check if start port is bigger than end port;
+     *  <li> Check if start and end ports were used with protocol 'all'
+     *  </ul>
+     *  All of the above cases will generate an {@link InvalidParameterValueException}.
+     */
+    protected void validateSourceStartAndEndPorts(NetworkACLItemVO networkACLItemVO) {
+        Integer sourcePortStart = networkACLItemVO.getSourcePortStart();
+        Integer sourcePortEnd = networkACLItemVO.getSourcePortEnd();
+        if (sourcePortStart == null && sourcePortEnd == null) {
+            return;
+        }
+
+        if (!NetUtils.isValidPort(sourcePortStart)) {
+            throw new InvalidParameterValueException("Start public port is an invalid value: " + sourcePortStart);
+        }
+
+        if (!NetUtils.isValidPort(sourcePortEnd)) {
+            throw new InvalidParameterValueException("End public port is an invalid value: " + sourcePortEnd);
+        }
+        if (sourcePortStart > sourcePortEnd) {
+            throw new InvalidParameterValueException(String.format("Start port can't be bigger than end port [startport=%d,endport=%d]", sourcePortStart, sourcePortEnd));
+        }
+        String protocol = networkACLItemVO.getProtocol();
+        if ("all".equalsIgnoreCase(protocol)) {
+            throw new InvalidParameterValueException("start port and end port must be null if protocol = 'all'");
+        }
+    }
+
+    @Override
+    public NetworkACLItem getNetworkACLItem(final long ruleId) {
+        return _networkAclMgr.getNetworkACLItem(ruleId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription = "Applying Network ACL Item", async = true)
+    public boolean applyNetworkACL(final long aclId) throws ResourceUnavailableException {
+        return _networkAclMgr.applyNetworkACL(aclId);
+    }
+
+    @Override
+    public Pair<List<? extends NetworkACLItem>, Integer> listNetworkACLItems(final ListNetworkACLsCmd cmd) {
+        final Long networkId = cmd.getNetworkId();
+        final Long id = cmd.getId();
+        Long aclId = cmd.getAclId();
+        final String trafficType = cmd.getTrafficType();
+        final String protocol = cmd.getProtocol();
+        final String action = cmd.getAction();
+        final Map<String, String> tags = cmd.getTags();
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchBuilder<NetworkACLItemVO> sb = _networkACLItemDao.createSearchBuilder();
+
+        sb.and("id", sb.entity().getId(), Op.EQ);
+        sb.and("aclId", sb.entity().getAclId(), Op.EQ);
+        sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
+        sb.and("protocol", sb.entity().getProtocol(), Op.EQ);
+        sb.and("action", sb.entity().getAction(), Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (aclId == null) {
+            //Join with network_acl table when aclId is not specified to list acl_items within permitted VPCs
+            final SearchBuilder<NetworkACLVO> vpcSearch = _networkACLDao.createSearchBuilder();
+            vpcSearch.and("vpcId", vpcSearch.entity().getVpcId(), Op.IN);
+            sb.join("vpcSearch", vpcSearch, sb.entity().getAclId(), vpcSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchCriteria<NetworkACLItemVO> sc = sb.create();
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (networkId != null) {
+            final Network network = _networkDao.findById(networkId);
+            aclId = network.getNetworkACLId();
+            if (aclId == null) {
+                // No aclId associated with the network.
+                //Return empty list
+                return new Pair(new ArrayList<NetworkACLItem>(), 0);
+            }
+        }
+
+        if (trafficType != null) {
+            sc.setParameters("trafficType", trafficType);
+        }
+
+        if (aclId != null) {
+            // Get VPC and check access
+            final NetworkACL acl = _networkACLDao.findById(aclId);
+            if (acl.getVpcId() != 0) {
+                final Vpc vpc = _vpcDao.findById(acl.getVpcId());
+                if (vpc == null) {
+                    throw new InvalidParameterValueException("Unable to find VPC associated with acl");
+                }
+                _accountMgr.checkAccess(caller, null, true, vpc);
+            }
+            sc.setParameters("aclId", aclId);
+        } else {
+            //ToDo: Add accountId to network_acl_item table for permission check
+
+            // aclId is not specified
+            // List permitted VPCs and filter aclItems
+            final List<Long> permittedAccounts = new ArrayList<Long>();
+            Long domainId = cmd.getDomainId();
+            boolean isRecursive = cmd.isRecursive();
+            final String accountName = cmd.getAccountName();
+            final Long projectId = cmd.getProjectId();
+            final boolean listAll = cmd.listAll();
+            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
+            _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+            domainId = domainIdRecursiveListProject.first();
+            isRecursive = domainIdRecursiveListProject.second();
+            final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+            final SearchBuilder<VpcVO> sbVpc = _vpcDao.createSearchBuilder();
+            _accountMgr.buildACLSearchBuilder(sbVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            final SearchCriteria<VpcVO> scVpc = sbVpc.create();
+            _accountMgr.buildACLSearchCriteria(scVpc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+            final List<VpcVO> vpcs = _vpcDao.search(scVpc, null);
+            final List<Long> vpcIds = new ArrayList<Long>();
+            for (final VpcVO vpc : vpcs) {
+                vpcIds.add(vpc.getId());
+            }
+            //Add vpc_id 0 to list acl_items in default ACL
+            vpcIds.add(0L);
+            sc.setJoinParameters("vpcSearch", "vpcId", vpcIds.toArray());
+        }
+
+        if (protocol != null) {
+            sc.setParameters("protocol", protocol);
+        }
+
+        if (action != null) {
+            sc.setParameters("action", action);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.NetworkACL.toString());
+            for (final String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        final Pair<List<NetworkACLItemVO>, Integer> result = _networkACLItemDao.searchAndCount(sc, filter);
+        final List<NetworkACLItemVO> aclItemVOs = result.first();
+        for (final NetworkACLItemVO item : aclItemVOs) {
+            _networkACLItemDao.loadCidrs(item);
+        }
+        return new Pair<List<? extends NetworkACLItem>, Integer>(aclItemVOs, result.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_DELETE, eventDescription = "Deleting Network ACL Item", async = true)
+    public boolean revokeNetworkACLItem(final long ruleId) {
+        final NetworkACLItemVO aclItem = _networkACLItemDao.findById(ruleId);
+        if (aclItem != null) {
+            final NetworkACL acl = _networkAclMgr.getNetworkACL(aclItem.getAclId());
+
+            final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+
+            if (aclItem.getAclId() == NetworkACL.DEFAULT_ALLOW || aclItem.getAclId() == NetworkACL.DEFAULT_DENY) {
+                throw new InvalidParameterValueException("ACL Items in default ACL cannot be deleted");
+            }
+
+            final Account caller = CallContext.current().getCallingAccount();
+
+            _accountMgr.checkAccess(caller, null, true, vpc);
+
+        }
+        return _networkAclMgr.revokeNetworkACLItem(ruleId);
+    }
+
+    /**
+     * Updates a network ACL with the given values found in the {@link UpdateNetworkACLItemCmd} parameter.
+     * First we will validate the network ACL rule provided in the command using {@link #validateNetworkAclRuleIdAndRetrieveIt(UpdateNetworkACLItemCmd)}.
+     * Then, we validate the ACL itself using {@link #validateNetworkAcl(NetworkACL)}. If all of the validation is ok, we do the following.
+     * <ul>
+     *  <li>Transfer new data to {@link NetworkACLItemVO} that is intended to be updated;
+     *  <li>Validate the ACL rule being updated using {@link #validateNetworkACLItem(NetworkACLItemVO)}.
+     * </ul>
+     *
+     * After the validations and updating the POJO we execute the update in the database using {@link NetworkACLManagerImpl#updateNetworkACLItem(NetworkACLItemVO)}.
+     *
+     */
+    @Override
+    public NetworkACLItem updateNetworkACLItem(UpdateNetworkACLItemCmd updateNetworkACLItemCmd) throws ResourceUnavailableException {
+        NetworkACLItemVO networkACLItemVo = validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmd);
+
+        NetworkACL acl = _networkAclMgr.getNetworkACL(networkACLItemVo.getAclId());
+        validateNetworkAcl(acl);
+
+        transferDataToNetworkAclRulePojo(updateNetworkACLItemCmd, networkACLItemVo, acl);
+        validateNetworkACLItem(networkACLItemVo);
+        return _networkAclMgr.updateNetworkACLItem(networkACLItemVo);
+    }
+
+    /**
+     *  We transfer the update information form {@link UpdateNetworkACLItemCmd} to the {@link NetworkACLItemVO} POJO passed as parameter.
+     *  There is one validation performed here, which is regarding the number of the ACL. We will check if there is already an ACL rule with that number, and if this is the case an {@link InvalidParameterValueException} is thrown.
+     *  All of the parameters in {@link UpdateNetworkACLItemCmd} that are not null will be set to their corresponding fields in {@link NetworkACLItemVO}.
+     *  If the parameter {@link UpdateNetworkACLItemCmd#isPartialUpgrade()} returns false, we will use null parameters, which will allow us to completely update the ACL rule.
+     *  However, the number and custom Uuid will never be set to null. Therefore, if it is not a partial upgrade, these values will remain the same.
+     *
+     *  We use {@link #validateAndCreateNetworkAclRuleAction(String)} when converting an action as {@link String} to its Enum corresponding value.
+     */
+    protected void transferDataToNetworkAclRulePojo(UpdateNetworkACLItemCmd updateNetworkACLItemCmd, NetworkACLItemVO networkACLItemVo, NetworkACL acl) {
+        Integer number = updateNetworkACLItemCmd.getNumber();
+        if (number != null) {
+            NetworkACLItemVO aclNumber = _networkACLItemDao.findByAclAndNumber(acl.getId(), number);
+            if (aclNumber != null && aclNumber.getId() != networkACLItemVo.getId()) {
+                throw new InvalidParameterValueException("ACL item with number " + number + " already exists in ACL: " + acl.getUuid());
+            }
+            networkACLItemVo.setNumber(number);
+        }
+        boolean isPartialUpgrade = updateNetworkACLItemCmd.isPartialUpgrade();
+
+        Integer sourcePortStart = updateNetworkACLItemCmd.getSourcePortStart();
+        if (!isPartialUpgrade || sourcePortStart != null) {
+            networkACLItemVo.setSourcePortStart(sourcePortStart);
+        }
+        Integer sourcePortEnd = updateNetworkACLItemCmd.getSourcePortEnd();
+        if (!isPartialUpgrade || sourcePortEnd != null) {
+            networkACLItemVo.setSourcePortEnd(sourcePortEnd);
+        }
+        List<String> sourceCidrList = updateNetworkACLItemCmd.getSourceCidrList();
+        if (!isPartialUpgrade || CollectionUtils.isNotEmpty(sourceCidrList)) {
+            networkACLItemVo.setSourceCidrList(sourceCidrList);
+        }
+        String protocol = updateNetworkACLItemCmd.getProtocol();
+        if (!isPartialUpgrade || StringUtils.isNotBlank(protocol)) {
+            networkACLItemVo.setProtocol(protocol);
+        }
+        Integer icmpCode = updateNetworkACLItemCmd.getIcmpCode();
+        if (!isPartialUpgrade || icmpCode != null) {
+            networkACLItemVo.setIcmpCode(icmpCode);
+        }
+        Integer icmpType = updateNetworkACLItemCmd.getIcmpType();
+        if (!isPartialUpgrade || icmpType != null) {
+            networkACLItemVo.setIcmpType(icmpType);
+        }
+        String action = updateNetworkACLItemCmd.getAction();
+        if (!isPartialUpgrade || StringUtils.isNotBlank(action)) {
+            Action aclRuleAction = validateAndCreateNetworkAclRuleAction(action);
+            networkACLItemVo.setAction(aclRuleAction);
+        }
+        TrafficType trafficType = updateNetworkACLItemCmd.getTrafficType();
+        if (!isPartialUpgrade || trafficType != null) {
+            networkACLItemVo.setTrafficType(trafficType);
+        }
+        String customId = updateNetworkACLItemCmd.getCustomId();
+        if (StringUtils.isNotBlank(customId)) {
+            networkACLItemVo.setUuid(customId);
+        }
+        boolean display = updateNetworkACLItemCmd.isDisplay();
+        if (!isPartialUpgrade || display != networkACLItemVo.isDisplay()) {
+            networkACLItemVo.setDisplay(display);
+        }
+        String reason = updateNetworkACLItemCmd.getReason();
+        if (!isPartialUpgrade || StringUtils.isNotBlank(reason)) {
+            networkACLItemVo.setReason(reason);
+        }
+    }
+
+    /**
+     * We validate the network ACL rule ID provided. If not ACL rule is found with the given Id an {@link InvalidParameterValueException} is thrown.
+     * If an ACL rule is found, we return the clone of the rule to avoid messing up with CGlib enhanced objects that might be linked to database entries.
+     */
+    protected NetworkACLItemVO validateNetworkAclRuleIdAndRetrieveIt(UpdateNetworkACLItemCmd updateNetworkACLItemCmd) {
+        Long id = updateNetworkACLItemCmd.getId();
+        NetworkACLItemVO networkACLItemVoFromDatabase = _networkACLItemDao.findById(id);
+        if (networkACLItemVoFromDatabase == null) {
+            throw new InvalidParameterValueException(String.format("Unable to find ACL rule with ID [%s]", id));
+        }
+        return networkACLItemVoFromDatabase.clone();
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_UPDATE, eventDescription = "updating network acl", async = true)
+    public NetworkACL updateNetworkACL(UpdateNetworkACLListCmd updateNetworkACLListCmd) {
+        Long id = updateNetworkACLListCmd.getId();
+        NetworkACLVO acl = _networkACLDao.findById(id);
+        Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, vpc);
+
+        String name = updateNetworkACLListCmd.getName();
+        if (StringUtils.isNotBlank(name)) {
+            acl.setName(name);
+        }
+        String description = updateNetworkACLListCmd.getDescription();
+        if (StringUtils.isNotBlank(description)) {
+            acl.setDescription(description);
+        }
+        String customId = updateNetworkACLListCmd.getCustomId();
+        if (StringUtils.isNotBlank(customId)) {
+            acl.setUuid(customId);
+        }
+        Boolean forDisplay = updateNetworkACLListCmd.getDisplay();
+        if (forDisplay != null) {
+            acl.setDisplay(forDisplay);
+        }
+        _networkACLDao.update(id, acl);
+        return _networkACLDao.findById(id);
+    }
+
+    @Override
+    public NetworkACLItem moveNetworkAclRuleToNewPosition(MoveNetworkAclItemCmd moveNetworkAclItemCmd) {
+        String uuidRuleBeingMoved = moveNetworkAclItemCmd.getUuidRuleBeingMoved();
+        String nextAclRuleUuid = moveNetworkAclItemCmd.getNextAclRuleUuid();
+        String previousAclRuleUuid = moveNetworkAclItemCmd.getPreviousAclRuleUuid();
+
+        if (StringUtils.isBlank(previousAclRuleUuid) && StringUtils.isBlank(nextAclRuleUuid)) {
+            throw new InvalidParameterValueException("Both previous and next ACL rule IDs cannot be blank.");
+        }
+
+        NetworkACLItemVO ruleBeingMoved = _networkACLItemDao.findByUuid(uuidRuleBeingMoved);
+        if (ruleBeingMoved == null) {
+            throw new InvalidParameterValueException(String.format("Could not find a rule with ID[%s]", uuidRuleBeingMoved));
+        }
+        NetworkACLItemVO previousRule = retrieveAndValidateAclRule(previousAclRuleUuid);
+        NetworkACLItemVO nextRule = retrieveAndValidateAclRule(nextAclRuleUuid);
+
+        validateMoveAclRulesData(ruleBeingMoved, previousRule, nextRule);
+
+        try {
+            NetworkACLVO lockedAcl = _networkACLDao.acquireInLockTable(ruleBeingMoved.getAclId());
+            List<NetworkACLItemVO> allAclRules = getAllAclRulesSortedByNumber(lockedAcl.getId());
+            validateAclConsistency(moveNetworkAclItemCmd, lockedAcl, allAclRules);
+
+            if (previousRule == null) {
+                return moveRuleToTheTop(ruleBeingMoved, allAclRules);
+            }
+            if (nextRule == null) {
+                return moveRuleToTheBottom(ruleBeingMoved, allAclRules);
+            }
+            return moveRuleBetweenAclRules(ruleBeingMoved, allAclRules, previousRule, nextRule);
+        } finally {
+            _networkACLDao.releaseFromLockTable(ruleBeingMoved.getAclId());
+        }
+    }
+
+    /**
+     * Validates the consistency of the ACL; the validation process is the following.
+     * <ul>
+     *  <li> If the ACL does not have rules yet, we do not have any validation to perform;
+     *  <li> we will check first if the user provided a consistency hash; if not, we will log a warning message informing administrators that the user is performing the call is assuming the risks of applying ACL replacement without a consistency check;
+     *  <li> if the ACL consistency hash is entered by the user, we check if it is the same as we currently have in the database. If it is different we throw an exception.
+     * </ul>
+     *
+     * If the consistency hash sent by the user is the same as the one we get with the database data we should be safe to proceed.
+     */
+    protected void validateAclConsistency(MoveNetworkAclItemCmd moveNetworkAclItemCmd, NetworkACLVO lockedAcl, List<NetworkACLItemVO> allAclRules) {
+        if (CollectionUtils.isEmpty(allAclRules)) {
+            s_logger.debug(String.format("No ACL rules for [id=%s, name=%s]. Therefore, there is no need for consistency validation.", lockedAcl.getUuid(), lockedAcl.getName()));
+            return;
+        }
+        String aclConsistencyHash = moveNetworkAclItemCmd.getAclConsistencyHash();
+        if (StringUtils.isBlank(aclConsistencyHash)) {
+            User callingUser = CallContext.current().getCallingUser();
+            Account callingAccount = CallContext.current().getCallingAccount();
+
+            s_logger.warn(String.format(
+                    "User [id=%s, name=%s] from Account [id=%s, name=%s] has not entered an ACL consistency hash to execute the replacement of an ACL rule. Therefore, she/he is assuming all of the risks of procedding without this validation.",
+                    callingUser.getUuid(), callingUser.getUsername(), callingAccount.getUuid(), callingAccount.getAccountName()));
+            return;
+        }
+        String aclRulesUuids = StringUtils.EMPTY;
+        for (NetworkACLItemVO rule : allAclRules) {
+            aclRulesUuids += rule.getUuid();
+        }
+        String md5UuidsSortedByNumber = DigestUtils.md5Hex(aclRulesUuids);
+        if (!md5UuidsSortedByNumber.equals(aclConsistencyHash)) {
+            throw new InvalidParameterValueException("It seems that the access control list in the database is not in the state that you used to apply the changed. Could you try it again?");
+        }
+    }
+
+    /**
+     * Loads all ACL rules from given network ACL list. Then, the ACL rules will be sorted according to the 'number' field in ascending order.
+     */
+    protected List<NetworkACLItemVO> getAllAclRulesSortedByNumber(long aclId) {
+        List<NetworkACLItemVO> allAclRules = _networkACLItemDao.listByACL(aclId);
+        Collections.sort(allAclRules, new Comparator<NetworkACLItemVO>() {
+            @Override
+            public int compare(NetworkACLItemVO o1, NetworkACLItemVO o2) {
+                return o1.number - o2.number;
+            }
+        });
+        return allAclRules;
+    }
+
+    /**
+     * Moves an ACL to the space between to other rules. If there is already enough room to accommodate the ACL rule being moved, we simply get the 'number' field from the previous ACL rule and add one, and then define this new value as the 'number' value for the ACL rule being moved.
+     * Otherwise, we will need to make room. This process is executed via {@link #updateAclRuleToNewPositionAndExecuteShiftIfNecessary(NetworkACLItemVO, int, List, int)}, which will create the space between ACL rules if necessary. This involves shifting ACL rules to accommodate the rule being moved.
+     */
+    protected NetworkACLItem moveRuleBetweenAclRules(NetworkACLItemVO ruleBeingMoved, List<NetworkACLItemVO> allAclRules, NetworkACLItemVO previousRule, NetworkACLItemVO nextRule) {
+        if (previousRule.getNumber() + 1 != nextRule.getNumber()) {
+            int newNumberFieldValue = previousRule.getNumber() + 1;
+            for (NetworkACLItemVO networkACLItemVO : allAclRules) {
+                if (networkACLItemVO.getNumber() == newNumberFieldValue) {
+                    throw new InvalidParameterValueException("There are some inconsistencies with the data you sent. The new position calculated already has a ACL rule on it.");
+                }
+            }
+            ruleBeingMoved.setNumber(newNumberFieldValue);
+            _networkACLItemDao.updateNumberFieldNetworkItem(ruleBeingMoved.getId(), newNumberFieldValue);
+            return _networkACLItemDao.findById(ruleBeingMoved.getId());
+        }
+        int positionToStartProcessing = 0;
+        for (int i = 0; i < allAclRules.size(); i++) {
+            if (allAclRules.get(i).getId() == previousRule.getId()) {
+                positionToStartProcessing = i + 1;
+                break;
+            }
+        }
+        return updateAclRuleToNewPositionAndExecuteShiftIfNecessary(ruleBeingMoved, previousRule.getNumber() + 1, allAclRules, positionToStartProcessing);
+    }
+
+    /**
+     *  Moves a network ACL rule to the bottom of the list. This is executed by getting the 'number' field of the last ACL rule from the ACL list, and incrementing one.
+     *  This new value is assigned to the network ACL being moved and updated in the database using {@link NetworkACLItemDao#updateNumberFieldNetworkItem(long, int)}.
+     */
+    protected NetworkACLItem moveRuleToTheBottom(NetworkACLItemVO ruleBeingMoved, List<NetworkACLItemVO> allAclRules) {
+        NetworkACLItemVO lastAclRule = allAclRules.get(allAclRules.size() - 1);
+
+        int newNumberFieldValue = lastAclRule.getNumber() + 1;
+        ruleBeingMoved.setNumber(newNumberFieldValue);
+
+        _networkACLItemDao.updateNumberFieldNetworkItem(ruleBeingMoved.getId(), newNumberFieldValue);
+        return _networkACLItemDao.findById(ruleBeingMoved.getId());
+    }
+
+    /**
+     *  Move the rule to the top of the ACL rule list. This means that the ACL rule being moved will receive the position '1'.
+     *  Also, if necessary other ACL rules will have their 'number' field updated to create room for the new top rule.
+     */
+    protected NetworkACLItem moveRuleToTheTop(NetworkACLItemVO ruleBeingMoved, List<NetworkACLItemVO> allAclRules) {
+        return updateAclRuleToNewPositionAndExecuteShiftIfNecessary(ruleBeingMoved, 1, allAclRules, 0);
+    }
+
+    /**
+     * Updates the ACL rule number executing the shift on subsequent ACL rules if necessary.
+     * For example, if we have the following ACL rules:
+     * <ul>
+     *  <li> ACL A - number 1
+     *  <li> ACL B - number 2
+     *  <li> ACL C - number 3
+     *  <li> ACL D - number 12
+     * </ul>
+     * If we move 'ACL D' to a place  between 'ACL A' and 'ACL B', this method will execute the shift needded to create the space for 'ACL D'.
+     * After applying this method, we will have the following condition.
+     * <ul>
+     *  <li> ACL A - number 1
+     *  <li> ACL D - number 2
+     *  <li> ACL B - number 3
+     *  <li> ACL C - number 4
+     * </ul>
+     */
+    protected NetworkACLItem updateAclRuleToNewPositionAndExecuteShiftIfNecessary(NetworkACLItemVO ruleBeingMoved, int newNumberFieldValue, List<NetworkACLItemVO> allAclRules,
+            int indexToStartProcessing) {
+        ruleBeingMoved.setNumber(newNumberFieldValue);
+        for (int i = indexToStartProcessing; i < allAclRules.size(); i++) {
+            NetworkACLItemVO networkACLItemVO = allAclRules.get(i);
+            if (networkACLItemVO.getId() == ruleBeingMoved.getId()) {
+                continue;
+            }
+            if (newNumberFieldValue != networkACLItemVO.getNumber()) {
+                break;
+            }
+            int newNumberFieldValueNextAclRule = newNumberFieldValue + 1;
+            updateAclRuleToNewPositionAndExecuteShiftIfNecessary(networkACLItemVO, newNumberFieldValueNextAclRule, allAclRules, i);
+        }
+        _networkACLItemDao.updateNumberFieldNetworkItem(ruleBeingMoved.getId(), newNumberFieldValue);
+        return _networkACLItemDao.findById(ruleBeingMoved.getId());
+    }
+
+    /**
+     * Searches in the database for an ACL rule by its UUID.
+     * An {@link InvalidParameterValueException} is thrown if no ACL rule is found with the given UUID.
+     */
+    protected NetworkACLItemVO retrieveAndValidateAclRule(String aclRuleUuid) {
+        if (StringUtils.isBlank(aclRuleUuid)) {
+            return null;
+        }
+        NetworkACLItemVO aclRule = _networkACLItemDao.findByUuid(aclRuleUuid);
+        if (aclRule == null) {
+            throw new InvalidParameterValueException(String.format("Could not find rule with ID [%s]", aclRuleUuid));
+        }
+        return aclRule;
+    }
+
+    /**
+     *  Validates if the data provided to move the ACL rule is supported by this implementation. The user needs to provide a valid ACL UUID, and at least one of the previous or the next ACL rule.
+     *  The validation is as follows:
+     *  <ul>
+     *      <li> If both ACL rules 'previous' and 'next' are invalid, we throw an {@link InvalidParameterValueException};
+     *      <li> informed previous and next ACL rules must have the same ACL ID as the rule being moved; otherwise, an {@link InvalidParameterValueException} is thrown;
+     *      <li> then we check if the user trying to move ACL rules has access to the VPC, where the ACL rules are being applied.
+     *  </ul>
+     */
+    protected void validateMoveAclRulesData(NetworkACLItemVO ruleBeingMoved, NetworkACLItemVO previousRule, NetworkACLItemVO nextRule) {
+        if (nextRule == null && previousRule == null) {
+            throw new InvalidParameterValueException("Both previous and next ACL rule IDs cannot be invalid.");
+        }
+        long aclId = ruleBeingMoved.getAclId();
+
+        if ((nextRule != null && nextRule.getAclId() != aclId) || (previousRule != null && previousRule.getAclId() != aclId)) {
+            throw new InvalidParameterValueException("Cannot use ACL rules from differenting ACLs. Rule being moved.");
+        }
+        NetworkACLVO acl = _networkACLDao.findById(aclId);
+        Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, vpc);
+    }
+}
\ No newline at end of file
diff --git a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java b/server/src/main/java/com/cloud/network/vpc/PrivateGatewayProfile.java
similarity index 100%
rename from server/src/com/cloud/network/vpc/PrivateGatewayProfile.java
rename to server/src/main/java/com/cloud/network/vpc/PrivateGatewayProfile.java
diff --git a/server/src/main/java/com/cloud/network/vpc/PrivateIpAddress.java b/server/src/main/java/com/cloud/network/vpc/PrivateIpAddress.java
new file mode 100644
index 0000000..6ec880f
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/vpc/PrivateIpAddress.java
@@ -0,0 +1,81 @@
+// 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.network.vpc;
+
+public class PrivateIpAddress implements PrivateIp {
+    String broadcastUri;
+    String gateway;
+    String netmask;
+    String ipAddress;
+    String macAddress;
+    long networkId;
+    boolean sourceNat;
+
+    /**
+     * @param privateIp
+     * @param broadcastUri
+     * @param gateway
+     * @param netmask
+     * @param macAddress TODO
+     * @param physicalNetworkId TODO
+     */
+    public PrivateIpAddress(PrivateIpVO privateIp, String broadcastUri, String gateway, String netmask, String macAddress) {
+        super();
+        this.ipAddress = privateIp.getIpAddress();
+        this.broadcastUri = broadcastUri;
+        this.gateway = gateway;
+        this.netmask = netmask;
+        this.macAddress = macAddress;
+        this.networkId = privateIp.getNetworkId();
+        this.sourceNat = privateIp.isSourceNat();
+    }
+
+    @Override
+    public String getBroadcastUri() {
+        return broadcastUri;
+    }
+
+    @Override
+    public String getGateway() {
+        return gateway;
+    }
+
+    @Override
+    public String getNetmask() {
+        return netmask;
+    }
+
+    @Override
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public String getMacAddress() {
+        return macAddress;
+    }
+
+    @Override
+    public long getNetworkId() {
+        return networkId;
+    }
+
+    @Override
+    public boolean getSourceNat() {
+        return sourceNat;
+    }
+}
diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
new file mode 100644
index 0000000..fef0851
--- /dev/null
+++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java
@@ -0,0 +1,2506 @@
+// 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.network.vpc;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
+import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.VpcProvider;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
+import com.cloud.network.vpc.VpcOffering.State;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.network.vpc.dao.StaticRouteDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.network.vpc.dao.VpcOfferingDao;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
+import com.cloud.network.vpc.dao.VpcServiceMapDao;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.org.Grouping;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExceptionUtil;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.dao.DomainRouterDao;
+
+public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvisioningService, VpcService {
+    private static final Logger s_logger = Logger.getLogger(VpcManagerImpl.class);
+
+    public static final String SERVICE = "service";
+    public static final String CAPABILITYTYPE = "capabilitytype";
+    public static final String CAPABILITYVALUE = "capabilityvalue";
+    public static final String TRUE_VALUE = "true";
+    public static final String FALSE_VALUE = "false";
+
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    VpcOfferingDao _vpcOffDao;
+    @Inject
+    VpcOfferingServiceMapDao _vpcOffSvcMapDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    NetworkDao _ntwkDao;
+    @Inject
+    NetworkOrchestrationService _ntwkMgr;
+    @Inject
+    NetworkModel _ntwkModel;
+    @Inject
+    NetworkService _ntwkSvc;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    VpcGatewayDao _vpcGatewayDao;
+    @Inject
+    PrivateIpDao _privateIpDao;
+    @Inject
+    StaticRouteDao _staticRouteDao;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOffServiceDao;
+    @Inject
+    VpcOfferingServiceMapDao _vpcOffServiceDao;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    Site2SiteVpnManager _s2sVpnMgr;
+    @Inject
+    VlanDao _vlanDao = null;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    VpcServiceMapDao _vpcSrvcDao;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    NetworkACLDao _networkAclDao;
+    @Inject
+    NetworkACLManager _networkAclMgr;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    VpcVirtualNetworkApplianceManager _routerService;
+    @Inject
+    DomainRouterDao _routerDao;
+
+    @Inject
+    private VpcPrivateGatewayTransactionCallable vpcTxCallable;
+
+    private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
+    private List<VpcProvider> vpcElements = null;
+    private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
+    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler,
+            Provider.JuniperContrailVpcRouter, Provider.Ovs, Provider.NuageVsp, Provider.BigSwitchBcf, Provider.ConfigDrive);
+
+    int _cleanupInterval;
+    int _maxNetworks;
+    SearchBuilder<IPAddressVO> IpAddressSearch;
+
+    protected final List<HypervisorType> hTypes = new ArrayList<HypervisorType>();
+
+    @PostConstruct
+    protected void setupSupportedVpcHypervisorsList() {
+        hTypes.add(HypervisorType.XenServer);
+        hTypes.add(HypervisorType.VMware);
+        hTypes.add(HypervisorType.KVM);
+        hTypes.add(HypervisorType.Simulator);
+        hTypes.add(HypervisorType.LXC);
+        hTypes.add(HypervisorType.Hyperv);
+        hTypes.add(HypervisorType.Ovm3);
+    }
+
+    @Override
+    @DB
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        // configure default vpc offering
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+
+                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
+                    s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
+
+                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
+                    final Set<Provider> defaultProviders = new HashSet<Provider>();
+                    defaultProviders.add(Provider.VPCVirtualRouter);
+                    for (final Service svc : getSupportedServices()) {
+                        if (svc == Service.Lb) {
+                            final Set<Provider> lbProviders = new HashSet<Provider>();
+                            lbProviders.add(Provider.VPCVirtualRouter);
+                            lbProviders.add(Provider.InternalLbVm);
+                            svcProviderMap.put(svc, lbProviders);
+                        } else {
+                            svcProviderMap.put(svc, defaultProviders);
+                        }
+                    }
+                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, false);
+                }
+
+                // configure default vpc offering with Netscaler as LB Provider
+                if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName) == null) {
+                    s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
+                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
+                    final Set<Provider> defaultProviders = new HashSet<Provider>();
+                    defaultProviders.add(Provider.VPCVirtualRouter);
+                    for (final Service svc : getSupportedServices()) {
+                        if (svc == Service.Lb) {
+                            final Set<Provider> lbProviders = new HashSet<Provider>();
+                            lbProviders.add(Provider.Netscaler);
+                            lbProviders.add(Provider.InternalLbVm);
+                            svcProviderMap.put(svc, lbProviders);
+                        } else {
+                            svcProviderMap.put(svc, defaultProviders);
+                        }
+                    }
+                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false, false, false);
+
+                }
+
+                if (_vpcOffDao.findByUniqueName(VpcOffering.redundantVPCOfferingName) == null) {
+                    s_logger.debug("Creating Redundant VPC offering " + VpcOffering.redundantVPCOfferingName);
+
+                    final Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
+                    final Set<Provider> defaultProviders = new HashSet<Provider>();
+                    defaultProviders.add(Provider.VPCVirtualRouter);
+                    for (final Service svc : getSupportedServices()) {
+                        if (svc == Service.Lb) {
+                            final Set<Provider> lbProviders = new HashSet<Provider>();
+                            lbProviders.add(Provider.VPCVirtualRouter);
+                            lbProviders.add(Provider.InternalLbVm);
+                            svcProviderMap.put(svc, lbProviders);
+                        } else {
+                            svcProviderMap.put(svc, defaultProviders);
+                        }
+                    }
+                    createVpcOffering(VpcOffering.redundantVPCOfferingName, VpcOffering.redundantVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, true);
+                }
+            }
+        });
+
+        final Map<String, String> configs = _configDao.getConfiguration(params);
+        final String value = configs.get(Config.VpcCleanupInterval.key());
+        _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60); // 1 hour
+
+        final String maxNtwks = configs.get(Config.VpcMaxNetworks.key());
+        _maxNetworks = NumbersUtil.parseInt(maxNtwks, 3); // max=3 is default
+
+        IpAddressSearch = _ipAddressDao.createSearchBuilder();
+        IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
+        IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ);
+        IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ);
+        IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ);
+        final SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
+        virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
+        IpAddressSearch
+        .join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
+        IpAddressSearch.done();
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        _executor.scheduleAtFixedRate(new VpcCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public List<? extends Network> getVpcNetworks(final long vpcId) {
+        return _ntwkDao.listByVpc(vpcId);
+    }
+
+    @Override
+    public VpcOffering getVpcOffering(final long vpcOffId) {
+        return _vpcOffDao.findById(vpcOffId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true)
+    public VpcOffering createVpcOffering(final String name, final String displayText, final List<String> supportedServices, final Map<String, List<String>> serviceProviders,
+            final Map serviceCapabilitystList, final Long serviceOfferingId) {
+
+        final Map<Network.Service, Set<Network.Provider>> svcProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
+        final Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
+        defaultProviders.add(Provider.VPCVirtualRouter);
+        // Just here for 4.1, replaced by commit 836ce6c1 in newer versions
+        final Set<Network.Provider> sdnProviders = new HashSet<Network.Provider>();
+        sdnProviders.add(Provider.NiciraNvp);
+        sdnProviders.add(Provider.JuniperContrailVpcRouter);
+        sdnProviders.add(Provider.NuageVsp);
+
+        boolean sourceNatSvc = false;
+        boolean firewallSvs = false;
+        // populate the services first
+        for (final String serviceName : supportedServices) {
+            // validate if the service is supported
+            final Service service = Network.Service.getService(serviceName);
+            if (service == null || nonSupportedServices.contains(service)) {
+                throw new InvalidParameterValueException("Service " + serviceName + " is not supported in VPC");
+            }
+
+            if (service == Service.Connectivity) {
+                s_logger.debug("Applying Connectivity workaround, setting provider to NiciraNvp");
+                svcProviderMap.put(service, sdnProviders);
+            } else {
+                svcProviderMap.put(service, defaultProviders);
+            }
+            if (service == Service.NetworkACL) {
+                firewallSvs = true;
+            }
+
+            if (service == Service.SourceNat) {
+                sourceNatSvc = true;
+            }
+        }
+
+        if (!sourceNatSvc) {
+            s_logger.debug("Automatically adding source nat service to the list of VPC services");
+            svcProviderMap.put(Service.SourceNat, defaultProviders);
+        }
+
+        if (!firewallSvs) {
+            s_logger.debug("Automatically adding network ACL service to the list of VPC services");
+            svcProviderMap.put(Service.NetworkACL, defaultProviders);
+        }
+
+        if (serviceProviders != null) {
+            for (final Entry<String, List<String>> serviceEntry : serviceProviders.entrySet()) {
+                final Network.Service service = Network.Service.getService(serviceEntry.getKey());
+                if (svcProviderMap.containsKey(service)) {
+                    final Set<Provider> providers = new HashSet<Provider>();
+                    for (final String prvNameStr : serviceEntry.getValue()) {
+                        // check if provider is supported
+                        final Network.Provider provider = Network.Provider.getProvider(prvNameStr);
+                        if (provider == null) {
+                            throw new InvalidParameterValueException("Invalid service provider: " + prvNameStr);
+                        }
+
+                        providers.add(provider);
+                    }
+                    svcProviderMap.put(service, providers);
+                } else {
+                    throw new InvalidParameterValueException("Service " + serviceEntry.getKey() + " is not enabled for the network " + "offering, can't add a provider to it");
+                }
+            }
+        }
+
+        // add gateway provider (if sourceNat provider is enabled)
+        final Set<Provider> sourceNatServiceProviders = svcProviderMap.get(Service.SourceNat);
+        if (CollectionUtils.isNotEmpty(sourceNatServiceProviders)) {
+            svcProviderMap.put(Service.Gateway, sourceNatServiceProviders);
+        }
+
+        validateConnectivtyServiceCapabilities(svcProviderMap.get(Service.Connectivity), serviceCapabilitystList);
+
+        final boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
+        final boolean offersRegionLevelVPC = isVpcOfferingForRegionLevelVpc(serviceCapabilitystList);
+        final boolean redundantRouter = isVpcOfferingRedundantRouter(serviceCapabilitystList);
+        final VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null, serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC,
+                redundantRouter);
+        CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
+
+        return offering;
+    }
+
+    @DB
+    protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
+            final boolean isDefault, final State state, final Long serviceOfferingId, final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC,
+            final boolean redundantRouter) {
+
+        return Transaction.execute(new TransactionCallback<VpcOffering>() {
+            @Override
+            public VpcOffering doInTransaction(final TransactionStatus status) {
+                // create vpc offering object
+                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC, redundantRouter);
+
+                if (state != null) {
+                    offering.setState(state);
+                }
+                s_logger.debug("Adding vpc offering " + offering);
+                offering = _vpcOffDao.persist(offering);
+                // populate services and providers
+                if (svcProviderMap != null) {
+                    for (final Network.Service service : svcProviderMap.keySet()) {
+                        final Set<Provider> providers = svcProviderMap.get(service);
+                        if (providers != null && !providers.isEmpty()) {
+                            for (final Network.Provider provider : providers) {
+                                final VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
+                                _vpcOffSvcMapDao.persist(offService);
+                                s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
+                            }
+                        } else {
+                            throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
+                        }
+                    }
+                }
+
+                return offering;
+            }
+        });
+    }
+
+    protected void checkCapabilityPerServiceProvider(final Set<Provider> providers, final Capability capability, final Service service) {
+        // TODO Shouldn't it fail it there are no providers?
+        if (providers != null) {
+            for (final Provider provider : providers) {
+                final NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
+                final Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
+                if (capabilities != null && !capabilities.isEmpty()) {
+                    final Map<Capability, String> connectivityCapabilities = capabilities.get(service);
+                    if (connectivityCapabilities == null || connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(capability)) {
+                        throw new InvalidParameterValueException(String.format("Provider %s does not support %s  capability.", provider.getName(), capability.getName()));
+                    }
+                }
+            }
+        }
+    }
+
+    private void validateConnectivtyServiceCapabilities(final Set<Provider> providers, final Map serviceCapabilitystList) {
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            final Collection serviceCapabilityCollection = serviceCapabilitystList.values();
+            final Iterator iter = serviceCapabilityCollection.iterator();
+
+            while (iter.hasNext()) {
+                final HashMap<String, String> svcCapabilityMap = (HashMap<String, String>) iter.next();
+                Capability capability = null;
+                final String svc = svcCapabilityMap.get(SERVICE);
+                final String capabilityName = svcCapabilityMap.get(CAPABILITYTYPE);
+                final String capabilityValue = svcCapabilityMap.get(CAPABILITYVALUE);
+                if (capabilityName != null) {
+                    capability = Capability.getCapability(capabilityName);
+                }
+
+                if (capability == null || capabilityValue == null) {
+                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+                }
+                final Service usedService = Service.getService(svc);
+
+                checkCapabilityPerServiceProvider(providers, capability, usedService);
+
+                if (!capabilityValue.equalsIgnoreCase(TRUE_VALUE) && !capabilityValue.equalsIgnoreCase(FALSE_VALUE)) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+            }
+        }
+    }
+
+    private boolean findCapabilityForService(final Map serviceCapabilitystList, final Capability capability, final Service service) {
+        boolean foundCapability = false;
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            final Iterator iter = serviceCapabilitystList.values().iterator();
+            while (iter.hasNext()) {
+                final HashMap<String, String> currentCapabilityMap = (HashMap<String, String>) iter.next();
+                final String currentCapabilityService = currentCapabilityMap.get(SERVICE);
+                final String currentCapabilityName = currentCapabilityMap.get(CAPABILITYTYPE);
+                final String currentCapabilityValue = currentCapabilityMap.get(CAPABILITYVALUE);
+
+                if (currentCapabilityName == null || currentCapabilityService == null || currentCapabilityValue == null) {
+                    throw new InvalidParameterValueException(String.format("Invalid capability with name %s, value %s and service %s", currentCapabilityName,
+                            currentCapabilityValue, currentCapabilityService));
+                }
+
+                if (currentCapabilityName.equalsIgnoreCase(capability.getName())) {
+                    foundCapability = currentCapabilityValue.equalsIgnoreCase(TRUE_VALUE);
+
+                    if (!currentCapabilityService.equalsIgnoreCase(service.getName())) {
+                        throw new InvalidParameterValueException(String.format("Invalid Service: %s specified. Capability %s can be specified only for service %s",
+                                currentCapabilityService, service.getName(), currentCapabilityName));
+                    }
+
+                    break;
+                }
+            }
+        }
+        return foundCapability;
+    }
+
+    private boolean isVpcOfferingForRegionLevelVpc(final Map serviceCapabilitystList) {
+        return findCapabilityForService(serviceCapabilitystList, Capability.RegionLevelVpc, Service.Connectivity);
+    }
+
+    private boolean isVpcOfferingSupportsDistributedRouter(final Map serviceCapabilitystList) {
+        return findCapabilityForService(serviceCapabilitystList, Capability.DistributedRouter, Service.Connectivity);
+    }
+
+    private boolean isVpcOfferingRedundantRouter(final Map serviceCapabilitystList) {
+        return findCapabilityForService(serviceCapabilitystList, Capability.RedundantRouter, Service.SourceNat);
+    }
+
+    @Override
+    public Vpc getActiveVpc(final long vpcId) {
+        return _vpcDao.getActiveVpcById(vpcId);
+    }
+
+    @Override
+    public Map<Service, Set<Provider>> getVpcOffSvcProvidersMap(final long vpcOffId) {
+        final Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
+        final List<VpcOfferingServiceMapVO> map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId);
+
+        for (final VpcOfferingServiceMapVO instance : map) {
+            final Service service = Service.getService(instance.getService());
+            Set<Provider> providers;
+            providers = serviceProviderMap.get(service);
+            if (providers == null) {
+                providers = new HashSet<Provider>();
+            }
+            providers.add(Provider.getProvider(instance.getProvider()));
+            serviceProviderMap.put(service, providers);
+        }
+
+        return serviceProviderMap;
+    }
+
+    @Override
+    public Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(final Long id, final String name, final String displayText, final List<String> supportedServicesStr,
+            final Boolean isDefault, final String keyword, final String state, final Long startIndex, final Long pageSizeVal) {
+        final Filter searchFilter = new Filter(VpcOfferingVO.class, "created", false, null, null);
+        final SearchCriteria<VpcOfferingVO> sc = _vpcOffDao.createSearchCriteria();
+
+        if (keyword != null) {
+            final SearchCriteria<VpcOfferingVO> ssc = _vpcOffDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
+        }
+
+        if (displayText != null) {
+            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
+        }
+
+        if (isDefault != null) {
+            sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", SearchCriteria.Op.EQ, state);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        final List<VpcOfferingVO> offerings = _vpcOffDao.search(sc, searchFilter);
+
+        // filter by supported services
+        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty();
+
+        if (listBySupportedServices) {
+            final List<VpcOfferingVO> supportedOfferings = new ArrayList<VpcOfferingVO>();
+            Service[] supportedServices = null;
+
+            if (listBySupportedServices) {
+                supportedServices = new Service[supportedServicesStr.size()];
+                int i = 0;
+                for (final String supportedServiceStr : supportedServicesStr) {
+                    final Service service = Service.getService(supportedServiceStr);
+                    if (service == null) {
+                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
+                    } else {
+                        supportedServices[i] = service;
+                    }
+                    i++;
+                }
+            }
+
+            for (final VpcOfferingVO offering : offerings) {
+                if (areServicesSupportedByVpcOffering(offering.getId(), supportedServices)) {
+                    supportedOfferings.add(offering);
+                }
+            }
+
+            final List<? extends VpcOffering> wPagination = StringUtils.applyPagination(supportedOfferings, startIndex, pageSizeVal);
+            if (wPagination != null) {
+                final Pair<List<? extends VpcOffering>, Integer> listWPagination = new Pair<List<? extends VpcOffering>, Integer>(wPagination, supportedOfferings.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends VpcOffering>, Integer>(supportedOfferings, supportedOfferings.size());
+        } else {
+            final List<? extends VpcOffering> wPagination = StringUtils.applyPagination(offerings, startIndex, pageSizeVal);
+            if (wPagination != null) {
+                final Pair<List<? extends VpcOffering>, Integer> listWPagination = new Pair<List<? extends VpcOffering>, Integer>(wPagination, offerings.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends VpcOffering>, Integer>(offerings, offerings.size());
+        }
+    }
+
+    protected boolean areServicesSupportedByVpcOffering(final long vpcOffId, final Service... services) {
+        return _vpcOffSvcMapDao.areServicesSupportedByNetworkOffering(vpcOffId, services);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_DELETE, eventDescription = "deleting vpc offering")
+    public boolean deleteVpcOffering(final long offId) {
+        CallContext.current().setEventDetails(" Id: " + offId);
+
+        // Verify vpc offering id
+        final VpcOfferingVO offering = _vpcOffDao.findById(offId);
+        if (offering == null) {
+            throw new InvalidParameterValueException("unable to find vpc offering " + offId);
+        }
+
+        // Don't allow to delete default vpc offerings
+        if (offering.isDefault() == true) {
+            throw new InvalidParameterValueException("Default network offering can't be deleted");
+        }
+
+        // don't allow to delete vpc offering if it's in use by existing vpcs
+        // (the offering can be disabled though)
+        final int vpcCount = _vpcDao.getVpcCountByOfferingId(offId);
+        if (vpcCount > 0) {
+            throw new InvalidParameterValueException("Can't delete vpc offering " + offId + " as its used by " + vpcCount + " vpcs. "
+                    + "To make the network offering unavaiable, disable it");
+        }
+
+        if (_vpcOffDao.remove(offId)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_UPDATE, eventDescription = "updating vpc offering")
+    public VpcOffering updateVpcOffering(final long vpcOffId, final String vpcOfferingName, final String displayText, final String state) {
+        CallContext.current().setEventDetails(" Id: " + vpcOffId);
+
+        // Verify input parameters
+        final VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId);
+        if (offeringToUpdate == null) {
+            throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId);
+        }
+
+        final VpcOfferingVO offering = _vpcOffDao.createForUpdate(vpcOffId);
+
+        if (vpcOfferingName != null) {
+            offering.setName(vpcOfferingName);
+        }
+
+        if (displayText != null) {
+            offering.setDisplayText(displayText);
+        }
+
+        if (state != null) {
+            boolean validState = false;
+            for (final VpcOffering.State st : VpcOffering.State.values()) {
+                if (st.name().equalsIgnoreCase(state)) {
+                    validState = true;
+                    offering.setState(st);
+                }
+            }
+            if (!validState) {
+                throw new InvalidParameterValueException("Incorrect state value: " + state);
+            }
+        }
+
+        if (_vpcOffDao.update(vpcOffId, offering)) {
+            s_logger.debug("Updated VPC offeirng id=" + vpcOffId);
+            return _vpcOffDao.findById(vpcOffId);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create = true)
+    public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwnerId, final String vpcName, final String displayText, final String cidr, String networkDomain,
+            final Boolean displayVpc) throws ResourceAllocationException {
+        final Account caller = CallContext.current().getCallingAccount();
+        final Account owner = _accountMgr.getAccount(vpcOwnerId);
+
+        // Verify that caller can perform actions in behalf of vpc owner
+        _accountMgr.checkAccess(caller, null, false, owner);
+
+        // check resource limit
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.vpc);
+
+        // Validate vpc offering
+        final VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId);
+        if (vpcOff == null || vpcOff.getState() != State.Enabled) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find vpc offering in " + State.Enabled + " state by specified id");
+            if (vpcOff == null) {
+                ex.addProxyObject(String.valueOf(vpcOffId), "vpcOfferingId");
+            } else {
+                ex.addProxyObject(vpcOff.getUuid(), "vpcOfferingId");
+            }
+            throw ex;
+        }
+
+        final boolean isRegionLevelVpcOff = vpcOff.offersRegionLevelVPC();
+        if (isRegionLevelVpcOff && networkDomain == null) {
+            throw new InvalidParameterValueException("Network domain must be specified for region level VPC");
+        }
+
+        // Validate zone
+        final DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by id specified");
+        }
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            // See DataCenterVO.java
+            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "zoneId");
+            throw ex;
+        }
+
+        if (networkDomain == null) {
+            // 1) Get networkDomain from the corresponding account
+            networkDomain = _ntwkModel.getAccountNetworkDomain(owner.getId(), zoneId);
+
+            // 2) If null, generate networkDomain using domain suffix from the
+            // global config variables
+            if (networkDomain == null) {
+                networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
+            }
+        }
+
+        final boolean useDistributedRouter = vpcOff.supportsDistributedRouter();
+        final VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, owner.getId(), owner.getDomainId(), vpcOffId, cidr, networkDomain, useDistributedRouter, isRegionLevelVpcOff,
+                vpcOff.getRedundantRouter());
+
+        return createVpc(displayVpc, vpc);
+    }
+
+    @DB
+    protected Vpc createVpc(final Boolean displayVpc, final VpcVO vpc) {
+        final String cidr = vpc.getCidr();
+        // Validate CIDR
+        if (!NetUtils.isValidIp4Cidr(cidr)) {
+            throw new InvalidParameterValueException("Invalid CIDR specified " + cidr);
+        }
+
+        // cidr has to be RFC 1918 complient
+        if (!NetUtils.validateGuestCidr(cidr)) {
+            throw new InvalidParameterValueException("Guest Cidr " + cidr + " is not RFC1918 compliant");
+        }
+
+        // validate network domain
+        if (!NetUtils.verifyDomainName(vpc.getNetworkDomain())) {
+            throw new InvalidParameterValueException("Invalid network domain. Total length shouldn't exceed 190 chars. Each domain "
+                    + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', " + "the digits '0' through '9', "
+                    + "and the hyphen ('-'); can't start or end with \"-\"");
+        }
+
+        return Transaction.execute(new TransactionCallback<VpcVO>() {
+            @Override
+            public VpcVO doInTransaction(final TransactionStatus status) {
+                if (displayVpc != null) {
+                    vpc.setDisplay(displayVpc);
+                }
+
+                final VpcVO persistedVpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(vpc.getZoneId(), vpc.getVpcOfferingId()));
+                _resourceLimitMgr.incrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
+                s_logger.debug("Created VPC " + persistedVpc);
+
+                return persistedVpc;
+            }
+        });
+    }
+
+    private Map<String, List<String>> finalizeServicesAndProvidersForVpc(final long zoneId, final long offeringId) {
+        final Map<String, List<String>> svcProviders = new HashMap<>();
+        final List<VpcOfferingServiceMapVO> servicesMap = _vpcOffSvcMapDao.listByVpcOffId(offeringId);
+
+        for (final VpcOfferingServiceMapVO serviceMap : servicesMap) {
+            final String service = serviceMap.getService();
+            String provider = serviceMap.getProvider();
+
+            if (provider == null) {
+                // Default to VPCVirtualRouter
+                provider = Provider.VPCVirtualRouter.getName();
+            }
+
+            if (!_ntwkModel.isProviderEnabledInZone(zoneId, provider)) {
+                throw new InvalidParameterValueException("Provider " + provider + " should be enabled in at least one physical network of the zone specified");
+            }
+
+            List<String> providers = null;
+            if (svcProviders.get(service) == null) {
+                providers = new ArrayList<String>();
+            } else {
+                providers = svcProviders.get(service);
+            }
+            providers.add(provider);
+            svcProviders.put(service, providers);
+        }
+
+        return svcProviders;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC")
+    public boolean deleteVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException {
+        CallContext.current().setEventDetails(" Id: " + vpcId);
+        final CallContext ctx = CallContext.current();
+
+        // Verify vpc id
+        final Vpc vpc = _vpcDao.findById(vpcId);
+        if (vpc == null) {
+            throw new InvalidParameterValueException("unable to find VPC id=" + vpcId);
+        }
+
+        // verify permissions
+        _accountMgr.checkAccess(ctx.getCallingAccount(), null, false, vpc);
+        _resourceTagDao.removeByIdAndType(vpcId, ResourceObjectType.Vpc);
+
+        return destroyVpc(vpc, ctx.getCallingAccount(), ctx.getCallingUserId());
+    }
+
+    @Override
+    @DB
+    public boolean destroyVpc(final Vpc vpc, final Account caller, final Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException {
+        s_logger.debug("Destroying vpc " + vpc);
+
+        // don't allow to delete vpc if it's in use by existing non system
+        // networks (system networks are networks of a private gateway of the
+        // VPC,
+        // and they will get removed as a part of VPC cleanup
+        final int networksCount = _ntwkDao.getNonSystemNetworkCountByVpcId(vpc.getId());
+        if (networksCount > 0) {
+            throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks");
+        }
+
+        // mark VPC as inactive
+        if (vpc.getState() != Vpc.State.Inactive) {
+            s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
+            final VpcVO vpcVO = _vpcDao.findById(vpc.getId());
+            vpcVO.setState(Vpc.State.Inactive);
+
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    _vpcDao.update(vpc.getId(), vpcVO);
+
+                    // decrement resource count
+                    _resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
+                }
+            });
+        }
+
+        // shutdown VPC
+        if (!shutdownVpc(vpc.getId())) {
+            s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process");
+            return false;
+        }
+
+        // cleanup vpc resources
+        if (!cleanupVpcResources(vpc.getId(), caller, callerUserId)) {
+            s_logger.warn("Failed to cleanup resources for vpc " + vpc);
+            return false;
+        }
+
+        // update the instance with removed flag only when the cleanup is
+        // executed successfully
+        if (_vpcDao.remove(vpc.getId())) {
+            s_logger.debug("Vpc " + vpc + " is destroyed succesfully");
+            return true;
+        } else {
+            s_logger.warn("Vpc " + vpc + " failed to destroy");
+            return false;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc")
+    public Vpc updateVpc(final long vpcId, final String vpcName, final String displayText, final String customId, final Boolean displayVpc) {
+        CallContext.current().setEventDetails(" Id: " + vpcId);
+        final Account caller = CallContext.current().getCallingAccount();
+
+        // Verify input parameters
+        final VpcVO vpcToUpdate = _vpcDao.findById(vpcId);
+        if (vpcToUpdate == null) {
+            throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
+        }
+
+        _accountMgr.checkAccess(caller, null, false, vpcToUpdate);
+
+        final VpcVO vpc = _vpcDao.createForUpdate(vpcId);
+
+        if (vpcName != null) {
+            vpc.setName(vpcName);
+        }
+
+        if (displayText != null) {
+            vpc.setDisplayText(displayText);
+        }
+
+        if (customId != null) {
+            vpc.setUuid(customId);
+        }
+
+        if (displayVpc != null) {
+            vpc.setDisplay(displayVpc);
+        }
+
+        if (_vpcDao.update(vpcId, vpc)) {
+            s_logger.debug("Updated VPC id=" + vpcId);
+            return _vpcDao.findById(vpcId);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Pair<List<? extends Vpc>, Integer> listVpcs(final Long id, final String vpcName, final String displayText, final List<String> supportedServicesStr, final String cidr,
+            final Long vpcOffId, final String state, final String accountName, Long domainId, final String keyword, final Long startIndex, final Long pageSizeVal,
+            final Long zoneId, Boolean isRecursive, final Boolean listAll, final Boolean restartRequired, final Map<String, String> tags, final Long projectId,
+            final Boolean display) {
+        final Account caller = CallContext.current().getCallingAccount();
+        final List<Long> permittedAccounts = new ArrayList<Long>();
+        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
+                null);
+        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        domainId = domainIdRecursiveListProject.first();
+        isRecursive = domainIdRecursiveListProject.second();
+        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        final Filter searchFilter = new Filter(VpcVO.class, "created", false, null, null);
+
+        final SearchBuilder<VpcVO> sb = _vpcDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("displayText", sb.entity().getDisplayText(), SearchCriteria.Op.LIKE);
+        sb.and("vpcOfferingId", sb.entity().getVpcOfferingId(), SearchCriteria.Op.EQ);
+        sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ);
+        sb.and("cidr", sb.entity().getCidr(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        // now set the SC criteria...
+        final SearchCriteria<VpcVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (keyword != null) {
+            final SearchCriteria<VpcVO> ssc = _vpcDao.createSearchCriteria();
+            ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (vpcName != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + vpcName + "%");
+        }
+
+        if (displayText != null) {
+            sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%");
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Vpc.toString());
+            for (final Map.Entry<String, String> entry : tags.entrySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), entry.getKey());
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), entry.getValue());
+                count++;
+            }
+        }
+
+        if (display != null) {
+            sc.setParameters("display", display);
+        }
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (vpcOffId != null) {
+            sc.addAnd("vpcOfferingId", SearchCriteria.Op.EQ, vpcOffId);
+        }
+
+        if (zoneId != null) {
+            sc.addAnd("zoneId", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", SearchCriteria.Op.EQ, state);
+        }
+
+        if (cidr != null) {
+            sc.addAnd("cidr", SearchCriteria.Op.EQ, cidr);
+        }
+
+        if (restartRequired != null) {
+            sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
+        }
+
+        final List<VpcVO> vpcs = _vpcDao.search(sc, searchFilter);
+
+        // filter by supported services
+        final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !vpcs.isEmpty();
+
+        if (listBySupportedServices) {
+            final List<VpcVO> supportedVpcs = new ArrayList<VpcVO>();
+            Service[] supportedServices = null;
+
+            if (listBySupportedServices) {
+                supportedServices = new Service[supportedServicesStr.size()];
+                int i = 0;
+                for (final String supportedServiceStr : supportedServicesStr) {
+                    final Service service = Service.getService(supportedServiceStr);
+                    if (service == null) {
+                        throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
+                    } else {
+                        supportedServices[i] = service;
+                    }
+                    i++;
+                }
+            }
+
+            for (final VpcVO vpc : vpcs) {
+                if (areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), supportedServices)) {
+                    supportedVpcs.add(vpc);
+                }
+            }
+
+            final List<? extends Vpc> wPagination = StringUtils.applyPagination(supportedVpcs, startIndex, pageSizeVal);
+            if (wPagination != null) {
+                final Pair<List<? extends Vpc>, Integer> listWPagination = new Pair<List<? extends Vpc>, Integer>(wPagination, supportedVpcs.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends Vpc>, Integer>(supportedVpcs, supportedVpcs.size());
+        } else {
+            final List<? extends Vpc> wPagination = StringUtils.applyPagination(vpcs, startIndex, pageSizeVal);
+            if (wPagination != null) {
+                final Pair<List<? extends Vpc>, Integer> listWPagination = new Pair<List<? extends Vpc>, Integer>(wPagination, vpcs.size());
+                return listWPagination;
+            }
+            return new Pair<List<? extends Vpc>, Integer>(vpcs, vpcs.size());
+        }
+    }
+
+    protected List<Service> getSupportedServices() {
+        final List<Service> services = new ArrayList<Service>();
+        services.add(Network.Service.Dhcp);
+        services.add(Network.Service.Dns);
+        services.add(Network.Service.UserData);
+        services.add(Network.Service.NetworkACL);
+        services.add(Network.Service.PortForwarding);
+        services.add(Network.Service.Lb);
+        services.add(Network.Service.SourceNat);
+        services.add(Network.Service.StaticNat);
+        services.add(Network.Service.Gateway);
+        services.add(Network.Service.Vpn);
+        return services;
+    }
+
+    @Override
+    public boolean startVpc(final long vpcId, final boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        final CallContext ctx = CallContext.current();
+        final Account caller = ctx.getCallingAccount();
+        final User callerUser = _accountMgr.getActiveUser(ctx.getCallingUserId());
+
+        // check if vpc exists
+        final Vpc vpc = getActiveVpc(vpcId);
+        if (vpc == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
+            ex.addProxyObject(String.valueOf(vpcId), "VPC");
+            throw ex;
+        }
+
+        // permission check
+        _accountMgr.checkAccess(caller, null, false, vpc);
+
+        final DataCenter dc = _entityMgr.findById(DataCenter.class, vpc.getZoneId());
+
+        final DeployDestination dest = new DeployDestination(dc, null, null, null);
+        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, _accountMgr.getAccount(vpc.getAccountId()));
+
+        boolean result = true;
+        try {
+            if (!startVpc(vpc, dest, context)) {
+                s_logger.warn("Failed to start vpc " + vpc);
+                result = false;
+            }
+        } catch (final Exception ex) {
+            s_logger.warn("Failed to start vpc " + vpc + " due to ", ex);
+            result = false;
+        } finally {
+            // do cleanup
+            if (!result && destroyOnFailure) {
+                s_logger.debug("Destroying vpc " + vpc + " that failed to start");
+                if (destroyVpc(vpc, caller, callerUser.getId())) {
+                    s_logger.warn("Successfully destroyed vpc " + vpc + " that failed to start");
+                } else {
+                    s_logger.warn("Failed to destroy vpc " + vpc + " that failed to start");
+                }
+            }
+        }
+        return result;
+    }
+
+    protected boolean startVpc(final Vpc vpc, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+        // deploy provider
+        boolean success = true;
+        final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
+        for (final VpcProvider element : getVpcElements()) {
+            if (providersToImplement.contains(element.getProvider())) {
+                if (element.implementVpc(vpc, dest, context)) {
+                    s_logger.debug("Vpc " + vpc + " has started successfully");
+                } else {
+                    s_logger.warn("Vpc " + vpc + " failed to start");
+                    success = false;
+                }
+            }
+        }
+        return success;
+    }
+
+    @Override
+    public boolean shutdownVpc(final long vpcId) throws ConcurrentOperationException, ResourceUnavailableException {
+        final CallContext ctx = CallContext.current();
+        final Account caller = ctx.getCallingAccount();
+
+        // check if vpc exists
+        final Vpc vpc = _vpcDao.findById(vpcId);
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
+        }
+
+        // permission check
+        _accountMgr.checkAccess(caller, null, false, vpc);
+
+        // shutdown provider
+        s_logger.debug("Shutting down vpc " + vpc);
+        // TODO - shutdown all vpc resources here (ACLs, gateways, etc)
+
+        boolean success = true;
+        final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
+        final ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(ctx.getCallingUserId()), caller);
+        for (final VpcProvider element : getVpcElements()) {
+            if (providersToImplement.contains(element.getProvider())) {
+                if (element.shutdownVpc(vpc, context)) {
+                    s_logger.debug("Vpc " + vpc + " has been shutdown succesfully");
+                } else {
+                    s_logger.warn("Vpc " + vpc + " failed to shutdown");
+                    success = false;
+                }
+            }
+        }
+
+        return success;
+    }
+
+    @DB
+    @Override
+    public void validateNtwkOffForNtwkInVpc(final Long networkId, final long newNtwkOffId, final String newCidr, final String newNetworkDomain, final Vpc vpc,
+            final String gateway, final Account networkOwner, final Long aclId) {
+
+        final NetworkOffering guestNtwkOff = _entityMgr.findById(NetworkOffering.class, newNtwkOffId);
+
+        if (guestNtwkOff == null) {
+            throw new InvalidParameterValueException("Can't find network offering by id specified");
+        }
+
+        if (networkId == null) {
+            // 1) Validate attributes that has to be passed in when create new
+            // guest network
+            validateNewVpcGuestNetwork(newCidr, gateway, networkOwner, vpc, newNetworkDomain);
+        }
+
+        // 2) validate network offering attributes
+        final List<Service> svcs = _ntwkModel.listNetworkOfferingServices(guestNtwkOff.getId());
+        validateNtwkOffForVpc(guestNtwkOff, svcs);
+
+        // 3) Check services/providers against VPC providers
+        final List<NetworkOfferingServiceMapVO> networkProviders = _ntwkOffServiceDao.listByNetworkOfferingId(guestNtwkOff.getId());
+
+        for (final NetworkOfferingServiceMapVO nSvcVO : networkProviders) {
+            final String pr = nSvcVO.getProvider();
+            final String service = nSvcVO.getService();
+            if (_vpcOffServiceDao.findByServiceProviderAndOfferingId(service, pr, vpc.getVpcOfferingId()) == null) {
+                throw new InvalidParameterValueException("Service/provider combination " + service + "/" + pr + " is not supported by VPC " + vpc);
+            }
+        }
+
+        // 4) Only one network in the VPC can support public LB inside the VPC.
+        // Internal LB can be supported on multiple VPC tiers
+        if (_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.Lb) && guestNtwkOff.isPublicLb()) {
+            final List<? extends Network> networks = getVpcNetworks(vpc.getId());
+            for (final Network network : networks) {
+                if (networkId != null && network.getId() == networkId.longValue()) {
+                    // skip my own network
+                    continue;
+                } else {
+                    final NetworkOffering otherOff = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+                    // throw only if networks have different offerings with
+                    // public lb support
+                    if (_ntwkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb) && otherOff.isPublicLb() && guestNtwkOff.getId() != otherOff.getId()) {
+                        throw new InvalidParameterValueException("Public LB service is already supported " + "by network " + network + " in VPC " + vpc);
+                    }
+                }
+            }
+        }
+
+        // 5) When aclId is provided, verify that ACLProvider is supported by
+        // network offering
+        if (aclId != null && !_ntwkModel.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.NetworkACL)) {
+            throw new InvalidParameterValueException("Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
+        }
+
+    }
+
+    @Override
+    public void validateNtwkOffForVpc(final NetworkOffering guestNtwkOff, final List<Service> supportedSvcs) {
+        // 1) in current release, only vpc provider is supported by Vpc offering
+        final List<Provider> providers = _ntwkModel.getNtwkOffDistinctProviders(guestNtwkOff.getId());
+        for (final Provider provider : providers) {
+            if (!supportedProviders.contains(provider)) {
+                throw new InvalidParameterValueException("Provider of type " + provider.getName() + " is not supported for network offerings that can be used in VPC");
+            }
+        }
+
+        // 2) Only Isolated networks with Source nat service enabled can be
+        // added to vpc
+        if (!(guestNtwkOff.getGuestType() == GuestType.Isolated && supportedSvcs.contains(Service.SourceNat))) {
+
+            throw new InvalidParameterValueException("Only network offerings of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName()
+                    + " are valid for vpc ");
+        }
+
+        // 3) No redundant router support
+        /*
+         * TODO This should have never been hardcoded like this in the first
+         * place if (guestNtwkOff.getRedundantRouter()) { throw new
+         * InvalidParameterValueException
+         * ("No redunant router support when network belnogs to VPC"); }
+         */
+
+        // 4) Conserve mode should be off
+        if (guestNtwkOff.isConserveMode()) {
+            throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC");
+        }
+
+        // 5) If Netscaler is LB provider make sure it is in dedicated mode
+        if (providers.contains(Provider.Netscaler) && !guestNtwkOff.isDedicatedLB()) {
+            throw new InvalidParameterValueException("Netscaler only with Dedicated LB can belong to VPC");
+        }
+        return;
+    }
+
+    @DB
+    protected void validateNewVpcGuestNetwork(final String cidr, final String gateway, final Account networkOwner, final Vpc vpc, final String networkDomain) {
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                final Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
+                if (locked == null) {
+                    throw new CloudRuntimeException("Unable to acquire lock on " + vpc);
+                }
+
+                try {
+                    // check number of active networks in vpc
+                    if (_ntwkDao.countVpcNetworks(vpc.getId()) >= _maxNetworks) {
+                        throw new CloudRuntimeException("Number of networks per VPC can't extend " + _maxNetworks + "; increase it using global config " + Config.VpcMaxNetworks);
+                    }
+
+                    // 1) CIDR is required
+                    if (cidr == null) {
+                        throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC");
+                    }
+
+                    // 2) Network cidr should be within vpcCidr
+                    if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) {
+                        throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr");
+                    }
+
+                    // 3) Network cidr shouldn't cross the cidr of other vpc
+                    // network cidrs
+                    final List<? extends Network> ntwks = _ntwkDao.listByVpc(vpc.getId());
+                    for (final Network ntwk : ntwks) {
+                        assert cidr != null : "Why the network cidr is null when it belongs to vpc?";
+
+                        if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), cidr) || NetUtils.isNetworkAWithinNetworkB(cidr, ntwk.getCidr())) {
+                            throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + " belonging to the same vpc " + vpc);
+                        }
+                    }
+
+                    // 4) vpc and network should belong to the same owner
+                    if (vpc.getAccountId() != networkOwner.getId()) {
+                        throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + networkOwner);
+                    }
+
+                    // 5) network domain should be the same as VPC's
+                    if (!networkDomain.equalsIgnoreCase(vpc.getNetworkDomain())) {
+                        throw new InvalidParameterValueException("Network domain of the new network should match network" + " domain of vpc " + vpc);
+                    }
+
+                    // 6) gateway should never be equal to the cidr subnet
+                    if (NetUtils.getCidrSubNet(cidr).equalsIgnoreCase(gateway)) {
+                        throw new InvalidParameterValueException("Invalid gateway specified. It should never be equal to the cidr subnet value");
+                    }
+                } finally {
+                    s_logger.debug("Releasing lock for " + locked);
+                    _vpcDao.releaseFromLockTable(locked.getId());
+                }
+            }
+        });
+    }
+
+    public List<VpcProvider> getVpcElements() {
+        if (vpcElements == null) {
+            vpcElements = new ArrayList<VpcProvider>();
+            vpcElements.add((VpcProvider) _ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName()));
+            vpcElements.add((VpcProvider) _ntwkModel.getElementImplementingProvider(Provider.JuniperContrailVpcRouter.getName()));
+        }
+
+        if (vpcElements == null) {
+            throw new CloudRuntimeException("Failed to initialize vpc elements");
+        }
+
+        return vpcElements;
+    }
+
+    @Override
+    public List<? extends Vpc> getVpcsForAccount(final long accountId) {
+        final List<Vpc> vpcs = new ArrayList<Vpc>();
+        vpcs.addAll(_vpcDao.listByAccountId(accountId));
+        return vpcs;
+    }
+
+    public boolean cleanupVpcResources(final long vpcId, final Account caller, final long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
+        s_logger.debug("Cleaning up resources for vpc id=" + vpcId);
+        boolean success = true;
+
+        // 1) Remove VPN connections and VPN gateway
+        s_logger.debug("Cleaning up existed site to site VPN connections");
+        _s2sVpnMgr.cleanupVpnConnectionByVpc(vpcId);
+        s_logger.debug("Cleaning up existed site to site VPN gateways");
+        _s2sVpnMgr.cleanupVpnGatewayByVpc(vpcId);
+
+        // 2) release all ip addresses
+        final List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null);
+        s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup");
+        for (final IPAddressVO ipToRelease : ipsToRelease) {
+            if (ipToRelease.isPortable()) {
+                // portable IP address are associated with owner, until
+                // explicitly requested to be disassociated.
+                // so as part of VPC clean up just break IP association with VPC
+                ipToRelease.setVpcId(null);
+                ipToRelease.setAssociatedWithNetworkId(null);
+                _ipAddressDao.update(ipToRelease.getId(), ipToRelease);
+                s_logger.debug("Portable IP address " + ipToRelease + " is no longer associated with any VPC");
+            } else {
+                success = success && _ipAddrMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller);
+                if (!success) {
+                    s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup");
+                }
+            }
+        }
+
+        if (success) {
+            s_logger.debug("Released ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
+        } else {
+            s_logger.warn("Failed to release ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
+            // although it failed, proceed to the next cleanup step as it
+            // doesn't depend on the public ip release
+        }
+
+        // 3) Delete all static route rules
+        if (!revokeStaticRoutesForVpc(vpcId, caller)) {
+            s_logger.warn("Failed to revoke static routes for vpc " + vpcId + " as a part of cleanup vpc process");
+            return false;
+        }
+
+        // 4) Delete private gateways
+        final List<PrivateGateway> gateways = getVpcPrivateGateways(vpcId);
+        if (gateways != null) {
+            for (final PrivateGateway gateway : gateways) {
+                if (gateway != null) {
+                    s_logger.debug("Deleting private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
+                    if (!deleteVpcPrivateGateway(gateway.getId())) {
+                        success = false;
+                        s_logger.debug("Failed to delete private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
+                    } else {
+                        s_logger.debug("Deleted private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
+                    }
+                }
+            }
+        }
+
+        //5) Delete ACLs
+        final SearchBuilder<NetworkACLVO> searchBuilder = _networkAclDao.createSearchBuilder();
+
+        searchBuilder.and("vpcId", searchBuilder.entity().getVpcId(), Op.IN);
+        final SearchCriteria<NetworkACLVO> searchCriteria = searchBuilder.create();
+        searchCriteria.setParameters("vpcId", vpcId, 0);
+
+        final Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null);
+        final Pair<List<NetworkACLVO>, Integer> aclsCountPair =  _networkAclDao.searchAndCount(searchCriteria, filter);
+
+        final List<NetworkACLVO> acls = aclsCountPair.first();
+        for (final NetworkACLVO networkAcl : acls) {
+            if (networkAcl.getId() != NetworkACL.DEFAULT_ALLOW && networkAcl.getId() != NetworkACL.DEFAULT_DENY) {
+                _networkAclMgr.deleteNetworkACL(networkAcl);
+            }
+        }
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc")
+    public boolean restartVpc(final long vpcId, final boolean cleanUp, final boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
+    InsufficientCapacityException {
+
+        final Account callerAccount = CallContext.current().getCallingAccount();
+        final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+        final ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
+
+        // Verify input parameters
+        Vpc vpc = getActiveVpc(vpcId);
+        if (vpc == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
+            ex.addProxyObject(String.valueOf(vpcId), "VPC");
+            throw ex;
+        }
+
+        _accountMgr.checkAccess(callerAccount, null, false, vpc);
+
+        s_logger.debug("Restarting VPC " + vpc);
+        boolean restartRequired = false;
+        try {
+            boolean forceCleanup = cleanUp;
+            if (!vpc.isRedundant() && makeRedundant) {
+                final VpcOfferingVO redundantOffering = _vpcOffDao.findByUniqueName(VpcOffering.redundantVPCOfferingName);
+
+                final VpcVO entity = _vpcDao.findById(vpcId);
+                entity.setRedundant(true);
+                entity.setVpcOfferingId(redundantOffering.getId());
+
+                // Change the VPC in order to get it updated after the end of
+                // the restart procedure.
+                if (_vpcDao.update(vpc.getId(), entity)) {
+                    vpc = entity;
+                }
+
+                // If the offering and redundant column are changing, force the
+                // clean up.
+                forceCleanup = true;
+            }
+
+            if (forceCleanup) {
+                if (!rollingRestartVpc(vpc, context)) {
+                    s_logger.warn("Failed to execute a rolling restart as a part of VPC " + vpc + " restart process");
+                    restartRequired = true;
+                    return false;
+                }
+                return true;
+            }
+
+            s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process without cleanup");
+            if (!startVpc(vpcId, false)) {
+                s_logger.warn("Failed to start vpc as a part of VPC " + vpc + " restart process");
+                restartRequired = true;
+                return false;
+            }
+            s_logger.debug("VPC " + vpc + " was restarted successfully");
+            return true;
+        } finally {
+            s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired);
+            final VpcVO vo = _vpcDao.findById(vpcId);
+            vo.setRestartRequired(restartRequired);
+            _vpcDao.update(vpc.getId(), vo);
+        }
+    }
+
+    @Override
+    public List<PrivateGateway> getVpcPrivateGateways(final long vpcId) {
+        final List<VpcGatewayVO> gateways = _vpcGatewayDao.listByVpcIdAndType(vpcId, VpcGateway.Type.Private);
+
+        if (gateways != null) {
+            final List<PrivateGateway> pvtGateway = new ArrayList<PrivateGateway>();
+            for (final VpcGatewayVO gateway : gateways) {
+                pvtGateway.add(getPrivateGatewayProfile(gateway));
+            }
+            return pvtGateway;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public PrivateGateway getVpcPrivateGateway(final long id) {
+        final VpcGateway gateway = _vpcGatewayDao.findById(id);
+
+        if (gateway == null || gateway.getType() != VpcGateway.Type.Private) {
+            return null;
+        }
+        return getPrivateGatewayProfile(gateway);
+    }
+
+    protected PrivateGateway getPrivateGatewayProfile(final VpcGateway gateway) {
+        final Network network = _ntwkModel.getNetwork(gateway.getNetworkId());
+        return new PrivateGatewayProfile(gateway, network.getPhysicalNetworkId());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating VPC private gateway", create = true)
+    public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway,
+            final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId) throws ResourceAllocationException,
+            ConcurrentOperationException, InsufficientCapacityException {
+
+        // Validate parameters
+        final Vpc vpc = getActiveVpc(vpcId);
+        if (vpc == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
+            ex.addProxyObject(String.valueOf(vpcId), "VPC");
+            throw ex;
+        }
+
+        PhysicalNetwork physNet = null;
+        // Validate physical network
+        if (physicalNetworkId == null) {
+            final List<? extends PhysicalNetwork> pNtwks = _ntwkModel.getPhysicalNtwksSupportingTrafficType(vpc.getZoneId(), TrafficType.Guest);
+            if (pNtwks.isEmpty() || pNtwks.size() != 1) {
+                throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id");
+            }
+            physNet = pNtwks.get(0);
+            physicalNetworkId = physNet.getId();
+        }
+
+        if (physNet == null) {
+            physNet = _entityMgr.findById(PhysicalNetwork.class, physicalNetworkId);
+        }
+        final Long dcId = physNet.getDataCenterId();
+
+        final Long physicalNetworkIdFinal = physicalNetworkId;
+        final PhysicalNetwork physNetFinal = physNet;
+        VpcGatewayVO gatewayVO = null;
+        try {
+            gatewayVO = Transaction.execute(new TransactionCallbackWithException<VpcGatewayVO, Exception>() {
+                @Override
+                public VpcGatewayVO doInTransaction(final TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException,
+                InsufficientCapacityException {
+                    s_logger.debug("Creating Private gateway for VPC " + vpc);
+                    // 1) create private network unless it is existing and
+                    // lswitch'd
+                    Network privateNtwk = null;
+                    if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
+                        final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
+                        privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, gatewayOwnerId, dcId, networkOfferingId);
+                        // if the dcid is different we get no network so next we
+                        // try to create it
+                    }
+                    if (privateNtwk == null) {
+                        s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
+                        final String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
+                        privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, broadcastUri, ipAddress, null, gateway, netmask,
+                                gatewayOwnerId, vpcId, isSourceNat, networkOfferingId);
+                    } else { // create the nic/ip as createPrivateNetwork
+                        // doesn''t do that work for us now
+                        s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
+                        final DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
+
+                        // add entry to private_ip_address table
+                        PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
+                        if (privateIp != null) {
+                            throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + " in zone "
+                                    + _entityMgr.findById(DataCenter.class, dcId).getName());
+                        }
+
+                        final Long mac = dc.getMacAddress();
+                        final Long nextMac = mac + 1;
+                        dc.setMacAddress(nextMac);
+
+                        s_logger.info("creating private ip address for vpc (" + ipAddress + ", " + privateNtwk.getId() + ", " + nextMac + ", " + vpcId + ", " + isSourceNat + ")");
+                        privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, isSourceNat);
+                        _privateIpDao.persist(privateIp);
+
+                        _dcDao.update(dc.getId(), dc);
+                    }
+
+                    long networkAclId = NetworkACL.DEFAULT_DENY;
+                    if (aclId != null) {
+                        final NetworkACLVO aclVO = _networkAclDao.findById(aclId);
+                        if (aclVO == null) {
+                            throw new InvalidParameterValueException("Invalid network acl id passed ");
+                        }
+                        if (aclVO.getVpcId() != vpcId && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
+                            throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
+                        }
+
+                        networkAclId = aclId;
+                    }
+
+                    { // experimental block, this is a hack
+                        // set vpc id in network to null
+                        // might be needed for all types of broadcast domains
+                        // the ugly hack is that vpc gateway nets are created as
+                        // guest network
+                        // while they are not.
+                        // A more permanent solution would be to define a type of
+                        // 'gatewaynetwork'
+                        // so that handling code is not mixed between the two
+                        final NetworkVO gatewaynet = _ntwkDao.findById(privateNtwk.getId());
+                        gatewaynet.setVpcId(null);
+                        _ntwkDao.persist(gatewaynet);
+                    }
+
+                    // 2) create gateway entry
+                    final VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), privateNtwk.getId(), broadcastUri,
+                            gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
+                    _vpcGatewayDao.persist(gatewayVO);
+
+                    s_logger.debug("Created vpc gateway entry " + gatewayVO);
+
+                    return gatewayVO;
+                }
+            });
+        } catch (final Exception e) {
+            ExceptionUtil.rethrowRuntime(e);
+            ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
+            ExceptionUtil.rethrow(e, ResourceAllocationException.class);
+            throw new IllegalStateException(e);
+        }
+
+        CallContext.current().setEventDetails("Private Gateway Id: " + gatewayVO.getId());
+        return getVpcPrivateGateway(gatewayVO.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "Applying VPC private gateway", async = true)
+    public PrivateGateway applyVpcPrivateGateway(final long gatewayId, final boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException {
+        final VpcGatewayVO vo = _vpcGatewayDao.findById(gatewayId);
+
+        boolean success = true;
+        try {
+            final List<Provider> providersToImplement = getVpcProviders(vo.getVpcId());
+
+            final PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
+            for (final VpcProvider provider : getVpcElements()) {
+                if (providersToImplement.contains(provider.getProvider())) {
+                    if (!provider.createPrivateGateway(gateway)) {
+                        success = false;
+                    }
+                }
+            }
+            if (success) {
+                s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
+                if (vo.getState() != VpcGateway.State.Ready) {
+                    vo.setState(VpcGateway.State.Ready);
+                    _vpcGatewayDao.update(vo.getId(), vo);
+                    s_logger.debug("Marke gateway " + gateway + " with state " + VpcGateway.State.Ready);
+                }
+                CallContext.current().setEventDetails("Private Gateway Id: " + gatewayId);
+                return getVpcPrivateGateway(gatewayId);
+            } else {
+                s_logger.warn("Private gateway " + gateway + " failed to apply on the backend");
+                return null;
+            }
+        } finally {
+            // do cleanup
+            if (!success) {
+                if (destroyOnFailure) {
+                    s_logger.debug("Destroying private gateway " + vo + " that failed to start");
+                    // calling deleting from db because on createprivategateway
+                    // fail, destroyPrivateGateway is already called
+                    if (deletePrivateGatewayFromTheDB(getVpcPrivateGateway(gatewayId))) {
+                        s_logger.warn("Successfully destroyed vpc " + vo + " that failed to start");
+                    } else {
+                        s_logger.warn("Failed to destroy vpc " + vo + " that failed to start");
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway")
+    @DB
+    public boolean deleteVpcPrivateGateway(final long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException {
+        final VpcGatewayVO gatewayToBeDeleted = _vpcGatewayDao.findById(gatewayId);
+        if (gatewayToBeDeleted == null) {
+            s_logger.debug("VPC gateway is already deleted for id=" + gatewayId);
+            return true;
+        }
+
+        final VpcGatewayVO gatewayVO = _vpcGatewayDao.acquireInLockTable(gatewayId);
+        if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) {
+            throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId);
+        }
+
+        try {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    // don't allow to remove gateway when there are static
+                    // routes associated with it
+                    final long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
+                    if (routeCount > 0) {
+                        throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount
+                                + " static routes applied. Remove the routes first");
+                    }
+
+                    gatewayVO.setState(VpcGateway.State.Deleting);
+                    _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
+                    s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Deleting);
+                }
+            });
+
+            // 1) delete the gateway on the backend
+            final List<Provider> providersToImplement = getVpcProviders(gatewayVO.getVpcId());
+            final PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
+            for (final VpcProvider provider : getVpcElements()) {
+                if (providersToImplement.contains(provider.getProvider())) {
+                    if (provider.deletePrivateGateway(gateway)) {
+                        s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
+                    } else {
+                        s_logger.warn("Private gateway " + gateway + " failed to apply on the backend");
+                        gatewayVO.setState(VpcGateway.State.Ready);
+                        _vpcGatewayDao.update(gatewayVO.getId(), gatewayVO);
+                        s_logger.debug("Marked gateway " + gatewayVO + " with state " + VpcGateway.State.Ready);
+
+                        return false;
+                    }
+                }
+            }
+
+            // 2) Delete private gateway from the DB
+            return deletePrivateGatewayFromTheDB(gateway);
+
+        } finally {
+            if (gatewayVO != null) {
+                _vpcGatewayDao.releaseFromLockTable(gatewayId);
+            }
+        }
+    }
+
+    @DB
+    protected boolean deletePrivateGatewayFromTheDB(final PrivateGateway gateway) {
+        // check if there are ips allocted in the network
+        final long networkId = gateway.getNetworkId();
+
+        vpcTxCallable.setGateway(gateway);
+
+        final ExecutorService txExecutor = Executors.newSingleThreadExecutor();
+        final Future<Boolean> futureResult = txExecutor.submit(vpcTxCallable);
+
+        boolean deleteNetworkFinal;
+        try {
+            deleteNetworkFinal = futureResult.get();
+            if (deleteNetworkFinal) {
+                final User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+                final Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
+                final ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
+                _ntwkMgr.destroyNetwork(networkId, context, false);
+                s_logger.debug("Deleted private network id=" + networkId);
+            }
+        } catch (final InterruptedException e) {
+            s_logger.error("deletePrivateGatewayFromTheDB failed to delete network id " + networkId + "due to => ", e);
+        } catch (final ExecutionException e) {
+            s_logger.error("deletePrivateGatewayFromTheDB failed to delete network id " + networkId + "due to => ", e);
+        }
+
+        return true;
+    }
+
+    @Override
+    public Pair<List<PrivateGateway>, Integer> listPrivateGateway(final ListPrivateGatewaysCmd cmd) {
+        final String ipAddress = cmd.getIpAddress();
+        final String vlan = cmd.getVlan();
+        final Long vpcId = cmd.getVpcId();
+        final Long id = cmd.getId();
+        Boolean isRecursive = cmd.isRecursive();
+        final Boolean listAll = cmd.listAll();
+        Long domainId = cmd.getDomainId();
+        final String accountName = cmd.getAccountName();
+        final Account caller = CallContext.current().getCallingAccount();
+        final List<Long> permittedAccounts = new ArrayList<Long>();
+        final String state = cmd.getState();
+        final Long projectId = cmd.getProjectId();
+
+        final Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
+                null);
+        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        domainId = domainIdRecursiveListProject.first();
+        isRecursive = domainIdRecursiveListProject.second();
+        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        final SearchBuilder<VpcGatewayVO> sb = _vpcGatewayDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        if (vlan != null) {
+            final SearchBuilder<NetworkVO> ntwkSearch = _ntwkDao.createSearchBuilder();
+            ntwkSearch.and("vlan", ntwkSearch.entity().getBroadcastUri(), SearchCriteria.Op.EQ);
+            sb.join("networkSearch", ntwkSearch, sb.entity().getNetworkId(), ntwkSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchCriteria<VpcGatewayVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        if (id != null) {
+            sc.addAnd("id", Op.EQ, id);
+        }
+
+        if (ipAddress != null) {
+            sc.addAnd("ip4Address", Op.EQ, ipAddress);
+        }
+
+        if (state != null) {
+            sc.addAnd("state", Op.EQ, state);
+        }
+
+        if (vpcId != null) {
+            sc.addAnd("vpcId", Op.EQ, vpcId);
+        }
+
+        if (vlan != null) {
+            sc.setJoinParameters("networkSearch", "vlan", BroadcastDomainType.Vlan.toUri(vlan));
+        }
+
+        final Pair<List<VpcGatewayVO>, Integer> vos = _vpcGatewayDao.searchAndCount(sc, searchFilter);
+        final List<PrivateGateway> privateGtws = new ArrayList<PrivateGateway>(vos.first().size());
+        for (final VpcGateway vo : vos.first()) {
+            privateGtws.add(getPrivateGatewayProfile(vo));
+        }
+
+        return new Pair<List<PrivateGateway>, Integer>(privateGtws, vos.second());
+    }
+
+    @Override
+    public StaticRoute getStaticRoute(final long routeId) {
+        return _staticRouteDao.findById(routeId);
+    }
+
+    @Override
+    public boolean applyStaticRoutesForVpc(final long vpcId) throws ResourceUnavailableException {
+        final Account caller = CallContext.current().getCallingAccount();
+        final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(vpcId);
+        return applyStaticRoutes(routes, caller, true);
+    }
+
+    protected boolean applyStaticRoutes(final List<? extends StaticRoute> routes, final Account caller, final boolean updateRoutesInDB) throws ResourceUnavailableException {
+        final boolean success = true;
+        final List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
+        final Map<Long, VpcGateway> gatewayMap = new HashMap<Long, VpcGateway>();
+        for (final StaticRoute route : routes) {
+            VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId());
+            if (gateway == null) {
+                gateway = _vpcGatewayDao.findById(route.getVpcGatewayId());
+                gatewayMap.put(gateway.getId(), gateway);
+            }
+            staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
+        }
+        if (!applyStaticRoutes(staticRouteProfiles)) {
+            s_logger.warn("Routes are not completely applied");
+            return false;
+        } else {
+            if (updateRoutesInDB) {
+                for (final StaticRoute route : routes) {
+                    if (route.getState() == StaticRoute.State.Revoke) {
+                        _staticRouteDao.remove(route.getId());
+                        s_logger.debug("Removed route " + route + " from the DB");
+                    } else if (route.getState() == StaticRoute.State.Add) {
+                        final StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId());
+                        ruleVO.setState(StaticRoute.State.Active);
+                        _staticRouteDao.update(ruleVO.getId(), ruleVO);
+                        s_logger.debug("Marked route " + route + " with state " + StaticRoute.State.Active);
+                    }
+                }
+            }
+        }
+
+        return success;
+    }
+
+    protected boolean applyStaticRoutes(final List<StaticRouteProfile> routes) throws ResourceUnavailableException {
+        if (routes.isEmpty()) {
+            s_logger.debug("No static routes to apply");
+            return true;
+        }
+        final Vpc vpc = _vpcDao.findById(routes.get(0).getVpcId());
+
+        s_logger.debug("Applying static routes for vpc " + vpc);
+        final String staticNatProvider = _vpcSrvcDao.getProviderForServiceInVpc(vpc.getId(), Service.StaticNat);
+
+        for (final VpcProvider provider : getVpcElements()) {
+            if (!(provider instanceof StaticNatServiceProvider && provider.getName().equalsIgnoreCase(staticNatProvider))) {
+                continue;
+            }
+
+            if (provider.applyStaticRoutes(vpc, routes)) {
+                s_logger.debug("Applied static routes for vpc " + vpc);
+            } else {
+                s_logger.warn("Failed to apply static routes for vpc " + vpc);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_DELETE, eventDescription = "deleting static route")
+    public boolean revokeStaticRoute(final long routeId) throws ResourceUnavailableException {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        final StaticRouteVO route = _staticRouteDao.findById(routeId);
+        if (route == null) {
+            throw new InvalidParameterValueException("Unable to find static route by id");
+        }
+
+        _accountMgr.checkAccess(caller, null, false, route);
+
+        markStaticRouteForRevoke(route, caller);
+
+        return applyStaticRoutesForVpc(route.getVpcId());
+    }
+
+    @DB
+    protected boolean revokeStaticRoutesForVpc(final long vpcId, final Account caller) throws ResourceUnavailableException {
+        // get all static routes for the vpc
+        final List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
+        s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId);
+        if (!routes.isEmpty()) {
+            // mark all of them as revoke
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    for (final StaticRouteVO route : routes) {
+                        markStaticRouteForRevoke(route, caller);
+                    }
+                }
+            });
+            return applyStaticRoutesForVpc(vpcId);
+        }
+
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create = true)
+    public StaticRoute createStaticRoute(final long gatewayId, final String cidr) throws NetworkRuleConflictException {
+        final Account caller = CallContext.current().getCallingAccount();
+
+        // parameters validation
+        final VpcGateway gateway = _vpcGatewayDao.findById(gatewayId);
+        if (gateway == null) {
+            throw new InvalidParameterValueException("Invalid gateway id is given");
+        }
+
+        if (gateway.getState() != VpcGateway.State.Ready) {
+            throw new InvalidParameterValueException("Gateway is not in the " + VpcGateway.State.Ready + " state: " + gateway.getState());
+        }
+
+        final Vpc vpc = getActiveVpc(gateway.getVpcId());
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
+        }
+        _accountMgr.checkAccess(caller, null, false, vpc);
+
+        if (!NetUtils.isValidIp4Cidr(cidr)) {
+            throw new InvalidParameterValueException("Invalid format for cidr " + cidr);
+        }
+
+        // validate the cidr
+        // 1) CIDR should be outside of VPC cidr for guest networks
+        if (NetUtils.isNetworksOverlap(vpc.getCidr(), cidr)) {
+            throw new InvalidParameterValueException("CIDR should be outside of VPC cidr " + vpc.getCidr());
+        }
+
+        // 2) CIDR should be outside of link-local cidr
+        if (NetUtils.isNetworksOverlap(vpc.getCidr(), NetUtils.getLinkLocalCIDR())) {
+            throw new InvalidParameterValueException("CIDR should be outside of link local cidr " + NetUtils.getLinkLocalCIDR());
+        }
+
+        // 3) Verify against blacklisted routes
+        if (isCidrBlacklisted(cidr, vpc.getZoneId())) {
+            throw new InvalidParameterValueException("The static gateway cidr overlaps with one of the blacklisted routes of the zone the VPC belongs to");
+        }
+
+        return Transaction.execute(new TransactionCallbackWithException<StaticRouteVO, NetworkRuleConflictException>() {
+            @Override
+            public StaticRouteVO doInTransaction(final TransactionStatus status) throws NetworkRuleConflictException {
+                StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
+                s_logger.debug("Adding static route " + newRoute);
+                newRoute = _staticRouteDao.persist(newRoute);
+
+                detectRoutesConflict(newRoute);
+
+                if (!_staticRouteDao.setStateToAdd(newRoute)) {
+                    throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
+                }
+                CallContext.current().setEventDetails("Static route Id: " + newRoute.getId());
+
+                return newRoute;
+            }
+        });
+    }
+
+    protected boolean isCidrBlacklisted(final String cidr, final long zoneId) {
+        final String routesStr = NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
+        if (routesStr != null && !routesStr.isEmpty()) {
+            final String[] cidrBlackList = routesStr.split(",");
+
+            if (cidrBlackList != null && cidrBlackList.length > 0) {
+                for (final String blackListedRoute : cidrBlackList) {
+                    if (NetUtils.isNetworksOverlap(blackListedRoute, cidr)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(final ListStaticRoutesCmd cmd) {
+        final Long id = cmd.getId();
+        final Long gatewayId = cmd.getGatewayId();
+        final Long vpcId = cmd.getVpcId();
+        Long domainId = cmd.getDomainId();
+        Boolean isRecursive = cmd.isRecursive();
+        final Boolean listAll = cmd.listAll();
+        final String accountName = cmd.getAccountName();
+        final Account caller = CallContext.current().getCallingAccount();
+        final List<Long> permittedAccounts = new ArrayList<Long>();
+        final Map<String, String> tags = cmd.getTags();
+        final Long projectId = cmd.getProjectId();
+
+        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
+                null);
+        _accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        domainId = domainIdRecursiveListProject.first();
+        isRecursive = domainIdRecursiveListProject.second();
+        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        final Filter searchFilter = new Filter(StaticRouteVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        final SearchBuilder<StaticRouteVO> sb = _staticRouteDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
+        sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchCriteria<StaticRouteVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        if (id != null) {
+            sc.addAnd("id", Op.EQ, id);
+        }
+
+        if (vpcId != null) {
+            sc.addAnd("vpcId", Op.EQ, vpcId);
+        }
+
+        if (gatewayId != null) {
+            sc.addAnd("vpcGatewayId", Op.EQ, gatewayId);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.StaticRoute.toString());
+            for (final String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        final Pair<List<StaticRouteVO>, Integer> result = _staticRouteDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends StaticRoute>, Integer>(result.first(), result.second());
+    }
+
+    protected void detectRoutesConflict(final StaticRoute newRoute) throws NetworkRuleConflictException {
+        // Multiple private gateways can exist within Vpc. Check for conflicts
+        // for all static routes in Vpc
+        // and not just the gateway
+        final List<? extends StaticRoute> routes = _staticRouteDao.listByVpcIdAndNotRevoked(newRoute.getVpcId());
+        assert routes.size() >= 1 : "For static routes, we now always first persist the route and then check for "
+                + "network conflicts so we should at least have one rule at this point.";
+
+        for (final StaticRoute route : routes) {
+            if (route.getId() == newRoute.getId()) {
+                continue; // Skips my own route.
+            }
+
+            if (NetUtils.isNetworksOverlap(route.getCidr(), newRoute.getCidr())) {
+                throw new NetworkRuleConflictException("New static route cidr conflicts with existing route " + route);
+            }
+        }
+    }
+
+    protected void markStaticRouteForRevoke(final StaticRouteVO route, final Account caller) {
+        s_logger.debug("Revoking static route " + route);
+        if (caller != null) {
+            _accountMgr.checkAccess(caller, null, false, route);
+        }
+
+        if (route.getState() == StaticRoute.State.Staged) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found a static route that is still in stage state so just removing it: " + route);
+            }
+            _staticRouteDao.remove(route.getId());
+        } else if (route.getState() == StaticRoute.State.Add || route.getState() == StaticRoute.State.Active) {
+            route.setState(StaticRoute.State.Revoke);
+            _staticRouteDao.update(route.getId(), route);
+            s_logger.debug("Marked static route " + route + " with state " + StaticRoute.State.Revoke);
+        }
+    }
+
+    protected class VpcCleanupTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                final GlobalLock lock = GlobalLock.getInternLock("VpcCleanup");
+                if (lock == null) {
+                    s_logger.debug("Couldn't get the global lock");
+                    return;
+                }
+
+                if (!lock.lock(30)) {
+                    s_logger.debug("Couldn't lock the db");
+                    return;
+                }
+
+                try {
+                    // Cleanup inactive VPCs
+                    final List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
+                    if (inactiveVpcs != null) {
+                        s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
+                        for (final VpcVO vpc : inactiveVpcs) {
+                            s_logger.debug("Cleaning up " + vpc);
+                            destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
+                        }
+                    }
+                } catch (final Exception e) {
+                    s_logger.error("Exception ", e);
+                } finally {
+                    lock.unlock();
+                }
+            } catch (final Exception e) {
+                s_logger.error("Exception ", e);
+            }
+        }
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
+    public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException,
+    ConcurrentOperationException {
+        final Account caller = CallContext.current().getCallingAccount();
+        Account owner = null;
+
+        final IpAddress ipToAssoc = _ntwkModel.getIp(ipId);
+        if (ipToAssoc != null) {
+            _accountMgr.checkAccess(caller, null, true, ipToAssoc);
+            owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId());
+        } else {
+            s_logger.debug("Unable to find ip address by id: " + ipId);
+            return null;
+        }
+
+        final Vpc vpc = _vpcDao.findById(vpcId);
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Invalid VPC id provided");
+        }
+
+        // check permissions
+        _accountMgr.checkAccess(caller, null, true, owner, vpc);
+
+        s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc);
+
+        final boolean isSourceNatFinal = isSrcNatIpRequired(vpc.getVpcOfferingId()) && getExistingSourceNatInVpc(owner.getId(), vpcId) == null;
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                final IPAddressVO ip = _ipAddressDao.findById(ipId);
+                // update ip address with networkId
+                ip.setVpcId(vpcId);
+                ip.setSourceNat(isSourceNatFinal);
+
+                _ipAddressDao.update(ipId, ip);
+
+                // mark ip as allocated
+                _ipAddrMgr.markPublicIpAsAllocated(ip);
+            }
+        });
+
+        s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc);
+
+        return _ipAddressDao.findById(ipId);
+    }
+
+    @Override
+    public void unassignIPFromVpcNetwork(final long ipId, final long networkId) {
+        final IPAddressVO ip = _ipAddressDao.findById(ipId);
+        if (isIpAllocatedToVpc(ip)) {
+            return;
+        }
+
+        if (ip == null || ip.getVpcId() == null) {
+            return;
+        }
+
+        s_logger.debug("Releasing VPC ip address " + ip + " from vpc network id=" + networkId);
+
+        final long vpcId = ip.getVpcId();
+        boolean success = false;
+        try {
+            // unassign ip from the VPC router
+            success = _ipAddrMgr.applyIpAssociations(_ntwkModel.getNetwork(networkId), true);
+        } catch (final ResourceUnavailableException ex) {
+            throw new CloudRuntimeException("Failed to apply ip associations for network id=" + networkId + " as a part of unassigning ip " + ipId + " from vpc", ex);
+        }
+
+        if (success) {
+            ip.setAssociatedWithNetworkId(null);
+            _ipAddressDao.update(ipId, ip);
+            s_logger.debug("IP address " + ip + " is no longer associated with the network inside vpc id=" + vpcId);
+        } else {
+            throw new CloudRuntimeException("Failed to apply ip associations for network id=" + networkId + " as a part of unassigning ip " + ipId + " from vpc");
+        }
+        s_logger.debug("Successfully released VPC ip address " + ip + " back to VPC pool ");
+    }
+
+    @Override
+    public boolean isIpAllocatedToVpc(final IpAddress ip) {
+        return ip != null && ip.getVpcId() != null && (ip.isOneToOneNat() || !_firewallDao.listByIp(ip.getId()).isEmpty());
+    }
+
+    @DB
+    @Override
+    public Network createVpcGuestNetwork(final long ntwkOffId, final String name, final String displayText, final String gateway, final String cidr, final String vlanId,
+            String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, final Boolean subdomainAccess,
+            final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
+            ResourceAllocationException {
+
+        final Vpc vpc = getActiveVpc(vpcId);
+
+        if (vpc == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC ");
+            ex.addProxyObject(String.valueOf(vpcId), "VPC");
+            throw ex;
+        }
+        _accountMgr.checkAccess(caller, null, false, vpc);
+
+        if (networkDomain == null) {
+            networkDomain = vpc.getNetworkDomain();
+        }
+
+        if (!vpc.isRegionLevelVpc() && vpc.getZoneId() != zoneId) {
+            throw new InvalidParameterValueException("New network doesn't belong to vpc zone");
+        }
+
+        // 1) Validate if network can be created for VPC
+        validateNtwkOffForNtwkInVpc(null, ntwkOffId, cidr, networkDomain, vpc, gateway, owner, aclId);
+
+        // 2) Create network
+        final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
+                                                                 subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null, externalId);
+
+        if (guestNetwork != null) {
+            guestNetwork.setNetworkACLId(aclId);
+            _ntwkDao.update(guestNetwork.getId(), (NetworkVO) guestNetwork);
+        }
+        return guestNetwork;
+    }
+
+    protected IPAddressVO getExistingSourceNatInVpc(final long ownerId, final long vpcId) {
+
+        final List<IPAddressVO> addrs = listPublicIpsAssignedToVpc(ownerId, true, vpcId);
+
+        IPAddressVO sourceNatIp = null;
+        if (addrs.isEmpty()) {
+            return null;
+        } else {
+            // Account already has ip addresses
+            for (final IPAddressVO addr : addrs) {
+                if (addr.isSourceNat()) {
+                    sourceNatIp = addr;
+                    return sourceNatIp;
+                }
+            }
+
+            assert sourceNatIp != null : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; vpcId=" + vpcId;
+        }
+
+        return sourceNatIp;
+    }
+
+    protected List<IPAddressVO> listPublicIpsAssignedToVpc(final long accountId, final Boolean sourceNat, final long vpcId) {
+        final SearchCriteria<IPAddressVO> sc = IpAddressSearch.create();
+        sc.setParameters("accountId", accountId);
+        sc.setParameters("vpcId", vpcId);
+
+        if (sourceNat != null) {
+            sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat);
+        }
+        sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork);
+
+        return _ipAddressDao.search(sc, null);
+    }
+
+    @Override
+    public PublicIp assignSourceNatIpAddressToVpc(final Account owner, final Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException {
+        final long dcId = vpc.getZoneId();
+
+        final IPAddressVO sourceNatIp = getExistingSourceNatInVpc(owner.getId(), vpc.getId());
+
+        PublicIp ipToReturn = null;
+
+        if (sourceNatIp != null) {
+            ipToReturn = PublicIp.createFromAddrAndVlan(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()));
+        } else {
+            ipToReturn = _ipAddrMgr.assignDedicateIpAddress(owner, null, vpc.getId(), dcId, true);
+        }
+
+        return ipToReturn;
+    }
+
+    @Override
+    public List<HypervisorType> getSupportedVpcHypervisors() {
+        return Collections.unmodifiableList(hTypes);
+    }
+
+    private List<Provider> getVpcProviders(final long vpcId) {
+        final List<String> providerNames = _vpcSrvcDao.getDistinctProviders(vpcId);
+        final Map<String, Provider> providers = new HashMap<String, Provider>();
+        for (final String providerName : providerNames) {
+            if (!providers.containsKey(providerName)) {
+                providers.put(providerName, Network.Provider.getProvider(providerName));
+            }
+        }
+
+        return new ArrayList<Provider>(providers.values());
+    }
+
+    @Inject
+    public void setVpcElements(final List<VpcProvider> vpcElements) {
+        this.vpcElements = vpcElements;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "Applying static route", async = true)
+    public boolean applyStaticRoute(final long routeId) throws ResourceUnavailableException {
+        final StaticRoute route = _staticRouteDao.findById(routeId);
+        return applyStaticRoutesForVpc(route.getVpcId());
+    }
+
+    @Override
+    public boolean isSrcNatIpRequired(long vpcOfferingId) {
+        final Map<Network.Service, Set<Network.Provider>> vpcOffSvcProvidersMap = getVpcOffSvcProvidersMap(vpcOfferingId);
+        return vpcOffSvcProvidersMap.get(Network.Service.SourceNat).contains(Network.Provider.VPCVirtualRouter);
+    }
+
+    /**
+     * rollingRestartVpc performs restart of routers of a VPC by first
+     * deploying a new VR and then destroying old VRs in rolling fashion. For
+     * non-redundant VPC, it will re-program the new router as final step
+     * otherwise deploys a backup router for the VPC.
+     * @param vpc vpc to be restarted
+     * @param context reservation context
+     * @return returns true when the rolling restart succeeds
+     * @throws ResourceUnavailableException
+     * @throws ConcurrentOperationException
+     * @throws InsufficientCapacityException
+     */
+    private boolean rollingRestartVpc(final Vpc vpc, final ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
+        if (!NetworkOrchestrationService.RollingRestartEnabled.value()) {
+            if (shutdownVpc(vpc.getId())) {
+                return startVpc(vpc.getId(), false);
+            }
+            s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process");
+            return false;
+        }
+        s_logger.debug("Performing rolling restart of routers of VPC " + vpc);
+        _ntwkMgr.destroyExpendableRouters(_routerDao.listByVpcId(vpc.getId()), context);
+
+        final DeployDestination dest = new DeployDestination(_dcDao.findById(vpc.getZoneId()), null, null, null);
+        final List<DomainRouterVO> oldRouters = _routerDao.listByVpcId(vpc.getId());
+
+        // Create a new router
+        if (oldRouters.size() > 0) {
+            vpc.setRollingRestart(true);
+        }
+        startVpc(vpc, dest, context);
+        if (oldRouters.size() > 0) {
+            vpc.setRollingRestart(false);
+        }
+
+        // For redundant vpc wait for 3*advert_int+skew_seconds for VRRP to kick in
+        if (vpc.isRedundant() || (oldRouters.size() == 1 && oldRouters.get(0).getIsRedundantRouter())) {
+            try {
+                Thread.sleep(NetworkOrchestrationService.RVRHandoverTime);
+            } catch (final InterruptedException ignored) {
+            }
+        }
+
+        // Destroy old routers
+        for (final DomainRouterVO oldRouter : oldRouters) {
+            _routerService.stopRouter(oldRouter.getId(), true);
+            _routerService.destroyRouter(oldRouter.getId(), context.getAccount(), context.getCaller().getId());
+        }
+
+        // Re-program VPC VR or add a new backup router for redundant VPC
+        if (!startVpc(vpc, dest, context)) {
+            s_logger.debug("Failed to re-program VPC router or deploy a new backup router for VPC" + vpc);
+            return false;
+        }
+
+        return _ntwkMgr.areRoutersRunning(_routerDao.listByVpcId(vpc.getId()));
+    }
+
+}
diff --git a/server/src/com/cloud/network/vpc/VpcPrivateGatewayTransactionCallable.java b/server/src/main/java/com/cloud/network/vpc/VpcPrivateGatewayTransactionCallable.java
similarity index 100%
rename from server/src/com/cloud/network/vpc/VpcPrivateGatewayTransactionCallable.java
rename to server/src/main/java/com/cloud/network/vpc/VpcPrivateGatewayTransactionCallable.java
diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
rename to server/src/main/java/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java
similarity index 100%
rename from server/src/com/cloud/network/vpn/Site2SiteVpnManager.java
rename to server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManager.java
diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
rename to server/src/main/java/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
diff --git a/server/src/com/cloud/projects/ProjectManager.java b/server/src/main/java/com/cloud/projects/ProjectManager.java
similarity index 100%
rename from server/src/com/cloud/projects/ProjectManager.java
rename to server/src/main/java/com/cloud/projects/ProjectManager.java
diff --git a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
new file mode 100644
index 0000000..48d6518
--- /dev/null
+++ b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
@@ -0,0 +1,1059 @@
+// 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.projects;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.mail.Authenticator;
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.URLName;
+import javax.mail.internet.InternetAddress;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.sun.mail.smtp.SMTPMessage;
+import com.sun.mail.smtp.SMTPSSLTransport;
+import com.sun.mail.smtp.SMTPTransport;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.ProjectAccountJoinDao;
+import com.cloud.api.query.dao.ProjectInvitationJoinDao;
+import com.cloud.api.query.dao.ProjectJoinDao;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.projects.Project.State;
+import com.cloud.projects.ProjectAccount.Role;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.projects.dao.ProjectInvitationDao;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Component
+public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
+    public static final Logger s_logger = Logger.getLogger(ProjectManagerImpl.class);
+    private EmailInvite _emailInvite;
+
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private ProjectDao _projectDao;
+    @Inject
+    private ProjectJoinDao _projectJoinDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    DomainManager _domainMgr;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    private ProjectAccountDao _projectAccountDao;
+    @Inject
+    private ProjectAccountJoinDao _projectAccountJoinDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ProjectInvitationDao _projectInvitationDao;
+    @Inject
+    private ProjectInvitationJoinDao _projectInvitationJoinDao;
+    @Inject
+    protected ResourceTagDao _resourceTagDao;
+
+    protected boolean _invitationRequired = false;
+    protected long _invitationTimeOut = 86400000;
+    protected boolean _allowUserToCreateProject = true;
+    protected ScheduledExecutorService _executor;
+    protected int _projectCleanupExpInvInterval = 60; //Interval defining how often project invitation cleanup thread is running
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+
+        Map<String, String> configs = _configDao.getConfiguration(params);
+        _invitationRequired = Boolean.valueOf(configs.get(Config.ProjectInviteRequired.key()));
+
+        String value = configs.get(Config.ProjectInvitationExpirationTime.key());
+        _invitationTimeOut = Long.parseLong(value != null ? value : "86400") * 1000;
+        _allowUserToCreateProject = Boolean.valueOf(configs.get(Config.AllowUserToCreateProject.key()));
+
+        // set up the email system for project invitations
+
+        String smtpHost = configs.get("project.smtp.host");
+        int smtpPort = NumbersUtil.parseInt(configs.get("project.smtp.port"), 25);
+        String useAuthStr = configs.get("project.smtp.useAuth");
+        boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
+        String smtpUsername = configs.get("project.smtp.username");
+        String smtpPassword = configs.get("project.smtp.password");
+        String emailSender = configs.get("project.email.sender");
+        String smtpDebugStr = configs.get("project.smtp.debug");
+        boolean smtpDebug = false;
+        if (smtpDebugStr != null) {
+            smtpDebug = Boolean.parseBoolean(smtpDebugStr);
+        }
+
+        _emailInvite = new EmailInvite(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
+        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Project-ExpireInvitations"));
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        _executor.scheduleWithFixedDelay(new ExpiredInvitationsCleanup(), _projectCleanupExpInvInterval, _projectCleanupExpInvInterval, TimeUnit.SECONDS);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create = true)
+    @DB
+    public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = caller;
+
+        //check if the user authorized to create the project
+        if (_accountMgr.isNormalUser(caller.getId()) && !_allowUserToCreateProject) {
+            throw new PermissionDeniedException("Regular user is not permitted to create a project");
+        }
+
+        //Verify request parameters
+        if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
+            throw new InvalidParameterValueException("Account name and domain id must be specified together");
+        }
+
+        if (accountName != null) {
+            owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
+        }
+
+        //don't allow 2 projects with the same name inside the same domain
+        if (_projectDao.findByNameAndDomain(name, owner.getDomainId()) != null) {
+            throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId());
+        }
+
+        //do resource limit check
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
+
+        final Account ownerFinal = owner;
+        return Transaction.execute(new TransactionCallback<Project>() {
+            @Override
+            public Project doInTransaction(TransactionStatus status) {
+
+        //Create an account associated with the project
+        StringBuilder acctNm = new StringBuilder("PrjAcct-");
+                acctNm.append(name).append("-").append(ownerFinal.getDomainId());
+
+        Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, null, domainId, null, null, UUID.randomUUID().toString());
+
+                Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
+
+        //assign owner to the project
+                assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
+
+        if (project != null) {
+            CallContext.current().setEventDetails("Project id=" + project.getId());
+            CallContext.current().putContextParameter(Project.class, project.getUuid());
+        }
+
+        //Increment resource count
+                _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);
+
+        return project;
+    }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async = true)
+    @DB
+    public Project enableProject(long projectId) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        ProjectVO project = getProject(projectId);
+        //verify input parameters
+        if (project == null) {
+            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        //at this point enabling project doesn't require anything, so just update the state
+        project.setState(State.Active);
+        _projectDao.update(projectId, project);
+
+        return project;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
+    public boolean deleteProject(long projectId) {
+        CallContext ctx = CallContext.current();
+
+        ProjectVO project = getProject(projectId);
+        //verify input parameters
+        if (project == null) {
+            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+        }
+
+        _accountMgr.checkAccess(ctx.getCallingAccount(), AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
+    }
+
+    @DB
+    @Override
+    public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) {
+        //mark project as inactive first, so you can't add resources to it
+        boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+        s_logger.debug("Marking project id=" + project.getId() + " with state " + State.Disabled + " as a part of project delete...");
+        project.setState(State.Disabled);
+        boolean updateResult = _projectDao.update(project.getId(), project);
+        //owner can be already removed at this point, so adding the conditional check
+        Account projectOwner = getProjectOwner(project.getId());
+        if (projectOwner != null) {
+            _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
+        }
+
+                return updateResult;
+            }
+        });
+
+        if (updateResult) {
+            //pass system caller when clenaup projects account
+            if (!cleanupProject(project, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM)) {
+                s_logger.warn("Failed to cleanup project's id=" + project.getId() + " resources, not removing the project yet");
+                return false;
+            } else {
+                return _projectDao.remove(project.getId());
+            }
+        } else {
+            s_logger.warn("Failed to mark the project id=" + project.getId() + " with state " + State.Disabled);
+            return false;
+        }
+    }
+
+    @DB
+    private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) {
+        boolean result = true;
+        //Delete project's account
+        AccountVO account = _accountDao.findById(project.getProjectAccountId());
+        s_logger.debug("Deleting projects " + project + " internal account id=" + account.getId() + " as a part of project cleanup...");
+
+        result = result && _accountMgr.deleteAccount(account, callerUserId, caller);
+
+        if (result) {
+            //Unassign all users from the project
+            result = Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    boolean result = true;
+            s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
+            List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
+            for (ProjectAccount projectAccount : projectAccounts) {
+                result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
+            }
+
+            s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
+            _projectInvitationDao.cleanupInvitations(project.getId());
+
+                    return result;
+                }
+            });
+            if (result) {
+                s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
+            }
+        } else {
+            s_logger.warn("Failed to cleanup project's internal account");
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean unassignAccountFromProject(long projectId, long accountId) {
+        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
+        if (projectAccount == null) {
+            s_logger.debug("Account id=" + accountId + " is not assigned to project id=" + projectId + " so no need to unassign");
+            return true;
+        }
+
+        if (_projectAccountDao.remove(projectAccount.getId())) {
+            return true;
+        } else {
+            s_logger.warn("Failed to unassign account id=" + accountId + " from the project id=" + projectId);
+            return false;
+        }
+    }
+
+    @Override
+    public ProjectVO getProject(long projectId) {
+        return _projectDao.findById(projectId);
+    }
+
+    @Override
+    public long getInvitationTimeout() {
+        return _invitationTimeOut;
+    }
+
+    @Override
+    public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole) {
+        return _projectAccountDao.persist(new ProjectAccountVO(project, accountId, accountRole));
+    }
+
+    @Override
+    @DB
+    public boolean deleteAccountFromProject(final long projectId, final long accountId) {
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+        boolean success = true;
+
+        //remove account
+        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
+        success = _projectAccountDao.remove(projectAccount.getId());
+
+        //remove all invitations for account
+        if (success) {
+            s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project...");
+            ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId);
+            if (invite != null) {
+                success = success && _projectInvitationDao.remove(invite.getId());
+            }
+        }
+
+        return success;
+    }
+        });
+    }
+
+    @Override
+    public Account getProjectOwner(long projectId) {
+        ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId);
+        if (prAcct != null) {
+            return _accountMgr.getAccount(prAcct.getAccountId());
+        }
+
+        return null;
+    }
+
+    @Override
+    public ProjectVO findByProjectAccountId(long projectAccountId) {
+        return _projectDao.findByProjectAccountId(projectAccountId);
+    }
+
+    @Override
+    public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) {
+        return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId);
+    }
+
+    @Override
+    public Project findByNameAndDomainId(String name, long domainId) {
+        return _projectDao.findByNameAndDomain(name, domainId);
+    }
+
+    @Override
+    public boolean canAccessProjectAccount(Account caller, long accountId) {
+        //ROOT admin always can access the project
+        if (_accountMgr.isRootAdmin(caller.getId())) {
+            return true;
+        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
+            Account owner = _accountMgr.getAccount(accountId);
+            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
+            return true;
+        }
+
+        return _projectAccountDao.canAccessProjectAccount(caller.getId(), accountId);
+    }
+
+    @Override
+    public boolean canModifyProjectAccount(Account caller, long accountId) {
+        //ROOT admin always can access the project
+        if (_accountMgr.isRootAdmin(caller.getId())) {
+            return true;
+        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
+            Account owner = _accountMgr.getAccount(accountId);
+            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
+            return true;
+        }
+        return _projectAccountDao.canModifyProjectAccount(caller.getId(), accountId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
+    public Project updateProject(final long projectId, final String displayText, final String newOwnerName) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        //check that the project exists
+        final ProjectVO project = getProject(projectId);
+
+        if (project == null) {
+            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
+        }
+
+        //verify permissions
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
+        if (displayText != null) {
+            project.setDisplayText(displayText);
+            _projectDao.update(projectId, project);
+        }
+
+        if (newOwnerName != null) {
+            //check that the new owner exists
+            Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
+            if (futureOwnerAccount == null) {
+                throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
+            }
+            Account currentOwnerAccount = getProjectOwner(projectId);
+            if (currentOwnerAccount == null) {
+                s_logger.error("Unable to find the current owner for the project id=" + projectId);
+                throw new InvalidParameterValueException("Unable to find the current owner for the project id=" + projectId);
+            }
+            if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
+                ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
+                if (futureOwner == null) {
+                            throw new InvalidParameterValueException("Account " + newOwnerName +
+                                " doesn't belong to the project. Add it to the project first and then change the project's ownership");
+                }
+
+                //do resource limit check
+                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
+
+                //unset the role for the old owner
+                ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
+                currentOwner.setAccountRole(Role.Regular);
+                _projectAccountDao.update(currentOwner.getId(), currentOwner);
+                _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
+
+                //set new owner
+                futureOwner.setAccountRole(Role.Admin);
+                _projectAccountDao.update(futureOwner.getId(), futureOwner);
+                _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
+
+            } else {
+                s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
+            }
+        }
+            }
+        });
+
+        return _projectDao.findById(projectId);
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true)
+    public boolean addAccountToProject(long projectId, String accountName, String email) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        //check that the project exists
+        Project project = getProject(projectId);
+
+        if (project == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
+            ex.addProxyObject(String.valueOf(projectId), "projectId");
+            throw ex;
+        }
+
+        //User can be added to Active project only
+        if (project.getState() != Project.State.Active) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active");
+            ex.addProxyObject(project.getUuid(), "projectId");
+            throw ex;
+        }
+
+        //check that account-to-add exists
+        Account account = null;
+        if (accountName != null) {
+            account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
+            if (account == null) {
+                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id");
+                DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
+                String domainUuid = String.valueOf(project.getDomainId());
+                if (domain != null) {
+                    domainUuid = domain.getUuid();
+                }
+                ex.addProxyObject(domainUuid, "domainId");
+                throw ex;
+            }
+
+            //verify permissions - only project owner can assign
+            _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+            //Check if the account already added to the project
+            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
+            if (projectAccount != null) {
+                s_logger.debug("Account " + accountName + " already added to the project id=" + projectId);
+                return true;
+            }
+        }
+
+        if (_invitationRequired) {
+            return inviteAccountToProject(project, account, email);
+        } else {
+            if (account == null) {
+                throw new InvalidParameterValueException("Account information is required for assigning account to the project");
+            }
+            if (assignAccountToProject(project, account.getId(), ProjectAccount.Role.Regular) != null) {
+                return true;
+            } else {
+                s_logger.warn("Failed to add account " + accountName + " to project id=" + projectId);
+                return false;
+            }
+        }
+    }
+
+    private boolean inviteAccountToProject(Project project, Account account, String email) {
+        if (account != null) {
+            if (createAccountInvitation(project, account.getId()) != null) {
+                return true;
+            } else {
+                s_logger.warn("Failed to generate invitation for account " + account.getAccountName() + " to project id=" + project);
+                return false;
+            }
+        }
+
+        if (email != null) {
+            //generate the token
+            String token = generateToken(10);
+            if (generateTokenBasedInvitation(project, email, token) != null) {
+                return true;
+            } else {
+                s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project);
+                return false;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async = true)
+    public boolean deleteAccountFromProject(long projectId, String accountName) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        //check that the project exists
+        Project project = getProject(projectId);
+
+        if (project == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
+            ex.addProxyObject(String.valueOf(projectId), "projectId");
+            throw ex;
+        }
+
+        //check that account-to-remove exists
+        Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
+        if (account == null) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
+            DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
+            String domainUuid = String.valueOf(project.getDomainId());
+            if (domain != null) {
+                domainUuid = domain.getUuid();
+            }
+            ex.addProxyObject(domainUuid, "domainId");
+            throw ex;
+        }
+
+        //verify permissions
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        //Check if the account exists in the project
+        ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
+        if (projectAccount == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id");
+            // Use the projectVO object and not the projectAccount object to inject the projectId.
+            ex.addProxyObject(project.getUuid(), "projectId");
+            throw ex;
+        }
+
+        //can't remove the owner of the project
+        if (projectAccount.getAccountRole() == Role.Admin) {
+            InvalidParameterValueException ex =
+                new InvalidParameterValueException("Unable to delete account " + accountName +
+                    " from the project with specified id as the account is the owner of the project");
+            ex.addProxyObject(project.getUuid(), "projectId");
+            throw ex;
+        }
+
+        return deleteAccountFromProject(projectId, account.getId());
+    }
+
+    public ProjectInvitation createAccountInvitation(Project project, Long accountId) {
+        if (activeInviteExists(project, accountId, null)) {
+            throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project);
+        }
+
+        ProjectInvitation invitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null));
+
+        return invitation;
+    }
+
+    @DB
+    public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+        //verify if the invitation was already generated
+        ProjectInvitationVO invite = null;
+        if (accountId != null) {
+            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
+        } else if (email != null) {
+            invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
+        }
+
+        if (invite != null) {
+            if (invite.getState() == ProjectInvitation.State.Completed ||
+                    (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
+                return true;
+            } else {
+                if (invite.getState() == ProjectInvitation.State.Pending) {
+                    expireInvitation(invite);
+                }
+                //remove the expired/declined invitation
+                if (accountId != null) {
+                    s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
+                } else if (email != null) {
+                    s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
+                }
+
+                _projectInvitationDao.expunge(invite.getId());
+            }
+        }
+
+        return false;
+    }
+        });
+    }
+
+    public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
+        //verify if the invitation was already generated
+        if (activeInviteExists(project, null, email)) {
+            throw new InvalidParameterValueException("There is already a pending invitation for email " + email + " to the project id=" + project);
+        }
+
+        ProjectInvitation projectInvitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token));
+        try {
+            _emailInvite.sendInvite(token, email, project.getId());
+        } catch (Exception ex) {
+            s_logger.warn("Failed to send project id=" + project + " invitation to the email " + email + "; removing the invitation record from the db", ex);
+            _projectInvitationDao.remove(projectInvitation.getId());
+            return null;
+        }
+
+        return projectInvitation;
+    }
+
+    private boolean expireInvitation(ProjectInvitationVO invite) {
+        s_logger.debug("Expiring invitation id=" + invite.getId());
+        invite.setState(ProjectInvitation.State.Expired);
+        return _projectInvitationDao.update(invite.getId(), invite);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async = true)
+    public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long accountId = null;
+        boolean result = true;
+
+        //if accountname and token are null, default accountname to caller's account name
+        if (accountName == null && token == null) {
+            accountName = caller.getAccountName();
+        }
+
+        //check that the project exists
+        final Project project = getProject(projectId);
+
+        if (project == null) {
+            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
+        }
+
+        if (accountName != null) {
+            //check that account-to-remove exists
+            Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
+            if (account == null) {
+                throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
+            }
+
+            //verify permissions
+            _accountMgr.checkAccess(caller, null, true, account);
+
+            accountId = account.getId();
+        } else {
+            accountId = caller.getId();
+        }
+
+        //check that invitation exists
+        ProjectInvitationVO invite = null;
+        if (token == null) {
+            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId, ProjectInvitation.State.Pending);
+        } else {
+            invite = _projectInvitationDao.findPendingByTokenAndProjectId(token, projectId, ProjectInvitation.State.Pending);
+        }
+
+        if (invite != null) {
+            if (!_projectInvitationDao.isActive(invite.getId(), _invitationTimeOut) && accept) {
+                expireInvitation(invite);
+                throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
+            } else {
+
+                final ProjectInvitationVO inviteFinal = invite;
+                final Long accountIdFinal = accountId;
+                final String accountNameFinal = accountName;
+                result = Transaction.execute(new TransactionCallback<Boolean>() {
+                    @Override
+                    public Boolean doInTransaction(TransactionStatus status) {
+                        boolean result = true;
+
+                ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
+
+                //update invitation
+                        s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
+                        inviteFinal.setState(newState);
+                        result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
+
+                if (result && accept) {
+                    //check if account already exists for the project (was added before invitation got accepted)
+                            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
+                    if (projectAccount != null) {
+                                s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
+                    } else {
+                                assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular);
+                    }
+                } else {
+                            s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
+                }
+
+                        return result;
+                    }
+                });
+            }
+        } else {
+            throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<Long> listPermittedProjectAccounts(long accountId) {
+        return _projectAccountDao.listPermittedAccountIds(accountId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project")
+    @DB
+    public Project activateProject(final long projectId) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        //check that the project exists
+        final ProjectVO project = getProject(projectId);
+
+        if (project == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
+            ex.addProxyObject(String.valueOf(projectId), "projectId");
+            throw ex;
+        }
+
+        //verify permissions
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        //allow project activation only when it's in Suspended state
+        Project.State currentState = project.getState();
+
+        if (currentState == State.Active) {
+            s_logger.debug("The project id=" + projectId + " is already active, no need to activate it again");
+            return project;
+        }
+
+        if (currentState != State.Suspended) {
+            throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+        project.setState(Project.State.Active);
+        _projectDao.update(projectId, project);
+
+        _accountMgr.enableAccount(project.getProjectAccountId());
+            }
+        });
+
+        return _projectDao.findById(projectId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_SUSPEND, eventDescription = "suspending project", async = true)
+    public Project suspendProject(long projectId) throws ConcurrentOperationException, ResourceUnavailableException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        ProjectVO project = getProject(projectId);
+        //verify input parameters
+        if (project == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
+            ex.addProxyObject(String.valueOf(projectId), "projectId");
+            throw ex;
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        if (suspendProject(project)) {
+            s_logger.debug("Successfully suspended project id=" + projectId);
+            return _projectDao.findById(projectId);
+        } else {
+            CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id");
+            ex.addProxyObject(project.getUuid(), "projectId");
+            throw ex;
+        }
+
+    }
+
+    private boolean suspendProject(ProjectVO project) throws ConcurrentOperationException, ResourceUnavailableException {
+
+        s_logger.debug("Marking project " + project + " with state " + State.Suspended + " as a part of project suspend...");
+        project.setState(State.Suspended);
+        boolean updateResult = _projectDao.update(project.getId(), project);
+
+        if (updateResult) {
+            long projectAccountId = project.getProjectAccountId();
+            if (!_accountMgr.disableAccount(projectAccountId)) {
+                s_logger.warn("Failed to suspend all project's " + project + " resources; the resources will be suspended later by background thread");
+            }
+        } else {
+            throw new CloudRuntimeException("Failed to mark the project " + project + " with state " + State.Suspended);
+        }
+        return true;
+    }
+
+    public static String generateToken(int length) {
+        String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        Random rand = new Random(System.currentTimeMillis());
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            int pos = rand.nextInt(charset.length());
+            sb.append(charset.charAt(pos));
+        }
+        return sb.toString();
+    }
+
+    class EmailInvite {
+        private Session _smtpSession;
+        private final String _smtpHost;
+        private int _smtpPort = -1;
+        private boolean _smtpUseAuth = false;
+        private final String _smtpUsername;
+        private final String _smtpPassword;
+        private final String _emailSender;
+
+        public EmailInvite(String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) {
+            _smtpHost = smtpHost;
+            _smtpPort = smtpPort;
+            _smtpUseAuth = smtpUseAuth;
+            _smtpUsername = smtpUsername;
+            _smtpPassword = smtpPassword;
+            _emailSender = emailSender;
+
+            if (_smtpHost != null) {
+                Properties smtpProps = new Properties();
+                smtpProps.put("mail.smtp.host", smtpHost);
+                smtpProps.put("mail.smtp.port", smtpPort);
+                smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
+                if (smtpUsername != null) {
+                    smtpProps.put("mail.smtp.user", smtpUsername);
+                }
+
+                smtpProps.put("mail.smtps.host", smtpHost);
+                smtpProps.put("mail.smtps.port", smtpPort);
+                smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
+                if (smtpUsername != null) {
+                    smtpProps.put("mail.smtps.user", smtpUsername);
+                }
+
+                if ((smtpUsername != null) && (smtpPassword != null)) {
+                    _smtpSession = Session.getInstance(smtpProps, new Authenticator() {
+                        @Override
+                        protected PasswordAuthentication getPasswordAuthentication() {
+                            return new PasswordAuthentication(smtpUsername, smtpPassword);
+                        }
+                    });
+                } else {
+                    _smtpSession = Session.getInstance(smtpProps);
+                }
+                _smtpSession.setDebug(smtpDebug);
+            } else {
+                _smtpSession = null;
+            }
+        }
+
+        public void sendInvite(String token, String email, long projectId) throws MessagingException, UnsupportedEncodingException {
+            if (_smtpSession != null) {
+                InternetAddress address = null;
+                if (email != null) {
+                    try {
+                        address = new InternetAddress(email, email);
+                    } catch (Exception ex) {
+                        s_logger.error("Exception creating address for: " + email, ex);
+                    }
+                }
+
+                String content = "You've been invited to join the CloudStack project id=" + projectId + ". Please use token " + token + " to complete registration";
+
+                SMTPMessage msg = new SMTPMessage(_smtpSession);
+                msg.setSender(new InternetAddress(_emailSender, _emailSender));
+                msg.setFrom(new InternetAddress(_emailSender, _emailSender));
+                msg.addRecipient(RecipientType.TO, address);
+                msg.setSubject("You are invited to join the cloud stack project id=" + projectId);
+                msg.setSentDate(new Date(DateUtil.currentGMTTime().getTime() >> 10));
+                msg.setContent(content, "text/plain");
+                msg.saveChanges();
+
+                SMTPTransport smtpTrans = null;
+                if (_smtpUseAuth) {
+                    smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
+                } else {
+                    smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
+                }
+                smtpTrans.connect();
+                smtpTrans.sendMessage(msg, msg.getAllRecipients());
+                smtpTrans.close();
+            } else {
+                throw new CloudRuntimeException("Unable to send email invitation; smtp ses");
+            }
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_REMOVE, eventDescription = "removing project invitation", async = true)
+    public boolean deleteProjectInvitation(long id) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        ProjectInvitation invitation = _projectInvitationDao.findById(id);
+        if (invitation == null) {
+            throw new InvalidParameterValueException("Unable to find project invitation by id " + id);
+        }
+
+        //check that the project exists
+        Project project = getProject(invitation.getProjectId());
+
+        //check permissions - only project owner can remove the invitations
+        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
+
+        if (_projectInvitationDao.remove(id)) {
+            s_logger.debug("Project Invitation id=" + id + " is removed");
+            return true;
+        } else {
+            s_logger.debug("Failed to remove project invitation id=" + id);
+            return false;
+        }
+    }
+
+    public class ExpiredInvitationsCleanup extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                TimeZone.getDefault();
+                List<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut);
+                if (!invitationsToExpire.isEmpty()) {
+                    s_logger.debug("Found " + invitationsToExpire.size() + " projects to expire");
+                    for (ProjectInvitationVO invitationToExpire : invitationsToExpire) {
+                        invitationToExpire.setState(ProjectInvitation.State.Expired);
+                        _projectInvitationDao.update(invitationToExpire.getId(), invitationToExpire);
+                        s_logger.trace("Expired project invitation id=" + invitationToExpire.getId());
+                    }
+                }
+            } catch (Exception ex) {
+                s_logger.warn("Exception while running expired invitations cleanup", ex);
+            }
+        }
+    }
+
+    @Override
+    public boolean projectInviteRequired() {
+        return _invitationRequired;
+    }
+
+    @Override
+    public boolean allowUserToCreateProject() {
+        return _allowUserToCreateProject;
+    }
+
+}
diff --git a/server/src/com/cloud/resource/DiscovererBase.java b/server/src/main/java/com/cloud/resource/DiscovererBase.java
similarity index 100%
rename from server/src/com/cloud/resource/DiscovererBase.java
rename to server/src/main/java/com/cloud/resource/DiscovererBase.java
diff --git a/server/src/com/cloud/resource/DummyHostDiscoverer.java b/server/src/main/java/com/cloud/resource/DummyHostDiscoverer.java
similarity index 100%
rename from server/src/com/cloud/resource/DummyHostDiscoverer.java
rename to server/src/main/java/com/cloud/resource/DummyHostDiscoverer.java
diff --git a/server/src/com/cloud/resource/DummyHostServerResource.java b/server/src/main/java/com/cloud/resource/DummyHostServerResource.java
similarity index 100%
rename from server/src/com/cloud/resource/DummyHostServerResource.java
rename to server/src/main/java/com/cloud/resource/DummyHostServerResource.java
diff --git a/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java
new file mode 100755
index 0000000..27fa42c
--- /dev/null
+++ b/server/src/main/java/com/cloud/resource/ResourceManagerImpl.java
@@ -0,0 +1,2986 @@
+// 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.resource;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.Pair;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
+import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
+import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
+import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.commons.collections.CollectionUtils;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetGPUStatsAnswer;
+import com.cloud.agent.api.GetGPUStatsCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PropagateResourceEventCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.agent.api.UpdateHostPasswordCommand;
+import com.cloud.agent.api.VgpuTypesInfo;
+import com.cloud.agent.api.to.GPUDeviceTO;
+import com.cloud.agent.transport.Request;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.CapacityState;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterIpAddressVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.PodCluster;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.ClusterVSMMapDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterIpAddressDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.PlannerHostReservationVO;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.gpu.GPU;
+import com.cloud.gpu.HostGpuGroupsVO;
+import com.cloud.gpu.VGPUTypesVO;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.gpu.dao.VGPUTypesDao;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.ha.HighAvailabilityManager.WorkType;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostStats;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.Status.Event;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.host.dao.HostTagsDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping;
+import com.cloud.org.Managed;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.StorageService;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.net.Ip;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.utils.ssh.SshException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.gson.Gson;
+
+@Component
+public class ResourceManagerImpl extends ManagerBase implements ResourceManager, ResourceService, Manager {
+    private static final Logger s_logger = Logger.getLogger(ResourceManagerImpl.class);
+
+    Gson _gson;
+
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private StorageManager _storageMgr;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private CapacityDao _capacityDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private HostDetailsDao _hostDetailsDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private HostTagsDao _hostTagsDao;
+    @Inject
+    private GuestOSCategoryDao _guestOSCategoryDao;
+    @Inject
+    protected HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    protected VGPUTypesDao _vgpuTypesDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private DataCenterIpAddressDao _privateIPAddressDao;
+    @Inject
+    private IPAddressDao _publicIPAddressDao;
+    @Inject
+    private VirtualMachineManager _vmMgr;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private HighAvailabilityManager _haMgr;
+    @Inject
+    private StorageService _storageSvr;
+    @Inject
+    PlannerHostReservationDao _plannerHostReserveDao;
+    @Inject
+    private DedicatedResourceDao _dedicatedDao;
+    @Inject
+    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+
+    private List<? extends Discoverer> _discoverers;
+
+    public List<? extends Discoverer> getDiscoverers() {
+        return _discoverers;
+    }
+
+    public void setDiscoverers(final List<? extends Discoverer> discoverers) {
+        _discoverers = discoverers;
+    }
+
+    @Inject
+    private ClusterManager _clusterMgr;
+    @Inject
+    private StoragePoolHostDao _storagePoolHostDao;
+
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private ConfigurationManager _configMgr;
+    @Inject
+    private ClusterVSMMapDao _clusterVSMMapDao;
+    @Inject
+    private UserVmDetailsDao userVmDetailsDao;
+
+    private final long _nodeId = ManagementServerNode.getManagementServerId();
+
+    private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
+
+    private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
+    private HypervisorType _defaultSystemVMHypervisor;
+
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds
+
+    private GenericSearchBuilder<HostVO, String> _hypervisorsInDC;
+
+    private SearchBuilder<HostGpuGroupsVO> _gpuAvailability;
+
+    private Map<Long,Integer> retryHostMaintenance = new ConcurrentHashMap<>();
+
+    private void insertListener(final Integer event, final ResourceListener listener) {
+        List<ResourceListener> lst = _lifeCycleListeners.get(event);
+        if (lst == null) {
+            lst = new ArrayList<ResourceListener>();
+            _lifeCycleListeners.put(event, lst);
+        }
+
+        if (lst.contains(listener)) {
+            throw new CloudRuntimeException("Duplicate resource lisener:" + listener.getClass().getSimpleName());
+        }
+
+        lst.add(listener);
+    }
+
+    @Override
+    public void registerResourceEvent(final Integer event, final ResourceListener listener) {
+        synchronized (_lifeCycleListeners) {
+            if ((event & ResourceListener.EVENT_DISCOVER_BEFORE) != 0) {
+                insertListener(ResourceListener.EVENT_DISCOVER_BEFORE, listener);
+            }
+            if ((event & ResourceListener.EVENT_DISCOVER_AFTER) != 0) {
+                insertListener(ResourceListener.EVENT_DISCOVER_AFTER, listener);
+            }
+            if ((event & ResourceListener.EVENT_DELETE_HOST_BEFORE) != 0) {
+                insertListener(ResourceListener.EVENT_DELETE_HOST_BEFORE, listener);
+            }
+            if ((event & ResourceListener.EVENT_DELETE_HOST_AFTER) != 0) {
+                insertListener(ResourceListener.EVENT_DELETE_HOST_AFTER, listener);
+            }
+            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) != 0) {
+                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, listener);
+            }
+            if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) != 0) {
+                insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, listener);
+            }
+            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) != 0) {
+                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, listener);
+            }
+            if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) != 0) {
+                insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, listener);
+            }
+        }
+    }
+
+    @Override
+    public void unregisterResourceEvent(final ResourceListener listener) {
+        synchronized (_lifeCycleListeners) {
+            final Iterator it = _lifeCycleListeners.entrySet().iterator();
+            while (it.hasNext()) {
+                final Map.Entry<Integer, List<ResourceListener>> items = (Map.Entry<Integer, List<ResourceListener>>)it.next();
+                final List<ResourceListener> lst = items.getValue();
+                lst.remove(listener);
+            }
+        }
+    }
+
+    protected void processResourceEvent(final Integer event, final Object... params) {
+        final List<ResourceListener> lst = _lifeCycleListeners.get(event);
+        if (lst == null || lst.size() == 0) {
+            return;
+        }
+
+        String eventName;
+        for (final ResourceListener l : lst) {
+            if (event.equals(ResourceListener.EVENT_DISCOVER_BEFORE)) {
+                l.processDiscoverEventBefore((Long)params[0], (Long)params[1], (Long)params[2], (URI)params[3], (String)params[4], (String)params[5],
+                        (List<String>)params[6]);
+                eventName = "EVENT_DISCOVER_BEFORE";
+            } else if (event.equals(ResourceListener.EVENT_DISCOVER_AFTER)) {
+                l.processDiscoverEventAfter((Map<? extends ServerResource, Map<String, String>>)params[0]);
+                eventName = "EVENT_DISCOVER_AFTER";
+            } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_BEFORE)) {
+                l.processDeleteHostEventBefore((HostVO)params[0]);
+                eventName = "EVENT_DELETE_HOST_BEFORE";
+            } else if (event.equals(ResourceListener.EVENT_DELETE_HOST_AFTER)) {
+                l.processDeletHostEventAfter((HostVO)params[0]);
+                eventName = "EVENT_DELETE_HOST_AFTER";
+            } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE)) {
+                l.processCancelMaintenaceEventBefore((Long)params[0]);
+                eventName = "EVENT_CANCEL_MAINTENANCE_BEFORE";
+            } else if (event.equals(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER)) {
+                l.processCancelMaintenaceEventAfter((Long)params[0]);
+                eventName = "EVENT_CANCEL_MAINTENANCE_AFTER";
+            } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE)) {
+                l.processPrepareMaintenaceEventBefore((Long)params[0]);
+                eventName = "EVENT_PREPARE_MAINTENANCE_BEFORE";
+            } else if (event.equals(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER)) {
+                l.processPrepareMaintenaceEventAfter((Long)params[0]);
+                eventName = "EVENT_PREPARE_MAINTENANCE_AFTER";
+            } else {
+                throw new CloudRuntimeException("Unknown resource event:" + event);
+            }
+            s_logger.debug("Sent resource event " + eventName + " to listener " + l.getClass().getSimpleName());
+        }
+
+    }
+
+    @DB
+    @Override
+    public List<? extends Cluster> discoverCluster(final AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException {
+        final long dcId = cmd.getZoneId();
+        final long podId = cmd.getPodId();
+        final String clusterName = cmd.getClusterName();
+        String url = cmd.getUrl();
+        final String username = cmd.getUsername();
+        final String password = cmd.getPassword();
+
+        if (url != null) {
+            url = URLDecoder.decode(url);
+        }
+
+        URI uri = null;
+
+        // Check if the zone exists in the system
+        final DataCenterVO zone = _dcDao.findById(dcId);
+        if (zone == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified");
+            ex.addProxyObject(String.valueOf(dcId), "dcId");
+            throw ex;
+        }
+
+        final Account account = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
+            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "dcId");
+            throw ex;
+        }
+
+        final HostPodVO pod = _podDao.findById(podId);
+        if (pod == null) {
+            throw new InvalidParameterValueException("Can't find pod with specified podId " + podId);
+        }
+
+        // Check if the pod exists in the system
+        if (_podDao.findById(podId) == null) {
+            throw new InvalidParameterValueException("Can't find pod by id " + podId);
+        }
+        // check if pod belongs to the zone
+        if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId);
+            ex.addProxyObject(pod.getUuid(), "podId");
+            ex.addProxyObject(zone.getUuid(), "dcId");
+            throw ex;
+        }
+
+        // Verify cluster information and create a new cluster if needed
+        if (clusterName == null || clusterName.isEmpty()) {
+            throw new InvalidParameterValueException("Please specify cluster name");
+        }
+
+        if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
+            throw new InvalidParameterValueException("Please specify a hypervisor");
+        }
+
+        final Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
+        if (hypervisorType == null) {
+            s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
+            throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
+        }
+
+        if (zone.isSecurityGroupEnabled() && zone.getNetworkType().equals(NetworkType.Advanced)) {
+            if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer
+                    && hypervisorType != HypervisorType.LXC && hypervisorType != HypervisorType.Simulator) {
+                throw new InvalidParameterValueException("Don't support hypervisor type " + hypervisorType + " in advanced security enabled zone");
+            }
+        }
+
+        Cluster.ClusterType clusterType = null;
+        if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
+            clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
+        }
+        if (clusterType == null) {
+            clusterType = Cluster.ClusterType.CloudManaged;
+        }
+
+        Grouping.AllocationState allocationState = null;
+        if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) {
+            try {
+                allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState());
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state");
+            }
+        }
+        if (allocationState == null) {
+            allocationState = Grouping.AllocationState.Enabled;
+        }
+
+        final Discoverer discoverer = getMatchingDiscover(hypervisorType);
+        if (discoverer == null) {
+
+            throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor());
+        }
+
+        if (hypervisorType == HypervisorType.VMware) {
+            final Map<String, String> allParams = cmd.getFullUrlParams();
+            discoverer.putParam(allParams);
+        }
+
+        final List<ClusterVO> result = new ArrayList<ClusterVO>();
+
+        ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
+        cluster.setHypervisorType(hypervisorType.toString());
+
+        cluster.setClusterType(clusterType);
+        cluster.setAllocationState(allocationState);
+        try {
+            cluster = _clusterDao.persist(cluster);
+        } catch (final Exception e) {
+            // no longer tolerate exception during the cluster creation phase
+            final CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod and data center with specified ids", e);
+            // Get the pod VO object's table name.
+            ex.addProxyObject(pod.getUuid(), "podId");
+            ex.addProxyObject(zone.getUuid(), "dcId");
+            throw ex;
+        }
+        result.add(cluster);
+
+        if (clusterType == Cluster.ClusterType.CloudManaged) {
+            final Map<String, String> details = new HashMap<String, String>();
+            // should do this nicer perhaps ?
+            if (hypervisorType == HypervisorType.Ovm3) {
+                final Map<String, String> allParams = cmd.getFullUrlParams();
+                details.put("ovm3vip", allParams.get("ovm3vip"));
+                details.put("ovm3pool", allParams.get("ovm3pool"));
+                details.put("ovm3cluster", allParams.get("ovm3cluster"));
+            }
+            details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
+            details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
+            _clusterDetailsDao.persist(cluster.getId(), details);
+            return result;
+        }
+
+        // save cluster details for later cluster/host cross-checking
+        final Map<String, String> details = new HashMap<String, String>();
+        details.put("url", url);
+        details.put("username", username);
+        details.put("password", password);
+        details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
+        details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
+        _clusterDetailsDao.persist(cluster.getId(), details);
+
+        boolean success = false;
+        try {
+            try {
+                uri = new URI(UriUtils.encodeURIComponent(url));
+                if (uri.getScheme() == null) {
+                    throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix");
+                } else if (uri.getScheme().equalsIgnoreCase("http")) {
+                    if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
+                        throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format http://hostname/path");
+                    }
+                }
+            } catch (final URISyntaxException e) {
+                throw new InvalidParameterValueException(url + " is not a valid uri");
+            }
+
+            final List<HostVO> hosts = new ArrayList<HostVO>();
+            Map<? extends ServerResource, Map<String, String>> resources = null;
+            resources = discoverer.find(dcId, podId, cluster.getId(), uri, username, password, null);
+
+            if (resources != null) {
+                for (final Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
+                    final ServerResource resource = entry.getKey();
+
+                    final HostVO host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, null, false);
+                    if (host != null) {
+                        hosts.add(host);
+                    }
+                    discoverer.postDiscovery(hosts, _nodeId);
+                }
+                s_logger.info("External cluster has been successfully discovered by " + discoverer.getName());
+                success = true;
+                return result;
+            }
+
+            s_logger.warn("Unable to find the server resources at " + url);
+            throw new DiscoveryException("Unable to add the external cluster");
+        } finally {
+            if (!success) {
+                _clusterDetailsDao.deleteDetails(cluster.getId());
+                _clusterDao.remove(cluster.getId());
+            }
+        }
+    }
+
+    @Override
+    public Discoverer getMatchingDiscover(final Hypervisor.HypervisorType hypervisorType) {
+        for (final Discoverer discoverer : _discoverers) {
+            if (discoverer.getHypervisorType() == hypervisorType) {
+                return discoverer;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<? extends Host> discoverHosts(final AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
+        Long dcId = cmd.getZoneId();
+        final Long podId = cmd.getPodId();
+        final Long clusterId = cmd.getClusterId();
+        String clusterName = cmd.getClusterName();
+        final String url = cmd.getUrl();
+        final String username = cmd.getUsername();
+        final String password = cmd.getPassword();
+        final List<String> hostTags = cmd.getHostTags();
+
+        dcId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), dcId);
+
+        // this is for standalone option
+        if (clusterName == null && clusterId == null) {
+            clusterName = "Standalone-" + url;
+        }
+
+        if (clusterId != null) {
+            final ClusterVO cluster = _clusterDao.findById(clusterId);
+            if (cluster == null) {
+                final InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster for specified clusterId");
+                ex.addProxyObject(clusterId.toString(), "clusterId");
+                throw ex;
+            } else {
+                if (cluster.getGuid() == null) {
+                    final List<HostVO> hosts = listAllHostsInCluster(clusterId);
+                    if (!hosts.isEmpty()) {
+                        final CloudRuntimeException ex =
+                                new CloudRuntimeException("Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up");
+                        ex.addProxyObject(cluster.getUuid(), "clusterId");
+                        throw ex;
+                    }
+                }
+            }
+        }
+
+        return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), false);
+    }
+
+    @Override
+    public List<? extends Host> discoverHosts(final AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
+        final Long dcId = cmd.getZoneId();
+        final String url = cmd.getUrl();
+        return discoverHostsFull(dcId, null, null, null, url, null, null, "SecondaryStorage", null, null, false);
+    }
+
+    private List<HostVO> discoverHostsFull(final Long dcId, final Long podId, Long clusterId, final String clusterName, String url, String username, String password,
+            final String hypervisorType, final List<String> hostTags, final Map<String, String> params, final boolean deferAgentCreation) throws IllegalArgumentException, DiscoveryException,
+            InvalidParameterValueException {
+        URI uri = null;
+
+        // Check if the zone exists in the system
+        final DataCenterVO zone = _dcDao.findById(dcId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by id " + dcId);
+        }
+
+        final Account account = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
+            final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "dcId");
+            throw ex;
+        }
+
+        // Check if the pod exists in the system
+        if (podId != null) {
+            final HostPodVO pod = _podDao.findById(podId);
+            if (pod == null) {
+                throw new InvalidParameterValueException("Can't find pod by id " + podId);
+            }
+            // check if pod belongs to the zone
+            if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
+                final InvalidParameterValueException ex =
+                        new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId);
+                ex.addProxyObject(pod.getUuid(), "podId");
+                ex.addProxyObject(zone.getUuid(), "dcId");
+                throw ex;
+            }
+        }
+
+        // Verify cluster information and create a new cluster if needed
+        if (clusterName != null && clusterId != null) {
+            throw new InvalidParameterValueException("Can't specify cluster by both id and name");
+        }
+
+        if (hypervisorType == null || hypervisorType.isEmpty()) {
+            throw new InvalidParameterValueException("Need to specify Hypervisor Type");
+        }
+
+        if ((clusterName != null || clusterId != null) && podId == null) {
+            throw new InvalidParameterValueException("Can't specify cluster without specifying the pod");
+        }
+
+        if (clusterId != null) {
+            if (_clusterDao.findById(clusterId) == null) {
+                throw new InvalidParameterValueException("Can't find cluster by id " + clusterId);
+            }
+
+            if (hypervisorType.equalsIgnoreCase(HypervisorType.VMware.toString())) {
+                // VMware only allows adding host to an existing cluster, as we
+                // already have a lot of information
+                // in cluster object, to simplify user input, we will construct
+                // neccessary information here
+                final Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
+                username = clusterDetails.get("username");
+                assert username != null;
+
+                password = clusterDetails.get("password");
+                assert password != null;
+
+                try {
+                    uri = new URI(UriUtils.encodeURIComponent(url));
+
+                    url = clusterDetails.get("url") + "/" + uri.getHost();
+                } catch (final URISyntaxException e) {
+                    throw new InvalidParameterValueException(url + " is not a valid uri");
+                }
+            }
+        }
+
+        if ((hypervisorType.equalsIgnoreCase(HypervisorType.BareMetal.toString()))) {
+            if (hostTags.isEmpty()) {
+                throw new InvalidParameterValueException("hosttag is mandatory while adding host of type Baremetal");
+            }
+        }
+
+        if (clusterName != null) {
+            final HostPodVO pod = _podDao.findById(podId);
+            if (pod == null) {
+                throw new InvalidParameterValueException("Can't find pod by id " + podId);
+            }
+            ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
+            cluster.setHypervisorType(hypervisorType);
+            try {
+                cluster = _clusterDao.persist(cluster);
+            } catch (final Exception e) {
+                cluster = _clusterDao.findBy(clusterName, podId);
+                if (cluster == null) {
+                    final CloudRuntimeException ex =
+                            new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod with specified podId and data center with specified dcID", e);
+                    ex.addProxyObject(pod.getUuid(), "podId");
+                    ex.addProxyObject(zone.getUuid(), "dcId");
+                    throw ex;
+                }
+            }
+            clusterId = cluster.getId();
+            if (_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio") == null) {
+                final ClusterDetailsVO cluster_cpu_detail = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", "1");
+                final ClusterDetailsVO cluster_memory_detail = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", "1");
+                _clusterDetailsDao.persist(cluster_cpu_detail);
+                _clusterDetailsDao.persist(cluster_memory_detail);
+            }
+
+        }
+
+        try {
+            uri = new URI(UriUtils.encodeURIComponent(url));
+            if (uri.getScheme() == null) {
+                throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// (or cifs://) as a prefix");
+            } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
+                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
+                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format nfs://hostname/path");
+                }
+            } else if (uri.getScheme().equalsIgnoreCase("cifs")) {
+                // Don't validate against a URI encoded URI.
+                final URI cifsUri = new URI(url);
+                final String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
+                if (warnMsg != null) {
+                    throw new InvalidParameterValueException(warnMsg);
+                }
+            }
+        } catch (final URISyntaxException e) {
+            throw new InvalidParameterValueException(url + " is not a valid uri");
+        }
+
+        final List<HostVO> hosts = new ArrayList<HostVO>();
+        s_logger.info("Trying to add a new host at " + url + " in data center " + dcId);
+        boolean isHypervisorTypeSupported = false;
+        for (final Discoverer discoverer : _discoverers) {
+            if (params != null) {
+                discoverer.putParam(params);
+            }
+
+            if (!discoverer.matchHypervisor(hypervisorType)) {
+                continue;
+            }
+            isHypervisorTypeSupported = true;
+            Map<? extends ServerResource, Map<String, String>> resources = null;
+
+            processResourceEvent(ResourceListener.EVENT_DISCOVER_BEFORE, dcId, podId, clusterId, uri, username, password, hostTags);
+            try {
+                resources = discoverer.find(dcId, podId, clusterId, uri, username, password, hostTags);
+            } catch (final DiscoveryException e) {
+                throw e;
+            } catch (final Exception e) {
+                s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + ", skip to another discoverer if there is any");
+            }
+            processResourceEvent(ResourceListener.EVENT_DISCOVER_AFTER, resources);
+
+            if (resources != null) {
+                for (final Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
+                    final ServerResource resource = entry.getKey();
+                    /*
+                     * For KVM, if we go to here, that means kvm agent is
+                     * already connected to mgt svr.
+                     */
+                    if (resource instanceof KvmDummyResourceBase) {
+                        final Map<String, String> details = entry.getValue();
+                        final String guid = details.get("guid");
+                        final List<HostVO> kvmHosts = listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId);
+                        for (final HostVO host : kvmHosts) {
+                            if (host.getGuid().equalsIgnoreCase(guid)) {
+                                if (hostTags != null) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("Adding Host Tags for KVM host, tags:  :" + hostTags);
+                                    }
+                                    _hostTagsDao.persist(host.getId(), hostTags);
+                                }
+                                hosts.add(host);
+
+                                _agentMgr.notifyMonitorsOfNewlyAddedHost(host.getId());
+
+                                return hosts;
+                            }
+                        }
+                        return null;
+                    }
+
+                    HostVO host = null;
+                    if (deferAgentCreation) {
+                        host = (HostVO)createHostAndAgentDeferred(resource, entry.getValue(), true, hostTags, false);
+                    } else {
+                        host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, hostTags, false);
+                    }
+                    if (host != null) {
+                        hosts.add(host);
+                    }
+                    discoverer.postDiscovery(hosts, _nodeId);
+
+                }
+                s_logger.info("server resources successfully discovered by " + discoverer.getName());
+                return hosts;
+            }
+        }
+        if (!isHypervisorTypeSupported) {
+            final String msg = "Do not support HypervisorType " + hypervisorType + " for " + url;
+            s_logger.warn(msg);
+            throw new DiscoveryException(msg);
+        }
+        s_logger.warn("Unable to find the server resources at " + url);
+        throw new DiscoveryException("Unable to add the host");
+    }
+
+    @Override
+    public Host getHost(final long hostId) {
+        return _hostDao.findById(hostId);
+    }
+
+    @DB
+    protected boolean doDeleteHost(final long hostId, final boolean isForced, final boolean isForceDeleteStorage) {
+        _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+        // Verify that host exists
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
+        }
+        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), host.getDataCenterId());
+
+        if (!isForced && host.getResourceState() != ResourceState.Maintenance) {
+            throw new CloudRuntimeException("Host " + host.getUuid() +
+                    " cannot be deleted as it is not in maintenance mode. Either put the host into maintenance or perform a forced deletion.");
+        }
+        // Get storage pool host mappings here because they can be removed as a
+        // part of handleDisconnect later
+        final List<StoragePoolHostVO> pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId);
+
+        final ResourceStateAdapter.DeleteHostAnswer answer =
+                (ResourceStateAdapter.DeleteHostAnswer)dispatchToStateAdapters(ResourceStateAdapter.Event.DELETE_HOST, false, host, isForced,
+                        isForceDeleteStorage);
+
+        if (answer == null) {
+            throw new CloudRuntimeException("No resource adapter respond to DELETE_HOST event for " + host.getName() + " id = " + hostId + ", hypervisorType is " +
+                    host.getHypervisorType() + ", host type is " + host.getType());
+        }
+
+        if (answer.getIsException()) {
+            return false;
+        }
+
+        if (!answer.getIsContinue()) {
+            return true;
+        }
+
+        Long clusterId = host.getClusterId();
+
+        _agentMgr.notifyMonitorsOfHostAboutToBeRemoved(host.getId());
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null);
+                _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove);
+
+                // delete host details
+                _hostDetailsDao.deleteDetails(hostId);
+
+                // if host is GPU enabled, delete GPU entries
+                _hostGpuGroupsDao.deleteGpuEntries(hostId);
+
+                // delete host tags
+                _hostTagsDao.deleteTags(hostId);
+
+                host.setGuid(null);
+                final Long clusterId = host.getClusterId();
+                host.setClusterId(null);
+                _hostDao.update(host.getId(), host);
+
+                _hostDao.remove(hostId);
+                if (clusterId != null) {
+                    final List<HostVO> hosts = listAllHostsInCluster(clusterId);
+                    if (hosts.size() == 0) {
+                        final ClusterVO cluster = _clusterDao.findById(clusterId);
+                        cluster.setGuid(null);
+                        _clusterDao.update(clusterId, cluster);
+                    }
+                }
+
+                try {
+                    resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId);
+                } catch (final NoTransitionException e) {
+                    s_logger.debug("Cannot transmit host " + host.getId() + " to Enabled state", e);
+                }
+
+                // Delete the associated entries in host ref table
+                _storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
+
+                // Make sure any VMs that were marked as being on this host are cleaned up
+                final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
+                for (final VMInstanceVO vm : vms) {
+                    // this is how VirtualMachineManagerImpl does it when it syncs VM states
+                    vm.setState(State.Stopped);
+                    vm.setHostId(null);
+                    _vmDao.persist(vm);
+                }
+
+                // For pool ids you got, delete local storage host entries in pool table
+                // where
+                for (final StoragePoolHostVO pool : pools) {
+                    final Long poolId = pool.getPoolId();
+                    final StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
+                    if (storagePool.isLocal() && isForceDeleteStorage) {
+                        storagePool.setUuid(null);
+                        storagePool.setClusterId(null);
+                        _storagePoolDao.update(poolId, storagePool);
+                        _storagePoolDao.remove(poolId);
+                        s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId);
+                    }
+                }
+
+                // delete the op_host_capacity entry
+                final Object[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
+                final SearchCriteria<CapacityVO> hostCapacitySC = _capacityDao.createSearchCriteria();
+                hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
+                hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes);
+                _capacityDao.remove(hostCapacitySC);
+                // remove from dedicated resources
+                final DedicatedResourceVO dr = _dedicatedDao.findByHostId(hostId);
+                if (dr != null) {
+                    _dedicatedDao.remove(dr.getId());
+                }
+            }
+        });
+
+        if (clusterId != null) {
+            _agentMgr.notifyMonitorsOfRemovedHost(host.getId(), clusterId);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean deleteHost(final long hostId, final boolean isForced, final boolean isForceDeleteStorage) {
+        try {
+            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.DeleteHost);
+            if (result != null) {
+                return result;
+            }
+        } catch (final AgentUnavailableException e) {
+            return false;
+        }
+
+        return doDeleteHost(hostId, isForced, isForceDeleteStorage);
+    }
+
+    @Override
+    @DB
+    public boolean deleteCluster(final DeleteClusterCmd cmd) {
+        try {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(final TransactionStatus status) {
+                    final ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true);
+                    if (cluster == null) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " does not even exist.  Delete call is ignored.");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist");
+                    }
+
+                    final Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType();
+
+                    final List<HostVO> hosts = listAllHostsInCluster(cmd.getId());
+                    if (hosts.size() > 0) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts");
+                    }
+
+                    // don't allow to remove the cluster if it has non-removed storage
+                    // pools
+                    final List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
+                    if (storagePools.size() > 0) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove");
+                        }
+                        throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools");
+                    }
+
+                    if (_clusterDao.remove(cmd.getId())) {
+                        _capacityDao.removeBy(null, null, null, cluster.getId(), null);
+                        // If this cluster is of type vmware, and if the nexus vswitch
+                        // global parameter setting is turned
+                        // on, remove the row in cluster_vsm_map for this cluster id.
+                        if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
+                            _clusterVSMMapDao.removeByClusterId(cmd.getId());
+                        }
+                        // remove from dedicated resources
+                        final DedicatedResourceVO dr = _dedicatedDao.findByClusterId(cluster.getId());
+                        if (dr != null) {
+                            _dedicatedDao.remove(dr.getId());
+                        }
+                    }
+
+                }
+            });
+            return true;
+        } catch (final CloudRuntimeException e) {
+            throw e;
+        } catch (final Throwable t) {
+            s_logger.error("Unable to delete cluster: " + cmd.getId(), t);
+            return false;
+        }
+    }
+
+    @Override
+    @DB
+    public Cluster updateCluster(final Cluster clusterToUpdate, final String clusterType, final String hypervisor, final String allocationState, final String managedstate) {
+
+        final ClusterVO cluster = (ClusterVO)clusterToUpdate;
+        // Verify cluster information and update the cluster if needed
+        boolean doUpdate = false;
+
+        if (hypervisor != null && !hypervisor.isEmpty()) {
+            final Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor);
+            if (hypervisorType == null) {
+                s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type");
+                throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type");
+            } else {
+                cluster.setHypervisorType(hypervisor);
+                doUpdate = true;
+            }
+        }
+
+        Cluster.ClusterType newClusterType = null;
+        if (clusterType != null && !clusterType.isEmpty()) {
+            try {
+                newClusterType = Cluster.ClusterType.valueOf(clusterType);
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
+            }
+            if (newClusterType == null) {
+                s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type");
+                throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type");
+            } else {
+                cluster.setClusterType(newClusterType);
+                doUpdate = true;
+            }
+        }
+
+        Grouping.AllocationState newAllocationState = null;
+        if (allocationState != null && !allocationState.isEmpty()) {
+            try {
+                newAllocationState = Grouping.AllocationState.valueOf(allocationState);
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state");
+            }
+            if (newAllocationState == null) {
+                s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State");
+                throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state");
+            } else {
+                cluster.setAllocationState(newAllocationState);
+                doUpdate = true;
+            }
+        }
+
+        Managed.ManagedState newManagedState = null;
+        final Managed.ManagedState oldManagedState = cluster.getManagedState();
+        if (managedstate != null && !managedstate.isEmpty()) {
+            try {
+                newManagedState = Managed.ManagedState.valueOf(managedstate);
+            } catch (final IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
+            }
+            if (newManagedState == null) {
+                s_logger.error("Unable to resolve Managed State '" + managedstate + "' to a supported state");
+                throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state");
+            } else {
+                doUpdate = true;
+            }
+        }
+
+        if (doUpdate) {
+            _clusterDao.update(cluster.getId(), cluster);
+        }
+
+        if (newManagedState != null && !newManagedState.equals(oldManagedState)) {
+            if (newManagedState.equals(Managed.ManagedState.Unmanaged)) {
+                boolean success = false;
+                try {
+                    cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged);
+                    _clusterDao.update(cluster.getId(), cluster);
+                    List<HostVO> hosts = listAllHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
+                    for (final HostVO host : hosts) {
+                        if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) &&
+                                !host.getStatus().equals(Status.Up) && !host.getStatus().equals(Status.Alert)) {
+                            final String msg = "host " + host.getPrivateIpAddress() + " should not be in " + host.getStatus().toString() + " status";
+                            throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg);
+                        }
+                    }
+
+                    for (final HostVO host : hosts) {
+                        if (host.getStatus().equals(Status.Up)) {
+                            umanageHost(host.getId());
+                        }
+                    }
+                    final int retry = 40;
+                    boolean lsuccess = true;
+                    for (int i = 0; i < retry; i++) {
+                        lsuccess = true;
+                        try {
+                            Thread.sleep(5 * 1000);
+                        } catch (final Exception e) {
+                        }
+                        hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
+                        for (final HostVO host : hosts) {
+                            if (!host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) && !host.getStatus().equals(Status.Alert)) {
+                                lsuccess = false;
+                                break;
+                            }
+                        }
+                        if (lsuccess == true) {
+                            success = true;
+                            break;
+                        }
+                    }
+                    if (success == false) {
+                        throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
+                    }
+                } finally {
+                    cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError);
+                    _clusterDao.update(cluster.getId(), cluster);
+                }
+            } else if (newManagedState.equals(Managed.ManagedState.Managed)) {
+                cluster.setManagedState(Managed.ManagedState.Managed);
+                _clusterDao.update(cluster.getId(), cluster);
+            }
+
+        }
+
+        return cluster;
+    }
+
+    @Override
+    public Host cancelMaintenance(final CancelMaintenanceCmd cmd) {
+        final Long hostId = cmd.getId();
+
+        // verify input parameters
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null || host.getRemoved() != null) {
+            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
+        }
+
+        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, hostId);
+        final boolean success = cancelMaintenance(hostId);
+        processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, hostId);
+        if (!success) {
+            throw new CloudRuntimeException("Internal error cancelling maintenance.");
+        }
+        return host;
+    }
+
+    @Override
+    public Host reconnectHost(ReconnectHostCmd cmd) throws AgentUnavailableException {
+        Long hostId = cmd.getId();
+
+        HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist");
+        }
+        _agentMgr.reconnect(hostId);
+        return host;
+    }
+
+    @Override
+    public boolean resourceStateTransitTo(final Host host, final ResourceState.Event event, final long msId) throws NoTransitionException {
+        final ResourceState currentState = host.getResourceState();
+        final ResourceState nextState = currentState.getNextState(event);
+        if (nextState == null) {
+            throw new NoTransitionException("No next resource state found for current state = " + currentState + " event = " + event);
+        }
+
+        // TO DO - Make it more granular and have better conversion into capacity type
+        if(host.getType() == Type.Routing){
+            final CapacityState capacityState =  nextState == ResourceState.Enabled ? CapacityState.Enabled : CapacityState.Disabled;
+            final short[] capacityTypes = {Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY};
+            _capacityDao.updateCapacityState(null, null, null, host.getId(), capacityState.toString(), capacityTypes);
+
+            final StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host.getId());
+
+            if(storagePool != null){
+                final short[] capacityTypesLocalStorage = {Capacity.CAPACITY_TYPE_LOCAL_STORAGE};
+                _capacityDao.updateCapacityState(null, null, null, storagePool.getId(), capacityState.toString(), capacityTypesLocalStorage);
+            }
+        }
+        return _hostDao.updateResourceState(currentState, event, nextState, host);
+    }
+
+    private boolean doMaintain(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        final MaintainAnswer answer = (MaintainAnswer)_agentMgr.easySend(hostId, new MaintainCommand());
+        if (answer == null || !answer.getResult()) {
+            s_logger.warn("Unable to send MaintainCommand to host: " + hostId);
+            return false;
+        }
+
+        try {
+            resourceStateTransitTo(host, ResourceState.Event.AdminAskMaintenace, _nodeId);
+        } catch (final NoTransitionException e) {
+            final String err = "Cannot transmit resource state of host " + host.getId() + " to " + ResourceState.Maintenance;
+            s_logger.debug(err, e);
+            throw new CloudRuntimeException(err + e.getMessage());
+        }
+
+        ActionEventUtils.onStartedActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(), EventTypes.EVENT_MAINTENANCE_PREPARE, "starting maintenance for host " + hostId, true, 0);
+        _agentMgr.pullAgentToMaintenance(hostId);
+        setHostMaintenanceRetries(host);
+
+        /* TODO: move below to listener */
+        if (host.getType() == Host.Type.Routing) {
+
+            final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
+            if (vms.size() == 0) {
+                return true;
+            }
+
+            final List<HostVO> hosts = listAllUpAndEnabledHosts(Host.Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId());
+            for (final VMInstanceVO vm : vms) {
+                if (hosts == null || hosts.isEmpty() || !answer.getMigrate()
+                        || _serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.vgpuType.toString()) != null) {
+                    // Migration is not supported for VGPU Vms so stop them.
+                    // for the last host in this cluster, stop all the VMs
+                    _haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
+                } else if (HypervisorType.LXC.equals(host.getHypervisorType()) && VirtualMachine.Type.User.equals(vm.getType())){
+                    //Migration is not supported for LXC Vms. Schedule restart instead.
+                    _haMgr.scheduleRestart(vm, false);
+                } else {
+                    _haMgr.scheduleMigration(vm);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Set retries for transiting the host into Maintenance
+     */
+    protected void setHostMaintenanceRetries(HostVO host) {
+        Integer retries = HostMaintenanceRetries.valueIn(host.getClusterId());
+        retryHostMaintenance.put(host.getId(), retries);
+        s_logger.debug(String.format("Setting the host %s (%s) retries for Maintenance mode: %s",
+                host.getId(), host.getName(), retries));
+    }
+
+    @Override
+    public boolean maintain(final long hostId) throws AgentUnavailableException {
+        final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
+        if (result != null) {
+            return result;
+        }
+
+        return doMaintain(hostId);
+    }
+
+    @Override
+    public Host maintain(final PrepareForMaintenanceCmd cmd) {
+        final Long hostId = cmd.getId();
+        final HostVO host = _hostDao.findById(hostId);
+
+        if (host == null) {
+            s_logger.debug("Unable to find host " + hostId);
+            throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID.");
+        }
+
+        if (_hostDao.countBy(host.getClusterId(), ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance) > 0) {
+            throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + host.getClusterId());
+        }
+
+        if (_storageMgr.isLocalStorageActiveOnHost(host.getId())) {
+            throw new InvalidParameterValueException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage.");
+        }
+
+        try {
+            processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId);
+            if (maintain(hostId)) {
+                processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, hostId);
+                return _hostDao.findById(hostId);
+            } else {
+                throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
+            }
+        } catch (final AgentUnavailableException e) {
+            throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId);
+        }
+    }
+
+    /**
+     * Add VNC details as user VM details for each VM in 'vms' (KVM hosts only)
+     */
+    protected void setKVMVncAccess(long hostId, List<VMInstanceVO> vms) {
+        for (VMInstanceVO vm : vms) {
+            GetVncPortAnswer vmVncPortAnswer = (GetVncPortAnswer) _agentMgr.easySend(hostId, new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
+            if (vmVncPortAnswer != null) {
+                userVmDetailsDao.addDetail(vm.getId(), "kvm.vnc.address", vmVncPortAnswer.getAddress(), true);
+                userVmDetailsDao.addDetail(vm.getId(), "kvm.vnc.port", String.valueOf(vmVncPortAnswer.getPort()), true);
+            }
+        }
+    }
+
+    /**
+     * Configure VNC access for host VMs which have failed migrating to another host while trying to enter Maintenance mode
+     */
+    protected void configureVncAccessForKVMHostFailedMigrations(HostVO host, List<VMInstanceVO> failedMigrations) {
+        if (host.getHypervisorType().equals(HypervisorType.KVM)) {
+            _agentMgr.pullAgentOutMaintenance(host.getId());
+            setKVMVncAccess(host.getId(), failedMigrations);
+            _agentMgr.pullAgentToMaintenance(host.getId());
+        }
+    }
+
+    /**
+     * Set host into ErrorInMaintenance state, as errors occurred during VM migrations. Do the following:
+     * - Cancel scheduled migrations for those which have already failed
+     * - Configure VNC access for VMs (KVM hosts only)
+     */
+    protected boolean setHostIntoErrorInMaintenance(HostVO host, List<VMInstanceVO> failedMigrations) throws NoTransitionException {
+        s_logger.debug("Unable to migrate " + failedMigrations.size() + " VM(s) from host " + host.getUuid());
+        _haMgr.cancelScheduledMigrations(host);
+        configureVncAccessForKVMHostFailedMigrations(host, failedMigrations);
+        resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId);
+        return false;
+    }
+
+    /**
+     * Safely transit host into Maintenance mode
+     */
+    protected boolean setHostIntoMaintenance(HostVO host) throws NoTransitionException {
+        s_logger.debug("Host " + host.getUuid() + " entering in Maintenance");
+        resourceStateTransitTo(host, ResourceState.Event.InternalEnterMaintenance, _nodeId);
+        ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(),
+                EventVO.LEVEL_INFO, EventTypes.EVENT_MAINTENANCE_PREPARE,
+                "completed maintenance for host " + host.getId(), 0);
+        return true;
+    }
+
+    /**
+     * Return true if host goes into Maintenance mode, only when:
+     * - No Running, Migrating or Failed migrations (host_id = last_host_id) for the host
+     */
+    protected boolean isHostInMaintenance(HostVO host, List<VMInstanceVO> runningVms, List<VMInstanceVO> migratingVms, List<VMInstanceVO> failedMigrations) throws NoTransitionException {
+        if (CollectionUtils.isEmpty(runningVms) && CollectionUtils.isEmpty(migratingVms)) {
+            return CollectionUtils.isEmpty(failedMigrations) ?
+                    setHostIntoMaintenance(host) :
+                    setHostIntoErrorInMaintenance(host, failedMigrations);
+        } else if (retryHostMaintenance.containsKey(host.getId())) {
+            Integer retriesLeft = retryHostMaintenance.get(host.getId());
+            if (retriesLeft != null) {
+                if (retriesLeft <= 0) {
+                    retryHostMaintenance.remove(host.getId());
+                    s_logger.debug(String.format("No retries left while preparing KVM host %s (%s) for Maintenance, " +
+                                    "please investigate this connection.",
+                            host.getId(), host.getName()));
+                    return setHostIntoErrorInMaintenance(host, failedMigrations);
+                }
+                retriesLeft--;
+                retryHostMaintenance.put(host.getId(), retriesLeft);
+                s_logger.debug(String.format("Retries left preparing KVM host %s (%s) for Maintenance: %s",
+                        host.getId(), host.getName(), retriesLeft));
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean checkAndMaintain(final long hostId) {
+        boolean hostInMaintenance = false;
+        final HostVO host = _hostDao.findById(hostId);
+
+        try {
+            if (host.getType() != Host.Type.Storage) {
+                final List<VMInstanceVO> vos = _vmDao.listByHostId(hostId);
+                final List<VMInstanceVO> vosMigrating = _vmDao.listVmsMigratingFromHost(hostId);
+                final List<VMInstanceVO> failedVmMigrations = _vmDao.listNonMigratingVmsByHostEqualsLastHost(hostId);
+
+                hostInMaintenance = isHostInMaintenance(host, vos, vosMigrating, failedVmMigrations);
+            }
+        } catch (final NoTransitionException e) {
+            s_logger.debug("Cannot transmit host " + host.getId() + "to Maintenance state", e);
+        }
+        return hostInMaintenance;
+    }
+
+    @Override
+    public Host updateHost(final UpdateHostCmd cmd) throws NoTransitionException {
+        final Long hostId = cmd.getId();
+        final Long guestOSCategoryId = cmd.getOsCategoryId();
+
+        // Verify that the host exists
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist");
+        }
+
+        if (cmd.getAllocationState() != null) {
+            final ResourceState.Event resourceEvent = ResourceState.Event.toEvent(cmd.getAllocationState());
+            if (resourceEvent != ResourceState.Event.Enable && resourceEvent != ResourceState.Event.Disable) {
+                throw new CloudRuntimeException("Invalid allocation state:" + cmd.getAllocationState() + ", only Enable/Disable are allowed");
+            }
+
+            resourceStateTransitTo(host, resourceEvent, _nodeId);
+        }
+
+        if (guestOSCategoryId != null) {
+            // Verify that the guest OS Category exists
+            if (!(guestOSCategoryId > 0) || _guestOSCategoryDao.findById(guestOSCategoryId) == null) {
+                throw new InvalidParameterValueException("Please specify a valid guest OS category.");
+            }
+
+            final GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
+            final DetailVO guestOSDetail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
+
+            if (guestOSCategory != null && !GuestOSCategoryVO.CATEGORY_NONE.equalsIgnoreCase(guestOSCategory.getName())) {
+                // Create/Update an entry for guest.os.category.id
+                if (guestOSDetail != null) {
+                    guestOSDetail.setValue(String.valueOf(guestOSCategory.getId()));
+                    _hostDetailsDao.update(guestOSDetail.getId(), guestOSDetail);
+                } else {
+                    final Map<String, String> detail = new HashMap<String, String>();
+                    detail.put("guest.os.category.id", String.valueOf(guestOSCategory.getId()));
+                    _hostDetailsDao.persist(hostId, detail);
+                }
+            } else {
+                // Delete any existing entry for guest.os.category.id
+                if (guestOSDetail != null) {
+                    _hostDetailsDao.remove(guestOSDetail.getId());
+                }
+            }
+        }
+
+        final List<String> hostTags = cmd.getHostTags();
+        if (hostTags != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Updating Host Tags to :" + hostTags);
+            }
+            _hostTagsDao.persist(hostId, hostTags);
+        }
+
+        final String url = cmd.getUrl();
+        if (url != null) {
+            _storageMgr.updateSecondaryStorage(cmd.getId(), cmd.getUrl());
+        }
+
+        final HostVO updatedHost = _hostDao.findById(hostId);
+        return updatedHost;
+    }
+
+    @Override
+    public Cluster getCluster(final Long clusterId) {
+        return _clusterDao.findById(clusterId);
+    }
+
+    @Override
+    public DataCenter getZone(Long zoneId) {
+        return _dcDao.findById(zoneId);
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _defaultSystemVMHypervisor = HypervisorType.getType(_configDao.getValue(Config.SystemVMDefaultHypervisor.toString()));
+        _gson = GsonHelper.getGson();
+
+        _hypervisorsInDC = _hostDao.createSearchBuilder(String.class);
+        _hypervisorsInDC.select(null, Func.DISTINCT, _hypervisorsInDC.entity().getHypervisorType());
+        _hypervisorsInDC.and("hypervisorType", _hypervisorsInDC.entity().getHypervisorType(), SearchCriteria.Op.NNULL);
+        _hypervisorsInDC.and("dataCenter", _hypervisorsInDC.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        _hypervisorsInDC.and("id", _hypervisorsInDC.entity().getId(), SearchCriteria.Op.NEQ);
+        _hypervisorsInDC.and("type", _hypervisorsInDC.entity().getType(), SearchCriteria.Op.EQ);
+        _hypervisorsInDC.done();
+
+        _gpuAvailability = _hostGpuGroupsDao.createSearchBuilder();
+        _gpuAvailability.and("hostId", _gpuAvailability.entity().getHostId(), Op.EQ);
+        _gpuAvailability.and("groupName", _gpuAvailability.entity().getGroupName(), Op.EQ);
+        final SearchBuilder<VGPUTypesVO> join1 = _vgpuTypesDao.createSearchBuilder();
+        join1.and("vgpuType", join1.entity().getVgpuType(), Op.EQ);
+        join1.and("remainingCapacity", join1.entity().getRemainingCapacity(), Op.GT);
+        _gpuAvailability.join("groupId", join1, _gpuAvailability.entity().getId(), join1.entity().getGpuGroupId(), JoinBuilder.JoinType.INNER);
+        _gpuAvailability.done();
+
+        return true;
+    }
+
+    @Override
+    public List<HypervisorType> getSupportedHypervisorTypes(final long zoneId, final boolean forVirtualRouter, final Long podId) {
+        final List<HypervisorType> hypervisorTypes = new ArrayList<HypervisorType>();
+
+        List<ClusterVO> clustersForZone = new ArrayList<ClusterVO>();
+        if (podId != null) {
+            clustersForZone = _clusterDao.listByPodId(podId);
+        } else {
+            clustersForZone = _clusterDao.listByZoneId(zoneId);
+        }
+
+        for (final ClusterVO cluster : clustersForZone) {
+            final HypervisorType hType = cluster.getHypervisorType();
+            if (!forVirtualRouter || forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm) {
+                hypervisorTypes.add(hType);
+            }
+        }
+
+        return hypervisorTypes;
+    }
+
+    @Override
+    public HypervisorType getDefaultHypervisor(final long zoneId) {
+        HypervisorType defaultHyper = HypervisorType.None;
+        if (_defaultSystemVMHypervisor != HypervisorType.None) {
+            defaultHyper = _defaultSystemVMHypervisor;
+        }
+
+        final DataCenterVO dc = _dcDao.findById(zoneId);
+        if (dc == null) {
+            return HypervisorType.None;
+        }
+        _dcDao.loadDetails(dc);
+        final String defaultHypervisorInZone = dc.getDetail("defaultSystemVMHypervisorType");
+        if (defaultHypervisorInZone != null) {
+            defaultHyper = HypervisorType.getType(defaultHypervisorInZone);
+        }
+
+        final List<VMTemplateVO> systemTemplates = _templateDao.listAllSystemVMTemplates();
+        boolean isValid = false;
+        for (final VMTemplateVO template : systemTemplates) {
+            if (template.getHypervisorType() == defaultHyper) {
+                isValid = true;
+                break;
+            }
+        }
+
+        if (isValid) {
+            final List<ClusterVO> clusters = _clusterDao.listByDcHyType(zoneId, defaultHyper.toString());
+            if (clusters.size() <= 0) {
+                isValid = false;
+            }
+        }
+
+        if (isValid) {
+            return defaultHyper;
+        } else {
+            return HypervisorType.None;
+        }
+    }
+
+    @Override
+    public HypervisorType getAvailableHypervisor(final long zoneId) {
+        HypervisorType defaultHype = getDefaultHypervisor(zoneId);
+        if (defaultHype == HypervisorType.None) {
+            final List<HypervisorType> supportedHypes = getSupportedHypervisorTypes(zoneId, false, null);
+            if (supportedHypes.size() > 0) {
+                Collections.shuffle(supportedHypes);
+                defaultHype = supportedHypes.get(0);
+            }
+        }
+
+        if (defaultHype == HypervisorType.None) {
+            defaultHype = HypervisorType.Any;
+        }
+        return defaultHype;
+    }
+
+    @Override
+    public void registerResourceStateAdapter(final String name, final ResourceStateAdapter adapter) {
+        synchronized (_resourceStateAdapters) {
+            if (_resourceStateAdapters.get(name) != null) {
+                throw new CloudRuntimeException(name + " has registered");
+            }
+            _resourceStateAdapters.put(name, adapter);
+        }
+    }
+
+    @Override
+    public void unregisterResourceStateAdapter(final String name) {
+        synchronized (_resourceStateAdapters) {
+            _resourceStateAdapters.remove(name);
+        }
+    }
+
+    private Object dispatchToStateAdapters(final ResourceStateAdapter.Event event, final boolean singleTaker, final Object... args) {
+        synchronized (_resourceStateAdapters) {
+            final Iterator<Map.Entry<String, ResourceStateAdapter>> it = _resourceStateAdapters.entrySet().iterator();
+            Object result = null;
+            while (it.hasNext()) {
+                final Map.Entry<String, ResourceStateAdapter> item = it.next();
+                final ResourceStateAdapter adapter = item.getValue();
+
+                final String msg = "Dispatching resource state event " + event + " to " + item.getKey();
+                s_logger.debug(msg);
+
+                if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) {
+                    result = adapter.createHostVOForConnectedAgent((HostVO)args[0], (StartupCommand[])args[1]);
+                    if (result != null && singleTaker) {
+                        break;
+                    }
+                } else if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT) {
+                    result =
+                            adapter.createHostVOForDirectConnectAgent((HostVO)args[0], (StartupCommand[])args[1], (ServerResource)args[2], (Map<String, String>)args[3],
+                                    (List<String>)args[4]);
+                    if (result != null && singleTaker) {
+                        break;
+                    }
+                } else if (event == ResourceStateAdapter.Event.DELETE_HOST) {
+                    try {
+                        result = adapter.deleteHost((HostVO)args[0], (Boolean)args[1], (Boolean)args[2]);
+                        if (result != null) {
+                            break;
+                        }
+                    } catch (final UnableDeleteHostException e) {
+                        s_logger.debug("Adapter " + adapter.getName() + " says unable to delete host", e);
+                        result = new ResourceStateAdapter.DeleteHostAnswer(false, true);
+                    }
+                } else {
+                    throw new CloudRuntimeException("Unknown resource state event:" + event);
+                }
+            }
+
+            return result;
+        }
+    }
+
+    @Override
+    public void checkCIDR(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPrivateNetmask) throws IllegalArgumentException {
+        if (serverPrivateIP == null) {
+            return;
+        }
+        // Get the CIDR address and CIDR size
+        final String cidrAddress = pod.getCidrAddress();
+        final long cidrSize = pod.getCidrSize();
+
+        // If the server's private IP address is not in the same subnet as the
+        // pod's CIDR, return false
+        final String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
+        final String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
+        if (!cidrSubnet.equals(serverSubnet)) {
+            s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " +
+                    dc.getName());
+            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() +
+                    " and zone: " + dc.getName());
+        }
+
+        // If the server's private netmask is less inclusive than the pod's CIDR
+        // netmask, return false
+        final String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
+        final long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
+        final long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
+        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
+            throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() +
+                    " and zone: " + dc.getName());
+        }
+
+    }
+
+    private boolean checkCIDR(final HostPodVO pod, final String serverPrivateIP, final String serverPrivateNetmask) {
+        if (serverPrivateIP == null) {
+            return true;
+        }
+        // Get the CIDR address and CIDR size
+        final String cidrAddress = pod.getCidrAddress();
+        final long cidrSize = pod.getCidrSize();
+
+        // If the server's private IP address is not in the same subnet as the
+        // pod's CIDR, return false
+        final String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
+        final String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
+        if (!cidrSubnet.equals(serverSubnet)) {
+            return false;
+        }
+
+        // If the server's private netmask is less inclusive than the pod's CIDR
+        // netmask, return false
+        final String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
+        final long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
+        final long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
+        if (serverNetmaskNumeric > cidrNetmaskNumeric) {
+            return false;
+        }
+        return true;
+    }
+
+    private HostVO getNewHost(StartupCommand[] startupCommands) {
+        StartupCommand startupCommand = startupCommands[0];
+
+        HostVO host = findHostByGuid(startupCommand.getGuid());
+
+        if (host != null) {
+            return host;
+        }
+
+        host = findHostByGuid(startupCommand.getGuidWithoutResource());
+
+        if (host != null) {
+            return host;
+        }
+
+        return null;
+    }
+
+    protected HostVO createHostVO(final StartupCommand[] cmds, final ServerResource resource, final Map<String, String> details, List<String> hostTags,
+            final ResourceStateAdapter.Event stateEvent) {
+        boolean newHost = false;
+        StartupCommand startup = cmds[0];
+
+        HostVO host = getNewHost(cmds);
+
+        if (host == null) {
+            host = new HostVO(startup.getGuid());
+
+            newHost = true;
+        }
+
+        String dataCenter = startup.getDataCenter();
+        String pod = startup.getPod();
+        final String cluster = startup.getCluster();
+
+        if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) {
+            final List<HostPodVO> pods = _podDao.listAllIncludingRemoved();
+            for (final HostPodVO hpv : pods) {
+                if (checkCIDR(hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) {
+                    pod = hpv.getName();
+                    dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName();
+                    break;
+                }
+            }
+        }
+
+        long dcId = -1;
+        DataCenterVO dc = _dcDao.findByName(dataCenter);
+        if (dc == null) {
+            try {
+                dcId = Long.parseLong(dataCenter);
+                dc = _dcDao.findById(dcId);
+            } catch (final NumberFormatException e) {
+                s_logger.debug("Cannot parse " + dataCenter + " into Long.");
+            }
+        }
+        if (dc == null) {
+            throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter);
+        }
+        dcId = dc.getId();
+
+        HostPodVO p = _podDao.findByName(pod, dcId);
+        if (p == null) {
+            try {
+                final long podId = Long.parseLong(pod);
+                p = _podDao.findById(podId);
+            } catch (final NumberFormatException e) {
+                s_logger.debug("Cannot parse " + pod + " into Long.");
+            }
+        }
+        /*
+         * ResourceStateAdapter is responsible for throwing Exception if Pod is
+         * null and non-null is required. for example, XcpServerDiscoever.
+         * Others, like PxeServer, ExternalFireware don't require Pod
+         */
+        final Long podId = p == null ? null : p.getId();
+
+        Long clusterId = null;
+        if (cluster != null) {
+            try {
+                clusterId = Long.valueOf(cluster);
+            } catch (final NumberFormatException e) {
+                if (podId != null) {
+                    ClusterVO c = _clusterDao.findBy(cluster, podId.longValue());
+                    if (c == null) {
+                        c = new ClusterVO(dcId, podId.longValue(), cluster);
+                        c = _clusterDao.persist(c);
+                    }
+                    clusterId = c.getId();
+                }
+            }
+        }
+
+        if (startup instanceof StartupRoutingCommand) {
+            final StartupRoutingCommand ssCmd = (StartupRoutingCommand)startup;
+            final List<String> implicitHostTags = ssCmd.getHostTags();
+            if (!implicitHostTags.isEmpty()) {
+                if (hostTags == null) {
+                    hostTags = _hostTagsDao.gethostTags(host.getId());
+                }
+                if (hostTags != null) {
+                    implicitHostTags.removeAll(hostTags);
+                    hostTags.addAll(implicitHostTags);
+                } else {
+                    hostTags = implicitHostTags;
+                }
+            }
+        }
+
+        host.setDataCenterId(dc.getId());
+        host.setPodId(podId);
+        host.setClusterId(clusterId);
+        host.setPrivateIpAddress(startup.getPrivateIpAddress());
+        host.setPrivateNetmask(startup.getPrivateNetmask());
+        host.setPrivateMacAddress(startup.getPrivateMacAddress());
+        host.setPublicIpAddress(startup.getPublicIpAddress());
+        host.setPublicMacAddress(startup.getPublicMacAddress());
+        host.setPublicNetmask(startup.getPublicNetmask());
+        host.setStorageIpAddress(startup.getStorageIpAddress());
+        host.setStorageMacAddress(startup.getStorageMacAddress());
+        host.setStorageNetmask(startup.getStorageNetmask());
+        host.setVersion(startup.getVersion());
+        host.setName(startup.getName());
+        host.setManagementServerId(_nodeId);
+        host.setStorageUrl(startup.getIqn());
+        host.setLastPinged(System.currentTimeMillis() >> 10);
+        host.setHostTags(hostTags);
+        host.setDetails(details);
+        if (startup.getStorageIpAddressDeux() != null) {
+            host.setStorageIpAddressDeux(startup.getStorageIpAddressDeux());
+            host.setStorageMacAddressDeux(startup.getStorageMacAddressDeux());
+            host.setStorageNetmaskDeux(startup.getStorageNetmaskDeux());
+        }
+        if (resource != null) {
+            /* null when agent is connected agent */
+            host.setResource(resource.getClass().getName());
+        }
+
+        host = (HostVO)dispatchToStateAdapters(stateEvent, true, host, cmds, resource, details, hostTags);
+        if (host == null) {
+            throw new CloudRuntimeException("No resource state adapter response");
+        }
+
+        if (newHost) {
+            host = _hostDao.persist(host);
+        } else {
+            _hostDao.update(host.getId(), host);
+        }
+
+        if (startup instanceof StartupRoutingCommand) {
+            final StartupRoutingCommand ssCmd = (StartupRoutingCommand)startup;
+
+            updateSupportsClonedVolumes(host, ssCmd.getSupportsClonedVolumes());
+        }
+
+        try {
+            resourceStateTransitTo(host, ResourceState.Event.InternalCreated, _nodeId);
+            /* Agent goes to Connecting status */
+            _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId);
+        } catch (final Exception e) {
+            s_logger.debug("Cannot transmit host " + host.getId() + " to Creating state", e);
+            _agentMgr.agentStatusTransitTo(host, Status.Event.Error, _nodeId);
+            try {
+                resourceStateTransitTo(host, ResourceState.Event.Error, _nodeId);
+            } catch (final NoTransitionException e1) {
+                s_logger.debug("Cannot transmit host " + host.getId() + "to Error state", e);
+            }
+        }
+
+        return host;
+    }
+
+    private void updateSupportsClonedVolumes(HostVO host, boolean supportsClonedVolumes) {
+        final String name = "supportsResign";
+
+        DetailVO hostDetail = _hostDetailsDao.findDetail(host.getId(), name);
+
+        if (hostDetail != null) {
+            if (supportsClonedVolumes) {
+                hostDetail.setValue(Boolean.TRUE.toString());
+
+                _hostDetailsDao.update(hostDetail.getId(), hostDetail);
+            }
+            else {
+                _hostDetailsDao.remove(hostDetail.getId());
+            }
+        }
+        else {
+            if (supportsClonedVolumes) {
+                hostDetail = new DetailVO(host.getId(), name, Boolean.TRUE.toString());
+
+                _hostDetailsDao.persist(hostDetail);
+            }
+        }
+
+        boolean clusterSupportsResigning = true;
+
+        List<HostVO> hostVOs = _hostDao.findByClusterId(host.getClusterId());
+
+        for (HostVO hostVO : hostVOs) {
+            DetailVO hostDetailVO = _hostDetailsDao.findDetail(hostVO.getId(), name);
+
+            if (hostDetailVO == null || Boolean.parseBoolean(hostDetailVO.getValue()) == false) {
+                clusterSupportsResigning = false;
+
+                break;
+            }
+        }
+
+        ClusterDetailsVO clusterDetailsVO = _clusterDetailsDao.findDetail(host.getClusterId(), name);
+
+        if (clusterDetailsVO != null) {
+            if (clusterSupportsResigning) {
+                clusterDetailsVO.setValue(Boolean.TRUE.toString());
+
+                _clusterDetailsDao.update(clusterDetailsVO.getId(), clusterDetailsVO);
+            }
+            else {
+                _clusterDetailsDao.remove(clusterDetailsVO.getId());
+            }
+        }
+        else {
+            if (clusterSupportsResigning) {
+                clusterDetailsVO = new ClusterDetailsVO(host.getClusterId(), name, Boolean.TRUE.toString());
+
+                _clusterDetailsDao.persist(clusterDetailsVO);
+            }
+        }
+    }
+
+    private boolean isFirstHostInCluster(final HostVO host) {
+        boolean isFirstHost = true;
+        if (host.getClusterId() != null) {
+            final SearchBuilder<HostVO> sb = _hostDao.createSearchBuilder();
+            sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.NULL);
+            sb.and("cluster", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+            sb.done();
+            final SearchCriteria<HostVO> sc = sb.create();
+            sc.setParameters("cluster", host.getClusterId());
+
+            final List<HostVO> hosts = _hostDao.search(sc, null);
+            if (hosts != null && hosts.size() > 1) {
+                isFirstHost = false;
+            }
+        }
+        return isFirstHost;
+    }
+
+    private void markHostAsDisconnected(HostVO host, final StartupCommand[] cmds) {
+        if (host == null) { // in case host is null due to some errors, try
+            // reloading the host from db
+            if (cmds != null) {
+                final StartupCommand firstCmd = cmds[0];
+                host = findHostByGuid(firstCmd.getGuid());
+                if (host == null) {
+                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
+                }
+            }
+        }
+
+        if (host != null) {
+            // Change agent status to Alert, so that host is considered for
+            // reconnection next time
+            _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId);
+        }
+    }
+
+    private Host createHostAndAgent(final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
+        HostVO host = null;
+        StartupCommand[] cmds = null;
+        boolean hostExists = false;
+        boolean created = false;
+
+        try {
+            cmds = resource.initialize();
+            if (cmds == null) {
+                s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned");
+                return null;
+            }
+
+            /* Generate a random version in a dev setup situation */
+            if (this.getClass().getPackage().getImplementationVersion() == null) {
+                for (final StartupCommand cmd : cmds) {
+                    if (cmd.getVersion() == null) {
+                        cmd.setVersion(Long.toString(System.currentTimeMillis()));
+                    }
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
+            }
+
+            if (old) {
+                final StartupCommand firstCmd = cmds[0];
+                host = findHostByGuid(firstCmd.getGuid());
+                if (host == null) {
+                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
+                }
+                if (host != null && host.getRemoved() == null) { // host already added, no need to add again
+                    s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new");
+                    hostExists = true; // ensures that host status is left unchanged in case of adding same one again
+                    return null;
+                }
+            }
+
+            // find out if the host we want to connect to is new (so we can send an event)
+            boolean newHost = getNewHost(cmds) == null;
+
+            host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT);
+
+            if (host != null) {
+                created = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance, newHost);
+                /* reload myself from database */
+                host = _hostDao.findById(host.getId());
+            }
+        } catch (final Exception e) {
+            s_logger.warn("Unable to connect due to ", e);
+        } finally {
+            if (hostExists) {
+                if (cmds != null) {
+                    resource.disconnected();
+                }
+            } else {
+                if (!created) {
+                    if (cmds != null) {
+                        resource.disconnected();
+                    }
+                    markHostAsDisconnected(host, cmds);
+                }
+            }
+        }
+
+        return host;
+    }
+
+    private Host createHostAndAgentDeferred(final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
+        HostVO host = null;
+        StartupCommand[] cmds = null;
+        boolean hostExists = false;
+        boolean deferAgentCreation = true;
+        boolean created = false;
+
+        try {
+            cmds = resource.initialize();
+            if (cmds == null) {
+                s_logger.info("Unable to fully initialize the agent because no StartupCommands are returned");
+                return null;
+            }
+
+            /* Generate a random version in a dev setup situation */
+            if (this.getClass().getPackage().getImplementationVersion() == null) {
+                for (final StartupCommand cmd : cmds) {
+                    if (cmd.getVersion() == null) {
+                        cmd.setVersion(Long.toString(System.currentTimeMillis()));
+                    }
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
+            }
+
+            if (old) {
+                final StartupCommand firstCmd = cmds[0];
+                host = findHostByGuid(firstCmd.getGuid());
+                if (host == null) {
+                    host = findHostByGuid(firstCmd.getGuidWithoutResource());
+                }
+                if (host != null && host.getRemoved() == null) { // host already
+                    // added, no
+                    // need to add
+                    // again
+                    s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new");
+                    hostExists = true; // ensures that host status is left
+                    // unchanged in case of adding same one
+                    // again
+                    return null;
+                }
+            }
+
+            host = null;
+            boolean newHost = false;
+
+            final GlobalLock addHostLock = GlobalLock.getInternLock("AddHostLock");
+
+            try {
+                if (addHostLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                    // to safely determine first host in cluster in multi-MS scenario
+                    try {
+                        // find out if the host we want to connect to is new (so we can send an event)
+                        newHost = getNewHost(cmds) == null;
+
+                        host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT);
+
+                        if (host != null) {
+                            // if first host in cluster no need to defer agent creation
+                            deferAgentCreation = !isFirstHostInCluster(host);
+                        }
+                    } finally {
+                        addHostLock.unlock();
+                    }
+                }
+            } finally {
+                addHostLock.releaseRef();
+            }
+
+            if (host != null) {
+                if (!deferAgentCreation) { // if first host in cluster then
+                    created = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance, newHost);
+                    host = _hostDao.findById(host.getId()); // reload
+                } else {
+                    host = _hostDao.findById(host.getId()); // reload
+                    // force host status to 'Alert' so that it is loaded for
+                    // connection during next scan task
+                    _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId);
+
+                    host = _hostDao.findById(host.getId()); // reload
+                    host.setLastPinged(0); // so that scan task can pick it up
+                    _hostDao.update(host.getId(), host);
+
+                }
+            }
+        } catch (final Exception e) {
+            s_logger.warn("Unable to connect due to ", e);
+        } finally {
+            if (hostExists) {
+                if (cmds != null) {
+                    resource.disconnected();
+                }
+            } else {
+                if (!deferAgentCreation && !created) {
+                    if (cmds != null) {
+                        resource.disconnected();
+                    }
+                    markHostAsDisconnected(host, cmds);
+                }
+            }
+        }
+
+        return host;
+    }
+
+    @Override
+    public Host createHostAndAgent(final Long hostId, final ServerResource resource, final Map<String, String> details, final boolean old, final List<String> hostTags, final boolean forRebalance) {
+        final Host host = createHostAndAgent(resource, details, old, hostTags, forRebalance);
+        return host;
+    }
+
+    @Override
+    public Host addHost(final long zoneId, final ServerResource resource, final Type hostType, final Map<String, String> hostDetails) {
+        // Check if the zone exists in the system
+        if (_dcDao.findById(zoneId) == null) {
+            throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
+        }
+
+        final Map<String, String> details = hostDetails;
+        final String guid = details.get("guid");
+        final List<HostVO> currentHosts = listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId);
+        for (final HostVO currentHost : currentHosts) {
+            if (currentHost.getGuid().equals(guid)) {
+                return currentHost;
+            }
+        }
+
+        return createHostAndAgent(resource, hostDetails, true, null, false);
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(final StartupCommand[] cmds) {
+        return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED);
+    }
+
+    private void checkIPConflicts(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPrivateNetmask, final String serverPublicIP, final String serverPublicNetmask) {
+        // If the server's private IP is the same as is public IP, this host has
+        // a host-only private network. Don't check for conflicts with the
+        // private IP address table.
+        if (!ObjectUtils.equals(serverPrivateIP, serverPublicIP)) {
+            if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
+                // If the server's private IP address is already in the
+                // database, return false
+                final List<DataCenterIpAddressVO> existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
+
+                assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
+                if (existingPrivateIPs.size() > 1) {
+                    throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() +
+                            " and zone: " + dc.getName());
+                }
+                if (existingPrivateIPs.size() == 1) {
+                    final DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
+                    if (vo.getInstanceId() != null) {
+                        throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() +
+                                " and zone: " + dc.getName());
+                    }
+                }
+            }
+        }
+
+        if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
+            // If the server's public IP address is already in the database,
+            // return false
+            final List<IPAddressVO> existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
+            if (existingPublicIPs.size() > 0) {
+                throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
+            }
+        }
+    }
+
+    @Override
+    public HostVO fillRoutingHostVO(final HostVO host, final StartupRoutingCommand ssCmd, final HypervisorType hyType, Map<String, String> details, final List<String> hostTags) {
+        if (host.getPodId() == null) {
+            s_logger.error("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
+            throw new IllegalArgumentException("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null");
+        }
+
+        final ClusterVO clusterVO = _clusterDao.findById(host.getClusterId());
+        if (clusterVO.getHypervisorType() != hyType) {
+            throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + hyType + " into cluster: " + clusterVO.getId() +
+                    " whose hypervisor type is: " + clusterVO.getHypervisorType());
+        }
+
+        final Map<String, String> hostDetails = ssCmd.getHostDetails();
+        if (hostDetails != null) {
+            if (details != null) {
+                details.putAll(hostDetails);
+            } else {
+                details = hostDetails;
+            }
+        }
+
+        final HostPodVO pod = _podDao.findById(host.getPodId());
+        final DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
+        checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask());
+        host.setType(com.cloud.host.Host.Type.Routing);
+        host.setDetails(details);
+        host.setCaps(ssCmd.getCapabilities());
+        host.setCpuSockets(ssCmd.getCpuSockets());
+        host.setCpus(ssCmd.getCpus());
+        host.setTotalMemory(ssCmd.getMemory());
+        host.setSpeed(ssCmd.getSpeed());
+        host.setHypervisorType(hyType);
+        host.setHypervisorVersion(ssCmd.getHypervisorVersion());
+        host.setGpuGroups(ssCmd.getGpuGroupDetails());
+        return host;
+    }
+
+    @Override
+    public void deleteRoutingHost(final HostVO host, final boolean isForced, final boolean forceDestroyStorage) throws UnableDeleteHostException {
+        if (host.getType() != Host.Type.Routing) {
+            throw new CloudRuntimeException("Non-Routing host gets in deleteRoutingHost, id is " + host.getId());
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Deleting Host: " + host.getId() + " Guid:" + host.getGuid());
+        }
+
+        if (forceDestroyStorage) {
+            // put local storage into mainenance mode, will set all the VMs on
+            // this local storage into stopped state
+            final StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host.getId());
+            if (storagePool != null) {
+                if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) {
+                    try {
+                        final StoragePool pool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId());
+                        if (pool == null) {
+                            s_logger.debug("Failed to set primary storage into maintenance mode");
+
+                            throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode");
+                        }
+                    } catch (final Exception e) {
+                        s_logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString());
+                        throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString());
+                    }
+                }
+
+                final List<VMInstanceVO> vmsOnLocalStorage = _storageMgr.listByStoragePool(storagePool.getId());
+                for (final VMInstanceVO vm : vmsOnLocalStorage) {
+                    try {
+                        _vmMgr.destroy(vm.getUuid(), false);
+                    } catch (final Exception e) {
+                        final String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId();
+                        s_logger.debug(errorMsg, e);
+                        throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
+                    }
+                }
+            }
+        } else {
+            // Check if there are vms running/starting/stopping on this host
+            final List<VMInstanceVO> vms = _vmDao.listByHostId(host.getId());
+            if (!vms.isEmpty()) {
+                if (isForced) {
+                    // Stop HA disabled vms and HA enabled vms in Stopping state
+                    // Restart HA enabled vms
+                    for (final VMInstanceVO vm : vms) {
+                        if (!vm.isHaEnabled() || vm.getState() == State.Stopping) {
+                            s_logger.debug("Stopping vm: " + vm + " as a part of deleteHost id=" + host.getId());
+                            try {
+                                _vmMgr.advanceStop(vm.getUuid(), false);
+                            } catch (final Exception e) {
+                                final String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId();
+                                s_logger.debug(errorMsg, e);
+                                throw new UnableDeleteHostException(errorMsg + "," + e.getMessage());
+                            }
+                        } else if (vm.isHaEnabled() && (vm.getState() == State.Running || vm.getState() == State.Starting)) {
+                            s_logger.debug("Scheduling restart for vm: " + vm + " " + vm.getState() + " on the host id=" + host.getId());
+                            _haMgr.scheduleRestart(vm, false);
+                        }
+                    }
+                } else {
+                    throw new UnableDeleteHostException("Unable to delete the host as there are vms in " + vms.get(0).getState() +
+                            " state using this host and isForced=false specified");
+                }
+            }
+        }
+    }
+
+    private boolean doCancelMaintenance(final long hostId) {
+        HostVO host;
+        host = _hostDao.findById(hostId);
+        if (host == null || host.getRemoved() != null) {
+            s_logger.warn("Unable to find host " + hostId);
+            return true;
+        }
+
+        /*
+         * TODO: think twice about returning true or throwing out exception, I
+         * really prefer to exception that always exposes bugs
+         */
+        if (host.getResourceState() != ResourceState.PrepareForMaintenance && host.getResourceState() != ResourceState.Maintenance &&
+                host.getResourceState() != ResourceState.ErrorInMaintenance) {
+            throw new CloudRuntimeException("Cannot perform cancelMaintenance when resource state is " + host.getResourceState() + ", hostId = " + hostId);
+        }
+
+        /* TODO: move to listener */
+        _haMgr.cancelScheduledMigrations(host);
+
+        boolean vms_migrating = false;
+        final List<VMInstanceVO> vms = _haMgr.findTakenMigrationWork();
+        for (final VMInstanceVO vm : vms) {
+            if (vm.getHostId() != null && vm.getHostId() == hostId) {
+                s_logger.warn("Unable to cancel migration because the vm is being migrated: " + vm + ", hostId = " + hostId);
+                vms_migrating = true;
+            }
+        }
+
+        handleAgentIfNotConnected(host, vms_migrating);
+
+        try {
+            resourceStateTransitTo(host, ResourceState.Event.AdminCancelMaintenance, _nodeId);
+            _agentMgr.pullAgentOutMaintenance(hostId);
+            retryHostMaintenance.remove(hostId);
+        } catch (final NoTransitionException e) {
+            s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
+            return false;
+        }
+
+        return true;
+
+    }
+
+    /**
+     * Handle agent (if available) if its not connected before cancelling maintenance.
+     * Agent must be connected before cancelling maintenance.
+     * If the host status is not Up:
+     * - If kvm.ssh.to.agent is true, then SSH into the host and restart the agent.
+     * - If kvm.shh.to.agent is false, then fail cancelling maintenance
+     */
+    protected void handleAgentIfNotConnected(HostVO host, boolean vmsMigrating) {
+        final boolean isAgentOnHost = host.getHypervisorType() == HypervisorType.KVM ||
+                host.getHypervisorType() == HypervisorType.LXC;
+        if (!isAgentOnHost || vmsMigrating || host.getStatus() == Status.Up) {
+            return;
+        }
+        final boolean sshToAgent = Boolean.parseBoolean(_configDao.getValue(KvmSshToAgentEnabled.key()));
+        if (sshToAgent) {
+            Pair<String, String> credentials = getHostCredentials(host);
+            connectAndRestartAgentOnHost(host, credentials.first(), credentials.second());
+        } else {
+            throw new CloudRuntimeException("SSH access is disabled, cannot cancel maintenance mode as " +
+                    "host agent is not connected");
+        }
+    }
+
+    /**
+     * Get host credentials
+     * @throws CloudRuntimeException if username or password are not found
+     */
+    protected Pair<String, String> getHostCredentials(HostVO host) {
+        _hostDao.loadDetails(host);
+        final String password = host.getDetail("password");
+        final String username = host.getDetail("username");
+        if (password == null || username == null) {
+            throw new CloudRuntimeException("SSH to agent is enabled, but username/password credentials are not found");
+        }
+        return new Pair<>(username, password);
+    }
+
+    /**
+     * True if agent is restarted via SSH. Assumes kvm.ssh.to.agent = true and host status is not Up
+     */
+    protected void connectAndRestartAgentOnHost(HostVO host, String username, String password) {
+        final com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(
+                host.getPrivateIpAddress(), 22, username, password);
+        if (connection == null) {
+            throw new CloudRuntimeException("SSH to agent is enabled, but failed to connect to host: " + host.getPrivateIpAddress());
+        }
+        try {
+            SSHCmdHelper.SSHCmdResult result = SSHCmdHelper.sshExecuteCmdOneShot(
+                    connection, "service cloudstack-agent restart");
+            if (result.getReturnCode() != 0) {
+                throw new CloudRuntimeException("Could not restart agent on host " + host.getId() + " due to: " + result.getStdErr());
+            }
+            s_logger.debug("cloudstack-agent restart result: " + result.toString());
+        } catch (final SshException e) {
+            throw new CloudRuntimeException("SSH to agent is enabled, but agent restart failed", e);
+        }
+    }
+
+    private boolean cancelMaintenance(final long hostId) {
+        try {
+            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.AdminCancelMaintenance);
+
+            if (result != null) {
+                return result;
+            }
+        } catch (final AgentUnavailableException e) {
+            return false;
+        }
+
+        return doCancelMaintenance(hostId);
+    }
+
+    @Override
+    public boolean executeUserRequest(final long hostId, final ResourceState.Event event) throws AgentUnavailableException {
+        if (event == ResourceState.Event.AdminAskMaintenace) {
+            return doMaintain(hostId);
+        } else if (event == ResourceState.Event.AdminCancelMaintenance) {
+            return doCancelMaintenance(hostId);
+        } else if (event == ResourceState.Event.DeleteHost) {
+            return doDeleteHost(hostId, false, false);
+        } else if (event == ResourceState.Event.Unmanaged) {
+            return doUmanageHost(hostId);
+        } else if (event == ResourceState.Event.UpdatePassword) {
+            return doUpdateHostPassword(hostId);
+        } else {
+            throw new CloudRuntimeException("Received an resource event we are not handling now, " + event);
+        }
+    }
+
+    private boolean doUmanageHost(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            s_logger.debug("Cannot find host " + hostId + ", assuming it has been deleted, skip umanage");
+            return true;
+        }
+
+        if (host.getHypervisorType() == HypervisorType.KVM || host.getHypervisorType() == HypervisorType.LXC) {
+            _agentMgr.easySend(hostId, new MaintainCommand());
+        }
+
+        _agentMgr.disconnectWithoutInvestigation(hostId, Event.ShutdownRequested);
+        return true;
+    }
+
+    @Override
+    public boolean umanageHost(final long hostId) {
+        try {
+            final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.Unmanaged);
+
+            if (result != null) {
+                return result;
+            }
+        } catch (final AgentUnavailableException e) {
+            return false;
+        }
+
+        return doUmanageHost(hostId);
+    }
+
+    private boolean doUpdateHostPassword(final long hostId) {
+        if (!_agentMgr.isAgentAttached(hostId)) {
+            return false;
+        }
+
+        DetailVO nv = _hostDetailsDao.findDetail(hostId, ApiConstants.USERNAME);
+        final String username = nv.getValue();
+        nv = _hostDetailsDao.findDetail(hostId, ApiConstants.PASSWORD);
+        final String password = nv.getValue();
+
+
+        final HostVO host = _hostDao.findById(hostId);
+        final String hostIpAddress = host.getPrivateIpAddress();
+
+        final UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(username, password, hostIpAddress);
+        final Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        s_logger.info("Result returned from update host password ==> " + answer.getDetails());
+        return answer.getResult();
+    }
+
+    @Override
+    public boolean updateClusterPassword(final UpdateHostPasswordCmd command) {
+        final boolean shouldUpdateHostPasswd = command.getUpdatePasswdOnHost();
+        // get agents for the cluster
+        final List<HostVO> hosts = listAllHostsInCluster(command.getClusterId());
+        for (final HostVO host : hosts) {
+            try {
+                final Boolean result = propagateResourceEvent(host.getId(), ResourceState.Event.UpdatePassword);
+                if (result != null) {
+                    return result;
+                }
+            } catch (final AgentUnavailableException e) {
+                s_logger.error("Agent is not availbale!", e);
+            }
+
+            if (shouldUpdateHostPasswd) {
+                final boolean isUpdated = doUpdateHostPassword(host.getId());
+                if (!isUpdated) {
+                    throw new CloudRuntimeException("CloudStack failed to update the password of the Host with UUID / ID ==> " + host.getUuid() + " / " + host.getId() + ". Please make sure you are still able to connect to your hosts.");
+                }
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean updateHostPassword(final UpdateHostPasswordCmd command) {
+        // update agent attache password
+        try {
+            final Boolean result = propagateResourceEvent(command.getHostId(), ResourceState.Event.UpdatePassword);
+            if (result != null) {
+                return result;
+            }
+        } catch (final AgentUnavailableException e) {
+            s_logger.error("Agent is not availbale!", e);
+        }
+
+        final boolean shouldUpdateHostPasswd = command.getUpdatePasswdOnHost();
+        // If shouldUpdateHostPasswd has been set to false, the method doUpdateHostPassword() won't be called.
+        return shouldUpdateHostPasswd && doUpdateHostPassword(command.getHostId());
+    }
+
+    public String getPeerName(final long agentHostId) {
+
+        final HostVO host = _hostDao.findById(agentHostId);
+        if (host != null && host.getManagementServerId() != null) {
+            if (_clusterMgr.getSelfPeerName().equals(Long.toString(host.getManagementServerId()))) {
+                return null;
+            }
+
+            return Long.toString(host.getManagementServerId());
+        }
+        return null;
+    }
+
+    public Boolean propagateResourceEvent(final long agentId, final ResourceState.Event event) throws AgentUnavailableException {
+        final String msPeer = getPeerName(agentId);
+        if (msPeer == null) {
+            return null;
+        }
+
+            s_logger.debug("Propagating resource request event:" + event.toString() + " to agent:" + agentId);
+        final Command[] cmds = new Command[1];
+        cmds[0] = new PropagateResourceEventCommand(agentId, event);
+
+        final String AnsStr = _clusterMgr.execute(msPeer, agentId, _gson.toJson(cmds), true);
+        if (AnsStr == null) {
+            throw new AgentUnavailableException(agentId);
+        }
+
+        final Answer[] answers = _gson.fromJson(AnsStr, Answer[].class);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Result for agent change is " + answers[0].getResult());
+        }
+
+        return answers[0].getResult();
+    }
+
+    @Override
+    public boolean maintenanceFailed(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Cant not find host " + hostId);
+            }
+            return false;
+        } else {
+            try {
+                return resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId);
+            } catch (final NoTransitionException e) {
+                s_logger.debug("No next resource state for host " + host.getId() + " while current state is " + host.getResourceState() + " with event " +
+                        ResourceState.Event.UnableToMigrate, e);
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public List<HostVO> findDirectlyConnectedHosts() {
+        /* The resource column is not null for direct connected resource */
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getResource(), Op.NNULL);
+        sc.and(sc.entity().getResourceState(), Op.NIN, ResourceState.Disabled);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (type != null) {
+            sc.and(sc.entity().getType(), Op.EQ, type);
+        }
+        if (clusterId != null) {
+            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
+        }
+        if (podId != null) {
+            sc.and(sc.entity().getPodId(), Op.EQ, podId);
+        }
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (type != null) {
+            sc.and(sc.entity().getType(), Op.EQ, type);
+        }
+        if (clusterId != null) {
+            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
+        }
+        if (podId != null) {
+            sc.and(sc.entity().getPodId(), Op.EQ, podId);
+        }
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllUpHosts(Type type, Long clusterId, Long podId, long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (type != null) {
+            sc.and(sc.entity().getType(), Op.EQ, type);
+        }
+        if (clusterId != null) {
+            sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
+        }
+        if (podId != null) {
+            sc.and(sc.entity().getPodId(), Op.EQ, podId);
+        }
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledNonHAHosts(final Type type, final Long clusterId, final Long podId, final long dcId) {
+        final String haTag = _haMgr.getHaTag();
+        return _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, haTag);
+    }
+
+    @Override
+    public List<HostVO> findHostByGuid(final long dcId, final String guid) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getGuid(), Op.EQ, guid);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllHostsInCluster(final long clusterId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listHostsInClusterByStatus(final long clusterId, final Status status) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getClusterId(), Op.EQ, clusterId);
+        sc.and(sc.entity().getStatus(), Op.EQ, status);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledHostsInOneZoneByType(final Type type, final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, type);
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllNotInMaintenanceHostsInOneZone(final Type type, final Long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (dcId != null) {
+            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        }
+        sc.and(sc.entity().getType(), Op.EQ, type);
+        sc.and(sc.entity().getResourceState(), Op.NIN, ResourceState.Maintenance, ResourceState.ErrorInMaintenance, ResourceState.PrepareForMaintenance,
+                ResourceState.Error);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllHostsInOneZoneByType(final Type type, final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, type);
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllHostsInAllZonesByType(final Type type) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, type);
+        return sc.list();
+    }
+
+    @Override
+    public List<HypervisorType> listAvailHypervisorInZone(final Long hostId, final Long zoneId) {
+        final SearchCriteria<String> sc = _hypervisorsInDC.create();
+        if (zoneId != null) {
+            sc.setParameters("dataCenter", zoneId);
+        }
+        if (hostId != null) {
+            // exclude the given host, since we want to check what hypervisor is already handled
+            // in adding this new host
+            sc.setParameters("id", hostId);
+        }
+        sc.setParameters("type", Host.Type.Routing);
+
+        // The search is not able to return list of enums, so getting
+        // list of hypervisors as strings and then converting them to enum
+        final List<String> hvs = _hostDao.customSearch(sc, null);
+        final List<HypervisorType> hypervisors = new ArrayList<HypervisorType>();
+        for (final String hv : hvs) {
+            hypervisors.add(HypervisorType.getType(hv));
+        }
+        return hypervisors;
+    }
+
+    @Override
+    public HostVO findHostByGuid(final String guid) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getGuid(), Op.EQ, guid);
+        return sc.find();
+    }
+
+    @Override
+    public HostVO findHostByName(final String name) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getName(), Op.EQ, name);
+        return sc.find();
+    }
+
+    @Override
+    public HostStats getHostStatistics(final long hostId) {
+        final Answer answer = _agentMgr.easySend(hostId, new GetHostStatsCommand(_hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId).getName(), hostId));
+
+        if (answer != null && answer instanceof UnsupportedAnswer) {
+            return null;
+        }
+
+        if (answer == null || !answer.getResult()) {
+            final String msg = "Unable to obtain host " + hostId + " statistics. ";
+            s_logger.warn(msg);
+            return null;
+        } else {
+
+            // now construct the result object
+            if (answer instanceof GetHostStatsAnswer) {
+                return ((GetHostStatsAnswer)answer).getHostStats();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Long getGuestOSCategoryId(final long hostId) {
+        final HostVO host = _hostDao.findById(hostId);
+        if (host == null) {
+            return null;
+        } else {
+            _hostDao.loadDetails(host);
+            final DetailVO detail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id");
+            if (detail == null) {
+                return null;
+            } else {
+                return Long.parseLong(detail.getValue());
+            }
+        }
+    }
+
+    @Override
+    public String getHostTags(final long hostId) {
+        final List<String> hostTags = _hostTagsDao.gethostTags(hostId);
+        if (hostTags == null) {
+            return null;
+        } else {
+            return StringUtils.listToCsvTags(hostTags);
+        }
+    }
+
+    @Override
+    public List<PodCluster> listByDataCenter(final long dcId) {
+        final List<HostPodVO> pods = _podDao.listByDataCenterId(dcId);
+        final ArrayList<PodCluster> pcs = new ArrayList<PodCluster>();
+        for (final HostPodVO pod : pods) {
+            final List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
+            if (clusters.size() == 0) {
+                pcs.add(new PodCluster(pod, null));
+            } else {
+                for (final ClusterVO cluster : clusters) {
+                    pcs.add(new PodCluster(pod, cluster));
+                }
+            }
+        }
+        return pcs;
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledHostsInOneZoneByHypervisor(final HypervisorType type, final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getHypervisorType(), Op.EQ, type);
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
+        return sc.list();
+    }
+
+    @Override
+    public List<HostVO> listAllUpAndEnabledHostsInOneZone(final long dcId) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+
+        sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
+
+        return sc.list();
+    }
+
+    @Override
+    public boolean isHostGpuEnabled(final long hostId) {
+        final SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
+        sc.setParameters("hostId", hostId);
+        return _hostGpuGroupsDao.customSearch(sc, null).size() > 0 ? true : false;
+    }
+
+    @Override
+    public List<HostGpuGroupsVO> listAvailableGPUDevice(final long hostId, final String groupName, final String vgpuType) {
+        final Filter searchFilter = new Filter(VGPUTypesVO.class, "remainingCapacity", false, null, null);
+        final SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
+        sc.setParameters("hostId", hostId);
+        sc.setParameters("groupName", groupName);
+        sc.setJoinParameters("groupId", "vgpuType", vgpuType);
+        sc.setJoinParameters("groupId", "remainingCapacity", 0);
+        return _hostGpuGroupsDao.customSearch(sc, searchFilter);
+    }
+
+    @Override
+    public boolean isGPUDeviceAvailable(final long hostId, final String groupName, final String vgpuType) {
+        if(!listAvailableGPUDevice(hostId, groupName, vgpuType).isEmpty()) {
+            return true;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host ID: "+ hostId +" does not have GPU device available");
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public GPUDeviceTO getGPUDevice(final long hostId, final String groupName, final String vgpuType) {
+        final List<HostGpuGroupsVO> gpuDeviceList = listAvailableGPUDevice(hostId, groupName, vgpuType);
+
+        if (CollectionUtils.isEmpty(gpuDeviceList)) {
+            final String errorMsg = "Host " + hostId + " does not have required GPU device or out of capacity. GPU group: " + groupName + ", vGPU Type: " + vgpuType;
+            s_logger.error(errorMsg);
+            throw new CloudRuntimeException(errorMsg);
+        }
+
+        return new GPUDeviceTO(gpuDeviceList.get(0).getGroupName(), vgpuType, null);
+    }
+
+    @Override
+    public void updateGPUDetails(final long hostId, final HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails) {
+        // Update GPU group capacity
+        final TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        _hostGpuGroupsDao.persist(hostId, new ArrayList<String>(groupDetails.keySet()));
+        _vgpuTypesDao.persist(hostId, groupDetails);
+        txn.commit();
+    }
+
+    @Override
+    public HashMap<String, HashMap<String, VgpuTypesInfo>> getGPUStatistics(final HostVO host) {
+        final Answer answer = _agentMgr.easySend(host.getId(), new GetGPUStatsCommand(host.getGuid(), host.getName()));
+        if (answer != null && answer instanceof UnsupportedAnswer) {
+            return null;
+        }
+        if (answer == null || !answer.getResult()) {
+            final String msg = "Unable to obtain GPU stats for host " + host.getName();
+            s_logger.warn(msg);
+            return null;
+        } else {
+            // now construct the result object
+            if (answer instanceof GetGPUStatsAnswer) {
+                return ((GetGPUStatsAnswer)answer).getGroupDetails();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public HostVO findOneRandomRunningHostByHypervisor(HypervisorType type) {
+        final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getHypervisorType(), Op.EQ, type);
+        sc.and(sc.entity().getType(),Op.EQ, Type.Routing);
+        sc.and(sc.entity().getStatus(), Op.EQ, Status.Up);
+        sc.and(sc.entity().getResourceState(), Op.EQ, ResourceState.Enabled);
+        sc.and(sc.entity().getRemoved(), Op.NULL);
+        List<HostVO> hosts = sc.list();
+        if (CollectionUtils.isEmpty(hosts)) {
+            return null;
+        } else {
+            Collections.shuffle(hosts, new Random(System.currentTimeMillis()));
+            return hosts.get(0);
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
+    public boolean releaseHostReservation(final Long hostId) {
+        try {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(final TransactionStatus status) {
+                    final PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
+                    if (reservationEntry != null) {
+                        final long id = reservationEntry.getId();
+                        final PlannerHostReservationVO hostReservation = _plannerHostReserveDao.lockRow(id, true);
+                        if (hostReservation == null) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
+                            }
+                            return false;
+                        }
+                        hostReservation.setResourceUsage(null);
+                        _plannerHostReserveDao.persist(hostReservation);
+                        return true;
+                    }
+
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Host reservation for host: " + hostId + " does not even exist.  Release reservartion call is ignored.");
+                    }
+
+                    return false;
+                }
+            });
+        } catch (final CloudRuntimeException e) {
+            throw e;
+        } catch (final Throwable t) {
+            s_logger.error("Unable to release host reservation for host: " + hostId, t);
+            return false;
+        }
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ResourceManagerImpl.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {HostMaintenanceRetries};
+    }
+}
diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
new file mode 100644
index 0000000..417ccfc
--- /dev/null
+++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -0,0 +1,1074 @@
+// 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.resourcelimit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.ResourceCount;
+import com.cloud.configuration.ResourceCountVO;
+import com.cloud.configuration.ResourceLimitVO;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.configuration.dao.ResourceLimitDao;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectAccount.Role;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.VolumeDaoImpl.SumCount;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable {
+    public static final Logger s_logger = Logger.getLogger(ResourceLimitManagerImpl.class);
+
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    private ResourceCountDao _resourceCountDao;
+    @Inject
+    private ResourceLimitDao _resourceLimitDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    @Inject
+    protected VMTemplateDao _vmTemplateDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private IPAddressDao _ipAddressDao;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private ProjectDao _projectDao;
+    @Inject
+    private ProjectAccountDao _projectAccountDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private VpcDao _vpcDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private TemplateDataStoreDao _vmTemplateStoreDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private SnapshotDataStoreDao _snapshotDataStoreDao;
+
+    protected GenericSearchBuilder<TemplateDataStoreVO, SumCount> templateSizeSearch;
+    protected GenericSearchBuilder<SnapshotDataStoreVO, SumCount> snapshotSizeSearch;
+
+    protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
+    ScheduledExecutorService _rcExecutor;
+    long _resourceCountCheckInterval = 0;
+    Map<ResourceType, Long> accountResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
+    Map<ResourceType, Long> domainResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
+    Map<ResourceType, Long> projectResourceLimitMap = new EnumMap<ResourceType, Long>(ResourceType.class);
+
+    @Override
+    public boolean start() {
+        if (_resourceCountCheckInterval > 0) {
+            _rcExecutor.scheduleAtFixedRate(new ResourceCountCheckTask(), _resourceCountCheckInterval, _resourceCountCheckInterval, TimeUnit.SECONDS);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+
+        ResourceCountSearch = _resourceCountDao.createSearchBuilder();
+        ResourceCountSearch.and("id", ResourceCountSearch.entity().getId(), SearchCriteria.Op.IN);
+        ResourceCountSearch.and("accountId", ResourceCountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+        ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
+        ResourceCountSearch.done();
+
+        templateSizeSearch = _vmTemplateStoreDao.createSearchBuilder(SumCount.class);
+        templateSizeSearch.select("sum", Func.SUM, templateSizeSearch.entity().getSize());
+        templateSizeSearch.and("downloadState", templateSizeSearch.entity().getDownloadState(), Op.EQ);
+        templateSizeSearch.and("destroyed", templateSizeSearch.entity().getDestroyed(), Op.EQ);
+        SearchBuilder<VMTemplateVO> join1 = _vmTemplateDao.createSearchBuilder();
+        join1.and("accountId", join1.entity().getAccountId(), Op.EQ);
+        templateSizeSearch.join("templates", join1, templateSizeSearch.entity().getTemplateId(), join1.entity().getId(), JoinBuilder.JoinType.INNER);
+        templateSizeSearch.done();
+
+        snapshotSizeSearch = _snapshotDataStoreDao.createSearchBuilder(SumCount.class);
+        snapshotSizeSearch.select("sum", Func.SUM, snapshotSizeSearch.entity().getPhysicalSize());
+        snapshotSizeSearch.and("state", snapshotSizeSearch.entity().getState(), Op.EQ);
+        snapshotSizeSearch.and("storeRole", snapshotSizeSearch.entity().getRole(), Op.EQ);
+        SearchBuilder<SnapshotVO> join2 = _snapshotDao.createSearchBuilder();
+        join2.and("accountId", join2.entity().getAccountId(), Op.EQ);
+        snapshotSizeSearch.join("snapshots", join2, snapshotSizeSearch.entity().getSnapshotId(), join2.entity().getId(), JoinBuilder.JoinType.INNER);
+        snapshotSizeSearch.done();
+
+        _resourceCountCheckInterval = ResourceCountCheckInterval.value();
+        if (_resourceCountCheckInterval > 0) {
+            _rcExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ResourceCountChecker"));
+        }
+
+        try {
+            projectResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPublicIPs.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSnapshots.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectTemplates.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectUserVms.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectNetworks.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVpcs.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectCpus.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectMemory.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPrimaryStorage.key())));
+            projectResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSecondaryStorage.key())));
+
+            accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountNetworks.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVpcs.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountCpus.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPrimaryStorage.key())));
+            accountResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key())));
+
+            domainResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPublicIPs.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSnapshots.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainTemplates.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainUserVms.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVolumes.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainNetworks.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainVpcs.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainCpus.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainMemory.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPrimaryStorage.key())));
+            domainResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSecondaryStorage.key())));
+        } catch (NumberFormatException e) {
+            s_logger.error("NumberFormatException during configuration", e);
+            throw new ConfigurationException("Configuration failed due to NumberFormatException, see log for the stacktrace");
+        }
+
+        return true;
+    }
+
+    @Override
+    public void incrementResourceCount(long accountId, ResourceType type, Long... delta) {
+        // don't upgrade resource count for system account
+        if (accountId == Account.ACCOUNT_ID_SYSTEM) {
+            s_logger.trace("Not incrementing resource count for system accounts, returning");
+            return;
+        }
+
+        long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue();
+
+        if (!updateResourceCountForAccount(accountId, type, true, numToIncrement)) {
+            // we should fail the operation (resource creation) when failed to update the resource count
+            throw new CloudRuntimeException("Failed to increment resource count of type " + type + " for account id=" + accountId);
+        }
+    }
+
+    @Override
+    public void decrementResourceCount(long accountId, ResourceType type, Long... delta) {
+        // don't upgrade resource count for system account
+        if (accountId == Account.ACCOUNT_ID_SYSTEM) {
+            s_logger.trace("Not decrementing resource count for system accounts, returning");
+            return;
+        }
+        long numToDecrement = (delta.length == 0) ? 1 : delta[0].longValue();
+
+        if (!updateResourceCountForAccount(accountId, type, false, numToDecrement)) {
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, "Failed to decrement resource count of type " + type + " for account id=" + accountId,
+                    "Failed to decrement resource count of type " + type + " for account id=" + accountId + "; use updateResourceCount API to recalculate/fix the problem");
+        }
+    }
+
+    @Override
+    public long findCorrectResourceLimitForAccount(Account account, ResourceType type) {
+
+        long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited
+
+        // No limits for Root Admin accounts
+        if (_accountMgr.isRootAdmin(account.getId())) {
+            return max;
+        }
+
+        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(account.getId(), ResourceOwnerType.Account, type);
+
+        // Check if limit is configured for account
+        if (limit != null) {
+            max = limit.getMax().longValue();
+        } else {
+            // If the account has an no limit set, then return global default account limits
+            Long value = null;
+            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                value = projectResourceLimitMap.get(type);
+            } else {
+                value = accountResourceLimitMap.get(type);
+            }
+            if (value != null) {
+                if (value < 0) { // return unlimit if value is set to negative
+                    return max;
+                }
+                // convert the value from GiB to bytes in case of primary or secondary storage.
+                if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
+                    value = value * ResourceType.bytesToGiB;
+                }
+                return value;
+            }
+        }
+
+        return max;
+    }
+
+    @Override
+    public long findCorrectResourceLimitForAccount(long accountId, Long limit, ResourceType type) {
+
+        long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited
+
+        // No limits for Root Admin accounts
+        if (_accountMgr.isRootAdmin(accountId)) {
+            return max;
+        }
+
+        Account account = _accountDao.findById(accountId);
+        if (account == null) {
+            return max;
+        }
+
+        // Check if limit is configured for account
+        if (limit != null) {
+            max = limit.longValue();
+        } else {
+            // If the account has an no limit set, then return global default account limits
+            Long value = null;
+            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                value = projectResourceLimitMap.get(type);
+            } else {
+                value = accountResourceLimitMap.get(type);
+            }
+            if (value != null) {
+                if (value < 0) { // return unlimit if value is set to negative
+                    return max;
+                }
+                if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
+                    value = value * ResourceType.bytesToGiB;
+                }
+                return value;
+            }
+        }
+
+        return max;
+    }
+
+    @Override
+    public long findCorrectResourceLimitForDomain(Domain domain, ResourceType type) {
+        long max = Resource.RESOURCE_UNLIMITED;
+
+        // no limits on ROOT domain
+        if (domain.getId() == Domain.ROOT_DOMAIN) {
+            return Resource.RESOURCE_UNLIMITED;
+        }
+        // Check account
+        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(domain.getId(), ResourceOwnerType.Domain, type);
+
+        if (limit != null) {
+            max = limit.getMax().longValue();
+        } else {
+            // check domain hierarchy
+            Long domainId = domain.getParent();
+            while ((domainId != null) && (limit == null)) {
+                if (domainId == Domain.ROOT_DOMAIN) {
+                    break;
+                }
+                limit = _resourceLimitDao.findByOwnerIdAndType(domainId, ResourceOwnerType.Domain, type);
+                DomainVO tmpDomain = _domainDao.findById(domainId);
+                domainId = tmpDomain.getParent();
+            }
+
+            if (limit != null) {
+                max = limit.getMax().longValue();
+            } else {
+                Long value = null;
+                value = domainResourceLimitMap.get(type);
+                if (value != null) {
+                    if (value < 0) { // return unlimit if value is set to negative
+                        return max;
+                    }
+                    if (type == ResourceType.primary_storage || type == ResourceType.secondary_storage) {
+                        value = value * ResourceType.bytesToGiB;
+                    }
+                    return value;
+                }
+            }
+        }
+
+        return max;
+    }
+
+    private void checkDomainResourceLimit(final Account account, final Project project, final ResourceType type, long numResources) throws ResourceAllocationException {
+        // check all domains in the account's domain hierarchy
+        Long domainId = null;
+        if (project != null) {
+            domainId = project.getDomainId();
+        } else {
+            domainId = account.getDomainId();
+        }
+
+        while (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            // no limit check if it is ROOT domain
+            if (domainId != Domain.ROOT_DOMAIN) {
+                long domainResourceLimit = findCorrectResourceLimitForDomain(domain, type);
+                long currentDomainResourceCount = _resourceCountDao.getResourceCount(domainId, ResourceOwnerType.Domain, type);
+                long requestedDomainResourceCount = currentDomainResourceCount + numResources;
+                String messageSuffix = " domain resource limits of Type '" + type + "'" + " for Domain Id = " + domainId + " is exceeded: Domain Resource Limit = " + domainResourceLimit
+                        + ", Current Domain Resource Amount = " + currentDomainResourceCount + ", Requested Resource Amount = " + numResources + ".";
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Checking if" + messageSuffix);
+                }
+
+                if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
+                    String message = "Maximum" + messageSuffix;
+                    ResourceAllocationException e = new ResourceAllocationException(message, type);
+                    s_logger.error(message, e);
+                    throw e;
+                }
+            }
+            domainId = domain.getParent();
+        }
+    }
+
+    private void checkAccountResourceLimit(final Account account, final Project project, final ResourceType type, long numResources) throws ResourceAllocationException {
+        // Check account limits
+        long accountResourceLimit = findCorrectResourceLimitForAccount(account, type);
+        long currentResourceCount = _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);
+        long requestedResourceCount = currentResourceCount + numResources;
+        String messageSuffix = " amount of resources of Type = '" + type + "' for " + (project == null ? "Account Name = " + account.getAccountName() : "Project Name = " + project.getName())
+                + " in Domain Id = " + account.getDomainId() + " is exceeded: Account Resource Limit = " + accountResourceLimit + ", Current Account Resource Amount = " + currentResourceCount
+                + ", Requested Resource Amount = " + numResources + ".";
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking if" + messageSuffix);
+        }
+
+        if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
+            String message = "Maximum" + messageSuffix;
+            ResourceAllocationException e = new ResourceAllocationException(message, type);
+            s_logger.error(message, e);
+            throw e;
+        }
+    }
+
+    private List<ResourceCountVO> lockAccountAndOwnerDomainRows(long accountId, final ResourceType type) {
+        Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type);
+        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+        sc.setParameters("id", rowIdsToLock.toArray());
+        return _resourceCountDao.lockRows(sc, null, true);
+    }
+
+    private List<ResourceCountVO> lockDomainRows(long domainId, final ResourceType type) {
+        Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(domainId, ResourceOwnerType.Domain, type);
+        SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();
+        sc.setParameters("id", rowIdsToLock.toArray());
+        return _resourceCountDao.lockRows(sc, null, true);
+    }
+
+    @Override
+    public long findDefaultResourceLimitForDomain(ResourceType resourceType) {
+        Long resourceLimit = null;
+        resourceLimit = domainResourceLimitMap.get(resourceType);
+        if (resourceLimit != null && (resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage)) {
+            resourceLimit = resourceLimit * ResourceType.bytesToGiB;
+        } else {
+            resourceLimit = Long.valueOf(Resource.RESOURCE_UNLIMITED);
+        }
+        return resourceLimit;
+    }
+
+    @Override
+    @DB
+    public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {
+        final long numResources = ((count.length == 0) ? 1 : count[0]);
+        Project project = null;
+
+        // Don't place any limits on system or root admin accounts
+        if (_accountMgr.isRootAdmin(account.getId())) {
+            return;
+        }
+
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            project = _projectDao.findByProjectAccountId(account.getId());
+        }
+
+        final Project projectFinal = project;
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
+                // Lock all rows first so nobody else can read it
+                lockAccountAndOwnerDomainRows(account.getId(), type);
+                // Check account limits
+                checkAccountResourceLimit(account, projectFinal, type, numResources);
+                // check all domains in the account's domain hierarchy
+                checkDomainResourceLimit(account, projectFinal, type, numResources);
+            }
+        });
+    }
+
+    @Override
+    public List<ResourceLimitVO> searchForLimits(Long id, Long accountId, Long domainId, ResourceType resourceType, Long startIndex, Long pageSizeVal) {
+        Account caller = CallContext.current().getCallingAccount();
+        List<ResourceLimitVO> limits = new ArrayList<ResourceLimitVO>();
+        boolean isAccount = true;
+
+        if (!_accountMgr.isAdmin(caller.getId())) {
+            accountId = caller.getId();
+            domainId = null;
+        } else {
+            if (domainId != null) {
+                // verify domain information and permissions
+                Domain domain = _domainDao.findById(domainId);
+                if (domain == null) {
+                    // return empty set
+                    return limits;
+                }
+
+                _accountMgr.checkAccess(caller, domain);
+
+                if (accountId != null) {
+                    // Verify account information and permissions
+                    Account account = _accountDao.findById(accountId);
+                    if (account == null) {
+                        // return empty set
+                        return limits;
+                    }
+
+                    _accountMgr.checkAccess(caller, null, true, account);
+                    domainId = null;
+                }
+            }
+        }
+
+        // If id is passed in, get the record and return it if permission check has passed
+        if (id != null) {
+            ResourceLimitVO vo = _resourceLimitDao.findById(id);
+            if (vo.getAccountId() != null) {
+                _accountMgr.checkAccess(caller, null, true, _accountDao.findById(vo.getAccountId()));
+                limits.add(vo);
+            } else if (vo.getDomainId() != null) {
+                _accountMgr.checkAccess(caller, _domainDao.findById(vo.getDomainId()));
+                limits.add(vo);
+            }
+
+            return limits;
+        }
+
+        // If account is not specified, default it to caller account
+        if (accountId == null) {
+            if (domainId == null) {
+                accountId = caller.getId();
+                isAccount = true;
+            } else {
+                isAccount = false;
+            }
+        } else {
+            isAccount = true;
+        }
+
+        SearchBuilder<ResourceLimitVO> sb = _resourceLimitDao.createSearchBuilder();
+        sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
+
+        SearchCriteria<ResourceLimitVO> sc = sb.create();
+        Filter filter = new Filter(ResourceLimitVO.class, "id", true, startIndex, pageSizeVal);
+
+        if (accountId != null) {
+            sc.setParameters("accountId", accountId);
+        }
+
+        if (domainId != null) {
+            sc.setParameters("domainId", domainId);
+            sc.setParameters("accountId", (Object[])null);
+        }
+
+        if (resourceType != null) {
+            sc.setParameters("type", resourceType);
+        }
+
+        List<ResourceLimitVO> foundLimits = _resourceLimitDao.search(sc, filter);
+
+        if (resourceType != null) {
+            if (foundLimits.isEmpty()) {
+                if (isAccount) {
+                    limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForAccount(_accountMgr.getAccount(accountId), resourceType), accountId, ResourceOwnerType.Account));
+                } else {
+                    limits.add(new ResourceLimitVO(resourceType, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), resourceType), domainId, ResourceOwnerType.Domain));
+                }
+            } else {
+                limits.addAll(foundLimits);
+            }
+        } else {
+            limits.addAll(foundLimits);
+
+            // see if any limits are missing from the table, and if yes - get it from the config table and add
+            ResourceType[] resourceTypes = ResourceCount.ResourceType.values();
+            if (foundLimits.size() != resourceTypes.length) {
+                List<String> accountLimitStr = new ArrayList<String>();
+                List<String> domainLimitStr = new ArrayList<String>();
+                for (ResourceLimitVO foundLimit : foundLimits) {
+                    if (foundLimit.getAccountId() != null) {
+                        accountLimitStr.add(foundLimit.getType().toString());
+                    } else {
+                        domainLimitStr.add(foundLimit.getType().toString());
+                    }
+                }
+
+                // get default from config values
+                if (isAccount) {
+                    if (accountLimitStr.size() < resourceTypes.length) {
+                        for (ResourceType rt : resourceTypes) {
+                            if (!accountLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Account)) {
+                                limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForAccount(_accountMgr.getAccount(accountId), rt), accountId, ResourceOwnerType.Account));
+                            }
+                        }
+                    }
+
+                } else {
+                    if (domainLimitStr.size() < resourceTypes.length) {
+                        for (ResourceType rt : resourceTypes) {
+                            if (!domainLimitStr.contains(rt.toString()) && rt.supportsOwner(ResourceOwnerType.Domain)) {
+                                limits.add(new ResourceLimitVO(rt, findCorrectResourceLimitForDomain(_domainDao.findById(domainId), rt), domainId, ResourceOwnerType.Domain));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return limits;
+    }
+
+    @Override
+    public ResourceLimitVO updateResourceLimit(Long accountId, Long domainId, Integer typeId, Long max) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        if (max == null) {
+            max = new Long(Resource.RESOURCE_UNLIMITED);
+        } else if (max.longValue() < Resource.RESOURCE_UNLIMITED) {
+            throw new InvalidParameterValueException("Please specify either '-1' for an infinite limit, or a limit that is at least '0'.");
+        }
+
+        // Map resource type
+        ResourceType resourceType = null;
+        if (typeId != null) {
+            for (ResourceType type : Resource.ResourceType.values()) {
+                if (type.getOrdinal() == typeId.intValue()) {
+                    resourceType = type;
+                }
+            }
+            if (resourceType == null) {
+                throw new InvalidParameterValueException("Please specify valid resource type");
+            }
+        }
+
+        //Convert max storage size from GiB to bytes
+        if ((resourceType == ResourceType.primary_storage || resourceType == ResourceType.secondary_storage) && max >= 0) {
+            max *= ResourceType.bytesToGiB;
+        }
+
+        ResourceOwnerType ownerType = null;
+        Long ownerId = null;
+
+        if (accountId != null) {
+            Account account = _entityMgr.findById(Account.class, accountId);
+            if (account == null) {
+                throw new InvalidParameterValueException("Unable to find account " + accountId);
+            }
+            if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+                throw new InvalidParameterValueException("Can't update system account");
+            }
+
+            //only Unlimited value is accepted if account is  Root Admin
+            if (_accountMgr.isRootAdmin(account.getId()) && max.shortValue() != Resource.RESOURCE_UNLIMITED) {
+                throw new InvalidParameterValueException("Only " + Resource.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts");
+            }
+
+            if ((caller.getAccountId() == accountId.longValue()) && (_accountMgr.isDomainAdmin(caller.getId()) || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) {
+                // If the admin is trying to update his own account, disallow.
+                throw new PermissionDeniedException("Unable to update resource limit for his own account " + accountId + ", permission denied");
+            }
+
+            if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, account);
+            } else {
+                _accountMgr.checkAccess(caller, null, true, account);
+            }
+
+            ownerType = ResourceOwnerType.Account;
+            ownerId = accountId;
+        } else if (domainId != null) {
+            Domain domain = _entityMgr.findById(Domain.class, domainId);
+
+            _accountMgr.checkAccess(caller, domain);
+
+            if (Domain.ROOT_DOMAIN == domainId.longValue()) {
+                // no one can add limits on ROOT domain, disallow...
+                throw new PermissionDeniedException("Cannot update resource limit for ROOT domain " + domainId + ", permission denied");
+            }
+
+            if ((caller.getDomainId() == domainId.longValue()) && caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                // if the admin is trying to update their own domain, disallow...
+                throw new PermissionDeniedException("Unable to update resource limit for domain " + domainId + ", permission denied");
+            }
+            Long parentDomainId = domain.getParent();
+            if (parentDomainId != null) {
+                DomainVO parentDomain = _domainDao.findById(parentDomainId);
+                long parentMaximum = findCorrectResourceLimitForDomain(parentDomain, resourceType);
+                if ((parentMaximum >= 0) && (max.longValue() > parentMaximum)) {
+                    throw new InvalidParameterValueException("Domain " + domain.getName() + "(id: " + parentDomain.getId() + ") has maximum allowed resource limit " + parentMaximum + " for "
+                            + resourceType + ", please specify a value less that or equal to " + parentMaximum);
+                }
+            }
+            ownerType = ResourceOwnerType.Domain;
+            ownerId = domainId;
+        }
+
+        if (ownerId == null) {
+            throw new InvalidParameterValueException("AccountId or domainId have to be specified in order to update resource limit");
+        }
+
+        ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(ownerId, ownerType, resourceType);
+        if (limit != null) {
+            // Update the existing limit
+            _resourceLimitDao.update(limit.getId(), max);
+            return _resourceLimitDao.findById(limit.getId());
+        } else {
+            return _resourceLimitDao.persist(new ResourceLimitVO(resourceType, max, ownerId, ownerType));
+        }
+    }
+
+    @Override
+    public List<ResourceCountVO> recalculateResourceCount(Long accountId, Long domainId, Integer typeId) throws InvalidParameterValueException, CloudRuntimeException, PermissionDeniedException {
+        Account callerAccount = CallContext.current().getCallingAccount();
+        long count = 0;
+        List<ResourceCountVO> counts = new ArrayList<ResourceCountVO>();
+        List<ResourceType> resourceTypes = new ArrayList<ResourceType>();
+
+        ResourceType resourceType = null;
+
+        if (typeId != null) {
+            for (ResourceType type : Resource.ResourceType.values()) {
+                if (type.getOrdinal() == typeId.intValue()) {
+                    resourceType = type;
+                }
+            }
+            if (resourceType == null) {
+                throw new InvalidParameterValueException("Please specify valid resource type");
+            }
+        }
+
+        DomainVO domain = _domainDao.findById(domainId);
+        if (domain == null) {
+            throw new InvalidParameterValueException("Please specify a valid domain ID.");
+        }
+        _accountMgr.checkAccess(callerAccount, domain);
+
+        if (resourceType != null) {
+            resourceTypes.add(resourceType);
+        } else {
+            resourceTypes = Arrays.asList(Resource.ResourceType.values());
+        }
+
+        for (ResourceType type : resourceTypes) {
+            if (accountId != null) {
+                if (type.supportsOwner(ResourceOwnerType.Account)) {
+                    count = recalculateAccountResourceCount(accountId, type);
+                    counts.add(new ResourceCountVO(type, count, accountId, ResourceOwnerType.Account));
+                }
+
+            } else {
+                if (type.supportsOwner(ResourceOwnerType.Domain)) {
+                    count = recalculateDomainResourceCount(domainId, type);
+                    counts.add(new ResourceCountVO(type, count, domainId, ResourceOwnerType.Domain));
+                }
+            }
+        }
+
+        return counts;
+    }
+
+    @DB
+    protected boolean updateResourceCountForAccount(final long accountId, final ResourceType type, final boolean increment, final long delta) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Updating resource Type = " + type + " count for Account = " + accountId + " Operation = " + (increment ? "increasing" : "decreasing") + " Amount = " + delta);
+        }
+        try {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    boolean result = true;
+                    List<ResourceCountVO> rowsToUpdate = lockAccountAndOwnerDomainRows(accountId, type);
+                    for (ResourceCountVO rowToUpdate : rowsToUpdate) {
+                        if (!_resourceCountDao.updateById(rowToUpdate.getId(), increment, delta)) {
+                            s_logger.trace("Unable to update resource count for the row " + rowToUpdate);
+                            result = false;
+                        }
+                    }
+                    return result;
+                }
+            });
+        } catch (Exception ex) {
+            s_logger.error("Failed to update resource count for account id=" + accountId);
+            return false;
+        }
+    }
+
+    @DB
+    protected long recalculateDomainResourceCount(final long domainId, final ResourceType type) {
+        return Transaction.execute(new TransactionCallback<Long>() {
+            @Override
+            public Long doInTransaction(TransactionStatus status) {
+                long newResourceCount = 0;
+                lockDomainRows(domainId, type);
+                ResourceCountVO domainRC = _resourceCountDao.findByOwnerAndType(domainId, ResourceOwnerType.Domain, type);
+                long oldResourceCount = domainRC.getCount();
+
+                List<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domainId);
+                // for each child domain update the resource count
+                if (type.supportsOwner(ResourceOwnerType.Domain)) {
+
+                    // calculate project count here
+                    if (type == ResourceType.project) {
+                        newResourceCount += _projectDao.countProjectsForDomain(domainId);
+                    }
+
+                    for (DomainVO childDomain : domainChildren) {
+                        long childDomainResourceCount = recalculateDomainResourceCount(childDomain.getId(), type);
+                        newResourceCount += childDomainResourceCount; // add the child domain count to parent domain count
+                    }
+                }
+
+                if (type.supportsOwner(ResourceOwnerType.Account)) {
+                    List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domainId);
+                    for (AccountVO account : accounts) {
+                        long accountResourceCount = recalculateAccountResourceCount(account.getId(), type);
+                        newResourceCount += accountResourceCount; // add account's resource count to parent domain count
+                    }
+                }
+                _resourceCountDao.setResourceCount(domainId, ResourceOwnerType.Domain, type, newResourceCount);
+
+                if (oldResourceCount != newResourceCount) {
+                    s_logger.warn("Discrepency in the resource count has been detected " + "(original count = " + oldResourceCount + " correct count = " + newResourceCount + ") for Type = " + type
+                            + " for Domain ID = " + domainId + " is fixed during resource count recalculation.");
+                }
+
+                return newResourceCount;
+            }
+        });
+    }
+
+    @DB
+    protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
+        final Long newCount;
+        if (type == Resource.ResourceType.user_vm) {
+            newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
+        } else if (type == Resource.ResourceType.volume) {
+            long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
+            newCount = _volumeDao.countAllocatedVolumesForAccount(accountId) - virtualRouterCount; // don't count the volumes of virtual router
+        } else if (type == Resource.ResourceType.snapshot) {
+            newCount = _snapshotDao.countSnapshotsForAccount(accountId);
+        } else if (type == Resource.ResourceType.public_ip) {
+            newCount = calculatePublicIpForAccount(accountId);
+        } else if (type == Resource.ResourceType.template) {
+            newCount = _vmTemplateDao.countTemplatesForAccount(accountId);
+        } else if (type == Resource.ResourceType.project) {
+            newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
+        } else if (type == Resource.ResourceType.network) {
+            newCount = _networkDao.countNetworksUserCanCreate(accountId);
+        } else if (type == Resource.ResourceType.vpc) {
+            newCount = _vpcDao.countByAccountId(accountId);
+        } else if (type == Resource.ResourceType.cpu) {
+            newCount = countCpusForAccount(accountId);
+        } else if (type == Resource.ResourceType.memory) {
+            newCount = calculateMemoryForAccount(accountId);
+        } else if (type == Resource.ResourceType.primary_storage) {
+            List<Long> virtualRouters = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId);
+            newCount = _volumeDao.primaryStorageUsedForAccount(accountId, virtualRouters);
+        } else if (type == Resource.ResourceType.secondary_storage) {
+            newCount = calculateSecondaryStorageForAccount(accountId);
+        } else {
+            throw new InvalidParameterValueException("Unsupported resource type " + type);
+        }
+
+        long oldCount = 0;
+        final ResourceCountVO accountRC = _resourceCountDao.findByOwnerAndType(accountId, ResourceOwnerType.Account, type);
+        if (accountRC != null) {
+            oldCount = accountRC.getCount();
+        }
+
+        if (newCount == null || !newCount.equals(oldCount)) {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    lockAccountAndOwnerDomainRows(accountId, type);
+                    _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount);
+                }
+            });
+        }
+
+        // No need to log message for primary and secondary storage because both are recalculating the
+        // resource count which will not lead to any discrepancy.
+        if (newCount != null && !newCount.equals(oldCount) &&
+                type != Resource.ResourceType.primary_storage && type != Resource.ResourceType.secondary_storage) {
+            s_logger.warn("Discrepancy in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type +
+                    " for account ID " + accountId + " is fixed during resource count recalculation.");
+        }
+
+        return (newCount == null) ? 0 : newCount;
+    }
+
+    public long countCpusForAccount(long accountId) {
+        return _resourceCountDao.countCpuNumberAllocatedToAccount(accountId);
+    }
+
+    public long calculateMemoryForAccount(long accountId) {
+        return _resourceCountDao.countMemoryAllocatedToAccount(accountId);
+    }
+
+    public long calculateSecondaryStorageForAccount(long accountId) {
+        long totalVolumesSize = _volumeDao.secondaryStorageUsedForAccount(accountId);
+        long totalSnapshotsSize = 0;
+        long totalTemplatesSize = 0;
+
+        SearchCriteria<SumCount> sc = templateSizeSearch.create();
+        sc.setParameters("downloadState", Status.DOWNLOADED);
+        sc.setParameters("destroyed", false);
+        sc.setJoinParameters("templates", "accountId", accountId);
+        List<SumCount> templates = _vmTemplateStoreDao.customSearch(sc, null);
+        if (templates != null) {
+            totalTemplatesSize = templates.get(0).sum;
+        }
+
+        SearchCriteria<SumCount> sc2 = snapshotSizeSearch.create();
+        sc2.setParameters("state", ObjectInDataStoreStateMachine.State.Ready);
+        sc2.setParameters("storeRole", DataStoreRole.Image);
+        sc2.setJoinParameters("snapshots", "accountId", accountId);
+        List<SumCount> snapshots = _snapshotDataStoreDao.customSearch(sc2, null);
+        if (snapshots != null) {
+            totalSnapshotsSize = snapshots.get(0).sum;
+        }
+        return totalVolumesSize + totalSnapshotsSize + totalTemplatesSize;
+    }
+
+    private long calculatePublicIpForAccount(long accountId) {
+        Long dedicatedCount = 0L;
+        Long allocatedCount = 0L;
+
+        List<VlanVO> dedicatedVlans = _vlanDao.listDedicatedVlans(accountId);
+        for (VlanVO dedicatedVlan : dedicatedVlans) {
+            List<IPAddressVO> ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId());
+            dedicatedCount += new Long(ips.size());
+        }
+        allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId);
+        if (dedicatedCount > allocatedCount) {
+            return dedicatedCount;
+        } else {
+            return allocatedCount;
+        }
+    }
+
+    @Override
+    public long getResourceCount(Account account, ResourceType type) {
+        return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);
+    }
+
+    private boolean isDisplayFlagOn(Boolean displayResource) {
+
+        // 1. If its null assume displayResource = 1
+        // 2. If its not null then send true if displayResource = 1
+        return (displayResource == null) || (displayResource != null && displayResource);
+    }
+
+    @Override
+    public void checkResourceLimit(Account account, ResourceType type, Boolean displayResource, long... count) throws ResourceAllocationException {
+
+        if (isDisplayFlagOn(displayResource)) {
+            checkResourceLimit(account, type, count);
+        }
+    }
+
+    @Override
+    public void incrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
+
+        if (isDisplayFlagOn(displayResource)) {
+            incrementResourceCount(accountId, type, delta);
+        }
+    }
+
+    @Override
+    public void decrementResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
+
+        if (isDisplayFlagOn(displayResource)) {
+            decrementResourceCount(accountId, type, delta);
+        }
+    }
+
+    @Override
+    public void changeResourceCount(long accountId, ResourceType type, Boolean displayResource, Long... delta) {
+
+        // meaning that the display flag is not changed so neither increment or decrement
+        if (displayResource == null) {
+            return;
+        }
+
+        // Increment because the display is turned on.
+        if (displayResource) {
+            incrementResourceCount(accountId, type, delta);
+        } else {
+            decrementResourceCount(accountId, type, delta);
+        }
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ResourceLimitManagerImpl.class.getName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {ResourceCountCheckInterval};
+    }
+
+    protected class ResourceCountCheckTask extends ManagedContextRunnable {
+        public ResourceCountCheckTask() {
+
+        }
+
+        @Override
+        protected void runInContext() {
+            s_logger.info("Started resource counters recalculation periodic task.");
+            List<DomainVO> domains = _domainDao.findImmediateChildrenForParent(Domain.ROOT_DOMAIN);
+
+            // recalculateDomainResourceCount will take care of re-calculation of resource counts for sub-domains
+            // and accounts of the sub-domains also. so just loop through immediate children of root domain
+            for (Domain domain : domains) {
+                for (ResourceType type : ResourceCount.ResourceType.values()) {
+                    if (type.supportsOwner(ResourceOwnerType.Domain)) {
+                        recalculateDomainResourceCount(domain.getId(), type);
+                    }
+                }
+            }
+
+            // run through the accounts in the root domain
+            List<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(Domain.ROOT_DOMAIN);
+            for (AccountVO account : accounts) {
+                for (ResourceType type : ResourceCount.ResourceType.values()) {
+                    if (type.supportsOwner(ResourceOwnerType.Account)) {
+                        recalculateAccountResourceCount(account.getId(), type);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/server/src/com/cloud/server/ConfigurationServer.java b/server/src/main/java/com/cloud/server/ConfigurationServer.java
similarity index 100%
rename from server/src/com/cloud/server/ConfigurationServer.java
rename to server/src/main/java/com/cloud/server/ConfigurationServer.java
diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
new file mode 100644
index 0000000..c4bcb4e
--- /dev/null
+++ b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java
@@ -0,0 +1,1375 @@
+// 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.server;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.security.NoSuchAlgorithmException;
+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 java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.configuration.ResourceCountVO;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.guru.ControlNetworkGuru;
+import com.cloud.network.guru.DirectPodBasedNetworkGuru;
+import com.cloud.network.guru.PodBasedNetworkGuru;
+import com.cloud.network.guru.PublicNetworkGuru;
+import com.cloud.network.guru.StorageNetworkGuru;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offerings.NetworkOfferingServiceMapVO;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.test.IPRangeConfig;
+import com.cloud.user.Account;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.PasswordGenerator;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.Script;
+
+public class ConfigurationServerImpl extends ManagerBase implements ConfigurationServer {
+    public static final Logger s_logger = Logger.getLogger(ConfigurationServerImpl.class);
+
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private DataCenterDao _zoneDao;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    private DataCenterDao _dataCenterDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private ResourceCountDao _resourceCountDao;
+    @Inject
+    private NetworkOfferingServiceMapDao _ntwkOfferingServiceMapDao;
+    @Inject
+    protected ConfigDepotAdmin _configDepotAdmin;
+    @Inject
+    protected ConfigDepot _configDepot;
+    @Inject
+    protected ConfigurationManager _configMgr;
+    @Inject
+    protected ManagementService _mgrService;
+
+
+    public ConfigurationServerImpl() {
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        try {
+            persistDefaultValues();
+            _configDepotAdmin.populateConfigurations();
+        } catch (InternalErrorException e) {
+            throw new RuntimeException("Unhandled configuration exception", e);
+        }
+        return true;
+    }
+
+    @Override
+    public void persistDefaultValues() throws InternalErrorException {
+
+        // Create system user and admin user
+        saveUser();
+
+        // Get init
+        String init = _configDao.getValue("init");
+
+        if (init == null || init.equals("false")) {
+            s_logger.debug("ConfigurationServer is saving default values to the database.");
+
+            // Save default Configuration Table values
+            List<String> categories = Config.getCategories();
+            for (String category : categories) {
+                // If this is not a premium environment, don't insert premium configuration values
+                if (!_configDao.isPremium() && category.equals("Premium")) {
+                    continue;
+                }
+
+                List<Config> configs = Config.getConfigs(category);
+                for (Config c : configs) {
+                    String name = c.key();
+
+                    // if the config value already present in the db, don't insert it again
+                    if (_configDao.findByName(name) != null) {
+                        continue;
+                    }
+
+                    String instance = "DEFAULT";
+                    String component = c.getComponent();
+                    String value = c.getDefaultValue();
+                    String description = c.getDescription();
+                    ConfigurationVO configVO = new ConfigurationVO(category, instance, component, name, value, description);
+                    configVO.setDefaultValue(value);
+                    _configDao.persist(configVO);
+                }
+            }
+
+            _configDao.update(Config.UseSecondaryStorageVm.key(), Config.UseSecondaryStorageVm.getCategory(), "true");
+            s_logger.debug("ConfigurationServer made secondary storage vm required.");
+
+            _configDao.update(Config.SecStorageEncryptCopy.key(), Config.SecStorageEncryptCopy.getCategory(), "false");
+            s_logger.debug("ConfigurationServer made secondary storage copy encrypt set to false.");
+
+            _configDao.update("secstorage.secure.copy.cert", "realhostip");
+            s_logger.debug("ConfigurationServer made secondary storage copy use realhostip.");
+
+            _configDao.update("user.password.encoders.exclude", "MD5,LDAP,PLAINTEXT");
+            s_logger.debug("Configuration server excluded insecure encoders");
+
+            _configDao.update("user.authenticators.exclude", "PLAINTEXT");
+            s_logger.debug("Configuration server excluded plaintext authenticator");
+
+            // Save default service offerings
+            createServiceOffering(User.UID_SYSTEM, "Small Instance", 1, 512, 500, "Small Instance", ProvisioningType.THIN, false, false, null);
+            createServiceOffering(User.UID_SYSTEM, "Medium Instance", 1, 1024, 1000, "Medium Instance", ProvisioningType.THIN, false, false, null);
+            // Save default disk offerings
+            createdefaultDiskOffering(null, "Small", "Small Disk, 5 GB", ProvisioningType.THIN, 5, null, false, false);
+            createdefaultDiskOffering(null, "Medium", "Medium Disk, 20 GB", ProvisioningType.THIN, 20, null, false, false);
+            createdefaultDiskOffering(null, "Large", "Large Disk, 100 GB", ProvisioningType.THIN, 100, null, false, false);
+            createdefaultDiskOffering(null, "Large", "Large Disk, 100 GB", ProvisioningType.THIN, 100, null, false, false);
+            createdefaultDiskOffering(null, "Custom", "Custom Disk", ProvisioningType.THIN, 0, null, true, false);
+
+            // Save the mount parent to the configuration table
+            String mountParent = getMountParent();
+            if (mountParent != null) {
+                _configDao.update(Config.MountParent.key(), Config.MountParent.getCategory(), mountParent);
+                s_logger.debug("ConfigurationServer saved \"" + mountParent + "\" as mount.parent.");
+            } else {
+                s_logger.debug("ConfigurationServer could not detect mount.parent.");
+            }
+
+            String hostIpAdr = NetUtils.getDefaultHostIp();
+            boolean needUpdateHostIp = true;
+            if (hostIpAdr != null) {
+                Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
+                if (devel) {
+                    String value = _configDao.getValue(ApiServiceConfiguration.ManagementServerAddresses.key());
+                    if (value != null && !value.equals("localhost")) {
+                        needUpdateHostIp = false;
+                    }
+                }
+
+                if (needUpdateHostIp) {
+                    _configDepot.createOrUpdateConfigObject(ApiServiceConfiguration.class.getSimpleName(), ApiServiceConfiguration.ManagementServerAddresses, hostIpAdr);
+                    s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host.");
+                }
+            }
+
+            // generate a single sign-on key
+            updateSSOKey();
+
+            // Create default network offerings
+            createDefaultNetworkOfferings();
+
+            // Create default networks
+            createDefaultNetworks();
+
+            // Create userIpAddress ranges
+
+            // Update existing vlans with networkId
+            List<VlanVO> vlans = _vlanDao.listAll();
+            if (vlans != null && !vlans.isEmpty()) {
+                for (final VlanVO vlan : vlans) {
+                    if (vlan.getNetworkId().longValue() == 0) {
+                        updateVlanWithNetworkId(vlan);
+                    }
+
+                    // Create vlan user_ip_address range
+                    String ipPange = vlan.getIpRange();
+                    String[] range = ipPange.split("-");
+                    final String startIp = range[0];
+                    final String endIp = range[1];
+
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            IPRangeConfig config = new IPRangeConfig();
+                            long startIPLong = NetUtils.ip2Long(startIp);
+                            long endIPLong = NetUtils.ip2Long(endIp);
+                            config.savePublicIPRange(TransactionLegacy.currentTxn(), startIPLong, endIPLong, vlan.getDataCenterId(), vlan.getId(), vlan.getNetworkId(),
+                                    vlan.getPhysicalNetworkId(), false);
+                        }
+                    });
+
+                }
+            }
+        }
+        // Update resource count if needed
+        updateResourceCount();
+
+        // store the public and private keys in the database
+        updateKeyPairs();
+
+        // generate a PSK to communicate with SSVM
+        updateSecondaryStorageVMSharedKey();
+
+        // generate a random password for system vm
+        updateSystemvmPassword();
+
+        // generate a random password used to authenticate zone-to-zone copy
+        generateSecStorageVmCopyPassword();
+
+        // Update the cloud identifier
+        updateCloudIdentifier();
+
+        _configDepotAdmin.populateConfigurations();
+        // setup XenServer default PV driver version
+        initiateXenServerPVDriverVersion();
+
+        // We should not update seed data UUID column here since this will be invoked in upgrade case as well.
+        //updateUuids();
+        // Set init to true
+        _configDao.update("init", "Hidden", "true");
+
+        // invalidate cache in DAO as we have changed DB status
+        _configDao.invalidateCache();
+    }
+
+    private void templateDetailsInitIfNotExist(long id, String name, String value) {
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        PreparedStatement stmt = null;
+        PreparedStatement stmtInsert = null;
+        boolean insert = false;
+        try {
+            txn.start();
+            stmt = txn.prepareAutoCloseStatement("SELECT id FROM vm_template_details WHERE template_id=? and name=?");
+            stmt.setLong(1, id);
+            stmt.setString(2, name);
+            ResultSet rs = stmt.executeQuery();
+            if (rs == null || !rs.next()) {
+                insert = true;
+            }
+            stmt.close();
+
+            if (insert) {
+                stmtInsert = txn.prepareAutoCloseStatement("INSERT INTO vm_template_details(template_id, name, value) VALUES(?, ?, ?)");
+                stmtInsert.setLong(1, id);
+                stmtInsert.setString(2, name);
+                stmtInsert.setString(3, value);
+                if (stmtInsert.executeUpdate() < 1) {
+                    throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name);
+                }
+            }
+            txn.commit();
+        } catch (Exception e) {
+            s_logger.warn("Unable to init template " + id + " datails: " + name, e);
+            throw new CloudRuntimeException("Unable to init template " + id + " datails: " + name);
+        }
+    }
+
+    private void initiateXenServerPVDriverVersion() {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                TransactionLegacy txn = TransactionLegacy.currentTxn();
+                String pvdriverversion = Config.XenServerPVdriverVersion.getDefaultValue();
+                PreparedStatement pstmt = null;
+                ResultSet rs1 = null;
+                ResultSet rs2 = null;
+                try {
+                    String oldValue = _configDao.getValue(Config.XenServerPVdriverVersion.key());
+                    if (oldValue == null) {
+                        String sql = "select resource from host where hypervisor_type='XenServer' and removed is null and status not in ('Error', 'Removed') group by resource";
+                        pstmt = txn.prepareAutoCloseStatement(sql);
+                        rs1 = pstmt.executeQuery();
+                        while (rs1.next()) {
+                            String resouce = rs1.getString(1); //resource column
+                            if (resouce == null)
+                                continue;
+                            if (resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56Resource")
+                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource")
+                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer56SP2Resource")
+                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer600Resource")
+                                    || resouce.equalsIgnoreCase("com.cloud.hypervisor.xenserver.resource.XenServer602Resource")) {
+                                pvdriverversion = "xenserver56";
+                                break;
+                            }
+                        }
+                        _configDao.getValueAndInitIfNotExist(Config.XenServerPVdriverVersion.key(), Config.XenServerPVdriverVersion.getCategory(), pvdriverversion,
+                                Config.XenServerPVdriverVersion.getDescription());
+                        sql = "select id from vm_template where hypervisor_type='XenServer'  and format!='ISO' and removed is null";
+                        pstmt = txn.prepareAutoCloseStatement(sql);
+                        rs2 = pstmt.executeQuery();
+                        List<Long> tmpl_ids = new ArrayList<Long>();
+                        while (rs2.next()) {
+                            tmpl_ids.add(rs2.getLong(1));
+                        }
+                        for (Long tmpl_id : tmpl_ids) {
+                            templateDetailsInitIfNotExist(tmpl_id, "hypervisortoolsversion", pvdriverversion);
+                        }
+                    }
+                } catch (Exception e) {
+                    s_logger.debug("initiateXenServerPVDriverVersion failed due to " + e.toString());
+                    // ignore
+                }
+            }
+        });
+    }
+
+    private String getMountParent() {
+        return getEnvironmentProperty("mount.parent");
+    }
+
+    private String getEnvironmentProperty(String name) {
+        try {
+            final File propsFile = PropertiesUtil.findConfigFile("environment.properties");
+
+            if (propsFile == null) {
+                return null;
+            } else {
+                final Properties props = new Properties();
+                try(final FileInputStream finputstream = new FileInputStream(propsFile);) {
+                    props.load(finputstream);
+                }catch (IOException e) {
+                    s_logger.error("getEnvironmentProperty:Exception:" + e.getMessage());
+                }
+                return props.getProperty("mount.parent");
+            }
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    @DB
+    public void saveUser() {
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                TransactionLegacy txn = TransactionLegacy.currentTxn();
+                // insert system account
+                String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (1, UUID(), 'system', '1', '1', '1', 1)";
+
+                try {
+                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
+                    stmt.executeUpdate();
+                } catch (SQLException ex) {
+                    s_logger.debug("Looks like system account already exists");
+                }
+                // insert system user
+                insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, user.default)"
+                        + " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), 1)";
+
+                try {
+                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
+                    stmt.executeUpdate();
+                } catch (SQLException ex) {
+                    s_logger.debug("Looks like system user already exists");
+                }
+
+                // insert admin user, but leave the account disabled until we set a
+                // password with the user authenticator
+                long id = 2;
+                String username = "admin";
+                String firstname = "admin";
+                String lastname = "cloud";
+
+                // create an account for the admin user first
+                insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, role_id, domain_id, account.default) VALUES (" + id + ", UUID(), '" + username
+                        + "', '1', '1', '1', 1)";
+                try {
+                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
+                    stmt.executeUpdate();
+                } catch (SQLException ex) {
+                    s_logger.debug("Looks like admin account already exists");
+                }
+
+                // now insert the user
+                insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, user.default) " + "VALUES (" + id
+                        + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled', 1)";
+
+                try {
+                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
+                    stmt.executeUpdate();
+                } catch (SQLException ex) {
+                    s_logger.debug("Looks like admin user already exists");
+                }
+
+                try {
+                    String tableName = "security_group";
+                    try {
+                        String checkSql = "SELECT * from network_group";
+                        PreparedStatement stmt = txn.prepareAutoCloseStatement(checkSql);
+                        stmt.executeQuery();
+                        tableName = "network_group";
+                    } catch (Exception ex) {
+                        // Ignore in case of exception, table must not exist
+                    }
+
+                    insertSql = "SELECT * FROM " + tableName + " where account_id=2 and name='default'";
+                    PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
+                    ResultSet rs = stmt.executeQuery();
+                    if (!rs.next()) {
+                        // save default security group
+                        if (tableName.equals("security_group")) {
+                            insertSql = "INSERT INTO " + tableName + " (uuid, name, description, account_id, domain_id) "
+                                    + "VALUES (UUID(), 'default', 'Default Security Group', 2, 1)";
+                        } else {
+                            insertSql = "INSERT INTO " + tableName + " (name, description, account_id, domain_id, account_name) "
+                                    + "VALUES ('default', 'Default Security Group', 2, 1, 'admin')";
+                        }
+
+                        try {
+                            stmt = txn.prepareAutoCloseStatement(insertSql);
+                            stmt.executeUpdate();
+                        } catch (SQLException ex) {
+                            s_logger.warn("Failed to create default security group for default admin account due to ", ex);
+                        }
+                    }
+                    rs.close();
+                } catch (Exception ex) {
+                    s_logger.warn("Failed to create default security group for default admin account due to ", ex);
+                }
+            }
+        });
+    }
+
+    protected void updateCloudIdentifier() {
+        // Creates and saves a UUID as the cloud identifier
+        String currentCloudIdentifier = _configDao.getValue("cloud.identifier");
+        if (currentCloudIdentifier == null || currentCloudIdentifier.isEmpty()) {
+            String uuid = UUID.randomUUID().toString();
+            _configDao.update(Config.CloudIdentifier.key(), Config.CloudIdentifier.getCategory(), uuid);
+        }
+    }
+
+    @DB
+    protected void updateSystemvmPassword() {
+        String userid = System.getProperty("user.name");
+        if (!userid.startsWith("cloud")) {
+            return;
+        }
+
+        if (!Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+            return;
+        }
+
+        String already = _configDao.getValue("system.vm.password");
+        if (already == null) {
+            TransactionLegacy txn = TransactionLegacy.currentTxn();
+            try {
+                String rpassword = _mgrService.generateRandomPassword();
+                String wSql = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) "
+                + "VALUES ('Secure','DEFAULT', 'management-server','system.vm.password', ?,'randmon password generated each management server starts for system vm')";
+                PreparedStatement stmt = txn.prepareAutoCloseStatement(wSql);
+                stmt.setString(1, DBEncryptionUtil.encrypt(rpassword));
+                stmt.executeUpdate();
+                s_logger.info("Updated systemvm password in database");
+            } catch (SQLException e) {
+                s_logger.error("Cannot retrieve systemvm password", e);
+            }
+        }
+
+    }
+
+    @Override
+    @DB
+    public void updateKeyPairs() {
+        // Grab the SSH key pair and insert it into the database, if it is not present
+
+        String username = System.getProperty("user.name");
+        Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
+        if (!username.equalsIgnoreCase("cloud") && !devel) {
+            s_logger.warn("Systemvm keypairs could not be set. Management server should be run as cloud user, or in development mode.");
+            return;
+        }
+        String already = _configDao.getValue("ssh.privatekey");
+        String homeDir = System.getProperty("user.home");
+        if (homeDir == null) {
+            throw new CloudRuntimeException("Cannot get home directory for account: " + username);
+        }
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Processing updateKeyPairs");
+        }
+
+        if (homeDir != null && homeDir.startsWith("~")) {
+            s_logger.error("No home directory was detected for the user '" + username + "'. Please check the profile of this user.");
+            throw new CloudRuntimeException("No home directory was detected for the user '" + username + "'. Please check the profile of this user.");
+        }
+
+        // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server
+        File privkeyfile = null;
+        File pubkeyfile = null;
+        if (devel) {
+            privkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud");
+            pubkeyfile = new File(homeDir + "/.ssh/id_rsa.cloud.pub");
+        } else {
+            privkeyfile = new File(homeDir + "/.ssh/id_rsa");
+            pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub");
+        }
+
+        if (already == null || already.isEmpty()) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Systemvm keypairs not found in database. Need to store them in the database");
+            }
+            // FIXME: take a global database lock here for safety.
+            boolean onWindows = isOnWindows();
+            if(!onWindows) {
+                Script.runSimpleBashScript("if [ -f " + privkeyfile + " ]; then rm -f " + privkeyfile + "; fi; ssh-keygen -t rsa -m PEM -N '' -f " + privkeyfile + " -q 2>/dev/null || ssh-keygen -t rsa -N '' -f " + privkeyfile + " -q");
+            }
+
+            final String privateKey;
+            final String publicKey;
+            try {
+                privateKey = new String(Files.readAllBytes(privkeyfile.toPath()));
+            } catch (IOException e) {
+                s_logger.error("Cannot read the private key file", e);
+                throw new CloudRuntimeException("Cannot read the private key file");
+            }
+            try {
+                publicKey = new String(Files.readAllBytes(pubkeyfile.toPath()));
+            } catch (IOException e) {
+                s_logger.error("Cannot read the public key file", e);
+                throw new CloudRuntimeException("Cannot read the public key file");
+            }
+
+            final String insertSql1 =
+                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
+                            "VALUES ('Hidden','DEFAULT', 'management-server','ssh.privatekey', '" + DBEncryptionUtil.encrypt(privateKey) +
+                            "','Private key for the entire CloudStack')";
+            final String insertSql2 =
+                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
+                            "VALUES ('Hidden','DEFAULT', 'management-server','ssh.publickey', '" + DBEncryptionUtil.encrypt(publicKey) +
+                            "','Public key for the entire CloudStack')";
+
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+
+                    TransactionLegacy txn = TransactionLegacy.currentTxn();
+                    try {
+                        PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1);
+                        stmt1.executeUpdate();
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Private key inserted into database");
+                        }
+                    } catch (SQLException ex) {
+                        s_logger.error("SQL of the private key failed", ex);
+                        throw new CloudRuntimeException("SQL of the private key failed");
+                    }
+
+                    try {
+                        PreparedStatement stmt2 = txn.prepareAutoCloseStatement(insertSql2);
+                        stmt2.executeUpdate();
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Public key inserted into database");
+                        }
+                    } catch (SQLException ex) {
+                        s_logger.error("SQL of the public key failed", ex);
+                        throw new CloudRuntimeException("SQL of the public key failed");
+                    }
+                }
+            });
+
+        } else {
+            s_logger.info("Keypairs already in database, updating local copy");
+            updateKeyPairsOnDisk(homeDir);
+        }
+        s_logger.info("Going to update systemvm iso with generated keypairs if needed");
+        try {
+            injectSshKeysIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath(), privkeyfile.getAbsolutePath());
+        } catch (CloudRuntimeException e) {
+            if (!devel) {
+                throw new CloudRuntimeException(e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public List<ConfigurationVO> getConfigListByScope(String scope, Long resourceId) {
+
+        // Getting the list of parameters defined at the scope
+        Set<ConfigKey<?>> configList = _configDepot.getConfigListByScope(scope);
+        List<ConfigurationVO> configVOList = new ArrayList<ConfigurationVO>();
+        for (ConfigKey<?> param : configList) {
+            ConfigurationVO configVo = _configDao.findByName(param.toString());
+            configVo.setValue(_configDepot.get(param.toString()).valueIn(resourceId).toString());
+            configVOList.add(configVo);
+        }
+        return configVOList;
+    }
+
+    private void writeKeyToDisk(String key, String keyPath) {
+        File keyfile = new File(keyPath);
+        if (!keyfile.exists()) {
+            try {
+                keyfile.createNewFile();
+            } catch (IOException e) {
+                s_logger.warn("Failed to create file: " + e.toString());
+                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot create  key file " + keyPath);
+            }
+        }
+
+        if (keyfile.exists()) {
+            try (FileOutputStream kStream = new FileOutputStream(keyfile);){
+                if (kStream != null) {
+                    kStream.write(key.getBytes());
+                }
+            } catch (FileNotFoundException e) {
+                s_logger.warn("Failed to write  key to " + keyfile.getAbsolutePath(), e);
+                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot find  key file " + keyPath);
+            } catch (IOException e) {
+                s_logger.warn("Failed to write  key to " + keyfile.getAbsolutePath(), e);
+                throw new CloudRuntimeException("Failed to update keypairs on disk: cannot write to  key file " + keyPath);
+            }
+        }
+
+    }
+
+    private void updateKeyPairsOnDisk(String homeDir) {
+        File keyDir = new File(homeDir + "/.ssh");
+        Boolean devel = Boolean.valueOf(_configDao.getValue("developer"));
+        if (!keyDir.isDirectory()) {
+            s_logger.warn("Failed to create " + homeDir + "/.ssh for storing the SSH keypars");
+            keyDir.mkdirs();
+        }
+        String pubKey = _configDao.getValue("ssh.publickey");
+        String prvKey = _configDao.getValue("ssh.privatekey");
+
+        // Using non-default file names (id_rsa.cloud and id_rsa.cloud.pub) in developer mode. This is to prevent SSH keys overwritten for user running management server
+        if (devel) {
+            writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa.cloud");
+            writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.cloud.pub");
+        } else {
+            writeKeyToDisk(prvKey, homeDir + "/.ssh/id_rsa");
+            writeKeyToDisk(pubKey, homeDir + "/.ssh/id_rsa.pub");
+        }
+    }
+
+    protected void injectSshKeysIntoSystemVmIsoPatch(String publicKeyPath, String privKeyPath) {
+        s_logger.info("Trying to inject public and private keys into systemvm iso");
+        String injectScript = getInjectScript();
+        String scriptPath = Script.findScript("", injectScript);
+        String systemVmIsoPath = Script.findScript("", "vms/systemvm.iso");
+        if (scriptPath == null) {
+            throw new CloudRuntimeException("Unable to find key inject script " + injectScript);
+        }
+        if (systemVmIsoPath == null) {
+            throw new CloudRuntimeException("Unable to find systemvm iso vms/systemvm.iso");
+        }
+        Script command = null;
+        if(isOnWindows()) {
+            command = new Script("python", s_logger);
+        } else {
+            command = new Script("/bin/bash", s_logger);
+        }
+        if (isOnWindows()) {
+            scriptPath = scriptPath.replaceAll("\\\\" ,"/" );
+            systemVmIsoPath = systemVmIsoPath.replaceAll("\\\\" ,"/" );
+            publicKeyPath = publicKeyPath.replaceAll("\\\\" ,"/" );
+            privKeyPath = privKeyPath.replaceAll("\\\\" ,"/" );
+        }
+        command.add(scriptPath);
+        command.add(publicKeyPath);
+        command.add(privKeyPath);
+        command.add(systemVmIsoPath);
+
+        final String result = command.execute();
+        s_logger.info("Injected public and private keys into systemvm iso with result : " + result);
+        if (result != null) {
+            s_logger.warn("Failed to inject generated public key into systemvm iso " + result);
+            throw new CloudRuntimeException("Failed to inject generated public key into systemvm iso " + result);
+        }
+    }
+
+    protected String getInjectScript() {
+        String injectScript = null;
+        boolean onWindows = isOnWindows();
+        if(onWindows) {
+            injectScript = "scripts/vm/systemvm/injectkeys.py";
+        } else {
+            injectScript = "scripts/vm/systemvm/injectkeys.sh";
+        }
+        return injectScript;
+    }
+
+    protected boolean isOnWindows() {
+        String os = System.getProperty("os.name", "generic").toLowerCase();
+        boolean onWindows = (os != null && os.startsWith("windows"));
+        return onWindows;
+    }
+
+    @DB
+    protected void generateSecStorageVmCopyPassword() {
+        String already = _configDao.getValue("secstorage.copy.password");
+
+        if (already == null) {
+
+            s_logger.info("Need to store secondary storage vm copy password in the database");
+            String password = PasswordGenerator.generateRandomPassword(12);
+
+            final String insertSql1 =
+                    "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " +
+                            "VALUES ('Hidden','DEFAULT', 'management-server','secstorage.copy.password', '" + DBEncryptionUtil.encrypt(password) +
+                            "','Password used to authenticate zone-to-zone template copy requests')";
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+
+                    TransactionLegacy txn = TransactionLegacy.currentTxn();
+                    try {
+                        PreparedStatement stmt1 = txn.prepareAutoCloseStatement(insertSql1);
+                        stmt1.executeUpdate();
+                        s_logger.debug("secondary storage vm copy password inserted into database");
+                    } catch (SQLException ex) {
+                        s_logger.warn("Failed to insert secondary storage vm copy password", ex);
+                    }
+                }
+            });
+        }
+    }
+
+    private void updateSSOKey() {
+        try {
+            _configDao.update(Config.SSOKey.key(), Config.SSOKey.getCategory(), getPrivateKey());
+        } catch (NoSuchAlgorithmException ex) {
+            s_logger.error("error generating sso key", ex);
+        }
+    }
+
+    /**
+     * preshared key to be used by management server to communicate with SSVM during volume/template upload
+     */
+    private void updateSecondaryStorageVMSharedKey() {
+        try {
+            ConfigurationVO configInDB = _configDao.findByName(Config.SSVMPSK.key());
+            if(configInDB == null) {
+                ConfigurationVO configVO = new ConfigurationVO(Config.SSVMPSK.getCategory(), "DEFAULT", Config.SSVMPSK.getComponent(), Config.SSVMPSK.key(), getPrivateKey(),
+                        Config.SSVMPSK.getDescription());
+                s_logger.info("generating a new SSVM PSK. This goes to SSVM on Start");
+                _configDao.persist(configVO);
+            } else if (StringUtils.isEmpty(configInDB.getValue())) {
+                s_logger.info("updating the SSVM PSK with new value. This goes to SSVM on Start");
+                _configDao.update(Config.SSVMPSK.key(), Config.SSVMPSK.getCategory(), getPrivateKey());
+            }
+        } catch (NoSuchAlgorithmException ex) {
+            s_logger.error("error generating ssvm psk", ex);
+        }
+    }
+
+    private String getPrivateKey() throws NoSuchAlgorithmException {
+        String encodedKey = null;
+        // Algorithm for generating Key is SHA1, should this be configurable?
+        KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
+        SecretKey key = generator.generateKey();
+        encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
+        return encodedKey;
+
+    }
+
+
+    @DB
+    protected HostPodVO createPod(long userId, String podName, final long zoneId, String gateway, String cidr, final String startIp, String endIp)
+            throws InternalErrorException {
+        String[] cidrPair = cidr.split("\\/");
+        String cidrAddress = cidrPair[0];
+        int cidrSize = Integer.parseInt(cidrPair[1]);
+
+        if (startIp != null) {
+            if (endIp == null) {
+                endIp = NetUtils.getIpRangeEndIpFromCidr(cidrAddress, cidrSize);
+            }
+        }
+
+        // Create the new pod in the database
+        String ipRange;
+        if (startIp != null) {
+            ipRange = startIp + "-";
+            if (endIp != null) {
+                ipRange += endIp;
+            }
+        } else {
+            ipRange = "";
+        }
+
+        final HostPodVO pod = new HostPodVO(podName, zoneId, gateway, cidrAddress, cidrSize, ipRange);
+        try {
+            final String endIpFinal = endIp;
+            Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InternalErrorException>() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) throws InternalErrorException {
+                    if (_podDao.persist(pod) == null) {
+                        throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support.");
+                    }
+
+                    if (startIp != null) {
+                        _zoneDao.addPrivateIpAddress(zoneId, pod.getId(), startIp, endIpFinal, false, null);
+                    }
+
+                    String ipNums = _configDao.getValue("linkLocalIp.nums");
+                    int nums = Integer.parseInt(ipNums);
+                    if (nums > 16 || nums <= 0) {
+                        throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "is wrong, should be 1~16");
+                    }
+                    /* local link ip address starts from 169.254.0.2 - 169.254.(nums) */
+                    String[] linkLocalIpRanges = NetUtils.getLinkLocalIPRange(nums);
+                    if (linkLocalIpRanges == null) {
+                        throw new InvalidParameterValueException("The linkLocalIp.nums: " + nums + "may be wrong, should be 1~16");
+                    } else {
+                        _zoneDao.addLinkLocalIpAddress(zoneId, pod.getId(), linkLocalIpRanges[0], linkLocalIpRanges[1]);
+                    }
+                }
+            });
+        } catch (Exception e) {
+            s_logger.error("Unable to create new pod due to " + e.getMessage(), e);
+            throw new InternalErrorException("Failed to create new pod. Please contact Cloud Support.");
+        }
+
+        return pod;
+    }
+
+    private DiskOfferingVO createdefaultDiskOffering(Long domainId, String name, String description, ProvisioningType provisioningType,
+            int numGibibytes, String tags, boolean isCustomized, boolean isSystemUse) {
+        long diskSize = numGibibytes;
+        diskSize = diskSize * 1024 * 1024 * 1024;
+        tags = cleanupTags(tags);
+
+        DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, provisioningType, diskSize, tags, isCustomized, null, null, null);
+        newDiskOffering.setUniqueName("Cloud.Com-" + name);
+        // leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
+        newDiskOffering.setSystemUse(isSystemUse);
+        newDiskOffering = _diskOfferingDao.persistDeafultDiskOffering(newDiskOffering);
+        return newDiskOffering;
+    }
+
+    private ServiceOfferingVO createServiceOffering(long userId, String name, int cpu, int ramSize, int speed, String displayText,
+            ProvisioningType provisioningType, boolean localStorageRequired, boolean offerHA, String tags) {
+        tags = cleanupTags(tags);
+        ServiceOfferingVO offering =
+                new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, offerHA, displayText, provisioningType, localStorageRequired, false, tags, false, null, false);
+        offering.setUniqueName("Cloud.Com-" + name);
+        // leaving the above reference to cloud.com in as it is an identifyer and has no real world relevance
+        offering = _serviceOfferingDao.persistSystemServiceOffering(offering);
+        return offering;
+    }
+
+    private String cleanupTags(String tags) {
+        if (tags != null) {
+            String[] tokens = tags.split(",");
+            StringBuilder t = new StringBuilder();
+            for (int i = 0; i < tokens.length; i++) {
+                t.append(tokens[i].trim()).append(",");
+            }
+            t.delete(t.length() - 1, t.length());
+            tags = t.toString();
+        }
+
+        return tags;
+    }
+
+    @DB
+    protected void createDefaultNetworkOfferings() {
+
+        NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPublicNetwork, TrafficType.Public, true);
+        publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering);
+        NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemManagementNetwork, TrafficType.Management, false);
+        managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering);
+        NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemControlNetwork, TrafficType.Control, false);
+        controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
+        NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
+        storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
+        NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
+        privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
+
+        //populate providers
+        final Map<Network.Service, Network.Provider> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
+        defaultSharedNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
+        defaultSharedNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
+        defaultSharedNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
+
+        final Map<Network.Service, Network.Provider> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders;
+
+        final Map<Network.Service, Network.Provider> defaultSharedSGNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
+        defaultSharedSGNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
+        defaultSharedSGNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
+        defaultSharedSGNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
+        defaultSharedSGNetworkOfferingProviders.put(Service.SecurityGroup, Provider.SecurityGroupProvider);
+
+        final Map<Network.Service, Network.Provider> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.UserData, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Firewall, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Gateway, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Lb, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.SourceNat, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.StaticNat, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, Provider.VirtualRouter);
+        defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, Provider.VirtualRouter);
+
+        final Map<Network.Service, Network.Provider> netscalerServiceProviders = new HashMap<Network.Service, Network.Provider>();
+        netscalerServiceProviders.put(Service.Dhcp, Provider.VirtualRouter);
+        netscalerServiceProviders.put(Service.Dns, Provider.VirtualRouter);
+        netscalerServiceProviders.put(Service.UserData, Provider.VirtualRouter);
+        netscalerServiceProviders.put(Service.SecurityGroup, Provider.SecurityGroupProvider);
+        netscalerServiceProviders.put(Service.StaticNat, Provider.Netscaler);
+        netscalerServiceProviders.put(Service.Lb, Provider.Netscaler);
+
+        // The only one diff between 1 and 2 network offerings is that the first one has SG enabled. In Basic zone only
+        // first network offering has to be enabled, in Advance zone - the second one
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // Offering #1
+                NetworkOfferingVO defaultSharedSGNetworkOffering =
+                        new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
+                                TrafficType.Guest, false, true, null, null, true, Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false, false);
+
+                defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled);
+                defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering);
+
+                for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #2
+                NetworkOfferingVO defaultSharedNetworkOffering =
+                        new NetworkOfferingVO(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, false, true, null, null, true,
+                                Availability.Optional, null, Network.GuestType.Shared, true, true, false, false, false, false);
+
+                defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled);
+                defaultSharedNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering);
+
+                for (Service service : defaultSharedNetworkOfferingProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultSharedNetworkOffering.getId(), service, defaultSharedNetworkOfferingProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #3
+                NetworkOfferingVO defaultIsolatedSourceNatEnabledNetworkOffering =
+                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
+                                "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Required, null,
+                                Network.GuestType.Isolated, true, false, false, false, true, false);
+
+                defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
+                defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering);
+
+                for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service,
+                                    defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #4
+                NetworkOfferingVO defaultIsolatedEnabledNetworkOffering =
+                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest,
+                                false, true, null, null, true, Availability.Optional, null, Network.GuestType.Isolated, true, true, false, false, false, false);
+
+                defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
+                defaultIsolatedEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering);
+
+                for (Service service : defaultIsolatedNetworkOfferingProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultIsolatedEnabledNetworkOffering.getId(), service, defaultIsolatedNetworkOfferingProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #5
+                NetworkOfferingVO defaultNetscalerNetworkOffering =
+                        new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
+                                "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true,
+                                Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false, false, false);
+
+                defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled);
+                defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering);
+
+                for (Service service : netscalerServiceProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultNetscalerNetworkOffering.getId(), service, netscalerServiceProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #6
+                NetworkOfferingVO defaultNetworkOfferingForVpcNetworks =
+                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
+                                "Offering for Isolated Vpc networks with Source Nat service enabled", TrafficType.Guest, false, false, null, null, true, Availability.Optional,
+                                null, Network.GuestType.Isolated, false, false, false, false, true, true);
+
+                defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled);
+                defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks);
+
+                Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
+                defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter);
+
+                for (Map.Entry<Service,Provider> entry : defaultVpcNetworkOfferingProviders.entrySet()) {
+                     NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworks.getId(), entry.getKey(), entry.getValue());
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                // Offering #7
+                NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB =
+                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
+                                "Offering for Isolated Vpc networks with Source Nat service enabled and LB service Disabled", TrafficType.Guest, false, false, null, null, true,
+                                Availability.Optional, null, Network.GuestType.Isolated, false, false, false, false, false, true);
+
+                defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled);
+                defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB);
+
+                Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProvidersNoLB = new HashMap<Network.Service, Network.Provider>();
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dhcp, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dns, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.UserData, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.NetworkACL, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Gateway, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.SourceNat, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.StaticNat, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.PortForwarding, Provider.VPCVirtualRouter);
+                defaultVpcNetworkOfferingProvidersNoLB.put(Service.Vpn, Provider.VPCVirtualRouter);
+
+                for (Map.Entry<Service,Provider> entry : defaultVpcNetworkOfferingProvidersNoLB.entrySet()) {
+                    NetworkOfferingServiceMapVO offService =
+                            new NetworkOfferingServiceMapVO(defaultNetworkOfferingForVpcNetworksNoLB.getId(), entry.getKey(), entry.getValue());
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                //offering #8 - network offering with internal lb service
+                NetworkOfferingVO internalLbOff =
+                        new NetworkOfferingVO(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
+                                "Offering for Isolated Vpc networks with Internal LB support", TrafficType.Guest, false, false, null, null, true, Availability.Optional, null,
+                                Network.GuestType.Isolated, false, false, false, true, false, true);
+
+                internalLbOff.setState(NetworkOffering.State.Enabled);
+                internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff);
+
+                Map<Network.Service, Network.Provider> internalLbOffProviders = new HashMap<Network.Service, Network.Provider>();
+                internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter);
+                internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter);
+                internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter);
+                internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter);
+                internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter);
+                internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm);
+                internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter);
+
+                for (Service service : internalLbOffProviders.keySet()) {
+                    NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(internalLbOff.getId(), service, internalLbOffProviders.get(service));
+                    _ntwkOfferingServiceMapDao.persist(offService);
+                    s_logger.trace("Added service for the network offering: " + offService);
+                }
+
+                _networkOfferingDao.persistDefaultL2NetworkOfferings();
+            }
+        });
+    }
+
+    private void createDefaultNetworks() {
+        List<DataCenterVO> zones = _dataCenterDao.listAll();
+        long id = 1;
+
+        HashMap<TrafficType, String> guruNames = new HashMap<TrafficType, String>();
+        guruNames.put(TrafficType.Public, PublicNetworkGuru.class.getSimpleName());
+        guruNames.put(TrafficType.Management, PodBasedNetworkGuru.class.getSimpleName());
+        guruNames.put(TrafficType.Control, ControlNetworkGuru.class.getSimpleName());
+        guruNames.put(TrafficType.Storage, StorageNetworkGuru.class.getSimpleName());
+        guruNames.put(TrafficType.Guest, DirectPodBasedNetworkGuru.class.getSimpleName());
+
+        for (DataCenterVO zone : zones) {
+            long zoneId = zone.getId();
+            long accountId = 1L;
+            Long domainId = zone.getDomainId();
+
+            if (domainId == null) {
+                domainId = 1L;
+            }
+            // Create default networks - system only
+            List<NetworkOfferingVO> ntwkOff = _networkOfferingDao.listSystemNetworkOfferings();
+
+            for (NetworkOfferingVO offering : ntwkOff) {
+                if (offering.isSystemOnly()) {
+                    long related = id;
+                    long networkOfferingId = offering.getId();
+                    Mode mode = Mode.Static;
+                    String networkDomain = null;
+
+                    BroadcastDomainType broadcastDomainType = null;
+                    TrafficType trafficType = offering.getTrafficType();
+
+                    boolean specifyIpRanges = false;
+
+                    if (trafficType == TrafficType.Management) {
+                        broadcastDomainType = BroadcastDomainType.Native;
+                    } else if (trafficType == TrafficType.Storage) {
+                        broadcastDomainType = BroadcastDomainType.Native;
+                        specifyIpRanges = true;
+                    } else if (trafficType == TrafficType.Control) {
+                        broadcastDomainType = BroadcastDomainType.LinkLocal;
+                    } else if (offering.getTrafficType() == TrafficType.Public) {
+                        if ((zone.getNetworkType() == NetworkType.Advanced && !zone.isSecurityGroupEnabled()) || zone.getNetworkType() == NetworkType.Basic) {
+                            specifyIpRanges = true;
+                            broadcastDomainType = BroadcastDomainType.Vlan;
+                        } else {
+                            continue;
+                        }
+                    }
+
+                    if (broadcastDomainType != null) {
+                        NetworkVO network =
+                                new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain,
+                                        Network.GuestType.Shared, zoneId, null, null, specifyIpRanges, null, offering.isRedundantRouter());
+                        network.setGuruName(guruNames.get(network.getTrafficType()));
+                        network.setDns1(zone.getDns1());
+                        network.setDns2(zone.getDns2());
+                        network.setState(State.Implemented);
+                        _networkDao.persist(network, false, getServicesAndProvidersForNetwork(networkOfferingId));
+                        id++;
+                    }
+                }
+            }
+        }
+    }
+
+    private void updateVlanWithNetworkId(VlanVO vlan) {
+        long zoneId = vlan.getDataCenterId();
+        long networkId = 0L;
+        DataCenterVO zone = _zoneDao.findById(zoneId);
+
+        if (zone.getNetworkType() == NetworkType.Advanced) {
+            networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Public);
+        } else {
+            networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Guest);
+        }
+
+        vlan.setNetworkId(networkId);
+        _vlanDao.update(vlan.getId(), vlan);
+    }
+
+    private long getSystemNetworkIdByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // find system public network offering
+        Long networkOfferingId = null;
+        List<NetworkOfferingVO> offerings = _networkOfferingDao.listSystemNetworkOfferings();
+        for (NetworkOfferingVO offering : offerings) {
+            if (offering.getTrafficType() == trafficType) {
+                networkOfferingId = offering.getId();
+                break;
+            }
+        }
+
+        if (networkOfferingId == null) {
+            throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType);
+        }
+
+        List<NetworkVO> networks = _networkDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId);
+        if (networks == null || networks.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId);
+        }
+        return networks.get(0).getId();
+    }
+
+    @DB
+    public void updateResourceCount() {
+        ResourceType[] resourceTypes = Resource.ResourceType.values();
+        List<AccountVO> accounts = _accountDao.listAll();
+        List<DomainVO> domains = _domainDao.listAll();
+        List<ResourceCountVO> domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain);
+        List<ResourceCountVO> accountResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Account);
+
+        final List<ResourceType> accountSupportedResourceTypes = new ArrayList<ResourceType>();
+        final List<ResourceType> domainSupportedResourceTypes = new ArrayList<ResourceType>();
+
+        for (ResourceType resourceType : resourceTypes) {
+            if (resourceType.supportsOwner(ResourceOwnerType.Account)) {
+                accountSupportedResourceTypes.add(resourceType);
+            }
+            if (resourceType.supportsOwner(ResourceOwnerType.Domain)) {
+                domainSupportedResourceTypes.add(resourceType);
+            }
+        }
+
+        final int accountExpectedCount = accountSupportedResourceTypes.size();
+        final int domainExpectedCount = domainSupportedResourceTypes.size();
+
+        if ((domainResourceCount.size() < domainExpectedCount * domains.size())) {
+            s_logger.debug("resource_count table has records missing for some domains...going to insert them");
+            for (final DomainVO domain : domains) {
+                // Lock domain
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        _domainDao.lockRow(domain.getId(), true);
+                        List<ResourceCountVO> domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain);
+                        List<String> domainCountStr = new ArrayList<String>();
+                        for (ResourceCountVO domainCount : domainCounts) {
+                            domainCountStr.add(domainCount.getType().toString());
+                        }
+
+                        if (domainCountStr.size() < domainExpectedCount) {
+                            for (ResourceType resourceType : domainSupportedResourceTypes) {
+                                if (!domainCountStr.contains(resourceType.toString())) {
+                                    ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, domain.getId(), ResourceOwnerType.Domain);
+                                    s_logger.debug("Inserting resource count of type " + resourceType + " for domain id=" + domain.getId());
+                                    _resourceCountDao.persist(resourceCountVO);
+                                }
+                            }
+                        }
+                    }
+                });
+
+            }
+        }
+
+        if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) {
+            s_logger.debug("resource_count table has records missing for some accounts...going to insert them");
+            for (final AccountVO account : accounts) {
+                // lock account
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        _accountDao.lockRow(account.getId(), true);
+                        List<ResourceCountVO> accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account);
+                        List<String> accountCountStr = new ArrayList<String>();
+                        for (ResourceCountVO accountCount : accountCounts) {
+                            accountCountStr.add(accountCount.getType().toString());
+                        }
+
+                        if (accountCountStr.size() < accountExpectedCount) {
+                            for (ResourceType resourceType : accountSupportedResourceTypes) {
+                                if (!accountCountStr.contains(resourceType.toString())) {
+                                    ResourceCountVO resourceCountVO = new ResourceCountVO(resourceType, 0, account.getId(), ResourceOwnerType.Account);
+                                    s_logger.debug("Inserting resource count of type " + resourceType + " for account id=" + account.getId());
+                                    _resourceCountDao.persist(resourceCountVO);
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    public Map<String, String> getServicesAndProvidersForNetwork(long networkOfferingId) {
+        Map<String, String> svcProviders = new HashMap<String, String>();
+        List<NetworkOfferingServiceMapVO> servicesMap = _ntwkOfferingServiceMapDao.listByNetworkOfferingId(networkOfferingId);
+
+        for (NetworkOfferingServiceMapVO serviceMap : servicesMap) {
+            if (svcProviders.containsKey(serviceMap.getService())) {
+                continue;
+            }
+            svcProviders.put(serviceMap.getService(), serviceMap.getProvider());
+        }
+
+        return svcProviders;
+    }
+
+}
diff --git a/server/src/com/cloud/server/Criteria.java b/server/src/main/java/com/cloud/server/Criteria.java
similarity index 100%
rename from server/src/com/cloud/server/Criteria.java
rename to server/src/main/java/com/cloud/server/Criteria.java
diff --git a/server/src/main/java/com/cloud/server/LockMasterListener.java b/server/src/main/java/com/cloud/server/LockMasterListener.java
new file mode 100644
index 0000000..27cf74f
--- /dev/null
+++ b/server/src/main/java/com/cloud/server/LockMasterListener.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 com.cloud.server;
+
+import java.util.List;
+
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.utils.db.Merovingian2;
+
+/**
+ * when a management server is down.
+ *
+ */
+public class LockMasterListener implements ClusterManagerListener {
+    Merovingian2 _lockMaster;
+
+    public LockMasterListener(long msId) {
+        _lockMaster = Merovingian2.createLockMaster(msId);
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (ManagementServerHost node : nodeList) {
+            _lockMaster.cleanupForServer(node.getMsid());
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+}
diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/main/java/com/cloud/server/ManagementServer.java
similarity index 100%
rename from server/src/com/cloud/server/ManagementServer.java
rename to server/src/main/java/com/cloud/server/ManagementServer.java
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
new file mode 100644
index 0000000..9275db0
--- /dev/null
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -0,0 +1,4121 @@
+// 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.server;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.storage.ScopeType;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.affinity.AffinityGroupProcessor;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd;
+import org.apache.cloudstack.api.command.admin.account.DeleteAccountCmd;
+import org.apache.cloudstack.api.command.admin.account.DisableAccountCmd;
+import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd;
+import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.account.LockAccountCmd;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.address.AcquirePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.address.AssociateIPAddrCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.address.ListPublicIpAddressesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.affinitygroup.UpdateVMAffinityGroupCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.alert.GenerateAlertCmd;
+import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
+import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.AddClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.DeleteClusterCmd;
+import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
+import org.apache.cloudstack.api.command.admin.cluster.UpdateClusterCmd;
+import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
+import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd;
+import org.apache.cloudstack.api.command.admin.config.ListHypervisorCapabilitiesCmd;
+import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
+import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
+import org.apache.cloudstack.api.command.admin.direct.download.UploadTemplateDirectDownloadCertificateCmd;
+import org.apache.cloudstack.api.command.admin.domain.CreateDomainCmd;
+import org.apache.cloudstack.api.command.admin.domain.DeleteDomainCmd;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
+import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
+import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
+import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.DeleteHostCmd;
+import org.apache.cloudstack.api.command.admin.host.FindHostsForMigrationCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostTagsCmd;
+import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd;
+import org.apache.cloudstack.api.command.admin.host.ReleaseHostReservationCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
+import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
+import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
+import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
+import org.apache.cloudstack.api.command.admin.internallb.ListInternalLBVMsCmd;
+import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
+import org.apache.cloudstack.api.command.admin.internallb.StartInternalLBVMCmd;
+import org.apache.cloudstack.api.command.admin.internallb.StopInternalLBVMCmd;
+import org.apache.cloudstack.api.command.admin.iso.AttachIsoCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.iso.CopyIsoCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.iso.DetachIsoCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.iso.ListIsoPermissionsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.iso.ListIsosCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.iso.RegisterIsoCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.loadbalancer.ListLoadBalancerRuleInstancesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.management.ListMgmtsCmd;
+import org.apache.cloudstack.api.command.admin.network.AddNetworkDeviceCmd;
+import org.apache.cloudstack.api.command.admin.network.AddNetworkServiceProviderCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.CreatePhysicalNetworkCmd;
+import org.apache.cloudstack.api.command.admin.network.CreateStorageNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteNetworkDeviceCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteNetworkServiceProviderCmd;
+import org.apache.cloudstack.api.command.admin.network.DeletePhysicalNetworkCmd;
+import org.apache.cloudstack.api.command.admin.network.DeleteStorageNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
+import org.apache.cloudstack.api.command.admin.network.ListNetworkDeviceCmd;
+import org.apache.cloudstack.api.command.admin.network.ListNetworkIsolationMethodsCmd;
+import org.apache.cloudstack.api.command.admin.network.ListNetworkServiceProvidersCmd;
+import org.apache.cloudstack.api.command.admin.network.ListNetworksCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.ListPhysicalNetworksCmd;
+import org.apache.cloudstack.api.command.admin.network.ListStorageNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.ListSupportedNetworkServicesCmd;
+import org.apache.cloudstack.api.command.admin.network.MigrateNetworkCmd;
+import org.apache.cloudstack.api.command.admin.network.MigrateVPCCmd;
+import org.apache.cloudstack.api.command.admin.network.ReleaseDedicatedGuestVlanRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdateNetworkCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdateNetworkServiceProviderCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdatePhysicalNetworkCmd;
+import org.apache.cloudstack.api.command.admin.network.UpdateStorageNetworkIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.DeleteServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
+import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.ChangeOutOfBandManagementPasswordCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.ConfigureOutOfBandManagementCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForClusterCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForHostCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.DisableOutOfBandManagementForZoneCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForClusterCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForHostCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.EnableOutOfBandManagementForZoneCmd;
+import org.apache.cloudstack.api.command.admin.outofbandmanagement.IssueOutOfBandManagementPowerActionCmd;
+import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
+import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
+import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
+import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
+import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
+import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd;
+import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd;
+import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.CleanVMReservationsCmd;
+import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
+import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
+import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.DestroyRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
+import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
+import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.StartRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.StopRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.AddImageStoreS3CMD;
+import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.FindStoragePoolsForMigrationCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStorageProvidersCmd;
+import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
+import org.apache.cloudstack.api.command.admin.storage.PreparePrimaryStorageForMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.UpdateCloudToUseObjectStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
+import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
+import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.DestroySystemVmCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.ListSystemVMsCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.MigrateSystemVMCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.RebootSystemVmCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.ScaleSystemVMCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.StartSystemVMCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.StopSystemVmCmd;
+import org.apache.cloudstack.api.command.admin.systemvm.UpgradeSystemVMCmd;
+import org.apache.cloudstack.api.command.admin.template.CopyTemplateCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.template.CreateTemplateCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.template.ListTemplatePermissionsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.template.ListTemplatesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd;
+import org.apache.cloudstack.api.command.admin.template.RegisterTemplateCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.usage.AddTrafficMonitorCmd;
+import org.apache.cloudstack.api.command.admin.usage.AddTrafficTypeCmd;
+import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficMonitorCmd;
+import org.apache.cloudstack.api.command.admin.usage.DeleteTrafficTypeCmd;
+import org.apache.cloudstack.api.command.admin.usage.GenerateUsageRecordsCmd;
+import org.apache.cloudstack.api.command.admin.usage.GetUsageRecordsCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficMonitorsCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypesCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListUsageTypesCmd;
+import org.apache.cloudstack.api.command.admin.usage.RemoveRawUsageRecordsCmd;
+import org.apache.cloudstack.api.command.admin.usage.UpdateTrafficTypeCmd;
+import org.apache.cloudstack.api.command.admin.user.CreateUserCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.DisableUserCmd;
+import org.apache.cloudstack.api.command.admin.user.EnableUserCmd;
+import org.apache.cloudstack.api.command.admin.user.GetUserCmd;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
+import org.apache.cloudstack.api.command.admin.user.LockUserCmd;
+import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
+import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd;
+import org.apache.cloudstack.api.command.admin.vm.AddNicToVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.DeployVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.DestroyVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.GetVMUserDataCmd;
+import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd;
+import org.apache.cloudstack.api.command.admin.vm.RebootVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.RemoveNicFromVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.ResetVMPasswordCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.ResetVMSSHKeyCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.RestoreVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.ScaleVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.StartVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.StopVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.UpdateDefaultNicForVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.UpdateVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vm.UpgradeVMCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vmsnapshot.RevertToVMSnapshotCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.AttachVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.CreateVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.DetachVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.ResizeVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.UpdateVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.volume.UploadVolumeCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd;
+import org.apache.cloudstack.api.command.admin.vpc.CreateVPCCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
+import org.apache.cloudstack.api.command.admin.vpc.DeletePrivateGatewayCmd;
+import org.apache.cloudstack.api.command.admin.vpc.DeleteVPCOfferingCmd;
+import org.apache.cloudstack.api.command.admin.vpc.ListVPCsCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
+import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
+import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
+import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd;
+import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd;
+import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
+import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
+import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.address.DisassociateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.address.ListPublicIpAddressesCmd;
+import org.apache.cloudstack.api.command.user.address.UpdateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.DeleteAffinityGroupCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupTypesCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
+import org.apache.cloudstack.api.command.user.affinitygroup.UpdateVMAffinityGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmProfileCmd;
+import org.apache.cloudstack.api.command.user.autoscale.CreateConditionCmd;
+import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScalePolicyCmd;
+import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.DeleteAutoScaleVmProfileCmd;
+import org.apache.cloudstack.api.command.user.autoscale.DeleteConditionCmd;
+import org.apache.cloudstack.api.command.user.autoscale.DisableAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.EnableAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScalePoliciesCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmGroupsCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListAutoScaleVmProfilesCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListConditionsCmd;
+import org.apache.cloudstack.api.command.user.autoscale.ListCountersCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd;
+import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd;
+import org.apache.cloudstack.api.command.user.config.ListCapabilitiesCmd;
+import org.apache.cloudstack.api.command.user.event.ArchiveEventsCmd;
+import org.apache.cloudstack.api.command.user.event.DeleteEventsCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventTypesCmd;
+import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
+import org.apache.cloudstack.api.command.user.firewall.CreateEgressFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.CreatePortForwardingRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.DeleteEgressFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.DeleteFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.DeletePortForwardingRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd;
+import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
+import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
+import org.apache.cloudstack.api.command.user.firewall.UpdateEgressFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.UpdateFirewallRuleCmd;
+import org.apache.cloudstack.api.command.user.firewall.UpdatePortForwardingRuleCmd;
+import org.apache.cloudstack.api.command.user.guest.ListGuestOsCategoriesCmd;
+import org.apache.cloudstack.api.command.user.guest.ListGuestOsCmd;
+import org.apache.cloudstack.api.command.user.iso.AttachIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.CopyIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.DetachIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
+import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.AssignCertToLoadBalancerCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateApplicationLoadBalancerCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteApplicationLoadBalancerCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBHealthCheckPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLBStickinessPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLBHealthCheckPoliciesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLBStickinessPoliciesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleInstancesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.RemoveCertFromLoadBalancerCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.RemoveFromLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateApplicationLoadBalancerCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBHealthCheckPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLBStickinessPolicyCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
+import org.apache.cloudstack.api.command.user.nat.CreateIpForwardingRuleCmd;
+import org.apache.cloudstack.api.command.user.nat.DeleteIpForwardingRuleCmd;
+import org.apache.cloudstack.api.command.user.nat.DisableStaticNatCmd;
+import org.apache.cloudstack.api.command.user.nat.EnableStaticNatCmd;
+import org.apache.cloudstack.api.command.user.nat.ListIpForwardingRulesCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLListCmd;
+import org.apache.cloudstack.api.command.user.network.DeleteNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
+import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
+import org.apache.cloudstack.api.command.user.network.ReplaceNetworkACLListCmd;
+import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
+import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
+import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
+import org.apache.cloudstack.api.command.user.project.ActivateProjectCmd;
+import org.apache.cloudstack.api.command.user.project.CreateProjectCmd;
+import org.apache.cloudstack.api.command.user.project.DeleteProjectCmd;
+import org.apache.cloudstack.api.command.user.project.DeleteProjectInvitationCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
+import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
+import org.apache.cloudstack.api.command.user.project.SuspendProjectCmd;
+import org.apache.cloudstack.api.command.user.project.UpdateProjectCmd;
+import org.apache.cloudstack.api.command.user.project.UpdateProjectInvitationCmd;
+import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.ListGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.RemoveFromGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.UpdateGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.resource.GetCloudIdentifierCmd;
+import org.apache.cloudstack.api.command.user.resource.ListHypervisorsCmd;
+import org.apache.cloudstack.api.command.user.resource.ListResourceLimitsCmd;
+import org.apache.cloudstack.api.command.user.resource.UpdateResourceCountCmd;
+import org.apache.cloudstack.api.command.user.resource.UpdateResourceLimitCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd;
+import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ArchiveSnapshotCmd;
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotFromVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
+import org.apache.cloudstack.api.command.user.snapshot.RevertSnapshotCmd;
+import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.ssh.CreateSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
+import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
+import org.apache.cloudstack.api.command.user.tag.CreateTagsCmd;
+import org.apache.cloudstack.api.command.user.tag.DeleteTagsCmd;
+import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
+import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
+import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
+import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
+import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
+import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
+import org.apache.cloudstack.api.command.user.vm.RemoveIpFromVmNicCmd;
+import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
+import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
+import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
+import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
+import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
+import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
+import org.apache.cloudstack.api.command.user.vm.StopVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
+import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
+import org.apache.cloudstack.api.command.user.volume.AddResourceDetailCmd;
+import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd;
+import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.RemoveResourceDetailCmd;
+import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
+import org.apache.cloudstack.api.command.user.vpc.CreateStaticRouteCmd;
+import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
+import org.apache.cloudstack.api.command.user.vpc.DeleteStaticRouteCmd;
+import org.apache.cloudstack.api.command.user.vpc.DeleteVPCCmd;
+import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
+import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
+import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
+import org.apache.cloudstack.api.command.user.vpc.ListVPCsCmd;
+import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd;
+import org.apache.cloudstack.api.command.user.vpc.UpdateVPCCmd;
+import org.apache.cloudstack.api.command.user.vpn.AddVpnUserCmd;
+import org.apache.cloudstack.api.command.user.vpn.CreateRemoteAccessVpnCmd;
+import org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd;
+import org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd;
+import org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd;
+import org.apache.cloudstack.api.command.user.vpn.DeleteRemoteAccessVpnCmd;
+import org.apache.cloudstack.api.command.user.vpn.DeleteVpnConnectionCmd;
+import org.apache.cloudstack.api.command.user.vpn.DeleteVpnCustomerGatewayCmd;
+import org.apache.cloudstack.api.command.user.vpn.DeleteVpnGatewayCmd;
+import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd;
+import org.apache.cloudstack.api.command.user.vpn.ListVpnConnectionsCmd;
+import org.apache.cloudstack.api.command.user.vpn.ListVpnCustomerGatewaysCmd;
+import org.apache.cloudstack.api.command.user.vpn.ListVpnGatewaysCmd;
+import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd;
+import org.apache.cloudstack.api.command.user.vpn.RemoveVpnUserCmd;
+import org.apache.cloudstack.api.command.user.vpn.ResetVpnConnectionCmd;
+import org.apache.cloudstack.api.command.user.vpn.UpdateRemoteAccessVpnCmd;
+import org.apache.cloudstack.api.command.user.vpn.UpdateVpnConnectionCmd;
+import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd;
+import org.apache.cloudstack.api.command.user.vpn.UpdateVpnGatewayCmd;
+import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
+import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.resourcedetail.dao.GuestOsDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.manager.allocator.HostAllocator;
+import com.cloud.alert.Alert;
+import com.cloud.alert.AlertManager;
+import com.cloud.alert.AlertVO;
+import com.cloud.alert.dao.AlertDao;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.QueryManagerImpl;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.consoleproxy.ConsoleProxyManagementState;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.dc.AccountVlanMapVO;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.AccountVlanMapDao;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.event.dao.EventDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.gpu.GPU;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostTagVO;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.host.dao.HostTagsDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilities;
+import com.cloud.hypervisor.HypervisorCapabilitiesVO;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.info.ConsoleProxyInfo;
+import com.cloud.network.IpAddress;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.projects.Project;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.projects.ProjectManager;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.GuestOSHypervisorVO;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.GuestOsCategory;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.GuestOSHypervisorDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.SSHKeyPair;
+import com.cloud.user.SSHKeyPairVO;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.SSHKeyPairDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.PasswordGenerator;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.MacAddress;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.ssh.SSHKeysHelper;
+import com.cloud.vm.ConsoleProxyVO;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.InstanceGroupVO;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.VirtualMachineProfileImpl;
+import com.cloud.vm.dao.ConsoleProxyDao;
+import com.cloud.vm.dao.InstanceGroupDao;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+public class ManagementServerImpl extends ManagerBase implements ManagementServer, Configurable {
+    public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
+
+    static final ConfigKey<Integer> vmPasswordLength = new ConfigKey<Integer>("Advanced", Integer.class, "vm.password.length", "6", "Specifies the length of a randomly generated password", false);
+    static final ConfigKey<Integer> sshKeyLength = new ConfigKey<Integer>("Advanced", Integer.class, "ssh.key.length", "2048", "Specifies custom SSH key length (bit)", true, ConfigKey.Scope.Global);
+    @Inject
+    public AccountManager _accountMgr;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    private IPAddressDao _publicIpAddressDao;
+    @Inject
+    private ConsoleProxyDao _consoleProxyDao;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private SecondaryStorageVmDao _secStorageVmDao;
+    @Inject
+    public EventDao _eventDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private AccountVlanMapDao _accountVlanMapDao;
+    @Inject
+    private PodVlanMapDao _podVlanMapDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private HostDetailsDao _detailsDao;
+    @Inject
+    private UserDao _userDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ConsoleProxyManager _consoleProxyMgr;
+    @Inject
+    private SecondaryStorageVmManager _secStorageVmMgr;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    public AlertDao _alertDao;
+    @Inject
+    private CapacityDao _capacityDao;
+    @Inject
+    private GuestOSDao _guestOSDao;
+    @Inject
+    private GuestOSCategoryDao _guestOSCategoryDao;
+    @Inject
+    private GuestOSHypervisorDao _guestOSHypervisorDao;
+    @Inject
+    private PrimaryDataStoreDao _poolDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private StorageManager _storageMgr;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private HostPodDao _hostPodDao;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    private int _purgeDelay;
+    private int _alertPurgeDelay;
+    @Inject
+    private InstanceGroupDao _vmGroupDao;
+    @Inject
+    protected SSHKeyPairDao _sshKeyPairDao;
+    @Inject
+    private LoadBalancerDao _loadbalancerDao;
+    @Inject
+    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
+    private List<HostAllocator> hostAllocators;
+    private List<StoragePoolAllocator> _storagePoolAllocators;
+    @Inject
+    private ResourceTagDao _resourceTagDao;
+    @Inject
+    private ImageStoreDao _imgStoreDao;
+    @Inject
+    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+    @Inject
+    private ProjectManager _projectMgr;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private HighAvailabilityManager _haMgr;
+    @Inject
+    private HostTagsDao _hostTagsDao;
+    @Inject
+    private ConfigDepot _configDepot;
+    @Inject
+    private UserVmManager _userVmMgr;
+    @Inject
+    private AccountService _accountService;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private DeploymentPlanningManager _dpMgr;
+    @Inject
+    private GuestOsDetailsDao _guestOsDetailsDao;
+    @Inject
+    private KeystoreManager _ksMgr;
+
+    private LockMasterListener _lockMasterListener;
+    private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
+    private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));
+
+    private Map<String, String> _configs;
+
+    private Map<String, Boolean> _availableIdsMap;
+
+    private List<UserAuthenticator> _userAuthenticators;
+    private List<UserAuthenticator> _userPasswordEncoders;
+    protected boolean _executeInSequence;
+
+    protected List<DeploymentPlanner> _planners;
+
+    private final List<HypervisorType> supportedHypervisors = new ArrayList<Hypervisor.HypervisorType>();
+
+    public List<DeploymentPlanner> getPlanners() {
+        return _planners;
+    }
+
+    public void setPlanners(final List<DeploymentPlanner> planners) {
+        _planners = planners;
+    }
+
+    @Inject
+    ClusterManager _clusterMgr;
+
+    @Inject
+    protected AffinityGroupVMMapDao _affinityGroupVMMapDao;
+
+    protected List<AffinityGroupProcessor> _affinityProcessors;
+
+    public List<AffinityGroupProcessor> getAffinityGroupProcessors() {
+        return _affinityProcessors;
+    }
+
+    public void setAffinityGroupProcessors(final List<AffinityGroupProcessor> affinityProcessors) {
+        _affinityProcessors = affinityProcessors;
+    }
+
+    public ManagementServerImpl() {
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_APPLICATION_MAINLOOP);
+    }
+
+    public List<UserAuthenticator> getUserAuthenticators() {
+        return _userAuthenticators;
+    }
+
+    public void setUserAuthenticators(final List<UserAuthenticator> authenticators) {
+        _userAuthenticators = authenticators;
+    }
+
+    public List<UserAuthenticator> getUserPasswordEncoders() {
+        return _userPasswordEncoders;
+    }
+
+    public void setUserPasswordEncoders(final List<UserAuthenticator> encoders) {
+        _userPasswordEncoders = encoders;
+    }
+
+    public List<HostAllocator> getHostAllocators() {
+        return hostAllocators;
+    }
+
+    public void setHostAllocators(final List<HostAllocator> hostAllocators) {
+        this.hostAllocators = hostAllocators;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+
+        _configs = _configDao.getConfiguration();
+
+        final String value = _configs.get("event.purge.interval");
+        final int cleanup = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
+
+        _purgeDelay = NumbersUtil.parseInt(_configs.get("event.purge.delay"), 0);
+        if (_purgeDelay != 0) {
+            _eventExecutor.scheduleAtFixedRate(new EventPurgeTask(), cleanup, cleanup, TimeUnit.SECONDS);
+        }
+
+        //Alerts purge configurations
+        final int alertPurgeInterval = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeInterval.key()), 60 * 60 * 24); // 1 day.
+        _alertPurgeDelay = NumbersUtil.parseInt(_configDao.getValue(Config.AlertPurgeDelay.key()), 0);
+        if (_alertPurgeDelay != 0) {
+            _alertExecutor.scheduleAtFixedRate(new AlertPurgeTask(), alertPurgeInterval, alertPurgeInterval, TimeUnit.SECONDS);
+        }
+
+        final String[] availableIds = TimeZone.getAvailableIDs();
+        _availableIdsMap = new HashMap<String, Boolean>(availableIds.length);
+        for (final String id : availableIds) {
+            _availableIdsMap.put(id, true);
+        }
+
+        supportedHypervisors.add(HypervisorType.KVM);
+        supportedHypervisors.add(HypervisorType.XenServer);
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        s_logger.info("Startup CloudStack management server...");
+
+        if (_lockMasterListener == null) {
+            _lockMasterListener = new LockMasterListener(ManagementServerNode.getManagementServerId());
+        }
+
+        _clusterMgr.registerListener(_lockMasterListener);
+
+        enableAdminUser("password");
+        return true;
+    }
+
+    protected Map<String, String> getConfigs() {
+        return _configs;
+    }
+
+    @Override
+    public String generateRandomPassword() {
+        final Integer passwordLength = vmPasswordLength.value();
+        return PasswordGenerator.generateRandomPassword(passwordLength);
+    }
+
+    @Override
+    public HostVO getHostBy(final long hostId) {
+        return _hostDao.findById(hostId);
+    }
+
+    @Override
+    public DetailVO findDetail(final long hostId, final String name) {
+        return _detailsDao.findDetail(hostId, name);
+    }
+
+    @Override
+    public long getId() {
+        return MacAddress.getMacAddress().toLong();
+    }
+
+    protected void checkPortParameters(final String publicPort, final String privatePort, final String privateIp, final String proto) {
+
+        if (!NetUtils.isValidPort(publicPort)) {
+            throw new InvalidParameterValueException("publicPort is an invalid value");
+        }
+        if (!NetUtils.isValidPort(privatePort)) {
+            throw new InvalidParameterValueException("privatePort is an invalid value");
+        }
+
+        // s_logger.debug("Checking if " + privateIp +
+        // " is a valid private IP address. Guest IP address is: " +
+        // _configs.get("guest.ip.network"));
+        //
+        // if (!NetUtils.isValidPrivateIp(privateIp,
+        // _configs.get("guest.ip.network"))) {
+        // throw new
+        // InvalidParameterValueException("Invalid private ip address");
+        // }
+        if (!NetUtils.isValidProto(proto)) {
+            throw new InvalidParameterValueException("Invalid protocol");
+        }
+    }
+
+    @Override
+    public boolean archiveEvents(final ArchiveEventsCmd cmd) {
+        final Account caller = getCaller();
+        final List<Long> ids = cmd.getIds();
+        boolean result = true;
+        List<Long> permittedAccountIds = new ArrayList<Long>();
+
+        if (_accountService.isNormalUser(caller.getId()) || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            permittedAccountIds.add(caller.getId());
+        } else {
+            final DomainVO domain = _domainDao.findById(caller.getDomainId());
+            final List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
+            permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
+        }
+
+        final List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds);
+        final ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents);
+
+        if (ids != null && events.size() < ids.size()) {
+            result = false;
+            return result;
+        }
+        _eventDao.archiveEvents(events);
+        return result;
+    }
+
+    @Override
+    public boolean deleteEvents(final DeleteEventsCmd cmd) {
+        final Account caller = getCaller();
+        final List<Long> ids = cmd.getIds();
+        boolean result = true;
+        List<Long> permittedAccountIds = new ArrayList<Long>();
+
+        if (_accountMgr.isNormalUser(caller.getId()) || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            permittedAccountIds.add(caller.getId());
+        } else {
+            final DomainVO domain = _domainDao.findById(caller.getDomainId());
+            final List<Long> permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
+            permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds);
+        }
+
+        final List<EventVO> events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds);
+        final ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]);
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents);
+
+        if (ids != null && events.size() < ids.size()) {
+            result = false;
+            return result;
+        }
+        for (final EventVO event : events) {
+            _eventDao.remove(event.getId());
+        }
+        return result;
+    }
+
+    @Override
+    public List<? extends Cluster> searchForClusters(long zoneId, final Long startIndex, final Long pageSizeVal, final String hypervisorType) {
+        final Filter searchFilter = new Filter(ClusterVO.class, "id", true, startIndex, pageSizeVal);
+        final SearchCriteria<ClusterVO> sc = _clusterDao.createSearchCriteria();
+
+        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
+
+        sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisorType);
+
+        return _clusterDao.search(sc, searchFilter);
+    }
+
+    @Override
+    public Pair<List<? extends Cluster>, Integer> searchForClusters(final ListClustersCmd cmd) {
+        final Object id = cmd.getId();
+        final Object name = cmd.getClusterName();
+        final Object podId = cmd.getPodId();
+        Long zoneId = cmd.getZoneId();
+        final Object hypervisorType = cmd.getHypervisorType();
+        final Object clusterType = cmd.getClusterType();
+        final Object allocationState = cmd.getAllocationState();
+        final String keyword = cmd.getKeyword();
+        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
+
+        final Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        final SearchBuilder<ClusterVO> sb = _clusterDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ);
+        sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ);
+
+        final SearchCriteria<ClusterVO> sc = sb.create();
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        if (podId != null) {
+            sc.setParameters("podId", podId);
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+
+        if (hypervisorType != null) {
+            sc.setParameters("hypervisorType", hypervisorType);
+        }
+
+        if (clusterType != null) {
+            sc.setParameters("clusterType", clusterType);
+        }
+
+        if (allocationState != null) {
+            sc.setParameters("allocationState", allocationState);
+        }
+
+        if (keyword != null) {
+            final SearchCriteria<ClusterVO> ssc = _clusterDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("hypervisorType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        final Pair<List<ClusterVO>, Integer> result = _clusterDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Cluster>, Integer>(result.first(), result.second());
+    }
+
+    private HypervisorType getHypervisorType(VMInstanceVO vm, StoragePool srcVolumePool, VirtualMachineProfile profile) {
+        HypervisorType type = null;
+        if (vm == null) {
+            StoragePoolVO poolVo = _poolDao.findById(srcVolumePool.getId());
+            if (ScopeType.CLUSTER.equals(poolVo.getScope())) {
+                Long clusterId = poolVo.getClusterId();
+                if (clusterId != null) {
+                    ClusterVO cluster = _clusterDao.findById(clusterId);
+                    type = cluster.getHypervisorType();
+                }
+            } else if (ScopeType.ZONE.equals(poolVo.getScope())) {
+                Long zoneId = poolVo.getDataCenterId();
+                if (zoneId != null) {
+                    DataCenterVO dc = _dcDao.findById(zoneId);
+                }
+            }
+
+            if (null == type) {
+                type = srcVolumePool.getHypervisor();
+            }
+        } else {
+            type = profile.getHypervisorType();
+        }
+        return type;
+    }
+
+    @Override
+    public Pair<List<? extends Host>, Integer> searchForServers(final ListHostsCmd cmd) {
+
+        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        final Object name = cmd.getHostName();
+        final Object type = cmd.getType();
+        final Object state = cmd.getState();
+        final Object pod = cmd.getPodId();
+        final Object cluster = cmd.getClusterId();
+        final Object id = cmd.getId();
+        final Object keyword = cmd.getKeyword();
+        final Object resourceState = cmd.getResourceState();
+        final Object haHosts = cmd.getHaHost();
+
+        final Pair<List<HostVO>, Integer> result = searchForServers(cmd.getStartIndex(), cmd.getPageSizeVal(), name, type, state, zoneId, pod, cluster, id, keyword, resourceState, haHosts, null,
+                null);
+        return new Pair<List<? extends Host>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> listHostsForMigrationOfVM(final Long vmId, final Long startIndex, final Long pageSize,
+            final String keyword) {
+        final Account caller = getCaller();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
+            }
+            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
+        }
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the VM with given id");
+            throw ex;
+        }
+
+        if (vm.getState() != State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not running, cannot migrate the vm" + vm);
+            }
+            final InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, cannot " + "migrate the vm with specified id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            s_logger.info(" Live Migration of GPU enabled VM : " + vm.getInstanceName() + " is not supported");
+            // Return empty list.
+            return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(new Pair<List<? extends Host>, Integer>(new ArrayList<HostVO>(), new Integer(0)),
+                    new ArrayList<Host>(), new HashMap<Host, Boolean>());
+        }
+
+        if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
+                && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.LXC)
+                && !vm.getHypervisorType().equals(HypervisorType.Simulator) && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
+            }
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
+        }
+
+        if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
+        }
+
+        final long srcHostId = vm.getHostId();
+        final Host srcHost = _hostDao.findById(srcHostId);
+        if (srcHost == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find the host with id: " + srcHostId + " of this VM:" + vm);
+            }
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the host (with specified id) of VM with specified id");
+            ex.addProxyObject(String.valueOf(srcHostId), "hostId");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        // Check if the vm can be migrated with storage.
+        boolean canMigrateWithStorage = false;
+
+        if (vm.getType() == VirtualMachine.Type.User) {
+            final HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
+            if (capabilities != null) {
+                canMigrateWithStorage = capabilities.isStorageMotionSupported();
+            }
+        }
+
+        // Check if the vm is using any disks on local storage.
+        final VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null);
+        final List<VolumeVO> volumes = _volumeDao.findCreatedByInstance(vmProfile.getId());
+        boolean usesLocal = false;
+        for (final VolumeVO volume : volumes) {
+            final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+            final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType());
+            if (diskProfile.useLocalStorage()) {
+                usesLocal = true;
+                break;
+            }
+        }
+
+        if (!canMigrateWithStorage && usesLocal) {
+            throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate");
+        }
+
+        final Type hostType = srcHost.getType();
+        Pair<List<HostVO>, Integer> allHostsPair = null;
+        List<HostVO> allHosts = null;
+        final Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, Boolean>();
+        DataCenterDeployment plan = null;
+        if (canMigrateWithStorage) {
+            allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, srcHost.getDataCenterId(), null, null, null, keyword, null, null, srcHost.getHypervisorType(),
+                    srcHost.getHypervisorVersion());
+            allHosts = allHostsPair.first();
+            allHosts.remove(srcHost);
+
+            for (final VolumeVO volume : volumes) {
+                StoragePool storagePool = _poolDao.findById(volume.getPoolId());
+                Long volClusterId = storagePool.getClusterId();
+
+                for (Iterator<HostVO> iterator = allHosts.iterator(); iterator.hasNext();) {
+                    final Host host = iterator.next();
+
+                    if (volClusterId != null) {
+                        if (storagePool.isLocal() || !host.getClusterId().equals(volClusterId) || usesLocal) {
+                            if (storagePool.isManaged()) {
+                                // At the time being, we do not support storage migration of a volume from managed storage unless the managed storage
+                                // is at the zone level and the source and target storage pool is the same.
+                                // If the source and target storage pool is the same and it is managed, then we still have to perform a storage migration
+                                // because we need to create a new target volume and copy the contents of the source volume into it before deleting the
+                                // source volume.
+                                iterator.remove();
+                            } else {
+                                if (hasSuitablePoolsForVolume(volume, host, vmProfile)) {
+                                    requiresStorageMotion.put(host, true);
+                                } else {
+                                    iterator.remove();
+                                }
+                            }
+                        }
+                    } else {
+                        if (storagePool.isManaged()) {
+                            if (srcHost.getClusterId() != host.getClusterId()) {
+                                // If the volume's storage pool is managed and at the zone level, then we still have to perform a storage migration
+                                // because we need to create a new target volume and copy the contents of the source volume into it before deleting
+                                // the source volume.
+                                requiresStorageMotion.put(host, true);
+                            }
+                        }
+                    }
+                }
+            }
+
+            plan = new DataCenterDeployment(srcHost.getDataCenterId(), null, null, null, null, null);
+        } else {
+            final Long cluster = srcHost.getClusterId();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Searching for all hosts in cluster " + cluster + " for migrating VM " + vm);
+            }
+            allHostsPair = searchForServers(startIndex, pageSize, null, hostType, null, null, null, cluster, null, keyword, null, null, null, null);
+            // Filter out the current host.
+            allHosts = allHostsPair.first();
+            allHosts.remove(srcHost);
+            plan = new DataCenterDeployment(srcHost.getDataCenterId(), srcHost.getPodId(), srcHost.getClusterId(), null, null, null);
+        }
+
+        final Pair<List<? extends Host>, Integer> otherHosts = new Pair<List<? extends Host>, Integer>(allHosts, new Integer(allHosts.size()));
+        List<Host> suitableHosts = new ArrayList<Host>();
+        final ExcludeList excludes = new ExcludeList();
+        excludes.addHost(srcHostId);
+
+        // call affinitygroup chain
+        final long vmGroupCount = _affinityGroupVMMapDao.countAffinityGroupsForVm(vm.getId());
+
+        if (vmGroupCount > 0) {
+            for (final AffinityGroupProcessor processor : _affinityProcessors) {
+                processor.process(vmProfile, plan, excludes);
+            }
+        }
+
+        for (final HostAllocator allocator : hostAllocators) {
+            if (canMigrateWithStorage) {
+                suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, allHosts, HostAllocator.RETURN_UPTO_ALL, false);
+            } else {
+                suitableHosts = allocator.allocateTo(vmProfile, plan, Host.Type.Routing, excludes, HostAllocator.RETURN_UPTO_ALL, false);
+            }
+
+            if (suitableHosts != null && !suitableHosts.isEmpty()) {
+                break;
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            if (suitableHosts.isEmpty()) {
+                s_logger.debug("No suitable hosts found");
+            } else {
+                s_logger.debug("Hosts having capacity and suitable for migration: " + suitableHosts);
+            }
+        }
+
+        return new Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>>(otherHosts, suitableHosts, requiresStorageMotion);
+    }
+
+    private boolean hasSuitablePoolsForVolume(final VolumeVO volume, final Host host, final VirtualMachineProfile vmProfile) {
+        final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+        final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, vmProfile.getHypervisorType());
+        final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null);
+        final ExcludeList avoid = new ExcludeList();
+
+        for (final StoragePoolAllocator allocator : _storagePoolAllocators) {
+            final List<StoragePool> poolList = allocator.allocateToPool(diskProfile, vmProfile, plan, avoid, 1);
+            if (poolList != null && !poolList.isEmpty()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public Pair<List<? extends StoragePool>, List<? extends StoragePool>> listStoragePoolsForMigrationOfVolume(final Long volumeId) {
+        final Account caller = getCaller();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied to migrate the volume");
+            }
+            throw new PermissionDeniedException("No permission to migrate volume, only root admin can migrate a volume");
+        }
+
+        final VolumeVO volume = _volumeDao.findById(volumeId);
+        if (volume == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with" + " specified id.");
+            ex.addProxyObject(volumeId.toString(), "volumeId");
+            throw ex;
+        }
+
+        // Volume must be attached to an instance for live migration.
+        List<? extends StoragePool> allPools = new ArrayList<StoragePool>();
+        List<? extends StoragePool> suitablePools = new ArrayList<StoragePool>();
+
+        // Volume must be in Ready state to be migrated.
+        if (!Volume.State.Ready.equals(volume.getState())) {
+            s_logger.info("Volume " + volume + " must be in ready state for migration.");
+            return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
+        }
+
+        final Long instanceId = volume.getInstanceId();
+        VMInstanceVO vm = null;
+        if (instanceId != null) {
+            vm = _vmInstanceDao.findById(instanceId);
+        }
+
+        if (vm == null) {
+            s_logger.info("Volume " + volume + " isn't attached to any vm. Looking for storage pools in the " + "zone to which this volumes can be migrated.");
+        } else if (vm.getState() != State.Running) {
+            s_logger.info("Volume " + volume + " isn't attached to any running vm. Looking for storage pools in the " + "cluster to which this volumes can be migrated.");
+        } else {
+            s_logger.info("Volume " + volume + " is attached to any running vm. Looking for storage pools in the " + "cluster to which this volumes can be migrated.");
+            boolean storageMotionSupported = false;
+            // Check if the underlying hypervisor supports storage motion.
+            final Long hostId = vm.getHostId();
+            if (hostId != null) {
+                final HostVO host = _hostDao.findById(hostId);
+                HypervisorCapabilitiesVO capabilities = null;
+                if (host != null) {
+                    capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(host.getHypervisorType(), host.getHypervisorVersion());
+                } else {
+                    s_logger.error("Details of the host on which the vm " + vm + ", to which volume " + volume + " is " + "attached, couldn't be retrieved.");
+                }
+
+                if (capabilities != null) {
+                    storageMotionSupported = capabilities.isStorageMotionSupported();
+                } else {
+                    s_logger.error("Capabilities for host " + host + " couldn't be retrieved.");
+                }
+            }
+
+            if (!storageMotionSupported) {
+                s_logger.info("Volume " + volume + " is attached to a running vm and the hypervisor doesn't support" + " storage motion.");
+                return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
+            }
+        }
+
+        StoragePool srcVolumePool = _poolDao.findById(volume.getPoolId());
+        allPools = getAllStoragePoolCompatileWithVolumeSourceStoragePool(srcVolumePool);
+        allPools.remove(srcVolumePool);
+        suitablePools = findAllSuitableStoragePoolsForVm(volume, vm, srcVolumePool);
+
+        return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
+    }
+
+    /**
+     * This method looks for all storage pools that are compatible with the given volume.
+     * <ul>
+     *  <li>We will look for storage systems that are zone wide.</li>
+     *  <li>We also all storage available filtering by data center, pod and cluster as the current storage pool used by the given volume.</li>
+     * </ul>
+     */
+    private List<? extends StoragePool> getAllStoragePoolCompatileWithVolumeSourceStoragePool(StoragePool srcVolumePool) {
+        List<StoragePoolVO> storagePools = new ArrayList<>();
+        List<StoragePoolVO> zoneWideStoragePools = _poolDao.findZoneWideStoragePoolsByTags(srcVolumePool.getDataCenterId(), null);
+        if (CollectionUtils.isNotEmpty(zoneWideStoragePools)) {
+            storagePools.addAll(zoneWideStoragePools);
+        }
+        List<StoragePoolVO> clusterAndLocalStoragePools = _poolDao.listBy(srcVolumePool.getDataCenterId(), srcVolumePool.getPodId(), srcVolumePool.getClusterId(), null);
+        if (CollectionUtils.isNotEmpty(clusterAndLocalStoragePools)) {
+            storagePools.addAll(clusterAndLocalStoragePools);
+        }
+        return storagePools;
+    }
+
+    /**
+     *  Looks for all suitable storage pools to allocate the given volume.
+     *  We take into account the service offering of the VM and volume to find suitable storage pools. It is also excluded from the search the current storage pool used by the volume.
+     *  We use {@link StoragePoolAllocator} to look for possible storage pools to allocate the given volume. We will look for possible local storage poosl even if the volume is using a shared storage disk offering.
+     *
+     *  Side note: the idea behind this method is to provide power for administrators of manually overriding deployments defined by CloudStack.
+     */
+    private List<StoragePool> findAllSuitableStoragePoolsForVm(final VolumeVO volume, VMInstanceVO vm, StoragePool srcVolumePool) {
+        List<StoragePool> suitablePools = new ArrayList<>();
+
+        HostVO host = _hostDao.findById(vm.getHostId());
+        if (host == null) {
+            host = _hostDao.findById(vm.getLastHostId());
+        }
+
+        ExcludeList avoid = new ExcludeList();
+        avoid.addPool(srcVolumePool.getId());
+
+        DataCenterDeployment plan = new DataCenterDeployment(volume.getDataCenterId(), srcVolumePool.getPodId(), srcVolumePool.getClusterId(), null, null, null);
+        VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
+        // OfflineVmwareMigration: vm might be null here; deal!
+        HypervisorType type = getHypervisorType(vm, srcVolumePool, profile);
+
+        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+        //This is an override mechanism so we can list the possible local storage pools that a volume in a shared pool might be able to be migrated to
+        DiskProfile diskProfile = new DiskProfile(volume, diskOffering, type);
+        diskProfile.setUseLocalStorage(true);
+
+        for (StoragePoolAllocator allocator : _storagePoolAllocators) {
+            List<StoragePool> pools = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
+            if (CollectionUtils.isEmpty(pools)) {
+                continue;
+            }
+            for (StoragePool pool : pools) {
+                boolean isLocalPoolSameHostAsSourcePool = pool.isLocal() && StringUtils.equals(host.getPrivateIpAddress(), pool.getHostAddress());
+                if (isLocalPoolSameHostAsSourcePool || pool.isShared()) {
+                    suitablePools.add(pool);
+                }
+
+            }
+        }
+        return suitablePools;
+    }
+
+    private Pair<List<HostVO>, Integer> searchForServers(final Long startIndex, final Long pageSize, final Object name, final Object type, final Object state, final Object zone, final Object pod,
+            final Object cluster, final Object id, final Object keyword, final Object resourceState, final Object haHosts, final Object hypervisorType, final Object hypervisorVersion) {
+        final Filter searchFilter = new Filter(HostVO.class, "id", Boolean.TRUE, startIndex, pageSize);
+
+        final SearchBuilder<HostVO> sb = _hostDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.LIKE);
+        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
+        sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
+        sb.and("resourceState", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
+        sb.and("hypervisorType", sb.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        sb.and("hypervisorVersion", sb.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ);
+
+        final String haTag = _haMgr.getHaTag();
+        SearchBuilder<HostTagVO> hostTagSearch = null;
+        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
+            hostTagSearch = _hostTagsDao.createSearchBuilder();
+            if ((Boolean)haHosts) {
+                hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.EQ);
+            } else {
+                hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
+                hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
+            }
+
+            hostTagSearch.cp();
+            sb.join("hostTagSearch", hostTagSearch, sb.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
+        }
+
+        final SearchCriteria<HostVO> sc = sb.create();
+
+        if (keyword != null) {
+            final SearchCriteria<HostVO> ssc = _hostDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("status", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("type", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+        if (type != null) {
+            sc.setParameters("type", "%" + type);
+        }
+        if (state != null) {
+            sc.setParameters("status", state);
+        }
+        if (zone != null) {
+            sc.setParameters("dataCenterId", zone);
+        }
+        if (pod != null) {
+            sc.setParameters("podId", pod);
+        }
+        if (cluster != null) {
+            sc.setParameters("clusterId", cluster);
+        }
+        if (hypervisorType != null) {
+            sc.setParameters("hypervisorType", hypervisorType);
+        }
+        if (hypervisorVersion != null) {
+            sc.setParameters("hypervisorVersion", hypervisorVersion);
+        }
+
+        if (resourceState != null) {
+            sc.setParameters("resourceState", resourceState);
+        }
+
+        if (haHosts != null && haTag != null && !haTag.isEmpty()) {
+            sc.setJoinParameters("hostTagSearch", "tag", haTag);
+        }
+
+        return _hostDao.searchAndCount(sc, searchFilter);
+    }
+
+    @Override
+    public Pair<List<? extends Pod>, Integer> searchForPods(final ListPodsByCmd cmd) {
+        final String podName = cmd.getPodName();
+        final Long id = cmd.getId();
+        Long zoneId = cmd.getZoneId();
+        final Object keyword = cmd.getKeyword();
+        final Object allocationState = cmd.getAllocationState();
+        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
+
+        final Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchBuilder<HostPodVO> sb = _hostPodDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ);
+
+        final SearchCriteria<HostPodVO> sc = sb.create();
+        if (keyword != null) {
+            final SearchCriteria<HostPodVO> ssc = _hostPodDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (podName != null) {
+            sc.setParameters("name", "%" + podName + "%");
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+
+        if (allocationState != null) {
+            sc.setParameters("allocationState", allocationState);
+        }
+
+        final Pair<List<HostPodVO>, Integer> result = _hostPodDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Pod>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends Vlan>, Integer> searchForVlans(final ListVlanIpRangesCmd cmd) {
+        // If an account name and domain ID are specified, look up the account
+        final String accountName = cmd.getAccountName();
+        final Long domainId = cmd.getDomainId();
+        Long accountId = null;
+        final Long networkId = cmd.getNetworkId();
+        final Boolean forVirtual = cmd.isForVirtualNetwork();
+        String vlanType = null;
+        final Long projectId = cmd.getProjectId();
+        final Long physicalNetworkId = cmd.getPhysicalNetworkId();
+
+        if (accountName != null && domainId != null) {
+            if (projectId != null) {
+                throw new InvalidParameterValueException("Account and projectId can't be specified together");
+            }
+            final Account account = _accountDao.findActiveAccount(accountName, domainId);
+            if (account == null) {
+                final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain");
+                // Since we don't have a DomainVO object here, we directly set
+                // tablename to "domain".
+                final DomainVO domain = ApiDBUtils.findDomainById(domainId);
+                String domainUuid = domainId.toString();
+                if (domain != null) {
+                    domainUuid = domain.getUuid();
+                }
+                ex.addProxyObject(domainUuid, "domainId");
+                throw ex;
+            } else {
+                accountId = account.getId();
+            }
+        }
+
+        if (forVirtual != null) {
+            if (forVirtual) {
+                vlanType = VlanType.VirtualNetwork.toString();
+            } else {
+                vlanType = VlanType.DirectAttached.toString();
+            }
+        }
+
+        // set project information
+        if (projectId != null) {
+            final Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by id " + projectId);
+                ex.addProxyObject(projectId.toString(), "projectId");
+                throw ex;
+            }
+            accountId = project.getProjectAccountId();
+        }
+
+        final Filter searchFilter = new Filter(VlanVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        final Object id = cmd.getId();
+        final Object vlan = cmd.getVlan();
+        final Object dataCenterId = cmd.getZoneId();
+        final Object podId = cmd.getPodId();
+        final Object keyword = cmd.getKeyword();
+
+        final SearchBuilder<VlanVO> sb = _vlanDao.createSearchBuilder();
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("vlan", sb.entity().getVlanTag(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("vlan", sb.entity().getVlanTag(), SearchCriteria.Op.EQ);
+        sb.and("networkId", sb.entity().getNetworkId(), SearchCriteria.Op.EQ);
+        sb.and("vlanType", sb.entity().getVlanType(), SearchCriteria.Op.EQ);
+        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
+
+        if (accountId != null) {
+            final SearchBuilder<AccountVlanMapVO> accountVlanMapSearch = _accountVlanMapDao.createSearchBuilder();
+            accountVlanMapSearch.and("accountId", accountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+            sb.join("accountVlanMapSearch", accountVlanMapSearch, sb.entity().getId(), accountVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.INNER);
+        }
+
+        if (podId != null) {
+            final SearchBuilder<PodVlanMapVO> podVlanMapSearch = _podVlanMapDao.createSearchBuilder();
+            podVlanMapSearch.and("podId", podVlanMapSearch.entity().getPodId(), SearchCriteria.Op.EQ);
+            sb.join("podVlanMapSearch", podVlanMapSearch, sb.entity().getId(), podVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchCriteria<VlanVO> sc = sb.create();
+        if (keyword != null) {
+            final SearchCriteria<VlanVO> ssc = _vlanDao.createSearchCriteria();
+            ssc.addOr("vlanTag", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("ipRange", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("vlanTag", SearchCriteria.Op.SC, ssc);
+        } else {
+            if (id != null) {
+                sc.setParameters("id", id);
+            }
+
+            if (vlan != null) {
+                sc.setParameters("vlan", vlan);
+            }
+
+            if (dataCenterId != null) {
+                sc.setParameters("dataCenterId", dataCenterId);
+            }
+
+            if (networkId != null) {
+                sc.setParameters("networkId", networkId);
+            }
+
+            if (accountId != null) {
+                sc.setJoinParameters("accountVlanMapSearch", "accountId", accountId);
+            }
+
+            if (podId != null) {
+                sc.setJoinParameters("podVlanMapSearch", "podId", podId);
+            }
+            if (vlanType != null) {
+                sc.setParameters("vlanType", vlanType);
+            }
+
+            if (physicalNetworkId != null) {
+                sc.setParameters("physicalNetworkId", physicalNetworkId);
+            }
+        }
+
+        final Pair<List<VlanVO>, Integer> result = _vlanDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Vlan>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends Configuration>, Integer> searchForConfigurations(final ListCfgsByCmd cmd) {
+        final Filter searchFilter = new Filter(ConfigurationVO.class, "name", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchCriteria<ConfigurationVO> sc = _configDao.createSearchCriteria();
+
+        final Object name = cmd.getConfigName();
+        final Object category = cmd.getCategory();
+        final Object keyword = cmd.getKeyword();
+        final Long zoneId = cmd.getZoneId();
+        final Long clusterId = cmd.getClusterId();
+        final Long storagepoolId = cmd.getStoragepoolId();
+        final Long accountId = cmd.getAccountId();
+        final Long domainId = cmd.getDomainId();
+        final Long imageStoreId = cmd.getImageStoreId();
+        String scope = null;
+        Long id = null;
+        int paramCountCheck = 0;
+
+        if (zoneId != null) {
+            scope = ConfigKey.Scope.Zone.toString();
+            id = zoneId;
+            paramCountCheck++;
+        }
+        if (clusterId != null) {
+            scope = ConfigKey.Scope.Cluster.toString();
+            id = clusterId;
+            paramCountCheck++;
+        }
+        if (accountId != null) {
+            scope = ConfigKey.Scope.Account.toString();
+            id = accountId;
+            paramCountCheck++;
+        }
+        if (domainId != null) {
+            scope = ConfigKey.Scope.Domain.toString();
+            id = domainId;
+            paramCountCheck++;
+        }
+        if (storagepoolId != null) {
+            scope = ConfigKey.Scope.StoragePool.toString();
+            id = storagepoolId;
+            paramCountCheck++;
+        }
+        if (imageStoreId != null) {
+            scope = ConfigKey.Scope.ImageStore.toString();
+            id = imageStoreId;
+            paramCountCheck++;
+        }
+
+        if (paramCountCheck > 1) {
+            throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
+        }
+
+        if (keyword != null) {
+            final SearchCriteria<ConfigurationVO> ssc = _configDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("instance", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("component", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("category", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("value", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
+        }
+
+        if (category != null) {
+            sc.addAnd("category", SearchCriteria.Op.EQ, category);
+        }
+
+        // hidden configurations are not displayed using the search API
+        sc.addAnd("category", SearchCriteria.Op.NEQ, "Hidden");
+
+        if (scope != null && !scope.isEmpty()) {
+            // getting the list of parameters at requested scope
+            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
+        }
+
+        final Pair<List<ConfigurationVO>, Integer> result = _configDao.searchAndCount(sc, searchFilter);
+
+        if (scope != null && !scope.isEmpty()) {
+            // Populate values corresponding the resource id
+            final List<ConfigurationVO> configVOList = new ArrayList<ConfigurationVO>();
+            for (final ConfigurationVO param : result.first()) {
+                final ConfigurationVO configVo = _configDao.findByName(param.getName());
+                if (configVo != null) {
+                    final ConfigKey<?> key = _configDepot.get(param.getName());
+                    if (key != null) {
+                        configVo.setValue(key.valueIn(id) == null ? null : key.valueIn(id).toString());
+                        configVOList.add(configVo);
+                    } else {
+                        s_logger.warn("ConfigDepot could not find parameter " + param.getName() + " for scope " + scope);
+                    }
+                } else {
+                    s_logger.warn("Configuration item  " + param.getName() + " not found in " + scope);
+                }
+            }
+
+            return new Pair<List<? extends Configuration>, Integer>(configVOList, configVOList.size());
+        }
+
+        return new Pair<List<? extends Configuration>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends IpAddress>, Integer> searchForIPAddresses(final ListPublicIpAddressesCmd cmd) {
+        final Object keyword = cmd.getKeyword();
+        final Long physicalNetworkId = cmd.getPhysicalNetworkId();
+        final Long associatedNetworkId = cmd.getAssociatedNetworkId();
+        final Long zone = cmd.getZoneId();
+        final String address = cmd.getIpAddress();
+        final Long vlan = cmd.getVlanId();
+        final Boolean forVirtualNetwork = cmd.isForVirtualNetwork();
+        final Boolean forLoadBalancing = cmd.isForLoadBalancing();
+        final Long ipId = cmd.getId();
+        final Boolean sourceNat = cmd.isSourceNat();
+        final Boolean staticNat = cmd.isStaticNat();
+        final Long vpcId = cmd.getVpcId();
+        final Boolean forDisplay = cmd.getDisplay();
+        final Map<String, String> tags = cmd.getTags();
+
+        final String state = cmd.getState();
+        Boolean isAllocated = cmd.isAllocatedOnly();
+        if (isAllocated == null) {
+            isAllocated = Boolean.TRUE;
+
+            if (state != null) {
+                isAllocated = Boolean.FALSE;
+            }
+        }
+
+        final Filter searchFilter = new Filter(IPAddressVO.class, "address", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchBuilder<IPAddressVO> sb = _publicIpAddressDao.createSearchBuilder();
+        Long domainId = null;
+        Boolean isRecursive = null;
+        final List<Long> permittedAccounts = new ArrayList<Long>();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = null;
+        if (isAllocated) {
+            final Account caller = getCaller();
+
+            final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(),
+                    null);
+            _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+            domainId = domainIdRecursiveListProject.first();
+            isRecursive = domainIdRecursiveListProject.second();
+            listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+            _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        }
+
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("address", sb.entity().getAddress(), SearchCriteria.Op.EQ);
+        sb.and("vlanDbId", sb.entity().getVlanId(), SearchCriteria.Op.EQ);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("physicalNetworkId", sb.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
+        sb.and("associatedNetworkIdEq", sb.entity().getAssociatedWithNetworkId(), SearchCriteria.Op.EQ);
+        sb.and("isSourceNat", sb.entity().isSourceNat(), SearchCriteria.Op.EQ);
+        sb.and("isStaticNat", sb.entity().isOneToOneNat(), SearchCriteria.Op.EQ);
+        sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("display", sb.entity().isDisplay(), SearchCriteria.Op.EQ);
+
+        if (forLoadBalancing != null && forLoadBalancing) {
+            final SearchBuilder<LoadBalancerVO> lbSearch = _loadbalancerDao.createSearchBuilder();
+            sb.join("lbSearch", lbSearch, sb.entity().getId(), lbSearch.entity().getSourceIpAddressId(), JoinType.INNER);
+            sb.groupBy(sb.entity().getId());
+        }
+
+        if (keyword != null && address == null) {
+            sb.and("addressLIKE", sb.entity().getAddress(), SearchCriteria.Op.LIKE);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            final SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchBuilder<VlanVO> vlanSearch = _vlanDao.createSearchBuilder();
+        vlanSearch.and("vlanType", vlanSearch.entity().getVlanType(), SearchCriteria.Op.EQ);
+        sb.join("vlanSearch", vlanSearch, sb.entity().getVlanId(), vlanSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+
+        if (isAllocated != null && isAllocated == true) {
+            sb.and("allocated", sb.entity().getAllocatedTime(), SearchCriteria.Op.NNULL);
+        }
+
+        VlanType vlanType = null;
+        if (forVirtualNetwork != null) {
+            vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached;
+        } else {
+            vlanType = VlanType.VirtualNetwork;
+        }
+
+        final SearchCriteria<IPAddressVO> sc = sb.create();
+        if (isAllocated) {
+            _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        }
+
+        sc.setJoinParameters("vlanSearch", "vlanType", vlanType);
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.PublicIpAddress.toString());
+            for (final String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        if (zone != null) {
+            sc.setParameters("dataCenterId", zone);
+        }
+
+        if (vpcId != null) {
+            sc.setParameters("vpcId", vpcId);
+        }
+
+        if (ipId != null) {
+            sc.setParameters("id", ipId);
+        }
+
+        if (sourceNat != null) {
+            sc.setParameters("isSourceNat", sourceNat);
+        }
+
+        if (staticNat != null) {
+            sc.setParameters("isStaticNat", staticNat);
+        }
+
+        if (address == null && keyword != null) {
+            sc.setParameters("addressLIKE", "%" + keyword + "%");
+        }
+
+        if (address != null) {
+            sc.setParameters("address", address);
+        }
+
+        if (vlan != null) {
+            sc.setParameters("vlanDbId", vlan);
+        }
+
+        if (physicalNetworkId != null) {
+            sc.setParameters("physicalNetworkId", physicalNetworkId);
+        }
+
+        if (associatedNetworkId != null) {
+            sc.setParameters("associatedNetworkIdEq", associatedNetworkId);
+        }
+
+        if (forDisplay != null) {
+            sc.setParameters("display", forDisplay);
+        }
+
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+
+        final Pair<List<IPAddressVO>, Integer> result = _publicIpAddressDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends IpAddress>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends GuestOS>, Integer> listGuestOSByCriteria(final ListGuestOsCmd cmd) {
+        final Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final Long id = cmd.getId();
+        final Long osCategoryId = cmd.getOsCategoryId();
+        final String description = cmd.getDescription();
+        final String keyword = cmd.getKeyword();
+
+        final SearchCriteria<GuestOSVO> sc = _guestOSDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (osCategoryId != null) {
+            sc.addAnd("categoryId", SearchCriteria.Op.EQ, osCategoryId);
+        }
+
+        if (description != null) {
+            sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + description + "%");
+        }
+
+        if (keyword != null) {
+            sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+        }
+
+        final Pair<List<GuestOSVO>, Integer> result = _guestOSDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends GuestOS>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends GuestOsCategory>, Integer> listGuestOSCategoriesByCriteria(final ListGuestOsCategoriesCmd cmd) {
+        final Filter searchFilter = new Filter(GuestOSCategoryVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final Long id = cmd.getId();
+        final String name = cmd.getName();
+        final String keyword = cmd.getKeyword();
+
+        final SearchCriteria<GuestOSCategoryVO> sc = _guestOSCategoryDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%");
+        }
+
+        if (keyword != null) {
+            sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+        }
+
+        final Pair<List<GuestOSCategoryVO>, Integer> result = _guestOSCategoryDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends GuestOsCategory>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public Pair<List<? extends GuestOSHypervisor>, Integer> listGuestOSMappingByCriteria(final ListGuestOsMappingCmd cmd) {
+        final Filter searchFilter = new Filter(GuestOSHypervisorVO.class, "hypervisorType", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final Long id = cmd.getId();
+        final Long osTypeId = cmd.getOsTypeId();
+        final String hypervisor = cmd.getHypervisor();
+        final String hypervisorVersion = cmd.getHypervisorVersion();
+
+        //throw exception if hypervisor name is not passed, but version is
+        if (hypervisorVersion != null && (hypervisor == null || hypervisor.isEmpty())) {
+            throw new InvalidParameterValueException("Hypervisor version parameter cannot be used without specifying a hypervisor : XenServer, KVM or VMware");
+        }
+
+        final SearchCriteria<GuestOSHypervisorVO> sc = _guestOSHypervisorDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (osTypeId != null) {
+            sc.addAnd("guestOsId", SearchCriteria.Op.EQ, osTypeId);
+        }
+
+        if (hypervisor != null) {
+            sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisor);
+        }
+
+        if (hypervisorVersion != null) {
+            sc.addAnd("hypervisorVersion", SearchCriteria.Op.EQ, hypervisorVersion);
+        }
+
+        final Pair<List<GuestOSHypervisorVO>, Integer> result = _guestOSHypervisorDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends GuestOSHypervisor>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding new guest OS to hypervisor name mapping", create = true)
+    public GuestOSHypervisor addGuestOsMapping(final AddGuestOsMappingCmd cmd) {
+        final Long osTypeId = cmd.getOsTypeId();
+        final String osStdName = cmd.getOsStdName();
+        final String hypervisor = cmd.getHypervisor();
+        final String hypervisorVersion = cmd.getHypervisorVersion();
+        final String osNameForHypervisor = cmd.getOsNameForHypervisor();
+        GuestOS guestOs = null;
+
+        if (osTypeId == null && (osStdName == null || osStdName.isEmpty())) {
+            throw new InvalidParameterValueException("Please specify either a guest OS name or UUID");
+        }
+
+        final HypervisorType hypervisorType = HypervisorType.getType(hypervisor);
+
+        if (!(hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.XenServer || hypervisorType == HypervisorType.VMware)) {
+            throw new InvalidParameterValueException("Please specify a valid hypervisor : XenServer, KVM or VMware");
+        }
+
+        final HypervisorCapabilitiesVO hypervisorCapabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
+        if (hypervisorCapabilities == null) {
+            throw new InvalidParameterValueException("Please specify a valid hypervisor and supported version");
+        }
+
+        //by this point either osTypeId or osStdType is non-empty. Find by either of them. ID takes preference if both are specified
+        if (osTypeId != null) {
+            guestOs = ApiDBUtils.findGuestOSById(osTypeId);
+        } else if (osStdName != null) {
+            guestOs = ApiDBUtils.findGuestOSByDisplayName(osStdName);
+        }
+
+        if (guestOs == null) {
+            throw new InvalidParameterValueException("Unable to find the guest OS by name or UUID");
+        }
+        //check for duplicates
+        final GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisorAndUserDefined(guestOs.getId(), hypervisorType.toString(), hypervisorVersion, true);
+
+        if (duplicate != null) {
+            throw new InvalidParameterValueException(
+                    "Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : " + guestOs.getDisplayName() + " already exists!");
+        }
+        final GuestOSHypervisorVO guestOsMapping = new GuestOSHypervisorVO();
+        guestOsMapping.setGuestOsId(guestOs.getId());
+        guestOsMapping.setGuestOsName(osNameForHypervisor);
+        guestOsMapping.setHypervisorType(hypervisorType.toString());
+        guestOsMapping.setHypervisorVersion(hypervisorVersion);
+        guestOsMapping.setIsUserDefined(true);
+        return _guestOSHypervisorDao.persist(guestOsMapping);
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding a new guest OS to hypervisor name mapping", async = true)
+    public GuestOSHypervisor getAddedGuestOsMapping(final Long guestOsMappingId) {
+        return getGuestOsHypervisor(guestOsMappingId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding new guest OS type", create = true)
+    public GuestOS addGuestOs(final AddGuestOsCmd cmd) {
+        final Long categoryId = cmd.getOsCategoryId();
+        final String displayName = cmd.getOsDisplayName();
+        final String name = cmd.getOsName();
+
+        final GuestOSCategoryVO guestOsCategory = ApiDBUtils.findGuestOsCategoryById(categoryId);
+        if (guestOsCategory == null) {
+            throw new InvalidParameterValueException("Guest OS category not found. Please specify a valid Guest OS category");
+        }
+
+        final GuestOS guestOs = ApiDBUtils.findGuestOSByDisplayName(displayName);
+        if (guestOs != null) {
+            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique name");
+        }
+
+        s_logger.debug("GuestOSDetails");
+        final GuestOSVO guestOsVo = new GuestOSVO();
+        guestOsVo.setCategoryId(categoryId.longValue());
+        guestOsVo.setDisplayName(displayName);
+        guestOsVo.setName(name);
+        guestOsVo.setIsUserDefined(true);
+        final GuestOS guestOsPersisted = _guestOSDao.persist(guestOsVo);
+
+        if (cmd.getDetails() != null && !cmd.getDetails().isEmpty()) {
+            Map<String, String> detailsMap = cmd.getDetails();
+            for (Object key : detailsMap.keySet()) {
+                _guestOsDetailsDao.addDetail(guestOsPersisted.getId(), (String)key, detailsMap.get(key), false);
+            }
+        }
+
+        return guestOsPersisted;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding a new guest OS type", async = true)
+    public GuestOS getAddedGuestOs(final Long guestOsId) {
+        return getGuestOs(guestOsId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_UPDATE, eventDescription = "updating guest OS type", async = true)
+    public GuestOS updateGuestOs(final UpdateGuestOsCmd cmd) {
+        final Long id = cmd.getId();
+        final String displayName = cmd.getOsDisplayName();
+
+        //check if guest OS exists
+        final GuestOS guestOsHandle = ApiDBUtils.findGuestOSById(id);
+        if (guestOsHandle == null) {
+            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
+        }
+
+        if (!guestOsHandle.isUserDefined()) {
+            throw new InvalidParameterValueException("Unable to modify system defined guest OS");
+        }
+
+        if (cmd.getDetails() != null && !cmd.getDetails().isEmpty()) {
+            Map<String, String> detailsMap = cmd.getDetails();
+            for (Object key : detailsMap.keySet()) {
+                _guestOsDetailsDao.addDetail(id, (String)key, detailsMap.get(key), false);
+            }
+        }
+
+        //Check if update is needed
+        if (displayName.equals(guestOsHandle.getDisplayName())) {
+            return guestOsHandle;
+        }
+
+        //Check if another Guest OS by same name exists
+        final GuestOS duplicate = ApiDBUtils.findGuestOSByDisplayName(displayName);
+        if (duplicate != null) {
+            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique guest OS name");
+        }
+        final GuestOSVO guestOs = _guestOSDao.createForUpdate(id);
+        guestOs.setDisplayName(displayName);
+        if (_guestOSDao.update(id, guestOs)) {
+            return _guestOSDao.findById(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_REMOVE, eventDescription = "removing guest OS type", async = true)
+    public boolean removeGuestOs(final RemoveGuestOsCmd cmd) {
+        final Long id = cmd.getId();
+
+        //check if guest OS exists
+        final GuestOS guestOs = ApiDBUtils.findGuestOSById(id);
+        if (guestOs == null) {
+            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
+        }
+
+        if (!guestOs.isUserDefined()) {
+            throw new InvalidParameterValueException("Unable to remove system defined guest OS");
+        }
+
+        return _guestOSDao.remove(id);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_UPDATE, eventDescription = "updating guest OS mapping", async = true)
+    public GuestOSHypervisor updateGuestOsMapping(final UpdateGuestOsMappingCmd cmd) {
+        final Long id = cmd.getId();
+        final String osNameForHypervisor = cmd.getOsNameForHypervisor();
+
+        //check if mapping exists
+        final GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
+        if (guestOsHypervisorHandle == null) {
+            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
+        }
+
+        if (!guestOsHypervisorHandle.getIsUserDefined()) {
+            throw new InvalidParameterValueException("Unable to modify system defined Guest OS mapping");
+        }
+
+        final GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(id);
+        guestOsHypervisor.setGuestOsName(osNameForHypervisor);
+        if (_guestOSHypervisorDao.update(id, guestOsHypervisor)) {
+            return _guestOSHypervisorDao.findById(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_REMOVE, eventDescription = "removing guest OS mapping", async = true)
+    public boolean removeGuestOsMapping(final RemoveGuestOsMappingCmd cmd) {
+        final Long id = cmd.getId();
+
+        //check if mapping exists
+        final GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
+        if (guestOsHypervisorHandle == null) {
+            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
+        }
+
+        if (!guestOsHypervisorHandle.getIsUserDefined()) {
+            throw new InvalidParameterValueException("Unable to remove system defined Guest OS mapping");
+        }
+
+        return _guestOSHypervisorDao.removeGuestOsMapping(id);
+
+    }
+
+    protected ConsoleProxyInfo getConsoleProxyForVm(final long dataCenterId, final long userVmId) {
+        return _consoleProxyMgr.assignProxy(dataCenterId, userVmId);
+    }
+
+    private ConsoleProxyVO startConsoleProxy(final long instanceId) {
+        return _consoleProxyMgr.startProxy(instanceId, true);
+    }
+
+    private ConsoleProxyVO stopConsoleProxy(final VMInstanceVO systemVm, final boolean isForced) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+
+        _itMgr.advanceStop(systemVm.getUuid(), isForced);
+        return _consoleProxyDao.findById(systemVm.getId());
+    }
+
+    private ConsoleProxyVO rebootConsoleProxy(final long instanceId) {
+        _consoleProxyMgr.rebootProxy(instanceId);
+        return _consoleProxyDao.findById(instanceId);
+    }
+
+    protected ConsoleProxyVO destroyConsoleProxy(final long instanceId) {
+        final ConsoleProxyVO proxy = _consoleProxyDao.findById(instanceId);
+
+        if (_consoleProxyMgr.destroyProxy(instanceId)) {
+            return proxy;
+        }
+        return null;
+    }
+
+    @Override
+    public String getConsoleAccessUrlRoot(final long vmId) {
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm != null) {
+            final ConsoleProxyInfo proxy = getConsoleProxyForVm(vm.getDataCenterId(), vmId);
+            if (proxy != null) {
+                return proxy.getProxyImageUrl();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Pair<String, Integer> getVncPort(final VirtualMachine vm) {
+        if (vm.getHostId() == null) {
+            s_logger.warn("VM " + vm.getHostName() + " does not have host, return -1 for its VNC port");
+            return new Pair<String, Integer>(null, -1);
+        }
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Trying to retrieve VNC port from agent about VM " + vm.getHostName());
+        }
+
+        final GetVncPortAnswer answer = (GetVncPortAnswer)_agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
+        if (answer != null && answer.getResult()) {
+            return new Pair<String, Integer>(answer.getAddress(), answer.getPort());
+        }
+
+        return new Pair<String, Integer>(null, -1);
+    }
+
+    @Override
+    public Pair<List<? extends Alert>, Integer> searchForAlerts(final ListAlertsCmd cmd) {
+        final Filter searchFilter = new Filter(AlertVO.class, "lastSent", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchCriteria<AlertVO> sc = _alertDao.createSearchCriteria();
+
+        final Object id = cmd.getId();
+        final Object type = cmd.getType();
+        final Object keyword = cmd.getKeyword();
+        final Object name = cmd.getName();
+
+        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+        if (zoneId != null) {
+            sc.addAnd("data_center_id", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        if (keyword != null) {
+            final SearchCriteria<AlertVO> ssc = _alertDao.createSearchCriteria();
+            ssc.addOr("subject", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("subject", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (type != null) {
+            sc.addAnd("type", SearchCriteria.Op.EQ, type);
+        }
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+
+        sc.addAnd("archived", SearchCriteria.Op.EQ, false);
+        final Pair<List<AlertVO>, Integer> result = _alertDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Alert>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public boolean archiveAlerts(final ArchiveAlertsCmd cmd) {
+        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
+        final boolean result = _alertDao.archiveAlert(cmd.getIds(), cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), zoneId);
+        return result;
+    }
+
+    @Override
+    public boolean deleteAlerts(final DeleteAlertsCmd cmd) {
+        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), null);
+        final boolean result = _alertDao.deleteAlert(cmd.getIds(), cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), zoneId);
+        return result;
+    }
+
+    @Override
+    public List<CapacityVO> listTopConsumedResources(final ListCapacityCmd cmd) {
+
+        final Integer capacityType = cmd.getType();
+        Long zoneId = cmd.getZoneId();
+        final Long podId = cmd.getPodId();
+        final Long clusterId = cmd.getClusterId();
+        final Boolean fetchLatest = cmd.getFetchLatest();
+
+        if (clusterId != null) {
+            throw new InvalidParameterValueException("Currently clusterId param is not suppoerted");
+        }
+        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
+
+        if (fetchLatest != null && fetchLatest) {
+            _alertMgr.recalculateCapacity();
+        }
+        List<SummedCapacity> summedCapacities = new ArrayList<SummedCapacity>();
+
+        if (zoneId == null && podId == null) {// Group by Zone, capacity type
+            final List<SummedCapacity> summedCapacitiesAtZone = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 1, cmd.getPageSizeVal());
+            if (summedCapacitiesAtZone != null) {
+                summedCapacities.addAll(summedCapacitiesAtZone);
+            }
+        } else if (podId == null) {// Group by Pod, capacity type
+            final List<SummedCapacity> summedCapacitiesAtPod = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 2, cmd.getPageSizeVal());
+            if (summedCapacitiesAtPod != null) {
+                summedCapacities.addAll(summedCapacitiesAtPod);
+            }
+        } else { // Group by Cluster, capacity type
+            final List<SummedCapacity> summedCapacitiesAtCluster = _capacityDao.listCapacitiesGroupedByLevelAndType(capacityType, zoneId, podId, clusterId, 3, cmd.getPageSizeVal());
+            if (summedCapacitiesAtCluster != null) {
+                summedCapacities.addAll(summedCapacitiesAtCluster);
+            }
+        }
+
+        List<SummedCapacity> summedCapacitiesForSecStorage = getStorageUsed(clusterId, podId, zoneId, capacityType);
+        if (summedCapacitiesForSecStorage != null) {
+            summedCapacities.addAll(summedCapacitiesForSecStorage);
+        }
+
+        // Sort Capacities
+        Collections.sort(summedCapacities, new Comparator<SummedCapacity>() {
+            @Override
+            public int compare(final SummedCapacity arg0, final SummedCapacity arg1) {
+                if (arg0.getPercentUsed() < arg1.getPercentUsed()) {
+                    return 1;
+                } else if (arg0.getPercentUsed().equals(arg1.getPercentUsed())) {
+                    return 0;
+                }
+                return -1;
+            }
+        });
+
+        final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
+
+        Integer pageSize = null;
+        try {
+            pageSize = Integer.valueOf(cmd.getPageSizeVal().toString());
+        } catch (final IllegalArgumentException e) {
+            throw new InvalidParameterValueException("pageSize " + cmd.getPageSizeVal() + " is out of Integer range is not supported for this call");
+        }
+
+        summedCapacities = summedCapacities.subList(0, summedCapacities.size() < cmd.getPageSizeVal() ? summedCapacities.size() : pageSize);
+        for (final SummedCapacity summedCapacity : summedCapacities) {
+            final CapacityVO capacity = new CapacityVO(summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getCapacityType(),
+                    summedCapacity.getPercentUsed());
+            capacity.setUsedCapacity(summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity());
+            capacity.setTotalCapacity(summedCapacity.getTotalCapacity());
+            capacities.add(capacity);
+        }
+        return capacities;
+    }
+
+    List<SummedCapacity> getStorageUsed(Long clusterId, Long podId, Long zoneId, Integer capacityType) {
+        if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) {
+            final List<SummedCapacity> list = new ArrayList<SummedCapacity>();
+            if (zoneId != null) {
+                final DataCenterVO zone = ApiDBUtils.findZoneById(zoneId);
+                if (zone == null || zone.getAllocationState() == AllocationState.Disabled) {
+                    return null;
+                }
+                List<CapacityVO> capacities = new ArrayList<CapacityVO>();
+                capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
+                capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
+                for (CapacityVO capacity : capacities) {
+                    if (capacity.getTotalCapacity() != 0) {
+                        capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
+                    } else {
+                        capacity.setUsedPercentage(0);
+                    }
+                    final SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(), capacity.getCapacityType(),
+                            capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
+                    list.add(summedCapacity);
+                }
+            } else {
+                List<DataCenterVO> dcList = _dcDao.listEnabledZones();
+                for (DataCenterVO dc : dcList) {
+                    List<CapacityVO> capacities = new ArrayList<CapacityVO>();
+                    capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, dc.getId()));
+                    capacities.add(_storageMgr.getStoragePoolUsedStats(null, null, null, dc.getId()));
+                    for (CapacityVO capacity : capacities) {
+                        if (capacity.getTotalCapacity() != 0) {
+                            capacity.setUsedPercentage((float)capacity.getUsedCapacity() / capacity.getTotalCapacity());
+                        } else {
+                            capacity.setUsedPercentage(0);
+                        }
+                        SummedCapacity summedCapacity = new SummedCapacity(capacity.getUsedCapacity(), capacity.getTotalCapacity(), capacity.getUsedPercentage(), capacity.getCapacityType(),
+                                capacity.getDataCenterId(), capacity.getPodId(), capacity.getClusterId());
+                        list.add(summedCapacity);
+                    }
+                }// End of for
+            }
+            return list;
+        }
+        return null;
+    }
+
+    @Override
+    public List<CapacityVO> listCapacities(final ListCapacityCmd cmd) {
+
+        final Integer capacityType = cmd.getType();
+        Long zoneId = cmd.getZoneId();
+        final Long podId = cmd.getPodId();
+        final Long clusterId = cmd.getClusterId();
+        final Boolean fetchLatest = cmd.getFetchLatest();
+
+        zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), zoneId);
+        if (fetchLatest != null && fetchLatest) {
+            _alertMgr.recalculateCapacity();
+        }
+
+        final List<SummedCapacity> summedCapacities = _capacityDao.findCapacityBy(capacityType, zoneId, podId, clusterId);
+        final List<CapacityVO> capacities = new ArrayList<CapacityVO>();
+
+        for (final SummedCapacity summedCapacity : summedCapacities) {
+            final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(), summedCapacity.getPodId(), summedCapacity.getClusterId(),
+                    summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType());
+            capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity());
+            capacities.add(capacity);
+        }
+
+        // op_host_Capacity contains only allocated stats and the real time
+        // stats are stored "in memory".
+        // Show Sec. Storage only when the api is invoked for the zone layer.
+        List<DataCenterVO> dcList = new ArrayList<DataCenterVO>();
+        if (zoneId == null && podId == null && clusterId == null) {
+            dcList = ApiDBUtils.listZones();
+        } else if (zoneId != null) {
+            dcList.add(ApiDBUtils.findZoneById(zoneId));
+        } else {
+            if (clusterId != null) {
+                zoneId = ApiDBUtils.findClusterById(clusterId).getDataCenterId();
+            } else {
+                zoneId = ApiDBUtils.findPodById(podId).getDataCenterId();
+            }
+            if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
+                capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
+            }
+        }
+
+        for (final DataCenterVO zone : dcList) {
+            zoneId = zone.getId();
+            if ((capacityType == null || capacityType == Capacity.CAPACITY_TYPE_SECONDARY_STORAGE) && podId == null && clusterId == null) {
+                capacities.add(_storageMgr.getSecondaryStorageUsedStats(null, zoneId));
+            }
+            if (capacityType == null || capacityType == Capacity.CAPACITY_TYPE_STORAGE) {
+                capacities.add(_storageMgr.getStoragePoolUsedStats(null, clusterId, podId, zoneId));
+            }
+        }
+        return capacities;
+    }
+
+    @Override
+    public long getMemoryOrCpuCapacityByHost(final Long hostId, final short capacityType) {
+
+        final CapacityVO capacity = _capacityDao.findByHostIdType(hostId, capacityType);
+        return capacity == null ? 0 : capacity.getReservedCapacity() + capacity.getUsedCapacity();
+
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateAccountCmd.class);
+        cmdList.add(DeleteAccountCmd.class);
+        cmdList.add(DisableAccountCmd.class);
+        cmdList.add(EnableAccountCmd.class);
+        cmdList.add(LockAccountCmd.class);
+        cmdList.add(UpdateAccountCmd.class);
+        cmdList.add(CreateCounterCmd.class);
+        cmdList.add(DeleteCounterCmd.class);
+        cmdList.add(AddClusterCmd.class);
+        cmdList.add(DeleteClusterCmd.class);
+        cmdList.add(ListClustersCmd.class);
+        cmdList.add(UpdateClusterCmd.class);
+        cmdList.add(ListCfgsByCmd.class);
+        cmdList.add(ListHypervisorCapabilitiesCmd.class);
+        cmdList.add(UpdateCfgCmd.class);
+        cmdList.add(UpdateHypervisorCapabilitiesCmd.class);
+        cmdList.add(CreateDomainCmd.class);
+        cmdList.add(DeleteDomainCmd.class);
+        cmdList.add(ListDomainChildrenCmd.class);
+        cmdList.add(ListDomainsCmd.class);
+        cmdList.add(ListDomainsCmdByAdmin.class);
+        cmdList.add(UpdateDomainCmd.class);
+        cmdList.add(AddHostCmd.class);
+        cmdList.add(AddSecondaryStorageCmd.class);
+        cmdList.add(CancelMaintenanceCmd.class);
+        cmdList.add(DeleteHostCmd.class);
+        cmdList.add(ListHostsCmd.class);
+        cmdList.add(ListHostTagsCmd.class);
+        cmdList.add(FindHostsForMigrationCmd.class);
+        cmdList.add(PrepareForMaintenanceCmd.class);
+        cmdList.add(ReconnectHostCmd.class);
+        cmdList.add(UpdateHostCmd.class);
+        cmdList.add(UpdateHostPasswordCmd.class);
+        cmdList.add(AddNetworkDeviceCmd.class);
+        cmdList.add(AddNetworkServiceProviderCmd.class);
+        cmdList.add(CreateNetworkOfferingCmd.class);
+        cmdList.add(CreatePhysicalNetworkCmd.class);
+        cmdList.add(CreateStorageNetworkIpRangeCmd.class);
+        cmdList.add(DeleteNetworkDeviceCmd.class);
+        cmdList.add(DeleteNetworkOfferingCmd.class);
+        cmdList.add(DeleteNetworkServiceProviderCmd.class);
+        cmdList.add(DeletePhysicalNetworkCmd.class);
+        cmdList.add(DeleteStorageNetworkIpRangeCmd.class);
+        cmdList.add(ListNetworkDeviceCmd.class);
+        cmdList.add(ListNetworkServiceProvidersCmd.class);
+        cmdList.add(ListPhysicalNetworksCmd.class);
+        cmdList.add(ListStorageNetworkIpRangeCmd.class);
+        cmdList.add(ListSupportedNetworkServicesCmd.class);
+        cmdList.add(UpdateNetworkOfferingCmd.class);
+        cmdList.add(UpdateNetworkServiceProviderCmd.class);
+        cmdList.add(UpdatePhysicalNetworkCmd.class);
+        cmdList.add(UpdateStorageNetworkIpRangeCmd.class);
+        cmdList.add(DedicateGuestVlanRangeCmd.class);
+        cmdList.add(ListDedicatedGuestVlanRangesCmd.class);
+        cmdList.add(ReleaseDedicatedGuestVlanRangeCmd.class);
+        cmdList.add(CreateDiskOfferingCmd.class);
+        cmdList.add(CreateServiceOfferingCmd.class);
+        cmdList.add(DeleteDiskOfferingCmd.class);
+        cmdList.add(DeleteServiceOfferingCmd.class);
+        cmdList.add(UpdateDiskOfferingCmd.class);
+        cmdList.add(UpdateServiceOfferingCmd.class);
+        cmdList.add(CreatePodCmd.class);
+        cmdList.add(DeletePodCmd.class);
+        cmdList.add(ListPodsByCmd.class);
+        cmdList.add(UpdatePodCmd.class);
+        cmdList.add(AddRegionCmd.class);
+        cmdList.add(RemoveRegionCmd.class);
+        cmdList.add(UpdateRegionCmd.class);
+        cmdList.add(ListAlertsCmd.class);
+        cmdList.add(ListCapacityCmd.class);
+        cmdList.add(UploadCustomCertificateCmd.class);
+        cmdList.add(ConfigureVirtualRouterElementCmd.class);
+        cmdList.add(CreateVirtualRouterElementCmd.class);
+        cmdList.add(DestroyRouterCmd.class);
+        cmdList.add(ListRoutersCmd.class);
+        cmdList.add(ListVirtualRouterElementsCmd.class);
+        cmdList.add(RebootRouterCmd.class);
+        cmdList.add(StartRouterCmd.class);
+        cmdList.add(StopRouterCmd.class);
+        cmdList.add(UpgradeRouterCmd.class);
+        cmdList.add(AddSwiftCmd.class);
+        cmdList.add(CancelPrimaryStorageMaintenanceCmd.class);
+        cmdList.add(CreateStoragePoolCmd.class);
+        cmdList.add(DeletePoolCmd.class);
+        cmdList.add(ListSwiftsCmd.class);
+        cmdList.add(ListStoragePoolsCmd.class);
+        cmdList.add(ListStorageTagsCmd.class);
+        cmdList.add(FindStoragePoolsForMigrationCmd.class);
+        cmdList.add(PreparePrimaryStorageForMaintenanceCmd.class);
+        cmdList.add(UpdateStoragePoolCmd.class);
+        cmdList.add(DestroySystemVmCmd.class);
+        cmdList.add(ListSystemVMsCmd.class);
+        cmdList.add(MigrateSystemVMCmd.class);
+        cmdList.add(RebootSystemVmCmd.class);
+        cmdList.add(StartSystemVMCmd.class);
+        cmdList.add(StopSystemVmCmd.class);
+        cmdList.add(UpgradeSystemVMCmd.class);
+        cmdList.add(PrepareTemplateCmd.class);
+        cmdList.add(AddTrafficMonitorCmd.class);
+        cmdList.add(AddTrafficTypeCmd.class);
+        cmdList.add(DeleteTrafficMonitorCmd.class);
+        cmdList.add(DeleteTrafficTypeCmd.class);
+        cmdList.add(GenerateUsageRecordsCmd.class);
+        cmdList.add(GetUsageRecordsCmd.class);
+        cmdList.add(RemoveRawUsageRecordsCmd.class);
+        cmdList.add(ListTrafficMonitorsCmd.class);
+        cmdList.add(ListTrafficTypeImplementorsCmd.class);
+        cmdList.add(ListTrafficTypesCmd.class);
+        cmdList.add(ListUsageTypesCmd.class);
+        cmdList.add(UpdateTrafficTypeCmd.class);
+        cmdList.add(CreateUserCmd.class);
+        cmdList.add(DeleteUserCmd.class);
+        cmdList.add(DisableUserCmd.class);
+        cmdList.add(EnableUserCmd.class);
+        cmdList.add(GetUserCmd.class);
+        cmdList.add(ListUsersCmd.class);
+        cmdList.add(LockUserCmd.class);
+        cmdList.add(MoveUserCmd.class);
+        cmdList.add(RegisterCmd.class);
+        cmdList.add(UpdateUserCmd.class);
+        cmdList.add(CreateVlanIpRangeCmd.class);
+        cmdList.add(DeleteVlanIpRangeCmd.class);
+        cmdList.add(ListVlanIpRangesCmd.class);
+        cmdList.add(DedicatePublicIpRangeCmd.class);
+        cmdList.add(ReleasePublicIpRangeCmd.class);
+        cmdList.add(AssignVMCmd.class);
+        cmdList.add(MigrateVMCmd.class);
+        cmdList.add(MigrateVirtualMachineWithVolumeCmd.class);
+        cmdList.add(RecoverVMCmd.class);
+        cmdList.add(CreatePrivateGatewayCmd.class);
+        cmdList.add(CreateVPCOfferingCmd.class);
+        cmdList.add(DeletePrivateGatewayCmd.class);
+        cmdList.add(DeleteVPCOfferingCmd.class);
+        cmdList.add(UpdateVPCOfferingCmd.class);
+        cmdList.add(CreateZoneCmd.class);
+        cmdList.add(DeleteZoneCmd.class);
+        cmdList.add(MarkDefaultZoneForAccountCmd.class);
+        cmdList.add(UpdateZoneCmd.class);
+        cmdList.add(AddAccountToProjectCmd.class);
+        cmdList.add(DeleteAccountFromProjectCmd.class);
+        cmdList.add(ListAccountsCmd.class);
+        cmdList.add(ListProjectAccountsCmd.class);
+        cmdList.add(AssociateIPAddrCmd.class);
+        cmdList.add(DisassociateIPAddrCmd.class);
+        cmdList.add(ListPublicIpAddressesCmd.class);
+        cmdList.add(CreateAutoScalePolicyCmd.class);
+        cmdList.add(CreateAutoScaleVmGroupCmd.class);
+        cmdList.add(CreateAutoScaleVmProfileCmd.class);
+        cmdList.add(CreateConditionCmd.class);
+        cmdList.add(DeleteAutoScalePolicyCmd.class);
+        cmdList.add(DeleteAutoScaleVmGroupCmd.class);
+        cmdList.add(DeleteAutoScaleVmProfileCmd.class);
+        cmdList.add(DeleteConditionCmd.class);
+        cmdList.add(DisableAutoScaleVmGroupCmd.class);
+        cmdList.add(EnableAutoScaleVmGroupCmd.class);
+        cmdList.add(ListAutoScalePoliciesCmd.class);
+        cmdList.add(ListAutoScaleVmGroupsCmd.class);
+        cmdList.add(ListAutoScaleVmProfilesCmd.class);
+        cmdList.add(ListConditionsCmd.class);
+        cmdList.add(ListCountersCmd.class);
+        cmdList.add(UpdateAutoScalePolicyCmd.class);
+        cmdList.add(UpdateAutoScaleVmGroupCmd.class);
+        cmdList.add(UpdateAutoScaleVmProfileCmd.class);
+        cmdList.add(ListCapabilitiesCmd.class);
+        cmdList.add(ListEventsCmd.class);
+        cmdList.add(ListEventTypesCmd.class);
+        cmdList.add(CreateEgressFirewallRuleCmd.class);
+        cmdList.add(CreateFirewallRuleCmd.class);
+        cmdList.add(CreatePortForwardingRuleCmd.class);
+        cmdList.add(DeleteEgressFirewallRuleCmd.class);
+        cmdList.add(DeleteFirewallRuleCmd.class);
+        cmdList.add(DeletePortForwardingRuleCmd.class);
+        cmdList.add(ListEgressFirewallRulesCmd.class);
+        cmdList.add(ListFirewallRulesCmd.class);
+        cmdList.add(ListPortForwardingRulesCmd.class);
+        cmdList.add(UpdatePortForwardingRuleCmd.class);
+        cmdList.add(ListGuestOsCategoriesCmd.class);
+        cmdList.add(ListGuestOsCmd.class);
+        cmdList.add(ListGuestOsMappingCmd.class);
+        cmdList.add(AddGuestOsCmd.class);
+        cmdList.add(AddGuestOsMappingCmd.class);
+        cmdList.add(UpdateGuestOsCmd.class);
+        cmdList.add(UpdateGuestOsMappingCmd.class);
+        cmdList.add(RemoveGuestOsCmd.class);
+        cmdList.add(RemoveGuestOsMappingCmd.class);
+        cmdList.add(AttachIsoCmd.class);
+        cmdList.add(CopyIsoCmd.class);
+        cmdList.add(DeleteIsoCmd.class);
+        cmdList.add(DetachIsoCmd.class);
+        cmdList.add(ExtractIsoCmd.class);
+        cmdList.add(ListIsoPermissionsCmd.class);
+        cmdList.add(ListIsosCmd.class);
+        cmdList.add(RegisterIsoCmd.class);
+        cmdList.add(UpdateIsoCmd.class);
+        cmdList.add(UpdateIsoPermissionsCmd.class);
+        cmdList.add(ListAsyncJobsCmd.class);
+        cmdList.add(QueryAsyncJobResultCmd.class);
+        cmdList.add(AssignToLoadBalancerRuleCmd.class);
+        cmdList.add(CreateLBStickinessPolicyCmd.class);
+        cmdList.add(CreateLBHealthCheckPolicyCmd.class);
+        cmdList.add(CreateLoadBalancerRuleCmd.class);
+        cmdList.add(DeleteLBStickinessPolicyCmd.class);
+        cmdList.add(DeleteLBHealthCheckPolicyCmd.class);
+        cmdList.add(DeleteLoadBalancerRuleCmd.class);
+        cmdList.add(ListLBStickinessPoliciesCmd.class);
+        cmdList.add(ListLBHealthCheckPoliciesCmd.class);
+        cmdList.add(ListLoadBalancerRuleInstancesCmd.class);
+        cmdList.add(ListLoadBalancerRulesCmd.class);
+        cmdList.add(RemoveFromLoadBalancerRuleCmd.class);
+        cmdList.add(UpdateLoadBalancerRuleCmd.class);
+        cmdList.add(CreateIpForwardingRuleCmd.class);
+        cmdList.add(DeleteIpForwardingRuleCmd.class);
+        cmdList.add(DisableStaticNatCmd.class);
+        cmdList.add(EnableStaticNatCmd.class);
+        cmdList.add(ListIpForwardingRulesCmd.class);
+        cmdList.add(CreateNetworkACLCmd.class);
+        cmdList.add(CreateNetworkCmd.class);
+        cmdList.add(DeleteNetworkACLCmd.class);
+        cmdList.add(DeleteNetworkCmd.class);
+        cmdList.add(ListNetworkACLsCmd.class);
+        cmdList.add(ListNetworkOfferingsCmd.class);
+        cmdList.add(ListNetworksCmd.class);
+        cmdList.add(RestartNetworkCmd.class);
+        cmdList.add(UpdateNetworkCmd.class);
+        cmdList.add(ListDiskOfferingsCmd.class);
+        cmdList.add(ListServiceOfferingsCmd.class);
+        cmdList.add(ActivateProjectCmd.class);
+        cmdList.add(CreateProjectCmd.class);
+        cmdList.add(DeleteProjectCmd.class);
+        cmdList.add(DeleteProjectInvitationCmd.class);
+        cmdList.add(ListProjectInvitationsCmd.class);
+        cmdList.add(ListProjectsCmd.class);
+        cmdList.add(SuspendProjectCmd.class);
+        cmdList.add(UpdateProjectCmd.class);
+        cmdList.add(UpdateProjectInvitationCmd.class);
+        cmdList.add(ListRegionsCmd.class);
+        cmdList.add(GetCloudIdentifierCmd.class);
+        cmdList.add(ListHypervisorsCmd.class);
+        cmdList.add(ListResourceLimitsCmd.class);
+        cmdList.add(UpdateResourceCountCmd.class);
+        cmdList.add(UpdateResourceLimitCmd.class);
+        cmdList.add(AuthorizeSecurityGroupEgressCmd.class);
+        cmdList.add(AuthorizeSecurityGroupIngressCmd.class);
+        cmdList.add(CreateSecurityGroupCmd.class);
+        cmdList.add(DeleteSecurityGroupCmd.class);
+        cmdList.add(ListSecurityGroupsCmd.class);
+        cmdList.add(RevokeSecurityGroupEgressCmd.class);
+        cmdList.add(RevokeSecurityGroupIngressCmd.class);
+        cmdList.add(CreateSnapshotCmd.class);
+        cmdList.add(CreateSnapshotFromVMSnapshotCmd.class);
+        cmdList.add(DeleteSnapshotCmd.class);
+        cmdList.add(ArchiveSnapshotCmd.class);
+        cmdList.add(CreateSnapshotPolicyCmd.class);
+        cmdList.add(UpdateSnapshotPolicyCmd.class);
+        cmdList.add(DeleteSnapshotPoliciesCmd.class);
+        cmdList.add(ListSnapshotPoliciesCmd.class);
+        cmdList.add(ListSnapshotsCmd.class);
+        cmdList.add(RevertSnapshotCmd.class);
+        cmdList.add(CreateSSHKeyPairCmd.class);
+        cmdList.add(DeleteSSHKeyPairCmd.class);
+        cmdList.add(ListSSHKeyPairsCmd.class);
+        cmdList.add(RegisterSSHKeyPairCmd.class);
+        cmdList.add(CreateTagsCmd.class);
+        cmdList.add(DeleteTagsCmd.class);
+        cmdList.add(ListTagsCmd.class);
+        cmdList.add(CopyTemplateCmd.class);
+        cmdList.add(CreateTemplateCmd.class);
+        cmdList.add(DeleteTemplateCmd.class);
+        cmdList.add(ExtractTemplateCmd.class);
+        cmdList.add(ListTemplatePermissionsCmd.class);
+        cmdList.add(ListTemplatesCmd.class);
+        cmdList.add(RegisterTemplateCmd.class);
+        cmdList.add(UpdateTemplateCmd.class);
+        cmdList.add(UpdateTemplatePermissionsCmd.class);
+        cmdList.add(AddNicToVMCmd.class);
+        cmdList.add(DeployVMCmd.class);
+        cmdList.add(DestroyVMCmd.class);
+        cmdList.add(ExpungeVMCmd.class);
+        cmdList.add(GetVMPasswordCmd.class);
+        cmdList.add(ListVMsCmd.class);
+        cmdList.add(ScaleVMCmd.class);
+        cmdList.add(RebootVMCmd.class);
+        cmdList.add(RemoveNicFromVMCmd.class);
+        cmdList.add(ResetVMPasswordCmd.class);
+        cmdList.add(ResetVMSSHKeyCmd.class);
+        cmdList.add(RestoreVMCmd.class);
+        cmdList.add(StartVMCmd.class);
+        cmdList.add(StopVMCmd.class);
+        cmdList.add(UpdateDefaultNicForVMCmd.class);
+        cmdList.add(UpdateVMCmd.class);
+        cmdList.add(UpgradeVMCmd.class);
+        cmdList.add(CreateVMGroupCmd.class);
+        cmdList.add(DeleteVMGroupCmd.class);
+        cmdList.add(ListVMGroupsCmd.class);
+        cmdList.add(UpdateVMGroupCmd.class);
+        cmdList.add(AttachVolumeCmd.class);
+        cmdList.add(CreateVolumeCmd.class);
+        cmdList.add(DeleteVolumeCmd.class);
+        cmdList.add(UpdateVolumeCmd.class);
+        cmdList.add(DetachVolumeCmd.class);
+        cmdList.add(ExtractVolumeCmd.class);
+        cmdList.add(ListVolumesCmd.class);
+        cmdList.add(MigrateVolumeCmd.class);
+        cmdList.add(ResizeVolumeCmd.class);
+        cmdList.add(UploadVolumeCmd.class);
+        cmdList.add(CreateStaticRouteCmd.class);
+        cmdList.add(CreateVPCCmd.class);
+        cmdList.add(DeleteStaticRouteCmd.class);
+        cmdList.add(DeleteVPCCmd.class);
+        cmdList.add(ListPrivateGatewaysCmd.class);
+        cmdList.add(ListStaticRoutesCmd.class);
+        cmdList.add(ListVPCOfferingsCmd.class);
+        cmdList.add(ListVPCsCmd.class);
+        cmdList.add(RestartVPCCmd.class);
+        cmdList.add(UpdateVPCCmd.class);
+        cmdList.add(AddVpnUserCmd.class);
+        cmdList.add(CreateRemoteAccessVpnCmd.class);
+        cmdList.add(CreateVpnConnectionCmd.class);
+        cmdList.add(CreateVpnCustomerGatewayCmd.class);
+        cmdList.add(CreateVpnGatewayCmd.class);
+        cmdList.add(DeleteRemoteAccessVpnCmd.class);
+        cmdList.add(DeleteVpnConnectionCmd.class);
+        cmdList.add(DeleteVpnCustomerGatewayCmd.class);
+        cmdList.add(DeleteVpnGatewayCmd.class);
+        cmdList.add(ListRemoteAccessVpnsCmd.class);
+        cmdList.add(ListVpnConnectionsCmd.class);
+        cmdList.add(ListVpnCustomerGatewaysCmd.class);
+        cmdList.add(ListVpnGatewaysCmd.class);
+        cmdList.add(ListVpnUsersCmd.class);
+        cmdList.add(RemoveVpnUserCmd.class);
+        cmdList.add(ResetVpnConnectionCmd.class);
+        cmdList.add(UpdateVpnCustomerGatewayCmd.class);
+        cmdList.add(ListZonesCmd.class);
+        cmdList.add(ListVMSnapshotCmd.class);
+        cmdList.add(CreateVMSnapshotCmd.class);
+        cmdList.add(RevertToVMSnapshotCmd.class);
+        cmdList.add(DeleteVMSnapshotCmd.class);
+        cmdList.add(AddIpToVmNicCmd.class);
+        cmdList.add(RemoveIpFromVmNicCmd.class);
+        cmdList.add(UpdateVmNicIpCmd.class);
+        cmdList.add(ListNicsCmd.class);
+        cmdList.add(ArchiveAlertsCmd.class);
+        cmdList.add(DeleteAlertsCmd.class);
+        cmdList.add(ArchiveEventsCmd.class);
+        cmdList.add(DeleteEventsCmd.class);
+        cmdList.add(CreateGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(DeleteGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(ListGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(UpdateGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(AssignToGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(RemoveFromGlobalLoadBalancerRuleCmd.class);
+        cmdList.add(ListStorageProvidersCmd.class);
+        cmdList.add(AddImageStoreCmd.class);
+        cmdList.add(AddImageStoreS3CMD.class);
+        cmdList.add(ListImageStoresCmd.class);
+        cmdList.add(DeleteImageStoreCmd.class);
+        cmdList.add(CreateSecondaryStagingStoreCmd.class);
+        cmdList.add(ListSecondaryStagingStoresCmd.class);
+        cmdList.add(DeleteSecondaryStagingStoreCmd.class);
+        cmdList.add(UpdateCloudToUseObjectStoreCmd.class);
+        cmdList.add(CreateApplicationLoadBalancerCmd.class);
+        cmdList.add(ListApplicationLoadBalancersCmd.class);
+        cmdList.add(DeleteApplicationLoadBalancerCmd.class);
+        cmdList.add(ConfigureInternalLoadBalancerElementCmd.class);
+        cmdList.add(CreateInternalLoadBalancerElementCmd.class);
+        cmdList.add(ListInternalLoadBalancerElementsCmd.class);
+        cmdList.add(CreateAffinityGroupCmd.class);
+        cmdList.add(DeleteAffinityGroupCmd.class);
+        cmdList.add(ListAffinityGroupsCmd.class);
+        cmdList.add(UpdateVMAffinityGroupCmd.class);
+        cmdList.add(ListAffinityGroupTypesCmd.class);
+        cmdList.add(CreatePortableIpRangeCmd.class);
+        cmdList.add(DeletePortableIpRangeCmd.class);
+        cmdList.add(ListPortableIpRangesCmd.class);
+        cmdList.add(ListDeploymentPlannersCmd.class);
+        cmdList.add(ReleaseHostReservationCmd.class);
+        cmdList.add(ScaleSystemVMCmd.class);
+        cmdList.add(AddResourceDetailCmd.class);
+        cmdList.add(RemoveResourceDetailCmd.class);
+        cmdList.add(ListResourceDetailsCmd.class);
+        cmdList.add(StopInternalLBVMCmd.class);
+        cmdList.add(StartInternalLBVMCmd.class);
+        cmdList.add(ListInternalLBVMsCmd.class);
+        cmdList.add(ListNetworkIsolationMethodsCmd.class);
+        cmdList.add(ListNetworkIsolationMethodsCmd.class);
+        cmdList.add(CreateNetworkACLListCmd.class);
+        cmdList.add(DeleteNetworkACLListCmd.class);
+        cmdList.add(ListNetworkACLListsCmd.class);
+        cmdList.add(ReplaceNetworkACLListCmd.class);
+        cmdList.add(UpdateNetworkACLItemCmd.class);
+        cmdList.add(MoveNetworkAclItemCmd.class);
+        cmdList.add(CleanVMReservationsCmd.class);
+        cmdList.add(UpgradeRouterTemplateCmd.class);
+        cmdList.add(UploadSslCertCmd.class);
+        cmdList.add(DeleteSslCertCmd.class);
+        cmdList.add(ListSslCertsCmd.class);
+        cmdList.add(AssignCertToLoadBalancerCmd.class);
+        cmdList.add(RemoveCertFromLoadBalancerCmd.class);
+        cmdList.add(GenerateAlertCmd.class);
+        cmdList.add(ListOvsElementsCmd.class);
+        cmdList.add(ConfigureOvsElementCmd.class);
+        cmdList.add(GetVMUserDataCmd.class);
+        cmdList.add(UpdateEgressFirewallRuleCmd.class);
+        cmdList.add(UpdateFirewallRuleCmd.class);
+        cmdList.add(UpdateNetworkACLListCmd.class);
+        cmdList.add(UpdateApplicationLoadBalancerCmd.class);
+        cmdList.add(UpdateIPAddrCmd.class);
+        cmdList.add(UpdateRemoteAccessVpnCmd.class);
+        cmdList.add(UpdateVpnConnectionCmd.class);
+        cmdList.add(UpdateVpnGatewayCmd.class);
+        // separated admin commands
+        cmdList.add(ListAccountsCmdByAdmin.class);
+        cmdList.add(ListZonesCmdByAdmin.class);
+        cmdList.add(ListTemplatesCmdByAdmin.class);
+        cmdList.add(CreateTemplateCmdByAdmin.class);
+        cmdList.add(CopyTemplateCmdByAdmin.class);
+        cmdList.add(RegisterTemplateCmdByAdmin.class);
+        cmdList.add(ListTemplatePermissionsCmdByAdmin.class);
+        cmdList.add(RegisterIsoCmdByAdmin.class);
+        cmdList.add(CopyIsoCmdByAdmin.class);
+        cmdList.add(ListIsosCmdByAdmin.class);
+        cmdList.add(AttachIsoCmdByAdmin.class);
+        cmdList.add(DetachIsoCmdByAdmin.class);
+        cmdList.add(ListIsoPermissionsCmdByAdmin.class);
+        cmdList.add(UpdateVMAffinityGroupCmdByAdmin.class);
+        cmdList.add(AddNicToVMCmdByAdmin.class);
+        cmdList.add(RemoveNicFromVMCmdByAdmin.class);
+        cmdList.add(UpdateDefaultNicForVMCmdByAdmin.class);
+        cmdList.add(ListLoadBalancerRuleInstancesCmdByAdmin.class);
+        cmdList.add(DeployVMCmdByAdmin.class);
+        cmdList.add(DestroyVMCmdByAdmin.class);
+        cmdList.add(RebootVMCmdByAdmin.class);
+        cmdList.add(ResetVMPasswordCmdByAdmin.class);
+        cmdList.add(ResetVMSSHKeyCmdByAdmin.class);
+        cmdList.add(RestoreVMCmdByAdmin.class);
+        cmdList.add(ScaleVMCmdByAdmin.class);
+        cmdList.add(StartVMCmdByAdmin.class);
+        cmdList.add(StopVMCmdByAdmin.class);
+        cmdList.add(UpdateVMCmdByAdmin.class);
+        cmdList.add(UpgradeVMCmdByAdmin.class);
+        cmdList.add(RevertToVMSnapshotCmdByAdmin.class);
+        cmdList.add(ListVMsCmdByAdmin.class);
+        cmdList.add(AttachVolumeCmdByAdmin.class);
+        cmdList.add(CreateVolumeCmdByAdmin.class);
+        cmdList.add(DetachVolumeCmdByAdmin.class);
+        cmdList.add(MigrateVolumeCmdByAdmin.class);
+        cmdList.add(ResizeVolumeCmdByAdmin.class);
+        cmdList.add(UpdateVolumeCmdByAdmin.class);
+        cmdList.add(UploadVolumeCmdByAdmin.class);
+        cmdList.add(ListVolumesCmdByAdmin.class);
+        cmdList.add(AssociateIPAddrCmdByAdmin.class);
+        cmdList.add(ListPublicIpAddressesCmdByAdmin.class);
+        cmdList.add(CreateNetworkCmdByAdmin.class);
+        cmdList.add(UpdateNetworkCmdByAdmin.class);
+        cmdList.add(ListNetworksCmdByAdmin.class);
+        cmdList.add(CreateVPCCmdByAdmin.class);
+        cmdList.add(ListVPCsCmdByAdmin.class);
+        cmdList.add(UpdateVPCCmdByAdmin.class);
+        cmdList.add(UpdateLBStickinessPolicyCmd.class);
+        cmdList.add(UpdateLBHealthCheckPolicyCmd.class);
+        cmdList.add(GetUploadParamsForTemplateCmd.class);
+        cmdList.add(GetUploadParamsForVolumeCmd.class);
+        cmdList.add(MigrateNetworkCmd.class);
+        cmdList.add(MigrateVPCCmd.class);
+        cmdList.add(AcquirePodIpCmdByAdmin.class);
+        cmdList.add(ReleasePodIpCmdByAdmin.class);
+        cmdList.add(CreateManagementNetworkIpRangeCmd.class);
+        cmdList.add(DeleteManagementNetworkIpRangeCmd.class);
+        cmdList.add(UploadTemplateDirectDownloadCertificateCmd.class);
+        cmdList.add(ListMgmtsCmd.class);
+
+        // Out-of-band management APIs for admins
+        cmdList.add(EnableOutOfBandManagementForHostCmd.class);
+        cmdList.add(DisableOutOfBandManagementForHostCmd.class);
+        cmdList.add(EnableOutOfBandManagementForClusterCmd.class);
+        cmdList.add(DisableOutOfBandManagementForClusterCmd.class);
+        cmdList.add(EnableOutOfBandManagementForZoneCmd.class);
+        cmdList.add(DisableOutOfBandManagementForZoneCmd.class);
+        cmdList.add(ConfigureOutOfBandManagementCmd.class);
+        cmdList.add(IssueOutOfBandManagementPowerActionCmd.class);
+        cmdList.add(ChangeOutOfBandManagementPasswordCmd.class);
+        cmdList.add(GetUserKeysCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return ManagementServer.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {vmPasswordLength, sshKeyLength};
+    }
+
+    protected class EventPurgeTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                final GlobalLock lock = GlobalLock.getInternLock("EventPurge");
+                if (lock == null) {
+                    s_logger.debug("Couldn't get the global lock");
+                    return;
+                }
+                if (!lock.lock(30)) {
+                    s_logger.debug("Couldn't lock the db");
+                    return;
+                }
+                try {
+                    final Calendar purgeCal = Calendar.getInstance();
+                    purgeCal.add(Calendar.DAY_OF_YEAR, -_purgeDelay);
+                    final Date purgeTime = purgeCal.getTime();
+                    s_logger.debug("Deleting events older than: " + purgeTime.toString());
+                    final List<EventVO> oldEvents = _eventDao.listOlderEvents(purgeTime);
+                    s_logger.debug("Found " + oldEvents.size() + " events to be purged");
+                    for (final EventVO event : oldEvents) {
+                        _eventDao.expunge(event.getId());
+                    }
+                } catch (final Exception e) {
+                    s_logger.error("Exception ", e);
+                } finally {
+                    lock.unlock();
+                }
+            } catch (final Exception e) {
+                s_logger.error("Exception ", e);
+            }
+        }
+    }
+
+    protected class AlertPurgeTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                final GlobalLock lock = GlobalLock.getInternLock("AlertPurge");
+                if (lock == null) {
+                    s_logger.debug("Couldn't get the global lock");
+                    return;
+                }
+                if (!lock.lock(30)) {
+                    s_logger.debug("Couldn't lock the db");
+                    return;
+                }
+                try {
+                    final Calendar purgeCal = Calendar.getInstance();
+                    purgeCal.add(Calendar.DAY_OF_YEAR, -_alertPurgeDelay);
+                    final Date purgeTime = purgeCal.getTime();
+                    s_logger.debug("Deleting alerts older than: " + purgeTime.toString());
+                    final List<AlertVO> oldAlerts = _alertDao.listOlderAlerts(purgeTime);
+                    s_logger.debug("Found " + oldAlerts.size() + " events to be purged");
+                    for (final AlertVO alert : oldAlerts) {
+                        _alertDao.expunge(alert.getId());
+                    }
+                } catch (final Exception e) {
+                    s_logger.error("Exception ", e);
+                } finally {
+                    lock.unlock();
+                }
+            } catch (final Exception e) {
+                s_logger.error("Exception ", e);
+            }
+        }
+    }
+
+    private SecondaryStorageVmVO startSecondaryStorageVm(final long instanceId) {
+        return _secStorageVmMgr.startSecStorageVm(instanceId);
+    }
+
+    private SecondaryStorageVmVO stopSecondaryStorageVm(final VMInstanceVO systemVm, final boolean isForced)
+            throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
+
+        _itMgr.advanceStop(systemVm.getUuid(), isForced);
+        return _secStorageVmDao.findById(systemVm.getId());
+    }
+
+    public SecondaryStorageVmVO rebootSecondaryStorageVm(final long instanceId) {
+        _secStorageVmMgr.rebootSecStorageVm(instanceId);
+        return _secStorageVmDao.findById(instanceId);
+    }
+
+    protected SecondaryStorageVmVO destroySecondaryStorageVm(final long instanceId) {
+        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(instanceId);
+        if (_secStorageVmMgr.destroySecStorageVm(instanceId)) {
+            return secStorageVm;
+        }
+        return null;
+    }
+
+    @Override
+    public Pair<List<? extends VirtualMachine>, Integer> searchForSystemVm(final ListSystemVMsCmd cmd) {
+        final String type = cmd.getSystemVmType();
+        final Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), cmd.getZoneId());
+        final Long id = cmd.getId();
+        final String name = cmd.getSystemVmName();
+        final String state = cmd.getState();
+        final String keyword = cmd.getKeyword();
+        final Long podId = cmd.getPodId();
+        final Long hostId = cmd.getHostId();
+        final Long storageId = cmd.getStorageId();
+
+        final Filter searchFilter = new Filter(VMInstanceVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        final SearchBuilder<VMInstanceVO> sb = _vmInstanceDao.createSearchBuilder();
+
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("hostName", sb.entity().getHostName(), SearchCriteria.Op.LIKE);
+        sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+        sb.and("podId", sb.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ);
+        sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ);
+        sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
+        sb.and("nulltype", sb.entity().getType(), SearchCriteria.Op.IN);
+
+        if (storageId != null) {
+            final SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
+            volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+            sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        final SearchCriteria<VMInstanceVO> sc = sb.create();
+
+        if (keyword != null) {
+            final SearchCriteria<VMInstanceVO> ssc = _vmInstanceDao.createSearchCriteria();
+            ssc.addOr("hostName", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            ssc.addOr("state", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+
+            sc.addAnd("hostName", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (name != null) {
+            sc.setParameters("hostName", name);
+        }
+        if (state != null) {
+            sc.setParameters("state", state);
+        }
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+        if (podId != null) {
+            sc.setParameters("podId", podId);
+        }
+        if (hostId != null) {
+            sc.setParameters("hostId", hostId);
+        }
+
+        if (type != null) {
+            sc.setParameters("type", type);
+        } else {
+            sc.setParameters("nulltype", VirtualMachine.Type.SecondaryStorageVm, VirtualMachine.Type.ConsoleProxy);
+        }
+
+        if (storageId != null) {
+            sc.setJoinParameters("volumeSearch", "poolId", storageId);
+        }
+
+        final Pair<List<VMInstanceVO>, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends VirtualMachine>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public VirtualMachine.Type findSystemVMTypeById(final long instanceId) {
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(instanceId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+        if (systemVm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm of specified instanceId");
+            ex.addProxyObject(String.valueOf(instanceId), "instanceId");
+            throw ex;
+        }
+        return systemVm.getType();
+    }
+
+    @Override
+    @ActionEvent(eventType = "", eventDescription = "", async = true)
+    public VirtualMachine startSystemVM(final long vmId) {
+
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+        if (systemVm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+        if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_START, "starting console proxy Vm");
+            return startConsoleProxy(vmId);
+        } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_START, "starting secondary storage Vm");
+            return startSecondaryStorageVm(vmId);
+        } else {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm with specified vmId");
+            ex.addProxyObject(systemVm.getUuid(), "vmId");
+            throw ex;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = "", eventDescription = "", async = true)
+    public VMInstanceVO stopSystemVM(final StopSystemVmCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
+        final Long id = cmd.getId();
+
+        // verify parameters
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+        if (systemVm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
+            ex.addProxyObject(id.toString(), "vmId");
+            throw ex;
+        }
+
+        try {
+            if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) {
+                ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_STOP, "stopping console proxy Vm");
+                return stopConsoleProxy(systemVm, cmd.isForced());
+            } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
+                ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_STOP, "stopping secondary storage Vm");
+                return stopSecondaryStorageVm(systemVm, cmd.isForced());
+            }
+            return null;
+        } catch (final OperationTimedoutException e) {
+            throw new CloudRuntimeException("Unable to stop " + systemVm, e);
+        }
+    }
+
+    @Override
+    public VMInstanceVO rebootSystemVM(final RebootSystemVmCmd cmd) {
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+
+        if (systemVm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
+            ex.addProxyObject(cmd.getId().toString(), "vmId");
+            throw ex;
+        }
+
+        if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_REBOOT, "rebooting console proxy Vm");
+            return rebootConsoleProxy(cmd.getId());
+        } else {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_REBOOT, "rebooting secondary storage Vm");
+            return rebootSecondaryStorageVm(cmd.getId());
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = "", eventDescription = "", async = true)
+    public VMInstanceVO destroySystemVM(final DestroySystemVmCmd cmd) {
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+
+        if (systemVm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId");
+            ex.addProxyObject(cmd.getId().toString(), "vmId");
+            throw ex;
+        }
+
+        if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_PROXY_DESTROY, "destroying console proxy Vm");
+            return destroyConsoleProxy(cmd.getId());
+        } else {
+            ActionEventUtils.startNestedActionEvent(EventTypes.EVENT_SSVM_DESTROY, "destroying secondary storage Vm");
+            return destroySecondaryStorageVm(cmd.getId());
+        }
+    }
+
+    private String signRequest(final String request, final String key) {
+        try {
+            s_logger.info("Request: " + request);
+            s_logger.info("Key: " + key);
+
+            if (key != null && request != null) {
+                final Mac mac = Mac.getInstance("HmacSHA1");
+                final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
+                mac.init(keySpec);
+                mac.update(request.getBytes());
+                final byte[] encryptedBytes = mac.doFinal();
+                return new String(Base64.encodeBase64(encryptedBytes));
+            }
+        } catch (final Exception ex) {
+            s_logger.error("unable to sign request", ex);
+        }
+        return null;
+    }
+
+    @Override
+    public ArrayList<String> getCloudIdentifierResponse(final long userId) {
+        final Account caller = getCaller();
+
+        // verify that user exists
+        User user = _accountMgr.getUserIncludingRemoved(userId);
+        if (user == null || user.getRemoved() != null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find active user of specified id");
+            ex.addProxyObject(String.valueOf(userId), "userId");
+            throw ex;
+        }
+
+        // check permissions
+        _accountMgr.checkAccess(caller, null, true, _accountMgr.getAccount(user.getAccountId()));
+
+        String cloudIdentifier = _configDao.getValue("cloud.identifier");
+        if (cloudIdentifier == null) {
+            cloudIdentifier = "";
+        }
+
+        String signature = "";
+        try {
+            // get the user obj to get his secret key
+            user = _accountMgr.getActiveUser(userId);
+            final String secretKey = user.getSecretKey();
+            final String input = cloudIdentifier;
+            signature = signRequest(input, secretKey);
+        } catch (final Exception e) {
+            s_logger.warn("Exception whilst creating a signature:" + e);
+        }
+
+        final ArrayList<String> cloudParams = new ArrayList<String>();
+        cloudParams.add(cloudIdentifier);
+        cloudParams.add(signature);
+
+        return cloudParams;
+    }
+
+    @Override
+    public Map<String, Object> listCapabilities(final ListCapabilitiesCmd cmd) {
+        final Map<String, Object> capabilities = new HashMap<String, Object>();
+
+        final Account caller = getCaller();
+        boolean securityGroupsEnabled = false;
+        boolean elasticLoadBalancerEnabled = false;
+        boolean KVMSnapshotEnabled = false;
+        String supportELB = "false";
+        final List<NetworkVO> networks = _networkDao.listSecurityGroupEnabledNetworks();
+        if (networks != null && !networks.isEmpty()) {
+            securityGroupsEnabled = true;
+            final String elbEnabled = _configDao.getValue(Config.ElasticLoadBalancerEnabled.key());
+            elasticLoadBalancerEnabled = elbEnabled == null ? false : Boolean.parseBoolean(elbEnabled);
+            if (elasticLoadBalancerEnabled) {
+                final String networkType = _configDao.getValue(Config.ElasticLoadBalancerNetwork.key());
+                if (networkType != null) {
+                    supportELB = networkType;
+                }
+            }
+        }
+
+        final long diskOffMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
+        final long diskOffMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
+        KVMSnapshotEnabled = Boolean.parseBoolean(_configDao.getValue("KVM.snapshot.enabled"));
+
+        final boolean userPublicTemplateEnabled = TemplateManager.AllowPublicUserTemplates.valueIn(caller.getId());
+
+        // add some parameters UI needs to handle API throttling
+        final boolean apiLimitEnabled = Boolean.parseBoolean(_configDao.getValue(Config.ApiLimitEnabled.key()));
+        final Integer apiLimitInterval = Integer.valueOf(_configDao.getValue(Config.ApiLimitInterval.key()));
+        final Integer apiLimitMax = Integer.valueOf(_configDao.getValue(Config.ApiLimitMax.key()));
+
+        final boolean allowUserViewDestroyedVM = (QueryManagerImpl.AllowUserViewDestroyedVM.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));
+        final boolean allowUserExpungeRecoverVM = (UserVmManager.AllowUserExpungeRecoverVm.valueIn(caller.getId()) | _accountService.isAdmin(caller.getId()));
+
+        // check if region-wide secondary storage is used
+        boolean regionSecondaryEnabled = false;
+        final List<ImageStoreVO> imgStores = _imgStoreDao.findRegionImageStores();
+        if (imgStores != null && imgStores.size() > 0) {
+            regionSecondaryEnabled = true;
+        }
+
+        capabilities.put("securityGroupsEnabled", securityGroupsEnabled);
+        capabilities.put("userPublicTemplateEnabled", userPublicTemplateEnabled);
+        capabilities.put("cloudStackVersion", getVersion());
+        capabilities.put("supportELB", supportELB);
+        capabilities.put("projectInviteRequired", _projectMgr.projectInviteRequired());
+        capabilities.put("allowusercreateprojects", _projectMgr.allowUserToCreateProject());
+        capabilities.put("customDiskOffMinSize", diskOffMinSize);
+        capabilities.put("customDiskOffMaxSize", diskOffMaxSize);
+        capabilities.put("regionSecondaryEnabled", regionSecondaryEnabled);
+        capabilities.put("KVMSnapshotEnabled", KVMSnapshotEnabled);
+        capabilities.put("allowUserViewDestroyedVM", allowUserViewDestroyedVM);
+        capabilities.put("allowUserExpungeRecoverVM", allowUserExpungeRecoverVM);
+        if (apiLimitEnabled) {
+            capabilities.put("apiLimitInterval", apiLimitInterval);
+            capabilities.put("apiLimitMax", apiLimitMax);
+        }
+
+        return capabilities;
+    }
+
+    @Override
+    public GuestOSVO getGuestOs(final Long guestOsId) {
+        return _guestOSDao.findById(guestOsId);
+    }
+
+    @Override
+    public GuestOSHypervisorVO getGuestOsHypervisor(final Long guestOsHypervisorId) {
+        return _guestOSHypervisorDao.findById(guestOsHypervisorId);
+    }
+
+    @Override
+    public InstanceGroupVO updateVmGroup(final UpdateVMGroupCmd cmd) {
+        final Account caller = getCaller();
+        final Long groupId = cmd.getId();
+        final String groupName = cmd.getGroupName();
+
+        // Verify input parameters
+        final InstanceGroupVO group = _vmGroupDao.findById(groupId.longValue());
+        if (group == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a vm group with specified groupId");
+            ex.addProxyObject(groupId.toString(), "groupId");
+            throw ex;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, group);
+
+        // Check if name is already in use by this account (exclude this group)
+        final boolean isNameInUse = _vmGroupDao.isNameInUse(group.getAccountId(), groupName);
+
+        if (isNameInUse && !group.getName().equals(groupName)) {
+            throw new InvalidParameterValueException("Unable to update vm group, a group with name " + groupName + " already exists for account");
+        }
+
+        if (groupName != null) {
+            _vmGroupDao.updateVmGroup(groupId, groupName);
+        }
+
+        return _vmGroupDao.findById(groupId);
+    }
+
+    @Override
+    public String getVersion() {
+        final Class<?> c = ManagementServer.class;
+        final String fullVersion = c.getPackage().getImplementationVersion();
+        if (fullVersion != null && fullVersion.length() > 0) {
+            return fullVersion;
+        }
+
+        return "unknown";
+    }
+
+    @Override
+    @DB
+    public String uploadCertificate(final UploadCustomCertificateCmd cmd) {
+        if (cmd.getPrivateKey() != null && cmd.getAlias() != null) {
+            throw new InvalidParameterValueException("Can't change the alias for private key certification");
+        }
+
+        if (cmd.getPrivateKey() == null) {
+            if (cmd.getAlias() == null) {
+                throw new InvalidParameterValueException("alias can't be empty, if it's a certification chain");
+            }
+
+            if (cmd.getCertIndex() == null) {
+                throw new InvalidParameterValueException("index can't be empty, if it's a certifciation chain");
+            }
+        }
+
+        final String certificate = cmd.getCertificate();
+        final String key = cmd.getPrivateKey();
+
+        if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) {
+            throw new InvalidParameterValueException("Failed to pass certificate validation check");
+        }
+
+        if (cmd.getPrivateKey() != null) {
+            _ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, cmd.getDomainSuffix());
+
+            // Reboot ssvm here since private key is present - meaning server cert being passed
+            final List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting);
+            for (final SecondaryStorageVmVO ssVmVm : alreadyRunning) {
+                _secStorageVmMgr.rebootSecStorageVm(ssVmVm.getId());
+            }
+        } else {
+            _ksMgr.saveCertificate(cmd.getAlias(), certificate, cmd.getCertIndex(), cmd.getDomainSuffix());
+        }
+
+        _consoleProxyMgr.setManagementState(ConsoleProxyManagementState.ResetSuspending);
+        return "Certificate has been successfully updated, if its the server certificate we would reboot all "
+        + "running console proxy VMs and secondary storage VMs to propagate the new certificate, "
+        + "please give a few minutes for console access and storage services service to be up and working again";
+    }
+
+    @Override
+    public List<String> getHypervisors(final Long zoneId) {
+        final List<String> result = new ArrayList<String>();
+        final String hypers = _configDao.getValue(Config.HypervisorList.key());
+        final String[] hypervisors = hypers.split(",");
+
+        if (zoneId != null) {
+            if (zoneId.longValue() == -1L) {
+                final List<DataCenterVO> zones = _dcDao.listAll();
+
+                for (final String hypervisor : hypervisors) {
+                    int hyperCount = 0;
+                    for (final DataCenterVO zone : zones) {
+                        final List<ClusterVO> clusters = _clusterDao.listByDcHyType(zone.getId(), hypervisor);
+                        if (!clusters.isEmpty()) {
+                            hyperCount++;
+                        }
+                    }
+                    if (hyperCount == zones.size()) {
+                        result.add(hypervisor);
+                    }
+                }
+            } else {
+                final List<ClusterVO> clustersForZone = _clusterDao.listByZoneId(zoneId);
+                for (final ClusterVO cluster : clustersForZone) {
+                    result.add(cluster.getHypervisorType().toString());
+                }
+            }
+
+        } else {
+            return Arrays.asList(hypervisors);
+        }
+        return result;
+    }
+
+    @Override
+    public SSHKeyPair createSSHKeyPair(final CreateSSHKeyPairCmd cmd) {
+        final Account caller = getCaller();
+        final String accountName = cmd.getAccountName();
+        final Long domainId = cmd.getDomainId();
+        final Long projectId = cmd.getProjectId();
+
+        final Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
+
+        final SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
+        if (s != null) {
+            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists.");
+        }
+
+        final SSHKeysHelper keys = new SSHKeysHelper(sshKeyLength.value());
+
+        final String name = cmd.getName();
+        final String publicKey = keys.getPublicKey();
+        final String fingerprint = keys.getPublicKeyFingerPrint();
+        final String privateKey = keys.getPrivateKey();
+
+        return createAndSaveSSHKeyPair(name, fingerprint, publicKey, privateKey, owner);
+    }
+
+    @Override
+    public boolean deleteSSHKeyPair(final DeleteSSHKeyPairCmd cmd) {
+        final Account caller = getCaller();
+        final String accountName = cmd.getAccountName();
+        final Long domainId = cmd.getDomainId();
+        final Long projectId = cmd.getProjectId();
+
+        Account owner = null;
+        try {
+            owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
+        } catch (InvalidParameterValueException ex) {
+            if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && accountName != null && domainId != null) {
+                owner = _accountDao.findAccountIncludingRemoved(accountName, domainId);
+            }
+            if (owner == null) {
+                throw ex;
+            }
+        }
+
+        final SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
+        if (s == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException(
+                    "A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName() + " in specified domain id");
+            final DomainVO domain = ApiDBUtils.findDomainById(owner.getDomainId());
+            String domainUuid = String.valueOf(owner.getDomainId());
+            if (domain != null) {
+                domainUuid = domain.getUuid();
+            }
+            ex.addProxyObject(domainUuid, "domainId");
+            throw ex;
+        }
+
+        return _sshKeyPairDao.deleteByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
+    }
+
+    @Override
+    public Pair<List<? extends SSHKeyPair>, Integer> listSSHKeyPairs(final ListSSHKeyPairsCmd cmd) {
+        final String name = cmd.getName();
+        final String fingerPrint = cmd.getFingerprint();
+        final String keyword = cmd.getKeyword();
+
+        final Account caller = getCaller();
+        final List<Long> permittedAccounts = new ArrayList<Long>();
+
+        final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        final Long domainId = domainIdRecursiveListProject.first();
+        final Boolean isRecursive = domainIdRecursiveListProject.second();
+        final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        final SearchBuilder<SSHKeyPairVO> sb = _sshKeyPairDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        final Filter searchFilter = new Filter(SSHKeyPairVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        final SearchCriteria<SSHKeyPairVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+
+        if (fingerPrint != null) {
+            sc.addAnd("fingerprint", SearchCriteria.Op.EQ, fingerPrint);
+        }
+
+        if (keyword != null) {
+            sc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addOr("fingerprint", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+        }
+
+        final Pair<List<SSHKeyPairVO>, Integer> result = _sshKeyPairDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends SSHKeyPair>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_SSH_KEYPAIR, eventDescription = "registering ssh keypair", async = true)
+    public SSHKeyPair registerSSHKeyPair(final RegisterSSHKeyPairCmd cmd) {
+        final Account owner = getOwner(cmd);
+        checkForKeyByName(cmd, owner);
+        checkForKeyByPublicKey(cmd, owner);
+
+        final String name = cmd.getName();
+        String key = cmd.getPublicKey();
+
+        final String publicKey = getPublicKeyFromKeyKeyMaterial(key);
+        final String fingerprint = getFingerprint(publicKey);
+
+        return createAndSaveSSHKeyPair(name, fingerprint, publicKey, null, owner);
+    }
+
+    /**
+     * @param cmd
+     * @param owner
+     * @throws InvalidParameterValueException
+     */
+    private void checkForKeyByPublicKey(final RegisterSSHKeyPairCmd cmd, final Account owner) throws InvalidParameterValueException {
+        final SSHKeyPairVO existingPair = _sshKeyPairDao.findByPublicKey(owner.getAccountId(), owner.getDomainId(), getPublicKeyFromKeyKeyMaterial(cmd.getPublicKey()));
+        if (existingPair != null) {
+            throw new InvalidParameterValueException("A key pair with key '" + cmd.getPublicKey() + "' already exists for this account.");
+        }
+    }
+
+    /**
+     * @param cmd
+     * @param owner
+     * @throws InvalidParameterValueException
+     */
+    protected void checkForKeyByName(final RegisterSSHKeyPairCmd cmd, final Account owner) throws InvalidParameterValueException {
+        final SSHKeyPairVO existingPair = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
+        if (existingPair != null) {
+            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists for this account.");
+        }
+    }
+
+    /**
+     * @param publicKey
+     * @return
+     */
+    private String getFingerprint(final String publicKey) {
+        final String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(publicKey);
+        return fingerprint;
+    }
+
+    /**
+     * @param key
+     * @return
+     * @throws InvalidParameterValueException
+     */
+    protected String getPublicKeyFromKeyKeyMaterial(final String key) throws InvalidParameterValueException {
+        final String publicKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(key);
+
+        if (publicKey == null) {
+            throw new InvalidParameterValueException("Public key is invalid");
+        }
+        return publicKey;
+    }
+
+    /**
+     * @param cmd
+     * @return
+     */
+    protected Account getOwner(final RegisterSSHKeyPairCmd cmd) {
+        final Account caller = getCaller();
+
+        final Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
+        return owner;
+    }
+
+    /**
+     * @return
+     */
+    protected Account getCaller() {
+        final Account caller = CallContext.current().getCallingAccount();
+        return caller;
+    }
+
+    private SSHKeyPair createAndSaveSSHKeyPair(final String name, final String fingerprint, final String publicKey, final String privateKey, final Account owner) {
+        final SSHKeyPairVO newPair = new SSHKeyPairVO();
+
+        newPair.setAccountId(owner.getAccountId());
+        newPair.setDomainId(owner.getDomainId());
+        newPair.setName(name);
+        newPair.setFingerprint(fingerprint);
+        newPair.setPublicKey(publicKey);
+        newPair.setPrivateKey(privateKey); // transient; not saved.
+
+        _sshKeyPairDao.persist(newPair);
+
+        return newPair;
+    }
+
+    @Override
+    public String getVMPassword(final GetVMPasswordCmd cmd) {
+        final Account caller = getCaller();
+
+        final UserVmVO vm = _userVmDao.findById(cmd.getId());
+        if (vm == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("No VM with specified id found.");
+            ex.addProxyObject(cmd.getId().toString(), "vmId");
+            throw ex;
+        }
+
+        // make permission check
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        _userVmDao.loadDetails(vm);
+        final String password = vm.getDetail("Encrypted.Password");
+        if (password == null || password.equals("")) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException(
+                    "No password for VM with specified id found. " + "If VM is created from password enabled template and SSH keypair is assigned to VM then only password can be retrieved.");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        return password;
+    }
+
+    private boolean updateHostsInCluster(final UpdateHostPasswordCmd command) {
+        // get all the hosts in this cluster
+        final List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(command.getClusterId());
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                for (final HostVO h : hosts) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Changing password for host name = " + h.getName());
+                    }
+                    // update password for this host
+                    final DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME);
+                    if (nv.getValue().equals(command.getUsername())) {
+                        final DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.PASSWORD);
+                        nvp.setValue(DBEncryptionUtil.encrypt(command.getPassword()));
+                        _detailsDao.persist(nvp);
+                    } else {
+                        // if one host in the cluster has diff username then
+                        // rollback to maintain consistency
+                        throw new InvalidParameterValueException("The username is not same for all hosts, please modify passwords for individual hosts.");
+                    }
+                }
+            }
+        });
+        return true;
+    }
+
+    /**
+     * This method updates the password of all hosts in a given cluster.
+     */
+    @Override
+    @DB
+    public boolean updateClusterPassword(final UpdateHostPasswordCmd command) {
+        if (command.getClusterId() == null) {
+            throw new InvalidParameterValueException("You should provide a cluster id.");
+        }
+
+        final ClusterVO cluster = ApiDBUtils.findClusterById(command.getClusterId());
+        if (cluster == null || !supportedHypervisors.contains(cluster.getHypervisorType())) {
+            throw new InvalidParameterValueException("This operation is not supported for this hypervisor type");
+        }
+        return updateHostsInCluster(command);
+    }
+
+    @Override
+    @DB
+    public boolean updateHostPassword(final UpdateHostPasswordCmd cmd) {
+        if (cmd.getHostId() == null) {
+            throw new InvalidParameterValueException("You should provide an host id.");
+        }
+
+        final HostVO host = _hostDao.findById(cmd.getHostId());
+
+        if (host.getHypervisorType() == HypervisorType.XenServer) {
+            throw new InvalidParameterValueException("Single host update is not supported by XenServer hypervisors. Please try again informing the Cluster ID.");
+        }
+
+        if (!supportedHypervisors.contains(host.getHypervisorType())) {
+            throw new InvalidParameterValueException("This operation is not supported for this hypervisor type");
+        }
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(final TransactionStatus status) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Changing password for host name = " + host.getName());
+                }
+                // update password for this host
+                final DetailVO nv = _detailsDao.findDetail(host.getId(), ApiConstants.USERNAME);
+                if (nv.getValue().equals(cmd.getUsername())) {
+                    final DetailVO nvp = _detailsDao.findDetail(host.getId(), ApiConstants.PASSWORD);
+                    nvp.setValue(DBEncryptionUtil.encrypt(cmd.getPassword()));
+                    _detailsDao.persist(nvp);
+                } else {
+                    // if one host in the cluster has diff username then
+                    // rollback to maintain consistency
+                    throw new InvalidParameterValueException("The username is not same for the hosts..");
+                }
+            }
+        });
+        return true;
+    }
+
+    @Override
+    public String[] listEventTypes() {
+        final Object eventObj = new EventTypes();
+        final Class<EventTypes> c = EventTypes.class;
+        final Field[] fields = c.getFields();
+        final String[] eventTypes = new String[fields.length];
+        try {
+            int i = 0;
+            for (final Field field : fields) {
+                eventTypes[i++] = field.get(eventObj).toString();
+            }
+            return eventTypes;
+        } catch (final IllegalArgumentException e) {
+            s_logger.error("Error while listing Event Types", e);
+        } catch (final IllegalAccessException e) {
+            s_logger.error("Error while listing Event Types", e);
+        }
+        return null;
+    }
+
+    @Override
+    public Pair<List<? extends HypervisorCapabilities>, Integer> listHypervisorCapabilities(final Long id, final HypervisorType hypervisorType, final String keyword, final Long startIndex,
+            final Long pageSizeVal) {
+        final Filter searchFilter = new Filter(HypervisorCapabilitiesVO.class, "id", true, startIndex, pageSizeVal);
+        final SearchCriteria<HypervisorCapabilitiesVO> sc = _hypervisorCapabilitiesDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (hypervisorType != null) {
+            sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisorType);
+        }
+
+        if (keyword != null) {
+            final SearchCriteria<HypervisorCapabilitiesVO> ssc = _hypervisorCapabilitiesDao.createSearchCriteria();
+            ssc.addOr("hypervisorType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("hypervisorType", SearchCriteria.Op.SC, ssc);
+        }
+
+        final Pair<List<HypervisorCapabilitiesVO>, Integer> result = _hypervisorCapabilitiesDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends HypervisorCapabilities>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public HypervisorCapabilities updateHypervisorCapabilities(final Long id, final Long maxGuestsLimit, final Boolean securityGroupEnabled) {
+        HypervisorCapabilitiesVO hpvCapabilities = _hypervisorCapabilitiesDao.findById(id, true);
+
+        if (hpvCapabilities == null) {
+            final InvalidParameterValueException ex = new InvalidParameterValueException("unable to find the hypervisor capabilities for specified id");
+            ex.addProxyObject(id.toString(), "Id");
+            throw ex;
+        }
+
+        final boolean updateNeeded = maxGuestsLimit != null || securityGroupEnabled != null;
+        if (!updateNeeded) {
+            return hpvCapabilities;
+        }
+
+        hpvCapabilities = _hypervisorCapabilitiesDao.createForUpdate(id);
+
+        if (maxGuestsLimit != null) {
+            hpvCapabilities.setMaxGuestsLimit(maxGuestsLimit);
+        }
+
+        if (securityGroupEnabled != null) {
+            hpvCapabilities.setSecurityGroupEnabled(securityGroupEnabled);
+        }
+
+        if (_hypervisorCapabilitiesDao.update(id, hpvCapabilities)) {
+            hpvCapabilities = _hypervisorCapabilitiesDao.findById(id);
+            CallContext.current().setEventDetails("Hypervisor Capabilities id=" + hpvCapabilities.getId());
+            return hpvCapabilities;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "Upgrading system VM", async = true)
+    public VirtualMachine upgradeSystemVM(final ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException, ConcurrentOperationException {
+
+        final VMInstanceVO vmInstance = _vmInstanceDao.findById(cmd.getId());
+        if (vmInstance.getHypervisorType() == HypervisorType.XenServer && vmInstance.getState().equals(State.Running)) {
+            throw new InvalidParameterValueException("Dynamic Scaling operation is not permitted for this hypervisor on system vm");
+        }
+        final boolean result = _userVmMgr.upgradeVirtualMachine(cmd.getId(), cmd.getServiceOfferingId(), cmd.getDetails());
+        if (result) {
+            final VirtualMachine vm = _vmInstanceDao.findById(cmd.getId());
+            return vm;
+        } else {
+            throw new CloudRuntimeException("Failed to upgrade System VM");
+        }
+    }
+
+    @Override
+    public VirtualMachine upgradeSystemVM(final UpgradeSystemVMCmd cmd) {
+        final Long systemVmId = cmd.getId();
+        final Long serviceOfferingId = cmd.getServiceOfferingId();
+        return upgradeStoppedSystemVm(systemVmId, serviceOfferingId, cmd.getDetails());
+
+    }
+
+    private VirtualMachine upgradeStoppedSystemVm(final Long systemVmId, final Long serviceOfferingId, final Map<String, String> customparameters) {
+        final Account caller = getCaller();
+
+        final VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(systemVmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
+        if (systemVm == null) {
+            throw new InvalidParameterValueException("Unable to find SystemVm with id " + systemVmId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, systemVm);
+
+        // Check that the specified service offering ID is valid
+        ServiceOfferingVO newServiceOffering = _offeringDao.findById(serviceOfferingId);
+        final ServiceOfferingVO currentServiceOffering = _offeringDao.findById(systemVmId, systemVm.getServiceOfferingId());
+        if (newServiceOffering.isDynamic()) {
+            newServiceOffering.setDynamicFlag(true);
+            _userVmMgr.validateCustomParameters(newServiceOffering, customparameters);
+            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customparameters);
+        }
+        _itMgr.checkIfCanUpgrade(systemVm, newServiceOffering);
+
+        final boolean result = _itMgr.upgradeVmDb(systemVmId, serviceOfferingId);
+
+        if (newServiceOffering.isDynamic()) {
+            //save the custom values to the database.
+            _userVmMgr.saveCustomOfferingDetails(systemVmId, newServiceOffering);
+        }
+        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
+            _userVmMgr.removeCustomOfferingDetails(systemVmId);
+        }
+
+        if (result) {
+            return _vmInstanceDao.findById(systemVmId);
+        } else {
+            throw new CloudRuntimeException("Unable to upgrade system vm " + systemVm);
+        }
+
+    }
+
+    private void enableAdminUser(final String password) {
+        String encodedPassword = null;
+
+        final UserVO adminUser = _userDao.getUser(2);
+        if (adminUser == null) {
+            final String msg = "CANNOT find admin user";
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        if (adminUser.getState() == Account.State.disabled) {
+            // This means its a new account, set the password using the
+            // authenticator
+
+            for (final UserAuthenticator authenticator : _userPasswordEncoders) {
+                encodedPassword = authenticator.encode(password);
+                if (encodedPassword != null) {
+                    break;
+                }
+            }
+
+            adminUser.setPassword(encodedPassword);
+            adminUser.setState(Account.State.enabled);
+            _userDao.persist(adminUser);
+            s_logger.info("Admin user enabled");
+        }
+
+    }
+
+    @Override
+    public List<String> listDeploymentPlanners() {
+        final List<String> plannersAvailable = new ArrayList<String>();
+        for (final DeploymentPlanner planner : _planners) {
+            plannersAvailable.add(planner.getName());
+        }
+
+        return plannersAvailable;
+    }
+
+    @Override
+    public void cleanupVMReservations() {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Processing cleanupVMReservations");
+        }
+
+        _dpMgr.cleanupVMReservations();
+    }
+
+    public List<StoragePoolAllocator> getStoragePoolAllocators() {
+        return _storagePoolAllocators;
+    }
+
+    @Inject
+    public void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators) {
+        _storagePoolAllocators = storagePoolAllocators;
+    }
+
+    public LockMasterListener getLockMasterListener() {
+        return _lockMasterListener;
+    }
+
+    public void setLockMasterListener(final LockMasterListener lockMasterListener) {
+        _lockMasterListener = lockMasterListener;
+    }
+
+}
diff --git a/server/src/main/java/com/cloud/server/StatsCollector.java b/server/src/main/java/com/cloud/server/StatsCollector.java
new file mode 100644
index 0000000..8e2bc7e
--- /dev/null
+++ b/server/src/main/java/com/cloud/server/StatsCollector.java
@@ -0,0 +1,1571 @@
+// 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.server;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.utils.graphite.GraphiteClient;
+import org.apache.cloudstack.utils.graphite.GraphiteException;
+import org.apache.cloudstack.utils.usage.UsageUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBFactory;
+import org.influxdb.dto.BatchPoints;
+import org.influxdb.dto.Point;
+import org.influxdb.dto.Pong;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.PerformanceMonitorCommand;
+import com.cloud.agent.api.VgpuTypesInfo;
+import com.cloud.agent.api.VmDiskStatsEntry;
+import com.cloud.agent.api.VmNetworkStatsEntry;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.VolumeStatsEntry;
+import com.cloud.cluster.ManagementServerHostVO;
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.gpu.dao.HostGpuGroupsDao;
+import com.cloud.host.Host;
+import com.cloud.host.HostStats;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.as.AutoScaleManager;
+import com.cloud.network.as.AutoScalePolicyConditionMapVO;
+import com.cloud.network.as.AutoScalePolicyVO;
+import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO;
+import com.cloud.network.as.AutoScaleVmGroupVO;
+import com.cloud.network.as.AutoScaleVmGroupVmMapVO;
+import com.cloud.network.as.AutoScaleVmProfileVO;
+import com.cloud.network.as.Condition.Operator;
+import com.cloud.network.as.ConditionVO;
+import com.cloud.network.as.Counter;
+import com.cloud.network.as.CounterVO;
+import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
+import com.cloud.network.as.dao.AutoScalePolicyDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
+import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
+import com.cloud.network.as.dao.AutoScaleVmProfileDao;
+import com.cloud.network.as.dao.ConditionDao;
+import com.cloud.network.as.dao.CounterDao;
+import com.cloud.org.Cluster;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.ImageStoreDetailsUtil;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StorageStats;
+import com.cloud.storage.VolumeStats;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.UserStatisticsVO;
+import com.cloud.user.VmDiskStatisticsVO;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.user.dao.VmDiskStatisticsDao;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentMethodInterceptable;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.MacAddress;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VmStats;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * Provides real time stats for various agent resources up to x seconds
+ *
+ */
+@Component
+public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable, Configurable {
+
+    public static enum ExternalStatsProtocol {
+        NONE("none"), GRAPHITE("graphite"), INFLUXDB("influxdb");
+        String _type;
+
+        ExternalStatsProtocol(String type) {
+            _type = type;
+        }
+
+        @Override
+        public String toString() {
+            return _type;
+        }
+    }
+
+    public static final Logger s_logger = Logger.getLogger(StatsCollector.class.getName());
+
+    private static final int UNDEFINED_PORT_VALUE = -1;
+
+    /**
+     * Default value for the Graphite connection port: {@value}
+     */
+    private static final int GRAPHITE_DEFAULT_PORT = 2003;
+
+    /**
+     * Default value for the InfluxDB connection port: {@value}
+     */
+    private static final int INFLUXDB_DEFAULT_PORT = 8086;
+
+    private static final String UUID_TAG = "uuid";
+
+    private static final String TOTAL_MEMORY_KBS_FIELD = "total_memory_kb";
+    private static final String FREE_MEMORY_KBS_FIELD = "free_memory_kb";
+    private static final String CPU_UTILIZATION_FIELD = "cpu_utilization";
+    private static final String CPUS_FIELD = "cpus";
+    private static final String CPU_SOCKETS_FIELD = "cpu_sockets";
+    private static final String NETWORK_READ_KBS_FIELD = "network_read_kbs";
+    private static final String NETWORK_WRITE_KBS_FIELD = "network_write_kbs";
+    private static final String MEMORY_TARGET_KBS_FIELD = "memory_target_kbs";
+    private static final String DISK_READ_IOPS_FIELD = "disk_read_iops";
+    private static final String DISK_READ_KBS_FIELD = "disk_read_kbs";
+    private static final String DISK_WRITE_IOPS_FIELD = "disk_write_iops";
+    private static final String DISK_WRITE_KBS_FIELD = "disk_write_kbs";
+
+    private static final String DEFAULT_DATABASE_NAME = "cloudstack";
+    private static final String INFLUXDB_HOST_MEASUREMENT = "host_stats";
+    private static final String INFLUXDB_VM_MEASUREMENT = "vm_stats";
+
+    private static final ConfigKey<Integer> vmDiskStatsInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.disk.stats.interval", "0",
+            "Interval (in seconds) to report vm disk statistics. Vm disk statistics will be disabled if this is set to 0 or less than 0.", false);
+    private static final ConfigKey<Integer> vmDiskStatsIntervalMin = new ConfigKey<Integer>("Advanced", Integer.class, "vm.disk.stats.interval.min", "300",
+            "Minimal interval (in seconds) to report vm disk statistics. If vm.disk.stats.interval is smaller than this, use this to report vm disk statistics.", false);
+    private static final ConfigKey<Integer> vmNetworkStatsInterval = new ConfigKey<Integer>("Advanced", Integer.class, "vm.network.stats.interval", "0",
+            "Interval (in seconds) to report vm network statistics (for Shared networks). Vm network statistics will be disabled if this is set to 0 or less than 0.", false);
+    private static final ConfigKey<Integer> vmNetworkStatsIntervalMin = new ConfigKey<Integer>("Advanced", Integer.class, "vm.network.stats.interval.min", "300",
+            "Minimal Interval (in seconds) to report vm network statistics (for Shared networks). If vm.network.stats.interval is smaller than this, use this to report vm network statistics.",
+            false);
+    private static final ConfigKey<Integer> StatsTimeout = new ConfigKey<Integer>("Advanced", Integer.class, "stats.timeout", "60000",
+            "The timeout for stats call in milli seconds.", true,
+            ConfigKey.Scope.Cluster);
+    private static final ConfigKey<String> statsOutputUri = new ConfigKey<String>("Advanced", String.class, "stats.output.uri", "",
+            "URI to send StatsCollector statistics to. The collector is defined on the URI scheme. Example: graphite://graphite-hostaddress:port or influxdb://influxdb-hostaddress/dbname. Note that the port is optional, if not added the default port for the respective collector (graphite or influxdb) will be used. Additionally, the database name '/dbname' is  also optional; default db name is 'cloudstack'. You must create and configure the database if using influxdb.",
+            true);
+
+    private static StatsCollector s_instance = null;
+
+    private ScheduledExecutorService _executor = null;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private UserVmManager _userVmMgr;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private VolumeDao _volsDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private StorageManager _storageManager;
+    @Inject
+    private DataStoreManager _dataStoreMgr;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private EndPointSelector _epSelector;
+    @Inject
+    private VmDiskStatisticsDao _vmDiskStatsDao;
+    @Inject
+    private ManagementServerHostDao _msHostDao;
+    @Inject
+    private UserStatisticsDao _userStatsDao;
+    @Inject
+    private NicDao _nicDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private AutoScaleVmGroupDao _asGroupDao;
+    @Inject
+    private AutoScaleVmGroupVmMapDao _asGroupVmDao;
+    @Inject
+    private AutoScaleManager _asManager;
+    @Inject
+    private VMInstanceDao _vmInstance;
+    @Inject
+    private AutoScaleVmGroupPolicyMapDao _asGroupPolicyDao;
+    @Inject
+    private AutoScalePolicyDao _asPolicyDao;
+    @Inject
+    private AutoScalePolicyConditionMapDao _asConditionMapDao;
+    @Inject
+    private ConditionDao _asConditionDao;
+    @Inject
+    private CounterDao _asCounterDao;
+    @Inject
+    private AutoScaleVmProfileDao _asProfileDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private HostGpuGroupsDao _hostGpuGroupsDao;
+    @Inject
+    private ImageStoreDetailsUtil imageStoreDetailsUtil;
+
+    private ConcurrentHashMap<Long, HostStats> _hostStats = new ConcurrentHashMap<Long, HostStats>();
+    private final ConcurrentHashMap<Long, VmStats> _VmStats = new ConcurrentHashMap<Long, VmStats>();
+    private final Map<String, VolumeStats> _volumeStats = new ConcurrentHashMap<String, VolumeStats>();
+    private ConcurrentHashMap<Long, StorageStats> _storageStats = new ConcurrentHashMap<Long, StorageStats>();
+    private ConcurrentHashMap<Long, StorageStats> _storagePoolStats = new ConcurrentHashMap<Long, StorageStats>();
+
+    private long hostStatsInterval = -1L;
+    private long hostAndVmStatsInterval = -1L;
+    private long storageStatsInterval = -1L;
+    private long volumeStatsInterval = -1L;
+    private long autoScaleStatsInterval = -1L;
+
+    private double _imageStoreCapacityThreshold = 0.90;
+
+    private String externalStatsPrefix = "";
+    String externalStatsHost = null;
+    int externalStatsPort = -1;
+    private String externalStatsScheme;
+    ExternalStatsProtocol externalStatsType = ExternalStatsProtocol.NONE;
+    private String databaseName = DEFAULT_DATABASE_NAME;
+
+    private ScheduledExecutorService _diskStatsUpdateExecutor;
+    private int _usageAggregationRange = 1440;
+    private String _usageTimeZone = "GMT";
+    private final long mgmtSrvrId = MacAddress.getMacAddress().toLong();
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5;    // 5 seconds
+    private boolean _dailyOrHourly = false;
+
+    //private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
+
+    public static StatsCollector getInstance() {
+        return s_instance;
+    }
+
+    public static StatsCollector getInstance(Map<String, String> configs) {
+        s_instance.init(configs);
+        return s_instance;
+    }
+
+    public StatsCollector() {
+        s_instance = this;
+    }
+
+    @Override
+    public boolean start() {
+        init(_configDao.getConfiguration());
+        return true;
+    }
+
+    protected void init(Map<String, String> configs) {
+        _executor = Executors.newScheduledThreadPool(6, new NamedThreadFactory("StatsCollector"));
+
+        hostStatsInterval = NumbersUtil.parseLong(configs.get("host.stats.interval"), 60000L);
+        hostAndVmStatsInterval = NumbersUtil.parseLong(configs.get("vm.stats.interval"), 60000L);
+        storageStatsInterval = NumbersUtil.parseLong(configs.get("storage.stats.interval"), 60000L);
+        volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), 600000L);
+        autoScaleStatsInterval = NumbersUtil.parseLong(configs.get("autoscale.stats.interval"), 60000L);
+
+        String statsUri = statsOutputUri.value();
+        if (StringUtils.isNotBlank(statsUri)) {
+            try {
+                URI uri = new URI(statsUri);
+                externalStatsScheme = uri.getScheme();
+
+                try {
+                    externalStatsType = ExternalStatsProtocol.valueOf(externalStatsScheme.toUpperCase());
+                } catch (IllegalArgumentException e) {
+                    s_logger.error(externalStatsScheme + " is not a valid protocol for external statistics. No statistics will be send.");
+                }
+
+                if (StringUtils.isNotEmpty(uri.getHost())) {
+                    externalStatsHost = uri.getHost();
+                }
+
+                externalStatsPort = retrieveExternalStatsPortFromUri(uri);
+
+                databaseName = configureDatabaseName(uri);
+
+                if (!StringUtils.isEmpty(uri.getPath())) {
+                    externalStatsPrefix = uri.getPath().substring(1);
+                }
+
+                /* Append a dot (.) to the prefix if it is set */
+                if (!StringUtils.isEmpty(externalStatsPrefix)) {
+                    externalStatsPrefix += ".";
+                } else {
+                    externalStatsPrefix = "";
+                }
+
+            } catch (URISyntaxException e) {
+                s_logger.error("Failed to parse external statistics URI: ", e);
+            }
+        }
+
+        if (hostStatsInterval > 0) {
+            _executor.scheduleWithFixedDelay(new HostCollector(), 15000L, hostStatsInterval, TimeUnit.MILLISECONDS);
+        }
+
+        if (hostAndVmStatsInterval > 0) {
+            _executor.scheduleWithFixedDelay(new VmStatsCollector(), 15000L, hostAndVmStatsInterval, TimeUnit.MILLISECONDS);
+        }
+
+        if (storageStatsInterval > 0) {
+            _executor.scheduleWithFixedDelay(new StorageCollector(), 15000L, storageStatsInterval, TimeUnit.MILLISECONDS);
+        }
+
+        if (autoScaleStatsInterval > 0) {
+            _executor.scheduleWithFixedDelay(new AutoScaleMonitor(), 15000L, autoScaleStatsInterval, TimeUnit.MILLISECONDS);
+        }
+
+        if (vmDiskStatsInterval.value() > 0) {
+            if (vmDiskStatsInterval.value() < vmDiskStatsIntervalMin.value()) {
+                s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is smaller than vm.disk.stats.interval.min - " + vmDiskStatsIntervalMin.value()
+                        + ", so use vm.disk.stats.interval.min");
+                _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsIntervalMin.value(), vmDiskStatsIntervalMin.value(), TimeUnit.SECONDS);
+            } else {
+                _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval.value(), vmDiskStatsInterval.value(), TimeUnit.SECONDS);
+            }
+        } else {
+            s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm disk stats thread");
+        }
+
+        if (vmNetworkStatsInterval.value() > 0) {
+            if (vmNetworkStatsInterval.value() < vmNetworkStatsIntervalMin.value()) {
+                s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is smaller than vm.network.stats.interval.min - "
+                        + vmNetworkStatsIntervalMin.value() + ", so use vm.network.stats.interval.min");
+                _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsIntervalMin.value(), vmNetworkStatsIntervalMin.value(), TimeUnit.SECONDS);
+            } else {
+                _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsInterval.value(), vmNetworkStatsInterval.value(), TimeUnit.SECONDS);
+            }
+        } else {
+            s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm network stats thread");
+        }
+
+        if (volumeStatsInterval > 0) {
+            _executor.scheduleAtFixedRate(new VolumeStatsTask(), 15000L, volumeStatsInterval, TimeUnit.MILLISECONDS);
+        }
+
+        //Schedule disk stats update task
+        _diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater"));
+
+        String aggregationRange = configs.get("usage.stats.job.aggregation.range");
+        _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
+        _usageTimeZone = configs.get("usage.aggregation.timezone");
+        if (_usageTimeZone == null) {
+            _usageTimeZone = "GMT";
+        }
+        TimeZone usageTimezone = TimeZone.getTimeZone(_usageTimeZone);
+        Calendar cal = Calendar.getInstance(usageTimezone);
+        cal.setTime(new Date());
+        long endDate = 0;
+        int HOURLY_TIME = 60;
+        final int DAILY_TIME = 60 * 24;
+        if (_usageAggregationRange == DAILY_TIME) {
+            cal.set(Calendar.HOUR_OF_DAY, 0);
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            cal.roll(Calendar.DAY_OF_YEAR, true);
+            cal.add(Calendar.MILLISECOND, -1);
+            endDate = cal.getTime().getTime();
+            _dailyOrHourly = true;
+        } else if (_usageAggregationRange == HOURLY_TIME) {
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            cal.roll(Calendar.HOUR_OF_DAY, true);
+            cal.add(Calendar.MILLISECOND, -1);
+            endDate = cal.getTime().getTime();
+            _dailyOrHourly = true;
+        } else {
+            endDate = cal.getTime().getTime();
+            _dailyOrHourly = false;
+        }
+        if (_usageAggregationRange < UsageUtils.USAGE_AGGREGATION_RANGE_MIN) {
+            s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + UsageUtils.USAGE_AGGREGATION_RANGE_MIN);
+            _usageAggregationRange = UsageUtils.USAGE_AGGREGATION_RANGE_MIN;
+        }
+        _diskStatsUpdateExecutor.scheduleAtFixedRate(new VmDiskStatsUpdaterTask(), (endDate - System.currentTimeMillis()), (_usageAggregationRange * 60 * 1000),
+                TimeUnit.MILLISECONDS);
+
+    }
+
+    /**
+     * Configures the database name according to the URI path. For instance, if the URI is as influxdb://address:port/dbname, the database name will be 'dbname'.
+     */
+    protected String configureDatabaseName(URI uri) {
+        String dbname = StringUtils.removeStart(uri.getPath(), "/");
+        if (StringUtils.isBlank(dbname)) {
+            return DEFAULT_DATABASE_NAME;
+        } else {
+            return dbname;
+        }
+    }
+
+    /**
+     * Configures the port to be used when connecting with the stats collector service.
+     * Default values are 8086 for influx DB and 2003 for GraphiteDB.
+     * Throws URISyntaxException in case of non configured port and external StatsType
+     */
+    protected int retrieveExternalStatsPortFromUri(URI uri) throws URISyntaxException {
+        int port = uri.getPort();
+        if (externalStatsType != ExternalStatsProtocol.NONE) {
+            if (port != UNDEFINED_PORT_VALUE) {
+                return port;
+            }
+            if (externalStatsType == ExternalStatsProtocol.GRAPHITE) {
+                return GRAPHITE_DEFAULT_PORT;
+            }
+            if (externalStatsType == ExternalStatsProtocol.INFLUXDB) {
+                return INFLUXDB_DEFAULT_PORT;
+            }
+        }
+        throw new URISyntaxException(uri.toString(), String.format(
+                "Cannot define a port for the Stats Collector host %s://%s:%s or URI scheme is incorrect. The configured URI in stats.output.uri is not supported. Please configure as the following examples: graphite://graphite-hostaddress:port, or influxdb://influxdb-hostaddress:port. Note that the port is optional, if not added the default port for the respective collector (graphite or influxdb) will be used.",
+                externalStatsPrefix, externalStatsHost, externalStatsPort));
+    }
+
+    class HostCollector extends AbstractStatsCollector {
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.debug("HostStatsCollector is running...");
+
+                SearchCriteria<HostVO> sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance();
+
+                Map<Object, Object> metrics = new HashMap<>();
+                List<HostVO> hosts = _hostDao.search(sc, null);
+
+                for (HostVO host : hosts) {
+                    HostStatsEntry hostStatsEntry = (HostStatsEntry)_resourceMgr.getHostStatistics(host.getId());
+                    if (hostStatsEntry != null) {
+                        hostStatsEntry.setHostVo(host);
+                        metrics.put(hostStatsEntry.getHostId(), hostStatsEntry);
+                        _hostStats.put(host.getId(), hostStatsEntry);
+                    } else {
+                        s_logger.warn("The Host stats is null for host: " + host.getId());
+                    }
+                }
+
+                if (externalStatsType == ExternalStatsProtocol.INFLUXDB) {
+                    sendMetricsToInfluxdb(metrics);
+                }
+
+                updateGpuEnabledHostsDetails(hosts);
+            } catch (Throwable t) {
+                s_logger.error("Error trying to retrieve host stats", t);
+            }
+        }
+
+        /**
+         * Updates GPU details on hosts supporting GPU.
+         */
+        private void updateGpuEnabledHostsDetails(List<HostVO> hosts) {
+            List<HostVO> gpuEnabledHosts = new ArrayList<HostVO>();
+            List<Long> hostIds = _hostGpuGroupsDao.listHostIds();
+            if (CollectionUtils.isEmpty(hostIds)) {
+                return;
+            }
+            for (HostVO host : hosts) {
+                if (hostIds.contains(host.getId())) {
+                    gpuEnabledHosts.add(host);
+                }
+            }
+            for (HostVO host : gpuEnabledHosts) {
+                HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = _resourceMgr.getGPUStatistics(host);
+                if (MapUtils.isEmpty(groupDetails)) {
+                    _resourceMgr.updateGPUDetails(host.getId(), groupDetails);
+                }
+            }
+        }
+
+        @Override
+        protected Point creteInfluxDbPoint(Object metricsObject) {
+            return createInfluxDbPointForHostMetrics(metricsObject);
+        }
+    }
+
+    class VmStatsCollector extends AbstractStatsCollector {
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.trace("VmStatsCollector is running...");
+
+                SearchCriteria<HostVO> sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance();
+                List<HostVO> hosts = _hostDao.search(sc, null);
+
+                Map<Object, Object> metrics = new HashMap<>();
+
+                for (HostVO host : hosts) {
+                    List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
+                    List<Long> vmIds = new ArrayList<Long>();
+
+                    for (UserVmVO vm : vms) {
+                        vmIds.add(vm.getId());
+                    }
+
+                    try {
+                        Map<Long, VmStatsEntry> vmStatsById = _userVmMgr.getVirtualMachineStatistics(host.getId(), host.getName(), vmIds);
+
+                        if (vmStatsById != null) {
+                            Set<Long> vmIdSet = vmStatsById.keySet();
+                            for (Long vmId : vmIdSet) {
+                                VmStatsEntry statsForCurrentIteration = vmStatsById.get(vmId);
+                                statsForCurrentIteration.setVmId(vmId);
+                                UserVmVO userVmVo = _userVmDao.findById(vmId);
+                                statsForCurrentIteration.setUserVmVO(userVmVo);
+
+                                storeVirtualMachineStatsInMemory(statsForCurrentIteration);
+
+                                if (externalStatsType == ExternalStatsProtocol.GRAPHITE) {
+                                    prepareVmMetricsForGraphite(metrics, statsForCurrentIteration);
+                                } else {
+                                    metrics.put(statsForCurrentIteration.getVmId(), statsForCurrentIteration);
+                                }
+                            }
+
+                            if (!metrics.isEmpty()) {
+                                if (externalStatsType == ExternalStatsProtocol.GRAPHITE) {
+                                    sendVmMetricsToGraphiteHost(metrics, host);
+                                } else if (externalStatsType == ExternalStatsProtocol.INFLUXDB) {
+                                    sendMetricsToInfluxdb(metrics);
+                                }
+                            }
+
+                            metrics.clear();
+                        }
+                    } catch (Exception e) {
+                        s_logger.debug("Failed to get VM stats for host with ID: " + host.getId());
+                        continue;
+                    }
+                }
+
+            } catch (Throwable t) {
+                s_logger.error("Error trying to retrieve VM stats", t);
+            }
+        }
+
+        @Override
+        protected Point creteInfluxDbPoint(Object metricsObject) {
+            return createInfluxDbPointForVmMetrics(metricsObject);
+        }
+    }
+
+    public VmStats getVmStats(long id) {
+        return _VmStats.get(id);
+    }
+
+    class VmDiskStatsUpdaterTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            GlobalLock scanLock = GlobalLock.getInternLock("vm.disk.stats");
+            try {
+                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                    //Check for ownership
+                    //msHost in UP state with min id should run the job
+                    ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
+                    if (msHost == null || (msHost.getMsid() != mgmtSrvrId)) {
+                        s_logger.debug("Skipping aggregate disk stats update");
+                        scanLock.unlock();
+                        return;
+                    }
+                    try {
+                        Transaction.execute(new TransactionCallbackNoReturn() {
+                            @Override
+                            public void doInTransactionWithoutResult(TransactionStatus status) {
+                                //get all stats with delta > 0
+                                List<VmDiskStatisticsVO> updatedVmNetStats = _vmDiskStatsDao.listUpdatedStats();
+                                for (VmDiskStatisticsVO stat : updatedVmNetStats) {
+                                    if (_dailyOrHourly) {
+                                        //update agg bytes
+                                        stat.setAggBytesRead(stat.getCurrentBytesRead() + stat.getNetBytesRead());
+                                        stat.setAggBytesWrite(stat.getCurrentBytesWrite() + stat.getNetBytesWrite());
+                                        stat.setAggIORead(stat.getCurrentIORead() + stat.getNetIORead());
+                                        stat.setAggIOWrite(stat.getCurrentIOWrite() + stat.getNetIOWrite());
+                                        _vmDiskStatsDao.update(stat.getId(), stat);
+                                    }
+                                }
+                                s_logger.debug("Successfully updated aggregate vm disk stats");
+                            }
+                        });
+                    } catch (Exception e) {
+                        s_logger.debug("Failed to update aggregate disk stats", e);
+                    } finally {
+                        scanLock.unlock();
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.debug("Exception while trying to acquire disk stats lock", e);
+            } finally {
+                scanLock.releaseRef();
+            }
+        }
+    }
+
+    class VmDiskStatsTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            //Check for ownership
+            //msHost in UP state with min id should run the job
+            ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
+            if (msHost == null || (msHost.getMsid() != mgmtSrvrId)) {
+                s_logger.debug("Skipping collect vm disk stats from hosts");
+                return;
+            }
+            // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03.
+            s_logger.trace("Running VM disk stats ...");
+            try {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        s_logger.debug("VmDiskStatsTask is running...");
+
+                        SearchCriteria<HostVO> sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance();
+                        sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, HypervisorType.KVM); // support KVM only util 2013.06.25
+                        List<HostVO> hosts = _hostDao.search(sc, null);
+
+                        for (HostVO host : hosts) {
+                            List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
+                            List<Long> vmIds = new ArrayList<Long>();
+
+                            for (UserVmVO vm : vms) {
+                                if (vm.getType() == VirtualMachine.Type.User) // user vm
+                                    vmIds.add(vm.getId());
+                            }
+
+                            HashMap<Long, List<VmDiskStatsEntry>> vmDiskStatsById = _userVmMgr.getVmDiskStatistics(host.getId(), host.getName(), vmIds);
+                            if (vmDiskStatsById == null)
+                                continue;
+
+                            Set<Long> vmIdSet = vmDiskStatsById.keySet();
+                            for (Long vmId : vmIdSet) {
+                                List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsById.get(vmId);
+                                if (vmDiskStats == null)
+                                    continue;
+                                UserVmVO userVm = _userVmDao.findById(vmId);
+                                for (VmDiskStatsEntry vmDiskStat : vmDiskStats) {
+                                    SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
+                                    sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
+                                    List<VolumeVO> volumes = _volsDao.search(sc_volume, null);
+
+                                    if (CollectionUtils.isEmpty(volumes))
+                                        break;
+
+                                    VolumeVO volume = volumes.get(0);
+                                    VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
+                                    VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), vmId, volume.getId());
+
+                                    if (areAllDiskStatsZero(vmDiskStat)) {
+                                        s_logger.debug("IO/bytes read and write are all 0. Not updating vm_disk_statistics");
+                                        continue;
+                                    }
+
+                                    if (vmDiskStat_lock == null) {
+                                        s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()
+                                                + " and volumeId:" + volume.getId());
+                                        continue;
+                                    }
+
+                                    if (isCurrentVmDiskStatsDifferentFromPrevious(previousVmDiskStats, vmDiskStat_lock)) {
+                                        s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + "Ignoring current answer. Host: " + host.getName()
+                                                + " . VM: " + vmDiskStat.getVmName() + " Read(Bytes): " + vmDiskStat.getBytesRead() + " write(Bytes): " + vmDiskStat.getBytesWrite()
+                                                + " Read(IO): " + vmDiskStat.getIORead() + " write(IO): " + vmDiskStat.getIOWrite());
+                                        continue;
+                                    }
+
+                                    if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Read # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesRead() + " Stored: "
+                                                    + vmDiskStat_lock.getCurrentBytesRead());
+                                        }
+                                        vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+                                    }
+                                    vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
+                                    if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Write # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesWrite() + " Stored: "
+                                                    + vmDiskStat_lock.getCurrentBytesWrite());
+                                        }
+                                        vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+                                    }
+                                    vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
+                                    if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Read # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIORead() + " Stored: "
+                                                    + vmDiskStat_lock.getCurrentIORead());
+                                        }
+                                        vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+                                    }
+                                    vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
+                                    if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Write # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIOWrite() + " Stored: "
+                                                    + vmDiskStat_lock.getCurrentIOWrite());
+                                        }
+                                        vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+                                    }
+                                    vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
+
+                                    if (!_dailyOrHourly) {
+                                        //update agg bytes
+                                        vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+                                        vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+                                        vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+                                        vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+                                    }
+
+                                    _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
+                                }
+                            }
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                s_logger.warn("Error while collecting vm disk stats from hosts", e);
+            }
+        }
+    }
+
+    class VmNetworkStatsTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            //Check for ownership
+            //msHost in UP state with min id should run the job
+            ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
+            if (msHost == null || (msHost.getMsid() != mgmtSrvrId)) {
+                s_logger.debug("Skipping collect vm network stats from hosts");
+                return;
+            }
+            // collect the vm network statistics(total) from hypervisor
+            try {
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        s_logger.debug("VmNetworkStatsTask is running...");
+
+                        SearchCriteria<HostVO> sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance();
+                        List<HostVO> hosts = _hostDao.search(sc, null);
+
+                        for (HostVO host : hosts) {
+                            List<UserVmVO> vms = _userVmDao.listRunningByHostId(host.getId());
+                            List<Long> vmIds = new ArrayList<Long>();
+
+                            for (UserVmVO vm : vms) {
+                                if (vm.getType() == VirtualMachine.Type.User) // user vm
+                                    vmIds.add(vm.getId());
+                            }
+
+                            HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = _userVmMgr.getVmNetworkStatistics(host.getId(), host.getName(), vmIds);
+                            if (vmNetworkStatsById == null)
+                                continue;
+
+                            Set<Long> vmIdSet = vmNetworkStatsById.keySet();
+                            for (Long vmId : vmIdSet) {
+                                List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsById.get(vmId);
+                                if (vmNetworkStats == null)
+                                    continue;
+                                UserVmVO userVm = _userVmDao.findById(vmId);
+                                if (userVm == null) {
+                                    s_logger.debug("Cannot find uservm with id: " + vmId + " , continue");
+                                    continue;
+                                }
+                                s_logger.debug("Now we are updating the user_statistics table for VM: " + userVm.getInstanceName()
+                                        + " after collecting vm network statistics from host: " + host.getName());
+                                for (VmNetworkStatsEntry vmNetworkStat : vmNetworkStats) {
+                                    SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
+                                    sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
+                                    NicVO nic = _nicDao.search(sc_nic, null).get(0);
+                                    List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
+                                    if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
+                                        continue; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
+                                    UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(),
+                                            nic.getIPv4Address(), vmId, "UserVm");
+                                    if (previousvmNetworkStats == null) {
+                                        previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(), nic.getIPv4Address(), vmId, "UserVm",
+                                                nic.getNetworkId());
+                                        _userStatsDao.persist(previousvmNetworkStats);
+                                    }
+                                    UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(),
+                                            nic.getIPv4Address(), vmId, "UserVm");
+
+                                    if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
+                                        s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
+                                        continue;
+                                    }
+
+                                    if (vmNetworkStat_lock == null) {
+                                        s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()
+                                                + " and nicId:" + nic.getId());
+                                        continue;
+                                    }
+
+                                    if (previousvmNetworkStats != null && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
+                                            || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
+                                        s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " + "Ignoring current answer. Host: "
+                                                + host.getName() + " . VM: " + vmNetworkStat.getVmName() + " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): "
+                                                + vmNetworkStat.getBytesReceived());
+                                        continue;
+                                    }
+
+                                    if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Sent # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmNetworkStat.getVmName() + " Reported: " + vmNetworkStat.getBytesSent() + " Stored: "
+                                                    + vmNetworkStat_lock.getCurrentBytesSent());
+                                        }
+                                        vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
+                                    }
+                                    vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
+
+                                    if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
+                                        if (s_logger.isDebugEnabled()) {
+                                            s_logger.debug("Received # of bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: "
+                                                    + host.getName() + " . VM: " + vmNetworkStat.getVmName() + " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: "
+                                                    + vmNetworkStat_lock.getCurrentBytesReceived());
+                                        }
+                                        vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
+                                    }
+                                    vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
+
+                                    if (!_dailyOrHourly) {
+                                        //update agg bytes
+                                        vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
+                                        vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
+                                    }
+
+                                    _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
+                                }
+                            }
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                s_logger.warn("Error while collecting vm network stats from hosts", e);
+            }
+        }
+    }
+
+    class VolumeStatsTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                List<StoragePoolVO> pools = _storagePoolDao.listAll();
+
+                for (StoragePoolVO pool : pools) {
+                    List<VolumeVO> volumes = _volsDao.findByPoolId(pool.getId(), null);
+                    List<String> volumeLocators = new ArrayList<String>();
+                    for (VolumeVO volume : volumes) {
+                        if (volume.getFormat() == ImageFormat.QCOW2) {
+                            volumeLocators.add(volume.getUuid());
+                        } else if (volume.getFormat() == ImageFormat.VHD) {
+                            volumeLocators.add(volume.getPath());
+                        } else if (volume.getFormat() == ImageFormat.OVA) {
+                            volumeLocators.add(volume.getChainInfo());
+                        } else {
+                            s_logger.warn("Volume stats not implemented for this format type " + volume.getFormat());
+                            break;
+                        }
+                    }
+                    try {
+                        Map<String, VolumeStatsEntry> volumeStatsByUuid;
+                        if (pool.getScope() == ScopeType.ZONE) {
+                            volumeStatsByUuid = new HashMap<>();
+                            for (final Cluster cluster : _clusterDao.listByZoneId(pool.getDataCenterId())) {
+                                final Map<String, VolumeStatsEntry> volumeStatsForCluster = _userVmMgr.getVolumeStatistics(cluster.getId(), pool.getUuid(), pool.getPoolType(),
+                                        volumeLocators, StatsTimeout.value());
+                                if (volumeStatsForCluster != null) {
+                                    volumeStatsByUuid.putAll(volumeStatsForCluster);
+                                }
+                            }
+                        } else {
+                            volumeStatsByUuid = _userVmMgr.getVolumeStatistics(pool.getClusterId(), pool.getUuid(), pool.getPoolType(), volumeLocators, StatsTimeout.value());
+                        }
+                        if (volumeStatsByUuid != null) {
+                            for (final Map.Entry<String, VolumeStatsEntry> entry : volumeStatsByUuid.entrySet()) {
+                                if (entry == null || entry.getKey() == null || entry.getValue() == null) {
+                                    continue;
+                                }
+                                _volumeStats.put(entry.getKey(), entry.getValue());
+                            }
+                        }
+                    } catch (Exception e) {
+                        s_logger.warn("Failed to get volume stats for cluster with ID: " + pool.getClusterId(), e);
+                        continue;
+                    }
+                }
+            } catch (Throwable t) {
+                s_logger.error("Error trying to retrieve volume stats", t);
+            }
+        }
+    }
+
+    public VolumeStats getVolumeStats(String volumeLocator) {
+        if (volumeLocator != null && _volumeStats.containsKey(volumeLocator)) {
+            return _volumeStats.get(volumeLocator);
+        }
+        return null;
+    }
+
+    class StorageCollector extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("StorageCollector is running...");
+                }
+
+                List<DataStore> stores = _dataStoreMgr.listImageStores();
+                ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<Long, StorageStats>();
+                for (DataStore store : stores) {
+                    if (store.getUri() == null) {
+                        continue;
+                    }
+
+                    Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(store.getId());
+                    GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), nfsVersion);
+                    EndPoint ssAhost = _epSelector.select(store);
+                    if (ssAhost == null) {
+                        s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName());
+                        continue;
+                    }
+                    long storeId = store.getId();
+                    Answer answer = ssAhost.sendMessage(command);
+                    if (answer != null && answer.getResult()) {
+                        storageStats.put(storeId, (StorageStats)answer);
+                        s_logger.trace("HostId: " + storeId + " Used: " + ((StorageStats)answer).getByteUsed() + " Total Available: " + ((StorageStats)answer).getCapacityBytes());
+                    }
+                }
+                _storageStats = storageStats;
+                ConcurrentHashMap<Long, StorageStats> storagePoolStats = new ConcurrentHashMap<Long, StorageStats>();
+
+                List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
+                for (StoragePoolVO pool : storagePools) {
+                    // check if the pool has enabled hosts
+                    List<Long> hostIds = _storageManager.getUpHostsInPool(pool.getId());
+                    if (hostIds == null || hostIds.isEmpty())
+                        continue;
+                    GetStorageStatsCommand command = new GetStorageStatsCommand(pool.getUuid(), pool.getPoolType(), pool.getPath());
+                    long poolId = pool.getId();
+                    try {
+                        Answer answer = _storageManager.sendToPool(pool, command);
+                        if (answer != null && answer.getResult()) {
+                            storagePoolStats.put(pool.getId(), (StorageStats)answer);
+
+                            // Seems like we have dynamically updated the pool size since the prev. size and the current do not match
+                            if (_storagePoolStats.get(poolId) != null && _storagePoolStats.get(poolId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()) {
+                                pool.setCapacityBytes(((StorageStats)answer).getCapacityBytes());
+                                _storagePoolDao.update(pool.getId(), pool);
+                            }
+                        }
+                    } catch (StorageUnavailableException e) {
+                        s_logger.info("Unable to reach " + pool, e);
+                    } catch (Exception e) {
+                        s_logger.warn("Unable to get stats for " + pool, e);
+                    }
+                }
+                _storagePoolStats = storagePoolStats;
+            } catch (Throwable t) {
+                s_logger.error("Error trying to retrieve storage stats", t);
+            }
+        }
+
+    }
+
+    class AutoScaleMonitor extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("AutoScaling Monitor is running...");
+                }
+                // list all AS VMGroups
+                List<AutoScaleVmGroupVO> asGroups = _asGroupDao.listAll();
+                for (AutoScaleVmGroupVO asGroup : asGroups) {
+                    // check group state
+                    if ((asGroup.getState().equals("enabled")) && (is_native(asGroup.getId()))) {
+                        // check minimum vm of group
+                        Integer currentVM = _asGroupVmDao.countByGroup(asGroup.getId());
+                        if (currentVM < asGroup.getMinMembers()) {
+                            _asManager.doScaleUp(asGroup.getId(), asGroup.getMinMembers() - currentVM);
+                            continue;
+                        }
+
+                        //check interval
+                        long now = (new Date()).getTime();
+                        if (asGroup.getLastInterval() != null)
+                            if ((now - asGroup.getLastInterval().getTime()) < asGroup.getInterval()) {
+                                continue;
+                            }
+
+                        // update last_interval
+                        asGroup.setLastInterval(new Date());
+                        _asGroupDao.persist(asGroup);
+
+                        // collect RRDs data for this group
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("[AutoScale] Collecting RRDs data...");
+                        }
+                        Map<String, String> params = new HashMap<String, String>();
+                        List<AutoScaleVmGroupVmMapVO> asGroupVmVOs = _asGroupVmDao.listByGroup(asGroup.getId());
+                        params.put("total_vm", String.valueOf(asGroupVmVOs.size()));
+                        for (int i = 0; i < asGroupVmVOs.size(); i++) {
+                            long vmId = asGroupVmVOs.get(i).getInstanceId();
+                            VMInstanceVO vmVO = _vmInstance.findById(vmId);
+                            //xe vm-list | grep vmname -B 1 | head -n 1 | awk -F':' '{print $2}'
+                            params.put("vmname" + String.valueOf(i + 1), vmVO.getInstanceName());
+                            params.put("vmid" + String.valueOf(i + 1), String.valueOf(vmVO.getId()));
+
+                        }
+                        // get random hostid because all vms are in a cluster
+                        long vmId = asGroupVmVOs.get(0).getInstanceId();
+                        VMInstanceVO vmVO = _vmInstance.findById(vmId);
+                        Long receiveHost = vmVO.getHostId();
+
+                        // setup parameters phase: duration and counter
+                        // list pair [counter, duration]
+                        List<Pair<String, Integer>> lstPair = getPairofCounternameAndDuration(asGroup.getId());
+                        int total_counter = 0;
+                        String[] lstCounter = new String[lstPair.size()];
+                        for (int i = 0; i < lstPair.size(); i++) {
+                            Pair<String, Integer> pair = lstPair.get(i);
+                            String strCounterNames = pair.first();
+                            Integer duration = pair.second();
+
+                            lstCounter[i] = strCounterNames.split(",")[0];
+                            total_counter++;
+                            params.put("duration" + String.valueOf(total_counter), duration.toString());
+                            params.put("counter" + String.valueOf(total_counter), lstCounter[i]);
+                            params.put("con" + String.valueOf(total_counter), strCounterNames.split(",")[1]);
+                        }
+                        params.put("total_counter", String.valueOf(total_counter));
+
+                        PerformanceMonitorCommand perfMon = new PerformanceMonitorCommand(params, 20);
+
+                        try {
+                            Answer answer = _agentMgr.send(receiveHost, perfMon);
+                            if (answer == null || !answer.getResult()) {
+                                s_logger.debug("Failed to send data to node !");
+                            } else {
+                                String result = answer.getDetails();
+                                s_logger.debug("[AutoScale] RRDs collection answer: " + result);
+                                HashMap<Long, Double> avgCounter = new HashMap<Long, Double>();
+
+                                // extract data
+                                String[] counterElements = result.split(",");
+                                if ((counterElements != null) && (counterElements.length > 0)) {
+                                    for (String string : counterElements) {
+                                        try {
+                                            String[] counterVals = string.split(":");
+                                            String[] counter_vm = counterVals[0].split("\\.");
+
+                                            Long counterId = Long.parseLong(counter_vm[1]);
+                                            Long conditionId = Long.parseLong(params.get("con" + counter_vm[1]));
+                                            Double coVal = Double.parseDouble(counterVals[1]);
+
+                                            // Summary of all counter by counterId key
+                                            if (avgCounter.get(counterId) == null) {
+                                                /* initialize if data is not set */
+                                                avgCounter.put(counterId, new Double(0));
+                                            }
+
+                                            String counterName = getCounternamebyCondition(conditionId.longValue());
+                                            if (Counter.Source.memory.toString().equals(counterName)) {
+                                                // calculate memory in percent
+                                                Long profileId = asGroup.getProfileId();
+                                                AutoScaleVmProfileVO profileVo = _asProfileDao.findById(profileId);
+                                                ServiceOfferingVO serviceOff = _serviceOfferingDao.findById(profileVo.getServiceOfferingId());
+                                                int maxRAM = serviceOff.getRamSize();
+
+                                                // get current RAM percent
+                                                coVal = coVal / maxRAM;
+                                            } else {
+                                                // cpu
+                                                coVal = coVal * 100;
+                                            }
+
+                                            // update data entry
+                                            avgCounter.put(counterId, avgCounter.get(counterId) + coVal);
+
+                                        } catch (Exception e) {
+                                            e.printStackTrace();
+                                        }
+                                    }
+
+                                    String scaleAction = getAutoscaleAction(avgCounter, asGroup.getId(), currentVM, params);
+                                    if (scaleAction != null) {
+                                        s_logger.debug("[AutoScale] Doing scale action: " + scaleAction + " for group " + asGroup.getId());
+                                        if (scaleAction.equals("scaleup")) {
+                                            _asManager.doScaleUp(asGroup.getId(), 1);
+                                        } else {
+                                            _asManager.doScaleDown(asGroup.getId());
+                                        }
+                                    }
+                                }
+                            }
+
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+
+                    }
+                }
+
+            } catch (Throwable t) {
+                s_logger.error("Error trying to monitor autoscaling", t);
+            }
+
+        }
+
+        private boolean is_native(long groupId) {
+            List<AutoScaleVmGroupPolicyMapVO> vos = _asGroupPolicyDao.listByVmGroupId(groupId);
+            for (AutoScaleVmGroupPolicyMapVO vo : vos) {
+                List<AutoScalePolicyConditionMapVO> ConditionPolicies = _asConditionMapDao.findByPolicyId(vo.getPolicyId());
+                for (AutoScalePolicyConditionMapVO ConditionPolicy : ConditionPolicies) {
+                    ConditionVO condition = _asConditionDao.findById(ConditionPolicy.getConditionId());
+                    CounterVO counter = _asCounterDao.findById(condition.getCounterid());
+                    if (counter.getSource() == Counter.Source.cpu || counter.getSource() == Counter.Source.memory)
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        private String getAutoscaleAction(HashMap<Long, Double> avgCounter, long groupId, long currentVM, Map<String, String> params) {
+
+            List<AutoScaleVmGroupPolicyMapVO> listMap = _asGroupPolicyDao.listByVmGroupId(groupId);
+            if ((listMap == null) || (listMap.size() == 0))
+                return null;
+            for (AutoScaleVmGroupPolicyMapVO asVmgPmap : listMap) {
+                AutoScalePolicyVO policyVO = _asPolicyDao.findById(asVmgPmap.getPolicyId());
+                if (policyVO != null) {
+                    Integer quitetime = policyVO.getQuietTime();
+                    Date quitetimeDate = policyVO.getLastQuiteTime();
+                    long last_quitetime = 0L;
+                    if (quitetimeDate != null) {
+                        last_quitetime = policyVO.getLastQuiteTime().getTime();
+                    }
+                    long current_time = (new Date()).getTime();
+
+                    // check quite time for this policy
+                    if ((current_time - last_quitetime) >= (long)quitetime) {
+
+                        // list all condition of this policy
+                        boolean bValid = true;
+                        List<ConditionVO> lstConditions = getConditionsbyPolicyId(policyVO.getId());
+                        if ((lstConditions != null) && (lstConditions.size() > 0)) {
+                            // check whole conditions of this policy
+                            for (ConditionVO conditionVO : lstConditions) {
+                                long thresholdValue = conditionVO.getThreshold();
+                                Double thresholdPercent = (double)thresholdValue / 100;
+                                CounterVO counterVO = _asCounterDao.findById(conditionVO.getCounterid());
+                                long counter_count = 1;
+                                do {
+                                    String counter_param = params.get("counter" + String.valueOf(counter_count));
+                                    Counter.Source counter_source = counterVO.getSource();
+                                    if (counter_param.equals(counter_source.toString()))
+                                        break;
+                                    counter_count++;
+                                } while (1 == 1);
+
+                                Double sum = avgCounter.get(counter_count);
+                                Double avg = sum / currentVM;
+                                Operator op = conditionVO.getRelationalOperator();
+                                boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent.equals(avg)))
+                                        || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg.doubleValue() >= thresholdPercent.doubleValue()))
+                                        || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg.doubleValue() > thresholdPercent.doubleValue()))
+                                        || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg.doubleValue() <= thresholdPercent.doubleValue()))
+                                        || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg.doubleValue() < thresholdPercent.doubleValue()));
+
+                                if (!bConditionCheck) {
+                                    bValid = false;
+                                    break;
+                                }
+                            }
+                            if (bValid) {
+                                return policyVO.getAction();
+                            }
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        private List<ConditionVO> getConditionsbyPolicyId(long policyId) {
+            List<AutoScalePolicyConditionMapVO> conditionMap = _asConditionMapDao.findByPolicyId(policyId);
+            if ((conditionMap == null) || (conditionMap.size() == 0))
+                return null;
+
+            List<ConditionVO> lstResult = new ArrayList<ConditionVO>();
+            for (AutoScalePolicyConditionMapVO asPCmap : conditionMap) {
+                lstResult.add(_asConditionDao.findById(asPCmap.getConditionId()));
+            }
+
+            return lstResult;
+        }
+
+        public List<Pair<String, Integer>> getPairofCounternameAndDuration(long groupId) {
+            AutoScaleVmGroupVO groupVo = _asGroupDao.findById(groupId);
+            if (groupVo == null)
+                return null;
+            List<Pair<String, Integer>> result = new ArrayList<Pair<String, Integer>>();
+            //list policy map
+            List<AutoScaleVmGroupPolicyMapVO> groupPolicymap = _asGroupPolicyDao.listByVmGroupId(groupVo.getId());
+            if (groupPolicymap == null)
+                return null;
+            for (AutoScaleVmGroupPolicyMapVO gpMap : groupPolicymap) {
+                //get duration
+                AutoScalePolicyVO policyVo = _asPolicyDao.findById(gpMap.getPolicyId());
+                Integer duration = policyVo.getDuration();
+                //get collection of counter name
+
+                StringBuffer buff = new StringBuffer();
+                List<AutoScalePolicyConditionMapVO> lstPCmap = _asConditionMapDao.findByPolicyId(policyVo.getId());
+                for (AutoScalePolicyConditionMapVO pcMap : lstPCmap) {
+                    String counterName = getCounternamebyCondition(pcMap.getConditionId());
+                    buff.append(counterName);
+                    buff.append(",");
+                    buff.append(pcMap.getConditionId());
+                }
+                // add to result
+                Pair<String, Integer> pair = new Pair<String, Integer>(buff.toString(), duration);
+                result.add(pair);
+            }
+
+            return result;
+        }
+
+        public String getCounternamebyCondition(long conditionId) {
+
+            ConditionVO condition = _asConditionDao.findById(conditionId);
+            if (condition == null)
+                return "";
+
+            long counterId = condition.getCounterid();
+            CounterVO counter = _asCounterDao.findById(counterId);
+            if (counter == null)
+                return "";
+
+            return counter.getSource().toString();
+        }
+    }
+
+    /**
+     * This class allows to writing metrics in InfluxDB for the table that matches the Collector extending it.
+     * Thus, VmStatsCollector and HostCollector can use same method to write on different measures (host_stats or vm_stats table).
+     */
+    abstract class AbstractStatsCollector extends ManagedContextRunnable {
+        /**
+         * Sends metrics to influxdb host. This method supports both VM and Host metrics
+         */
+        protected void sendMetricsToInfluxdb(Map<Object, Object> metrics) {
+            InfluxDB influxDbConnection = createInfluxDbConnection();
+
+            Pong response = influxDbConnection.ping();
+            if (response.getVersion().equalsIgnoreCase("unknown")) {
+                throw new CloudRuntimeException(String.format("Cannot ping influxdb host %s:%s.", externalStatsHost, externalStatsPort));
+            }
+
+            Collection<Object> metricsObjects = metrics.values();
+            List<Point> points = new ArrayList<>();
+
+            s_logger.debug(String.format("Sending stats to %s host %s:%s", externalStatsType, externalStatsHost, externalStatsPort));
+
+            for (Object metricsObject : metricsObjects) {
+                Point vmPoint = creteInfluxDbPoint(metricsObject);
+                points.add(vmPoint);
+            }
+            writeBatches(influxDbConnection, databaseName, points);
+        }
+
+        /**
+         * Creates a InfluxDB point for the given stats collector (VmStatsCollector, or HostCollector).
+         */
+        protected abstract Point creteInfluxDbPoint(Object metricsObject);
+    }
+
+    public boolean imageStoreHasEnoughCapacity(DataStore imageStore) {
+        StorageStats imageStoreStats = _storageStats.get(imageStore.getId());
+        if (imageStoreStats != null && (imageStoreStats.getByteUsed() / (imageStoreStats.getCapacityBytes() * 1.0)) <= _imageStoreCapacityThreshold) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sends VMs metrics to the configured graphite host.
+     */
+    protected void sendVmMetricsToGraphiteHost(Map<Object, Object> metrics, HostVO host) {
+        s_logger.debug(String.format("Sending VmStats of host %s to %s host %s:%s", host.getId(), externalStatsType, externalStatsHost, externalStatsPort));
+        try {
+            GraphiteClient g = new GraphiteClient(externalStatsHost, externalStatsPort);
+            g.sendMetrics(metrics);
+        } catch (GraphiteException e) {
+            s_logger.debug("Failed sending VmStats to Graphite host " + externalStatsHost + ":" + externalStatsPort + ": " + e.getMessage());
+        }
+    }
+
+    /**
+     * Prepares metrics for Graphite.
+     * @note this method must only be executed in case the configured stats collector is a Graphite host;
+     * otherwise, it will compromise the map of metrics used by another type of collector (e.g. InfluxDB).
+     */
+    private void prepareVmMetricsForGraphite(Map<Object, Object> metrics, VmStatsEntry statsForCurrentIteration) {
+        VMInstanceVO vmVO = _vmInstance.findById(statsForCurrentIteration.getVmId());
+        String vmName = vmVO.getUuid();
+
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".cpu.num", statsForCurrentIteration.getNumCPUs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".cpu.utilization", statsForCurrentIteration.getCPUUtilization());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".network.read_kbs", statsForCurrentIteration.getNetworkReadKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".network.write_kbs", statsForCurrentIteration.getNetworkWriteKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_kbs", statsForCurrentIteration.getDiskWriteKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_kbs", statsForCurrentIteration.getDiskReadKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_iops", statsForCurrentIteration.getDiskWriteIOs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_iops", statsForCurrentIteration.getDiskReadIOs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.total_kbs", statsForCurrentIteration.getMemoryKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.internalfree_kbs", statsForCurrentIteration.getIntFreeMemoryKBs());
+        metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.target_kbs", statsForCurrentIteration.getTargetMemoryKBs());
+    }
+
+    /**
+     * Stores virtual machine stats in memory (map of {@link VmStatsEntry}).
+     */
+    private void storeVirtualMachineStatsInMemory(VmStatsEntry statsForCurrentIteration) {
+        VmStatsEntry statsInMemory = (VmStatsEntry)_VmStats.get(statsForCurrentIteration.getVmId());
+
+        if (statsInMemory == null) {
+            //no stats exist for this vm, directly persist
+            _VmStats.put(statsForCurrentIteration.getVmId(), statsForCurrentIteration);
+        } else {
+            //update each field
+            statsInMemory.setCPUUtilization(statsForCurrentIteration.getCPUUtilization());
+            statsInMemory.setNumCPUs(statsForCurrentIteration.getNumCPUs());
+            statsInMemory.setNetworkReadKBs(statsInMemory.getNetworkReadKBs() + statsForCurrentIteration.getNetworkReadKBs());
+            statsInMemory.setNetworkWriteKBs(statsInMemory.getNetworkWriteKBs() + statsForCurrentIteration.getNetworkWriteKBs());
+            statsInMemory.setDiskWriteKBs(statsInMemory.getDiskWriteKBs() + statsForCurrentIteration.getDiskWriteKBs());
+            statsInMemory.setDiskReadIOs(statsInMemory.getDiskReadIOs() + statsForCurrentIteration.getDiskReadIOs());
+            statsInMemory.setDiskWriteIOs(statsInMemory.getDiskWriteIOs() + statsForCurrentIteration.getDiskWriteIOs());
+            statsInMemory.setDiskReadKBs(statsInMemory.getDiskReadKBs() + statsForCurrentIteration.getDiskReadKBs());
+            statsInMemory.setMemoryKBs(statsForCurrentIteration.getMemoryKBs());
+            statsInMemory.setIntFreeMemoryKBs(statsForCurrentIteration.getIntFreeMemoryKBs());
+            statsInMemory.setTargetMemoryKBs(statsForCurrentIteration.getTargetMemoryKBs());
+
+            _VmStats.put(statsForCurrentIteration.getVmId(), statsInMemory);
+        }
+    }
+
+    /**
+     * Sends host metrics to a configured InfluxDB host. The metrics respects the following specification.</br>
+     * <b>Tags:</b>vm_id, uuid, instance_name, data_center_id, host_id</br>
+     * <b>Fields:</b>memory_total_kb, memory_internal_free_kbs, memory_target_kbs, cpu_utilization, cpus, network_write_kb, disk_read_iops, disk_read_kbs, disk_write_iops, disk_write_kbs
+     */
+    protected Point createInfluxDbPointForHostMetrics(Object metricsObject) {
+        HostStatsEntry hostStatsEntry = (HostStatsEntry)metricsObject;
+
+        Map<String, String> tagsToAdd = new HashMap<>();
+        tagsToAdd.put(UUID_TAG, hostStatsEntry.getHostVo().getUuid());
+
+        Map<String, Object> fieldsToAdd = new HashMap<>();
+        fieldsToAdd.put(TOTAL_MEMORY_KBS_FIELD, hostStatsEntry.getTotalMemoryKBs());
+        fieldsToAdd.put(FREE_MEMORY_KBS_FIELD, hostStatsEntry.getFreeMemoryKBs());
+        fieldsToAdd.put(CPU_UTILIZATION_FIELD, hostStatsEntry.getCpuUtilization());
+        fieldsToAdd.put(CPUS_FIELD, hostStatsEntry.getHostVo().getCpus());
+        fieldsToAdd.put(CPU_SOCKETS_FIELD, hostStatsEntry.getHostVo().getCpuSockets());
+        fieldsToAdd.put(NETWORK_READ_KBS_FIELD, hostStatsEntry.getNetworkReadKBs());
+        fieldsToAdd.put(NETWORK_WRITE_KBS_FIELD, hostStatsEntry.getNetworkWriteKBs());
+
+        return Point.measurement(INFLUXDB_HOST_MEASUREMENT).tag(tagsToAdd).time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).fields(fieldsToAdd).build();
+    }
+
+    /**
+     * Sends VMs metrics to a configured InfluxDB host. The metrics respects the following specification.</br>
+     * <b>Tags:</b>vm_id, uuid, instance_name, data_center_id, host_id</br>
+     * <b>Fields:</b>memory_total_kb, memory_internal_free_kbs, memory_target_kbs, cpu_utilization, cpus, network_write_kb, disk_read_iops, disk_read_kbs, disk_write_iops, disk_write_kbs
+     */
+    protected Point createInfluxDbPointForVmMetrics(Object metricsObject) {
+        VmStatsEntry vmStatsEntry = (VmStatsEntry)metricsObject;
+        UserVmVO userVmVO = vmStatsEntry.getUserVmVO();
+
+        Map<String, String> tagsToAdd = new HashMap<>();
+        tagsToAdd.put(UUID_TAG, userVmVO.getUuid());
+
+        Map<String, Object> fieldsToAdd = new HashMap<>();
+        fieldsToAdd.put(TOTAL_MEMORY_KBS_FIELD, vmStatsEntry.getMemoryKBs());
+        fieldsToAdd.put(FREE_MEMORY_KBS_FIELD, vmStatsEntry.getIntFreeMemoryKBs());
+        fieldsToAdd.put(MEMORY_TARGET_KBS_FIELD, vmStatsEntry.getTargetMemoryKBs());
+        fieldsToAdd.put(CPU_UTILIZATION_FIELD, vmStatsEntry.getCPUUtilization());
+        fieldsToAdd.put(CPUS_FIELD, vmStatsEntry.getNumCPUs());
+        fieldsToAdd.put(NETWORK_READ_KBS_FIELD, vmStatsEntry.getNetworkReadKBs());
+        fieldsToAdd.put(NETWORK_WRITE_KBS_FIELD, vmStatsEntry.getNetworkWriteKBs());
+        fieldsToAdd.put(DISK_READ_IOPS_FIELD, vmStatsEntry.getDiskReadIOs());
+        fieldsToAdd.put(DISK_READ_KBS_FIELD, vmStatsEntry.getDiskReadKBs());
+        fieldsToAdd.put(DISK_WRITE_IOPS_FIELD, vmStatsEntry.getDiskWriteIOs());
+        fieldsToAdd.put(DISK_WRITE_KBS_FIELD, vmStatsEntry.getDiskWriteKBs());
+
+        return Point.measurement(INFLUXDB_VM_MEASUREMENT).tag(tagsToAdd).time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).fields(fieldsToAdd).build();
+    }
+
+    /**
+     * Creates connection to InfluxDB. If the database does not exist, it throws a CloudRuntimeException. </br>
+     * @note the user can configure the database name on parameter 'stats.output.influxdb.database.name'; such database must be yet created and configured by the user.
+     * The Default name for the database is 'cloudstack_stats'.
+     */
+    protected InfluxDB createInfluxDbConnection() {
+        String influxDbQueryUrl = String.format("http://%s:%s/", externalStatsHost, externalStatsPort);
+        InfluxDB influxDbConnection = InfluxDBFactory.connect(influxDbQueryUrl);
+
+        if (!influxDbConnection.databaseExists(databaseName)) {
+            throw new CloudRuntimeException(String.format("Database with name %s does not exist in influxdb host %s:%s", databaseName, externalStatsHost, externalStatsPort));
+        }
+
+        return influxDbConnection;
+    }
+
+    /**
+     * Writes batches of InfluxDB database points into a given database.
+     */
+    protected void writeBatches(InfluxDB influxDbConnection, String dbName, List<Point> points) {
+        BatchPoints batchPoints = BatchPoints.database(dbName).build();
+
+        for (Point point : points) {
+            batchPoints.point(point);
+        }
+
+        influxDbConnection.write(batchPoints);
+    }
+
+    /**
+     * Returns true if at least one of the current disk stats is different from the previous.</br>
+     * The considered disk stats are the following: bytes read, bytes write, IO read,  and IO write.
+     */
+    protected boolean isCurrentVmDiskStatsDifferentFromPrevious(VmDiskStatisticsVO previousVmDiskStats, VmDiskStatisticsVO currentVmDiskStats) {
+        if (previousVmDiskStats != null) {
+            boolean bytesReadDifferentFromPrevious = previousVmDiskStats.getCurrentBytesRead() != currentVmDiskStats.getCurrentBytesRead();
+            boolean bytesWriteDifferentFromPrevious = previousVmDiskStats.getCurrentBytesWrite() != currentVmDiskStats.getCurrentBytesWrite();
+            boolean ioReadDifferentFromPrevious = previousVmDiskStats.getCurrentIORead() != currentVmDiskStats.getCurrentIORead();
+            boolean ioWriteDifferentFromPrevious = previousVmDiskStats.getCurrentIOWrite() != currentVmDiskStats.getCurrentIOWrite();
+            return bytesReadDifferentFromPrevious || bytesWriteDifferentFromPrevious || ioReadDifferentFromPrevious || ioWriteDifferentFromPrevious;
+        }
+        if (currentVmDiskStats == null) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if all the VmDiskStatsEntry are Zeros (Bytes read, Bytes write, IO read, and IO write must be all equals to zero)
+     */
+    protected boolean areAllDiskStatsZero(VmDiskStatsEntry vmDiskStat) {
+        return (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0) && (vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0);
+    }
+
+    /**
+     * Creates a HostVO SearchCriteria where:
+     * <ul>
+     *  <li>"status" is Up;</li>
+     *  <li>"resourceState" is not in Maintenance, PrepareForMaintenance, or ErrorInMaintenance; and</li>
+     *  <li>"type" is Routing.</li>
+     * </ul>
+     */
+    private SearchCriteria<HostVO> createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance() {
+        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
+        sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
+        sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
+        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString());
+        return sc;
+    }
+
+    public StorageStats getStorageStats(long id) {
+        return _storageStats.get(id);
+    }
+
+    public HostStats getHostStats(long hostId) {
+        return _hostStats.get(hostId);
+    }
+
+    public StorageStats getStoragePoolStats(long id) {
+        return _storagePoolStats.get(id);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return StatsCollector.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {vmDiskStatsInterval, vmDiskStatsIntervalMin, vmNetworkStatsInterval, vmNetworkStatsIntervalMin, StatsTimeout, statsOutputUri};
+    }
+}
diff --git a/server/src/com/cloud/server/api/response/BaremetalTemplateResponse.java b/server/src/main/java/com/cloud/server/api/response/BaremetalTemplateResponse.java
similarity index 100%
rename from server/src/com/cloud/server/api/response/BaremetalTemplateResponse.java
rename to server/src/main/java/com/cloud/server/api/response/BaremetalTemplateResponse.java
diff --git a/server/src/com/cloud/server/api/response/NwDeviceDhcpResponse.java b/server/src/main/java/com/cloud/server/api/response/NwDeviceDhcpResponse.java
similarity index 100%
rename from server/src/com/cloud/server/api/response/NwDeviceDhcpResponse.java
rename to server/src/main/java/com/cloud/server/api/response/NwDeviceDhcpResponse.java
diff --git a/server/src/com/cloud/server/api/response/NwDevicePxeServerResponse.java b/server/src/main/java/com/cloud/server/api/response/NwDevicePxeServerResponse.java
similarity index 100%
rename from server/src/com/cloud/server/api/response/NwDevicePxeServerResponse.java
rename to server/src/main/java/com/cloud/server/api/response/NwDevicePxeServerResponse.java
diff --git a/server/src/com/cloud/server/api/response/PxePingResponse.java b/server/src/main/java/com/cloud/server/api/response/PxePingResponse.java
similarity index 100%
rename from server/src/com/cloud/server/api/response/PxePingResponse.java
rename to server/src/main/java/com/cloud/server/api/response/PxePingResponse.java
diff --git a/server/src/com/cloud/server/auth/UserAuthenticator.java b/server/src/main/java/com/cloud/server/auth/UserAuthenticator.java
similarity index 100%
rename from server/src/com/cloud/server/auth/UserAuthenticator.java
rename to server/src/main/java/com/cloud/server/auth/UserAuthenticator.java
diff --git a/server/src/com/cloud/servlet/CloudStartupServlet.java b/server/src/main/java/com/cloud/servlet/CloudStartupServlet.java
similarity index 100%
rename from server/src/com/cloud/servlet/CloudStartupServlet.java
rename to server/src/main/java/com/cloud/servlet/CloudStartupServlet.java
diff --git a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java b/server/src/main/java/com/cloud/servlet/ConsoleProxyClientParam.java
similarity index 100%
rename from server/src/com/cloud/servlet/ConsoleProxyClientParam.java
rename to server/src/main/java/com/cloud/servlet/ConsoleProxyClientParam.java
diff --git a/server/src/com/cloud/servlet/ConsoleProxyPasswordBasedEncryptor.java b/server/src/main/java/com/cloud/servlet/ConsoleProxyPasswordBasedEncryptor.java
similarity index 100%
rename from server/src/com/cloud/servlet/ConsoleProxyPasswordBasedEncryptor.java
rename to server/src/main/java/com/cloud/servlet/ConsoleProxyPasswordBasedEncryptor.java
diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/main/java/com/cloud/servlet/ConsoleProxyServlet.java
similarity index 100%
rename from server/src/com/cloud/servlet/ConsoleProxyServlet.java
rename to server/src/main/java/com/cloud/servlet/ConsoleProxyServlet.java
diff --git a/server/src/com/cloud/storage/CreateSnapshotPayload.java b/server/src/main/java/com/cloud/storage/CreateSnapshotPayload.java
similarity index 100%
rename from server/src/com/cloud/storage/CreateSnapshotPayload.java
rename to server/src/main/java/com/cloud/storage/CreateSnapshotPayload.java
diff --git a/server/src/com/cloud/storage/ImageStoreDetailsUtil.java b/server/src/main/java/com/cloud/storage/ImageStoreDetailsUtil.java
similarity index 100%
rename from server/src/com/cloud/storage/ImageStoreDetailsUtil.java
rename to server/src/main/java/com/cloud/storage/ImageStoreDetailsUtil.java
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitor.java b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitor.java
similarity index 100%
rename from server/src/com/cloud/storage/ImageStoreUploadMonitor.java
rename to server/src/main/java/com/cloud/storage/ImageStoreUploadMonitor.java
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
rename to server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/main/java/com/cloud/storage/LocalStoragePoolListener.java
similarity index 100%
rename from server/src/com/cloud/storage/LocalStoragePoolListener.java
rename to server/src/main/java/com/cloud/storage/LocalStoragePoolListener.java
diff --git a/server/src/com/cloud/storage/OCFS2Manager.java b/server/src/main/java/com/cloud/storage/OCFS2Manager.java
similarity index 100%
rename from server/src/com/cloud/storage/OCFS2Manager.java
rename to server/src/main/java/com/cloud/storage/OCFS2Manager.java
diff --git a/server/src/com/cloud/storage/OCFS2ManagerImpl.java b/server/src/main/java/com/cloud/storage/OCFS2ManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/OCFS2ManagerImpl.java
rename to server/src/main/java/com/cloud/storage/OCFS2ManagerImpl.java
diff --git a/server/src/com/cloud/storage/RegisterVolumePayload.java b/server/src/main/java/com/cloud/storage/RegisterVolumePayload.java
similarity index 100%
rename from server/src/com/cloud/storage/RegisterVolumePayload.java
rename to server/src/main/java/com/cloud/storage/RegisterVolumePayload.java
diff --git a/server/src/com/cloud/storage/ResizeVolumePayload.java b/server/src/main/java/com/cloud/storage/ResizeVolumePayload.java
similarity index 100%
rename from server/src/com/cloud/storage/ResizeVolumePayload.java
rename to server/src/main/java/com/cloud/storage/ResizeVolumePayload.java
diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java
new file mode 100644
index 0000000..40ecb84
--- /dev/null
+++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java
@@ -0,0 +1,2529 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
+import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
+import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.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.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.TemplateJoinDao;
+import com.cloud.api.query.vo.TemplateJoinVO;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.CapacityState;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.ConfigurationManagerImpl;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageConflictException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.org.Grouping;
+import com.cloud.org.Grouping.AllocationState;
+import com.cloud.resource.ResourceState;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.server.ManagementServer;
+import com.cloud.server.StatsCollector;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.StoragePoolTagsDao;
+import com.cloud.storage.dao.StoragePoolWorkDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.listener.StoragePoolMonitor;
+import com.cloud.storage.listener.VolumeStateListener;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Component
+public class StorageManagerImpl extends ManagerBase implements StorageManager, ClusterManagerListener, Configurable {
+    private static final Logger s_logger = Logger.getLogger(StorageManagerImpl.class);
+
+    protected String _name;
+    @Inject
+    protected AgentManager _agentMgr;
+    @Inject
+    protected TemplateManager _tmpltMgr;
+    @Inject
+    protected AccountManager _accountMgr;
+    @Inject
+    protected ConfigurationManager _configMgr;
+    @Inject
+    protected VolumeDao _volsDao;
+    @Inject
+    private VolumeDataStoreDao _volumeDataStoreDao;
+    @Inject
+    protected HostDao _hostDao;
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    @Inject
+    protected StoragePoolHostDao _storagePoolHostDao;
+    @Inject
+    protected VMTemplatePoolDao _vmTemplatePoolDao = null;
+    @Inject
+    protected VMTemplateZoneDao _vmTemplateZoneDao;
+    @Inject
+    protected VMTemplateDao _vmTemplateDao = null;
+    @Inject
+    protected VMInstanceDao _vmInstanceDao;
+    @Inject
+    protected PrimaryDataStoreDao _storagePoolDao = null;
+    @Inject
+    protected StoragePoolDetailsDao _storagePoolDetailsDao;
+    @Inject
+    protected ImageStoreDao _imageStoreDao = null;
+    @Inject
+    protected ImageStoreDetailsDao _imageStoreDetailsDao = null;
+    @Inject
+    protected SnapshotDataStoreDao _snapshotStoreDao = null;
+    @Inject
+    protected TemplateDataStoreDao _templateStoreDao = null;
+    @Inject
+    protected TemplateJoinDao _templateViewDao = null;
+    @Inject
+    protected VolumeDataStoreDao _volumeStoreDao = null;
+    @Inject
+    protected CapacityDao _capacityDao;
+    @Inject
+    protected CapacityManager _capacityMgr;
+    @Inject
+    protected DataCenterDao _dcDao = null;
+    @Inject
+    protected VMTemplateDao _templateDao;
+    @Inject
+    protected UserDao _userDao;
+    @Inject
+    protected ClusterDao _clusterDao;
+    @Inject
+    protected StoragePoolWorkDao _storagePoolWorkDao;
+    @Inject
+    protected HypervisorGuruManager _hvGuruMgr;
+    @Inject
+    protected VolumeDao _volumeDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    ManagementServer _msServer;
+    @Inject
+    VolumeService volService;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    TemplateDataFactory tmplFactory;
+    @Inject
+    SnapshotDataFactory snapshotFactory;
+    @Inject
+    ConfigurationServer _configServer;
+    @Inject
+    DataStoreManager _dataStoreMgr;
+    @Inject
+    DataStoreProviderManager _dataStoreProviderMgr;
+    @Inject
+    private TemplateService _imageSrv;
+    @Inject
+    EndPointSelector _epSelector;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    SnapshotService _snapshotService;
+    @Inject
+    StoragePoolTagsDao _storagePoolTagsDao;
+
+    protected List<StoragePoolDiscoverer> _discoverers;
+
+    public List<StoragePoolDiscoverer> getDiscoverers() {
+        return _discoverers;
+    }
+
+    public void setDiscoverers(List<StoragePoolDiscoverer> discoverers) {
+        _discoverers = discoverers;
+    }
+
+    protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
+    protected GenericSearchBuilder<StoragePoolHostVO, Long> UpHostsInPoolSearch;
+    protected SearchBuilder<VMInstanceVO> StoragePoolSearch;
+    protected SearchBuilder<StoragePoolVO> LocalStorageSearch;
+
+    ScheduledExecutorService _executor = null;
+    int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes
+    int _downloadUrlCleanupInterval;
+    int _downloadUrlExpirationInterval;
+    // protected BigDecimal _overProvisioningFactor = new BigDecimal(1);
+    private long _serverId;
+
+    private final Map<String, HypervisorHostListener> hostListeners = new HashMap<String, HypervisorHostListener>();
+
+    public boolean share(VMInstanceVO vm, List<VolumeVO> vols, HostVO host, boolean cancelPreviousShare) throws StorageUnavailableException {
+
+        // if pool is in maintenance and it is the ONLY pool available; reject
+        List<VolumeVO> rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), Type.ROOT);
+        if (rootVolForGivenVm != null && rootVolForGivenVm.size() > 0) {
+            boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId());
+            if (!isPoolAvailable) {
+                throw new StorageUnavailableException("Can not share " + vm, rootVolForGivenVm.get(0).getPoolId());
+            }
+        }
+
+        // this check is done for maintenance mode for primary storage
+        // if any one of the volume is unusable, we return false
+        // if we return false, the allocator will try to switch to another PS if
+        // available
+        for (VolumeVO vol : vols) {
+            if (vol.getRemoved() != null) {
+                s_logger.warn("Volume id:" + vol.getId() + " is removed, cannot share on this instance");
+                // not ok to share
+                return false;
+            }
+        }
+        // ok to share
+        return true;
+    }
+
+    private boolean isPoolAvailable(Long poolId) {
+        // get list of all pools
+        List<StoragePoolVO> pools = _storagePoolDao.listAll();
+
+        // if no pools or 1 pool which is in maintenance
+        if (pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(StoragePoolStatus.Maintenance))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, HypervisorType type) {
+        List<StoragePoolVO> pools = _storagePoolDao.listByDataCenterId(datacenterId);
+        List<StoragePoolVO> retPools = new ArrayList<StoragePoolVO>();
+        for (StoragePoolVO pool : pools) {
+            if (pool.getStatus() != StoragePoolStatus.Up) {
+                continue;
+            }
+            if (pool.getScope() == ScopeType.ZONE) {
+                if (pool.getHypervisor() != null && pool.getHypervisor() == type) {
+                    retPools.add(pool);
+                }
+            } else {
+                ClusterVO cluster = _clusterDao.findById(pool.getClusterId());
+                if (type == cluster.getHypervisorType()) {
+                    retPools.add(pool);
+                }
+            }
+        }
+        Collections.shuffle(retPools);
+        return retPools;
+    }
+
+    @Override
+    public boolean isLocalStorageActiveOnHost(Long hostId) {
+        List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId);
+        for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) {
+            StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(storagePoolHostRef.getPoolId());
+            if (PrimaryDataStoreVO.getPoolType() == StoragePoolType.LVM || PrimaryDataStoreVO.getPoolType() == StoragePoolType.EXT) {
+                SearchBuilder<VolumeVO> volumeSB = _volsDao.createSearchBuilder();
+                volumeSB.and("poolId", volumeSB.entity().getPoolId(), SearchCriteria.Op.EQ);
+                volumeSB.and("removed", volumeSB.entity().getRemoved(), SearchCriteria.Op.NULL);
+                volumeSB.and("state", volumeSB.entity().getState(), SearchCriteria.Op.NIN);
+
+                SearchBuilder<VMInstanceVO> activeVmSB = _vmInstanceDao.createSearchBuilder();
+                activeVmSB.and("state", activeVmSB.entity().getState(), SearchCriteria.Op.IN);
+                volumeSB.join("activeVmSB", activeVmSB, volumeSB.entity().getInstanceId(), activeVmSB.entity().getId(), JoinBuilder.JoinType.INNER);
+
+                SearchCriteria<VolumeVO> volumeSC = volumeSB.create();
+                volumeSC.setParameters("poolId", PrimaryDataStoreVO.getId());
+                volumeSC.setParameters("state", Volume.State.Expunging, Volume.State.Destroy);
+                volumeSC.setJoinParameters("activeVmSB", "state", State.Starting, State.Running, State.Stopping, State.Migrating);
+
+                List<VolumeVO> volumes = _volsDao.search(volumeSC, null);
+                if (volumes.size() > 0) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException {
+        return sendToPool(pool, null, null, cmds).second();
+    }
+
+    @Override
+    public Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException {
+        Answer[] answers = sendToPool(pool, hostIdsToTryFirst, null, new Commands(cmd)).second();
+        if (answers == null) {
+            return null;
+        }
+        return answers[0];
+    }
+
+    @Override
+    public Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException {
+        Answer[] answers = sendToPool(pool, new Commands(cmd));
+        if (answers == null) {
+            return null;
+        }
+        return answers[0];
+    }
+
+    public Long chooseHostForStoragePool(StoragePoolVO poolVO, List<Long> avoidHosts, boolean sendToVmResidesOn, Long vmId) {
+        if (sendToVmResidesOn) {
+            if (vmId != null) {
+                VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+                if (vmInstance != null) {
+                    Long hostId = vmInstance.getHostId();
+                    if (hostId != null && !avoidHosts.contains(vmInstance.getHostId())) {
+                        return hostId;
+                    }
+                }
+            }
+            /*
+             * Can't find the vm where host resides on(vm is destroyed? or
+             * volume is detached from vm), randomly choose a host to send the
+             * cmd
+             */
+        }
+        List<StoragePoolHostVO> poolHosts = _storagePoolHostDao.listByHostStatus(poolVO.getId(), Status.Up);
+        Collections.shuffle(poolHosts);
+        if (poolHosts != null && poolHosts.size() > 0) {
+            for (StoragePoolHostVO sphvo : poolHosts) {
+                if (!avoidHosts.contains(sphvo.getHostId())) {
+                    return sphvo.getHostId();
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) {
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+        _storagePoolAcquisitionWaitSeconds = NumbersUtil.parseInt(configs.get("pool.acquisition.wait.seconds"), 1800);
+        s_logger.info("pool.acquisition.wait.seconds is configured as " + _storagePoolAcquisitionWaitSeconds + " seconds");
+
+        _agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
+
+        s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value()
+        + ", template cleanup enabled: " + TemplateCleanupEnabled.value());
+
+        String cleanupInterval = configs.get("extract.url.cleanup.interval");
+        _downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
+
+        String urlExpirationInterval = configs.get("extract.url.expiration.interval");
+        _downloadUrlExpirationInterval = NumbersUtil.parseInt(urlExpirationInterval, 14400);
+
+        String workers = configs.get("expunge.workers");
+        int wrks = NumbersUtil.parseInt(workers, 10);
+        _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("StorageManager-Scavenger"));
+
+        _agentMgr.registerForHostEvents(ComponentContext.inject(LocalStoragePoolListener.class), true, false, false);
+
+        _serverId = _msServer.getId();
+
+        UpHostsInPoolSearch = _storagePoolHostDao.createSearchBuilder(Long.class);
+        UpHostsInPoolSearch.selectFields(UpHostsInPoolSearch.entity().getHostId());
+        SearchBuilder<HostVO> hostSearch = _hostDao.createSearchBuilder();
+        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
+        hostSearch.and("resourceState", hostSearch.entity().getResourceState(), Op.EQ);
+        UpHostsInPoolSearch.join("hosts", hostSearch, hostSearch.entity().getId(), UpHostsInPoolSearch.entity().getHostId(), JoinType.INNER);
+        UpHostsInPoolSearch.and("pool", UpHostsInPoolSearch.entity().getPoolId(), Op.EQ);
+        UpHostsInPoolSearch.done();
+
+        StoragePoolSearch = _vmInstanceDao.createSearchBuilder();
+
+        SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
+        volumeSearch.and("volumeType", volumeSearch.entity().getVolumeType(), SearchCriteria.Op.EQ);
+        volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+        volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ);
+        StoragePoolSearch.join("vmVolume", volumeSearch, volumeSearch.entity().getInstanceId(), StoragePoolSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        StoragePoolSearch.done();
+
+        LocalStorageSearch = _storagePoolDao.createSearchBuilder();
+        SearchBuilder<StoragePoolHostVO> storageHostSearch = _storagePoolHostDao.createSearchBuilder();
+        storageHostSearch.and("hostId", storageHostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
+        LocalStorageSearch.join("poolHost", storageHostSearch, storageHostSearch.entity().getPoolId(), LocalStorageSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+        LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN);
+        LocalStorageSearch.done();
+
+        Volume.State.getStateMachine().registerListener(new VolumeStateListener(_configDao, _vmInstanceDao));
+
+        return true;
+    }
+
+    @Override
+    public String getStoragePoolTags(long poolId) {
+        return StringUtils.listToCsvTags(getStoragePoolTagList(poolId));
+    }
+
+    @Override
+    public List<String> getStoragePoolTagList(long poolId) {
+        return _storagePoolDao.searchForStoragePoolTags(poolId);
+    }
+
+    @Override
+    public boolean start() {
+        if (StorageCleanupEnabled.value()) {
+            Random generator = new Random();
+            int initialDelay = generator.nextInt(StorageCleanupInterval.value());
+            _executor.scheduleWithFixedDelay(new StorageGarbageCollector(), initialDelay, StorageCleanupInterval.value(), TimeUnit.SECONDS);
+        } else {
+            s_logger.debug("Storage cleanup is not enabled, so the storage cleanup thread is not being scheduled.");
+        }
+
+        _executor.scheduleWithFixedDelay(new DownloadURLGarbageCollector(), _downloadUrlCleanupInterval, _downloadUrlCleanupInterval, TimeUnit.SECONDS);
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        if (StorageCleanupEnabled.value()) {
+            _executor.shutdown();
+        }
+        return true;
+    }
+
+    @DB
+    @Override
+    public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException {
+        DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
+        if (dc == null) {
+            return null;
+        }
+        boolean useLocalStorageForSystemVM = false;
+        Boolean isLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dc.getId());
+        if (isLocal != null) {
+            useLocalStorageForSystemVM = isLocal.booleanValue();
+        }
+        if (!(dc.isLocalStorageEnabled() || useLocalStorageForSystemVM)) {
+            return null;
+        }
+        DataStore store;
+        try {
+            String hostAddress = pInfo.getHost();
+            if (host.getHypervisorType() == Hypervisor.HypervisorType.VMware) {
+                hostAddress = "VMFS datastore: " + pInfo.getHostPath();
+            }
+            StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, pInfo.getHostPath(), pInfo.getUuid());
+            if (pool == null && host.getHypervisorType() == HypervisorType.VMware) {
+                // perform run-time upgrade. In versions prior to 2.2.12, there
+                // is a bug that we don't save local datastore info (host path
+                // is empty), this will cause us
+                // not able to distinguish multiple local datastores that may be
+                // available on the host, to support smooth migration, we
+                // need to perform runtime upgrade here
+                if (pInfo.getHostPath().length() > 0) {
+                    pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, "", pInfo.getUuid());
+                }
+            }
+            if (pool == null) {
+                //the path can be different, but if they have the same uuid, assume they are the same storage
+                pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, null, pInfo.getUuid());
+                if (pool != null) {
+                    s_logger.debug("Found a storage pool: " + pInfo.getUuid() + ", but with different hostpath " + pInfo.getHostPath() + ", still treat it as the same pool");
+                }
+            }
+
+            DataStoreProvider provider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
+            DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+            if (pool == null) {
+                Map<String, Object> params = new HashMap<String, Object>();
+                String name = createLocalStoragePoolName(host, pInfo);
+                params.put("zoneId", host.getDataCenterId());
+                params.put("clusterId", host.getClusterId());
+                params.put("podId", host.getPodId());
+                params.put("url", pInfo.getPoolType().toString() + "://" + pInfo.getHost() + "/" + pInfo.getHostPath());
+                params.put("name", name);
+                params.put("localStorage", true);
+                params.put("details", pInfo.getDetails());
+                params.put("uuid", pInfo.getUuid());
+                params.put("providerName", provider.getName());
+
+                store = lifeCycle.initialize(params);
+            } else {
+                store = _dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+            }
+
+            pool = _storagePoolDao.findById(store.getId());
+            if (pool.getStatus() != StoragePoolStatus.Maintenance && pool.getStatus() != StoragePoolStatus.Removed) {
+                HostScope scope = new HostScope(host.getId(), host.getClusterId(), host.getDataCenterId());
+                lifeCycle.attachHost(store, scope, pInfo);
+            }
+
+        } catch (Exception e) {
+            s_logger.warn("Unable to setup the local storage pool for " + host, e);
+            throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e);
+        }
+
+        return _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
+    }
+
+    /**
+     * Creates the local storage pool name.
+     * The name will follow the pattern: <hostname>-local-<firstBlockOfUuid>
+     */
+    protected String createLocalStoragePoolName(Host host, StoragePoolInfo storagePoolInformation) {
+        return String.format("%s-%s-%s", org.apache.commons.lang3.StringUtils.trim(host.getName()), "local", storagePoolInformation.getUuid().split("-")[0]);
+    }
+
+    @Override
+    public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException {
+        String providerName = cmd.getStorageProviderName();
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
+
+        if (storeProvider == null) {
+            storeProvider = _dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider();
+            if (storeProvider == null) {
+                throw new InvalidParameterValueException("can't find storage provider: " + providerName);
+            }
+        }
+
+        Long clusterId = cmd.getClusterId();
+        Long podId = cmd.getPodId();
+        Long zoneId = cmd.getZoneId();
+
+        ScopeType scopeType = ScopeType.CLUSTER;
+        String scope = cmd.getScope();
+        if (scope != null) {
+            try {
+                scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
+            } catch (Exception e) {
+                throw new InvalidParameterValueException("invalid scope for pool " + scope);
+            }
+        }
+
+        if (scopeType == ScopeType.CLUSTER && clusterId == null) {
+            throw new InvalidParameterValueException("cluster id can't be null, if scope is cluster");
+        } else if (scopeType == ScopeType.ZONE && zoneId == null) {
+            throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
+        }
+
+        HypervisorType hypervisorType = HypervisorType.KVM;
+        if (scopeType == ScopeType.ZONE) {
+            // ignore passed clusterId and podId
+            clusterId = null;
+            podId = null;
+            String hypervisor = cmd.getHypervisor();
+            if (hypervisor != null) {
+                try {
+                    hypervisorType = HypervisorType.getType(hypervisor);
+                } catch (Exception e) {
+                    throw new InvalidParameterValueException("invalid hypervisor type " + hypervisor);
+                }
+            } else {
+                throw new InvalidParameterValueException("Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage.");
+            }
+            if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Hyperv && hypervisorType != HypervisorType.LXC
+                    && hypervisorType != HypervisorType.Any) {
+                throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor);
+            }
+        }
+
+        Map<String, String> details = extractApiParamAsMap(cmd.getDetails());
+        DataCenterVO zone = _dcDao.findById(cmd.getZoneId());
+        if (zone == null) {
+            throw new InvalidParameterValueException("unable to find zone by id " + zoneId);
+        }
+        // Check if zone is disabled
+        Account account = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+        }
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("zoneId", zone.getId());
+        params.put("clusterId", clusterId);
+        params.put("podId", podId);
+        params.put("url", cmd.getUrl());
+        params.put("tags", cmd.getTags());
+        params.put("name", cmd.getStoragePoolName());
+        params.put("details", details);
+        params.put("providerName", storeProvider.getName());
+        params.put("managed", cmd.isManaged());
+        params.put("capacityBytes", cmd.getCapacityBytes());
+        params.put("capacityIops", cmd.getCapacityIops());
+
+        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+        DataStore store = null;
+        try {
+            store = lifeCycle.initialize(params);
+            if (scopeType == ScopeType.CLUSTER) {
+                ClusterScope clusterScope = new ClusterScope(clusterId, podId, zoneId);
+                lifeCycle.attachCluster(store, clusterScope);
+            } else if (scopeType == ScopeType.ZONE) {
+                ZoneScope zoneScope = new ZoneScope(zoneId);
+                lifeCycle.attachZone(store, zoneScope, hypervisorType);
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to add data store: " + e.getMessage(), e);
+            try {
+                // clean up the db, just absorb the exception thrown in deletion with error logged, so that user can get error for adding data store
+                // not deleting data store.
+                if (store != null) {
+                    lifeCycle.deleteDataStore(store);
+                }
+            } catch (Exception ex) {
+                s_logger.debug("Failed to clean up storage pool: " + ex.getMessage());
+            }
+            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
+        }
+
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
+    }
+
+    private Map<String, String> extractApiParamAsMap(Map ds) {
+        Map<String, String> details = new HashMap<String, String>();
+        if (ds != null) {
+            Collection detailsCollection = ds.values();
+            Iterator it = detailsCollection.iterator();
+            while (it.hasNext()) {
+                HashMap d = (HashMap)it.next();
+                Iterator it2 = d.entrySet().iterator();
+                while (it2.hasNext()) {
+                    Map.Entry entry = (Map.Entry)it2.next();
+                    details.put((String)entry.getKey(), (String)entry.getValue());
+                }
+            }
+        }
+        return details;
+    }
+
+    @ActionEvent(eventType = EventTypes.EVENT_DISABLE_PRIMARY_STORAGE, eventDescription = "disable storage pool")
+    private void disablePrimaryStoragePool(StoragePoolVO primaryStorage) {
+        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up)) {
+            throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be disabled. Storage pool state : " + primaryStorage.getStatus().toString());
+        }
+
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreLifeCycle dataStoreLifeCycle = provider.getDataStoreLifeCycle();
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).disableStoragePool(store);
+    }
+
+    @ActionEvent(eventType = EventTypes.EVENT_ENABLE_PRIMARY_STORAGE, eventDescription = "enable storage pool")
+    private void enablePrimaryStoragePool(StoragePoolVO primaryStorage) {
+        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Disabled)) {
+            throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be enabled. Storage pool state : " + primaryStorage.getStatus().toString());
+        }
+
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreLifeCycle dataStoreLifeCycle = provider.getDataStoreLifeCycle();
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).enableStoragePool(store);
+    }
+
+    @Override
+    public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException {
+        // Input validation
+        Long id = cmd.getId();
+
+        StoragePoolVO pool = _storagePoolDao.findById(id);
+        if (pool == null) {
+            throw new IllegalArgumentException("Unable to find storage pool with ID: " + id);
+        }
+
+        final List<String> storagePoolTags = cmd.getTags();
+        if (storagePoolTags != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Updating Storage Pool Tags to :" + storagePoolTags);
+            }
+            _storagePoolTagsDao.persist(pool.getId(), storagePoolTags);
+        }
+
+        Long updatedCapacityBytes = null;
+        Long capacityBytes = cmd.getCapacityBytes();
+
+        if (capacityBytes != null) {
+            if (capacityBytes != pool.getCapacityBytes()) {
+                updatedCapacityBytes = capacityBytes;
+            }
+        }
+
+        Long updatedCapacityIops = null;
+        Long capacityIops = cmd.getCapacityIops();
+
+        if (capacityIops != null) {
+            if (!capacityIops.equals(pool.getCapacityIops())) {
+                updatedCapacityIops = capacityIops;
+            }
+        }
+
+        if (updatedCapacityBytes != null || updatedCapacityIops != null) {
+            StoragePoolVO storagePool = _storagePoolDao.findById(id);
+            DataStoreProvider dataStoreProvider = _dataStoreProviderMgr.getDataStoreProvider(storagePool.getStorageProviderName());
+            DataStoreLifeCycle dataStoreLifeCycle = dataStoreProvider.getDataStoreLifeCycle();
+
+            if (dataStoreLifeCycle instanceof PrimaryDataStoreLifeCycle) {
+                Map<String, String> details = new HashMap<String, String>();
+
+                details.put(PrimaryDataStoreLifeCycle.CAPACITY_BYTES, updatedCapacityBytes != null ? String.valueOf(updatedCapacityBytes) : null);
+                details.put(PrimaryDataStoreLifeCycle.CAPACITY_IOPS, updatedCapacityIops != null ? String.valueOf(updatedCapacityIops) : null);
+
+                ((PrimaryDataStoreLifeCycle)dataStoreLifeCycle).updateStoragePool(storagePool, details);
+            }
+        }
+
+        Boolean enabled = cmd.getEnabled();
+        if (enabled != null) {
+            if (enabled) {
+                enablePrimaryStoragePool(pool);
+            } else {
+                disablePrimaryStoragePool(pool);
+            }
+        }
+
+        if (updatedCapacityBytes != null) {
+            _storagePoolDao.updateCapacityBytes(id, capacityBytes);
+        }
+
+        if (updatedCapacityIops != null) {
+            _storagePoolDao.updateCapacityIops(id, capacityIops);
+        }
+
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
+    }
+
+    @Override
+    public void removeStoragePoolFromCluster(long hostId, String iScsiName, StoragePool storagePool) {
+        final Map<String, String> details = new HashMap<>();
+
+        details.put(DeleteStoragePoolCommand.DATASTORE_NAME, iScsiName);
+        details.put(DeleteStoragePoolCommand.IQN, iScsiName);
+        details.put(DeleteStoragePoolCommand.STORAGE_HOST, storagePool.getHostAddress());
+        details.put(DeleteStoragePoolCommand.STORAGE_PORT, String.valueOf(storagePool.getPort()));
+
+        final DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand();
+
+        cmd.setDetails(details);
+        cmd.setRemoveDatastore(true);
+
+        final Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        if (answer == null || !answer.getResult()) {
+            String errMsg = "Error interacting with host (related to DeleteStoragePoolCommand)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : "");
+
+            s_logger.error(errMsg);
+
+            throw new CloudRuntimeException(errMsg);
+        }
+    }
+
+    @Override
+    @DB
+    public boolean deletePool(DeletePoolCmd cmd) {
+        Long id = cmd.getId();
+        boolean forced = cmd.isForced();
+
+        StoragePoolVO sPool = _storagePoolDao.findById(id);
+        if (sPool == null) {
+            s_logger.warn("Unable to find pool:" + id);
+            throw new InvalidParameterValueException("Unable to find pool by id " + id);
+        }
+        if (sPool.getStatus() != StoragePoolStatus.Maintenance) {
+            s_logger.warn("Unable to delete storage id: " + id + " due to it is not in Maintenance state");
+            throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
+        }
+        Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(id);
+        if (forced) {
+            if (vlms.first() > 0) {
+                Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(id);
+                if (nonDstrdVlms.first() > 0) {
+                    throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
+                }
+                // force expunge non-destroyed volumes
+                List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed();
+                for (VolumeVO vol : vols) {
+                    AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));
+                    try {
+                        future.get();
+                    } catch (InterruptedException e) {
+                        s_logger.debug("expunge volume failed:" + vol.getId(), e);
+                    } catch (ExecutionException e) {
+                        s_logger.debug("expunge volume failed:" + vol.getId(), e);
+                    }
+                }
+            }
+        } else {
+            // Check if the pool has associated volumes in the volumes table
+            // If it does , then you cannot delete the pool
+            if (vlms.first() > 0) {
+                throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated volumes for this pool");
+            }
+        }
+
+        // First get the host_id from storage_pool_host_ref for given pool id
+        StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId());
+
+        if (lock == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to acquire lock when deleting PrimaryDataStoreVO with ID: " + sPool.getId());
+            }
+            return false;
+        }
+
+        _storagePoolDao.releaseFromLockTable(lock.getId());
+        s_logger.trace("Released lock for storage pool " + id);
+
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
+        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+        DataStore store = _dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary);
+        return lifeCycle.deleteDataStore(store);
+    }
+
+    @Override
+    public void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException {
+        StoragePool pool = (StoragePool)_dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary);
+        assert (pool.isShared()) : "Now, did you actually read the name of this method?";
+        s_logger.debug("Adding pool " + pool.getName() + " to  host " + hostId);
+
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        HypervisorHostListener listener = hostListeners.get(provider.getName());
+        listener.hostConnect(hostId, pool.getId());
+    }
+
+    @Override
+    public BigDecimal getStorageOverProvisioningFactor(Long poolId) {
+        return new BigDecimal(CapacityManager.StorageOverprovisioningFactor.valueIn(poolId));
+    }
+
+    @Override
+    public void createCapacityEntry(StoragePoolVO storagePool, short capacityType, long allocated) {
+        SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
+        capacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, storagePool.getId());
+        capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, storagePool.getDataCenterId());
+        capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
+
+        List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
+
+        long totalOverProvCapacity;
+        if (storagePool.getPoolType().supportsOverProvisioning()) {
+            // All this is for the inaccuracy of floats for big number multiplication.
+            BigDecimal overProvFactor = getStorageOverProvisioningFactor(storagePool.getId());
+            totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();
+            s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString() + " with overprovisioning factor " + overProvFactor.toString());
+            s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + storagePool.getCapacityBytes());
+        } else {
+            s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString());
+            totalOverProvCapacity = storagePool.getCapacityBytes();
+        }
+
+        s_logger.debug("Total over provisioned capacity of the pool " + storagePool.getName() + " id: " + storagePool.getId() + " is " + totalOverProvCapacity);
+        CapacityState capacityState = CapacityState.Enabled;
+        if (storagePool.getScope() == ScopeType.ZONE) {
+            DataCenterVO dc = ApiDBUtils.findZoneById(storagePool.getDataCenterId());
+            AllocationState allocationState = dc.getAllocationState();
+            capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
+        } else {
+            if (storagePool.getClusterId() != null) {
+                ClusterVO cluster = ApiDBUtils.findClusterById(storagePool.getClusterId());
+                if (cluster != null) {
+                    AllocationState allocationState = _configMgr.findClusterAllocationState(cluster);
+                    capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
+                }
+            }
+        }
+
+        if (storagePool.getScope() == ScopeType.HOST) {
+            List<StoragePoolHostVO> stoargePoolHostVO = _storagePoolHostDao.listByPoolId(storagePool.getId());
+
+            if (stoargePoolHostVO != null && !stoargePoolHostVO.isEmpty()) {
+                HostVO host = _hostDao.findById(stoargePoolHostVO.get(0).getHostId());
+
+                if (host != null) {
+                    capacityState = (host.getResourceState() == ResourceState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
+                }
+            }
+        }
+
+        if (capacities.size() == 0) {
+            CapacityVO capacity = new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), storagePool.getClusterId(), allocated, totalOverProvCapacity,
+                    capacityType);
+            capacity.setCapacityState(capacityState);
+            _capacityDao.persist(capacity);
+        } else {
+            CapacityVO capacity = capacities.get(0);
+            if (capacity.getTotalCapacity() != totalOverProvCapacity || allocated != capacity.getUsedCapacity() || capacity.getCapacityState() != capacityState) {
+                capacity.setTotalCapacity(totalOverProvCapacity);
+                capacity.setUsedCapacity(allocated);
+                capacity.setCapacityState(capacityState);
+                _capacityDao.update(capacity.getId(), capacity);
+            }
+        }
+        s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - " + storagePool.getDataCenterId() + ", HostOrPoolId - "
+                + storagePool.getId() + ", PodId " + storagePool.getPodId());
+    }
+
+    @Override
+    public List<Long> getUpHostsInPool(long poolId) {
+        SearchCriteria<Long> sc = UpHostsInPoolSearch.create();
+        sc.setParameters("pool", poolId);
+        sc.setJoinParameters("hosts", "status", Status.Up);
+        sc.setJoinParameters("hosts", "resourceState", ResourceState.Enabled);
+        return _storagePoolHostDao.customSearch(sc, null);
+    }
+
+    @Override
+    public Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws StorageUnavailableException {
+        List<Long> hostIds = getUpHostsInPool(pool.getId());
+        Collections.shuffle(hostIds);
+        if (hostIdsToTryFirst != null) {
+            for (int i = hostIdsToTryFirst.length - 1; i >= 0; i--) {
+                if (hostIds.remove(hostIdsToTryFirst[i])) {
+                    hostIds.add(0, hostIdsToTryFirst[i]);
+                }
+            }
+        }
+
+        if (hostIdsToAvoid != null) {
+            hostIds.removeAll(hostIdsToAvoid);
+        }
+        if (hostIds == null || hostIds.isEmpty()) {
+            throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + " due to there is no enabled hosts up in this cluster", pool.getId());
+        }
+        for (Long hostId : hostIds) {
+            try {
+                List<Answer> answers = new ArrayList<Answer>();
+                Command[] cmdArray = cmds.toCommands();
+                for (Command cmd : cmdArray) {
+                    long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
+                    answers.add(_agentMgr.send(targetHostId, cmd));
+                }
+                return new Pair<Long, Answer[]>(hostId, answers.toArray(new Answer[answers.size()]));
+            } catch (AgentUnavailableException e) {
+                s_logger.debug("Unable to send storage pool command to " + pool + " via " + hostId, e);
+            } catch (OperationTimedoutException e) {
+                s_logger.debug("Unable to send storage pool command to " + pool + " via " + hostId, e);
+            }
+        }
+
+        throw new StorageUnavailableException("Unable to send command to the pool ", pool.getId());
+    }
+
+    @Override
+    public Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException {
+        Commands cmds = new Commands(cmd);
+        Pair<Long, Answer[]> result = sendToPool(pool, hostIdsToTryFirst, hostIdsToAvoid, cmds);
+        return new Pair<Long, Answer>(result.first(), result.second()[0]);
+    }
+
+    @Override
+    public void cleanupStorage(boolean recurring) {
+        GlobalLock scanLock = GlobalLock.getInternLock("storagemgr.cleanup");
+
+        try {
+            if (scanLock.lock(3)) {
+                try {
+                    // Cleanup primary storage pools
+                    if (TemplateCleanupEnabled.value()) {
+                        List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
+                        for (StoragePoolVO pool : storagePools) {
+                            try {
+
+                                List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
+                                s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
+                                for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
+                                    if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+                                        s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
+                                        + " because it is not completely downloaded.");
+                                        continue;
+                                    }
+
+                                    if (!templatePoolVO.getMarkedForGC()) {
+                                        templatePoolVO.setMarkedForGC(true);
+                                        _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
+                                        s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
+                                        + " for garbage collection.");
+                                        continue;
+                                    }
+
+                                    _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO);
+                                }
+                            } catch (Exception e) {
+                                s_logger.warn("Problem cleaning up primary storage pool " + pool, e);
+                            }
+                        }
+                    }
+
+                    //destroy snapshots in destroying state in snapshot_store_ref
+                    List<SnapshotDataStoreVO> ssSnapshots = _snapshotStoreDao.listByState(ObjectInDataStoreStateMachine.State.Destroying);
+                    for (SnapshotDataStoreVO ssSnapshotVO : ssSnapshots) {
+                        try {
+                            _snapshotService.deleteSnapshot(snapshotFactory.getSnapshot(ssSnapshotVO.getSnapshotId(), DataStoreRole.Image));
+                        } catch (Exception e) {
+                            s_logger.debug("Failed to delete snapshot: " + ssSnapshotVO.getId() + " from storage");
+                        }
+                    }
+                    cleanupSecondaryStorage(recurring);
+
+                    List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long)StorageCleanupDelay.value() << 10)));
+                    for (VolumeVO vol : vols) {
+                        try {
+                            // If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
+                            // system, but not necessary.
+                            handleManagedStorage(vol);
+                        } catch (Exception e) {
+                            s_logger.warn("Unable to destroy host-side clustered file system " + vol.getUuid(), e);
+                        }
+
+                        try {
+                            VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
+                            if (volumeInfo != null) {
+                                volService.expungeVolumeAsync(volumeInfo);
+                            } else {
+                                s_logger.debug("Volume " + vol.getUuid() + " is already destroyed");
+                            }
+                        } catch (Exception e) {
+                            s_logger.warn("Unable to destroy volume " + vol.getUuid(), e);
+                        }
+                    }
+
+                    // remove snapshots in Error state
+                    List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error);
+                    for (SnapshotVO snapshotVO : snapshots) {
+                        try {
+                            List<SnapshotDataStoreVO> storeRefs = _snapshotStoreDao.findBySnapshotId(snapshotVO.getId());
+                            for (SnapshotDataStoreVO ref : storeRefs) {
+                                _snapshotStoreDao.expunge(ref.getId());
+                            }
+                            _snapshotDao.expunge(snapshotVO.getId());
+                        } catch (Exception e) {
+                            s_logger.warn("Unable to destroy snapshot " + snapshotVO.getUuid(), e);
+                        }
+                    }
+
+                    // destroy uploaded volumes in abandoned/error state
+                    List<VolumeDataStoreVO> volumeDataStores = _volumeDataStoreDao.listByVolumeState(Volume.State.UploadError, Volume.State.UploadAbandoned);
+                    for (VolumeDataStoreVO volumeDataStore : volumeDataStores) {
+                        VolumeVO volume = _volumeDao.findById(volumeDataStore.getVolumeId());
+                        if (volume == null) {
+                            s_logger.warn("Uploaded volume with id " + volumeDataStore.getVolumeId() + " not found, so cannot be destroyed");
+                            continue;
+                        }
+                        try {
+                            DataStore dataStore = _dataStoreMgr.getDataStore(volumeDataStore.getDataStoreId(), DataStoreRole.Image);
+                            EndPoint ep = _epSelector.select(dataStore, volumeDataStore.getExtractUrl());
+                            if (ep == null) {
+                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded volume " + volume.getUuid());
+                                continue;
+                            }
+                            Host host = _hostDao.findById(ep.getId());
+                            if (host != null && host.getManagementServerId() != null) {
+                                if (_serverId == host.getManagementServerId().longValue()) {
+                                    volService.destroyVolume(volume.getId());
+                                    // decrement volume resource count
+                                    _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
+                                    // expunge volume from secondary if volume is on image store
+                                    VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
+                                    if (volOnSecondary != null) {
+                                        s_logger.info("Expunging volume " + volume.getUuid() + " uploaded using HTTP POST from secondary data store");
+                                        AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnSecondary);
+                                        VolumeApiResult result = future.get();
+                                        if (!result.isSuccess()) {
+                                            s_logger.warn("Failed to expunge volume " + volume.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
+                                        }
+                                    }
+                                }
+                            }
+                        } catch (Throwable th) {
+                            s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid() + ". Error details: " + th.getMessage());
+                        }
+                    }
+
+                    // destroy uploaded templates in abandoned/error state
+                    List<TemplateDataStoreVO> templateDataStores = _templateStoreDao.listByTemplateState(VirtualMachineTemplate.State.UploadError, VirtualMachineTemplate.State.UploadAbandoned);
+                    for (TemplateDataStoreVO templateDataStore : templateDataStores) {
+                        VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
+                        if (template == null) {
+                            s_logger.warn("Uploaded template with id " + templateDataStore.getTemplateId() + " not found, so cannot be destroyed");
+                            continue;
+                        }
+                        try {
+                            DataStore dataStore = _dataStoreMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
+                            EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
+                            if (ep == null) {
+                                s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName() + ", cannot destroy uploaded template " + template.getUuid());
+                                continue;
+                            }
+                            Host host = _hostDao.findById(ep.getId());
+                            if (host != null && host.getManagementServerId() != null) {
+                                if (_serverId == host.getManagementServerId().longValue()) {
+                                    AsyncCallFuture<TemplateApiResult> future = _imageSrv.deleteTemplateAsync(tmplFactory.getTemplate(template.getId(), dataStore));
+                                    TemplateApiResult result = future.get();
+                                    if (!result.isSuccess()) {
+                                        s_logger.warn("Failed to delete template " + template.getUuid() + " from the image store " + dataStore.getName() + " due to: " + result.getResult());
+                                        continue;
+                                    }
+                                    // remove from template_zone_ref
+                                    List<VMTemplateZoneVO> templateZones = _vmTemplateZoneDao.listByZoneTemplate(((ImageStoreEntity)dataStore).getDataCenterId(), template.getId());
+                                    if (templateZones != null) {
+                                        for (VMTemplateZoneVO templateZone : templateZones) {
+                                            _vmTemplateZoneDao.remove(templateZone.getId());
+                                        }
+                                    }
+                                    // mark all the occurrences of this template in the given store as destroyed
+                                    _templateStoreDao.removeByTemplateStore(template.getId(), dataStore.getId());
+                                    // find all eligible image stores for this template
+                                    List<DataStore> imageStores = _tmpltMgr.getImageStoreByTemplate(template.getId(), null);
+                                    if (imageStores == null || imageStores.size() == 0) {
+                                        template.setState(VirtualMachineTemplate.State.Inactive);
+                                        _templateDao.update(template.getId(), template);
+
+                                        // decrement template resource count
+                                        _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
+                                    }
+                                }
+                            }
+                        } catch (Throwable th) {
+                            s_logger.warn("Unable to destroy uploaded template " + template.getUuid() + ". Error details: " + th.getMessage());
+                        }
+                    }
+                } finally {
+                    scanLock.unlock();
+                }
+            }
+        } finally {
+            scanLock.releaseRef();
+        }
+    }
+
+    /**
+     * This method only applies for managed storage.
+     *
+     * For XenServer and vSphere, see if we need to remove an SR or a datastore, then remove the underlying volume
+     * from any applicable access control list (before other code attempts to delete the volume that supports it).
+     *
+     * For KVM, just tell the underlying storage plug-in to remove the volume from any applicable access control list
+     * (before other code attempts to delete the volume that supports it).
+     */
+    private void handleManagedStorage(Volume volume) {
+        Long instanceId = volume.getInstanceId();
+
+        if (instanceId != null) {
+            StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+
+            if (storagePool != null && storagePool.isManaged()) {
+                VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
+
+                Long lastHostId = vmInstanceVO.getLastHostId();
+
+                if (lastHostId != null) {
+                    HostVO host = _hostDao.findById(lastHostId);
+                    ClusterVO cluster = _clusterDao.findById(host.getClusterId());
+                    VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
+
+                    if (cluster.getHypervisorType() == HypervisorType.KVM) {
+                        volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
+                    } else {
+                        DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
+                        DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
+
+                        DettachCommand cmd = new DettachCommand(disk, null);
+
+                        cmd.setManaged(true);
+
+                        cmd.setStorageHost(storagePool.getHostAddress());
+                        cmd.setStoragePort(storagePool.getPort());
+
+                        cmd.set_iScsiName(volume.get_iScsiName());
+
+                        Answer answer = _agentMgr.easySend(lastHostId, cmd);
+
+                        if (answer != null && answer.getResult()) {
+                            volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
+                        } else {
+                            s_logger.warn("Unable to remove host-side clustered file system for the following volume: " + volume.getUuid());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @DB
+    List<Long> findAllVolumeIdInSnapshotTable(Long storeId) {
+        String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE snapshots.id = snapshot_store_ref.snapshot_id and store_id=? GROUP BY volume_id";
+        List<Long> list = new ArrayList<Long>();
+        try {
+            TransactionLegacy txn = TransactionLegacy.currentTxn();
+            ResultSet rs = null;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, storeId);
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                list.add(rs.getLong(1));
+            }
+            return list;
+        } catch (Exception e) {
+            s_logger.debug("failed to get all volumes who has snapshots in secondary storage " + storeId + " due to " + e.getMessage());
+            return null;
+        }
+
+    }
+
+    List<String> findAllSnapshotForVolume(Long volumeId) {
+        String sql = "SELECT backup_snap_id FROM snapshots WHERE volume_id=? and backup_snap_id is not NULL";
+        try {
+            TransactionLegacy txn = TransactionLegacy.currentTxn();
+            ResultSet rs = null;
+            PreparedStatement pstmt = null;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(1, volumeId);
+            rs = pstmt.executeQuery();
+            List<String> list = new ArrayList<String>();
+            while (rs.next()) {
+                list.add(rs.getString(1));
+            }
+            return list;
+        } catch (Exception e) {
+            s_logger.debug("failed to get all snapshots for a volume " + volumeId + " due to " + e.getMessage());
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    public void cleanupSecondaryStorage(boolean recurring) {
+        // NOTE that object_store refactor will immediately delete the object from secondary storage when deleteTemplate etc api is issued.
+        // so here we don't need to issue DeleteCommand to resource anymore, only need to remove db entry.
+        try {
+            // Cleanup templates in template_store_ref
+            List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
+            for (DataStore store : imageStores) {
+                try {
+                    long storeId = store.getId();
+                    List<TemplateDataStoreVO> destroyedTemplateStoreVOs = _templateStoreDao.listDestroyed(storeId);
+                    s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() + " templates to cleanup on template_store_ref for store: " + store.getName());
+                    for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Deleting template store DB entry: " + destroyedTemplateStoreVO);
+                        }
+                        _templateStoreDao.remove(destroyedTemplateStoreVO.getId());
+                    }
+                } catch (Exception e) {
+                    s_logger.warn("problem cleaning up templates in template_store_ref for store: " + store.getName(), e);
+                }
+            }
+
+            // CleanUp snapshots on snapshot_store_ref
+            for (DataStore store : imageStores) {
+                try {
+                    List<SnapshotDataStoreVO> destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId());
+                    s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size() + " snapshots to cleanup on snapshot_store_ref for store: " + store.getName());
+                    for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) {
+                        // check if this snapshot has child
+                        SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store);
+                        if (snap.getChild() != null) {
+                            s_logger.debug("Skip snapshot on store: " + destroyedSnapshotStoreVO + " , because it has child");
+                            continue;
+                        }
+
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Deleting snapshot store DB entry: " + destroyedSnapshotStoreVO);
+                        }
+
+                        _snapshotDao.remove(destroyedSnapshotStoreVO.getSnapshotId());
+                        SnapshotDataStoreVO snapshotOnPrimary = _snapshotStoreDao.findBySnapshot(destroyedSnapshotStoreVO.getSnapshotId(), DataStoreRole.Primary);
+                        if (snapshotOnPrimary != null) {
+                            _snapshotStoreDao.remove(snapshotOnPrimary.getId());
+                        }
+                        _snapshotStoreDao.remove(destroyedSnapshotStoreVO.getId());
+                    }
+
+                } catch (Exception e2) {
+                    s_logger.warn("problem cleaning up snapshots in snapshot_store_ref for store: " + store.getName(), e2);
+                }
+
+            }
+
+            // CleanUp volumes on volume_store_ref
+            for (DataStore store : imageStores) {
+                try {
+                    List<VolumeDataStoreVO> destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId());
+                    s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size() + " volumes to cleanup on volume_store_ref for store: " + store.getName());
+                    for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Deleting volume store DB entry: " + destroyedStoreVO);
+                        }
+                        _volumeStoreDao.remove(destroyedStoreVO.getId());
+                    }
+
+                } catch (Exception e2) {
+                    s_logger.warn("problem cleaning up volumes in volume_store_ref for store: " + store.getName(), e2);
+                }
+            }
+        } catch (Exception e3) {
+            s_logger.warn("problem cleaning up secondary storage DB entries. ", e3);
+        }
+    }
+
+    @Override
+    public String getPrimaryStorageNameLabel(VolumeVO volume) {
+        Long poolId = volume.getPoolId();
+
+        // poolId is null only if volume is destroyed, which has been checked
+        // before.
+        assert poolId != null;
+        StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(poolId);
+        assert PrimaryDataStoreVO != null;
+        return PrimaryDataStoreVO.getUuid();
+    }
+
+    @Override
+    @DB
+    public PrimaryDataStoreInfo preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException {
+        StoragePoolVO primaryStorage = null;
+        primaryStorage = _storagePoolDao.findById(primaryStorageId);
+
+        if (primaryStorage == null) {
+            String msg = "Unable to obtain lock on the storage pool record in preparePrimaryStorageForMaintenance()";
+            s_logger.error(msg);
+            throw new InvalidParameterValueException(msg);
+        }
+
+        if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) {
+            throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
+        }
+
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        lifeCycle.maintain(store);
+
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+    }
+
+    @Override
+    @DB
+    public PrimaryDataStoreInfo cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException {
+        Long primaryStorageId = cmd.getId();
+        StoragePoolVO primaryStorage = null;
+
+        primaryStorage = _storagePoolDao.findById(primaryStorageId);
+
+        if (primaryStorage == null) {
+            String msg = "Unable to obtain lock on the storage pool in cancelPrimaryStorageForMaintenance()";
+            s_logger.error(msg);
+            throw new InvalidParameterValueException(msg);
+        }
+
+        if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) {
+            throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString(),
+                    primaryStorageId);
+        }
+
+        DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
+        DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+        DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+        lifeCycle.cancelMaintain(store);
+
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
+    }
+
+    protected class StorageGarbageCollector extends ManagedContextRunnable {
+
+        public StorageGarbageCollector() {
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.trace("Storage Garbage Collection Thread is running.");
+
+                cleanupStorage(true);
+
+            } catch (Exception e) {
+                s_logger.error("Caught the following Exception", e);
+            }
+        }
+    }
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+        for (ManagementServerHost vo : nodeList) {
+            if (vo.getMsid() == _serverId) {
+                s_logger.info("Cleaning up storage maintenance jobs associated with Management server: " + vo.getMsid());
+                List<Long> poolIds = _storagePoolWorkDao.searchForPoolIdsForPendingWorkJobs(vo.getMsid());
+                if (poolIds.size() > 0) {
+                    for (Long poolId : poolIds) {
+                        StoragePoolVO pool = _storagePoolDao.findById(poolId);
+                        // check if pool is in an inconsistent state
+                        if (pool != null && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)
+                                || pool.getStatus().equals(StoragePoolStatus.CancelMaintenance))) {
+                            _storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId);
+                            pool.setStatus(StoragePoolStatus.ErrorInMaintenance);
+                            _storagePoolDao.update(poolId, pool);
+                        }
+
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    @Override
+    public CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId) {
+        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
+        if (zoneId != null) {
+            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        List<Long> hosts = new ArrayList<Long>();
+        if (hostId != null) {
+            hosts.add(hostId);
+        } else {
+            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
+            if (stores != null) {
+                for (DataStore store : stores) {
+                    hosts.add(store.getId());
+                }
+            }
+        }
+
+        CapacityVO capacity = new CapacityVO(hostId, zoneId, null, null, 0, 0, Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
+        for (Long id : hosts) {
+            StorageStats stats = ApiDBUtils.getSecondaryStorageStatistics(id);
+            if (stats == null) {
+                continue;
+            }
+            capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity());
+            capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
+        }
+
+        return capacity;
+    }
+
+    @Override
+    public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId) {
+        SearchCriteria<StoragePoolVO> sc = _storagePoolDao.createSearchCriteria();
+        List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
+
+        if (zoneId != null) {
+            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        }
+
+        if (podId != null) {
+            sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
+        }
+
+        if (clusterId != null) {
+            sc.addAnd("clusterId", SearchCriteria.Op.EQ, clusterId);
+        }
+
+        if (poolId != null) {
+            sc.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, poolId);
+        }
+        if (poolId != null) {
+            pools.add(_storagePoolDao.findById(poolId));
+        } else {
+            pools = _storagePoolDao.search(sc, null);
+        }
+
+        CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, Capacity.CAPACITY_TYPE_STORAGE);
+        for (StoragePoolVO PrimaryDataStoreVO : pools) {
+            StorageStats stats = ApiDBUtils.getStoragePoolStatistics(PrimaryDataStoreVO.getId());
+            if (stats == null) {
+                continue;
+            }
+            capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity());
+            capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity());
+        }
+        return capacity;
+    }
+
+    @Override
+    public PrimaryDataStoreInfo getStoragePool(long id) {
+        return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(id, DataStoreRole.Primary);
+    }
+
+    @Override
+    @DB
+    public List<VMInstanceVO> listByStoragePool(long storagePoolId) {
+        SearchCriteria<VMInstanceVO> sc = StoragePoolSearch.create();
+        sc.setJoinParameters("vmVolume", "volumeType", Volume.Type.ROOT);
+        sc.setJoinParameters("vmVolume", "poolId", storagePoolId);
+        sc.setJoinParameters("vmVolume", "state", Volume.State.Ready);
+        return _vmInstanceDao.search(sc, null);
+    }
+
+    @Override
+    @DB
+    public StoragePoolVO findLocalStorageOnHost(long hostId) {
+        SearchCriteria<StoragePoolVO> sc = LocalStorageSearch.create();
+        sc.setParameters("type", new Object[] {StoragePoolType.Filesystem, StoragePoolType.LVM});
+        sc.setJoinParameters("poolHost", "hostId", hostId);
+        List<StoragePoolVO> storagePools = _storagePoolDao.search(sc, null);
+        if (!storagePools.isEmpty()) {
+            return storagePools.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Host updateSecondaryStorage(long secStorageId, String newUrl) {
+        HostVO secHost = _hostDao.findById(secStorageId);
+        if (secHost == null) {
+            throw new InvalidParameterValueException("Can not find out the secondary storage id: " + secStorageId);
+        }
+
+        if (secHost.getType() != Host.Type.SecondaryStorage) {
+            throw new InvalidParameterValueException("host: " + secStorageId + " is not a secondary storage");
+        }
+
+        URI uri = null;
+        try {
+            uri = new URI(UriUtils.encodeURIComponent(newUrl));
+            if (uri.getScheme() == null) {
+                throw new InvalidParameterValueException("uri.scheme is null " + newUrl + ", add nfs:// (or cifs://) as a prefix");
+            } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
+                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
+                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format nfs://hostname/path");
+                }
+            } else if (uri.getScheme().equalsIgnoreCase("cifs")) {
+                // Don't validate against a URI encoded URI.
+                URI cifsUri = new URI(newUrl);
+                String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
+                if (warnMsg != null) {
+                    throw new InvalidParameterValueException(warnMsg);
+                }
+            }
+        } catch (URISyntaxException e) {
+            throw new InvalidParameterValueException(newUrl + " is not a valid uri");
+        }
+
+        String oldUrl = secHost.getStorageUrl();
+
+        URI oldUri = null;
+        try {
+            oldUri = new URI(UriUtils.encodeURIComponent(oldUrl));
+            if (!oldUri.getScheme().equalsIgnoreCase(uri.getScheme())) {
+                throw new InvalidParameterValueException("can not change old scheme:" + oldUri.getScheme() + " to " + uri.getScheme());
+            }
+        } catch (URISyntaxException e) {
+            s_logger.debug("Failed to get uri from " + oldUrl);
+        }
+
+        secHost.setStorageUrl(newUrl);
+        secHost.setGuid(newUrl);
+        secHost.setName(newUrl);
+        _hostDao.update(secHost.getId(), secHost);
+        return secHost;
+    }
+
+    @Override
+    public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) {
+
+        if (format == null) {
+            return HypervisorType.None;
+        }
+
+        if (format == ImageFormat.VHD) {
+            return HypervisorType.XenServer;
+        } else if (format == ImageFormat.OVA) {
+            return HypervisorType.VMware;
+        } else if (format == ImageFormat.QCOW2) {
+            return HypervisorType.KVM;
+        } else if (format == ImageFormat.RAW) {
+            return HypervisorType.Ovm;
+        } else if (format == ImageFormat.VHDX) {
+            return HypervisorType.Hyperv;
+        } else {
+            return HypervisorType.None;
+        }
+    }
+
+    private boolean checkUsagedSpace(StoragePool pool) {
+        // Managed storage does not currently deal with accounting for physically used space (only provisioned space). Just return true if "pool" is managed.
+        if (pool.isManaged()) {
+            return true;
+        }
+
+        StatsCollector sc = StatsCollector.getInstance();
+        double storageUsedThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(pool.getDataCenterId());
+        if (sc != null) {
+            long totalSize = pool.getCapacityBytes();
+            StorageStats stats = sc.getStoragePoolStats(pool.getId());
+            if (stats == null) {
+                stats = sc.getStorageStats(pool.getId());
+            }
+            if (stats != null) {
+                double usedPercentage = ((double)stats.getByteUsed() / (double)totalSize);
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Checking pool " + pool.getId() + " for storage, totalSize: " + pool.getCapacityBytes() + ", usedBytes: " + stats.getByteUsed() + ", usedPct: " + usedPercentage
+                            + ", disable threshold: " + storageUsedThreshold);
+                }
+                if (usedPercentage >= storageUsedThreshold) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Insufficient space on pool: " + pool.getId() + " since its usage percentage: " + usedPercentage + " has crossed the pool.storage.capacity.disablethreshold: "
+                                + storageUsedThreshold);
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean storagePoolHasEnoughIops(List<Volume> requestedVolumes, StoragePool pool) {
+        if (requestedVolumes == null || requestedVolumes.isEmpty() || pool == null) {
+            return false;
+        }
+
+        // Only IOPS-guaranteed primary storage like SolidFire is using/setting IOPS.
+        // This check returns true for storage that does not specify IOPS.
+        if (pool.getCapacityIops() == null) {
+            s_logger.info("Storage pool " + pool.getName() + " (" + pool.getId() + ") does not supply IOPS capacity, assuming enough capacity");
+
+            return true;
+        }
+
+        StoragePoolVO storagePoolVo = _storagePoolDao.findById(pool.getId());
+        long currentIops = _capacityMgr.getUsedIops(storagePoolVo);
+
+        long requestedIops = 0;
+
+        for (Volume requestedVolume : requestedVolumes) {
+            Long minIops = requestedVolume.getMinIops();
+
+            if (minIops != null && minIops > 0) {
+                requestedIops += minIops;
+            }
+        }
+
+        long futureIops = currentIops + requestedIops;
+
+        return futureIops <= pool.getCapacityIops();
+    }
+
+    @Override
+    public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool) {
+        return storagePoolHasEnoughSpace(volumes, pool, null);
+    }
+
+    @Override
+    public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool, Long clusterId) {
+        if (volumes == null || volumes.isEmpty()) {
+            return false;
+        }
+
+        if (!checkUsagedSpace(pool)) {
+            return false;
+        }
+
+        // allocated space includes templates
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Destination pool id: " + pool.getId());
+        }
+        // allocated space includes templates
+        final StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
+        long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
+        long totalAskingSize = 0;
+
+        for (Volume volume : volumes) {
+            // refreshing the volume from the DB to get latest hv_ss_reserve (hypervisor snapshot reserve) field
+            // I could have just assigned this to "volume", but decided to make a new variable for it so that it
+            // might be clearer that this "volume" in "volumes" still might have an old value for hv_ss_reverse.
+            VolumeVO volumeVO = _volumeDao.findById(volume.getId());
+
+            if (volumeVO.getHypervisorSnapshotReserve() == null) {
+                // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
+                volService.updateHypervisorSnapshotReserveForVolume(getDiskOfferingVO(volumeVO), volumeVO.getId(), getHypervisorType(volumeVO));
+
+                // hv_ss_reserve field might have been updated; refresh from DB to make use of it in getDataObjectSizeIncludingHypervisorSnapshotReserve
+                volumeVO = _volumeDao.findById(volume.getId());
+            }
+
+            // this if statement should resolve to true at most once per execution of the for loop its contained within (for a root disk that is
+            // to leverage a template)
+            if (volume.getTemplateId() != null) {
+                VMTemplateVO tmpl = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
+
+                if (tmpl != null && !ImageFormat.ISO.equals(tmpl.getFormat())) {
+                    allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, tmpl);
+                }
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Pool ID for the volume with ID " + volumeVO.getId() + " is " + volumeVO.getPoolId());
+            }
+
+            // 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 ((volumeVO.getState() != Volume.State.Ready) || (volumeVO.getPoolId() != pool.getId())) {
+                totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeVO, poolVO);
+
+                totalAskingSize += getAskingSizeForTemplateBasedOnClusterAndStoragePool(volumeVO.getTemplateId(), clusterId, poolVO);
+            }
+        }
+
+        return checkPoolforSpace(pool, allocatedSizeWithTemplate, totalAskingSize);
+    }
+
+    @Override
+    public boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSiz) {
+        if (!checkUsagedSpace(pool)) {
+            return false;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Destination pool id: " + pool.getId());
+        }
+        long totalAskingSize = newSiz - currentSize;
+
+        if (totalAskingSize <= 0) {
+            return true;
+        } else {
+            final StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
+            final long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
+            return checkPoolforSpace(pool, allocatedSizeWithTemplate, totalAskingSize);
+        }
+    }
+
+    private boolean checkPoolforSpace(StoragePool pool, long allocatedSizeWithTemplate, long totalAskingSize) {
+        // allocated space includes templates
+        StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
+
+        long totalOverProvCapacity;
+
+        if (pool.getPoolType().supportsOverProvisioning()) {
+            BigDecimal overProvFactor = getStorageOverProvisioningFactor(pool.getId());
+
+            totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(pool.getCapacityBytes())).longValue();
+
+            s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString() + " with over-provisioning factor " + overProvFactor.toString());
+            s_logger.debug("Total over-provisioned capacity calculated is " + overProvFactor + " * " + pool.getCapacityBytes());
+        } else {
+            totalOverProvCapacity = pool.getCapacityBytes();
+
+            s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString());
+        }
+
+        s_logger.debug("Total capacity of the pool " + poolVO.getName() + " with ID " + pool.getId() + " is " + totalOverProvCapacity);
+
+        double storageAllocatedThreshold = CapacityManager.StorageAllocatedCapacityDisableThreshold.valueIn(pool.getDataCenterId());
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Checking pool: " + pool.getId() + " for storage allocation , maxSize : " + totalOverProvCapacity + ", totalAllocatedSize : " + allocatedSizeWithTemplate
+                    + ", askingSize : " + totalAskingSize + ", allocated disable threshold: " + storageAllocatedThreshold);
+        }
+
+        double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize) / (double)(totalOverProvCapacity);
+
+        if (usedPercentage > storageAllocatedThreshold) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for storage allocation since its allocated percentage: " + usedPercentage
+                        + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " + storageAllocatedThreshold + ", skipping this pool");
+            }
+
+            return false;
+        }
+
+        if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for storage allocation, not enough storage, maxSize : " + totalOverProvCapacity
+                        + ", totalAllocatedSize : " + allocatedSizeWithTemplate + ", askingSize : " + totalAskingSize);
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Storage plug-ins for managed storage can be designed in such a way as to store a template on the primary storage once and
+     * make use of it via storage-side cloning.
+     *
+     * This method determines how many more bytes it will need for the template (if the template is already stored on the primary storage,
+     * then the answer is 0).
+     */
+    private long getAskingSizeForTemplateBasedOnClusterAndStoragePool(Long templateId, Long clusterId, StoragePoolVO storagePoolVO) {
+        if (templateId == null || clusterId == null || storagePoolVO == null || !storagePoolVO.isManaged()) {
+            return 0;
+        }
+
+        VMTemplateVO tmpl = _templateDao.findByIdIncludingRemoved(templateId);
+
+        if (tmpl == null || ImageFormat.ISO.equals(tmpl.getFormat())) {
+            return 0;
+        }
+
+        HypervisorType hypervisorType = tmpl.getHypervisorType();
+
+        // The getSupportsResigning method is applicable for XenServer as a UUID-resigning patch may or may not be installed on those hypervisor hosts.
+        if (_clusterDao.getSupportsResigning(clusterId) || HypervisorType.VMware.equals(hypervisorType) || HypervisorType.KVM.equals(hypervisorType)) {
+            return getBytesRequiredForTemplate(tmpl, storagePoolVO);
+        }
+
+        return 0;
+    }
+
+    private long getDataObjectSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) {
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
+
+        if (storeDriver instanceof PrimaryDataStoreDriver) {
+            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
+
+            VolumeInfo volumeInfo = volFactory.getVolume(volume.getId());
+
+            return primaryStoreDriver.getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeInfo, pool);
+        }
+
+        return volume.getSize();
+    }
+
+    private DiskOfferingVO getDiskOfferingVO(Volume volume) {
+        Long diskOfferingId = volume.getDiskOfferingId();
+
+        return _diskOfferingDao.findById(diskOfferingId);
+    }
+
+    private HypervisorType getHypervisorType(Volume volume) {
+        Long instanceId = volume.getInstanceId();
+
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId);
+
+        if (vmInstance != null) {
+            return vmInstance.getHypervisorType();
+        }
+
+        return null;
+    }
+
+    private long getBytesRequiredForTemplate(VMTemplateVO tmpl, StoragePool pool) {
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
+        DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
+
+        if (storeDriver instanceof PrimaryDataStoreDriver) {
+            PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver;
+
+            TemplateInfo templateInfo = tmplFactory.getReadyTemplateOnImageStore(tmpl.getId(), pool.getDataCenterId());
+
+            return primaryStoreDriver.getBytesRequiredForTemplate(templateInfo, pool);
+        }
+
+        return tmpl.getSize();
+    }
+
+    @Override
+    public void createCapacityEntry(long poolId) {
+        StoragePoolVO storage = _storagePoolDao.findById(poolId);
+        createCapacityEntry(storage, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, 0);
+    }
+
+    @Override
+    public synchronized boolean registerHostListener(String providerName, HypervisorHostListener listener) {
+        hostListeners.put(providerName, listener);
+        return true;
+    }
+
+    @Override
+    public Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException {
+        return null;
+    }
+
+    @Override
+    public Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException {
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
+
+        if (storeProvider == null) {
+            storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider();
+            if (storeProvider == null) {
+                throw new InvalidParameterValueException("can't find image store provider: " + providerName);
+            }
+            providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name
+        }
+
+        ScopeType scopeType = ScopeType.ZONE;
+        if (zoneId == null) {
+            scopeType = ScopeType.REGION;
+        }
+
+        if (name == null) {
+            name = url;
+        }
+
+        ImageStoreVO imageStore = _imageStoreDao.findByName(name);
+        if (imageStore != null) {
+            throw new InvalidParameterValueException("The image store with name " + name + " already exists, try creating with another name");
+        }
+
+        // check if scope is supported by store provider
+        if (!((ImageStoreProvider)storeProvider).isScopeSupported(scopeType)) {
+            throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType);
+        }
+
+        // check if we have already image stores from other different providers,
+        // we currently are not supporting image stores from different
+        // providers co-existing
+        List<ImageStoreVO> imageStores = _imageStoreDao.listImageStores();
+        for (ImageStoreVO store : imageStores) {
+            if (!store.getProviderName().equalsIgnoreCase(providerName)) {
+                throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added");
+            }
+        }
+
+        if (zoneId != null) {
+            // Check if the zone exists in the system
+            DataCenterVO zone = _dcDao.findById(zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Can't find zone by id " + zoneId);
+            }
+
+            Account account = CallContext.current().getCallingAccount();
+            if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
+                PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
+                ex.addProxyObject(zone.getUuid(), "dcId");
+                throw ex;
+            }
+        }
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("zoneId", zoneId);
+        params.put("url", url);
+        params.put("name", name);
+        params.put("details", details);
+        params.put("scope", scopeType);
+        params.put("providerName", storeProvider.getName());
+        params.put("role", DataStoreRole.Image);
+
+        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+
+        DataStore store;
+        try {
+            store = lifeCycle.initialize(params);
+        } catch (Exception e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to add data store: " + e.getMessage(), e);
+            }
+            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
+        }
+
+        if (((ImageStoreProvider)storeProvider).needDownloadSysTemplate()) {
+            // trigger system vm template download
+            _imageSrv.downloadBootstrapSysTemplate(store);
+        } else {
+            // populate template_store_ref table
+            _imageSrv.addSystemVMTemplatesToSecondary(store);
+        }
+
+        // associate builtin template with zones associated with this image store
+        associateCrosszoneTemplatesToZone(zoneId);
+
+        // duplicate cache store records to region wide storage
+        if (scopeType == ScopeType.REGION) {
+            duplicateCacheStoreRecordsToRegionStore(store.getId());
+        }
+
+        return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image);
+    }
+
+    @Override
+    public ImageStore migrateToObjectStore(String name, String url, String providerName, Map<String, String> details) throws DiscoveryException, InvalidParameterValueException {
+        // check if current cloud is ready to migrate, we only support cloud with only NFS secondary storages
+        List<ImageStoreVO> imgStores = _imageStoreDao.listImageStores();
+        List<ImageStoreVO> nfsStores = new ArrayList<ImageStoreVO>();
+        if (imgStores != null && imgStores.size() > 0) {
+            for (ImageStoreVO store : imgStores) {
+                if (!store.getProviderName().equals(DataStoreProvider.NFS_IMAGE)) {
+                    throw new InvalidParameterValueException("We only support migrate NFS secondary storage to use object store!");
+                } else {
+                    nfsStores.add(store);
+                }
+            }
+        }
+        // convert all NFS secondary storage to staging store
+        if (nfsStores != null && nfsStores.size() > 0) {
+            for (ImageStoreVO store : nfsStores) {
+                long storeId = store.getId();
+
+                _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
+
+                DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(store.getProviderName());
+                DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
+                DataStore secStore = _dataStoreMgr.getDataStore(storeId, DataStoreRole.Image);
+                lifeCycle.migrateToObjectStore(secStore);
+                // update store_role in template_store_ref and snapshot_store_ref to ImageCache
+                _templateStoreDao.updateStoreRoleToCachce(storeId);
+                _snapshotStoreDao.updateStoreRoleToCache(storeId);
+            }
+        }
+        // add object store
+        return discoverImageStore(name, url, providerName, null, details);
+    }
+
+    private void duplicateCacheStoreRecordsToRegionStore(long storeId) {
+        _templateStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
+        _snapshotStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
+        _volumeStoreDao.duplicateCacheRecordsOnRegionStore(storeId);
+    }
+
+    private void associateCrosszoneTemplatesToZone(Long zoneId) {
+        VMTemplateZoneVO tmpltZone;
+
+        List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
+        List<Long> dcIds = new ArrayList<Long>();
+        if (zoneId != null) {
+            dcIds.add(zoneId);
+        } else {
+            List<DataCenterVO> dcs = _dcDao.listAll();
+            if (dcs != null) {
+                for (DataCenterVO dc : dcs) {
+                    dcIds.add(dc.getId());
+                }
+            }
+        }
+
+        for (VMTemplateVO vt : allTemplates) {
+            if (vt.isCrossZones()) {
+                for (Long dcId : dcIds) {
+                    tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
+                    if (tmpltZone == null) {
+                        VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
+                        _vmTemplateZoneDao.persist(vmTemplateZone);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean deleteImageStore(DeleteImageStoreCmd cmd) {
+        final long storeId = cmd.getId();
+        // Verify that image store exists
+        ImageStoreVO store = _imageStoreDao.findById(storeId);
+        if (store == null) {
+            throw new InvalidParameterValueException("Image store with id " + storeId + " doesn't exist");
+        }
+        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
+
+        // Verify that there are no live snapshot, template, volume on the image
+        // store to be deleted
+        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listByStoreId(storeId, DataStoreRole.Image);
+        if (snapshots != null && snapshots.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete image store with active snapshots backup!");
+        }
+        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listByStoreId(storeId);
+        if (volumes != null && volumes.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete image store with active volumes backup!");
+        }
+
+        // search if there are user templates stored on this image store, excluding system, builtin templates
+        List<TemplateJoinVO> templates = _templateViewDao.listActiveTemplates(storeId);
+        if (templates != null && templates.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete image store with active templates backup!");
+        }
+
+        // ready to delete
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // first delete from image_store_details table, we need to do that since
+                // we are not actually deleting record from main
+                // image_data_store table, so delete cascade will not work
+                _imageStoreDetailsDao.deleteDetails(storeId);
+                _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.Image);
+                _volumeStoreDao.deletePrimaryRecordsForStore(storeId);
+                _templateStoreDao.deletePrimaryRecordsForStore(storeId);
+                _imageStoreDao.remove(storeId);
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    public ImageStore createSecondaryStagingStore(CreateSecondaryStagingStoreCmd cmd) {
+        String providerName = cmd.getProviderName();
+        DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
+
+        if (storeProvider == null) {
+            storeProvider = _dataStoreProviderMgr.getDefaultCacheDataStoreProvider();
+            if (storeProvider == null) {
+                throw new InvalidParameterValueException("can't find cache store provider: " + providerName);
+            }
+        }
+
+        Long dcId = cmd.getZoneId();
+
+        ScopeType scopeType = null;
+        String scope = cmd.getScope();
+        if (scope != null) {
+            try {
+                scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
+
+            } catch (Exception e) {
+                throw new InvalidParameterValueException("invalid scope for cache store " + scope);
+            }
+
+            if (scopeType != ScopeType.ZONE) {
+                throw new InvalidParameterValueException("Only zone wide cache storage is supported");
+            }
+        }
+
+        if (scopeType == ScopeType.ZONE && dcId == null) {
+            throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
+        }
+
+        // Check if the zone exists in the system
+        DataCenterVO zone = _dcDao.findById(dcId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by id " + dcId);
+        }
+
+        Account account = CallContext.current().getCallingAccount();
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
+            PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
+            ex.addProxyObject(zone.getUuid(), "dcId");
+            throw ex;
+        }
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("zoneId", dcId);
+        params.put("url", cmd.getUrl());
+        params.put("name", cmd.getUrl());
+        params.put("details", cmd.getDetails());
+        params.put("scope", scopeType);
+        params.put("providerName", storeProvider.getName());
+        params.put("role", DataStoreRole.ImageCache);
+
+        DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
+        DataStore store = null;
+        try {
+            store = lifeCycle.initialize(params);
+        } catch (Exception e) {
+            s_logger.debug("Failed to add data store: " + e.getMessage(), e);
+            throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
+        }
+
+        return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);
+    }
+
+    @Override
+    public boolean deleteSecondaryStagingStore(DeleteSecondaryStagingStoreCmd cmd) {
+        final long storeId = cmd.getId();
+        // Verify that cache store exists
+        ImageStoreVO store = _imageStoreDao.findById(storeId);
+        if (store == null) {
+            throw new InvalidParameterValueException("Cache store with id " + storeId + " doesn't exist");
+        }
+        _accountMgr.checkAccessAndSpecifyAuthority(CallContext.current().getCallingAccount(), store.getDataCenterId());
+
+        // Verify that there are no live snapshot, template, volume on the cache
+        // store that is currently referenced
+        List<SnapshotDataStoreVO> snapshots = _snapshotStoreDao.listActiveOnCache(storeId);
+        if (snapshots != null && snapshots.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete cache store with staging snapshots currently in use!");
+        }
+        List<VolumeDataStoreVO> volumes = _volumeStoreDao.listActiveOnCache(storeId);
+        if (volumes != null && volumes.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete cache store with staging volumes currently in use!");
+        }
+
+        List<TemplateDataStoreVO> templates = _templateStoreDao.listActiveOnCache(storeId);
+        if (templates != null && templates.size() > 0) {
+            throw new InvalidParameterValueException("Cannot delete cache store with staging templates currently in use!");
+        }
+
+        // ready to delete
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // first delete from image_store_details table, we need to do that since
+                // we are not actually deleting record from main
+                // image_data_store table, so delete cascade will not work
+                _imageStoreDetailsDao.deleteDetails(storeId);
+                _snapshotStoreDao.deletePrimaryRecordsForStore(storeId, DataStoreRole.ImageCache);
+                _volumeStoreDao.deletePrimaryRecordsForStore(storeId);
+                _templateStoreDao.deletePrimaryRecordsForStore(storeId);
+                _imageStoreDao.remove(storeId);
+            }
+        });
+
+        return true;
+    }
+
+    protected class DownloadURLGarbageCollector implements Runnable {
+
+        public DownloadURLGarbageCollector() {
+        }
+
+        @Override
+        public void run() {
+            try {
+                s_logger.trace("Download URL Garbage Collection Thread is running.");
+
+                cleanupDownloadUrls();
+
+            } catch (Exception e) {
+                s_logger.error("Caught the following Exception", e);
+            }
+        }
+    }
+
+    @Override
+    public void cleanupDownloadUrls() {
+
+        // Cleanup expired volume URLs
+        List<VolumeDataStoreVO> volumesOnImageStoreList = _volumeStoreDao.listVolumeDownloadUrls();
+        HashSet<Long> expiredVolumeIds = new HashSet<Long>();
+        HashSet<Long> activeVolumeIds = new HashSet<Long>();
+        for (VolumeDataStoreVO volumeOnImageStore : volumesOnImageStoreList) {
+
+            long volumeId = volumeOnImageStore.getVolumeId();
+            try {
+                long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), volumeOnImageStore.getExtractUrlCreated());
+                if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) {  // URL hasnt expired yet
+                    activeVolumeIds.add(volumeId);
+                    continue;
+                }
+                expiredVolumeIds.add(volumeId);
+                s_logger.debug("Removing download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeId);
+
+                // Remove it from image store
+                ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(volumeOnImageStore.getDataStoreId(), DataStoreRole.Image);
+                secStore.deleteExtractUrl(volumeOnImageStore.getInstallPath(), volumeOnImageStore.getExtractUrl(), Upload.Type.VOLUME);
+
+                // Now expunge it from DB since this entry was created only for download purpose
+                _volumeStoreDao.expunge(volumeOnImageStore.getId());
+            } catch (Throwable th) {
+                s_logger.warn("Caught exception while deleting download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeOnImageStore.getVolumeId(), th);
+            }
+        }
+        for (Long volumeId : expiredVolumeIds) {
+            if (activeVolumeIds.contains(volumeId)) {
+                continue;
+            }
+            Volume volume = _volumeDao.findById(volumeId);
+            if (volume != null && volume.getState() == Volume.State.Expunged) {
+                _volumeDao.remove(volumeId);
+            }
+        }
+
+        // Cleanup expired template URLs
+        List<TemplateDataStoreVO> templatesOnImageStoreList = _templateStoreDao.listTemplateDownloadUrls();
+        for (TemplateDataStoreVO templateOnImageStore : templatesOnImageStoreList) {
+
+            try {
+                long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), templateOnImageStore.getExtractUrlCreated());
+                if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) {  // URL hasnt expired yet
+                    continue;
+                }
+
+                s_logger.debug("Removing download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId());
+
+                // Remove it from image store
+                ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(templateOnImageStore.getDataStoreId(), DataStoreRole.Image);
+                secStore.deleteExtractUrl(templateOnImageStore.getInstallPath(), templateOnImageStore.getExtractUrl(), Upload.Type.TEMPLATE);
+
+                // Now remove download details from DB.
+                templateOnImageStore.setExtractUrl(null);
+                templateOnImageStore.setExtractUrlCreated(null);
+                _templateStoreDao.update(templateOnImageStore.getId(), templateOnImageStore);
+            } catch (Throwable th) {
+                s_logger.warn("caught exception while deleting download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId(), th);
+            }
+        }
+    }
+
+    // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate
+    @Override
+    public Long getDiskBytesReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
+        if ((offering != null) && (offering.getBytesReadRate() != null) && (offering.getBytesReadRate() > 0)) {
+            return offering.getBytesReadRate();
+        } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) {
+            return diskOffering.getBytesReadRate();
+        } else {
+            Long bytesReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesReadRate.key()));
+            if ((bytesReadRate > 0) && ((offering == null) || (!offering.isSystemUse()))) {
+                return bytesReadRate;
+            }
+        }
+        return 0L;
+    }
+
+    // get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate
+    @Override
+    public Long getDiskBytesWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
+        if ((offering != null) && (offering.getBytesWriteRate() != null) && (offering.getBytesWriteRate() > 0)) {
+            return offering.getBytesWriteRate();
+        } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) {
+            return diskOffering.getBytesWriteRate();
+        } else {
+            Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key()));
+            if ((bytesWriteRate > 0) && ((offering == null) || (!offering.isSystemUse()))) {
+                return bytesWriteRate;
+            }
+        }
+        return 0L;
+    }
+
+    // get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate
+    @Override
+    public Long getDiskIopsReadRate(final ServiceOffering offering, final DiskOffering diskOffering) {
+        if ((offering != null) && (offering.getIopsReadRate() != null) && (offering.getIopsReadRate() > 0)) {
+            return offering.getIopsReadRate();
+        } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) {
+            return diskOffering.getIopsReadRate();
+        } else {
+            Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key()));
+            if ((iopsReadRate > 0) && ((offering == null) || (!offering.isSystemUse()))) {
+                return iopsReadRate;
+            }
+        }
+        return 0L;
+    }
+
+    // get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate
+    @Override
+    public Long getDiskIopsWriteRate(final ServiceOffering offering, final DiskOffering diskOffering) {
+        if ((offering != null) && (offering.getIopsWriteRate() != null) && (offering.getIopsWriteRate() > 0)) {
+            return offering.getIopsWriteRate();
+        } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) {
+            return diskOffering.getIopsWriteRate();
+        } else {
+            Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key()));
+            if ((iopsWriteRate > 0) && ((offering == null) || (!offering.isSystemUse()))) {
+                return iopsWriteRate;
+            }
+        }
+        return 0L;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return StorageManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] { StorageCleanupInterval, StorageCleanupDelay, StorageCleanupEnabled, TemplateCleanupEnabled,
+                KvmStorageOfflineMigrationWait, KvmStorageOnlineMigrationWait, MaxNumberOfManagedClusteredFileSystems, PRIMARY_STORAGE_DOWNLOAD_WAIT};
+    }
+
+    @Override
+    public void setDiskProfileThrottling(DiskProfile dskCh, final ServiceOffering offering, final DiskOffering diskOffering) {
+        dskCh.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
+        dskCh.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
+        dskCh.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
+        dskCh.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
+    }
+
+    @Override
+    public DiskTO getDiskWithThrottling(final DataTO volTO, final Volume.Type volumeType, final long deviceId, final String path, final long offeringId, final long diskOfferingId) {
+        DiskTO disk = null;
+        if (volTO != null && volTO instanceof VolumeObjectTO) {
+            VolumeObjectTO volumeTO = (VolumeObjectTO)volTO;
+            ServiceOffering offering = _entityMgr.findById(ServiceOffering.class, offeringId);
+            DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
+            if (volumeType == Volume.Type.ROOT) {
+                setVolumeObjectTOThrottling(volumeTO, offering, diskOffering);
+            } else {
+                setVolumeObjectTOThrottling(volumeTO, null, diskOffering);
+            }
+            disk = new DiskTO(volumeTO, deviceId, path, volumeType);
+        } else {
+            disk = new DiskTO(volTO, deviceId, path, volumeType);
+        }
+        return disk;
+    }
+
+    private void setVolumeObjectTOThrottling(VolumeObjectTO volumeTO, final ServiceOffering offering, final DiskOffering diskOffering) {
+        volumeTO.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
+        volumeTO.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
+        volumeTO.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
+        volumeTO.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
+    }
+
+}
diff --git a/server/src/com/cloud/storage/StoragePoolAutomation.java b/server/src/main/java/com/cloud/storage/StoragePoolAutomation.java
similarity index 100%
rename from server/src/com/cloud/storage/StoragePoolAutomation.java
rename to server/src/main/java/com/cloud/storage/StoragePoolAutomation.java
diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/StoragePoolAutomationImpl.java
rename to server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java
diff --git a/server/src/main/java/com/cloud/storage/TemplateProfile.java b/server/src/main/java/com/cloud/storage/TemplateProfile.java
new file mode 100644
index 0000000..304b652
--- /dev/null
+++ b/server/src/main/java/com/cloud/storage/TemplateProfile.java
@@ -0,0 +1,334 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+
+public class TemplateProfile {
+    Long userId;
+    String name;
+    String displayText;
+    Integer bits;
+    Boolean passwordEnabled;
+    Boolean sshKeyEnbaled;
+    Boolean requiresHvm;
+    String url;
+    Boolean isPublic;
+    Boolean featured;
+    Boolean isExtractable;
+    ImageFormat format;
+    Long guestOsId;
+    List<Long> zoneIdList;
+    HypervisorType hypervisorType;
+    String accountName;
+    Long domainId;
+    Long accountId;
+    String chksum;
+    Boolean bootable;
+    Long templateId;
+    VMTemplateVO template;
+    String templateTag;
+    Map details;
+    Boolean isDynamicallyScalable;
+    TemplateType templateType;
+    Boolean directDownload;
+    Long size;
+
+    public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url,
+                           Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, List<Long> zoneIdList, HypervisorType hypervisorType,
+                           String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, Boolean sshKeyEnabled) {
+        this.templateId = templateId;
+        this.userId = userId;
+        this.name = name;
+        this.displayText = displayText;
+        this.bits = bits;
+        this.passwordEnabled = passwordEnabled;
+        this.requiresHvm = requiresHvm;
+        this.url = url;
+        this.isPublic = isPublic;
+        this.featured = featured;
+        this.isExtractable = isExtractable;
+        this.format = format;
+        this.guestOsId = guestOsId;
+        this.zoneIdList = zoneIdList;
+        this.hypervisorType = hypervisorType;
+        this.accountName = accountName;
+        this.domainId = domainId;
+        this.accountId = accountId;
+        this.chksum = chksum;
+        this.bootable = bootable;
+        this.details = details;
+        this.sshKeyEnbaled = sshKeyEnabled;
+    }
+
+    public TemplateProfile(Long userId, VMTemplateVO template, Long zoneId) {
+        this.userId = userId;
+        this.template = template;
+        if (zoneId != null) {
+            this.zoneIdList = new ArrayList<>();
+            this.zoneIdList.add(zoneId);
+        }
+        else this.zoneIdList = null;
+    }
+
+    public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url,
+            Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, List<Long> zoneId,
+
+            HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details,
+            Boolean sshKeyEnabled, Long imageStoreId, Boolean isDynamicallyScalable, TemplateType templateType, Boolean directDownload) {
+        this(templateId,
+            userId,
+            name,
+            displayText,
+            bits,
+            passwordEnabled,
+            requiresHvm,
+            url,
+            isPublic,
+            featured,
+            isExtractable,
+            format,
+            guestOsId,
+            zoneId,
+            hypervisorType,
+            accountName,
+            domainId,
+            accountId,
+            chksum,
+            bootable,
+            details,
+            sshKeyEnabled);
+        this.templateTag = templateTag;
+        this.isDynamicallyScalable = isDynamicallyScalable;
+        this.templateType = templateType;
+        this.directDownload = directDownload;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(Long id) {
+        this.templateId = id;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public void setDisplayText(String text) {
+        this.displayText = text;
+    }
+
+    public Integer getBits() {
+        return bits;
+    }
+
+    public void setBits(Integer bits) {
+        this.bits = bits;
+    }
+
+    public Boolean isPasswordEnabled() {
+        return passwordEnabled;
+    }
+
+    public void setPasswordEnabled(Boolean enabled) {
+        this.passwordEnabled = enabled;
+    }
+
+    public Boolean isRequiresHVM() {
+        return requiresHvm;
+    }
+
+    public void setRequiresHVM(Boolean hvm) {
+        this.requiresHvm = hvm;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public Boolean isPublic() {
+        return isPublic;
+    }
+
+    public void setIsPublic(Boolean is) {
+        this.isPublic = is;
+    }
+
+    public Boolean isFeatured() {
+        return featured;
+    }
+
+    public void setFeatured(Boolean featured) {
+        this.featured = featured;
+    }
+
+    public Boolean isExtractable() {
+        return isExtractable;
+    }
+
+    public void setIsExtractable(Boolean is) {
+        this.isExtractable = is;
+    }
+
+    public ImageFormat getFormat() {
+        return format;
+    }
+
+    public void setFormat(ImageFormat format) {
+        this.format = format;
+    }
+
+    public Long getGuestOsId() {
+        return guestOsId;
+    }
+
+    public void setGuestOsId(Long id) {
+        this.guestOsId = id;
+    }
+
+    public List<Long> getZoneIdList() {
+        return zoneIdList;
+    }
+
+    public HypervisorType getHypervisorType() {
+        return hypervisorType;
+    }
+
+    public void setHypervisorType(HypervisorType type) {
+        this.hypervisorType = type;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(Long id) {
+        this.domainId = id;
+    }
+
+    public Long getAccountId() {
+        return accountId;
+    }
+
+    public void setAccountId(Long id) {
+        this.accountId = id;
+    }
+
+    public String getCheckSum() {
+        return chksum;
+    }
+
+    public void setCheckSum(String chksum) {
+        this.chksum = chksum;
+    }
+
+    public Boolean isBootable() {
+        return this.bootable;
+    }
+
+    public void setBootable(Boolean bootable) {
+        this.bootable = bootable;
+    }
+
+    public VMTemplateVO getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(VMTemplateVO template) {
+        this.template = template;
+    }
+
+    public String getTemplateTag() {
+        return templateTag;
+    }
+
+    public void setTemplateTag(String templateTag) {
+        this.templateTag = templateTag;
+    }
+
+    public Map getDetails() {
+        return this.details;
+    }
+
+    public void setDetails(Map details) {
+        this.details = details;
+    }
+
+    public void setSshKeyEnabled(Boolean enabled) {
+        this.sshKeyEnbaled = enabled;
+    }
+
+    public Boolean isSshKeyEnabled() {
+        return this.sshKeyEnbaled;
+    }
+
+    public Boolean IsDynamicallyScalable() {
+        return this.isDynamicallyScalable;
+    }
+
+    public void setScalabe(Boolean isDynamicallyScalabe) {
+        this.isDynamicallyScalable = isDynamicallyScalabe;
+    }
+
+    public TemplateType getTemplateType() {
+        return templateType;
+    }
+
+    public void setTemplateType(TemplateType templateType) {
+        this.templateType = templateType;
+    }
+
+    public boolean isDirectDownload() {
+        return directDownload == null ? false : directDownload;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public void setSize(Long size) {
+        this.size = size;
+    }
+}
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
new file mode 100644
index 0000000..b2a395b
--- /dev/null
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -0,0 +1,3382 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
+import org.apache.cloudstack.api.response.GetUploadParamsResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.AsyncJob;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.Outcome;
+import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
+import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
+import org.apache.cloudstack.jobs.JobInfo;
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
+import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.domain.Domain;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.gpu.GPU;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilitiesVO;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.org.Grouping;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotApiService;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.VmDiskStatisticsVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.VmDiskStatisticsDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.EncryptionUtil;
+import com.cloud.utils.EnumUtils;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Predicate;
+import com.cloud.utils.ReflectionUse;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.UriUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.db.UUIDManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmService;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VmDetailConstants;
+import com.cloud.vm.VmWork;
+import com.cloud.vm.VmWorkAttachVolume;
+import com.cloud.vm.VmWorkConstants;
+import com.cloud.vm.VmWorkDetachVolume;
+import com.cloud.vm.VmWorkExtractVolume;
+import com.cloud.vm.VmWorkJobHandler;
+import com.cloud.vm.VmWorkJobHandlerProxy;
+import com.cloud.vm.VmWorkMigrateVolume;
+import com.cloud.vm.VmWorkResizeVolume;
+import com.cloud.vm.VmWorkSerializer;
+import com.cloud.vm.VmWorkTakeVolumeSnapshot;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonParseException;
+
+public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler, Configurable {
+    private final static Logger s_logger = Logger.getLogger(VolumeApiServiceImpl.class);
+    public static final String VM_WORK_JOB_HANDLER = VolumeApiServiceImpl.class.getSimpleName();
+
+    @Inject
+    private UserVmManager _userVmMgr;
+    @Inject
+    private VolumeOrchestrationService _volumeMgr;
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private TemplateManager _tmpltMgr;
+    @Inject
+    private SnapshotManager _snapshotMgr;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private ConfigurationManager _configMgr;
+    @Inject
+    private VolumeDao _volsDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private SnapshotDao _snapshotDao;
+    @Inject
+    private ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private UserVmService _userVmService;
+    @Inject
+    private VolumeDataStoreDao _volumeStoreDao;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private ResourceLimitService _resourceLimitMgr;
+    @Inject
+    private VmDiskStatisticsDao _vmDiskStatsDao;
+    @Inject
+    private VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private DataStoreManager dataStoreMgr;
+    @Inject
+    private VolumeService volService;
+    @Inject
+    private VolumeDataFactory volFactory;
+    @Inject
+    private SnapshotApiService snapshotMgr;
+    @Inject
+    private UUIDManager _uuidMgr;
+    @Inject
+    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
+    @Inject
+    private AsyncJobManager _jobMgr;
+    @Inject
+    private VmWorkJobDao _workJobDao;
+    @Inject
+    private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private StorageManager storageMgr;
+    @Inject
+    private StoragePoolDetailsDao storagePoolDetailsDao;
+    @Inject
+    private StorageUtil storageUtil;
+
+    protected Gson _gson;
+
+    private List<StoragePoolAllocator> _storagePoolAllocators;
+
+    VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
+
+    static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.job.check.interval", "3000", "Interval in milliseconds to check if the job is complete", false);
+
+    static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
+            "Check the url for a volume before downloading it from the management server. Set to false when you managment has no internet access.", true);
+
+    private long _maxVolumeSizeInGb;
+    private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
+
+    protected VolumeApiServiceImpl() {
+        _volStateMachine = Volume.State.getStateMachine();
+        _gson = GsonHelper.getGsonLogger();
+    }
+
+    /*
+     * Upload the volume to secondary storage.
+     */
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true)
+    public VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+        long ownerId = cmd.getEntityOwnerId();
+        Account owner = _entityMgr.findById(Account.class, ownerId);
+        Long zoneId = cmd.getZoneId();
+        String volumeName = cmd.getVolumeName();
+        String url = cmd.getUrl();
+        String format = cmd.getFormat();
+        Long diskOfferingId = cmd.getDiskOfferingId();
+        String imageStoreUuid = cmd.getImageStoreUuid();
+        DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
+
+        validateVolume(caller, ownerId, zoneId, volumeName, url, format, diskOfferingId);
+
+        VolumeVO volume = persistVolume(owner, zoneId, volumeName, url, cmd.getFormat(), diskOfferingId, Volume.State.Allocated);
+
+        VolumeInfo vol = volFactory.getVolume(volume.getId());
+
+        RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(), cmd.getFormat());
+        vol.addPayload(payload);
+
+        volService.registerVolume(vol, store);
+        return volume;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true)
+    public GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException {
+        Account caller = CallContext.current().getCallingAccount();
+        long ownerId = cmd.getEntityOwnerId();
+        final Account owner = _entityMgr.findById(Account.class, ownerId);
+        final Long zoneId = cmd.getZoneId();
+        final String volumeName = cmd.getName();
+        String format = cmd.getFormat();
+        final Long diskOfferingId = cmd.getDiskOfferingId();
+        String imageStoreUuid = cmd.getImageStoreUuid();
+        final DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
+
+        validateVolume(caller, ownerId, zoneId, volumeName, null, format, diskOfferingId);
+
+        return Transaction.execute(new TransactionCallbackWithException<GetUploadParamsResponse, MalformedURLException>() {
+            @Override
+            public GetUploadParamsResponse doInTransaction(TransactionStatus status) throws MalformedURLException {
+
+                VolumeVO volume = persistVolume(owner, zoneId, volumeName, null, cmd.getFormat(), diskOfferingId, Volume.State.NotUploaded);
+
+                VolumeInfo vol = volFactory.getVolume(volume.getId());
+
+                RegisterVolumePayload payload = new RegisterVolumePayload(null, cmd.getChecksum(), cmd.getFormat());
+                vol.addPayload(payload);
+
+                Pair<EndPoint, DataObject> pair = volService.registerVolumeForPostUpload(vol, store);
+                EndPoint ep = pair.first();
+                DataObject dataObject = pair.second();
+
+                GetUploadParamsResponse response = new GetUploadParamsResponse();
+
+                String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
+
+                String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, ep.getPublicAddr(), vol.getUuid());
+                response.setPostURL(new URL(url));
+
+                // set the post url, this is used in the monitoring thread to determine the SSVM
+                VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId());
+                assert (volumeStore != null) : "sincle volume is registered, volumestore cannot be null at this stage";
+                volumeStore.setExtractUrl(url);
+                _volumeStoreDao.persist(volumeStore);
+
+                response.setId(UUID.fromString(vol.getUuid()));
+
+                int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
+                DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
+                String expires = currentDateTime.plusMinutes(timeout).toString();
+                response.setTimeout(expires);
+
+                String key = _configDao.getValue(Config.SSVMPSK.key());
+                /*
+                 * encoded metadata using the post upload config key
+                 */
+                TemplateOrVolumePostUploadCommand command = new TemplateOrVolumePostUploadCommand(vol.getId(), vol.getUuid(), volumeStore.getInstallPath(), cmd.getChecksum(), vol.getType().toString(),
+                        vol.getName(), vol.getFormat().toString(), dataObject.getDataStore().getUri(), dataObject.getDataStore().getRole().toString());
+                command.setLocalPath(volumeStore.getLocalDownloadPath());
+                //using the existing max upload size configuration
+                command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
+                command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
+                command.setDefaultMaxAccountSecondaryStorage(_configDao.getValue(Config.DefaultMaxAccountSecondaryStorage.key()));
+                command.setAccountId(vol.getAccountId());
+                Gson gson = new GsonBuilder().create();
+                String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
+                response.setMetadata(metadata);
+
+                /*
+                 * signature calculated on the url, expiry, metadata.
+                 */
+                response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
+                return response;
+            }
+        });
+    }
+
+    private boolean validateVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format, Long diskOfferingId) throws ResourceAllocationException {
+
+        // permission check
+        Account volumeOwner = _accountMgr.getActiveAccountById(ownerId);
+        _accountMgr.checkAccess(caller, null, true, volumeOwner);
+
+        // Check that the resource limit for volumes won't be exceeded
+        _resourceLimitMgr.checkResourceLimit(volumeOwner, ResourceType.volume);
+
+        // Verify that zone exists
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+        }
+
+        // Check if zone is disabled
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+        }
+
+        //validating the url only when url is not null. url can be null incase of form based post upload
+        if (url != null) {
+            if (url.toLowerCase().contains("file://")) {
+                throw new InvalidParameterValueException("File:// type urls are currently unsupported");
+            }
+            UriUtils.validateUrl(format, url);
+            if (VolumeUrlCheck.value()) { // global setting that can be set when their MS does not have internet access
+                s_logger.debug("Checking url: " + url);
+                UriUtils.checkUrlExistence(url);
+            }
+            // Check that the resource limit for secondary storage won't be exceeded
+            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+        } else {
+            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage);
+        }
+
+        try {
+            ImageFormat.valueOf(format.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
+            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+        }
+
+        // Check that the the disk offering specified is valid
+        if (diskOfferingId != null) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
+            if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
+                throw new InvalidParameterValueException("Please specify a valid disk offering.");
+            }
+            if (!diskOffering.isCustomized()) {
+                throw new InvalidParameterValueException("Please specify a custom sized disk offering.");
+            }
+
+            if (diskOffering.getDomainId() == null) {
+                // do nothing as offering is public
+            } else {
+                _configMgr.checkDiskOfferingAccess(volumeOwner, diskOffering);
+            }
+        }
+
+        return false;
+    }
+
+    public String getRandomVolumeName() {
+        return UUID.randomUUID().toString();
+    }
+
+    @DB
+    protected VolumeVO persistVolume(final Account owner, final Long zoneId, final String volumeName, final String url, final String format, final Long diskOfferingId, final Volume.State state) {
+        return Transaction.execute(new TransactionCallback<VolumeVO>() {
+            @Override
+            public VolumeVO doInTransaction(TransactionStatus status) {
+                VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, new Long(-1), null, null, Storage.ProvisioningType.THIN, 0, Volume.Type.DATADISK);
+                volume.setPoolId(null);
+                volume.setDataCenterId(zoneId);
+                volume.setPodId(null);
+                volume.setState(state); // initialize the state
+                // to prevent a null pointer deref I put the system account id here when no owner is given.
+                // TODO Decide if this is valid or whether  throwing a CloudRuntimeException is more appropriate
+                volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId());
+                volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
+
+                if (diskOfferingId == null) {
+                    DiskOfferingVO diskOfferingVO = _diskOfferingDao.findByUniqueName("Cloud.com-Custom");
+                    if (diskOfferingVO != null) {
+                        long defaultDiskOfferingId = diskOfferingVO.getId();
+                        volume.setDiskOfferingId(defaultDiskOfferingId);
+                    }
+                } else {
+                    volume.setDiskOfferingId(diskOfferingId);
+
+                    DiskOfferingVO diskOfferingVO = _diskOfferingDao.findById(diskOfferingId);
+
+                    Boolean isCustomizedIops = diskOfferingVO != null && diskOfferingVO.isCustomizedIops() != null ? diskOfferingVO.isCustomizedIops() : false;
+
+                    if (isCustomizedIops == null || !isCustomizedIops) {
+                        volume.setMinIops(diskOfferingVO.getMinIops());
+                        volume.setMaxIops(diskOfferingVO.getMaxIops());
+                    }
+                }
+
+                // volume.setSize(size);
+                volume.setInstanceId(null);
+                volume.setUpdated(new Date());
+                volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId());
+                volume.setFormat(ImageFormat.valueOf(format));
+                volume = _volsDao.persist(volume);
+                CallContext.current().setEventDetails("Volume Id: " + volume.getUuid());
+
+                // Increment resource count during allocation; if actual creation fails,
+                // decrement it
+                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume);
+                //url can be null incase of postupload
+                if (url != null) {
+                    _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(url));
+                }
+
+                return volume;
+            }
+        });
+    }
+
+    /**
+     * Retrieves the volume name from CreateVolumeCmd object.
+     *
+     * If the retrieved volume name is null, empty or blank, then A random name
+     * will be generated using getRandomVolumeName method.
+     *
+     * @param cmd
+     * @return Either the retrieved name or a random name.
+     */
+    public String getVolumeNameFromCommand(CreateVolumeCmd cmd) {
+        String userSpecifiedName = cmd.getVolumeName();
+
+        if (org.apache.commons.lang.StringUtils.isBlank(userSpecifiedName)) {
+            userSpecifiedName = getRandomVolumeName();
+        }
+
+        return userSpecifiedName;
+    }
+
+    /*
+     * Just allocate a volume in the database, don't send the createvolume cmd
+     * to hypervisor. The volume will be finally created only when it's attached
+     * to a VM.
+     */
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
+    public VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        long ownerId = cmd.getEntityOwnerId();
+        Account owner = _accountMgr.getActiveAccountById(ownerId);
+        Boolean displayVolume = cmd.getDisplayVolume();
+
+        // permission check
+        _accountMgr.checkAccess(caller, null, true, _accountMgr.getActiveAccountById(ownerId));
+
+        if (displayVolume == null) {
+            displayVolume = true;
+        } else {
+            if (!_accountMgr.isRootAdmin(caller.getId())) {
+                throw new PermissionDeniedException("Cannot update parameter displayvolume, only admin permitted ");
+            }
+        }
+
+        // Check that the resource limit for volumes won't be exceeded
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, displayVolume);
+
+        Long zoneId = cmd.getZoneId();
+        Long diskOfferingId = null;
+        DiskOfferingVO diskOffering = null;
+        Storage.ProvisioningType provisioningType;
+        Long size = null;
+        Long minIops = null;
+        Long maxIops = null;
+        // Volume VO used for extracting the source template id
+        VolumeVO parentVolume = null;
+
+        // validate input parameters before creating the volume
+        if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) || (cmd.getSnapshotId() != null && cmd.getDiskOfferingId() != null)) {
+            throw new InvalidParameterValueException("Either disk Offering Id or snapshot Id must be passed whilst creating volume");
+        }
+
+        if (cmd.getSnapshotId() == null) {// create a new volume
+
+            diskOfferingId = cmd.getDiskOfferingId();
+            size = cmd.getSize();
+            Long sizeInGB = size;
+            if (size != null) {
+                if (size > 0) {
+                    size = size * 1024 * 1024 * 1024; // user specify size in GB
+                } else {
+                    throw new InvalidParameterValueException("Disk size must be larger than 0");
+                }
+            }
+
+            // Check that the the disk offering is specified
+            diskOffering = _diskOfferingDao.findById(diskOfferingId);
+            if ((diskOffering == null) || diskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
+                throw new InvalidParameterValueException("Please specify a valid disk offering.");
+            }
+
+            if (diskOffering.isCustomized()) {
+                if (size == null) {
+                    throw new InvalidParameterValueException("This disk offering requires a custom size specified");
+                }
+                Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
+                Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
+
+                if ((sizeInGB < customDiskOfferingMinSize) || (sizeInGB > customDiskOfferingMaxSize)) {
+                    throw new InvalidParameterValueException("Volume size: " + sizeInGB + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize + " Min:" + customDiskOfferingMinSize);
+                }
+            }
+
+            if (!diskOffering.isCustomized() && size != null) {
+                throw new InvalidParameterValueException("This disk offering does not allow custom size");
+            }
+
+            if (diskOffering.getDomainId() == null) {
+                // do nothing as offering is public
+            } else {
+                _configMgr.checkDiskOfferingAccess(caller, diskOffering);
+            }
+
+            if (diskOffering.getDiskSize() > 0) {
+                size = diskOffering.getDiskSize();
+            }
+
+            Boolean isCustomizedIops = diskOffering.isCustomizedIops();
+
+            if (isCustomizedIops != null) {
+                if (isCustomizedIops) {
+                    minIops = cmd.getMinIops();
+                    maxIops = cmd.getMaxIops();
+
+                    if (minIops == null && maxIops == null) {
+                        minIops = 0L;
+                        maxIops = 0L;
+                    } else {
+                        if (minIops == null || minIops <= 0) {
+                            throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
+                        }
+
+                        if (maxIops == null) {
+                            maxIops = 0L;
+                        }
+
+                        if (minIops > maxIops) {
+                            throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
+                        }
+                    }
+                } else {
+                    minIops = diskOffering.getMinIops();
+                    maxIops = diskOffering.getMaxIops();
+                }
+            }
+
+            provisioningType = diskOffering.getProvisioningType();
+
+            if (!validateVolumeSizeRange(size)) {// convert size from mb to gb
+                // for validation
+                throw new InvalidParameterValueException("Invalid size for custom volume creation: " + size + " ,max volume size is:" + _maxVolumeSizeInGb);
+            }
+        } else { // create volume from snapshot
+            Long snapshotId = cmd.getSnapshotId();
+            SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
+            if (snapshotCheck == null) {
+                throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
+            }
+
+            if (snapshotCheck.getState() != Snapshot.State.BackedUp) {
+                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation");
+            }
+            parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId());
+
+            diskOfferingId = snapshotCheck.getDiskOfferingId();
+            diskOffering = _diskOfferingDao.findById(diskOfferingId);
+            if (zoneId == null) {
+                // if zoneId is not provided, we default to create volume in the same zone as the snapshot zone.
+                zoneId = snapshotCheck.getDataCenterId();
+            }
+            size = snapshotCheck.getSize(); // ; disk offering is used for tags
+            // purposes
+
+            minIops = snapshotCheck.getMinIops();
+            maxIops = snapshotCheck.getMaxIops();
+
+            provisioningType = diskOffering.getProvisioningType();
+            // check snapshot permissions
+            _accountMgr.checkAccess(caller, null, true, snapshotCheck);
+
+            // one step operation - create volume in VM's cluster and attach it
+            // to the VM
+            Long vmId = cmd.getVirtualMachineId();
+            if (vmId != null) {
+                // Check that the virtual machine ID is valid and it's a user vm
+                UserVmVO vm = _userVmDao.findById(vmId);
+                if (vm == null || vm.getType() != VirtualMachine.Type.User) {
+                    throw new InvalidParameterValueException("Please specify a valid User VM.");
+                }
+
+                // Check that the VM is in the correct state
+                if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
+                    throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+                }
+
+                // permission check
+                _accountMgr.checkAccess(caller, null, false, vm);
+            }
+
+        }
+
+        // Check that the resource limit for primary storage won't be exceeded
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, displayVolume, new Long(size));
+
+        // Verify that zone exists
+        DataCenterVO zone = _dcDao.findById(zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
+        }
+
+        // Check if zone is disabled
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+        }
+
+        // If local storage is disabled then creation of volume with local disk
+        // offering not allowed
+        if (!zone.isLocalStorageEnabled() && diskOffering.isUseLocalStorage()) {
+            throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+        }
+
+        String userSpecifiedName = getVolumeNameFromCommand(cmd);
+
+        VolumeVO volume = commitVolume(cmd, caller, owner, displayVolume, zoneId, diskOfferingId, provisioningType, size, minIops, maxIops, parentVolume, userSpecifiedName,
+                _uuidMgr.generateUuid(Volume.class, cmd.getCustomId()));
+
+        return volume;
+    }
+
+    private VolumeVO commitVolume(final CreateVolumeCmd cmd, final Account caller, final Account owner, final Boolean displayVolume, final Long zoneId, final Long diskOfferingId,
+            final Storage.ProvisioningType provisioningType, final Long size, final Long minIops, final Long maxIops, final VolumeVO parentVolume, final String userSpecifiedName, final String uuid) {
+        return Transaction.execute(new TransactionCallback<VolumeVO>() {
+            @Override
+            public VolumeVO doInTransaction(TransactionStatus status) {
+                VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, new Long(-1), null, null, provisioningType, 0, Volume.Type.DATADISK);
+                volume.setPoolId(null);
+                volume.setUuid(uuid);
+                volume.setDataCenterId(zoneId);
+                volume.setPodId(null);
+                volume.setAccountId(owner.getId());
+                volume.setDomainId(owner.getDomainId());
+                volume.setDiskOfferingId(diskOfferingId);
+                volume.setSize(size);
+                volume.setMinIops(minIops);
+                volume.setMaxIops(maxIops);
+                volume.setInstanceId(null);
+                volume.setUpdated(new Date());
+                volume.setDisplayVolume(displayVolume);
+                if (parentVolume != null) {
+                    volume.setTemplateId(parentVolume.getTemplateId());
+                    volume.setFormat(parentVolume.getFormat());
+                } else {
+                    volume.setTemplateId(null);
+                }
+
+                volume = _volsDao.persist(volume);
+                if (cmd.getSnapshotId() == null && displayVolume) {
+                    // for volume created from snapshot, create usage event after volume creation
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size,
+                            Volume.class.getName(), volume.getUuid(), displayVolume);
+                }
+
+                CallContext.current().setEventDetails("Volume Id: " + volume.getUuid());
+
+                // Increment resource count during allocation; if actual creation fails,
+                // decrement it
+                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
+                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
+                return volume;
+            }
+        });
+    }
+
+    public boolean validateVolumeSizeRange(long size) {
+        if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
+            throw new InvalidParameterValueException("Please specify a size of at least 1 GB.");
+        } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) {
+            throw new InvalidParameterValueException("Requested volume size is " + size + ", but the maximum size allowed is " + _maxVolumeSizeInGb + " GB.");
+        }
+
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true)
+    public VolumeVO createVolume(CreateVolumeCmd cmd) {
+        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
+        boolean created = true;
+
+        try {
+            if (cmd.getSnapshotId() != null) {
+                volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId(), cmd.getVirtualMachineId());
+                if (volume.getState() != Volume.State.Ready) {
+                    created = false;
+                }
+
+                // if VM Id is provided, attach the volume to the VM
+                if (cmd.getVirtualMachineId() != null) {
+                    try {
+                        attachVolumeToVM(cmd.getVirtualMachineId(), volume.getId(), volume.getDeviceId());
+                    } catch (Exception ex) {
+                        StringBuilder message = new StringBuilder("Volume: ");
+                        message.append(volume.getUuid());
+                        message.append(" created successfully, but failed to attach the newly created volume to VM: ");
+                        message.append(cmd.getVirtualMachineId());
+                        message.append(" due to error: ");
+                        message.append(ex.getMessage());
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug(message, ex);
+                        }
+                        throw new CloudRuntimeException(message.toString());
+                    }
+                }
+            }
+            return volume;
+        } catch (Exception e) {
+            created = false;
+            VolumeInfo vol = volFactory.getVolume(cmd.getEntityId());
+            vol.stateTransit(Volume.Event.DestroyRequested);
+            throw new CloudRuntimeException("Failed to create volume: " + volume.getId(), e);
+        } finally {
+            if (!created) {
+                s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
+                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume());
+                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, cmd.getDisplayVolume(), new Long(volume.getSize()));
+            }
+        }
+    }
+
+    protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Long vmId) throws StorageUnavailableException {
+        VolumeInfo createdVolume = null;
+        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+        snapshot.getVolumeId();
+
+        UserVmVO vm = null;
+        if (vmId != null) {
+            vm = _userVmDao.findById(vmId);
+        }
+
+        // sync old snapshots to region store if necessary
+
+        createdVolume = _volumeMgr.createVolumeFromSnapshot(volume, snapshot, vm);
+        VolumeVO volumeVo = _volsDao.findById(createdVolume.getId());
+        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(),
+                createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid(), volumeVo.isDisplayVolume());
+
+        return volumeVo;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
+    public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException {
+        Long newSize;
+        Long newMinIops;
+        Long newMaxIops;
+        Integer newHypervisorSnapshotReserve;
+        boolean shrinkOk = cmd.isShrinkOk();
+
+        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
+        if (volume == null) {
+            throw new InvalidParameterValueException("No such volume");
+        }
+
+        // checking if there are any ongoing snapshots on the volume which is to be resized
+        List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(cmd.getId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
+        if (ongoingSnapshots.size() > 0) {
+            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on this volume, resize volume is not permitted, please try again later.");
+        }
+
+        /* Does the caller have authority to act on this volume? */
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+
+        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+        DiskOfferingVO newDiskOffering = null;
+
+        if (cmd.getNewDiskOfferingId() != null && volume.getDiskOfferingId() != cmd.getNewDiskOfferingId()) {
+            newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
+        }
+
+        /* Only works for KVM/XenServer/VMware (or "Any") for now, and volumes with 'None' since they're just allocated in DB */
+
+        HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
+
+        if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Any
+                && hypervisorType != HypervisorType.None) {
+            throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support  rootdisksize override");
+        }
+
+        if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) {
+            throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. Volume " + volume.getUuid() + " is in state " + volume.getState() + ".");
+        }
+
+        // if we are to use the existing disk offering
+        if (newDiskOffering == null) {
+            newSize = cmd.getSize();
+            newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve();
+
+            // if the caller is looking to change the size of the volume
+            if (newSize != null) {
+                if (!diskOffering.isCustomized() && !volume.getVolumeType().equals(Volume.Type.ROOT)) {
+                    throw new InvalidParameterValueException("To change a volume's size without providing a new disk offering, its current disk offering must be "
+                            + "customizable or it must be a root volume (if providing a disk offering, make sure it is different from the current disk offering).");
+                }
+
+                // convert from bytes to GiB
+                newSize = newSize << 30;
+            } else {
+                // no parameter provided; just use the original size of the volume
+                newSize = volume.getSize();
+            }
+
+            newMinIops = cmd.getMinIops();
+
+            if (newMinIops != null) {
+                if (!volume.getVolumeType().equals(Volume.Type.ROOT) && (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops())) {
+                    throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Min IOPS' parameter.");
+                }
+            } else {
+                // no parameter provided; just use the original min IOPS of the volume
+                newMinIops = volume.getMinIops();
+            }
+
+            newMaxIops = cmd.getMaxIops();
+
+            if (newMaxIops != null) {
+                if (!volume.getVolumeType().equals(Volume.Type.ROOT) && (diskOffering.isCustomizedIops() == null || !diskOffering.isCustomizedIops())) {
+                    throw new InvalidParameterValueException("The current disk offering does not support customization of the 'Max IOPS' parameter.");
+                }
+            } else {
+                // no parameter provided; just use the original max IOPS of the volume
+                newMaxIops = volume.getMaxIops();
+            }
+
+            validateIops(newMinIops, newMaxIops);
+        } else {
+            if (newDiskOffering.getRemoved() != null) {
+                throw new InvalidParameterValueException("Requested disk offering has been removed.");
+            }
+
+            if (!DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) {
+                throw new InvalidParameterValueException("Requested disk offering type is invalid.");
+            }
+
+            if (diskOffering.getTags() != null) {
+                if (!StringUtils.areTagsEqual(diskOffering.getTags(), newDiskOffering.getTags())) {
+                    throw new InvalidParameterValueException("The tags on the new and old disk offerings must match.");
+                }
+            } else if (newDiskOffering.getTags() != null) {
+                throw new InvalidParameterValueException("There are no tags on the current disk offering. The new disk offering needs to have no tags, as well.");
+            }
+
+            if (newDiskOffering.getDomainId() != null) {
+                // not a public offering; check access
+                _configMgr.checkDiskOfferingAccess(CallContext.current().getCallingAccount(), newDiskOffering);
+            }
+
+            if (newDiskOffering.isCustomized()) {
+                newSize = cmd.getSize();
+
+                if (newSize == null) {
+                    throw new InvalidParameterValueException("The new disk offering requires that a size be specified.");
+                }
+
+                // convert from GiB to bytes
+                newSize = newSize << 30;
+            } else {
+                if (cmd.getSize() != null) {
+                    throw new InvalidParameterValueException("You cannnot pass in a custom disk size to a non-custom disk offering.");
+                }
+
+                newSize = newDiskOffering.getDiskSize();
+            }
+
+            if (!volume.getSize().equals(newSize) && !volume.getVolumeType().equals(Volume.Type.DATADISK)) {
+                throw new InvalidParameterValueException("Only data volumes can be resized via a new disk offering.");
+            }
+
+            if (newDiskOffering.isCustomizedIops() != null && newDiskOffering.isCustomizedIops()) {
+                newMinIops = cmd.getMinIops() != null ? cmd.getMinIops() : volume.getMinIops();
+                newMaxIops = cmd.getMaxIops() != null ? cmd.getMaxIops() : volume.getMaxIops();
+
+                validateIops(newMinIops, newMaxIops);
+            } else {
+                newMinIops = newDiskOffering.getMinIops();
+                newMaxIops = newDiskOffering.getMaxIops();
+            }
+
+            // if the hypervisor snapshot reserve value is null, it must remain null (currently only KVM uses null and null is all KVM uses for a value here)
+            newHypervisorSnapshotReserve = volume.getHypervisorSnapshotReserve() != null ? newDiskOffering.getHypervisorSnapshotReserve() : null;
+        }
+
+        long currentSize = volume.getSize();
+
+        // if the caller is looking to change the size of the volume
+        if (currentSize != newSize) {
+            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("A volume that is attached to a VM with any VM snapshots cannot be resized.");
+                }
+            }
+
+            if (!validateVolumeSizeRange(newSize)) {
+                throw new InvalidParameterValueException("Requested size out of range");
+            }
+
+            Long storagePoolId = volume.getPoolId();
+
+            if (storagePoolId != null) {
+                StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
+
+                if (storagePoolVO.isManaged()) {
+                    Long instanceId = volume.getInstanceId();
+
+                    if (instanceId != null) {
+                        VMInstanceVO vmInstanceVO = _vmInstanceDao.findById(instanceId);
+
+                        if (vmInstanceVO.getHypervisorType() == HypervisorType.KVM && vmInstanceVO.getState() != State.Stopped) {
+                            throw new CloudRuntimeException("This kind of KVM disk cannot be resized while it is connected to a VM that's not in the Stopped state.");
+                        }
+                    }
+                }
+            }
+
+            /*
+             * Let's make certain they (think they) know what they're doing if they
+             * want to shrink by forcing them to provide the shrinkok parameter.
+             * This will be checked again at the hypervisor level where we can see
+             * the actual disk size.
+             */
+            if (currentSize > newSize && !shrinkOk) {
+                throw new InvalidParameterValueException("Going from existing size of " + currentSize + " to size of " + newSize + " would shrink the volume."
+                        + "Need to sign off by supplying the shrinkok parameter with value of true.");
+            }
+
+            if (newSize > currentSize) {
+                /* Check resource limit for this account on primary storage resource */
+                _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), ResourceType.primary_storage, volume.isDisplayVolume(),
+                        new Long(newSize - currentSize).longValue());
+            }
+        }
+
+        // Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
+        // the requested change
+
+        /* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
+        if (volume.getState() == Volume.State.Allocated) {
+            s_logger.debug("Volume is in the allocated state, but has never been created. Simply updating database with new size and IOPS.");
+
+            volume.setSize(newSize);
+            volume.setMinIops(newMinIops);
+            volume.setMaxIops(newMaxIops);
+            volume.setHypervisorSnapshotReserve(newHypervisorSnapshotReserve);
+
+            if (newDiskOffering != null) {
+                volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
+            }
+
+            _volsDao.update(volume.getId(), volume);
+
+            return volume;
+        }
+
+        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
+
+        if (userVm != null) {
+            if (volume.getVolumeType().equals(Volume.Type.ROOT) && userVm.getPowerState() != VirtualMachine.PowerState.PowerOff && hypervisorType == HypervisorType.VMware) {
+                s_logger.error(" For ROOT volume resize VM should be in Power Off state.");
+                throw new InvalidParameterValueException("VM current state is : " + userVm.getPowerState() + ". But VM should be in " + VirtualMachine.PowerState.PowerOff + " state.");
+            }
+            // serialize VM operation
+            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+                // avoid re-entrance
+
+                VmWorkJobVO placeHolder = null;
+
+                placeHolder = createPlaceHolderWork(userVm.getId());
+
+                try {
+                    return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
+                            newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
+                } finally {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+            } else {
+                Outcome<Volume> outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve,
+                        newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk);
+
+                try {
+                    outcome.get();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("Operation was interrupted", e);
+                } catch (java.util.concurrent.ExecutionException e) {
+                    throw new RuntimeException("Execution exception", e);
+                }
+
+                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+
+                if (jobResult != null) {
+                    if (jobResult instanceof ConcurrentOperationException) {
+                        throw (ConcurrentOperationException)jobResult;
+                    } else if (jobResult instanceof ResourceAllocationException) {
+                        throw (ResourceAllocationException)jobResult;
+                    } else if (jobResult instanceof RuntimeException) {
+                        throw (RuntimeException)jobResult;
+                    } else if (jobResult instanceof Throwable) {
+                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                    } else if (jobResult instanceof Long) {
+                        return _volsDao.findById((Long)jobResult);
+                    }
+                }
+
+                return volume;
+            }
+        }
+
+        return orchestrateResizeVolume(volume.getId(), currentSize, newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null,
+                shrinkOk);
+    }
+
+    private void validateIops(Long minIops, Long maxIops) {
+        if ((minIops == null && maxIops != null) || (minIops != null && maxIops == null)) {
+            throw new InvalidParameterValueException("Either 'miniops' and 'maxiops' must both be provided or neither must be provided.");
+        }
+
+        if (minIops != null && maxIops != null) {
+            if (minIops > maxIops) {
+                throw new InvalidParameterValueException("The 'miniops' parameter must be less than or equal to the 'maxiops' parameter.");
+            }
+        }
+    }
+
+    private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long newSize, Long newMinIops, Long newMaxIops, Integer newHypervisorSnapshotReserve, Long newDiskOfferingId,
+            boolean shrinkOk) {
+        VolumeVO volume = _volsDao.findById(volumeId);
+        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
+        StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
+        boolean isManaged = storagePool.isManaged();
+
+        if (!storageMgr.storagePoolHasEnoughSpaceForResize(storagePool, currentSize, newSize)) {
+            throw new CloudRuntimeException("Storage pool " + storagePool.getName() + " does not have enough space to resize volume " + volume.getName());
+        }
+
+        /*
+         * get a list of hosts to send the commands to, try the system the
+         * associated vm is running on first, then the last known place it ran.
+         * If not attached to a userVm, we pass 'none' and resizevolume.sh is ok
+         * with that since it only needs the vm name to live resize
+         */
+        long[] hosts = null;
+        String instanceName = "none";
+        if (userVm != null) {
+            instanceName = userVm.getInstanceName();
+            if (userVm.getHostId() != null) {
+                hosts = new long[] {userVm.getHostId()};
+            } else if (userVm.getLastHostId() != null) {
+                hosts = new long[] {userVm.getLastHostId()};
+            }
+
+            final String errorMsg = "The VM must be stopped or the disk detached in order to resize with the XenServer Hypervisor.";
+
+            if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
+                HostVO host = _hostDao.findById(hosts[0]);
+
+                if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
+                    throw new InvalidParameterValueException(errorMsg);
+                }
+            }
+
+            /* Xen only works offline, SR does not support VDI.resizeOnline */
+            if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
+                throw new InvalidParameterValueException(errorMsg);
+            }
+        }
+
+        ResizeVolumePayload payload = new ResizeVolumePayload(newSize, newMinIops, newMaxIops, newHypervisorSnapshotReserve, shrinkOk, instanceName, hosts, isManaged);
+
+        try {
+            VolumeInfo vol = volFactory.getVolume(volume.getId());
+            vol.addPayload(payload);
+
+            // this call to resize has a different impact depending on whether the
+            // underlying primary storage is managed or not
+            // if managed, this is the chance for the plug-in to change the size and/or IOPS values
+            // if not managed, this is the chance for the plug-in to talk to the hypervisor layer
+            // to change the size of the disk
+            AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
+            VolumeApiResult result = future.get();
+
+            if (result.isFailed()) {
+                s_logger.warn("Failed to resize the volume " + volume);
+                String details = "";
+                if (result.getResult() != null && !result.getResult().isEmpty()) {
+                    details = result.getResult();
+                }
+                throw new CloudRuntimeException(details);
+            }
+
+            // managed storage is designed in such a way that the storage plug-in does not
+            // talk to the hypervisor layer; as such, if the storage is managed and the
+            // current and new sizes are different, then CloudStack (i.e. not a storage plug-in)
+            // needs to tell the hypervisor to resize the disk
+            if (storagePool.isManaged() && currentSize != newSize) {
+                if (hosts != null && hosts.length > 0) {
+                    HostVO hostVO = _hostDao.findById(hosts[0]);
+
+                    if (hostVO.getHypervisorType() != HypervisorType.KVM) {
+                        volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
+                    }
+                }
+
+                volume.setSize(newSize);
+
+                _volsDao.update(volume.getId(), volume);
+            }
+
+            volume = _volsDao.findById(volume.getId());
+
+            if (newDiskOfferingId != null) {
+                volume.setDiskOfferingId(newDiskOfferingId);
+            }
+
+            if (currentSize != newSize) {
+                volume.setSize(newSize);
+            }
+
+            _volsDao.update(volume.getId(), volume);
+
+            /* Update resource count for the account on primary storage resource */
+            if (!shrinkOk) {
+                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(newSize - currentSize));
+            } else {
+                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), new Long(currentSize - newSize));
+            }
+            return volume;
+        } catch (InterruptedException e) {
+            s_logger.warn("failed get resize volume result", e);
+            throw new CloudRuntimeException(e.getMessage());
+        } catch (ExecutionException e) {
+            s_logger.warn("failed get resize volume result", e);
+            throw new CloudRuntimeException(e.getMessage());
+        } catch (Exception e) {
+            s_logger.warn("failed get resize volume result", e);
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume")
+    /**
+     * Executes the removal of the volume. If the volume is only allocated we do not try to remove it from primary and secondary storage.
+     * Otherwise, after the removal in the database, we will try to remove the volume from both primary and secondary storage.
+     */
+    public boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException {
+        VolumeVO volume = retrieveAndValidateVolume(volumeId, caller);
+        try {
+            destroyVolumeIfPossible(volume);
+            // Mark volume as removed if volume has not been created on primary or secondary
+            if (volume.getState() == Volume.State.Allocated) {
+                _volsDao.remove(volumeId);
+                stateTransitTo(volume, Volume.Event.DestroyRequested);
+                return true;
+            }
+            expungeVolumesInPrimaryStorageIfNeeded(volume);
+            expungeVolumesInSecondaryStorageIfNeeded(volume);
+            cleanVolumesCache(volume);
+            return true;
+        } catch (InterruptedException | ExecutionException | NoTransitionException e) {
+            s_logger.warn("Failed to expunge volume: " + volume.getUuid(), e);
+            return false;
+        }
+    }
+
+    /**
+     *  Retrieves and validates the volume for the {@link #deleteVolume(long, Account)} method. The following validation are executed.
+     *  <ul>
+     *      <li> if no volume is found in the database, we throw an {@link InvalidParameterValueException};
+     *      <li> if there are snapshots operation on the volume we cannot delete it. Therefore, an {@link InvalidParameterValueException} is thrown;
+     *      <li> if the volume is still attached to a VM we throw an {@link InvalidParameterValueException};
+     *      <li> if volume state is in {@link Volume.State#UploadOp}, we check the {@link VolumeDataStoreVO}. Then, if the {@link VolumeDataStoreVO} for the given volume has download status of {@link VMTemplateStorageResourceAssoc.Status#DOWNLOAD_IN_PROGRESS}, an exception is throw;
+     *      <li> if the volume state is in {@link Volume.State#NotUploaded} or if the state is {@link Volume.State#UploadInProgress}, an {@link InvalidParameterValueException} is thrown;
+     *      <li> we also check if the user has access to the given volume using {@link AccountManager#checkAccess(Account, org.apache.cloudstack.acl.SecurityChecker.AccessType, boolean, String)}.
+     *  </ul>
+     *
+     *  After all validations we return the volume object.
+     */
+    protected VolumeVO retrieveAndValidateVolume(long volumeId, Account caller) {
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
+        }
+        if (!_snapshotMgr.canOperateOnVolume(volume)) {
+            throw new InvalidParameterValueException("There are snapshot operations in progress on the volume, unable to delete it");
+        }
+        if (volume.getInstanceId() != null) {
+            throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
+        }
+        if (volume.getState() == Volume.State.UploadOp) {
+            VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
+            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
+                throw new InvalidParameterValueException("Please specify a volume that is not uploading");
+            }
+        }
+        if (volume.getState() == Volume.State.NotUploaded || volume.getState() == Volume.State.UploadInProgress) {
+            throw new InvalidParameterValueException("The volume is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
+        }
+        _accountMgr.checkAccess(caller, null, true, volume);
+        return volume;
+    }
+
+    /**
+     * Destroy the volume if possible and then decrement the following resource types.
+     * <ul>
+     *  <li> {@link ResourceType#volume};
+     *  <li> {@link ResourceType#primary_storage}
+     * </ul>
+     *
+     * A volume can be destroyed if it is not in any of the following states.
+     * <ul>
+     *  <li> {@value Volume.State#Destroy};
+     *  <li> {@value Volume.State#Expunging};
+     *  <li> {@value Volume.State#Expunged}.
+     * </ul>
+     *
+     * The volume is destroyed via {@link VolumeService#destroyVolume(long)} method.
+     */
+    protected void destroyVolumeIfPossible(VolumeVO volume) {
+        if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunged) {
+            volService.destroyVolume(volume.getId());
+
+            // Decrement the resource count for volumes and primary storage belonging user VM's only
+            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
+            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplayVolume(), volume.getSize());
+        }
+    }
+
+    /**
+     * We will check if the given volume is in the primary storage. If it is, we will execute an asynchronous call to delete it there.
+     * If the volume is not in the primary storage, we do nothing here.
+     */
+    protected void expungeVolumesInPrimaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException {
+        VolumeInfo volOnPrimary = volFactory.getVolume(volume.getId(), DataStoreRole.Primary);
+        if (volOnPrimary != null) {
+            s_logger.info("Expunging volume " + volume.getId() + " from primary data store");
+            AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnPrimary);
+            future.get();
+        }
+    }
+
+    /**
+     * We will check if the given volume is in the secondary storage. If the volume is not in the primary storage, we do nothing here.
+     * If it is, we will execute an asynchronous call to delete it there. Then, we decrement the {@link ResourceType#secondary_storage} for the account that owns the volume.
+     */
+    protected void expungeVolumesInSecondaryStorageIfNeeded(VolumeVO volume) throws InterruptedException, ExecutionException {
+        VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
+        if (volOnSecondary != null) {
+            s_logger.info("Expunging volume " + volume.getId() + " from secondary data store");
+            AsyncCallFuture<VolumeApiResult> future2 = volService.expungeVolumeAsync(volOnSecondary);
+            future2.get();
+
+            _resourceLimitMgr.decrementResourceCount(volOnSecondary.getAccountId(), ResourceType.secondary_storage, volOnSecondary.getSize());
+        }
+    }
+
+    /**
+     * Clean volumes cache entries (if they exist).
+     */
+    protected void cleanVolumesCache(VolumeVO volume) {
+        List<VolumeInfo> cacheVols = volFactory.listVolumeOnCache(volume.getId());
+        if (CollectionUtils.isEmpty(cacheVols)) {
+            return;
+        }
+        for (VolumeInfo volOnCache : cacheVols) {
+            s_logger.info("Delete volume from image cache store: " + volOnCache.getDataStore().getName());
+            volOnCache.delete();
+        }
+    }
+
+    protected boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException {
+        return _volStateMachine.transitTo(vol, event, null, _volsDao);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
+    public Volume attachVolumeToVM(AttachVolumeCmd command) {
+        return attachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId());
+    }
+
+    private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
+        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+
+        if (volumeToAttach.isAttachedVM()) {
+            throw new CloudRuntimeException("This volume is already attached to a VM.");
+        }
+
+        UserVmVO vm = _userVmDao.findById(vmId);
+        VolumeVO exstingVolumeOfVm = null;
+        List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
+        if (rootVolumesOfVm.size() > 1) {
+            throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
+        } else {
+            if (!rootVolumesOfVm.isEmpty()) {
+                exstingVolumeOfVm = rootVolumesOfVm.get(0);
+            } else {
+                // locate data volume of the vm
+                List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
+                for (VolumeVO diskVolume : diskVolumesOfVm) {
+                    if (diskVolume.getState() != Volume.State.Allocated) {
+                        exstingVolumeOfVm = diskVolume;
+                        break;
+                    }
+                }
+            }
+        }
+
+        HypervisorType rootDiskHyperType = vm.getHypervisorType();
+        HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+        VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
+
+        //don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
+        StoragePoolVO destPrimaryStorage = null;
+        if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
+            destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
+        }
+
+        boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;
+
+        if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) {
+            try {
+                newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage);
+            } catch (NoTransitionException e) {
+                s_logger.debug("Failed to create volume on primary storage", e);
+                throw new CloudRuntimeException("Failed to create volume on primary storage", e);
+            }
+        }
+
+        // reload the volume from db
+        newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
+        boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage);
+
+        if (moveVolumeNeeded) {
+            PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)newVolumeOnPrimaryStorage.getDataStore();
+            if (primaryStore.isLocal()) {
+                throw new CloudRuntimeException(
+                        "Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() + " as migration of local data volume is not allowed");
+            }
+            StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
+
+            try {
+                newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(),
+                        volumeToAttachHyperType);
+            } catch (ConcurrentOperationException e) {
+                s_logger.debug("move volume failed", e);
+                throw new CloudRuntimeException("move volume failed", e);
+            } catch (StorageUnavailableException e) {
+                s_logger.debug("move volume failed", e);
+                throw new CloudRuntimeException("move volume failed", e);
+            }
+        }
+        VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
+        // Getting the fresh vm object in case of volume migration to check the current state of VM
+        if (moveVolumeNeeded || volumeOnSecondary) {
+            vm = _userVmDao.findById(vmId);
+            if (vm == null) {
+                throw new InvalidParameterValueException("VM not found.");
+            }
+        }
+        newVol = sendAttachVolumeCommand(vm, newVol, deviceId);
+        return newVol;
+    }
+
+    public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Check that the volume ID is valid
+        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+        // Check that the volume is a data volume
+        if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
+            throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
+        }
+
+        // Check that the volume is not currently attached to any VM
+        if (volumeToAttach.getInstanceId() != null) {
+            throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
+        }
+
+        // Check that the volume is not destroyed
+        if (volumeToAttach.getState() == Volume.State.Destroy) {
+            throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
+        }
+
+        // Check that the virtual machine ID is valid and it's a user vm
+        UserVmVO vm = _userVmDao.findById(vmId);
+        if (vm == null || vm.getType() != VirtualMachine.Type.User) {
+            throw new InvalidParameterValueException("Please specify a valid User VM.");
+        }
+
+        // Check that the VM is in the correct state
+        if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
+            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+        }
+
+        // Check that the VM and the volume are in the same zone
+        if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
+            throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
+        }
+
+        // Check that the device ID is valid
+        if (deviceId != null) {
+            // validate ROOT volume type
+            if (deviceId.longValue() == 0) {
+                validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
+                // vm shouldn't have any volume with deviceId 0
+                if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
+                    throw new InvalidParameterValueException("Vm already has root volume attached to it");
+                }
+                // volume can't be in Uploaded state
+                if (volumeToAttach.getState() == Volume.State.Uploaded) {
+                    throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
+                }
+            }
+        }
+
+        // Check that the number of data volumes attached to VM is less than
+        // that supported by hypervisor
+        if (deviceId == null || deviceId.longValue() != 0) {
+            List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
+            int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
+            if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
+                throw new InvalidParameterValueException(
+                        "The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
+            }
+        }
+
+        // If local storage is disabled then attaching a volume with local disk
+        // offering not allowed
+        DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
+        if (!dataCenter.isLocalStorageEnabled()) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
+            if (diskOffering.isUseLocalStorage()) {
+                throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
+            }
+        }
+
+        // if target VM has associated VM snapshots
+        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+        if (vmSnapshots.size() > 0) {
+            throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
+        }
+
+        // permission check
+        _accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
+
+        if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
+            throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
+        }
+
+        Account owner = _accountDao.findById(volumeToAttach.getAccountId());
+
+        if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
+            try {
+                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
+            } catch (ResourceAllocationException e) {
+                s_logger.error("primary storage resource limit check failed", e);
+                throw new InvalidParameterValueException(e.getMessage());
+            }
+        }
+
+        HypervisorType rootDiskHyperType = vm.getHypervisorType();
+        HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
+
+        StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+
+        // managed storage can be used for different types of hypervisors
+        // only perform this check if the volume's storage pool is not null and not managed
+        if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
+            if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
+                throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
+            }
+        }
+
+        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+
+        if (asyncExecutionContext != null) {
+            AsyncJob job = asyncExecutionContext.getJob();
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+            }
+
+            _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
+        }
+
+        AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+
+            VmWorkJobVO placeHolder = null;
+            placeHolder = createPlaceHolderWork(vmId);
+            try {
+                return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
+            } finally {
+                _workJobDao.expunge(placeHolder.getId());
+            }
+
+        } else {
+            Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
+
+            Volume vol = null;
+            try {
+                outcome.get();
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof InvalidParameterValueException) {
+                    throw (InvalidParameterValueException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                } else if (jobResult instanceof Long) {
+                    vol = _volsDao.findById((Long)jobResult);
+                }
+            }
+            return vol;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
+    public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId, String chainInfo) {
+
+        VolumeVO volume = _volsDao.findById(volumeId);
+
+        if (volume == null) {
+            throw new InvalidParameterValueException("The volume id doesn't exist");
+        }
+
+        if (path != null) {
+            volume.setPath(path);
+        }
+
+        if (chainInfo != null) {
+            volume.setChainInfo(chainInfo);
+        }
+
+        if (state != null) {
+            try {
+                Volume.State volumeState = Volume.State.valueOf(state);
+                volume.setState(volumeState);
+            } catch (IllegalArgumentException ex) {
+                throw new InvalidParameterValueException("Invalid volume state specified");
+            }
+        }
+
+        if (storageId != null) {
+            StoragePool pool = _storagePoolDao.findById(storageId);
+            if (pool.getDataCenterId() != volume.getDataCenterId()) {
+                throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
+            }
+            volume.setPoolId(pool.getId());
+        }
+
+        if (customId != null) {
+            volume.setUuid(customId);
+        }
+
+        updateDisplay(volume, displayVolume);
+
+        _volsDao.update(volumeId, volume);
+
+        return volume;
+    }
+
+    @Override
+    public void updateDisplay(Volume volume, Boolean displayVolume) {
+        // 1. Resource limit changes
+        updateResourceCount(volume, displayVolume);
+
+        // 2. generate usage event if not in destroyed state
+        saveUsageEvent(volume, displayVolume);
+
+        // 3. Set the flag
+        if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
+            // FIXME - Confused - typecast for now.
+            ((VolumeVO)volume).setDisplayVolume(displayVolume);
+            _volsDao.update(volume.getId(), (VolumeVO)volume);
+        }
+
+    }
+
+    private void updateResourceCount(Volume volume, Boolean displayVolume) {
+        // Update only when the flag has changed.
+        if (displayVolume != null && displayVolume != volume.isDisplayVolume()) {
+            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
+            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
+        }
+    }
+
+    private void saveUsageEvent(Volume volume, Boolean displayVolume) {
+
+        // Update only when the flag has changed  &&  only when volume in a non-destroyed state.
+        if ((displayVolume != null && displayVolume != volume.isDisplayVolume()) && !isVolumeDestroyed(volume)) {
+            if (displayVolume) {
+                // flag turned 1 equivalent to freshly created volume
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(),
+                        volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+            } else {
+                // flag turned 0 equivalent to deleting a volume
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
+                        volume.getUuid());
+            }
+        }
+    }
+
+    private boolean isVolumeDestroyed(Volume volume) {
+        if (volume.getState() == Volume.State.Destroy || volume.getState() == Volume.State.Expunging && volume.getState() == Volume.State.Expunged) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
+    public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null) || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null))
+                || (cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null))) {
+            throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)");
+        }
+
+        Long volumeId = cmmd.getId();
+        VolumeVO volume = null;
+
+        if (volumeId != null) {
+            volume = _volsDao.findById(volumeId);
+        } else {
+            volume = _volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0);
+        }
+
+        // Check that the volume ID is valid
+        if (volume == null) {
+            throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
+        }
+
+        Long vmId = null;
+
+        if (cmmd.getVirtualMachineId() == null) {
+            vmId = volume.getInstanceId();
+        } else {
+            vmId = cmmd.getVirtualMachineId();
+        }
+
+        // Permissions check
+        _accountMgr.checkAccess(caller, null, true, volume);
+
+        // Check that the volume is currently attached to a VM
+        if (vmId == null) {
+            throw new InvalidParameterValueException("The specified volume is not attached to a VM.");
+        }
+
+        // Check that the VM is in the correct state
+        UserVmVO vm = _userVmDao.findById(vmId);
+        if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) {
+            throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
+        }
+
+        // Check that the volume is a data/root volume
+        if (!(volume.getVolumeType() == Volume.Type.ROOT || volume.getVolumeType() == Volume.Type.DATADISK)) {
+            throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK.toString() + " or " + Volume.Type.ROOT.toString());
+        }
+
+        // Root volume detach is allowed for following hypervisors: Xen/KVM/VmWare
+        if (volume.getVolumeType() == Volume.Type.ROOT) {
+            validateRootVolumeDetachAttach(volume, vm);
+        }
+
+        // Don't allow detach if target VM has associated VM snapshots
+        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+        if (vmSnapshots.size() > 0) {
+            throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots");
+        }
+
+        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (asyncExecutionContext != null) {
+            AsyncJob job = asyncExecutionContext.getJob();
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Trying to attaching volume " + volumeId + "to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
+            }
+
+            _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
+        }
+
+        AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+            // avoid re-entrance
+            VmWorkJobVO placeHolder = null;
+            placeHolder = createPlaceHolderWork(vmId);
+            try {
+                return orchestrateDetachVolumeFromVM(vmId, volumeId);
+            } finally {
+                _workJobDao.expunge(placeHolder.getId());
+            }
+        } else {
+            Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId);
+
+            Volume vol = null;
+            try {
+                outcome.get();
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Operation is interrupted", e);
+            } catch (java.util.concurrent.ExecutionException e) {
+                throw new RuntimeException("Execution excetion", e);
+            }
+
+            Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+            if (jobResult != null) {
+                if (jobResult instanceof ConcurrentOperationException) {
+                    throw (ConcurrentOperationException)jobResult;
+                } else if (jobResult instanceof RuntimeException) {
+                    throw (RuntimeException)jobResult;
+                } else if (jobResult instanceof Throwable) {
+                    throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                } else if (jobResult instanceof Long) {
+                    vol = _volsDao.findById((Long)jobResult);
+                }
+            }
+            return vol;
+        }
+    }
+
+    private void validateRootVolumeDetachAttach(VolumeVO volume, UserVmVO vm) {
+        if (!(vm.getHypervisorType() == HypervisorType.XenServer || vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.KVM
+                || vm.getHypervisorType() == HypervisorType.Simulator)) {
+            throw new InvalidParameterValueException("Root volume detach is not supported for hypervisor type " + vm.getHypervisorType());
+        }
+        if (!(vm.getState() == State.Stopped) || (vm.getState() == State.Destroyed)) {
+            throw new InvalidParameterValueException("Root volume detach can happen only when vm is in states: " + State.Stopped.toString() + " or " + State.Destroyed.toString());
+        }
+
+        if (volume.getPoolId() != null) {
+            StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId());
+            if (pool.isManaged()) {
+                throw new InvalidParameterValueException("Root volume detach is not supported for Managed DataStores");
+            }
+        }
+    }
+
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume")
+    public Volume detachVolumeViaDestroyVM(long vmId, long volumeId) {
+        return orchestrateDetachVolumeFromVM(vmId, volumeId);
+    }
+
+    private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) {
+        Volume volume = _volsDao.findById(volumeId);
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        String errorMsg = "Failed to detach volume " + volume.getName() + " from VM " + vm.getHostName();
+        boolean sendCommand = vm.getState() == State.Running;
+
+        Long hostId = vm.getHostId();
+
+        if (hostId == null) {
+            hostId = vm.getLastHostId();
+            HostVO host = _hostDao.findById(hostId);
+
+            if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
+                sendCommand = true;
+            }
+        }
+
+        HostVO host = null;
+        StoragePoolVO volumePool = _storagePoolDao.findByIdIncludingRemoved(volume.getPoolId());
+
+        if (hostId != null) {
+            host = _hostDao.findById(hostId);
+
+            if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumePool != null && volumePool.isManaged()) {
+                sendCommand = true;
+            }
+        }
+
+        if (volumePool == null) {
+            sendCommand = false;
+        }
+
+        Answer answer = null;
+
+        if (sendCommand) {
+            // collect vm disk statistics before detach a volume
+            UserVmVO userVm = _userVmDao.findById(vmId);
+            if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
+                _userVmService.collectVmDiskStatistics(userVm);
+            }
+
+            DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
+            DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
+
+            DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
+
+            cmd.setManaged(volumePool.isManaged());
+
+            cmd.setStorageHost(volumePool.getHostAddress());
+            cmd.setStoragePort(volumePool.getPort());
+
+            cmd.set_iScsiName(volume.get_iScsiName());
+
+            try {
+                answer = _agentMgr.send(hostId, cmd);
+            } catch (Exception e) {
+                throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
+            }
+        }
+
+        if (!sendCommand || (answer != null && answer.getResult())) {
+            // Mark the volume as detached
+            _volsDao.detachVolume(volume.getId());
+
+            // volume.getPoolId() should be null if the VM we are detaching the disk from has never been started before
+            if (volume.getPoolId() != null) {
+                DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary);
+                volService.revokeAccess(volFactory.getVolume(volume.getId()), host, dataStore);
+            }
+            if (volumePool != null && hostId != null) {
+                handleTargetsForVMware(hostId, volumePool.getHostAddress(), volumePool.getPort(), volume.get_iScsiName());
+            }
+            return _volsDao.findById(volumeId);
+        } else {
+
+            if (answer != null) {
+                String details = answer.getDetails();
+                if (details != null && !details.isEmpty()) {
+                    errorMsg += "; " + details;
+                }
+            }
+
+            throw new CloudRuntimeException(errorMsg);
+        }
+    }
+
+    public void updateMissingRootDiskController(final VMInstanceVO vm, final String rootVolChainInfo) {
+        if (vm == null || !VirtualMachine.Type.User.equals(vm.getType()) || Strings.isNullOrEmpty(rootVolChainInfo)) {
+            return;
+        }
+        String rootDiskController = null;
+        try {
+            final VirtualMachineDiskInfo infoInChain = _gson.fromJson(rootVolChainInfo, VirtualMachineDiskInfo.class);
+            if (infoInChain != null) {
+                rootDiskController = infoInChain.getControllerFromDeviceBusName();
+            }
+            final UserVmVO userVmVo = _userVmDao.findById(vm.getId());
+            if ((rootDiskController != null) && (!rootDiskController.isEmpty())) {
+                _userVmDao.loadDetails(userVmVo);
+                _userVmMgr.persistDeviceBusInfo(userVmVo, rootDiskController);
+            }
+        } catch (JsonParseException e) {
+            s_logger.debug("Error parsing chain info json: " + e.getMessage());
+        }
+    }
+
+    private void handleTargetsForVMware(long hostId, String storageAddress, int storagePort, String iScsiName) {
+        HostVO host = _hostDao.findById(hostId);
+
+        if (host.getHypervisorType() == HypervisorType.VMware) {
+            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+            List<Map<String, String>> targets = new ArrayList<>();
+
+            Map<String, String> target = new HashMap<>();
+
+            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
+            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
+            target.put(ModifyTargetsCommand.IQN, iScsiName);
+
+            targets.add(target);
+
+            cmd.setTargets(targets);
+            cmd.setApplyToAllHostsInCluster(true);
+            cmd.setAdd(false);
+            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+
+            sendModifyTargetsCommand(cmd, hostId);
+        }
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            String msg = "Unable to get an answer to the modify targets command";
+
+            s_logger.warn(msg);
+        } else if (!answer.getResult()) {
+            String msg = "Unable to modify target on the following host: " + hostId;
+
+            s_logger.warn(msg);
+        }
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true)
+    public Volume migrateVolume(MigrateVolumeCmd cmd) {
+        Long volumeId = cmd.getVolumeId();
+        Long storagePoolId = cmd.getStoragePoolId();
+
+        VolumeVO vol = _volsDao.findById(volumeId);
+        if (vol == null) {
+            throw new InvalidParameterValueException("Failed to find the volume id: " + volumeId);
+        }
+
+        if (vol.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("Volume must be in ready state");
+        }
+
+        boolean liveMigrateVolume = false;
+        Long instanceId = vol.getInstanceId();
+        Long srcClusterId = null;
+        VMInstanceVO vm = null;
+        if (instanceId != null) {
+            vm = _vmInstanceDao.findById(instanceId);
+        }
+
+        // Check that Vm to which this volume is attached does not have VM Snapshots
+        // OfflineVmwareMigration: considder if this is needed and desirable
+        if (vm != null && _vmSnapshotDao.findByVm(vm.getId()).size() > 0) {
+            throw new InvalidParameterValueException("Volume cannot be migrated, please remove all VM snapshots for VM to which this volume is attached");
+        }
+
+        // OfflineVmwareMigration: extract this block as method and check if it is subject to regression
+        if (vm != null && vm.getState() == State.Running) {
+            // Check if the VM is GPU enabled.
+            if (_serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+                throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+            }
+            // Check if the underlying hypervisor supports storage motion.
+            Long hostId = vm.getHostId();
+            if (hostId != null) {
+                HostVO host = _hostDao.findById(hostId);
+                HypervisorCapabilitiesVO capabilities = null;
+                if (host != null) {
+                    capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(host.getHypervisorType(), host.getHypervisorVersion());
+                    srcClusterId = host.getClusterId();
+                }
+
+                if (capabilities != null) {
+                    liveMigrateVolume = capabilities.isStorageMotionSupported();
+                }
+            }
+
+            // If vm is running, and hypervisor doesn't support live migration, then return error
+            if (!liveMigrateVolume) {
+                throw new InvalidParameterValueException("Volume needs to be detached from VM");
+            }
+        }
+
+        if (liveMigrateVolume && !cmd.isLiveMigrate()) {
+            throw new InvalidParameterValueException("The volume " + vol + "is attached to a vm and for migrating it " + "the parameter livemigrate should be specified");
+        }
+
+        StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        if (destPool == null) {
+            throw new InvalidParameterValueException("Failed to find the destination storage pool: " + storagePoolId);
+        } else if (destPool.isInMaintenance()) {
+            throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode.");
+        }
+
+        if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) {
+            throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName());
+        }
+
+        // OfflineVmwareMigration: check storage tags on disk(offering)s in comparison to destination storage pool
+        // OfflineVmwareMigration: if no match return a proper error now
+        DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
+        if(diskOffering.equals(null)) {
+            throw new CloudRuntimeException("volume '" + vol.getUuid() +"', has no diskoffering. Migration target cannot be checked.");
+        }
+        if(! doesTargetStorageSupportDiskOffering(destPool, diskOffering)) {
+            throw new CloudRuntimeException("Migration target has no matching tags for volume '" +vol.getName() + "(" + vol.getUuid() + ")'");
+        }
+
+        if (liveMigrateVolume && destPool.getClusterId() != null && srcClusterId != null) {
+            if (!srcClusterId.equals(destPool.getClusterId())) {
+                throw new InvalidParameterValueException("Cannot migrate a volume of a virtual machine to a storage pool in a different cluster");
+            }
+        }
+        // In case of VMware, if ROOT volume is being cold-migrated, then ensure destination storage pool is in the same Datacenter as the VM.
+        if (vm != null && vm.getHypervisorType().equals(HypervisorType.VMware)) {
+            if (!liveMigrateVolume && vol.volumeType.equals(Volume.Type.ROOT)) {
+                Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
+                HostVO host = _hostDao.findById(hostId);
+                if (host != null) {
+                    srcClusterId = host.getClusterId();
+                }
+                if (srcClusterId != null && destPool.getClusterId() != null && !srcClusterId.equals(destPool.getClusterId())) {
+                    String srcDcName = _clusterDetailsDao.getVmwareDcName(srcClusterId);
+                    String destDcName = _clusterDetailsDao.getVmwareDcName(destPool.getClusterId());
+                    if (srcDcName != null && destDcName != null && !srcDcName.equals(destDcName)) {
+                        throw new InvalidParameterValueException("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter");
+                    }
+                }
+                updateMissingRootDiskController(vm, vol.getChainInfo());
+            }
+        }
+        DiskOfferingVO newDiskOffering = retrieveAndValidateNewDiskOffering(cmd);
+        validateConditionsToReplaceDiskOfferingOfVolume(vol, newDiskOffering, destPool);
+        if (vm != null) {
+            // serialize VM operation
+            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+                // avoid re-entrance
+
+                VmWorkJobVO placeHolder = null;
+                placeHolder = createPlaceHolderWork(vm.getId());
+                try {
+                    return orchestrateMigrateVolume(vol, destPool, liveMigrateVolume, newDiskOffering);
+                } finally {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+
+            } else {
+                Outcome<Volume> outcome = migrateVolumeThroughJobQueue(vm, vol, destPool, liveMigrateVolume, newDiskOffering);
+
+                try {
+                    outcome.get();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("Operation is interrupted", e);
+                } catch (java.util.concurrent.ExecutionException e) {
+                    throw new RuntimeException("Execution excetion", e);
+                }
+
+                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+                if (jobResult != null) {
+                    if (jobResult instanceof ConcurrentOperationException) {
+                        throw (ConcurrentOperationException)jobResult;
+                    } else if (jobResult instanceof RuntimeException) {
+                        throw (RuntimeException)jobResult;
+                    } else if (jobResult instanceof Throwable) {
+                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                    }
+                }
+
+                // retrieve the migrated new volume from job result
+                if (jobResult != null && jobResult instanceof Long) {
+                    return _entityMgr.findById(VolumeVO.class, ((Long)jobResult));
+                }
+                return null;
+            }
+        }
+
+        return orchestrateMigrateVolume(vol, destPool, liveMigrateVolume, newDiskOffering);
+    }
+
+    /**
+     * Retrieves the new disk offering UUID that might be sent to replace the current one in the volume being migrated.
+     * If no disk offering UUID is provided we return null. Otherwise, we perform the following checks.
+     * <ul>
+     *  <li>Is the disk offering UUID entered valid? If not, an  {@link InvalidParameterValueException} is thrown;
+     *  <li>If the disk offering was already removed, we thrown an {@link InvalidParameterValueException} is thrown;
+     *  <li>We then check if the user executing the operation has access to the given disk offering.
+     * </ul>
+     *
+     * If all checks pass, we move forward returning the disk offering object.
+     */
+    private DiskOfferingVO retrieveAndValidateNewDiskOffering(MigrateVolumeCmd cmd) {
+        String newDiskOfferingUuid = cmd.getNewDiskOfferingUuid();
+        if (org.apache.commons.lang.StringUtils.isBlank(newDiskOfferingUuid)) {
+            return null;
+        }
+        DiskOfferingVO newDiskOffering = _diskOfferingDao.findByUuid(newDiskOfferingUuid);
+        if (newDiskOffering == null) {
+            throw new InvalidParameterValueException(String.format("The disk offering informed is not valid [id=%s].", newDiskOfferingUuid));
+        }
+        if (newDiskOffering.getRemoved() != null) {
+            throw new InvalidParameterValueException(String.format("We cannot assign a removed disk offering [id=%s] to a volume. ", newDiskOffering.getUuid()));
+        }
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, newDiskOffering);
+        return newDiskOffering;
+    }
+
+    /**
+     * Performs the validations required for replacing the disk offering while migrating the volume of storage. If no new disk offering is provided, we do not execute any validation.
+     * If a disk offering is informed, we then proceed with the following checks.
+     * <ul>
+     *  <li>We check if the given volume is of ROOT type. We cannot change the disk offering of a ROOT volume. Therefore, we thrown an {@link InvalidParameterValueException};
+     *  <li>We the disk is being migrated to shared storage and the new disk offering is for local storage (or vice versa), we throw an {@link InvalidParameterValueException}. Bear in mind that we are validating only the new disk offering. If none is provided we can override the current disk offering. This means, placing a volume with shared disk offering in local storage and vice versa;
+     *  <li>We then proceed checking the target storage pool supports the new disk offering {@link #doesTargetStorageSupportNewDiskOffering(StoragePool, DiskOfferingVO)}.
+     * </ul>
+     *
+     * If all of the above validations pass, we check if the size of the new disk offering is different from the volume. If it is, we log a warning message.
+     */
+    protected void validateConditionsToReplaceDiskOfferingOfVolume(VolumeVO volume, DiskOfferingVO newDiskOffering, StoragePool destPool) {
+        if (newDiskOffering == null) {
+            return;
+        }
+        if ((destPool.isShared() && newDiskOffering.isUseLocalStorage()) || destPool.isLocal() && newDiskOffering.isShared()) {
+            throw new InvalidParameterValueException("You cannot move the volume to a shared storage and assing a disk offering for local storage and vice versa.");
+        }
+        if (!doesTargetStorageSupportDiskOffering(destPool, newDiskOffering)) {
+            throw new InvalidParameterValueException(String.format("Target Storage [id=%s] tags [%s] does not match new disk offering [id=%s] tags [%s].", destPool.getUuid(),
+                    getStoragePoolTags(destPool), newDiskOffering.getUuid(), newDiskOffering.getTags()));
+        }
+        if (volume.getSize() != newDiskOffering.getDiskSize()) {
+            DiskOfferingVO oldDiskOffering = this._diskOfferingDao.findById(volume.getDiskOfferingId());
+            s_logger.warn(String.format(
+                    "You are migrating a volume [id=%s] and changing the disk offering[from id=%s to id=%s] to reflect this migration. However, the sizes of the volume and the new disk offering are different.",
+                    volume.getUuid(), oldDiskOffering.getUuid(), newDiskOffering.getUuid()));
+        }
+        s_logger.info(String.format("Changing disk offering to [uuid=%s] while migrating volume [uuid=%s, name=%s].", newDiskOffering.getUuid(), volume.getUuid(), volume.getName()));
+    }
+
+    /**
+     *  Checks if the target storage supports the new disk offering.
+     *  This validation is consistent with the mechanism used to select a storage pool to deploy a volume when a virtual machine is deployed or when a new data disk is allocated.
+     *
+     *  The scenarios when this method returns true or false is presented in the following table.
+     *
+     *   <table border="1">
+     *      <tr>
+     *          <th>#</th><th>Disk offering tags</th><th>Storage tags</th><th>Does the storage support the disk offering?</th>
+     *      </tr>
+     *      <body>
+     *      <tr>
+     *          <td>1</td><td>A,B</td><td>A</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>2</td><td>A,B,C</td><td>A,B,C,D,X</td><td>YES</td>
+     *      </tr>
+     *      <tr>
+     *          <td>3</td><td>A,B,C</td><td>X,Y,Z</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>4</td><td>null</td><td>A,S,D</td><td>YES</td>
+     *      </tr>
+     *      <tr>
+     *          <td>5</td><td>A</td><td>null</td><td>NO</td>
+     *      </tr>
+     *      <tr>
+     *          <td>6</td><td>null</td><td>null</td><td>YES</td>
+     *      </tr>
+     *      </body>
+     *   </table>
+     */
+    protected boolean doesTargetStorageSupportDiskOffering(StoragePool destPool, DiskOfferingVO diskOffering) {
+        String targetStoreTags = diskOffering.getTags();
+        return doesTargetStorageSupportDiskOffering(destPool, targetStoreTags);
+    }
+
+    @Override
+    public boolean doesTargetStorageSupportDiskOffering(StoragePool destPool, String diskOfferingTags) {
+        if (org.apache.commons.lang.StringUtils.isBlank(diskOfferingTags)) {
+            return true;
+        }
+        String storagePoolTags = getStoragePoolTags(destPool);
+        if (org.apache.commons.lang.StringUtils.isBlank(storagePoolTags)) {
+            return false;
+        }
+        String[] storageTagsAsStringArray = org.apache.commons.lang.StringUtils.split(storagePoolTags, ",");
+        String[] newDiskOfferingTagsAsStringArray = org.apache.commons.lang.StringUtils.split(diskOfferingTags, ",");
+
+        return CollectionUtils.isSubCollection(Arrays.asList(newDiskOfferingTagsAsStringArray), Arrays.asList(storageTagsAsStringArray));
+    }
+
+    /**
+     *  Retrieves the storage pool tags as a {@link String}. If the storage pool does not have tags we return a null value.
+     */
+    protected String getStoragePoolTags(StoragePool destPool) {
+        List<StoragePoolDetailVO> storagePoolDetails = storagePoolDetailsDao.listDetails(destPool.getId());
+        if (CollectionUtils.isEmpty(storagePoolDetails)) {
+            return null;
+        }
+        String storageTags = "";
+        for (StoragePoolDetailVO storagePoolDetailVO : storagePoolDetails) {
+            storageTags = storageTags + storagePoolDetailVO.getName() + ",";
+        }
+        return storageTags.substring(0, storageTags.length() - 1);
+    }
+
+    private Volume orchestrateMigrateVolume(VolumeVO volume, StoragePool destPool, boolean liveMigrateVolume, DiskOfferingVO newDiskOffering) {
+        Volume newVol = null;
+        try {
+            if (liveMigrateVolume) {
+                newVol = liveMigrateVolume(volume, destPool);
+            } else {
+                newVol = _volumeMgr.migrateVolume(volume, destPool);
+            }
+            if (newDiskOffering != null) {
+                _volsDao.updateDiskOffering(newVol.getId(), newDiskOffering.getId());
+            }
+        } catch (StorageUnavailableException e) {
+            s_logger.debug("Failed to migrate volume", e);
+            throw new CloudRuntimeException(e.getMessage());
+        } catch (Exception e) {
+            s_logger.debug("Failed to migrate volume", e);
+            throw new CloudRuntimeException(e.getMessage());
+        }
+        return newVol;
+    }
+
+    @DB
+    protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
+        VolumeInfo vol = volFactory.getVolume(volume.getId());
+
+        DataStore dataStoreTarget = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
+        AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, dataStoreTarget);
+        try {
+            VolumeApiResult result = future.get();
+            if (result.isFailed()) {
+                s_logger.debug("migrate volume failed:" + result.getResult());
+                throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
+            }
+            return result.getVolume();
+        } catch (InterruptedException e) {
+            s_logger.debug("migrate volume failed", e);
+            throw new CloudRuntimeException(e.getMessage());
+        } catch (ExecutionException e) {
+            s_logger.debug("migrate volume failed", e);
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true)
+    public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
+            throws ResourceAllocationException {
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
+
+        if (storagePoolVO.isManaged() && locationType == null) {
+            locationType = Snapshot.LocationType.PRIMARY;
+        }
+
+        VMInstanceVO vm = null;
+        if (volume.getInstanceId() != null) {
+            vm = _vmInstanceDao.findById(volume.getInstanceId());
+        }
+
+        if (vm != null) {
+            // serialize VM operation
+            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+                // avoid re-entrance
+
+                VmWorkJobVO placeHolder = null;
+                placeHolder = createPlaceHolderWork(vm.getId());
+                try {
+                    return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm, locationType, asyncBackup);
+                } finally {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+
+            } else {
+                Outcome<Snapshot> outcome = takeVolumeSnapshotThroughJobQueue(vm.getId(), volumeId, policyId, snapshotId, account.getId(), quiescevm, locationType, asyncBackup);
+
+                try {
+                    outcome.get();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("Operation is interrupted", e);
+                } catch (java.util.concurrent.ExecutionException e) {
+                    throw new RuntimeException("Execution excetion", e);
+                }
+
+                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+                if (jobResult != null) {
+                    if (jobResult instanceof ConcurrentOperationException) {
+                        throw (ConcurrentOperationException)jobResult;
+                    } else if (jobResult instanceof ResourceAllocationException) {
+                        throw (ResourceAllocationException)jobResult;
+                    } else if (jobResult instanceof Throwable) {
+                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                    }
+                }
+
+                return _snapshotDao.findById(snapshotId);
+            }
+        } else {
+            CreateSnapshotPayload payload = new CreateSnapshotPayload();
+            payload.setSnapshotId(snapshotId);
+            payload.setSnapshotPolicyId(policyId);
+            payload.setAccount(account);
+            payload.setQuiescevm(quiescevm);
+            payload.setAsyncBackup(asyncBackup);
+            volume.addPayload(payload);
+            return volService.takeSnapshot(volume);
+        }
+    }
+
+    private Snapshot orchestrateTakeVolumeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
+            throws ResourceAllocationException {
+
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+
+        if (volume == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        CreateSnapshotPayload payload = new CreateSnapshotPayload();
+
+        payload.setSnapshotId(snapshotId);
+        payload.setSnapshotPolicyId(policyId);
+        payload.setAccount(account);
+        payload.setQuiescevm(quiescevm);
+        payload.setLocationType(locationType);
+        payload.setAsyncBackup(asyncBackup);
+        volume.addPayload(payload);
+
+        return volService.takeSnapshot(volume);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true)
+    public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+        }
+        DataCenter zone = _dcDao.findById(volume.getDataCenterId());
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
+        }
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        if (ImageFormat.DIR.equals(volume.getFormat())) {
+            throw new InvalidParameterValueException("Snapshot not supported for volume:" + volumeId);
+        }
+
+        if (volume.getTemplateId() != null) {
+            VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
+            if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
+                throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
+            }
+        }
+
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId());
+
+        if (!storagePoolVO.isManaged() && locationType != null) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " LocationType is supported only for managed storage");
+        }
+
+        if (storagePoolVO.isManaged() && locationType == null) {
+            locationType = Snapshot.LocationType.PRIMARY;
+        }
+
+        StoragePool storagePool = (StoragePool)volume.getDataStore();
+        if (storagePool == null) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
+        }
+
+        return snapshotMgr.allocSnapshot(volumeId, policyId, snapshotName, locationType);
+    }
+
+    @Override
+    public Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
+        }
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+        }
+        _accountMgr.checkAccess(caller, null, true, volume);
+        VirtualMachine attachVM = volume.getAttachedVM();
+        if (attachVM == null || attachVM.getId() != vm.getId()) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't attach to vm :" + vm);
+        }
+
+        DataCenter zone = _dcDao.findById(volume.getDataCenterId());
+        if (zone == null) {
+            throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
+        }
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        if (volume.getTemplateId() != null) {
+            VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
+            if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
+                throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
+            }
+        }
+
+        StoragePool storagePool = (StoragePool)volume.getDataStore();
+        if (storagePool == null) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
+        }
+
+        return snapshotMgr.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshotName, null);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true)
+    public String extractVolume(ExtractVolumeCmd cmd) {
+        Long volumeId = cmd.getId();
+        Long zoneId = cmd.getZoneId();
+        String mode = cmd.getMode();
+        Account account = CallContext.current().getCallingAccount();
+
+        if (!_accountMgr.isRootAdmin(account.getId()) && ApiDBUtils.isExtractionDisabled()) {
+            throw new PermissionDeniedException("Extraction has been disabled by admin");
+        }
+
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId");
+            ex.addProxyObject(volumeId.toString(), "volumeId");
+            throw ex;
+        }
+
+        // perform permission check
+        _accountMgr.checkAccess(account, null, true, volume);
+
+        if (_dcDao.findById(zoneId) == null) {
+            throw new InvalidParameterValueException("Please specify a valid zone.");
+        }
+        if (volume.getPoolId() == null) {
+            throw new InvalidParameterValueException("The volume doesn't belong to a storage pool so can't extract it");
+        }
+        // Extract activity only for detached volumes or for volumes whose
+        // instance is stopped
+        if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) {
+            s_logger.debug("Invalid state of the volume with ID: " + volumeId + ". It should be either detached or the VM should be in stopped state.");
+            PermissionDeniedException ex = new PermissionDeniedException("Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state.");
+            ex.addProxyObject(volume.getUuid(), "volumeId");
+            throw ex;
+        }
+
+        if (volume.getVolumeType() != Volume.Type.DATADISK) {
+            // Datadisk dont have any template dependence.
+
+            VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
+            if (template != null) { // For ISO based volumes template = null and
+                // we allow extraction of all ISO based
+                // volumes
+                boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
+                if (!isExtractable && account != null && !_accountMgr.isRootAdmin(account.getId())) {
+                    // Global admins are always allowed to extract
+                    PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted");
+                    ex.addProxyObject(volume.getUuid(), "volumeId");
+                    throw ex;
+                }
+            }
+        }
+
+        if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) {
+            throw new InvalidParameterValueException("Please specify a valid extract Mode ");
+        }
+
+        // Check if the url already exists
+        VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
+        if (volumeStoreRef != null && volumeStoreRef.getExtractUrl() != null) {
+            return volumeStoreRef.getExtractUrl();
+        }
+
+        VMInstanceVO vm = null;
+        if (volume.getInstanceId() != null) {
+            vm = _vmInstanceDao.findById(volume.getInstanceId());
+        }
+
+        if (vm != null) {
+            // serialize VM operation
+            AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
+            if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
+                // avoid re-entrance
+
+                VmWorkJobVO placeHolder = null;
+                placeHolder = createPlaceHolderWork(vm.getId());
+                try {
+                    return orchestrateExtractVolume(volume.getId(), zoneId);
+                } finally {
+                    _workJobDao.expunge(placeHolder.getId());
+                }
+
+            } else {
+                Outcome<String> outcome = extractVolumeThroughJobQueue(vm.getId(), volume.getId(), zoneId);
+
+                try {
+                    outcome.get();
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("Operation is interrupted", e);
+                } catch (java.util.concurrent.ExecutionException e) {
+                    throw new RuntimeException("Execution excetion", e);
+                }
+
+                Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
+                if (jobResult != null) {
+                    if (jobResult instanceof ConcurrentOperationException) {
+                        throw (ConcurrentOperationException)jobResult;
+                    } else if (jobResult instanceof RuntimeException) {
+                        throw (RuntimeException)jobResult;
+                    } else if (jobResult instanceof Throwable) {
+                        throw new RuntimeException("Unexpected exception", (Throwable)jobResult);
+                    }
+                }
+
+                // retrieve the entity url from job result
+                if (jobResult != null && jobResult instanceof String) {
+                    return (String)jobResult;
+                }
+                return null;
+            }
+        }
+
+        return orchestrateExtractVolume(volume.getId(), zoneId);
+    }
+
+    private String orchestrateExtractVolume(long volumeId, long zoneId) {
+        // get latest volume state to make sure that it is not updated by other parallel operations
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null || volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("Volume to be extracted has been removed or not in right state!");
+        }
+        // perform extraction
+        ImageStoreEntity secStore = (ImageStoreEntity)dataStoreMgr.getImageStore(zoneId);
+        String value = _configDao.getValue(Config.CopyVolumeWait.toString());
+        NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue()));
+
+        // Copy volume from primary to secondary storage
+        VolumeInfo srcVol = volFactory.getVolume(volumeId);
+        AsyncCallFuture<VolumeApiResult> cvAnswer = volService.copyVolume(srcVol, secStore);
+        // Check if you got a valid answer.
+        VolumeApiResult cvResult = null;
+        try {
+            cvResult = cvAnswer.get();
+        } catch (InterruptedException e1) {
+            s_logger.debug("failed copy volume", e1);
+            throw new CloudRuntimeException("Failed to copy volume", e1);
+        } catch (ExecutionException e1) {
+            s_logger.debug("failed copy volume", e1);
+            throw new CloudRuntimeException("Failed to copy volume", e1);
+        }
+        if (cvResult == null || cvResult.isFailed()) {
+            String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage.";
+            throw new CloudRuntimeException(errorString);
+        }
+
+        VolumeInfo vol = cvResult.getVolume();
+
+        String extractUrl = secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat(), vol);
+        VolumeDataStoreVO volumeStoreRef = _volumeStoreDao.findByVolume(volumeId);
+
+        volumeStoreRef.setExtractUrl(extractUrl);
+        volumeStoreRef.setExtractUrlCreated(DateUtil.now());
+        volumeStoreRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        volumeStoreRef.setDownloadPercent(100);
+        volumeStoreRef.setZoneId(zoneId);
+
+        _volumeStoreDao.update(volumeStoreRef.getId(), volumeStoreRef);
+
+        return extractUrl;
+    }
+
+    @Override
+    public boolean isDisplayResourceEnabled(Long id) {
+        Volume volume = _volsDao.findById(id);
+        if (volume == null) {
+            return true; // bad id given, default to true
+        }
+        return volume.isDisplayVolume();
+    }
+
+    private boolean needMoveVolume(VolumeVO existingVolume, VolumeInfo newVolume) {
+        if (existingVolume == null || existingVolume.getPoolId() == null || newVolume.getPoolId() == null) {
+            return false;
+        }
+
+        DataStore storeForExistingVol = dataStoreMgr.getPrimaryDataStore(existingVolume.getPoolId());
+        DataStore storeForNewVol = dataStoreMgr.getPrimaryDataStore(newVolume.getPoolId());
+
+        Scope storeForExistingStoreScope = storeForExistingVol.getScope();
+        if (storeForExistingStoreScope == null) {
+            throw new CloudRuntimeException("Can't get scope of data store: " + storeForExistingVol.getId());
+        }
+
+        Scope storeForNewStoreScope = storeForNewVol.getScope();
+        if (storeForNewStoreScope == null) {
+            throw new CloudRuntimeException("Can't get scope of data store: " + storeForNewVol.getId());
+        }
+
+        if (storeForNewStoreScope.getScopeType() == ScopeType.ZONE) {
+            return false;
+        }
+
+        if (storeForExistingStoreScope.getScopeType() != storeForNewStoreScope.getScopeType()) {
+            if (storeForNewStoreScope.getScopeType() == ScopeType.CLUSTER) {
+                Long vmClusterId = null;
+                if (storeForExistingStoreScope.getScopeType() == ScopeType.HOST) {
+                    HostScope hs = (HostScope)storeForExistingStoreScope;
+                    vmClusterId = hs.getClusterId();
+                } else if (storeForExistingStoreScope.getScopeType() == ScopeType.ZONE) {
+                    Long hostId = _vmInstanceDao.findById(existingVolume.getInstanceId()).getHostId();
+                    if (hostId != null) {
+                        HostVO host = _hostDao.findById(hostId);
+                        vmClusterId = host.getClusterId();
+                    }
+                }
+                if (storeForNewStoreScope.getScopeId().equals(vmClusterId)) {
+                    return false;
+                } else {
+                    return true;
+                }
+            } else if (storeForNewStoreScope.getScopeType() == ScopeType.HOST
+                    && (storeForExistingStoreScope.getScopeType() == ScopeType.CLUSTER || storeForExistingStoreScope.getScopeType() == ScopeType.ZONE)) {
+                Long hostId = _vmInstanceDao.findById(existingVolume.getInstanceId()).getHostId();
+                if (storeForNewStoreScope.getScopeId().equals(hostId)) {
+                    return false;
+                }
+            }
+            throw new InvalidParameterValueException("Can't move volume between scope: " + storeForNewStoreScope.getScopeType() + " and " + storeForExistingStoreScope.getScopeType());
+        }
+
+        return !storeForExistingStoreScope.isSameScope(storeForNewStoreScope);
+    }
+
+    private synchronized void checkAndSetAttaching(Long volumeId) {
+        VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
+
+        if (volumeToAttach.isAttachedVM()) {
+            throw new CloudRuntimeException("volume: " + volumeToAttach.getName() + " is already attached to a VM: " + volumeToAttach.getAttachedVmName());
+        }
+
+        if (Volume.State.Allocated.equals(volumeToAttach.getState())) {
+            return;
+        }
+
+        if (Volume.State.Ready.equals(volumeToAttach.getState())) {
+            volumeToAttach.stateTransit(Volume.Event.AttachRequested);
+            return;
+        }
+
+        final String error = "Volume: " + volumeToAttach.getName() + " is in " + volumeToAttach.getState() + ". It should be in Ready or Allocated state";
+        s_logger.error(error);
+        throw new CloudRuntimeException(error);
+    }
+
+    private void verifyManagedStorage(Long storagePoolId, Long hostId) {
+        if (storagePoolId == null || hostId == null) {
+            return;
+        }
+
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
+
+        if (storagePoolVO == null || !storagePoolVO.isManaged()) {
+            return;
+        }
+
+        HostVO hostVO = _hostDao.findById(hostId);
+
+        if (hostVO == null) {
+            return;
+        }
+
+        if (!storageUtil.managedStoragePoolCanScale(storagePoolVO, hostVO.getClusterId(), hostVO.getId())) {
+            throw new CloudRuntimeException("Insufficient number of available " + getNameOfClusteredFileSystem(hostVO));
+        }
+    }
+
+    private String getNameOfClusteredFileSystem(HostVO hostVO) {
+        HypervisorType hypervisorType = hostVO.getHypervisorType();
+
+        if (HypervisorType.XenServer.equals(hypervisorType)) {
+            return "SRs";
+        }
+
+        if (HypervisorType.VMware.equals(hypervisorType)) {
+            return "datastores";
+        }
+
+        return "clustered file systems";
+    }
+
+    private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
+        String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName();
+        boolean sendCommand = vm.getState() == State.Running;
+        AttachAnswer answer = null;
+        Long hostId = vm.getHostId();
+
+        if (hostId == null) {
+            hostId = vm.getLastHostId();
+
+            HostVO host = _hostDao.findById(hostId);
+
+            if (host != null && host.getHypervisorType() == HypervisorType.VMware) {
+                sendCommand = true;
+            }
+        }
+
+        HostVO host = null;
+        StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
+
+        if (hostId != null) {
+            host = _hostDao.findById(hostId);
+
+            if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged()) {
+                sendCommand = true;
+            }
+        }
+
+        verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId);
+
+        // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
+        DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
+
+        checkAndSetAttaching(volumeToAttach.getId());
+
+        boolean attached = false;
+        try {
+            // if we don't have a host, the VM we are attaching the disk to has never been started before
+            if (host != null) {
+                try {
+                    volService.grantAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
+                } catch (Exception e) {
+                    volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
+
+                    throw new CloudRuntimeException(e.getMessage());
+                }
+            }
+
+            if (sendCommand) {
+                if (host != null && host.getHypervisorType() == HypervisorType.KVM && volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
+                    volumeToAttach.setPath(volumeToAttach.get_iScsiName());
+
+                    _volsDao.update(volumeToAttach.getId(), volumeToAttach);
+                }
+
+                DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
+
+                deviceId = getDeviceId(vm, deviceId);
+
+                DiskTO disk = storageMgr.getDiskWithThrottling(volTO, volumeToAttach.getVolumeType(), deviceId, volumeToAttach.getPath(), vm.getServiceOfferingId(),
+                        volumeToAttach.getDiskOfferingId());
+
+                AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
+
+                ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore);
+
+                Map<String, String> details = new HashMap<String, String>();
+
+                disk.setDetails(details);
+
+                details.put(DiskTO.MANAGED, String.valueOf(volumeToAttachStoragePool.isManaged()));
+                details.put(DiskTO.STORAGE_HOST, volumeToAttachStoragePool.getHostAddress());
+                details.put(DiskTO.STORAGE_PORT, String.valueOf(volumeToAttachStoragePool.getPort()));
+                details.put(DiskTO.VOLUME_SIZE, String.valueOf(volumeToAttach.getSize()));
+                details.put(DiskTO.IQN, volumeToAttach.get_iScsiName());
+                details.put(DiskTO.MOUNT_POINT, volumeToAttach.get_iScsiName());
+                details.put(DiskTO.PROTOCOL_TYPE, (volumeToAttach.getPoolType() != null) ? volumeToAttach.getPoolType().toString() : null);
+
+                if (chapInfo != null) {
+                    details.put(DiskTO.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
+                    details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
+                    details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
+                    details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
+                }
+                _userVmDao.loadDetails(vm);
+                Map<String, String> controllerInfo = new HashMap<String, String>();
+                controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
+                controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
+                cmd.setControllerInfo(controllerInfo);
+                s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);
+
+                try {
+                    answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
+                } catch (Exception e) {
+                    if (host != null) {
+                        volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
+                    }
+                    throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage());
+                }
+            }
+
+            if (!sendCommand || (answer != null && answer.getResult())) {
+                // Mark the volume as attached
+                if (sendCommand) {
+                    DiskTO disk = answer.getDisk();
+
+                    _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), disk.getDiskSeq());
+
+                    volumeToAttach = _volsDao.findById(volumeToAttach.getId());
+
+                    if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
+                        volumeToAttach.setPath(answer.getDisk().getPath());
+
+                        _volsDao.update(volumeToAttach.getId(), volumeToAttach);
+                    }
+                } else {
+                    deviceId = getDeviceId(vm, deviceId);
+
+                    _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
+
+                    volumeToAttach = _volsDao.findById(volumeToAttach.getId());
+
+                    if (vm.getHypervisorType() == HypervisorType.KVM &&
+                            volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged() &&
+                            volumeToAttach.getPath() == null && volumeToAttach.get_iScsiName() != null) {
+                        volumeToAttach.setPath(volumeToAttach.get_iScsiName());
+                        _volsDao.update(volumeToAttach.getId(), volumeToAttach);
+                    }
+                }
+
+                // insert record for disk I/O statistics
+                VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
+                if (diskstats == null) {
+                    diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(), vm.getId(), volumeToAttach.getId());
+                    _vmDiskStatsDao.persist(diskstats);
+                }
+
+                attached = true;
+            } else {
+                if (answer != null) {
+                    String details = answer.getDetails();
+                    if (details != null && !details.isEmpty()) {
+                        errorMsg += "; " + details;
+                    }
+                }
+                if (host != null) {
+                    volService.revokeAccess(volFactory.getVolume(volumeToAttach.getId()), host, dataStore);
+                }
+                throw new CloudRuntimeException(errorMsg);
+            }
+        } finally {
+            Volume.Event ev = Volume.Event.OperationFailed;
+            VolumeInfo volInfo = volFactory.getVolume(volumeToAttach.getId());
+            if (attached) {
+                ev = Volume.Event.OperationSucceeded;
+                s_logger.debug("Volume: " + volInfo.getName() + " successfully attached to VM: " + volInfo.getAttachedVmName());
+            } else {
+                s_logger.debug("Volume: " + volInfo.getName() + " failed to attach to VM: " + volInfo.getAttachedVmName());
+            }
+            volInfo.stateTransit(ev);
+        }
+        return _volsDao.findById(volumeToAttach.getId());
+    }
+
+    private int getMaxDataVolumesSupported(UserVmVO vm) {
+        Long hostId = vm.getHostId();
+        if (hostId == null) {
+            hostId = vm.getLastHostId();
+        }
+        HostVO host = _hostDao.findById(hostId);
+        Integer maxDataVolumesSupported = null;
+        if (host != null) {
+            _hostDao.loadDetails(host);
+            maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version"));
+        }
+        if (maxDataVolumesSupported == null || maxDataVolumesSupported.intValue() <= 0) {
+            maxDataVolumesSupported = 6; // 6 data disks by default if nothing
+            // is specified in
+            // 'hypervisor_capabilities' table
+        }
+
+        return maxDataVolumesSupported.intValue();
+    }
+
+    private Long getDeviceId(UserVmVO vm, Long deviceId) {
+        // allocate deviceId
+        int maxDevices = getMaxDataVolumesSupported(vm) + 2; // add 2 to consider devices root volume and cdrom
+        int maxDeviceId = maxDevices - 1;
+        List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
+        if (deviceId != null) {
+            if (deviceId.longValue() < 0 || deviceId.longValue() > maxDeviceId || deviceId.longValue() == 3) {
+                throw new RuntimeException("deviceId should be 0,1,2,4-" + maxDeviceId);
+            }
+            for (VolumeVO vol : vols) {
+                if (vol.getDeviceId().equals(deviceId)) {
+                    throw new RuntimeException("deviceId " + deviceId + " is used by vm " + vm.getId());
+                }
+            }
+        } else {
+            // allocate deviceId here
+            List<String> devIds = new ArrayList<String>();
+            for (int i = 1; i <= maxDeviceId; i++) {
+                devIds.add(String.valueOf(i));
+            }
+            devIds.remove("3");
+            for (VolumeVO vol : vols) {
+                devIds.remove(vol.getDeviceId().toString().trim());
+            }
+            if (devIds.isEmpty()) {
+                throw new RuntimeException("All device Ids are used by vm " + vm.getId());
+            }
+            deviceId = Long.parseLong(devIds.iterator().next());
+        }
+
+        return deviceId;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) {
+        String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
+        _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
+        return true;
+    }
+
+    public List<StoragePoolAllocator> getStoragePoolAllocators() {
+        return _storagePoolAllocators;
+    }
+
+    @Inject
+    public void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators) {
+        _storagePoolAllocators = storagePoolAllocators;
+    }
+
+    public class VmJobVolumeUrlOutcome extends OutcomeImpl<String> {
+        public VmJobVolumeUrlOutcome(final AsyncJob job) {
+            super(String.class, job, VmJobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
+                    assert (jobVo != null);
+                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                        return true;
+                    }
+
+                    return false;
+                }
+            }, AsyncJob.Topics.JOB_STATE);
+        }
+    }
+
+    public class VmJobVolumeOutcome extends OutcomeImpl<Volume> {
+        private long _volumeId;
+
+        public VmJobVolumeOutcome(final AsyncJob job, final long volumeId) {
+            super(Volume.class, job, VmJobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
+                    assert (jobVo != null);
+                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                        return true;
+                    }
+
+                    return false;
+                }
+            }, AsyncJob.Topics.JOB_STATE);
+            _volumeId = volumeId;
+        }
+
+        @Override
+        protected Volume retrieve() {
+            return _volsDao.findById(_volumeId);
+        }
+    }
+
+    public class VmJobSnapshotOutcome extends OutcomeImpl<Snapshot> {
+        private long _snapshotId;
+
+        public VmJobSnapshotOutcome(final AsyncJob job, final long snapshotId) {
+            super(Snapshot.class, job, VmJobCheckInterval.value(), new Predicate() {
+                @Override
+                public boolean checkCondition() {
+                    AsyncJobVO jobVo = _entityMgr.findById(AsyncJobVO.class, job.getId());
+                    assert (jobVo != null);
+                    if (jobVo == null || jobVo.getStatus() != JobInfo.Status.IN_PROGRESS) {
+                        return true;
+                    }
+
+                    return false;
+                }
+            }, AsyncJob.Topics.JOB_STATE);
+            _snapshotId = snapshotId;
+        }
+
+        @Override
+        protected Snapshot retrieve() {
+            return _snapshotDao.findById(_snapshotId);
+        }
+    }
+
+    public Outcome<Volume> attachVolumeToVmThroughJobQueue(final Long vmId, final Long volumeId, final Long deviceId) {
+
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkAttachVolume.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        // save work context info (there are some duplications)
+        VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, deviceId);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobVO jobVo = _jobMgr.getAsyncJob(workJob.getId());
+        s_logger.debug("New job " + workJob.getId() + ", result field: " + jobVo.getResult());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVolumeOutcome(workJob, volumeId);
+    }
+
+    public Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId) {
+
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkDetachVolume.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        // save work context info (there are some duplications)
+        VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVolumeOutcome(workJob, volumeId);
+    }
+
+    public Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId, final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops,
+            final Integer newHypervisorSnapshotReserve, final Long newServiceOfferingId, final boolean shrinkOk) {
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkResizeVolume.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        // save work context info (there are some duplications)
+        VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, currentSize, newSize,
+                newMinIops, newMaxIops, newHypervisorSnapshotReserve, newServiceOfferingId, shrinkOk);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVolumeOutcome(workJob, volumeId);
+    }
+
+    public Outcome<String> extractVolumeThroughJobQueue(final Long vmId, final long volumeId, final long zoneId) {
+
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkExtractVolume.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        // save work context info (there are some duplications)
+        VmWorkExtractVolume workInfo = new VmWorkExtractVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, zoneId);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVolumeUrlOutcome(workJob);
+    }
+
+    private Outcome<Volume> migrateVolumeThroughJobQueue(VMInstanceVO vm, VolumeVO vol, StoragePool destPool, boolean liveMigrateVolume, DiskOfferingVO newDiskOffering) {
+        CallContext context = CallContext.current();
+        User callingUser = context.getCallingUser();
+        Account callingAccount = context.getCallingAccount();
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkMigrateVolume.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        Long newDiskOfferingId = newDiskOffering != null ? newDiskOffering.getId() : null;
+
+        // save work context info (there are some duplications)
+        VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(), VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, vol.getId(), destPool.getId(),
+                liveMigrateVolume, newDiskOfferingId);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobVolumeOutcome(workJob, vol.getId());
+    }
+
+    public Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId, final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm,
+            final Snapshot.LocationType locationType, final boolean asyncBackup) {
+
+        final CallContext context = CallContext.current();
+        final User callingUser = context.getCallingUser();
+        final Account callingAccount = context.getCallingAccount();
+
+        final VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+        VmWorkJobVO workJob = new VmWorkJobVO(context.getContextId());
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
+        workJob.setCmd(VmWorkTakeVolumeSnapshot.class.getName());
+
+        workJob.setAccountId(callingAccount.getId());
+        workJob.setUserId(callingUser.getId());
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(vm.getId());
+        workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
+
+        // save work context info (there are some duplications)
+        VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot(callingUser.getId(), accountId != null ? accountId : callingAccount.getId(), vm.getId(),
+                VolumeApiServiceImpl.VM_WORK_JOB_HANDLER, volumeId, policyId, snapshotId, quiesceVm, locationType, asyncBackup);
+        workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
+
+        _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
+
+        AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
+
+        return new VmJobSnapshotOutcome(workJob, snapshotId);
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateExtractVolume(VmWorkExtractVolume work) throws Exception {
+        String volUrl = orchestrateExtractVolume(work.getVolumeId(), work.getZoneId());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(volUrl));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateAttachVolumeToVM(VmWorkAttachVolume work) throws Exception {
+        Volume vol = orchestrateAttachVolumeToVM(work.getVmId(), work.getVolumeId(), work.getDeviceId());
+
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateDetachVolumeFromVM(VmWorkDetachVolume work) throws Exception {
+        Volume vol = orchestrateDetachVolumeFromVM(work.getVmId(), work.getVolumeId());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateResizeVolume(VmWorkResizeVolume work) throws Exception {
+        Volume vol = orchestrateResizeVolume(work.getVolumeId(), work.getCurrentSize(), work.getNewSize(), work.getNewMinIops(), work.getNewMaxIops(), work.getNewHypervisorSnapshotReserve(),
+                work.getNewServiceOfferingId(), work.isShrinkOk());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(vol.getId())));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateMigrateVolume(VmWorkMigrateVolume work) throws Exception {
+        VolumeVO volume = _volsDao.findById(work.getVolumeId());
+        StoragePoolVO targetStoragePool = _storagePoolDao.findById(work.getDestPoolId());
+        DiskOfferingVO newDiskOffering = _diskOfferingDao.findById(work.getNewDiskOfferingId());
+
+        Volume newVol = orchestrateMigrateVolume(volume, targetStoragePool, work.isLiveMigrate(), newDiskOffering);
+
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(newVol.getId()));
+    }
+
+    @ReflectionUse
+    private Pair<JobInfo.Status, String> orchestrateTakeVolumeSnapshot(VmWorkTakeVolumeSnapshot work) throws Exception {
+        Account account = _accountDao.findById(work.getAccountId());
+        orchestrateTakeVolumeSnapshot(work.getVolumeId(), work.getPolicyId(), work.getSnapshotId(), account, work.isQuiesceVm(), work.getLocationType(), work.isAsyncBackup());
+        return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(work.getSnapshotId()));
+    }
+
+    @Override
+    public Pair<JobInfo.Status, String> handleVmWorkJob(VmWork work) throws Exception {
+        return _jobHandlerProxy.handleVmWorkJob(work);
+    }
+
+    private VmWorkJobVO createPlaceHolderWork(long instanceId) {
+        VmWorkJobVO workJob = new VmWorkJobVO("");
+
+        workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
+        workJob.setCmd("");
+        workJob.setCmdInfo("");
+
+        workJob.setAccountId(0);
+        workJob.setUserId(0);
+        workJob.setStep(VmWorkJobVO.Step.Starting);
+        workJob.setVmType(VirtualMachine.Type.Instance);
+        workJob.setVmInstanceId(instanceId);
+        workJob.setInitMsid(ManagementServerNode.getManagementServerId());
+
+        _workJobDao.persist(workJob);
+
+        return workJob;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return VolumeApiService.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {ConcurrentMigrationsThresholdPerDatastore};
+    }
+}
\ No newline at end of file
diff --git a/server/src/com/cloud/storage/download/DownloadAbandonedState.java b/server/src/main/java/com/cloud/storage/download/DownloadAbandonedState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadAbandonedState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadAbandonedState.java
diff --git a/server/src/com/cloud/storage/download/DownloadActiveState.java b/server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadActiveState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadActiveState.java
diff --git a/server/src/com/cloud/storage/download/DownloadCompleteState.java b/server/src/main/java/com/cloud/storage/download/DownloadCompleteState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadCompleteState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadCompleteState.java
diff --git a/server/src/com/cloud/storage/download/DownloadErrorState.java b/server/src/main/java/com/cloud/storage/download/DownloadErrorState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadErrorState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadErrorState.java
diff --git a/server/src/com/cloud/storage/download/DownloadInProgressState.java b/server/src/main/java/com/cloud/storage/download/DownloadInProgressState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadInProgressState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadInProgressState.java
diff --git a/server/src/com/cloud/storage/download/DownloadInactiveState.java b/server/src/main/java/com/cloud/storage/download/DownloadInactiveState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadInactiveState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadInactiveState.java
diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/main/java/com/cloud/storage/download/DownloadListener.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadListener.java
rename to server/src/main/java/com/cloud/storage/download/DownloadListener.java
diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/main/java/com/cloud/storage/download/DownloadMonitor.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadMonitor.java
rename to server/src/main/java/com/cloud/storage/download/DownloadMonitor.java
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/main/java/com/cloud/storage/download/DownloadMonitorImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadMonitorImpl.java
rename to server/src/main/java/com/cloud/storage/download/DownloadMonitorImpl.java
diff --git a/server/src/com/cloud/storage/download/DownloadState.java b/server/src/main/java/com/cloud/storage/download/DownloadState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/DownloadState.java
rename to server/src/main/java/com/cloud/storage/download/DownloadState.java
diff --git a/server/src/com/cloud/storage/download/NotDownloadedState.java b/server/src/main/java/com/cloud/storage/download/NotDownloadedState.java
similarity index 100%
rename from server/src/com/cloud/storage/download/NotDownloadedState.java
rename to server/src/main/java/com/cloud/storage/download/NotDownloadedState.java
diff --git a/server/src/com/cloud/storage/listener/SnapshotStateListener.java b/server/src/main/java/com/cloud/storage/listener/SnapshotStateListener.java
similarity index 100%
rename from server/src/com/cloud/storage/listener/SnapshotStateListener.java
rename to server/src/main/java/com/cloud/storage/listener/SnapshotStateListener.java
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java
similarity index 100%
rename from server/src/com/cloud/storage/listener/StoragePoolMonitor.java
rename to server/src/main/java/com/cloud/storage/listener/StoragePoolMonitor.java
diff --git a/server/src/com/cloud/storage/listener/StorageSyncListener.java b/server/src/main/java/com/cloud/storage/listener/StorageSyncListener.java
similarity index 100%
rename from server/src/com/cloud/storage/listener/StorageSyncListener.java
rename to server/src/main/java/com/cloud/storage/listener/StorageSyncListener.java
diff --git a/server/src/com/cloud/storage/listener/VolumeStateListener.java b/server/src/main/java/com/cloud/storage/listener/VolumeStateListener.java
similarity index 100%
rename from server/src/com/cloud/storage/listener/VolumeStateListener.java
rename to server/src/main/java/com/cloud/storage/listener/VolumeStateListener.java
diff --git a/server/src/com/cloud/storage/monitor/StorageHostMonitor.java b/server/src/main/java/com/cloud/storage/monitor/StorageHostMonitor.java
similarity index 100%
rename from server/src/com/cloud/storage/monitor/StorageHostMonitor.java
rename to server/src/main/java/com/cloud/storage/monitor/StorageHostMonitor.java
diff --git a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java b/server/src/main/java/com/cloud/storage/resource/DummySecondaryStorageResource.java
similarity index 100%
rename from server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java
rename to server/src/main/java/com/cloud/storage/resource/DummySecondaryStorageResource.java
diff --git a/server/src/com/cloud/storage/secondary/SecStorageVmAlertEventArgs.java b/server/src/main/java/com/cloud/storage/secondary/SecStorageVmAlertEventArgs.java
similarity index 100%
rename from server/src/com/cloud/storage/secondary/SecStorageVmAlertEventArgs.java
rename to server/src/main/java/com/cloud/storage/secondary/SecStorageVmAlertEventArgs.java
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/main/java/com/cloud/storage/secondary/SecondaryStorageListener.java
similarity index 100%
rename from server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
rename to server/src/main/java/com/cloud/storage/secondary/SecondaryStorageListener.java
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmAllocator.java b/server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmAllocator.java
similarity index 100%
rename from server/src/com/cloud/storage/secondary/SecondaryStorageVmAllocator.java
rename to server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmAllocator.java
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmDefaultAllocator.java b/server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmDefaultAllocator.java
similarity index 100%
rename from server/src/com/cloud/storage/secondary/SecondaryStorageVmDefaultAllocator.java
rename to server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmDefaultAllocator.java
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmManager.java
similarity index 100%
rename from server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java
rename to server/src/main/java/com/cloud/storage/secondary/SecondaryStorageVmManager.java
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java
similarity index 100%
rename from server/src/com/cloud/storage/snapshot/SnapshotManager.java
rename to server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java
diff --git a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
new file mode 100755
index 0000000..ee65486
--- /dev/null
+++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -0,0 +1,1458 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.snapshot;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.DeleteSnapshotsDirCommand;
+import com.cloud.alert.AlertManager;
+import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
+import com.cloud.api.query.MutualExclusiveIdsManagerBase;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ResourceTag.ResourceObjectType;
+import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Type;
+import com.cloud.storage.SnapshotPolicyVO;
+import com.cloud.storage.SnapshotScheduleVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.SnapshotPolicyDao;
+import com.cloud.storage.dao.SnapshotScheduleDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.DateUtil.IntervalType;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
+import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+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.StorageStrategyFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implements SnapshotManager, SnapshotApiService, Configurable {
+    private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class);
+    @Inject
+    VMTemplateDao _templateDao;
+    @Inject
+    UserVmDao _vmDao;
+    @Inject
+    VolumeDao _volsDao;
+    @Inject
+    AccountDao _accountDao;
+    @Inject
+    SnapshotDao _snapshotDao;
+    @Inject
+    SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    SnapshotPolicyDao _snapshotPolicyDao = null;
+    @Inject
+    SnapshotScheduleDao _snapshotScheduleDao;
+    @Inject
+    DomainDao _domainDao;
+    @Inject
+    StorageManager _storageMgr;
+    @Inject
+    SnapshotScheduler _snapSchedMgr;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    AlertManager _alertMgr;
+    @Inject
+    ClusterDao _clusterDao;
+    @Inject
+    ResourceLimitService _resourceLimitMgr;
+    @Inject
+    DomainManager _domainMgr;
+    @Inject
+    ResourceTagDao _resourceTagDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    DataStoreManager dataStoreMgr;
+    @Inject
+    SnapshotService snapshotSrv;
+    @Inject
+    VolumeDataFactory volFactory;
+    @Inject
+    SnapshotDataFactory snapshotFactory;
+    @Inject
+    EndPointSelector _epSelector;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    StorageStrategyFactory _storageStrategyFactory;
+
+    private int _totalRetries;
+    private int _pauseInterval;
+    private int snapshotBackupRetries, snapshotBackupRetryInterval;
+
+    private ScheduledExecutorService backupSnapshotExecutor;
+
+    @Override
+    public String getConfigComponentName() {
+        return SnapshotManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {BackupRetryAttempts, BackupRetryInterval, SnapshotHourlyMax, SnapshotDailyMax, SnapshotMonthlyMax, SnapshotWeeklyMax, usageSnapshotSelection,
+                BackupSnapshotAfterTakingSnapshot};
+    }
+
+    @Override
+    public Answer sendToPool(Volume vol, Command cmd) {
+        StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(vol.getPoolId());
+        long[] hostIdsToTryFirst = null;
+
+        Long vmHostId = getHostIdForSnapshotOperation(vol);
+
+        if (vmHostId != null) {
+            hostIdsToTryFirst = new long[] {vmHostId};
+        }
+
+        List<Long> hostIdsToAvoid = new ArrayList<Long>();
+        for (int retry = _totalRetries; retry >= 0; retry--) {
+            try {
+                Pair<Long, Answer> result = _storageMgr.sendToPool(pool, hostIdsToTryFirst, hostIdsToAvoid, cmd);
+                if (result.second().getResult()) {
+                    return result.second();
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("The result for " + cmd.getClass().getName() + " is " + result.second().getDetails() + " through " + result.first());
+                }
+                hostIdsToAvoid.add(result.first());
+            } catch (StorageUnavailableException e1) {
+                s_logger.warn("Storage unavailable ", e1);
+                return null;
+            }
+
+            try {
+                Thread.sleep(_pauseInterval * 1000);
+            } catch (InterruptedException e) {
+                s_logger.debug("[ignored] interupted while retry cmd.");
+            }
+
+            s_logger.debug("Retrying...");
+        }
+
+        s_logger.warn("After " + _totalRetries + " retries, the command " + cmd.getClass().getName() + " did not succeed.");
+
+        return null;
+    }
+
+    @Override
+    public Long getHostIdForSnapshotOperation(Volume vol) {
+        VMInstanceVO vm = _vmDao.findById(vol.getInstanceId());
+        if (vm != null) {
+            if (vm.getHostId() != null) {
+                return vm.getHostId();
+            } else if (vm.getLastHostId() != null) {
+                return vm.getLastHostId();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Snapshot revertSnapshot(Long snapshotId) {
+        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+        if (snapshot == null) {
+            throw new InvalidParameterValueException("No such snapshot");
+        }
+
+        VolumeVO volume = _volsDao.findById(snapshot.getVolumeId());
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("The volume is not in Ready state.");
+        }
+
+        Long instanceId = volume.getInstanceId();
+
+        // If this volume is attached to an VM, then the VM needs to be in the stopped state
+        // in order to revert the volume
+        if (instanceId != null) {
+            UserVmVO vm = _vmDao.findById(instanceId);
+            if (vm.getState() != State.Stopped && vm.getState() != State.Shutdowned) {
+                throw new InvalidParameterValueException("The VM the specified disk is attached to is not in the shutdown state.");
+            }
+            // If target VM has associated VM snapshots then don't allow to revert from snapshot
+            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(instanceId);
+            if (vmSnapshots.size() > 0) {
+                throw new InvalidParameterValueException("Unable to revert snapshot for VM, please remove VM snapshots before reverting VM from snapshot");
+            }
+        }
+
+        DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, dataStoreMgr);
+
+        SnapshotInfo snapshotInfo = snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
+        if (snapshotInfo == null) {
+            throw new CloudRuntimeException("snapshot:" + snapshotId + " not exist in data store");
+        }
+
+        SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.REVERT);
+
+        if (snapshotStrategy == null) {
+            s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
+            return null;
+        }
+
+        boolean result = snapshotStrategy.revertSnapshot(snapshotInfo);
+        if (result) {
+            // update volume size and primary storage count
+            _resourceLimitMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize() - snapshot.getSize()));
+            volume.setSize(snapshot.getSize());
+            _volsDao.update(volume.getId(), volume);
+            return snapshotInfo;
+        }
+        return null;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_POLICY_UPDATE, eventDescription = "updating snapshot policy", async = true)
+    public SnapshotPolicy updateSnapshotPolicy(UpdateSnapshotPolicyCmd cmd) {
+
+        Long id = cmd.getId();
+        String customUUID = cmd.getCustomId();
+        Boolean display = cmd.getDisplay();
+
+        SnapshotPolicyVO policyVO = _snapshotPolicyDao.findById(id);
+        if (display != null) {
+            boolean previousDisplay = policyVO.isDisplay();
+            policyVO.setDisplay(display);
+            _snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policyVO, previousDisplay);
+        }
+
+        if (customUUID != null)
+            policyVO.setUuid(customUUID);
+
+        _snapshotPolicyDao.update(id, policyVO);
+
+        return policyVO;
+
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "creating snapshot", async = true)
+    public Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner) {
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("No such volume exist");
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("Volume is not in ready state");
+        }
+
+        // does the caller have the authority to act on this volume
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+
+        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
+        if (snapshot == null) {
+            s_logger.debug("Failed to create snapshot");
+            throw new CloudRuntimeException("Failed to create snapshot");
+        }
+        try {
+            postCreateSnapshot(volumeId, snapshot.getId(), policyId);
+            //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event
+            SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId());
+            if (freshSnapshot != null) {
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
+                        volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
+            }
+            _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
+
+        } catch (Exception e) {
+            s_logger.debug("Failed to create snapshot", e);
+            throw new CloudRuntimeException("Failed to create snapshot", e);
+        }
+
+        return snapshot;
+    }
+
+    @Override
+    public Snapshot archiveSnapshot(Long snapshotId) {
+        SnapshotInfo snapshotOnPrimary = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
+
+        if (snapshotOnPrimary == null || !snapshotOnPrimary.getStatus().equals(ObjectInDataStoreStateMachine.State.Ready)) {
+            throw new CloudRuntimeException("Can only archive snapshots present on primary storage. " + "Cannot find snapshot " + snapshotId + " on primary storage");
+        }
+
+        SnapshotInfo snapshotOnSecondary = snapshotSrv.backupSnapshot(snapshotOnPrimary);
+        SnapshotVO snapshotVO = _snapshotDao.findById(snapshotOnSecondary.getId());
+        snapshotVO.setLocationType(Snapshot.LocationType.SECONDARY);
+        _snapshotDao.persist(snapshotVO);
+
+        try {
+            snapshotSrv.deleteSnapshot(snapshotOnPrimary);
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Snapshot archived to Secondary Storage but there was an error deleting "
+                    + " the snapshot on Primary Storage. Please manually delete the primary snapshot " + snapshotId, e);
+        }
+
+        return snapshotOnSecondary;
+    }
+
+    @Override
+    public Snapshot backupSnapshot(Long snapshotId) {
+        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image);
+        if (snapshot != null) {
+            throw new CloudRuntimeException("Already in the backup snapshot:" + snapshotId);
+        }
+
+        return snapshotSrv.backupSnapshot(snapshot);
+    }
+
+    @Override
+    public Snapshot backupSnapshotFromVmSnapshot(Long snapshotId, Long vmId, Long volumeId, Long vmSnapshotId) {
+        VMInstanceVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
+        }
+        if (!HypervisorType.KVM.equals(vm.getHypervisorType())) {
+            throw new InvalidParameterValueException("Unsupported hypervisor type " + vm.getHypervisorType() + ". This supports KVM only");
+        }
+
+        VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
+        if (vmSnapshot == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to vmSnapshot:" + vmSnapshotId + " doesn't exist");
+        }
+        // check vmsnapshot permissions
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, vmSnapshot);
+
+        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+        if (snapshot == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to snapshot:" + snapshotId + " doesn't exist");
+        }
+
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
+        }
+
+        if (volume.getState() != Volume.State.Ready) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        DataStore store = volume.getDataStore();
+        SnapshotDataStoreVO parentSnapshotDataStoreVO = _snapshotStoreDao.findParent(store.getRole(), store.getId(), volumeId);
+        if (parentSnapshotDataStoreVO != null) {
+            //Double check the snapshot is removed or not
+            SnapshotVO parentSnap = _snapshotDao.findById(parentSnapshotDataStoreVO.getSnapshotId());
+            if (parentSnap != null && parentSnapshotDataStoreVO.getInstallPath() != null && parentSnapshotDataStoreVO.getInstallPath().equals(vmSnapshot.getName())) {
+                throw new InvalidParameterValueException("Creating snapshot failed due to snapshot : " + parentSnap.getUuid() + " is created from the same vm snapshot");
+            }
+        }
+        SnapshotInfo snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
+        snapshotInfo = (SnapshotInfo)store.create(snapshotInfo);
+        SnapshotDataStoreVO snapshotOnPrimaryStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), store.getRole());
+        snapshotOnPrimaryStore.setState(ObjectInDataStoreStateMachine.State.Ready);
+        snapshotOnPrimaryStore.setInstallPath(vmSnapshot.getName());
+        _snapshotStoreDao.update(snapshotOnPrimaryStore.getId(), snapshotOnPrimaryStore);
+        snapshot.setState(Snapshot.State.CreatedOnPrimary);
+        _snapshotDao.update(snapshot.getId(), snapshot);
+
+        snapshotInfo = this.snapshotFactory.getSnapshot(snapshotId, store);
+
+        Long snapshotOwnerId = vm.getAccountId();
+
+        try {
+            SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
+            if (snapshotStrategy == null) {
+                throw new CloudRuntimeException("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
+            }
+            snapshotInfo = snapshotStrategy.backupSnapshot(snapshotInfo);
+
+        } catch (Exception e) {
+            s_logger.debug("Failed to backup snapshot from vm snapshot", e);
+            _resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.snapshot);
+            _resourceLimitMgr.decrementResourceCount(snapshotOwnerId, ResourceType.secondary_storage, new Long(volume.getSize()));
+            throw new CloudRuntimeException("Failed to backup snapshot from vm snapshot", e);
+        }
+        return snapshotInfo;
+    }
+
+    @Override
+    public SnapshotVO getParentSnapshot(VolumeInfo volume) {
+        long preId = _snapshotDao.getLastSnapshot(volume.getId(), DataStoreRole.Primary);
+
+        SnapshotVO preSnapshotVO = null;
+        if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) {
+            preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId);
+        }
+
+        return preSnapshotVO;
+    }
+
+    private Long getSnapshotUserId() {
+        Long userId = CallContext.current().getCallingUserId();
+        if (userId == null) {
+            return User.UID_SYSTEM;
+        }
+        return userId;
+    }
+
+    private void postCreateSnapshot(Long volumeId, Long snapshotId, Long policyId) {
+        Long userId = getSnapshotUserId();
+        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
+        if (policyId != Snapshot.MANUAL_POLICY_ID) {
+            SnapshotScheduleVO snapshotSchedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, policyId, true);
+            if (snapshotSchedule != null) {
+                snapshotSchedule.setSnapshotId(snapshotId);
+                _snapshotScheduleDao.update(snapshotSchedule.getId(), snapshotSchedule);
+            }
+        }
+
+        if (snapshot != null && snapshot.isRecursive()) {
+            postCreateRecurringSnapshotForPolicy(userId, volumeId, snapshotId, policyId);
+        }
+    }
+
+    private void postCreateRecurringSnapshotForPolicy(long userId, long volumeId, long snapshotId, long policyId) {
+        // Use count query
+        SnapshotVO spstVO = _snapshotDao.findById(snapshotId);
+        Type type = spstVO.getRecurringType();
+        int maxSnaps = type.getMax();
+
+        List<SnapshotVO> snaps = listSnapsforVolumeTypeNotDestroyed(volumeId, type);
+        SnapshotPolicyVO policy = _snapshotPolicyDao.findById(policyId);
+        if (policy != null && policy.getMaxSnaps() < maxSnaps) {
+            maxSnaps = policy.getMaxSnaps();
+        }
+        while (snaps.size() > maxSnaps && snaps.size() > 1) {
+            SnapshotVO oldestSnapshot = snaps.get(0);
+            long oldSnapId = oldestSnapshot.getId();
+            if (policy != null) {
+                s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
+            }
+            if (deleteSnapshot(oldSnapId)) {
+                //log Snapshot delete event
+                ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE,
+                        "Successfully deleted oldest snapshot: " + oldSnapId, 0);
+            }
+            snaps.remove(oldestSnapshot);
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_DELETE, eventDescription = "deleting snapshot", async = true)
+    public boolean deleteSnapshot(long snapshotId) {
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify parameters
+        SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
+
+        if (snapshotCheck == null) {
+            throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId);
+        }
+
+        if (snapshotCheck.getState() == Snapshot.State.Destroyed) {
+            throw new InvalidParameterValueException("Snapshot with id: " + snapshotId + " is already destroyed");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, snapshotCheck);
+
+        SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshotCheck, SnapshotOperation.DELETE);
+
+        if (snapshotStrategy == null) {
+            s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
+
+            return false;
+        }
+
+        DataStoreRole dataStoreRole = getDataStoreRole(snapshotCheck, _snapshotStoreDao, dataStoreMgr);
+
+        SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, dataStoreRole);
+
+        try {
+            boolean result = snapshotStrategy.deleteSnapshot(snapshotId);
+
+            if (result) {
+                if (snapshotCheck.getState() == Snapshot.State.BackedUp) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(), snapshotCheck.getDataCenterId(), snapshotId,
+                            snapshotCheck.getName(), null, null, 0L, snapshotCheck.getClass().getName(), snapshotCheck.getUuid());
+                }
+
+                if (snapshotCheck.getState() != Snapshot.State.Error && snapshotCheck.getState() != Snapshot.State.Destroyed) {
+                    _resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.snapshot);
+                }
+
+                if (snapshotCheck.getState() == Snapshot.State.BackedUp) {
+                    if (snapshotStoreRef != null) {
+                        _resourceLimitMgr.decrementResourceCount(snapshotCheck.getAccountId(), ResourceType.secondary_storage, new Long(snapshotStoreRef.getPhysicalSize()));
+                    }
+                }
+            }
+
+            return result;
+        } catch (Exception e) {
+            s_logger.debug("Failed to delete snapshot: " + snapshotCheck.getId() + ":" + e.toString());
+
+            throw new CloudRuntimeException("Failed to delete snapshot:" + e.toString());
+        }
+    }
+
+    @Override
+    public String getSecondaryStorageURL(SnapshotVO snapshot) {
+        SnapshotDataStoreVO snapshotStore = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
+        if (snapshotStore != null) {
+            DataStore store = dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image);
+            if (store != null) {
+                return store.getUri();
+            }
+        }
+        throw new CloudRuntimeException("Can not find secondary storage hosting the snapshot");
+    }
+
+    @Override
+    public Pair<List<? extends Snapshot>, Integer> listSnapshots(ListSnapshotsCmd cmd) {
+        Long volumeId = cmd.getVolumeId();
+        String name = cmd.getSnapshotName();
+        Long id = cmd.getId();
+        String keyword = cmd.getKeyword();
+        String snapshotTypeStr = cmd.getSnapshotType();
+        String intervalTypeStr = cmd.getIntervalType();
+        Map<String, String> tags = cmd.getTags();
+        Long zoneId = cmd.getZoneId();
+        Account caller = CallContext.current().getCallingAccount();
+        List<Long> permittedAccounts = new ArrayList<Long>();
+
+        // Verify parameters
+        if (volumeId != null) {
+            VolumeVO volume = _volsDao.findById(volumeId);
+            if (volume != null) {
+                _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+            }
+        }
+
+        List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
+
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(),
+                cmd.isRecursive(), null);
+        _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+
+        Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+        SearchBuilder<SnapshotVO> sb = _snapshotDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("statusNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); //exclude those Destroyed snapshot, not showing on UI
+        sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ);
+        sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
+        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
+        sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN);
+        sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ);
+        sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+
+        if (tags != null && !tags.isEmpty()) {
+            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
+            for (int count = 0; count < tags.size(); count++) {
+                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
+                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
+                tagSearch.cp();
+            }
+            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
+            sb.groupBy(sb.entity().getId());
+            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+        }
+
+        SearchCriteria<SnapshotVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sc.setParameters("statusNEQ", Snapshot.State.Destroyed);
+
+        if (volumeId != null) {
+            sc.setParameters("volumeId", volumeId);
+        }
+
+        if (tags != null && !tags.isEmpty()) {
+            int count = 0;
+            sc.setJoinParameters("tagSearch", "resourceType", ResourceObjectType.Snapshot.toString());
+            for (String key : tags.keySet()) {
+                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
+                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
+                count++;
+            }
+        }
+
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
+
+        setIdsListToSearchCriteria(sc, ids);
+
+        if (name != null) {
+            sc.setParameters("name", "%" + name + "%");
+        }
+
+        if (id != null) {
+            sc.setParameters("id", id);
+        }
+
+        if (keyword != null) {
+            SearchCriteria<SnapshotVO> ssc = _snapshotDao.createSearchCriteria();
+            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
+            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
+        }
+
+        if (snapshotTypeStr != null) {
+            Type snapshotType = SnapshotVO.getSnapshotType(snapshotTypeStr);
+            if (snapshotType == null) {
+                throw new InvalidParameterValueException("Unsupported snapshot type " + snapshotTypeStr);
+            }
+            if (snapshotType == Type.RECURRING) {
+                sc.setParameters("snapshotTypeEQ", Type.HOURLY.ordinal(), Type.DAILY.ordinal(), Type.WEEKLY.ordinal(), Type.MONTHLY.ordinal());
+            } else {
+                sc.setParameters("snapshotTypeEQ", snapshotType.ordinal());
+            }
+        } else if (intervalTypeStr != null && volumeId != null) {
+            Type type = SnapshotVO.getSnapshotType(intervalTypeStr);
+            if (type == null) {
+                throw new InvalidParameterValueException("Unsupported snapstho interval type " + intervalTypeStr);
+            }
+            sc.setParameters("snapshotTypeEQ", type.ordinal());
+        } else {
+            // Show only MANUAL and RECURRING snapshot types
+            sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal());
+        }
+
+        Pair<List<SnapshotVO>, Integer> result = _snapshotDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Snapshot>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    public boolean deleteSnapshotDirsForAccount(long accountId) {
+
+        List<VolumeVO> volumes = _volsDao.findIncludingRemovedByAccount(accountId);
+        // The above call will list only non-destroyed volumes.
+        // So call this method before marking the volumes as destroyed.
+        // i.e Call them before the VMs for those volumes are destroyed.
+        boolean success = true;
+        for (VolumeVO volume : volumes) {
+            if (volume.getPoolId() == null) {
+                continue;
+            }
+            Long volumeId = volume.getId();
+            Long dcId = volume.getDataCenterId();
+            if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty()) {
+                // This volume doesn't have any snapshots. Nothing do delete.
+                continue;
+            }
+            List<DataStore> ssHosts = dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId));
+            for (DataStore ssHost : ssHosts) {
+                String snapshotDir = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId + "/" + volumeId;
+                DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(ssHost.getTO(), snapshotDir);
+                EndPoint ep = _epSelector.select(ssHost);
+                Answer answer = null;
+                if (ep == null) {
+                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                    s_logger.error(errMsg);
+                    answer = new Answer(cmd, false, errMsg);
+                } else {
+                    answer = ep.sendMessage(cmd);
+                }
+                if ((answer != null) && answer.getResult()) {
+                    s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId);
+                } else {
+                    success = false;
+                    if (answer != null) {
+                        s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getUri());
+                        s_logger.error(answer.getDetails());
+                    }
+                }
+            }
+
+            // Either way delete the snapshots for this volume.
+            List<SnapshotVO> snapshots = listSnapsforVolume(volumeId);
+            for (SnapshotVO snapshot : snapshots) {
+                SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.DELETE);
+                if (snapshotStrategy == null) {
+                    s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshot.getId() + "'");
+                    continue;
+                }
+                SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image);
+
+                if (snapshotStrategy.deleteSnapshot(snapshot.getId())) {
+                    if (Type.MANUAL == snapshot.getRecurringType()) {
+                        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.snapshot);
+                        if (snapshotStoreRef != null) {
+                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(snapshotStoreRef.getPhysicalSize()));
+                        }
+                    }
+
+                    // Log event after successful deletion
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(),
+                            null, null, volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
+                }
+            }
+        }
+
+        // Returns true if snapshotsDir has been deleted for all volumes.
+        return success;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_POLICY_CREATE, eventDescription = "creating snapshot policy")
+    public SnapshotPolicyVO createPolicy(CreateSnapshotPolicyCmd cmd, Account policyOwner) {
+        Long volumeId = cmd.getVolumeId();
+        boolean display = cmd.isDisplay();
+        SnapshotPolicyVO policy = null;
+        VolumeVO volume = _volsDao.findById(cmd.getVolumeId());
+        if (volume == null) {
+            throw new InvalidParameterValueException("Failed to create snapshot policy, unable to find a volume with id " + volumeId);
+        }
+
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+
+        // If display is false we don't actually schedule snapshots.
+        if (volume.getState() != Volume.State.Ready && display) {
+            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
+        }
+
+        if (volume.getTemplateId() != null) {
+            VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
+            if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
+                throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
+            }
+        }
+
+        AccountVO owner = _accountDao.findById(volume.getAccountId());
+        Long instanceId = volume.getInstanceId();
+        if (instanceId != null) {
+            // It is not detached, but attached to a VM
+            if (_vmDao.findById(instanceId) == null) {
+                // It is not a UserVM but a SystemVM or DomR
+                throw new InvalidParameterValueException("Failed to create snapshot policy, snapshots of volumes attached to System or router VM are not allowed");
+            }
+        }
+        IntervalType intvType = DateUtil.IntervalType.getIntervalType(cmd.getIntervalType());
+        if (intvType == null) {
+            throw new InvalidParameterValueException("Unsupported interval type " + cmd.getIntervalType());
+        }
+        Type type = getSnapshotType(intvType);
+
+        TimeZone timeZone = TimeZone.getTimeZone(cmd.getTimezone());
+        String timezoneId = timeZone.getID();
+        if (!timezoneId.equals(cmd.getTimezone())) {
+            s_logger.warn("Using timezone: " + timezoneId + " for running this snapshot policy as an equivalent of " + cmd.getTimezone());
+        }
+        try {
+            DateUtil.getNextRunTime(intvType, cmd.getSchedule(), timezoneId, null);
+        } catch (Exception e) {
+            throw new InvalidParameterValueException("Invalid schedule: " + cmd.getSchedule() + " for interval type: " + cmd.getIntervalType());
+        }
+
+        if (cmd.getMaxSnaps() <= 0) {
+            throw new InvalidParameterValueException("maxSnaps should be greater than 0");
+        }
+
+        int intervalMaxSnaps = type.getMax();
+        if (cmd.getMaxSnaps() > intervalMaxSnaps) {
+            throw new InvalidParameterValueException("maxSnaps exceeds limit: " + intervalMaxSnaps + " for interval type: " + cmd.getIntervalType());
+        }
+
+        // Verify that max doesn't exceed domain and account snapshot limits in case display is on
+        if (display) {
+            long accountLimit = _resourceLimitMgr.findCorrectResourceLimitForAccount(owner, ResourceType.snapshot);
+            long domainLimit = _resourceLimitMgr.findCorrectResourceLimitForDomain(_domainMgr.getDomain(owner.getDomainId()), ResourceType.snapshot);
+            int max = cmd.getMaxSnaps().intValue();
+            if (!_accountMgr.isRootAdmin(owner.getId()) && ((accountLimit != -1 && max > accountLimit) || (domainLimit != -1 && max > domainLimit))) {
+                String message = "domain/account";
+                if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                    message = "domain/project";
+                }
+
+                throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the " + message + " level snapshot limit");
+            }
+        }
+
+        final GlobalLock createSnapshotPolicyLock = GlobalLock.getInternLock("createSnapshotPolicy_" + volumeId);
+        boolean isLockAcquired = createSnapshotPolicyLock.lock(5);
+        if (isLockAcquired) {
+            s_logger.debug("Acquired lock for creating snapshot policy of volume : " + volume.getName());
+            try {
+                policy = _snapshotPolicyDao.findOneByVolumeInterval(volumeId, intvType);
+                if (policy == null) {
+                    policy = new SnapshotPolicyVO(volumeId, cmd.getSchedule(), timezoneId, intvType, cmd.getMaxSnaps(), display);
+                    policy = _snapshotPolicyDao.persist(policy);
+                    _snapSchedMgr.scheduleNextSnapshotJob(policy);
+                } else {
+                    boolean previousDisplay = policy.isDisplay();
+                    policy.setSchedule(cmd.getSchedule());
+                    policy.setTimezone(timezoneId);
+                    policy.setInterval((short)intvType.ordinal());
+                    policy.setMaxSnaps(cmd.getMaxSnaps());
+                    policy.setActive(true);
+                    policy.setDisplay(display);
+                    _snapshotPolicyDao.update(policy.getId(), policy);
+                    _snapSchedMgr.scheduleOrCancelNextSnapshotJobOnDisplayChange(policy, previousDisplay);
+                }
+            } finally {
+                createSnapshotPolicyLock.unlock();
+            }
+
+            // TODO - Make createSnapshotPolicy - BaseAsyncCreate and remove this.
+            CallContext.current().putContextParameter(SnapshotPolicy.class, policy.getUuid());
+            return policy;
+        } else {
+            s_logger.warn("Unable to acquire lock for creating snapshot policy of volume : " + volume.getName());
+            return null;
+        }
+    }
+
+    protected boolean deletePolicy(long userId, Long policyId) {
+        SnapshotPolicyVO snapshotPolicy = _snapshotPolicyDao.findById(policyId);
+        _snapSchedMgr.removeSchedule(snapshotPolicy.getVolumeId(), snapshotPolicy.getId());
+        return _snapshotPolicyDao.remove(policyId);
+    }
+
+    @Override
+    public Pair<List<? extends SnapshotPolicy>, Integer> listPoliciesforVolume(ListSnapshotPoliciesCmd cmd) {
+        Long volumeId = cmd.getVolumeId();
+        boolean display = cmd.isDisplay();
+        Long id = cmd.getId();
+        Pair<List<SnapshotPolicyVO>, Integer> result = null;
+        // TODO - Have a better way of doing this.
+        if (id != null) {
+            result = _snapshotPolicyDao.listAndCountById(id, display, null);
+            if (result != null && result.first() != null && !result.first().isEmpty()) {
+                SnapshotPolicyVO snapshotPolicy = result.first().get(0);
+                volumeId = snapshotPolicy.getVolumeId();
+            }
+        }
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Unable to find a volume with id " + volumeId);
+        }
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+        if (result != null)
+            return new Pair<List<? extends SnapshotPolicy>, Integer>(result.first(), result.second());
+        result = _snapshotPolicyDao.listAndCountByVolumeId(volumeId, display);
+        return new Pair<List<? extends SnapshotPolicy>, Integer>(result.first(), result.second());
+    }
+
+    private List<SnapshotPolicyVO> listPoliciesforVolume(long volumeId) {
+        return _snapshotPolicyDao.listByVolumeId(volumeId);
+    }
+
+    private List<SnapshotVO> listSnapsforVolume(long volumeId) {
+        return _snapshotDao.listByVolumeId(volumeId);
+    }
+
+    private List<SnapshotVO> listSnapsforVolumeTypeNotDestroyed(long volumeId, Type type) {
+        return _snapshotDao.listByVolumeIdTypeNotDestroyed(volumeId, type);
+    }
+
+    @Override
+    public void deletePoliciesForVolume(Long volumeId) {
+        List<SnapshotPolicyVO> policyInstances = listPoliciesforVolume(volumeId);
+        for (SnapshotPolicyVO policyInstance : policyInstances) {
+            Long policyId = policyInstance.getId();
+            deletePolicy(1L, policyId);
+        }
+        // We also want to delete the manual snapshots scheduled for this volume
+        // We can only delete the schedules in the future, not the ones which are already executing.
+        SnapshotScheduleVO snapshotSchedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, Snapshot.MANUAL_POLICY_ID, false);
+        if (snapshotSchedule != null) {
+            _snapshotScheduleDao.expunge(snapshotSchedule.getId());
+        }
+    }
+
+    @Override
+    public List<SnapshotScheduleVO> findRecurringSnapshotSchedule(ListRecurringSnapshotScheduleCmd cmd) {
+        Long volumeId = cmd.getVolumeId();
+        Long policyId = cmd.getSnapshotPolicyId();
+        Account account = CallContext.current().getCallingAccount();
+
+        // Verify parameters
+        VolumeVO volume = _volsDao.findById(volumeId);
+        if (volume == null) {
+            throw new InvalidParameterValueException("Failed to list snapshot schedule, unable to find a volume with id " + volumeId);
+        }
+
+        if (account != null) {
+            long volAcctId = volume.getAccountId();
+            if (_accountMgr.isAdmin(account.getId())) {
+                Account userAccount = _accountDao.findById(Long.valueOf(volAcctId));
+                if (!_domainDao.isChildDomain(account.getDomainId(), userAccount.getDomainId())) {
+                    throw new PermissionDeniedException("Unable to list snapshot schedule for volume " + volumeId + ", permission denied.");
+                }
+            } else if (account.getId() != volAcctId) {
+                throw new PermissionDeniedException("Unable to list snapshot schedule, account " + account.getAccountName() + " does not own volume id " + volAcctId);
+            }
+        }
+
+        // List only future schedules, not past ones.
+        List<SnapshotScheduleVO> snapshotSchedules = new ArrayList<SnapshotScheduleVO>();
+        if (policyId == null) {
+            List<SnapshotPolicyVO> policyInstances = listPoliciesforVolume(volumeId);
+            for (SnapshotPolicyVO policyInstance : policyInstances) {
+                SnapshotScheduleVO snapshotSchedule = _snapshotScheduleDao.getCurrentSchedule(volumeId, policyInstance.getId(), false);
+                snapshotSchedules.add(snapshotSchedule);
+            }
+        } else {
+            snapshotSchedules.add(_snapshotScheduleDao.getCurrentSchedule(volumeId, policyId, false));
+        }
+        return snapshotSchedules;
+    }
+
+    private Type getSnapshotType(Long policyId) {
+        if (policyId.equals(Snapshot.MANUAL_POLICY_ID)) {
+            return Type.MANUAL;
+        } else {
+            SnapshotPolicyVO spstPolicyVO = _snapshotPolicyDao.findById(policyId);
+            IntervalType intvType = DateUtil.getIntervalType(spstPolicyVO.getInterval());
+            return getSnapshotType(intvType);
+        }
+    }
+
+    private Type getSnapshotType(IntervalType intvType) {
+        if (intvType.equals(IntervalType.HOURLY)) {
+            return Type.HOURLY;
+        } else if (intvType.equals(IntervalType.DAILY)) {
+            return Type.DAILY;
+        } else if (intvType.equals(IntervalType.WEEKLY)) {
+            return Type.WEEKLY;
+        } else if (intvType.equals(IntervalType.MONTHLY)) {
+            return Type.MONTHLY;
+        }
+        return null;
+    }
+
+    private boolean hostSupportSnapsthotForVolume(HostVO host, VolumeInfo volume) {
+        if (host.getHypervisorType() != HypervisorType.KVM) {
+            return true;
+        }
+
+        //Turn off snapshot by default for KVM if the volume attached to vm that is not in the Stopped/Destroyed state,
+        //unless it is set in the global flag
+        Long vmId = volume.getInstanceId();
+        if (vmId != null) {
+            VMInstanceVO vm = _vmDao.findById(vmId);
+            if (vm.getState() != VirtualMachine.State.Stopped && vm.getState() != VirtualMachine.State.Destroyed) {
+                boolean snapshotEnabled = Boolean.parseBoolean(_configDao.getValue("kvm.snapshot.enabled"));
+                if (!snapshotEnabled) {
+                    s_logger.debug("Snapshot is not supported on host " + host + " for the volume " + volume + " attached to the vm " + vm);
+                    return false;
+                }
+            }
+        }
+
+        // Determine host capabilities
+        String caps = host.getCapabilities();
+
+        if (caps != null) {
+            String[] tokens = caps.split(",");
+            for (String token : tokens) {
+                if (token.contains("snapshot")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean supportedByHypervisor(VolumeInfo volume) {
+        HypervisorType hypervisorType;
+        StoragePoolVO storagePool = _storagePoolDao.findById(volume.getDataStore().getId());
+        ScopeType scope = storagePool.getScope();
+        if (scope.equals(ScopeType.ZONE)) {
+            hypervisorType = storagePool.getHypervisor();
+        } else {
+            hypervisorType = volume.getHypervisorType();
+        }
+
+        if (hypervisorType.equals(HypervisorType.Ovm)) {
+            throw new InvalidParameterValueException("Ovm won't support taking snapshot");
+        }
+
+        if (hypervisorType.equals(HypervisorType.KVM)) {
+            List<HostVO> hosts = null;
+            if (scope.equals(ScopeType.CLUSTER)) {
+                ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId());
+                hosts = _resourceMgr.listAllHostsInCluster(cluster.getId());
+            } else if (scope.equals(ScopeType.ZONE)) {
+                hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(hypervisorType, volume.getDataCenterId());
+            }
+            if (hosts != null && !hosts.isEmpty()) {
+                HostVO host = hosts.get(0);
+                if (!hostSupportSnapsthotForVolume(host, volume)) {
+                    throw new CloudRuntimeException("KVM Snapshot is not supported: " + host.getId());
+                }
+            }
+        }
+
+        // if volume is attached to a vm in destroyed or expunging state; disallow
+        if (volume.getInstanceId() != null) {
+            UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
+            if (userVm != null) {
+                if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) {
+                    throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in "
+                            + userVm.getState().toString() + " state");
+                }
+
+                if (userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
+                    List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary,
+                            Snapshot.State.BackingUp);
+                    if (activeSnapshots.size() > 0) {
+                        throw new InvalidParameterValueException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
+                    }
+                }
+
+                List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), VMSnapshot.State.Creating, VMSnapshot.State.Reverting,
+                        VMSnapshot.State.Expunging);
+                if (activeVMSnapshots.size() > 0) {
+                    throw new CloudRuntimeException("There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
+                }
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    @DB
+    public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException {
+        CreateSnapshotPayload payload = (CreateSnapshotPayload)volume.getpayload();
+
+        updateSnapshotPayload(volume.getPoolId(), payload);
+
+        Long snapshotId = payload.getSnapshotId();
+        Account snapshotOwner = payload.getAccount();
+        SnapshotInfo snapshot = snapshotFactory.getSnapshot(snapshotId, volume.getDataStore());
+        snapshot.addPayload(payload);
+        try {
+            SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.TAKE);
+
+            if (snapshotStrategy == null) {
+                throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId);
+            }
+
+            SnapshotInfo snapshotOnPrimary = snapshotStrategy.takeSnapshot(snapshot);
+            boolean backupSnapToSecondary = BackupSnapshotAfterTakingSnapshot.value() == null || BackupSnapshotAfterTakingSnapshot.value();
+
+            if (backupSnapToSecondary) {
+                backupSnapshotToSecondary(payload.getAsyncBackup(), snapshotStrategy, snapshotOnPrimary);
+            } else {
+                s_logger.debug("skipping backup of snapshot [uuid=" + snapshot.getUuid() + "] to secondary due to configuration");
+                snapshotOnPrimary.markBackedUp();
+            }
+
+            try {
+                postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId());
+
+                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());
+
+                // Correct the resource count of snapshot in case of delta snapshots.
+                _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize() - snapshotStoreRef.getPhysicalSize()));
+            } catch (Exception e) {
+                s_logger.debug("post process snapshot failed", e);
+            }
+        } catch (CloudRuntimeException cre) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to create snapshot" + cre.getLocalizedMessage());
+            }
+            _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
+            _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize()));
+            throw cre;
+        } catch (Exception e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Failed to create snapshot", e);
+            }
+            _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
+            _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, new Long(volume.getSize()));
+            throw new CloudRuntimeException("Failed to create snapshot", e);
+        }
+        return snapshot;
+    }
+
+    protected void backupSnapshotToSecondary(boolean asyncBackup, SnapshotStrategy snapshotStrategy, SnapshotInfo snapshotOnPrimary) {
+        if (asyncBackup) {
+            backupSnapshotExecutor.schedule(new BackupSnapshotTask(snapshotOnPrimary, snapshotBackupRetries - 1, snapshotStrategy), 0, TimeUnit.SECONDS);
+        } else {
+            SnapshotInfo backupedSnapshot = snapshotStrategy.backupSnapshot(snapshotOnPrimary);
+            if (backupedSnapshot != null) {
+                snapshotStrategy.postSnapshotCreation(snapshotOnPrimary);
+            }
+        }
+    }
+
+    protected class BackupSnapshotTask extends ManagedContextRunnable {
+        SnapshotInfo snapshot;
+        int attempts;
+        SnapshotStrategy snapshotStrategy;
+
+        public BackupSnapshotTask(SnapshotInfo snap, int maxRetries, SnapshotStrategy strategy) {
+            snapshot = snap;
+            attempts = maxRetries;
+            snapshotStrategy = strategy;
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                s_logger.debug("Value of attempts is " + (snapshotBackupRetries - attempts));
+
+                SnapshotInfo backupedSnapshot = snapshotStrategy.backupSnapshot(snapshot);
+
+                if (backupedSnapshot != null) {
+                    snapshotStrategy.postSnapshotCreation(snapshot);
+                }
+            } catch (final Exception e) {
+                if (attempts >= 0) {
+                    s_logger.debug("Backing up of snapshot failed, for snapshot with ID " + snapshot.getSnapshotId() + ", left with " + attempts + " more attempts");
+                    backupSnapshotExecutor.schedule(new BackupSnapshotTask(snapshot, --attempts, snapshotStrategy), snapshotBackupRetryInterval, TimeUnit.SECONDS);
+                } else {
+                    s_logger.debug("Done with " + snapshotBackupRetries + " attempts in  backing up of snapshot with ID " + snapshot.getSnapshotId());
+                    snapshotSrv.cleanupOnSnapshotBackupFailure(snapshot);
+                }
+            }
+        }
+    }
+
+    private void updateSnapshotPayload(long storagePoolId, CreateSnapshotPayload payload) {
+        StoragePoolVO storagePoolVO = _storagePoolDao.findById(storagePoolId);
+
+        if (storagePoolVO.isManaged()) {
+            Snapshot.LocationType locationType = payload.getLocationType();
+
+            if (locationType == null) {
+                payload.setLocationType(Snapshot.LocationType.PRIMARY);
+            }
+        } else {
+            payload.setLocationType(null);
+        }
+    }
+
+    private static DataStoreRole getDataStoreRole(Snapshot snapshot, SnapshotDataStoreDao snapshotStoreDao, DataStoreManager dataStoreMgr) {
+        SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+        if (snapshotStore == null) {
+            return DataStoreRole.Image;
+        }
+
+        long storagePoolId = snapshotStore.getDataStoreId();
+        DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+
+        Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
+
+        if (mapCapabilities != null) {
+            String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString());
+            Boolean supportsStorageSystemSnapshots = new Boolean(value);
+
+            if (supportsStorageSystemSnapshots) {
+                return DataStoreRole.Primary;
+            }
+        }
+
+        return DataStoreRole.Image;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+        String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
+
+        Type.HOURLY.setMax(SnapshotHourlyMax.value());
+        Type.DAILY.setMax(SnapshotDailyMax.value());
+        Type.WEEKLY.setMax(SnapshotWeeklyMax.value());
+        Type.MONTHLY.setMax(SnapshotMonthlyMax.value());
+        _totalRetries = NumbersUtil.parseInt(_configDao.getValue("total.retries"), 4);
+        _pauseInterval = 2 * NumbersUtil.parseInt(_configDao.getValue("ping.interval"), 60);
+
+        snapshotBackupRetries = BackupRetryAttempts.value();
+        snapshotBackupRetryInterval = BackupRetryInterval.value();
+        backupSnapshotExecutor = Executors.newScheduledThreadPool(10, new NamedThreadFactory("BackupSnapshotTask"));
+        s_logger.info("Snapshot Manager is configured.");
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        //destroy snapshots in destroying state
+        List<SnapshotVO> snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Destroying);
+        for (SnapshotVO snapshotVO : snapshots) {
+            try {
+                if (!deleteSnapshot(snapshotVO.getId())) {
+                    s_logger.debug("Failed to delete snapshot in destroying state with id " + snapshotVO.getUuid());
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to delete snapshot in destroying state with id " + snapshotVO.getUuid());
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        backupSnapshotExecutor.shutdown();
+        return true;
+    }
+
+    @Override
+    public boolean deleteSnapshotPolicies(DeleteSnapshotPoliciesCmd cmd) {
+        Long policyId = cmd.getId();
+        List<Long> policyIds = cmd.getIds();
+        Long userId = getSnapshotUserId();
+
+        if ((policyId == null) && (policyIds == null)) {
+            throw new InvalidParameterValueException("No policy id (or list of ids) specified.");
+        }
+
+        if (policyIds == null) {
+            policyIds = new ArrayList<Long>();
+            policyIds.add(policyId);
+        } else if (policyIds.size() <= 0) {
+            // Not even sure how this is even possible
+            throw new InvalidParameterValueException("There are no policy ids");
+        }
+
+        for (Long policy : policyIds) {
+            SnapshotPolicyVO snapshotPolicyVO = _snapshotPolicyDao.findById(policy);
+            if (snapshotPolicyVO == null) {
+                throw new InvalidParameterValueException("Policy id given: " + policy + " does not exist");
+            }
+            VolumeVO volume = _volsDao.findById(snapshotPolicyVO.getVolumeId());
+            if (volume == null) {
+                throw new InvalidParameterValueException("Policy id given: " + policy + " does not belong to a valid volume");
+            }
+
+            _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
+        }
+
+        boolean success = true;
+
+        if (policyIds.contains(Snapshot.MANUAL_POLICY_ID)) {
+            throw new InvalidParameterValueException("Invalid Policy id given: " + Snapshot.MANUAL_POLICY_ID);
+        }
+
+        for (Long pId : policyIds) {
+            if (!deletePolicy(userId, pId)) {
+                success = false;
+                s_logger.warn("Failed to delete snapshot policy with Id: " + policyId);
+                return success;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public boolean canOperateOnVolume(Volume volume) {
+        List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
+        if (snapshots.size() > 0) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void cleanupSnapshotsByVolume(Long volumeId) {
+        List<SnapshotInfo> infos = snapshotFactory.getSnapshots(volumeId, DataStoreRole.Primary);
+        for (SnapshotInfo info : infos) {
+            try {
+                if (info != null) {
+                    snapshotSrv.deleteSnapshot(info);
+                }
+            } catch (CloudRuntimeException e) {
+                String msg = "Cleanup of Snapshot with uuid " + info.getUuid() + " in primary storage is failed. Ignoring";
+                s_logger.warn(msg);
+            }
+        }
+    }
+
+    @Override
+    public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+        VolumeInfo volume = volFactory.getVolume(volumeId);
+        supportedByHypervisor(volume);
+
+        // Verify permissions
+        _accountMgr.checkAccess(caller, null, true, volume);
+        Type snapshotType = getSnapshotType(policyId);
+        Account owner = _accountMgr.getAccount(volume.getAccountId());
+
+        try {
+            _resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
+            _resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize()).longValue());
+        } catch (ResourceAllocationException e) {
+            if (snapshotType != Type.MANUAL) {
+                String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
+                s_logger.warn(msg);
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, "Snapshot resource limit exceeded for account id : " + owner.getId()
+                        + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
+            }
+            throw e;
+        }
+
+        // Determine the name for this snapshot
+        // Snapshot Name: VMInstancename + volumeName + timeString
+        String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
+
+        VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId());
+        String vmDisplayName = "detached";
+        if (vmInstance != null) {
+            vmDisplayName = vmInstance.getHostName();
+        }
+        if (snapshotName == null)
+            snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString;
+
+        HypervisorType hypervisorType = HypervisorType.None;
+        StoragePoolVO storagePool = _storagePoolDao.findById(volume.getDataStore().getId());
+        if (storagePool.getScope() == ScopeType.ZONE) {
+            hypervisorType = storagePool.getHypervisor();
+
+            // at the time being, managed storage only supports XenServer, ESX(i), and KVM (i.e. not Hyper-V), so the VHD file type can be mapped to XenServer
+            if (storagePool.isManaged() && HypervisorType.Any.equals(hypervisorType)) {
+                if (ImageFormat.VHD.equals(volume.getFormat())) {
+                    hypervisorType = HypervisorType.XenServer;
+                } else if (ImageFormat.OVA.equals(volume.getFormat())) {
+                    hypervisorType = HypervisorType.VMware;
+                } else if (ImageFormat.QCOW2.equals(volume.getFormat())) {
+                    hypervisorType = HypervisorType.KVM;
+                }
+            }
+        } else {
+            hypervisorType = volume.getHypervisorType();
+        }
+
+        SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName,
+                (short)snapshotType.ordinal(), snapshotType.name(), volume.getSize(), volume.getMinIops(), volume.getMaxIops(), hypervisorType, locationType);
+
+        SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
+        if (snapshot == null) {
+            throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId());
+        }
+        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.snapshot);
+        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, new Long(volume.getSize()));
+        return snapshot;
+    }
+}
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotScheduler.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotScheduler.java
similarity index 100%
rename from server/src/com/cloud/storage/snapshot/SnapshotScheduler.java
rename to server/src/main/java/com/cloud/storage/snapshot/SnapshotScheduler.java
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
rename to server/src/main/java/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
diff --git a/server/src/com/cloud/storage/upload/NotUploadedState.java b/server/src/main/java/com/cloud/storage/upload/NotUploadedState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/NotUploadedState.java
rename to server/src/main/java/com/cloud/storage/upload/NotUploadedState.java
diff --git a/server/src/com/cloud/storage/upload/UploadAbandonedState.java b/server/src/main/java/com/cloud/storage/upload/UploadAbandonedState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadAbandonedState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadAbandonedState.java
diff --git a/server/src/com/cloud/storage/upload/UploadActiveState.java b/server/src/main/java/com/cloud/storage/upload/UploadActiveState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadActiveState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadActiveState.java
diff --git a/server/src/com/cloud/storage/upload/UploadCompleteState.java b/server/src/main/java/com/cloud/storage/upload/UploadCompleteState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadCompleteState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadCompleteState.java
diff --git a/server/src/com/cloud/storage/upload/UploadErrorState.java b/server/src/main/java/com/cloud/storage/upload/UploadErrorState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadErrorState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadErrorState.java
diff --git a/server/src/com/cloud/storage/upload/UploadInProgressState.java b/server/src/main/java/com/cloud/storage/upload/UploadInProgressState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadInProgressState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadInProgressState.java
diff --git a/server/src/com/cloud/storage/upload/UploadInactiveState.java b/server/src/main/java/com/cloud/storage/upload/UploadInactiveState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadInactiveState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadInactiveState.java
diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/main/java/com/cloud/storage/upload/UploadListener.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadListener.java
rename to server/src/main/java/com/cloud/storage/upload/UploadListener.java
diff --git a/server/src/com/cloud/storage/upload/UploadMonitor.java b/server/src/main/java/com/cloud/storage/upload/UploadMonitor.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadMonitor.java
rename to server/src/main/java/com/cloud/storage/upload/UploadMonitor.java
diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/main/java/com/cloud/storage/upload/UploadMonitorImpl.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadMonitorImpl.java
rename to server/src/main/java/com/cloud/storage/upload/UploadMonitorImpl.java
diff --git a/server/src/com/cloud/storage/upload/UploadState.java b/server/src/main/java/com/cloud/storage/upload/UploadState.java
similarity index 100%
rename from server/src/com/cloud/storage/upload/UploadState.java
rename to server/src/main/java/com/cloud/storage/upload/UploadState.java
diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/tags/TaggedResourceManagerImpl.java
rename to server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
similarity index 100%
rename from server/src/com/cloud/template/HypervisorTemplateAdapter.java
rename to server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
diff --git a/server/src/com/cloud/template/TemplateAdapter.java b/server/src/main/java/com/cloud/template/TemplateAdapter.java
similarity index 100%
rename from server/src/com/cloud/template/TemplateAdapter.java
rename to server/src/main/java/com/cloud/template/TemplateAdapter.java
diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
new file mode 100644
index 0000000..dc4074c
--- /dev/null
+++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
@@ -0,0 +1,481 @@
+// 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.template;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Grouping;
+import com.cloud.projects.ProjectManager;
+import com.cloud.server.ConfigurationServer;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.TemplateProfile;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.GuestOSHypervisorDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.EnumUtils;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
+
+public abstract class TemplateAdapterBase extends AdapterBase implements TemplateAdapter {
+    private final static Logger s_logger = Logger.getLogger(TemplateAdapterBase.class);
+    protected @Inject
+    DomainDao _domainDao;
+    protected @Inject
+    AccountDao _accountDao;
+    protected @Inject
+    ConfigurationDao _configDao;
+    protected @Inject
+    UserDao _userDao;
+    protected @Inject
+    AccountManager _accountMgr;
+    protected @Inject
+    DataCenterDao _dcDao;
+    protected @Inject
+    VMTemplateDao _tmpltDao;
+    protected @Inject
+    TemplateDataStoreDao _tmpltStoreDao;
+    protected @Inject
+    VMTemplateZoneDao _tmpltZoneDao;
+    protected @Inject
+    UsageEventDao _usageEventDao;
+    protected @Inject
+    HostDao _hostDao;
+    protected @Inject
+    UserVmDao _userVmDao;
+    protected @Inject
+    GuestOSHypervisorDao _osHyperDao;
+    protected @Inject
+    ResourceLimitService _resourceLimitMgr;
+    protected @Inject
+    ImageStoreDao _imgStoreDao;
+    @Inject
+    TemplateManager templateMgr;
+    @Inject
+    ConfigurationServer _configServer;
+    @Inject
+    ProjectManager _projectMgr;
+    @Inject
+    private TemplateDataStoreDao templateDataStoreDao;
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
+        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String accountName,
+        Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload) throws ResourceAllocationException {
+        return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId,
+            hypervisorType, chksum, bootable, null, null, details, false, null, false, TemplateType.USER, directDownload);
+    }
+
+    @Override
+    public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
+        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneIdList, HypervisorType hypervisorType, String chksum,
+        Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable,
+        TemplateType templateType, boolean directDownload) throws ResourceAllocationException {
+        //Long accountId = null;
+        // parameters verification
+
+        if (isPublic == null) {
+            isPublic = Boolean.FALSE;
+        }
+
+        if (isIso) {
+            if (bootable == null) {
+                bootable = Boolean.TRUE;
+            }
+            GuestOS noneGuestOs = ApiDBUtils.findGuestOSByDisplayName(ApiConstants.ISO_GUEST_OS_NONE);
+            if ((guestOSId == null || guestOSId == noneGuestOs.getId()) && bootable == true) {
+                throw new InvalidParameterValueException("Please pass a valid GuestOS Id");
+            }
+            if (bootable == false) {
+                guestOSId = noneGuestOs.getId(); //Guest os id of None.
+            }
+        } else {
+            if (bits == null) {
+                bits = Integer.valueOf(64);
+            }
+            if (passwordEnabled == null) {
+                passwordEnabled = false;
+            }
+            if (requiresHVM == null) {
+                requiresHVM = true;
+            }
+        }
+
+        if (isExtractable == null) {
+            isExtractable = Boolean.FALSE;
+        }
+        if (sshkeyEnabled == null) {
+            sshkeyEnabled = Boolean.FALSE;
+        }
+
+        boolean isAdmin = _accountMgr.isRootAdmin(templateOwner.getId());
+        boolean isRegionStore = false;
+        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+        if (stores != null && stores.size() > 0) {
+            isRegionStore = true;
+        }
+
+        if (!isAdmin && zoneIdList == null && !isRegionStore ) {
+            // domain admin and user should also be able to register template on a region store
+            throw new InvalidParameterValueException("Please specify a valid zone Id. Only admins can create templates in all zones.");
+        }
+
+        // check for the url format only when url is not null. url can be null incase of form based upload
+        if (url != null && url.toLowerCase().contains("file://")) {
+            throw new InvalidParameterValueException("File:// type urls are currently unsupported");
+        }
+
+        // check whether owner can create public templates
+        boolean allowPublicUserTemplates = TemplateManager.AllowPublicUserTemplates.valueIn(templateOwner.getId());
+        if (!isAdmin && !allowPublicUserTemplates && isPublic) {
+            throw new InvalidParameterValueException("Only private templates/ISO can be created.");
+        }
+
+        if (!isAdmin || featured == null) {
+            featured = Boolean.FALSE;
+        }
+
+        ImageFormat imgfmt;
+        try {
+            imgfmt = ImageFormat.valueOf(format.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            s_logger.debug("ImageFormat IllegalArgumentException: " + e.getMessage());
+            throw new IllegalArgumentException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+        }
+
+        // Check that the resource limit for templates/ISOs won't be exceeded
+        UserVO user = _userDao.findById(userId);
+        if (user == null) {
+            throw new IllegalArgumentException("Unable to find user with id " + userId);
+        }
+
+        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
+
+        // If a zoneId is specified, make sure it is valid
+        if (zoneIdList != null) {
+            for (Long zoneId :zoneIdList) {
+                DataCenterVO zone = _dcDao.findById(zoneId);
+                if (zone == null) {
+                    throw new IllegalArgumentException("Please specify a valid zone.");
+                }
+                Account caller = CallContext.current().getCallingAccount();
+                if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
+                    throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId);
+                }
+            }
+        }
+
+        List<VMTemplateVO> systemvmTmplts = _tmpltDao.listAllSystemVMTemplates();
+        for (VMTemplateVO template : systemvmTmplts) {
+            if (template.getName().equalsIgnoreCase(name) || template.getDisplayText().equalsIgnoreCase(displayText)) {
+                throw new IllegalArgumentException("Cannot use reserved names for templates");
+            }
+        }
+
+        if (hypervisorType.equals(Hypervisor.HypervisorType.XenServer)) {
+            if (details == null || !details.containsKey("hypervisortoolsversion") || details.get("hypervisortoolsversion") == null ||
+                ((String)details.get("hypervisortoolsversion")).equalsIgnoreCase("none")) {
+                String hpvs = _configDao.getValue(Config.XenServerPVdriverVersion.key());
+                if (hpvs != null) {
+                    if (details == null) {
+                        details = new HashMap<String, String>();
+                    }
+                    details.put("hypervisortoolsversion", hpvs);
+                }
+            }
+        }
+
+        Long id = _tmpltDao.getNextInSequence(Long.class, "id");
+        CallContext.current().setEventDetails("Id: " + id + " name: " + name);
+        return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, imgfmt, guestOSId, zoneIdList,
+            hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details,
+            sshkeyEnabled, null, isDynamicallyScalable, templateType, directDownload);
+
+    }
+
+    @Override
+    public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
+        //check if the caller can operate with the template owner
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType();
+
+        List<Long> zoneId = cmd.getZoneIds();
+        // ignore passed zoneId if we are using region wide image store
+        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+        if (stores != null && stores.size() > 0) {
+            zoneId = null;
+        }
+
+        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
+        if(hypervisorType == HypervisorType.None) {
+            throw new InvalidParameterValueException("Hypervisor Type: " + cmd.getHypervisor() + " is invalid. Supported Hypervisor types are "
+                    + EnumUtils.listValues(HypervisorType.values()).replace("None, ", ""));
+        }
+
+        return prepare(false, CallContext.current().getCallingUserId(), cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(),
+                cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneId, hypervisorType, cmd.getChecksum(), true,
+                cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER, cmd.isDirectDownload());
+
+    }
+
+    @Override
+    public TemplateProfile prepare(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException {
+        //check if the caller can operate with the template owner
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        boolean isRouting = (cmd.isRoutingType() == null) ? false : cmd.isRoutingType();
+
+        List<Long> zoneList = null;
+        Long zoneId = cmd.getZoneId();
+        // ignore passed zoneId if we are using region wide image store
+        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+        if (!(stores != null && stores.size() > 0)) {
+            zoneList = new ArrayList<>();
+            zoneList.add(zoneId);
+        }
+
+        HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
+        if(hypervisorType == HypervisorType.None) {
+            throw new InvalidParameterValueException("Hypervisor Type: " + cmd.getHypervisor() + " is invalid. Supported Hypervisor types are "
+                                                         + EnumUtils.listValues(HypervisorType.values()).replace("None, ", ""));
+        }
+
+        return prepare(false, CallContext.current().getCallingUserId(), cmd.getName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(),
+                       cmd.getRequiresHvm(), null, cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneList,
+                       hypervisorType, cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null,
+                       cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER, false);
+
+    }
+
+    @Override
+    public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
+        //check if the caller can operate with the template owner
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        List<Long> zoneList = null;
+        Long zoneId = cmd.getZoneId();
+        // ignore passed zoneId if we are using region wide image store
+        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+        if (CollectionUtils.isEmpty(stores) && zoneId != null && zoneId > 0L) {
+            zoneList = new ArrayList<>();
+            zoneList.add(zoneId);
+        }
+
+        return prepare(true, CallContext.current().getCallingUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, cmd.isPasswordEnabled(), true, cmd.getUrl(), cmd.isPublic(),
+            cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), zoneList, HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null,
+            owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(), TemplateType.USER, cmd.isDirectDownload());
+    }
+
+    protected VMTemplateVO persistTemplate(TemplateProfile profile, VirtualMachineTemplate.State initialState) {
+        List<Long> zoneIdList = profile.getZoneIdList();
+        VMTemplateVO template =
+            new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.isPublic(), profile.isFeatured(), profile.isExtractable(),
+                profile.getTemplateType(), profile.getUrl(), profile.isRequiresHVM(), profile.getBits(), profile.getAccountId(), profile.getCheckSum(),
+                profile.getDisplayText(), profile.isPasswordEnabled(), profile.getGuestOsId(), profile.isBootable(), profile.getHypervisorType(),
+                profile.getTemplateTag(), profile.getDetails(), profile.isSshKeyEnabled(), profile.IsDynamicallyScalable(), profile.isDirectDownload());
+        template.setState(initialState);
+
+        if (profile.isDirectDownload()) {
+            template.setSize(profile.getSize());
+        }
+
+        if (zoneIdList == null) {
+            List<DataCenterVO> dcs = _dcDao.listAll();
+
+            if (dcs.isEmpty()) {
+                throw new CloudRuntimeException("No zones are present in the system, can't add template");
+            }
+
+            template.setCrossZones(true);
+            for (DataCenterVO dc : dcs) {
+                _tmpltDao.addTemplateToZone(template, dc.getId());
+            }
+
+        } else {
+            for (Long zoneId: zoneIdList) {
+                _tmpltDao.addTemplateToZone(template, zoneId);
+            }
+        }
+        return _tmpltDao.findById(template.getId());
+    }
+
+    private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg) throws PermissionDeniedException {
+
+        if (account != null) {
+            if (!_accountMgr.isAdmin(account.getId())) {
+                if ((vmInstanceCheck != null) && (account.getId() != vmInstanceCheck.getAccountId())) {
+                    throw new PermissionDeniedException(msg + ". Permission denied.");
+                }
+
+                if ((template != null) &&
+                    (!template.isPublicTemplate() && (account.getId() != template.getAccountId()) && (template.getTemplateType() != TemplateType.PERHOST))) {
+                    //special handling for the project case
+                    Account owner = _accountMgr.getAccount(template.getAccountId());
+                    if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                        if (!_projectMgr.canAccessProjectAccount(account, owner.getId())) {
+                            throw new PermissionDeniedException(msg + ". Permission denied. The caller can't access project's template");
+                        }
+                    } else {
+                        throw new PermissionDeniedException(msg + ". Permission denied.");
+                    }
+                }
+            } else {
+                if ((vmInstanceCheck != null) && !_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
+                    throw new PermissionDeniedException(msg + ". Permission denied.");
+                }
+                // FIXME: if template/ISO owner is null we probably need to
+                // throw some kind of exception
+
+                if (template != null) {
+                    Account templateOwner = _accountDao.findById(template.getAccountId());
+                    if ((templateOwner != null) && !_domainDao.isChildDomain(account.getDomainId(), templateOwner.getDomainId())) {
+                        throw new PermissionDeniedException(msg + ". Permission denied.");
+                    }
+                }
+            }
+        }
+
+        return userId;
+    }
+
+    @Override
+    public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
+        Long templateId = cmd.getId();
+        Long userId = CallContext.current().getCallingUserId();
+        Account account = CallContext.current().getCallingAccount();
+        Long zoneId = cmd.getZoneId();
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+        }
+
+        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete template ");
+
+        UserVO user = _userDao.findById(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("Please specify a valid user.");
+        }
+
+        if (template.getFormat() == ImageFormat.ISO) {
+            throw new InvalidParameterValueException("Please specify a valid template.");
+        }
+
+        return new TemplateProfile(userId, template, zoneId);
+    }
+
+    @Override
+    public TemplateProfile prepareExtractTemplate(ExtractTemplateCmd cmd) {
+        Long templateId = cmd.getId();
+        Long userId = CallContext.current().getCallingUserId();
+        Long zoneId = cmd.getZoneId();
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+        }
+        return new TemplateProfile(userId, template, zoneId);
+    }
+
+    @Override
+    public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
+        Long templateId = cmd.getId();
+        Long userId = CallContext.current().getCallingUserId();
+        Account account = CallContext.current().getCallingAccount();
+        Long zoneId = cmd.getZoneId();
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
+        }
+
+        userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso ");
+
+        UserVO user = _userDao.findById(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("Please specify a valid user.");
+        }
+
+        if (template.getFormat() != ImageFormat.ISO) {
+            throw new InvalidParameterValueException("Please specify a valid iso.");
+        }
+
+        return new TemplateProfile(userId, template, zoneId);
+    }
+
+    @Override
+    abstract public VMTemplateVO create(TemplateProfile profile);
+
+    @Override
+    abstract public boolean delete(TemplateProfile profile);
+}
diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
new file mode 100755
index 0000000..df3b59b
--- /dev/null
+++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
@@ -0,0 +1,2184 @@
+// 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.template;
+
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.storage.ImageStoreUploadMonitorImpl;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.EncryptionUtil;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.EnumUtils;
+import com.google.common.base.Joiner;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd;
+import org.apache.cloudstack.api.response.GetUploadParamsResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+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;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CommandResult;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.ApiResponseHelper;
+import com.cloud.api.query.dao.UserVmJoinDao;
+import com.cloud.api.query.vo.UserVmJoinVO;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.UsageEventVO;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.projects.Project;
+import com.cloud.projects.ProjectManager;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.LaunchPermissionVO;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolHostVO;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.TemplateProfile;
+import com.cloud.storage.Upload;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.LaunchPermissionDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
+import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.template.TemplateAdapter.TemplateAdapterType;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService, Configurable {
+    private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
+
+    @Inject
+    private VMTemplateDao _tmpltDao;
+    @Inject
+    private TemplateDataStoreDao _tmplStoreDao;
+    @Inject
+    private VMTemplatePoolDao _tmpltPoolDao;
+    @Inject
+    private VMTemplateZoneDao _tmpltZoneDao;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+    @Inject
+    private PrimaryDataStoreDao _poolDao;
+    @Inject
+    private StoragePoolHostDao _poolHostDao;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private SnapshotDao _snapshotDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private GuestOSDao _guestOSDao;
+    @Inject
+    private StorageManager _storageMgr;
+    @Inject
+    private UsageEventDao _usageEventDao;
+    @Inject
+    private AccountService _accountService;
+    @Inject
+    private ResourceLimitService _resourceLimitMgr;
+    @Inject
+    private LaunchPermissionDao _launchPermissionDao;
+    @Inject
+    private ProjectManager _projectMgr;
+    @Inject
+    private VolumeDataFactory _volFactory;
+    @Inject
+    private TemplateDataFactory _tmplFactory;
+    @Inject
+    private SnapshotDataFactory _snapshotFactory;
+    @Inject
+    StorageStrategyFactory _storageStrategyFactory;
+    @Inject
+    private TemplateService _tmpltSvr;
+    @Inject
+    private DataStoreManager _dataStoreMgr;
+    @Inject
+    private VolumeOrchestrationService _volumeMgr;
+    @Inject
+    private EndPointSelector _epSelector;
+    @Inject
+    private UserVmJoinDao _userVmJoinDao;
+    @Inject
+    private SnapshotDataStoreDao _snapshotStoreDao;
+    @Inject
+    private ImageStoreDao _imgStoreDao;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    private VMTemplateDetailsDao _tmpltDetailsDao;
+
+    private boolean _disableExtraction = false;
+    private List<TemplateAdapter> _adapters;
+
+    ExecutorService _preloadExecutor;
+
+    @Inject
+    private StorageCacheManager cacheMgr;
+    @Inject
+    private EndPointSelector selector;
+
+
+    private TemplateAdapter getAdapter(HypervisorType type) {
+        TemplateAdapter adapter = null;
+        if (type == HypervisorType.BareMetal) {
+            adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName());
+        } else {
+            // see HypervisorTemplateAdapter
+            adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
+        }
+
+        if (adapter == null) {
+            throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
+        }
+
+        return adapter;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
+    public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException {
+        TemplateAdapter adapter = getAdapter(HypervisorType.None);
+        TemplateProfile profile = adapter.prepare(cmd);
+        VMTemplateVO template = adapter.create(profile);
+
+        if (template != null) {
+            return template;
+        } else {
+            throw new CloudRuntimeException("Failed to create ISO");
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template")
+    public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException {
+        Account account = CallContext.current().getCallingAccount();
+        if (cmd.getTemplateTag() != null) {
+            if (!_accountService.isRootAdmin(account.getId())) {
+                throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
+            }
+        }
+        if (cmd.isRoutingType() != null) {
+            if (!_accountService.isRootAdmin(account.getId())) {
+                throw new PermissionDeniedException("Parameter isrouting can only be specified by a Root Admin, permission denied");
+            }
+        }
+
+        TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
+        TemplateProfile profile = adapter.prepare(cmd);
+        VMTemplateVO template = adapter.create(profile);
+
+        if (template != null) {
+            return template;
+        } else {
+            throw new CloudRuntimeException("Failed to create a template");
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating post upload template")
+    public GetUploadParamsResponse registerTemplateForPostUpload(GetUploadParamsForTemplateCmd cmd) throws ResourceAllocationException, MalformedURLException {
+        TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
+        TemplateProfile profile = adapter.prepare(cmd);
+        List<TemplateOrVolumePostUploadCommand> payload = adapter.createTemplateForPostUpload(profile);
+
+        if(CollectionUtils.isNotEmpty(payload)) {
+            GetUploadParamsResponse response = new GetUploadParamsResponse();
+
+            /*
+             * There can be one or more commands depending on the number of secondary stores the template needs to go to. Taking the first one to do the url upload. The
+             * template will be propagated to the rest through copy by management server commands.
+             */
+            TemplateOrVolumePostUploadCommand firstCommand = payload.get(0);
+
+            String ssvmUrlDomain = _configDao.getValue(Config.SecStorageSecureCopyCert.key());
+
+            String url = ImageStoreUtil.generatePostUploadUrl(ssvmUrlDomain, firstCommand.getRemoteEndPoint(), firstCommand.getEntityUUID());
+            response.setPostURL(new URL(url));
+
+            // set the post url, this is used in the monitoring thread to determine the SSVM
+            TemplateDataStoreVO templateStore = _tmplStoreDao.findByTemplate(firstCommand.getEntityId(), DataStoreRole.getRole(firstCommand.getDataToRole()));
+            if (templateStore != null) {
+                templateStore.setExtractUrl(url);
+                _tmplStoreDao.persist(templateStore);
+            }
+
+            response.setId(UUID.fromString(firstCommand.getEntityUUID()));
+
+            int timeout = ImageStoreUploadMonitorImpl.getUploadOperationTimeout();
+            DateTime currentDateTime = new DateTime(DateTimeZone.UTC);
+            String expires = currentDateTime.plusMinutes(timeout).toString();
+            response.setTimeout(expires);
+
+            String key = _configDao.getValue(Config.SSVMPSK.key());
+            /*
+             * encoded metadata using the post upload config ssh key
+             */
+            Gson gson = new GsonBuilder().create();
+            String metadata = EncryptionUtil.encodeData(gson.toJson(firstCommand), key);
+            response.setMetadata(metadata);
+
+            /*
+             * signature calculated on the url, expiry, metadata.
+             */
+            response.setSignature(EncryptionUtil.generateSignature(metadata + url + expires, key));
+
+            return response;
+        } else {
+            throw new CloudRuntimeException("Unable to register template.");
+        }
+    }
+
+
+    @Override
+    public DataStore getImageStore(String storeUuid, Long zoneId) {
+        DataStore imageStore = null;
+        if (storeUuid != null) {
+            imageStore = _dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
+        } else {
+            imageStore = _dataStoreMgr.getImageStore(zoneId);
+            if (imageStore == null) {
+                throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
+            }
+        }
+
+        return imageStore;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true)
+    public String extract(ExtractIsoCmd cmd) {
+        Account account = CallContext.current().getCallingAccount();
+        Long templateId = cmd.getId();
+        Long zoneId = cmd.getZoneId();
+        String url = cmd.getUrl();
+        String mode = cmd.getMode();
+        Long eventId = cmd.getStartEventId();
+
+        return extract(account, templateId, url, zoneId, mode, eventId, true);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true)
+    public String extract(ExtractTemplateCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long templateId = cmd.getId();
+        Long zoneId = cmd.getZoneId();
+        String url = cmd.getUrl();
+        String mode = cmd.getMode();
+        Long eventId = cmd.getStartEventId();
+
+        VirtualMachineTemplate template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+        }
+
+        return extract(caller, templateId, url, zoneId, mode, eventId, false);
+    }
+
+    @Override
+    public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId, Long storageId) {
+
+        VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
+        if (vmTemplate == null) {
+            throw new InvalidParameterValueException("Unable to find template id=" + templateId);
+        }
+
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, vmTemplate);
+
+        if (storageId != null) {
+            StoragePoolVO pool = _poolDao.findById(storageId);
+            if (pool != null) {
+                if (pool.getStatus() == StoragePoolStatus.Up && pool.getDataCenterId() == zoneId) {
+                    prepareTemplateInOneStoragePool(vmTemplate, pool);
+                } else {
+                    s_logger.warn("Skip loading template " + vmTemplate.getId() + " into primary storage " + pool.getId() + " as either the pool zone "
+                            + pool.getDataCenterId() + " is different from the requested zone " + zoneId + " or the pool is currently not available.");
+                }
+            }
+        } else {
+            prepareTemplateInAllStoragePools(vmTemplate, zoneId);
+        }
+        return vmTemplate;
+    }
+
+    private String extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO) {
+        String desc = Upload.Type.TEMPLATE.toString();
+        if (isISO) {
+            desc = Upload.Type.ISO.toString();
+        }
+        if (!_accountMgr.isRootAdmin(caller.getId()) && _disableExtraction) {
+            throw new PermissionDeniedException("Extraction has been disabled by admin");
+        }
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null || template.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find " + desc + " with id " + templateId);
+        }
+
+        if (template.getTemplateType() == Storage.TemplateType.SYSTEM) {
+            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
+        } else if (template.getTemplateType() == Storage.TemplateType.PERHOST) {
+            throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
+        }
+
+        if (isISO) {
+            if (template.getFormat() != ImageFormat.ISO) {
+                throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
+            }
+        } else {
+            if (template.getFormat() == ImageFormat.ISO) {
+                throw new InvalidParameterValueException("Unsupported format, could not extract the template");
+            }
+        }
+
+        if (zoneId != null && _dcDao.findById(zoneId) == null) {
+            throw new IllegalArgumentException("Please specify a valid zone.");
+        }
+
+        if (!_accountMgr.isRootAdmin(caller.getId()) && !template.isExtractable()) {
+            throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
+
+        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
+
+        TemplateDataStoreVO tmpltStoreRef = null;
+        ImageStoreEntity tmpltStore = null;
+        if (ssStores != null) {
+            for (DataStore store : ssStores) {
+                tmpltStoreRef = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
+                if (tmpltStoreRef != null) {
+                    if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+                        tmpltStore = (ImageStoreEntity)store;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (tmpltStore == null) {
+            throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
+        }
+
+        // Check if the url already exists
+        if(tmpltStoreRef.getExtractUrl() != null){
+            return tmpltStoreRef.getExtractUrl();
+        }
+
+        // Handle NFS to S3 object store migration case, we trigger template sync from NFS to S3 during extract template or copy template
+        _tmpltSvr.syncTemplateToRegionStore(templateId, tmpltStore);
+
+        TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, tmpltStore);
+        String extractUrl = tmpltStore.createEntityExtractUrl(templateObject.getInstallPath(), template.getFormat(), templateObject);
+        tmpltStoreRef.setExtractUrl(extractUrl);
+        tmpltStoreRef.setExtractUrlCreated(DateUtil.now());
+        _tmplStoreDao.update(tmpltStoreRef.getId(), tmpltStoreRef);
+        return extractUrl;
+    }
+
+    @Override
+    public void prepareIsoForVmProfile(VirtualMachineProfile profile, DeployDestination dest) {
+        UserVmVO vm = _userVmDao.findById(profile.getId());
+        if (vm.getIsoId() != null) {
+            Map<Volume, StoragePool> storageForDisks = dest.getStorageForDisks();
+            Long poolId = null;
+            if (MapUtils.isNotEmpty(storageForDisks)) {
+                for (StoragePool storagePool : storageForDisks.values()) {
+                    if (poolId != null && storagePool.getId() != poolId) {
+                        throw new CloudRuntimeException("Cannot determine where to download iso");
+                    }
+                    poolId = storagePool.getId();
+                }
+            }
+            TemplateInfo template = prepareIso(vm.getIsoId(), vm.getDataCenterId(), dest.getHost().getId(), poolId);
+            if (template == null){
+                s_logger.error("Failed to prepare ISO on secondary or cache storage");
+                throw new CloudRuntimeException("Failed to prepare ISO on secondary or cache storage");
+            }
+            if (template.isBootable()) {
+                profile.setBootLoaderType(BootloaderType.CD);
+            }
+
+            GuestOSVO guestOS = _guestOSDao.findById(template.getGuestOSId());
+            String displayName = null;
+            if (guestOS != null) {
+                displayName = guestOS.getDisplayName();
+            }
+
+            TemplateObjectTO iso = (TemplateObjectTO)template.getTO();
+            iso.setDirectDownload(template.isDirectDownload());
+            iso.setGuestOsType(displayName);
+            DiskTO disk = new DiskTO(iso, 3L, null, Volume.Type.ISO);
+            profile.addDisk(disk);
+        } else {
+            TemplateObjectTO iso = new TemplateObjectTO();
+            iso.setFormat(ImageFormat.ISO);
+            DiskTO disk = new DiskTO(iso, 3L, null, Volume.Type.ISO);
+            profile.addDisk(disk);
+        }
+    }
+
+    private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) {
+        s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
+        _preloadExecutor.execute(new ManagedContextRunnable() {
+            @Override
+            protected void runInContext() {
+                try {
+                    reallyRun();
+                } catch (Throwable e) {
+                    s_logger.warn("Unexpected exception ", e);
+                }
+            }
+
+            private void reallyRun() {
+                s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
+                StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId());
+                prepareTemplateForCreate(template, pol);
+                s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId());
+            }
+        });
+    }
+
+    public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
+        List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
+        for (final StoragePoolVO pool : pools) {
+            if (pool.getDataCenterId() == zoneId) {
+                prepareTemplateInOneStoragePool(template, pool);
+            } else {
+                s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() +
+                        " is different from the requested zone " + zoneId);
+            }
+        }
+    }
+
+    @Override
+    @DB
+    public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
+        VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
+
+        long poolId = pool.getId();
+        long templateId = template.getId();
+        VMTemplateStoragePoolVO templateStoragePoolRef = null;
+        TemplateDataStoreVO templateStoreRef = null;
+
+        templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
+        if (templateStoragePoolRef != null) {
+            templateStoragePoolRef.setMarkedForGC(false);
+            _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
+
+            if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
+                }
+
+                return templateStoragePoolRef;
+            }
+        }
+
+        templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        if (templateStoreRef == null) {
+            s_logger.error("Unable to find a secondary storage host who has completely downloaded the template.");
+            return null;
+        }
+
+        List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
+        if (vos == null || vos.isEmpty()) {
+            throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
+        }
+
+        if (templateStoragePoolRef == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
+            }
+            DataStore srcSecStore = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
+            TemplateInfo srcTemplate = _tmplFactory.getTemplate(templateId, srcSecStore);
+
+            AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool);
+            try {
+                TemplateApiResult result = future.get();
+                if (result.isFailed()) {
+                    s_logger.debug("prepare template failed:" + result.getResult());
+                    return null;
+                }
+
+                return _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
+            } catch (Exception ex) {
+                s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage");
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public String getChecksum(DataStore store, String templatePath, String algorithm) {
+        EndPoint ep = _epSelector.select(store);
+        ComputeChecksumCommand cmd = new ComputeChecksumCommand(store.getTO(), templatePath, algorithm);
+        Answer answer = null;
+        if (ep == null) {
+            String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+            s_logger.error(errMsg);
+            answer = new Answer(cmd, false, errMsg);
+        } else {
+            answer = ep.sendMessage(cmd);
+        }
+        if (answer != null && answer.getResult()) {
+            return answer.getDetails();
+        }
+        return null;
+    }
+
+    @Override
+    @DB
+    public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) {
+        // have to use the same lock that prepareTemplateForCreate use to
+        // maintain state consistency
+        VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200);
+
+        if (templateStoragePoolRef == null) {
+            s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId);
+            return false;
+        }
+
+        try {
+            templateStoragePoolRef.setTemplateSize(0);
+            templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
+
+            _tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef);
+        } finally {
+            _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
+        }
+
+        return true;
+    }
+
+    @Override
+    @DB
+    public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
+        long tmpltId = template.getId();
+        long dstZoneId = dstZone.getId();
+        // find all eligible image stores for the destination zone
+        List<DataStore> dstSecStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId));
+        if (dstSecStores == null || dstSecStores.isEmpty()) {
+            throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId());
+        }
+        AccountVO account = _accountDao.findById(template.getAccountId());
+        // find the size of the template to be copied
+        TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
+
+        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
+        _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()).longValue());
+
+        // Event details
+        String copyEventType;
+        if (template.getFormat().equals(ImageFormat.ISO)) {
+            copyEventType = EventTypes.EVENT_ISO_COPY;
+        } else {
+            copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
+        }
+
+        TemplateInfo srcTemplate = _tmplFactory.getTemplate(template.getId(), srcSecStore);
+        // Copy will just find one eligible image store for the destination zone
+        // and copy template there, not propagate to all image stores
+        // for that zone
+        for (DataStore dstSecStore : dstSecStores) {
+            TemplateDataStoreVO dstTmpltStore = _tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId);
+            if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) {
+                return true; // already downloaded on this image store
+            }
+            if (dstTmpltStore != null && dstTmpltStore.getDownloadState() != Status.DOWNLOAD_IN_PROGRESS) {
+                _tmplStoreDao.removeByTemplateStore(tmpltId, dstSecStore.getId());
+            }
+
+            AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
+            try {
+                TemplateApiResult result = future.get();
+                if (result.isFailed()) {
+                    s_logger.debug("copy template failed for image store " + dstSecStore.getName() + ":" + result.getResult());
+                    continue; // try next image store
+                }
+
+                _tmpltDao.addTemplateToZone(template, dstZoneId);
+
+                if (account.getId() != Account.ACCOUNT_ID_SYSTEM) {
+                    UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getPhysicalSize(),
+                            srcTmpltStore.getSize(), template.getClass().getName(), template.getUuid());
+                }
+
+                // Copy every Datadisk template that belongs to the template to Destination zone
+                List<VMTemplateVO> dataDiskTemplates = _tmpltDao.listByParentTemplatetId(template.getId());
+                if (dataDiskTemplates != null && !dataDiskTemplates.isEmpty()) {
+                    for (VMTemplateVO dataDiskTemplate : dataDiskTemplates) {
+                        s_logger.debug("Copying " + dataDiskTemplates.size() + " for source template " + template.getId() + ". Copy all Datadisk templates to destination datastore " + dstSecStore.getName());
+                        TemplateInfo srcDataDiskTemplate = _tmplFactory.getTemplate(dataDiskTemplate.getId(), srcSecStore);
+                        AsyncCallFuture<TemplateApiResult> dataDiskCopyFuture = _tmpltSvr.copyTemplate(srcDataDiskTemplate, dstSecStore);
+                        try {
+                            TemplateApiResult dataDiskCopyResult = dataDiskCopyFuture.get();
+                            if (dataDiskCopyResult.isFailed()) {
+                                s_logger.error("Copy of datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName()
+                                        + " failed with error: " + dataDiskCopyResult.getResult() + " , will try copying the next one");
+                                continue; // Continue to copy next Datadisk template
+                            }
+                            _tmpltDao.addTemplateToZone(dataDiskTemplate, dstZoneId);
+                            _resourceLimitMgr.incrementResourceCount(dataDiskTemplate.getAccountId(), ResourceType.secondary_storage, dataDiskTemplate.getSize());
+                        } catch (Exception ex) {
+                            s_logger.error("Failed to copy datadisk template: " + srcDataDiskTemplate.getId() + " to image store: " + dstSecStore.getName()
+                                    + " , will try copying the next one");
+                        }
+                    }
+                }
+            } catch (Exception ex) {
+                s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one");
+            }
+        }
+        return true;
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
+    public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
+        Long templateId = cmd.getId();
+        Long userId = CallContext.current().getCallingUserId();
+        Long sourceZoneId = cmd.getSourceZoneId();
+        List<Long> destZoneIds = cmd.getDestinationZoneIds();
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify parameters
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null || template.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find template with id");
+        }
+
+        // Verify template is not Datadisk template
+        if (template.getTemplateType().equals(TemplateType.DATADISK)) {
+            throw new InvalidParameterValueException("Template " + template.getId() + " is of type Datadisk. Cannot copy Datadisk templates.");
+        }
+
+        if (sourceZoneId != null) {
+            if (destZoneIds!= null && destZoneIds.contains(sourceZoneId)) {
+                throw new InvalidParameterValueException("Please specify different source and destination zones.");
+            }
+
+            DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
+            if (sourceZone == null) {
+                throw new InvalidParameterValueException("Please specify a valid source zone.");
+            }
+        }
+
+        Map<Long, DataCenterVO> dataCenterVOs = new HashMap();
+
+        for (Long destZoneId: destZoneIds) {
+            DataCenterVO dstZone = _dcDao.findById(destZoneId);
+            if (dstZone == null) {
+                throw new InvalidParameterValueException("Please specify a valid destination zone.");
+            }
+            dataCenterVOs.put(destZoneId, dstZone);
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
+
+        List<String> failedZones = new ArrayList<>();
+
+        boolean success = false;
+        if (template.getHypervisorType() == HypervisorType.BareMetal) {
+            if (template.isCrossZones()) {
+                s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
+                return template;
+            }
+            for (Long destZoneId: destZoneIds) {
+                if (!addTemplateToZone(template, destZoneId, sourceZoneId)) {
+                    failedZones.add(dataCenterVOs.get(destZoneId).getName());
+                }
+            }
+        } else {
+            DataStore srcSecStore = null;
+            if (sourceZoneId != null) {
+                // template is on zone-wide secondary storage
+                srcSecStore = getImageStore(sourceZoneId, templateId);
+            } else {
+                // template is on region store
+                srcSecStore = getImageStore(templateId);
+            }
+
+            if (srcSecStore == null) {
+                throw new InvalidParameterValueException("There is no template " + templateId + " ready on image store.");
+            }
+
+            if (template.isCrossZones()) {
+                // sync template from cache store to region store if it is not there, for cases where we are going to migrate existing NFS to S3.
+                _tmpltSvr.syncTemplateToRegionStore(templateId, srcSecStore);
+                s_logger.debug("Template " + templateId + " is cross-zone, don't need to copy");
+                return template;
+            }
+            for (Long destZoneId : destZoneIds) {
+                DataStore dstSecStore = getImageStore(destZoneId, templateId);
+                if (dstSecStore != null) {
+                    s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() +
+                            " in zone " + destZoneId + " , don't need to copy");
+                    continue;
+                }
+                if (!copy(userId, template, srcSecStore, dataCenterVOs.get(destZoneId))) {
+                    failedZones.add(dataCenterVOs.get(destZoneId).getName());
+                }
+                else{
+                    if (template.getSize() != null) {
+                        // increase resource count
+                        long accountId = template.getAccountId();
+                        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize());
+                    }
+                }
+            }
+
+
+        }
+
+        if ((destZoneIds != null) && (destZoneIds.size() > failedZones.size())){
+            if (!failedZones.isEmpty()) {
+                s_logger.debug("There were failures when copying template to zones: " +
+                        StringUtils.listToCsvTags(failedZones));
+            }
+            return template;
+        } else {
+            throw new CloudRuntimeException("Failed to copy template");
+        }
+    }
+
+    private boolean addTemplateToZone(VMTemplateVO template, long dstZoneId, long sourceZoneid) throws ResourceAllocationException{
+        long tmpltId = template.getId();
+        DataCenterVO dstZone = _dcDao.findById(dstZoneId);
+        DataCenterVO sourceZone = _dcDao.findById(sourceZoneid);
+
+        AccountVO account = _accountDao.findById(template.getAccountId());
+
+
+        _resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
+
+        try {
+            _tmpltDao.addTemplateToZone(template, dstZoneId);
+            return true;
+        } catch (Exception ex) {
+            s_logger.debug("failed to copy template from Zone: " + sourceZone.getUuid() + " to Zone: " + dstZone.getUuid());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean delete(long userId, long templateId, Long zoneId) {
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null || template.getRemoved() != null) {
+            throw new InvalidParameterValueException("Please specify a valid template.");
+        }
+
+        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
+        return adapter.delete(new TemplateProfile(userId, template, zoneId));
+    }
+
+    @Override
+    public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool) {
+        List<VMTemplateStoragePoolVO> unusedTemplatesInPool = new ArrayList<VMTemplateStoragePoolVO>();
+        List<VMTemplateStoragePoolVO> allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId());
+
+        for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) {
+            VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
+
+            // If this is a routing template, consider it in use
+            if (template.getTemplateType() == TemplateType.SYSTEM) {
+                continue;
+            }
+
+            // If the template is not yet downloaded to the pool, consider it in
+            // use
+            if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) {
+                continue;
+            }
+
+            if (template.getFormat() != ImageFormat.ISO && !_volumeDao.isAnyVolumeActivelyUsingTemplateOnPool(template.getId(), pool.getId())) {
+                unusedTemplatesInPool.add(templatePoolVO);
+            }
+        }
+
+        return unusedTemplatesInPool;
+    }
+
+    @Override
+    @DB
+    public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
+        // Need to hold the lock; otherwise, another thread may create a volume from the template at the same time.
+        // Assumption here is that we will hold the same lock during create volume from template.
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolVO.getId());
+
+        if (templatePoolRef == null) {
+            s_logger.debug("Can't aquire the lock for template pool ref: " + templatePoolVO.getId());
+
+            return;
+        }
+
+        PrimaryDataStore pool = (PrimaryDataStore)_dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
+        TemplateInfo template = _tmplFactory.getTemplate(templatePoolRef.getTemplateId(), pool);
+
+        try {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Evicting " + templatePoolVO);
+            }
+
+            if (pool.isManaged()) {
+                // For managed store, just delete the template volume.
+                AsyncCallFuture<TemplateApiResult> future = _tmpltSvr.deleteTemplateOnPrimary(template, pool);
+                TemplateApiResult result = future.get();
+
+                if (result.isFailed()) {
+                    s_logger.debug("Failed to delete template " + template.getId() + " from storage pool " + pool.getId());
+                } else {
+                    // Remove the templatePoolVO.
+                    if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
+                        s_logger.debug("Successfully evicted template " + template.getName() + " from storage pool " + pool.getName());
+                    }
+                }
+            } else {
+                DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
+                Answer answer = _storageMgr.sendToPool(pool, cmd);
+
+                if (answer != null && answer.getResult()) {
+                    // Remove the templatePoolVO.
+                    if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
+                        s_logger.debug("Successfully evicted template " + template.getName() + " from storage pool " + pool.getName());
+                    }
+                } else {
+                    s_logger.info("Will retry evict template " + template.getName() + " from storage pool " + pool.getName());
+                }
+            }
+        } catch (StorageUnavailableException | InterruptedException | ExecutionException e) {
+            s_logger.info("Storage is unavailable currently. Will retry evicte template " + template.getName() + " from storage pool " + pool.getName());
+        } finally {
+            _tmpltPoolDao.releaseFromLockTable(templatePoolRef.getId());
+        }
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+        String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString());
+        _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction);
+
+        _preloadExecutor = Executors.newFixedThreadPool(TemplatePreloaderPoolSize.value(), new NamedThreadFactory("Template-Preloader"));
+
+        return true;
+    }
+
+    protected TemplateManagerImpl() {
+    }
+
+    @Override
+    public boolean templateIsDeleteable(VMTemplateHostVO templateHostRef) {
+        VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateHostRef.getTemplateId());
+        long templateId = template.getId();
+        HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
+        long zoneId = secondaryStorageHost.getDataCenterId();
+        DataCenterVO zone = _dcDao.findById(zoneId);
+
+        // Check if there are VMs running in the template host ref's zone that
+        // use the template
+        List<VMInstanceVO> nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId);
+
+        if (!nonExpungedVms.isEmpty()) {
+            s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() +
+                    " is not deleteable because there are non-expunged VMs deployed from this template.");
+            return false;
+        }
+        List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
+        // check if there is any VM using this ISO.
+        if (!userVmUsingIso.isEmpty()) {
+            s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
+            return false;
+        }
+        // Check if there are any snapshots for the template in the template
+        // host ref's zone
+        List<VolumeVO> volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId);
+        for (VolumeVO volume : volumes) {
+            List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1");
+            if (!snapshots.isEmpty()) {
+                s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() +
+                        " is not deleteable because there are 2.1 snapshots using this template.");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean templateIsDeleteable(long templateId) {
+        List<UserVmJoinVO> userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId);
+        // check if there is any Vm using this ISO. We only need to check the
+        // case where templateId is an ISO since
+        // VM can be launched from ISO in secondary storage, while template will
+        // always be copied to
+        // primary storage before deploying VM.
+        if (!userVmUsingIso.isEmpty()) {
+            s_logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true)
+    public boolean detachIso(long vmId) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long userId = CallContext.current().getCallingUserId();
+
+        // Verify input parameters
+        UserVmVO vmInstanceCheck = _userVmDao.findById(vmId);
+        if (vmInstanceCheck == null) {
+            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
+        }
+
+        UserVm userVM = _userVmDao.findById(vmId);
+        if (userVM == null) {
+            throw new InvalidParameterValueException("Please specify a valid VM.");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, userVM);
+
+        Long isoId = userVM.getIsoId();
+        if (isoId == null) {
+            throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
+        }
+        CallContext.current().setEventDetails("Vm Id: " + userVM.getUuid() + " ISO Id: " + isoId);
+
+        State vmState = userVM.getState();
+        if (vmState != State.Running && vmState != State.Stopped) {
+            throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
+        }
+
+        boolean result = attachISOToVM(vmId, userId, isoId, false); // attach=false
+        // => detach
+        if (result) {
+            return result;
+        } else {
+            throw new CloudRuntimeException("Failed to detach iso");
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true)
+    public boolean attachIso(long isoId, long vmId) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long userId = CallContext.current().getCallingUserId();
+
+        // Verify input parameters
+        UserVmVO vm = _userVmDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
+        }
+
+        VMTemplateVO iso = _tmpltDao.findById(isoId);
+        if (iso == null || iso.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId);
+        }
+
+        // check permissions
+        // check if caller has access to VM and ISO
+        // and also check if the VM's owner has access to the ISO.
+
+        _accountMgr.checkAccess(caller, null, false, iso, vm);
+
+        Account vmOwner = _accountDao.findById(vm.getAccountId());
+        _accountMgr.checkAccess(vmOwner, null, false, iso, vm);
+
+        State vmState = vm.getState();
+        if (vmState != State.Running && vmState != State.Stopped) {
+            throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
+        }
+
+        if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer) {
+            throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType());
+        }
+
+        if ("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
+            throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType());
+        }
+        boolean result = attachISOToVM(vmId, userId, isoId, true);
+        if (result) {
+            return result;
+        } else {
+            throw new CloudRuntimeException("Failed to attach iso");
+        }
+    }
+
+    // for ISO, we need to consider whether to copy to cache storage or not if it is not on NFS, since our hypervisor resource always assumes that they are in NFS
+    @Override
+    public TemplateInfo prepareIso(long isoId, long dcId, Long hostId, Long poolId) {
+        TemplateInfo tmplt;
+        boolean bypassed = false;
+        if (_tmplFactory.isTemplateMarkedForDirectDownload(isoId)) {
+            tmplt = _tmplFactory.getReadyBypassedTemplateOnPrimaryStore(isoId, poolId, hostId);
+            bypassed = true;
+        } else {
+            tmplt = _tmplFactory.getTemplate(isoId, DataStoreRole.Image, dcId);
+        }
+
+        if (tmplt == null || tmplt.getFormat() != ImageFormat.ISO) {
+            s_logger.warn("ISO: " + isoId + " does not exist in vm_template table");
+            return null;
+        }
+
+        if (!bypassed && tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) {
+            // if it is s3, need to download into cache storage first
+            Scope destScope = new ZoneScope(dcId);
+            TemplateInfo cacheData = (TemplateInfo)cacheMgr.createCacheObject(tmplt, destScope);
+            if (cacheData == null) {
+                s_logger.error("Failed in copy iso from S3 to cache storage");
+                return null;
+            }
+            return cacheData;
+        } else {
+            return tmplt;
+        }
+    }
+
+    private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
+        UserVmVO vm = _userVmDao.findById(vmId);
+
+        if (vm == null) {
+            return false;
+        } else if (vm.getState() != State.Running) {
+            return true;
+        }
+
+        // prepare ISO ready to mount on hypervisor resource level
+        TemplateInfo tmplt = prepareIso(isoId, vm.getDataCenterId(), vm.getHostId(), null);
+        if (tmplt == null) {
+            s_logger.error("Failed to prepare ISO ready to mount on hypervisor resource level");
+            throw new CloudRuntimeException("Failed to prepare ISO ready to mount on hypervisor resource level");
+        }
+        String vmName = vm.getInstanceName();
+
+        HostVO host = _hostDao.findById(vm.getHostId());
+        if (host == null) {
+            s_logger.warn("Host: " + vm.getHostId() + " does not exist");
+            return false;
+        }
+
+        DataTO isoTO = tmplt.getTO();
+        DiskTO disk = new DiskTO(isoTO, null, null, Volume.Type.ISO);
+        Command cmd = null;
+        if (attach) {
+            cmd = new AttachCommand(disk, vmName);
+        } else {
+            cmd = new DettachCommand(disk, vmName);
+        }
+        Answer a = _agentMgr.easySend(vm.getHostId(), cmd);
+        return (a != null && a.getResult());
+    }
+
+    private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) {
+        UserVmVO vm = _userVmDao.findById(vmId);
+        VMTemplateVO iso = _tmpltDao.findById(isoId);
+
+        boolean success = attachISOToVM(vmId, isoId, attach);
+        if (success && attach) {
+            vm.setIsoId(iso.getId());
+            _userVmDao.update(vmId, vm);
+        }
+        if (success && !attach) {
+            vm.setIsoId(null);
+            _userVmDao.update(vmId, vm);
+        }
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
+    public boolean deleteTemplate(DeleteTemplateCmd cmd) {
+        Long templateId = cmd.getId();
+        Account caller = CallContext.current().getCallingAccount();
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find template with id " + templateId);
+        }
+
+        List<VMInstanceVO> vmInstanceVOList;
+        if(cmd.getZoneId() != null) {
+            vmInstanceVOList = _vmInstanceDao.listNonExpungedByZoneAndTemplate(cmd.getZoneId(), templateId);
+        }
+        else {
+            vmInstanceVOList = _vmInstanceDao.listNonExpungedByTemplate(templateId);
+        }
+        if(!cmd.isForced() && CollectionUtils.isNotEmpty(vmInstanceVOList)) {
+            final String message = String.format("Unable to delete template with id: %1$s because VM instances: [%2$s] are using it.",  templateId, Joiner.on(",").join(vmInstanceVOList));
+            s_logger.warn(message);
+            throw new InvalidParameterValueException(message);
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
+
+        if (template.getFormat() == ImageFormat.ISO) {
+            throw new InvalidParameterValueException("Please specify a valid template.");
+        }
+
+        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
+        TemplateProfile profile = adapter.prepareDelete(cmd);
+        return adapter.delete(profile);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
+    public boolean deleteIso(DeleteIsoCmd cmd) {
+        Long templateId = cmd.getId();
+        Account caller = CallContext.current().getCallingAccount();
+        Long zoneId = cmd.getZoneId();
+
+        VMTemplateVO template = _tmpltDao.findById(templateId);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find iso with id " + templateId);
+        }
+
+        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template);
+
+        if (template.getFormat() != ImageFormat.ISO) {
+            throw new InvalidParameterValueException("Please specify a valid iso.");
+        }
+
+        // check if there is any VM using this ISO.
+        if (!templateIsDeleteable(templateId)) {
+            throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms");
+        }
+
+        if (zoneId != null && (_dataStoreMgr.getImageStore(zoneId) == null)) {
+            throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone.");
+        }
+
+        TemplateAdapter adapter = getAdapter(template.getHypervisorType());
+        TemplateProfile profile = adapter.prepareDelete(cmd);
+        boolean result = adapter.delete(profile);
+        if (result) {
+            return true;
+        } else {
+            throw new CloudRuntimeException("Failed to delete ISO");
+        }
+    }
+
+    @Override
+    public List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long id = cmd.getId();
+
+        if (id.equals(Long.valueOf(1))) {
+            throw new PermissionDeniedException("unable to list permissions for " + cmd.getMediaType() + " with id " + id);
+        }
+
+        VirtualMachineTemplate template = _tmpltDao.findById(id);
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id);
+        }
+
+        if (cmd instanceof ListTemplatePermissionsCmd) {
+            if (template.getFormat().equals(ImageFormat.ISO)) {
+                throw new InvalidParameterValueException("Please provide a valid template");
+            }
+        } else if (cmd instanceof ListIsoPermissionsCmd) {
+            if (!template.getFormat().equals(ImageFormat.ISO)) {
+                throw new InvalidParameterValueException("Please provide a valid iso");
+            }
+        }
+
+        if (!template.isPublicTemplate()) {
+            _accountMgr.checkAccess(caller, null, true, template);
+        }
+
+        List<String> accountNames = new ArrayList<String>();
+        List<LaunchPermissionVO> permissions = _launchPermissionDao.findByTemplate(id);
+        if ((permissions != null) && !permissions.isEmpty()) {
+            for (LaunchPermissionVO permission : permissions) {
+                Account acct = _accountDao.findById(permission.getAccountId());
+                accountNames.add(acct.getAccountName());
+            }
+        }
+
+        // also add the owner if not public
+        if (!template.isPublicTemplate()) {
+            Account templateOwner = _accountDao.findById(template.getAccountId());
+            accountNames.add(templateOwner.getAccountName());
+        }
+
+        return accountNames;
+    }
+
+    @DB
+    @Override
+    public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) {
+        // Input validation
+        final Long id = cmd.getId();
+        final Account caller = CallContext.current().getCallingAccount();
+        List<String> accountNames = cmd.getAccountNames();
+        List<Long> projectIds = cmd.getProjectIds();
+        Boolean isFeatured = cmd.isFeatured();
+        Boolean isPublic = cmd.isPublic();
+        Boolean isExtractable = cmd.isExtractable();
+        String operation = cmd.getOperation();
+        String mediaType = "";
+
+        VMTemplateVO template = _tmpltDao.findById(id);
+
+        if (template == null) {
+            throw new InvalidParameterValueException("unable to find " + mediaType + " with id " + id);
+        }
+
+        if (cmd instanceof UpdateTemplatePermissionsCmd) {
+            mediaType = "template";
+            if (template.getFormat().equals(ImageFormat.ISO)) {
+                throw new InvalidParameterValueException("Please provide a valid template");
+            }
+        }
+        if (cmd instanceof UpdateIsoPermissionsCmd) {
+            mediaType = "iso";
+            if (!template.getFormat().equals(ImageFormat.ISO)) {
+                throw new InvalidParameterValueException("Please provide a valid iso");
+            }
+        }
+
+        // convert projectIds to accountNames
+        if (projectIds != null) {
+            // CS-17842, initialize accountNames list
+            if (accountNames == null) {
+                accountNames = new ArrayList<String>();
+            }
+            for (Long projectId : projectIds) {
+                Project project = _projectMgr.getProject(projectId);
+                if (project == null) {
+                    throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+                }
+
+                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
+                    throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
+                }
+                accountNames.add(_accountMgr.getAccount(project.getProjectAccountId()).getAccountName());
+            }
+        }
+
+        //_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
+        _accountMgr.checkAccess(caller, AccessType.OperateEntry, true, template); //TODO: should we replace all ModifyEntry as OperateEntry?
+
+        // If the template is removed throw an error.
+        if (template.getRemoved() != null) {
+            s_logger.error("unable to update permissions for " + mediaType + " with id " + id + " as it is removed  ");
+            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id + " as it is removed ");
+        }
+
+        if (id.equals(Long.valueOf(1))) {
+            throw new InvalidParameterValueException("unable to update permissions for " + mediaType + " with id " + id);
+        }
+
+        boolean isAdmin = _accountMgr.isAdmin(caller.getId());
+        // check configuration parameter(allow.public.user.templates) value for
+        // the template owner
+        boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(template.getAccountId());
+        if (!isAdmin && !allowPublicUserTemplates && isPublic != null && isPublic) {
+            throw new InvalidParameterValueException("Only private " + mediaType + "s can be created.");
+        }
+
+        if (accountNames != null) {
+            if ((operation == null) || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) {
+                throw new InvalidParameterValueException(
+                    "Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." + "  Given operation is: '" +
+                        operation + "'");
+            }
+        }
+
+        Long ownerId = template.getAccountId();
+        if (ownerId == null) {
+            // if there is no owner of the template then it's probably already a
+            // public template (or domain private template) so
+            // publishing to individual users is irrelevant
+            throw new InvalidParameterValueException("Update template permissions is an invalid operation on template " + template.getName());
+        }
+
+        //Only admin or owner of the template should be able to change its permissions
+        if (caller.getId() != ownerId && !isAdmin) {
+            throw new InvalidParameterValueException("Unable to grant permission to account " + caller.getAccountName() + " as it is neither admin nor owner or the template");
+        }
+
+        VMTemplateVO updatedTemplate = _tmpltDao.createForUpdate();
+
+        if (isPublic != null) {
+            updatedTemplate.setPublicTemplate(isPublic.booleanValue());
+        }
+
+        if (isFeatured != null) {
+            updatedTemplate.setFeatured(isFeatured.booleanValue());
+        }
+
+        if (isExtractable != null) {
+            // Only Root admins allowed to change it for templates
+            if (!template.getFormat().equals(ImageFormat.ISO) && !_accountMgr.isRootAdmin(caller.getId())) {
+                throw new InvalidParameterValueException("Only ROOT admins are allowed to modify isExtractable attribute.");
+            } else {
+                // For Isos normal user can change it, as their are no derivatives.
+                updatedTemplate.setExtractable(isExtractable.booleanValue());
+            }
+        }
+
+        _tmpltDao.update(template.getId(), updatedTemplate);
+
+        //when operation is add/remove, accountNames can not be null
+        if (("add".equalsIgnoreCase(operation) || "remove".equalsIgnoreCase(operation)) && accountNames == null) {
+            throw new InvalidParameterValueException("Operation " + operation + " requires accounts or projectIds to be passed in");
+        }
+
+        //Derive the domain id from the template owner as updateTemplatePermissions is not cross domain operation
+        Account owner = _accountMgr.getAccount(ownerId);
+        final Domain domain = _domainDao.findById(owner.getDomainId());
+        if ("add".equalsIgnoreCase(operation)) {
+            final List<String> accountNamesFinal = accountNames;
+            final List<Long> accountIds = new ArrayList<Long>();
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    for (String accountName : accountNamesFinal) {
+                        Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId());
+                        if (permittedAccount != null) {
+                            if (permittedAccount.getId() == caller.getId()) {
+                                continue; // don't grant permission to the template
+                                // owner, they implicitly have permission
+                            }
+                            accountIds.add(permittedAccount.getId());
+                            LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId());
+                            if (existingPermission == null) {
+                                LaunchPermissionVO launchPermission = new LaunchPermissionVO(id, permittedAccount.getId());
+                                _launchPermissionDao.persist(launchPermission);
+                            }
+                        } else {
+                            throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + " in domain id=" +
+                                domain.getUuid() + ", account not found.  " + "No permissions updated, please verify the account names and retry.");
+                }
+            }
+                }
+            });
+
+            // add ACL permission in IAM
+            Map<String, Object> permit = new HashMap<String, Object>();
+            permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class);
+            permit.put(ApiConstants.ENTITY_ID, id);
+            permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry);
+            permit.put(ApiConstants.ACCOUNTS, accountIds);
+            _messageBus.publish(_name, EntityManager.MESSAGE_GRANT_ENTITY_EVENT, PublishScope.LOCAL, permit);
+        } else if ("remove".equalsIgnoreCase(operation)) {
+            List<Long> accountIds = new ArrayList<Long>();
+            for (String accountName : accountNames) {
+                Account permittedAccount = _accountDao.findActiveAccount(accountName, domain.getId());
+                if (permittedAccount != null) {
+                    accountIds.add(permittedAccount.getId());
+                }
+            }
+            _launchPermissionDao.removePermissions(id, accountIds);
+            // remove ACL permission in IAM
+            Map<String, Object> permit = new HashMap<String, Object>();
+            permit.put(ApiConstants.ENTITY_TYPE, VirtualMachineTemplate.class);
+            permit.put(ApiConstants.ENTITY_ID, id);
+            permit.put(ApiConstants.ACCESS_TYPE, AccessType.UseEntry);
+            permit.put(ApiConstants.ACCOUNTS, accountIds);
+            _messageBus.publish(_name, EntityManager.MESSAGE_REVOKE_ENTITY_EVENT, PublishScope.LOCAL, permit);
+        } else if ("reset".equalsIgnoreCase(operation)) {
+            // do we care whether the owning account is an admin? if the
+            // owner is an admin, will we still set public to false?
+            updatedTemplate = _tmpltDao.createForUpdate();
+            updatedTemplate.setPublicTemplate(false);
+            updatedTemplate.setFeatured(false);
+            _tmpltDao.update(template.getId(), updatedTemplate);
+            _launchPermissionDao.removeAllPermissions(id);
+            _messageBus.publish(_name, TemplateManager.MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT, PublishScope.LOCAL, template.getId());
+        }
+        return true;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true)
+    public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException {
+        final long templateId = command.getEntityId();
+        Long volumeId = command.getVolumeId();
+        Long snapshotId = command.getSnapshotId();
+        VMTemplateVO privateTemplate = null;
+        final Long accountId = CallContext.current().getCallingAccountId();
+        SnapshotVO snapshot = null;
+        VolumeVO volume = null;
+
+        try {
+            TemplateInfo tmplInfo = _tmplFactory.getTemplate(templateId, DataStoreRole.Image);
+            long zoneId = 0;
+            if (snapshotId != null) {
+                snapshot = _snapshotDao.findById(snapshotId);
+                zoneId = snapshot.getDataCenterId();
+            } else if (volumeId != null) {
+                volume = _volumeDao.findById(volumeId);
+                zoneId = volume.getDataCenterId();
+            }
+            DataStore store = _dataStoreMgr.getImageStore(zoneId);
+            if (store == null) {
+                throw new CloudRuntimeException("cannot find an image store for zone " + zoneId);
+            }
+            AsyncCallFuture<TemplateApiResult> future = null;
+
+            if (snapshotId != null) {
+                DataStoreRole dataStoreRole = ApiResponseHelper.getDataStoreRole(snapshot, _snapshotStoreDao, _dataStoreMgr);
+
+                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) {
+                        store = snapStore; // pick snapshot image store to create template
+                    }
+                }
+
+                future = _tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store);
+            } else if (volumeId != null) {
+                VolumeInfo volInfo = _volFactory.getVolume(volumeId);
+
+                future = _tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store);
+            } else {
+                throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
+            }
+
+            CommandResult result = null;
+
+            try {
+                result = future.get();
+
+                if (result.isFailed()) {
+                    privateTemplate = null;
+                    s_logger.debug("Failed to create template" + result.getResult());
+                    throw new CloudRuntimeException("Failed to create template" + result.getResult());
+                }
+
+                // create entries in template_zone_ref table
+                if (_dataStoreMgr.isRegionStore(store)) {
+                    // template created on region store
+                    _tmpltSvr.associateTemplateToZone(templateId, null);
+                } else {
+                    VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
+                    _tmpltZoneDao.persist(templateZone);
+                }
+
+                privateTemplate = _tmpltDao.findById(templateId);
+                TemplateDataStoreVO srcTmpltStore = _tmplStoreDao.findByStoreTemplate(store.getId(), templateId);
+                UsageEventVO usageEvent =
+                        new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId, privateTemplate.getId(), privateTemplate.getName(), null,
+                                privateTemplate.getSourceTemplateId(), srcTmpltStore.getPhysicalSize(), privateTemplate.getSize());
+                _usageEventDao.persist(usageEvent);
+            } catch (InterruptedException e) {
+                s_logger.debug("Failed to create template", e);
+                throw new CloudRuntimeException("Failed to create template", e);
+            } catch (ExecutionException e) {
+                s_logger.debug("Failed to create template", e);
+                throw new CloudRuntimeException("Failed to create template", e);
+            }
+
+        } finally {
+            if (privateTemplate == null) {
+                final VolumeVO volumeFinal = volume;
+                final SnapshotVO snapshotFinal = snapshot;
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        // template_store_ref entries should have been removed using our
+                        // DataObject.processEvent command in case of failure, but clean
+                        // it up here to avoid
+                        // some leftovers which will cause removing template from
+                        // vm_template table fail.
+                        _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
+                        // Remove the template_zone_ref record
+                        _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
+                        // Remove the template record
+                        _tmpltDao.expunge(templateId);
+
+                        // decrement resource count
+                        if (accountId != null) {
+                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
+                            _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volumeFinal != null ? volumeFinal.getSize()
+                                    : snapshotFinal.getSize()));
+                        }
+                    }
+                });
+
+            }
+        }
+
+        if (privateTemplate != null) {
+            return privateTemplate;
+        } else {
+            throw new CloudRuntimeException("Failed to create a template");
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true)
+    public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+        boolean isAdmin = (_accountMgr.isAdmin(caller.getId()));
+
+        _accountMgr.checkAccess(caller, null, true, templateOwner);
+
+        String name = cmd.getTemplateName();
+        if ((name == null) || (name.length() > 32)) {
+            throw new InvalidParameterValueException("Template name cannot be null and should be less than 32 characters");
+        }
+
+        if (cmd.getTemplateTag() != null) {
+            if (!_accountService.isRootAdmin(caller.getId())) {
+                throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
+            }
+        }
+
+        // do some parameter defaulting
+        Integer bits = cmd.getBits();
+        Boolean requiresHvm = cmd.getRequiresHvm();
+        Boolean passwordEnabled = cmd.isPasswordEnabled();
+        Boolean sshKeyEnabled = cmd.isSshKeyEnabled();
+        Boolean isPublic = cmd.isPublic();
+        Boolean featured = cmd.isFeatured();
+        int bitsValue = ((bits == null) ? 64 : bits.intValue());
+        boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm.booleanValue());
+        boolean passwordEnabledValue = ((passwordEnabled == null) ? false : passwordEnabled.booleanValue());
+        boolean sshKeyEnabledValue = ((sshKeyEnabled == null) ? false : sshKeyEnabled.booleanValue());
+        if (isPublic == null) {
+            isPublic = Boolean.FALSE;
+        }
+        boolean isDynamicScalingEnabled = cmd.isDynamicallyScalable();
+        // check whether template owner can create public templates
+        boolean allowPublicUserTemplates = AllowPublicUserTemplates.valueIn(templateOwner.getId());
+        if (!isAdmin && !allowPublicUserTemplates && isPublic) {
+            throw new PermissionDeniedException("Failed to create template " + name + ", only private templates can be created.");
+        }
+
+        Long volumeId = cmd.getVolumeId();
+        Long snapshotId = cmd.getSnapshotId();
+        if ((volumeId == null) && (snapshotId == null)) {
+            throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified.");
+        }
+        if ((volumeId != null) && (snapshotId != null)) {
+            throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId +
+                    ") and snapshot ID (" + snapshotId + ")");
+        }
+
+        HypervisorType hyperType;
+        VolumeVO volume = null;
+        SnapshotVO snapshot = null;
+        VMTemplateVO privateTemplate = null;
+        if (volumeId != null) { // create template from volume
+            volume = _volumeDao.findById(volumeId);
+            if (volume == null) {
+                throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId);
+            }
+            // check permissions
+            _accountMgr.checkAccess(caller, null, true, volume);
+
+            // If private template is created from Volume, check that the volume
+            // will not be active when the private template is
+            // created
+            if (!_volumeMgr.volumeInactive(volume)) {
+                String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first";
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info(msg);
+                }
+                throw new CloudRuntimeException(msg);
+            }
+
+            hyperType = _volumeDao.getHypervisorType(volumeId);
+            if (HypervisorType.LXC.equals(hyperType)) {
+                throw new InvalidParameterValueException("Template creation is not supported for LXC volume: " + volumeId);
+            }
+        } else { // create template from snapshot
+            snapshot = _snapshotDao.findById(snapshotId);
+            if (snapshot == null) {
+                throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId);
+            }
+            // Volume could be removed so find including removed to record source template id.
+            volume = _volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId());
+
+            // check permissions
+            _accountMgr.checkAccess(caller, null, true, snapshot);
+
+            if (snapshot.getState() != Snapshot.State.BackedUp) {
+                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp +
+                        " state yet and can't be used for template creation");
+            }
+
+            /*
+             * // bug #11428. Operation not supported if vmware and snapshots
+             * parent volume = ROOT if(snapshot.getHypervisorType() ==
+             * HypervisorType.VMware && snapshotVolume.getVolumeType() ==
+             * Type.DATADISK){ throw new UnsupportedServiceException(
+             * "operation not supported, snapshot with id " + snapshotId +
+             * " is created from Data Disk"); }
+             */
+
+            hyperType = snapshot.getHypervisorType();
+        }
+
+        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template);
+        _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.secondary_storage, new Long(volume != null ? volume.getSize() : snapshot.getSize()).longValue());
+
+        if (!isAdmin || featured == null) {
+            featured = Boolean.FALSE;
+        }
+        Long guestOSId = cmd.getOsTypeId();
+        GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
+        if (guestOS == null) {
+            throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist.");
+        }
+
+        Long nextTemplateId = _tmpltDao.getNextInSequence(Long.class, "id");
+        String description = cmd.getDisplayText();
+        boolean isExtractable = false;
+        Long sourceTemplateId = null;
+        if (volume != null) {
+            VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
+            isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
+            if (volume.getIsoId() != null && volume.getIsoId() != 0) {
+                sourceTemplateId = volume.getIsoId();
+            } else if (volume.getTemplateId() != null) {
+                sourceTemplateId = volume.getTemplateId();
+            }
+        }
+        String templateTag = cmd.getTemplateTag();
+        if (templateTag != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Adding template tag: " + templateTag);
+            }
+        }
+        privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable,
+                TemplateType.USER, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description,
+                passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), sshKeyEnabledValue, isDynamicScalingEnabled, false);
+
+        if (sourceTemplateId != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("This template is getting created from other template, setting source template Id to: " + sourceTemplateId);
+            }
+        }
+
+
+        // for region wide storage, set cross zones flag
+        List<ImageStoreVO> stores = _imgStoreDao.findRegionImageStores();
+        if (!CollectionUtils.isEmpty(stores)) {
+            privateTemplate.setCrossZones(true);
+        }
+
+        privateTemplate.setSourceTemplateId(sourceTemplateId);
+
+        VMTemplateVO template = _tmpltDao.persist(privateTemplate);
+        // Increment the number of templates
+        if (template != null) {
+            Map<String, String> details = new HashMap<String, String>();
+
+            if (sourceTemplateId != null) {
+                VMTemplateVO sourceTemplate = _tmpltDao.findById(sourceTemplateId);
+                if (sourceTemplate != null && sourceTemplate.getDetails() != null) {
+                    details.putAll(sourceTemplate.getDetails());
+                }
+            }
+
+            if (volume != null) {
+                Long vmId = volume.getInstanceId();
+                if (vmId != null) {
+                    UserVmVO userVm = _userVmDao.findById(vmId);
+                    if (userVm != null) {
+                        _userVmDao.loadDetails(userVm);
+                        details.putAll(userVm.getDetails());
+                    }
+                }
+            }
+            if (cmd.getDetails() != null) {
+                details.remove("Encrypted.Password"); // new password will be generated during vm deployment from password enabled template
+                details.putAll(cmd.getDetails());
+            }
+            if (!details.isEmpty()) {
+                privateTemplate.setDetails(details);
+                _tmpltDao.saveDetails(privateTemplate);
+            }
+
+            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.template);
+            _resourceLimitMgr.incrementResourceCount(templateOwner.getId(), ResourceType.secondary_storage,
+                    new Long(volume != null ? volume.getSize() : snapshot.getSize()));
+        }
+
+        if (template != null) {
+            return template;
+        } else {
+            throw new CloudRuntimeException("Failed to create a template");
+        }
+
+    }
+
+    @Override
+    public Pair<String, String> getAbsoluteIsoPath(long templateId, long dataCenterId) {
+        TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        if (templateStoreRef == null) {
+            throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId);
+        }
+        DataStore store = _dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image);
+        String isoPath = store.getUri() + "/" + templateStoreRef.getInstallPath();
+        return new Pair<String, String>(isoPath, store.getUri());
+    }
+
+    @Override
+    public String getSecondaryStorageURL(long zoneId) {
+        DataStore secStore = _dataStoreMgr.getImageStore(zoneId);
+        if (secStore == null) {
+            return null;
+        }
+
+        return secStore.getUri();
+    }
+
+    // get the image store where a template in a given zone is downloaded to,
+    // just pick one is enough.
+    @Override
+    public DataStore getImageStore(long zoneId, long tmpltId) {
+        TemplateDataStoreVO tmpltStore = _tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        if (tmpltStore != null) {
+            return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
+        }
+
+        return null;
+    }
+
+    // get the region wide image store where a template is READY on,
+    // just pick one is enough.
+    @Override
+    public DataStore getImageStore(long tmpltId) {
+        TemplateDataStoreVO tmpltStore = _tmplStoreDao.findReadyByTemplate(tmpltId, DataStoreRole.Image);
+        if (tmpltStore != null) {
+            return _dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Long getTemplateSize(long templateId, long zoneId) {
+        if (_tmplStoreDao.isTemplateMarkedForDirectDownload(templateId)) {
+            // check if template is marked for direct download
+            return _tmplStoreDao.getReadyBypassedTemplate(templateId).getSize();
+        }
+        TemplateDataStoreVO templateStoreRef = _tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+        if (templateStoreRef == null) {
+            // check if it is ready on image cache stores
+            templateStoreRef = _tmplStoreDao.findByTemplateZoneStagingDownloadStatus(templateId, zoneId,
+                    VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
+            if (templateStoreRef == null) {
+                throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + zoneId);
+            }
+        }
+        return templateStoreRef.getSize();
+
+    }
+
+    // find image store where this template is located
+    @Override
+    public List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId) {
+        // find all eligible image stores for this zone scope
+        List<DataStore> imageStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
+        if (imageStores == null || imageStores.size() == 0) {
+            return null;
+        }
+        List<DataStore> stores = new ArrayList<DataStore>();
+        for (DataStore store : imageStores) {
+            // check if the template is stored there
+            List<TemplateDataStoreVO> storeTmpl = _tmplStoreDao.listByTemplateStore(templateId, store.getId());
+            if (storeTmpl != null && storeTmpl.size() > 0) {
+                stores.add(store);
+            }
+        }
+        return stores;
+    }
+
+    @Override
+    public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) {
+        return updateTemplateOrIso(cmd);
+    }
+
+    @Override
+    public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) {
+        return updateTemplateOrIso(cmd);
+    }
+
+    private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
+        Long id = cmd.getId();
+        String name = cmd.getTemplateName();
+        String displayText = cmd.getDisplayText();
+        String format = cmd.getFormat();
+        Long guestOSId = cmd.getOsTypeId();
+        Boolean passwordEnabled = cmd.getPasswordEnabled();
+        Boolean sshKeyEnabled = cmd.isSshKeyEnabled();
+        Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
+        Boolean isRoutingTemplate = cmd.isRoutingType();
+        Boolean bootable = cmd.getBootable();
+        Boolean requiresHvm = cmd.getRequiresHvm();
+        Integer sortKey = cmd.getSortKey();
+        Map details = cmd.getDetails();
+        Account account = CallContext.current().getCallingAccount();
+        boolean cleanupDetails = cmd.isCleanupDetails();
+
+        // verify that template exists
+        VMTemplateVO template = _tmpltDao.findById(id);
+        if (template == null || template.getRemoved() != null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id");
+            ex.addProxyObject(String.valueOf(id), "templateId");
+            throw ex;
+        }
+
+        verifyTemplateId(id);
+
+        // do a permission check
+        _accountMgr.checkAccess(account, AccessType.OperateEntry, true, template);
+        if (cmd.isRoutingType() != null) {
+            if (!_accountService.isRootAdmin(account.getId())) {
+                throw new PermissionDeniedException("Parameter isrouting can only be specified by a Root Admin, permission denied");
+            }
+        }
+
+        // update is needed if any of the fields below got filled by the user
+        boolean updateNeeded =
+                !(name == null &&
+                  displayText == null &&
+                  format == null &&
+                  guestOSId == null &&
+                  passwordEnabled == null &&
+                  bootable == null &&
+                  sshKeyEnabled == null &&
+                  requiresHvm == null &&
+                  sortKey == null &&
+                  isDynamicallyScalable == null &&
+                  isRoutingTemplate == null &&
+                  (! cleanupDetails && details == null) //update details in every case except this one
+                  );
+        if (!updateNeeded) {
+            return template;
+        }
+
+        template = _tmpltDao.createForUpdate(id);
+
+        if (name != null) {
+            template.setName(name);
+        }
+
+        if (displayText != null) {
+            template.setDisplayText(displayText);
+        }
+
+        if (sortKey != null) {
+            template.setSortKey(sortKey);
+        }
+
+        ImageFormat imageFormat = null;
+        if (format != null) {
+            try {
+                imageFormat = ImageFormat.valueOf(format.toUpperCase());
+            } catch (IllegalArgumentException e) {
+                throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are " + EnumUtils.listValues(ImageFormat.values()));
+            }
+
+            template.setFormat(imageFormat);
+        }
+
+        if (guestOSId != null) {
+            long oldGuestOSId = template.getGuestOSId();
+            GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
+
+            if (guestOS == null) {
+                throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
+            } else {
+                template.setGuestOSId(guestOSId);
+            }
+
+            if (guestOSId != oldGuestOSId) { // vm guest os type need to be updated if template guest os id changes.
+                SearchCriteria<VMInstanceVO> sc = _vmInstanceDao.createSearchCriteria();
+                sc.addAnd("templateId", SearchCriteria.Op.EQ, id);
+                sc.addAnd("state", SearchCriteria.Op.NEQ, State.Expunging);
+                List<VMInstanceVO> vms = _vmInstanceDao.search(sc, null);
+                if (vms != null && !vms.isEmpty()) {
+                    for (VMInstanceVO vm: vms) {
+                        vm.setGuestOSId(guestOSId);
+                        _vmInstanceDao.update(vm.getId(), vm);
+                    }
+                }
+            }
+        }
+
+        if (passwordEnabled != null) {
+            template.setEnablePassword(passwordEnabled);
+        }
+
+        if (sshKeyEnabled != null) {
+            template.setEnableSshKey(sshKeyEnabled);
+        }
+
+        if (bootable != null) {
+            template.setBootable(bootable);
+        }
+
+        if (requiresHvm != null) {
+            template.setRequiresHvm(requiresHvm);
+        }
+
+        if (isDynamicallyScalable != null) {
+            template.setDynamicallyScalable(isDynamicallyScalable);
+        }
+
+        if (isRoutingTemplate != null) {
+            if (isRoutingTemplate) {
+                template.setTemplateType(TemplateType.ROUTING);
+            } else {
+                template.setTemplateType(TemplateType.USER);
+            }
+        }
+
+        if (cleanupDetails) {
+            template.setDetails(null);
+            _tmpltDetailsDao.removeDetails(id);
+        }
+        else if (details != null && !details.isEmpty()) {
+            template.setDetails(details);
+            _tmpltDao.saveDetails(template);
+        }
+
+        _tmpltDao.update(id, template);
+
+        return _tmpltDao.findById(id);
+    }
+
+    void verifyTemplateId(Long id) {
+        // Don't allow to modify system template
+        if (id.equals(Long.valueOf(1))) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id");
+            ex.addProxyObject(String.valueOf(id), "templateId");
+            throw ex;
+        }
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return TemplateManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize};
+    }
+
+    public List<TemplateAdapter> getTemplateAdapters() {
+        return _adapters;
+    }
+
+    @Inject
+    public void setTemplateAdapters(List<TemplateAdapter> adapters) {
+        _adapters = adapters;
+    }
+}
diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/main/java/com/cloud/test/DatabaseConfig.java
similarity index 100%
rename from server/src/com/cloud/test/DatabaseConfig.java
rename to server/src/main/java/com/cloud/test/DatabaseConfig.java
diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/main/java/com/cloud/test/IPRangeConfig.java
similarity index 100%
rename from server/src/com/cloud/test/IPRangeConfig.java
rename to server/src/main/java/com/cloud/test/IPRangeConfig.java
diff --git a/server/src/main/java/com/cloud/test/PodZoneConfig.java b/server/src/main/java/com/cloud/test/PodZoneConfig.java
new file mode 100644
index 0000000..ee017d5
--- /dev/null
+++ b/server/src/main/java/com/cloud/test/PodZoneConfig.java
@@ -0,0 +1,570 @@
+// 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.test;
+
+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.Vector;
+
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.net.NetUtils;
+
+public class PodZoneConfig {
+
+    public static void main(String[] args) {
+        PodZoneConfig config = ComponentContext.inject(PodZoneConfig.class);
+        //config.run(args);
+        System.exit(0);
+    }
+
+    public void savePod(boolean printOutput, long id, String name, long dcId, String gateway, String cidr, int vlanStart, int vlanEnd) {
+        // Check that the cidr was valid
+        if (!IPRangeConfig.validCIDR(cidr))
+            printError("Please enter a valid CIDR for pod: " + name);
+
+        // Get the individual cidrAddress and cidrSize values
+        String[] cidrPair = cidr.split("\\/");
+        String cidrAddress = cidrPair[0];
+        String cidrSize = cidrPair[1];
+
+        String sql = null;
+        if (id != -1)
+            sql =
+                "INSERT INTO `cloud`.`host_pod_ref` (id, name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + id + "','" + name + "','" + dcId +
+                    "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')";
+        else
+            sql =
+                "INSERT INTO `cloud`.`host_pod_ref` (name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + name + "','" + dcId + "','" + gateway +
+                    "','" + cidrAddress + "','" + cidrSize + "')";
+
+        DatabaseConfig.saveSQL(sql, "Failed to save pod due to exception. Please contact Cloud Support.");
+
+        if (printOutput)
+            System.out.println("Successfully saved pod.");
+    }
+
+    public void checkAllPodCidrSubnets() {
+        Vector<Long> allZoneIDs = getAllZoneIDs();
+        for (Long dcId : allZoneIDs) {
+            HashMap<Long, Vector<Object>> currentPodCidrSubnets = getCurrentPodCidrSubnets(dcId.longValue());
+            String result = checkPodCidrSubnets(dcId.longValue(), currentPodCidrSubnets);
+            if (!result.equals("success"))
+                printError(result);
+        }
+    }
+
+    private String checkPodCidrSubnets(long dcId, HashMap<Long, Vector<Object>> currentPodCidrSubnets) {
+
+//        DataCenterDao _dcDao = null;
+//        final ComponentLocator locator = ComponentLocator.getLocator("management-server");
+
+//        _dcDao = locator.getDao(DataCenterDao.class);
+        // For each pod, return an error if any of the following is true:
+        // 1. The pod's CIDR subnet conflicts with the guest network subnet
+        // 2. The pod's CIDR subnet conflicts with the CIDR subnet of any other pod
+
+        String zoneName = PodZoneConfig.getZoneName(dcId);
+
+        //get the guest network cidr and guest netmask from the zone
+//        DataCenterVO dcVo = _dcDao.findById(dcId);
+
+        String guestNetworkCidr = IPRangeConfig.getGuestNetworkCidr(dcId);
+
+        if (guestNetworkCidr == null || guestNetworkCidr.isEmpty())
+            return "Please specify a valid guest cidr";
+        String[] cidrTuple = guestNetworkCidr.split("\\/");
+
+        String guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]));
+        long guestCidrSize = Long.parseLong(cidrTuple[1]);
+
+        // Iterate through all pods in this zone
+        for (Long podId : currentPodCidrSubnets.keySet()) {
+            String podName;
+            if (podId.longValue() == -1)
+                podName = "newPod";
+            else
+                podName = PodZoneConfig.getPodName(podId.longValue(), dcId);
+
+            Vector<Object> cidrPair = currentPodCidrSubnets.get(podId);
+            String cidrAddress = (String)cidrPair.get(0);
+            long cidrSize = ((Long)cidrPair.get(1)).longValue();
+
+            long cidrSizeToUse = -1;
+            if (cidrSize < guestCidrSize)
+                cidrSizeToUse = cidrSize;
+            else
+                cidrSizeToUse = guestCidrSize;
+
+            String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
+            String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse);
+
+            // Check that cidrSubnet does not equal guestSubnet
+            if (cidrSubnet.equals(guestSubnet)) {
+                if (podName.equals("newPod")) {
+                    return "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR.";
+                } else {
+                    return "Warning: The subnet of pod " + podName + " in zone " + zoneName +
+                        " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management.";
+                }
+            }
+
+            // Iterate through the rest of the pods
+            for (Long otherPodId : currentPodCidrSubnets.keySet()) {
+                if (podId.equals(otherPodId))
+                    continue;
+
+                // Check that cidrSubnet does not equal otherCidrSubnet
+                Vector<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId);
+                String otherCidrAddress = (String)otherCidrPair.get(0);
+                long otherCidrSize = ((Long)otherCidrPair.get(1)).longValue();
+
+                if (cidrSize < otherCidrSize)
+                    cidrSizeToUse = cidrSize;
+                else
+                    cidrSizeToUse = otherCidrSize;
+
+                cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse);
+                String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse);
+
+                if (cidrSubnet.equals(otherCidrSubnet)) {
+                    String otherPodName = PodZoneConfig.getPodName(otherPodId.longValue(), dcId);
+                    if (podName.equals("newPod")) {
+                        return "The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName +
+                            ". Please specify a different CIDR.";
+                    } else {
+                        return "Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName +
+                            " have conflicting CIDR subnets. Please change the CIDR of one of these pods.";
+                    }
+                }
+            }
+        }
+
+        return "success";
+    }
+
+    @DB
+    protected HashMap<Long, Vector<Object>> getCurrentPodCidrSubnets(long dcId) {
+        HashMap<Long, Vector<Object>> currentPodCidrSubnets = new HashMap<Long, Vector<Object>>();
+
+        String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + dcId;
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
+            ResultSet rs = stmt.executeQuery();
+            while (rs.next()) {
+                Long podId = rs.getLong("id");
+                String cidrAddress = rs.getString("cidr_address");
+                long cidrSize = rs.getLong("cidr_size");
+                Vector<Object> cidrPair = new Vector<Object>();
+                cidrPair.add(0, cidrAddress);
+                cidrPair.add(1, new Long(cidrSize));
+                currentPodCidrSubnets.put(podId, cidrPair);
+            }
+        } catch (SQLException ex) {
+            System.out.println(ex.getMessage());
+            printError("There was an issue with reading currently saved pod CIDR subnets. Please contact Cloud Support.");
+            return null;
+        }
+
+        return currentPodCidrSubnets;
+    }
+
+    public void deletePod(String name, long dcId) {
+        String sql = "DELETE FROM `cloud`.`host_pod_ref` WHERE name=\"" + name + "\" AND data_center_id=\"" + dcId + "\"";
+        DatabaseConfig.saveSQL(sql, "Failed to delete pod due to exception. Please contact Cloud Support.");
+    }
+
+    public long getVlanDbId(String zone, String vlanId) {
+        long zoneId = getZoneId(zone);
+
+        return DatabaseConfig.getDatabaseValueLong("SELECT * FROM `cloud`.`vlan` WHERE data_center_id=\"" + zoneId + "\" AND vlan_id =\"" + vlanId + "\"", "id",
+            "Unable to start DB connection to read vlan DB id. Please contact Cloud Support.");
+    }
+
+    public List<String> modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange,
+        long networkId, long physicalNetworkId) {
+        // Check if the zone is valid
+        long zoneId = getZoneId(zone);
+        if (zoneId == -1)
+            return genReturnList("false", "Please specify a valid zone.");
+
+        //check if physical network is valid
+        long physicalNetworkDbId = checkPhysicalNetwork(physicalNetworkId);
+        if (physicalNetworkId == -1)
+            return genReturnList("false", "Please specify a valid physical network.");
+
+        Long podId = pod != null ? getPodId(pod, zone) : null;
+        if (podId != null && podId == -1)
+            return genReturnList("false", "Please specify a valid pod.");
+
+        if (add) {
+
+            // Make sure the gateway is valid
+            if (!NetUtils.isValidIp4(vlanGateway))
+                return genReturnList("false", "Please specify a valid gateway.");
+
+            // Make sure the netmask is valid
+            if (!NetUtils.isValidIp4(vlanNetmask))
+                return genReturnList("false", "Please specify a valid netmask.");
+
+            // Check if a vlan with the same vlanId already exists in the specified zone
+            if (getVlanDbId(zone, vlanId) != -1)
+                return genReturnList("false", "A VLAN with the specified VLAN ID already exists in zone " + zone + ".");
+
+            /*
+            // Check if another vlan in the same zone has the same subnet
+            String newVlanSubnet = NetUtils.getSubNet(vlanGateway, vlanNetmask);
+            List<VlanVO> vlans = _vlanDao.findByZone(zoneId);
+            for (VlanVO vlan : vlans) {
+                String currentVlanSubnet = NetUtils.getSubNet(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                if (newVlanSubnet.equals(currentVlanSubnet))
+                    return genReturnList("false", "The VLAN with ID " + vlan.getVlanId() + " in zone " + zone + " has the same subnet. Please specify a different gateway/netmask.");
+            }
+             */
+
+            // Everything was fine, so persist the VLAN
+            saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange, networkId, physicalNetworkDbId);
+            if (podId != null) {
+                long vlanDbId = getVlanDbId(zone, vlanId);
+                String sql = "INSERT INTO `cloud`.`pod_vlan_map` (pod_id, vlan_db_id) " + "VALUES (?,?)";
+                String errorMsg =  "Failed to save pod_vlan_map due to exception vlanDbId=" + vlanDbId + ", podId=" + podId + ". Please contact Cloud Support.";
+                TransactionLegacy txn = TransactionLegacy.open("saveSQL");
+                try ( PreparedStatement stmt = txn.prepareAutoCloseStatement(sql); ) {
+                        stmt.setString(1, podId.toString());
+                        stmt.setString(2, String.valueOf(vlanDbId));
+                        stmt.executeUpdate();
+                    } catch (SQLException ex) {
+                        System.out.println("SQL Exception: " + ex.getMessage());
+                        printError(errorMsg);
+                    }
+            }
+
+            return genReturnList("true", "Successfully added VLAN.");
+
+        } else {
+            return genReturnList("false", "That operation is not suppored.");
+        }
+
+        /*
+        else {
+
+            // Check if a VLAN actually exists in the specified zone
+            long vlanDbId = getVlanDbId(zone, vlanId);
+            if (vlanDbId == -1)
+                return genReturnList("false", "A VLAN with ID " + vlanId + " does not exist in zone " + zone);
+
+            // Check if there are any public IPs that are in the specified vlan.
+            List<IPAddressVO> ips = _publicIpAddressDao.listByVlanDbId(vlanDbId);
+            if (ips.size() != 0)
+                return genReturnList("false", "Please delete all IP addresses that are in VLAN " + vlanId + " before deleting the VLAN.");
+
+            // Delete the vlan
+            _vlanDao.delete(vlanDbId);
+
+            return genReturnList("true", "Successfully deleted VLAN.");
+        }
+         */
+    }
+
+    @DB
+    public void saveZone(boolean printOutput, long id, String name, String dns1, String dns2, String dns3, String dns4, String guestNetworkCidr, String networkType) {
+
+        if (printOutput)
+            System.out.println("Saving zone, please wait...");
+
+        String columns = null;
+        String values = null;
+
+        if (id != -1) {
+            columns = "(id, name";
+            values = "('" + id + "','" + name + "'";
+        } else {
+            columns = "(name";
+            values = "('" + name + "'";
+        }
+
+        if (dns1 != null) {
+            columns += ", dns1";
+            values += ",'" + dns1 + "'";
+        }
+
+        if (dns2 != null) {
+            columns += ", dns2";
+            values += ",'" + dns2 + "'";
+        }
+
+        if (dns3 != null) {
+            columns += ", internal_dns1";
+            values += ",'" + dns3 + "'";
+        }
+
+        if (dns4 != null) {
+            columns += ", internal_dns2";
+            values += ",'" + dns4 + "'";
+        }
+
+        if (guestNetworkCidr != null) {
+            columns += ", guest_network_cidr";
+            values += ",'" + guestNetworkCidr + "'";
+        }
+
+        if (networkType != null) {
+            columns += ", networktype";
+            values += ",'" + networkType + "'";
+        }
+
+        columns += ", uuid";
+        values += ", UUID()";
+
+        columns += ")";
+        values += ")";
+
+        String sql = "INSERT INTO `cloud`.`data_center` " + columns + " VALUES " + values;
+
+        DatabaseConfig.saveSQL(sql, "Failed to save zone due to exception. Please contact Cloud Support.");
+
+        if (printOutput)
+            System.out.println("Successfully saved zone.");
+    }
+
+    @DB
+    public void savePhysicalNetwork(boolean printOutput, long id, long dcId, int vnetStart, int vnetEnd) {
+
+        if (printOutput)
+            System.out.println("Saving physical network, please wait...");
+
+        String columns = null;
+        String values = null;
+
+        columns = "(id ";
+        values = "('" + id + "'";
+
+        columns += ", name ";
+        values += ",'physical network'";
+
+        columns += ", data_center_id ";
+        values += ",'" + dcId + "'";
+
+        //save vnet information
+        columns += ", vnet";
+        values += ",'" + vnetStart + "-" + vnetEnd + "'";
+
+        columns += ", state";
+        values += ", 'Enabled'";
+
+        columns += ", uuid";
+        values += ", UUID()";
+
+        columns += ")";
+        values += ")";
+
+        String sql = "INSERT INTO `cloud`.`physical_network` " + columns + " VALUES " + values;
+
+        DatabaseConfig.saveSQL(sql, "Failed to save physical network due to exception. Please contact Cloud Support.");
+
+        // Hardcode the vnet range to be the full range
+        int begin = 0x64;
+        int end = 64000;
+
+        // If vnet arguments were passed in, use them
+        if (vnetStart != -1 && vnetEnd != -1) {
+            begin = vnetStart;
+            end = vnetEnd;
+        }
+
+        String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_id) VALUES ( ?, ?, ?)";
+
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet);
+            for (int i = begin; i <= end; i++) {
+                stmt.setString(1, Integer.toString(i));
+                stmt.setLong(2, dcId);
+                stmt.setLong(3, id);
+                stmt.addBatch();
+            }
+            stmt.executeBatch();
+        } catch (SQLException ex) {
+            printError("Error creating vnet for the physical network. Please contact Cloud Support.");
+        }
+
+        //add default traffic types
+
+        //get default Xen network labels
+        String defaultXenPrivateNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Management);
+        String defaultXenPublicNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Public);
+        String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage);
+        String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest);
+
+        String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` " + "(physical_network_id, traffic_type, xenserver_network_label) VALUES ( ?, ?, ?)";
+
+        try {
+            PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType);
+            for (TrafficType traffic : TrafficType.values()) {
+                if (traffic.equals(TrafficType.Control) || traffic.equals(TrafficType.Vpn) || traffic.equals(TrafficType.None)) {
+                    continue;
+                }
+                stmt.setLong(1, id);
+                stmt.setString(2, traffic.toString());
+                if (traffic.equals(TrafficType.Public)) {
+                    stmt.setString(3, defaultXenPublicNetworkLabel);
+                } else if (traffic.equals(TrafficType.Management)) {
+                    stmt.setString(3, defaultXenPrivateNetworkLabel);
+                } else if (traffic.equals(TrafficType.Storage)) {
+                    stmt.setString(3, defaultXenStorageNetworkLabel);
+                } else if (traffic.equals(TrafficType.Guest)) {
+                    stmt.setString(3, defaultXenGuestNetworkLabel);
+                }
+
+                stmt.addBatch();
+            }
+            stmt.executeBatch();
+        } catch (SQLException ex) {
+            printError("Error adding default traffic types for the physical network. Please contact Cloud Support.");
+        }
+
+        if (printOutput)
+            System.out.println("Successfully saved physical network.");
+    }
+
+    private String getDefaultXenNetworkLabel(TrafficType trafficType) {
+        String xenLabel = null;
+        String configName = null;
+        switch (trafficType) {
+            case Public:
+                configName = "xenserver.public.network.device";
+                break;
+            case Guest:
+                configName = "xenserver.guest.network.device";
+                break;
+            case Storage:
+                configName = "xenserver.storage.network.device1";
+                break;
+            case Management:
+                configName = "xenserver.private.network.device";
+                break;
+        }
+
+        if (configName != null) {
+            xenLabel = getConfiguredValue(configName);
+        }
+        return xenLabel;
+    }
+
+    public static String getConfiguredValue(String configName) {
+        return DatabaseConfig.getDatabaseValueString("SELECT value FROM `cloud`.`configuration` where name = \"" + configName + "\"", "value",
+            "Unable to start DB connection to read configuration. Please contact Cloud Support.");
+    }
+
+    public void deleteZone(String name) {
+        String sql = "DELETE FROM `cloud`.`data_center` WHERE name=\"" + name + "\"";
+        DatabaseConfig.saveSQL(sql, "Failed to delete zone due to exception. Please contact Cloud Support.");
+    }
+
+    public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange, long networkId,
+        long physicalNetworkId) {
+        String sql =
+            "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, ip4_range, network_id, physical_network_id) " + "VALUES ('" +
+                vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange + "','" + networkId + "','" + physicalNetworkId +
+                "')";
+        DatabaseConfig.saveSQL(sql, "Failed to save vlan due to exception. Please contact Cloud Support.");
+    }
+
+    public static long getPodId(String pod, String zone) {
+        long dcId = getZoneId(zone);
+        String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
+        String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
+        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
+    }
+
+    public static long getPodId(String pod, long dcId) {
+        String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\"";
+        String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support.";
+        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
+    }
+
+    public static long getZoneId(String zone) {
+        String selectSql = "SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\"";
+        String errorMsg = "Could not read zone ID from database. Please contact Cloud Support.";
+        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
+    }
+
+    public static long checkPhysicalNetwork(long physicalNetworkId) {
+        String selectSql = "SELECT * FROM `cloud`.`physical_network` WHERE id = \"" + physicalNetworkId + "\"";
+        String errorMsg = "Could not read physicalNetwork ID from database. Please contact Cloud Support.";
+        return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg);
+    }
+
+    @DB
+    public Vector<Long> getAllZoneIDs() {
+        Vector<Long> allZoneIDs = new Vector<Long>();
+
+        String selectSql = "SELECT id FROM data_center";
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        try {
+            PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql);
+            ResultSet rs = stmt.executeQuery();
+            while (rs.next()) {
+                Long dcId = rs.getLong("id");
+                allZoneIDs.add(dcId);
+            }
+        } catch (SQLException ex) {
+            System.out.println(ex.getMessage());
+            printError("There was an issue with reading zone IDs. Please contact Cloud Support.");
+            return null;
+        }
+
+        return allZoneIDs;
+    }
+
+    public static boolean validPod(String pod, String zone) {
+        return (getPodId(pod, zone) != -1);
+    }
+
+    public static boolean validZone(String zone) {
+        return (getZoneId(zone) != -1);
+    }
+
+    public static String getPodName(long podId, long dcId) {
+        return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`host_pod_ref` WHERE id=" + podId + " AND data_center_id=" + dcId, "name",
+            "Unable to start DB connection to read pod name. Please contact Cloud Support.");
+    }
+
+    public static String getZoneName(long dcId) {
+        return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE id=" + dcId, "name",
+            "Unable to start DB connection to read zone name. Please contact Cloud Support.");
+    }
+
+    private static void printError(String message) {
+        DatabaseConfig.printError(message);
+    }
+
+    private List<String> genReturnList(String success, String message) {
+        List<String> returnList = new ArrayList<String>();
+        returnList.add(0, success);
+        returnList.add(1, message);
+        return returnList;
+    }
+
+}
diff --git a/server/src/com/cloud/test/TestAppender.java b/server/src/main/java/com/cloud/test/TestAppender.java
similarity index 100%
rename from server/src/com/cloud/test/TestAppender.java
rename to server/src/main/java/com/cloud/test/TestAppender.java
diff --git a/server/src/com/cloud/usage/UsageServiceImpl.java b/server/src/main/java/com/cloud/usage/UsageServiceImpl.java
similarity index 100%
rename from server/src/com/cloud/usage/UsageServiceImpl.java
rename to server/src/main/java/com/cloud/usage/UsageServiceImpl.java
diff --git a/server/src/main/java/com/cloud/user/AccountManager.java b/server/src/main/java/com/cloud/user/AccountManager.java
new file mode 100644
index 0000000..de6dcca
--- /dev/null
+++ b/server/src/main/java/com/cloud/user/AccountManager.java
@@ -0,0 +1,190 @@
+// 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.user;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+/**
+ * AccountManager includes logic that deals with accounts, domains, and users.
+ *
+ */
+public interface AccountManager extends AccountService, Configurable {
+    /**
+     * Disables an account by accountId
+     * @return true if disable was successful, false otherwise
+     */
+    boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
+
+    boolean deleteAccount(AccountVO account, long callerUserId, Account caller);
+
+    Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId);
+
+    Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid);
+
+    /**
+     * Logs out a user
+     */
+    void logoutUser(long userId);
+
+    /**
+     * Authenticates a user when s/he logs in.
+     *
+     * @param username
+     *            required username for authentication
+     * @param password
+     *            password to use for authentication, can be null for single sign-on case
+     * @param domainId
+     *            id of domain where user with username resides
+     * @param requestParameters
+     *            the request parameters of the login request, which should contain timestamp of when the request signature is
+     *            made, and the signature itself in the single sign-on case
+     * @return a user object, null if the user failed to authenticate
+     */
+    UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters);
+
+    /**
+     * Locate a user by their apiKey
+     *
+     * @param apiKey
+     *            that was created for a particular user
+     * @return the user/account pair if one exact match was found, null otherwise
+     */
+    Pair<User, Account> findUserByApiKey(String apiKey);
+
+    boolean enableAccount(long accountId);
+
+    void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria);
+
+    void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria);
+
+    void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria);
+
+    void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts,
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation);
+
+    void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria);
+
+    /**
+     * Deletes a user by userId
+     *
+     * @param accountId
+     *            - id of the account do delete
+     *
+     * @return true if delete was successful, false otherwise
+     */
+    boolean deleteUserAccount(long accountId);
+
+    /**
+     * Updates an account
+     *
+     * @param cmd
+     *            - the parameter containing accountId or account nameand domainId
+     * @return updated account object
+     */
+    Account updateAccount(UpdateAccountCmd cmd);
+
+    /**
+     * Disables an account by accountName and domainId
+     * @param disabled
+     *            account if success
+     * @return true if disable was successful, false otherwise
+     */
+    Account disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
+
+    /**
+     * Enables an account by accountId
+     *
+     * @param accountName
+     *            - the enableAccount command defining the accountId to be deleted.
+     */
+    Account enableAccount(String accountName, Long domainId, Long accountId);
+
+    /**
+     * Deletes user by Id
+     */
+    boolean deleteUser(DeleteUserCmd deleteUserCmd);
+
+    /**
+     * moves a user to another account within the same domain
+     * @return true if the user was successfully moved
+     */
+    boolean moveUser(MoveUserCmd moveUserCmd);
+
+    @Override
+    UserAccount updateUser(UpdateUserCmd cmd);
+
+    /**
+     * Disables a user by userId
+     *
+     * @param userId
+     *            - the userId
+     * @return UserAccount object
+     */
+    UserAccount disableUser(long userId);
+
+    /**
+     * Enables a user
+     *
+     * @param userId
+     *            - the userId
+     * @return UserAccount object
+     */
+    UserAccount enableUser(long userId);
+
+    /**
+     * Locks an account by accountId. A locked account cannot access the API, but will still have running VMs/IP
+     * addresses
+     * allocated/etc.
+     *
+     * @param accountName
+     *            - the LockAccount command defining the accountId to be locked.
+     */
+    Account lockAccount(String accountName, Long domainId, Long accountId);
+
+    List<String> listAclGroupsByAccount(Long accountId);
+
+    public static final String MESSAGE_ADD_ACCOUNT_EVENT = "Message.AddAccount.Event";
+
+    public static final String MESSAGE_REMOVE_ACCOUNT_EVENT = "Message.RemoveAccount.Event";
+    public static final ConfigKey<Boolean> UseSecretKeyInResponse = new ConfigKey<Boolean>("Advanced", Boolean.class, "use.secret.key.in.response", "false",
+            "This parameter allows the users to enable or disable of showing secret key as a part of response for various APIs. By default it is set to false.", true);
+
+    boolean moveUser(long id, Long domainId, long accountId);
+}
diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
new file mode 100644
index 0000000..bda4cca
--- /dev/null
+++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
@@ -0,0 +1,2883 @@
+// 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.user;
+
+import java.net.InetAddress;
+import java.net.URLEncoder;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.QuerySelector;
+import org.apache.cloudstack.acl.Role;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.affinity.AffinityGroup;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
+import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceOwnerType;
+import com.cloud.configuration.ResourceCountVO;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.configuration.dao.ResourceLimitDao;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.ActionEvents;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.VpnUserVO;
+import com.cloud.network.as.AutoScaleManager;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.AccountGuestVlanMapVO;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.RemoteAccessVpnVO;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.security.SecurityGroupManager;
+import com.cloud.network.security.dao.SecurityGroupDao;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.projects.ProjectInvitationVO;
+import com.cloud.projects.ProjectManager;
+import com.cloud.projects.ProjectVO;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.region.ha.GlobalLoadBalancingRulesService;
+import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account.State;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.SSHKeyPairDao;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.ConstantTimeComparator;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.InstanceGroupVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.InstanceGroupDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager {
+    public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class);
+
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private ConfigurationDao _configDao;
+    @Inject
+    private ResourceCountDao _resourceCountDao;
+    @Inject
+    private UserDao _userDao;
+    @Inject
+    private InstanceGroupDao _vmGroupDao;
+    @Inject
+    private UserAccountDao _userAccountDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private UserVmDao _userVmDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private SecurityGroupDao _securityGroupDao;
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private SecurityGroupManager _networkGroupMgr;
+    @Inject
+    private NetworkOrchestrationService _networkMgr;
+    @Inject
+    private SnapshotManager _snapMgr;
+    @Inject
+    private VMSnapshotManager _vmSnapshotMgr;
+    @Inject
+    private VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    private UserVmManager _vmMgr;
+    @Inject
+    private TemplateManager _tmpltMgr;
+    @Inject
+    private ConfigurationManager _configMgr;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private RemoteAccessVpnDao _remoteAccessVpnDao;
+    @Inject
+    private RemoteAccessVpnService _remoteAccessVpnMgr;
+    @Inject
+    private VpnUserDao _vpnUser;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private DomainManager _domainMgr;
+    @Inject
+    private ProjectManager _projectMgr;
+    @Inject
+    private ProjectDao _projectDao;
+    @Inject
+    private AccountDetailsDao _accountDetailsDao;
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private ProjectAccountDao _projectAccountDao;
+    @Inject
+    private IPAddressDao _ipAddressDao;
+    @Inject
+    private VpcManager _vpcMgr;
+    @Inject
+    private Site2SiteVpnManager _vpnMgr;
+    @Inject
+    private AutoScaleManager _autoscaleMgr;
+    @Inject
+    private VolumeApiService volumeService;
+    @Inject
+    private AffinityGroupDao _affinityGroupDao;
+    @Inject
+    private AccountGuestVlanMapDao _accountGuestVlanMapDao;
+    @Inject
+    private DataCenterVnetDao _dataCenterVnetDao;
+    @Inject
+    private ResourceLimitService _resourceLimitMgr;
+    @Inject
+    private ResourceLimitDao _resourceLimitDao;
+    @Inject
+    private DedicatedResourceDao _dedicatedDao;
+    @Inject
+    private GlobalLoadBalancerRuleDao _gslbRuleDao;
+    @Inject
+    private SSHKeyPairDao _sshKeyPairDao;
+
+    private List<QuerySelector> _querySelectors;
+
+    @Inject
+    private MessageBus _messageBus;
+
+    @Inject
+    private GlobalLoadBalancingRulesService _gslbService;
+
+    private List<UserAuthenticator> _userAuthenticators;
+    protected List<UserAuthenticator> _userPasswordEncoders;
+
+    @Inject
+    private IpAddressManager _ipAddrMgr;
+
+    private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
+
+    private int _allowedLoginAttempts;
+
+    private UserVO _systemUser;
+    private AccountVO _systemAccount;
+
+    private List<SecurityChecker> _securityCheckers;
+    private int _cleanupInterval;
+
+    public List<UserAuthenticator> getUserAuthenticators() {
+        return _userAuthenticators;
+    }
+
+    public void setUserAuthenticators(List<UserAuthenticator> authenticators) {
+        _userAuthenticators = authenticators;
+    }
+
+    public List<UserAuthenticator> getUserPasswordEncoders() {
+        return _userPasswordEncoders;
+    }
+
+    public void setUserPasswordEncoders(List<UserAuthenticator> encoders) {
+        _userPasswordEncoders = encoders;
+    }
+
+    public List<SecurityChecker> getSecurityCheckers() {
+        return _securityCheckers;
+    }
+
+    public void setSecurityCheckers(List<SecurityChecker> securityCheckers) {
+        _securityCheckers = securityCheckers;
+    }
+
+    public List<QuerySelector> getQuerySelectors() {
+        return _querySelectors;
+    }
+
+    public void setQuerySelectors(List<QuerySelector> querySelectors) {
+        _querySelectors = querySelectors;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
+        if (_systemAccount == null) {
+            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        _systemUser = _userDao.findById(User.UID_SYSTEM);
+        if (_systemUser == null) {
+            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration(params);
+
+        String loginAttempts = configs.get(Config.IncorrectLoginAttemptsAllowed.key());
+        _allowedLoginAttempts = NumbersUtil.parseInt(loginAttempts, 5);
+
+        String value = configs.get(Config.AccountCleanupInterval.key());
+        _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
+
+        return true;
+    }
+
+    @Override
+    public UserVO getSystemUser() {
+        if (_systemUser == null) {
+            _systemUser = _userDao.findById(User.UID_SYSTEM);
+        }
+        return _systemUser;
+    }
+
+    @Override
+    public boolean start() {
+        _executor.scheduleAtFixedRate(new AccountCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public AccountVO getSystemAccount() {
+        if (_systemAccount == null) {
+            _systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM);
+        }
+        return _systemAccount;
+    }
+
+    @Override
+    public boolean isAdmin(Long accountId) {
+        if (accountId != null) {
+            AccountVO acct = _accountDao.findById(accountId);
+            if (acct == null) {
+                return false;  //account is deleted or does not exist
+            }
+            if ((isRootAdmin(accountId)) || (isDomainAdmin(accountId)) || (isResourceDomainAdmin(accountId))) {
+                return true;
+            } else if (acct.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) {
+                return true;
+            }
+
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isRootAdmin(Long accountId) {
+        if (accountId != null) {
+            AccountVO acct = _accountDao.findById(accountId);
+            if (acct == null) {
+                return false;  //account is deleted or does not exist
+            }
+            for (SecurityChecker checker : _securityCheckers) {
+                try {
+                    if (checker.checkAccess(acct, null, null, "SystemCapability")) {
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("Root Access granted to " + acct + " by " + checker.getName());
+                        }
+                        return true;
+                    }
+                } catch (PermissionDeniedException ex) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isDomainAdmin(Long accountId) {
+        if (accountId != null) {
+            AccountVO acct = _accountDao.findById(accountId);
+            if (acct == null) {
+                return false;  //account is deleted or does not exist
+            }
+            for (SecurityChecker checker : _securityCheckers) {
+                try {
+                    if (checker.checkAccess(acct, null, null, "DomainCapability")) {
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("DomainAdmin Access granted to " + acct + " by " + checker.getName());
+                        }
+                        return true;
+                    }
+                } catch (PermissionDeniedException ex) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isNormalUser(long accountId) {
+        AccountVO acct = _accountDao.findById(accountId);
+        if (acct != null && acct.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isResourceDomainAdmin(Long accountId) {
+        if (accountId != null) {
+            AccountVO acct = _accountDao.findById(accountId);
+            if (acct == null) {
+                return false;  //account is deleted or does not exist
+            }
+            for (SecurityChecker checker : _securityCheckers) {
+                try {
+                    if (checker.checkAccess(acct, null, null, "DomainResourceCapability")) {
+                        if (s_logger.isTraceEnabled()) {
+                            s_logger.trace("ResourceDomainAdmin Access granted to " + acct + " by " + checker.getName());
+                        }
+                        return true;
+                    }
+                } catch (PermissionDeniedException ex) {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean isInternalAccount(long accountId) {
+        Account account = _accountDao.findById(accountId);
+        if (account == null) {
+            return false;  //account is deleted or does not exist
+        }
+        if (isRootAdmin(accountId) || (account.getType() == Account.ACCOUNT_ID_SYSTEM)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void checkAccess(Account caller, Domain domain) throws PermissionDeniedException {
+        for (SecurityChecker checker : _securityCheckers) {
+            if (checker.checkAccess(caller, domain)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + caller + " to " + domain + " by " + checker.getName());
+                }
+                return;
+            }
+        }
+        throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + domain);
+    }
+
+    @Override
+    public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) {
+        checkAccess(caller, accessType, sameOwner, null, entities);
+    }
+
+    @Override
+    public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) {
+
+        //check for the same owner
+        Long ownerId = null;
+        ControlledEntity prevEntity = null;
+        if (sameOwner) {
+            for (ControlledEntity entity : entities) {
+                if (sameOwner) {
+                    if (ownerId == null) {
+                        ownerId = entity.getAccountId();
+                    } else if (ownerId.longValue() != entity.getAccountId()) {
+                        throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts");
+                    }
+                    prevEntity = entity;
+                }
+            }
+        }
+
+        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(caller.getId())) {
+            // no need to make permission checks if the system/root admin makes the call
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("No need to make permission check for System/RootAdmin account, returning true");
+            }
+            return;
+        }
+
+        HashMap<Long, List<ControlledEntity>> domains = new HashMap<Long, List<ControlledEntity>>();
+
+        for (ControlledEntity entity : entities) {
+            long domainId = entity.getDomainId();
+            if (entity.getAccountId() != -1 && domainId == -1) { // If account exists domainId should too so calculate
+                // it. This condition might be hit for templates or entities which miss domainId in their tables
+                Account account = ApiDBUtils.findAccountById(entity.getAccountId());
+                domainId = account != null ? account.getDomainId() : -1;
+            }
+            if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate) && !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry)
+                    && !(entity instanceof AffinityGroup)) {
+                List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
+                // for templates, we don't have to do cross domains check
+                if (toBeChecked == null) {
+                    toBeChecked = new ArrayList<ControlledEntity>();
+                    domains.put(domainId, toBeChecked);
+                }
+                toBeChecked.add(entity);
+            }
+            boolean granted = false;
+            for (SecurityChecker checker : _securityCheckers) {
+                if (checker.checkAccess(caller, entity, accessType, apiName)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
+                    }
+                    granted = true;
+                    break;
+                }
+            }
+
+            if (!granted) {
+                assert false : "How can all of the security checkers pass on checking this check: " + entity;
+            throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
+            }
+        }
+
+        for (Map.Entry<Long, List<ControlledEntity>> domain : domains.entrySet()) {
+            for (SecurityChecker checker : _securityCheckers) {
+                Domain d = _domainMgr.getDomain(domain.getKey());
+                if (d == null || d.getRemoved() != null) {
+                    throw new PermissionDeniedException("Domain is not found.", caller, domain.getValue());
+                }
+                try {
+                    checker.checkAccess(caller, d);
+                } catch (PermissionDeniedException e) {
+                    e.addDetails(caller, domain.getValue());
+                    throw e;
+                }
+            }
+        }
+
+        // check that resources belong to the same account
+
+    }
+
+    @Override
+    public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
+        // We just care for resource domain admin for now. He should be permitted to see only his zone.
+        if (isResourceDomainAdmin(caller.getAccountId())) {
+            if (zoneId == null) {
+                return getZoneIdForAccount(caller);
+            } else if (zoneId.compareTo(getZoneIdForAccount(caller)) != 0) {
+                throw new PermissionDeniedException("Caller " + caller + "is not allowed to access the zone " + zoneId);
+            } else {
+                return zoneId;
+            }
+        } else {
+            return zoneId;
+        }
+    }
+
+    private Long getZoneIdForAccount(Account account) {
+
+        // Currently just for resource domain admin
+        List<DataCenterVO> dcList = _dcDao.findZonesByDomainId(account.getDomainId());
+        if (dcList != null && dcList.size() != 0) {
+            return dcList.get(0).getId();
+        } else {
+            throw new CloudRuntimeException("Failed to find any private zone for Resource domain admin.");
+        }
+
+    }
+
+    @DB
+    public void updateLoginAttempts(final Long id, final int attempts, final boolean toDisable) {
+        try {
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    UserAccountVO user = null;
+                    user = _userAccountDao.lockRow(id, true);
+                    user.setLoginAttempts(attempts);
+                    if (toDisable) {
+                        user.setState(State.disabled.toString());
+                    }
+                    _userAccountDao.update(id, user);
+                }
+            });
+        } catch (Exception e) {
+            s_logger.error("Failed to update login attempts for user with id " + id);
+        }
+    }
+
+    private boolean doSetUserStatus(long userId, State state) {
+        UserVO userForUpdate = _userDao.createForUpdate();
+        userForUpdate.setState(state);
+        return _userDao.update(Long.valueOf(userId), userForUpdate);
+    }
+
+    @Override
+    public boolean enableAccount(long accountId) {
+        boolean success = false;
+        AccountVO acctForUpdate = _accountDao.createForUpdate();
+        acctForUpdate.setState(State.enabled);
+        acctForUpdate.setNeedsCleanup(false);
+        success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
+        return success;
+    }
+
+    protected boolean lockAccount(long accountId) {
+        boolean success = false;
+        Account account = _accountDao.findById(accountId);
+        if (account != null) {
+            if (account.getState().equals(State.locked)) {
+                return true; // already locked, no-op
+            } else if (account.getState().equals(State.enabled)) {
+                AccountVO acctForUpdate = _accountDao.createForUpdate();
+                acctForUpdate.setState(State.locked);
+                success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Attempting to lock a non-enabled account, current state is " + account.getState() + " (accountId: " + accountId + "), locking failed.");
+                }
+            }
+        } else {
+            s_logger.warn("Failed to lock account " + accountId + ", account not found.");
+        }
+        return success;
+    }
+
+    @Override
+    public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) {
+        long accountId = account.getId();
+
+        // delete the account record
+        if (!_accountDao.remove(accountId)) {
+            s_logger.error("Unable to delete account " + accountId);
+            return false;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Removed account " + accountId);
+        }
+
+        return cleanupAccount(account, callerUserId, caller);
+    }
+
+    protected boolean cleanupAccount(AccountVO account, long callerUserId, Account caller) {
+        long accountId = account.getId();
+        boolean accountCleanupNeeded = false;
+
+        try {
+            // cleanup the users from the account
+            List<UserVO> users = _userDao.listByAccount(accountId);
+            for (UserVO user : users) {
+                if (!_userDao.remove(user.getId())) {
+                    s_logger.error("Unable to delete user: " + user + " as a part of account " + account + " cleanup");
+                    accountCleanupNeeded = true;
+                }
+            }
+
+            // delete global load balancer rules for the account.
+            List<org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(accountId);
+            if (gslbRules != null && !gslbRules.isEmpty()) {
+                _gslbService.revokeAllGslbRulesForAccount(caller, accountId);
+            }
+
+            // delete the account from project accounts
+            _projectAccountDao.removeAccountFromProjects(accountId);
+
+            if (account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
+                // delete the account from group
+                _messageBus.publish(_name, MESSAGE_REMOVE_ACCOUNT_EVENT, PublishScope.LOCAL, accountId);
+            }
+
+            // delete all vm groups belonging to accont
+            List<InstanceGroupVO> groups = _vmGroupDao.listByAccountId(accountId);
+            for (InstanceGroupVO group : groups) {
+                if (!_vmMgr.deleteVmGroup(group.getId())) {
+                    s_logger.error("Unable to delete group: " + group.getId());
+                    accountCleanupNeeded = true;
+                }
+            }
+
+            // Delete the snapshots dir for the account. Have to do this before destroying the VMs.
+            boolean success = _snapMgr.deleteSnapshotDirsForAccount(accountId);
+            if (success) {
+                s_logger.debug("Successfully deleted snapshots directories for all volumes under account " + accountId + " across all zones");
+            }
+
+            // clean up templates
+            List<VMTemplateVO> userTemplates = _templateDao.listByAccountId(accountId);
+            boolean allTemplatesDeleted = true;
+            for (VMTemplateVO template : userTemplates) {
+                if (template.getRemoved() == null) {
+                    try {
+                        allTemplatesDeleted = _tmpltMgr.delete(callerUserId, template.getId(), null);
+                    } catch (Exception e) {
+                        s_logger.warn("Failed to delete template while removing account: " + template.getName() + " due to: ", e);
+                        allTemplatesDeleted = false;
+                    }
+                }
+            }
+
+            if (!allTemplatesDeleted) {
+                s_logger.warn("Failed to delete templates while removing account id=" + accountId);
+                accountCleanupNeeded = true;
+            }
+
+            // Destroy VM Snapshots
+            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(Long.valueOf(accountId));
+            for (VMSnapshot vmSnapshot : vmSnapshots) {
+                try {
+                    _vmSnapshotMgr.deleteVMSnapshot(vmSnapshot.getId());
+                } catch (Exception e) {
+                    s_logger.debug("Failed to cleanup vm snapshot " + vmSnapshot.getId() + " due to " + e.toString());
+                }
+            }
+
+            // Destroy the account's VMs
+            List<UserVmVO> vms = _userVmDao.listByAccountId(accountId);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Expunging # of vms (accountId=" + accountId + "): " + vms.size());
+            }
+
+            for (UserVmVO vm : vms) {
+                if (vm.getState() != VirtualMachine.State.Destroyed && vm.getState() != VirtualMachine.State.Expunging) {
+                    try {
+                        _vmMgr.destroyVm(vm.getId(), false);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        s_logger.warn("Failed destroying instance " + vm.getUuid() + " as part of account deletion.");
+                    }
+                }
+                // no need to catch exception at this place as expunging vm
+                // should pass in order to perform further cleanup
+                if (!_vmMgr.expunge(vm, callerUserId, caller)) {
+                    s_logger.error("Unable to expunge vm: " + vm.getId());
+                    accountCleanupNeeded = true;
+                }
+            }
+
+            // Mark the account's volumes as destroyed
+            List<VolumeVO> volumes = _volumeDao.findDetachedByAccount(accountId);
+            for (VolumeVO volume : volumes) {
+                if (!volume.getState().equals(Volume.State.Destroy)) {
+                    try {
+                        volumeService.deleteVolume(volume.getId(), caller);
+                    } catch (Exception ex) {
+                        s_logger.warn("Failed to cleanup volumes as a part of account id=" + accountId + " cleanup due to Exception: ", ex);
+                        accountCleanupNeeded = true;
+                    }
+                }
+            }
+
+            // delete remote access vpns and associated users
+            List<RemoteAccessVpnVO> remoteAccessVpns = _remoteAccessVpnDao.findByAccount(accountId);
+            List<VpnUserVO> vpnUsers = _vpnUser.listByAccount(accountId);
+
+            for (VpnUserVO vpnUser : vpnUsers) {
+                _remoteAccessVpnMgr.removeVpnUser(accountId, vpnUser.getUsername(), caller);
+            }
+
+            try {
+                for (RemoteAccessVpnVO vpn : remoteAccessVpns) {
+                    _remoteAccessVpnMgr.destroyRemoteAccessVpnForIp(vpn.getServerAddressId(), caller, false);
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to cleanup remote access vpn resources as a part of account id=" + accountId + " cleanup due to Exception: ", ex);
+                accountCleanupNeeded = true;
+            }
+
+            // Cleanup security groups
+            int numRemoved = _securityGroupDao.removeByAccountId(accountId);
+            s_logger.info("deleteAccount: Deleted " + numRemoved + " network groups for account " + accountId);
+
+            // Cleanup affinity groups
+            int numAGRemoved = _affinityGroupDao.removeByAccountId(accountId);
+            s_logger.info("deleteAccount: Deleted " + numAGRemoved + " affinity groups for account " + accountId);
+
+            // Delete all the networks
+            boolean networksDeleted = true;
+            s_logger.debug("Deleting networks for account " + account.getId());
+            List<NetworkVO> networks = _networkDao.listByOwner(accountId);
+            if (networks != null) {
+                for (NetworkVO network : networks) {
+
+                    ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller);
+
+                    if (!_networkMgr.destroyNetwork(network.getId(), context, false)) {
+                        s_logger.warn("Unable to destroy network " + network + " as a part of account id=" + accountId + " cleanup.");
+                        accountCleanupNeeded = true;
+                        networksDeleted = false;
+                    } else {
+                        s_logger.debug("Network " + network.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup.");
+                    }
+                }
+            }
+
+            // Delete all VPCs
+            boolean vpcsDeleted = true;
+            s_logger.debug("Deleting vpcs for account " + account.getId());
+            List<? extends Vpc> vpcs = _vpcMgr.getVpcsForAccount(account.getId());
+            for (Vpc vpc : vpcs) {
+
+                if (!_vpcMgr.destroyVpc(vpc, caller, callerUserId)) {
+                    s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup.");
+                    accountCleanupNeeded = true;
+                    vpcsDeleted = false;
+                } else {
+                    s_logger.debug("VPC " + vpc.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup.");
+                }
+            }
+
+            if (networksDeleted && vpcsDeleted) {
+                // release ip addresses belonging to the account
+                List<? extends IpAddress> ipsToRelease = _ipAddressDao.listByAccount(accountId);
+                for (IpAddress ip : ipsToRelease) {
+                    s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup");
+                    if (!_ipAddrMgr.disassociatePublicIpAddress(ip.getId(), callerUserId, caller)) {
+                        s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup");
+                        accountCleanupNeeded = true;
+                    }
+                }
+            }
+
+            // Delete Site 2 Site VPN customer gateway
+            s_logger.debug("Deleting site-to-site VPN customer gateways for account " + accountId);
+            if (!_vpnMgr.deleteCustomerGatewayByAccount(accountId)) {
+                s_logger.warn("Fail to delete site-to-site VPN customer gateways for account " + accountId);
+            }
+
+            // Delete autoscale resources if any
+            try {
+                _autoscaleMgr.cleanUpAutoScaleResources(accountId);
+            } catch (CloudRuntimeException ex) {
+                s_logger.warn("Failed to cleanup AutoScale resources as a part of account id=" + accountId + " cleanup due to exception:", ex);
+                accountCleanupNeeded = true;
+            }
+
+            // release account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned
+            // up successfully
+            if (networksDeleted) {
+                if (!_configMgr.releaseAccountSpecificVirtualRanges(accountId)) {
+                    accountCleanupNeeded = true;
+                } else {
+                    s_logger.debug("Account specific Virtual IP ranges " + " are successfully released as a part of account id=" + accountId + " cleanup.");
+                }
+            }
+
+            // release account specific guest vlans
+            List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId);
+            for (AccountGuestVlanMapVO map : maps) {
+                _dataCenterVnetDao.releaseDedicatedGuestVlans(map.getId());
+            }
+            int vlansReleased = _accountGuestVlanMapDao.removeByAccountId(accountId);
+            s_logger.info("deleteAccount: Released " + vlansReleased + " dedicated guest vlan ranges from account " + accountId);
+
+            // release account specific acquired portable IP's. Since all the portable IP's must have been already
+            // disassociated with VPC/guest network (due to deletion), so just mark portable IP as free.
+            List<? extends IpAddress> ipsToRelease = _ipAddressDao.listByAccount(accountId);
+            for (IpAddress ip : ipsToRelease) {
+                if (ip.isPortable()) {
+                    s_logger.debug("Releasing portable ip " + ip + " as a part of account id=" + accountId + " cleanup");
+                    _ipAddrMgr.releasePortableIpAddress(ip.getId());
+                }
+            }
+
+            // release dedication if any
+            List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByAccountId(accountId);
+            if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
+                s_logger.debug("Releasing dedicated resources for account " + accountId);
+                for (DedicatedResourceVO dr : dedicatedResources) {
+                    if (!_dedicatedDao.remove(dr.getId())) {
+                        s_logger.warn("Fail to release dedicated resources for account " + accountId);
+                    }
+                }
+            }
+
+            // Updating and deleting the resourceLimit and resourceCount should be the last step in cleanupAccount
+// process.
+            // Update resource count for this account and for parent domains.
+            List<ResourceCountVO> resourceCounts = _resourceCountDao.listByOwnerId(accountId, ResourceOwnerType.Account);
+            for (ResourceCountVO resourceCount : resourceCounts) {
+                _resourceLimitMgr.decrementResourceCount(accountId, resourceCount.getType(), resourceCount.getCount());
+            }
+
+            // Delete resource count and resource limits entries set for this account (if there are any).
+            _resourceCountDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
+            _resourceLimitDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account);
+
+            // Delete ssh keypairs
+            List<SSHKeyPairVO> sshkeypairs = _sshKeyPairDao.listKeyPairs(accountId, account.getDomainId());
+            for (SSHKeyPairVO keypair : sshkeypairs) {
+                _sshKeyPairDao.remove(keypair.getId());
+            }
+            return true;
+        } catch (Exception ex) {
+            s_logger.warn("Failed to cleanup account " + account + " due to ", ex);
+            accountCleanupNeeded = true;
+            return true;
+        } finally {
+            s_logger.info("Cleanup for account " + account.getId() + (accountCleanupNeeded ? " is needed." : " is not needed."));
+            if (accountCleanupNeeded) {
+                _accountDao.markForCleanup(accountId);
+            } else {
+                account.setNeedsCleanup(false);
+                _accountDao.update(accountId, account);
+            }
+        }
+    }
+
+    @Override
+    public boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
+        boolean success = false;
+        if (accountId <= 2) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("disableAccount -- invalid account id: " + accountId);
+            }
+            return false;
+        }
+
+        AccountVO account = _accountDao.findById(accountId);
+        if ((account == null) || (account.getState().equals(State.disabled) && !account.getNeedsCleanup())) {
+            success = true;
+        } else {
+            AccountVO acctForUpdate = _accountDao.createForUpdate();
+            acctForUpdate.setState(State.disabled);
+            success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
+
+            if (success) {
+                boolean disableAccountResult = false;
+                try {
+                    disableAccountResult = doDisableAccount(accountId);
+                } finally {
+                    if (!disableAccountResult) {
+                        s_logger.warn("Failed to disable account " + account + " resources as a part of disableAccount call, marking the account for cleanup");
+                        _accountDao.markForCleanup(accountId);
+                    } else {
+                        acctForUpdate = _accountDao.createForUpdate();
+                        account.setNeedsCleanup(false);
+                        _accountDao.update(accountId, account);
+                    }
+                }
+            }
+        }
+        return success;
+    }
+
+    private boolean doDisableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
+        List<VMInstanceVO> vms = _vmDao.listByAccountId(accountId);
+        boolean success = true;
+        for (VMInstanceVO vm : vms) {
+            try {
+                try {
+                    _itMgr.advanceStop(vm.getUuid(), false);
+                } catch (OperationTimedoutException ote) {
+                    s_logger.warn("Operation for stopping vm timed out, unable to stop vm " + vm.getHostName(), ote);
+                    success = false;
+                }
+            } catch (AgentUnavailableException aue) {
+                s_logger.warn("Agent running on host " + vm.getHostId() + " is unavailable, unable to stop vm " + vm.getHostName(), aue);
+                success = false;
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
+        @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
+    public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName,
+            final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID) {
+
+        return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, roleId, domainId, networkDomain, details, accountUUID, userUUID,
+                User.Source.UNKNOWN);
+    }
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API commands /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    @DB
+    @ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
+        @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
+    public UserAccount createUserAccount(final String userName, final String password, final String firstName,
+                                         final String lastName, final String email, final String timezone,
+                                         String accountName, final short accountType, final Long roleId, Long domainId,
+                                         final String networkDomain, final Map<String, String> details,
+                                         String accountUUID, final String userUUID,
+            final User.Source source) {
+
+        if (accountName == null) {
+            accountName = userName;
+        }
+        if (domainId == null) {
+            domainId = Domain.ROOT_DOMAIN;
+        }
+
+        if (StringUtils.isEmpty(userName)) {
+            throw new InvalidParameterValueException("Username is empty");
+        }
+
+        if (StringUtils.isEmpty(firstName)) {
+            throw new InvalidParameterValueException("Firstname is empty");
+        }
+
+        if (StringUtils.isEmpty(lastName)) {
+            throw new InvalidParameterValueException("Lastname is empty");
+        }
+
+        // Validate domain
+        Domain domain = _domainMgr.getDomain(domainId);
+        if (domain == null) {
+            throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account");
+        }
+
+        // Check permissions
+        checkAccess(getCurrentCallingAccount(), domain);
+
+        if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
+            throw new InvalidParameterValueException("The user " + userName + " already exists in domain " + domainId);
+        }
+
+        if (networkDomain != null && networkDomain.length() > 0) {
+            if (!NetUtils.verifyDomainName(networkDomain)) {
+                throw new InvalidParameterValueException(
+                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+            }
+        }
+
+        final String accountNameFinal = accountName;
+        final Long domainIdFinal = domainId;
+        final String accountUUIDFinal = accountUUID;
+        Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<Pair<Long, Account>>() {
+            @Override
+            public Pair<Long, Account> doInTransaction(TransactionStatus status) {
+                // create account
+                String accountUUID = accountUUIDFinal;
+                if (accountUUID == null) {
+                    accountUUID = UUID.randomUUID().toString();
+                }
+                AccountVO account = createAccount(accountNameFinal, accountType, roleId, domainIdFinal, networkDomain, details, accountUUID);
+                long accountId = account.getId();
+
+                // create the first user for the account
+                UserVO user = createUser(accountId, userName, password, firstName, lastName, email, timezone, userUUID, source);
+
+                if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                    // set registration token
+                    byte[] bytes = (domainIdFinal + accountNameFinal + userName + System.currentTimeMillis()).getBytes();
+                    String registrationToken = UUID.nameUUIDFromBytes(bytes).toString();
+                    user.setRegistrationToken(registrationToken);
+                }
+
+                return new Pair<Long, Account>(user.getId(), account);
+            }
+        });
+
+        long userId = pair.first();
+        Account account = pair.second();
+
+        // create correct account and group association based on accountType
+        if (accountType != Account.ACCOUNT_TYPE_PROJECT) {
+            Map<Long, Long> accountGroupMap = new HashMap<Long, Long>();
+            accountGroupMap.put(account.getId(), new Long(accountType + 1));
+            _messageBus.publish(_name, MESSAGE_ADD_ACCOUNT_EVENT, PublishScope.LOCAL, accountGroupMap);
+        }
+
+        CallContext.current().putContextParameter(Account.class, account.getUuid());
+
+        // check success
+        return _userAccountDao.findById(userId);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
+    public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
+            User.Source source) {
+        // default domain to ROOT if not specified
+        if (domainId == null) {
+            domainId = Domain.ROOT_DOMAIN;
+        }
+
+        Domain domain = _domainMgr.getDomain(domainId);
+        if (domain == null) {
+            throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user");
+        } else if (domain.getState().equals(Domain.State.Inactive)) {
+            throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted");
+        }
+
+        checkAccess(getCurrentCallingAccount(), domain);
+
+        Account account = _accountDao.findEnabledAccount(accountName, domainId);
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user");
+        }
+
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("Account id : " + account.getId() + " is a system account, can't add a user to it");
+        }
+
+        if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
+            throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId);
+        }
+        UserVO user = null;
+        user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source);
+        return user;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
+    public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID) {
+
+        return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "Updating User")
+    public UserAccount updateUser(UpdateUserCmd updateUserCmd) {
+        UserVO user = retrieveAndValidateUser(updateUserCmd);
+        s_logger.debug("Updating user with Id: " + user.getUuid());
+
+        validateAndUpdateApiAndSecretKeyIfNeeded(updateUserCmd, user);
+        Account account = retrieveAndValidateAccount(user);
+
+        validateAndUpdateFirstNameIfNeeded(updateUserCmd, user);
+        validateAndUpdateLastNameIfNeeded(updateUserCmd, user);
+        validateAndUpdateUsernameIfNeeded(updateUserCmd, user, account);
+
+        validateUserPasswordAndUpdateIfNeeded(updateUserCmd.getPassword(), user, updateUserCmd.getCurrentPassword());
+        String email = updateUserCmd.getEmail();
+        if (StringUtils.isNotBlank(email)) {
+            user.setEmail(email);
+        }
+        String timezone = updateUserCmd.getTimezone();
+        if (StringUtils.isNotBlank(timezone)) {
+            user.setTimezone(timezone);
+        }
+        _userDao.update(user.getId(), user);
+        return _userAccountDao.findById(user.getId());
+    }
+
+    /**
+     * Updates the password in the user POJO if needed. If no password is provided, then the password is not updated.
+     * The following validations are executed if 'password' is not null. Admins (root admins or domain admins) can execute password updates without entering the current password.
+     * <ul>
+     *  <li> If 'password' is blank, we throw an {@link InvalidParameterValueException};
+     *  <li> If 'current password' is not provided and user is not an Admin, we throw an {@link InvalidParameterValueException};
+     *  <li> If a normal user is calling this method, we use {@link #validateCurrentPassword(UserVO, String)} to check if the provided old password matches the database one;
+     * </ul>
+     *
+     * If all checks pass, we encode the given password with the most preferable password mechanism given in {@link #_userPasswordEncoders}.
+     */
+    protected void validateUserPasswordAndUpdateIfNeeded(String newPassword, UserVO user, String currentPassword) {
+        if (newPassword == null) {
+            s_logger.trace("No new password to update for user: " + user.getUuid());
+            return;
+        }
+        if (StringUtils.isBlank(newPassword)) {
+            throw new InvalidParameterValueException("Password cannot be empty or blank.");
+        }
+        Account callingAccount = getCurrentCallingAccount();
+        boolean isRootAdminExecutingPasswordUpdate = callingAccount.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(callingAccount.getId());
+        boolean isDomainAdmin = isDomainAdmin(callingAccount.getId());
+        boolean isAdmin = isDomainAdmin || isRootAdminExecutingPasswordUpdate;
+        if (isAdmin) {
+            s_logger.trace(String.format("Admin account [uuid=%s] executing password update for user [%s] ", callingAccount.getUuid(), user.getUuid()));
+        }
+        if (!isAdmin && StringUtils.isBlank(currentPassword)) {
+            throw new InvalidParameterValueException("To set a new password the current password must be provided.");
+        }
+        if (CollectionUtils.isEmpty(_userPasswordEncoders)) {
+            throw new CloudRuntimeException("No user authenticators configured!");
+        }
+        if (!isAdmin) {
+            validateCurrentPassword(user, currentPassword);
+        }
+        UserAuthenticator userAuthenticator = _userPasswordEncoders.get(0);
+        String newPasswordEncoded = userAuthenticator.encode(newPassword);
+        user.setPassword(newPasswordEncoded);
+    }
+
+    /**
+     * Iterates over all configured user authenticators and tries to authenticate the user using the current password.
+     * If the user is authenticated with success, we have nothing else to do here; otherwise, an {@link InvalidParameterValueException} is thrown.
+     */
+    protected void validateCurrentPassword(UserVO user, String currentPassword) {
+        AccountVO userAccount = _accountDao.findById(user.getAccountId());
+        boolean currentPasswordMatchesDataBasePassword = false;
+        for (UserAuthenticator userAuthenticator : _userPasswordEncoders) {
+            Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = userAuthenticator.authenticate(user.getUsername(), currentPassword, userAccount.getDomainId(), null);
+            if (authenticationResult == null) {
+                s_logger.trace(String.format("Authenticator [%s] is returning null for the authenticate mehtod.", userAuthenticator.getClass()));
+                continue;
+            }
+            if (BooleanUtils.toBoolean(authenticationResult.first())) {
+                s_logger.debug(String.format("User [id=%s] re-authenticated [authenticator=%s] during password update.", user.getUuid(), userAuthenticator.getName()));
+                currentPasswordMatchesDataBasePassword = true;
+                break;
+            }
+        }
+        if (!currentPasswordMatchesDataBasePassword) {
+            throw new InvalidParameterValueException("Current password is incorrect.");
+        }
+    }
+
+    /**
+     * Validates the user 'username' if provided. The 'username' cannot be blank (when provided).
+     * <ul>
+     *  <li> If the 'username' is not provided, we do not update it (setting to null) in the User POJO.
+     *  <li> If the 'username' is blank, we throw an {@link InvalidParameterValueException}.
+     *  <li> The username must be unique in each domain. Therefore, if there is already another user with the same username, an {@link InvalidParameterValueException} is thrown.
+     * </ul>
+     */
+    protected void validateAndUpdateUsernameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user, Account account) {
+        String userName = updateUserCmd.getUsername();
+        if (userName == null) {
+            return;
+        }
+        if (StringUtils.isBlank(userName)) {
+            throw new InvalidParameterValueException("Username cannot be empty.");
+        }
+        List<UserVO> duplicatedUsers = _userDao.findUsersByName(userName);
+        for (UserVO duplicatedUser : duplicatedUsers) {
+            if (duplicatedUser.getId() == user.getId()) {
+                continue;
+            }
+            Account duplicatedUserAccountWithUserThatHasTheSameUserName = _accountDao.findById(duplicatedUser.getAccountId());
+            if (duplicatedUserAccountWithUserThatHasTheSameUserName.getDomainId() == account.getDomainId()) {
+                DomainVO domain = _domainDao.findById(duplicatedUserAccountWithUserThatHasTheSameUserName.getDomainId());
+                throw new InvalidParameterValueException(String.format("Username [%s] already exists in domain [id=%s,name=%s]", duplicatedUser.getUsername(), domain.getUuid(), domain.getName()));
+            }
+        }
+        user.setUsername(userName);
+    }
+
+    /**
+     * Validates the user 'lastName' if provided. The 'lastName' cannot be blank (when provided).
+     * <ul>
+     *  <li> If the 'lastName' is not provided, we do not update it (setting to null) in the User POJO.
+     *  <li> If the 'lastName' is blank, we throw an {@link InvalidParameterValueException}.
+     * </ul>
+     */
+    protected void validateAndUpdateLastNameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
+        String lastName = updateUserCmd.getLastname();
+        if (lastName != null) {
+            if (StringUtils.isBlank(lastName)) {
+                throw new InvalidParameterValueException("Lastname cannot be empty.");
+            }
+
+            user.setLastname(lastName);
+        }
+    }
+
+    /**
+     * Validates the user 'firstName' if provided. The 'firstName' cannot be blank (when provided).
+     * <ul>
+     *  <li> If the 'firstName' is not provided, we do not update it (setting to null) in the User POJO.
+     *  <li> If the 'firstName' is blank, we throw an {@link InvalidParameterValueException}.
+     * </ul>
+     */
+    protected void validateAndUpdateFirstNameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
+        String firstName = updateUserCmd.getFirstname();
+        if (firstName != null) {
+            if (StringUtils.isBlank(firstName)) {
+                throw new InvalidParameterValueException("Firstname cannot be empty.");
+            }
+            user.setFirstname(firstName);
+        }
+    }
+
+    /**
+     * Searches an account for the given users. Then, we validate it as follows:
+     * <ul>
+     *  <li>If no account is found for the given user, we throw a {@link CloudRuntimeException}. There must be something wrong in the database for this case.
+     *  <li>If the account is of {@link Account#ACCOUNT_TYPE_PROJECT}, we throw an {@link InvalidParameterValueException}.
+     *  <li>If the account is of {@link Account#ACCOUNT_ID_SYSTEM}, we throw an {@link InvalidParameterValueException}.
+     * </ul>
+     *
+     * Afterwards, we check if the logged user has access to the user being updated via {@link #checkAccess(Account, AccessType, boolean, ControlledEntity...)}
+     */
+    protected Account retrieveAndValidateAccount(UserVO user) {
+        Account account = _accountDao.findById(user.getAccountId());
+        if (account == null) {
+            throw new CloudRuntimeException("Unable to find user account with ID: " + user.getAccountId());
+        }
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find user with ID: " + user.getUuid());
+        }
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("user UUID : " + user.getUuid() + " is a system account; update is not allowed.");
+        }
+        checkAccess(getCurrentCallingAccount(), AccessType.OperateEntry, true, account);
+        return account;
+    }
+
+    /**
+     * Returns the calling account using the method {@link CallContext#getCallingAccount()}.
+     * We are introducing this method to avoid using 'PowerMockRunner' in unit tests. Then, we can mock the calls to this method, which facilitates the development of test cases.
+     */
+    protected Account getCurrentCallingAccount() {
+        return CallContext.current().getCallingAccount();
+    }
+
+    /**
+     * Validates user API and Secret keys. If a new pair of keys is provided, we update them in the user POJO.
+     * <ul>
+     * <li>When updating the keys, it must be provided a pair (API and Secret keys); otherwise, an {@link InvalidParameterValueException} is thrown.
+     * <li>If a pair of keys is provided, we validate to see if there is an user already using the provided API key. If there is someone else using, we throw an {@link InvalidParameterValueException} because two users cannot have the same API key.
+     * </ul>
+     */
+    protected void validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
+        String apiKey = updateUserCmd.getApiKey();
+        String secretKey = updateUserCmd.getSecretKey();
+
+        boolean isApiKeyBlank = StringUtils.isBlank(apiKey);
+        boolean isSecretKeyBlank = StringUtils.isBlank(secretKey);
+        if (isApiKeyBlank ^ isSecretKeyBlank) {
+            throw new InvalidParameterValueException("Please provide a userApiKey/userSecretKey pair");
+        }
+        if (isApiKeyBlank && isSecretKeyBlank) {
+            return;
+        }
+        Pair<User, Account> apiKeyOwner = _accountDao.findUserAccountByApiKey(apiKey);
+        if (apiKeyOwner != null) {
+            User userThatHasTheProvidedApiKey = apiKeyOwner.first();
+            if (userThatHasTheProvidedApiKey.getId() != user.getId()) {
+                throw new InvalidParameterValueException(String.format("The API key [%s] already exists in the system. Please provide a unique key.", apiKey));
+            }
+        }
+        user.setApiKey(apiKey);
+        user.setSecretKey(secretKey);
+    }
+
+    /**
+     * Searches for a user with the given userId. If no user is found we throw an {@link InvalidParameterValueException}.
+     */
+    protected UserVO retrieveAndValidateUser(UpdateUserCmd updateUserCmd) {
+        Long userId = updateUserCmd.getId();
+
+        UserVO user = _userDao.getUser(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("Unable to find user with id: " + userId);
+        }
+        return user;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_DISABLE, eventDescription = "disabling User", async = true)
+    public UserAccount disableUser(long userId) {
+        Account caller = getCurrentCallingAccount();
+
+        // Check if user exists in the system
+        User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+
+        Account account = _accountDao.findById(user.getAccountId());
+        if (account == null) {
+            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
+        }
+
+        // don't allow disabling user belonging to project's account
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+
+        // If the user is a System user, return an error
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new InvalidParameterValueException("User id : " + userId + " is a system user, disabling is not allowed");
+        }
+
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        boolean success = doSetUserStatus(userId, State.disabled);
+        if (success) {
+
+            CallContext.current().putContextParameter(User.class, user.getUuid());
+
+            // user successfully disabled
+            return _userAccountDao.findById(userId);
+        } else {
+            throw new CloudRuntimeException("Unable to disable user " + userId);
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User")
+    public UserAccount enableUser(final long userId) {
+
+        Account caller = getCurrentCallingAccount();
+
+        // Check if user exists in the system
+        final User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+
+        Account account = _accountDao.findById(user.getAccountId());
+        if (account == null) {
+            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
+        }
+
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find active user by id " + userId);
+        }
+
+        // If the user is a System user, return an error
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new InvalidParameterValueException("User id : " + userId + " is a system user, enabling is not allowed");
+        }
+
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        boolean success = Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                boolean success = doSetUserStatus(userId, State.enabled);
+
+                // make sure the account is enabled too
+                success = success && enableAccount(user.getAccountId());
+
+                return success;
+            }
+        });
+
+        if (success) {
+            // whenever the user is successfully enabled, reset the login attempts to zero
+            updateLoginAttempts(userId, 0, false);
+
+            CallContext.current().putContextParameter(User.class, user.getUuid());
+
+            return _userAccountDao.findById(userId);
+        } else {
+            throw new CloudRuntimeException("Unable to enable user " + userId);
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_LOCK, eventDescription = "locking User")
+    public UserAccount lockUser(long userId) {
+        Account caller = getCurrentCallingAccount();
+
+        // Check if user with id exists in the system
+        User user = _userDao.findById(userId);
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("Unable to find user by id");
+        }
+
+        Account account = _accountDao.findById(user.getAccountId());
+        if (account == null) {
+            throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
+        }
+
+        // don't allow to lock user of the account of type Project
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find user by id");
+        }
+
+        // If the user is a System user, return an error. We do not allow this
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("user id : " + userId + " is a system user, locking is not allowed");
+        }
+
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        // make sure the account is enabled too
+        // if the user is either locked already or disabled already, don't change state...only lock currently enabled
+// users
+        boolean success = true;
+        if (user.getState().equals(State.locked)) {
+            // already locked...no-op
+            return _userAccountDao.findById(userId);
+        } else if (user.getState().equals(State.enabled)) {
+            success = doSetUserStatus(user.getId(), State.locked);
+
+            boolean lockAccount = true;
+            List<UserVO> allUsersByAccount = _userDao.listByAccount(user.getAccountId());
+            for (UserVO oneUser : allUsersByAccount) {
+                if (oneUser.getState().equals(State.enabled)) {
+                    lockAccount = false;
+                    break;
+                }
+            }
+
+            if (lockAccount) {
+                success = (success && lockAccount(user.getAccountId()));
+            }
+        } else {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Attempting to lock a non-enabled user, current state is " + user.getState() + " (userId: " + user.getId() + "), locking failed.");
+            }
+            success = false;
+        }
+
+        if (success) {
+
+            CallContext.current().putContextParameter(User.class, user.getUuid());
+
+            return _userAccountDao.findById(userId);
+        } else {
+            throw new CloudRuntimeException("Unable to lock user " + userId);
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true)
+    public boolean deleteUserAccount(long accountId) {
+
+        CallContext ctx = CallContext.current();
+        long callerUserId = ctx.getCallingUserId();
+        Account caller = ctx.getCallingAccount();
+
+        // If the user is a System user, return an error. We do not allow this
+        AccountVO account = _accountDao.findById(accountId);
+
+        if (account == null || account.getRemoved() != null) {
+            if (account != null) {
+                s_logger.info("The account:" + account.getAccountName() + " is already removed");
+            }
+            return true;
+        }
+
+        // don't allow removing Project account
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("The specified account does not exist in the system");
+        }
+
+        checkAccess(caller, null, true, account);
+
+        // don't allow to delete default account (system and admin)
+        if (account.isDefault()) {
+            throw new InvalidParameterValueException("The account is default and can't be removed");
+        }
+
+        // Account that manages project(s) can't be removed
+        List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
+        if (!managedProjectIds.isEmpty()) {
+            StringBuilder projectIds = new StringBuilder();
+            for (Long projectId : managedProjectIds) {
+                projectIds.append(projectId + ", ");
+            }
+
+            throw new InvalidParameterValueException("The account id=" + accountId + " manages project(s) with ids " + projectIds + "and can't be removed");
+        }
+
+        CallContext.current().putContextParameter(Account.class, account.getUuid());
+
+        return deleteAccount(account, callerUserId, caller);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_ENABLE, eventDescription = "enabling account", async = true)
+    public AccountVO enableAccount(String accountName, Long domainId, Long accountId) {
+
+        // Check if account exists
+        Account account = null;
+        if (accountId != null) {
+            account = _accountDao.findById(accountId);
+        } else {
+            account = _accountDao.findActiveAccount(accountName, domainId);
+        }
+
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, enable is not allowed");
+        }
+
+        // Check if user performing the action is allowed to modify this account
+        Account caller = getCurrentCallingAccount();
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        boolean success = enableAccount(account.getId());
+        if (success) {
+
+            CallContext.current().putContextParameter(Account.class, account.getUuid());
+
+            return _accountDao.findById(account.getId());
+        } else {
+            throw new CloudRuntimeException("Unable to enable account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "locking account", async = true)
+    public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
+        Account caller = getCurrentCallingAccount();
+
+        Account account = null;
+        if (accountId != null) {
+            account = _accountDao.findById(accountId);
+        } else {
+            account = _accountDao.findActiveAccount(accountName, domainId);
+        }
+
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, lock is not allowed");
+        }
+
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        if (lockAccount(account.getId())) {
+            CallContext.current().putContextParameter(Account.class, account.getUuid());
+            return _accountDao.findById(account.getId());
+        } else {
+            throw new CloudRuntimeException("Unable to lock account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "disabling account", async = true)
+    public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
+        Account caller = getCurrentCallingAccount();
+
+        Account account = null;
+        if (accountId != null) {
+            account = _accountDao.findById(accountId);
+        } else {
+            account = _accountDao.findActiveAccount(accountName, domainId);
+        }
+
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new PermissionDeniedException("Account id : " + accountId + " is a system account, disable is not allowed");
+        }
+
+        checkAccess(caller, AccessType.OperateEntry, true, account);
+
+        if (disableAccount(account.getId())) {
+            CallContext.current().putContextParameter(Account.class, account.getUuid());
+            return _accountDao.findById(account.getId());
+        } else {
+            throw new CloudRuntimeException("Unable to update account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_UPDATE, eventDescription = "updating account", async = true)
+    public AccountVO updateAccount(UpdateAccountCmd cmd) {
+        Long accountId = cmd.getId();
+        Long domainId = cmd.getDomainId();
+        Long roleId = cmd.getRoleId();
+        String accountName = cmd.getAccountName();
+        String newAccountName = cmd.getNewName();
+        String networkDomain = cmd.getNetworkDomain();
+        final Map<String, String> details = cmd.getDetails();
+
+        boolean success = false;
+        Account account = null;
+        if (accountId != null) {
+            account = _accountDao.findById(accountId);
+        } else {
+            account = _accountDao.findEnabledAccount(accountName, domainId);
+        }
+
+        final AccountVO acctForUpdate = _accountDao.findById(account.getId());
+
+        // Check if account exists
+        if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            s_logger.error("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+            throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+
+        // Don't allow to modify system account
+        if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
+            throw new InvalidParameterValueException("Can not modify system account");
+        }
+
+        // Check if user performing the action is allowed to modify this account
+        Account caller = getCurrentCallingAccount();
+        checkAccess(caller, _domainMgr.getDomain(account.getDomainId()));
+
+        if(newAccountName != null) {
+
+            if (newAccountName.isEmpty()) {
+                throw new InvalidParameterValueException("The new account name for account '" + account.getUuid() + "' " +
+                        "within domain '" + domainId + "'  is empty string. Account will be not renamed.");
+            }
+
+            // check if the new proposed account name is absent in the domain
+            Account existingAccount = _accountDao.findActiveAccount(newAccountName, domainId);
+            if (existingAccount != null && existingAccount.getId() != account.getId()) {
+                throw new InvalidParameterValueException("The account with the proposed name '" +
+                        newAccountName + "' exists in the domain '" +
+                        domainId + "' with existing account id '" + existingAccount.getId() + "'");
+            }
+
+            acctForUpdate.setAccountName(newAccountName);
+        }
+
+        if (networkDomain != null && !networkDomain.isEmpty()) {
+            if (!NetUtils.verifyDomainName(networkDomain)) {
+                throw new InvalidParameterValueException("Invalid network domain or format. " +
+                        "Total length shouldn't exceed 190 chars. Every domain part must be between 1 and 63 " +
+                        "characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+            }
+        }
+
+
+        if (roleId != null) {
+            final List<Role> roles = cmd.roleService.listRoles();
+            final boolean roleNotFound = roles.stream().filter(r -> r.getId() == roleId).count() == 0;
+            if (roleNotFound) {
+                throw new InvalidParameterValueException("Role with ID '" + roleId.toString() + "' " +
+                        "is not found or not available for the account '" + account.getUuid() + "' " +
+                        "in the domain '" + domainId + "'.");
+            }
+
+            acctForUpdate.setRoleId(roleId);
+        }
+
+        if (networkDomain != null) {
+            if (networkDomain.isEmpty()) {
+                acctForUpdate.setNetworkDomain(null);
+            } else {
+                acctForUpdate.setNetworkDomain(networkDomain);
+            }
+        }
+
+        final Account accountFinal = account;
+        success = Transaction.execute((TransactionCallback<Boolean>) status -> {
+            boolean success1 = _accountDao.update(accountFinal.getId(), acctForUpdate);
+
+            if (details != null && success1) {
+                _accountDetailsDao.update(accountFinal.getId(), details);
+            }
+
+            return success1;
+        });
+
+        if (success) {
+            CallContext.current().putContextParameter(Account.class, account.getUuid());
+            return _accountDao.findById(account.getId());
+        } else {
+            throw new CloudRuntimeException("Unable to update account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId);
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_DELETE, eventDescription = "deleting User")
+    public boolean deleteUser(DeleteUserCmd deleteUserCmd) {
+        UserVO user = getValidUserVO(deleteUserCmd.getId());
+
+        Account account = _accountDao.findById(user.getAccountId());
+
+        // don't allow to delete the user from the account of type Project
+        checkAccountAndAccess(user, account);
+        return _userDao.remove(deleteUserCmd.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
+    public boolean moveUser(MoveUserCmd cmd) {
+        final Long id = cmd.getId();
+        UserVO user = getValidUserVO(id);
+        Account oldAccount = _accountDao.findById(user.getAccountId());
+        checkAccountAndAccess(user, oldAccount);
+        long domainId = oldAccount.getDomainId();
+
+        long newAccountId = getNewAccountId(domainId, cmd.getAccountName(), cmd.getAccountId());
+
+        return moveUser(user, newAccountId);
+    }
+
+    @Override
+    public boolean moveUser(long id, Long domainId, long accountId) {
+        UserVO user = getValidUserVO(id);
+        Account oldAccount = _accountDao.findById(user.getAccountId());
+        checkAccountAndAccess(user, oldAccount);
+        Account newAccount = _accountDao.findById(accountId);
+        checkIfNotMovingAcrossDomains(domainId, newAccount);
+        return moveUser(user, accountId);
+    }
+
+    private boolean moveUser(UserVO user, long newAccountId) {
+        if (newAccountId == user.getAccountId()) {
+            // could do a not silent fail but the objective of the user is reached
+            return true; // no need to create a new user object for this user
+        }
+
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                UserVO newUser = new UserVO(user);
+                user.setExternalEntity(user.getUuid());
+                user.setUuid(UUID.randomUUID().toString());
+                user.setApiKey(null);
+                user.setSecretKey(null);
+                _userDao.update(user.getId(), user);
+                newUser.setAccountId(newAccountId);
+                boolean success = _userDao.remove(user.getId());
+                UserVO persisted = _userDao.persist(newUser);
+                return success && persisted.getUuid().equals(user.getExternalEntity());
+            }
+        });
+    }
+
+    private long getNewAccountId(long domainId, String accountName, Long accountId) {
+        Account newAccount = null;
+        if (StringUtils.isNotBlank(accountName)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Getting id for account by name '" + accountName + "' in domain " + domainId);
+            }
+            newAccount = _accountDao.findEnabledAccount(accountName, domainId);
+        }
+        if (newAccount == null && accountId != null) {
+            newAccount = _accountDao.findById(accountId);
+        }
+        if (newAccount == null) {
+            throw new CloudRuntimeException("no account name or account id. this should have been caught before this point");
+        }
+
+        checkIfNotMovingAcrossDomains(domainId, newAccount);
+        return newAccount.getAccountId();
+    }
+
+    private void checkIfNotMovingAcrossDomains(long domainId, Account newAccount) {
+        if (newAccount.getDomainId() != domainId) {
+            // not in scope
+            throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
+        }
+    }
+
+    private void checkAccountAndAccess(UserVO user, Account account) {
+        // don't allow to delete the user from the account of type Project
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            throw new InvalidParameterValueException("Project users cannot be deleted or moved.");
+        }
+
+        checkAccess(getCurrentCallingAccount(), AccessType.OperateEntry, true, account);
+        CallContext.current().putContextParameter(User.class, user.getUuid());
+    }
+
+    private UserVO getValidUserVO(long id) {
+        UserVO user = _userDao.findById(id);
+
+        if (user == null || user.getRemoved() != null) {
+            throw new InvalidParameterValueException("The specified user doesn't exist in the system");
+        }
+
+        // don't allow to delete default user (system and admin users)
+        if (user.isDefault()) {
+            throw new InvalidParameterValueException("The user is default and can't be (re)moved");
+        }
+
+        return user;
+    }
+
+    protected class AccountCleanupTask extends ManagedContextRunnable {
+        @Override
+        protected void runInContext() {
+            try {
+                GlobalLock lock = GlobalLock.getInternLock("AccountCleanup");
+                if (lock == null) {
+                    s_logger.debug("Couldn't get the global lock");
+                    return;
+                }
+
+                if (!lock.lock(30)) {
+                    s_logger.debug("Couldn't lock the db");
+                    return;
+                }
+
+                try {
+                    // Cleanup removed accounts
+                    List<AccountVO> removedAccounts = _accountDao.findCleanupsForRemovedAccounts(null);
+                    s_logger.info("Found " + removedAccounts.size() + " removed accounts to cleanup");
+                    for (AccountVO account : removedAccounts) {
+                        s_logger.debug("Cleaning up " + account.getId());
+                        cleanupAccount(account, getSystemUser().getId(), getSystemAccount());
+                    }
+
+                    // cleanup disabled accounts
+                    List<AccountVO> disabledAccounts = _accountDao.findCleanupsForDisabledAccounts();
+                    s_logger.info("Found " + disabledAccounts.size() + " disabled accounts to cleanup");
+                    for (AccountVO account : disabledAccounts) {
+                        s_logger.debug("Disabling account " + account.getId());
+                        try {
+                            disableAccount(account.getId());
+                        } catch (Exception e) {
+                            s_logger.error("Skipping due to error on account " + account.getId(), e);
+                        }
+                    }
+
+                    // cleanup inactive domains
+                    List<? extends Domain> inactiveDomains = _domainMgr.findInactiveDomains();
+                    s_logger.info("Found " + inactiveDomains.size() + " inactive domains to cleanup");
+                    for (Domain inactiveDomain : inactiveDomains) {
+                        long domainId = inactiveDomain.getId();
+                        try {
+                            List<AccountVO> accountsForCleanupInDomain = _accountDao.findCleanupsForRemovedAccounts(domainId);
+                            if (accountsForCleanupInDomain.isEmpty()) {
+                                // release dedication if any, before deleting the domain
+                                List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listByDomainId(domainId);
+                                if (dedicatedResources != null && !dedicatedResources.isEmpty()) {
+                                    s_logger.debug("Releasing dedicated resources for domain" + domainId);
+                                    for (DedicatedResourceVO dr : dedicatedResources) {
+                                        if (!_dedicatedDao.remove(dr.getId())) {
+                                            s_logger.warn("Fail to release dedicated resources for domain " + domainId);
+                                        }
+                                    }
+                                }
+                                s_logger.debug("Removing inactive domain id=" + domainId);
+                                _domainMgr.removeDomain(domainId);
+                            } else {
+                                s_logger.debug("Can't remove inactive domain id=" + domainId + " as it has accounts that need cleanup");
+                            }
+                        } catch (Exception e) {
+                            s_logger.error("Skipping due to error on domain " + domainId, e);
+                        }
+                    }
+
+                    // cleanup inactive projects
+                    List<ProjectVO> inactiveProjects = _projectDao.listByState(Project.State.Disabled);
+                    s_logger.info("Found " + inactiveProjects.size() + " disabled projects to cleanup");
+                    for (ProjectVO project : inactiveProjects) {
+                        try {
+                            Account projectAccount = getAccount(project.getProjectAccountId());
+                            if (projectAccount == null) {
+                                s_logger.debug("Removing inactive project id=" + project.getId());
+                                _projectMgr.deleteProject(CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId(), project);
+                            } else {
+                                s_logger.debug("Can't remove disabled project " + project + " as it has non removed account id=" + project.getId());
+                            }
+                        } catch (Exception e) {
+                            s_logger.error("Skipping due to error on project " + project, e);
+                        }
+                    }
+
+                } catch (Exception e) {
+                    s_logger.error("Exception ", e);
+                } finally {
+                    lock.unlock();
+                }
+            } catch (Exception e) {
+                s_logger.error("Exception ", e);
+            }
+        }
+    }
+
+    @Override
+    public Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId) {
+        // don't default the owner to the system account
+        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM && ((accountName == null || domainId == null) && projectId == null)) {
+            throw new InvalidParameterValueException("Account and domainId are needed for resource creation");
+        }
+
+        // projectId and account/domainId can't be specified together
+        if ((accountName != null && domainId != null) && projectId != null) {
+            throw new InvalidParameterValueException("ProjectId and account/domainId can't be specified together");
+        }
+
+        if (projectId != null) {
+            Project project = _projectMgr.getProject(projectId);
+            if (project == null) {
+                throw new InvalidParameterValueException("Unable to find project by id=" + projectId);
+            }
+
+            if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
+                throw new PermissionDeniedException("Account " + caller + " is unauthorised to use project id=" + projectId);
+            }
+
+            return getAccount(project.getProjectAccountId());
+        }
+
+        if (isAdmin(caller.getId()) && accountName != null && domainId != null) {
+            Domain domain = _domainMgr.getDomain(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId);
+            }
+
+            Account owner = _accountDao.findActiveAccount(accountName, domainId);
+            if (owner == null) {
+                throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId);
+            }
+            checkAccess(caller, domain);
+
+            return owner;
+        } else if (!isAdmin(caller.getId()) && accountName != null && domainId != null) {
+            if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) {
+                throw new PermissionDeniedException("Can't create/list resources for account " + accountName + " in domain " + domainId + ", permission denied");
+            } else {
+                return caller;
+            }
+        } else {
+            if ((accountName == null && domainId != null) || (accountName != null && domainId == null)) {
+                throw new InvalidParameterValueException("AccountName and domainId must be specified together");
+            }
+            // regular user can't create/list resources for other people
+            return caller;
+        }
+    }
+
+    @Override
+    public Account getActiveAccountByName(String accountName, Long domainId) {
+        if (accountName == null || domainId == null) {
+            throw new InvalidParameterValueException("Both accountName and domainId are required for finding active account in the system");
+        } else {
+            return _accountDao.findActiveAccount(accountName, domainId);
+        }
+    }
+
+    @Override
+    public UserAccount getActiveUserAccount(String username, Long domainId) {
+        return _userAccountDao.getUserAccount(username, domainId);
+    }
+
+    @Override
+    public Account getActiveAccountById(long accountId) {
+        return _accountDao.findById(accountId);
+    }
+
+    @Override
+    public Account getAccount(long accountId) {
+        return _accountDao.findByIdIncludingRemoved(accountId);
+    }
+
+    @Override
+    public RoleType getRoleType(Account account) {
+        if (account == null) {
+            return RoleType.Unknown;
+        }
+        return RoleType.getByAccountType(account.getType());
+    }
+
+    @Override
+    public User getActiveUser(long userId) {
+        return _userDao.findById(userId);
+    }
+
+    @Override
+    public User getUserIncludingRemoved(long userId) {
+        return _userDao.findByIdIncludingRemoved(userId);
+    }
+
+    @Override
+    public User getActiveUserByRegistrationToken(String registrationToken) {
+        return _userDao.findUserByRegistrationToken(registrationToken);
+    }
+
+    @Override
+    public void markUserRegistered(long userId) {
+        UserVO userForUpdate = _userDao.createForUpdate();
+        userForUpdate.setRegistered(true);
+        _userDao.update(Long.valueOf(userId), userForUpdate);
+    }
+
+    @Override
+    @DB
+    public AccountVO createAccount(final String accountName, final short accountType, final Long roleId, final Long domainId, final String networkDomain, final Map<String, String> details,
+            final String uuid) {
+        // Validate domain
+        Domain domain = _domainMgr.getDomain(domainId);
+        if (domain == null) {
+            throw new InvalidParameterValueException("The domain " + domainId + " does not exist; unable to create account");
+        }
+
+        if (domain.getState().equals(Domain.State.Inactive)) {
+            throw new CloudRuntimeException("The account cannot be created as domain " + domain.getName() + " is being deleted");
+        }
+
+        if ((domainId != Domain.ROOT_DOMAIN) && (accountType == Account.ACCOUNT_TYPE_ADMIN)) {
+            throw new InvalidParameterValueException(
+                    "Invalid account type " + accountType + " given for an account in domain " + domainId + "; unable to create user of admin role type in non-ROOT domain.");
+        }
+
+        // Validate account/user/domain settings
+        if (_accountDao.findActiveAccount(accountName, domainId) != null) {
+            throw new InvalidParameterValueException("The specified account: " + accountName + " already exists");
+        }
+
+        if (networkDomain != null) {
+            if (!NetUtils.verifyDomainName(networkDomain)) {
+                throw new InvalidParameterValueException(
+                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                                + "and the hyphen ('-'); can't start or end with \"-\"");
+            }
+        }
+
+        // Verify account type
+        if ((accountType < Account.ACCOUNT_TYPE_NORMAL) || (accountType > Account.ACCOUNT_TYPE_PROJECT)) {
+            throw new InvalidParameterValueException("Invalid account type " + accountType + " given; unable to create user");
+        }
+
+        if (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+            List<DataCenterVO> dc = _dcDao.findZonesByDomainId(domainId);
+            if (dc.isEmpty()) {
+                throw new InvalidParameterValueException("The account cannot be created as domain " + domain.getName() + " is not associated with any private Zone");
+            }
+        }
+
+        // Create the account
+        return Transaction.execute(new TransactionCallback<AccountVO>() {
+            @Override
+            public AccountVO doInTransaction(TransactionStatus status) {
+                AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid));
+
+                if (account == null) {
+                    throw new CloudRuntimeException("Failed to create account name " + accountName + " in domain id=" + domainId);
+                }
+
+                Long accountId = account.getId();
+
+                if (details != null) {
+                    _accountDetailsDao.persist(accountId, details);
+                }
+
+                // Create resource count records for the account
+                _resourceCountDao.createResourceCounts(accountId, ResourceLimit.ResourceOwnerType.Account);
+
+                // Create default security group
+                _networkGroupMgr.createDefaultSecurityGroup(accountId);
+
+                return account;
+            }
+        });
+    }
+
+    protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID, User.Source source) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
+        }
+
+        String encodedPassword = null;
+        for (UserAuthenticator authenticator : _userPasswordEncoders) {
+            encodedPassword = authenticator.encode(password);
+            if (encodedPassword != null) {
+                break;
+            }
+        }
+        if (encodedPassword == null) {
+            throw new CloudRuntimeException("Failed to encode password");
+        }
+
+        if (userUUID == null) {
+            userUUID = UUID.randomUUID().toString();
+        }
+        UserVO user = _userDao.persist(new UserVO(accountId, userName, encodedPassword, firstName, lastName, email, timezone, userUUID, source));
+        CallContext.current().putContextParameter(User.class, user.getUuid());
+        return user;
+    }
+
+    @Override
+    public void logoutUser(long userId) {
+        UserAccount userAcct = _userAccountDao.findById(userId);
+        if (userAcct != null) {
+            ActionEventUtils.onActionEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out");
+        } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted...
+    }
+
+    @Override
+    public UserAccount authenticateUser(final String username, final String password, final Long domainId, final InetAddress loginIpAddress, final Map<String, Object[]> requestParameters) {
+        UserAccount user = null;
+        if (password != null && !password.isEmpty()) {
+            user = getUserAccount(username, password, domainId, requestParameters);
+        } else {
+            String key = _configDao.getValue("security.singlesignon.key");
+            if (key == null) {
+                // the SSO key is gone, don't authenticate
+                return null;
+            }
+
+            String singleSignOnTolerance = _configDao.getValue("security.singlesignon.tolerance.millis");
+            if (singleSignOnTolerance == null) {
+                // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be
+                // valid),
+                // don't authenticate
+                return null;
+            }
+
+            long tolerance = Long.parseLong(singleSignOnTolerance);
+            String signature = null;
+            long timestamp = 0L;
+            String unsignedRequest = null;
+            StringBuffer unsignedRequestBuffer = new StringBuffer();
+
+            // - build a request string with sorted params, make sure it's all lowercase
+            // - sign the request, verify the signature is the same
+            List<String> parameterNames = new ArrayList<String>();
+
+            for (Object paramNameObj : requestParameters.keySet()) {
+                parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
+            }
+
+            Collections.sort(parameterNames);
+
+            try {
+                for (String paramName : parameterNames) {
+                    // parameters come as name/value pairs in the form String/String[]
+                    String paramValue = ((String[])requestParameters.get(paramName))[0];
+
+                    if ("signature".equalsIgnoreCase(paramName)) {
+                        signature = paramValue;
+                    } else {
+                        if ("timestamp".equalsIgnoreCase(paramName)) {
+                            String timestampStr = paramValue;
+                            try {
+                                // If the timestamp is in a valid range according to our tolerance, verify the request
+                                // signature, otherwise return null to indicate authentication failure
+                                timestamp = Long.parseLong(timestampStr);
+                                long currentTime = System.currentTimeMillis();
+                                if (Math.abs(currentTime - timestamp) > tolerance) {
+                                    if (s_logger.isDebugEnabled()) {
+                                        s_logger.debug("Expired timestamp passed in to login, current time = " + currentTime + ", timestamp = " + timestamp);
+                                    }
+                                    return null;
+                                }
+                            } catch (NumberFormatException nfe) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Invalid timestamp passed in to login: " + timestampStr);
+                                }
+                                return null;
+                            }
+                        }
+
+                        if (unsignedRequestBuffer.length() != 0) {
+                            unsignedRequestBuffer.append("&");
+                        }
+                        unsignedRequestBuffer.append(paramName).append("=").append(URLEncoder.encode(paramValue, "UTF-8"));
+                    }
+                }
+
+                if ((signature == null) || (timestamp == 0L)) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Missing parameters in login request, signature = " + signature + ", timestamp = " + timestamp);
+                    }
+                    return null;
+                }
+
+                unsignedRequest = unsignedRequestBuffer.toString().toLowerCase().replaceAll("\\+", "%20");
+
+                Mac mac = Mac.getInstance("HmacSHA1");
+                SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
+                mac.init(keySpec);
+                mac.update(unsignedRequest.getBytes());
+                byte[] encryptedBytes = mac.doFinal();
+                String computedSignature = new String(Base64.encodeBase64(encryptedBytes));
+                boolean equalSig = ConstantTimeComparator.compareStrings(signature, computedSignature);
+                if (!equalSig) {
+                    s_logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
+                } else {
+                    user = _userAccountDao.getUserAccount(username, domainId);
+                }
+            } catch (Exception ex) {
+                s_logger.error("Exception authenticating user", ex);
+                return null;
+            }
+        }
+
+        if (user != null) {
+            // don't allow to authenticate system user
+            if (user.getId() == User.UID_SYSTEM) {
+                s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId);
+                return null;
+            }
+            // don't allow baremetal system user
+            if (BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME.equals(user.getUsername())) {
+                s_logger.error("Won't authenticate user: " + username + " in domain " + domainId);
+                return null;
+            }
+
+            // We authenticated successfully by now, let's check if we are allowed to login from the ip address the reqest comes from
+            final Account account = getAccount(user.getAccountId());
+            final DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId());
+
+            // Get the CIDRs from where this account is allowed to make calls
+            final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s", "");
+            final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
+
+            if (ApiSourceCidrChecksEnabled) {
+                s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs);
+
+                // Block when is not in the list of allowed IPs
+                if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) {
+                    s_logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replaceAll("/", "") + " does not match " + accessAllowedCidrs);
+                    throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip "
+                            + loginIpAddress.toString().replaceAll("/", "") + "; please provide valid credentials");
+                }
+            }
+
+            // Here all is fine!
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
+            }
+
+            ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in from IP Address " + loginIpAddress);
+
+            return user;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("User: " + username + " in domain " + domainId + " has failed to log in");
+            }
+            return null;
+        }
+    }
+
+    private UserAccount getUserAccount(String username, String password, Long domainId, Map<String, Object[]> requestParameters) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Attempting to log in user: " + username + " in domain " + domainId);
+        }
+        UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
+
+        boolean authenticated = false;
+        HashSet<ActionOnFailedAuthentication> actionsOnFailedAuthenticaion = new HashSet<ActionOnFailedAuthentication>();
+        User.Source userSource = userAccount != null ? userAccount.getSource() : User.Source.UNKNOWN;
+        for (UserAuthenticator authenticator : _userAuthenticators) {
+            if (userSource != User.Source.UNKNOWN) {
+                if (!authenticator.getName().equalsIgnoreCase(userSource.name())) {
+                    continue;
+                }
+            }
+            Pair<Boolean, ActionOnFailedAuthentication> result = authenticator.authenticate(username, password, domainId, requestParameters);
+            if (result.first()) {
+                authenticated = true;
+                break;
+            } else if (result.second() != null) {
+                actionsOnFailedAuthenticaion.add(result.second());
+            }
+        }
+
+        boolean updateIncorrectLoginCount = actionsOnFailedAuthenticaion.contains(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
+
+        if (authenticated) {
+
+            Domain domain = _domainMgr.getDomain(domainId);
+            String domainName = null;
+            if (domain != null) {
+                domainName = domain.getName();
+            }
+            userAccount = _userAccountDao.getUserAccount(username, domainId);
+
+            if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
+                }
+                throw new CloudAuthenticationException("User " + username + " (or their account) in domain " + domainName + " is disabled/locked. Please contact the administrator.");
+            }
+            // Whenever the user is able to log in successfully, reset the login attempts to zero
+            if (!isInternalAccount(userAccount.getId())) {
+                updateLoginAttempts(userAccount.getId(), 0, false);
+            }
+
+            return userAccount;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to authenticate user with username " + username + " in domain " + domainId);
+            }
+
+            if (userAccount == null) {
+                s_logger.warn("Unable to find an user with username " + username + " in domain " + domainId);
+                return null;
+            }
+
+            if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) {
+                if (!isInternalAccount(userAccount.getId())) {
+                    // Internal accounts are not disabled
+                    int attemptsMade = userAccount.getLoginAttempts() + 1;
+                    if (updateIncorrectLoginCount) {
+                        if (attemptsMade < _allowedLoginAttempts) {
+                            updateLoginAttempts(userAccount.getId(), attemptsMade, false);
+                            s_logger.warn("Login attempt failed. You have " + (_allowedLoginAttempts - attemptsMade) + " attempt(s) remaining");
+                        } else {
+                            updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts, true);
+                            s_logger.warn("User " + userAccount.getUsername() + " has been disabled due to multiple failed login attempts." + " Please contact admin.");
+                        }
+                    }
+                }
+            } else {
+                s_logger.info("User " + userAccount.getUsername() + " is disabled/locked");
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public Pair<User, Account> findUserByApiKey(String apiKey) {
+        return _accountDao.findUserAccountByApiKey(apiKey);
+    }
+
+    @Override
+    public Map<String, String> getKeys(GetUserKeysCmd cmd) {
+        final long userId = cmd.getID();
+
+        User user = getActiveUser(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("Unable to find user by id");
+        }
+        final ControlledEntity account = getAccount(getUserAccountById(userId).getAccountId()); //Extracting the Account from the userID of the requested user.
+        checkAccess(CallContext.current().getCallingUser(), account);
+
+        Map<String, String> keys = new HashMap<String, String>();
+        keys.put("apikey", user.getApiKey());
+        keys.put("secretkey", user.getSecretKey());
+
+        return keys;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
+    public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
+        Account caller = getCurrentCallingAccount();
+        final Long userId = cmd.getId();
+
+        User user = getUserIncludingRemoved(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("unable to find user by id");
+        }
+
+        Account account = _accountDao.findById(user.getAccountId());
+        checkAccess(caller, null, true, account);
+
+        // don't allow updating system user
+        if (user.getId() == User.UID_SYSTEM) {
+            throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed");
+        }
+        // don't allow baremetal system user
+        if (BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME.equals(user.getUsername())) {
+            throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed");
+        }
+
+        // generate both an api key and a secret key, update the user table with the keys, return the keys to the user
+        final String[] keys = new String[2];
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                keys[0] = createUserApiKey(userId);
+                keys[1] = createUserSecretKey(userId);
+            }
+        });
+
+        return keys;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
+    public String[] createApiKeyAndSecretKey(final long userId) {
+        User user = getUserIncludingRemoved(userId);
+        if (user == null) {
+            throw new InvalidParameterValueException("Unable to find user by id");
+        }
+        final String[] keys = new String[2];
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                keys[0] = AccountManagerImpl.this.createUserApiKey(userId);
+                keys[1] = AccountManagerImpl.this.createUserSecretKey(userId);
+            }
+        });
+        return keys;
+    }
+
+    private String createUserApiKey(long userId) {
+        try {
+            UserVO updatedUser = _userDao.createForUpdate();
+
+            String encodedKey = null;
+            Pair<User, Account> userAcct = null;
+            int retryLimit = 10;
+            do {
+                // FIXME: what algorithm should we use for API keys?
+                KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
+                SecretKey key = generator.generateKey();
+                encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
+                userAcct = _accountDao.findUserAccountByApiKey(encodedKey);
+                retryLimit--;
+            } while ((userAcct != null) && (retryLimit >= 0));
+
+            if (userAcct != null) {
+                return null;
+            }
+            updatedUser.setApiKey(encodedKey);
+            _userDao.update(userId, updatedUser);
+            return encodedKey;
+        } catch (NoSuchAlgorithmException ex) {
+            s_logger.error("error generating secret key for user id=" + userId, ex);
+        }
+        return null;
+    }
+
+    private String createUserSecretKey(long userId) {
+        try {
+            UserVO updatedUser = _userDao.createForUpdate();
+            String encodedKey = null;
+            int retryLimit = 10;
+            UserVO userBySecretKey = null;
+            do {
+                KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
+                SecretKey key = generator.generateKey();
+                encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
+                userBySecretKey = _userDao.findUserBySecretKey(encodedKey);
+                retryLimit--;
+            } while ((userBySecretKey != null) && (retryLimit >= 0));
+
+            if (userBySecretKey != null) {
+                return null;
+            }
+
+            updatedUser.setSecretKey(encodedKey);
+            _userDao.update(userId, updatedUser);
+            return encodedKey;
+        } catch (NoSuchAlgorithmException ex) {
+            s_logger.error("error generating secret key for user id=" + userId, ex);
+        }
+        return null;
+    }
+
+    @Override
+    public void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+
+        if (sb.entity() instanceof IPAddressVO) {
+            sb.and("accountIdIN", ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), SearchCriteria.Op.IN);
+            sb.and("domainId", ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), SearchCriteria.Op.EQ);
+        } else if (sb.entity() instanceof ProjectInvitationVO) {
+            sb.and("accountIdIN", ((ProjectInvitationVO)sb.entity()).getForAccountId(), SearchCriteria.Op.IN);
+            sb.and("domainId", ((ProjectInvitationVO)sb.entity()).getInDomainId(), SearchCriteria.Op.EQ);
+        } else {
+            sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+            sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+        }
+
+        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
+            // if accountId isn't specified, we can do a domain match for the admin case if isRecursive is true
+            SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
+            domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
+
+            if (sb.entity() instanceof IPAddressVO) {
+                sb.join("domainSearch", domainSearch, ((IPAddressVO)sb.entity()).getAllocatedInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            } else if (sb.entity() instanceof ProjectInvitationVO) {
+                sb.join("domainSearch", domainSearch, ((ProjectInvitationVO)sb.entity()).getInDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            } else {
+                sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            }
+
+        }
+        if (listProjectResourcesCriteria != null) {
+            SearchBuilder<AccountVO> accountSearch = _accountDao.createSearchBuilder();
+            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
+                accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.EQ);
+            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
+                accountSearch.and("type", accountSearch.entity().getType(), SearchCriteria.Op.NEQ);
+            }
+
+            if (sb.entity() instanceof IPAddressVO) {
+                sb.join("accountSearch", accountSearch, ((IPAddressVO)sb.entity()).getAllocatedToAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            } else if (sb.entity() instanceof ProjectInvitationVO) {
+                sb.join("accountSearch", accountSearch, ((ProjectInvitationVO)sb.entity()).getForAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            } else {
+                sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
+            }
+        }
+    }
+
+    @Override
+    public void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+
+        if (listProjectResourcesCriteria != null) {
+            sc.setJoinParameters("accountSearch", "type", Account.ACCOUNT_TYPE_PROJECT);
+        }
+
+        if (!permittedAccounts.isEmpty()) {
+            sc.setParameters("accountIdIN", permittedAccounts.toArray());
+        } else if (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            if (isRecursive) {
+                sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
+            } else {
+                sc.setParameters("domainId", domainId);
+            }
+        }
+    }
+
+    //TODO: deprecate this to use the new buildACLSearchParameters with permittedDomains, permittedAccounts, and permittedResources as return
+    @Override
+    public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts,
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) {
+        Long domainId = domainIdRecursiveListProject.first();
+        if (domainId != null) {
+            Domain domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
+            }
+            // check permissions
+            checkAccess(caller, domain);
+        }
+
+        if (accountName != null) {
+            if (projectId != null) {
+                throw new InvalidParameterValueException("Account and projectId can't be specified together");
+            }
+
+            Account userAccount = null;
+            Domain domain = null;
+            if (domainId != null) {
+                userAccount = _accountDao.findActiveAccount(accountName, domainId);
+                domain = _domainDao.findById(domainId);
+            } else {
+                userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId());
+                domain = _domainDao.findById(caller.getDomainId());
+            }
+
+            if (userAccount != null) {
+                checkAccess(caller, null, false, userAccount);
+                // check permissions
+                permittedAccounts.add(userAccount.getId());
+            } else {
+                throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid());
+            }
+        }
+
+        // set project information
+        if (projectId != null) {
+            if (!forProjectInvitation) {
+                if (projectId.longValue() == -1) {
+                    if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                        permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
+
+                        //permittedAccounts can be empty when the caller is not a part of any project (a domain account)
+                        if (permittedAccounts.isEmpty()) {
+                            permittedAccounts.add(caller.getId());
+                        }
+                    } else {
+                        domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly);
+                    }
+                } else {
+                    Project project = _projectMgr.getProject(projectId);
+                    if (project == null) {
+                        throw new InvalidParameterValueException("Unable to find project by id " + projectId);
+                    }
+                    if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
+                        throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId);
+                    }
+                    permittedAccounts.add(project.getProjectAccountId());
+                }
+            }
+        } else {
+            if (id == null) {
+                domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
+            }
+            if (permittedAccounts.isEmpty() && domainId == null) {
+                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                    permittedAccounts.add(caller.getId());
+                } else if (!listAll) {
+                    if (id == null) {
+                        permittedAccounts.add(caller.getId());
+                    } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+                        domainIdRecursiveListProject.first(caller.getDomainId());
+                        domainIdRecursiveListProject.second(true);
+                    }
+                } else if (domainId == null) {
+                    if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
+                        domainIdRecursiveListProject.first(caller.getDomainId());
+                        domainIdRecursiveListProject.second(true);
+                    }
+                }
+            } else if (domainId != null) {
+                if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
+                    permittedAccounts.add(caller.getId());
+                }
+            }
+
+        }
+
+    }
+
+    @Override
+    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+
+        sb.and("accountIdIN", sb.entity().getAccountId(), SearchCriteria.Op.IN);
+        sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
+
+        if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
+            // if accountId isn't specified, we can do a domain match for the
+            // admin case if isRecursive is true
+            sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE);
+        }
+
+        if (listProjectResourcesCriteria != null) {
+            if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.ListProjectResourcesOnly) {
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.EQ);
+            } else if (listProjectResourcesCriteria == Project.ListProjectResourcesCriteria.SkipProjectResources) {
+                sb.and("accountType", sb.entity().getAccountType(), SearchCriteria.Op.NEQ);
+            }
+        }
+
+    }
+
+    @Override
+    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        if (listProjectResourcesCriteria != null) {
+            sc.setParameters("accountType", Account.ACCOUNT_TYPE_PROJECT);
+        }
+
+        if (!permittedAccounts.isEmpty()) {
+            sc.setParameters("accountIdIN", permittedAccounts.toArray());
+        } else if (domainId != null) {
+            DomainVO domain = _domainDao.findById(domainId);
+            if (isRecursive) {
+                sc.setParameters("domainPath", domain.getPath() + "%");
+            } else {
+                sc.setParameters("domainId", domainId);
+            }
+        }
+
+    }
+
+    @Override
+    public UserAccount getUserByApiKey(String apiKey) {
+        return _userAccountDao.getUserByApiKey(apiKey);
+    }
+
+    @Override
+    public List<String> listAclGroupsByAccount(Long accountId) {
+        if (_querySelectors == null || _querySelectors.size() == 0) {
+            return new ArrayList<String>();
+        }
+
+        QuerySelector qs = _querySelectors.get(0);
+        return qs.listAclGroupsByAccount(accountId);
+    }
+
+    @Override
+    public Long finalyzeAccountId(final String accountName, final Long domainId, final Long projectId, final boolean enabledOnly) {
+        if (accountName != null) {
+            if (domainId == null) {
+                throw new InvalidParameterValueException("Account must be specified with domainId parameter");
+            }
+
+            final Domain domain = _domainMgr.getDomain(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Unable to find domain by id");
+            }
+
+            final Account account = getActiveAccountByName(accountName, domainId);
+            if (account != null && account.getType() != Account.ACCOUNT_TYPE_PROJECT) {
+                if (!enabledOnly || account.getState() == Account.State.enabled) {
+                    return account.getId();
+                } else {
+                    throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active");
+                }
+            } else {
+                // idList is not used anywhere, so removed it now
+                // List<IdentityProxy> idList = new ArrayList<IdentityProxy>();
+                // idList.add(new IdentityProxy("domain", domainId, "domainId"));
+                throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain with specified id");
+            }
+        }
+
+        if (projectId != null) {
+            final Project project = _projectMgr.getProject(projectId);
+            if (project != null) {
+                if (!enabledOnly || project.getState() == Project.State.Active) {
+                    return project.getProjectAccountId();
+                } else {
+                    final PermissionDeniedException ex = new PermissionDeniedException(
+                            "Can't add resources to the project with specified projectId in state=" + project.getState() + " as it's no longer active");
+                    ex.addProxyObject(project.getUuid(), "projectId");
+                    throw ex;
+                }
+            } else {
+                throw new InvalidParameterValueException("Unable to find project by id");
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public UserAccount getUserAccountById(Long userId) {
+        return _userAccountDao.findById(userId);
+    }
+
+    @Override
+    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
+        for (SecurityChecker checker : _securityCheckers) {
+            if (checker.checkAccess(account, so)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + account + " to " + so + " by " + checker.getName());
+                }
+                return;
+            }
+        }
+
+        assert false : "How can all of the security checkers pass on checking this caller?";
+        throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + so);
+    }
+
+    @Override
+    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
+        for (SecurityChecker checker : _securityCheckers) {
+            if (checker.checkAccess(account, dof)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + account + " to " + dof + " by " + checker.getName());
+                }
+                return;
+            }
+        }
+
+        assert false : "How can all of the security checkers pass on checking this caller?";
+        throw new PermissionDeniedException("There's no way to confirm " + account + " has access to " + dof);
+    }
+
+    @Override
+    public void checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
+        for (SecurityChecker checker : _securityCheckers) {
+            if (checker.checkAccess(user, entity)) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Access granted to " + user + "to " + entity + "by " + checker.getName());
+                }
+                return;
+            }
+        }
+        throw new PermissionDeniedException("There's no way to confirm " + user + " has access to " + entity);
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return AccountManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {UseSecretKeyInResponse};
+    }
+}
\ No newline at end of file
diff --git a/server/src/com/cloud/user/DomainManager.java b/server/src/main/java/com/cloud/user/DomainManager.java
similarity index 100%
rename from server/src/com/cloud/user/DomainManager.java
rename to server/src/main/java/com/cloud/user/DomainManager.java
diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/main/java/com/cloud/user/DomainManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/user/DomainManagerImpl.java
rename to server/src/main/java/com/cloud/user/DomainManagerImpl.java
diff --git a/server/src/main/java/com/cloud/uuididentity/UUIDManagerImpl.java b/server/src/main/java/com/cloud/uuididentity/UUIDManagerImpl.java
new file mode 100644
index 0000000..8f3e9a1
--- /dev/null
+++ b/server/src/main/java/com/cloud/uuididentity/UUIDManagerImpl.java
@@ -0,0 +1,128 @@
+// 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.uuididentity;
+
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.UUIDManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class UUIDManagerImpl implements UUIDManager {
+
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    AccountManager _accountMgr;
+    //TODO - Make this configurable.
+    private static final int UUID_RETRY = 3;
+
+    @Override
+    public <T> void checkUuid(String uuid, Class<T> entityType) {
+
+        if (uuid == null) {
+            return;
+        }
+
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Only admin and system allowed to do this
+        if (!(caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId()))) {
+            throw new PermissionDeniedException("Please check your permissions, you are not allowed to create/update custom id");
+        }
+
+        checkUuidSimple(uuid, entityType);
+    }
+
+    @Override
+    public <T> void checkUuidSimple(String uuid, Class<T> entityType) {
+
+        if (uuid == null) {
+            return;
+        }
+
+        // check format
+        if (!IsUuidFormat(uuid)) {
+            throw new InvalidParameterValueException("UUID: " + uuid + " doesn't follow the UUID format");
+        }
+
+        // check unique
+        if (!IsUuidUnique(entityType, uuid)) {
+            throw new InvalidParameterValueException("UUID: " + uuid + " already exists so can't create/update with custom id");
+        }
+
+    }
+
+    public boolean IsUuidFormat(String uuid) {
+
+        // Match against UUID regex to check if input is uuid string
+        boolean isUuid = uuid.matches("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
+        return isUuid;
+    }
+
+    public <T> boolean IsUuidUnique(Class<T> entityType, String uuid) {
+
+        T obj = _entityMgr.findByUuid(entityType, uuid);
+        if (obj != null) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public <T> String generateUuid(Class<T> entityType, String customId) {
+
+        if (customId == null) { // if no customid is passed then generate it.
+            int retry = UUID_RETRY;
+            while (retry-- != 0) {  // there might be collision so retry
+                String uuid = UUID.randomUUID().toString();
+                if (IsUuidUnique(entityType, uuid)) {
+                    return uuid;
+                }
+            }
+
+            throw new CloudRuntimeException("Unable to generate a unique uuid, please try again");
+        } else {
+            checkUuid(customId, entityType);
+            return customId;
+        }
+    }
+
+    @Override
+    public <T> String getUuid(Class<T> entityType, Long customId) {
+        if (customId == null) {
+            return null;
+        }
+        Identity identity = (Identity) this._entityMgr.findById(entityType, customId);
+        if (identity == null) {
+            throw new InvalidParameterValueException("Unable to find UUID for id " + customId);
+        }
+        return identity.getUuid();
+
+    }
+
+}
diff --git a/server/src/com/cloud/vm/SystemVmLoadScanHandler.java b/server/src/main/java/com/cloud/vm/SystemVmLoadScanHandler.java
similarity index 100%
rename from server/src/com/cloud/vm/SystemVmLoadScanHandler.java
rename to server/src/main/java/com/cloud/vm/SystemVmLoadScanHandler.java
diff --git a/server/src/com/cloud/vm/SystemVmLoadScanner.java b/server/src/main/java/com/cloud/vm/SystemVmLoadScanner.java
similarity index 100%
rename from server/src/com/cloud/vm/SystemVmLoadScanner.java
rename to server/src/main/java/com/cloud/vm/SystemVmLoadScanner.java
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/main/java/com/cloud/vm/UserVmManager.java
similarity index 100%
rename from server/src/com/cloud/vm/UserVmManager.java
rename to server/src/main/java/com/cloud/vm/UserVmManager.java
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
new file mode 100644
index 0000000..5caa059
--- /dev/null
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -0,0 +1,6644 @@
+// 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.vm;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.affinity.AffinityGroupService;
+import org.apache.cloudstack.affinity.AffinityGroupVO;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
+import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
+import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
+import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
+import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
+import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
+import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
+import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
+import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
+import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
+import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
+import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
+import org.apache.cloudstack.api.command.user.vm.SecurityGroupAction;
+import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
+import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
+import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
+import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
+import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetVmDiskStatsAnswer;
+import com.cloud.agent.api.GetVmDiskStatsCommand;
+import com.cloud.agent.api.GetVmIpAddressCommand;
+import com.cloud.agent.api.GetVmNetworkStatsAnswer;
+import com.cloud.agent.api.GetVmNetworkStatsCommand;
+import com.cloud.agent.api.GetVmStatsAnswer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVolumeStatsAnswer;
+import com.cloud.agent.api.GetVolumeStatsCommand;
+import com.cloud.agent.api.ModifyTargetsCommand;
+import com.cloud.agent.api.PvlanSetupCommand;
+import com.cloud.agent.api.RestoreVMSnapshotAnswer;
+import com.cloud.agent.api.RestoreVMSnapshotCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.VmDiskStatsEntry;
+import com.cloud.agent.api.VmNetworkStatsEntry;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.VolumeStatsEntry;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.DedicatedResourceVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.deploy.PlannerHostReservationVO;
+import com.cloud.deploy.dao.PlannerHostReservationDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.UsageEventVO;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.CloudException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ManagementServerException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.exception.VirtualMachineMigrationException;
+import com.cloud.gpu.GPU;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilitiesVO;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.LoadBalancerVMMapVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.security.SecurityGroup;
+import com.cloud.network.security.SecurityGroupManager;
+import com.cloud.network.security.dao.SecurityGroupDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.server.ManagementService;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.service.dao.ServiceOfferingDetailsDao;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.DiskOfferingDao;
+import com.cloud.storage.dao.GuestOSCategoryDao;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.template.TemplateApiService;
+import com.cloud.template.TemplateManager;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountService;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.SSHKeyPair;
+import com.cloud.user.SSHKeyPairVO;
+import com.cloud.user.User;
+import com.cloud.user.UserStatisticsVO;
+import com.cloud.user.UserVO;
+import com.cloud.user.VmDiskStatisticsVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.SSHKeyPairDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.user.dao.VmDiskStatisticsDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.Journal;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.utils.crypt.RSAHelper;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithException;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.db.UUIDManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.InstanceGroupDao;
+import com.cloud.vm.dao.InstanceGroupVMMapDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicExtraDhcpOptionDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import com.google.common.base.Strings;
+
+public class UserVmManagerImpl extends ManagerBase implements UserVmManager, VirtualMachineGuru, UserVmService, Configurable {
+    private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
+
+    /**
+     * The number of seconds to wait before timing out when trying to acquire a global lock.
+     */
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 3;
+
+    private static final long GiB_TO_BYTES = 1024 * 1024 * 1024;
+
+    @Inject
+    private EntityManager _entityMgr;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private DiskOfferingDao _diskOfferingDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private VMTemplateZoneDao _templateZoneDao;
+    @Inject
+    private TemplateDataStoreDao _templateStoreDao;
+    @Inject
+    private DomainDao _domainDao;
+    @Inject
+    private UserVmDao _vmDao;
+    @Inject
+    private VolumeDao _volsDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private FirewallRulesDao _rulesDao;
+    @Inject
+    private LoadBalancerVMMapDao _loadBalancerVMMapDao;
+    @Inject
+    private PortForwardingRulesDao _portForwardingDao;
+    @Inject
+    private IPAddressDao _ipAddressDao;
+    @Inject
+    private HostPodDao _podDao;
+    @Inject
+    private NetworkModel _networkModel;
+    @Inject
+    private NetworkOrchestrationService _networkMgr;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private ConfigurationManager _configMgr;
+    @Inject
+    private AccountDao _accountDao;
+    @Inject
+    private UserDao _userDao;
+    @Inject
+    private SnapshotDao _snapshotDao;
+    @Inject
+    private GuestOSDao _guestOSDao;
+    @Inject
+    private HighAvailabilityManager _haMgr;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private AccountService _accountService;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    private PrimaryDataStoreDao _storagePoolDao;
+    @Inject
+    private SecurityGroupManager _securityGroupMgr;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    private InstanceGroupDao _vmGroupDao;
+    @Inject
+    private InstanceGroupVMMapDao _groupVMMapDao;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    private NicDao _nicDao;
+    @Inject
+    private RulesManager _rulesMgr;
+    @Inject
+    private LoadBalancingRulesManager _lbMgr;
+    @Inject
+    private SSHKeyPairDao _sshKeyPairDao;
+    @Inject
+    private UserVmDetailsDao userVmDetailsDao;
+    @Inject
+    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
+    @Inject
+    private SecurityGroupDao _securityGroupDao;
+    @Inject
+    private CapacityManager _capacityMgr;
+    @Inject
+    private VMInstanceDao _vmInstanceDao;
+    @Inject
+    private ResourceLimitService _resourceLimitMgr;
+    @Inject
+    private FirewallManager _firewallMgr;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    private PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    private VpcManager _vpcMgr;
+    @Inject
+    private TemplateManager _templateMgr;
+    @Inject
+    private GuestOSCategoryDao _guestOSCategoryDao;
+    @Inject
+    private UsageEventDao _usageEventDao;
+    @Inject
+    private VmDiskStatisticsDao _vmDiskStatsDao;
+    @Inject
+    private VMSnapshotDao _vmSnapshotDao;
+    @Inject
+    private VMSnapshotManager _vmSnapshotMgr;
+    @Inject
+    private AffinityGroupVMMapDao _affinityGroupVMMapDao;
+    @Inject
+    private AffinityGroupDao _affinityGroupDao;
+    @Inject
+    private DedicatedResourceDao _dedicatedDao;
+    @Inject
+    private AffinityGroupService _affinityGroupService;
+    @Inject
+    private PlannerHostReservationDao _plannerHostReservationDao;
+    @Inject
+    private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
+    @Inject
+    private UserStatisticsDao _userStatsDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    private VolumeService _volService;
+    @Inject
+    private VolumeDataFactory volFactory;
+    @Inject
+    private UUIDManager _uuidMgr;
+    @Inject
+    private DeploymentPlanningManager _planningMgr;
+    @Inject
+    private VolumeApiService _volumeService;
+    @Inject
+    private DataStoreManager _dataStoreMgr;
+    @Inject
+    private VpcVirtualNetworkApplianceManager _virtualNetAppliance;
+    @Inject
+    private DomainRouterDao _routerDao;
+    @Inject
+    private VMNetworkMapDao _vmNetworkMapDao;
+    @Inject
+    private IpAddressManager _ipAddrMgr;
+    @Inject
+    private NicExtraDhcpOptionDao _nicExtraDhcpOptionDao;
+    @Inject
+    private TemplateApiService _tmplService;
+    @Inject
+    private ConfigurationDao _configDao;
+
+    private ScheduledExecutorService _executor = null;
+    private ScheduledExecutorService _vmIpFetchExecutor = null;
+    private int _expungeInterval;
+    private int _expungeDelay;
+    private boolean _dailyOrHourly = false;
+    private int capacityReleaseInterval;
+    private ExecutorService _vmIpFetchThreadExecutor;
+
+
+    private String _instance;
+    private boolean _instanceNameFlag;
+    private int _scaleRetry;
+    private Map<Long, VmAndCountDetails> vmIdCountMap = new ConcurrentHashMap<>();
+
+    private static final int MAX_HTTP_GET_LENGTH = 2 * MAX_USER_DATA_LENGTH_BYTES;
+    private static final int MAX_HTTP_POST_LENGTH = 16 * MAX_USER_DATA_LENGTH_BYTES;
+
+    @Inject
+    private OrchestrationService _orchSrvc;
+
+    @Inject
+    private VolumeOrchestrationService volumeMgr;
+
+    @Inject
+    private ManagementService _mgr;
+
+    private static final ConfigKey<Integer> VmIpFetchWaitInterval = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.retrieval.interval", "180",
+            "Wait Interval (in seconds) for shared network vm dhcp ip addr fetch for next iteration ", true);
+
+    private static final ConfigKey<Integer> VmIpFetchTrialMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.max.retry", "10",
+            "The max number of retrieval times for shared entwork vm dhcp ip fetch, in case of failures", true);
+
+    private static final ConfigKey<Integer> VmIpFetchThreadPoolMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipFetch.threadPool.max", "10",
+            "number of threads for fetching vms ip address", true);
+
+    private static final ConfigKey<Integer> VmIpFetchTaskWorkers = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipfetchtask.workers", "10",
+            "number of worker threads for vm ip fetch task ", true);
+
+    private static final ConfigKey<Boolean> AllowDeployVmIfGivenHostFails = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.deploy.vm.if.deploy.on.given.host.fails", "false",
+            "allow vm to deploy on different host if vm fails to deploy on the given host ", true);
+
+    private static final ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>("Advanced", Boolean.class, "enable.additional.vm.configuration",
+            "false", "allow additional arbitrary configuration to vm", true, ConfigKey.Scope.Account);
+    private static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
+            "On destroy, force-stop takes this value ", true);
+
+
+    @Override
+    public UserVmVO getVirtualMachine(long vmId) {
+        return _vmDao.findById(vmId);
+    }
+
+    @Override
+    public List<? extends UserVm> getVirtualMachines(long hostId) {
+        return _vmDao.listByHostId(hostId);
+    }
+
+    private void resourceLimitCheck(Account owner, Boolean displayVm, Long cpu, Long memory) throws ResourceAllocationException {
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm, displayVm);
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, displayVm, cpu);
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, displayVm, memory);
+    }
+
+    private void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
+        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
+        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
+        _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
+    }
+
+    private void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
+        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
+        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
+        _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
+    }
+
+    public class VmAndCountDetails {
+        long vmId;
+        int  retrievalCount = VmIpFetchTrialMax.value();
+
+
+        public VmAndCountDetails() {
+        }
+
+        public VmAndCountDetails (long vmId, int retrievalCount) {
+            this.vmId = vmId;
+            this.retrievalCount = retrievalCount;
+        }
+
+        public VmAndCountDetails (long vmId) {
+            this.vmId = vmId;
+        }
+
+        public int getRetrievalCount() {
+            return retrievalCount;
+        }
+
+        public void setRetrievalCount(int retrievalCount) {
+            this.retrievalCount = retrievalCount;
+        }
+
+        public long getVmId() {
+            return vmId;
+        }
+
+        public void setVmId(long vmId) {
+            this.vmId = vmId;
+        }
+
+        public void decrementCount() {
+            this.retrievalCount--;
+
+        }
+    }
+
+    private class VmIpAddrFetchThread extends ManagedContextRunnable {
+
+
+        long nicId;
+        long vmId;
+        String vmName;
+        boolean isWindows;
+        Long hostId;
+        String networkCidr;
+
+        public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
+            this.vmId = vmId;
+            this.nicId = nicId;
+            this.vmName = instanceName;
+            this.isWindows = windows;
+            this.hostId = hostId;
+            this.networkCidr = networkCidr;
+        }
+
+        @Override
+        protected void runInContext() {
+            GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
+            boolean decrementCount = true;
+
+            try {
+                s_logger.debug("Trying for vm "+ vmId +" nic Id "+nicId +" ip retrieval ...");
+                Answer answer = _agentMgr.send(hostId, cmd);
+                NicVO nic = _nicDao.findById(nicId);
+                if (answer.getResult()) {
+                    String vmIp = answer.getDetails();
+
+                    if (NetUtils.isValidIp4(vmIp)) {
+                        // set this vm ip addr in vm nic.
+                        if (nic != null) {
+                            nic.setIPv4Address(vmIp);
+                            _nicDao.update(nicId, nic);
+                            s_logger.debug("Vm "+ vmId +" IP "+vmIp +" got retrieved successfully");
+                            vmIdCountMap.remove(nicId);
+                            decrementCount = false;
+                            ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
+                                    Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
+                                    "VM " + vmId + " nic id " + nicId + " ip address " + vmIp + " got fetched successfully");
+                        }
+                    }
+                } else {
+                    //previously vm has ip and nic table has ip address. After vm restart or stop/start
+                    //if vm doesnot get the ip then set the ip in nic table to null
+                    if (nic.getIPv4Address() != null) {
+                        nic.setIPv4Address(null);
+                        _nicDao.update(nicId, nic);
+                    }
+                    if (answer.getDetails() != null) {
+                        s_logger.debug("Failed to get vm ip for Vm "+ vmId + answer.getDetails());
+                    }
+                }
+            } catch (OperationTimedoutException e) {
+                s_logger.warn("Timed Out", e);
+            } catch (AgentUnavailableException e) {
+                s_logger.warn("Agent Unavailable ", e);
+            } finally {
+                if (decrementCount) {
+                    VmAndCountDetails vmAndCount = vmIdCountMap.get(nicId);
+                    vmAndCount.decrementCount();
+                    s_logger.debug("Ip is not retrieved for VM " + vmId +" nic "+nicId + " ... decremented count to "+vmAndCount.getRetrievalCount());
+                    vmIdCountMap.put(nicId, vmAndCount);
+                }
+            }
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_RESETPASSWORD, eventDescription = "resetting Vm password", async = true)
+    public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long vmId = cmd.getId();
+        UserVmVO userVm = _vmDao.findById(cmd.getId());
+
+        // Do parameters input validation
+        if (userVm == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + cmd.getId());
+        }
+
+        _vmDao.loadDetails(userVm);
+
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
+        if (template == null || !template.isEnablePassword()) {
+            throw new InvalidParameterValueException("Fail to reset password for the virtual machine, the template is not password enabled");
+        }
+
+        if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
+            s_logger.error("vm is not in the right state: " + vmId);
+            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
+        }
+
+        if (userVm.getState() != State.Stopped) {
+            s_logger.error("vm is not in the right state: " + vmId);
+            throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do password reset");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, userVm);
+
+        boolean result = resetVMPasswordInternal(vmId, password);
+
+        if (result) {
+            userVm.setPassword(password);
+        } else {
+            throw new CloudRuntimeException("Failed to reset password for the virtual machine ");
+        }
+
+        return userVm;
+    }
+
+    private boolean resetVMPasswordInternal(Long vmId, String password) throws ResourceUnavailableException, InsufficientCapacityException {
+        Long userId = CallContext.current().getCallingUserId();
+        VMInstanceVO vmInstance = _vmDao.findById(vmId);
+
+        if (password == null || password.equals("")) {
+            return false;
+        }
+
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
+        if (template.isEnablePassword()) {
+            Nic defaultNic = _networkModel.getDefaultNic(vmId);
+            if (defaultNic == null) {
+                s_logger.error("Unable to reset password for vm " + vmInstance + " as the instance doesn't have default nic");
+                return false;
+            }
+
+            Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
+            NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork),
+                    _networkModel.getNetworkTag(template.getHypervisorType(), defaultNetwork));
+            VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
+            vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
+
+            UserDataServiceProvider element = _networkMgr.getPasswordResetProvider(defaultNetwork);
+            if (element == null) {
+                throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for password reset");
+            }
+
+            boolean result = element.savePassword(defaultNetwork, defaultNicProfile, vmProfile);
+
+            // Need to reboot the virtual machine so that the password gets
+            // redownloaded from the DomR, and reset on the VM
+            if (!result) {
+                s_logger.debug("Failed to reset password for the virtual machine; no need to reboot the vm");
+                return false;
+            } else {
+                final UserVmVO userVm = _vmDao.findById(vmId);
+                _vmDao.loadDetails(userVm);
+                // update the password in vm_details table too
+                // Check if an SSH key pair was selected for the instance and if so
+                // use it to encrypt & save the vm password
+                encryptAndStorePassword(userVm, password);
+
+                if (vmInstance.getState() == State.Stopped) {
+                    s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of password reset");
+                    return true;
+                }
+
+                if (rebootVirtualMachine(userId, vmId) == null) {
+                    s_logger.warn("Failed to reboot the vm " + vmInstance);
+                    return false;
+                } else {
+                    s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of password reset");
+                    return true;
+                }
+            }
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Reset password called for a vm that is not using a password enabled template");
+            }
+            return false;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_RESETSSHKEY, eventDescription = "resetting Vm SSHKey", async = true)
+    public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
+        Long vmId = cmd.getId();
+
+        UserVmVO userVm = _vmDao.findById(cmd.getId());
+        if (userVm == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine by id" + cmd.getId());
+        }
+
+        _vmDao.loadDetails(userVm);
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
+
+        // Do parameters input validation
+
+        if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
+            s_logger.error("vm is not in the right state: " + vmId);
+            throw new InvalidParameterValueException("Vm with specified id is not in the right state");
+        }
+        if (userVm.getState() != State.Stopped) {
+            s_logger.error("vm is not in the right state: " + vmId);
+            throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do SSH Key reset");
+        }
+
+        SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
+        if (s == null) {
+            throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName()
+            + " in specified domain id");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, userVm);
+        String password = null;
+        String sshPublicKey = s.getPublicKey();
+        if (template != null && template.isEnablePassword()) {
+            password = _mgr.generateRandomPassword();
+        }
+
+        boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password);
+
+        if (!result) {
+            throw new CloudRuntimeException("Failed to reset SSH Key for the virtual machine ");
+        }
+        return userVm;
+    }
+
+    private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String password) throws ResourceUnavailableException, InsufficientCapacityException {
+        Long userId = CallContext.current().getCallingUserId();
+        VMInstanceVO vmInstance = _vmDao.findById(vmId);
+
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
+        Nic defaultNic = _networkModel.getDefaultNic(vmId);
+        if (defaultNic == null) {
+            s_logger.error("Unable to reset SSH Key for vm " + vmInstance + " as the instance doesn't have default nic");
+            return false;
+        }
+
+        Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
+        NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork),
+                _networkModel.getNetworkTag(template.getHypervisorType(), defaultNetwork));
+
+        VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
+
+        if (template.isEnablePassword()) {
+            vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
+        }
+
+        UserDataServiceProvider element = _networkMgr.getSSHKeyResetProvider(defaultNetwork);
+        if (element == null) {
+            throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for SSH Key reset");
+        }
+        boolean result = element.saveSSHKey(defaultNetwork, defaultNicProfile, vmProfile, sshPublicKey);
+
+        // Need to reboot the virtual machine so that the password gets redownloaded from the DomR, and reset on the VM
+        if (!result) {
+            s_logger.debug("Failed to reset SSH Key for the virtual machine; no need to reboot the vm");
+            return false;
+        } else {
+            final UserVmVO userVm = _vmDao.findById(vmId);
+            _vmDao.loadDetails(userVm);
+            userVm.setDetail("SSH.PublicKey", sshPublicKey);
+            if (template.isEnablePassword()) {
+                userVm.setPassword(password);
+                //update the encrypted password in vm_details table too
+                encryptAndStorePassword(userVm, password);
+            } else {
+                _vmDao.saveDetails(userVm);
+            }
+
+            if (vmInstance.getState() == State.Stopped) {
+                s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of SSH Key reset");
+                return true;
+            }
+            if (rebootVirtualMachine(userId, vmId) == null) {
+                s_logger.warn("Failed to reboot the vm " + vmInstance);
+                return false;
+            } else {
+                s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of SSH Key reset");
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public boolean stopVirtualMachine(long userId, long vmId) {
+        boolean status = false;
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Stopping vm=" + vmId);
+        }
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null || vm.getRemoved() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is either removed or deleted.");
+            }
+            return true;
+        }
+
+        _userDao.findById(userId);
+        try {
+            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
+            status = vmEntity.stop(Long.toString(userId));
+        } catch (ResourceUnavailableException e) {
+            s_logger.debug("Unable to stop due to ", e);
+            status = false;
+        } catch (CloudException e) {
+            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
+        }
+        return status;
+    }
+
+    private UserVm rebootVirtualMachine(long userId, long vmId) throws InsufficientCapacityException, ResourceUnavailableException {
+        UserVmVO vm = _vmDao.findById(vmId);
+
+        if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
+            s_logger.warn("Vm id=" + vmId + " doesn't exist");
+            return null;
+        }
+
+        if (vm.getState() == State.Running && vm.getHostId() != null) {
+            collectVmDiskStatistics(vm);
+            collectVmNetworkStatistics(vm);
+            DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
+            try {
+                if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
+                    //List all networks of vm
+                    List<Long> vmNetworks = _vmNetworkMapDao.getNetworks(vmId);
+                    List<DomainRouterVO> routers = new ArrayList<DomainRouterVO>();
+                    //List the stopped routers
+                    for(long vmNetworkId : vmNetworks) {
+                        List<DomainRouterVO> router = _routerDao.listStopped(vmNetworkId);
+                        routers.addAll(router);
+                    }
+                    //A vm may not have many nics attached and even fewer routers might be stopped (only in exceptional cases)
+                    //Safe to start the stopped router serially, this is consistent with the way how multiple networks are added to vm during deploy
+                    //and routers are started serially ,may revisit to make this process parallel
+                    for(DomainRouterVO routerToStart : routers) {
+                        s_logger.warn("Trying to start router " + routerToStart.getInstanceName() + " as part of vm: " + vm.getInstanceName() + " reboot");
+                        _virtualNetAppliance.startRouter(routerToStart.getId(),true);
+                    }
+                }
+            } catch (ConcurrentOperationException e) {
+                throw new CloudRuntimeException("Concurrent operations on starting router. " + e);
+            } catch (Exception ex){
+                throw new CloudRuntimeException("Router start failed due to" + ex);
+            }finally {
+                s_logger.info("Rebooting vm " + vm.getInstanceName());
+                _itMgr.reboot(vm.getUuid(), null);
+            }
+            return _vmDao.findById(vmId);
+        } else {
+            s_logger.error("Vm id=" + vmId + " is not in Running state, failed to reboot");
+            return null;
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "upgrading Vm")
+    /*
+     * TODO: cleanup eventually - Refactored API call
+     */
+    // This method will be deprecated as we use ScaleVMCmd for both stopped VMs and running VMs
+    public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException {
+        Long vmId = cmd.getId();
+        Long svcOffId = cmd.getServiceOfferingId();
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify input parameters
+        //UserVmVO vmInstance = _vmDao.findById(vmId);
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        } else if (!(vmInstance.getState().equals(State.Stopped))) {
+            throw new InvalidParameterValueException("Unable to upgrade virtual machine " + vmInstance.toString() + " " + " in state " + vmInstance.getState()
+            + "; make sure the virtual machine is stopped");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        // Check resource limits for CPU and Memory.
+        Map<String, String> customParameters = cmd.getDetails();
+        ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
+        if (newServiceOffering.isDynamic()) {
+            newServiceOffering.setDynamicFlag(true);
+            validateCustomParameters(newServiceOffering, cmd.getDetails());
+            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
+        }
+        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+
+        int newCpu = newServiceOffering.getCpu();
+        int newMemory = newServiceOffering.getRamSize();
+        int currentCpu = currentServiceOffering.getCpu();
+        int currentMemory = currentServiceOffering.getRamSize();
+
+        if (newCpu > currentCpu) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
+        }
+        if (newMemory > currentMemory) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
+        }
+
+        // Check that the specified service offering ID is valid
+        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
+
+        _itMgr.upgradeVmDb(vmId, svcOffId);
+        if (newServiceOffering.isDynamic()) {
+            //save the custom values to the database.
+            saveCustomOfferingDetails(vmId, newServiceOffering);
+        }
+        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
+            removeCustomOfferingDetails(vmId);
+        }
+
+        // Increment or decrement CPU and Memory count accordingly.
+        if (newCpu > currentCpu) {
+            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
+        } else if (currentCpu > newCpu) {
+            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
+        }
+        if (newMemory > currentMemory) {
+            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
+        } else if (currentMemory > newMemory) {
+            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
+        }
+
+        // Generate usage event for VM upgrade
+        UserVmVO userVm = _vmDao.findById(vmId);
+        generateUsageEvent( userVm, userVm.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
+
+        return userVm;
+    }
+
+    @Override
+    public void validateCustomParameters(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
+        if (customParameters.size() != 0) {
+            if (serviceOffering.getCpu() == null) {
+                String cpuNumber = customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name());
+                if ((cpuNumber == null) || (NumbersUtil.parseInt(cpuNumber, -1) <= 0)) {
+                    throw new InvalidParameterValueException("Invalid cpu cores value, specify a value between 1 and " + Integer.MAX_VALUE);
+                }
+            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
+                throw new InvalidParameterValueException("The cpu cores of this offering id:" + serviceOffering.getId()
+                + " is not customizable. This is predefined in the template.");
+            }
+
+            if (serviceOffering.getSpeed() == null) {
+                String cpuSpeed = customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name());
+                if ((cpuSpeed == null) || (NumbersUtil.parseInt(cpuSpeed, -1) <= 0)) {
+                    throw new InvalidParameterValueException("Invalid cpu speed value, specify a value between 1 and " + Integer.MAX_VALUE);
+                }
+            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
+                throw new InvalidParameterValueException("The cpu speed of this offering id:" + serviceOffering.getId()
+                + " is not customizable. This is predefined in the template.");
+            }
+
+            if (serviceOffering.getRamSize() == null) {
+                String memory = customParameters.get(UsageEventVO.DynamicParameters.memory.name());
+                if (memory == null || (NumbersUtil.parseInt(memory, -1) < 32)) {
+                    throw new InvalidParameterValueException("Invalid memory value, specify a value between 32 and " + Integer.MAX_VALUE + " MB");
+                }
+            } else if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
+                throw new InvalidParameterValueException("The memory of this offering id:" + serviceOffering.getId() + " is not customizable. This is predefined in the template.");
+            }
+        } else {
+            throw new InvalidParameterValueException("Need to specify custom parameter values cpu, cpu speed and memory when using custom offering");
+        }
+    }
+
+    private UserVm upgradeStoppedVirtualMachine(Long vmId, Long svcOffId, Map<String, String> customParameters) throws ResourceAllocationException {
+        Account caller = CallContext.current().getCallingAccount();
+
+        // Verify input parameters
+        //UserVmVO vmInstance = _vmDao.findById(vmId);
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        // Check resource limits for CPU and Memory.
+        ServiceOfferingVO newServiceOffering = _offeringDao.findById(svcOffId);
+        if (newServiceOffering.isDynamic()) {
+            newServiceOffering.setDynamicFlag(true);
+            validateCustomParameters(newServiceOffering, customParameters);
+            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
+        }
+        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+
+        int newCpu = newServiceOffering.getCpu();
+        int newMemory = newServiceOffering.getRamSize();
+        int currentCpu = currentServiceOffering.getCpu();
+        int currentMemory = currentServiceOffering.getRamSize();
+
+        if (newCpu > currentCpu) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
+        }
+        if (newMemory > currentMemory) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
+        }
+
+        // Check that the specified service offering ID is valid
+        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
+
+        DiskOfferingVO newROOTDiskOffering = _diskOfferingDao.findById(newServiceOffering.getId());
+
+        List<VolumeVO> vols = _volsDao.findReadyRootVolumesByInstance(vmInstance.getId());
+
+        for (final VolumeVO rootVolumeOfVm : vols) {
+            rootVolumeOfVm.setDiskOfferingId(newROOTDiskOffering.getId());
+
+            _volsDao.update(rootVolumeOfVm.getId(), rootVolumeOfVm);
+
+            ResizeVolumeCmd resizeVolumeCmd = new ResizeVolumeCmd(rootVolumeOfVm.getId(), newROOTDiskOffering.getMinIops(), newROOTDiskOffering.getMaxIops());
+
+            _volumeService.resizeVolume(resizeVolumeCmd);
+        }
+
+        // Check if the new service offering can be applied to vm instance
+        ServiceOffering newSvcOffering = _offeringDao.findById(svcOffId);
+        Account owner = _accountMgr.getActiveAccountById(vmInstance.getAccountId());
+        _accountMgr.checkAccess(owner, newSvcOffering);
+
+        _itMgr.upgradeVmDb(vmId, svcOffId);
+        if (newServiceOffering.isDynamic()) {
+            //save the custom values to the database.
+            saveCustomOfferingDetails(vmId, newServiceOffering);
+        }
+        if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
+            removeCustomOfferingDetails(vmId);
+        }
+
+        // Increment or decrement CPU and Memory count accordingly.
+        if (newCpu > currentCpu) {
+            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
+        } else if (currentCpu > newCpu) {
+            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(currentCpu - newCpu));
+        }
+        if (newMemory > currentMemory) {
+            _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(newMemory - currentMemory));
+        } else if (currentMemory > newMemory) {
+            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(currentMemory - newMemory));
+        }
+
+        return _vmDao.findById(vmInstance.getId());
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_CREATE, eventDescription = "Creating Nic", async = true)
+    public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
+        Long vmId = cmd.getVmId();
+        Long networkId = cmd.getNetworkId();
+        String ipAddress = cmd.getIpAddress();
+        String macAddress = cmd.getMacAddress();
+        Account caller = CallContext.current().getCallingAccount();
+
+        UserVmVO vmInstance = _vmDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
+            throw new InvalidParameterValueException("NIC cannot be added to VM with VM Snapshots");
+        }
+
+        NetworkVO network = _networkDao.findById(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("unable to find a network with id " + networkId);
+        }
+
+        if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+            if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain)
+                    && !(network.getAclType() == ACLType.Account && network.getAccountId() == vmInstance.getAccountId())) {
+                throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vmId: " + vmId);
+            }
+        }
+
+        List<NicVO> allNics = _nicDao.listByVmId(vmInstance.getId());
+        for (NicVO nic : allNics) {
+            if (nic.getNetworkId() == network.getId()) {
+                throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid());
+            }
+        }
+
+        macAddress = validateOrReplaceMacAddress(macAddress, network.getId());
+
+        if(_nicDao.findByNetworkIdAndMacAddress(networkId, macAddress) != null) {
+            throw new CloudRuntimeException("A NIC with this MAC address exists for network: " + network.getUuid());
+        }
+
+        NicProfile profile = new NicProfile(ipAddress, null, macAddress);
+        if (ipAddress != null) {
+            if (!(NetUtils.isValidIp4(ipAddress) || NetUtils.isValidIp6(ipAddress))) {
+                throw new InvalidParameterValueException("Invalid format for IP address parameter: " + ipAddress);
+            }
+        }
+
+        // Perform permission check on VM
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't add a new NIC to a VM on a Basic Network");
+        }
+
+        // Perform account permission check on network
+        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
+
+        //ensure network belongs in zone
+        if (network.getDataCenterId() != vmInstance.getDataCenterId()) {
+            throw new CloudRuntimeException(vmInstance + " is in zone:" + vmInstance.getDataCenterId() + " but " + network + " is in zone:" + network.getDataCenterId());
+        }
+
+        // Get all vms hostNames in the network
+        List<String> hostNames = _vmInstanceDao.listDistinctHostNames(network.getId());
+        // verify that there are no duplicates, listDistictHostNames could return hostNames even if the NIC
+        //in the network is removed, so also check if the NIC is present and then throw an exception.
+        //This will also check if there are multiple nics of same vm in the network
+        if (hostNames.contains(vmInstance.getHostName())) {
+            for (String hostName : hostNames) {
+                VMInstanceVO vm = _vmInstanceDao.findVMByHostName(hostName);
+                if (_networkModel.getNicInNetwork(vm.getId(), network.getId()) != null && vm.getHostName().equals(vmInstance.getHostName())) {
+                    throw new CloudRuntimeException(network + " already has a vm with host name: " + vmInstance.getHostName());
+                }
+            }
+        }
+
+        NicProfile guestNic = null;
+        boolean cleanUp = true;
+
+        try {
+            guestNic = _itMgr.addVmToNetwork(vmInstance, network, profile);
+            saveExtraDhcpOptions(guestNic.getId(), cmd.getDhcpOptionsMap());
+            _networkMgr.configureExtraDhcpOptions(network, guestNic.getId(), cmd.getDhcpOptionsMap());
+            cleanUp = false;
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + ": " + e);
+        } catch (InsufficientCapacityException e) {
+            throw new CloudRuntimeException("Insufficient capacity when adding NIC to " + vmInstance + ": " + e);
+        } catch (ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Concurrent operations on adding NIC to " + vmInstance + ": " + e);
+        } finally {
+            if(cleanUp) {
+                try {
+                    _itMgr.removeVmFromNetwork(vmInstance, network, null);
+                } catch (ResourceUnavailableException e) {
+                    throw new CloudRuntimeException("Error while cleaning up NIC " + e);
+                }
+            }
+        }
+        CallContext.current().putContextParameter(Nic.class, guestNic.getUuid());
+        s_logger.debug("Successful addition of " + network + " from " + vmInstance);
+        return _vmDao.findById(vmInstance.getId());
+    }
+
+    /**
+     * If the given MAC address is invalid it replaces the given MAC with the next available MAC address
+     */
+    protected String validateOrReplaceMacAddress(String macAddress, long networkId) {
+        if (!NetUtils.isValidMac(macAddress)) {
+            try {
+                macAddress = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
+            } catch (InsufficientAddressCapacityException e) {
+                throw new CloudRuntimeException(String.format("A MAC address cannot be generated for this NIC in the network [id=%s] ", networkId));
+            }
+        }
+        return macAddress;
+    }
+
+    private void saveExtraDhcpOptions(long nicId, Map<Integer, String> dhcpOptions) {
+        List<NicExtraDhcpOptionVO> nicExtraDhcpOptionVOList = dhcpOptions
+                .entrySet()
+                .stream()
+                .map(entry -> new NicExtraDhcpOptionVO(nicId, entry.getKey(), entry.getValue()))
+                .collect(Collectors.toList());
+
+        _nicExtraDhcpOptionDao.saveExtraDhcpOptions(nicExtraDhcpOptionVOList);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_DELETE, eventDescription = "Removing Nic", async = true)
+    public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
+        Long vmId = cmd.getVmId();
+        Long nicId = cmd.getNicId();
+        Account caller = CallContext.current().getCallingAccount();
+
+        UserVmVO vmInstance = _vmDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
+            throw new InvalidParameterValueException("NIC cannot be removed from VM with VM Snapshots");
+        }
+
+        NicVO nic = _nicDao.findById(nicId);
+        if (nic == null) {
+            throw new InvalidParameterValueException("Unable to find a nic with id " + nicId);
+        }
+
+        NetworkVO network = _networkDao.findById(nic.getNetworkId());
+        if (network == null) {
+            throw new InvalidParameterValueException("Unable to find a network with id " + nic.getNetworkId());
+        }
+
+        // Perform permission check on VM
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new InvalidParameterValueException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't remove a NIC from a VM on a Basic Network");
+        }
+
+        // check to see if nic is attached to VM
+        if (nic.getInstanceId() != vmId) {
+            throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance);
+        }
+
+        // Perform account permission check on network
+        _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
+
+        // don't delete default NIC on a user VM
+        if (nic.isDefaultNic() && vmInstance.getType() == VirtualMachine.Type.User) {
+            throw new InvalidParameterValueException("Unable to remove nic from " + vmInstance + " in " + network + ", nic is default.");
+        }
+
+        // if specified nic is associated with PF/LB/Static NAT
+        if (_rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0) {
+            throw new InvalidParameterValueException("Unable to remove nic from " + vmInstance + " in " + network + ", nic has associated Port forwarding or Load balancer or Static NAT rules.");
+        }
+
+        boolean nicremoved = false;
+        try {
+            nicremoved = _itMgr.removeNicFromVm(vmInstance, nic);
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance + ": " + e);
+
+        } catch (ConcurrentOperationException e) {
+            throw new CloudRuntimeException("Concurrent operations on removing " + network + " from " + vmInstance + ": " + e);
+        }
+
+        if (!nicremoved) {
+            throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance);
+        }
+
+        s_logger.debug("Successful removal of " + network + " from " + vmInstance);
+        return _vmDao.findById(vmInstance.getId());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_NIC_UPDATE, eventDescription = "Creating Nic", async = true)
+    public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) throws InvalidParameterValueException, CloudRuntimeException {
+        Long vmId = cmd.getVmId();
+        Long nicId = cmd.getNicId();
+        Account caller = CallContext.current().getCallingAccount();
+
+        UserVmVO vmInstance = _vmDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
+            throw new InvalidParameterValueException("NIC cannot be updated for VM with VM Snapshots");
+        }
+
+        NicVO nic = _nicDao.findById(nicId);
+        if (nic == null) {
+            throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
+        }
+        NetworkVO network = _networkDao.findById(nic.getNetworkId());
+        if (network == null) {
+            throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId());
+        }
+
+        // Perform permission check on VM
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterId());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterId() + ", has a NetworkType of Basic. Can't change default NIC on a Basic Network");
+        }
+
+        // no need to check permissions for network, we'll enumerate the ones they already have access to
+        Network existingdefaultnet = _networkModel.getDefaultNetworkForVm(vmId);
+
+        //check to see if nic is attached to VM
+        if (nic.getInstanceId() != vmId) {
+            throw new InvalidParameterValueException(nic + " is not a nic on  " + vmInstance);
+        }
+        // if current default equals chosen new default, Throw an exception
+        if (nic.isDefaultNic()) {
+            throw new CloudRuntimeException("refusing to set default nic because chosen nic is already the default");
+        }
+
+        //make sure the VM is Running or Stopped
+        if ((vmInstance.getState() != State.Running) && (vmInstance.getState() != State.Stopped)) {
+            throw new CloudRuntimeException("refusing to set default " + vmInstance + " is not Running or Stopped");
+        }
+
+        NicProfile existing = null;
+        List<NicProfile> nicProfiles = _networkMgr.getNicProfiles(vmInstance);
+        for (NicProfile nicProfile : nicProfiles) {
+            if (nicProfile.isDefaultNic() && existingdefaultnet != null && nicProfile.getNetworkId() == existingdefaultnet.getId()) {
+                existing = nicProfile;
+            }
+        }
+
+        if (existing == null) {
+            s_logger.warn("Failed to update default nic, no nic profile found for existing default network");
+            throw new CloudRuntimeException("Failed to find a nic profile for the existing default network. This is bad and probably means some sort of configuration corruption");
+        }
+
+        Network oldDefaultNetwork = null;
+        oldDefaultNetwork = _networkModel.getDefaultNetworkForVm(vmId);
+        String oldNicIdString = Long.toString(_networkModel.getDefaultNic(vmId).getId());
+        long oldNetworkOfferingId = -1L;
+
+        if (oldDefaultNetwork != null) {
+            oldNetworkOfferingId = oldDefaultNetwork.getNetworkOfferingId();
+        }
+        NicVO existingVO = _nicDao.findById(existing.id);
+        Integer chosenID = nic.getDeviceId();
+        Integer existingID = existing.getDeviceId();
+
+        nic.setDefaultNic(true);
+        nic.setDeviceId(existingID);
+        existingVO.setDefaultNic(false);
+        existingVO.setDeviceId(chosenID);
+
+        nic = _nicDao.persist(nic);
+        existingVO = _nicDao.persist(existingVO);
+
+        Network newdefault = null;
+        newdefault = _networkModel.getDefaultNetworkForVm(vmId);
+
+        if (newdefault == null) {
+            nic.setDefaultNic(false);
+            nic.setDeviceId(chosenID);
+            existingVO.setDefaultNic(true);
+            existingVO.setDeviceId(existingID);
+
+            nic = _nicDao.persist(nic);
+            _nicDao.persist(existingVO);
+
+            newdefault = _networkModel.getDefaultNetworkForVm(vmId);
+            if (newdefault.getId() == existingdefaultnet.getId()) {
+                throw new CloudRuntimeException("Setting a default nic failed, and we had no default nic, but we were able to set it back to the original");
+            }
+            throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default");
+        } else if (newdefault.getId() == nic.getNetworkId()) {
+            s_logger.debug("successfully set default network to " + network + " for " + vmInstance);
+            String nicIdString = Long.toString(nic.getId());
+            long newNetworkOfferingId = network.getNetworkOfferingId();
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(),
+                    oldNicIdString, oldNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), nicIdString,
+                    newNetworkOfferingId, null, 1L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(), nicIdString,
+                    newNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vmInstance.getAccountId(), vmInstance.getDataCenterId(), vmInstance.getId(),
+                    oldNicIdString, oldNetworkOfferingId, null, 0L, VirtualMachine.class.getName(), vmInstance.getUuid(), vmInstance.isDisplay());
+
+            if (vmInstance.getState() != State.Stopped) {
+                try {
+                    VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
+                    User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+                    ReservationContext context = new ReservationContextImpl(null, null, callerUser, caller);
+                    DeployDestination dest = new DeployDestination(dc, null, null, null);
+                    _networkMgr.prepare(vmProfile, dest, context);
+                } catch (final Exception e) {
+                    s_logger.info("Got exception: ", e);
+                }
+            }
+
+            return _vmDao.findById(vmInstance.getId());
+        }
+
+        throw new CloudRuntimeException("something strange happened, new default network(" + newdefault.getId() + ") is not null, and is not equal to the network("
+                + nic.getNetworkId() + ") of the chosen nic");
+    }
+
+    @Override
+    public UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd) {
+        Long nicId = cmd.getNicId();
+        String ipaddr = cmd.getIpaddress();
+        Account caller = CallContext.current().getCallingAccount();
+
+        //check whether the nic belongs to user vm.
+        NicVO nicVO = _nicDao.findById(nicId);
+        if (nicVO == null) {
+            throw new InvalidParameterValueException("There is no nic for the " + nicId);
+        }
+
+        if (nicVO.getVmType() != VirtualMachine.Type.User) {
+            throw new InvalidParameterValueException("The nic is not belongs to user vm");
+        }
+
+        UserVm vm = _vmDao.findById(nicVO.getInstanceId());
+        if (vm == null) {
+            throw new InvalidParameterValueException("There is no vm with the nic");
+        }
+
+        Network network = _networkDao.findById(nicVO.getNetworkId());
+        if (network == null) {
+            throw new InvalidParameterValueException("There is no network with the nic");
+        }
+        // Don't allow to update vm nic ip if network is not in Implemented/Setup/Allocated state
+        if (!(network.getState() == Network.State.Allocated || network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) {
+            throw new InvalidParameterValueException("Network is not in the right state to update vm nic ip. Correct states are: " + Network.State.Allocated + ", " + Network.State.Implemented + ", "
+                    + Network.State.Setup);
+        }
+
+        NetworkOfferingVO offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
+        if (offering == null) {
+            throw new InvalidParameterValueException("There is no network offering with the network");
+        }
+        if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && vm.getState() != State.Stopped) {
+            InvalidParameterValueException ex = new InvalidParameterValueException(
+                    "VM is not Stopped, unable to update the vm nic having the specified id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        // verify permissions
+        _accountMgr.checkAccess(caller, null, true, vm);
+        Account ipOwner = _accountDao.findByIdIncludingRemoved(vm.getAccountId());
+
+        // verify ip address
+        s_logger.debug("Calling the ip allocation ...");
+        DataCenter dc = _dcDao.findById(network.getDataCenterId());
+        if (dc == null) {
+            throw new InvalidParameterValueException("There is no dc with the nic");
+        }
+        if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
+            try {
+                ipaddr = _ipAddrMgr.allocateGuestIP(network, ipaddr);
+            } catch (InsufficientAddressCapacityException e) {
+                throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
+            }
+            if (ipaddr == null) {
+                throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
+            }
+
+            if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
+                IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmId(vm.getId());
+                if (oldIP != null) {
+                    oldIP.setVmIp(ipaddr);
+                    _ipAddressDao.persist(oldIP);
+                }
+            }
+            // implementing the network elements and resources as a part of vm nic ip update if network has services and it is in Implemented state
+            if (!_networkModel.listNetworkOfferingServices(offering.getId()).isEmpty() && network.getState() == Network.State.Implemented) {
+                User callerUser = _accountMgr.getActiveUser(CallContext.current().getCallingUserId());
+                ReservationContext context = new ReservationContextImpl(null, null, callerUser, caller);
+                DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
+
+                s_logger.debug("Implementing the network " + network + " elements and resources as a part of vm nic ip update");
+                try {
+                    // implement the network elements and rules again
+                    _networkMgr.implementNetworkElementsAndResources(dest, context, network, offering);
+                } catch (Exception ex) {
+                    s_logger.warn("Failed to implement network " + network + " elements and resources as a part of vm nic ip update due to ", ex);
+                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of vm nic ip update");
+                    e.addProxyObject(network.getUuid(), "networkId");
+                    // restore to old ip address
+                    if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) {
+                        IPAddressVO oldIP = _ipAddressDao.findByAssociatedVmId(vm.getId());
+                        if (oldIP != null) {
+                            oldIP.setVmIp(nicVO.getIPv4Address());
+                            _ipAddressDao.persist(oldIP);
+                        }
+                    }
+                    throw e;
+                }
+            }
+        } else if (dc.getNetworkType() == NetworkType.Basic || network.getGuestType()  == Network.GuestType.Shared) {
+            //handle the basic networks here
+            //for basic zone, need to provide the podId to ensure proper ip alloation
+            Long podId = null;
+            if (dc.getNetworkType() == NetworkType.Basic) {
+                podId = vm.getPodIdToDeployIn();
+                if (podId == null) {
+                    throw new InvalidParameterValueException("vm pod id is null in Basic zone; can't decide the range for ip allocation");
+                }
+            }
+
+            try {
+                ipaddr = _ipAddrMgr.allocatePublicIpForGuestNic(network, podId, ipOwner, ipaddr);
+                if (ipaddr == null) {
+                    throw new InvalidParameterValueException("Allocating ip to guest nic " + nicVO.getUuid() + " failed, please choose another ip");
+                }
+
+                final IPAddressVO newIp = _ipAddressDao.findByIpAndDcId(dc.getId(), ipaddr);
+                final Vlan vlan = _vlanDao.findById(newIp.getVlanId());
+                nicVO.setIPv4Gateway(vlan.getVlanGateway());
+                nicVO.setIPv4Netmask(vlan.getVlanNetmask());
+
+                final IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nicVO.getNetworkId(), nicVO.getIPv4Address());
+                if (ip != null) {
+                    Transaction.execute(new TransactionCallbackNoReturn() {
+                        @Override
+                        public void doInTransactionWithoutResult(TransactionStatus status) {
+                            _ipAddrMgr.markIpAsUnavailable(ip.getId());
+                            _ipAddressDao.unassignIpAddress(ip.getId());
+                        }
+                    });
+                }
+            } catch (InsufficientAddressCapacityException e) {
+                s_logger.error("Allocating ip to guest nic " + nicVO.getUuid() + " failed, for insufficient address capacity");
+                return null;
+            }
+        } else {
+            s_logger.error("UpdateVmNicIpCmd is not supported in this network...");
+            return null;
+        }
+
+        s_logger.debug("Updating IPv4 address of NIC " + nicVO + " to " + ipaddr + "/" + nicVO.getIPv4Netmask() + " with gateway " + nicVO.getIPv4Gateway());
+        nicVO.setIPv4Address(ipaddr);
+        _nicDao.persist(nicVO);
+
+        return vm;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_UPGRADE, eventDescription = "Upgrading VM", async = true)
+    public UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
+    VirtualMachineMigrationException {
+
+        Long vmId = cmd.getId();
+        Long newServiceOfferingId = cmd.getServiceOfferingId();
+        VirtualMachine vm = (VirtualMachine) this._entityMgr.findById(VirtualMachine.class, vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find VM's UUID");
+        }
+        CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
+
+        boolean result = upgradeVirtualMachine(vmId, newServiceOfferingId, cmd.getDetails());
+        if (result) {
+            UserVmVO vmInstance = _vmDao.findById(vmId);
+            if (vmInstance.getState().equals(State.Stopped)) {
+                // Generate usage event for VM upgrade
+                generateUsageEvent(vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
+            }
+            if (vmInstance.getState().equals(State.Running)) {
+                // Generate usage event for Dynamic scaling of VM
+                generateUsageEvent( vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_DYNAMIC_SCALE);
+            }
+            return vmInstance;
+        } else {
+            throw new CloudRuntimeException("Failed to scale the VM");
+        }
+    }
+
+    @Override
+    public HashMap<Long, List<VmDiskStatsEntry>> getVmDiskStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
+        HashMap<Long, List<VmDiskStatsEntry>> vmDiskStatsById = new HashMap<Long, List<VmDiskStatsEntry>>();
+
+        if (vmIds.isEmpty()) {
+            return vmDiskStatsById;
+        }
+
+        List<String> vmNames = new ArrayList<String>();
+
+        for (Long vmId : vmIds) {
+            UserVmVO vm = _vmDao.findById(vmId);
+            vmNames.add(vm.getInstanceName());
+        }
+
+        Answer answer = _agentMgr.easySend(hostId, new GetVmDiskStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
+        if (answer == null || !answer.getResult()) {
+            s_logger.warn("Unable to obtain VM disk statistics.");
+            return null;
+        } else {
+            HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = ((GetVmDiskStatsAnswer)answer).getVmDiskStatsMap();
+
+            if (vmDiskStatsByName == null) {
+                s_logger.warn("Unable to obtain VM disk statistics.");
+                return null;
+            }
+
+            for (Map.Entry<String, List<VmDiskStatsEntry>> entry: vmDiskStatsByName.entrySet()) {
+                vmDiskStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue());
+            }
+        }
+
+        return vmDiskStatsById;
+    }
+
+    @Override
+    public boolean upgradeVirtualMachine(Long vmId, Long newServiceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
+
+        // Verify input parameters
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+
+        if (vmInstance != null) {
+            if (vmInstance.getState().equals(State.Stopped)) {
+                upgradeStoppedVirtualMachine(vmId, newServiceOfferingId, customParameters);
+                return true;
+            }
+            if (vmInstance.getState().equals(State.Running)) {
+                return upgradeRunningVirtualMachine(vmId, newServiceOfferingId, customParameters);
+            }
+        }
+        return false;
+    }
+
+    private boolean upgradeRunningVirtualMachine(Long vmId, Long newServiceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+        if (vmInstance.getHypervisorType() != HypervisorType.XenServer && vmInstance.getHypervisorType() != HypervisorType.VMware && vmInstance.getHypervisorType() != HypervisorType.Simulator) {
+            s_logger.info("Scaling the VM dynamically is not supported for VMs running on Hypervisor "+vmInstance.getHypervisorType());
+            throw new InvalidParameterValueException("Scaling the VM dynamically is not supported for VMs running on Hypervisor "+vmInstance.getHypervisorType());
+        }
+
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        //Check if its a scale "up"
+        ServiceOfferingVO newServiceOffering = _offeringDao.findById(newServiceOfferingId);
+        if (newServiceOffering.isDynamic()) {
+            newServiceOffering.setDynamicFlag(true);
+            validateCustomParameters(newServiceOffering, customParameters);
+            newServiceOffering = _offeringDao.getcomputeOffering(newServiceOffering, customParameters);
+        }
+
+        // Check that the specified service offering ID is valid
+        _itMgr.checkIfCanUpgrade(vmInstance, newServiceOffering);
+
+        ServiceOfferingVO currentServiceOffering = _offeringDao.findByIdIncludingRemoved(vmInstance.getId(), vmInstance.getServiceOfferingId());
+        int newCpu = newServiceOffering.getCpu();
+        int newMemory = newServiceOffering.getRamSize();
+        int newSpeed = newServiceOffering.getSpeed();
+        int currentCpu = currentServiceOffering.getCpu();
+        int currentMemory = currentServiceOffering.getRamSize();
+        int currentSpeed = currentServiceOffering.getSpeed();
+        int memoryDiff = newMemory - currentMemory;
+        int cpuDiff = newCpu * newSpeed - currentCpu * currentSpeed;
+
+        // Don't allow to scale when (Any of the new values less than current values) OR (All current and new values are same)
+        if ((newSpeed < currentSpeed || newMemory < currentMemory || newCpu < currentCpu) || (newSpeed == currentSpeed && newMemory == currentMemory && newCpu == currentCpu)) {
+            throw new InvalidParameterValueException("Only scaling up the vm is supported, new service offering(speed=" + newSpeed + ",cpu=" + newCpu + ",memory=," + newMemory
+                    + ")" + " should have at least one value(cpu/ram) greater than old value and no resource value less than older(speed=" + currentSpeed + ",cpu=" + currentCpu
+                    + ",memory=," + currentMemory + ")");
+        }
+
+        _offeringDao.loadDetails(currentServiceOffering);
+        _offeringDao.loadDetails(newServiceOffering);
+
+        Map<String, String> currentDetails = currentServiceOffering.getDetails();
+        Map<String, String> newDetails = newServiceOffering.getDetails();
+        String currentVgpuType = currentDetails.get("vgpuType");
+        String newVgpuType = newDetails.get("vgpuType");
+        if(currentVgpuType != null) {
+            if(newVgpuType == null || !newVgpuType.equalsIgnoreCase(currentVgpuType)) {
+                throw new InvalidParameterValueException("Dynamic scaling of vGPU type is not supported. VM has vGPU Type: " + currentVgpuType);
+            }
+        }
+
+        // Check resource limits
+        if (newCpu > currentCpu) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.cpu, newCpu - currentCpu);
+        }
+        if (newMemory > currentMemory) {
+            _resourceLimitMgr.checkResourceLimit(caller, ResourceType.memory, newMemory - currentMemory);
+        }
+
+        // Dynamically upgrade the running vms
+        boolean success = false;
+        if (vmInstance.getState().equals(State.Running)) {
+            int retry = _scaleRetry;
+            ExcludeList excludes = new ExcludeList();
+
+            // Check zone wide flag
+            boolean enableDynamicallyScaleVm = EnableDynamicallyScaleVm.valueIn(vmInstance.getDataCenterId());
+            if (!enableDynamicallyScaleVm) {
+                throw new PermissionDeniedException("Dynamically scaling virtual machines is disabled for this zone, please contact your admin");
+            }
+
+            // Check vm flag
+            if (!vmInstance.isDynamicallyScalable()) {
+                throw new CloudRuntimeException("Unable to Scale the vm: " + vmInstance.getUuid() + " as vm does not have tools to support dynamic scaling");
+            }
+
+            // Check disable threshold for cluster is not crossed
+            HostVO host = _hostDao.findById(vmInstance.getHostId());
+            if (_capacityMgr.checkIfClusterCrossesThreshold(host.getClusterId(), cpuDiff, memoryDiff)) {
+                throw new CloudRuntimeException("Unable to scale vm: " + vmInstance.getUuid() + " due to insufficient resources");
+            }
+
+            while (retry-- != 0) { // It's != so that it can match -1.
+                try {
+                    boolean existingHostHasCapacity = false;
+
+                    // Increment CPU and Memory count accordingly.
+                    if (newCpu > currentCpu) {
+                        _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
+                    }
+
+                    if (memoryDiff > 0) {
+                        _resourceLimitMgr.incrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
+                    }
+
+                    // #1 Check existing host has capacity
+                    if (!excludes.shouldAvoid(ApiDBUtils.findHostById(vmInstance.getHostId()))) {
+                        existingHostHasCapacity = _capacityMgr.checkIfHostHasCpuCapability(vmInstance.getHostId(), newCpu, newSpeed)
+                                && _capacityMgr.checkIfHostHasCapacity(vmInstance.getHostId(), cpuDiff, (memoryDiff) * 1024L * 1024L, false,
+                                        _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_CPU),
+                                        _capacityMgr.getClusterOverProvisioningFactor(host.getClusterId(), Capacity.CAPACITY_TYPE_MEMORY), false);
+                        excludes.addHost(vmInstance.getHostId());
+                    }
+
+                    // #2 migrate the vm if host doesn't have capacity or is in avoid set
+                    if (!existingHostHasCapacity) {
+                        _itMgr.findHostAndMigrate(vmInstance.getUuid(), newServiceOfferingId, excludes);
+                    }
+
+                    // #3 scale the vm now
+                    _itMgr.upgradeVmDb(vmId, newServiceOfferingId);
+                    if (newServiceOffering.isDynamic()) {
+                        //save the custom values to the database.
+                        saveCustomOfferingDetails(vmId, newServiceOffering);
+                    }
+                    vmInstance = _vmInstanceDao.findById(vmId);
+                    _itMgr.reConfigureVm(vmInstance.getUuid(), currentServiceOffering, existingHostHasCapacity);
+                    success = true;
+                    if (currentServiceOffering.isDynamic() && !newServiceOffering.isDynamic()) {
+                        removeCustomOfferingDetails(vmId);
+                    }
+                    return success;
+                } catch (InsufficientCapacityException e) {
+                    s_logger.warn("Received exception while scaling ", e);
+                } catch (ResourceUnavailableException e) {
+                    s_logger.warn("Received exception while scaling ", e);
+                } catch (ConcurrentOperationException e) {
+                    s_logger.warn("Received exception while scaling ", e);
+                } catch (Exception e) {
+                    s_logger.warn("Received exception while scaling ", e);
+                } finally {
+                    if (!success) {
+                        _itMgr.upgradeVmDb(vmId, currentServiceOffering.getId()); // rollback
+
+                        // Decrement CPU and Memory count accordingly.
+                        if (newCpu > currentCpu) {
+                            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.cpu, new Long(newCpu - currentCpu));
+                        }
+                        //restoring old service offering will take care of removing new SO.
+                        if(currentServiceOffering.isDynamic()){
+                            saveCustomOfferingDetails(vmId, currentServiceOffering);
+                        }
+
+                        if (memoryDiff > 0) {
+                            _resourceLimitMgr.decrementResourceCount(caller.getAccountId(), ResourceType.memory, new Long(memoryDiff));
+                        }
+                    }
+                }
+            }
+        }
+        return success;
+    }
+
+    @Override
+    public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering) {
+        //save the custom values to the database.
+        Map<String, String> details = userVmDetailsDao.listDetailsKeyPairs(vmId);
+        details.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
+        details.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
+        details.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
+        List<UserVmDetailVO> detailList = new ArrayList<UserVmDetailVO>();
+        for (Map.Entry<String, String> entry: details.entrySet()) {
+            UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true);
+            detailList.add(detailVO);
+        }
+        userVmDetailsDao.saveDetails(detailList);
+    }
+
+    @Override
+    public void removeCustomOfferingDetails(long vmId) {
+        Map<String, String> details = userVmDetailsDao.listDetailsKeyPairs(vmId);
+        details.remove(UsageEventVO.DynamicParameters.cpuNumber.name());
+        details.remove(UsageEventVO.DynamicParameters.cpuSpeed.name());
+        details.remove(UsageEventVO.DynamicParameters.memory.name());
+        List<UserVmDetailVO> detailList = new ArrayList<UserVmDetailVO>();
+        for(Map.Entry<String, String> entry: details.entrySet()) {
+            UserVmDetailVO detailVO = new UserVmDetailVO(vmId, entry.getKey(), entry.getValue(), true);
+            detailList.add(detailVO);
+        }
+        userVmDetailsDao.saveDetails(detailList);
+    }
+
+    @Override
+    public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
+        HashMap<Long, VmStatsEntry> vmStatsById = new HashMap<Long, VmStatsEntry>();
+
+        if (vmIds.isEmpty()) {
+            return vmStatsById;
+        }
+
+        List<String> vmNames = new ArrayList<String>();
+
+        for (Long vmId : vmIds) {
+            UserVmVO vm = _vmDao.findById(vmId);
+            vmNames.add(vm.getInstanceName());
+        }
+
+        Answer answer = _agentMgr.easySend(hostId, new GetVmStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
+        if (answer == null || !answer.getResult()) {
+            s_logger.warn("Unable to obtain VM statistics.");
+            return null;
+        } else {
+            HashMap<String, VmStatsEntry> vmStatsByName = ((GetVmStatsAnswer)answer).getVmStatsMap();
+
+            if (vmStatsByName == null) {
+                s_logger.warn("Unable to obtain VM statistics.");
+                return null;
+            }
+
+            for (Map.Entry<String, VmStatsEntry> entry : vmStatsByName.entrySet()) {
+                vmStatsById.put(vmIds.get(vmNames.indexOf(entry.getKey())), entry.getValue());
+            }
+        }
+
+        return vmStatsById;
+    }
+
+    @Override
+    public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocator, int timeout) {
+        List<HostVO> neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up);
+        for (HostVO neighbor : neighbors) {
+            GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocator);
+            if (timeout > 0) {
+                cmd.setWait(timeout/1000);
+            }
+            Answer answer = _agentMgr.easySend(neighbor.getId(), cmd);
+            if (answer instanceof GetVolumeStatsAnswer){
+                GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer)answer;
+                return volstats.getVolumeStats();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    @DB
+    public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {
+
+        final Long vmId = cmd.getId();
+        Account caller = CallContext.current().getCallingAccount();
+        final Long userId = caller.getAccountId();
+
+        // Verify input parameters
+        final UserVmVO vm = _vmDao.findById(vmId);
+
+        if (vm == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
+        if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
+            throw new PermissionDeniedException("Recovering a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
+        }
+
+        if (vm.getRemoved() != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to find vm or vm is removed: " + vmId);
+            }
+            throw new InvalidParameterValueException("Unable to find vm by id " + vmId);
+        }
+
+        if (vm.getState() != State.Destroyed) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("vm is not in the right state: " + vmId);
+            }
+            throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Recovering vm " + vmId);
+        }
+
+        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
+            @Override public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
+
+                Account account = _accountDao.lockRow(vm.getAccountId(), true);
+
+                // if the account is deleted, throw error
+                if (account.getRemoved() != null) {
+                    throw new CloudRuntimeException("Unable to recover VM as the account is deleted");
+                }
+
+                // Get serviceOffering for Virtual Machine
+                ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
+
+                // First check that the maximum number of UserVMs, CPU and Memory limit for the given
+                // accountId will not be exceeded
+                resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
+
+                _haMgr.cancelDestroy(vm, vm.getHostId());
+
+                try {
+                    if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
+                        s_logger.debug("Unable to recover the vm because it is not in the correct state: " + vmId);
+                        throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
+                    }
+                } catch (NoTransitionException e) {
+                    throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
+                }
+
+                // Recover the VM's disks
+                List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
+                for (VolumeVO volume : volumes) {
+                    if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
+                        // Create an event
+                        Long templateId = volume.getTemplateId();
+                        Long diskOfferingId = volume.getDiskOfferingId();
+                        Long offeringId = null;
+                        if (diskOfferingId != null) {
+                            DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
+                            if (offering != null && (offering.getType() == DiskOfferingVO.Type.Disk)) {
+                                offeringId = offering.getId();
+                            }
+                        }
+                        UsageEventUtils
+                        .publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId,
+                                templateId, volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
+                    }
+                }
+
+                //Update Resource Count for the given account
+                resourceCountIncrement(account.getId(), vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
+            }
+        });
+
+        return _vmDao.findById(vmId);
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+
+        if (_configDao == null) {
+            throw new ConfigurationException("Unable to get the configuration dao.");
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
+
+        _instance = configs.get("instance.name");
+        if (_instance == null) {
+            _instance = "DEFAULT";
+        }
+
+        String workers = configs.get("expunge.workers");
+        int wrks = NumbersUtil.parseInt(workers, 10);
+        capacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.CapacitySkipcountingHours.key()), 3600);
+
+        String time = configs.get("expunge.interval");
+        _expungeInterval = NumbersUtil.parseInt(time, 86400);
+        time = configs.get("expunge.delay");
+        _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval);
+
+        _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
+
+        String vmIpWorkers = configs.get(VmIpFetchTaskWorkers.value());
+        int vmipwrks = NumbersUtil.parseInt(vmIpWorkers, 10);
+
+        _vmIpFetchExecutor =   Executors.newScheduledThreadPool(vmipwrks, new NamedThreadFactory("UserVm-ipfetch"));
+
+        String aggregationRange = configs.get("usage.stats.job.aggregation.range");
+        int _usageAggregationRange  = NumbersUtil.parseInt(aggregationRange, 1440);
+        int HOURLY_TIME = 60;
+        final int DAILY_TIME = 60 * 24;
+        if (_usageAggregationRange == DAILY_TIME) {
+            _dailyOrHourly = true;
+        } else if (_usageAggregationRange == HOURLY_TIME) {
+            _dailyOrHourly = true;
+        } else {
+            _dailyOrHourly = false;
+        }
+
+        _itMgr.registerGuru(VirtualMachine.Type.User, this);
+
+        VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao, _vmDao, this, _configDao));
+
+        String value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
+        _instanceNameFlag = (value == null) ? false : Boolean.parseBoolean(value);
+
+        _scaleRetry = NumbersUtil.parseInt(configs.get(Config.ScaleRetry.key()), 2);
+
+        _vmIpFetchThreadExecutor = Executors.newFixedThreadPool(VmIpFetchThreadPoolMax.value(), new NamedThreadFactory("vmIpFetchThread"));
+
+        s_logger.info("User VM Manager is configured.");
+
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        _executor.scheduleWithFixedDelay(new ExpungeTask(), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
+        _vmIpFetchExecutor.scheduleWithFixedDelay(new VmIpFetchTask(), VmIpFetchWaitInterval.value(), VmIpFetchWaitInterval.value(), TimeUnit.SECONDS);
+        loadVmDetailsInMapForExternalDhcpIp();
+        return true;
+    }
+
+    private void loadVmDetailsInMapForExternalDhcpIp() {
+
+        List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
+
+        for (NetworkVO network: networks) {
+            if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
+
+                for (NicVO nic : nics) {
+
+                    if (nic.getIPv4Address() == null) {
+                        long nicId = nic.getId();
+                        long vmId = nic.getInstanceId();
+                        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+
+                        // only load running vms. For stopped vms get loaded on starting
+                        if (vmInstance.getState() == State.Running) {
+                            VmAndCountDetails vmAndCount = new VmAndCountDetails(vmId, VmIpFetchTrialMax.value());
+                            vmIdCountMap.put(nicId, vmAndCount);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean stop() {
+        _executor.shutdown();
+        _vmIpFetchExecutor.shutdown();
+        return true;
+    }
+
+    public String getRandomPrivateTemplateName() {
+        return UUID.randomUUID().toString();
+    }
+
+    @Override
+    public boolean expunge(UserVmVO vm, long callerUserId, Account caller) {
+        vm = _vmDao.acquireInLockTable(vm.getId());
+        if (vm == null) {
+            return false;
+        }
+        try {
+
+            releaseNetworkResourcesOnExpunge(vm.getId());
+
+            List<VolumeVO> rootVol = _volsDao.findByInstanceAndType(vm.getId(), Volume.Type.ROOT);
+            // expunge the vm
+            _itMgr.advanceExpunge(vm.getUuid());
+            // Update Resource count
+            if (vm.getAccountId() != Account.ACCOUNT_ID_SYSTEM && !rootVol.isEmpty()) {
+                _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume);
+                _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(rootVol.get(0).getSize()));
+            }
+
+            // Only if vm is not expunged already, cleanup it's resources
+            if (vm.getRemoved() == null) {
+                // Cleanup vm resources - all the PF/LB/StaticNat rules
+                // associated with vm
+                s_logger.debug("Starting cleaning up vm " + vm + " resources...");
+                if (cleanupVmResources(vm.getId())) {
+                    s_logger.debug("Successfully cleaned up vm " + vm + " resources as a part of expunge process");
+                } else {
+                    s_logger.warn("Failed to cleanup resources as a part of vm " + vm + " expunge");
+                    return false;
+                }
+
+                _vmDao.remove(vm.getId());
+            }
+
+            return true;
+
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to expunge  " + vm, e);
+            return false;
+        } catch (OperationTimedoutException e) {
+            s_logger.warn("Operation time out on expunging " + vm, e);
+            return false;
+        } catch (ConcurrentOperationException e) {
+            s_logger.warn("Concurrent operations on expunging " + vm, e);
+            return false;
+        } finally {
+            _vmDao.releaseFromLockTable(vm.getId());
+        }
+    }
+
+    /**
+     * Release network resources, it was done on vm stop previously.
+     * @param id vm id
+     * @throws ConcurrentOperationException
+     * @throws ResourceUnavailableException
+     */
+    private void releaseNetworkResourcesOnExpunge(long id) throws ConcurrentOperationException, ResourceUnavailableException {
+        final VMInstanceVO vmInstance = _vmDao.findById(id);
+        if (vmInstance != null){
+            final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vmInstance);
+            _networkMgr.release(profile, false);
+        }
+        else {
+            s_logger.error("Couldn't find vm with id = " + id + ", unable to release network resources");
+        }
+    }
+
+    private boolean cleanupVmResources(long vmId) {
+        boolean success = true;
+        // Remove vm from security groups
+        _securityGroupMgr.removeInstanceFromGroups(vmId);
+
+        // Remove vm from instance group
+        removeInstanceFromInstanceGroup(vmId);
+
+        // cleanup firewall rules
+        if (_firewallMgr.revokeFirewallRulesForVm(vmId)) {
+            s_logger.debug("Firewall rules are removed successfully as a part of vm id=" + vmId + " expunge");
+        } else {
+            success = false;
+            s_logger.warn("Fail to remove firewall rules as a part of vm id=" + vmId + " expunge");
+        }
+
+        // cleanup port forwarding rules
+        if (_rulesMgr.revokePortForwardingRulesForVm(vmId)) {
+            s_logger.debug("Port forwarding rules are removed successfully as a part of vm id=" + vmId + " expunge");
+        } else {
+            success = false;
+            s_logger.warn("Fail to remove port forwarding rules as a part of vm id=" + vmId + " expunge");
+        }
+
+        // cleanup load balancer rules
+        if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
+            s_logger.debug("Removed vm id=" + vmId + " from all load balancers as a part of expunge process");
+        } else {
+            success = false;
+            s_logger.warn("Fail to remove vm id=" + vmId + " from load balancers as a part of expunge process");
+        }
+
+        // If vm is assigned to static nat, disable static nat for the ip
+        // address and disassociate ip if elasticIP is enabled
+        List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(vmId);
+
+        for (IPAddressVO ip : ips) {
+            try {
+                if (_rulesMgr.disableStaticNat(ip.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM, true)) {
+                    s_logger.debug("Disabled 1-1 nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
+                } else {
+                    s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge");
+                    success = false;
+                }
+            } catch (ResourceUnavailableException e) {
+                success = false;
+                s_logger.warn("Failed to disable static nat for ip address " + ip + " as a part of vm id=" + vmId + " expunge because resource is unavailable", e);
+            }
+        }
+
+        return success;
+    }
+
+    @Override
+    public void deletePrivateTemplateRecord(Long templateId) {
+        if (templateId != null) {
+            _templateDao.remove(templateId);
+        }
+    }
+
+    // used for vm transitioning to error state
+    private void updateVmStateForFailedVmCreation(Long vmId, Long hostId) {
+
+        UserVmVO vm = _vmDao.findById(vmId);
+
+        if (vm != null) {
+            if (vm.getState().equals(State.Stopped)) {
+                s_logger.debug("Destroying vm " + vm + " as it failed to create on Host with Id:" + hostId);
+                try {
+                    _itMgr.stateTransitTo(vm, VirtualMachine.Event.OperationFailedToError, null);
+                } catch (NoTransitionException e1) {
+                    s_logger.warn(e1.getMessage());
+                }
+                // destroy associated volumes for vm in error state
+                // get all volumes in non destroyed state
+                List<VolumeVO> volumesForThisVm = _volsDao.findUsableVolumesForInstance(vm.getId());
+                for (VolumeVO volume : volumesForThisVm) {
+                    if (volume.getState() != Volume.State.Destroy) {
+                        volumeMgr.destroyVolume(volume);
+                    }
+                }
+                String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId;
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+
+                // Get serviceOffering for Virtual Machine
+                ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
+
+                // Update Resource Count for the given account
+                resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
+            }
+        }
+    }
+
+
+
+    private class VmIpFetchTask extends ManagedContextRunnable {
+
+        @Override
+        protected void runInContext() {
+            GlobalLock scanLock = GlobalLock.getInternLock("vmIpFetch");
+            try {
+                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                    try {
+
+                        for (Entry<Long, VmAndCountDetails> entry:   vmIdCountMap.entrySet()) {
+                            long nicId = entry.getKey();
+                            VmAndCountDetails vmIdAndCount = entry.getValue();
+                            long vmId = vmIdAndCount.getVmId();
+
+                            if (vmIdAndCount.getRetrievalCount() <= 0) {
+                                vmIdCountMap.remove(nicId);
+                                s_logger.debug("Vm " + vmId +" nic "+nicId + " count is zero .. removing vm nic from map ");
+
+                                ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
+                                        Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
+                                        "VM " + vmId + " nic id "+ nicId + " ip addr fetch failed ");
+
+                                continue;
+                            }
+
+
+                            UserVm userVm = _vmDao.findById(vmId);
+                            VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+                            NicVO nicVo = _nicDao.findById(nicId);
+                            NetworkVO network = _networkDao.findById(nicVo.getNetworkId());
+
+                            VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(userVm);
+                            VirtualMachine vm = vmProfile.getVirtualMachine();
+                            boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+
+                            _vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
+                                    isWindows, vm.getHostId(), network.getCidr()));
+
+                        }
+                    } catch (Exception e) {
+                        s_logger.error("Caught the Exception in VmIpFetchTask", e);
+                    } finally {
+                        scanLock.unlock();
+                    }
+                }
+            } finally {
+                scanLock.releaseRef();
+            }
+
+        }
+    }
+
+
+    private class ExpungeTask extends ManagedContextRunnable {
+        public ExpungeTask() {
+        }
+
+        @Override
+        protected void runInContext() {
+            GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
+            try {
+                if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+                    try {
+                        List<UserVmVO> vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long)_expungeDelay << 10)));
+                        if (s_logger.isInfoEnabled()) {
+                            if (vms.size() == 0) {
+                                s_logger.trace("Found " + vms.size() + " vms to expunge.");
+                            } else {
+                                s_logger.info("Found " + vms.size() + " vms to expunge.");
+                            }
+                        }
+                        for (UserVmVO vm : vms) {
+                            try {
+                                expungeVm(vm.getId());
+                            } catch (Exception e) {
+                                s_logger.warn("Unable to expunge " + vm, e);
+                            }
+                        }
+                    } catch (Exception e) {
+                        s_logger.error("Caught the following Exception", e);
+                    } finally {
+                        scanLock.unlock();
+                    }
+                }
+            } finally {
+                scanLock.releaseRef();
+            }
+        }
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_UPDATE, eventDescription = "updating Vm")
+    public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException {
+        validateInputsAndPermissionForUpdateVirtualMachineCommand(cmd);
+
+        String displayName = cmd.getDisplayName();
+        String group = cmd.getGroup();
+        Boolean ha = cmd.getHaEnable();
+        Boolean isDisplayVm = cmd.getDisplayVm();
+        Long id = cmd.getId();
+        Long osTypeId = cmd.getOsTypeId();
+        String userData = cmd.getUserData();
+        Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
+        String hostName = cmd.getHostName();
+        Map<String,String> details = cmd.getDetails();
+        List<Long> securityGroupIdList = getSecurityGroupIdList(cmd);
+        boolean cleanupDetails = cmd.isCleanupDetails();
+        String extraConfig = cmd.getExtraConfig();
+
+        UserVmVO vmInstance = _vmDao.findById(cmd.getId());
+        long accountId = vmInstance.getAccountId();
+
+        if (isDisplayVm != null && isDisplayVm != vmInstance.isDisplay()) {
+            updateDisplayVmFlag(isDisplayVm, id, vmInstance);
+        }
+        if (cleanupDetails){
+            userVmDetailsDao.removeDetails(id);
+        }
+        else {
+            if (MapUtils.isNotEmpty(details)) {
+                vmInstance.setDetails(details);
+                _vmDao.saveDetails(vmInstance);
+            }
+            if (StringUtils.isNotBlank(extraConfig) && EnableAdditionalVmConfig.valueIn(accountId)) {
+                AccountVO account = _accountDao.findById(accountId);
+                addExtraConfig(vmInstance, account, extraConfig);
+            }
+        }
+        return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable,
+                cmd.getHttpMethod(), cmd.getCustomId(), hostName, cmd.getInstanceName(), securityGroupIdList, cmd.getDhcpOptionsMap());
+    }
+
+    protected void updateDisplayVmFlag(Boolean isDisplayVm, Long id, UserVmVO vmInstance) {
+        vmInstance.setDisplayVm(isDisplayVm);
+
+        // Resource limit changes
+        ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
+        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm);
+        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu()));
+        _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize()));
+
+        // Usage
+        saveUsageEvent(vmInstance);
+
+        // take care of the root volume as well.
+        List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(id, Volume.Type.ROOT);
+        if (!rootVols.isEmpty()) {
+            _volumeService.updateDisplay(rootVols.get(0), isDisplayVm);
+        }
+
+        // take care of the data volumes as well.
+        List<VolumeVO> dataVols = _volsDao.findByInstanceAndType(id, Volume.Type.DATADISK);
+        for (Volume dataVol : dataVols) {
+            _volumeService.updateDisplay(dataVol, isDisplayVm);
+        }
+    }
+
+    protected void validateInputsAndPermissionForUpdateVirtualMachineCommand(UpdateVMCmd cmd) {
+        UserVmVO vmInstance = _vmDao.findById(cmd.getId());
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find virtual machine with id: " + cmd.getId());
+        }
+        validateGuestOsIdForUpdateVirtualMachineCommand(cmd);
+        Account caller = CallContext.current().getCallingAccount();
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+    }
+
+    protected void validateGuestOsIdForUpdateVirtualMachineCommand(UpdateVMCmd cmd) {
+        Long osTypeId = cmd.getOsTypeId();
+        if (osTypeId != null) {
+            GuestOSVO guestOS = _guestOSDao.findById(osTypeId);
+            if (guestOS == null) {
+                throw new InvalidParameterValueException("Please specify a valid guest OS ID.");
+            }
+        }
+    }
+
+    private void saveUsageEvent(UserVmVO vm) {
+
+        // If vm not destroyed
+        if( vm.getState() != State.Destroyed && vm.getState() != State.Expunging && vm.getState() != State.Error){
+
+            if(vm.isDisplayVm()){
+                //1. Allocated VM Usage Event
+                generateUsageEvent(vm, true, EventTypes.EVENT_VM_CREATE);
+
+                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
+                    //2. Running VM Usage Event
+                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_START);
+
+                    // 3. Network offering usage
+                    generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_ASSIGN);
+                }
+
+            }else {
+                //1. Allocated VM Usage Event
+                generateUsageEvent(vm, true, EventTypes.EVENT_VM_DESTROY);
+
+                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
+                    //2. Running VM Usage Event
+                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_STOP);
+
+                    // 3. Network offering usage
+                    generateNetworkUsageForVm(vm, true, EventTypes.EVENT_NETWORK_OFFERING_REMOVE);
+                }
+            }
+        }
+
+    }
+
+    private void generateNetworkUsageForVm(VirtualMachine vm, boolean isDisplay, String eventType){
+
+        List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        for (NicVO nic : nics) {
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            long isDefault = (nic.isDefaultNic()) ? 1 : 0;
+            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                    Long.toString(nic.getId()), network.getNetworkOfferingId(), null, isDefault, vm.getClass().getName(), vm.getUuid(), isDisplay);
+        }
+
+    }
+
+    @Override
+    public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
+            Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List<Long> securityGroupIdList, Map<String, Map<Integer, String>> extraDhcpOptionsMap)
+                    throws ResourceUnavailableException, InsufficientCapacityException {
+        UserVmVO vm = _vmDao.findById(id);
+        if (vm == null) {
+            throw new CloudRuntimeException("Unable to find virtual machine with id " + id);
+        }
+
+        if(instanceName != null){
+            VMInstanceVO vmInstance = _vmInstanceDao.findVMByInstanceName(instanceName);
+            if(vmInstance != null && vmInstance.getId() != id){
+                throw new CloudRuntimeException("Instance name : " + instanceName + " is not unique");
+            }
+        }
+
+        if (vm.getState() == State.Error || vm.getState() == State.Expunging) {
+            s_logger.error("vm is not in the right state: " + id);
+            throw new InvalidParameterValueException("Vm with id " + id + " is not in the right state");
+        }
+
+        if (displayName == null) {
+            displayName = vm.getDisplayName();
+        }
+
+        if (ha == null) {
+            ha = vm.isHaEnabled();
+        }
+
+        ServiceOffering offering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
+        if (!offering.isOfferHA() && ha) {
+            throw new InvalidParameterValueException("Can't enable ha for the vm as it's created from the Service offering having HA disabled");
+        }
+
+        if (isDisplayVmEnabled == null) {
+            isDisplayVmEnabled = vm.isDisplayVm();
+        }
+
+        boolean updateUserdata = false;
+        if (userData != null) {
+            // check and replace newlines
+            userData = userData.replace("\\n", "");
+            userData = validateUserData(userData, httpMethod);
+            // update userData on domain router.
+            updateUserdata = true;
+        } else {
+            userData = vm.getUserData();
+        }
+
+        if (isDynamicallyScalable == null) {
+            isDynamicallyScalable = vm.isDynamicallyScalable();
+        }
+
+        if (osTypeId == null) {
+            osTypeId = vm.getGuestOSId();
+        }
+
+        if (group != null) {
+            addInstanceToGroup(id, group);
+        }
+
+        if (isDynamicallyScalable == null) {
+            isDynamicallyScalable = vm.isDynamicallyScalable();
+        }
+
+        boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware);
+
+        if (securityGroupIdList != null && isVMware) {
+            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
+        } else {
+            // Get default guest network in Basic zone
+            Network defaultNetwork = null;
+            try {
+                DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
+
+                if (zone.getNetworkType() == NetworkType.Basic) {
+                    // Get default guest network in Basic zone
+                    defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
+                } else if (zone.isSecurityGroupEnabled()) {
+                    NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId());
+                    if (defaultNic != null) {
+                        defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
+                    }
+                }
+            } catch (InvalidParameterValueException e) {
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug(e.getMessage(),e);
+                }
+                defaultNetwork = _networkModel.getDefaultNetworkForVm(id);
+            }
+
+            if (securityGroupIdList != null && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
+                if (vm.getState() == State.Stopped) {
+                    // Remove instance from security groups
+                    _securityGroupMgr.removeInstanceFromGroups(id);
+                    // Add instance in provided groups
+                    _securityGroupMgr.addInstanceToGroups(id, securityGroupIdList);
+                } else {
+                    throw new InvalidParameterValueException("Virtual machine must be stopped prior to update security groups ");
+                }
+            }
+        }
+        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
+        if (hostName != null) {
+            // Check is hostName is RFC compliant
+            checkNameForRFCCompliance(hostName);
+
+            if (vm.getHostName().equalsIgnoreCase(hostName)) {
+                s_logger.debug("Vm " + vm + " is already set with the hostName specified: " + hostName);
+                hostName = null;
+            }
+
+            // Verify that vm's hostName is unique
+
+            List<NetworkVO> vmNtwks = new ArrayList<NetworkVO>(nics.size());
+            for (Nic nic : nics) {
+                vmNtwks.add(_networkDao.findById(nic.getNetworkId()));
+            }
+            checkIfHostNameUniqueInNtwkDomain(hostName, vmNtwks);
+        }
+
+        List<NetworkVO> networks = nics.stream()
+                .map(nic -> _networkDao.findById(nic.getNetworkId()))
+                .collect(Collectors.toList());
+
+        verifyExtraDhcpOptionsNetwork(extraDhcpOptionsMap, networks);
+        for (Nic nic : nics) {
+            _networkMgr.saveExtraDhcpOptions(networks.stream()
+                    .filter(network -> network.getId() == nic.getNetworkId())
+                    .findFirst()
+                    .get()
+                    .getUuid(), nic.getId(), extraDhcpOptionsMap);
+        }
+
+        _vmDao.updateVM(id, displayName, ha, osTypeId, userData, isDisplayVmEnabled, isDynamicallyScalable, customId, hostName, instanceName);
+
+        if (updateUserdata) {
+            boolean result = updateUserDataInternal(_vmDao.findById(id));
+            if (result) {
+                s_logger.debug("User data successfully updated for vm id=" + id);
+            } else {
+                throw new CloudRuntimeException("Failed to reset userdata for the virtual machine ");
+            }
+        }
+
+        return _vmDao.findById(id);
+    }
+
+    private boolean updateUserDataInternal(UserVm vm) throws ResourceUnavailableException, InsufficientCapacityException {
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
+
+        List<? extends Nic> nics = _nicDao.listByVmId(vm.getId());
+        if (nics == null || nics.isEmpty()) {
+            s_logger.error("unable to find any nics for vm " + vm.getUuid());
+            return false;
+        }
+
+        boolean userDataApplied = false;
+        for (Nic nic : nics) {
+            userDataApplied |= applyUserData(template.getHypervisorType(), vm, nic);
+        }
+        return userDataApplied;
+    }
+
+    protected boolean applyUserData(HypervisorType hyperVisorType, UserVm vm, Nic nic) throws ResourceUnavailableException, InsufficientCapacityException {
+        Network network = _networkDao.findById(nic.getNetworkId());
+        NicProfile nicProfile = new NicProfile(nic, network, null, null, null, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(
+                hyperVisorType, network));
+        VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vm);
+
+        if (_networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.UserData)) {
+            UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network);
+            if (element == null) {
+                throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update");
+            }
+            boolean result = element.saveUserData(network, nicProfile, vmProfile);
+            if (!result) {
+                s_logger.error("Failed to update userdata for vm " + vm + " and nic " + nic);
+            } else {
+                return true;
+            }
+        } else {
+            s_logger.debug("Not applying userdata for nic id=" + nic.getId() + " in vm id=" + vmProfile.getId() + " because it is not supported in network id=" + network.getId());
+        }
+        return false;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_START, eventDescription = "starting Vm", async = true)
+    public UserVm startVirtualMachine(StartVMCmd cmd) throws ExecutionException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        return startVirtualMachine(cmd.getId(), cmd.getHostId(), null, cmd.getDeploymentPlanner()).first();
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_REBOOT, eventDescription = "rebooting Vm", async = true)
+    public UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long vmId = cmd.getId();
+
+        // Verify input parameters
+        UserVmVO vmInstance = _vmDao.findById(vmId);
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, vmInstance);
+
+        checkIfHostOfVMIsInPrepareForMaintenanceState(vmInstance.getHostId(), vmId, "Reboot");
+
+        // If the VM is Volatile in nature, on reboot discard the VM's root disk and create a new root disk for it: by calling restoreVM
+        long serviceOfferingId = vmInstance.getServiceOfferingId();
+        ServiceOfferingVO offering = _serviceOfferingDao.findById(vmInstance.getId(), serviceOfferingId);
+        if (offering != null && offering.getRemoved() == null) {
+            if (offering.isVolatileVm()) {
+                return restoreVMInternal(caller, vmInstance, null);
+            }
+        } else {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the vm");
+        }
+
+        UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId);
+        if (userVm != null ) {
+            // update the vmIdCountMap if the vm is in advanced shared network with out services
+            final List<NicVO> nics = _nicDao.listByVmId(vmId);
+            for (NicVO nic : nics) {
+                Network network = _networkModel.getNetwork(nic.getNetworkId());
+                if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                    s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
+                            "reboot for vm ip fetch ");
+                    vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
+                }
+            }
+            return  userVm;
+        }
+        return  null;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_DESTROY, eventDescription = "destroying Vm", async = true)
+    public UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
+        CallContext ctx = CallContext.current();
+        long vmId = cmd.getId();
+        boolean expunge = cmd.getExpunge();
+
+        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
+        if (expunge && !_accountMgr.isAdmin(ctx.getCallingAccount().getId()) && !AllowUserExpungeRecoverVm.valueIn(cmd.getEntityOwnerId())) {
+            throw new PermissionDeniedException("Parameter " + ApiConstants.EXPUNGE + " can be passed by Admin only. Or when the allow.user.expunge.recover.vm key is set.");
+        }
+        // check if VM exists
+        UserVmVO vm = _vmDao.findById(vmId);
+
+        if (vm == null || vm.getRemoved() != null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
+            s_logger.debug("Vm id=" + vmId + " is already destroyed");
+            return vm;
+        }
+
+        // check if there are active volume snapshots tasks
+        s_logger.debug("Checking if there are any ongoing snapshots on the ROOT volumes associated with VM with ID " + vmId);
+        if (checkStatusOfVolumeSnapshots(vmId, Volume.Type.ROOT)) {
+            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on ROOT volume, vm destroy is not permitted, please try again later.");
+        }
+        s_logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm with id " + vmId);
+
+        List<VolumeVO> volumes = getVolumesFromIds(cmd);
+
+        checkForUnattachedVolumes(vmId, volumes);
+        validateVolumes(volumes);
+
+        stopVirtualMachine(vmId, VmDestroyForcestop.value());
+
+        detachVolumesFromVm(volumes);
+
+        UserVm destroyedVm = destroyVm(vmId, expunge);
+        if (expunge) {
+            if (!expunge(vm, ctx.getCallingUserId(), ctx.getCallingAccount())) {
+                throw new CloudRuntimeException("Failed to expunge vm " + destroyedVm);
+            }
+        }
+
+        deleteVolumesFromVm(volumes);
+
+        return destroyedVm;
+    }
+
+    private List<VolumeVO> getVolumesFromIds(DestroyVMCmd cmd) {
+        List<VolumeVO> volumes = new ArrayList<>();
+        if (cmd.getVolumeIds() != null) {
+            for (Long volId : cmd.getVolumeIds()) {
+                VolumeVO vol = _volsDao.findById(volId);
+
+                if (vol == null) {
+                    throw new InvalidParameterValueException("Unable to find volume with ID: " + volId);
+                }
+                volumes.add(vol);
+            }
+        }
+        return volumes;
+    }
+
+    @Override
+    @DB
+    public InstanceGroupVO createVmGroup(CreateVMGroupCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long domainId = cmd.getDomainId();
+        String accountName = cmd.getAccountName();
+        String groupName = cmd.getGroupName();
+        Long projectId = cmd.getProjectId();
+
+        Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
+        long accountId = owner.getId();
+
+        // Check if name is already in use by this account
+        boolean isNameInUse = _vmGroupDao.isNameInUse(accountId, groupName);
+
+        if (isNameInUse) {
+            throw new InvalidParameterValueException("Unable to create vm group, a group with name " + groupName + " already exists for account " + accountId);
+        }
+
+        return createVmGroup(groupName, accountId);
+    }
+
+    @DB
+    private InstanceGroupVO createVmGroup(String groupName, long accountId) {
+        Account account = null;
+        try {
+            account = _accountDao.acquireInLockTable(accountId); // to ensure
+            // duplicate
+            // vm group
+            // names are
+            // not
+            // created.
+            if (account == null) {
+                s_logger.warn("Failed to acquire lock on account");
+                return null;
+            }
+            InstanceGroupVO group = _vmGroupDao.findByAccountAndName(accountId, groupName);
+            if (group == null) {
+                group = new InstanceGroupVO(groupName, accountId);
+                group = _vmGroupDao.persist(group);
+            }
+            return group;
+        } finally {
+            if (account != null) {
+                _accountDao.releaseFromLockTable(accountId);
+            }
+        }
+    }
+
+    @Override
+    public boolean deleteVmGroup(DeleteVMGroupCmd cmd) {
+        Account caller = CallContext.current().getCallingAccount();
+        Long groupId = cmd.getId();
+
+        // Verify input parameters
+        InstanceGroupVO group = _vmGroupDao.findById(groupId);
+        if ((group == null) || (group.getRemoved() != null)) {
+            throw new InvalidParameterValueException("unable to find a vm group with id " + groupId);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, group);
+
+        return deleteVmGroup(groupId);
+    }
+
+    @Override
+    public boolean deleteVmGroup(long groupId) {
+        // delete all the mappings from group_vm_map table
+        List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByGroupId(groupId);
+        for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+            SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
+            sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+            _groupVMMapDao.expunge(sc);
+        }
+
+        if (_vmGroupDao.remove(groupId)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @DB
+    public boolean addInstanceToGroup(final long userVmId, String groupName) {
+        UserVmVO vm = _vmDao.findById(userVmId);
+
+        InstanceGroupVO group = _vmGroupDao.findByAccountAndName(vm.getAccountId(), groupName);
+        // Create vm group if the group doesn't exist for this account
+        if (group == null) {
+            group = createVmGroup(groupName, vm.getAccountId());
+        }
+
+        if (group != null) {
+            UserVm userVm = _vmDao.acquireInLockTable(userVmId);
+            if (userVm == null) {
+                s_logger.warn("Failed to acquire lock on user vm id=" + userVmId);
+            }
+            try {
+                final InstanceGroupVO groupFinal = group;
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        // don't let the group be deleted when we are assigning vm to
+                        // it.
+                        InstanceGroupVO ngrpLock = _vmGroupDao.lockRow(groupFinal.getId(), false);
+                        if (ngrpLock == null) {
+                            s_logger.warn("Failed to acquire lock on vm group id=" + groupFinal.getId() + " name=" + groupFinal.getName());
+                            throw new CloudRuntimeException("Failed to acquire lock on vm group id=" + groupFinal.getId() + " name=" + groupFinal.getName());
+                        }
+
+                        // Currently don't allow to assign a vm to more than one group
+                        if (_groupVMMapDao.listByInstanceId(userVmId) != null) {
+                            // Delete all mappings from group_vm_map table
+                            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(userVmId);
+                            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+                                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
+                                sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+                                _groupVMMapDao.expunge(sc);
+                            }
+                        }
+                        InstanceGroupVMMapVO groupVmMapVO = new InstanceGroupVMMapVO(groupFinal.getId(), userVmId);
+                        _groupVMMapDao.persist(groupVmMapVO);
+
+                    }
+                });
+
+                return true;
+            } finally {
+                if (userVm != null) {
+                    _vmDao.releaseFromLockTable(userVmId);
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public InstanceGroupVO getGroupForVm(long vmId) {
+        // TODO - in future releases vm can be assigned to multiple groups; but
+        // currently return just one group per vm
+        try {
+            List<InstanceGroupVMMapVO> groupsToVmMap = _groupVMMapDao.listByInstanceId(vmId);
+
+            if (groupsToVmMap != null && groupsToVmMap.size() != 0) {
+                InstanceGroupVO group = _vmGroupDao.findById(groupsToVmMap.get(0).getGroupId());
+                return group;
+            } else {
+                return null;
+            }
+        } catch (Exception e) {
+            s_logger.warn("Error trying to get group for a vm: ", e);
+            return null;
+        }
+    }
+
+    @Override
+    public void removeInstanceFromInstanceGroup(long vmId) {
+        try {
+            List<InstanceGroupVMMapVO> groupVmMaps = _groupVMMapDao.listByInstanceId(vmId);
+            for (InstanceGroupVMMapVO groupMap : groupVmMaps) {
+                SearchCriteria<InstanceGroupVMMapVO> sc = _groupVMMapDao.createSearchCriteria();
+                sc.addAnd("instanceId", SearchCriteria.Op.EQ, groupMap.getInstanceId());
+                _groupVMMapDao.expunge(sc);
+            }
+        } catch (Exception e) {
+            s_logger.warn("Error trying to remove vm from group: ", e);
+        }
+    }
+
+    private boolean validPassword(String password) {
+        if (password == null || password.length() == 0) {
+            return false;
+        }
+        for (int i = 0; i < password.length(); i++) {
+            if (password.charAt(i) == ' ') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
+    public UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
+            Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
+            String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
+            Map<String, String> customParametes, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
+    StorageUnavailableException, ResourceAllocationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
+
+        // Verify that caller can perform actions in behalf of vm owner
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        // Verify that owner can use the service offering
+        _accountMgr.checkAccess(owner, serviceOffering);
+        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
+
+        // Get default guest network in Basic zone
+        Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
+
+        if (defaultNetwork == null) {
+            throw new InvalidParameterValueException("Unable to find a default network to start a vm");
+        } else {
+            networkList.add(_networkDao.findById(defaultNetwork.getId()));
+        }
+
+        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
+
+        if (securityGroupIdList != null && isVmWare) {
+            throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
+        } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
+            //add the default securityGroup only if no security group is specified
+            if (securityGroupIdList == null || securityGroupIdList.isEmpty()) {
+                if (securityGroupIdList == null) {
+                    securityGroupIdList = new ArrayList<Long>();
+                }
+                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(owner.getId());
+                if (defaultGroup != null) {
+                    securityGroupIdList.add(defaultGroup.getId());
+                } else {
+                    // create default security group for the account
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Couldn't find default security group for the account " + owner + " so creating a new one");
+                    }
+                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
+                            owner.getDomainId(), owner.getId(), owner.getAccountName());
+                    securityGroupIdList.add(defaultGroup.getId());
+                }
+            }
+        }
+
+        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
+                userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParametes, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
+    public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
+            List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
+            HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
+            List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException,
+    ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
+        boolean isSecurityGroupEnabledNetworkUsed = false;
+        boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware || (hypervisor != null && hypervisor == HypervisorType.VMware));
+
+        // Verify that caller can perform actions in behalf of vm owner
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        // Verify that owner can use the service offering
+        _accountMgr.checkAccess(owner, serviceOffering);
+        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
+
+        // If no network is specified, find system security group enabled network
+        if (networkIdList == null || networkIdList.isEmpty()) {
+            Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId());
+            if (networkWithSecurityGroup == null) {
+                throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid());
+            }
+
+            networkList.add(_networkDao.findById(networkWithSecurityGroup.getId()));
+            isSecurityGroupEnabledNetworkUsed = true;
+
+        } else if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
+            if (isVmWare) {
+                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
+            }
+            // Only one network can be specified, and it should be security group enabled
+            if (networkIdList.size() > 1) {
+                throw new InvalidParameterValueException("Only support one network per VM if security group enabled");
+            }
+
+            NetworkVO network = _networkDao.findById(networkIdList.get(0));
+
+            if (network == null) {
+                throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
+            }
+
+            if (!_networkModel.isSecurityGroupSupportedInNetwork(network)) {
+                throw new InvalidParameterValueException("Network is not security group enabled: " + network.getId());
+            }
+
+            networkList.add(network);
+            isSecurityGroupEnabledNetworkUsed = true;
+
+        } else {
+            // Verify that all the networks are Shared/Guest; can't create combination of SG enabled and disabled networks
+            for (Long networkId : networkIdList) {
+                NetworkVO network = _networkDao.findById(networkId);
+
+                if (network == null) {
+                    throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
+                }
+
+                boolean isSecurityGroupEnabled = _networkModel.isSecurityGroupSupportedInNetwork(network);
+                if (isSecurityGroupEnabled) {
+                    if (networkIdList.size() > 1) {
+                        throw new InvalidParameterValueException("Can't create a vm with multiple networks one of" + " which is Security Group enabled");
+                    }
+
+                    isSecurityGroupEnabledNetworkUsed = true;
+                }
+
+                if (!(network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared)) {
+                    throw new InvalidParameterValueException("Can specify only Shared Guest networks when" + " deploy vm in Advance Security Group enabled zone");
+                }
+
+                // Perform account permission check
+                if (network.getAclType() == ACLType.Account) {
+                    _accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
+                }
+                networkList.add(network);
+            }
+        }
+
+        // if network is security group enabled, and no security group is specified, then add the default security group automatically
+        if (isSecurityGroupEnabledNetworkUsed && !isVmWare && _networkModel.canAddDefaultSecurityGroup()) {
+
+            //add the default securityGroup only if no security group is specified
+            if (securityGroupIdList == null || securityGroupIdList.isEmpty()) {
+                if (securityGroupIdList == null) {
+                    securityGroupIdList = new ArrayList<Long>();
+                }
+
+                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(owner.getId());
+                if (defaultGroup != null) {
+                    securityGroupIdList.add(defaultGroup.getId());
+                } else {
+                    // create default security group for the account
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Couldn't find default security group for the account " + owner + " so creating a new one");
+                    }
+                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
+                            owner.getDomainId(), owner.getId(), owner.getAccountName());
+                    securityGroupIdList.add(defaultGroup.getId());
+                }
+            }
+        }
+
+        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, securityGroupIdList, group, httpmethod,
+                userData, sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayVm, keyboard, affinityGroupIdList, customParameters, customId, dhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "deploying Vm", create = true)
+    public UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
+            String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
+            String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayvm, String keyboard, List<Long> affinityGroupIdList,
+            Map<String, String> customParametrs, String customId, Map<String, Map<Integer, String>> dhcpOptionsMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException,
+    StorageUnavailableException, ResourceAllocationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        List<NetworkVO> networkList = new ArrayList<NetworkVO>();
+
+        // Verify that caller can perform actions in behalf of vm owner
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        // Verify that owner can use the service offering
+        _accountMgr.checkAccess(owner, serviceOffering);
+        _accountMgr.checkAccess(owner, _diskOfferingDao.findById(diskOfferingId));
+
+        List<HypervisorType> vpcSupportedHTypes = _vpcMgr.getSupportedVpcHypervisors();
+        if (networkIdList == null || networkIdList.isEmpty()) {
+            NetworkVO defaultNetwork = null;
+
+            // if no network is passed in
+            // Check if default virtual network offering has
+            // Availability=Required. If it's true, search for corresponding
+            // network
+            // * if network is found, use it. If more than 1 virtual network is
+            // found, throw an error
+            // * if network is not found, create a new one and use it
+
+            List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+            if (requiredOfferings.size() < 1) {
+                throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
+                        + " to automatically create the network as a part of vm creation");
+            }
+
+            if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
+                // get Virtual networks
+                List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated);
+                if (virtualNetworks == null) {
+                    throw new InvalidParameterValueException("No (virtual) networks are found for account " + owner);
+                }
+                if (virtualNetworks.isEmpty()) {
+                    long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
+                    // Validate physical network
+                    PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+                    if (physicalNetwork == null) {
+                        throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+                                + requiredOfferings.get(0).getTags());
+                    }
+                    s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
+                    Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
+                            null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null,
+                            null);
+                    if (newNetwork != null) {
+                        defaultNetwork = _networkDao.findById(newNetwork.getId());
+                    }
+                } else if (virtualNetworks.size() > 1) {
+                    throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds");
+                } else {
+                    defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
+                }
+            } else {
+                throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
+            }
+
+            if (defaultNetwork != null) {
+                networkList.add(defaultNetwork);
+            }
+
+        } else {
+            for (Long networkId : networkIdList) {
+                NetworkVO network = _networkDao.findById(networkId);
+                if (network == null) {
+                    throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue());
+                }
+                if (network.getVpcId() != null) {
+                    // Only ISOs, XenServer, KVM, and VmWare template types are
+                    // supported for vpc networks
+                    if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) {
+                        throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + template.getHypervisorType() + " in vpc network " + network);
+                    } else if (template.getFormat() == ImageFormat.ISO && !vpcSupportedHTypes.contains(hypervisor)) {
+                        // Only XenServer, KVM, and VMware hypervisors are supported
+                        // for vpc networks
+                        throw new InvalidParameterValueException("Can't create vm of hypervisor type " + hypervisor + " in vpc network");
+
+                    }
+                }
+
+                _networkModel.checkNetworkPermissions(owner, network);
+
+                // don't allow to use system networks
+                NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+                if (networkOffering.isSystemOnly()) {
+                    throw new InvalidParameterValueException("Network id=" + networkId + " is system only and can't be used for vm deployment");
+                }
+                networkList.add(network);
+            }
+        }
+        verifyExtraDhcpOptionsNetwork(dhcpOptionsMap, networkList);
+
+        return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, diskSize, networkList, null, group, httpmethod, userData,
+                sshKeyPair, hypervisor, caller, requestedIps, defaultIps, displayvm, keyboard, affinityGroupIdList, customParametrs, customId, dhcpOptionsMap, dataDiskTemplateToDiskOfferingMap);
+    }
+
+    private void verifyExtraDhcpOptionsNetwork(Map<String, Map<Integer, String>> dhcpOptionsMap, List<NetworkVO> networkList) throws InvalidParameterValueException {
+        if (dhcpOptionsMap != null) {
+            for (String networkUuid : dhcpOptionsMap.keySet()) {
+                boolean networkFound = false;
+                for (NetworkVO network : networkList) {
+                    if (network.getUuid().equals(networkUuid)) {
+                        networkFound = true;
+                        break;
+                    }
+                }
+
+                if (!networkFound) {
+                    throw new InvalidParameterValueException("VM does not has a nic in the Network (" + networkUuid + ") that is specified in the extra dhcp options.");
+                }
+            }
+        }
+    }
+
+    public void checkNameForRFCCompliance(String name) {
+        if (!NetUtils.verifyDomainNameLabel(name, true)) {
+            throw new InvalidParameterValueException("Invalid name. Vm name can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
+                    + "and the hyphen ('-'), must be between 1 and 63 characters long, and can't start or end with \"-\" and can't start with digit");
+        }
+    }
+
+    @DB
+    private UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate tmplt, String hostName, String displayName, Account owner,
+            Long diskOfferingId, Long diskSize, List<NetworkVO> networkList, List<Long> securityGroupIdList, String group, HTTPMethod httpmethod, String userData,
+            String sshKeyPair, HypervisorType hypervisor, Account caller, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean isDisplayVm, String keyboard,
+            List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> datadiskTemplateToDiskOfferringMap) throws InsufficientCapacityException, ResourceUnavailableException,
+    ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
+
+        _accountMgr.checkAccess(caller, null, true, owner);
+
+        if (owner.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of vm to deploy is disabled: " + owner);
+        }
+        VMTemplateVO template = _templateDao.findById(tmplt.getId());
+        if (template != null) {
+            _templateDao.loadDetails(template);
+        }
+
+        HypervisorType hypervisorType = null;
+        if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) {
+            if (hypervisor == null || hypervisor == HypervisorType.None) {
+                throw new InvalidParameterValueException("hypervisor parameter is needed to deploy VM or the hypervisor parameter value passed is invalid");
+            }
+            hypervisorType = hypervisor;
+        } else {
+            if (hypervisor != null && hypervisor != HypervisorType.None && hypervisor != template.getHypervisorType()) {
+                throw new InvalidParameterValueException("Hypervisor passed to the deployVm call, is different from the hypervisor type of the template");
+            }
+            hypervisorType = template.getHypervisorType();
+        }
+
+        long accountId = owner.getId();
+
+        assert !(requestedIps != null && (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null)) : "requestedIp list and defaultNetworkIp should never be specified together";
+
+        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
+                && !_accountMgr.isRootAdmin(caller.getId())) {
+            throw new PermissionDeniedException(
+                    "Cannot perform this operation, Zone is currently disabled: "
+                            + zone.getId());
+        }
+
+        // check if zone is dedicated
+        DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zone.getId());
+        if (dedicatedZone != null) {
+            DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId());
+            if (domain == null) {
+                throw new CloudRuntimeException("Unable to find the domain " + zone.getDomainId() + " for the zone: " + zone);
+            }
+            // check that caller can operate with domain
+            _configMgr.checkZoneAccess(caller, zone);
+            // check that vm owner can create vm in the domain
+            _configMgr.checkZoneAccess(owner, zone);
+        }
+
+        ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId());
+        if (offering.isDynamic()) {
+            offering.setDynamicFlag(true);
+            validateCustomParameters(offering, customParameters);
+            offering = _offeringDao.getcomputeOffering(offering, customParameters);
+        }
+        // check if account/domain is with in resource limits to create a new vm
+        boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
+        long size = 0;
+        // custom root disk size, resizes base template to larger size
+        if (customParameters.containsKey("rootdisksize")) {
+            // only KVM, XenServer and VMware supports rootdisksize override
+            if (!(hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.XenServer || hypervisorType == HypervisorType.VMware || hypervisorType == HypervisorType.Simulator)) {
+                throw new InvalidParameterValueException("Hypervisor " + hypervisorType + " does not support rootdisksize override");
+            }
+
+            Long rootDiskSize = NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1);
+            if (rootDiskSize <= 0) {
+                throw new InvalidParameterValueException("Root disk size should be a positive number.");
+            }
+            size = rootDiskSize * GiB_TO_BYTES;
+        } else {
+            // For baremetal, size can be null
+            Long templateSize = _templateDao.findById(template.getId()).getSize();
+            if (templateSize != null) {
+                size = templateSize;
+            }
+        }
+        if (diskOfferingId != null) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
+            if (diskOffering != null && diskOffering.isCustomized()) {
+                if (diskSize == null) {
+                    throw new InvalidParameterValueException("This disk offering requires a custom size specified");
+                }
+                Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
+                Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
+                if ((diskSize < customDiskOfferingMinSize) || (diskSize > customDiskOfferingMaxSize)) {
+                    throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize
+                            + " Min:" + customDiskOfferingMinSize);
+                }
+                size += diskSize * GiB_TO_BYTES;
+            }
+            size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
+        }
+        resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
+
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso || diskOfferingId == null ? 1 : 2));
+        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size);
+
+        // verify security group ids
+        if (securityGroupIdList != null) {
+            for (Long securityGroupId : securityGroupIdList) {
+                SecurityGroup sg = _securityGroupDao.findById(securityGroupId);
+                if (sg == null) {
+                    throw new InvalidParameterValueException("Unable to find security group by id " + securityGroupId);
+                } else {
+                    // verify permissions
+                    _accountMgr.checkAccess(caller, null, true, owner, sg);
+                }
+            }
+        }
+
+        if (datadiskTemplateToDiskOfferringMap != null && !datadiskTemplateToDiskOfferringMap.isEmpty()) {
+            for (Entry<Long, DiskOffering> datadiskTemplateToDiskOffering : datadiskTemplateToDiskOfferringMap.entrySet()) {
+                VMTemplateVO dataDiskTemplate = _templateDao.findById(datadiskTemplateToDiskOffering.getKey());
+                DiskOffering dataDiskOffering = datadiskTemplateToDiskOffering.getValue();
+
+                if (dataDiskTemplate == null
+                        || (!dataDiskTemplate.getTemplateType().equals(TemplateType.DATADISK)) && (dataDiskTemplate.getState().equals(VirtualMachineTemplate.State.Active))) {
+                    throw new InvalidParameterValueException("Invalid template id specified for Datadisk template" + datadiskTemplateToDiskOffering.getKey());
+                }
+                long dataDiskTemplateId = datadiskTemplateToDiskOffering.getKey();
+                if (!dataDiskTemplate.getParentTemplateId().equals(template.getId())) {
+                    throw new InvalidParameterValueException("Invalid Datadisk template. Specified Datadisk template" + dataDiskTemplateId
+                            + " doesn't belong to template " + template.getId());
+                }
+                if (dataDiskOffering == null) {
+                    throw new InvalidParameterValueException("Invalid disk offering id " + datadiskTemplateToDiskOffering.getValue().getId() +
+                            " specified for datadisk template " + dataDiskTemplateId);
+                }
+                if (dataDiskOffering.isCustomized()) {
+                    throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
+                            dataDiskTemplateId + ". Custom Disk offerings are not supported for Datadisk templates");
+                }
+                if (dataDiskOffering.getDiskSize() < dataDiskTemplate.getSize()) {
+                    throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
+                            dataDiskTemplateId + ". Disk offering size should be greater than or equal to the template size");
+                }
+                _templateDao.loadDetails(dataDiskTemplate);
+                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, 1);
+                _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, dataDiskOffering.getDiskSize());
+            }
+        }
+
+        // check that the affinity groups exist
+        if (affinityGroupIdList != null) {
+            for (Long affinityGroupId : affinityGroupIdList) {
+                AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
+                if (ag == null) {
+                    throw new InvalidParameterValueException("Unable to find affinity group " + ag);
+                } else if (!_affinityGroupService.isAffinityGroupProcessorAvailable(ag.getType())) {
+                    throw new InvalidParameterValueException("Affinity group type is not supported for group: " + ag + " ,type: " + ag.getType()
+                    + " , Please try again after removing the affinity group");
+                } else {
+                    // verify permissions
+                    if (ag.getAclType() == ACLType.Domain) {
+                        _accountMgr.checkAccess(caller, null, false, owner, ag);
+                        // Root admin has access to both VM and AG by default,
+                        // but
+                        // make sure the owner of these entities is same
+                        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
+                            if (!_affinityGroupService.isAffinityGroupAvailableInDomain(ag.getId(), owner.getDomainId())) {
+                                throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's domain");
+                            }
+                        }
+                    } else {
+                        _accountMgr.checkAccess(caller, null, true, owner, ag);
+                        // Root admin has access to both VM and AG by default,
+                        // but
+                        // make sure the owner of these entities is same
+                        if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
+                            if (ag.getAccountId() != owner.getAccountId()) {
+                                throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's account");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (hypervisorType != HypervisorType.BareMetal) {
+            // check if we have available pools for vm deployment
+            long availablePools = _storagePoolDao.countPoolsByStatus(StoragePoolStatus.Up);
+            if (availablePools < 1) {
+                throw new StorageUnavailableException("There are no available pools in the UP state for vm deployment", -1);
+            }
+        }
+
+        if (template.getTemplateType().equals(TemplateType.SYSTEM)) {
+            throw new InvalidParameterValueException("Unable to use system template " + template.getId() + " to deploy a user vm");
+        }
+        List<VMTemplateZoneVO> listZoneTemplate = _templateZoneDao.listByZoneTemplate(zone.getId(), template.getId());
+        if (listZoneTemplate == null || listZoneTemplate.isEmpty()) {
+            throw new InvalidParameterValueException("The template " + template.getId() + " is not available for use");
+        }
+
+        if (isIso && !template.isBootable()) {
+            throw new InvalidParameterValueException("Installing from ISO requires an ISO that is bootable: " + template.getId());
+        }
+
+        // Check templates permissions
+        _accountMgr.checkAccess(owner, AccessType.UseEntry, false, template);
+
+        // check if the user data is correct
+        userData = validateUserData(userData, httpmethod);
+
+        // Find an SSH public key corresponding to the key pair name, if one is
+        // given
+        String sshPublicKey = null;
+        if (sshKeyPair != null && !sshKeyPair.equals("")) {
+            SSHKeyPair pair = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), sshKeyPair);
+            if (pair == null) {
+                throw new InvalidParameterValueException("A key pair with name '" + sshKeyPair + "' was not found.");
+            }
+
+            sshPublicKey = pair.getPublicKey();
+        }
+
+        List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
+
+        LinkedHashMap<String, NicProfile> networkNicMap = new LinkedHashMap<String, NicProfile>();
+
+        short defaultNetworkNumber = 0;
+        boolean securityGroupEnabled = false;
+        boolean vpcNetwork = false;
+        for (NetworkVO network : networkList) {
+            if ((network.getDataCenterId() != zone.getId())) {
+                if (!network.isStrechedL2Network()) {
+                    throw new InvalidParameterValueException("Network id=" + network.getId() +
+                            " doesn't belong to zone " + zone.getId());
+                }
+
+                NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+                Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType());
+
+                String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity);
+                if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
+                    throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" +
+                            " streched to the zone, as we could not find a valid physical network");
+                }
+            }
+
+            //relax the check if the caller is admin account
+            if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
+                if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain)
+                        && !(network.getAclType() == ACLType.Account && network.getAccountId() == accountId)) {
+                    throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vm");
+                }
+            }
+
+            IpAddresses requestedIpPair = null;
+            if (requestedIps != null && !requestedIps.isEmpty()) {
+                requestedIpPair = requestedIps.get(network.getId());
+            }
+
+            if (requestedIpPair == null) {
+                requestedIpPair = new IpAddresses(null, null);
+            } else {
+                _networkModel.checkRequestedIpAddresses(network.getId(), requestedIpPair);
+            }
+
+            NicProfile profile = new NicProfile(requestedIpPair.getIp4Address(), requestedIpPair.getIp6Address(), requestedIpPair.getMacAddress());
+
+            if (defaultNetworkNumber == 0) {
+                defaultNetworkNumber++;
+                // if user requested specific ip for default network, add it
+                if (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null) {
+                    _networkModel.checkRequestedIpAddresses(network.getId(), defaultIps);
+                    profile = new NicProfile(defaultIps.getIp4Address(), defaultIps.getIp6Address());
+                } else if (defaultIps.getMacAddress() != null) {
+                    profile = new NicProfile(null, null, defaultIps.getMacAddress());
+                }
+
+                profile.setDefaultNic(true);
+                if (!_networkModel.areServicesSupportedInNetwork(network.getId(), new Service[]{Service.UserData})) {
+                    if ((userData != null) && (!userData.isEmpty())) {
+                        throw new InvalidParameterValueException("Unable to deploy VM as UserData is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
+                    }
+
+                    if ((sshPublicKey != null) && (!sshPublicKey.isEmpty())) {
+                        throw new InvalidParameterValueException("Unable to deploy VM as SSH keypair is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
+                    }
+
+                    if (template.isEnablePassword()) {
+                        throw new InvalidParameterValueException("Unable to deploy VM as template " + template.getId() + " is password enabled, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
+                    }
+                }
+            }
+
+            networks.add(new Pair<NetworkVO, NicProfile>(network, profile));
+
+            if (_networkModel.isSecurityGroupSupportedInNetwork(network)) {
+                securityGroupEnabled = true;
+            }
+
+            // vm can't be a part of more than 1 VPC network
+            if (network.getVpcId() != null) {
+                if (vpcNetwork) {
+                    throw new InvalidParameterValueException("Vm can't be a part of more than 1 VPC network");
+                }
+                vpcNetwork = true;
+            }
+
+            networkNicMap.put(network.getUuid(), profile);
+        }
+
+        if (securityGroupIdList != null && !securityGroupIdList.isEmpty() && !securityGroupEnabled) {
+            throw new InvalidParameterValueException("Unable to deploy vm with security groups as SecurityGroup service is not enabled for the vm's network");
+        }
+
+        // Verify network information - network default network has to be set;
+        // and vm can't have more than one default network
+        // This is a part of business logic because default network is required
+        // by Agent Manager in order to configure default
+        // gateway for the vm
+        if (defaultNetworkNumber == 0) {
+            throw new InvalidParameterValueException("At least 1 default network has to be specified for the vm");
+        } else if (defaultNetworkNumber > 1) {
+            throw new InvalidParameterValueException("Only 1 default network per vm is supported");
+        }
+
+        long id = _vmDao.getNextInSequence(Long.class, "id");
+
+        if (hostName != null) {
+            // Check is hostName is RFC compliant
+            checkNameForRFCCompliance(hostName);
+        }
+
+        String instanceName = null;
+        String uuidName = _uuidMgr.generateUuid(UserVm.class, customId);
+        if (_instanceNameFlag && hypervisor.equals(HypervisorType.VMware)) {
+            if (hostName == null) {
+                if (displayName != null) {
+                    hostName = displayName;
+                } else {
+                    hostName = generateHostName(uuidName);
+                }
+            }
+            // If global config vm.instancename.flag is set to true, then CS will set guest VM's name as it appears on the hypervisor, to its hostname.
+            // In case of VMware since VM name must be unique within a DC, check if VM with the same hostname already exists in the zone.
+            VMInstanceVO vmByHostName = _vmInstanceDao.findVMByHostNameInZone(hostName, zone.getId());
+            if (vmByHostName != null && vmByHostName.getState() != VirtualMachine.State.Expunging) {
+                throw new InvalidParameterValueException("There already exists a VM by the name: " + hostName + ".");
+            }
+        } else {
+            if (hostName == null) {
+                //Generate name using uuid and instance.name global config
+                hostName = generateHostName(uuidName);
+            }
+        }
+
+        if (hostName != null) {
+            // Check is hostName is RFC compliant
+            checkNameForRFCCompliance(hostName);
+        }
+        instanceName = VirtualMachineName.getVmName(id, owner.getId(), _instance);
+
+        // Check if VM with instanceName already exists.
+        VMInstanceVO vmObj = _vmInstanceDao.findVMByInstanceName(instanceName);
+        if (vmObj != null && vmObj.getState() != VirtualMachine.State.Expunging) {
+            throw new InvalidParameterValueException("There already exists a VM by the display name supplied");
+        }
+
+        checkIfHostNameUniqueInNtwkDomain(hostName, networkList);
+
+        long userId = CallContext.current().getCallingUserId();
+        if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
+            List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
+            if (!userVOs.isEmpty()) {
+                userId =  userVOs.get(0).getId();
+            }
+        }
+
+        UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering,
+                isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, dhcpOptionMap, datadiskTemplateToDiskOfferringMap);
+
+        // Assign instance to the group
+        try {
+            if (group != null) {
+                boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group);
+                if (!addToGroup) {
+                    throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
+                }
+            }
+        } catch (Exception ex) {
+            throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
+        }
+
+        _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
+
+        if (affinityGroupIdList != null && !affinityGroupIdList.isEmpty()) {
+            _affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
+        }
+
+        CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
+        return vm;
+    }
+
+    private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
+        // Check that hostName is unique in the network domain
+        Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
+        for (Network network : networkList) {
+            String ntwkDomain = network.getNetworkDomain();
+            if (!ntwkDomains.containsKey(ntwkDomain)) {
+                List<Long> ntwkIds = new ArrayList<Long>();
+                ntwkIds.add(network.getId());
+                ntwkDomains.put(ntwkDomain, ntwkIds);
+            } else {
+                List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
+                ntwkIds.add(network.getId());
+                ntwkDomains.put(ntwkDomain, ntwkIds);
+            }
+        }
+
+        for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
+            for (Long ntwkId : ntwkDomain.getValue()) {
+                // * get all vms hostNames in the network
+                List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
+                // * verify that there are no duplicates
+                if (hostNames.contains(hostName)) {
+                    throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
+                            + _networkModel.getNetwork(ntwkId));
+                }
+            }
+        }
+    }
+
+    private String generateHostName(String uuidName) {
+        return _instance + "-" + uuidName;
+    }
+
+    private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplate template, final String hostName, final String displayName, final Account owner,
+            final Long diskOfferingId, final Long diskSize, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
+            final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, NicProfile> networkNicMap,
+            final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters, final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException {
+        return Transaction.execute(new TransactionCallbackWithException<UserVmVO, InsufficientCapacityException>() {
+            @Override
+            public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCapacityException {
+                UserVmVO vm = new UserVmVO(id, instanceName, displayName, template.getId(), hypervisorType, template.getGuestOSId(), offering.isOfferHA(),
+                        offering.getLimitCpuUse(), owner.getDomainId(), owner.getId(), userId, offering.getId(), userData, hostName, diskOfferingId);
+                vm.setUuid(uuidName);
+                vm.setDynamicallyScalable(template.isDynamicallyScalable());
+
+                Map<String, String> details = template.getDetails();
+                if (details != null && !details.isEmpty()) {
+                    vm.details.putAll(details);
+                }
+
+                if (sshPublicKey != null) {
+                    vm.setDetail("SSH.PublicKey", sshPublicKey);
+                }
+
+                if (keyboard != null && !keyboard.isEmpty()) {
+                    vm.setDetail(VmDetailConstants.KEYBOARD, keyboard);
+                }
+
+                if (isIso) {
+                    vm.setIsoId(template.getId());
+                }
+                Long rootDiskSize = null;
+                // custom root disk size, resizes base template to larger size
+                if (customParameters.containsKey("rootdisksize")) {
+                    // already verified for positive number
+                    rootDiskSize = Long.parseLong(customParameters.get("rootdisksize"));
+
+                    VMTemplateVO templateVO = _templateDao.findById(template.getId());
+                    if (templateVO == null) {
+                        throw new InvalidParameterValueException("Unable to look up template by id " + template.getId());
+                    }
+
+                    validateRootDiskResize(hypervisorType, rootDiskSize, templateVO, vm, customParameters);
+                }
+
+                if (isDisplayVm != null) {
+                    vm.setDisplayVm(isDisplayVm);
+                } else {
+                    vm.setDisplayVm(true);
+                }
+
+                long guestOSId = template.getGuestOSId();
+                GuestOSVO guestOS = _guestOSDao.findById(guestOSId);
+                long guestOSCategoryId = guestOS.getCategoryId();
+                GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId);
+
+                // If hypervisor is vSphere and OS is OS X, set special settings.
+                if (hypervisorType.equals(HypervisorType.VMware)) {
+                    if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")) {
+                        vm.setDetail("smc.present", "TRUE");
+                        vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
+                        vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
+                        vm.setDetail("firmware", "efi");
+                        s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi");
+                    } else {
+                        String controllerSetting = _configDao.getValue("vmware.root.disk.controller");
+                        // Don't override if VM already has root/data disk controller detail
+                        if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) {
+                            vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting);
+                        }
+                        if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) {
+                            if (controllerSetting.equalsIgnoreCase("scsi")) {
+                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi");
+                            } else {
+                                vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "osdefault");
+                            }
+                        }
+                    }
+                }
+
+                _vmDao.persist(vm);
+                for (String key : customParameters.keySet()) {
+                    if( key.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) ||
+                            key.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) ||
+                            key.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
+                        // handle double byte strings.
+                        vm.setDetail(key, Integer.toString(Integer.parseInt(customParameters.get(key))));
+                    } else {
+                        vm.setDetail(key, customParameters.get(key));
+                    }
+                }
+                vm.setDetail("deployvm", "true");
+                _vmDao.saveDetails(vm);
+
+                s_logger.debug("Allocating in the DB for vm");
+                DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
+
+                List<String> computeTags = new ArrayList<String>();
+                computeTags.add(offering.getHostTag());
+
+                List<String> rootDiskTags = new ArrayList<String>();
+                rootDiskTags.add(offering.getTags());
+
+                if (isIso) {
+                    _orchSrvc.createVirtualMachineFromScratch(vm.getUuid(), Long.toString(owner.getAccountId()), vm.getIsoId().toString(), hostName, displayName,
+                            hypervisorType.name(), guestOSCategory.getName(), offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags,
+                            networkNicMap, plan, extraDhcpOptionMap);
+                } else {
+                    _orchSrvc.createVirtualMachine(vm.getUuid(), Long.toString(owner.getAccountId()), Long.toString(template.getId()), hostName, displayName, hypervisorType.name(),
+                            offering.getCpu(), offering.getSpeed(), offering.getRamSize(), diskSize, computeTags, rootDiskTags, networkNicMap, plan, rootDiskSize, extraDhcpOptionMap, dataDiskTemplateToDiskOfferingMap);
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully allocated DB entry for " + vm);
+                }
+                CallContext.current().setEventDetails("Vm Id: " + vm.getUuid());
+
+                if (!offering.isDynamic()) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
+                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
+                } else {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
+                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm());
+                }
+
+                //Update Resource Count for the given account
+                resourceCountIncrement(accountId, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
+                return vm;
+            }
+        });
+    }
+
+    public void validateRootDiskResize(final HypervisorType hypervisorType, Long rootDiskSize, VMTemplateVO templateVO, UserVmVO vm, final Map<String, String> customParameters) throws InvalidParameterValueException
+    {
+        // rootdisksize must be larger than template.
+        if ((rootDiskSize << 30) < templateVO.getSize()) {
+            Long templateVOSizeGB = templateVO.getSize() / GiB_TO_BYTES;
+            String error = "Unsupported: rootdisksize override is smaller than template size " + templateVO.getSize() + "B (" + templateVOSizeGB + "GB)";
+            s_logger.error(error);
+            throw new InvalidParameterValueException(error);
+        } else if ((rootDiskSize << 30) > templateVO.getSize()) {
+            if (hypervisorType == HypervisorType.VMware && (vm.getDetails() == null || vm.getDetails().get("rootDiskController") == null)) {
+                s_logger.warn("If Root disk controller parameter is not overridden, then Root disk resize may fail because current Root disk controller value is NULL.");
+            } else if (hypervisorType == HypervisorType.VMware && !vm.getDetails().get("rootDiskController").toLowerCase().contains("scsi")) {
+                String error = "Found unsupported root disk controller: " + vm.getDetails().get("rootDiskController");
+                s_logger.error(error);
+                throw new InvalidParameterValueException(error);
+            } else {
+                s_logger.debug("Rootdisksize override validation successful. Template root disk size " + (templateVO.getSize() / GiB_TO_BYTES) + "GB Root disk size specified " + rootDiskSize + "GB");
+            }
+        } else {
+            s_logger.debug("Root disk size specified is " + (rootDiskSize << 30) + "B and Template root disk size is " + templateVO.getSize() + "B. Both are equal so no need to override");
+            customParameters.remove("rootdisksize");
+        }
+    }
+
+
+    @Override
+    public void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType){
+        ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
+        if (!serviceOffering.isDynamic()) {
+            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                    VirtualMachine.class.getName(), vm.getUuid(), isDisplay);
+        }
+        else {
+            Map<String, String> customParameters = new HashMap<String, String>();
+            customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
+            customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
+            customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
+            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                    VirtualMachine.class.getName(), vm.getUuid(), customParameters, isDisplay);
+        }
+    }
+
+    @Override
+    public HashMap<Long, List<VmNetworkStatsEntry>> getVmNetworkStatistics(long hostId, String hostName, List<Long> vmIds) {
+        HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = new HashMap<Long, List<VmNetworkStatsEntry>>();
+
+        if (vmIds.isEmpty()) {
+            return vmNetworkStatsById;
+        }
+
+        List<String> vmNames = new ArrayList<String>();
+
+        for (Long vmId : vmIds) {
+            UserVmVO vm = _vmDao.findById(vmId);
+            vmNames.add(vm.getInstanceName());
+        }
+
+        Answer answer = _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
+        if (answer == null || !answer.getResult()) {
+            s_logger.warn("Unable to obtain VM network statistics.");
+            return null;
+        } else {
+            HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = ((GetVmNetworkStatsAnswer)answer).getVmNetworkStatsMap();
+
+            if (vmNetworkStatsByName == null) {
+                s_logger.warn("Unable to obtain VM network statistics.");
+                return null;
+            }
+
+            for (String vmName : vmNetworkStatsByName.keySet()) {
+                vmNetworkStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmNetworkStatsByName.get(vmName));
+            }
+        }
+
+        return vmNetworkStatsById;
+    }
+
+    @Override
+    public void collectVmNetworkStatistics (final UserVm userVm) {
+        if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) {
+            return;
+        }
+        s_logger.debug("Collect vm network statistics from host before stopping Vm");
+        long hostId = userVm.getHostId();
+        List<String> vmNames = new ArrayList<String>();
+        vmNames.add(userVm.getInstanceName());
+        final HostVO host = _hostDao.findById(hostId);
+
+        GetVmNetworkStatsAnswer networkStatsAnswer = null;
+        try {
+            networkStatsAnswer = (GetVmNetworkStatsAnswer) _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, host.getGuid(), host.getName()));
+        } catch (Exception e) {
+            s_logger.warn("Error while collecting network stats for vm: " + userVm.getHostName() + " from host: " + host.getName(), e);
+            return;
+        }
+        if (networkStatsAnswer != null) {
+            if (!networkStatsAnswer.getResult()) {
+                s_logger.warn("Error while collecting network stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + networkStatsAnswer.getDetails());
+                return;
+            }
+            try {
+                final GetVmNetworkStatsAnswer networkStatsAnswerFinal = networkStatsAnswer;
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = networkStatsAnswerFinal.getVmNetworkStatsMap();
+                        if (vmNetworkStatsByName == null) {
+                            return;
+                        }
+                        List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsByName.get(userVm.getInstanceName());
+                        if (vmNetworkStats == null) {
+                            return;
+                        }
+
+                        for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
+                            SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
+                            sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
+                            NicVO nic = _nicDao.search(sc_nic, null).get(0);
+                            List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
+                            if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
+                            {
+                                break; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
+                            }
+                            UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
+                            if (previousvmNetworkStats == null) {
+                                previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), userVm.getId(), "UserVm", nic.getNetworkId());
+                                _userStatsDao.persist(previousvmNetworkStats);
+                            }
+                            UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
+
+                            if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
+                                s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
+                                continue;
+                            }
+
+                            if (vmNetworkStat_lock == null) {
+                                s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId());
+                                continue;
+                            }
+
+                            if (previousvmNetworkStats != null
+                                    && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
+                                            || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
+                                s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " +
+                                        "Ignoring current answer. Host: " + host.getName()  + " . VM: " + vmNetworkStat.getVmName() +
+                                        " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived());
+                                continue;
+                            }
+
+                            if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Sent # of bytes that's less than the last one.  " +
+                                            "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
+                                            " Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent());
+                                }
+                                vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
+                            }
+                            vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
+
+                            if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Received # of bytes that's less than the last one.  " +
+                                            "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
+                                            " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived());
+                                }
+                                vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
+                            }
+                            vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
+
+                            if (! _dailyOrHourly) {
+                                //update agg bytes
+                                vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
+                                vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
+                            }
+
+                            _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                s_logger.warn("Unable to update vm network statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
+            }
+        }
+    }
+
+    protected String validateUserData(String userData, HTTPMethod httpmethod) {
+        byte[] decodedUserData = null;
+        if (userData != null) {
+
+            if (userData.contains("%")) {
+                try {
+                    userData = URLDecoder.decode(userData, "UTF-8");
+                } catch (UnsupportedEncodingException e) {
+                    throw new InvalidParameterValueException("Url decoding of userdata failed.");
+                }
+            }
+
+            if (!Base64.isBase64(userData)) {
+                throw new InvalidParameterValueException("User data is not base64 encoded");
+            }
+            // If GET, use 4K. If POST, support upto 32K.
+            if (httpmethod.equals(HTTPMethod.GET)) {
+                if (userData.length() >= MAX_HTTP_GET_LENGTH) {
+                    throw new InvalidParameterValueException("User data is too long for an http GET request");
+                }
+                decodedUserData = Base64.decodeBase64(userData.getBytes());
+                if (decodedUserData.length > MAX_HTTP_GET_LENGTH) {
+                    throw new InvalidParameterValueException("User data is too long for GET request");
+                }
+            } else if (httpmethod.equals(HTTPMethod.POST)) {
+                if (userData.length() >= MAX_HTTP_POST_LENGTH) {
+                    throw new InvalidParameterValueException("User data is too long for an http POST request");
+                }
+                decodedUserData = Base64.decodeBase64(userData.getBytes());
+                if (decodedUserData.length > MAX_HTTP_POST_LENGTH) {
+                    throw new InvalidParameterValueException("User data is too long for POST request");
+                }
+            }
+
+            if (decodedUserData == null || decodedUserData.length < 1) {
+                throw new InvalidParameterValueException("User data is too short");
+            }
+            // Re-encode so that the '=' paddings are added if necessary since 'isBase64' does not require it, but python does on the VR.
+            return Base64.encodeBase64String(decodedUserData);
+        }
+        return null;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription = "starting Vm", async = true)
+    public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
+        return startVirtualMachine(cmd, null, cmd.getDeploymentPlanner());
+    }
+
+    private UserVm startVirtualMachine(DeployVMCmd cmd, Map<VirtualMachineProfile.Param, Object> additonalParams, String deploymentPlannerToUse)
+            throws ResourceUnavailableException,
+            InsufficientCapacityException, ConcurrentOperationException {
+
+        long vmId = cmd.getEntityId();
+        Long hostId = cmd.getHostId();
+        UserVmVO vm = _vmDao.findById(vmId);
+
+        Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = null;
+        try {
+            vmParamPair = startVirtualMachine(vmId, hostId, additonalParams, deploymentPlannerToUse);
+            vm = vmParamPair.first();
+
+            // At this point VM should be in "Running" state
+            UserVmVO tmpVm = _vmDao.findById(vm.getId());
+            if (!tmpVm.getState().equals(State.Running)) {
+                // Some other thread changed state of VM, possibly vmsync
+                s_logger.error("VM " + tmpVm + " unexpectedly went to " + tmpVm.getState() + " state");
+                throw new ConcurrentOperationException("Failed to deploy VM "+vm);
+            }
+
+            try {
+                if (!cmd.getDataDiskTemplateToDiskOfferingMap().isEmpty()) {
+                    List<VolumeVO> vols = _volsDao.findByInstance(tmpVm.getId());
+                    for (VolumeVO vol : vols) {
+                        if (vol.getVolumeType() == Volume.Type.DATADISK) {
+                            DiskOffering doff =  _entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
+                            _volService.resizeVolumeOnHypervisor(vol.getId(), doff.getDiskSize(), tmpVm.getHostId(), vm.getInstanceName());
+                        }
+                    }
+                }
+            }
+            catch (Exception e) {
+                s_logger.fatal("Unable to resize the data disk for vm " + vm.getDisplayName() + " due to " + e.getMessage(), e);
+            }
+
+        } finally {
+            updateVmStateForFailedVmCreation(vm.getId(), hostId);
+        }
+
+        // Check that the password was passed in and is valid
+        VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
+        if (template.isEnablePassword()) {
+            // this value is not being sent to the backend; need only for api
+            // display purposes
+            vm.setPassword((String)vmParamPair.second().get(VirtualMachineProfile.Param.VmPassword));
+        }
+
+        return vm;
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+        UserVmVO vm = _vmDao.findById(profile.getId());
+        Map<String, String> details = userVmDetailsDao.listDetailsKeyPairs(vm.getId());
+        vm.setDetails(details);
+
+
+        // add userdata info into vm profile
+        Nic defaultNic = _networkModel.getDefaultNic(vm.getId());
+        if(defaultNic != null) {
+            Network network = _networkModel.getNetwork(defaultNic.getNetworkId());
+            if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
+                boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+
+                List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
+                        vm.getUuid(), defaultNic.getIPv4Address(), vm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows);
+                String vmName = vm.getInstanceName();
+                String configDriveIsoRootFolder = "/tmp";
+                String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
+                profile.setVmData(vmData);
+                profile.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value());
+                profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder);
+                profile.setConfigDriveIsoFile(isoFile);
+            }
+        }
+
+        _templateMgr.prepareIsoForVmProfile(profile, dest);
+        return true;
+    }
+
+    @Override
+    public boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic) {
+        if (!nic.getBroadCastUri().getScheme().equals("pvlan")) {
+            return false;
+        }
+        String op = "add";
+        if (!add) {
+            // "delete" would remove all the rules(if using ovs) related to this vm
+            op = "delete";
+        }
+        Network network = _networkDao.findById(nic.getNetworkId());
+        Host host = _hostDao.findById(hostId);
+        String networkTag = _networkModel.getNetworkTag(host.getHypervisorType(), network);
+        PvlanSetupCommand cmd = PvlanSetupCommand.createVmSetup(op, nic.getBroadCastUri(), networkTag, nic.getMacAddress());
+        Answer answer = null;
+        try {
+            answer = _agentMgr.send(hostId, cmd);
+        } catch (OperationTimedoutException e) {
+            s_logger.warn("Timed Out", e);
+            return false;
+        } catch (AgentUnavailableException e) {
+            s_logger.warn("Agent Unavailable ", e);
+            return false;
+        }
+
+        boolean result = true;
+        if (answer == null || !answer.getResult()) {
+            result = false;
+        }
+        return result;
+    }
+
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+        UserVmVO userVm = _vmDao.findById(profile.getId());
+        List<NicVO> nics = _nicDao.listByVmId(userVm.getId());
+        for (NicVO nic : nics) {
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            if (network.getTrafficType() == TrafficType.Guest || network.getTrafficType() == TrafficType.Public) {
+                userVm.setPrivateIpAddress(nic.getIPv4Address());
+                userVm.setPrivateMacAddress(nic.getMacAddress());
+                _vmDao.update(userVm.getId(), userVm);
+            }
+        }
+
+        List<VolumeVO> volumes = _volsDao.findByInstance(userVm.getId());
+        VmDiskStatisticsVO diskstats = null;
+        for (VolumeVO volume : volumes) {
+            diskstats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
+            if (diskstats == null) {
+                diskstats = new VmDiskStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
+                _vmDiskStatsDao.persist(diskstats);
+            }
+        }
+
+        finalizeCommandsOnStart(cmds, profile);
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+        UserVmVO vm = _vmDao.findById(profile.getId());
+        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vm.getId());
+        RestoreVMSnapshotCommand command = _vmSnapshotMgr.createRestoreCommand(vm, vmSnapshots);
+        if (command != null) {
+            cmds.addCommand("restoreVMSnapshot", command);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean  finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+        UserVmVO vm = _vmDao.findById(profile.getId());
+
+        Answer[] answersToCmds = cmds.getAnswers();
+        if (answersToCmds == null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Returning from finalizeStart() since there are no answers to read");
+            }
+            return true;
+        }
+        Answer startAnswer = cmds.getAnswer(StartAnswer.class);
+        String returnedIp = null;
+        String originalIp = null;
+        if (startAnswer != null) {
+            StartAnswer startAns = (StartAnswer)startAnswer;
+            VirtualMachineTO vmTO = startAns.getVirtualMachine();
+            for (NicTO nicTO : vmTO.getNics()) {
+                if (nicTO.getType() == TrafficType.Guest) {
+                    returnedIp = nicTO.getIp();
+                }
+            }
+        }
+
+        List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        NicVO guestNic = null;
+        NetworkVO guestNetwork = null;
+        for (NicVO nic : nics) {
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            long isDefault = (nic.isDefaultNic()) ? 1 : 0;
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), Long.toString(nic.getId()),
+                    network.getNetworkOfferingId(), null, isDefault, VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplay());
+            if (network.getTrafficType() == TrafficType.Guest) {
+                originalIp = nic.getIPv4Address();
+                guestNic = nic;
+                guestNetwork = network;
+                // In vmware, we will be effecting pvlan settings in portgroups in StartCommand.
+                if (profile.getHypervisorType() != HypervisorType.VMware) {
+                    if (nic.getBroadcastUri().getScheme().equals("pvlan")) {
+                        NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+                        if (!setupVmForPvlan(true, hostId, nicProfile)) {
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+        boolean ipChanged = false;
+        if (originalIp != null && !originalIp.equalsIgnoreCase(returnedIp)) {
+            if (returnedIp != null && guestNic != null) {
+                guestNic.setIPv4Address(returnedIp);
+                ipChanged = true;
+            }
+        }
+        if (returnedIp != null && !returnedIp.equalsIgnoreCase(originalIp)) {
+            if (guestNic != null) {
+                guestNic.setIPv4Address(returnedIp);
+                ipChanged = true;
+            }
+        }
+        if (ipChanged) {
+            _dcDao.findById(vm.getDataCenterId());
+            UserVmVO userVm = _vmDao.findById(profile.getId());
+            // dc.getDhcpProvider().equalsIgnoreCase(Provider.ExternalDhcpServer.getName())
+            if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestNetwork.getId(), Service.Dhcp, Provider.ExternalDhcpServer)) {
+                _nicDao.update(guestNic.getId(), guestNic);
+                userVm.setPrivateIpAddress(guestNic.getIPv4Address());
+                _vmDao.update(userVm.getId(), userVm);
+
+                s_logger.info("Detected that ip changed in the answer, updated nic in the db with new ip " + returnedIp);
+            }
+        }
+
+        // get system ip and create static nat rule for the vm
+        try {
+            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
+        } catch (Exception ex) {
+            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
+            return false;
+        }
+
+        Answer answer = cmds.getAnswer("restoreVMSnapshot");
+        if (answer != null && answer instanceof RestoreVMSnapshotAnswer) {
+            RestoreVMSnapshotAnswer restoreVMSnapshotAnswer = (RestoreVMSnapshotAnswer) answer;
+            if (restoreVMSnapshotAnswer == null || !restoreVMSnapshotAnswer.getResult()) {
+                s_logger.warn("Unable to restore the vm snapshot from image file to the VM: " + restoreVMSnapshotAnswer.getDetails());
+            }
+        }
+
+        final VirtualMachineProfile vmProfile = profile;
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                final UserVmVO vm = _vmDao.findById(vmProfile.getId());
+                final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+                for (NicVO nic : nics) {
+                    Network network = _networkModel.getNetwork(nic.getNetworkId());
+                    if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+                        vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
+                    }
+                }
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    public void finalizeExpunge(VirtualMachine vm) {
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_STOP, eventDescription = "stopping Vm", async = true)
+    public UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException {
+        // Input validation
+        Account caller = CallContext.current().getCallingAccount();
+        Long userId = CallContext.current().getCallingUserId();
+
+        // if account is removed, return error
+        if (caller != null && caller.getRemoved() != null) {
+            throw new PermissionDeniedException("The account " + caller.getUuid() + " is removed");
+        }
+
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        _userDao.findById(userId);
+        boolean status = false;
+        try {
+            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
+
+            if(forced) {
+                status = vmEntity.stopForced(Long.toString(userId));
+            } else {
+                status = vmEntity.stop(Long.toString(userId));
+            }
+            if (status) {
+                return _vmDao.findById(vmId);
+            } else {
+                return null;
+            }
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
+        } catch (CloudException e) {
+            throw new CloudRuntimeException("Unable to contact the agent to stop the virtual machine " + vm, e);
+        }
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+        VirtualMachine vm = profile.getVirtualMachine();
+        // release elastic IP here
+        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
+        if (ip != null && ip.getSystem()) {
+            CallContext ctx = CallContext.current();
+            try {
+                long networkId = ip.getAssociatedWithNetworkId();
+                Network guestNetwork = _networkDao.findById(networkId);
+                NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, guestNetwork.getNetworkOfferingId());
+                assert (offering.isAssociatePublicIP() == true) : "User VM should not have system owned public IP associated with it when offering configured not to associate public IP.";
+                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
+            } catch (Exception ex) {
+                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ", ex);
+            }
+        }
+
+        final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+        for (final NicVO nic : nics) {
+            final NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            if (network != null && network.getTrafficType() == TrafficType.Guest) {
+                final String nicIp = Strings.isNullOrEmpty(nic.getIPv4Address()) ? nic.getIPv6Address() : nic.getIPv4Address();
+                if (!Strings.isNullOrEmpty(nicIp)) {
+                    NicProfile nicProfile = new NicProfile(nic.getIPv4Address(), nic.getIPv6Address(), nic.getMacAddress());
+                    nicProfile.setId(nic.getId());
+                    _networkMgr.cleanupNicDhcpDnsEntry(network, profile, nicProfile);
+                }
+                if (nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) {
+                    NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic");
+                    setupVmForPvlan(false, vm.getHostId(), nicProfile);
+                }
+            }
+        }
+    }
+
+    @Override
+    public Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        // Input validation
+        Account callerAccount = CallContext.current().getCallingAccount();
+        UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
+
+        // if account is removed, return error
+        if (callerAccount != null && callerAccount.getRemoved() != null) {
+            throw new InvalidParameterValueException("The account " + callerAccount.getId() + " is removed");
+        }
+
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
+        }
+
+        _accountMgr.checkAccess(callerAccount, null, true, vm);
+
+        Account owner = _accountDao.findById(vm.getAccountId());
+
+        if (owner == null) {
+            throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
+        }
+
+        if (owner.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
+        }
+
+        Host destinationHost = null;
+        if (hostId != null) {
+            Account account = CallContext.current().getCallingAccount();
+            if (!_accountService.isRootAdmin(account.getId())) {
+                throw new PermissionDeniedException(
+                        "Parameter hostid can only be specified by a Root Admin, permission denied");
+            }
+            destinationHost = _hostDao.findById(hostId);
+            if (destinationHost == null) {
+                throw new InvalidParameterValueException("Unable to find the host to deploy the VM, host id=" + hostId);
+            }
+        }
+
+        // check if vm is security group enabled
+        if (_securityGroupMgr.isVmSecurityGroupEnabled(vmId) && _securityGroupMgr.getSecurityGroupsForVm(vmId).isEmpty()
+                && !_securityGroupMgr.isVmMappedToDefaultSecurityGroup(vmId) && _networkModel.canAddDefaultSecurityGroup()) {
+            // if vm is not mapped to security group, create a mapping
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Vm " + vm + " is security group enabled, but not mapped to default security group; creating the mapping automatically");
+            }
+
+            SecurityGroup defaultSecurityGroup = _securityGroupMgr.getDefaultSecurityGroup(vm.getAccountId());
+            if (defaultSecurityGroup != null) {
+                List<Long> groupList = new ArrayList<Long>();
+                groupList.add(defaultSecurityGroup.getId());
+                _securityGroupMgr.addInstanceToGroups(vmId, groupList);
+            }
+        }
+
+        DataCenterDeployment plan = null;
+        boolean deployOnGivenHost = false;
+        if (destinationHost != null) {
+            s_logger.debug("Destination Host to deploy the VM is specified, specifying a deployment plan to deploy the VM");
+            plan = new DataCenterDeployment(vm.getDataCenterId(), destinationHost.getPodId(), destinationHost.getClusterId(), destinationHost.getId(), null, null);
+            if (!AllowDeployVmIfGivenHostFails.value()) {
+                deployOnGivenHost = true;
+            }
+        }
+
+        // Set parameters
+        Map<VirtualMachineProfile.Param, Object> params = null;
+        VMTemplateVO template = null;
+        if (vm.isUpdateParameters()) {
+            _vmDao.loadDetails(vm);
+            // Check that the password was passed in and is valid
+            template = _templateDao.findByIdIncludingRemoved(vm.getTemplateId());
+
+            String password = "saved_password";
+            if (template.isEnablePassword()) {
+                if (vm.getDetail("password") != null) {
+                    password = DBEncryptionUtil.decrypt(vm.getDetail("password"));
+                } else {
+                    password = _mgr.generateRandomPassword();
+                    vm.setPassword(password);
+                }
+            }
+
+            if (!validPassword(password)) {
+                throw new InvalidParameterValueException("A valid password for this virtual machine was not provided.");
+            }
+
+            // Check if an SSH key pair was selected for the instance and if so
+            // use it to encrypt & save the vm password
+            encryptAndStorePassword(vm, password);
+
+            params = new HashMap<VirtualMachineProfile.Param, Object>();
+            if (additionalParams != null) {
+                params.putAll(additionalParams);
+            }
+            params.put(VirtualMachineProfile.Param.VmPassword, password);
+        }
+
+        VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
+
+        DeploymentPlanner planner = null;
+        if (deploymentPlannerToUse != null) {
+            // if set to null, the deployment planner would be later figured out either from global config var, or from
+            // the service offering
+            planner = _planningMgr.getDeploymentPlannerByName(deploymentPlannerToUse);
+            if (planner == null) {
+                throw new InvalidParameterValueException("Can't find a planner by name " + deploymentPlannerToUse);
+            }
+        }
+
+        String reservationId = vmEntity.reserve(planner, plan, new ExcludeList(), Long.toString(callerUser.getId()));
+        vmEntity.deploy(reservationId, Long.toString(callerUser.getId()), params, deployOnGivenHost);
+
+        Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = new Pair(vm, params);
+        if (vm != null && vm.isUpdateParameters()) {
+            // this value is not being sent to the backend; need only for api
+            // display purposes
+            if (template.isEnablePassword()) {
+                if (vm.getDetail("password") != null) {
+                    userVmDetailsDao.removeDetail(vm.getId(), "password");
+                }
+                vm.setUpdateParameters(false);
+                _vmDao.update(vm.getId(), vm);
+            }
+        }
+
+        return vmParamPair;
+    }
+
+    @Override
+    public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableException, ConcurrentOperationException {
+        // Account caller = CallContext.current().getCallingAccount();
+        // Long userId = CallContext.current().getCallingUserId();
+        Long userId = 2L;
+
+        // Verify input parameters
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null || vm.getRemoved() != null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId");
+            throw ex;
+        }
+
+        if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) {
+            s_logger.trace("Vm id=" + vmId + " is already destroyed");
+            return vm;
+        }
+
+        boolean status;
+        State vmState = vm.getState();
+
+        try {
+            VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
+            status = vmEntity.destroy(Long.toString(userId), expunge);
+        } catch (CloudException e) {
+            CloudRuntimeException ex = new CloudRuntimeException("Unable to destroy with specified vmId", e);
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if (status) {
+            // Mark the account's volumes as destroyed
+            List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
+            for (VolumeVO volume : volumes) {
+                if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
+                }
+            }
+
+            if (vmState != State.Error) {
+                // Get serviceOffering for Virtual Machine
+                ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
+
+                //Update Resource Count for the given account
+                resourceCountDecrement(vm.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
+            }
+            return _vmDao.findById(vmId);
+        } else {
+            CloudRuntimeException ex = new CloudRuntimeException("Failed to destroy vm with specified vmId");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+    }
+
+    @Override
+    public void collectVmDiskStatistics(final UserVm userVm) {
+        // support KVM only util 2013.06.25
+        if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) {
+            return;
+        }
+        s_logger.debug("Collect vm disk statistics from host before stopping Vm");
+        long hostId = userVm.getHostId();
+        List<String> vmNames = new ArrayList<String>();
+        vmNames.add(userVm.getInstanceName());
+        final HostVO host = _hostDao.findById(hostId);
+
+        GetVmDiskStatsAnswer diskStatsAnswer = null;
+        try {
+            diskStatsAnswer = (GetVmDiskStatsAnswer)_agentMgr.easySend(hostId, new GetVmDiskStatsCommand(vmNames, host.getGuid(), host.getName()));
+        } catch (Exception e) {
+            s_logger.warn("Error while collecting disk stats for vm: " + userVm.getInstanceName() + " from host: " + host.getName(), e);
+            return;
+        }
+        if (diskStatsAnswer != null) {
+            if (!diskStatsAnswer.getResult()) {
+                s_logger.warn("Error while collecting disk stats vm: " + userVm.getInstanceName() + " from host: " + host.getName() + "; details: " + diskStatsAnswer.getDetails());
+                return;
+            }
+            try {
+                final GetVmDiskStatsAnswer diskStatsAnswerFinal = diskStatsAnswer;
+                Transaction.execute(new TransactionCallbackNoReturn() {
+                    @Override
+                    public void doInTransactionWithoutResult(TransactionStatus status) {
+                        HashMap<String, List<VmDiskStatsEntry>> vmDiskStatsByName = diskStatsAnswerFinal.getVmDiskStatsMap();
+                        if (vmDiskStatsByName == null) {
+                            return;
+                        }
+                        List<VmDiskStatsEntry> vmDiskStats = vmDiskStatsByName.get(userVm.getInstanceName());
+                        if (vmDiskStats == null) {
+                            return;
+                        }
+
+                        for (VmDiskStatsEntry vmDiskStat : vmDiskStats) {
+                            SearchCriteria<VolumeVO> sc_volume = _volsDao.createSearchCriteria();
+                            sc_volume.addAnd("path", SearchCriteria.Op.EQ, vmDiskStat.getPath());
+                            List<VolumeVO> volumes = _volsDao.search(sc_volume, null);
+                            if ((volumes == null) || (volumes.size() == 0)) {
+                                break;
+                            }
+                            VolumeVO volume = volumes.get(0);
+                            VmDiskStatisticsVO previousVmDiskStats = _vmDiskStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
+                            VmDiskStatisticsVO vmDiskStat_lock = _vmDiskStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), userVm.getId(), volume.getId());
+
+                            if ((vmDiskStat.getIORead() == 0) && (vmDiskStat.getIOWrite() == 0) && (vmDiskStat.getBytesRead() == 0) && (vmDiskStat.getBytesWrite() == 0)) {
+                                s_logger.debug("Read/Write of IO and Bytes are both 0. Not updating vm_disk_statistics");
+                                continue;
+                            }
+
+                            if (vmDiskStat_lock == null) {
+                                s_logger.warn("unable to find vm disk stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId() + " and volumeId:"
+                                        + volume.getId());
+                                continue;
+                            }
+
+                            if (previousVmDiskStats != null
+                                    && ((previousVmDiskStats.getCurrentIORead() != vmDiskStat_lock.getCurrentIORead()) || ((previousVmDiskStats.getCurrentIOWrite() != vmDiskStat_lock
+                                    .getCurrentIOWrite())
+                                            || (previousVmDiskStats.getCurrentBytesRead() != vmDiskStat_lock.getCurrentBytesRead()) || (previousVmDiskStats
+                                                    .getCurrentBytesWrite() != vmDiskStat_lock.getCurrentBytesWrite())))) {
+                                s_logger.debug("vm disk stats changed from the time GetVmDiskStatsCommand was sent. " + "Ignoring current answer. Host: " + host.getName()
+                                + " . VM: " + vmDiskStat.getVmName() + " IO Read: " + vmDiskStat.getIORead() + " IO Write: " + vmDiskStat.getIOWrite() + " Bytes Read: "
+                                + vmDiskStat.getBytesRead() + " Bytes Write: " + vmDiskStat.getBytesWrite());
+                                continue;
+                            }
+
+                            if (vmDiskStat_lock.getCurrentIORead() > vmDiskStat.getIORead()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Read # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
+                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIORead() + " Stored: " + vmDiskStat_lock.getCurrentIORead());
+                                }
+                                vmDiskStat_lock.setNetIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+                            }
+                            vmDiskStat_lock.setCurrentIORead(vmDiskStat.getIORead());
+                            if (vmDiskStat_lock.getCurrentIOWrite() > vmDiskStat.getIOWrite()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Write # of IO that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
+                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getIOWrite() + " Stored: " + vmDiskStat_lock.getCurrentIOWrite());
+                                }
+                                vmDiskStat_lock.setNetIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+                            }
+                            vmDiskStat_lock.setCurrentIOWrite(vmDiskStat.getIOWrite());
+                            if (vmDiskStat_lock.getCurrentBytesRead() > vmDiskStat.getBytesRead()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Read # of Bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
+                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesRead() + " Stored: " + vmDiskStat_lock.getCurrentBytesRead());
+                                }
+                                vmDiskStat_lock.setNetBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+                            }
+                            vmDiskStat_lock.setCurrentBytesRead(vmDiskStat.getBytesRead());
+                            if (vmDiskStat_lock.getCurrentBytesWrite() > vmDiskStat.getBytesWrite()) {
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("Write # of Bytes that's less than the last one.  " + "Assuming something went wrong and persisting it. Host: " + host.getName()
+                                    + " . VM: " + vmDiskStat.getVmName() + " Reported: " + vmDiskStat.getBytesWrite() + " Stored: "
+                                    + vmDiskStat_lock.getCurrentBytesWrite());
+                                }
+                                vmDiskStat_lock.setNetBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+                            }
+                            vmDiskStat_lock.setCurrentBytesWrite(vmDiskStat.getBytesWrite());
+
+                            if (!_dailyOrHourly) {
+                                //update agg bytes
+                                vmDiskStat_lock.setAggIORead(vmDiskStat_lock.getNetIORead() + vmDiskStat_lock.getCurrentIORead());
+                                vmDiskStat_lock.setAggIOWrite(vmDiskStat_lock.getNetIOWrite() + vmDiskStat_lock.getCurrentIOWrite());
+                                vmDiskStat_lock.setAggBytesRead(vmDiskStat_lock.getNetBytesRead() + vmDiskStat_lock.getCurrentBytesRead());
+                                vmDiskStat_lock.setAggBytesWrite(vmDiskStat_lock.getNetBytesWrite() + vmDiskStat_lock.getCurrentBytesWrite());
+                            }
+
+                            _vmDiskStatsDao.update(vmDiskStat_lock.getId(), vmDiskStat_lock);
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                s_logger.warn("Unable to update vm disk statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
+            }
+        }
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_EXPUNGE, eventDescription = "expunging Vm", async = true)
+    public UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException {
+        Account caller = CallContext.current().getCallingAccount();
+        Long userId = caller.getId();
+
+        // Verify input parameters
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId");
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+        if (vm.getRemoved() != null) {
+            s_logger.trace("Vm id=" + vmId + " is already expunged");
+            return vm;
+        }
+
+        if (!(vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getState() == State.Error)) {
+            CloudRuntimeException ex = new CloudRuntimeException("Please destroy vm with specified vmId before expunge");
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+        // When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
+        if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
+            throw new PermissionDeniedException("Expunging a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
+        }
+
+        _vmSnapshotMgr.deleteVMSnapshotsFromDB(vmId);
+
+        boolean status;
+
+        status = expunge(vm, userId, caller);
+        if (status) {
+            return _vmDao.findByIdIncludingRemoved(vmId);
+        } else {
+            CloudRuntimeException ex = new CloudRuntimeException("Failed to expunge vm with specified vmId");
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+    }
+
+    @Override
+    public HypervisorType getHypervisorTypeOfUserVM(long vmId) {
+        UserVmVO userVm = _vmDao.findById(vmId);
+        if (userVm == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id");
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+        return userVm.getHypervisorType();
+    }
+
+    @Override
+    public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
+    StorageUnavailableException, ResourceAllocationException {
+        //Verify that all objects exist before passing them to the service
+        Account owner = _accountService.getActiveAccountById(cmd.getEntityOwnerId());
+
+        verifyDetails(cmd.getDetails());
+
+        Long zoneId = cmd.getZoneId();
+
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+        if (zone == null) {
+            throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId);
+        }
+
+        Long serviceOfferingId = cmd.getServiceOfferingId();
+
+        ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        Long templateId = cmd.getTemplateId();
+
+        if (!serviceOffering.isDynamic()) {
+            for(String detail: cmd.getDetails().keySet()) {
+                if(detail.equalsIgnoreCase(VmDetailConstants.CPU_NUMBER) || detail.equalsIgnoreCase(VmDetailConstants.CPU_SPEED) || detail.equalsIgnoreCase(VmDetailConstants.MEMORY)) {
+                    throw new InvalidParameterValueException("cpuNumber or cpuSpeed or memory should not be specified for static service offering");
+                }
+            }
+        }
+
+        VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+        // Make sure a valid template ID was specified
+        if (template == null) {
+            throw new InvalidParameterValueException("Unable to use template " + templateId);
+        }
+
+        Long diskOfferingId = cmd.getDiskOfferingId();
+        DiskOffering diskOffering = null;
+        if (diskOfferingId != null) {
+            diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
+            if (diskOffering == null) {
+                throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
+            }
+        }
+
+        if (!zone.isLocalStorageEnabled()) {
+            if (serviceOffering.isUseLocalStorage()) {
+                throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
+            }
+            if (diskOffering != null && diskOffering.isUseLocalStorage()) {
+                throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it");
+            }
+        }
+
+        String ipAddress = cmd.getIpAddress();
+        String ip6Address = cmd.getIp6Address();
+        String macAddress = cmd.getMacAddress();
+        String name = cmd.getName();
+        String displayName = cmd.getDisplayName();
+        UserVm vm = null;
+        IpAddresses addrs = new IpAddresses(ipAddress, ip6Address, macAddress);
+        Long size = cmd.getSize();
+        String group = cmd.getGroup();
+        String userData = cmd.getUserData();
+        String sshKeyPairName = cmd.getSSHKeyPairName();
+        Boolean displayVm = cmd.isDisplayVm();
+        String keyboard = cmd.getKeyboard();
+        Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = cmd.getDataDiskTemplateToDiskOfferingMap();
+        if (zone.getNetworkType() == NetworkType.Basic) {
+            if (cmd.getNetworkIds() != null) {
+                throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
+            } else {
+                vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId,
+                        size , group , cmd.getHypervisor(), cmd.getHttpMethod(), userData , sshKeyPairName , cmd.getIpToNetworkMap(), addrs, displayVm , keyboard , cmd.getAffinityGroupIdList(),
+                        cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
+            }
+        } else {
+            if (zone.isSecurityGroupEnabled())  {
+                vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), getSecurityGroupIdList(cmd), owner, name,
+                        displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
+                        cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
+
+            } else {
+                if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
+                    throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
+                }
+                vm = createAdvancedVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), owner, name, displayName, diskOfferingId, size, group,
+                        cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(),
+                        cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap);
+            }
+        }
+        // check if this templateId has a child ISO
+        List<VMTemplateVO> child_templates = _templateDao.listByParentTemplatetId(templateId);
+        for (VMTemplateVO tmpl: child_templates){
+            if (tmpl.getFormat() == Storage.ImageFormat.ISO){
+                s_logger.info("MDOV trying to attach disk to the VM " + tmpl.getId() + " vmid=" + vm.getId());
+                _tmplService.attachIso(tmpl.getId(), vm.getId());
+            }
+        }
+
+        // Add extraConfig to user_vm_details table
+        Account caller = CallContext.current().getCallingAccount();
+        Long callerId = caller.getId();
+        String extraConfig = cmd.getExtraConfig();
+        if (StringUtils.isNotBlank(extraConfig) && EnableAdditionalVmConfig.valueIn(callerId) ) {
+            addExtraConfig(vm, caller, extraConfig);
+        }
+
+        return vm;
+    }
+
+    /**
+     * Persist extra configurations as details for VMware VMs
+     */
+    protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) {
+        String[] configDataArr = decodedUrl.split("\\r?\\n");
+        for (String config: configDataArr) {
+            String[] keyValue = config.split("=");
+            try {
+                userVmDetailsDao.addDetail(vm.getId(), keyValue[0], keyValue[1], true);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                throw new CloudRuntimeException("Issue occurred during parsing of:" + config);
+            }
+        }
+    }
+
+    /**
+     * Persist extra configurations as details for hypervisors except Vmware
+     */
+    protected void persistExtraConfigNonVmware(String decodedUrl, UserVm vm) {
+        String[] extraConfigs = decodedUrl.split("\n\n");
+        for (String cfg : extraConfigs) {
+            int i = 1;
+            String[] cfgParts = cfg.split("\n");
+            String extraConfigKey = ApiConstants.EXTRA_CONFIG;
+            String extraConfigValue;
+            if (cfgParts[0].matches("\\S+:$")) {
+                extraConfigKey += "-" + cfgParts[0].substring(0,cfgParts[0].length() - 1);
+                extraConfigValue = cfg.replace(cfgParts[0] + "\n", "");
+            } else {
+                extraConfigKey += "-" + String.valueOf(i);
+                extraConfigValue = cfg;
+            }
+            userVmDetailsDao.addDetail(vm.getId(), extraConfigKey, extraConfigValue, true);
+            i++;
+        }
+    }
+
+    protected void addExtraConfig(UserVm vm, Account caller, String extraConfig) {
+        String decodedUrl = decodeExtraConfig(extraConfig);
+        HypervisorType hypervisorType = vm.getHypervisorType();
+        if (hypervisorType == HypervisorType.VMware) {
+            persistExtraConfigVmware(decodedUrl, vm);
+        } else {
+            persistExtraConfigNonVmware(decodedUrl, vm);
+        }
+    }
+
+    protected String decodeExtraConfig(String encodeString) {
+        String decodedUrl;
+        try {
+            decodedUrl = URLDecoder.decode(encodeString, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new CloudRuntimeException("Failed to provided decode URL string: " + e.getMessage());
+        }
+        return decodedUrl;
+    }
+
+    protected List<Long> getSecurityGroupIdList(SecurityGroupAction cmd) {
+        if (cmd.getSecurityGroupNameList() != null && cmd.getSecurityGroupIdList() != null) {
+            throw new InvalidParameterValueException("securitygroupids parameter is mutually exclusive with securitygroupnames parameter");
+        }
+
+        //transform group names to ids here
+        if (cmd.getSecurityGroupNameList() != null) {
+            List<Long> securityGroupIds = new ArrayList<Long>();
+            for (String groupName : cmd.getSecurityGroupNameList()) {
+                SecurityGroup sg = _securityGroupMgr.getSecurityGroup(groupName, cmd.getEntityOwnerId());
+                if (sg == null) {
+                    throw new InvalidParameterValueException("Unable to find group by name " + groupName);
+                } else {
+                    securityGroupIds.add(sg.getId());
+                }
+            }
+            return securityGroupIds;
+        } else {
+            return cmd.getSecurityGroupIdList();
+        }
+    }
+
+    // this is an opportunity to verify that parameters that came in via the Details Map are OK
+    // for example, minIops and maxIops should either both be specified or neither be specified and,
+    // if specified, minIops should be <= maxIops
+    private void verifyDetails(Map<String,String> details) {
+        if (details != null) {
+            String minIops = details.get("minIops");
+            String maxIops = details.get("maxIops");
+
+            verifyMinAndMaxIops(minIops, maxIops);
+
+            minIops = details.get("minIopsDo");
+            maxIops = details.get("maxIopsDo");
+
+            verifyMinAndMaxIops(minIops, maxIops);
+        }
+    }
+
+    private void verifyMinAndMaxIops(String minIops, String maxIops) {
+        if ((minIops != null && maxIops == null) || (minIops == null && maxIops != null)) {
+            throw new InvalidParameterValueException("Either 'Min IOPS' and 'Max IOPS' must both be specified or neither be specified.");
+        }
+
+        long lMinIops;
+
+        try {
+            if (minIops != null) {
+                lMinIops = Long.parseLong(minIops);
+            }
+            else {
+                lMinIops = 0;
+            }
+        }
+        catch (NumberFormatException ex) {
+            throw new InvalidParameterValueException("'Min IOPS' must be a whole number.");
+        }
+
+        long lMaxIops;
+
+        try {
+            if (maxIops != null) {
+                lMaxIops = Long.parseLong(maxIops);
+            }
+            else {
+                lMaxIops = 0;
+            }
+        }
+        catch (NumberFormatException ex) {
+            throw new InvalidParameterValueException("'Max IOPS' must be a whole number.");
+        }
+
+        if (lMinIops > lMaxIops) {
+            throw new InvalidParameterValueException("'Min IOPS' must be less than or equal to 'Max IOPS'.");
+        }
+    }
+
+    @Override
+    public UserVm getUserVm(long vmId) {
+        return _vmDao.findById(vmId);
+    }
+
+    @Override
+    public VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool) {
+        // access check - only root admin can migrate VM
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
+            }
+            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
+        }
+
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId);
+        }
+
+        if (vm.getState() != State.Stopped) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm having the specified id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if (vm.getType() != VirtualMachine.Type.User) {
+            // OffLineVmwareMigration: *WHY* ?
+            throw new InvalidParameterValueException("can only do storage migration on user vm");
+        }
+
+        List<VolumeVO> vols = _volsDao.findByInstance(vm.getId());
+        if (vols.size() > 1) {
+            // OffLineVmwareMigration: data disks are not permitted, here!
+            if (vols.size() > 1 &&
+                    // OffLineVmwareMigration: allow multiple disks for vmware
+                    !HypervisorType.VMware.equals(vm.getHypervisorType())) {
+                throw new InvalidParameterValueException("Data disks attached to the vm, can not migrate. Need to detach data disks first");
+            }
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
+            throw new InvalidParameterValueException("VM's disk cannot be migrated, please remove all the VM Snapshots for this VM");
+        }
+
+        checkDestinationHypervisorType(destPool, vm);
+
+        _itMgr.storageMigration(vm.getUuid(), destPool);
+        return _vmDao.findById(vm.getId());
+
+    }
+
+    private void checkDestinationHypervisorType(StoragePool destPool, VMInstanceVO vm) {
+        HypervisorType destHypervisorType = destPool.getHypervisor();
+        if (destHypervisorType == null) {
+            destHypervisorType = _clusterDao.findById(
+                    destPool.getClusterId()).getHypervisorType();
+        }
+
+        if (vm.getHypervisorType() != destHypervisorType && destHypervisorType != HypervisorType.Any) {
+            throw new InvalidParameterValueException("hypervisor is not compatible: dest: " + destHypervisorType.toString() + ", vm: " + vm.getHypervisorType().toString());
+        }
+
+    }
+
+    private boolean isVMUsingLocalStorage(VMInstanceVO vm) {
+        boolean usesLocalStorage = false;
+
+        List<VolumeVO> volumes = _volsDao.findByInstance(vm.getId());
+        for (VolumeVO vol : volumes) {
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
+            if (diskOffering.isUseLocalStorage()) {
+                usesLocalStorage = true;
+                break;
+            }
+            StoragePoolVO storagePool = _storagePoolDao.findById(vol.getPoolId());
+            if (storagePool.isLocal()) {
+                usesLocalStorage = true;
+                break;
+            }
+        }
+        return usesLocalStorage;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
+    public VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
+    VirtualMachineMigrationException {
+        // access check - only root admin can migrate VM
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
+            }
+            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
+        }
+
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId);
+        }
+        // business logic
+        if (vm.getState() != State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
+            }
+            InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        checkIfHostOfVMIsInPrepareForMaintenanceState(vm.getHostId(), vmId, "Migrate");
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+        }
+
+        if (!isOnSupportedHypevisorForMigration(vm)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv, cannot migrate this VM form hypervisor type " + vm.getHypervisorType());
+            }
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
+        }
+
+        if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
+        }
+
+        if (isVMUsingLocalStorage(vm)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(vm + " is using Local Storage, cannot migrate this VM.");
+            }
+            throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate");
+        }
+
+        // check if migrating to same host
+        long srcHostId = vm.getHostId();
+        if (destinationHost.getId() == srcHostId) {
+            throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please specify valid destination host to migrate the VM");
+        }
+
+        // check if host is UP
+        if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) {
+            throw new InvalidParameterValueException("Cannot migrate VM, destination host is not in correct state, has status: " + destinationHost.getState() + ", state: "
+                    + destinationHost.getResourceState());
+        }
+
+        if (vm.getType() != VirtualMachine.Type.User) {
+            // for System VMs check that the destination host is within the same
+            // cluster
+            HostVO srcHost = _hostDao.findById(srcHostId);
+            if (srcHost != null && srcHost.getClusterId() != null && destinationHost.getClusterId() != null) {
+                if (srcHost.getClusterId().longValue() != destinationHost.getClusterId().longValue()) {
+                    throw new InvalidParameterValueException("Cannot migrate the VM, destination host is not in the same cluster as current host of the VM");
+                }
+            }
+        }
+
+        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+
+        // call to core process
+        DataCenterVO dcVO = _dcDao.findById(destinationHost.getDataCenterId());
+        HostPodVO pod = _podDao.findById(destinationHost.getPodId());
+        Cluster cluster = _clusterDao.findById(destinationHost.getClusterId());
+        DeployDestination dest = new DeployDestination(dcVO, pod, cluster, destinationHost);
+
+        // check max guest vm limit for the destinationHost
+        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
+        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Host name: " + destinationHost.getName() + ", hostId: " + destinationHost.getId()
+                + " already has max Running VMs(count includes system VMs), cannot migrate to this host");
+            }
+            throw new VirtualMachineMigrationException("Destination host, hostId: " + destinationHost.getId()
+            + " already has max Running VMs(count includes system VMs), cannot migrate to this host");
+        }
+        //check if there are any ongoing volume snapshots on the volumes associated with the VM.
+        s_logger.debug("Checking if there are any ongoing snapshots volumes associated with VM with ID " + vmId);
+        if (checkStatusOfVolumeSnapshots(vmId, null)) {
+            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on volume(s) attached to this VM, VM Migration is not permitted, please try again later.");
+        }
+        s_logger.debug("Found no ongoing snapshots on volumes associated with the vm with id " + vmId);
+
+        UserVmVO uservm = _vmDao.findById(vmId);
+        if (uservm != null) {
+            collectVmDiskStatistics(uservm);
+            collectVmNetworkStatistics(uservm);
+        }
+        _itMgr.migrate(vm.getUuid(), srcHostId, dest);
+        VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+        if (vmInstance.getType().equals(VirtualMachine.Type.User)) {
+            return _vmDao.findById(vmId);
+        } else {
+            return vmInstance;
+        }
+    }
+
+    private boolean isOnSupportedHypevisorForMigration(VMInstanceVO vm) {
+        return (vm.getHypervisorType().equals(HypervisorType.XenServer) ||
+                vm.getHypervisorType().equals(HypervisorType.VMware) ||
+                vm.getHypervisorType().equals(HypervisorType.KVM) ||
+                vm.getHypervisorType().equals(HypervisorType.Ovm) ||
+                vm.getHypervisorType().equals(HypervisorType.Hyperv) ||
+                vm.getHypervisorType().equals(HypervisorType.LXC) ||
+                vm.getHypervisorType().equals(HypervisorType.Simulator) ||
+                vm.getHypervisorType().equals(HypervisorType.Ovm3));
+    }
+
+    private boolean checkIfHostIsDedicated(HostVO host) {
+        long hostId = host.getId();
+        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+        if (dedicatedHost != null || dedicatedClusterOfHost != null || dedicatedPodOfHost != null) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void checkIfHostOfVMIsInPrepareForMaintenanceState(Long hostId, Long vmId, String operation) {
+        HostVO host = _hostDao.findById(hostId);
+        if (host.getResourceState() != ResourceState.PrepareForMaintenance) {
+            return;
+        }
+
+        s_logger.debug("Host is in PrepareForMaintenance state - " + operation + " VM operation on the VM id: " + vmId + " is not allowed");
+        throw new InvalidParameterValueException(operation + " VM operation on the VM id: " + vmId + " is not allowed as host is preparing for maintenance mode");
+    }
+
+    private Long accountOfDedicatedHost(HostVO host) {
+        long hostId = host.getId();
+        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+        if (dedicatedHost != null) {
+            return dedicatedHost.getAccountId();
+        }
+        if (dedicatedClusterOfHost != null) {
+            return dedicatedClusterOfHost.getAccountId();
+        }
+        if (dedicatedPodOfHost != null) {
+            return dedicatedPodOfHost.getAccountId();
+        }
+        return null;
+    }
+
+    private Long domainOfDedicatedHost(HostVO host) {
+        long hostId = host.getId();
+        DedicatedResourceVO dedicatedHost = _dedicatedDao.findByHostId(hostId);
+        DedicatedResourceVO dedicatedClusterOfHost = _dedicatedDao.findByClusterId(host.getClusterId());
+        DedicatedResourceVO dedicatedPodOfHost = _dedicatedDao.findByPodId(host.getPodId());
+        if (dedicatedHost != null) {
+            return dedicatedHost.getDomainId();
+        }
+        if (dedicatedClusterOfHost != null) {
+            return dedicatedClusterOfHost.getDomainId();
+        }
+        if (dedicatedPodOfHost != null) {
+            return dedicatedPodOfHost.getDomainId();
+        }
+        return null;
+    }
+
+    public void checkHostsDedication(VMInstanceVO vm, long srcHostId, long destHostId) {
+        HostVO srcHost = _hostDao.findById(srcHostId);
+        HostVO destHost = _hostDao.findById(destHostId);
+        boolean srcExplDedicated = checkIfHostIsDedicated(srcHost);
+        boolean destExplDedicated = checkIfHostIsDedicated(destHost);
+        //if srcHost is explicitly dedicated and destination Host is not
+        if (srcExplDedicated && !destExplDedicated) {
+            //raise an alert
+            String msg = "VM is being migrated from a explicitly dedicated host " + srcHost.getName() + " to non-dedicated host " + destHost.getName();
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+        }
+        //if srcHost is non dedicated but destination Host is explicitly dedicated
+        if (!srcExplDedicated && destExplDedicated) {
+            //raise an alert
+            String msg = "VM is being migrated from a non dedicated host " + srcHost.getName() + " to a explicitly dedicated host " + destHost.getName();
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+        }
+
+        //if hosts are dedicated to different account/domains, raise an alert
+        if (srcExplDedicated && destExplDedicated) {
+            if (!((accountOfDedicatedHost(srcHost) == null) || (accountOfDedicatedHost(srcHost).equals(accountOfDedicatedHost(destHost))))) {
+                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host "
+                        + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost);
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            }
+            if (!((domainOfDedicatedHost(srcHost) == null) || (domainOfDedicatedHost(srcHost).equals(domainOfDedicatedHost(destHost))))) {
+                String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host "
+                        + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost);
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            }
+        }
+
+        // Checks for implicitly dedicated hosts
+        ServiceOfferingVO deployPlanner = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
+        if (deployPlanner.getDeploymentPlanner() != null && deployPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) {
+            //VM is deployed using implicit planner
+            long accountOfVm = vm.getAccountId();
+            String msg = "VM of account " + accountOfVm + " with implicit deployment planner being migrated to host " + destHost.getName();
+            //Get all vms on destination host
+            boolean emptyDestination = false;
+            List<VMInstanceVO> vmsOnDest = getVmsOnHost(destHostId);
+            if (vmsOnDest == null || vmsOnDest.isEmpty()) {
+                emptyDestination = true;
+            }
+
+            if (!emptyDestination) {
+                //Check if vm is deployed using strict implicit planner
+                if (!isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId())) {
+                    //Check if all vms on destination host are created using strict implicit mode
+                    if (!checkIfAllVmsCreatedInStrictMode(accountOfVm, vmsOnDest)) {
+                        msg = "VM of account " + accountOfVm + " with strict implicit deployment planner being migrated to host " + destHost.getName()
+                        + " not having all vms strict implicitly dedicated to account " + accountOfVm;
+                    }
+                } else {
+                    //If vm is deployed using preferred implicit planner, check if all vms on destination host must be
+                    //using implicit planner and must belong to same account
+                    for (VMInstanceVO vmsDest : vmsOnDest) {
+                        ServiceOfferingVO destPlanner = _offeringDao.findById(vm.getId(), vmsDest.getServiceOfferingId());
+                        if (!((destPlanner.getDeploymentPlanner() != null && destPlanner.getDeploymentPlanner().equals("ImplicitDedicationPlanner")) && vmsDest.getAccountId() == accountOfVm)) {
+                            msg = "VM of account " + accountOfVm + " with preffered implicit deployment planner being migrated to host " + destHost.getName()
+                            + " not having all vms implicitly dedicated to account " + accountOfVm;
+                        }
+                    }
+                }
+            }
+            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+            s_logger.warn(msg);
+
+        } else {
+            //VM is not deployed using implicit planner, check if it migrated between dedicated hosts
+            List<PlannerHostReservationVO> reservedHosts = _plannerHostReservationDao.listAllDedicatedHosts();
+            boolean srcImplDedicated = false;
+            boolean destImplDedicated = false;
+            String msg = null;
+            for (PlannerHostReservationVO reservedHost : reservedHosts) {
+                if (reservedHost.getHostId() == srcHostId) {
+                    srcImplDedicated = true;
+                }
+                if (reservedHost.getHostId() == destHostId) {
+                    destImplDedicated = true;
+                }
+            }
+            if (srcImplDedicated) {
+                if (destImplDedicated) {
+                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to another implicitly dedicated host " + destHost.getName();
+                } else {
+                    msg = "VM is being migrated from implicitly dedicated host " + srcHost.getName() + " to shared host " + destHost.getName();
+                }
+                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                s_logger.warn(msg);
+            } else {
+                if (destImplDedicated) {
+                    msg = "VM is being migrated from shared host " + srcHost.getName() + " to implicitly dedicated host " + destHost.getName();
+                    _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
+                    s_logger.warn(msg);
+                }
+            }
+        }
+    }
+
+    private List<VMInstanceVO> getVmsOnHost(long hostId) {
+        List<VMInstanceVO> vms =  _vmInstanceDao.listUpByHostId(hostId);
+        List<VMInstanceVO> vmsByLastHostId = _vmInstanceDao.listByLastHostId(hostId);
+        if (vmsByLastHostId.size() > 0) {
+            // check if any VMs are within skip.counting.hours, if yes we have to consider the host.
+            for (VMInstanceVO stoppedVM : vmsByLastHostId) {
+                long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - stoppedVM.getUpdateTime().getTime()) / 1000;
+                if (secondsSinceLastUpdate < capacityReleaseInterval) {
+                    vms.add(stoppedVM);
+                }
+            }
+        }
+
+        return vms;
+    }
+
+    private boolean isServiceOfferingUsingPlannerInPreferredMode(long serviceOfferingId) {
+        boolean preferred = false;
+        Map<String, String> details = serviceOfferingDetailsDao.listDetailsKeyPairs(serviceOfferingId);
+        if (details != null && !details.isEmpty()) {
+            String preferredAttribute = details.get("ImplicitDedicationMode");
+            if (preferredAttribute != null && preferredAttribute.equals("Preferred")) {
+                preferred = true;
+            }
+        }
+        return preferred;
+    }
+
+    private boolean checkIfAllVmsCreatedInStrictMode(Long accountId, List<VMInstanceVO> allVmsOnHost) {
+        boolean createdByImplicitStrict = true;
+        if (allVmsOnHost.isEmpty()) {
+            return false;
+        }
+        for (VMInstanceVO vm : allVmsOnHost) {
+            if (!isImplicitPlannerUsedByOffering(vm.getServiceOfferingId()) || vm.getAccountId() != accountId) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by a planner other" + " than implicit, or running vms of other account");
+                createdByImplicitStrict = false;
+                break;
+            } else if (isServiceOfferingUsingPlannerInPreferredMode(vm.getServiceOfferingId()) || vm.getAccountId() != accountId) {
+                s_logger.info("Host " + vm.getHostId() + " found to be running a vm created by an implicit planner" + " in preferred mode, or running vms of other account");
+                createdByImplicitStrict = false;
+                break;
+            }
+        }
+        return createdByImplicitStrict;
+    }
+
+    private boolean isImplicitPlannerUsedByOffering(long offeringId) {
+        boolean implicitPlannerUsed = false;
+        ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(offeringId);
+        if (offering == null) {
+            s_logger.error("Couldn't retrieve the offering by the given id : " + offeringId);
+        } else {
+            String plannerName = offering.getDeploymentPlanner();
+            if (plannerName != null) {
+                if (plannerName.equals("ImplicitDedicationPlanner")) {
+                    implicitPlannerUsed = true;
+                }
+            }
+        }
+
+        return implicitPlannerUsed;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MIGRATE, eventDescription = "migrating VM", async = true)
+    public VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, Map<String, String> volumeToPool) throws ResourceUnavailableException,
+    ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException {
+        // Access check - only root administrator can migrate VM.
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Caller is not a root admin, permission denied to migrate the VM");
+            }
+            throw new PermissionDeniedException("No permission to migrate VM, Only Root Admin can migrate a VM!");
+        }
+
+        VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find the vm by id " + vmId);
+        }
+
+        // OfflineVmwareMigration: this would be it ;) if multiple paths exist: unify
+        if (vm.getState() != State.Running) {
+            // OfflineVmwareMigration: and not vmware
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is not Running, unable to migrate the vm " + vm);
+            }
+            CloudRuntimeException ex = new CloudRuntimeException("VM is not Running, unable to migrate the vm with" + " specified id");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        if(serviceOfferingDetailsDao.findDetail(vm.getServiceOfferingId(), GPU.Keys.pciDevice.toString()) != null) {
+            throw new InvalidParameterValueException("Live Migration of GPU enabled VM is not supported");
+        }
+
+        // OfflineVmwareMigration: this condition is to complicated. (already a method somewhere)
+        if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
+                && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)
+                && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
+            throw new InvalidParameterValueException("Unsupported hypervisor type for vm migration, we support" + " XenServer/VMware/KVM only");
+        }
+
+        long srcHostId = vm.getHostId();
+        Host srcHost = _resourceMgr.getHost(srcHostId);
+
+        if(srcHost == null ){
+            throw new InvalidParameterValueException("Cannot migrate VM, there is not Host with id: " + srcHostId);
+        }
+
+        // Check if src and destination hosts are valid and migrating to same host
+        if (destinationHost.getId() == srcHostId) {
+            throw new InvalidParameterValueException("Cannot migrate VM, VM is already present on this host, please" + " specify valid destination host to migrate the VM");
+        }
+
+        // Check if the source and destination hosts are of the same type and support storage motion.
+        if (!srcHost.getHypervisorType().equals(destinationHost.getHypervisorType())) {
+            throw new CloudRuntimeException("The source and destination hosts are not of the same type and version. Source hypervisor type and version: " +
+                    srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " +
+                    destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
+        }
+
+        String srcHostVersion = srcHost.getHypervisorVersion();
+        String destinationHostVersion = destinationHost.getHypervisorVersion();
+
+        if (HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
+            if (srcHostVersion == null) {
+                srcHostVersion = "";
+            }
+
+            if (destinationHostVersion == null) {
+                destinationHostVersion = "";
+            }
+        }
+
+        if (!srcHostVersion.equals(destinationHostVersion)) {
+            throw new CloudRuntimeException("The source and destination hosts are not of the same type and version. Source hypervisor type and version: " +
+                    srcHost.getHypervisorType().toString() + " " + srcHost.getHypervisorVersion() + ", Destination hypervisor type and version: " +
+                    destinationHost.getHypervisorType().toString() + " " + destinationHost.getHypervisorVersion());
+        }
+
+        HypervisorCapabilitiesVO capabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(srcHost.getHypervisorType(), srcHost.getHypervisorVersion());
+
+        if (capabilities == null && HypervisorType.KVM.equals(srcHost.getHypervisorType())) {
+            List<HypervisorCapabilitiesVO> lstHypervisorCapabilities = _hypervisorCapabilitiesDao.listAllByHypervisorType(HypervisorType.KVM);
+
+            if (lstHypervisorCapabilities != null) {
+                for (HypervisorCapabilitiesVO hypervisorCapabilities : lstHypervisorCapabilities) {
+                    if (hypervisorCapabilities.isStorageMotionSupported()) {
+                        capabilities = hypervisorCapabilities;
+
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (!capabilities.isStorageMotionSupported()) {
+            throw new CloudRuntimeException("Migration with storage isn't supported on hypervisor " + srcHost.getHypervisorType() + " of version " + srcHost.getHypervisorVersion());
+        }
+
+        // Check if destination host is up.
+        if (destinationHost.getState() != com.cloud.host.Status.Up || destinationHost.getResourceState() != ResourceState.Enabled) {
+            throw new CloudRuntimeException("Cannot migrate VM, destination host is not in correct state, has " + "status: " + destinationHost.getState() + ", state: "
+                    + destinationHost.getResourceState());
+        }
+
+        // Check that Vm does not have VM Snapshots
+        if (_vmSnapshotDao.findByVm(vmId).size() > 0) {
+            throw new InvalidParameterValueException("VM with VM Snapshots cannot be migrated with storage, please remove all VM snapshots");
+        }
+
+        List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
+        Map<Long, Long> volToPoolObjectMap = new HashMap<Long, Long>();
+        if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
+            if (volumeToPool.isEmpty()) {
+                // If the destination host is in the same cluster and volumes do not have to be migrated across pools
+                // then fail the call. migrateVirtualMachine api should have been used.
+                throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destinationHost
+                        + " doesn't involve migrating the volumes.");
+            }
+        }
+
+        if (!volumeToPool.isEmpty()) {
+            // Check if all the volumes and pools passed as parameters are valid.
+            for (Map.Entry<String, String> entry : volumeToPool.entrySet()) {
+                VolumeVO volume = _volsDao.findByUuid(entry.getKey());
+                StoragePoolVO pool = _storagePoolDao.findByUuid(entry.getValue());
+                if (volume == null) {
+                    throw new InvalidParameterValueException("There is no volume present with the given id " + entry.getKey());
+                } else if (pool == null) {
+                    throw new InvalidParameterValueException("There is no storage pool present with the given id " + entry.getValue());
+                } else if (pool.isInMaintenance()) {
+                    throw new InvalidParameterValueException("Cannot migrate volume " + volume + "to the destination storage pool " + pool.getName() +
+                            " as the storage pool is in maintenance mode.");
+                } else {
+                    // Verify the volume given belongs to the vm.
+                    if (!vmVolumes.contains(volume)) {
+                        throw new InvalidParameterValueException("There volume " + volume + " doesn't belong to " + "the virtual machine " + vm + " that has to be migrated");
+                    }
+                    volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId()));
+                }
+            }
+        }
+
+        // Check if all the volumes are in the correct state.
+        for (VolumeVO volume : vmVolumes) {
+            if (volume.getState() != Volume.State.Ready) {
+                throw new CloudRuntimeException("Volume " + volume + " of the VM is not in Ready state. Cannot " + "migrate the vm with its volumes.");
+            }
+        }
+
+        // Check max guest vm limit for the destinationHost.
+        HostVO destinationHostVO = _hostDao.findById(destinationHost.getId());
+        if (_capacityMgr.checkIfHostReachMaxGuestLimit(destinationHostVO)) {
+            throw new VirtualMachineMigrationException("Host name: " + destinationHost.getName() + ", hostId: " + destinationHost.getId()
+            + " already has max running vms (count includes system VMs). Cannot" + " migrate to this host");
+        }
+
+        checkHostsDedication(vm, srcHostId, destinationHost.getId());
+
+        _itMgr.migrateWithStorage(vm.getUuid(), srcHostId, destinationHost.getId(), volToPoolObjectMap);
+        return _vmDao.findById(vm.getId());
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false)
+    public UserVm moveVMToUser(final AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        // VERIFICATIONS and VALIDATIONS
+
+        // VV 1: verify the two users
+        Account caller = CallContext.current().getCallingAccount();
+        if (!_accountMgr.isRootAdmin(caller.getId())
+                && !_accountMgr.isDomainAdmin(caller.getId())) { // only
+            // root
+            // admin
+            // can
+            // assign
+            // VMs
+            throw new InvalidParameterValueException("Only domain admins are allowed to assign VMs and not " + caller.getType());
+        }
+
+        // get and check the valid VM
+        final UserVmVO vm = _vmDao.findById(cmd.getVmId());
+        if (vm == null) {
+            throw new InvalidParameterValueException("There is no vm by that id " + cmd.getVmId());
+        } else if (vm.getState() == State.Running) { // VV 3: check if vm is
+            // running
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("VM is Running, unable to move the vm " + vm);
+            }
+            InvalidParameterValueException ex = new InvalidParameterValueException("VM is Running, unable to move the vm with specified vmId");
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+
+        final Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId());
+        if (oldAccount == null) {
+            throw new InvalidParameterValueException("Invalid account for VM " + vm.getAccountId() + " in domain.");
+        }
+        final Account newAccount = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
+        if (newAccount == null) {
+            throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountName() + " in domain " + cmd.getDomainId());
+        }
+
+        if (newAccount.getState() == Account.State.disabled) {
+            throw new InvalidParameterValueException("The new account owner " + cmd.getAccountName() + " is disabled.");
+        }
+
+        //check caller has access to both the old and new account
+        _accountMgr.checkAccess(caller, null, true, oldAccount);
+        _accountMgr.checkAccess(caller, null, true, newAccount);
+
+        // make sure the accounts are not same
+        if (oldAccount.getAccountId() == newAccount.getAccountId()) {
+            throw new InvalidParameterValueException("The new account is the same as the old account. Account id =" + oldAccount.getAccountId());
+        }
+
+        // don't allow to move the vm if there are existing PF/LB/Static Nat
+        // rules, or vm is assigned to static Nat ip
+        List<PortForwardingRuleVO> pfrules = _portForwardingDao.listByVm(cmd.getVmId());
+        if (pfrules != null && pfrules.size() > 0) {
+            throw new InvalidParameterValueException("Remove the Port forwarding rules for this VM before assigning to another user.");
+        }
+        List<FirewallRuleVO> snrules = _rulesDao.listStaticNatByVmId(vm.getId());
+        if (snrules != null && snrules.size() > 0) {
+            throw new InvalidParameterValueException("Remove the StaticNat rules for this VM before assigning to another user.");
+        }
+        List<LoadBalancerVMMapVO> maps = _loadBalancerVMMapDao.listByInstanceId(vm.getId());
+        if (maps != null && maps.size() > 0) {
+            throw new InvalidParameterValueException("Remove the load balancing rules for this VM before assigning to another user.");
+        }
+        // check for one on one nat
+        List<IPAddressVO> ips = _ipAddressDao.findAllByAssociatedVmId(cmd.getVmId());
+        for (IPAddressVO ip : ips) {
+            if (ip.isOneToOneNat()) {
+                throw new InvalidParameterValueException("Remove the one to one nat rule for this VM for ip " + ip.toString());
+            }
+        }
+
+        final List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
+
+        for (VolumeVO volume : volumes) {
+            List<SnapshotVO> snapshots = _snapshotDao.listByStatusNotIn(volume.getId(), Snapshot.State.Destroyed,Snapshot.State.Error);
+            if (snapshots != null && snapshots.size() > 0) {
+                throw new InvalidParameterValueException(
+                        "Snapshots exists for volume: "+ volume.getName()+ ", Detach volume or remove snapshots for volume before assigning VM to another user.");
+            }
+        }
+
+        DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
+
+        // Get serviceOffering and Volumes for Virtual Machine
+        final ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId());
+
+        //Remove vm from instance group
+        removeInstanceFromInstanceGroup(cmd.getVmId());
+
+        // VV 2: check if account/domain is with in resource limits to create a new vm
+        resourceLimitCheck(newAccount, vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
+
+        // VV 3: check if volumes and primary storage space are with in resource limits
+        _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume, _volsDao.findByInstance(cmd.getVmId()).size());
+        Long totalVolumesSize = (long)0;
+        for (VolumeVO volume : volumes) {
+            totalVolumesSize += volume.getSize();
+        }
+        _resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
+
+        // VV 4: Check if new owner can use the vm template
+        VirtualMachineTemplate template = _templateDao.findById(vm.getTemplateId());
+        if (!template.isPublicTemplate()) {
+            Account templateOwner = _accountMgr.getAccount(template.getAccountId());
+            _accountMgr.checkAccess(newAccount, null, true, templateOwner);
+        }
+
+        // VV 5: check the new account can create vm in the domain
+        DomainVO domain = _domainDao.findById(cmd.getDomainId());
+        _accountMgr.checkAccess(newAccount, domain);
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                //generate destroy vm event for usage
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(),
+                        vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(),
+                        vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
+                // update resource counts for old account
+                resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
+
+                // OWNERSHIP STEP 1: update the vm owner
+                vm.setAccountId(newAccount.getAccountId());
+                vm.setDomainId(cmd.getDomainId());
+                _vmDao.persist(vm);
+
+                // OS 2: update volume
+                for (VolumeVO volume : volumes) {
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
+                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
+                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
+                    volume.setAccountId(newAccount.getAccountId());
+                    volume.setDomainId(newAccount.getDomainId());
+                    _volsDao.persist(volume);
+                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
+                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                            volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
+                            volume.getUuid(), volume.isDisplayVolume());
+                }
+
+                //update resource count of new account
+                resourceCountIncrement(newAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
+
+                //generate usage events to account for this change
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                        vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                        VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
+            }
+        });
+
+        VirtualMachine vmoi = _itMgr.findById(vm.getId());
+        VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi);
+
+        // OS 3: update the network
+        List<Long> networkIdList = cmd.getNetworkIds();
+        List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
+
+        if (zone.getNetworkType() == NetworkType.Basic) {
+            if (networkIdList != null && !networkIdList.isEmpty()) {
+                throw new InvalidParameterValueException("Can't move vm with network Ids; this is a basic zone VM");
+            }
+            // cleanup the old security groups
+            _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
+            // cleanup the network for the oldOwner
+            _networkMgr.cleanupNics(vmOldProfile);
+            _networkMgr.expungeNics(vmOldProfile);
+            // security groups will be recreated for the new account, when the
+            // VM is started
+            List<NetworkVO> networkList = new ArrayList<NetworkVO>();
+
+            // Get default guest network in Basic zone
+            Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
+
+            if (defaultNetwork == null) {
+                throw new InvalidParameterValueException("Unable to find a default network to start a vm");
+            } else {
+                networkList.add(_networkDao.findById(defaultNetwork.getId()));
+            }
+
+            boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
+
+            if (securityGroupIdList != null && isVmWare) {
+                throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
+            } else if (!isVmWare && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
+                if (securityGroupIdList == null) {
+                    securityGroupIdList = new ArrayList<Long>();
+                }
+                SecurityGroup defaultGroup = _securityGroupMgr.getDefaultSecurityGroup(newAccount.getId());
+                if (defaultGroup != null) {
+                    // check if security group id list already contains Default
+                    // security group, and if not - add it
+                    boolean defaultGroupPresent = false;
+                    for (Long securityGroupId : securityGroupIdList) {
+                        if (securityGroupId.longValue() == defaultGroup.getId()) {
+                            defaultGroupPresent = true;
+                            break;
+                        }
+                    }
+
+                    if (!defaultGroupPresent) {
+                        securityGroupIdList.add(defaultGroup.getId());
+                    }
+
+                } else {
+                    // create default security group for the account
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Couldn't find default security group for the account " + newAccount + " so creating a new one");
+                    }
+                    defaultGroup = _securityGroupMgr.createSecurityGroup(SecurityGroupManager.DEFAULT_GROUP_NAME, SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
+                            newAccount.getDomainId(), newAccount.getId(), newAccount.getAccountName());
+                    securityGroupIdList.add(defaultGroup.getId());
+                }
+            }
+
+            LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
+            NicProfile profile = new NicProfile();
+            profile.setDefaultNic(true);
+            networks.put(networkList.get(0), new ArrayList<NicProfile>(Arrays.asList(profile)));
+
+            VirtualMachine vmi = _itMgr.findById(vm.getId());
+            VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
+            _networkMgr.allocate(vmProfile, networks, null);
+
+            _securityGroupMgr.addInstanceToGroups(vm.getId(), securityGroupIdList);
+
+            s_logger.debug("AssignVM: Basic zone, adding security groups no " + securityGroupIdList.size() + " to " + vm.getInstanceName());
+        } else {
+            if (zone.isSecurityGroupEnabled())  { // advanced zone with security groups
+                // cleanup the old security groups
+                _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
+
+                Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
+                String requestedIPv4ForDefaultNic = null;
+                String requestedIPv6ForDefaultNic = null;
+                // if networkIdList is null and the first network of vm is shared network, then keep it if possible
+                if (networkIdList == null || networkIdList.isEmpty()) {
+                    NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
+                    if (defaultNicOld != null) {
+                        NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
+                        if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
+                            try {
+                                _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
+                                applicableNetworks.add(defaultNetworkOld);
+                                requestedIPv4ForDefaultNic = defaultNicOld.getIPv4Address();
+                                requestedIPv6ForDefaultNic = defaultNicOld.getIPv6Address();
+                                s_logger.debug("AssignVM: use old shared network " + defaultNetworkOld.getName() + " with old ip " + requestedIPv4ForDefaultNic + " on default nic of vm:" + vm.getInstanceName());
+                            } catch (PermissionDeniedException e) {
+                                s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
+                            }
+                        }
+                    }
+                }
+                // cleanup the network for the oldOwner
+                _networkMgr.cleanupNics(vmOldProfile);
+                _networkMgr.expungeNics(vmOldProfile);
+
+                if (networkIdList != null && !networkIdList.isEmpty()) {
+                    // add any additional networks
+                    for (Long networkId : networkIdList) {
+                        NetworkVO network = _networkDao.findById(networkId);
+                        if (network == null) {
+                            InvalidParameterValueException ex = new InvalidParameterValueException(
+                                    "Unable to find specified network id");
+                            ex.addProxyObject(networkId.toString(), "networkId");
+                            throw ex;
+                        }
+
+                        _networkModel.checkNetworkPermissions(newAccount, network);
+
+                        // don't allow to use system networks
+                        NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+                        if (networkOffering.isSystemOnly()) {
+                            InvalidParameterValueException ex = new InvalidParameterValueException(
+                                    "Specified Network id is system only and can't be used for vm deployment");
+                            ex.addProxyObject(network.getUuid(), "networkId");
+                            throw ex;
+                        }
+                        applicableNetworks.add(network);
+                    }
+                }
+
+                // add the new nics
+                LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
+                int toggle = 0;
+                NetworkVO defaultNetwork = null;
+                for (NetworkVO appNet : applicableNetworks) {
+                    NicProfile defaultNic = new NicProfile();
+                    if (toggle == 0) {
+                        defaultNic.setDefaultNic(true);
+                        defaultNic.setRequestedIPv4(requestedIPv4ForDefaultNic);
+                        defaultNic.setRequestedIPv6(requestedIPv6ForDefaultNic);
+                        defaultNetwork = appNet;
+                        toggle++;
+                    }
+                    networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+
+                }
+
+                boolean isVmWare = (template.getHypervisorType() == HypervisorType.VMware);
+                if (securityGroupIdList != null && isVmWare) {
+                    throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
+                } else if (!isVmWare && (defaultNetwork == null || _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork)) && _networkModel.canAddDefaultSecurityGroup()) {
+                    if (securityGroupIdList == null) {
+                        securityGroupIdList = new ArrayList<Long>();
+                    }
+                    SecurityGroup defaultGroup = _securityGroupMgr
+                            .getDefaultSecurityGroup(newAccount.getId());
+                    if (defaultGroup != null) {
+                        // check if security group id list already contains Default
+                        // security group, and if not - add it
+                        boolean defaultGroupPresent = false;
+                        for (Long securityGroupId : securityGroupIdList) {
+                            if (securityGroupId.longValue() == defaultGroup.getId()) {
+                                defaultGroupPresent = true;
+                                break;
+                            }
+                        }
+
+                        if (!defaultGroupPresent) {
+                            securityGroupIdList.add(defaultGroup.getId());
+                        }
+
+                    } else {
+                        // create default security group for the account
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("Couldn't find default security group for the account "
+                                    + newAccount + " so creating a new one");
+                        }
+                        defaultGroup = _securityGroupMgr.createSecurityGroup(
+                                SecurityGroupManager.DEFAULT_GROUP_NAME,
+                                SecurityGroupManager.DEFAULT_GROUP_DESCRIPTION,
+                                newAccount.getDomainId(), newAccount.getId(),
+                                newAccount.getAccountName());
+                        securityGroupIdList.add(defaultGroup.getId());
+                    }
+                }
+
+                VirtualMachine vmi = _itMgr.findById(vm.getId());
+                VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
+
+                if (applicableNetworks.isEmpty()) {
+                    throw new InvalidParameterValueException("No network is specified, please specify one when you move the vm. For now, please add a network to VM on NICs tab.");
+                } else {
+                    _networkMgr.allocate(vmProfile, networks, null);
+                }
+
+                _securityGroupMgr.addInstanceToGroups(vm.getId(),
+                        securityGroupIdList);
+                s_logger.debug("AssignVM: Advanced zone, adding security groups no "
+                        + securityGroupIdList.size() + " to "
+                        + vm.getInstanceName());
+
+            } else {
+                if (securityGroupIdList != null && !securityGroupIdList.isEmpty()) {
+                    throw new InvalidParameterValueException("Can't move vm with security groups; security group feature is not enabled in this zone");
+                }
+                Set<NetworkVO> applicableNetworks = new HashSet<NetworkVO>();
+                // if networkIdList is null and the first network of vm is shared network, then keep it if possible
+                if (networkIdList == null || networkIdList.isEmpty()) {
+                    NicVO defaultNicOld = _nicDao.findDefaultNicForVM(vm.getId());
+                    if (defaultNicOld != null) {
+                        NetworkVO defaultNetworkOld = _networkDao.findById(defaultNicOld.getNetworkId());
+                        if (defaultNetworkOld != null && defaultNetworkOld.getGuestType() == Network.GuestType.Shared && defaultNetworkOld.getAclType() == ACLType.Domain) {
+                            try {
+                                _networkModel.checkNetworkPermissions(newAccount, defaultNetworkOld);
+                                applicableNetworks.add(defaultNetworkOld);
+                            } catch (PermissionDeniedException e) {
+                                s_logger.debug("AssignVM: the shared network on old default nic can not be applied to new account");
+                            }
+                        }
+                    }
+                }
+
+                // cleanup the network for the oldOwner
+                _networkMgr.cleanupNics(vmOldProfile);
+                _networkMgr.expungeNics(vmOldProfile);
+
+                if (networkIdList != null && !networkIdList.isEmpty()) {
+                    // add any additional networks
+                    for (Long networkId : networkIdList) {
+                        NetworkVO network = _networkDao.findById(networkId);
+                        if (network == null) {
+                            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id");
+                            ex.addProxyObject(networkId.toString(), "networkId");
+                            throw ex;
+                        }
+
+                        _networkModel.checkNetworkPermissions(newAccount, network);
+
+                        // don't allow to use system networks
+                        NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
+                        if (networkOffering.isSystemOnly()) {
+                            InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment");
+                            ex.addProxyObject(network.getUuid(), "networkId");
+                            throw ex;
+                        }
+                        applicableNetworks.add(network);
+                    }
+                } else if (applicableNetworks.isEmpty()) {
+                    NetworkVO defaultNetwork = null;
+                    List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+                    if (requiredOfferings.size() < 1) {
+                        throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
+                                + " to automatically create the network as a part of vm creation");
+                    }
+                    if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
+                        // get Virtual networks
+                        List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated);
+                        if (virtualNetworks.isEmpty()) {
+                            long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0)
+                                    .getTrafficType());
+                            // Validate physical network
+                            PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+                            if (physicalNetwork == null) {
+                                throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+                                        + requiredOfferings.get(0).getTags());
+                            }
+                            s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId()
+                                    + " as a part of deployVM process");
+                            Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
+                                    newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
+                                    null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
+                                    null, null, true, null, null);
+                            // if the network offering has persistent set to true, implement the network
+                            if (requiredOfferings.get(0).isPersistent()) {
+                                DeployDestination dest = new DeployDestination(zone, null, null, null);
+                                UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
+                                Journal journal = new Journal.LogJournal("Implementing " + newNetwork, s_logger);
+                                ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
+                                s_logger.debug("Implementing the network for account" + newNetwork + " as a part of" + " network provision for persistent networks");
+                                try {
+                                    Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(newNetwork.getId(), dest, context);
+                                    if (implementedNetwork == null || implementedNetwork.first() == null) {
+                                        s_logger.warn("Failed to implement the network " + newNetwork);
+                                    }
+                                    newNetwork = implementedNetwork.second();
+                                } catch (Exception ex) {
+                                    s_logger.warn("Failed to implement network " + newNetwork + " elements and"
+                                            + " resources as a part of network provision for persistent network due to ", ex);
+                                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network"
+                                            + " (with specified id) elements and resources as a part of network provision");
+                                    e.addProxyObject(newNetwork.getUuid(), "networkId");
+                                    throw e;
+                                }
+                            }
+                            defaultNetwork = _networkDao.findById(newNetwork.getId());
+                        } else if (virtualNetworks.size() > 1) {
+                            throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + "for account " + newAccount
+                                    + "; please specify networkIds");
+                        } else {
+                            defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
+                        }
+                    } else {
+                        throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
+                    }
+
+                    applicableNetworks.add(defaultNetwork);
+                }
+
+                // add the new nics
+                LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>();
+                int toggle = 0;
+                for (NetworkVO appNet : applicableNetworks) {
+                    NicProfile defaultNic = new NicProfile();
+                    if (toggle == 0) {
+                        defaultNic.setDefaultNic(true);
+                        toggle++;
+                    }
+                    networks.put(appNet, new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+                }
+                VirtualMachine vmi = _itMgr.findById(vm.getId());
+                VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmi);
+                _networkMgr.allocate(vmProfile, networks, null);
+                s_logger.debug("AssignVM: Advance virtual, adding networks no " + networks.size() + " to " + vm.getInstanceName());
+            } // END IF NON SEC GRP ENABLED
+        } // END IF ADVANCED
+        s_logger.info("AssignVM: vm " + vm.getInstanceName() + " now belongs to account " + newAccount.getAccountName());
+        return vm;
+    }
+
+    @Override
+    public UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException {
+        // Input validation
+        Account caller = CallContext.current().getCallingAccount();
+
+        long vmId = cmd.getVmId();
+        Long newTemplateId = cmd.getTemplateId();
+
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find VM with ID " + vmId);
+            ex.addProxyObject(String.valueOf(vmId), "vmId");
+            throw ex;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, vm);
+
+        //check if there are any active snapshots on volumes associated with the VM
+        s_logger.debug("Checking if there are any ongoing snapshots on the ROOT volumes associated with VM with ID " + vmId);
+        if (checkStatusOfVolumeSnapshots(vmId, Volume.Type.ROOT)) {
+            throw new CloudRuntimeException("There is/are unbacked up snapshot(s) on ROOT volume, Re-install VM is not permitted, please try again later.");
+        }
+        s_logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm with id " + vmId);
+        return restoreVMInternal(caller, vm, newTemplateId);
+    }
+
+    public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
+
+        Long userId = caller.getId();
+        Account owner = _accountDao.findById(vm.getAccountId());
+        _userDao.findById(userId);
+        long vmId = vm.getId();
+        boolean needRestart = false;
+
+        // Input validation
+        if (owner == null) {
+            throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
+        }
+
+        if (owner.getState() == Account.State.disabled) {
+            throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
+        }
+
+        if (vm.getState() != VirtualMachine.State.Running && vm.getState() != VirtualMachine.State.Stopped) {
+            throw new CloudRuntimeException("Vm " + vm.getUuid() + " currently in " + vm.getState() + " state, restore vm can only execute when VM in Running or Stopped");
+        }
+
+        if (vm.getState() == VirtualMachine.State.Running) {
+            needRestart = true;
+        }
+
+        List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
+        if (rootVols.isEmpty()) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid());
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+        if (rootVols.size() > 1) {
+            InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid());
+            ex.addProxyObject(vm.getUuid(), "vmId");
+            throw ex;
+        }
+        VolumeVO root = rootVols.get(0);
+        if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
+            Long templateId = root.getTemplateId();
+            boolean isISO = false;
+            if (templateId == null) {
+                // Assuming that for a vm deployed using ISO, template ID is set to NULL
+                isISO = true;
+                templateId = vm.getIsoId();
+            }
+
+            // If target VM has associated VM snapshots then don't allow restore of VM
+            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+            if (vmSnapshots.size() > 0) {
+                throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
+            }
+
+            VMTemplateVO template = null;
+            //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
+            if (newTemplateId != null) {
+                template = _templateDao.findById(newTemplateId);
+                _accountMgr.checkAccess(caller, null, true, template);
+                if (isISO) {
+                    if (!template.getFormat().equals(ImageFormat.ISO)) {
+                        throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
+                    }
+                } else {
+                    if (template.getFormat().equals(ImageFormat.ISO)) {
+                        throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
+                    }
+                }
+            } else {
+                if (isISO && templateId == null) {
+                    throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
+                }
+                template = _templateDao.findById(templateId);
+                if (template == null) {
+                    InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    ex.addProxyObject(root.getUuid(), "volumeId");
+                    throw ex;
+                }
+            }
+
+            checkRestoreVmFromTemplate(vm, template);
+
+            if (needRestart) {
+                try {
+                    _itMgr.stop(vm.getUuid());
+                } catch (ResourceUnavailableException e) {
+                    s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
+                    CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    throw ex;
+                }
+            }
+
+            /* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
+            Volume newVol = null;
+            if (newTemplateId != null) {
+                if (isISO) {
+                    newVol = volumeMgr.allocateDuplicateVolume(root, null);
+                    vm.setIsoId(newTemplateId);
+                    vm.setGuestOSId(template.getGuestOSId());
+                    vm.setTemplateId(newTemplateId);
+                    _vmDao.update(vmId, vm);
+                } else {
+                    newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
+                    vm.setGuestOSId(template.getGuestOSId());
+                    vm.setTemplateId(newTemplateId);
+                    _vmDao.update(vmId, vm);
+                }
+            } else {
+                newVol = volumeMgr.allocateDuplicateVolume(root, null);
+            }
+
+            // 1. Save usage event and update resource count for user vm volumes
+            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
+            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
+            // 2. Create Usage event for the newly created volume
+            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
+            _usageEventDao.persist(usageEvent);
+
+            handleManagedStorage(vm, root);
+
+            _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
+
+            // Detach, destroy and create the usage event for the old root volume.
+            _volsDao.detachVolume(root.getId());
+            volumeMgr.destroyVolume(root);
+
+            // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
+            if (vm.getHypervisorType() == HypervisorType.VMware) {
+                VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
+                if (volumeInStorage != null) {
+                    s_logger.info("Expunging volume " + root.getId() + " from primary data store");
+                    AsyncCallFuture<VolumeApiResult> future = _volService.expungeVolumeAsync(volFactory.getVolume(root.getId()));
+                    try {
+                        future.get();
+                    } catch (Exception e) {
+                        s_logger.debug("Failed to expunge volume:" + root.getId(), e);
+                    }
+                }
+            }
+
+            Map<VirtualMachineProfile.Param, Object> params = null;
+            String password = null;
+
+            if (template.isEnablePassword()) {
+                password = _mgr.generateRandomPassword();
+                boolean result = resetVMPasswordInternal(vmId, password);
+                if (!result) {
+                    throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
+                }
+            }
+
+            if (needRestart) {
+                try {
+                    if (vm.getDetail("password") != null) {
+                        params = new HashMap<VirtualMachineProfile.Param, Object>();
+                        params.put(VirtualMachineProfile.Param.VmPassword, password);
+                    }
+                    _itMgr.start(vm.getUuid(), params);
+                    vm = _vmDao.findById(vmId);
+                    if (template.isEnablePassword()) {
+                        // this value is not being sent to the backend; need only for api
+                        // display purposes
+                        vm.setPassword(password);
+                        if (vm.isUpdateParameters()) {
+                            vm.setUpdateParameters(false);
+                            _vmDao.loadDetails(vm);
+                            if (vm.getDetail("password") != null) {
+                                userVmDetailsDao.removeDetail(vm.getId(), "password");
+                            }
+                            _vmDao.update(vm.getId(), vm);
+                        }
+                    }
+                } catch (Exception e) {
+                    s_logger.debug("Unable to start VM " + vm.getUuid(), e);
+                    CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    throw ex;
+                }
+            }
+        }
+
+        s_logger.debug("Restore VM " + vmId + " done successfully");
+        return vm;
+
+    }
+
+    /**
+     * Perform basic checkings to make sure restore is possible. If not, #InvalidParameterValueException is thrown.
+     *
+     * @param vm vm
+     * @param template template
+     * @throws InvalidParameterValueException if restore is not possible
+     */
+    private void checkRestoreVmFromTemplate(UserVmVO vm, VMTemplateVO template) {
+        TemplateDataStoreVO tmplStore;
+        if (!template.isDirectDownload()) {
+            tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
+            if (tmplStore == null) {
+                throw new InvalidParameterValueException("Cannot restore the vm as the template " + template.getUuid() + " isn't available in the zone");
+            }
+        } else {
+            tmplStore = _templateStoreDao.findByTemplate(template.getId(), DataStoreRole.Image);
+            if (tmplStore == null || (tmplStore != null && !tmplStore.getDownloadState().equals(VMTemplateStorageResourceAssoc.Status.BYPASSED))) {
+                throw new InvalidParameterValueException("Cannot restore the vm as the bypassed template " + template.getUuid() + " isn't available in the zone");
+            }
+        }
+    }
+
+    private void handleManagedStorage(UserVmVO vm, VolumeVO root) {
+        if (Volume.State.Allocated.equals(root.getState())) {
+            return;
+        }
+
+        StoragePoolVO storagePool = _storagePoolDao.findById(root.getPoolId());
+
+        if (storagePool != null && storagePool.isManaged()) {
+            Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
+
+            if (hostId != null) {
+                VolumeInfo volumeInfo = volFactory.getVolume(root.getId());
+                Host host = _hostDao.findById(hostId);
+
+                final Command cmd;
+
+                if (host.getHypervisorType() == HypervisorType.XenServer) {
+                    DiskTO disk = new DiskTO(volumeInfo.getTO(), root.getDeviceId(), root.getPath(), root.getVolumeType());
+
+                    // it's OK in this case to send a detach command to the host for a root volume as this
+                    // will simply lead to the SR that supports the root volume being removed
+                    cmd = new DettachCommand(disk, vm.getInstanceName());
+
+                    DettachCommand detachCommand = (DettachCommand)cmd;
+
+                    detachCommand.setManaged(true);
+
+                    detachCommand.setStorageHost(storagePool.getHostAddress());
+                    detachCommand.setStoragePort(storagePool.getPort());
+
+                    detachCommand.set_iScsiName(root.get_iScsiName());
+                }
+                else if (host.getHypervisorType() == HypervisorType.VMware) {
+                    PrimaryDataStore primaryDataStore = (PrimaryDataStore)volumeInfo.getDataStore();
+                    Map<String, String> details = primaryDataStore.getDetails();
+
+                    if (details == null) {
+                        details = new HashMap<>();
+
+                        primaryDataStore.setDetails(details);
+                    }
+
+                    details.put(DiskTO.MANAGED, Boolean.TRUE.toString());
+
+                    cmd = new DeleteCommand(volumeInfo.getTO());
+                }
+                else if (host.getHypervisorType() == HypervisorType.KVM) {
+                    cmd = null;
+                }
+                else {
+                    throw new CloudRuntimeException("This hypervisor type is not supported on managed storage for this command.");
+                }
+
+                if (cmd != null) {
+                    Commands cmds = new Commands(Command.OnError.Stop);
+
+                    cmds.addCommand(cmd);
+
+                    try {
+                        _agentMgr.send(hostId, cmds);
+                    } catch (Exception ex) {
+                        throw new CloudRuntimeException(ex.getMessage());
+                    }
+
+                    if (!cmds.isSuccessful()) {
+                        for (Answer answer : cmds.getAnswers()) {
+                            if (!answer.getResult()) {
+                                s_logger.warn("Failed to reset vm due to: " + answer.getDetails());
+
+                                throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails());
+                            }
+                        }
+                    }
+                }
+
+                // root.getPoolId() should be null if the VM we are detaching the disk from has never been started before
+                DataStore dataStore = root.getPoolId() != null ? _dataStoreMgr.getDataStore(root.getPoolId(), DataStoreRole.Primary) : null;
+
+                volumeMgr.revokeAccess(volFactory.getVolume(root.getId()), host, dataStore);
+
+                if (dataStore != null) {
+                    handleTargetsForVMware(host.getId(), storagePool.getHostAddress(), storagePool.getPort(), root.get_iScsiName());
+                }
+            }
+        }
+    }
+
+    private void handleTargetsForVMware(long hostId, String storageAddress, int storagePort, String iScsiName) {
+        HostVO host = _hostDao.findById(hostId);
+
+        if (host.getHypervisorType() == HypervisorType.VMware) {
+            ModifyTargetsCommand cmd = new ModifyTargetsCommand();
+
+            List<Map<String, String>> targets = new ArrayList<>();
+
+            Map<String, String> target = new HashMap<>();
+
+            target.put(ModifyTargetsCommand.STORAGE_HOST, storageAddress);
+            target.put(ModifyTargetsCommand.STORAGE_PORT, String.valueOf(storagePort));
+            target.put(ModifyTargetsCommand.IQN, iScsiName);
+
+            targets.add(target);
+
+            cmd.setTargets(targets);
+            cmd.setApplyToAllHostsInCluster(true);
+            cmd.setAdd(false);
+            cmd.setTargetTypeToRemove(ModifyTargetsCommand.TargetTypeToRemove.DYNAMIC);
+
+            sendModifyTargetsCommand(cmd, hostId);
+        }
+    }
+
+    private void sendModifyTargetsCommand(ModifyTargetsCommand cmd, long hostId) {
+        Answer answer = _agentMgr.easySend(hostId, cmd);
+
+        if (answer == null) {
+            String msg = "Unable to get an answer to the modify targets command";
+
+            s_logger.warn(msg);
+        }
+        else if (!answer.getResult()) {
+            String msg = "Unable to modify target on the following host: " + hostId;
+
+            s_logger.warn(msg);
+        }
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile profile) {
+        UserVmVO vm = _vmDao.findById(profile.getId());
+        if (vm != null && vm.getState() == State.Stopping) {
+            collectVmDiskStatistics(vm);
+            collectVmNetworkStatistics(vm);
+        }
+    }
+
+    private void encryptAndStorePassword(UserVmVO vm, String password) {
+        String sshPublicKey = vm.getDetail("SSH.PublicKey");
+        if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
+            if (!sshPublicKey.startsWith("ssh-rsa")) {
+                s_logger.warn("Only RSA public keys can be used to encrypt a vm password.");
+                return;
+            }
+            String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
+            if (encryptedPasswd == null) {
+                throw new CloudRuntimeException("Error encrypting password");
+            }
+
+            vm.setDetail("Encrypted.Password", encryptedPasswd);
+            _vmDao.saveDetails(vm);
+        }
+    }
+
+    @Override
+    public void persistDeviceBusInfo(UserVmVO vm, String rootDiskController) {
+        String existingVmRootDiskController = vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER);
+        if (StringUtils.isEmpty(existingVmRootDiskController) && !StringUtils.isEmpty(rootDiskController)) {
+            vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskController);
+            _vmDao.saveDetails(vm);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Persisted device bus information rootDiskController=" + rootDiskController + " for vm: " + vm.getDisplayName());
+            }
+        }
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return UserVmManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax,
+            VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig};
+    }
+
+    @Override
+    public String getVmUserData(long vmId) {
+        UserVmVO vm = _vmDao.findById(vmId);
+        if (vm == null) {
+            throw new InvalidParameterValueException("Unable to find virual machine with id " + vmId);
+        }
+
+        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, vm);
+        return vm.getUserData();
+    }
+
+    @Override
+    public boolean isDisplayResourceEnabled(Long vmId) {
+        UserVm vm = _vmDao.findById(vmId);
+        if (vm != null) {
+            return vm.isDisplayVm();
+        }
+
+        return true;
+    }
+
+    private boolean checkStatusOfVolumeSnapshots(long vmId, Volume.Type type) {
+        List<VolumeVO> listVolumes = null;
+        if (type == Volume.Type.ROOT) {
+            listVolumes = _volsDao.findByInstanceAndType(vmId, type);
+        } else if (type == Volume.Type.DATADISK) {
+            listVolumes = _volsDao.findByInstanceAndType(vmId, type);
+        } else {
+            listVolumes = _volsDao.findByInstance(vmId);
+        }
+        s_logger.debug("Found "+listVolumes.size()+" no. of volumes of type "+type+" for vm with VM ID "+vmId);
+        for (VolumeVO volume : listVolumes) {
+            Long volumeId = volume.getId();
+            s_logger.debug("Checking status of snapshots for Volume with Volume Id: "+volumeId);
+            List<SnapshotVO> ongoingSnapshots = _snapshotDao.listByStatus(volumeId, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
+            int ongoingSnapshotsCount = ongoingSnapshots.size();
+            s_logger.debug("The count of ongoing Snapshots for VM with ID "+vmId+" and disk type "+type+" is "+ongoingSnapshotsCount);
+            if (ongoingSnapshotsCount > 0) {
+                s_logger.debug("Found "+ongoingSnapshotsCount+" no. of snapshots, on volume of type "+type+", which snapshots are not yet backed up");
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void checkForUnattachedVolumes(long vmId, List<VolumeVO> volumes) {
+
+        StringBuilder sb = new StringBuilder();
+
+        for (VolumeVO volume : volumes) {
+            if (volume.getInstanceId() == null || vmId != volume.getInstanceId()) {
+                sb.append(volume.toString() + "; ");
+            }
+        }
+
+        if (!StringUtils.isEmpty(sb.toString())) {
+            throw new InvalidParameterValueException("The following supplied volumes are not attached to the VM: " + sb.toString());
+        }
+    }
+
+    private void validateVolumes(List<VolumeVO> volumes) {
+
+        for (VolumeVO volume : volumes) {
+            if (!(volume.getVolumeType() == Volume.Type.ROOT || volume.getVolumeType() == Volume.Type.DATADISK)) {
+                throw new InvalidParameterValueException("Please specify volume of type " + Volume.Type.DATADISK.toString() + " or " + Volume.Type.ROOT.toString());
+            }
+        }
+    }
+
+    private void detachVolumesFromVm(List<VolumeVO> volumes) {
+
+        for (VolumeVO volume : volumes) {
+
+            Volume detachResult = _volumeService.detachVolumeViaDestroyVM(volume.getInstanceId(), volume.getId());
+
+            if (detachResult == null) {
+                s_logger.error("DestroyVM remove volume - failed to detach and delete volume " + volume.getInstanceId() + " from instance " + volume.getId());
+            }
+        }
+    }
+
+    private void deleteVolumesFromVm(List<VolumeVO> volumes) {
+
+        for (VolumeVO volume : volumes) {
+
+            boolean deleteResult = _volumeService.deleteVolume(volume.getId(), CallContext.current().getCallingAccount());
+
+            if (!deleteResult) {
+                s_logger.error("DestroyVM remove volume - failed to delete volume " + volume.getInstanceId() + " from instance " + volume.getId());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/server/src/com/cloud/vm/UserVmStateListener.java b/server/src/main/java/com/cloud/vm/UserVmStateListener.java
similarity index 100%
rename from server/src/com/cloud/vm/UserVmStateListener.java
rename to server/src/main/java/com/cloud/vm/UserVmStateListener.java
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
similarity index 100%
rename from server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
rename to server/src/main/java/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
diff --git a/server/src/com/cloud/vm/snapshot/VmWorkCreateVMSnapshot.java b/server/src/main/java/com/cloud/vm/snapshot/VmWorkCreateVMSnapshot.java
similarity index 100%
rename from server/src/com/cloud/vm/snapshot/VmWorkCreateVMSnapshot.java
rename to server/src/main/java/com/cloud/vm/snapshot/VmWorkCreateVMSnapshot.java
diff --git a/server/src/com/cloud/vm/snapshot/VmWorkDeleteAllVMSnapshots.java b/server/src/main/java/com/cloud/vm/snapshot/VmWorkDeleteAllVMSnapshots.java
similarity index 100%
rename from server/src/com/cloud/vm/snapshot/VmWorkDeleteAllVMSnapshots.java
rename to server/src/main/java/com/cloud/vm/snapshot/VmWorkDeleteAllVMSnapshots.java
diff --git a/server/src/com/cloud/vm/snapshot/VmWorkDeleteVMSnapshot.java b/server/src/main/java/com/cloud/vm/snapshot/VmWorkDeleteVMSnapshot.java
similarity index 100%
rename from server/src/com/cloud/vm/snapshot/VmWorkDeleteVMSnapshot.java
rename to server/src/main/java/com/cloud/vm/snapshot/VmWorkDeleteVMSnapshot.java
diff --git a/server/src/com/cloud/vm/snapshot/VmWorkRevertToVMSnapshot.java b/server/src/main/java/com/cloud/vm/snapshot/VmWorkRevertToVMSnapshot.java
similarity index 100%
rename from server/src/com/cloud/vm/snapshot/VmWorkRevertToVMSnapshot.java
rename to server/src/main/java/com/cloud/vm/snapshot/VmWorkRevertToVMSnapshot.java
diff --git a/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java
new file mode 100644
index 0000000..ae471b2
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/acl/RoleManagerImpl.java
@@ -0,0 +1,331 @@
+// 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.acl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.dao.RoleDao;
+import org.apache.cloudstack.acl.dao.RolePermissionsDao;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.acl.CreateRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.CreateRolePermissionCmd;
+import org.apache.cloudstack.api.command.admin.acl.DeleteRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.DeleteRolePermissionCmd;
+import org.apache.cloudstack.api.command.admin.acl.ListRolePermissionsCmd;
+import org.apache.cloudstack.api.command.admin.acl.ListRolesCmd;
+import org.apache.cloudstack.api.command.admin.acl.UpdateRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.UpdateRolePermissionCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.ListUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.google.common.base.Strings;
+
+public class RoleManagerImpl extends ManagerBase implements RoleService, Configurable, PluggableService {
+
+    private Logger logger = Logger.getLogger(getClass());
+
+    @Inject
+    private AccountDao accountDao;
+    @Inject
+    private RoleDao roleDao;
+    @Inject
+    private RolePermissionsDao rolePermissionsDao;
+    @Inject
+    private AccountManager accountManager;
+
+    private void checkCallerAccess() {
+        if (!isEnabled()) {
+            throw new PermissionDeniedException("Dynamic api checker is not enabled, aborting role operation");
+        }
+        Account caller = getCurrentAccount();
+        if (caller == null || caller.getRoleId() == null) {
+            throw new PermissionDeniedException("Restricted API called by an invalid user account");
+        }
+        Role callerRole = findRole(caller.getRoleId());
+        if (callerRole == null || callerRole.getRoleType() != RoleType.Admin) {
+            throw new PermissionDeniedException("Restricted API called by an user account of non-Admin role type");
+        }
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return RoleService.EnableDynamicApiChecker.value();
+    }
+
+    @Override
+    public Role findRole(Long id) {
+        if (id == null || id < 1L) {
+            logger.trace(String.format("Role ID is invalid [%s]", id));
+            return null;
+        }
+        RoleVO role = roleDao.findById(id);
+        if (role == null) {
+            logger.trace(String.format("Role not found [id=%s]", id));
+            return null;
+        }
+        Account account = getCurrentAccount();
+        if (!accountManager.isRootAdmin(account.getId()) && RoleType.Admin == role.getRoleType()) {
+            logger.debug(String.format("Role [id=%s, name=%s] is of 'Admin' type and is only visible to 'Root admins'.", id, role.getName()));
+            return null;
+        }
+        return role;
+    }
+
+    /**
+     * Simple call to {@link CallContext#current()} to retrieve the current calling account.
+     * This method facilitates unit testing, it avoids mocking static methods.
+     */
+    protected Account getCurrentAccount() {
+        return CallContext.current().getCallingAccount();
+    }
+
+    @Override
+    public RolePermission findRolePermission(final Long id) {
+        if (id == null) {
+            return null;
+        }
+        return rolePermissionsDao.findById(id);
+    }
+
+    @Override
+    public RolePermission findRolePermissionByUuid(final String uuid) {
+        if (Strings.isNullOrEmpty(uuid)) {
+            return null;
+        }
+        return rolePermissionsDao.findByUuid(uuid);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_CREATE, eventDescription = "creating Role")
+    public Role createRole(final String name, final RoleType roleType, final String description) {
+        checkCallerAccess();
+        if (roleType == null || roleType == RoleType.Unknown) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role type provided");
+        }
+        return Transaction.execute(new TransactionCallback<RoleVO>() {
+            @Override
+            public RoleVO doInTransaction(TransactionStatus status) {
+                return roleDao.persist(new RoleVO(name, roleType, description));
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_UPDATE, eventDescription = "updating Role")
+    public Role updateRole(final Role role, final String name, final RoleType roleType, final String description) {
+        checkCallerAccess();
+
+        if (roleType != null && roleType == RoleType.Unknown) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unknown is not a valid role type");
+        }
+        RoleVO roleVO = (RoleVO)role;
+        if (!Strings.isNullOrEmpty(name)) {
+            roleVO.setName(name);
+        }
+        if (roleType != null) {
+            if (role.getId() <= RoleType.User.getId()) {
+                throw new PermissionDeniedException("The role type of default roles cannot be changed");
+            }
+            List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
+            if (accounts == null || accounts.isEmpty()) {
+                roleVO.setRoleType(roleType);
+            } else {
+                throw new PermissionDeniedException("Found accounts that have role in use, won't allow to change role type");
+            }
+        }
+        if (!Strings.isNullOrEmpty(description)) {
+            roleVO.setDescription(description);
+        }
+
+        roleDao.update(role.getId(), roleVO);
+        return role;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_DELETE, eventDescription = "deleting Role")
+    public boolean deleteRole(final Role role) {
+        checkCallerAccess();
+        if (role == null) {
+            return false;
+        }
+        if (role.getId() <= RoleType.User.getId()) {
+            throw new PermissionDeniedException("Default roles cannot be deleted");
+        }
+        List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
+        if (accounts == null || accounts.size() == 0) {
+            return Transaction.execute(new TransactionCallback<Boolean>() {
+                @Override
+                public Boolean doInTransaction(TransactionStatus status) {
+                    List<? extends RolePermission> rolePermissions = rolePermissionsDao.findAllByRoleIdSorted(role.getId());
+                    if (rolePermissions != null && !rolePermissions.isEmpty()) {
+                        for (RolePermission rolePermission : rolePermissions) {
+                            rolePermissionsDao.remove(rolePermission.getId());
+                        }
+                    }
+                    if (roleDao.remove(role.getId())) {
+                        RoleVO roleVO = roleDao.findByIdIncludingRemoved(role.getId());
+                        roleVO.setName(null);
+                        return roleDao.update(role.getId(), roleVO);
+                    }
+                    return false;
+                }
+            });
+        }
+        throw new PermissionDeniedException("Found accounts that have role in use, won't allow to delete role");
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_CREATE, eventDescription = "creating Role Permission")
+    public RolePermission createRolePermission(final Role role, final Rule rule, final RolePermission.Permission permission, final String description) {
+        checkCallerAccess();
+        return Transaction.execute(new TransactionCallback<RolePermissionVO>() {
+            @Override
+            public RolePermissionVO doInTransaction(TransactionStatus status) {
+                return rolePermissionsDao.persist(new RolePermissionVO(role.getId(), rule.toString(), permission, description));
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_UPDATE, eventDescription = "updating Role Permission order")
+    public boolean updateRolePermission(final Role role, final List<RolePermission> newOrder) {
+        checkCallerAccess();
+        return role != null && newOrder != null && rolePermissionsDao.update(role, newOrder);
+    }
+
+    @Override
+    public boolean updateRolePermission(Role role, RolePermission rolePermission, RolePermission.Permission permission) {
+        checkCallerAccess();
+        return role != null && rolePermissionsDao.update(role, rolePermission, permission);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_DELETE, eventDescription = "deleting Role Permission")
+    public boolean deleteRolePermission(final RolePermission rolePermission) {
+        checkCallerAccess();
+        return rolePermission != null && rolePermissionsDao.remove(rolePermission.getId());
+    }
+
+    @Override
+    public List<Role> findRolesByName(String name) {
+        List<? extends Role> roles = null;
+        if (StringUtils.isNotBlank(name)) {
+            roles = roleDao.findAllByName(name);
+        }
+        removeRootAdminRolesIfNeeded(roles);
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    /**
+     *  Removes roles of the given list that have the type '{@link RoleType#Admin}' if the user calling the method is not a 'root admin'.
+     *  The actual removal is executed via {@link #removeRootAdminRoles(List)}. Therefore, if the method is called by a 'root admin', we do nothing here.
+     */
+    protected void removeRootAdminRolesIfNeeded(List<? extends Role> roles) {
+        Account account = getCurrentAccount();
+        if (!accountManager.isRootAdmin(account.getId())) {
+            removeRootAdminRoles(roles);
+        }
+    }
+
+    /**
+     * Remove all roles that have the {@link RoleType#Admin}.
+     */
+    protected void removeRootAdminRoles(List<? extends Role> roles) {
+        if (CollectionUtils.isEmpty(roles)) {
+            return;
+        }
+        Iterator<? extends Role> rolesIterator = roles.iterator();
+        while (rolesIterator.hasNext()) {
+            Role role = rolesIterator.next();
+            if (RoleType.Admin == role.getRoleType()) {
+                rolesIterator.remove();
+            }
+        }
+
+    }
+
+    @Override
+    public List<Role> findRolesByType(RoleType roleType) {
+        if (roleType == null || RoleType.Admin == roleType && !accountManager.isRootAdmin(getCurrentAccount().getId())) {
+            return Collections.emptyList();
+        }
+        List<? extends Role> roles = roleDao.findAllByRoleType(roleType);
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    @Override
+    public List<Role> listRoles() {
+        List<? extends Role> roles = roleDao.listAll();
+        removeRootAdminRolesIfNeeded(roles);
+        return ListUtils.toListOfInterface(roles);
+    }
+
+    @Override
+    public List<RolePermission> findAllPermissionsBy(final Long roleId) {
+        List<? extends RolePermission> permissions = rolePermissionsDao.findAllByRoleIdSorted(roleId);
+        if (permissions != null) {
+            return new ArrayList<>(permissions);
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return RoleService.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {RoleService.EnableDynamicApiChecker};
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<>();
+        cmdList.add(CreateRoleCmd.class);
+        cmdList.add(ListRolesCmd.class);
+        cmdList.add(UpdateRoleCmd.class);
+        cmdList.add(DeleteRoleCmd.class);
+        cmdList.add(CreateRolePermissionCmd.class);
+        cmdList.add(ListRolePermissionsCmd.class);
+        cmdList.add(UpdateRolePermissionCmd.class);
+        cmdList.add(DeleteRolePermissionCmd.class);
+        return cmdList;
+    }
+}
diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
rename to server/src/main/java/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
diff --git a/server/src/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java b/server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java
rename to server/src/main/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImpl.java
diff --git a/server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithm.java b/server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithm.java
similarity index 100%
rename from server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithm.java
rename to server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithm.java
diff --git a/server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithm.java b/server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithm.java
similarity index 100%
rename from server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithm.java
rename to server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithm.java
diff --git a/server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithm.java b/server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithm.java
similarity index 100%
rename from server/src/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithm.java
rename to server/src/main/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithm.java
diff --git a/server/src/org/apache/cloudstack/annotation/AnnotationManagerImpl.java b/server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/annotation/AnnotationManagerImpl.java
rename to server/src/main/java/org/apache/cloudstack/annotation/AnnotationManagerImpl.java
diff --git a/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java b/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java
new file mode 100644
index 0000000..0487735
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/ca/CAManagerImpl.java
@@ -0,0 +1,429 @@
+// 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.ca;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.ca.IssueCertificateCmd;
+import org.apache.cloudstack.api.command.admin.ca.ListCAProvidersCmd;
+import org.apache.cloudstack.api.command.admin.ca.ListCaCertificateCmd;
+import org.apache.cloudstack.api.command.admin.ca.ProvisionCertificateCmd;
+import org.apache.cloudstack.api.command.admin.ca.RevokeCertificateCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.ca.CAProvider;
+import org.apache.cloudstack.framework.ca.Certificate;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.poll.BackgroundPollManager;
+import org.apache.cloudstack.poll.BackgroundPollTask;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.cloudstack.utils.security.CertUtils;
+import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.alert.AlertManager;
+import com.cloud.certificate.CrlVO;
+import com.cloud.certificate.dao.CrlDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.google.common.base.Strings;
+
+public class CAManagerImpl extends ManagerBase implements CAManager {
+    public static final Logger LOG = Logger.getLogger(CAManagerImpl.class);
+
+    @Inject
+    private CrlDao crlDao;
+    @Inject
+    private HostDao hostDao;
+    @Inject
+    private AgentManager agentManager;
+    @Inject
+    private BackgroundPollManager backgroundPollManager;
+    @Inject
+    private AlertManager alertManager;
+
+    private static CAProvider configuredCaProvider;
+    private static Map<String, CAProvider> caProviderMap = new HashMap<>();
+    private static Map<String, Date> alertMap = new ConcurrentHashMap<>();
+    private static Map<String, X509Certificate> activeCertMap = new ConcurrentHashMap<>();
+
+    private List<CAProvider> caProviders;
+
+    private CAProvider getConfiguredCaProvider() {
+        if (configuredCaProvider != null) {
+            return configuredCaProvider;
+        }
+        if (caProviderMap.containsKey(CAProviderPlugin.value()) && caProviderMap.get(CAProviderPlugin.value()) != null) {
+            configuredCaProvider = caProviderMap.get(CAProviderPlugin.value());
+            return configuredCaProvider;
+        }
+        throw new CloudRuntimeException("Failed to find default configured CA provider plugin");
+    }
+
+    private CAProvider getCAProvider(final String provider) {
+        if (Strings.isNullOrEmpty(provider)) {
+            return getConfiguredCaProvider();
+        }
+        final String caProviderName = provider.toLowerCase();
+        if (!caProviderMap.containsKey(caProviderName)) {
+            throw new CloudRuntimeException(String.format("CA provider plugin '%s' not found", caProviderName));
+        }
+        final CAProvider caProvider = caProviderMap.get(caProviderName);
+        if (caProvider == null) {
+            throw new CloudRuntimeException(String.format("CA provider plugin '%s' returned is null", caProviderName));
+        }
+        return caProvider;
+    }
+
+    ///////////////////////////////////////////////////////////
+    /////////////// CA Manager API Handlers ///////////////////
+    ///////////////////////////////////////////////////////////
+
+    @Override
+    public List<CAProvider> getCaProviders() {
+        return caProviders;
+    }
+
+    @Override
+    public Map<String, X509Certificate> getActiveCertificatesMap() {
+        return activeCertMap;
+    }
+
+    @Override
+    public boolean canProvisionCertificates() {
+        return getConfiguredCaProvider().canProvisionCertificates();
+    }
+
+    @Override
+    public String getCaCertificate(final String caProvider) throws IOException {
+        final CAProvider provider = getCAProvider(caProvider);
+        return CertUtils.x509CertificatesToPem(provider.getCaCertificate());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_ISSUE, eventDescription = "issuing certificate", async = true)
+    public Certificate issueCertificate(final String csr, final List<String> domainNames, final List<String> ipAddresses, final Integer validityDuration, final String caProvider) {
+        CallContext.current().setEventDetails("domain(s): " + domainNames + " addresses: " + ipAddresses);
+        final CAProvider provider = getCAProvider(caProvider);
+        Integer validity = CAManager.CertValidityPeriod.value();
+        if (validityDuration != null) {
+            validity = validityDuration;
+        }
+        if (Strings.isNullOrEmpty(csr)) {
+            if (domainNames == null || domainNames.isEmpty()) {
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "No domains or CSR provided");
+            }
+            return provider.issueCertificate(domainNames, ipAddresses, validity);
+        }
+        return provider.issueCertificate(csr, domainNames, ipAddresses, validity);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_REVOKE, eventDescription = "revoking certificate", async = true)
+    public boolean revokeCertificate(final BigInteger certSerial, final String certCn, final String caProvider) {
+        CallContext.current().setEventDetails("cert serial: " + certSerial);
+        final CrlVO crl = crlDao.revokeCertificate(certSerial, certCn);
+        if (crl != null && crl.getCertSerial().equals(certSerial)) {
+            final CAProvider provider = getCAProvider(caProvider);
+            return provider.revokeCertificate(certSerial, certCn);
+        }
+        return false;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_PROVISION, eventDescription = "provisioning certificate for host", async = true)
+    public boolean provisionCertificate(final Host host, final Boolean reconnect, final String caProvider) {
+        if (host == null) {
+            throw new CloudRuntimeException("Unable to find valid host to renew certificate for");
+        }
+        CallContext.current().setEventDetails("host id: " + host.getId());
+        CallContext.current().putContextParameter(Host.class, host.getUuid());
+        final String csr;
+        try {
+            csr = generateKeyStoreAndCsr(host, null);
+            if (Strings.isNullOrEmpty(csr)) {
+                return false;
+            }
+            final Certificate certificate = issueCertificate(csr, Arrays.asList(host.getName(), host.getPrivateIpAddress()), Arrays.asList(host.getPrivateIpAddress(), host.getPublicIpAddress(), host.getStorageIpAddress()), CAManager.CertValidityPeriod.value(), caProvider);
+            return deployCertificate(host, certificate, reconnect, null);
+        } catch (final AgentUnavailableException | OperationTimedoutException e) {
+            LOG.error("Host/agent is not available or operation timed out, failed to setup keystore and generate CSR for host/agent id=" + host.getId() + ", due to: ", e);
+            throw new CloudRuntimeException("Failed to generate keystore and get CSR from the host/agent id=" + host.getId());
+        }
+    }
+
+    @Override
+    public String generateKeyStoreAndCsr(final Host host, final Map<String, String> sshAccessDetails) throws AgentUnavailableException, OperationTimedoutException {
+        final SetupKeyStoreCommand cmd = new SetupKeyStoreCommand(CertValidityPeriod.value());
+        if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) {
+            cmd.setAccessDetail(sshAccessDetails);
+        }
+        CallContext.current().setEventDetails("generating keystore and CSR for host id: " + host.getId());
+        final SetupKeystoreAnswer answer = (SetupKeystoreAnswer)agentManager.send(host.getId(), cmd);
+        return answer.getCsr();
+    }
+
+    @Override
+    public boolean deployCertificate(final Host host, final Certificate certificate, final Boolean reconnect, final Map<String, String> sshAccessDetails)
+            throws AgentUnavailableException, OperationTimedoutException {
+        final SetupCertificateCommand cmd = new SetupCertificateCommand(certificate);
+        if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) {
+            cmd.setAccessDetail(sshAccessDetails);
+        }
+        CallContext.current().setEventDetails("deploying certificate for host id: " + host.getId());
+        final SetupCertificateAnswer answer = (SetupCertificateAnswer)agentManager.send(host.getId(), cmd);
+        if (answer.getResult()) {
+            CallContext.current().setEventDetails("successfully deployed certificate for host id: " + host.getId());
+        } else {
+            CallContext.current().setEventDetails("failed to deploy certificate for host id: " + host.getId());
+        }
+
+        if (answer.getResult()) {
+            getActiveCertificatesMap().put(host.getPrivateIpAddress(), certificate.getClientCertificate());
+            if (sshAccessDetails == null && reconnect != null && reconnect) {
+                LOG.info(String.format("Successfully setup certificate on host, reconnecting with agent with id=%d, name=%s, address=%s", host.getId(), host.getName(), host.getPublicIpAddress()));
+                try {
+                    agentManager.reconnect(host.getId());
+                } catch (AgentUnavailableException | CloudRuntimeException e) {
+                    LOG.debug("Error when reconnecting to host: " + host.getUuid(), e);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void purgeHostCertificate(final Host host) {
+        if (host == null) {
+            return;
+        }
+        final String privateAddress = host.getPrivateIpAddress();
+        final String publicAddress = host.getPublicIpAddress();
+        final Map<String, X509Certificate> activeCertsMap = getActiveCertificatesMap();
+        if (!Strings.isNullOrEmpty(privateAddress) && activeCertsMap.containsKey(privateAddress)) {
+            activeCertsMap.remove(privateAddress);
+        }
+        if (!Strings.isNullOrEmpty(publicAddress) && activeCertsMap.containsKey(publicAddress)) {
+            activeCertsMap.remove(publicAddress);
+        }
+    }
+
+    @Override
+    public void sendAlert(final Host host, final String subject, final String message) {
+        if (host == null) {
+            return;
+        }
+        alertManager.sendAlert(AlertManager.AlertType.ALERT_TYPE_CA_CERT, host.getDataCenterId(), host.getPodId(), subject, message);
+    }
+
+    @Override
+    public SSLEngine createSSLEngine(final SSLContext sslContext, final String remoteAddress) throws GeneralSecurityException, IOException {
+        if (sslContext == null) {
+            throw new CloudRuntimeException("SSLContext provided to create SSLEngine is null, aborting");
+        }
+        if (Strings.isNullOrEmpty(remoteAddress)) {
+            throw new CloudRuntimeException("Remote client address connecting to mgmt server cannot be empty/null");
+        }
+        return getConfiguredCaProvider().createSSLEngine(sslContext, remoteAddress, getActiveCertificatesMap());
+    }
+
+    @Override
+    public KeyStore getManagementKeyStore() throws KeyStoreException {
+        return getConfiguredCaProvider().getManagementKeyStore();
+    }
+
+    @Override
+    public char[] getKeyStorePassphrase() {
+        return getConfiguredCaProvider().getKeyStorePassphrase();
+    }
+
+    ////////////////////////////////////////////////////
+    /////////////// CA Manager Setup ///////////////////
+    ////////////////////////////////////////////////////
+
+    public static final class CABackgroundTask extends ManagedContextRunnable implements BackgroundPollTask {
+        private CAManager caManager;
+        private HostDao hostDao;
+
+        public CABackgroundTask(final CAManager caManager, final HostDao hostDao) {
+            this.caManager = caManager;
+            this.hostDao = hostDao;
+        }
+
+        @Override
+        protected void runInContext() {
+            try {
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("CA background task is running...");
+                }
+                final DateTime now = DateTime.now(DateTimeZone.UTC);
+                final Map<String, X509Certificate> certsMap = caManager.getActiveCertificatesMap();
+                for (final Iterator<Map.Entry<String, X509Certificate>> it = certsMap.entrySet().iterator(); it.hasNext();) {
+                    final Map.Entry<String, X509Certificate> entry = it.next();
+                    if (entry == null) {
+                        continue;
+                    }
+                    final String hostIp = entry.getKey();
+                    final X509Certificate certificate = entry.getValue();
+                    if (certificate == null) {
+                        it.remove();
+                        continue;
+                    }
+                    final Host host = hostDao.findByIp(hostIp);
+                    if (host == null || host.getManagementServerId() == null || host.getManagementServerId() != ManagementServerNode.getManagementServerId() || host.getStatus() != Status.Up) {
+                        if (host == null || (host.getManagementServerId() != null && host.getManagementServerId() != ManagementServerNode.getManagementServerId())) {
+                            it.remove();
+                        }
+                        continue;
+                    }
+
+                    final String hostDescription = String.format("host id=%d, uuid=%s, name=%s, ip=%s, zone id=%d", host.getId(), host.getUuid(), host.getName(), hostIp, host.getDataCenterId());
+
+                    try {
+                        certificate.checkValidity(now.plusDays(CertExpiryAlertPeriod.valueIn(host.getClusterId())).toDate());
+                    } catch (final CertificateExpiredException | CertificateNotYetValidException e) {
+                        LOG.warn("Certificate is going to expire for " + hostDescription, e);
+                        if (AutomaticCertRenewal.valueIn(host.getClusterId())) {
+                            try {
+                                LOG.debug("Attempting certificate auto-renewal for " + hostDescription, e);
+                                boolean result = caManager.provisionCertificate(host, false, null);
+                                if (result) {
+                                    LOG.debug("Succeeded in auto-renewing certificate for " + hostDescription, e);
+                                } else {
+                                    LOG.debug("Failed in auto-renewing certificate for " + hostDescription, e);
+                                }
+                            } catch (final Throwable ex) {
+                                LOG.warn("Failed to auto-renew certificate for " + hostDescription + ", with error=", ex);
+                                caManager.sendAlert(host, "Certificate auto-renewal failed for " + hostDescription,
+                                        String.format("Certificate is going to expire for %s. Auto-renewal failed to renew the certificate, please renew it manually. It is not valid after %s.",
+                                                hostDescription, certificate.getNotAfter()));
+                            }
+                        } else {
+                            if (alertMap.containsKey(hostIp)) {
+                                final Date lastSentDate = alertMap.get(hostIp);
+                                if (now.minusDays(1).toDate().before(lastSentDate)) {
+                                    continue;
+                                }
+                            }
+                            caManager.sendAlert(host, "Certificate expiring soon for " + hostDescription,
+                                    String.format("Certificate is going to expire for %s. Please renew it, it is not valid after %s.", hostDescription, certificate.getNotAfter()));
+                            alertMap.put(hostIp, new Date());
+                        }
+                    }
+                }
+            } catch (final Throwable t) {
+                LOG.error("Error trying to run CA background task", t);
+            }
+        }
+
+        @Override
+        public Long getDelay() {
+            return CABackgroundJobDelay.value() * 1000L;
+        }
+    }
+
+    public void setCaProviders(final List<CAProvider> caProviders) {
+        this.caProviders = caProviders;
+        initializeCaProviderMap();
+    }
+
+    private void initializeCaProviderMap() {
+        if (caProviderMap != null && caProviderMap.size() != caProviders.size()) {
+            for (final CAProvider caProvider : caProviders) {
+                caProviderMap.put(caProvider.getProviderName().toLowerCase(), caProvider);
+            }
+        }
+    }
+
+    @Override
+    public boolean start() {
+        super.start();
+        initializeCaProviderMap();
+        if (caProviderMap.containsKey(CAProviderPlugin.value())) {
+            configuredCaProvider = caProviderMap.get(CAProviderPlugin.value());
+        }
+        if (configuredCaProvider == null) {
+            LOG.error("Failed to find valid configured CA provider, please check!");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        backgroundPollManager.submitTask(new CABackgroundTask(this, hostDao));
+        return true;
+    }
+
+    //////////////////////////////////////////////////////////
+    /////////////// CA Manager Descriptors ///////////////////
+    //////////////////////////////////////////////////////////
+
+    @Override
+    public List<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(ListCAProvidersCmd.class);
+        cmdList.add(ListCaCertificateCmd.class);
+        cmdList.add(IssueCertificateCmd.class);
+        cmdList.add(ProvisionCertificateCmd.class);
+        cmdList.add(RevokeCertificateCmd.class);
+        return cmdList;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return CAManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {CAProviderPlugin, CertKeySize, CertSignatureAlgorithm, CertValidityPeriod, AutomaticCertRenewal, CABackgroundJobDelay, CertExpiryAlertPeriod};
+    }
+}
diff --git a/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java
new file mode 100644
index 0000000..21bb0a1
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImpl.java
@@ -0,0 +1,135 @@
+//
+// 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.diagnostics;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.inject.Inject;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.google.common.base.Strings;
+import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+
+public class DiagnosticsServiceImpl extends ManagerBase implements PluggableService, DiagnosticsService {
+    private static final Logger LOGGER = Logger.getLogger(DiagnosticsServiceImpl.class);
+
+    @Inject
+    private AgentManager agentManager;
+    @Inject
+    private VMInstanceDao instanceDao;
+    @Inject
+    private VirtualMachineManager vmManager;
+    @Inject
+    private NetworkOrchestrationService networkManager;
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_SYSTEM_VM_DIAGNOSTICS, eventDescription = "running diagnostics on system vm", async = true)
+    public Map<String, String> runDiagnosticsCommand(final RunDiagnosticsCmd cmd) {
+        final Long vmId = cmd.getId();
+        final String cmdType = cmd.getType().getValue();
+        final String ipAddress = cmd.getAddress();
+        final String optionalArguments = cmd.getOptionalArguments();
+        final VMInstanceVO vmInstance = instanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.DomainRouter, VirtualMachine.Type.SecondaryStorageVm);
+
+        if (vmInstance == null) {
+            throw new InvalidParameterValueException("Unable to find a system vm with id " + vmId);
+        }
+        final Long hostId = vmInstance.getHostId();
+
+        if (hostId == null) {
+            throw new CloudRuntimeException("Unable to find host for virtual machine instance: " + vmInstance.getInstanceName());
+        }
+
+        final String shellCmd = prepareShellCmd(cmdType, ipAddress, optionalArguments);
+
+        if (Strings.isNullOrEmpty(shellCmd)) {
+            throw new IllegalArgumentException("Optional parameters contain unwanted characters: " + optionalArguments);
+        }
+
+        final Hypervisor.HypervisorType hypervisorType = vmInstance.getHypervisorType();
+
+        final DiagnosticsCommand command = new DiagnosticsCommand(shellCmd, vmManager.getExecuteInSequence(hypervisorType));
+        final Map<String, String> accessDetails = networkManager.getSystemVMAccessDetails(vmInstance);
+
+        if (Strings.isNullOrEmpty(accessDetails.get(NetworkElementCommand.ROUTER_IP))) {
+            throw new CloudRuntimeException("Unable to set system vm ControlIP for system vm with ID: " + vmId);
+        }
+
+        command.setAccessDetail(accessDetails);
+
+        Map<String, String> detailsMap;
+
+        final Answer answer = agentManager.easySend(hostId, command);
+
+        if (answer != null && (answer instanceof DiagnosticsAnswer)) {
+            detailsMap = ((DiagnosticsAnswer) answer).getExecutionDetails();
+            return detailsMap;
+        } else {
+            throw new CloudRuntimeException("Failed to execute diagnostics command on remote host: " + answer.getDetails());
+        }
+    }
+
+    protected boolean hasValidChars(String optionalArgs) {
+        if (Strings.isNullOrEmpty(optionalArgs)) {
+            return true;
+        } else {
+            final String regex = "^[\\w\\-\\s.]+$";
+            final Pattern pattern = Pattern.compile(regex);
+            return pattern.matcher(optionalArgs).find();
+        }
+
+    }
+
+    protected String prepareShellCmd(String cmdType, String ipAddress, String optionalParams) {
+        final String CMD_TEMPLATE = String.format("%s %s", cmdType, ipAddress);
+        if (Strings.isNullOrEmpty(optionalParams)) {
+            return CMD_TEMPLATE;
+        } else {
+            if (hasValidChars(optionalParams)) {
+                return String.format("%s %s", CMD_TEMPLATE, optionalParams);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<>();
+        cmdList.add(RunDiagnosticsCmd.class);
+        return cmdList;
+    }
+}
\ No newline at end of file
diff --git a/server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java b/server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
old mode 100755
new mode 100644
similarity index 100%
rename from server/src/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
rename to server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
diff --git a/server/src/org/apache/cloudstack/ha/HAManager.java b/server/src/main/java/org/apache/cloudstack/ha/HAManager.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/HAManager.java
rename to server/src/main/java/org/apache/cloudstack/ha/HAManager.java
diff --git a/server/src/main/java/org/apache/cloudstack/ha/HAManagerImpl.java b/server/src/main/java/org/apache/cloudstack/ha/HAManagerImpl.java
new file mode 100644
index 0000000..ab269b1
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/ha/HAManagerImpl.java
@@ -0,0 +1,724 @@
+// 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.ha;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.ha.ConfigureHAForHostCmd;
+import org.apache.cloudstack.api.command.admin.ha.DisableHAForClusterCmd;
+import org.apache.cloudstack.api.command.admin.ha.DisableHAForHostCmd;
+import org.apache.cloudstack.api.command.admin.ha.DisableHAForZoneCmd;
+import org.apache.cloudstack.api.command.admin.ha.EnableHAForClusterCmd;
+import org.apache.cloudstack.api.command.admin.ha.EnableHAForHostCmd;
+import org.apache.cloudstack.api.command.admin.ha.EnableHAForZoneCmd;
+import org.apache.cloudstack.api.command.admin.ha.ListHostHAProvidersCmd;
+import org.apache.cloudstack.api.command.admin.ha.ListHostHAResourcesCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.ha.dao.HAConfigDao;
+import org.apache.cloudstack.ha.provider.HAProvider;
+import org.apache.cloudstack.ha.provider.HAProvider.HAProviderConfig;
+import org.apache.cloudstack.ha.task.ActivityCheckTask;
+import org.apache.cloudstack.ha.task.FenceTask;
+import org.apache.cloudstack.ha.task.HealthCheckTask;
+import org.apache.cloudstack.ha.task.RecoveryTask;
+import org.apache.cloudstack.kernel.Partition;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.poll.BackgroundPollManager;
+import org.apache.cloudstack.poll.BackgroundPollTask;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+
+import com.cloud.cluster.ClusterManagerListener;
+import org.apache.cloudstack.management.ManagementServerHost;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterDetailsVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterDetailVO;
+import com.cloud.dc.dao.DataCenterDetailsDao;
+import com.cloud.domain.Domain;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.EventTypes;
+import com.cloud.ha.Investigator;
+import com.cloud.host.Host;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.org.Cluster;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.utils.fsm.StateMachine2;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+public final class HAManagerImpl extends ManagerBase implements HAManager, ClusterManagerListener, PluggableService, Configurable, StateListener<HAConfig.HAState, HAConfig.Event, HAConfig> {
+    public static final Logger LOG = Logger.getLogger(HAManagerImpl.class);
+
+    @Inject
+    private HAConfigDao haConfigDao;
+
+    @Inject
+    private HostDao hostDao;
+
+    @Inject
+    private ClusterDetailsDao clusterDetailsDao;
+
+    @Inject
+    private DataCenterDetailsDao dataCenterDetailsDao;
+
+    @Inject
+    private BackgroundPollManager pollManager;
+
+    private List<HAProvider<HAResource>> haProviders;
+    private Map<String, HAProvider<HAResource>> haProviderMap = new HashMap<>();
+
+    private static ExecutorService healthCheckExecutor;
+    private static ExecutorService activityCheckExecutor;
+    private static ExecutorService recoveryExecutor;
+    private static ExecutorService fenceExecutor;
+
+    private static final String HA_ENABLED_DETAIL = "resourceHAEnabled";
+
+    //////////////////////////////////////////////////////
+    //////////////// HA Manager methods //////////////////
+    //////////////////////////////////////////////////////
+
+    public Map<String, HAResourceCounter> haCounterMap = new ConcurrentHashMap<>();
+
+    public HAProvider<HAResource> getHAProvider(final String name) {
+        return haProviderMap.get(name);
+    }
+
+    private String resourceCounterKey(final Long resourceId, final HAResource.ResourceType resourceType) {
+        return resourceId.toString() + resourceType.toString();
+    }
+
+    public synchronized HAResourceCounter getHACounter(final Long resourceId, final HAResource.ResourceType resourceType) {
+        final String key = resourceCounterKey(resourceId, resourceType);
+        if (!haCounterMap.containsKey(key)) {
+            haCounterMap.put(key, new HAResourceCounter());
+        }
+        return haCounterMap.get(key);
+    }
+
+    public synchronized void purgeHACounter(final Long resourceId, final HAResource.ResourceType resourceType) {
+        final String key = resourceCounterKey(resourceId, resourceType);
+        if (haCounterMap.containsKey(key)) {
+            haCounterMap.remove(key);
+        }
+    }
+
+    public boolean transitionHAState(final HAConfig.Event event, final HAConfig haConfig) {
+        if (event == null || haConfig == null) {
+            return false;
+        }
+        final HAConfig.HAState currentHAState = haConfig.getState();
+        try {
+            final HAConfig.HAState nextState = HAConfig.HAState.getStateMachine().getNextState(currentHAState, event);
+            boolean result = HAConfig.HAState.getStateMachine().transitTo(haConfig, event, null, haConfigDao);
+            if (result) {
+                final String message = String.format("Transitioned host HA state from:%s to:%s due to event:%s for the host id:%d",
+                        currentHAState, nextState, event, haConfig.getResourceId());
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace(message);
+                }
+                if (nextState == HAConfig.HAState.Recovering || nextState == HAConfig.HAState.Fencing || nextState == HAConfig.HAState.Fenced) {
+                    ActionEventUtils.onActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(),
+                            Domain.ROOT_DOMAIN, EventTypes.EVENT_HA_STATE_TRANSITION, message);
+                }
+            }
+            return result;
+        } catch (NoTransitionException e) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Unable to find next HA state for current HA state: " + currentHAState + " for event: " + event + " for host" + haConfig.getResourceId());
+            }
+        }
+        return false;
+    }
+
+    private boolean transitionResourceStateToDisabled(final Partition partition) {
+        List<? extends HAResource> resources;
+        if (partition.partitionType() == Partition.PartitionType.Cluster) {
+            resources = hostDao.findByClusterId(partition.getId());
+        } else if (partition.partitionType() == Partition.PartitionType.Zone) {
+            resources = hostDao.findByDataCenterId(partition.getId());
+        } else {
+            return true;
+        }
+
+        boolean result = true;
+        for (final HAResource resource: resources) {
+            result = result && transitionHAState(HAConfig.Event.Disabled,
+                    haConfigDao.findHAResource(resource.getId(), resource.resourceType()));
+        }
+        return result;
+    }
+
+    private boolean checkHAOwnership(final HAConfig haConfig) {
+        // Skip for resources not owned by this mgmt server
+        return !(haConfig.getManagementServerId() != null
+                && haConfig.getManagementServerId() != ManagementServerNode.getManagementServerId());
+    }
+
+    private HAResource validateAndFindHAResource(final HAConfig haConfig) {
+        HAResource resource = null;
+        if (haConfig == null) {
+            return null;
+        }
+        if (haConfig.getResourceType() == HAResource.ResourceType.Host) {
+            final Host host = hostDao.findById(haConfig.getResourceId());
+            if (host != null && host.getRemoved() != null) {
+                return null;
+            }
+            resource = host;
+            if (haConfig.getState() == null || (resource == null && haConfig.getState() != HAConfig.HAState.Disabled)) {
+                disableHA(haConfig.getResourceId(), haConfig.getResourceType());
+                return null;
+            }
+        }
+        if (!haConfig.isEnabled() || !isHAEnabledForZone(resource) || !isHAEnabledForCluster(resource)) {
+            if (haConfig.getState() != HAConfig.HAState.Disabled) {
+                if (transitionHAState(HAConfig.Event.Disabled, haConfig) ) {
+                    purgeHACounter(haConfig.getResourceId(), haConfig.getResourceType());
+                }
+            }
+            return null;
+        } else if (haConfig.getState() == HAConfig.HAState.Disabled) {
+            transitionHAState(HAConfig.Event.Enabled, haConfig);
+        }
+        return resource;
+    }
+
+    private HAProvider<HAResource> validateAndFindHAProvider(final HAConfig haConfig, final HAResource resource) {
+        if (haConfig == null) {
+            return null;
+        }
+        final HAProvider<HAResource> haProvider = haProviderMap.get(haConfig.getHaProvider());
+        if (haProvider != null && !haProvider.isEligible(resource)) {
+            if (haConfig.getState() != HAConfig.HAState.Ineligible) {
+                transitionHAState(HAConfig.Event.Ineligible, haConfig);
+            }
+            return null;
+        } else if (haConfig.getState() == HAConfig.HAState.Ineligible) {
+            transitionHAState(HAConfig.Event.Eligible, haConfig);
+        }
+        return haProvider;
+    }
+
+    public boolean isHAEnabledForZone(final HAResource resource) {
+        if (resource == null || resource.getDataCenterId() < 1L) {
+            return true;
+        }
+        final DataCenterDetailVO zoneDetails = dataCenterDetailsDao.findDetail(resource.getDataCenterId(), HA_ENABLED_DETAIL);
+        return zoneDetails == null || Strings.isNullOrEmpty(zoneDetails.getValue()) || Boolean.valueOf(zoneDetails.getValue());
+    }
+
+    private boolean isHAEnabledForCluster(final HAResource resource) {
+        if (resource == null || resource.getClusterId() == null) {
+            return true;
+        }
+        final ClusterDetailsVO clusterDetails = clusterDetailsDao.findDetail(resource.getClusterId(), HA_ENABLED_DETAIL);
+        return clusterDetails == null || Strings.isNullOrEmpty(clusterDetails.getValue()) || Boolean.valueOf(clusterDetails.getValue());
+    }
+
+    private boolean isHAEligibleForResource(final HAResource resource) {
+        if (resource == null || resource.getId() < 1L) {
+            return false;
+        }
+        HAResource.ResourceType resourceType = null;
+        if (resource instanceof Host) {
+            resourceType = HAResource.ResourceType.Host;
+        }
+        if (resourceType == null) {
+            return false;
+        }
+        final HAConfig haConfig = haConfigDao.findHAResource(resource.getId(), resourceType);
+        return haConfig != null && haConfig.isEnabled()
+                && haConfig.getState() != HAConfig.HAState.Disabled
+                && haConfig.getState() != HAConfig.HAState.Ineligible;
+    }
+
+    public boolean isHAEligible(final HAResource resource) {
+        return resource != null && isHAEnabledForZone(resource)
+                && isHAEnabledForCluster(resource)
+                && isHAEligibleForResource(resource);
+    }
+
+    public void validateHAProviderConfigForResource(final Long resourceId, final HAResource.ResourceType resourceType, final HAProvider<HAResource> haProvider) {
+        if (HAResource.ResourceType.Host.equals(resourceType)) {
+            final Host host = hostDao.findById(resourceId);
+            if (host.getHypervisorType() == null || haProvider.resourceSubType() == null || !host.getHypervisorType().toString().equals(haProvider.resourceSubType().toString())) {
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Incompatible haprovider provided for the resource of hypervisor type:" + host.getHypervisorType());
+            }
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    //////////////// HA Investigator wrapper for Old HA ////////////////
+    ////////////////////////////////////////////////////////////////////
+
+    public Boolean isVMAliveOnHost(final Host host) throws Investigator.UnknownVM {
+        final HAConfig haConfig = haConfigDao.findHAResource(host.getId(), HAResource.ResourceType.Host);
+        if (haConfig != null) {
+            if (haConfig.getState() == HAConfig.HAState.Fenced) {
+                if (LOG.isDebugEnabled()){
+                    LOG.debug("HA: Host is fenced " + host.getId());
+                }
+                return false;
+            }
+            if (LOG.isDebugEnabled()){
+                LOG.debug("HA: HOST is alive " + host.getId());
+            }
+            return true;
+        }
+        throw new Investigator.UnknownVM();
+    }
+
+    public Status getHostStatus(final Host host) {
+        final HAConfig haConfig = haConfigDao.findHAResource(host.getId(), HAResource.ResourceType.Host);
+        if (haConfig != null) {
+            if (haConfig.getState() == HAConfig.HAState.Fenced) {
+                if (LOG.isDebugEnabled()){
+                    LOG.debug("HA: Agent is available/suspect/checking Up " + host.getId());
+                }
+                return Status.Down;
+            } else if (haConfig.getState() == HAConfig.HAState.Degraded || haConfig.getState() == HAConfig.HAState.Recovering || haConfig.getState() == HAConfig.HAState.Fencing) {
+                if (LOG.isDebugEnabled()){
+                    LOG.debug("HA: Agent is disconnected " + host.getId());
+                }
+                return Status.Disconnected;
+            }
+            return Status.Up;
+        }
+        return Status.Unknown;
+    }
+
+    //////////////////////////////////////////////////////
+    //////////////// HA API handlers /////////////////////
+    //////////////////////////////////////////////////////
+
+    private boolean configureHA(final Long resourceId, final HAResource.ResourceType resourceType, final Boolean enable, final String haProvider) {
+        return Transaction.execute(new TransactionCallback<Boolean>() {
+            @Override
+            public Boolean doInTransaction(TransactionStatus status) {
+                HAConfigVO haConfig = (HAConfigVO) haConfigDao.findHAResource(resourceId, resourceType);
+                if (haConfig == null) {
+                    haConfig = new HAConfigVO();
+                    if (haProvider != null) {
+                        haConfig.setHaProvider(haProvider);
+                    }
+                    if (enable != null) {
+                        haConfig.setEnabled(enable);
+                        haConfig.setManagementServerId(ManagementServerNode.getManagementServerId());
+                    }
+                    haConfig.setResourceId(resourceId);
+                    haConfig.setResourceType(resourceType);
+                    if (Strings.isNullOrEmpty(haConfig.getHaProvider())) {
+                        throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "HAProvider is not provided for the resource, failing configuration.");
+                    }
+                    if (haConfigDao.persist(haConfig) != null) {
+                        return true;
+                    }
+                } else {
+                    if (enable != null) {
+                        haConfig.setEnabled(enable);
+                    }
+                    if (haProvider != null) {
+                        haConfig.setHaProvider(haProvider);
+                    }
+                    if (Strings.isNullOrEmpty(haConfig.getHaProvider())) {
+                        throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "HAProvider is not provided for the resource, failing configuration.");
+                    }
+                    return haConfigDao.update(haConfig.getId(), haConfig);
+                }
+                return false;
+            }
+        });
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_CONFIGURE, eventDescription = "configuring HA for resource")
+    public boolean configureHA(final Long resourceId, final HAResource.ResourceType resourceType, final String haProvider) {
+        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
+        Preconditions.checkArgument(resourceType != null);
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(haProvider));
+
+        if (!haProviderMap.containsKey(haProvider.toLowerCase())) {
+            throw new CloudRuntimeException("Given HA provider does not exist.");
+        }
+        validateHAProviderConfigForResource(resourceId, resourceType, haProviderMap.get(haProvider.toLowerCase()));
+        return configureHA(resourceId, resourceType, null, haProvider.toLowerCase());
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for resource")
+    public boolean enableHA(final Long resourceId, final HAResource.ResourceType resourceType) {
+        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
+        Preconditions.checkArgument(resourceType != null);
+        return configureHA(resourceId, resourceType, true, null);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for resource")
+    public boolean disableHA(final Long resourceId, final HAResource.ResourceType resourceType) {
+        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
+        Preconditions.checkArgument(resourceType != null);
+        boolean result = configureHA(resourceId, resourceType, false, null);
+        if (result) {
+            transitionHAState(HAConfig.Event.Disabled, haConfigDao.findHAResource(resourceId, resourceType));
+            purgeHACounter(resourceId, resourceType);
+        }
+        return result;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for a cluster")
+    public boolean enableHA(final Cluster cluster) {
+        clusterDetailsDao.persist(cluster.getId(), HA_ENABLED_DETAIL, String.valueOf(true));
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for a cluster")
+    public boolean disableHA(final Cluster cluster) {
+        clusterDetailsDao.persist(cluster.getId(), HA_ENABLED_DETAIL, String.valueOf(false));
+        return transitionResourceStateToDisabled(cluster);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for a zone")
+    public boolean enableHA(final DataCenter zone) {
+        dataCenterDetailsDao.persist(zone.getId(), HA_ENABLED_DETAIL, String.valueOf(true));
+        return true;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for a zone")
+    public boolean disableHA(final DataCenter zone) {
+        dataCenterDetailsDao.persist(zone.getId(), HA_ENABLED_DETAIL, String.valueOf(false));
+        return transitionResourceStateToDisabled(zone);
+    }
+
+    @Override
+    public List<HAConfig> listHAResources(final Long resourceId, final HAResource.ResourceType resourceType) {
+        return haConfigDao.listHAResource(resourceId, resourceType);
+    }
+
+    @Override
+    public List<String> listHAProviders(final HAResource.ResourceType resourceType, final HAResource.ResourceSubType entityType) {
+        final List<String> haProviderNames = new ArrayList<>();
+        for (final HAProvider<HAResource> haProvider : haProviders) {
+            if (haProvider.resourceType().equals(resourceType) && haProvider.resourceSubType().equals(entityType)) {
+                haProviderNames.add(haProvider.getClass().getSimpleName());
+            }
+        }
+        return haProviderNames;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<>();
+        cmdList.add(ConfigureHAForHostCmd.class);
+        cmdList.add(EnableHAForHostCmd.class);
+        cmdList.add(EnableHAForClusterCmd.class);
+        cmdList.add(EnableHAForZoneCmd.class);
+        cmdList.add(DisableHAForHostCmd.class);
+        cmdList.add(DisableHAForClusterCmd.class);
+        cmdList.add(DisableHAForZoneCmd.class);
+        cmdList.add(ListHostHAResourcesCmd.class);
+        cmdList.add(ListHostHAProvidersCmd.class);
+        return cmdList;
+    }
+
+    //////////////////////////////////////////////////////
+    //////////////// Event Listeners /////////////////////
+    //////////////////////////////////////////////////////
+
+    @Override
+    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
+    }
+
+    @Override
+    public void onManagementNodeIsolated() {
+    }
+
+    private boolean processHAStateChange(final HAConfig haConfig, final HAConfig.HAState newState, final boolean status) {
+        if (!status || !checkHAOwnership(haConfig)) {
+            return false;
+        }
+
+        final HAResource resource = validateAndFindHAResource(haConfig);
+        if (resource == null) {
+            return false;
+        }
+
+        final HAProvider<HAResource> haProvider = validateAndFindHAProvider(haConfig, resource);
+        if (haProvider == null) {
+            return false;
+        }
+
+        final HAResourceCounter counter = getHACounter(haConfig.getResourceId(), haConfig.getResourceType());
+
+        // Perform activity checks
+        if (newState == HAConfig.HAState.Checking) {
+            final ActivityCheckTask job = ComponentContext.inject(new ActivityCheckTask(resource, haProvider, haConfig,
+                    HAProviderConfig.ActivityCheckTimeout, activityCheckExecutor, counter.getSuspectTimeStamp()));
+            activityCheckExecutor.submit(job);
+        }
+
+        // Attempt recovery
+        if (newState == HAConfig.HAState.Recovering) {
+            if (counter.getRecoveryCounter() >= (Long) (haProvider.getConfigValue(HAProviderConfig.MaxRecoveryAttempts, resource))) {
+                return false;
+            }
+            final RecoveryTask task = ComponentContext.inject(new RecoveryTask(resource, haProvider, haConfig,
+                    HAProviderConfig.RecoveryTimeout, recoveryExecutor));
+            final Future<Boolean> recoveryFuture = recoveryExecutor.submit(task);
+            counter.setRecoveryFuture(recoveryFuture);
+        }
+
+        // Fencing
+        if (newState == HAConfig.HAState.Fencing) {
+            final FenceTask task = ComponentContext.inject(new FenceTask(resource, haProvider, haConfig,
+                    HAProviderConfig.FenceTimeout, fenceExecutor));
+            final Future<Boolean> fenceFuture = fenceExecutor.submit(task);
+            counter.setFenceFuture(fenceFuture);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(final HAConfig.HAState oldState, final HAConfig.Event event, final HAConfig.HAState newState, final HAConfig haConfig, final boolean status, final Object opaque) {
+        if (oldState != newState || newState == HAConfig.HAState.Suspect || newState == HAConfig.HAState.Checking) {
+            return false;
+        }
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("HA state pre-transition:: new state=" + newState + ", old state=" + oldState + ", for resource id=" + haConfig.getResourceId() + ", status=" + status + ", ha config state=" + haConfig.getState());
+        }
+        if (status && haConfig.getState() != newState) {
+            LOG.warn("HA state pre-transition:: HA state is not equal to transition state, HA state=" + haConfig.getState() + ", new state=" + newState);
+        }
+        return processHAStateChange(haConfig, newState, status);
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(final StateMachine2.Transition<HAConfig.HAState, HAConfig.Event> transition, final HAConfig haConfig, final boolean status, final Object opaque) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("HA state post-transition:: new state=" + transition.getToState() + ", old state=" + transition.getCurrentState() + ", for resource id=" + haConfig.getResourceId() + ", status=" + status + ", ha config state=" + haConfig.getState());
+        }
+        if (status && haConfig.getState() != transition.getToState()) {
+            LOG.warn("HA state post-transition:: HA state is not equal to transition state, HA state=" + haConfig.getState() + ", new state=" + transition.getToState());
+        }
+        return processHAStateChange(haConfig, transition.getToState(), status);
+    }
+
+    ///////////////////////////////////////////////////
+    //////////////// Manager Init /////////////////////
+    ///////////////////////////////////////////////////
+
+    @Override
+    public boolean start() {
+        haProviderMap.clear();
+        for (final HAProvider<HAResource> haProvider : haProviders) {
+            haProviderMap.put(haProvider.getClass().getSimpleName().toLowerCase(), haProvider);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        haConfigDao.expireServerOwnership(ManagementServerNode.getManagementServerId());
+        return true;
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        // Health Check
+        final int healthCheckWorkers = MaxConcurrentHealthCheckOperations.value();
+        final int healthCheckQueueSize = MaxPendingHealthCheckOperations.value();
+        healthCheckExecutor = new ThreadPoolExecutor(healthCheckWorkers, healthCheckWorkers,
+                0L, TimeUnit.MILLISECONDS,
+                new ArrayBlockingQueue<Runnable>(healthCheckQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
+
+        // Activity Check
+        final int activityCheckWorkers = MaxConcurrentActivityCheckOperations.value();
+        final int activityCheckQueueSize = MaxPendingActivityCheckOperations.value();
+        activityCheckExecutor = new ThreadPoolExecutor(activityCheckWorkers, activityCheckWorkers,
+                0L, TimeUnit.MILLISECONDS,
+                new ArrayBlockingQueue<Runnable>(activityCheckQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
+
+        // Recovery
+        final int recoveryOperationWorkers = MaxConcurrentRecoveryOperations.value();
+        final int recoveryOperationQueueSize = MaxPendingRecoveryOperations.value();
+        recoveryExecutor = new ThreadPoolExecutor(recoveryOperationWorkers, recoveryOperationWorkers,
+                0L, TimeUnit.MILLISECONDS,
+                new ArrayBlockingQueue<Runnable>(recoveryOperationQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
+
+        // Fence
+        final int fenceOperationWorkers = MaxConcurrentFenceOperations.value();
+        final int fenceOperationQueueSize = MaxPendingFenceOperations.value();
+        fenceExecutor = new ThreadPoolExecutor(fenceOperationWorkers, fenceOperationWorkers,
+                0L, TimeUnit.MILLISECONDS,
+                new ArrayBlockingQueue<Runnable>(fenceOperationQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
+
+        pollManager.submitTask(new HAManagerBgPollTask());
+        HAConfig.HAState.getStateMachine().registerListener(this);
+
+        LOG.debug("HA manager has been configured");
+        return true;
+    }
+
+    public void setHaProviders(List<HAProvider<HAResource>> haProviders) {
+        this.haProviders = haProviders;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return HAManager.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {
+                MaxConcurrentHealthCheckOperations,
+                MaxPendingHealthCheckOperations,
+                MaxConcurrentActivityCheckOperations,
+                MaxPendingActivityCheckOperations,
+                MaxConcurrentRecoveryOperations,
+                MaxPendingRecoveryOperations,
+                MaxConcurrentFenceOperations,
+                MaxPendingFenceOperations
+        };
+    }
+
+    /////////////////////////////////////////////////
+    //////////////// Poll Tasks /////////////////////
+    /////////////////////////////////////////////////
+
+    private final class HAManagerBgPollTask extends ManagedContextRunnable implements BackgroundPollTask {
+        @Override
+        protected void runInContext() {
+            try {
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("HA health check task is running...");
+                }
+                final List<HAConfig> haConfigList = new ArrayList<HAConfig>(haConfigDao.listAll());
+                for (final HAConfig haConfig : haConfigList) {
+                    if (haConfig == null) {
+                        continue;
+                    }
+
+                    if (!checkHAOwnership(haConfig)) {
+                        continue;
+                    }
+
+                    final HAResource resource = validateAndFindHAResource(haConfig);
+                    if (resource == null) {
+                        continue;
+                    }
+
+                    final HAProvider<HAResource> haProvider = validateAndFindHAProvider(haConfig, resource);
+                    if (haProvider == null) {
+                        continue;
+                    }
+
+                    switch (haConfig.getState()) {
+                        case Available:
+                        case Suspect:
+                        case Degraded:
+                        case Fenced:
+                            final HealthCheckTask task = ComponentContext.inject(new HealthCheckTask(resource, haProvider, haConfig,
+                                    HAProviderConfig.HealthCheckTimeout, healthCheckExecutor));
+                            healthCheckExecutor.submit(task);
+                            break;
+                    default:
+                        break;
+                    }
+
+                    final HAResourceCounter counter = getHACounter(haConfig.getResourceId(), haConfig.getResourceType());
+
+                    if (haConfig.getState() == HAConfig.HAState.Suspect) {
+                        if (counter.canPerformActivityCheck((Long)(haProvider.getConfigValue(HAProviderConfig.MaxActivityCheckInterval, resource)))) {
+                            transitionHAState(HAConfig.Event.PerformActivityCheck, haConfig);
+                        }
+                    }
+
+                    if (haConfig.getState() == HAConfig.HAState.Degraded) {
+                        if (counter.canRecheckActivity((Long)(haProvider.getConfigValue(HAProviderConfig.MaxDegradedWaitTimeout, resource)))) {
+                            transitionHAState(HAConfig.Event.PeriodicRecheckResourceActivity, haConfig);
+                        }
+                    }
+
+                    if (haConfig.getState() == HAConfig.HAState.Recovering) {
+                        if (counter.getRecoveryCounter() >= (Long) (haProvider.getConfigValue(HAProviderConfig.MaxRecoveryAttempts, resource))) {
+                            transitionHAState(HAConfig.Event.RecoveryOperationThresholdExceeded, haConfig);
+                        } else {
+                            transitionHAState(HAConfig.Event.RetryRecovery, haConfig);
+                        }
+                    }
+
+                    if (haConfig.getState() == HAConfig.HAState.Recovered) {
+                        counter.markRecoveryStarted();
+                        if (counter.canExitRecovery((Long)(haProvider.getConfigValue(HAProviderConfig.RecoveryWaitTimeout, resource)))) {
+                            if (transitionHAState(HAConfig.Event.RecoveryWaitPeriodTimeout, haConfig)) {
+                                counter.markRecoveryCompleted();
+                            }
+                        }
+                    }
+
+                    if (haConfig.getState() == HAConfig.HAState.Fencing && counter.canAttemptFencing()) {
+                        transitionHAState(HAConfig.Event.RetryFencing, haConfig);
+                    }
+                }
+            } catch (Throwable t) {
+                LOG.error("Error trying to perform health checks in HA manager", t);
+            }
+        }
+
+        @Override
+        public Long getDelay() {
+            return null;
+        }
+    }
+}
diff --git a/server/src/org/apache/cloudstack/ha/HAResourceCounter.java b/server/src/main/java/org/apache/cloudstack/ha/HAResourceCounter.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/HAResourceCounter.java
rename to server/src/main/java/org/apache/cloudstack/ha/HAResourceCounter.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/ActivityCheckerInterface.java b/server/src/main/java/org/apache/cloudstack/ha/provider/ActivityCheckerInterface.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/ActivityCheckerInterface.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/ActivityCheckerInterface.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HACheckerException.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HACheckerException.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HACheckerException.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HACheckerException.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HAFenceException.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HAFenceException.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HAFenceException.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HAFenceException.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HAProvider.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HAProvider.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HAProvider.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HAProvider.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HARecoveryException.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HARecoveryException.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HARecoveryException.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HARecoveryException.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HealthCheckerInterface.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HealthCheckerInterface.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HealthCheckerInterface.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HealthCheckerInterface.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/HostHAProvider.java b/server/src/main/java/org/apache/cloudstack/ha/provider/HostHAProvider.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/HostHAProvider.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/HostHAProvider.java
diff --git a/server/src/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java b/server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
rename to server/src/main/java/org/apache/cloudstack/ha/provider/host/HAAbstractHostProvider.java
diff --git a/server/src/org/apache/cloudstack/ha/task/ActivityCheckTask.java b/server/src/main/java/org/apache/cloudstack/ha/task/ActivityCheckTask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/task/ActivityCheckTask.java
rename to server/src/main/java/org/apache/cloudstack/ha/task/ActivityCheckTask.java
diff --git a/server/src/org/apache/cloudstack/ha/task/BaseHATask.java b/server/src/main/java/org/apache/cloudstack/ha/task/BaseHATask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/task/BaseHATask.java
rename to server/src/main/java/org/apache/cloudstack/ha/task/BaseHATask.java
diff --git a/server/src/org/apache/cloudstack/ha/task/FenceTask.java b/server/src/main/java/org/apache/cloudstack/ha/task/FenceTask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/task/FenceTask.java
rename to server/src/main/java/org/apache/cloudstack/ha/task/FenceTask.java
diff --git a/server/src/org/apache/cloudstack/ha/task/HealthCheckTask.java b/server/src/main/java/org/apache/cloudstack/ha/task/HealthCheckTask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/task/HealthCheckTask.java
rename to server/src/main/java/org/apache/cloudstack/ha/task/HealthCheckTask.java
diff --git a/server/src/org/apache/cloudstack/ha/task/RecoveryTask.java b/server/src/main/java/org/apache/cloudstack/ha/task/RecoveryTask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/ha/task/RecoveryTask.java
rename to server/src/main/java/org/apache/cloudstack/ha/task/RecoveryTask.java
diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
rename to server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
diff --git a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java b/server/src/main/java/org/apache/cloudstack/network/ssl/CertServiceImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
rename to server/src/main/java/org/apache/cloudstack/network/ssl/CertServiceImpl.java
diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java
diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java b/server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java
diff --git a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java b/server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
diff --git a/server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java b/server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
new file mode 100644
index 0000000..8efb163
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
@@ -0,0 +1,320 @@
+// 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.network.topology;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.routing.IpAliasTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.VpnUser;
+import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.router.CommandSetupHelper;
+import com.cloud.network.router.NetworkHelper;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.AdvancedVpnRules;
+import com.cloud.network.rules.BasicVpnRules;
+import com.cloud.network.rules.DhcpEntryRules;
+import com.cloud.network.rules.DhcpPvlanRules;
+import com.cloud.network.rules.DhcpSubNetRules;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRules;
+import com.cloud.network.rules.IpAssociationRules;
+import com.cloud.network.rules.LoadBalancingRules;
+import com.cloud.network.rules.NetworkAclsRules;
+import com.cloud.network.rules.NicPlugInOutRules;
+import com.cloud.network.rules.PasswordToRouterRules;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.PrivateGatewayRules;
+import com.cloud.network.rules.SshKeyToRouterRules;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StaticNatRule;
+import com.cloud.network.rules.StaticNatRules;
+import com.cloud.network.rules.StaticRoutesRules;
+import com.cloud.network.rules.UserdataPwdRules;
+import com.cloud.network.rules.UserdataToRouterRules;
+import com.cloud.network.rules.VirtualNetworkApplianceFactory;
+import com.cloud.network.rules.VpcIpAssociationRules;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicIpAliasVO;
+
+@Component
+public class BasicNetworkVisitor extends NetworkTopologyVisitor {
+
+    private static final Logger s_logger = Logger.getLogger(BasicNetworkVisitor.class);
+
+    @Autowired
+    @Qualifier("networkHelper")
+    protected NetworkHelper _networkGeneralHelper;
+
+    @Inject
+    protected VirtualNetworkApplianceFactory _virtualNetworkApplianceFactory;
+
+    @Inject
+    protected CommandSetupHelper _commandSetupHelper;
+
+    @Override
+    public VirtualNetworkApplianceFactory getVirtualNetworkApplianceFactory() {
+        return _virtualNetworkApplianceFactory;
+    }
+
+    @Override
+    public boolean visit(final StaticNatRules nat) throws ResourceUnavailableException {
+        final Network network = nat.getNetwork();
+        final VirtualRouter router = nat.getRouter();
+        final List<? extends StaticNat> rules = nat.getRules();
+
+        final Commands cmds = new Commands(Command.OnError.Continue);
+        _commandSetupHelper.createApplyStaticNatCommands(rules, router, cmds, network.getId());
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    @Override
+    public boolean visit(final LoadBalancingRules loadbalancing) throws ResourceUnavailableException {
+        final Network network = loadbalancing.getNetwork();
+        final DomainRouterVO router = (DomainRouterVO) loadbalancing.getRouter();
+        final List<LoadBalancingRule> rules = loadbalancing.getRules();
+
+        final Commands cmds = new Commands(Command.OnError.Continue);
+        _commandSetupHelper.createApplyLoadBalancingRulesCommands(rules, router, cmds, network.getId());
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean visit(final FirewallRules firewall) throws ResourceUnavailableException {
+        final Network network = firewall.getNetwork();
+        final VirtualRouter router = firewall.getRouter();
+        final List<? extends FirewallRule> rules = firewall.getRules();
+        final List<LoadBalancingRule> loadbalancingRules = firewall.getLoadbalancingRules();
+
+        final Purpose purpose = firewall.getPurpose();
+
+        final Commands cmds = new Commands(Command.OnError.Continue);
+        if (purpose == Purpose.LoadBalancing) {
+
+            _commandSetupHelper.createApplyLoadBalancingRulesCommands(loadbalancingRules, router, cmds, network.getId());
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+
+        } else if (purpose == Purpose.PortForwarding) {
+
+            _commandSetupHelper.createApplyPortForwardingRulesCommands((List<? extends PortForwardingRule>) rules, router, cmds, network.getId());
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+
+        } else if (purpose == Purpose.StaticNat) {
+
+            _commandSetupHelper.createApplyStaticNatRulesCommands((List<StaticNatRule>) rules, router, cmds, network.getId());
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+
+        } else if (purpose == Purpose.Firewall) {
+
+            _commandSetupHelper.createApplyFirewallRulesCommands(rules, router, cmds, network.getId());
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+
+        }
+        s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose());
+
+        return false;
+    }
+
+    @Override
+    public boolean visit(final IpAssociationRules ipRules) throws ResourceUnavailableException {
+        final Network network = ipRules.getNetwork();
+        final VirtualRouter router = ipRules.getRouter();
+
+        final Commands commands = new Commands(Command.OnError.Continue);
+        final List<? extends PublicIpAddress> ips = ipRules.getIpAddresses();
+
+        _commandSetupHelper.createAssociateIPCommands(router, ips, commands, network.getId());
+        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
+    }
+
+    @Override
+    public boolean visit(final UserdataPwdRules userdata) throws ResourceUnavailableException {
+        final VirtualRouter router = userdata.getRouter();
+
+        final Commands commands = new Commands(Command.OnError.Stop);
+        final VirtualMachineProfile profile = userdata.getProfile();
+        final NicVO nicVo = userdata.getNicVo();
+        final UserVmVO userVM = userdata.getUserVM();
+        final DeployDestination destination = userdata.getDestination();
+
+        if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {
+            _commandSetupHelper.createPasswordCommand(router, profile, nicVo, commands);
+            _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, userVM.getDetail("SSH.PublicKey"), commands);
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, commands);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean visit(final DhcpEntryRules dhcp) throws ResourceUnavailableException {
+        final VirtualRouter router = dhcp.getRouter();
+
+        final Commands commands = new Commands(Command.OnError.Stop);
+        final NicVO nicVo = dhcp.getNicVo();
+        final UserVmVO userVM = dhcp.getUserVM();
+        final DeployDestination destination = dhcp.getDestination();
+        final boolean remove = dhcp.isRemove();
+
+        if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {
+            _commandSetupHelper.createDhcpEntryCommand(router, userVM, nicVo, remove, commands);
+
+            return _networkGeneralHelper.sendCommandsToRouter(router, commands);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean visit(final SshKeyToRouterRules sshkey) throws ResourceUnavailableException {
+        final VirtualRouter router = sshkey.getRouter();
+        final VirtualMachineProfile profile = sshkey.getProfile();
+        final String sshKeystr = sshkey.getSshPublicKey();
+        final UserVmVO userVM = sshkey.getUserVM();
+
+        final Commands commands = new Commands(Command.OnError.Stop);
+        final NicVO nicVo = sshkey.getNicVo();
+        final VMTemplateVO template = sshkey.getTemplate();
+
+        if (template != null && template.isEnablePassword()) {
+            _commandSetupHelper.createPasswordCommand(router, profile, nicVo, commands);
+        }
+
+        _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, sshKeystr, commands);
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
+    }
+
+    @Override
+    public boolean visit(final PasswordToRouterRules passwd) throws ResourceUnavailableException {
+        final VirtualRouter router = passwd.getRouter();
+        final NicVO nicVo = passwd.getNicVo();
+        final VirtualMachineProfile profile = passwd.getProfile();
+
+        final Commands cmds = new Commands(Command.OnError.Stop);
+        _commandSetupHelper.createPasswordCommand(router, profile, nicVo, cmds);
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    @Override
+    public boolean visit(final UserdataToRouterRules userdata) throws ResourceUnavailableException {
+        final VirtualRouter router = userdata.getRouter();
+
+        final UserVmVO userVM = userdata.getUserVM();
+        final NicVO nicVo = userdata.getNicVo();
+
+        final Commands commands = new Commands(Command.OnError.Stop);
+        _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, null, commands);
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
+    }
+
+    @Override
+    public boolean visit(final BasicVpnRules vpnRules) throws ResourceUnavailableException {
+        final VirtualRouter router = vpnRules.getRouter();
+        final List<? extends VpnUser> users = vpnRules.getUsers();
+
+        final Commands cmds = new Commands(Command.OnError.Continue);
+        _commandSetupHelper.createApplyVpnUsersCommand(users, router, cmds);
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    @Override
+    public boolean visit(final DhcpSubNetRules subnet) throws ResourceUnavailableException {
+        final VirtualRouter router = subnet.getRouter();
+        final Network network = subnet.getNetwork();
+        final NicIpAliasVO nicAlias = subnet.getNicAlias();
+        final String routerAliasIp = subnet.getRouterAliasIp();
+
+        final Commands cmds = new Commands(Command.OnError.Stop);
+
+        final List<IpAliasTO> ipaliasTo = new ArrayList<IpAliasTO>();
+        ipaliasTo.add(new IpAliasTO(routerAliasIp, nicAlias.getNetmask(), nicAlias.getAliasCount().toString()));
+
+        _commandSetupHelper.createIpAlias(router, ipaliasTo, nicAlias.getNetworkId(), cmds);
+
+        // also add the required configuration to the dnsmasq for supporting
+        // dhcp and dns on the new ip.
+        _commandSetupHelper.configDnsMasq(router, network, cmds);
+
+        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
+    }
+
+    @Override
+    public boolean visit(final DhcpPvlanRules dhcpRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("DhcpPvlanRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final NicPlugInOutRules nicPlugInOutRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("NicPlugInOutRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final NetworkAclsRules aclsRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("NetworkAclsRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final VpcIpAssociationRules ipRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("VpcIpAssociationRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final PrivateGatewayRules pvtGatewayRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("PrivateGatewayRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final StaticRoutesRules staticRoutesRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("StaticRoutesRules not implemented in Basic Network Topology.");
+    }
+
+    @Override
+    public boolean visit(final AdvancedVpnRules vpnRules) throws ResourceUnavailableException {
+        throw new CloudRuntimeException("AdvancedVpnRules not implemented in Basic Network Topology.");
+    }
+}
\ No newline at end of file
diff --git a/server/src/org/apache/cloudstack/network/topology/NetworkTopology.java b/server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopology.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/NetworkTopology.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopology.java
diff --git a/server/src/org/apache/cloudstack/network/topology/NetworkTopologyContext.java b/server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopologyContext.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/NetworkTopologyContext.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopologyContext.java
diff --git a/server/src/org/apache/cloudstack/network/topology/NetworkTopologyVisitor.java b/server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopologyVisitor.java
similarity index 100%
rename from server/src/org/apache/cloudstack/network/topology/NetworkTopologyVisitor.java
rename to server/src/main/java/org/apache/cloudstack/network/topology/NetworkTopologyVisitor.java
diff --git a/server/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java b/server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java
rename to server/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceImpl.java
diff --git a/server/src/org/apache/cloudstack/outofbandmanagement/PowerOperationTask.java b/server/src/main/java/org/apache/cloudstack/outofbandmanagement/PowerOperationTask.java
similarity index 100%
rename from server/src/org/apache/cloudstack/outofbandmanagement/PowerOperationTask.java
rename to server/src/main/java/org/apache/cloudstack/outofbandmanagement/PowerOperationTask.java
diff --git a/server/src/org/apache/cloudstack/poll/BackgroundPollManagerImpl.java b/server/src/main/java/org/apache/cloudstack/poll/BackgroundPollManagerImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/poll/BackgroundPollManagerImpl.java
rename to server/src/main/java/org/apache/cloudstack/poll/BackgroundPollManagerImpl.java
diff --git a/server/src/org/apache/cloudstack/region/RegionAccount.java b/server/src/main/java/org/apache/cloudstack/region/RegionAccount.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionAccount.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionAccount.java
diff --git a/server/src/org/apache/cloudstack/region/RegionDomain.java b/server/src/main/java/org/apache/cloudstack/region/RegionDomain.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionDomain.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionDomain.java
diff --git a/server/src/org/apache/cloudstack/region/RegionManager.java b/server/src/main/java/org/apache/cloudstack/region/RegionManager.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionManager.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionManager.java
diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/main/java/org/apache/cloudstack/region/RegionManagerImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionManagerImpl.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionManagerImpl.java
diff --git a/server/src/org/apache/cloudstack/region/RegionServiceImpl.java b/server/src/main/java/org/apache/cloudstack/region/RegionServiceImpl.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionServiceImpl.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionServiceImpl.java
diff --git a/server/src/org/apache/cloudstack/region/RegionServiceProvider.java b/server/src/main/java/org/apache/cloudstack/region/RegionServiceProvider.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionServiceProvider.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionServiceProvider.java
diff --git a/server/src/org/apache/cloudstack/region/RegionUser.java b/server/src/main/java/org/apache/cloudstack/region/RegionUser.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionUser.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionUser.java
diff --git a/server/src/org/apache/cloudstack/region/RegionsApiUtil.java b/server/src/main/java/org/apache/cloudstack/region/RegionsApiUtil.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/RegionsApiUtil.java
rename to server/src/main/java/org/apache/cloudstack/region/RegionsApiUtil.java
diff --git a/server/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java
new file mode 100644
index 0000000..baa3ba0
--- /dev/null
+++ b/server/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java
@@ -0,0 +1,728 @@
+// 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.region.gslb;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.ListGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.RemoveFromGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.api.command.user.region.ha.gslb.UpdateGlobalLoadBalancerRuleCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.region.Region;
+import org.apache.cloudstack.region.dao.RegionDao;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
+import com.cloud.agent.api.routing.SiteLoadBalancerConfig;
+import com.cloud.configuration.Config;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.region.ha.GlobalLoadBalancerRule;
+import com.cloud.region.ha.GlobalLoadBalancingRulesService;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingRulesService {
+
+    private static final Logger s_logger = Logger.getLogger(GlobalLoadBalancingRulesServiceImpl.class);
+
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    GlobalLoadBalancerRuleDao _gslbRuleDao;
+    @Inject
+    GlobalLoadBalancerLbRuleMapDao _gslbLbMapDao;
+    @Inject
+    RegionDao _regionDao;
+    @Inject
+    RulesManager _rulesMgr;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    ConfigurationDao _globalConfigDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
+    @Inject
+    AgentManager _agentMgr;
+
+    protected List<GslbServiceProvider> _gslbProviders;
+
+    public void setGslbServiceProviders(List<GslbServiceProvider> providers) {
+        _gslbProviders = providers;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, eventDescription = "creating global load " + "balancer rule", create = true)
+    public GlobalLoadBalancerRule createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newRule) {
+
+        final Integer regionId = newRule.getRegionId();
+        final String algorithm = newRule.getAlgorithm();
+        final String stickyMethod = newRule.getStickyMethod();
+        final String name = newRule.getName();
+        final String description = newRule.getDescription();
+        final String domainName = newRule.getServiceDomainName();
+        final String serviceType = newRule.getServiceType();
+
+        final Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId());
+
+        if (!GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
+            throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
+        }
+
+        if (!GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
+            throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
+        }
+
+        if (!GlobalLoadBalancerRule.ServiceType.isValidServiceType(serviceType)) {
+            throw new InvalidParameterValueException("Invalid service type: " + serviceType);
+        }
+
+        if (!NetUtils.verifyDomainName(domainName)) {
+            throw new InvalidParameterValueException("Invalid domain name : " + domainName);
+        }
+
+        GlobalLoadBalancerRuleVO gslbRuleWithDomainName = _gslbRuleDao.findByDomainName(domainName);
+        if (gslbRuleWithDomainName != null) {
+            throw new InvalidParameterValueException("Domain name " + domainName + "is in use");
+        }
+
+        Region region = _regionDao.findById(regionId);
+        if (region == null) {
+            throw new InvalidParameterValueException("Invalid region ID: " + regionId);
+        }
+
+        String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
+        if (!region.checkIfServiceEnabled(Region.Service.Gslb) || (providerDnsName == null)) {
+            throw new CloudRuntimeException("GSLB service is not enabled in region : " + region.getName());
+        }
+
+        GlobalLoadBalancerRuleVO newGslbRule = Transaction.execute(new TransactionCallback<GlobalLoadBalancerRuleVO>() {
+            @Override
+            public GlobalLoadBalancerRuleVO doInTransaction(TransactionStatus status) {
+                GlobalLoadBalancerRuleVO newGslbRule =
+                    new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, stickyMethod, serviceType, regionId, gslbOwner.getId(),
+                        gslbOwner.getDomainId(), GlobalLoadBalancerRule.State.Staged);
+                _gslbRuleDao.persist(newGslbRule);
+
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), 0, newGslbRule.getId(), name,
+                    GlobalLoadBalancerRule.class.getName(), newGslbRule.getUuid());
+
+                return newGslbRule;
+            }
+        });
+
+        s_logger.debug("successfully created new global load balancer rule for the account " + gslbOwner.getId());
+
+        return newGslbRule;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE,
+                 eventDescription = "Assigning a load balancer rule to global load balancer rule",
+                 async = true)
+    public boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd) {
+
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        final long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId();
+        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
+        if (gslbRule == null) {
+            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
+        }
+
+        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
+
+        if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
+            throw new InvalidParameterValueException("global load balancer rule id: " + gslbRule.getUuid() + " is in revoked state");
+        }
+
+        final List<Long> newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds();
+        if (newLbRuleIds == null || newLbRuleIds.isEmpty()) {
+            throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be assigned" + " global load balancer rule");
+        }
+
+        List<Long> oldLbRuleIds = new ArrayList<Long>();
+        List<Long> oldZones = new ArrayList<Long>();
+        List<Long> newZones = new ArrayList<Long>(oldZones);
+        List<Pair<Long, Long>> physcialNetworks = new ArrayList<Pair<Long, Long>>();
+
+        // get the list of load balancer rules id's that are assigned currently to GSLB rule and corresponding zone id's
+        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
+        if (gslbLbMapVos != null) {
+            for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
+                LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
+                Network network = _networkDao.findById(loadBalancer.getNetworkId());
+                oldZones.add(network.getDataCenterId());
+                oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
+            }
+        }
+
+        /* check each of the load balancer rule id passed in the 'AssignToGlobalLoadBalancerRuleCmd' command is
+         *     valid ID
+         *     caller has access to the rule
+         *     check rule is not revoked
+         *     no two rules are in same zone
+         *     rule is not already assigned to gslb rule
+         */
+        for (Long lbRuleId : newLbRuleIds) {
+
+            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
+            if (loadBalancer == null) {
+                throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
+            }
+
+            _accountMgr.checkAccess(caller, null, true, loadBalancer);
+
+            if (gslbRule.getAccountId() != loadBalancer.getAccountId()) {
+                throw new InvalidParameterValueException("GSLB rule and load balancer rule does not belong to same account");
+            }
+
+            if (loadBalancer.getState() == LoadBalancer.State.Revoke) {
+                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is in revoke state");
+            }
+
+            if (oldLbRuleIds != null && oldLbRuleIds.contains(loadBalancer.getId())) {
+                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is already assigned");
+            }
+
+            Network network = _networkDao.findById(loadBalancer.getNetworkId());
+
+            if (oldZones != null && oldZones.contains(network.getDataCenterId()) || newZones != null && newZones.contains(network.getDataCenterId())) {
+                throw new InvalidParameterValueException("Load balancer rule specified should be in unique zone");
+            }
+
+            newZones.add(network.getDataCenterId());
+            physcialNetworks.add(new Pair<Long, Long>(network.getDataCenterId(), network.getPhysicalNetworkId()));
+        }
+
+        // for each of the physical network check if GSLB service provider configured
+        for (Pair<Long, Long> physicalNetwork : physcialNetworks) {
+            if (!checkGslbServiceEnabledInZone(physicalNetwork.first(), physicalNetwork.second())) {
+                throw new InvalidParameterValueException("GSLB service is not enabled in the Zone:" + physicalNetwork.first() + " and physical network " +
+                    physicalNetwork.second());
+            }
+        }
+
+        final Map<Long, Long> lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap();
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // persist the mapping for the new Lb rule that needs to assigned to a gslb rule
+                for (Long lbRuleId : newLbRuleIds) {
+                    GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO();
+                    newGslbLbMap.setGslbLoadBalancerId(gslbRuleId);
+                    newGslbLbMap.setLoadBalancerId(lbRuleId);
+                    if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) {
+                        newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId));
+                    }
+                    _gslbLbMapDao.persist(newGslbLbMap);
+                }
+
+                // mark the gslb rule state as add
+                if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
+                    gslbRule.setState(GlobalLoadBalancerRule.State.Add);
+                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+                }
+            }
+        });
+
+        boolean success = false;
+        try {
+            s_logger.debug("Configuring gslb rule configuration on the gslb service providers in the participating zones");
+
+            // apply the gslb rule on to the back end gslb service providers on zones participating in gslb
+            if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
+                s_logger.warn("Failed to add load balancer rules " + newLbRuleIds + " to global load balancer rule id " + gslbRuleId);
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to add load balancer rules to GSLB rule ");
+                throw ex;
+            }
+
+            // on success set state to Active
+            gslbRule.setState(GlobalLoadBalancerRule.State.Active);
+            _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+
+            success = true;
+
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Failed to apply new GSLB configuration while assigning new LB rules to GSLB rule.");
+        }
+
+        return success;
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_GLOBAL_LOAD_BALANCER_RULE,
+                 eventDescription = "Removing a load balancer rule to be part of global load balancer rule")
+    public boolean removeFromGlobalLoadBalancerRule(RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd) {
+
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        final long gslbRuleId = removeFromGslbCmd.getGlobalLoadBalancerRuleId();
+        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
+        if (gslbRule == null) {
+            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
+        }
+
+        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
+
+        if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
+            throw new InvalidParameterValueException("global load balancer rule id: " + gslbRuleId + " is already in revoked state");
+        }
+
+        final List<Long> lbRuleIdsToremove = removeFromGslbCmd.getLoadBalancerRulesIds();
+        if (lbRuleIdsToremove == null || lbRuleIdsToremove.isEmpty()) {
+            throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be un-assigned" + " to global load balancer rule");
+        }
+
+        // get the active list of LB rule id's that are assigned currently to GSLB rule and corresponding zone id's
+        List<Long> oldLbRuleIds = new ArrayList<Long>();
+        List<Long> oldZones = new ArrayList<Long>();
+
+        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
+        if (gslbLbMapVos == null) {
+            throw new InvalidParameterValueException(" There are no load balancer rules that are assigned to global " + " load balancer rule id: " + gslbRule.getUuid() +
+                " that are available for deletion");
+        }
+
+        for (Long lbRuleId : lbRuleIdsToremove) {
+            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
+            if (loadBalancer == null) {
+                throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
+            }
+
+            _accountMgr.checkAccess(caller, null, true, loadBalancer);
+        }
+
+        for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
+            LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
+            Network network = _networkDao.findById(loadBalancer.getNetworkId());
+            oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
+            oldZones.add(network.getDataCenterId());
+        }
+
+        for (Long lbRuleId : lbRuleIdsToremove) {
+            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
+            if (oldLbRuleIds != null && !oldLbRuleIds.contains(loadBalancer.getId())) {
+                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is not assigned" + " to global load balancer rule: " +
+                    gslbRule.getUuid());
+            }
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                // update the mapping of gslb rule to Lb rule, to revoke state
+                for (Long lbRuleId : lbRuleIdsToremove) {
+                    GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId);
+                    removeGslbLbMap.setRevoke(true);
+                    _gslbLbMapDao.update(removeGslbLbMap.getId(), removeGslbLbMap);
+                }
+
+                // mark the gslb rule state as add
+                if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged) {
+                    gslbRule.setState(GlobalLoadBalancerRule.State.Add);
+                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+                }
+
+            }
+        });
+
+        boolean success = false;
+        try {
+            s_logger.debug("Attempting to configure global load balancer rule configuration on the gslb service providers ");
+
+            // apply the gslb rule on to the back end gslb service providers
+            if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
+                s_logger.warn("Failed to remove load balancer rules " + lbRuleIdsToremove + " from global load balancer rule id " + gslbRuleId);
+                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove load balancer rule ids from GSLB rule ");
+                throw ex;
+            }
+
+            Transaction.execute(new TransactionCallbackNoReturn() {
+                @Override
+                public void doInTransactionWithoutResult(TransactionStatus status) {
+                    // remove the mappings of gslb rule to Lb rule that are in revoked state
+                    for (Long lbRuleId : lbRuleIdsToremove) {
+                        GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId);
+                        _gslbLbMapDao.remove(removeGslbLbMap.getId());
+                    }
+
+                    // on success set state back to Active
+                    gslbRule.setState(GlobalLoadBalancerRule.State.Active);
+                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+
+                }
+            });
+
+            success = true;
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Failed to update removed load balancer details from gloabal load balancer");
+        }
+
+        return success;
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, eventDescription = "Delete global load balancer rule")
+    public boolean deleteGlobalLoadBalancerRule(DeleteGlobalLoadBalancerRuleCmd deleteGslbCmd) {
+
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+        long gslbRuleId = deleteGslbCmd.getGlobalLoadBalancerId();
+
+        try {
+            revokeGslbRule(gslbRuleId, caller);
+        } catch (Exception e) {
+            s_logger.warn("Failed to delete GSLB rule due to" + e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    @DB
+    private void revokeGslbRule(final long gslbRuleId, Account caller) {
+
+        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
+
+        if (gslbRule == null) {
+            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
+        }
+
+        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
+
+        if (gslbRule.getState() == com.cloud.region.ha.GlobalLoadBalancerRule.State.Staged) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Rule Id: " + gslbRuleId + " is still in Staged state so just removing it.");
+            }
+            _gslbRuleDao.remove(gslbRuleId);
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(),
+                GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
+            return;
+        } else if (gslbRule.getState() == GlobalLoadBalancerRule.State.Add || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
+            //mark the GSlb rule to be in revoke state
+            gslbRule.setState(GlobalLoadBalancerRule.State.Revoke);
+            _gslbRuleDao.update(gslbRuleId, gslbRule);
+        }
+
+        final List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = Transaction.execute(new TransactionCallback<List<GlobalLoadBalancerLbRuleMapVO>>() {
+            @Override
+            public List<GlobalLoadBalancerLbRuleMapVO> doInTransaction(TransactionStatus status) {
+                List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
+                if (gslbLbMapVos != null) {
+                    //mark all the GSLB-LB mapping to be in revoke state
+                    for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
+                        gslbLbMap.setRevoke(true);
+                        _gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap);
+                    }
+                }
+
+                return gslbLbMapVos;
+            }
+        });
+
+        try {
+            if (gslbLbMapVos != null) {
+                applyGlobalLoadBalancerRuleConfig(gslbRuleId, true);
+            }
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Failed to update the gloabal load balancer");
+        }
+
+        Transaction.execute(new TransactionCallbackNoReturn() {
+            @Override
+            public void doInTransactionWithoutResult(TransactionStatus status) {
+                //remove all mappings between GSLB rule and load balancer rules
+                if (gslbLbMapVos != null) {
+                    for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
+                        _gslbLbMapDao.remove(gslbLbMap.getId());
+                    }
+                }
+
+                //remove the GSLB rule itself
+                _gslbRuleDao.remove(gslbRuleId);
+
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(),
+                    GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
+            }
+        });
+
+    }
+
+    @Override
+    public GlobalLoadBalancerRule updateGlobalLoadBalancerRule(UpdateGlobalLoadBalancerRuleCmd updateGslbCmd) {
+
+        String algorithm = updateGslbCmd.getAlgorithm();
+        String stickyMethod = updateGslbCmd.getStickyMethod();
+        String description = updateGslbCmd.getDescription();
+
+        long gslbRuleId = updateGslbCmd.getId();
+        GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
+        if (gslbRule == null) {
+            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
+        }
+
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
+
+        if (algorithm != null && !GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
+            throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
+        }
+
+        if (stickyMethod != null && !GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
+            throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
+        }
+
+        if (algorithm != null) {
+            gslbRule.setAlgorithm(algorithm);
+        }
+        if (stickyMethod != null) {
+            gslbRule.setPersistence(stickyMethod);
+        }
+        if (description != null) {
+            gslbRule.setDescription(description);
+        }
+        gslbRule.setState(GlobalLoadBalancerRule.State.Add);
+        _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+
+        try {
+            s_logger.debug("Updating global load balancer with id " + gslbRule.getUuid());
+
+            // apply the gslb rule on to the back end gslb service providers on zones participating in gslb
+            applyGlobalLoadBalancerRuleConfig(gslbRuleId, false);
+
+            // on success set state to Active
+            gslbRule.setState(GlobalLoadBalancerRule.State.Active);
+            _gslbRuleDao.update(gslbRule.getId(), gslbRule);
+
+            return gslbRule;
+        } catch (ResourceUnavailableException e) {
+            throw new CloudRuntimeException("Failed to configure gslb config due to " + e.getMessage());
+        }
+    }
+
+    @Override
+    public List<GlobalLoadBalancerRule> listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd) {
+
+        CallContext ctx = CallContext.current();
+        Account caller = ctx.getCallingAccount();
+
+        Integer regionId = listGslbCmd.getRegionId();
+        Long ruleId = listGslbCmd.getId();
+        List<GlobalLoadBalancerRule> response = new ArrayList<GlobalLoadBalancerRule>();
+        if (regionId == null && ruleId == null) {
+            throw new InvalidParameterValueException("Invalid arguments. At least one of region id, " + "rule id must be specified");
+        }
+
+        if (regionId != null && ruleId != null) {
+            throw new InvalidParameterValueException("Invalid arguments. Only one of region id, " + "rule id must be specified");
+        }
+
+        if (ruleId != null) {
+            GlobalLoadBalancerRule gslbRule = _gslbRuleDao.findById(ruleId);
+            if (gslbRule == null) {
+                throw new InvalidParameterValueException("Invalid gslb rule id specified");
+            }
+            _accountMgr.checkAccess(caller, org.apache.cloudstack.acl.SecurityChecker.AccessType.UseEntry, false, gslbRule);
+
+            response.add(gslbRule);
+            return response;
+        }
+
+        if (regionId != null) {
+            List<GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(caller.getAccountId());
+            if (gslbRules != null) {
+                response.addAll(gslbRules);
+            }
+            return response;
+        }
+
+        return null;
+    }
+
+    @Override
+    public List<LoadBalancer> listSiteLoadBalancers(long gslbRuleId) {
+        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
+        List<LoadBalancer> siteLoadBalancers = new ArrayList<LoadBalancer>();
+        if (gslbLbMapVos != null) {
+            for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
+                LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
+                siteLoadBalancers.add(loadBalancer);
+            }
+            return siteLoadBalancers;
+        }
+        return null;
+    }
+
+    private boolean applyGlobalLoadBalancerRuleConfig(long gslbRuleId, boolean revoke) throws ResourceUnavailableException {
+
+        GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
+        assert (gslbRule != null);
+
+        String lbMethod = gslbRule.getAlgorithm();
+        String persistenceMethod = gslbRule.getPersistence();
+        String serviceType = gslbRule.getServiceType();
+
+        // each Gslb rule will have a FQDN, formed from the domain name associated with the gslb rule
+        // and the deployment DNS name configured in global config parameter 'cloud.dns.name'
+        String domainName = gslbRule.getGslbDomain();
+        String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
+        String gslbFqdn = domainName + "." + providerDnsName;
+
+        GlobalLoadBalancerConfigCommand gslbConfigCmd = new GlobalLoadBalancerConfigCommand(gslbFqdn, lbMethod, persistenceMethod, serviceType, gslbRuleId, revoke);
+
+        // list of the physical network participating in global load balancing
+        List<Pair<Long, Long>> gslbSiteIds = new ArrayList<Pair<Long, Long>>();
+
+        // map of the zone and info corresponding to the load balancer configured in the zone
+        Map<Long, SiteLoadBalancerConfig> zoneSiteLoadbalancerMap = new HashMap<Long, SiteLoadBalancerConfig>();
+
+        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
+
+        assert (gslbLbMapVos != null && !gslbLbMapVos.isEmpty());
+
+        for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
+
+            // get the zone in which load balancer rule is deployed
+            LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
+            Network network = _networkDao.findById(loadBalancer.getNetworkId());
+            long dataCenterId = network.getDataCenterId();
+            long physicalNetworkId = network.getPhysicalNetworkId();
+
+            gslbSiteIds.add(new Pair<Long, Long>(dataCenterId, physicalNetworkId));
+
+            IPAddressVO ip = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId());
+            SiteLoadBalancerConfig siteLb =
+                new SiteLoadBalancerConfig(gslbLbMapVo.isRevoke(), serviceType, ip.getAddress().addr(), Integer.toString(loadBalancer.getDefaultPortStart()),
+                    dataCenterId);
+            GslbServiceProvider gslbProvider = lookupGslbServiceProvider();
+            if (gslbProvider == null) {
+                throw new CloudRuntimeException("No GSLB provider is available");
+            }
+            siteLb.setGslbProviderPublicIp(gslbProvider.getZoneGslbProviderPublicIp(dataCenterId, physicalNetworkId));
+            siteLb.setGslbProviderPrivateIp(gslbProvider.getZoneGslbProviderPrivateIp(dataCenterId, physicalNetworkId));
+            siteLb.setWeight(gslbLbMapVo.getWeight());
+
+            zoneSiteLoadbalancerMap.put(network.getDataCenterId(), siteLb);
+        }
+
+        // loop through all the zones, participating in GSLB, and send GSLB config command
+        // to the corresponding GSLB service provider in that zone
+        for (Pair<Long, Long> zoneId : gslbSiteIds) {
+
+            List<SiteLoadBalancerConfig> slbs = new ArrayList<SiteLoadBalancerConfig>();
+            // set site as 'local' for the site in that zone
+            for (Pair<Long, Long> innerLoopZoneId : gslbSiteIds) {
+                SiteLoadBalancerConfig siteLb = zoneSiteLoadbalancerMap.get(innerLoopZoneId.first());
+                siteLb.setLocal(zoneId.first() == innerLoopZoneId.first());
+                slbs.add(siteLb);
+            }
+
+            gslbConfigCmd.setSiteLoadBalancers(slbs);
+            gslbConfigCmd.setForRevoke(revoke);
+
+            // revoke GSLB configuration completely on the site GSLB provider for the sites that no longer
+            // are participants of a GSLB rule
+            SiteLoadBalancerConfig siteLb = zoneSiteLoadbalancerMap.get(zoneId.first());
+            if (siteLb.forRevoke()) {
+                gslbConfigCmd.setForRevoke(true);
+            }
+
+            try {
+                lookupGslbServiceProvider().applyGlobalLoadBalancerRule(zoneId.first(), zoneId.second(), gslbConfigCmd);
+            } catch (ResourceUnavailableException | NullPointerException e) {
+                String msg = "Failed to configure GSLB rule in the zone " + zoneId.first() + " due to " + e.getMessage();
+                s_logger.warn(msg);
+                throw new CloudRuntimeException(msg);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean revokeAllGslbRulesForAccount(com.cloud.user.Account caller, long accountId) throws com.cloud.exception.ResourceUnavailableException {
+        List<GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(accountId);
+        if (gslbRules != null && !gslbRules.isEmpty()) {
+            for (GlobalLoadBalancerRule gslbRule : gslbRules) {
+                revokeGslbRule(gslbRule.getId(), caller);
+            }
+        }
+        s_logger.debug("Successfully cleaned up GSLB rules for account id=" + accountId);
+        return true;
+    }
+
+    private boolean checkGslbServiceEnabledInZone(long zoneId, long physicalNetworkId) {
+
+        GslbServiceProvider gslbProvider = lookupGslbServiceProvider();
+        if (gslbProvider == null) {
+            throw new CloudRuntimeException("No GSLB provider is available");
+        }
+
+        return gslbProvider.isServiceEnabledInZone(zoneId, physicalNetworkId);
+    }
+
+    protected GslbServiceProvider lookupGslbServiceProvider() {
+        return _gslbProviders.size() == 0 ? null : _gslbProviders.get(0);
+    }
+
+    @Override
+    public GlobalLoadBalancerRule findById(long gslbRuleId) {
+        return _gslbRuleDao.findById(gslbRuleId);
+    }
+}
\ No newline at end of file
diff --git a/server/src/org/apache/cloudstack/region/gslb/GslbServiceProvider.java b/server/src/main/java/org/apache/cloudstack/region/gslb/GslbServiceProvider.java
similarity index 100%
rename from server/src/org/apache/cloudstack/region/gslb/GslbServiceProvider.java
rename to server/src/main/java/org/apache/cloudstack/region/gslb/GslbServiceProvider.java
diff --git a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java b/server/src/main/java/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
similarity index 100%
rename from server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
rename to server/src/main/java/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
diff --git a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java b/server/src/main/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
similarity index 100%
rename from server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
rename to server/src/main/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
diff --git a/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java b/server/src/main/java/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
similarity index 100%
rename from server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
rename to server/src/main/java/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
diff --git a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
new file mode 100644
index 0000000..2f67c42
--- /dev/null
+++ b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
@@ -0,0 +1,303 @@
+<!--
+  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"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xmlns:util="http://www.springframework.org/schema/util"
+       
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/aop 
+                      http://www.springframework.org/schema/aop/spring-aop.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context.xsd
+                      http://www.springframework.org/schema/util
+                      http://www.springframework.org/schema/util/spring-util.xsd"
+                      >
+
+    <bean id="authenticationManagerImpl" class="com.cloud.api.auth.APIAuthenticationManagerImpl">
+        <property name="apiAuthenticators"
+                  value="#{pluggableAPIAuthenticatorsRegistry.registered}" />
+    </bean>
+
+    <bean id="roleManagerImpl" class="org.apache.cloudstack.acl.RoleManagerImpl" />
+
+    <bean id="accountManagerImpl" class="com.cloud.user.AccountManagerImpl">
+        <property name="userAuthenticators"
+            value="#{userAuthenticatorsRegistry.registered}" />
+        <property name="userPasswordEncoders"
+            value="#{userPasswordEncodersRegistry.registered}" />
+        <property name="securityCheckers" value="#{securityCheckersRegistry.registered}" />
+        <property name="querySelectors" value="#{querySelectorsRegistry.registered}" />        
+    </bean>
+
+    <bean id="managementServerImpl" class="com.cloud.server.ManagementServerImpl">
+        <property name="lockMasterListener" ref="lockMasterListener" />
+        <property name="userAuthenticators"
+            value="#{userAuthenticatorsRegistry.registered}" />
+        <property name="userPasswordEncoders"
+            value="#{userPasswordEncodersRegistry.registered}" />
+        <property name="hostAllocators" value="#{hostAllocatorsRegistry.registered}" />
+        <property name="affinityGroupProcessors"
+            value="#{affinityProcessorsRegistry.registered}" />
+        <property name="planners"
+            value="#{deploymentPlannersRegistry.registered}" />
+        <property name="storagePoolAllocators"
+            value="#{storagePoolAllocatorsRegistry.registered}" />
+    </bean>
+
+    <bean id="storageManagerImpl" class="com.cloud.storage.StorageManagerImpl" />
+
+    <bean id="resourceManagerImpl" class="com.cloud.resource.ResourceManagerImpl">
+        <property name="discoverers"
+            value="#{resourceDiscoverersRegistry.registered}" />
+    </bean>
+
+    <!-- the new background poll manager -->
+    <bean id="bgPollManager" class="org.apache.cloudstack.poll.BackgroundPollManagerImpl">
+    </bean>
+
+    <!-- the new HA manager -->
+    <bean id="haManagerImpl" class="org.apache.cloudstack.ha.HAManagerImpl">
+        <property name="haProviders" value="#{haProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl">
+        <property name="investigators" value="#{haInvestigatorsRegistry.registered}" />
+        <property name="fenceBuilders" value="#{haFenceBuildersRegistry.registered}" />
+        <property name="haPlanners" value="#{haPlannersRegistry.registered}" />
+    </bean>
+
+    <bean id="ipAddressManagerImpl" class="com.cloud.network.IpAddressManagerImpl">
+    </bean>
+
+    <bean id="networkModelImpl" class="com.cloud.network.NetworkModelImpl">
+        <property name="networkElements" value="#{networkElementsRegistry.registered}" />
+    </bean>
+
+
+    <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
+
+
+    <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
+
+    <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.ConsoleProxyManagerImpl">
+        <property name="consoleProxyAllocators"
+            value="#{consoleProxyAllocatorsRegistry.registered}" />
+    </bean>
+
+    <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
+
+    <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
+
+    <bean id="NetworkMigrationManagerImpl" class="com.cloud.network.NetworkMigrationManagerImpl" />
+
+
+    <bean id="alertManagerImpl" class="com.cloud.alert.AlertManagerImpl" />
+
+    <bean id="autoScaleManagerImpl" class="com.cloud.network.as.AutoScaleManagerImpl" />
+
+    <bean id="capacityManagerImpl" class="com.cloud.capacity.CapacityManagerImpl" />
+
+    <bean id="configurationManagerImpl" class="com.cloud.configuration.ConfigurationManagerImpl" >  
+        <property name="secChecker" value="#{securityCheckersRegistry.registered}" />
+    </bean>
+
+    <bean id="externalDeviceUsageManagerImpl" class="com.cloud.network.ExternalDeviceUsageManagerImpl" />
+
+    <bean id="externalNetworkDeviceManagerImpl" class="com.cloud.network.ExternalNetworkDeviceManagerImpl" />
+
+    <bean id="firewallManagerImpl" class="com.cloud.network.firewall.FirewallManagerImpl" >
+        <property name="firewallElements" value="#{firewallServiceProvidersRegistry.registered}" />
+        <property name="networkAclElements" value="#{networkACLServiceProvidersRegistry.registered}" />
+        <property name="pfElements" value="#{portForwardingServiceProvidersRegistry.registered}" />
+        <property name="staticNatElements" value="#{staticNatServiceProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="hypervisorGuruManagerImpl" class="com.cloud.hypervisor.HypervisorGuruManagerImpl" >
+        <property name="hvGuruList" value="#{hypervisorGurusRegistry.registered}" />
+    </bean>
+
+    <bean id="uUIDManagerImpl" class="com.cloud.uuididentity.UUIDManagerImpl" />
+
+    <bean id="loadBalancingRulesManagerImpl" class="com.cloud.network.lb.LoadBalancingRulesManagerImpl" >
+        <property name="lbProviders" value="#{loadBalancingServiceProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="networkACLManagerImpl" class="com.cloud.network.vpc.NetworkACLManagerImpl" >
+        <property name="networkAclElements" value="#{networkACLServiceProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="networkACLServiceImpl" class="com.cloud.network.vpc.NetworkACLServiceImpl" />
+
+    <bean id="networkServiceImpl" class="com.cloud.network.NetworkServiceImpl" >
+        <property name="networkGurus" value="#{networkGurusRegistry.registered}" />
+    </bean>
+
+    <bean id="networkUsageManagerImpl" class="com.cloud.network.NetworkUsageManagerImpl" />
+
+    <bean id="oCFS2ManagerImpl" class="com.cloud.storage.OCFS2ManagerImpl" />
+
+    <bean id="outOfBandManagementServiceImpl" class="org.apache.cloudstack.outofbandmanagement.OutOfBandManagementServiceImpl">
+        <property name="outOfBandManagementDrivers" value="#{outOfBandManagementDriversRegistry.registered}" />
+    </bean>
+
+    <bean id="projectManagerImpl" class="com.cloud.projects.ProjectManagerImpl" />
+
+    <bean id="queryManagerImpl" class="com.cloud.api.query.QueryManagerImpl" />
+
+    <bean id="regionManagerImpl" class="org.apache.cloudstack.region.RegionManagerImpl" />
+
+    <bean id="regionServiceImpl" class="org.apache.cloudstack.region.RegionServiceImpl" />
+
+    <bean id="remoteAccessVpnManagerImpl" class="com.cloud.network.vpn.RemoteAccessVpnManagerImpl" >
+        <property name="vpnServiceProviders" value="#{remoteAccessVPNServiceProviderRegistry.registered}" />
+    </bean>
+
+    <bean id="resourceLimitManagerImpl" class="com.cloud.resourcelimit.ResourceLimitManagerImpl" />
+
+    <bean id="rulesManagerImpl" class="com.cloud.network.rules.RulesManagerImpl" />
+
+    <bean id="site2SiteVpnManagerImpl" class="com.cloud.network.vpn.Site2SiteVpnManagerImpl" >
+        <property name="s2sProviders" value="#{site2SiteVpnServiceProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="snapshotManagerImpl" class="com.cloud.storage.snapshot.SnapshotManagerImpl" />
+
+    <bean id="snapshotSchedulerImpl" class="com.cloud.storage.snapshot.SnapshotSchedulerImpl" >
+        <property name="asyncJobDispatcher" ref="ApiAsyncJobDispatcher" />
+    </bean>
+    <bean id="storageNetworkManagerImpl" class="com.cloud.network.StorageNetworkManagerImpl" />
+    <bean id="taggedResourceManagerImpl" class="com.cloud.tags.TaggedResourceManagerImpl" />
+    <bean id="resourceMetaDataManagerImpl" class="com.cloud.metadata.ResourceMetaDataManagerImpl" />
+
+    <bean id="templateManagerImpl" class="com.cloud.template.TemplateManagerImpl">
+        <property name="templateAdapters" value="#{templateAdapterRegistry.registered}" />
+    </bean>
+
+    <bean id="uploadMonitorImpl" class="com.cloud.storage.upload.UploadMonitorImpl" />
+    <bean id="usageServiceImpl" class="com.cloud.usage.UsageServiceImpl" />
+    
+    <bean id="virtualNetworkApplianceManagerImpl"
+        class="com.cloud.network.router.VirtualNetworkApplianceManagerImpl" />
+        
+    <bean id="vpcManagerImpl" class="com.cloud.network.vpc.VpcManagerImpl" >
+        <property name="vpcElements" value="#{vpcProvidersRegistry.registered}"></property>
+    </bean>
+    
+    <bean id="vpcTxCallable" class="com.cloud.network.vpc.VpcPrivateGatewayTransactionCallable" />
+    
+    <bean id="vpcVirtualNetworkApplianceManagerImpl"
+        class="com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl" />
+    
+    <bean id="virtualNetworkApplianceFactory"
+        class="com.cloud.network.rules.VirtualNetworkApplianceFactory" />
+    
+    <bean id="topologyContext" class="org.apache.cloudstack.network.topology.NetworkTopologyContext" init-method="init" />
+    
+    <bean id="basicNetworkTopology" class="org.apache.cloudstack.network.topology.BasicNetworkTopology" />
+    <bean id="advancedNetworkTopology" class="org.apache.cloudstack.network.topology.AdvancedNetworkTopology" />
+    
+    <bean id="basicNetworkVisitor" class="org.apache.cloudstack.network.topology.BasicNetworkVisitor" />
+    <bean id="advancedNetworkVisitor" class="org.apache.cloudstack.network.topology.AdvancedNetworkVisitor" />
+    
+    <bean id="commandSetupHelper"
+        class="com.cloud.network.router.CommandSetupHelper" />
+    
+    <bean id="routerControlHelper"
+        class="com.cloud.network.router.RouterControlHelper" />
+        
+    <bean id="networkHelper"
+        class="com.cloud.network.router.NetworkHelperImpl" />
+        
+    <bean id="vpcNetworkHelper"
+        class="com.cloud.network.router.VpcNetworkHelperImpl" />
+        
+    <bean id="nicProfileHelper"
+        class="com.cloud.network.router.NicProfileHelperImpl" />
+        
+    <bean id="routerDeploymentDefinitionBuilder"
+        class="org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder" />
+
+    <bean id="ApiAsyncJobDispatcher" class="com.cloud.api.ApiAsyncJobDispatcher">
+        <property name="name" value="ApiAsyncJobDispatcher" />
+    </bean>
+
+
+    <bean id="statsCollector" class="com.cloud.server.StatsCollector" />
+
+    <bean id="storagePoolAutomationImpl" class="com.cloud.storage.StoragePoolAutomationImpl" />
+
+    <bean id="domainManagerImpl" class="com.cloud.user.DomainManagerImpl" />
+
+    <bean id="downloadMonitorImpl" class="com.cloud.storage.download.DownloadMonitorImpl" />
+  
+    <bean id="lBHealthCheckManagerImpl" class="com.cloud.network.lb.LBHealthCheckManagerImpl" />
+
+    <bean id="volumeApiServiceImpl" class="com.cloud.storage.VolumeApiServiceImpl">
+        <property name="storagePoolAllocators"
+            value="#{storagePoolAllocatorsRegistry.registered}" />
+    </bean>
+    
+    <bean id="ApplicationLoadBalancerService" class="org.apache.cloudstack.network.lb.ApplicationLoadBalancerManagerImpl" />
+
+    <bean id="vMSnapshotManagerImpl" class="com.cloud.vm.snapshot.VMSnapshotManagerImpl" />
+
+    <bean id="AffinityGroupServiceImpl"
+        class="org.apache.cloudstack.affinity.AffinityGroupServiceImpl">
+        <property name="affinityGroupProcessors"
+            value="#{affinityProcessorsRegistry.registered}" />
+    </bean>
+
+    <bean id="DeploymentPlanningManager" class="com.cloud.deploy.DeploymentPlanningManagerImpl">
+        <property name="planners"
+            value="#{deploymentPlannersRegistry.registered}" />
+        <property name="affinityGroupProcessors"
+            value="#{affinityProcessorsRegistry.registered}" />
+        <property name="storagePoolAllocators"
+            value="#{storagePoolAllocatorsRegistry.registered}" />
+        <property name="hostAllocators" value="#{hostAllocatorsRegistry.registered}" />
+    </bean>
+
+    <bean id="AffinityGroupJoinDaoImpl" class="com.cloud.api.query.dao.AffinityGroupJoinDaoImpl" />
+
+    <bean id="PlannerHostReservationDaoImpl" class="com.cloud.deploy.dao.PlannerHostReservationDaoImpl" />
+
+    <bean id="GlobalLoadBalancingRulesServiceImpl"
+        class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" >
+        <property name="gslbServiceProviders" value="#{gslbServiceProvidersRegistry.registered}" />
+    </bean>
+    <bean id="certServiceImpl" class="org.apache.cloudstack.network.ssl.CertServiceImpl" />
+
+    <bean id="imageStoreUploadMonitorImpl" class="com.cloud.storage.ImageStoreUploadMonitorImpl" />
+
+    <!-- the new CA manager -->
+    <bean id="caManager" class="org.apache.cloudstack.ca.CAManagerImpl">
+        <property name="caProviders" value="#{caProvidersRegistry.registered}" />
+    </bean>
+
+    <bean id="annotationService" class="org.apache.cloudstack.annotation.AnnotationManagerImpl" />
+
+    <bean id="indirectAgentLBService" class="org.apache.cloudstack.agent.lb.IndirectAgentLBServiceImpl" />
+
+    <bean id="directDownloadManager" class="org.apache.cloudstack.direct.download.DirectDownloadManagerImpl" />
+
+    <bean id="DiagnosticsService" class="org.apache.cloudstack.diagnostics.DiagnosticsServiceImpl" />
+</beans>
diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
rename to server/src/main/resources/META-INF/cloudstack/core/spring-server-core-misc-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-backend/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-backend/spring-server-alert-adapter-backend-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-compute/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-compute/spring-server-alert-adapter-compute-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-storage/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml b/server/src/main/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-alert-adapter-storage/spring-server-alert-adapter-storage-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-allocator/module.properties b/server/src/main/resources/META-INF/cloudstack/server-allocator/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-allocator/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-allocator/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml b/server/src/main/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-allocator/spring-server-allocator-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-api/module.properties b/server/src/main/resources/META-INF/cloudstack/server-api/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-api/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-api/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml b/server/src/main/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-api/spring-server-api-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-compute/module.properties b/server/src/main/resources/META-INF/cloudstack/server-compute/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-compute/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-compute/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml b/server/src/main/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-compute/spring-server-compute-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-discoverer/module.properties b/server/src/main/resources/META-INF/cloudstack/server-discoverer/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-discoverer/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-discoverer/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml b/server/src/main/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-discoverer/spring-server-discoverer-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-fencer/module.properties b/server/src/main/resources/META-INF/cloudstack/server-fencer/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-fencer/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-fencer/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml b/server/src/main/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-fencer/spring-server-fencer-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-investigator/module.properties b/server/src/main/resources/META-INF/cloudstack/server-investigator/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-investigator/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-investigator/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml b/server/src/main/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-investigator/spring-server-investigator-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-network/module.properties b/server/src/main/resources/META-INF/cloudstack/server-network/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-network/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-network/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml b/server/src/main/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-network/spring-server-network-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-planner/module.properties b/server/src/main/resources/META-INF/cloudstack/server-planner/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-planner/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-planner/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml b/server/src/main/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-planner/spring-server-planner-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-storage/module.properties b/server/src/main/resources/META-INF/cloudstack/server-storage/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-storage/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-storage/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml b/server/src/main/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-storage/spring-server-storage-context.xml
diff --git a/server/resources/META-INF/cloudstack/server-template-adapter/module.properties b/server/src/main/resources/META-INF/cloudstack/server-template-adapter/module.properties
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-template-adapter/module.properties
rename to server/src/main/resources/META-INF/cloudstack/server-template-adapter/module.properties
diff --git a/server/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml b/server/src/main/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml
rename to server/src/main/resources/META-INF/cloudstack/server-template-adapter/spring-server-template-adapter-context.xml
diff --git a/server/resources/META-INF/cloudstack/system/spring-server-system-context.xml b/server/src/main/resources/META-INF/cloudstack/system/spring-server-system-context.xml
similarity index 100%
rename from server/resources/META-INF/cloudstack/system/spring-server-system-context.xml
rename to server/src/main/resources/META-INF/cloudstack/system/spring-server-system-context.xml
diff --git a/server/resources/com/cloud/upgrade/databaseCreatorContext.xml b/server/src/main/resources/com/cloud/upgrade/databaseCreatorContext.xml
similarity index 100%
rename from server/resources/com/cloud/upgrade/databaseCreatorContext.xml
rename to server/src/main/resources/com/cloud/upgrade/databaseCreatorContext.xml
diff --git a/server/scripts/vmops-fix-mysql-config b/server/src/main/scripts/vmops-fix-mysql-config
similarity index 100%
rename from server/scripts/vmops-fix-mysql-config
rename to server/src/main/scripts/vmops-fix-mysql-config
diff --git a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java
deleted file mode 100644
index 4402a1b..0000000
--- a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java
+++ /dev/null
@@ -1,330 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.acl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.acl.dao.RoleDao;
-import org.apache.cloudstack.acl.dao.RolePermissionsDao;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.admin.acl.CreateRoleCmd;
-import org.apache.cloudstack.api.command.admin.acl.CreateRolePermissionCmd;
-import org.apache.cloudstack.api.command.admin.acl.DeleteRoleCmd;
-import org.apache.cloudstack.api.command.admin.acl.DeleteRolePermissionCmd;
-import org.apache.cloudstack.api.command.admin.acl.ListRolePermissionsCmd;
-import org.apache.cloudstack.api.command.admin.acl.ListRolesCmd;
-import org.apache.cloudstack.api.command.admin.acl.UpdateRoleCmd;
-import org.apache.cloudstack.api.command.admin.acl.UpdateRolePermissionCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.ListUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.google.common.base.Strings;
-
-public class RoleManagerImpl extends ManagerBase implements RoleService, Configurable, PluggableService {
-
-    private Logger logger = Logger.getLogger(getClass());
-
-    @Inject
-    private AccountDao accountDao;
-    @Inject
-    private RoleDao roleDao;
-    @Inject
-    private RolePermissionsDao rolePermissionsDao;
-    @Inject
-    private AccountManager accountManager;
-
-    private void checkCallerAccess() {
-        if (!isEnabled()) {
-            throw new PermissionDeniedException("Dynamic api checker is not enabled, aborting role operation");
-        }
-        Account caller = getCurrentAccount();
-        if (caller == null || caller.getRoleId() == null) {
-            throw new PermissionDeniedException("Restricted API called by an invalid user account");
-        }
-        Role callerRole = findRole(caller.getRoleId());
-        if (callerRole == null || callerRole.getRoleType() != RoleType.Admin) {
-            throw new PermissionDeniedException("Restricted API called by an user account of non-Admin role type");
-        }
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return RoleService.EnableDynamicApiChecker.value();
-    }
-
-    @Override
-    public Role findRole(Long id) {
-        if (id == null || id < 1L) {
-            logger.trace(String.format("Role ID is invalid [%s]", id));
-            return null;
-        }
-        RoleVO role = roleDao.findById(id);
-        if (role == null) {
-            logger.trace(String.format("Role not found [id=%s]", id));
-            return null;
-        }
-        Account account = getCurrentAccount();
-        if (!accountManager.isRootAdmin(account.getId()) && RoleType.Admin == role.getRoleType()) {
-            logger.debug(String.format("Role [id=%s, name=%s] is of 'Admin' type and is only visible to 'Root admins'.", id, role.getName()));
-            return null;
-        }
-        return role;
-    }
-
-    /**
-     * Simple call to {@link CallContext#current()} to retrieve the current calling account.
-     * This method facilitates unit testing, it avoids mocking static methods.
-     */
-    protected Account getCurrentAccount() {
-        return CallContext.current().getCallingAccount();
-    }
-
-    @Override
-    public RolePermission findRolePermission(final Long id) {
-        if (id == null) {
-            return null;
-        }
-        return rolePermissionsDao.findById(id);
-    }
-
-    @Override
-    public RolePermission findRolePermissionByUuid(final String uuid) {
-        if (Strings.isNullOrEmpty(uuid)) {
-            return null;
-        }
-        return rolePermissionsDao.findByUuid(uuid);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_CREATE, eventDescription = "creating Role")
-    public Role createRole(final String name, final RoleType roleType, final String description) {
-        checkCallerAccess();
-        if (roleType == null || roleType == RoleType.Unknown) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role type provided");
-        }
-        return Transaction.execute(new TransactionCallback<RoleVO>() {
-            @Override
-            public RoleVO doInTransaction(TransactionStatus status) {
-                return roleDao.persist(new RoleVO(name, roleType, description));
-            }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_UPDATE, eventDescription = "updating Role")
-    public Role updateRole(final Role role, final String name, final RoleType roleType, final String description) {
-        checkCallerAccess();
-
-        if (roleType != null && roleType == RoleType.Unknown) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unknown is not a valid role type");
-        }
-        RoleVO roleVO = (RoleVO)role;
-        if (!Strings.isNullOrEmpty(name)) {
-            roleVO.setName(name);
-        }
-        if (roleType != null) {
-            if (role.getId() <= RoleType.User.getId()) {
-                throw new PermissionDeniedException("The role type of default roles cannot be changed");
-            }
-            List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
-            if (accounts == null || accounts.isEmpty()) {
-                roleVO.setRoleType(roleType);
-            } else {
-                throw new PermissionDeniedException("Found accounts that have role in use, won't allow to change role type");
-            }
-        }
-        if (!Strings.isNullOrEmpty(description)) {
-            roleVO.setDescription(description);
-        }
-
-        roleDao.update(role.getId(), roleVO);
-        return role;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_DELETE, eventDescription = "deleting Role")
-    public boolean deleteRole(final Role role) {
-        checkCallerAccess();
-        if (role == null) {
-            return false;
-        }
-        if (role.getId() <= RoleType.User.getId()) {
-            throw new PermissionDeniedException("Default roles cannot be deleted");
-        }
-        List<? extends Account> accounts = accountDao.findAccountsByRole(role.getId());
-        if (accounts == null || accounts.size() == 0) {
-            return Transaction.execute(new TransactionCallback<Boolean>() {
-                @Override
-                public Boolean doInTransaction(TransactionStatus status) {
-                    List<? extends RolePermission> rolePermissions = rolePermissionsDao.findAllByRoleIdSorted(role.getId());
-                    if (rolePermissions != null && !rolePermissions.isEmpty()) {
-                        for (RolePermission rolePermission : rolePermissions) {
-                            rolePermissionsDao.remove(rolePermission.getId());
-                        }
-                    }
-                    if (roleDao.remove(role.getId())) {
-                        RoleVO roleVO = roleDao.findByIdIncludingRemoved(role.getId());
-                        roleVO.setName(null);
-                        return roleDao.update(role.getId(), roleVO);
-                    }
-                    return false;
-                }
-            });
-        }
-        throw new PermissionDeniedException("Found accounts that have role in use, won't allow to delete role");
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_CREATE, eventDescription = "creating Role Permission")
-    public RolePermission createRolePermission(final Role role, final Rule rule, final RolePermission.Permission permission, final String description) {
-        checkCallerAccess();
-        return Transaction.execute(new TransactionCallback<RolePermissionVO>() {
-            @Override
-            public RolePermissionVO doInTransaction(TransactionStatus status) {
-                return rolePermissionsDao.persist(new RolePermissionVO(role.getId(), rule.toString(), permission, description));
-            }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_UPDATE, eventDescription = "updating Role Permission order")
-    public boolean updateRolePermission(final Role role, final List<RolePermission> newOrder) {
-        checkCallerAccess();
-        return role != null && newOrder != null && rolePermissionsDao.update(role, newOrder);
-    }
-
-    @Override
-    public boolean updateRolePermission(Role role, RolePermission rolePermission, RolePermission.Permission permission) {
-        checkCallerAccess();
-        return role != null && rolePermissionsDao.update(role, rolePermission, permission);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_DELETE, eventDescription = "deleting Role Permission")
-    public boolean deleteRolePermission(final RolePermission rolePermission) {
-        checkCallerAccess();
-        return rolePermission != null && rolePermissionsDao.remove(rolePermission.getId());
-    }
-
-    @Override
-    public List<Role> findRolesByName(String name) {
-        List<? extends Role> roles = null;
-        if (StringUtils.isNotBlank(name)) {
-            roles = roleDao.findAllByName(name);
-        }
-        removeRootAdminRolesIfNeeded(roles);
-        return ListUtils.toListOfInterface(roles);
-    }
-
-    /**
-     *  Removes roles of the given list that have the type '{@link RoleType#Admin}' if the user calling the method is not a 'root admin'.
-     *  The actual removal is executed via {@link #removeRootAdminRoles(List)}. Therefore, if the method is called by a 'root admin', we do nothing here.
-     */
-    protected void removeRootAdminRolesIfNeeded(List<? extends Role> roles) {
-        Account account = getCurrentAccount();
-        if (!accountManager.isRootAdmin(account.getId())) {
-            removeRootAdminRoles(roles);
-        }
-    }
-
-    /**
-     * Remove all roles that have the {@link RoleType#Admin}.
-     */
-    protected void removeRootAdminRoles(List<? extends Role> roles) {
-        if (CollectionUtils.isEmpty(roles)) {
-            return;
-        }
-        Iterator<? extends Role> rolesIterator = roles.iterator();
-        while (rolesIterator.hasNext()) {
-            Role role = rolesIterator.next();
-            if (RoleType.Admin == role.getRoleType()) {
-                rolesIterator.remove();
-            }
-        }
-    }
-
-    @Override
-    public List<Role> findRolesByType(RoleType roleType) {
-        if (roleType == null || RoleType.Admin == roleType && !accountManager.isRootAdmin(getCurrentAccount().getId())) {
-            return Collections.emptyList();
-        }
-        List<? extends Role> roles = roleDao.findAllByRoleType(roleType);
-        return ListUtils.toListOfInterface(roles);
-    }
-
-    @Override
-    public List<Role> listRoles() {
-        List<? extends Role> roles = roleDao.listAll();
-        removeRootAdminRolesIfNeeded(roles);
-        return ListUtils.toListOfInterface(roles);
-    }
-
-    @Override
-    public List<RolePermission> findAllPermissionsBy(final Long roleId) {
-        List<? extends RolePermission> permissions = rolePermissionsDao.findAllByRoleIdSorted(roleId);
-        if (permissions != null) {
-            return new ArrayList<>(permissions);
-        }
-        return Collections.emptyList();
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return RoleService.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {RoleService.EnableDynamicApiChecker};
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<>();
-        cmdList.add(CreateRoleCmd.class);
-        cmdList.add(ListRolesCmd.class);
-        cmdList.add(UpdateRoleCmd.class);
-        cmdList.add(DeleteRoleCmd.class);
-        cmdList.add(CreateRolePermissionCmd.class);
-        cmdList.add(ListRolePermissionsCmd.class);
-        cmdList.add(UpdateRolePermissionCmd.class);
-        cmdList.add(DeleteRolePermissionCmd.class);
-        return cmdList;
-    }
-}
diff --git a/server/src/org/apache/cloudstack/ca/CAManagerImpl.java b/server/src/org/apache/cloudstack/ca/CAManagerImpl.java
deleted file mode 100644
index 23a0379..0000000
--- a/server/src/org/apache/cloudstack/ca/CAManagerImpl.java
+++ /dev/null
@@ -1,439 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.ca;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.admin.ca.IssueCertificateCmd;
-import org.apache.cloudstack.api.command.admin.ca.ListCAProvidersCmd;
-import org.apache.cloudstack.api.command.admin.ca.ListCaCertificateCmd;
-import org.apache.cloudstack.api.command.admin.ca.ProvisionCertificateCmd;
-import org.apache.cloudstack.api.command.admin.ca.RevokeCertificateCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.ca.CAProvider;
-import org.apache.cloudstack.framework.ca.Certificate;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.poll.BackgroundPollManager;
-import org.apache.cloudstack.poll.BackgroundPollTask;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.cloudstack.utils.security.CertUtils;
-import org.apache.log4j.Logger;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.alert.AlertManager;
-import com.cloud.certificate.CrlVO;
-import com.cloud.certificate.dao.CrlDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.Host;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.google.common.base.Strings;
-
-public class CAManagerImpl extends ManagerBase implements CAManager {
-    public static final Logger LOG = Logger.getLogger(CAManagerImpl.class);
-
-    @Inject
-    private CrlDao crlDao;
-    @Inject
-    private HostDao hostDao;
-    @Inject
-    private AgentManager agentManager;
-    @Inject
-    private BackgroundPollManager backgroundPollManager;
-    @Inject
-    private AlertManager alertManager;
-
-    private static CAProvider configuredCaProvider;
-    private static Map<String, CAProvider> caProviderMap = new HashMap<>();
-    private static Map<String, Date> alertMap = new ConcurrentHashMap<>();
-    private static Map<String, X509Certificate> activeCertMap = new ConcurrentHashMap<>();
-
-    private List<CAProvider> caProviders;
-
-    private CAProvider getConfiguredCaProvider() {
-        if (configuredCaProvider != null) {
-            return configuredCaProvider;
-        }
-        if (caProviderMap.containsKey(CAProviderPlugin.value()) && caProviderMap.get(CAProviderPlugin.value()) != null) {
-            configuredCaProvider = caProviderMap.get(CAProviderPlugin.value());
-            return configuredCaProvider;
-        }
-        throw new CloudRuntimeException("Failed to find default configured CA provider plugin");
-    }
-
-    private CAProvider getCAProvider(final String provider) {
-        if (Strings.isNullOrEmpty(provider)) {
-            return getConfiguredCaProvider();
-        }
-        final String caProviderName = provider.toLowerCase();
-        if (!caProviderMap.containsKey(caProviderName)) {
-            throw new CloudRuntimeException(String.format("CA provider plugin '%s' not found", caProviderName));
-        }
-        final CAProvider caProvider = caProviderMap.get(caProviderName);
-        if (caProvider == null) {
-            throw new CloudRuntimeException(String.format("CA provider plugin '%s' returned is null", caProviderName));
-        }
-        return caProvider;
-    }
-
-    ///////////////////////////////////////////////////////////
-    /////////////// CA Manager API Handlers ///////////////////
-    ///////////////////////////////////////////////////////////
-
-    @Override
-    public List<CAProvider> getCaProviders() {
-        return caProviders;
-    }
-
-    @Override
-    public Map<String, X509Certificate> getActiveCertificatesMap() {
-        return activeCertMap;
-    }
-
-    @Override
-    public boolean canProvisionCertificates() {
-        return getConfiguredCaProvider().canProvisionCertificates();
-    }
-
-    @Override
-    public String getCaCertificate(final String caProvider) throws IOException {
-        final CAProvider provider = getCAProvider(caProvider);
-        return CertUtils.x509CertificatesToPem(provider.getCaCertificate());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_ISSUE, eventDescription = "issuing certificate", async = true)
-    public Certificate issueCertificate(final String csr, final List<String> domainNames, final List<String> ipAddresses, final Integer validityDuration, final String caProvider) {
-        CallContext.current().setEventDetails("domain(s): " + domainNames + " addresses: " + ipAddresses);
-        final CAProvider provider = getCAProvider(caProvider);
-        Integer validity = CAManager.CertValidityPeriod.value();
-        if (validityDuration != null) {
-            validity = validityDuration;
-        }
-        if (Strings.isNullOrEmpty(csr)) {
-            if (domainNames == null || domainNames.isEmpty()) {
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "No domains or CSR provided");
-            }
-            return provider.issueCertificate(domainNames, ipAddresses, validity);
-        }
-        return provider.issueCertificate(csr, domainNames, ipAddresses, validity);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_REVOKE, eventDescription = "revoking certificate", async = true)
-    public boolean revokeCertificate(final BigInteger certSerial, final String certCn, final String caProvider) {
-        CallContext.current().setEventDetails("cert serial: " + certSerial);
-        final CrlVO crl = crlDao.revokeCertificate(certSerial, certCn);
-        if (crl != null && crl.getCertSerial().equals(certSerial)) {
-            final CAProvider provider = getCAProvider(caProvider);
-            return provider.revokeCertificate(certSerial, certCn);
-        }
-        return false;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_CA_CERTIFICATE_PROVISION, eventDescription = "provisioning certificate for host", async = true)
-    public boolean provisionCertificate(final Host host, final Boolean reconnect, final String caProvider) {
-        if (host == null) {
-            throw new CloudRuntimeException("Unable to find valid host to renew certificate for");
-        }
-        CallContext.current().setEventDetails("host id: " + host.getId());
-        CallContext.current().putContextParameter(Host.class, host.getUuid());
-        final String csr;
-        try {
-            csr = generateKeyStoreAndCsr(host, null);
-            if (Strings.isNullOrEmpty(csr)) {
-                return false;
-            }
-            final Certificate certificate = issueCertificate(csr, Arrays.asList(host.getName(), host.getPrivateIpAddress()), Arrays.asList(host.getPrivateIpAddress(), host.getPublicIpAddress(), host.getStorageIpAddress()), CAManager.CertValidityPeriod.value(), caProvider);
-            return deployCertificate(host, certificate, reconnect, null);
-        } catch (final AgentUnavailableException | OperationTimedoutException e) {
-            LOG.error("Host/agent is not available or operation timed out, failed to setup keystore and generate CSR for host/agent id=" + host.getId() + ", due to: ", e);
-            throw new CloudRuntimeException("Failed to generate keystore and get CSR from the host/agent id=" + host.getId());
-        }
-    }
-
-    @Override
-    public String generateKeyStoreAndCsr(final Host host, final Map<String, String> sshAccessDetails) throws AgentUnavailableException, OperationTimedoutException {
-        final SetupKeyStoreCommand cmd = new SetupKeyStoreCommand(CertValidityPeriod.value());
-        if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) {
-            cmd.setAccessDetail(sshAccessDetails);
-        }
-        CallContext.current().setEventDetails("generating keystore and CSR for host id: " + host.getId());
-        final SetupKeystoreAnswer answer = (SetupKeystoreAnswer) agentManager.send(host.getId(), cmd);
-        return answer.getCsr();
-    }
-
-    @Override
-    public boolean deployCertificate(final Host host, final Certificate certificate, final Boolean reconnect, final Map<String, String> sshAccessDetails) throws AgentUnavailableException, OperationTimedoutException {
-        final SetupCertificateCommand cmd = new SetupCertificateCommand(certificate);
-        if (sshAccessDetails != null && !sshAccessDetails.isEmpty()) {
-            cmd.setAccessDetail(sshAccessDetails);
-        }
-        CallContext.current().setEventDetails("deploying certificate for host id: " + host.getId());
-        final SetupCertificateAnswer answer = (SetupCertificateAnswer) agentManager.send(host.getId(), cmd);
-        if (answer.getResult()) {
-            CallContext.current().setEventDetails("successfully deployed certificate for host id: " + host.getId());
-        } else {
-            CallContext.current().setEventDetails("failed to deploy certificate for host id: " + host.getId());
-        }
-
-        if (answer.getResult()) {
-            getActiveCertificatesMap().put(host.getPrivateIpAddress(), certificate.getClientCertificate());
-            if (sshAccessDetails == null && reconnect != null && reconnect) {
-                LOG.info(String.format("Successfully setup certificate on host, reconnecting with agent with id=%d, name=%s, address=%s",
-                        host.getId(), host.getName(), host.getPublicIpAddress()));
-                return agentManager.reconnect(host.getId());
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void purgeHostCertificate(final Host host) {
-        if (host == null) {
-            return;
-        }
-        final String privateAddress = host.getPrivateIpAddress();
-        final String publicAddress = host.getPublicIpAddress();
-        final Map<String, X509Certificate> activeCertsMap = getActiveCertificatesMap();
-        if (!Strings.isNullOrEmpty(privateAddress) && activeCertsMap.containsKey(privateAddress)) {
-            activeCertsMap.remove(privateAddress);
-        }
-        if (!Strings.isNullOrEmpty(publicAddress) && activeCertsMap.containsKey(publicAddress)) {
-            activeCertsMap.remove(publicAddress);
-        }
-    }
-
-    @Override
-    public void sendAlert(final Host host, final String subject, final String message) {
-        if (host == null) {
-            return;
-        }
-        alertManager.sendAlert(AlertManager.AlertType.ALERT_TYPE_CA_CERT,
-                host.getDataCenterId(), host.getPodId(), subject, message);
-    }
-
-    @Override
-    public SSLEngine createSSLEngine(final SSLContext sslContext, final String remoteAddress) throws GeneralSecurityException, IOException {
-        if (sslContext == null) {
-            throw new CloudRuntimeException("SSLContext provided to create SSLEngine is null, aborting");
-        }
-        if (Strings.isNullOrEmpty(remoteAddress)) {
-            throw new CloudRuntimeException("Remote client address connecting to mgmt server cannot be empty/null");
-        }
-        return getConfiguredCaProvider().createSSLEngine(sslContext, remoteAddress, getActiveCertificatesMap());
-    }
-
-    @Override
-    public KeyStore getManagementKeyStore() throws KeyStoreException {
-        return getConfiguredCaProvider().getManagementKeyStore();
-    }
-
-    @Override
-    public char[] getKeyStorePassphrase() {
-        return getConfiguredCaProvider().getKeyStorePassphrase();
-    }
-
-    ////////////////////////////////////////////////////
-    /////////////// CA Manager Setup ///////////////////
-    ////////////////////////////////////////////////////
-
-    public static final class CABackgroundTask extends ManagedContextRunnable implements BackgroundPollTask {
-        private CAManager caManager;
-        private HostDao hostDao;
-
-        public CABackgroundTask(final CAManager caManager, final HostDao hostDao) {
-            this.caManager = caManager;
-            this.hostDao = hostDao;
-        }
-
-        @Override
-        protected void runInContext() {
-            try {
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace("CA background task is running...");
-                }
-                final DateTime now = DateTime.now(DateTimeZone.UTC);
-                final Map<String, X509Certificate> certsMap = caManager.getActiveCertificatesMap();
-                for (final Iterator<Map.Entry<String, X509Certificate>> it = certsMap.entrySet().iterator(); it.hasNext(); ) {
-                    final Map.Entry<String, X509Certificate> entry = it.next();
-                    if (entry == null) {
-                        continue;
-                    }
-                    final String hostIp = entry.getKey();
-                    final X509Certificate certificate = entry.getValue();
-                    if (certificate == null) {
-                        it.remove();
-                        continue;
-                    }
-                    final Host host = hostDao.findByIp(hostIp);
-                    if (host == null || host.getManagementServerId() == null ||
-                            host.getManagementServerId() != ManagementServerNode.getManagementServerId() ||
-                            host.getStatus() != Status.Up) {
-                        if (host == null ||
-                                (host.getManagementServerId() != null &&
-                                        host.getManagementServerId() != ManagementServerNode.getManagementServerId())) {
-                            it.remove();
-                        }
-                        continue;
-                    }
-
-                    final String hostDescription = String.format("host id=%d, uuid=%s, name=%s, ip=%s, zone id=%d",
-                            host.getId(), host.getUuid(), host.getName(), hostIp, host.getDataCenterId());
-
-                    try {
-                        certificate.checkValidity(now.plusDays(CertExpiryAlertPeriod.valueIn(host.getClusterId())).toDate());
-                    } catch (final CertificateExpiredException | CertificateNotYetValidException e) {
-                        LOG.warn("Certificate is going to expire for " + hostDescription);
-                        if (AutomaticCertRenewal.valueIn(host.getClusterId())) {
-                            try {
-                                LOG.debug("Attempting certificate auto-renewal for " + hostDescription);
-                                boolean result = caManager.provisionCertificate(host, false, null);
-                                if (result) {
-                                    LOG.debug("Succeeded in auto-renewing certificate for " + hostDescription);
-                                } else {
-                                    LOG.debug("Failed in auto-renewing certificate for " + hostDescription);
-                                }
-                            } catch (final Throwable ex) {
-                                LOG.warn("Failed to auto-renew certificate for " + hostDescription + ", with error=", ex);
-                                caManager.sendAlert(host, "Certificate auto-renewal failed for " + hostDescription,
-                                        String.format("Certificate is going to expire for %s. Auto-renewal failed to renew the certificate, please renew it manually. It is not valid after %s.", hostDescription, certificate.getNotAfter()));
-                            }
-                        } else {
-                            if (alertMap.containsKey(hostIp)) {
-                                final Date lastSentDate = alertMap.get(hostIp);
-                                if (now.minusDays(1).toDate().before(lastSentDate)) {
-                                    continue;
-                                }
-                            }
-                            caManager.sendAlert(host, "Certificate expiring soon for " + hostDescription,
-                                    String.format("Certificate is going to expire for %s. Please renew it, it is not valid after %s.",
-                                            hostDescription, certificate.getNotAfter()));
-                            alertMap.put(hostIp, new Date());
-                        }
-                    }
-                }
-            } catch (final Throwable t) {
-                LOG.error("Error trying to run CA background task", t);
-            }
-        }
-
-        @Override
-        public Long getDelay() {
-            return CABackgroundJobDelay.value() * 1000L;
-        }
-    }
-
-    public void setCaProviders(final List<CAProvider> caProviders) {
-        this.caProviders = caProviders;
-        initializeCaProviderMap();
-    }
-
-    private void initializeCaProviderMap() {
-        if (caProviderMap != null && caProviderMap.size() != caProviders.size()) {
-            for (final CAProvider caProvider : caProviders) {
-                caProviderMap.put(caProvider.getProviderName().toLowerCase(), caProvider);
-            }
-        }
-    }
-
-    @Override
-    public boolean start() {
-        super.start();
-        initializeCaProviderMap();
-        if (caProviderMap.containsKey(CAProviderPlugin.value())) {
-            configuredCaProvider = caProviderMap.get(CAProviderPlugin.value());
-        }
-        if (configuredCaProvider == null) {
-            LOG.error("Failed to find valid configured CA provider, please check!");
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        backgroundPollManager.submitTask(new CABackgroundTask(this, hostDao));
-        return true;
-    }
-
-    //////////////////////////////////////////////////////////
-    /////////////// CA Manager Descriptors ///////////////////
-    //////////////////////////////////////////////////////////
-
-    @Override
-    public List<Class<?>> getCommands() {
-        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(ListCAProvidersCmd.class);
-        cmdList.add(ListCaCertificateCmd.class);
-        cmdList.add(IssueCertificateCmd.class);
-        cmdList.add(ProvisionCertificateCmd.class);
-        cmdList.add(RevokeCertificateCmd.class);
-        return cmdList;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return CAManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[]{
-                CAProviderPlugin,
-                CertKeySize,
-                CertSignatureAlgorithm,
-                CertValidityPeriod,
-                AutomaticCertRenewal,
-                CABackgroundJobDelay,
-                CertExpiryAlertPeriod
-        };
-    }
-}
diff --git a/server/src/org/apache/cloudstack/ha/HAManagerImpl.java b/server/src/org/apache/cloudstack/ha/HAManagerImpl.java
deleted file mode 100644
index 86ac037..0000000
--- a/server/src/org/apache/cloudstack/ha/HAManagerImpl.java
+++ /dev/null
@@ -1,724 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.ha;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.command.admin.ha.ConfigureHAForHostCmd;
-import org.apache.cloudstack.api.command.admin.ha.DisableHAForClusterCmd;
-import org.apache.cloudstack.api.command.admin.ha.DisableHAForHostCmd;
-import org.apache.cloudstack.api.command.admin.ha.DisableHAForZoneCmd;
-import org.apache.cloudstack.api.command.admin.ha.EnableHAForClusterCmd;
-import org.apache.cloudstack.api.command.admin.ha.EnableHAForHostCmd;
-import org.apache.cloudstack.api.command.admin.ha.EnableHAForZoneCmd;
-import org.apache.cloudstack.api.command.admin.ha.ListHostHAProvidersCmd;
-import org.apache.cloudstack.api.command.admin.ha.ListHostHAResourcesCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.ha.dao.HAConfigDao;
-import org.apache.cloudstack.ha.provider.HAProvider;
-import org.apache.cloudstack.ha.provider.HAProvider.HAProviderConfig;
-import org.apache.cloudstack.ha.task.ActivityCheckTask;
-import org.apache.cloudstack.ha.task.FenceTask;
-import org.apache.cloudstack.ha.task.HealthCheckTask;
-import org.apache.cloudstack.ha.task.RecoveryTask;
-import org.apache.cloudstack.kernel.Partition;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.poll.BackgroundPollManager;
-import org.apache.cloudstack.poll.BackgroundPollTask;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import com.cloud.cluster.ClusterManagerListener;
-import com.cloud.cluster.ManagementServerHost;
-import com.cloud.dc.ClusterDetailsDao;
-import com.cloud.dc.ClusterDetailsVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterDetailVO;
-import com.cloud.dc.dao.DataCenterDetailsDao;
-import com.cloud.domain.Domain;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.ActionEventUtils;
-import com.cloud.event.EventTypes;
-import com.cloud.ha.Investigator;
-import com.cloud.host.Host;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.org.Cluster;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateListener;
-import com.cloud.utils.fsm.StateMachine2;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-
-public final class HAManagerImpl extends ManagerBase implements HAManager, ClusterManagerListener, PluggableService, Configurable, StateListener<HAConfig.HAState, HAConfig.Event, HAConfig> {
-    public static final Logger LOG = Logger.getLogger(HAManagerImpl.class);
-
-    @Inject
-    private HAConfigDao haConfigDao;
-
-    @Inject
-    private HostDao hostDao;
-
-    @Inject
-    private ClusterDetailsDao clusterDetailsDao;
-
-    @Inject
-    private DataCenterDetailsDao dataCenterDetailsDao;
-
-    @Inject
-    private BackgroundPollManager pollManager;
-
-    private List<HAProvider<HAResource>> haProviders;
-    private Map<String, HAProvider<HAResource>> haProviderMap = new HashMap<>();
-
-    private static ExecutorService healthCheckExecutor;
-    private static ExecutorService activityCheckExecutor;
-    private static ExecutorService recoveryExecutor;
-    private static ExecutorService fenceExecutor;
-
-    private static final String HA_ENABLED_DETAIL = "resourceHAEnabled";
-
-    //////////////////////////////////////////////////////
-    //////////////// HA Manager methods //////////////////
-    //////////////////////////////////////////////////////
-
-    public Map<String, HAResourceCounter> haCounterMap = new ConcurrentHashMap<>();
-
-    public HAProvider<HAResource> getHAProvider(final String name) {
-        return haProviderMap.get(name);
-    }
-
-    private String resourceCounterKey(final Long resourceId, final HAResource.ResourceType resourceType) {
-        return resourceId.toString() + resourceType.toString();
-    }
-
-    public synchronized HAResourceCounter getHACounter(final Long resourceId, final HAResource.ResourceType resourceType) {
-        final String key = resourceCounterKey(resourceId, resourceType);
-        if (!haCounterMap.containsKey(key)) {
-            haCounterMap.put(key, new HAResourceCounter());
-        }
-        return haCounterMap.get(key);
-    }
-
-    public synchronized void purgeHACounter(final Long resourceId, final HAResource.ResourceType resourceType) {
-        final String key = resourceCounterKey(resourceId, resourceType);
-        if (haCounterMap.containsKey(key)) {
-            haCounterMap.remove(key);
-        }
-    }
-
-    public boolean transitionHAState(final HAConfig.Event event, final HAConfig haConfig) {
-        if (event == null || haConfig == null) {
-            return false;
-        }
-        final HAConfig.HAState currentHAState = haConfig.getState();
-        try {
-            final HAConfig.HAState nextState = HAConfig.HAState.getStateMachine().getNextState(currentHAState, event);
-            boolean result = HAConfig.HAState.getStateMachine().transitTo(haConfig, event, null, haConfigDao);
-            if (result) {
-                final String message = String.format("Transitioned host HA state from:%s to:%s due to event:%s for the host id:%d",
-                        currentHAState, nextState, event, haConfig.getResourceId());
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace(message);
-                }
-                if (nextState == HAConfig.HAState.Recovering || nextState == HAConfig.HAState.Fencing || nextState == HAConfig.HAState.Fenced) {
-                    ActionEventUtils.onActionEvent(CallContext.current().getCallingUserId(), CallContext.current().getCallingAccountId(),
-                            Domain.ROOT_DOMAIN, EventTypes.EVENT_HA_STATE_TRANSITION, message);
-                }
-            }
-            return result;
-        } catch (NoTransitionException e) {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Unable to find next HA state for current HA state: " + currentHAState + " for event: " + event + " for host" + haConfig.getResourceId());
-            }
-        }
-        return false;
-    }
-
-    private boolean transitionResourceStateToDisabled(final Partition partition) {
-        List<? extends HAResource> resources;
-        if (partition.partitionType() == Partition.PartitionType.Cluster) {
-            resources = hostDao.findByClusterId(partition.getId());
-        } else if (partition.partitionType() == Partition.PartitionType.Zone) {
-            resources = hostDao.findByDataCenterId(partition.getId());
-        } else {
-            return true;
-        }
-
-        boolean result = true;
-        for (final HAResource resource: resources) {
-            result = result && transitionHAState(HAConfig.Event.Disabled,
-                    haConfigDao.findHAResource(resource.getId(), resource.resourceType()));
-        }
-        return result;
-    }
-
-    private boolean checkHAOwnership(final HAConfig haConfig) {
-        // Skip for resources not owned by this mgmt server
-        return !(haConfig.getManagementServerId() != null
-                && haConfig.getManagementServerId() != ManagementServerNode.getManagementServerId());
-    }
-
-    private HAResource validateAndFindHAResource(final HAConfig haConfig) {
-        HAResource resource = null;
-        if (haConfig == null) {
-            return null;
-        }
-        if (haConfig.getResourceType() == HAResource.ResourceType.Host) {
-            final Host host = hostDao.findById(haConfig.getResourceId());
-            if (host != null && host.getRemoved() != null) {
-                return null;
-            }
-            resource = host;
-            if (haConfig.getState() == null || (resource == null && haConfig.getState() != HAConfig.HAState.Disabled)) {
-                disableHA(haConfig.getResourceId(), haConfig.getResourceType());
-                return null;
-            }
-        }
-        if (!haConfig.isEnabled() || !isHAEnabledForZone(resource) || !isHAEnabledForCluster(resource)) {
-            if (haConfig.getState() != HAConfig.HAState.Disabled) {
-                if (transitionHAState(HAConfig.Event.Disabled, haConfig) ) {
-                    purgeHACounter(haConfig.getResourceId(), haConfig.getResourceType());
-                }
-            }
-            return null;
-        } else if (haConfig.getState() == HAConfig.HAState.Disabled) {
-            transitionHAState(HAConfig.Event.Enabled, haConfig);
-        }
-        return resource;
-    }
-
-    private HAProvider<HAResource> validateAndFindHAProvider(final HAConfig haConfig, final HAResource resource) {
-        if (haConfig == null) {
-            return null;
-        }
-        final HAProvider<HAResource> haProvider = haProviderMap.get(haConfig.getHaProvider());
-        if (haProvider != null && !haProvider.isEligible(resource)) {
-            if (haConfig.getState() != HAConfig.HAState.Ineligible) {
-                transitionHAState(HAConfig.Event.Ineligible, haConfig);
-            }
-            return null;
-        } else if (haConfig.getState() == HAConfig.HAState.Ineligible) {
-            transitionHAState(HAConfig.Event.Eligible, haConfig);
-        }
-        return haProvider;
-    }
-
-    public boolean isHAEnabledForZone(final HAResource resource) {
-        if (resource == null || resource.getDataCenterId() < 1L) {
-            return true;
-        }
-        final DataCenterDetailVO zoneDetails = dataCenterDetailsDao.findDetail(resource.getDataCenterId(), HA_ENABLED_DETAIL);
-        return zoneDetails == null || Strings.isNullOrEmpty(zoneDetails.getValue()) || Boolean.valueOf(zoneDetails.getValue());
-    }
-
-    private boolean isHAEnabledForCluster(final HAResource resource) {
-        if (resource == null || resource.getClusterId() == null) {
-            return true;
-        }
-        final ClusterDetailsVO clusterDetails = clusterDetailsDao.findDetail(resource.getClusterId(), HA_ENABLED_DETAIL);
-        return clusterDetails == null || Strings.isNullOrEmpty(clusterDetails.getValue()) || Boolean.valueOf(clusterDetails.getValue());
-    }
-
-    private boolean isHAEligibleForResource(final HAResource resource) {
-        if (resource == null || resource.getId() < 1L) {
-            return false;
-        }
-        HAResource.ResourceType resourceType = null;
-        if (resource instanceof Host) {
-            resourceType = HAResource.ResourceType.Host;
-        }
-        if (resourceType == null) {
-            return false;
-        }
-        final HAConfig haConfig = haConfigDao.findHAResource(resource.getId(), resourceType);
-        return haConfig != null && haConfig.isEnabled()
-                && haConfig.getState() != HAConfig.HAState.Disabled
-                && haConfig.getState() != HAConfig.HAState.Ineligible;
-    }
-
-    public boolean isHAEligible(final HAResource resource) {
-        return resource != null && isHAEnabledForZone(resource)
-                && isHAEnabledForCluster(resource)
-                && isHAEligibleForResource(resource);
-    }
-
-    public void validateHAProviderConfigForResource(final Long resourceId, final HAResource.ResourceType resourceType, final HAProvider<HAResource> haProvider) {
-        if (HAResource.ResourceType.Host.equals(resourceType)) {
-            final Host host = hostDao.findById(resourceId);
-            if (host.getHypervisorType() == null || haProvider.resourceSubType() == null || !host.getHypervisorType().toString().equals(haProvider.resourceSubType().toString())) {
-                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Incompatible haprovider provided for the resource of hypervisor type:" + host.getHypervisorType());
-            }
-        }
-    }
-
-    ////////////////////////////////////////////////////////////////////
-    //////////////// HA Investigator wrapper for Old HA ////////////////
-    ////////////////////////////////////////////////////////////////////
-
-    public Boolean isVMAliveOnHost(final Host host) throws Investigator.UnknownVM {
-        final HAConfig haConfig = haConfigDao.findHAResource(host.getId(), HAResource.ResourceType.Host);
-        if (haConfig != null) {
-            if (haConfig.getState() == HAConfig.HAState.Fenced) {
-                if (LOG.isDebugEnabled()){
-                    LOG.debug("HA: Host is fenced " + host.getId());
-                }
-                return false;
-            }
-            if (LOG.isDebugEnabled()){
-                LOG.debug("HA: HOST is alive " + host.getId());
-            }
-            return true;
-        }
-        throw new Investigator.UnknownVM();
-    }
-
-    public Status getHostStatus(final Host host) {
-        final HAConfig haConfig = haConfigDao.findHAResource(host.getId(), HAResource.ResourceType.Host);
-        if (haConfig != null) {
-            if (haConfig.getState() == HAConfig.HAState.Fenced) {
-                if (LOG.isDebugEnabled()){
-                    LOG.debug("HA: Agent is available/suspect/checking Up " + host.getId());
-                }
-                return Status.Down;
-            } else if (haConfig.getState() == HAConfig.HAState.Degraded || haConfig.getState() == HAConfig.HAState.Recovering || haConfig.getState() == HAConfig.HAState.Fencing) {
-                if (LOG.isDebugEnabled()){
-                    LOG.debug("HA: Agent is disconnected " + host.getId());
-                }
-                return Status.Disconnected;
-            }
-            return Status.Up;
-        }
-        return Status.Unknown;
-    }
-
-    //////////////////////////////////////////////////////
-    //////////////// HA API handlers /////////////////////
-    //////////////////////////////////////////////////////
-
-    private boolean configureHA(final Long resourceId, final HAResource.ResourceType resourceType, final Boolean enable, final String haProvider) {
-        return Transaction.execute(new TransactionCallback<Boolean>() {
-            @Override
-            public Boolean doInTransaction(TransactionStatus status) {
-                HAConfigVO haConfig = (HAConfigVO) haConfigDao.findHAResource(resourceId, resourceType);
-                if (haConfig == null) {
-                    haConfig = new HAConfigVO();
-                    if (haProvider != null) {
-                        haConfig.setHaProvider(haProvider);
-                    }
-                    if (enable != null) {
-                        haConfig.setEnabled(enable);
-                        haConfig.setManagementServerId(ManagementServerNode.getManagementServerId());
-                    }
-                    haConfig.setResourceId(resourceId);
-                    haConfig.setResourceType(resourceType);
-                    if (Strings.isNullOrEmpty(haConfig.getHaProvider())) {
-                        throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "HAProvider is not provided for the resource, failing configuration.");
-                    }
-                    if (haConfigDao.persist(haConfig) != null) {
-                        return true;
-                    }
-                } else {
-                    if (enable != null) {
-                        haConfig.setEnabled(enable);
-                    }
-                    if (haProvider != null) {
-                        haConfig.setHaProvider(haProvider);
-                    }
-                    if (Strings.isNullOrEmpty(haConfig.getHaProvider())) {
-                        throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "HAProvider is not provided for the resource, failing configuration.");
-                    }
-                    return haConfigDao.update(haConfig.getId(), haConfig);
-                }
-                return false;
-            }
-        });
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_CONFIGURE, eventDescription = "configuring HA for resource")
-    public boolean configureHA(final Long resourceId, final HAResource.ResourceType resourceType, final String haProvider) {
-        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
-        Preconditions.checkArgument(resourceType != null);
-        Preconditions.checkArgument(!Strings.isNullOrEmpty(haProvider));
-
-        if (!haProviderMap.containsKey(haProvider.toLowerCase())) {
-            throw new CloudRuntimeException("Given HA provider does not exist.");
-        }
-        validateHAProviderConfigForResource(resourceId, resourceType, haProviderMap.get(haProvider.toLowerCase()));
-        return configureHA(resourceId, resourceType, null, haProvider.toLowerCase());
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for resource")
-    public boolean enableHA(final Long resourceId, final HAResource.ResourceType resourceType) {
-        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
-        Preconditions.checkArgument(resourceType != null);
-        return configureHA(resourceId, resourceType, true, null);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for resource")
-    public boolean disableHA(final Long resourceId, final HAResource.ResourceType resourceType) {
-        Preconditions.checkArgument(resourceId != null && resourceId > 0L);
-        Preconditions.checkArgument(resourceType != null);
-        boolean result = configureHA(resourceId, resourceType, false, null);
-        if (result) {
-            transitionHAState(HAConfig.Event.Disabled, haConfigDao.findHAResource(resourceId, resourceType));
-            purgeHACounter(resourceId, resourceType);
-        }
-        return result;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for a cluster")
-    public boolean enableHA(final Cluster cluster) {
-        clusterDetailsDao.persist(cluster.getId(), HA_ENABLED_DETAIL, String.valueOf(true));
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for a cluster")
-    public boolean disableHA(final Cluster cluster) {
-        clusterDetailsDao.persist(cluster.getId(), HA_ENABLED_DETAIL, String.valueOf(false));
-        return transitionResourceStateToDisabled(cluster);
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_ENABLE, eventDescription = "enabling HA for a zone")
-    public boolean enableHA(final DataCenter zone) {
-        dataCenterDetailsDao.persist(zone.getId(), HA_ENABLED_DETAIL, String.valueOf(true));
-        return true;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_HA_RESOURCE_DISABLE, eventDescription = "disabling HA for a zone")
-    public boolean disableHA(final DataCenter zone) {
-        dataCenterDetailsDao.persist(zone.getId(), HA_ENABLED_DETAIL, String.valueOf(false));
-        return transitionResourceStateToDisabled(zone);
-    }
-
-    @Override
-    public List<HAConfig> listHAResources(final Long resourceId, final HAResource.ResourceType resourceType) {
-        return haConfigDao.listHAResource(resourceId, resourceType);
-    }
-
-    @Override
-    public List<String> listHAProviders(final HAResource.ResourceType resourceType, final HAResource.ResourceSubType entityType) {
-        final List<String> haProviderNames = new ArrayList<>();
-        for (final HAProvider<HAResource> haProvider : haProviders) {
-            if (haProvider.resourceType().equals(resourceType) && haProvider.resourceSubType().equals(entityType)) {
-                haProviderNames.add(haProvider.getClass().getSimpleName());
-            }
-        }
-        return haProviderNames;
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<>();
-        cmdList.add(ConfigureHAForHostCmd.class);
-        cmdList.add(EnableHAForHostCmd.class);
-        cmdList.add(EnableHAForClusterCmd.class);
-        cmdList.add(EnableHAForZoneCmd.class);
-        cmdList.add(DisableHAForHostCmd.class);
-        cmdList.add(DisableHAForClusterCmd.class);
-        cmdList.add(DisableHAForZoneCmd.class);
-        cmdList.add(ListHostHAResourcesCmd.class);
-        cmdList.add(ListHostHAProvidersCmd.class);
-        return cmdList;
-    }
-
-    //////////////////////////////////////////////////////
-    //////////////// Event Listeners /////////////////////
-    //////////////////////////////////////////////////////
-
-    @Override
-    public void onManagementNodeJoined(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeLeft(List<? extends ManagementServerHost> nodeList, long selfNodeId) {
-    }
-
-    @Override
-    public void onManagementNodeIsolated() {
-    }
-
-    private boolean processHAStateChange(final HAConfig haConfig, final HAConfig.HAState newState, final boolean status) {
-        if (!status || !checkHAOwnership(haConfig)) {
-            return false;
-        }
-
-        final HAResource resource = validateAndFindHAResource(haConfig);
-        if (resource == null) {
-            return false;
-        }
-
-        final HAProvider<HAResource> haProvider = validateAndFindHAProvider(haConfig, resource);
-        if (haProvider == null) {
-            return false;
-        }
-
-        final HAResourceCounter counter = getHACounter(haConfig.getResourceId(), haConfig.getResourceType());
-
-        // Perform activity checks
-        if (newState == HAConfig.HAState.Checking) {
-            final ActivityCheckTask job = ComponentContext.inject(new ActivityCheckTask(resource, haProvider, haConfig,
-                    HAProviderConfig.ActivityCheckTimeout, activityCheckExecutor, counter.getSuspectTimeStamp()));
-            activityCheckExecutor.submit(job);
-        }
-
-        // Attempt recovery
-        if (newState == HAConfig.HAState.Recovering) {
-            if (counter.getRecoveryCounter() >= (Long) (haProvider.getConfigValue(HAProviderConfig.MaxRecoveryAttempts, resource))) {
-                return false;
-            }
-            final RecoveryTask task = ComponentContext.inject(new RecoveryTask(resource, haProvider, haConfig,
-                    HAProviderConfig.RecoveryTimeout, recoveryExecutor));
-            final Future<Boolean> recoveryFuture = recoveryExecutor.submit(task);
-            counter.setRecoveryFuture(recoveryFuture);
-        }
-
-        // Fencing
-        if (newState == HAConfig.HAState.Fencing) {
-            final FenceTask task = ComponentContext.inject(new FenceTask(resource, haProvider, haConfig,
-                    HAProviderConfig.FenceTimeout, fenceExecutor));
-            final Future<Boolean> fenceFuture = fenceExecutor.submit(task);
-            counter.setFenceFuture(fenceFuture);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean preStateTransitionEvent(final HAConfig.HAState oldState, final HAConfig.Event event, final HAConfig.HAState newState, final HAConfig haConfig, final boolean status, final Object opaque) {
-        if (oldState != newState || newState == HAConfig.HAState.Suspect || newState == HAConfig.HAState.Checking) {
-            return false;
-        }
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("HA state pre-transition:: new state=" + newState + ", old state=" + oldState + ", for resource id=" + haConfig.getResourceId() + ", status=" + status + ", ha config state=" + haConfig.getState());
-        }
-        if (status && haConfig.getState() != newState) {
-            LOG.warn("HA state pre-transition:: HA state is not equal to transition state, HA state=" + haConfig.getState() + ", new state=" + newState);
-        }
-        return processHAStateChange(haConfig, newState, status);
-    }
-
-    @Override
-    public boolean postStateTransitionEvent(final StateMachine2.Transition<HAConfig.HAState, HAConfig.Event> transition, final HAConfig haConfig, final boolean status, final Object opaque) {
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("HA state post-transition:: new state=" + transition.getToState() + ", old state=" + transition.getCurrentState() + ", for resource id=" + haConfig.getResourceId() + ", status=" + status + ", ha config state=" + haConfig.getState());
-        }
-        if (status && haConfig.getState() != transition.getToState()) {
-            LOG.warn("HA state post-transition:: HA state is not equal to transition state, HA state=" + haConfig.getState() + ", new state=" + transition.getToState());
-        }
-        return processHAStateChange(haConfig, transition.getToState(), status);
-    }
-
-    ///////////////////////////////////////////////////
-    //////////////// Manager Init /////////////////////
-    ///////////////////////////////////////////////////
-
-    @Override
-    public boolean start() {
-        haProviderMap.clear();
-        for (final HAProvider<HAResource> haProvider : haProviders) {
-            haProviderMap.put(haProvider.getClass().getSimpleName().toLowerCase(), haProvider);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        haConfigDao.expireServerOwnership(ManagementServerNode.getManagementServerId());
-        return true;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        // Health Check
-        final int healthCheckWorkers = MaxConcurrentHealthCheckOperations.value();
-        final int healthCheckQueueSize = MaxPendingHealthCheckOperations.value();
-        healthCheckExecutor = new ThreadPoolExecutor(healthCheckWorkers, healthCheckWorkers,
-                0L, TimeUnit.MILLISECONDS,
-                new ArrayBlockingQueue<Runnable>(healthCheckQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
-
-        // Activity Check
-        final int activityCheckWorkers = MaxConcurrentActivityCheckOperations.value();
-        final int activityCheckQueueSize = MaxPendingActivityCheckOperations.value();
-        activityCheckExecutor = new ThreadPoolExecutor(activityCheckWorkers, activityCheckWorkers,
-                0L, TimeUnit.MILLISECONDS,
-                new ArrayBlockingQueue<Runnable>(activityCheckQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
-
-        // Recovery
-        final int recoveryOperationWorkers = MaxConcurrentRecoveryOperations.value();
-        final int recoveryOperationQueueSize = MaxPendingRecoveryOperations.value();
-        recoveryExecutor = new ThreadPoolExecutor(recoveryOperationWorkers, recoveryOperationWorkers,
-                0L, TimeUnit.MILLISECONDS,
-                new ArrayBlockingQueue<Runnable>(recoveryOperationQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
-
-        // Fence
-        final int fenceOperationWorkers = MaxConcurrentFenceOperations.value();
-        final int fenceOperationQueueSize = MaxPendingFenceOperations.value();
-        fenceExecutor = new ThreadPoolExecutor(fenceOperationWorkers, fenceOperationWorkers,
-                0L, TimeUnit.MILLISECONDS,
-                new ArrayBlockingQueue<Runnable>(fenceOperationQueueSize, true), new ThreadPoolExecutor.CallerRunsPolicy());
-
-        pollManager.submitTask(new HAManagerBgPollTask());
-        HAConfig.HAState.getStateMachine().registerListener(this);
-
-        LOG.debug("HA manager has been configured");
-        return true;
-    }
-
-    public void setHaProviders(List<HAProvider<HAResource>> haProviders) {
-        this.haProviders = haProviders;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return HAManager.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {
-                MaxConcurrentHealthCheckOperations,
-                MaxPendingHealthCheckOperations,
-                MaxConcurrentActivityCheckOperations,
-                MaxPendingActivityCheckOperations,
-                MaxConcurrentRecoveryOperations,
-                MaxPendingRecoveryOperations,
-                MaxConcurrentFenceOperations,
-                MaxPendingFenceOperations
-        };
-    }
-
-    /////////////////////////////////////////////////
-    //////////////// Poll Tasks /////////////////////
-    /////////////////////////////////////////////////
-
-    private final class HAManagerBgPollTask extends ManagedContextRunnable implements BackgroundPollTask {
-        @Override
-        protected void runInContext() {
-            try {
-                if (LOG.isTraceEnabled()) {
-                    LOG.trace("HA health check task is running...");
-                }
-                final List<HAConfig> haConfigList = new ArrayList<HAConfig>(haConfigDao.listAll());
-                for (final HAConfig haConfig : haConfigList) {
-                    if (haConfig == null) {
-                        continue;
-                    }
-
-                    if (!checkHAOwnership(haConfig)) {
-                        continue;
-                    }
-
-                    final HAResource resource = validateAndFindHAResource(haConfig);
-                    if (resource == null) {
-                        continue;
-                    }
-
-                    final HAProvider<HAResource> haProvider = validateAndFindHAProvider(haConfig, resource);
-                    if (haProvider == null) {
-                        continue;
-                    }
-
-                    switch (haConfig.getState()) {
-                        case Available:
-                        case Suspect:
-                        case Degraded:
-                        case Fenced:
-                            final HealthCheckTask task = ComponentContext.inject(new HealthCheckTask(resource, haProvider, haConfig,
-                                    HAProviderConfig.HealthCheckTimeout, healthCheckExecutor));
-                            healthCheckExecutor.submit(task);
-                            break;
-                    default:
-                        break;
-                    }
-
-                    final HAResourceCounter counter = getHACounter(haConfig.getResourceId(), haConfig.getResourceType());
-
-                    if (haConfig.getState() == HAConfig.HAState.Suspect) {
-                        if (counter.canPerformActivityCheck((Long)(haProvider.getConfigValue(HAProviderConfig.MaxActivityCheckInterval, resource)))) {
-                            transitionHAState(HAConfig.Event.PerformActivityCheck, haConfig);
-                        }
-                    }
-
-                    if (haConfig.getState() == HAConfig.HAState.Degraded) {
-                        if (counter.canRecheckActivity((Long)(haProvider.getConfigValue(HAProviderConfig.MaxDegradedWaitTimeout, resource)))) {
-                            transitionHAState(HAConfig.Event.PeriodicRecheckResourceActivity, haConfig);
-                        }
-                    }
-
-                    if (haConfig.getState() == HAConfig.HAState.Recovering) {
-                        if (counter.getRecoveryCounter() >= (Long) (haProvider.getConfigValue(HAProviderConfig.MaxRecoveryAttempts, resource))) {
-                            transitionHAState(HAConfig.Event.RecoveryOperationThresholdExceeded, haConfig);
-                        } else {
-                            transitionHAState(HAConfig.Event.RetryRecovery, haConfig);
-                        }
-                    }
-
-                    if (haConfig.getState() == HAConfig.HAState.Recovered) {
-                        counter.markRecoveryStarted();
-                        if (counter.canExitRecovery((Long)(haProvider.getConfigValue(HAProviderConfig.RecoveryWaitTimeout, resource)))) {
-                            if (transitionHAState(HAConfig.Event.RecoveryWaitPeriodTimeout, haConfig)) {
-                                counter.markRecoveryCompleted();
-                            }
-                        }
-                    }
-
-                    if (haConfig.getState() == HAConfig.HAState.Fencing && counter.canAttemptFencing()) {
-                        transitionHAState(HAConfig.Event.RetryFencing, haConfig);
-                    }
-                }
-            } catch (Throwable t) {
-                LOG.error("Error trying to perform health checks in HA manager", t);
-            }
-        }
-
-        @Override
-        public Long getDelay() {
-            return null;
-        }
-    }
-}
diff --git a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java b/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
deleted file mode 100644
index 35d846b..0000000
--- a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
+++ /dev/null
@@ -1,320 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.network.topology;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.VpnUser;
-import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.router.CommandSetupHelper;
-import com.cloud.network.router.NetworkHelper;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.AdvancedVpnRules;
-import com.cloud.network.rules.BasicVpnRules;
-import com.cloud.network.rules.DhcpEntryRules;
-import com.cloud.network.rules.DhcpPvlanRules;
-import com.cloud.network.rules.DhcpSubNetRules;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRules;
-import com.cloud.network.rules.IpAssociationRules;
-import com.cloud.network.rules.LoadBalancingRules;
-import com.cloud.network.rules.NetworkAclsRules;
-import com.cloud.network.rules.NicPlugInOutRules;
-import com.cloud.network.rules.PasswordToRouterRules;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.rules.PrivateGatewayRules;
-import com.cloud.network.rules.SshKeyToRouterRules;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.rules.StaticNatRules;
-import com.cloud.network.rules.StaticRoutesRules;
-import com.cloud.network.rules.UserdataPwdRules;
-import com.cloud.network.rules.UserdataToRouterRules;
-import com.cloud.network.rules.VirtualNetworkApplianceFactory;
-import com.cloud.network.rules.VpcIpAssociationRules;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.NicIpAliasVO;
-
-@Component
-public class BasicNetworkVisitor extends NetworkTopologyVisitor {
-
-    private static final Logger s_logger = Logger.getLogger(BasicNetworkVisitor.class);
-
-    @Autowired
-    @Qualifier("networkHelper")
-    protected NetworkHelper _networkGeneralHelper;
-
-    @Inject
-    protected VirtualNetworkApplianceFactory _virtualNetworkApplianceFactory;
-
-    @Inject
-    protected CommandSetupHelper _commandSetupHelper;
-
-    @Override
-    public VirtualNetworkApplianceFactory getVirtualNetworkApplianceFactory() {
-        return _virtualNetworkApplianceFactory;
-    }
-
-    @Override
-    public boolean visit(final StaticNatRules nat) throws ResourceUnavailableException {
-        final Network network = nat.getNetwork();
-        final VirtualRouter router = nat.getRouter();
-        final List<? extends StaticNat> rules = nat.getRules();
-
-        final Commands cmds = new Commands(Command.OnError.Continue);
-        _commandSetupHelper.createApplyStaticNatCommands(rules, router, cmds, network.getId());
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    @Override
-    public boolean visit(final LoadBalancingRules loadbalancing) throws ResourceUnavailableException {
-        final Network network = loadbalancing.getNetwork();
-        final DomainRouterVO router = (DomainRouterVO) loadbalancing.getRouter();
-        final List<LoadBalancingRule> rules = loadbalancing.getRules();
-
-        final Commands cmds = new Commands(Command.OnError.Continue);
-        _commandSetupHelper.createApplyLoadBalancingRulesCommands(rules, router, cmds, network.getId());
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean visit(final FirewallRules firewall) throws ResourceUnavailableException {
-        final Network network = firewall.getNetwork();
-        final VirtualRouter router = firewall.getRouter();
-        final List<? extends FirewallRule> rules = firewall.getRules();
-        final List<LoadBalancingRule> loadbalancingRules = firewall.getLoadbalancingRules();
-
-        final Purpose purpose = firewall.getPurpose();
-
-        final Commands cmds = new Commands(Command.OnError.Continue);
-        if (purpose == Purpose.LoadBalancing) {
-
-            _commandSetupHelper.createApplyLoadBalancingRulesCommands(loadbalancingRules, router, cmds, network.getId());
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-
-        } else if (purpose == Purpose.PortForwarding) {
-
-            _commandSetupHelper.createApplyPortForwardingRulesCommands((List<? extends PortForwardingRule>) rules, router, cmds, network.getId());
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-
-        } else if (purpose == Purpose.StaticNat) {
-
-            _commandSetupHelper.createApplyStaticNatRulesCommands((List<StaticNatRule>) rules, router, cmds, network.getId());
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-
-        } else if (purpose == Purpose.Firewall) {
-
-            _commandSetupHelper.createApplyFirewallRulesCommands(rules, router, cmds, network.getId());
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-
-        }
-        s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose());
-
-        return false;
-    }
-
-    @Override
-    public boolean visit(final IpAssociationRules ipRules) throws ResourceUnavailableException {
-        final Network network = ipRules.getNetwork();
-        final VirtualRouter router = ipRules.getRouter();
-
-        final Commands commands = new Commands(Command.OnError.Continue);
-        final List<? extends PublicIpAddress> ips = ipRules.getIpAddresses();
-
-        _commandSetupHelper.createAssociateIPCommands(router, ips, commands, network.getId());
-        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
-    }
-
-    @Override
-    public boolean visit(final UserdataPwdRules userdata) throws ResourceUnavailableException {
-        final VirtualRouter router = userdata.getRouter();
-
-        final Commands commands = new Commands(Command.OnError.Stop);
-        final VirtualMachineProfile profile = userdata.getProfile();
-        final NicVO nicVo = userdata.getNicVo();
-        final UserVmVO userVM = userdata.getUserVM();
-        final DeployDestination destination = userdata.getDestination();
-
-        if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {
-            _commandSetupHelper.createPasswordCommand(router, profile, nicVo, commands);
-            _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, userVM.getDetail("SSH.PublicKey"), commands);
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, commands);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean visit(final DhcpEntryRules dhcp) throws ResourceUnavailableException {
-        final VirtualRouter router = dhcp.getRouter();
-
-        final Commands commands = new Commands(Command.OnError.Stop);
-        final NicVO nicVo = dhcp.getNicVo();
-        final UserVmVO userVM = dhcp.getUserVM();
-        final DeployDestination destination = dhcp.getDestination();
-        final boolean remove = dhcp.isRemove();
-
-        if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {
-            _commandSetupHelper.createDhcpEntryCommand(router, userVM, nicVo, remove, commands);
-
-            return _networkGeneralHelper.sendCommandsToRouter(router, commands);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean visit(final SshKeyToRouterRules sshkey) throws ResourceUnavailableException {
-        final VirtualRouter router = sshkey.getRouter();
-        final VirtualMachineProfile profile = sshkey.getProfile();
-        final String sshKeystr = sshkey.getSshPublicKey();
-        final UserVmVO userVM = sshkey.getUserVM();
-
-        final Commands commands = new Commands(Command.OnError.Stop);
-        final NicVO nicVo = sshkey.getNicVo();
-        final VMTemplateVO template = sshkey.getTemplate();
-
-        if (template != null && template.getEnablePassword()) {
-            _commandSetupHelper.createPasswordCommand(router, profile, nicVo, commands);
-        }
-
-        _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, sshKeystr, commands);
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
-    }
-
-    @Override
-    public boolean visit(final PasswordToRouterRules passwd) throws ResourceUnavailableException {
-        final VirtualRouter router = passwd.getRouter();
-        final NicVO nicVo = passwd.getNicVo();
-        final VirtualMachineProfile profile = passwd.getProfile();
-
-        final Commands cmds = new Commands(Command.OnError.Stop);
-        _commandSetupHelper.createPasswordCommand(router, profile, nicVo, cmds);
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    @Override
-    public boolean visit(final UserdataToRouterRules userdata) throws ResourceUnavailableException {
-        final VirtualRouter router = userdata.getRouter();
-
-        final UserVmVO userVM = userdata.getUserVM();
-        final NicVO nicVo = userdata.getNicVo();
-
-        final Commands commands = new Commands(Command.OnError.Stop);
-        _commandSetupHelper.createVmDataCommand(router, userVM, nicVo, null, commands);
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, commands);
-    }
-
-    @Override
-    public boolean visit(final BasicVpnRules vpnRules) throws ResourceUnavailableException {
-        final VirtualRouter router = vpnRules.getRouter();
-        final List<? extends VpnUser> users = vpnRules.getUsers();
-
-        final Commands cmds = new Commands(Command.OnError.Continue);
-        _commandSetupHelper.createApplyVpnUsersCommand(users, router, cmds);
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    @Override
-    public boolean visit(final DhcpSubNetRules subnet) throws ResourceUnavailableException {
-        final VirtualRouter router = subnet.getRouter();
-        final Network network = subnet.getNetwork();
-        final NicIpAliasVO nicAlias = subnet.getNicAlias();
-        final String routerAliasIp = subnet.getRouterAliasIp();
-
-        final Commands cmds = new Commands(Command.OnError.Stop);
-
-        final List<IpAliasTO> ipaliasTo = new ArrayList<IpAliasTO>();
-        ipaliasTo.add(new IpAliasTO(routerAliasIp, nicAlias.getNetmask(), nicAlias.getAliasCount().toString()));
-
-        _commandSetupHelper.createIpAlias(router, ipaliasTo, nicAlias.getNetworkId(), cmds);
-
-        // also add the required configuration to the dnsmasq for supporting
-        // dhcp and dns on the new ip.
-        _commandSetupHelper.configDnsMasq(router, network, cmds);
-
-        return _networkGeneralHelper.sendCommandsToRouter(router, cmds);
-    }
-
-    @Override
-    public boolean visit(final DhcpPvlanRules dhcpRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("DhcpPvlanRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final NicPlugInOutRules nicPlugInOutRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("NicPlugInOutRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final NetworkAclsRules aclsRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("NetworkAclsRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final VpcIpAssociationRules ipRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("VpcIpAssociationRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final PrivateGatewayRules pvtGatewayRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("PrivateGatewayRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final StaticRoutesRules staticRoutesRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("StaticRoutesRules not implemented in Basic Network Topology.");
-    }
-
-    @Override
-    public boolean visit(final AdvancedVpnRules vpnRules) throws ResourceUnavailableException {
-        throw new CloudRuntimeException("AdvancedVpnRules not implemented in Basic Network Topology.");
-    }
-}
\ No newline at end of file
diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java
deleted file mode 100644
index 583dcfc..0000000
--- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java
+++ /dev/null
@@ -1,725 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.region.gslb;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.AssignToGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.CreateGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.DeleteGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.ListGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.RemoveFromGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.api.command.user.region.ha.gslb.UpdateGlobalLoadBalancerRuleCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.region.Region;
-import org.apache.cloudstack.region.dao.RegionDao;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.SiteLoadBalancerConfig;
-import com.cloud.configuration.Config;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.rules.LoadBalancer;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.region.ha.GlobalLoadBalancerRule;
-import com.cloud.region.ha.GlobalLoadBalancingRulesService;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-
-public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingRulesService {
-
-    private static final Logger s_logger = Logger.getLogger(GlobalLoadBalancingRulesServiceImpl.class);
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    GlobalLoadBalancerRuleDao _gslbRuleDao;
-    @Inject
-    GlobalLoadBalancerLbRuleMapDao _gslbLbMapDao;
-    @Inject
-    RegionDao _regionDao;
-    @Inject
-    RulesManager _rulesMgr;
-    @Inject
-    LoadBalancerDao _lbDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    ConfigurationDao _globalConfigDao;
-    @Inject
-    IPAddressDao _ipAddressDao;
-    @Inject
-    AgentManager _agentMgr;
-
-    protected List<GslbServiceProvider> _gslbProviders;
-
-    public void setGslbServiceProviders(List<GslbServiceProvider> providers) {
-        _gslbProviders = providers;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, eventDescription = "creating global load " + "balancer rule", create = true)
-    public GlobalLoadBalancerRule createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newRule) {
-
-        final Integer regionId = newRule.getRegionId();
-        final String algorithm = newRule.getAlgorithm();
-        final String stickyMethod = newRule.getStickyMethod();
-        final String name = newRule.getName();
-        final String description = newRule.getDescription();
-        final String domainName = newRule.getServiceDomainName();
-        final String serviceType = newRule.getServiceType();
-
-        final Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId());
-
-        if (!GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
-            throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
-        }
-
-        if (!GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
-            throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
-        }
-
-        if (!GlobalLoadBalancerRule.ServiceType.isValidServiceType(serviceType)) {
-            throw new InvalidParameterValueException("Invalid service type: " + serviceType);
-        }
-
-        if (!NetUtils.verifyDomainName(domainName)) {
-            throw new InvalidParameterValueException("Invalid domain name : " + domainName);
-        }
-
-        GlobalLoadBalancerRuleVO gslbRuleWithDomainName = _gslbRuleDao.findByDomainName(domainName);
-        if (gslbRuleWithDomainName != null) {
-            throw new InvalidParameterValueException("Domain name " + domainName + "is in use");
-        }
-
-        Region region = _regionDao.findById(regionId);
-        if (region == null) {
-            throw new InvalidParameterValueException("Invalid region ID: " + regionId);
-        }
-
-        String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
-        if (!region.checkIfServiceEnabled(Region.Service.Gslb) || (providerDnsName == null)) {
-            throw new CloudRuntimeException("GSLB service is not enabled in region : " + region.getName());
-        }
-
-        GlobalLoadBalancerRuleVO newGslbRule = Transaction.execute(new TransactionCallback<GlobalLoadBalancerRuleVO>() {
-            @Override
-            public GlobalLoadBalancerRuleVO doInTransaction(TransactionStatus status) {
-                GlobalLoadBalancerRuleVO newGslbRule =
-                    new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, stickyMethod, serviceType, regionId, gslbOwner.getId(),
-                        gslbOwner.getDomainId(), GlobalLoadBalancerRule.State.Staged);
-                _gslbRuleDao.persist(newGslbRule);
-
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), 0, newGslbRule.getId(), name,
-                    GlobalLoadBalancerRule.class.getName(), newGslbRule.getUuid());
-
-                return newGslbRule;
-            }
-        });
-
-        s_logger.debug("successfully created new global load balancer rule for the account " + gslbOwner.getId());
-
-        return newGslbRule;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_ASSIGN_TO_GLOBAL_LOAD_BALANCER_RULE,
-                 eventDescription = "Assigning a load balancer rule to global load balancer rule",
-                 async = true)
-    public boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd) {
-
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        final long gslbRuleId = assignToGslbCmd.getGlobalLoadBalancerRuleId();
-        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
-        if (gslbRule == null) {
-            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
-        }
-
-        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
-
-        if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
-            throw new InvalidParameterValueException("global load balancer rule id: " + gslbRule.getUuid() + " is in revoked state");
-        }
-
-        final List<Long> newLbRuleIds = assignToGslbCmd.getLoadBalancerRulesIds();
-        if (newLbRuleIds == null || newLbRuleIds.isEmpty()) {
-            throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be assigned" + " global load balancer rule");
-        }
-
-        List<Long> oldLbRuleIds = new ArrayList<Long>();
-        List<Long> oldZones = new ArrayList<Long>();
-        List<Long> newZones = new ArrayList<Long>(oldZones);
-        List<Pair<Long, Long>> physcialNetworks = new ArrayList<Pair<Long, Long>>();
-
-        // get the list of load balancer rules id's that are assigned currently to GSLB rule and corresponding zone id's
-        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
-        if (gslbLbMapVos != null) {
-            for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
-                LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
-                Network network = _networkDao.findById(loadBalancer.getNetworkId());
-                oldZones.add(network.getDataCenterId());
-                oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
-            }
-        }
-
-        /* check each of the load balancer rule id passed in the 'AssignToGlobalLoadBalancerRuleCmd' command is
-         *     valid ID
-         *     caller has access to the rule
-         *     check rule is not revoked
-         *     no two rules are in same zone
-         *     rule is not already assigned to gslb rule
-         */
-        for (Long lbRuleId : newLbRuleIds) {
-
-            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
-            if (loadBalancer == null) {
-                throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
-            }
-
-            _accountMgr.checkAccess(caller, null, true, loadBalancer);
-
-            if (gslbRule.getAccountId() != loadBalancer.getAccountId()) {
-                throw new InvalidParameterValueException("GSLB rule and load balancer rule does not belong to same account");
-            }
-
-            if (loadBalancer.getState() == LoadBalancer.State.Revoke) {
-                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is in revoke state");
-            }
-
-            if (oldLbRuleIds != null && oldLbRuleIds.contains(loadBalancer.getId())) {
-                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is already assigned");
-            }
-
-            Network network = _networkDao.findById(loadBalancer.getNetworkId());
-
-            if (oldZones != null && oldZones.contains(network.getDataCenterId()) || newZones != null && newZones.contains(network.getDataCenterId())) {
-                throw new InvalidParameterValueException("Load balancer rule specified should be in unique zone");
-            }
-
-            newZones.add(network.getDataCenterId());
-            physcialNetworks.add(new Pair<Long, Long>(network.getDataCenterId(), network.getPhysicalNetworkId()));
-        }
-
-        // for each of the physical network check if GSLB service provider configured
-        for (Pair<Long, Long> physicalNetwork : physcialNetworks) {
-            if (!checkGslbServiceEnabledInZone(physicalNetwork.first(), physicalNetwork.second())) {
-                throw new InvalidParameterValueException("GSLB service is not enabled in the Zone:" + physicalNetwork.first() + " and physical network " +
-                    physicalNetwork.second());
-            }
-        }
-
-        final Map<Long, Long> lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap();
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // persist the mapping for the new Lb rule that needs to assigned to a gslb rule
-                for (Long lbRuleId : newLbRuleIds) {
-                    GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO();
-                    newGslbLbMap.setGslbLoadBalancerId(gslbRuleId);
-                    newGslbLbMap.setLoadBalancerId(lbRuleId);
-                    if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) {
-                        newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId));
-                    }
-                    _gslbLbMapDao.persist(newGslbLbMap);
-                }
-
-                // mark the gslb rule state as add
-                if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
-                    gslbRule.setState(GlobalLoadBalancerRule.State.Add);
-                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-                }
-            }
-        });
-
-        boolean success = false;
-        try {
-            s_logger.debug("Configuring gslb rule configuration on the gslb service providers in the participating zones");
-
-            // apply the gslb rule on to the back end gslb service providers on zones participating in gslb
-            if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
-                s_logger.warn("Failed to add load balancer rules " + newLbRuleIds + " to global load balancer rule id " + gslbRuleId);
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to add load balancer rules to GSLB rule ");
-                throw ex;
-            }
-
-            // on success set state to Active
-            gslbRule.setState(GlobalLoadBalancerRule.State.Active);
-            _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-
-            success = true;
-
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Failed to apply new GSLB configuration while assigning new LB rules to GSLB rule.");
-        }
-
-        return success;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_REMOVE_FROM_GLOBAL_LOAD_BALANCER_RULE,
-                 eventDescription = "Removing a load balancer rule to be part of global load balancer rule")
-    public boolean removeFromGlobalLoadBalancerRule(RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd) {
-
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        final long gslbRuleId = removeFromGslbCmd.getGlobalLoadBalancerRuleId();
-        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
-        if (gslbRule == null) {
-            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
-        }
-
-        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
-
-        if (gslbRule.getState() == GlobalLoadBalancerRule.State.Revoke) {
-            throw new InvalidParameterValueException("global load balancer rule id: " + gslbRuleId + " is already in revoked state");
-        }
-
-        final List<Long> lbRuleIdsToremove = removeFromGslbCmd.getLoadBalancerRulesIds();
-        if (lbRuleIdsToremove == null || lbRuleIdsToremove.isEmpty()) {
-            throw new InvalidParameterValueException("empty list of load balancer rule Ids specified to be un-assigned" + " to global load balancer rule");
-        }
-
-        // get the active list of LB rule id's that are assigned currently to GSLB rule and corresponding zone id's
-        List<Long> oldLbRuleIds = new ArrayList<Long>();
-        List<Long> oldZones = new ArrayList<Long>();
-
-        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
-        if (gslbLbMapVos == null) {
-            throw new InvalidParameterValueException(" There are no load balancer rules that are assigned to global " + " load balancer rule id: " + gslbRule.getUuid() +
-                " that are available for deletion");
-        }
-
-        for (Long lbRuleId : lbRuleIdsToremove) {
-            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
-            if (loadBalancer == null) {
-                throw new InvalidParameterValueException("Specified load balancer rule ID does not exist.");
-            }
-
-            _accountMgr.checkAccess(caller, null, true, loadBalancer);
-        }
-
-        for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
-            LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
-            Network network = _networkDao.findById(loadBalancer.getNetworkId());
-            oldLbRuleIds.add(gslbLbMapVo.getLoadBalancerId());
-            oldZones.add(network.getDataCenterId());
-        }
-
-        for (Long lbRuleId : lbRuleIdsToremove) {
-            LoadBalancerVO loadBalancer = _lbDao.findById(lbRuleId);
-            if (oldLbRuleIds != null && !oldLbRuleIds.contains(loadBalancer.getId())) {
-                throw new InvalidParameterValueException("Load balancer ID " + loadBalancer.getUuid() + " is not assigned" + " to global load balancer rule: " +
-                    gslbRule.getUuid());
-            }
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // update the mapping of gslb rule to Lb rule, to revoke state
-                for (Long lbRuleId : lbRuleIdsToremove) {
-                    GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId);
-                    removeGslbLbMap.setRevoke(true);
-                    _gslbLbMapDao.update(removeGslbLbMap.getId(), removeGslbLbMap);
-                }
-
-                // mark the gslb rule state as add
-                if (gslbRule.getState() == GlobalLoadBalancerRule.State.Staged) {
-                    gslbRule.setState(GlobalLoadBalancerRule.State.Add);
-                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-                }
-
-            }
-        });
-
-        boolean success = false;
-        try {
-            s_logger.debug("Attempting to configure global load balancer rule configuration on the gslb service providers ");
-
-            // apply the gslb rule on to the back end gslb service providers
-            if (!applyGlobalLoadBalancerRuleConfig(gslbRuleId, false)) {
-                s_logger.warn("Failed to remove load balancer rules " + lbRuleIdsToremove + " from global load balancer rule id " + gslbRuleId);
-                CloudRuntimeException ex = new CloudRuntimeException("Failed to remove load balancer rule ids from GSLB rule ");
-                throw ex;
-            }
-
-            Transaction.execute(new TransactionCallbackNoReturn() {
-                @Override
-                public void doInTransactionWithoutResult(TransactionStatus status) {
-                    // remove the mappings of gslb rule to Lb rule that are in revoked state
-                    for (Long lbRuleId : lbRuleIdsToremove) {
-                        GlobalLoadBalancerLbRuleMapVO removeGslbLbMap = _gslbLbMapDao.findByGslbRuleIdAndLbRuleId(gslbRuleId, lbRuleId);
-                        _gslbLbMapDao.remove(removeGslbLbMap.getId());
-                    }
-
-                    // on success set state back to Active
-                    gslbRule.setState(GlobalLoadBalancerRule.State.Active);
-                    _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-
-                }
-            });
-
-            success = true;
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Failed to update removed load balancer details from gloabal load balancer");
-        }
-
-        return success;
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, eventDescription = "Delete global load balancer rule")
-    public boolean deleteGlobalLoadBalancerRule(DeleteGlobalLoadBalancerRuleCmd deleteGslbCmd) {
-
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-        long gslbRuleId = deleteGslbCmd.getGlobalLoadBalancerId();
-
-        try {
-            revokeGslbRule(gslbRuleId, caller);
-        } catch (Exception e) {
-            s_logger.warn("Failed to delete GSLB rule due to" + e.getMessage());
-            return false;
-        }
-
-        return true;
-    }
-
-    @DB
-    private void revokeGslbRule(final long gslbRuleId, Account caller) {
-
-        final GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
-
-        if (gslbRule == null) {
-            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
-        }
-
-        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
-
-        if (gslbRule.getState() == com.cloud.region.ha.GlobalLoadBalancerRule.State.Staged) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Rule Id: " + gslbRuleId + " is still in Staged state so just removing it.");
-            }
-            _gslbRuleDao.remove(gslbRuleId);
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(),
-                GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
-            return;
-        } else if (gslbRule.getState() == GlobalLoadBalancerRule.State.Add || gslbRule.getState() == GlobalLoadBalancerRule.State.Active) {
-            //mark the GSlb rule to be in revoke state
-            gslbRule.setState(GlobalLoadBalancerRule.State.Revoke);
-            _gslbRuleDao.update(gslbRuleId, gslbRule);
-        }
-
-        final List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = Transaction.execute(new TransactionCallback<List<GlobalLoadBalancerLbRuleMapVO>>() {
-            @Override
-            public List<GlobalLoadBalancerLbRuleMapVO> doInTransaction(TransactionStatus status) {
-                List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
-                if (gslbLbMapVos != null) {
-                    //mark all the GSLB-LB mapping to be in revoke state
-                    for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
-                        gslbLbMap.setRevoke(true);
-                        _gslbLbMapDao.update(gslbLbMap.getId(), gslbLbMap);
-                    }
-                }
-
-                return gslbLbMapVos;
-            }
-        });
-
-        try {
-            if (gslbLbMapVos != null) {
-                applyGlobalLoadBalancerRuleConfig(gslbRuleId, true);
-            }
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Failed to update the gloabal load balancer");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                //remove all mappings between GSLB rule and load balancer rules
-                if (gslbLbMapVos != null) {
-                    for (GlobalLoadBalancerLbRuleMapVO gslbLbMap : gslbLbMapVos) {
-                        _gslbLbMapDao.remove(gslbLbMap.getId());
-                    }
-                }
-
-                //remove the GSLB rule itself
-                _gslbRuleDao.remove(gslbRuleId);
-
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_DELETE, gslbRule.getAccountId(), 0, gslbRule.getId(), gslbRule.getName(),
-                    GlobalLoadBalancerRule.class.getName(), gslbRule.getUuid());
-            }
-        });
-
-    }
-
-    @Override
-    public GlobalLoadBalancerRule updateGlobalLoadBalancerRule(UpdateGlobalLoadBalancerRuleCmd updateGslbCmd) {
-
-        String algorithm = updateGslbCmd.getAlgorithm();
-        String stickyMethod = updateGslbCmd.getStickyMethod();
-        String description = updateGslbCmd.getDescription();
-
-        long gslbRuleId = updateGslbCmd.getId();
-        GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
-        if (gslbRule == null) {
-            throw new InvalidParameterValueException("Invalid global load balancer rule id: " + gslbRuleId);
-        }
-
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        _accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, gslbRule);
-
-        if (algorithm != null && !GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
-            throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
-        }
-
-        if (stickyMethod != null && !GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
-            throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
-        }
-
-        if (algorithm != null) {
-            gslbRule.setAlgorithm(algorithm);
-        }
-        if (stickyMethod != null) {
-            gslbRule.setPersistence(stickyMethod);
-        }
-        if (description != null) {
-            gslbRule.setDescription(description);
-        }
-        gslbRule.setState(GlobalLoadBalancerRule.State.Add);
-        _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-
-        try {
-            s_logger.debug("Updating global load balancer with id " + gslbRule.getUuid());
-
-            // apply the gslb rule on to the back end gslb service providers on zones participating in gslb
-            applyGlobalLoadBalancerRuleConfig(gslbRuleId, false);
-
-            // on success set state to Active
-            gslbRule.setState(GlobalLoadBalancerRule.State.Active);
-            _gslbRuleDao.update(gslbRule.getId(), gslbRule);
-
-            return gslbRule;
-        } catch (ResourceUnavailableException e) {
-            throw new CloudRuntimeException("Failed to configure gslb config due to " + e.getMessage());
-        }
-    }
-
-    @Override
-    public List<GlobalLoadBalancerRule> listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd) {
-
-        CallContext ctx = CallContext.current();
-        Account caller = ctx.getCallingAccount();
-
-        Integer regionId = listGslbCmd.getRegionId();
-        Long ruleId = listGslbCmd.getId();
-        List<GlobalLoadBalancerRule> response = new ArrayList<GlobalLoadBalancerRule>();
-        if (regionId == null && ruleId == null) {
-            throw new InvalidParameterValueException("Invalid arguments. At least one of region id, " + "rule id must be specified");
-        }
-
-        if (regionId != null && ruleId != null) {
-            throw new InvalidParameterValueException("Invalid arguments. Only one of region id, " + "rule id must be specified");
-        }
-
-        if (ruleId != null) {
-            GlobalLoadBalancerRule gslbRule = _gslbRuleDao.findById(ruleId);
-            if (gslbRule == null) {
-                throw new InvalidParameterValueException("Invalid gslb rule id specified");
-            }
-            _accountMgr.checkAccess(caller, org.apache.cloudstack.acl.SecurityChecker.AccessType.UseEntry, false, gslbRule);
-
-            response.add(gslbRule);
-            return response;
-        }
-
-        if (regionId != null) {
-            List<GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(caller.getAccountId());
-            if (gslbRules != null) {
-                response.addAll(gslbRules);
-            }
-            return response;
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<LoadBalancer> listSiteLoadBalancers(long gslbRuleId) {
-        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
-        List<LoadBalancer> siteLoadBalancers = new ArrayList<LoadBalancer>();
-        if (gslbLbMapVos != null) {
-            for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
-                LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
-                siteLoadBalancers.add(loadBalancer);
-            }
-            return siteLoadBalancers;
-        }
-        return null;
-    }
-
-    private boolean applyGlobalLoadBalancerRuleConfig(long gslbRuleId, boolean revoke) throws ResourceUnavailableException {
-
-        GlobalLoadBalancerRuleVO gslbRule = _gslbRuleDao.findById(gslbRuleId);
-        assert (gslbRule != null);
-
-        String lbMethod = gslbRule.getAlgorithm();
-        String persistenceMethod = gslbRule.getPersistence();
-        String serviceType = gslbRule.getServiceType();
-
-        // each Gslb rule will have a FQDN, formed from the domain name associated with the gslb rule
-        // and the deployment DNS name configured in global config parameter 'cloud.dns.name'
-        String domainName = gslbRule.getGslbDomain();
-        String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
-        String gslbFqdn = domainName + "." + providerDnsName;
-
-        GlobalLoadBalancerConfigCommand gslbConfigCmd = new GlobalLoadBalancerConfigCommand(gslbFqdn, lbMethod, persistenceMethod, serviceType, gslbRuleId, revoke);
-
-        // list of the physical network participating in global load balancing
-        List<Pair<Long, Long>> gslbSiteIds = new ArrayList<Pair<Long, Long>>();
-
-        // map of the zone and info corresponding to the load balancer configured in the zone
-        Map<Long, SiteLoadBalancerConfig> zoneSiteLoadbalancerMap = new HashMap<Long, SiteLoadBalancerConfig>();
-
-        List<GlobalLoadBalancerLbRuleMapVO> gslbLbMapVos = _gslbLbMapDao.listByGslbRuleId(gslbRuleId);
-
-        assert (gslbLbMapVos != null && !gslbLbMapVos.isEmpty());
-
-        for (GlobalLoadBalancerLbRuleMapVO gslbLbMapVo : gslbLbMapVos) {
-
-            // get the zone in which load balancer rule is deployed
-            LoadBalancerVO loadBalancer = _lbDao.findById(gslbLbMapVo.getLoadBalancerId());
-            Network network = _networkDao.findById(loadBalancer.getNetworkId());
-            long dataCenterId = network.getDataCenterId();
-            long physicalNetworkId = network.getPhysicalNetworkId();
-
-            gslbSiteIds.add(new Pair<Long, Long>(dataCenterId, physicalNetworkId));
-
-            IPAddressVO ip = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId());
-            SiteLoadBalancerConfig siteLb =
-                new SiteLoadBalancerConfig(gslbLbMapVo.isRevoke(), serviceType, ip.getAddress().addr(), Integer.toString(loadBalancer.getDefaultPortStart()),
-                    dataCenterId);
-
-            siteLb.setGslbProviderPublicIp(lookupGslbServiceProvider().getZoneGslbProviderPublicIp(dataCenterId, physicalNetworkId));
-            siteLb.setGslbProviderPrivateIp(lookupGslbServiceProvider().getZoneGslbProviderPrivateIp(dataCenterId, physicalNetworkId));
-            siteLb.setWeight(gslbLbMapVo.getWeight());
-
-            zoneSiteLoadbalancerMap.put(network.getDataCenterId(), siteLb);
-        }
-
-        // loop through all the zones, participating in GSLB, and send GSLB config command
-        // to the corresponding GSLB service provider in that zone
-        for (Pair<Long, Long> zoneId : gslbSiteIds) {
-
-            List<SiteLoadBalancerConfig> slbs = new ArrayList<SiteLoadBalancerConfig>();
-            // set site as 'local' for the site in that zone
-            for (Pair<Long, Long> innerLoopZoneId : gslbSiteIds) {
-                SiteLoadBalancerConfig siteLb = zoneSiteLoadbalancerMap.get(innerLoopZoneId.first());
-                siteLb.setLocal(zoneId.first() == innerLoopZoneId.first());
-                slbs.add(siteLb);
-            }
-
-            gslbConfigCmd.setSiteLoadBalancers(slbs);
-            gslbConfigCmd.setForRevoke(revoke);
-
-            // revoke GSLB configuration completely on the site GSLB provider for the sites that no longer
-            // are participants of a GSLB rule
-            SiteLoadBalancerConfig siteLb = zoneSiteLoadbalancerMap.get(zoneId.first());
-            if (siteLb.forRevoke()) {
-                gslbConfigCmd.setForRevoke(true);
-            }
-
-            try {
-                lookupGslbServiceProvider().applyGlobalLoadBalancerRule(zoneId.first(), zoneId.second(), gslbConfigCmd);
-            } catch (ResourceUnavailableException | NullPointerException e) {
-                String msg = "Failed to configure GSLB rule in the zone " + zoneId.first() + " due to " + e.getMessage();
-                s_logger.warn(msg);
-                throw new CloudRuntimeException(msg);
-            }
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean revokeAllGslbRulesForAccount(com.cloud.user.Account caller, long accountId) throws com.cloud.exception.ResourceUnavailableException {
-        List<GlobalLoadBalancerRuleVO> gslbRules = _gslbRuleDao.listByAccount(accountId);
-        if (gslbRules != null && !gslbRules.isEmpty()) {
-            for (GlobalLoadBalancerRule gslbRule : gslbRules) {
-                revokeGslbRule(gslbRule.getId(), caller);
-            }
-        }
-        s_logger.debug("Successfully cleaned up GSLB rules for account id=" + accountId);
-        return true;
-    }
-
-    private boolean checkGslbServiceEnabledInZone(long zoneId, long physicalNetworkId) {
-
-        GslbServiceProvider gslbProvider = lookupGslbServiceProvider();
-        if (gslbProvider == null) {
-            throw new CloudRuntimeException("No GSLB provider is available");
-        }
-
-        return gslbProvider.isServiceEnabledInZone(zoneId, physicalNetworkId);
-    }
-
-    protected GslbServiceProvider lookupGslbServiceProvider() {
-        return _gslbProviders.size() == 0 ? null : _gslbProviders.get(0);
-    }
-
-    @Override
-    public GlobalLoadBalancerRule findById(long gslbRuleId) {
-        return _gslbRuleDao.findById(gslbRuleId);
-    }
-}
\ No newline at end of file
diff --git a/server/test/async-job-component.xml b/server/src/test/async-job-component.xml
similarity index 100%
rename from server/test/async-job-component.xml
rename to server/src/test/async-job-component.xml
diff --git a/server/test/com/cloud/alert/AlertControlsUnitTest.java b/server/src/test/java/com/cloud/alert/AlertControlsUnitTest.java
similarity index 100%
rename from server/test/com/cloud/alert/AlertControlsUnitTest.java
rename to server/src/test/java/com/cloud/alert/AlertControlsUnitTest.java
diff --git a/server/test/com/cloud/alert/MockAlertManagerImpl.java b/server/src/test/java/com/cloud/alert/MockAlertManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/alert/MockAlertManagerImpl.java
rename to server/src/test/java/com/cloud/alert/MockAlertManagerImpl.java
diff --git a/server/test/com/cloud/api/APITest.java b/server/src/test/java/com/cloud/api/APITest.java
similarity index 100%
rename from server/test/com/cloud/api/APITest.java
rename to server/src/test/java/com/cloud/api/APITest.java
diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
new file mode 100644
index 0000000..2809005
--- /dev/null
+++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java
@@ -0,0 +1,144 @@
+// 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.api;
+
+import com.cloud.domain.DomainVO;
+import com.cloud.usage.UsageVO;
+import com.cloud.user.AccountVO;
+import com.cloud.vm.NicSecondaryIp;
+
+import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
+import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.usage.UsageService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.lang.reflect.Field;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ApiDBUtils.class)
+public class ApiResponseHelperTest {
+
+    @Mock
+    UsageService usageService;
+
+    ApiResponseHelper helper;
+
+    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss ZZZ");
+
+    @Before
+    public void injectMocks() throws SecurityException, NoSuchFieldException,
+            IllegalArgumentException, IllegalAccessException {
+        Field usageSvcField = ApiResponseHelper.class
+                .getDeclaredField("_usageSvc");
+        usageSvcField.setAccessible(true);
+        helper = new ApiResponseHelper();
+        usageSvcField.set(helper, usageService);
+    }
+
+    @Test
+    public void getDateStringInternal() throws ParseException {
+        Mockito.when(usageService.getUsageTimezone()).thenReturn(
+                TimeZone.getTimeZone("UTC"));
+        assertEquals("2014-06-29'T'23:45:00+00:00", helper
+                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:00 UTC")));
+        assertEquals("2014-06-29'T'23:45:01+00:00", helper
+                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:01 UTC")));
+        assertEquals("2014-06-29'T'23:45:11+00:00", helper
+                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:11 UTC")));
+        assertEquals("2014-06-29'T'23:05:11+00:00", helper
+                .getDateStringInternal(dateFormat.parse("2014-06-29 23:05:11 UTC")));
+        assertEquals("2014-05-29'T'08:45:11+00:00", helper
+                .getDateStringInternal(dateFormat.parse("2014-05-29 08:45:11 UTC")));
+    }
+
+    @Test
+    public void testUsageRecordResponse(){
+        //Creating the usageVO object to be passed to the createUsageResponse.
+        Long zoneId = null;
+        Long accountId = null;
+        Long domainId = null;
+        String Description = "Test Object";
+        String usageDisplay = " ";
+        int usageType = -1;
+        Double rawUsage = null;
+        Long vmId = null;
+        String vmName = " ";
+        Long offeringId = null;
+        Long templateId = null;
+        Long usageId = null;
+        Date startDate = null;
+        Date endDate = null;
+        String type = " ";
+        UsageVO usage = new UsageVO(zoneId,accountId,domainId,Description,usageDisplay,usageType,rawUsage,vmId,vmName,offeringId,templateId,usageId,startDate,endDate,type);
+
+        DomainVO domain = new DomainVO();
+        domain.setName("DomainName");
+
+        AccountVO account = new AccountVO();
+
+        PowerMockito.mockStatic(ApiDBUtils.class);
+        when(ApiDBUtils.findAccountById(anyLong())).thenReturn(account);
+        when(ApiDBUtils.findDomainById(anyLong())).thenReturn(domain);
+
+        UsageRecordResponse MockResponse = helper.createUsageResponse(usage);
+        assertEquals("DomainName",MockResponse.getDomainName());
+    }
+
+    @Test
+    public void setResponseIpAddressTestIpv4() {
+        NicSecondaryIp result = Mockito.mock(NicSecondaryIp.class);
+        NicSecondaryIpResponse response = new NicSecondaryIpResponse();
+        setResult(result, "ipv4", "ipv6");
+
+        ApiResponseHelper.setResponseIpAddress(result, response);
+
+        assertTrue(response.getIpAddr().equals("ipv4"));
+    }
+
+    private void setResult(NicSecondaryIp result, String ipv4, String ipv6) {
+        when(result.getIp4Address()).thenReturn(ipv4);
+        when(result.getIp6Address()).thenReturn(ipv6);
+    }
+
+    @Test
+    public void setResponseIpAddressTestIpv6() {
+        NicSecondaryIp result = Mockito.mock(NicSecondaryIp.class);
+        NicSecondaryIpResponse response = new NicSecondaryIpResponse();
+        setResult(result, null, "ipv6");
+
+        ApiResponseHelper.setResponseIpAddress(result, response);
+
+        assertTrue(response.getIpAddr().equals("ipv6"));
+    }
+
+}
diff --git a/server/test/com/cloud/api/ApiServletTest.java b/server/src/test/java/com/cloud/api/ApiServletTest.java
similarity index 100%
rename from server/test/com/cloud/api/ApiServletTest.java
rename to server/src/test/java/com/cloud/api/ApiServletTest.java
diff --git a/server/test/com/cloud/api/ListPerfTest.java b/server/src/test/java/com/cloud/api/ListPerfTest.java
similarity index 100%
rename from server/test/com/cloud/api/ListPerfTest.java
rename to server/src/test/java/com/cloud/api/ListPerfTest.java
diff --git a/server/test/com/cloud/api/LoginResponse.java b/server/src/test/java/com/cloud/api/LoginResponse.java
similarity index 100%
rename from server/test/com/cloud/api/LoginResponse.java
rename to server/src/test/java/com/cloud/api/LoginResponse.java
diff --git a/server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java b/server/src/test/java/com/cloud/api/dispatch/CommandCreationWorkerTest.java
similarity index 100%
rename from server/test/com/cloud/api/dispatch/CommandCreationWorkerTest.java
rename to server/src/test/java/com/cloud/api/dispatch/CommandCreationWorkerTest.java
diff --git a/server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.java b/server/src/test/java/com/cloud/api/dispatch/DispatchChainFactoryTest.java
similarity index 100%
rename from server/test/com/cloud/api/dispatch/DispatchChainFactoryTest.java
rename to server/src/test/java/com/cloud/api/dispatch/DispatchChainFactoryTest.java
diff --git a/server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java b/server/src/test/java/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
similarity index 100%
rename from server/test/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
rename to server/src/test/java/com/cloud/api/dispatch/ParamGenericValidationWorkerTest.java
diff --git a/server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java b/server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java
similarity index 100%
rename from server/test/com/cloud/api/dispatch/ParamProcessWorkerTest.java
rename to server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java
diff --git a/server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java b/server/src/test/java/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java
similarity index 100%
rename from server/test/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java
rename to server/src/test/java/com/cloud/api/dispatch/SpecificCmdValidationWorkerTest.java
diff --git a/server/test/com/cloud/api/query/MutualExclusiveIdsManagerBaseTest.java b/server/src/test/java/com/cloud/api/query/MutualExclusiveIdsManagerBaseTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/MutualExclusiveIdsManagerBaseTest.java
rename to server/src/test/java/com/cloud/api/query/MutualExclusiveIdsManagerBaseTest.java
diff --git a/server/test/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java b/server/src/test/java/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java
rename to server/src/test/java/com/cloud/api/query/dao/GenericDaoBaseWithTagInformationBaseTest.java
diff --git a/server/test/com/cloud/api/query/dao/SecurityGroupJoinDaoImplTest.java b/server/src/test/java/com/cloud/api/query/dao/SecurityGroupJoinDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/dao/SecurityGroupJoinDaoImplTest.java
rename to server/src/test/java/com/cloud/api/query/dao/SecurityGroupJoinDaoImplTest.java
diff --git a/server/test/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java b/server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
rename to server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
diff --git a/server/test/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java b/server/src/test/java/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java
rename to server/src/test/java/com/cloud/api/query/dao/UserVmJoinDaoImplTest.java
diff --git a/server/test/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java b/server/src/test/java/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java
rename to server/src/test/java/com/cloud/api/query/dao/VolumeJoinDaoImplTest.java
diff --git a/server/test/com/cloud/capacity/CapacityManagerTest.java b/server/src/test/java/com/cloud/capacity/CapacityManagerTest.java
similarity index 100%
rename from server/test/com/cloud/capacity/CapacityManagerTest.java
rename to server/src/test/java/com/cloud/capacity/CapacityManagerTest.java
diff --git a/server/test/com/cloud/configuration/ConfigurationManagerTest.java b/server/src/test/java/com/cloud/configuration/ConfigurationManagerTest.java
similarity index 100%
rename from server/test/com/cloud/configuration/ConfigurationManagerTest.java
rename to server/src/test/java/com/cloud/configuration/ConfigurationManagerTest.java
diff --git a/server/test/com/cloud/configuration/ValidateIpRangeTest.java b/server/src/test/java/com/cloud/configuration/ValidateIpRangeTest.java
similarity index 100%
rename from server/test/com/cloud/configuration/ValidateIpRangeTest.java
rename to server/src/test/java/com/cloud/configuration/ValidateIpRangeTest.java
diff --git a/server/test/com/cloud/consoleproxy/ConsoleProxyManagerTest.java b/server/src/test/java/com/cloud/consoleproxy/ConsoleProxyManagerTest.java
similarity index 100%
rename from server/test/com/cloud/consoleproxy/ConsoleProxyManagerTest.java
rename to server/src/test/java/com/cloud/consoleproxy/ConsoleProxyManagerTest.java
diff --git a/server/test/com/cloud/event/ActionEventUtilsTest.java b/server/src/test/java/com/cloud/event/ActionEventUtilsTest.java
similarity index 100%
rename from server/test/com/cloud/event/ActionEventUtilsTest.java
rename to server/src/test/java/com/cloud/event/ActionEventUtilsTest.java
diff --git a/server/test/com/cloud/event/EventControlsUnitTest.java b/server/src/test/java/com/cloud/event/EventControlsUnitTest.java
similarity index 100%
rename from server/test/com/cloud/event/EventControlsUnitTest.java
rename to server/src/test/java/com/cloud/event/EventControlsUnitTest.java
diff --git a/server/test/com/cloud/ha/HighAvailabilityManagerImplTest.java b/server/src/test/java/com/cloud/ha/HighAvailabilityManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/ha/HighAvailabilityManagerImplTest.java
rename to server/src/test/java/com/cloud/ha/HighAvailabilityManagerImplTest.java
diff --git a/server/test/com/cloud/ha/KVMFencerTest.java b/server/src/test/java/com/cloud/ha/KVMFencerTest.java
similarity index 100%
rename from server/test/com/cloud/ha/KVMFencerTest.java
rename to server/src/test/java/com/cloud/ha/KVMFencerTest.java
diff --git a/server/test/com/cloud/hypervisor/KVMGuruTest.java b/server/src/test/java/com/cloud/hypervisor/KVMGuruTest.java
similarity index 100%
rename from server/test/com/cloud/hypervisor/KVMGuruTest.java
rename to server/src/test/java/com/cloud/hypervisor/KVMGuruTest.java
diff --git a/server/test/com/cloud/keystore/KeystoreTest.java b/server/src/test/java/com/cloud/keystore/KeystoreTest.java
similarity index 100%
rename from server/test/com/cloud/keystore/KeystoreTest.java
rename to server/src/test/java/com/cloud/keystore/KeystoreTest.java
diff --git a/server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java b/server/src/test/java/com/cloud/metadata/ResourceMetaDataManagerTest.java
similarity index 100%
rename from server/test/com/cloud/metadata/ResourceMetaDataManagerTest.java
rename to server/src/test/java/com/cloud/metadata/ResourceMetaDataManagerTest.java
diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java
similarity index 100%
rename from server/test/com/cloud/network/CreatePrivateNetworkTest.java
rename to server/src/test/java/com/cloud/network/CreatePrivateNetworkTest.java
diff --git a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java b/server/src/test/java/com/cloud/network/DedicateGuestVlanRangesTest.java
similarity index 100%
rename from server/test/com/cloud/network/DedicateGuestVlanRangesTest.java
rename to server/src/test/java/com/cloud/network/DedicateGuestVlanRangesTest.java
diff --git a/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java b/server/src/test/java/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
rename to server/src/test/java/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
diff --git a/server/src/test/java/com/cloud/network/IpAddressManagerTest.java b/server/src/test/java/com/cloud/network/IpAddressManagerTest.java
new file mode 100644
index 0000000..09519b9
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/IpAddressManagerTest.java
@@ -0,0 +1,232 @@
+// 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.network;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.Service;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.rules.StaticNatImpl;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.user.AccountVO;
+import com.cloud.utils.net.Ip;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IpAddressManagerTest {
+
+    @Mock
+    IPAddressDao ipAddressDao;
+
+    @Mock
+    NetworkDao networkDao;
+
+    @Mock
+    NetworkOfferingDao networkOfferingDao;
+
+    @Spy
+    @InjectMocks
+    IpAddressManagerImpl ipAddressManager;
+
+    @InjectMocks
+    NetworkModelImpl networkModel = Mockito.spy(new NetworkModelImpl());
+
+    IPAddressVO ipAddressVO;
+
+    AccountVO account;
+
+    @Before
+    public void setup() throws ResourceUnavailableException {
+
+        ipAddressVO = new IPAddressVO(new Ip("192.0.0.1"), 1L, 1L, 1L,false);
+        ipAddressVO.setAllocatedToAccountId(1L);
+
+        account = new AccountVO("admin", 1L, null, (short) 1, 1L, "c65a73d5-ebbd-11e7-8f45-107b44277808");
+        account.setId(1L);
+
+        NetworkOfferingVO networkOfferingVO = Mockito.mock(NetworkOfferingVO.class);
+        networkOfferingVO.setSharedSourceNat(false);
+
+        Mockito.when(networkOfferingDao.findById(Mockito.anyLong())).thenReturn(networkOfferingVO);
+    }
+
+    @Test
+    public void testGetStaticNatSourceIps() {
+        String publicIpAddress = "192.168.1.3";
+        IPAddressVO vo = mock(IPAddressVO.class);
+        when(vo.getAddress()).thenReturn(new Ip(publicIpAddress));
+        when(vo.getId()).thenReturn(1l);
+
+        when(ipAddressDao.findById(anyLong())).thenReturn(vo);
+        StaticNat snat = new StaticNatImpl(1, 1, 1, 1, publicIpAddress, false);
+
+        List<IPAddressVO> ips = ipAddressManager.getStaticNatSourceIps(Collections.singletonList(snat));
+        Assert.assertNotNull(ips);
+        Assert.assertEquals(1, ips.size());
+
+        IPAddressVO returnedVO = ips.get(0);
+        Assert.assertEquals(vo, returnedVO);
+    }
+
+    @Test
+    public void isIpEqualsGatewayOrNetworkOfferingsEmptyTestRequestedIpEqualsIp6Gateway() {
+        Network network = setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(0l, "gateway", "ip6Gateway", null, new ArrayList<Service>());
+
+        boolean result = ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, "ip6Gateway");
+
+        Mockito.verify(networkModel, Mockito.times(0)).listNetworkOfferingServices(Mockito.anyLong());
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void isIpEqualsGatewayOrNetworkOfferingsEmptyTestRequestedIpEqualsGateway() {
+        Network network = setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(0l, "gateway", "ip6Gateway", null, new ArrayList<Service>());
+
+        boolean result = ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, "gateway");
+
+        Mockito.verify(networkModel, Mockito.times(0)).listNetworkOfferingServices(Mockito.anyLong());
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void isIpEqualsGatewayOrNetworkOfferingsEmptyTestExpectFalseServicesNotEmpty() {
+        List<Service> services = new ArrayList<Service>();
+        Service serviceGateway = new Service("Gateway");
+        services.add(serviceGateway);
+        Network network = setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(0l, "gateway", "ip6Gateway", null, services);
+
+        boolean result = ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, "requestedIp");
+
+        Mockito.verify(networkModel).listNetworkOfferingServices(Mockito.anyLong());
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void isIpEqualsGatewayOrNetworkOfferingsEmptyTestExpectFalseServicesCidrNotNull() {
+        Network network = setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(0l, "gateway", "ip6Gateway", "cidr", new ArrayList<Service>());
+
+        boolean result = ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, "requestedIp");
+
+        Mockito.verify(networkModel).listNetworkOfferingServices(Mockito.anyLong());
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void assertSourceNatImplementedNetwork() {
+
+        NetworkVO networkImplemented = Mockito.mock(NetworkVO.class);
+        when(networkImplemented.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
+        when(networkImplemented.getNetworkOfferingId()).thenReturn(8L);
+        when(networkImplemented.getState()).thenReturn(Network.State.Implemented);
+        when(networkImplemented.getGuestType()).thenReturn(Network.GuestType.Isolated);
+        when(networkImplemented.getVpcId()).thenReturn(null);
+        when(networkImplemented.getId()).thenReturn(1L);
+
+        Mockito.when(networkDao.findById(1L)).thenReturn(networkImplemented);
+        doReturn(null).when(ipAddressManager).getExistingSourceNatInNetwork(1L, 1L);
+
+        boolean isSourceNat = ipAddressManager.isSourceNatAvailableForNetwork(account, ipAddressVO, networkImplemented);
+
+        assertTrue("Source NAT should be true", isSourceNat);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void assertSourceNatAllocatedNetwork() {
+
+        NetworkVO networkAllocated = Mockito.mock(NetworkVO.class);
+        when(networkAllocated.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
+        when(networkAllocated.getNetworkOfferingId()).thenReturn(8L);
+        when(networkAllocated.getState()).thenReturn(Network.State.Allocated);
+        when(networkAllocated.getGuestType()).thenReturn(Network.GuestType.Isolated);
+        when(networkAllocated.getVpcId()).thenReturn(null);
+        when(networkAllocated.getId()).thenReturn(2L);
+
+        Mockito.when(networkDao.findById(2L)).thenReturn(networkAllocated);
+        doReturn(null).when(ipAddressManager).getExistingSourceNatInNetwork(1L, 2L);
+
+        ipAddressManager.isSourceNatAvailableForNetwork(account, ipAddressVO, networkAllocated);
+    }
+
+    @Test
+    public void assertExistingSourceNatAllocatedNetwork() {
+
+        NetworkVO networkNat = Mockito.mock(NetworkVO.class);
+        when(networkNat.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
+        when(networkNat.getNetworkOfferingId()).thenReturn(8L);
+        when(networkNat.getState()).thenReturn(Network.State.Implemented);
+        when(networkNat.getGuestType()).thenReturn(Network.GuestType.Isolated);
+        when(networkNat.getId()).thenReturn(3L);
+        when(networkNat.getVpcId()).thenReturn(null);
+        when(networkNat.getId()).thenReturn(3L);
+
+        IPAddressVO sourceNat = new IPAddressVO(new Ip("192.0.0.2"), 1L, 1L, 1L,true);
+
+        Mockito.when(networkDao.findById(3L)).thenReturn(networkNat);
+        doReturn(sourceNat).when(ipAddressManager).getExistingSourceNatInNetwork(1L, 3L);
+
+        boolean isSourceNat = ipAddressManager.isSourceNatAvailableForNetwork(account, ipAddressVO, networkNat);
+
+        assertFalse("Source NAT should be false", isSourceNat);
+    }
+
+    @Test
+    public void isIpEqualsGatewayOrNetworkOfferingsEmptyTestNetworkOfferingsEmptyAndCidrNull() {
+        Network network = setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(0l, "gateway", "ip6Gateway", null, new ArrayList<Service>());
+
+        boolean result = ipAddressManager.isIpEqualsGatewayOrNetworkOfferingsEmpty(network, "requestedIp");
+
+        Mockito.verify(networkModel).listNetworkOfferingServices(Mockito.anyLong());
+        Assert.assertTrue(result);
+    }
+
+    private Network setTestIsIpEqualsGatewayOrNetworkOfferingsEmpty(long networkOfferingId, String gateway, String ip6Gateway, String cidr, List<Service> services) {
+        Network network = mock(Network.class);
+        Mockito.when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
+        Mockito.when(network.getGateway()).thenReturn(gateway);
+        Mockito.when(network.getIp6Gateway()).thenReturn(ip6Gateway);
+        Mockito.when(network.getCidr()).thenReturn(cidr);
+        Mockito.doReturn(services).when(networkModel).listNetworkOfferingServices(Mockito.anyLong());
+        return network;
+    }
+
+}
\ No newline at end of file
diff --git a/server/src/test/java/com/cloud/network/Ipv6AddressManagerTest.java b/server/src/test/java/com/cloud/network/Ipv6AddressManagerTest.java
new file mode 100644
index 0000000..3f082d5
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/Ipv6AddressManagerTest.java
@@ -0,0 +1,258 @@
+// 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.network;
+
+import static org.mockito.Mockito.mock;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.vm.NicProfile;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.IpAddress.State;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.dao.IPAddressDaoImpl;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.UserIpv6AddressDaoImpl;
+import com.cloud.user.Account;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+
+public class Ipv6AddressManagerTest {
+
+    @InjectMocks
+    Ipv6AddressManagerImpl ip6Manager = Mockito.spy(new Ipv6AddressManagerImpl());
+
+    @InjectMocks
+    NicSecondaryIpDaoImpl nicSecondaryIpDao = Mockito.spy(new NicSecondaryIpDaoImpl());
+
+    @InjectMocks
+    UserIpv6AddressDaoImpl ipv6Dao = Mockito.spy(new UserIpv6AddressDaoImpl());
+
+    @InjectMocks
+    IpAddressManagerImpl ipAddressManager = Mockito.spy(new IpAddressManagerImpl());
+
+    @InjectMocks
+    NetworkModelImpl networkModel = Mockito.mock(NetworkModelImpl.class);// = Mockito.spy(new NetworkModelImpl());
+
+    @InjectMocks
+    IPAddressDaoImpl ipAddressDao = Mockito.spy(new IPAddressDaoImpl());
+
+    private Network network = mockNetwork();
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void isIp6TakenTestNoNull() {
+        setIsIp6TakenTest(new UserIpv6AddressVO(), new NicSecondaryIpVO(0l, "ipaddr", 0l, 0l, 0l, 0l));
+        boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6");
+        assertAndVerifyIsIp6Taken(true, result);
+    }
+
+    @Test
+    public void isIp6TakenTestSecIpNull() {
+        setIsIp6TakenTest(new UserIpv6AddressVO(), null);
+        boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6");
+        assertAndVerifyIsIp6Taken(true, result);
+    }
+
+    @Test
+    public void isIp6TakenTestUserIpv6AddressNull() {
+        setIsIp6TakenTest(null, new NicSecondaryIpVO(0l, "ipaddr", 0l, 0l, 0l, 0l));
+        boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6");
+        assertAndVerifyIsIp6Taken(true, result);
+    }
+
+    @Test
+    public void isIp6TakenTestAllNull() {
+        setIsIp6TakenTest(null, null);
+        boolean result = ip6Manager.isIp6Taken(network, "requestedIpv6");
+        assertAndVerifyIsIp6Taken(false, result);
+    }
+
+    private void assertAndVerifyIsIp6Taken(boolean expected, boolean result) {
+        Assert.assertEquals(expected, result);
+        Mockito.verify(ipv6Dao).findByNetworkIdAndIp(Mockito.anyLong(), Mockito.anyString());
+        Mockito.verify(nicSecondaryIpDao).findByIp6AddressAndNetworkId(Mockito.anyString(), Mockito.anyLong());
+    }
+
+    private void setIsIp6TakenTest(UserIpv6AddressVO userIpv6, NicSecondaryIpVO nicSecondaryIp) {
+        Mockito.doReturn(userIpv6).when(ipv6Dao).findByNetworkIdAndIp(Mockito.anyLong(), Mockito.anyString());
+        Mockito.doReturn(nicSecondaryIp).when(nicSecondaryIpDao).findByIp6AddressAndNetworkId(Mockito.anyString(), Mockito.anyLong());
+    }
+
+    private Network mockNetwork() {
+        Network network = mock(Network.class);
+        Mockito.when(network.getId()).thenReturn(0l);
+        Mockito.when(network.getIp6Cidr()).thenReturn("2001:db8::/32");
+        return network;
+    }
+
+    @Test
+    public void allocatePublicIp6ForGuestNicTestNoException() throws InsufficientAddressCapacityException {
+        Account owner = Mockito.mock(Account.class);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        String returnedIp = ip6Manager.allocatePublicIp6ForGuestNic(network, 0l, owner, requestedIpv6);
+
+        Mockito.verify(ip6Manager).checkIfCanAllocateIpv6Address(network, requestedIpv6);
+        Assert.assertEquals(requestedIpv6, returnedIp);
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void checkIfCanAllocateIpv6AddressTestIp6IsTaken() throws InsufficientAddressCapacityException {
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", true, false);
+
+        ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6);
+
+        verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 0);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void checkIfCanAllocateIpv6AddressTestIpIsIpEqualsGatewayOrNetworkOfferingsEmpty() throws InsufficientAddressCapacityException {
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, true);
+
+        ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6);
+
+        verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 1);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void checkIfCanAllocateIpv6AddressTestIpINotInTheNetwork() throws InsufficientAddressCapacityException {
+        String requestedIpv6 = "2002:db8::10";
+        setCheckIfCanAllocateIpv6AddresscTest(requestedIpv6, false, false);
+
+        ip6Manager.checkIfCanAllocateIpv6Address(network, requestedIpv6);
+
+        verifyCheckIfCanAllocateIpv6AddressTest(network, requestedIpv6, 1, 1);
+    }
+
+    private void verifyCheckIfCanAllocateIpv6AddressTest(Network network, String requestedIpv6, int isIp6TakenTimes, int isIpEqualsGatewayTimes) {
+        Mockito.verify(ip6Manager, Mockito.times(isIp6TakenTimes)).isIp6Taken(network, requestedIpv6);
+        Mockito.verify(ipAddressManager, Mockito.times(isIpEqualsGatewayTimes)).isIpEqualsGatewayOrNetworkOfferingsEmpty(network, requestedIpv6);
+    }
+
+    private String setCheckIfCanAllocateIpv6AddresscTest(String requestedIpv6, boolean isIp6Taken, boolean isIpEqualsGatewayOrNetworkOfferingsEmpty) {
+        Mockito.doReturn(isIp6Taken).when(ip6Manager).isIp6Taken(Mockito.eq(network), Mockito.anyString());
+        Mockito.doReturn(isIpEqualsGatewayOrNetworkOfferingsEmpty).when(ipAddressManager).isIpEqualsGatewayOrNetworkOfferingsEmpty(network, requestedIpv6);
+        NetUtils.isIp6InNetwork(requestedIpv6, network.getIp6Cidr());
+        return requestedIpv6;
+    }
+
+    @Test
+    public void acquireGuestIpv6AddressTest() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(true, State.Free);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+
+        verifyAcquireGuestIpv6AddressTest();
+    }
+
+    private void verifyAcquireGuestIpv6AddressTest() {
+        Mockito.verify(networkModel).areThereIPv6AddressAvailableInNetwork(Mockito.anyLong());
+        Mockito.verify(networkModel).checkRequestedIpAddresses(Mockito.anyLong(), Mockito.any(IpAddresses.class));
+        Mockito.verify(ipAddressDao).findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString());
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void acquireGuestIpv6AddressTestUnavailableIp() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(false, State.Free);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+
+        verifyAcquireGuestIpv6AddressTest();
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void acquireGuestIpv6AddressTestStateAllocating() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(false, State.Allocating);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+
+        verifyAcquireGuestIpv6AddressTest();
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void acquireGuestIpv6AddressTestStateAllocated() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(false, State.Allocated);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+
+        verifyAcquireGuestIpv6AddressTest();
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void acquireGuestIpv6AddressTestStateReleasing() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(false, State.Releasing);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8::10", false, false);
+
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+
+        verifyAcquireGuestIpv6AddressTest();
+    }
+
+    private void setAcquireGuestIpv6AddressTest(boolean isIPAvailable, State state) {
+        mockNetwork();
+        IPAddressVO ipVo = Mockito.mock(IPAddressVO.class);
+        Mockito.doReturn(isIPAvailable).when(networkModel).areThereIPv6AddressAvailableInNetwork(Mockito.anyLong());
+        Mockito.doReturn(ipVo).when(ipAddressDao).findByIpAndSourceNetworkId(Mockito.anyLong(), Mockito.anyString());
+        Mockito.when(ipVo.getState()).thenReturn(state);
+    }
+
+    @Test
+    public void setNICIPv6AddressTest() {
+        NicProfile nic = new NicProfile();
+        Network network = mock(Network.class);
+        DataCenter dc = mock(DataCenter.class);
+
+        nic.setMacAddress("1e:00:b1:00:0a:f6");
+
+        Mockito.when(network.getIp6Cidr()).thenReturn("2001:db8:100::/64");
+        Mockito.when(network.getIp6Gateway()).thenReturn("2001:db8:100::1");
+
+        Mockito.when(dc.getIp6Dns1()).thenReturn("2001:db8::53:1");
+        Mockito.when(dc.getIp6Dns1()).thenReturn("2001:db8::53:2");
+
+        String expected = "2001:db8:100:0:1c00:b1ff:fe00:af6";
+
+        ip6Manager.setNicIp6Address(nic, dc, network);
+
+        Assert.assertEquals(expected, nic.getIPv6Address());
+    }
+
+    @Test(expected = InsufficientAddressCapacityException.class)
+    public void acquireGuestIpv6AddressEUI64Test() throws InsufficientAddressCapacityException {
+        setAcquireGuestIpv6AddressTest(true, State.Free);
+        String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8:13f::1c00:4aff:fe00:fe", false, false);
+        ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
+    }
+}
diff --git a/server/test/com/cloud/network/MockFirewallManagerImpl.java b/server/src/test/java/com/cloud/network/MockFirewallManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/network/MockFirewallManagerImpl.java
rename to server/src/test/java/com/cloud/network/MockFirewallManagerImpl.java
diff --git a/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java
new file mode 100644
index 0000000..a35cec5
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/MockNetworkModelImpl.java
@@ -0,0 +1,910 @@
+// 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.network;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.dc.Vlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.user.Account;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
+
+public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
+     */
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#start()
+     */
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#stop()
+     */
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#getName()
+     */
+    @Override
+    public String getName() {
+        return "MockNetworkModelImpl";
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
+     */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+   * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
+   */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSystemAccountNetworkOfferings(java.lang.String[])
+     */
+    @Override
+    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNics(long)
+     */
+    @Override
+    public List<? extends Nic> getNics(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNextAvailableMacAddressInNetwork(long)
+     */
+    @Override
+    public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPublicIpAddress(long)
+     */
+    @Override
+    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPodVlans(long)
+     */
+    @Override
+    public List<? extends Vlan> listPodVlans(long podId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksUsedByVm(long, boolean)
+     */
+    @Override
+    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicInNetwork(long, long)
+     */
+    @Override
+    public Nic getNicInNetwork(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicsForTraffic(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultNetworkForVm(long)
+     */
+    @Override
+    public Network getDefaultNetworkForVm(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultNic(long)
+     */
+    @Override
+    public Nic getDefaultNic(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getUserDataUpdateProvider(com.cloud.network.Network)
+     */
+    @Override
+    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#networkIsConfiguredForExternalNetworking(long, long)
+     */
+    @Override
+    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkServiceCapabilities(long, com.cloud.network.Network.Service)
+     */
+    @Override
+    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isSharedNetworkWithoutServices(long networkId) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service[])
+     */
+    @Override
+    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long)
+     */
+    @Override
+    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long)
+     */
+    @Override
+    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpOfNetworkElementInVirtualNetwork(long, long)
+     */
+    @Override
+    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksForAccount(long, long, com.cloud.network.Network.GuestType)
+     */
+    @Override
+    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listAllNetworksInAllZonesByType(com.cloud.network.Network.GuestType)
+     */
+    @Override
+    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getStartIpAddress(long)
+     */
+    @Override
+    public String getStartIpAddress(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpInNetwork(long, long)
+     */
+    @Override
+    public String getIpInNetwork(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpInNetworkIncludingRemoved(long, long)
+     */
+    @Override
+    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPodIdForVlan(long)
+     */
+    @Override
+    public Long getPodIdForVlan(long vlanDbId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworkOfferingsForUpgrade(long)
+     */
+    @Override
+    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isSecurityGroupSupportedInNetwork(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isSecurityGroupSupportedInNetwork(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderSupportServiceInNetwork(long, com.cloud.network.Network.Service, com.cloud.network.Network.Provider)
+     */
+    @Override
+    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderEnabledInPhysicalNetwork(long, java.lang.String)
+     */
+    @Override
+    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkTag(com.cloud.hypervisor.Hypervisor.HypervisorType, com.cloud.network.Network)
+     */
+    @Override
+    public String getNetworkTag(HypervisorType hType, Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getElementServices(com.cloud.network.Network.Provider)
+     */
+    @Override
+    public List<Service> getElementServices(Provider provider) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canElementEnableIndividualServices(com.cloud.network.Network.Provider)
+     */
+    @Override
+    public boolean canElementEnableIndividualServices(Provider provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesSupportedInNetwork(long, com.cloud.network.Network.Service[])
+     */
+    @Override
+    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkSystem(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isNetworkSystem(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceCapabilities(com.cloud.offering.NetworkOffering, com.cloud.network.Network.Service)
+     */
+    @Override
+    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNetworkId(com.cloud.network.Network)
+     */
+    @Override
+    public Long getPhysicalNetworkId(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAllowSubdomainAccessGlobal()
+     */
+    @Override
+    public boolean getAllowSubdomainAccessGlobal() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderForNetwork(com.cloud.network.Network.Provider, long)
+     */
+    @Override
+    public boolean isProviderForNetwork(Provider provider, long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderForNetworkOffering(com.cloud.network.Network.Provider, long)
+     */
+    @Override
+    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canProviderSupportServices(java.util.Map)
+     */
+    @Override
+    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNetworkInfo(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canAddDefaultSecurityGroup()
+     */
+    @Override
+    public boolean canAddDefaultSecurityGroup() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworkOfferingServices(long)
+     */
+    @Override
+    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesEnabledInZone(long, com.cloud.offering.NetworkOffering, java.util.List)
+     */
+    @Override
+    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#checkIpForService(com.cloud.network.IPAddressVO, com.cloud.network.Network.Service, java.lang.Long)
+     */
+    @Override
+    public boolean checkIpForService(IpAddress ip, Service service, Long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String)
+     */
+    @Override
+    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultUniqueProviderForService(java.lang.String)
+     */
+    @Override
+    public Provider getDefaultUniqueProviderForService(String serviceName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#checkNetworkPermissions(com.cloud.user.Account, com.cloud.network.Network)
+     */
+    @Override
+    public void checkNetworkPermissions(Account owner, Network network) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultStorageTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultPublicTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultGuestTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getElementImplementingProvider(java.lang.String)
+     */
+    @Override
+    public NetworkElement getElementImplementingProvider(String providerName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAccountNetworkDomain(long, long)
+     */
+    @Override
+    public String getAccountNetworkDomain(long accountId, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNtwkOffDistinctProviders(long)
+     */
+    @Override
+    public List<Provider> getNtwkOffDistinctProviders(long ntwkOffId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean)
+     */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNtwksSupportingTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isPrivateGateway(com.cloud.vm.Nic)
+     */
+    @Override
+    public boolean isPrivateGateway(long ntwkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkCapabilities(long)
+     */
+    @Override
+    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSystemNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDedicatedNetworkDomain(long)
+     */
+    @Override
+    public Long getDedicatedNetworkDomain(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceProvidersMap(long)
+     */
+    @Override
+    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listSupportedNetworkServiceProviders(java.lang.String)
+     */
+    @Override
+    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksByVpc(long)
+     */
+    @Override
+    public List<? extends Network> listNetworksByVpc(long vpcId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canUseForDeploy(com.cloud.network.Network)
+     */
+    @Override
+    public boolean canUseForDeploy(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getExclusiveGuestNetwork(long)
+     */
+    @Override
+    public Network getExclusiveGuestNetwork(long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkRate(long, java.lang.Long)
+     */
+    @Override
+    public Integer getNetworkRate(long networkId, Long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isVmPartOfNetwork(long, long)
+     */
+    @Override
+    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultPhysicalNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetwork(long)
+     */
+    @Override
+    public Network getNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIp(long)
+     */
+    @Override
+    public IpAddress getIp(long sourceIpAddressId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkAvailableInDomain(long, long)
+     */
+    @Override
+    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicProfile(com.cloud.vm.VirtualMachine, long, java.lang.String)
+     */
+    @Override
+    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAvailableIps(com.cloud.network.Network, java.lang.String)
+     */
+    @Override
+    public Set<Long> getAvailableIps(Network network, String requestedIp) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDomainNetworkDomain(long, long)
+     */
+    @Override
+    public String getDomainNetworkDomain(long domainId, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpToServices(java.util.List, boolean, boolean)
+     */
+    @Override
+    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getProviderToIpList(com.cloud.network.Network, java.util.Map)
+     */
+    @Override
+    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSourceNatIpAddressForGuestNetwork(com.cloud.user.Account, com.cloud.network.Network)
+     */
+    @Override
+    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkInlineMode(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isNetworkInlineMode(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean areThereIPv6AddressAvailableInNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isIP6AddressAvailableInVlan(long vlanId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public String getStartIpv6Address(long id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isProviderEnabledInZone(long zoneId, String provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Nic getPlaceholderNicForRouter(Network network, Long podId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<String> getUsedIpsInNetwork(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Detail, String> getNtwkOffDetails(long offId) {
+        return null;
+    }
+
+    @Override
+    public IsolationType[] listNetworkIsolationMethods() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
+        return null;
+    }
+
+    @Override
+    public boolean getExecuteInSeqNtwkElmtCmd() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isNetworkReadyForGc(long networkId) {
+        return true;
+    }
+
+    @Override
+    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
+        return false;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
+        return null;
+    }
+
+    @Override
+    public String getValidNetworkCidr(Network guestNetwork) {
+        return null;
+    }
+
+}
diff --git a/server/test/com/cloud/network/NetworkModelTest.java b/server/src/test/java/com/cloud/network/NetworkModelTest.java
similarity index 100%
rename from server/test/com/cloud/network/NetworkModelTest.java
rename to server/src/test/java/com/cloud/network/NetworkModelTest.java
diff --git a/server/test/com/cloud/network/UpdatePhysicalNetworkTest.java b/server/src/test/java/com/cloud/network/UpdatePhysicalNetworkTest.java
similarity index 100%
rename from server/test/com/cloud/network/UpdatePhysicalNetworkTest.java
rename to server/src/test/java/com/cloud/network/UpdatePhysicalNetworkTest.java
diff --git a/server/test/com/cloud/network/dao/NetworkDaoTest.java b/server/src/test/java/com/cloud/network/dao/NetworkDaoTest.java
similarity index 100%
rename from server/test/com/cloud/network/dao/NetworkDaoTest.java
rename to server/src/test/java/com/cloud/network/dao/NetworkDaoTest.java
diff --git a/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java b/server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java
similarity index 100%
rename from server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java
rename to server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java
diff --git a/server/src/test/java/com/cloud/network/element/VirtualRouterElementTest.java b/server/src/test/java/com/cloud/network/element/VirtualRouterElementTest.java
new file mode 100644
index 0000000..2d66ea7
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/element/VirtualRouterElementTest.java
@@ -0,0 +1,508 @@
+// 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.network.element;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyList;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.network.dao.NetworkDetailVO;
+import com.cloud.network.dao.NetworkDetailsDao;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.cluster.dao.ManagementServerHostDao;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.NetworkModelImpl;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.VirtualRouterProvider.Type;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVMMapDao;
+import com.cloud.network.dao.MonitoringServiceDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.OpRouterMonitorServiceDao;
+import com.cloud.network.dao.OvsProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionDao;
+import com.cloud.network.dao.Site2SiteVpnGatewayDao;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
+import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.user.dao.UserStatisticsDao;
+import com.cloud.user.dao.UserStatsLogDao;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.ReservationContextImpl;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.NicIpAliasDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import org.mockito.stubbing.Answer;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VirtualRouterElementTest {
+    @Mock private ClusterDao _clusterDao;
+    @Mock private ConfigurationDao _configDao;
+    @Mock private DataCenterDao _dcDao;
+    @Mock private GuestOSDao _guestOSDao;
+    @Mock private HostDao _hostDao;
+    @Mock private IPAddressDao _ipAddressDao;
+    @Mock private UserIpv6AddressDao _ipv6Dao;
+    @Mock private LoadBalancerDao _loadBalancerDao;
+    @Mock private LoadBalancerVMMapDao _loadBalancerVMMapDao;
+    @Mock private MonitoringServiceDao _monitorServiceDao;
+    @Mock private ManagementServerHostDao _msHostDao;
+    @Mock private NetworkDao _networkDao;
+    @Mock private NetworkOfferingDao _networkOfferingDao;
+    @Mock private NetworkDetailsDao _networkDetailsDao;
+    @Mock private NicDao _nicDao;
+    @Mock private NicIpAliasDao _nicIpAliasDao;
+    @Mock private OpRouterMonitorServiceDao _opRouterMonitorServiceDao;
+    @Mock private PortForwardingRulesDao _pfRulesDao;
+    @Mock private PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Mock private HostPodDao _podDao;
+    @Mock private DomainRouterDao _routerDao;
+    @Mock private FirewallRulesDao _rulesDao;
+    @Mock private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
+    @Mock private Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
+    @Mock private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
+    @Mock private ServiceOfferingDao _serviceOfferingDao;
+    @Mock private VMTemplateDao _templateDao;
+    @Mock private UserDao _userDao;
+    @Mock private UserStatisticsDao _userStatsDao;
+    @Mock private UserStatsLogDao _userStatsLogDao;
+    @Mock private UserVmDao _userVmDao;
+    @Mock private VlanDao _vlanDao;
+    @Mock private VMInstanceDao _vmDao;
+    @Mock private UserVmDetailsDao _vmDetailsDao;
+    @Mock private VolumeDao _volumeDao;
+    @Mock private RemoteAccessVpnDao _vpnDao;
+    @Mock private VpnUserDao _vpnUsersDao;
+    @Mock private VirtualRouterProviderDao _vrProviderDao;
+    @Mock private LoadBalancerDao _lbDao;
+    @Mock private NetworkDao _networksDao;
+    @Mock private OvsProviderDao _ovsProviderDao;
+
+    @Mock private ServiceOfferingVO _offering;
+    @Mock private NetworkModelImpl _networkModel;
+
+    @Mock private AccountManager _accountMgr;
+    @Mock private ConfigurationManager _configMgr;
+    @Mock private NetworkModel _networkMdl;
+    @Mock private NetworkOrchestrationService _networkMgr;
+    @Mock private ResourceManager _resourceMgr;
+    @Mock private UserVmManager _userVmMgr;
+    @Mock private VirtualMachineManager _itMgr;
+
+    @InjectMocks
+    private RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder;
+
+    @InjectMocks
+    private VpcVirtualNetworkApplianceManagerImpl _routerMgr;
+
+    @InjectMocks
+    private VirtualRouterElement virtualRouterElement;
+
+    DataCenter testDataCenter = new DataCenterVO(/* id */ 1L,
+            "name",
+            "description",
+            "dns1",
+            /* dns2 */ null,
+            /* dns3 */ null,
+            /* dns4 */ null,
+            "cidr",
+            "domain",
+            /*domainid */ null,
+            NetworkType.Advanced,
+            "zoneToken",
+            "domainSuffix");
+    DeployDestination testDestination = new DeployDestination(testDataCenter,null,null,null);
+    ReservationContext testContext = new ReservationContextImpl(null, null, null);
+    NetworkVO testNetwork = new NetworkVO();
+    NicProfile testNicProfile = new NicProfile();
+    NetworkOfferingVO testOffering = new NetworkOfferingVO();
+    @Mock VirtualMachineProfile testVMProfile;
+
+    @Test
+    @Ignore("Ignore it until it's fixed in order not to brake the build")
+    public void testImplementInAdvancedZoneOnXenServer() throws Exception {
+        virtualRouterElement._routerMgr = _routerMgr;
+        mockDAOs(testNetwork, testOffering);
+        mockMgrs();
+
+        final boolean done = virtualRouterElement.implement(testNetwork, testOffering, testDestination, testContext);
+        assertTrue("no cigar for network daddy",done);
+    }
+
+    @Test
+    @Ignore("Ignore it until it's fixed in order not to brake the build")
+    public void testPrepare() {
+        virtualRouterElement._routerMgr = _routerMgr;
+        virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
+        mockDAOs(testNetwork, testOffering);
+        mockMgrs();
+
+        boolean done = false;
+        try {
+            done = virtualRouterElement.prepare(testNetwork, testNicProfile, testVMProfile, testDestination, testContext);
+        } catch (ConcurrentOperationException | InsufficientCapacityException | ResourceUnavailableException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        assertTrue("can not even start to create a router", done);
+
+    }
+
+    @Test
+    public void testGetRouters1(){
+        Network networkUpdateInprogress=new NetworkVO(1l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
+        mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
+        //getRoutes should always return the router that is updating.
+        List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
+        assertTrue(routers.size()==1);
+        assertTrue(routers.get(0).getUpdateState()== VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
+    }
+
+    @Test
+    public void testGetRouters2(){
+        Network networkUpdateInprogress=new NetworkVO(2l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
+        mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
+        //alwyas return backup routers first when both master and backup need update.
+        List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
+        assertTrue(routers.size()==1);
+        assertTrue(routers.get(0).getRedundantState()==RedundantState.BACKUP && routers.get(0).getUpdateState()==VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
+    }
+
+    @Test
+    public void testGetRouters3(){
+        Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
+        mockDAOs((NetworkVO)network,testOffering);
+        //alwyas return backup routers first when both master and backup need update.
+        List<DomainRouterVO> routers=virtualRouterElement.getRouters(network);
+        assertTrue(routers.size()==4);
+    }
+
+    @Test
+    public void getResourceCountTest(){
+        Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
+        mockDAOs((NetworkVO)network,testOffering);
+        int routers=virtualRouterElement.getResourceCount(network);
+        assertTrue(routers==4);
+    }
+
+    @Test
+    public void completeAggregationCommandTest1() throws AgentUnavailableException,ResourceUnavailableException {
+        virtualRouterElement._routerMgr = Mockito.mock(VpcVirtualNetworkApplianceManagerImpl.class);
+        virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
+        Network network = new NetworkVO(6l, null, null, null, 1l, 1l, 1l, 1l, "d", "d", "d", null, 1l, 1l, null, true, null, true);
+        when(virtualRouterElement._routerMgr.completeAggregatedExecution(any(Network.class), anyList())).thenReturn(true);
+        mockDAOs((NetworkVO) network, testOffering);
+        when(virtualRouterElement._routerDao.persist(any(DomainRouterVO.class))).thenAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                Object args[] = invocationOnMock.getArguments();
+                DomainRouterVO router = (DomainRouterVO) args[0];
+                if (router.getUpdateState() != VirtualRouter.UpdateState.UPDATE_COMPLETE) {
+                    throw new CloudRuntimeException("TestFailed: completeAggregationCommandTest1 failed");
+                } else return null;
+            }
+        });
+        virtualRouterElement.completeAggregatedExecution(network, testDestination);
+    }
+    /**
+     * @param networks
+     * @param offerings
+     * @throws ConcurrentOperationException
+     */
+    private void mockMgrs() throws ConcurrentOperationException {
+        final Service service = Service.Connectivity;
+        testNetwork.setState(Network.State.Implementing);
+        testNetwork.setTrafficType(TrafficType.Guest);
+        when(_networkMdl.isProviderEnabledInPhysicalNetwork(0L, "VirtualRouter")).thenReturn(true);
+        when(_networkMdl.isProviderSupportServiceInNetwork(testNetwork.getId(), service, Network.Provider.VirtualRouter)).thenReturn(true);
+        when(_networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, 0L)).thenReturn(true);
+        when(testVMProfile.getType()).thenReturn(VirtualMachine.Type.User);
+        when(testVMProfile.getHypervisorType()).thenReturn(HypervisorType.XenServer);
+        final List<NetworkVO> networks = new ArrayList<NetworkVO>(1);
+        networks.add(testNetwork);
+        final List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(1);
+        offerings.add(testOffering);
+        doReturn(offerings).when(_networkModel).getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
+        doReturn(networks).when(_networkMgr).setupNetwork(any(Account.class), any(NetworkOffering.class), any(DeploymentPlan.class), any(String.class), any(String.class), anyBoolean());
+        // being anti-social and testing my own case first
+        doReturn(HypervisorType.XenServer).when(_resourceMgr).getDefaultHypervisor(anyLong());
+        doReturn(new AccountVO()).when(_accountMgr).getAccount(testNetwork.getAccountId());
+    }
+
+    /**
+     * @param network
+     */
+    private void mockDAOs(final NetworkVO network, final NetworkOfferingVO offering) {
+        when(_networkDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
+        when(_networksDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
+        when(_physicalProviderDao.findByServiceProvider(0L, "VirtualRouter")).thenReturn(new PhysicalNetworkServiceProviderVO());
+        when(_vrProviderDao.findByNspIdAndType(0L, Type.VirtualRouter)).thenReturn(new VirtualRouterProviderVO());
+        when(_networkOfferingDao.findById(0L)).thenReturn(offering);
+        // watchit: (in this test) there can be only one
+        when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(0L);
+        final ServiceOfferingVO svcoff = new ServiceOfferingVO("name",
+                /* cpu */ 1,
+                /* ramsize */ 1024*1024,
+                /* (clock?)speed */ 1024*1024*1024,
+                /* rateMbps */ 1,
+                /* multicastRateMbps */ 0,
+                /* offerHA */ false,
+                "displayText",
+                ProvisioningType.THIN,
+                /* useLocalStorage */ false,
+                /* recreatable */ false,
+                "tags",
+                /* systemUse */ false,
+                VirtualMachine.Type.DomainRouter,
+                /* defaultUse */ false);
+        when(_serviceOfferingDao.findById(0L)).thenReturn(svcoff);
+        when(_serviceOfferingDao.findByName(Matchers.anyString())).thenReturn(svcoff);
+        final DomainRouterVO router = new DomainRouterVO(/* id */ 1L,
+                /* serviceOfferingId */ 1L,
+                /* elementId */ 0L,
+                "name",
+                /* templateId */0L,
+                HypervisorType.XenServer,
+                /* guestOSId */ 0L,
+                /* domainId */ 0L,
+                /* accountId */ 1L,
+                /* userId */ 1L,
+                /* isRedundantRouter */ false,
+                RedundantState.UNKNOWN,
+                /* haEnabled */ false,
+                /* stopPending */ false,
+                /* vpcId */ null);
+        final DomainRouterVO routerNeedUpdateBackup = new DomainRouterVO(/* id */ 2L,
+                /* serviceOfferingId */ 1L,
+                /* elementId */ 0L,
+                "name",
+                /* templateId */0L,
+                HypervisorType.XenServer,
+                /* guestOSId */ 0L,
+                /* domainId */ 0L,
+                /* accountId */ 1L,
+                /* userId */ 1L,
+                /* isRedundantRouter */ false,
+                RedundantState.BACKUP,
+                /* haEnabled */ false,
+                /* stopPending */ false,
+                /* vpcId */ null);
+                routerNeedUpdateBackup.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
+        final DomainRouterVO routerNeedUpdateMaster = new DomainRouterVO(/* id */ 3L,
+                /* serviceOfferingId */ 1L,
+                /* elementId */ 0L,
+                "name",
+                /* templateId */0L,
+                HypervisorType.XenServer,
+                /* guestOSId */ 0L,
+                /* domainId */ 0L,
+                /* accountId */ 1L,
+                /* userId */ 1L,
+                /* isRedundantRouter */ false,
+                RedundantState.MASTER,
+                /* haEnabled */ false,
+                /* stopPending */ false,
+                /* vpcId */ null);
+        routerNeedUpdateMaster.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
+        final DomainRouterVO routerUpdateComplete = new DomainRouterVO(/* id */ 4L,
+                /* serviceOfferingId */ 1L,
+                /* elementId */ 0L,
+                "name",
+                /* templateId */0L,
+                HypervisorType.XenServer,
+                /* guestOSId */ 0L,
+                /* domainId */ 0L,
+                /* accountId */ 1L,
+                /* userId */ 1L,
+                /* isRedundantRouter */ false,
+                RedundantState.UNKNOWN,
+                /* haEnabled */ false,
+                /* stopPending */ false,
+                /* vpcId */ null);
+                routerUpdateComplete.setUpdateState(VirtualRouter.UpdateState.UPDATE_COMPLETE);
+        final DomainRouterVO routerUpdateInProgress = new DomainRouterVO(/* id */ 5L,
+                /* serviceOfferingId */ 1L,
+                /* elementId */ 0L,
+                "name",
+                /* templateId */0L,
+                HypervisorType.XenServer,
+                /* guestOSId */ 0L,
+                /* domainId */ 0L,
+                /* accountId */ 1L,
+                /* userId */ 1L,
+                /* isRedundantRouter */ false,
+                RedundantState.UNKNOWN,
+                /* haEnabled */ false,
+                /* stopPending */ false,
+                /* vpcId */ null);
+                routerUpdateInProgress.setUpdateState(VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
+        List<DomainRouterVO> routerList1=new ArrayList<>();
+        routerList1.add(routerUpdateComplete);
+        routerList1.add(routerNeedUpdateBackup);
+        routerList1.add(routerNeedUpdateMaster);
+        routerList1.add(routerUpdateInProgress);
+        List<DomainRouterVO> routerList2=new ArrayList<>();
+        routerList2.add(routerUpdateComplete);
+        routerList2.add(routerNeedUpdateBackup);
+        routerList2.add(routerNeedUpdateMaster);
+        List<DomainRouterVO> routerList3=new ArrayList<>();
+        routerList3.add(routerUpdateComplete);
+        routerList3.add(routerUpdateInProgress);
+        when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
+        when(_templateDao.findRoutingTemplate(HypervisorType.XenServer, "SystemVM Template (XenServer)")).thenReturn(new VMTemplateVO());
+        when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
+        when(_routerDao.findById(router.getId())).thenReturn(router);
+        when(_routerDao.listByNetworkAndRole(1l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
+        when(_routerDao.listByNetworkAndRole(2l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList2);
+        when(_routerDao.listByNetworkAndRole(3l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
+        when(_routerDao.listByNetworkAndRole(6l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList3);
+        when(_networkDetailsDao.findDetail(1l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(1l,Network.updatingInSequence,"true",true));
+        when(_networkDetailsDao.findDetail(2l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
+        when(_networkDetailsDao.findDetail(6l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
+        when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
+    }
+
+    @Test
+    public void testCanHandle() {
+        Network network = Mockito.mock(Network.class);
+
+        final long networkId = 1;
+        final long physicalNetworkId = 42;
+        final long networkOfferingId = 10;
+        final long dataCenterId = 33;
+
+        when(network.getId()).thenReturn(networkId);
+        when(network.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
+        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
+        when(network.getDataCenterId()).thenReturn(dataCenterId);
+        when(network.getVpcId()).thenReturn(null);
+
+        when(virtualRouterElement._networkMdl.getPhysicalNetworkId(network)).thenReturn(physicalNetworkId);
+        when(virtualRouterElement._networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())).thenReturn(true);
+        when(virtualRouterElement._networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, networkId)).thenReturn(true);
+
+        assertTrue(virtualRouterElement.canHandle(network, null));
+    }
+
+    @Test
+    public void testAddPasswordAndUserdata() throws Exception {
+        Network network = Mockito.mock(Network.class);
+        VirtualMachineProfile vm = Mockito.mock(VirtualMachineProfile.class);
+        NicProfile nic = Mockito.mock(NicProfile.class);
+        DeployDestination dest = Mockito.mock(DeployDestination.class);
+        ReservationContext context = Mockito.mock(ReservationContext.class);
+        Service service = Service.UserData;
+
+        final long networkId = 1;
+        final long physicalNetworkId = 42;
+        final long networkOfferingId = 10;
+        final long dataCenterId = 33;
+
+        when(network.getId()).thenReturn(networkId);
+        when(network.getPhysicalNetworkId()).thenReturn(physicalNetworkId);
+        when(network.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
+        when(network.getDataCenterId()).thenReturn(dataCenterId);
+        when(network.getVpcId()).thenReturn(null);
+
+        when(vm.getType()).thenReturn(VirtualMachine.Type.User);
+
+        when(virtualRouterElement._networkMdl.getPhysicalNetworkId(network)).thenReturn(physicalNetworkId);
+        when(virtualRouterElement._networkMdl.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())).thenReturn(true);
+        when(virtualRouterElement._networkMdl.isProviderSupportServiceInNetwork(networkId, service, Network.Provider.VirtualRouter)).thenReturn(true);
+
+        when(virtualRouterElement._dcDao.findById(dataCenterId)).thenReturn(Mockito.mock(DataCenterVO.class));
+
+        when(virtualRouterElement.canHandle(network, service)).thenReturn(false);
+
+        assertTrue(virtualRouterElement.addPasswordAndUserdata(network, nic, vm, dest, context));
+    }
+}
diff --git a/server/test/com/cloud/network/element/VpcVirtualRouterElementTest.java b/server/src/test/java/com/cloud/network/element/VpcVirtualRouterElementTest.java
similarity index 100%
rename from server/test/com/cloud/network/element/VpcVirtualRouterElementTest.java
rename to server/src/test/java/com/cloud/network/element/VpcVirtualRouterElementTest.java
diff --git a/server/src/test/java/com/cloud/network/firewall/FirewallManagerTest.java b/server/src/test/java/com/cloud/network/firewall/FirewallManagerTest.java
new file mode 100644
index 0000000..4a42a54
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/firewall/FirewallManagerTest.java
@@ -0,0 +1,218 @@
+// 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.network.firewall;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.spy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.user.AccountManager;
+import com.cloud.user.DomainManager;
+import junit.framework.Assert;
+
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkRuleApplier;
+import com.cloud.network.element.FirewallServiceProvider;
+import com.cloud.network.element.VirtualRouterElement;
+import com.cloud.network.element.VpcVirtualRouterElement;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(MockitoJUnitRunner.class)
+public class FirewallManagerTest {
+    private static final Logger s_logger = Logger.getLogger(FirewallManagerTest.class);
+
+
+    @Ignore("Requires database to be set up")
+    @Test
+    public void testInjected() {
+
+//        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)ComponentLocator.getCurrentLocator().getManager(FirewallManager.class);
+//        Assert.assertTrue(firewallMgr._firewallElements.enumeration().hasMoreElements());
+//        Assert.assertTrue(firewallMgr._pfElements.enumeration().hasMoreElements());
+//        Assert.assertTrue(firewallMgr._staticNatElements.enumeration().hasMoreElements());
+//        Assert.assertTrue(firewallMgr._networkAclElements.enumeration().hasMoreElements());
+//        Assert.assertNotNull(firewallMgr._networkModel);
+//
+//        Assert.assertNotNull(firewallMgr._firewallElements.get("VirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._firewallElements.get("VpcVirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._pfElements.get("VirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._pfElements.get("VpcVirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._staticNatElements.get("VirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._staticNatElements.get("VpcVirtualRouter"));
+//        Assert.assertNotNull(firewallMgr._networkAclElements.get("VpcVirtualRouter"));
+//        Assert.assertNull(firewallMgr._networkAclElements.get("VirtualRouter"));
+//
+//
+//        Assert.assertTrue(firewallMgr._firewallElements.get("VirtualRouter") instanceof FirewallServiceProvider);
+//        Assert.assertTrue(firewallMgr._pfElements.get("VirtualRouter") instanceof PortForwardingServiceProvider);
+//        Assert.assertTrue(firewallMgr._staticNatElements.get("VirtualRouter") instanceof StaticNatServiceProvider);
+//        Assert.assertTrue(firewallMgr._networkAclElements.get("VpcVirtualRouter") instanceof NetworkACLServiceProvider);
+
+        s_logger.info("Done testing injection of service elements into firewall manager");
+
+    }
+
+    @Mock
+    AccountManager _accountMgr;
+    @Mock
+    NetworkOrchestrationService _networkMgr;
+    @Mock
+    NetworkModel _networkModel;
+    @Mock
+    DomainManager _domainMgr;
+    @Mock
+    VpcManager _vpcMgr;
+    @Mock
+    IpAddressManager _ipAddrMgr;
+    @Mock
+    FirewallRulesDao _firewallDao;
+
+    @InjectMocks
+    FirewallManager _firewallMgr = new FirewallManagerImpl();
+
+    @Before
+    public void initMocks() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Ignore("Requires database to be set up")
+    @Test
+    public void testApplyRules() {
+        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
+        FirewallRuleVO rule = new FirewallRuleVO("rule1", 1, 80, "TCP", 1, 2, 1, FirewallRule.Purpose.Firewall, null, null, null, null);
+        ruleList.add(rule);
+        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
+
+        NetworkOrchestrationService netMgr = mock(NetworkOrchestrationService.class);
+        IpAddressManager addrMgr = mock(IpAddressManager.class);
+        firewallMgr._networkMgr = netMgr;
+
+        try {
+            firewallMgr.applyRules(ruleList, false, false);
+            verify(addrMgr).applyRules(any(List.class), any(FirewallRule.Purpose.class), any(NetworkRuleApplier.class), anyBoolean());
+
+        } catch (ResourceUnavailableException e) {
+            Assert.fail("Unreachable code");
+        }
+    }
+
+    @Ignore("Requires database to be set up")
+    @Test
+    public void testApplyFWRules() {
+        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
+        FirewallRuleVO rule = new FirewallRuleVO("rule1", 1, 80, "TCP", 1, 2, 1, FirewallRule.Purpose.Firewall, null, null, null, null);
+        ruleList.add(rule);
+        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
+        VirtualRouterElement virtualRouter = mock(VirtualRouterElement.class);
+        VpcVirtualRouterElement vpcVirtualRouter = mock(VpcVirtualRouterElement.class);
+
+        List<FirewallServiceProvider> fwElements = new ArrayList<FirewallServiceProvider>();
+        fwElements.add(ComponentContext.inject(VirtualRouterElement.class));
+        fwElements.add(ComponentContext.inject(VpcVirtualRouterElement.class));
+
+        firewallMgr._firewallElements = fwElements;
+
+        try {
+            when(virtualRouter.applyFWRules(any(Network.class), any(List.class))).thenReturn(false);
+            when(vpcVirtualRouter.applyFWRules(any(Network.class), any(List.class))).thenReturn(true);
+            //Network network, Purpose purpose, List<? extends FirewallRule> rules
+            firewallMgr.applyRules(mock(Network.class), Purpose.Firewall, ruleList);
+            verify(vpcVirtualRouter).applyFWRules(any(Network.class), any(List.class));
+            verify(virtualRouter).applyFWRules(any(Network.class), any(List.class));
+
+        } catch (ResourceUnavailableException e) {
+            Assert.fail("Unreachable code");
+        }
+    }
+
+    @Test
+    public void testDetectRulesConflict() {
+        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
+        FirewallRuleVO rule1 = spy(new FirewallRuleVO("rule1", 3, 500, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
+        FirewallRuleVO rule2 = spy(new FirewallRuleVO("rule2", 3, 1701, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
+        FirewallRuleVO rule3 = spy(new FirewallRuleVO("rule3", 3, 4500, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
+
+        List<String> sString = Arrays.asList("10.1.1.1/24","192.168.1.1/24");
+        List<String> dString1 = Arrays.asList("10.1.1.1/25");
+        List<String> dString2 = Arrays.asList("10.1.1.128/25");
+
+        FirewallRuleVO rule4 = spy(new FirewallRuleVO("rule4", 3L, 10, 20, "TCP", 1, 2, 1, Purpose.Firewall, sString, dString1, null, null,
+                null, FirewallRule.TrafficType.Egress));
+
+        ruleList.add(rule1);
+        ruleList.add(rule2);
+        ruleList.add(rule3);
+        ruleList.add(rule4);
+
+        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
+
+        when(firewallMgr._firewallDao.listByIpAndPurposeAndNotRevoked(3,null)).thenReturn(ruleList);
+        when(rule1.getId()).thenReturn(1L);
+        when(rule2.getId()).thenReturn(2L);
+        when(rule3.getId()).thenReturn(3L);
+        when(rule4.getId()).thenReturn(4L);
+
+        FirewallRule newRule1 = new FirewallRuleVO("newRule1", 3, 500, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
+        FirewallRule newRule2 = new FirewallRuleVO("newRule2", 3, 1701, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
+        FirewallRule newRule3 = new FirewallRuleVO("newRule3", 3, 4500, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
+        FirewallRule newRule4 = new FirewallRuleVO("newRule4", 3L, 15, 25, "TCP", 1, 2, 1, Purpose.Firewall, sString, dString2, null, null,
+                null, FirewallRule.TrafficType.Egress);
+
+        try {
+            firewallMgr.detectRulesConflict(newRule1);
+            firewallMgr.detectRulesConflict(newRule2);
+            firewallMgr.detectRulesConflict(newRule3);
+            firewallMgr.detectRulesConflict(newRule4);
+        }
+        catch (NetworkRuleConflictException ex) {
+            Assert.fail();
+        }
+    }
+
+
+
+}
diff --git a/server/src/test/java/com/cloud/network/guru/DirectNetworkGuruTest.java b/server/src/test/java/com/cloud/network/guru/DirectNetworkGuruTest.java
new file mode 100644
index 0000000..72bec50
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/guru/DirectNetworkGuruTest.java
@@ -0,0 +1,132 @@
+// 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.network.guru;
+
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+public class DirectNetworkGuruTest {
+
+    protected DirectNetworkGuru guru = new DirectNetworkGuru();
+
+    @Mock
+    PhysicalNetworkVO physicalNetwork;
+
+    @Mock
+    DataCenterVO dc;
+
+    @Mock
+    NetworkOffering offering;
+
+    @Mock
+    NetworkOfferingServiceMapDao ntwkOfferingSrvcDao;
+
+    @Mock
+    DataCenterDao dcDao;
+
+    @Mock
+    PhysicalNetworkDao physicalNetworkDao;
+
+    @Mock
+    Network network;
+
+    @Mock
+    NetworkModel networkModel;
+
+    @Mock
+    DeploymentPlan plan;
+
+    @Mock
+    Account owner;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        guru._ntwkOfferingSrvcDao = ntwkOfferingSrvcDao;
+        guru._dcDao = dcDao;
+        guru._physicalNetworkDao = physicalNetworkDao;
+        guru._networkModel = networkModel;
+
+        when(physicalNetwork.getId()).thenReturn(1l);
+        when(physicalNetwork.getIsolationMethods()).thenReturn(Arrays.asList("VXLAN", "VLAN"));
+
+        when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
+        when(dc.getId()).thenReturn(1l);
+        when(offering.getGuestType()).thenReturn(GuestType.Shared);
+        when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
+        when(offering.getId()).thenReturn(42l);
+        when(ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp)).thenReturn(false);
+        when(ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NiciraNvp)).thenReturn(false);
+    }
+
+    @Test
+    public void testIsMyIsolationMethod() {
+        assertTrue(guru.isMyIsolationMethod(physicalNetwork));
+    }
+
+    @Test
+    public void testIsolationMethods() {
+        IsolationMethod[] expected = new IsolationMethod[] { new IsolationMethod("VLAN"), new IsolationMethod("VXLAN") };
+        assertEquals(expected, guru.getIsolationMethods());
+    }
+
+    @Test
+    public void testTrafficTypes() {
+        assertTrue(guru.isMyTrafficType(TrafficType.Guest));
+    }
+
+    @Test
+    public void testCanHandle() {
+        assertTrue(guru.canHandle(offering, dc, physicalNetwork));
+    }
+
+    @Test
+    public void testCanDesign() {
+        when(dcDao.findById(dc.getId())).thenReturn(dc);
+        when(plan.getDataCenterId()).thenReturn(1l);
+        when(plan.getPhysicalNetworkId()).thenReturn(1l);
+        when(physicalNetworkDao.findById(physicalNetwork.getId())).thenReturn(physicalNetwork);
+        when(offering.isRedundantRouter()).thenReturn(false);
+
+        when(networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.SecurityGroup)).thenReturn(true);
+
+        assertNotNull(guru.design(offering, plan, network, owner));
+    }
+}
diff --git a/server/test/com/cloud/network/lb/AssignLoadBalancerTest.java b/server/src/test/java/com/cloud/network/lb/AssignLoadBalancerTest.java
similarity index 100%
rename from server/test/com/cloud/network/lb/AssignLoadBalancerTest.java
rename to server/src/test/java/com/cloud/network/lb/AssignLoadBalancerTest.java
diff --git a/server/test/com/cloud/network/lb/UpdateLoadBalancerTest.java b/server/src/test/java/com/cloud/network/lb/UpdateLoadBalancerTest.java
similarity index 100%
rename from server/test/com/cloud/network/lb/UpdateLoadBalancerTest.java
rename to server/src/test/java/com/cloud/network/lb/UpdateLoadBalancerTest.java
diff --git a/server/test/com/cloud/network/router/NetworkHelperImplTest.java b/server/src/test/java/com/cloud/network/router/NetworkHelperImplTest.java
similarity index 100%
rename from server/test/com/cloud/network/router/NetworkHelperImplTest.java
rename to server/src/test/java/com/cloud/network/router/NetworkHelperImplTest.java
diff --git a/server/test/com/cloud/network/router/RouterControlHelperTest.java b/server/src/test/java/com/cloud/network/router/RouterControlHelperTest.java
similarity index 100%
rename from server/test/com/cloud/network/router/RouterControlHelperTest.java
rename to server/src/test/java/com/cloud/network/router/RouterControlHelperTest.java
diff --git a/server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java b/server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java
rename to server/src/test/java/com/cloud/network/router/VirtualNetworkApplianceManagerImplTest.java
diff --git a/server/test/com/cloud/network/security/SecurityGroupManagerImpl2Test.java b/server/src/test/java/com/cloud/network/security/SecurityGroupManagerImpl2Test.java
similarity index 100%
rename from server/test/com/cloud/network/security/SecurityGroupManagerImpl2Test.java
rename to server/src/test/java/com/cloud/network/security/SecurityGroupManagerImpl2Test.java
diff --git a/server/test/com/cloud/network/security/SecurityGroupManagerImplTest.java b/server/src/test/java/com/cloud/network/security/SecurityGroupManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/network/security/SecurityGroupManagerImplTest.java
rename to server/src/test/java/com/cloud/network/security/SecurityGroupManagerImplTest.java
diff --git a/server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java b/server/src/test/java/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java
rename to server/src/test/java/com/cloud/network/security/SecurityGroupManagerTestConfiguration.java
diff --git a/server/test/com/cloud/network/security/SecurityGroupQueueTest.java b/server/src/test/java/com/cloud/network/security/SecurityGroupQueueTest.java
similarity index 100%
rename from server/test/com/cloud/network/security/SecurityGroupQueueTest.java
rename to server/src/test/java/com/cloud/network/security/SecurityGroupQueueTest.java
diff --git a/server/src/test/java/com/cloud/network/vpc/NetworkACLManagerImplTest.java b/server/src/test/java/com/cloud/network/vpc/NetworkACLManagerImplTest.java
new file mode 100644
index 0000000..1d7cdc1
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/vpc/NetworkACLManagerImplTest.java
@@ -0,0 +1,81 @@
+// 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.network.vpc;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.vpc.NetworkACLItem.State;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NetworkACLManagerImplTest {
+
+    @Spy
+    @InjectMocks
+    private NetworkACLManagerImpl networkACLManagerImpl;
+    @Mock
+    private NetworkACLItemDao networkACLItemDaoMock;
+
+    @Test(expected = CloudRuntimeException.class)
+    public void updateNetworkACLItemTestUpdateDoesNotWork() throws ResourceUnavailableException {
+        NetworkACLItemVO networkACLItemVOMock = new NetworkACLItemVO();
+        networkACLItemVOMock.id = 1L;
+
+        Mockito.doReturn(false).when(networkACLItemDaoMock).update(1L, networkACLItemVOMock);
+
+        networkACLManagerImpl.updateNetworkACLItem(networkACLItemVOMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void updateNetworkACLItemTestUpdateWorksButApplyDoesNotWork() throws ResourceUnavailableException {
+        NetworkACLItemVO networkACLItemVOMock = new NetworkACLItemVO();
+        networkACLItemVOMock.id = 1L;
+        networkACLItemVOMock.aclId = 2L;
+
+        Mockito.doReturn(true).when(networkACLItemDaoMock).update(1L, networkACLItemVOMock);
+        Mockito.doReturn(false).when(networkACLManagerImpl).applyNetworkACL(2L);
+
+        networkACLManagerImpl.updateNetworkACLItem(networkACLItemVOMock);
+    }
+
+    @Test
+    public void updateNetworkACLItemTestHappyDay() throws ResourceUnavailableException {
+        NetworkACLItemVO networkACLItemVOMock = new NetworkACLItemVO();
+        networkACLItemVOMock.id = 1L;
+        networkACLItemVOMock.aclId = 2L;
+
+        Mockito.doReturn(true).when(networkACLItemDaoMock).update(1L, networkACLItemVOMock);
+        Mockito.doReturn(true).when(networkACLManagerImpl).applyNetworkACL(2L);
+
+        NetworkACLItem returnedNetworkAclItem = networkACLManagerImpl.updateNetworkACLItem(networkACLItemVOMock);
+
+        Mockito.verify(networkACLItemDaoMock).update(1L, networkACLItemVOMock);
+        Mockito.verify(networkACLManagerImpl).applyNetworkACL(2L);
+
+        Assert.assertEquals(networkACLItemVOMock, returnedNetworkAclItem);
+        Assert.assertEquals(State.Add, returnedNetworkAclItem.getState());
+    }
+}
diff --git a/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java b/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java
new file mode 100644
index 0000000..9815526
--- /dev/null
+++ b/server/src/test/java/com/cloud/network/vpc/NetworkACLServiceImplTest.java
@@ -0,0 +1,1369 @@
+// 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.network.vpc;
+
+import static org.mockito.Mockito.times;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
+import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
+import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.commons.lang.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.vpc.NetworkACLItem.Action;
+import com.cloud.network.vpc.NetworkACLItem.TrafficType;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(CallContext.class)
+public class NetworkACLServiceImplTest {
+
+    @Spy
+    @InjectMocks
+    private NetworkACLServiceImpl networkAclServiceImpl = new NetworkACLServiceImpl();
+    @Mock
+    private NetworkModel networkModelMock;
+    @Mock
+    private NetworkACLManager networkAclManagerMock;
+    @Mock
+    private NetworkACLItemDao networkAclItemDaoMock;
+    @Mock
+    private EntityManager entityManagerMock;
+    @Mock
+    private AccountManager accountManagerMock;
+    @Mock
+    private NetworkACLDao networkAclDaoMock;
+
+    @Mock
+    private CreateNetworkACLCmd createNetworkAclCmdMock;
+    @Mock
+    private UpdateNetworkACLItemCmd updateNetworkACLItemCmdMock;
+    @Mock
+    private Network networkMock;
+    @Mock
+    private NetworkACLVO networkAclMock;
+    @Mock
+    private NetworkACLItemVO networkAclItemVoMock;
+    @Mock
+    private NetworkACLVO networkACLVOMock;
+    @Mock
+    private UpdateNetworkACLListCmd updateNetworkACLListCmdMock;
+
+    private Long networkAclMockId = 1L;
+    private Long networkOfferingMockId = 2L;
+    private Long networkMockVpcMockId = 3L;
+    private long networkAclListId = 1l;
+
+    @Mock
+    private MoveNetworkAclItemCmd moveNetworkAclItemCmdMock;
+    @Mock
+    private NetworkACLItemVO aclRuleBeingMovedMock;
+    private String uuidAclRuleBeingMoved = "uuidRuleBeingMoved";
+
+    @Mock
+    private NetworkACLItemVO previousAclRuleMock;
+    private String previousAclRuleUuid = "uuidPreviousAclRule";
+
+    @Mock
+    private NetworkACLItemVO nextAclRuleMock;
+    private String nextAclRuleUuid = "uuidNextAclRule";
+
+    @Mock
+    private CallContext callContextMock;
+
+    @Before
+    public void befoteTest() {
+        PowerMockito.mockStatic(CallContext.class);
+        PowerMockito.when(CallContext.current()).thenReturn(callContextMock);
+        Mockito.doReturn(Mockito.mock(User.class)).when(callContextMock).getCallingUser();
+        Mockito.doReturn(Mockito.mock(Account.class)).when(callContextMock).getCallingAccount();
+
+        Mockito.when(networkAclDaoMock.findById(networkAclListId)).thenReturn(networkACLVOMock);
+        Mockito.when(createNetworkAclCmdMock.getNetworkId()).thenReturn(1L);
+        Mockito.when(createNetworkAclCmdMock.getProtocol()).thenReturn("tcp");
+
+        Mockito.when(networkMock.getNetworkOfferingId()).thenReturn(networkOfferingMockId);
+        Mockito.when(networkMock.getVpcId()).thenReturn(networkMockVpcMockId);
+
+        Mockito.when(moveNetworkAclItemCmdMock.getUuidRuleBeingMoved()).thenReturn(uuidAclRuleBeingMoved);
+
+        Mockito.when(aclRuleBeingMovedMock.getUuid()).thenReturn(uuidAclRuleBeingMoved);
+        Mockito.when(aclRuleBeingMovedMock.getAclId()).thenReturn(networkAclMockId);
+
+        Mockito.when(previousAclRuleMock.getUuid()).thenReturn(previousAclRuleUuid);
+        Mockito.when(nextAclRuleMock.getUuid()).thenReturn(nextAclRuleUuid);
+
+        Mockito.when(networkAclMock.getVpcId()).thenReturn(networkMockVpcMockId);
+    }
+
+    @Test
+    public void createNetworkACLItemTestAclNumberNull() {
+        createNetworkACLItemTestForNumberAndExecuteTest(null);
+    }
+
+    @Test
+    public void createNetworkACLItemTestAclNumberNotNull() {
+        createNetworkACLItemTestForNumberAndExecuteTest(10);
+    }
+
+    private void createNetworkACLItemTestForNumberAndExecuteTest(Integer number) {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(number);
+
+        Mockito.doReturn(networkAclMockId).when(networkAclServiceImpl).createAclListIfNeeded(createNetworkAclCmdMock);
+        Mockito.when(networkAclManagerMock.getNetworkACL(networkAclMockId)).thenReturn(networkAclMock);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+        Mockito.doNothing().when(networkAclServiceImpl).validateNetworkAcl(networkAclMock);
+
+        Mockito.doReturn(Action.Allow).when(networkAclServiceImpl).validateAndCreateNetworkAclRuleAction(Mockito.anyString());
+        Mockito.when(networkAclItemDaoMock.getMaxNumberByACL(networkAclMockId)).thenReturn(5);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateNetworkACLItem(Mockito.any(NetworkACLItemVO.class));
+        Mockito.when(networkAclManagerMock.createNetworkACLItem(Mockito.any(NetworkACLItemVO.class))).thenAnswer(new Answer<NetworkACLItemVO>() {
+            @Override
+            public NetworkACLItemVO answer(InvocationOnMock invocation) throws Throwable {
+                return (NetworkACLItemVO)invocation.getArguments()[0];
+            }
+        });
+
+        NetworkACLItem netowkrAclRuleCreated = networkAclServiceImpl.createNetworkACLItem(createNetworkAclCmdMock);
+
+        Assert.assertEquals(number == null ? 6 : number, netowkrAclRuleCreated.getNumber());
+
+        InOrder inOrder = Mockito.inOrder(networkAclManagerMock, networkAclServiceImpl, networkAclItemDaoMock);
+        inOrder.verify(networkAclServiceImpl).createAclListIfNeeded(createNetworkAclCmdMock);
+        inOrder.verify(networkAclManagerMock).getNetworkACL(networkAclMockId);
+        inOrder.verify(networkAclServiceImpl).validateNetworkAcl(networkAclMock);
+        inOrder.verify(networkAclServiceImpl).validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+        inOrder.verify(networkAclServiceImpl).validateAndCreateNetworkAclRuleAction(Mockito.anyString());
+        inOrder.verify(networkAclItemDaoMock, Mockito.times(number == null ? 1 : 0)).getMaxNumberByACL(networkAclMockId);
+        inOrder.verify(networkAclServiceImpl).validateNetworkACLItem(Mockito.any(NetworkACLItemVO.class));
+        inOrder.verify(networkAclManagerMock).createNetworkACLItem(Mockito.any(NetworkACLItemVO.class));
+    }
+
+    @Test
+    public void createAclListIfNeededTestAclRuleListIdNotNull() {
+        Long expectedAclListId = 1L;
+        Mockito.when(createNetworkAclCmdMock.getACLId()).thenReturn(expectedAclListId);
+
+        Long returnetAclListId = networkAclServiceImpl.createAclListIfNeeded(createNetworkAclCmdMock);
+
+        Assert.assertEquals(expectedAclListId, returnetAclListId);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void createAclListIfNeededTestAclRuleListIdNullAndNetworkDoesNotHaveVpc() {
+        Mockito.when(createNetworkAclCmdMock.getACLId()).thenReturn(null);
+
+        long networkId = 1L;
+        Mockito.when(createNetworkAclCmdMock.getNetworkId()).thenReturn(networkId);
+
+        Network networkMock = Mockito.mock(Network.class);
+        Mockito.when(networkMock.getVpcId()).thenReturn(null);
+
+        Mockito.doReturn(networkMock).when(networkModelMock).getNetwork(networkId);
+
+        networkAclServiceImpl.createAclListIfNeeded(createNetworkAclCmdMock);
+    }
+
+    @Test
+    public void createAclListIfNeededTestAclRuleListIdNullAndNetworkWithVpcAndNotAclListYet() {
+        Mockito.when(createNetworkAclCmdMock.getACLId()).thenReturn(null);
+
+        long networkId = 1L;
+        Mockito.when(createNetworkAclCmdMock.getNetworkId()).thenReturn(networkId);
+
+        Network networkMock = Mockito.mock(Network.class);
+        Mockito.when(networkMock.getVpcId()).thenReturn(12L);
+        Mockito.when(networkMock.getNetworkACLId()).thenReturn(null);
+
+        Mockito.doReturn(networkMock).when(networkModelMock).getNetwork(networkId);
+
+        Long expectedAclListId = 15L;
+        Mockito.doReturn(expectedAclListId).when(networkAclServiceImpl).createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+
+        Long aclIdReturned = networkAclServiceImpl.createAclListIfNeeded(createNetworkAclCmdMock);
+
+        Assert.assertEquals(expectedAclListId, aclIdReturned);
+        Mockito.verify(networkAclServiceImpl).createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+    }
+
+    @Test
+    public void createAclListIfNeededTestAclRuleListIdNullAndNetworkWithVpcAndAclListAlreadyCreated() {
+        Mockito.when(createNetworkAclCmdMock.getACLId()).thenReturn(null);
+
+        long networkId = 1L;
+        Mockito.when(createNetworkAclCmdMock.getNetworkId()).thenReturn(networkId);
+        Network networkMock = Mockito.mock(Network.class);
+        ;
+        Mockito.when(networkMock.getVpcId()).thenReturn(12L);
+        Long expectedAclListId = 15L;
+        Mockito.when(networkMock.getNetworkACLId()).thenReturn(expectedAclListId);
+
+        Mockito.doReturn(networkMock).when(networkModelMock).getNetwork(networkId);
+
+        Mockito.doReturn(16L).when(networkAclServiceImpl).createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+
+        Long aclIdReturned = networkAclServiceImpl.createAclListIfNeeded(createNetworkAclCmdMock);
+
+        Assert.assertEquals(expectedAclListId, aclIdReturned);
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void createAclListForNetworkAndReturnAclListIdTestServicesNotSupportedByNetworkOffering() {
+        Mockito.doReturn(false).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void createAclListForNetworkAndReturnAclListIdTestServicesSupportedByNetworkOfferingButVpcNotFound() {
+        Mockito.doReturn(true).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        Mockito.doReturn(null).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+
+        networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createAclListForNetworkAndReturnAclListIdTestCreateNetworkAclReturnsNull() {
+        Mockito.doReturn(true).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.doReturn(null).when(networkAclManagerMock).createNetworkACL(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean());
+
+        networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createAclListForNetworkAndReturnAclListIdTestAclNetworkIsCreatedButNotApplied() throws ResourceUnavailableException {
+        Mockito.doReturn(true).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.doReturn(Mockito.mock(NetworkACL.class)).when(networkAclManagerMock).createNetworkACL(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean());
+        Mockito.doReturn(false).when(networkAclManagerMock).replaceNetworkACL(Mockito.any(NetworkACL.class), Mockito.any(NetworkVO.class));
+
+        NetworkVO networkVoMock = new NetworkVO();
+        networkVoMock.setNetworkOfferingId(networkOfferingMockId);
+        networkVoMock.setVpcId(networkMockVpcMockId);
+
+        networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkVoMock);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createAclListForNetworkAndReturnAclListIdTestAclNetworkIsCreatedButNotAppliedWithException() throws ResourceUnavailableException {
+        Mockito.doReturn(true).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.doReturn(Mockito.mock(NetworkACL.class)).when(networkAclManagerMock).createNetworkACL(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean());
+
+        Mockito.doThrow(ResourceUnavailableException.class).when(networkAclManagerMock).replaceNetworkACL(Mockito.any(NetworkACL.class), Mockito.any(NetworkVO.class));
+
+        NetworkVO networkVoMock = new NetworkVO();
+        networkVoMock.setNetworkOfferingId(networkOfferingMockId);
+        networkVoMock.setVpcId(networkMockVpcMockId);
+
+        networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkVoMock);
+    }
+
+    @Test
+    public void createAclListForNetworkAndReturnAclListIdTestAclIsCreatedAndAppliedWithSuccess() throws ResourceUnavailableException {
+        Mockito.doReturn(true).when(networkModelMock).areServicesSupportedByNetworkOffering(networkOfferingMockId, Network.Service.NetworkACL);
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+
+        NetworkACL networkAclMock = Mockito.mock(NetworkACL.class);
+        Long expectedNetworkAclId = 5L;
+        Mockito.when(networkAclMock.getId()).thenReturn(expectedNetworkAclId);
+        Mockito.doReturn(networkAclMock).when(networkAclManagerMock).createNetworkACL(Mockito.anyString(), Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean());
+
+        Mockito.doReturn(true).when(networkAclManagerMock).replaceNetworkACL(Mockito.any(NetworkACL.class), Mockito.any(NetworkVO.class));
+
+        NetworkVO networkVoMock = new NetworkVO();
+        networkVoMock.setNetworkOfferingId(networkOfferingMockId);
+        networkVoMock.setVpcId(networkMockVpcMockId);
+
+        Long networkAclIdReceived = networkAclServiceImpl.createAclListForNetworkAndReturnAclListId(createNetworkAclCmdMock, networkVoMock);
+
+        Assert.assertEquals(expectedNetworkAclId, networkAclIdReceived);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAclRuleNumberTestNumberLessThanOne() {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(0);
+        networkAclServiceImpl.validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAclRuleNumberTestNumberNegative() {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(-1);
+        networkAclServiceImpl.validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAclRuleNumberTestNumberInOtherAcl() {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(1);
+        Mockito.doReturn(Mockito.mock(NetworkACLItemVO.class)).when(networkAclItemDaoMock).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+
+        networkAclServiceImpl.validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+
+        Mockito.verify(networkAclItemDaoMock).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+    }
+
+    @Test
+    public void validateAclRuleNumberTestHappyDay() {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(1);
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+
+        networkAclServiceImpl.validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+        Mockito.verify(networkAclItemDaoMock).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+    }
+
+    @Test
+    public void validateAclRuleNumberTestNumberNull() {
+        Mockito.when(createNetworkAclCmdMock.getNumber()).thenReturn(null);
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+
+        networkAclServiceImpl.validateAclRuleNumber(createNetworkAclCmdMock, networkAclMock);
+        Mockito.verify(networkAclItemDaoMock, Mockito.times(0)).findByAclAndNumber(Mockito.anyLong(), Mockito.anyInt());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclTestAclNull() {
+        networkAclServiceImpl.validateNetworkAcl(null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclTestAclDefaulAllow() {
+        Mockito.when(networkAclMock.getId()).thenReturn(2L);
+        networkAclServiceImpl.validateNetworkAcl(networkAclMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclTestAclDefaulDeny() {
+        Mockito.when(networkAclMock.getId()).thenReturn(1L);
+        networkAclServiceImpl.validateNetworkAcl(networkAclMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclTestAclNotDefaulWithoutVpc() {
+        Mockito.when(networkAclMock.getId()).thenReturn(3L);
+        Mockito.doReturn(null).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        ;
+
+        networkAclServiceImpl.validateNetworkAcl(networkAclMock);
+    }
+
+    @Test
+    @PrepareForTest(CallContext.class)
+    public void validateNetworkAclTestAclNotDefaulWithVpc() {
+        CallContext callContextMock = Mockito.mock(CallContext.class);
+        Mockito.doReturn(Mockito.mock(Account.class)).when(callContextMock).getCallingAccount();
+
+        PowerMockito.mockStatic(CallContext.class);
+        PowerMockito.when(CallContext.current()).thenReturn(callContextMock);
+
+        Mockito.when(networkAclMock.getId()).thenReturn(3L);
+        Mockito.when(networkAclMock.getVpcId()).thenReturn(networkMockVpcMockId);
+
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+
+        networkAclServiceImpl.validateNetworkAcl(networkAclMock);
+
+        Mockito.verify(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+
+        PowerMockito.verifyStatic();
+        CallContext.current();
+
+    }
+
+    @Test
+    public void validateAndCreateNetworkAclRuleActionTestActionNull() {
+        NetworkACLItem.Action receivedAction = networkAclServiceImpl.validateAndCreateNetworkAclRuleAction(null);
+
+        Assert.assertEquals(NetworkACLItem.Action.Allow, receivedAction);
+
+        Mockito.verify(networkAclServiceImpl).validateNetworkAclRuleAction(null);
+    }
+
+    @Test
+    public void validateAndCreateNetworkAclRuleActionTestActionAllow() {
+        NetworkACLItem.Action receivedAction = networkAclServiceImpl.validateAndCreateNetworkAclRuleAction("allow");
+
+        Assert.assertEquals(NetworkACLItem.Action.Allow, receivedAction);
+        Mockito.verify(networkAclServiceImpl).validateNetworkAclRuleAction("allow");
+    }
+
+    @Test
+    public void validateAndCreateNetworkAclRuleActionTestActionDeny() {
+        NetworkACLItem.Action receivedAction = networkAclServiceImpl.validateAndCreateNetworkAclRuleAction("deny");
+
+        Assert.assertEquals(NetworkACLItem.Action.Deny, receivedAction);
+        Mockito.verify(networkAclServiceImpl).validateNetworkAclRuleAction("deny");
+    }
+
+    @Test
+    public void validateNetworkAclRuleActionTestActionNull() {
+        networkAclServiceImpl.validateNetworkAclRuleAction(null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclRuleActionTestInvalidAction() {
+        networkAclServiceImpl.validateNetworkAclRuleAction("Invalid");
+    }
+
+    @Test
+    public void validateNetworkAclRuleActionTestValidActions() {
+        networkAclServiceImpl.validateNetworkAclRuleAction("deny");
+        networkAclServiceImpl.validateNetworkAclRuleAction("allow");
+    }
+
+    @Test
+    public void validateNetworkACLItemTest() {
+        Mockito.doNothing().when(networkAclServiceImpl).validateSourceStartAndEndPorts(networkAclItemVoMock);
+        Mockito.doNothing().when(networkAclServiceImpl).validateSourceCidrList(networkAclItemVoMock);
+        Mockito.doNothing().when(networkAclServiceImpl).validateProtocol(networkAclItemVoMock);
+
+        networkAclServiceImpl.validateNetworkACLItem(networkAclItemVoMock);
+
+        InOrder inOrder = Mockito.inOrder(networkAclServiceImpl);
+        inOrder.verify(networkAclServiceImpl).validateSourceStartAndEndPorts(networkAclItemVoMock);
+        inOrder.verify(networkAclServiceImpl).validateSourceCidrList(networkAclItemVoMock);
+        inOrder.verify(networkAclServiceImpl).validateProtocol(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateSourceStartAndEndPortsTestBothPortsNull() {
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateSourceStartAndEndPortsTestStartPorInvalid() {
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(65536);
+
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateSourceStartAndEndPortsTestStartPorValidButEndPortInvalid() {
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(65535);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(65536);
+
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateSourceStartAndEndPortsTestStartPortBiggerThanEndPort() {
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(65535);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(2);
+
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateSourceStartAndEndPortsTestPortsWithAllProtocol() {
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(1);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(2);
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("all");
+
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateSourceStartAndEndPortsTestPortsWithTcpProtocol() {
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(1);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(2);
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("tcp");
+
+        networkAclServiceImpl.validateSourceStartAndEndPorts(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateSourceCidrListTestEmptySourceCirdList() {
+        Mockito.when(networkAclItemVoMock.getSourceCidrList()).thenReturn(new ArrayList<>());
+        networkAclServiceImpl.validateSourceCidrList(networkAclItemVoMock);
+    }
+
+    @Test(expected = ServerApiException.class)
+    public void validateSourceCidrListTestInvalidCidrs() {
+        ArrayList<String> cidrsInvalid = new ArrayList<>();
+        cidrsInvalid.add("256.0.0.0./32");
+
+        Mockito.when(networkAclItemVoMock.getSourceCidrList()).thenReturn(cidrsInvalid);
+        networkAclServiceImpl.validateSourceCidrList(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateSourceCidrListTestValidCidrs() {
+        ArrayList<String> cidrsInvalid = new ArrayList<>();
+        cidrsInvalid.add("192.168.12.0/24");
+
+        Mockito.when(networkAclItemVoMock.getSourceCidrList()).thenReturn(cidrsInvalid);
+        networkAclServiceImpl.validateSourceCidrList(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateProtocolTestProtocolIsNullOrBlank() {
+        Mockito.doNothing().when(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn(null);
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("    ");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateProtocolTestProtocolIsNumericValueLessThanZero() {
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("-1");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateProtocolTestProtocolIsNumericValueMoreThan255() {
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("256");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateProtocolTestProtocolIsNumericValidValue() {
+        Mockito.doNothing().when(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("255");
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(null);
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(null);
+
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.verify(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateProtocolTestProtocolIsStringInvalid() {
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("invalid");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateProtocolTestProtocolIsStringValid() {
+        Mockito.doNothing().when(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(null);
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(null);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("tcp");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("all");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("udp");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.verify(networkAclServiceImpl, Mockito.times(3)).validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateProtocolTestProtocolNotIcmpWithIcmpConfigurations() {
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(1);
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(1);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("tcp");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateProtocolTestProtocolNotIcmpWithSourcePorts() {
+        Mockito.doNothing().when(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(null);
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(null);
+
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(1);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(1);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("tcp");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.verify(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateProtocolTestProtocolIcmpWithIcmpConfigurations() {
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(1);
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(1);
+
+        Mockito.when(networkAclItemVoMock.getSourcePortStart()).thenReturn(null);
+        Mockito.when(networkAclItemVoMock.getSourcePortEnd()).thenReturn(null);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+
+        Mockito.when(networkAclItemVoMock.getProtocol()).thenReturn("icmp");
+        networkAclServiceImpl.validateProtocol(networkAclItemVoMock);
+
+        Mockito.verify(networkAclServiceImpl).validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateIcmpTypeAndCodeTestIcmpTypeNull() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(null);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateIcmpTypeAndCodeTestIcmpTypeInvalid() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(256);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateIcmpTypeAndCodeTestIcmpTypeNegativeOne() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(-1);
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(null);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateIcmpTypeAndCodeTestIcmpTypeNegativeOneAndIcmpCodeNegativeOne() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(-1);
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(-1);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateIcmpTypeAndCodeTestIcmpTypeValidAndIcmpCodeInvalid() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(255);
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(16);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void validateIcmpTypeAndCodeTestIcmpTypeValidAndIcmpCodeValid() {
+        Mockito.when(networkAclItemVoMock.getIcmpType()).thenReturn(255);
+        Mockito.when(networkAclItemVoMock.getIcmpCode()).thenReturn(1);
+
+        networkAclServiceImpl.validateIcmpTypeAndCode(networkAclItemVoMock);
+    }
+
+    @Test
+    public void updateNetworkACLItemTest() throws ResourceUnavailableException {
+        Mockito.when(networkAclItemVoMock.getAclId()).thenReturn(networkAclMockId);
+        Mockito.doReturn(networkAclItemVoMock).when(networkAclServiceImpl).validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
+        Mockito.doReturn(networkAclMock).when(networkAclManagerMock).getNetworkACL(networkAclMockId);
+        Mockito.doNothing().when(networkAclServiceImpl).validateNetworkAcl(Mockito.eq(networkAclMock));
+        Mockito.doNothing().when(networkAclServiceImpl).transferDataToNetworkAclRulePojo(Mockito.eq(updateNetworkACLItemCmdMock), Mockito.eq(networkAclItemVoMock), Mockito.eq(networkAclMock));
+        Mockito.doNothing().when(networkAclServiceImpl).validateNetworkACLItem(networkAclItemVoMock);
+        Mockito.doReturn(networkAclItemVoMock).when(networkAclManagerMock).updateNetworkACLItem(networkAclItemVoMock);
+
+        networkAclServiceImpl.updateNetworkACLItem(updateNetworkACLItemCmdMock);
+
+        InOrder inOrder = Mockito.inOrder(networkAclServiceImpl, networkAclManagerMock);
+        inOrder.verify(networkAclServiceImpl).validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
+        inOrder.verify(networkAclManagerMock).getNetworkACL(networkAclMockId);
+        inOrder.verify(networkAclServiceImpl).validateNetworkAcl(networkAclMock);
+        inOrder.verify(networkAclServiceImpl).transferDataToNetworkAclRulePojo(Mockito.eq(updateNetworkACLItemCmdMock), Mockito.eq(networkAclItemVoMock), Mockito.eq(networkAclMock));
+        inOrder.verify(networkAclServiceImpl).validateNetworkACLItem(networkAclItemVoMock);
+        inOrder.verify(networkAclManagerMock).updateNetworkACLItem(networkAclItemVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateNetworkAclRuleIdAndRetrieveItTestNetworkAclNotFound() {
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findById(Mockito.anyLong());
+
+        networkAclServiceImpl.validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
+    }
+
+    @Test
+    public void validateNetworkAclRuleIdAndRetrieveItTestNetworkAclFound() {
+        Mockito.doReturn(networkAclItemVoMock).when(networkAclItemDaoMock).findById(Mockito.anyLong());
+
+        NetworkACLItemVO returnedNetworkAclItemVo = networkAclServiceImpl.validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
+
+        Assert.assertNotEquals(networkAclItemVoMock, returnedNetworkAclItemVo);
+        Mockito.verify(networkAclItemVoMock).clone();
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void transferDataToNetworkAclRulePojoTestNumberOfAcltoBeUpdatedAlreadyInUse() {
+        int aclNumberToUpdate = 1;
+        Mockito.when(updateNetworkACLItemCmdMock.getNumber()).thenReturn(aclNumberToUpdate);
+        Mockito.when(networkAclMock.getId()).thenReturn(networkAclMockId);
+        Mockito.when(networkAclItemVoMock.getId()).thenReturn(100L);
+        NetworkACLItemVO otherNetworkAclItemVoMock = Mockito.mock(NetworkACLItemVO.class);
+        Mockito.when(otherNetworkAclItemVoMock.getId()).thenReturn(101L);
+        Mockito.doReturn(otherNetworkAclItemVoMock).when(networkAclItemDaoMock).findByAclAndNumber(networkAclMockId, aclNumberToUpdate);
+
+        networkAclServiceImpl.transferDataToNetworkAclRulePojo(updateNetworkACLItemCmdMock, networkAclItemVoMock, networkAclMock);
+    }
+
+    @Test
+    public void transferDataToNetworkAclRulePojoTestPartialUpgradeAllValuesNull() {
+        Mockito.when(updateNetworkACLItemCmdMock.isPartialUpgrade()).thenReturn(true);
+        Mockito.when(updateNetworkACLItemCmdMock.getNumber()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortStart()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortEnd()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourceCidrList()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getProtocol()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpCode()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpType()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getAction()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getTrafficType()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getCustomId()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getReason()).thenReturn(null);
+
+        Mockito.when(updateNetworkACLItemCmdMock.isDisplay()).thenReturn(false);
+        Mockito.when(networkAclItemVoMock.isDisplay()).thenReturn(false);
+
+        networkAclServiceImpl.transferDataToNetworkAclRulePojo(updateNetworkACLItemCmdMock, networkAclItemVoMock, networkAclMock);
+
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setNumber(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setSourcePortStart(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setSourcePortEnd(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setSourceCidrList(Mockito.anyListOf(String.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setProtocol(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setIcmpCode(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setIcmpType(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setAction(Mockito.any(Action.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setTrafficType(Mockito.any(TrafficType.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setUuid(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setReason(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setDisplay(Mockito.anyBoolean());
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).validateAndCreateNetworkAclRuleAction(Mockito.anyString());
+    }
+
+    @Test
+    public void transferDataToNetworkAclRulePojoTestNotPartialUpgradeAllValuesNull() {
+        Mockito.when(updateNetworkACLItemCmdMock.isPartialUpgrade()).thenReturn(false);
+
+        Mockito.when(updateNetworkACLItemCmdMock.getNumber()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortStart()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortEnd()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourceCidrList()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getProtocol()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpCode()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpType()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getAction()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getTrafficType()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getCustomId()).thenReturn(null);
+        Mockito.when(updateNetworkACLItemCmdMock.getReason()).thenReturn(null);
+
+        Mockito.when(updateNetworkACLItemCmdMock.isDisplay()).thenReturn(false);
+        Mockito.when(networkAclItemVoMock.isDisplay()).thenReturn(false);
+
+        networkAclServiceImpl.transferDataToNetworkAclRulePojo(updateNetworkACLItemCmdMock, networkAclItemVoMock, networkAclMock);
+
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setNumber(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setSourcePortStart(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setSourcePortEnd(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setSourceCidrList(Mockito.anyListOf(String.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setProtocol(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setIcmpCode(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setIcmpType(Mockito.anyInt());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setAction(Mockito.any(Action.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setTrafficType(Mockito.any(TrafficType.class));
+        Mockito.verify(networkAclItemVoMock, Mockito.times(0)).setUuid(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setReason(Mockito.anyString());
+        Mockito.verify(networkAclItemVoMock, Mockito.times(1)).setDisplay(Mockito.anyBoolean());
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).validateAndCreateNetworkAclRuleAction(Mockito.anyString());
+    }
+
+    @Test
+    public void transferDataToNetworkAclRulePojoTestAllValuesWithUpdateData() {
+        Mockito.when(updateNetworkACLItemCmdMock.getNumber()).thenReturn(1);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortStart()).thenReturn(23);
+        Mockito.when(updateNetworkACLItemCmdMock.getSourcePortEnd()).thenReturn(24);
+
+        ArrayList<String> cidrsList = new ArrayList<>();
+        cidrsList.add("192.168.6.0/24");
+        Mockito.when(updateNetworkACLItemCmdMock.getSourceCidrList()).thenReturn(cidrsList);
+
+        Mockito.when(updateNetworkACLItemCmdMock.getProtocol()).thenReturn("all");
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpCode()).thenReturn(5);
+        Mockito.when(updateNetworkACLItemCmdMock.getIcmpType()).thenReturn(6);
+        Mockito.when(updateNetworkACLItemCmdMock.getAction()).thenReturn("deny");
+        Mockito.when(updateNetworkACLItemCmdMock.getTrafficType()).thenReturn(TrafficType.Egress);
+        Mockito.when(updateNetworkACLItemCmdMock.getCustomId()).thenReturn("customUuid");
+        Mockito.when(updateNetworkACLItemCmdMock.getReason()).thenReturn("reason");
+
+        Mockito.when(updateNetworkACLItemCmdMock.isDisplay()).thenReturn(true);
+        Mockito.when(networkAclItemVoMock.isDisplay()).thenReturn(false);
+
+        networkAclServiceImpl.transferDataToNetworkAclRulePojo(updateNetworkACLItemCmdMock, networkAclItemVoMock, networkAclMock);
+
+        Mockito.verify(networkAclItemVoMock).setNumber(1);
+        Mockito.verify(networkAclItemVoMock).setSourcePortStart(23);
+        Mockito.verify(networkAclItemVoMock).setSourcePortEnd(24);
+        Mockito.verify(networkAclItemVoMock).setSourceCidrList(cidrsList);
+        Mockito.verify(networkAclItemVoMock).setProtocol("all");
+        Mockito.verify(networkAclItemVoMock).setIcmpCode(5);
+        Mockito.verify(networkAclItemVoMock).setIcmpType(6);
+        Mockito.verify(networkAclItemVoMock).setAction(Action.Deny);
+        Mockito.verify(networkAclItemVoMock).setTrafficType(TrafficType.Egress);
+        Mockito.verify(networkAclItemVoMock).setUuid("customUuid");
+        Mockito.verify(networkAclItemVoMock).setReason("reason");
+        Mockito.verify(networkAclItemVoMock).setDisplay(true);
+        Mockito.verify(networkAclServiceImpl).validateAndCreateNetworkAclRuleAction("deny");
+    }
+
+    @Test
+    @PrepareForTest(CallContext.class)
+    public void updateNetworkACLTestParametersNotNull() {
+        String name = "name";
+        String description = "desc";
+        String customId = "customId";
+
+        Mockito.when(updateNetworkACLListCmdMock.getName()).thenReturn(name);
+        Mockito.when(updateNetworkACLListCmdMock.getDescription()).thenReturn(description);
+        Mockito.when(updateNetworkACLListCmdMock.getCustomId()).thenReturn(customId);
+        Mockito.when(updateNetworkACLListCmdMock.getId()).thenReturn(networkAclListId);
+        Mockito.when(updateNetworkACLListCmdMock.getDisplay()).thenReturn(false);
+
+        networkAclServiceImpl.updateNetworkACL(updateNetworkACLListCmdMock);
+
+        InOrder inOrder = Mockito.inOrder(networkAclDaoMock, entityManagerMock, entityManagerMock, accountManagerMock, networkACLVOMock);
+
+        inOrder.verify(networkAclDaoMock).findById(networkAclListId);
+        inOrder.verify(entityManagerMock).findById(Mockito.eq(Vpc.class), Mockito.anyLong());
+        inOrder.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+
+        inOrder.verify(networkACLVOMock).setName(name);
+        inOrder.verify(networkACLVOMock).setDescription(description);
+        inOrder.verify(networkACLVOMock).setUuid(customId);
+        inOrder.verify(networkACLVOMock).setDisplay(false);
+
+        inOrder.verify(networkAclDaoMock).update(networkAclListId, networkACLVOMock);
+        inOrder.verify(networkAclDaoMock).findById(networkAclListId);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void moveNetworkAclRuleToNewPositionTestBothPreviousAndNextAclRuleIdsNull() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(null, null);
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void moveNetworkAclRuleToNewPositionTestBothPreviousAndNextAclRuleIdsEmpty() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand("", "");
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void moveNetworkAclRuleToNewPositionTestBothPreviousAndNextAclRuleIdsBlank() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand("     ", "         ");
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+    }
+
+    private void configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(String nextAclRuleUuid, String previousAclRuleUuid) {
+        Mockito.when(moveNetworkAclItemCmdMock.getNextAclRuleUuid()).thenReturn(nextAclRuleUuid);
+        Mockito.when(moveNetworkAclItemCmdMock.getPreviousAclRuleUuid()).thenReturn(previousAclRuleUuid);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void moveNetworkAclRuleToNewPositionTestAclRuleBeingMovedNotFound() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(nextAclRuleUuid, previousAclRuleUuid);
+
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findByUuid(uuidAclRuleBeingMoved);
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+    }
+
+    @Test
+    public void moveNetworkAclRuleToNewPositionTestMoveRuleToTop() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(nextAclRuleUuid, previousAclRuleUuid);
+
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findByUuid(uuidAclRuleBeingMoved);
+
+        Mockito.doReturn(null).when(networkAclServiceImpl).retrieveAndValidateAclRule(previousAclRuleUuid);
+        Mockito.doReturn(nextAclRuleMock).when(networkAclServiceImpl).retrieveAndValidateAclRule(nextAclRuleUuid);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateMoveAclRulesData(aclRuleBeingMovedMock, null, nextAclRuleMock);
+
+        configureMoveMethodsToDoNothing();
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).moveRuleToTheTop(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleToTheBottom(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleBetweenAclRules(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class), Mockito.eq(previousAclRuleMock),
+                Mockito.eq(nextAclRuleMock));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).validateAclConsistency(Mockito.any(MoveNetworkAclItemCmd.class), Mockito.any(NetworkACLVO.class),
+                Mockito.anyListOf(NetworkACLItemVO.class));
+    }
+
+    @Test
+    public void moveNetworkAclRuleToNewPositionTestMoveRuleToBottom() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(nextAclRuleUuid, previousAclRuleUuid);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateMoveAclRulesData(aclRuleBeingMovedMock, previousAclRuleMock, null);
+
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findByUuid(uuidAclRuleBeingMoved);
+
+        Mockito.doReturn(previousAclRuleMock).when(networkAclServiceImpl).retrieveAndValidateAclRule(previousAclRuleUuid);
+        Mockito.doReturn(null).when(networkAclServiceImpl).retrieveAndValidateAclRule(nextAclRuleUuid);
+
+        configureMoveMethodsToDoNothing();
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleToTheTop(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).moveRuleToTheBottom(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleBetweenAclRules(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class), Mockito.eq(previousAclRuleMock),
+                Mockito.eq(nextAclRuleMock));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).validateAclConsistency(Mockito.any(MoveNetworkAclItemCmd.class), Mockito.any(NetworkACLVO.class),
+                Mockito.anyListOf(NetworkACLItemVO.class));
+    }
+
+    @Test
+    public void moveNetworkAclRuleToNewPositionTestMoveBetweenAclRules() {
+        configureNextAndPreviousAclRuleUuidsForMoveAclRuleCommand(nextAclRuleUuid, previousAclRuleUuid);
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateMoveAclRulesData(aclRuleBeingMovedMock, previousAclRuleMock, nextAclRuleMock);
+
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findByUuid(uuidAclRuleBeingMoved);
+
+        Mockito.doReturn(previousAclRuleMock).when(networkAclServiceImpl).retrieveAndValidateAclRule(previousAclRuleUuid);
+        Mockito.doReturn(nextAclRuleMock).when(networkAclServiceImpl).retrieveAndValidateAclRule(nextAclRuleUuid);
+
+        configureMoveMethodsToDoNothing();
+
+        networkAclServiceImpl.moveNetworkAclRuleToNewPosition(moveNetworkAclItemCmdMock);
+
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleToTheTop(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).moveRuleToTheBottom(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).moveRuleBetweenAclRules(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class), Mockito.eq(previousAclRuleMock),
+                Mockito.eq(nextAclRuleMock));
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).validateAclConsistency(Mockito.any(MoveNetworkAclItemCmd.class), Mockito.any(NetworkACLVO.class),
+                Mockito.anyListOf(NetworkACLItemVO.class));
+    }
+
+    private void configureMoveMethodsToDoNothing() {
+        Mockito.doReturn(networkACLVOMock).when(networkAclDaoMock).acquireInLockTable(Mockito.anyLong());
+        Mockito.doReturn(true).when(networkAclDaoMock).releaseFromLockTable(Mockito.anyLong());
+
+        Mockito.doNothing().when(networkAclServiceImpl).validateAclConsistency(Mockito.any(MoveNetworkAclItemCmd.class), Mockito.any(NetworkACLVO.class), Mockito.anyListOf(NetworkACLItemVO.class));
+
+        Mockito.doReturn(new ArrayList<>()).when(networkAclServiceImpl).getAllAclRulesSortedByNumber(networkAclMockId);
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).moveRuleToTheTop(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).moveRuleToTheBottom(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class));
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).moveRuleBetweenAclRules(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyListOf(NetworkACLItemVO.class),
+                Mockito.eq(previousAclRuleMock), Mockito.eq(nextAclRuleMock));
+    }
+
+    @Test
+    public void retrieveAndValidateAclRuleTestUuidNull() {
+        NetworkACLItemVO networkACLItemVOReceived = networkAclServiceImpl.retrieveAndValidateAclRule(null);
+
+        Assert.assertNull(networkACLItemVOReceived);
+    }
+
+    @Test
+    public void retrieveAndValidateAclRuleTestUuidEmpty() {
+        NetworkACLItemVO networkACLItemVOReceived = networkAclServiceImpl.retrieveAndValidateAclRule(StringUtils.EMPTY);
+
+        Assert.assertNull(networkACLItemVOReceived);
+    }
+
+    @Test
+    public void retrieveAndValidateAclRuleTestUuidBlank() {
+        NetworkACLItemVO networkACLItemVOReceived = networkAclServiceImpl.retrieveAndValidateAclRule("        ");
+
+        Assert.assertNull(networkACLItemVOReceived);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateAclRuleTestAclRuleNotFound() {
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findByUuid(nextAclRuleUuid);
+
+        networkAclServiceImpl.retrieveAndValidateAclRule(nextAclRuleUuid);
+    }
+
+    @Test
+    public void retrieveAndValidateAclRuleTestAclRuleFound() {
+        Mockito.doReturn(nextAclRuleMock).when(networkAclItemDaoMock).findByUuid(nextAclRuleUuid);
+
+        NetworkACLItemVO networkACLItemVOReceived = networkAclServiceImpl.retrieveAndValidateAclRule(nextAclRuleUuid);
+
+        Assert.assertEquals(nextAclRuleMock, networkACLItemVOReceived);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateMoveAclRulesDataTestInvalidPreviousAndNextAclRules() {
+        networkAclServiceImpl.validateMoveAclRulesData(aclRuleBeingMovedMock, null, null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateMoveAclRulesDataTestPreviousRuleWithDifferentAclId() {
+        Mockito.when(previousAclRuleMock.getAclId()).thenReturn(99L);
+
+        networkAclServiceImpl.validateMoveAclRulesData(aclRuleBeingMovedMock, previousAclRuleMock, null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateMoveAclRulesDataTestNextRuleWithDifferentAclId() {
+        Mockito.when(nextAclRuleMock.getAclId()).thenReturn(99L);
+
+        networkAclServiceImpl.validateMoveAclRulesData(aclRuleBeingMovedMock, null, nextAclRuleMock);
+    }
+
+    @Test
+    @PrepareForTest(CallContext.class)
+    public void updateNetworkACLTestParametersWithNullValues() {
+        Mockito.when(updateNetworkACLListCmdMock.getName()).thenReturn(null);
+        Mockito.when(updateNetworkACLListCmdMock.getDescription()).thenReturn(null);
+        Mockito.when(updateNetworkACLListCmdMock.getCustomId()).thenReturn(null);
+        Mockito.when(updateNetworkACLListCmdMock.getId()).thenReturn(networkAclListId);
+        Mockito.when(updateNetworkACLListCmdMock.getDisplay()).thenReturn(null);
+
+        networkAclServiceImpl.updateNetworkACL(updateNetworkACLListCmdMock);
+
+        InOrder inOrder = Mockito.inOrder(networkAclDaoMock, entityManagerMock, entityManagerMock, accountManagerMock, networkACLVOMock);
+
+        inOrder.verify(networkAclDaoMock).findById(networkAclListId);
+        inOrder.verify(entityManagerMock).findById(Mockito.eq(Vpc.class), Mockito.anyLong());
+        inOrder.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+
+        Mockito.verify(networkACLVOMock, Mockito.times(0)).setName(null);
+        inOrder.verify(networkACLVOMock, Mockito.times(0)).setDescription(null);
+        inOrder.verify(networkACLVOMock, Mockito.times(0)).setUuid(null);
+        inOrder.verify(networkACLVOMock, Mockito.times(0)).setDisplay(false);
+
+        inOrder.verify(networkAclDaoMock).update(networkAclListId, networkACLVOMock);
+        inOrder.verify(networkAclDaoMock).findById(networkAclListId);
+    }
+
+    @Test
+    public void validateMoveAclRulesDataTestSuccesfullExecution() {
+        Mockito.when(nextAclRuleMock.getAclId()).thenReturn(networkAclMockId);
+        Mockito.when(previousAclRuleMock.getAclId()).thenReturn(networkAclMockId);
+
+        Mockito.doReturn(networkAclMock).when(networkAclDaoMock).findById(networkAclMockId);
+        Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+
+        CallContext callContextMock = Mockito.mock(CallContext.class);
+        Mockito.doReturn(Mockito.mock(Account.class)).when(callContextMock).getCallingAccount();
+
+        PowerMockito.mockStatic(CallContext.class);
+        PowerMockito.when(CallContext.current()).thenReturn(callContextMock);
+
+        Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+
+        networkAclServiceImpl.validateMoveAclRulesData(aclRuleBeingMovedMock, previousAclRuleMock, nextAclRuleMock);
+
+        Mockito.verify(networkAclDaoMock).findById(networkAclMockId);
+        Mockito.verify(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
+        Mockito.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
+    }
+
+    @Test
+    public void getAllAclRulesSortedByNumberTest() {
+        List<NetworkACLItemVO> networkAclItemVos = new ArrayList<>();
+
+        NetworkACLItemVO networkACLItemVO1 = new NetworkACLItemVO();
+        networkACLItemVO1.setNumber(1);
+
+        NetworkACLItemVO networkACLItemVO2 = new NetworkACLItemVO();
+        networkACLItemVO2.setNumber(2);
+
+        NetworkACLItemVO networkACLItemVO3 = new NetworkACLItemVO();
+        networkACLItemVO3.setNumber(3);
+
+        NetworkACLItemVO networkACLItemVO4 = new NetworkACLItemVO();
+        networkACLItemVO4.setNumber(4);
+
+        networkAclItemVos.add(networkACLItemVO1);
+        networkAclItemVos.add(networkACLItemVO2);
+        networkAclItemVos.add(networkACLItemVO3);
+        networkAclItemVos.add(networkACLItemVO4);
+
+        Collections.shuffle(networkAclItemVos);
+
+        Mockito.doReturn(networkAclItemVos).when(networkAclItemDaoMock).listByACL(networkAclMockId);
+
+        List<NetworkACLItemVO> allAclRulesSortedByNumber = networkAclServiceImpl.getAllAclRulesSortedByNumber(networkAclMockId);
+
+        Assert.assertEquals(networkAclItemVos.size(), allAclRulesSortedByNumber.size());
+        Assert.assertEquals(networkACLItemVO1, networkAclItemVos.get(0));
+        Assert.assertEquals(networkACLItemVO2, networkAclItemVos.get(1));
+        Assert.assertEquals(networkACLItemVO3, networkAclItemVos.get(2));
+        Assert.assertEquals(networkACLItemVO4, networkAclItemVos.get(3));
+
+    }
+
+    @Test
+    public void moveRuleToTheTopTest() {
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.eq(aclRuleBeingMovedMock), Mockito.anyInt(),
+                Mockito.anyListOf(NetworkACLItemVO.class), Mockito.anyInt());
+
+        networkAclServiceImpl.moveRuleToTheTop(aclRuleBeingMovedMock, new ArrayList<>());
+
+        Mockito.verify(networkAclServiceImpl).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.eq(aclRuleBeingMovedMock), Mockito.eq(1), Mockito.anyListOf(NetworkACLItemVO.class),
+                Mockito.eq(0));
+    }
+
+    @Test
+    public void moveRuleToTheBottomTest() {
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+
+        NetworkACLItemVO networkACLItemVO1 = new NetworkACLItemVO();
+        networkACLItemVO1.setNumber(100);
+
+        allAclRules.add(networkACLItemVO1);
+        Mockito.when(aclRuleBeingMovedMock.getId()).thenReturn(99l);
+
+        Mockito.doNothing().when(networkAclItemDaoMock).updateNumberFieldNetworkItem(Mockito.anyLong(), Mockito.anyInt());
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findById(99l);
+
+        networkAclServiceImpl.moveRuleToTheBottom(aclRuleBeingMovedMock, allAclRules);
+
+        Mockito.verify(aclRuleBeingMovedMock).setNumber(101);
+        Mockito.verify(networkAclItemDaoMock).updateNumberFieldNetworkItem(99l, 101);
+        Mockito.verify(networkAclItemDaoMock).findById(99l);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void moveRuleBetweenAclRulesTestThereIsSpaceBetweenPreviousRuleAndNextRuleToAccomodateTheNewRuleWithOtherruleColliding() {
+        Mockito.when(previousAclRuleMock.getNumber()).thenReturn(10);
+        Mockito.when(nextAclRuleMock.getNumber()).thenReturn(15);
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        NetworkACLItemVO networkACLItemVO1 = new NetworkACLItemVO();
+        networkACLItemVO1.setNumber(11);
+
+        allAclRules.add(previousAclRuleMock);
+        allAclRules.add(networkACLItemVO1);
+        allAclRules.add(nextAclRuleMock);
+
+        networkAclServiceImpl.moveRuleBetweenAclRules(aclRuleBeingMovedMock, allAclRules, previousAclRuleMock, nextAclRuleMock);
+    }
+
+    @Test
+    public void moveRuleBetweenAclRulesTestThereIsSpaceBetweenPreviousRuleAndNextRuleToAccomodateTheNewRule() {
+        Mockito.when(previousAclRuleMock.getNumber()).thenReturn(10);
+        Mockito.when(nextAclRuleMock.getNumber()).thenReturn(11);
+        Mockito.when(aclRuleBeingMovedMock.getNumber()).thenReturn(50);
+        Mockito.when(aclRuleBeingMovedMock.getId()).thenReturn(1l);
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        NetworkACLItemVO networkACLItemVO12 = new NetworkACLItemVO();
+        networkACLItemVO12.setNumber(12);
+        NetworkACLItemVO networkACLItemVO13 = new NetworkACLItemVO();
+        networkACLItemVO13.setNumber(13);
+        NetworkACLItemVO networkACLItemVO14 = new NetworkACLItemVO();
+        networkACLItemVO14.setNumber(14);
+
+        allAclRules.add(previousAclRuleMock);
+        allAclRules.add(nextAclRuleMock);
+        allAclRules.add(networkACLItemVO12);
+        allAclRules.add(networkACLItemVO13);
+        allAclRules.add(networkACLItemVO14);
+        allAclRules.add(aclRuleBeingMovedMock);
+
+        Mockito.doNothing().when(networkAclItemDaoMock).updateNumberFieldNetworkItem(Mockito.anyLong(), Mockito.anyInt());
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findById(1l);
+
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.any(NetworkACLItemVO.class), Mockito.anyInt(),
+                Mockito.anyListOf(NetworkACLItemVO.class), Mockito.anyInt());
+
+        networkAclServiceImpl.moveRuleBetweenAclRules(aclRuleBeingMovedMock, allAclRules, previousAclRuleMock, nextAclRuleMock);
+
+        Mockito.verify(networkAclItemDaoMock, times(0)).updateNumberFieldNetworkItem(aclRuleBeingMovedMock.getId(), 11);
+        Mockito.verify(networkAclItemDaoMock, times(0)).findById(1l);
+        Mockito.verify(networkAclServiceImpl, Mockito.times(1)).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.any(NetworkACLItemVO.class), Mockito.eq(11),
+                Mockito.anyListOf(NetworkACLItemVO.class), Mockito.eq(1));
+    }
+
+    @Test
+    public void moveRuleBetweenAclRulesTestThereIsNoSpaceBetweenPreviousRuleAndNextRuleToAccomodateTheNewRule() {
+        Mockito.when(previousAclRuleMock.getNumber()).thenReturn(10);
+        Mockito.when(nextAclRuleMock.getNumber()).thenReturn(15);
+        Mockito.when(aclRuleBeingMovedMock.getNumber()).thenReturn(50);
+        Mockito.when(aclRuleBeingMovedMock.getId()).thenReturn(1l);
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+
+        allAclRules.add(previousAclRuleMock);
+        allAclRules.add(nextAclRuleMock);
+        allAclRules.add(aclRuleBeingMovedMock);
+
+        Mockito.doNothing().when(networkAclItemDaoMock).updateNumberFieldNetworkItem(Mockito.anyLong(), Mockito.anyInt());
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclItemDaoMock).findById(1l);
+
+        Mockito.doReturn(aclRuleBeingMovedMock).when(networkAclServiceImpl).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.any(NetworkACLItemVO.class), Mockito.anyInt(),
+                Mockito.anyListOf(NetworkACLItemVO.class), Mockito.anyInt());
+
+        networkAclServiceImpl.moveRuleBetweenAclRules(aclRuleBeingMovedMock, allAclRules, previousAclRuleMock, nextAclRuleMock);
+
+        Mockito.verify(networkAclItemDaoMock).updateNumberFieldNetworkItem(aclRuleBeingMovedMock.getId(), 11);
+        Mockito.verify(networkAclItemDaoMock).findById(1l);
+        Mockito.verify(networkAclServiceImpl, Mockito.times(0)).updateAclRuleToNewPositionAndExecuteShiftIfNecessary(Mockito.any(NetworkACLItemVO.class), Mockito.anyInt(),
+                Mockito.anyListOf(NetworkACLItemVO.class), Mockito.anyInt());
+    }
+
+    @Test
+    public void updateAclRuleToNewPositionAndExecuteShiftIfNecessaryTest() {
+        Mockito.when(previousAclRuleMock.getNumber()).thenReturn(10);
+
+        Mockito.when(nextAclRuleMock.getNumber()).thenReturn(11);
+        Mockito.when(nextAclRuleMock.getId()).thenReturn(50l);
+
+        Mockito.when(aclRuleBeingMovedMock.getNumber()).thenReturn(50);
+        Mockito.when(aclRuleBeingMovedMock.getId()).thenReturn(1l);
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        NetworkACLItemVO networkACLItemVO12 = new NetworkACLItemVO();
+        networkACLItemVO12.setNumber(12);
+        networkACLItemVO12.id = 12;
+        NetworkACLItemVO networkACLItemVO13 = new NetworkACLItemVO();
+        networkACLItemVO13.id = 13;
+        networkACLItemVO13.setNumber(13);
+        NetworkACLItemVO networkACLItemVO14 = new NetworkACLItemVO();
+        networkACLItemVO14.setNumber(14);
+        networkACLItemVO14.id = 14;
+
+        allAclRules.add(previousAclRuleMock);
+        allAclRules.add(nextAclRuleMock);
+        allAclRules.add(networkACLItemVO12);
+        allAclRules.add(networkACLItemVO13);
+        allAclRules.add(networkACLItemVO14);
+        allAclRules.add(aclRuleBeingMovedMock);
+
+        Mockito.doNothing().when(networkAclItemDaoMock).updateNumberFieldNetworkItem(Mockito.anyLong(), Mockito.anyInt());
+        Mockito.doReturn(null).when(networkAclItemDaoMock).findById(Mockito.anyLong());
+
+        networkAclServiceImpl.updateAclRuleToNewPositionAndExecuteShiftIfNecessary(aclRuleBeingMovedMock, 11, allAclRules, 1);
+
+        Mockito.verify(aclRuleBeingMovedMock).setNumber(11);
+        Mockito.verify(nextAclRuleMock).setNumber(12);
+        Mockito.verify(networkAclItemDaoMock).updateNumberFieldNetworkItem(1l, 11);
+        Mockito.verify(networkAclItemDaoMock).updateNumberFieldNetworkItem(50l, 12);
+
+        Assert.assertEquals(13, networkACLItemVO12.getNumber());
+        Assert.assertEquals(14, networkACLItemVO13.getNumber());
+        Assert.assertEquals(15, networkACLItemVO14.getNumber());
+    }
+
+    @Test
+    public void validateAclConsistencyTestRuleListEmpty() {
+        networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, new ArrayList<>());
+
+        Mockito.verify(moveNetworkAclItemCmdMock, Mockito.times(0)).getAclConsistencyHash();
+    }
+
+    @Test
+    public void validateAclConsistencyTestRuleListNull() {
+        networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, null);
+
+        Mockito.verify(moveNetworkAclItemCmdMock, Mockito.times(0)).getAclConsistencyHash();
+    }
+
+    @Test
+    public void validateAclConsistencyTestAclConsistencyHashIsNull() {
+        Mockito.doReturn(null).when(moveNetworkAclItemCmdMock).getAclConsistencyHash();
+
+        validateAclConsistencyTestAclConsistencyHashBlank();
+    }
+
+    @Test
+    public void validateAclConsistencyTestAclConsistencyHashIsEmpty() {
+        Mockito.doReturn("").when(moveNetworkAclItemCmdMock).getAclConsistencyHash();
+
+        validateAclConsistencyTestAclConsistencyHashBlank();
+    }
+
+    @Test
+    public void validateAclConsistencyTestAclConsistencyHashIsBlank() {
+        Mockito.doReturn("            ").when(moveNetworkAclItemCmdMock).getAclConsistencyHash();
+
+        validateAclConsistencyTestAclConsistencyHashBlank();
+    }
+
+    private void validateAclConsistencyTestAclConsistencyHashBlank() {
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        allAclRules.add(networkAclItemVoMock);
+
+        networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, allAclRules);
+
+        Mockito.verify(moveNetworkAclItemCmdMock, Mockito.times(1)).getAclConsistencyHash();
+        Mockito.verify(callContextMock, Mockito.times(1)).getCallingAccount();
+        Mockito.verify(callContextMock, Mockito.times(1)).getCallingUser();
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAclConsistencyTestAclConsistencyHashIsNotEqualsToDatabaseHash() {
+        Mockito.doReturn("differentHash").when(moveNetworkAclItemCmdMock).getAclConsistencyHash();
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        allAclRules.add(networkAclItemVoMock);
+
+        networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, allAclRules);
+    }
+
+    @Test
+    public void validateAclConsistencyTest() {
+        Mockito.doReturn("eac527fe45c77232ef06d9c7eb8abd94").when(moveNetworkAclItemCmdMock).getAclConsistencyHash();
+
+        ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
+        allAclRules.add(networkAclItemVoMock);
+
+        Mockito.doReturn("someUuid").when(networkAclItemVoMock).getUuid();
+        networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, allAclRules);
+
+        Mockito.verify(moveNetworkAclItemCmdMock, Mockito.times(1)).getAclConsistencyHash();
+    }
+}
\ No newline at end of file
diff --git a/server/test/com/cloud/network/vpc/VpcManagerImplTest.java b/server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/network/vpc/VpcManagerImplTest.java
rename to server/src/test/java/com/cloud/network/vpc/VpcManagerImplTest.java
diff --git a/server/test/com/cloud/projects/MockProjectManagerImpl.java b/server/src/test/java/com/cloud/projects/MockProjectManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/projects/MockProjectManagerImpl.java
rename to server/src/test/java/com/cloud/projects/MockProjectManagerImpl.java
diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/resource/MockResourceManagerImpl.java
rename to server/src/test/java/com/cloud/resource/MockResourceManagerImpl.java
diff --git a/server/test/com/cloud/resource/ResourceManagerImplTest.java b/server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/resource/ResourceManagerImplTest.java
rename to server/src/test/java/com/cloud/resource/ResourceManagerImplTest.java
diff --git a/server/test/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java b/server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java
rename to server/src/test/java/com/cloud/resourcelimit/ResourceLimitManagerImplTest.java
diff --git a/server/test/com/cloud/server/ConfigurationServerImplTest.java b/server/src/test/java/com/cloud/server/ConfigurationServerImplTest.java
similarity index 100%
rename from server/test/com/cloud/server/ConfigurationServerImplTest.java
rename to server/src/test/java/com/cloud/server/ConfigurationServerImplTest.java
diff --git a/server/test/com/cloud/server/ManagementServerImplTest.java b/server/src/test/java/com/cloud/server/ManagementServerImplTest.java
similarity index 100%
rename from server/test/com/cloud/server/ManagementServerImplTest.java
rename to server/src/test/java/com/cloud/server/ManagementServerImplTest.java
diff --git a/server/src/test/java/com/cloud/server/StatsCollectorTest.java b/server/src/test/java/com/cloud/server/StatsCollectorTest.java
new file mode 100644
index 0000000..040d08d
--- /dev/null
+++ b/server/src/test/java/com/cloud/server/StatsCollectorTest.java
@@ -0,0 +1,227 @@
+//
+// 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.server;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBFactory;
+import org.influxdb.dto.BatchPoints;
+import org.influxdb.dto.BatchPoints.Builder;
+import org.influxdb.dto.Point;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import com.cloud.agent.api.VmDiskStatsEntry;
+import com.cloud.server.StatsCollector.ExternalStatsProtocol;
+import com.cloud.user.VmDiskStatisticsVO;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(DataProviderRunner.class)
+@PrepareForTest({InfluxDBFactory.class, BatchPoints.class})
+public class StatsCollectorTest {
+    private StatsCollector statsCollector = Mockito.spy(new StatsCollector());
+
+    private static final int GRAPHITE_DEFAULT_PORT = 2003;
+    private static final int INFLUXDB_DEFAULT_PORT = 8086;
+    private static final String HOST_ADDRESS = "192.168.16.10";
+    private static final String URL = String.format("http://%s:%s/", HOST_ADDRESS, INFLUXDB_DEFAULT_PORT);
+
+    private static final String DEFAULT_DATABASE_NAME = "cloudstack";
+
+    @Test
+    public void createInfluxDbConnectionTest() {
+        configureAndTestCreateInfluxDbConnection(true);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void createInfluxDbConnectionTestExpectException() {
+        configureAndTestCreateInfluxDbConnection(false);
+    }
+
+    private void configureAndTestCreateInfluxDbConnection(boolean databaseExists) {
+        statsCollector.externalStatsHost = HOST_ADDRESS;
+        statsCollector.externalStatsPort = INFLUXDB_DEFAULT_PORT;
+        InfluxDB influxDbConnection = Mockito.mock(InfluxDB.class);
+        Mockito.when(influxDbConnection.databaseExists(DEFAULT_DATABASE_NAME)).thenReturn(databaseExists);
+        PowerMockito.mockStatic(InfluxDBFactory.class);
+        PowerMockito.when(InfluxDBFactory.connect(URL)).thenReturn(influxDbConnection);
+
+        InfluxDB returnedConnection = statsCollector.createInfluxDbConnection();
+
+        Assert.assertEquals(influxDbConnection, returnedConnection);
+    }
+
+    @Test
+    public void writeBatchesTest() {
+        InfluxDB influxDbConnection = Mockito.mock(InfluxDB.class);
+        Mockito.doNothing().when(influxDbConnection).write(Mockito.any(Point.class));
+        Builder builder = Mockito.mock(Builder.class);
+        BatchPoints batchPoints = Mockito.mock(BatchPoints.class);
+        PowerMockito.mockStatic(BatchPoints.class);
+        PowerMockito.when(BatchPoints.database(DEFAULT_DATABASE_NAME)).thenReturn(builder);
+        Mockito.when(builder.build()).thenReturn(batchPoints);
+        Map<String, String> tagsToAdd = new HashMap<>();
+        tagsToAdd.put("hostId", "1");
+        Map<String, Object> fieldsToAdd = new HashMap<>();
+        fieldsToAdd.put("total_memory_kbs", 10000000);
+        Point point = Point.measurement("measure").tag(tagsToAdd).time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).fields(fieldsToAdd).build();
+        List<Point> points = new ArrayList<>();
+        points.add(point);
+        Mockito.when(batchPoints.point(point)).thenReturn(batchPoints);
+
+        statsCollector.writeBatches(influxDbConnection, DEFAULT_DATABASE_NAME, points);
+
+        Mockito.verify(influxDbConnection).write(batchPoints);
+    }
+
+    @Test
+    public void configureExternalStatsPortTestGraphitePort() throws URISyntaxException {
+        URI uri = new URI(HOST_ADDRESS);
+        statsCollector.externalStatsType = ExternalStatsProtocol.GRAPHITE;
+        int port = statsCollector.retrieveExternalStatsPortFromUri(uri);
+        Assert.assertEquals(GRAPHITE_DEFAULT_PORT, port);
+    }
+
+    @Test
+    public void configureExternalStatsPortTestInfluxdbPort() throws URISyntaxException {
+        URI uri = new URI(HOST_ADDRESS);
+        statsCollector.externalStatsType = ExternalStatsProtocol.INFLUXDB;
+        int port = statsCollector.retrieveExternalStatsPortFromUri(uri);
+        Assert.assertEquals(INFLUXDB_DEFAULT_PORT, port);
+    }
+
+    @Test(expected = URISyntaxException.class)
+    public void configureExternalStatsPortTestExpectException() throws URISyntaxException {
+        statsCollector.externalStatsType = ExternalStatsProtocol.NONE;
+        URI uri = new URI(HOST_ADDRESS);
+        statsCollector.retrieveExternalStatsPortFromUri(uri);
+    }
+
+    @Test
+    public void configureExternalStatsPortTestInfluxDbCustomizedPort() throws URISyntaxException {
+        statsCollector.externalStatsType = ExternalStatsProtocol.INFLUXDB;
+        URI uri = new URI("test://" + HOST_ADDRESS + ":1234");
+        int port = statsCollector.retrieveExternalStatsPortFromUri(uri);
+        Assert.assertEquals(1234, port);
+    }
+
+    @Test
+    public void configureDatabaseNameTestDefaultDbName() throws URISyntaxException {
+        URI uri = new URI(URL);
+        String dbName = statsCollector.configureDatabaseName(uri);
+        Assert.assertEquals(DEFAULT_DATABASE_NAME, dbName);
+    }
+
+    @Test
+    public void configureDatabaseNameTestCustomDbName() throws URISyntaxException {
+        String configuredDbName = "dbName";
+        URI uri = new URI(URL + configuredDbName);
+        String dbName = statsCollector.configureDatabaseName(uri);
+        Assert.assertEquals(configuredDbName, dbName);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestNull() {
+        VmDiskStatisticsVO currentVmDiskStatisticsVO = new VmDiskStatisticsVO(1l, 1l, 1l, 1l);
+        boolean result = statsCollector.isCurrentVmDiskStatsDifferentFromPrevious(null, currentVmDiskStatisticsVO);
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestBothNull() {
+        boolean result = statsCollector.isCurrentVmDiskStatsDifferentFromPrevious(null, null);
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestDifferentIoWrite() {
+        configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(123l, 123l, 123l, 12l, true);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestDifferentIoRead() {
+        configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(123l, 123l, 12l, 123l, true);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestDifferentBytesRead() {
+        configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(12l, 123l, 123l, 123l, true);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestDifferentBytesWrite() {
+        configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(123l, 12l, 123l, 123l, true);
+    }
+
+    @Test
+    public void isCurrentVmDiskStatsDifferentFromPreviousTestAllEqual() {
+        configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(123l, 123l, 123l, 123l, false);
+    }
+
+    private void configureAndTestisCurrentVmDiskStatsDifferentFromPrevious(long bytesRead, long bytesWrite, long ioRead, long ioWrite, boolean expectedResult) {
+        VmDiskStatisticsVO previousVmDiskStatisticsVO = new VmDiskStatisticsVO(1l, 1l, 1l, 1l);
+        previousVmDiskStatisticsVO.setCurrentBytesRead(123l);
+        previousVmDiskStatisticsVO.setCurrentBytesWrite(123l);
+        previousVmDiskStatisticsVO.setCurrentIORead(123l);
+        previousVmDiskStatisticsVO.setCurrentIOWrite(123l);
+
+        VmDiskStatisticsVO currentVmDiskStatisticsVO = new VmDiskStatisticsVO(1l, 1l, 1l, 1l);
+        currentVmDiskStatisticsVO.setCurrentBytesRead(bytesRead);
+        currentVmDiskStatisticsVO.setCurrentBytesWrite(bytesWrite);
+        currentVmDiskStatisticsVO.setCurrentIORead(ioRead);
+        currentVmDiskStatisticsVO.setCurrentIOWrite(ioWrite);
+
+        boolean result = statsCollector.isCurrentVmDiskStatsDifferentFromPrevious(previousVmDiskStatisticsVO, currentVmDiskStatisticsVO);
+        Assert.assertEquals(expectedResult, result);
+    }
+
+    @Test
+    @DataProvider({
+        "0,0,0,0,true", "1,0,0,0,false", "0,1,0,0,false", "0,0,1,0,false",
+        "0,0,0,1,false", "1,0,0,1,false", "1,0,1,0,false", "1,1,0,0,false",
+        "0,1,1,0,false", "0,1,0,1,false", "0,0,1,1,false", "0,1,1,1,false",
+        "1,1,0,1,false", "1,0,1,1,false", "1,1,1,0,false", "1,1,1,1,false",
+    })
+    public void configureAndTestCheckIfDiskStatsAreZero(long bytesRead, long bytesWrite, long ioRead, long ioWrite, boolean expected) {
+        VmDiskStatsEntry vmDiskStatsEntry = new VmDiskStatsEntry();
+        vmDiskStatsEntry.setBytesRead(bytesRead);
+        vmDiskStatsEntry.setBytesWrite(bytesWrite);
+        vmDiskStatsEntry.setIORead(ioRead);
+        vmDiskStatsEntry.setIOWrite(ioWrite);
+
+        boolean result = statsCollector.areAllDiskStatsZero(vmDiskStatsEntry);
+        Assert.assertEquals(expected, result);
+    }
+}
diff --git a/server/test/com/cloud/servlet/ConsoleProxyServletTest.java b/server/src/test/java/com/cloud/servlet/ConsoleProxyServletTest.java
similarity index 100%
rename from server/test/com/cloud/servlet/ConsoleProxyServletTest.java
rename to server/src/test/java/com/cloud/servlet/ConsoleProxyServletTest.java
diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTest.java b/server/src/test/java/com/cloud/snapshot/SnapshotDaoTest.java
similarity index 100%
rename from server/test/com/cloud/snapshot/SnapshotDaoTest.java
rename to server/src/test/java/com/cloud/snapshot/SnapshotDaoTest.java
diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java b/server/src/test/java/com/cloud/snapshot/SnapshotDaoTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/snapshot/SnapshotDaoTestConfiguration.java
rename to server/src/test/java/com/cloud/snapshot/SnapshotDaoTestConfiguration.java
diff --git a/server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java b/server/src/test/java/com/cloud/storage/ImageStoreDetailsUtilTest.java
similarity index 100%
rename from server/test/com/cloud/storage/ImageStoreDetailsUtilTest.java
rename to server/src/test/java/com/cloud/storage/ImageStoreDetailsUtilTest.java
diff --git a/server/src/test/java/com/cloud/storage/StorageManagerImplTest.java b/server/src/test/java/com/cloud/storage/StorageManagerImplTest.java
new file mode 100644
index 0000000..dc79ac5
--- /dev/null
+++ b/server/src/test/java/com/cloud/storage/StorageManagerImplTest.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.host.Host;
+
+@RunWith(MockitoJUnitRunner.class)
+public class StorageManagerImplTest {
+
+    @Spy
+    private StorageManagerImpl storageManagerImpl;
+
+    @Test
+    public void createLocalStoragePoolName() {
+        String hostMockName = "host1";
+        executeCreateLocalStoragePoolNameForHostName(hostMockName);
+    }
+
+    @Test
+    public void createLocalStoragePoolNameUsingHostNameWithSpaces() {
+        String hostMockName = "      hostNameWithSpaces      ";
+        executeCreateLocalStoragePoolNameForHostName(hostMockName);
+    }
+
+    private void executeCreateLocalStoragePoolNameForHostName(String hostMockName) {
+        String firstBlockUuid = "dsdsh665";
+
+        String expectedLocalStorageName = hostMockName.trim() + "-local-" + firstBlockUuid;
+
+        Host hostMock = Mockito.mock(Host.class);
+        StoragePoolInfo storagePoolInfoMock = Mockito.mock(StoragePoolInfo.class);
+
+        Mockito.when(hostMock.getName()).thenReturn(hostMockName);
+        Mockito.when(storagePoolInfoMock.getUuid()).thenReturn(firstBlockUuid + "-213151-df21ef333d-2d33f1");
+
+        String localStoragePoolName = storageManagerImpl.createLocalStoragePoolName(hostMock, storagePoolInfoMock);
+        Assert.assertEquals(expectedLocalStorageName, localStoragePoolName);
+    }
+}
diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
new file mode 100644
index 0000000..693b437
--- /dev/null
+++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java
@@ -0,0 +1,1089 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
+import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
+import org.apache.cloudstack.framework.async.AsyncCallFuture;
+import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.configuration.Resource;
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.org.Grouping;
+import com.cloud.serializer.GsonHelper;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.vm.UserVmManager;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VolumeApiServiceImplTest {
+
+    @Spy
+    @InjectMocks
+    private VolumeApiServiceImpl volumeApiServiceImpl;
+    @Mock
+    private SnapshotManager snapshotManagerMock;
+    @Mock
+    private VolumeDataStoreDao volumeDataStoreDaoMock;
+    @Mock
+    private VolumeDao volumeDaoMock;
+    @Mock
+    private AccountManager accountManagerMock;
+    @Mock
+    private UserVmDao userVmDaoMock;
+    @Mock
+    private PrimaryDataStoreDao primaryDataStoreDaoMock;
+    @Mock
+    private VMSnapshotDao _vmSnapshotDao;
+    @Mock
+    private AsyncJobManager _jobMgr;
+    @Mock
+    private AsyncJobJoinMapDao _joinMapDao;
+    @Mock
+    private VolumeDataFactory volumeDataFactoryMock;
+    @Mock
+    private VMInstanceDao _vmInstanceDao;
+    @Mock
+    private VolumeInfo volumeInfoMock;
+    @Mock
+    private SnapshotInfo snapshotInfoMock;
+    @Mock
+    private VolumeService volumeServiceMock;
+    @Mock
+    private CreateVolumeCmd createVol;
+    @Mock
+    private UserVmManager userVmManager;
+    @Mock
+    private DataCenterDao _dcDao;
+    @Mock
+    private ResourceLimitService resourceLimitServiceMock;
+    @Mock
+    private AccountDao _accountDao;
+    @Mock
+    private HostDao _hostDao;
+    @Mock
+    private StoragePoolDetailsDao storagePoolDetailsDao;
+
+    private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
+    private Class<?> _detachCmdClass = detachCmd.getClass();
+
+    @Mock
+    private StoragePool storagePoolMock;
+    private long storagePoolMockId = 1;
+    @Mock
+    private DiskOfferingVO newDiskOfferingMock;
+
+    @Mock
+    private VolumeVO volumeVoMock;
+    @Mock
+    private Account accountMock;
+    @Mock
+    private VolumeDataStoreVO volumeDataStoreVoMock;
+    @Mock
+    private AsyncCallFuture<VolumeApiResult> asyncCallFutureVolumeapiResultMock;
+
+    private long accountMockId = 456l;
+    private long volumeMockId = 12313l;
+    private long vmInstanceMockId = 1123l;
+    private long volumeSizeMock = 456789921939l;
+
+    @Before
+    public void setup() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(volumeMockId).when(volumeDataStoreVoMock).getVolumeId();
+        Mockito.doReturn(volumeMockId).when(volumeVoMock).getId();
+        Mockito.doReturn(accountMockId).when(accountMock).getId();
+        Mockito.doReturn(volumeSizeMock).when(volumeVoMock).getSize();
+        Mockito.doReturn(volumeSizeMock).when(newDiskOfferingMock).getDiskSize();
+
+        Mockito.doReturn(Mockito.mock(VolumeApiResult.class)).when(asyncCallFutureVolumeapiResultMock).get();
+
+        Mockito.when(storagePoolMock.getId()).thenReturn(storagePoolMockId);
+
+        volumeApiServiceImpl._gson = GsonHelper.getGsonLogger();
+
+        // mock caller context
+        AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
+        CallContext.register(user, account);
+        // mock async context
+        AsyncJobExecutionContext context = new AsyncJobExecutionContext();
+        AsyncJobExecutionContext.init(_jobMgr, _joinMapDao);
+        AsyncJobVO job = new AsyncJobVO();
+        context.setJob(job);
+        AsyncJobExecutionContext.setCurrentExecutionContext(context);
+
+        TransactionLegacy txn = TransactionLegacy.open("runVolumeDaoImplTest");
+        try {
+            // volume of running vm id=1
+            VolumeVO volumeOfRunningVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 1L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            when(volumeDaoMock.findById(1L)).thenReturn(volumeOfRunningVm);
+
+            UserVmVO runningVm = new UserVmVO(1L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
+            runningVm.setState(State.Running);
+            runningVm.setDataCenterId(1L);
+            when(userVmDaoMock.findById(1L)).thenReturn(runningVm);
+
+            // volume of stopped vm id=2
+            VolumeVO volumeOfStoppedVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            volumeOfStoppedVm.setPoolId(1L);
+            when(volumeDaoMock.findById(2L)).thenReturn(volumeOfStoppedVm);
+
+            UserVmVO stoppedVm = new UserVmVO(2L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
+            stoppedVm.setState(State.Stopped);
+            stoppedVm.setDataCenterId(1L);
+            when(userVmDaoMock.findById(2L)).thenReturn(stoppedVm);
+
+            // volume of hyperV vm id=3
+            UserVmVO hyperVVm = new UserVmVO(3L, "vm", "vm", 1, HypervisorType.Hyperv, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
+            hyperVVm.setState(State.Stopped);
+            hyperVVm.setDataCenterId(1L);
+            when(userVmDaoMock.findById(3L)).thenReturn(hyperVVm);
+
+            VolumeVO volumeOfStoppeHyperVVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 3L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            volumeOfStoppeHyperVVm.setPoolId(1L);
+            when(volumeDaoMock.findById(3L)).thenReturn(volumeOfStoppeHyperVVm);
+
+            StoragePoolVO unmanagedPool = new StoragePoolVO();
+
+            when(primaryDataStoreDaoMock.findById(1L)).thenReturn(unmanagedPool);
+
+            // volume of managed pool id=4
+            StoragePoolVO managedPool = new StoragePoolVO();
+            managedPool.setManaged(true);
+            when(primaryDataStoreDaoMock.findById(2L)).thenReturn(managedPool);
+            VolumeVO managedPoolVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            managedPoolVolume.setPoolId(2L);
+            when(volumeDaoMock.findById(4L)).thenReturn(managedPoolVolume);
+
+            // non-root non-datadisk volume
+            VolumeInfo volumeWithIncorrectVolumeType = Mockito.mock(VolumeInfo.class);
+            when(volumeWithIncorrectVolumeType.getId()).thenReturn(5L);
+            when(volumeWithIncorrectVolumeType.getVolumeType()).thenReturn(Volume.Type.ISO);
+            when(volumeDataFactoryMock.getVolume(5L)).thenReturn(volumeWithIncorrectVolumeType);
+
+            // correct root volume
+            VolumeInfo correctRootVolume = Mockito.mock(VolumeInfo.class);
+            when(correctRootVolume.getId()).thenReturn(6L);
+            when(correctRootVolume.getDataCenterId()).thenReturn(1L);
+            when(correctRootVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
+            when(correctRootVolume.getInstanceId()).thenReturn(null);
+            when(correctRootVolume.getState()).thenReturn(Volume.State.Ready);
+            when(correctRootVolume.getTemplateId()).thenReturn(null);
+            when(correctRootVolume.getPoolId()).thenReturn(1L);
+            when(volumeDataFactoryMock.getVolume(6L)).thenReturn(correctRootVolume);
+
+            VolumeVO correctRootVolumeVO = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            when(volumeDaoMock.findById(6L)).thenReturn(correctRootVolumeVO);
+
+            // managed root volume
+            VolumeInfo managedVolume = Mockito.mock(VolumeInfo.class);
+            when(managedVolume.getId()).thenReturn(7L);
+            when(managedVolume.getDataCenterId()).thenReturn(1L);
+            when(managedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
+            when(managedVolume.getInstanceId()).thenReturn(null);
+            when(managedVolume.getPoolId()).thenReturn(2L);
+            when(volumeDataFactoryMock.getVolume(7L)).thenReturn(managedVolume);
+
+            VolumeVO managedVolume1 = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            managedVolume1.setPoolId(2L);
+            managedVolume1.setDataCenterId(1L);
+            when(volumeDaoMock.findById(7L)).thenReturn(managedVolume1);
+
+            // vm having root volume
+            UserVmVO vmHavingRootVolume = new UserVmVO(4L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
+            vmHavingRootVolume.setState(State.Stopped);
+            vmHavingRootVolume.setDataCenterId(1L);
+            when(userVmDaoMock.findById(4L)).thenReturn(vmHavingRootVolume);
+            List<VolumeVO> vols = new ArrayList<VolumeVO>();
+            vols.add(new VolumeVO());
+            when(volumeDaoMock.findByInstanceAndDeviceId(4L, 0L)).thenReturn(vols);
+
+            // volume in uploaded state
+            VolumeInfo uploadedVolume = Mockito.mock(VolumeInfo.class);
+            when(uploadedVolume.getId()).thenReturn(8L);
+            when(uploadedVolume.getDataCenterId()).thenReturn(1L);
+            when(uploadedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
+            when(uploadedVolume.getInstanceId()).thenReturn(null);
+            when(uploadedVolume.getPoolId()).thenReturn(1L);
+            when(uploadedVolume.getState()).thenReturn(Volume.State.Uploaded);
+            when(volumeDataFactoryMock.getVolume(8L)).thenReturn(uploadedVolume);
+
+            VolumeVO upVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
+            upVolume.setPoolId(1L);
+            upVolume.setDataCenterId(1L);
+            upVolume.setState(Volume.State.Uploaded);
+            when(volumeDaoMock.findById(8L)).thenReturn(upVolume);
+
+            // helper dao methods mock
+            when(_vmSnapshotDao.findByVm(any(Long.class))).thenReturn(new ArrayList<VMSnapshotVO>());
+            when(_vmInstanceDao.findById(any(Long.class))).thenReturn(stoppedVm);
+
+            DataCenterVO enabledZone = Mockito.mock(DataCenterVO.class);
+            when(enabledZone.getAllocationState()).thenReturn(Grouping.AllocationState.Enabled);
+
+            when(_dcDao.findById(anyLong())).thenReturn(enabledZone);
+
+        } finally {
+            txn.close("runVolumeDaoImplTest");
+        }
+
+        // helper methods mock
+        doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
+        doNothing().when(_jobMgr).updateAsyncJobAttachment(any(Long.class), any(String.class), any(Long.class));
+        when(_jobMgr.submitAsyncJob(any(AsyncJobVO.class), any(String.class), any(Long.class))).thenReturn(1L);
+    }
+
+    /**
+     * TESTS FOR DETACH ROOT VOLUME, COUNT=4
+     */
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testDetachVolumeFromRunningVm() throws NoSuchFieldException, IllegalAccessException {
+        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
+        dedicateIdField.setAccessible(true);
+        dedicateIdField.set(detachCmd, 1L);
+        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testDetachVolumeFromStoppedHyperVVm() throws NoSuchFieldException, IllegalAccessException {
+        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
+        dedicateIdField.setAccessible(true);
+        dedicateIdField.set(detachCmd, 3L);
+        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testDetachVolumeOfManagedDataStore() throws NoSuchFieldException, IllegalAccessException {
+        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
+        dedicateIdField.setAccessible(true);
+        dedicateIdField.set(detachCmd, 4L);
+        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
+    }
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Test
+    public void testDetachVolumeFromStoppedXenVm() throws NoSuchFieldException, IllegalAccessException {
+        thrown.expect(NullPointerException.class);
+        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
+        dedicateIdField.setAccessible(true);
+        dedicateIdField.set(detachCmd, 2L);
+        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
+    }
+
+    /**
+     * TESTS FOR ATTACH ROOT VOLUME, COUNT=7
+     */
+
+    // Negative test - try to attach non-root non-datadisk volume
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachIncorrectDiskType() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(1L, 5L, 0L);
+    }
+
+    // Negative test - attach root volume to running vm
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachRootDiskToRunningVm() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(1L, 6L, 0L);
+    }
+
+    // Negative test - attach root volume to non-xen vm
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachRootDiskToHyperVm() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(3L, 6L, 0L);
+    }
+
+    // Negative test - attach root volume from the managed data store
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachRootDiskOfManagedDataStore() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(2L, 7L, 0L);
+    }
+
+    // Negative test - root volume can't be attached to the vm already having a root volume attached
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachRootDiskToVmHavingRootDisk() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(4L, 6L, 0L);
+    }
+
+    // Negative test - root volume in uploaded state can't be attached
+    @Test(expected = InvalidParameterValueException.class)
+    public void attachRootInUploadedState() throws NoSuchFieldException, IllegalAccessException {
+        volumeApiServiceImpl.attachVolumeToVM(2L, 8L, 0L);
+    }
+
+    // Positive test - attach ROOT volume in correct state, to the vm not having root volume attached
+    @Test
+    public void attachRootVolumePositive() throws NoSuchFieldException, IllegalAccessException {
+        thrown.expect(NullPointerException.class);
+        volumeApiServiceImpl.attachVolumeToVM(2L, 6L, 0L);
+    }
+
+    // volume not Ready
+    @Test(expected = InvalidParameterValueException.class)
+    public void testTakeSnapshotF1() throws ResourceAllocationException {
+        when(volumeDataFactoryMock.getVolume(anyLong())).thenReturn(volumeInfoMock);
+        when(volumeInfoMock.getState()).thenReturn(Volume.State.Allocated);
+        when(volumeInfoMock.getPoolId()).thenReturn(1L);
+        volumeApiServiceImpl.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false, null, false);
+    }
+
+    @Test
+    public void testTakeSnapshotF2() throws ResourceAllocationException {
+        when(volumeDataFactoryMock.getVolume(anyLong())).thenReturn(volumeInfoMock);
+        when(volumeInfoMock.getState()).thenReturn(Volume.State.Ready);
+        when(volumeInfoMock.getInstanceId()).thenReturn(null);
+        when(volumeInfoMock.getPoolId()).thenReturn(1L);
+        when(volumeServiceMock.takeSnapshot(Mockito.any(VolumeInfo.class))).thenReturn(snapshotInfoMock);
+        volumeApiServiceImpl.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false, null, false);
+    }
+
+    @Test
+    public void testNullGetVolumeNameFromCmd() {
+        when(createVol.getVolumeName()).thenReturn(null);
+        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVol));
+    }
+
+    @Test
+    public void testEmptyGetVolumeNameFromCmd() {
+        when(createVol.getVolumeName()).thenReturn("");
+        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVol));
+    }
+
+    @Test
+    public void testBlankGetVolumeNameFromCmd() {
+        when(createVol.getVolumeName()).thenReturn("   ");
+        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVol));
+    }
+
+    @Test
+    public void testNonEmptyGetVolumeNameFromCmd() {
+        when(createVol.getVolumeName()).thenReturn("abc");
+        Assert.assertSame(volumeApiServiceImpl.getVolumeNameFromCommand(createVol), "abc");
+    }
+
+    @Test
+    public void testUpdateMissingRootDiskControllerWithNullChainInfo() {
+        volumeApiServiceImpl.updateMissingRootDiskController(null, null);
+        verify(userVmManager, times(0)).persistDeviceBusInfo(any(UserVmVO.class), anyString());
+    }
+
+    @Test
+    public void testUpdateMissingRootDiskControllerWithValidChainInfo() {
+        UserVmVO vm = userVmDaoMock.findById(1L);
+
+        Mockito.doNothing().when(userVmManager).persistDeviceBusInfo(any(UserVmVO.class), eq("scsi"));
+        volumeApiServiceImpl.updateMissingRootDiskController(vm, "{\"diskDeviceBusName\":\"scsi0:0\",\"diskChain\":[\"[somedatastore] i-3-VM-somePath/ROOT-1.vmdk\"]}");
+        verify(userVmManager, times(1)).persistDeviceBusInfo(any(UserVmVO.class), eq("scsi"));
+    }
+
+    /**
+     * Setting locationType for a non-managed storage should give an error
+     */
+    @Test
+    public void testAllocSnapshotNonManagedStorageArchive() {
+        try {
+            volumeApiServiceImpl.allocSnapshot(6L, 1L, "test", Snapshot.LocationType.SECONDARY);
+        } catch (InvalidParameterValueException e) {
+            Assert.assertEquals(e.getMessage(), "VolumeId: 6 LocationType is supported only for managed storage");
+            return;
+        } catch (ResourceAllocationException e) {
+            Assert.fail("Unexpected excepiton " + e.getMessage());
+        }
+
+        Assert.fail("Expected Exception for archive in non-managed storage");
+    }
+
+    /**
+     * The resource limit check for primary storage should not be skipped for Volume in 'Uploaded' state.
+     */
+    @Test
+    public void testResourceLimitCheckForUploadedVolume() throws NoSuchFieldException, IllegalAccessException, ResourceAllocationException {
+        doThrow(new ResourceAllocationException("primary storage resource limit check failed", Resource.ResourceType.primary_storage)).when(resourceLimitServiceMock)
+        .checkResourceLimit(any(AccountVO.class), any(Resource.ResourceType.class), any(Long.class));
+        UserVmVO vm = Mockito.mock(UserVmVO.class);
+        VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
+        when(volumeToAttach.getId()).thenReturn(9L);
+        when(volumeToAttach.getDataCenterId()).thenReturn(34L);
+        when(volumeToAttach.getVolumeType()).thenReturn(Volume.Type.DATADISK);
+        when(volumeToAttach.getInstanceId()).thenReturn(null);
+        when(userVmDaoMock.findById(anyLong())).thenReturn(vm);
+        when(vm.getType()).thenReturn(VirtualMachine.Type.User);
+        when(vm.getState()).thenReturn(State.Running);
+        when(vm.getDataCenterId()).thenReturn(34L);
+        when(volumeDaoMock.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10));
+        when(volumeDataFactoryMock.getVolume(9L)).thenReturn(volumeToAttach);
+        when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
+        DataCenterVO zoneWithDisabledLocalStorage = Mockito.mock(DataCenterVO.class);
+        when(_dcDao.findById(anyLong())).thenReturn(zoneWithDisabledLocalStorage);
+        when(zoneWithDisabledLocalStorage.isLocalStorageEnabled()).thenReturn(true);
+        try {
+            volumeApiServiceImpl.attachVolumeToVM(2L, 9L, null);
+        } catch (InvalidParameterValueException e) {
+            Assert.assertEquals(e.getMessage(), ("primary storage resource limit check failed"));
+        }
+    }
+
+    @After
+    public void tearDown() {
+        CallContext.unregister();
+    }
+
+    @Test
+    public void getStoragePoolTagsTestStorageWithoutTags() {
+        Mockito.when(storagePoolDetailsDao.listDetails(storagePoolMockId)).thenReturn(new ArrayList<>());
+
+        String returnedStoragePoolTags = volumeApiServiceImpl.getStoragePoolTags(storagePoolMock);
+
+        Assert.assertNull(returnedStoragePoolTags);
+
+    }
+
+    @Test
+    public void getStoragePoolTagsTestStorageWithTags() {
+        ArrayList<StoragePoolDetailVO> tags = new ArrayList<>();
+        StoragePoolDetailVO tag1 = new StoragePoolDetailVO(1l, "tag1", "value", true);
+        StoragePoolDetailVO tag2 = new StoragePoolDetailVO(1l, "tag2", "value", true);
+        StoragePoolDetailVO tag3 = new StoragePoolDetailVO(1l, "tag3", "value", true);
+
+        tags.add(tag1);
+        tags.add(tag2);
+        tags.add(tag3);
+
+        Mockito.when(storagePoolDetailsDao.listDetails(storagePoolMockId)).thenReturn(tags);
+
+        String returnedStoragePoolTags = volumeApiServiceImpl.getStoragePoolTags(storagePoolMock);
+
+        Assert.assertEquals("tag1,tag2,tag3", returnedStoragePoolTags);
+    }
+
+    @Test
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestNoNewDiskOffering() {
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, null, storagePoolMock);
+
+        Mockito.verify(volumeVoMock, times(0)).getVolumeType();
+    }
+
+    @Test
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestRootVolume() {
+        Mockito.when(volumeVoMock.getVolumeType()).thenReturn(Type.ROOT);
+
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestTargetPoolSharedDiskOfferingLocal() {
+        Mockito.when(volumeVoMock.getVolumeType()).thenReturn(Type.DATADISK);
+        Mockito.when(newDiskOfferingMock.isUseLocalStorage()).thenReturn(true);
+        Mockito.when(storagePoolMock.isShared()).thenReturn(true);
+
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestTargetPoolLocalDiskOfferingShared() {
+        Mockito.when(volumeVoMock.getVolumeType()).thenReturn(Type.DATADISK);
+        Mockito.when(newDiskOfferingMock.isShared()).thenReturn(true);
+        Mockito.when(storagePoolMock.isLocal()).thenReturn(true);
+
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestTagsDoNotMatch() {
+        Mockito.when(volumeVoMock.getVolumeType()).thenReturn(Type.DATADISK);
+
+        Mockito.when(newDiskOfferingMock.isUseLocalStorage()).thenReturn(false);
+        Mockito.when(storagePoolMock.isShared()).thenReturn(true);
+
+        Mockito.when(newDiskOfferingMock.isShared()).thenReturn(true);
+        Mockito.when(storagePoolMock.isLocal()).thenReturn(false);
+
+        Mockito.when(newDiskOfferingMock.getTags()).thenReturn("tag1");
+
+        Mockito.doReturn(null).when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
+    }
+
+    @Test
+    public void validateConditionsToReplaceDiskOfferingOfVolumeTestEverythingWorking() {
+        Mockito.when(volumeVoMock.getVolumeType()).thenReturn(Type.DATADISK);
+
+        Mockito.when(newDiskOfferingMock.isUseLocalStorage()).thenReturn(false);
+        Mockito.when(storagePoolMock.isShared()).thenReturn(true);
+
+        Mockito.when(newDiskOfferingMock.isShared()).thenReturn(true);
+        Mockito.when(storagePoolMock.isLocal()).thenReturn(false);
+
+        Mockito.when(newDiskOfferingMock.getTags()).thenReturn("tag1");
+
+        Mockito.doReturn("tag1").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        volumeApiServiceImpl.validateConditionsToReplaceDiskOfferingOfVolume(volumeVoMock, newDiskOfferingMock, storagePoolMock);
+
+        InOrder inOrder = Mockito.inOrder(volumeVoMock, newDiskOfferingMock, storagePoolMock, volumeApiServiceImpl);
+        inOrder.verify(storagePoolMock).isShared();
+        inOrder.verify(newDiskOfferingMock).isUseLocalStorage();
+        inOrder.verify(storagePoolMock).isLocal();
+        inOrder.verify(newDiskOfferingMock, times(0)).isShared();
+        inOrder.verify(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        inOrder.verify(volumeVoMock).getSize();
+        inOrder.verify(newDiskOfferingMock).getDiskSize();
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestVolumeNotFound() {
+        Mockito.doReturn(null).when(volumeDaoMock).findById(volumeMockId);
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestCannotOperateOnVolumeDueToSnapshot() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(false).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestVolumePluggedIntoVm() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(vmInstanceMockId).when(volumeVoMock).getInstanceId();
+
+        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestStateUploadOpAndDownloadInProgress() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
+        Mockito.doReturn(Volume.State.UploadOp).when(volumeVoMock).getState();
+
+        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+        Mockito.doReturn(volumeDataStoreVoMock).when(volumeDataStoreDaoMock).findByVolume(volumeMockId);
+        Mockito.doReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS).when(volumeDataStoreVoMock).getDownloadState();
+
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestStateNotUploaded() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
+        Mockito.doReturn(Volume.State.NotUploaded).when(volumeVoMock).getState();
+
+        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateVolumeTestUploadInProgress() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
+        Mockito.doReturn(Volume.State.UploadInProgress).when(volumeVoMock).getState();
+
+        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+    }
+
+    @Test
+    public void retrieveAndValidateVolumeTest() {
+        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
+        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
+        Mockito.doNothing().when(accountManagerMock).checkAccess(accountMock, null, true, volumeVoMock);
+        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
+
+        Mockito.verify(accountManagerMock).checkAccess(accountMock, null, true, volumeVoMock);
+    }
+
+    @Test
+    public void destroyVolumeIfPossibleTestVolumeStateIsDestroy() {
+        Mockito.doReturn(Volume.State.Destroy).when(volumeVoMock).getState();
+        configureMocksForTestDestroyVolumeWhenVolume();
+
+        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
+
+        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
+    }
+
+    @Test
+    public void destroyVolumeIfPossibleTestVolumeStateIsExpunging() {
+        Mockito.doReturn(Volume.State.Expunging).when(volumeVoMock).getState();
+        configureMocksForTestDestroyVolumeWhenVolume();
+
+        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
+
+        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
+    }
+
+    @Test
+    public void destroyVolumeIfPossibleTestVolumeStateIsExpunged() {
+        Mockito.doReturn(Volume.State.Expunged).when(volumeVoMock).getState();
+        configureMocksForTestDestroyVolumeWhenVolume();
+
+        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
+
+        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
+    }
+
+    @Test
+    public void destroyVolumeIfPossibleTestVolumeStateReady() {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+        configureMocksForTestDestroyVolumeWhenVolume();
+
+        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
+
+        Mockito.verify(volumeServiceMock, Mockito.times(1)).destroyVolume(volumeMockId);
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.volume, true);
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
+    }
+
+    private void verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState() {
+        Mockito.verify(volumeServiceMock, Mockito.times(0)).destroyVolume(volumeMockId);
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.volume, true);
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
+    }
+
+    private void configureMocksForTestDestroyVolumeWhenVolume() {
+        Mockito.doReturn(accountMockId).when(volumeVoMock).getAccountId();
+        Mockito.doReturn(true).when(volumeVoMock).isDisplayVolume();
+
+        Mockito.doNothing().when(volumeServiceMock).destroyVolume(volumeMockId);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.volume, true);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
+    }
+
+    @Test
+    public void expungeVolumesInPrimaryStorageIfNeededTestVolumeNotInPrimaryDataStore() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(null).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
+
+        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.verify(volumeServiceMock, Mockito.times(0)).expungeVolumeAsync(volumeInfoMock);
+        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(0)).get();
+    }
+
+    @Test
+    public void expungeVolumesInPrimaryStorageIfNeededTestVolumeInPrimaryDataStore() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
+
+        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.verify(volumeServiceMock, Mockito.times(1)).expungeVolumeAsync(volumeInfoMock);
+        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(1)).get();
+    }
+
+    @Test(expected = InterruptedException.class)
+    public void expungeVolumesInPrimaryStorageIfNeededTestThrowingInterruptedException() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
+        Mockito.doThrow(InterruptedException.class).when(asyncCallFutureVolumeapiResultMock).get();
+
+        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+    }
+
+    @Test(expected = ExecutionException.class)
+    public void expungeVolumesInPrimaryStorageIfNeededTestThrowingExecutionException() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
+        Mockito.doThrow(ExecutionException.class).when(asyncCallFutureVolumeapiResultMock).get();
+
+        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+    }
+
+    @Test
+    public void expungeVolumesInSecondaryStorageIfNeededTestVolumeNotFoundInSecondaryStorage() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(null).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
+        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
+
+        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.verify(volumeServiceMock, Mockito.times(0)).expungeVolumeAsync(volumeInfoMock);
+        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(0)).get();
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+    }
+
+    @Test
+    public void expungeVolumesInSecondaryStorageIfNeededTestVolumeFoundInSecondaryStorage() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
+        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
+
+        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.verify(volumeServiceMock, Mockito.times(1)).expungeVolumeAsync(volumeInfoMock);
+        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(1)).get();
+        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+    }
+
+    @Test(expected = InterruptedException.class)
+    public void expungeVolumesInSecondaryStorageIfNeededTestThrowinInterruptedException() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
+        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
+
+        Mockito.doThrow(InterruptedException.class).when(asyncCallFutureVolumeapiResultMock).get();
+
+        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+
+    }
+
+    @Test(expected = ExecutionException.class)
+    public void expungeVolumesInSecondaryStorageIfNeededTestThrowingExecutionException() throws InterruptedException, ExecutionException {
+        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
+        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
+        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
+        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
+        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
+
+        Mockito.doThrow(ExecutionException.class).when(asyncCallFutureVolumeapiResultMock).get();
+
+        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+
+    }
+
+    @Test
+    public void cleanVolumesCacheTest() {
+        List<VolumeInfo> volumeInfos = new ArrayList<>();
+        VolumeInfo volumeInfoMock1 = Mockito.mock(VolumeInfo.class);
+        VolumeInfo volumeInfoMock2 = Mockito.mock(VolumeInfo.class);
+
+        DataStore dataStoreMock1 = Mockito.mock(DataStore.class);
+        DataStore dataStoreMock2 = Mockito.mock(DataStore.class);
+        Mockito.doReturn(dataStoreMock1).when(volumeInfoMock1).getDataStore();
+        Mockito.doReturn(dataStoreMock2).when(volumeInfoMock2).getDataStore();
+
+        volumeInfos.add(volumeInfoMock1);
+        volumeInfos.add(volumeInfoMock2);
+
+        Mockito.doReturn(volumeInfos).when(volumeDataFactoryMock).listVolumeOnCache(volumeMockId);
+
+        volumeApiServiceImpl.cleanVolumesCache(volumeVoMock);
+
+        Mockito.verify(dataStoreMock1).getName();
+        Mockito.verify(dataStoreMock2).getName();
+
+        Mockito.verify(volumeInfoMock1).delete();
+        Mockito.verify(volumeInfoMock2).delete();
+    }
+
+    @Test
+    public void deleteVolumeTestVolumeStateAllocated() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Allocated).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).cleanVolumesCache(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+
+        Assert.assertTrue(result);
+        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.verify(volumeDaoMock).remove(volumeMockId);
+        Mockito.verify(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).cleanVolumesCache(volumeVoMock);
+    }
+
+    @Test
+    public void deleteVolumeTestVolumeStateReady() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).cleanVolumesCache(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+
+        Assert.assertTrue(result);
+        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).cleanVolumesCache(volumeVoMock);
+    }
+
+    @Test
+    public void deleteVolumeTestVolumeStateReadyThrowingInterruptedException() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doThrow(InterruptedException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+
+        Assert.assertFalse(result);
+        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+    }
+
+    @Test
+    public void deleteVolumeTestVolumeStateReadyThrowingExecutionException() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doThrow(ExecutionException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+
+        Assert.assertFalse(result);
+        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+    }
+
+    @Test
+    public void deleteVolumeTestVolumeStateReadyThrowingNoTransitionException() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doThrow(NoTransitionException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+
+        Assert.assertFalse(result);
+        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
+        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void deleteVolumeTestVolumeStateReadyThrowingRuntimeException() throws InterruptedException, ExecutionException, NoTransitionException {
+        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
+
+        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
+        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
+        Mockito.doThrow(RuntimeException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
+
+        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
+        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
+
+        volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingMoreTagsThanStorageTags() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("A,B,C").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("A").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsIsSubSetOfStorageTags() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("A,B,C").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("A,B,C,D,X,Y").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsEmptyAndStorageTagsNotEmpty() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("A,B,C,D,X,Y").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsNotEmptyAndStorageTagsEmpty() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("A").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsEmptyAndStorageTagsEmpty() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertTrue(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsDifferentFromdStorageTags() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("A,B").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("C,D").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertFalse(result);
+    }
+
+    @Test
+    public void doesTargetStorageSupportDiskOfferingTestDiskOfferingTagsEqualsStorageTags() {
+        DiskOfferingVO diskOfferingVoMock = Mockito.mock(DiskOfferingVO.class);
+        Mockito.doReturn("A").when(diskOfferingVoMock).getTags();
+
+        StoragePool storagePoolMock = Mockito.mock(StoragePool.class);
+        Mockito.doReturn("A").when(volumeApiServiceImpl).getStoragePoolTags(storagePoolMock);
+
+        boolean result = volumeApiServiceImpl.doesTargetStorageSupportDiskOffering(storagePoolMock, diskOfferingVoMock);
+
+        Assert.assertTrue(result);
+    }
+}
diff --git a/server/src/test/java/com/cloud/storage/dao/AsyncJobJoinDaoTest.java b/server/src/test/java/com/cloud/storage/dao/AsyncJobJoinDaoTest.java
new file mode 100644
index 0000000..ed93698
--- /dev/null
+++ b/server/src/test/java/com/cloud/storage/dao/AsyncJobJoinDaoTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.cloud.storage.dao;
+
+import com.cloud.api.query.dao.AsyncJobJoinDaoImpl;
+import com.cloud.api.query.vo.AsyncJobJoinVO;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.Date;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AsyncJobJoinDaoTest {
+
+    @InjectMocks
+    AsyncJobJoinDaoImpl dao;
+
+    @Test
+    public void testNewAsyncJobResponseValidValues() {
+        final AsyncJobJoinVO job = new AsyncJobJoinVO();
+        ReflectionTestUtils.setField(job,"uuid","a2b22932-1b61-4406-8e89-4ae19968e8d3");
+        ReflectionTestUtils.setField(job,"accountUuid","4dea2836-72cc-11e8-b2de-107b4429825a");
+        ReflectionTestUtils.setField(job,"domainUuid","4dea136b-72cc-11e8-b2de-107b4429825a");
+        ReflectionTestUtils.setField(job,"userUuid","4decc724-72cc-11e8-b2de-107b4429825a");
+        ReflectionTestUtils.setField(job,"cmd","org.apache.cloudstack.api.command.admin.vm.StartVMCmdByAdmin");
+        ReflectionTestUtils.setField(job,"status",0);
+        ReflectionTestUtils.setField(job,"resultCode",0);
+        ReflectionTestUtils.setField(job,"result",null);
+        ReflectionTestUtils.setField(job,"created",new Date());
+        ReflectionTestUtils.setField(job,"removed",new Date());
+        ReflectionTestUtils.setField(job,"instanceType",ApiCommandJobType.VirtualMachine);
+        ReflectionTestUtils.setField(job,"instanceId",3L);
+        final AsyncJobResponse response = dao.newAsyncJobResponse(job);
+        Assert.assertEquals(job.getUuid(),response.getJobId());
+        Assert.assertEquals(job.getAccountUuid(), ReflectionTestUtils.getField(response, "accountId"));
+        Assert.assertEquals(job.getUserUuid(), ReflectionTestUtils.getField(response, "userId"));
+        Assert.assertEquals(job.getCmd(), ReflectionTestUtils.getField(response, "cmd"));
+        Assert.assertEquals(job.getStatus(), ReflectionTestUtils.getField(response, "jobStatus"));
+        Assert.assertEquals(job.getStatus(), ReflectionTestUtils.getField(response, "jobProcStatus"));
+        Assert.assertEquals(job.getResultCode(), ReflectionTestUtils.getField(response, "jobResultCode"));
+        Assert.assertEquals(null, ReflectionTestUtils.getField(response, "jobResultType"));
+        Assert.assertEquals(job.getResult(), ReflectionTestUtils.getField(response, "jobResult"));
+        Assert.assertEquals(job.getInstanceType().toString(), ReflectionTestUtils.getField(response, "jobInstanceType"));
+        Assert.assertEquals(job.getInstanceUuid(), ReflectionTestUtils.getField(response, "jobInstanceId"));
+        Assert.assertEquals(job.getCreated(), ReflectionTestUtils.getField(response, "created"));
+        Assert.assertEquals(job.getRemoved(), ReflectionTestUtils.getField(response, "removed"));
+    }
+
+    @Test
+    public void testNewAsyncJobResponseNullValues() {
+        final AsyncJobJoinVO job = new AsyncJobJoinVO();
+        final AsyncJobResponse response = dao.newAsyncJobResponse(job);
+        Assert.assertEquals(job.getUuid(),response.getJobId());
+        Assert.assertEquals(job.getAccountUuid(), ReflectionTestUtils.getField(response, "accountId"));
+        Assert.assertEquals(job.getUserUuid(), ReflectionTestUtils.getField(response, "userId"));
+        Assert.assertEquals(job.getCmd(), ReflectionTestUtils.getField(response, "cmd"));
+        Assert.assertEquals(job.getStatus(), ReflectionTestUtils.getField(response, "jobStatus"));
+        Assert.assertEquals(job.getStatus(), ReflectionTestUtils.getField(response, "jobProcStatus"));
+        Assert.assertEquals(job.getResultCode(), ReflectionTestUtils.getField(response, "jobResultCode"));
+        Assert.assertEquals(null, ReflectionTestUtils.getField(response, "jobResultType"));
+        Assert.assertEquals(job.getResult(), ReflectionTestUtils.getField(response, "jobResult"));
+        Assert.assertEquals(job.getInstanceType(), ReflectionTestUtils.getField(response, "jobInstanceType"));
+        Assert.assertEquals(job.getInstanceUuid(), ReflectionTestUtils.getField(response, "jobInstanceId"));
+        Assert.assertEquals(job.getCreated(), ReflectionTestUtils.getField(response, "created"));
+        Assert.assertEquals(job.getRemoved(), ReflectionTestUtils.getField(response, "removed"));
+    }
+}
diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTest.java b/server/src/test/java/com/cloud/storage/dao/StoragePoolDaoTest.java
similarity index 100%
rename from server/test/com/cloud/storage/dao/StoragePoolDaoTest.java
rename to server/src/test/java/com/cloud/storage/dao/StoragePoolDaoTest.java
diff --git a/server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java b/server/src/test/java/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java
rename to server/src/test/java/com/cloud/storage/dao/StoragePoolDaoTestConfiguration.java
diff --git a/server/test/com/cloud/storage/listener/StoragePoolMonitorTest.java b/server/src/test/java/com/cloud/storage/listener/StoragePoolMonitorTest.java
similarity index 100%
rename from server/test/com/cloud/storage/listener/StoragePoolMonitorTest.java
rename to server/src/test/java/com/cloud/storage/listener/StoragePoolMonitorTest.java
diff --git a/server/src/test/java/com/cloud/storage/snapshot/SnapshotManagerTest.java b/server/src/test/java/com/cloud/storage/snapshot/SnapshotManagerTest.java
new file mode 100755
index 0000000..973485f
--- /dev/null
+++ b/server/src/test/java/com/cloud/storage/snapshot/SnapshotManagerTest.java
@@ -0,0 +1,353 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.storage.snapshot;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
+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.StorageStrategyFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.snapshot.VMSnapshot;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SnapshotManagerTest {
+    @Spy
+    SnapshotManagerImpl _snapshotMgr = new SnapshotManagerImpl();
+    @Mock
+    SnapshotDao _snapshotDao;
+    @Mock
+    VolumeDao _volumeDao;
+    @Mock
+    UserVmDao _vmDao;
+    @Mock
+    PrimaryDataStoreDao _storagePoolDao;
+    @Mock
+    VMSnapshotDao _vmSnapshotDao;
+    @Mock
+    VMSnapshotVO vmSnapshotMock;
+    @Mock
+    Account account;
+    @Mock
+    UserVmVO vmMock;
+    @Mock
+    VolumeVO volumeMock;
+    @Mock
+    VolumeInfo volumeInfoMock;
+    @Mock
+    VolumeDataFactory volumeFactory;
+    @Mock
+    SnapshotVO snapshotMock;
+    @Mock
+    SnapshotInfo snapshotInfoMock;
+    @Mock
+    SnapshotDataFactory snapshotFactory;
+    @Mock
+    StorageStrategyFactory _storageStrategyFactory;
+    @Mock
+    SnapshotStrategy snapshotStrategy;
+    @Mock
+    AccountManager _accountMgr;
+    @Mock
+    ResourceLimitService _resourceLimitMgr;
+    @Mock
+    StoragePoolVO poolMock;
+    @Mock
+    ResourceManager _resourceMgr;
+    @Mock
+    DataStore storeMock;
+    @Mock
+    SnapshotDataStoreDao snapshotStoreDao;
+    @Mock
+    SnapshotDataStoreVO snapshotStoreMock;
+    @Mock
+    SnapshotService snapshotSrv;
+
+
+    private static final long TEST_SNAPSHOT_ID = 3L;
+    private static final long TEST_VOLUME_ID = 4L;
+    private static final long TEST_VM_ID = 5L;
+    private static final long TEST_STORAGE_POOL_ID = 6L;
+    private static final long TEST_VM_SNAPSHOT_ID = 6L;
+
+    @Before
+    public void setup() throws ResourceAllocationException {
+        MockitoAnnotations.initMocks(this);
+        _snapshotMgr._snapshotDao = _snapshotDao;
+        _snapshotMgr._volsDao = _volumeDao;
+        _snapshotMgr._vmDao = _vmDao;
+        _snapshotMgr.volFactory = volumeFactory;
+        _snapshotMgr.snapshotFactory = snapshotFactory;
+        _snapshotMgr._storageStrategyFactory = _storageStrategyFactory;
+        _snapshotMgr._accountMgr = _accountMgr;
+        _snapshotMgr._resourceLimitMgr = _resourceLimitMgr;
+        _snapshotMgr._storagePoolDao = _storagePoolDao;
+        _snapshotMgr._resourceMgr = _resourceMgr;
+        _snapshotMgr._vmSnapshotDao = _vmSnapshotDao;
+        _snapshotMgr._snapshotStoreDao = snapshotStoreDao;
+
+        when(_snapshotDao.findById(anyLong())).thenReturn(snapshotMock);
+        when(snapshotMock.getVolumeId()).thenReturn(TEST_VOLUME_ID);
+        when(snapshotMock.isRecursive()).thenReturn(false);
+
+        when(_volumeDao.findById(anyLong())).thenReturn(volumeMock);
+        when(volumeMock.getState()).thenReturn(Volume.State.Ready);
+        when(volumeFactory.getVolume(anyLong())).thenReturn(volumeInfoMock);
+        when(volumeInfoMock.getDataStore()).thenReturn(storeMock);
+        when(volumeInfoMock.getState()).thenReturn(Volume.State.Ready);
+        when(storeMock.getId()).thenReturn(TEST_STORAGE_POOL_ID);
+
+        when(snapshotFactory.getSnapshot(anyLong(), Mockito.any(DataStoreRole.class))).thenReturn(snapshotInfoMock);
+        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.BACKUP))).thenReturn(snapshotStrategy);
+        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.REVERT))).thenReturn(snapshotStrategy);
+        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.DELETE))).thenReturn(snapshotStrategy);
+
+        doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
+        doNothing().when(_snapshotMgr._resourceLimitMgr).checkResourceLimit(any(Account.class), any(ResourceType.class));
+        doNothing().when(_snapshotMgr._resourceLimitMgr).checkResourceLimit(any(Account.class), any(ResourceType.class), anyLong());
+        doNothing().when(_snapshotMgr._resourceLimitMgr).decrementResourceCount(anyLong(), any(ResourceType.class), anyLong());
+        doNothing().when(_snapshotMgr._resourceLimitMgr).incrementResourceCount(anyLong(), any(ResourceType.class));
+        doNothing().when(_snapshotMgr._resourceLimitMgr).incrementResourceCount(anyLong(), any(ResourceType.class), anyLong());
+
+        Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
+        CallContext.register(user, account);
+        when(_accountMgr.getAccount(anyLong())).thenReturn(account);
+
+        when(_storagePoolDao.findById(anyLong())).thenReturn(poolMock);
+        when(poolMock.getScope()).thenReturn(ScopeType.ZONE);
+        when(poolMock.getHypervisor()).thenReturn(HypervisorType.KVM);
+        when(_resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(any(HypervisorType.class), anyLong())).thenReturn(null);
+    }
+
+    @After
+    public void tearDown() {
+        CallContext.unregister();
+    }
+
+    // vm is destroyed
+    @Test(expected = CloudRuntimeException.class)
+    public void testAllocSnapshotF1() throws ResourceAllocationException {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getState()).thenReturn(State.Destroyed);
+        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
+    }
+
+    // active snapshots
+    @SuppressWarnings("unchecked")
+    @Test(expected = InvalidParameterValueException.class)
+    public void testAllocSnapshotF2() throws ResourceAllocationException {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getId()).thenReturn(TEST_VM_ID);
+        when(vmMock.getState()).thenReturn(State.Stopped);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
+        List<SnapshotVO> mockList = mock(List.class);
+        when(mockList.size()).thenReturn(1);
+        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
+        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
+    }
+
+    // active vm snapshots
+    @SuppressWarnings("unchecked")
+    @Test(expected = CloudRuntimeException.class)
+    public void testAllocSnapshotF3() throws ResourceAllocationException {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getId()).thenReturn(TEST_VM_ID);
+        when(vmMock.getState()).thenReturn(State.Stopped);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
+        List<SnapshotVO> mockList = mock(List.class);
+        when(mockList.size()).thenReturn(0);
+        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
+        List<VMSnapshotVO> mockList2 = mock(List.class);
+        when(mockList2.size()).thenReturn(1);
+        when(_vmSnapshotDao.listByInstanceId(TEST_VM_ID, VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging)).thenReturn(mockList2);
+        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
+    }
+
+    // successful test
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testAllocSnapshotF4() throws ResourceAllocationException {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getId()).thenReturn(TEST_VM_ID);
+        when(vmMock.getState()).thenReturn(State.Stopped);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
+        List<SnapshotVO> mockList = mock(List.class);
+        when(mockList.size()).thenReturn(0);
+        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
+        List<VMSnapshotVO> mockList2 = mock(List.class);
+        when(mockList2.size()).thenReturn(0);
+        when(_vmSnapshotDao.listByInstanceId(TEST_VM_ID, VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging)).thenReturn(mockList2);
+        when(_snapshotDao.persist(any(SnapshotVO.class))).thenReturn(snapshotMock);
+        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testDeleteSnapshotF1() {
+        when(snapshotStrategy.deleteSnapshot(TEST_SNAPSHOT_ID)).thenReturn(true);
+        when(snapshotMock.getState()).thenReturn(Snapshot.State.Destroyed);
+        when(snapshotMock.getAccountId()).thenReturn(2L);
+        when(snapshotMock.getDataCenterId()).thenReturn(2L);
+
+        _snapshotMgr.deleteSnapshot(TEST_SNAPSHOT_ID);
+    }
+
+    // vm state not stopped
+    @Test(expected = InvalidParameterValueException.class)
+    public void testRevertSnapshotF1() {
+        when(volumeMock.getInstanceId()).thenReturn(TEST_VM_ID);
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getState()).thenReturn(State.Running);
+        _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
+    }
+
+    // vm on Xenserver, return null
+    @Test
+    public void testRevertSnapshotF2() {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getState()).thenReturn(State.Stopped);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
+        when(volumeMock.getFormat()).thenReturn(ImageFormat.VHD);
+        Snapshot snapshot = _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
+        Assert.assertNull(snapshot);
+    }
+
+    // vm on KVM, successful
+    @Test
+    public void testRevertSnapshotF3() {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getState()).thenReturn(State.Stopped);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(volumeMock.getFormat()).thenReturn(ImageFormat.QCOW2);
+        when (snapshotStrategy.revertSnapshot(Mockito.any(SnapshotInfo.class))).thenReturn(true);
+        when(_volumeDao.update(anyLong(), any(VolumeVO.class))).thenReturn(true);
+        Snapshot snapshot = _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
+        Assert.assertNotNull(snapshot);
+    }
+
+    // vm on Xenserver, expected exception
+    @Test(expected = InvalidParameterValueException.class)
+    public void testBackupSnapshotFromVmSnapshotF1() {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
+        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
+        Assert.assertNull(snapshot);
+    }
+
+    // vm on KVM, first time
+    @Test
+    public void testBackupSnapshotFromVmSnapshotF2() {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(_vmSnapshotDao.findById(anyLong())).thenReturn(vmSnapshotMock);
+        when(snapshotStoreDao.findParent(any(DataStoreRole.class), anyLong(), anyLong())).thenReturn(null);
+        when(snapshotFactory.getSnapshot(anyLong(), Mockito.any(DataStore.class))).thenReturn(snapshotInfoMock);
+        when(storeMock.create(snapshotInfoMock)).thenReturn(snapshotInfoMock);
+        when(snapshotStoreDao.findBySnapshot(anyLong(), any(DataStoreRole.class))).thenReturn(snapshotStoreMock);
+        when(snapshotStoreDao.update(anyLong(), any(SnapshotDataStoreVO.class))).thenReturn(true);
+        when(_snapshotDao.update(anyLong(), any(SnapshotVO.class))).thenReturn(true);
+        when(vmMock.getAccountId()).thenReturn(2L);
+        when(snapshotStrategy.backupSnapshot(any(SnapshotInfo.class))).thenReturn(snapshotInfoMock);
+
+        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
+        Assert.assertNotNull(snapshot);
+    }
+
+    // vm on KVM, already backed up
+    @Test(expected = InvalidParameterValueException.class)
+    public void testBackupSnapshotFromVmSnapshotF3() {
+        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
+        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
+        when(_vmSnapshotDao.findById(anyLong())).thenReturn(vmSnapshotMock);
+        when(snapshotStoreDao.findParent(any(DataStoreRole.class), anyLong(), anyLong())).thenReturn(snapshotStoreMock);
+        when(snapshotStoreMock.getInstallPath()).thenReturn("VM_SNAPSHOT_NAME");
+        when(vmSnapshotMock.getName()).thenReturn("VM_SNAPSHOT_NAME");
+        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
+        Assert.assertNull(snapshot);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testArchiveSnapshotSnapshotNotOnPrimary() {
+        when(snapshotFactory.getSnapshot(anyLong(), Mockito.eq(DataStoreRole.Primary))).thenReturn(null);
+        _snapshotMgr.archiveSnapshot(TEST_SNAPSHOT_ID);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testArchiveSnapshotSnapshotNotReady() {
+        when(snapshotFactory.getSnapshot(anyLong(), Mockito.eq(DataStoreRole.Primary))).thenReturn(snapshotInfoMock);
+        when(snapshotInfoMock.getStatus()).thenReturn(ObjectInDataStoreStateMachine.State.Destroyed);
+        _snapshotMgr.archiveSnapshot(TEST_SNAPSHOT_ID);
+    }
+}
diff --git a/server/test/com/cloud/template/HypervisorTemplateAdapterTest.java b/server/src/test/java/com/cloud/template/HypervisorTemplateAdapterTest.java
similarity index 100%
rename from server/test/com/cloud/template/HypervisorTemplateAdapterTest.java
rename to server/src/test/java/com/cloud/template/HypervisorTemplateAdapterTest.java
diff --git a/server/test/com/cloud/template/TemplateManagerImplTest.java b/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/template/TemplateManagerImplTest.java
rename to server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
new file mode 100644
index 0000000..e730277
--- /dev/null
+++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
@@ -0,0 +1,702 @@
+// 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.user;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.acl.DomainChecker;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication;
+import com.cloud.user.Account.State;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.UserVmManagerImpl;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AccountManagerImplTest extends AccountManagetImplTestBase {
+
+    @Mock
+    private UserVmManagerImpl _vmMgr;
+    @Mock
+    private AccountVO callingAccount;
+    @Mock
+    private DomainChecker domainChecker;
+    @Mock
+    private AccountService accountService;
+    @Mock
+    private GetUserKeysCmd _listkeyscmd;
+    @Mock
+    private User _user;
+    @Mock
+    private UserAccountVO userAccountVO;
+
+    @Mock
+    private UpdateUserCmd UpdateUserCmdMock;
+
+    private long userVoIdMock = 111l;
+    @Mock
+    private UserVO userVoMock;
+
+    private long accountMockId = 100l;
+    @Mock
+    private Account accountMock;
+
+    @Before
+    public void beforeTest() {
+        Mockito.doReturn(accountMockId).when(accountMock).getId();
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+
+        Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
+
+        Mockito.doReturn(userVoIdMock).when(userVoMock).getId();
+    }
+
+    @Test
+    public void disableAccountNotexisting() throws ConcurrentOperationException, ResourceUnavailableException {
+        Mockito.when(accountDaoMock.findById(42l)).thenReturn(null);
+        Assert.assertTrue(accountManagerImpl.disableAccount(42));
+    }
+
+    @Test
+    public void disableAccountDisabled() throws ConcurrentOperationException, ResourceUnavailableException {
+        AccountVO disabledAccount = new AccountVO();
+        disabledAccount.setState(State.disabled);
+        Mockito.when(accountDaoMock.findById(42l)).thenReturn(disabledAccount);
+        Assert.assertTrue(accountManagerImpl.disableAccount(42));
+    }
+
+    @Test
+    public void disableAccount() throws ConcurrentOperationException, ResourceUnavailableException {
+        AccountVO account = new AccountVO();
+        account.setState(State.enabled);
+        Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
+        Mockito.when(accountDaoMock.createForUpdate()).thenReturn(new AccountVO());
+        Mockito.when(accountDaoMock.update(Mockito.eq(42l), Mockito.any(AccountVO.class))).thenReturn(true);
+        Mockito.when(_vmDao.listByAccountId(42l)).thenReturn(Arrays.asList(Mockito.mock(VMInstanceVO.class)));
+        Assert.assertTrue(accountManagerImpl.disableAccount(42));
+        Mockito.verify(accountDaoMock, Mockito.atLeastOnce()).update(Mockito.eq(42l), Mockito.any(AccountVO.class));
+    }
+
+    @Test
+    public void deleteUserAccount() {
+        AccountVO account = new AccountVO();
+        account.setId(42l);
+        DomainVO domain = new DomainVO();
+        Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
+        Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class), Mockito.anyString())).thenReturn(true);
+        Mockito.when(accountDaoMock.remove(42l)).thenReturn(true);
+        Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l)).thenReturn(true);
+        Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
+        Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class))).thenReturn(true);
+        Mockito.when(_vmSnapshotDao.listByAccountId(Mockito.anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
+
+        List<SSHKeyPairVO> sshkeyList = new ArrayList<SSHKeyPairVO>();
+        SSHKeyPairVO sshkey = new SSHKeyPairVO();
+        sshkey.setId(1l);
+        sshkeyList.add(sshkey);
+        Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList);
+        Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true);
+
+        Assert.assertTrue(accountManagerImpl.deleteUserAccount(42));
+        // assert that this was a clean delete
+        Mockito.verify(accountDaoMock, Mockito.never()).markForCleanup(Mockito.eq(42l));
+    }
+
+    @Test
+    public void deleteUserAccountCleanup() {
+        AccountVO account = new AccountVO();
+        account.setId(42l);
+        DomainVO domain = new DomainVO();
+        Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
+        Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class), Mockito.anyString())).thenReturn(true);
+        Mockito.when(accountDaoMock.remove(42l)).thenReturn(true);
+        Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l)).thenReturn(true);
+        Mockito.when(_userVmDao.listByAccountId(42l)).thenReturn(Arrays.asList(Mockito.mock(UserVmVO.class)));
+        Mockito.when(_vmMgr.expunge(Mockito.any(UserVmVO.class), Mockito.anyLong(), Mockito.any(Account.class))).thenReturn(false);
+        Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
+        Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class))).thenReturn(true);
+
+        Assert.assertTrue(accountManagerImpl.deleteUserAccount(42));
+        // assert that this was NOT a clean delete
+        Mockito.verify(accountDaoMock, Mockito.atLeastOnce()).markForCleanup(Mockito.eq(42l));
+    }
+
+    @Test
+    public void testAuthenticateUser() throws UnknownHostException {
+        Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> successAuthenticationPair = new Pair<>(true, null);
+        Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> failureAuthenticationPair = new Pair<>(false,
+                UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
+
+        UserAccountVO userAccountVO = new UserAccountVO();
+        userAccountVO.setSource(User.Source.UNKNOWN);
+        userAccountVO.setState(Account.State.disabled.toString());
+        Mockito.when(userAccountDaoMock.getUserAccount("test", 1L)).thenReturn(userAccountVO);
+        Mockito.when(userAuthenticator.authenticate("test", "fail", 1L, null)).thenReturn(failureAuthenticationPair);
+        Mockito.when(userAuthenticator.authenticate("test", null, 1L, null)).thenReturn(successAuthenticationPair);
+        Mockito.when(userAuthenticator.authenticate("test", "", 1L, null)).thenReturn(successAuthenticationPair);
+
+        //Test for incorrect password. authentication should fail
+        UserAccount userAccount = accountManagerImpl.authenticateUser("test", "fail", 1L, InetAddress.getByName("127.0.0.1"), null);
+        Assert.assertNull(userAccount);
+
+        //Test for null password. authentication should fail
+        userAccount = accountManagerImpl.authenticateUser("test", null, 1L, InetAddress.getByName("127.0.0.1"), null);
+        Assert.assertNull(userAccount);
+
+        //Test for empty password. authentication should fail
+        userAccount = accountManagerImpl.authenticateUser("test", "", 1L, InetAddress.getByName("127.0.0.1"), null);
+        Assert.assertNull(userAccount);
+
+        //Verifying that the authentication method is only called when password is specified
+        Mockito.verify(userAuthenticator, Mockito.times(1)).authenticate("test", "fail", 1L, null);
+        Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", null, 1L, null);
+        Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", "", 1L, null);
+    }
+
+    @Test(expected = PermissionDeniedException.class)
+    public void testgetUserCmd() {
+        CallContext.register(callingUser, callingAccount); // Calling account is user account i.e normal account
+        Mockito.when(_listkeyscmd.getID()).thenReturn(1L);
+        Mockito.when(accountManagerImpl.getActiveUser(1L)).thenReturn(_user);
+        Mockito.when(accountManagerImpl.getUserAccountById(1L)).thenReturn(userAccountVO);
+        Mockito.when(userAccountVO.getAccountId()).thenReturn(1L);
+        Mockito.when(accountManagerImpl.getAccount(Mockito.anyLong())).thenReturn(accountMock); // Queried account - admin account
+
+        Mockito.when(callingUser.getAccountId()).thenReturn(1L);
+        Mockito.when(accountDaoMock.findById(1L)).thenReturn(callingAccount);
+
+        Mockito.when(accountService.isNormalUser(Mockito.anyLong())).thenReturn(Boolean.TRUE);
+        Mockito.when(accountMock.getAccountId()).thenReturn(2L);
+
+        accountManagerImpl.getKeys(_listkeyscmd);
+    }
+
+    @Test
+    public void updateUserTestTimeZoneAndEmailNull() {
+        prepareMockAndExecuteUpdateUserTest(0);
+    }
+
+    @Test
+    public void updateUserTestTimeZoneAndEmailNotNull() {
+        Mockito.when(UpdateUserCmdMock.getEmail()).thenReturn("email");
+        Mockito.when(UpdateUserCmdMock.getTimezone()).thenReturn("timezone");
+        prepareMockAndExecuteUpdateUserTest(1);
+    }
+
+    private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) {
+        Mockito.doReturn(userVoMock).when(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
+        Mockito.doNothing().when(accountManagerImpl).validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+        Mockito.doReturn(accountMock).when(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
+
+        Mockito.doNothing().when(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
+        Mockito.doNothing().when(accountManagerImpl).validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
+        Mockito.doNothing().when(accountManagerImpl).validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+        Mockito.doNothing().when(accountManagerImpl).validateUserPasswordAndUpdateIfNeeded(Mockito.anyString(), Mockito.eq(userVoMock), Mockito.anyString());
+
+        Mockito.doReturn(true).when(userDaoMock).update(Mockito.anyLong(), Mockito.eq(userVoMock));
+        Mockito.doReturn(Mockito.mock(UserAccountVO.class)).when(userAccountDaoMock).findById(Mockito.anyLong());
+
+        accountManagerImpl.updateUser(UpdateUserCmdMock);
+
+        InOrder inOrder = Mockito.inOrder(userVoMock, accountManagerImpl, userDaoMock, userAccountDaoMock);
+
+        inOrder.verify(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
+        inOrder.verify(accountManagerImpl).validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+        inOrder.verify(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
+
+        inOrder.verify(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
+        inOrder.verify(accountManagerImpl).validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
+        inOrder.verify(accountManagerImpl).validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+        inOrder.verify(accountManagerImpl).validateUserPasswordAndUpdateIfNeeded(Mockito.anyString(), Mockito.eq(userVoMock), Mockito.anyString());
+
+        inOrder.verify(userVoMock, Mockito.times(numberOfExpectedCallsForSetEmailAndSetTimeZone)).setEmail(Mockito.anyString());
+        inOrder.verify(userVoMock, Mockito.times(numberOfExpectedCallsForSetEmailAndSetTimeZone)).setTimezone(Mockito.anyString());
+
+        inOrder.verify(userDaoMock).update(Mockito.anyLong(), Mockito.eq(userVoMock));
+        inOrder.verify(userAccountDaoMock).findById(Mockito.anyLong());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateUserTestNoUserFound() {
+        Mockito.doReturn(null).when(userDaoMock).getUser(Mockito.anyLong());
+
+        accountManagerImpl.retrieveAndValidateUser(UpdateUserCmdMock);
+    }
+
+    @Test
+    public void retrieveAndValidateUserTestUserIsFound() {
+        Mockito.doReturn(userVoMock).when(userDaoMock).getUser(Mockito.anyLong());
+
+        UserVO receivedUser = accountManagerImpl.retrieveAndValidateUser(UpdateUserCmdMock);
+
+        Assert.assertEquals(userVoMock, receivedUser);
+    }
+
+    @Test
+    public void validateAndUpdatApiAndSecretKeyIfNeededTestNoKeys() {
+        accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(accountDaoMock, Mockito.times(0)).findUserAccountByApiKey(Mockito.anyString());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlyApiKeyInformed() {
+        Mockito.doReturn("apiKey").when(UpdateUserCmdMock).getApiKey();
+
+        accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlySecretKeyInformed() {
+        Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
+
+        accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdatApiAndSecretKeyIfNeededTestApiKeyAlreadyUsedBySomeoneElse() {
+        String apiKey = "apiKey";
+        Mockito.doReturn(apiKey).when(UpdateUserCmdMock).getApiKey();
+        Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
+
+        Mockito.doReturn(1L).when(userVoMock).getId();
+
+        User otherUserMock = Mockito.mock(User.class);
+        Mockito.doReturn(2L).when(otherUserMock).getId();
+
+        Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
+        Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
+
+        accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+    }
+
+    @Test
+    public void validateAndUpdatApiAndSecretKeyIfNeededTest() {
+        String apiKey = "apiKey";
+        Mockito.doReturn(apiKey).when(UpdateUserCmdMock).getApiKey();
+
+        String secretKey = "secretKey";
+        Mockito.doReturn(secretKey).when(UpdateUserCmdMock).getSecretKey();
+
+        Mockito.doReturn(1L).when(userVoMock).getId();
+
+        User otherUserMock = Mockito.mock(User.class);
+        Mockito.doReturn(1L).when(otherUserMock).getId();
+
+        Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
+        Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
+
+        accountManagerImpl.validateAndUpdateApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(accountDaoMock).findUserAccountByApiKey(apiKey);
+        Mockito.verify(userVoMock).setApiKey(apiKey);
+        Mockito.verify(userVoMock).setSecretKey(secretKey);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void retrieveAndValidateAccountTestAccountNotFound() {
+        Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
+
+        Mockito.doReturn(null).when(accountDaoMock).findById(accountMockId);
+
+        accountManagerImpl.retrieveAndValidateAccount(userVoMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void retrieveAndValidateAccountTestAccountTypeEqualsProjectType() {
+        Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
+        Mockito.doReturn(Account.ACCOUNT_TYPE_PROJECT).when(accountMock).getType();
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
+
+        accountManagerImpl.retrieveAndValidateAccount(userVoMock);
+    }
+
+    @Test(expected = PermissionDeniedException.class)
+    public void retrieveAndValidateAccountTestAccountTypeEqualsSystemType() {
+        Mockito.doReturn(Account.ACCOUNT_ID_SYSTEM).when(userVoMock).getAccountId();
+        Mockito.doReturn(Account.ACCOUNT_ID_SYSTEM).when(accountMock).getId();
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(Account.ACCOUNT_ID_SYSTEM);
+
+        accountManagerImpl.retrieveAndValidateAccount(userVoMock);
+    }
+
+    @Test
+    public void retrieveAndValidateAccountTest() {
+        Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
+
+        Mockito.doNothing().when(accountManagerImpl).checkAccess(Mockito.eq(accountMock), Mockito.eq(AccessType.OperateEntry), Mockito.anyBoolean(), Mockito.any(Account.class));
+        accountManagerImpl.retrieveAndValidateAccount(userVoMock);
+
+        Mockito.verify(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.verify(accountManagerImpl).checkAccess(Mockito.eq(accountMock), Mockito.eq(AccessType.OperateEntry), Mockito.anyBoolean(), Mockito.any(Account.class));
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdateFirstNameIfNeededTestFirstNameBlank() {
+        Mockito.doReturn("   ").when(UpdateUserCmdMock).getFirstname();
+
+        accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
+    }
+
+    @Test
+    public void validateAndUpdateFirstNameIfNeededTestFirstNameNull() {
+        Mockito.doReturn(null).when(UpdateUserCmdMock).getFirstname();
+
+        accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(userVoMock, Mockito.times(0)).setFirstname(Mockito.anyString());
+    }
+
+    @Test
+    public void validateAndUpdateFirstNameIfNeededTest() {
+        String firstname = "firstName";
+        Mockito.doReturn(firstname).when(UpdateUserCmdMock).getFirstname();
+
+        accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(userVoMock).setFirstname(firstname);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdateLastNameIfNeededTestLastNameBlank() {
+        Mockito.doReturn("   ").when(UpdateUserCmdMock).getLastname();
+
+        accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
+    }
+
+    @Test
+    public void validateAndUpdateLastNameIfNeededTestLastNameNull() {
+        Mockito.doReturn(null).when(UpdateUserCmdMock).getLastname();
+
+        accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(userVoMock, Mockito.times(0)).setLastname(Mockito.anyString());
+    }
+
+    @Test
+    public void validateAndUpdateLastNameIfNeededTest() {
+        String lastName = "lastName";
+        Mockito.doReturn(lastName).when(UpdateUserCmdMock).getLastname();
+
+        accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
+
+        Mockito.verify(userVoMock).setLastname(lastName);
+    }
+
+    @Test
+    public void validateAndUpdateUsernameIfNeededTestNullUsername() {
+        Mockito.doReturn(null).when(UpdateUserCmdMock).getUsername();
+
+        accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+
+        Mockito.verify(userVoMock, Mockito.times(0)).setUsername(Mockito.anyString());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdateUsernameIfNeededTestBlankUsername() {
+        Mockito.doReturn("   ").when(UpdateUserCmdMock).getUsername();
+
+        accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateAndUpdateUsernameIfNeededTestDuplicatedUserSameDomainThisUser() {
+        long domanIdCurrentUser = 22l;
+
+        String userName = "username";
+        Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
+        Mockito.doReturn(userName).when(userVoMock).getUsername();
+        Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
+
+        long userVoDuplicatedMockId = 67l;
+        UserVO userVoDuplicatedMock = Mockito.mock(UserVO.class);
+        Mockito.doReturn(userName).when(userVoDuplicatedMock).getUsername();
+        Mockito.doReturn(userVoDuplicatedMockId).when(userVoDuplicatedMock).getId();
+
+        long accountIdUserDuplicated = 98l;
+        Mockito.doReturn(accountIdUserDuplicated).when(userVoDuplicatedMock).getAccountId();
+
+        Account accountUserDuplicatedMock = Mockito.mock(Account.class);
+        Mockito.doReturn(accountIdUserDuplicated).when(accountUserDuplicatedMock).getId();
+        Mockito.doReturn(domanIdCurrentUser).when(accountUserDuplicatedMock).getDomainId();
+
+        List<UserVO> usersWithSameUserName = new ArrayList<>();
+        usersWithSameUserName.add(userVoMock);
+        usersWithSameUserName.add(userVoDuplicatedMock);
+
+        Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
+
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
+        Mockito.doReturn(accountUserDuplicatedMock).when(accountDaoMock).findById(accountIdUserDuplicated);
+
+        Mockito.doReturn(Mockito.mock(DomainVO.class)).when(_domainDao).findById(Mockito.anyLong());
+
+        accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+    }
+
+    @Test
+    public void validateAndUpdateUsernameIfNeededTestDuplicatedUserButInDifferentDomains() {
+        long domanIdCurrentUser = 22l;
+
+        String userName = "username";
+        Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
+        Mockito.doReturn(userName).when(userVoMock).getUsername();
+        Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
+
+        long userVoDuplicatedMockId = 67l;
+        UserVO userVoDuplicatedMock = Mockito.mock(UserVO.class);
+        Mockito.doReturn(userName).when(userVoDuplicatedMock).getUsername();
+        Mockito.doReturn(userVoDuplicatedMockId).when(userVoDuplicatedMock).getId();
+
+        long accountIdUserDuplicated = 98l;
+        Mockito.doReturn(accountIdUserDuplicated).when(userVoDuplicatedMock).getAccountId();
+
+        Account accountUserDuplicatedMock = Mockito.mock(Account.class);
+        Mockito.doReturn(accountIdUserDuplicated).when(accountUserDuplicatedMock).getId();
+        Mockito.doReturn(45l).when(accountUserDuplicatedMock).getDomainId();
+
+        List<UserVO> usersWithSameUserName = new ArrayList<>();
+        usersWithSameUserName.add(userVoMock);
+        usersWithSameUserName.add(userVoDuplicatedMock);
+
+        Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
+
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
+        Mockito.doReturn(accountUserDuplicatedMock).when(accountDaoMock).findById(accountIdUserDuplicated);
+
+        accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+
+        Mockito.verify(userVoMock).setUsername(userName);
+    }
+
+    @Test
+    public void validateAndUpdateUsernameIfNeededTestNoDuplicatedUserNames() {
+        long domanIdCurrentUser = 22l;
+
+        String userName = "username";
+        Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
+        Mockito.doReturn(userName).when(userVoMock).getUsername();
+        Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
+
+        List<UserVO> usersWithSameUserName = new ArrayList<>();
+
+        Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
+
+        Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
+
+        accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
+
+        Mockito.verify(userVoMock).setUsername(userName);
+    }
+
+    @Test
+    public void valiateUserPasswordAndUpdateIfNeededTestPasswordNull() {
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(null, userVoMock, null);
+
+        Mockito.verify(userVoMock, Mockito.times(0)).setPassword(Mockito.anyString());
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void valiateUserPasswordAndUpdateIfNeededTestBlankPassword() {
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("       ", userVoMock, null);
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void valiateUserPasswordAndUpdateIfNeededTestNoAdminAndNoCurrentPasswordProvided() {
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
+        Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
+        Mockito.doReturn(true).when(accountManagerImpl).isResourceDomainAdmin(accountMockId);
+
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, "  ");
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void valiateUserPasswordAndUpdateIfNeededTestNoUserAuthenticatorsConfigured() {
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.doReturn(true).when(accountManagerImpl).isRootAdmin(accountMockId);
+        Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
+
+        Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, null);
+    }
+
+    @Test
+    public void validateUserPasswordAndUpdateIfNeededTestRootAdminUpdatingUserPassword() {
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.doReturn(true).when(accountManagerImpl).isRootAdmin(accountMockId);
+        Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
+
+        String newPassword = "newPassword";
+
+        String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
+
+        Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
+
+        Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+        Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
+    }
+
+    @Test
+    public void validateUserPasswordAndUpdateIfNeededTestDomainAdminUpdatingUserPassword() {
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
+        Mockito.doReturn(true).when(accountManagerImpl).isDomainAdmin(accountMockId);
+
+        String newPassword = "newPassword";
+
+        String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
+
+        Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
+
+        Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+        Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
+    }
+
+    @Test
+    public void validateUserPasswordAndUpdateIfNeededTestUserUpdatingHisPassword() {
+        Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
+        Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
+        Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
+
+        String newPassword = "newPassword";
+        String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
+
+        Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
+
+        String currentPassword = "theCurrentPassword";
+        accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
+
+        Mockito.verify(accountManagerImpl, Mockito.times(1)).validateCurrentPassword(userVoMock, currentPassword);
+        Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
+    }
+
+    private String configureUserMockAuthenticators(String newPassword) {
+        accountManagerImpl._userPasswordEncoders = new ArrayList<>();
+        UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
+        String expectedUserPasswordAfterEncoded = "passwordEncodedByAuthenticator1";
+        Mockito.doReturn(expectedUserPasswordAfterEncoded).when(authenticatorMock1).encode(newPassword);
+
+        UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
+        Mockito.doReturn("passwordEncodedByAuthenticator2").when(authenticatorMock2).encode(newPassword);
+
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
+        return expectedUserPasswordAfterEncoded;
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void validateCurrentPasswordTestUserNotAuthenticatedWithProvidedCurrentPassword() {
+        Mockito.doReturn(Mockito.mock(AccountVO.class)).when(accountDaoMock).findById(accountMockId);
+        String newPassword = "newPassword";
+        configureUserMockAuthenticators(newPassword);
+
+        accountManagerImpl.validateCurrentPassword(userVoMock, "currentPassword");
+    }
+
+    @Test
+    public void validateCurrentPasswordTestUserAuthenticatedWithProvidedCurrentPasswordViaFirstAuthenticator() {
+        AccountVO accountVoMock = Mockito.mock(AccountVO.class);
+        long domainId = 14l;
+        Mockito.doReturn(domainId).when(accountVoMock).getDomainId();
+
+        Mockito.doReturn(accountVoMock).when(accountDaoMock).findById(accountMockId);
+        String username = "username";
+        Mockito.doReturn(username).when(userVoMock).getUsername();
+
+        accountManagerImpl._userPasswordEncoders = new ArrayList<>();
+        UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
+        UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
+
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
+
+        Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = new Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication>(true,
+                UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
+
+        String currentPassword = "currentPassword";
+        Mockito.doReturn(authenticationResult).when(authenticatorMock1).authenticate(username, currentPassword, domainId, null);
+
+        accountManagerImpl.validateCurrentPassword(userVoMock, currentPassword);
+
+        Mockito.verify(authenticatorMock1, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
+        Mockito.verify(authenticatorMock2, Mockito.times(0)).authenticate(username, currentPassword, domainId, null);
+    }
+
+    @Test
+    public void validateCurrentPasswordTestUserAuthenticatedWithProvidedCurrentPasswordViaSecondAuthenticator() {
+        AccountVO accountVoMock = Mockito.mock(AccountVO.class);
+        long domainId = 14l;
+        Mockito.doReturn(domainId).when(accountVoMock).getDomainId();
+
+        Mockito.doReturn(accountVoMock).when(accountDaoMock).findById(accountMockId);
+        String username = "username";
+        Mockito.doReturn(username).when(userVoMock).getUsername();
+
+        accountManagerImpl._userPasswordEncoders = new ArrayList<>();
+        UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
+        UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
+
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
+        accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
+
+        Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = new Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication>(true,
+                UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
+
+        String currentPassword = "currentPassword";
+        Mockito.doReturn(authenticationResult).when(authenticatorMock2).authenticate(username, currentPassword, domainId, null);
+
+        accountManagerImpl.validateCurrentPassword(userVoMock, currentPassword);
+
+        Mockito.verify(authenticatorMock1, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
+        Mockito.verify(authenticatorMock2, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
+    }
+
+}
diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java
new file mode 100644
index 0000000..48eb473
--- /dev/null
+++ b/server/src/test/java/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java
@@ -0,0 +1,198 @@
+// 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.user;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+
+import com.cloud.domain.DomainVO;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.CloudException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.Volume.Type;
+import com.cloud.storage.VolumeVO;
+import com.cloud.vm.UserVmManagerImpl;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+
+public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplTestBase {
+
+    private static final Long ACCOUNT_ID = 1l;
+    private static final String VOLUME_UUID = "vol-111111";
+
+    @Spy
+    @InjectMocks
+    UserVmManagerImpl _vmMgr;
+    Map<String, Object> oldFields = new HashMap<>();
+    UserVmVO vm = mock(UserVmVO.class);
+
+    // Configures the static fields of the UsageEventUtils class, Storing the
+    // previous values to be restored during the cleanup phase, to avoid
+    // interference with other unit tests.
+    protected UsageEventUtils setupUsageUtils() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+
+        _usageEventDao = new MockUsageEventDao();
+        UsageEventUtils utils = new UsageEventUtils();
+
+        List<String> usageUtilsFields = new ArrayList<String>();
+        usageUtilsFields.add("usageEventDao");
+        usageUtilsFields.add("accountDao");
+        usageUtilsFields.add("dcDao");
+        usageUtilsFields.add("configDao");
+
+        for (String fieldName : usageUtilsFields) {
+            try {
+                Field f = UsageEventUtils.class.getDeclaredField(fieldName);
+                f.setAccessible(true);
+                Field staticField = UsageEventUtils.class.getDeclaredField("s_" + fieldName);
+                staticField.setAccessible(true);
+                oldFields.put(f.getName(), staticField.get(null));
+                f.set(utils, this.getClass().getSuperclass().getDeclaredField("_" + fieldName).get(this));
+            } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+                e.printStackTrace();
+            }
+        }
+        Method method;
+        method = UsageEventUtils.class.getDeclaredMethod("init");
+        method.setAccessible(true);
+        method.invoke(utils);
+        return utils;
+    }
+
+    protected void defineMocksBehavior() throws AgentUnavailableException, ConcurrentOperationException, CloudException {
+
+        AccountVO account = new AccountVO();
+        account.setId(ACCOUNT_ID);
+        when(accountDaoMock.remove(ACCOUNT_ID)).thenReturn(true);
+        when(accountDaoMock.findById(ACCOUNT_ID)).thenReturn(account);
+
+        DomainVO domain = new DomainVO();
+        VirtualMachineEntity vmEntity = mock(VirtualMachineEntity.class);
+
+        when(_orchSrvc.getVirtualMachine(anyString())).thenReturn(vmEntity);
+        when(vmEntity.destroy(anyString(), anyBoolean())).thenReturn(true);
+
+        Mockito.doReturn(vm).when(_vmDao).findById(anyLong());
+
+        VolumeVO vol = new VolumeVO(VOLUME_UUID, 1l, 1l, 1l, 1l, 1l, "folder", "path", null, 50, Type.ROOT);
+        vol.setDisplayVolume(true);
+        List<VolumeVO> volumes = new ArrayList<>();
+        volumes.add(vol);
+
+        when(securityChecker.checkAccess(any(Account.class), any(ControlledEntity.class), any(AccessType.class), anyString())).thenReturn(true);
+
+        when(_userVmDao.findById(anyLong())).thenReturn(vm);
+        when(_userVmDao.listByAccountId(ACCOUNT_ID)).thenReturn(Arrays.asList(vm));
+        when(_userVmDao.findByUuid(any(String.class))).thenReturn(vm);
+
+        when(_volumeDao.findByInstance(anyLong())).thenReturn(volumes);
+
+        ServiceOfferingVO offering = mock(ServiceOfferingVO.class);
+        when(offering.getCpu()).thenReturn(500);
+        when(offering.getId()).thenReturn(1l);
+        when(offering.getCpu()).thenReturn(500);
+        when(offering.getRamSize()).thenReturn(500);
+        when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(offering);
+
+        when(_domainMgr.getDomain(anyLong())).thenReturn(domain);
+
+        Mockito.doReturn(true).when(_vmMgr).expunge(any(UserVmVO.class), anyLong(), any(Account.class));
+
+    }
+
+    @Before
+    public void init() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, AgentUnavailableException,
+    ConcurrentOperationException, CloudException {
+
+        setupUsageUtils();
+        defineMocksBehavior();
+    }
+
+    @After
+    // Restores static fields of the UsageEventUtil class to previous values.
+    public void cleanupUsageUtils() throws ReflectiveOperationException, SecurityException {
+
+        UsageEventUtils utils = new UsageEventUtils();
+        for (String fieldName : oldFields.keySet()) {
+            Field f = UsageEventUtils.class.getDeclaredField(fieldName);
+            f.setAccessible(true);
+            f.set(utils, oldFields.get(fieldName));
+        }
+        Method method = UsageEventUtils.class.getDeclaredMethod("init");
+        method.setAccessible(true);
+        method.invoke(utils);
+    }
+
+    protected List<UsageEventVO> deleteUserAccountRootVolumeUsageEvents(boolean vmDestroyedPrior) throws AgentUnavailableException, ConcurrentOperationException, CloudException {
+
+        when(vm.getState()).thenReturn(vmDestroyedPrior ? VirtualMachine.State.Destroyed : VirtualMachine.State.Running);
+        when(vm.getRemoved()).thenReturn(vmDestroyedPrior ? new Date() : null);
+        accountManagerImpl.deleteUserAccount(ACCOUNT_ID);
+
+        return _usageEventDao.listAll();
+    }
+
+    @Test
+    // If the VM is alerady destroyed, no events should get emitted
+    public void destroyedVMRootVolumeUsageEvent()
+            throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
+        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(true);
+        Assert.assertEquals(0, emittedEvents.size());
+    }
+
+    @Test
+    // If the VM is running, we should see one emitted event for the root
+    // volume.
+    public void runningVMRootVolumeUsageEvent()
+            throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
+        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(false);
+        Assert.assertEquals(1, emittedEvents.size());
+        UsageEventVO event = emittedEvents.get(0);
+        Assert.assertEquals(EventTypes.EVENT_VOLUME_DELETE, event.getType());
+        Assert.assertEquals(VOLUME_UUID, event.getResourceName());
+
+    }
+}
diff --git a/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java b/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java
new file mode 100644
index 0000000..885a23d
--- /dev/null
+++ b/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java
@@ -0,0 +1,222 @@
+// 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.user;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.configuration.dao.ResourceLimitDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.DataCenterVnetDao;
+import com.cloud.dc.dao.DedicatedResourceDao;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.network.as.AutoScaleManager;
+import com.cloud.network.dao.AccountGuestVlanMapDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.RemoteAccessVpnDao;
+import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.security.SecurityGroupManager;
+import com.cloud.network.security.dao.SecurityGroupDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.projects.ProjectManager;
+import com.cloud.projects.dao.ProjectAccountDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.SSHKeyPairDao;
+import com.cloud.user.dao.UserAccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.InstanceGroupDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+import com.cloud.vm.snapshot.dao.VMSnapshotDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AccountManagetImplTestBase {
+
+    @Mock
+    AccountDao accountDaoMock;
+    @Mock
+    ConfigurationDao _configDao;
+    @Mock
+    ResourceCountDao _resourceCountDao;
+    @Mock
+    UserDao userDaoMock;
+    @Mock
+    InstanceGroupDao _vmGroupDao;
+    @Mock
+    UserAccountDao userAccountDaoMock;
+    @Mock
+    VolumeDao _volumeDao;
+    @Mock
+    UserVmDao _userVmDao;
+    @Mock
+    VMTemplateDao _templateDao;
+    @Mock
+    NetworkDao _networkDao;
+    @Mock
+    SecurityGroupDao _securityGroupDao;
+    @Mock
+    VMInstanceDao _vmDao;
+    @Mock
+    protected SnapshotDao _snapshotDao;
+    @Mock
+    protected VMTemplateDao _vmTemplateDao;
+    @Mock
+    SecurityGroupManager _networkGroupMgr;
+    @Mock
+    NetworkOrchestrationService _networkMgr;
+    @Mock
+    SnapshotManager _snapMgr;
+    @Mock
+    TemplateManager _tmpltMgr;
+    @Mock
+    ConfigurationManager _configMgr;
+    @Mock
+    VirtualMachineManager _itMgr;
+    @Mock
+    RemoteAccessVpnDao _remoteAccessVpnDao;
+    @Mock
+    RemoteAccessVpnService _remoteAccessVpnMgr;
+    @Mock
+    VpnUserDao _vpnUser;
+    @Mock
+    DataCenterDao _dcDao;
+    @Mock
+    DomainManager _domainMgr;
+    @Mock
+    ProjectManager _projectMgr;
+    @Mock
+    ProjectDao _projectDao;
+    @Mock
+    AccountDetailsDao _accountDetailsDao;
+    @Mock
+    DomainDao _domainDao;
+    @Mock
+    ProjectAccountDao _projectAccountDao;
+    @Mock
+    IPAddressDao _ipAddressDao;
+    @Mock
+    VpcManager _vpcMgr;
+    @Mock
+    DomainRouterDao _routerDao;
+    @Mock
+    Site2SiteVpnManager _vpnMgr;
+    @Mock
+    AutoScaleManager _autoscaleMgr;
+    @Mock
+    VolumeApiService volumeService;
+    @Mock
+    AffinityGroupDao _affinityGroupDao;
+    @Mock
+    AccountGuestVlanMapDao _accountGuestVlanMapDao;
+    @Mock
+    DataCenterVnetDao _dataCenterVnetDao;
+    @Mock
+    ResourceLimitService _resourceLimitMgr;
+    @Mock
+    ResourceLimitDao _resourceLimitDao;
+    @Mock
+    DedicatedResourceDao _dedicatedDao;
+    @Mock
+    GlobalLoadBalancerRuleDao _gslbRuleDao;
+    @Mock
+    MessageBus _messageBus;
+    @Mock
+    VMSnapshotManager _vmSnapshotMgr;
+    @Mock
+    VMSnapshotDao _vmSnapshotDao;
+    @Mock
+    User callingUser;
+    @Mock
+    Account callingAccount;
+
+    @Mock
+    SecurityChecker securityChecker;
+    @Mock
+    UserAuthenticator userAuthenticator;
+    @Mock
+    ServiceOfferingDao _serviceOfferingDao;
+    @Mock
+    ServiceOfferingDao _offeringDao;
+    @Mock
+    OrchestrationService _orchSrvc;
+    @Mock
+    SSHKeyPairDao _sshKeyPairDao;
+
+    @Spy
+    @InjectMocks
+    AccountManagerImpl accountManagerImpl;
+    @Mock
+    UsageEventDao _usageEventDao;
+
+    @Before
+    public void setup() {
+        accountManagerImpl.setUserAuthenticators(Arrays.asList(userAuthenticator));
+        accountManagerImpl.setSecurityCheckers(Arrays.asList(securityChecker));
+        CallContext.register(callingUser, callingAccount);
+    }
+
+    @After
+    public void cleanup() {
+        CallContext.unregister();
+    }
+
+    public static Map<String, Field> getInheritedFields(Class<?> type) {
+        Map<String, Field> fields = new HashMap<>();
+        for (Class<?> c = type; c != null; c = c.getSuperclass()) {
+            for (Field f : c.getDeclaredFields()) {
+                fields.put(f.getName(), f);
+            }
+        }
+        return fields;
+    }
+}
diff --git a/server/test/com/cloud/user/DomainManagerImplTest.java b/server/src/test/java/com/cloud/user/DomainManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/user/DomainManagerImplTest.java
rename to server/src/test/java/com/cloud/user/DomainManagerImplTest.java
diff --git a/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java b/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java
new file mode 100644
index 0000000..4fbf752
--- /dev/null
+++ b/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java
@@ -0,0 +1,430 @@
+// 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.user;
+
+import java.util.List;
+import java.util.Map;
+import java.net.InetAddress;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+public class MockAccountManagerImpl extends ManagerBase implements Manager, AccountManager {
+
+    @Override
+    public boolean deleteUserAccount(long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public UserAccount disableUser(long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount enableUser(long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount lockUser(long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount updateUser(UpdateUserCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account enableAccount(String accountName, Long domainId, Long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account lockAccount(String accountName, Long domainId, Long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account updateAccount(UpdateAccountCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getSystemAccount() {
+        return new AccountVO();
+    }
+
+    @Override
+    public User getSystemUser() {
+        return new UserVO();
+    }
+
+    @Override
+    public boolean deleteUser(DeleteUserCmd deleteUserCmd) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean moveUser(MoveUserCmd moveUserCmd) {
+        return false;
+    }
+
+    @Override
+    public boolean moveUser(long id, Long domainId, long accountId) {
+        return false;
+    }
+
+    @Override
+    public boolean isAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getActiveAccountByName(String accountName, Long domainId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount getActiveUserAccount(String username, Long domainId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getActiveAccountById(long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getAccount(long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getActiveUser(long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getUserIncludingRemoved(long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isRootAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public User getActiveUserByRegistrationToken(String registrationToken) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void markUserRegistered(long userId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void checkAccess(Account account, Domain domain) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+
+    @Override
+    public UserAccount getUserAccountById(Long userId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void logoutUser(long userId) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters) {
+        return null;
+    }
+
+    @Override
+    public Pair<User, Account> findUserByApiKey(String apiKey) {
+        return null;
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
+        return null;
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(final long userId) {
+        return null;
+    }
+
+    @Override
+    public boolean enableAccount(long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
+            ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
+            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId,
+            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {
+        // TODO Auto-generated method stub
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.user.AccountService#getUserByApiKey(java.lang.String)
+     */
+    @Override
+    public UserAccount getUserByApiKey(String apiKey) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName,
+        short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId,
+                                         Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User createUser(String userName, String password, String firstName,
+            String lastName, String email, String timeZone, String accountName,
+            Long domainId, String userUUID) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override public User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
+                                     String userUUID, User.Source source) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RoleType getRoleType(Account account) {
+        return null;
+    }
+
+    @Override
+    public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isDomainAdmin(Long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isNormalUser(long accountId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<String> listAclGroupsByAccount(Long accountId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
+            ControlledEntity... entities) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getKeys(GetUserKeysCmd cmd) {
+        return null;
+    }
+
+    @Override
+    public void checkAccess(User user, ControlledEntity entity)
+        throws PermissionDeniedException {
+
+    }
+    @Override
+    public String getConfigComponentName() {
+        return null;
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return null;
+    }
+
+}
diff --git a/server/test/com/cloud/user/MockUsageEventDao.java b/server/src/test/java/com/cloud/user/MockUsageEventDao.java
similarity index 100%
rename from server/test/com/cloud/user/MockUsageEventDao.java
rename to server/src/test/java/com/cloud/user/MockUsageEventDao.java
diff --git a/server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java b/server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/vm/DeploymentPlanningManagerImplTest.java
rename to server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java
diff --git a/server/test/com/cloud/vm/FirstFitPlannerTest.java b/server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java
similarity index 100%
rename from server/test/com/cloud/vm/FirstFitPlannerTest.java
rename to server/src/test/java/com/cloud/vm/FirstFitPlannerTest.java
diff --git a/server/test/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
similarity index 100%
rename from server/test/com/cloud/vm/UserVmManagerImplTest.java
rename to server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java
diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerTest.java
similarity index 100%
rename from server/test/com/cloud/vm/UserVmManagerTest.java
rename to server/src/test/java/com/cloud/vm/UserVmManagerTest.java
diff --git a/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoImplTest.java b/server/src/test/java/com/cloud/vm/dao/UserVmCloneSettingDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/vm/dao/UserVmCloneSettingDaoImplTest.java
rename to server/src/test/java/com/cloud/vm/dao/UserVmCloneSettingDaoImplTest.java
diff --git a/server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java b/server/src/test/java/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java
rename to server/src/test/java/com/cloud/vm/dao/UserVmCloneSettingDaoTestConfiguration.java
diff --git a/server/test/com/cloud/vm/dao/UserVmDaoImplTest.java b/server/src/test/java/com/cloud/vm/dao/UserVmDaoImplTest.java
similarity index 100%
rename from server/test/com/cloud/vm/dao/UserVmDaoImplTest.java
rename to server/src/test/java/com/cloud/vm/dao/UserVmDaoImplTest.java
diff --git a/server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java b/server/src/test/java/com/cloud/vm/dao/UserVmDaoTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/vm/dao/UserVmDaoTestConfiguration.java
rename to server/src/test/java/com/cloud/vm/dao/UserVmDaoTestConfiguration.java
diff --git a/server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java b/server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
similarity index 100%
rename from server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
rename to server/src/test/java/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
rename to server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java
diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
new file mode 100644
index 0000000..b3027f2
--- /dev/null
+++ b/server/src/test/java/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -0,0 +1,980 @@
+// 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.vpc;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
+import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
+import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
+import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
+import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.GuestVlan;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.element.DnsServiceProvider;
+import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.user.User;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicSecondaryIp;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Component
+public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrchestrationService, NetworkService {
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+
+    @Inject
+    List<NetworkElement> _networkElements;
+
+    private static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
+    private static final Logger s_logger = Logger.getLogger(MockNetworkManagerImpl.class);
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#start()
+     */
+    @Override
+    public boolean start() {
+        for (NetworkElement element : _networkElements) {
+            Provider implementedProvider = element.getProvider();
+            if (implementedProvider != null) {
+                if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) {
+                    s_logger.error("Cannot start MapNetworkManager: Provider <-> NetworkElement must be a one-to-one map, " +
+                        "multiple NetworkElements found for Provider: " + implementedProvider.getName());
+                    return false;
+                }
+                s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName());
+            }
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
+     */
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#stop()
+     */
+    @Override
+    public boolean stop() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#getName()
+     */
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getIsolatedNetworksOwnedByAccountInZone(long, com.cloud.user.Account)
+     */
+    @Override
+    public List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#allocateIP(com.cloud.user.Account, long, java.lang.Long)
+     */
+    @Override
+    public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp) throws ResourceAllocationException, InsufficientAddressCapacityException,
+        ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
+        InsufficientAddressCapacityException, ConcurrentOperationException {
+        return null;
+    }
+
+    @Override
+    public boolean releasePortableIpAddress(long ipAddressId) {
+        return false;// TODO Auto-generated method stub
+    }
+
+    /* (non-Javadoc)
+    * @see com.cloud.network.NetworkService#releaseIpAddress(long)
+    */
+    @Override
+    public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#createGuestNetwork(com.cloud.api.commands.CreateNetworkCmd)
+     */
+    @Override
+    public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#searchForNetworks(com.cloud.api.commands.ListNetworksCmd)
+     */
+    @Override
+    public Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#deleteNetwork(long)
+     */
+    @Override
+    public boolean deleteNetwork(long networkId, boolean forced) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#restartNetwork(com.cloud.api.commands.RestartNetworkCmd, boolean)
+     */
+    @Override
+    public boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
+        InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getActiveNicsInNetwork(long)
+     */
+    @Override
+    public int getActiveNicsInNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getNetwork(long)
+     */
+    @Override
+    public Network getNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getIp(long)
+     */
+    @Override
+    public IpAddress getIp(long id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#updateGuestNetwork(long, java.lang.String, java.lang.String, com.cloud.user.Account, com.cloud.user.User, java.lang.String, java.lang.Long, java.lang.Boolean)
+     */
+    @Override
+    public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix,
+        Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID,boolean updateInSequence, boolean forced) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
+        return null;
+    }
+
+    @Override public Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+             * @see com.cloud.network.NetworkService#createPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.util.List, java.lang.String, java.lang.Long, java.util.List, java.lang.String)
+             */
+    @Override
+    public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange,
+        Long domainId, List<String> tags, String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#searchPhysicalNetworks(java.lang.Long, java.lang.Long, java.lang.String, java.lang.Long, java.lang.Long, java.lang.String)
+     */
+    @Override
+    public Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#updatePhysicalNetwork(java.lang.Long, java.lang.String, java.util.List, java.lang.String, java.lang.String)
+     */
+    @Override
+    public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#deletePhysicalNetwork(java.lang.Long)
+     */
+    @Override
+    public boolean deletePhysicalNetwork(Long id) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
+        // TODO Auto-generated method stub
+        return true;
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#listNetworkServices(java.lang.String)
+     */
+    @Override
+    public List<? extends Service> listNetworkServices(String providerName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#addProviderToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.Long, java.util.List)
+     */
+    @Override
+    public PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId,
+        List<String> enabledServices) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#listNetworkServiceProviders(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.Long)
+     */
+    @Override
+    public Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex,
+        Long pageSize) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#updateNetworkServiceProvider(java.lang.Long, java.lang.String, java.util.List)
+     */
+    @Override
+    public PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List<String> enabledServices) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#deleteNetworkServiceProvider(java.lang.Long)
+     */
+    @Override
+    public boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getPhysicalNetwork(java.lang.Long)
+     */
+    @Override
+    public PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getCreatedPhysicalNetwork(java.lang.Long)
+     */
+    @Override
+    public PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getPhysicalNetworkServiceProvider(java.lang.Long)
+     */
+    @Override
+    public PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getCreatedPhysicalNetworkServiceProvider(java.lang.Long)
+     */
+    @Override
+    public PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
+        String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getPhysicalNetworkTrafficType(java.lang.Long)
+     */
+    @Override
+    public PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#updatePhysicalNetworkTrafficType(java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#deletePhysicalNetworkTrafficType(java.lang.Long)
+     */
+    @Override
+    public boolean deletePhysicalNetworkTrafficType(Long id) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#listTrafficTypes(java.lang.Long)
+     */
+    @Override
+    public Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getExclusiveGuestNetwork(long)
+     */
+    @Override
+    public Network getExclusiveGuestNetwork(long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#listTrafficTypeImplementor(org.apache.cloudstack.api.commands.ListTrafficTypeImplementorsCmd)
+     */
+    @Override
+    public List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long, com.cloud.user.Account)
+     */
+    @Override
+    public List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#associateIPToNetwork(long, long)
+     */
+    @Override
+    public IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException,
+        ResourceUnavailableException, ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#createPrivateNetwork(java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long, java.lang.Long)
+     */
+    @Override
+    public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIP, String gateway,
+        String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException,
+        InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#setupNetwork(com.cloud.user.Account, com.cloud.offerings.NetworkOfferingVO, com.cloud.deploy.DeploymentPlan, java.lang.String, java.lang.String, boolean)
+     */
+    @Override
+    public List<NetworkVO> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
+        throws ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#setupNetwork(com.cloud.user.Account, com.cloud.offerings.NetworkOfferingVO, com.cloud.network.Network, com.cloud.deploy.DeploymentPlan, java.lang.String, java.lang.String, boolean, java.lang.Long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
+     */
+    @Override
+    public List<NetworkVO> setupNetwork(Account owner, NetworkOffering offering, Network predefined, DeploymentPlan plan, String name, String displayText,
+        boolean errorIfAlreadySetup, Long domainId, ACLType aclType, Boolean subdomainAccess, Long vpcId, Boolean isNetworkDisplayEnabled)
+        throws ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#allocate(com.cloud.vm.VirtualMachineProfile, java.util.List)
+     */
+    @Override
+    public void allocate(VirtualMachineProfile vm, LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions)
+            throws InsufficientCapacityException, ConcurrentOperationException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void configureExtraDhcpOptions(Network network, long nicId, Map<Integer, String> extraDhcpOptions) {
+
+    }
+
+    @Override public void configureExtraDhcpOptions(Network network, long nicId) {
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#prepare(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+     */
+    @Override
+    public void prepare(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
+        ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#release(com.cloud.vm.VirtualMachineProfile, boolean)
+     */
+    @Override
+    public void release(VirtualMachineProfile vmProfile, boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#cleanupNics(com.cloud.vm.VirtualMachineProfile)
+     */
+    @Override
+    public void cleanupNics(VirtualMachineProfile vm) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#expungeNics(com.cloud.vm.VirtualMachineProfile)
+     */
+    @Override
+    public void expungeNics(VirtualMachineProfile vm) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#getNicProfiles(com.cloud.vm.VirtualMachine)
+     */
+    @Override
+    public List<NicProfile> getNicProfiles(VirtualMachine vm) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getSystemVMAccessDetails(VirtualMachine vm) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#implementNetwork(long, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+     */
+    @Override
+    public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
+        ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Integer, String> getExtraDhcpOptions(long nicId) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#shutdownNetwork(long, com.cloud.vm.ReservationContext, boolean)
+     */
+    @Override
+    public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#destroyNetwork(long, com.cloud.vm.ReservationContext)
+     */
+    @Override
+    public boolean destroyNetwork(long networkId, ReservationContext context, boolean forced) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#createGuestNetwork(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.cloud.user.Account, java.lang.Long, com.cloud.network.PhysicalNetwork, long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
+     */
+    @Override
+    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
+                                      Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
+                                      String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
+        ResourceAllocationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#getPasswordResetProvider(com.cloud.network.Network)
+     */
+    @Override
+    public UserDataServiceProvider getPasswordResetProvider(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserDataServiceProvider getSSHKeyResetProvider(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#startNetwork(long, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
+     */
+    @Override
+    public boolean startNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
+        InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#reallocate(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DataCenterDeployment)
+     */
+    @Override
+    public boolean reallocate(VirtualMachineProfile vm, DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void saveExtraDhcpOptions(String networkUuid, Long nicId, Map<String, Map<Integer, String>> extraDhcpOptionMap) {
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#allocateNic(com.cloud.vm.NicProfile, com.cloud.network.Network, java.lang.Boolean, int, com.cloud.vm.VirtualMachineProfile)
+     */
+    @Override
+    public Pair<NicProfile, Integer> allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, VirtualMachineProfile vm)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context, long nicId, Network network)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
+        ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#removeNic(com.cloud.vm.VirtualMachineProfile, com.cloud.vm.Nic)
+     */
+    @Override
+    public void removeNic(VirtualMachineProfile vm, Nic nic) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+    * @see com.cloud.network.NetworkManager#setupDns(com.cloud.network.Network, com.cloud.network.Network.Provider)
+    */
+    @Override
+    public boolean setupDns(Network network, Provider provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.vm.Nic)
+     */
+    @Override
+    public void releaseNic(VirtualMachineProfile vmProfile, Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean, boolean)
+     */
+    @Override
+    public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile vmProfile, boolean prepare)
+        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
+        ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#convertNetworkToNetworkProfile(long)
+     */
+    @Override
+    public NetworkProfile convertNetworkToNetworkProfile(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#restartNetwork(java.lang.Long, com.cloud.user.Account, com.cloud.user.User, boolean)
+     */
+    @Override
+    public boolean restartNetwork(Long networkId, Account callerAccount, User callerUser, boolean cleanup) throws ConcurrentOperationException,
+        ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#shutdownNetworkElementsAndResources(com.cloud.vm.ReservationContext, boolean, com.cloud.network.NetworkVO)
+     */
+    @Override
+    public boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean b, Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#implementNetworkElementsAndResources(com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext, com.cloud.network.NetworkVO, com.cloud.offerings.NetworkOfferingVO)
+     */
+    @Override
+    public void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, Network network, NetworkOffering findById)
+        throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkManager#finalizeServicesAndProvidersForNetwork(com.cloud.offering.NetworkOffering, java.lang.Long)
+     */
+    @Override
+    public Map<String, String> finalizeServicesAndProvidersForNetwork(NetworkOffering offering, Long physicalNetworkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isNetworkInlineMode(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<Provider> getProvidersForServiceInNetwork(Network network, Service service) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public StaticNatServiceProvider getStaticNatProviderForNetwork(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkService#getNetwork(java.lang.String)
+     */
+    @Override
+    public Network getNetwork(String networkUuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isSecondaryIpSetForNic(long nicId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean releaseSecondaryIpFromNic(long ipAddressId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public List<? extends Nic> listVmNics(long vmId, Long nicId, Long networkId, String keyword) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<? extends Nic> listNics(ListNicsCmd listNicsCmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Network.Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public NicVO savePlaceholderNic(Network network, String ip4Address, String ip6Address, Type vmType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DhcpServiceProvider getDhcpServiceProvider(Network network) {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public DnsServiceProvider getDnsServiceProvider(Network network) {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void removeDhcpServiceInSubnet(Nic nic) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType) {
+        return false;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest) {
+        return;
+    }
+
+    @Override
+    public boolean canUpdateInSequence(Network network, boolean forced) {
+        return false;
+    }
+
+    @Override
+    public List<String> getServicesNotSupportedInNewOffering(Network network, long newNetworkOfferingId) {
+        return null;
+    }
+
+    @Override
+    public void cleanupConfigForServicesInNetwork(List<String> services, Network network) {
+        return;
+    }
+
+    @Override
+    public void configureUpdateInSequence(Network network) {
+        return;
+    }
+
+    @Override
+    public int getResourceCount(Network network) {
+        return 0;
+    }
+
+    @Override public List<NetworkGuru> getNetworkGurus() {
+        return null;
+    }
+
+    @Override
+    public void destroyExpendableRouters(final List<? extends VirtualRouter> routers, final ReservationContext context) throws ResourceUnavailableException {
+    }
+
+    @Override
+    public boolean areRoutersRunning(final List<? extends VirtualRouter> routers) {
+        return false;
+    }
+
+    @Override
+    public void cleanupNicDhcpDnsEntry(Network network, VirtualMachineProfile vmProfile, NicProfile nicProfile) {
+    }
+
+    @Override
+    public void finalizeUpdateInSequence(Network network, boolean success) {
+        return;
+    }
+
+    @Override
+    public void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void commitNicForMigration(VirtualMachineProfile src, VirtualMachineProfile dst) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void rollbackNicForMigration(VirtualMachineProfile src, VirtualMachineProfile dst) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public IpAddress updateIP(Long id, String customId, Boolean displayIp) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) {
+        return false;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd) {
+        return null;
+    }
+
+    @Override
+    public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
+        return true;
+    }
+
+    @Override
+    public AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException {
+        return null;
+    }
+}
diff --git a/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java
new file mode 100644
index 0000000..56670d2
--- /dev/null
+++ b/server/src/test/java/com/cloud/vpc/MockNetworkModelImpl.java
@@ -0,0 +1,925 @@
+// 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.vpc;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import com.cloud.dc.Vlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.IpAddresses;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Detail;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
+import com.cloud.user.Account;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
+
+public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
+
+    @Inject
+    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
+     */
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#start()
+     */
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#stop()
+     */
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.utils.component.Manager#getName()
+     */
+    @Override
+    public String getName() {
+        return "MockNetworkModelImpl";
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
+     */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
+     */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
+
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSystemAccountNetworkOfferings(java.lang.String[])
+     */
+    @Override
+    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNics(long)
+     */
+    @Override
+    public List<? extends Nic> getNics(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNextAvailableMacAddressInNetwork(long)
+     */
+    @Override
+    public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPublicIpAddress(long)
+     */
+    @Override
+    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPodVlans(long)
+     */
+    @Override
+    public List<? extends Vlan> listPodVlans(long podId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksUsedByVm(long, boolean)
+     */
+    @Override
+    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicInNetwork(long, long)
+     */
+    @Override
+    public Nic getNicInNetwork(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicsForTraffic(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultNetworkForVm(long)
+     */
+    @Override
+    public Network getDefaultNetworkForVm(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultNic(long)
+     */
+    @Override
+    public Nic getDefaultNic(long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getUserDataUpdateProvider(com.cloud.network.Network)
+     */
+    @Override
+    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#networkIsConfiguredForExternalNetworking(long, long)
+     */
+    @Override
+    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkServiceCapabilities(long, com.cloud.network.Network.Service)
+     */
+    @Override
+    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isSharedNetworkWithoutServices(long networkId) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service[])
+     */
+    @Override
+    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
+        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long)
+     */
+    @Override
+    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long)
+     */
+    @Override
+    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpOfNetworkElementInVirtualNetwork(long, long)
+     */
+    @Override
+    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksForAccount(long, long, com.cloud.network.Network.GuestType)
+     */
+    @Override
+    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listAllNetworksInAllZonesByType(com.cloud.network.Network.GuestType)
+     */
+    @Override
+    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getStartIpAddress(long)
+     */
+    @Override
+    public String getStartIpAddress(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpInNetwork(long, long)
+     */
+    @Override
+    public String getIpInNetwork(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpInNetworkIncludingRemoved(long, long)
+     */
+    @Override
+    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPodIdForVlan(long)
+     */
+    @Override
+    public Long getPodIdForVlan(long vlanDbId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworkOfferingsForUpgrade(long)
+     */
+    @Override
+    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isSecurityGroupSupportedInNetwork(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isSecurityGroupSupportedInNetwork(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderSupportServiceInNetwork(long, com.cloud.network.Network.Service, com.cloud.network.Network.Provider)
+     */
+    @Override
+    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderEnabledInPhysicalNetwork(long, java.lang.String)
+     */
+    @Override
+    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkTag(com.cloud.hypervisor.Hypervisor.HypervisorType, com.cloud.network.Network)
+     */
+    @Override
+    public String getNetworkTag(HypervisorType hType, Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getElementServices(com.cloud.network.Network.Provider)
+     */
+    @Override
+    public List<Service> getElementServices(Provider provider) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canElementEnableIndividualServices(com.cloud.network.Network.Provider)
+     */
+    @Override
+    public boolean canElementEnableIndividualServices(Provider provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesSupportedInNetwork(long, com.cloud.network.Network.Service[])
+     */
+    @Override
+    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkSystem(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isNetworkSystem(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceCapabilities(com.cloud.offering.NetworkOffering, com.cloud.network.Network.Service)
+     */
+    @Override
+    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNetworkId(com.cloud.network.Network)
+     */
+    @Override
+    public Long getPhysicalNetworkId(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAllowSubdomainAccessGlobal()
+     */
+    @Override
+    public boolean getAllowSubdomainAccessGlobal() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderForNetwork(com.cloud.network.Network.Provider, long)
+     */
+    @Override
+    public boolean isProviderForNetwork(Provider provider, long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isProviderForNetworkOffering(com.cloud.network.Network.Provider, long)
+     */
+    @Override
+    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canProviderSupportServices(java.util.Map)
+     */
+    @Override
+    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNetworkInfo(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canAddDefaultSecurityGroup()
+     */
+    @Override
+    public boolean canAddDefaultSecurityGroup() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworkOfferingServices(long)
+     */
+    @Override
+    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
+        if (networkOfferingId == 2) {
+            return new ArrayList<Service>();
+        }
+
+        List<Service> services = new ArrayList<Service>();
+        services.add(Service.SourceNat);
+        return services;
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#areServicesEnabledInZone(long, com.cloud.offering.NetworkOffering, java.util.List)
+     */
+    @Override
+    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#checkIpForService(com.cloud.network.IPAddressVO, com.cloud.network.Network.Service, java.lang.Long)
+     */
+    @Override
+    public boolean checkIpForService(IpAddress ip, Service service, Long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+         * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String)
+         */
+    @Override
+    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultUniqueProviderForService(java.lang.String)
+     */
+    @Override
+    public Provider getDefaultUniqueProviderForService(String serviceName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#checkNetworkPermissions(com.cloud.user.Account, com.cloud.network.Network)
+     */
+    @Override
+    public void checkNetworkPermissions(Account owner, Network network) {
+        // TODO Auto-generated method stub
+
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultStorageTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultPublicTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultGuestTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
+     */
+    @Override
+    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getElementImplementingProvider(java.lang.String)
+     */
+    @Override
+    public NetworkElement getElementImplementingProvider(String providerName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAccountNetworkDomain(long, long)
+     */
+    @Override
+    public String getAccountNetworkDomain(long accountId, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNtwkOffDistinctProviders(long)
+     */
+    @Override
+    public List<Provider> getNtwkOffDistinctProviders(long ntwkOffId) {
+        return new ArrayList<Provider>();
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean)
+     */
+    @Override
+    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getPhysicalNtwksSupportingTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isPrivateGateway(com.cloud.vm.Nic)
+     */
+    @Override
+    public boolean isPrivateGateway(long ntwkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkCapabilities(long)
+     */
+    @Override
+    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSystemNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDedicatedNetworkDomain(long)
+     */
+    @Override
+    public Long getDedicatedNetworkDomain(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceProvidersMap(long)
+     */
+    @Override
+    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listSupportedNetworkServiceProviders(java.lang.String)
+     */
+    @Override
+    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#listNetworksByVpc(long)
+     */
+    @Override
+    public List<? extends Network> listNetworksByVpc(long vpcId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#canUseForDeploy(com.cloud.network.Network)
+     */
+    @Override
+    public boolean canUseForDeploy(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getExclusiveGuestNetwork(long)
+     */
+    @Override
+    public Network getExclusiveGuestNetwork(long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetworkRate(long, java.lang.Long)
+     */
+    @Override
+    public Integer getNetworkRate(long networkId, Long vmId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isVmPartOfNetwork(long, long)
+     */
+    @Override
+    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDefaultPhysicalNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
+     */
+    @Override
+    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNetwork(long)
+     */
+    @Override
+    public Network getNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIp(long)
+     */
+    @Override
+    public IpAddress getIp(long sourceIpAddressId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkAvailableInDomain(long, long)
+     */
+    @Override
+    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getNicProfile(com.cloud.vm.VirtualMachine, long, java.lang.String)
+     */
+    @Override
+    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getAvailableIps(com.cloud.network.Network, java.lang.String)
+     */
+    @Override
+    public Set<Long> getAvailableIps(Network network, String requestedIp) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getDomainNetworkDomain(long, long)
+     */
+    @Override
+    public String getDomainNetworkDomain(long domainId, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getIpToServices(java.util.List, boolean, boolean)
+     */
+    @Override
+    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getProviderToIpList(com.cloud.network.Network, java.util.Map)
+     */
+    @Override
+    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#getSourceNatIpAddressForGuestNetwork(com.cloud.user.Account, com.cloud.network.Network)
+     */
+    @Override
+    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.NetworkModel#isNetworkInlineMode(com.cloud.network.Network)
+     */
+    @Override
+    public boolean isNetworkInlineMode(Network network) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean areThereIPv6AddressAvailableInNetwork(long networkId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isIP6AddressAvailableInVlan(long vlanId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public String getStartIpv6Address(long id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isProviderEnabledInZone(long zoneId, String provider) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Nic getPlaceholderNicForRouter(Network network, Long podId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<String> getUsedIpsInNetwork(Network network) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Detail, String> getNtwkOffDetails(long offId) {
+        return null;
+    }
+
+    @Override
+    public IsolationType[] listNetworkIsolationMethods() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
+        return null;
+    }
+
+    @Override
+    public boolean getExecuteInSeqNtwkElmtCmd() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isNetworkReadyForGc(long networkId) {
+        return true;
+    }
+
+    @Override
+    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
+        return false;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
+        return null;
+    }
+
+    @Override
+    public String getValidNetworkCidr(Network guestNetwork) {
+        return null;
+    }
+
+}
diff --git a/server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/MockResourceLimitManagerImpl.java
rename to server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java
diff --git a/server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java
rename to server/src/test/java/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java
diff --git a/server/test/com/cloud/vpc/MockSite2SiteVpnServiceProvider.java b/server/src/test/java/com/cloud/vpc/MockSite2SiteVpnServiceProvider.java
similarity index 100%
rename from server/test/com/cloud/vpc/MockSite2SiteVpnServiceProvider.java
rename to server/src/test/java/com/cloud/vpc/MockSite2SiteVpnServiceProvider.java
diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
similarity index 100%
rename from server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
rename to server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
diff --git a/server/src/test/java/com/cloud/vpc/NetworkACLManagerTest.java b/server/src/test/java/com/cloud/vpc/NetworkACLManagerTest.java
new file mode 100644
index 0000000..ca1ddc6
--- /dev/null
+++ b/server/src/test/java/com/cloud/vpc/NetworkACLManagerTest.java
@@ -0,0 +1,323 @@
+// 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.vpc;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkACLServiceProvider;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.NetworkACLItem.State;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.NetworkACLManagerImpl;
+import com.cloud.network.vpc.NetworkACLVO;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.VpcGateway;
+import com.cloud.network.vpc.VpcGatewayVO;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcService;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.EntityManager;
+
+import junit.framework.TestCase;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class NetworkACLManagerTest extends TestCase {
+    @Inject
+    NetworkACLManager _aclMgr;
+
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    NetworkACLDao _networkACLDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    EntityManager _entityMgr;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    List<NetworkACLServiceProvider> _networkAclElements;
+    @Inject
+    VpcService _vpcSvc;
+    @Inject
+    VpcGatewayDao _vpcGatewayDao;
+
+    private NetworkACLVO acl;
+    private NetworkACLItemVO aclItem;
+
+    @Override
+    @Before
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+        final Account account = new AccountVO("testaccount", 1, "testdomain", (short)0, UUID.randomUUID().toString());
+        final UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
+
+        CallContext.register(user, account);
+        acl = Mockito.mock(NetworkACLVO.class);
+        aclItem = Mockito.mock(NetworkACLItemVO.class);
+    }
+
+    @Override
+    @After
+    public void tearDown() {
+        CallContext.unregister();
+    }
+
+    @Test
+    public void testCreateACL() throws Exception {
+        Mockito.when(_networkACLDao.persist(Matchers.any(NetworkACLVO.class))).thenReturn(acl);
+        assertNotNull(_aclMgr.createNetworkACL("acl_new", "acl desc", 1L, true));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testApplyACL() throws Exception {
+        final NetworkVO network = Mockito.mock(NetworkVO.class);
+        Mockito.when(_networkDao.findById(Matchers.anyLong())).thenReturn(network);
+        Mockito.when(_networkModel.isProviderSupportServiceInNetwork(Matchers.anyLong(), Matchers.any(Network.Service.class), Matchers.any(Network.Provider.class))).thenReturn(true);
+        Mockito.when(_networkAclElements.get(0).applyNetworkACLs(Matchers.any(Network.class), Matchers.anyList())).thenReturn(true);
+        assertTrue(_aclMgr.applyACLToNetwork(1L));
+    }
+
+    @Test
+    public void testApplyNetworkACL() throws Exception {
+        driveTestApplyNetworkACL(true, true, true);
+        driveTestApplyNetworkACL(false, false, true);
+        driveTestApplyNetworkACL(false, true, false);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void driveTestApplyNetworkACL(final boolean result, final boolean applyNetworkACLs, final boolean applyACLToPrivateGw) throws Exception {
+        // In order to test ONLY our scope method, we mock the others
+        final NetworkACLManager aclManager = Mockito.spy(_aclMgr);
+
+        // Prepare
+        // Reset mocked objects to reuse
+        Mockito.reset(_networkACLItemDao);
+
+        // Make sure it is handled
+        final long aclId = 1L;
+        final NetworkVO network = Mockito.mock(NetworkVO.class);
+        final List<NetworkVO> networks = new ArrayList<NetworkVO>();
+        networks.add(network);
+        Mockito.when(_networkDao.listByAclId(Matchers.anyLong())).thenReturn(networks);
+        Mockito.when(_networkDao.findById(Matchers.anyLong())).thenReturn(network);
+        Mockito.when(_networkModel.isProviderSupportServiceInNetwork(Matchers.anyLong(), Matchers.any(Network.Service.class), Matchers.any(Network.Provider.class))).thenReturn(true);
+        Mockito.when(_networkAclElements.get(0).applyNetworkACLs(Matchers.any(Network.class), Matchers.anyList())).thenReturn(applyNetworkACLs);
+
+        // Make sure it applies ACL to private gateway
+        final List<VpcGatewayVO> vpcGateways = new ArrayList<VpcGatewayVO>();
+        final VpcGatewayVO vpcGateway = Mockito.mock(VpcGatewayVO.class);
+        final PrivateGateway privateGateway = Mockito.mock(PrivateGateway.class);
+        Mockito.when(_vpcSvc.getVpcPrivateGateway(Mockito.anyLong())).thenReturn(privateGateway);
+        vpcGateways.add(vpcGateway);
+        Mockito.when(_vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private)).thenReturn(vpcGateways);
+
+        // Create 4 rules to test all 4 scenarios: only revoke should
+        // be deleted, only add should update
+        final List<NetworkACLItemVO> rules = new ArrayList<NetworkACLItemVO>();
+        final NetworkACLItemVO ruleActive = Mockito.mock(NetworkACLItemVO.class);
+        final NetworkACLItemVO ruleStaged = Mockito.mock(NetworkACLItemVO.class);
+        final NetworkACLItemVO rule2Revoke = Mockito.mock(NetworkACLItemVO.class);
+        final NetworkACLItemVO rule2Add = Mockito.mock(NetworkACLItemVO.class);
+        Mockito.when(ruleActive.getState()).thenReturn(NetworkACLItem.State.Active);
+        Mockito.when(ruleStaged.getState()).thenReturn(NetworkACLItem.State.Staged);
+        Mockito.when(rule2Add.getState()).thenReturn(NetworkACLItem.State.Add);
+        Mockito.when(rule2Revoke.getState()).thenReturn(NetworkACLItem.State.Revoke);
+        rules.add(ruleActive);
+        rules.add(ruleStaged);
+        rules.add(rule2Add);
+        rules.add(rule2Revoke);
+
+        final long revokeId = 8;
+        Mockito.when(rule2Revoke.getId()).thenReturn(revokeId);
+
+        final long addId = 9;
+        Mockito.when(rule2Add.getId()).thenReturn(addId);
+        Mockito.when(_networkACLItemDao.findById(addId)).thenReturn(rule2Add);
+
+        Mockito.when(_networkACLItemDao.listByACL(aclId)).thenReturn(rules);
+        // Mock methods to avoid
+        Mockito.doReturn(applyACLToPrivateGw).when(aclManager).applyACLToPrivateGw(privateGateway);
+
+        // Execute
+        assertEquals("Result was not congruent with applyNetworkACLs and applyACLToPrivateGw", result, aclManager.applyNetworkACL(aclId));
+
+        // Assert if conditions met, network ACL was applied
+        final int timesProcessingDone = applyNetworkACLs && applyACLToPrivateGw ? 1 : 0;
+        Mockito.verify(_networkACLItemDao, Mockito.times(timesProcessingDone)).remove(revokeId);
+        Mockito.verify(rule2Add, Mockito.times(timesProcessingDone)).setState(NetworkACLItem.State.Active);
+        Mockito.verify(_networkACLItemDao, Mockito.times(timesProcessingDone)).update(addId, rule2Add);
+    }
+
+    @Test
+    public void testRevokeACLItem() throws Exception {
+        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
+        assertTrue(_aclMgr.revokeNetworkACLItem(1L));
+    }
+
+    @Test
+    public void deleteNonEmptyACL() throws Exception {
+        final List<NetworkACLItemVO> aclItems = new ArrayList<NetworkACLItemVO>();
+        aclItems.add(aclItem);
+        Mockito.when(_networkACLItemDao.listByACL(Matchers.anyLong())).thenReturn(aclItems);
+        Mockito.when(acl.getId()).thenReturn(3l);
+        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
+        Mockito.when(aclItem.getState()).thenReturn(State.Add);
+        Mockito.when(aclItem.getId()).thenReturn(3l);
+        Mockito.when(_networkACLDao.remove(Matchers.anyLong())).thenReturn(true);
+
+        final boolean result = _aclMgr.deleteNetworkACL(acl);
+
+        Mockito.verify(aclItem, Mockito.times(4)).getState();
+
+        assertTrue("Operation should be successfull!", result);
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {NetworkACLManagerImpl.class}, includeFilters = {
+            @ComponentScan.Filter(value = NetworkACLTestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+    public static class NetworkACLTestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        @Bean
+        public AccountManager accountManager() {
+            return Mockito.mock(AccountManager.class);
+        }
+
+        @Bean
+        public NetworkOrchestrationService networkManager() {
+            return Mockito.mock(NetworkOrchestrationService.class);
+        }
+
+        @Bean
+        public NetworkModel networkModel() {
+            return Mockito.mock(NetworkModel.class);
+        }
+
+        @Bean
+        public VpcManager vpcManager() {
+            return Mockito.mock(VpcManager.class);
+        }
+
+        @Bean
+        public EntityManager entityManager() {
+            return Mockito.mock(EntityManager.class);
+        }
+
+        @Bean
+        public ResourceTagDao resourceTagDao() {
+            return Mockito.mock(ResourceTagDao.class);
+        }
+
+        @Bean
+        public NetworkACLDao networkACLDao() {
+            return Mockito.mock(NetworkACLDao.class);
+        }
+
+        @Bean
+        public NetworkACLItemDao networkACLItemDao() {
+            return Mockito.mock(NetworkACLItemDao.class);
+        }
+
+        @Bean
+        public NetworkDao networkDao() {
+            return Mockito.mock(NetworkDao.class);
+        }
+
+        @Bean
+        public ConfigurationManager configMgr() {
+            return Mockito.mock(ConfigurationManager.class);
+        }
+
+        @Bean
+        public NetworkACLServiceProvider networkElements() {
+            return Mockito.mock(NetworkACLServiceProvider.class);
+        }
+
+        @Bean
+        public VpcGatewayDao vpcGatewayDao() {
+            return Mockito.mock(VpcGatewayDao.class);
+        }
+
+        @Bean
+        public VpcService vpcService() {
+            return Mockito.mock(VpcService.class);
+        }
+
+        @Bean
+        public MessageBus messageBus() {
+            return Mockito.mock(MessageBus.class);
+        }
+
+        public static class Library implements TypeFilter {
+            @Override
+            public boolean match(final MetadataReader mdr, final MetadataReaderFactory arg1) throws IOException {
+                mdr.getClassMetadata().getClassName();
+                final ComponentScan cs = NetworkACLTestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+    }
+
+}
diff --git a/server/src/test/java/com/cloud/vpc/NetworkACLServiceTest.java b/server/src/test/java/com/cloud/vpc/NetworkACLServiceTest.java
new file mode 100644
index 0000000..35a94a2
--- /dev/null
+++ b/server/src/test/java/com/cloud/vpc/NetworkACLServiceTest.java
@@ -0,0 +1,200 @@
+// 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.vpc;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.NetworkACLService;
+import com.cloud.network.vpc.NetworkACLServiceImpl;
+import com.cloud.network.vpc.NetworkACLVO;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcService;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcGatewayDao;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.EntityManager;
+
+import junit.framework.TestCase;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class NetworkACLServiceTest extends TestCase {
+
+    @Inject
+    private NetworkACLService _aclService;
+    @Inject
+    private NetworkACLManager _networkAclMgr;
+    @Inject
+    private NetworkACLDao _networkACLDao;
+    @Inject
+    private NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    private EntityManager _entityMgr;
+
+    private NetworkACLVO acl;
+    private NetworkACLItemVO aclItem;
+
+    @Override
+    @Before
+    public void setUp() {
+        ComponentContext.initComponentsLifeCycle();
+        Account account = new AccountVO("testaccount", 1, "testdomain", (short)0, UUID.randomUUID().toString());
+        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
+
+        CallContext.register(user, account);
+    }
+
+    @Override
+    @After
+    public void tearDown() {
+        CallContext.unregister();
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testDeleteDefaultACL() throws Exception {
+        Mockito.when(_networkACLDao.findById(Matchers.anyLong())).thenReturn(acl);
+        Mockito.when(_networkAclMgr.deleteNetworkACL(acl)).thenReturn(true);
+        _aclService.deleteNetworkACL(1L);
+    }
+
+    @Test
+    public void testDeleteACLItem() throws Exception {
+        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
+        Mockito.when(_networkAclMgr.getNetworkACL(Matchers.anyLong())).thenReturn(acl);
+        Mockito.when(_networkAclMgr.revokeNetworkACLItem(Matchers.anyLong())).thenReturn(true);
+        Mockito.when(_entityMgr.findById(Mockito.eq(Vpc.class), Mockito.anyLong())).thenReturn(new VpcVO());
+        assertTrue(_aclService.revokeNetworkACLItem(1L));
+    }
+
+    @Configuration
+    @ComponentScan(basePackageClasses = {NetworkACLServiceImpl.class}, includeFilters = {
+            @ComponentScan.Filter(value = NetworkACLTestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+    public static class NetworkACLTestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+        @Bean
+        public EntityManager entityManager() {
+            return Mockito.mock(EntityManager.class);
+        }
+
+        @Bean
+        public AccountManager accountManager() {
+            return Mockito.mock(AccountManager.class);
+        }
+
+        @Bean
+        public NetworkOrchestrationService networkManager() {
+            return Mockito.mock(NetworkOrchestrationService.class);
+        }
+
+        @Bean
+        public NetworkModel networkModel() {
+            return Mockito.mock(NetworkModel.class);
+        }
+
+        @Bean
+        public VpcManager vpcManager() {
+            return Mockito.mock(VpcManager.class);
+        }
+
+        @Bean
+        public ResourceTagDao resourceTagDao() {
+            return Mockito.mock(ResourceTagDao.class);
+        }
+
+        @Bean
+        public NetworkACLDao networkACLDao() {
+            return Mockito.mock(NetworkACLDao.class);
+        }
+
+        @Bean
+        public NetworkACLItemDao networkACLItemDao() {
+            return Mockito.mock(NetworkACLItemDao.class);
+        }
+
+        @Bean
+        public NetworkDao networkDao() {
+            return Mockito.mock(NetworkDao.class);
+        }
+
+        @Bean
+        public NetworkACLManager networkACLManager() {
+            return Mockito.mock(NetworkACLManager.class);
+        }
+
+        @Bean
+        public VpcGatewayDao vpcGatewayDao() {
+            return Mockito.mock(VpcGatewayDao.class);
+        }
+
+        @Bean
+        public VpcDao vpcDao() {
+            return Mockito.mock(VpcDao.class);
+        }
+
+        @Bean
+        public VpcService vpcService() {
+            return Mockito.mock(VpcService.class);
+        }
+
+        public static class Library implements TypeFilter {
+            @Override
+            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+                mdr.getClassMetadata().getClassName();
+                ComponentScan cs = NetworkACLTestConfiguration.class.getAnnotation(ComponentScan.class);
+                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+            }
+        }
+    }
+
+}
diff --git a/server/test/com/cloud/vpc/Site2SiteVpnTest.java b/server/src/test/java/com/cloud/vpc/Site2SiteVpnTest.java
similarity index 100%
rename from server/test/com/cloud/vpc/Site2SiteVpnTest.java
rename to server/src/test/java/com/cloud/vpc/Site2SiteVpnTest.java
diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/src/test/java/com/cloud/vpc/VpcApiUnitTest.java
similarity index 100%
rename from server/test/com/cloud/vpc/VpcApiUnitTest.java
rename to server/src/test/java/com/cloud/vpc/VpcApiUnitTest.java
diff --git a/server/test/com/cloud/vpc/VpcTestConfiguration.java b/server/src/test/java/com/cloud/vpc/VpcTestConfiguration.java
similarity index 100%
rename from server/test/com/cloud/vpc/VpcTestConfiguration.java
rename to server/src/test/java/com/cloud/vpc/VpcTestConfiguration.java
diff --git a/server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockConfigurationDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockConfigurationDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockConfigurationDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockNetworkDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockNetworkDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkOfferingServiceMapDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockNetworkOfferingServiceMapDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockNetworkOfferingServiceMapDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockNetworkOfferingServiceMapDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockNetworkServiceMapDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockVpcDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockVpcDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockVpcOfferingDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockVpcOfferingDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java b/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
rename to server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
diff --git a/server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java b/server/src/test/java/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java
similarity index 100%
rename from server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java
rename to server/src/test/java/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java
diff --git a/server/test/org/apache/cloudstack/acl/RoleManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/acl/RoleManagerImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/acl/RoleManagerImplTest.java
rename to server/src/test/java/org/apache/cloudstack/acl/RoleManagerImplTest.java
diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/src/test/java/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
rename to server/src/test/java/org/apache/cloudstack/affinity/AffinityApiUnitTest.java
diff --git a/server/test/org/apache/cloudstack/affinity/AffinityGroupServiceImplTest.java b/server/src/test/java/org/apache/cloudstack/affinity/AffinityGroupServiceImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/affinity/AffinityGroupServiceImplTest.java
rename to server/src/test/java/org/apache/cloudstack/affinity/AffinityGroupServiceImplTest.java
diff --git a/server/test/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImplTest.java b/server/src/test/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImplTest.java
rename to server/src/test/java/org/apache/cloudstack/agent/lb/IndirectAgentLBServiceImplTest.java
diff --git a/server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithmTest.java b/server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithmTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithmTest.java
rename to server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBRoundRobinAlgorithmTest.java
diff --git a/server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithmTest.java b/server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithmTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithmTest.java
rename to server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBShuffleAlgorithmTest.java
diff --git a/server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithmTest.java b/server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithmTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithmTest.java
rename to server/src/test/java/org/apache/cloudstack/agent/lb/algorithm/IndirectAgentLBStaticAlgorithmTest.java
diff --git a/server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java b/server/src/test/java/org/apache/cloudstack/ca/CABackgroundTaskTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/ca/CABackgroundTaskTest.java
rename to server/src/test/java/org/apache/cloudstack/ca/CABackgroundTaskTest.java
diff --git a/server/src/test/java/org/apache/cloudstack/ca/CAManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/ca/CAManagerImplTest.java
new file mode 100644
index 0000000..64cbf20
--- /dev/null
+++ b/server/src/test/java/org/apache/cloudstack/ca/CAManagerImplTest.java
@@ -0,0 +1,121 @@
+//
+// 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.ca;
+
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.framework.ca.CAProvider;
+import org.apache.cloudstack.framework.ca.Certificate;
+import org.apache.cloudstack.utils.security.CertUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.certificate.CrlVO;
+import com.cloud.certificate.dao.CrlDao;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CAManagerImplTest {
+
+    @Mock
+    private HostDao hostDao;
+    @Mock
+    private CrlDao crlDao;
+    @Mock
+    private AgentManager agentManager;
+    @Mock
+    private CAProvider caProvider;
+
+    private CAManagerImpl caManager;
+
+    private void addField(final CAManagerImpl provider, final String name, final Object o) throws IllegalAccessException, NoSuchFieldException {
+        Field f = CAManagerImpl.class.getDeclaredField(name);
+        f.setAccessible(true);
+        f.set(provider, o);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        caManager = new CAManagerImpl();
+        addField(caManager, "crlDao", crlDao);
+        addField(caManager, "hostDao", hostDao);
+        addField(caManager, "agentManager", agentManager);
+        addField(caManager, "configuredCaProvider", caProvider);
+
+        Mockito.when(caProvider.getProviderName()).thenReturn("root");
+        caManager.setCaProviders(Collections.singletonList(caProvider));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        Mockito.reset(crlDao);
+        Mockito.reset(agentManager);
+        Mockito.reset(caProvider);
+    }
+
+    @Test(expected = ServerApiException.class)
+    public void testIssueCertificateThrowsException() throws Exception {
+        caManager.issueCertificate(null, null, null, 1, null);
+    }
+
+    @Test
+    public void testIssueCertificate() throws Exception {
+        caManager.issueCertificate(null, Collections.singletonList("domain.example"), null, 1, null);
+        Mockito.verify(caProvider, Mockito.times(1)).issueCertificate(Mockito.anyList(), Mockito.anyList(), Mockito.anyInt());
+        Mockito.verify(caProvider, Mockito.times(0)).issueCertificate(Mockito.anyString(), Mockito.anyList(), Mockito.anyList(), Mockito.anyInt());
+    }
+
+    @Test
+    public void testRevokeCertificate() throws Exception {
+        final CrlVO crl = new CrlVO(CertUtils.generateRandomBigInt(), "some.domain", "some-uuid");
+        Mockito.when(crlDao.revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString())).thenReturn(crl);
+        Mockito.when(caProvider.revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString())).thenReturn(true);
+        Assert.assertTrue(caManager.revokeCertificate(crl.getCertSerial(), crl.getCertCn(), null));
+        Mockito.verify(caProvider, Mockito.times(1)).revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString());
+    }
+
+    @Test
+    public void testProvisionCertificate() throws Exception {
+        final Host host = Mockito.mock(Host.class);
+        Mockito.when(host.getPrivateIpAddress()).thenReturn("1.2.3.4");
+        final KeyPair keyPair = CertUtils.generateRandomKeyPair(1024);
+        final X509Certificate certificate = CertUtils.generateV3Certificate(null, keyPair, keyPair.getPublic(), "CN=ca", "SHA256withRSA", 365, null, null);
+        Mockito.when(caProvider.issueCertificate(Mockito.anyString(), Mockito.anyList(), Mockito.anyList(), Mockito.anyInt())).thenReturn(new Certificate(certificate, null, Collections.singletonList(certificate)));
+        Mockito.when(agentManager.send(Mockito.anyLong(), Mockito.any(SetupKeyStoreCommand.class))).thenReturn(new SetupKeystoreAnswer("someCsr"));
+        Mockito.doNothing().when(agentManager).reconnect(Mockito.anyLong());
+        Assert.assertTrue(caManager.provisionCertificate(host, true, null));
+        Mockito.verify(agentManager, Mockito.times(2)).send(Mockito.anyLong(), Mockito.any(Answer.class));
+        Mockito.verify(agentManager, Mockito.times(1)).reconnect(Mockito.anyLong());
+    }
+}
\ No newline at end of file
diff --git a/server/src/test/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImplTest.java b/server/src/test/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImplTest.java
new file mode 100644
index 0000000..d85c543
--- /dev/null
+++ b/server/src/test/java/org/apache/cloudstack/diagnostics/DiagnosticsServiceImplTest.java
@@ -0,0 +1,196 @@
+//
+// 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.diagnostics;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.VMInstanceDao;
+import junit.framework.TestCase;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.command.admin.diagnostics.RunDiagnosticsCmd;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DiagnosticsServiceImplTest extends TestCase {
+
+    @Mock
+    private AgentManager agentManager;
+    @Mock
+    private VMInstanceDao instanceDao;
+    @Mock
+    private RunDiagnosticsCmd diagnosticsCmd;
+    @Mock
+    private DiagnosticsCommand command;
+    @Mock
+    private VMInstanceVO instanceVO;
+    @Mock
+    private VirtualMachineManager vmManager;
+    @Mock
+    private NetworkOrchestrationService networkManager;
+
+    @InjectMocks
+    private DiagnosticsServiceImpl diagnosticsService = new DiagnosticsServiceImpl();
+
+    @Before
+    public void setUp() throws Exception {
+        Mockito.when(diagnosticsCmd.getId()).thenReturn(1L);
+        Mockito.when(diagnosticsCmd.getType()).thenReturn(DiagnosticsType.PING);
+        Mockito.when(instanceDao.findByIdTypes(Mockito.anyLong(), Mockito.any(VirtualMachine.Type.class),
+                Mockito.any(VirtualMachine.Type.class), Mockito.any(VirtualMachine.Type.class))).thenReturn(instanceVO);
+
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        Mockito.reset(diagnosticsCmd);
+        Mockito.reset(agentManager);
+        Mockito.reset(instanceDao);
+        Mockito.reset(instanceVO);
+        Mockito.reset(command);
+    }
+
+    @Test
+    public void testRunDiagnosticsCommandTrue() throws Exception {
+        Mockito.when(diagnosticsCmd.getAddress()).thenReturn("8.8.8.8");
+        Map<String, String> accessDetailsMap = new HashMap<>();
+        accessDetailsMap.put(NetworkElementCommand.ROUTER_IP, "169.20.175.10");
+        Mockito.when(networkManager.getSystemVMAccessDetails(Mockito.any(VMInstanceVO.class))).thenReturn(accessDetailsMap);
+        final String details = "PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=1 ttl=125 time=7.88 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=2 ttl=125 time=251 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=3 ttl=125 time=64.9 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=4 ttl=125 time=50.7 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=5 ttl=125 time=67.9 ms\n" +
+                "\n" +
+                "--- 8.8.8.8 ping statistics ---\n" +
+                "5 packets transmitted, 5 received, 0% packet loss, time 4003ms\n" +
+                "rtt min/avg/max/mdev = 7.881/88.587/251.410/84.191 ms&&\n" +
+                "&&\n" +
+                "0\n";
+
+        Mockito.when(agentManager.easySend(Mockito.anyLong(), Mockito.any(DiagnosticsCommand.class))).thenReturn(new DiagnosticsAnswer(command, true, details));
+
+        Map<String, String> detailsMap = diagnosticsService.runDiagnosticsCommand(diagnosticsCmd);
+
+        String stdout = "PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=1 ttl=125 time=7.88 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=2 ttl=125 time=251 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=3 ttl=125 time=64.9 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=4 ttl=125 time=50.7 ms\n" +
+                "64 bytes from 8.8.8.8: icmp_seq=5 ttl=125 time=67.9 ms\n" +
+                "\n" +
+                "--- 8.8.8.8 ping statistics ---\n" +
+                "5 packets transmitted, 5 received, 0% packet loss, time 4003ms\n" +
+                "rtt min/avg/max/mdev = 7.881/88.587/251.410/84.191 ms";
+
+        assertEquals(3, detailsMap.size());
+        assertEquals("Mismatch between actual and expected STDERR", "", detailsMap.get(ApiConstants.STDERR));
+        assertEquals("Mismatch between actual and expected EXITCODE", "0", detailsMap.get(ApiConstants.EXITCODE));
+        assertEquals("Mismatch between actual and expected STDOUT", stdout, detailsMap.get(ApiConstants.STDOUT));
+    }
+
+    @Test
+    public void testRunDiagnosticsCommandFalse() throws Exception {
+        Mockito.when(diagnosticsCmd.getAddress()).thenReturn("192.0.2.2");
+
+        Map<String, String> accessDetailsMap = new HashMap<>();
+        accessDetailsMap.put(NetworkElementCommand.ROUTER_IP, "169.20.175.10");
+        Mockito.when(networkManager.getSystemVMAccessDetails(Mockito.any(VMInstanceVO.class))).thenReturn(accessDetailsMap);
+
+        String details = "PING 192.0.2.2 (192.0.2.2): 56 data bytes\n" +
+                "76 bytes from 213.130.48.253: Destination Net Unreachable\n" +
+                "--- 192.0.2.2 ping statistics ---\n" +
+                "4 packets transmitted, 0 packets received, 100% packet loss&&\n" +
+                "&&\n" +
+                "1\n";
+        String stdout = "PING 192.0.2.2 (192.0.2.2): 56 data bytes\n" +
+                "76 bytes from 213.130.48.253: Destination Net Unreachable\n" +
+                "--- 192.0.2.2 ping statistics ---\n" +
+                "4 packets transmitted, 0 packets received, 100% packet loss";
+        Mockito.when(agentManager.easySend(Mockito.anyLong(), Mockito.any(DiagnosticsCommand.class))).thenReturn(new DiagnosticsAnswer(command, true, details));
+
+        Map<String, String> detailsMap = diagnosticsService.runDiagnosticsCommand(diagnosticsCmd);
+
+        assertEquals(3, detailsMap.size());
+        assertEquals("Mismatch between actual and expected STDERR", "", detailsMap.get(ApiConstants.STDERR));
+        assertTrue("Mismatch between actual and expected EXITCODE", !detailsMap.get(ApiConstants.EXITCODE).equalsIgnoreCase("0"));
+        assertEquals("Mismatch between actual and expected STDOUT", stdout, detailsMap.get(ApiConstants.STDOUT));
+    }
+
+    @Test(expected = InvalidParameterValueException.class)
+    public void testRunDiagnosticsThrowsInvalidParamException() throws Exception {
+        Mockito.when(diagnosticsCmd.getAddress()).thenReturn("");
+        Mockito.when(instanceDao.findByIdTypes(Mockito.anyLong(), Mockito.any(VirtualMachine.Type.class),
+                Mockito.any(VirtualMachine.Type.class), Mockito.any(VirtualMachine.Type.class))).thenReturn(null);
+
+        diagnosticsService.runDiagnosticsCommand(diagnosticsCmd);
+    }
+
+    @Test(expected = CloudRuntimeException.class)
+    public void testVMControlIPisNull() throws Exception {
+        Mockito.when(diagnosticsCmd.getAddress()).thenReturn("0.42.42.42");
+
+        Map<String, String> accessDetailsMap = new HashMap<>();
+        accessDetailsMap.put(NetworkElementCommand.ROUTER_IP, null);
+        Mockito.when(networkManager.getSystemVMAccessDetails(Mockito.any(VMInstanceVO.class))).thenReturn(accessDetailsMap);
+
+        diagnosticsService.runDiagnosticsCommand(diagnosticsCmd);
+    }
+
+    @Test
+    public void testInvalidCharsInParams() throws Exception {
+        assertFalse(diagnosticsService.hasValidChars("'\\''"));
+        assertFalse(diagnosticsService.hasValidChars("-I eth0 &"));
+        assertFalse(diagnosticsService.hasValidChars("-I eth0 ;"));
+        assertFalse(diagnosticsService.hasValidChars(" &2 > "));
+        assertFalse(diagnosticsService.hasValidChars(" &2 >> "));
+        assertFalse(diagnosticsService.hasValidChars(" | "));
+        assertFalse(diagnosticsService.hasValidChars("|"));
+        assertFalse(diagnosticsService.hasValidChars(","));
+    }
+
+    @Test
+    public void testValidCharsInParams() throws Exception {
+        assertTrue(diagnosticsService.hasValidChars(""));
+        assertTrue(diagnosticsService.hasValidChars("."));
+        assertTrue(diagnosticsService.hasValidChars(" "));
+        assertTrue(diagnosticsService.hasValidChars("-I eth0 www.google.com"));
+        assertTrue(diagnosticsService.hasValidChars(" "));
+        assertTrue(diagnosticsService.hasValidChars(" -I cloudbr0 --sport "));
+        assertTrue(diagnosticsService.hasValidChars(" --back -m20 "));
+        assertTrue(diagnosticsService.hasValidChars("-c 5 -4"));
+        assertTrue(diagnosticsService.hasValidChars("-c 5 -4 -AbDfhqUV"));
+    }
+}
\ No newline at end of file
diff --git a/server/test/org/apache/cloudstack/direct/download/DirectDownloadManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/direct/download/DirectDownloadManagerImplTest.java
rename to server/src/test/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImplTest.java
diff --git a/server/test/org/apache/cloudstack/network/lb/ApplicationLoadBalancerTest.java b/server/src/test/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/network/lb/ApplicationLoadBalancerTest.java
rename to server/src/test/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerTest.java
diff --git a/server/test/org/apache/cloudstack/network/ssl/CertServiceTest.java b/server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/network/ssl/CertServiceTest.java
rename to server/src/test/java/org/apache/cloudstack/network/ssl/CertServiceTest.java
diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/src/test/java/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
similarity index 100%
rename from server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
rename to server/src/test/java/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
diff --git a/server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java
rename to server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java
diff --git a/server/test/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceTest.java b/server/src/test/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceTest.java
rename to server/src/test/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagementServiceTest.java
diff --git a/server/test/org/apache/cloudstack/poll/BackgroundPollManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/poll/BackgroundPollManagerImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/poll/BackgroundPollManagerImplTest.java
rename to server/src/test/java/org/apache/cloudstack/poll/BackgroundPollManagerImplTest.java
diff --git a/server/test/org/apache/cloudstack/privategw/AclOnPrivateGwTest.java b/server/src/test/java/org/apache/cloudstack/privategw/AclOnPrivateGwTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/privategw/AclOnPrivateGwTest.java
rename to server/src/test/java/org/apache/cloudstack/privategw/AclOnPrivateGwTest.java
diff --git a/server/test/org/apache/cloudstack/region/RegionManagerTest.java b/server/src/test/java/org/apache/cloudstack/region/RegionManagerTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/region/RegionManagerTest.java
rename to server/src/test/java/org/apache/cloudstack/region/RegionManagerTest.java
diff --git a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java b/server/src/test/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java
rename to server/src/test/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java
diff --git a/server/test/org/apache/cloudstack/service/ServiceOfferingVOTest.java b/server/src/test/java/org/apache/cloudstack/service/ServiceOfferingVOTest.java
similarity index 100%
rename from server/test/org/apache/cloudstack/service/ServiceOfferingVOTest.java
rename to server/src/test/java/org/apache/cloudstack/service/ServiceOfferingVOTest.java
diff --git a/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTest.java b/server/src/test/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionTest.java
similarity index 100%
rename from server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTest.java
rename to server/src/test/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionTest.java
diff --git a/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java b/server/src/test/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
similarity index 100%
rename from server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
rename to server/src/test/java/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
diff --git a/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java b/server/src/test/java/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
similarity index 100%
rename from server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
rename to server/src/test/java/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
diff --git a/server/test/resources/CloneSettingDaoTestContext.xml b/server/src/test/resources/CloneSettingDaoTestContext.xml
similarity index 100%
rename from server/test/resources/CloneSettingDaoTestContext.xml
rename to server/src/test/resources/CloneSettingDaoTestContext.xml
diff --git a/server/test/resources/SecurityGroupManagerTestContext.xml b/server/src/test/resources/SecurityGroupManagerTestContext.xml
similarity index 100%
rename from server/test/resources/SecurityGroupManagerTestContext.xml
rename to server/src/test/resources/SecurityGroupManagerTestContext.xml
diff --git a/server/test/resources/SnapshotDaoTestContext.xml b/server/src/test/resources/SnapshotDaoTestContext.xml
similarity index 100%
rename from server/test/resources/SnapshotDaoTestContext.xml
rename to server/src/test/resources/SnapshotDaoTestContext.xml
diff --git a/server/test/resources/StoragePoolDaoTestContext.xml b/server/src/test/resources/StoragePoolDaoTestContext.xml
similarity index 100%
rename from server/test/resources/StoragePoolDaoTestContext.xml
rename to server/src/test/resources/StoragePoolDaoTestContext.xml
diff --git a/server/test/resources/UserVMDaoTestContext.xml b/server/src/test/resources/UserVMDaoTestContext.xml
similarity index 100%
rename from server/test/resources/UserVMDaoTestContext.xml
rename to server/src/test/resources/UserVMDaoTestContext.xml
diff --git a/server/test/resources/VpcApiUnitTestContext.xml b/server/src/test/resources/VpcApiUnitTestContext.xml
similarity index 100%
rename from server/test/resources/VpcApiUnitTestContext.xml
rename to server/src/test/resources/VpcApiUnitTestContext.xml
diff --git a/server/test/resources/VpcTestContext.xml b/server/src/test/resources/VpcTestContext.xml
similarity index 100%
rename from server/test/resources/VpcTestContext.xml
rename to server/src/test/resources/VpcTestContext.xml
diff --git a/server/test/resources/appLoadBalancer.xml b/server/src/test/resources/appLoadBalancer.xml
similarity index 100%
rename from server/test/resources/appLoadBalancer.xml
rename to server/src/test/resources/appLoadBalancer.xml
diff --git a/server/test/resources/certs/bad_format_cert.crt b/server/src/test/resources/certs/bad_format_cert.crt
similarity index 100%
rename from server/test/resources/certs/bad_format_cert.crt
rename to server/src/test/resources/certs/bad_format_cert.crt
diff --git a/server/test/resources/certs/dsa_self_signed.key b/server/src/test/resources/certs/dsa_self_signed.key
similarity index 100%
rename from server/test/resources/certs/dsa_self_signed.key
rename to server/src/test/resources/certs/dsa_self_signed.key
diff --git a/server/test/resources/certs/expired_cert.crt b/server/src/test/resources/certs/expired_cert.crt
similarity index 100%
rename from server/test/resources/certs/expired_cert.crt
rename to server/src/test/resources/certs/expired_cert.crt
diff --git a/server/test/resources/certs/non_root.crt b/server/src/test/resources/certs/non_root.crt
similarity index 100%
rename from server/test/resources/certs/non_root.crt
rename to server/src/test/resources/certs/non_root.crt
diff --git a/server/test/resources/certs/non_root.csr b/server/src/test/resources/certs/non_root.csr
similarity index 100%
rename from server/test/resources/certs/non_root.csr
rename to server/src/test/resources/certs/non_root.csr
diff --git a/server/test/resources/certs/non_root.key b/server/src/test/resources/certs/non_root.key
similarity index 100%
rename from server/test/resources/certs/non_root.key
rename to server/src/test/resources/certs/non_root.key
diff --git a/server/test/resources/certs/non_x509_pem.crt b/server/src/test/resources/certs/non_x509_pem.crt
similarity index 100%
rename from server/test/resources/certs/non_x509_pem.crt
rename to server/src/test/resources/certs/non_x509_pem.crt
diff --git a/server/test/resources/certs/root_chain.crt b/server/src/test/resources/certs/root_chain.crt
similarity index 100%
rename from server/test/resources/certs/root_chain.crt
rename to server/src/test/resources/certs/root_chain.crt
diff --git a/server/test/resources/certs/root_chain.csr b/server/src/test/resources/certs/root_chain.csr
similarity index 100%
rename from server/test/resources/certs/root_chain.csr
rename to server/src/test/resources/certs/root_chain.csr
diff --git a/server/test/resources/certs/root_chain.key b/server/src/test/resources/certs/root_chain.key
similarity index 100%
rename from server/test/resources/certs/root_chain.key
rename to server/src/test/resources/certs/root_chain.key
diff --git a/server/test/resources/certs/rsa_ca_signed.crt b/server/src/test/resources/certs/rsa_ca_signed.crt
similarity index 100%
rename from server/test/resources/certs/rsa_ca_signed.crt
rename to server/src/test/resources/certs/rsa_ca_signed.crt
diff --git a/server/test/resources/certs/rsa_ca_signed.csr b/server/src/test/resources/certs/rsa_ca_signed.csr
similarity index 100%
rename from server/test/resources/certs/rsa_ca_signed.csr
rename to server/src/test/resources/certs/rsa_ca_signed.csr
diff --git a/server/test/resources/certs/rsa_ca_signed.key b/server/src/test/resources/certs/rsa_ca_signed.key
similarity index 100%
rename from server/test/resources/certs/rsa_ca_signed.key
rename to server/src/test/resources/certs/rsa_ca_signed.key
diff --git a/server/test/resources/certs/rsa_self_signed.crt b/server/src/test/resources/certs/rsa_self_signed.crt
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed.crt
rename to server/src/test/resources/certs/rsa_self_signed.crt
diff --git a/server/test/resources/certs/rsa_self_signed.csr b/server/src/test/resources/certs/rsa_self_signed.csr
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed.csr
rename to server/src/test/resources/certs/rsa_self_signed.csr
diff --git a/server/test/resources/certs/rsa_self_signed.key b/server/src/test/resources/certs/rsa_self_signed.key
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed.key
rename to server/src/test/resources/certs/rsa_self_signed.key
diff --git a/server/test/resources/certs/rsa_self_signed_with_pwd.crt b/server/src/test/resources/certs/rsa_self_signed_with_pwd.crt
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed_with_pwd.crt
rename to server/src/test/resources/certs/rsa_self_signed_with_pwd.crt
diff --git a/server/test/resources/certs/rsa_self_signed_with_pwd.csr b/server/src/test/resources/certs/rsa_self_signed_with_pwd.csr
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed_with_pwd.csr
rename to server/src/test/resources/certs/rsa_self_signed_with_pwd.csr
diff --git a/server/test/resources/certs/rsa_self_signed_with_pwd.key b/server/src/test/resources/certs/rsa_self_signed_with_pwd.key
similarity index 100%
rename from server/test/resources/certs/rsa_self_signed_with_pwd.key
rename to server/src/test/resources/certs/rsa_self_signed_with_pwd.key
diff --git a/server/test/resources/cleanup.sql b/server/src/test/resources/cleanup.sql
similarity index 100%
rename from server/test/resources/cleanup.sql
rename to server/src/test/resources/cleanup.sql
diff --git a/server/test/resources/createNetworkOffering.xml b/server/src/test/resources/createNetworkOffering.xml
similarity index 100%
rename from server/test/resources/createNetworkOffering.xml
rename to server/src/test/resources/createNetworkOffering.xml
diff --git a/server/test/resources/db.properties b/server/src/test/resources/db.properties
similarity index 100%
rename from server/test/resources/db.properties
rename to server/src/test/resources/db.properties
diff --git a/server/test/resources/fake.sql b/server/src/test/resources/fake.sql
similarity index 100%
rename from server/test/resources/fake.sql
rename to server/src/test/resources/fake.sql
diff --git a/server/test/resources/testContext.xml b/server/src/test/resources/testContext.xml
similarity index 100%
rename from server/test/resources/testContext.xml
rename to server/src/test/resources/testContext.xml
diff --git a/server/test/sync-queue-component.xml b/server/src/test/sync-queue-component.xml
similarity index 100%
rename from server/test/sync-queue-component.xml
rename to server/src/test/sync-queue-component.xml
diff --git a/server/test/com/cloud/api/ApiResponseHelperTest.java b/server/test/com/cloud/api/ApiResponseHelperTest.java
deleted file mode 100644
index eda7ca4..0000000
--- a/server/test/com/cloud/api/ApiResponseHelperTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.api;
-
-import com.cloud.domain.DomainVO;
-import com.cloud.usage.UsageVO;
-import com.cloud.user.AccountVO;
-import org.apache.cloudstack.api.response.UsageRecordResponse;
-import org.apache.cloudstack.usage.UsageService;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import java.lang.reflect.Field;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.when;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(ApiDBUtils.class)
-public class ApiResponseHelperTest {
-
-    @Mock
-    UsageService usageService;
-
-    ApiResponseHelper helper;
-
-    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss ZZZ");
-
-    @Before
-    public void injectMocks() throws SecurityException, NoSuchFieldException,
-            IllegalArgumentException, IllegalAccessException {
-        Field usageSvcField = ApiResponseHelper.class
-                .getDeclaredField("_usageSvc");
-        usageSvcField.setAccessible(true);
-        helper = new ApiResponseHelper();
-        usageSvcField.set(helper, usageService);
-    }
-
-    @Test
-    public void getDateStringInternal() throws ParseException {
-        Mockito.when(usageService.getUsageTimezone()).thenReturn(
-                TimeZone.getTimeZone("UTC"));
-        assertEquals("2014-06-29'T'23:45:00+00:00", helper
-                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:00 UTC")));
-        assertEquals("2014-06-29'T'23:45:01+00:00", helper
-                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:01 UTC")));
-        assertEquals("2014-06-29'T'23:45:11+00:00", helper
-                .getDateStringInternal(dateFormat.parse("2014-06-29 23:45:11 UTC")));
-        assertEquals("2014-06-29'T'23:05:11+00:00", helper
-                .getDateStringInternal(dateFormat.parse("2014-06-29 23:05:11 UTC")));
-        assertEquals("2014-05-29'T'08:45:11+00:00", helper
-                .getDateStringInternal(dateFormat.parse("2014-05-29 08:45:11 UTC")));
-    }
-
-    @Test
-    public void testUsageRecordResponse(){
-        //Creating the usageVO object to be passed to the createUsageResponse.
-        Long zoneId = null;
-        Long accountId = null;
-        Long domainId = null;
-        String Description = "Test Object";
-        String usageDisplay = " ";
-        int usageType = -1;
-        Double rawUsage = null;
-        Long vmId = null;
-        String vmName = " ";
-        Long offeringId = null;
-        Long templateId = null;
-        Long usageId = null;
-        Date startDate = null;
-        Date endDate = null;
-        String type = " ";
-        UsageVO usage = new UsageVO(zoneId,accountId,domainId,Description,usageDisplay,usageType,rawUsage,vmId,vmName,offeringId,templateId,usageId,startDate,endDate,type);
-
-        DomainVO domain = new DomainVO();
-        domain.setName("DomainName");
-
-        AccountVO account = new AccountVO();
-
-        PowerMockito.mockStatic(ApiDBUtils.class);
-        when(ApiDBUtils.findAccountById(anyLong())).thenReturn(account);
-        when(ApiDBUtils.findDomainById(anyLong())).thenReturn(domain);
-
-        UsageRecordResponse MockResponse = helper.createUsageResponse(usage);
-        assertEquals("DomainName",MockResponse.getDomainName());
-    }
-}
diff --git a/server/test/com/cloud/network/IpAddressManagerTest.java b/server/test/com/cloud/network/IpAddressManagerTest.java
deleted file mode 100644
index 0bf92ee..0000000
--- a/server/test/com/cloud/network/IpAddressManagerTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.rules.StaticNat;
-import com.cloud.network.rules.StaticNatImpl;
-import com.cloud.utils.net.Ip;
-
-import static org.mockito.Mockito.when;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.mock;
-
-public class IpAddressManagerTest {
-
-    @Mock
-    IPAddressDao _ipAddrDao;
-
-    @InjectMocks
-    IpAddressManagerImpl _ipManager;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void testGetStaticNatSourceIps() {
-        String publicIpAddress = "192.168.1.3";
-        IPAddressVO vo = mock(IPAddressVO.class);
-        when(vo.getAddress()).thenReturn(new Ip(publicIpAddress));
-        when(vo.getId()).thenReturn(1l);
-
-        when(_ipAddrDao.findById(anyLong())).thenReturn(vo);
-        StaticNat snat = new StaticNatImpl(1, 1, 1, 1, publicIpAddress, false);
-
-        List<IPAddressVO> ips = _ipManager.getStaticNatSourceIps(Collections.singletonList(snat));
-        Assert.assertNotNull(ips);
-        Assert.assertEquals(1, ips.size());
-
-        IPAddressVO returnedVO = ips.get(0);
-        Assert.assertEquals(vo, returnedVO);
-    }
-}
diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java
deleted file mode 100644
index d142554..0000000
--- a/server/test/com/cloud/network/MockNetworkModelImpl.java
+++ /dev/null
@@ -1,910 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.ConfigurationException;
-
-import com.cloud.dc.Vlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.user.Account;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine;
-
-public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
-     */
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#start()
-     */
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#stop()
-     */
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#getName()
-     */
-    @Override
-    public String getName() {
-        return "MockNetworkModelImpl";
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
-     */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-   * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
-   */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSystemAccountNetworkOfferings(java.lang.String[])
-     */
-    @Override
-    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNics(long)
-     */
-    @Override
-    public List<? extends Nic> getNics(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNextAvailableMacAddressInNetwork(long)
-     */
-    @Override
-    public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPublicIpAddress(long)
-     */
-    @Override
-    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPodVlans(long)
-     */
-    @Override
-    public List<? extends Vlan> listPodVlans(long podId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksUsedByVm(long, boolean)
-     */
-    @Override
-    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicInNetwork(long, long)
-     */
-    @Override
-    public Nic getNicInNetwork(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicsForTraffic(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultNetworkForVm(long)
-     */
-    @Override
-    public Network getDefaultNetworkForVm(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultNic(long)
-     */
-    @Override
-    public Nic getDefaultNic(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getUserDataUpdateProvider(com.cloud.network.Network)
-     */
-    @Override
-    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#networkIsConfiguredForExternalNetworking(long, long)
-     */
-    @Override
-    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkServiceCapabilities(long, com.cloud.network.Network.Service)
-     */
-    @Override
-    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isSharedNetworkWithoutServices(long networkId) {
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service[])
-     */
-    @Override
-    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long)
-     */
-    @Override
-    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long)
-     */
-    @Override
-    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpOfNetworkElementInVirtualNetwork(long, long)
-     */
-    @Override
-    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksForAccount(long, long, com.cloud.network.Network.GuestType)
-     */
-    @Override
-    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listAllNetworksInAllZonesByType(com.cloud.network.Network.GuestType)
-     */
-    @Override
-    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getStartIpAddress(long)
-     */
-    @Override
-    public String getStartIpAddress(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpInNetwork(long, long)
-     */
-    @Override
-    public String getIpInNetwork(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpInNetworkIncludingRemoved(long, long)
-     */
-    @Override
-    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPodIdForVlan(long)
-     */
-    @Override
-    public Long getPodIdForVlan(long vlanDbId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworkOfferingsForUpgrade(long)
-     */
-    @Override
-    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isSecurityGroupSupportedInNetwork(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isSecurityGroupSupportedInNetwork(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderSupportServiceInNetwork(long, com.cloud.network.Network.Service, com.cloud.network.Network.Provider)
-     */
-    @Override
-    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderEnabledInPhysicalNetwork(long, java.lang.String)
-     */
-    @Override
-    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkTag(com.cloud.hypervisor.Hypervisor.HypervisorType, com.cloud.network.Network)
-     */
-    @Override
-    public String getNetworkTag(HypervisorType hType, Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getElementServices(com.cloud.network.Network.Provider)
-     */
-    @Override
-    public List<Service> getElementServices(Provider provider) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canElementEnableIndividualServices(com.cloud.network.Network.Provider)
-     */
-    @Override
-    public boolean canElementEnableIndividualServices(Provider provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesSupportedInNetwork(long, com.cloud.network.Network.Service[])
-     */
-    @Override
-    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkSystem(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isNetworkSystem(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceCapabilities(com.cloud.offering.NetworkOffering, com.cloud.network.Network.Service)
-     */
-    @Override
-    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNetworkId(com.cloud.network.Network)
-     */
-    @Override
-    public Long getPhysicalNetworkId(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAllowSubdomainAccessGlobal()
-     */
-    @Override
-    public boolean getAllowSubdomainAccessGlobal() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderForNetwork(com.cloud.network.Network.Provider, long)
-     */
-    @Override
-    public boolean isProviderForNetwork(Provider provider, long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderForNetworkOffering(com.cloud.network.Network.Provider, long)
-     */
-    @Override
-    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canProviderSupportServices(java.util.Map)
-     */
-    @Override
-    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNetworkInfo(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canAddDefaultSecurityGroup()
-     */
-    @Override
-    public boolean canAddDefaultSecurityGroup() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworkOfferingServices(long)
-     */
-    @Override
-    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesEnabledInZone(long, com.cloud.offering.NetworkOffering, java.util.List)
-     */
-    @Override
-    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#checkIpForService(com.cloud.network.IPAddressVO, com.cloud.network.Network.Service, java.lang.Long)
-     */
-    @Override
-    public boolean checkIpForService(IpAddress ip, Service service, Long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String)
-     */
-    @Override
-    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultUniqueProviderForService(java.lang.String)
-     */
-    @Override
-    public Provider getDefaultUniqueProviderForService(String serviceName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#checkNetworkPermissions(com.cloud.user.Account, com.cloud.network.Network)
-     */
-    @Override
-    public void checkNetworkPermissions(Account owner, Network network) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultStorageTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultPublicTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultGuestTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getElementImplementingProvider(java.lang.String)
-     */
-    @Override
-    public NetworkElement getElementImplementingProvider(String providerName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAccountNetworkDomain(long, long)
-     */
-    @Override
-    public String getAccountNetworkDomain(long accountId, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNtwkOffDistinctProviders(long)
-     */
-    @Override
-    public List<Provider> getNtwkOffDistinctProviders(long ntwkOffId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean)
-     */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNtwksSupportingTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isPrivateGateway(com.cloud.vm.Nic)
-     */
-    @Override
-    public boolean isPrivateGateway(long ntwkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkCapabilities(long)
-     */
-    @Override
-    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSystemNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDedicatedNetworkDomain(long)
-     */
-    @Override
-    public Long getDedicatedNetworkDomain(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceProvidersMap(long)
-     */
-    @Override
-    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listSupportedNetworkServiceProviders(java.lang.String)
-     */
-    @Override
-    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksByVpc(long)
-     */
-    @Override
-    public List<? extends Network> listNetworksByVpc(long vpcId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canUseForDeploy(com.cloud.network.Network)
-     */
-    @Override
-    public boolean canUseForDeploy(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getExclusiveGuestNetwork(long)
-     */
-    @Override
-    public Network getExclusiveGuestNetwork(long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkRate(long, java.lang.Long)
-     */
-    @Override
-    public Integer getNetworkRate(long networkId, Long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isVmPartOfNetwork(long, long)
-     */
-    @Override
-    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultPhysicalNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetwork(long)
-     */
-    @Override
-    public Network getNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIp(long)
-     */
-    @Override
-    public IpAddress getIp(long sourceIpAddressId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkAvailableInDomain(long, long)
-     */
-    @Override
-    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicProfile(com.cloud.vm.VirtualMachine, long, java.lang.String)
-     */
-    @Override
-    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAvailableIps(com.cloud.network.Network, java.lang.String)
-     */
-    @Override
-    public Set<Long> getAvailableIps(Network network, String requestedIp) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDomainNetworkDomain(long, long)
-     */
-    @Override
-    public String getDomainNetworkDomain(long domainId, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpToServices(java.util.List, boolean, boolean)
-     */
-    @Override
-    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getProviderToIpList(com.cloud.network.Network, java.util.Map)
-     */
-    @Override
-    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSourceNatIpAddressForGuestNetwork(com.cloud.user.Account, com.cloud.network.Network)
-     */
-    @Override
-    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkInlineMode(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isNetworkInlineMode(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInVlan(long vlanId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public String getStartIpv6Address(long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isProviderEnabledInZone(long zoneId, String provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Nic getPlaceholderNicForRouter(Network network, Long podId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<String> getUsedIpsInNetwork(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<Detail, String> getNtwkOffDetails(long offId) {
-        return null;
-    }
-
-    @Override
-    public IsolationType[] listNetworkIsolationMethods() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
-        return null;
-    }
-
-    @Override
-    public boolean getExecuteInSeqNtwkElmtCmd() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isNetworkReadyForGc(long networkId) {
-        return true;
-    }
-
-    @Override
-    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
-        return null;
-    }
-
-    @Override
-    public String getValidNetworkCidr(Network guestNetwork) {
-        return null;
-    }
-
-}
diff --git a/server/test/com/cloud/network/NetworkManagerTestComponentLibrary.java b/server/test/com/cloud/network/NetworkManagerTestComponentLibrary.java
deleted file mode 100644
index d09b030..0000000
--- a/server/test/com/cloud/network/NetworkManagerTestComponentLibrary.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network;
-
-public class NetworkManagerTestComponentLibrary {
-
-    /* (non-Javadoc)
-     * @see com.cloud.configuration.DefaultComponentLibrary#populateManagers()
-     */
-    protected void populateManagers() {
-//        addManager("configuration manager", MockConfigurationManagerImpl.class);
-//        addManager("account manager", MockAccountManagerImpl.class);
-//        addManager("domain manager", MockDomainManagerImpl.class);
-//        addManager("resource limit manager", MockResourceLimitManagerImpl.class);
-//        addManager("network service", NetworkServiceImpl.class);
-//        addManager("network manager", NetworkManagerImpl.class);
-//        addManager("network model", NetworkModelImpl.class);
-//        addManager("LoadBalancingRulesManager", LoadBalancingRulesManagerImpl.class);
-//        //addManager("AutoScaleManager", AutoScaleManagerImpl.class);
-//        addManager("RulesManager", RulesManagerImpl.class);
-//        addManager("RemoteAccessVpnManager", RemoteAccessVpnManagerImpl.class);
-//        addManager("FirewallManager", FirewallManagerImpl.class);
-//        addManager("StorageNetworkManager", StorageNetworkManagerImpl.class);
-//        addManager("VPC Manager", MockVpcManagerImpl.class);
-//        addManager("VpcVirtualRouterManager", MockVpcVirtualNetworkApplianceManager.class);
-//        addManager("NetworkACLManager", NetworkACLManagerImpl.class);
-//        addManager("Site2SiteVpnManager", Site2SiteVpnManagerImpl.class);
-//        addManager("Alert Manager", MockAlertManagerImpl.class);
-//        addManager("ProjectManager", MockProjectManagerImpl.class);
-//        //addManager("SwiftManager", SwiftManagerImpl.class);
-//        //addManager("S3Manager", S3ManagerImpl.class);
-//        //addManager("SecondaryStorageManager", SecondaryStorageManagerImpl.class);
-//        //addManager("SecurityGroupManager", SecurityGroupManagerImpl2.class);
-//        addManager("AgentManager", MockAgentManagerImpl.class);
-//        addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class);
-//        //addManager("TemplateManager", TemplateManagerImpl.class);
-//        //addManager("VirtualMachineManager", MockVirtualMachineManagerImpl.class);
-//        addManager("ResourceManager", MockResourceManagerImpl.class);
-//        addManager("ExternalDhcpManager", ExternalDhcpManagerImpl.class);
-
-    }
-
-}
diff --git a/server/test/com/cloud/network/element/VirtualRouterElementTest.java b/server/test/com/cloud/network/element/VirtualRouterElementTest.java
deleted file mode 100644
index 4fbc28e..0000000
--- a/server/test/com/cloud/network/element/VirtualRouterElementTest.java
+++ /dev/null
@@ -1,452 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.element;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyList;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.network.dao.NetworkDetailVO;
-import com.cloud.network.dao.NetworkDetailsDao;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.utils.exception.CloudRuntimeException;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import com.cloud.cluster.dao.ManagementServerHostDao;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VlanDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.NetworkModelImpl;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.VirtualRouterProvider.Type;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.LoadBalancerDao;
-import com.cloud.network.dao.LoadBalancerVMMapDao;
-import com.cloud.network.dao.MonitoringServiceDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.OpRouterMonitorServiceDao;
-import com.cloud.network.dao.OvsProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
-import com.cloud.network.dao.Site2SiteVpnConnectionDao;
-import com.cloud.network.dao.Site2SiteVpnGatewayDao;
-import com.cloud.network.dao.UserIpv6AddressDao;
-import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.router.VirtualRouter.RedundantState;
-import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
-import com.cloud.network.rules.dao.PortForwardingRulesDao;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.Storage.ProvisioningType;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.dao.UserDao;
-import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.user.dao.UserStatsLogDao;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.ReservationContextImpl;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.NicIpAliasDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import org.mockito.stubbing.Answer;
-
-@RunWith(MockitoJUnitRunner.class)
-public class VirtualRouterElementTest {
-    @Mock private ClusterDao _clusterDao;
-    @Mock private ConfigurationDao _configDao;
-    @Mock private DataCenterDao _dcDao;
-    @Mock private GuestOSDao _guestOSDao;
-    @Mock private HostDao _hostDao;
-    @Mock private IPAddressDao _ipAddressDao;
-    @Mock private UserIpv6AddressDao _ipv6Dao;
-    @Mock private LoadBalancerDao _loadBalancerDao;
-    @Mock private LoadBalancerVMMapDao _loadBalancerVMMapDao;
-    @Mock private MonitoringServiceDao _monitorServiceDao;
-    @Mock private ManagementServerHostDao _msHostDao;
-    @Mock private NetworkDao _networkDao;
-    @Mock private NetworkOfferingDao _networkOfferingDao;
-    @Mock private NetworkDetailsDao _networkDetailsDao;
-    @Mock private NicDao _nicDao;
-    @Mock private NicIpAliasDao _nicIpAliasDao;
-    @Mock private OpRouterMonitorServiceDao _opRouterMonitorServiceDao;
-    @Mock private PortForwardingRulesDao _pfRulesDao;
-    @Mock private PhysicalNetworkServiceProviderDao _physicalProviderDao;
-    @Mock private HostPodDao _podDao;
-    @Mock private DomainRouterDao _routerDao;
-    @Mock private FirewallRulesDao _rulesDao;
-    @Mock private Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao;
-    @Mock private Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
-    @Mock private Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
-    @Mock private ServiceOfferingDao _serviceOfferingDao;
-    @Mock private VMTemplateDao _templateDao;
-    @Mock private UserDao _userDao;
-    @Mock private UserStatisticsDao _userStatsDao;
-    @Mock private UserStatsLogDao _userStatsLogDao;
-    @Mock private UserVmDao _userVmDao;
-    @Mock private VlanDao _vlanDao;
-    @Mock private VMInstanceDao _vmDao;
-    @Mock private UserVmDetailsDao _vmDetailsDao;
-    @Mock private VolumeDao _volumeDao;
-    @Mock private RemoteAccessVpnDao _vpnDao;
-    @Mock private VpnUserDao _vpnUsersDao;
-    @Mock private VirtualRouterProviderDao _vrProviderDao;
-    @Mock private LoadBalancerDao _lbDao;
-    @Mock private NetworkDao _networksDao;
-    @Mock private OvsProviderDao _ovsProviderDao;
-
-    @Mock private ServiceOfferingVO _offering;
-    @Mock private NetworkModelImpl _networkModel;
-
-    @Mock private AccountManager _accountMgr;
-    @Mock private ConfigurationManager _configMgr;
-    @Mock private NetworkModel _networkMdl;
-    @Mock private NetworkOrchestrationService _networkMgr;
-    @Mock private ResourceManager _resourceMgr;
-    @Mock private UserVmManager _userVmMgr;
-    @Mock private VirtualMachineManager _itMgr;
-
-    @InjectMocks
-    private RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder;
-
-    @InjectMocks
-    private VpcVirtualNetworkApplianceManagerImpl _routerMgr;
-
-    @InjectMocks
-    private VirtualRouterElement virtualRouterElement;
-
-    DataCenter testDataCenter = new DataCenterVO(/* id */ 1L,
-            "name",
-            "description",
-            "dns1",
-            /* dns2 */ null,
-            /* dns3 */ null,
-            /* dns4 */ null,
-            "cidr",
-            "domain",
-            /*domainid */ null,
-            NetworkType.Advanced,
-            "zoneToken",
-            "domainSuffix");
-    DeployDestination testDestination = new DeployDestination(testDataCenter,null,null,null);
-    ReservationContext testContext = new ReservationContextImpl(null, null, null);
-    NetworkVO testNetwork = new NetworkVO();
-    NicProfile testNicProfile = new NicProfile();
-    NetworkOfferingVO testOffering = new NetworkOfferingVO();
-    @Mock VirtualMachineProfile testVMProfile;
-
-    @Test
-    @Ignore("Ignore it until it's fixed in order not to brake the build")
-    public void testImplementInAdvancedZoneOnXenServer() throws Exception {
-        virtualRouterElement._routerMgr = _routerMgr;
-        mockDAOs(testNetwork, testOffering);
-        mockMgrs();
-
-        final boolean done = virtualRouterElement.implement(testNetwork, testOffering, testDestination, testContext);
-        assertTrue("no cigar for network daddy",done);
-    }
-
-    @Test
-    @Ignore("Ignore it until it's fixed in order not to brake the build")
-    public void testPrepare() {
-        virtualRouterElement._routerMgr = _routerMgr;
-        virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
-        mockDAOs(testNetwork, testOffering);
-        mockMgrs();
-
-        boolean done = false;
-        try {
-            done = virtualRouterElement.prepare(testNetwork, testNicProfile, testVMProfile, testDestination, testContext);
-        } catch (ConcurrentOperationException | InsufficientCapacityException | ResourceUnavailableException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        assertTrue("can not even start to create a router", done);
-
-    }
-
-    @Test
-    public void testGetRouters1(){
-        Network networkUpdateInprogress=new NetworkVO(1l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
-        mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
-        //getRoutes should always return the router that is updating.
-        List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
-        assertTrue(routers.size()==1);
-        assertTrue(routers.get(0).getUpdateState()== VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
-    }
-
-    @Test
-    public void testGetRouters2(){
-        Network networkUpdateInprogress=new NetworkVO(2l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
-        mockDAOs((NetworkVO)networkUpdateInprogress,testOffering);
-        //alwyas return backup routers first when both master and backup need update.
-        List<DomainRouterVO> routers=virtualRouterElement.getRouters(networkUpdateInprogress);
-        assertTrue(routers.size()==1);
-        assertTrue(routers.get(0).getRedundantState()==RedundantState.BACKUP && routers.get(0).getUpdateState()==VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
-    }
-
-    @Test
-    public void testGetRouters3(){
-        Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
-        mockDAOs((NetworkVO)network,testOffering);
-        //alwyas return backup routers first when both master and backup need update.
-        List<DomainRouterVO> routers=virtualRouterElement.getRouters(network);
-        assertTrue(routers.size()==4);
-    }
-
-    @Test
-    public void getResourceCountTest(){
-        Network network=new NetworkVO(3l,null,null,null,1l,1l,1l,1l,"d","d","d",null,1l,1l,null,true,null,true);
-        mockDAOs((NetworkVO)network,testOffering);
-        int routers=virtualRouterElement.getResourceCount(network);
-        assertTrue(routers==4);
-    }
-
-    @Test
-    public void completeAggregationCommandTest1() throws AgentUnavailableException,ResourceUnavailableException {
-        virtualRouterElement._routerMgr = Mockito.mock(VpcVirtualNetworkApplianceManagerImpl.class);
-        virtualRouterElement.routerDeploymentDefinitionBuilder = routerDeploymentDefinitionBuilder;
-        Network network = new NetworkVO(6l, null, null, null, 1l, 1l, 1l, 1l, "d", "d", "d", null, 1l, 1l, null, true, null, true);
-        when(virtualRouterElement._routerMgr.completeAggregatedExecution(any(Network.class), anyList())).thenReturn(true);
-        mockDAOs((NetworkVO) network, testOffering);
-        when(virtualRouterElement._routerDao.persist(any(DomainRouterVO.class))).thenAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
-                Object args[] = invocationOnMock.getArguments();
-                DomainRouterVO router = (DomainRouterVO) args[0];
-                if (router.getUpdateState() != VirtualRouter.UpdateState.UPDATE_COMPLETE) {
-                    throw new CloudRuntimeException("TestFailed: completeAggregationCommandTest1 failed");
-                } else return null;
-            }
-        });
-        virtualRouterElement.completeAggregatedExecution(network, testDestination);
-    }
-    /**
-     * @param networks
-     * @param offerings
-     * @throws ConcurrentOperationException
-     */
-    private void mockMgrs() throws ConcurrentOperationException {
-        final Service service = Service.Connectivity;
-        testNetwork.setState(Network.State.Implementing);
-        testNetwork.setTrafficType(TrafficType.Guest);
-        when(_networkMdl.isProviderEnabledInPhysicalNetwork(0L, "VirtualRouter")).thenReturn(true);
-        when(_networkMdl.isProviderSupportServiceInNetwork(testNetwork.getId(), service, Network.Provider.VirtualRouter)).thenReturn(true);
-        when(_networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, 0L)).thenReturn(true);
-        when(testVMProfile.getType()).thenReturn(VirtualMachine.Type.User);
-        when(testVMProfile.getHypervisorType()).thenReturn(HypervisorType.XenServer);
-        final List<NetworkVO> networks = new ArrayList<NetworkVO>(1);
-        networks.add(testNetwork);
-        final List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(1);
-        offerings.add(testOffering);
-        doReturn(offerings).when(_networkModel).getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
-        doReturn(networks).when(_networkMgr).setupNetwork(any(Account.class), any(NetworkOffering.class), any(DeploymentPlan.class), any(String.class), any(String.class), anyBoolean());
-        // being anti-social and testing my own case first
-        doReturn(HypervisorType.XenServer).when(_resourceMgr).getDefaultHypervisor(anyLong());
-        doReturn(new AccountVO()).when(_accountMgr).getAccount(testNetwork.getAccountId());
-    }
-
-    /**
-     * @param network
-     */
-    private void mockDAOs(final NetworkVO network, final NetworkOfferingVO offering) {
-        when(_networkDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
-        when(_networksDao.acquireInLockTable(network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value())).thenReturn(network);
-        when(_physicalProviderDao.findByServiceProvider(0L, "VirtualRouter")).thenReturn(new PhysicalNetworkServiceProviderVO());
-        when(_vrProviderDao.findByNspIdAndType(0L, Type.VirtualRouter)).thenReturn(new VirtualRouterProviderVO());
-        when(_networkOfferingDao.findById(0L)).thenReturn(offering);
-        // watchit: (in this test) there can be only one
-        when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(0L);
-        final ServiceOfferingVO svcoff = new ServiceOfferingVO("name",
-                /* cpu */ 1,
-                /* ramsize */ 1024*1024,
-                /* (clock?)speed */ 1024*1024*1024,
-                /* rateMbps */ 1,
-                /* multicastRateMbps */ 0,
-                /* offerHA */ false,
-                "displayText",
-                ProvisioningType.THIN,
-                /* useLocalStorage */ false,
-                /* recreatable */ false,
-                "tags",
-                /* systemUse */ false,
-                VirtualMachine.Type.DomainRouter,
-                /* defaultUse */ false);
-        when(_serviceOfferingDao.findById(0L)).thenReturn(svcoff);
-        when(_serviceOfferingDao.findByName(Matchers.anyString())).thenReturn(svcoff);
-        final DomainRouterVO router = new DomainRouterVO(/* id */ 1L,
-                /* serviceOfferingId */ 1L,
-                /* elementId */ 0L,
-                "name",
-                /* templateId */0L,
-                HypervisorType.XenServer,
-                /* guestOSId */ 0L,
-                /* domainId */ 0L,
-                /* accountId */ 1L,
-                /* userId */ 1L,
-                /* isRedundantRouter */ false,
-                RedundantState.UNKNOWN,
-                /* haEnabled */ false,
-                /* stopPending */ false,
-                /* vpcId */ null);
-        final DomainRouterVO routerNeedUpdateBackup = new DomainRouterVO(/* id */ 2L,
-                /* serviceOfferingId */ 1L,
-                /* elementId */ 0L,
-                "name",
-                /* templateId */0L,
-                HypervisorType.XenServer,
-                /* guestOSId */ 0L,
-                /* domainId */ 0L,
-                /* accountId */ 1L,
-                /* userId */ 1L,
-                /* isRedundantRouter */ false,
-                RedundantState.BACKUP,
-                /* haEnabled */ false,
-                /* stopPending */ false,
-                /* vpcId */ null);
-                routerNeedUpdateBackup.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
-        final DomainRouterVO routerNeedUpdateMaster = new DomainRouterVO(/* id */ 3L,
-                /* serviceOfferingId */ 1L,
-                /* elementId */ 0L,
-                "name",
-                /* templateId */0L,
-                HypervisorType.XenServer,
-                /* guestOSId */ 0L,
-                /* domainId */ 0L,
-                /* accountId */ 1L,
-                /* userId */ 1L,
-                /* isRedundantRouter */ false,
-                RedundantState.MASTER,
-                /* haEnabled */ false,
-                /* stopPending */ false,
-                /* vpcId */ null);
-        routerNeedUpdateMaster.setUpdateState(VirtualRouter.UpdateState.UPDATE_NEEDED);
-        final DomainRouterVO routerUpdateComplete = new DomainRouterVO(/* id */ 4L,
-                /* serviceOfferingId */ 1L,
-                /* elementId */ 0L,
-                "name",
-                /* templateId */0L,
-                HypervisorType.XenServer,
-                /* guestOSId */ 0L,
-                /* domainId */ 0L,
-                /* accountId */ 1L,
-                /* userId */ 1L,
-                /* isRedundantRouter */ false,
-                RedundantState.UNKNOWN,
-                /* haEnabled */ false,
-                /* stopPending */ false,
-                /* vpcId */ null);
-                routerUpdateComplete.setUpdateState(VirtualRouter.UpdateState.UPDATE_COMPLETE);
-        final DomainRouterVO routerUpdateInProgress = new DomainRouterVO(/* id */ 5L,
-                /* serviceOfferingId */ 1L,
-                /* elementId */ 0L,
-                "name",
-                /* templateId */0L,
-                HypervisorType.XenServer,
-                /* guestOSId */ 0L,
-                /* domainId */ 0L,
-                /* accountId */ 1L,
-                /* userId */ 1L,
-                /* isRedundantRouter */ false,
-                RedundantState.UNKNOWN,
-                /* haEnabled */ false,
-                /* stopPending */ false,
-                /* vpcId */ null);
-                routerUpdateInProgress.setUpdateState(VirtualRouter.UpdateState.UPDATE_IN_PROGRESS);
-        List<DomainRouterVO> routerList1=new ArrayList<>();
-        routerList1.add(routerUpdateComplete);
-        routerList1.add(routerNeedUpdateBackup);
-        routerList1.add(routerNeedUpdateMaster);
-        routerList1.add(routerUpdateInProgress);
-        List<DomainRouterVO> routerList2=new ArrayList<>();
-        routerList2.add(routerUpdateComplete);
-        routerList2.add(routerNeedUpdateBackup);
-        routerList2.add(routerNeedUpdateMaster);
-        List<DomainRouterVO> routerList3=new ArrayList<>();
-        routerList3.add(routerUpdateComplete);
-        routerList3.add(routerUpdateInProgress);
-        when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
-        when(_templateDao.findRoutingTemplate(HypervisorType.XenServer, "SystemVM Template (XenServer)")).thenReturn(new VMTemplateVO());
-        when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
-        when(_routerDao.findById(router.getId())).thenReturn(router);
-        when(_routerDao.listByNetworkAndRole(1l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
-        when(_routerDao.listByNetworkAndRole(2l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList2);
-        when(_routerDao.listByNetworkAndRole(3l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList1);
-        when(_routerDao.listByNetworkAndRole(6l, VirtualRouter.Role.VIRTUAL_ROUTER)).thenReturn(routerList3);
-        when(_networkDetailsDao.findDetail(1l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(1l,Network.updatingInSequence,"true",true));
-        when(_networkDetailsDao.findDetail(2l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
-        when(_networkDetailsDao.findDetail(6l, Network.updatingInSequence)).thenReturn(new NetworkDetailVO(2l,Network.updatingInSequence,"true",true));
-        when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
-    }
-
-}
diff --git a/server/test/com/cloud/network/firewall/FirewallManagerTest.java b/server/test/com/cloud/network/firewall/FirewallManagerTest.java
deleted file mode 100644
index a0bc897..0000000
--- a/server/test/com/cloud/network/firewall/FirewallManagerTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.network.firewall;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.spy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.FirewallRulesDao;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.user.AccountManager;
-import com.cloud.user.DomainManager;
-import junit.framework.Assert;
-
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.IpAddressManager;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkRuleApplier;
-import com.cloud.network.element.FirewallServiceProvider;
-import com.cloud.network.element.VirtualRouterElement;
-import com.cloud.network.element.VpcVirtualRouterElement;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRuleVO;
-import com.cloud.utils.component.ComponentContext;
-
-//@Ignore("Requires database to be set up")
-@RunWith(MockitoJUnitRunner.class)
-//@ContextConfiguration(locations = "classpath:/testContext.xml")
-//@ComponentSetup(managerName="management-server", setupXml="network-mgr-component.xml")
-public class FirewallManagerTest {
-    private static final Logger s_logger = Logger.getLogger(FirewallManagerTest.class);
-
-//    @Before
-//    public void setUp() {
-//        Logger daoLogger = Logger.getLogger(GenericDaoBase.class);
-//        Logger cloudLogger = Logger.getLogger("com.cloud");
-//
-//        componentlogger.setLevel(Level.WARN);
-//        daoLogger.setLevel(Level.ERROR);
-//        cloudLogger.setLevel(Level.ERROR);
-//        s_logger.setLevel(Level.INFO);
-//        super.setUp();
-//    }
-
-    @Ignore("Requires database to be set up")
-    @Test
-    public void testInjected() {
-
-//        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)ComponentLocator.getCurrentLocator().getManager(FirewallManager.class);
-//        Assert.assertTrue(firewallMgr._firewallElements.enumeration().hasMoreElements());
-//        Assert.assertTrue(firewallMgr._pfElements.enumeration().hasMoreElements());
-//        Assert.assertTrue(firewallMgr._staticNatElements.enumeration().hasMoreElements());
-//        Assert.assertTrue(firewallMgr._networkAclElements.enumeration().hasMoreElements());
-//        Assert.assertNotNull(firewallMgr._networkModel);
-//
-//        Assert.assertNotNull(firewallMgr._firewallElements.get("VirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._firewallElements.get("VpcVirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._pfElements.get("VirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._pfElements.get("VpcVirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._staticNatElements.get("VirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._staticNatElements.get("VpcVirtualRouter"));
-//        Assert.assertNotNull(firewallMgr._networkAclElements.get("VpcVirtualRouter"));
-//        Assert.assertNull(firewallMgr._networkAclElements.get("VirtualRouter"));
-//
-//
-//        Assert.assertTrue(firewallMgr._firewallElements.get("VirtualRouter") instanceof FirewallServiceProvider);
-//        Assert.assertTrue(firewallMgr._pfElements.get("VirtualRouter") instanceof PortForwardingServiceProvider);
-//        Assert.assertTrue(firewallMgr._staticNatElements.get("VirtualRouter") instanceof StaticNatServiceProvider);
-//        Assert.assertTrue(firewallMgr._networkAclElements.get("VpcVirtualRouter") instanceof NetworkACLServiceProvider);
-
-        s_logger.info("Done testing injection of service elements into firewall manager");
-
-    }
-
-    @Mock
-    AccountManager _accountMgr;
-    @Mock
-    NetworkOrchestrationService _networkMgr;
-    @Mock
-    NetworkModel _networkModel;
-    @Mock
-    DomainManager _domainMgr;
-    @Mock
-    VpcManager _vpcMgr;
-    @Mock
-    IpAddressManager _ipAddrMgr;
-    @Mock
-    FirewallRulesDao _firewallDao;
-
-    @InjectMocks
-    FirewallManager _firewallMgr = new FirewallManagerImpl();
-
-    @Before
-    public void initMocks() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Ignore("Requires database to be set up")
-    @Test
-    public void testApplyRules() {
-        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
-        FirewallRuleVO rule = new FirewallRuleVO("rule1", 1, 80, "TCP", 1, 2, 1, FirewallRule.Purpose.Firewall, null, null, null, null);
-        ruleList.add(rule);
-        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
-
-        NetworkOrchestrationService netMgr = mock(NetworkOrchestrationService.class);
-        IpAddressManager addrMgr = mock(IpAddressManager.class);
-        firewallMgr._networkMgr = netMgr;
-
-        try {
-            firewallMgr.applyRules(ruleList, false, false);
-            verify(addrMgr).applyRules(any(List.class), any(FirewallRule.Purpose.class), any(NetworkRuleApplier.class), anyBoolean());
-
-        } catch (ResourceUnavailableException e) {
-            Assert.fail("Unreachable code");
-        }
-    }
-
-    @Ignore("Requires database to be set up")
-    @Test
-    public void testApplyFWRules() {
-        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
-        FirewallRuleVO rule = new FirewallRuleVO("rule1", 1, 80, "TCP", 1, 2, 1, FirewallRule.Purpose.Firewall, null, null, null, null);
-        ruleList.add(rule);
-        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
-        VirtualRouterElement virtualRouter = mock(VirtualRouterElement.class);
-        VpcVirtualRouterElement vpcVirtualRouter = mock(VpcVirtualRouterElement.class);
-
-        List<FirewallServiceProvider> fwElements = new ArrayList<FirewallServiceProvider>();
-        fwElements.add(ComponentContext.inject(VirtualRouterElement.class));
-        fwElements.add(ComponentContext.inject(VpcVirtualRouterElement.class));
-
-        firewallMgr._firewallElements = fwElements;
-
-        try {
-            when(virtualRouter.applyFWRules(any(Network.class), any(List.class))).thenReturn(false);
-            when(vpcVirtualRouter.applyFWRules(any(Network.class), any(List.class))).thenReturn(true);
-            //Network network, Purpose purpose, List<? extends FirewallRule> rules
-            firewallMgr.applyRules(mock(Network.class), Purpose.Firewall, ruleList);
-            verify(vpcVirtualRouter).applyFWRules(any(Network.class), any(List.class));
-            verify(virtualRouter).applyFWRules(any(Network.class), any(List.class));
-
-        } catch (ResourceUnavailableException e) {
-            Assert.fail("Unreachable code");
-        }
-    }
-
-    @Test
-    public void testDetectRulesConflict() {
-        List<FirewallRuleVO> ruleList = new ArrayList<FirewallRuleVO>();
-        FirewallRuleVO rule1 = spy(new FirewallRuleVO("rule1", 3, 500, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
-        FirewallRuleVO rule2 = spy(new FirewallRuleVO("rule2", 3, 1701, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
-        FirewallRuleVO rule3 = spy(new FirewallRuleVO("rule3", 3, 4500, "UDP", 1, 2, 1, Purpose.Vpn, null, null, null, null));
-
-        List<String> sString = Arrays.asList("10.1.1.1/24","192.168.1.1/24");
-        List<String> dString1 = Arrays.asList("10.1.1.1/25");
-        List<String> dString2 = Arrays.asList("10.1.1.128/25");
-
-        FirewallRuleVO rule4 = spy(new FirewallRuleVO("rule4", 3L, 10, 20, "TCP", 1, 2, 1, Purpose.Firewall, sString, dString1, null, null,
-                null, FirewallRule.TrafficType.Egress));
-
-        ruleList.add(rule1);
-        ruleList.add(rule2);
-        ruleList.add(rule3);
-        ruleList.add(rule4);
-
-        FirewallManagerImpl firewallMgr = (FirewallManagerImpl)_firewallMgr;
-
-        when(firewallMgr._firewallDao.listByIpAndPurposeAndNotRevoked(3,null)).thenReturn(ruleList);
-        when(rule1.getId()).thenReturn(1L);
-        when(rule2.getId()).thenReturn(2L);
-        when(rule3.getId()).thenReturn(3L);
-        when(rule4.getId()).thenReturn(4L);
-
-        FirewallRule newRule1 = new FirewallRuleVO("newRule1", 3, 500, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
-        FirewallRule newRule2 = new FirewallRuleVO("newRule2", 3, 1701, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
-        FirewallRule newRule3 = new FirewallRuleVO("newRule3", 3, 4500, "TCP", 1, 2, 1, Purpose.PortForwarding, null, null, null, null);
-        FirewallRule newRule4 = new FirewallRuleVO("newRule4", 3L, 15, 25, "TCP", 1, 2, 1, Purpose.Firewall, sString, dString2, null, null,
-                null, FirewallRule.TrafficType.Egress);
-
-        try {
-            firewallMgr.detectRulesConflict(newRule1);
-            firewallMgr.detectRulesConflict(newRule2);
-            firewallMgr.detectRulesConflict(newRule3);
-            firewallMgr.detectRulesConflict(newRule4);
-        }
-        catch (NetworkRuleConflictException ex) {
-            Assert.fail();
-        }
-    }
-
-
-
-}
diff --git a/server/test/com/cloud/network/guru/DirectNetworkGuruTest.java b/server/test/com/cloud/network/guru/DirectNetworkGuruTest.java
deleted file mode 100644
index 98d43f3..0000000
--- a/server/test/com/cloud/network/guru/DirectNetworkGuruTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.guru;
-
-import com.cloud.network.PhysicalNetwork;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-
-public class DirectNetworkGuruTest {
-
-    DirectNetworkGuru guru = new DirectNetworkGuru();
-
-    @Mock
-    PhysicalNetwork physicalNetwork;
-
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        when(physicalNetwork.getIsolationMethods()).thenReturn(Arrays.asList("VXLAN", "VLAN"));
-    }
-
-    @Test
-    public void testIsMyIsolationMethodUppercaseMethods() {
-        assertTrue(guru.isMyIsolationMethod(physicalNetwork));
-    }
-
-    @Test
-    public void testIsMyIsolationMethodLowercaseMethods() {
-        when(physicalNetwork.getIsolationMethods()).thenReturn(Arrays.asList("vxlan", "vlan"));
-        assertTrue(guru.isMyIsolationMethod(physicalNetwork));
-    }
-}
diff --git a/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java b/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java
deleted file mode 100644
index 0156afb..0000000
--- a/server/test/com/cloud/network/vpn/MockRemoteAccessVPNServiceProvider.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpn;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.VpnUser;
-import com.cloud.network.element.RemoteAccessVPNServiceProvider;
-import com.cloud.utils.component.ManagerBase;
-
-public class MockRemoteAccessVPNServiceProvider extends ManagerBase implements RemoteAccessVPNServiceProvider {
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        return "MockRemoteAccessVPNServiceProvider";
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public String[] applyVpnUsers(RemoteAccessVpn vpn, List<? extends VpnUser> users) throws ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean startVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean stopVpn(RemoteAccessVpn vpn) throws ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-}
diff --git a/server/test/com/cloud/network/vpn/RemoteAccessVpnTest.java b/server/test/com/cloud/network/vpn/RemoteAccessVpnTest.java
deleted file mode 100644
index 58315e6..0000000
--- a/server/test/com/cloud/network/vpn/RemoteAccessVpnTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.vpn;
-
-import org.apache.log4j.Logger;
-import org.junit.After;
-import org.junit.Test;
-
-public class RemoteAccessVpnTest {
-    private final static Logger s_logger = Logger.getLogger(RemoteAccessVpnTest.class);
-
-//    private static void addDaos(MockComponentLocator locator) {
-//        locator.addDao("AccountDao", AccountDaoImpl.class);
-//        locator.addDao("VpnUserDao", VpnUserDaoImpl.class);
-//        locator.addDao("FirewallRulesDao", FirewallRulesDaoImpl.class);
-//        locator.addDao("IPAddressDao", IPAddressDaoImpl.class);
-//        locator.addDao("DomainDao", DomainDaoImpl.class);
-//        locator.addDao("UsageEventDao", UsageEventDaoImpl.class);
-//        locator.addDao("RemoteAccessVpnDao", RemoteAccessVpnDaoImpl.class);
-//        locator.addDao("ConfigurationDao", ConfigurationDaoImpl.class);
-//
-//    }
-//
-//    private static void addManagers(MockComponentLocator locator) {
-//        locator.addManager("AccountManager", MockAccountManagerImpl.class);
-//        locator.addManager("DomainManager", MockDomainManagerImpl.class);
-//        locator.addManager("NetworkManager", MockNetworkManagerImpl.class);
-//        locator.addManager("NetworkModel", MockNetworkModelImpl.class);
-//        locator.addManager("RulesManager", MockRulesManagerImpl.class);
-//        locator.addManager("FirewallManager", MockFirewallManagerImpl.class);
-//    }
-
-//    @Before
-//    public void setUp() {
-//        locator = new MockComponentLocator("management-server");
-//        addDaos(locator);
-//        addManagers(locator);
-//        s_logger.info("Finished setUp");
-//    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    @Test
-    public void testInjected() throws Exception {
-//        List<Pair<String, Class<? extends RemoteAccessVPNServiceProvider>>> list =
-//                new ArrayList<Pair<String, Class<? extends RemoteAccessVPNServiceProvider>>>();
-//        list.add(new Pair<String, Class<? extends RemoteAccessVPNServiceProvider>>("RemoteAccessVPNServiceProvider", MockRemoteAccessVPNServiceProvider.class));
-//        locator.addAdapterChain(RemoteAccessVPNServiceProvider.class, list);
-//        s_logger.info("Finished add adapter");
-//        locator.makeActive(new DefaultInterceptorLibrary());
-//        s_logger.info("Finished make active");
-//        RemoteAccessVpnManagerImpl vpnMgr = ComponentLocator.inject(RemoteAccessVpnManagerImpl.class);
-//        s_logger.info("Finished inject");
-//        Assert.assertTrue(vpnMgr.configure("RemoteAccessVpnMgr",new HashMap<String, Object>()) );
-//        Assert.assertTrue(vpnMgr.start());
-//        int numProviders = vpnMgr.getRemoteAccessVPNServiceProviders().size();
-//        Assert.assertTrue(numProviders > 0);
-    }
-
-}
diff --git a/server/test/com/cloud/storage/VolumeApiServiceImplTest.java b/server/test/com/cloud/storage/VolumeApiServiceImplTest.java
deleted file mode 100644
index 366fd22..0000000
--- a/server/test/com/cloud/storage/VolumeApiServiceImplTest.java
+++ /dev/null
@@ -1,881 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.Spy;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import com.cloud.configuration.Resource;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.org.Grouping;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.db.TransactionLegacy;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-@RunWith(MockitoJUnitRunner.class)
-public class VolumeApiServiceImplTest {
-
-    @Spy
-    @InjectMocks
-    private VolumeApiServiceImpl volumeApiServiceImpl = new VolumeApiServiceImpl();
-    @Mock
-    private VolumeDao volumeDaoMock;
-    @Mock
-    private SnapshotManager snapshotManagerMock;
-    @Mock
-    private VolumeDataStoreDao volumeDataStoreDaoMock;
-    @Mock
-    private AccountManager accountManagerMock;
-    @Mock
-    private VolumeService volumeServiceMock;
-    @Mock
-    private ResourceLimitService resourceLimitServiceMock;
-    @Mock
-    private VolumeDataFactory volumeDataFactoryMock;
-
-    @Mock
-    private UserVmDao userVmDaoMock;
-    @Mock
-    private PrimaryDataStoreDao primaryDataStoreDaoMock;
-    @Mock
-    private VMSnapshotDao vmSnapshotDaoMock;
-    @Mock
-    private AsyncJobManager asyncJobManagerMock;
-    @Mock
-    private AsyncJobJoinMapDao asyncJobJoinMapDaoMock;
-    @Mock
-    private UserVmManager userVmManagerMock;
-    @Mock
-    private VMInstanceDao vMInstanceDaoMock;
-    @Mock
-    private SnapshotInfo snapshotInfoMock;
-    @Mock
-    private CreateVolumeCmd createVolumeCmdMock;
-    @Mock
-    private DataCenterDao dataCenterDaoMock;
-    @Mock
-    private AccountDao accountDaoMock;
-    @Mock
-    private HostDao hostdaoMock;
-
-    DetachVolumeCmd detachCmd = new DetachVolumeCmd();
-    Class<?> _detachCmdClass = detachCmd.getClass();
-
-    @Mock
-    private Account accountMock;
-    @Mock
-    private VolumeVO volumeVoMock;
-    @Mock
-    private VolumeDataStoreVO volumeDataStoreVoMock;
-    @Mock
-    private AsyncCallFuture<VolumeApiResult> asyncCallFutureVolumeapiResultMock;
-    @Mock
-    private VolumeInfo volumeInfoMock;
-
-    private long accountMockId = 456l;
-    private long volumeMockId = 12313l;
-    private long vmInstanceMockId = 1123l;
-    private long volumeSizeMock = 456789921939l;
-
-    @Before
-    public void setup() throws Exception {
-        Mockito.doReturn(volumeMockId).when(volumeDataStoreVoMock).getVolumeId();
-        Mockito.doReturn(volumeMockId).when(volumeVoMock).getId();
-        Mockito.doReturn(accountMockId).when(accountMock).getId();
-        Mockito.doReturn(volumeSizeMock).when(volumeVoMock).getSize();
-        Mockito.doReturn(Mockito.mock(VolumeApiResult.class)).when(asyncCallFutureVolumeapiResultMock).get();
-
-        // mock caller context
-        AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
-        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
-        CallContext.register(user, account);
-        // mock async context
-        AsyncJobExecutionContext context = new AsyncJobExecutionContext();
-        AsyncJobExecutionContext.init(volumeApiServiceImpl._jobMgr, asyncJobJoinMapDaoMock);
-        AsyncJobVO job = new AsyncJobVO();
-        context.setJob(job);
-        AsyncJobExecutionContext.setCurrentExecutionContext(context);
-
-        TransactionLegacy txn = TransactionLegacy.open("runVolumeDaoImplTest");
-        try {
-            // volume of running vm id=1
-            VolumeVO volumeOfRunningVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 1L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            when(volumeApiServiceImpl._volsDao.findById(1L)).thenReturn(volumeOfRunningVm);
-
-            UserVmVO runningVm = new UserVmVO(1L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
-            runningVm.setState(State.Running);
-            runningVm.setDataCenterId(1L);
-            when(volumeApiServiceImpl._userVmDao.findById(1L)).thenReturn(runningVm);
-
-            // volume of stopped vm id=2
-            VolumeVO volumeOfStoppedVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            volumeOfStoppedVm.setPoolId(1L);
-            when(volumeApiServiceImpl._volsDao.findById(2L)).thenReturn(volumeOfStoppedVm);
-
-            UserVmVO stoppedVm = new UserVmVO(2L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
-            stoppedVm.setState(State.Stopped);
-            stoppedVm.setDataCenterId(1L);
-            when(volumeApiServiceImpl._userVmDao.findById(2L)).thenReturn(stoppedVm);
-
-            // volume of hyperV vm id=3
-            UserVmVO hyperVVm = new UserVmVO(3L, "vm", "vm", 1, HypervisorType.Hyperv, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
-            hyperVVm.setState(State.Stopped);
-            hyperVVm.setDataCenterId(1L);
-            when(volumeApiServiceImpl._userVmDao.findById(3L)).thenReturn(hyperVVm);
-
-            VolumeVO volumeOfStoppeHyperVVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 3L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            volumeOfStoppeHyperVVm.setPoolId(1L);
-            when(volumeApiServiceImpl._volsDao.findById(3L)).thenReturn(volumeOfStoppeHyperVVm);
-
-            StoragePoolVO unmanagedPool = new StoragePoolVO();
-
-            when(volumeApiServiceImpl._storagePoolDao.findById(1L)).thenReturn(unmanagedPool);
-
-            // volume of managed pool id=4
-            StoragePoolVO managedPool = new StoragePoolVO();
-            managedPool.setManaged(true);
-            when(volumeApiServiceImpl._storagePoolDao.findById(2L)).thenReturn(managedPool);
-            VolumeVO managedPoolVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            managedPoolVolume.setPoolId(2L);
-            when(volumeApiServiceImpl._volsDao.findById(4L)).thenReturn(managedPoolVolume);
-
-            // non-root non-datadisk volume
-            VolumeInfo volumeWithIncorrectVolumeType = Mockito.mock(VolumeInfo.class);
-            when(volumeWithIncorrectVolumeType.getId()).thenReturn(5L);
-            when(volumeWithIncorrectVolumeType.getVolumeType()).thenReturn(Volume.Type.ISO);
-            when(volumeApiServiceImpl.volFactory.getVolume(5L)).thenReturn(volumeWithIncorrectVolumeType);
-
-            // correct root volume
-            VolumeInfo correctRootVolume = Mockito.mock(VolumeInfo.class);
-            when(correctRootVolume.getId()).thenReturn(6L);
-            when(correctRootVolume.getDataCenterId()).thenReturn(1L);
-            when(correctRootVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
-            when(correctRootVolume.getInstanceId()).thenReturn(null);
-            when(correctRootVolume.getState()).thenReturn(Volume.State.Ready);
-            when(correctRootVolume.getTemplateId()).thenReturn(null);
-            when(correctRootVolume.getPoolId()).thenReturn(1L);
-            when(volumeApiServiceImpl.volFactory.getVolume(6L)).thenReturn(correctRootVolume);
-
-            VolumeVO correctRootVolumeVO = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            when(volumeApiServiceImpl._volsDao.findById(6L)).thenReturn(correctRootVolumeVO);
-
-            // managed root volume
-            VolumeInfo managedVolume = Mockito.mock(VolumeInfo.class);
-            when(managedVolume.getId()).thenReturn(7L);
-            when(managedVolume.getDataCenterId()).thenReturn(1L);
-            when(managedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
-            when(managedVolume.getInstanceId()).thenReturn(null);
-            when(managedVolume.getPoolId()).thenReturn(2L);
-            when(volumeApiServiceImpl.volFactory.getVolume(7L)).thenReturn(managedVolume);
-
-            VolumeVO managedVolume1 = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            managedVolume1.setPoolId(2L);
-            managedVolume1.setDataCenterId(1L);
-            when(volumeApiServiceImpl._volsDao.findById(7L)).thenReturn(managedVolume1);
-
-            // vm having root volume
-            UserVmVO vmHavingRootVolume = new UserVmVO(4L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm", null);
-            vmHavingRootVolume.setState(State.Stopped);
-            vmHavingRootVolume.setDataCenterId(1L);
-            when(volumeApiServiceImpl._userVmDao.findById(4L)).thenReturn(vmHavingRootVolume);
-            List<VolumeVO> vols = new ArrayList<VolumeVO>();
-            vols.add(new VolumeVO());
-            when(volumeApiServiceImpl._volsDao.findByInstanceAndDeviceId(4L, 0L)).thenReturn(vols);
-
-            // volume in uploaded state
-            VolumeInfo uploadedVolume = Mockito.mock(VolumeInfo.class);
-            when(uploadedVolume.getId()).thenReturn(8L);
-            when(uploadedVolume.getDataCenterId()).thenReturn(1L);
-            when(uploadedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
-            when(uploadedVolume.getInstanceId()).thenReturn(null);
-            when(uploadedVolume.getPoolId()).thenReturn(1L);
-            when(uploadedVolume.getState()).thenReturn(Volume.State.Uploaded);
-            when(volumeApiServiceImpl.volFactory.getVolume(8L)).thenReturn(uploadedVolume);
-
-            VolumeVO upVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
-            upVolume.setPoolId(1L);
-            upVolume.setDataCenterId(1L);
-            upVolume.setState(Volume.State.Uploaded);
-            when(volumeApiServiceImpl._volsDao.findById(8L)).thenReturn(upVolume);
-
-            // helper dao methods mock
-            when(volumeApiServiceImpl._vmSnapshotDao.findByVm(any(Long.class))).thenReturn(new ArrayList<VMSnapshotVO>());
-            when(volumeApiServiceImpl._vmInstanceDao.findById(any(Long.class))).thenReturn(stoppedVm);
-
-            DataCenterVO enabledZone = Mockito.mock(DataCenterVO.class);
-            when(enabledZone.getAllocationState()).thenReturn(Grouping.AllocationState.Enabled);
-
-            when(volumeApiServiceImpl._dcDao.findById(anyLong())).thenReturn(enabledZone);
-
-        } finally {
-            txn.close("runVolumeDaoImplTest");
-        }
-
-        // helper methods mock
-        doNothing().when(volumeApiServiceImpl._accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
-        doNothing().when(volumeApiServiceImpl._jobMgr).updateAsyncJobAttachment(any(Long.class), any(String.class), any(Long.class));
-        when(volumeApiServiceImpl._jobMgr.submitAsyncJob(any(AsyncJobVO.class), any(String.class), any(Long.class))).thenReturn(1L);
-    }
-
-    /**
-     * TESTS FOR DETACH ROOT VOLUME, COUNT=4
-     * @throws Exception
-     */
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testDetachVolumeFromRunningVm() throws NoSuchFieldException, IllegalAccessException {
-        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
-        dedicateIdField.setAccessible(true);
-        dedicateIdField.set(detachCmd, 1L);
-        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testDetachVolumeFromStoppedHyperVVm() throws NoSuchFieldException, IllegalAccessException {
-        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
-        dedicateIdField.setAccessible(true);
-        dedicateIdField.set(detachCmd, 3L);
-        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testDetachVolumeOfManagedDataStore() throws NoSuchFieldException, IllegalAccessException {
-        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
-        dedicateIdField.setAccessible(true);
-        dedicateIdField.set(detachCmd, 4L);
-        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
-    }
-
-    @Rule
-    public ExpectedException thrown = ExpectedException.none();
-
-    @Test
-    public void testDetachVolumeFromStoppedXenVm() throws NoSuchFieldException, IllegalAccessException {
-        thrown.expect(NullPointerException.class);
-        Field dedicateIdField = _detachCmdClass.getDeclaredField("id");
-        dedicateIdField.setAccessible(true);
-        dedicateIdField.set(detachCmd, 2L);
-        volumeApiServiceImpl.detachVolumeFromVM(detachCmd);
-    }
-
-    /**
-     * TESTS FOR ATTACH ROOT VOLUME, COUNT=7
-     */
-
-    // Negative test - try to attach non-root non-datadisk volume
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachIncorrectDiskType() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(1L, 5L, 0L);
-    }
-
-    // Negative test - attach root volume to running vm
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachRootDiskToRunningVm() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(1L, 6L, 0L);
-    }
-
-    // Negative test - attach root volume to non-xen vm
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachRootDiskToHyperVm() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(3L, 6L, 0L);
-    }
-
-    // Negative test - attach root volume from the managed data store
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachRootDiskOfManagedDataStore() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(2L, 7L, 0L);
-    }
-
-    // Negative test - root volume can't be attached to the vm already having a root volume attached
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachRootDiskToVmHavingRootDisk() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(4L, 6L, 0L);
-    }
-
-    // Negative test - root volume in uploaded state can't be attached
-    @Test(expected = InvalidParameterValueException.class)
-    public void attachRootInUploadedState() throws NoSuchFieldException, IllegalAccessException {
-        volumeApiServiceImpl.attachVolumeToVM(2L, 8L, 0L);
-    }
-
-    // Positive test - attach ROOT volume in correct state, to the vm not having root volume attached
-    @Test
-    public void attachRootVolumePositive() throws NoSuchFieldException, IllegalAccessException {
-        thrown.expect(NullPointerException.class);
-        volumeApiServiceImpl.attachVolumeToVM(2L, 6L, 0L);
-    }
-
-    // volume not Ready
-    @Test(expected = InvalidParameterValueException.class)
-    public void testTakeSnapshotF1() throws ResourceAllocationException {
-        when(volumeDataFactoryMock.getVolume(anyLong())).thenReturn(volumeInfoMock);
-        when(volumeInfoMock.getState()).thenReturn(Volume.State.Allocated);
-        when(volumeInfoMock.getPoolId()).thenReturn(1L);
-        volumeApiServiceImpl.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false, null, false);
-    }
-
-    @Test
-    public void testTakeSnapshotF2() throws ResourceAllocationException {
-        when(volumeDataFactoryMock.getVolume(anyLong())).thenReturn(volumeInfoMock);
-        when(volumeInfoMock.getState()).thenReturn(Volume.State.Ready);
-        when(volumeInfoMock.getInstanceId()).thenReturn(null);
-        when(volumeInfoMock.getPoolId()).thenReturn(1L);
-        when(volumeServiceMock.takeSnapshot(Mockito.any(VolumeInfo.class))).thenReturn(snapshotInfoMock);
-        volumeApiServiceImpl.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false, null, false);
-    }
-
-    @Test
-    public void testNullGetVolumeNameFromCmd() {
-        when(createVolumeCmdMock.getVolumeName()).thenReturn(null);
-        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVolumeCmdMock));
-    }
-
-    @Test
-    public void testEmptyGetVolumeNameFromCmd() {
-        when(createVolumeCmdMock.getVolumeName()).thenReturn("");
-        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVolumeCmdMock));
-    }
-
-    @Test
-    public void testBlankGetVolumeNameFromCmd() {
-        when(createVolumeCmdMock.getVolumeName()).thenReturn("   ");
-        Assert.assertNotNull(volumeApiServiceImpl.getVolumeNameFromCommand(createVolumeCmdMock));
-    }
-
-    @Test
-    public void testNonEmptyGetVolumeNameFromCmd() {
-        when(createVolumeCmdMock.getVolumeName()).thenReturn("abc");
-        Assert.assertSame(volumeApiServiceImpl.getVolumeNameFromCommand(createVolumeCmdMock), "abc");
-    }
-
-    @Test
-    public void testUpdateMissingRootDiskControllerWithNullChainInfo() {
-        volumeApiServiceImpl.updateMissingRootDiskController(null, null);
-        verify(userVmManagerMock, times(0)).persistDeviceBusInfo(any(UserVmVO.class), anyString());
-    }
-
-    @Test
-    public void testUpdateMissingRootDiskControllerWithValidChainInfo() {
-        UserVmVO vm = userVmDaoMock.findById(1L);
-        assert vm.getType() == VirtualMachine.Type.User;
-        volumeApiServiceImpl.updateMissingRootDiskController(vm, "{\"diskDeviceBusName\":\"scsi0:0\",\"diskChain\":[\"[somedatastore] i-3-VM-somePath/ROOT-1.vmdk\"]}");
-        verify(userVmManagerMock, times(1)).persistDeviceBusInfo(any(UserVmVO.class), eq("scsi"));
-    }
-
-    @Test
-    /**
-     * Setting locationType for a non-managed storage should give an error
-     */
-    public void testAllocSnapshotNonManagedStorageArchive() {
-        try {
-            volumeApiServiceImpl.allocSnapshot(6L, 1L, "test", Snapshot.LocationType.SECONDARY);
-        } catch (InvalidParameterValueException e) {
-            Assert.assertEquals(e.getMessage(), "VolumeId: 6 LocationType is supported only for managed storage");
-            return;
-        } catch (ResourceAllocationException e) {
-            Assert.fail("Unexpected excepiton " + e.getMessage());
-        }
-
-        Assert.fail("Expected Exception for archive in non-managed storage");
-    }
-
-    /**
-     * The resource limit check for primary storage should not be skipped for Volume in 'Uploaded' state.
-     * @throws NoSuchFieldException
-     * @throws IllegalAccessException
-     * @throws ResourceAllocationException
-     */
-    @Test
-    public void testResourceLimitCheckForUploadedVolume() throws NoSuchFieldException, IllegalAccessException, ResourceAllocationException {
-        doThrow(new ResourceAllocationException("primary storage resource limit check failed", Resource.ResourceType.primary_storage)).when(volumeApiServiceImpl._resourceLimitMgr)
-        .checkResourceLimit(any(AccountVO.class), any(Resource.ResourceType.class), any(Long.class));
-        UserVmVO vm = Mockito.mock(UserVmVO.class);
-        VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
-        when(volumeToAttach.getId()).thenReturn(9L);
-        when(volumeToAttach.getDataCenterId()).thenReturn(34L);
-        when(volumeToAttach.getVolumeType()).thenReturn(Volume.Type.DATADISK);
-        when(volumeToAttach.getInstanceId()).thenReturn(null);
-        when(userVmDaoMock.findById(anyLong())).thenReturn(vm);
-        when(vm.getType()).thenReturn(VirtualMachine.Type.User);
-        when(vm.getState()).thenReturn(State.Running);
-        when(vm.getDataCenterId()).thenReturn(34L);
-        when(volumeApiServiceImpl._volsDao.findByInstanceAndType(anyLong(), any(Volume.Type.class))).thenReturn(new ArrayList<>(10));
-        when(volumeApiServiceImpl.volFactory.getVolume(9L)).thenReturn(volumeToAttach);
-        when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
-        DataCenterVO zoneWithDisabledLocalStorage = Mockito.mock(DataCenterVO.class);
-        when(volumeApiServiceImpl._dcDao.findById(anyLong())).thenReturn(zoneWithDisabledLocalStorage);
-        when(zoneWithDisabledLocalStorage.isLocalStorageEnabled()).thenReturn(true);
-        try {
-            volumeApiServiceImpl.attachVolumeToVM(2L, 9L, null);
-        } catch (InvalidParameterValueException e) {
-            Assert.assertEquals(e.getMessage(), ("primary storage resource limit check failed"));
-        }
-    }
-
-    @After
-    public void tearDown() {
-        CallContext.unregister();
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestVolumeNotFound() {
-        Mockito.doReturn(null).when(volumeDaoMock).findById(volumeMockId);
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestCannotOperateOnVolumeDueToSnapshot() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(false).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestVolumePluggedIntoVm() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(vmInstanceMockId).when(volumeVoMock).getInstanceId();
-
-        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestStateUploadOpAndDownloadInProgress() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
-        Mockito.doReturn(Volume.State.UploadOp).when(volumeVoMock).getState();
-
-        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-        Mockito.doReturn(volumeDataStoreVoMock).when(volumeDataStoreDaoMock).findByVolume(volumeMockId);
-        Mockito.doReturn(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS).when(volumeDataStoreVoMock).getDownloadState();
-
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestStateNotUploaded() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
-        Mockito.doReturn(Volume.State.NotUploaded).when(volumeVoMock).getState();
-
-        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void retrieveAndValidateVolumeTestUploadInProgress() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
-        Mockito.doReturn(Volume.State.UploadInProgress).when(volumeVoMock).getState();
-
-        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-    }
-
-    @Test
-    public void retrieveAndValidateVolumeTest() {
-        Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findById(volumeMockId);
-        Mockito.doReturn(null).when(volumeVoMock).getInstanceId();
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(true).when(snapshotManagerMock).canOperateOnVolume(volumeVoMock);
-        Mockito.doNothing().when(accountManagerMock).checkAccess(accountMock, null, true, volumeVoMock);
-        volumeApiServiceImpl.retrieveAndValidateVolume(volumeMockId, accountMock);
-
-        Mockito.verify(accountManagerMock).checkAccess(accountMock, null, true, volumeVoMock);
-    }
-
-    @Test
-    public void destroyVolumeIfPossibleTestVolumeStateIsDestroy() {
-        Mockito.doReturn(Volume.State.Destroy).when(volumeVoMock).getState();
-        configureMocksForTestDestroyVolumeWhenVolume();
-
-        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
-
-        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
-    }
-
-    @Test
-    public void destroyVolumeIfPossibleTestVolumeStateIsExpunging() {
-        Mockito.doReturn(Volume.State.Expunging).when(volumeVoMock).getState();
-        configureMocksForTestDestroyVolumeWhenVolume();
-
-        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
-
-        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
-    }
-
-    @Test
-    public void destroyVolumeIfPossibleTestVolumeStateIsExpunged() {
-        Mockito.doReturn(Volume.State.Expunged).when(volumeVoMock).getState();
-        configureMocksForTestDestroyVolumeWhenVolume();
-
-        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
-
-        verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState();
-    }
-
-    @Test
-    public void destroyVolumeIfPossibleTestVolumeStateReady() {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-        configureMocksForTestDestroyVolumeWhenVolume();
-
-        volumeApiServiceImpl.destroyVolumeIfPossible(volumeVoMock);
-
-        Mockito.verify(volumeServiceMock, Mockito.times(1)).destroyVolume(volumeMockId);
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.volume, true);
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
-    }
-
-    private void verifyMocksForTestDestroyVolumeWhenVolumeIsNotInRightState() {
-        Mockito.verify(volumeServiceMock, Mockito.times(0)).destroyVolume(volumeMockId);
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.volume, true);
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
-    }
-
-    private void configureMocksForTestDestroyVolumeWhenVolume() {
-        Mockito.doReturn(accountMockId).when(volumeVoMock).getAccountId();
-        Mockito.doReturn(true).when(volumeVoMock).isDisplayVolume();
-
-        Mockito.doNothing().when(volumeServiceMock).destroyVolume(volumeMockId);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.volume, true);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.primary_storage, true, volumeSizeMock);
-    }
-
-    @Test
-    public void expungeVolumesInPrimaryStorageIfNeededTestVolumeNotInPrimaryDataStore() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(null).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
-
-        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.verify(volumeServiceMock, Mockito.times(0)).expungeVolumeAsync(volumeInfoMock);
-        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(0)).get();
-    }
-
-    @Test
-    public void expungeVolumesInPrimaryStorageIfNeededTestVolumeInPrimaryDataStore() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
-
-        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.verify(volumeServiceMock, Mockito.times(1)).expungeVolumeAsync(volumeInfoMock);
-        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(1)).get();
-    }
-
-    @Test(expected = InterruptedException.class)
-    public void expungeVolumesInPrimaryStorageIfNeededTestThrowingInterruptedException() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
-        Mockito.doThrow(InterruptedException.class).when(asyncCallFutureVolumeapiResultMock).get();
-
-        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-    }
-
-    @Test(expected = ExecutionException.class)
-    public void expungeVolumesInPrimaryStorageIfNeededTestThrowingExecutionException() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Primary);
-        Mockito.doThrow(ExecutionException.class).when(asyncCallFutureVolumeapiResultMock).get();
-
-        volumeApiServiceImpl.expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-    }
-
-    @Test
-    public void expungeVolumesInSecondaryStorageIfNeededTestVolumeNotFoundInSecondaryStorage() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(null).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
-        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
-
-        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.verify(volumeServiceMock, Mockito.times(0)).expungeVolumeAsync(volumeInfoMock);
-        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(0)).get();
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(0)).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-    }
-
-    @Test
-    public void expungeVolumesInSecondaryStorageIfNeededTestVolumeFoundInSecondaryStorage() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
-        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
-
-        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.verify(volumeServiceMock, Mockito.times(1)).expungeVolumeAsync(volumeInfoMock);
-        Mockito.verify(asyncCallFutureVolumeapiResultMock, Mockito.times(1)).get();
-        Mockito.verify(resourceLimitServiceMock, Mockito.times(1)).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-    }
-
-    @Test(expected = InterruptedException.class)
-    public void expungeVolumesInSecondaryStorageIfNeededTestthrowinInterruptedException() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
-        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
-
-        Mockito.doThrow(InterruptedException.class).when(asyncCallFutureVolumeapiResultMock).get();
-
-        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-
-    }
-
-    @Test(expected = ExecutionException.class)
-    public void expungeVolumesInSecondaryStorageIfNeededTestthrowinExecutionException() throws InterruptedException, ExecutionException {
-        Mockito.doReturn(asyncCallFutureVolumeapiResultMock).when(volumeServiceMock).expungeVolumeAsync(volumeInfoMock);
-        Mockito.doReturn(volumeInfoMock).when(volumeDataFactoryMock).getVolume(volumeMockId, DataStoreRole.Image);
-        Mockito.doNothing().when(resourceLimitServiceMock).decrementResourceCount(accountMockId, ResourceType.secondary_storage, volumeSizeMock);
-        Mockito.doReturn(accountMockId).when(volumeInfoMock).getAccountId();
-        Mockito.doReturn(volumeSizeMock).when(volumeInfoMock).getSize();
-
-        Mockito.doThrow(ExecutionException.class).when(asyncCallFutureVolumeapiResultMock).get();
-
-        volumeApiServiceImpl.expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-
-    }
-
-    @Test
-    public void cleanVolumesCacheTest() {
-        List<VolumeInfo> volumeInfos = new ArrayList<>();
-        VolumeInfo volumeInfoMock1 = Mockito.mock(VolumeInfo.class);
-        VolumeInfo volumeInfoMock2 = Mockito.mock(VolumeInfo.class);
-
-        DataStore dataStoreMock1 = Mockito.mock(DataStore.class);
-        DataStore dataStoreMock2 = Mockito.mock(DataStore.class);
-        Mockito.doReturn(dataStoreMock1).when(volumeInfoMock1).getDataStore();
-        Mockito.doReturn(dataStoreMock2).when(volumeInfoMock2).getDataStore();
-
-        volumeInfos.add(volumeInfoMock1);
-        volumeInfos.add(volumeInfoMock2);
-
-        Mockito.doReturn(volumeInfos).when(volumeDataFactoryMock).listVolumeOnCache(volumeMockId);
-
-        volumeApiServiceImpl.cleanVolumesCache(volumeVoMock);
-
-        Mockito.verify(dataStoreMock1).getName();
-        Mockito.verify(dataStoreMock2).getName();
-
-        Mockito.verify(volumeInfoMock1).delete();
-        Mockito.verify(volumeInfoMock2).delete();
-    }
-
-    @Test
-    public void deleteVolumeTestVolumeStateAllocated() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Allocated).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).cleanVolumesCache(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-
-        assertTrue(result);
-        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.verify(volumeDaoMock).remove(volumeMockId);
-        Mockito.verify(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).cleanVolumesCache(volumeVoMock);
-    }
-
-    @Test
-    public void deleteVolumeTestVolumeStateReady() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).cleanVolumesCache(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-
-        assertTrue(result);
-        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).expungeVolumesInSecondaryStorageIfNeeded(volumeVoMock);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(1)).cleanVolumesCache(volumeVoMock);
-    }
-
-    @Test
-    public void deleteVolumeTestVolumeStateReadyThrowingInterruptedException() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doThrow(InterruptedException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-
-        assertFalse(result);
-        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-    }
-
-    @Test
-    public void deleteVolumeTestVolumeStateReadyThrowingExecutionException() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doThrow(ExecutionException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-
-        assertFalse(result);
-        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-    }
-
-    @Test
-    public void deleteVolumeTestVolumeStateReadyThrowingNoTransitionException() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doThrow(NoTransitionException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        boolean result = volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-
-        assertFalse(result);
-        Mockito.verify(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.verify(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.verify(volumeDaoMock, Mockito.times(0)).remove(volumeMockId);
-        Mockito.verify(volumeApiServiceImpl, Mockito.times(0)).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void deleteVolumeTestVolumeStateReadyThrowingRuntimeException() throws InterruptedException, ExecutionException, NoTransitionException {
-        Mockito.doReturn(Volume.State.Ready).when(volumeVoMock).getState();
-
-        Mockito.doReturn(volumeVoMock).when(volumeApiServiceImpl).retrieveAndValidateVolume(volumeMockId, accountMock);
-        Mockito.doNothing().when(volumeApiServiceImpl).destroyVolumeIfPossible(volumeVoMock);
-        Mockito.doThrow(RuntimeException.class).when(volumeApiServiceImpl).expungeVolumesInPrimaryStorageIfNeeded(volumeVoMock);
-
-        Mockito.doReturn(true).when(volumeDaoMock).remove(volumeMockId);
-        Mockito.doReturn(true).when(volumeApiServiceImpl).stateTransitTo(volumeVoMock, Volume.Event.DestroyRequested);
-
-        volumeApiServiceImpl.deleteVolume(volumeMockId, accountMock);
-    }
-}
diff --git a/server/test/com/cloud/storage/snapshot/SnapshotManagerTest.java b/server/test/com/cloud/storage/snapshot/SnapshotManagerTest.java
deleted file mode 100755
index 39eb703..0000000
--- a/server/test/com/cloud/storage/snapshot/SnapshotManagerTest.java
+++ /dev/null
@@ -1,339 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.storage.snapshot;
-
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-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.StorageStrategyFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.ScopeType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.snapshot.VMSnapshot;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SnapshotManagerTest {
-    @Spy
-    SnapshotManagerImpl _snapshotMgr = new SnapshotManagerImpl();
-    @Mock
-    SnapshotDao _snapshotDao;
-    @Mock
-    VolumeDao _volumeDao;
-    @Mock
-    UserVmDao _vmDao;
-    @Mock
-    PrimaryDataStoreDao _storagePoolDao;
-    @Mock
-    VMSnapshotDao _vmSnapshotDao;
-    @Mock
-    VMSnapshotVO vmSnapshotMock;
-    @Mock
-    Account account;
-    @Mock
-    UserVmVO vmMock;
-    @Mock
-    VolumeVO volumeMock;
-    @Mock
-    VolumeInfo volumeInfoMock;
-    @Mock
-    VolumeDataFactory volumeFactory;
-    @Mock
-    SnapshotVO snapshotMock;
-    @Mock
-    SnapshotInfo snapshotInfoMock;
-    @Mock
-    SnapshotDataFactory snapshotFactory;
-    @Mock
-    StorageStrategyFactory _storageStrategyFactory;
-    @Mock
-    SnapshotStrategy snapshotStrategy;
-    @Mock
-    AccountManager _accountMgr;
-    @Mock
-    ResourceLimitService _resourceLimitMgr;
-    @Mock
-    StoragePoolVO poolMock;
-    @Mock
-    ResourceManager _resourceMgr;
-    @Mock
-    DataStore storeMock;
-    @Mock
-    SnapshotDataStoreDao snapshotStoreDao;
-    @Mock
-    SnapshotDataStoreVO snapshotStoreMock;
-    @Mock
-    SnapshotService snapshotSrv;
-
-
-    private static final long TEST_SNAPSHOT_ID = 3L;
-    private static final long TEST_VOLUME_ID = 4L;
-    private static final long TEST_VM_ID = 5L;
-    private static final long TEST_STORAGE_POOL_ID = 6L;
-    private static final long TEST_VM_SNAPSHOT_ID = 6L;
-
-    @Before
-    public void setup() throws ResourceAllocationException {
-        MockitoAnnotations.initMocks(this);
-        _snapshotMgr._snapshotDao = _snapshotDao;
-        _snapshotMgr._volsDao = _volumeDao;
-        _snapshotMgr._vmDao = _vmDao;
-        _snapshotMgr.volFactory = volumeFactory;
-        _snapshotMgr.snapshotFactory = snapshotFactory;
-        _snapshotMgr._storageStrategyFactory = _storageStrategyFactory;
-        _snapshotMgr._accountMgr = _accountMgr;
-        _snapshotMgr._resourceLimitMgr = _resourceLimitMgr;
-        _snapshotMgr._storagePoolDao = _storagePoolDao;
-        _snapshotMgr._resourceMgr = _resourceMgr;
-        _snapshotMgr._vmSnapshotDao = _vmSnapshotDao;
-        _snapshotMgr._snapshotStoreDao = snapshotStoreDao;
-
-        when(_snapshotDao.findById(anyLong())).thenReturn(snapshotMock);
-        when(snapshotMock.getVolumeId()).thenReturn(TEST_VOLUME_ID);
-        when(snapshotMock.isRecursive()).thenReturn(false);
-
-        when(_volumeDao.findById(anyLong())).thenReturn(volumeMock);
-        when(volumeMock.getState()).thenReturn(Volume.State.Ready);
-        when(volumeFactory.getVolume(anyLong())).thenReturn(volumeInfoMock);
-        when(volumeInfoMock.getDataStore()).thenReturn(storeMock);
-        when(volumeInfoMock.getState()).thenReturn(Volume.State.Ready);
-        when(storeMock.getId()).thenReturn(TEST_STORAGE_POOL_ID);
-
-        when(snapshotFactory.getSnapshot(anyLong(), Mockito.any(DataStoreRole.class))).thenReturn(snapshotInfoMock);
-        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.BACKUP))).thenReturn(snapshotStrategy);
-        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.REVERT))).thenReturn(snapshotStrategy);
-        when(_storageStrategyFactory.getSnapshotStrategy(Mockito.any(SnapshotVO.class), Mockito.eq(SnapshotOperation.DELETE))).thenReturn(snapshotStrategy);
-
-        doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
-        doNothing().when(_snapshotMgr._resourceLimitMgr).checkResourceLimit(any(Account.class), any(ResourceType.class));
-        doNothing().when(_snapshotMgr._resourceLimitMgr).checkResourceLimit(any(Account.class), any(ResourceType.class), anyLong());
-        doNothing().when(_snapshotMgr._resourceLimitMgr).decrementResourceCount(anyLong(), any(ResourceType.class), anyLong());
-        doNothing().when(_snapshotMgr._resourceLimitMgr).incrementResourceCount(anyLong(), any(ResourceType.class));
-        doNothing().when(_snapshotMgr._resourceLimitMgr).incrementResourceCount(anyLong(), any(ResourceType.class), anyLong());
-
-        Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
-        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
-        CallContext.register(user, account);
-        when(_accountMgr.getAccount(anyLong())).thenReturn(account);
-
-        when(_storagePoolDao.findById(anyLong())).thenReturn(poolMock);
-        when(poolMock.getScope()).thenReturn(ScopeType.ZONE);
-        when(poolMock.getHypervisor()).thenReturn(HypervisorType.KVM);
-        when(_resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(any(HypervisorType.class), anyLong())).thenReturn(null);
-    }
-
-    @After
-    public void tearDown() {
-        CallContext.unregister();
-    }
-
-    // vm is destroyed
-    @Test(expected = CloudRuntimeException.class)
-    public void testAllocSnapshotF1() throws ResourceAllocationException {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getState()).thenReturn(State.Destroyed);
-        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
-    }
-
-    // active snapshots
-    @SuppressWarnings("unchecked")
-    @Test(expected = InvalidParameterValueException.class)
-    public void testAllocSnapshotF2() throws ResourceAllocationException {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getId()).thenReturn(TEST_VM_ID);
-        when(vmMock.getState()).thenReturn(State.Stopped);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
-        List<SnapshotVO> mockList = mock(List.class);
-        when(mockList.size()).thenReturn(1);
-        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
-        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
-    }
-
-    // active vm snapshots
-    @SuppressWarnings("unchecked")
-    @Test(expected = CloudRuntimeException.class)
-    public void testAllocSnapshotF3() throws ResourceAllocationException {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getId()).thenReturn(TEST_VM_ID);
-        when(vmMock.getState()).thenReturn(State.Stopped);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
-        List<SnapshotVO> mockList = mock(List.class);
-        when(mockList.size()).thenReturn(0);
-        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
-        List<VMSnapshotVO> mockList2 = mock(List.class);
-        when(mockList2.size()).thenReturn(1);
-        when(_vmSnapshotDao.listByInstanceId(TEST_VM_ID, VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging)).thenReturn(mockList2);
-        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
-    }
-
-    // successful test
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testAllocSnapshotF4() throws ResourceAllocationException {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getId()).thenReturn(TEST_VM_ID);
-        when(vmMock.getState()).thenReturn(State.Stopped);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(volumeInfoMock.getInstanceId()).thenReturn(TEST_VM_ID);
-        List<SnapshotVO> mockList = mock(List.class);
-        when(mockList.size()).thenReturn(0);
-        when(_snapshotDao.listByInstanceId(TEST_VM_ID, Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
-        List<VMSnapshotVO> mockList2 = mock(List.class);
-        when(mockList2.size()).thenReturn(0);
-        when(_vmSnapshotDao.listByInstanceId(TEST_VM_ID, VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging)).thenReturn(mockList2);
-        when(_snapshotDao.persist(any(SnapshotVO.class))).thenReturn(snapshotMock);
-        _snapshotMgr.allocSnapshot(TEST_VOLUME_ID, Snapshot.MANUAL_POLICY_ID, null, null);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testDeleteSnapshotF1() {
-        when(snapshotStrategy.deleteSnapshot(TEST_SNAPSHOT_ID)).thenReturn(true);
-        when(snapshotMock.getState()).thenReturn(Snapshot.State.Destroyed);
-        when(snapshotMock.getAccountId()).thenReturn(2L);
-        when(snapshotMock.getDataCenterId()).thenReturn(2L);
-
-        _snapshotMgr.deleteSnapshot(TEST_SNAPSHOT_ID);
-    }
-
-    // vm state not stopped
-    @Test(expected = InvalidParameterValueException.class)
-    public void testRevertSnapshotF1() {
-        when(volumeMock.getInstanceId()).thenReturn(TEST_VM_ID);
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getState()).thenReturn(State.Running);
-        _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
-    }
-
-    // vm on Xenserver, return null
-    @Test
-    public void testRevertSnapshotF2() {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getState()).thenReturn(State.Stopped);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
-        when(volumeMock.getFormat()).thenReturn(ImageFormat.VHD);
-        Snapshot snapshot = _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
-        Assert.assertNull(snapshot);
-    }
-
-    // vm on KVM, successful
-    @Test
-    public void testRevertSnapshotF3() {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getState()).thenReturn(State.Stopped);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(volumeMock.getFormat()).thenReturn(ImageFormat.QCOW2);
-        when (snapshotStrategy.revertSnapshot(Mockito.any(SnapshotInfo.class))).thenReturn(true);
-        when(_volumeDao.update(anyLong(), any(VolumeVO.class))).thenReturn(true);
-        Snapshot snapshot = _snapshotMgr.revertSnapshot(TEST_SNAPSHOT_ID);
-        Assert.assertNotNull(snapshot);
-    }
-
-    // vm on Xenserver, expected exception
-    @Test(expected = InvalidParameterValueException.class)
-    public void testBackupSnapshotFromVmSnapshotF1() {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
-        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
-        Assert.assertNull(snapshot);
-    }
-
-    // vm on KVM, first time
-    @Test
-    public void testBackupSnapshotFromVmSnapshotF2() {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(_vmSnapshotDao.findById(anyLong())).thenReturn(vmSnapshotMock);
-        when(snapshotStoreDao.findParent(any(DataStoreRole.class), anyLong(), anyLong())).thenReturn(null);
-        when(snapshotFactory.getSnapshot(anyLong(), Mockito.any(DataStore.class))).thenReturn(snapshotInfoMock);
-        when(storeMock.create(snapshotInfoMock)).thenReturn(snapshotInfoMock);
-        when(snapshotStoreDao.findBySnapshot(anyLong(), any(DataStoreRole.class))).thenReturn(snapshotStoreMock);
-        when(snapshotStoreDao.update(anyLong(), any(SnapshotDataStoreVO.class))).thenReturn(true);
-        when(_snapshotDao.update(anyLong(), any(SnapshotVO.class))).thenReturn(true);
-        when(vmMock.getAccountId()).thenReturn(2L);
-        when(snapshotStrategy.backupSnapshot(any(SnapshotInfo.class))).thenReturn(snapshotInfoMock);
-
-        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
-        Assert.assertNotNull(snapshot);
-    }
-
-    // vm on KVM, already backed up
-    @Test(expected = InvalidParameterValueException.class)
-    public void testBackupSnapshotFromVmSnapshotF3() {
-        when(_vmDao.findById(anyLong())).thenReturn(vmMock);
-        when(vmMock.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
-        when(_vmSnapshotDao.findById(anyLong())).thenReturn(vmSnapshotMock);
-        when(snapshotStoreDao.findParent(any(DataStoreRole.class), anyLong(), anyLong())).thenReturn(snapshotStoreMock);
-        when(snapshotStoreMock.getInstallPath()).thenReturn("VM_SNAPSHOT_NAME");
-        when(vmSnapshotMock.getName()).thenReturn("VM_SNAPSHOT_NAME");
-        Snapshot snapshot = _snapshotMgr.backupSnapshotFromVmSnapshot(TEST_SNAPSHOT_ID, TEST_VM_ID, TEST_VOLUME_ID, TEST_VM_SNAPSHOT_ID);
-        Assert.assertNull(snapshot);
-    }
-}
diff --git a/server/test/com/cloud/user/AccountManagerImplTest.java b/server/test/com/cloud/user/AccountManagerImplTest.java
deleted file mode 100644
index 9190cf8..0000000
--- a/server/test/com/cloud/user/AccountManagerImplTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import com.cloud.acl.DomainChecker;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.server.auth.UserAuthenticator;
-import com.cloud.utils.Pair;
-
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account.State;
-import com.cloud.vm.UserVmManagerImpl;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-
-
-public class AccountManagerImplTest extends AccountManagetImplTestBase {
-
-
-    @Mock
-    UserVmManagerImpl _vmMgr;
-
-    @Test
-    public void disableAccountNotexisting()
-            throws ConcurrentOperationException, ResourceUnavailableException {
-        Mockito.when(_accountDao.findById(42l)).thenReturn(null);
-        Assert.assertTrue(accountManager.disableAccount(42));
-    }
-
-    @Test
-    public void disableAccountDisabled() throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        AccountVO disabledAccount = new AccountVO();
-        disabledAccount.setState(State.disabled);
-        Mockito.when(_accountDao.findById(42l)).thenReturn(disabledAccount);
-        Assert.assertTrue(accountManager.disableAccount(42));
-    }
-
-    @Test
-    public void disableAccount() throws ConcurrentOperationException,
-    ResourceUnavailableException {
-        AccountVO account = new AccountVO();
-        account.setState(State.enabled);
-        Mockito.when(_accountDao.findById(42l)).thenReturn(account);
-        Mockito.when(_accountDao.createForUpdate()).thenReturn(new AccountVO());
-        Mockito.when(
-                _accountDao.update(Mockito.eq(42l),
-                        Mockito.any(AccountVO.class))).thenReturn(true);
-        Mockito.when(_vmDao.listByAccountId(42l)).thenReturn(
-                Arrays.asList(Mockito.mock(VMInstanceVO.class)));
-        Assert.assertTrue(accountManager.disableAccount(42));
-        Mockito.verify(_accountDao, Mockito.atLeastOnce()).update(
-                Mockito.eq(42l), Mockito.any(AccountVO.class));
-    }
-
-    @Test
-    public void deleteUserAccount() {
-        AccountVO account = new AccountVO();
-        account.setId(42l);
-        DomainVO domain = new DomainVO();
-        Mockito.when(_accountDao.findById(42l)).thenReturn(account);
-        Mockito.when(
-                securityChecker.checkAccess(Mockito.any(Account.class),
-                        Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class),
-                        Mockito.anyString()))
-        .thenReturn(true);
-        Mockito.when(_accountDao.remove(42l)).thenReturn(true);
-        Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l))
-        .thenReturn(true);
-        Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
-        Mockito.when(
-                securityChecker.checkAccess(Mockito.any(Account.class),
-                        Mockito.any(Domain.class)))
-        .thenReturn(true);
-        Mockito.when(_vmSnapshotDao.listByAccountId(Mockito.anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
-
-        List<SSHKeyPairVO> sshkeyList = new ArrayList<SSHKeyPairVO>();
-        SSHKeyPairVO sshkey = new SSHKeyPairVO();
-        sshkey.setId(1l);
-        sshkeyList.add(sshkey);
-        Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList);
-        Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true);
-
-        Assert.assertTrue(accountManager.deleteUserAccount(42));
-        // assert that this was a clean delete
-        Mockito.verify(_accountDao, Mockito.never()).markForCleanup(
-                Mockito.eq(42l));
-    }
-
-    @Test
-    public void deleteUserAccountCleanup() {
-        AccountVO account = new AccountVO();
-        account.setId(42l);
-        DomainVO domain = new DomainVO();
-        Mockito.when(_accountDao.findById(42l)).thenReturn(account);
-        Mockito.when(
-                securityChecker.checkAccess(Mockito.any(Account.class),
-                        Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class),
-                        Mockito.anyString()))
-        .thenReturn(true);
-        Mockito.when(_accountDao.remove(42l)).thenReturn(true);
-        Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l))
-        .thenReturn(true);
-        Mockito.when(_userVmDao.listByAccountId(42l)).thenReturn(
-                Arrays.asList(Mockito.mock(UserVmVO.class)));
-        Mockito.when(
-                _vmMgr.expunge(Mockito.any(UserVmVO.class), Mockito.anyLong(),
-                        Mockito.any(Account.class))).thenReturn(false);
-        Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
-        Mockito.when(
-                securityChecker.checkAccess(Mockito.any(Account.class),
-                        Mockito.any(Domain.class)))
-        .thenReturn(true);
-
-        Assert.assertTrue(accountManager.deleteUserAccount(42));
-        // assert that this was NOT a clean delete
-        Mockito.verify(_accountDao, Mockito.atLeastOnce()).markForCleanup(
-                Mockito.eq(42l));
-    }
-
-
-    @Test
-    public void testAuthenticateUser() throws UnknownHostException {
-        Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> successAuthenticationPair = new Pair<>(true, null);
-        Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> failureAuthenticationPair = new Pair<>(false,
-                UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
-
-        UserAccountVO userAccountVO = new UserAccountVO();
-        userAccountVO.setSource(User.Source.UNKNOWN);
-        userAccountVO.setState(Account.State.disabled.toString());
-        Mockito.when(_userAccountDao.getUserAccount("test", 1L)).thenReturn(userAccountVO);
-        Mockito.when(userAuthenticator.authenticate("test", "fail", 1L, null)).thenReturn(failureAuthenticationPair);
-        Mockito.when(userAuthenticator.authenticate("test", null, 1L, null)).thenReturn(successAuthenticationPair);
-        Mockito.when(userAuthenticator.authenticate("test", "", 1L, null)).thenReturn(successAuthenticationPair);
-
-        //Test for incorrect password. authentication should fail
-        UserAccount userAccount = accountManager.authenticateUser("test", "fail", 1L, InetAddress.getByName("127.0.0.1"), null);
-        Assert.assertNull(userAccount);
-
-        //Test for null password. authentication should fail
-        userAccount = accountManager.authenticateUser("test", null, 1L, InetAddress.getByName("127.0.0.1"), null);
-        Assert.assertNull(userAccount);
-
-        //Test for empty password. authentication should fail
-        userAccount = accountManager.authenticateUser("test", "", 1L, InetAddress.getByName("127.0.0.1"), null);
-        Assert.assertNull(userAccount);
-
-        //Verifying that the authentication method is only called when password is specified
-        Mockito.verify(userAuthenticator, Mockito.times(1)).authenticate("test", "fail", 1L, null);
-        Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", null, 1L, null);
-        Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", "", 1L, null);
-    }
-
-    @Mock
-    AccountVO callingAccount;
-    @Mock
-    DomainChecker domainChecker;
-    @Mock
-    AccountService accountService;
-    @Mock
-    private GetUserKeysCmd _listkeyscmd;
-    @Mock
-    private Account _account;
-    @Mock
-    private User _user;
-    @Mock
-    private UserAccountVO userAccountVO;
-
-
-    @Test (expected = PermissionDeniedException.class)
-    public void testgetUserCmd(){
-        CallContext.register(callingUser, callingAccount); // Calling account is user account i.e normal account
-        Mockito.when(_listkeyscmd.getID()).thenReturn(1L);
-        Mockito.when(accountManager.getActiveUser(1L)).thenReturn(_user);
-        Mockito.when(accountManager.getUserAccountById(1L)).thenReturn(userAccountVO);
-        Mockito.when(userAccountVO.getAccountId()).thenReturn(1L);
-        Mockito.when(accountManager.getAccount(Mockito.anyLong())).thenReturn(_account); // Queried account - admin account
-
-        Mockito.when(callingUser.getAccountId()).thenReturn(1L);
-        Mockito.when(_accountDao.findById(1L)).thenReturn(callingAccount);
-
-        Mockito.when(accountService.isNormalUser(Mockito.anyLong())).thenReturn(Boolean.TRUE);
-        Mockito.when(_account.getAccountId()).thenReturn(2L);
-
-        accountManager.getKeys(_listkeyscmd);
-
-        }
-}
diff --git a/server/test/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java b/server/test/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java
deleted file mode 100644
index 2397713..0000000
--- a/server/test/com/cloud/user/AccountManagerImplVolumeDeleteEventTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.anyBoolean;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mockito;
-import org.mockito.Spy;
-
-import com.cloud.domain.DomainVO;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.UsageEventVO;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.CloudException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.Volume.Type;
-import com.cloud.vm.UserVmManagerImpl;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VirtualMachine;
-
-
-public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplTestBase {
-
-    private static final Long ACCOUNT_ID = 1l;
-    private static final String VOLUME_UUID = "vol-111111";
-
-    @Spy
-    @InjectMocks
-    UserVmManagerImpl _vmMgr;
-    Map<String, Object> oldFields = new HashMap<>();
-    UserVmVO vm = mock(UserVmVO.class);
-
-
-    // Configures the static fields of the UsageEventUtils class, Storing the
-    // previous values to be restored during the cleanup phase, to avoid
-    // interference with other unit tests.
-    protected UsageEventUtils setupUsageUtils() throws NoSuchMethodException, SecurityException, IllegalAccessException,
-    IllegalArgumentException, InvocationTargetException {
-
-        _usageEventDao = new MockUsageEventDao();
-        UsageEventUtils utils = new UsageEventUtils();
-
-        List<String> usageUtilsFields = new ArrayList<String>();
-        usageUtilsFields.add("usageEventDao");
-        usageUtilsFields.add("accountDao");
-        usageUtilsFields.add("dcDao");
-        usageUtilsFields.add("configDao");
-
-        for (String fieldName : usageUtilsFields) {
-            try {
-                Field f = UsageEventUtils.class.getDeclaredField(fieldName);
-                f.setAccessible(true);
-                Field staticField = UsageEventUtils.class.getDeclaredField("s_" + fieldName);
-                staticField.setAccessible(true);
-                oldFields.put(f.getName(), staticField.get(null));
-                f.set(utils,
-                        this.getClass().getSuperclass().getDeclaredField("_" + fieldName).get(this));
-            } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
-                e.printStackTrace();
-            }
-        }
-        Method method;
-        method = UsageEventUtils.class.getDeclaredMethod("init");
-        method.setAccessible(true);
-        method.invoke(utils);
-        return utils;
-    }
-
-
-    protected void defineMocksBehavior()
-            throws AgentUnavailableException, ConcurrentOperationException, CloudException {
-
-        AccountVO account = new AccountVO();
-        account.setId(ACCOUNT_ID);
-        when(_accountDao.remove(ACCOUNT_ID)).thenReturn(true);
-        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);
-
-        DomainVO domain = new DomainVO();
-        VirtualMachineEntity vmEntity = mock(VirtualMachineEntity.class);
-
-        when(_orchSrvc.getVirtualMachine(anyString())).thenReturn(vmEntity);
-        when(vmEntity.destroy(anyString(), anyBoolean())).thenReturn(true);
-
-        Mockito.doReturn(vm).when(_vmDao).findById(anyLong());
-
-        VolumeVO vol = new VolumeVO(VOLUME_UUID, 1l, 1l, 1l, 1l, 1l, "folder", "path", null, 50, Type.ROOT);
-        vol.setDisplayVolume(true);
-        List<VolumeVO> volumes = new ArrayList<>();
-        volumes.add(vol);
-
-        when(securityChecker.checkAccess(any(Account.class), any(ControlledEntity.class), any(AccessType.class),
-                anyString())).thenReturn(true);
-
-        when(_userVmDao.findById(anyLong())).thenReturn(vm);
-        when(_userVmDao.listByAccountId(ACCOUNT_ID)).thenReturn(Arrays.asList(vm));
-        when(_userVmDao.findByUuid(any(String.class))).thenReturn(vm);
-
-        when(_volumeDao.findByInstance(anyLong())).thenReturn(volumes);
-
-        ServiceOfferingVO offering = mock(ServiceOfferingVO.class);
-        when(offering.getCpu()).thenReturn(500);
-        when(offering.getId()).thenReturn(1l);
-        when(offering.getCpu()).thenReturn(500);
-        when(offering.getRamSize()).thenReturn(500);
-        when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong()))
-        .thenReturn(offering);
-
-        when(_domainMgr.getDomain(anyLong())).thenReturn(domain);
-
-        Mockito.doReturn(true).when(_vmMgr).expunge(any(UserVmVO.class), anyLong(), any(Account.class));
-
-    }
-
-    @Before
-    public void init()
-            throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
-            InvocationTargetException, AgentUnavailableException, ConcurrentOperationException, CloudException {
-
-        setupUsageUtils();
-        defineMocksBehavior();
-    }
-
-    @After
-    // Restores static fields of the UsageEventUtil class to previous values.
-    public void cleanupUsageUtils() throws ReflectiveOperationException, SecurityException {
-
-        UsageEventUtils utils = new UsageEventUtils();
-        for (String fieldName : oldFields.keySet()) {
-            Field f = UsageEventUtils.class.getDeclaredField(fieldName);
-            f.setAccessible(true);
-            f.set(utils, oldFields.get(fieldName));
-        }
-        Method method = UsageEventUtils.class.getDeclaredMethod("init");
-        method.setAccessible(true);
-        method.invoke(utils);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected List<UsageEventVO> deleteUserAccountRootVolumeUsageEvents(boolean vmDestroyedPrior)
-            throws AgentUnavailableException, ConcurrentOperationException, CloudException {
-
-        when(vm.getState())
-        .thenReturn(vmDestroyedPrior ? VirtualMachine.State.Destroyed : VirtualMachine.State.Running);
-        when(vm.getRemoved()).thenReturn(vmDestroyedPrior ? new Date() : null);
-        accountManager.deleteUserAccount(ACCOUNT_ID);
-
-        return _usageEventDao.listAll();
-    }
-
-    @Test
-    // If the VM is alerady destroyed, no events should get emitted
-    public void destroyedVMRootVolumeUsageEvent() throws SecurityException, IllegalArgumentException,
-    ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
-        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(true);
-        Assert.assertEquals(0, emittedEvents.size());
-    }
-
-    @Test
-    // If the VM is running, we should see one emitted event for the root
-    // volume.
-    public void runningVMRootVolumeUsageEvent() throws SecurityException, IllegalArgumentException,
-    ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
-        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(false);
-        Assert.assertEquals(1, emittedEvents.size());
-        UsageEventVO event = emittedEvents.get(0);
-        Assert.assertEquals(EventTypes.EVENT_VOLUME_DELETE, event.getType());
-        Assert.assertEquals(VOLUME_UUID, event.getResourceName());
-
-    }
-}
diff --git a/server/test/com/cloud/user/AccountManagetImplTestBase.java b/server/test/com/cloud/user/AccountManagetImplTestBase.java
deleted file mode 100644
index 53b781a..0000000
--- a/server/test/com/cloud/user/AccountManagetImplTestBase.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.service.api.OrchestrationService;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.springframework.test.util.ReflectionTestUtils;
-
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.dao.ResourceCountDao;
-import com.cloud.configuration.dao.ResourceLimitDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.DataCenterVnetDao;
-import com.cloud.dc.dao.DedicatedResourceDao;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.dao.UsageEventDao;
-import com.cloud.network.as.AutoScaleManager;
-import com.cloud.network.dao.AccountGuestVlanMapDao;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.RemoteAccessVpnDao;
-import com.cloud.network.dao.VpnUserDao;
-import com.cloud.network.security.SecurityGroupManager;
-import com.cloud.network.security.dao.SecurityGroupDao;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpn.RemoteAccessVpnService;
-import com.cloud.network.vpn.Site2SiteVpnManager;
-import com.cloud.projects.ProjectManager;
-import com.cloud.projects.dao.ProjectAccountDao;
-import com.cloud.projects.dao.ProjectDao;
-import com.cloud.server.auth.UserAuthenticator;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.VolumeApiService;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.SSHKeyPairDao;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.InstanceGroupDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotManager;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-@RunWith(MockitoJUnitRunner.class)
-public class AccountManagetImplTestBase {
-
-    @Mock
-    AccountDao _accountDao;
-    @Mock
-    ConfigurationDao _configDao;
-    @Mock
-    ResourceCountDao _resourceCountDao;
-    @Mock
-    UserDao _userDao;
-    @Mock
-    InstanceGroupDao _vmGroupDao;
-    @Mock
-    UserAccountDao _userAccountDao;
-    @Mock
-    VolumeDao _volumeDao;
-    @Mock
-    UserVmDao _userVmDao;
-    @Mock
-    VMTemplateDao _templateDao;
-    @Mock
-    NetworkDao _networkDao;
-    @Mock
-    SecurityGroupDao _securityGroupDao;
-    @Mock
-    VMInstanceDao _vmDao;
-    @Mock
-    protected SnapshotDao _snapshotDao;
-    @Mock
-    protected VMTemplateDao _vmTemplateDao;
-    @Mock
-    SecurityGroupManager _networkGroupMgr;
-    @Mock
-    NetworkOrchestrationService _networkMgr;
-    @Mock
-    SnapshotManager _snapMgr;
-    @Mock
-    TemplateManager _tmpltMgr;
-    @Mock
-    ConfigurationManager _configMgr;
-    @Mock
-    VirtualMachineManager _itMgr;
-    @Mock
-    RemoteAccessVpnDao _remoteAccessVpnDao;
-    @Mock
-    RemoteAccessVpnService _remoteAccessVpnMgr;
-    @Mock
-    VpnUserDao _vpnUser;
-    @Mock
-    DataCenterDao _dcDao;
-    @Mock
-    DomainManager _domainMgr;
-    @Mock
-    ProjectManager _projectMgr;
-    @Mock
-    ProjectDao _projectDao;
-    @Mock
-    AccountDetailsDao _accountDetailsDao;
-    @Mock
-    DomainDao _domainDao;
-    @Mock
-    ProjectAccountDao _projectAccountDao;
-    @Mock
-    IPAddressDao _ipAddressDao;
-    @Mock
-    VpcManager _vpcMgr;
-    @Mock
-    DomainRouterDao _routerDao;
-    @Mock
-    Site2SiteVpnManager _vpnMgr;
-    @Mock
-    AutoScaleManager _autoscaleMgr;
-    @Mock
-    VolumeApiService volumeService;
-    @Mock
-    AffinityGroupDao _affinityGroupDao;
-    @Mock
-    AccountGuestVlanMapDao _accountGuestVlanMapDao;
-    @Mock
-    DataCenterVnetDao _dataCenterVnetDao;
-    @Mock
-    ResourceLimitService _resourceLimitMgr;
-    @Mock
-    ResourceLimitDao _resourceLimitDao;
-    @Mock
-    DedicatedResourceDao _dedicatedDao;
-    @Mock
-    GlobalLoadBalancerRuleDao _gslbRuleDao;
-    @Mock
-    MessageBus _messageBus;
-    @Mock
-    VMSnapshotManager _vmSnapshotMgr;
-    @Mock
-    VMSnapshotDao _vmSnapshotDao;
-    @Mock
-    User callingUser;
-    @Mock
-    Account callingAccount;
-
-    @Mock
-    SecurityChecker securityChecker;
-    @Mock
-    UserAuthenticator userAuthenticator;
-    @Mock
-    ServiceOfferingDao _serviceOfferingDao;
-    @Mock
-    ServiceOfferingDao _offeringDao;
-    @Mock
-    OrchestrationService _orchSrvc;
-    @Mock
-    SSHKeyPairDao _sshKeyPairDao;
-
-    AccountManagerImpl accountManager;
-
-    UsageEventDao _usageEventDao = new MockUsageEventDao();
-
-    @Before
-    public void setup()
-            throws NoSuchFieldException, SecurityException,
-            IllegalArgumentException, IllegalAccessException {
-        accountManager = new AccountManagerImpl();
-        Map<String, Field> declaredFields = getInheritedFields(this.getClass());
-        for (Field field : AccountManagerImpl.class.getDeclaredFields()) {
-            if (field.getAnnotation(Inject.class) != null) {
-                field.setAccessible(true);
-                if (declaredFields.containsKey(field.getName())) {
-                    Field mockField = declaredFields.get(field.getName());
-                    field.set(accountManager, mockField.get(this));
-                }
-            }
-        }
-        ReflectionTestUtils.setField(accountManager, "_userAuthenticators", Arrays.asList(userAuthenticator));
-        accountManager.setSecurityCheckers(Arrays.asList(securityChecker));
-        CallContext.register(callingUser, callingAccount);
-    }
-
-    @After
-    public void cleanup() {
-        CallContext.unregister();
-    }
-
-    public static Map<String, Field> getInheritedFields(Class<?> type) {
-        Map<String, Field> fields = new HashMap<>();
-        for (Class<?> c = type; c != null; c = c.getSuperclass()) {
-            for (Field f : c.getDeclaredFields()) {
-                fields.put(f.getName(), f);
-            }
-        }
-        return fields;
-    }
-
-    public static Map<Class<?>, Field> getInheritedFieldsByClass(Class<?> type) {
-        Map<Class<?>, Field> fields = new HashMap<>();
-        for (Class<?> c = type; c != null; c = c.getSuperclass()) {
-            for (Field f : c.getDeclaredFields()) {
-                fields.put(f.getType(), f);
-            }
-        }
-        return fields;
-    }
-}
diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java
deleted file mode 100644
index 0a92c14..0000000
--- a/server/test/com/cloud/user/MockAccountManagerImpl.java
+++ /dev/null
@@ -1,437 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.util.List;
-import java.util.Map;
-import java.net.InetAddress;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
-
-import com.cloud.api.query.vo.ControlledViewEntity;
-import com.cloud.domain.Domain;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.offering.DiskOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class MockAccountManagerImpl extends ManagerBase implements Manager, AccountManager {
-
-    @Override
-    public boolean deleteUserAccount(long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public UserAccount disableUser(long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount enableUser(long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount lockUser(long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount updateUser(UpdateUserCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account enableAccount(String accountName, Long domainId, Long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account lockAccount(String accountName, Long domainId, Long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account updateAccount(UpdateAccountCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getSystemAccount() {
-        return new AccountVO();
-    }
-
-    @Override
-    public User getSystemUser() {
-        return new UserVO();
-    }
-
-    @Override
-    public boolean deleteUser(DeleteUserCmd deleteUserCmd) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean moveUser(MoveUserCmd moveUserCmd) {
-        return false;
-    }
-
-    @Override
-    public boolean moveUser(long id, Long domainId, long accountId) {
-        return false;
-    }
-
-    @Override
-    public boolean isAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Account finalizeOwner(Account caller, String accountName, Long domainId, Long projectId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getActiveAccountByName(String accountName, Long domainId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount getActiveUserAccount(String username, Long domainId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
-                                  String timeZone) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getActiveAccountById(long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Account getAccount(long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User getActiveUser(long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User getUserIncludingRemoved(long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isRootAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public User getActiveUserByRegistrationToken(String registrationToken) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void markUserRegistered(long userId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void checkAccess(Account account, Domain domain) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void checkAccess(Account account, ServiceOffering so) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void checkAccess(Account account, DiskOffering dof) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-
-    @Override
-    public UserAccount getUserAccountById(Long userId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void logoutUser(long userId) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters) {
-        return null;
-    }
-
-    @Override
-    public Pair<User, Account> findUserByApiKey(String apiKey) {
-        return null;
-    }
-
-    @Override
-    public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
-        return null;
-    }
-
-    @Override
-    public String[] createApiKeyAndSecretKey(final long userId) {
-        return null;
-    }
-
-    @Override
-    public boolean enableAccount(long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
-            ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
-            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId,
-            boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) {
-        // TODO Auto-generated method stub
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.user.AccountService#getUserByApiKey(java.lang.String)
-     */
-    @Override
-    public UserAccount getUserByApiKey(String apiKey) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName,
-        short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId,
-                                         Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public User createUser(String userName, String password, String firstName,
-            String lastName, String email, String timeZone, String accountName,
-            Long domainId, String userUUID) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override public User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
-                                     String userUUID, User.Source source) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public RoleType getRoleType(Account account) {
-        return null;
-    }
-
-    @Override
-    public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Account createAccount(String accountName, short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String uuid) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isDomainAdmin(Long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isNormalUser(long accountId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public List<String> listAclGroupsByAccount(Long accountId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
-            ControlledEntity... entities) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<String, String> getKeys(GetUserKeysCmd cmd) {
-        return null;
-    }
-
-    @Override
-    public void checkAccess(User user, ControlledEntity entity)
-        throws PermissionDeniedException {
-
-    }
-    @Override
-    public String getConfigComponentName() {
-        return null;
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return null;
-    }
-
-}
diff --git a/server/test/com/cloud/user/MockDomainManagerImpl.java b/server/test/com/cloud/user/MockDomainManagerImpl.java
deleted file mode 100644
index 394c3e2..0000000
--- a/server/test/com/cloud/user/MockDomainManagerImpl.java
+++ /dev/null
@@ -1,164 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.user;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.ConfigurationException;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd;
-import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
-import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
-
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-
-@Component
-public class MockDomainManagerImpl extends ManagerBase implements DomainManager, DomainService {
-
-    @Override
-    public Domain getDomain(long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Domain getDomain(String uuid) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Domain getDomainByName(String name, long parentId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isChildDomain(Long parentId, Long childId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean deleteDomain(long domainId, Boolean cleanup) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Pair<List<? extends Domain>, Integer> searchForDomains(ListDomainsCmd cmd) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Pair<List<? extends Domain>, Integer> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Set<Long> getDomainChildrenIds(String parentDomainPath) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DomainVO findDomainByPath(String domainPath) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DomainVO findDomainByIdOrPath(Long id, String domainPath) {
-        return null;
-    }
-
-    @Override
-    public Set<Long> getDomainParentIds(long domainId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean removeDomain(long domainId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public List<? extends Domain> findInactiveDomains() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean deleteDomain(DomainVO domain, Boolean cleanup) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    @Override
-    public boolean start() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Domain createDomain(String name, Long parentId, String networkDomain, String domainUUID) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Domain updateDomain(UpdateDomainCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, String domainUUID) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
deleted file mode 100644
index 980b440..0000000
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ /dev/null
@@ -1,979 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.vpc;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
-import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
-import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
-import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
-import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
-import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
-import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
-import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.deploy.DeploymentPlan;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.GuestVlan;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkProfile;
-import com.cloud.network.NetworkService;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkServiceProvider;
-import com.cloud.network.PhysicalNetworkTrafficType;
-import com.cloud.network.dao.NetworkServiceMapDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.DhcpServiceProvider;
-import com.cloud.network.element.DnsServiceProvider;
-import com.cloud.network.element.LoadBalancingServiceProvider;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.StaticNatServiceProvider;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.network.guru.NetworkGuru;
-import com.cloud.network.router.VirtualRouter;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.user.User;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.NicVO;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.Type;
-import com.cloud.vm.VirtualMachineProfile;
-
-@Component
-public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrchestrationService, NetworkService {
-    @Inject
-    NetworkServiceMapDao _ntwkSrvcDao;
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-
-    @Inject
-    List<NetworkElement> _networkElements;
-
-    private static HashMap<String, String> s_providerToNetworkElementMap = new HashMap<String, String>();
-    private static final Logger s_logger = Logger.getLogger(MockNetworkManagerImpl.class);
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#start()
-     */
-    @Override
-    public boolean start() {
-        for (NetworkElement element : _networkElements) {
-            Provider implementedProvider = element.getProvider();
-            if (implementedProvider != null) {
-                if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) {
-                    s_logger.error("Cannot start MapNetworkManager: Provider <-> NetworkElement must be a one-to-one map, " +
-                        "multiple NetworkElements found for Provider: " + implementedProvider.getName());
-                    return false;
-                }
-                s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName());
-            }
-        }
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
-     */
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#stop()
-     */
-    @Override
-    public boolean stop() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#getName()
-     */
-    @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getIsolatedNetworksOwnedByAccountInZone(long, com.cloud.user.Account)
-     */
-    @Override
-    public List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#allocateIP(com.cloud.user.Account, long, java.lang.Long)
-     */
-    @Override
-    public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp) throws ResourceAllocationException, InsufficientAddressCapacityException,
-        ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
-        return null;
-    }
-
-    @Override
-    public boolean releasePortableIpAddress(long ipAddressId) {
-        return false;// TODO Auto-generated method stub
-    }
-
-    /* (non-Javadoc)
-    * @see com.cloud.network.NetworkService#releaseIpAddress(long)
-    */
-    @Override
-    public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#createGuestNetwork(com.cloud.api.commands.CreateNetworkCmd)
-     */
-    @Override
-    public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#searchForNetworks(com.cloud.api.commands.ListNetworksCmd)
-     */
-    @Override
-    public Pair<List<? extends Network>, Integer> searchForNetworks(ListNetworksCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#deleteNetwork(long)
-     */
-    @Override
-    public boolean deleteNetwork(long networkId, boolean forced) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#restartNetwork(com.cloud.api.commands.RestartNetworkCmd, boolean)
-     */
-    @Override
-    public boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup, boolean makeRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
-        InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getActiveNicsInNetwork(long)
-     */
-    @Override
-    public int getActiveNicsInNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getNetwork(long)
-     */
-    @Override
-    public Network getNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getIp(long)
-     */
-    @Override
-    public IpAddress getIp(long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#updateGuestNetwork(long, java.lang.String, java.lang.String, com.cloud.user.Account, com.cloud.user.User, java.lang.String, java.lang.Long, java.lang.Boolean)
-     */
-    @Override
-    public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix,
-        Long networkOfferingId, Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID,boolean updateInSequence, boolean forced) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
-        return null;
-    }
-
-    @Override public Vpc migrateVpcNetwork(long vpcId, long vpcNetworkofferingId, Map<String, String> networkToOffering, Account account, User callerUser, boolean resume) {
-        return null;
-    }
-
-    /* (non-Javadoc)
-             * @see com.cloud.network.NetworkService#createPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.util.List, java.lang.String, java.lang.Long, java.util.List, java.lang.String)
-             */
-    @Override
-    public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange,
-        Long domainId, List<String> tags, String name) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#searchPhysicalNetworks(java.lang.Long, java.lang.Long, java.lang.String, java.lang.Long, java.lang.Long, java.lang.String)
-     */
-    @Override
-    public Pair<List<? extends PhysicalNetwork>, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#updatePhysicalNetwork(java.lang.Long, java.lang.String, java.util.List, java.lang.String, java.lang.String)
-     */
-    @Override
-    public PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List<String> tags, String newVnetRangeString, String state) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#deletePhysicalNetwork(java.lang.Long)
-     */
-    @Override
-    public boolean deletePhysicalNetwork(Long id) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId) {
-        // TODO Auto-generated method stub
-        return true;
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#listNetworkServices(java.lang.String)
-     */
-    @Override
-    public List<? extends Service> listNetworkServices(String providerName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#addProviderToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.Long, java.util.List)
-     */
-    @Override
-    public PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId,
-        List<String> enabledServices) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#listNetworkServiceProviders(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.Long)
-     */
-    @Override
-    public Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex,
-        Long pageSize) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#updateNetworkServiceProvider(java.lang.Long, java.lang.String, java.util.List)
-     */
-    @Override
-    public PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List<String> enabledServices) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#deleteNetworkServiceProvider(java.lang.Long)
-     */
-    @Override
-    public boolean deleteNetworkServiceProvider(Long id) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getPhysicalNetwork(java.lang.Long)
-     */
-    @Override
-    public PhysicalNetwork getPhysicalNetwork(Long physicalNetworkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getCreatedPhysicalNetwork(java.lang.Long)
-     */
-    @Override
-    public PhysicalNetwork getCreatedPhysicalNetwork(Long physicalNetworkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getPhysicalNetworkServiceProvider(java.lang.Long)
-     */
-    @Override
-    public PhysicalNetworkServiceProvider getPhysicalNetworkServiceProvider(Long providerId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getCreatedPhysicalNetworkServiceProvider(java.lang.Long)
-     */
-    @Override
-    public PhysicalNetworkServiceProvider getCreatedPhysicalNetworkServiceProvider(Long providerId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
-     */
-    @Override
-    public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-        String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getPhysicalNetworkTrafficType(java.lang.Long)
-     */
-    @Override
-    public PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#updatePhysicalNetworkTrafficType(java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
-     */
-    @Override
-    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#deletePhysicalNetworkTrafficType(java.lang.Long)
-     */
-    @Override
-    public boolean deletePhysicalNetworkTrafficType(Long id) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#listTrafficTypes(java.lang.Long)
-     */
-    @Override
-    public Pair<List<? extends PhysicalNetworkTrafficType>, Integer> listTrafficTypes(Long physicalNetworkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getExclusiveGuestNetwork(long)
-     */
-    @Override
-    public Network getExclusiveGuestNetwork(long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#listTrafficTypeImplementor(org.apache.cloudstack.api.commands.ListTrafficTypeImplementorsCmd)
-     */
-    @Override
-    public List<Pair<TrafficType, String>> listTrafficTypeImplementor(ListTrafficTypeImplementorsCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long, com.cloud.user.Account)
-     */
-    @Override
-    public List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#associateIPToNetwork(long, long)
-     */
-    @Override
-    public IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException,
-        ResourceUnavailableException, ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#createPrivateNetwork(java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long, java.lang.Long)
-     */
-    @Override
-    public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIP, String gateway,
-        String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId) throws ResourceAllocationException, ConcurrentOperationException,
-        InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#setupNetwork(com.cloud.user.Account, com.cloud.offerings.NetworkOfferingVO, com.cloud.deploy.DeploymentPlan, java.lang.String, java.lang.String, boolean)
-     */
-    @Override
-    public List<NetworkVO> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
-        throws ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#setupNetwork(com.cloud.user.Account, com.cloud.offerings.NetworkOfferingVO, com.cloud.network.Network, com.cloud.deploy.DeploymentPlan, java.lang.String, java.lang.String, boolean, java.lang.Long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
-     */
-    @Override
-    public List<NetworkVO> setupNetwork(Account owner, NetworkOffering offering, Network predefined, DeploymentPlan plan, String name, String displayText,
-        boolean errorIfAlreadySetup, Long domainId, ACLType aclType, Boolean subdomainAccess, Long vpcId, Boolean isNetworkDisplayEnabled)
-        throws ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#allocate(com.cloud.vm.VirtualMachineProfile, java.util.List)
-     */
-    @Override
-    public void allocate(VirtualMachineProfile vm, LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions)
-            throws InsufficientCapacityException, ConcurrentOperationException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void configureExtraDhcpOptions(Network network, long nicId, Map<Integer, String> extraDhcpOptions) {
-
-    }
-
-    @Override public void configureExtraDhcpOptions(Network network, long nicId) {
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#prepare(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
-     */
-    @Override
-    public void prepare(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException,
-        ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#release(com.cloud.vm.VirtualMachineProfile, boolean)
-     */
-    @Override
-    public void release(VirtualMachineProfile vmProfile, boolean forced) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#cleanupNics(com.cloud.vm.VirtualMachineProfile)
-     */
-    @Override
-    public void cleanupNics(VirtualMachineProfile vm) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#expungeNics(com.cloud.vm.VirtualMachineProfile)
-     */
-    @Override
-    public void expungeNics(VirtualMachineProfile vm) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#getNicProfiles(com.cloud.vm.VirtualMachine)
-     */
-    @Override
-    public List<NicProfile> getNicProfiles(VirtualMachine vm) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<String, String> getSystemVMAccessDetails(VirtualMachine vm) {
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#implementNetwork(long, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
-     */
-    @Override
-    public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
-        ResourceUnavailableException, InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<Integer, String> getExtraDhcpOptions(long nicId) {
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#shutdownNetwork(long, com.cloud.vm.ReservationContext, boolean)
-     */
-    @Override
-    public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#destroyNetwork(long, com.cloud.vm.ReservationContext)
-     */
-    @Override
-    public boolean destroyNetwork(long networkId, ReservationContext context, boolean forced) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#createGuestNetwork(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.cloud.user.Account, java.lang.Long, com.cloud.network.PhysicalNetwork, long, org.apache.cloudstack.acl.ControlledEntity.ACLType, java.lang.Boolean, java.lang.Long)
-     */
-    @Override
-    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
-                                      Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
-                                      String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
-        ResourceAllocationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#getPasswordResetProvider(com.cloud.network.Network)
-     */
-    @Override
-    public UserDataServiceProvider getPasswordResetProvider(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public UserDataServiceProvider getSSHKeyResetProvider(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#startNetwork(long, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext)
-     */
-    @Override
-    public boolean startNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
-        InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#reallocate(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DataCenterDeployment)
-     */
-    @Override
-    public boolean reallocate(VirtualMachineProfile vm, DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void saveExtraDhcpOptions(String networkUuid, Long nicId, Map<String, Map<Integer, String>> extraDhcpOptionMap) {
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#allocateNic(com.cloud.vm.NicProfile, com.cloud.network.Network, java.lang.Boolean, int, com.cloud.vm.VirtualMachineProfile)
-     */
-    @Override
-    public Pair<NicProfile, Integer> allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, VirtualMachineProfile vm)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context, long nicId, Network network)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
-        ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#removeNic(com.cloud.vm.VirtualMachineProfile, com.cloud.vm.Nic)
-     */
-    @Override
-    public void removeNic(VirtualMachineProfile vm, Nic nic) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-    * @see com.cloud.network.NetworkManager#setupDns(com.cloud.network.Network, com.cloud.network.Network.Provider)
-    */
-    @Override
-    public boolean setupDns(Network network, Provider provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.vm.Nic)
-     */
-    @Override
-    public void releaseNic(VirtualMachineProfile vmProfile, Nic nic) throws ConcurrentOperationException, ResourceUnavailableException {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean, boolean)
-     */
-    @Override
-    public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile vmProfile, boolean prepare)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException,
-        ResourceUnavailableException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#convertNetworkToNetworkProfile(long)
-     */
-    @Override
-    public NetworkProfile convertNetworkToNetworkProfile(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#restartNetwork(java.lang.Long, com.cloud.user.Account, com.cloud.user.User, boolean)
-     */
-    @Override
-    public boolean restartNetwork(Long networkId, Account callerAccount, User callerUser, boolean cleanup) throws ConcurrentOperationException,
-        ResourceUnavailableException, InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#shutdownNetworkElementsAndResources(com.cloud.vm.ReservationContext, boolean, com.cloud.network.NetworkVO)
-     */
-    @Override
-    public boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean b, Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#implementNetworkElementsAndResources(com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext, com.cloud.network.NetworkVO, com.cloud.offerings.NetworkOfferingVO)
-     */
-    @Override
-    public void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, Network network, NetworkOffering findById)
-        throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkManager#finalizeServicesAndProvidersForNetwork(com.cloud.offering.NetworkOffering, java.lang.Long)
-     */
-    @Override
-    public Map<String, String> finalizeServicesAndProvidersForNetwork(NetworkOffering offering, Long physicalNetworkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isNetworkInlineMode(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public List<Provider> getProvidersForServiceInNetwork(Network network, Service service) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public StaticNatServiceProvider getStaticNatProviderForNetwork(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network, Scheme lbScheme) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkService#getNetwork(java.lang.String)
-     */
-    @Override
-    public Network getNetwork(String networkUuid) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isSecondaryIpSetForNic(long nicId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public NicSecondaryIp allocateSecondaryGuestIP(long nicId, String ipaddress) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean releaseSecondaryIpFromNic(long ipAddressId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public List<? extends Nic> listVmNics(long vmId, Long nicId, Long networkId, String keyword) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<? extends Nic> listNics(ListNicsCmd listNicsCmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<Network.Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public NicVO savePlaceholderNic(Network network, String ip4Address, String ip6Address, Type vmType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DhcpServiceProvider getDhcpServiceProvider(Network network) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public DnsServiceProvider getDnsServiceProvider(Network network) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public void removeDhcpServiceInSubnet(Nic nic) {
-        //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest) {
-        return;
-    }
-
-    @Override
-    public boolean canUpdateInSequence(Network network, boolean forced) {
-        return false;
-    }
-
-    @Override
-    public List<String> getServicesNotSupportedInNewOffering(Network network, long newNetworkOfferingId) {
-        return null;
-    }
-
-    @Override
-    public void cleanupConfigForServicesInNetwork(List<String> services, Network network) {
-        return;
-    }
-
-    @Override
-    public void configureUpdateInSequence(Network network) {
-        return;
-    }
-
-    @Override
-    public int getResourceCount(Network network) {
-        return 0;
-    }
-
-    @Override public List<NetworkGuru> getNetworkGurus() {
-        return null;
-    }
-
-    @Override
-    public void destroyExpendableRouters(final List<? extends VirtualRouter> routers, final ReservationContext context) throws ResourceUnavailableException {
-    }
-
-    @Override
-    public boolean areRoutersRunning(final List<? extends VirtualRouter> routers) {
-        return false;
-    }
-
-    @Override
-    public void cleanupNicDhcpDnsEntry(Network network, VirtualMachineProfile vmProfile, NicProfile nicProfile) {
-    }
-
-    @Override
-    public void finalizeUpdateInSequence(Network network, boolean success) {
-        return;
-    }
-
-    @Override
-    public void prepareNicForMigration(VirtualMachineProfile vm, DeployDestination dest) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void commitNicForMigration(VirtualMachineProfile src, VirtualMachineProfile dst) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void rollbackNicForMigration(VirtualMachineProfile src, VirtualMachineProfile dst) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public IpAddress updateIP(Long id, String customId, Boolean displayIp) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd) {
-        return null;
-    }
-
-    @Override
-    public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
-        return true;
-    }
-
-    @Override
-    public AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException {
-        return null;
-    }
-}
diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java
deleted file mode 100644
index 33192a7..0000000
--- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java
+++ /dev/null
@@ -1,925 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.vpc;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.dc.Vlan;
-import com.cloud.exception.InsufficientAddressCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.GuestType;
-import com.cloud.network.Network.IpAddresses;
-import com.cloud.network.Network.Provider;
-import com.cloud.network.Network.Service;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.IsolationType;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.PhysicalNetwork;
-import com.cloud.network.PhysicalNetworkSetupInfo;
-import com.cloud.network.PublicIpAddress;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.NetworkElement;
-import com.cloud.network.element.UserDataServiceProvider;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Detail;
-import com.cloud.offerings.NetworkOfferingVO;
-import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
-import com.cloud.user.Account;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine;
-
-public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
-
-    @Inject
-    NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
-     */
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#start()
-     */
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#stop()
-     */
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.utils.component.Manager#getName()
-     */
-    @Override
-    public String getName() {
-        return "MockNetworkModelImpl";
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
-     */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToGuestNtwk(long, long, java.lang.Boolean)
-     */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToGuestNtwk(long associatedNetworkId, Boolean sourceNat) {
-
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSystemAccountNetworkOfferings(java.lang.String[])
-     */
-    @Override
-    public List<NetworkOfferingVO> getSystemAccountNetworkOfferings(String... offeringNames) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNics(long)
-     */
-    @Override
-    public List<? extends Nic> getNics(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNextAvailableMacAddressInNetwork(long)
-     */
-    @Override
-    public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPublicIpAddress(long)
-     */
-    @Override
-    public PublicIpAddress getPublicIpAddress(long ipAddressId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPodVlans(long)
-     */
-    @Override
-    public List<? extends Vlan> listPodVlans(long podId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksUsedByVm(long, boolean)
-     */
-    @Override
-    public List<NetworkVO> listNetworksUsedByVm(long vmId, boolean isSystem) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicInNetwork(long, long)
-     */
-    @Override
-    public Nic getNicInNetwork(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicsForTraffic(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultNetworkForVm(long)
-     */
-    @Override
-    public Network getDefaultNetworkForVm(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultNic(long)
-     */
-    @Override
-    public Nic getDefaultNic(long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getUserDataUpdateProvider(com.cloud.network.Network)
-     */
-    @Override
-    public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#networkIsConfiguredForExternalNetworking(long, long)
-     */
-    @Override
-    public boolean networkIsConfiguredForExternalNetworking(long zoneId, long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkServiceCapabilities(long, com.cloud.network.Network.Service)
-     */
-    @Override
-    public Map<Capability, String> getNetworkServiceCapabilities(long networkId, Service service) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isSharedNetworkWithoutServices(long networkId) {
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service[])
-     */
-    @Override
-    public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
-        return (_ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(networkOfferingId, services));
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkWithSGWithFreeIPs(java.lang.Long)
-     */
-    @Override
-    public NetworkVO getNetworkWithSGWithFreeIPs(Long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkWithSecurityGroupEnabled(java.lang.Long)
-     */
-    @Override
-    public NetworkVO getNetworkWithSecurityGroupEnabled(Long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpOfNetworkElementInVirtualNetwork(long, long)
-     */
-    @Override
-    public String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksForAccount(long, long, com.cloud.network.Network.GuestType)
-     */
-    @Override
-    public List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, GuestType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listAllNetworksInAllZonesByType(com.cloud.network.Network.GuestType)
-     */
-    @Override
-    public List<NetworkVO> listAllNetworksInAllZonesByType(GuestType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getStartIpAddress(long)
-     */
-    @Override
-    public String getStartIpAddress(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpInNetwork(long, long)
-     */
-    @Override
-    public String getIpInNetwork(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpInNetworkIncludingRemoved(long, long)
-     */
-    @Override
-    public String getIpInNetworkIncludingRemoved(long vmId, long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPodIdForVlan(long)
-     */
-    @Override
-    public Long getPodIdForVlan(long vlanDbId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworkOfferingsForUpgrade(long)
-     */
-    @Override
-    public List<Long> listNetworkOfferingsForUpgrade(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isSecurityGroupSupportedInNetwork(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isSecurityGroupSupportedInNetwork(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderSupportServiceInNetwork(long, com.cloud.network.Network.Service, com.cloud.network.Network.Provider)
-     */
-    @Override
-    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderEnabledInPhysicalNetwork(long, java.lang.String)
-     */
-    @Override
-    public boolean isProviderEnabledInPhysicalNetwork(long physicalNetowrkId, String providerName) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkTag(com.cloud.hypervisor.Hypervisor.HypervisorType, com.cloud.network.Network)
-     */
-    @Override
-    public String getNetworkTag(HypervisorType hType, Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getElementServices(com.cloud.network.Network.Provider)
-     */
-    @Override
-    public List<Service> getElementServices(Provider provider) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canElementEnableIndividualServices(com.cloud.network.Network.Provider)
-     */
-    @Override
-    public boolean canElementEnableIndividualServices(Provider provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesSupportedInNetwork(long, com.cloud.network.Network.Service[])
-     */
-    @Override
-    public boolean areServicesSupportedInNetwork(long networkId, Service... services) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkSystem(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isNetworkSystem(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceCapabilities(com.cloud.offering.NetworkOffering, com.cloud.network.Network.Service)
-     */
-    @Override
-    public Map<Capability, String> getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNetworkId(com.cloud.network.Network)
-     */
-    @Override
-    public Long getPhysicalNetworkId(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAllowSubdomainAccessGlobal()
-     */
-    @Override
-    public boolean getAllowSubdomainAccessGlobal() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderForNetwork(com.cloud.network.Network.Provider, long)
-     */
-    @Override
-    public boolean isProviderForNetwork(Provider provider, long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isProviderForNetworkOffering(com.cloud.network.Network.Provider, long)
-     */
-    @Override
-    public boolean isProviderForNetworkOffering(Provider provider, long networkOfferingId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canProviderSupportServices(java.util.Map)
-     */
-    @Override
-    public void canProviderSupportServices(Map<Provider, Set<Service>> providersMap) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNetworkInfo(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public List<PhysicalNetworkSetupInfo> getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canAddDefaultSecurityGroup()
-     */
-    @Override
-    public boolean canAddDefaultSecurityGroup() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworkOfferingServices(long)
-     */
-    @Override
-    public List<Service> listNetworkOfferingServices(long networkOfferingId) {
-        if (networkOfferingId == 2) {
-            return new ArrayList<Service>();
-        }
-
-        List<Service> services = new ArrayList<Service>();
-        services.add(Service.SourceNat);
-        return services;
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#areServicesEnabledInZone(long, com.cloud.offering.NetworkOffering, java.util.List)
-     */
-    @Override
-    public boolean areServicesEnabledInZone(long zoneId, NetworkOffering offering, List<Service> services) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#checkIpForService(com.cloud.network.IPAddressVO, com.cloud.network.Network.Service, java.lang.Long)
-     */
-    @Override
-    public boolean checkIpForService(IpAddress ip, Service service, Long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean providerSupportsCapability(Set<Provider> providers, Service service, Capability cap) {
-        return false;
-    }
-
-    /* (non-Javadoc)
-         * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String)
-         */
-    @Override
-    public void checkCapabilityForProvider(Set<Provider> providers, Service service, Capability cap, String capValue) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultUniqueProviderForService(java.lang.String)
-     */
-    @Override
-    public Provider getDefaultUniqueProviderForService(String serviceName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#checkNetworkPermissions(com.cloud.user.Account, com.cloud.network.Network)
-     */
-    @Override
-    public void checkNetworkPermissions(Account owner, Network network) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultStorageTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultPublicTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultGuestTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
-     */
-    @Override
-    public String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getElementImplementingProvider(java.lang.String)
-     */
-    @Override
-    public NetworkElement getElementImplementingProvider(String providerName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAccountNetworkDomain(long, long)
-     */
-    @Override
-    public String getAccountNetworkDomain(long accountId, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNtwkOffDistinctProviders(long)
-     */
-    @Override
-    public List<Provider> getNtwkOffDistinctProviders(long ntwkOffId) {
-        return new ArrayList<Provider>();
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean)
-     */
-    @Override
-    public List<IPAddressVO> listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getPhysicalNtwksSupportingTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public List<? extends PhysicalNetwork> getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isPrivateGateway(com.cloud.vm.Nic)
-     */
-    @Override
-    public boolean isPrivateGateway(long ntwkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkCapabilities(long)
-     */
-    @Override
-    public Map<Service, Map<Capability, String>> getNetworkCapabilities(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSystemNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDedicatedNetworkDomain(long)
-     */
-    @Override
-    public Long getDedicatedNetworkDomain(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkOfferingServiceProvidersMap(long)
-     */
-    @Override
-    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listSupportedNetworkServiceProviders(java.lang.String)
-     */
-    @Override
-    public List<? extends Provider> listSupportedNetworkServiceProviders(String serviceName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#listNetworksByVpc(long)
-     */
-    @Override
-    public List<? extends Network> listNetworksByVpc(long vpcId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#canUseForDeploy(com.cloud.network.Network)
-     */
-    @Override
-    public boolean canUseForDeploy(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getExclusiveGuestNetwork(long)
-     */
-    @Override
-    public Network getExclusiveGuestNetwork(long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#findPhysicalNetworkId(long, java.lang.String, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetworkRate(long, java.lang.Long)
-     */
-    @Override
-    public Integer getNetworkRate(long networkId, Long vmId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isVmPartOfNetwork(long, long)
-     */
-    @Override
-    public boolean isVmPartOfNetwork(long vmId, long ntwkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDefaultPhysicalNetworkByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
-    @Override
-    public PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNetwork(long)
-     */
-    @Override
-    public Network getNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIp(long)
-     */
-    @Override
-    public IpAddress getIp(long sourceIpAddressId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkAvailableInDomain(long, long)
-     */
-    @Override
-    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getNicProfile(com.cloud.vm.VirtualMachine, long, java.lang.String)
-     */
-    @Override
-    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getAvailableIps(com.cloud.network.Network, java.lang.String)
-     */
-    @Override
-    public Set<Long> getAvailableIps(Network network, String requestedIp) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getDomainNetworkDomain(long, long)
-     */
-    @Override
-    public String getDomainNetworkDomain(long domainId, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getIpToServices(java.util.List, boolean, boolean)
-     */
-    @Override
-    public Map<PublicIpAddress, Set<Service>> getIpToServices(List<? extends PublicIpAddress> publicIps, boolean rulesRevoked, boolean includingFirewall) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getProviderToIpList(com.cloud.network.Network, java.util.Map)
-     */
-    @Override
-    public Map<Provider, ArrayList<PublicIpAddress>> getProviderToIpList(Network network, Map<PublicIpAddress, Set<Service>> ipToServices) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#getSourceNatIpAddressForGuestNetwork(com.cloud.user.Account, com.cloud.network.Network)
-     */
-    @Override
-    public PublicIpAddress getSourceNatIpAddressForGuestNetwork(Account owner, Network guestNetwork) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
-     * @see com.cloud.network.NetworkModel#isNetworkInlineMode(com.cloud.network.Network)
-     */
-    @Override
-    public boolean isNetworkInlineMode(Network network) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInNetwork(long networkId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isIP6AddressAvailableInVlan(long vlanId) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public String getStartIpv6Address(long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isProviderEnabledInZone(long zoneId, String provider) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public Nic getPlaceholderNicForRouter(Network network, Long podId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IpAddress getPublicIpAddress(String ipAddress, long zoneId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<String> getUsedIpsInNetwork(Network network) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Map<Detail, String> getNtwkOffDetails(long offId) {
-        return null;
-    }
-
-    @Override
-    public IsolationType[] listNetworkIsolationMethods() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) {
-        return null;
-    }
-
-    @Override
-    public boolean getExecuteInSeqNtwkElmtCmd() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isNetworkReadyForGc(long networkId) {
-        return true;
-    }
-
-    @Override
-    public boolean getNetworkEgressDefaultPolicy(Long networkId) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId, String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows) {
-        return null;
-    }
-
-    @Override
-    public String getValidNetworkCidr(Network guestNetwork) {
-        return null;
-    }
-
-}
diff --git a/server/test/com/cloud/vpc/NetworkACLManagerTest.java b/server/test/com/cloud/vpc/NetworkACLManagerTest.java
deleted file mode 100644
index 9daf551..0000000
--- a/server/test/com/cloud/vpc/NetworkACLManagerTest.java
+++ /dev/null
@@ -1,338 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements.  See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.cloud.vpc;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import junit.framework.TestCase;
-
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.test.utils.SpringUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.element.NetworkACLServiceProvider;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.NetworkACLItem.State;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.network.vpc.NetworkACLManager;
-import com.cloud.network.vpc.NetworkACLManagerImpl;
-import com.cloud.network.vpc.NetworkACLVO;
-import com.cloud.network.vpc.PrivateGateway;
-import com.cloud.network.vpc.VpcGateway;
-import com.cloud.network.vpc.VpcGatewayVO;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcService;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.User;
-import com.cloud.user.UserVO;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.EntityManager;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class NetworkACLManagerTest extends TestCase {
-    @Inject
-    NetworkACLManager _aclMgr;
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    ConfigurationManager _configMgr;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    NetworkModel _networkModel;
-    @Inject
-    List<NetworkACLServiceProvider> _networkAclElements;
-    @Inject
-    VpcService _vpcSvc;
-    @Inject
-    VpcGatewayDao _vpcGatewayDao;
-
-    private NetworkACLVO acl;
-    private NetworkACLItemVO aclItem;
-
-    @Override
-    @Before
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-        final Account account = new AccountVO("testaccount", 1, "testdomain", (short)0, UUID.randomUUID().toString());
-        final UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
-
-        CallContext.register(user, account);
-        acl = Mockito.mock(NetworkACLVO.class);
-        aclItem = Mockito.mock(NetworkACLItemVO.class);
-    }
-
-    @Override
-    @After
-    public void tearDown() {
-        CallContext.unregister();
-    }
-
-    @Test
-    public void testCreateACL() throws Exception {
-        Mockito.when(_networkACLDao.persist(Matchers.any(NetworkACLVO.class))).thenReturn(acl);
-        assertNotNull(_aclMgr.createNetworkACL("acl_new", "acl desc", 1L, true));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testApplyACL() throws Exception {
-        final NetworkVO network = Mockito.mock(NetworkVO.class);
-        Mockito.when(_networkDao.findById(Matchers.anyLong())).thenReturn(network);
-        Mockito.when(_networkModel.isProviderSupportServiceInNetwork(Matchers.anyLong(), Matchers.any(Network.Service.class), Matchers.any(Network.Provider.class)))
-        .thenReturn(true);
-        Mockito.when(_networkAclElements.get(0).applyNetworkACLs(Matchers.any(Network.class), Matchers.anyList())).thenReturn(true);
-        assertTrue(_aclMgr.applyACLToNetwork(1L));
-    }
-
-    @Test
-    public void testApplyNetworkACL() throws Exception {
-        driveTestApplyNetworkACL(true, true, true);
-        driveTestApplyNetworkACL(false, false, true);
-        driveTestApplyNetworkACL(false, true, false);
-    }
-
-    @SuppressWarnings("unchecked")
-    public void driveTestApplyNetworkACL(final boolean result, final boolean applyNetworkACLs, final boolean applyACLToPrivateGw) throws Exception {
-        // In order to test ONLY our scope method, we mock the others
-        final NetworkACLManager aclManager = Mockito.spy(_aclMgr);
-
-        // Prepare
-        // Reset mocked objects to reuse
-        Mockito.reset(_networkACLItemDao);
-
-        // Make sure it is handled
-        final long aclId = 1L;
-        final NetworkVO network = Mockito.mock(NetworkVO.class);
-        final List<NetworkVO> networks = new ArrayList<NetworkVO>();
-        networks.add(network);
-        Mockito.when(_networkDao.listByAclId(Matchers.anyLong()))
-        .thenReturn(networks);
-        Mockito.when(_networkDao.findById(Matchers.anyLong())).thenReturn(network);
-        Mockito.when(_networkModel.isProviderSupportServiceInNetwork(Matchers.anyLong(),
-                Matchers.any(Network.Service.class), Matchers.any(Network.Provider.class)))
-                .thenReturn(true);
-        Mockito.when(_networkAclElements.get(0).applyNetworkACLs(Matchers.any(Network.class),
-                Matchers.anyList())).thenReturn(applyNetworkACLs);
-
-        // Make sure it applies ACL to private gateway
-        final List<VpcGatewayVO> vpcGateways = new ArrayList<VpcGatewayVO>();
-        final VpcGatewayVO vpcGateway = Mockito.mock(VpcGatewayVO.class);
-        final PrivateGateway privateGateway = Mockito.mock(PrivateGateway.class);
-        Mockito.when(_vpcSvc.getVpcPrivateGateway(Mockito.anyLong())).thenReturn(privateGateway);
-        vpcGateways.add(vpcGateway);
-        Mockito.when(_vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private))
-        .thenReturn(vpcGateways);
-
-        // Create 4 rules to test all 4 scenarios: only revoke should
-        // be deleted, only add should update
-        final List<NetworkACLItemVO> rules = new ArrayList<NetworkACLItemVO>();
-        final NetworkACLItemVO ruleActive = Mockito.mock(NetworkACLItemVO.class);
-        final NetworkACLItemVO ruleStaged = Mockito.mock(NetworkACLItemVO.class);
-        final NetworkACLItemVO rule2Revoke = Mockito.mock(NetworkACLItemVO.class);
-        final NetworkACLItemVO rule2Add = Mockito.mock(NetworkACLItemVO.class);
-        Mockito.when(ruleActive.getState()).thenReturn(NetworkACLItem.State.Active);
-        Mockito.when(ruleStaged.getState()).thenReturn(NetworkACLItem.State.Staged);
-        Mockito.when(rule2Add.getState()).thenReturn(NetworkACLItem.State.Add);
-        Mockito.when(rule2Revoke.getState()).thenReturn(NetworkACLItem.State.Revoke);
-        rules.add(ruleActive);
-        rules.add(ruleStaged);
-        rules.add(rule2Add);
-        rules.add(rule2Revoke);
-
-        final long revokeId = 8;
-        Mockito.when(rule2Revoke.getId()).thenReturn(revokeId);
-
-        final long addId = 9;
-        Mockito.when(rule2Add.getId()).thenReturn(addId);
-        Mockito.when(_networkACLItemDao.findById(addId)).thenReturn(rule2Add);
-
-        Mockito.when(_networkACLItemDao.listByACL(aclId))
-        .thenReturn(rules);
-        // Mock methods to avoid
-        Mockito.doReturn(applyACLToPrivateGw).when(aclManager).applyACLToPrivateGw(privateGateway);
-
-        // Execute
-        assertEquals("Result was not congruent with applyNetworkACLs and applyACLToPrivateGw", result, aclManager.applyNetworkACL(aclId));
-
-        // Assert if conditions met, network ACL was applied
-        final int timesProcessingDone = applyNetworkACLs && applyACLToPrivateGw ? 1 : 0;
-        Mockito.verify(_networkACLItemDao, Mockito.times(timesProcessingDone)).remove(revokeId);
-        Mockito.verify(rule2Add, Mockito.times(timesProcessingDone)).setState(NetworkACLItem.State.Active);
-        Mockito.verify(_networkACLItemDao, Mockito.times(timesProcessingDone)).update(addId, rule2Add);
-    }
-
-
-    @Test
-    public void testRevokeACLItem() throws Exception {
-        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
-        assertTrue(_aclMgr.revokeNetworkACLItem(1L));
-    }
-
-    @Test
-    public void testUpdateACLItem() throws Exception {
-        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
-        Mockito.when(_networkACLItemDao.update(Matchers.anyLong(), Matchers.any(NetworkACLItemVO.class))).thenReturn(true);
-        assertNotNull(_aclMgr.updateNetworkACLItem(1L, "UDP", null, NetworkACLItem.TrafficType.Ingress, "Deny", 10, 22, 32, null, null, null, true));
-    }
-
-    @Test
-    public void deleteNonEmptyACL() throws Exception {
-        final List<NetworkACLItemVO> aclItems = new ArrayList<NetworkACLItemVO>();
-        aclItems.add(aclItem);
-        Mockito.when(_networkACLItemDao.listByACL(Matchers.anyLong())).thenReturn(aclItems);
-        Mockito.when(acl.getId()).thenReturn(3l);
-        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
-        Mockito.when(aclItem.getState()).thenReturn(State.Add);
-        Mockito.when(aclItem.getId()).thenReturn(3l);
-        Mockito.when(_networkACLDao.remove(Matchers.anyLong())).thenReturn(true);
-
-        final boolean result = _aclMgr.deleteNetworkACL(acl);
-
-        Mockito.verify(aclItem, Mockito.times(4)).getState();
-
-        assertTrue("Operation should be successfull!", result);
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {NetworkACLManagerImpl.class}, includeFilters = {@ComponentScan.Filter(value = NetworkACLTestConfiguration.Library.class,
-    type = FilterType.CUSTOM)}, useDefaultFilters = false)
-    public static class NetworkACLTestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public AccountManager accountManager() {
-            return Mockito.mock(AccountManager.class);
-        }
-
-        @Bean
-        public NetworkOrchestrationService networkManager() {
-            return Mockito.mock(NetworkOrchestrationService.class);
-        }
-
-        @Bean
-        public NetworkModel networkModel() {
-            return Mockito.mock(NetworkModel.class);
-        }
-
-        @Bean
-        public VpcManager vpcManager() {
-            return Mockito.mock(VpcManager.class);
-        }
-
-        @Bean
-        public EntityManager entityManager() {
-            return Mockito.mock(EntityManager.class);
-        }
-
-        @Bean
-        public ResourceTagDao resourceTagDao() {
-            return Mockito.mock(ResourceTagDao.class);
-        }
-
-        @Bean
-        public NetworkACLDao networkACLDao() {
-            return Mockito.mock(NetworkACLDao.class);
-        }
-
-        @Bean
-        public NetworkACLItemDao networkACLItemDao() {
-            return Mockito.mock(NetworkACLItemDao.class);
-        }
-
-        @Bean
-        public NetworkDao networkDao() {
-            return Mockito.mock(NetworkDao.class);
-        }
-
-        @Bean
-        public ConfigurationManager configMgr() {
-            return Mockito.mock(ConfigurationManager.class);
-        }
-
-        @Bean
-        public NetworkACLServiceProvider networkElements() {
-            return Mockito.mock(NetworkACLServiceProvider.class);
-        }
-
-        @Bean
-        public VpcGatewayDao vpcGatewayDao() {
-            return Mockito.mock(VpcGatewayDao.class);
-        }
-
-        @Bean
-        public VpcService vpcService() {
-            return Mockito.mock(VpcService.class);
-        }
-
-        @Bean
-        public MessageBus messageBus() {
-            return Mockito.mock(MessageBus.class);
-        }
-
-        public static class Library implements TypeFilter {
-            @Override
-            public boolean match(final MetadataReader mdr, final MetadataReaderFactory arg1) throws IOException {
-                mdr.getClassMetadata().getClassName();
-                final ComponentScan cs = NetworkACLTestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-
-}
diff --git a/server/test/com/cloud/vpc/NetworkACLServiceTest.java b/server/test/com/cloud/vpc/NetworkACLServiceTest.java
deleted file mode 100644
index 1909a4f..0000000
--- a/server/test/com/cloud/vpc/NetworkACLServiceTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements.  See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.cloud.vpc;
-
-import java.io.IOException;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import com.cloud.user.User;
-import junit.framework.TestCase;
-
-import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.test.utils.SpringUtils;
-import org.apache.log4j.Logger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.vpc.NetworkACLItem;
-import com.cloud.network.vpc.NetworkACLItemDao;
-import com.cloud.network.vpc.NetworkACLItemVO;
-import com.cloud.network.vpc.NetworkACLManager;
-import com.cloud.network.vpc.NetworkACLService;
-import com.cloud.network.vpc.NetworkACLServiceImpl;
-import com.cloud.network.vpc.NetworkACLVO;
-import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.VpcManager;
-import com.cloud.network.vpc.VpcService;
-import com.cloud.network.vpc.VpcVO;
-import com.cloud.network.vpc.dao.NetworkACLDao;
-import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.dao.VpcGatewayDao;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.UserVO;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.EntityManager;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class NetworkACLServiceTest extends TestCase {
-    @Inject
-    NetworkACLService _aclService;
-
-    @Inject
-    AccountManager _accountMgr;
-    @Inject
-    VpcManager _vpcMgr;
-    @Inject
-    NetworkACLManager _networkAclMgr;
-    @Inject
-    NetworkACLDao _networkACLDao;
-    @Inject
-    NetworkACLItemDao _networkACLItemDao;
-    @Inject
-    EntityManager _entityMgr;
-    @Inject
-    VpcDao _vpcDao;
-    @Inject
-    VpcService _vpcSrv;
-
-    private CreateNetworkACLCmd createACLItemCmd;
-    private NetworkACLVO acl;
-    private NetworkACLItemVO aclItem;
-
-    private static final Logger s_logger = Logger.getLogger(NetworkACLServiceTest.class);
-
-    @Override
-    @Before
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-        Account account = new AccountVO("testaccount", 1, "testdomain", (short)0, UUID.randomUUID().toString());
-        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
-
-        CallContext.register(user, account);
-
-        createACLItemCmd = new CreateNetworkACLCmd() {
-            @Override
-            public Long getACLId() {
-                return 3L;
-            }
-
-            @Override
-            public Integer getNumber() {
-                return 1;
-            }
-
-            @Override
-            public String getProtocol() {
-                return "TCP";
-            }
-        };
-
-        acl = new NetworkACLVO() {
-            @Override
-            public Long getVpcId() {
-                return 1L;
-            }
-
-            @Override
-            public long getId() {
-                return 1L;
-            }
-
-        };
-
-        aclItem = new NetworkACLItemVO() {
-            @Override
-            public long getAclId() {
-                return 4L;
-            }
-        };
-    }
-
-    @Override
-    @After
-    public void tearDown() {
-        CallContext.unregister();
-    }
-
-    @Test
-    public void testCreateACL() throws Exception {
-        Mockito.when(_entityMgr.findById(Matchers.eq(Vpc.class), Matchers.anyLong())).thenReturn(new VpcVO());
-        Mockito.when(_networkAclMgr.createNetworkACL("acl_new", "acl desc", 1L, true)).thenReturn(acl);
-        assertNotNull(_aclService.createNetworkACL("acl_new", "acl desc", 1L, true));
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testDeleteDefaultACL() throws Exception {
-        Mockito.when(_networkACLDao.findById(Matchers.anyLong())).thenReturn(acl);
-        Mockito.when(_networkAclMgr.deleteNetworkACL(acl)).thenReturn(true);
-        _aclService.deleteNetworkACL(1L);
-    }
-
-    @Test
-    public void testCreateACLItem() throws Exception {
-        Mockito.when(_entityMgr.findById(Matchers.eq(Vpc.class), Matchers.anyLong())).thenReturn(new VpcVO());
-        Mockito.when(_networkAclMgr.getNetworkACL(Matchers.anyLong())).thenReturn(acl);
-        Mockito.when(
-            _networkAclMgr.createNetworkACLItem(Matchers.anyInt(), Matchers.anyInt(), Matchers.anyString(), Matchers.anyList(), Matchers.anyInt(), Matchers.anyInt(),
-                        Matchers.any(NetworkACLItem.TrafficType.class), Matchers.anyLong(), Matchers.anyString(), Matchers.anyInt(), Matchers.anyBoolean())).thenReturn(
-                new NetworkACLItemVO());
-        Mockito.when(_networkACLItemDao.findByAclAndNumber(Matchers.anyLong(), Matchers.anyInt())).thenReturn(null);
-        assertNotNull(_aclService.createNetworkACLItem(createACLItemCmd));
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void testCreateACLItemDuplicateNumber() throws Exception {
-        Mockito.when(_entityMgr.findById(Matchers.eq(Vpc.class), Matchers.anyLong())).thenReturn(new VpcVO());
-        Mockito.when(_networkAclMgr.getNetworkACL(Matchers.anyLong())).thenReturn(acl);
-        Mockito.when(_networkACLItemDao.findByAclAndNumber(Matchers.anyLong(), Matchers.anyInt())).thenReturn(new NetworkACLItemVO());
-        _aclService.createNetworkACLItem(createACLItemCmd);
-    }
-
-    @Test
-    public void testDeleteACLItem() throws Exception {
-        Mockito.when(_networkACLItemDao.findById(Matchers.anyLong())).thenReturn(aclItem);
-        Mockito.when(_networkAclMgr.getNetworkACL(Matchers.anyLong())).thenReturn(acl);
-        Mockito.when(_networkAclMgr.revokeNetworkACLItem(Matchers.anyLong())).thenReturn(true);
-        Mockito.when(_entityMgr.findById(Mockito.eq(Vpc.class), Mockito.anyLong())).thenReturn(new VpcVO());
-        assertTrue(_aclService.revokeNetworkACLItem(1L));
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {NetworkACLServiceImpl.class}, includeFilters = {@ComponentScan.Filter(value = NetworkACLTestConfiguration.Library.class,
-                                                                                                               type = FilterType.CUSTOM)}, useDefaultFilters = false)
-    public static class NetworkACLTestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public EntityManager entityManager() {
-            return Mockito.mock(EntityManager.class);
-        }
-
-        @Bean
-        public AccountManager accountManager() {
-            return Mockito.mock(AccountManager.class);
-        }
-
-        @Bean
-        public NetworkOrchestrationService networkManager() {
-            return Mockito.mock(NetworkOrchestrationService.class);
-        }
-
-        @Bean
-        public NetworkModel networkModel() {
-            return Mockito.mock(NetworkModel.class);
-        }
-
-        @Bean
-        public VpcManager vpcManager() {
-            return Mockito.mock(VpcManager.class);
-        }
-
-        @Bean
-        public ResourceTagDao resourceTagDao() {
-            return Mockito.mock(ResourceTagDao.class);
-        }
-
-        @Bean
-        public NetworkACLDao networkACLDao() {
-            return Mockito.mock(NetworkACLDao.class);
-        }
-
-        @Bean
-        public NetworkACLItemDao networkACLItemDao() {
-            return Mockito.mock(NetworkACLItemDao.class);
-        }
-
-        @Bean
-        public NetworkDao networkDao() {
-            return Mockito.mock(NetworkDao.class);
-        }
-
-        @Bean
-        public NetworkACLManager networkACLManager() {
-            return Mockito.mock(NetworkACLManager.class);
-        }
-
-        @Bean
-        public VpcGatewayDao vpcGatewayDao() {
-            return Mockito.mock(VpcGatewayDao.class);
-        }
-
-        @Bean
-        public VpcDao vpcDao() {
-            return Mockito.mock(VpcDao.class);
-        }
-
-        @Bean
-        public VpcService vpcService() {
-            return Mockito.mock(VpcService.class);
-        }
-
-        public static class Library implements TypeFilter {
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                mdr.getClassMetadata().getClassName();
-                ComponentScan cs = NetworkACLTestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-
-}
diff --git a/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java b/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
deleted file mode 100644
index 14ecc97..0000000
--- a/server/test/org/apache/cloudstack/ca/CAManagerImplTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package org.apache.cloudstack.ca;
-
-import java.lang.reflect.Field;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.framework.ca.CAProvider;
-import org.apache.cloudstack.framework.ca.Certificate;
-import org.apache.cloudstack.utils.security.CertUtils;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.certificate.CrlVO;
-import com.cloud.certificate.dao.CrlDao;
-import com.cloud.host.Host;
-import com.cloud.host.dao.HostDao;
-
-@RunWith(MockitoJUnitRunner.class)
-public class CAManagerImplTest {
-
-    @Mock
-    private HostDao hostDao;
-    @Mock
-    private CrlDao crlDao;
-    @Mock
-    private AgentManager agentManager;
-    @Mock
-    private CAProvider caProvider;
-
-    private CAManagerImpl caManager;
-
-    private void addField(final CAManagerImpl provider, final String name, final Object o) throws IllegalAccessException, NoSuchFieldException {
-        Field f = CAManagerImpl.class.getDeclaredField(name);
-        f.setAccessible(true);
-        f.set(provider, o);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        caManager = new CAManagerImpl();
-        addField(caManager, "crlDao", crlDao);
-        addField(caManager, "hostDao", hostDao);
-        addField(caManager, "agentManager", agentManager);
-        addField(caManager, "configuredCaProvider", caProvider);
-
-        Mockito.when(caProvider.getProviderName()).thenReturn("root");
-        caManager.setCaProviders(Collections.singletonList(caProvider));
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        Mockito.reset(crlDao);
-        Mockito.reset(agentManager);
-        Mockito.reset(caProvider);
-    }
-
-    @Test(expected = ServerApiException.class)
-    public void testIssueCertificateThrowsException() throws Exception {
-        caManager.issueCertificate(null, null, null, 1, null);
-    }
-
-    @Test
-    public void testIssueCertificate() throws Exception {
-        caManager.issueCertificate(null, Collections.singletonList("domain.example"), null, 1, null);
-        Mockito.verify(caProvider, Mockito.times(1)).issueCertificate(Mockito.anyList(), Mockito.anyList(), Mockito.anyInt());
-        Mockito.verify(caProvider, Mockito.times(0)).issueCertificate(Mockito.anyString(), Mockito.anyList(), Mockito.anyList(), Mockito.anyInt());
-    }
-
-    @Test
-    public void testRevokeCertificate() throws Exception {
-        final CrlVO crl = new CrlVO(CertUtils.generateRandomBigInt(), "some.domain", "some-uuid");
-        Mockito.when(crlDao.revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString())).thenReturn(crl);
-        Mockito.when(caProvider.revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString())).thenReturn(true);
-        Assert.assertTrue(caManager.revokeCertificate(crl.getCertSerial(), crl.getCertCn(), null));
-        Mockito.verify(caProvider, Mockito.times(1)).revokeCertificate(Mockito.any(BigInteger.class), Mockito.anyString());
-    }
-
-    @Test
-    public void testProvisionCertificate() throws Exception {
-        final Host host = Mockito.mock(Host.class);
-        Mockito.when(host.getPrivateIpAddress()).thenReturn("1.2.3.4");
-        final KeyPair keyPair = CertUtils.generateRandomKeyPair(1024);
-        final X509Certificate certificate = CertUtils.generateV3Certificate(null, keyPair, keyPair.getPublic(), "CN=ca", "SHA256withRSA", 365, null, null);
-        Mockito.when(caProvider.issueCertificate(Mockito.anyString(), Mockito.anyList(), Mockito.anyList(), Mockito.anyInt())).thenReturn(new Certificate(certificate, null, Collections.singletonList(certificate)));
-        Mockito.when(agentManager.send(Mockito.anyLong(), Mockito.any(SetupKeyStoreCommand.class))).thenReturn(new SetupKeystoreAnswer("someCsr"));
-        Mockito.when(agentManager.reconnect(Mockito.anyLong())).thenReturn(true);
-        Assert.assertTrue(caManager.provisionCertificate(host, true, null));
-        Mockito.verify(agentManager, Mockito.times(2)).send(Mockito.anyLong(), Mockito.any(Answer.class));
-        Mockito.verify(agentManager, Mockito.times(1)).reconnect(Mockito.anyLong());
-    }
-}
\ No newline at end of file
diff --git a/server/test/resources/network-mgr-component.xml b/server/test/resources/network-mgr-component.xml
deleted file mode 100644
index a0ddce0..0000000
--- a/server/test/resources/network-mgr-component.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<?xml version="1.0"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<!--
-  components.xml is the configuration file for the VM Ops
-  insertion servers.  Someone can quickly pull together an
-  insertion server by selecting the correct adapters to use.
-
-  Here are some places to look for information.
-    - To find out the general functionality that each Manager 
-      or Adapter provide, look at the javadoc for the interface
-      that it implements.  The interface is usually the
-      "key" attribute in the declaration.
-    - To find specific implementation of each Manager or
-      Adapter, look at the javadoc for the actual class.  The 
-      class can be found in the <class> element.
-    - To find out the configuration parameters for each Manager 
-      or Adapter, look at the javadoc for the actual implementation
-      class.  It should be documented in the description of the 
-      class.
-    - To know more about the components.xml in general, look for
-      the javadoc for ComponentLocator.java.
-
-  If you found that the Manager or Adapter are not properly 
-  documented, please contact the author.
--->
-<components.xml>
-    <interceptor library="com.cloud.configuration.DefaultInterceptorLibrary"/>
-    <management-server class="com.cloud.network.NetworkManagerImpl" library="com.cloud.network.NetworkManagerTestComponentLibrary">
-        <dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl">
-             <param name="premium">true</param>
-        </dao>
-        <adapters key="com.cloud.network.guru.NetworkGuru">
-            <!--
-                 NOTE: The order of those gurus implicates priority of network traffic types the guru implements.
-                 The upper the higher priority. It effects listTafficTypeImplementors API which returns impelmentor
-                 of a specific network traffic.
-                 A fair question is, if two gurus implement the same two network traffic types, but these traffic types
-                 have cross priority, how to rank them? For example:
-                    GuruA (TrafficTypeA, TrafficTypeB)
-                    GuruB (TrafficTypeA, TrafficTypeB)
-                 we want GuruB.TrafficTypeB > GuruA.TrafficTypeB and GuruB.TrafficTypeA < GuruA.TrafficTypeA. As the priority
-                 implicated by order can not map to multiple traffic type, you have to do implement GuruC which inherits GuruB
-                 for TrafficTypeB. Then ranking them in order of:
-                    GuruC (TrafficTypeB)
-                    GuruA (TrafficTypeA, TrafficTypeB)
-                    GuruB (TrafficTypeA, TrafficTypeB)
-                 now GuruC represents TrafficTypeB with highest priority while GuruA represents TrafficTypeA with highest pirority.
-
-                 However, above case barely happens.
-            -->
-
-            <adapter name="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru"/>
-            <adapter name="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru"/>
-            <adapter name="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru"/>
-            <adapter name="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru"/>
-            <adapter name="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru"/>
-            <adapter name="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru"/>
-            <adapter name="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru"/>
-            <!--<adapter name="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru"/> -->
-            <adapter name="PrivateNetworkGuru" class="com.cloud.network.guru.PrivateNetworkGuru"/>
-            <!--<adapter name="NiciraNvpGuestNetworkGuru" class="com.cloud.network.guru.NiciraNvpGuestNetworkGuru"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.IpAddrAllocator">
-            <adapter name="Basic" class="com.cloud.network.ExternalIpAddressAllocator"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.NetworkElement">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <!--<adapter name="Ovs" class="com.cloud.network.element.OvsElement"/> -->
-            <!--<adapter name="ExternalDhcpServer" class="com.cloud.network.element.ExternalDhcpElement"/>-->
-            <adapter name="BareMetal" class="com.cloud.network.element.BareMetalElement"/>
-            <adapter name="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <!--<adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.element.FirewallServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.DhcpServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <adapter name="ExternalDhcpElement" class="com.cloud.network.element.ExternalDhcpElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.UserDataServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.SourceNatServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <!--<adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/>   -->
-        </adapters>
-        <adapters key="com.cloud.network.element.StaticNatServiceProvider">
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <!-- <adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.element.PortForwardingServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <!-- <adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.element.LoadBalancingServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.RemoteAccessVPNServiceProvider">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.Site2SiteVpnServiceProvider">
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.IpDeployer">
-            <adapter name="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement"/>
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-            <!-- <adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.element.ConnectivityProvider">
-            <!-- <adapter name="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        </adapters>
-        <adapters key="com.cloud.network.element.NetworkACLServiceProvider">
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-        <adapters key="com.cloud.network.element.VpcProvider">
-            <adapter name="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement"/>
-        </adapters>
-
-        <!--<manager name="OvsTunnelManager" key="com.cloud.network.ovs.OvsTunnelManager" class="com.cloud.network.ovs.OvsTunnelManagerImpl"/>-->
-        <!--<manager name="ElasticLoadBalancerManager" key="com.cloud.network.lb.ElasticLoadBalancerManager" class="com.cloud.network.lb.ElasticLoadBalancerManagerImpl"/>-->
-        <pluggableservice name="VirtualRouterElementService" key="com.cloud.network.element.VirtualRouterElementService" class="com.cloud.network.element.VirtualRouterElement"/>
-        <!-- <pluggableservice name="NiciraNvpElementService" key="com.cloud.network.element.NiciraNvpElementService" class="com.cloud.network.element.NiciraNvpElement"/> -->
-        <!--<dao name="OvsTunnelInterfaceDao" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" singleton="false"/> -->
-        <!--<dao name="OvsTunnelAccountDao" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" singleton="false"/> -->
-        <!--<dao name="NiciraNvpDao" class="com.cloud.network.dao.NiciraNvpDaoImpl" singleton="false"/> -->
-        <!--<dao name="NiciraNvpNicMappingDao" class="com.cloud.network.dao.NiciraNvpNicMappingDaoImpl" singleton="false"/> -->
-        <!--<dao name="NiciraNvpRouterMappingDao" class="com.cloud.network.dao.NiciraNvpRouterMappingDaoImpl" singleton="false"/> -->
-        <!--<dao name="ElasticLbVmMapDao" class="com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl" singleton="false"/> -->
-    </management-server>
-
-    <configuration-server class="com.cloud.server.ConfigurationServerImpl">
-        <dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl" singleton="false">
-             <param name="premium">true</param>
-        </dao>
-        <dao name="Snapshot policy defaults" class="com.cloud.storage.dao.SnapshotPolicyDaoImpl" singleton="false"/>
-        <dao name="DiskOffering configuration server" class="com.cloud.storage.dao.DiskOfferingDaoImpl" singleton="false"/>         
-        <dao name="ServiceOffering configuration server" class="com.cloud.service.dao.ServiceOfferingDaoImpl" singleton="false"/>
-        <dao name="host zone configuration server" class="com.cloud.dc.dao.DataCenterDaoImpl" singleton="false"/>
-        <dao name="host pod configuration server" class="com.cloud.dc.dao.HostPodDaoImpl" singleton="false"/>
-        <dao name="DomainDao" class="com.cloud.domain.dao.DomainDaoImpl" singleton="false"/>
-        <dao name="NetworkOfferingDao" class="com.cloud.offerings.dao.NetworkOfferingDaoImpl" singleton="false"/>
-        <dao name="DataCenterDao" class="com.cloud.dc.dao.DataCenterDaoImpl" singleton="false"/>
-        <dao name="NetworkDao" class="com.cloud.network.dao.NetworkDaoImpl" singleton="false"/>
-        <dao name="IpAddressDao" class="com.cloud.network.dao.IPAddressDaoImpl" singleton="false"/>     
-        <dao name="VlanDao" class="com.cloud.dc.dao.VlanDaoImpl" singleton="false"/>
-        <dao name="ResouceCountDao" class="com.cloud.configuration.dao.ResourceCountDaoImpl" singleton="false"/>
-        <dao name="AccountDao" class="com.cloud.user.dao.AccountDaoImpl" singleton="false"/>
-        <dao name="UserDao" class="com.cloud.user.dao.UserDaoImpl" singleton="false"/>
-        <dao name="NetworkOfferingServiceDao" class="com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl" singleton="false"/>
-        <dao name="VirtualRouterProviderDao" class="com.cloud.network.dao.VirtualRouterProviderDaoImpl" singleton="false"/>
-        <dao name="Site2SiteCustomerGatewayDao" class="com.cloud.network.dao.Site2SiteCustomerGatewayDaoImpl" singleton="false"/>
-        <dao name="Site2SiteVpnGatewayDao" class="com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl" singleton="false"/>
-        <dao name="Site2SiteVpnConnectionDao" class="com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl" singleton="false"/>
-    </configuration-server>
-    
-    
-</components.xml>
diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml
deleted file mode 100755
index da2e50e..0000000
--- a/services/console-proxy-rdp/rdpconsole/pom.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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>
-  <groupId>rdpclient</groupId>
-  <artifactId>cloudstack-service-console-proxy-rdpclient</artifactId>
-  <packaging>jar</packaging>
-  <name>Apache CloudStack Console Proxy - RDP Client</name>
-
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-services</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-
-  <!-- not parenting to the maven-default pom, as we want this in services -->
-  <build>
-    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
-    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
-    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
-    <outputDirectory>${basedir}/target/classes</outputDirectory>
-    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>${basedir}/src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>${basedir}/src/test/resources</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-        <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-                <excludes>
-                    <exclude>rdpclient/MockServerTest.java</exclude>
-                </excludes>
-            </configuration>
-        </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${cs.junit.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <!-- Apache Portable Runtime implementation of SSL protocol, which is compatible with broken MS RDP SSL suport.
-    NOTE: tomcat-native package with /usr/lib/libtcnative-1.so library is necessary for APR to work. -->
-    <dependency>
-      <groupId>org.apache.tomcat.embed</groupId>
-      <artifactId>tomcat-embed-core</artifactId>
-      <version>8.0.30</version>
-    </dependency>
-    <!-- Another implementation of SSL protocol. Does not work with broken MS RDP SSL too. -->
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcprov-jdk15on</artifactId>
-      <version>${cs.bcprov.version}</version>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/services/console-proxy/plugin/pom.xml b/services/console-proxy/plugin/pom.xml
deleted file mode 100644
index 1417a73..0000000
--- a/services/console-proxy/plugin/pom.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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-console-proxy</artifactId>
-  <name>Apache CloudStack Console Proxy - Plugin</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-console-proxy</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-</project>
diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml
index d14203f..1af1db6 100644
--- a/services/console-proxy/pom.xml
+++ b/services/console-proxy/pom.xml
@@ -1,39 +1,50 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>cloudstack-service-console-proxy</artifactId>
-  <name>Apache CloudStack Console Proxy</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-services</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
-  <modules>
-    <!-- The plugin isn't used by anything
-    <module>plugin</module>
-    -->
-    <module>server</module>
-  </modules>
+<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>cloudstack-service-console-proxy</artifactId>
+    <name>Apache CloudStack Console Proxy</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-services</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <module>server</module>
+        <module>rdpconsole</module>
+    </modules>
 </project>
diff --git a/services/console-proxy-rdp/rdpconsole/README.txt b/services/console-proxy/rdpconsole/README.txt
old mode 100755
new mode 100644
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/README.txt
rename to services/console-proxy/rdpconsole/README.txt
diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml
new file mode 100644
index 0000000..f0534f3
--- /dev/null
+++ b/services/console-proxy/rdpconsole/pom.xml
@@ -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.
+-->
+<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>
+    <groupId>rdpclient</groupId>
+    <artifactId>cloudstack-service-console-proxy-rdpclient</artifactId>
+    <packaging>jar</packaging>
+    <name>Apache CloudStack Console Proxy - RDP Client</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-service-console-proxy</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!--
+            Apache Portable Runtime implementation of SSL protocol, which is compatible with broken MS RDP SSL suport.
+            NOTE: tomcat-native package with /usr/lib/libtcnative-1.so library is necessary for APR to work.
+        -->
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+        </dependency>
+        <!-- Another implementation of SSL protocol. Does not work with broken MS RDP SSL too. -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/services/console-proxy-rdp/rdpconsole/rdp-config.bat b/services/console-proxy/rdpconsole/rdp-config.bat
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/rdp-config.bat
rename to services/console-proxy/rdpconsole/rdp-config.bat
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java b/services/console-proxy/rdpconsole/src/main/java/common/AwtKeyEventSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
rename to services/console-proxy/rdpconsole/src/main/java/common/AwtKeyEventSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java b/services/console-proxy/rdpconsole/src/main/java/common/AwtMouseEventSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
rename to services/console-proxy/rdpconsole/src/main/java/common/AwtMouseEventSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java b/services/console-proxy/rdpconsole/src/main/java/common/BitmapOrder.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
rename to services/console-proxy/rdpconsole/src/main/java/common/BitmapOrder.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java b/services/console-proxy/rdpconsole/src/main/java/common/BitmapRectangle.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
rename to services/console-proxy/rdpconsole/src/main/java/common/BitmapRectangle.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy/rdpconsole/src/main/java/common/BufferedImageCanvas.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
rename to services/console-proxy/rdpconsole/src/main/java/common/BufferedImageCanvas.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java b/services/console-proxy/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java b/services/console-proxy/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java b/services/console-proxy/rdpconsole/src/main/java/common/Client.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
rename to services/console-proxy/rdpconsole/src/main/java/common/Client.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java b/services/console-proxy/rdpconsole/src/main/java/common/CopyRectOrder.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
rename to services/console-proxy/rdpconsole/src/main/java/common/CopyRectOrder.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java b/services/console-proxy/rdpconsole/src/main/java/common/KeyOrder.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
rename to services/console-proxy/rdpconsole/src/main/java/common/KeyOrder.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java b/services/console-proxy/rdpconsole/src/main/java/common/MouseOrder.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
rename to services/console-proxy/rdpconsole/src/main/java/common/MouseOrder.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java b/services/console-proxy/rdpconsole/src/main/java/common/OrderType.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
rename to services/console-proxy/rdpconsole/src/main/java/common/OrderType.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java b/services/console-proxy/rdpconsole/src/main/java/common/ScreenDescription.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
rename to services/console-proxy/rdpconsole/src/main/java/common/ScreenDescription.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java b/services/console-proxy/rdpconsole/src/main/java/common/SizeChangeListener.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
rename to services/console-proxy/rdpconsole/src/main/java/common/SizeChangeListener.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java b/services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java b/services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/Any.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/Any.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/BerType.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/BerType.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/BitString.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/BitString.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/ObjectID.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/ObjectID.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/OctetString.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/OctetString.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/Sequence.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/Sequence.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/SequenceOf.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/SequenceOf.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java b/services/console-proxy/rdpconsole/src/main/java/common/asn1/Tag.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
rename to services/console-proxy/rdpconsole/src/main/java/common/asn1/Tag.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/IncrementalOption.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/IncrementalOption.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/IntOption.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/IntOption.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/Option.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/Option.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/OptionParser.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/OptionParser.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/StringArrayOption.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/StringArrayOption.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/StringOption.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/StringOption.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java b/services/console-proxy/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
rename to services/console-proxy/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/RdpClient.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/RdpClient.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java b/services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
rename to services/console-proxy/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java b/services/console-proxy/rdpconsole/src/main/java/streamer/BaseElement.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/BaseElement.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java b/services/console-proxy/rdpconsole/src/main/java/streamer/BufferPool.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/BufferPool.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java b/services/console-proxy/rdpconsole/src/main/java/streamer/ByteBuffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/ByteBuffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/DataSink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/DataSink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java b/services/console-proxy/rdpconsole/src/main/java/streamer/DataSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/DataSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Direction.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Direction.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Element.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Element.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Event.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Event.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java b/services/console-proxy/rdpconsole/src/main/java/streamer/InputStreamSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/InputStreamSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Link.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Link.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java b/services/console-proxy/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Order.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Order.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/OutputStreamSink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/OutputStreamSink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Pipeline.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Pipeline.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java b/services/console-proxy/rdpconsole/src/main/java/streamer/PipelineImpl.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/PipelineImpl.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java b/services/console-proxy/rdpconsole/src/main/java/streamer/Queue.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/Queue.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java b/services/console-proxy/rdpconsole/src/main/java/streamer/SocketWrapper.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/SocketWrapper.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java b/services/console-proxy/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/SyncLink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/SyncLink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java b/services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java b/services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java b/services/console-proxy/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/Dumper.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/Dumper.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/FakeSink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/FakeSink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/FakeSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/FakeSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockServer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockServer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockSink.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockSink.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java b/services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockSource.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/debug/MockSource.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java b/services/console-proxy/rdpconsole/src/main/java/streamer/ssl/SSLState.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/ssl/SSLState.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java b/services/console-proxy/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java b/services/console-proxy/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
rename to services/console-proxy/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/VncClient.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/VncClient.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java b/services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
rename to services/console-proxy/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt b/services/console-proxy/rdpconsole/src/main/resources/jaas_ntlm_config.txt
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
rename to services/console-proxy/rdpconsole/src/main/resources/jaas_ntlm_config.txt
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt b/services/console-proxy/rdpconsole/src/test/doc/README.txt
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
rename to services/console-proxy/rdpconsole/src/test/doc/README.txt
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat b/services/console-proxy/rdpconsole/src/test/doc/dev-rdp-config.bat
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
rename to services/console-proxy/rdpconsole/src/test/doc/dev-rdp-config.bat
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt b/services/console-proxy/rdpconsole/src/test/doc/freerdp-debug-log.txt
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
rename to services/console-proxy/rdpconsole/src/test/doc/freerdp-debug-log.txt
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp-key.pem b/services/console-proxy/rdpconsole/src/test/doc/rdp-key.pem
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/doc/rdp-key.pem
rename to services/console-proxy/rdpconsole/src/test/doc/rdp-key.pem
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx b/services/console-proxy/rdpconsole/src/test/doc/rdp.pfx
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx
rename to services/console-proxy/rdpconsole/src/test/doc/rdp.pfx
Binary files differ
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/common/ClientTest.java b/services/console-proxy/rdpconsole/src/test/java/common/ClientTest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/java/common/ClientTest.java
rename to services/console-proxy/rdpconsole/src/test/java/common/ClientTest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java b/services/console-proxy/rdpconsole/src/test/java/rdpclient/MockServerTest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
rename to services/console-proxy/rdpconsole/src/test/java/rdpclient/MockServerTest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/streamer/BaseElementTest.java b/services/console-proxy/rdpconsole/src/test/java/streamer/BaseElementTest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/java/streamer/BaseElementTest.java
rename to services/console-proxy/rdpconsole/src/test/java/streamer/BaseElementTest.java
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/streamer/ByteBufferTest.java b/services/console-proxy/rdpconsole/src/test/java/streamer/ByteBufferTest.java
similarity index 100%
rename from services/console-proxy-rdp/rdpconsole/src/test/java/streamer/ByteBufferTest.java
rename to services/console-proxy/rdpconsole/src/test/java/streamer/ByteBufferTest.java
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index 012452b..11ee05f 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -1,63 +1,64 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-console-proxy</artifactId>
-  <name>Apache CloudStack Console Proxy - Server</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-console-proxy</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>rdpclient</groupId>
-      <artifactId>cloudstack-service-console-proxy-rdpclient</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <resources>
-      <resource>
-        <directory>certs</directory>
-        <excludes>
-          <exclude>realhostip.csr</exclude>
-        </excludes>
-      </resource>
-    </resources>
-  </build>
+<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-console-proxy</artifactId>
+    <name>Apache CloudStack Console Proxy - Server</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-service-console-proxy</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>rdpclient</groupId>
+            <artifactId>cloudstack-service-console-proxy-rdpclient</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <resources>
+            <resource>
+                <directory>certs</directory>
+                <excludes>
+                    <exclude>realhostip.csr</exclude>
+                </excludes>
+            </resource>
+        </resources>
+    </build>
 </project>
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/AjaxFIFOImageCache.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/AjaxFIFOImageCache.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/AuthenticationException.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/AuthenticationException.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/AuthenticationException.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/AuthenticationException.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxy.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClient.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClient.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClient.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClient.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientBase.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientBase.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientBase.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientListener.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientListener.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientParam.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientParam.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientStatsCollector.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientStatsCollector.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientStatsCollector.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyClientStatsCollector.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyGCThread.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyMonitor.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyMonitor.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyPasswordBasedEncryptor.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyPasswordBasedEncryptor.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyPasswordBasedEncryptor.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyPasswordBasedEncryptor.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyRdpClient.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyRdpClient.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyServerFactory.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyServerFactory.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyVncClient.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyVncClient.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/InputEventType.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/InputEventType.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/InputEventType.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/InputEventType.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/rdp/KeysymToKeycode.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/rdp/KeysymToKeycode.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/ITileScanListener.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/ITileScanListener.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/ITileScanListener.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/ITileScanListener.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/ImageHelper.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/ImageHelper.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/ImageHelper.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/ImageHelper.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/Logger.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/Logger.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/Logger.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/Logger.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/LoggerFactory.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/LoggerFactory.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/LoggerFactory.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/LoggerFactory.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/RawHTTP.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/RawHTTP.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/RawHTTP.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/RawHTTP.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/Region.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/Region.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/Region.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/Region.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/RegionClassifier.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/RegionClassifier.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/RegionClassifier.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/RegionClassifier.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/TileInfo.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/TileInfo.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/TileInfo.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/TileInfo.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/util/TileTracker.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/TileTracker.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/util/TileTracker.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/util/TileTracker.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/PaintNotificationListener.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/PaintNotificationListener.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/RfbConstants.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/RfbConstants.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/RfbConstants.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/RfbConstants.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncClient.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncClient.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncClient.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncClient.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncClientPacketSender.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncClientPacketSender.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncScreenDescription.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncScreenDescription.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/SetPixelFormatPacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/SetPixelFormatPacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/client/SetPixelFormatPacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/client/SetPixelFormatPacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/AbstractRect.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/AbstractRect.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/AbstractRect.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/AbstractRect.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/CopyRect.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/CopyRect.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/CopyRect.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/CopyRect.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/FrameBufferSizeChangeRequest.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/FrameBufferSizeChangeRequest.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/FrameBufferSizeChangeRequest.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/FrameBufferSizeChangeRequest.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/FramebufferUpdatePacket.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/FramebufferUpdatePacket.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/FramebufferUpdatePacket.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/FramebufferUpdatePacket.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/RawRect.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/RawRect.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/RawRect.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/RawRect.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/Rect.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/Rect.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/Rect.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/Rect.java
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/ServerCutText.java b/services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/ServerCutText.java
similarity index 100%
rename from services/console-proxy/server/src/com/cloud/consoleproxy/vnc/packet/server/ServerCutText.java
rename to services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/packet/server/ServerCutText.java
diff --git a/services/console-proxy/server/test/com/cloud/consoleproxy/ConsoleProxyRdpClientTest.java b/services/console-proxy/server/src/test/java/com/cloud/consoleproxy/ConsoleProxyRdpClientTest.java
similarity index 100%
rename from services/console-proxy/server/test/com/cloud/consoleproxy/ConsoleProxyRdpClientTest.java
rename to services/console-proxy/server/src/test/java/com/cloud/consoleproxy/ConsoleProxyRdpClientTest.java
diff --git a/services/iam/plugin/pom.xml b/services/iam/plugin/pom.xml
deleted file mode 100644
index 6efef06..0000000
--- a/services/iam/plugin/pom.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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-iam</artifactId>
-  <name>Apache CloudStack IAM - Plugin</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-iam</artifactId>
-    <version>4.11.4.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-engine-schema</artifactId>
-      <version>${project.version}</version>    
-    </dependency> 
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>    
-    </dependency>  
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-iam</artifactId>
-      <version>${project.version}</version>    
-    </dependency>  
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>              
-  </dependencies> 
-</project>
diff --git a/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/module.properties b/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/module.properties
deleted file mode 100644
index c87480d..0000000
--- a/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/module.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-name=iam-access-checkers
-parent=api
\ No newline at end of file
diff --git a/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/spring-iam-access-checkers-context.xml b/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/spring-iam-access-checkers-context.xml
deleted file mode 100644
index 87e8c94..0000000
--- a/services/iam/plugin/resources/META-INF/cloudstack/iam-access-checkers/spring-iam-access-checkers-context.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context.xsd"
-                      >                     
-
-    <bean id="RoleBasedAPIAccessChecker" class="org.apache.cloudstack.iam.RoleBasedAPIAccessChecker" />
-    <bean id="RoleBasedEntityAccessChecker" class="org.apache.cloudstack.iam.RoleBasedEntityAccessChecker" />
-    <bean id="RoleBasedEntityQuerySelector" class="org.apache.cloudstack.iam.RoleBasedEntityQuerySelector" />
-    <bean id="IAMApiServiceImpl" class="org.apache.cloudstack.iam.IAMApiServiceImpl" />
-
-</beans>
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddAccountToIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddAccountToIAMGroupCmd.java
deleted file mode 100644
index bea3fc9..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddAccountToIAMGroupCmd.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "addAccountToIAMGroup", description = "add account to an iam group", responseObject = IAMGroupResponse.class)
-public class AddAccountToIAMGroupCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AddAccountToIAMGroupCmd.class.getName());
-    private static final String s_name = "addaccounttoiamgroupresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMGroupResponse.class,
- required = true, description = "The ID of the iam group")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AccountResponse.class, description = "comma separated list of account id that are going to be assigned to the iam group.")
-    private List<Long> accountIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getAccountIdList() {
-        return accountIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM group Id: " + getId());
-        IAMGroup result = _iamApiSrv.addAccountsToGroup(accountIdList, id);
-        if (result != null){
-            IAMGroupResponse response = _iamApiSrv.createIAMGroupResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add accounts to iam group");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "adding accounts to iam group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java
deleted file mode 100644
index d69f3d0..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AddIAMPermissionToIAMPolicyCmd.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "addIAMPermissionToIAMPolicy", description = "Add IAM permission to an iam policy", responseObject = IAMPolicyResponse.class)
-public class AddIAMPermissionToIAMPolicyCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AddIAMPermissionToIAMPolicyCmd.class.getName());
-    private static final String s_name = "addiampermissiontoiampolicyresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMPolicyResponse.class,
- required = true, description = "The ID of the iam policy")
-    private Long id;
-
-    @Parameter(name = ApiConstants.IAM_ACTION, type = CommandType.STRING, required = true, description = "action api name.")
-    private String action;
-
-    @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, required = false, description = "entity class simple name.")
-    private String entityType;
-
-    @Parameter(name = ApiConstants.IAM_SCOPE, type = CommandType.STRING,
- required = false, description = "iam permission scope")
-    private String scope;
-
-    @Parameter(name = ApiConstants.IAM_SCOPE_ID, type = CommandType.STRING, required = false, description = "The UUID of the permission scope id")
-    private String scopeId;
-
-    @Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = false, description = "Read Only access is added; Only applicable when action = List/Read api name")
-    private Boolean readOnly;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public String getAction() {
-        return action;
-    }
-
-    public String getEntityType() {
-        return entityType;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public Long getScopeId() {
-        // here we will convert the passed String UUID to Long ID since internally we store it as entity internal ID.
-        return _iamApiSrv.getPermissionScopeId(scope, entityType, scopeId);
-    }
-
-    public Boolean isReadOnly() {
-        return (readOnly != null) ? readOnly : false;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM policy Id: " + getId());
-        // Only explicit ALLOW is supported for this release, no explicit deny
-        IAMPolicy result = _iamApiSrv.addIAMPermissionToIAMPolicy(id, entityType, PermissionScope.valueOf(scope),
-                getScopeId(), action, Permission.Allow, false, isReadOnly());
-        if (result != null) {
-            IAMPolicyResponse response = _iamApiSrv.createIAMPolicyResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to grant permission to iam policy "
-                    + getId());
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_POLICY_GRANT;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "granting permission to iam policy";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMPolicy;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToAccountCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToAccountCmd.java
deleted file mode 100644
index fc174cf..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToAccountCmd.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "attachIAMPolicyToAccount", description = "attach iam policy to accounts", responseObject = SuccessResponse.class)
-public class AttachIAMPolicyToAccountCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AttachIAMPolicyToAccountCmd.class.getName());
-    private static final String s_name = "attachiampolicytoaccountresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMPolicyResponse.class,
- required = true, description = "The ID of the iam policy")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AccountResponse.class, description = "comma separated list of account id that the policy will attach to.")
-    private List<Long> accountIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getAccountIdList() {
-        return accountIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM policy Id: " + getId());
-        _iamApiSrv.attachIAMPolicyToAccounts(id, accountIdList);
-        SuccessResponse response = new SuccessResponse();
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "adding IAM policy to accounts";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Account;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToIAMGroupCmd.java
deleted file mode 100644
index 1705c4a..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/AttachIAMPolicyToIAMGroupCmd.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "attachIAMPolicyToIAMGroup", description = "attach iam policy to an iam group", responseObject = IAMGroupResponse.class)
-public class AttachIAMPolicyToIAMGroupCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(AttachIAMPolicyToIAMGroupCmd.class.getName());
-    private static final String s_name = "attachiampolicytoiamgroupresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMGroupResponse.class,
- required = true, description = "The ID of the iam group")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.IAM_POLICIES, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = IAMPolicyResponse.class, description = "comma separated list of iam policy id that are going to be applied to the iam group.")
-    private List<Long> policyIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getPolicyIdList() {
-        return policyIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM group Id: " + getId());
-        IAMGroup result = _iamApiSrv.attachIAMPoliciesToGroup(policyIdList, id);
-        if (result != null){
-            IAMGroupResponse response = _iamApiSrv.createIAMGroupResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add roles to iam group");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "adding iam roles to iam group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java
deleted file mode 100644
index 93940e8..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMGroupCmd.java
+++ /dev/null
@@ -1,168 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.user.Account;
-
-@APICommand(name = "createIAMGroup", responseObject = IAMGroupResponse.class, description = "Creates an IAM group")
-public class CreateIAMGroupCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateIAMGroupCmd.class.getName());
-
-    private static final String s_name = "createiamgroupresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an account for the iam group. Must be used with domainId.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, description = "domainId of the account owning the iam group", entityType = DomainResponse.class)
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "optional description of the iam group")
-    private String description;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the iam group")
-    private String name;
-
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || _accountService.isAdmin(account.getId())) {
-            if ((domainId != null) && (accountName != null)) {
-                Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
-                if (userAccount != null) {
-                    return userAccount.getId();
-                }
-            }
-        }
-
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this
-                                          // command to SYSTEM so ERROR events
-                                          // are tracked
-    }
-
-    @Override
-    public void execute() {
-        IAMGroup grp = _entityMgr.findById(IAMGroup.class, getEntityId());
-        if (grp != null) {
-            IAMGroupResponse response = _iamApiSrv.createIAMGroupResponse(grp);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create iam group:" + name);
-        }
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        Account account = CallContext.current().getCallingAccount();
-        IAMGroup result = _iamApiSrv.createIAMGroup(account, name, description);
-        if (result != null) {
-            setEntityId(result.getId());
-            setEntityUuid(result.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create iam group entity" + name);
-        }
-
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating IAM group";
-    }
-
-    @Override
-    public String getCreateEventType() {
-        return EventTypes.EVENT_IAM_GROUP_CREATE;
-    }
-
-    @Override
-    public String getCreateEventDescription() {
-        return "creating IAM group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java
deleted file mode 100644
index 7ebab67..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/CreateIAMPolicyCmd.java
+++ /dev/null
@@ -1,175 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCreateCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.user.Account;
-
-@APICommand(name = "createIAMPolicy", responseObject = IAMPolicyResponse.class, description = "Creates an iam policy")
-public class CreateIAMPolicyCmd extends BaseAsyncCreateCmd {
-    public static final Logger s_logger = Logger.getLogger(CreateIAMPolicyCmd.class.getName());
-
-    private static final String s_name = "createiampolicyresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    // ///////////////////////////////////////////////////
-    // ////////////// API parameters /////////////////////
-    // ///////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an account for the iam policy. Must be used with domainId.")
-    private String accountName;
-
-    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, description = "domainId of the account owning the iam policy", entityType = DomainResponse.class)
-    private Long domainId;
-
-    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "optional description of the iam policy")
-    private String description;
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the iam policy")
-    private String name;
-
-    @ACL
-    @Parameter(name = ApiConstants.IAM_PARENT_POLICY_ID, type = CommandType.UUID, description = "The ID of parent iam policy.", entityType = IAMPolicyResponse.class)
-    private Long parentPolicyId;
-
-
-    // ///////////////////////////////////////////////////
-    // ///////////////// Accessors ///////////////////////
-    // ///////////////////////////////////////////////////
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public Long getDomainId() {
-        return domainId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Long getParentPolicyId() {
-        return parentPolicyId;
-    }
-
-    // ///////////////////////////////////////////////////
-    // ///////////// API Implementation///////////////////
-    // ///////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        Account account = CallContext.current().getCallingAccount();
-        if ((account == null) || _accountService.isAdmin(account.getId())) {
-            if ((domainId != null) && (accountName != null)) {
-                Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
-                if (userAccount != null) {
-                    return userAccount.getId();
-                }
-            }
-        }
-
-        if (account != null) {
-            return account.getId();
-        }
-
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this
-                                          // command to SYSTEM so ERROR events
-                                          // are tracked
-    }
-
-    @Override
-    public void execute() {
-        IAMPolicy policy = _entityMgr.findById(IAMPolicy.class, getEntityId());
-        if (policy != null) {
-            IAMPolicyResponse response = _iamApiSrv.createIAMPolicyResponse(policy);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create iam policy:" + name);
-        }
-    }
-
-    @Override
-    public void create() throws ResourceAllocationException {
-        Account account = CallContext.current().getCallingAccount();
-        IAMPolicy result = _iamApiSrv.createIAMPolicy(account, name, description, parentPolicyId);
-        if (result != null) {
-            setEntityId(result.getId());
-            setEntityUuid(result.getUuid());
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create iam policy entity" + name);
-        }
-
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_POLICY_CREATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "creating IAM policy";
-    }
-
-    @Override
-    public String getCreateEventType() {
-        return EventTypes.EVENT_IAM_POLICY_CREATE;
-    }
-
-    @Override
-    public String getCreateEventDescription() {
-        return "creating IAM policy";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMPolicy;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMGroupCmd.java
deleted file mode 100644
index 60b1e24..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMGroupCmd.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.iam.IAMApiService;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-
-@APICommand(name = "deleteIAMGroup", description = "Deletes acl group", responseObject = SuccessResponse.class)
-public class DeleteIAMGroupCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteIAMGroupCmd.class.getName());
-    private static final String s_name = "deleteaclgroupresponse";
-
-    @Inject
-    public IAMApiService _aclApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, description = "The ID of the acl group.", required = true, entityType = IAMGroupResponse.class)
-    private Long id;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute(){
-        boolean result = _aclApiSrv.deleteIAMGroup(id);
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete acl group");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Deleting Acl group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMPolicyCmd.java
deleted file mode 100644
index 037f4cd..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/DeleteIAMPolicyCmd.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-
-import com.cloud.event.EventTypes;
-import com.cloud.user.Account;
-
-@APICommand(name = "deleteIAMPolicy", description = "Deletes iam policy", responseObject = SuccessResponse.class)
-public class DeleteIAMPolicyCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(DeleteIAMPolicyCmd.class.getName());
-    private static final String s_name = "deleteiampolicyresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, description = "The ID of the iam policy.", required = true, entityType = IAMPolicyResponse.class)
-    private Long id;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-    public Long getId() {
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM;
-    }
-
-    @Override
-    public void execute(){
-        boolean result = _iamApiSrv.deleteIAMPolicy(id);
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete iam policy");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_POLICY_DELETE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "Deleting IAM policy";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMPolicy;
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMGroupsCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMGroupsCmd.java
deleted file mode 100644
index ece87fa..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMGroupsCmd.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-
-
-@APICommand(name = "listIAMGroups", description = "Lists iam groups", responseObject = IAMGroupResponse.class)
-public class ListIAMGroupsCmd extends BaseListDomainResourcesCmd {
-    public static final Logger s_logger = Logger.getLogger(ListIAMGroupsCmd.class.getName());
-
-    private static final String s_name = "listiamgroupsresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists iam groups by name")
-    private String iamGroupName;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, description = "list the iam group by the id provided", entityType = IAMGroupResponse.class)
-    private Long id;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-    public String getIAMGroupName() {
-        return iamGroupName;
-    }
-
-
-    public Long getId(){
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute(){
-
-        ListResponse<IAMGroupResponse> response = _iamApiSrv.listIAMGroups(id, iamGroupName, getDomainId(),
-                getStartIndex(), getPageSizeVal());
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMPoliciesCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMPoliciesCmd.java
deleted file mode 100644
index 096cc3b..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/ListIAMPoliciesCmd.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-
-
-@APICommand(name = "listIAMPolicies", description = "Lists IAM policies", responseObject = IAMPolicyResponse.class)
-public class ListIAMPoliciesCmd extends BaseListDomainResourcesCmd {
-    public static final Logger s_logger = Logger.getLogger(ListIAMPoliciesCmd.class.getName());
-
-    private static final String s_name = "listiampoliciesresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists iam policies by name")
-    private String iamPolicyName;
-
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, description = "list the iam policy by the id provided", entityType = IAMPolicyResponse.class)
-    private Long id;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-    public String getIAMPolicyName() {
-        return iamPolicyName;
-    }
-
-
-    public Long getId(){
-        return id;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-    @Override
-    public void execute(){
-
-        ListResponse<IAMPolicyResponse> response = _iamApiSrv.listIAMPolicies(id, iamPolicyName, getDomainId(),
-                getStartIndex(), getPageSizeVal());
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMPolicy;
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveAccountFromIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveAccountFromIAMGroupCmd.java
deleted file mode 100644
index 5ff5039..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveAccountFromIAMGroupCmd.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "removeAccountFromIAMGroup", description = "remove accounts from an iam group", responseObject = IAMGroupResponse.class)
-public class RemoveAccountFromIAMGroupCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveAccountFromIAMGroupCmd.class.getName());
-    private static final String s_name = "removeaccountfromiamgroupresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMGroupResponse.class,
- required = true, description = "The ID of the iam group")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AccountResponse.class, description = "comma separated list of account id that are going to be assigned to the iam group.")
-    private List<Long> accountIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getAccountIdList() {
-        return accountIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM group Id: " + getId());
-        IAMGroup result = _iamApiSrv.removeAccountsFromGroup(accountIdList, id);
-        if (result != null){
-            IAMGroupResponse response = _iamApiSrv.createIAMGroupResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove accounts from iam group");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "removing accounts from iam group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPermissionFromIAMPolicyCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPermissionFromIAMPolicyCmd.java
deleted file mode 100644
index bf065a0..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPermissionFromIAMPolicyCmd.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "removeIAMPermissionFromIAMPolicy", description = "Remove iam permission from an iam policy", responseObject = IAMPolicyResponse.class)
-public class RemoveIAMPermissionFromIAMPolicyCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveIAMPermissionFromIAMPolicyCmd.class.getName());
-    private static final String s_name = "removeiampermissionfromiampolicyresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMPolicyResponse.class,
-            required = true, description = "The ID of the iam policy")
-    private Long id;
-
-    @Parameter(name = ApiConstants.IAM_ACTION, type = CommandType.STRING, required = true, description = "action api name.")
-    private String action;
-
-    @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, required = false, description = "entity class simple name.")
-    private String entityType;
-
-    @Parameter(name = ApiConstants.IAM_SCOPE, type = CommandType.STRING,
-            required = false, description = "iam permission scope")
-    private String scope;
-
-    @Parameter(name = ApiConstants.IAM_SCOPE_ID, type = CommandType.STRING, required = false, description = "The ID of the permission scope id")
-    private String scopeId;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public String getAction() {
-        return action;
-    }
-
-    public String getEntityType() {
-        return entityType;
-    }
-
-    public String getScope() {
-        return scope;
-    }
-
-    public Long getScopeId() {
-        // here we will convert the passed String UUID to Long ID since internally we store it as entity internal ID.
-        return _iamApiSrv.getPermissionScopeId(scope, entityType, scopeId);
-    }
-
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM policy Id: " + getId());
-        IAMPolicy result = _iamApiSrv.removeIAMPermissionFromIAMPolicy(id, entityType, PermissionScope.valueOf(scope), getScopeId(), action);
-        if (result != null) {
-            IAMPolicyResponse response = _iamApiSrv.createIAMPolicyResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove permission from iam policy " + getId());
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_POLICY_REVOKE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "removing permission from iam policy";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMPolicy;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromAccountCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromAccountCmd.java
deleted file mode 100644
index 48c2a73..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromAccountCmd.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.AccountResponse;
-import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.IAMApiService;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "removeIAMPolicyFromAccount", description = "remove iam policy from accounts", responseObject = SuccessResponse.class)
-public class RemoveIAMPolicyFromAccountCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveIAMPolicyFromAccountCmd.class.getName());
-    private static final String s_name = "removeiampolicyfromaccountresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMPolicyResponse.class,
- required = true, description = "The ID of the iam group")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AccountResponse.class, description = "comma separated list of iam policy id that are going to be applied to the iam group.")
-    private List<Long> accountIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getAccountIdList() {
-        return accountIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM policy Id: " + getId());
-        _iamApiSrv.removeIAMPolicyFromAccounts(id, accountIdList);
-        SuccessResponse response = new SuccessResponse();
-        response.setResponseName(getCommandName());
-        setResponseObject(response);
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "removing iam policy from accounts";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.Account;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromIAMGroupCmd.java b/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromIAMGroupCmd.java
deleted file mode 100644
index a99143d..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/command/iam/RemoveIAMPolicyFromIAMGroupCmd.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.iam;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.api.ACL;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiCommandJobType;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseAsyncCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.user.Account;
-
-
-@APICommand(name = "removeIAMPolicyFromIAMGroup", description = "remove iam policy from an iam group", responseObject = IAMGroupResponse.class)
-public class RemoveIAMPolicyFromIAMGroupCmd extends BaseAsyncCmd {
-    public static final Logger s_logger = Logger.getLogger(RemoveIAMPolicyFromIAMGroupCmd.class.getName());
-    private static final String s_name = "removeiampolicyfromiamgroupresponse";
-
-    @Inject
-    public IAMApiService _iamApiSrv;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-
-    @ACL
-    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IAMGroupResponse.class,
- required = true, description = "The ID of the iam group")
-    private Long id;
-
-    @ACL
-    @Parameter(name = ApiConstants.IAM_POLICIES, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = IAMPolicyResponse.class, description = "comma separated list of iam policy id that are going to be applied to the iam group.")
-    private List<Long> policyIdList;
-
-
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
-
-
-    public Long getId() {
-        return id;
-    }
-
-
-    public List<Long> getRoleIdList() {
-        return policyIdList;
-    }
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-
-    @Override
-    public String getCommandName() {
-        return s_name;
-    }
-
-
-    @Override
-    public long getEntityOwnerId() {
-        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
-    }
-
-    @Override
-    public void execute() throws ResourceUnavailableException,
-            InsufficientCapacityException, ServerApiException {
-        CallContext.current().setEventDetails("IAM group Id: " + getId());
-        IAMGroup result = _iamApiSrv.removeIAMPoliciesFromGroup(policyIdList, id);
-        if (result != null){
-            IAMGroupResponse response = _iamApiSrv.createIAMGroupResponse(result);
-            response.setResponseName(getCommandName());
-            setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add roles to iam group");
-        }
-    }
-
-    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_IAM_GROUP_UPDATE;
-    }
-
-    @Override
-    public String getEventDescription() {
-        return "removing IAM roles from IAM group";
-    }
-
-    @Override
-    public ApiCommandJobType getInstanceType() {
-        return ApiCommandJobType.IAMGroup;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMGroupResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMGroupResponse.java
deleted file mode 100644
index af28d53..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMGroupResponse.java
+++ /dev/null
@@ -1,193 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response.iam;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-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 org.apache.cloudstack.api.response.ControlledViewEntityResponse;
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.serializer.Param;
-
-@SuppressWarnings("unused")
-@EntityReference(value = IAMGroup.class)
-public class IAMGroupResponse extends BaseResponse implements ControlledViewEntityResponse {
-
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the ID of the iam group")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the iam group")
-    private String name;
-
-    @SerializedName(ApiConstants.DESCRIPTION)
-    @Param(description = "the description of the iam group")
-    private String description;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the domain ID of the iam group")
-    private String domainId;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "the domain name of the iam role")
-    private String domainName;
-
-    @SerializedName(ApiConstants.ACCOUNT)
-    @Param(description = "the account owning the policy")
-    private String accountName;
-
-    @SerializedName(ApiConstants.IAM_MEMBER_ACCOUNTS)
-    @Param(description = "account names assigned to this iam group ")
-    private Set<String> accountNameList;
-
-    @SerializedName(ApiConstants.IAM_POLICIES)
-    @Param(description = "iam policies attached to this iam group ")
-    private Set<String> policyNameList;
-
-    public IAMGroupResponse() {
-        accountNameList = new LinkedHashSet<String>();
-        policyNameList = new LinkedHashSet<String>();
-    }
-
-    @Override
-    public String getObjectId() {
-        return getId();
-    }
-
-
-    public String getId() {
-        return id;
-     }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    @Override
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    @Override
-    public void setDomainName(String domainName) {
-        this.domainName = domainName;
-    }
-
-    @Override
-    public void setAccountName(String accountName) {
-        this.accountName = accountName;
-
-    }
-
-    @Override
-    public void setProjectId(String projectId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setProjectName(String projectName) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public String getDomainId() {
-        return domainId;
-    }
-
-    public String getDomainName() {
-        return domainName;
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public Set<String> getAccountNameList() {
-        return accountNameList;
-    }
-
-    public void setMemberAccounts(Set<String> accts) {
-        accountNameList = accts;
-    }
-
-    public void addMemberAccount(String acct) {
-        accountNameList.add(acct);
-    }
-
-    public void setPolicyList(Set<String> policies) {
-        policyNameList = policies;
-    }
-
-    public void addPolicy(String policy) {
-        policyNameList.add(policy);
-    }
-
-    public Set<String> getPolicyList() {
-        return policyNameList;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        IAMGroupResponse other = (IAMGroupResponse)obj;
-        if (id == null) {
-            if (other.id != null)
-                return false;
-        } else if (!id.equals(other.id))
-            return false;
-        return true;
-    }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java
deleted file mode 100644
index 046e1f4..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response.iam;
-
-import com.google.gson.annotations.SerializedName;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-
-import com.cloud.serializer.Param;
-
-public class IAMPermissionResponse extends BaseResponse {
-
-    @SerializedName(ApiConstants.IAM_ACTION)
-    @Param(description = "action of this permission")
-    private String action;
-
-    @SerializedName(ApiConstants.ENTITY_TYPE)
-    @Param(description = "the entity type of this permission")
-    private String entityType;
-
-    @SerializedName(ApiConstants.IAM_SCOPE)
-    @Param(description = "scope of this permission")
-    private PermissionScope scope;
-
-    @SerializedName(ApiConstants.IAM_SCOPE_ID)
-    @Param(description = "scope id of this permission")
-    private Long scopeId;
-
-    @SerializedName(ApiConstants.IAM_ALLOW_DENY)
-    @Param(description = "allow or deny of this permission")
-    private IAMPolicyPermission.Permission permission;
-
-    public String getEntityType() {
-        return entityType;
-    }
-
-    public void setEntityType(String entityType) {
-        this.entityType = entityType;
-    }
-
-    public String getAction() {
-        return action;
-    }
-
-    public void setAction(String action) {
-        this.action = action;
-    }
-
-    public PermissionScope getScope() {
-        return scope;
-    }
-
-    public void setScope(PermissionScope scope) {
-        this.scope = scope;
-    }
-
-    public Long getScopeId() {
-        return scopeId;
-    }
-
-    public void setScopeId(Long scopeId) {
-        this.scopeId = scopeId;
-    }
-
-    public IAMPolicyPermission.Permission getPermission() {
-        return permission;
-    }
-
-    public void setPermission(IAMPolicyPermission.Permission permission) {
-        this.permission = permission;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((action == null) ? 0 : action.hashCode());
-        result = prime * result + ((entityType == null) ? 0 : entityType.hashCode());
-        result = prime * result + ((scope == null) ? 0 : scope.hashCode());
-        result = prime * result + ((scopeId == null) ? 0 : scopeId.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        IAMPermissionResponse other = (IAMPermissionResponse) obj;
-        if ((entityType == null && other.entityType != null) || (entityType != null && !entityType.equals(other.entityType))) {
-            return false;
-        } else if ((action == null && other.action != null) || (action != null && !action.equals(other.action))) {
-            return false;
-        } else if ((scope == null && other.scope != null) || (scope != null && !scope.equals(other.scope))) {
-            return false;
-        } else if ((scopeId == null && other.scopeId != null) || (scopeId != null && !scopeId.equals(other.scopeId))) {
-            return false;
-        }
-        return true;
-    }
-
-
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java
deleted file mode 100644
index dc29369..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java
+++ /dev/null
@@ -1,177 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response.iam;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-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 org.apache.cloudstack.api.response.ControlledViewEntityResponse;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-
-import com.cloud.serializer.Param;
-
-@SuppressWarnings("unused")
-@EntityReference(value = IAMPolicy.class)
-public class IAMPolicyResponse extends BaseResponse implements ControlledViewEntityResponse {
-
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the ID of the iam policy")
-    private String id;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the iam policy")
-    private String name;
-
-    @SerializedName(ApiConstants.DESCRIPTION)
-    @Param(description = "the description of the iam policy")
-    private String description;
-
-    @SerializedName(ApiConstants.DOMAIN_ID)
-    @Param(description = "the domain ID of the iam policy")
-    private String domainId;
-
-    @SerializedName(ApiConstants.DOMAIN)
-    @Param(description = "the domain name of the iam policy")
-    private String domainName;
-
-    @SerializedName(ApiConstants.ACCOUNT)
-    @Param(description = "the account owning the policy")
-    private String accountName;
-
-    @SerializedName(ApiConstants.IAM_PERMISSIONS)
-    @Param(description = "set of permissions for the iam policy")
-    private Set<IAMPermissionResponse> permissionList;
-
-    public IAMPolicyResponse() {
-        permissionList = new LinkedHashSet<IAMPermissionResponse>();
-    }
-
-    @Override
-    public String getObjectId() {
-        return getId();
-    }
-
-
-    public String getId() {
-        return id;
-     }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    @Override
-    public void setDomainId(String domainId) {
-        this.domainId = domainId;
-    }
-
-    @Override
-    public void setDomainName(String domainName) {
-        this.domainName = domainName;
-    }
-
-    public Set<IAMPermissionResponse> getPermissionList() {
-        return permissionList;
-    }
-
-    public void setPermissionList(Set<IAMPermissionResponse> perms) {
-        permissionList = perms;
-    }
-
-    public void addPermission(IAMPermissionResponse perm) {
-        permissionList.add(perm);
-    }
-
-    @Override
-    public void setAccountName(String accountName) {
-        this.accountName = accountName;
-    }
-
-    @Override
-    public void setProjectId(String projectId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setProjectName(String projectName) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public String getDomainId() {
-        return domainId;
-    }
-
-    public String getDomainName() {
-        return domainName;
-    }
-
-    public String getAccountName() {
-        return accountName;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        IAMPolicyResponse other = (IAMPolicyResponse) obj;
-        if (id == null) {
-            if (other.id != null)
-                return false;
-        } else if (!id.equals(other.id))
-            return false;
-        return true;
-    }
-
-
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java
deleted file mode 100644
index 6735d48..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import java.util.List;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-
-import com.cloud.user.Account;
-import com.cloud.utils.component.PluggableService;
-
-public interface IAMApiService extends PluggableService {
-
-    /* ACL group related interfaces */
-    IAMGroup createIAMGroup(Account caller, String iamGroupName, String description);
-
-    boolean deleteIAMGroup(Long iamGroupId);
-
-    List<IAMGroup> listIAMGroups(long accountId);
-
-    IAMGroup addAccountsToGroup(List<Long> acctIds, Long groupId);
-
-    IAMGroup removeAccountsFromGroup(List<Long> acctIds, Long groupId);
-
-    /* IAM Policy related interfaces */
-    IAMPolicy createIAMPolicy(Account caller, String iamPolicyName, String description, Long parentPolicyId);
-
-    boolean deleteIAMPolicy(long iamPolicyId);
-
-    List<IAMPolicy> listIAMPolicies(long accountId);
-
-    IAMGroup attachIAMPoliciesToGroup(List<Long> policyIds, Long groupId);
-
-    IAMGroup removeIAMPoliciesFromGroup(List<Long> policyIds, Long groupId);
-
-    void attachIAMPolicyToAccounts(Long policyId, List<Long> accountIds);
-
-    void removeIAMPolicyFromAccounts(Long policyId, List<Long> accountIds);
-
-    IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId,
-            String action, Permission perm, Boolean recursive, Boolean readOnly);
-
-    IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, String action);
-
-    IAMPolicyPermission getIAMPolicyPermission(long accountId, String entityType, String action);
-
-    /* Utility routine to grant/revoke invidivual resource to list of accounts */
-    void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds);
-
-    void revokeEntityPermissioinFromAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds);
-
-    /* Response Generation */
-    IAMPolicyResponse createIAMPolicyResponse(IAMPolicy policy);
-
-    IAMGroupResponse createIAMGroupResponse(IAMGroup group);
-
-    ListResponse<IAMGroupResponse> listIAMGroups(Long iamGroupId, String iamGroupName,
-            Long domainId, Long startIndex, Long pageSize);
-
-    ListResponse<IAMPolicyResponse> listIAMPolicies(Long iamPolicyId, String iamPolicyName,
-            Long domainId, Long startIndex, Long pageSize);
-
-    // Convert passed scope uuid to internal scope long id
-    Long getPermissionScopeId(String scope, String entityType, String scopeId);
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java
deleted file mode 100644
index b0dc383..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java
+++ /dev/null
@@ -1,825 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.bouncycastle.util.IPAddress;
-
-import com.amazonaws.auth.policy.Condition;
-import com.amazonaws.services.ec2.model.SecurityGroup;
-import com.amazonaws.services.ec2.model.Snapshot;
-import com.amazonaws.services.ec2.model.Volume;
-import com.amazonaws.services.ec2.model.Vpc;
-import com.amazonaws.services.elasticache.model.Event;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.affinity.AffinityGroup;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.api.command.iam.AddAccountToIAMGroupCmd;
-import org.apache.cloudstack.api.command.iam.AddIAMPermissionToIAMPolicyCmd;
-import org.apache.cloudstack.api.command.iam.AttachIAMPolicyToAccountCmd;
-import org.apache.cloudstack.api.command.iam.AttachIAMPolicyToIAMGroupCmd;
-import org.apache.cloudstack.api.command.iam.CreateIAMGroupCmd;
-import org.apache.cloudstack.api.command.iam.CreateIAMPolicyCmd;
-import org.apache.cloudstack.api.command.iam.DeleteIAMGroupCmd;
-import org.apache.cloudstack.api.command.iam.DeleteIAMPolicyCmd;
-import org.apache.cloudstack.api.command.iam.ListIAMGroupsCmd;
-import org.apache.cloudstack.api.command.iam.ListIAMPoliciesCmd;
-import org.apache.cloudstack.api.command.iam.RemoveAccountFromIAMGroupCmd;
-import org.apache.cloudstack.api.command.iam.RemoveIAMPermissionFromIAMPolicyCmd;
-import org.apache.cloudstack.api.command.iam.RemoveIAMPolicyFromAccountCmd;
-import org.apache.cloudstack.api.command.iam.RemoveIAMPolicyFromIAMGroupCmd;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.api.response.iam.IAMPermissionResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.api.IAMService;
-
-import com.cloud.api.ApiServerService;
-import com.cloud.domain.Domain;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.IpAddress;
-import com.cloud.network.MonitoringService;
-import com.cloud.network.Network;
-import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteCustomerGateway;
-import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.Site2SiteVpnGateway;
-import com.cloud.network.UserIpv6Address;
-import com.cloud.network.VpnUser;
-import com.cloud.network.as.AutoScalePolicy;
-import com.cloud.network.as.AutoScaleVmGroup;
-import com.cloud.network.as.AutoScaleVmProfile;
-import com.cloud.network.lb.SslCert;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.PortForwardingRule;
-import com.cloud.network.vpc.StaticRoute;
-import com.cloud.network.vpc.VpcGateway;
-import com.cloud.projects.ProjectInvitation;
-import com.cloud.region.ha.GlobalLoadBalancerRule;
-import com.cloud.server.ResourceTag;
-import com.cloud.template.TemplateManager;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.DomainManager;
-import com.cloud.user.SSHKeyPair;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.vm.InstanceGroup;
-import com.cloud.vm.NicIpAlias;
-import com.cloud.vm.NicSecondaryIp;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.snapshot.VMSnapshot;
-
-public class IAMApiServiceImpl extends ManagerBase implements IAMApiService, Manager {
-
-    public static final Logger s_logger = Logger.getLogger(IAMApiServiceImpl.class);
-    private String _name;
-
-    @Inject
-    ApiServerService _apiServer;
-
-    @Inject
-    IAMService _iamSrv;
-
-    @Inject
-    DomainDao _domainDao;
-
-    @Inject
-    AccountDao _accountDao;
-
-    @Inject
-    AccountManager _accountMgr;
-
-    @Inject
-    MessageBus _messageBus;
-
-    @Inject
-    EntityManager _entityMgr;
-
-    private static final Map<String, Class<?>> s_typeMap = new HashMap<String, Class<?>>();
-    static {
-        s_typeMap.put(VirtualMachine.class.getSimpleName(), VirtualMachine.class);
-        s_typeMap.put(Volume.class.getSimpleName(), Volume.class);
-        s_typeMap.put(ResourceTag.class.getSimpleName(), ResourceTag.class);
-        s_typeMap.put(Account.class.getSimpleName(), Account.class);
-        s_typeMap.put(AffinityGroup.class.getSimpleName(), AffinityGroup.class);
-        s_typeMap.put(AutoScalePolicy.class.getSimpleName(), AutoScalePolicy.class);
-        s_typeMap.put(AutoScaleVmProfile.class.getSimpleName(), AutoScaleVmProfile.class);
-        s_typeMap.put(AutoScaleVmGroup.class.getSimpleName(), AutoScaleVmGroup.class);
-        s_typeMap.put(Condition.class.getSimpleName(), Condition.class);
-        s_typeMap.put(Vpc.class.getSimpleName(), Vpc.class);
-        s_typeMap.put(VpcGateway.class.getSimpleName(), VpcGateway.class);
-        s_typeMap.put(VpnUser.class.getSimpleName(), VpnUser.class);
-        s_typeMap.put(VMSnapshot.class.getSimpleName(), VMSnapshot.class);
-        s_typeMap.put(VirtualMachineTemplate.class.getSimpleName(), VirtualMachineTemplate.class);
-        s_typeMap.put(UserIpv6Address.class.getSimpleName(), UserIpv6Address.class);
-        s_typeMap.put(StaticRoute.class.getSimpleName(), StaticRoute.class);
-        s_typeMap.put(SSHKeyPair.class.getSimpleName(), SSHKeyPair.class);
-        s_typeMap.put(Snapshot.class.getSimpleName(), Snapshot.class);
-        s_typeMap.put(Site2SiteVpnGateway.class.getSimpleName(), Site2SiteVpnGateway.class);
-        s_typeMap.put(Site2SiteCustomerGateway.class.getSimpleName(), Site2SiteCustomerGateway.class);
-        s_typeMap.put(Site2SiteVpnConnection.class.getSimpleName(), Site2SiteVpnConnection.class);
-        s_typeMap.put(SecurityGroup.class.getSimpleName(), SecurityGroup.class);
-        s_typeMap.put(RemoteAccessVpn.class.getSimpleName(), RemoteAccessVpn.class);
-        s_typeMap.put(ProjectInvitation.class.getSimpleName(), ProjectInvitation.class);
-        s_typeMap.put(NicSecondaryIp.class.getSimpleName(), NicSecondaryIp.class);
-        s_typeMap.put(NicIpAlias.class.getSimpleName(), NicIpAlias.class);
-        s_typeMap.put(Network.class.getSimpleName(), Network.class);
-        s_typeMap.put(IpAddress.class.getSimpleName(), IPAddress.class);
-        s_typeMap.put(InstanceGroup.class.getSimpleName(), InstanceGroup.class);
-        s_typeMap.put(GlobalLoadBalancerRule.class.getSimpleName(), GlobalLoadBalancerRule.class);
-        s_typeMap.put(FirewallRule.class.getSimpleName(), FirewallRule.class);
-        s_typeMap.put(PortForwardingRule.class.getSimpleName(), PortForwardingRule.class);
-        s_typeMap.put(Event.class.getSimpleName(), Event.class);
-        s_typeMap.put(AsyncJob.class.getSimpleName(), AsyncJob.class);
-        s_typeMap.put(IAMGroup.class.getSimpleName(), IAMGroup.class);
-        s_typeMap.put(IAMPolicy.class.getSimpleName(), IAMPolicy.class);
-        s_typeMap.put(MonitoringService.class.getSimpleName(), MonitoringService.class);
-        s_typeMap.put(SslCert.class.getSimpleName(), SslCert.class);
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-
-        _messageBus.subscribe(AccountManager.MESSAGE_ADD_ACCOUNT_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                HashMap<Long, Long> acctGroupMap = (HashMap<Long, Long>) obj;
-                for (Long accountId : acctGroupMap.keySet()) {
-                    Long groupId = acctGroupMap.get(accountId);
-                    s_logger.debug("MessageBus message: new Account Added: " + accountId + ", adding it to groupId :"
-                            + groupId);
-                    addAccountToIAMGroup(accountId, groupId);
-                    // add it to domain group too
-                    AccountVO account = _accountDao.findById(accountId);
-                    Domain domain = _domainDao.findById(account.getDomainId());
-                    if (domain != null) {
-                        List<IAMGroup> domainGroups = listDomainGroup(domain);
-
-                        if (domainGroups != null) {
-                            for (IAMGroup group : domainGroups) {
-                                addAccountToIAMGroup(accountId, new Long(group.getId()));
-                            }
-                        }
-                    }
-                }
-            }
-        });
-
-        _messageBus.subscribe(AccountManager.MESSAGE_REMOVE_ACCOUNT_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Long accountId = ((Long) obj);
-                if (accountId != null) {
-                    s_logger.debug("MessageBus message: Account removed: " + accountId
-                            + ", releasing the group associations");
-                    removeAccountFromIAMGroups(accountId);
-                }
-            }
-        });
-
-        _messageBus.subscribe(DomainManager.MESSAGE_ADD_DOMAIN_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Long domainId = ((Long) obj);
-                if (domainId != null) {
-                    s_logger.debug("MessageBus message: new Domain created: " + domainId + ", creating a new group");
-                    Domain domain = _domainDao.findById(domainId);
-                    _iamSrv.createIAMGroup("DomainGrp-" + domain.getUuid(), "Domain group", domain.getPath());
-                }
-            }
-        });
-
-        _messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Long domainId = ((Long) obj);
-                if (domainId != null) {
-                    s_logger.debug("MessageBus message: Domain removed: " + domainId + ", removing the domain group");
-                    Domain domain = _domainDao.findById(domainId);
-                    List<IAMGroup> groups = listDomainGroup(domain);
-                    for (IAMGroup group : groups) {
-                        _iamSrv.deleteIAMGroup(group.getId());
-                    }
-                }
-            }
-        });
-
-        _messageBus.subscribe(TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Long templateId = (Long)obj;
-                if (templateId != null) {
-                    s_logger.debug("MessageBus message: new public template registered: " + templateId
-                            + ", grant permission to default root admin, domain admin and normal user policies");
-                    _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(),
-                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-                    _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(),
-                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-                    _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(),
-                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-                }
-            }
-        });
-
-        _messageBus.subscribe(TemplateManager.MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Long templateId = (Long)obj;
-                if (templateId != null) {
-                    s_logger.debug("MessageBus message: reset template permission: " + templateId);
-                    resetTemplatePermission(templateId);
-                }
-            }
-        });
-
-        _messageBus.subscribe(EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Pair<Class<?>, Long> entity = (Pair<Class<?>, Long>)obj;
-                if (entity != null) {
-                    String entityType = entity.first().getSimpleName();
-                    Long entityId = entity.second();
-                    s_logger.debug("MessageBus message: delete an entity: (" + entityType + "," + entityId + "), remove its related permission");
-                    _iamSrv.removeIAMPermissionForEntity(entityType, entityId);
-                }
-            }
-        });
-
-
-        _messageBus.subscribe(EntityManager.MESSAGE_GRANT_ENTITY_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Map<String, Object> permit = (Map<String, Object>)obj;
-                if (permit != null) {
-                    Class<?> entityType = (Class<?>)permit.get(ApiConstants.ENTITY_TYPE);
-                    Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID);
-                    AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE);
-                    String action = (String)permit.get(ApiConstants.IAM_ACTION);
-                    List<Long> acctIds = (List<Long>)permit.get(ApiConstants.ACCOUNTS);
-                    s_logger.debug("MessageBus message: grant accounts permission to an entity: (" + entityType + "," + entityId + ")");
-                    grantEntityPermissioinToAccounts(entityType.getSimpleName(), entityId, accessType, action, acctIds);
-                }
-            }
-        });
-
-        _messageBus.subscribe(EntityManager.MESSAGE_REVOKE_ENTITY_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Map<String, Object> permit = (Map<String, Object>)obj;
-                if (permit != null) {
-                    Class<?> entityType = (Class<?>)permit.get(ApiConstants.ENTITY_TYPE);
-                    Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID);
-                    AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE);
-                    String action = (String)permit.get(ApiConstants.IAM_ACTION);
-                    List<Long> acctIds = (List<Long>)permit.get(ApiConstants.ACCOUNTS);
-                    s_logger.debug("MessageBus message: revoke from accounts permission to an entity: (" + entityType + "," + entityId + ")");
-                    revokeEntityPermissioinFromAccounts(entityType.getSimpleName(), entityId, accessType, action, acctIds);
-                }
-            }
-        });
-
-        _messageBus.subscribe(EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, new MessageSubscriber() {
-            @Override
-            public void onPublishMessage(String senderAddress, String subject, Object obj) {
-                Map<String, Object> params = (Map<String, Object>) obj;
-                if (params != null) {
-                    addDomainWideResourceAccess(params);
-                }
-            }
-        });
-
-        return super.configure(name, params);
-    }
-
-    @Override
-    public boolean start() {
-        s_logger.info("Populating IAM group and account association for default accounts...");
-
-        // populate group <-> account association if not present for CS admin
-        // and system accounts
-        populateIAMGroupAdminAccountMap();
-
-        return true;
-    }
-
-    private void populateIAMGroupAdminAccountMap() {
-        List<Long> sysAccts = new ArrayList<Long>();
-        sysAccts.add(Account.ACCOUNT_ID_SYSTEM);
-        sysAccts.add(Account.ACCOUNT_ID_SYSTEM + 1);
-        _iamSrv.addAccountsToGroup(sysAccts, new Long(Account.ACCOUNT_TYPE_ADMIN + 1));
-    }
-
-    private void addDomainWideResourceAccess(Map<String, Object> params) {
-
-        Class<?> entityType = (Class<?>)params.get(ApiConstants.ENTITY_TYPE);
-        Long entityId = (Long) params.get(ApiConstants.ENTITY_ID);
-        Long domainId = (Long) params.get(ApiConstants.DOMAIN_ID);
-        Boolean isRecursive = (Boolean) params.get(ApiConstants.SUBDOMAIN_ACCESS);
-
-        if (entityType == Network.class) {
-            createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType.toString(),
-                    entityId, "listNetworks", AccessType.UseEntry, domainId, isRecursive);
-        } else if (entityType == AffinityGroup.class) {
-            createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide affinityGroup", entityType.toString(),
-                    entityId, "listAffinityGroups", AccessType.UseEntry, domainId, isRecursive);
-        }
-
-    }
-
-    private void createPolicyAndAddToDomainGroup(String policyName, String description, String entityType,
-            Long entityId, String action, AccessType accessType, Long domainId, Boolean recursive) {
-
-       Domain domain = _domainDao.findById(domainId);
-       if (domain != null) {
-            IAMPolicy policy = _iamSrv.createIAMPolicy(policyName, description, null, domain.getPath());
-            _iamSrv.addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE.toString(),
-                    entityId, action, accessType.toString(), Permission.Allow, recursive);
-            List<Long> policyList = new ArrayList<Long>();
-            policyList.add(new Long(policy.getId()));
-
-           List<IAMGroup> domainGroups = listDomainGroup(domain);
-           if (domainGroups != null) {
-               for (IAMGroup group : domainGroups) {
-                   _iamSrv.attachIAMPoliciesToGroup(policyList, group.getId());
-               }
-           }
-       }
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_CREATE, eventDescription = "Creating Acl Group", create = true)
-    public IAMGroup createIAMGroup(Account caller, String iamGroupName, String description) {
-        Long domainId = caller.getDomainId();
-        Domain callerDomain = _domainDao.findById(domainId);
-        if (callerDomain == null) {
-            throw new InvalidParameterValueException("Caller does not have a domain");
-        }
-        return _iamSrv.createIAMGroup(iamGroupName, description, callerDomain.getPath());
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_DELETE, eventDescription = "Deleting Acl Group")
-    public boolean deleteIAMGroup(final Long iamGroupId) {
-        return _iamSrv.deleteIAMGroup(iamGroupId);
-    }
-
-    @Override
-    public List<IAMGroup> listIAMGroups(long accountId) {
-        return _iamSrv.listIAMGroups(accountId);
-    }
-
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Adding accounts to acl group")
-    public IAMGroup addAccountsToGroup(final List<Long> acctIds, final Long groupId) {
-        return _iamSrv.addAccountsToGroup(acctIds, groupId);
-    }
-
-
-    private void removeAccountFromIAMGroups(long accountId) {
-        List<IAMGroup> groups = listIAMGroups(accountId);
-        List<Long> accts = new ArrayList<Long>();
-        accts.add(accountId);
-        if (groups != null) {
-            for (IAMGroup grp : groups) {
-                removeAccountsFromGroup(accts, grp.getId());
-            }
-        }
-    }
-
-    private void addAccountToIAMGroup(long accountId, long groupId) {
-        List<Long> accts = new ArrayList<Long>();
-        accts.add(accountId);
-        addAccountsToGroup(accts, groupId);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Removing accounts from acl group")
-    public IAMGroup removeAccountsFromGroup(final List<Long> acctIds, final Long groupId) {
-        return _iamSrv.removeAccountsFromGroup(acctIds, groupId);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_CREATE, eventDescription = "Creating IAM Policy", create = true)
-    public IAMPolicy createIAMPolicy(Account caller, final String iamPolicyName, final String description, final Long parentPolicyId) {
-        Long domainId = caller.getDomainId();
-        Domain callerDomain = _domainDao.findById(domainId);
-        if (callerDomain == null) {
-            throw new InvalidParameterValueException("Caller does not have a domain");
-        }
-        return _iamSrv.createIAMPolicy(iamPolicyName, description, parentPolicyId, callerDomain.getPath());
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_DELETE, eventDescription = "Deleting IAM Policy")
-    public boolean deleteIAMPolicy(final long iamPolicyId) {
-        return _iamSrv.deleteIAMPolicy(iamPolicyId);
-    }
-
-
-    @Override
-    public List<IAMPolicy> listIAMPolicies(long accountId) {
-        return _iamSrv.listIAMPolicies(accountId);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Attaching policy to acl group")
-    public IAMGroup attachIAMPoliciesToGroup(final List<Long> policyIds, final Long groupId) {
-        return _iamSrv.attachIAMPoliciesToGroup(policyIds, groupId);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Removing policies from acl group")
-    public IAMGroup removeIAMPoliciesFromGroup(final List<Long> policyIds, final Long groupId) {
-        return _iamSrv.removeIAMPoliciesFromGroup(policyIds, groupId);
-    }
-
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE, eventDescription = "Attaching policy to accounts")
-    public void attachIAMPolicyToAccounts(final Long policyId, final List<Long> accountIds) {
-        _iamSrv.attachIAMPolicyToAccounts(policyId, accountIds);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE, eventDescription = "Removing policy from accounts")
-    public void removeIAMPolicyFromAccounts(final Long policyId, final List<Long> accountIds) {
-        _iamSrv.removeIAMPolicyFromAccounts(policyId, accountIds);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_GRANT, eventDescription = "Granting acl permission to IAM Policy")
-    public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope,
-            Long scopeId, String action, Permission perm, Boolean recursive, Boolean readOnly) {
-        Class<?> cmdClass = _apiServer.getCmdClass(action);
-        AccessType accessType = null;
-        if (BaseListCmd.class.isAssignableFrom(cmdClass)) {
-            if (readOnly) {
-                accessType = AccessType.ListEntry;
-            } else {
-                accessType = AccessType.UseEntry;
-            }
-        } else {
-            accessType = AccessType.OperateEntry;
-        }
-        String accessTypeStr = (accessType != null) ? accessType.toString() : null;
-        return _iamSrv.addIAMPermissionToIAMPolicy(iamPolicyId, entityType, scope.toString(), scopeId, action,
-                accessTypeStr, perm, recursive);
-    }
-
-    @DB
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_REVOKE, eventDescription = "Revoking acl permission from IAM Policy")
-    public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, String action) {
-        return _iamSrv.removeIAMPermissionFromIAMPolicy(iamPolicyId, entityType, scope.toString(), scopeId, action);
-    }
-
-    @Override
-    public IAMPolicyPermission getIAMPolicyPermission(long accountId, String entityType, String action) {
-        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(accountId);
-        IAMPolicyPermission curPerm = null;
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> perms = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action,
-                    entityType);
-            if (perms == null || perms.size() == 0)
-                continue;
-            IAMPolicyPermission perm = perms.get(0); // just pick one
-            if (curPerm == null) {
-                curPerm = perm;
-            } else if (PermissionScope.valueOf(perm.getScope()).greaterThan(PermissionScope.valueOf(curPerm.getScope()))) {
-                // pick the more relaxed allowed permission
-                curPerm = perm;
-            }
-        }
-
-        return curPerm;
-    }
-
-
-    @Override
-    public IAMPolicyResponse createIAMPolicyResponse(IAMPolicy policy) {
-        IAMPolicyResponse response = new IAMPolicyResponse();
-        response.setId(policy.getUuid());
-        response.setName(policy.getName());
-        response.setDescription(policy.getDescription());
-        String domainPath = policy.getPath();
-        if (domainPath != null) {
-            DomainVO domain = _domainDao.findDomainByPath(domainPath);
-            if (domain != null) {
-                response.setDomainId(domain.getUuid());
-                response.setDomainName(domain.getName());
-            }
-        }
-        long accountId = policy.getAccountId();
-        AccountVO owner = _accountDao.findById(accountId);
-        if (owner != null) {
-            response.setAccountName(owner.getAccountName());
-        }
-        // find permissions associated with this policy
-        List<IAMPolicyPermission> permissions = _iamSrv.listPolicyPermissions(policy.getId());
-        if (permissions != null && permissions.size() > 0) {
-            for (IAMPolicyPermission permission : permissions) {
-                IAMPermissionResponse perm = new IAMPermissionResponse();
-                perm.setAction(permission.getAction());
-                if (permission.getEntityType() != null) {
-                    perm.setEntityType(permission.getEntityType());
-                }
-                if (permission.getScope() != null) {
-                    perm.setScope(PermissionScope.valueOf(permission.getScope()));
-                }
-                perm.setScopeId(permission.getScopeId());
-                perm.setPermission(permission.getPermission());
-                response.addPermission(perm);
-            }
-        }
-        response.setObjectName("aclpolicy");
-        return response;
-    }
-
-    @Override
-    public IAMGroupResponse createIAMGroupResponse(IAMGroup group) {
-        IAMGroupResponse response = new IAMGroupResponse();
-        response.setId(group.getUuid());
-        response.setName(group.getName());
-        response.setDescription(group.getDescription());
-        String domainPath = group.getPath();
-        if (domainPath != null) {
-            DomainVO domain = _domainDao.findDomainByPath(domainPath);
-            if (domain != null) {
-                response.setDomainId(domain.getUuid());
-                response.setDomainName(domain.getName());
-            }
-        }
-        long accountId = group.getAccountId();
-        AccountVO owner = _accountDao.findById(accountId);
-        if (owner != null) {
-            response.setAccountName(owner.getAccountName());
-        }
-        // find all the members in this group
-        List<Long> members = _iamSrv.listAccountsByGroup(group.getId());
-        if (members != null && members.size() > 0) {
-            for (Long member : members) {
-                AccountVO mem = _accountDao.findById(member);
-                if (mem != null) {
-                    response.addMemberAccount(mem.getAccountName());
-                }
-            }
-        }
-
-        // find all the policies attached to this group
-        List<IAMPolicy> policies = _iamSrv.listIAMPoliciesByGroup(group.getId());
-        if (policies != null && policies.size() > 0) {
-            for (IAMPolicy policy : policies) {
-                response.addPolicy(policy.getName());
-            }
-        }
-
-        response.setObjectName("aclgroup");
-        return response;
-
-    }
-
-    public List<IAMGroup> listDomainGroup(Domain domain) {
-
-        if (domain != null) {
-            String domainPath = domain.getPath();
-            // search for groups
-            Pair<List<IAMGroup>, Integer> result = _iamSrv.listIAMGroups(null, "DomainGrp-" + domain.getUuid(),
-                    domainPath, null, null);
-            return result.first();
-        }
-        return new ArrayList<IAMGroup>();
-
-    }
-
-    @Override
-    public ListResponse<IAMGroupResponse> listIAMGroups(Long iamGroupId, String iamGroupName, Long domainId, Long startIndex, Long pageSize) {
-        // acl check
-        Account caller = CallContext.current().getCallingAccount();
-
-        Domain domain = null;
-        if (domainId != null) {
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
-            }
-
-            _accountMgr.checkAccess(caller, domain);
-        } else {
-            domain = _domainDao.findById(caller.getDomainId());
-        }
-        String domainPath = domain.getPath();
-        // search for groups
-        Pair<List<IAMGroup>, Integer> result = _iamSrv.listIAMGroups(iamGroupId, iamGroupName, domainPath, startIndex, pageSize);
-        // generate group response
-        ListResponse<IAMGroupResponse> response = new ListResponse<IAMGroupResponse>();
-        List<IAMGroupResponse> groupResponses = new ArrayList<IAMGroupResponse>();
-        for (IAMGroup group : result.first()) {
-            IAMGroupResponse resp = createIAMGroupResponse(group);
-            groupResponses.add(resp);
-        }
-        response.setResponses(groupResponses, result.second());
-        return response;
-    }
-
-    @Override
-    public ListResponse<IAMPolicyResponse> listIAMPolicies(Long iamPolicyId, String iamPolicyName, Long domainId, Long startIndex,
-            Long pageSize) {
-        // acl check
-        Account caller = CallContext.current().getCallingAccount();
-
-        Domain domain = null;
-        if (domainId != null) {
-            domain = _domainDao.findById(domainId);
-            if (domain == null) {
-                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
-            }
-
-            _accountMgr.checkAccess(caller, domain);
-        } else {
-            domain = _domainDao.findById(caller.getDomainId());
-        }
-        String domainPath = domain.getPath();
-        // search for policies
-        Pair<List<IAMPolicy>, Integer> result = _iamSrv.listIAMPolicies(iamPolicyId, iamPolicyName, domainPath, startIndex, pageSize);
-        // generate policy response
-        ListResponse<IAMPolicyResponse> response = new ListResponse<IAMPolicyResponse>();
-        List<IAMPolicyResponse> policyResponses = new ArrayList<IAMPolicyResponse>();
-        for (IAMPolicy policy : result.first()) {
-            IAMPolicyResponse resp = createIAMPolicyResponse(policy);
-            policyResponses.add(resp);
-        }
-        response.setResponses(policyResponses, result.second());
-        return response;
-    }
-
-    @Override
-    public void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds) {
-        // check if there is already a policy with only this permission added to it
-        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(entityType, entityId, accessType.toString(), action);
-        if (policy == null) {
-            // not found, just create a policy with resource grant permission
-            Account caller = CallContext.current().getCallingAccount();
-            String aclPolicyName = "policyGrant" + entityType + entityId;
-            String description = "Policy to grant permission to " + entityType + entityId;
-            policy = createIAMPolicy(caller, aclPolicyName, description, null);
-            // add permission to this policy
-            addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action,
-                    Permission.Allow, false, false);
-        }
-        // attach this policy to list of accounts if not attached already
-        Long policyId = policy.getId();
-        for (Long acctId : accountIds) {
-            if (!isPolicyAttachedToAccount(policyId, acctId)) {
-                attachIAMPolicyToAccounts(policyId, Collections.singletonList(acctId));
-            }
-        }
-    }
-
-    @Override
-    public void revokeEntityPermissioinFromAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds) {
-        // there should already a policy with only this permission added to it, this call is mainly used
-        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(entityType, entityId, accessType.toString(), action);
-        if (policy == null) {
-            s_logger.warn("Cannot find a policy associated with this entity permissioin to be revoked, just return");
-            return;
-        }
-        // detach this policy from list of accounts if not detached already
-        Long policyId = policy.getId();
-        for (Long acctId : accountIds) {
-            if (isPolicyAttachedToAccount(policyId, acctId)) {
-                removeIAMPolicyFromAccounts(policyId, Collections.singletonList(acctId));
-            }
-        }
-
-    }
-
-    private boolean isPolicyAttachedToAccount(Long policyId, Long accountId) {
-        List<IAMPolicy> pList = listIAMPolicies(accountId);
-        for (IAMPolicy p : pList) {
-            if (p.getId() == policyId.longValue()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void resetTemplatePermission(Long templateId){
-        // reset template will change template to private, so we need to remove its permission for domain admin and normal user group
-        _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(),
-                PermissionScope.RESOURCE.toString(), templateId, "listTemplates");
-        _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(),
-                PermissionScope.RESOURCE.toString(), templateId, "listTemplates");
-        // check if there is a policy with only UseEntry permission for this template added
-        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(VirtualMachineTemplate.class.getSimpleName(), templateId, AccessType.UseEntry.toString(), "listTemplates");
-        if ( policy == null ){
-            s_logger.info("No policy found for this template grant: " + templateId + ", no detach to be done");
-            return;
-        }
-        // delete the policy, which should detach it from groups and accounts
-        _iamSrv.deleteIAMPolicy(policy.getId());
-
-    }
-
-    @Override
-    public Long getPermissionScopeId(String scope, String entityType, String scopeId) {
-        if (scopeId.equals("-1")) {
-            return -1L;
-        }
-        PermissionScope permScope = PermissionScope.valueOf(scope);
-        InternalIdentity entity = null;
-        switch (permScope) {
-        case DOMAIN:
-            entity = _domainDao.findByUuid(scopeId);
-            break;
-        case ACCOUNT:
-            entity = _accountDao.findByUuid(scopeId);
-            break;
-        case RESOURCE:
-            Class<?> clazz = s_typeMap.get(entityType);
-            entity = (InternalIdentity)_entityMgr.findByUuid(clazz, scopeId);
-        }
-
-        if (entity != null) {
-            return entity.getId();
-        }
-        throw new InvalidParameterValueException("Unable to find scopeId " + scopeId + " with scope " + scope + " and type " + entityType);
-    }
-
-    @Override
-    public List<Class<?>> getCommands() {
-        List<Class<?>> cmdList = new ArrayList<Class<?>>();
-        cmdList.add(CreateIAMPolicyCmd.class);
-        cmdList.add(DeleteIAMPolicyCmd.class);
-        cmdList.add(ListIAMPoliciesCmd.class);
-        cmdList.add(AddIAMPermissionToIAMPolicyCmd.class);
-        cmdList.add(RemoveIAMPermissionFromIAMPolicyCmd.class);
-        cmdList.add(AttachIAMPolicyToIAMGroupCmd.class);
-        cmdList.add(RemoveIAMPolicyFromIAMGroupCmd.class);
-        cmdList.add(CreateIAMGroupCmd.class);
-        cmdList.add(DeleteIAMGroupCmd.class);
-        cmdList.add(ListIAMGroupsCmd.class);
-        cmdList.add(AddAccountToIAMGroupCmd.class);
-        cmdList.add(RemoveAccountFromIAMGroupCmd.class);
-        cmdList.add(AttachIAMPolicyToAccountCmd.class);
-        cmdList.add(RemoveIAMPolicyFromAccountCmd.class);
-        return cmdList;
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
deleted file mode 100644
index 3072b77..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
+++ /dev/null
@@ -1,287 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.APIChecker;
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.api.IAMService;
-
-import com.cloud.api.ApiServerService;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.template.VirtualMachineTemplate;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.user.User;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-//This is the Role Based API access checker that grab's the  account's roles
-//based on the set of roles, access is granted if any of the role has access to the api
-public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker {
-
-    protected static final Logger s_logger = Logger.getLogger(RoleBasedAPIAccessChecker.class);
-
-    @Inject
-    AccountService _accountService;
-    @Inject
-    ApiServerService _apiServer;
-    @Inject
-    IAMService _iamSrv;
-    @Inject
-    VMTemplateDao _templateDao;
-
-    Set<String> commandsPropertiesOverrides = new HashSet<String>();
-    Map<RoleType, Set<String>> commandsPropertiesRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
-
-    List<PluggableService> _services;
-
-    protected RoleBasedAPIAccessChecker() {
-        super();
-        for (RoleType roleType : RoleType.values()) {
-            commandsPropertiesRoleBasedApisMap.put(roleType, new HashSet<String>());
-        }
-     }
-
-    @Override
-    public boolean checkAccess(User user, String commandName) throws PermissionDeniedException {
-        Account account = _accountService.getAccount(user.getAccountId());
-        if (account == null) {
-            throw new PermissionDeniedException("The account id=" + user.getAccountId() + "for user id=" + user.getId()
-                    + "is null");
-        }
-
-        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(account.getAccountId());
-
-        boolean isAllowed = _iamSrv.isActionAllowedForPolicies(commandName, policies);
-        if (!isAllowed) {
-            throw new PermissionDeniedException("The API does not exist or is blacklisted. api: " + commandName);
-        }
-        return isAllowed;
-     }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        processMapping(PropertiesUtil.processConfigFile(new String[] { "commands.properties" }));
-        return true;
-     }
-
-    @Override
-    public boolean start() {
-
-        // drop all default policy api permissions - we reload them every time
-        // to include any changes done to the @APICommand or
-        // commands.properties.
-
-        for (RoleType role : RoleType.values()) {
-            Long policyId = getDefaultPolicyId(role);
-            if (policyId != null) {
-                _iamSrv.resetIAMPolicy(policyId);
-            }
-         }
-
-        // add the system-domain capability
-
-        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), null, null, null,
-                "SystemCapability", null, Permission.Allow, false);
-        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), null, null, null,
-                "DomainCapability", null, Permission.Allow, false);
-        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1), null, null, null,
-                "DomainResourceCapability", null, Permission.Allow, false);
-
-        // add permissions for public templates
-        List<VMTemplateVO> pTmplts = _templateDao.listByPublic();
-        for (VMTemplateVO tmpl : pTmplts){
-            _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(),
-                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-            _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), VirtualMachineTemplate.class.getSimpleName(),
-                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-            _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), VirtualMachineTemplate.class.getSimpleName(),
-                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
-        }
-
-        for (PluggableService service : _services) {
-            for (Class<?> cmdClass : service.getCommands()) {
-                APICommand command = cmdClass.getAnnotation(APICommand.class);
-                if (!commandsPropertiesOverrides.contains(command.name())) {
-                    for (RoleType role : command.authorized()) {
-                        addDefaultAclPolicyPermission(command.name(), cmdClass, role);
-                    }
-                 }
-             }
-         }
-
-        // read commands.properties and load api acl permissions -
-        // commands.properties overrides any @APICommand authorization
-
-        for (String apiName : commandsPropertiesOverrides) {
-            Class<?> cmdClass = _apiServer.getCmdClass(apiName);
-            for (RoleType role : RoleType.values()) {
-                if (commandsPropertiesRoleBasedApisMap.get(role).contains(apiName)) {
-                    // insert permission for this role for this api
-                    addDefaultAclPolicyPermission(apiName, cmdClass, role);
-                }
-             }
-         }
-
-        return super.start();
-     }
-
-    private Long getDefaultPolicyId(RoleType role) {
-        Long policyId = null;
-        switch (role) {
-        case User:
-            policyId = new Long(Account.ACCOUNT_TYPE_NORMAL + 1);
-            break;
-
-        case Admin:
-            policyId = new Long(Account.ACCOUNT_TYPE_ADMIN + 1);
-            break;
-
-        case DomainAdmin:
-            policyId = new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1);
-            break;
-
-        case ResourceAdmin:
-            policyId = new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1);
-            break;
-        }
-
-        return policyId;
-    }
-
-    private void processMapping(Map<String, String> configMap) {
-        for (Map.Entry<String, String> entry : configMap.entrySet()) {
-            String apiName = entry.getKey();
-            String roleMask = entry.getValue();
-            commandsPropertiesOverrides.add(apiName);
-            try {
-                short cmdPermissions = Short.parseShort(roleMask);
-                for (RoleType roleType : RoleType.values()) {
-                    if ((cmdPermissions & roleType.getMask()) != 0)
-                        commandsPropertiesRoleBasedApisMap.get(roleType).add(apiName);
-                }
-            } catch (NumberFormatException nfe) {
-                s_logger.info("Malformed key=value pair for entry: " + entry.toString());
-             }
-         }
-     }
-
-    public List<PluggableService> getServices() {
-        return _services;
-     }
-
-    @Inject
-    public void setServices(List<PluggableService> services) {
-        _services = services;
-     }
-
-    private void addDefaultAclPolicyPermission(String apiName, Class<?> cmdClass, RoleType role) {
-        AccessType accessType = null;
-        Class<?>[] entityTypes = null;
-
-        PermissionScope permissionScope = PermissionScope.ACCOUNT;
-        Long policyId = getDefaultPolicyId(role);
-        switch (role) {
-        case User:
-            permissionScope = PermissionScope.ACCOUNT;
-            break;
-
-        case Admin:
-            permissionScope = PermissionScope.ALL;
-            break;
-
-        case DomainAdmin:
-            permissionScope = PermissionScope.DOMAIN;
-            break;
-
-        case ResourceAdmin:
-            permissionScope = PermissionScope.DOMAIN;
-            break;
-         }
-
-        boolean addAccountScopedUseEntry = false;
-
-        if (cmdClass != null) {
-            BaseCmd cmdObj;
-            try {
-                cmdObj = (BaseCmd) cmdClass.newInstance();
-                if (cmdObj instanceof BaseListCmd) {
-                    if (permissionScope == PermissionScope.ACCOUNT) {
-                        accessType = AccessType.UseEntry;
-                    } else {
-                        accessType = AccessType.ListEntry;
-                        addAccountScopedUseEntry = true;
-                    }
-                } else {
-                    accessType = AccessType.OperateEntry;
-                }
-            } catch (Exception e) {
-                throw new CloudRuntimeException(String.format(
-                        "%s is claimed as an API command, but it cannot be instantiated", cmdClass.getName()));
-            }
-
-            APICommand at = cmdClass.getAnnotation(APICommand.class);
-            entityTypes = at.entityType();
-        }
-
-        if (entityTypes == null || entityTypes.length == 0) {
-            _iamSrv.addIAMPermissionToIAMPolicy(policyId, null, permissionScope.toString(), new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
-                    apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
-            if (addAccountScopedUseEntry) {
-                _iamSrv.addIAMPermissionToIAMPolicy(policyId, null, PermissionScope.ACCOUNT.toString(), new Long(
-                        IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, AccessType.UseEntry.toString(), Permission.Allow, false);
-            }
-        } else {
-            for (Class<?> entityType : entityTypes) {
-                _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.getSimpleName(), permissionScope.toString(), new Long(
-                        IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
-                        apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
-                if (addAccountScopedUseEntry) {
-                    _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.getSimpleName(), PermissionScope.ACCOUNT.toString(), new Long(
-                            IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER), apiName, AccessType.UseEntry.toString(), Permission.Allow, false);
-                }
-            }
-         }
-
-     }
-
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java
deleted file mode 100644
index ce9d975..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java
+++ /dev/null
@@ -1,329 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.SecurityChecker;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMService;
-
-import com.cloud.acl.DomainChecker;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-
-public class RoleBasedEntityAccessChecker extends DomainChecker implements SecurityChecker {
-
-    private static final Logger s_logger = Logger.getLogger(RoleBasedEntityAccessChecker.class.getName());
-
-    @Inject
-    AccountService _accountService;
-
-    @Inject DomainDao _domainDao;
-
-    @Inject
-    IAMService _iamSrv;
-
-
-    @Override
-    public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
-            throws PermissionDeniedException {
-        return checkAccess(caller, entity, accessType, null);
-    }
-
-    private String buildAccessCacheKey(Account caller, ControlledEntity entity, AccessType accessType, String action) {
-        StringBuffer key = new StringBuffer();
-        key.append(caller.getAccountId());
-        key.append("-");
-        String entityType = null;
-        if (entity != null && entity.getEntityType() != null) {
-            entityType = entity.getEntityType().getSimpleName();
-            if (entity instanceof InternalIdentity) {
-                entityType += ((InternalIdentity)entity).getId();
-            }
-        }
-        key.append(entityType != null ? entityType : "null");
-        key.append("-");
-        key.append(accessType != null ? accessType.toString() : "null");
-        key.append("-");
-        key.append(action != null ? action : "null");
-        return key.toString();
-    }
-
-    @Override
-    public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action)
-            throws PermissionDeniedException {
-
-        if (caller == null) {
-            throw new InvalidParameterValueException("Caller cannot be passed as NULL to IAM!");
-        }
-
-        if (entity == null && action == null) {
-            throw new InvalidParameterValueException("Entity and action cannot be both NULL in checkAccess!");
-        }
-
-        // check IAM cache first
-        String accessKey = buildAccessCacheKey(caller, entity, accessType, action);
-        CheckAccessResult allowDeny = (CheckAccessResult)_iamSrv.getFromIAMCache(accessKey);
-        if (allowDeny != null) {
-            s_logger.debug("IAM access check for " + accessKey + " from cache: " + allowDeny.isAllow());
-            if (allowDeny.isAllow()) {
-                return true;
-            } else {
-                if (allowDeny.getDenyMsg() != null) {
-                    throw new PermissionDeniedException(allowDeny.getDenyMsg());
-                } else {
-                    return false;
-                }
-            }
-        }
-
-        if (entity == null && action != null) {
-            // check if caller can do this action
-            List<IAMPolicy> policies = _iamSrv.listIAMPolicies(caller.getAccountId());
-
-            boolean isAllowed = _iamSrv.isActionAllowedForPolicies(action, policies);
-            if (!isAllowed) {
-                String msg = "The action '" + action + "' not allowed for account " + caller;
-                _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(msg));
-                throw new PermissionDeniedException(msg);
-            }
-            _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(true));
-            return true;
-        }
-
-
-        // if a Project entity, skip
-        Account entityAccount = _accountService.getAccount(entity.getAccountId());
-        if (entityAccount != null && entityAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) {
-            _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(false));
-            return false;
-        }
-
-        String entityType = null;
-        if (entity.getEntityType() != null) {
-            entityType = entity.getEntityType().getSimpleName();
-        }
-
-        if (accessType == null) {
-            accessType = AccessType.UseEntry;
-        }
-
-        // get all Policies of this caller by considering recursive domain group policy
-        List<IAMPolicy> policies = getEffectivePolicies(caller);
-        HashMap<IAMPolicy, Boolean> policyPermissionMap = new HashMap<IAMPolicy, Boolean>();
-
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> permissions = new ArrayList<IAMPolicyPermission>();
-
-            if (action != null) {
-                permissions = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action, entityType);
-                if (permissions.isEmpty()) {
-                    if (accessType != null) {
-                        for (AccessType type : AccessType.values()) {
-                            if (type.ordinal() >= accessType.ordinal()) {
-                                permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
-                                        type.toString(), entityType));
-                            }
-                        }
-                    }
-                }
-            } else {
-                if (accessType != null) {
-                    for (AccessType type : AccessType.values()) {
-                        if (type.ordinal() >= accessType.ordinal()) {
-                            permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
-                                    type.toString(), entityType));
-                        }
-                    }
-                }
-            }
-            for (IAMPolicyPermission permission : permissions) {
-                if (checkPermissionScope(caller, permission.getScope(), permission.getScopeId(), entity)) {
-                    if (permission.getEntityType().equals(entityType)) {
-                        policyPermissionMap.put(policy, permission.getPermission().isGranted());
-                        break;
-                    } else if (permission.getEntityType().equals("*")) {
-                        policyPermissionMap.put(policy, permission.getPermission().isGranted());
-                    }
-                }
-            }
-            if (policyPermissionMap.containsKey(policy) && policyPermissionMap.get(policy)) {
-                _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(true));
-                return true;
-            }
-        }
-
-        if (!policies.isEmpty()) { // Since we reach this point, none of the
-                                   // roles granted access
-
-            String msg = "Account " + caller + " does not have permission to access resource " + entity
-                    + " for access type: " + accessType;
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(msg);
-            }
-            _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(msg));
-            throw new PermissionDeniedException(msg);
-        }
-
-        _iamSrv.addToIAMCache(accessKey, new CheckAccessResult(false));
-        return false;
-    }
-
-    @Override
-    public boolean checkAccess(Account caller, AccessType accessType, String action, ControlledEntity... entities)
-            throws PermissionDeniedException {
-
-        // operate access on multiple entities?
-        if (accessType != null && accessType == AccessType.OperateEntry) {
-            // In this case caller MUST own n-1 entities.
-
-            for (ControlledEntity entity : entities) {
-                checkAccess(caller, entity, accessType, action);
-
-                boolean otherEntitiesAccess = true;
-
-                for (ControlledEntity otherEntity : entities) {
-                    if (otherEntity.getAccountId() == caller.getAccountId()
-                            || (checkAccess(caller, otherEntity, accessType, action) && otherEntity.getAccountId() == entity
-                                    .getAccountId())) {
-                        continue;
-                    } else {
-                        otherEntitiesAccess = false;
-                        break;
-                    }
-                }
-
-                if (otherEntitiesAccess) {
-                    return true;
-                }
-            }
-
-            throw new PermissionDeniedException(caller
-                    + " does not have permission to perform this operation on these resources");
-
-        } else {
-            for (ControlledEntity entity : entities) {
-                if (!checkAccess(caller, entity, accessType, action)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    private boolean checkPermissionScope(Account caller, String scope, Long scopeId, ControlledEntity entity) {
-
-        if(scopeId != null && !scopeId.equals(new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))){
-            //scopeId is set
-            if (scope.equals(PermissionScope.ACCOUNT.name())) {
-                if(scopeId == entity.getAccountId()){
-                    return true;
-                }
-            } else if (scope.equals(PermissionScope.DOMAIN.name())) {
-                if (_domainDao.isChildDomain(scopeId, entity.getDomainId())) {
-                    return true;
-                }
-            } else if (scope.equals(PermissionScope.RESOURCE.name())) {
-                if (entity instanceof InternalIdentity) {
-                    InternalIdentity entityWithId = (InternalIdentity) entity;
-                    if(scopeId.equals(entityWithId.getId())){
-                        return true;
-                    }
-                }
-            }
-        } else if (scopeId == null || scopeId.equals(new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))) {
-            if (scope.equals(PermissionScope.ACCOUNT.name())) {
-                if(caller.getAccountId() == entity.getAccountId()){
-                    return true;
-                }
-            } else if (scope.equals(PermissionScope.DOMAIN.name())) {
-                if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private List<IAMPolicy> getEffectivePolicies(Account caller) {
-
-        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(caller.getId());
-
-        List<IAMGroup> groups = _iamSrv.listIAMGroups(caller.getId());
-        for (IAMGroup group : groups) {
-            // for each group find the grand parent groups.
-            List<IAMGroup> parentGroups = _iamSrv.listParentIAMGroups(group.getId());
-            for (IAMGroup parentGroup : parentGroups) {
-                policies.addAll(_iamSrv.listRecursiveIAMPoliciesByGroup(parentGroup.getId()));
-            }
-        }
-
-        return policies;
-    }
-
-    private class CheckAccessResult {
-        boolean allow;
-        String denyMsg;
-
-        public CheckAccessResult(boolean aw) {
-            this(aw, null);
-        }
-
-        public CheckAccessResult(String msg) {
-            this(false, msg);
-        }
-
-        public CheckAccessResult(boolean aw, String msg) {
-            allow = aw;
-            denyMsg = msg;
-        }
-
-        public boolean isAllow() {
-            return allow;
-        }
-
-        public void setAllow(boolean aw) {
-            allow = aw;
-        }
-
-
-        public String getDenyMsg() {
-            return denyMsg;
-        }
-
-        public void setDenyMsg(String denyMsg) {
-            this.denyMsg = denyMsg;
-        }
-
-    }
-}
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java
deleted file mode 100644
index a9be17a..0000000
--- a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java
+++ /dev/null
@@ -1,188 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.QuerySelector;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMService;
-
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.user.Account;
-import com.cloud.utils.component.AdapterBase;
-
-public class RoleBasedEntityQuerySelector extends AdapterBase implements QuerySelector {
-
-    private static final Logger s_logger = Logger.getLogger(RoleBasedEntityQuerySelector.class.getName());
-
-    @Inject
-    IAMService _iamService;
-    @Inject
-    DomainDao _domainDao;
-
-    @Override
-    public List<Long> getAuthorizedDomains(Account caller, String action, AccessType accessType) {
-        long accountId = caller.getAccountId();
-        if (accessType == null) {
-            accessType = AccessType.UseEntry;  // default always show resources authorized to use
-        }
-        // Get the static Policies of the Caller
-        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
-        // for each policy, find granted permission with Domain scope
-        List<Long> domainIds = new ArrayList<Long>();
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> pp = new ArrayList<IAMPolicyPermission>();
-            pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action,
-                    PermissionScope.DOMAIN.toString(), accessType.toString()));
-
-            if (pp != null) {
-                for (IAMPolicyPermission p : pp) {
-                    if (p.getScopeId() != null) {
-                        Long domainId = null;
-                        if (p.getScopeId().longValue() == -1) {
-                            domainId = caller.getDomainId();
-                            //domainIds.add(caller.getDomainId());
-                        } else {
-                            domainId = p.getScopeId();
-                            //domainIds.add(p.getScopeId());
-                        }
-                        //domainIds.add(domainId);
-                        // add all the domain children from this domain (including this domain itself). Like RoleBasedEntityAccessChecker, we made an assumption, if DOMAIN scope is granted, it means that
-                        // the whole domain tree is granted access.
-                        DomainVO domain = _domainDao.findById(domainId);
-                        List<Long> childDomains = _domainDao.getDomainChildrenIds(domain.getPath());
-                        if (childDomains != null && childDomains.size() > 0) {
-                            domainIds.addAll(childDomains);
-                        }
-
-                    }
-                }
-            }
-        }
-        return domainIds;
-    }
-
-    @Override
-    public List<Long> getAuthorizedAccounts(Account caller, String action, AccessType accessType) {
-        long accountId = caller.getAccountId();
-        if (accessType == null) {
-            accessType = AccessType.UseEntry;  // default always show resources authorized to use
-        }
-        // Get the static Policies of the Caller
-        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
-        // for each policy, find granted permission with Account scope
-        List<Long> accountIds = new ArrayList<Long>();
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> pp = new ArrayList<IAMPolicyPermission>();
-            pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action,
-                    PermissionScope.ACCOUNT.toString(), accessType.toString()));
-
-            if (pp != null) {
-                for (IAMPolicyPermission p : pp) {
-                    if (p.getScopeId() != null) {
-                        if (p.getScopeId().longValue() == -1) {
-                            accountIds.add(caller.getId());
-                        } else {
-                            accountIds.add(p.getScopeId());
-                        }
-                    }
-                }
-            }
-        }
-        return accountIds;
-    }
-
-    @Override
-    public List<Long> getAuthorizedResources(Account caller, String action, AccessType accessType) {
-        long accountId = caller.getAccountId();
-        if (accessType == null) {
-            accessType = AccessType.UseEntry;  // default always show resources authorized to use
-        }
-        // Get the static Policies of the Caller
-        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
-
-        // add the policies that grant recursive access
-        List<IAMGroup> groups = _iamService.listIAMGroups(caller.getId());
-        for (IAMGroup group : groups) {
-            // for each group find the grand parent groups.
-            List<IAMGroup> parentGroups = _iamService.listParentIAMGroups(group.getId());
-            for (IAMGroup parentGroup : parentGroups) {
-                policies.addAll(_iamService.listRecursiveIAMPoliciesByGroup(parentGroup.getId()));
-            }
-        }
-
-        // for each policy, find granted permission with Resource scope
-        List<Long> entityIds = new ArrayList<Long>();
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> pp = new ArrayList<IAMPolicyPermission>();
-            pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action,
-                    PermissionScope.RESOURCE.toString(), accessType.toString()));
-
-            if (pp != null) {
-                for (IAMPolicyPermission p : pp) {
-                    if (p.getScopeId() != null) {
-                        entityIds.add(p.getScopeId());
-                    }
-                }
-            }
-        }
-        return entityIds;
-    }
-
-    @Override
-    public boolean isGrantedAll(Account caller, String action, AccessType accessType) {
-        long accountId = caller.getAccountId();
-        if (accessType == null) {
-            accessType = AccessType.UseEntry;  // default always show resources authorized to use
-        }
-        // Get the static Policies of the Caller
-        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
-        // for each policy, find granted permission with ALL scope
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermission> pp = new ArrayList<IAMPolicyPermission>();
-            pp.addAll(_iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ALL.toString(),
-                    accessType.toString()));
-            if (pp != null && pp.size() > 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public List<String> listAclGroupsByAccount(long accountId) {
-        List<IAMGroup> groups = _iamService.listIAMGroups(accountId);
-        List<String> groupNames = new ArrayList<String>();
-        for (IAMGroup grp : groups) {
-            groupNames.add(grp.getName());
-        }
-        return groupNames;
-    }
-
-}
-
diff --git a/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java b/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java
deleted file mode 100644
index 84e1e56..0000000
--- a/services/iam/plugin/test/org/apache/cloudstack/iam/test/IAMApiServiceTest.java
+++ /dev/null
@@ -1,385 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
-import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
-import org.apache.cloudstack.api.response.iam.IAMPermissionResponse;
-import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.framework.messagebus.MessageBus;
-import org.apache.cloudstack.iam.IAMApiService;
-import org.apache.cloudstack.iam.IAMApiServiceImpl;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.api.IAMService;
-import org.apache.cloudstack.iam.server.IAMGroupVO;
-import org.apache.cloudstack.iam.server.IAMPolicyPermissionVO;
-import org.apache.cloudstack.iam.server.IAMPolicyVO;
-import org.apache.cloudstack.test.utils.SpringUtils;
-
-import com.cloud.api.ApiServerService;
-import com.cloud.domain.DomainVO;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.network.dao.NetworkDomainDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.UserVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.vm.VirtualMachine;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class IAMApiServiceTest {
-
-    @Inject
-    IAMService _iamSrv;
-
-    @Inject
-    DomainDao _domainDao;
-
-    @Inject
-    IAMApiService _aclSrv;
-
-    @Inject
-    AccountManager _accountMgr;
-
-    @Inject
-    AccountDao _accountDao;
-
-    @Inject
-    ApiServerService _apiServer;
-
-    private static Account caller;
-    private static Long callerId;
-    private static String callerAccountName = "tester";
-    private static Long callerDomainId = 3L;
-    private static String callerDomainPath = "/root/testdomain";
-    private static DomainVO callerDomain;
-
-    @BeforeClass
-    public static void setUpClass() throws ConfigurationException {
-    }
-
-    @Before
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-        caller = new AccountVO(callerAccountName, callerDomainId, null, Account.ACCOUNT_TYPE_ADMIN, UUID.randomUUID().toString());
-        callerId = caller.getId();
-        callerDomain = new DomainVO();
-        callerDomain.setPath(callerDomainPath);
-        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
-        CallContext.register(user, caller);
-
-        when(_domainDao.findById(callerDomainId)).thenReturn(callerDomain);
-        doNothing().when(_accountMgr).checkAccess(caller, callerDomain);
-    }
-
-    @Test
-    public void createIAMGroupTest() {
-        IAMGroup group = new IAMGroupVO("group1", "tester group1");
-        List<IAMGroup> groups = new ArrayList<IAMGroup>();
-        groups.add(group);
-        Pair<List<IAMGroup>, Integer> grpList = new Pair<List<IAMGroup>, Integer>(groups, 1);
-        when(_iamSrv.createIAMGroup("group1", "tester group1", callerDomainPath)).thenReturn(group);
-        when(_iamSrv.listIAMGroups(null, null, callerDomainPath, 0L, 20L)).thenReturn(grpList);
-
-        IAMGroup createdGrp = _aclSrv.createIAMGroup(caller, "group1", "tester group1");
-        assertNotNull("IAM group 'group1' failed to create ", createdGrp);
-        ListResponse<IAMGroupResponse> grpResp = _aclSrv.listIAMGroups(null, null, callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
-        IAMGroupResponse resp = grpResp.getResponses().get(0);
-        assertEquals("Error in created group name", "group1", resp.getName());
-    }
-
-    @Test
-    public void deleteIAMGroupTest() {
-        when(_iamSrv.deleteIAMGroup(1L)).thenReturn(true);
-        assertTrue("failed to delete acl group 1", _aclSrv.deleteIAMGroup(1L));
-    }
-
-    @Test
-    public void listIAMGroupTest() {
-        IAMGroup group = new IAMGroupVO("group1", "tester group1");
-        List<IAMGroup> groups = new ArrayList<IAMGroup>();
-        groups.add(group);
-        when(_iamSrv.listIAMGroups(callerId)).thenReturn(groups);
-        List<IAMGroup> grps = _aclSrv.listIAMGroups(callerId);
-        assertTrue(grps != null && grps.size() == 1);
-        IAMGroup grp = grps.get(0);
-        assertEquals("Error to retrieve group", "group1", grp.getName());
-    }
-
-    @Test
-    public void addRemoveAccountToGroupTest() {
-        IAMGroup group = new IAMGroupVO("group1", "tester group1");
-        List<IAMGroup> groups = new ArrayList<IAMGroup>();
-        groups.add(group);
-        Long groupId = group.getId();
-        List<Long> acctIds = new ArrayList<Long>();
-        AccountVO acct1 = new AccountVO(100L);
-        acct1.setAccountName("account1");
-        AccountVO acct2 = new AccountVO(200L);
-        acct2.setAccountName("account2");
-        acctIds.add(acct1.getId());
-        acctIds.add(acct2.getId());
-        when(_accountDao.findById(acct1.getId())).thenReturn(acct1);
-        when(_accountDao.findById(acct2.getId())).thenReturn(acct2);
-        when(_iamSrv.addAccountsToGroup(acctIds, groupId)).thenReturn(group);
-        when(_iamSrv.listAccountsByGroup(groupId)).thenReturn(acctIds);
-        Pair<List<IAMGroup>, Integer> grpList = new Pair<List<IAMGroup>, Integer>(groups, 1);
-        when(_iamSrv.listIAMGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
-        _aclSrv.addAccountsToGroup(acctIds, groupId);
-        ListResponse<IAMGroupResponse> grpResp = _aclSrv.listIAMGroups(null, "group1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
-        IAMGroupResponse resp = grpResp.getResponses().get(0);
-        Set<String> acctNames = resp.getAccountNameList();
-        assertEquals("There should be 2 accounts in the group", 2, acctNames.size());
-        assertTrue("account1 should be assigned to the group", acctNames.contains("account1"));
-        assertTrue("account2 should be assigned to the group", acctNames.contains("account2"));
-        // remove "account2" from group1
-        acctIds.remove(1);
-        List<Long> rmAccts = new ArrayList<Long>();
-        rmAccts.add(acct2.getId());
-        when(_iamSrv.removeAccountsFromGroup(rmAccts, groupId)).thenReturn(group);
-        _aclSrv.removeAccountsFromGroup(acctIds, groupId);
-        grpResp = _aclSrv.listIAMGroups(null, "group1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
-        resp = grpResp.getResponses().get(0);
-        acctNames = resp.getAccountNameList();
-        assertEquals("There should be 1 accounts in the group", 1, acctNames.size());
-        assertFalse("account2 should not belong to the group anymore", acctNames.contains("account2"));
-    }
-
-    @Test
-    public void createIAMPolicyTest() {
-        IAMPolicy policy = new IAMPolicyVO("policy1", "tester policy1");
-        List<IAMPolicy> policies = new ArrayList<IAMPolicy>();
-        policies.add(policy);
-        Pair<List<IAMPolicy>, Integer> policyList = new Pair<List<IAMPolicy>, Integer>(policies, 1);
-        when(_iamSrv.createIAMPolicy("policy1", "tester policy1", null, callerDomainPath)).thenReturn(policy);
-        when(_iamSrv.listIAMPolicies(null, null, callerDomainPath, 0L, 20L)).thenReturn(policyList);
-
-        IAMPolicy createdPolicy = _aclSrv.createIAMPolicy(caller, "policy1", "tester policy1", null);
-        assertNotNull("IAM policy 'policy1' failed to create ", createdPolicy);
-        ListResponse<IAMPolicyResponse> policyResp = _aclSrv.listIAMPolicies(null, null, callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
-        IAMPolicyResponse resp = policyResp.getResponses().get(0);
-        assertEquals("Error in created group name", "policy1", resp.getName());
-    }
-
-    @Test
-    public void deleteIAMPolicyTest() {
-        when(_iamSrv.deleteIAMPolicy(1L)).thenReturn(true);
-        assertTrue("failed to delete acl policy 1", _aclSrv.deleteIAMPolicy(1L));
-    }
-
-    @Test
-    public void listIAMPolicyTest() {
-        IAMPolicy policy = new IAMPolicyVO("policy1", "tester policy1");
-        List<IAMPolicy> policies = new ArrayList<IAMPolicy>();
-        policies.add(policy);
-        when(_iamSrv.listIAMPolicies(callerId)).thenReturn(policies);
-        List<IAMPolicy> polys = _aclSrv.listIAMPolicies(callerId);
-        assertTrue(polys != null && polys.size() == 1);
-        IAMPolicy p = polys.get(0);
-        assertEquals("Error to retrieve group", "policy1", p.getName());
-    }
-
-    @Test
-    public void addRemovePolicyToGroupTest() {
-        IAMGroup group = new IAMGroupVO("group1", "tester group1");
-        List<IAMGroup> groups = new ArrayList<IAMGroup>();
-        groups.add(group);
-        Long groupId = group.getId();
-        List<Long> policyIds = new ArrayList<Long>();
-        policyIds.add(100L);
-        policyIds.add(200L);
-        IAMPolicy policy1 = new IAMPolicyVO("policy1", "my first policy");
-        IAMPolicy policy2 = new IAMPolicyVO("policy2", "my second policy");
-        List<IAMPolicy> policies = new ArrayList<IAMPolicy>();
-        policies.add(policy1);
-        policies.add(policy2);
-        when(_iamSrv.attachIAMPoliciesToGroup(policyIds, groupId)).thenReturn(group);
-        when(_iamSrv.listIAMPoliciesByGroup(groupId)).thenReturn(policies);
-        Pair<List<IAMGroup>, Integer> grpList = new Pair<List<IAMGroup>, Integer>(groups, 1);
-        when(_iamSrv.listIAMGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
-        _aclSrv.attachIAMPoliciesToGroup(policyIds, groupId);
-        ListResponse<IAMGroupResponse> grpResp = _aclSrv.listIAMGroups(null, "group1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
-        IAMGroupResponse resp = grpResp.getResponses().get(0);
-        Set<String> policyNames = resp.getPolicyList();
-        assertEquals("There should be 2 policies in the group", 2, policyNames.size());
-        assertTrue("policy1 should be assigned to the group", policyNames.contains("policy1"));
-        assertTrue("policy2 should be assigned to the group", policyNames.contains("policy2"));
-        // remove "policy2" from group1
-        policyIds.remove(1);
-        policies.remove(policy2);
-        when(_iamSrv.removeIAMPoliciesFromGroup(policyIds, groupId)).thenReturn(group);
-        _aclSrv.removeIAMPoliciesFromGroup(policyIds, groupId);
-        grpResp = _aclSrv.listIAMGroups(null, "group1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", grpResp.getCount() == 1);
-        resp = grpResp.getResponses().get(0);
-        policyNames = resp.getPolicyList();
-        assertEquals("There should be 1 policy attached to the group", 1, policyNames.size());
-        assertFalse("policy2 should not belong to the group anymore", policyNames.contains("policy2"));
-    }
-
-    @Test
-    public void addRemovePermissionToPolicyTest() {
-        IAMPolicy policy = new IAMPolicyVO("policy1", "tester policy1");
-        List<IAMPolicy> policies = new ArrayList<IAMPolicy>();
-        policies.add(policy);
-        Long policyId = policy.getId();
-        Long resId = 200L;
-        Class clz = ListVMsCmd.class;
-        when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(clz);
-        when(
-                _iamSrv.addIAMPermissionToIAMPolicy(policyId, VirtualMachine.class.getSimpleName(),
-                        PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines",
-                        AccessType.UseEntry.toString(), Permission.Allow, false)).thenReturn(policy);
-        _aclSrv.addIAMPermissionToIAMPolicy(policyId, VirtualMachine.class.getSimpleName(),
-                PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow, false, false);
-        Pair<List<IAMPolicy>, Integer> policyList = new Pair<List<IAMPolicy>, Integer>(policies, 1);
-        List<IAMPolicyPermission> policyPerms = new ArrayList<IAMPolicyPermission>();
-        IAMPolicyPermission perm = new IAMPolicyPermissionVO(policyId, "listVirtualMachines",
-                VirtualMachine.class.getSimpleName(), AccessType.UseEntry.toString(),
-                PermissionScope.RESOURCE.toString(),
-                resId, Permission.Allow, false);
-        policyPerms.add(perm);
-        when(_iamSrv.listIAMPolicies(null, "policy1", callerDomainPath, 0L, 20L)).thenReturn(policyList);
-        when(_iamSrv.listPolicyPermissions(policyId)).thenReturn(policyPerms);
-        ListResponse<IAMPolicyResponse> policyResp = _aclSrv.listIAMPolicies(null, "policy1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
-        IAMPolicyResponse resp = policyResp.getResponses().get(0);
-        Set<IAMPermissionResponse> permList = resp.getPermissionList();
-        assertTrue("Permission list should not be empty", permList != null && permList.size() > 0);
-        IAMPermissionResponse permResp = permList.iterator().next();
-        assertEquals("There should be one permission for listVirtualMachines", "listVirtualMachines", permResp.getAction());
-
-        //remove permission from policy
-        policyPerms.remove(perm);
-        _aclSrv.removeIAMPermissionFromIAMPolicy(policyId, VirtualMachine.class.getSimpleName(),
-                PermissionScope.RESOURCE, resId, "listVirtualMachines");
-        policyResp = _aclSrv.listIAMPolicies(null, "policy1", callerDomainId, 0L, 20L);
-        assertTrue("No. of response items should be one", policyResp.getCount() == 1);
-        resp = policyResp.getResponses().get(0);
-        permList = resp.getPermissionList();
-        assertTrue("Permission list should be empty", permList != null && permList.size() == 0);
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {IAMApiServiceImpl.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
-    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public DomainDao domainDao() {
-            return Mockito.mock(DomainDao.class);
-        }
-
-        @Bean
-        public IAMService iamService() {
-            return Mockito.mock(IAMService.class);
-        }
-
-        @Bean
-        public AccountDao accountDao() {
-            return Mockito.mock(AccountDao.class);
-        }
-
-        @Bean
-        public NetworkDomainDao networkDomainDao() {
-            return Mockito.mock(NetworkDomainDao.class);
-        }
-
-        @Bean
-        public AccountManager accountManager() {
-            return Mockito.mock(AccountManager.class);
-        }
-
-        @Bean
-        public MessageBus messageBus() {
-            return Mockito.mock(MessageBus.class);
-        }
-
-        @Bean
-        public EntityManager entityMgr() {
-            return Mockito.mock(EntityManager.class);
-        }
-
-        @Bean
-        public ApiServerService apiServerService() {
-            return Mockito.mock(ApiServerService.class);
-        }
-
-        public static class Library implements TypeFilter {
-
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-}
diff --git a/services/iam/plugin/test/resources/db.properties b/services/iam/plugin/test/resources/db.properties
deleted file mode 100644
index fc2fb33..0000000
--- a/services/iam/plugin/test/resources/db.properties
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-# management server clustering parameters, change cluster.node.IP to the machine IP address
-# in which the management server is running
-cluster.node.IP=127.0.0.1
-cluster.servlet.port=9090
-region.id=1
-
-# CloudStack database settings
-db.cloud.username=cloud
-db.cloud.password=cloud
-db.root.password=
-db.cloud.host=localhost
-db.cloud.driver=jdbc:mysql
-db.cloud.port=3306
-db.cloud.name=cloud
-
-# CloudStack database tuning parameters
-db.cloud.maxActive=250
-db.cloud.maxIdle=30
-db.cloud.maxWait=10000
-db.cloud.autoReconnect=true
-db.cloud.validationQuery=SELECT 1
-db.cloud.testOnBorrow=true
-db.cloud.testWhileIdle=true
-db.cloud.timeBetweenEvictionRunsMillis=40000
-db.cloud.minEvictableIdleTimeMillis=240000
-db.cloud.poolPreparedStatements=false
-db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096
-
-# usage database settings
-db.usage.username=cloud
-db.usage.password=cloud
-db.usage.host=localhost
-# It's not guaranteed that using a different DB provider than the one from the regular cloud DB will work
-db.usage.driver=jdbc:mysql
-db.usage.port=3306
-db.usage.name=cloud_usage
-
-# usage database tuning parameters
-db.usage.maxActive=100
-db.usage.maxIdle=30
-db.usage.maxWait=10000
-db.usage.autoReconnect=true
-
-# Simulator database settings
-db.simulator.username=cloud
-db.simulator.password=cloud
-db.simulator.host=localhost
-# It's not guaranteed that using a different DB provider than the one from the regular cloud DB will work
-db.simulator.driver=jdbc:mysql
-db.simulator.port=3306
-db.simulator.name=simulator
-db.simulator.maxActive=250
-db.simulator.maxIdle=30
-db.simulator.maxWait=10000
-db.simulator.autoReconnect=true
diff --git a/services/iam/pom.xml b/services/iam/pom.xml
deleted file mode 100644
index 30611c0..0000000
--- a/services/iam/pom.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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>cloudstack-service-iam</artifactId>
-  <name>Apache CloudStack IAM Service</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-services</artifactId>
-    <version>4.7.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
-  <modules>
-    <module>plugin</module>
-    <module>server</module>
-  </modules>
-  <!-- 
-  <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>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>      
-    </dependency>	
-  </dependencies>
-  -->
-  
-</project>
diff --git a/services/iam/server/pom.xml b/services/iam/server/pom.xml
deleted file mode 100644
index 8711fe5..0000000
--- a/services/iam/server/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<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-iam</artifactId>
-  <name>Apache CloudStack IAM - Server</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-iam</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-	<dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>net.sf.ehcache</groupId>
-      <artifactId>ehcache-core</artifactId>
-    </dependency>      
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-	<dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>      
-    </dependency>       
-  </dependencies>
-</project>
diff --git a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml b/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml
deleted file mode 100644
index 1c79836..0000000
--- a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans.xsd
-                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context.xsd"
-                      >                     
-
-    <bean id="IAMGroupDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMGroupDaoImpl" />
-    <bean id="IAMPolicyDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMPolicyDaoImpl" />    
-    <bean id="IAMGroupAccountMapDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDaoImpl" />
-    <bean id="IAMGroupPolicyMapDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDaoImpl" />    
-    <bean id="IAMPolicyPermissionDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDaoImpl" />
-    <bean id="IAMAccountPolicyMapDaoImpl" class="org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDaoImpl" />    
-
-        
-    <bean id="IAMServiceImpl" class="org.apache.cloudstack.iam.server.IAMServiceImpl" >
-      <property name="configParams">
-        <map>
-          <entry key="cache.size" value="5000" />
-          <entry key="cache.time.to.live" value="300" />
-        </map>
-      </property>
-   </bean>
-
-</beans>
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMGroup.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMGroup.java
deleted file mode 100644
index 868d0a0..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMGroup.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.api;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface IAMGroup extends InternalIdentity, Identity {
-
-    String getName();
-
-    String getDescription();
-
-    @Override
-    long getId();
-
-    @Override
-    String getUuid();
-
-    String getPath();
-
-    long getAccountId();
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicy.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicy.java
deleted file mode 100644
index e6daeb1..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicy.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.api;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
-public interface IAMPolicy extends InternalIdentity, Identity {
-
-    String getName();
-
-    String getDescription();
-
-    public enum PolicyType {
-        Static, Dynamic
-    }
-
-    @Override
-    long getId();
-
-    @Override
-    String getUuid();
-
-    String getPath();
-
-    long getAccountId();
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicyPermission.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicyPermission.java
deleted file mode 100644
index b91086f..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMPolicyPermission.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.api;
-
-
-public interface IAMPolicyPermission {
-
-    String getAction();
-
-    long getAclPolicyId();
-
-    String getEntityType();
-
-    String getAccessType();
-
-    String getScope();
-
-    Long getScopeId();
-
-    Permission getPermission();
-
-    public enum Permission {
-        Allow(true), Deny(false);
-
-        boolean result;
-
-        Permission(boolean result) {
-            this.result = result;
-        }
-
-        public boolean isGranted() {
-            return result;
-        }
-    }
-
-    long getId();
-
-    public static final long PERMISSION_SCOPE_ID_CURRENT_CALLER = -1;
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
deleted file mode 100644
index 3a470ee..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.api;
-
-import java.util.List;
-
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-
-import com.cloud.utils.Pair;
-
-public interface IAMService {
-
-    /* IAM group related interfaces */
-    IAMGroup createIAMGroup(String iamGroupName, String description, String path);
-
-    boolean deleteIAMGroup(Long iamGroupId);
-
-    List<IAMGroup> listIAMGroups(long accountId);
-
-    IAMGroup addAccountsToGroup(List<Long> acctIds, Long groupId);
-
-    IAMGroup removeAccountsFromGroup(List<Long> acctIds, Long groupId);
-
-    List<Long> listAccountsByGroup(long groupId);
-
-    Pair<List<IAMGroup>, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize);
-
-    /* IAM Policy related interfaces */
-    IAMPolicy createIAMPolicy(String iamPolicyName, String description, Long parentPolicyId, String path);
-
-    boolean deleteIAMPolicy(long iamPolicyId);
-
-    List<IAMPolicy> listIAMPolicies(long accountId);
-
-    List<IAMPolicy> listIAMPoliciesByGroup(long groupId);
-
-    Pair<List<IAMPolicy>, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize);
-
-    IAMGroup attachIAMPoliciesToGroup(List<Long> policyIds, Long groupId);
-
-    IAMGroup removeIAMPoliciesFromGroup(List<Long> policyIds, Long groupId);
-
-    void attachIAMPolicyToAccounts(Long policyId, List<Long> acctIds);
-
-    void removeIAMPolicyFromAccounts(Long policyId, List<Long> acctIds);
-
-    IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId,
-            String action, String accessType, Permission perm, Boolean recursive);
-
-    IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId,
-            String action);
-
-    void removeIAMPermissionForEntity(final String entityType, final Long entityId);
-
-    IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action);
-
-    IAMPolicy getResourceOwnerPolicy();
-
-    List<IAMPolicyPermission> listPolicyPermissions(long policyId);
-
-    List<IAMPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope, String accessType);
-
-    List<IAMPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action, String entityType);
-
-    boolean isActionAllowedForPolicies(String action, List<IAMPolicy> policies);
-
-    List<Long> getGrantedEntities(long accountId, String action, String scope);
-
-    IAMPolicy resetIAMPolicy(long iamPolicyId);
-
-    List<IAMPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
-            String entityType);
-
-    List<IAMGroup> listParentIAMGroups(long groupId);
-
-    List<IAMPolicy> listRecursiveIAMPoliciesByGroup(long groupId);
-
-    /* Interface used for cache IAM checkAccess result */
-    void addToIAMCache(Object accessKey, Object allowDeny);
-
-    Object getFromIAMCache(Object accessKey);
-
-    void invalidateIAMCache();
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMAccountPolicyMapVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMAccountPolicyMapVO.java
deleted file mode 100644
index 18f085a..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMAccountPolicyMapVO.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_account_policy_map"))
-public class IAMAccountPolicyMapVO {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = "policy_id")
-    private long iamPolicyId;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    public IAMAccountPolicyMapVO() {
-    }
-
-    public IAMAccountPolicyMapVO(long accountId, long iamPolicyId) {
-        this.accountId = accountId;
-        this.iamPolicyId = iamPolicyId;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public long getIamPolicyId() {
-        return iamPolicyId;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupAccountMapVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupAccountMapVO.java
deleted file mode 100644
index dac7d35..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupAccountMapVO.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_group_account_map"))
-public class IAMGroupAccountMapVO {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "group_id")
-    private long aclGroupId;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    public IAMGroupAccountMapVO() {
-    }
-
-    public IAMGroupAccountMapVO(long aclGroupId, long accountId) {
-        this.aclGroupId = aclGroupId;
-        this.accountId = accountId;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public long getAclGroupId() {
-        return aclGroupId;
-    }
-
-
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupPolicyMapVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupPolicyMapVO.java
deleted file mode 100644
index 946d1f7..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupPolicyMapVO.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_group_policy_map"))
-public class IAMGroupPolicyMapVO {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Column(name = "group_id")
-    private long aclGroupId;
-
-    @Column(name = "policy_id")
-    private long aclPolicyId;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    public IAMGroupPolicyMapVO() {
-    }
-
-    public IAMGroupPolicyMapVO(long aclGroupId, long aclPolicyId) {
-        this.aclGroupId = aclGroupId;
-        this.aclPolicyId = aclPolicyId;
-    }
-
-    public long getId() {
-        return id;
-    }
-
-    public long getAclGroupId() {
-        return aclGroupId;
-    }
-
-
-    public long getAclPolicyId() {
-        return aclPolicyId;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupVO.java
deleted file mode 100644
index 80edb89..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMGroupVO.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.iam.api.IAMGroup;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_group"))
-public class IAMGroupVO implements IAMGroup {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "description")
-    private String description;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "path")
-    private String path;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    public IAMGroupVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-
-    public IAMGroupVO(String name, String description) {
-        this.name = name;
-        this.description = description;
-        uuid = UUID.randomUUID().toString();
-        path = "/";
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    @Override
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    @Override
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(long acctId) {
-        accountId = acctId;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyPermissionVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyPermissionVO.java
deleted file mode 100644
index 13d6b81..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyPermissionVO.java
+++ /dev/null
@@ -1,181 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_policy_permission"))
-public class IAMPolicyPermissionVO implements IAMPolicyPermission {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "policy_id")
-    private long aclPolicyId;
-
-    @Column(name = "action")
-    private String action;
-
-    @Column(name = "resource_type")
-    private String entityType;
-
-    @Column(name = "access_type")
-    private String accessType;
-
-    @Column(name = "scope")
-    private String scope;
-
-    @Column(name = "scope_id")
-    private Long scopeId;
-
-    @Column(name = "permission")
-    @Enumerated(value = EnumType.STRING)
-    private Permission permission;
-
-    @Column(name = "recursive")
-    private Boolean recursive;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    public IAMPolicyPermissionVO() {
-
-    }
-
-    public IAMPolicyPermissionVO(long aclPolicyId, String action, String entityType, String accessType, String scope,
-            Long scopeId, Permission permission, Boolean recursive) {
-        this.aclPolicyId = aclPolicyId;
-        this.action = action;
-        this.entityType = entityType;
-        this.accessType = accessType;
-        this.scope = scope;
-        this.scopeId = scopeId;
-        this.permission = permission;
-        this.recursive = recursive;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public long getAclPolicyId() {
-        return aclPolicyId;
-    }
-
-
-    public void setAclPolicyId(long aclPolicyId) {
-        this.aclPolicyId = aclPolicyId;
-    }
-
-    @Override
-    public String getEntityType() {
-        return entityType;
-    }
-
-    @Override
-    public String getAccessType() {
-        return accessType;
-    }
-
-
-    public void setEntityType(String entityType) {
-        this.entityType = entityType;
-    }
-
-    public void setAccessType(String accessType) {
-        this.accessType = accessType;
-    }
-
-    @Override
-    public String getScope() {
-        return scope;
-    }
-
-    public void setScope(String scope) {
-        this.scope = scope;
-    }
-
-
-    @Override
-    public String getAction() {
-        return action;
-    }
-
-    @Override
-    public Long getScopeId() {
-        // TODO
-        // handle special -1 scopeId, current caller domain, account
-        /*
-         * if ( scopeId < 0 ){ Account caller =
-         * CallContext.current().getCallingAccount(); if ( scope ==
-         * PermissionScope.DOMAIN){ return caller.getDomainId(); } else if
-         * (scope == PermissionScope.ACCOUNT) { return caller.getAccountId(); }
-         * }
-         */
-        return scopeId;
-    }
-
-    @Override
-    public Permission getPermission() {
-        return permission;
-    }
-
-    public void setAction(String action) {
-        this.action = action;
-    }
-
-    public void setScopeId(Long scopeId) {
-        this.scopeId = scopeId;
-    }
-
-    public void setPermission(Permission permission) {
-        this.permission = permission;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public Boolean isRecursive() {
-        return recursive;
-    }
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyVO.java
deleted file mode 100644
index 25ebd01..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMPolicyVO.java
+++ /dev/null
@@ -1,138 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.Date;
-import java.util.UUID;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.iam.api.IAMPolicy;
-
-import com.cloud.utils.db.GenericDao;
-
-@Entity
-@Table(name = ("iam_policy"))
-public class IAMPolicyVO implements IAMPolicy {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "description")
-    private String description;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "path")
-    private String path;
-
-    @Column(name = "account_id")
-    private long accountId;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    @Column(name = GenericDao.CREATED_COLUMN)
-    private Date created;
-
-    @Column(name = "policy_type")
-    @Enumerated(value = EnumType.STRING)
-    private IAMPolicy.PolicyType policyType;
-
-    public IAMPolicyVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-
-    public IAMPolicyVO(String name, String description) {
-        this.name = name;
-        this.description = description;
-        uuid = UUID.randomUUID().toString();
-        policyType = IAMPolicy.PolicyType.Static;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    @Override
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
-    @Override
-    public long getAccountId() {
-        return accountId;
-    }
-
-    public void setAccountId(long accountId) {
-        this.accountId = accountId;
-    }
-
-    public IAMPolicy.PolicyType getPolicyType() {
-        return policyType;
-    }
-
-    public void setPolicyType(IAMPolicy.PolicyType policyType) {
-        this.policyType = policyType;
-    }
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
deleted file mode 100644
index 4ae694b..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
+++ /dev/null
@@ -1,904 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.PermissionScope;
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission;
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.api.IAMService;
-import org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMPolicyDao;
-import org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDao;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.Manager;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericSearchBuilder;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
-
-public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
-
-    public static final Logger s_logger = Logger.getLogger(IAMServiceImpl.class);
-    private String _name;
-
-    @Inject
-    IAMPolicyDao _aclPolicyDao;
-
-    @Inject
-    IAMGroupDao _aclGroupDao;
-
-    @Inject
-    EntityManager _entityMgr;
-
-    @Inject
-    IAMGroupPolicyMapDao _aclGroupPolicyMapDao;
-
-    @Inject
-    IAMAccountPolicyMapDao _aclAccountPolicyMapDao;
-
-    @Inject
-    IAMGroupAccountMapDao _aclGroupAccountMapDao;
-
-    @Inject
-    IAMPolicyPermissionDao _policyPermissionDao;
-
-    private Cache _iamCache;
-
-    private void createIAMCache(final Map<String, ? extends Object> params) {
-        final String value = (String)params.get("cache.size");
-
-        if (value != null) {
-            final CacheManager cm = CacheManager.create();
-            final int maxElements = NumbersUtil.parseInt(value, 0);
-            final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300);
-            final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300);
-            _iamCache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle);
-            cm.addCache(_iamCache);
-            s_logger.info("IAM Cache created: " + _iamCache.toString());
-        } else {
-            _iamCache = null;
-        }
-    }
-
-    @Override
-    public void addToIAMCache(Object accessKey, Object allowDeny) {
-        if (_iamCache != null) {
-            try {
-                s_logger.debug("Put IAM access check for " + accessKey + " in cache");
-                _iamCache.put(new Element(accessKey, allowDeny));
-            } catch (final Exception e) {
-                s_logger.debug("Can't put " + accessKey + " to IAM cache", e);
-            }
-        }
-    }
-
-    @Override
-    public void invalidateIAMCache() {
-        //This may need to use event bus to publish to other MS, but event bus now is missing this functionality to handle PublishScope.GLOBAL
-        if (_iamCache != null) {
-            s_logger.debug("Invalidate IAM cache");
-            _iamCache.removeAll();
-        }
-    }
-
-    @Override
-    public Object getFromIAMCache(Object accessKey) {
-        if (_iamCache != null) {
-            final Element element = _iamCache.get(accessKey);
-            return element == null ? null : element.getObjectValue();
-        }
-        return null;
-    }
-
-    @Override
-    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
-        boolean result = super.configure(name, params);
-        // create IAM cache
-        createIAMCache(params);
-        return result;
-    }
-
-    @DB
-    @Override
-    public IAMGroup createIAMGroup(String iamGroupName, String description, String path) {
-        // check if the group is already existing
-        IAMGroup grp = _aclGroupDao.findByName(path, iamGroupName);
-        if (grp != null) {
-            throw new InvalidParameterValueException(
-                    "Unable to create acl group with name " + iamGroupName
-                            + " already exists for path " + path);
-        }
-        IAMGroupVO rvo = new IAMGroupVO(iamGroupName, description);
-        rvo.setPath(path);
-
-        return _aclGroupDao.persist(rvo);
-    }
-
-    @DB
-    @Override
-    public boolean deleteIAMGroup(final Long iamGroupId) {
-        // get the Acl Group entity
-        final IAMGroup grp = _aclGroupDao.findById(iamGroupId);
-        if (grp == null) {
-            throw new InvalidParameterValueException("Unable to find acl group: " + iamGroupId
-                    + "; failed to delete acl group.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // remove this group related entry in acl_group_policy_map
-                List<IAMGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByGroupId(grp.getId());
-                if (groupPolicyMap != null) {
-                    for (IAMGroupPolicyMapVO gr : groupPolicyMap) {
-                        _aclGroupPolicyMapDao.remove(gr.getId());
-                    }
-                }
-
-                // remove this group related entry in acl_group_account table
-                List<IAMGroupAccountMapVO> groupAcctMap = _aclGroupAccountMapDao.listByGroupId(grp.getId());
-                if (groupAcctMap != null) {
-                    for (IAMGroupAccountMapVO grpAcct : groupAcctMap) {
-                        _aclGroupAccountMapDao.remove(grpAcct.getId());
-                    }
-                }
-
-                // remove this group from acl_group table
-                _aclGroupDao.remove(iamGroupId);
-            }
-        });
-
-        invalidateIAMCache();
-        return true;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMGroup> listIAMGroups(long accountId) {
-
-        GenericSearchBuilder<IAMGroupAccountMapVO, Long> groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class);
-        groupSB.selectFields(groupSB.entity().getAclGroupId());
-        groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
-        SearchCriteria<Long> groupSc = groupSB.create();
-        groupSc.setParameters("account", accountId);
-
-        List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null);
-
-        if (groupIds == null || groupIds.isEmpty()) {
-            return new ArrayList<IAMGroup>();
-        }
-        SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
-        sb.and("ids", sb.entity().getId(), Op.IN);
-        SearchCriteria<IAMGroupVO> sc = sb.create();
-        sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()]));
-        @SuppressWarnings("rawtypes")
-        List groups = _aclGroupDao.search(sc, null);
-        return groups;
-    }
-
-    @DB
-    @Override
-    public IAMGroup addAccountsToGroup(final List<Long> acctIds, final Long groupId) {
-        // get the Acl Group entity
-        IAMGroup group = _aclGroupDao.findById(groupId);
-        if (group == null) {
-            throw new InvalidParameterValueException("Unable to find acl group: " + groupId
-                    + "; failed to add accounts to acl group.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_group_account_map table
-                for (Long acctId : acctIds) {
-                    // check account permissions
-                    IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId);
-                    if (grMap == null) {
-                        // not there already
-                        grMap = new IAMGroupAccountMapVO(groupId, acctId);
-                        _aclGroupAccountMapDao.persist(grMap);
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-        return group;
-    }
-
-    @DB
-    @Override
-    public IAMGroup removeAccountsFromGroup(final List<Long> acctIds, final Long groupId) {
-        // get the Acl Group entity
-        IAMGroup group = _aclGroupDao.findById(groupId);
-        if (group == null) {
-            throw new InvalidParameterValueException("Unable to find acl group: " + groupId
-                    + "; failed to remove accounts from acl group.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // remove entries from acl_group_account_map table
-                for (Long acctId : acctIds) {
-                    IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId);
-                    if (grMap != null) {
-                        // not removed yet
-                        _aclGroupAccountMapDao.remove(grMap.getId());
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-        return group;
-    }
-
-    @Override
-    public List<Long> listAccountsByGroup(long groupId) {
-        List<IAMGroupAccountMapVO> grpAcctMap = _aclGroupAccountMapDao.listByGroupId(groupId);
-        if (grpAcctMap == null || grpAcctMap.size() == 0) {
-            return new ArrayList<Long>();
-        }
-
-        List<Long> accts = new ArrayList<Long>();
-        for (IAMGroupAccountMapVO grpAcct : grpAcctMap) {
-            accts.add(grpAcct.getAccountId());
-        }
-        return accts;
-    }
-
-    @Override
-    public Pair<List<IAMGroup>, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize) {
-        if (iamGroupId != null) {
-            IAMGroup group = _aclGroupDao.findById(iamGroupId);
-            if (group == null) {
-                throw new InvalidParameterValueException("Unable to find acl group by id " + iamGroupId);
-            }
-        }
-
-        Filter searchFilter = new Filter(IAMGroupVO.class, "id", true, startIndex, pageSize);
-
-        SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<IAMGroupVO> sc = sb.create();
-
-        if (iamGroupName != null) {
-            sc.setParameters("name", iamGroupName);
-        }
-
-        if (iamGroupId != null) {
-            sc.setParameters("id", iamGroupId);
-        }
-
-        sc.setParameters("path", path + "%");
-
-        Pair<List<IAMGroupVO>, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter);
-        return new Pair<List<IAMGroup>, Integer>(new ArrayList<IAMGroup>(groups.first()), groups.second());
-    }
-
-    @Override
-    public List<IAMGroup> listParentIAMGroups(long groupId) {
-        IAMGroup group = _aclGroupDao.findById(groupId);
-        if (group == null) {
-            throw new InvalidParameterValueException("Unable to find acl group by id " + groupId);
-        }
-
-        String path = group.getPath();
-        List<String> pathList = new ArrayList<String>();
-
-        String[] parts = path.split("/");
-
-        for (String part : parts) {
-            int start = path.indexOf(part);
-            if (start > 0) {
-                String subPath = path.substring(0, start);
-                pathList.add(subPath);
-            }
-        }
-
-        if (pathList.isEmpty()) {
-            return new ArrayList<IAMGroup>();
-        }
-
-        SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
-        sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN);
-
-        SearchCriteria<IAMGroupVO> sc = sb.create();
-        sc.setParameters("paths", pathList.toArray());
-
-        List<IAMGroupVO> groups = _aclGroupDao.search(sc, null);
-
-        return new ArrayList<IAMGroup>(groups);
-
-    }
-
-    @DB
-    @Override
-    public IAMPolicy createIAMPolicy(final String iamPolicyName, final String description, final Long parentPolicyId, final String path) {
-
-        // check if the policy is already existing
-        IAMPolicy ro = _aclPolicyDao.findByName(iamPolicyName);
-        if (ro != null) {
-            throw new InvalidParameterValueException(
-                    "Unable to create acl policy with name " + iamPolicyName
-                            + " already exists");
-        }
-
-        IAMPolicy role = Transaction.execute(new TransactionCallback<IAMPolicy>() {
-            @Override
-            public IAMPolicy doInTransaction(TransactionStatus status) {
-                IAMPolicyVO rvo = new IAMPolicyVO(iamPolicyName, description);
-                rvo.setPath(path);
-
-                IAMPolicy role = _aclPolicyDao.persist(rvo);
-                if (parentPolicyId != null) {
-                    // copy parent role permissions
-                    List<IAMPolicyPermissionVO> perms = _policyPermissionDao.listByPolicy(parentPolicyId);
-                    if (perms != null) {
-                        for (IAMPolicyPermissionVO perm : perms) {
-                            perm.setAclPolicyId(role.getId());
-                            _policyPermissionDao.persist(perm);
-                        }
-                    }
-                }
-                return role;
-            }
-        });
-
-
-        return role;
-    }
-
-    @DB
-    @Override
-    public boolean deleteIAMPolicy(final long iamPolicyId) {
-        // get the Acl Policy entity
-        final IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId
-                    + "; failed to delete acl policy.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // remove this policy related entry in acl_group_policy_map
-                List<IAMGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByPolicyId(policy.getId());
-                if (groupPolicyMap != null) {
-                    for (IAMGroupPolicyMapVO gr : groupPolicyMap) {
-                        _aclGroupPolicyMapDao.remove(gr.getId());
-                    }
-                }
-
-                // remove this policy related entry in acl_account_policy_map table
-                List<IAMAccountPolicyMapVO> policyAcctMap = _aclAccountPolicyMapDao.listByPolicyId(policy.getId());
-                if (policyAcctMap != null) {
-                    for (IAMAccountPolicyMapVO policyAcct : policyAcctMap) {
-                        _aclAccountPolicyMapDao.remove(policyAcct.getId());
-                    }
-                }
-
-                // remove this policy related entry in acl_policy_permission table
-                List<IAMPolicyPermissionVO> policyPermMap = _policyPermissionDao.listByPolicy(policy.getId());
-                if (policyPermMap != null) {
-                    for (IAMPolicyPermissionVO policyPerm : policyPermMap) {
-                        _policyPermissionDao.remove(policyPerm.getId());
-                    }
-                }
-
-                // remove this role from acl_role table
-                _aclPolicyDao.remove(iamPolicyId);
-            }
-        });
-
-        invalidateIAMCache();
-
-        return true;
-    }
-
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicy> listIAMPolicies(long accountId) {
-
-        // static policies of the account
-        SearchBuilder<IAMGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder();
-        groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
-
-        GenericSearchBuilder<IAMGroupPolicyMapVO, Long> policySB = _aclGroupPolicyMapDao.createSearchBuilder(Long.class);
-        policySB.selectFields(policySB.entity().getAclPolicyId());
-        policySB.join("accountgroupjoin", groupSB, groupSB.entity().getAclGroupId(), policySB.entity().getAclGroupId(),
-                JoinType.INNER);
-        policySB.done();
-        SearchCriteria<Long> policySc = policySB.create();
-        policySc.setJoinParameters("accountgroupjoin", "account", accountId);
-
-        List<Long> policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null);
-        // add policies directly attached to the account
-        List<IAMAccountPolicyMapVO> acctPolicies = _aclAccountPolicyMapDao.listByAccountId(accountId);
-        for (IAMAccountPolicyMapVO p : acctPolicies) {
-            policyIds.add(p.getIamPolicyId());
-        }
-        if (policyIds.size() == 0) {
-            return new ArrayList<IAMPolicy>();
-        }
-        SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
-        sb.and("ids", sb.entity().getId(), Op.IN);
-        SearchCriteria<IAMPolicyVO> sc = sb.create();
-        sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()]));
-        @SuppressWarnings("rawtypes")
-        List policies = _aclPolicyDao.customSearch(sc, null);
-
-        return policies;
-
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicy> listIAMPoliciesByGroup(long groupId) {
-        List<IAMGroupPolicyMapVO> policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId);
-        if (policyGrpMap == null || policyGrpMap.size() == 0) {
-            return new ArrayList<IAMPolicy>();
-        }
-
-        List<Long> policyIds = new ArrayList<Long>();
-        for (IAMGroupPolicyMapVO pg : policyGrpMap) {
-            policyIds.add(pg.getAclPolicyId());
-        }
-
-        SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
-        sb.and("ids", sb.entity().getId(), Op.IN);
-        SearchCriteria<IAMPolicyVO> sc = sb.create();
-        sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()]));
-        @SuppressWarnings("rawtypes")
-        List policies = _aclPolicyDao.customSearch(sc, null);
-
-        return policies;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicy> listRecursiveIAMPoliciesByGroup(long groupId) {
-        List<IAMGroupPolicyMapVO> policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId);
-        if (policyGrpMap == null || policyGrpMap.size() == 0) {
-            return new ArrayList<IAMPolicy>();
-        }
-
-        List<Long> policyIds = new ArrayList<Long>();
-        for (IAMGroupPolicyMapVO pg : policyGrpMap) {
-            policyIds.add(pg.getAclPolicyId());
-        }
-
-        SearchBuilder<IAMPolicyPermissionVO> permSb = _policyPermissionDao.createSearchBuilder();
-        permSb.and("isRecursive", permSb.entity().isRecursive(), Op.EQ);
-
-        SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
-        sb.and("ids", sb.entity().getId(), Op.IN);
-        sb.join("recursivePerm", permSb, sb.entity().getId(), permSb.entity().getAclPolicyId(),
-                JoinBuilder.JoinType.INNER);
-
-        SearchCriteria<IAMPolicyVO> sc = sb.create();
-        sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()]));
-        sc.setJoinParameters("recursivePerm", "isRecursive", true);
-
-        @SuppressWarnings("rawtypes")
-        List policies = _aclPolicyDao.customSearch(sc, null);
-
-        return policies;
-    }
-
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Pair<List<IAMPolicy>, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize) {
-
-        if (iamPolicyId != null) {
-            IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId);
-            if (policy == null) {
-                throw new InvalidParameterValueException("Unable to find acl policy by id " + iamPolicyId);
-            }
-        }
-
-        Filter searchFilter = new Filter(IAMPolicyVO.class, "id", true, startIndex, pageSize);
-
-        SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
-        sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
-        sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
-
-        SearchCriteria<IAMPolicyVO> sc = sb.create();
-
-        if (iamPolicyName != null) {
-            sc.setParameters("name", iamPolicyName);
-        }
-
-        if (iamPolicyId != null) {
-            sc.setParameters("id", iamPolicyId);
-        }
-
-        sc.setParameters("path", path + "%");
-
-        Pair<List<IAMPolicyVO>, Integer> policies = _aclPolicyDao.searchAndCount(sc, searchFilter);
-        @SuppressWarnings("rawtypes")
-        List policyList = policies.first();
-        return new Pair<List<IAMPolicy>, Integer>(policyList, policies.second());
-    }
-
-    @DB
-    @Override
-    public IAMGroup attachIAMPoliciesToGroup(final List<Long> policyIds, final Long groupId) {
-        // get the Acl Group entity
-        IAMGroup group = _aclGroupDao.findById(groupId);
-        if (group == null) {
-            throw new InvalidParameterValueException("Unable to find acl group: " + groupId
-                    + "; failed to add roles to acl group.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_group_policy_map table
-                for (Long policyId : policyIds) {
-                    IAMPolicy policy = _aclPolicyDao.findById(policyId);
-                    if (policy == null) {
-                        throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
-                                + "; failed to add policies to acl group.");
-                    }
-
-                    IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId);
-                    if (grMap == null) {
-                        // not there already
-                        grMap = new IAMGroupPolicyMapVO(groupId, policyId);
-                        _aclGroupPolicyMapDao.persist(grMap);
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-        return group;
-    }
-
-    @DB
-    @Override
-    public IAMGroup removeIAMPoliciesFromGroup(final List<Long> policyIds, final Long groupId) {
-        // get the Acl Group entity
-        IAMGroup group = _aclGroupDao.findById(groupId);
-        if (group == null) {
-            throw new InvalidParameterValueException("Unable to find acl group: " + groupId
-                    + "; failed to remove roles from acl group.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_group_role_map table
-                for (Long policyId : policyIds) {
-                    IAMPolicy policy = _aclPolicyDao.findById(policyId);
-                    if (policy == null) {
-                        throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
-                                + "; failed to add policies to acl group.");
-                    }
-
-                    IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId);
-                    if (grMap != null) {
-                        // not removed yet
-                        _aclGroupPolicyMapDao.remove(grMap.getId());
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-        return group;
-    }
-
-
-    @Override
-    public void attachIAMPolicyToAccounts(final Long policyId, final List<Long> acctIds) {
-        IAMPolicy policy = _aclPolicyDao.findById(policyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
-                    + "; failed to add policy to account.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_group_policy_map table
-                for (Long acctId : acctIds) {
-                    IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId);
-                    if (acctMap == null) {
-                        // not there already
-                        acctMap = new IAMAccountPolicyMapVO(acctId, policyId);
-                        _aclAccountPolicyMapDao.persist(acctMap);
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-    }
-
-    @Override
-    public void removeIAMPolicyFromAccounts(final Long policyId, final List<Long> acctIds) {
-        IAMPolicy policy = _aclPolicyDao.findById(policyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
-                    + "; failed to add policy to account.");
-        }
-
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // add entries in acl_group_policy_map table
-                for (Long acctId : acctIds) {
-                    IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId);
-                    if (acctMap != null) {
-                        // exists
-                        _aclAccountPolicyMapDao.remove(acctMap.getId());
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-    }
-
-    @DB
-    @Override
-    public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId,
-            String action, String accessType, Permission perm, Boolean recursive) {
-        // get the Acl Policy entity
-        IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId
-                    + "; failed to add permission to policy.");
-        }
-
-        // add entry in acl_policy_permission table
-        IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope,
-                scopeId, action, perm, accessType);
-        if (permit == null) {
-            // not there already
-            permit = new IAMPolicyPermissionVO(iamPolicyId, action, entityType, accessType, scope, scopeId, perm,
-                    recursive);
-            _policyPermissionDao.persist(permit);
-        }
-
-        invalidateIAMCache();
-        return policy;
-
-    }
-
-    @DB
-    @Override
-    public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId,
-            String action) {
-        // get the Acl Policy entity
-        IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId
-                    + "; failed to revoke permission from policy.");
-        }
-        // remove entry from acl_entity_permission table
-        IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope,
-                scopeId, action, Permission.Allow, null);
-        if (permit != null) {
-            // not removed yet
-            _policyPermissionDao.remove(permit.getId());
-        }
-
-        invalidateIAMCache();
-        return policy;
-    }
-
-    @DB
-    @Override
-    public void removeIAMPermissionForEntity(final String entityType, final Long entityId) {
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                // remove entry from acl_entity_permission table
-                List<IAMPolicyPermissionVO> permitList = _policyPermissionDao.listByEntity(entityType, entityId);
-                for (IAMPolicyPermissionVO permit : permitList) {
-                    long policyId = permit.getAclPolicyId();
-                    _policyPermissionDao.remove(permit.getId());
-
-                    // remove the policy if there are no other permissions
-                    if ((_policyPermissionDao.listByPolicy(policyId)).isEmpty()) {
-                        deleteIAMPolicy(policyId);
-                    }
-                }
-            }
-        });
-
-        invalidateIAMCache();
-    }
-
-    @DB
-    @Override
-    public IAMPolicy resetIAMPolicy(long iamPolicyId) {
-        // get the Acl Policy entity
-        IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId);
-        if (policy == null) {
-            throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId
-                    + "; failed to reset the policy.");
-        }
-
-        SearchBuilder<IAMPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder();
-        sb.and("policyId", sb.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
-        sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
-        sb.done();
-        SearchCriteria<IAMPolicyPermissionVO> permissionSC = sb.create();
-        permissionSC.setParameters("policyId", iamPolicyId);
-        _policyPermissionDao.expunge(permissionSC);
-
-        invalidateIAMCache();
-        return policy;
-    }
-
-    @Override
-    public boolean isActionAllowedForPolicies(String action, List<IAMPolicy> policies) {
-
-        boolean allowed = false;
-
-        if (policies == null || policies.size() == 0) {
-            return allowed;
-        }
-
-        List<Long> policyIds = new ArrayList<Long>();
-        for (IAMPolicy policy : policies) {
-            policyIds.add(policy.getId());
-        }
-
-        SearchBuilder<IAMPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder();
-        sb.and("action", sb.entity().getAction(), Op.EQ);
-        sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN);
-
-        SearchCriteria<IAMPolicyPermissionVO> sc = sb.create();
-        sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()]));
-        sc.setParameters("action", action);
-
-        List<IAMPolicyPermissionVO> permissions = _policyPermissionDao.customSearch(sc, null);
-
-        if (permissions != null && !permissions.isEmpty()) {
-            allowed = true;
-        }
-
-        return allowed;
-    }
-
-
-    @Override
-    public List<Long> getGrantedEntities(long accountId, String action, String scope) {
-        // Get the static Policies of the Caller
-        List<IAMPolicy> policies = listIAMPolicies(accountId);
-        // for each policy, find granted permission within the given scope
-        List<Long> entityIds = new ArrayList<Long>();
-        for (IAMPolicy policy : policies) {
-            List<IAMPolicyPermissionVO> pp = _policyPermissionDao.listByPolicyActionAndScope(policy.getId(), action,
-                    scope, null);
-            if (pp != null) {
-                for (IAMPolicyPermissionVO p : pp) {
-                    if (p.getScopeId() != null) {
-                        entityIds.add(p.getScopeId());
-                    }
-                }
-            }
-        }
-        return entityIds;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<IAMPolicyPermission> listPolicyPermissions(long policyId) {
-        @SuppressWarnings("rawtypes")
-        List pp = _policyPermissionDao.listByPolicy(policyId);
-        return pp;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope,
-            String accessType) {
-        @SuppressWarnings("rawtypes")
-        List pp = _policyPermissionDao.listByPolicyActionAndScope(policyId, action, scope, accessType);
-        return pp;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action,
-            String entityType) {
-        @SuppressWarnings("rawtypes")
-        List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType);
-        return pp;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<IAMPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
-            String entityType) {
-        @SuppressWarnings("rawtypes")
-        List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType);
-        return pp;
-    }
-
-    @Override
-    public IAMPolicy getResourceOwnerPolicy() {
-        return _aclPolicyDao.findByName("RESOURCE_OWNER");
-    }
-
-    // search for policy with only one resource grant permission
-    @Override
-    public IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action) {
-        List<IAMPolicyVO> policyList = _aclPolicyDao.listAll();
-        for (IAMPolicyVO policy : policyList) {
-            List<IAMPolicyPermission> pp = listPolicyPermissions(policy.getId());
-            if (pp != null && pp.size() == 1) {
-                // resource grant policy should only have one ACL permission assigned
-                IAMPolicyPermission permit = pp.get(0);
-                if (permit.getEntityType().equals(entityType) && permit.getScope().equals(PermissionScope.RESOURCE.toString())
-                        && permit.getScopeId().longValue() == entityId.longValue()) {
-                    if (accessType != null && permit.getAccessType().equals(accessType)) {
-                        return policy;
-                    } else if (action != null && permit.getAction().equals(action)) {
-                        return policy;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDao.java
deleted file mode 100644
index 0162589..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDao.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-
-import org.apache.cloudstack.iam.server.IAMAccountPolicyMapVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMAccountPolicyMapDao extends GenericDao<IAMAccountPolicyMapVO, Long> {
-
-    List<IAMAccountPolicyMapVO> listByAccountId(long acctId);
-
-    List<IAMAccountPolicyMapVO> listByPolicyId(long policyId);
-
-    IAMAccountPolicyMapVO findByAccountAndPolicy(long acctId, long policyId);
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDaoImpl.java
deleted file mode 100644
index d74e86f..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMAccountPolicyMapDaoImpl.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.server.IAMAccountPolicyMapVO;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-public class IAMAccountPolicyMapDaoImpl extends GenericDaoBase<IAMAccountPolicyMapVO, Long> implements IAMAccountPolicyMapDao {
-
-    private SearchBuilder<IAMAccountPolicyMapVO> ListByAccountId;
-    private SearchBuilder<IAMAccountPolicyMapVO> ListByPolicyId;
-    private SearchBuilder<IAMAccountPolicyMapVO> findByPolicyAccountId;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        ListByAccountId = createSearchBuilder();
-        ListByAccountId.and("accountId", ListByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
-        ListByAccountId.done();
-
-        ListByPolicyId = createSearchBuilder();
-        ListByPolicyId.and("policyId", ListByPolicyId.entity().getIamPolicyId(), SearchCriteria.Op.EQ);
-        ListByPolicyId.done();
-
-        findByPolicyAccountId = createSearchBuilder();
-        findByPolicyAccountId.and("policyId", findByPolicyAccountId.entity().getIamPolicyId(), SearchCriteria.Op.EQ);
-        findByPolicyAccountId.and("accountId", findByPolicyAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
-        findByPolicyAccountId.done();
-
-        return true;
-    }
-
-    @Override
-    public List<IAMAccountPolicyMapVO> listByAccountId(long acctId) {
-        SearchCriteria<IAMAccountPolicyMapVO> sc = ListByAccountId.create();
-        sc.setParameters("accountId", acctId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMAccountPolicyMapVO> listByPolicyId(long policyId) {
-        SearchCriteria<IAMAccountPolicyMapVO> sc = ListByPolicyId.create();
-        sc.setParameters("policyId", policyId);
-        return listBy(sc);
-    }
-
-    @Override
-    public IAMAccountPolicyMapVO findByAccountAndPolicy(long acctId, long policyId) {
-        SearchCriteria<IAMAccountPolicyMapVO> sc = findByPolicyAccountId.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("accountId", acctId);
-        return findOneBy(sc);
-    }
-}
\ No newline at end of file
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDao.java
deleted file mode 100644
index a94dbaa..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDao.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-
-import org.apache.cloudstack.iam.server.IAMGroupAccountMapVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMGroupAccountMapDao extends GenericDao<IAMGroupAccountMapVO, Long> {
-
-    List<IAMGroupAccountMapVO> listByGroupId(long groupId);
-
-    List<IAMGroupAccountMapVO> listByAccountId(long accountId);
-
-    IAMGroupAccountMapVO findAccountInAdminGroup(long accountId);
-
-    IAMGroupAccountMapVO findByGroupAndAccount(long groupId, long acctId);
-
-    void removeAccountFromGroups(long accountId);
-
-    IAMGroupAccountMapVO findAccountInDomainAdminGroup(long accountId);
-
-    IAMGroupAccountMapVO findAccountInUserGroup(long accountId);
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDaoImpl.java
deleted file mode 100644
index 4bb5d1a..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupAccountMapDaoImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.server.IAMGroupAccountMapVO;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class IAMGroupAccountMapDaoImpl extends GenericDaoBase<IAMGroupAccountMapVO, Long> implements IAMGroupAccountMapDao {
-    private SearchBuilder<IAMGroupAccountMapVO> ListByGroupId;
-    private SearchBuilder<IAMGroupAccountMapVO> ListByAccountId;
-    private SearchBuilder<IAMGroupAccountMapVO> _findByAccountAndGroupId;
-
-    public static final Logger s_logger = Logger.getLogger(IAMGroupAccountMapDaoImpl.class.getName());
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        ListByGroupId = createSearchBuilder();
-        ListByGroupId.and("groupId", ListByGroupId.entity().getAclGroupId(), SearchCriteria.Op.EQ);
-        ListByGroupId.done();
-
-        ListByAccountId = createSearchBuilder();
-        ListByAccountId.and("accountId", ListByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
-        ListByAccountId.done();
-
-        _findByAccountAndGroupId = createSearchBuilder();
-        _findByAccountAndGroupId
-                .and("groupId", _findByAccountAndGroupId.entity().getAclGroupId(), SearchCriteria.Op.EQ);
-        _findByAccountAndGroupId.and("accountId", _findByAccountAndGroupId.entity().getAccountId(),
-                SearchCriteria.Op.EQ);
-        _findByAccountAndGroupId.done();
-
-        return true;
-    }
-
-    @Override
-    public List<IAMGroupAccountMapVO> listByGroupId(long groupId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = ListByGroupId.create();
-        sc.setParameters("groupId", groupId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMGroupAccountMapVO> listByAccountId(long accountId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = ListByAccountId.create();
-        sc.setParameters("accountId", accountId);
-        return listBy(sc);
-    }
-
-    @Override
-    public IAMGroupAccountMapVO findAccountInAdminGroup(long accountId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = _findByAccountAndGroupId.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("groupId", 2);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public IAMGroupAccountMapVO findAccountInDomainAdminGroup(long accountId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = _findByAccountAndGroupId.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("groupId", 3);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public IAMGroupAccountMapVO findAccountInUserGroup(long accountId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = _findByAccountAndGroupId.create();
-        sc.setParameters("accountId", accountId);
-        sc.setParameters("groupId", 1);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public IAMGroupAccountMapVO findByGroupAndAccount(long groupId, long acctId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = _findByAccountAndGroupId.create();
-        sc.setParameters("accountId", acctId);
-        sc.setParameters("groupId", groupId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public void removeAccountFromGroups(long accountId) {
-        SearchCriteria<IAMGroupAccountMapVO> sc = ListByAccountId.create();
-        sc.setParameters("accountId", accountId);
-
-        int rowsRemoved = remove(sc);
-        if (rowsRemoved > 0) {
-            s_logger.debug("Removed account id=" + accountId + " from " + rowsRemoved + " groups");
-        }
-    }
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDao.java
deleted file mode 100644
index 54408a6..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDao.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.server.IAMGroupVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMGroupDao extends GenericDao<IAMGroupVO, Long> {
-
-    IAMGroup findByName(String path, String groupName);
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDaoImpl.java
deleted file mode 100644
index 45be0b3..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupDaoImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.server.IAMGroupVO;
-import org.springframework.stereotype.Component;
-
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class IAMGroupDaoImpl extends GenericDaoBase<IAMGroupVO, Long> implements IAMGroupDao {
-    private SearchBuilder<IAMGroupVO> nameSearch;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        nameSearch = createSearchBuilder();
-        nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ);
-        nameSearch.and("path", nameSearch.entity().getPath(), SearchCriteria.Op.EQ);
-        nameSearch.done();
-
-
-        return true;
-    }
-
-    @Override
-    public IAMGroup findByName(String path, String name) {
-        SearchCriteria<IAMGroupVO> sc = nameSearch.create();
-        sc.setParameters("name", name);
-        if (path != null) {
-            sc.setParameters("path", path);
-        }
-        return findOneBy(sc);
-    }
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDao.java
deleted file mode 100644
index 3f5f232..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDao.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-
-import org.apache.cloudstack.iam.server.IAMGroupPolicyMapVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMGroupPolicyMapDao extends GenericDao<IAMGroupPolicyMapVO, Long> {
-
-    List<IAMGroupPolicyMapVO> listByGroupId(long groupId);
-
-    List<IAMGroupPolicyMapVO> listByPolicyId(long policyId);
-
-    IAMGroupPolicyMapVO findByGroupAndPolicy(long groupId, long policyId);
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDaoImpl.java
deleted file mode 100644
index ac42f04..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMGroupPolicyMapDaoImpl.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.server.IAMGroupPolicyMapVO;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-public class IAMGroupPolicyMapDaoImpl extends GenericDaoBase<IAMGroupPolicyMapVO, Long> implements IAMGroupPolicyMapDao {
-
-    private SearchBuilder<IAMGroupPolicyMapVO> ListByGroupId;
-    private SearchBuilder<IAMGroupPolicyMapVO> ListByPolicyId;
-    private SearchBuilder<IAMGroupPolicyMapVO> findByPolicyGroupId;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        ListByGroupId = createSearchBuilder();
-        ListByGroupId.and("groupId", ListByGroupId.entity().getAclGroupId(), SearchCriteria.Op.EQ);
-        ListByGroupId.done();
-
-        ListByPolicyId = createSearchBuilder();
-        ListByPolicyId.and("policyId", ListByPolicyId.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
-        ListByPolicyId.done();
-
-        findByPolicyGroupId = createSearchBuilder();
-        findByPolicyGroupId.and("policyId", findByPolicyGroupId.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
-        findByPolicyGroupId.and("groupId", findByPolicyGroupId.entity().getAclGroupId(), SearchCriteria.Op.EQ);
-        findByPolicyGroupId.done();
-
-        return true;
-    }
-
-    @Override
-    public List<IAMGroupPolicyMapVO> listByGroupId(long groupId) {
-        SearchCriteria<IAMGroupPolicyMapVO> sc = ListByGroupId.create();
-        sc.setParameters("groupId", groupId);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMGroupPolicyMapVO> listByPolicyId(long policyId) {
-        SearchCriteria<IAMGroupPolicyMapVO> sc = ListByPolicyId.create();
-        sc.setParameters("policyId", policyId);
-        return listBy(sc);
-    }
-
-    @Override
-    public IAMGroupPolicyMapVO findByGroupAndPolicy(long groupId, long policyId) {
-        SearchCriteria<IAMGroupPolicyMapVO> sc = findByPolicyGroupId.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("groupId", groupId);
-        return findOneBy(sc);
-    }
-}
\ No newline at end of file
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDao.java
deleted file mode 100644
index ace7d85..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDao.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.server.IAMPolicyVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMPolicyDao extends GenericDao<IAMPolicyVO, Long> {
-
-    IAMPolicy findByName(String policyName);
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDaoImpl.java
deleted file mode 100644
index 293cf6f..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyDaoImpl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.server.IAMPolicyVO;
-import org.springframework.stereotype.Component;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-@Component
-public class IAMPolicyDaoImpl extends GenericDaoBase<IAMPolicyVO, Long> implements IAMPolicyDao {
-    private SearchBuilder<IAMPolicyVO> nameSearch;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        nameSearch = createSearchBuilder();
-        nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ);
-        // nameSearch.and("domainId", nameSearch.entity().getDomainId(),
-        // SearchCriteria.Op.EQ);
-        nameSearch.done();
-
-
-        return true;
-    }
-
-    @Override
-    public IAMPolicy findByName(String name) {
-        SearchCriteria<IAMPolicyVO> sc = nameSearch.create();
-        sc.setParameters("name", name);
-
-        return findOneBy(sc);
-    }
-
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java
deleted file mode 100644
index ebb4916..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDao.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-import java.util.List;
-
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.server.IAMPolicyPermissionVO;
-
-import com.cloud.utils.db.GenericDao;
-
-public interface IAMPolicyPermissionDao extends GenericDao<IAMPolicyPermissionVO, Long> {
-
-    List<IAMPolicyPermissionVO> listByPolicy(long policyId);
-
-    IAMPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityType, String scope, Long scopeId,
-            String action, Permission perm, String accessType);
-
-    List<IAMPolicyPermissionVO> listByPolicyActionAndScope(long policyId, String action, String scope, String accessType);
-
-    List<IAMPolicyPermissionVO> listByPolicyActionAndEntity(long policyId, String action, String entityType);
-
-    List<IAMPolicyPermissionVO> listByPolicyAccessAndEntity(long policyId, String accessType, String entityType);
-
-    List<IAMPolicyPermissionVO> listByEntity(String entityType, Long entityId);
-}
diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java
deleted file mode 100644
index 44b77d1..0000000
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/IAMPolicyPermissionDaoImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam.server.dao;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission;
-import org.apache.cloudstack.iam.server.IAMPolicyPermissionVO;
-
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-
-public class IAMPolicyPermissionDaoImpl extends GenericDaoBase<IAMPolicyPermissionVO, Long> implements
-        IAMPolicyPermissionDao {
-
-    private SearchBuilder<IAMPolicyPermissionVO> policyIdSearch;
-    private SearchBuilder<IAMPolicyPermissionVO> fullSearch;
-    private SearchBuilder<IAMPolicyPermissionVO> entitySearch;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        policyIdSearch = createSearchBuilder();
-        policyIdSearch.and("policyId", policyIdSearch.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
-        policyIdSearch.done();
-
-        fullSearch = createSearchBuilder();
-        fullSearch.and("policyId", fullSearch.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
-        fullSearch.and("entityType", fullSearch.entity().getEntityType(), SearchCriteria.Op.EQ);
-        fullSearch.and("scope", fullSearch.entity().getScope(), SearchCriteria.Op.EQ);
-        fullSearch.and("scopeId", fullSearch.entity().getScopeId(), SearchCriteria.Op.EQ);
-        fullSearch.and("action", fullSearch.entity().getAction(), SearchCriteria.Op.EQ);
-        fullSearch.and("permission", fullSearch.entity().getPermission(), SearchCriteria.Op.EQ);
-        fullSearch.and("accessType", fullSearch.entity().getAccessType(), SearchCriteria.Op.EQ);
-        fullSearch.done();
-
-        entitySearch = createSearchBuilder();
-        entitySearch.and("entityType", entitySearch.entity().getEntityType(), SearchCriteria.Op.EQ);
-        entitySearch.and("scopeId", entitySearch.entity().getScopeId(), SearchCriteria.Op.EQ);
-        entitySearch.done();
-
-        return true;
-    }
-
-    @Override
-    public List<IAMPolicyPermissionVO> listByPolicy(long policyId) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = policyIdSearch.create();
-        sc.setParameters("policyId", policyId);
-        return listBy(sc);
-    }
-
-    @Override
-    public IAMPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityType, String scope, Long scopeId,
-            String action, Permission perm, String accessType) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = fullSearch.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("entityType", entityType);
-        sc.setParameters("scope", scope);
-        sc.setParameters("scopeId", scopeId);
-        sc.setParameters("action", action);
-        sc.setParameters("permission", perm);
-        if (accessType != null) {
-            // accessType can be optional, used mainly in list apis with
-            // ListEntry and UseEntry distinction
-            sc.setParameters("accessType", accessType);
-        }
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<IAMPolicyPermissionVO> listByPolicyActionAndScope(long policyId, String action, String scope, String accessType) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = fullSearch.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("action", action);
-        sc.setParameters("scope", scope);
-        sc.setParameters("permission", Permission.Allow);
-        if ( accessType != null ){
-            // accessType can be optional, used mainly in list apis with ListEntry and UseEntry distinction
-            sc.setParameters("accessType", accessType);
-        }
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMPolicyPermissionVO> listByPolicyActionAndEntity(long policyId, String action, String entityType) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = fullSearch.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("entityType", entityType);
-        sc.setParameters("action", action);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMPolicyPermissionVO> listByPolicyAccessAndEntity(long policyId, String accessType,
-            String entityType) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = fullSearch.create();
-        sc.setParameters("policyId", policyId);
-        sc.setParameters("entityType", entityType);
-        sc.setParameters("accessType", accessType);
-        return listBy(sc);
-    }
-
-    @Override
-    public List<IAMPolicyPermissionVO> listByEntity(String entityType, Long entityId) {
-        SearchCriteria<IAMPolicyPermissionVO> sc = entitySearch.create();
-        sc.setParameters("entityType", entityType);
-        sc.setParameters("scopeId", entityId);
-        return listBy(sc);
-    }
-
-}
diff --git a/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java b/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
deleted file mode 100644
index 53cfc71..0000000
--- a/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.iam;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.FilterType;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.core.type.filter.TypeFilter;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-
-import org.apache.cloudstack.iam.api.IAMGroup;
-import org.apache.cloudstack.iam.api.IAMPolicy;
-import org.apache.cloudstack.iam.api.IAMService;
-import org.apache.cloudstack.iam.server.IAMGroupVO;
-import org.apache.cloudstack.iam.server.IAMPolicyVO;
-import org.apache.cloudstack.iam.server.IAMServiceImpl;
-import org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupDao;
-import org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDao;
-import org.apache.cloudstack.iam.server.dao.IAMPolicyDao;
-import org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDao;
-import org.apache.cloudstack.test.utils.SpringUtils;
-
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.SearchCriteria;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
-public class IAMServiceUnitTest {
-
-    @Inject
-    IAMService _iamService;
-
-    @Inject
-    IAMPolicyDao _aclPolicyDao;
-
-    @Inject
-    IAMGroupDao _aclGroupDao;
-
-    @Inject
-    EntityManager _entityMgr;
-
-    @Inject
-    IAMGroupPolicyMapDao _aclGroupPolicyMapDao;
-
-    @Inject
-    IAMGroupAccountMapDao _aclGroupAccountMapDao;
-
-    @Inject
-    IAMPolicyPermissionDao _policyPermissionDao;
-
-    @BeforeClass
-    public static void setUpClass() throws ConfigurationException {
-    }
-
-    @Before
-    public void setUp() {
-        ComponentContext.initComponentsLifeCycle();
-        IAMGroupVO group = new IAMGroupVO("group1", "my first group");
-        Mockito.when(_aclGroupDao.persist(Mockito.any(IAMGroupVO.class))).thenReturn(group);
-        List<IAMGroupVO> groups = new ArrayList<IAMGroupVO>();
-        groups.add(group);
-        when(_aclGroupDao.search(Mockito.any(SearchCriteria.class), Mockito.any(com.cloud.utils.db.Filter.class)))
-                .thenReturn(groups);
-
-        IAMPolicyVO policy = new IAMPolicyVO("policy1", "my first policy");
-        Mockito.when(_aclPolicyDao.persist(Mockito.any(IAMPolicyVO.class))).thenReturn(policy);
-
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void createAclGroupTest() {
-        IAMGroup group = _iamService.createIAMGroup("group1", "my first group", "/root/mydomain");
-        assertNotNull("Acl group 'group1' failed to create ", group);
-
-        IAMGroupVO group2 = new IAMGroupVO("group1", "my second group");
-        when(_aclGroupDao.findByName(eq("/root/mydomain"), eq("group1"))).thenReturn(group2);
-
-        IAMGroup group3 = _iamService.createIAMGroup("group1", "my first group", "/root/mydomain");
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void deleteAclGroupInvalidIdTest() {
-        when(_aclGroupDao.findById(20L)).thenReturn(null);
-        _iamService.deleteIAMGroup(20L);
-    }
-
-    @Test
-    public void accountGroupMaptest() {
-        // create group
-        IAMGroupVO group = new IAMGroupVO("group1", "my first group");
-
-        // add account to group
-        List<Long> accountIds = new ArrayList<Long>();
-        accountIds.add(100L);
-        when(_aclGroupDao.findById(20L)).thenReturn(group);
-        _iamService.addAccountsToGroup(accountIds, 20L);
-
-        _iamService.removeAccountsFromGroup(accountIds, 20L);
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void createAclPolicyTest() {
-        IAMPolicy policy = _iamService.createIAMPolicy("policy1", "my first policy", null, "/root/mydomain");
-        assertNotNull("Acl policy 'policy1' failed to create ", policy);
-
-        IAMPolicyVO rvo = new IAMPolicyVO("policy2", "second policy");
-        when(_aclPolicyDao.findByName(eq("policy2"))).thenReturn(rvo);
-
-        _iamService.createIAMPolicy("policy2", "second policy", null, "/root/mydomain");
-    }
-
-    @Test(expected = InvalidParameterValueException.class)
-    public void deleteAclPolicyInvalidIdTest() {
-        when(_aclPolicyDao.findById(34L)).thenReturn(null);
-        _iamService.deleteIAMPolicy(34L);
-    }
-
-    @Configuration
-    @ComponentScan(basePackageClasses = {IAMServiceImpl.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
-    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
-
-        @Bean
-        public IAMPolicyDao aclPolicyDao() {
-            return Mockito.mock(IAMPolicyDao.class);
-        }
-
-        @Bean
-        public IAMGroupDao aclGroupDao() {
-            return Mockito.mock(IAMGroupDao.class);
-        }
-
-        @Bean
-        public EntityManager entityManager() {
-            return Mockito.mock(EntityManager.class);
-        }
-
-        @Bean
-        public IAMGroupPolicyMapDao aclGroupPolicyMapDao() {
-            return Mockito.mock(IAMGroupPolicyMapDao.class);
-        }
-
-        @Bean
-        public IAMGroupAccountMapDao aclGroupAccountMapDao() {
-            return Mockito.mock(IAMGroupAccountMapDao.class);
-        }
-
-        @Bean
-        public IAMAccountPolicyMapDao aclAccountPolicyMapDao() {
-            return Mockito.mock(IAMAccountPolicyMapDao.class);
-        }
-
-        @Bean
-        public IAMPolicyPermissionDao aclPolicyPermissionDao() {
-            return Mockito.mock(IAMPolicyPermissionDao.class);
-        }
-
-        public static class Library implements TypeFilter {
-
-            @Override
-            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
-                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
-                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
-            }
-        }
-    }
-}
diff --git a/services/iam/server/test/resources/db.properties b/services/iam/server/test/resources/db.properties
deleted file mode 100644
index a672d63..0000000
--- a/services/iam/server/test/resources/db.properties
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-# management server clustering parameters, change cluster.node.IP to the machine IP address
-# in which the management server(Tomcat) is running
-cluster.node.IP=127.0.0.1
-cluster.servlet.port=9090
-region.id=1
-
-# CloudStack database settings
-db.cloud.username=cloud
-db.cloud.password=cloud
-db.root.password=
-db.cloud.host=localhost
-db.cloud.driver=jdbc:mysql
-db.cloud.port=3306
-db.cloud.name=cloud
-
-# CloudStack database tuning parameters
-db.cloud.maxActive=250
-db.cloud.maxIdle=30
-db.cloud.maxWait=10000
-db.cloud.autoReconnect=true
-db.cloud.validationQuery=SELECT 1
-db.cloud.testOnBorrow=true
-db.cloud.testWhileIdle=true
-db.cloud.timeBetweenEvictionRunsMillis=40000
-db.cloud.minEvictableIdleTimeMillis=240000
-db.cloud.poolPreparedStatements=false
-db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096
-
-# usage database settings
-db.usage.username=cloud
-db.usage.password=cloud
-db.usage.host=localhost
-# It's not guaranteed that using a different DB provider than the one from the regular cloud DB will work
-db.usage.driver=jdbc:mysql
-db.usage.port=3306
-db.usage.name=cloud_usage
-
-# usage database tuning parameters
-db.usage.maxActive=100
-db.usage.maxIdle=30
-db.usage.maxWait=10000
-db.usage.autoReconnect=true
-
-# Simulator database settings
-db.simulator.username=cloud
-db.simulator.password=cloud
-db.simulator.host=localhost
-# It's not guaranteed that using a different DB provider than the one from the regular cloud DB will work
-db.simulator.driver=jdbc:mysql
-db.simulator.port=3306
-db.simulator.name=simulator
-db.simulator.maxActive=250
-db.simulator.maxIdle=30
-db.simulator.maxWait=10000
-db.simulator.autoReconnect=true
diff --git a/services/pom.xml b/services/pom.xml
index 9845a00..80a217b 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -1,51 +1,50 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>cloudstack-services</artifactId>
-  <name>Apache CloudStack Cloud Services</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>cloudstack-checkstyle</id>
-              <phase>none</phase>
-              <inherited>false</inherited>
-            </execution>
-          </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <modules>
-    <module>console-proxy</module>
-    <module>console-proxy-rdp/rdpconsole</module>
-    <module>secondary-storage</module>
-  </modules>
+<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>cloudstack-services</artifactId>
+    <name>Apache CloudStack Cloud Services</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <module>console-proxy</module>
+        <module>secondary-storage</module>
+    </modules>
 </project>
diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml
index 1c07ef4..ccb04ed 100644
--- a/services/secondary-storage/controller/pom.xml
+++ b/services/secondary-storage/controller/pom.xml
@@ -1,50 +1,51 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-controller-secondary-storage</artifactId>
-  <name>Apache CloudStack Secondary Storage Controller</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-secondary-storage</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <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>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+<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-controller-secondary-storage</artifactId>
+    <name>Apache CloudStack Secondary Storage Controller</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-service-secondary-storage</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <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>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
new file mode 100644
index 0000000..ecfc67e
--- /dev/null
+++ b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
@@ -0,0 +1,184 @@
+// 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.secondarystorage;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Command;
+import com.cloud.configuration.Config;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.secstorage.CommandExecLogVO;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+
+public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
+    private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
+
+    private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
+    private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
+    private int _maxExecutionTimeMs = 1800000;
+
+    @Inject
+    SecondaryStorageVmDao _secStorageVmDao;
+    @Inject
+    CommandExecLogDao _cmdExecLogDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    protected SearchBuilder<CommandExecLogVO> activeCommandSearch;
+    protected SearchBuilder<HostVO> hostSearch;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
+        _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
+
+        int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
+        _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
+
+        hostSearch = _hostDao.createSearchBuilder();
+        hostSearch.and("dc", hostSearch.entity().getDataCenterId(), Op.EQ);
+        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
+
+        activeCommandSearch = _cmdExecLogDao.createSearchBuilder();
+        activeCommandSearch.and("created", activeCommandSearch.entity().getCreated(), Op.GTEQ);
+        activeCommandSearch.join("hostSearch", hostSearch, activeCommandSearch.entity().getInstanceId(), hostSearch.entity().getId(), JoinType.INNER);
+
+        hostSearch.done();
+        activeCommandSearch.done();
+        return true;
+    }
+
+    @Override
+    public Pair<AfterScanAction, Object> scanPool(Long pool) {
+        long dataCenterId = pool.longValue();
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+        }
+
+        Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
+
+        _cmdExecLogDao.expungeExpiredRecords(cutTime);
+
+        boolean suspendAutoLoading = !reserveStandbyCapacity();
+        if (!suspendAutoLoading) {
+            // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
+            String restart = _configDao.getValue("consoleproxy.restart");
+            if (restart != null && restart.equalsIgnoreCase("false")) {
+                s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
+                suspendAutoLoading = true;
+            }
+        }
+
+        List<SecondaryStorageVmVO> alreadyRunning =
+                _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
+        if (alreadyRunning.size() == 0) {
+            s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
+
+            List<SecondaryStorageVmVO> stopped =
+                    _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
+            if (stopped.size() == 0 || !suspendAutoLoading) {
+                List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
+                if (stopping.size() > 0) {
+                    s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
+                    return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+                }
+
+                expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
+            }
+        }
+
+        if (!suspendAutoLoading) {
+            // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
+            if (alreadyRunning.size() == 0) {
+                s_logger.info("Primary secondary storage is not even started, wait until next turn");
+                return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+            }
+
+            alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
+
+            List<CommandExecLogVO> activeCmds = findActiveCommands(dataCenterId, cutTime);
+            if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
+                s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
+                        "), starting a new one");
+                return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
+            }
+        }
+
+        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+    }
+
+    @Override
+    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+
+        // TODO, need performance optimization
+        List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
+        for (Long vmId : vms) {
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
+            HostVO host;
+            host = _resourceMgr.findHostByName(secStorageVm.getHostName());
+            if (host != null && host.getStatus() == Status.Up)
+                return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
+        }
+
+        return null;
+    }
+
+    private List<CommandExecLogVO> findActiveCommands(long dcId, Date cutTime) {
+        SearchCriteria<CommandExecLogVO> sc = activeCommandSearch.create();
+
+        sc.setParameters("created", cutTime);
+        sc.setJoinParameters("hostSearch", "dc", dcId);
+        sc.setJoinParameters("hostSearch", "status", Status.Up);
+
+        return _cmdExecLogDao.search(sc, null);
+    }
+
+    private boolean reserveStandbyCapacity() {
+        String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
+        if (value != null && value.equalsIgnoreCase("true")) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
new file mode 100644
index 0000000..1d3eba8
--- /dev/null
+++ b/services/secondary-storage/controller/src/main/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
@@ -0,0 +1,1516 @@
+// 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.secondarystorage;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.agent.lb.IndirectAgentLB;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ConfigurationManagerImpl;
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.info.RunningHostInfoAgregator;
+import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.StorageNetworkManager;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.ImageStoreDetailsUtil;
+import com.cloud.storage.Storage;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.UploadDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.secondary.SecStorageVmAlertEventArgs;
+import com.cloud.storage.secondary.SecondaryStorageListener;
+import com.cloud.storage.secondary.SecondaryStorageVmAllocator;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.events.SubscriptionMgr;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanHandler;
+import com.cloud.vm.SystemVmLoadScanner;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineGuru;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+//
+// Possible secondary storage vm state transition cases
+//        Creating -> Destroyed
+//        Creating -> Stopped --> Starting -> Running
+//        HA -> Stopped -> Starting -> Running
+//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
+//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
+//        Running -> HA            (if agent lost connection)
+//        Stopped -> Destroyed
+//
+//        Creating state indicates of record creating and IP address allocation are ready, it is a transient
+//         state which will soon be switching towards Running if everything goes well.
+//        Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
+//        Starting state can only be entered from Stopped states
+//
+// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
+// because sooner or later, it will be driven into Running state
+//
+public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
+        ResourceStateAdapter, Configurable {
+    private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
+
+    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
+    // seconds
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
+    // minutes
+
+    private static final int STARTUP_DELAY = 60000; // 60 seconds
+
+    private int _mgmtPort = 8250;
+
+    private List<SecondaryStorageVmAllocator> _ssVmAllocators;
+
+    @Inject
+    protected SecondaryStorageVmDao _secStorageVmDao;
+    @Inject
+    protected StorageNetworkManager _sNwMgr;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private StoragePoolHostDao _storagePoolHostDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    protected NetworkOrchestrationService _networkMgr;
+    @Inject
+    protected NetworkModel _networkModel;
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    private SecondaryStorageListener _listener;
+
+    private ServiceOfferingVO _serviceOffering;
+
+    @Inject
+    protected ConfigurationDao _configDao;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private AccountService _accountMgr;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    protected VMInstanceDao _vmDao;
+    @Inject
+    protected CapacityDao _capacityDao;
+    @Inject
+    UserVmDetailsDao _vmDetailsDao;
+    @Inject
+    protected ResourceManager _resourceMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    protected IPAddressDao _ipAddressDao = null;
+    @Inject
+    protected RulesManager _rulesMgr;
+    @Inject
+    TemplateManager templateMgr;
+    @Inject
+    UploadDao _uploadDao;
+
+    @Inject
+    KeystoreManager _keystoreMgr;
+    @Inject
+    DataStoreManager _dataStoreMgr;
+    @Inject
+    ImageStoreDao _imageStoreDao;
+    @Inject
+    TemplateDataStoreDao _tmplStoreDao;
+    @Inject
+    VolumeDataStoreDao _volumeStoreDao;
+    @Inject
+    private ImageStoreDetailsUtil imageStoreDetailsUtil;
+    @Inject
+    private IndirectAgentLB indirectAgentLB;
+
+    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
+    private int _secStorageVmMtuSize;
+
+    private String _instance;
+    private boolean _useSSlCopy;
+    private String _httpProxy;
+    private String _allowedInternalSites;
+    protected long _nodeId = ManagementServerNode.getManagementServerId();
+
+    private SystemVmLoadScanner<Long> _loadScanner;
+    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
+
+    private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
+
+    static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
+            "Comma separated list of NTP servers to configure in Secondary storage VM", false, ConfigKey.Scope.Global, null);
+
+    public SecondaryStorageManagerImpl() {
+    }
+
+    @Override
+    public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
+        try {
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+            _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
+            return _secStorageVmDao.findById(secStorageVm.getId());
+        } catch (StorageUnavailableException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (Exception e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        }
+    }
+
+    SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
+        if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
+            return _secStorageVmDao.findByInstanceName(ssAHost.getName());
+        }
+        return null;
+    }
+
+    @Override
+    public boolean generateSetupCommand(Long ssHostId) {
+        HostVO cssHost = _hostDao.findById(ssHostId);
+        Long zoneId = cssHost.getDataCenterId();
+        if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
+
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
+            if (secStorageVm == null) {
+                s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
+                return false;
+            }
+
+            List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
+            for (DataStore ssStore : ssStores) {
+                if (!(ssStore.getTO() instanceof NfsTO)) {
+                    continue; // only do this for Nfs
+                }
+                String secUrl = ssStore.getUri();
+                SecStorageSetupCommand setupCmd = null;
+                if (!_useSSlCopy) {
+                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
+                } else {
+                    KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
+                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
+                }
+
+                Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(ssStore.getId());
+                setupCmd.setNfsVersion(nfsVersion);
+
+                //template/volume file upload key
+                String postUploadKey = _configDao.getValue(Config.SSVMPSK.key());
+                setupCmd.setPostUploadKey(postUploadKey);
+
+                Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
+                if (answer != null && answer.getResult()) {
+                    SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
+                    if (an.get_dir() != null) {
+                        // update the parent path in image_store table for this image store
+                        ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
+                        svo.setParent(an.get_dir());
+                        _imageStoreDao.update(ssStore.getId(), svo);
+                    }
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+                    }
+                    return false;
+                }
+            }
+        }
+        /* After removing SecondaryStorage entries from host table, control should never come here!!
+        else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
+            List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
+            String secUrl = cssHost.getStorageUrl();
+            SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
+            for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
+                HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
+                Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
+                if (answer != null && answer.getResult()) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+                    }
+                    return false;
+                }
+            }
+        }
+         */
+        return true;
+    }
+
+    @Override
+    public boolean generateVMSetupCommand(Long ssAHostId) {
+        HostVO ssAHost = _hostDao.findById(ssAHostId);
+        if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
+            return false;
+        }
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+        if (secStorageVm == null) {
+            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+            return false;
+        }
+
+        SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
+        if (_allowedInternalSites != null) {
+            List<String> allowedCidrs = new ArrayList<String>();
+            String[] cidrs = _allowedInternalSites.split(",");
+            for (String cidr : cidrs) {
+                if (NetUtils.isValidIp4Cidr(cidr) || NetUtils.isValidIp4(cidr) || !cidr.startsWith("0.0.0.0")) {
+                    allowedCidrs.add(cidr);
+                }
+            }
+            setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
+        }
+        String copyPasswd = _configDao.getValue("secstorage.copy.password");
+        setupCmd.setCopyPassword(copyPasswd);
+        setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
+        Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
+        if (answer != null && answer.getResult()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
+            }
+            return true;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+        return null;
+    }
+
+    @Override
+    public boolean generateFirewallConfiguration(Long ssAHostId) {
+        if (ssAHostId == null) {
+            return true;
+        }
+        HostVO ssAHost = _hostDao.findById(ssAHostId);
+        SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+
+        if (thisSecStorageVm == null) {
+            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+            return false;
+        }
+
+        String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+        SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
+        thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+        sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
+        List<HostVO> ssvms = sc.list();
+        for (HostVO ssvm : ssvms) {
+            if (ssvm.getId() == ssAHostId) {
+                continue;
+            }
+            Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
+            if (answer != null && answer.getResult()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
+                }
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
+                }
+                return false;
+            }
+        }
+
+        SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
+        for (HostVO ssvm : ssvms) {
+            if (ssvm.getId() == ssAHostId) {
+                continue;
+            }
+            allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+        }
+
+        Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
+        if (answer != null && answer.getResult()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
+            }
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
+            }
+            return false;
+        }
+
+        return true;
+
+    }
+
+    protected boolean isSecondaryStorageVmRequired(long dcId) {
+        DataCenterVO dc = _dcDao.findById(dcId);
+        _dcDao.loadDetails(dc);
+        String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
+        if (ssvmReq != null) {
+            return Boolean.parseBoolean(ssvmReq);
+        }
+        return true;
+    }
+
+    public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
+
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
+            }
+            return null;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
+        }
+
+        Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
+
+        long secStorageVmId = (Long)context.get("secStorageVmId");
+        if (secStorageVmId == 0) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
+            }
+
+            return null;
+        }
+
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+        // SecondaryStorageVmVO secStorageVm =
+        // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
+        if (secStorageVm != null) {
+            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
+            return secStorageVm;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
+                    secStorageVmId);
+            }
+            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
+        }
+        return null;
+    }
+
+    /**
+     * Get the default network for the secondary storage VM, based on the zone it is in. Delegates to
+     * either {@link #getDefaultNetworkForZone(DataCenter)} or {@link #getDefaultNetworkForAdvancedSGZone(DataCenter)},
+     * depending on the zone network type and whether or not security groups are enabled in the zone.
+     * @param dc - The zone (DataCenter) of the secondary storage VM.
+     * @return The default network for use with the secondary storage VM.
+     */
+    protected NetworkVO getDefaultNetworkForCreation(DataCenter dc) {
+        if (dc.getNetworkType() == NetworkType.Advanced) {
+            return getDefaultNetworkForAdvancedZone(dc);
+        } else {
+            return getDefaultNetworkForBasicZone(dc);
+        }
+    }
+
+    /**
+     * Get default network for a secondary storage VM starting up in an advanced zone. If the zone
+     * is security group-enabled, the first network found that supports SG services is returned.
+     * If the zone is not SG-enabled, the Public network is returned.
+     * @param dc - The zone.
+     * @return The selected default network.
+     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
+     */
+    protected NetworkVO getDefaultNetworkForAdvancedZone(DataCenter dc) {
+        if (dc.getNetworkType() != NetworkType.Advanced) {
+            throw new CloudRuntimeException("Zone " + dc + " is not advanced.");
+        }
+
+        if (dc.isSecurityGroupEnabled()) {
+            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dc.getId());
+            if (CollectionUtils.isEmpty(networks)) {
+                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+            }
+
+            return networks.get(0);
+        }
+        else {
+            TrafficType defaultTrafficType = TrafficType.Public;
+            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
+            // api should never allow this situation to happen
+            if (defaultNetworks.size() != 1) {
+                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+            }
+
+            return defaultNetworks.get(0);
+        }
+    }
+
+    /**
+     * Get default network for secondary storage VM for starting up in a basic zone. Basic zones select
+     * the Guest network whether or not the zone is SG-enabled.
+     * @param dc - The zone.
+     * @return The default network according to the zone's network selection rules.
+     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
+     */
+    protected NetworkVO getDefaultNetworkForBasicZone(DataCenter dc) {
+        if (dc.getNetworkType() != NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + dc + "is not basic.");
+        }
+
+        TrafficType defaultTrafficType = TrafficType.Guest;
+        List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
+        // api should never allow this situation to happen
+        if (defaultNetworks.size() != 1) {
+            throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+        }
+
+        return defaultNetworks.get(0);
+    }
+
+    protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
+        DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
+        if (secStore == null) {
+            String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
+        String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
+        Account systemAcct = _accountMgr.getSystemAccount();
+
+        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+
+        NetworkVO defaultNetwork = getDefaultNetworkForCreation(dc);
+
+        List<? extends NetworkOffering> offerings = null;
+        if (_sNwMgr.isStorageIpRangeAvailable(dataCenterId)) {
+            offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork, NetworkOffering.SystemStorageNetwork);
+        } else {
+            offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork);
+        }
+        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(offerings.size() + 1);
+        NicProfile defaultNic = new NicProfile();
+        defaultNic.setDefaultNic(true);
+        defaultNic.setDeviceId(2);
+        try {
+            networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
+                    new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+            for (NetworkOffering offering : offerings) {
+                networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), new ArrayList<NicProfile>());
+            }
+        } catch (ConcurrentOperationException e) {
+            s_logger.info("Unable to setup due to concurrent operation. " + e);
+            return new HashMap<String, Object>();
+        }
+
+        VMTemplateVO template = null;
+        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
+        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
+        if (template == null) {
+            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
+        }
+
+        ServiceOfferingVO serviceOffering = _serviceOffering;
+        if (serviceOffering == null) {
+            serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.ssvmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
+        }
+        SecondaryStorageVmVO secStorageVm =
+            new SecondaryStorageVmVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
+                systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), role, serviceOffering.isOfferHA());
+        secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
+        secStorageVm = _secStorageVmDao.persist(secStorageVm);
+        try {
+            _itMgr.allocate(name, template, serviceOffering, networks, plan, null);
+            secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("InsufficientCapacity", e);
+            throw new CloudRuntimeException("Insufficient capacity exception", e);
+        }
+
+        Map<String, Object> context = new HashMap<String, Object>();
+        context.put("secStorageVmId", secStorageVm.getId());
+        return context;
+    }
+
+    private SecondaryStorageVmAllocator getCurrentAllocator() {
+
+        // for now, only one adapter is supported
+        if (_ssVmAllocators.size() > 0) {
+            return _ssVmAllocators.get(0);
+        }
+
+        return null;
+    }
+
+    protected String connect(String ipAddress, int port) {
+        return null;
+    }
+
+    public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Assign  secondary storage vm from running pool for request from data center : " + dataCenterId);
+        }
+
+        SecondaryStorageVmAllocator allocator = getCurrentAllocator();
+        assert (allocator != null);
+        List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
+        if (runningList != null && runningList.size() > 0) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
+                for (SecondaryStorageVmVO secStorageVm : runningList) {
+                    s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
+                }
+            }
+
+            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
+
+            return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
+            }
+        }
+        return null;
+    }
+
+    public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
+        List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
+        if (l != null && l.size() > 0) {
+            return l.get(0);
+        }
+
+        return null;
+    }
+
+    private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
+        }
+
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " according to zone config");
+            }
+            return;
+        }
+        SecondaryStorageVmVO secStorageVm = null;
+        String errorString = null;
+        try {
+            boolean secStorageVmFromStoppedPool = false;
+            secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
+            if (secStorageVm == null) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
+                }
+
+                if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                    try {
+                        secStorageVm = startNew(dataCenterId, role);
+                        for (UploadVO upload : _uploadDao.listAll()) {
+                            _uploadDao.expunge(upload.getId());
+                        }
+                    } finally {
+                        _allocLock.unlock();
+                    }
+                } else {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Unable to acquire synchronization lock for secondary storage vm allocation, wait for next scan");
+                    }
+                    return;
+                }
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Found a stopped secondary storage vm, starting it. Vm id : " + secStorageVm.getId());
+                }
+                secStorageVmFromStoppedPool = true;
+            }
+
+            if (secStorageVm != null) {
+                long secStorageVmId = secStorageVm.getId();
+                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
+                try {
+                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                        try {
+                            secStorageVm = startSecStorageVm(secStorageVmId);
+                        } finally {
+                            secStorageVmLock.unlock();
+                        }
+                    } else {
+                        if (s_logger.isInfoEnabled()) {
+                            s_logger.info("Unable to acquire synchronization lock for starting secondary storage vm id : " + secStorageVm.getId());
+                        }
+                        return;
+                    }
+                } finally {
+                    secStorageVmLock.releaseRef();
+                }
+
+                if (secStorageVm == null) {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Unable to start secondary storage vm for standby capacity, vm id : " + secStorageVmId + ", will recycle it and start a new one");
+                    }
+
+                    if (secStorageVmFromStoppedPool) {
+                        destroySecStorageVm(secStorageVmId);
+                    }
+                } else {
+                    SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                            new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_UP, dataCenterId, secStorageVmId, secStorageVm, null));
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            errorString = e.getMessage();
+            throw e;
+        } finally {
+            // TODO - For now put all the alerts as creation failure. Distinguish between creation vs start failure in future.
+            // Also add failure reason since startvm masks some of them.
+            if(secStorageVm == null || secStorageVm.getState() != State.Running)
+                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                        new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, 0l, null, errorString));
+        }
+    }
+
+    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
+        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
+        if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
+            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
+            if (template == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                }
+                return false;
+            }
+
+            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+            if (stores.size() < 1) {
+                s_logger.debug("No image store added  in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                return false;
+            }
+
+            DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
+            if (store == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                }
+                return false;
+            }
+
+            boolean useLocalStorage = false;
+            Boolean useLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId);
+            if (useLocal != null) {
+                useLocalStorage = useLocal.booleanValue();
+            }
+            List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !useLocalStorage);
+            if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
+                return true;
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
+                        ", " + ConfigurationManagerImpl.SystemVMUseLocalStorage.key() + ": " + useLocalStorage + ". " +
+                        "If you want to use local storage to start SSVM, need to set " + ConfigurationManagerImpl.SystemVMUseLocalStorage.key() + " to true");
+                }
+            }
+
+        }
+        return false;
+    }
+
+    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
+        Date cutTime = DateUtil.currentGMTTime();
+        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
+
+        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
+        if (l.size() > 0) {
+            for (RunningHostCountInfo countInfo : l) {
+                aggregator.aggregate(countInfo);
+            }
+        }
+
+        return aggregator.getZoneHostInfoMap();
+    }
+
+    @Override
+    public boolean start() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start secondary storage vm manager");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _loadScanner.stop();
+        _allocLock.releaseRef();
+        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+        return true;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start configuring secondary storage vm manager : " + name);
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+        _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
+        String useServiceVM = _configDao.getValue("secondary.storage.vm");
+        boolean _useServiceVM = false;
+        if ("true".equalsIgnoreCase(useServiceVM)) {
+            _useServiceVM = true;
+        }
+
+        String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
+        if ("true".equalsIgnoreCase(sslcopy)) {
+            _useSSlCopy = true;
+        }
+
+        //default to HTTP in case of missing domain
+        String ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
+        if(_useSSlCopy && (ssvmUrlDomain == null || ssvmUrlDomain.isEmpty())){
+            s_logger.warn("Empty secondary storage url domain, explicitly disabling SSL");
+            _useSSlCopy = false;
+        }
+
+        _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
+
+        String value = configs.get("secstorage.capacityscan.interval");
+        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
+
+        _instance = configs.get("instance.name");
+        if (_instance == null) {
+            _instance = "DEFAULT";
+        }
+
+        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
+
+        value = agentMgrConfigs.get("port");
+        _mgmtPort = NumbersUtil.parseInt(value, 8250);
+
+        _listener = new SecondaryStorageListener(this);
+        _agentMgr.registerForHostEvents(_listener, true, false, true);
+
+        _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
+
+        //check if there is a default service offering configured
+        String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
+        if (ssvmSrvcOffIdStr != null) {
+            _serviceOffering = _offeringDao.findByUuid(ssvmSrvcOffIdStr);
+            if (_serviceOffering == null) {
+                try {
+                    _serviceOffering = _offeringDao.findById(Long.parseLong(ssvmSrvcOffIdStr));
+                } catch (NumberFormatException ex) {
+                    s_logger.debug("The system service offering specified by global config is not id, but uuid=" + ssvmSrvcOffIdStr + " for secondary storage vm");
+                }
+            }
+            if (_serviceOffering == null) {
+                s_logger.warn("Can't find system service offering specified by global config, uuid=" + ssvmSrvcOffIdStr + " for secondary storage vm");
+            }
+        }
+
+        if (_serviceOffering == null || !_serviceOffering.isSystemUse()) {
+            int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
+            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
+            List<ServiceOfferingVO> offerings = _offeringDao.createSystemServiceOfferings("System Offering For Secondary Storage VM",
+                    ServiceOffering.ssvmDefaultOffUniqueName, 1, ramSize, cpuFreq, null, null, false, null,
+                    Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.SecondaryStorageVm, true);
+            // this can sometimes happen, if DB is manually or programmatically manipulated
+            if (offerings == null || offerings.size() < 2) {
+                String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
+                s_logger.error(msg);
+                throw new ConfigurationException(msg);
+            }
+        }
+
+        if (_useServiceVM) {
+            _loadScanner = new SystemVmLoadScanner<Long>(this);
+            _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
+        }
+
+        _httpProxy = configs.get(Config.SecStorageProxy.key());
+        if (_httpProxy != null) {
+            boolean valid = true;
+            String errMsg = null;
+            try {
+                URI uri = new URI(_httpProxy);
+                if (!"http".equalsIgnoreCase(uri.getScheme())) {
+                    errMsg = "Only support http proxy";
+                    valid = false;
+                } else if (uri.getHost() == null) {
+                    errMsg = "host can not be null";
+                    valid = false;
+                } else if (uri.getPort() == -1) {
+                    _httpProxy = _httpProxy + ":3128";
+                }
+            } catch (URISyntaxException e) {
+                errMsg = e.toString();
+            } finally {
+                if (!valid) {
+                    s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
+                    throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
+                }
+            }
+        }
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Secondary storage vm Manager is configured.");
+        }
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+        return true;
+    }
+
+    @Override
+    public boolean stopSecStorageVm(long secStorageVmId) {
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+        if (secStorageVm == null) {
+            String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(msg);
+            }
+            return false;
+        }
+        try {
+            if (secStorageVm.getHostId() != null) {
+                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
+                try {
+                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                        try {
+                            _itMgr.stop(secStorageVm.getUuid());
+                            return true;
+                        } finally {
+                            secStorageVmLock.unlock();
+                        }
+                    } else {
+                        String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
+                        s_logger.debug(msg);
+                        return false;
+                    }
+                } finally {
+                    secStorageVmLock.releaseRef();
+                }
+            }
+
+            // vm was already stopped, return true
+            return true;
+        } catch (ResourceUnavailableException e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public boolean rebootSecStorageVm(long secStorageVmId) {
+        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+
+        if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
+            return false;
+        }
+
+        if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
+            final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName(), _itMgr.getExecuteInSequence(secStorageVm.getHypervisorType()));
+            final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
+
+            if (answer != null && answer.getResult()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
+                }
+
+                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                    new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
+
+                return true;
+            } else {
+                String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(msg);
+                }
+                return false;
+            }
+        } else {
+            return startSecStorageVm(secStorageVmId) != null;
+        }
+    }
+
+    @Override
+    public boolean destroySecStorageVm(long vmId) {
+        SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
+
+        try {
+            _itMgr.expunge(ssvm.getUuid());
+            _secStorageVmDao.remove(ssvm.getId());
+            HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
+            if (host != null) {
+                s_logger.debug("Removing host entry for ssvm id=" + vmId);
+                _hostDao.remove(host.getId());
+                //Expire the download urls in the entire zone for templates and volumes.
+                _tmplStoreDao.expireDnldUrlsForZone(host.getDataCenterId());
+                _volumeStoreDao.expireDnldUrlsForZone(host.getDataCenterId());
+                return true;
+            }
+            return false;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to expunge " + ssvm, e);
+            return false;
+        }
+    }
+
+    @Override
+    public void onAgentConnect(Long dcId, StartupCommand cmd) {
+    }
+
+    private String getAllocLockName() {
+        // to improve security, it may be better to return a unique mashed
+        // name(for example MD5 hashed)
+        return "secStorageVm.alloc";
+    }
+
+    private String getSecStorageVmLockName(long id) {
+        return "secStorageVm." + id;
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+        SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
+        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
+        vm.setDetails(details);
+
+        DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
+        assert (secStore != null);
+
+        StringBuilder buf = profile.getBootArgsBuilder();
+        buf.append(" template=domP type=secstorage");
+        buf.append(" host=").append(StringUtils.toCSVList(indirectAgentLB.getManagementServerList(dest.getHost().getId(), dest.getDataCenter().getId(), null)));
+        buf.append(" port=").append(_mgmtPort);
+        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
+
+        buf.append(" zone=").append(dest.getDataCenter().getId());
+        buf.append(" pod=").append(dest.getPod().getId());
+
+        buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
+
+        buf.append(" workers=").append(_configDao.getValue("workers"));
+
+        if (_configDao.isPremium()) {
+            s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
+            buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
+        } else {
+            buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
+        }
+        buf.append(" instance=SecStorage");
+        buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
+        buf.append(" role=").append(vm.getRole().toString());
+        buf.append(" mtu=").append(_secStorageVmMtuSize);
+
+        boolean externalDhcp = false;
+        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
+        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
+            externalDhcp = true;
+        }
+
+        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
+        }
+
+        if (NTPServerConfig.value() != null) {
+            buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
+        }
+
+        for (NicProfile nic : profile.getNics()) {
+            int deviceId = nic.getDeviceId();
+            if (nic.getIPv4Address() == null) {
+                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
+                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
+            } else {
+                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
+                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
+            }
+
+            if (nic.isDefaultNic()) {
+                buf.append(" gateway=").append(nic.getIPv4Gateway());
+            }
+            if (nic.getTrafficType() == TrafficType.Management) {
+                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
+                if (NetUtils.isValidIp4Cidr(mgmt_cidr)) {
+                    buf.append(" mgmtcidr=").append(mgmt_cidr);
+                }
+                buf.append(" localgw=").append(dest.getPod().getGateway());
+                buf.append(" private.network.device=").append("eth").append(deviceId);
+            } else if (nic.getTrafficType() == TrafficType.Public) {
+                buf.append(" public.network.device=").append("eth").append(deviceId);
+            } else if (nic.getTrafficType() == TrafficType.Storage) {
+                buf.append(" storageip=").append(nic.getIPv4Address());
+                buf.append(" storagenetmask=").append(nic.getIPv4Netmask());
+                buf.append(" storagegateway=").append(nic.getIPv4Gateway());
+            }
+        }
+
+        /* External DHCP mode */
+        if (externalDhcp) {
+            buf.append(" bootproto=dhcp");
+        }
+
+        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
+        buf.append(" internaldns1=").append(dc.getInternalDns1());
+        if (dc.getInternalDns2() != null) {
+            buf.append(" internaldns2=").append(dc.getInternalDns2());
+        }
+        buf.append(" dns1=").append(dc.getDns1());
+        if (dc.getDns2() != null) {
+            buf.append(" dns2=").append(dc.getDns2());
+        }
+        Integer nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStore.getId()) : null;
+        buf.append(" nfsVersion=").append(nfsVersion);
+
+        String bootArgs = buf.toString();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+        finalizeCommandsOnStart(cmds, profile);
+
+        SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+        DataCenter dc = dest.getDataCenter();
+        List<NicProfile> nics = profile.getNics();
+        for (NicProfile nic : nics) {
+            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
+                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
+                secVm.setPublicIpAddress(nic.getIPv4Address());
+                secVm.setPublicNetmask(nic.getIPv4Netmask());
+                secVm.setPublicMacAddress(nic.getMacAddress());
+            } else if (nic.getTrafficType() == TrafficType.Management) {
+                secVm.setPrivateIpAddress(nic.getIPv4Address());
+                secVm.setPrivateMacAddress(nic.getMacAddress());
+            }
+        }
+        _secStorageVmDao.update(secVm.getId(), secVm);
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+
+        NicProfile managementNic = null;
+        NicProfile controlNic = null;
+        for (NicProfile nic : profile.getNics()) {
+            if (nic.getTrafficType() == TrafficType.Management) {
+                managementNic = nic;
+            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
+                controlNic = nic;
+            }
+        }
+
+        if (controlNic == null) {
+            if (managementNic == null) {
+                s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
+                return false;
+            }
+            controlNic = managementNic;
+        }
+
+        // verify ssh access on management nic for system vm running on HyperV
+        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
+            controlNic = managementNic;
+        }
+
+        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922);
+        cmds.addCommand("checkSsh", check);
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
+        if (!answer.getResult()) {
+            s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
+            return false;
+        }
+
+        try {
+            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
+            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
+            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
+            if (ipaddr != null && ipaddr.getSystem()) {
+                SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+                // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
+                secVm.setPublicIpAddress(ipaddr.getAddress().addr());
+                _secStorageVmDao.update(secVm.getId(), secVm);
+            }
+        } catch (Exception ex) {
+            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+        //release elastic IP here
+        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
+        if (ip != null && ip.getSystem()) {
+            CallContext ctx = CallContext.current();
+            try {
+                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
+            } catch (Exception ex) {
+                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
+                    ex);
+            }
+        }
+    }
+
+    @Override
+    public void finalizeExpunge(VirtualMachine vm) {
+        SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
+
+        ssvm.setPublicIpAddress(null);
+        ssvm.setPublicMacAddress(null);
+        ssvm.setPublicNetmask(null);
+        _secStorageVmDao.update(ssvm.getId(), ssvm);
+    }
+
+    @Override
+    public String getScanHandlerName() {
+        return "secstorage";
+    }
+
+    @Override
+    public boolean canScan() {
+        return true;
+    }
+
+    @Override
+    public void onScanStart() {
+        _zoneHostInfoMap = getZoneHostInfo();
+    }
+
+    @Override
+    public Long[] getScannablePools() {
+        List<DataCenterVO> zones = _dcDao.listEnabledZones();
+
+        Long[] dcIdList = new Long[zones.size()];
+        int i = 0;
+        for (DataCenterVO dc : zones) {
+            dcIdList[i++] = dc.getId();
+        }
+
+        return dcIdList;
+    }
+
+    @Override
+    public boolean isPoolReadyForScan(Long pool) {
+        // pool is at zone basis
+        long dataCenterId = pool.longValue();
+
+        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
+            }
+            return false;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
+        }
+        return true;
+    }
+
+    @Override
+    public Pair<AfterScanAction, Object> scanPool(Long pool) {
+        long dataCenterId = pool.longValue();
+
+        List<SecondaryStorageVmVO> ssVms =
+            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
+                State.Stopped, State.Stopping);
+        int vmSize = (ssVms == null) ? 0 : ssVms.size();
+        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+        int storeSize = (ssStores == null) ? 0 : ssStores.size();
+        if (storeSize > vmSize) {
+            s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
+            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
+        }
+
+        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
+    }
+
+    @Override
+    public void expandPool(Long pool, Object actionArgs) {
+        long dataCenterId = pool.longValue();
+        allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
+    }
+
+    @Override
+    public void shrinkPool(Long pool, Object actionArgs) {
+    }
+
+    @Override
+    public void onScanEnd() {
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        /* Called when Secondary Storage VM connected */
+        StartupCommand firstCmd = cmd[0];
+        if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
+            return null;
+        }
+
+        host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
+        return host;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
+        // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
+        /*
+        StartupCommand firstCmd = startup[0];
+        if (!(firstCmd instanceof StartupStorageCommand)) {
+            return null;
+        }
+
+        com.cloud.host.Host.Type type = null;
+        StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
+        if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
+            type = ssCmd.getHostType();
+        } else {
+            if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
+                type = Host.Type.SecondaryStorage;
+                if (resource != null && resource instanceof DummySecondaryStorageResource) {
+                    host.setResource(null);
+                }
+            } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
+                type = Host.Type.LocalSecondaryStorage;
+            } else {
+                type = Host.Type.Storage;
+            }
+
+            final Map<String, String> hostDetails = ssCmd.getHostDetails();
+            if (hostDetails != null) {
+                if (details != null) {
+                    details.putAll(hostDetails);
+                } else {
+                    details = hostDetails;
+                }
+            }
+
+            host.setDetails(details);
+            host.setParent(ssCmd.getParent());
+            host.setTotalSize(ssCmd.getTotalSize());
+            host.setHypervisorType(HypervisorType.None);
+            host.setType(type);
+            if (ssCmd.getNfsShare() != null) {
+                host.setStorageUrl(ssCmd.getNfsShare());
+            }
+        }
+         */
+        return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
+        return null;
+    }
+
+    @Override
+    public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (dcId != null) {
+            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        }
+        sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+        return sc.list();
+    }
+
+    @Override
+    public HostVO pickSsvmHost(HostVO ssHost) {
+        if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
+            return ssHost;
+        } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
+            Long dcId = ssHost.getDataCenterId();
+            List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
+            if (ssAHosts == null || ssAHosts.isEmpty()) {
+                return null;
+            }
+            Collections.shuffle(ssAHosts);
+            return ssAHosts.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile profile) {
+
+    }
+
+    public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
+        return _ssVmAllocators;
+    }
+
+    @Inject
+    public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
+        _ssVmAllocators = ssVmAllocators;
+    }
+
+    @Override
+    public String getConfigComponentName() {
+        return SecondaryStorageManagerImpl.class.getSimpleName();
+    }
+
+    @Override
+    public ConfigKey<?>[] getConfigKeys() {
+        return new ConfigKey<?>[] {NTPServerConfig};
+    }
+
+}
diff --git a/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml b/services/secondary-storage/controller/src/main/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
similarity index 100%
rename from services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
rename to services/secondary-storage/controller/src/main/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
deleted file mode 100644
index 357c55e..0000000
--- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,184 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.secondarystorage;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.Command;
-import com.cloud.configuration.Config;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.secstorage.CommandExecLogVO;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-
-public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
-    private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
-
-    private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
-    private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
-    private int _maxExecutionTimeMs = 1800000;
-
-    @Inject
-    SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
-    CommandExecLogDao _cmdExecLogDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    ResourceManager _resourceMgr;
-    protected SearchBuilder<CommandExecLogVO> activeCommandSearch;
-    protected SearchBuilder<HostVO> hostSearch;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
-        _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
-
-        int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
-        _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
-
-        hostSearch = _hostDao.createSearchBuilder();
-        hostSearch.and("dc", hostSearch.entity().getDataCenterId(), Op.EQ);
-        hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ);
-
-        activeCommandSearch = _cmdExecLogDao.createSearchBuilder();
-        activeCommandSearch.and("created", activeCommandSearch.entity().getCreated(), Op.GTEQ);
-        activeCommandSearch.join("hostSearch", hostSearch, activeCommandSearch.entity().getInstanceId(), hostSearch.entity().getId(), JoinType.INNER);
-
-        hostSearch.done();
-        activeCommandSearch.done();
-        return true;
-    }
-
-    @Override
-    public Pair<AfterScanAction, Object> scanPool(Long pool) {
-        long dataCenterId = pool.longValue();
-        if (!isSecondaryStorageVmRequired(dataCenterId)) {
-            return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-        }
-
-        Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
-
-        _cmdExecLogDao.expungeExpiredRecords(cutTime);
-
-        boolean suspendAutoLoading = !reserveStandbyCapacity();
-        if (!suspendAutoLoading) {
-            // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
-            String restart = _configDao.getValue("consoleproxy.restart");
-            if (restart != null && restart.equalsIgnoreCase("false")) {
-                s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
-                suspendAutoLoading = true;
-            }
-        }
-
-        List<SecondaryStorageVmVO> alreadyRunning =
-                _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
-        if (alreadyRunning.size() == 0) {
-            s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
-
-            List<SecondaryStorageVmVO> stopped =
-                    _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
-            if (stopped.size() == 0 || !suspendAutoLoading) {
-                List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
-                if (stopping.size() > 0) {
-                    s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
-                    return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-                }
-
-                expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
-            }
-        }
-
-        if (!suspendAutoLoading) {
-            // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
-            if (alreadyRunning.size() == 0) {
-                s_logger.info("Primary secondary storage is not even started, wait until next turn");
-                return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-            }
-
-            alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
-
-            List<CommandExecLogVO> activeCmds = listActiveCommands(dataCenterId, cutTime);
-            if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
-                s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
-                        "), starting a new one");
-                return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
-            }
-        }
-
-        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-    }
-
-    @Override
-    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
-
-        // TODO, need performance optimization
-        List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
-        for (Long vmId : vms) {
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
-            HostVO host;
-            host = _resourceMgr.findHostByName(secStorageVm.getHostName());
-            if (host != null && host.getStatus() == Status.Up)
-                return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
-        }
-
-        return null;
-    }
-
-    private List<CommandExecLogVO> listActiveCommands(long dcId, Date cutTime) {
-        SearchCriteria<CommandExecLogVO> sc = activeCommandSearch.create();
-
-        sc.setParameters("created", cutTime);
-        sc.setJoinParameters("hostSearch", "dc", dcId);
-        sc.setJoinParameters("hostSearch", "status", Status.Up);
-
-        return _cmdExecLogDao.search(sc, null);
-    }
-
-    private boolean reserveStandbyCapacity() {
-        String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
-        if (value != null && value.equalsIgnoreCase("true")) {
-            return true;
-        }
-
-        return false;
-    }
-}
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
deleted file mode 100644
index 66c436b..0000000
--- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,1516 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.secondarystorage;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.agent.lb.IndirectAgentLB;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManagerImpl;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.info.RunningHostInfoAgregator;
-import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.StorageNetworkManager;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.ImageStoreDetailsUtil;
-import com.cloud.storage.Storage;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.secondary.SecStorageVmAlertEventArgs;
-import com.cloud.storage.secondary.SecondaryStorageListener;
-import com.cloud.storage.secondary.SecondaryStorageVmAllocator;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.events.SubscriptionMgr;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanHandler;
-import com.cloud.vm.SystemVmLoadScanner;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineGuru;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-//
-// Possible secondary storage vm state transition cases
-//        Creating -> Destroyed
-//        Creating -> Stopped --> Starting -> Running
-//        HA -> Stopped -> Starting -> Running
-//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
-//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
-//        Running -> HA            (if agent lost connection)
-//        Stopped -> Destroyed
-//
-//        Creating state indicates of record creating and IP address allocation are ready, it is a transient
-//         state which will soon be switching towards Running if everything goes well.
-//        Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
-//        Starting state can only be entered from Stopped states
-//
-// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
-// because sooner or later, it will be driven into Running state
-//
-public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
-        ResourceStateAdapter, Configurable {
-    private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
-
-    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
-    // seconds
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
-    // minutes
-
-    private static final int STARTUP_DELAY = 60000; // 60 seconds
-
-    private int _mgmtPort = 8250;
-
-    private List<SecondaryStorageVmAllocator> _ssVmAllocators;
-
-    @Inject
-    protected SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
-    protected StorageNetworkManager _sNwMgr;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private StoragePoolHostDao _storagePoolHostDao;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    protected NetworkOrchestrationService _networkMgr;
-    @Inject
-    protected NetworkModel _networkModel;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    private SecondaryStorageListener _listener;
-
-    private ServiceOfferingVO _serviceOffering;
-
-    @Inject
-    protected ConfigurationDao _configDao;
-    @Inject
-    private ServiceOfferingDao _offeringDao;
-    @Inject
-    private AccountService _accountMgr;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    protected VMInstanceDao _vmDao;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    protected IPAddressDao _ipAddressDao = null;
-    @Inject
-    protected RulesManager _rulesMgr;
-    @Inject
-    TemplateManager templateMgr;
-    @Inject
-    UploadDao _uploadDao;
-
-    @Inject
-    KeystoreManager _keystoreMgr;
-    @Inject
-    DataStoreManager _dataStoreMgr;
-    @Inject
-    ImageStoreDao _imageStoreDao;
-    @Inject
-    TemplateDataStoreDao _tmplStoreDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    private ImageStoreDetailsUtil imageStoreDetailsUtil;
-    @Inject
-    private IndirectAgentLB indirectAgentLB;
-
-    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
-    private int _secStorageVmMtuSize;
-
-    private String _instance;
-    private boolean _useSSlCopy;
-    private String _httpProxy;
-    private String _allowedInternalSites;
-    protected long _nodeId = ManagementServerNode.getManagementServerId();
-
-    private SystemVmLoadScanner<Long> _loadScanner;
-    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
-
-    private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
-
-    static final ConfigKey<String> NTPServerConfig = new ConfigKey<String>(String.class, "ntp.server.list", "Advanced", null,
-            "Comma separated list of NTP servers to configure in Secondary storage VM", false, ConfigKey.Scope.Global, null);
-
-    public SecondaryStorageManagerImpl() {
-    }
-
-    @Override
-    public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
-        try {
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-            _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
-            return _secStorageVmDao.findById(secStorageVm.getId());
-        } catch (StorageUnavailableException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (Exception e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        }
-    }
-
-    SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
-        if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
-            return _secStorageVmDao.findByInstanceName(ssAHost.getName());
-        }
-        return null;
-    }
-
-    @Override
-    public boolean generateSetupCommand(Long ssHostId) {
-        HostVO cssHost = _hostDao.findById(ssHostId);
-        Long zoneId = cssHost.getDataCenterId();
-        if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
-
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
-            if (secStorageVm == null) {
-                s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
-                return false;
-            }
-
-            List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
-            for (DataStore ssStore : ssStores) {
-                if (!(ssStore.getTO() instanceof NfsTO)) {
-                    continue; // only do this for Nfs
-                }
-                String secUrl = ssStore.getUri();
-                SecStorageSetupCommand setupCmd = null;
-                if (!_useSSlCopy) {
-                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
-                } else {
-                    KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
-                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
-                }
-
-                Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(ssStore.getId());
-                setupCmd.setNfsVersion(nfsVersion);
-
-                //template/volume file upload key
-                String postUploadKey = _configDao.getValue(Config.SSVMPSK.key());
-                setupCmd.setPostUploadKey(postUploadKey);
-
-                Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
-                if (answer != null && answer.getResult()) {
-                    SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
-                    if (an.get_dir() != null) {
-                        // update the parent path in image_store table for this image store
-                        ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
-                        svo.setParent(an.get_dir());
-                        _imageStoreDao.update(ssStore.getId(), svo);
-                    }
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
-                    }
-                    return false;
-                }
-            }
-        }
-        /* After removing SecondaryStorage entries from host table, control should never come here!!
-        else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
-            List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
-            String secUrl = cssHost.getStorageUrl();
-            SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
-            for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
-                HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
-                Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
-                if (answer != null && answer.getResult()) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
-                    }
-                    return false;
-                }
-            }
-        }
-         */
-        return true;
-    }
-
-    @Override
-    public boolean generateVMSetupCommand(Long ssAHostId) {
-        HostVO ssAHost = _hostDao.findById(ssAHostId);
-        if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
-            return false;
-        }
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
-        if (secStorageVm == null) {
-            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
-            return false;
-        }
-
-        SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
-        if (_allowedInternalSites != null) {
-            List<String> allowedCidrs = new ArrayList<String>();
-            String[] cidrs = _allowedInternalSites.split(",");
-            for (String cidr : cidrs) {
-                if (NetUtils.isValidIp4Cidr(cidr) || NetUtils.isValidIp4(cidr) || !cidr.startsWith("0.0.0.0")) {
-                    allowedCidrs.add(cidr);
-                }
-            }
-            setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
-        }
-        String copyPasswd = _configDao.getValue("secstorage.copy.password");
-        setupCmd.setCopyPassword(copyPasswd);
-        setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
-        Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
-        if (answer != null && answer.getResult()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
-            }
-            return true;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
-        return null;
-    }
-
-    @Override
-    public boolean generateFirewallConfiguration(Long ssAHostId) {
-        if (ssAHostId == null) {
-            return true;
-        }
-        HostVO ssAHost = _hostDao.findById(ssAHostId);
-        SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
-
-        if (thisSecStorageVm == null) {
-            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
-            return false;
-        }
-
-        String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
-        SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
-        thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
-
-        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
-        sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
-        List<HostVO> ssvms = sc.list();
-        for (HostVO ssvm : ssvms) {
-            if (ssvm.getId() == ssAHostId) {
-                continue;
-            }
-            Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
-            if (answer != null && answer.getResult()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
-                }
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
-                }
-                return false;
-            }
-        }
-
-        SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
-        for (HostVO ssvm : ssvms) {
-            if (ssvm.getId() == ssAHostId) {
-                continue;
-            }
-            allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
-        }
-
-        Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
-        if (answer != null && answer.getResult()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
-            }
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
-            }
-            return false;
-        }
-
-        return true;
-
-    }
-
-    protected boolean isSecondaryStorageVmRequired(long dcId) {
-        DataCenterVO dc = _dcDao.findById(dcId);
-        _dcDao.loadDetails(dc);
-        String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
-        if (ssvmReq != null) {
-            return Boolean.parseBoolean(ssvmReq);
-        }
-        return true;
-    }
-
-    public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
-
-        if (!isSecondaryStorageVmRequired(dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
-            }
-            return null;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
-        }
-
-        Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
-
-        long secStorageVmId = (Long)context.get("secStorageVmId");
-        if (secStorageVmId == 0) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
-            }
-
-            return null;
-        }
-
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-        // SecondaryStorageVmVO secStorageVm =
-        // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
-        if (secStorageVm != null) {
-            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
-            return secStorageVm;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
-                    secStorageVmId);
-            }
-            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
-        }
-        return null;
-    }
-
-    /**
-     * Get the default network for the secondary storage VM, based on the zone it is in. Delegates to
-     * either {@link #getDefaultNetworkForZone(DataCenter)} or {@link #getDefaultNetworkForAdvancedSGZone(DataCenter)},
-     * depending on the zone network type and whether or not security groups are enabled in the zone.
-     * @param dc - The zone (DataCenter) of the secondary storage VM.
-     * @return The default network for use with the secondary storage VM.
-     */
-    protected NetworkVO getDefaultNetworkForCreation(DataCenter dc) {
-        if (dc.getNetworkType() == NetworkType.Advanced) {
-            return getDefaultNetworkForAdvancedZone(dc);
-        } else {
-            return getDefaultNetworkForBasicZone(dc);
-        }
-    }
-
-    /**
-     * Get default network for a secondary storage VM starting up in an advanced zone. If the zone
-     * is security group-enabled, the first network found that supports SG services is returned.
-     * If the zone is not SG-enabled, the Public network is returned.
-     * @param dc - The zone.
-     * @return The selected default network.
-     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
-     */
-    protected NetworkVO getDefaultNetworkForAdvancedZone(DataCenter dc) {
-        if (dc.getNetworkType() != NetworkType.Advanced) {
-            throw new CloudRuntimeException("Zone " + dc + " is not advanced.");
-        }
-
-        if (dc.isSecurityGroupEnabled()) {
-            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dc.getId());
-            if (CollectionUtils.isEmpty(networks)) {
-                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
-            }
-
-            return networks.get(0);
-        }
-        else {
-            TrafficType defaultTrafficType = TrafficType.Public;
-            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
-            // api should never allow this situation to happen
-            if (defaultNetworks.size() != 1) {
-                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-            }
-
-            return defaultNetworks.get(0);
-        }
-    }
-
-    /**
-     * Get default network for secondary storage VM for starting up in a basic zone. Basic zones select
-     * the Guest network whether or not the zone is SG-enabled.
-     * @param dc - The zone.
-     * @return The default network according to the zone's network selection rules.
-     * @throws CloudRuntimeException - If the zone is not a valid choice or a network couldn't be found.
-     */
-    protected NetworkVO getDefaultNetworkForBasicZone(DataCenter dc) {
-        if (dc.getNetworkType() != NetworkType.Basic) {
-            throw new CloudRuntimeException("Zone " + dc + "is not basic.");
-        }
-
-        TrafficType defaultTrafficType = TrafficType.Guest;
-        List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dc.getId(), defaultTrafficType);
-        // api should never allow this situation to happen
-        if (defaultNetworks.size() != 1) {
-            throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-        }
-
-        return defaultNetworks.get(0);
-    }
-
-    protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
-        DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
-        if (secStore == null) {
-            String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-
-        long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
-        String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
-        Account systemAcct = _accountMgr.getSystemAccount();
-
-        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-
-        NetworkVO defaultNetwork = getDefaultNetworkForCreation(dc);
-
-        List<? extends NetworkOffering> offerings = null;
-        if (_sNwMgr.isStorageIpRangeAvailable(dataCenterId)) {
-            offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork, NetworkOffering.SystemStorageNetwork);
-        } else {
-            offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork);
-        }
-        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(offerings.size() + 1);
-        NicProfile defaultNic = new NicProfile();
-        defaultNic.setDefaultNic(true);
-        defaultNic.setDeviceId(2);
-        try {
-            networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
-                    new ArrayList<NicProfile>(Arrays.asList(defaultNic)));
-            for (NetworkOffering offering : offerings) {
-                networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), new ArrayList<NicProfile>());
-            }
-        } catch (ConcurrentOperationException e) {
-            s_logger.info("Unable to setup due to concurrent operation. " + e);
-            return new HashMap<String, Object>();
-        }
-
-        VMTemplateVO template = null;
-        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
-        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
-        if (template == null) {
-            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
-        }
-
-        ServiceOfferingVO serviceOffering = _serviceOffering;
-        if (serviceOffering == null) {
-            serviceOffering = _offeringDao.findDefaultSystemOffering(ServiceOffering.ssvmDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
-        }
-        SecondaryStorageVmVO secStorageVm =
-            new SecondaryStorageVmVO(id, serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
-                systemAcct.getDomainId(), systemAcct.getId(), _accountMgr.getSystemUser().getId(), role, serviceOffering.getOfferHA());
-        secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
-        secStorageVm = _secStorageVmDao.persist(secStorageVm);
-        try {
-            _itMgr.allocate(name, template, serviceOffering, networks, plan, null);
-            secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("InsufficientCapacity", e);
-            throw new CloudRuntimeException("Insufficient capacity exception", e);
-        }
-
-        Map<String, Object> context = new HashMap<String, Object>();
-        context.put("secStorageVmId", secStorageVm.getId());
-        return context;
-    }
-
-    private SecondaryStorageVmAllocator getCurrentAllocator() {
-
-        // for now, only one adapter is supported
-        if (_ssVmAllocators.size() > 0) {
-            return _ssVmAllocators.get(0);
-        }
-
-        return null;
-    }
-
-    protected String connect(String ipAddress, int port) {
-        return null;
-    }
-
-    public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Assign  secondary storage vm from running pool for request from data center : " + dataCenterId);
-        }
-
-        SecondaryStorageVmAllocator allocator = getCurrentAllocator();
-        assert (allocator != null);
-        List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
-        if (runningList != null && runningList.size() > 0) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
-                for (SecondaryStorageVmVO secStorageVm : runningList) {
-                    s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
-                }
-            }
-
-            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
-
-            return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
-            }
-        }
-        return null;
-    }
-
-    public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
-        List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
-        if (l != null && l.size() > 0) {
-            return l.get(0);
-        }
-
-        return null;
-    }
-
-    private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
-        }
-
-        if (!isSecondaryStorageVmRequired(dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " according to zone config");
-            }
-            return;
-        }
-        SecondaryStorageVmVO secStorageVm = null;
-        String errorString = null;
-        try {
-            boolean secStorageVmFromStoppedPool = false;
-            secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
-            if (secStorageVm == null) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
-                }
-
-                if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                    try {
-                        secStorageVm = startNew(dataCenterId, role);
-                        for (UploadVO upload : _uploadDao.listAll()) {
-                            _uploadDao.expunge(upload.getId());
-                        }
-                    } finally {
-                        _allocLock.unlock();
-                    }
-                } else {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Unable to acquire synchronization lock for secondary storage vm allocation, wait for next scan");
-                    }
-                    return;
-                }
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Found a stopped secondary storage vm, starting it. Vm id : " + secStorageVm.getId());
-                }
-                secStorageVmFromStoppedPool = true;
-            }
-
-            if (secStorageVm != null) {
-                long secStorageVmId = secStorageVm.getId();
-                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
-                try {
-                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                        try {
-                            secStorageVm = startSecStorageVm(secStorageVmId);
-                        } finally {
-                            secStorageVmLock.unlock();
-                        }
-                    } else {
-                        if (s_logger.isInfoEnabled()) {
-                            s_logger.info("Unable to acquire synchronization lock for starting secondary storage vm id : " + secStorageVm.getId());
-                        }
-                        return;
-                    }
-                } finally {
-                    secStorageVmLock.releaseRef();
-                }
-
-                if (secStorageVm == null) {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Unable to start secondary storage vm for standby capacity, vm id : " + secStorageVmId + ", will recycle it and start a new one");
-                    }
-
-                    if (secStorageVmFromStoppedPool) {
-                        destroySecStorageVm(secStorageVmId);
-                    }
-                } else {
-                    SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                            new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_UP, dataCenterId, secStorageVmId, secStorageVm, null));
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
-                    }
-                }
-            }
-        } catch (Exception e) {
-            errorString = e.getMessage();
-            throw e;
-        } finally {
-            // TODO - For now put all the alerts as creation failure. Distinguish between creation vs start failure in future.
-            // Also add failure reason since startvm masks some of them.
-            if(secStorageVm == null || secStorageVm.getState() != State.Running)
-                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                        new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, 0l, null, errorString));
-        }
-    }
-
-    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
-        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
-        if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
-            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
-            if (template == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                }
-                return false;
-            }
-
-            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
-            if (stores.size() < 1) {
-                s_logger.debug("No image store added  in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                return false;
-            }
-
-            DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
-            if (store == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                }
-                return false;
-            }
-
-            boolean useLocalStorage = false;
-            Boolean useLocal = ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId);
-            if (useLocal != null) {
-                useLocalStorage = useLocal.booleanValue();
-            }
-            List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !useLocalStorage);
-            if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
-                return true;
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
-                        ", " + ConfigurationManagerImpl.SystemVMUseLocalStorage.key() + ": " + useLocalStorage + ". " +
-                        "If you want to use local storage to start SSVM, need to set " + ConfigurationManagerImpl.SystemVMUseLocalStorage.key() + " to true");
-                }
-            }
-
-        }
-        return false;
-    }
-
-    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
-        Date cutTime = DateUtil.currentGMTTime();
-        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
-
-        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
-        if (l.size() > 0) {
-            for (RunningHostCountInfo countInfo : l) {
-                aggregator.aggregate(countInfo);
-            }
-        }
-
-        return aggregator.getZoneHostInfoMap();
-    }
-
-    @Override
-    public boolean start() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start secondary storage vm manager");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _loadScanner.stop();
-        _allocLock.releaseRef();
-        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
-        return true;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start configuring secondary storage vm manager : " + name);
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
-        _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
-        String useServiceVM = _configDao.getValue("secondary.storage.vm");
-        boolean _useServiceVM = false;
-        if ("true".equalsIgnoreCase(useServiceVM)) {
-            _useServiceVM = true;
-        }
-
-        String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
-        if ("true".equalsIgnoreCase(sslcopy)) {
-            _useSSlCopy = true;
-        }
-
-        //default to HTTP in case of missing domain
-        String ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
-        if(_useSSlCopy && (ssvmUrlDomain == null || ssvmUrlDomain.isEmpty())){
-            s_logger.warn("Empty secondary storage url domain, explicitly disabling SSL");
-            _useSSlCopy = false;
-        }
-
-        _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
-
-        String value = configs.get("secstorage.capacityscan.interval");
-        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
-
-        _instance = configs.get("instance.name");
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-
-        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
-
-        value = agentMgrConfigs.get("port");
-        _mgmtPort = NumbersUtil.parseInt(value, 8250);
-
-        _listener = new SecondaryStorageListener(this);
-        _agentMgr.registerForHostEvents(_listener, true, false, true);
-
-        _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
-
-        //check if there is a default service offering configured
-        String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
-        if (ssvmSrvcOffIdStr != null) {
-            _serviceOffering = _offeringDao.findByUuid(ssvmSrvcOffIdStr);
-            if (_serviceOffering == null) {
-                try {
-                    _serviceOffering = _offeringDao.findById(Long.parseLong(ssvmSrvcOffIdStr));
-                } catch (NumberFormatException ex) {
-                    s_logger.debug("The system service offering specified by global config is not id, but uuid=" + ssvmSrvcOffIdStr + " for secondary storage vm");
-                }
-            }
-            if (_serviceOffering == null) {
-                s_logger.warn("Can't find system service offering specified by global config, uuid=" + ssvmSrvcOffIdStr + " for secondary storage vm");
-            }
-        }
-
-        if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
-            int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
-            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
-            List<ServiceOfferingVO> offerings = _offeringDao.createSystemServiceOfferings("System Offering For Secondary Storage VM",
-                    ServiceOffering.ssvmDefaultOffUniqueName, 1, ramSize, cpuFreq, null, null, false, null,
-                    Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.SecondaryStorageVm, true);
-            // this can sometimes happen, if DB is manually or programmatically manipulated
-            if (offerings == null || offerings.size() < 2) {
-                String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
-                s_logger.error(msg);
-                throw new ConfigurationException(msg);
-            }
-        }
-
-        if (_useServiceVM) {
-            _loadScanner = new SystemVmLoadScanner<Long>(this);
-            _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
-        }
-
-        _httpProxy = configs.get(Config.SecStorageProxy.key());
-        if (_httpProxy != null) {
-            boolean valid = true;
-            String errMsg = null;
-            try {
-                URI uri = new URI(_httpProxy);
-                if (!"http".equalsIgnoreCase(uri.getScheme())) {
-                    errMsg = "Only support http proxy";
-                    valid = false;
-                } else if (uri.getHost() == null) {
-                    errMsg = "host can not be null";
-                    valid = false;
-                } else if (uri.getPort() == -1) {
-                    _httpProxy = _httpProxy + ":3128";
-                }
-            } catch (URISyntaxException e) {
-                errMsg = e.toString();
-            } finally {
-                if (!valid) {
-                    s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
-                    throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
-                }
-            }
-        }
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Secondary storage vm Manager is configured.");
-        }
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        return true;
-    }
-
-    @Override
-    public boolean stopSecStorageVm(long secStorageVmId) {
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-        if (secStorageVm == null) {
-            String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(msg);
-            }
-            return false;
-        }
-        try {
-            if (secStorageVm.getHostId() != null) {
-                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
-                try {
-                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                        try {
-                            _itMgr.stop(secStorageVm.getUuid());
-                            return true;
-                        } finally {
-                            secStorageVmLock.unlock();
-                        }
-                    } else {
-                        String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
-                        s_logger.debug(msg);
-                        return false;
-                    }
-                } finally {
-                    secStorageVmLock.releaseRef();
-                }
-            }
-
-            // vm was already stopped, return true
-            return true;
-        } catch (ResourceUnavailableException e) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public boolean rebootSecStorageVm(long secStorageVmId) {
-        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-
-        if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
-            return false;
-        }
-
-        if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
-            final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName(), _itMgr.getExecuteInSequence(secStorageVm.getHypervisorType()));
-            final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
-
-            if (answer != null && answer.getResult()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
-                }
-
-                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                    new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
-
-                return true;
-            } else {
-                String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(msg);
-                }
-                return false;
-            }
-        } else {
-            return startSecStorageVm(secStorageVmId) != null;
-        }
-    }
-
-    @Override
-    public boolean destroySecStorageVm(long vmId) {
-        SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
-
-        try {
-            _itMgr.expunge(ssvm.getUuid());
-            _secStorageVmDao.remove(ssvm.getId());
-            HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
-            if (host != null) {
-                s_logger.debug("Removing host entry for ssvm id=" + vmId);
-                _hostDao.remove(host.getId());
-                //Expire the download urls in the entire zone for templates and volumes.
-                _tmplStoreDao.expireDnldUrlsForZone(host.getDataCenterId());
-                _volumeStoreDao.expireDnldUrlsForZone(host.getDataCenterId());
-                return true;
-            }
-            return false;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to expunge " + ssvm, e);
-            return false;
-        }
-    }
-
-    @Override
-    public void onAgentConnect(Long dcId, StartupCommand cmd) {
-    }
-
-    private String getAllocLockName() {
-        // to improve security, it may be better to return a unique mashed
-        // name(for example MD5 hashed)
-        return "secStorageVm.alloc";
-    }
-
-    private String getSecStorageVmLockName(long id) {
-        return "secStorageVm." + id;
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-        SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
-        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
-        vm.setDetails(details);
-
-        DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
-        assert (secStore != null);
-
-        StringBuilder buf = profile.getBootArgsBuilder();
-        buf.append(" template=domP type=secstorage");
-        buf.append(" host=").append(StringUtils.toCSVList(indirectAgentLB.getManagementServerList(dest.getHost().getId(), dest.getDataCenter().getId(), null)));
-        buf.append(" port=").append(_mgmtPort);
-        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
-
-        buf.append(" zone=").append(dest.getDataCenter().getId());
-        buf.append(" pod=").append(dest.getPod().getId());
-
-        buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
-
-        buf.append(" workers=").append(_configDao.getValue("workers"));
-
-        if (_configDao.isPremium()) {
-            s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
-            buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
-        } else {
-            buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
-        }
-        buf.append(" instance=SecStorage");
-        buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
-        buf.append(" role=").append(vm.getRole().toString());
-        buf.append(" mtu=").append(_secStorageVmMtuSize);
-
-        boolean externalDhcp = false;
-        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
-        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
-            externalDhcp = true;
-        }
-
-        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
-            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
-        }
-
-        if (NTPServerConfig.value() != null) {
-            buf.append(" ntpserverlist=").append(NTPServerConfig.value().replaceAll("\\s+",""));
-        }
-
-        for (NicProfile nic : profile.getNics()) {
-            int deviceId = nic.getDeviceId();
-            if (nic.getIPv4Address() == null) {
-                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
-                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
-            } else {
-                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIPv4Address());
-                buf.append(" eth").append(deviceId).append("mask=").append(nic.getIPv4Netmask());
-            }
-
-            if (nic.isDefaultNic()) {
-                buf.append(" gateway=").append(nic.getIPv4Gateway());
-            }
-            if (nic.getTrafficType() == TrafficType.Management) {
-                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
-                if (NetUtils.isValidIp4Cidr(mgmt_cidr)) {
-                    buf.append(" mgmtcidr=").append(mgmt_cidr);
-                }
-                buf.append(" localgw=").append(dest.getPod().getGateway());
-                buf.append(" private.network.device=").append("eth").append(deviceId);
-            } else if (nic.getTrafficType() == TrafficType.Public) {
-                buf.append(" public.network.device=").append("eth").append(deviceId);
-            } else if (nic.getTrafficType() == TrafficType.Storage) {
-                buf.append(" storageip=").append(nic.getIPv4Address());
-                buf.append(" storagenetmask=").append(nic.getIPv4Netmask());
-                buf.append(" storagegateway=").append(nic.getIPv4Gateway());
-            }
-        }
-
-        /* External DHCP mode */
-        if (externalDhcp) {
-            buf.append(" bootproto=dhcp");
-        }
-
-        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
-        buf.append(" internaldns1=").append(dc.getInternalDns1());
-        if (dc.getInternalDns2() != null) {
-            buf.append(" internaldns2=").append(dc.getInternalDns2());
-        }
-        buf.append(" dns1=").append(dc.getDns1());
-        if (dc.getDns2() != null) {
-            buf.append(" dns2=").append(dc.getDns2());
-        }
-        Integer nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStore.getId()) : null;
-        buf.append(" nfsVersion=").append(nfsVersion);
-
-        String bootArgs = buf.toString();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-        finalizeCommandsOnStart(cmds, profile);
-
-        SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
-        DataCenter dc = dest.getDataCenter();
-        List<NicProfile> nics = profile.getNics();
-        for (NicProfile nic : nics) {
-            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
-                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
-                secVm.setPublicIpAddress(nic.getIPv4Address());
-                secVm.setPublicNetmask(nic.getIPv4Netmask());
-                secVm.setPublicMacAddress(nic.getMacAddress());
-            } else if (nic.getTrafficType() == TrafficType.Management) {
-                secVm.setPrivateIpAddress(nic.getIPv4Address());
-                secVm.setPrivateMacAddress(nic.getMacAddress());
-            }
-        }
-        _secStorageVmDao.update(secVm.getId(), secVm);
-        return true;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-
-        NicProfile managementNic = null;
-        NicProfile controlNic = null;
-        for (NicProfile nic : profile.getNics()) {
-            if (nic.getTrafficType() == TrafficType.Management) {
-                managementNic = nic;
-            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIPv4Address() != null) {
-                controlNic = nic;
-            }
-        }
-
-        if (controlNic == null) {
-            if (managementNic == null) {
-                s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
-                return false;
-            }
-            controlNic = managementNic;
-        }
-
-        // verify ssh access on management nic for system vm running on HyperV
-        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
-            controlNic = managementNic;
-        }
-
-        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIPv4Address(), 3922);
-        cmds.addCommand("checkSsh", check);
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
-        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
-        if (!answer.getResult()) {
-            s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
-            return false;
-        }
-
-        try {
-            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
-            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
-            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
-            if (ipaddr != null && ipaddr.getSystem()) {
-                SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
-                // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
-                secVm.setPublicIpAddress(ipaddr.getAddress().addr());
-                _secStorageVmDao.update(secVm.getId(), secVm);
-            }
-        } catch (Exception ex) {
-            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
-        //release elastic IP here
-        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
-        if (ip != null && ip.getSystem()) {
-            CallContext ctx = CallContext.current();
-            try {
-                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
-                    ex);
-            }
-        }
-    }
-
-    @Override
-    public void finalizeExpunge(VirtualMachine vm) {
-        SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
-
-        ssvm.setPublicIpAddress(null);
-        ssvm.setPublicMacAddress(null);
-        ssvm.setPublicNetmask(null);
-        _secStorageVmDao.update(ssvm.getId(), ssvm);
-    }
-
-    @Override
-    public String getScanHandlerName() {
-        return "secstorage";
-    }
-
-    @Override
-    public boolean canScan() {
-        return true;
-    }
-
-    @Override
-    public void onScanStart() {
-        _zoneHostInfoMap = getZoneHostInfo();
-    }
-
-    @Override
-    public Long[] getScannablePools() {
-        List<DataCenterVO> zones = _dcDao.listEnabledZones();
-
-        Long[] dcIdList = new Long[zones.size()];
-        int i = 0;
-        for (DataCenterVO dc : zones) {
-            dcIdList[i++] = dc.getId();
-        }
-
-        return dcIdList;
-    }
-
-    @Override
-    public boolean isPoolReadyForScan(Long pool) {
-        // pool is at zone basis
-        long dataCenterId = pool.longValue();
-
-        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
-            }
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
-        }
-        return true;
-    }
-
-    @Override
-    public Pair<AfterScanAction, Object> scanPool(Long pool) {
-        long dataCenterId = pool.longValue();
-
-        List<SecondaryStorageVmVO> ssVms =
-            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
-                State.Stopped, State.Stopping);
-        int vmSize = (ssVms == null) ? 0 : ssVms.size();
-        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
-        int storeSize = (ssStores == null) ? 0 : ssStores.size();
-        if (storeSize > vmSize) {
-            s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
-            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
-        }
-
-        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
-    }
-
-    @Override
-    public void expandPool(Long pool, Object actionArgs) {
-        long dataCenterId = pool.longValue();
-        allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
-    }
-
-    @Override
-    public void shrinkPool(Long pool, Object actionArgs) {
-    }
-
-    @Override
-    public void onScanEnd() {
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        /* Called when Secondary Storage VM connected */
-        StartupCommand firstCmd = cmd[0];
-        if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
-            return null;
-        }
-
-        host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
-        return host;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
-        // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
-        /*
-        StartupCommand firstCmd = startup[0];
-        if (!(firstCmd instanceof StartupStorageCommand)) {
-            return null;
-        }
-
-        com.cloud.host.Host.Type type = null;
-        StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
-        if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
-            type = ssCmd.getHostType();
-        } else {
-            if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
-                type = Host.Type.SecondaryStorage;
-                if (resource != null && resource instanceof DummySecondaryStorageResource) {
-                    host.setResource(null);
-                }
-            } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
-                type = Host.Type.LocalSecondaryStorage;
-            } else {
-                type = Host.Type.Storage;
-            }
-
-            final Map<String, String> hostDetails = ssCmd.getHostDetails();
-            if (hostDetails != null) {
-                if (details != null) {
-                    details.putAll(hostDetails);
-                } else {
-                    details = hostDetails;
-                }
-            }
-
-            host.setDetails(details);
-            host.setParent(ssCmd.getParent());
-            host.setTotalSize(ssCmd.getTotalSize());
-            host.setHypervisorType(HypervisorType.None);
-            host.setType(type);
-            if (ssCmd.getNfsShare() != null) {
-                host.setStorageUrl(ssCmd.getNfsShare());
-            }
-        }
-         */
-        return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
-        return null;
-    }
-
-    @Override
-    public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
-        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (dcId != null) {
-            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        }
-        sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
-        return sc.list();
-    }
-
-    @Override
-    public HostVO pickSsvmHost(HostVO ssHost) {
-        if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
-            return ssHost;
-        } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
-            Long dcId = ssHost.getDataCenterId();
-            List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
-            if (ssAHosts == null || ssAHosts.isEmpty()) {
-                return null;
-            }
-            Collections.shuffle(ssAHosts);
-            return ssAHosts.get(0);
-        }
-        return null;
-    }
-
-    @Override
-    public void prepareStop(VirtualMachineProfile profile) {
-
-    }
-
-    public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
-        return _ssVmAllocators;
-    }
-
-    @Inject
-    public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
-        _ssVmAllocators = ssVmAllocators;
-    }
-
-    @Override
-    public String getConfigComponentName() {
-        return SecondaryStorageManagerImpl.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {NTPServerConfig};
-    }
-
-}
diff --git a/services/secondary-storage/controller/test/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerTest.java b/services/secondary-storage/controller/src/test/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerTest.java
similarity index 100%
rename from services/secondary-storage/controller/test/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerTest.java
rename to services/secondary-storage/controller/src/test/java/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerTest.java
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 1966650..03f82d5 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -1,34 +1,50 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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>cloudstack-service-secondary-storage</artifactId>
-  <name>Apache CloudStack Secondary Storage</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-services</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <modules>
-    <module>controller</module>
-    <module>server</module>
-  </modules>
+<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>cloudstack-service-secondary-storage</artifactId>
+    <name>Apache CloudStack Secondary Storage</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-services</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <modules>
+        <module>controller</module>
+        <module>server</module>
+    </modules>
 </project>
diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml
index df778cc..6faded1 100644
--- a/services/secondary-storage/server/pom.xml
+++ b/services/secondary-storage/server/pom.xml
@@ -1,114 +1,115 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-secondary-storage</artifactId>
-  <name>Apache CloudStack Secondary Storage Service</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack-service-secondary-storage</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
+<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-secondary-storage</artifactId>
+    <name>Apache CloudStack Secondary Storage Service</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack-service-secondary-storage</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
     <dependencies>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <!-- required deps for the systemvm -->
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-storage-configdrive</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <!-- dependencies for starting a post upload server on ssvm -->
-      <dependency>
-        <groupId>io.netty</groupId>
-        <artifactId>netty-all</artifactId>
-        <version>4.0.33.Final</version>
-        <scope>compile</scope>
-      </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-         <skipTests>${skipTests}</skipTests>
-         <systemPropertyVariables>
-            <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
-        </systemPropertyVariables>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>java</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <mainClass>com.cloud.agent.AgentShell</mainClass>
-          <arguments>
-            <argument>zone=1</argument>
-            <argument>pod=1</argument>
-            <argument>host=192.168.56.1</argument>
-            <argument>name=192.168.56.10</argument>
-            <argument>eth1ip=192.168.56.10</argument>
-            <argument>eth2ip=192.168.56.10</argument>
-            <argument>guid=SecondaryStorage.1</argument>
-            <argument>secondary.storage.vm=false</argument>
-            <argument>instance=Secondary</argument>
-          </arguments>
-          <systemProperties>
-            <systemProperty>
-              <key>javax.net.ssl.trustStore</key>
-              <value>certs/realhostip.keystore</value>
-              <key>log.home</key>
-              <value>${PWD}/</value>
-            </systemProperty>
-          </systemProperties>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <!-- required deps for the systemvm -->
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-agent</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-storage-configdrive</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- dependencies for starting a post upload server on ssvm -->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.0.33.Final</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>${skipTests}</skipTests>
+                    <systemPropertyVariables>
+                        <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
+                    </systemPropertyVariables>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <mainClass>com.cloud.agent.AgentShell</mainClass>
+                    <arguments>
+                        <argument>zone=1</argument>
+                        <argument>pod=1</argument>
+                        <argument>host=192.168.56.1</argument>
+                        <argument>name=192.168.56.10</argument>
+                        <argument>eth1ip=192.168.56.10</argument>
+                        <argument>eth2ip=192.168.56.10</argument>
+                        <argument>guid=SecondaryStorage.1</argument>
+                        <argument>secondary.storage.vm=false</argument>
+                        <argument>instance=Secondary</argument>
+                    </arguments>
+                    <systemProperties>
+                        <systemProperty>
+                            <key>javax.net.ssl.trustStore</key>
+                            <value>certs/realhostip.keystore</value>
+                            <key>log.home</key>
+                            <value>${PWD}/</value>
+                        </systemProperty>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
new file mode 100644
index 0000000..3dc6775
--- /dev/null
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -0,0 +1,3386 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.storage.resource;
+
+import static com.cloud.network.NetworkModel.METATDATA_DIR;
+import static com.cloud.network.NetworkModel.PASSWORD_DIR;
+import static com.cloud.network.NetworkModel.PASSWORD_FILE;
+import static com.cloud.network.NetworkModel.PUBLIC_KEYS_FILE;
+import static com.cloud.network.NetworkModel.USERDATA_DIR;
+import static com.cloud.network.NetworkModel.USERDATA_FILE;
+import static com.cloud.utils.StringUtils.join;
+import static com.cloud.utils.storage.S3.S3Utils.putFile;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.storage.command.UploadStatusAnswer;
+import org.apache.cloudstack.storage.command.UploadStatusAnswer.UploadStatus;
+import org.apache.cloudstack.storage.command.UploadStatusCommand;
+import org.apache.cloudstack.storage.configdrive.ConfigDrive;
+import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder;
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser;
+import org.apache.cloudstack.storage.template.UploadEntity;
+import org.apache.cloudstack.storage.template.UploadManager;
+import org.apache.cloudstack.storage.template.UploadManagerImpl;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
+import org.apache.cloudstack.utils.security.DigestHelper;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
+import org.joda.time.format.ISODateTimeFormat;
+
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.DeleteSnapshotsDirCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.HandleConfigDriveIsoCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.storage.CreateDatadiskTemplateAnswer;
+import com.cloud.agent.api.storage.CreateDatadiskTemplateCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.GetDatadisksAnswer;
+import com.cloud.agent.api.storage.GetDatadisksCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.ListVolumeAnswer;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.OVFHelper;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DatadiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.configuration.Resource;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.template.OVAProcessor;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.RawImageProcessor;
+import com.cloud.storage.template.TARProcessor;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.utils.EncryptionUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.SwiftUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.storage.S3.S3Utils;
+import com.cloud.vm.SecondaryStorageVm;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.http.HttpContentCompressor;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+
+public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+
+    public static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
+
+    private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
+    private static final String VOLUME_ROOT_DIR = "volumes";
+    private static final String POST_UPLOAD_KEY_LOCATION = "/etc/cloudstack/agent/ms-psk";
+
+    private static final Map<String, String> updatableConfigData = Maps.newHashMap();
+    static {
+
+        updatableConfigData.put(PUBLIC_KEYS_FILE, METATDATA_DIR);
+        updatableConfigData.put(USERDATA_FILE, USERDATA_DIR);
+        updatableConfigData.put(PASSWORD_FILE, PASSWORD_DIR);
+    }
+
+    int _timeout;
+
+    public int getTimeout() {
+        return _timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        _timeout = timeout;
+    }
+
+    String _instance;
+    String _dc;
+    String _pod;
+    String _guid;
+    String _role;
+    Map<String, Object> _params;
+    protected StorageLayer _storage;
+    protected boolean _inSystemVM = false;
+    boolean _sslCopy = false;
+
+    protected DownloadManager _dlMgr;
+    protected UploadManager _upldMgr;
+    private String _configSslScr;
+    private String _configAuthScr;
+    private String _configIpFirewallScr;
+    private String _publicIp;
+    private String _hostname;
+    private String _localgw;
+    private String _eth1mask;
+    private String _eth1ip;
+    private String _storageIp;
+    private String _storageNetmask;
+    private String _storageGateway;
+    private Integer _nfsVersion;
+    private final List<String> nfsIps = new ArrayList<String>();
+    protected String _parent = "/mnt/SecStorage";
+    final private String _tmpltpp = "template.properties";
+    protected String createTemplateFromSnapshotXenScript;
+    private HashMap<String, UploadEntity> uploadEntityStateMap = new HashMap<String, UploadEntity>();
+    private String _ssvmPSK = null;
+    private long processTimeout;
+
+    public void setParentPath(String path) {
+        _parent = path;
+    }
+
+    public String getMountingRoot() {
+        return _parent;
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    public void setInSystemVM(boolean inSystemVM) {
+        _inSystemVM = inSystemVM;
+    }
+
+    /**
+     * Retrieve converted "nfsVersion" value from params
+     * @param params
+     * @return nfsVersion value if exists, null in other case
+     */
+    public static Integer retrieveNfsVersionFromParams(Map<String, Object> params) {
+        Integer nfsVersion = null;
+        if (params.get("nfsVersion") != null) {
+            String nfsVersionParam = (String)params.get("nfsVersion");
+            try {
+                nfsVersion = Integer.valueOf(nfsVersionParam);
+            } catch (NumberFormatException e){
+                s_logger.error("Couldn't cast " + nfsVersionParam + " to integer");
+                return null;
+            }
+        }
+        return nfsVersion;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof DownloadProgressCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+        } else if (cmd instanceof DownloadCommand) {
+            return execute((DownloadCommand)cmd);
+        } else if (cmd instanceof UploadCommand) {
+            return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
+        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
+            return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
+        } else if (cmd instanceof DeleteEntityDownloadURLCommand) {
+            return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
+        } else if (cmd instanceof GetStorageStatsCommand) {
+            return execute((GetStorageStatsCommand)cmd);
+        } else if (cmd instanceof CheckHealthCommand) {
+            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+        } else if (cmd instanceof ReadyCommand) {
+            return new ReadyAnswer((ReadyCommand)cmd);
+        } else if (cmd instanceof SecStorageFirewallCfgCommand) {
+            return execute((SecStorageFirewallCfgCommand)cmd);
+        } else if (cmd instanceof SecStorageVMSetupCommand) {
+            return execute((SecStorageVMSetupCommand)cmd);
+        } else if (cmd instanceof SecStorageSetupCommand) {
+            return execute((SecStorageSetupCommand)cmd);
+        } else if (cmd instanceof ComputeChecksumCommand) {
+            return execute((ComputeChecksumCommand)cmd);
+        } else if (cmd instanceof ListTemplateCommand) {
+            return execute((ListTemplateCommand)cmd);
+        } else if (cmd instanceof ListVolumeCommand) {
+            return execute((ListVolumeCommand)cmd);
+        } else if (cmd instanceof DeleteSnapshotsDirCommand) {
+            return execute((DeleteSnapshotsDirCommand)cmd);
+        } else if (cmd instanceof CopyCommand) {
+            return execute((CopyCommand)cmd);
+        } else if (cmd instanceof DeleteCommand) {
+            return execute((DeleteCommand)cmd);
+        } else if (cmd instanceof UploadStatusCommand) {
+            return execute((UploadStatusCommand)cmd);
+        } else if (cmd instanceof HandleConfigDriveIsoCommand) {
+            return execute((HandleConfigDriveIsoCommand)cmd);
+        } else if (cmd instanceof GetDatadisksCommand) {
+            return execute((GetDatadisksCommand)cmd);
+        } else if (cmd instanceof CreateDatadiskTemplateCommand) {
+            return execute((CreateDatadiskTemplateCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(HandleConfigDriveIsoCommand cmd) {
+        if (cmd.isCreate()) {
+            if (cmd.getIsoData() == null) {
+                return new Answer(cmd, false, "Invalid config drive ISO data");
+            }
+            String nfsMountPoint = getRootDir(cmd.getDestStore().getUrl(), _nfsVersion);
+            File isoFile = new File(nfsMountPoint, cmd.getIsoFile());
+            if(isoFile.exists()) {
+                s_logger.debug("config drive iso already exists");
+            }
+            Path tempDir = null;
+            try {
+                tempDir = java.nio.file.Files.createTempDirectory(ConfigDrive.CONFIGDRIVEDIR);
+                File tmpIsoFile = ConfigDriveBuilder.base64StringToFile(cmd.getIsoData(), tempDir.toAbsolutePath().toString(), cmd.getIsoFile());
+                copyLocalToNfs(tmpIsoFile, new File(cmd.getIsoFile()), cmd.getDestStore());
+            } catch (IOException | ConfigurationException e) {
+                return new Answer(cmd, false, "Failed due to exception: " + e.getMessage());
+            } finally {
+                try {
+                    if (tempDir != null) {
+                        FileUtils.deleteDirectory(tempDir.toFile());
+                    }
+                } catch (IOException ioe) {
+                    s_logger.warn("Failed to delete ConfigDrive temporary directory: " + tempDir.toString(), ioe);
+                }
+            }
+            return new Answer(cmd, true, "Successfully saved config drive at secondary storage");
+        } else {
+            DataStoreTO dstore = cmd.getDestStore();
+            if (dstore instanceof NfsTO) {
+                NfsTO nfs = (NfsTO) dstore;
+                String relativeTemplatePath = new File(cmd.getIsoFile()).getPath();
+                String nfsMountPoint = getRootDir(nfs.getUrl(), _nfsVersion);
+                File tmpltPath = new File(nfsMountPoint, relativeTemplatePath);
+                try {
+                    Files.deleteIfExists(tmpltPath.toPath());
+                } catch (IOException e) {
+                    return new Answer(cmd, e);
+                }
+                return new Answer(cmd);
+            } else {
+                return new Answer(cmd, false, "Not implemented yet");
+            }
+        }
+    }
+
+    protected void copyLocalToNfs(File localFile, File isoFile, DataStoreTO destData) throws ConfigurationException, IOException {
+        String scriptsDir = "scripts/storage/secondary";
+        String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
+        if (createVolScr == null) {
+            throw new ConfigurationException("Unable to find createvolume.sh");
+        }
+        s_logger.info("createvolume.sh found in " + createVolScr);
+
+        int installTimeoutPerGig = 180 * 60 * 1000;
+        int imgSizeGigs = (int) Math.ceil(localFile.length() * 1.0d / (1024 * 1024 * 1024));
+        imgSizeGigs++; // add one just in case
+        long timeout = imgSizeGigs * installTimeoutPerGig;
+
+        Script scr = new Script(createVolScr, timeout, s_logger);
+        scr.add("-s", Integer.toString(imgSizeGigs));
+        scr.add("-n", isoFile.getName());
+        scr.add("-t", getRootDir(destData.getUrl(), _nfsVersion) + "/" + isoFile.getParent());
+        scr.add("-f", localFile.getAbsolutePath());
+        scr.add("-d", "configDrive");
+        String result;
+        result = scr.execute();
+
+        if (result != null) {
+            // script execution failure
+            throw new CloudRuntimeException("Failed to run script " + createVolScr);
+        }
+    }
+
+    public Answer execute(GetDatadisksCommand cmd) {
+        DataTO srcData = cmd.getData();
+        TemplateObjectTO template = (TemplateObjectTO)srcData;
+        DataStoreTO srcStore = srcData.getDataStore();
+        if (!(srcStore instanceof NfsTO)) {
+            return new CreateDatadiskTemplateAnswer("Unsupported protocol");
+        }
+        NfsTO nfsImageStore = (NfsTO)srcStore;
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+        assert (secondaryStorageUrl != null);
+        String templateUrl = secondaryStorageUrl + File.separator + srcData.getPath();
+        Pair<String, String> templateInfo = decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
+        String templateRelativeFolderPath = templateInfo.first();
+
+        try {
+            String secondaryMountPoint = getRootDir(secondaryStorageUrl, _nfsVersion);
+            s_logger.info("MDOVE Secondary storage mount point: " + secondaryMountPoint);
+
+            String srcOVAFileName = getTemplateOnSecStorageFilePath(secondaryMountPoint, templateRelativeFolderPath, templateInfo.second(), ImageFormat.OVA.getFileExtension());
+
+            String ovfFilePath = getOVFFilePath(srcOVAFileName);
+            if (ovfFilePath == null) {
+                Script command = new Script("tar", 0, s_logger);
+                command.add("--no-same-owner");
+                command.add("--no-same-permissions");
+                command.add("-xf", srcOVAFileName);
+                command.setWorkDir(secondaryMountPoint + File.separator + templateRelativeFolderPath);
+                s_logger.info("Executing command: " + command.toString());
+                String result = command.execute();
+                if (result != null) {
+                    String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
+                    s_logger.error(msg);
+                    throw new Exception(msg);
+                }
+
+                command = new Script("chmod", 0, s_logger);
+                command.add("-R");
+                command.add("666", secondaryMountPoint + File.separator + templateRelativeFolderPath);
+                result = command.execute();
+                if (result != null) {
+                    s_logger.warn("Unable to set permissions for " + secondaryMountPoint + File.separator + templateRelativeFolderPath + " due to " + result);
+                }
+            }
+
+            Script command = new Script("cp", _timeout, s_logger);
+            command.add(ovfFilePath);
+            command.add(ovfFilePath + ".orig");
+            String result = command.execute();
+            if (result != null) {
+                String msg = "Unable to rename original OVF, error msg: " + result;
+                s_logger.error(msg);
+            }
+
+            s_logger.debug("Reading OVF " + ovfFilePath + " to retrive the number of disks present in OVA");
+            OVFHelper ovfHelper = new OVFHelper();
+
+            List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfo(ovfFilePath);
+            return new GetDatadisksAnswer(disks);
+        } catch (Exception e) {
+            String msg = "Get Datadisk Template Count failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new GetDatadisksAnswer(msg);
+        }
+    }
+
+    public Answer execute(CreateDatadiskTemplateCommand cmd) {
+        TemplateObjectTO diskTemplate = new TemplateObjectTO();
+        TemplateObjectTO dataDiskTemplate = (TemplateObjectTO)cmd.getDataDiskTemplate();
+        DataStoreTO dataStore = dataDiskTemplate.getDataStore();
+        if (!(dataStore instanceof NfsTO)) {
+            return new CreateDatadiskTemplateAnswer("Unsupported protocol");
+        }
+        NfsTO nfsImageStore = (NfsTO)dataStore;
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+        assert (secondaryStorageUrl != null);
+
+        try {
+            String secondaryMountPoint = getRootDir(secondaryStorageUrl, _nfsVersion);
+
+            long templateId = dataDiskTemplate.getId();
+            String templateUniqueName = dataDiskTemplate.getUniqueName();
+            String origDisk = cmd.getPath();
+            long virtualSize = dataDiskTemplate.getSize();
+            String diskName = origDisk.substring((origDisk.lastIndexOf(File.separator)) + 1);
+            long physicalSize = new File(origDisk).length();
+            String newTmplDir = getTemplateRelativeDirInSecStorage(dataDiskTemplate.getAccountId(), dataDiskTemplate.getId());
+            String newTmplDirAbsolute = secondaryMountPoint + File.separator + newTmplDir;
+
+            String ovfFilePath = getOVFFilePath(origDisk);
+            if (!cmd.getBootable()) {
+                // Create folder to hold datadisk template
+                synchronized (newTmplDir.intern()) {
+                    Script command = new Script("mkdir", _timeout, s_logger);
+                    command.add("-p");
+                    command.add(newTmplDirAbsolute);
+                    String result = command.execute();
+                    if (result != null) {
+                        String msg = "Unable to prepare template directory: " + newTmplDir + ", storage: " + secondaryStorageUrl + ", error msg: " + result;
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+                }
+                // Move Datadisk VMDK from parent template folder to Datadisk template folder
+                synchronized (origDisk.intern()) {
+                    Script command = new Script("mv", _timeout, s_logger);
+                    command.add(origDisk);
+                    command.add(newTmplDirAbsolute);
+                    String result = command.execute();
+                    if (result != null) {
+                        String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+                    command = new Script("cp", _timeout, s_logger);
+                    command.add(ovfFilePath + ".orig");
+                    command.add(newTmplDirAbsolute);
+                    result = command.execute();
+                    if (result != null) {
+                        String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
+                        s_logger.error(msg);
+                        throw new Exception(msg);
+                    }
+                }
+            }
+
+            // Create OVF for the disk
+            String newOvfFilePath = newTmplDirAbsolute + File.separator + ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1);
+            OVFHelper ovfHelper = new OVFHelper();
+            ovfHelper.rewriteOVFFile(ovfFilePath + ".orig", newOvfFilePath, diskName);
+
+            postCreatePrivateTemplate(newTmplDirAbsolute, templateId, templateUniqueName, physicalSize, virtualSize);
+            writeMetaOvaForTemplate(newTmplDirAbsolute, ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1), diskName, templateUniqueName, physicalSize);
+
+            diskTemplate.setId(templateId);
+            if (diskName.endsWith("iso")){
+                diskTemplate.setPath(newTmplDir + File.separator + diskName);
+            }
+            else {
+                diskTemplate.setPath(newTmplDir + File.separator + templateUniqueName + ".ova");
+            }
+            diskTemplate.setSize(virtualSize);
+            diskTemplate.setPhysicalSize(physicalSize);
+        } catch (Exception e) {
+            String msg = "Create Datadisk template failed due to " + e.getMessage();
+            s_logger.error(msg, e);
+            return new CreateDatadiskTemplateAnswer(msg);
+        }
+        return new CreateDatadiskTemplateAnswer(diskTemplate);
+    }
+
+    /*
+     *  return Pair of <Template relative path, Template name>
+     *  Template url may or may not end with .ova extension
+     */
+    public static Pair<String, String> decodeTemplateRelativePathAndNameFromUrl(String storeUrl, String templateUrl, String defaultName) {
+
+        String templateName = null;
+        String mountPoint = null;
+        if (templateUrl.endsWith(".ova")) {
+            int index = templateUrl.lastIndexOf("/");
+            mountPoint = templateUrl.substring(0, index);
+            mountPoint = mountPoint.substring(storeUrl.length() + 1);
+            if (!mountPoint.endsWith("/")) {
+                mountPoint = mountPoint + "/";
+            }
+
+            templateName = templateUrl.substring(index + 1).replace(".ova", "");
+
+            if (templateName == null || templateName.isEmpty()) {
+                templateName = defaultName;
+            }
+        } else {
+            mountPoint = templateUrl.substring(storeUrl.length() + 1);
+            if (!mountPoint.endsWith("/")) {
+                mountPoint = mountPoint + "/";
+            }
+            templateName = defaultName;
+        }
+
+        return new Pair<String, String>(mountPoint, templateName);
+    }
+
+    public static String getTemplateOnSecStorageFilePath(String secStorageMountPoint, String templateRelativeFolderPath, String templateName, String fileExtension) {
+
+        StringBuffer sb = new StringBuffer();
+        sb.append(secStorageMountPoint);
+        if (!secStorageMountPoint.endsWith("/")) {
+            sb.append("/");
+        }
+
+        sb.append(templateRelativeFolderPath);
+        if (!secStorageMountPoint.endsWith("/")) {
+            sb.append("/");
+        }
+
+        sb.append(templateName);
+        if (!fileExtension.startsWith(".")) {
+            sb.append(".");
+        }
+        sb.append(fileExtension);
+
+        return sb.toString();
+    }
+
+    public static String getSecondaryDatastoreUUID(String storeUrl) {
+        return UUID.nameUUIDFromBytes(storeUrl.getBytes()).toString();
+    }
+
+    private static String getTemplateRelativeDirInSecStorage(long accountId, long templateId) {
+        return "template/tmpl/" + accountId + "/" + templateId;
+    }
+
+    private void postCreatePrivateTemplate(final String installFullPath, final long templateId, final String templateName, final long size, final long virtualSize) throws Exception {
+        // TODO a bit ugly here
+        try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/template.properties"), "UTF-8"));) {
+            out.write("filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("description=privateTemplate");
+            out.newLine();
+            out.write("hvm=false");
+            out.newLine();
+            out.write("size=" + size);
+            out.newLine();
+            out.write("ova=false");
+            out.newLine();
+            out.write("id=" + templateId);
+            out.newLine();
+            out.write("ova.filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("uniquename=" + templateName);
+            out.newLine();
+            out.write("ova.virtualsize=" + virtualSize);
+            out.newLine();
+            out.write("virtualsize=" + virtualSize);
+            out.newLine();
+            out.write("ova.size=" + size);
+            out.newLine();
+            out.write("checksum=");
+            out.newLine();
+            out.write("public=false");
+            out.newLine();
+        }
+    }
+
+    private void writeMetaOvaForTemplate(final String installFullPath, final String ovfFilename, final String vmdkFilename, final String templateName, final long diskSize) throws Exception {
+
+        // TODO a bit ugly here
+        BufferedWriter out = null;
+        try {
+            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName + ".ova.meta"), "UTF-8"));
+            out.write("ova.filename=" + templateName + ".ova");
+            out.newLine();
+            out.write("version=1.0");
+            out.newLine();
+            out.write("ovf=" + ovfFilename);
+            out.newLine();
+            out.write("numDisks=1");
+            out.newLine();
+            out.write("disk1.name=" + vmdkFilename);
+            out.newLine();
+            out.write("disk1.size=" + diskSize);
+            out.newLine();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    private String getOVFFilePath(String srcOVAFileName) {
+        File file = new File(srcOVAFileName);
+        assert (_storage != null);
+        String[] files = _storage.listFiles(file.getParent());
+        if (files != null) {
+            for (String fileName : files) {
+                if (fileName.toLowerCase().endsWith(".ovf")) {
+                    File ovfFile = new File(fileName);
+                    return file.getParent() + File.separator + ovfFile.getName();
+                }
+            }
+        }
+        return null;
+    }
+
+    protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
+        if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+            SnapshotObjectTO snapshot = new SnapshotObjectTO();
+            snapshot.setPath(destPath + File.separator + destFile.getName());
+
+            CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
+            return answer;
+        }
+        // do post processing to unzip the file if it is compressed
+        String scriptsDir = "scripts/storage/secondary";
+        String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
+        if (createTmpltScr == null) {
+            throw new ConfigurationException("Unable to find createtmplt.sh");
+        }
+        s_logger.info("createtmplt.sh found in " + createTmpltScr);
+        String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
+        if (createVolScr == null) {
+            throw new ConfigurationException("Unable to find createvolume.sh");
+        }
+        s_logger.info("createvolume.sh found in " + createVolScr);
+        String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
+
+        int installTimeoutPerGig = 180 * 60 * 1000;
+        long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
+        imgSizeGigs++; // add one just in case
+        long timeout = imgSizeGigs * installTimeoutPerGig;
+
+        String origPath = destFile.getAbsolutePath();
+        String extension = null;
+        if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
+            extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
+        } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
+            extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
+        }
+
+        String templateName = UUID.randomUUID().toString();
+        String templateFilename = templateName + "." + extension;
+        Script scr = new Script(script, timeout, s_logger);
+        scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
+        scr.add("-n", templateFilename);
+
+        scr.add("-t", downloadPath);
+        scr.add("-f", origPath); // this is the temporary
+        // template file downloaded
+        String result;
+        result = scr.execute();
+
+        if (result != null) {
+            // script execution failure
+            throw new CloudRuntimeException("Failed to run script " + script);
+        }
+
+        String finalFileName = templateFilename;
+        String finalDownloadPath = destPath + File.separator + templateFilename;
+        // compute the size of
+        long size = _storage.getSize(downloadPath + File.separator + templateFilename);
+
+        DataTO newDestTO = null;
+
+        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+            TemplateObjectTO newTemplTO = new TemplateObjectTO();
+            newTemplTO.setPath(finalDownloadPath);
+            newTemplTO.setName(finalFileName);
+            newTemplTO.setSize(size);
+            newTemplTO.setPhysicalSize(size);
+            newDestTO = newTemplTO;
+        } else {
+            VolumeObjectTO newVolTO = new VolumeObjectTO();
+            newVolTO.setPath(finalDownloadPath);
+            newVolTO.setName(finalFileName);
+            newVolTO.setSize(size);
+            newDestTO = newVolTO;
+        }
+
+        return new CopyCmdAnswer(newDestTO);
+    }
+
+    protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
+        final String storagePath = destImageStore.getUrl();
+        final String destPath = destData.getPath();
+        try {
+            String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
+            final File downloadDirectory = _storage.getFile(downloadPath);
+
+            if (downloadDirectory.exists()) {
+                s_logger.debug("Directory " + downloadPath + " already exists");
+            } else {
+                if (!downloadDirectory.mkdirs()) {
+                    final String errMsg = "Unable to create directory " + downloadPath + " to copy from Swift to cache.";
+                    s_logger.error(errMsg);
+                    return new CopyCmdAnswer(errMsg);
+                }
+            }
+
+            File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
+            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+        } catch (Exception e) {
+            s_logger.debug("Failed to copy swift to nfs", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
+        final String storagePath = destImageStore.getUrl();
+        final String destPath = destData.getPath();
+
+        try {
+
+            String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
+            final File downloadDirectory = _storage.getFile(downloadPath);
+
+            if (downloadDirectory.exists()) {
+                s_logger.debug("Directory " + downloadPath + " already exists");
+            } else {
+                if (!downloadDirectory.mkdirs()) {
+                    final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
+                    s_logger.error(errMsg);
+                    return new CopyCmdAnswer(errMsg);
+                }
+            }
+            File destFile = new File(downloadDirectory, substringAfterLast(srcData.getPath(), S3Utils.SEPARATOR));
+            S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), destFile).waitForCompletion();
+
+            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+        } catch (Exception e) {
+
+            final String errMsg = format("Failed to download" + "due to $1%s", e.getMessage());
+            s_logger.error(errMsg, e);
+            return new CopyCmdAnswer(errMsg);
+        }
+    }
+
+    protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
+        String srcMountPoint = getRootDir(srcDataStore.getUrl(), _nfsVersion);
+        String snapshotPath = srcData.getPath();
+        int index = snapshotPath.lastIndexOf("/");
+        String snapshotName = snapshotPath.substring(index + 1);
+        if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
+            snapshotName = snapshotName + ".vhd";
+        }
+        snapshotPath = snapshotPath.substring(0, index);
+
+        snapshotPath = srcMountPoint + File.separator + snapshotPath;
+        String destMountPoint = getRootDir(destDataStore.getUrl(), _nfsVersion);
+        String destPath = destMountPoint + File.separator + destData.getPath();
+
+        String errMsg = null;
+        try {
+            _storage.mkdir(destPath);
+
+            String templateUuid = UUID.randomUUID().toString();
+            String templateName = templateUuid + ".vhd";
+            Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
+            command.add("-p", snapshotPath);
+            command.add("-s", snapshotName);
+            command.add("-n", templateName);
+            command.add("-t", destPath);
+            String result = command.execute();
+
+            if (result != null && !result.equalsIgnoreCase("")) {
+                return new CopyCmdAnswer(result);
+            }
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            Processor processor = new VhdProcessor();
+
+            processor.configure("Vhd Processor", params);
+            FormatInfo info = processor.process(destPath, null, templateUuid);
+
+            TemplateLocation loc = new TemplateLocation(_storage, destPath);
+            loc.create(1, true, templateUuid);
+            loc.addFormat(info);
+            loc.save();
+            TemplateProp prop = loc.getTemplateInfo();
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(destData.getPath() + File.separator + templateName);
+            newTemplate.setFormat(ImageFormat.VHD);
+            newTemplate.setSize(prop.getSize());
+            newTemplate.setPhysicalSize(prop.getPhysicalSize());
+            newTemplate.setName(templateUuid);
+            return new CopyCmdAnswer(newTemplate);
+        } catch (ConfigurationException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        } catch (InternalErrorException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        } catch (IOException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        }
+
+        return new CopyCmdAnswer(errMsg);
+    }
+
+    protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
+
+        if (srcData.getHypervisorType() == HypervisorType.XenServer) {
+            return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
+        } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
+            File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl(), _nfsVersion);
+            File destFile = getFile(destData.getPath(), destDataStore.getUrl(), _nfsVersion);
+
+            VolumeObjectTO volumeObjectTO = srcData.getVolume();
+            ImageFormat srcFormat = null;
+            //TODO: the image format should be stored in snapshot table, instead of getting from volume
+            if (volumeObjectTO != null) {
+                srcFormat = volumeObjectTO.getFormat();
+            } else {
+                srcFormat = ImageFormat.QCOW2;
+            }
+
+            // get snapshot file name
+            String templateName = srcFile.getName();
+            // add kvm file extension for copied template name
+            String fileName = templateName + "." + srcFormat.getFileExtension();
+            String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
+            s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
+            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
+            String metaFileName = destFile.getAbsolutePath() + File.separator + _tmpltpp;
+            File metaFile = new File(metaFileName);
+            try {
+                _storage.create(destFile.getAbsolutePath(), _tmpltpp);
+                try ( // generate template.properties file
+                        FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
+                    // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
+                    // to send template name back.
+                    bufferWriter.write("uniquename=" + destData.getName());
+                    bufferWriter.write("\n");
+                    bufferWriter.write("filename=" + fileName);
+                }
+                try {
+                    /**
+                     * Snapshots might be in either QCOW2 or RAW image format
+                     *
+                     * For example RBD snapshots are in RAW format
+                     */
+                    Processor processor = null;
+                    if (srcFormat == ImageFormat.QCOW2) {
+                        processor = new QCOW2Processor();
+                    } else if (srcFormat == ImageFormat.RAW) {
+                        processor = new RawImageProcessor();
+                    } else {
+                        throw new ConfigurationException("Unknown image format " + srcFormat.toString());
+                    }
+
+                    Map<String, Object> params = new HashMap<String, Object>();
+                    params.put(StorageLayer.InstanceConfigKey, _storage);
+
+                    processor.configure("template processor", params);
+                    String destPath = destFile.getAbsolutePath();
+
+                    FormatInfo info = processor.process(destPath, null, templateName);
+                    TemplateLocation loc = new TemplateLocation(_storage, destPath);
+                    loc.create(1, true, destData.getName());
+                    loc.addFormat(info);
+                    loc.save();
+
+                    TemplateProp prop = loc.getTemplateInfo();
+                    TemplateObjectTO newTemplate = new TemplateObjectTO();
+                    newTemplate.setPath(destData.getPath() + File.separator + fileName);
+                    newTemplate.setFormat(srcFormat);
+                    newTemplate.setSize(prop.getSize());
+                    newTemplate.setPhysicalSize(prop.getPhysicalSize());
+                    return new CopyCmdAnswer(newTemplate);
+                } catch (ConfigurationException e) {
+                    s_logger.debug("Failed to create template:" + e.toString());
+                    return new CopyCmdAnswer(e.toString());
+                } catch (InternalErrorException e) {
+                    s_logger.debug("Failed to create template:" + e.toString());
+                    return new CopyCmdAnswer(e.toString());
+                }
+            } catch (IOException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            }
+        }
+
+        return new CopyCmdAnswer("");
+    }
+
+    protected File getFile(String path, String nfsPath, Integer nfsVersion) {
+        String filePath = getRootDir(nfsPath, nfsVersion) + File.separator + path;
+        File f = new File(filePath);
+        if (!f.exists()) {
+            f = findFile(filePath);
+            if (f == null) {
+                _storage.mkdirs(filePath);
+                f = new File(filePath);
+            }
+        }
+        return f;
+    }
+
+    protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        DataStoreTO destDataStore = destData.getDataStore();
+        if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
+            if (!(srcDataStore instanceof NfsTO)) {
+                s_logger.debug("only support nfs storage as src, when create template from snapshot");
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            if (destDataStore instanceof NfsTO) {
+                return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
+            } else if (destDataStore instanceof SwiftTO) {
+                //create template on the same data store
+                CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+                        (NfsTO)srcDataStore);
+                if (!answer.getResult()) {
+                    return answer;
+                }
+                s_logger.debug("starting copy template to swift");
+                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
+                newTemplate.setDataStore(srcDataStore);
+                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
+                Answer result = copyFromNfsToSwift(newCpyCmd);
+
+                cleanupStagingNfs(newTemplate);
+                return result;
+
+            } else if (destDataStore instanceof S3TO) {
+                //create template on the same data store
+                CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+                        (NfsTO)srcDataStore);
+                if (!answer.getResult()) {
+                    return answer;
+                }
+                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
+                newTemplate.setDataStore(srcDataStore);
+                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
+                Answer result = copyFromNfsToS3(newCpyCmd);
+
+                cleanupStagingNfs(newTemplate);
+
+                return result;
+            }
+        }
+        s_logger.debug("Failed to create template from snapshot");
+        return new CopyCmdAnswer("Unsupported protocol");
+    }
+
+    /**
+     * clean up template data on staging area
+     * @param newTemplate: The template on the secondary storage that needs to be cleaned up
+     */
+    protected void cleanupStagingNfs(TemplateObjectTO newTemplate) {
+        try {
+            DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
+            execute(deleteCommand);
+        } catch (Exception e) {
+            s_logger.debug("Failed to clean up staging area:", e);
+        }
+    }
+
+    protected Answer copyFromNfsToImage(CopyCommand cmd) {
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        if (destDataStore instanceof S3TO) {
+            return copyFromNfsToS3(cmd);
+        } else if (destDataStore instanceof SwiftTO) {
+            return copyFromNfsToSwift(cmd);
+        } else {
+            return new CopyCmdAnswer("unsupported ");
+        }
+    }
+
+    protected Answer execute(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+            return createTemplateFromSnapshot(cmd);
+        }
+
+        if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
+            NfsTO destImageStore = (NfsTO)destDataStore;
+            if (srcDataStore instanceof S3TO) {
+                S3TO s3 = (S3TO)srcDataStore;
+                return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
+            } else if (srcDataStore instanceof SwiftTO) {
+                return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
+            }
+        }
+
+        if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
+            return copyFromNfsToImage(cmd);
+        }
+
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
+        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
+    }
+
+    private String determineS3TemplateNameFromKey(String key) {
+        return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
+    }
+
+    protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
+        return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
+    }
+
+    protected Long determineS3VolumeIdFromKey(String key) {
+        return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
+    }
+
+    private String determineStorageTemplatePath(final String storagePath, String dataPath, Integer nfsVersion) {
+        return join(asList(getRootDir(storagePath, nfsVersion), dataPath), File.separator);
+    }
+
+    protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
+        HttpClient client = new DefaultHttpClient();
+        HttpGet get = new HttpGet(url);
+        try {
+            HttpResponse response = client.execute(get);
+            HttpEntity entity = response.getEntity();
+            if (entity == null) {
+                s_logger.debug("Faled to get entity");
+                throw new CloudRuntimeException("Failed to get url: " + url);
+            }
+
+            String nfsMountPath = getRootDir(nfs.getUrl(), _nfsVersion);
+
+            String filePath = nfsMountPath + File.separator + path;
+            File directory = new File(filePath);
+            if (!directory.exists()) {
+                _storage.mkdirs(filePath);
+            }
+            File destFile = new File(filePath + File.separator + name);
+            if (!destFile.createNewFile()) {
+                s_logger.warn("Reusing existing file " + destFile.getPath());
+            }
+            try (FileOutputStream outputStream = new FileOutputStream(destFile);) {
+                entity.writeTo(outputStream);
+            } catch (IOException e) {
+                s_logger.debug("downloadFromUrlToNfs:Exception:" + e.getMessage(), e);
+            }
+            return new File(destFile.getAbsolutePath());
+        } catch (IOException e) {
+            s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
+            throw new CloudRuntimeException(e);
+        }
+    }
+
+    protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
+        SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
+        String path = cmd.getInstallPath();
+        DataStoreTO cacheStore = cmd.getCacheStore();
+        if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
+            return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        }
+
+        File file = null;
+        try {
+            NfsTO nfsCacheStore = (NfsTO)cacheStore;
+            String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
+            file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
+            String container = "T-" + cmd.getId();
+            String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
+
+            long virtualSize = getVirtualSize(file, getTemplateFormat(file.getName()));
+            long size = file.length();
+            String uniqueName = cmd.getName();
+
+            //put metda file
+            File uniqDir = _storage.createUniqDir();
+            String metaFileName = uniqDir.getAbsolutePath() + File.separator + _tmpltpp;
+            _storage.create(uniqDir.getAbsolutePath(), _tmpltpp);
+
+            File metaFile = swiftWriteMetadataFile(metaFileName, uniqueName, fileName, size, virtualSize);
+
+            SwiftUtil.putObject(swiftTO, metaFile, container, _tmpltpp);
+            metaFile.delete();
+            uniqDir.delete();
+            String md5sum = null;
+            try (FileInputStream fs = new FileInputStream(file)) {
+                md5sum = DigestUtils.md5Hex(fs);
+            } catch (IOException e) {
+                s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
+            }
+
+            DownloadAnswer answer = new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, virtualSize, file.length(), md5sum);
+            return answer;
+        } catch (IOException e) {
+            s_logger.debug("Failed to register template into swift", e);
+            return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        } finally {
+            if (file != null) {
+                file.delete();
+            }
+        }
+    }
+
+    private Answer execute(DownloadCommand cmd) {
+        DataStoreTO dstore = cmd.getDataStore();
+        if (dstore instanceof NfsTO || dstore instanceof S3TO) {
+            return _dlMgr.handleDownloadCommand(this, cmd);
+        } else if (dstore instanceof SwiftTO) {
+            return registerTemplateOnSwift(cmd);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    private ImageFormat getTemplateFormat(String filePath) {
+        String ext = null;
+        int extensionPos = filePath.lastIndexOf('.');
+        int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
+        int i = lastSeparator > extensionPos ? -1 : extensionPos;
+        if (i > 0) {
+            ext = filePath.substring(i + 1);
+        }
+        if (ext != null) {
+            if (ext.equalsIgnoreCase("vhd")) {
+                return ImageFormat.VHD;
+            } else if (ext.equalsIgnoreCase("vhdx")) {
+                return ImageFormat.VHDX;
+            } else if (ext.equalsIgnoreCase("qcow2")) {
+                return ImageFormat.QCOW2;
+            } else if (ext.equalsIgnoreCase("ova")) {
+                return ImageFormat.OVA;
+            } else if (ext.equalsIgnoreCase("tar")) {
+                return ImageFormat.TAR;
+            } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
+                return ImageFormat.RAW;
+            } else if (ext.equalsIgnoreCase("vmdk")) {
+                return ImageFormat.VMDK;
+            } else if (ext.equalsIgnoreCase("vdi")) {
+                return ImageFormat.VDI;
+            }
+        }
+
+        return null;
+
+    }
+
+    protected long getVirtualSize(File file, ImageFormat format) {
+        Processor processor = null;
+        try {
+            if (format == null) {
+                return file.length();
+            } else if (format == ImageFormat.QCOW2) {
+                processor = new QCOW2Processor();
+            } else if (format == ImageFormat.OVA) {
+                processor = new OVAProcessor();
+            } else if (format == ImageFormat.VHD) {
+                processor = new VhdProcessor();
+            } else if (format == ImageFormat.RAW) {
+                processor = new RawImageProcessor();
+            } else if (format == ImageFormat.VMDK) {
+                processor = new VmdkProcessor();
+            }
+            if (format == ImageFormat.TAR) {
+                processor = new TARProcessor();
+            }
+
+            if (processor == null) {
+                return file.length();
+            }
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            processor.configure("template processor", params);
+            return processor.getVirtualSize(file);
+        } catch (Exception e) {
+            s_logger.warn("Failed to get virtual size of file " + file.getPath() + ", returning file size instead: ", e);
+            return file.length();
+        }
+
+    }
+
+    protected File findFile(String path) {
+
+        File srcFile = _storage.getFile(path);
+        if (!srcFile.exists()) {
+            srcFile = _storage.getFile(path + ".qcow2");
+            if (!srcFile.exists()) {
+                srcFile = _storage.getFile(path + ".vhd");
+                if (!srcFile.exists()) {
+                    srcFile = _storage.getFile(path + ".ova");
+                    if (!srcFile.exists()) {
+                        srcFile = _storage.getFile(path + ".vmdk");
+                        if (!srcFile.exists()) {
+                            return null;
+                        }
+                    }
+                }
+            }
+        }
+
+        return srcFile;
+    }
+
+    protected Answer copyFromNfsToS3(CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        NfsTO srcStore = (NfsTO)srcDataStore;
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        final S3TO s3 = (S3TO)destDataStore;
+
+        try {
+            final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath(), _nfsVersion);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
+            }
+
+            final String bucket = s3.getBucketName();
+            File srcFile = findFile(templatePath);
+            if (srcFile == null) {
+                return new CopyCmdAnswer("Can't find src file:" + templatePath);
+            }
+
+            ImageFormat format = getTemplateFormat(srcFile.getName());
+            String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
+
+            putFile(s3, srcFile, bucket, key).waitForCompletion();
+
+            DataTO retObj = null;
+            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+                TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(key);
+                newTemplate.setSize(getVirtualSize(srcFile, format));
+                newTemplate.setPhysicalSize(srcFile.length());
+                newTemplate.setFormat(format);
+                retObj = newTemplate;
+            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(key);
+                newVol.setSize(srcFile.length());
+                retObj = newVol;
+            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+                newSnapshot.setPath(key);
+                retObj = newSnapshot;
+            }
+
+            return new CopyCmdAnswer(retObj);
+        } catch (Exception e) {
+            s_logger.error("failed to upload" + srcData.getPath(), e);
+            return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
+        }
+    }
+
+    /***
+     *This method will create a file using the filenName and metaFileName.
+     *That file will contain the given attributes (unique name, file name, size, and virtualSize).
+     *
+     * @param metaFileName : The path of the metadata file
+     * @param filename      :attribute:  Filename of the template
+     * @param uniqueName    :attribute:  Unique name of the template
+     * @param size          :attribute:  physical size of the template
+     * @param virtualSize   :attribute:  virtual size of the template
+     * @return File representing the metadata file
+     * @throws IOException
+     */
+
+    protected File swiftWriteMetadataFile(String metaFileName, String uniqueName, String filename, long size, long virtualSize) throws IOException {
+        File metaFile = new File(metaFileName);
+        FileWriter writer = new FileWriter(metaFile);
+        BufferedWriter bufferWriter = new BufferedWriter(writer);
+        bufferWriter.write("uniquename=" + uniqueName);
+        bufferWriter.write("\n");
+        bufferWriter.write("filename=" + filename);
+        bufferWriter.write("\n");
+        bufferWriter.write("size=" + size);
+        bufferWriter.write("\n");
+        bufferWriter.write("virtualsize=" + virtualSize);
+        bufferWriter.close();
+        writer.close();
+        return metaFile;
+    }
+
+    /**
+     * Creates a template.properties for Swift with its correct unique name
+     *
+     * @param swift  The swift object
+     * @param srcFile Source file on the staging NFS
+     * @param containerName Destination container  @return true on successful write
+     * @param uniqueName Unique name identifying the template
+     */
+    protected boolean swiftUploadMetadataFile(SwiftTO swift, File srcFile, String containerName, String uniqueName) throws IOException {
+
+        File uniqDir = _storage.createUniqDir();
+        String metaFileName = uniqDir.getAbsolutePath() + File.separator + _tmpltpp;
+        _storage.create(uniqDir.getAbsolutePath(), _tmpltpp);
+
+        long virtualSize = getVirtualSize(srcFile, getTemplateFormat(srcFile.getName()));
+
+        File metaFile = swiftWriteMetadataFile(metaFileName, uniqueName, srcFile.getName(), srcFile.length(), virtualSize);
+
+        SwiftUtil.putObject(swift, metaFile, containerName, _tmpltpp);
+        metaFile.delete();
+        uniqDir.delete();
+
+        return true;
+    }
+
+    /**
+     * Copies data from NFS and uploads it into a Swift container
+     *
+     * @param cmd CopyComand
+     * @return CopyCmdAnswer
+     */
+    protected Answer copyFromNfsToSwift(CopyCommand cmd) {
+
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        NfsTO srcStore = (NfsTO)srcDataStore;
+        DataStoreTO destDataStore = destData.getDataStore();
+        File srcFile = getFile(srcData.getPath(), srcStore.getUrl(), _nfsVersion);
+
+        SwiftTO swift = (SwiftTO)destDataStore;
+        long pathId = destData.getId();
+
+        try {
+
+            if (destData instanceof SnapshotObjectTO) {
+                pathId = ((SnapshotObjectTO)destData).getVolume().getId();
+            }
+
+            String containerName = SwiftUtil.getContainerName(destData.getObjectType().toString(), pathId);
+            String swiftPath = SwiftUtil.putObject(swift, srcFile, containerName, srcFile.getName());
+
+            DataTO retObj = null;
+            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+                TemplateObjectTO destTemplateData = (TemplateObjectTO)destData;
+                String uniqueName = destTemplateData.getName();
+                swiftUploadMetadataFile(swift, srcFile, containerName, uniqueName);
+                TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(swiftPath);
+                newTemplate.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
+                newTemplate.setPhysicalSize(srcFile.length());
+                newTemplate.setFormat(getTemplateFormat(srcFile.getName()));
+                retObj = newTemplate;
+            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(containerName);
+                newVol.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
+                retObj = newVol;
+            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+                newSnapshot.setPath(containerName + File.separator + srcFile.getName());
+                retObj = newSnapshot;
+            }
+
+            return new CopyCmdAnswer(retObj);
+
+        } catch (Exception e) {
+            s_logger.error("failed to upload " + srcData.getPath(), e);
+            return new CopyCmdAnswer("failed to upload " + srcData.getPath() + e.toString());
+        }
+    }
+
+    String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
+        + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDownload failed  err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDownload failed , err=" + parser.getLines();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
+                + swift.getUserName() + " -K " + swift.getKey() + " download " + container);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDownloadContainer failed  err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
+        long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
+        List<String> files = new ArrayList<String>();
+        if (lFilename.equals("*")) {
+            File dir = new File(lDir);
+            String[] dir_lst = dir.list();
+            if (dir_lst != null) {
+                for (String file : dir_lst) {
+                    if (file.startsWith(".")) {
+                        continue;
+                    }
+                    files.add(file);
+                }
+            }
+        } else {
+            files.add(lFilename);
+        }
+
+        for (String file : files) {
+            File f = new File(lDir + "/" + file);
+            long size = f.length();
+            Script command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            if (size <= SWIFT_MAX_SIZE) {
+                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
+                        + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file);
+            } else {
+                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
+                        + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
+            }
+            OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+            String result = command.execute(parser);
+            if (result != null) {
+                String errMsg = "swiftUpload failed , err=" + result;
+                s_logger.warn(errMsg);
+                return errMsg;
+            }
+            if (parser.getLines() != null) {
+                String[] lines = parser.getLines().split("\\n");
+                for (String line : lines) {
+                    if (line.contains("Errno") || line.contains("failed")) {
+                        String errMsg = "swiftUpload failed , err=" + parser.getLines();
+                        s_logger.warn(errMsg);
+                        return errMsg;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    String[] swiftList(SwiftTO swift, String container, String rFilename) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
+        + " -K " + swift.getKey() + " list " + container + " " + rFilename);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            return lines;
+        } else {
+            if (result != null) {
+                String errMsg = "swiftList failed , err=" + result;
+                s_logger.warn(errMsg);
+            } else {
+                String errMsg = "swiftList failed, no lines returns";
+                s_logger.warn(errMsg);
+            }
+        }
+        return null;
+    }
+
+    String swiftDelete(SwiftTO swift, String container, String object) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
+        + " -K " + swift.getKey() + " delete " + container + " " + object);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDelete failed , err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDelete failed , err=" + parser.getLines();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+    }
+
+    public Answer execute(DeleteSnapshotsDirCommand cmd) {
+        DataStoreTO dstore = cmd.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeSnapshotPath = cmd.getDirectory();
+            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
+
+            if (relativeSnapshotPath.startsWith(File.separator)) {
+                relativeSnapshotPath = relativeSnapshotPath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteSnapshotPath = parent + relativeSnapshotPath;
+            File snapshotDir = new File(absoluteSnapshotPath);
+            String details = null;
+            if (!snapshotDir.exists()) {
+                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, true, details);
+            }
+            // delete all files in the directory
+            String lPath = absoluteSnapshotPath + "/*";
+            String result = deleteLocalFile(lPath);
+            if (result != null) {
+                String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            // delete the directory
+            if (!snapshotDir.delete()) {
+                details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = cmd.getDirectory();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            String path = cmd.getDirectory();
+            String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
+            // that
+            // the
+            // filename
+            // is
+            // the
+            // last
+            // section
+            // in
+            // the
+            // path
+            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
+            if (result != null) {
+                String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+    }
+
+    private Answer execute(ComputeChecksumCommand cmd) {
+
+        String relativeTemplatePath = cmd.getTemplatePath();
+        DataStoreTO store = cmd.getStore();
+        if (!(store instanceof NfsTO)) {
+            return new Answer(cmd, false, "can't handle non nfs data store");
+        }
+        NfsTO nfsStore = (NfsTO)store;
+        String parent = getRootDir(nfsStore.getUrl(), _nfsVersion);
+
+        if (relativeTemplatePath.startsWith(File.separator)) {
+            relativeTemplatePath = relativeTemplatePath.substring(1);
+        }
+
+        if (!parent.endsWith(File.separator)) {
+            parent += File.separator;
+        }
+        String absoluteTemplatePath = parent + relativeTemplatePath;
+        String algorithm = cmd.getAlgorithm();
+        File f = new File(absoluteTemplatePath);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath);
+        }
+        String checksum = null;
+
+        try (InputStream is = new FileInputStream(f);){
+            checksum = DigestHelper.digest(algorithm, is).toString();
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Successfully calculated checksum for file " + absoluteTemplatePath + " - " + checksum);
+            }
+        } catch (IOException e) {
+            String logMsg = "Unable to process file for " + algorithm + " - " + absoluteTemplatePath;
+            s_logger.error(logMsg);
+            return new Answer(cmd, false, checksum);
+        } catch (NoSuchAlgorithmException e) {
+            return new Answer(cmd, false, checksum);
+        }
+
+        return new Answer(cmd, true, checksum);
+    }
+
+    private void configCerts(KeystoreManager.Certificates certs) {
+        if (certs == null) {
+            configureSSL();
+        } else {
+            String prvKey = certs.getPrivKey();
+            String pubCert = certs.getPrivCert();
+            String certChain = certs.getCertChain();
+            String rootCACert = certs.getRootCACert();
+
+            try {
+                File prvKeyFile = File.createTempFile("prvkey", null);
+                String prvkeyPath = prvKeyFile.getAbsolutePath();
+                try (BufferedWriter prvt_key_file = new BufferedWriter(new FileWriter(prvKeyFile));) {
+                    prvt_key_file.write(prvKey);
+                } catch (IOException e) {
+                    s_logger.debug("Failed to config ssl: " + e.toString());
+                }
+
+                File pubCertFile = File.createTempFile("pubcert", null);
+                String pubCertFilePath = pubCertFile.getAbsolutePath();
+
+                try (BufferedWriter pub_cert_file = new BufferedWriter(new FileWriter(pubCertFile));) {
+                    pub_cert_file.write(pubCert);
+                } catch (IOException e) {
+                    s_logger.debug("Failed to config ssl: " + e.toString());
+                }
+
+                String certChainFilePath = null, rootCACertFilePath = null;
+                File certChainFile = null, rootCACertFile = null;
+                if (certChain != null) {
+                    certChainFile = File.createTempFile("certchain", null);
+                    certChainFilePath = certChainFile.getAbsolutePath();
+                    try (BufferedWriter cert_chain_out = new BufferedWriter(new FileWriter(certChainFile));) {
+                        cert_chain_out.write(certChain);
+                    } catch (IOException e) {
+                        s_logger.debug("Failed to config ssl: " + e.toString());
+                    }
+                }
+
+                if (rootCACert != null) {
+                    rootCACertFile = File.createTempFile("rootcert", null);
+                    rootCACertFilePath = rootCACertFile.getAbsolutePath();
+                    try (BufferedWriter root_ca_cert_file = new BufferedWriter(new FileWriter(rootCACertFile));) {
+                        root_ca_cert_file.write(rootCACert);
+                    } catch (IOException e) {
+                        s_logger.debug("Failed to config ssl: " + e.toString());
+                    }
+                }
+
+                configureSSL(prvkeyPath, pubCertFilePath, certChainFilePath, rootCACertFilePath);
+
+                prvKeyFile.delete();
+                pubCertFile.delete();
+                if (certChainFile != null) {
+                    certChainFile.delete();
+                }
+                if (rootCACertFile != null) {
+                    rootCACertFile.delete();
+                }
+
+            } catch (IOException e) {
+                s_logger.debug("Failed to config ssl: " + e.toString());
+            }
+        }
+    }
+
+    private Answer execute(SecStorageSetupCommand cmd) {
+        if (!_inSystemVM) {
+            return new Answer(cmd, true, null);
+        }
+        Answer answer = null;
+        DataStoreTO dStore = cmd.getDataStore();
+        if (dStore instanceof NfsTO) {
+            String secUrl = cmd.getSecUrl();
+            try {
+                URI uri = new URI(secUrl);
+                String nfsHostIp = getUriHostIp(uri);
+
+                addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
+
+                String dir = mountUri(uri, cmd.getNfsVersion());
+
+                configCerts(cmd.getCerts());
+
+                nfsIps.add(nfsHostIp);
+                answer = new SecStorageSetupAnswer(dir);
+            } catch (Exception e) {
+                String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+                s_logger.error(msg);
+                answer = new Answer(cmd, false, msg);
+
+            }
+        } else {
+            // TODO: what do we need to setup for S3/Swift, maybe need to mount
+            // to some cache storage
+            answer = new Answer(cmd, true, null);
+        }
+
+        savePostUploadPSK(cmd.getPostUploadKey());
+        startPostUploadServer();
+        return answer;
+    }
+
+    private void startPostUploadServer() {
+        final int PORT = 8210;
+        final int NO_OF_WORKERS = 15;
+        final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
+        final EventLoopGroup workerGroup = new NioEventLoopGroup(NO_OF_WORKERS);
+        final ServerBootstrap b = new ServerBootstrap();
+        final NfsSecondaryStorageResource storageResource = this;
+        b.group(bossGroup, workerGroup);
+        b.channel(NioServerSocketChannel.class);
+        b.handler(new LoggingHandler(LogLevel.INFO));
+        b.childHandler(new ChannelInitializer<SocketChannel>() {
+            @Override
+            protected void initChannel(SocketChannel ch) throws Exception {
+                ChannelPipeline pipeline = ch.pipeline();
+                pipeline.addLast(new HttpRequestDecoder());
+                pipeline.addLast(new HttpResponseEncoder());
+                pipeline.addLast(new HttpContentCompressor());
+                pipeline.addLast(new HttpUploadServerHandler(storageResource));
+            }
+        });
+        new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Channel ch = b.bind(PORT).sync().channel();
+                    s_logger.info(String.format("Started post upload server on port %d with %d workers", PORT, NO_OF_WORKERS));
+                    ch.closeFuture().sync();
+                } catch (InterruptedException e) {
+                    s_logger.info("Failed to start post upload server");
+                    s_logger.debug("Exception while starting post upload server", e);
+                } finally {
+                    bossGroup.shutdownGracefully();
+                    workerGroup.shutdownGracefully();
+                    s_logger.info("shutting down post upload server");
+                }
+            }
+        }.start();
+        s_logger.info("created a thread to start post upload server");
+    }
+
+    private void savePostUploadPSK(String psk) {
+        try {
+            FileUtils.writeStringToFile(new File(POST_UPLOAD_KEY_LOCATION), psk, "utf-8");
+        } catch (IOException ex) {
+            s_logger.debug("Failed to copy PSK to the file.", ex);
+        }
+    }
+
+    protected Answer deleteSnapshot(final DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String snapshotPath = obj.getPath();
+            if (snapshotPath.startsWith(File.separator)) {
+                snapshotPath = snapshotPath.substring(1);
+            }
+            // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
+            // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
+            // and return true.
+            String fullSnapPath = parent + snapshotPath;
+            File snapDir = new File(fullSnapPath);
+            if (snapDir.exists() && snapDir.isDirectory()) {
+                s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
+                return new Answer(cmd, true, null);
+            }
+            // passed snapshot path is a snapshot file path, then get snapshot directory first
+            int index = snapshotPath.lastIndexOf("/");
+            String snapshotName = snapshotPath.substring(index + 1);
+            snapshotPath = snapshotPath.substring(0, index);
+            String absoluteSnapshotPath = parent + snapshotPath;
+            // check if snapshot directory exists
+            File snapshotDir = new File(absoluteSnapshotPath);
+            String details = null;
+            if (!snapshotDir.exists()) {
+                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, true, details);
+            }
+            // delete snapshot in the directory if exists
+            String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
+            String result = deleteLocalFile(lPath);
+            if (result != null) {
+                details = "failed to delete snapshot " + lPath + " , err=" + result;
+                s_logger.warn(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteObject(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            SwiftTO swiftTO = (SwiftTO)dstore;
+            String path = obj.getPath();
+            SwiftUtil.deleteObject(swiftTO, path);
+
+            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
+        String[] containers = SwiftUtil.list(swift, "", null);
+        if (containers == null) {
+            return null;
+        }
+        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+        for (String container : containers) {
+            if (container.startsWith("T-")) {
+                String[] files = SwiftUtil.list(swift, container, _tmpltpp);
+                if (files.length != 1) {
+                    continue;
+                }
+                try {
+                    File tempFile = File.createTempFile("template", ".tmp");
+                    File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + _tmpltpp);
+                    if (tmpFile == null) {
+                        continue;
+                    }
+                    try (FileReader fr = new FileReader(tmpFile); BufferedReader brf = new BufferedReader(fr);) {
+                        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, physicalSize, true, false);
+                            tmpltInfos.put(uniqName, prop);
+                        }
+                    } catch (IOException ex) {
+                        s_logger.debug("swiftListTemplate:Exception:" + ex.getMessage());
+                        continue;
+                    }
+                } catch (IOException e) {
+                    s_logger.debug("Failed to create templ file:" + e.toString());
+                    continue;
+                } catch (Exception e) {
+                    s_logger.debug("Failed to get properties: " + e.toString());
+                    continue;
+                }
+            }
+        }
+        return tmpltInfos;
+    }
+
+    Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
+        String bucket = s3.getBucketName();
+        // List the objects in the source directory on S3
+        final List<S3ObjectSummary> objectSummaries = S3Utils.listDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
+        if (objectSummaries == null) {
+            return null;
+        }
+        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+        for (S3ObjectSummary objectSummary : objectSummaries) {
+            String key = objectSummary.getKey();
+            // String installPath = StringUtils.substringBeforeLast(key,
+            // S3Utils.SEPARATOR);
+            String uniqueName = determineS3TemplateNameFromKey(key);
+            // TODO: isPublic value, where to get?
+            TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+            tmpltInfos.put(uniqueName, tInfo);
+        }
+        return tmpltInfos;
+
+    }
+
+    Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
+        String bucket = s3.getBucketName();
+        // List the objects in the source directory on S3
+        final List<S3ObjectSummary> objectSummaries = S3Utils.listDirectory(s3, bucket, VOLUME_ROOT_DIR);
+        if (objectSummaries == null) {
+            return null;
+        }
+        Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
+        for (S3ObjectSummary objectSummary : objectSummaries) {
+            String key = objectSummary.getKey();
+            // String installPath = StringUtils.substringBeforeLast(key,
+            // S3Utils.SEPARATOR);
+            Long id = determineS3VolumeIdFromKey(key);
+            // TODO: how to get volume template name
+            TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+            tmpltInfos.put(id, tInfo);
+        }
+        return tmpltInfos;
+
+    }
+
+    private Answer execute(ListTemplateCommand cmd) {
+        if (!_inSystemVM) {
+            return new ListTemplateAnswer(null, null);
+        }
+
+        DataStoreTO store = cmd.getDataStore();
+        if (store instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)store;
+            String secUrl = nfs.getUrl();
+            String root = getRootDir(secUrl, cmd.getNfsVersion());
+            Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
+            return new ListTemplateAnswer(secUrl, templateInfos);
+        } else if (store instanceof SwiftTO) {
+            SwiftTO swift = (SwiftTO)store;
+            Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
+            return new ListTemplateAnswer(swift.toString(), templateInfos);
+        } else if (store instanceof S3TO) {
+            S3TO s3 = (S3TO)store;
+            Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
+            return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + store);
+        }
+    }
+
+    private Answer execute(ListVolumeCommand cmd) {
+        if (!_inSystemVM) {
+            return new ListVolumeAnswer(cmd.getSecUrl(), null);
+        }
+        DataStoreTO store = cmd.getDataStore();
+        if (store instanceof NfsTO) {
+            String root = getRootDir(cmd.getSecUrl(), _nfsVersion);
+            Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
+            return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
+        } else if (store instanceof S3TO) {
+            S3TO s3 = (S3TO)store;
+            Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
+            return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + store);
+        }
+
+    }
+
+    private Answer execute(SecStorageVMSetupCommand cmd) {
+        if (!_inSystemVM) {
+            return new Answer(cmd, true, null);
+        }
+        boolean success = true;
+        StringBuilder result = new StringBuilder();
+        for (String cidr : cmd.getAllowedInternalSites()) {
+            if (nfsIps.contains(cidr)) {
+                /*
+                 * if the internal download ip is the same with secondary
+                 * storage ip, adding internal sites will flush ip route to nfs
+                 * through storage ip.
+                 */
+                continue;
+            }
+            String tmpresult = allowOutgoingOnPrivate(cidr);
+            if (tmpresult != null) {
+                result.append(", ").append(tmpresult);
+                success = false;
+            }
+        }
+        if (success) {
+            if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
+                String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
+                if (tmpresult != null) {
+                    result.append("Failed to configure auth for copy ").append(tmpresult);
+                    success = false;
+                }
+            }
+        }
+        return new Answer(cmd, success, result.toString());
+
+    }
+
+    private String deleteLocalFile(String fullPath) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("rm -rf " + fullPath);
+        String result = command.execute();
+        if (result != null) {
+            String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        return null;
+    }
+
+    public String allowOutgoingOnPrivate(String destCidr) {
+        if (!_inSystemVM) {
+            return null;
+        }
+        Script command = new Script("/bin/bash", s_logger);
+        String intf = "eth1";
+        command.add("-c");
+        command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp  -j ACCEPT");
+
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result);
+            return "Error in allowing outgoing to " + destCidr + ", err=" + result;
+        }
+
+        addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr);
+
+        return null;
+    }
+
+    private Answer execute(SecStorageFirewallCfgCommand cmd) {
+        if (!_inSystemVM) {
+            return new Answer(cmd, true, null);
+        }
+
+        List<String> ipList = new ArrayList<String>();
+
+        for (PortConfig pCfg : cmd.getPortConfigs()) {
+            if (pCfg.isAdd()) {
+                ipList.add(pCfg.getSourceIp());
+            }
+        }
+        boolean success = true;
+        String result;
+        result = configureIpFirewall(ipList, cmd.getIsAppendAIp());
+        if (result != null) {
+            success = false;
+        }
+
+        return new Answer(cmd, success, result);
+    }
+
+    private UploadStatusAnswer execute(UploadStatusCommand cmd) {
+        String entityUuid = cmd.getEntityUuid();
+        if (uploadEntityStateMap.containsKey(entityUuid)) {
+            UploadEntity uploadEntity = uploadEntityStateMap.get(entityUuid);
+            if (uploadEntity.getUploadState() == UploadEntity.Status.ERROR) {
+                uploadEntityStateMap.remove(entityUuid);
+                return new UploadStatusAnswer(cmd, UploadStatus.ERROR, uploadEntity.getErrorMessage());
+            } else if (uploadEntity.getUploadState() == UploadEntity.Status.COMPLETED) {
+                UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.COMPLETED);
+                answer.setVirtualSize(uploadEntity.getVirtualSize());
+                answer.setInstallPath(uploadEntity.getTmpltPath());
+                answer.setPhysicalSize(uploadEntity.getPhysicalSize());
+                answer.setDownloadPercent(100);
+                uploadEntityStateMap.remove(entityUuid);
+                return answer;
+            } else if (uploadEntity.getUploadState() == UploadEntity.Status.IN_PROGRESS) {
+                UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.IN_PROGRESS);
+                long downloadedSize = FileUtils.sizeOfDirectory(new File(uploadEntity.getInstallPathPrefix()));
+                int downloadPercent = (int)(100 * downloadedSize / uploadEntity.getContentLength());
+                answer.setDownloadPercent(Math.min(downloadPercent, 100));
+                return answer;
+            }
+        }
+        return new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN);
+    }
+
+    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        DataStoreTO store = cmd.getStore();
+        if (store instanceof S3TO || store instanceof SwiftTO) {
+            long infinity = Integer.MAX_VALUE;
+            return new GetStorageStatsAnswer(cmd, infinity, 0L);
+        }
+
+        String rootDir = getRootDir(((NfsTO)store).getUrl(), cmd.getNfsVersion());
+        final long usedSize = getUsedSize(rootDir);
+        final long totalSize = getTotalSize(rootDir);
+        if (usedSize == -1 || totalSize == -1) {
+            return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+        } else {
+            return new GetStorageStatsAnswer(cmd, totalSize, usedSize);
+        }
+    }
+
+    protected Answer execute(final DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataObjectType objType = obj.getObjectType();
+        if (obj.getPath() == null) {
+            // account for those fake entries for NFS migration to object store
+            return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
+        }
+        switch (objType) {
+        case TEMPLATE:
+            return deleteTemplate(cmd);
+        case VOLUME:
+            return deleteVolume(cmd);
+        case SNAPSHOT:
+            return deleteSnapshot(cmd);
+        }
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    protected Answer deleteTemplate(DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeTemplatePath = obj.getPath();
+            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
+
+            if (relativeTemplatePath.startsWith(File.separator)) {
+                relativeTemplatePath = relativeTemplatePath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteTemplatePath = parent + relativeTemplatePath;
+            File tmpltPath = new File(absoluteTemplatePath);
+            File tmpltParent = null;
+            if (tmpltPath.exists() && tmpltPath.isDirectory()) {
+                tmpltParent = tmpltPath;
+            } else {
+                tmpltParent = tmpltPath.getParentFile();
+            }
+
+            String details = null;
+            if (!tmpltParent.exists()) {
+                details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, true, details);
+            }
+            File[] tmpltFiles = tmpltParent.listFiles();
+            if (tmpltFiles == null || tmpltFiles.length == 0) {
+                details = "No files under template parent directory " + tmpltParent.getName();
+                s_logger.debug(details);
+            } else {
+                boolean found = false;
+                for (File f : tmpltFiles) {
+                    if (!found && f.getName().equals(_tmpltpp)) {
+                        found = true;
+                    }
+
+                    // KVM HA monitor makes a mess in the templates with its
+                    // heartbeat tests
+                    // Don't let this stop us from cleaning up the template
+                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
+                        s_logger.debug("Deleting KVMHA directory contents from template location");
+                        File[] haFiles = f.listFiles();
+                        for (File haFile : haFiles) {
+                            haFile.delete();
+                        }
+                    }
+
+                    if (!f.delete()) {
+                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
+                    }
+                }
+
+                if (!found) {
+                    details = "Can not find template.properties under " + tmpltParent.getName();
+                    s_logger.debug(details);
+                }
+            }
+            if (!tmpltParent.delete()) {
+                details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            SwiftTO swift = (SwiftTO)dstore;
+            String container = "T-" + obj.getId();
+            String object = "";
+
+            try {
+                String result = swiftDelete(swift, container, object);
+                if (result != null) {
+                    String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
+                    s_logger.warn(errMsg);
+                    return new Answer(cmd, false, errMsg);
+                }
+                return new Answer(cmd, true, "success");
+            } catch (Exception e) {
+                String errMsg = cmd + " Command failed due to " + e.toString();
+                s_logger.warn(errMsg, e);
+                return new Answer(cmd, false, errMsg);
+            }
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+    }
+
+    protected Answer deleteVolume(final DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeVolumePath = obj.getPath();
+            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
+
+            if (relativeVolumePath.startsWith(File.separator)) {
+                relativeVolumePath = relativeVolumePath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteVolumePath = parent + relativeVolumePath;
+            File volPath = new File(absoluteVolumePath);
+            File tmpltParent = null;
+            if (volPath.exists() && volPath.isDirectory()) {
+                // for vmware, absoluteVolumePath represents a directory where volume files are located.
+                tmpltParent = volPath;
+            } else {
+                // for other hypervisors, the volume .vhd or .qcow2 file path is passed
+                tmpltParent = new File(absoluteVolumePath).getParentFile();
+            }
+            String details = null;
+            if (!tmpltParent.exists()) {
+                details = "volume parent directory " + tmpltParent.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, true, details);
+            }
+            File[] tmpltFiles = tmpltParent.listFiles();
+            if (tmpltFiles == null || tmpltFiles.length == 0) {
+                details = "No files under volume parent directory " + tmpltParent.getName();
+                s_logger.debug(details);
+            } else {
+                boolean found = false;
+                for (File f : tmpltFiles) {
+                    if (!found && f.getName().equals("volume.properties")) {
+                        found = true;
+                    }
+
+                    // KVM HA monitor makes a mess in the templates with its
+                    // heartbeat tests
+                    // Don't let this stop us from cleaning up the template
+                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
+                        s_logger.debug("Deleting KVMHA directory contents from template location");
+                        File[] haFiles = f.listFiles();
+                        for (File haFile : haFiles) {
+                            haFile.delete();
+                        }
+                    }
+
+                    if (!f.delete()) {
+                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
+                    }
+                }
+                if (!found) {
+                    details = "Can not find volume.properties under " + tmpltParent.getName();
+                    s_logger.debug(details);
+                }
+            }
+            if (!tmpltParent.delete()) {
+                details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + tmpltParent.getPath();
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            Long volumeId = obj.getId();
+            String path = obj.getPath();
+            String filename = StringUtils.substringAfterLast(path, "/"); // assuming
+            // that
+            // the
+            // filename
+            // is
+            // the
+            // last
+            // section
+            // in
+            // the
+            // path
+            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
+            if (result != null) {
+                String errMsg = "failed to delete volume " + filename + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "Deleted volume " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    @Override
+    synchronized public String getRootDir(String secUrl, Integer nfsVersion) {
+        if (!_inSystemVM) {
+            return _parent;
+        }
+        try {
+            URI uri = new URI(secUrl);
+            String dir = mountUri(uri, nfsVersion);
+            return _parent + "/" + dir;
+        } catch (Exception e) {
+            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    protected long getUsedSize(String rootDir) {
+        return _storage.getUsedSpace(rootDir);
+    }
+
+    protected long getTotalSize(String rootDir) {
+        return _storage.getTotalSpace(rootDir);
+    }
+
+    protected long convertFilesystemSize(final String size) {
+        if (size == null || size.isEmpty()) {
+            return -1;
+        }
+
+        long multiplier = 1;
+        if (size.endsWith("T")) {
+            multiplier = 1024l * 1024l * 1024l * 1024l;
+        } else if (size.endsWith("G")) {
+            multiplier = 1024l * 1024l * 1024l;
+        } else if (size.endsWith("M")) {
+            multiplier = 1024l * 1024l;
+        } else {
+            assert (false) : "Well, I have no idea what this is: " + size;
+        }
+
+        return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
+    }
+
+    @Override
+    public Type getType() {
+        if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) {
+            return Host.Type.SecondaryStorage;
+        }
+
+        return Host.Type.SecondaryStorageCmdExecutor;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(final long id) {
+        return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _eth1ip = (String)params.get("eth1ip");
+        _eth1mask = (String)params.get("eth1mask");
+        if (_eth1ip != null) { // can only happen inside service vm
+            params.put("private.network.device", "eth1");
+        } else {
+            s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
+        }
+        String eth2ip = (String)params.get("eth2ip");
+        if (eth2ip != null) {
+            params.put("public.network.device", "eth2");
+        }
+        _publicIp = (String)params.get("eth2ip");
+        _hostname = (String)params.get("name");
+
+        String inSystemVM = (String)params.get("secondary.storage.vm");
+        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+            s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
+            _inSystemVM = true;
+        }
+
+        _storageIp = (String)params.get("storageip");
+        if (_storageIp == null && _inSystemVM) {
+            s_logger.warn("There is no storageip in /proc/cmdline, something wrong!");
+        }
+        _storageNetmask = (String)params.get("storagenetmask");
+        _storageGateway = (String)params.get("storagegateway");
+        super.configure(name, params);
+
+        _params = params;
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
+
+        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+        configureStorageLayerClass(params);
+
+        if (_inSystemVM) {
+            _storage.mkdirs(_parent);
+        }
+
+        _configSslScr = Script.findScript(getDefaultScriptsDir(), "config_ssl.sh");
+        if (_configSslScr != null) {
+            s_logger.info("config_ssl.sh found in " + _configSslScr);
+        }
+
+        _configAuthScr = Script.findScript(getDefaultScriptsDir(), "config_auth.sh");
+        if (_configAuthScr != null) {
+            s_logger.info("config_auth.sh found in " + _configAuthScr);
+        }
+
+        _configIpFirewallScr = Script.findScript(getDefaultScriptsDir(), "ipfirewall.sh");
+        if (_configIpFirewallScr != null) {
+            s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
+        }
+
+        createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
+        if (createTemplateFromSnapshotXenScript == null) {
+            throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
+        }
+
+        _role = (String)params.get("role");
+        if (_role == null) {
+            _role = SecondaryStorageVm.Role.templateProcessor.toString();
+        }
+        s_logger.info("Secondary storage runs in role " + _role);
+
+        _guid = (String)params.get("guid");
+        if (_guid == null) {
+            throw new ConfigurationException("Unable to find the guid");
+        }
+
+        _dc = (String)params.get("zone");
+        if (_dc == null) {
+            throw new ConfigurationException("Unable to find the zone");
+        }
+        _pod = (String)params.get("pod");
+
+        _instance = (String)params.get("instance");
+
+        if (!_inSystemVM) {
+            _parent = (String)params.get("mount.path");
+        }
+
+        if (_inSystemVM) {
+            _localgw = (String)params.get("localgw");
+            if (_localgw != null) { // can only happen inside service vm
+                String mgmtHost = (String)params.get("host");
+                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+
+                String internalDns1 = (String)params.get("internaldns1");
+                if (internalDns1 == null) {
+                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
+                } else {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+                }
+
+                String internalDns2 = (String)params.get("internaldns2");
+                if (internalDns2 != null) {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+                }
+
+            }
+
+            startAdditionalServices();
+            _params.put("install.numthreads", "50");
+            _params.put("secondary.storage.vm", "true");
+            _nfsVersion = retrieveNfsVersionFromParams(params);
+        }
+
+        try {
+            _params.put(StorageLayer.InstanceConfigKey, _storage);
+            _dlMgr = new DownloadManagerImpl();
+            _dlMgr.configure("DownloadManager", _params);
+            _upldMgr = new UploadManagerImpl();
+            _upldMgr.configure("UploadManager", params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Caught problem while configuring DownloadManager", e);
+            return false;
+        }
+        return true;
+    }
+
+    protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
+        String value;
+        if (_storage == null) {
+            value = (String)params.get(StorageLayer.ClassConfigKey);
+            if (value == null) {
+                value = "com.cloud.storage.JavaStorageLayer";
+            }
+
+            try {
+                Class<?> clazz = Class.forName(value);
+                _storage = (StorageLayer)clazz.newInstance();
+                _storage.configure("StorageLayer", params);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            } catch (InstantiationException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            } catch (IllegalAccessException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            }
+        }
+    }
+
+    private void startAdditionalServices() {
+        if (!_inSystemVM) {
+            return;
+        }
+        Script command = new Script("/bin/systemctl", s_logger);
+        command.add("restart");
+        command.add("ssh");
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in starting sshd service err=" + result);
+        }
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in opening up ssh port err=" + result);
+        }
+    }
+
+    private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
+        if (!_inSystemVM) {
+            return;
+        }
+        s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
+        if (destIpOrCidr == null) {
+            s_logger.debug("addRouteToInternalIp: destIp is null");
+            return;
+        }
+        if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) {
+            s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
+            return;
+        }
+        boolean inSameSubnet = false;
+        if (NetUtils.isValidIp4(destIpOrCidr)) {
+            if (eth1ip != null && eth1mask != null) {
+                inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
+            } else {
+                s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
+            }
+        } else {
+            inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
+        }
+        if (inSameSubnet) {
+            s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
+            return;
+        }
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route delete " + destIpOrCidr);
+        command.execute();
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route add " + destIpOrCidr + " via " + localgw);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in configuring route to internal ip err=" + result);
+        } else {
+            s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
+        }
+    }
+
+    private void configureSSL() {
+        if (!_inSystemVM) {
+            return;
+        }
+        Script command = new Script(_configSslScr);
+        command.add("-i", _publicIp);
+        command.add("-h", _hostname);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use ssl");
+        }
+    }
+
+    private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath, String rootCACert) {
+        if (!_inSystemVM) {
+            return;
+        }
+        Script command = new Script(_configSslScr);
+        command.add("-i", _publicIp);
+        command.add("-h", _hostname);
+        command.add("-k", prvkeyPath);
+        command.add("-p", prvCertPath);
+        if (certChainPath != null) {
+            command.add("-t", certChainPath);
+        }
+        if (rootCACert != null) {
+            command.add("-u", rootCACert);
+        }
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use ssl");
+        }
+    }
+
+    private String configureAuth(String user, String passwd) {
+        Script command = new Script(_configAuthScr);
+        command.add(user);
+        command.add(passwd);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use auth");
+        }
+        return result;
+    }
+
+    private String configureIpFirewall(List<String> ipList, boolean isAppend) {
+        Script command = new Script(_configIpFirewallScr);
+        command.add(String.valueOf(isAppend));
+        for (String ip : ipList) {
+            command.add(ip);
+        }
+
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure firewall for command : " + command);
+        }
+        return result;
+    }
+
+    /**
+     * Mount remote device named on local file system on subfolder of _parent
+     * field.
+     * <p>
+     *
+     * Supported schemes are "nfs" and "cifs".
+     * <p>
+     *
+     * CIFS parameters are documented with mount.cifs at
+     * http://linux.die.net/man/8/mount.cifs
+     * For simplicity, when a URI is used to specify a CIFS share,
+     * options such as domain,user,password are passed as query parameters.
+     *
+     * @param uri
+     *            crresponding to the remote device. Will throw for unsupported
+     *            scheme.
+     * @param nfsVersion NFS version to use in mount command
+     * @return name of folder in _parent that device was mounted.
+     * @throws UnknownHostException
+     */
+    protected String mountUri(URI uri, Integer nfsVersion) throws UnknownHostException {
+        String uriHostIp = getUriHostIp(uri);
+        String nfsPath = uriHostIp + ":" + uri.getPath();
+
+        // Single means of calculating mount directory regardless of scheme
+        String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes(com.cloud.utils.StringUtils.getPreferredCharset())).toString();
+        String localRootPath = _parent + "/" + dir;
+
+        // remote device syntax varies by scheme.
+        String remoteDevice;
+        if (uri.getScheme().equals("cifs")) {
+            remoteDevice = "//" + uriHostIp + uri.getPath();
+            s_logger.debug("Mounting device with cifs-style path of " + remoteDevice);
+        } else {
+            remoteDevice = nfsPath;
+            s_logger.debug("Mounting device with nfs-style path of " + remoteDevice);
+        }
+        mount(localRootPath, remoteDevice, uri, nfsVersion);
+        return dir;
+    }
+
+    protected void mount(String localRootPath, String remoteDevice, URI uri, Integer nfsVersion) {
+        s_logger.debug("mount " + uri.toString() + " on " + localRootPath + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
+        ensureLocalRootPathExists(localRootPath, uri);
+
+        if (mountExists(localRootPath, uri)) {
+            return;
+        }
+
+        attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
+
+        // XXX: Adding the check for creation of snapshots dir here. Might have
+        // to move it somewhere more logical later.
+        checkForSnapshotsDir(localRootPath);
+        checkForVolumesDir(localRootPath);
+    }
+
+    protected void attemptMount(String localRootPath, String remoteDevice, URI uri, Integer nfsVersion) {
+        String result;
+        s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
+        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+
+        String scheme = uri.getScheme().toLowerCase();
+        command.add("-t", scheme);
+
+        if (scheme.equals("nfs")) {
+            if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
+                // See http://wiki.qnap.com/wiki/Mounting_an_NFS_share_from_OS_X
+                command.add("-o", "resvport");
+            }
+            if (_inSystemVM) {
+                command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0" + ((nfsVersion != null) ? ",vers=" + nfsVersion : ""));
+            }
+        } else if (scheme.equals("cifs")) {
+            String extraOpts = parseCifsMountOptions(uri);
+
+            // nfs acdirmax / acdirmin correspoonds to CIFS actimeo (see
+            // http://linux.die.net/man/8/mount.cifs)
+            // no equivalent to nfs timeo, retrans or tcp in CIFS
+            // todo: allow security mode to be set.
+            command.add("-o", extraOpts + "soft,actimeo=0");
+        } else {
+            String errMsg = "Unsupported storage device scheme " + scheme + " in uri " + uri.toString();
+            s_logger.error(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+
+        command.add(remoteDevice);
+        command.add(localRootPath);
+        result = command.execute();
+        if (result != null) {
+            // Fedora Core 12 errors out with any -o option executed from java
+            String errMsg = "Unable to mount " + remoteDevice + " at " + localRootPath + " due to " + result;
+            s_logger.error(errMsg);
+            File file = new File(localRootPath);
+            if (file.exists()) {
+                file.delete();
+            }
+            throw new CloudRuntimeException(errMsg);
+        }
+        s_logger.debug("Successfully mounted " + remoteDevice + " at " + localRootPath);
+    }
+
+    protected String parseCifsMountOptions(URI uri) {
+        List<NameValuePair> args = URLEncodedUtils.parse(uri, "UTF-8");
+        boolean foundUser = false;
+        boolean foundPswd = false;
+        StringBuilder extraOpts = new StringBuilder();
+        for (NameValuePair nvp : args) {
+            String name = nvp.getName();
+            if (name.equals("user")) {
+                foundUser = true;
+                s_logger.debug("foundUser is" + foundUser);
+            } else if (name.equals("password")) {
+                foundPswd = true;
+                s_logger.debug("password is present in uri");
+            }
+
+            extraOpts.append(name + "=" + nvp.getValue() + ",");
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.error("extraOpts now " + extraOpts);
+        }
+
+        if (!foundUser || !foundPswd) {
+            String errMsg = "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'.  E.g. "
+                    + "cifs://example.com/some_share?user=foo&password=bar";
+            s_logger.error(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+        return extraOpts.toString();
+    }
+
+    protected boolean mountExists(String localRootPath, URI uri) {
+        Script script = null;
+        script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+
+        List<String> res = new ArrayList<String>();
+        ZfsPathParser parser = new ZfsPathParser(localRootPath);
+        script.execute(parser);
+        res.addAll(parser.getPaths());
+        for (String s : res) {
+            if (s.contains(localRootPath)) {
+                s_logger.debug("Some device already mounted at " + localRootPath + ", no need to mount " + uri.toString());
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected void ensureLocalRootPathExists(String localRootPath, URI uri) {
+        s_logger.debug("making available " + localRootPath + " on " + uri.toString());
+        File file = new File(localRootPath);
+        s_logger.debug("local folder for mount will be " + file.getPath());
+        if (!file.exists()) {
+            s_logger.debug("create mount point: " + file.getPath());
+            _storage.mkdir(file.getPath());
+
+            // Need to check after mkdir to allow O/S to complete operation
+            if (!file.exists()) {
+                String errMsg = "Unable to create local folder for: " + localRootPath + " in order to mount " + uri.toString();
+                s_logger.error(errMsg);
+                throw new CloudRuntimeException(errMsg);
+            }
+        }
+    }
+
+    protected String getUriHostIp(URI uri) throws UnknownHostException {
+        String nfsHost = uri.getHost();
+        InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+        String nfsHostIp = nfsHostAddr.getHostAddress();
+        s_logger.info("Determined host " + nfsHost + " corresponds to IP " + nfsHostIp);
+        return nfsHostIp;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+
+        final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
+        fillNetworkInformation(cmd);
+        if (_publicIp != null) {
+            cmd.setPublicIpAddress(_publicIp);
+        }
+
+        if (_inSystemVM) {
+            Script command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            command.add("ln -sf " + _parent + " /var/www/html/copy");
+            String result = command.execute();
+            if (result != null) {
+                s_logger.warn("Error in linking  err=" + result);
+                return null;
+            }
+        }
+        return new StartupCommand[] {cmd};
+    }
+
+    protected boolean checkForSnapshotsDir(String mountPoint) {
+        String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
+        return createDir("snapshots", snapshotsDirLocation, mountPoint);
+    }
+
+    protected boolean checkForVolumesDir(String mountPoint) {
+        String volumesDirLocation = mountPoint + "/" + "volumes";
+        return createDir("volumes", volumesDirLocation, mountPoint);
+    }
+
+    protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
+        boolean dirExists = false;
+
+        File dir = new File(dirLocation);
+        if (dir.exists()) {
+            if (dir.isDirectory()) {
+                s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
+                dirExists = true;
+            } else {
+                if (dir.delete() && _storage.mkdir(dirLocation)) {
+                    dirExists = true;
+                }
+            }
+        } else if (_storage.mkdir(dirLocation)) {
+            dirExists = true;
+        }
+
+        if (dirExists) {
+            s_logger.info(dirName + " directory created/exists on Secondary Storage.");
+        } else {
+            s_logger.info(dirName + " directory does not exist on Secondary Storage.");
+        }
+
+        return dirExists;
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return "./scripts/storage/secondary";
+    }
+
+    @Override
+    public void setName(String name) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void fillNetworkInformation(final StartupCommand cmd) {
+        final String dummyMac = "00:06:0A:0B:0C:0D";
+        final String dummyNetmask = "255.255.255.0";
+        if (!_inSystemVM) {
+            cmd.setPrivateIpAddress(_eth1ip);
+            cmd.setPrivateMacAddress(dummyMac);
+            cmd.setPrivateNetmask(dummyNetmask);
+            cmd.setPublicIpAddress(_publicIp);
+            cmd.setPublicMacAddress(dummyMac);
+            cmd.setPublicNetmask(dummyNetmask);
+            cmd.setName(_hostname);
+        } else {
+            super.fillNetworkInformation(cmd);
+        }
+    }
+
+    private String getScriptLocation(UploadEntity.ResourceType resourceType) {
+
+        String scriptsDir = (String)_params.get("template.scripts.dir");
+        if (scriptsDir == null) {
+            scriptsDir = "scripts/storage/secondary";
+        }
+        String scriptname = null;
+        if (resourceType == UploadEntity.ResourceType.VOLUME) {
+            scriptname = "createvolume.sh";
+        } else if (resourceType == UploadEntity.ResourceType.TEMPLATE) {
+            scriptname = "createtmplt.sh";
+        } else {
+            throw new InvalidParameterValueException("cannot find script for resource type: " + resourceType);
+        }
+        return Script.findScript(scriptsDir, scriptname);
+    }
+
+    public UploadEntity createUploadEntity(String uuid, String metadata, long contentLength) {
+        TemplateOrVolumePostUploadCommand cmd = getTemplateOrVolumePostUploadCmd(metadata);
+        UploadEntity uploadEntity = null;
+        if (cmd == null) {
+            String errorMessage = "unable decode and deserialize metadata.";
+            updateStateMapWithError(uuid, errorMessage);
+            throw new InvalidParameterValueException(errorMessage);
+        } else {
+            uuid = cmd.getEntityUUID();
+            processTimeout = cmd.getProcessTimeout();
+            if (isOneTimePostUrlUsed(cmd)) {
+                uploadEntity = uploadEntityStateMap.get(uuid);
+                StringBuilder errorMessage = new StringBuilder("The one time post url is already used");
+                if (uploadEntity != null) {
+                    errorMessage.append(" and the upload is in ").append(uploadEntity.getUploadState()).append(" state.");
+                }
+                throw new InvalidParameterValueException(errorMessage.toString());
+            }
+            int maxSizeInGB = Integer.parseInt(cmd.getMaxUploadSize());
+            int contentLengthInGB = getSizeInGB(contentLength);
+            if (contentLengthInGB > maxSizeInGB) {
+                String errorMessage = "Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " + maxSizeInGB + "GB.";
+                updateStateMapWithError(uuid, errorMessage);
+                throw new InvalidParameterValueException(errorMessage);
+            }
+            checkSecondaryStorageResourceLimit(cmd, contentLengthInGB);
+            try {
+                String absolutePath = cmd.getAbsolutePath();
+                uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
+                uploadEntity.setMetaDataPopulated(true);
+                uploadEntity.setResourceType(UploadEntity.ResourceType.valueOf(cmd.getType()));
+                uploadEntity.setProcessTimeout(processTimeout);
+                uploadEntity.setFormat(Storage.ImageFormat.valueOf(cmd.getImageFormat()));
+                //relative path with out ssvm mount info.
+                uploadEntity.setTemplatePath(absolutePath);
+                String dataStoreUrl = cmd.getDataTo();
+                String installPathPrefix = this.getRootDir(dataStoreUrl, cmd.getNfsVersion()) + File.separator + absolutePath;
+                uploadEntity.setInstallPathPrefix(installPathPrefix);
+                uploadEntity.setHvm(cmd.getRequiresHvm());
+                uploadEntity.setChksum(cmd.getChecksum());
+                uploadEntity.setMaxSizeInGB(maxSizeInGB);
+                uploadEntity.setDescription(cmd.getDescription());
+                uploadEntity.setContentLength(contentLength);
+                // create a install dir
+                if (!_storage.exists(installPathPrefix)) {
+                    _storage.mkdir(installPathPrefix);
+                }
+                uploadEntityStateMap.put(uuid, uploadEntity);
+            } catch (Exception e) {
+                //upload entity will be null incase an exception occurs and the handler will not proceed.
+                s_logger.error("exception occurred while creating upload entity ", e);
+                updateStateMapWithError(uuid, e.getMessage());
+            }
+        }
+        return uploadEntity;
+    }
+
+    private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
+        String rootDir = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator;
+        long accountId = cmd.getAccountId();
+
+        long accountTemplateDirSize = 0;
+        File accountTemplateDir = new File(rootDir + getTemplatePathForAccount(accountId));
+        if (accountTemplateDir.exists()) {
+            FileUtils.sizeOfDirectory(accountTemplateDir);
+        }
+        long accountVolumeDirSize = 0;
+        File accountVolumeDir = new File(rootDir + getVolumePathForAccount(accountId));
+        if (accountVolumeDir.exists()) {
+            accountVolumeDirSize = FileUtils.sizeOfDirectory(accountVolumeDir);
+        }
+        long accountSnapshotDirSize = 0;
+        File accountSnapshotDir = new File(rootDir + getSnapshotPathForAccount(accountId));
+        if (accountSnapshotDir.exists()) {
+            accountSnapshotDirSize = FileUtils.sizeOfDirectory(accountSnapshotDir);
+        }
+        s_logger.debug(
+                "accountTemplateDirSize: " + accountTemplateDirSize + " accountSnapshotDirSize: " + accountSnapshotDirSize + " accountVolumeDirSize: " + accountVolumeDirSize);
+
+        int accountDirSizeInGB = getSizeInGB(accountTemplateDirSize + accountSnapshotDirSize + accountVolumeDirSize);
+        int defaultMaxAccountSecondaryStorageInGB = Integer.parseInt(cmd.getDefaultMaxAccountSecondaryStorage());
+
+        if (defaultMaxAccountSecondaryStorageInGB != Resource.RESOURCE_UNLIMITED && (accountDirSizeInGB + contentLengthInGB) > defaultMaxAccountSecondaryStorageInGB) {
+            s_logger.error("accountDirSizeInGb: " + accountDirSizeInGB + " defaultMaxAccountSecondaryStorageInGB: " + defaultMaxAccountSecondaryStorageInGB + " contentLengthInGB:"
+                    + contentLengthInGB);
+            String errorMessage = "Maximum number of resources of type secondary_storage for account has exceeded";
+            updateStateMapWithError(cmd.getEntityUUID(), errorMessage);
+            throw new InvalidParameterValueException(errorMessage);
+        }
+    }
+
+    private String getVolumePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + accountId;
+    }
+
+    private String getTemplatePathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + accountId;
+    }
+
+    private String getSnapshotPathForAccount(long accountId) {
+        return TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId;
+    }
+
+    private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
+        String uuid = cmd.getEntityUUID();
+        String uploadPath = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator + cmd.getAbsolutePath();
+        return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
+    }
+
+    private int getSizeInGB(long sizeInBytes) {
+        return (int)Math.ceil(sizeInBytes * 1.0d / (1024 * 1024 * 1024));
+    }
+
+    public String postUpload(String uuid, String filename, long processTimeout) {
+        UploadEntity uploadEntity = uploadEntityStateMap.get(uuid);
+        int installTimeoutPerGig = 180 * 60 * 1000;
+
+        String resourcePath = uploadEntity.getInstallPathPrefix();
+        String finalResourcePath = uploadEntity.getTmpltPath(); // template download
+        UploadEntity.ResourceType resourceType = uploadEntity.getResourceType();
+
+        String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
+
+        String uploadedFileExtension = FilenameUtils.getExtension(filename);
+        String userSelectedFormat = uploadEntity.getFormat().toString();
+        if (uploadedFileExtension.equals("zip") || uploadedFileExtension.equals("bz2") || uploadedFileExtension.equals("gz")) {
+            userSelectedFormat += "." + uploadedFileExtension;
+        }
+        String formatError = ImageStoreUtil.checkTemplateFormat(fileSavedTempLocation, userSelectedFormat);
+        if (StringUtils.isNotBlank(formatError)) {
+            String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + userSelectedFormat + ". Received: " + formatError;
+            s_logger.error(errorString);
+            return errorString;
+        }
+
+        int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
+        int maxSize = uploadEntity.getMaxSizeInGB();
+        if (imgSizeGigs > maxSize) {
+            String errorMessage = "Maximum file upload size exceeded. Physical file size: " + imgSizeGigs + "GB. Maximum allowed size: " + maxSize + "GB.";
+            s_logger.error(errorMessage);
+            return errorMessage;
+        }
+        imgSizeGigs++; // add one just in case
+        long timeout = (long)imgSizeGigs * installTimeoutPerGig;
+        Script scr = new Script(getScriptLocation(resourceType), timeout, s_logger);
+        scr.add("-s", Integer.toString(imgSizeGigs));
+        scr.add("-S", Long.toString(UploadEntity.s_maxTemplateSize));
+        if (uploadEntity.getDescription() != null && uploadEntity.getDescription().length() > 1) {
+            scr.add("-d", uploadEntity.getDescription());
+        }
+        if (uploadEntity.isHvm()) {
+            scr.add("-h");
+        }
+        String checkSum = uploadEntity.getChksum();
+        if (StringUtils.isNotBlank(checkSum)) {
+            scr.add("-c", checkSum);
+        }
+
+        // add options common to ISO and template
+        String extension = uploadEntity.getFormat().getFileExtension();
+        String templateName = "";
+        if (extension.equals("iso")) {
+            templateName = uploadEntity.getUuid().trim().replace(" ", "_");
+        } else {
+            try {
+                templateName = UUID.nameUUIDFromBytes((uploadEntity.getFilename() + System.currentTimeMillis()).getBytes("UTF-8")).toString();
+            } catch (UnsupportedEncodingException e) {
+                templateName = uploadEntity.getUuid().trim().replace(" ", "_");
+            }
+        }
+
+        // run script to mv the temporary template file to the final template
+        // file
+        String templateFilename = templateName + "." + extension;
+        uploadEntity.setTemplatePath(finalResourcePath + "/" + templateFilename);
+        scr.add("-n", templateFilename);
+
+        scr.add("-t", resourcePath);
+        scr.add("-f", fileSavedTempLocation); // this is the temporary
+        // template file downloaded
+        if (uploadEntity.getChksum() != null && uploadEntity.getChksum().length() > 1) {
+            scr.add("-c", uploadEntity.getChksum());
+        }
+        scr.add("-u"); // cleanup
+        String result;
+        result = scr.execute();
+
+        if (result != null) {
+            return result;
+        }
+
+        // Set permissions for the downloaded template
+        File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
+        _storage.setWorldReadableAndWriteable(downloadedTemplate);
+
+        // Set permissions for template/volume.properties
+        String propertiesFile = resourcePath;
+        if (resourceType == UploadEntity.ResourceType.TEMPLATE) {
+            propertiesFile += "/template.properties";
+        } else {
+            propertiesFile += "/volume.properties";
+        }
+        File templateProperties = new File(propertiesFile);
+        _storage.setWorldReadableAndWriteable(templateProperties);
+
+        TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
+        try {
+            loc.create(uploadEntity.getEntityId(), true, uploadEntity.getFilename());
+        } catch (IOException e) {
+            s_logger.warn("Something is wrong with template location " + resourcePath, e);
+            loc.purge();
+            return "Unable to upload due to " + e.getMessage();
+        }
+
+        Map<String, Processor> processors = _dlMgr.getProcessors();
+        for (Processor processor : processors.values()) {
+            FormatInfo info = null;
+            try {
+                info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
+            } catch (InternalErrorException e) {
+                s_logger.error("Template process exception ", e);
+                return e.toString();
+            }
+            if (info != null) {
+                loc.addFormat(info);
+                uploadEntity.setVirtualSize(info.virtualSize);
+                uploadEntity.setPhysicalSize(info.size);
+                break;
+            }
+        }
+
+        if (!loc.save()) {
+            s_logger.warn("Cleaning up because we're unable to save the formats");
+            loc.purge();
+        }
+        uploadEntity.setStatus(UploadEntity.Status.COMPLETED);
+        uploadEntityStateMap.put(uploadEntity.getUuid(), uploadEntity);
+        return null;
+    }
+
+    private String getPostUploadPSK() {
+        if (_ssvmPSK == null) {
+            try {
+                _ssvmPSK = FileUtils.readFileToString(new File(POST_UPLOAD_KEY_LOCATION), "utf-8");
+            } catch (IOException e) {
+                s_logger.debug("Error while reading SSVM PSK from location " + POST_UPLOAD_KEY_LOCATION, e);
+            }
+        }
+        return _ssvmPSK;
+    }
+
+    public void updateStateMapWithError(String uuid, String errorMessage) {
+        UploadEntity uploadEntity = null;
+        if (uploadEntityStateMap.get(uuid) != null) {
+            uploadEntity = uploadEntityStateMap.get(uuid);
+        } else {
+            uploadEntity = new UploadEntity();
+        }
+        uploadEntity.setStatus(UploadEntity.Status.ERROR);
+        uploadEntity.setErrorMessage(errorMessage);
+        uploadEntityStateMap.put(uuid, uploadEntity);
+    }
+
+    public void validatePostUploadRequest(String signature, String metadata, String timeout, String hostname, long contentLength, String uuid)
+            throws InvalidParameterValueException {
+        // check none of the params are empty
+        if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(metadata) || StringUtils.isEmpty(timeout)) {
+            updateStateMapWithError(uuid, "signature, metadata and expires are compulsory fields.");
+            throw new InvalidParameterValueException("signature, metadata and expires are compulsory fields.");
+        }
+
+        //check that contentLength exists and is greater than zero
+        if (contentLength <= 0) {
+            throw new InvalidParameterValueException("content length is not set in the request or has invalid value.");
+        }
+
+        //validate signature
+        String fullUrl = "https://" + hostname + "/upload/" + uuid;
+        String computedSignature = EncryptionUtil.generateSignature(metadata + fullUrl + timeout, getPostUploadPSK());
+        boolean isSignatureValid = computedSignature.equals(signature);
+        if (!isSignatureValid) {
+            updateStateMapWithError(uuid, "signature validation failed.");
+            throw new InvalidParameterValueException("signature validation failed.");
+        }
+
+        //validate timeout
+        DateTime timeoutDateTime = DateTime.parse(timeout, ISODateTimeFormat.dateTime());
+        if (timeoutDateTime.isBeforeNow()) {
+            updateStateMapWithError(uuid, "request not valid anymore.");
+            throw new InvalidParameterValueException("request not valid anymore.");
+        }
+    }
+
+    private TemplateOrVolumePostUploadCommand getTemplateOrVolumePostUploadCmd(String metadata) {
+        TemplateOrVolumePostUploadCommand cmd = null;
+        try {
+            Gson gson = new GsonBuilder().create();
+            cmd = gson.fromJson(EncryptionUtil.decodeData(metadata, getPostUploadPSK()), TemplateOrVolumePostUploadCommand.class);
+        } catch (Exception ex) {
+            s_logger.error("exception while decoding and deserialising metadata", ex);
+        }
+        return cmd;
+    }
+
+}
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManager.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManager.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadEntity.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadEntity.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadManager.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadManager.java
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadManagerImpl.java
similarity index 100%
rename from services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
rename to services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/UploadManagerImpl.java
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/server/src/main/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
similarity index 100%
rename from services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
rename to services/secondary-storage/server/src/main/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/server/src/main/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
similarity index 100%
rename from services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
rename to services/secondary-storage/server/src/main/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
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
deleted file mode 100644
index be68f63..0000000
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,3434 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.resource;
-
-import static com.cloud.network.NetworkModel.METATDATA_DIR;
-import static com.cloud.network.NetworkModel.PASSWORD_DIR;
-import static com.cloud.network.NetworkModel.PASSWORD_FILE;
-import static com.cloud.network.NetworkModel.PUBLIC_KEYS_FILE;
-import static com.cloud.network.NetworkModel.USERDATA_DIR;
-import static com.cloud.network.NetworkModel.USERDATA_FILE;
-import static com.cloud.utils.StringUtils.join;
-import static com.cloud.utils.storage.S3.S3Utils.putFile;
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.apache.commons.lang.StringUtils.substringAfterLast;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
-import org.apache.cloudstack.storage.command.UploadStatusAnswer;
-import org.apache.cloudstack.storage.command.UploadStatusAnswer.UploadStatus;
-import org.apache.cloudstack.storage.command.UploadStatusCommand;
-import org.apache.cloudstack.storage.configdrive.ConfigDrive;
-import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder;
-import org.apache.cloudstack.storage.template.DownloadManager;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser;
-import org.apache.cloudstack.storage.template.UploadEntity;
-import org.apache.cloudstack.storage.template.UploadManager;
-import org.apache.cloudstack.storage.template.UploadManagerImpl;
-import org.apache.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
-import org.apache.cloudstack.utils.security.DigestHelper;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.log4j.Logger;
-import org.joda.time.DateTime;
-import org.joda.time.format.ISODateTimeFormat;
-
-import com.amazonaws.services.s3.model.S3ObjectSummary;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CheckHealthAnswer;
-import com.cloud.agent.api.CheckHealthCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ComputeChecksumCommand;
-import com.cloud.agent.api.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.GetStorageStatsAnswer;
-import com.cloud.agent.api.GetStorageStatsCommand;
-import com.cloud.agent.api.HandleConfigDriveIsoCommand;
-import com.cloud.agent.api.PingCommand;
-import com.cloud.agent.api.PingStorageCommand;
-import com.cloud.agent.api.ReadyAnswer;
-import com.cloud.agent.api.ReadyCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
-import com.cloud.agent.api.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.storage.CreateDatadiskTemplateAnswer;
-import com.cloud.agent.api.storage.CreateDatadiskTemplateCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.GetDatadisksAnswer;
-import com.cloud.agent.api.storage.GetDatadisksCommand;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.storage.OVFHelper;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DatadiskTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.configuration.Resource;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.template.OVAProcessor;
-import com.cloud.storage.template.Processor;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.QCOW2Processor;
-import com.cloud.storage.template.RawImageProcessor;
-import com.cloud.storage.template.TARProcessor;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.storage.template.VhdProcessor;
-import com.cloud.storage.template.VmdkProcessor;
-import com.cloud.utils.EncryptionUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.SwiftUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-import com.cloud.utils.storage.S3.S3Utils;
-import com.cloud.vm.SecondaryStorageVm;
-import com.google.common.collect.Maps;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.codec.http.HttpContentCompressor;
-import io.netty.handler.codec.http.HttpRequestDecoder;
-import io.netty.handler.codec.http.HttpResponseEncoder;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-
-public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
-
-    public static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
-
-    private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
-    private static final String VOLUME_ROOT_DIR = "volumes";
-    private static final String POST_UPLOAD_KEY_LOCATION = "/etc/cloudstack/agent/ms-psk";
-
-    private static final Map<String, String> updatableConfigData = Maps.newHashMap();
-    static {
-
-        updatableConfigData.put(PUBLIC_KEYS_FILE, METATDATA_DIR);
-        updatableConfigData.put(USERDATA_FILE, USERDATA_DIR);
-        updatableConfigData.put(PASSWORD_FILE, PASSWORD_DIR);
-    }
-
-    int _timeout;
-
-    public int getTimeout() {
-        return _timeout;
-    }
-
-    public void setTimeout(int timeout) {
-        _timeout = timeout;
-    }
-
-    String _instance;
-    String _dc;
-    String _pod;
-    String _guid;
-    String _role;
-    Map<String, Object> _params;
-    protected StorageLayer _storage;
-    protected boolean _inSystemVM = false;
-    boolean _sslCopy = false;
-
-    protected DownloadManager _dlMgr;
-    protected UploadManager _upldMgr;
-    private String _configSslScr;
-    private String _configAuthScr;
-    private String _configIpFirewallScr;
-    private String _publicIp;
-    private String _hostname;
-    private String _localgw;
-    private String _eth1mask;
-    private String _eth1ip;
-    private String _storageIp;
-    private String _storageNetmask;
-    private String _storageGateway;
-    private Integer _nfsVersion;
-    private final List<String> nfsIps = new ArrayList<String>();
-    protected String _parent = "/mnt/SecStorage";
-    final private String _tmpltpp = "template.properties";
-    protected String createTemplateFromSnapshotXenScript;
-    private HashMap<String, UploadEntity> uploadEntityStateMap = new HashMap<String, UploadEntity>();
-    private String _ssvmPSK = null;
-    private long processTimeout;
-
-    public void setParentPath(String path) {
-        _parent = path;
-    }
-
-    public String getMountingRoot() {
-        return _parent;
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    public void setInSystemVM(boolean inSystemVM) {
-        _inSystemVM = inSystemVM;
-    }
-
-    /**
-     * Applies MTU per the "mtu" value from params
-     * @param params
-     */
-    public static void applyMtu(Map<String, Object> params) {
-        if (params == null || params.get("mtu") == null) {
-            return;
-        }
-        final Integer mtu = NumbersUtil.parseInt((String) params.get("mtu"), 0);
-        if (mtu > 0) {
-            final Script command = new Script("/sbin/ip", s_logger);
-            command.add("link");
-            command.add("set");
-            command.add("dev");
-            command.add("eth1");
-            command.add("mtu");
-            command.add(String.valueOf(mtu));
-            final String result = command.execute();
-            if (result != null) {
-                s_logger.warn("Error in setting MTU on storage/management nic: " + result);
-            }
-        }
-    }
-
-    /**
-     * Retrieve converted "nfsVersion" value from params
-     * @param params
-     * @return nfsVersion value if exists, null in other case
-     */
-    public static Integer retrieveNfsVersionFromParams(Map<String, Object> params) {
-        Integer nfsVersion = null;
-        if (params.get("nfsVersion") != null) {
-            String nfsVersionParam = (String)params.get("nfsVersion");
-            try {
-                nfsVersion = Integer.valueOf(nfsVersionParam);
-            } catch (NumberFormatException e){
-                s_logger.error("Couldn't cast " + nfsVersionParam + " to integer");
-                return null;
-            }
-        }
-        return nfsVersion;
-    }
-
-    @Override
-    public Answer executeRequest(Command cmd) {
-        if (cmd instanceof DownloadProgressCommand) {
-            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
-        } else if (cmd instanceof DownloadCommand) {
-            return execute((DownloadCommand)cmd);
-        } else if (cmd instanceof UploadCommand) {
-            return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
-        } else if (cmd instanceof CreateEntityDownloadURLCommand) {
-            return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
-        } else if (cmd instanceof DeleteEntityDownloadURLCommand) {
-            return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
-        } else if (cmd instanceof GetStorageStatsCommand) {
-            return execute((GetStorageStatsCommand)cmd);
-        } else if (cmd instanceof CheckHealthCommand) {
-            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
-        } else if (cmd instanceof ReadyCommand) {
-            return new ReadyAnswer((ReadyCommand)cmd);
-        } else if (cmd instanceof SecStorageFirewallCfgCommand) {
-            return execute((SecStorageFirewallCfgCommand)cmd);
-        } else if (cmd instanceof SecStorageVMSetupCommand) {
-            return execute((SecStorageVMSetupCommand)cmd);
-        } else if (cmd instanceof SecStorageSetupCommand) {
-            return execute((SecStorageSetupCommand)cmd);
-        } else if (cmd instanceof ComputeChecksumCommand) {
-            return execute((ComputeChecksumCommand)cmd);
-        } else if (cmd instanceof ListTemplateCommand) {
-            return execute((ListTemplateCommand)cmd);
-        } else if (cmd instanceof ListVolumeCommand) {
-            return execute((ListVolumeCommand)cmd);
-        } else if (cmd instanceof DeleteSnapshotsDirCommand) {
-            return execute((DeleteSnapshotsDirCommand)cmd);
-        } else if (cmd instanceof CopyCommand) {
-            return execute((CopyCommand)cmd);
-        } else if (cmd instanceof DeleteCommand) {
-            return execute((DeleteCommand)cmd);
-        } else if (cmd instanceof UploadStatusCommand) {
-            return execute((UploadStatusCommand)cmd);
-        } else if (cmd instanceof HandleConfigDriveIsoCommand) {
-            return execute((HandleConfigDriveIsoCommand)cmd);
-        } else if (cmd instanceof GetDatadisksCommand) {
-            return execute((GetDatadisksCommand)cmd);
-        } else if (cmd instanceof CreateDatadiskTemplateCommand) {
-            return execute((CreateDatadiskTemplateCommand)cmd);
-        } else {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    private Answer execute(HandleConfigDriveIsoCommand cmd) {
-        if (cmd.isCreate()) {
-            if (cmd.getIsoData() == null) {
-                return new Answer(cmd, false, "Invalid config drive ISO data");
-            }
-            String nfsMountPoint = getRootDir(cmd.getDestStore().getUrl(), _nfsVersion);
-            File isoFile = new File(nfsMountPoint, cmd.getIsoFile());
-            if(isoFile.exists()) {
-                s_logger.debug("config drive iso already exists");
-            }
-            Path tempDir = null;
-            try {
-                tempDir = java.nio.file.Files.createTempDirectory(ConfigDrive.CONFIGDRIVEDIR);
-                File tmpIsoFile = ConfigDriveBuilder.base64StringToFile(cmd.getIsoData(), tempDir.toAbsolutePath().toString(), cmd.getIsoFile());
-                copyLocalToNfs(tmpIsoFile, new File(cmd.getIsoFile()), cmd.getDestStore());
-            } catch (IOException | ConfigurationException e) {
-                return new Answer(cmd, false, "Failed due to exception: " + e.getMessage());
-            } finally {
-                try {
-                    if (tempDir != null) {
-                        FileUtils.deleteDirectory(tempDir.toFile());
-                    }
-                } catch (IOException ioe) {
-                    s_logger.warn("Failed to delete ConfigDrive temporary directory: " + tempDir.toString(), ioe);
-                }
-            }
-            return new Answer(cmd, true, "Successfully saved config drive at secondary storage");
-        } else {
-            DataStoreTO dstore = cmd.getDestStore();
-            if (dstore instanceof NfsTO) {
-                NfsTO nfs = (NfsTO) dstore;
-                String relativeTemplatePath = new File(cmd.getIsoFile()).getPath();
-                String nfsMountPoint = getRootDir(nfs.getUrl(), _nfsVersion);
-                File tmpltPath = new File(nfsMountPoint, relativeTemplatePath);
-                try {
-                    Files.deleteIfExists(tmpltPath.toPath());
-                } catch (IOException e) {
-                    return new Answer(cmd, e);
-                }
-                return new Answer(cmd);
-            } else {
-                return new Answer(cmd, false, "Not implemented yet");
-            }
-        }
-    }
-
-    protected void copyLocalToNfs(File localFile, File isoFile, DataStoreTO destData) throws ConfigurationException, IOException {
-        String scriptsDir = "scripts/storage/secondary";
-        String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
-        if (createVolScr == null) {
-            throw new ConfigurationException("Unable to find createvolume.sh");
-        }
-        s_logger.info("createvolume.sh found in " + createVolScr);
-
-        int installTimeoutPerGig = 180 * 60 * 1000;
-        int imgSizeGigs = (int) Math.ceil(localFile.length() * 1.0d / (1024 * 1024 * 1024));
-        imgSizeGigs++; // add one just in case
-        long timeout = imgSizeGigs * installTimeoutPerGig;
-
-        Script scr = new Script(createVolScr, timeout, s_logger);
-        scr.add("-s", Integer.toString(imgSizeGigs));
-        scr.add("-n", isoFile.getName());
-        scr.add("-t", getRootDir(destData.getUrl(), _nfsVersion) + "/" + isoFile.getParent());
-        scr.add("-f", localFile.getAbsolutePath());
-        scr.add("-d", "configDrive");
-        String result;
-        result = scr.execute();
-
-        if (result != null) {
-            // script execution failure
-            throw new CloudRuntimeException("Failed to run script " + createVolScr);
-        }
-    }
-
-    public Answer execute(GetDatadisksCommand cmd) {
-        DataTO srcData = cmd.getData();
-        TemplateObjectTO template = (TemplateObjectTO)srcData;
-        DataStoreTO srcStore = srcData.getDataStore();
-        if (!(srcStore instanceof NfsTO)) {
-            return new CreateDatadiskTemplateAnswer("Unsupported protocol");
-        }
-        NfsTO nfsImageStore = (NfsTO)srcStore;
-        String secondaryStorageUrl = nfsImageStore.getUrl();
-        assert (secondaryStorageUrl != null);
-        String templateUrl = secondaryStorageUrl + File.separator + srcData.getPath();
-        Pair<String, String> templateInfo = decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
-        String templateRelativeFolderPath = templateInfo.first();
-
-        try {
-            String secondaryMountPoint = getRootDir(secondaryStorageUrl, _nfsVersion);
-            s_logger.info("MDOVE Secondary storage mount point: " + secondaryMountPoint);
-
-            String srcOVAFileName = getTemplateOnSecStorageFilePath(secondaryMountPoint, templateRelativeFolderPath, templateInfo.second(), ImageFormat.OVA.getFileExtension());
-
-            String ovfFilePath = getOVFFilePath(srcOVAFileName);
-            if (ovfFilePath == null) {
-                Script command = new Script("tar", 0, s_logger);
-                command.add("--no-same-owner");
-                command.add("--no-same-permissions");
-                command.add("-xf", srcOVAFileName);
-                command.setWorkDir(secondaryMountPoint + File.separator + templateRelativeFolderPath);
-                s_logger.info("Executing command: " + command.toString());
-                String result = command.execute();
-                if (result != null) {
-                    String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-
-                command = new Script("chmod", 0, s_logger);
-                command.add("-R");
-                command.add("666", secondaryMountPoint + File.separator + templateRelativeFolderPath);
-                result = command.execute();
-                if (result != null) {
-                    s_logger.warn("Unable to set permissions for " + secondaryMountPoint + File.separator + templateRelativeFolderPath + " due to " + result);
-                }
-            }
-
-            Script command = new Script("cp", _timeout, s_logger);
-            command.add(ovfFilePath);
-            command.add(ovfFilePath + ".orig");
-            String result = command.execute();
-            if (result != null) {
-                String msg = "Unable to rename original OVF, error msg: " + result;
-                s_logger.error(msg);
-            }
-
-            s_logger.debug("Reading OVF " + ovfFilePath + " to retrive the number of disks present in OVA");
-            OVFHelper ovfHelper = new OVFHelper();
-
-            List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfo(ovfFilePath);
-            return new GetDatadisksAnswer(disks);
-        } catch (Exception e) {
-            String msg = "Get Datadisk Template Count failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new GetDatadisksAnswer(msg);
-        }
-    }
-
-    public Answer execute(CreateDatadiskTemplateCommand cmd) {
-        TemplateObjectTO diskTemplate = new TemplateObjectTO();
-        TemplateObjectTO dataDiskTemplate = (TemplateObjectTO)cmd.getDataDiskTemplate();
-        DataStoreTO dataStore = dataDiskTemplate.getDataStore();
-        if (!(dataStore instanceof NfsTO)) {
-            return new CreateDatadiskTemplateAnswer("Unsupported protocol");
-        }
-        NfsTO nfsImageStore = (NfsTO)dataStore;
-        String secondaryStorageUrl = nfsImageStore.getUrl();
-        assert (secondaryStorageUrl != null);
-
-        try {
-            String secondaryMountPoint = getRootDir(secondaryStorageUrl, _nfsVersion);
-
-            long templateId = dataDiskTemplate.getId();
-            String templateUniqueName = dataDiskTemplate.getUniqueName();
-            String origDisk = cmd.getPath();
-            long virtualSize = dataDiskTemplate.getSize();
-            String diskName = origDisk.substring((origDisk.lastIndexOf(File.separator)) + 1);
-            long physicalSize = new File(origDisk).length();
-            String newTmplDir = getTemplateRelativeDirInSecStorage(dataDiskTemplate.getAccountId(), dataDiskTemplate.getId());
-            String newTmplDirAbsolute = secondaryMountPoint + File.separator + newTmplDir;
-
-            String ovfFilePath = getOVFFilePath(origDisk);
-            if (!cmd.getBootable()) {
-                // Create folder to hold datadisk template
-                synchronized (newTmplDir.intern()) {
-                    Script command = new Script("mkdir", _timeout, s_logger);
-                    command.add("-p");
-                    command.add(newTmplDirAbsolute);
-                    String result = command.execute();
-                    if (result != null) {
-                        String msg = "Unable to prepare template directory: " + newTmplDir + ", storage: " + secondaryStorageUrl + ", error msg: " + result;
-                        s_logger.error(msg);
-                        throw new Exception(msg);
-                    }
-                }
-                // Move Datadisk VMDK from parent template folder to Datadisk template folder
-                synchronized (origDisk.intern()) {
-                    Script command = new Script("mv", _timeout, s_logger);
-                    command.add(origDisk);
-                    command.add(newTmplDirAbsolute);
-                    String result = command.execute();
-                    if (result != null) {
-                        String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
-                        s_logger.error(msg);
-                        throw new Exception(msg);
-                    }
-                    command = new Script("cp", _timeout, s_logger);
-                    command.add(ovfFilePath + ".orig");
-                    command.add(newTmplDirAbsolute);
-                    result = command.execute();
-                    if (result != null) {
-                        String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
-                        s_logger.error(msg);
-                        throw new Exception(msg);
-                    }
-                }
-            }
-
-            // Create OVF for the disk
-            String newOvfFilePath = newTmplDirAbsolute + File.separator + ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1);
-            OVFHelper ovfHelper = new OVFHelper();
-            ovfHelper.rewriteOVFFile(ovfFilePath + ".orig", newOvfFilePath, diskName);
-
-            postCreatePrivateTemplate(newTmplDirAbsolute, templateId, templateUniqueName, physicalSize, virtualSize);
-            writeMetaOvaForTemplate(newTmplDirAbsolute, ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1), diskName, templateUniqueName, physicalSize);
-
-            diskTemplate.setId(templateId);
-            if (diskName.endsWith("iso")){
-                diskTemplate.setPath(newTmplDir + File.separator + diskName);
-            }
-            else {
-                diskTemplate.setPath(newTmplDir + File.separator + templateUniqueName + ".ova");
-            }
-            diskTemplate.setSize(virtualSize);
-            diskTemplate.setPhysicalSize(physicalSize);
-        } catch (Exception e) {
-            String msg = "Create Datadisk template failed due to " + e.getMessage();
-            s_logger.error(msg, e);
-            return new CreateDatadiskTemplateAnswer(msg);
-        }
-        return new CreateDatadiskTemplateAnswer(diskTemplate);
-    }
-
-    /*
-     *  return Pair of <Template relative path, Template name>
-     *  Template url may or may not end with .ova extension
-     */
-    public static Pair<String, String> decodeTemplateRelativePathAndNameFromUrl(String storeUrl, String templateUrl, String defaultName) {
-
-        String templateName = null;
-        String mountPoint = null;
-        if (templateUrl.endsWith(".ova")) {
-            int index = templateUrl.lastIndexOf("/");
-            mountPoint = templateUrl.substring(0, index);
-            mountPoint = mountPoint.substring(storeUrl.length() + 1);
-            if (!mountPoint.endsWith("/")) {
-                mountPoint = mountPoint + "/";
-            }
-
-            templateName = templateUrl.substring(index + 1).replace(".ova", "");
-
-            if (templateName == null || templateName.isEmpty()) {
-                templateName = defaultName;
-            }
-        } else {
-            mountPoint = templateUrl.substring(storeUrl.length() + 1);
-            if (!mountPoint.endsWith("/")) {
-                mountPoint = mountPoint + "/";
-            }
-            templateName = defaultName;
-        }
-
-        return new Pair<String, String>(mountPoint, templateName);
-    }
-
-    public static String getTemplateOnSecStorageFilePath(String secStorageMountPoint, String templateRelativeFolderPath, String templateName, String fileExtension) {
-
-        StringBuffer sb = new StringBuffer();
-        sb.append(secStorageMountPoint);
-        if (!secStorageMountPoint.endsWith("/")) {
-            sb.append("/");
-        }
-
-        sb.append(templateRelativeFolderPath);
-        if (!secStorageMountPoint.endsWith("/")) {
-            sb.append("/");
-        }
-
-        sb.append(templateName);
-        if (!fileExtension.startsWith(".")) {
-            sb.append(".");
-        }
-        sb.append(fileExtension);
-
-        return sb.toString();
-    }
-
-    public static String getSecondaryDatastoreUUID(String storeUrl) {
-        return UUID.nameUUIDFromBytes(storeUrl.getBytes()).toString();
-    }
-
-    private static String getTemplateRelativeDirInSecStorage(long accountId, long templateId) {
-        return "template/tmpl/" + accountId + "/" + templateId;
-    }
-
-    private void postCreatePrivateTemplate(final String installFullPath, final long templateId, final String templateName, final long size, final long virtualSize) throws Exception {
-        // TODO a bit ugly here
-        try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/template.properties"), "UTF-8"));) {
-            out.write("filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("description=privateTemplate");
-            out.newLine();
-            out.write("hvm=false");
-            out.newLine();
-            out.write("size=" + size);
-            out.newLine();
-            out.write("ova=false");
-            out.newLine();
-            out.write("id=" + templateId);
-            out.newLine();
-            out.write("ova.filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("uniquename=" + templateName);
-            out.newLine();
-            out.write("ova.virtualsize=" + virtualSize);
-            out.newLine();
-            out.write("virtualsize=" + virtualSize);
-            out.newLine();
-            out.write("ova.size=" + size);
-            out.newLine();
-            out.write("checksum=");
-            out.newLine();
-            out.write("public=false");
-            out.newLine();
-        }
-    }
-
-    private void writeMetaOvaForTemplate(final String installFullPath, final String ovfFilename, final String vmdkFilename, final String templateName, final long diskSize) throws Exception {
-
-        // TODO a bit ugly here
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName + ".ova.meta"), "UTF-8"));
-            out.write("ova.filename=" + templateName + ".ova");
-            out.newLine();
-            out.write("version=1.0");
-            out.newLine();
-            out.write("ovf=" + ovfFilename);
-            out.newLine();
-            out.write("numDisks=1");
-            out.newLine();
-            out.write("disk1.name=" + vmdkFilename);
-            out.newLine();
-            out.write("disk1.size=" + diskSize);
-            out.newLine();
-        } finally {
-            if (out != null) {
-                out.close();
-            }
-        }
-    }
-
-    private String getOVFFilePath(String srcOVAFileName) {
-        File file = new File(srcOVAFileName);
-        assert (_storage != null);
-        String[] files = _storage.listFiles(file.getParent());
-        if (files != null) {
-            for (String fileName : files) {
-                if (fileName.toLowerCase().endsWith(".ovf")) {
-                    File ovfFile = new File(fileName);
-                    return file.getParent() + File.separator + ovfFile.getName();
-                }
-            }
-        }
-        return null;
-    }
-
-    protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
-        if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
-            SnapshotObjectTO snapshot = new SnapshotObjectTO();
-            snapshot.setPath(destPath + File.separator + destFile.getName());
-
-            CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
-            return answer;
-        }
-        // do post processing to unzip the file if it is compressed
-        String scriptsDir = "scripts/storage/secondary";
-        String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
-        if (createTmpltScr == null) {
-            throw new ConfigurationException("Unable to find createtmplt.sh");
-        }
-        s_logger.info("createtmplt.sh found in " + createTmpltScr);
-        String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
-        if (createVolScr == null) {
-            throw new ConfigurationException("Unable to find createvolume.sh");
-        }
-        s_logger.info("createvolume.sh found in " + createVolScr);
-        String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
-
-        int installTimeoutPerGig = 180 * 60 * 1000;
-        long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
-        imgSizeGigs++; // add one just in case
-        long timeout = imgSizeGigs * installTimeoutPerGig;
-
-        String origPath = destFile.getAbsolutePath();
-        String extension = null;
-        if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
-            extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
-        } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
-            extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
-        }
-
-        String templateName = UUID.randomUUID().toString();
-        String templateFilename = templateName + "." + extension;
-        Script scr = new Script(script, timeout, s_logger);
-        scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
-        scr.add("-n", templateFilename);
-
-        scr.add("-t", downloadPath);
-        scr.add("-f", origPath); // this is the temporary
-        // template file downloaded
-        String result;
-        result = scr.execute();
-
-        if (result != null) {
-            // script execution failure
-            throw new CloudRuntimeException("Failed to run script " + script);
-        }
-
-        String finalFileName = templateFilename;
-        String finalDownloadPath = destPath + File.separator + templateFilename;
-        // compute the size of
-        long size = _storage.getSize(downloadPath + File.separator + templateFilename);
-
-        DataTO newDestTO = null;
-
-        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-            TemplateObjectTO newTemplTO = new TemplateObjectTO();
-            newTemplTO.setPath(finalDownloadPath);
-            newTemplTO.setName(finalFileName);
-            newTemplTO.setSize(size);
-            newTemplTO.setPhysicalSize(size);
-            newDestTO = newTemplTO;
-        } else {
-            VolumeObjectTO newVolTO = new VolumeObjectTO();
-            newVolTO.setPath(finalDownloadPath);
-            newVolTO.setName(finalFileName);
-            newVolTO.setSize(size);
-            newDestTO = newVolTO;
-        }
-
-        return new CopyCmdAnswer(newDestTO);
-    }
-
-    protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
-        final String storagePath = destImageStore.getUrl();
-        final String destPath = destData.getPath();
-        try {
-            String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
-            final File downloadDirectory = _storage.getFile(downloadPath);
-
-            if (downloadDirectory.exists()) {
-                s_logger.debug("Directory " + downloadPath + " already exists");
-            } else {
-                if (!downloadDirectory.mkdirs()) {
-                    final String errMsg = "Unable to create directory " + downloadPath + " to copy from Swift to cache.";
-                    s_logger.error(errMsg);
-                    return new CopyCmdAnswer(errMsg);
-                }
-            }
-
-            File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
-            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy swift to nfs", e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
-        final String storagePath = destImageStore.getUrl();
-        final String destPath = destData.getPath();
-
-        try {
-
-            String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion);
-            final File downloadDirectory = _storage.getFile(downloadPath);
-
-            if (downloadDirectory.exists()) {
-                s_logger.debug("Directory " + downloadPath + " already exists");
-            } else {
-                if (!downloadDirectory.mkdirs()) {
-                    final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
-                    s_logger.error(errMsg);
-                    return new CopyCmdAnswer(errMsg);
-                }
-            }
-            File destFile = new File(downloadDirectory, substringAfterLast(srcData.getPath(), S3Utils.SEPARATOR));
-            S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), destFile).waitForCompletion();
-
-            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
-        } catch (Exception e) {
-
-            final String errMsg = format("Failed to download" + "due to $1%s", e.getMessage());
-            s_logger.error(errMsg, e);
-            return new CopyCmdAnswer(errMsg);
-        }
-    }
-
-    protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
-        String srcMountPoint = getRootDir(srcDataStore.getUrl(), _nfsVersion);
-        String snapshotPath = srcData.getPath();
-        int index = snapshotPath.lastIndexOf("/");
-        String snapshotName = snapshotPath.substring(index + 1);
-        if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
-            snapshotName = snapshotName + ".vhd";
-        }
-        snapshotPath = snapshotPath.substring(0, index);
-
-        snapshotPath = srcMountPoint + File.separator + snapshotPath;
-        String destMountPoint = getRootDir(destDataStore.getUrl(), _nfsVersion);
-        String destPath = destMountPoint + File.separator + destData.getPath();
-
-        String errMsg = null;
-        try {
-            _storage.mkdir(destPath);
-
-            String templateUuid = UUID.randomUUID().toString();
-            String templateName = templateUuid + ".vhd";
-            Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
-            command.add("-p", snapshotPath);
-            command.add("-s", snapshotName);
-            command.add("-n", templateName);
-            command.add("-t", destPath);
-            String result = command.execute();
-
-            if (result != null && !result.equalsIgnoreCase("")) {
-                return new CopyCmdAnswer(result);
-            }
-
-            Map<String, Object> params = new HashMap<String, Object>();
-            params.put(StorageLayer.InstanceConfigKey, _storage);
-            Processor processor = new VhdProcessor();
-
-            processor.configure("Vhd Processor", params);
-            FormatInfo info = processor.process(destPath, null, templateUuid);
-
-            TemplateLocation loc = new TemplateLocation(_storage, destPath);
-            loc.create(1, true, templateUuid);
-            loc.addFormat(info);
-            loc.save();
-            TemplateProp prop = loc.getTemplateInfo();
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(destData.getPath() + File.separator + templateName);
-            newTemplate.setFormat(ImageFormat.VHD);
-            newTemplate.setSize(prop.getSize());
-            newTemplate.setPhysicalSize(prop.getPhysicalSize());
-            newTemplate.setName(templateUuid);
-            return new CopyCmdAnswer(newTemplate);
-        } catch (ConfigurationException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        } catch (InternalErrorException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        } catch (IOException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        }
-
-        return new CopyCmdAnswer(errMsg);
-    }
-
-    protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
-
-        if (srcData.getHypervisorType() == HypervisorType.XenServer) {
-            return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
-        } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
-            File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl(), _nfsVersion);
-            File destFile = getFile(destData.getPath(), destDataStore.getUrl(), _nfsVersion);
-
-            VolumeObjectTO volumeObjectTO = srcData.getVolume();
-            ImageFormat srcFormat = null;
-            //TODO: the image format should be stored in snapshot table, instead of getting from volume
-            if (volumeObjectTO != null) {
-                srcFormat = volumeObjectTO.getFormat();
-            } else {
-                srcFormat = ImageFormat.QCOW2;
-            }
-
-            // get snapshot file name
-            String templateName = srcFile.getName();
-            // add kvm file extension for copied template name
-            String fileName = templateName + "." + srcFormat.getFileExtension();
-            String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
-            s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
-            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
-            String metaFileName = destFile.getAbsolutePath() + File.separator + _tmpltpp;
-            File metaFile = new File(metaFileName);
-            try {
-                _storage.create(destFile.getAbsolutePath(), _tmpltpp);
-                try ( // generate template.properties file
-                        FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
-                    // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
-                    // to send template name back.
-                    bufferWriter.write("uniquename=" + destData.getName());
-                    bufferWriter.write("\n");
-                    bufferWriter.write("filename=" + fileName);
-                }
-                try {
-                    /**
-                     * Snapshots might be in either QCOW2 or RAW image format
-                     *
-                     * For example RBD snapshots are in RAW format
-                     */
-                    Processor processor = null;
-                    if (srcFormat == ImageFormat.QCOW2) {
-                        processor = new QCOW2Processor();
-                    } else if (srcFormat == ImageFormat.RAW) {
-                        processor = new RawImageProcessor();
-                    } else {
-                        throw new ConfigurationException("Unknown image format " + srcFormat.toString());
-                    }
-
-                    Map<String, Object> params = new HashMap<String, Object>();
-                    params.put(StorageLayer.InstanceConfigKey, _storage);
-
-                    processor.configure("template processor", params);
-                    String destPath = destFile.getAbsolutePath();
-
-                    FormatInfo info = processor.process(destPath, null, templateName);
-                    TemplateLocation loc = new TemplateLocation(_storage, destPath);
-                    loc.create(1, true, destData.getName());
-                    loc.addFormat(info);
-                    loc.save();
-
-                    TemplateProp prop = loc.getTemplateInfo();
-                    TemplateObjectTO newTemplate = new TemplateObjectTO();
-                    newTemplate.setPath(destData.getPath() + File.separator + fileName);
-                    newTemplate.setFormat(srcFormat);
-                    newTemplate.setSize(prop.getSize());
-                    newTemplate.setPhysicalSize(prop.getPhysicalSize());
-                    return new CopyCmdAnswer(newTemplate);
-                } catch (ConfigurationException e) {
-                    s_logger.debug("Failed to create template:" + e.toString());
-                    return new CopyCmdAnswer(e.toString());
-                } catch (InternalErrorException e) {
-                    s_logger.debug("Failed to create template:" + e.toString());
-                    return new CopyCmdAnswer(e.toString());
-                }
-            } catch (IOException e) {
-                s_logger.debug("Failed to create template:" + e.toString());
-                return new CopyCmdAnswer(e.toString());
-            }
-        }
-
-        return new CopyCmdAnswer("");
-    }
-
-    protected File getFile(String path, String nfsPath, Integer nfsVersion) {
-        String filePath = getRootDir(nfsPath, nfsVersion) + File.separator + path;
-        File f = new File(filePath);
-        if (!f.exists()) {
-            f = findFile(filePath);
-            if (f == null) {
-                _storage.mkdirs(filePath);
-                f = new File(filePath);
-            }
-        }
-        return f;
-    }
-
-    protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        DataStoreTO destDataStore = destData.getDataStore();
-        if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
-            if (!(srcDataStore instanceof NfsTO)) {
-                s_logger.debug("only support nfs storage as src, when create template from snapshot");
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
-            if (destDataStore instanceof NfsTO) {
-                return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
-            } else if (destDataStore instanceof SwiftTO) {
-                //create template on the same data store
-                CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
-                        (NfsTO)srcDataStore);
-                if (!answer.getResult()) {
-                    return answer;
-                }
-                s_logger.debug("starting copy template to swift");
-                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
-                newTemplate.setDataStore(srcDataStore);
-                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
-                Answer result = copyFromNfsToSwift(newCpyCmd);
-
-                cleanupStagingNfs(newTemplate);
-                return result;
-
-            } else if (destDataStore instanceof S3TO) {
-                //create template on the same data store
-                CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
-                        (NfsTO)srcDataStore);
-                if (!answer.getResult()) {
-                    return answer;
-                }
-                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
-                newTemplate.setDataStore(srcDataStore);
-                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
-                Answer result = copyFromNfsToS3(newCpyCmd);
-
-                cleanupStagingNfs(newTemplate);
-
-                return result;
-            }
-        }
-        s_logger.debug("Failed to create template from snapshot");
-        return new CopyCmdAnswer("Unsupported protocol");
-    }
-
-    /**
-     * clean up template data on staging area
-     * @param newTemplate: The template on the secondary storage that needs to be cleaned up
-     */
-    protected void cleanupStagingNfs(TemplateObjectTO newTemplate) {
-        try {
-            DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
-            execute(deleteCommand);
-        } catch (Exception e) {
-            s_logger.debug("Failed to clean up staging area:", e);
-        }
-    }
-
-    protected Answer copyFromNfsToImage(CopyCommand cmd) {
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        if (destDataStore instanceof S3TO) {
-            return copyFromNfsToS3(cmd);
-        } else if (destDataStore instanceof SwiftTO) {
-            return copyFromNfsToSwift(cmd);
-        } else {
-            return new CopyCmdAnswer("unsupported ");
-        }
-    }
-
-    protected Answer execute(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
-            return createTemplateFromSnapshot(cmd);
-        }
-
-        if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
-            NfsTO destImageStore = (NfsTO)destDataStore;
-            if (srcDataStore instanceof S3TO) {
-                S3TO s3 = (S3TO)srcDataStore;
-                return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
-            } else if (srcDataStore instanceof SwiftTO) {
-                return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
-            }
-        }
-
-        if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
-            return copyFromNfsToImage(cmd);
-        }
-
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
-        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
-    }
-
-    private String determineS3TemplateNameFromKey(String key) {
-        return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
-    }
-
-    protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
-        return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
-    }
-
-    protected Long determineS3VolumeIdFromKey(String key) {
-        return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
-    }
-
-    private String determineStorageTemplatePath(final String storagePath, String dataPath, Integer nfsVersion) {
-        return join(asList(getRootDir(storagePath, nfsVersion), dataPath), File.separator);
-    }
-
-    protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
-        HttpClient client = new DefaultHttpClient();
-        HttpGet get = new HttpGet(url);
-        try {
-            HttpResponse response = client.execute(get);
-            HttpEntity entity = response.getEntity();
-            if (entity == null) {
-                s_logger.debug("Faled to get entity");
-                throw new CloudRuntimeException("Failed to get url: " + url);
-            }
-
-            String nfsMountPath = getRootDir(nfs.getUrl(), _nfsVersion);
-
-            String filePath = nfsMountPath + File.separator + path;
-            File directory = new File(filePath);
-            if (!directory.exists()) {
-                _storage.mkdirs(filePath);
-            }
-            File destFile = new File(filePath + File.separator + name);
-            if (!destFile.createNewFile()) {
-                s_logger.warn("Reusing existing file " + destFile.getPath());
-            }
-            try (FileOutputStream outputStream = new FileOutputStream(destFile);) {
-                entity.writeTo(outputStream);
-            } catch (IOException e) {
-                s_logger.debug("downloadFromUrlToNfs:Exception:" + e.getMessage(), e);
-            }
-            return new File(destFile.getAbsolutePath());
-        } catch (IOException e) {
-            s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
-            throw new CloudRuntimeException(e);
-        }
-    }
-
-    protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
-        SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
-        String path = cmd.getInstallPath();
-        DataStoreTO cacheStore = cmd.getCacheStore();
-        if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
-            return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        }
-
-        File file = null;
-        try {
-            NfsTO nfsCacheStore = (NfsTO)cacheStore;
-            String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
-            file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
-            String container = "T-" + cmd.getId();
-            String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
-
-            long virtualSize = getVirtualSize(file, getTemplateFormat(file.getName()));
-            long size = file.length();
-            String uniqueName = cmd.getName();
-
-            //put metda file
-            File uniqDir = _storage.createUniqDir();
-            String metaFileName = uniqDir.getAbsolutePath() + File.separator + _tmpltpp;
-            _storage.create(uniqDir.getAbsolutePath(), _tmpltpp);
-
-            File metaFile = swiftWriteMetadataFile(metaFileName, uniqueName, fileName, size, virtualSize);
-
-            SwiftUtil.putObject(swiftTO, metaFile, container, _tmpltpp);
-            metaFile.delete();
-            uniqDir.delete();
-            String md5sum = null;
-            try (FileInputStream fs = new FileInputStream(file)) {
-                md5sum = DigestUtils.md5Hex(fs);
-            } catch (IOException e) {
-                s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
-            }
-
-            DownloadAnswer answer = new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, virtualSize, file.length(), md5sum);
-            return answer;
-        } catch (IOException e) {
-            s_logger.debug("Failed to register template into swift", e);
-            return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        } finally {
-            if (file != null) {
-                file.delete();
-            }
-        }
-    }
-
-    private Answer execute(DownloadCommand cmd) {
-        DataStoreTO dstore = cmd.getDataStore();
-        if (dstore instanceof NfsTO || dstore instanceof S3TO) {
-            return _dlMgr.handleDownloadCommand(this, cmd);
-        } else if (dstore instanceof SwiftTO) {
-            return registerTemplateOnSwift(cmd);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    private ImageFormat getTemplateFormat(String filePath) {
-        String ext = null;
-        int extensionPos = filePath.lastIndexOf('.');
-        int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
-        int i = lastSeparator > extensionPos ? -1 : extensionPos;
-        if (i > 0) {
-            ext = filePath.substring(i + 1);
-        }
-        if (ext != null) {
-            if (ext.equalsIgnoreCase("vhd")) {
-                return ImageFormat.VHD;
-            } else if (ext.equalsIgnoreCase("vhdx")) {
-                return ImageFormat.VHDX;
-            } else if (ext.equalsIgnoreCase("qcow2")) {
-                return ImageFormat.QCOW2;
-            } else if (ext.equalsIgnoreCase("ova")) {
-                return ImageFormat.OVA;
-            } else if (ext.equalsIgnoreCase("tar")) {
-                return ImageFormat.TAR;
-            } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
-                return ImageFormat.RAW;
-            } else if (ext.equalsIgnoreCase("vmdk")) {
-                return ImageFormat.VMDK;
-            } else if (ext.equalsIgnoreCase("vdi")) {
-                return ImageFormat.VDI;
-            }
-        }
-
-        return null;
-
-    }
-
-    protected long getVirtualSize(File file, ImageFormat format) {
-        Processor processor = null;
-        try {
-            if (format == null) {
-                return file.length();
-            } else if (format == ImageFormat.QCOW2) {
-                processor = new QCOW2Processor();
-            } else if (format == ImageFormat.OVA) {
-                processor = new OVAProcessor();
-            } else if (format == ImageFormat.VHD) {
-                processor = new VhdProcessor();
-            } else if (format == ImageFormat.RAW) {
-                processor = new RawImageProcessor();
-            } else if (format == ImageFormat.VMDK) {
-                processor = new VmdkProcessor();
-            }
-            if (format == ImageFormat.TAR) {
-                processor = new TARProcessor();
-            }
-
-            if (processor == null) {
-                return file.length();
-            }
-
-            Map<String, Object> params = new HashMap<String, Object>();
-            params.put(StorageLayer.InstanceConfigKey, _storage);
-            processor.configure("template processor", params);
-            return processor.getVirtualSize(file);
-        } catch (Exception e) {
-            s_logger.warn("Failed to get virtual size of file " + file.getPath() + ", returning file size instead: ", e);
-            return file.length();
-        }
-
-    }
-
-    protected File findFile(String path) {
-
-        File srcFile = _storage.getFile(path);
-        if (!srcFile.exists()) {
-            srcFile = _storage.getFile(path + ".qcow2");
-            if (!srcFile.exists()) {
-                srcFile = _storage.getFile(path + ".vhd");
-                if (!srcFile.exists()) {
-                    srcFile = _storage.getFile(path + ".ova");
-                    if (!srcFile.exists()) {
-                        srcFile = _storage.getFile(path + ".vmdk");
-                        if (!srcFile.exists()) {
-                            return null;
-                        }
-                    }
-                }
-            }
-        }
-
-        return srcFile;
-    }
-
-    protected Answer copyFromNfsToS3(CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        NfsTO srcStore = (NfsTO)srcDataStore;
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        final S3TO s3 = (S3TO)destDataStore;
-
-        try {
-            final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath(), _nfsVersion);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
-            }
-
-            final String bucket = s3.getBucketName();
-            File srcFile = findFile(templatePath);
-            if (srcFile == null) {
-                return new CopyCmdAnswer("Can't find src file:" + templatePath);
-            }
-
-            ImageFormat format = getTemplateFormat(srcFile.getName());
-            String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
-
-            putFile(s3, srcFile, bucket, key).waitForCompletion();
-
-            DataTO retObj = null;
-            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-                TemplateObjectTO newTemplate = new TemplateObjectTO();
-                newTemplate.setPath(key);
-                newTemplate.setSize(getVirtualSize(srcFile, format));
-                newTemplate.setPhysicalSize(srcFile.length());
-                newTemplate.setFormat(format);
-                retObj = newTemplate;
-            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
-                VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(key);
-                newVol.setSize(srcFile.length());
-                retObj = newVol;
-            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
-                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-                newSnapshot.setPath(key);
-                retObj = newSnapshot;
-            }
-
-            return new CopyCmdAnswer(retObj);
-        } catch (Exception e) {
-            s_logger.error("failed to upload" + srcData.getPath(), e);
-            return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
-        }
-    }
-
-    /***
-     *This method will create a file using the filenName and metaFileName.
-     *That file will contain the given attributes (unique name, file name, size, and virtualSize).
-     *
-     * @param metaFileName : The path of the metadata file
-     * @param filename      :attribute:  Filename of the template
-     * @param uniqueName    :attribute:  Unique name of the template
-     * @param size          :attribute:  physical size of the template
-     * @param virtualSize   :attribute:  virtual size of the template
-     * @return File representing the metadata file
-     * @throws IOException
-     */
-
-    protected File swiftWriteMetadataFile(String metaFileName, String uniqueName, String filename, long size, long virtualSize) throws IOException {
-        File metaFile = new File(metaFileName);
-        FileWriter writer = new FileWriter(metaFile);
-        BufferedWriter bufferWriter = new BufferedWriter(writer);
-        bufferWriter.write("uniquename=" + uniqueName);
-        bufferWriter.write("\n");
-        bufferWriter.write("filename=" + filename);
-        bufferWriter.write("\n");
-        bufferWriter.write("size=" + size);
-        bufferWriter.write("\n");
-        bufferWriter.write("virtualsize=" + virtualSize);
-        bufferWriter.close();
-        writer.close();
-        return metaFile;
-    }
-
-    /**
-     * Creates a template.properties for Swift with its correct unique name
-     *
-     * @param swift  The swift object
-     * @param srcFile Source file on the staging NFS
-     * @param containerName Destination container  @return true on successful write
-     * @param uniqueName Unique name identifying the template
-     */
-    protected boolean swiftUploadMetadataFile(SwiftTO swift, File srcFile, String containerName, String uniqueName) throws IOException {
-
-        File uniqDir = _storage.createUniqDir();
-        String metaFileName = uniqDir.getAbsolutePath() + File.separator + _tmpltpp;
-        _storage.create(uniqDir.getAbsolutePath(), _tmpltpp);
-
-        long virtualSize = getVirtualSize(srcFile, getTemplateFormat(srcFile.getName()));
-
-        File metaFile = swiftWriteMetadataFile(metaFileName, uniqueName, srcFile.getName(), srcFile.length(), virtualSize);
-
-        SwiftUtil.putObject(swift, metaFile, containerName, _tmpltpp);
-        metaFile.delete();
-        uniqDir.delete();
-
-        return true;
-    }
-
-    /**
-     * Copies data from NFS and uploads it into a Swift container
-     *
-     * @param cmd CopyComand
-     * @return CopyCmdAnswer
-     */
-    protected Answer copyFromNfsToSwift(CopyCommand cmd) {
-
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        NfsTO srcStore = (NfsTO)srcDataStore;
-        DataStoreTO destDataStore = destData.getDataStore();
-        File srcFile = getFile(srcData.getPath(), srcStore.getUrl(), _nfsVersion);
-
-        SwiftTO swift = (SwiftTO)destDataStore;
-        long pathId = destData.getId();
-
-        try {
-
-            if (destData instanceof SnapshotObjectTO) {
-                pathId = ((SnapshotObjectTO)destData).getVolume().getId();
-            }
-
-            String containerName = SwiftUtil.getContainerName(destData.getObjectType().toString(), pathId);
-            String swiftPath = SwiftUtil.putObject(swift, srcFile, containerName, srcFile.getName());
-
-            DataTO retObj = null;
-            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-                TemplateObjectTO destTemplateData = (TemplateObjectTO)destData;
-                String uniqueName = destTemplateData.getName();
-                swiftUploadMetadataFile(swift, srcFile, containerName, uniqueName);
-                TemplateObjectTO newTemplate = new TemplateObjectTO();
-                newTemplate.setPath(swiftPath);
-                newTemplate.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
-                newTemplate.setPhysicalSize(srcFile.length());
-                newTemplate.setFormat(getTemplateFormat(srcFile.getName()));
-                retObj = newTemplate;
-            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
-                VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(containerName);
-                newVol.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
-                retObj = newVol;
-            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
-                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-                newSnapshot.setPath(containerName + File.separator + srcFile.getName());
-                retObj = newSnapshot;
-            }
-
-            return new CopyCmdAnswer(retObj);
-
-        } catch (Exception e) {
-            s_logger.error("failed to upload " + srcData.getPath(), e);
-            return new CopyCmdAnswer("failed to upload " + srcData.getPath() + e.toString());
-        }
-    }
-
-    String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
-        + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDownload failed  err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDownload failed , err=" + parser.getLines();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-
-    }
-
-    String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
-                + swift.getUserName() + " -K " + swift.getKey() + " download " + container);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDownloadContainer failed  err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-
-    }
-
-    String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
-        long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
-        List<String> files = new ArrayList<String>();
-        if (lFilename.equals("*")) {
-            File dir = new File(lDir);
-            String[] dir_lst = dir.list();
-            if (dir_lst != null) {
-                for (String file : dir_lst) {
-                    if (file.startsWith(".")) {
-                        continue;
-                    }
-                    files.add(file);
-                }
-            }
-        } else {
-            files.add(lFilename);
-        }
-
-        for (String file : files) {
-            File f = new File(lDir + "/" + file);
-            long size = f.length();
-            Script command = new Script("/bin/bash", s_logger);
-            command.add("-c");
-            if (size <= SWIFT_MAX_SIZE) {
-                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
-                        + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file);
-            } else {
-                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":"
-                        + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
-            }
-            OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-            String result = command.execute(parser);
-            if (result != null) {
-                String errMsg = "swiftUpload failed , err=" + result;
-                s_logger.warn(errMsg);
-                return errMsg;
-            }
-            if (parser.getLines() != null) {
-                String[] lines = parser.getLines().split("\\n");
-                for (String line : lines) {
-                    if (line.contains("Errno") || line.contains("failed")) {
-                        String errMsg = "swiftUpload failed , err=" + parser.getLines();
-                        s_logger.warn(errMsg);
-                        return errMsg;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    String[] swiftList(SwiftTO swift, String container, String rFilename) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
-        + " -K " + swift.getKey() + " list " + container + " " + rFilename);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            return lines;
-        } else {
-            if (result != null) {
-                String errMsg = "swiftList failed , err=" + result;
-                s_logger.warn(errMsg);
-            } else {
-                String errMsg = "swiftList failed, no lines returns";
-                s_logger.warn(errMsg);
-            }
-        }
-        return null;
-    }
-
-    String swiftDelete(SwiftTO swift, String container, String object) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
-        + " -K " + swift.getKey() + " delete " + container + " " + object);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDelete failed , err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDelete failed , err=" + parser.getLines();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-    }
-
-    public Answer execute(DeleteSnapshotsDirCommand cmd) {
-        DataStoreTO dstore = cmd.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeSnapshotPath = cmd.getDirectory();
-            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
-
-            if (relativeSnapshotPath.startsWith(File.separator)) {
-                relativeSnapshotPath = relativeSnapshotPath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteSnapshotPath = parent + relativeSnapshotPath;
-            File snapshotDir = new File(absoluteSnapshotPath);
-            String details = null;
-            if (!snapshotDir.exists()) {
-                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, true, details);
-            }
-            // delete all files in the directory
-            String lPath = absoluteSnapshotPath + "/*";
-            String result = deleteLocalFile(lPath);
-            if (result != null) {
-                String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            // delete the directory
-            if (!snapshotDir.delete()) {
-                details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = cmd.getDirectory();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            String path = cmd.getDirectory();
-            String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
-            // that
-            // the
-            // filename
-            // is
-            // the
-            // last
-            // section
-            // in
-            // the
-            // path
-            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
-            if (result != null) {
-                String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-    }
-
-    private Answer execute(ComputeChecksumCommand cmd) {
-
-        String relativeTemplatePath = cmd.getTemplatePath();
-        DataStoreTO store = cmd.getStore();
-        if (!(store instanceof NfsTO)) {
-            return new Answer(cmd, false, "can't handle non nfs data store");
-        }
-        NfsTO nfsStore = (NfsTO)store;
-        String parent = getRootDir(nfsStore.getUrl(), _nfsVersion);
-
-        if (relativeTemplatePath.startsWith(File.separator)) {
-            relativeTemplatePath = relativeTemplatePath.substring(1);
-        }
-
-        if (!parent.endsWith(File.separator)) {
-            parent += File.separator;
-        }
-        String absoluteTemplatePath = parent + relativeTemplatePath;
-        String algorithm = cmd.getAlgorithm();
-        File f = new File(absoluteTemplatePath);
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath);
-        }
-        String checksum = null;
-
-        try (InputStream is = new FileInputStream(f);){
-            checksum = DigestHelper.digest(algorithm, is).toString();
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Successfully calculated checksum for file " + absoluteTemplatePath + " - " + checksum);
-            }
-        } catch (IOException e) {
-            String logMsg = "Unable to process file for " + algorithm + " - " + absoluteTemplatePath;
-            s_logger.error(logMsg);
-            return new Answer(cmd, false, checksum);
-        } catch (NoSuchAlgorithmException e) {
-            return new Answer(cmd, false, checksum);
-        }
-
-        return new Answer(cmd, true, checksum);
-    }
-
-    private void configCerts(KeystoreManager.Certificates certs) {
-        if (certs == null) {
-            configureSSL();
-        } else {
-            String prvKey = certs.getPrivKey();
-            String pubCert = certs.getPrivCert();
-            String certChain = certs.getCertChain();
-            String rootCACert = certs.getRootCACert();
-
-            try {
-                File prvKeyFile = File.createTempFile("prvkey", null);
-                String prvkeyPath = prvKeyFile.getAbsolutePath();
-                try (BufferedWriter prvt_key_file = new BufferedWriter(new FileWriter(prvKeyFile));) {
-                    prvt_key_file.write(prvKey);
-                } catch (IOException e) {
-                    s_logger.debug("Failed to config ssl: " + e.toString());
-                }
-
-                File pubCertFile = File.createTempFile("pubcert", null);
-                String pubCertFilePath = pubCertFile.getAbsolutePath();
-
-                try (BufferedWriter pub_cert_file = new BufferedWriter(new FileWriter(pubCertFile));) {
-                    pub_cert_file.write(pubCert);
-                } catch (IOException e) {
-                    s_logger.debug("Failed to config ssl: " + e.toString());
-                }
-
-                String certChainFilePath = null, rootCACertFilePath = null;
-                File certChainFile = null, rootCACertFile = null;
-                if (certChain != null) {
-                    certChainFile = File.createTempFile("certchain", null);
-                    certChainFilePath = certChainFile.getAbsolutePath();
-                    try (BufferedWriter cert_chain_out = new BufferedWriter(new FileWriter(certChainFile));) {
-                        cert_chain_out.write(certChain);
-                    } catch (IOException e) {
-                        s_logger.debug("Failed to config ssl: " + e.toString());
-                    }
-                }
-
-                if (rootCACert != null) {
-                    rootCACertFile = File.createTempFile("rootcert", null);
-                    rootCACertFilePath = rootCACertFile.getAbsolutePath();
-                    try (BufferedWriter root_ca_cert_file = new BufferedWriter(new FileWriter(rootCACertFile));) {
-                        root_ca_cert_file.write(rootCACert);
-                    } catch (IOException e) {
-                        s_logger.debug("Failed to config ssl: " + e.toString());
-                    }
-                }
-
-                configureSSL(prvkeyPath, pubCertFilePath, certChainFilePath, rootCACertFilePath);
-
-                prvKeyFile.delete();
-                pubCertFile.delete();
-                if (certChainFile != null) {
-                    certChainFile.delete();
-                }
-                if (rootCACertFile != null) {
-                    rootCACertFile.delete();
-                }
-
-            } catch (IOException e) {
-                s_logger.debug("Failed to config ssl: " + e.toString());
-            }
-        }
-    }
-
-    private Answer execute(SecStorageSetupCommand cmd) {
-        if (!_inSystemVM) {
-            return new Answer(cmd, true, null);
-        }
-        Answer answer = null;
-        DataStoreTO dStore = cmd.getDataStore();
-        if (dStore instanceof NfsTO) {
-            String secUrl = cmd.getSecUrl();
-            try {
-                URI uri = new URI(secUrl);
-                String nfsHostIp = getUriHostIp(uri);
-
-                addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
-
-                String dir = mountUri(uri, cmd.getNfsVersion());
-
-                configCerts(cmd.getCerts());
-
-                nfsIps.add(nfsHostIp);
-                answer = new SecStorageSetupAnswer(dir);
-            } catch (Exception e) {
-                String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-                s_logger.error(msg);
-                answer = new Answer(cmd, false, msg);
-
-            }
-        } else {
-            // TODO: what do we need to setup for S3/Swift, maybe need to mount
-            // to some cache storage
-            answer = new Answer(cmd, true, null);
-        }
-
-        savePostUploadPSK(cmd.getPostUploadKey());
-        startPostUploadServer();
-        return answer;
-    }
-
-    private void startPostUploadServer() {
-        final int PORT = 8210;
-        final int NO_OF_WORKERS = 15;
-        final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
-        final EventLoopGroup workerGroup = new NioEventLoopGroup(NO_OF_WORKERS);
-        final ServerBootstrap b = new ServerBootstrap();
-        final NfsSecondaryStorageResource storageResource = this;
-        b.group(bossGroup, workerGroup);
-        b.channel(NioServerSocketChannel.class);
-        b.handler(new LoggingHandler(LogLevel.INFO));
-        b.childHandler(new ChannelInitializer<SocketChannel>() {
-            @Override
-            protected void initChannel(SocketChannel ch) throws Exception {
-                ChannelPipeline pipeline = ch.pipeline();
-                pipeline.addLast(new HttpRequestDecoder());
-                pipeline.addLast(new HttpResponseEncoder());
-                pipeline.addLast(new HttpContentCompressor());
-                pipeline.addLast(new HttpUploadServerHandler(storageResource));
-            }
-        });
-        new Thread() {
-            @Override
-            public void run() {
-                try {
-                    Channel ch = b.bind(PORT).sync().channel();
-                    s_logger.info(String.format("Started post upload server on port %d with %d workers", PORT, NO_OF_WORKERS));
-                    ch.closeFuture().sync();
-                } catch (InterruptedException e) {
-                    s_logger.info("Failed to start post upload server");
-                    s_logger.debug("Exception while starting post upload server", e);
-                } finally {
-                    bossGroup.shutdownGracefully();
-                    workerGroup.shutdownGracefully();
-                    s_logger.info("shutting down post upload server");
-                }
-            }
-        }.start();
-        s_logger.info("created a thread to start post upload server");
-    }
-
-    private void savePostUploadPSK(String psk) {
-        try {
-            FileUtils.writeStringToFile(new File(POST_UPLOAD_KEY_LOCATION), psk, "utf-8");
-        } catch (IOException ex) {
-            s_logger.debug("Failed to copy PSK to the file.", ex);
-        }
-    }
-
-    protected Answer deleteSnapshot(final DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String snapshotPath = obj.getPath();
-            if (snapshotPath.startsWith(File.separator)) {
-                snapshotPath = snapshotPath.substring(1);
-            }
-            // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
-            // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
-            // and return true.
-            String fullSnapPath = parent + snapshotPath;
-            File snapDir = new File(fullSnapPath);
-            if (snapDir.exists() && snapDir.isDirectory()) {
-                s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
-                return new Answer(cmd, true, null);
-            }
-            // passed snapshot path is a snapshot file path, then get snapshot directory first
-            int index = snapshotPath.lastIndexOf("/");
-            String snapshotName = snapshotPath.substring(index + 1);
-            snapshotPath = snapshotPath.substring(0, index);
-            String absoluteSnapshotPath = parent + snapshotPath;
-            // check if snapshot directory exists
-            File snapshotDir = new File(absoluteSnapshotPath);
-            String details = null;
-            if (!snapshotDir.exists()) {
-                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, true, details);
-            }
-            // delete snapshot in the directory if exists
-            String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
-            String result = deleteLocalFile(lPath);
-            if (result != null) {
-                details = "failed to delete snapshot " + lPath + " , err=" + result;
-                s_logger.warn(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteObject(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            SwiftTO swiftTO = (SwiftTO)dstore;
-            String path = obj.getPath();
-            SwiftUtil.deleteObject(swiftTO, path);
-
-            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
-        String[] containers = SwiftUtil.list(swift, "", null);
-        if (containers == null) {
-            return null;
-        }
-        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
-        for (String container : containers) {
-            if (container.startsWith("T-")) {
-                String[] files = SwiftUtil.list(swift, container, _tmpltpp);
-                if (files.length != 1) {
-                    continue;
-                }
-                try {
-                    File tempFile = File.createTempFile("template", ".tmp");
-                    File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + _tmpltpp);
-                    if (tmpFile == null) {
-                        continue;
-                    }
-                    try (FileReader fr = new FileReader(tmpFile); BufferedReader brf = new BufferedReader(fr);) {
-                        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, physicalSize, true, false);
-                            tmpltInfos.put(uniqName, prop);
-                        }
-                    } catch (IOException ex) {
-                        s_logger.debug("swiftListTemplate:Exception:" + ex.getMessage());
-                        continue;
-                    }
-                } catch (IOException e) {
-                    s_logger.debug("Failed to create templ file:" + e.toString());
-                    continue;
-                } catch (Exception e) {
-                    s_logger.debug("Failed to get properties: " + e.toString());
-                    continue;
-                }
-            }
-        }
-        return tmpltInfos;
-    }
-
-    Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
-        String bucket = s3.getBucketName();
-        // List the objects in the source directory on S3
-        final List<S3ObjectSummary> objectSummaries = S3Utils.listDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
-        if (objectSummaries == null) {
-            return null;
-        }
-        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
-        for (S3ObjectSummary objectSummary : objectSummaries) {
-            String key = objectSummary.getKey();
-            // String installPath = StringUtils.substringBeforeLast(key,
-            // S3Utils.SEPARATOR);
-            String uniqueName = determineS3TemplateNameFromKey(key);
-            // TODO: isPublic value, where to get?
-            TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
-            tmpltInfos.put(uniqueName, tInfo);
-        }
-        return tmpltInfos;
-
-    }
-
-    Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
-        String bucket = s3.getBucketName();
-        // List the objects in the source directory on S3
-        final List<S3ObjectSummary> objectSummaries = S3Utils.listDirectory(s3, bucket, VOLUME_ROOT_DIR);
-        if (objectSummaries == null) {
-            return null;
-        }
-        Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
-        for (S3ObjectSummary objectSummary : objectSummaries) {
-            String key = objectSummary.getKey();
-            // String installPath = StringUtils.substringBeforeLast(key,
-            // S3Utils.SEPARATOR);
-            Long id = determineS3VolumeIdFromKey(key);
-            // TODO: how to get volume template name
-            TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
-            tmpltInfos.put(id, tInfo);
-        }
-        return tmpltInfos;
-
-    }
-
-    private Answer execute(ListTemplateCommand cmd) {
-        if (!_inSystemVM) {
-            return new ListTemplateAnswer(null, null);
-        }
-
-        DataStoreTO store = cmd.getDataStore();
-        if (store instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)store;
-            String secUrl = nfs.getUrl();
-            String root = getRootDir(secUrl, cmd.getNfsVersion());
-            Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
-            return new ListTemplateAnswer(secUrl, templateInfos);
-        } else if (store instanceof SwiftTO) {
-            SwiftTO swift = (SwiftTO)store;
-            Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
-            return new ListTemplateAnswer(swift.toString(), templateInfos);
-        } else if (store instanceof S3TO) {
-            S3TO s3 = (S3TO)store;
-            Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
-            return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + store);
-        }
-    }
-
-    private Answer execute(ListVolumeCommand cmd) {
-        if (!_inSystemVM) {
-            return new ListVolumeAnswer(cmd.getSecUrl(), null);
-        }
-        DataStoreTO store = cmd.getDataStore();
-        if (store instanceof NfsTO) {
-            String root = getRootDir(cmd.getSecUrl(), _nfsVersion);
-            Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
-            return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
-        } else if (store instanceof S3TO) {
-            S3TO s3 = (S3TO)store;
-            Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
-            return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + store);
-        }
-
-    }
-
-    private Answer execute(SecStorageVMSetupCommand cmd) {
-        if (!_inSystemVM) {
-            return new Answer(cmd, true, null);
-        }
-        boolean success = true;
-        StringBuilder result = new StringBuilder();
-        for (String cidr : cmd.getAllowedInternalSites()) {
-            if (nfsIps.contains(cidr)) {
-                /*
-                 * if the internal download ip is the same with secondary
-                 * storage ip, adding internal sites will flush ip route to nfs
-                 * through storage ip.
-                 */
-                continue;
-            }
-            String tmpresult = allowOutgoingOnPrivate(cidr);
-            if (tmpresult != null) {
-                result.append(", ").append(tmpresult);
-                success = false;
-            }
-        }
-        if (success) {
-            if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
-                String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
-                if (tmpresult != null) {
-                    result.append("Failed to configure auth for copy ").append(tmpresult);
-                    success = false;
-                }
-            }
-        }
-        return new Answer(cmd, success, result.toString());
-
-    }
-
-    private String deleteLocalFile(String fullPath) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("rm -rf " + fullPath);
-        String result = command.execute();
-        if (result != null) {
-            String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        return null;
-    }
-
-    public String allowOutgoingOnPrivate(String destCidr) {
-        if (!_inSystemVM) {
-            return null;
-        }
-        Script command = new Script("/bin/bash", s_logger);
-        String intf = "eth1";
-        command.add("-c");
-        command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp  -j ACCEPT");
-
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result);
-            return "Error in allowing outgoing to " + destCidr + ", err=" + result;
-        }
-
-        addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr);
-
-        return null;
-    }
-
-    private Answer execute(SecStorageFirewallCfgCommand cmd) {
-        if (!_inSystemVM) {
-            return new Answer(cmd, true, null);
-        }
-
-        List<String> ipList = new ArrayList<String>();
-
-        for (PortConfig pCfg : cmd.getPortConfigs()) {
-            if (pCfg.isAdd()) {
-                ipList.add(pCfg.getSourceIp());
-            }
-        }
-        boolean success = true;
-        String result;
-        result = configureIpFirewall(ipList, cmd.getIsAppendAIp());
-        if (result != null) {
-            success = false;
-        }
-
-        return new Answer(cmd, success, result);
-    }
-
-    private UploadStatusAnswer execute(UploadStatusCommand cmd) {
-        String entityUuid = cmd.getEntityUuid();
-        if (uploadEntityStateMap.containsKey(entityUuid)) {
-            UploadEntity uploadEntity = uploadEntityStateMap.get(entityUuid);
-            if (uploadEntity.getUploadState() == UploadEntity.Status.ERROR) {
-                uploadEntityStateMap.remove(entityUuid);
-                return new UploadStatusAnswer(cmd, UploadStatus.ERROR, uploadEntity.getErrorMessage());
-            } else if (uploadEntity.getUploadState() == UploadEntity.Status.COMPLETED) {
-                UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.COMPLETED);
-                answer.setVirtualSize(uploadEntity.getVirtualSize());
-                answer.setInstallPath(uploadEntity.getTmpltPath());
-                answer.setPhysicalSize(uploadEntity.getPhysicalSize());
-                answer.setDownloadPercent(100);
-                uploadEntityStateMap.remove(entityUuid);
-                return answer;
-            } else if (uploadEntity.getUploadState() == UploadEntity.Status.IN_PROGRESS) {
-                UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.IN_PROGRESS);
-                long downloadedSize = FileUtils.sizeOfDirectory(new File(uploadEntity.getInstallPathPrefix()));
-                int downloadPercent = (int)(100 * downloadedSize / uploadEntity.getContentLength());
-                answer.setDownloadPercent(Math.min(downloadPercent, 100));
-                return answer;
-            }
-        }
-        return new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN);
-    }
-
-    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
-        DataStoreTO store = cmd.getStore();
-        if (store instanceof S3TO || store instanceof SwiftTO) {
-            long infinity = Integer.MAX_VALUE;
-            return new GetStorageStatsAnswer(cmd, infinity, 0L);
-        }
-
-        String rootDir = getRootDir(((NfsTO)store).getUrl(), cmd.getNfsVersion());
-        final long usedSize = getUsedSize(rootDir);
-        final long totalSize = getTotalSize(rootDir);
-        if (usedSize == -1 || totalSize == -1) {
-            return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
-        } else {
-            return new GetStorageStatsAnswer(cmd, totalSize, usedSize);
-        }
-    }
-
-    protected Answer execute(final DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataObjectType objType = obj.getObjectType();
-        if (obj.getPath() == null) {
-            // account for those fake entries for NFS migration to object store
-            return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
-        }
-        switch (objType) {
-        case TEMPLATE:
-            return deleteTemplate(cmd);
-        case VOLUME:
-            return deleteVolume(cmd);
-        case SNAPSHOT:
-            return deleteSnapshot(cmd);
-        }
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    protected Answer deleteTemplate(DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeTemplatePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
-
-            if (relativeTemplatePath.startsWith(File.separator)) {
-                relativeTemplatePath = relativeTemplatePath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteTemplatePath = parent + relativeTemplatePath;
-            File tmpltPath = new File(absoluteTemplatePath);
-            File tmpltParent = null;
-            if (tmpltPath.exists() && tmpltPath.isDirectory()) {
-                tmpltParent = tmpltPath;
-            } else {
-                tmpltParent = tmpltPath.getParentFile();
-            }
-
-            String details = null;
-            if (!tmpltParent.exists()) {
-                details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, true, details);
-            }
-            File[] tmpltFiles = tmpltParent.listFiles();
-            if (tmpltFiles == null || tmpltFiles.length == 0) {
-                details = "No files under template parent directory " + tmpltParent.getName();
-                s_logger.debug(details);
-            } else {
-                boolean found = false;
-                for (File f : tmpltFiles) {
-                    if (!found && f.getName().equals(_tmpltpp)) {
-                        found = true;
-                    }
-
-                    // KVM HA monitor makes a mess in the templates with its
-                    // heartbeat tests
-                    // Don't let this stop us from cleaning up the template
-                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
-                        s_logger.debug("Deleting KVMHA directory contents from template location");
-                        File[] haFiles = f.listFiles();
-                        for (File haFile : haFiles) {
-                            haFile.delete();
-                        }
-                    }
-
-                    if (!f.delete()) {
-                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
-                    }
-                }
-
-                if (!found) {
-                    details = "Can not find template.properties under " + tmpltParent.getName();
-                    s_logger.debug(details);
-                }
-            }
-            if (!tmpltParent.delete()) {
-                details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            SwiftTO swift = (SwiftTO)dstore;
-            String container = "T-" + obj.getId();
-            String object = "";
-
-            try {
-                String result = swiftDelete(swift, container, object);
-                if (result != null) {
-                    String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
-                    s_logger.warn(errMsg);
-                    return new Answer(cmd, false, errMsg);
-                }
-                return new Answer(cmd, true, "success");
-            } catch (Exception e) {
-                String errMsg = cmd + " Command failed due to " + e.toString();
-                s_logger.warn(errMsg, e);
-                return new Answer(cmd, false, errMsg);
-            }
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-    }
-
-    protected Answer deleteVolume(final DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeVolumePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl(), _nfsVersion);
-
-            if (relativeVolumePath.startsWith(File.separator)) {
-                relativeVolumePath = relativeVolumePath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteVolumePath = parent + relativeVolumePath;
-            File volPath = new File(absoluteVolumePath);
-            File tmpltParent = null;
-            if (volPath.exists() && volPath.isDirectory()) {
-                // for vmware, absoluteVolumePath represents a directory where volume files are located.
-                tmpltParent = volPath;
-            } else {
-                // for other hypervisors, the volume .vhd or .qcow2 file path is passed
-                tmpltParent = new File(absoluteVolumePath).getParentFile();
-            }
-            String details = null;
-            if (!tmpltParent.exists()) {
-                details = "volume parent directory " + tmpltParent.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, true, details);
-            }
-            File[] tmpltFiles = tmpltParent.listFiles();
-            if (tmpltFiles == null || tmpltFiles.length == 0) {
-                details = "No files under volume parent directory " + tmpltParent.getName();
-                s_logger.debug(details);
-            } else {
-                boolean found = false;
-                for (File f : tmpltFiles) {
-                    if (!found && f.getName().equals("volume.properties")) {
-                        found = true;
-                    }
-
-                    // KVM HA monitor makes a mess in the templates with its
-                    // heartbeat tests
-                    // Don't let this stop us from cleaning up the template
-                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
-                        s_logger.debug("Deleting KVMHA directory contents from template location");
-                        File[] haFiles = f.listFiles();
-                        for (File haFile : haFiles) {
-                            haFile.delete();
-                        }
-                    }
-
-                    if (!f.delete()) {
-                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
-                    }
-                }
-                if (!found) {
-                    details = "Can not find volume.properties under " + tmpltParent.getName();
-                    s_logger.debug(details);
-                }
-            }
-            if (!tmpltParent.delete()) {
-                details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + tmpltParent.getPath();
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            Long volumeId = obj.getId();
-            String path = obj.getPath();
-            String filename = StringUtils.substringAfterLast(path, "/"); // assuming
-            // that
-            // the
-            // filename
-            // is
-            // the
-            // last
-            // section
-            // in
-            // the
-            // path
-            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
-            if (result != null) {
-                String errMsg = "failed to delete volume " + filename + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "Deleted volume " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    @Override
-    synchronized public String getRootDir(String secUrl, Integer nfsVersion) {
-        if (!_inSystemVM) {
-            return _parent;
-        }
-        try {
-            URI uri = new URI(secUrl);
-            String dir = mountUri(uri, nfsVersion);
-            return _parent + "/" + dir;
-        } catch (Exception e) {
-            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    protected long getUsedSize(String rootDir) {
-        return _storage.getUsedSpace(rootDir);
-    }
-
-    protected long getTotalSize(String rootDir) {
-        return _storage.getTotalSpace(rootDir);
-    }
-
-    protected long convertFilesystemSize(final String size) {
-        if (size == null || size.isEmpty()) {
-            return -1;
-        }
-
-        long multiplier = 1;
-        if (size.endsWith("T")) {
-            multiplier = 1024l * 1024l * 1024l * 1024l;
-        } else if (size.endsWith("G")) {
-            multiplier = 1024l * 1024l * 1024l;
-        } else if (size.endsWith("M")) {
-            multiplier = 1024l * 1024l;
-        } else {
-            assert (false) : "Well, I have no idea what this is: " + size;
-        }
-
-        return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
-    }
-
-    @Override
-    public Type getType() {
-        if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) {
-            return Host.Type.SecondaryStorage;
-        }
-
-        return Host.Type.SecondaryStorageCmdExecutor;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(final long id) {
-        return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _eth1ip = (String)params.get("eth1ip");
-        _eth1mask = (String)params.get("eth1mask");
-        if (_eth1ip != null) { // can only happen inside service vm
-            params.put("private.network.device", "eth1");
-        } else {
-            s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
-        }
-        String eth2ip = (String)params.get("eth2ip");
-        if (eth2ip != null) {
-            params.put("public.network.device", "eth2");
-        }
-        _publicIp = (String)params.get("eth2ip");
-        _hostname = (String)params.get("name");
-
-        String inSystemVM = (String)params.get("secondary.storage.vm");
-        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
-            s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
-            _inSystemVM = true;
-        }
-
-        _storageIp = (String)params.get("storageip");
-        if (_storageIp == null && _inSystemVM) {
-            s_logger.warn("There is no storageip in /proc/cmdline, something wrong!");
-        }
-        _storageNetmask = (String)params.get("storagenetmask");
-        _storageGateway = (String)params.get("storagegateway");
-        super.configure(name, params);
-
-        _params = params;
-        String value = (String)params.get("scripts.timeout");
-        _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
-
-        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
-        configureStorageLayerClass(params);
-
-        if (_inSystemVM) {
-            _storage.mkdirs(_parent);
-        }
-
-        _configSslScr = Script.findScript(getDefaultScriptsDir(), "config_ssl.sh");
-        if (_configSslScr != null) {
-            s_logger.info("config_ssl.sh found in " + _configSslScr);
-        }
-
-        _configAuthScr = Script.findScript(getDefaultScriptsDir(), "config_auth.sh");
-        if (_configAuthScr != null) {
-            s_logger.info("config_auth.sh found in " + _configAuthScr);
-        }
-
-        _configIpFirewallScr = Script.findScript(getDefaultScriptsDir(), "ipfirewall.sh");
-        if (_configIpFirewallScr != null) {
-            s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
-        }
-
-        createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
-        if (createTemplateFromSnapshotXenScript == null) {
-            throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
-        }
-
-        _role = (String)params.get("role");
-        if (_role == null) {
-            _role = SecondaryStorageVm.Role.templateProcessor.toString();
-        }
-        s_logger.info("Secondary storage runs in role " + _role);
-
-        _guid = (String)params.get("guid");
-        if (_guid == null) {
-            throw new ConfigurationException("Unable to find the guid");
-        }
-
-        _dc = (String)params.get("zone");
-        if (_dc == null) {
-            throw new ConfigurationException("Unable to find the zone");
-        }
-        _pod = (String)params.get("pod");
-
-        _instance = (String)params.get("instance");
-
-        if (!_inSystemVM) {
-            _parent = (String)params.get("mount.path");
-        }
-
-        if (_inSystemVM) {
-            _localgw = (String)params.get("localgw");
-            if (_localgw != null) { // can only happen inside service vm
-                String mgmtHost = (String)params.get("host");
-                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
-
-                String internalDns1 = (String)params.get("internaldns1");
-                if (internalDns1 == null) {
-                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
-                } else {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
-                }
-
-                String internalDns2 = (String)params.get("internaldns2");
-                if (internalDns2 != null) {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
-                }
-
-            }
-
-            startAdditionalServices();
-            applyMtu(params);
-            _params.put("install.numthreads", "50");
-            _params.put("secondary.storage.vm", "true");
-            _nfsVersion = retrieveNfsVersionFromParams(params);
-        }
-
-        try {
-            _params.put(StorageLayer.InstanceConfigKey, _storage);
-            _dlMgr = new DownloadManagerImpl();
-            _dlMgr.configure("DownloadManager", _params);
-            _upldMgr = new UploadManagerImpl();
-            _upldMgr.configure("UploadManager", params);
-        } catch (ConfigurationException e) {
-            s_logger.warn("Caught problem while configuring DownloadManager", e);
-            return false;
-        }
-        return true;
-    }
-
-    protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
-        String value;
-        if (_storage == null) {
-            value = (String)params.get(StorageLayer.ClassConfigKey);
-            if (value == null) {
-                value = "com.cloud.storage.JavaStorageLayer";
-            }
-
-            try {
-                Class<?> clazz = Class.forName(value);
-                _storage = (StorageLayer)clazz.newInstance();
-                _storage.configure("StorageLayer", params);
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            }
-        }
-    }
-
-    private void startAdditionalServices() {
-        if (!_inSystemVM) {
-            return;
-        }
-        Script command = new Script("/bin/systemctl", s_logger);
-        command.add("restart");
-        command.add("ssh");
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in starting sshd service err=" + result);
-        }
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in opening up ssh port err=" + result);
-        }
-    }
-
-    private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
-        if (!_inSystemVM) {
-            return;
-        }
-        s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
-        if (destIpOrCidr == null) {
-            s_logger.debug("addRouteToInternalIp: destIp is null");
-            return;
-        }
-        if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) {
-            s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
-            return;
-        }
-        boolean inSameSubnet = false;
-        if (NetUtils.isValidIp4(destIpOrCidr)) {
-            if (eth1ip != null && eth1mask != null) {
-                inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
-            } else {
-                s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
-            }
-        } else {
-            inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
-        }
-        if (inSameSubnet) {
-            s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
-            return;
-        }
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ip route delete " + destIpOrCidr);
-        command.execute();
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ip route add " + destIpOrCidr + " via " + localgw);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in configuring route to internal ip err=" + result);
-        } else {
-            s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
-        }
-    }
-
-    private void configureSSL() {
-        if (!_inSystemVM) {
-            return;
-        }
-        Script command = new Script(_configSslScr);
-        command.add("-i", _publicIp);
-        command.add("-h", _hostname);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to configure httpd to use ssl");
-        }
-    }
-
-    private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath, String rootCACert) {
-        if (!_inSystemVM) {
-            return;
-        }
-        Script command = new Script(_configSslScr);
-        command.add("-i", _publicIp);
-        command.add("-h", _hostname);
-        command.add("-k", prvkeyPath);
-        command.add("-p", prvCertPath);
-        if (certChainPath != null) {
-            command.add("-t", certChainPath);
-        }
-        if (rootCACert != null) {
-            command.add("-u", rootCACert);
-        }
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to configure httpd to use ssl");
-        }
-    }
-
-    private String configureAuth(String user, String passwd) {
-        Script command = new Script(_configAuthScr);
-        command.add(user);
-        command.add(passwd);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to configure httpd to use auth");
-        }
-        return result;
-    }
-
-    private String configureIpFirewall(List<String> ipList, boolean isAppend) {
-        Script command = new Script(_configIpFirewallScr);
-        command.add(String.valueOf(isAppend));
-        for (String ip : ipList) {
-            command.add(ip);
-        }
-
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to configure firewall for command : " + command);
-        }
-        return result;
-    }
-
-    /**
-     * Mount remote device named on local file system on subfolder of _parent
-     * field.
-     * <p>
-     *
-     * Supported schemes are "nfs" and "cifs".
-     * <p>
-     *
-     * CIFS parameters are documented with mount.cifs at
-     * http://linux.die.net/man/8/mount.cifs
-     * For simplicity, when a URI is used to specify a CIFS share,
-     * options such as domain,user,password are passed as query parameters.
-     *
-     * @param uri
-     *            crresponding to the remote device. Will throw for unsupported
-     *            scheme.
-     * @param nfsVersion NFS version to use in mount command
-     * @return name of folder in _parent that device was mounted.
-     * @throws UnknownHostException
-     */
-    protected String mountUri(URI uri, Integer nfsVersion) throws UnknownHostException {
-        String uriHostIp = getUriHostIp(uri);
-        String nfsPath = uriHostIp + ":" + uri.getPath();
-
-        // Single means of calculating mount directory regardless of scheme
-        String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes(com.cloud.utils.StringUtils.getPreferredCharset())).toString();
-        String localRootPath = _parent + "/" + dir;
-
-        // remote device syntax varies by scheme.
-        String remoteDevice;
-        if (uri.getScheme().equals("cifs")) {
-            remoteDevice = "//" + uriHostIp + uri.getPath();
-            s_logger.debug("Mounting device with cifs-style path of " + remoteDevice);
-        } else {
-            remoteDevice = nfsPath;
-            s_logger.debug("Mounting device with nfs-style path of " + remoteDevice);
-        }
-        mount(localRootPath, remoteDevice, uri, nfsVersion);
-        return dir;
-    }
-
-    protected void umount(String localRootPath, URI uri) {
-        ensureLocalRootPathExists(localRootPath, uri);
-
-        if (!mountExists(localRootPath, uri)) {
-            return;
-        }
-
-        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
-        command.add(localRootPath);
-        String result = command.execute();
-        if (result != null) {
-            // Fedora Core 12 errors out with any -o option executed from java
-            String errMsg = "Unable to umount " + localRootPath + " due to " + result;
-            s_logger.error(errMsg);
-            File file = new File(localRootPath);
-            if (file.exists()) {
-                file.delete();
-            }
-            throw new CloudRuntimeException(errMsg);
-        }
-        s_logger.debug("Successfully umounted " + localRootPath);
-    }
-
-    protected void mount(String localRootPath, String remoteDevice, URI uri, Integer nfsVersion) {
-        s_logger.debug("mount " + uri.toString() + " on " + localRootPath + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
-        ensureLocalRootPathExists(localRootPath, uri);
-
-        if (mountExists(localRootPath, uri)) {
-            return;
-        }
-
-        attemptMount(localRootPath, remoteDevice, uri, nfsVersion);
-
-        // XXX: Adding the check for creation of snapshots dir here. Might have
-        // to move it somewhere more logical later.
-        checkForSnapshotsDir(localRootPath);
-        checkForVolumesDir(localRootPath);
-    }
-
-    protected void attemptMount(String localRootPath, String remoteDevice, URI uri, Integer nfsVersion) {
-        String result;
-        s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : ""));
-        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
-
-        String scheme = uri.getScheme().toLowerCase();
-        command.add("-t", scheme);
-
-        if (scheme.equals("nfs")) {
-            if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) {
-                // See http://wiki.qnap.com/wiki/Mounting_an_NFS_share_from_OS_X
-                command.add("-o", "resvport");
-            }
-            if (_inSystemVM) {
-                command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0" + ((nfsVersion != null) ? ",vers=" + nfsVersion : ""));
-            }
-        } else if (scheme.equals("cifs")) {
-            String extraOpts = parseCifsMountOptions(uri);
-
-            // nfs acdirmax / acdirmin correspoonds to CIFS actimeo (see
-            // http://linux.die.net/man/8/mount.cifs)
-            // no equivalent to nfs timeo, retrans or tcp in CIFS
-            // todo: allow security mode to be set.
-            command.add("-o", extraOpts + "soft,actimeo=0");
-        } else {
-            String errMsg = "Unsupported storage device scheme " + scheme + " in uri " + uri.toString();
-            s_logger.error(errMsg);
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        command.add(remoteDevice);
-        command.add(localRootPath);
-        result = command.execute();
-        if (result != null) {
-            // Fedora Core 12 errors out with any -o option executed from java
-            String errMsg = "Unable to mount " + remoteDevice + " at " + localRootPath + " due to " + result;
-            s_logger.error(errMsg);
-            File file = new File(localRootPath);
-            if (file.exists()) {
-                file.delete();
-            }
-            throw new CloudRuntimeException(errMsg);
-        }
-        s_logger.debug("Successfully mounted " + remoteDevice + " at " + localRootPath);
-    }
-
-    protected String parseCifsMountOptions(URI uri) {
-        List<NameValuePair> args = URLEncodedUtils.parse(uri, "UTF-8");
-        boolean foundUser = false;
-        boolean foundPswd = false;
-        StringBuilder extraOpts = new StringBuilder();
-        for (NameValuePair nvp : args) {
-            String name = nvp.getName();
-            if (name.equals("user")) {
-                foundUser = true;
-                s_logger.debug("foundUser is" + foundUser);
-            } else if (name.equals("password")) {
-                foundPswd = true;
-                s_logger.debug("password is present in uri");
-            }
-
-            extraOpts.append(name + "=" + nvp.getValue() + ",");
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.error("extraOpts now " + extraOpts);
-        }
-
-        if (!foundUser || !foundPswd) {
-            String errMsg = "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'.  E.g. "
-                    + "cifs://example.com/some_share?user=foo&password=bar";
-            s_logger.error(errMsg);
-            throw new CloudRuntimeException(errMsg);
-        }
-        return extraOpts.toString();
-    }
-
-    protected boolean mountExists(String localRootPath, URI uri) {
-        Script script = null;
-        script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
-
-        List<String> res = new ArrayList<String>();
-        ZfsPathParser parser = new ZfsPathParser(localRootPath);
-        script.execute(parser);
-        res.addAll(parser.getPaths());
-        for (String s : res) {
-            if (s.contains(localRootPath)) {
-                s_logger.debug("Some device already mounted at " + localRootPath + ", no need to mount " + uri.toString());
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected void ensureLocalRootPathExists(String localRootPath, URI uri) {
-        s_logger.debug("making available " + localRootPath + " on " + uri.toString());
-        File file = new File(localRootPath);
-        s_logger.debug("local folder for mount will be " + file.getPath());
-        if (!file.exists()) {
-            s_logger.debug("create mount point: " + file.getPath());
-            _storage.mkdir(file.getPath());
-
-            // Need to check after mkdir to allow O/S to complete operation
-            if (!file.exists()) {
-                String errMsg = "Unable to create local folder for: " + localRootPath + " in order to mount " + uri.toString();
-                s_logger.error(errMsg);
-                throw new CloudRuntimeException(errMsg);
-            }
-        }
-    }
-
-    protected String getUriHostIp(URI uri) throws UnknownHostException {
-        String nfsHost = uri.getHost();
-        InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
-        String nfsHostIp = nfsHostAddr.getHostAddress();
-        s_logger.info("Determined host " + nfsHost + " corresponds to IP " + nfsHostIp);
-        return nfsHostIp;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-
-        final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
-        fillNetworkInformation(cmd);
-        if (_publicIp != null) {
-            cmd.setPublicIpAddress(_publicIp);
-        }
-
-        if (_inSystemVM) {
-            Script command = new Script("/bin/bash", s_logger);
-            command.add("-c");
-            command.add("ln -sf " + _parent + " /var/www/html/copy");
-            String result = command.execute();
-            if (result != null) {
-                s_logger.warn("Error in linking  err=" + result);
-                return null;
-            }
-        }
-        return new StartupCommand[] {cmd};
-    }
-
-    protected boolean checkForSnapshotsDir(String mountPoint) {
-        String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
-        return createDir("snapshots", snapshotsDirLocation, mountPoint);
-    }
-
-    protected boolean checkForVolumesDir(String mountPoint) {
-        String volumesDirLocation = mountPoint + "/" + "volumes";
-        return createDir("volumes", volumesDirLocation, mountPoint);
-    }
-
-    protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
-        boolean dirExists = false;
-
-        File dir = new File(dirLocation);
-        if (dir.exists()) {
-            if (dir.isDirectory()) {
-                s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
-                dirExists = true;
-            } else {
-                if (dir.delete() && _storage.mkdir(dirLocation)) {
-                    dirExists = true;
-                }
-            }
-        } else if (_storage.mkdir(dirLocation)) {
-            dirExists = true;
-        }
-
-        if (dirExists) {
-            s_logger.info(dirName + " directory created/exists on Secondary Storage.");
-        } else {
-            s_logger.info(dirName + " directory does not exist on Secondary Storage.");
-        }
-
-        return dirExists;
-    }
-
-    @Override
-    protected String getDefaultScriptsDir() {
-        return "./scripts/storage/secondary";
-    }
-
-    @Override
-    public void setName(String name) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setConfigParams(Map<String, Object> params) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Map<String, Object> getConfigParams() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getRunLevel() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void setRunLevel(int level) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void fillNetworkInformation(final StartupCommand cmd) {
-        final String dummyMac = "00:06:0A:0B:0C:0D";
-        final String dummyNetmask = "255.255.255.0";
-        if (!_inSystemVM) {
-            cmd.setPrivateIpAddress(_eth1ip);
-            cmd.setPrivateMacAddress(dummyMac);
-            cmd.setPrivateNetmask(dummyNetmask);
-            cmd.setPublicIpAddress(_publicIp);
-            cmd.setPublicMacAddress(dummyMac);
-            cmd.setPublicNetmask(dummyNetmask);
-            cmd.setName(_hostname);
-        } else {
-            super.fillNetworkInformation(cmd);
-        }
-    }
-
-    private String getScriptLocation(UploadEntity.ResourceType resourceType) {
-
-        String scriptsDir = (String)_params.get("template.scripts.dir");
-        if (scriptsDir == null) {
-            scriptsDir = "scripts/storage/secondary";
-        }
-        String scriptname = null;
-        if (resourceType == UploadEntity.ResourceType.VOLUME) {
-            scriptname = "createvolume.sh";
-        } else if (resourceType == UploadEntity.ResourceType.TEMPLATE) {
-            scriptname = "createtmplt.sh";
-        } else {
-            throw new InvalidParameterValueException("cannot find script for resource type: " + resourceType);
-        }
-        return Script.findScript(scriptsDir, scriptname);
-    }
-
-    public UploadEntity createUploadEntity(String uuid, String metadata, long contentLength) {
-        TemplateOrVolumePostUploadCommand cmd = getTemplateOrVolumePostUploadCmd(metadata);
-        UploadEntity uploadEntity = null;
-        if (cmd == null) {
-            String errorMessage = "unable decode and deserialize metadata.";
-            updateStateMapWithError(uuid, errorMessage);
-            throw new InvalidParameterValueException(errorMessage);
-        } else {
-            uuid = cmd.getEntityUUID();
-            processTimeout = cmd.getProcessTimeout();
-            if (isOneTimePostUrlUsed(cmd)) {
-                uploadEntity = uploadEntityStateMap.get(uuid);
-                StringBuilder errorMessage = new StringBuilder("The one time post url is already used");
-                if (uploadEntity != null) {
-                    errorMessage.append(" and the upload is in ").append(uploadEntity.getUploadState()).append(" state.");
-                }
-                throw new InvalidParameterValueException(errorMessage.toString());
-            }
-            int maxSizeInGB = Integer.parseInt(cmd.getMaxUploadSize());
-            int contentLengthInGB = getSizeInGB(contentLength);
-            if (contentLengthInGB > maxSizeInGB) {
-                String errorMessage = "Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " + maxSizeInGB + "GB.";
-                updateStateMapWithError(uuid, errorMessage);
-                throw new InvalidParameterValueException(errorMessage);
-            }
-            checkSecondaryStorageResourceLimit(cmd, contentLengthInGB);
-            try {
-                String absolutePath = cmd.getAbsolutePath();
-                uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
-                uploadEntity.setMetaDataPopulated(true);
-                uploadEntity.setResourceType(UploadEntity.ResourceType.valueOf(cmd.getType()));
-                uploadEntity.setProcessTimeout(processTimeout);
-                uploadEntity.setFormat(Storage.ImageFormat.valueOf(cmd.getImageFormat()));
-                //relative path with out ssvm mount info.
-                uploadEntity.setTemplatePath(absolutePath);
-                String dataStoreUrl = cmd.getDataTo();
-                String installPathPrefix = this.getRootDir(dataStoreUrl, cmd.getNfsVersion()) + File.separator + absolutePath;
-                uploadEntity.setInstallPathPrefix(installPathPrefix);
-                uploadEntity.setHvm(cmd.getRequiresHvm());
-                uploadEntity.setChksum(cmd.getChecksum());
-                uploadEntity.setMaxSizeInGB(maxSizeInGB);
-                uploadEntity.setDescription(cmd.getDescription());
-                uploadEntity.setContentLength(contentLength);
-                // create a install dir
-                if (!_storage.exists(installPathPrefix)) {
-                    _storage.mkdir(installPathPrefix);
-                }
-                uploadEntityStateMap.put(uuid, uploadEntity);
-            } catch (Exception e) {
-                //upload entity will be null incase an exception occurs and the handler will not proceed.
-                s_logger.error("exception occurred while creating upload entity ", e);
-                updateStateMapWithError(uuid, e.getMessage());
-            }
-        }
-        return uploadEntity;
-    }
-
-    private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) {
-        String rootDir = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator;
-        long accountId = cmd.getAccountId();
-
-        long accountTemplateDirSize = 0;
-        File accountTemplateDir = new File(rootDir + getTemplatePathForAccount(accountId));
-        if (accountTemplateDir.exists()) {
-            FileUtils.sizeOfDirectory(accountTemplateDir);
-        }
-        long accountVolumeDirSize = 0;
-        File accountVolumeDir = new File(rootDir + getVolumePathForAccount(accountId));
-        if (accountVolumeDir.exists()) {
-            accountVolumeDirSize = FileUtils.sizeOfDirectory(accountVolumeDir);
-        }
-        long accountSnapshotDirSize = 0;
-        File accountSnapshotDir = new File(rootDir + getSnapshotPathForAccount(accountId));
-        if (accountSnapshotDir.exists()) {
-            accountSnapshotDirSize = FileUtils.sizeOfDirectory(accountSnapshotDir);
-        }
-        s_logger.debug(
-                "accountTemplateDirSize: " + accountTemplateDirSize + " accountSnapshotDirSize: " + accountSnapshotDirSize + " accountVolumeDirSize: " + accountVolumeDirSize);
-
-        int accountDirSizeInGB = getSizeInGB(accountTemplateDirSize + accountSnapshotDirSize + accountVolumeDirSize);
-        int defaultMaxAccountSecondaryStorageInGB = Integer.parseInt(cmd.getDefaultMaxAccountSecondaryStorage());
-
-        if (defaultMaxAccountSecondaryStorageInGB != Resource.RESOURCE_UNLIMITED && (accountDirSizeInGB + contentLengthInGB) > defaultMaxAccountSecondaryStorageInGB) {
-            s_logger.error("accountDirSizeInGb: " + accountDirSizeInGB + " defaultMaxAccountSecondaryStorageInGB: " + defaultMaxAccountSecondaryStorageInGB + " contentLengthInGB:"
-                    + contentLengthInGB);
-            String errorMessage = "Maximum number of resources of type secondary_storage for account has exceeded";
-            updateStateMapWithError(cmd.getEntityUUID(), errorMessage);
-            throw new InvalidParameterValueException(errorMessage);
-        }
-    }
-
-    private String getVolumePathForAccount(long accountId) {
-        return TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + accountId;
-    }
-
-    private String getTemplatePathForAccount(long accountId) {
-        return TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + accountId;
-    }
-
-    private String getSnapshotPathForAccount(long accountId) {
-        return TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId;
-    }
-
-    private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) {
-        String uuid = cmd.getEntityUUID();
-        String uploadPath = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator + cmd.getAbsolutePath();
-        return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists();
-    }
-
-    private int getSizeInGB(long sizeInBytes) {
-        return (int)Math.ceil(sizeInBytes * 1.0d / (1024 * 1024 * 1024));
-    }
-
-    public String postUpload(String uuid, String filename, long processTimeout) {
-        UploadEntity uploadEntity = uploadEntityStateMap.get(uuid);
-        int installTimeoutPerGig = 180 * 60 * 1000;
-
-        String resourcePath = uploadEntity.getInstallPathPrefix();
-        String finalResourcePath = uploadEntity.getTmpltPath(); // template download
-        UploadEntity.ResourceType resourceType = uploadEntity.getResourceType();
-
-        String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
-
-        String uploadedFileExtension = FilenameUtils.getExtension(filename);
-        String userSelectedFormat = uploadEntity.getFormat().toString();
-        if (uploadedFileExtension.equals("zip") || uploadedFileExtension.equals("bz2") || uploadedFileExtension.equals("gz")) {
-            userSelectedFormat += "." + uploadedFileExtension;
-        }
-        String formatError = ImageStoreUtil.checkTemplateFormat(fileSavedTempLocation, userSelectedFormat);
-        if (StringUtils.isNotBlank(formatError)) {
-            String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + userSelectedFormat + ". Received: " + formatError;
-            s_logger.error(errorString);
-            return errorString;
-        }
-
-        int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
-        int maxSize = uploadEntity.getMaxSizeInGB();
-        if (imgSizeGigs > maxSize) {
-            String errorMessage = "Maximum file upload size exceeded. Physical file size: " + imgSizeGigs + "GB. Maximum allowed size: " + maxSize + "GB.";
-            s_logger.error(errorMessage);
-            return errorMessage;
-        }
-        imgSizeGigs++; // add one just in case
-        long timeout = (long)imgSizeGigs * installTimeoutPerGig;
-        Script scr = new Script(getScriptLocation(resourceType), timeout, s_logger);
-        scr.add("-s", Integer.toString(imgSizeGigs));
-        scr.add("-S", Long.toString(UploadEntity.s_maxTemplateSize));
-        if (uploadEntity.getDescription() != null && uploadEntity.getDescription().length() > 1) {
-            scr.add("-d", uploadEntity.getDescription());
-        }
-        if (uploadEntity.isHvm()) {
-            scr.add("-h");
-        }
-        String checkSum = uploadEntity.getChksum();
-        if (StringUtils.isNotBlank(checkSum)) {
-            scr.add("-c", checkSum);
-        }
-
-        // add options common to ISO and template
-        String extension = uploadEntity.getFormat().getFileExtension();
-        String templateName = "";
-        if (extension.equals("iso")) {
-            templateName = uploadEntity.getUuid().trim().replace(" ", "_");
-        } else {
-            try {
-                templateName = UUID.nameUUIDFromBytes((uploadEntity.getFilename() + System.currentTimeMillis()).getBytes("UTF-8")).toString();
-            } catch (UnsupportedEncodingException e) {
-                templateName = uploadEntity.getUuid().trim().replace(" ", "_");
-            }
-        }
-
-        // run script to mv the temporary template file to the final template
-        // file
-        String templateFilename = templateName + "." + extension;
-        uploadEntity.setTemplatePath(finalResourcePath + "/" + templateFilename);
-        scr.add("-n", templateFilename);
-
-        scr.add("-t", resourcePath);
-        scr.add("-f", fileSavedTempLocation); // this is the temporary
-        // template file downloaded
-        if (uploadEntity.getChksum() != null && uploadEntity.getChksum().length() > 1) {
-            scr.add("-c", uploadEntity.getChksum());
-        }
-        scr.add("-u"); // cleanup
-        String result;
-        result = scr.execute();
-
-        if (result != null) {
-            return result;
-        }
-
-        // Set permissions for the downloaded template
-        File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
-        _storage.setWorldReadableAndWriteable(downloadedTemplate);
-
-        // Set permissions for template/volume.properties
-        String propertiesFile = resourcePath;
-        if (resourceType == UploadEntity.ResourceType.TEMPLATE) {
-            propertiesFile += "/template.properties";
-        } else {
-            propertiesFile += "/volume.properties";
-        }
-        File templateProperties = new File(propertiesFile);
-        _storage.setWorldReadableAndWriteable(templateProperties);
-
-        TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
-        try {
-            loc.create(uploadEntity.getEntityId(), true, uploadEntity.getFilename());
-        } catch (IOException e) {
-            s_logger.warn("Something is wrong with template location " + resourcePath, e);
-            loc.purge();
-            return "Unable to upload due to " + e.getMessage();
-        }
-
-        Map<String, Processor> processors = _dlMgr.getProcessors();
-        for (Processor processor : processors.values()) {
-            FormatInfo info = null;
-            try {
-                info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
-            } catch (InternalErrorException e) {
-                s_logger.error("Template process exception ", e);
-                return e.toString();
-            }
-            if (info != null) {
-                loc.addFormat(info);
-                uploadEntity.setVirtualSize(info.virtualSize);
-                uploadEntity.setPhysicalSize(info.size);
-                break;
-            }
-        }
-
-        if (!loc.save()) {
-            s_logger.warn("Cleaning up because we're unable to save the formats");
-            loc.purge();
-        }
-        uploadEntity.setStatus(UploadEntity.Status.COMPLETED);
-        uploadEntityStateMap.put(uploadEntity.getUuid(), uploadEntity);
-        return null;
-    }
-
-    private String getPostUploadPSK() {
-        if (_ssvmPSK == null) {
-            try {
-                _ssvmPSK = FileUtils.readFileToString(new File(POST_UPLOAD_KEY_LOCATION), "utf-8");
-            } catch (IOException e) {
-                s_logger.debug("Error while reading SSVM PSK from location " + POST_UPLOAD_KEY_LOCATION, e);
-            }
-        }
-        return _ssvmPSK;
-    }
-
-    public void updateStateMapWithError(String uuid, String errorMessage) {
-        UploadEntity uploadEntity = null;
-        if (uploadEntityStateMap.get(uuid) != null) {
-            uploadEntity = uploadEntityStateMap.get(uuid);
-        } else {
-            uploadEntity = new UploadEntity();
-        }
-        uploadEntity.setStatus(UploadEntity.Status.ERROR);
-        uploadEntity.setErrorMessage(errorMessage);
-        uploadEntityStateMap.put(uuid, uploadEntity);
-    }
-
-    public void validatePostUploadRequest(String signature, String metadata, String timeout, String hostname, long contentLength, String uuid)
-            throws InvalidParameterValueException {
-        // check none of the params are empty
-        if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(metadata) || StringUtils.isEmpty(timeout)) {
-            updateStateMapWithError(uuid, "signature, metadata and expires are compulsory fields.");
-            throw new InvalidParameterValueException("signature, metadata and expires are compulsory fields.");
-        }
-
-        //check that contentLength exists and is greater than zero
-        if (contentLength <= 0) {
-            throw new InvalidParameterValueException("content length is not set in the request or has invalid value.");
-        }
-
-        //validate signature
-        String fullUrl = "https://" + hostname + "/upload/" + uuid;
-        String computedSignature = EncryptionUtil.generateSignature(metadata + fullUrl + timeout, getPostUploadPSK());
-        boolean isSignatureValid = computedSignature.equals(signature);
-        if (!isSignatureValid) {
-            updateStateMapWithError(uuid, "signature validation failed.");
-            throw new InvalidParameterValueException("signature validation failed.");
-        }
-
-        //validate timeout
-        DateTime timeoutDateTime = DateTime.parse(timeout, ISODateTimeFormat.dateTime());
-        if (timeoutDateTime.isBeforeNow()) {
-            updateStateMapWithError(uuid, "request not valid anymore.");
-            throw new InvalidParameterValueException("request not valid anymore.");
-        }
-    }
-
-    private TemplateOrVolumePostUploadCommand getTemplateOrVolumePostUploadCmd(String metadata) {
-        TemplateOrVolumePostUploadCommand cmd = null;
-        try {
-            Gson gson = new GsonBuilder().create();
-            cmd = gson.fromJson(EncryptionUtil.decodeData(metadata, getPostUploadPSK()), TemplateOrVolumePostUploadCommand.class);
-        } catch (Exception ex) {
-            s_logger.error("exception while decoding and deserialising metadata", ex);
-        }
-        return cmd;
-    }
-
-}
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
similarity index 100%
rename from services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
rename to services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
similarity index 100%
rename from services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
rename to services/secondary-storage/server/src/test/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
diff --git a/setup/db/create-schema-premium.sql b/setup/db/create-schema-premium.sql
index 3c86710..d8d60ff 100644
--- a/setup/db/create-schema-premium.sql
+++ b/setup/db/create-schema-premium.sql
@@ -285,42 +285,4 @@
 
 USE `cloud`;
 
-CREATE TABLE `cloud`.`netapp_volume` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `ip_address` varchar(255) NOT NULL COMMENT 'ip address/fqdn of the volume',
-  `pool_id` bigint unsigned NOT NULL COMMENT 'id for the pool',
-  `pool_name` varchar(255) NOT NULL COMMENT 'name for the pool',
-  `aggregate_name` varchar(255) NOT NULL COMMENT 'name for the aggregate',
-  `volume_name` varchar(255) NOT NULL COMMENT 'name for the volume',
-  `volume_size` varchar(255) NOT NULL COMMENT 'volume size',
-  `snapshot_policy` varchar(255) NOT NULL COMMENT 'snapshot policy',
-  `snapshot_reservation` int NOT NULL COMMENT 'snapshot reservation',  
-  `username` varchar(255) NOT NULL COMMENT 'username',  
-  `password` varchar(200) COMMENT 'password',
-  `round_robin_marker` int COMMENT 'This marks the volume to be picked up for lun creation, RR fashion',
-  PRIMARY KEY  (`id`),
-  CONSTRAINT `fk_netapp_volume__pool_id` FOREIGN KEY `fk_netapp_volume__pool_id` (`pool_id`) REFERENCES `cloud`.`netapp_pool` (`id`) ON DELETE CASCADE,
-  INDEX `i_netapp_volume__pool_id`(`pool_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `cloud`.`netapp_pool` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `name` varchar(255) NOT NULL UNIQUE COMMENT 'name for the pool',
-  `algorithm` varchar(255) NOT NULL COMMENT 'algorithm',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `cloud`.`netapp_lun` (
-  `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
-  `lun_name` varchar(255) NOT NULL COMMENT 'lun name',
-  `target_iqn` varchar(255) NOT NULL COMMENT 'target iqn',
-  `path` varchar(255) NOT NULL COMMENT 'lun path',
-  `size` bigint NOT NULL COMMENT 'lun size',
-  `volume_id` bigint unsigned NOT NULL COMMENT 'parent volume id',
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_netapp_lun__volume_id` FOREIGN KEY `fk_netapp_lun__volume_id` (`volume_id`) REFERENCES `cloud`.`netapp_volume` (`id`) ON DELETE CASCADE,
-  INDEX `i_netapp_lun__volume_id`(`volume_id`),
-  INDEX `i_netapp_lun__lun_name`(`lun_name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
 SET foreign_key_checks = 1;
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index 7665aec..2c680918 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -195,9 +195,6 @@
 DROP TABLE IF EXISTS `cloud`.`vm_compute_tags`;
 DROP TABLE IF EXISTS `cloud`.`vm_root_disk_tags`;
 DROP TABLE IF EXISTS `cloud`.`vm_network_map`;
-DROP TABLE IF EXISTS `cloud`.`netapp_volume`;
-DROP TABLE IF EXISTS `cloud`.`netapp_pool`;
-DROP TABLE IF EXISTS `cloud`.`netapp_lun`;
 
 CREATE TABLE `cloud`.`version` (
   `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
diff --git a/setup/db/hypervisor_capabilities.simulator.sql b/setup/db/hypervisor_capabilities.simulator.sql
index 32f9aaa..f0644f7 100755
--- a/setup/db/hypervisor_capabilities.simulator.sql
+++ b/setup/db/hypervisor_capabilities.simulator.sql
@@ -16,4 +16,4 @@
 -- under the License.
 
 
-INSERT INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'Simulator', 'default', 50, 1, 6, NULL, 0, 1);
+INSERT INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'Simulator', 'default', 50, 1, 6, NULL, 1, 1);
diff --git a/systemvm/debian/opt/cloud/bin/cs/CsHelper.py b/systemvm/debian/opt/cloud/bin/cs/CsHelper.py
index ff404f0..278e1e6 100755
--- a/systemvm/debian/opt/cloud/bin/cs/CsHelper.py
+++ b/systemvm/debian/opt/cloud/bin/cs/CsHelper.py
@@ -188,6 +188,8 @@
         logging.info("Executing: %s" % command)
         result = subprocess.check_output(command, shell=True)
         returncode = 0
+
+        logging.debug("Command [%s] has the result [%s]" % (command, result))
         return result.splitlines()
     except subprocess.CalledProcessError as e:
         logging.error(e)
diff --git a/systemvm/debian/opt/cloud/bin/diagnostics.py b/systemvm/debian/opt/cloud/bin/diagnostics.py
new file mode 100755
index 0000000..477f99d
--- /dev/null
+++ b/systemvm/debian/opt/cloud/bin/diagnostics.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# 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 shlex
+import subprocess
+import sys
+
+
+def run_cmd(command):
+    if command is not None:
+        try:
+            p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            stdout, stderr = p.communicate()
+            return_code = p.returncode
+
+        except OSError as e:
+            stdout = "Check your command type"
+            stderr = "Exception occurred: %s" % e
+            return_code = 1
+
+        finally:
+            print('%s&&' % stdout.strip())
+            print('%s&&' % stderr.strip())
+            print('%s' % return_code)
+
+
+def get_command():
+    arguments = sys.argv
+    cmd = " ".join(arguments[1:])
+    cmd_type = sys.argv[1]
+
+    if cmd_type == 'ping':
+        if '-c' in arguments:
+            return cmd
+        else:
+            return cmd + " -c 4"
+
+    elif cmd_type == 'traceroute':
+        if '-m' in arguments:
+            return cmd
+        else:
+            return cmd + " -m 20"
+
+    elif cmd_type == 'arping':
+        if '-c' in arguments:
+            return cmd
+        else:
+            return cmd + " -c 4"
+
+    else:
+        return None
+
+
+if __name__ == "__main__":
+    command = get_command()
+    run_cmd(command)
diff --git a/systemvm/pom.xml b/systemvm/pom.xml
index e42c154..a31b0b4 100644
--- a/systemvm/pom.xml
+++ b/systemvm/pom.xml
@@ -1,241 +1,238 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-systemvm</artifactId>
-  <name>Apache CloudStack System VM</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <properties>
-    <mkisofs>mkisofs</mkisofs>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-agent</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-secondary-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-console-proxy</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <configuration>
-          <finalName>agent</finalName>
-          <appendAssemblyId>false</appendAssemblyId>
-          <descriptors>
-            <descriptor>systemvm-agent-descriptor.xml</descriptor>
-          </descriptors>
-        </configuration>
-        <executions>
-          <execution>
-            <id>make-systemvm</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy-resources</id>
-            <!-- here the phase you need -->
-            <phase>package</phase>
-            <goals>
-              <goal>copy-resources</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>dist</outputDirectory>
-              <resources>          
-                <resource>
-                  <directory>target</directory>
-                  <includes>
-                    <include>agent.zip</include>
-                  </includes>
-                </resource>
-              </resources>              
-            </configuration>            
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>build-cloud-scripts</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <mkdir dir="${basedir}/dist" />
-                <mkdir dir="${basedir}/target/build-patch" />
-                <copy overwrite="true" todir="${basedir}/target/build-patch">
-                  <fileset dir="${basedir}/debian/">
-                    <include name="**/*" />
-                  </fileset>
-                </copy>
-                <copy overwrite="true" todir="${basedir}/target/build-patch/opt/cloud/bin/">
-                  <fileset dir="${basedir}/../scripts/util/">
-                    <include name="**/keystore-*" />
-                  </fileset>
-                </copy>
-                <tar destfile="${basedir}/target/patch.tar">
-                  <tarfileset dir="${basedir}/target/build-patch/"
-                    filemode="755">
-                    <include name="**/*" />
-                    <exclude name="**/.classpath" />
-                    <exclude name="**/log**"/>
-                    <exclude name="**/logrotate.d"/>
-                    <exclude name="**/.project" />
-                    <exclude name="**/wscript_build" />
-                  </tarfileset>
-                  <tarfileset dir="${basedir}/target/build-patch/"
-                   filemode="644">
-                   <include name="**/log**"/>
-                   <include name="**/logrotate.d/**"/>
-                  </tarfileset>
-                </tar>
-                <gzip destfile="${basedir}/dist/cloud-scripts.tgz" src="${basedir}/target/patch.tar" />
-                <delete dir="${basedir}/target/build-patch" />
-                <delete file="${basedir}/target/patch.tar" />
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    <plugin>
-      <groupId>org.codehaus.mojo</groupId>
-       <artifactId>exec-maven-plugin</artifactId>
-       <version>1.2.1</version>
-       <executions>
-         <execution>
-           <phase>package</phase>
-           <goals>
-             <goal>exec</goal>
-           </goals>
-         </execution>
-       </executions>
-       <configuration>
-         <executable>${mkisofs}</executable>
-         <workingDirectory>dist</workingDirectory>
-         <arguments>
-           <argument>-quiet</argument>
-           <argument>-r</argument>
-           <argument>-o</argument>
-           <argument>systemvm.iso</argument>
-           <argument>agent.zip</argument>
-           <argument>cloud-scripts.tgz</argument>
-         </arguments>
-       </configuration>
-     </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <!-- Debian will never distribute mkisofs due to licensing issues.
-         Fortunately genisoimage is a work-alike -->
-    <profile>
-      <id>genisoimage</id>
-      <activation>
-        <file>
-          <exists>/usr/bin/genisoimage</exists>
-        </file>
-      </activation>
-      <properties>
-        <mkisofs>genisoimage</mkisofs>
-      </properties>
-    </profile>
-    <profile>
-      <id>vmware</id>
-      <activation>
-        <property>
-          <name>noredist</name>
-        </property>
-      </activation>
-        <dependencies>
-            <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-vmware-base</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-        </dependencies>
-    </profile>
-    <profile>
-      <id>quickcloud</id>
-      <build>
-      <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>java</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <mainClass>com.cloud.agent.AgentShell</mainClass>
-          <arguments>
-            <argument>zone=1</argument>
-            <argument>pod=1</argument>
-            <argument>host=192.168.56.1</argument>
-            <argument>guid=ConsoleProxy.1</argument>
-          </arguments>
-          <systemProperties>
-            <systemProperty>
-              <key>javax.net.ssl.trustStore</key>
-              <value>certs/realhostip.keystore</value>
-              <key>log.home</key>
-              <value>${PWD}/</value>
-            </systemProperty>
-          </systemProperties>
-        </configuration>
-      </plugin>
-      </plugins>
+<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-systemvm</artifactId>
+    <name>Apache CloudStack System VM</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <properties>
+        <mkisofs>mkisofs</mkisofs>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-agent</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-secondary-storage</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-console-proxy</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <finalName>agent</finalName>
+                    <appendAssemblyId>false</appendAssemblyId>
+                    <descriptors>
+                        <descriptor>systemvm-agent-descriptor.xml</descriptor>
+                    </descriptors>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-systemvm</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <!-- here the phase you need -->
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>dist</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>target</directory>
+                                    <includes>
+                                        <include>agent.zip</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>build-cloud-scripts</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target>
+                                <mkdir dir="${basedir}/dist" />
+                                <mkdir dir="${basedir}/target/build-patch" />
+                                <copy overwrite="true" todir="${basedir}/target/build-patch">
+                                    <fileset dir="${basedir}/debian/">
+                                        <include name="**/*" />
+                                    </fileset>
+                                </copy>
+                                <copy overwrite="true" todir="${basedir}/target/build-patch/opt/cloud/bin/">
+                                    <fileset dir="${basedir}/../scripts/util/">
+                                        <include name="**/keystore-*" />
+                                    </fileset>
+                                </copy>
+                                <tar destfile="${basedir}/target/patch.tar">
+                                    <tarfileset dir="${basedir}/target/build-patch/" filemode="755">
+                                        <include name="**/*" />
+                                        <exclude name="**/.classpath" />
+                                        <exclude name="**/log**" />
+                                        <exclude name="**/logrotate.d" />
+                                        <exclude name="**/.project" />
+                                        <exclude name="**/wscript_build" />
+                                    </tarfileset>
+                                    <tarfileset dir="${basedir}/target/build-patch/" filemode="644">
+                                        <include name="**/log**" />
+                                        <include name="**/logrotate.d/**" />
+                                    </tarfileset>
+                                </tar>
+                                <gzip destfile="${basedir}/dist/cloud-scripts.tgz" src="${basedir}/target/patch.tar" />
+                                <delete dir="${basedir}/target/build-patch" />
+                                <delete file="${basedir}/target/patch.tar" />
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <executable>${mkisofs}</executable>
+                    <workingDirectory>dist</workingDirectory>
+                    <arguments>
+                        <argument>-quiet</argument>
+                        <argument>-r</argument>
+                        <argument>-o</argument>
+                        <argument>systemvm.iso</argument>
+                        <argument>agent.zip</argument>
+                        <argument>cloud-scripts.tgz</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+        </plugins>
     </build>
-  </profile>
-  </profiles>
-
+    <profiles>
+        <!-- Debian will never distribute mkisofs due to licensing issues. Fortunately genisoimage is a work-alike -->
+        <profile>
+            <id>genisoimage</id>
+            <activation>
+                <file>
+                    <exists>/usr/bin/genisoimage</exists>
+                </file>
+            </activation>
+            <properties>
+                <mkisofs>genisoimage</mkisofs>
+            </properties>
+        </profile>
+        <profile>
+            <id>vmware</id>
+            <activation>
+                <property>
+                    <name>noredist</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.cloudstack</groupId>
+                    <artifactId>cloud-vmware-base</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>quickcloud</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <mainClass>com.cloud.agent.AgentShell</mainClass>
+                            <arguments>
+                                <argument>zone=1</argument>
+                                <argument>pod=1</argument>
+                                <argument>host=192.168.56.1</argument>
+                                <argument>guid=ConsoleProxy.1</argument>
+                            </arguments>
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>javax.net.ssl.trustStore</key>
+                                    <value>certs/realhostip.keystore</value>
+                                    <key>log.home</key>
+                                    <value>${PWD}/</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/test/integration/component/test_tags.py b/test/integration/component/test_tags.py
index efe8a76..9180e7b 100644
--- a/test/integration/component/test_tags.py
+++ b/test/integration/component/test_tags.py
@@ -2516,6 +2516,21 @@
             domainid=self.child_do_admin.domainid,
             zoneid=self.zone.id
         )
+        tag = "tag1"
+        self.so_with_tag = ServiceOffering.create(
+            self.apiclient,
+            self.services["service_offering"],
+            hosttags=tag
+        )
+        self.vm = VirtualMachine.create(
+            self.api_client,
+            self.services["virtual_machine"],
+            accountid=self.child_do_admin.name,
+            domainid=self.child_do_admin.domainid,
+            networkids=self.network.id,
+            serviceofferingid=self.so_with_tag.id
+        )
+
         self.debug("Fetching the network details for account: %s" %
                    self.child_do_admin.name
         )
diff --git a/test/integration/component/test_updateResourceCount.py b/test/integration/component/test_updateResourceCount.py
new file mode 100644
index 0000000..c9bd6e6
--- /dev/null
+++ b/test/integration/component/test_updateResourceCount.py
@@ -0,0 +1,235 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+""" Test update resource count API method
+"""
+# Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.utils import (random_gen,
+                              cleanup_resources)
+from marvin.lib.base import (Domain,
+                             Account,
+                             ServiceOffering,
+                             VirtualMachine,
+                             Network,
+                             User,
+                             NATRule,
+                             Template,
+                             PublicIPAddress,
+                             Resources)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               list_accounts,
+                               list_virtual_machines,
+                               list_service_offering,
+                               list_templates,
+                               list_users,
+                               get_builtin_template_info,
+                               wait_for_cleanup)
+from nose.plugins.attrib import attr
+from marvin.cloudstackException import CloudstackAPIException
+import time
+
+
+class Services:
+
+    """These are some configurations that will get implemented in ACS. They are put here to follow some sort of standard that seems to be in place.
+    """
+
+    def __init__(self):
+        self.services = {
+            "account": {
+                "email": "test@test.com",
+                "firstname": "Test",
+                "lastname": "Tester",
+                "username": "test",
+                "password": "acountFirstUserPass",
+            },
+            "service_offering_custom": {
+                "name": "Custom service offering test",
+                "displaytext": "Custom service offering test",
+                "cpunumber": None,
+                "cpuspeed": None,
+                # in MHz
+                "memory": None,
+                # In MBs
+            },
+            "service_offering_normal": {
+                "name": "Normal service offering",
+                "displaytext": "Normal service offering",
+                "cpunumber": 2,
+                "cpuspeed": 1000,
+                # in MHz
+                "memory": 512,
+                # In MBs
+            },
+            "virtual_machine": {
+                "displayname": "Test VM",
+                "username": "root",
+                "password": "password",
+                "ssh_port": 22,
+                "hypervisor": 'XenServer',
+                # Hypervisor type should be same as
+                # hypervisor type of cluster
+                "privateport": 22,
+                "publicport": 22,
+                "protocol": 'TCP',
+            },
+            "ostype": 'CentOS 5.3 (64-bit)',
+            "sleep": 60,
+            "timeout": 10
+        }
+
+
+class TestUpdateResourceCount(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestUpdateResourceCount, cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+
+        cls.services = Services().services
+        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.template = get_template(
+            cls.api_client,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+        cls.services["virtual_machine"]["template"] = cls.template.id
+
+        cls.service_offering_custom = ServiceOffering.create(
+            cls.api_client,
+            cls.services["service_offering_custom"]
+        )
+        cls.service_offering_normal = ServiceOffering.create(
+            cls.api_client,
+            cls.services["service_offering_normal"]
+        )
+        cls._cleanup = [cls.service_offering_custom, cls.service_offering_normal]
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        self.account = Account.create(
+            self.apiclient,
+            self.services["account"]
+        )
+        self.debug("Created account: %s" % self.account.name)
+        self.cleanup.append(self.account)
+        
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created accounts, domains etc
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    @attr(
+        tags=[
+            "advanced",
+            "basic",
+            "eip",
+            "advancedns",
+            "sg"],
+        required_hardware="false")
+    def test_01_updateResourceCount(self):
+        """Test update resource count for an account using a custom service offering to deploy a VM.
+        """
+        
+        # This test will execute the following steps to assure resource count update is working properly
+        # 1. Create an account.
+        # 2. Start 2 VMs; one with normal service offering and other with a custom service offering
+        # 3. Call the update resource count method and check the CPU and memory values.
+        #    The two VMs will add up to 3 CPUs and 1024Mb of RAM.
+        # 4. If the return of updateResourceCount method matches with the expected one, the test passes; otherwise, it fails.
+        # 5. Remove everything created by deleting the account
+        
+        vm_1 = VirtualMachine.create(
+            self.apiclient,
+            self.services["virtual_machine"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering_custom.id,
+            customcpunumber = 1,
+            customcpuspeed = 1000,
+            custommemory = 512
+        )
+        
+        self.debug("Deployed VM 1 in account: %s, ID: %s" % (
+            self.account.name,
+            vm_1.id
+        ))
+        
+        vm_2 = VirtualMachine.create(
+            self.apiclient,
+            self.services["virtual_machine"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering_normal.id
+        )
+        self.debug("Deployed VM 2 in account: %s, ID: %s" % (
+            self.account.name,
+            vm_2.id
+        ))
+
+        resourceCountCpu = Resources.updateCount(
+            self.apiclient,
+            resourcetype=8,
+            account=self.account.name,
+            domainid=self.account.domainid
+        ) 
+            
+        self.debug("ResourceCount for CPU: %s" % (
+            resourceCountCpu[0].resourcecount
+        ))
+        self.assertEqual(
+            resourceCountCpu[0].resourcecount,
+            3,
+            "The number of CPU cores does not seem to be right."
+        )
+        resourceCountMemory = Resources.updateCount(
+            self.apiclient,
+            resourcetype=9,
+            account=self.account.name,
+            domainid=self.account.domainid
+        ) 
+            
+        self.debug("ResourceCount for memory: %s" % (
+            resourceCountMemory[0].resourcecount
+        ))
+        self.assertEqual(
+            resourceCountMemory[0].resourcecount,
+            1024,
+            "The memory amount does not seem to be right."
+        )
+        return
\ No newline at end of file
diff --git a/test/integration/plugins/solidfire/TestAddRemoveHosts.py b/test/integration/plugins/solidfire/TestAddRemoveHosts.py
index d9118dd..1dd29bb 100644
--- a/test/integration/plugins/solidfire/TestAddRemoveHosts.py
+++ b/test/integration/plugins/solidfire/TestAddRemoveHosts.py
@@ -34,7 +34,7 @@
 from marvin.lib.base import Account, ServiceOffering, User, Host, StoragePool, VirtualMachine
 
 # common - commonly used methods for all tests are listed here
-from marvin.lib.common import get_domain, get_template, get_zone, list_hosts, list_clusters, list_volumes
+from marvin.lib.common import get_domain, get_template, get_zone, list_clusters, list_hosts, list_volumes
 
 # utils - utility classes for common cleanup, external library wrappers, etc.
 from marvin.lib.utils import cleanup_resources
@@ -46,14 +46,15 @@
 #
 # Running the tests:
 #  Change the "hypervisor_type" variable to control which hypervisor type to test.
-#  If using XenServer, set a breakpoint on each test after the first one. When the breakpoint is hit, reset the added/removed
-#   host to a snapshot state and re-start it. Once it's up and running, run the test code.
+#  If using XenServer, set a breakpoint on each test after the first one. When the breakpoint is hit, reset the
+#   added/removed host to a snapshot state and re-start it. Once it's up and running, run the test code.
 #  Check that ip_address_of_new_xenserver_host / ip_address_of_new_kvm_host is correct.
 #  If using XenServer, verify the "xen_server_master_hostname" variable is correct.
 #  If using KVM, verify the "kvm_1_ip_address" variable is correct.
 #
 # Note:
-#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0]
+#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0] and
+#   this variable's value: TestData.clusterId.
 
 
 class TestData:
@@ -95,18 +96,18 @@
     # modify to control which hypervisor type to test
     hypervisor_type = xenServer
     xen_server_master_hostname = "XenServer-6.5-1"
-    kvm_1_ip_address = "10.117.40.112"
-    ip_address_of_new_xenserver_host = "10.117.40.107"
-    ip_address_of_new_kvm_host = "10.117.40.116"
+    kvm_1_ip_address = "10.117.40.111"
+    ip_address_of_new_xenserver_host = "10.117.40.118"
+    ip_address_of_new_kvm_host = "10.117.40.115"
 
     def __init__(self):
         self.testdata = {
             TestData.solidFire: {
-                TestData.mvip: "10.117.40.120",
+                TestData.mvip: "10.117.78.225",
                 TestData.username: "admin",
                 TestData.password: "admin",
                 TestData.port: 443,
-                TestData.url: "https://10.117.40.120:443"
+                TestData.url: "https://10.117.78.225:443"
             },
             TestData.kvm: {
                 TestData.username: "root",
@@ -147,7 +148,7 @@
             TestData.primaryStorage: {
                 TestData.name: "SolidFire-%d" % random.randint(0, 100),
                 TestData.scope: "ZONE",
-                TestData.url: "MVIP=10.117.40.120;SVIP=10.117.41.120;" +
+                TestData.url: "MVIP=10.117.78.225;SVIP=10.117.94.225;" +
                        "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                        "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
                        "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
@@ -160,7 +161,7 @@
             TestData.primaryStorage2: {
                 TestData.name: "SolidFireShared-%d" % random.randint(0, 100),
                 TestData.scope: "CLUSTER",
-                TestData.url: "MVIP=10.117.40.120;SVIP=10.117.41.120;" +
+                TestData.url: "MVIP=10.117.78.225;SVIP=10.117.94.225;" +
                        "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                        "minIops=5000;maxIops=50000;burstIops=75000",
                 TestData.provider: "SolidFireShared",
@@ -454,6 +455,143 @@
 
         self._perform_add_remove_xenserver_host(primary_storage_2.id, sf_iscsi_name)
 
+    # Make sure each host is in its own VAG.
+    # Create a VM that needs a new volume from the storage that has a VAG per host.
+    # Verify the volume is in all VAGs.
+    # Remove one of the hosts.
+    # Check that the IQN is no longer in its previous VAG, but that the volume ID is still in that VAG, though.
+    # Add the host back into the cluster. The IQN should be added to a VAG that already has an IQN from this cluster in it.
+    def test_vag_per_host_5(self):
+        hosts = list_hosts(self.apiClient, clusterid=self.cluster.id)
+
+        self.assertTrue(
+            len(hosts) >= 2,
+            "There needs to be at least two hosts."
+        )
+
+        unique_vag_ids = self._get_unique_vag_ids(hosts)
+
+        self.assertTrue(len(hosts) == len(unique_vag_ids), "To run this test, each host should be in its own VAG.")
+
+        primarystorage = self.testdata[TestData.primaryStorage]
+
+        primary_storage = StoragePool.create(
+            self.apiClient,
+            primarystorage,
+            scope=primarystorage[TestData.scope],
+            zoneid=self.zone.id,
+            provider=primarystorage[TestData.provider],
+            tags=primarystorage[TestData.tags],
+            capacityiops=primarystorage[TestData.capacityIops],
+            capacitybytes=primarystorage[TestData.capacityBytes],
+            hypervisor=primarystorage[TestData.hypervisor]
+        )
+
+        self.cleanup.append(primary_storage)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiClient,
+            self.testdata[TestData.virtualMachine],
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            serviceofferingid=self.compute_offering.id,
+            templateid=self.template.id,
+            domainid=self.domain.id,
+            startvm=True
+        )
+
+        root_volume = self._get_root_volume(self.virtual_machine)
+
+        sf_account_id = sf_util.get_sf_account_id(self.cs_api, self.account.id, primary_storage.id, self, TestAddRemoveHosts._sf_account_id_should_be_non_zero_int_err_msg)
+
+        sf_volumes = sf_util.get_active_sf_volumes(self.sfe, sf_account_id)
+
+        sf_volume = sf_util.check_and_get_sf_volume(sf_volumes, root_volume.name, self)
+
+        sf_vag_ids = sf_util.get_vag_ids(self.cs_api, self.cluster.id, primary_storage.id, self)
+
+        sf_util.check_vags(sf_volume, sf_vag_ids, self)
+
+        host = Host(hosts[0].__dict__)
+
+        host_iqn = self._get_host_iqn(host)
+
+        all_vags = sf_util.get_all_vags(self.sfe)
+
+        host_vag = self._get_host_vag(host_iqn, all_vags)
+
+        self.assertTrue(host_vag != None, "The host should be in a VAG.")
+
+        host.delete(self.apiClient)
+
+        sf_volumes = sf_util.get_active_sf_volumes(self.sfe, sf_account_id)
+
+        sf_volume = sf_util.check_and_get_sf_volume(sf_volumes, root_volume.name, self)
+
+        sf_util.check_vags(sf_volume, sf_vag_ids, self)
+
+        all_vags = sf_util.get_all_vags(self.sfe)
+
+        host_vag = self._get_host_vag(host_iqn, all_vags)
+
+        self.assertTrue(host_vag == None, "The host should not be in a VAG.")
+
+        details = {
+            TestData.username: "root",
+            TestData.password: "solidfire",
+            TestData.url: "http://" + host.ipaddress,
+            TestData.podId : host.podid,
+            TestData.zoneId: host.zoneid
+        }
+
+        host = Host.create(
+            self.apiClient,
+            self.cluster,
+            details,
+            hypervisor=host.hypervisor
+        )
+
+        self.assertTrue(
+            isinstance(host, Host),
+            "'host' is not a 'Host'."
+        )
+
+        hosts = list_hosts(self.apiClient, clusterid=self.cluster.id)
+
+        unique_vag_ids = self._get_unique_vag_ids(hosts)
+
+        self.assertTrue(len(hosts) == len(unique_vag_ids) + 1, "There should be one more host than unique VAG.")
+
+    def _get_unique_vag_ids(self, hosts):
+        all_vags = sf_util.get_all_vags(self.sfe)
+
+        unique_vag_ids = []
+
+        for host in hosts:
+            host = Host(host.__dict__)
+
+            host_iqn = self._get_host_iqn(host)
+
+            host_vag = self._get_host_vag(host_iqn, all_vags)
+
+            if host_vag != None and host_vag.volume_access_group_id not in unique_vag_ids:
+                unique_vag_ids.append(host_vag.volume_access_group_id)
+
+        return unique_vag_ids
+
+    def _get_host_vag(self, host_iqn, vags):
+        self.assertTrue(host_iqn, "'host_iqn' should not be 'None'.")
+        self.assertTrue(vags, "'vags' should not be 'None'.")
+
+        self.assertTrue(isinstance(host_iqn, basestring), "'host_iqn' should be a 'string'.")
+        self.assertTrue(isinstance(vags, list), "'vags' should be a 'list'.")
+
+        for vag in vags:
+            if host_iqn in vag.initiators:
+                return vag
+
+        return None
+
     def _perform_add_remove_xenserver_host(self, primary_storage_id, sr_name):
         xen_sr = self.xen_session.xenapi.SR.get_by_name_label(sr_name)[0]
 
@@ -463,7 +601,7 @@
 
         num_pbds = len(pbds)
 
-        sf_vag_id = self._get_sf_vag_id(self.cluster.id, primary_storage_id)
+        sf_vag_id = sf_util.get_vag_id(self.cs_api, self.cluster.id, primary_storage_id, self)
 
         host_iscsi_iqns = self._get_xenserver_host_iscsi_iqns()
 
@@ -604,7 +742,7 @@
         )
 
     def _perform_add_remove_kvm_host(self, primary_storage_id):
-        sf_vag_id = self._get_sf_vag_id(self.cluster.id, primary_storage_id)
+        sf_vag_id = sf_util.get_vag_id(self.cs_api, self.cluster.id, primary_storage_id, self)
 
         kvm_login = self.testdata[TestData.kvm]
 
@@ -720,6 +858,14 @@
 
         return sql_result[0][0]
 
+    def _get_host_iqn(self, host):
+        sql_query = "Select url From host Where uuid = '" + str(host.id) + "'"
+
+        # make sure you can connect to MySQL: https://teamtreehouse.com/community/cant-connect-remotely-to-mysql-server-with-mysql-workbench
+        sql_result = self.dbConnection.execute(sql_query)
+
+        return sql_result[0][0]
+
     def _get_xenserver_host_iscsi_iqns(self):
         hosts = self.xen_session.xenapi.host.get_all()
 
@@ -767,20 +913,6 @@
 
         return result[len(searchFor):].strip()
 
-    def _get_sf_vag_id(self, cluster_id, primary_storage_id):
-        # Get SF Volume Access Group ID
-        sf_vag_id_request = {'clusterid': cluster_id, 'storageid': primary_storage_id}
-        sf_vag_id_result = self.cs_api.getSolidFireVolumeAccessGroupId(sf_vag_id_request)
-        sf_vag_id = sf_vag_id_result['apisolidfirevolumeaccessgroupid']['solidFireVolumeAccessGroupId']
-
-        self.assertEqual(
-            isinstance(sf_vag_id, int),
-            True,
-            TestAddRemoveHosts._vag_id_should_be_non_zero_int_err_msg
-        )
-
-        return sf_vag_id
-
     def _get_sf_vag(self, sf_vag_id):
         return self.sfe.list_volume_access_groups(sf_vag_id, 1).volume_access_groups[0]
 
diff --git a/test/integration/plugins/solidfire/TestCapacityManagement.py b/test/integration/plugins/solidfire/TestCapacityManagement.py
index ab6eff1..0cc9db2 100644
--- a/test/integration/plugins/solidfire/TestCapacityManagement.py
+++ b/test/integration/plugins/solidfire/TestCapacityManagement.py
@@ -33,7 +33,7 @@
 from marvin.lib.base import Account, ServiceOffering, StoragePool, User, VirtualMachine
 
 # common - commonly used methods for all tests are listed here
-from marvin.lib.common import get_domain, get_template, get_zone, list_clusters, list_hosts
+from marvin.lib.common import get_domain, get_template, get_zone, list_hosts
 
 # utils - utility classes for common cleanup, external library wrappers, etc.
 from marvin.lib.utils import cleanup_resources
@@ -47,7 +47,7 @@
 #  If using XenServer, verify the "xen_server_hostname" variable is correct.
 #
 # Note:
-#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0]
+#  If you do have more than one cluster, you might need to change this variable: TestData.clusterId.
 
 
 class TestData():
@@ -193,7 +193,6 @@
 
         # Get Resources from Cloud Infrastructure
         cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
-        cls.cluster = list_clusters(cls.apiClient)[0]
         cls.template = get_template(cls.apiClient, cls.zone.id, hypervisor=TestData.hypervisor_type)
         cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])
 
diff --git a/test/integration/plugins/solidfire/TestManagedClusteredFilesystems.py b/test/integration/plugins/solidfire/TestManagedClusteredFilesystems.py
new file mode 100644
index 0000000..053dfb6
--- /dev/null
+++ b/test/integration/plugins/solidfire/TestManagedClusteredFilesystems.py
@@ -0,0 +1,431 @@
+# 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 logging
+import random
+import SignedAPICall
+import XenAPI
+
+from solidfire.factory import ElementFactory
+
+from util import sf_util
+
+# All tests inherit from cloudstackTestCase
+from marvin.cloudstackTestCase import cloudstackTestCase
+
+# Import Integration Libraries
+
+# base - contains all resources as entities and defines create, delete, list operations on them
+from marvin.lib.base import Account, Cluster, ServiceOffering, Snapshot, StoragePool, User, VirtualMachine, Volume
+
+# common - commonly used methods for all tests are listed here
+from marvin.lib.common import get_domain, get_template, get_zone, list_hosts, list_volumes
+
+# utils - utility classes for common cleanup, external library wrappers, etc.
+from marvin.lib.utils import cleanup_resources
+
+# Prerequisites:
+#  Only one zone
+#  Only one pod
+#  Two clusters
+#
+# Running the tests:
+#  If using XenServer, verify the "xen_server_hostname" variable is correct.
+#  Set the Global Setting "max.number.managed.clustered.file.systems" equal to 2.
+#
+# Note:
+#  Verify that TestData.clusterId and TestData.clusterId2 are set properly.
+
+
+class TestData():
+    # constants
+    account = "account"
+    allocationstate = "allocationstate"
+    capacityBytes = "capacitybytes"
+    capacityIops = "capacityiops"
+    clusterId = "clusterId"
+    clusterId2 = "clusterId2"
+    computeOffering = "computeoffering"
+    domainId = "domainId"
+    email = "email"
+    firstname = "firstname"
+    hypervisor = "hypervisor"
+    lastname = "lastname"
+    mvip = "mvip"
+    name = "name"
+    password = "password"
+    port = "port"
+    primaryStorage = "primarystorage"
+    provider = "provider"
+    scope = "scope"
+    solidFire = "solidfire"
+    storageTag = "SolidFire_SAN_1"
+    tags = "tags"
+    url = "url"
+    user = "user"
+    username = "username"
+    xenServer = "xenserver"
+    zoneId = "zoneId"
+
+    hypervisor_type = xenServer
+    xen_server_hostname = "XenServer-6.5-1"
+
+    def __init__(self):
+        self.testdata = {
+            TestData.solidFire: {
+                TestData.mvip: "10.117.78.225",
+                TestData.username: "admin",
+                TestData.password: "admin",
+                TestData.port: 443,
+                TestData.url: "https://10.117.78.225:443"
+            },
+            TestData.xenServer: {
+                TestData.username: "root",
+                TestData.password: "solidfire"
+            },
+            TestData.account: {
+                TestData.email: "test@test.com",
+                TestData.firstname: "John",
+                TestData.lastname: "Doe",
+                TestData.username: "test",
+                TestData.password: "test"
+            },
+            TestData.user: {
+                TestData.email: "user@test.com",
+                TestData.firstname: "Jane",
+                TestData.lastname: "Doe",
+                TestData.username: "testuser",
+                TestData.password: "password"
+            },
+            TestData.primaryStorage: {
+                TestData.name: "SolidFire-%d" % random.randint(0, 100),
+                TestData.scope: "ZONE",
+                TestData.url: "MVIP=10.117.78.225;SVIP=10.117.94.225;" +
+                       "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
+                       "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
+                       "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
+                TestData.provider: "SolidFire",
+                TestData.tags: TestData.storageTag,
+                TestData.capacityIops: 4500000,
+                TestData.capacityBytes: 2251799813685248,
+                TestData.hypervisor: "Any"
+            },
+            TestData.computeOffering: {
+                TestData.name: "SF_CO_1",
+                "displaytext": "SF_CO_1 (Min IOPS = 300; Max IOPS = 600)",
+                "cpunumber": 1,
+                "cpuspeed": 100,
+                "memory": 128,
+                "storagetype": "shared",
+                "customizediops": False,
+                "miniops": "300",
+                "maxiops": "600",
+                "hypervisorsnapshotreserve": 200,
+                TestData.tags: TestData.storageTag
+            },
+            TestData.zoneId: 1,
+            TestData.clusterId: 1,
+            TestData.clusterId2: 6,
+            TestData.domainId: 1,
+            TestData.url: "10.117.40.114"
+        }
+
+
+class TestManagedClusteredFilesystems(cloudstackTestCase):
+    _should_only_be_one_volume_in_list_err_msg = "There should only be one volume in this list."
+    _volume_should_have_failed_to_attach_to_vm = "The volume should have failed to attach to the VM."
+
+    @classmethod
+    def setUpClass(cls):
+        # Set up API client
+        testclient = super(TestManagedClusteredFilesystems, cls).getClsTestClient()
+
+        cls.apiClient = testclient.getApiClient()
+        cls.configData = testclient.getParsedTestDataConfig()
+        cls.dbConnection = testclient.getDbConnection()
+
+        cls.testdata = TestData().testdata
+
+        sf_util.set_supports_resign(True, cls.dbConnection)
+
+        cls._connect_to_hypervisor()
+
+        # Set up SolidFire connection
+        solidfire = cls.testdata[TestData.solidFire]
+
+        cls.sfe = ElementFactory.create(solidfire[TestData.mvip], solidfire[TestData.username], solidfire[TestData.password])
+
+        # Get Resources from Cloud Infrastructure
+        cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
+        cls.template = get_template(cls.apiClient, cls.zone.id, hypervisor=TestData.hypervisor_type)
+        cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])
+
+        # Create test account
+        cls.account = Account.create(
+            cls.apiClient,
+            cls.testdata["account"],
+            admin=1
+        )
+
+        # Set up connection to make customized API calls
+        cls.user = User.create(
+            cls.apiClient,
+            cls.testdata["user"],
+            account=cls.account.name,
+            domainid=cls.domain.id
+        )
+
+        url = cls.testdata[TestData.url]
+
+        api_url = "http://" + url + ":8080/client/api"
+        userkeys = User.registerUserKeys(cls.apiClient, cls.user.id)
+
+        cls.cs_api = SignedAPICall.CloudStack(api_url, userkeys.apikey, userkeys.secretkey)
+
+        primarystorage = cls.testdata[TestData.primaryStorage]
+
+        cls.primary_storage = StoragePool.create(
+            cls.apiClient,
+            primarystorage,
+            scope=primarystorage[TestData.scope],
+            zoneid=cls.zone.id,
+            provider=primarystorage[TestData.provider],
+            tags=primarystorage[TestData.tags],
+            capacityiops=primarystorage[TestData.capacityIops],
+            capacitybytes=primarystorage[TestData.capacityBytes],
+            hypervisor=primarystorage[TestData.hypervisor]
+        )
+
+        cls.compute_offering = ServiceOffering.create(
+            cls.apiClient,
+            cls.testdata[TestData.computeOffering]
+        )
+
+        # Resources that are to be destroyed
+        cls._cleanup = [
+            cls.compute_offering,
+            cls.user,
+            cls.account
+        ]
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cleanup_resources(cls.apiClient, cls._cleanup)
+
+            cls.primary_storage.delete(cls.apiClient)
+
+            sf_util.purge_solidfire_volumes(cls.sfe)
+        except Exception as e:
+            logging.debug("Exception in tearDownClass(cls): %s" % e)
+
+    def setUp(self):
+        self.cleanup = []
+
+    def tearDown(self):
+        cleanup_resources(self.apiClient, self.cleanup)
+
+#   Only two 'permanent' SRs per cluster
+#
+#   Disable the second cluster
+#
+#   Create VM
+#   Create VM
+#   Create VM (should fail)
+#   Take snapshot of first root disk
+#   Create a volume from this snapshot
+#   Attach new volume to second VM (should fail)
+#
+#   Enable the second cluster
+#
+#   Attach new volume to second VM (should fail)
+#   Create VM (should end up in new cluster)
+#   Delete first VM (this should free up one SR in the first cluster)
+#   Attach new volume to second VM
+#   Detach new volume from second VM
+#   Attach new volume to second VM
+#   Create a volume from the snapshot
+#   Attach this new volume to the second VM (should fail)
+#   Attach this new volume to the first VM in the new cluster
+    def test_managed_clustered_filesystems_limit(self):
+        args = { "id": self.testdata[TestData.clusterId2], TestData.allocationstate: "Disabled" }
+
+        Cluster.update(self.apiClient, **args)
+
+        virtual_machine_names = {
+            "name": "TestVM1",
+            "displayname": "Test VM 1"
+        }
+
+        virtual_machine_1 = self._create_vm(virtual_machine_names)
+
+        list_volumes_response = list_volumes(
+            self.apiClient,
+            virtualmachineid=virtual_machine_1.id,
+            listall=True
+        )
+
+        sf_util.check_list(list_volumes_response, 1, self, TestManagedClusteredFilesystems._should_only_be_one_volume_in_list_err_msg)
+
+        vm_1_root_volume = list_volumes_response[0]
+
+        virtual_machine_names = {
+            "name": "TestVM2",
+            "displayname": "Test VM 2"
+        }
+
+        virtual_machine_2 = self._create_vm(virtual_machine_names)
+
+        virtual_machine_names = {
+            "name": "TestVM3",
+            "displayname": "Test VM 3"
+        }
+
+        class VMStartedException(Exception):
+            def __init__(self, *args, **kwargs):
+                Exception.__init__(self, *args, **kwargs)
+
+        try:
+            # The VM should fail to be created as there should be an insufficient number of clustered filesystems
+            # remaining in the compute cluster.
+            self._create_vm(virtual_machine_names)
+
+            raise VMStartedException("The VM should have failed to start.")
+        except VMStartedException:
+            raise
+        except Exception:
+            pass
+
+        vol_snap = Snapshot.create(
+            self.apiClient,
+            volume_id=vm_1_root_volume.id
+        )
+
+        services = {"diskname": "Vol-1", "zoneid": self.testdata[TestData.zoneId], "ispublic": True}
+
+        volume_created_from_snapshot_1 = Volume.create_from_snapshot(self.apiClient, vol_snap.id, services, account=self.account.name, domainid=self.domain.id)
+
+        class VolumeAttachedException(Exception):
+            def __init__(self, *args, **kwargs):
+                Exception.__init__(self, *args, **kwargs)
+
+        try:
+            # The volume should fail to be attached as there should be an insufficient number of clustered filesystems
+            # remaining in the compute cluster.
+            virtual_machine_2.attach_volume(
+                self.apiClient,
+                volume_created_from_snapshot_1
+            )
+
+            raise VolumeAttachedException(TestManagedClusteredFilesystems._volume_should_have_failed_to_attach_to_vm)
+        except VolumeAttachedException:
+            raise
+        except Exception:
+            pass
+
+        args = { "id": self.testdata[TestData.clusterId2], TestData.allocationstate: "Enabled" }
+
+        Cluster.update(self.apiClient, **args)
+
+        try:
+            # The volume should fail to be attached as there should be an insufficient number of clustered filesystems
+            # remaining in the compute cluster.
+            virtual_machine_2.attach_volume(
+                self.apiClient,
+                volume_created_from_snapshot_1
+            )
+
+            raise VolumeAttachedException(TestManagedClusteredFilesystems._volume_should_have_failed_to_attach_to_vm)
+        except VolumeAttachedException:
+            raise
+        except Exception:
+            pass
+
+        virtual_machine_names = {
+            "name": "TestVMA",
+            "displayname": "Test VM A"
+        }
+
+        virtual_machine_a = self._create_vm(virtual_machine_names)
+
+        host_for_vm_1 = list_hosts(self.apiClient, id=virtual_machine_1.hostid)[0]
+        host_for_vm_a = list_hosts(self.apiClient, id=virtual_machine_a.hostid)[0]
+
+        self.assertTrue(
+            host_for_vm_1.clusterid != host_for_vm_a.clusterid,
+            "VMs 1 and VM a should be in different clusters."
+        )
+
+        virtual_machine_1.delete(self.apiClient, True)
+
+        volume_created_from_snapshot_1 = virtual_machine_2.attach_volume(
+            self.apiClient,
+            volume_created_from_snapshot_1
+        )
+
+        virtual_machine_2.detach_volume(self.apiClient, volume_created_from_snapshot_1)
+
+        volume_created_from_snapshot_1 = virtual_machine_2.attach_volume(
+            self.apiClient,
+            volume_created_from_snapshot_1
+        )
+
+        services = {"diskname": "Vol-2", "zoneid": self.testdata[TestData.zoneId], "ispublic": True}
+
+        volume_created_from_snapshot_2 = Volume.create_from_snapshot(self.apiClient, vol_snap.id, services, account=self.account.name, domainid=self.domain.id)
+
+        try:
+            # The volume should fail to be attached as there should be an insufficient number of clustered filesystems
+            # remaining in the compute cluster.
+            virtual_machine_2.attach_volume(
+                self.apiClient,
+                volume_created_from_snapshot_2
+            )
+
+            raise VolumeAttachedException(TestManagedClusteredFilesystems._volume_should_have_failed_to_attach_to_vm)
+        except VolumeAttachedException:
+            raise
+        except Exception:
+            pass
+
+        virtual_machine_a.attach_volume(
+            self.apiClient,
+            volume_created_from_snapshot_2
+        )
+
+    def _create_vm(self, virtual_machine_names):
+        return VirtualMachine.create(
+            self.apiClient,
+            virtual_machine_names,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            serviceofferingid=self.compute_offering.id,
+            templateid=self.template.id,
+            domainid=self.domain.id,
+            startvm=True
+        )
+
+    @classmethod
+    def _connect_to_hypervisor(cls):
+        host_ip = "https://" + \
+              list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name=TestData.xen_server_hostname)[0].ipaddress
+
+        cls.xen_session = XenAPI.Session(host_ip)
+
+        xen_server = cls.testdata[TestData.xenServer]
+
+        cls.xen_session.xenapi.login_with_password(xen_server[TestData.username], xen_server[TestData.password])
diff --git a/test/integration/plugins/solidfire/TestOnlineStorageMigration.py b/test/integration/plugins/solidfire/TestOnlineStorageMigration.py
new file mode 100644
index 0000000..f7d8c14
--- /dev/null
+++ b/test/integration/plugins/solidfire/TestOnlineStorageMigration.py
@@ -0,0 +1,402 @@
+# 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 logging
+import random
+import SignedAPICall
+import XenAPI
+
+from solidfire.factory import ElementFactory
+
+from util import sf_util
+
+# All tests inherit from cloudstackTestCase
+from marvin.cloudstackTestCase import cloudstackTestCase
+
+# Import Integration Libraries
+
+# base - contains all resources as entities and defines create, delete, list operations on them
+from marvin.lib.base import Account, ServiceOffering, Snapshot, StoragePool, User, VirtualMachine, Volume
+
+# common - commonly used methods for all tests are listed here
+from marvin.lib.common import list_clusters, get_domain, list_hosts, list_snapshots, get_template, list_volumes, get_zone
+
+# utils - utility classes for common cleanup, external library wrappers, etc.
+from marvin.lib.utils import cleanup_resources
+
+# Prerequisites:
+#  Only one zone
+#  Only one pod
+#  Only one cluster
+#
+# Running the tests:
+#  If using XenServer, verify the "xen_server_hostname" variable is correct.
+#
+# Note:
+#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0]
+
+
+class TestData():
+    # constants
+    account = "account"
+    capacityBytes = "capacitybytes"
+    capacityIops = "capacityiops"
+    clusterId = "clusterId"
+    computeOffering = "computeoffering"
+    domainId = "domainId"
+    email = "email"
+    firstname = "firstname"
+    hypervisor = "hypervisor"
+    lastname = "lastname"
+    managementServer = "managementServer"
+    mvip = "mvip"
+    name = "name"
+    nfs_folder = "/export/primary2"
+    nfs_path = "nfs://10.117.40.114" + nfs_folder
+    nfs_storage_tag = "NFS-123"
+    password = "password"
+    podId = "podId"
+    port = "port"
+    primaryStorage = "primarystorage"
+    primaryStorage2 = "primarystorage2"
+    provider = "provider"
+    scope = "scope"
+    solidFire = "solidfire"
+    storageTag = "SolidFire_SAN_1"
+    tags = "tags"
+    url = "url"
+    user = "user"
+    username = "username"
+    xenServer = "xenserver"
+    zoneId = "zoneId"
+
+    hypervisor_type = xenServer
+    xen_server_hostname = "XenServer-6.5-1"
+
+    def __init__(self):
+        self.testdata = {
+            TestData.solidFire: {
+                TestData.mvip: "10.117.40.120",
+                TestData.username: "admin",
+                TestData.password: "admin",
+                TestData.port: 443,
+                TestData.url: "https://10.117.40.120:443"
+            },
+            TestData.xenServer: {
+                TestData.username: "root",
+                TestData.password: "solidfire"
+            },
+            TestData.managementServer: {
+                TestData.username: "cloudstack",
+                TestData.password: "solidfire"
+            },
+            TestData.account: {
+                TestData.email: "test@test.com",
+                TestData.firstname: "John",
+                TestData.lastname: "Doe",
+                TestData.username: "test",
+                TestData.password: "test"
+            },
+            TestData.user: {
+                TestData.email: "user@test.com",
+                TestData.firstname: "Jane",
+                TestData.lastname: "Doe",
+                TestData.username: "testuser",
+                TestData.password: "password"
+            },
+            TestData.primaryStorage: {
+                TestData.name: "NFS-%d" % random.randint(0, 100),
+                TestData.scope: "CLUSTER",
+                TestData.clusterId: 1,
+                TestData.url: TestData.nfs_path,
+                TestData.tags: TestData.nfs_storage_tag
+            },
+            TestData.primaryStorage2: {
+                TestData.name: "SolidFire-%d" % random.randint(0, 100),
+                TestData.scope: "ZONE",
+                TestData.url: "MVIP=10.117.40.120;SVIP=10.117.41.120;" +
+                       "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
+                       "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
+                       "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
+                TestData.provider: "SolidFire",
+                TestData.tags: TestData.storageTag,
+                TestData.capacityIops: 4500000,
+                TestData.capacityBytes: 2251799813685248, # 2 PiB
+                TestData.hypervisor: "Any"
+            },
+            TestData.computeOffering: {
+                TestData.name: "SF_CO_1",
+                "displaytext": "SF_CO_1 (Min IOPS = 300; Max IOPS = 600)",
+                "cpunumber": 1,
+                "cpuspeed": 100,
+                "memory": 128,
+                "storagetype": "shared",
+                "customizediops": False,
+                "miniops": "300",
+                "maxiops": "600",
+                "hypervisorsnapshotreserve": 200,
+                TestData.tags: TestData.nfs_storage_tag
+            },
+            TestData.zoneId: 1,
+            TestData.podId: 1,
+            TestData.clusterId: 1,
+            TestData.domainId: 1,
+            TestData.url: "10.117.40.114"
+        }
+
+
+class TestOnlineStorageMigration(cloudstackTestCase):
+    _should_only_be_one_volume_in_list_err_msg = "There should only be one volume in this list."
+    _volume_not_on_correct_primary_storage = "The volume is not on the correct primary storage."
+    _snapshot_not_associated_with_correct_volume = "The snapshot is not associated with the correct volume."
+
+    @classmethod
+    def setUpClass(cls):
+        # Set up API client
+        testclient = super(TestOnlineStorageMigration, cls).getClsTestClient()
+
+        cls.apiClient = testclient.getApiClient()
+        cls.configData = testclient.getParsedTestDataConfig()
+        cls.dbConnection = testclient.getDbConnection()
+
+        cls.testdata = TestData().testdata
+
+        sf_util.set_supports_resign(True, cls.dbConnection)
+
+        cls._connect_to_hypervisor()
+
+        # Set up SolidFire connection
+        solidfire = cls.testdata[TestData.solidFire]
+
+        cls.sfe = ElementFactory.create(solidfire[TestData.mvip], solidfire[TestData.username], solidfire[TestData.password])
+
+        # Get Resources from Cloud Infrastructure
+        cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
+        cls.cluster = list_clusters(cls.apiClient)[0]
+        cls.template = get_template(cls.apiClient, cls.zone.id, hypervisor=TestData.hypervisor_type)
+        cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])
+
+        # Create test account
+        cls.account = Account.create(
+            cls.apiClient,
+            cls.testdata["account"],
+            admin=1
+        )
+
+        # Set up connection to make customized API calls
+        cls.user = User.create(
+            cls.apiClient,
+            cls.testdata["user"],
+            account=cls.account.name,
+            domainid=cls.domain.id
+        )
+
+        url = cls.testdata[TestData.url]
+
+        api_url = "http://" + url + ":8080/client/api"
+        userkeys = User.registerUserKeys(cls.apiClient, cls.user.id)
+
+        cls.cs_api = SignedAPICall.CloudStack(api_url, userkeys.apikey, userkeys.secretkey)
+
+        primarystorage = cls.testdata[TestData.primaryStorage]
+
+        cls.primary_storage = StoragePool.create(
+            cls.apiClient,
+            primarystorage,
+            scope=primarystorage[TestData.scope],
+            zoneid=cls.zone.id,
+            podid=cls.testdata[TestData.podId],
+            clusterid=cls.cluster.id,
+            tags=primarystorage[TestData.tags]
+        )
+
+        primarystorage2 = cls.testdata[TestData.primaryStorage2]
+
+        cls.primary_storage_2 = StoragePool.create(
+            cls.apiClient,
+            primarystorage2,
+            scope=primarystorage2[TestData.scope],
+            zoneid=cls.zone.id,
+            provider=primarystorage2[TestData.provider],
+            tags=primarystorage2[TestData.tags],
+            capacityiops=primarystorage2[TestData.capacityIops],
+            capacitybytes=primarystorage2[TestData.capacityBytes],
+            hypervisor=primarystorage2[TestData.hypervisor]
+        )
+
+        cls.compute_offering = ServiceOffering.create(
+            cls.apiClient,
+            cls.testdata[TestData.computeOffering]
+        )
+
+        # Resources that are to be destroyed
+        cls._cleanup = [
+            cls.compute_offering,
+            cls.user,
+            cls.account
+        ]
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cleanup_resources(cls.apiClient, cls._cleanup)
+
+            cls.primary_storage.delete(cls.apiClient)
+            cls.primary_storage_2.delete(cls.apiClient)
+
+            ms = cls.testdata[TestData.managementServer]
+            ip_address = cls.testdata[TestData.url]
+
+            cls._delete_all_files(ip_address, ms[TestData.username], ms[TestData.password], TestData.nfs_folder)
+
+            sf_util.purge_solidfire_volumes(cls.sfe)
+        except Exception as e:
+            logging.debug("Exception in tearDownClass(cls): %s" % e)
+
+    def setUp(self):
+        self.cleanup = []
+
+    def tearDown(self):
+        cleanup_resources(self.apiClient, self.cleanup)
+
+    def test_online_migrate_volume_from_nfs_storage_to_managed_storage(self):
+        if TestData.hypervisor_type != TestData.xenServer:
+            return
+
+        virtual_machine = VirtualMachine.create(
+            self.apiClient,
+            self._get_vm_name(),
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            serviceofferingid=self.compute_offering.id,
+            templateid=self.template.id,
+            domainid=self.domain.id,
+            startvm=True
+        )
+
+        self.cleanup.append(virtual_machine)
+
+        vm_root_volume = self._get_only_volume(virtual_machine.id)
+
+        self._verify_volume_on_primary_storage(vm_root_volume, self.primary_storage)
+
+        # Migrate the root disk from NFS storage to managed storage.
+
+        Volume.migrate(self.apiClient, livemigrate=True, volumeid=vm_root_volume.id, storageid=self.primary_storage_2.id)
+
+        vm_root_volume = self._get_only_volume(virtual_machine.id)
+
+        self._verify_volume_on_primary_storage(vm_root_volume, self.primary_storage_2)
+
+    def test_online_migrate_volume_with_snapshot_from_nfs_storage_to_managed_storage(self):
+        if TestData.hypervisor_type != TestData.xenServer:
+            return
+
+        virtual_machine = VirtualMachine.create(
+            self.apiClient,
+            self._get_vm_name(),
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            serviceofferingid=self.compute_offering.id,
+            templateid=self.template.id,
+            domainid=self.domain.id,
+            startvm=True
+        )
+
+        self.cleanup.append(virtual_machine)
+
+        vm_root_volume = self._get_only_volume(virtual_machine.id)
+
+        self._verify_volume_on_primary_storage(vm_root_volume, self.primary_storage)
+
+        vol_snap = Snapshot.create(
+            self.apiClient,
+            volume_id=vm_root_volume.id
+        )
+
+        self.cleanup.append(vol_snap)
+
+        self._verify_snapshot_belongs_to_volume(vol_snap.id, vm_root_volume.id)
+
+        # Migrate the root disk from NFS storage to managed storage.
+
+        Volume.migrate(self.apiClient, livemigrate=True, volumeid=vm_root_volume.id, storageid=self.primary_storage_2.id)
+
+        vm_root_volume = self._get_only_volume(virtual_machine.id)
+
+        self._verify_volume_on_primary_storage(vm_root_volume, self.primary_storage_2)
+
+        self._verify_snapshot_belongs_to_volume(vol_snap.id, vm_root_volume.id)
+
+    def _verify_snapshot_belongs_to_volume(self, snapshot_id, volume_id):
+        snapshot = list_snapshots(
+            self.apiClient,
+            id=snapshot_id
+        )[0]
+
+        self.assertEqual(
+            snapshot.volumeid,
+            volume_id,
+            TestOnlineStorageMigration._snapshot_not_associated_with_correct_volume
+        )
+
+    def _get_only_volume(self, virtual_machine_id):
+        list_volumes_response = list_volumes(
+            self.apiClient,
+            virtualmachineid=virtual_machine_id,
+            listall=True
+        )
+
+        sf_util.check_list(list_volumes_response, 1, self, TestOnlineStorageMigration._should_only_be_one_volume_in_list_err_msg)
+
+        return list_volumes_response[0]
+
+    def _verify_volume_on_primary_storage(self, vm_root_volume, primary_storage):
+        self.assertEqual(
+            vm_root_volume.storageid,
+            primary_storage.id,
+            TestOnlineStorageMigration._volume_not_on_correct_primary_storage
+        )
+
+    def _get_vm_name(self):
+        number = random.randint(0, 1000)
+
+        vm_name = {
+            TestData.name: "VM-%d" % number,
+            "displayname": "Test VM %d" % number
+        }
+
+        return vm_name
+
+    @classmethod
+    def _delete_all_files(cls, ip_address, username, password, path):
+        ssh_connection = sf_util.get_ssh_connection(ip_address, username, password)
+
+        ssh_connection.exec_command("sudo rm -rf " + path + "/*")
+
+        ssh_connection.close()
+
+    @classmethod
+    def _connect_to_hypervisor(cls):
+        host_ip = "https://" + \
+              list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name=TestData.xen_server_hostname)[0].ipaddress
+
+        cls.xen_session = XenAPI.Session(host_ip)
+
+        xen_server = cls.testdata[TestData.xenServer]
+
+        cls.xen_session.xenapi.login_with_password(xen_server[TestData.username], xen_server[TestData.password])
diff --git a/test/integration/plugins/solidfire/TestSnapshots.py b/test/integration/plugins/solidfire/TestSnapshots.py
index fab509e..d9ab3b2 100644
--- a/test/integration/plugins/solidfire/TestSnapshots.py
+++ b/test/integration/plugins/solidfire/TestSnapshots.py
@@ -35,7 +35,7 @@
 from marvin.lib.base import Account, DiskOffering, ServiceOffering, Snapshot, StoragePool, Template, User, VirtualMachine, Volume
 
 # common - commonly used methods for all tests are listed here
-from marvin.lib.common import get_domain, get_template, get_zone, list_clusters, list_volumes, list_snapshots
+from marvin.lib.common import get_domain, get_template, get_zone, list_volumes, list_snapshots
 
 # utils - utility classes for common cleanup, external library wrappers, etc.
 from marvin.lib.utils import cleanup_resources, wait_until
@@ -87,16 +87,16 @@
     def __init__(self):
         self.testdata = {
             TestData.solidFire: {
-                TestData.mvip: "10.117.40.120",
+                TestData.mvip: "10.117.78.225",
                 TestData.username: "admin",
                 TestData.password: "admin",
                 TestData.port: 443,
-                TestData.url: "https://10.117.40.120:443"
+                TestData.url: "https://10.117.78.225:443"
             },
             TestData.primaryStorage: {
                 "name": "SolidFire-%d" % random.randint(0, 100),
                 TestData.scope: "ZONE",
-                "url": "MVIP=10.117.40.120;SVIP=10.117.41.120;" +
+                "url": "MVIP=10.117.78.225;SVIP=10.117.94.225;" +
                        "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                        "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
                        "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
@@ -155,7 +155,6 @@
                 TestData.diskName: "test-volume-2",
             },
             TestData.zoneId: 1,
-            TestData.clusterId: 1,
             TestData.domainId: 1,
             TestData.url: "10.117.40.114"
         }
@@ -198,7 +197,6 @@
 
         # Get Resources from Cloud Infrastructure
         cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
-        cls.cluster = list_clusters(cls.apiClient)[0]
         cls.template = get_template(cls.apiClient, cls.zone.id, hypervisor=TestData.hypervisor_type)
         cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])
 
diff --git a/test/integration/plugins/solidfire/TestUploadDownload.py b/test/integration/plugins/solidfire/TestUploadDownload.py
index d81600e..a15f27b 100644
--- a/test/integration/plugins/solidfire/TestUploadDownload.py
+++ b/test/integration/plugins/solidfire/TestUploadDownload.py
@@ -185,7 +185,7 @@
 
         # Get Resources from Cloud Infrastructure
         cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
-        cls.cluster = list_clusters(cls.apiClient)[1]
+        cls.cluster = list_clusters(cls.apiClient)[0]
         cls.template = get_template(cls.apiClient, cls.zone.id, hypervisor=TestData.hypervisor_type)
         cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])
 
diff --git a/test/integration/plugins/solidfire/TestVMMigrationWithStorage.py b/test/integration/plugins/solidfire/TestVMMigrationWithStorage.py
index 93ab3b6..7da6c9d 100644
--- a/test/integration/plugins/solidfire/TestVMMigrationWithStorage.py
+++ b/test/integration/plugins/solidfire/TestVMMigrationWithStorage.py
@@ -40,6 +40,9 @@
 #  Only one zone
 #  Only one pod
 #  Two clusters (have system VMs (including the VR) running on local or NFS storage)
+#
+# Running the tests:
+#  Verify the "xen_server_hostname_src" and "xen_server_hostname_dest" variables are correct.
 
 
 class TestData():
@@ -81,6 +84,9 @@
     xenServer = "xenserver"
     zoneId = "zoneid"
 
+    xen_server_hostname_src = "XenServer-6.5-1"
+    xen_server_hostname_dest = "XenServer-6.5-3"
+
     def __init__(self):
         self.testdata = {
             TestData.solidFire: {
@@ -233,7 +239,7 @@
 
         # Set up xenAPI connection
         host_ip = "https://" + \
-                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId1], name="XenServer-6.5-1")[0].ipaddress
+                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId1], name=TestData.xen_server_hostname_src)[0].ipaddress
 
         # Set up XenAPI connection
         cls.xen_session_1 = XenAPI.Session(host_ip)
@@ -242,7 +248,7 @@
 
         # Set up xenAPI connection
         host_ip = "https://" + \
-                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId2], name="XenServer-6.5-3")[0].ipaddress
+                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId2], name=TestData.xen_server_hostname_dest)[0].ipaddress
 
         # Set up XenAPI connection
         cls.xen_session_2 = XenAPI.Session(host_ip)
@@ -532,9 +538,9 @@
         hosts = list_hosts(self.apiClient)
 
         for host in hosts:
-            if host.name == "XenServer-6.5-1":
+            if host.name == TestData.xen_server_hostname_src:
                 src_host = host
-            elif host.name == "XenServer-6.5-3":
+            elif host.name == TestData.xen_server_hostname_dest:
                 dest_host = host
 
         self.assertIsNotNone(src_host, "Could not locate the source host")
diff --git a/test/integration/plugins/solidfire/TestVMSnapshots.py b/test/integration/plugins/solidfire/TestVMSnapshots.py
index 45c4242..106d583 100644
--- a/test/integration/plugins/solidfire/TestVMSnapshots.py
+++ b/test/integration/plugins/solidfire/TestVMSnapshots.py
@@ -44,6 +44,10 @@
 #  Only one pod
 #  Only one cluster
 
+# Running the tests:
+#  Change the "hypervisor_type" variable to control which hypervisor type to test.
+#  If using XenServer, verify the "xen_server_hostname" variable is correct.
+
 
 class TestData:
     account = "account"
@@ -74,6 +78,7 @@
 
     # modify to control which hypervisor type to test
     hypervisor_type = xenServer
+    xen_server_hostname = "XenServer-6.5-1"
 
     def __init__(self):
         self.testdata = {
@@ -129,7 +134,7 @@
                 "customizediops": False,
                 "miniops": "10000",
                 "maxiops": "15000",
-                "hypervisorsnapshotreserve": 200,
+                "hypervisorsnapshotreserve": 400,
                 TestData.tags: TestData.storageTag
             },
             TestData.diskOffering: {
@@ -139,7 +144,7 @@
                 "customizediops": False,
                 "miniops": 300,
                 "maxiops": 500,
-                "hypervisorsnapshotreserve": 200,
+                "hypervisorsnapshotreserve": 400,
                 TestData.tags: TestData.storageTag,
                 "storagetype": "shared"
             },
@@ -179,7 +184,7 @@
 
         # Set up XenAPI connection
         host_ip = "https://" + \
-                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name="XenServer-6.5-1")[0].ipaddress
+                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name=TestData.xen_server_hostname)[0].ipaddress
 
         cls.xen_session = XenAPI.Session(host_ip)
 
diff --git a/test/integration/plugins/solidfire/TestVolumes.py b/test/integration/plugins/solidfire/TestVolumes.py
index 9d3ab2f..9685e50 100644
--- a/test/integration/plugins/solidfire/TestVolumes.py
+++ b/test/integration/plugins/solidfire/TestVolumes.py
@@ -51,7 +51,8 @@
 #  If using XenServer, change the "supports_cloning" variable to True or False as desired.
 #
 # Note:
-#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0]
+#  If you do have more than one cluster, you might need to change this line: cls.cluster = list_clusters(cls.apiClient)[0] and
+#   this variable's value: TestData.clusterId.
 
 
 class TestData():
@@ -79,6 +80,7 @@
     tags = "tags"
     templateCacheNameKvm = "centos55-x86-64"
     templateCacheNameXenServer = "centos56-x86-64-xen"
+    # templateCacheNameXenServer = "centos65-x86-64-XenServer"
     testAccount = "testaccount"
     url = "url"
     user = "user"
@@ -91,17 +93,17 @@
     zoneId = "zoneId"
 
     # modify to control which hypervisor type to test
-    hypervisor_type = kvm
+    hypervisor_type = xenServer
     xen_server_hostname = "XenServer-6.5-1"
 
     def __init__(self):
         self.testdata = {
             TestData.solidFire: {
-                TestData.mvip: "10.117.40.120",
+                TestData.mvip: "10.117.78.225",
                 TestData.username: "admin",
                 TestData.password: "admin",
                 TestData.port: 443,
-                TestData.url: "https://10.117.40.120:443"
+                TestData.url: "https://10.117.78.225:443"
             },
             TestData.kvm: {
                 TestData.username: "root",
@@ -135,7 +137,7 @@
             TestData.primaryStorage: {
                 "name": "SolidFire-%d" % random.randint(0, 100),
                 TestData.scope: "ZONE",
-                "url": "MVIP=10.117.40.120;SVIP=10.117.41.120;" +
+                "url": "MVIP=10.117.78.225;SVIP=10.117.94.225;" +
                        "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                        "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
                        "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
diff --git a/test/integration/smoke/test_accounts.py b/test/integration/smoke/test_accounts.py
index 08fa813..6169bf5 100644
--- a/test/integration/smoke/test_accounts.py
+++ b/test/integration/smoke/test_accounts.py
@@ -30,7 +30,7 @@
                              User,
                              NATRule,
                              Template,
-                             PublicIPAddress)
+                             PublicIPAddress, Role)
 from marvin.lib.common import (get_domain,
                                get_zone,
                                get_test_template,
@@ -67,6 +67,11 @@
                 # username
                 "password": "fr3sca",
             },
+            "role": {
+                "name": "MarvinFake Role",
+                "type": "User",
+                "description": "Fake Role created by Marvin test"
+            },
             "user": {
                 "email": "user@test.com",
                 "firstname": "User",
@@ -261,6 +266,53 @@
         return
 
 
+    @attr(tags=["advanced", "basic", "eip", "advancedns", "sg"],
+          required_hardware="false")
+    def test_02_update_account(self):
+        """
+        Tests that accounts can be updated with new name, network domain, dynamic role
+        :return:
+        """
+        dynamic_roles_active = self.apiclient.listCapabilities(listCapabilities.listCapabilitiesCmd()).dynamicrolesenabled
+        if not dynamic_roles_active:
+            self.skipTest("Dynamic Role-Based API checker not enabled, skipping test")
+
+        ts = str(time.time())
+        network_domain = 'mycloud.com'
+
+        account = Account.create(self.apiclient, self.services['account'])
+        self.cleanup.append(account)
+
+        role = Role.create(self.apiclient, self.services['role'])
+        self.cleanup.append(role)
+
+        account.update(self.apiclient, newname=account.name + ts)
+        account.update(self.apiclient, roleid=role.id)
+        account.update(self.apiclient, networkdomain=network_domain)
+
+        list_accounts_response = list_accounts(self.apiclient, id=account.id)
+        test_account = list_accounts_response[0]
+
+        self.assertEqual(
+            test_account.roleid, role.id,
+            "Check the role for the account is changed")
+
+        self.assertEqual(
+            test_account.networkdomain, network_domain,
+            "Check the domain for the account is changed")
+
+        self.assertEqual(
+            test_account.name, account.name + ts,
+            "Check the name for the account is changed")
+
+        try:
+            account.update(self.apiclient, newname="")
+            self.fail("Account name change to empty name succeeded. Must be error.")
+        except CloudstackAPIException:
+            pass
+
+
+
 class TestRemoveUserFromAccount(cloudstackTestCase):
 
     @classmethod
diff --git a/test/integration/smoke/test_async_job.py b/test/integration/smoke/test_async_job.py
new file mode 100644
index 0000000..f727dd8
--- /dev/null
+++ b/test/integration/smoke/test_async_job.py
@@ -0,0 +1,135 @@
+# 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.
+
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.utils import cleanup_resources
+from marvin.lib.base import ServiceOffering, DiskOffering, Account, VirtualMachine,\
+    queryAsyncJobResult, PASS
+from marvin.lib.common import get_domain, get_zone, get_test_template
+from pytz import timezone
+
+
+class TestAsyncJob(cloudstackTestCase):
+    """
+    Test queryAsyncJobResult
+    """
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestAsyncJob, cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+
+        cls.testdata = cls.testClient.getParsedTestDataConfig()
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client)
+        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
+        cls.hypervisor = cls.testClient.getHypervisorInfo()
+
+        cls.template = get_test_template(
+            cls.api_client,
+            cls.zone.id,
+            cls.hypervisor
+        )
+
+        # Create service, disk offerings  etc
+        cls.service_offering = ServiceOffering.create(
+            cls.api_client,
+            cls.testdata["service_offering"]
+        )
+
+        cls.disk_offering = DiskOffering.create(
+            cls.api_client,
+            cls.testdata["disk_offering"]
+        )
+
+        cls._cleanup = [
+            cls.service_offering,
+            cls.disk_offering
+        ]
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as exception:
+            raise Exception("Warning: Exception during cleanup : %s" % exception)
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.hypervisor = self.testClient.getHypervisorInfo()
+        self.testdata["virtual_machine"]["zoneid"] = self.zone.id
+        self.testdata["virtual_machine"]["template"] = self.template.id
+        self.testdata["iso"]["zoneid"] = self.zone.id
+        self.account = Account.create(
+            self.apiclient,
+            self.testdata["account"],
+            domainid=self.domain.id
+        )
+        self.cleanup = [self.account]
+
+    def tearDown(self):
+        try:
+            self.debug("Cleaning up the resources")
+            cleanup_resources(self.apiclient, self.cleanup)
+            self.debug("Cleanup complete!")
+        except Exception as exception:
+            self.debug("Warning! Exception in tearDown: %s" % exception)
+
+    @attr(tags=["advanced", "eip", "advancedns", "basic", "sg"], required_hardware="false")
+    def test_query_async_job_result(self):
+        """
+        Test queryAsyncJobResult API for expected values
+        """
+        self.debug("Deploying instance in the account: %s" %
+                   self.account.name)
+        virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.testdata["virtual_machine"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            diskofferingid=self.disk_offering.id,
+            hypervisor=self.hypervisor
+        )
+
+        response = virtual_machine.getState(
+            self.apiclient,
+            VirtualMachine.RUNNING)
+        self.assertEqual(response[0], PASS, response[1])
+
+        cmd = queryAsyncJobResult.queryAsyncJobResultCmd()
+        cmd.jobid = virtual_machine.jobid
+        cmd_response = self.apiclient.queryAsyncJobResult(cmd)
+
+        db_result = self.dbclient.execute("select * from async_job where uuid='%s'" %
+                                          virtual_machine.jobid)
+
+        # verify that 'completed' value from api equals 'removed' db column value
+        completed = cmd_response.completed
+        removed = timezone('UTC').localize(db_result[0][17])
+        removed = removed.strftime("%Y-%m-%dT%H:%M:%S%z")
+        self.assertEqual(completed, removed,
+                         "Expected 'completed' timestamp value %s to be equal to "
+                         "'removed' db column value %s." % (completed, removed))
+
+        # verify that api job_status value equals db job_status value
+        jobstatus_db = db_result[0][8]
+        jobstatus_api = cmd_response.jobstatus
+        self.assertEqual(jobstatus_api, jobstatus_db,
+                         "Expected 'jobstatus' api value %s to be equal to "
+                         "'job_status' db column value %s." % (jobstatus_api, jobstatus_db))
diff --git a/test/integration/smoke/test_diagnostics.py b/test/integration/smoke/test_diagnostics.py
new file mode 100644
index 0000000..6364d83
--- /dev/null
+++ b/test/integration/smoke/test_diagnostics.py
@@ -0,0 +1,539 @@
+# 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.
+""" BVT tests for remote diagnostics of system VMs
+"""
+# Import Local Modules
+from marvin.codes import FAILED
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.cloudstackAPI import runDiagnostics
+from marvin.lib.utils import (cleanup_resources)
+from marvin.lib.base import (Account,
+                             ServiceOffering,
+                             VirtualMachine)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_test_template,
+                               list_ssvms,
+                               list_routers)
+
+from nose.plugins.attrib import attr
+
+
+class TestRemoteDiagnostics(cloudstackTestCase):
+    """
+    Test remote diagnostics with system VMs and VR as root admin
+    """
+
+    @classmethod
+    def setUpClass(cls):
+
+        testClient = super(TestRemoteDiagnostics, cls).getClsTestClient()
+        cls.apiclient = testClient.getApiClient()
+        cls.services = testClient.getParsedTestDataConfig()
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.apiclient)
+        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+        cls.hypervisor = testClient.getHypervisorInfo()
+        cls.services['mode'] = cls.zone.networktype
+        template = get_test_template(
+            cls.apiclient,
+            cls.zone.id,
+            cls.hypervisor
+        )
+        if template == FAILED:
+            cls.fail("get_test_template() failed to return template")
+
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+
+        # Create an account, network, VM and IP addresses
+        cls.account = Account.create(
+            cls.apiclient,
+            cls.services["account"],
+            domainid=cls.domain.id
+        )
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.services["service_offerings"]["tiny"]
+        )
+        cls.vm_1 = VirtualMachine.create(
+            cls.apiclient,
+            cls.services["virtual_machine"],
+            templateid=template.id,
+            accountid=cls.account.name,
+            domainid=cls.account.domainid,
+            serviceofferingid=cls.service_offering.id
+        )
+        cls.cleanup = [
+            cls.account,
+            cls.service_offering
+        ]
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cls.apiclient = super(
+                TestRemoteDiagnostics,
+                cls
+            ).getClsTestClient().getApiClient()
+            # Clean up, terminate the created templates
+            cleanup_resources(cls.apiclient, cls.cleanup)
+
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.hypervisor = self.testClient.getHypervisorInfo()
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_01_ping_in_vr_success(self):
+        '''
+        Test Ping command execution in VR
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on VR
+
+        list_router_response = list_routers(
+            self.apiclient,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.assertEqual(
+            isinstance(list_router_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        router = list_router_response[0]
+        self.debug('Starting the router with ID: %s' % router.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = router.id
+        cmd.ipaddress = '8.8.8.8'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Ping in VR')
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_02_ping_in_vr_failure(self):
+        '''
+        Test Ping command execution in VR
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on VR
+        # 2. Validate Ping command execution with a non-existent/pingable IP address
+
+        if self.hypervisor.lower() == 'simulator':
+            raise self.skipTest("Skipping negative test case for Simulator hypervisor")
+
+        list_router_response = list_routers(
+            self.apiclient,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.assertEqual(
+            isinstance(list_router_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        router = list_router_response[0]
+        self.debug('Starting the router with ID: %s' % router.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = router.id
+        cmd.ipaddress = '192.0.2.2'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertNotEqual(
+            '0',
+            cmd_response.exitcode,
+            'Check diagnostics command returns a non-zero exit code')
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_03_ping_in_ssvm_success(self):
+        '''
+        Test Ping command execution in SSVM
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on SSVM
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='secondarystoragevm',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        ssvm = list_ssvm_response[0]
+
+        self.debug('Setting up SSVM with ID %s' % ssvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = ssvm.id
+        cmd.ipaddress = '8.8.8.8'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Ping in SSVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_04_ping_in_ssvm_failure(self):
+        '''
+        Test Ping command execution in SSVM
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on SSVM
+        # 2. Validate Ping command execution with a non-existent/pingable IP address
+
+        if self.hypervisor.lower() == 'simulator':
+            raise self.skipTest("Skipping negative test case for Simulator hypervisor")
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='secondarystoragevm',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        ssvm = list_ssvm_response[0]
+
+        self.debug('Setting up SSVM with ID %s' % ssvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = ssvm.id
+        cmd.ipaddress = '192.0.2.2'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertNotEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Ping in SSVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_05_ping_in_cpvm_success(self):
+        '''
+        Test Ping command execution in CPVM
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on CPVM
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='consoleproxy',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        cpvm = list_ssvm_response[0]
+
+        self.debug('Setting up CPVM with ID %s' % cpvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = cpvm.id
+        cmd.ipaddress = '8.8.8.8'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Ping in CPVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_06_ping_in_cpvm_failure(self):
+        '''
+        Test Ping command execution in CPVM
+        '''
+
+        # Validate the following:
+        # 1. Ping command is executed remotely on CPVM
+        # 2. Validate Ping command execution with a non-existent/pingable IP address
+
+        if self.hypervisor.lower() == 'simulator':
+            raise self.skipTest("Skipping negative test case for Simulator hypervisor")
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='consoleproxy',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        cpvm = list_ssvm_response[0]
+
+        self.debug('Setting up CPVM with ID %s' % cpvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = cpvm.id
+        cmd.ipaddress = '192.0.2.2'
+        cmd.type = 'ping'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertNotEqual(
+            '0',
+            cmd_response.exitcode,
+            'Check diagnostics command returns a non-zero exit code'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_07_arping_in_vr(self):
+        '''
+        Test Arping command execution in VR
+        '''
+
+        # Validate the following:
+        # 1. Arping command is executed remotely on VR
+
+        list_router_response = list_routers(
+            self.apiclient,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.assertEqual(
+            isinstance(list_router_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        router = list_router_response[0]
+        self.debug('Starting the router with ID: %s' % router.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = router.id
+        cmd.ipaddress = router.gateway
+        cmd.type = 'arping'
+        cmd.params = "-I eth2"
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Arping in VR')
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_08_arping_in_ssvm(self):
+        '''
+        Test Arping command execution in SSVM
+        '''
+
+        # Validate the following:
+        # 1. Arping command is executed remotely on SSVM
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='secondarystoragevm',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        ssvm = list_ssvm_response[0]
+
+        self.debug('Setting up SSVM with ID %s' % ssvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = ssvm.id
+        cmd.ipaddress = ssvm.gateway
+        cmd.type = 'arping'
+        cmd.params = '-I eth2'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Arping in SSVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_09_arping_in_cpvm(self):
+        '''
+        Test Arping command execution in CPVM
+        '''
+
+        # Validate the following:
+        # 1. Arping command is executed remotely on CPVM
+
+        list_cpvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='secondarystoragevm',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_cpvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        cpvm = list_cpvm_response[0]
+
+        self.debug('Setting up CPVM with ID %s' % cpvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = cpvm.id
+        cmd.ipaddress = cpvm.gateway
+        cmd.type = 'arping'
+        cmd.params = '-I eth2'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Arping in CPVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_10_traceroute_in_vr(self):
+        '''
+        Test Arping command execution in VR
+        '''
+
+        # Validate the following:
+        # 1. Arping command is executed remotely on VR
+
+        list_router_response = list_routers(
+            self.apiclient,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.assertEqual(
+            isinstance(list_router_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        router = list_router_response[0]
+        self.debug('Starting the router with ID: %s' % router.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = router.id
+        cmd.ipaddress = '8.8.4.4'
+        cmd.type = 'traceroute'
+        cmd.params = "-m 10"
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Arping in VR')
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_11_traceroute_in_ssvm(self):
+        '''
+        Test Traceroute command execution in SSVM
+        '''
+
+        # Validate the following:
+        # 1. Traceroute command is executed remotely on SSVM
+
+        list_ssvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='secondarystoragevm',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_ssvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        ssvm = list_ssvm_response[0]
+
+        self.debug('Setting up SSVM with ID %s' % ssvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = ssvm.id
+        cmd.ipaddress = '8.8.4.4'
+        cmd.type = 'traceroute'
+        cmd.params = '-m 10'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Traceroute in SSVM'
+        )
+
+    @attr(tags=["advanced", "advancedns", "ssh", "smoke"], required_hardware="true")
+    def test_12_traceroute_in_cpvm(self):
+        '''
+        Test Traceroute command execution in CPVMM
+        '''
+
+        # Validate the following:
+        # 1. Traceroute command is executed remotely on CPVM
+
+        list_cpvm_response = list_ssvms(
+            self.apiclient,
+            systemvmtype='consoleproxy',
+            state='Running',
+        )
+
+        self.assertEqual(
+            isinstance(list_cpvm_response, list),
+            True,
+            'Check list response returns a valid list'
+        )
+        cpvm = list_cpvm_response[0]
+
+        self.debug('Setting up CPVMM with ID %s' % cpvm.id)
+
+        cmd = runDiagnostics.runDiagnosticsCmd()
+        cmd.targetid = cpvm.id
+        cmd.ipaddress = '8.8.4.4'
+        cmd.type = 'traceroute'
+        cmd.params = '-m 10'
+        cmd_response = self.apiclient.runDiagnostics(cmd)
+
+        self.assertEqual(
+            '0',
+            cmd_response.exitcode,
+            'Failed to run remote Traceroute in CPVM'
+        )
diff --git a/test/integration/smoke/test_disk_offerings.py b/test/integration/smoke/test_disk_offerings.py
index fed0690..af7ba6a2 100644
--- a/test/integration/smoke/test_disk_offerings.py
+++ b/test/integration/smoke/test_disk_offerings.py
@@ -5,9 +5,9 @@
 # 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
@@ -171,6 +171,58 @@
                         )
         return
 
+    @attr(hypervisor="kvm")
+    @attr(tags = ["advanced", "basic", "eip", "sg", "advancedns", "simulator", "smoke"])
+    def test_05_create_burst_type_disk_offering(self):
+        """Test to create a disk offering with io bursting enabled"""
+
+        # Validate the following:
+        # 1. createDiskOfferings should return valid info for new offering with io burst settings
+        # 2. The Cloud Database contains the valid information
+
+        burstBits = {}
+        for key in self.services["ioburst"]:
+            if str(key).startswith("bytes") or str(key).startswith("iops"):
+                burstBits[key] = self.services["ioburst"][key]
+
+        disk_offering = DiskOffering.create(
+            self.apiclient,
+            self.services["ioburst"],
+            None,
+            False,
+            None,
+            **burstBits
+        )
+        self.cleanup.append(disk_offering)
+
+        self.debug("Created Disk offering with ID: %s" % disk_offering.id)
+
+        list_disk_response = list_disk_offering(
+            self.apiclient,
+            id=disk_offering.id
+        )
+        self.assertEqual(
+            isinstance(list_disk_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        self.assertNotEqual(
+            len(list_disk_response),
+            0,
+            "Check Disk offering is created"
+        )
+        disk_response = list_disk_response[0]
+
+        for key in burstBits:
+            k = str(key)
+            mapped = 'disk' + k[:1].upper() + k[1:]
+            self.assertEqual(
+                disk_response[mapped],
+                self.services["ioburst"][key],
+                "Check " + str(key) + " in createServiceOffering"
+            )
+        return
+
 class TestDiskOfferings(cloudstackTestCase):
 
     def setUp(self):
@@ -193,7 +245,7 @@
         testClient = super(TestDiskOfferings, cls).getClsTestClient()
         cls.apiclient = cls.testClient.getApiClient()
         cls.services = cls.testClient.getParsedTestDataConfig()
-        
+
         cls.disk_offering_1 = DiskOffering.create(
                                                   cls.apiclient,
                                                   cls.services["disk_offering"]
@@ -227,9 +279,9 @@
         random_displaytext = random_gen()
         random_name = random_gen()
 
-        self.debug("Updating Disk offering with ID: %s" % 
+        self.debug("Updating Disk offering with ID: %s" %
                                     self.disk_offering_1.id)
-        
+
         cmd = updateDiskOffering.updateDiskOfferingCmd()
         cmd.id = self.disk_offering_1.id
         cmd.displaytext = random_displaytext
@@ -276,7 +328,7 @@
         """
         self.disk_offering_2.delete(self.apiclient)
 
-        self.debug("Deleted Disk offering with ID: %s" % 
+        self.debug("Deleted Disk offering with ID: %s" %
                                     self.disk_offering_2.id)
         list_disk_response = list_disk_offering(
                                                 self.apiclient,
diff --git a/test/integration/smoke/test_hostha_simulator.py b/test/integration/smoke/test_hostha_simulator.py
index 4dfb9e9..bb25d47 100644
--- a/test/integration/smoke/test_hostha_simulator.py
+++ b/test/integration/smoke/test_hostha_simulator.py
@@ -161,7 +161,7 @@
         cmd.recover = recover
         cmd.fence = fence
         response = self.apiclient.configureSimulatorHAProviderState(cmd)
-        self.assertEqual(response.success, 'true')
+        self.assertEqual(response.success, True)
 
 
     def getSimulatorHAStateTransitions(self, hostId):
diff --git a/test/integration/smoke/test_iso.py b/test/integration/smoke/test_iso.py
index afd540a..53e42cb 100644
--- a/test/integration/smoke/test_iso.py
+++ b/test/integration/smoke/test_iso.py
@@ -304,6 +304,7 @@
             self.apiclient,
             id=self.iso_1.id
         )
+
         self.assertEqual(
             isinstance(list_iso_response, list),
             True,
@@ -332,6 +333,13 @@
             self.services["ostypeid"],
             "Check OSTypeID of updated ISO"
         )
+
+        self.assertEqual(
+            iso_response.passwordenabled,
+            bool(self.services["passwordenabled"]),
+            "Check passwordenabled of updated ISO"
+        )
+
         return
 
     @attr(
diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py
index 1a0d1a7..e49f547 100644
--- a/test/integration/smoke/test_network.py
+++ b/test/integration/smoke/test_network.py
@@ -110,6 +110,42 @@
             cls.user.domainid
         )
 
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.services["service_offerings"]["tiny"],
+        )
+
+        cls.hypervisor = testClient.getHypervisorInfo()
+        cls.template = get_test_template(
+            cls.apiclient,
+            cls.zone.id,
+            cls.hypervisor
+        )
+        if cls.template == FAILED:
+            assert False, "get_test_template() failed to return template"
+
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+
+        cls.account_vm = VirtualMachine.create(
+            cls.apiclient,
+            cls.services["virtual_machine"],
+            templateid=cls.template.id,
+            accountid=cls.account.name,
+            domainid=cls.account.domainid,
+            networkids=cls.account_network.id,
+            serviceofferingid=cls.service_offering.id
+        )
+
+        cls.user_vm = VirtualMachine.create(
+            cls.apiclient,
+            cls.services["virtual_machine"],
+            templateid=cls.template.id,
+            accountid=cls.user.name,
+            domainid=cls.user.domainid,
+            networkids=cls.user_network.id,
+            serviceofferingid=cls.service_offering.id
+        )
+
         # Create Source NAT IP addresses
         PublicIPAddress.create(
             cls.apiclient,
@@ -124,6 +160,8 @@
             cls.user.domainid
         )
         cls._cleanup = [
+            cls.account_vm,
+            cls.user_vm,
             cls.account_network,
             cls.user_network,
             cls.account,
diff --git a/test/integration/smoke/test_portforwardingrules.py b/test/integration/smoke/test_portforwardingrules.py
index 11901bd..8aaa088 100644
--- a/test/integration/smoke/test_portforwardingrules.py
+++ b/test/integration/smoke/test_portforwardingrules.py
@@ -16,33 +16,23 @@
 # under the License.
 
 # Import Local Modules
-from marvin.cloudstackTestCase import cloudstackTestCase, unittest
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.codes import PASS
 from marvin.lib.base import (PublicIPAddress,
                              NetworkOffering,
-                             Autoscale,
                              Network,
-                             NetworkServiceProvider,
-                             Template,
                              VirtualMachine,
-                             VPC,
                              VpcOffering,
-                             StaticNATRule,
-                             FireWallRule,
                              NATRule,
-                             Vpn,
-                             VpnUser,
-                             LoadBalancerRule,
                              Account,
-                             ServiceOffering,
-                             PhysicalNetwork,
-                             User)
+                             ServiceOffering)
 from marvin.lib.common import (get_domain,
                                get_zone,
                                get_test_template)
 from marvin.lib.utils import validateList, cleanup_resources
-from marvin.codes import PASS
 from nose.plugins.attrib import attr
 
+
 class TestPortForwardingRules(cloudstackTestCase):
 
     @classmethod
@@ -121,6 +111,7 @@
             cleanup_resources(cls.api_client, cls._cleanup)
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
 
     def __verify_values(self, expected_vals, actual_vals):
         """
@@ -153,8 +144,6 @@
                     (exp_val, act_val))
         return return_flag
 
-
-
     @attr(tags=["advanced"], required_hardware="true")
     def test_01_create_delete_portforwarding_fornonvpc(self):
         """
@@ -213,6 +202,7 @@
             networkofferingid=network_offerings_list[0].id,
             zoneid=self.zone.id
         )
+
         self.assertIsNotNone(
             network,
             "Network creation failed"
@@ -227,6 +217,25 @@
             list_ipaddresses_before,
             "IP Addresses listed for newly created User"
         )
+
+        service_offering = ServiceOffering.create(
+            self.apiClient,
+            self.services["service_offerings"]["tiny"],
+        )
+
+        self.services["virtual_machine"]["zoneid"] = self.zone.id
+
+        vm = VirtualMachine.create(
+            self.userapiclient,
+            self.services["virtual_machine"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkids=network.id,
+            serviceofferingid=service_offering.id
+        )
+
+        VirtualMachine.delete(vm, self.apiClient, expunge=True)
+
         # Associating an IP Addresses to Network created
         associated_ipaddress = PublicIPAddress.create(
             self.userapiclient,
@@ -248,9 +257,9 @@
             status[0],
             "IP Addresses Association Failed"
         )
-        # Verifying the length of the list is 1
+        # Verifying the length of the list is 2
         self.assertEqual(
-            1,
+            2,
             len(list_ipaddresses_after),
             "Number of IP Addresses associated are not matching expected"
         )
@@ -281,9 +290,9 @@
             status[0],
             "VM Created is not in Running state"
         )
-        # Verifying the length of the list is 1
+        # Verifying the length of the list is 2
         self.assertEqual(
-            1,
+            2,
             len(list_ipaddresses_after),
             "VM Created is not in Running state"
         )
@@ -370,35 +379,34 @@
         # Deleting Port Forwarding Rule
         portfwd_rule.delete(self.userapiclient)
 
-
         # Creating a Port Forwarding rule with port range
         portfwd_rule = NATRule.create(
             self.userapiclient,
             virtual_machine=vm_created,
             services=self.services["natrulerange"],
             ipaddressid=associated_ipaddress.ipaddress.id,
-            )
+        )
         self.assertIsNotNone(
             portfwd_rule,
             "Failed to create Port Forwarding Rule"
         )
-        #update the private port for port forwarding rule
+        # update the private port for port forwarding rule
         updatefwd_rule = portfwd_rule.update(self.userapiclient,
-                            portfwd_rule.id,
-                            virtual_machine=vm_created,
-                            services=self.services["updatenatrulerange"],
-                            )
+                                             portfwd_rule.id,
+                                             virtual_machine=vm_created,
+                                             services=self.services["updatenatrulerange"],
+                                             )
 
         # Verifying details of Sticky Policy created
         # Creating expected and actual values dictionaries
         expected_dict = {
             "privateport": str(self.services["updatenatrulerange"]["privateport"]),
             "privateendport": str(self.services["updatenatrulerange"]["privateendport"]),
-            }
+        }
         actual_dict = {
             "privateport": str(updatefwd_rule.privateport),
             "privateendport": str(updatefwd_rule.privateendport),
-            }
+        }
         portfwd_status = self.__verify_values(
             expected_dict,
             actual_dict
@@ -425,4 +433,3 @@
         vm_created.delete(self.apiClient)
         self.cleanup.append(self.account)
         return
-
diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py
index 882df3c..d397c77 100644
--- a/test/integration/smoke/test_primary_storage.py
+++ b/test/integration/smoke/test_primary_storage.py
@@ -16,21 +16,19 @@
 # under the License.
 """ BVT tests for Primary Storage
 """
-#Import Local Modules
-import marvin
+
+# Import System modules
+# Import Local Modules
 from marvin.cloudstackTestCase import *
-from marvin.cloudstackAPI import *
-from marvin.lib.utils import *
 from marvin.lib.base import *
 from marvin.lib.common import *
-from nose.plugins.attrib import attr
-import logging
 from marvin.lib.decoratorGenerators import skipTestIf
+from marvin.lib.utils import *
+from nose.plugins.attrib import attr
 
-#Import System modules
-import time
 _multiprocess_shared_ = True
 
+
 class TestPrimaryStorageServices(cloudstackTestCase):
 
     def setUp(self):
@@ -43,24 +41,20 @@
         self.pod = get_pod(self.apiclient, self.zone.id)
         self.hypervisor = self.testClient.getHypervisorInfo()
         self.domain = get_domain(self.apiclient)
-        self.template = get_template(
-            self.apiclient ,
-            self.zone.id ,
-            self.services["ostype"]
-        )
+        self.template = get_template(self.apiclient, self.zone.id, self.services["ostype"])
 
         return
 
     def tearDown(self):
         try:
-            #Clean up, terminate the created templates
+            # Clean up, terminate the created templates
             cleanup_resources(self.apiclient, self.cleanup)
 
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
         return
 
-    @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_01_primary_storage_nfs(self):
         """Test primary storage pools - XEN, KVM, VMWare. Not Supported for hyperv
         """
@@ -68,39 +62,36 @@
         if self.hypervisor.lower() in ["hyperv"]:
             raise self.skipTest("NFS primary storage not supported for Hyper-V")
 
-
         # Validate the following:
         # 1. List Clusters
         # 2. verify that the cluster is in 'Enabled' allocation state
         # 3. verify that the host is added successfully and
         #    in Up state with listHosts api response
 
-        #Create NFS storage pools with on XEN/KVM/VMWare clusters
-
+        # Create NFS storage pools with on XEN/KVM/VMWare clusters
 
         clusters = list_clusters(
             self.apiclient,
             zoneid=self.zone.id
         )
-        assert isinstance(clusters,list) and len(clusters)>0
+        assert isinstance(clusters, list) and len(clusters) > 0
         for cluster in clusters:
-
-            #Host should be present before adding primary storage
+            # Host should be present before adding primary storage
             list_hosts_response = list_hosts(
-                                             self.apiclient,
-                                             clusterid=cluster.id
-                                             )
+                self.apiclient,
+                clusterid=cluster.id
+            )
             self.assertEqual(
-                            isinstance(list_hosts_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+                isinstance(list_hosts_response, list),
+                True,
+                "Check list response returns a valid list"
+            )
 
             self.assertNotEqual(
-                        len(list_hosts_response),
-                        0,
-                        "Check list Hosts in the cluster: " + cluster.name
-                        )
+                len(list_hosts_response),
+                0,
+                "Check list Hosts in the cluster: " + cluster.name
+            )
 
             storage = StoragePool.create(self.apiclient,
                                          self.services["nfs"],
@@ -116,53 +107,52 @@
                 storage.state,
                 'Up',
                 "Check primary storage state "
-                )
+            )
 
             self.assertEqual(
                 storage.type,
                 'NetworkFilesystem',
                 "Check storage pool type "
-                )
+            )
 
-            #Verify List Storage pool Response has newly added storage pool
+            # Verify List Storage pool Response has newly added storage pool
             storage_pools_response = list_storage_pools(
-                                                        self.apiclient,
-                                                        id=storage.id,
-                                                        )
+                self.apiclient,
+                id=storage.id,
+            )
             self.assertEqual(
-                            isinstance(storage_pools_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+                isinstance(storage_pools_response, list),
+                True,
+                "Check list response returns a valid list"
+            )
             self.assertNotEqual(
-                            len(storage_pools_response),
-                            0,
-                            "Check list Hosts response"
-                        )
+                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"
-                    )
+                storage_response.id,
+                storage.id,
+                "Check storage pool ID"
+            )
             self.assertEqual(
-                    storage.type,
-                    storage_response.type,
-                    "Check storage pool type "
-                )
+                storage.type,
+                storage_response.type,
+                "Check storage pool type "
+            )
             # Call cleanup for reusing primary storage
             cleanup_resources(self.apiclient, self.cleanup)
             self.cleanup = []
             return
 
-
-    @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true")
+    @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true")
     def test_01_primary_storage_iscsi(self):
         """Test primary storage pools - XEN. Not Supported for kvm,hyperv,vmware
         """
 
-        if self.hypervisor.lower() in ["kvm","hyperv", "vmware", "lxc"]:
+        if self.hypervisor.lower() in ["kvm", "hyperv", "vmware", "lxc"]:
             raise self.skipTest("iscsi primary storage not supported on kvm, VMWare, Hyper-V, or LXC")
 
         if not self.services["configurableData"]["iscsi"]["url"]:
@@ -179,26 +169,24 @@
             self.apiclient,
             zoneid=self.zone.id
         )
-        assert isinstance(clusters,list) and len(clusters)>0
+        assert isinstance(clusters, list) and len(clusters) > 0
         for cluster in clusters:
-
-            #Host should be present before adding primary storage
+            # Host should be present before adding primary storage
             list_hosts_response = list_hosts(
-                                             self.apiclient,
-                                             clusterid=cluster.id
-                                             )
+                self.apiclient,
+                clusterid=cluster.id
+            )
             self.assertEqual(
-                            isinstance(list_hosts_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+                isinstance(list_hosts_response, list),
+                True,
+                "Check list response returns a valid list"
+            )
 
             self.assertNotEqual(
-                        len(list_hosts_response),
-                        0,
-                        "Check list Hosts in the cluster: " + cluster.name
-                        )
-
+                len(list_hosts_response),
+                0,
+                "Check list Hosts in the cluster: " + cluster.name
+            )
 
             storage = StoragePool.create(self.apiclient,
                                          self.services["configurableData"]["iscsi"],
@@ -214,58 +202,58 @@
                 storage.state,
                 'Up',
                 "Check primary storage state "
-                )
+            )
 
             self.assertEqual(
                 storage.type,
                 'IscsiLUN',
                 "Check storage pool type "
-                )
+            )
 
-            #Verify List Storage pool Response has newly added storage pool
+            # Verify List Storage pool Response has newly added storage pool
             storage_pools_response = list_storage_pools(
-                                                        self.apiclient,
-                                                        id=storage.id,
-                                                        )
+                self.apiclient,
+                id=storage.id,
+            )
             self.assertEqual(
-                            isinstance(storage_pools_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+                isinstance(storage_pools_response, list),
+                True,
+                "Check list response returns a valid list"
+            )
             self.assertNotEqual(
-                            len(storage_pools_response),
-                            0,
-                            "Check list Hosts response"
-                        )
+                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"
-                    )
+                storage_response.id,
+                storage.id,
+                "Check storage pool ID"
+            )
             self.assertEqual(
-                    storage.type,
-                    storage_response.type,
-                    "Check storage pool type "
-                )
+                storage.type,
+                storage_response.type,
+                "Check storage pool type "
+            )
             # Call cleanup for reusing primary storage
             cleanup_resources(self.apiclient, self.cleanup)
             self.cleanup = []
 
         return
 
-    @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_01_add_primary_storage_disabled_host(self):
         """Test add primary storage pool with disabled host
         """
 
-        #Disable a host
+        # Disable a host
         clusters = list_clusters(
             self.apiclient,
             zoneid=self.zone.id
         )
-        assert isinstance(clusters,list) and len(clusters)>0
+        assert isinstance(clusters, list) and len(clusters) > 0
         for cluster in clusters:
 
             list_hosts_response = list_hosts(
@@ -273,15 +261,14 @@
                 clusterid=cluster.id,
                 type="Routing"
             )
-            assert isinstance(list_hosts_response,list)
+            assert isinstance(list_hosts_response, list)
             if len(list_hosts_response) < 2:
                 continue
             selected_cluster = cluster
             selected_host = list_hosts_response[0]
             Host.update(self.apiclient, id=selected_host.id, allocationstate="Disable")
 
-
-            #create a pool
+            # create a pool
             storage_pool_2 = StoragePool.create(
                 self.apiclient,
                 self.services["nfs2"],
@@ -289,24 +276,23 @@
                 zoneid=self.zone.id,
                 podid=self.pod.id
             )
-            #self.cleanup.append(storage_pool_2)
+            # self.cleanup.append(storage_pool_2)
 
-            #Enable host and disable others
+            # Enable host and disable others
             Host.update(self.apiclient, id=selected_host.id, allocationstate="Enable")
-            for host in list_hosts_response :
-                if(host.id == selected_host.id) :
+            for host in list_hosts_response:
+                if (host.id == selected_host.id):
                     continue
                 Host.update(self.apiclient, id=host.id, allocationstate="Disable")
 
-
-            #put other pools in maintenance
-            storage_pool_list = StoragePool.list(self.apiclient, zoneid = self.zone.id)
-            for pool in storage_pool_list :
-                if(pool.id == storage_pool_2.id) :
+            # put other pools in maintenance
+            storage_pool_list = StoragePool.list(self.apiclient, zoneid=self.zone.id)
+            for pool in storage_pool_list:
+                if (pool.id == storage_pool_2.id):
                     continue
-                StoragePool.update(self.apiclient,id=pool.id, enabled=False)
+                StoragePool.update(self.apiclient, id=pool.id, enabled=False)
 
-            #deployvm
+            # deployvm
             try:
                 # Create Account
                 account = Account.create(
@@ -333,20 +319,20 @@
                 self.cleanup.append(self.virtual_machine)
                 self.cleanup.append(account)
             finally:
-                #cancel maintenance
-                for pool in storage_pool_list :
-                    if(pool.id == storage_pool_2.id) :
+                # cancel maintenance
+                for pool in storage_pool_list:
+                    if (pool.id == storage_pool_2.id):
                         continue
-                    StoragePool.update(self.apiclient,id=pool.id, enabled=True)
-                #Enable all hosts
-                for host in list_hosts_response :
-                    if(host.id == selected_host.id) :
+                    StoragePool.update(self.apiclient, id=pool.id, enabled=True)
+                # Enable all hosts
+                for host in list_hosts_response:
+                    if (host.id == selected_host.id):
                         continue
                     Host.update(self.apiclient, id=host.id, allocationstate="Enable")
 
                 cleanup_resources(self.apiclient, self.cleanup)
                 self.cleanup = []
-                StoragePool.enableMaintenance(self.apiclient,storage_pool_2.id)
+                StoragePool.enableMaintenance(self.apiclient, storage_pool_2.id)
                 time.sleep(30);
                 cmd = deleteStoragePool.deleteStoragePoolCmd()
                 cmd.id = storage_pool_2.id
@@ -359,21 +345,23 @@
 class StorageTagsServices:
     """Test Storage Tags Data Class.
     """
+
     def __init__(self):
         self.storage_tags = {
-            "a" : "NFS-A",
-            "b" : "NFS-B"
+            "a": "NFS-A",
+            "b": "NFS-B"
         }
-    
+
+
 class TestStorageTags(cloudstackTestCase):
-    
+
     @classmethod
     def setUpClass(cls):
         cls.logger = logging.getLogger('TestStorageTags')
         cls.stream_handler = logging.StreamHandler()
         cls.logger.setLevel(logging.DEBUG)
         cls.logger.addHandler(cls.stream_handler)
-        
+
         test_case = super(TestStorageTags, cls)
         testClient = test_case.getClsTestClient()
         cls.config = test_case.getClsConfig()
@@ -383,44 +371,39 @@
         cls.pod = get_pod(cls.apiclient, cls.zone.id)
         cls.hypervisor = testClient.getHypervisorInfo()
         cls.domain = get_domain(cls.apiclient)
-        cls.template = get_template(
-            cls.apiclient,
-            cls.zone.id,
-            cls.services["ostype"]
-        )
+        cls.template = get_template(cls.apiclient, cls.zone.id, cls.services["ostype"])
         cls.services["virtual_machine"]["zoneid"] = cls.zone.id
         cls.services["virtual_machine"]["template"] = cls.template.id
         cls.services["storage_tags"] = StorageTagsServices().storage_tags
-        
+
         cls.hypervisorNotSupported = False
         if cls.hypervisor.lower() in ["hyperv"]:
             cls.hypervisorNotSupported = True
         cls._cleanup = []
-        
+
         if not cls.hypervisorNotSupported:
-            
             cls.clusters = list_clusters(
                 cls.apiclient,
                 zoneid=cls.zone.id
             )
             assert isinstance(cls.clusters, list) and len(cls.clusters) > 0
-    
+
             # Create PS with Storage Tag
             cls.storage_pool_1 = StoragePool.create(cls.apiclient,
-                                         cls.services["nfs"],
-                                         clusterid=cls.clusters[0].id,
-                                         zoneid=cls.zone.id,
-                                         podid=cls.pod.id,
-                                         tags=cls.services["storage_tags"]["a"]
-            )
-            #PS not appended to _cleanup, it is removed on tearDownClass before cleaning up resources
+                                                    cls.services["nfs"],
+                                                    clusterid=cls.clusters[0].id,
+                                                    zoneid=cls.zone.id,
+                                                    podid=cls.pod.id,
+                                                    tags=cls.services["storage_tags"]["a"]
+                                                    )
+            # PS not appended to _cleanup, it is removed on tearDownClass before cleaning up resources
             assert cls.storage_pool_1.state == 'Up'
             storage_pools_response = list_storage_pools(cls.apiclient,
                                                         id=cls.storage_pool_1.id)
             assert isinstance(storage_pools_response, list) and len(storage_pools_response) > 0
             storage_response = storage_pools_response[0]
             assert storage_response.id == cls.storage_pool_1.id and storage_response.type == cls.storage_pool_1.type
-            
+
             # Create Service Offerings with different Storage Tags
             cls.service_offering_1 = ServiceOffering.create(
                 cls.apiclient,
@@ -434,7 +417,7 @@
                 tags=cls.services["storage_tags"]["b"]
             )
             cls._cleanup.append(cls.service_offering_2)
-            
+
             # Create Disk Offerings with different Storage Tags
             cls.disk_offering_1 = DiskOffering.create(
                 cls.apiclient,
@@ -448,7 +431,7 @@
                 tags=cls.services["storage_tags"]["b"]
             )
             cls._cleanup.append(cls.disk_offering_2)
-            
+
             # Create Account
             cls.account = Account.create(
                 cls.apiclient,
@@ -456,7 +439,7 @@
                 domainid=cls.domain.id
             )
             cls._cleanup.append(cls.account)
-            
+
             # Create VM-1 with using Service Offering 1
             cls.virtual_machine_1 = VirtualMachine.create(
                 cls.apiclient,
@@ -469,29 +452,30 @@
                 mode=cls.zone.networktype
             )
             # VM-1 not appended to _cleanup, it is expunged on tearDownClass before cleaning up resources
-            
+
         return
-    
+
     @classmethod
     def tearDownClass(cls):
         try:
             # First expunge vm, so PS can be cleaned up
             cls.virtual_machine_1.delete(cls.apiclient)
+            time.sleep(60)
 
             # Force delete primary storage
             cmd = enableStorageMaintenance.enableStorageMaintenanceCmd()
             cmd.id = cls.storage_pool_1.id
             cls.apiclient.enableStorageMaintenance(cmd)
-            time.sleep(30)
+            time.sleep(45)
             cmd = deleteStoragePool.deleteStoragePoolCmd()
             cmd.id = cls.storage_pool_1.id
             cmd.forced = True
             cls.apiclient.deleteStoragePool(cmd)
-
+            time.sleep(30)
             cleanup_resources(cls.apiclient, cls._cleanup)
         except Exception as e:
             raise Exception("Cleanup failed with %s" % e)
-    
+
     def setUp(self):
         self.dbclient = self.testClient.getDbConnection()
         self.cleanup = []
@@ -502,16 +486,16 @@
             cleanup_resources(self.apiclient, self.cleanup)
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
-    
+
     @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     @skipTestIf("hypervisorNotSupported")
     def test_01_deploy_vms_storage_tags(self):
         """Test Deploy VMS using different Service Offerings with Storage Tags
         """
-        
+
         # Save cleanup size before trying to deploy VM-2
         cleanup_size = len(self.cleanup)
-        
+
         # Try deploying VM-2 using CO-2 -> Should fail to find storage and fail deployment
         try:
             self.virtual_machine_2 = VirtualMachine.create(
@@ -526,32 +510,32 @@
             self.cleanup.append(self.virtual_machine_2)
         except Exception as e:
             self.debug("Expected exception %s: " % e)
-        
+
         self.debug("Asssert that vm2 was not deployed, so it couldn't be appended to cleanup")
         self.assertEquals(cleanup_size, len(self.cleanup))
-        
+
         # Create V-1 using DO-1
         self.volume_1 = Volume.create(
-           self.apiclient,
-           self.services,
-           zoneid=self.zone.id,
-           account=self.account.name,
-           domainid=self.account.domainid,
-           diskofferingid=self.disk_offering_1.id
+            self.apiclient,
+            self.services,
+            zoneid=self.zone.id,
+            account=self.account.name,
+            domainid=self.account.domainid,
+            diskofferingid=self.disk_offering_1.id
         )
         self.cleanup.append(self.volume_1)
-        
+
         # Create V-2 using DO-2
         self.volume_2 = Volume.create(
-           self.apiclient,
-           self.services,
-           zoneid=self.zone.id,
-           account=self.account.name,
-           domainid=self.account.domainid,
-           diskofferingid=self.disk_offering_2.id
+            self.apiclient,
+            self.services,
+            zoneid=self.zone.id,
+            account=self.account.name,
+            domainid=self.account.domainid,
+            diskofferingid=self.disk_offering_2.id
         )
         self.cleanup.append(self.volume_2)
-        
+
         # Try attaching V-2 to VM-1 -> Should fail finding storage and fail attachment
         try:
             self.virtual_machine_1.attach_volume(
@@ -560,7 +544,7 @@
             )
         except Exception as e:
             self.debug("Expected exception %s: " % e)
-        
+
         vm_1_volumes = Volume.list(
             self.apiclient,
             virtualmachineid=self.virtual_machine_1.id,
@@ -569,9 +553,9 @@
         )
         self.debug("VM-1 Volumes: %s" % vm_1_volumes)
         self.assertEquals(None, vm_1_volumes, "Check that volume V-2 has not been attached to VM-1")
-        
+
         # Attach V_1 to VM_1
-        self.virtual_machine_1.attach_volume(self.apiclient,self.volume_1)
+        self.virtual_machine_1.attach_volume(self.apiclient, self.volume_1)
         vm_1_volumes = Volume.list(
             self.apiclient,
             virtualmachineid=self.virtual_machine_1.id,
@@ -581,22 +565,22 @@
         self.debug("VM-1 Volumes: %s" % vm_1_volumes)
         self.assertEquals(vm_1_volumes[0].id, self.volume_1.id, "Check that volume V-1 has been attached to VM-1")
         self.virtual_machine_1.detach_volume(self.apiclient, self.volume_1)
-        
+
         return
-    
+
     def check_storage_pool_tag(self, poolid, tag):
         cmd = listStorageTags.listStorageTagsCmd()
         storage_tags_response = self.apiclient.listStorageTags(cmd)
         pool_tags = filter(lambda x: x.poolid == poolid, storage_tags_response)
         self.assertEquals(1, len(pool_tags), "Check storage tags size")
         self.assertEquals(tag, pool_tags[0].name, "Check storage tag on storage pool")
-    
+
     @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     @skipTestIf("hypervisorNotSupported")
     def test_02_edit_primary_storage_tags(self):
         """ Test Edit Storage Tags
         """
-        
+
         qresultset = self.dbclient.execute(
             "select id from storage_pool where uuid = '%s';"
             % str(self.storage_pool_1.id)
@@ -604,43 +588,43 @@
         self.assertEquals(1, len(qresultset), "Check DB Query result set")
         qresult = qresultset[0]
         storage_pool_db_id = qresult[0]
-        
+
         self.check_storage_pool_tag(storage_pool_db_id, self.services["storage_tags"]["a"])
-        
+
         # Update Storage Tag
         StoragePool.update(
             self.apiclient,
             id=self.storage_pool_1.id,
             tags=self.services["storage_tags"]["b"]
         )
-        
+
         self.check_storage_pool_tag(storage_pool_db_id, self.services["storage_tags"]["b"])
-        
+
         # Revert Storage Tag
         StoragePool.update(
             self.apiclient,
             id=self.storage_pool_1.id,
             tags=self.services["storage_tags"]["a"]
         )
-        
+
         self.check_storage_pool_tag(storage_pool_db_id, self.services["storage_tags"]["a"])
-        
+
         return
-    
+
     @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     @skipTestIf("hypervisorNotSupported")
     def test_03_migration_options_storage_tags(self):
         """ Test Volume migration options for Storage Pools with different Storage Tags
         """
-        
+
         # Create PS-2 using Storage Tag
         storage_pool_2 = StoragePool.create(self.apiclient,
-                                             self.services["nfs2"],
-                                             clusterid=self.clusters[0].id,
-                                             zoneid=self.zone.id,
-                                             podid=self.pod.id,
-                                             tags=self.services["storage_tags"]["a"]
-        )
+                                            self.services["nfs2"],
+                                            clusterid=self.clusters[0].id,
+                                            zoneid=self.zone.id,
+                                            podid=self.pod.id,
+                                            tags=self.services["storage_tags"]["a"]
+                                            )
         self.cleanup.append(storage_pool_2)
         assert storage_pool_2.state == 'Up'
         storage_pools_response = list_storage_pools(self.apiclient,
@@ -648,7 +632,7 @@
         assert isinstance(storage_pools_response, list) and len(storage_pools_response) > 0
         storage_response = storage_pools_response[0]
         assert storage_response.id == storage_pool_2.id and storage_response.type == storage_pool_2.type
-        
+
         vm_1_volumes = Volume.list(
             self.apiclient,
             virtualmachineid=self.virtual_machine_1.id,
@@ -660,28 +644,41 @@
         if self.hypervisor.lower() not in ["vmware", "xenserver"]:
             self.virtual_machine_1.stop(self.apiclient)
 
+        volumePool = StoragePool.list(
+            self.apiclient,
+            id=vol.storageid
+        )
+        self.debug("Volume %s is on storage: %s" % (vol.id, volumePool))
+        allStoragePools = StoragePool.list(
+            self.apiclient
+        )
+        self.debug("All storage pools in the system: %s" % (allStoragePools))
         # Check migration options for volume
         pools_response = StoragePool.listForMigration(
             self.apiclient,
             id=vol.id
         )
-        pools_suitable = filter(lambda p : p.suitableformigration, pools_response)
+        pools_suitable = filter(lambda p: p.suitableformigration, pools_response)
+
+        self.debug("Suitable storage pools found: %s" % len(pools_suitable))
         self.assertEquals(1, len(pools_suitable), "Check that there is only one item on the list")
         self.assertEquals(pools_suitable[0].id, storage_pool_2.id, "Check that PS-2 is the migration option for volume")
-        
+
         # Update PS-2 Storage Tags
         StoragePool.update(
             self.apiclient,
             id=storage_pool_2.id,
             tags=self.services["storage_tags"]["b"]
         )
-        
+
         # Check migration options for volume after updating PS-2 Storage Tags
         pools_response = StoragePool.listForMigration(
             self.apiclient,
             id=vol.id
         )
-        pools_suitable = filter(lambda p : p.suitableformigration, pools_response)
+        pools_suitable = filter(lambda p: p.suitableformigration, pools_response)
+
+        self.debug("Suitable storage pools found: %s" % len(pools_suitable))
         self.assertEquals(0, len(pools_suitable), "Check that there is no migration option for volume")
-        
-        return
\ No newline at end of file
+
+        return
diff --git a/test/integration/smoke/test_public_ip_range.py b/test/integration/smoke/test_public_ip_range.py
index 92b35ad..40bc098 100644
--- a/test/integration/smoke/test_public_ip_range.py
+++ b/test/integration/smoke/test_public_ip_range.py
@@ -297,6 +297,12 @@
             "Check whether System VM Public IP is in range dedicated to system vms"
         )
 
+        # Disable Zone to be sure System VMs will not get recreated between calls
+        cmd = updateZone.updateZoneCmd()
+        cmd.id = self.zone.id
+        cmd.allocationstate = 'Disabled'
+        self.apiclient.updateZone(cmd)
+
         # Delete System VM and IP range, so System VM can get IP from original ranges
         self.debug("Destroying System VM: %s" % systemvm_id)
         cmd = destroySystemVm.destroySystemVmCmd()
@@ -306,6 +312,12 @@
         domain_id = public_ip_range.vlan.domainid
         public_ip_range.delete(self.apiclient)
 
+        # Enable Zone
+        cmd = updateZone.updateZoneCmd()
+        cmd.id = self.zone.id
+        cmd.allocationstate = 'Enabled'
+        self.apiclient.updateZone(cmd)
+
         # Wait for System VM to start and check System VM public IP
         systemvm_id = self.wait_for_system_vm_start(
             domain_id,
@@ -353,10 +365,14 @@
             "vlan":self.services["vlan"]
         }
 
-        self.base_system_vm(
-            services,
-            'secondarystoragevm'
-        )
+        try:
+            self.base_system_vm(
+                services,
+                'secondarystoragevm'
+            )
+        except Exception:
+            self.delete_range()
+
         return
 
     @attr(tags = ["advanced", "publiciprange", "dedicate", "release"], required_hardware="false")
@@ -377,8 +393,45 @@
             "vlan":self.services["vlan"]
         }
 
-        self.base_system_vm(
-            services,
-            'consoleproxy'
-        )
+        try:
+            self.base_system_vm(
+                services,
+                'consoleproxy'
+            )
+        except Exception:
+            self.delete_range()
+
         return
+
+    def delete_range(self):
+
+        # List System VMs
+        system_vms = list_ssvms(
+            self.apiclient,
+        )
+
+        # Disable Zone to be sure System VMs will not get recreated between calls
+        cmd = updateZone.updateZoneCmd()
+        cmd.id = self.zone.id
+        cmd.allocationstate = 'Disabled'
+        self.apiclient.updateZone(cmd)
+
+        # Delete System VM and IP range, so System VM can get IP from original ranges
+        for v in system_vms:
+            self.debug("Destroying System VM: %s" % v.id)
+            cmd = destroySystemVm.destroySystemVmCmd()
+            cmd.id = v.id
+            self.apiclient.destroySystemVm(cmd)
+
+        public_ip_range = PublicIpRange.list(
+            self.apiclient,
+            forsystemvms=True
+        )
+
+        public_ip_range.delete(self.apiclient)
+
+        # Enable Zone
+        cmd = updateZone.updateZoneCmd()
+        cmd.id = self.zone.id
+        cmd.allocationstate = 'Enabled'
+        self.apiclient.updateZone(cmd)
diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py
index e4d7b40..ddd6bcf 100644
--- a/test/integration/smoke/test_scale_vm.py
+++ b/test/integration/smoke/test_scale_vm.py
@@ -159,7 +159,14 @@
         cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
         cmd.serviceofferingid = self.big_offering.id
         cmd.id = self.virtual_machine.id
-        self.apiclient.scaleVirtualMachine(cmd)
+
+        try:
+            self.apiclient.scaleVirtualMachine(cmd)
+        except Exception as e:
+            if "LicenceRestriction" in str(e):
+                self.skipTest("Your XenServer License does not allow scaling")
+            else:
+                self.fail("Scaling failed with the following exception: " + str(e))
 
         list_vm_response = VirtualMachine.list(
             self.apiclient,
diff --git a/test/integration/smoke/test_service_offerings.py b/test/integration/smoke/test_service_offerings.py
index 9d4650b..61d83b9 100644
--- a/test/integration/smoke/test_service_offerings.py
+++ b/test/integration/smoke/test_service_offerings.py
@@ -129,6 +129,73 @@
             "Check name in createServiceOffering"
         )
         return
+    @attr(
+        tags=[
+            "advanced",
+            "advancedns",
+            "smoke",
+            "basic",
+            "eip",
+            "sg"],
+        required_hardware="false")
+    def test_02_create_iops_offering(self):
+        """Test to create service io burst offering"""
+
+        # Validate the following:
+        # 1. createServiceOfferings should return a valid information
+        #    for newly created offering
+        # 2. The Cloud Database contains the valid information
+
+
+
+        svcs = self.services["service_offerings"]["tiny"]
+        kws = {}
+
+        for key in self.services["ioburst"]:
+            if str(key).startswith("bytes") or str(key).startswith("iops"):
+                kws[key] = self.services["ioburst"][key]
+            else:
+                svcs[key] = self.services["ioburst"][key]
+
+        service_offering = ServiceOffering.create(
+            self.apiclient,
+            svcs,
+            None,
+            None,
+            **kws
+        )
+        self.cleanup.append(service_offering)
+
+        self.debug(
+            "Created service offering with ID: %s" %
+            service_offering.id)
+
+        list_service_response = list_service_offering(
+            self.apiclient,
+            id=service_offering.id
+        )
+        self.assertEqual(
+            isinstance(list_service_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+
+        self.assertNotEqual(
+            len(list_service_response),
+            0,
+            "Check Service offering is created"
+        )
+
+        for key in kws:
+            k = str(key)
+            mapped = 'disk' + k[:1].upper() + k[1:]
+            self.assertEqual(
+                list_service_response[0][mapped],
+                kws[key],
+                "Check " + str(key) + " => " + str(mapped) +  " in createServiceOffering"
+            )
+
+        return
 
 
 class TestServiceOfferings(cloudstackTestCase):
diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py
index d1962c4..b7a996f 100644
--- a/test/integration/smoke/test_vm_life_cycle.py
+++ b/test/integration/smoke/test_vm_life_cycle.py
@@ -16,34 +16,40 @@
 # under the License.
 """ BVT tests for Virtual Machine Life Cycle
 """
-#Import Local Modules
+# Import Local Modules
 from marvin.cloudstackTestCase import cloudstackTestCase
 from marvin.cloudstackAPI import (recoverVirtualMachine,
                                   destroyVirtualMachine,
                                   attachIso,
                                   detachIso,
                                   provisionCertificate,
-                                  updateConfiguration)
-from marvin.lib.utils import *
-
+                                  updateConfiguration,
+                                  migrateVirtualMachine)
+from marvin.lib.utils import (cleanup_resources,
+                              validateList,
+                              SshClient)
 from marvin.lib.base import (Account,
                              ServiceOffering,
                              VirtualMachine,
                              Host,
                              Iso,
                              Router,
-                             Configurations)
+                             Configurations,
+                             StoragePool,
+                             Volume,
+                             DiskOffering)
 from marvin.lib.common import (get_domain,
-                                get_zone,
-                                get_template,
+                               get_zone,
+                               get_template,
                                list_hosts)
 from marvin.codes import FAILED, PASS
 from nose.plugins.attrib import attr
-#Import System modules
+# Import System modules
 import time
-import re
 
 _multiprocess_shared_ = True
+
+
 class TestDeployVM(cloudstackTestCase):
 
     @classmethod
@@ -57,8 +63,8 @@
         cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
         cls.services['mode'] = cls.zone.networktype
 
-        #If local storage is enabled, alter the offerings to use localstorage
-        #this step is needed for devcloud
+        # If local storage is enabled, alter the offerings to use localstorage
+        # this step is needed for devcloud
         if cls.zone.localstorageenabled == True:
             cls.services["service_offerings"]["tiny"]["storagetype"] = 'local'
             cls.services["service_offerings"]["small"]["storagetype"] = 'local'
@@ -116,8 +122,7 @@
         self.dbclient = self.testClient.getDbConnection()
         self.cleanup = []
 
-
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_deploy_vm(self):
         """Test Deploy Virtual Machine
         """
@@ -125,47 +130,46 @@
         # 1. Virtual Machine is accessible via SSH
         # 2. listVirtualMachines returns accurate information
         list_vm_response = VirtualMachine.list(
-                                                 self.apiclient,
-                                                 id=self.virtual_machine.id
-                                                 )
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
 
         self.debug(
-                "Verify listVirtualMachines response for virtual machine: %s" \
-                % self.virtual_machine.id
-            )
+            "Verify listVirtualMachines response for virtual machine: %s" \
+            % self.virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM available in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM available in List Virtual Machines"
+        )
         vm_response = list_vm_response[0]
         self.assertEqual(
 
-                            vm_response.id,
-                            self.virtual_machine.id,
-                            "Check virtual machine id in listVirtualMachines"
-                        )
+            vm_response.id,
+            self.virtual_machine.id,
+            "Check virtual machine id in listVirtualMachines"
+        )
         self.assertEqual(
-                    vm_response.name,
-                    self.virtual_machine.name,
-                    "Check virtual machine name in listVirtualMachines"
-                    )
+            vm_response.name,
+            self.virtual_machine.name,
+            "Check virtual machine name in listVirtualMachines"
+        )
         self.assertEqual(
             vm_response.state,
             'Running',
-             msg="VM is not in Running state"
+            msg="VM is not in Running state"
         )
         return
 
-
-    @attr(tags = ["advanced"], required_hardware="false")
+    @attr(tags=["advanced"], required_hardware="false")
     def test_advZoneVirtualRouter(self):
-        #TODO: SIMENH: duplicate test, remove it
+        # TODO: SIMENH: duplicate test, remove it
         """
         Test advanced zone virtual router
         1. Is Running
@@ -174,21 +178,20 @@
         @return:
         """
         routers = Router.list(self.apiclient, account=self.account.name)
-        self.assertTrue(len(routers) > 0, msg = "No virtual router found")
+        self.assertTrue(len(routers) > 0, msg="No virtual router found")
         router = routers[0]
 
         self.assertEqual(router.state, 'Running', msg="Router is not in running state")
         self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
 
-        #Has linklocal, public and guest ips
+        # Has linklocal, public and guest ips
         self.assertIsNotNone(router.linklocalip, msg="Router has no linklocal ip")
         self.assertIsNotNone(router.publicip, msg="Router has no public ip")
         self.assertIsNotNone(router.guestipaddress, msg="Router has no guest ip")
 
-
-    @attr(mode = ["basic"], required_hardware="false")
+    @attr(mode=["basic"], required_hardware="false")
     def test_basicZoneVirtualRouter(self):
-        #TODO: SIMENH: duplicate test, remove it
+        # TODO: SIMENH: duplicate test, remove it
         """
         Tests for basic zone virtual router
         1. Is Running
@@ -196,13 +199,13 @@
         @return:
         """
         routers = Router.list(self.apiclient, account=self.account.name)
-        self.assertTrue(len(routers) > 0, msg = "No virtual router found")
+        self.assertTrue(len(routers) > 0, msg="No virtual router found")
         router = routers[0]
 
         self.assertEqual(router.state, 'Running', msg="Router is not in running state")
         self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
 
-    @attr(tags = ['advanced','basic','sg'], required_hardware="false")
+    @attr(tags=['advanced', 'basic', 'sg'], required_hardware="false")
     def test_deploy_vm_multiple(self):
         """Test Multiple Deploy Virtual Machine
 
@@ -234,7 +237,8 @@
 
         list_vms = VirtualMachine.list(self.apiclient, ids=[virtual_machine1.id, virtual_machine2.id], listAll=True)
         self.debug(
-            "Verify listVirtualMachines response for virtual machines: %s, %s" % (virtual_machine1.id, virtual_machine2.id)
+            "Verify listVirtualMachines response for virtual machines: %s, %s" % (
+                virtual_machine1.id, virtual_machine2.id)
         )
         self.assertEqual(
             isinstance(list_vms, list),
@@ -269,18 +273,18 @@
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.services['mode'] = cls.zone.networktype
 
-        #if local storage is enabled, alter the offerings to use localstorage
-        #this step is needed for devcloud
+        # if local storage is enabled, alter the offerings to use localstorage
+        # this step is needed for devcloud
         if cls.zone.localstorageenabled == True:
             cls.services["service_offerings"]["tiny"]["storagetype"] = 'local'
             cls.services["service_offerings"]["small"]["storagetype"] = 'local'
             cls.services["service_offerings"]["medium"]["storagetype"] = 'local'
 
         template = get_template(
-                            cls.apiclient,
-                            cls.zone.id,
-                            cls.services["ostype"]
-                            )
+            cls.apiclient,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
         if template == FAILED:
             assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
 
@@ -292,50 +296,50 @@
 
         # Create VMs, NAT Rules etc
         cls.account = Account.create(
-                            cls.apiclient,
-                            cls.services["account"],
-                            domainid=domain.id
-                            )
+            cls.apiclient,
+            cls.services["account"],
+            domainid=domain.id
+        )
 
         cls.small_offering = ServiceOffering.create(
-                                    cls.apiclient,
-                                    cls.services["service_offerings"]["small"]
-                                    )
+            cls.apiclient,
+            cls.services["service_offerings"]["small"]
+        )
 
         cls.medium_offering = ServiceOffering.create(
-                                    cls.apiclient,
-                                    cls.services["service_offerings"]["medium"]
-                                    )
-        #create small and large virtual machines
+            cls.apiclient,
+            cls.services["service_offerings"]["medium"]
+        )
+        # create small and large virtual machines
         cls.small_virtual_machine = VirtualMachine.create(
-                                        cls.apiclient,
-                                        cls.services["small"],
-                                        accountid=cls.account.name,
-                                        domainid=cls.account.domainid,
-                                        serviceofferingid=cls.small_offering.id,
-                                        mode=cls.services["mode"]
-                                        )
+            cls.apiclient,
+            cls.services["small"],
+            accountid=cls.account.name,
+            domainid=cls.account.domainid,
+            serviceofferingid=cls.small_offering.id,
+            mode=cls.services["mode"]
+        )
         cls.medium_virtual_machine = VirtualMachine.create(
-                                       cls.apiclient,
-                                       cls.services["small"],
-                                       accountid=cls.account.name,
-                                       domainid=cls.account.domainid,
-                                       serviceofferingid=cls.medium_offering.id,
-                                       mode=cls.services["mode"]
-                                    )
+            cls.apiclient,
+            cls.services["small"],
+            accountid=cls.account.name,
+            domainid=cls.account.domainid,
+            serviceofferingid=cls.medium_offering.id,
+            mode=cls.services["mode"]
+        )
         cls.virtual_machine = VirtualMachine.create(
-                                        cls.apiclient,
-                                        cls.services["small"],
-                                        accountid=cls.account.name,
-                                        domainid=cls.account.domainid,
-                                        serviceofferingid=cls.small_offering.id,
-                                        mode=cls.services["mode"]
-                                        )
+            cls.apiclient,
+            cls.services["small"],
+            accountid=cls.account.name,
+            domainid=cls.account.domainid,
+            serviceofferingid=cls.small_offering.id,
+            mode=cls.services["mode"]
+        )
         cls._cleanup = [
-                        cls.small_offering,
-                        cls.medium_offering,
-                        cls.account
-                        ]
+            cls.small_offering,
+            cls.medium_offering,
+            cls.account
+        ]
 
     @classmethod
     def tearDownClass(cls):
@@ -353,14 +357,13 @@
 
     def tearDown(self):
         try:
-            #Clean up, terminate the created ISOs
+            # Clean up, terminate the created ISOs
             cleanup_resources(self.apiclient, self.cleanup)
         except Exception as e:
             raise Exception("Warning: Exception during cleanup : %s" % e)
         return
 
-
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_01_stop_vm(self):
         """Test Stop Virtual Machine
         """
@@ -375,8 +378,7 @@
             self.fail("Failed to stop VM: %s" % e)
         return
 
-
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_01_stop_vm_forced(self):
         """Test Force Stop Virtual Machine
         """
@@ -386,30 +388,29 @@
             self.fail("Failed to stop VM: %s" % e)
 
         list_vm_response = VirtualMachine.list(
-                                            self.apiclient,
-                                            id=self.small_virtual_machine.id
-                                            )
+            self.apiclient,
+            id=self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM avaliable in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM avaliable in List Virtual Machines"
+        )
 
         self.assertEqual(
-                            list_vm_response[0].state,
-                            "Stopped",
-                            "Check virtual machine is in stopped state"
-                        )
+            list_vm_response[0].state,
+            "Stopped",
+            "Check virtual machine is in stopped state"
+        )
         return
 
-
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_02_start_vm(self):
         """Test Start Virtual Machine
         """
@@ -421,33 +422,33 @@
         self.small_virtual_machine.start(self.apiclient)
 
         list_vm_response = VirtualMachine.list(
-                                            self.apiclient,
-                                            id=self.small_virtual_machine.id
-                                            )
+            self.apiclient,
+            id=self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM avaliable in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM avaliable in List Virtual Machines"
+        )
 
         self.debug(
-                "Verify listVirtualMachines response for virtual machine: %s" \
-                % self.small_virtual_machine.id
-                )
+            "Verify listVirtualMachines response for virtual machine: %s" \
+            % self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            list_vm_response[0].state,
-                            "Running",
-                            "Check virtual machine is in running state"
-                        )
+            list_vm_response[0].state,
+            "Running",
+            "Check virtual machine is in running state"
+        )
         return
 
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_03_reboot_vm(self):
         """Test Reboot Virtual Machine
         """
@@ -461,30 +462,29 @@
         self.small_virtual_machine.reboot(self.apiclient)
 
         list_vm_response = VirtualMachine.list(
-                                            self.apiclient,
-                                            id=self.small_virtual_machine.id
-                                            )
+            self.apiclient,
+            id=self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM avaliable in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM available in List Virtual Machines"
+        )
 
         self.assertEqual(
-                            list_vm_response[0].state,
-                            "Running",
-                            "Check virtual machine is in running state"
-                        )
+            list_vm_response[0].state,
+            "Running",
+            "Check virtual machine is in running state"
+        )
         return
 
-
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_06_destroy_vm(self):
         """Test destroy Virtual Machine
         """
@@ -498,31 +498,31 @@
         self.small_virtual_machine.delete(self.apiclient, expunge=False)
 
         list_vm_response = VirtualMachine.list(
-                                            self.apiclient,
-                                            id=self.small_virtual_machine.id
-                                            )
+            self.apiclient,
+            id=self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM avaliable in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM avaliable in List Virtual Machines"
+        )
 
         self.assertEqual(
-                            list_vm_response[0].state,
-                            "Destroyed",
-                            "Check virtual machine is in destroyed state"
-                        )
+            list_vm_response[0].state,
+            "Destroyed",
+            "Check virtual machine is in destroyed state"
+        )
         return
 
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_07_restore_vm(self):
-        #TODO: SIMENH: add another test the data on the restored VM.
+        # TODO: SIMENH: add another test the data on the restored VM.
         """Test recover Virtual Machine
         """
 
@@ -538,30 +538,30 @@
         self.apiclient.recoverVirtualMachine(cmd)
 
         list_vm_response = VirtualMachine.list(
-                                            self.apiclient,
-                                            id=self.small_virtual_machine.id
-                                            )
+            self.apiclient,
+            id=self.small_virtual_machine.id
+        )
         self.assertEqual(
-                            isinstance(list_vm_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         self.assertNotEqual(
-                            len(list_vm_response),
-                            0,
-                            "Check VM avaliable in List Virtual Machines"
-                        )
+            len(list_vm_response),
+            0,
+            "Check VM avaliable in List Virtual Machines"
+        )
 
         self.assertEqual(
-                            list_vm_response[0].state,
-                            "Stopped",
-                            "Check virtual machine is in Stopped state"
-                        )
+            list_vm_response[0].state,
+            "Stopped",
+            "Check virtual machine is in Stopped state"
+        )
 
         return
 
-    @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false")
+    @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false")
     def test_08_migrate_vm(self):
         """Test migrate VM
         """
@@ -589,10 +589,10 @@
         # For XenServer and VMware, migration is possible between hosts belonging to different clusters
         # with the help of XenMotion and Vmotion respectively.
 
-        if self.hypervisor.lower() in ["kvm","simulator"]:
-            #identify suitable host
+        if self.hypervisor.lower() in ["kvm", "simulator"]:
+            # identify suitable host
             clusters = [h.clusterid for h in hosts]
-            #find hosts withe same clusterid
+            # find hosts withe same clusterid
             clusters = [cluster for index, cluster in enumerate(clusters) if clusters.count(cluster) > 1]
 
             if len(clusters) <= 1:
@@ -605,8 +605,8 @@
         target_host = suitable_hosts[0]
         migrate_host = suitable_hosts[1]
 
-        #deploy VM on target host
-        self.vm_to_migrate = VirtualMachine.create(
+        # deploy VM on target host
+        vm_to_migrate = VirtualMachine.create(
             self.apiclient,
             self.services["small"],
             accountid=self.account.name,
@@ -616,30 +616,30 @@
             hostid=target_host.id
         )
         self.debug("Migrating VM-ID: %s to Host: %s" % (
-                                        self.vm_to_migrate.id,
-                                        migrate_host.id
-                                        ))
+            vm_to_migrate.id,
+            migrate_host.id
+        ))
 
-        self.vm_to_migrate.migrate(self.apiclient, migrate_host.id)
+        vm_to_migrate.migrate(self.apiclient, migrate_host.id)
 
         retries_cnt = 3
-        while retries_cnt >=0:
+        while retries_cnt >= 0:
             list_vm_response = VirtualMachine.list(self.apiclient,
-                                                   id=self.vm_to_migrate.id)
+                                                   id=vm_to_migrate.id)
             self.assertNotEqual(
-                                list_vm_response,
-                                None,
-                                "Check virtual machine is listed"
-                               )
+                list_vm_response,
+                None,
+                "Check virtual machine is listed"
+            )
             vm_response = list_vm_response[0]
-            self.assertEqual(vm_response.id,self.vm_to_migrate.id,"Check virtual machine ID of migrated VM")
-            self.assertEqual(vm_response.hostid,migrate_host.id,"Check destination hostID of migrated VM")
+            self.assertEqual(vm_response.id, vm_to_migrate.id, "Check virtual machine ID of migrated VM")
+            self.assertEqual(vm_response.hostid, migrate_host.id, "Check destination hostID of migrated VM")
             retries_cnt = retries_cnt - 1
         return
 
-    @attr(configuration = "expunge.interval")
-    @attr(configuration = "expunge.delay")
-    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    @attr(configuration="expunge.interval")
+    @attr(configuration="expunge.delay")
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
     def test_09_expunge_vm(self):
         """Test destroy(expunge) Virtual Machine
         """
@@ -653,26 +653,26 @@
         self.apiclient.destroyVirtualMachine(cmd)
 
         config = Configurations.list(
-                                     self.apiclient,
-                                     name='expunge.delay'
-                                     )
+            self.apiclient,
+            name='expunge.delay'
+        )
 
         expunge_delay = int(config[0].value)
         time.sleep(expunge_delay * 2)
 
-        #VM should be destroyed unless expunge thread hasn't run
-        #Wait for two cycles of the expunge thread
+        # VM should be destroyed unless expunge thread hasn't run
+        # Wait for two cycles of the expunge thread
         config = Configurations.list(
-                                     self.apiclient,
-                                     name='expunge.interval'
-                                     )
+            self.apiclient,
+            name='expunge.interval'
+        )
         expunge_cycle = int(config[0].value)
         wait_time = expunge_cycle * 4
         while wait_time >= 0:
             list_vm_response = VirtualMachine.list(
-                                                self.apiclient,
-                                                id=self.small_virtual_machine.id
-                                                )
+                self.apiclient,
+                id=self.small_virtual_machine.id
+            )
             if not list_vm_response:
                 break
             self.debug("Waiting for VM to expunge")
@@ -681,10 +681,10 @@
 
         self.debug("listVirtualMachines response: %s" % list_vm_response)
 
-        self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response")
+        self.assertEqual(list_vm_response, None, "Check Expunged virtual machine is in listVirtualMachines response")
         return
 
-    @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true")
+    @attr(tags=["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true")
     def test_10_attachAndDetach_iso(self):
         """Test for attach and detach ISO to virtual machine"""
 
@@ -700,24 +700,24 @@
             self.skipTest("ISOs are not supported on LXC")
 
         iso = Iso.create(
-                         self.apiclient,
-                         self.services["iso1"],
-                         account=self.account.name,
-                         domainid=self.account.domainid
-                         )
+            self.apiclient,
+            self.services["iso1"],
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
 
         self.debug("Successfully created ISO with ID: %s" % iso.id)
         try:
             iso.download(self.apiclient)
         except Exception as e:
-            self.fail("Exception while downloading ISO %s: %s"\
+            self.fail("Exception while downloading ISO %s: %s" \
                       % (iso.id, e))
 
         self.debug("Attach ISO with ID: %s to VM ID: %s" % (
-                                                    iso.id,
-                                                    self.virtual_machine.id
-                                                    ))
-        #Attach ISO to virtual machine
+            iso.id,
+            self.virtual_machine.id
+        ))
+        # Attach ISO to virtual machine
         cmd = attachIso.attachIsoCmd()
         cmd.id = iso.id
         cmd.virtualmachineid = self.virtual_machine.id
@@ -727,7 +727,7 @@
             ssh_client = self.virtual_machine.get_ssh_client()
         except Exception as e:
             self.fail("SSH failed for virtual machine: %s - %s" %
-                                (self.virtual_machine.ipaddress, e))
+                      (self.virtual_machine.ipaddress, e))
 
         mount_dir = "/mnt/tmp"
         cmds = "mkdir -p %s" % mount_dir
@@ -748,24 +748,24 @@
 
         # Get ISO size
         iso_response = Iso.list(
-                                 self.apiclient,
-                                 id=iso.id
-                                 )
+            self.apiclient,
+            id=iso.id
+        )
         self.assertEqual(
-                            isinstance(iso_response, list),
-                            True,
-                            "Check list response returns a valid list"
-                        )
+            isinstance(iso_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
 
         try:
-            #Unmount ISO
+            # Unmount ISO
             command = "umount %s" % mount_dir
             ssh_client.execute(command)
         except Exception as e:
             self.fail("SSH failed for virtual machine: %s - %s" %
-                                (self.virtual_machine.ipaddress, e))
+                      (self.virtual_machine.ipaddress, e))
 
-        #Detach from VM
+        # Detach from VM
         cmd = detachIso.detachIsoCmd()
         cmd.virtualmachineid = self.virtual_machine.id
         self.apiclient.detachIso(cmd)
@@ -774,18 +774,56 @@
             res = ssh_client.execute(c)
         except Exception as e:
             self.fail("SSH failed for virtual machine: %s - %s" %
-                                (self.virtual_machine.ipaddress, e))
+                      (self.virtual_machine.ipaddress, e))
 
         # Check if ISO is properly detached from VM (using fdisk)
         result = self.services["mount"] in str(res)
 
         self.assertEqual(
-                         result,
-                         False,
-                         "Check if ISO is detached from virtual machine"
-                         )
+            result,
+            False,
+            "Check if ISO is detached from virtual machine"
+        )
         return
 
+    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
+    def test_11_destroy_vm_and_volumes(self):
+        """Test destroy Virtual Machine and it's volumes
+        """
+
+        # Validate the following
+        # 1. Deploys a VM and attaches disks to it
+        # 2. Destroys the VM with DataDisks option
+
+        small_disk_offering = DiskOffering.list(self.apiclient, name='Small')[0]
+
+        small_virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.small_offering.id,
+            mode=self.services["mode"]
+        )
+        vol1 = Volume.create(
+            self.apiclient,
+            self.services,
+            account=self.account.name,
+            diskofferingid=small_disk_offering.id,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id
+        )
+
+        small_virtual_machine.attach_volume(self.apiclient, vol1)
+
+        self.debug("Destroy VM - ID: %s" % small_virtual_machine.id)
+        small_virtual_machine.delete(self.apiclient, volumeIds=vol1.id)
+
+        self.assertEqual(VirtualMachine.list(self.apiclient, id=small_virtual_machine.id), None, "List response contains records when it should not")
+
+        self.assertEqual(Volume.list(self.apiclient, id=vol1.id), None, "List response contains records when it should not")
+
+
 class TestSecuredVmMigration(cloudstackTestCase):
 
     @classmethod
@@ -803,14 +841,15 @@
         domain = get_domain(cls.apiclient)
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.services['mode'] = cls.zone.networktype
-        cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
+        cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][
+            0].__dict__
         cls.management_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
 
         template = get_template(
-                            cls.apiclient,
-                            cls.zone.id,
-                            cls.services["ostype"]
-                            )
+            cls.apiclient,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
         if template == FAILED:
             assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
 
@@ -822,20 +861,20 @@
 
         # Create VMs, NAT Rules etc
         cls.account = Account.create(
-                            cls.apiclient,
-                            cls.services["account"],
-                            domainid=domain.id
-                            )
+            cls.apiclient,
+            cls.services["account"],
+            domainid=domain.id
+        )
 
         cls.small_offering = ServiceOffering.create(
-                                    cls.apiclient,
-                                    cls.services["service_offerings"]["small"]
-                                    )
+            cls.apiclient,
+            cls.services["service_offerings"]["small"]
+        )
 
         cls._cleanup = [
-                        cls.small_offering,
-                        cls.account
-                        ]
+            cls.small_offering,
+            cls.account
+        ]
 
     @classmethod
     def tearDownClass(cls):
@@ -877,19 +916,20 @@
         target_hosts = Host.listForMigration(self.apiclient,
                                              virtualmachineid=virtualmachineid)
         for host in target_hosts:
-            h = list_hosts(self.apiclient,type='Routing', id=host.id)[0]
+            h = list_hosts(self.apiclient, type='Routing', id=host.id)[0]
             if h.details.secured == secured:
                 return h
 
         cloudstackTestCase.skipTest(self, "No target hosts available, skipping test.")
 
     def check_migration_protocol(self, protocol, host):
-        resp = SshClient(host.ipaddress, port=22, user=self.hostConfig["username"],passwd=self.hostConfig["password"])\
+        resp = SshClient(host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]) \
             .execute("grep -a listen_%s=1 /etc/libvirt/libvirtd.conf | tail -1" % protocol)
 
         if protocol not in resp[0]:
             cloudstackTestCase.fail(self, "Libvirt listen protocol expected: '" + protocol + "\n"
-                                    "does not match actual: " + resp[0])
+                                                                                             "does not match actual: " +
+                                    resp[0])
 
     def migrate_and_check(self, vm, src_host, dest_host, proto='tls'):
         """
@@ -918,7 +958,7 @@
                 return
 
     def unsecure_host(self, host):
-        SshClient(host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"])\
+        SshClient(host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]) \
             .execute("rm -f /etc/cloudstack/agent/cloud* && \
                       sed -i 's/listen_tls.*/listen_tls=0/g' /etc/libvirt/libvirtd.conf && \
                       sed -i 's/listen_tcp.*/listen_tcp=1/g' /etc/libvirt/libvirtd.conf && \
@@ -1033,7 +1073,8 @@
             self.migrate_and_check(vm, secure_host, unsecure_host, proto='tls')
         except Exception:
             pass
-        else: self.fail("Migration succeeded, instead it should fail")
+        else:
+            self.fail("Migration succeeded, instead it should fail")
 
     @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false")
     def test_04_nonsecured_to_secured_vm_migration(self):
@@ -1054,5 +1095,217 @@
             self.migrate_and_check(vm, unsecure_host, secure_host, proto='tcp')
         except Exception:
             pass
-        else: self.fail("Migration succeeded, instead it should fail")
+        else:
+            self.fail("Migration succeeded, instead it should fail")
 
+
+class TestMigrateVMwithVolume(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        testClient = super(TestMigrateVMwithVolume, cls).getClsTestClient()
+        cls.apiclient = testClient.getApiClient()
+        cls.services = testClient.getParsedTestDataConfig()
+        cls.hypervisor = testClient.getHypervisorInfo()
+        cls._cleanup = []
+
+        # Get Zone, Domain and templates
+        domain = get_domain(cls.apiclient)
+        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][
+            0].__dict__
+        cls.management_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
+
+        template = get_template(
+            cls.apiclient,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
+        if template == FAILED:
+            assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
+
+        # Set Zones and disk offerings
+        cls.services["small"]["zoneid"] = cls.zone.id
+        cls.services["small"]["template"] = template.id
+
+        cls.services["iso1"]["zoneid"] = cls.zone.id
+
+        # Create VMs, NAT Rules etc
+        cls.account = Account.create(
+            cls.apiclient,
+            cls.services["account"],
+            domainid=domain.id
+        )
+
+        cls.small_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.services["service_offerings"]["small"]
+        )
+
+        cls._cleanup = [
+            cls.small_offering,
+            cls.account
+        ]
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.apiclient = super(TestMigrateVMwithVolume, cls).getClsTestClient().getApiClient()
+        try:
+            cleanup_resources(cls.apiclient, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+
+        if self.hypervisor.lower() not in ["vmware"]:
+            self.skipTest("VM Migration with Volumes is not supported on other than VMware")
+
+            self.hosts = Host.list(
+                self.apiclient,
+                zoneid=self.zone.id,
+                type='Routing',
+                hypervisor='KVM')
+
+            if len(self.hosts) < 2:
+                self.skipTest("Requires at least two hosts for performing migration related tests")
+
+    def tearDown(self):
+        try:
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+
+    def get_target_host(self, virtualmachineid):
+        target_hosts = Host.listForMigration(self.apiclient,
+                                             virtualmachineid=virtualmachineid)[0]
+        if len(target_hosts) < 1:
+            self.skipTest("No target hosts found")
+
+        return target_hosts[0]
+
+    def get_target_pool(self, volid):
+        target_pools = StoragePool.listForMigration(self.apiclient, id=volid)
+
+        if len(target_pools) < 1:
+            self.skipTest("Not enough storage pools found")
+
+        return target_pools[0]
+
+    def get_vm_volumes(self, id):
+        return Volume.list(self.apiclient, virtualmachineid=id, listall=True)
+
+    def deploy_vm(self):
+        return VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.small_offering.id,
+            mode=self.services["mode"])
+
+    def migrate_vm_with_pools(self, target_pool, id):
+        cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
+
+        cmd.storageid = target_pool.id
+        cmd.virtualmachineid = id
+
+        return self.apiclient.migrateVirtualMachine(cmd)
+
+    def create_volume(self):
+        small_disk_offering = DiskOffering.list(self.apiclient, name='Small')[0]
+
+        return Volume.create(
+            self.apiclient,
+            self.services,
+            account=self.account.name,
+            diskofferingid=small_disk_offering.id,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id
+        )
+
+    """
+    BVT for Vmware Offline VM and Volume Migration
+    """
+
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false")
+    def test_01_migrate_VM_and_root_volume(self):
+        """Test VM will be migrated with it's root volume"""
+        # Validate the following
+        # 1. Deploys a VM
+        # 2. Finds suitable host for migration
+        # 3. Finds suitable storage pool for root volume
+        # 4. Migrate the VM to new host and storage pool and assert migration successful
+
+        vm = self.deploy_vm()
+
+        root_volume = self.get_vm_volumes(vm.id)[0]
+
+        target_pool = self.get_target_pool(root_volume.id)
+
+        vm.stop(self.apiclient)
+
+        self.migrate_vm_with_pools(target_pool, vm.id)
+
+        root_volume = self.get_vm_volumes(vm.id)[0]
+        self.assertEqual(root_volume.storageid, target_pool.id, "Pool ID was not as expected")
+
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false")
+    def test_02_migrate_VM_with_two_data_disks(self):
+        """Test VM will be migrated with it's root volume"""
+        # Validate the following
+        # 1. Deploys a VM and attaches 2 data disks
+        # 2. Finds suitable host for migration
+        # 3. Finds suitable storage pool for volumes
+        # 4. Migrate the VM to new host and storage pool and assert migration successful
+
+        vm = self.deploy_vm()
+
+        volume1 = self.create_volume()
+        volume2 = self.create_volume()
+
+        vm.attach_volume(self.apiclient, volume1)
+        vm.attach_volume(self.apiclient, volume2)
+
+        root_volume = self.get_vm_volumes(vm.id)[0]
+
+        target_pool = self.get_target_pool(root_volume.id)
+
+        vm.stop(self.apiclient)
+
+        self.migrate_vm_with_pools(target_pool, vm.id)
+
+        volume1 = Volume.list(self.apiclient, id=volume1.id)[0]
+        volume2 = Volume.list(self.apiclient, id=volume2.id)[0]
+        root_volume = self.get_vm_volumes(vm.id)[0]
+
+        self.assertEqual(root_volume.storageid, target_pool.id, "Pool ID was not as expected")
+        self.assertEqual(volume1.storageid, target_pool.id, "Pool ID was not as expected")
+        self.assertEqual(volume2.storageid, target_pool.id, "Pool ID was not as expected")
+
+    @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false")
+    def test_03_migrate_detached_volume(self):
+        """Test VM will be migrated with it's root volume"""
+        # Validate the following
+        # 1. Deploys a VM and attaches 1 data disk
+        # 2. Detaches the Disk
+        # 3. Finds suitable storage pool for the Disk
+        # 4. Migrate the storage pool and assert migration successful
+
+        vm = self.deploy_vm()
+
+        volume1 = self.create_volume()
+
+        vm.attach_volume(self.apiclient, volume1)
+        vm.detach_volume(self.apiclient, volume1)
+
+        target_pool = self.get_target_pool(volume1.id)
+
+        Volume.migrate(self.apiclient, storageid=target_pool.id, volumeid=volume1.id)
+
+        vol = Volume.list(self.apiclient, volume=volume1.id)[0]
+
+        self.assertEqual(vol.storageid, target_pool.id, "Storage pool was not the same as expected")
diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py
index c71411a..17f8547 100644
--- a/test/integration/smoke/test_volumes.py
+++ b/test/integration/smoke/test_volumes.py
@@ -37,7 +37,8 @@
                                 get_zone,
                                 get_template,
                                 find_storage_pool_type,
-                                get_pod)
+                                get_pod,
+                                list_disk_offering)
 from marvin.lib.utils import checkVolumeSize
 from marvin.codes import SUCCESS, FAILED, XEN_SERVER
 from nose.plugins.attrib import attr
@@ -929,3 +930,80 @@
         if not res:
             self.fail("Failed to return root volume response")
         return response
+
+
+    @attr(tags=["advanced", "advancedns", "smoke", "basic"], required_hardware="true")
+    def test_11_migrate_volume_and_change_offering(self):
+
+    # Validates the following
+    #
+    # 1. Creates a new Volume with a small disk offering
+    #
+    # 2. Migrates the Volume to another primary storage and changes the offering
+    #
+    # 3. Verifies the Volume has new offering when migrated to the new storage.
+
+        small_offering = list_disk_offering(
+            self.apiclient,
+            name = "Small"
+        )[0]
+
+        large_offering = list_disk_offering(
+            self.apiclient,
+            name = "Large"
+        )[0]
+        volume = Volume.create(
+            self.apiClient,
+            self.services,
+            zoneid = self.zone.id,
+            account = self.account.name,
+            domainid = self.account.domainid,
+            diskofferingid = small_offering.id
+        )
+        self.debug("Created a small volume: %s" % volume.id)
+
+        self.virtual_machine.attach_volume(self.apiclient, volume=volume)
+
+        if self.virtual_machine.hypervisor == "KVM":
+            self.virtual_machine.stop(self.apiclient)
+
+        pools = StoragePool.listForMigration(
+            self.apiclient,
+            id=volume.id
+            )
+
+        pool = None
+
+        if pools and len(pools) > 0:
+            pool = pools[0]
+        else:
+            raise self.skipTest("Not enough storage pools found, skipping test")
+        
+        if hasattr(pool, 'tags'):
+            StoragePool.update(self.apiclient, id=pool.id, tags="")
+
+        self.debug("Migrating Volume-ID: %s to Pool: %s" % (volume.id, pool.id))
+        livemigrate = False
+        if self.virtual_machine.hypervisor.lower() == "vmware" or self.virtual_machine.hypervisor.lower() == 'xenserver':
+            livemigrate = True
+
+        Volume.migrate(
+            self.apiclient,
+            volumeid = volume.id,
+            storageid = pool.id,
+            newdiskofferingid = large_offering.id,
+            livemigrate = livemigrate
+        )
+        if self.virtual_machine.hypervisor == "KVM":
+            self.virtual_machine.start(self.apiclient
+        )
+        migrated_vol = Volume.list(
+            self.apiclient,
+            id = volume.id
+        )[0]
+        self.assertEqual(
+            migrated_vol.diskofferingname,
+            large_offering.name,
+            "Offering name did not match with the new one "
+        )
+        return
diff --git a/test/pom.xml b/test/pom.xml
index 2fff029..c9c792b 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -1,29 +1,30 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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">
+<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-testclient</artifactId>
     <name>Apache CloudStack Test</name>
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
     </parent>
     <dependencies>
         <dependency>
@@ -34,16 +35,11 @@
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
-            </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>${cs.junit.version}</version>
         </dependency>
         <dependency>
             <groupId>com.trilead</groupId>
             <artifactId>trilead-ssh2</artifactId>
-            </dependency>
+        </dependency>
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>apache-log4j-extras</artifactId>
@@ -62,13 +58,11 @@
         <dependency>
             <groupId>org.seleniumhq.selenium.client-drivers</groupId>
             <artifactId>selenium-java-client-driver</artifactId>
-            <version>1.0.1</version>
+            <version>${cs.selenium-java-client-driver.version}</version>
         </dependency>
     </dependencies>
     <build>
         <defaultGoal>compile</defaultGoal>
-        <sourceDirectory>test</sourceDirectory>
-        <testSourceDirectory>test</testSourceDirectory>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/test/src/com/cloud/sample/UserCloudAPIExecutor.java b/test/src-not-used/main/java/com/cloud/sample/UserCloudAPIExecutor.java
similarity index 100%
rename from test/src/com/cloud/sample/UserCloudAPIExecutor.java
rename to test/src-not-used/main/java/com/cloud/sample/UserCloudAPIExecutor.java
diff --git a/test/src/com/cloud/test/longrun/BuildGuestNetwork.java b/test/src-not-used/main/java/com/cloud/test/longrun/BuildGuestNetwork.java
similarity index 100%
rename from test/src/com/cloud/test/longrun/BuildGuestNetwork.java
rename to test/src-not-used/main/java/com/cloud/test/longrun/BuildGuestNetwork.java
diff --git a/test/src/com/cloud/test/longrun/GuestNetwork.java b/test/src-not-used/main/java/com/cloud/test/longrun/GuestNetwork.java
similarity index 100%
rename from test/src/com/cloud/test/longrun/GuestNetwork.java
rename to test/src-not-used/main/java/com/cloud/test/longrun/GuestNetwork.java
diff --git a/test/src/com/cloud/test/longrun/PerformanceWithAPI.java b/test/src-not-used/main/java/com/cloud/test/longrun/PerformanceWithAPI.java
similarity index 100%
rename from test/src/com/cloud/test/longrun/PerformanceWithAPI.java
rename to test/src-not-used/main/java/com/cloud/test/longrun/PerformanceWithAPI.java
diff --git a/test/src/com/cloud/test/longrun/User.java b/test/src-not-used/main/java/com/cloud/test/longrun/User.java
similarity index 100%
rename from test/src/com/cloud/test/longrun/User.java
rename to test/src-not-used/main/java/com/cloud/test/longrun/User.java
diff --git a/test/src/com/cloud/test/longrun/VirtualMachine.java b/test/src-not-used/main/java/com/cloud/test/longrun/VirtualMachine.java
similarity index 100%
rename from test/src/com/cloud/test/longrun/VirtualMachine.java
rename to test/src-not-used/main/java/com/cloud/test/longrun/VirtualMachine.java
diff --git a/test/src/com/cloud/test/regression/ApiCommand.java b/test/src-not-used/main/java/com/cloud/test/regression/ApiCommand.java
similarity index 100%
rename from test/src/com/cloud/test/regression/ApiCommand.java
rename to test/src-not-used/main/java/com/cloud/test/regression/ApiCommand.java
diff --git a/test/src/com/cloud/test/regression/ConfigTest.java b/test/src-not-used/main/java/com/cloud/test/regression/ConfigTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/ConfigTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/ConfigTest.java
diff --git a/test/src/com/cloud/test/regression/DelegatedAdminTest.java b/test/src-not-used/main/java/com/cloud/test/regression/DelegatedAdminTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/DelegatedAdminTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/DelegatedAdminTest.java
diff --git a/test/src/com/cloud/test/regression/Deploy.java b/test/src-not-used/main/java/com/cloud/test/regression/Deploy.java
similarity index 100%
rename from test/src/com/cloud/test/regression/Deploy.java
rename to test/src-not-used/main/java/com/cloud/test/regression/Deploy.java
diff --git a/test/src/com/cloud/test/regression/EventsApiTest.java b/test/src-not-used/main/java/com/cloud/test/regression/EventsApiTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/EventsApiTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/EventsApiTest.java
diff --git a/test/src/com/cloud/test/regression/HA.java b/test/src-not-used/main/java/com/cloud/test/regression/HA.java
similarity index 100%
rename from test/src/com/cloud/test/regression/HA.java
rename to test/src-not-used/main/java/com/cloud/test/regression/HA.java
diff --git a/test/src/com/cloud/test/regression/LoadBalancingTest.java b/test/src-not-used/main/java/com/cloud/test/regression/LoadBalancingTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/LoadBalancingTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/LoadBalancingTest.java
diff --git a/test/src/com/cloud/test/regression/PortForwardingTest.java b/test/src-not-used/main/java/com/cloud/test/regression/PortForwardingTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/PortForwardingTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/PortForwardingTest.java
diff --git a/test/src/com/cloud/test/regression/SanityTest.java b/test/src-not-used/main/java/com/cloud/test/regression/SanityTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/SanityTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/SanityTest.java
diff --git a/test/src/com/cloud/test/regression/Test.java b/test/src-not-used/main/java/com/cloud/test/regression/Test.java
similarity index 100%
rename from test/src/com/cloud/test/regression/Test.java
rename to test/src-not-used/main/java/com/cloud/test/regression/Test.java
diff --git a/test/src/com/cloud/test/regression/TestCase.java b/test/src-not-used/main/java/com/cloud/test/regression/TestCase.java
similarity index 100%
rename from test/src/com/cloud/test/regression/TestCase.java
rename to test/src-not-used/main/java/com/cloud/test/regression/TestCase.java
diff --git a/test/src/com/cloud/test/regression/TestCaseEngine.java b/test/src-not-used/main/java/com/cloud/test/regression/TestCaseEngine.java
similarity index 100%
rename from test/src/com/cloud/test/regression/TestCaseEngine.java
rename to test/src-not-used/main/java/com/cloud/test/regression/TestCaseEngine.java
diff --git a/test/src/com/cloud/test/regression/VMApiTest.java b/test/src-not-used/main/java/com/cloud/test/regression/VMApiTest.java
similarity index 100%
rename from test/src/com/cloud/test/regression/VMApiTest.java
rename to test/src-not-used/main/java/com/cloud/test/regression/VMApiTest.java
diff --git a/test/src/com/cloud/test/stress/SshTest.java b/test/src-not-used/main/java/com/cloud/test/stress/SshTest.java
similarity index 100%
rename from test/src/com/cloud/test/stress/SshTest.java
rename to test/src-not-used/main/java/com/cloud/test/stress/SshTest.java
diff --git a/test/src/com/cloud/test/stress/StressTestDirectAttach.java b/test/src-not-used/main/java/com/cloud/test/stress/StressTestDirectAttach.java
similarity index 100%
rename from test/src/com/cloud/test/stress/StressTestDirectAttach.java
rename to test/src-not-used/main/java/com/cloud/test/stress/StressTestDirectAttach.java
diff --git a/test/src/com/cloud/test/stress/TestClientWithAPI.java b/test/src-not-used/main/java/com/cloud/test/stress/TestClientWithAPI.java
similarity index 100%
rename from test/src/com/cloud/test/stress/TestClientWithAPI.java
rename to test/src-not-used/main/java/com/cloud/test/stress/TestClientWithAPI.java
diff --git a/test/src/com/cloud/test/stress/WgetTest.java b/test/src-not-used/main/java/com/cloud/test/stress/WgetTest.java
similarity index 100%
rename from test/src/com/cloud/test/stress/WgetTest.java
rename to test/src-not-used/main/java/com/cloud/test/stress/WgetTest.java
diff --git a/test/src/com/cloud/test/ui/AbstractSeleniumTestCase.java b/test/src-not-used/main/java/com/cloud/test/ui/AbstractSeleniumTestCase.java
similarity index 100%
rename from test/src/com/cloud/test/ui/AbstractSeleniumTestCase.java
rename to test/src-not-used/main/java/com/cloud/test/ui/AbstractSeleniumTestCase.java
diff --git a/test/src/com/cloud/test/ui/AddAndDeleteAISO.java b/test/src-not-used/main/java/com/cloud/test/ui/AddAndDeleteAISO.java
similarity index 100%
rename from test/src/com/cloud/test/ui/AddAndDeleteAISO.java
rename to test/src-not-used/main/java/com/cloud/test/ui/AddAndDeleteAISO.java
diff --git a/test/src/com/cloud/test/ui/AddAndDeleteATemplate.java b/test/src-not-used/main/java/com/cloud/test/ui/AddAndDeleteATemplate.java
similarity index 100%
rename from test/src/com/cloud/test/ui/AddAndDeleteATemplate.java
rename to test/src-not-used/main/java/com/cloud/test/ui/AddAndDeleteATemplate.java
diff --git a/test/src/com/cloud/test/ui/UIScenarioTest.java b/test/src-not-used/main/java/com/cloud/test/ui/UIScenarioTest.java
similarity index 100%
rename from test/src/com/cloud/test/ui/UIScenarioTest.java
rename to test/src-not-used/main/java/com/cloud/test/ui/UIScenarioTest.java
diff --git a/test/src/com/cloud/test/utils/ConsoleProxy.java b/test/src-not-used/main/java/com/cloud/test/utils/ConsoleProxy.java
similarity index 100%
rename from test/src/com/cloud/test/utils/ConsoleProxy.java
rename to test/src-not-used/main/java/com/cloud/test/utils/ConsoleProxy.java
diff --git a/test/src/com/cloud/test/utils/IpSqlGenerator.java b/test/src-not-used/main/java/com/cloud/test/utils/IpSqlGenerator.java
similarity index 100%
rename from test/src/com/cloud/test/utils/IpSqlGenerator.java
rename to test/src-not-used/main/java/com/cloud/test/utils/IpSqlGenerator.java
diff --git a/test/src/com/cloud/test/utils/ProxyLoadTemp.java b/test/src-not-used/main/java/com/cloud/test/utils/ProxyLoadTemp.java
similarity index 100%
rename from test/src/com/cloud/test/utils/ProxyLoadTemp.java
rename to test/src-not-used/main/java/com/cloud/test/utils/ProxyLoadTemp.java
diff --git a/test/src/com/cloud/test/utils/SignEC2.java b/test/src-not-used/main/java/com/cloud/test/utils/SignEC2.java
similarity index 100%
rename from test/src/com/cloud/test/utils/SignEC2.java
rename to test/src-not-used/main/java/com/cloud/test/utils/SignEC2.java
diff --git a/test/src/com/cloud/test/utils/SignRequest.java b/test/src-not-used/main/java/com/cloud/test/utils/SignRequest.java
similarity index 100%
rename from test/src/com/cloud/test/utils/SignRequest.java
rename to test/src-not-used/main/java/com/cloud/test/utils/SignRequest.java
diff --git a/test/src/com/cloud/test/utils/SqlDataGenerator.java b/test/src-not-used/main/java/com/cloud/test/utils/SqlDataGenerator.java
similarity index 100%
rename from test/src/com/cloud/test/utils/SqlDataGenerator.java
rename to test/src-not-used/main/java/com/cloud/test/utils/SqlDataGenerator.java
diff --git a/test/src/com/cloud/test/utils/SubmitCert.java b/test/src-not-used/main/java/com/cloud/test/utils/SubmitCert.java
similarity index 100%
rename from test/src/com/cloud/test/utils/SubmitCert.java
rename to test/src-not-used/main/java/com/cloud/test/utils/SubmitCert.java
diff --git a/test/src/com/cloud/test/utils/TestClient.java b/test/src-not-used/main/java/com/cloud/test/utils/TestClient.java
similarity index 100%
rename from test/src/com/cloud/test/utils/TestClient.java
rename to test/src-not-used/main/java/com/cloud/test/utils/TestClient.java
diff --git a/test/src/com/cloud/test/utils/UtilsForTest.java b/test/src-not-used/main/java/com/cloud/test/utils/UtilsForTest.java
similarity index 100%
rename from test/src/com/cloud/test/utils/UtilsForTest.java
rename to test/src-not-used/main/java/com/cloud/test/utils/UtilsForTest.java
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index a025efe..1b2a979 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -169,7 +169,6 @@
     'Ucs' : 'UCS',
     'CacheStores' : 'Cache Stores',
     'CacheStore' : 'Cache Store',
-    'IAM' : 'IAM',
     'OvsElement' : 'Ovs Element',
     'StratosphereSsp' : ' Stratosphere SSP',
     'Metrics' : 'Metrics',
@@ -190,7 +189,9 @@
     'CA': 'Certificate',
     'listElastistorInterface': 'Misc',
     'cloudian': 'Cloudian',
-    'Sioc' : 'Sioc'
+    'Sioc' : 'Sioc',
+    'Diagnostics': 'Diagnostics',
+    'Management': 'Management',
     }
 
 
diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml
index d6b7b69..5c8ec85 100644
--- a/tools/apidoc/pom.xml
+++ b/tools/apidoc/pom.xml
@@ -1,13 +1,21 @@
-<!-- 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. -->
+<!--
+  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>
@@ -17,7 +25,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloud-tools</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <properties>
@@ -25,23 +33,20 @@
         <client.config.jars>${client.config.base}/cloud-client-ui-${project.version}.jar</client.config.jars>
         <client.config.conf>${client.config.base}/classes</client.config.conf>
     </properties>
-
     <dependencies>
-      <dependency>
-        <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-server</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-client-ui</artifactId>
-        <version>${project.version}</version>
-	<type>pom</type>
-      </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-client-ui</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+        </dependency>
     </dependencies>
-
     <build>
-        <defaultGoal>install</defaultGoal>
         <plugins>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh
index ba6fe4d..edbe11f 100755
--- a/tools/appliance/build.sh
+++ b/tools/appliance/build.sh
@@ -34,8 +34,12 @@
 END
   exit 0
 }
-echo $@ | grep help >/dev/null && usage
-echo $@ | grep '\-h' >/dev/null && usage
+
+for i in $@; do
+    if [ "$i" == "-h" -o "$i" == "--help" -o "$i" == "help" ]; then
+        usage
+    fi
+done
 
 # requires 32-bit vhd-util and faketime binaries to be available (even for 64 bit builds)
 # Something like (on centos 6.5)...
@@ -194,8 +198,10 @@
     cp -r "${appliance}" "${appliance_build_name}"
     set +e
     if [ ! -z "${version}" ]; then
-    sed ${sed_regex_option} -i -e "s/^CLOUDSTACK_RELEASE=.+/CLOUDSTACK_RELEASE=${version}/" \
-        "${appliance_build_name}/scripts/configure_systemvm_services.sh"
+      if [ -f "${appliance_build_name}/scripts/configure_systemvm_services.sh" ]; then
+          sed ${sed_regex_option} -i -e "s/^CLOUDSTACK_RELEASE=.+/CLOUDSTACK_RELEASE=${version}/" \
+              "${appliance_build_name}/scripts/configure_systemvm_services.sh"
+      fi
     fi
     set -e
     add_on_exit rm -rf "${appliance_build_name}"
@@ -215,7 +221,7 @@
   cd ${appliance_build_name} && packer build template.json && cd ..
 }
 
-function stage_vmx (){
+function stage_vmx() {
   cat << VMXFILE > "${1}.vmx"
 .encoding = "UTF-8"
 displayname = "${1}"
diff --git a/tools/build/build_asf.sh b/tools/build/build_asf.sh
index 04a2d24..7530be5 100755
--- a/tools/build/build_asf.sh
+++ b/tools/build/build_asf.sh
@@ -98,12 +98,8 @@
 perl -pi -e "s/-SNAPSHOT//" deps/XenServerJava/pom.xml
 perl -pi -e "s/-SNAPSHOT//" tools/apidoc/pom.xml
 perl -pi -e "s/-SNAPSHOT//" build/replace.properties
-perl -pi -e "s/-SNAPSHOT//" services/console-proxy/plugin/pom.xml
 perl -pi -e "s/-SNAPSHOT//" tools/marvin/setup.py
 perl -pi -e "s/-SNAPSHOT//" tools/marvin/marvin/deployAndRun.py
-perl -pi -e "s/-SNAPSHOT//" services/iam/plugin/pom.xml
-perl -pi -e "s/-SNAPSHOT//" services/iam/pom.xm
-perl -pi -e "s/-SNAPSHOT//" services/iam/server/pom.xml
 perl -pi -e "s/-SNAPSHOT//" tools/docker/Dockerfile
 perl -pi -e "s/-SNAPSHOT//" tools/docker/Dockerfile.marvin
 perl -pi -e "s/-SNAPSHOT//" tools/docker/Dockerfile.centos6
diff --git a/tools/build/setnextversion.sh b/tools/build/setnextversion.sh
index 2387b89..8d8037c 100755
--- a/tools/build/setnextversion.sh
+++ b/tools/build/setnextversion.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # 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
@@ -16,77 +16,145 @@
 # specific language governing permissions and limitations
 # under the License.
 
-version='TESTBUILD'
-sourcedir=~/cloudstack/
-branch='master'
+set -e
 
-usage(){
-    echo "usage: $0 -v version [-b branch] [-s source dir] [-h]"
-    echo "  -v sets the version"
-    echo "  -b sets the branch (defaults to 'master')"
-    echo "  -s sets the source directory (defaults to $sourcedir)"
-    echo "  -h"
+usage() {
+    cat << USAGE
+Usage: setnextversion.sh --version string [OPTIONS]...
+Set the next version of CloudStack in the POMs.
+
+Mandatory arguments:
+   -v, --version string                    Set the next version to be applied
+
+Optional arguments:
+   -b, --branch string                     Set the branch to update the version into (default "master")
+   -s, --sourcedir string                  Set the source directory to clone repo into (default "$sourcedir")
+   -n, --no-commit                         Apply only the version change and don't git commit them (default "false")
+
+Other arguments:
+   -h, --help                              Display this help message and exit
+
+Examples:
+   setnextversion.sh --version x.y.z.a-SNAPSHOT
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --branch foo-feature
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --sourcedir /path/to/cloudstack/repo
+   setnextversion.sh --version x.y.z.a-SNAPSHOT --no-commit
+
+USAGE
+    exit 0
 }
 
-while getopts v:s:b:h opt
-do
-    case "$opt" in
-      v)  version="$OPTARG";;
-      s)  sourcedir="$OPTARG";;
-      b)  branch="$OPTARG";;
-      h)  usage
-          exit 0;;
-      /?)       # unknown flag
-          usage
-          exit 1;;
+while [ -n "$1" ]; do
+    case "$1" in
+        -h | --help)
+            usage
+            ;;
+
+        -v | --version)
+            if [ -n "$version" ]; then
+                echo "ERROR: you have already entered value for -v, --version"
+                exit 1
+            else
+                version=$2
+                shift 2
+            fi
+            ;;
+
+        -b | --branch)
+            if [ -n "$branch" ]; then
+                echo "ERROR: you have already entered value for -b, --branch"
+                exit 1
+            else
+                branch=$2
+                shift 2
+            fi
+            ;;
+
+        -s | --sourcedir)
+            if [ -n "$sourcedir" ]; then
+                echo "ERROR: you have already entered value for -s, --sourcedir"
+                exit 1
+            else
+                sourcedir=$2
+                shift 2
+            fi
+            ;;
+
+        -n | --no-commit)
+            if [ "$nocommit" == "true" ]; then
+                echo "ERROR: you have already entered value for -n, --no-commit"
+                exit 1
+            else
+                nocommit="true"
+                shift 1
+            fi
+            ;;
+
+        -*|*)
+            echo "ERROR: no such option $1. -h or --help for help"
+            exit 1
+            ;;
     esac
 done
-shift `expr $OPTIND - 1`
 
-if [ $version == 'TESTBUILD' ]; then
-    echo >&2 "A version must be specified with the -v option: $0 -v 4.0.0.RC1"
+if [ -z "$version" ]; then
+    echo >&2 "A version must be specified with the -v, --version option: $0 -v 4.0.0.RC1"
     exit 1
 fi
 
-echo "Using version: $version"
-echo "Using source directory: $sourcedir"
-echo "Using branch: $branch"
+if [ -z "$branch" ]; then
+    branch="master"
+fi
+
+if [ -z "$sourcedir" ]; then
+    sourcedir="~/cloudstack/"
+fi
+
+if [ -z "$nocommit" ]; then
+    nocommit="false"
+fi
+
+echo "Using version          : $version"
+echo "Using source directory : $sourcedir"
+echo "Using branch           : $branch"
 
 cd $sourcedir
 
-echo 'checking out correct branch'
+echo "checking out correct branch"
 git checkout $branch
 
-echo 'determining current mvn version'
-export currentversion=`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['`
+echo "determining current POM version"
+export currentversion=`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -B | grep -v '\['`
 echo "found $currentversion"
 
-echo 'setting version numbers'
-mvn versions:set -DnewVersion=$version -P vmware -P developer -P systemvm -P simulator -P baremetal -P ucs -Dnoredist
-mv deps/XenServerJava/pom.xml.versionsBackup deps/XenServerJava/pom.xml
-perl -pi -e "s/$currentversion/$version/" deps/XenServerJava/pom.xml
-perl -pi -e "s/$currentversion/$version/" tools/apidoc/pom.xml
+echo "setting new version numbers"
+mvn versions:set -DnewVersion=$version -P vmware -P developer -P systemvm -P simulator -Dnoredist versions:commit
+
 perl -pi -e "s/$currentversion/$version/" debian/changelog
-perl -pi -e "s/$currentversion/$version/" tools/marvin/setup.py
-perl -pi -e "s/$currentversion/$version/" services/iam/plugin/pom.xml
-perl -pi -e "s/$currentversion/$version/" services/iam/pom.xm
-perl -pi -e "s/$currentversion/$version/" services/iam/server/pom.xml
+perl -pi -e "s/$currentversion/$version/" tools/apidoc/pom.xml
 perl -pi -e "s/$currentversion/$version/" tools/checkstyle/pom.xml
-perl -pi -e "s/$currentversion/$version/" services/console-proxy/plugin/pom.xml
+perl -pi -e "s/$currentversion/$version/" tools/marvin/setup.py
+
 # Dockerfiles
 perl -pi -e "s/Version=\"$currentversion\"/Version=\"$version\"/" tools/docker/Dockerfile
+
+# Marvin Dockerfiles
 perl -pi -e "s/Version=\"$currentversion\"/Version=\"$version\"/" tools/docker/Dockerfile.marvin
-# centos6 based dockerfile
+perl -pi -e "s/Marvin-(.*).tar.gz/Marvin-${version}.tar.gz/" tools/docker/Dockerfile.marvin
+
+# centos6 based Dockerfile
 perl -pi -e "s/Version=\"$currentversion\"/Version=\"$version\"/" tools/docker/Dockerfile.centos6
 perl -pi -e "s/cloudstack-common-(.*).el6.x86_64.rpm/cloudstack-common-${version}.el6.x86_64.rpm/" tools/docker/Dockerfile.centos6
 perl -pi -e "s/cloudstack-management-(.*)el6.x86_64.rpm/cloudstack-management-${version}.el6.x86_64.rpm/" tools/docker/Dockerfile.centos6
-perl -pi -e "s/Marvin-(.*).tar.gz/Marvin-${version}.tar.gz/" tools/docker/Dockerfile.marvin
+
 # systemtpl.sh:  system vm template version without -SNAPSHOT
 
 git clean -f
 
-echo 'commit changes'
-git commit -a -s -m "Updating pom.xml version numbers for release $version"
-export commitsh=`git show HEAD | head -n 1 | cut -d ' ' -f 2`
+if [ "$nocommit" == "false" ]; then
+    echo "commit changes"
+    git commit -a -s -m "Updating pom.xml version numbers for release $version"
+    export commitsh=`git show HEAD | head -n 1 | cut -d ' ' -f 2`
 
-echo "committed as $commitsh"
+    echo "committed as $commitsh"
+fi
diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml
index b8143ad..e604320 100644
--- a/tools/checkstyle/pom.xml
+++ b/tools/checkstyle/pom.xml
@@ -1,44 +1,31 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ 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>
+  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>
     <name>Apache CloudStack Developer Tools - Checkstyle Configuration</name>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>checkstyle</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
+    <version>4.12.0.0</version>
 
-    <build>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-checkstyle-plugin</artifactId>
-          <version>2.13</version>
-          <executions>
-            <execution>
-              <phase>none</phase>
-            </execution>
-          </executions>
-        </plugin>
-      </plugins>
-    </build>
-
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
 </project>
diff --git a/tools/checkstyle/src/main/resources/cloud-style.xml b/tools/checkstyle/src/main/resources/cloud-style.xml
index 47ea1fb..6aaef17 100644
--- a/tools/checkstyle/src/main/resources/cloud-style.xml
+++ b/tools/checkstyle/src/main/resources/cloud-style.xml
@@ -21,7 +21,6 @@
     <module name="LineLength">
       <property name="max" value="1024" />
     </module>
-
     <module name="RedundantImport" />
     <module name="UnusedImports" />
     <module name="MemberName">
@@ -36,12 +35,13 @@
 	<module name="ConstantName">
 	  <property name="format" value="^[a-zA-Z][a-zA-Z0-9_]*$"/>
 	</module>
-
     <module name="PackageName" />
+    <module name="PackageDeclaration"><property name="matchDirectoryStructure" value="true"/></module>
     <module name="ParameterName" />
     <module name="TypeName" />
     <module name="AvoidStarImport" />
   </module>
+
   <module name="RegexpSingleline">
     <!-- \s matches whitespace character, $ matches end of line. -->
     <property name="format" value="\s+$" />
diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml
index bea58ff..c08c95b 100644
--- a/tools/devcloud-kvm/pom.xml
+++ b/tools/devcloud-kvm/pom.xml
@@ -1,145 +1,149 @@
-<!-- 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-devcloud-kvm</artifactId>
-  <name>Apache CloudStack DevCloud-KVM</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-tools</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-developer</artifactId>
-      <version>${project.version}</version>
-      <type>pom</type>
-      <optional>true</optional>
-      <scope>runtime</scope>
-    </dependency>
-  </dependencies>
+<!--
+  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
 
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
-  <profiles>
-    <profile>
-      <id>deploydb</id>
-      <activation>
-        <property>
-          <name>deploydb</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>properties-maven-plugin</artifactId>
-            <version>1.0-alpha-2</version>
-            <executions>
-              <execution>
-                <phase>initialize</phase>
-                <goals>
-                  <goal>read-project-properties</goal>
-                </goals>
-                <configuration>
-                  <files>
-                    <file>${project.parent.basedir}/utils/conf/db.properties</file>
-                    <file>${project.parent.basedir}/utils/conf/db.properties.override</file>
-                  </files>
-                  <quiet>true</quiet>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>sql-maven-plugin</artifactId>
-            <version>1.5</version>
-            <dependencies>
-              <!-- specify the dependent jdbc driver here -->
-              <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${cs.mysql.version}</version>
-              </dependency>
-            </dependencies>
-            <configuration>
-              <driver>org.gjt.mm.mysql.Driver</driver>
-              <url>${db.cloud.driver}://${db.cloud.host}:${db.cloud.port}/cloud</url>
-              <username>${db.cloud.username}</username>
-              <password>${db.cloud.password}</password>
-              <!--all executions are ignored if -Dmaven.test.skip=true -->
-              <skip>${maven.test.skip}</skip>
-              <forceMojoExecution>true</forceMojoExecution>
-            </configuration>
-            <executions>
-              <execution>
-                <id>create-schema</id>
-                <phase>process-resources</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <srcFiles>
-                    <srcFile>${basedir}/devcloud-kvm.sql</srcFile>
-                  </srcFiles>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>deploysvr</id>
-      <activation>
-        <property>
-          <name>deploysvr</name>
-        </property>
-      </activation>
-      <build> 
-        <plugins>
-          <plugin>
-         <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <executable>python</executable>
-          <arguments>
-            <argument>../marvin/marvin/deployDataCenter.py</argument>
-            <argument>-i</argument>
-            <argument>devcloud-kvm.cfg</argument>
-          </arguments>
-        </configuration>
-          </plugin>
-        </plugins>
-      </build> 
-    </profile>
-  </profiles>
+    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-devcloud-kvm</artifactId>
+    <name>Apache CloudStack DevCloud-KVM</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-tools</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-developer</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <optional>true</optional>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>deploydb</id>
+            <activation>
+                <property>
+                    <name>deploydb</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>properties-maven-plugin</artifactId>
+                        <version>1.0-alpha-2</version>
+                        <executions>
+                            <execution>
+                                <phase>initialize</phase>
+                                <goals>
+                                    <goal>read-project-properties</goal>
+                                </goals>
+                                <configuration>
+                                    <files>
+                                        <file>${project.parent.basedir}/utils/conf/db.properties</file>
+                                        <file>${project.parent.basedir}/utils/conf/db.properties.override</file>
+                                    </files>
+                                    <quiet>true</quiet>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>sql-maven-plugin</artifactId>
+                        <version>1.5</version>
+                        <dependencies>
+                            <!-- specify the dependent jdbc driver here -->
+                            <dependency>
+                                <groupId>mysql</groupId>
+                                <artifactId>mysql-connector-java</artifactId>
+                                <version>${cs.mysql.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <configuration>
+                            <driver>org.gjt.mm.mysql.Driver</driver>
+                            <url>${db.cloud.driver}://${db.cloud.host}:${db.cloud.port}/cloud</url>
+                            <username>${db.cloud.username}</username>
+                            <password>${db.cloud.password}</password>
+                            <!--all executions are ignored if -Dmaven.test.skip=true -->
+                            <skip>${maven.test.skip}</skip>
+                            <forceMojoExecution>true</forceMojoExecution>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>create-schema</id>
+                                <phase>process-resources</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <srcFiles>
+                                        <srcFile>${basedir}/devcloud-kvm.sql</srcFile>
+                                    </srcFiles>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>deploysvr</id>
+            <activation>
+                <property>
+                    <name>deploysvr</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <executable>python</executable>
+                            <arguments>
+                                <argument>../marvin/marvin/deployDataCenter.py</argument>
+                                <argument>-i</argument>
+                                <argument>devcloud-kvm.cfg</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml
index 7058ecb..bf81ebb 100644
--- a/tools/devcloud4/pom.xml
+++ b/tools/devcloud4/pom.xml
@@ -1,112 +1,116 @@
-<!-- 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-devcloud4</artifactId>
-  <name>Apache CloudStack DevCloud4</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-tools</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-developer</artifactId>
-      <version>${project.version}</version>
-      <type>pom</type>
-      <optional>true</optional>
-      <scope>runtime</scope>
-    </dependency>
-  </dependencies>
+<!--
+  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
 
-  <build>
-    <defaultGoal>install</defaultGoal>
-  </build>
-  <profiles>
-    <profile>
-      <id>deploydb</id>
-      <activation>
-        <property>
-          <name>deploydb</name>
-        </property>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>properties-maven-plugin</artifactId>
-            <version>1.0-alpha-2</version>
-            <executions>
-              <execution>
-                <phase>initialize</phase>
-                <goals>
-                  <goal>read-project-properties</goal>
-                </goals>
-                <configuration>
-                  <files>
-                    <file>${project.parent.parent.basedir}/utils/conf/db.properties</file>
-                    <file>${project.parent.parent.basedir}/utils/conf/db.properties.override</file>
-                  </files>
-                  <quiet>true</quiet>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>sql-maven-plugin</artifactId>
-            <version>1.5</version>
-            <dependencies>
-              <!-- specify the dependent jdbc driver here -->
-              <dependency>
-                <groupId>mysql</groupId>
-                <artifactId>mysql-connector-java</artifactId>
-                <version>${cs.mysql.version}</version>
-              </dependency>
-            </dependencies>
-            <configuration>
-              <driver>org.gjt.mm.mysql.Driver</driver>
-              <url>${db.cloud.driver}://${db.cloud.host}:${db.cloud.port}/cloud</url>
-              <username>${db.cloud.username}</username>
-              <password>${db.cloud.password}</password>
-              <!--all executions are ignored if -Dmaven.test.skip=true -->
-              <skip>${maven.test.skip}</skip>
-              <forceMojoExecution>true</forceMojoExecution>
-            </configuration>
-            <executions>
-              <execution>
-                <id>create-schema</id>
-                <phase>process-resources</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <srcFiles>
-                    <srcFile>${basedir}/prefill.sql</srcFile>
-                  </srcFiles>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+    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-devcloud4</artifactId>
+    <name>Apache CloudStack DevCloud4</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-tools</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-developer</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <optional>true</optional>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>deploydb</id>
+            <activation>
+                <property>
+                    <name>deploydb</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>properties-maven-plugin</artifactId>
+                        <version>1.0-alpha-2</version>
+                        <executions>
+                            <execution>
+                                <phase>initialize</phase>
+                                <goals>
+                                    <goal>read-project-properties</goal>
+                                </goals>
+                                <configuration>
+                                    <files>
+                                        <file>${project.parent.parent.basedir}/utils/conf/db.properties</file>
+                                        <file>${project.parent.parent.basedir}/utils/conf/db.properties.override</file>
+                                    </files>
+                                    <quiet>true</quiet>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>sql-maven-plugin</artifactId>
+                        <version>1.5</version>
+                        <dependencies>
+                            <!-- specify the dependent jdbc driver here -->
+                            <dependency>
+                                <groupId>mysql</groupId>
+                                <artifactId>mysql-connector-java</artifactId>
+                                <version>${cs.mysql.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <configuration>
+                            <driver>org.gjt.mm.mysql.Driver</driver>
+                            <url>${db.cloud.driver}://${db.cloud.host}:${db.cloud.port}/cloud</url>
+                            <username>${db.cloud.username}</username>
+                            <password>${db.cloud.password}</password>
+                            <!--all executions are ignored if -Dmaven.test.skip=true -->
+                            <skip>${maven.test.skip}</skip>
+                            <forceMojoExecution>true</forceMojoExecution>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>create-schema</id>
+                                <phase>process-resources</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <srcFiles>
+                                        <srcFile>${basedir}/prefill.sql</srcFile>
+                                    </srcFiles>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 8a9c1d2..8deb161 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -20,7 +20,7 @@
 FROM ubuntu:16.04
 
 MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
-LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.4.0-SNAPSHOT"
+LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0.0"
 
 RUN apt-get -y update && apt-get install -y \
     genisoimage \
diff --git a/tools/docker/Dockerfile.centos6 b/tools/docker/Dockerfile.centos6
index 326c7fd..af0509b 100644
--- a/tools/docker/Dockerfile.centos6
+++ b/tools/docker/Dockerfile.centos6
@@ -18,7 +18,7 @@
 FROM centos:6
 
 MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
-LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.4.0-SNAPSHOT"
+LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0.0"
 
 ENV PKG_URL=https://builds.cloudstack.org/job/package-master-rhel63/lastSuccessfulBuild/artifact/dist/rpmbuild/RPMS/x86_64
 
@@ -26,8 +26,8 @@
 RUN rpm -i http://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-2.1.3-1.el6.x86_64.rpm
 
 RUN yum install -y nc wget \
-    ${PKG_URL}/cloudstack-common-4.11.4.0-SNAPSHOT.el6.x86_64.rpm \
-    ${PKG_URL}/cloudstack-management-4.11.4.0-SNAPSHOT.el6.x86_64.rpm
+    ${PKG_URL}/cloudstack-common-4.12.0.0.el6.x86_64.rpm \
+    ${PKG_URL}/cloudstack-management-4.12.0.0.el6.x86_64.rpm
 
 RUN cd /etc/cloudstack/management; \
     ln -s tomcat6-nonssl.conf tomcat6.conf; \
diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin
index 33ae40c..0345db7 100644
--- a/tools/docker/Dockerfile.marvin
+++ b/tools/docker/Dockerfile.marvin
@@ -20,11 +20,11 @@
 FROM python:2
 
 MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
-LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.4.0-SNAPSHOT"
+LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0.0"
 
 ENV WORK_DIR=/marvin
 
-ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.11.4.0-SNAPSHOT.tar.gz
+ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.12.0.0.tar.gz
 
 RUN apt-get update && apt-get install -y vim
 RUN pip install --upgrade paramiko nose requests
diff --git a/tools/docker/Dockerfile.smokedev b/tools/docker/Dockerfile.smokedev
new file mode 100644
index 0000000..2faf44b
--- /dev/null
+++ b/tools/docker/Dockerfile.smokedev
@@ -0,0 +1,143 @@
+# 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.
+#
+# CloudStack-simulator build
+
+FROM ubuntu:16.04
+
+MAINTAINER "Apache CloudStack" <dev@cloudstack.apache.org>
+LABEL Vendor="Apache.org" License="ApacheV2" Version="4.12.0-SNAPSHOT"
+
+RUN apt-get -y update && apt-get install -y \
+    genisoimage \
+    libffi-dev \
+    libssl-dev \
+    git \
+    sudo \
+    ipmitool \
+    maven \
+    openjdk-8-jdk \
+    python-dev \
+    python-setuptools \
+    python-pip \
+    python-mysql.connector \
+    supervisor \
+    python-crypto \
+    python-openssl
+
+RUN echo 'mysql-server mysql-server/root_password password root' |  debconf-set-selections; \
+    echo 'mysql-server mysql-server/root_password_again password root' |  debconf-set-selections;
+
+RUN apt-get install -qqy mysql-server && \
+    apt-get clean all && \
+    mkdir /var/run/mysqld; \
+    chown mysql /var/run/mysqld
+
+#
+# this package is needed if one wants to run marvin tests from
+# inside the running simulator.
+#
+RUN pip install pyOpenSSL
+
+RUN echo '''sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"''' >> /etc/mysql/mysql.conf.d/mysqld.cnf
+RUN (/usr/bin/mysqld_safe &); sleep 5; mysqladmin -u root -proot password ''
+
+COPY agent /root/agent
+COPY api /root/api
+COPY build /root/build
+COPY client /root/client
+COPY cloud-cli /root/cloud-cli
+COPY cloudstack.iml /root/cloudstack.iml
+COPY core /root/core
+COPY debian /root/debian
+COPY deps /root/deps
+COPY developer /root/developer
+COPY engine /root/engine
+COPY framework /root/framework
+COPY LICENSE.header /root/LICENSE.header
+COPY LICENSE /root/LICENSE
+COPY maven-standard /root/maven-standard
+COPY NOTICE /root/NOTICE
+COPY packaging /root/packaging
+COPY plugins /root/plugins
+COPY pom.xml /root/pom.xml
+COPY python /root/python
+COPY quickcloud /root/quickcloud
+COPY requirements.txt /root/requirements.txt
+COPY scripts /root/scripts
+COPY server /root/server
+COPY services /root/services
+COPY setup /root/setup
+COPY systemvm /root/systemvm
+COPY target /root/target
+COPY test/bindirbak /root/test/bindirbak
+COPY test/conf /root/test/conf
+COPY test/metadata /root/test/metadata
+COPY test/pom.xml /root/test/pom.xml
+COPY test/scripts /root/test/scripts
+COPY test/selenium /root/test/selenium
+COPY test/systemvm /root/test/systemvm
+COPY test/target /root/test/target
+COPY tools/pom.xml /root/tools/pom.xml
+COPY tools/apidoc /root/tools/apidoc
+COPY tools/checkstyle /root/tools/checkstyle
+COPY tools/devcloud4/pom.xml /root/tools/devcloud4/pom.xml
+COPY tools/devcloud-kvm/pom.xml /root/tools/devcloud-kvm/pom.xml
+COPY tools/marvin/pom.xml /root/tools/marvin/pom.xml
+COPY tools/pom.xml /root/tools/pom.xml
+COPY ui /root/ui
+COPY usage /root/usage
+COPY utils /root/utils
+COPY vmware-base /root/vmware-base
+
+RUN cd /root && mvn -Pdeveloper -Dsimulator -DskipTests -pl "!:cloud-marvin" install
+
+RUN (/usr/bin/mysqld_safe &) && \
+    sleep 5 && \
+    cd /root && \
+    mvn -Pdeveloper -pl developer -Ddeploydb && \
+    mvn -Pdeveloper -pl developer -Ddeploydb-simulator
+
+COPY tools/marvin /root/tools/marvin
+COPY tools/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY tools/docker/docker_run_tests.sh /root
+
+RUN cd /root && mvn -Pdeveloper -Dsimulator -DskipTests -pl ":cloud-marvin"
+
+RUN MARVIN_FILE=`find /root/tools/marvin/dist/ -name "Marvin*.tar.gz"` && pip install $MARVIN_FILE
+
+COPY test/integration /root/test/integration
+COPY tools /root/tools
+
+RUN pip install --upgrade pyOpenSSL
+
+EXPOSE 8080 8096
+
+WORKDIR /root
+
+CMD ["/usr/bin/supervisord"]
+
+# --------------------------------
+#
+# docker run -v ~/dev/tmp:/tmp -v ~/IdeaProjects/cloudstack/test/integration/smoke:/root/test/integration/smoke -it
+# --name simulator -p 8080:8080 -p8096:8096 simulator:4.12
+#
+# docker exec -it simulator bash
+#
+# cat /root/docker_run_tests.sh
+# for instructions
+#
\ No newline at end of file
diff --git a/tools/docker/docker-compose.yml b/tools/docker/docker-compose.yml
new file mode 100644
index 0000000..86934f6
--- /dev/null
+++ b/tools/docker/docker-compose.yml
@@ -0,0 +1,35 @@
+# 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.
+
+version: '2'
+services:
+  db:
+    image: mariadb:10.0
+    volumes:
+      - ./mariadb-docker:/etc/mysql/conf.d
+      - db:/var/lib/mysql
+    environment:
+      MYSQL_DATABASE: cloud
+#      MYSQL_ROOT_PASSWORD: root
+      MYSQL_ALLOW_EMPTY_PASSWORD: 1
+      MYSQL_USER: cloud
+      MYSQL_PASSWORD: cloud
+    ports:
+      - "3306:3306"
+
+volumes:
+  db:
diff --git a/tools/docker/docker_run_tests.sh b/tools/docker/docker_run_tests.sh
new file mode 100644
index 0000000..1cc2703
--- /dev/null
+++ b/tools/docker/docker_run_tests.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# 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.
+
+MODE=${1:-advanced}
+SUITE=${2:-smoke}
+
+export MARVIN_CONFIG=setup/dev/$MODE.cfg
+export TEST_SUITE=test/integration/$SUITE
+export ZONE_NAME=Sandbox-simulator
+
+cd /root
+
+python tools/marvin/marvin/deployDataCenter.py -i setup/dev/$MODE.cfg
+
+cat <<EOF
+
+RUN WHOLE '$SUITE' SUITE
+--------------------------
+nosetests-2.7 \
+  --with-marvin \
+  --marvin-config=${MARVIN_CONFIG} \
+  -w ${TEST_SUITE} \
+  --with-xunit \
+  --xunit-file=/tmp/bvt_selfservice_cases.xml \
+  --zone=${ZONE_NAME} \
+  --hypervisor=simulator \
+  -a tags=$MODE,required_hardware=false
+--------------------------
+OR INDIVIDUAL TEST LIKE
+--------------------------
+nosetests-2.7 -s --with-marvin --marvin-config=${MARVIN_CONFIG} --zone=${ZONE_NAME} \
+    --hypervisor=simulator -a tags=$MODE,required_hardware=false \
+    test/integration/smoke/test_accounts.py:TestAccounts
+--------------------------
+EOF
diff --git a/tools/docker/mariadb-docker/cloudstack-docker.cnf b/tools/docker/mariadb-docker/cloudstack-docker.cnf
new file mode 100644
index 0000000..771aa86
--- /dev/null
+++ b/tools/docker/mariadb-docker/cloudstack-docker.cnf
@@ -0,0 +1,24 @@
+# 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.
+
+[mysqld]
+server-id=master-dev
+innodb_rollback_on_timeout=1
+innodb_lock_wait_timeout=600
+max_connections=1000
+log-bin=mysql-bin
+binlog-format = 'ROW'
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 7c5ce5c..929741b 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -1239,6 +1239,24 @@
         "disksize": 1,  # in GB
         "provisioningtype": "fat"
     },
+    "ioburst": {
+        "name": "io burst disk offering",
+        "displaytext": "io burst disk offering",
+        "disksize": 1,
+        "provisioningtype": "sparse",
+        "bytesReadRate": 500,
+        "bytesReadRateMax": 2000,
+        "bytesReadRateMaxLength": 120,
+        "bytesWriteRate": 501,
+        "bytesWriteRateMax": 2001,
+        "bytesWriteRateMaxLength": 121,
+        "iopsReadRate": 1000,
+        "iopsReadRateMax": 2500,
+        "iopsReadRateMaxLength": 122,
+        "iopsWriteRate": 1001,
+        "iopsWriteRateMax": 2501,
+        "iopsWriteRateMaxLength": 123
+    },
     "sparse_disk_offering": {
         "displaytext": "Sparse",
         "name": "Sparse",
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index ede8256..5fe2ea7 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -32,8 +32,10 @@
 import hashlib
 import base64
 
+
 class Domain:
     """ Domain Life Cycle """
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -86,7 +88,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listDomains(cmd))
+        return (apiclient.listDomains(cmd))
 
 
 class Role:
@@ -127,7 +129,7 @@
 
         cmd = listRoles.listRolesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listRoles(cmd))
+        return (apiclient.listRoles(cmd))
 
 
 class RolePermission:
@@ -169,11 +171,12 @@
 
         cmd = listRolePermissions.listRolePermissionsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listRolePermissions(cmd))
+        return (apiclient.listRolePermissions(cmd))
 
 
 class Account:
     """ Account Life Cycle """
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -196,7 +199,7 @@
         username = username[:6]
         apiclientid = apiclient.id[-85:] if len(apiclient.id) > 85 else apiclient.id
         cmd.username = "-".join([username,
-                             random_gen(id=apiclientid, size=6)])
+                                 random_gen(id=apiclientid, size=6)])
 
         if "accountUUID" in services:
             cmd.accountid = "-".join([services["accountUUID"], random_gen()])
@@ -229,7 +232,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listAccounts(cmd))
+        return (apiclient.listAccounts(cmd))
 
     def disable(self, apiclient, lock=False):
         """Disable an account"""
@@ -238,9 +241,19 @@
         cmd.lock = lock
         apiclient.disableAccount(cmd)
 
+    def update(self, apiclient, roleid=None, newname=None, networkdomain=""):
+        """Update account"""
+        cmd = updateAccount.updateAccountCmd()
+        cmd.id = self.id
+        cmd.networkdomain = networkdomain
+        cmd.newname = newname
+        cmd.roleid = roleid
+        apiclient.updateAccount(cmd)
+
 
 class User:
     """ User Life Cycle """
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -270,7 +283,7 @@
         cmd.id = self.id
         apiclient.deleteUser(cmd)
 
-    def move(self, api_client, dest_accountid = None, dest_account = None, domain= None):
+    def move(self, api_client, dest_accountid=None, dest_account=None, domain=None):
 
         if all([dest_account, dest_accountid]) is None:
             raise Exception("Please add either destination account or destination account ID.")
@@ -292,7 +305,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listUsers(cmd))
+        return (apiclient.listUsers(cmd))
 
     @classmethod
     def registerUserKeys(cls, apiclient, userid):
@@ -342,6 +355,7 @@
     EXPUNGING = EXPUNGING
     STOPPING = STOPPING
     STARTING = STARTING
+
     # Varibles denoting VM state - end
 
     def __init__(self, items, services):
@@ -584,9 +598,9 @@
         cmd.datadisktemplatetodiskofferinglist = []
         for datadisktemplate, diskoffering in datadisktemplate_diskoffering_list.items():
             cmd.datadisktemplatetodiskofferinglist.append({
-                                            'datadisktemplateid': datadisktemplate,
-                                            'diskofferingid': diskoffering
-                                           })
+                'datadisktemplateid': datadisktemplate,
+                'diskofferingid': diskoffering
+            })
 
         # program default access to ssh
         if mode.lower() == 'basic':
@@ -599,6 +613,10 @@
 
         virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
 
+        if 'password' in virtual_machine.__dict__.keys():
+            if virtual_machine.password:
+                services['password'] = virtual_machine.password
+
         virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress
         if startvm is False:
             virtual_machine.public_ip = virtual_machine.nic[0].ipaddress
@@ -737,7 +755,7 @@
                 if hasattr(self, "projectid"):
                     projectid = self.projectid
                 vms = VirtualMachine.list(apiclient, projectid=projectid,
-                        id=self.id, listAll=True)
+                                          id=self.id, listAll=True)
                 validationresult = validateList(vms)
                 if validationresult[0] == FAIL:
                     raise Exception("VM list validation failed: %s" % validationresult[2])
@@ -757,7 +775,7 @@
         cmd = resetSSHKeyForVirtualMachine.resetSSHKeyForVirtualMachineCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.resetSSHKeyForVirtualMachine(cmd))
+        return (apiclient.resetSSHKeyForVirtualMachine(cmd))
 
     def update(self, apiclient, **kwargs):
         """Updates the VM data"""
@@ -765,7 +783,7 @@
         cmd = updateVirtualMachine.updateVirtualMachineCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateVirtualMachine(cmd))
+        return (apiclient.updateVirtualMachine(cmd))
 
     def delete(self, apiclient, expunge=True, **kwargs):
         """Destroy an Instance"""
@@ -801,7 +819,7 @@
                 cmd.migrateto.append({
                     'volume': volume,
                     'pool': pool
-            })
+                })
         apiclient.migrateVirtualMachineWithVolume(cmd)
 
     def attach_volume(self, apiclient, volume, deviceid=None):
@@ -846,7 +864,7 @@
 
     def update_default_nic(self, apiclient, nicId):
         """Set a NIC to be the default network adapter for a VM"""
-        cmd = updateDefaultNicForVirtualMachine.\
+        cmd = updateDefaultNicForVirtualMachine. \
             updateDefaultNicForVirtualMachineCmd()
         cmd.nicid = nicId
         cmd.virtualmachineid = self.id
@@ -874,7 +892,7 @@
 
     def change_service_offering(self, apiclient, serviceOfferingId):
         """Change service offering of the instance"""
-        cmd = changeServiceForVirtualMachine.\
+        cmd = changeServiceForVirtualMachine. \
             changeServiceForVirtualMachineCmd()
         cmd.id = self.id
         cmd.serviceofferingid = serviceOfferingId
@@ -888,12 +906,12 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVirtualMachines(cmd))
+        return (apiclient.listVirtualMachines(cmd))
 
     def resetPassword(self, apiclient):
         """Resets VM password if VM created using password enabled template"""
 
-        cmd = resetPasswordForVirtualMachine.\
+        cmd = resetPasswordForVirtualMachine. \
             resetPasswordForVirtualMachineCmd()
         cmd.id = self.id
         try:
@@ -931,7 +949,7 @@
         return apiclient.updateVMAffinityGroup(cmd)
 
     def scale(self, apiclient, serviceOfferingId,
-            customcpunumber=None, customcpuspeed=None, custommemory=None):
+              customcpunumber=None, customcpuspeed=None, custommemory=None):
         """Change service offering of the instance"""
         cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
         cmd.id = self.id
@@ -949,6 +967,7 @@
 class Volume:
     """Manage Volume Life cycle
     """
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -1066,14 +1085,14 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVolumes(cmd))
+        return (apiclient.listVolumes(cmd))
 
     def resize(self, apiclient, **kwargs):
         """Resize a volume"""
         cmd = resizeVolume.resizeVolumeCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.resizeVolume(cmd))
+        return (apiclient.resizeVolume(cmd))
 
     @classmethod
     def upload(cls, apiclient, services, zoneid=None,
@@ -1145,7 +1164,7 @@
         """Migrate a volume"""
         cmd = migrateVolume.migrateVolumeCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.migrateVolume(cmd))
+        return (apiclient.migrateVolume(cmd))
 
 
 class Snapshot:
@@ -1155,6 +1174,7 @@
     # Variables denoting possible Snapshot states - start
     BACKED_UP = BACKED_UP
     BACKING_UP = BACKING_UP
+
     # Variables denoting possible Snapshot states - end
 
     def __init__(self, items):
@@ -1174,8 +1194,8 @@
             cmd.projectid = projectid
         if locationtype:
             cmd.locationtype = locationtype
-	if asyncbackup:
-	    cmd.asyncbackup = asyncbackup
+        if asyncbackup:
+            cmd.asyncbackup = asyncbackup
         return Snapshot(apiclient.createSnapshot(cmd).__dict__)
 
     def delete(self, apiclient):
@@ -1192,7 +1212,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listSnapshots(cmd))
+        return (apiclient.listSnapshots(cmd))
 
     def validateState(self, apiclient, snapshotstate, timeout=600):
         """Check if snapshot is in required state
@@ -1212,9 +1232,9 @@
                     break
                 timeout -= 60
                 time.sleep(60)
-            #end while
+            # end while
             if isSnapshotInRequiredState:
-                return[PASS, None]
+                return [PASS, None]
             else:
                 raise Exception("Snapshot not in required state")
         except Exception as e:
@@ -1323,7 +1343,7 @@
             "ispublic"] if "ispublic" in services else False
         cmd.isextractable = services[
             "isextractable"] if "isextractable" in services else False
-        cmd.isdynamicallyscalable=services["isdynamicallyscalable"] if "isdynamicallyscalable" in services else False
+        cmd.isdynamicallyscalable = services["isdynamicallyscalable"] if "isdynamicallyscalable" in services else False
         cmd.passwordenabled = services[
             "passwordenabled"] if "passwordenabled" in services else False
 
@@ -1344,7 +1364,6 @@
         if "directdownload" in services:
             cmd.directdownload = services["directdownload"]
 
-
         # Register Template
         template = apiclient.registerTemplate(cmd)
 
@@ -1471,7 +1490,7 @@
         cmd = updateTemplatePermissions.updateTemplatePermissionsCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateTemplatePermissions(cmd))
+        return (apiclient.updateTemplatePermissions(cmd))
 
     def update(self, apiclient, **kwargs):
         """Updates the template details"""
@@ -1479,7 +1498,7 @@
         cmd = updateTemplate.updateTemplateCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateTemplate(cmd))
+        return (apiclient.updateTemplate(cmd))
 
     def copy(self, apiclient, sourcezoneid, destzoneid):
         "Copy Template from source Zone to Destination Zone"
@@ -1499,7 +1518,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listTemplates(cmd))
+        return (apiclient.listTemplates(cmd))
 
 
 class Iso:
@@ -1615,7 +1634,7 @@
         cmd = updateIso.updateIsoCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateIso(cmd))
+        return (apiclient.updateIso(cmd))
 
     @classmethod
     def copy(cls, apiclient, id, sourcezoneid, destzoneid):
@@ -1636,7 +1655,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listIsos(cmd))
+        return (apiclient.listIsos(cmd))
 
 
 class PublicIPAddress:
@@ -1695,7 +1714,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listPublicIpAddresses(cmd))
+        return (apiclient.listPublicIpAddresses(cmd))
 
 
 class NATRule:
@@ -1744,7 +1763,7 @@
 
     @classmethod
     def update(self, apiclient, id, virtual_machine, services, fordisplay=False,
-           vmguestip=None):
+               vmguestip=None):
         """Create Port forwarding rule"""
         cmd = updatePortForwardingRule.updatePortForwardingRuleCmd()
         cmd.id = id
@@ -1781,7 +1800,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listPortForwardingRules(cmd))
+        return (apiclient.listPortForwardingRules(cmd))
 
 
 class StaticNATRule:
@@ -1844,7 +1863,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listIpForwardingRules(cmd))
+        return (apiclient.listIpForwardingRules(cmd))
 
     @classmethod
     def enable(cls, apiclient, ipaddressid, virtualmachineid, networkid=None,
@@ -1873,7 +1892,6 @@
 
 
 class EgressFireWallRule:
-
     """Manage Egress Firewall rule"""
 
     def __init__(self, items):
@@ -1915,11 +1933,10 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listEgressFirewallRules(cmd))
+        return (apiclient.listEgressFirewallRules(cmd))
 
 
 class FireWallRule:
-
     """Manage Firewall rule"""
 
     def __init__(self, items):
@@ -1962,11 +1979,10 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listFirewallRules(cmd))
+        return (apiclient.listFirewallRules(cmd))
 
 
 class Autoscale:
-
     """Manage Auto scale"""
 
     def __init__(self, items):
@@ -1978,7 +1994,7 @@
 
         cmd = listCounters.listCountersCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listCounters(cmd))
+        return (apiclient.listCounters(cmd))
 
     @classmethod
     def createCondition(cls, apiclient, counterid, relationaloperator, threshold):
@@ -1988,7 +2004,7 @@
         cmd.counterid = counterid
         cmd.relationaloperator = relationaloperator
         cmd.threshold = threshold
-        return(apiclient.createCondition(cmd))
+        return (apiclient.createCondition(cmd))
 
     @classmethod
     def listConditions(cls, apiclient, **kwargs):
@@ -1996,7 +2012,7 @@
 
         cmd = listConditions.listConditionsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listConditions(cmd))
+        return (apiclient.listConditions(cmd))
 
     @classmethod
     def listAutoscalePolicies(cls, apiclient, **kwargs):
@@ -2004,7 +2020,7 @@
 
         cmd = listAutoScalePolicies.listAutoScalePoliciesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listAutoScalePolicies(cmd))
+        return (apiclient.listAutoScalePolicies(cmd))
 
     @classmethod
     def createAutoscalePolicy(cls, apiclient, action, conditionids, duration, quiettime=None):
@@ -2017,7 +2033,7 @@
         if quiettime:
             cmd.quiettime = quiettime
 
-        return(apiclient.createAutoScalePolicy(cmd))
+        return (apiclient.createAutoScalePolicy(cmd))
 
     @classmethod
     def updateAutoscalePolicy(cls, apiclient, id, **kwargs):
@@ -2026,7 +2042,7 @@
         cmd = updateAutoScalePolicy.updateAutoScalePolicyCmd()
         cmd.id = id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateAutoScalePolicy(cmd))
+        return (apiclient.updateAutoScalePolicy(cmd))
 
     @classmethod
     def listAutoscaleVmPofiles(cls, apiclient, **kwargs):
@@ -2034,7 +2050,7 @@
 
         cmd = listAutoScaleVmProfiles.listAutoScaleVmProfilesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listAutoScaleVmProfiles(cmd))
+        return (apiclient.listAutoScaleVmProfiles(cmd))
 
     @classmethod
     def createAutoscaleVmProfile(cls, apiclient, serviceofferingid, zoneid, templateid,
@@ -2058,7 +2074,7 @@
                     'value': value
                 })
 
-        return(apiclient.createAutoScaleVmProfile(cmd))
+        return (apiclient.createAutoScaleVmProfile(cmd))
 
     @classmethod
     def updateAutoscaleVMProfile(cls, apiclient, id, **kwargs):
@@ -2067,11 +2083,11 @@
         cmd = updateAutoScaleVmProfile.updateAutoScaleVmProfileCmd()
         cmd.id = id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateAutoScaleVmProfile(cmd))
+        return (apiclient.updateAutoScaleVmProfile(cmd))
 
     @classmethod
     def createAutoscaleVmGroup(cls, apiclient, lbruleid, minmembers, maxmembers,
-                                 scaledownpolicyids, scaleuppolicyids, vmprofileid, interval=None):
+                               scaledownpolicyids, scaleuppolicyids, vmprofileid, interval=None):
         """creates Autoscale VM Group."""
 
         cmd = createAutoScaleVmGroup.createAutoScaleVmGroupCmd()
@@ -2084,7 +2100,7 @@
         if interval:
             cmd.interval = interval
 
-        return(apiclient.createAutoScaleVmGroup(cmd))
+        return (apiclient.createAutoScaleVmGroup(cmd))
 
     @classmethod
     def listAutoscaleVmGroup(cls, apiclient, **kwargs):
@@ -2092,7 +2108,7 @@
 
         cmd = listAutoScaleVmGroups.listAutoScaleVmGroupsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listAutoScaleVmGroups(cmd))
+        return (apiclient.listAutoScaleVmGroups(cmd))
 
     @classmethod
     def enableAutoscaleVmGroup(cls, apiclient, id, **kwargs):
@@ -2101,7 +2117,7 @@
         cmd = enableAutoScaleVmGroup.enableAutoScaleVmGroupCmd()
         cmd.id = id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.enableAutoScaleVmGroup(cmd))
+        return (apiclient.enableAutoScaleVmGroup(cmd))
 
     @classmethod
     def disableAutoscaleVmGroup(cls, apiclient, id, **kwargs):
@@ -2110,7 +2126,7 @@
         cmd = disableAutoScaleVmGroup.disableAutoScaleVmGroupCmd()
         cmd.id = id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.disableAutoScaleVmGroup(cmd))
+        return (apiclient.disableAutoScaleVmGroup(cmd))
 
     @classmethod
     def updateAutoscaleVMGroup(cls, apiclient, id, **kwargs):
@@ -2119,11 +2135,10 @@
         cmd = updateAutoScaleVmGroup.updateAutoScaleVmGroupCmd()
         cmd.id = id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateAutoScaleVmGroup(cmd))
+        return (apiclient.updateAutoScaleVmGroup(cmd))
 
 
 class ServiceOffering:
-
     """Manage service offerings cycle"""
 
     def __init__(self, items):
@@ -2206,7 +2221,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listServiceOfferings(cmd))
+        return (apiclient.listServiceOfferings(cmd))
 
 
 class DiskOffering:
@@ -2216,7 +2231,7 @@
         self.__dict__.update(items)
 
     @classmethod
-    def create(cls, apiclient, services, tags=None, custom=False, domainid=None):
+    def create(cls, apiclient, services, tags=None, custom=False, domainid=None, **kwargs):
         """Create Disk offering"""
         cmd = createDiskOffering.createDiskOfferingCmd()
         cmd.displaytext = services["displaytext"]
@@ -2255,6 +2270,7 @@
         if "provisioningtype" in services:
             cmd.provisioningtype = services["provisioningtype"]
 
+        [setattr(cmd, k, v) for k, v in kwargs.items()]
         return DiskOffering(apiclient.createDiskOffering(cmd).__dict__)
 
     def delete(self, apiclient):
@@ -2272,7 +2288,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listDiskOfferings(cmd))
+        return (apiclient.listDiskOfferings(cmd))
 
 
 class NetworkOffering:
@@ -2305,8 +2321,8 @@
                 })
         if "serviceCapabilityList" in services:
             cmd.servicecapabilitylist = []
-            for service, capability in services["serviceCapabilityList"].\
-                                       items():
+            for service, capability in services["serviceCapabilityList"]. \
+                    items():
                 for ctype, value in capability.items():
                     cmd.servicecapabilitylist.append({
                         'service': service,
@@ -2329,7 +2345,6 @@
         if "servicepackagedescription" in services:
             cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"]
 
-
         cmd.availability = 'Optional'
 
         [setattr(cmd, k, v) for k, v in kwargs.items()]
@@ -2349,7 +2364,7 @@
         cmd = updateNetworkOffering.updateNetworkOfferingCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateNetworkOffering(cmd))
+        return (apiclient.updateNetworkOffering(cmd))
 
     @classmethod
     def list(cls, apiclient, **kwargs):
@@ -2359,7 +2374,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetworkOfferings(cmd))
+        return (apiclient.listNetworkOfferings(cmd))
 
 
 class SnapshotPolicy:
@@ -2394,10 +2409,12 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listSnapshotPolicies(cmd))
+        return (apiclient.listSnapshotPolicies(cmd))
+
 
 class GuestOs:
     """Guest OS calls (currently read-only implemented)"""
+
     def __init(self, items):
         self.__dict__.update(items)
 
@@ -2422,7 +2439,8 @@
 
         cmd = listOsTypes.listOsTypesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listOsTypes(cmd))
+        return (apiclient.listOsTypes(cmd))
+
 
 class Hypervisor:
     """Manage Hypervisor"""
@@ -2438,7 +2456,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listHypervisors(cmd))
+        return (apiclient.listHypervisors(cmd))
 
 
 class LoadBalancerRule:
@@ -2570,7 +2588,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listLoadBalancerRules(cmd))
+        return (apiclient.listLoadBalancerRules(cmd))
 
     @classmethod
     def listLoadBalancerRuleInstances(cls, apiclient, id, lbvmips=False, applied=None, **kwargs):
@@ -2635,7 +2653,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listClusters(cmd))
+        return (apiclient.listClusters(cmd))
 
     @classmethod
     def update(cls, apiclient, **kwargs):
@@ -2643,7 +2661,7 @@
 
         cmd = updateCluster.updateClusterCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateCluster(cmd))
+        return (apiclient.updateCluster(cmd))
 
 
 class Host:
@@ -2739,7 +2757,8 @@
         retry_interval = 10
         num_tries = 10
 
-        wait_result, return_val = wait_until(retry_interval, num_tries, Host._check_resource_state, apiclient, self.id, HOST_RS_MAINTENANCE)
+        wait_result, return_val = wait_until(retry_interval, num_tries, Host._check_resource_state, apiclient, self.id,
+                                             HOST_RS_MAINTENANCE)
 
         if not wait_result:
             raise Exception(return_val)
@@ -2773,7 +2792,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listHosts(cmd))
+        return (apiclient.listHosts(cmd))
 
     @classmethod
     def listForMigration(cls, apiclient, **kwargs):
@@ -2783,7 +2802,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.findHostsForMigration(cmd))
+        return (apiclient.findHostsForMigration(cmd))
 
     @classmethod
     def update(cls, apiclient, **kwargs):
@@ -2791,7 +2810,7 @@
 
         cmd = updateHost.updateHostCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateHost(cmd))
+        return (apiclient.updateHost(cmd))
 
     @classmethod
     def reconnect(cls, apiclient, **kwargs):
@@ -2799,7 +2818,7 @@
 
         cmd = reconnectHost.reconnectHostCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.reconnectHost(cmd))
+        return (apiclient.reconnectHost(cmd))
 
     @classmethod
     def getState(cls, apiclient, hostid, state, resourcestate, timeout=600):
@@ -2816,11 +2835,12 @@
         while timeout > 0:
             try:
                 hosts = Host.list(apiclient,
-                          id=hostid, listall=True)
+                                  id=hostid, listall=True)
                 validationresult = validateList(hosts)
                 if validationresult[0] == FAIL:
                     raise Exception("Host list validation failed: %s" % validationresult[2])
-                elif str(hosts[0].state).lower().decode("string_escape") == str(state).lower() and str(hosts[0].resourcestate).lower().decode("string_escape") == str(resourcestate).lower():
+                elif str(hosts[0].state).lower().decode("string_escape") == str(state).lower() and str(
+                        hosts[0].resourcestate).lower().decode("string_escape") == str(resourcestate).lower():
                     returnValue = [PASS, None]
                     break
             except Exception as e:
@@ -2830,6 +2850,7 @@
             timeout -= 60
         return returnValue
 
+
 class StoragePool:
     """Manage Storage pools (Primary Storage)"""
 
@@ -2930,7 +2951,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listStoragePools(cmd))
+        return (apiclient.listStoragePools(cmd))
 
     @classmethod
     def listForMigration(cls, apiclient, **kwargs):
@@ -2940,7 +2961,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.findStoragePoolsForMigration(cmd))
+        return (apiclient.findStoragePoolsForMigration(cmd))
 
     @classmethod
     def update(cls, apiclient, **kwargs):
@@ -2964,7 +2985,7 @@
         while timeout > 0:
             try:
                 pools = StoragePool.list(apiclient,
-                          id=poolid, listAll=True)
+                                         id=poolid, listAll=True)
                 validationresult = validateList(pools)
                 if validationresult[0] == FAIL:
                     raise Exception("Pool list validation failed: %s" % validationresult[2])
@@ -2978,6 +2999,7 @@
             timeout -= 60
         return returnValue
 
+
 class Network:
     """Manage Network pools"""
 
@@ -3054,7 +3076,7 @@
         cmd = updateNetwork.updateNetworkCmd()
         cmd.id = self.id
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateNetwork(cmd))
+        return (apiclient.updateNetwork(cmd))
 
     def restart(self, apiclient, cleanup=None):
         """Restarts the network"""
@@ -3063,14 +3085,14 @@
         cmd.id = self.id
         if cleanup:
             cmd.cleanup = cleanup
-        return(apiclient.restartNetwork(cmd))
+        return (apiclient.restartNetwork(cmd))
 
     def migrate(self, apiclient, network_offering_id, resume=False):
         cmd = migrateNetwork.migrateNetworkCmd()
         cmd.networkid = self.id
         cmd.networkofferingid = network_offering_id
         cmd.resume = resume
-        return(apiclient.migrateNetwork(cmd))
+        return (apiclient.migrateNetwork(cmd))
 
     @classmethod
     def list(cls, apiclient, **kwargs):
@@ -3080,7 +3102,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetworks(cmd))
+        return (apiclient.listNetworks(cmd))
 
 
 class NetworkACL:
@@ -3157,7 +3179,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetworkACLs(cmd))
+        return (apiclient.listNetworkACLs(cmd))
 
 
 class NetworkACLList:
@@ -3204,7 +3226,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetworkACLLists(cmd))
+        return (apiclient.listNetworkACLLists(cmd))
 
 
 class Vpn:
@@ -3273,14 +3295,14 @@
         """List all VPN Gateways matching criteria"""
         cmd = listVpnGateways.listVpnGatewaysCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listVpnGateways(cmd))
+        return (apiclient.listVpnGateways(cmd))
 
     @classmethod
     def listVpnConnection(cls, apiclient, **kwargs):
         """List all VPN Connections matching criteria"""
         cmd = listVpnConnections.listVpnConnectionsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listVpnConnections(cmd))
+        return (apiclient.listVpnConnections(cmd))
 
     def delete(self, apiclient):
         """Delete remote VPN access"""
@@ -3297,7 +3319,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listRemoteAccessVpns(cmd))
+        return (apiclient.listRemoteAccessVpns(cmd))
 
 
 class VpnUser:
@@ -3343,7 +3365,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVpnUsers(cmd))
+        return (apiclient.listVpnUsers(cmd))
 
 
 class Zone:
@@ -3395,7 +3417,8 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listZones(cmd))
+        return (apiclient.listZones(cmd))
+
 
 class Pod:
     """Manage Pod"""
@@ -3441,6 +3464,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         return apiclient.updatePod(cmd)
 
+
 class PublicIpRange:
     """Manage VlanIpRange"""
 
@@ -3486,7 +3510,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVlanIpRanges(cmd))
+        return (apiclient.listVlanIpRanges(cmd))
 
     @classmethod
     def dedicate(
@@ -3546,7 +3570,8 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listPortableIpRanges(cmd))
+        return (apiclient.listPortableIpRanges(cmd))
+
 
 class SecondaryStagingStore:
     """Manage Staging Store"""
@@ -3582,7 +3607,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listSecondaryStagingStores(cmd))
+        return (apiclient.listSecondaryStagingStores(cmd))
 
 
 class ImageStore:
@@ -3619,7 +3644,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listImageStores(cmd))
+        return (apiclient.listImageStores(cmd))
 
 
 class PhysicalNetwork:
@@ -3678,7 +3703,7 @@
     def release(self, apiclient):
         """Release guest vlan range"""
 
-        cmd = releaseDedicatedGuestVlanRange.\
+        cmd = releaseDedicatedGuestVlanRange. \
             releaseDedicatedGuestVlanRangeCmd()
         cmd.id = self.id
         return apiclient.releaseDedicatedGuestVlanRange(cmd)
@@ -3818,7 +3843,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listSecurityGroups(cmd))
+        return (apiclient.listSecurityGroups(cmd))
 
 
 class VpnCustomerGateway:
@@ -3878,7 +3903,7 @@
             cmd.dpd = services["dpd"]
         if "forceencap" in services:
             cmd.forceencap = services["forceencap"]
-        return(apiclient.updateVpnCustomerGateway(cmd))
+        return (apiclient.updateVpnCustomerGateway(cmd))
 
     def delete(self, apiclient):
         """Delete VPN Customer Gateway"""
@@ -3895,7 +3920,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVpnCustomerGateways(cmd))
+        return (apiclient.listVpnCustomerGateways(cmd))
 
 
 class Project:
@@ -3974,7 +3999,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listProjectAccounts(cmd))
+        return (apiclient.listProjectAccounts(cmd))
 
     @classmethod
     def list(cls, apiclient, **kwargs):
@@ -3984,7 +4009,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listProjects(cmd))
+        return (apiclient.listProjects(cmd))
 
 
 class ProjectInvitation:
@@ -4022,7 +4047,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listProjectInvitations(cmd))
+        return (apiclient.listProjectInvitations(cmd))
 
 
 class Configurations:
@@ -4041,10 +4066,9 @@
         if clusterid:
             cmd.clusterid = clusterid
         if storageid:
-            cmd.storageid=storageid
+            cmd.storageid = storageid
         apiclient.updateConfiguration(cmd)
 
-
     @classmethod
     def list(cls, apiclient, **kwargs):
         """Lists configurations"""
@@ -4053,14 +4077,15 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listConfigurations(cmd))
+        return (apiclient.listConfigurations(cmd))
 
     @classmethod
     def listCapabilities(cls, apiclient, **kwargs):
         """Lists capabilities"""
         cmd = listCapabilities.listCapabilitiesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listCapabilities(cmd))
+        return (apiclient.listCapabilities(cmd))
+
 
 class NetScaler:
     """Manage external netscaler device"""
@@ -4091,12 +4116,12 @@
         url = 'https://' + str(services["ipaddress"]) + '?'
         url = url + 'publicinterface=' + str(services["publicinterface"]) + '&'
         url = url + 'privateinterface=' + \
-            str(services["privateinterface"]) + '&'
+              str(services["privateinterface"]) + '&'
         url = url + 'numretries=' + str(services["numretries"]) + '&'
 
         if "lbdevicecapacity" in services:
             url = url + 'lbdevicecapacity=' + \
-                str(services["lbdevicecapacity"]) + '&'
+                  str(services["lbdevicecapacity"]) + '&'
 
         url = url + 'lbdevicededicated=' + str(services["lbdevicededicated"])
 
@@ -4114,11 +4139,11 @@
     def configure(self, apiclient, **kwargs):
         """List already registered netscaler devices"""
 
-        cmd = configureNetscalerLoadBalancer.\
+        cmd = configureNetscalerLoadBalancer. \
             configureNetscalerLoadBalancerCmd()
         cmd.lbdeviceid = self.lbdeviceid
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.configureNetscalerLoadBalancer(cmd))
+        return (apiclient.configureNetscalerLoadBalancer(cmd))
 
     @classmethod
     def list(cls, apiclient, **kwargs):
@@ -4128,7 +4153,8 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetscalerLoadBalancers(cmd))
+        return (apiclient.listNetscalerLoadBalancers(cmd))
+
 
 class NiciraNvp:
 
@@ -4165,7 +4191,7 @@
         elif services and 'l2gatewayserviceuuid' in services:
             cmd.l2gatewayserviceuuid = services['l2gatewayserviceuuid']
 
-	return NiciraNvp(apiclient.addNiciraNvpDevice(cmd).__dict__)
+        return NiciraNvp(apiclient.addNiciraNvpDevice(cmd).__dict__)
 
     def delete(self, apiclient):
         cmd = deleteNiciraNvpDevice.deleteNiciraNvpDeviceCmd()
@@ -4179,7 +4205,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNiciraNvpDevices(cmd))
+        return (apiclient.listNiciraNvpDevices(cmd))
 
 
 class NetworkServiceProvider:
@@ -4231,7 +4257,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNetworkServiceProviders(cmd))
+        return (apiclient.listNetworkServiceProviders(cmd))
 
 
 class Nuage:
@@ -4286,7 +4312,7 @@
 
         cmd = listNuageVspDevices.listNuageVspDevicesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listNuageVspDevices(cmd))
+        return (apiclient.listNuageVspDevices(cmd))
 
 
 class Router:
@@ -4341,7 +4367,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listRouters(cmd))
+        return (apiclient.listRouters(cmd))
 
 
 class Tag:
@@ -4388,7 +4414,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listTags(cmd))
+        return (apiclient.listTags(cmd))
 
 
 class VpcOffering:
@@ -4422,7 +4448,7 @@
         if "serviceCapabilityList" in services:
             cmd.servicecapabilitylist = []
             for service, capability in \
-                services["serviceCapabilityList"].items():
+                    services["serviceCapabilityList"].items():
                 for ctype, value in capability.items():
                     cmd.servicecapabilitylist.append({
                         'service': service,
@@ -4452,7 +4478,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVPCOfferings(cmd))
+        return (apiclient.listVPCOfferings(cmd))
 
     def delete(self, apiclient):
         """Deletes existing VPC offering"""
@@ -4507,8 +4533,7 @@
         cmd.vpcofferingid = vpc_offering_id
         cmd.tiernetworkofferings = vpc_network_offering_ids
         cmd.resume = resume
-        return(apiclient.migrateVPC(cmd))
-
+        return (apiclient.migrateVPC(cmd))
 
     def delete(self, apiclient):
         """Delete VPC network"""
@@ -4532,7 +4557,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVPCs(cmd))
+        return (apiclient.listVPCs(cmd))
 
 
 class PrivateGateway:
@@ -4574,7 +4599,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listPrivateGateways(cmd))
+        return (apiclient.listPrivateGateways(cmd))
 
 
 class AffinityGroup:
@@ -4611,8 +4636,10 @@
             cmd.listall = True
         return apiclient.listAffinityGroups(cmd)
 
+
 class StaticRoute:
     """Manage static route lifecycle"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -4640,11 +4667,12 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listStaticRoutes(cmd))
+        return (apiclient.listStaticRoutes(cmd))
 
 
 class VNMC:
     """Manage VNMC lifecycle"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -4674,7 +4702,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listCiscoVnmcResources(cmd))
+        return (apiclient.listCiscoVnmcResources(cmd))
 
 
 class SSHKeyPair:
@@ -4718,7 +4746,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listSSHKeyPairs(cmd))
+        return (apiclient.listSSHKeyPairs(cmd))
 
 
 class Capacities:
@@ -4732,7 +4760,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listCapacity(cmd))
+        return (apiclient.listCapacity(cmd))
 
 
 class Alert:
@@ -4746,7 +4774,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listAlerts(cmd))
+        return (apiclient.listAlerts(cmd))
 
 
 class InstanceGroup:
@@ -4825,7 +4853,7 @@
     def changeServiceOffering(self, apiclient, serviceOfferingId):
         """Change service offering of the vm tier"""
 
-        cmd = changeServiceForVirtualMachine.\
+        cmd = changeServiceForVirtualMachine. \
             changeServiceForVirtualMachineCmd()
         cmd.group = self.id
         cmd.serviceofferingid = serviceOfferingId
@@ -4840,6 +4868,7 @@
 
 class ASA1000V:
     """Manage ASA 1000v lifecycle"""
+
     def create(cls, apiclient, hostname, insideportprofile,
                clusterid, physicalnetworkid):
         """Registers ASA 1000v appliance"""
@@ -4866,10 +4895,12 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listCiscoAsa1000vResources(cmd))
+        return (apiclient.listCiscoAsa1000vResources(cmd))
+
 
 class VmSnapshot:
     """Manage VM Snapshot life cycle"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -4893,7 +4924,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listVMSnapshot(cmd))
+        return (apiclient.listVMSnapshot(cmd))
 
     @classmethod
     def revertToSnapshot(cls, apiclient, vmsnapshotid):
@@ -4907,8 +4938,10 @@
         cmd.vmsnapshotid = vmsnapshotid
         return apiclient.deleteVMSnapshot(cmd)
 
+
 class Region:
     """ Regions related Api """
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -5042,7 +5075,8 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listLoadBalancerRules(cmd))
+        return (apiclient.listLoadBalancerRules(cmd))
+
 
 class Resources:
     """Manage resource limits"""
@@ -5058,7 +5092,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listResourceLimits(cmd))
+        return (apiclient.listResourceLimits(cmd))
 
     @classmethod
     def updateLimit(cls, apiclient, **kwargs):
@@ -5066,7 +5100,7 @@
 
         cmd = updateResourceLimit.updateResourceLimitCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateResourceLimit(cmd))
+        return (apiclient.updateResourceLimit(cmd))
 
     @classmethod
     def updateCount(cls, apiclient, **kwargs):
@@ -5074,10 +5108,12 @@
 
         cmd = updateResourceCount.updateResourceCountCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.updateResourceCount(cmd))
+        return (apiclient.updateResourceCount(cmd))
+
 
 class NIC:
     """NIC related API"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -5088,14 +5124,14 @@
         cmd.nicid = id
         if ipaddress:
             cmd.ipaddress = ipaddress
-        return(apiclient.addIpToNic(cmd))
+        return (apiclient.addIpToNic(cmd))
 
     @classmethod
     def removeIp(cls, apiclient, ipaddressid):
         """Remove secondary Ip from NIC"""
         cmd = removeIpFromNic.removeIpFromNicCmd()
         cmd.id = ipaddressid
-        return(apiclient.addIpToNic(cmd))
+        return (apiclient.addIpToNic(cmd))
 
     @classmethod
     def list(cls, apiclient, **kwargs):
@@ -5105,143 +5141,12 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listNics(cmd))
+        return (apiclient.listNics(cmd))
 
-class IAMGroup:
-    def __init__(self, items):
-        self.__dict__.update(items)
-
-    @classmethod
-    def create(cls, apiclient, iam_grp, account=None, domainid=None):
-        cmd = createIAMGroup.createIAMGroupCmd()
-        cmd.name = iam_grp['name']
-        cmd.description = iam_grp['description']
-        if account:
-            cmd.account = account
-        if domainid:
-            cmd.domainid = domainid
-        return IAMGroup(apiclient.createIAMGroup(cmd).__dict__)
-
-    def update(self, apiclient):
-        pass
-
-    def delete(self, apiclient):
-        cmd = deleteIAMGroup.deleteIAMGroupCmd()
-        cmd.id = self.id
-        return apiclient.deleteIAMGroup(cmd)
-
-    @classmethod
-    def list(cls, apiclient, **kwargs):
-        cmd = listIAMGroups.listIAMGroupsCmd()
-        [setattr(cmd, k, v) for k, v in kwargs.items()]
-        if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
-            cmd.listall = True
-        return apiclient.listIAMGroups(cmd)
-
-    def addAccount(self, apiclient, accts):
-        """Add accounts to iam group"""
-        cmd = addAccountToIAMGroup.addAccountToIAMGroupCmd()
-        cmd.id = self.id
-        cmd.accounts = [str(acct.id) for acct in accts]
-        apiclient.addAccountToIAMGroup(cmd)
-        return
-
-    def removeAccount(self, apiclient, accts):
-        """ Remove accounts from iam group"""
-        cmd = removeAccountFromIAMGroup.removeAccountFromIAMGroupCmd()
-        cmd.id = self.id
-        cmd.accounts = [str(acct.id) for acct in accts]
-        apiclient.removeAccountFromIAMGroup(cmd)
-        return
-
-    def attachPolicy(self, apiclient, policies):
-        """Add policies to iam group"""
-        cmd = attachIAMPolicyToIAMGroup.attachIAMPolicyToIAMGroupCmd()
-        cmd.id = self.id
-        cmd.policies = [str(policy.id) for policy in policies]
-        apiclient.attachIAMPolicyToIAMGroup(cmd)
-        return
-
-    def detachPolicy(self, apiclient, policies):
-        """Remove policies from iam group"""
-        cmd = removeIAMPolicyFromIAMGroup.removeIAMPolicyFromIAMGroupCmd()
-        cmd.id = self.id
-        cmd.policies = [str(policy.id) for policy in policies]
-        apiclient.removeIAMPolicyFromIAMGroup(cmd)
-        return
-
-class IAMPolicy:
-    def __init__(self, items):
-        self.__dict__.update(items)
-
-    @classmethod
-    def create(cls, apiclient, iam_policy, account=None, domainid=None):
-        cmd = createIAMPolicy.createIAMPolicyCmd()
-        cmd.name = iam_policy['name']
-        cmd.description = iam_policy['description']
-        if account:
-            cmd.account = account
-        if domainid:
-            cmd.domainid = domainid
-        return IAMPolicy(apiclient.createIAMPolicy(cmd).__dict__)
-
-    def update(self, apiclient):
-        pass
-
-    def delete(self, apiclient):
-        cmd = deleteIAMPolicy.deleteIAMPolicyCmd()
-        cmd.id = self.id
-        return apiclient.deleteIAMPolicy(cmd)
-
-    @classmethod
-    def list(cls, apiclient, **kwargs):
-        cmd = listIAMPolicies.listIAMPoliciesCmd()
-        [setattr(cmd, k, v) for k, v in kwargs.items()]
-        if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
-            cmd.listall = True
-        return apiclient.listIAMPoliciesCmd(cmd)
-
-    def addPermission(self, apiclient, permission):
-        """Add permission to iam policy"""
-        cmd = addIAMPermissionToIAMPolicy.addIAMPermissionToIAMPolicyCmd()
-        cmd.id = self.id
-        cmd.action = permission['action']
-        cmd.entitytype = permission['entitytype']
-        cmd.scope = permission['scope']
-        cmd.scopeid = permission['scopeid']
-        apiclient.addIAMPermissionToIAMPolicy(cmd)
-        return
-
-    def removePermission(self, apiclient, permission):
-        """Remove permission from iam policy"""
-        cmd = removeIAMPermissionFromIAMPolicy.\
-            removeIAMPermissionFromIAMPolicyCmd()
-        cmd.id = self.id
-        cmd.action = permission['action']
-        cmd.entitytype = permission['entitytype']
-        cmd.scope = permission['scope']
-        cmd.scopeid = permission['scopeid']
-        apiclient.removeIAMPermissionFromIAMPolicy(cmd)
-        return
-
-    def attachAccount(self, apiclient, accts):
-        """Attach iam policy to accounts"""
-        cmd = attachIAMPolicyToAccount.attachIAMPolicyToAccountCmd()
-        cmd.id = self.id
-        cmd.accounts = [str(acct.id) for acct in accts]
-        apiclient.attachIAMPolicyToAccount(cmd)
-        return
-
-    def detachAccount(self, apiclient, accts):
-        """Detach iam policy from accounts"""
-        cmd = removeIAMPolicyFromAccount.removeIAMPolicyFromAccountCmd()
-        cmd.id = self.id
-        cmd.accounts = [str(acct.id) for acct in accts]
-        apiclient.removeIAMPolicyFromAccount(cmd)
-        return
 
 class SimulatorMock:
     """Manage simulator mock lifecycle"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -5283,8 +5188,10 @@
         except Exception as e:
             raise e
 
+
 class Usage:
     """Manage Usage Generation"""
+
     def __init__(self, items):
         self.__dict__.update(items)
 
@@ -5295,7 +5202,7 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listUsageRecords(cmd))
+        return (apiclient.listUsageRecords(cmd))
 
     @classmethod
     def listTypes(cls, apiclient, **kwargs):
@@ -5304,14 +5211,15 @@
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         if 'account' in kwargs.keys() and 'domainid' in kwargs.keys():
             cmd.listall = True
-        return(apiclient.listUsageTypes(cmd))
+        return (apiclient.listUsageTypes(cmd))
 
     @classmethod
     def generateRecords(cls, apiclient, **kwargs):
         """Lists domains"""
         cmd = generateUsageRecords.generateUsageRecordsCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.generateUsageRecords(cmd))
+        return (apiclient.generateUsageRecords(cmd))
+
 
 class TrafficType:
     """Manage different traffic types in the setup"""
@@ -5325,7 +5233,8 @@
 
         cmd = listTrafficTypes.listTrafficTypesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listTrafficTypes(cmd))
+        return (apiclient.listTrafficTypes(cmd))
+
 
 class StorageNetworkIpRange:
     """Manage Storage Network Ip Range"""
@@ -5339,7 +5248,8 @@
 
         cmd = listStorageNetworkIpRange.listStorageNetworkIpRangeCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listStorageNetworkIpRange(cmd))
+        return (apiclient.listStorageNetworkIpRange(cmd))
+
 
 class RegisteredServicePackage:
     """Manage ServicePackage registered with NCC"""
@@ -5353,7 +5263,7 @@
 
         cmd = listRegisteredServicePackages.listRegisteredServicePackagesCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
-        return(apiclient.listRegisteredServicePackages(cmd))
+        return (apiclient.listRegisteredServicePackages(cmd))
 
 
 class ResourceDetails:
diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml
index 75a1f8c..6460af7 100644
--- a/tools/marvin/pom.xml
+++ b/tools/marvin/pom.xml
@@ -1,287 +1,293 @@
-<!-- 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. -->
+<!--
+  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-marvin</artifactId>
-  <name>Apache CloudStack marvin</name>
-  <packaging>pom</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloud-tools</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-apidoc</artifactId>
-      <version>${project.version}</version>
-      <type>pom</type>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <defaultGoal>install</defaultGoal>
-    <plugins>
-      <plugin>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>clean</id>
-            <phase>clean</phase>
-            <goals>
-              <goal>run</goal>
-            </goals>
-            <configuration>
-              <target>
-                <delete dir="marvin/cloudstackAPI" />
-                <echo>Deleting ${project.artifactId} API sources</echo>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <id>generate-sources</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-            <configuration>
-              <workingDirectory>${basedir}/marvin</workingDirectory>
-              <executable>python</executable>
-              <arguments>
-                <argument>codegenerator.py</argument>
-                <argument>-s</argument>
-                <argument>${basedir}/../apidoc/target/commands.xml</argument>
-                <echo>Generating ${project.artifactId} API classes}</echo>
-              </arguments>
-            </configuration>
-          </execution>
-          <execution>
-            <id>package</id>
-            <phase>package</phase>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-            <configuration>
-              <workingDirectory>${exec.workingdir}</workingDirectory>
-              <executable>python</executable>
-              <arguments>
-                <argument>mvn-setup.py</argument>
-                <argument>${project.version}</argument>
-                <argument>sdist</argument>
-              </arguments>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <!-- Custom profiles for sync and integration tests -->
-  <profiles>
-    <profile>
-      <id>marvin.sync</id>
-      <activation>
-        <property>
-          <name>endpoint</name>
-          <value>localhost</value>
-        </property>
-      </activation>
-      <build>
+    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-marvin</artifactId>
+    <name>Apache CloudStack marvin</name>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloud-tools</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-apidoc</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+        </dependency>
+    </dependencies>
+    <build>
         <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <id>generate-sources</id>
-                <phase>generate-sources</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <configuration>
-                  <workingDirectory>${basedir}/marvin</workingDirectory>
-                  <executable>python</executable>
-                  <arguments>
-                    <argument>codegenerator.py</argument>
-                    <argument>-e</argument>
-                    <argument>${endpoint}</argument>
-                    <echo>Generating ${project.artifactId} API classes}</echo>
-                  </arguments>
-                </configuration>
-              </execution>
-              <execution>
-                <id>package</id>
-                <phase>package</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <configuration>
-                  <workingDirectory>${exec.workingdir}</workingDirectory>
-                  <executable>python</executable>
-                  <arguments>
-                    <argument>mvn-setup.py</argument>
-                    <argument>${project.version}</argument>
-                    <argument>sdist</argument>
-                  </arguments>
-                </configuration>
-              </execution>
-              <execution>
-                <id>install</id>
-                <phase>install</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <configuration>
-                  <workingDirectory>${basedir}/dist</workingDirectory>
-                  <executable>pip</executable>
-                  <arguments>
-                    <argument>install</argument>
-                    <argument>--allow-external</argument>
-                    <argument>--upgrade</argument>
-                    <argument>Marvin-${project.version}.tar.gz</argument>
-                  </arguments>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>clean</id>
+                        <phase>clean</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target>
+                                <delete dir="marvin/cloudstackAPI" />
+                                <echo>Deleting ${project.artifactId} API sources</echo>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-sources</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${basedir}/marvin</workingDirectory>
+                            <executable>python</executable>
+                            <arguments>
+                                <argument>codegenerator.py</argument>
+                                <argument>-s</argument>
+                                <argument>${basedir}/../apidoc/target/commands.xml</argument>
+                                <echo>Generating ${project.artifactId} API classes}</echo>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>package</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${exec.workingdir}</workingDirectory>
+                            <executable>python</executable>
+                            <arguments>
+                                <argument>mvn-setup.py</argument>
+                                <argument>${project.version}</argument>
+                                <argument>sdist</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>marvin.setup</id>
-      <properties>
-        <marvin.config>${user.dir}/setup/dev/advanced.cfg</marvin.config>
-      </properties>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <version>1.5</version>
-            <executions>
-              <execution>
-                <id>setproperty</id>
-                <phase>validate</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <source>
-                    pom.properties['resolved.basedir']=project.basedir.absolutePath.replace('\','/').replace('D:','/cyg/d');
-                    pom.properties['resolved.userdir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d');
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <id>pre-integration-test</id>
-                <phase>pre-integration-test</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <configuration>
-                  <workingDirectory>${basedir}/marvin</workingDirectory>
-                  <executable>python</executable>
-                  <arguments>
-                   <argument>deployAndRun.py</argument>
-                   <argument>-c</argument>
-                   <argument>${resolved.userdir}/${marvin.config}</argument>
-                   <argument>-d</argument>
-                   <argument>${resolved.basedir}/marvin/testSetupSuccess.py</argument>
-                  </arguments>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>marvin.test</id>
-      <properties>
-        <tag>simulator</tag>
-        <test>test/integration/smoke</test>
-        <marvin.config>${user.dir}/setup/dev/advanced.cfg</marvin.config>
-      </properties>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <version>1.5</version>
-            <executions>
-              <execution>
-                <id>setproperty</id>
-                <phase>validate</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <properties>
-                    <resolved.user.dir>${user.dir}</resolved.user.dir>
-                    <resolved.marvin.config>${marvin.config}</resolved.marvin.config>
-                  </properties>
-                  <source>
-                    project.properties['resolved.user.dir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d');
-                    project.properties['resolved.marvin.config']='${marvin.config}'.replace('\','/').replace('D:','/cyg/d');
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <id>integration-test</id>
-                <phase>integration-test</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-                <configuration>
-                  <workingDirectory>${basedir}/marvin</workingDirectory>
-                  <executable>nosetests</executable>
-                  <arguments>
-                    <argument>--with-marvin</argument>
-                    <argument>--marvin-config</argument>
-                    <argument>${resolved.user.dir}/${resolved.marvin.config}</argument>
-                    <argument>--load</argument>
-                    <argument>-a</argument>
-                    <argument>tags=${tag}</argument>
-                    <argument>${resolved.user.dir}/${test}</argument>
-                    <argument>-v</argument>
-                  </arguments>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+    </build>
+    <!-- Custom profiles for sync and integration tests -->
+    <profiles>
+        <profile>
+            <id>marvin.sync</id>
+            <activation>
+                <property>
+                    <name>endpoint</name>
+                    <value>localhost</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>generate-sources</id>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <workingDirectory>${basedir}/marvin</workingDirectory>
+                                    <executable>python</executable>
+                                    <arguments>
+                                        <argument>codegenerator.py</argument>
+                                        <argument>-e</argument>
+                                        <argument>${endpoint}</argument>
+                                        <echo>Generating ${project.artifactId} API classes}</echo>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>package</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <workingDirectory>${exec.workingdir}</workingDirectory>
+                                    <executable>python</executable>
+                                    <arguments>
+                                        <argument>mvn-setup.py</argument>
+                                        <argument>${project.version}</argument>
+                                        <argument>sdist</argument>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>install</id>
+                                <phase>install</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <workingDirectory>${basedir}/dist</workingDirectory>
+                                    <executable>pip</executable>
+                                    <arguments>
+                                        <argument>install</argument>
+                                        <argument>--allow-external</argument>
+                                        <argument>--upgrade</argument>
+                                        <argument>Marvin-${project.version}.tar.gz</argument>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>marvin.setup</id>
+            <properties>
+                <marvin.config>${user.dir}/setup/dev/advanced.cfg</marvin.config>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.gmaven</groupId>
+                        <artifactId>gmaven-plugin</artifactId>
+                        <version>1.5</version>
+                        <executions>
+                            <execution>
+                                <id>setproperty</id>
+                                <phase>validate</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <source>
+                                        pom.properties['resolved.basedir']=project.basedir.absolutePath.replace('\','/').replace('D:','/cyg/d');
+                                        pom.properties['resolved.userdir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d');
+                                    </source>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>pre-integration-test</id>
+                                <phase>pre-integration-test</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <workingDirectory>${basedir}/marvin</workingDirectory>
+                                    <executable>python</executable>
+                                    <arguments>
+                                        <argument>deployAndRun.py</argument>
+                                        <argument>-c</argument>
+                                        <argument>${resolved.userdir}/${marvin.config}</argument>
+                                        <argument>-d</argument>
+                                        <argument>${resolved.basedir}/marvin/testSetupSuccess.py</argument>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>marvin.test</id>
+            <properties>
+                <tag>simulator</tag>
+                <test>test/integration/smoke</test>
+                <marvin.config>${user.dir}/setup/dev/advanced.cfg</marvin.config>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.gmaven</groupId>
+                        <artifactId>gmaven-plugin</artifactId>
+                        <version>1.5</version>
+                        <executions>
+                            <execution>
+                                <id>setproperty</id>
+                                <phase>validate</phase>
+                                <goals>
+                                    <goal>execute</goal>
+                                </goals>
+                                <configuration>
+                                    <properties>
+                                        <resolved.user.dir>${user.dir}</resolved.user.dir>
+                                        <resolved.marvin.config>${marvin.config}</resolved.marvin.config>
+                                    </properties>
+                                    <source>
+                                        project.properties['resolved.user.dir']='${user.dir}'.replace('\','/').replace('D:','/cyg/d');
+                                        project.properties['resolved.marvin.config']='${marvin.config}'.replace('\','/').replace('D:','/cyg/d');
+                                    </source>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>integration-test</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                                <configuration>
+                                    <workingDirectory>${basedir}/marvin</workingDirectory>
+                                    <executable>nosetests</executable>
+                                    <arguments>
+                                        <argument>--with-marvin</argument>
+                                        <argument>--marvin-config</argument>
+                                        <argument>${resolved.user.dir}/${resolved.marvin.config}</argument>
+                                        <argument>--load</argument>
+                                        <argument>-a</argument>
+                                        <argument>tags=${tag}</argument>
+                                        <argument>${resolved.user.dir}/${test}</argument>
+                                        <argument>-v</argument>
+                                    </arguments>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py
index 8f743ba..3e9c6fe 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.11.4.0-SNAPSHOT"
+VERSION = "4.12.0.0"
 
 setup(name="Marvin",
       version=VERSION,
@@ -55,6 +55,7 @@
           "netaddr >= 0.7.14",
           "dnspython",
           "ipmisim >= 0.7",
+          "pytz",
           "retries",
           "PyCrypt"
       ],
diff --git a/tools/pom.xml b/tools/pom.xml
index d91bd80..e0ccd2f 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -1,42 +1,52 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ 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>
+  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>
     <name>Apache CloudStack Developer Tools</name>
     <artifactId>cloud-tools</artifactId>
     <packaging>pom</packaging>
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack</artifactId>
-        <version>4.11.4.0-SNAPSHOT</version>
+        <version>4.12.0.0</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <build>
-        <defaultGoal>install</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>cloudstack-checkstyle</id>
+                        <phase>none</phase>
+                        <inherited>false</inherited>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
     </build>
     <modules>
         <module>apidoc</module>
         <module>marvin</module>
         <module>devcloud4</module>
-	<module>devcloud-kvm</module>
+        <module>devcloud-kvm</module>
     </modules>
 </project>
diff --git a/tools/whisker/LICENSE b/tools/whisker/LICENSE
index e107c4f..de89620 100644
--- a/tools/whisker/LICENSE
+++ b/tools/whisker/LICENSE
@@ -4726,13 +4726,13 @@
             qunit.css  from http://docs.jquery.com/QUnit
             qunit.js  from http://docs.jquery.com/QUnit
 
-Within the utils/src/com/cloud/utils/db directory
+Within the utils/src/main/java/com/cloud/utils/db directory
     licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt  (as above)
     Copyright (c) 2004 Clinton Begin
         from Clinton Begin  http://code.google.com/p/mybatis/ 
             ScriptRunner.java  from http://code.google.com/p/mybatis/
 
-Within the utils/src/org/apache/commons/httpclient/contrib/ssl directory
+Within the utils/src/main/java/org/apache/commons/httpclient/contrib/ssl directory
     licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt  (as above)
     Copyright (c) 2007 The Apache Software Foundation
         from The Apache Software Foundation  http://www.apache.org/ 
diff --git a/tools/whisker/descriptor-for-packaging.xml b/tools/whisker/descriptor-for-packaging.xml
index 3a7624d..be02601 100644
--- a/tools/whisker/descriptor-for-packaging.xml
+++ b/tools/whisker/descriptor-for-packaging.xml
@@ -2629,7 +2629,7 @@
             </by-organisation>
         </with-license>
     </within>
-    <within dir='utils/src/com/cloud/utils/db'>
+    <within dir='utils/src/main/java/com/cloud/utils/db'>
         <with-license id='ApacheLicenseVersion2'>
             <copyright-notice>
 Copyright (c) 2004 Clinton Begin
@@ -2991,7 +2991,7 @@
                </by-organisation>
         </with-license>
     </within>
-    <within dir='utils/src/org/apache/commons/httpclient/contrib/ssl'>
+    <within dir='utils/src/main/java/org/apache/commons/httpclient/contrib/ssl'>
         <with-license id='ApacheLicenseVersion2'>
             <copyright-notice>
 Copyright (c) 2007 The Apache Software Foundation
diff --git a/tools/whisker/descriptor.xml b/tools/whisker/descriptor.xml
index 8cad773..c64913c 100644
--- a/tools/whisker/descriptor.xml
+++ b/tools/whisker/descriptor.xml
@@ -2609,7 +2609,7 @@
             </by-organisation>
         </with-license>
     </within>
-    <within dir='utils/src/com/cloud/utils/db'>
+    <within dir='utils/src/main/java/com/cloud/utils/db'>
         <with-license id='ApacheLicenseVersion2'>
             <copyright-notice>
 Copyright (c) 2004 Clinton Begin
@@ -2639,7 +2639,7 @@
 			</by-organisation>
 		</with-license>
     </within>
-    <within dir='utils/src/org/apache/commons/httpclient/contrib/ssl'>
+    <within dir='utils/src/main/java/org/apache/commons/httpclient/contrib/ssl'>
         <with-license id='ApacheLicenseVersion2'>
             <copyright-notice>
 Copyright (c) 2007 The Apache Software Foundation
diff --git a/tools/wix-cloudstack-maven-plugin/pom.xml b/tools/wix-cloudstack-maven-plugin/pom.xml
deleted file mode 100644
index 6eb2052..0000000
--- a/tools/wix-cloudstack-maven-plugin/pom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
-  license agreements. See the NOTICE file distributed with this work for additional
-  information regarding copyright ownership. The ASF licenses this file to you under
-  the Apache License, Version 2.0 (the "License"); you may not use this file except
-  in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-  Unless required by applicable law or agreed to in writing, software distributed under
-  the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
-  OF ANY KIND, either express or implied. See the License for the specific language
-  governing permissions and limitations under the License. -->
-<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>Wix-cloudstack-maven-plugin</artifactId>
-  <name>Apache CloudStack - Wix Maven Plugin</name>
-  <packaging>maven-plugin</packaging>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../../pom.xml</relativePath>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-plugin-api</artifactId>
-      <version>${maven-plugin-api.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-exec</artifactId>
-      <version>${commons-exec.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.bitbucket.joxley</groupId>
-      <artifactId>wix-maven-plugin</artifactId>
-      <version>${wix-maven-plugin.version}</version>
-    </dependency>
-  </dependencies>
-
-  <properties>
-    <maven-plugin-api.version>2.0</maven-plugin-api.version>
-    <commons-exec.version>1.1</commons-exec.version>
-    <wix-maven-plugin.version>1.1.1</wix-maven-plugin.version>
-  </properties>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <!-- Ignore/Execute plugin execution -->
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>1.0.0</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-enforcer-plugin</artifactId>
-                    <versionRange>[1.0.0,)</versionRange>
-                    <goals>
-                      <goal>enforce</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore />
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-</project>
diff --git a/tools/wix-cloudstack-maven-plugin/src/org/apache/cloudstack/wix/HeatMojo.java b/tools/wix-cloudstack-maven-plugin/src/org/apache/cloudstack/wix/HeatMojo.java
deleted file mode 100644
index 075908e..0000000
--- a/tools/wix-cloudstack-maven-plugin/src/org/apache/cloudstack/wix/HeatMojo.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.wix;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.bitbucket.joxley.wix.AbstractWixMojo;
-
-/**
- *
- * @goal heat
- *
- * @phase package
- *
- */
-public class HeatMojo extends AbstractWixMojo {
-
-  /**
-   * Directory name to be harvested
-   *
-   * @parameter expression="${dir}"
-   * @required
-   *
-   */
-  private String dir;
-
-  /**
-   * use template, one of: fragment,module,product
-   * @parameter expression="${template}" defaults to fragment
-   *
-   */
-  private String template;
-
-  /**
-   * Output file
-   *
-   * @parameter expression="${outputFile}"
-   */
-  private File outputFile;
-
-  /**
-  *
-  * variable names to be passed to heat command
-  * @parameter expression="${vars}"
-  */
-  private String vars;
-
-  /**
-  *
-  * variable names to be passed to heat command
-  * @parameter expression="${workingDirectory}"
-  */
-  private File workingDirectory;
-
-  /**
-  *
-  * variable names to be passed to heat command
-  * @parameter expression="${componentGroup}"
-  */
-  private String componentGroup;
-
-  /**
-   *
-   * <DirectoryName>  directory reference to root directories
-   * @parameter expression="${directoryName}"
-   */
-  private String directoryName;
-
-  @Override
-  public void execute() throws MojoExecutionException, MojoFailureException {
-    try {
-      CommandLine commandLine = new CommandLine("heat");
-
-      if(dir != null && !dir.trim().isEmpty()) {
-        commandLine.addArgument("dir");
-        commandLine.addArgument(dir);
-      }
-
-      commandLine.addArgument("-gg");
-      commandLine.addArgument("-cg");
-      commandLine.addArgument(componentGroup);
-      commandLine.addArgument("-ke");
-      commandLine.addArgument("-sfrag");
-
-      if(template == null || template.trim().isEmpty()) {
-        commandLine.addArgument("-template");
-        commandLine.addArgument("fragment");
-      } else {
-        commandLine.addArgument("-template");
-        commandLine.addArgument(template);
-      }
-
-      if (outputFile != null) {
-        commandLine.addArgument("-out");
-        commandLine.addArgument(outputFile.getAbsolutePath());
-      }
-
-      if (directoryName != null) {
-        commandLine.addArgument("-dr");
-        commandLine.addArgument(directoryName);
-      }
-
-      if (vars != null) {
-        commandLine.addArguments(vars, false);
-      }
-
-      DefaultExecutor executor = new DefaultExecutor();
-      getLog().debug("working directory " + commandLine.toString());
-      executor.setWorkingDirectory(getWorkingDirectory(workingDirectory));
-      int exitValue = executor.execute(commandLine);
-
-      if (exitValue != 0) {
-        throw new MojoExecutionException(
-            "Problem executing heat, return code " + exitValue);
-      }
-
-    } catch (ExecuteException e) {
-      throw new MojoExecutionException("Problem executing heat", e);
-    } catch (IOException e) {
-      throw new MojoExecutionException("Problem executing heat", e);
-    }
-  }
-
-}
diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index dadc3c9..5294f56 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -3240,6 +3240,7 @@
   height: 12px;
 }
 
+div.toolbar div.button.export:hover,
 div.toolbar div.button.add:hover,
 div.toolbar div.button.refresh:hover,
 div.toolbar div.button.main-action:hover,
@@ -4178,6 +4179,15 @@
   float: left;
 }
 
+.ui-dialog div.form-container div.value label {
+  display: block;
+  width: 119px;
+  text-align: left;
+  font-size: 13px;
+  margin-top: 2px;
+  margin-left: -10px;
+}
+
 .ui-dialog div.form-container div.value input.hasDatepicker {
   color: #2F5D86;
   cursor: pointer;
@@ -8390,7 +8400,6 @@
   border-right: 1px solid #CFC9C9;
   height: 15px;
   overflow: auto;
-  padding-right: 0;
 }
 
 .multi-edit .data .data-body .data-item > table tbody tr td span {
@@ -8425,8 +8434,65 @@
   color: #0000FF;
 }
 
-.multi-edit .data .data-body .data-item table tbody tr td.multi-actions {
-  border-right: none;
+div#details-tab-aclRules table.multi-edit tr th.number,
+div#details-tab-aclRules div.data-item table tr td.number {
+  width: 45px !important;
+  min-width: 45px !important;
+  max-width: 45px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.action,
+div#details-tab-aclRules div.multi-edit table tr td.action {
+    width: 40px !important;
+    min-width: 40px !important;
+    max-width: 40px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.protocol,
+div#details-tab-aclRules div.multi-edit table tr td.protocol {
+    width: 50px !important;
+    min-width: 50px !important;
+    max-width: 50px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.protocolnumber,
+div#details-tab-aclRules div.multi-edit table tr td.protocolnumber {
+    width: 60px !important;
+    min-width: 60px !important;
+    max-width: 60px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.traffictype,
+div#details-tab-aclRules div.multi-edit table tr td.traffictype {
+    width: 60px !important;
+    min-width: 60px !important;
+    max-width: 60px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.reason,
+div#details-tab-aclRules div.multi-edit table tr td.reason {
+    width: 60px !important;
+    min-width: 60px !important;
+    max-width: 60px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.icmptype, div#details-tab-aclRules div.multi-edit table tr td.icmptype,
+div#details-tab-aclRules div.multi-edit table tr th.icmpcode, div#details-tab-aclRules div.multi-edit table tr td.icmpcode {
+    width: 60px !important;
+    min-width: 60px !important;
+    max-width: 60px !important;
+}
+
+div#details-tab-aclRules div.multi-edit table tr th.startport, div#details-tab-aclRules div.multi-edit table tr td.startport,
+div#details-tab-aclRules div.multi-edit table tr th.endport, div#details-tab-aclRules div.multi-edit table tr td.endport {
+    width: 60px !important;
+    min-width: 60px !important;
+    max-width: 60px !important;
+}
+
+div#details-tab-aclRules td.cidrlist span {
+	text-align: center;
+	width: 100%;
 }
 
 .multi-edit .data .data-body .data-item table tbody tr td.multi-actions .action {
@@ -8547,17 +8613,18 @@
 
 .detail-view .multi-edit table tr th,
 .detail-view .multi-edit table tr td {
-  width: 87px !important;
-  min-width: 87px !important;
-  max-width: 87px !important;
+  width: 84px !important;
+  min-width: 84px !important;
+  max-width: 84px !important;
   font-size: 10px;
 }
 
 /* special case for 'Source CIDR' column - make it wide enough to fit a CIDR without ellipsizing*/
 .detail-view .multi-edit table tr th.cidrlist,
 .detail-view .multi-edit table tr td.cidrlist {
-  min-width: 112px !important;
-  max-width: 112px !important;
+  min-width: 118px !important;
+  max-width: 118px !important;
+  padding: 0 0 0 0;
 }
 .detail-view .multi-edit td.cidrlist input {
   width: 85%;
@@ -8614,9 +8681,9 @@
 /*Sortable*/
 .multi-edit table tbody tr td.reorder,
 .multi-edit table thead tr th.reorder {
-  width: 30px !important;
-  min-width: 30px !important;
-  max-width: 30px !important;
+  width: 16px !important;
+  min-width: 16px !important;
+  max-width: 16px !important;
 }
 
 /*Security Rules*/
@@ -9672,7 +9739,8 @@
   top: 68px;
 }
 
-.system-dashboard.zone .status_box li.system-vms .icon {
+.system-dashboard.zone .status_box li.system-vms .icon,
+.system-dashboard.zone .status_box li.management-servers .icon {
   background-position: -408px -399px;
 }
 
@@ -12508,6 +12576,14 @@
   background-position: -169px -583px;
 }
 
+.updateVmwareDc .icon {
+  background-position: -265px -148px;
+}
+
+.updateVmwareDc:hover .icon {
+  background-position: -265px -728px;
+}
+
 .stop .icon,
 .removeVmwareDc .icon,
 .release .icon {
@@ -12804,6 +12880,14 @@
   background-position: -168px -613px;
 }
 
+.diagnostics .icon {
+  background-position: -165px -122px;
+}
+
+.diagnostics:hover .icon {
+  background-position: -165px -704px;
+}
+
 .enableOutOfBandManagement .icon {
   background-position: -138px -65px;
 }
@@ -13038,7 +13122,7 @@
   -khtml-border-radius: 10px;
   border-radius: 10px;
   border-radius: 10px 10px 10px 10px;
-  background-position: -74px -162px;
+  background-position: -82px -162px;
 }
 
 .moveDrag:hover .icon {
@@ -13359,3 +13443,31 @@
     left: 310px;
 }
 
+div.button.export {
+	position: relative;
+	left: 0px;
+	top: 5px;
+	font-size: 12px;
+	font-weight: 100;
+	color: #000000;
+	margin: 0 10px 0 0;
+	cursor: pointer;
+	text-shadow: 0px 1px 1px #DEE5EA;
+	padding: 5px 5px 5px 5px;
+	background: linear-gradient(to bottom, rgba(247,247,247,1) 1%,rgba(234,234,234,1) 100%);
+	border: 1px solid #B7B7B7;
+	float: right;
+	border-radius: 4px 4px 4px 4px;
+	height: 12px;
+}
+
+div.button.export a {
+	padding: 0px 0 3px 20px;
+	background: url(../images/exportCsvIcon.png) no-repeat;
+	position: relative;
+	left: 0px;
+	top: 0px;
+	background-size: 15.5px;
+	text-decoration: none;
+	color: black;
+}
\ No newline at end of file
diff --git a/ui/images/exportCsvIcon.png b/ui/images/exportCsvIcon.png
new file mode 100644
index 0000000..cc486ec
--- /dev/null
+++ b/ui/images/exportCsvIcon.png
Binary files differ
diff --git a/ui/index.html b/ui/index.html
index 3d503c8..6e33598 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -102,7 +102,7 @@
                                     <p><translate key="message.select.a.zone"/></p>
                                     <div class="select-area">
                                         <div class="desc"></div>
-                                        <select name="zoneid" class="required">
+                                        <select name="zoneid" class="required" required>
                                         </select>
                                     </div>
                                 </div>
@@ -1218,6 +1218,15 @@
                                   view-all-title="label.sockets"
                                   view-all-target="sockets"><translate key="label.view.all"/></span>
                         </li>
+                        <li class="block management-servers">
+                            <span class="header"><translate key="label.management.servers"/></span>
+                            <span class="icon">&nbsp;</span>
+                            <span class="overview total" data-item="managementServerCount"></span>
+                            <span class="button view-all clusters"
+                                  tr="label.management.servers" trf="view-all-title"
+                                  view-all-title="label.management.servers"
+                                  view-all-target="managementServers"><translate key="label.view.all"/></span>
+                        </li>
                     </ul>
                 </div>
             </div>
@@ -1775,29 +1784,29 @@
 
             // Inject translated l10n language options
             var l10nDropdown = $($.find('#l10n-options'));
-            l10nDropdown.append($('<option>', {value: 'en', text: translate('label.lang.english')}));
-            l10nDropdown.append($('<option>', {value: 'ja_JP', text: translate('label.lang.japanese')}));
-            l10nDropdown.append($('<option>', {value: 'zh_CN', text: translate('label.lang.chinese')}));
-            l10nDropdown.append($('<option>', {value: 'ru_RU', text: translate('label.lang.russian')}));
-            l10nDropdown.append($('<option>', {value: 'fr_FR', text: translate('label.lang.french')}));
-            l10nDropdown.append($('<option>', {value: 'pt_BR', text: translate('label.lang.brportugese')}));
-            l10nDropdown.append($('<option>', {value: 'ca', text: translate('label.lang.catalan')}));
-            l10nDropdown.append($('<option>', {value: 'ko_KR', text: translate('label.lang.korean')}));
-            l10nDropdown.append($('<option>', {value: 'es', text: translate('label.lang.spanish')}));
-            l10nDropdown.append($('<option>', {value: 'de_DE', text: translate('label.lang.german')}));
-            l10nDropdown.append($('<option>', {value: 'it_IT', text: translate('label.lang.italian')}));
-            l10nDropdown.append($('<option>', {value: 'nb_NO', text: translate('label.lang.norwegian')}));
-            l10nDropdown.append($('<option>', {value: 'ar', text: translate('label.lang.arabic')}));
-            l10nDropdown.append($('<option>', {value: 'nl_NL', text: translate('label.lang.dutch')}));
-            l10nDropdown.append($('<option>', {value: 'pl', text: translate('label.lang.polish')}));
-            l10nDropdown.append($('<option>', {value: 'hu', text: translate('label.lang.hungarian')}));
+            l10nDropdown.append($('<option>', {value: 'en', text: 'English'}));
+            l10nDropdown.append($('<option>', {value: 'ja_JP', text: '日本語'}));
+            l10nDropdown.append($('<option>', {value: 'zh_CN', text: '简体中文'}));
+            l10nDropdown.append($('<option>', {value: 'ru_RU', text: 'Русский'}));
+            l10nDropdown.append($('<option>', {value: 'fr_FR', text: 'Français'}));
+            l10nDropdown.append($('<option>', {value: 'pt_BR', text: 'Português brasileiro'}));
+            l10nDropdown.append($('<option>', {value: 'ca', text: 'Catalan'}));
+            l10nDropdown.append($('<option>', {value: 'ko_KR', text: '한국어'}));
+            l10nDropdown.append($('<option>', {value: 'es', text: 'Españo'}));
+            l10nDropdown.append($('<option>', {value: 'de_DE', text: 'Deutsch'}));
+            l10nDropdown.append($('<option>', {value: 'it_IT', text: 'Italiano'}));
+            l10nDropdown.append($('<option>', {value: 'nb_NO', text: 'Norsk'}));
+            l10nDropdown.append($('<option>', {value: 'ar', text: 'Arabic'}));
+            l10nDropdown.append($('<option>', {value: 'nl_NL', text: 'Nederlands (Nederlands)'}));
+            l10nDropdown.append($('<option>', {value: 'pl', text: 'Polish'}));
+            l10nDropdown.append($('<option>', {value: 'hu', text: 'Magyar'}));
 
             // Inject translated keyboard options
             var keyboardDropdown = $($.find('#keyboard-options'));
-            keyboardDropdown.append($('<option>', {value: 'us', text: translate('label.standard.us.keyboard')}));
-            keyboardDropdown.append($('<option>', {value: 'uk', text: translate('label.uk.keyboard')}));
-            keyboardDropdown.append($('<option>', {value: 'jp', text: translate('label.japanese.keyboard')}));
-            keyboardDropdown.append($('<option>', {value: 'sc', text: translate('label.simplified.chinese.keyboard')}));
+            keyboardDropdown.append($('<option>', {value: 'us', text: 'Standard (US) keyboard'}));
+            keyboardDropdown.append($('<option>', {value: 'uk', text: 'UK keyboard'}));
+            keyboardDropdown.append($('<option>', {value: 'jp', text: '日本語キーボード'}));
+            keyboardDropdown.append($('<option>', {value: 'sc', text: '简体中文键盘'}));
         </script>
 
         <script src="lib/excanvas.js" type="text/javascript"></script>
diff --git a/ui/l10n/ar.js b/ui/l10n/ar.js
index 3b560a8..87c1193 100644
--- a/ui/l10n/ar.js
+++ b/ui/l10n/ar.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP Code",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP Type",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "تغير خصائص العنصر",
     "confirm.enable.s3": "فضلا قم بتعبئة البيانات القادمة لتمكين التخزين S3 للذاكرة الثانوية.",
     "confirm.enable.swift": "Please fill in the following information to enable support for Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Accounts",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Acquire New IP",
     "label.acquire.new.secondary.ip": "Acquire new secondary IP",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "إضافة حسابات",
     "label.add.accounts.to": "إضافة حسابات إلى",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Add new affinity group",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "إضافة مسار",
     "label.add.rule": "إضافة قاعدة",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Add Secondary Storage",
     "label.add.security.group": "Add Security Group",
     "label.add.service.offering": "Add Service Offering",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Disk Write Rate (IOPS)",
     "label.disk.offering": "Disk Offering",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning Type",
     "label.disk.read.bytes": "Disk Read (Bytes)",
@@ -1084,6 +1093,8 @@
     "label.migrate.to.host": "التحول إلى المضيف",
     "label.migrate.to.storage": "التحول إلى التخزين",
     "label.migrate.volume": "Migrate Volume",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
@@ -1140,6 +1151,7 @@
     "label.networks": "الشبكات",
     "label.new": "جديد",
     "label.new.password": "New Password",
+    "label.current.password": "Current Password",
     "label.new.project": "مشروع جديد",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "New VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "المشاريع",
     "label.protocol": "Protocol",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "Providers",
     "label.public": "Public",
@@ -1427,6 +1440,7 @@
     "label.routing": "Routing",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Rule Number",
     "label.rules": "Rules",
     "label.running.vms": "Running VMs",
diff --git a/ui/l10n/ca.js b/ui/l10n/ca.js
index f6ae80f..2580301 100644
--- a/ui/l10n/ca.js
+++ b/ui/l10n/ca.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP Code",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP Type",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Changed item properties",
     "confirm.enable.s3": "Please fill in the following information to enable support for S3-backed Secondary Storage",
     "confirm.enable.swift": "Si us plau ompliu la següent informació per habilitar el suport per a Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Accounts",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Acquire New IP",
     "label.acquire.new.secondary.ip": "Acquire new secondary IP",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Afegir comptes",
     "label.add.accounts.to": "Afegir comptes a",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Add new affinity group",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Add route",
     "label.add.rule": "Afegir regla",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Add Secondary Storage",
     "label.add.security.group": "Add Security Group",
     "label.add.service.offering": "Add Service Offering",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Disk Write Rate (IOPS)",
     "label.disk.offering": "Disk Offering",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning Type",
     "label.disk.read.bytes": "Disk Read (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrate to storage",
     "label.migrate.volume": "Migrate Volume",
     "label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Xarxes",
     "label.new": "Nou",
     "label.new.password": "New Password",
+    "label.current.password": "Current Password",
     "label.new.project": "Nou projecte",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "Nova MV",
@@ -1278,6 +1290,7 @@
     "label.projects": "Projectes",
     "label.protocol": "Protocol",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "Proveïdors",
     "label.public": "Public",
@@ -1427,6 +1440,7 @@
     "label.routing": "Routing",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Rule Number",
     "label.rules": "Rules",
     "label.running.vms": "Running VMs",
diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js
index 934f8f9..cae753e 100644
--- a/ui/l10n/de_DE.js
+++ b/ui/l10n/de_DE.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP-Code",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP-Typ",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Geänderte Eintragseigenschaften",
     "confirm.enable.s3": "Bitte fügen Sie die folgenden Informationen hinzu, um die Unterstützung für \"S3-backed Secondary Storage\" hinzuzufügen",
     "confirm.enable.swift": "Bitte fügen Sie die folgenden Informationen hinzu, um die Unterstützung für Swift zu ermöglichen.",
@@ -99,9 +101,12 @@
     "label.accounts": "Benutzerkonten",
     "label.acl": "ACL",
     "label.acl.id": "ACL-Kennung",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL-Listenregeln",
     "label.acl.name": "ACL-Name",
     "label.acl.replaced": "ACL ersetzt",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Neue IP erwerben",
     "label.acquire.new.secondary.ip": "Neue sekundäre IP erwerben",
     "label.action": "Aktion",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Konten hinzufügen",
     "label.add.accounts.to": "Konten hinzufügen zu",
     "label.add.acl.list": "ACL-Liste hinzufügen",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Neue Affinitätsgruppe hinzufügen",
     "label.add.baremetal.dhcp.device": "Baremetal DHCP-Gerät hinzufügen",
     "label.add.baremetal.rack.configuration": "Baremetal Rackkonfiguration hinzufügen",
@@ -367,6 +373,7 @@
     "label.add.role": "Rolle hinzufügen",
     "label.add.route": "Route hinzufügen",
     "label.add.rule": "Regel hinzufügen",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Sekundärspeicher hinzufügen",
     "label.add.security.group": "Sicherheitsgruppe hinzufügen",
     "label.add.service.offering": "Dienstangebot hinzufügen",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Festplatten-Schreibrate (IOPS)",
     "label.disk.offering": "Festplattenangebot",
     "label.disk.offering.details": "Festplattenangebotdetails",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisionierungstyp",
     "label.disk.read.bytes": "Festplatte Lesen (Bytes)",
@@ -967,6 +976,7 @@
     "label.logout": "Abmelden",
     "label.lun": "LUN",
     "label.lxc.traffic.label": "LXC Datenverkehrs-Bezeichnung",
+    "label.mac.address": "MAC Adresse",
     "label.make.project.owner": "Mache Benutzerkonto zum Projekteigentümer",
     "label.make.redundant": "Redundant machen",
     "label.manage": "Verwalten",
@@ -1085,6 +1095,8 @@
     "label.migrate.to.storage": "Zu Speicher migrieren",
     "label.migrate.volume": "Volumen migrieren",
     "label.migrate.volume.to.primary.storage": "Migriere ein Speichervolumen zu einem anderen Hauptspeicher",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instanzen",
     "label.min.past.the.hr": "min seit Std. vergangen",
     "label.minimum": "Minimum",
@@ -1140,6 +1152,7 @@
     "label.networks": "Netzwerke",
     "label.new": "Neu",
     "label.new.password": "Neues Passwort",
+    "label.current.password": "Current Password",
     "label.new.project": "Neues Projekt",
     "label.new.ssh.key.pair": "Neues SSH-Schlüsselpaar",
     "label.new.vm": "Neue VM",
@@ -1278,6 +1291,7 @@
     "label.projects": "Projekte",
     "label.protocol": "Protokoll",
     "label.protocol.number": "Protokollnummer",
+    "label.protocol.number.short" : "#Protokoll",
     "label.provider": "Anbieter",
     "label.providers": "Anbieter",
     "label.public": "Öffentlich",
@@ -1427,6 +1441,7 @@
     "label.routing": "Routing",
     "label.routing.host": "Routing Host",
     "label.rule": "Regel",
+    "label.rule.number.short": "#Regel",
     "label.rule.number": "Regelnummer",
     "label.rules": "Regeln",
     "label.running.vms": "Laufende VMs",
diff --git a/ui/l10n/en.js b/ui/l10n/en.js
index b9f3682..9f48a6d 100644
--- a/ui/l10n/en.js
+++ b/ui/l10n/en.js
@@ -14,8 +14,11 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-var dictionary = {"ICMP.code":"ICMP Code",
+var dictionary = {
+"ICMP.code":"ICMP Code",
+"ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
 "ICMP.type":"ICMP Type",
+"ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
 "changed.item.properties":"Changed item properties",
 "confirm.enable.s3":"Please fill in the following information to enable support for S3-backed Secondary Storage",
 "confirm.enable.swift":"Please fill in the following information to enable support for Swift",
@@ -99,9 +102,12 @@
 "label.accounts":"Accounts",
 "label.acl":"ACL",
 "label.acl.id":"ACL ID",
+"label.acl.export": "Export ACLs",
 "label.acl.list.rules":"ACL List Rules",
 "label.acl.name":"ACL Name",
 "label.acl.replaced":"ACL replaced",
+"label.acl.reason": "Reason",
+"label.acl.reason.description": "Enter the reason behind an ACL rule.",
 "label.acquire.new.ip":"Acquire New IP",
 "label.acquire.new.secondary.ip":"Acquire new secondary IP",
 "label.action":"Action",
@@ -270,6 +276,7 @@
 "label.action.restore.instance.processing":"Restoring Instance....",
 "label.action.revert.snapshot":"Revert to Snapshot",
 "label.action.revert.snapshot.processing":"Reverting to Snapshot...",
+"label.action.run.diagnostics":"Run Diagnostics",
 "label.action.secure.host":"Provision Host Security Keys",
 "label.action.start.instance":"Start Instance",
 "label.action.start.instance.processing":"Starting Instance....",
@@ -315,6 +322,7 @@
 "label.add.accounts":"Add accounts",
 "label.add.accounts.to":"Add accounts to",
 "label.add.acl.list":"Add ACL List",
+"label.edit.acl.list": "Edit ACL List",
 "label.add.affinity.group":"Add new affinity group",
 "label.add.baremetal.dhcp.device":"Add Baremetal DHCP Device",
 "label.add.baremetal.rack.configuration":"Add Baremetal Rack Configuration",
@@ -371,6 +379,7 @@
 "label.add.role":"Add Role",
 "label.add.route":"Add route",
 "label.add.rule":"Add rule",
+"label.add.rule.desc": "Create a new ACL rule",
 "label.add.secondary.storage":"Add Secondary Storage",
 "label.add.security.group":"Add Security Group",
 "label.add.service.offering":"Add Service Offering",
@@ -502,6 +511,7 @@
 "label.by.type":"By Type",
 "label.by.type.id":"By Type ID",
 "label.by.zone":"By Zone",
+"label.bypass.vlan.overlap.check": "Bypass VLAN id/range overlap",
 "label.bytes.received":"Bytes Received",
 "label.bytes.sent":"Bytes Sent",
 "label.cache.mode":"Write-cache Type",
@@ -631,6 +641,7 @@
 "label.delete.secondary.staging.store":"Delete Secondary Staging Store",
 "label.delete.sslcertificate":"Delete SSL Certificate",
 "label.delete.ucs.manager":"Delete UCS Manager",
+"label.delete.volumes":"Volumes to be deleted",
 "label.delete.vpn.user":"Delete VPN user",
 "label.deleting.failed":"Deleting Failed",
 "label.deleting.processing":"Deleting....",
@@ -672,6 +683,8 @@
 "label.disk.iops.write.rate":"Disk Write Rate (IOPS)",
 "label.disk.offering":"Disk Offering",
 "label.disk.offering.details":"Disk offering details",
+"label.disk.newOffering": "New Disk Offering",
+"label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
 "label.disk.physicalsize":"Physical Size",
 "label.disk.provisioningtype":"Provisioning Type",
 "label.disk.read.bytes":"Disk Read (Bytes)",
@@ -1003,6 +1016,8 @@
 "label.management":"Management",
 "label.management.ips":"Management IP Addresses",
 "label.management.server":"Management Server",
+"label.mac.address": "MAC Address",
+"label.management.servers":"Management Servers",
 "label.mac.address.changes":"MAC Address Changes",
 "label.max.cpus":"Max. CPU cores",
 "label.max.guest.limit":"Max guest limit",
@@ -1114,6 +1129,8 @@
 "label.migrate.to.storage":"Migrate to storage",
 "label.migrate.volume":"Migrate Volume",
 "label.migrate.volume.to.primary.storage":"Migrate volume to another primary storage",
+"label.migrate.volume.newDiskOffering": "Replace disk offering?",
+"label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
 "label.min.instances":"Min Instances",
 "label.min.past.the.hr":"min past the hr",
 "label.minimum":"Minimum",
@@ -1174,6 +1191,7 @@
 "label.networks":"Networks",
 "label.new":"New",
 "label.new.password":"New Password",
+"label.current.password": "Current Password",
 "label.new.project":"New Project",
 "label.new.ssh.key.pair":"New SSH Key Pair",
 "label.new.vm":"New VM",
@@ -1208,6 +1226,7 @@
 "label.number.of.clusters":"Number of Clusters",
 "label.number.of.cpu.sockets":"The Number of CPU Sockets",
 "label.number.of.hosts":"Number of Hosts",
+"label.number.of.management.servers":"Number of Management Servers",
 "label.number.of.pods":"Number of Pods",
 "label.number.of.system.vms":"Number of System VMs",
 "label.number.of.virtual.routers":"Number of Virtual Routers",
@@ -1317,6 +1336,7 @@
 "label.promiscuous.mode":"Promiscuous Mode",
 "label.protocol":"Protocol",
 "label.protocol.number":"Protocol Number",
+"label.protocol.number.short" : "#Protocol",
 "label.provider":"Provider",
 "label.providers":"Providers",
 "label.public":"Public",
@@ -1468,7 +1488,11 @@
 "label.routing.host":"Routing Host",
 "label.rule":"Rule",
 "label.rule.number":"Rule Number",
+"label.rule.number.short": "#Rule",
 "label.rules":"Rules",
+"label.run.diagnostics.type":"Type",
+"label.run.diagnostics.destination":"Destination",
+"label.run.diagnostics.extra":"Extra Arguments",
 "label.running.vms":"Running VMs",
 "label.s3.access_key":"Access Key",
 "label.s3.bucket":"Bucket",
@@ -1691,6 +1715,7 @@
 "label.update.project.resources":"Update project resources",
 "label.update.ssl":" SSL Certificate",
 "label.update.ssl.cert":" SSL Certificate",
+"label.update.vmware.datacenter":"Update VMware datacenter",
 "label.updating":"Updating",
 "label.upgrade.required":"Upgrade is required",
 "label.upgrade.router.newer.template":"Upgrade Router to Use Newer Template",
@@ -1792,6 +1817,8 @@
 "label.volgroup":"Volume Group",
 "label.volume":"Volume",
 "label.volume.details":"Volume details",
+"label.volume.empty":"No volumes attached to this VM",
+"label.volume.ids":"Volume ID's",
 "label.volume.limits":"Volume Limits",
 "label.volume.migrated":"Volume migrated",
 "label.volume.name":"Volume Name",
@@ -2088,6 +2115,9 @@
 "message.desc.zone":"A zone is the largest organizational unit in CloudStack, and it typically corresponds to a single datacenter. Zones provide physical isolation and redundancy. A zone consists of one or more pods (each of which contains hosts and primary storage servers) and a secondary storage server which is shared by all pods in the zone.",
 "message.detach.disk":"Are you sure you want to detach this disk?",
 "message.detach.iso.confirm":"Please confirm that you want to detach the ISO from this virtual instance.",
+"message.diagnostics.exitcode":"exitcode: var",
+"message.diagnostics.stderr":"stderr: var",
+"message.diagnostics.stdout":"stdout: var",
 "message.disable.account":"Please confirm that you want to disable this account.  By disabling the account, all users for this account will no longer have access to their cloud resources.  All running virtual machines will be immediately shut down.",
 "message.disable.snapshot.policy":"You have successfully disabled your current snapshot policy.",
 "message.disable.user":"Please confirm that you would like to disable this user.",
diff --git a/ui/l10n/es.js b/ui/l10n/es.js
index 35257d4..285df3d 100644
--- a/ui/l10n/es.js
+++ b/ui/l10n/es.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "Código ICMP",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "Tipo ICMP",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Cambiadas las propiedades del elemento",
     "confirm.enable.s3": "Por favor, complete la siguiente información para habilitar el soporte del Almacenamiento Secundario sobre S3",
     "confirm.enable.swift": "Por favor, complete la siguiente información para habilitar el soporte para Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Cuentas",
     "label.acl": "ACL",
     "label.acl.id": "ID de ACL",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "Lista de Reglas ACL",
     "label.acl.name": "Nombre de ACL",
     "label.acl.replaced": "ACL reemplazada",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Adquirir nueva IP",
     "label.acquire.new.secondary.ip": "Adquirir nueva IP secundaria",
     "label.action": "Acción",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Agregar Cuentas",
     "label.add.accounts.to": "Agregar Cuentas a",
     "label.add.acl.list": "Agregar Lista ACL",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Agregar un nuevo grupo de afinidad",
     "label.add.baremetal.dhcp.device": "Agregar dispositivo DHCP Baremetal",
     "label.add.baremetal.rack.configuration": "Agregar Configuración de Rack Baremetal",
@@ -367,6 +373,7 @@
     "label.add.role": "Agregar Rol",
     "label.add.route": "Agregar ruta",
     "label.add.rule": "Agregar regla",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Añadir almacenamiento secundario",
     "label.add.security.group": "Agregar grupo de seguridad",
     "label.add.service.offering": "Añadir Oferta de Servicio",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Tasa Escritura de Disco (IOPS)",
     "label.disk.offering": "Oferta de Disco",
     "label.disk.offering.details": "Detalles de Oferta de Disco",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Tipo de Aprovisionamiento",
     "label.disk.read.bytes": "Lectura Disco (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrar a almacenamiento",
     "label.migrate.volume": "Migrar Volumen",
     "label.migrate.volume.to.primary.storage": "Migrar volumen a otro almacenamiento primario",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Instancias Mínimas",
     "label.min.past.the.hr": "minuto(s) después de la hora",
     "label.minimum": "Mínimo",
@@ -1140,6 +1151,7 @@
     "label.networks": "Redes",
     "label.new": "Nuevo",
     "label.new.password": "Nueva contraseña",
+    "label.current.password": "Current Password",
     "label.new.project": "Nuevo Proyecto",
     "label.new.ssh.key.pair": "Nuevo Par de Claves SSH",
     "label.new.vm": "Nueva MV",
@@ -1278,6 +1290,7 @@
     "label.projects": "Proyectos",
     "label.protocol": "Protocolo",
     "label.protocol.number": "Número de Protocolo",
+    "label.protocol.number.short" : "#Protocolo",
     "label.provider": "Proveedor",
     "label.providers": "Proveedores",
     "label.public": "Pública",
@@ -1427,6 +1440,7 @@
     "label.routing": "Enrutamiento",
     "label.routing.host": "Servidor de Routeo",
     "label.rule": "Regla",
+    "label.rule.number.short": "#Regla",
     "label.rule.number": "Número de Regla",
     "label.rules": "Reglas",
     "label.running.vms": "MVs corriendo",
diff --git a/ui/l10n/fr_FR.js b/ui/l10n/fr_FR.js
index 9935a81..88b6cad 100644
--- a/ui/l10n/fr_FR.js
+++ b/ui/l10n/fr_FR.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "Code ICMP",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "Type ICMP",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Propriétés de l'élément modifiées",
     "confirm.enable.s3": "Remplir les informations suivantes pour activer le support de stockage secondaire S3",
     "confirm.enable.swift": "Remplir les informations suivantes pour activer Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Comptes",
     "label.acl": "ACL",
     "label.acl.id": "ID ACL",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "Liste règles ACL",
     "label.acl.name": "Nom ACL",
     "label.acl.replaced": "ACL remplacée",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Acquérir nouvelle adr. IP",
     "label.acquire.new.secondary.ip": "Acquérir nouvelle IP secondaire",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Ajouter des comptes",
     "label.add.accounts.to": "Ajouter des comptes sur",
     "label.add.acl.list": "Ajouter Liste ACL",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Ajouter nouveau groupe d'affinité",
     "label.add.baremetal.dhcp.device": "Ajouter un DHCP Baremetal",
     "label.add.baremetal.rack.configuration": "Ajouter Configuration Rack Baremetal",
@@ -367,6 +373,7 @@
     "label.add.role": "Ajouter Rôle",
     "label.add.route": "Ajouter route",
     "label.add.rule": "Ajouter règle",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Ajouter un stockage secondaire",
     "label.add.security.group": "Ajouter un groupe de sécurité",
     "label.add.service.offering": "Ajouter Offre Service",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Débit écriture disque (IOPS)",
     "label.disk.offering": "Offre de Disque",
     "label.disk.offering.details": "Détails offre de disque",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Type de provisionnement",
     "label.disk.read.bytes": "Lecture Disque (Octets)",
@@ -975,6 +984,7 @@
     "label.management": "Administration",
     "label.management.ips": "Adresses IP de gestion",
     "label.management.server": "Serveur de gestion",
+    "label.management.servers": "Serveurs de gestion",
     "label.max.cpus": "Nombre coeurs CPU max.",
     "label.max.guest.limit": "Nombre maximum d'invités",
     "label.max.instances": "Instance Max.",
@@ -1085,6 +1095,8 @@
     "label.migrate.to.storage": "Migrer vers un stockage",
     "label.migrate.volume": "Volume Migré",
     "label.migrate.volume.to.primary.storage": "Migration du volume vers un autre stockage primaire",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Instances Min.",
     "label.min.past.the.hr": "min ap. l'heure",
     "label.minimum": "Minimum",
@@ -1140,6 +1152,7 @@
     "label.networks": "Réseaux",
     "label.new": "Nouveau",
     "label.new.password": "Nouveau mot de passe",
+    "label.current.password": "Current Password",
     "label.new.project": "Nouveau projet",
     "label.new.ssh.key.pair": "Nouvelle bi-clé SSH",
     "label.new.vm": "Nouvelle VM",
@@ -1172,6 +1185,7 @@
     "label.number.of.clusters": "Nombre de clusters",
     "label.number.of.cpu.sockets": "Le nombre de sockets CPU",
     "label.number.of.hosts": "Nombre d'Hôtes",
+    "label.number.of.management.servers":"Nombre de serveurs de gestion",
     "label.number.of.pods": "Nombre de Pods",
     "label.number.of.system.vms": "Nombre de VM Système",
     "label.number.of.virtual.routers": "Nombre de routeurs virtuels",
@@ -1278,6 +1292,7 @@
     "label.projects": "Projets",
     "label.protocol": "Protocole",
     "label.protocol.number": "Numéro Protocole",
+    "label.protocol.number.short" : "#Protocole",
     "label.provider": "Fournisseur",
     "label.providers": "Fournisseurs",
     "label.public": "Publique",
@@ -1427,6 +1442,7 @@
     "label.routing": "Routage",
     "label.routing.host": "Hôte de routage",
     "label.rule": "Règle",
+    "label.rule.number.short": "#Règle",
     "label.rule.number": "Numéro règle",
     "label.rules": "Règles",
     "label.running.vms": "VMs actives",
diff --git a/ui/l10n/hu.js b/ui/l10n/hu.js
index 912ecf9..2ed1f34 100644
--- a/ui/l10n/hu.js
+++ b/ui/l10n/hu.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP kód",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP típus",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Az elem tulajdonságai megváltoztak",
     "confirm.enable.s3": "Töltsd ki a következő információkat az S3 másodlagos tár bekapcsolásához!",
     "confirm.enable.swift": "Töltsd ki a következő információkat a Swift támogatás bekapcsolásához!",
@@ -99,9 +101,12 @@
     "label.accounts": "Számlák",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL név",
     "label.acl.replaced": "ACL lehelyettesítve",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Új IP cím beszerzése",
     "label.acquire.new.secondary.ip": "Új másodlagos IP cím beszerzése",
     "label.action": "Művelet",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Számlák felvétele",
     "label.add.accounts.to": "Számla felvétele:",
     "label.add.acl.list": "ACL lista felvétele",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Új affinítási csoport felvétele",
     "label.add.baremetal.dhcp.device": "Baremetal DHCP eszköz felvétele",
     "label.add.baremetal.rack.configuration": "Baremetal rack konfiguráció felvétele",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Útvonal felvétele",
     "label.add.rule": "Szabály felvétele",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Másodlagos tár felvétele",
     "label.add.security.group": "Biztonsági csoport felvétele",
     "label.add.service.offering": "Szolgáltatás ajánlat felvétele",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Írási ráta (IOPS)",
     "label.disk.offering": "Merevlemez ajánlat",
     "label.disk.offering.details": "Merevlemez ajánlat részletei",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Létrehozás típusa",
     "label.disk.read.bytes": "Merevlemez olvasás (Byte)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Mozgatás tárra",
     "label.migrate.volume": "Kötet mozgatása",
     "label.migrate.volume.to.primary.storage": "Kötet mozgatása másik elsődleges tárra",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Példányok minimális száma",
     "label.min.past.the.hr": "percben",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Hálózatok",
     "label.new": "Új",
     "label.new.password": "Új jelszó",
+    "label.current.password": "Current Password",
     "label.new.project": "Új projekt",
     "label.new.ssh.key.pair": "Új SSH kulcspár",
     "label.new.vm": "Új VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Projektek",
     "label.protocol": "Protokol",
     "label.protocol.number": "Protokoll szám",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Szolgáltató",
     "label.providers": "Szolgáltatók",
     "label.public": "Publikus",
@@ -1427,6 +1440,7 @@
     "label.routing": "Útvonalválasztás",
     "label.routing.host": "Routing kiszolgáló",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Szabály szám",
     "label.rules": "Szabályok",
     "label.running.vms": "Futó VM-ek",
diff --git a/ui/l10n/it_IT.js b/ui/l10n/it_IT.js
index f725584..c2210ca 100644
--- a/ui/l10n/it_IT.js
+++ b/ui/l10n/it_IT.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "Codice ICMP",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "Tipo ICMP",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Elementi delle proprietà modificati",
     "confirm.enable.s3": "Si prega di inserire i valori richiesti per abilitare il supporto per il Secondary Storage di tipo S3",
     "confirm.enable.swift": "Si prega di inserire i valori richiesti per abilitare il supporto per Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Utenti",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Acquisizione nuovo indirizzo IP",
     "label.acquire.new.secondary.ip": "Acquisizione nuovo IP secondario",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Aggiungere utenti",
     "label.add.accounts.to": "Aggiungere utenti a",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Aggiungere un nuovo gruppo di affinità",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Aggiungere una rotta",
     "label.add.rule": "Aggiungere regola",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Aggiungere uno Storage Secondario",
     "label.add.security.group": "Aggiungere un Gruppo di Sicurezza",
     "label.add.service.offering": "Aggiungere un'Offerta di Servizio",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Disk Write Rate (IOPS)",
     "label.disk.offering": "Offerta Disco",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Tipo di Provisioning",
     "label.disk.read.bytes": "Disk Read (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrare verso uno storage",
     "label.migrate.volume": "Migrate Volume",
     "label.migrate.volume.to.primary.storage": "Migrare un volume verso un altro primary storage",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Reti",
     "label.new": "Nuovo",
     "label.new.password": "New Password",
+    "label.current.password": "Current Password",
     "label.new.project": "Nuovo Progetto",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "Nuova VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Progetti",
     "label.protocol": "Protocol",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "Fornitori",
     "label.public": "Public",
@@ -1427,6 +1440,7 @@
     "label.routing": "Routing",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Rule Number",
     "label.rules": "Regole",
     "label.running.vms": "Running VMs",
diff --git a/ui/l10n/ja_JP.js b/ui/l10n/ja_JP.js
index 40cf38f..db94ca8 100644
--- a/ui/l10n/ja_JP.js
+++ b/ui/l10n/ja_JP.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP コード",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP の種類",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "項目のプロパティの変更",
     "confirm.enable.s3": "S3 ベースのセカンダリ ストレージのサポートを有効にするには、次の情報を入力してください。",
     "confirm.enable.swift": "Swift のサポートを有効にするには、次の情報を入力してください。",
@@ -99,9 +101,12 @@
     "label.accounts": "アカウント",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL ルールのリスト",
     "label.acl.name": "ACL 名",
     "label.acl.replaced": "ACL が置き換えられました",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "新しい IP アドレスの取得",
     "label.acquire.new.secondary.ip": "セカンダリ IP アドレスの取得",
     "label.action": "操作",
@@ -313,6 +318,7 @@
     "label.add.accounts": "アカウントの追加",
     "label.add.accounts.to": "アカウントの追加先:",
     "label.add.acl.list": "ACL 一覧の追加",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "新しいアフィニティ グループの追加",
     "label.add.baremetal.dhcp.device": "ベアメタル DHCP デバイスの追加",
     "label.add.baremetal.rack.configuration": "ベアメタルラック設定の追加",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "ルートの追加",
     "label.add.rule": "規則の追加",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "セカンダリ ストレージの追加",
     "label.add.security.group": "セキュリティ グループの追加",
     "label.add.service.offering": "サービス オファリングの追加",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "ディスク書き込み速度 (IOPS)",
     "label.disk.offering": "ディスク オファリング",
     "label.disk.offering.details": "ディスクオファリングの詳細",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "プロビジョニングの種類",
     "label.disk.read.bytes": "ディスク読み取り (バイト)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "ストレージへ移行",
     "label.migrate.volume": "ボリュームの移行",
     "label.migrate.volume.to.primary.storage": "別のプライマリ ストレージへのボリュームの移行",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "最小インスタンス数",
     "label.min.past.the.hr": "分(毎時)",
     "label.minimum": "最小",
@@ -1140,6 +1151,7 @@
     "label.networks": "ネットワーク",
     "label.new": "新規",
     "label.new.password": "新しいパスワード",
+    "label.current.password": "Current Password",
     "label.new.project": "新しいプロジェクト",
     "label.new.ssh.key.pair": "新しい SSH キーペア",
     "label.new.vm": "新しい VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "プロジェクト",
     "label.protocol": "プロトコル",
     "label.protocol.number": "プロトコル番号",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "プロバイダー",
     "label.providers": "プロバイダー",
     "label.public": "パブリック",
@@ -1427,6 +1440,7 @@
     "label.routing": "ルーティング",
     "label.routing.host": "ルーティング ホスト",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "規則番号",
     "label.rules": "規則",
     "label.running.vms": "実行中の VM",
diff --git a/ui/l10n/ko_KR.js b/ui/l10n/ko_KR.js
index f6980bc..52cd183 100644
--- a/ui/l10n/ko_KR.js
+++ b/ui/l10n/ko_KR.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP 코드",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP 종류",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "항목 속성 변경",
     "confirm.enable.s3": "S3 기반 2차 저장소 지원을 하려면 아래 정보를 입력해 주십시오.",
     "confirm.enable.swift": "Swift 기술 지원를 사용 하려면 다음 정보를 입력해 주십시오.",
@@ -99,9 +101,12 @@
     "label.accounts": "계정 정보",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "새로운 IP 주소 취득",
     "label.acquire.new.secondary.ip": "새로운 두번째 IP 주소 취득",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "계정 정보 추가",
     "label.add.accounts.to": "계정 정보 추가:",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Add new affinity group",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "라우트 추가",
     "label.add.rule": "규칙 추가",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "2차 스토리지 추가",
     "label.add.security.group": "보안 그룹 추가",
     "label.add.service.offering": "서비스제공 추가",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Disk Write Rate (IOPS)",
     "label.disk.offering": "디스크 제공",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning Type",
     "label.disk.read.bytes": "Disk Read (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrate to storage",
     "label.migrate.volume": "Migrate Volume",
     "label.migrate.volume.to.primary.storage": "다른 기본 스토리지에 볼륨 이전",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
     "label.minimum": "최소",
@@ -1140,6 +1151,7 @@
     "label.networks": "네트워크",
     "label.new": "신규",
     "label.new.password": "새로운 암호",
+    "label.current.password": "Current Password",
     "label.new.project": "새 프로젝트",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "새 VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "프로젝트",
     "label.protocol": "프로토콜",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "제공자",
     "label.public": "공개",
@@ -1427,6 +1440,7 @@
     "label.routing": "라우팅",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Rule Number",
     "label.rules": "규칙",
     "label.running.vms": "실행중 VM",
diff --git a/ui/l10n/nb_NO.js b/ui/l10n/nb_NO.js
index 28cd09c..fbe3bba 100644
--- a/ui/l10n/nb_NO.js
+++ b/ui/l10n/nb_NO.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP-kode",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP-type",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Endrede egenskaper",
     "confirm.enable.s3": "Vennligst fyll inn følgende informasjon for å aktivere støtte for S3-støttet sekundærlagring",
     "confirm.enable.swift": "Vennligst fyll inn følgende informasjon for å aktivere støtte for Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Kontoer",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL Liste Regler",
     "label.acl.name": "ACL Navn",
     "label.acl.replaced": "ACL erstattet",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Tilegne ny IP",
     "label.acquire.new.secondary.ip": "Tilegne ny sekundær IP",
     "label.action": "Handling",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Legg til kontoer",
     "label.add.accounts.to": "Legg kontoer til",
     "label.add.acl.list": "Legg til ACL liste",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Legg til affinitetsgruppe",
     "label.add.baremetal.dhcp.device": "Legg Til Barmetall DHCP Enhet",
     "label.add.baremetal.rack.configuration": "Legg Til Barmetall Rack Konfigurering",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Legg til rute",
     "label.add.rule": "Legg til regel",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Legg til sekundærlagring",
     "label.add.security.group": "Legg til sikkerhetsgruppe",
     "label.add.service.offering": "Legg til tjenestetilbud",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Diskskrivehastighet (IOPS)",
     "label.disk.offering": "Disktilbud",
     "label.disk.offering.details": "Disktilbud detaljer",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisjoneringstype",
     "label.disk.read.bytes": "Disk lese (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrer til lagring",
     "label.migrate.volume": "Migrer volum",
     "label.migrate.volume.to.primary.storage": "Migrer volumet til en annen primærlagring.",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instanser",
     "label.min.past.the.hr": "minutter etter time",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Nettverk",
     "label.new": "Ny",
     "label.new.password": "Nytt passord",
+    "label.current.password": "Current Password",
     "label.new.project": "Nytt prosjekt",
     "label.new.ssh.key.pair": "Nytt SSH-nøkkelpar",
     "label.new.vm": "Ny VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Prosjekter",
     "label.protocol": "Protokoll",
     "label.protocol.number": "Protokollnummer",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Tilbyder",
     "label.providers": "Tilbydere",
     "label.public": "Offentlig",
@@ -1427,6 +1440,7 @@
     "label.routing": "Ruting",
     "label.routing.host": "Ruter Vert",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Regel",
     "label.rule.number": "Regelnummer",
     "label.rules": "Regler",
     "label.running.vms": "Kjørende VMer",
diff --git a/ui/l10n/nl_NL.js b/ui/l10n/nl_NL.js
index 4508241..d1a96da 100644
--- a/ui/l10n/nl_NL.js
+++ b/ui/l10n/nl_NL.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP Code",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP Type",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Item eigenschappen gewijzigd",
     "confirm.enable.s3": "Vul de volgende informatie in om ondersteuning voor S3-aangestuurde Secundaire Opslag te activeren",
     "confirm.enable.swift": "Vul de volgende informatie in om ondersteuning voor Swift te activeren",
@@ -99,9 +101,12 @@
     "label.accounts": "Accounts",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL lijst regels",
     "label.acl.name": "ACL naam",
     "label.acl.replaced": "ACL vervangen",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Bemachtig nieuw IP",
     "label.acquire.new.secondary.ip": "Verkrijg nieuw secundair IP",
     "label.action": "Actie",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Voeg accounts toe",
     "label.add.accounts.to": "Voeg accounts toe aan",
     "label.add.acl.list": "voeg een ACL lijst toe",
+    "label.edit.acl.list": "Verander een ACL lijst",
     "label.add.affinity.group": "Nieuwe affinity groep toevoegen",
     "label.add.baremetal.dhcp.device": "Voeg Baremetal DHCP Apparaat toe",
     "label.add.baremetal.rack.configuration": "voeg baremetal rek configuratie toe",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Route toevoegen",
     "label.add.rule": "Regel toevoegen",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Secundaire Opslag toevoegen",
     "label.add.security.group": "Security Group toevoegen",
     "label.add.service.offering": "Service Aanbieding toevoegen",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Schrijf snelheid Schijf (IOPS)",
     "label.disk.offering": "Schijf Aanbieding",
     "label.disk.offering.details": "schijfe offerte gegevens",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning type",
     "label.disk.read.bytes": "Schijf lezen (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migreer naar opslag",
     "label.migrate.volume": "Migreer volume",
     "label.migrate.volume.to.primary.storage": "Migreer volume naar andere primaire opslag",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min na het uur",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Netwerken",
     "label.new": "Nieuw",
     "label.new.password": "Nieuw wachtwoord",
+    "label.current.password": "Current Password",
     "label.new.project": "Nieuw Project",
     "label.new.ssh.key.pair": "nieuw SSH sleutelpaar",
     "label.new.vm": "Nieuwe VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Projecten",
     "label.protocol": "Protocol",
     "label.protocol.number": "protocol nummer",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "Providers",
     "label.public": "Publiek",
@@ -1427,6 +1440,7 @@
     "label.routing": "Routing",
     "label.routing.host": "routeer machine",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Regel Nummer",
     "label.rules": "Regels",
     "label.running.vms": "Draaiende VMs",
diff --git a/ui/l10n/pl.js b/ui/l10n/pl.js
index 30c04b9..ccac03c 100644
--- a/ui/l10n/pl.js
+++ b/ui/l10n/pl.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP Code",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP Type",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Changed item properties",
     "confirm.enable.s3": "Please fill in the following information to enable support for S3-backed Secondary Storage",
     "confirm.enable.swift": "Please fill in the following information to enable support for Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Konta",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Acquire New IP",
     "label.acquire.new.secondary.ip": "Acquire new secondary IP",
     "label.action": "Action",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Dodaj konta",
     "label.add.accounts.to": "Dodaj konto do",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Add new affinity group",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Add route",
     "label.add.rule": "Dodaj regułę",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Add Secondary Storage",
     "label.add.security.group": "Add Security Group",
     "label.add.service.offering": "Add Service Offering",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Disk Write Rate (IOPS)",
     "label.disk.offering": "Disk Offering",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning Type",
     "label.disk.read.bytes": "Disk Read (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrate to storage",
     "label.migrate.volume": "Migrate Volume",
     "label.migrate.volume.to.primary.storage": "Migrate volume to another primary storage",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
     "label.minimum": "Minimum",
@@ -1140,6 +1151,7 @@
     "label.networks": "Sieci",
     "label.new": "Nowy",
     "label.new.password": "New Password",
+    "label.current.password": "Current Password",
     "label.new.project": "Nowy projekt",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "New VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Projekty",
     "label.protocol": "Protokół",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Provider",
     "label.providers": "Dostawcy",
     "label.public": "Pobliczny",
@@ -1427,6 +1440,7 @@
     "label.routing": "Routing",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Rule Number",
     "label.rules": "Zasady",
     "label.running.vms": "Running VMs",
diff --git a/ui/l10n/pt_BR.js b/ui/l10n/pt_BR.js
index ccfa59a..06b8553 100644
--- a/ui/l10n/pt_BR.js
+++ b/ui/l10n/pt_BR.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "Código ICMP",
+    "ICMP.code.desc": "Informe -1, se vocês quiser permitir todos os códigos ICMP.",
     "ICMP.type": "Tipo ICMP",
+    "ICMP.type.desc": "Informe -1, se vocês quiser permitir todos os tipos ICMP.",
     "changed.item.properties": "Propriedades do item alteradas",
     "confirm.enable.s3": "Por favor, preencha as informações abaixo para habilitar suporte o Storage Secundário fornecido por S3",
     "confirm.enable.swift": "Por favor, preencha as informações abaixo para habilitar suporte ao Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Contas",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "Lista de regas de ACL",
     "label.acl.name": "Nome da ACL",
     "label.acl.replaced": "ACL trocado",
+    "label.acl.reason": "Motivo",
+    "label.acl.reason.description": "Motivo para se utilizar a regra.",
     "label.acquire.new.ip": "Adquirir novo IP",
     "label.acquire.new.secondary.ip": "Adquira um novo IP secundário",
     "label.action": "Ação",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Adicionar contas",
     "label.add.accounts.to": "Adicionar contas para",
     "label.add.acl.list": "Adiciona Lista ACL",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Adicionar um grupo de afinidade",
     "label.add.baremetal.dhcp.device": "Adiciona Dispositivo DHCP Baremetal",
     "label.add.baremetal.rack.configuration": "Adicionar Configuração de Rack de Baremetal",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Adicionar rota",
     "label.add.rule": "Adicionar regra",
+    "label.add.rule.desc": "Criar nova regra ACL",
     "label.add.secondary.storage": "Adicionar Storage Secundário",
     "label.add.security.group": "Adicionar Security Group",
     "label.add.service.offering": "Adicionar Plano",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Taxa de Escrita no Disco (IOPS)",
     "label.disk.offering": "Oferta de Disco",
     "label.disk.offering.details": "Detalhes da oferta de disco",
+    "label.disk.newOffering": "Nova oferta de disco",
+    "label.disk.newOffering.description": "Oferta de disco a ser aplicada no volume após migração.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Tipo de Provisionamento",
     "label.disk.read.bytes": "Leitura do Disco (Bytes)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Migrar para storage",
     "label.migrate.volume": "Migrar Volume",
     "label.migrate.volume.to.primary.storage": "Migrar volume para outro storage primário",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Instâncias Min",
     "label.min.past.the.hr": "minutos passados da última hora",
     "label.minimum": "Mí­nimo",
@@ -1140,6 +1151,7 @@
     "label.networks": "Redes",
     "label.new": "Novo",
     "label.new.password": "Nova Senha",
+    "label.current.password": "Senha Antiga",
     "label.new.project": "Novo Projeto",
     "label.new.ssh.key.pair": "Novo par de chaves SSH",
     "label.new.vm": "Nova VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "Projetos",
     "label.protocol": "Protocolo",
     "label.protocol.number": "Número do Protocolo",
+    "label.protocol.number.short" : "#Protocolo",
     "label.provider": "Provedor",
     "label.providers": "Providers",
     "label.public": "Público",
@@ -1427,6 +1440,7 @@
     "label.routing": "Roteamento",
     "label.routing.host": "Host de Roteamento",
     "label.rule": "Regra",
+    "label.rule.number.short": "#Regra",
     "label.rule.number": "Regra Número",
     "label.rules": "Regras",
     "label.running.vms": "VMs Rodando",
diff --git a/ui/l10n/ru_RU.js b/ui/l10n/ru_RU.js
index 6a11b38..a61fe1e 100644
--- a/ui/l10n/ru_RU.js
+++ b/ui/l10n/ru_RU.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "Код ICMP",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "Тип ICMP",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "Параметры элемента изменены",
     "confirm.enable.s3": "Заполните информацию для включения  S3-совместимого дополнительного хранилища",
     "confirm.enable.swift": "Заполните нижеследующую информацию для включения поддержи Swift",
@@ -99,9 +101,12 @@
     "label.accounts": "Учётные записи",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL List Rules",
     "label.acl.name": "ACL Name",
     "label.acl.replaced": "ACL replaced",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "Получить новый IP",
     "label.acquire.new.secondary.ip": "Запросить дополнительный IP-адрес",
     "label.action": "Действия",
@@ -313,6 +318,7 @@
     "label.add.accounts": "Добавить учётные записи",
     "label.add.accounts.to": "Добавить учётные записи",
     "label.add.acl.list": "Add ACL List",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "Добавить новую affinity group",
     "label.add.baremetal.dhcp.device": "Add Baremetal DHCP Device",
     "label.add.baremetal.rack.configuration": "Add Baremetal Rack Configuration",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "Добавить маршрут",
     "label.add.rule": "Добавить правило",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "Добавить дополнительное хранилище",
     "label.add.security.group": "Добавить группу безопасности",
     "label.add.service.offering": "Добавить службу",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "Скорость записи диска (IOPS)",
     "label.disk.offering": "Услуга дискового пространства",
     "label.disk.offering.details": "Disk offering details",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "Provisioning Type",
     "label.disk.read.bytes": "Прочитано с диска (Байт)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "Перенести на хранилище",
     "label.migrate.volume": "Перенос диска",
     "label.migrate.volume.to.primary.storage": "Перенести диск в другое основное хранилище",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "Min Instances",
     "label.min.past.the.hr": "min past the hr",
     "label.minimum": "Минимум",
@@ -1140,6 +1151,7 @@
     "label.networks": "Сети",
     "label.new": "Создать",
     "label.new.password": "Новый пароль",
+    "label.current.password": "Current Password",
     "label.new.project": "Новый проект",
     "label.new.ssh.key.pair": "New SSH Key Pair",
     "label.new.vm": "Новая ВМ",
@@ -1278,6 +1290,7 @@
     "label.projects": "Проекты",
     "label.protocol": "Протокол",
     "label.protocol.number": "Protocol Number",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "Поставщики",
     "label.providers": "Поставщики",
     "label.public": "Публичный",
@@ -1427,6 +1440,7 @@
     "label.routing": "Маршрутизация",
     "label.routing.host": "Routing Host",
     "label.rule": "Rule",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "Номер правила",
     "label.rules": "Правила",
     "label.running.vms": "Запущенные ВМ",
diff --git a/ui/l10n/zh_CN.js b/ui/l10n/zh_CN.js
index dc44fdb..6015f41 100644
--- a/ui/l10n/zh_CN.js
+++ b/ui/l10n/zh_CN.js
@@ -16,7 +16,9 @@
 // under the License.
 var dictionary = {
     "ICMP.code": "ICMP 代码",
+    "ICMP.code.desc": "Please specify -1 if you want to allow all ICMP codes",
     "ICMP.type": "ICMP 类型",
+    "ICMP.type.desc": "Please specify -1 if you want to allow all ICMP types.",
     "changed.item.properties": "更改项目属性",
     "confirm.enable.s3": "请填写以下信息以启用对 S3 支持的二级存储的支持",
     "confirm.enable.swift": "请填写以下信息以启用对 SWIFT 的支持",
@@ -99,9 +101,12 @@
     "label.accounts": "帐户",
     "label.acl": "ACL",
     "label.acl.id": "ACL ID",
+    "label.acl.export": "Export ACLs",
     "label.acl.list.rules": "ACL列表策略",
     "label.acl.name": "ACL 名称",
     "label.acl.replaced": "ACL 已替换",
+    "label.acl.reason": "Reason",
+    "label.acl.reason.description": "Enter the reason behind an ACL rule.",
     "label.acquire.new.ip": "获取新 IP",
     "label.acquire.new.secondary.ip": "获取新二级 IP",
     "label.action": "操作",
@@ -313,6 +318,7 @@
     "label.add.accounts": "添加帐户",
     "label.add.accounts.to": "添加帐户至",
     "label.add.acl.list": "添加 ACL 列表",
+    "label.edit.acl.list": "Edit ACL List",
     "label.add.affinity.group": "添加新关联性组",
     "label.add.baremetal.dhcp.device": "添加裸机 DHCP 设备",
     "label.add.baremetal.rack.configuration": "添加 Baremetal Rack 配置",
@@ -367,6 +373,7 @@
     "label.add.role": "Add Role",
     "label.add.route": "添加路由",
     "label.add.rule": "添加规则",
+    "label.add.rule.desc": "Create a new ACL rule",
     "label.add.secondary.storage": "添加二级存储",
     "label.add.security.group": "添加安全组",
     "label.add.service.offering": "添加服务方案",
@@ -659,6 +666,8 @@
     "label.disk.iops.write.rate": "磁盘写入速度(IOPS)",
     "label.disk.offering": "磁盘方案",
     "label.disk.offering.details": "磁盘方案详情",
+    "label.disk.newOffering": "New Disk Offering",
+    "label.disk.newOffering.description": "New disk offering to be used by this volume after the migration.",
     "label.disk.physicalsize":"Physical Size",
     "label.disk.provisioningtype": "置备类型",
     "label.disk.read.bytes": "磁盘读取(字节)",
@@ -1085,6 +1094,8 @@
     "label.migrate.to.storage": "迁移到存储",
     "label.migrate.volume": "迁移卷",
     "label.migrate.volume.to.primary.storage": "将卷迁移到其他主存储",
+    "label.migrate.volume.newDiskOffering": "Replace disk offering?",
+    "label.migrate.volume.newDiskOffering.desc": "This option allows administrators to replace the old disk offering, using one that better suits the new placement of the volume.",
     "label.min.instances": "最小实例数",
     "label.min.past.the.hr": "分 每小时",
     "label.minimum": "最小值",
@@ -1140,6 +1151,7 @@
     "label.networks": "网络",
     "label.new": "新建",
     "label.new.password": "新密码",
+    "label.current.password": "Current Password",
     "label.new.project": "新建项目",
     "label.new.ssh.key.pair": "新SSH密钥对",
     "label.new.vm": "新建 VM",
@@ -1278,6 +1290,7 @@
     "label.projects": "项目",
     "label.protocol": "协议",
     "label.protocol.number": "协议编号",
+    "label.protocol.number.short" : "#Protocol",
     "label.provider": "提供程序",
     "label.providers": "提供程序",
     "label.public": "公用",
@@ -1427,6 +1440,7 @@
     "label.routing": "正在路由",
     "label.routing.host": "正在路由主机",
     "label.rule": "规则",
+    "label.rule.number.short": "#Rule",
     "label.rule.number": "规则编号",
     "label.rules": "规则",
     "label.running.vms": "正在运行的 VM",
diff --git a/ui/lib/flot/jquery.colorhelpers.js b/ui/lib/flot/jquery.colorhelpers.js
index d3524d7..7a0414e 100644
--- a/ui/lib/flot/jquery.colorhelpers.js
+++ b/ui/lib/flot/jquery.colorhelpers.js
@@ -18,162 +18,163 @@
  *
  * V. 1.1: Fix error handling so e.g. parsing an empty string does
  * produce a color rather than just crashing.
- */ 
+ */
 
 (function($) {
-    $.color = {};
+  $.color = {};
 
-    // construct color object with some convenient chainable helpers
-    $.color.make = function (r, g, b, a) {
-        var o = {};
-        o.r = r || 0;
-        o.g = g || 0;
-        o.b = b || 0;
-        o.a = a != null ? a : 1;
+  // construct color object with some convenient chainable helpers
+  $.color.make = function (r, g, b, a) {
+    var o = {};
+    o.r = r || 0;
+    o.g = g || 0;
+    o.b = b || 0;
+    o.a = a != null ? a : 1;
 
-        o.add = function (c, d) {
-            for (var i = 0; i < c.length; ++i)
-                o[c.charAt(i)] += d;
-            return o.normalize();
-        };
-        
-        o.scale = function (c, f) {
-            for (var i = 0; i < c.length; ++i)
-                o[c.charAt(i)] *= f;
-            return o.normalize();
-        };
-        
-        o.toString = function () {
-            if (o.a >= 1.0) {
-                return "rgb("+[o.r, o.g, o.b].join(",")+")";
-            } else {
-                return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
-            }
-        };
-
-        o.normalize = function () {
-            function clamp(min, value, max) {
-                return value < min ? min: (value > max ? max: value);
-            }
-            
-            o.r = clamp(0, parseInt(o.r), 255);
-            o.g = clamp(0, parseInt(o.g), 255);
-            o.b = clamp(0, parseInt(o.b), 255);
-            o.a = clamp(0, o.a, 1);
-            return o;
-        };
-
-        o.clone = function () {
-            return $.color.make(o.r, o.b, o.g, o.a);
-        };
-
-        return o.normalize();
-    }
-
-    // extract CSS color property from element, going up in the DOM
-    // if it's "transparent"
-    $.color.extract = function (elem, css) {
-        var c;
-        do {
-            c = elem.css(css).toLowerCase();
-            // keep going until we find an element that has color, or
-            // we hit the body
-            if (c != '' && c != 'transparent')
-                break;
-            elem = elem.parent();
-        } while (!$.nodeName(elem.get(0), "body"));
-
-        // catch Safari's way of signalling transparent
-        if (c == "rgba(0, 0, 0, 0)")
-            c = "transparent";
-        
-        return $.color.parse(c);
-    }
-    
-    // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
-    // returns color object, if parsing failed, you get black (0, 0,
-    // 0) out
-    $.color.parse = function (str) {
-        var res, m = $.color.make;
-
-        // Look for rgb(num,num,num)
-        if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
-            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
-        
-        // Look for rgba(num,num,num,num)
-        if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
-            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
-            
-        // Look for rgb(num%,num%,num%)
-        if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
-            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
-
-        // Look for rgba(num%,num%,num%,num)
-        if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
-            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
-        
-        // Look for #a0b1c2
-        if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
-            return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
-
-        // Look for #fff
-        if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
-            return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
-
-        // Otherwise, we're most likely dealing with a named color
-        var name = $.trim(str).toLowerCase();
-        if (name == "transparent")
-            return m(255, 255, 255, 0);
-        else {
-            // default to black
-            res = lookupColors[name] || [0, 0, 0];
-            return m(res[0], res[1], res[2]);
-        }
-    }
-    
-    var lookupColors = {
-        aqua:[0,255,255],
-        azure:[240,255,255],
-        beige:[245,245,220],
-        black:[0,0,0],
-        blue:[0,0,255],
-        brown:[165,42,42],
-        cyan:[0,255,255],
-        darkblue:[0,0,139],
-        darkcyan:[0,139,139],
-        darkgrey:[169,169,169],
-        darkgreen:[0,100,0],
-        darkkhaki:[189,183,107],
-        darkmagenta:[139,0,139],
-        darkolivegreen:[85,107,47],
-        darkorange:[255,140,0],
-        darkorchid:[153,50,204],
-        darkred:[139,0,0],
-        darksalmon:[233,150,122],
-        darkviolet:[148,0,211],
-        fuchsia:[255,0,255],
-        gold:[255,215,0],
-        green:[0,128,0],
-        indigo:[75,0,130],
-        khaki:[240,230,140],
-        lightblue:[173,216,230],
-        lightcyan:[224,255,255],
-        lightgreen:[144,238,144],
-        lightgrey:[211,211,211],
-        lightpink:[255,182,193],
-        lightyellow:[255,255,224],
-        lime:[0,255,0],
-        magenta:[255,0,255],
-        maroon:[128,0,0],
-        navy:[0,0,128],
-        olive:[128,128,0],
-        orange:[255,165,0],
-        pink:[255,192,203],
-        purple:[128,0,128],
-        violet:[128,0,128],
-        red:[255,0,0],
-        silver:[192,192,192],
-        white:[255,255,255],
-        yellow:[255,255,0]
+    o.add = function (c, d) {
+      for (var i = 0; i < c.length; ++i)
+        o[c.charAt(i)] += d;
+      return o.normalize();
     };
+
+    o.scale = function (c, f) {
+      for (var i = 0; i < c.length; ++i)
+        o[c.charAt(i)] *= f;
+      return o.normalize();
+    };
+
+    o.toString = function () {
+      if (o.a >= 1.0) {
+        return "rgb("+[o.r, o.g, o.b].join(",")+")";
+      } else {
+        return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
+      }
+    };
+
+    o.normalize = function () {
+      function clamp(min, value, max) {
+        return value < min ? min: (value > max ? max: value);
+      }
+
+      o.r = clamp(0, parseInt(o.r), 255);
+      o.g = clamp(0, parseInt(o.g), 255);
+      o.b = clamp(0, parseInt(o.b), 255);
+      o.a = clamp(0, o.a, 1);
+      return o;
+    };
+
+    o.clone = function () {
+      return $.color.make(o.r, o.b, o.g, o.a);
+    };
+
+    return o.normalize();
+  }
+
+  // extract CSS color property from element, going up in the DOM
+  // if it's "transparent"
+  $.color.extract = function (elem, css) {
+    var c;
+
+    do {
+      c = elem.css(css).toLowerCase();
+      // keep going until we find an element that has color, or
+      // we hit the body or root (have no parent)
+      if (c != '' && c != 'transparent')
+        break;
+      elem = elem.parent();
+    } while (elem.length && !$.nodeName(elem.get(0), "body"));
+
+    // catch Safari's way of signalling transparent
+    if (c == "rgba(0, 0, 0, 0)")
+      c = "transparent";
+
+    return $.color.parse(c);
+  }
+
+  // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
+  // returns color object, if parsing failed, you get black (0, 0,
+  // 0) out
+  $.color.parse = function (str) {
+    var res, m = $.color.make;
+
+    // Look for rgb(num,num,num)
+    if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
+      return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
+
+    // Look for rgba(num,num,num,num)
+    if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+      return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
+
+    // Look for rgb(num%,num%,num%)
+    if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
+      return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
+
+    // Look for rgba(num%,num%,num%,num)
+    if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+      return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
+
+    // Look for #a0b1c2
+    if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
+      return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
+
+    // Look for #fff
+    if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
+      return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
+
+    // Otherwise, we're most likely dealing with a named color
+    var name = $.trim(str).toLowerCase();
+    if (name == "transparent")
+      return m(255, 255, 255, 0);
+    else {
+      // default to black
+      res = lookupColors[name] || [0, 0, 0];
+      return m(res[0], res[1], res[2]);
+    }
+  }
+
+  var lookupColors = {
+    aqua:[0,255,255],
+    azure:[240,255,255],
+    beige:[245,245,220],
+    black:[0,0,0],
+    blue:[0,0,255],
+    brown:[165,42,42],
+    cyan:[0,255,255],
+    darkblue:[0,0,139],
+    darkcyan:[0,139,139],
+    darkgrey:[169,169,169],
+    darkgreen:[0,100,0],
+    darkkhaki:[189,183,107],
+    darkmagenta:[139,0,139],
+    darkolivegreen:[85,107,47],
+    darkorange:[255,140,0],
+    darkorchid:[153,50,204],
+    darkred:[139,0,0],
+    darksalmon:[233,150,122],
+    darkviolet:[148,0,211],
+    fuchsia:[255,0,255],
+    gold:[255,215,0],
+    green:[0,128,0],
+    indigo:[75,0,130],
+    khaki:[240,230,140],
+    lightblue:[173,216,230],
+    lightcyan:[224,255,255],
+    lightgreen:[144,238,144],
+    lightgrey:[211,211,211],
+    lightpink:[255,182,193],
+    lightyellow:[255,255,224],
+    lime:[0,255,0],
+    magenta:[255,0,255],
+    maroon:[128,0,0],
+    navy:[0,0,128],
+    olive:[128,128,0],
+    orange:[255,165,0],
+    pink:[255,192,203],
+    purple:[128,0,128],
+    violet:[128,0,128],
+    red:[255,0,0],
+    silver:[192,192,192],
+    white:[255,255,255],
+    yellow:[255,255,0]
+  };
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.crosshair.js b/ui/lib/flot/jquery.flot.crosshair.js
index 1d433f0..eb12405 100644
--- a/ui/lib/flot/jquery.flot.crosshair.js
+++ b/ui/lib/flot/jquery.flot.crosshair.js
@@ -1,29 +1,31 @@
-/*
-Flot plugin for showing crosshairs, thin lines, when the mouse hovers
-over the plot.
+/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
 
-  crosshair: {
-    mode: null or "x" or "y" or "xy"
-    color: color
-    lineWidth: number
-  }
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-Set the mode to one of "x", "y" or "xy". The "x" mode enables a
-vertical crosshair that lets you trace the values on the x axis, "y"
-enables a horizontal crosshair and "xy" enables them both. "color" is
-the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"),
-"lineWidth" is the width of the drawn lines (default is 1).
+The plugin supports these options:
+
+	crosshair: {
+		mode: null or "x" or "y" or "xy"
+		color: color
+		lineWidth: number
+	}
+
+Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
+crosshair that lets you trace the values on the x axis, "y" enables a
+horizontal crosshair and "xy" enables them both. "color" is the color of the
+crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
+the drawn lines (default is 1).
 
 The plugin also adds four public methods:
 
-  - setCrosshair(pos)
+  - setCrosshair( pos )
 
-    Set the position of the crosshair. Note that this is cleared if
-    the user moves the mouse. "pos" is in coordinates of the plot and
-    should be on the form { x: xpos, y: ypos } (you can use x2/x3/...
-    if you're using multiple axes), which is coincidentally the same
-    format as what you get from a "plothover" event. If "pos" is null,
-    the crosshair is cleared.
+    Set the position of the crosshair. Note that this is cleared if the user
+    moves the mouse. "pos" is in coordinates of the plot and should be on the
+    form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
+    axes), which is coincidentally the same format as what you get from a
+    "plothover" event. If "pos" is null, the crosshair is cleared.
 
   - clearCrosshair()
 
@@ -31,22 +33,25 @@
 
   - lockCrosshair(pos)
 
-    Cause the crosshair to lock to the current location, no longer
-    updating if the user moves the mouse. Optionally supply a position
-    (passed on to setCrosshair()) to move it to.
+    Cause the crosshair to lock to the current location, no longer updating if
+    the user moves the mouse. Optionally supply a position (passed on to
+    setCrosshair()) to move it to.
 
     Example usage:
-      var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
-      $("#graph").bind("plothover", function (evt, position, item) {
-        if (item) {
-          // Lock the crosshair to the data point being hovered
-          myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] });
-        }
-        else {
-          // Return normal crosshair operation
-          myFlot.unlockCrosshair();
-        }
-      });
+
+	var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
+	$("#graph").bind( "plothover", function ( evt, position, item ) {
+		if ( item ) {
+			// Lock the crosshair to the data point being hovered
+			myFlot.lockCrosshair({
+				x: item.datapoint[ 0 ],
+				y: item.datapoint[ 1 ]
+			});
+		} else {
+			// Return normal crosshair operation
+			myFlot.unlockCrosshair();
+		}
+	});
 
   - unlockCrosshair()
 
@@ -54,114 +59,118 @@
 */
 
 (function ($) {
-    var options = {
-        crosshair: {
-            mode: null, // one of null, "x", "y" or "xy",
-            color: "rgba(170, 0, 0, 0.80)",
-            lineWidth: 1
-        }
-    };
-    
-    function init(plot) {
-        // position of crosshair in pixels
-        var crosshair = { x: -1, y: -1, locked: false };
-
-        plot.setCrosshair = function setCrosshair(pos) {
-            if (!pos)
-                crosshair.x = -1;
-            else {
-                var o = plot.p2c(pos);
-                crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
-                crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
-            }
-            
-            plot.triggerRedrawOverlay();
-        };
-        
-        plot.clearCrosshair = plot.setCrosshair; // passes null for pos
-        
-        plot.lockCrosshair = function lockCrosshair(pos) {
-            if (pos)
-                plot.setCrosshair(pos);
-            crosshair.locked = true;
-        }
-
-        plot.unlockCrosshair = function unlockCrosshair() {
-            crosshair.locked = false;
-        }
-
-        function onMouseOut(e) {
-            if (crosshair.locked)
-                return;
-
-            if (crosshair.x != -1) {
-                crosshair.x = -1;
-                plot.triggerRedrawOverlay();
-            }
-        }
-
-        function onMouseMove(e) {
-            if (crosshair.locked)
-                return;
-                
-            if (plot.getSelection && plot.getSelection()) {
-                crosshair.x = -1; // hide the crosshair while selecting
-                return;
-            }
-                
-            var offset = plot.offset();
-            crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
-            crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
-            plot.triggerRedrawOverlay();
-        }
-        
-        plot.hooks.bindEvents.push(function (plot, eventHolder) {
-            if (!plot.getOptions().crosshair.mode)
-                return;
-
-            eventHolder.mouseout(onMouseOut);
-            eventHolder.mousemove(onMouseMove);
-        });
-
-        plot.hooks.drawOverlay.push(function (plot, ctx) {
-            var c = plot.getOptions().crosshair;
-            if (!c.mode)
-                return;
-
-            var plotOffset = plot.getPlotOffset();
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            if (crosshair.x != -1) {
-                ctx.strokeStyle = c.color;
-                ctx.lineWidth = c.lineWidth;
-                ctx.lineJoin = "round";
-
-                ctx.beginPath();
-                if (c.mode.indexOf("x") != -1) {
-                    ctx.moveTo(crosshair.x, 0);
-                    ctx.lineTo(crosshair.x, plot.height());
-                }
-                if (c.mode.indexOf("y") != -1) {
-                    ctx.moveTo(0, crosshair.y);
-                    ctx.lineTo(plot.width(), crosshair.y);
-                }
-                ctx.stroke();
-            }
-            ctx.restore();
-        });
-
-        plot.hooks.shutdown.push(function (plot, eventHolder) {
-            eventHolder.unbind("mouseout", onMouseOut);
-            eventHolder.unbind("mousemove", onMouseMove);
-        });
+  var options = {
+    crosshair: {
+      mode: null, // one of null, "x", "y" or "xy",
+      color: "rgba(170, 0, 0, 0.80)",
+      lineWidth: 1
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'crosshair',
-        version: '1.0'
+  };
+
+  function init(plot) {
+    // position of crosshair in pixels
+    var crosshair = { x: -1, y: -1, locked: false };
+
+    plot.setCrosshair = function setCrosshair(pos) {
+      if (!pos)
+        crosshair.x = -1;
+      else {
+        var o = plot.p2c(pos);
+        crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
+        crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
+      }
+
+      plot.triggerRedrawOverlay();
+    };
+
+    plot.clearCrosshair = plot.setCrosshair; // passes null for pos
+
+    plot.lockCrosshair = function lockCrosshair(pos) {
+      if (pos)
+        plot.setCrosshair(pos);
+      crosshair.locked = true;
+    };
+
+    plot.unlockCrosshair = function unlockCrosshair() {
+      crosshair.locked = false;
+    };
+
+    function onMouseOut(e) {
+      if (crosshair.locked)
+        return;
+
+      if (crosshair.x != -1) {
+        crosshair.x = -1;
+        plot.triggerRedrawOverlay();
+      }
+    }
+
+    function onMouseMove(e) {
+      if (crosshair.locked)
+        return;
+
+      if (plot.getSelection && plot.getSelection()) {
+        crosshair.x = -1; // hide the crosshair while selecting
+        return;
+      }
+
+      var offset = plot.offset();
+      crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
+      crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
+      plot.triggerRedrawOverlay();
+    }
+
+    plot.hooks.bindEvents.push(function (plot, eventHolder) {
+      if (!plot.getOptions().crosshair.mode)
+        return;
+
+      eventHolder.mouseout(onMouseOut);
+      eventHolder.mousemove(onMouseMove);
     });
+
+    plot.hooks.drawOverlay.push(function (plot, ctx) {
+      var c = plot.getOptions().crosshair;
+      if (!c.mode)
+        return;
+
+      var plotOffset = plot.getPlotOffset();
+
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+
+      if (crosshair.x != -1) {
+        var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
+
+        ctx.strokeStyle = c.color;
+        ctx.lineWidth = c.lineWidth;
+        ctx.lineJoin = "round";
+
+        ctx.beginPath();
+        if (c.mode.indexOf("x") != -1) {
+          var drawX = Math.floor(crosshair.x) + adj;
+          ctx.moveTo(drawX, 0);
+          ctx.lineTo(drawX, plot.height());
+        }
+        if (c.mode.indexOf("y") != -1) {
+          var drawY = Math.floor(crosshair.y) + adj;
+          ctx.moveTo(0, drawY);
+          ctx.lineTo(plot.width(), drawY);
+        }
+        ctx.stroke();
+      }
+      ctx.restore();
+    });
+
+    plot.hooks.shutdown.push(function (plot, eventHolder) {
+      eventHolder.unbind("mouseout", onMouseOut);
+      eventHolder.unbind("mousemove", onMouseMove);
+    });
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'crosshair',
+    version: '1.0'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.fillbetween.js b/ui/lib/flot/jquery.flot.fillbetween.js
index 69700e7..c89d336 100644
--- a/ui/lib/flot/jquery.flot.fillbetween.js
+++ b/ui/lib/flot/jquery.flot.fillbetween.js
@@ -1,183 +1,226 @@
-/*
-Flot plugin for computing bottoms for filled line and bar charts.
+/* Flot plugin for computing bottoms for filled line and bar charts.
 
-The case: you've got two series that you want to fill the area
-between. In Flot terms, you need to use one as the fill bottom of the
-other. You can specify the bottom of each data point as the third
-coordinate manually, or you can use this plugin to compute it for you.
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-In order to name the other series, you need to give it an id, like this
+The case: you've got two series that you want to fill the area between. In Flot
+terms, you need to use one as the fill bottom of the other. You can specify the
+bottom of each data point as the third coordinate manually, or you can use this
+plugin to compute it for you.
 
-  var dataset = [
-       { data: [ ... ], id: "foo" } ,         // use default bottom
-       { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
-       ];
+In order to name the other series, you need to give it an id, like this:
 
-  $.plot($("#placeholder"), dataset, { line: { show: true, fill: true }});
+	var dataset = [
+		{ data: [ ... ], id: "foo" } ,         // use default bottom
+		{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
+	];
 
-As a convenience, if the id given is a number that doesn't appear as
-an id in the series, it is interpreted as the index in the array
-instead (so fillBetween: 0 can also mean the first series).
-  
-Internally, the plugin modifies the datapoints in each series. For
-line series, extra data points might be inserted through
-interpolation. Note that at points where the bottom line is not
-defined (due to a null point or start/end of line), the current line
-will show a gap too. The algorithm comes from the jquery.flot.stack.js
-plugin, possibly some code could be shared.
+	$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
+
+As a convenience, if the id given is a number that doesn't appear as an id in
+the series, it is interpreted as the index in the array instead (so fillBetween:
+0 can also mean the first series).
+
+Internally, the plugin modifies the datapoints in each series. For line series,
+extra data points might be inserted through interpolation. Note that at points
+where the bottom line is not defined (due to a null point or start/end of line),
+the current line will show a gap too. The algorithm comes from the
+jquery.flot.stack.js plugin, possibly some code could be shared.
+
 */
 
-(function ($) {
-    var options = {
-        series: { fillBetween: null } // or number
-    };
-    
-    function init(plot) {
-        function findBottomSeries(s, allseries) {
-            var i;
-            for (i = 0; i < allseries.length; ++i) {
-                if (allseries[i].id == s.fillBetween)
-                    return allseries[i];
-            }
+(function ( $ ) {
 
-            if (typeof s.fillBetween == "number") {
-                i = s.fillBetween;
-            
-                if (i < 0 || i >= allseries.length)
-                    return null;
-
-                return allseries[i];
-            }
-            
-            return null;
-        }
-        
-        function computeFillBottoms(plot, s, datapoints) {
-            if (s.fillBetween == null)
-                return;
-
-            var other = findBottomSeries(s, plot.getData());
-            if (!other)
-                return;
-
-            var ps = datapoints.pointsize,
-                points = datapoints.points,
-                otherps = other.datapoints.pointsize,
-                otherpoints = other.datapoints.points,
-                newpoints = [],
-                px, py, intery, qx, qy, bottom,
-                withlines = s.lines.show,
-                withbottom = ps > 2 && datapoints.format[2].y,
-                withsteps = withlines && s.lines.steps,
-                fromgap = true,
-                i = 0, j = 0, l;
-
-            while (true) {
-                if (i >= points.length)
-                    break;
-
-                l = newpoints.length;
-
-                if (points[i] == null) {
-                    // copy gaps
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(points[i + m]);
-                    i += ps;
-                }
-                else if (j >= otherpoints.length) {
-                    // for lines, we can't use the rest of the points
-                    if (!withlines) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                    }
-                    i += ps;
-                }
-                else if (otherpoints[j] == null) {
-                    // oops, got a gap
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(null);
-                    fromgap = true;
-                    j += otherps;
-                }
-                else {
-                    // cases where we actually got two points
-                    px = points[i];
-                    py = points[i + 1];
-                    qx = otherpoints[j];
-                    qy = otherpoints[j + 1];
-                    bottom = 0;
-
-                    if (px == qx) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-
-                        //newpoints[l + 1] += qy;
-                        bottom = qy;
-                        
-                        i += ps;
-                        j += otherps;
-                    }
-                    else if (px > qx) {
-                        // we got past point below, might need to
-                        // insert interpolated extra point
-                        if (withlines && i > 0 && points[i - ps] != null) {
-                            intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
-                            newpoints.push(qx);
-                            newpoints.push(intery)
-                            for (m = 2; m < ps; ++m)
-                                newpoints.push(points[i + m]);
-                            bottom = qy; 
-                        }
-
-                        j += otherps;
-                    }
-                    else { // px < qx
-                        if (fromgap && withlines) {
-                            // if we come from a gap, we just skip this point
-                            i += ps;
-                            continue;
-                        }
-                            
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                        
-                        // we might be able to interpolate a point below,
-                        // this can give us a better y
-                        if (withlines && j > 0 && otherpoints[j - otherps] != null)
-                            bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx);
-
-                        //newpoints[l + 1] += bottom;
-                        
-                        i += ps;
-                    }
-
-                    fromgap = false;
-                    
-                    if (l != newpoints.length && withbottom)
-                        newpoints[l + 2] = bottom;
-                }
-
-                // maintain the line steps invariant
-                if (withsteps && l != newpoints.length && l > 0
-                    && newpoints[l] != null
-                    && newpoints[l] != newpoints[l - ps]
-                    && newpoints[l + 1] != newpoints[l - ps + 1]) {
-                    for (m = 0; m < ps; ++m)
-                        newpoints[l + ps + m] = newpoints[l + m];
-                    newpoints[l + 1] = newpoints[l - ps + 1];
-                }
-            }
-
-            datapoints.points = newpoints;
-        }
-        
-        plot.hooks.processDatapoints.push(computeFillBottoms);
+  var options = {
+    series: {
+      fillBetween: null	// or number
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'fillbetween',
-        version: '1.0'
-    });
+  };
+
+  function init( plot ) {
+
+    function findBottomSeries( s, allseries ) {
+
+      var i;
+
+      for ( i = 0; i < allseries.length; ++i ) {
+        if ( allseries[ i ].id === s.fillBetween ) {
+          return allseries[ i ];
+        }
+      }
+
+      if ( typeof s.fillBetween === "number" ) {
+        if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
+          return null;
+        }
+        return allseries[ s.fillBetween ];
+      }
+
+      return null;
+    }
+
+    function computeFillBottoms( plot, s, datapoints ) {
+
+      if ( s.fillBetween == null ) {
+        return;
+      }
+
+      var other = findBottomSeries( s, plot.getData() );
+
+      if ( !other ) {
+        return;
+      }
+
+      var ps = datapoints.pointsize,
+          points = datapoints.points,
+          otherps = other.datapoints.pointsize,
+          otherpoints = other.datapoints.points,
+          newpoints = [],
+          px, py, intery, qx, qy, bottom,
+          withlines = s.lines.show,
+          withbottom = ps > 2 && datapoints.format[2].y,
+          withsteps = withlines && s.lines.steps,
+          fromgap = true,
+          i = 0,
+          j = 0,
+          l, m;
+
+      while ( true ) {
+
+        if ( i >= points.length ) {
+          break;
+        }
+
+        l = newpoints.length;
+
+        if ( points[ i ] == null ) {
+
+          // copy gaps
+
+          for ( m = 0; m < ps; ++m ) {
+            newpoints.push( points[ i + m ] );
+          }
+
+          i += ps;
+
+        } else if ( j >= otherpoints.length ) {
+
+          // for lines, we can't use the rest of the points
+
+          if ( !withlines ) {
+            for ( m = 0; m < ps; ++m ) {
+              newpoints.push( points[ i + m ] );
+            }
+          }
+
+          i += ps;
+
+        } else if ( otherpoints[ j ] == null ) {
+
+          // oops, got a gap
+
+          for ( m = 0; m < ps; ++m ) {
+            newpoints.push( null );
+          }
+
+          fromgap = true;
+          j += otherps;
+
+        } else {
+
+          // cases where we actually got two points
+
+          px = points[ i ];
+          py = points[ i + 1 ];
+          qx = otherpoints[ j ];
+          qy = otherpoints[ j + 1 ];
+          bottom = 0;
+
+          if ( px === qx ) {
+
+            for ( m = 0; m < ps; ++m ) {
+              newpoints.push( points[ i + m ] );
+            }
+
+            //newpoints[ l + 1 ] += qy;
+            bottom = qy;
+
+            i += ps;
+            j += otherps;
+
+          } else if ( px > qx ) {
+
+            // we got past point below, might need to
+            // insert interpolated extra point
+
+            if ( withlines && i > 0 && points[ i - ps ] != null ) {
+              intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
+              newpoints.push( qx );
+              newpoints.push( intery );
+              for ( m = 2; m < ps; ++m ) {
+                newpoints.push( points[ i + m ] );
+              }
+              bottom = qy;
+            }
+
+            j += otherps;
+
+          } else { // px < qx
+
+            // if we come from a gap, we just skip this point
+
+            if ( fromgap && withlines ) {
+              i += ps;
+              continue;
+            }
+
+            for ( m = 0; m < ps; ++m ) {
+              newpoints.push( points[ i + m ] );
+            }
+
+            // we might be able to interpolate a point below,
+            // this can give us a better y
+
+            if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
+              bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
+            }
+
+            //newpoints[l + 1] += bottom;
+
+            i += ps;
+          }
+
+          fromgap = false;
+
+          if ( l !== newpoints.length && withbottom ) {
+            newpoints[ l + 2 ] = bottom;
+          }
+        }
+
+        // maintain the line steps invariant
+
+        if ( withsteps && l !== newpoints.length && l > 0 &&
+            newpoints[ l ] !== null &&
+            newpoints[ l ] !== newpoints[ l - ps ] &&
+            newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
+          for (m = 0; m < ps; ++m) {
+            newpoints[ l + ps + m ] = newpoints[ l + m ];
+          }
+          newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
+        }
+      }
+
+      datapoints.points = newpoints;
+    }
+
+    plot.hooks.processDatapoints.push( computeFillBottoms );
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: "fillbetween",
+    version: "1.0"
+  });
+
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.image.js b/ui/lib/flot/jquery.flot.image.js
index 29ccb12..3527076 100644
--- a/ui/lib/flot/jquery.flot.image.js
+++ b/ui/lib/flot/jquery.flot.image.js
@@ -1,238 +1,241 @@
-/*
-Flot plugin for plotting images, e.g. useful for putting ticks on a
-prerendered complex visualization.
+/* Flot plugin for plotting images.
 
-The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
-(x2, y2) are where you intend the two opposite corners of the image to
-end up in the plot. Image must be a fully loaded Javascript image (you
-can make one with new Image()). If the image is not complete, it's
-skipped when plotting.
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-There are two helpers included for retrieving images. The easiest work
-the way that you put in URLs instead of images in the data (like
-["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
-options, callback) where data and options are the same as you pass in
-to $.plot. This loads the images, replaces the URLs in the data with
-the corresponding images and calls "callback" when all images are
-loaded (or failed loading). In the callback, you can then call $.plot
-with the data set. See the included example.
+The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
+(x2, y2) are where you intend the two opposite corners of the image to end up
+in the plot. Image must be a fully loaded Javascript image (you can make one
+with new Image()). If the image is not complete, it's skipped when plotting.
 
-A more low-level helper, $.plot.image.load(urls, callback) is also
-included. Given a list of URLs, it calls callback with an object
-mapping from URL to Image object when all images are loaded or have
-failed loading.
+There are two helpers included for retrieving images. The easiest work the way
+that you put in URLs instead of images in the data, like this:
 
-Options for the plugin are
+	[ "myimage.png", 0, 0, 10, 10 ]
 
-  series: {
-      images: {
-          show: boolean
-          anchor: "corner" or "center"
-          alpha: [0,1]
-      }
-  }
+Then call $.plot.image.loadData( data, options, callback ) where data and
+options are the same as you pass in to $.plot. This loads the images, replaces
+the URLs in the data with the corresponding images and calls "callback" when
+all images are loaded (or failed loading). In the callback, you can then call
+$.plot with the data set. See the included example.
 
-which can be specified for a specific series
+A more low-level helper, $.plot.image.load(urls, callback) is also included.
+Given a list of URLs, it calls callback with an object mapping from URL to
+Image object when all images are loaded or have failed loading.
 
-  $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])
+The plugin supports these options:
 
-Note that because the data format is different from usual data points,
-you can't use images with anything else in a specific data series.
+	series: {
+		images: {
+			show: boolean
+			anchor: "corner" or "center"
+			alpha: [ 0, 1 ]
+		}
+	}
 
-Setting "anchor" to "center" causes the pixels in the image to be
-anchored at the corner pixel centers inside of at the pixel corners,
-effectively letting half a pixel stick out to each side in the plot.
+They can be specified for a specific series:
 
+	$.plot( $("#placeholder"), [{
+		data: [ ... ],
+		images: { ... }
+	])
 
-A possible future direction could be support for tiling for large
-images (like Google Maps).
+Note that because the data format is different from usual data points, you
+can't use images with anything else in a specific data series.
+
+Setting "anchor" to "center" causes the pixels in the image to be anchored at
+the corner pixel centers inside of at the pixel corners, effectively letting
+half a pixel stick out to each side in the plot.
+
+A possible future direction could be support for tiling for large images (like
+Google Maps).
 
 */
 
 (function ($) {
-    var options = {
-        series: {
-            images: {
-                show: false,
-                alpha: 1,
-                anchor: "corner" // or "center"
-            }
+  var options = {
+    series: {
+      images: {
+        show: false,
+        alpha: 1,
+        anchor: "corner" // or "center"
+      }
+    }
+  };
+
+  $.plot.image = {};
+
+  $.plot.image.loadDataImages = function (series, options, callback) {
+    var urls = [], points = [];
+
+    var defaultShow = options.series.images.show;
+
+    $.each(series, function (i, s) {
+      if (!(defaultShow || s.images.show))
+        return;
+
+      if (s.data)
+        s = s.data;
+
+      $.each(s, function (i, p) {
+        if (typeof p[0] == "string") {
+          urls.push(p[0]);
+          points.push(p);
         }
-    };
-
-    $.plot.image = {};
-
-    $.plot.image.loadDataImages = function (series, options, callback) {
-        var urls = [], points = [];
-
-        var defaultShow = options.series.images.show;
-        
-        $.each(series, function (i, s) {
-            if (!(defaultShow || s.images.show))
-                return;
-            
-            if (s.data)
-                s = s.data;
-
-            $.each(s, function (i, p) {
-                if (typeof p[0] == "string") {
-                    urls.push(p[0]);
-                    points.push(p);
-                }
-            });
-        });
-
-        $.plot.image.load(urls, function (loadedImages) {
-            $.each(points, function (i, p) {
-                var url = p[0];
-                if (loadedImages[url])
-                    p[0] = loadedImages[url];
-            });
-
-            callback();
-        });
-    }
-    
-    $.plot.image.load = function (urls, callback) {
-        var missing = urls.length, loaded = {};
-        if (missing == 0)
-            callback({});
-
-        $.each(urls, function (i, url) {
-            var handler = function () {
-                --missing;
-                
-                loaded[url] = this;
-                
-                if (missing == 0)
-                    callback(loaded);
-            };
-
-            $('<img />').load(handler).error(handler).attr('src', url);
-        });
-    }
-    
-    function drawSeries(plot, ctx, series) {
-        var plotOffset = plot.getPlotOffset();
-        
-        if (!series.images || !series.images.show)
-            return;
-        
-        var points = series.datapoints.points,
-            ps = series.datapoints.pointsize;
-        
-        for (var i = 0; i < points.length; i += ps) {
-            var img = points[i],
-                x1 = points[i + 1], y1 = points[i + 2],
-                x2 = points[i + 3], y2 = points[i + 4],
-                xaxis = series.xaxis, yaxis = series.yaxis,
-                tmp;
-
-            // actually we should check img.complete, but it
-            // appears to be a somewhat unreliable indicator in
-            // IE6 (false even after load event)
-            if (!img || img.width <= 0 || img.height <= 0)
-                continue;
-
-            if (x1 > x2) {
-                tmp = x2;
-                x2 = x1;
-                x1 = tmp;
-            }
-            if (y1 > y2) {
-                tmp = y2;
-                y2 = y1;
-                y1 = tmp;
-            }
-            
-            // if the anchor is at the center of the pixel, expand the 
-            // image by 1/2 pixel in each direction
-            if (series.images.anchor == "center") {
-                tmp = 0.5 * (x2-x1) / (img.width - 1);
-                x1 -= tmp;
-                x2 += tmp;
-                tmp = 0.5 * (y2-y1) / (img.height - 1);
-                y1 -= tmp;
-                y2 += tmp;
-            }
-            
-            // clip
-            if (x1 == x2 || y1 == y2 ||
-                x1 >= xaxis.max || x2 <= xaxis.min ||
-                y1 >= yaxis.max || y2 <= yaxis.min)
-                continue;
-
-            var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
-            if (x1 < xaxis.min) {
-                sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
-                x1 = xaxis.min;
-            }
-
-            if (x2 > xaxis.max) {
-                sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
-                x2 = xaxis.max;
-            }
-
-            if (y1 < yaxis.min) {
-                sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
-                y1 = yaxis.min;
-            }
-
-            if (y2 > yaxis.max) {
-                sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
-                y2 = yaxis.max;
-            }
-            
-            x1 = xaxis.p2c(x1);
-            x2 = xaxis.p2c(x2);
-            y1 = yaxis.p2c(y1);
-            y2 = yaxis.p2c(y2);
-            
-            // the transformation may have swapped us
-            if (x1 > x2) {
-                tmp = x2;
-                x2 = x1;
-                x1 = tmp;
-            }
-            if (y1 > y2) {
-                tmp = y2;
-                y2 = y1;
-                y1 = tmp;
-            }
-
-            tmp = ctx.globalAlpha;
-            ctx.globalAlpha *= series.images.alpha;
-            ctx.drawImage(img,
-                          sx1, sy1, sx2 - sx1, sy2 - sy1,
-                          x1 + plotOffset.left, y1 + plotOffset.top,
-                          x2 - x1, y2 - y1);
-            ctx.globalAlpha = tmp;
-        }
-    }
-
-    function processRawData(plot, series, data, datapoints) {
-        if (!series.images.show)
-            return;
-
-        // format is Image, x1, y1, x2, y2 (opposite corners)
-        datapoints.format = [
-            { required: true },
-            { x: true, number: true, required: true },
-            { y: true, number: true, required: true },
-            { x: true, number: true, required: true },
-            { y: true, number: true, required: true }
-        ];
-    }
-    
-    function init(plot) {
-        plot.hooks.processRawData.push(processRawData);
-        plot.hooks.drawSeries.push(drawSeries);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'image',
-        version: '1.1'
+      });
     });
+
+    $.plot.image.load(urls, function (loadedImages) {
+      $.each(points, function (i, p) {
+        var url = p[0];
+        if (loadedImages[url])
+          p[0] = loadedImages[url];
+      });
+
+      callback();
+    });
+  }
+
+  $.plot.image.load = function (urls, callback) {
+    var missing = urls.length, loaded = {};
+    if (missing == 0)
+      callback({});
+
+    $.each(urls, function (i, url) {
+      var handler = function () {
+        --missing;
+
+        loaded[url] = this;
+
+        if (missing == 0)
+          callback(loaded);
+      };
+
+      $('<img />').load(handler).error(handler).attr('src', url);
+    });
+  };
+
+  function drawSeries(plot, ctx, series) {
+    var plotOffset = plot.getPlotOffset();
+
+    if (!series.images || !series.images.show)
+      return;
+
+    var points = series.datapoints.points,
+        ps = series.datapoints.pointsize;
+
+    for (var i = 0; i < points.length; i += ps) {
+      var img = points[i],
+          x1 = points[i + 1], y1 = points[i + 2],
+          x2 = points[i + 3], y2 = points[i + 4],
+          xaxis = series.xaxis, yaxis = series.yaxis,
+          tmp;
+
+      // actually we should check img.complete, but it
+      // appears to be a somewhat unreliable indicator in
+      // IE6 (false even after load event)
+      if (!img || img.width <= 0 || img.height <= 0)
+        continue;
+
+      if (x1 > x2) {
+        tmp = x2;
+        x2 = x1;
+        x1 = tmp;
+      }
+      if (y1 > y2) {
+        tmp = y2;
+        y2 = y1;
+        y1 = tmp;
+      }
+
+      // if the anchor is at the center of the pixel, expand the
+      // image by 1/2 pixel in each direction
+      if (series.images.anchor == "center") {
+        tmp = 0.5 * (x2-x1) / (img.width - 1);
+        x1 -= tmp;
+        x2 += tmp;
+        tmp = 0.5 * (y2-y1) / (img.height - 1);
+        y1 -= tmp;
+        y2 += tmp;
+      }
+
+      // clip
+      if (x1 == x2 || y1 == y2 ||
+          x1 >= xaxis.max || x2 <= xaxis.min ||
+          y1 >= yaxis.max || y2 <= yaxis.min)
+        continue;
+
+      var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
+      if (x1 < xaxis.min) {
+        sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
+        x1 = xaxis.min;
+      }
+
+      if (x2 > xaxis.max) {
+        sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
+        x2 = xaxis.max;
+      }
+
+      if (y1 < yaxis.min) {
+        sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
+        y1 = yaxis.min;
+      }
+
+      if (y2 > yaxis.max) {
+        sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
+        y2 = yaxis.max;
+      }
+
+      x1 = xaxis.p2c(x1);
+      x2 = xaxis.p2c(x2);
+      y1 = yaxis.p2c(y1);
+      y2 = yaxis.p2c(y2);
+
+      // the transformation may have swapped us
+      if (x1 > x2) {
+        tmp = x2;
+        x2 = x1;
+        x1 = tmp;
+      }
+      if (y1 > y2) {
+        tmp = y2;
+        y2 = y1;
+        y1 = tmp;
+      }
+
+      tmp = ctx.globalAlpha;
+      ctx.globalAlpha *= series.images.alpha;
+      ctx.drawImage(img,
+          sx1, sy1, sx2 - sx1, sy2 - sy1,
+          x1 + plotOffset.left, y1 + plotOffset.top,
+          x2 - x1, y2 - y1);
+      ctx.globalAlpha = tmp;
+    }
+  }
+
+  function processRawData(plot, series, data, datapoints) {
+    if (!series.images.show)
+      return;
+
+    // format is Image, x1, y1, x2, y2 (opposite corners)
+    datapoints.format = [
+      { required: true },
+      { x: true, number: true, required: true },
+      { y: true, number: true, required: true },
+      { x: true, number: true, required: true },
+      { y: true, number: true, required: true }
+    ];
+  }
+
+  function init(plot) {
+    plot.hooks.processRawData.push(processRawData);
+    plot.hooks.drawSeries.push(drawSeries);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'image',
+    version: '1.1'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.js b/ui/lib/flot/jquery.flot.js
index aabc544..d156da9 100644
--- a/ui/lib/flot/jquery.flot.js
+++ b/ui/lib/flot/jquery.flot.js
@@ -1,16 +1,17 @@
-/*! Javascript plotting library for jQuery, v. 0.7.
- *
- * Released under the MIT license by IOLA, December 2007.
- *
- */
+/* Javascript plotting library for jQuery, version 0.8.3.
+
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
+
+*/
 
 // first an inline dependency, jquery.colorhelpers.js, we inline it here
 // for convenience
 
 /* Plugin for jQuery for working with colors.
- * 
+ *
  * Version 1.1.
- * 
+ *
  * Inspiration from jQuery color animation plugin by John Resig.
  *
  * Released under the MIT license by Ole Laursen, October 2009.
@@ -27,2573 +28,3141 @@
  *
  * V. 1.1: Fix error handling so e.g. parsing an empty string does
  * produce a color rather than just crashing.
- */ 
-(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
+ */
+(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
 
 // the actual Flot code
 (function($) {
-    function Plot(placeholder, data_, options_, plugins) {
-        // data is on the form:
-        //   [ series1, series2 ... ]
-        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
-        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
-        
-        var series = [],
-            options = {
-                // the color theme used for graphs
-                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
-                legend: {
-                    show: true,
-                    noColumns: 1, // number of colums in legend table
-                    labelFormatter: null, // fn: string -> string
-                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
-                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
-                    position: "ne", // position of default legend container within plot
-                    margin: 5, // distance from grid edge to default legend container within plot
-                    backgroundColor: null, // null means auto-detect
-                    backgroundOpacity: 0.85 // set to 0 to avoid background
-                },
-                xaxis: {
-                    show: null, // null = auto-detect, true = always, false = never
-                    position: "bottom", // or "top"
-                    mode: null, // null or "time"
-                    color: null, // base color, labels, ticks
-                    tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
-                    transform: null, // null or f: number -> number to transform axis
-                    inverseTransform: null, // if transform is set, this should be the inverse function
-                    min: null, // min. value to show, null means set automatically
-                    max: null, // max. value to show, null means set automatically
-                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
-                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
-                    tickFormatter: null, // fn: number -> string
-                    labelWidth: null, // size of tick labels in pixels
-                    labelHeight: null,
-                    reserveSpace: null, // whether to reserve space even if axis isn't shown
-                    tickLength: null, // size in pixels of ticks, or "full" for whole line
-                    alignTicksWithAxis: null, // axis number or null for no sync
-                    
-                    // mode specific options
-                    tickDecimals: null, // no. of decimals, null means auto
-                    tickSize: null, // number or [number, "unit"]
-                    minTickSize: null, // number or [number, "unit"]
-                    monthNames: null, // list of names of months
-                    timeformat: null, // format string to use
-                    twelveHourClock: false // 12 or 24 time in time mode
-                },
-                yaxis: {
-                    autoscaleMargin: 0.02,
-                    position: "left" // or "right"
-                },
-                xaxes: [],
-                yaxes: [],
-                series: {
-                    points: {
-                        show: false,
-                        radius: 3,
-                        lineWidth: 2, // in pixels
-                        fill: true,
-                        fillColor: "#ffffff",
-                        symbol: "circle" // or callback
-                    },
-                    lines: {
-                        // we don't put in show: false so we can see
-                        // whether lines were actively disabled 
-                        lineWidth: 2, // in pixels
-                        fill: false,
-                        fillColor: null,
-                        steps: false
-                    },
-                    bars: {
-                        show: false,
-                        lineWidth: 2, // in pixels
-                        barWidth: 1, // in units of the x axis
-                        fill: true,
-                        fillColor: null,
-                        align: "left", // or "center" 
-                        horizontal: false
-                    },
-                    shadowSize: 3
-                },
-                grid: {
-                    show: true,
-                    aboveData: false,
-                    color: "#545454", // primary color used for outline and labels
-                    backgroundColor: null, // null for transparent, else color
-                    borderColor: null, // set if different from the grid color
-                    tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
-                    labelMargin: 5, // in pixels
-                    axisMargin: 8, // in pixels
-                    borderWidth: 2, // in pixels
-                    minBorderMargin: null, // in pixels, null means taken from points radius
-                    markings: null, // array of ranges or fn: axes -> array of ranges
-                    markingsColor: "#f4f4f4",
-                    markingsLineWidth: 2,
-                    // interactive stuff
-                    clickable: false,
-                    hoverable: false,
-                    autoHighlight: true, // highlight in case mouse is near
-                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
-                },
-                hooks: {}
+
+  // Cache the prototype hasOwnProperty for faster access
+
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+  // A shim to provide 'detach' to jQuery versions prior to 1.4.  Using a DOM
+  // operation produces the same effect as detach, i.e. removing the element
+  // without touching its jQuery data.
+
+  // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
+
+  if (!$.fn.detach) {
+    $.fn.detach = function() {
+      return this.each(function() {
+        if (this.parentNode) {
+          this.parentNode.removeChild( this );
+        }
+      });
+    };
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  // The Canvas object is a wrapper around an HTML5 <canvas> tag.
+  //
+  // @constructor
+  // @param {string} cls List of classes to apply to the canvas.
+  // @param {element} container Element onto which to append the canvas.
+  //
+  // Requiring a container is a little iffy, but unfortunately canvas
+  // operations don't work unless the canvas is attached to the DOM.
+
+  function Canvas(cls, container) {
+
+    var element = container.children("." + cls)[0];
+
+    if (element == null) {
+
+      element = document.createElement("canvas");
+      element.className = cls;
+
+      $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
+          .appendTo(container);
+
+      // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
+
+      if (!element.getContext) {
+        if (window.G_vmlCanvasManager) {
+          element = window.G_vmlCanvasManager.initElement(element);
+        } else {
+          throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
+        }
+      }
+    }
+
+    this.element = element;
+
+    var context = this.context = element.getContext("2d");
+
+    // Determine the screen's ratio of physical to device-independent
+    // pixels.  This is the ratio between the canvas width that the browser
+    // advertises and the number of pixels actually present in that space.
+
+    // The iPhone 4, for example, has a device-independent width of 320px,
+    // but its screen is actually 640px wide.  It therefore has a pixel
+    // ratio of 2, while most normal devices have a ratio of 1.
+
+    var devicePixelRatio = window.devicePixelRatio || 1,
+        backingStoreRatio =
+            context.webkitBackingStorePixelRatio ||
+            context.mozBackingStorePixelRatio ||
+            context.msBackingStorePixelRatio ||
+            context.oBackingStorePixelRatio ||
+            context.backingStorePixelRatio || 1;
+
+    this.pixelRatio = devicePixelRatio / backingStoreRatio;
+
+    // Size the canvas to match the internal dimensions of its container
+
+    this.resize(container.width(), container.height());
+
+    // Collection of HTML div layers for text overlaid onto the canvas
+
+    this.textContainer = null;
+    this.text = {};
+
+    // Cache of text fragments and metrics, so we can avoid expensively
+    // re-calculating them when the plot is re-rendered in a loop.
+
+    this._textCache = {};
+  }
+
+  // Resizes the canvas to the given dimensions.
+  //
+  // @param {number} width New width of the canvas, in pixels.
+  // @param {number} width New height of the canvas, in pixels.
+
+  Canvas.prototype.resize = function(width, height) {
+
+    if (width <= 0 || height <= 0) {
+      throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
+    }
+
+    var element = this.element,
+        context = this.context,
+        pixelRatio = this.pixelRatio;
+
+    // Resize the canvas, increasing its density based on the display's
+    // pixel ratio; basically giving it more pixels without increasing the
+    // size of its element, to take advantage of the fact that retina
+    // displays have that many more pixels in the same advertised space.
+
+    // Resizing should reset the state (excanvas seems to be buggy though)
+
+    if (this.width != width) {
+      element.width = width * pixelRatio;
+      element.style.width = width + "px";
+      this.width = width;
+    }
+
+    if (this.height != height) {
+      element.height = height * pixelRatio;
+      element.style.height = height + "px";
+      this.height = height;
+    }
+
+    // Save the context, so we can reset in case we get replotted.  The
+    // restore ensure that we're really back at the initial state, and
+    // should be safe even if we haven't saved the initial state yet.
+
+    context.restore();
+    context.save();
+
+    // Scale the coordinate space to match the display density; so even though we
+    // may have twice as many pixels, we still want lines and other drawing to
+    // appear at the same size; the extra pixels will just make them crisper.
+
+    context.scale(pixelRatio, pixelRatio);
+  };
+
+  // Clears the entire canvas area, not including any overlaid HTML text
+
+  Canvas.prototype.clear = function() {
+    this.context.clearRect(0, 0, this.width, this.height);
+  };
+
+  // Finishes rendering the canvas, including managing the text overlay.
+
+  Canvas.prototype.render = function() {
+
+    var cache = this._textCache;
+
+    // For each text layer, add elements marked as active that haven't
+    // already been rendered, and remove those that are no longer active.
+
+    for (var layerKey in cache) {
+      if (hasOwnProperty.call(cache, layerKey)) {
+
+        var layer = this.getTextLayer(layerKey),
+            layerCache = cache[layerKey];
+
+        layer.hide();
+
+        for (var styleKey in layerCache) {
+          if (hasOwnProperty.call(layerCache, styleKey)) {
+            var styleCache = layerCache[styleKey];
+            for (var key in styleCache) {
+              if (hasOwnProperty.call(styleCache, key)) {
+
+                var positions = styleCache[key].positions;
+
+                for (var i = 0, position; position = positions[i]; i++) {
+                  if (position.active) {
+                    if (!position.rendered) {
+                      layer.append(position.element);
+                      position.rendered = true;
+                    }
+                  } else {
+                    positions.splice(i--, 1);
+                    if (position.rendered) {
+                      position.element.detach();
+                    }
+                  }
+                }
+
+                if (positions.length == 0) {
+                  delete styleCache[key];
+                }
+              }
+            }
+          }
+        }
+
+        layer.show();
+      }
+    }
+  };
+
+  // Creates (if necessary) and returns the text overlay container.
+  //
+  // @param {string} classes String of space-separated CSS classes used to
+  //     uniquely identify the text layer.
+  // @return {object} The jQuery-wrapped text-layer div.
+
+  Canvas.prototype.getTextLayer = function(classes) {
+
+    var layer = this.text[classes];
+
+    // Create the text layer if it doesn't exist
+
+    if (layer == null) {
+
+      // Create the text layer container, if it doesn't exist
+
+      if (this.textContainer == null) {
+        this.textContainer = $("<div class='flot-text'></div>")
+            .css({
+              position: "absolute",
+              top: 0,
+              left: 0,
+              bottom: 0,
+              right: 0,
+              'font-size': "smaller",
+              color: "#545454"
+            })
+            .insertAfter(this.element);
+      }
+
+      layer = this.text[classes] = $("<div></div>")
+          .addClass(classes)
+          .css({
+            position: "absolute",
+            top: 0,
+            left: 0,
+            bottom: 0,
+            right: 0
+          })
+          .appendTo(this.textContainer);
+    }
+
+    return layer;
+  };
+
+  // Creates (if necessary) and returns a text info object.
+  //
+  // The object looks like this:
+  //
+  // {
+  //     width: Width of the text's wrapper div.
+  //     height: Height of the text's wrapper div.
+  //     element: The jQuery-wrapped HTML div containing the text.
+  //     positions: Array of positions at which this text is drawn.
+  // }
+  //
+  // The positions array contains objects that look like this:
+  //
+  // {
+  //     active: Flag indicating whether the text should be visible.
+  //     rendered: Flag indicating whether the text is currently visible.
+  //     element: The jQuery-wrapped HTML div containing the text.
+  //     x: X coordinate at which to draw the text.
+  //     y: Y coordinate at which to draw the text.
+  // }
+  //
+  // Each position after the first receives a clone of the original element.
+  //
+  // The idea is that that the width, height, and general 'identity' of the
+  // text is constant no matter where it is placed; the placements are a
+  // secondary property.
+  //
+  // Canvas maintains a cache of recently-used text info objects; getTextInfo
+  // either returns the cached element or creates a new entry.
+  //
+  // @param {string} layer A string of space-separated CSS classes uniquely
+  //     identifying the layer containing this text.
+  // @param {string} text Text string to retrieve info for.
+  // @param {(string|object)=} font Either a string of space-separated CSS
+  //     classes or a font-spec object, defining the text's font and style.
+  // @param {number=} angle Angle at which to rotate the text, in degrees.
+  //     Angle is currently unused, it will be implemented in the future.
+  // @param {number=} width Maximum width of the text before it wraps.
+  // @return {object} a text info object.
+
+  Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
+
+    var textStyle, layerCache, styleCache, info;
+
+    // Cast the value to a string, in case we were given a number or such
+
+    text = "" + text;
+
+    // If the font is a font-spec object, generate a CSS font definition
+
+    if (typeof font === "object") {
+      textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
+    } else {
+      textStyle = font;
+    }
+
+    // Retrieve (or create) the cache for the text's layer and styles
+
+    layerCache = this._textCache[layer];
+
+    if (layerCache == null) {
+      layerCache = this._textCache[layer] = {};
+    }
+
+    styleCache = layerCache[textStyle];
+
+    if (styleCache == null) {
+      styleCache = layerCache[textStyle] = {};
+    }
+
+    info = styleCache[text];
+
+    // If we can't find a matching element in our cache, create a new one
+
+    if (info == null) {
+
+      var element = $("<div></div>").html(text)
+          .css({
+            position: "absolute",
+            'max-width': width,
+            top: -9999
+          })
+          .appendTo(this.getTextLayer(layer));
+
+      if (typeof font === "object") {
+        element.css({
+          font: textStyle,
+          color: font.color
+        });
+      } else if (typeof font === "string") {
+        element.addClass(font);
+      }
+
+      info = styleCache[text] = {
+        width: element.outerWidth(true),
+        height: element.outerHeight(true),
+        element: element,
+        positions: []
+      };
+
+      element.detach();
+    }
+
+    return info;
+  };
+
+  // Adds a text string to the canvas text overlay.
+  //
+  // The text isn't drawn immediately; it is marked as rendering, which will
+  // result in its addition to the canvas on the next render pass.
+  //
+  // @param {string} layer A string of space-separated CSS classes uniquely
+  //     identifying the layer containing this text.
+  // @param {number} x X coordinate at which to draw the text.
+  // @param {number} y Y coordinate at which to draw the text.
+  // @param {string} text Text string to draw.
+  // @param {(string|object)=} font Either a string of space-separated CSS
+  //     classes or a font-spec object, defining the text's font and style.
+  // @param {number=} angle Angle at which to rotate the text, in degrees.
+  //     Angle is currently unused, it will be implemented in the future.
+  // @param {number=} width Maximum width of the text before it wraps.
+  // @param {string=} halign Horizontal alignment of the text; either "left",
+  //     "center" or "right".
+  // @param {string=} valign Vertical alignment of the text; either "top",
+  //     "middle" or "bottom".
+
+  Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
+
+    var info = this.getTextInfo(layer, text, font, angle, width),
+        positions = info.positions;
+
+    // Tweak the div's position to match the text's alignment
+
+    if (halign == "center") {
+      x -= info.width / 2;
+    } else if (halign == "right") {
+      x -= info.width;
+    }
+
+    if (valign == "middle") {
+      y -= info.height / 2;
+    } else if (valign == "bottom") {
+      y -= info.height;
+    }
+
+    // Determine whether this text already exists at this position.
+    // If so, mark it for inclusion in the next render pass.
+
+    for (var i = 0, position; position = positions[i]; i++) {
+      if (position.x == x && position.y == y) {
+        position.active = true;
+        return;
+      }
+    }
+
+    // If the text doesn't exist at this position, create a new entry
+
+    // For the very first position we'll re-use the original element,
+    // while for subsequent ones we'll clone it.
+
+    position = {
+      active: true,
+      rendered: false,
+      element: positions.length ? info.element.clone() : info.element,
+      x: x,
+      y: y
+    };
+
+    positions.push(position);
+
+    // Move the element to its final position within the container
+
+    position.element.css({
+      top: Math.round(y),
+      left: Math.round(x),
+      'text-align': halign	// In case the text wraps
+    });
+  };
+
+  // Removes one or more text strings from the canvas text overlay.
+  //
+  // If no parameters are given, all text within the layer is removed.
+  //
+  // Note that the text is not immediately removed; it is simply marked as
+  // inactive, which will result in its removal on the next render pass.
+  // This avoids the performance penalty for 'clear and redraw' behavior,
+  // where we potentially get rid of all text on a layer, but will likely
+  // add back most or all of it later, as when redrawing axes, for example.
+  //
+  // @param {string} layer A string of space-separated CSS classes uniquely
+  //     identifying the layer containing this text.
+  // @param {number=} x X coordinate of the text.
+  // @param {number=} y Y coordinate of the text.
+  // @param {string=} text Text string to remove.
+  // @param {(string|object)=} font Either a string of space-separated CSS
+  //     classes or a font-spec object, defining the text's font and style.
+  // @param {number=} angle Angle at which the text is rotated, in degrees.
+  //     Angle is currently unused, it will be implemented in the future.
+
+  Canvas.prototype.removeText = function(layer, x, y, text, font, angle) {
+    if (text == null) {
+      var layerCache = this._textCache[layer];
+      if (layerCache != null) {
+        for (var styleKey in layerCache) {
+          if (hasOwnProperty.call(layerCache, styleKey)) {
+            var styleCache = layerCache[styleKey];
+            for (var key in styleCache) {
+              if (hasOwnProperty.call(styleCache, key)) {
+                var positions = styleCache[key].positions;
+                for (var i = 0, position; position = positions[i]; i++) {
+                  position.active = false;
+                }
+              }
+            }
+          }
+        }
+      }
+    } else {
+      var positions = this.getTextInfo(layer, text, font, angle).positions;
+      for (var i = 0, position; position = positions[i]; i++) {
+        if (position.x == x && position.y == y) {
+          position.active = false;
+        }
+      }
+    }
+  };
+
+  ///////////////////////////////////////////////////////////////////////////
+  // The top-level container for the entire plot.
+
+  function Plot(placeholder, data_, options_, plugins) {
+    // data is on the form:
+    //   [ series1, series2 ... ]
+    // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
+    // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
+
+    var series = [],
+        options = {
+          // the color theme used for graphs
+          colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
+          legend: {
+            show: true,
+            noColumns: 1, // number of colums in legend table
+            labelFormatter: null, // fn: string -> string
+            labelBoxBorderColor: "#ccc", // border color for the little label boxes
+            container: null, // container (as jQuery object) to put legend in, null means default on top of graph
+            position: "ne", // position of default legend container within plot
+            margin: 5, // distance from grid edge to default legend container within plot
+            backgroundColor: null, // null means auto-detect
+            backgroundOpacity: 0.85, // set to 0 to avoid background
+            sorted: null    // default to no legend sorting
+          },
+          xaxis: {
+            show: null, // null = auto-detect, true = always, false = never
+            position: "bottom", // or "top"
+            mode: null, // null or "time"
+            font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
+            color: null, // base color, labels, ticks
+            tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
+            transform: null, // null or f: number -> number to transform axis
+            inverseTransform: null, // if transform is set, this should be the inverse function
+            min: null, // min. value to show, null means set automatically
+            max: null, // max. value to show, null means set automatically
+            autoscaleMargin: null, // margin in % to add if auto-setting min/max
+            ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
+            tickFormatter: null, // fn: number -> string
+            labelWidth: null, // size of tick labels in pixels
+            labelHeight: null,
+            reserveSpace: null, // whether to reserve space even if axis isn't shown
+            tickLength: null, // size in pixels of ticks, or "full" for whole line
+            alignTicksWithAxis: null, // axis number or null for no sync
+            tickDecimals: null, // no. of decimals, null means auto
+            tickSize: null, // number or [number, "unit"]
+            minTickSize: null // number or [number, "unit"]
+          },
+          yaxis: {
+            autoscaleMargin: 0.02,
+            position: "left" // or "right"
+          },
+          xaxes: [],
+          yaxes: [],
+          series: {
+            points: {
+              show: false,
+              radius: 3,
+              lineWidth: 2, // in pixels
+              fill: true,
+              fillColor: "#ffffff",
+              symbol: "circle" // or callback
             },
-        canvas = null,      // the canvas for the plot itself
+            lines: {
+              // we don't put in show: false so we can see
+              // whether lines were actively disabled
+              lineWidth: 2, // in pixels
+              fill: false,
+              fillColor: null,
+              steps: false
+              // Omit 'zero', so we can later default its value to
+              // match that of the 'fill' option.
+            },
+            bars: {
+              show: false,
+              lineWidth: 2, // in pixels
+              barWidth: 1, // in units of the x axis
+              fill: true,
+              fillColor: null,
+              align: "left", // "left", "right", or "center"
+              horizontal: false,
+              zero: true
+            },
+            shadowSize: 3,
+            highlightColor: null
+          },
+          grid: {
+            show: true,
+            aboveData: false,
+            color: "#545454", // primary color used for outline and labels
+            backgroundColor: null, // null for transparent, else color
+            borderColor: null, // set if different from the grid color
+            tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
+            margin: 0, // distance from the canvas edge to the grid
+            labelMargin: 5, // in pixels
+            axisMargin: 8, // in pixels
+            borderWidth: 2, // in pixels
+            minBorderMargin: null, // in pixels, null means taken from points radius
+            markings: null, // array of ranges or fn: axes -> array of ranges
+            markingsColor: "#f4f4f4",
+            markingsLineWidth: 2,
+            // interactive stuff
+            clickable: false,
+            hoverable: false,
+            autoHighlight: true, // highlight in case mouse is near
+            mouseActiveRadius: 10 // how far the mouse can be away to activate an item
+          },
+          interaction: {
+            redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow
+          },
+          hooks: {}
+        },
+        surface = null,     // the canvas for the plot itself
         overlay = null,     // canvas for interactive stuff on top of plot
         eventHolder = null, // jQuery object that events should be bound to
         ctx = null, octx = null,
         xaxes = [], yaxes = [],
         plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
-        canvasWidth = 0, canvasHeight = 0,
         plotWidth = 0, plotHeight = 0,
         hooks = {
-            processOptions: [],
-            processRawData: [],
-            processDatapoints: [],
-            drawSeries: [],
-            draw: [],
-            bindEvents: [],
-            drawOverlay: [],
-            shutdown: []
+          processOptions: [],
+          processRawData: [],
+          processDatapoints: [],
+          processOffset: [],
+          drawBackground: [],
+          drawSeries: [],
+          draw: [],
+          bindEvents: [],
+          drawOverlay: [],
+          shutdown: []
         },
         plot = this;
 
-        // public functions
-        plot.setData = setData;
-        plot.setupGrid = setupGrid;
-        plot.draw = draw;
-        plot.getPlaceholder = function() { return placeholder; };
-        plot.getCanvas = function() { return canvas; };
-        plot.getPlotOffset = function() { return plotOffset; };
-        plot.width = function () { return plotWidth; };
-        plot.height = function () { return plotHeight; };
-        plot.offset = function () {
-            var o = eventHolder.offset();
-            o.left += plotOffset.left;
-            o.top += plotOffset.top;
-            return o;
-        };
-        plot.getData = function () { return series; };
-        plot.getAxes = function () {
-            var res = {}, i;
-            $.each(xaxes.concat(yaxes), function (_, axis) {
-                if (axis)
-                    res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
-            });
-            return res;
-        };
-        plot.getXAxes = function () { return xaxes; };
-        plot.getYAxes = function () { return yaxes; };
-        plot.c2p = canvasToAxisCoords;
-        plot.p2c = axisToCanvasCoords;
-        plot.getOptions = function () { return options; };
-        plot.highlight = highlight;
-        plot.unhighlight = unhighlight;
-        plot.triggerRedrawOverlay = triggerRedrawOverlay;
-        plot.pointOffset = function(point) {
-            return {
-                left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left),
-                top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top)
-            };
-        };
-        plot.shutdown = shutdown;
-        plot.resize = function () {
-            getCanvasDimensions();
-            resizeCanvas(canvas);
-            resizeCanvas(overlay);
-        };
+    // public functions
+    plot.setData = setData;
+    plot.setupGrid = setupGrid;
+    plot.draw = draw;
+    plot.getPlaceholder = function() { return placeholder; };
+    plot.getCanvas = function() { return surface.element; };
+    plot.getPlotOffset = function() { return plotOffset; };
+    plot.width = function () { return plotWidth; };
+    plot.height = function () { return plotHeight; };
+    plot.offset = function () {
+      var o = eventHolder.offset();
+      o.left += plotOffset.left;
+      o.top += plotOffset.top;
+      return o;
+    };
+    plot.getData = function () { return series; };
+    plot.getAxes = function () {
+      var res = {}, i;
+      $.each(xaxes.concat(yaxes), function (_, axis) {
+        if (axis)
+          res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
+      });
+      return res;
+    };
+    plot.getXAxes = function () { return xaxes; };
+    plot.getYAxes = function () { return yaxes; };
+    plot.c2p = canvasToAxisCoords;
+    plot.p2c = axisToCanvasCoords;
+    plot.getOptions = function () { return options; };
+    plot.highlight = highlight;
+    plot.unhighlight = unhighlight;
+    plot.triggerRedrawOverlay = triggerRedrawOverlay;
+    plot.pointOffset = function(point) {
+      return {
+        left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
+        top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
+      };
+    };
+    plot.shutdown = shutdown;
+    plot.destroy = function () {
+      shutdown();
+      placeholder.removeData("plot").empty();
 
-        // public attributes
-        plot.hooks = hooks;
-        
-        // initialize
-        initPlugins(plot);
-        parseOptions(options_);
-        setupCanvases();
-        setData(data_);
-        setupGrid();
-        draw();
-        bindEvents();
-
-
-        function executeHooks(hook, args) {
-            args = [plot].concat(args);
-            for (var i = 0; i < hook.length; ++i)
-                hook[i].apply(this, args);
-        }
-
-        function initPlugins() {
-            for (var i = 0; i < plugins.length; ++i) {
-                var p = plugins[i];
-                p.init(plot);
-                if (p.options)
-                    $.extend(true, options, p.options);
-            }
-        }
-        
-        function parseOptions(opts) {
-            var i;
-            
-            $.extend(true, options, opts);
-            
-            if (options.xaxis.color == null)
-                options.xaxis.color = options.grid.color;
-            if (options.yaxis.color == null)
-                options.yaxis.color = options.grid.color;
-            
-            if (options.xaxis.tickColor == null) // backwards-compatibility
-                options.xaxis.tickColor = options.grid.tickColor;
-            if (options.yaxis.tickColor == null) // backwards-compatibility
-                options.yaxis.tickColor = options.grid.tickColor;
-
-            if (options.grid.borderColor == null)
-                options.grid.borderColor = options.grid.color;
-            if (options.grid.tickColor == null)
-                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
-            
-            // fill in defaults in axes, copy at least always the
-            // first as the rest of the code assumes it'll be there
-            for (i = 0; i < Math.max(1, options.xaxes.length); ++i)
-                options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]);
-            for (i = 0; i < Math.max(1, options.yaxes.length); ++i)
-                options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]);
-
-            // backwards compatibility, to be removed in future
-            if (options.xaxis.noTicks && options.xaxis.ticks == null)
-                options.xaxis.ticks = options.xaxis.noTicks;
-            if (options.yaxis.noTicks && options.yaxis.ticks == null)
-                options.yaxis.ticks = options.yaxis.noTicks;
-            if (options.x2axis) {
-                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
-                options.xaxes[1].position = "top";
-            }
-            if (options.y2axis) {
-                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
-                options.yaxes[1].position = "right";
-            }
-            if (options.grid.coloredAreas)
-                options.grid.markings = options.grid.coloredAreas;
-            if (options.grid.coloredAreasColor)
-                options.grid.markingsColor = options.grid.coloredAreasColor;
-            if (options.lines)
-                $.extend(true, options.series.lines, options.lines);
-            if (options.points)
-                $.extend(true, options.series.points, options.points);
-            if (options.bars)
-                $.extend(true, options.series.bars, options.bars);
-            if (options.shadowSize != null)
-                options.series.shadowSize = options.shadowSize;
-
-            // save options on axes for future reference
-            for (i = 0; i < options.xaxes.length; ++i)
-                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
-            for (i = 0; i < options.yaxes.length; ++i)
-                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
-
-            // add hooks from options
-            for (var n in hooks)
-                if (options.hooks[n] && options.hooks[n].length)
-                    hooks[n] = hooks[n].concat(options.hooks[n]);
-
-            executeHooks(hooks.processOptions, [options]);
-        }
-
-        function setData(d) {
-            series = parseData(d);
-            fillInSeriesOptions();
-            processData();
-        }
-        
-        function parseData(d) {
-            var res = [];
-            for (var i = 0; i < d.length; ++i) {
-                var s = $.extend(true, {}, options.series);
-
-                if (d[i].data != null) {
-                    s.data = d[i].data; // move the data instead of deep-copy
-                    delete d[i].data;
-
-                    $.extend(true, s, d[i]);
-
-                    d[i].data = s.data;
-                }
-                else
-                    s.data = d[i];
-                res.push(s);
-            }
-
-            return res;
-        }
-        
-        function axisNumber(obj, coord) {
-            var a = obj[coord + "axis"];
-            if (typeof a == "object") // if we got a real axis, extract number
-                a = a.n;
-            if (typeof a != "number")
-                a = 1; // default to first axis
-            return a;
-        }
-
-        function allAxes() {
-            // return flat array without annoying null entries
-            return $.grep(xaxes.concat(yaxes), function (a) { return a; });
-        }
-        
-        function canvasToAxisCoords(pos) {
-            // return an object with x/y corresponding to all used axes 
-            var res = {}, i, axis;
-            for (i = 0; i < xaxes.length; ++i) {
-                axis = xaxes[i];
-                if (axis && axis.used)
-                    res["x" + axis.n] = axis.c2p(pos.left);
-            }
-
-            for (i = 0; i < yaxes.length; ++i) {
-                axis = yaxes[i];
-                if (axis && axis.used)
-                    res["y" + axis.n] = axis.c2p(pos.top);
-            }
-            
-            if (res.x1 !== undefined)
-                res.x = res.x1;
-            if (res.y1 !== undefined)
-                res.y = res.y1;
-
-            return res;
-        }
-        
-        function axisToCanvasCoords(pos) {
-            // get canvas coords from the first pair of x/y found in pos
-            var res = {}, i, axis, key;
-
-            for (i = 0; i < xaxes.length; ++i) {
-                axis = xaxes[i];
-                if (axis && axis.used) {
-                    key = "x" + axis.n;
-                    if (pos[key] == null && axis.n == 1)
-                        key = "x";
-
-                    if (pos[key] != null) {
-                        res.left = axis.p2c(pos[key]);
-                        break;
-                    }
-                }
-            }
-            
-            for (i = 0; i < yaxes.length; ++i) {
-                axis = yaxes[i];
-                if (axis && axis.used) {
-                    key = "y" + axis.n;
-                    if (pos[key] == null && axis.n == 1)
-                        key = "y";
-
-                    if (pos[key] != null) {
-                        res.top = axis.p2c(pos[key]);
-                        break;
-                    }
-                }
-            }
-            
-            return res;
-        }
-        
-        function getOrCreateAxis(axes, number) {
-            if (!axes[number - 1])
-                axes[number - 1] = {
-                    n: number, // save the number for future reference
-                    direction: axes == xaxes ? "x" : "y",
-                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
-                };
-                
-            return axes[number - 1];
-        }
-
-        function fillInSeriesOptions() {
-            var i;
-            
-            // collect what we already got of colors
-            var neededColors = series.length,
-                usedColors = [],
-                assignedColors = [];
-            for (i = 0; i < series.length; ++i) {
-                var sc = series[i].color;
-                if (sc != null) {
-                    --neededColors;
-                    if (typeof sc == "number")
-                        assignedColors.push(sc);
-                    else
-                        usedColors.push($.color.parse(series[i].color));
-                }
-            }
-            
-            // we might need to generate more colors if higher indices
-            // are assigned
-            for (i = 0; i < assignedColors.length; ++i) {
-                neededColors = Math.max(neededColors, assignedColors[i] + 1);
-            }
-
-            // produce colors as needed
-            var colors = [], variation = 0;
-            i = 0;
-            while (colors.length < neededColors) {
-                var c;
-                if (options.colors.length == i) // check degenerate case
-                    c = $.color.make(100, 100, 100);
-                else
-                    c = $.color.parse(options.colors[i]);
-
-                // vary color if needed
-                var sign = variation % 2 == 1 ? -1 : 1;
-                c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2)
-
-                // FIXME: if we're getting to close to something else,
-                // we should probably skip this one
-                colors.push(c);
-                
-                ++i;
-                if (i >= options.colors.length) {
-                    i = 0;
-                    ++variation;
-                }
-            }
-
-            // fill in the options
-            var colori = 0, s;
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                // assign colors
-                if (s.color == null) {
-                    s.color = colors[colori].toString();
-                    ++colori;
-                }
-                else if (typeof s.color == "number")
-                    s.color = colors[s.color].toString();
-
-                // turn on lines automatically in case nothing is set
-                if (s.lines.show == null) {
-                    var v, show = true;
-                    for (v in s)
-                        if (s[v] && s[v].show) {
-                            show = false;
-                            break;
-                        }
-                    if (show)
-                        s.lines.show = true;
-                }
-
-                // setup axes
-                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
-                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
-            }
-        }
-        
-        function processData() {
-            var topSentry = Number.POSITIVE_INFINITY,
-                bottomSentry = Number.NEGATIVE_INFINITY,
-                fakeInfinity = Number.MAX_VALUE,
-                i, j, k, m, length,
-                s, points, ps, x, y, axis, val, f, p;
-
-            function updateAxis(axis, min, max) {
-                if (min < axis.datamin && min != -fakeInfinity)
-                    axis.datamin = min;
-                if (max > axis.datamax && max != fakeInfinity)
-                    axis.datamax = max;
-            }
-
-            $.each(allAxes(), function (_, axis) {
-                // init axis
-                axis.datamin = topSentry;
-                axis.datamax = bottomSentry;
-                axis.used = false;
-            });
-            
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                s.datapoints = { points: [] };
-                
-                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
-            }
-            
-            // first pass: clean and copy data
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-
-                var data = s.data, format = s.datapoints.format;
-
-                if (!format) {
-                    format = [];
-                    // find out how to copy
-                    format.push({ x: true, number: true, required: true });
-                    format.push({ y: true, number: true, required: true });
-
-                    if (s.bars.show || (s.lines.show && s.lines.fill)) {
-                        format.push({ y: true, number: true, required: false, defaultValue: 0 });
-                        if (s.bars.horizontal) {
-                            delete format[format.length - 1].y;
-                            format[format.length - 1].x = true;
-                        }
-                    }
-                    
-                    s.datapoints.format = format;
-                }
-
-                if (s.datapoints.pointsize != null)
-                    continue; // already filled in
-
-                s.datapoints.pointsize = format.length;
-                
-                ps = s.datapoints.pointsize;
-                points = s.datapoints.points;
-
-                insertSteps = s.lines.show && s.lines.steps;
-                s.xaxis.used = s.yaxis.used = true;
-                
-                for (j = k = 0; j < data.length; ++j, k += ps) {
-                    p = data[j];
-
-                    var nullify = p == null;
-                    if (!nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = p[m];
-                            f = format[m];
-
-                            if (f) {
-                                if (f.number && val != null) {
-                                    val = +val; // convert to number
-                                    if (isNaN(val))
-                                        val = null;
-                                    else if (val == Infinity)
-                                        val = fakeInfinity;
-                                    else if (val == -Infinity)
-                                        val = -fakeInfinity;
-                                }
-
-                                if (val == null) {
-                                    if (f.required)
-                                        nullify = true;
-                                    
-                                    if (f.defaultValue != null)
-                                        val = f.defaultValue;
-                                }
-                            }
-                            
-                            points[k + m] = val;
-                        }
-                    }
-                    
-                    if (nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = points[k + m];
-                            if (val != null) {
-                                f = format[m];
-                                // extract min/max info
-                                if (f.x)
-                                    updateAxis(s.xaxis, val, val);
-                                if (f.y)
-                                    updateAxis(s.yaxis, val, val);
-                            }
-                            points[k + m] = null;
-                        }
-                    }
-                    else {
-                        // a little bit of line specific stuff that
-                        // perhaps shouldn't be here, but lacking
-                        // better means...
-                        if (insertSteps && k > 0
-                            && points[k - ps] != null
-                            && points[k - ps] != points[k]
-                            && points[k - ps + 1] != points[k + 1]) {
-                            // copy the point to make room for a middle point
-                            for (m = 0; m < ps; ++m)
-                                points[k + ps + m] = points[k + m];
-
-                            // middle point has same y
-                            points[k + 1] = points[k - ps + 1];
-
-                            // we've added a point, better reflect that
-                            k += ps;
-                        }
-                    }
-                }
-            }
-
-            // give the hooks a chance to run
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
-            }
-
-            // second pass: find datamax/datamin for auto-scaling
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                points = s.datapoints.points,
-                ps = s.datapoints.pointsize;
-
-                var xmin = topSentry, ymin = topSentry,
-                    xmax = bottomSentry, ymax = bottomSentry;
-                
-                for (j = 0; j < points.length; j += ps) {
-                    if (points[j] == null)
-                        continue;
-
-                    for (m = 0; m < ps; ++m) {
-                        val = points[j + m];
-                        f = format[m];
-                        if (!f || val == fakeInfinity || val == -fakeInfinity)
-                            continue;
-                        
-                        if (f.x) {
-                            if (val < xmin)
-                                xmin = val;
-                            if (val > xmax)
-                                xmax = val;
-                        }
-                        if (f.y) {
-                            if (val < ymin)
-                                ymin = val;
-                            if (val > ymax)
-                                ymax = val;
-                        }
-                    }
-                }
-                
-                if (s.bars.show) {
-                    // make sure we got room for the bar on the dancing floor
-                    var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
-                    if (s.bars.horizontal) {
-                        ymin += delta;
-                        ymax += delta + s.bars.barWidth;
-                    }
-                    else {
-                        xmin += delta;
-                        xmax += delta + s.bars.barWidth;
-                    }
-                }
-                
-                updateAxis(s.xaxis, xmin, xmax);
-                updateAxis(s.yaxis, ymin, ymax);
-            }
-
-            $.each(allAxes(), function (_, axis) {
-                if (axis.datamin == topSentry)
-                    axis.datamin = null;
-                if (axis.datamax == bottomSentry)
-                    axis.datamax = null;
-            });
-        }
-
-        function makeCanvas(skipPositioning, cls) {
-            var c = document.createElement('canvas');
-            c.className = cls;
-            c.width = canvasWidth;
-            c.height = canvasHeight;
-                    
-            if (!skipPositioning)
-                $(c).css({ position: 'absolute', left: 0, top: 0 });
-                
-            $(c).appendTo(placeholder);
-                
-            if (!c.getContext) // excanvas hack
-                c = window.G_vmlCanvasManager.initElement(c);
-
-            // used for resetting in case we get replotted
-            c.getContext("2d").save();
-            
-            return c;
-        }
-
-        function getCanvasDimensions() {
-            canvasWidth = placeholder.width();
-            canvasHeight = placeholder.height();
-            
-            if (canvasWidth <= 0 || canvasHeight <= 0)
-                throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
-        }
-
-        function resizeCanvas(c) {
-            // resizing should reset the state (excanvas seems to be
-            // buggy though)
-            if (c.width != canvasWidth)
-                c.width = canvasWidth;
-
-            if (c.height != canvasHeight)
-                c.height = canvasHeight;
-
-            // so try to get back to the initial state (even if it's
-            // gone now, this should be safe according to the spec)
-            var cctx = c.getContext("2d");
-            cctx.restore();
-
-            // and save again
-            cctx.save();
-        }
-        
-        function setupCanvases() {
-            var reused,
-                existingCanvas = placeholder.children("canvas.base"),
-                existingOverlay = placeholder.children("canvas.overlay");
-
-            if (existingCanvas.length == 0 || existingOverlay == 0) {
-                // init everything
-                
-                placeholder.html(""); // make sure placeholder is clear
-            
-                placeholder.css({ padding: 0 }); // padding messes up the positioning
-                
-                if (placeholder.css("position") == 'static')
-                    placeholder.css("position", "relative"); // for positioning labels and overlay
-
-                getCanvasDimensions();
-                
-                canvas = makeCanvas(true, "base");
-                overlay = makeCanvas(false, "overlay"); // overlay canvas for interactive features
-
-                reused = false;
-            }
-            else {
-                // reuse existing elements
-
-                canvas = existingCanvas.get(0);
-                overlay = existingOverlay.get(0);
-
-                reused = true;
-            }
-
-            ctx = canvas.getContext("2d");
-            octx = overlay.getContext("2d");
-
-            // we include the canvas in the event holder too, because IE 7
-            // sometimes has trouble with the stacking order
-            eventHolder = $([overlay, canvas]);
-
-            if (reused) {
-                // run shutdown in the old plot object
-                placeholder.data("plot").shutdown();
-
-                // reset reused canvases
-                plot.resize();
-                
-                // make sure overlay pixels are cleared (canvas is cleared when we redraw)
-                octx.clearRect(0, 0, canvasWidth, canvasHeight);
-                
-                // then whack any remaining obvious garbage left
-                eventHolder.unbind();
-                placeholder.children().not([canvas, overlay]).remove();
-            }
-
-            // save in case we get replotted
-            placeholder.data("plot", plot);
-        }
-
-        function bindEvents() {
-            // bind events
-            if (options.grid.hoverable) {
-                eventHolder.mousemove(onMouseMove);
-                eventHolder.mouseleave(onMouseLeave);
-            }
-
-            if (options.grid.clickable)
-                eventHolder.click(onClick);
-
-            executeHooks(hooks.bindEvents, [eventHolder]);
-        }
-
-        function shutdown() {
-            if (redrawTimeout)
-                clearTimeout(redrawTimeout);
-            
-            eventHolder.unbind("mousemove", onMouseMove);
-            eventHolder.unbind("mouseleave", onMouseLeave);
-            eventHolder.unbind("click", onClick);
-            
-            executeHooks(hooks.shutdown, [eventHolder]);
-        }
-
-        function setTransformationHelpers(axis) {
-            // set helper functions on the axis, assumes plot area
-            // has been computed already
-            
-            function identity(x) { return x; }
-            
-            var s, m, t = axis.options.transform || identity,
-                it = axis.options.inverseTransform;
-            
-            // precompute how much the axis is scaling a point
-            // in canvas space
-            if (axis.direction == "x") {
-                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
-                m = Math.min(t(axis.max), t(axis.min));
-            }
-            else {
-                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
-                s = -s;
-                m = Math.max(t(axis.max), t(axis.min));
-            }
-
-            // data point to canvas coordinate
-            if (t == identity) // slight optimization
-                axis.p2c = function (p) { return (p - m) * s; };
-            else
-                axis.p2c = function (p) { return (t(p) - m) * s; };
-            // canvas coordinate to data point
-            if (!it)
-                axis.c2p = function (c) { return m + c / s; };
-            else
-                axis.c2p = function (c) { return it(m + c / s); };
-        }
-
-        function measureTickLabels(axis) {
-            var opts = axis.options, i, ticks = axis.ticks || [], labels = [],
-                l, w = opts.labelWidth, h = opts.labelHeight, dummyDiv;
-
-            function makeDummyDiv(labels, width) {
-                return $('<div style="position:absolute;top:-10000px;' + width + 'font-size:smaller">' +
-                         '<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis">'
-                         + labels.join("") + '</div></div>')
-                    .appendTo(placeholder);
-            }
-            
-            if (axis.direction == "x") {
-                // to avoid measuring the widths of the labels (it's slow), we
-                // construct fixed-size boxes and put the labels inside
-                // them, we don't need the exact figures and the
-                // fixed-size box content is easy to center
-                if (w == null)
-                    w = Math.floor(canvasWidth / (ticks.length > 0 ? ticks.length : 1));
-
-                // measure x label heights
-                if (h == null) {
-                    labels = [];
-                    for (i = 0; i < ticks.length; ++i) {
-                        l = ticks[i].label;
-                        if (l)
-                            labels.push('<div class="tickLabel" style="float:left;width:' + w + 'px">' + l + '</div>');
-                    }
-
-                    if (labels.length > 0) {
-                        // stick them all in the same div and measure
-                        // collective height
-                        labels.push('<div style="clear:left"></div>');
-                        dummyDiv = makeDummyDiv(labels, "width:10000px;");
-                        h = dummyDiv.height();
-                        dummyDiv.remove();
-                    }
-                }
-            }
-            else if (w == null || h == null) {
-                // calculate y label dimensions
-                for (i = 0; i < ticks.length; ++i) {
-                    l = ticks[i].label;
-                    if (l)
-                        labels.push('<div class="tickLabel">' + l + '</div>');
-                }
-                
-                if (labels.length > 0) {
-                    dummyDiv = makeDummyDiv(labels, "");
-                    if (w == null)
-                        w = dummyDiv.children().width();
-                    if (h == null)
-                        h = dummyDiv.find("div.tickLabel").height();
-                    dummyDiv.remove();
-                }
-            }
-
-            if (w == null)
-                w = 0;
-            if (h == null)
-                h = 0;
-
-            axis.labelWidth = w;
-            axis.labelHeight = h;
-        }
-
-        function allocateAxisBoxFirstPhase(axis) {
-            // find the bounding box of the axis by looking at label
-            // widths/heights and ticks, make room by diminishing the
-            // plotOffset
-
-            var lw = axis.labelWidth,
-                lh = axis.labelHeight,
-                pos = axis.options.position,
-                tickLength = axis.options.tickLength,
-                axismargin = options.grid.axisMargin,
-                padding = options.grid.labelMargin,
-                all = axis.direction == "x" ? xaxes : yaxes,
-                index;
-
-            // determine axis margin
-            var samePosition = $.grep(all, function (a) {
-                return a && a.options.position == pos && a.reserveSpace;
-            });
-            if ($.inArray(axis, samePosition) == samePosition.length - 1)
-                axismargin = 0; // outermost
-
-            // determine tick length - if we're innermost, we can use "full"
-            if (tickLength == null)
-                tickLength = "full";
-
-            var sameDirection = $.grep(all, function (a) {
-                return a && a.reserveSpace;
-            });
-
-            var innermost = $.inArray(axis, sameDirection) == 0;
-            if (!innermost && tickLength == "full")
-                tickLength = 5;
-                
-            if (!isNaN(+tickLength))
-                padding += +tickLength;
-
-            // compute box
-            if (axis.direction == "x") {
-                lh += padding;
-                
-                if (pos == "bottom") {
-                    plotOffset.bottom += lh + axismargin;
-                    axis.box = { top: canvasHeight - plotOffset.bottom, height: lh };
-                }
-                else {
-                    axis.box = { top: plotOffset.top + axismargin, height: lh };
-                    plotOffset.top += lh + axismargin;
-                }
-            }
-            else {
-                lw += padding;
-                
-                if (pos == "left") {
-                    axis.box = { left: plotOffset.left + axismargin, width: lw };
-                    plotOffset.left += lw + axismargin;
-                }
-                else {
-                    plotOffset.right += lw + axismargin;
-                    axis.box = { left: canvasWidth - plotOffset.right, width: lw };
-                }
-            }
-
-             // save for future reference
-            axis.position = pos;
-            axis.tickLength = tickLength;
-            axis.box.padding = padding;
-            axis.innermost = innermost;
-        }
-
-        function allocateAxisBoxSecondPhase(axis) {
-            // set remaining bounding box coordinates
-            if (axis.direction == "x") {
-                axis.box.left = plotOffset.left;
-                axis.box.width = plotWidth;
-            }
-            else {
-                axis.box.top = plotOffset.top;
-                axis.box.height = plotHeight;
-            }
-        }
-        
-        function setupGrid() {
-            var i, axes = allAxes();
-
-            // first calculate the plot and axis box dimensions
-
-            $.each(axes, function (_, axis) {
-                axis.show = axis.options.show;
-                if (axis.show == null)
-                    axis.show = axis.used; // by default an axis is visible if it's got data
-                
-                axis.reserveSpace = axis.show || axis.options.reserveSpace;
-
-                setRange(axis);
-            });
-
-            allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });
-
-            plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
-            if (options.grid.show) {
-                $.each(allocatedAxes, function (_, axis) {
-                    // make the ticks
-                    setupTickGeneration(axis);
-                    setTicks(axis);
-                    snapRangeToTicks(axis, axis.ticks);
-
-                    // find labelWidth/Height for axis
-                    measureTickLabels(axis);
-                });
-
-                // with all dimensions in house, we can compute the
-                // axis boxes, start from the outside (reverse order)
-                for (i = allocatedAxes.length - 1; i >= 0; --i)
-                    allocateAxisBoxFirstPhase(allocatedAxes[i]);
-
-                // make sure we've got enough space for things that
-                // might stick out
-                var minMargin = options.grid.minBorderMargin;
-                if (minMargin == null) {
-                    minMargin = 0;
-                    for (i = 0; i < series.length; ++i)
-                        minMargin = Math.max(minMargin, series[i].points.radius + series[i].points.lineWidth/2);
-                }
-                    
-                for (var a in plotOffset) {
-                    plotOffset[a] += options.grid.borderWidth;
-                    plotOffset[a] = Math.max(minMargin, plotOffset[a]);
-                }
-            }
-            
-            plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
-            plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
-
-            // now we got the proper plotWidth/Height, we can compute the scaling
-            $.each(axes, function (_, axis) {
-                setTransformationHelpers(axis);
-            });
-
-            if (options.grid.show) {
-                $.each(allocatedAxes, function (_, axis) {
-                    allocateAxisBoxSecondPhase(axis);
-                });
-
-                insertAxisLabels();
-            }
-            
-            insertLegend();
-        }
-        
-        function setRange(axis) {
-            var opts = axis.options,
-                min = +(opts.min != null ? opts.min : axis.datamin),
-                max = +(opts.max != null ? opts.max : axis.datamax),
-                delta = max - min;
-
-            if (delta == 0.0) {
-                // degenerate case
-                var widen = max == 0 ? 1 : 0.01;
-
-                if (opts.min == null)
-                    min -= widen;
-                // always widen max if we couldn't widen min to ensure we
-                // don't fall into min == max which doesn't work
-                if (opts.max == null || opts.min != null)
-                    max += widen;
-            }
-            else {
-                // consider autoscaling
-                var margin = opts.autoscaleMargin;
-                if (margin != null) {
-                    if (opts.min == null) {
-                        min -= delta * margin;
-                        // make sure we don't go below zero if all values
-                        // are positive
-                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
-                            min = 0;
-                    }
-                    if (opts.max == null) {
-                        max += delta * margin;
-                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
-                            max = 0;
-                    }
-                }
-            }
-            axis.min = min;
-            axis.max = max;
-        }
-
-        function setupTickGeneration(axis) {
-            var opts = axis.options;
-                
-            // estimate number of ticks
-            var noTicks;
-            if (typeof opts.ticks == "number" && opts.ticks > 0)
-                noTicks = opts.ticks;
-            else
-                // heuristic based on the model a*sqrt(x) fitted to
-                // some data points that seemed reasonable
-                noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? canvasWidth : canvasHeight);
-
-            var delta = (axis.max - axis.min) / noTicks,
-                size, generator, unit, formatter, i, magn, norm;
-
-            if (opts.mode == "time") {
-                // pretty handling of time
-                
-                // map of app. size of time units in milliseconds
-                var timeUnitSize = {
-                    "second": 1000,
-                    "minute": 60 * 1000,
-                    "hour": 60 * 60 * 1000,
-                    "day": 24 * 60 * 60 * 1000,
-                    "month": 30 * 24 * 60 * 60 * 1000,
-                    "year": 365.2425 * 24 * 60 * 60 * 1000
-                };
-
-
-                // the allowed tick sizes, after 1 year we use
-                // an integer algorithm
-                var spec = [
-                    [1, "second"], [2, "second"], [5, "second"], [10, "second"],
-                    [30, "second"], 
-                    [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
-                    [30, "minute"], 
-                    [1, "hour"], [2, "hour"], [4, "hour"],
-                    [8, "hour"], [12, "hour"],
-                    [1, "day"], [2, "day"], [3, "day"],
-                    [0.25, "month"], [0.5, "month"], [1, "month"],
-                    [2, "month"], [3, "month"], [6, "month"],
-                    [1, "year"]
-                ];
-
-                var minSize = 0;
-                if (opts.minTickSize != null) {
-                    if (typeof opts.tickSize == "number")
-                        minSize = opts.tickSize;
-                    else
-                        minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
-                }
-
-                for (var i = 0; i < spec.length - 1; ++i)
-                    if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
-                                 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
-                       && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
-                        break;
-                size = spec[i][0];
-                unit = spec[i][1];
-                
-                // special-case the possibility of several years
-                if (unit == "year") {
-                    magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
-                    norm = (delta / timeUnitSize.year) / magn;
-                    if (norm < 1.5)
-                        size = 1;
-                    else if (norm < 3)
-                        size = 2;
-                    else if (norm < 7.5)
-                        size = 5;
-                    else
-                        size = 10;
-
-                    size *= magn;
-                }
-
-                axis.tickSize = opts.tickSize || [size, unit];
-                
-                generator = function(axis) {
-                    var ticks = [],
-                        tickSize = axis.tickSize[0], unit = axis.tickSize[1],
-                        d = new Date(axis.min);
-                    
-                    var step = tickSize * timeUnitSize[unit];
-
-                    if (unit == "second")
-                        d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
-                    if (unit == "minute")
-                        d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
-                    if (unit == "hour")
-                        d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
-                    if (unit == "month")
-                        d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
-                    if (unit == "year")
-                        d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
-                    
-                    // reset smaller components
-                    d.setUTCMilliseconds(0);
-                    if (step >= timeUnitSize.minute)
-                        d.setUTCSeconds(0);
-                    if (step >= timeUnitSize.hour)
-                        d.setUTCMinutes(0);
-                    if (step >= timeUnitSize.day)
-                        d.setUTCHours(0);
-                    if (step >= timeUnitSize.day * 4)
-                        d.setUTCDate(1);
-                    if (step >= timeUnitSize.year)
-                        d.setUTCMonth(0);
-
-
-                    var carry = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = d.getTime();
-                        ticks.push(v);
-                        if (unit == "month") {
-                            if (tickSize < 1) {
-                                // a bit complicated - we'll divide the month
-                                // up but we need to take care of fractions
-                                // so we don't end up in the middle of a day
-                                d.setUTCDate(1);
-                                var start = d.getTime();
-                                d.setUTCMonth(d.getUTCMonth() + 1);
-                                var end = d.getTime();
-                                d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
-                                carry = d.getUTCHours();
-                                d.setUTCHours(0);
-                            }
-                            else
-                                d.setUTCMonth(d.getUTCMonth() + tickSize);
-                        }
-                        else if (unit == "year") {
-                            d.setUTCFullYear(d.getUTCFullYear() + tickSize);
-                        }
-                        else
-                            d.setTime(v + step);
-                    } while (v < axis.max && v != prev);
-
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    var d = new Date(v);
-
-                    // first check global format
-                    if (opts.timeformat != null)
-                        return $.plot.formatDate(d, opts.timeformat, opts.monthNames);
-                    
-                    var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
-                    var span = axis.max - axis.min;
-                    var suffix = (opts.twelveHourClock) ? " %p" : "";
-                    
-                    if (t < timeUnitSize.minute)
-                        fmt = "%h:%M:%S" + suffix;
-                    else if (t < timeUnitSize.day) {
-                        if (span < 2 * timeUnitSize.day)
-                            fmt = "%h:%M" + suffix;
-                        else
-                            fmt = "%b %d %h:%M" + suffix;
-                    }
-                    else if (t < timeUnitSize.month)
-                        fmt = "%b %d";
-                    else if (t < timeUnitSize.year) {
-                        if (span < timeUnitSize.year)
-                            fmt = "%b";
-                        else
-                            fmt = "%b %y";
-                    }
-                    else
-                        fmt = "%y";
-                    
-                    return $.plot.formatDate(d, fmt, opts.monthNames);
-                };
-            }
-            else {
-                // pretty rounding of base-10 numbers
-                var maxDec = opts.tickDecimals;
-                var dec = -Math.floor(Math.log(delta) / Math.LN10);
-                if (maxDec != null && dec > maxDec)
-                    dec = maxDec;
-
-                magn = Math.pow(10, -dec);
-                norm = delta / magn; // norm is between 1.0 and 10.0
-                
-                if (norm < 1.5)
-                    size = 1;
-                else if (norm < 3) {
-                    size = 2;
-                    // special case for 2.5, requires an extra decimal
-                    if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
-                        size = 2.5;
-                        ++dec;
-                    }
-                }
-                else if (norm < 7.5)
-                    size = 5;
-                else
-                    size = 10;
-
-                size *= magn;
-                
-                if (opts.minTickSize != null && size < opts.minTickSize)
-                    size = opts.minTickSize;
-
-                axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
-                axis.tickSize = opts.tickSize || size;
-
-                generator = function (axis) {
-                    var ticks = [];
-
-                    // spew out all possible ticks
-                    var start = floorInBase(axis.min, axis.tickSize),
-                        i = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = start + i * axis.tickSize;
-                        ticks.push(v);
-                        ++i;
-                    } while (v < axis.max && v != prev);
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    return v.toFixed(axis.tickDecimals);
-                };
-            }
-
-            if (opts.alignTicksWithAxis != null) {
-                var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
-                if (otherAxis && otherAxis.used && otherAxis != axis) {
-                    // consider snapping min/max to outermost nice ticks
-                    var niceTicks = generator(axis);
-                    if (niceTicks.length > 0) {
-                        if (opts.min == null)
-                            axis.min = Math.min(axis.min, niceTicks[0]);
-                        if (opts.max == null && niceTicks.length > 1)
-                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
-                    }
-                    
-                    generator = function (axis) {
-                        // copy ticks, scaled to this axis
-                        var ticks = [], v, i;
-                        for (i = 0; i < otherAxis.ticks.length; ++i) {
-                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
-                            v = axis.min + v * (axis.max - axis.min);
-                            ticks.push(v);
-                        }
-                        return ticks;
-                    };
-                    
-                    // we might need an extra decimal since forced
-                    // ticks don't necessarily fit naturally
-                    if (axis.mode != "time" && opts.tickDecimals == null) {
-                        var extraDec = Math.max(0, -Math.floor(Math.log(delta) / Math.LN10) + 1),
-                            ts = generator(axis);
-
-                        // only proceed if the tick interval rounded
-                        // with an extra decimal doesn't give us a
-                        // zero at end
-                        if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
-                            axis.tickDecimals = extraDec;
-                    }
-                }
-            }
-
-            axis.tickGenerator = generator;
-            if ($.isFunction(opts.tickFormatter))
-                axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
-            else
-                axis.tickFormatter = formatter;
-        }
-        
-        function setTicks(axis) {
-            var oticks = axis.options.ticks, ticks = [];
-            if (oticks == null || (typeof oticks == "number" && oticks > 0))
-                ticks = axis.tickGenerator(axis);
-            else if (oticks) {
-                if ($.isFunction(oticks))
-                    // generate the ticks
-                    ticks = oticks({ min: axis.min, max: axis.max });
-                else
-                    ticks = oticks;
-            }
-
-            // clean up/labelify the supplied ticks, copy them over
-            var i, v;
-            axis.ticks = [];
-            for (i = 0; i < ticks.length; ++i) {
-                var label = null;
-                var t = ticks[i];
-                if (typeof t == "object") {
-                    v = +t[0];
-                    if (t.length > 1)
-                        label = t[1];
-                }
-                else
-                    v = +t;
-                if (label == null)
-                    label = axis.tickFormatter(v, axis);
-                if (!isNaN(v))
-                    axis.ticks.push({ v: v, label: label });
-            }
-        }
-
-        function snapRangeToTicks(axis, ticks) {
-            if (axis.options.autoscaleMargin && ticks.length > 0) {
-                // snap to ticks
-                if (axis.options.min == null)
-                    axis.min = Math.min(axis.min, ticks[0].v);
-                if (axis.options.max == null && ticks.length > 1)
-                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
-            }
-        }
-      
-        function draw() {
-            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
-
-            var grid = options.grid;
-
-            // draw background, if any
-            if (grid.show && grid.backgroundColor)
-                drawBackground();
-            
-            if (grid.show && !grid.aboveData)
-                drawGrid();
-
-            for (var i = 0; i < series.length; ++i) {
-                executeHooks(hooks.drawSeries, [ctx, series[i]]);
-                drawSeries(series[i]);
-            }
-
-            executeHooks(hooks.draw, [ctx]);
-            
-            if (grid.show && grid.aboveData)
-                drawGrid();
-        }
-
-        function extractRange(ranges, coord) {
-            var axis, from, to, key, axes = allAxes();
-
-            for (i = 0; i < axes.length; ++i) {
-                axis = axes[i];
-                if (axis.direction == coord) {
-                    key = coord + axis.n + "axis";
-                    if (!ranges[key] && axis.n == 1)
-                        key = coord + "axis"; // support x1axis as xaxis
-                    if (ranges[key]) {
-                        from = ranges[key].from;
-                        to = ranges[key].to;
-                        break;
-                    }
-                }
-            }
-
-            // backwards-compat stuff - to be removed in future
-            if (!ranges[key]) {
-                axis = coord == "x" ? xaxes[0] : yaxes[0];
-                from = ranges[coord + "1"];
-                to = ranges[coord + "2"];
-            }
-
-            // auto-reverse as an added bonus
-            if (from != null && to != null && from > to) {
-                var tmp = from;
-                from = to;
-                to = tmp;
-            }
-            
-            return { from: from, to: to, axis: axis };
-        }
-        
-        function drawBackground() {
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
-            ctx.fillRect(0, 0, plotWidth, plotHeight);
-            ctx.restore();
-        }
-
-        function drawGrid() {
-            var i;
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // draw markings
-            var markings = options.grid.markings;
-            if (markings) {
-                if ($.isFunction(markings)) {
-                    var axes = plot.getAxes();
-                    // xmin etc. is backwards compatibility, to be
-                    // removed in the future
-                    axes.xmin = axes.xaxis.min;
-                    axes.xmax = axes.xaxis.max;
-                    axes.ymin = axes.yaxis.min;
-                    axes.ymax = axes.yaxis.max;
-                    
-                    markings = markings(axes);
-                }
-
-                for (i = 0; i < markings.length; ++i) {
-                    var m = markings[i],
-                        xrange = extractRange(m, "x"),
-                        yrange = extractRange(m, "y");
-
-                    // fill in missing
-                    if (xrange.from == null)
-                        xrange.from = xrange.axis.min;
-                    if (xrange.to == null)
-                        xrange.to = xrange.axis.max;
-                    if (yrange.from == null)
-                        yrange.from = yrange.axis.min;
-                    if (yrange.to == null)
-                        yrange.to = yrange.axis.max;
-
-                    // clip
-                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
-                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
-                        continue;
-
-                    xrange.from = Math.max(xrange.from, xrange.axis.min);
-                    xrange.to = Math.min(xrange.to, xrange.axis.max);
-                    yrange.from = Math.max(yrange.from, yrange.axis.min);
-                    yrange.to = Math.min(yrange.to, yrange.axis.max);
-
-                    if (xrange.from == xrange.to && yrange.from == yrange.to)
-                        continue;
-
-                    // then draw
-                    xrange.from = xrange.axis.p2c(xrange.from);
-                    xrange.to = xrange.axis.p2c(xrange.to);
-                    yrange.from = yrange.axis.p2c(yrange.from);
-                    yrange.to = yrange.axis.p2c(yrange.to);
-                    
-                    if (xrange.from == xrange.to || yrange.from == yrange.to) {
-                        // draw line
-                        ctx.beginPath();
-                        ctx.strokeStyle = m.color || options.grid.markingsColor;
-                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
-                        ctx.moveTo(xrange.from, yrange.from);
-                        ctx.lineTo(xrange.to, yrange.to);
-                        ctx.stroke();
-                    }
-                    else {
-                        // fill area
-                        ctx.fillStyle = m.color || options.grid.markingsColor;
-                        ctx.fillRect(xrange.from, yrange.to,
-                                     xrange.to - xrange.from,
-                                     yrange.from - yrange.to);
-                    }
-                }
-            }
-            
-            // draw the ticks
-            var axes = allAxes(), bw = options.grid.borderWidth;
-
-            for (var j = 0; j < axes.length; ++j) {
-                var axis = axes[j], box = axis.box,
-                    t = axis.tickLength, x, y, xoff, yoff;
-                if (!axis.show || axis.ticks.length == 0)
-                    continue
-                
-                ctx.strokeStyle = axis.options.tickColor || $.color.parse(axis.options.color).scale('a', 0.22).toString();
-                ctx.lineWidth = 1;
-
-                // find the edges
-                if (axis.direction == "x") {
-                    x = 0;
-                    if (t == "full")
-                        y = (axis.position == "top" ? 0 : plotHeight);
-                    else
-                        y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
-                }
-                else {
-                    y = 0;
-                    if (t == "full")
-                        x = (axis.position == "left" ? 0 : plotWidth);
-                    else
-                        x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
-                }
-                
-                // draw tick bar
-                if (!axis.innermost) {
-                    ctx.beginPath();
-                    xoff = yoff = 0;
-                    if (axis.direction == "x")
-                        xoff = plotWidth;
-                    else
-                        yoff = plotHeight;
-                    
-                    if (ctx.lineWidth == 1) {
-                        x = Math.floor(x) + 0.5;
-                        y = Math.floor(y) + 0.5;
-                    }
-
-                    ctx.moveTo(x, y);
-                    ctx.lineTo(x + xoff, y + yoff);
-                    ctx.stroke();
-                }
-
-                // draw ticks
-                ctx.beginPath();
-                for (i = 0; i < axis.ticks.length; ++i) {
-                    var v = axis.ticks[i].v;
-                    
-                    xoff = yoff = 0;
-
-                    if (v < axis.min || v > axis.max
-                        // skip those lying on the axes if we got a border
-                        || (t == "full" && bw > 0
-                            && (v == axis.min || v == axis.max)))
-                        continue;
-
-                    if (axis.direction == "x") {
-                        x = axis.p2c(v);
-                        yoff = t == "full" ? -plotHeight : t;
-                        
-                        if (axis.position == "top")
-                            yoff = -yoff;
-                    }
-                    else {
-                        y = axis.p2c(v);
-                        xoff = t == "full" ? -plotWidth : t;
-                        
-                        if (axis.position == "left")
-                            xoff = -xoff;
-                    }
-
-                    if (ctx.lineWidth == 1) {
-                        if (axis.direction == "x")
-                            x = Math.floor(x) + 0.5;
-                        else
-                            y = Math.floor(y) + 0.5;
-                    }
-
-                    ctx.moveTo(x, y);
-                    ctx.lineTo(x + xoff, y + yoff);
-                }
-                
-                ctx.stroke();
-            }
-            
-            
-            // draw border
-            if (bw) {
-                ctx.lineWidth = bw;
-                ctx.strokeStyle = options.grid.borderColor;
-                ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
-            }
-
-            ctx.restore();
-        }
-
-        function insertAxisLabels() {
-            placeholder.find(".tickLabels").remove();
-            
-            var html = ['<div class="tickLabels" style="font-size:smaller">'];
-
-            var axes = allAxes();
-            for (var j = 0; j < axes.length; ++j) {
-                var axis = axes[j], box = axis.box;
-                if (!axis.show)
-                    continue;
-                //debug: html.push('<div style="position:absolute;opacity:0.10;background-color:red;left:' + box.left + 'px;top:' + box.top + 'px;width:' + box.width +  'px;height:' + box.height + 'px"></div>')
-                html.push('<div class="' + axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis" style="color:' + axis.options.color + '">');
-                for (var i = 0; i < axis.ticks.length; ++i) {
-                    var tick = axis.ticks[i];
-                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
-                        continue;
-
-                    var pos = {}, align;
-                    
-                    if (axis.direction == "x") {
-                        align = "center";
-                        pos.left = Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2);
-                        if (axis.position == "bottom")
-                            pos.top = box.top + box.padding;
-                        else
-                            pos.bottom = canvasHeight - (box.top + box.height - box.padding);
-                    }
-                    else {
-                        pos.top = Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2);
-                        if (axis.position == "left") {
-                            pos.right = canvasWidth - (box.left + box.width - box.padding)
-                            align = "right";
-                        }
-                        else {
-                            pos.left = box.left + box.padding;
-                            align = "left";
-                        }
-                    }
-
-                    pos.width = axis.labelWidth;
-
-                    var style = ["position:absolute", "text-align:" + align ];
-                    for (var a in pos)
-                        style.push(a + ":" + pos[a] + "px")
-                    
-                    html.push('<div class="tickLabel" style="' + style.join(';') + '">' + tick.label + '</div>');
-                }
-                html.push('</div>');
-            }
-
-            html.push('</div>');
-
-            placeholder.append(html.join(""));
-        }
-
-        function drawSeries(series) {
-            if (series.lines.show)
-                drawSeriesLines(series);
-            if (series.bars.show)
-                drawSeriesBars(series);
-            if (series.points.show)
-                drawSeriesPoints(series);
-        }
-        
-        function drawSeriesLines(series) {
-            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    prevx = null, prevy = null;
-                
-                ctx.beginPath();
-                for (var i = ps; i < points.length; i += ps) {
-                    var x1 = points[i - ps], y1 = points[i - ps + 1],
-                        x2 = points[i], y2 = points[i + 1];
-                    
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min) {
-                        if (y2 < axisy.min)
-                            continue;   // line segment is outside
-                        // compute new intersection point
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min) {
-                        if (y1 < axisy.min)
-                            continue;
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max) {
-                        if (y2 > axisy.max)
-                            continue;
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max) {
-                        if (y1 > axisy.max)
-                            continue;
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (x1 != prevx || y1 != prevy)
-                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
-                    
-                    prevx = x2;
-                    prevy = y2;
-                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
-                }
-                ctx.stroke();
-            }
-
-            function plotLineArea(datapoints, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
-                    i = 0, top, areaOpen = false,
-                    ypos = 1, segmentStart = 0, segmentEnd = 0;
-
-                // we process each segment in two turns, first forward
-                // direction to sketch out top, then once we hit the
-                // end we go backwards to sketch the bottom
-                while (true) {
-                    if (ps > 0 && i > points.length + ps)
-                        break;
-
-                    i += ps; // ps is negative if going backwards
-
-                    var x1 = points[i - ps],
-                        y1 = points[i - ps + ypos],
-                        x2 = points[i], y2 = points[i + ypos];
-
-                    if (areaOpen) {
-                        if (ps > 0 && x1 != null && x2 == null) {
-                            // at turning point
-                            segmentEnd = i;
-                            ps = -ps;
-                            ypos = 2;
-                            continue;
-                        }
-
-                        if (ps < 0 && i == segmentStart + ps) {
-                            // done with the reverse sweep
-                            ctx.fill();
-                            areaOpen = false;
-                            ps = -ps;
-                            ypos = 1;
-                            i = segmentStart = segmentEnd + ps;
-                            continue;
-                        }
-                    }
-
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip x values
-                    
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (!areaOpen) {
-                        // open area
-                        ctx.beginPath();
-                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
-                        areaOpen = true;
-                    }
-                    
-                    // now first check the case where both is outside
-                    if (y1 >= axisy.max && y2 >= axisy.max) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
-                        continue;
-                    }
-                    else if (y1 <= axisy.min && y2 <= axisy.min) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
-                        continue;
-                    }
-                    
-                    // else it's a bit more complicated, there might
-                    // be a flat maxed out rectangle first, then a
-                    // triangular cutout or reverse; to find these
-                    // keep track of the current x values
-                    var x1old = x1, x2old = x2;
-
-                    // clip the y values, without shortcutting, we
-                    // go through all cases in turn
-                    
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-                    // if the x value was changed we got a rectangle
-                    // to fill
-                    if (x1 != x1old) {
-                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
-                        // it goes to (x1, y1), but we fill that below
-                    }
-                    
-                    // fill triangular section, this sometimes result
-                    // in redundant points if (x1, y1) hasn't changed
-                    // from previous line to, but we just ignore that
-                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
-                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-
-                    // fill the other rectangle if it's there
-                    if (x2 != x2old) {
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
-                    }
-                }
-            }
-
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-            ctx.lineJoin = "round";
-
-            var lw = series.lines.lineWidth,
-                sw = series.shadowSize;
-            // FIXME: consider another form of shadow when filling is turned on
-            if (lw > 0 && sw > 0) {
-                // draw shadow as a thick and thin line with transparency
-                ctx.lineWidth = sw;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                // position shadow at angle from the mid of line
-                var angle = Math.PI/18;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
-                ctx.lineWidth = sw/2;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
-            if (fillStyle) {
-                ctx.fillStyle = fillStyle;
-                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
-            }
-
-            if (lw > 0)
-                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function drawSeriesPoints(series) {
-            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-
-                for (var i = 0; i < points.length; i += ps) {
-                    var x = points[i], y = points[i + 1];
-                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                        continue;
-                    
-                    ctx.beginPath();
-                    x = axisx.p2c(x);
-                    y = axisy.p2c(y) + offset;
-                    if (symbol == "circle")
-                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
-                    else
-                        symbol(ctx, x, y, radius, shadow);
-                    ctx.closePath();
-                    
-                    if (fillStyle) {
-                        ctx.fillStyle = fillStyle;
-                        ctx.fill();
-                    }
-                    ctx.stroke();
-                }
-            }
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            var lw = series.points.lineWidth,
-                sw = series.shadowSize,
-                radius = series.points.radius,
-                symbol = series.points.symbol;
-            if (lw > 0 && sw > 0) {
-                // draw shadow in two steps
-                var w = sw / 2;
-                ctx.lineWidth = w;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                plotPoints(series.datapoints, radius, null, w + w/2, true,
-                           series.xaxis, series.yaxis, symbol);
-
-                ctx.strokeStyle = "rgba(0,0,0,0.2)";
-                plotPoints(series.datapoints, radius, null, w/2, true,
-                           series.xaxis, series.yaxis, symbol);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            plotPoints(series.datapoints, radius,
-                       getFillStyle(series.points, series.color), 0, false,
-                       series.xaxis, series.yaxis, symbol);
-            ctx.restore();
-        }
-
-        function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
-            var left, right, bottom, top,
-                drawLeft, drawRight, drawTop, drawBottom,
-                tmp;
-
-            // in horizontal mode, we start the bar from the left
-            // instead of from the bottom so it appears to be
-            // horizontal rather than vertical
-            if (horizontal) {
-                drawBottom = drawRight = drawTop = true;
-                drawLeft = false;
-                left = b;
-                right = x;
-                top = y + barLeft;
-                bottom = y + barRight;
-
-                // account for negative bars
-                if (right < left) {
-                    tmp = right;
-                    right = left;
-                    left = tmp;
-                    drawLeft = true;
-                    drawRight = false;
-                }
-            }
-            else {
-                drawLeft = drawRight = drawTop = true;
-                drawBottom = false;
-                left = x + barLeft;
-                right = x + barRight;
-                bottom = b;
-                top = y;
-
-                // account for negative bars
-                if (top < bottom) {
-                    tmp = top;
-                    top = bottom;
-                    bottom = tmp;
-                    drawBottom = true;
-                    drawTop = false;
-                }
-            }
-           
-            // clip
-            if (right < axisx.min || left > axisx.max ||
-                top < axisy.min || bottom > axisy.max)
-                return;
-            
-            if (left < axisx.min) {
-                left = axisx.min;
-                drawLeft = false;
-            }
-
-            if (right > axisx.max) {
-                right = axisx.max;
-                drawRight = false;
-            }
-
-            if (bottom < axisy.min) {
-                bottom = axisy.min;
-                drawBottom = false;
-            }
-            
-            if (top > axisy.max) {
-                top = axisy.max;
-                drawTop = false;
-            }
-
-            left = axisx.p2c(left);
-            bottom = axisy.p2c(bottom);
-            right = axisx.p2c(right);
-            top = axisy.p2c(top);
-            
-            // fill the bar
-            if (fillStyleCallback) {
-                c.beginPath();
-                c.moveTo(left, bottom);
-                c.lineTo(left, top);
-                c.lineTo(right, top);
-                c.lineTo(right, bottom);
-                c.fillStyle = fillStyleCallback(bottom, top);
-                c.fill();
-            }
-
-            // draw outline
-            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
-                c.beginPath();
-
-                // FIXME: inline moveTo is buggy with excanvas
-                c.moveTo(left, bottom + offset);
-                if (drawLeft)
-                    c.lineTo(left, top + offset);
-                else
-                    c.moveTo(left, top + offset);
-                if (drawTop)
-                    c.lineTo(right, top + offset);
-                else
-                    c.moveTo(right, top + offset);
-                if (drawRight)
-                    c.lineTo(right, bottom + offset);
-                else
-                    c.moveTo(right, bottom + offset);
-                if (drawBottom)
-                    c.lineTo(left, bottom + offset);
-                else
-                    c.moveTo(left, bottom + offset);
-                c.stroke();
-            }
-        }
-        
-        function drawSeriesBars(series) {
-            function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-                
-                for (var i = 0; i < points.length; i += ps) {
-                    if (points[i] == null)
-                        continue;
-                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
-                }
-            }
-
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // FIXME: figure out a way to add shadows (for instance along the right edge)
-            ctx.lineWidth = series.bars.lineWidth;
-            ctx.strokeStyle = series.color;
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
-            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function getFillStyle(filloptions, seriesColor, bottom, top) {
-            var fill = filloptions.fill;
-            if (!fill)
-                return null;
-
-            if (filloptions.fillColor)
-                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
-            
-            var c = $.color.parse(seriesColor);
-            c.a = typeof fill == "number" ? fill : 0.4;
-            c.normalize();
-            return c.toString();
-        }
-        
-        function insertLegend() {
-            placeholder.find(".legend").remove();
-
-            if (!options.legend.show)
-                return;
-            
-            var fragments = [], rowStarted = false,
-                lf = options.legend.labelFormatter, s, label;
-            for (var i = 0; i < series.length; ++i) {
-                s = series[i];
-                label = s.label;
-                if (!label)
-                    continue;
-                
-                if (i % options.legend.noColumns == 0) {
-                    if (rowStarted)
-                        fragments.push('</tr>');
-                    fragments.push('<tr>');
-                    rowStarted = true;
-                }
-
-                if (lf)
-                    label = lf(label, s);
-                
-                fragments.push(
-                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
-                    '<td class="legendLabel">' + label + '</td>');
-            }
-            if (rowStarted)
-                fragments.push('</tr>');
-            
-            if (fragments.length == 0)
-                return;
-
-            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
-            if (options.legend.container != null)
-                $(options.legend.container).html(table);
-            else {
-                var pos = "",
-                    p = options.legend.position,
-                    m = options.legend.margin;
-                if (m[0] == null)
-                    m = [m, m];
-                if (p.charAt(0) == "n")
-                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
-                else if (p.charAt(0) == "s")
-                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
-                if (p.charAt(1) == "e")
-                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
-                else if (p.charAt(1) == "w")
-                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
-                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
-                if (options.legend.backgroundOpacity != 0.0) {
-                    // put in the transparent background
-                    // separately to avoid blended labels and
-                    // label boxes
-                    var c = options.legend.backgroundColor;
-                    if (c == null) {
-                        c = options.grid.backgroundColor;
-                        if (c && typeof c == "string")
-                            c = $.color.parse(c);
-                        else
-                            c = $.color.extract(legend, 'background-color');
-                        c.a = 1;
-                        c = c.toString();
-                    }
-                    var div = legend.children();
-                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
-                }
-            }
-        }
-
-
-        // interactive features
-        
-        var highlights = [],
-            redrawTimeout = null;
-        
-        // returns the data item the mouse is over, or null if none is found
-        function findNearbyItem(mouseX, mouseY, seriesFilter) {
-            var maxDistance = options.grid.mouseActiveRadius,
-                smallestDistance = maxDistance * maxDistance + 1,
-                item = null, foundPoint = false, i, j;
-
-            for (i = series.length - 1; i >= 0; --i) {
-                if (!seriesFilter(series[i]))
-                    continue;
-                
-                var s = series[i],
-                    axisx = s.xaxis,
-                    axisy = s.yaxis,
-                    points = s.datapoints.points,
-                    ps = s.datapoints.pointsize,
-                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
-                    my = axisy.c2p(mouseY),
-                    maxx = maxDistance / axisx.scale,
-                    maxy = maxDistance / axisy.scale;
-
-                // with inverse transforms, we can't use the maxx/maxy
-                // optimization, sadly
-                if (axisx.options.inverseTransform)
-                    maxx = Number.MAX_VALUE;
-                if (axisy.options.inverseTransform)
-                    maxy = Number.MAX_VALUE;
-                
-                if (s.lines.show || s.points.show) {
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1];
-                        if (x == null)
-                            continue;
-                        
-                        // For points and lines, the cursor must be within a
-                        // certain distance to the data point
-                        if (x - mx > maxx || x - mx < -maxx ||
-                            y - my > maxy || y - my < -maxy)
-                            continue;
-
-                        // We have to calculate distances in pixels, not in
-                        // data units, because the scales of the axes may be different
-                        var dx = Math.abs(axisx.p2c(x) - mouseX),
-                            dy = Math.abs(axisy.p2c(y) - mouseY),
-                            dist = dx * dx + dy * dy; // we save the sqrt
-
-                        // use <= to ensure last point takes precedence
-                        // (last generally means on top of)
-                        if (dist < smallestDistance) {
-                            smallestDistance = dist;
-                            item = [i, j / ps];
-                        }
-                    }
-                }
-                    
-                if (s.bars.show && !item) { // no other point can be nearby
-                    var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
-                        barRight = barLeft + s.bars.barWidth;
-                    
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1], b = points[j + 2];
-                        if (x == null)
-                            continue;
-  
-                        // for a bar graph, the cursor must be inside the bar
-                        if (series[i].bars.horizontal ? 
-                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) && 
-                             my >= y + barLeft && my <= y + barRight) :
-                            (mx >= x + barLeft && mx <= x + barRight &&
-                             my >= Math.min(b, y) && my <= Math.max(b, y)))
-                                item = [i, j / ps];
-                    }
-                }
-            }
-
-            if (item) {
-                i = item[0];
-                j = item[1];
-                ps = series[i].datapoints.pointsize;
-                
-                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
-                         dataIndex: j,
-                         series: series[i],
-                         seriesIndex: i };
-            }
-            
-            return null;
-        }
-
-        function onMouseMove(e) {
-            if (options.grid.hoverable)
-                triggerClickHoverEvent("plothover", e,
-                                       function (s) { return s["hoverable"] != false; });
-        }
-
-        function onMouseLeave(e) {
-            if (options.grid.hoverable)
-                triggerClickHoverEvent("plothover", e,
-                                       function (s) { return false; });
-        }
-
-        function onClick(e) {
-            triggerClickHoverEvent("plotclick", e,
-                                   function (s) { return s["clickable"] != false; });
-        }
-
-        // trigger click or hover event (they send the same parameters
-        // so we share their code)
-        function triggerClickHoverEvent(eventname, event, seriesFilter) {
-            var offset = eventHolder.offset(),
-                canvasX = event.pageX - offset.left - plotOffset.left,
-                canvasY = event.pageY - offset.top - plotOffset.top,
-            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
-
-            pos.pageX = event.pageX;
-            pos.pageY = event.pageY;
-
-            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
-
-            if (item) {
-                // fill in mouse pos for any listeners out there
-                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
-                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
-            }
-
-            if (options.grid.autoHighlight) {
-                // clear auto-highlights
-                for (var i = 0; i < highlights.length; ++i) {
-                    var h = highlights[i];
-                    if (h.auto == eventname &&
-                        !(item && h.series == item.series &&
-                          h.point[0] == item.datapoint[0] &&
-                          h.point[1] == item.datapoint[1]))
-                        unhighlight(h.series, h.point);
-                }
-                
-                if (item)
-                    highlight(item.series, item.datapoint, eventname);
-            }
-            
-            placeholder.trigger(eventname, [ pos, item ]);
-        }
-
-        function triggerRedrawOverlay() {
-            if (!redrawTimeout)
-                redrawTimeout = setTimeout(drawOverlay, 30);
-        }
-
-        function drawOverlay() {
-            redrawTimeout = null;
-
-            // draw highlights
-            octx.save();
-            octx.clearRect(0, 0, canvasWidth, canvasHeight);
-            octx.translate(plotOffset.left, plotOffset.top);
-            
-            var i, hi;
-            for (i = 0; i < highlights.length; ++i) {
-                hi = highlights[i];
-
-                if (hi.series.bars.show)
-                    drawBarHighlight(hi.series, hi.point);
-                else
-                    drawPointHighlight(hi.series, hi.point);
-            }
-            octx.restore();
-            
-            executeHooks(hooks.drawOverlay, [octx]);
-        }
-        
-        function highlight(s, point, auto) {
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number") {
-                var ps = s.datapoints.pointsize;
-                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
-            }
-
-            var i = indexOfHighlight(s, point);
-            if (i == -1) {
-                highlights.push({ series: s, point: point, auto: auto });
-
-                triggerRedrawOverlay();
-            }
-            else if (!auto)
-                highlights[i].auto = false;
-        }
-            
-        function unhighlight(s, point) {
-            if (s == null && point == null) {
-                highlights = [];
-                triggerRedrawOverlay();
-            }
-            
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number")
-                point = s.data[point];
-
-            var i = indexOfHighlight(s, point);
-            if (i != -1) {
-                highlights.splice(i, 1);
-
-                triggerRedrawOverlay();
-            }
-        }
-        
-        function indexOfHighlight(s, p) {
-            for (var i = 0; i < highlights.length; ++i) {
-                var h = highlights[i];
-                if (h.series == s && h.point[0] == p[0]
-                    && h.point[1] == p[1])
-                    return i;
-            }
-            return -1;
-        }
-        
-        function drawPointHighlight(series, point) {
-            var x = point[0], y = point[1],
-                axisx = series.xaxis, axisy = series.yaxis;
-            
-            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                return;
-            
-            var pointRadius = series.points.radius + series.points.lineWidth / 2;
-            octx.lineWidth = pointRadius;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var radius = 1.5 * pointRadius,
-                x = axisx.p2c(x),
-                y = axisy.p2c(y);
-            
-            octx.beginPath();
-            if (series.points.symbol == "circle")
-                octx.arc(x, y, radius, 0, 2 * Math.PI, false);
-            else
-                series.points.symbol(octx, x, y, radius, false);
-            octx.closePath();
-            octx.stroke();
-        }
-
-        function drawBarHighlight(series, point) {
-            octx.lineWidth = series.bars.lineWidth;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
-                    0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
-        }
-
-        function getColorOrGradient(spec, bottom, top, defaultColor) {
-            if (typeof spec == "string")
-                return spec;
-            else {
-                // assume this is a gradient spec; IE currently only
-                // supports a simple vertical gradient properly, so that's
-                // what we support too
-                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
-                
-                for (var i = 0, l = spec.colors.length; i < l; ++i) {
-                    var c = spec.colors[i];
-                    if (typeof c != "string") {
-                        var co = $.color.parse(defaultColor);
-                        if (c.brightness != null)
-                            co = co.scale('rgb', c.brightness)
-                        if (c.opacity != null)
-                            co.a *= c.opacity;
-                        c = co.toString();
-                    }
-                    gradient.addColorStop(i / (l - 1), c);
-                }
-                
-                return gradient;
-            }
-        }
-    }
-
-    $.plot = function(placeholder, data, options) {
-        //var t0 = new Date();
-        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
-        //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
-        return plot;
+      series = [];
+      options = null;
+      surface = null;
+      overlay = null;
+      eventHolder = null;
+      ctx = null;
+      octx = null;
+      xaxes = [];
+      yaxes = [];
+      hooks = null;
+      highlights = [];
+      plot = null;
+    };
+    plot.resize = function () {
+      var width = placeholder.width(),
+          height = placeholder.height();
+      surface.resize(width, height);
+      overlay.resize(width, height);
     };
 
-    $.plot.version = "0.7";
-    
-    $.plot.plugins = [];
+    // public attributes
+    plot.hooks = hooks;
 
-    // returns a string with the date d formatted according to fmt
-    $.plot.formatDate = function(d, fmt, monthNames) {
-        var leftPad = function(n) {
-            n = "" + n;
-            return n.length == 1 ? "0" + n : n;
-        };
-        
-        var r = [];
-        var escape = false, padNext = false;
-        var hours = d.getUTCHours();
-        var isAM = hours < 12;
-        if (monthNames == null)
-            monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+    // initialize
+    initPlugins(plot);
+    parseOptions(options_);
+    setupCanvases();
+    setData(data_);
+    setupGrid();
+    draw();
+    bindEvents();
 
-        if (fmt.search(/%p|%P/) != -1) {
-            if (hours > 12) {
-                hours = hours - 12;
-            } else if (hours == 0) {
-                hours = 12;
-            }
-        }
-        for (var i = 0; i < fmt.length; ++i) {
-            var c = fmt.charAt(i);
-            
-            if (escape) {
-                switch (c) {
-                case 'h': c = "" + hours; break;
-                case 'H': c = leftPad(hours); break;
-                case 'M': c = leftPad(d.getUTCMinutes()); break;
-                case 'S': c = leftPad(d.getUTCSeconds()); break;
-                case 'd': c = "" + d.getUTCDate(); break;
-                case 'm': c = "" + (d.getUTCMonth() + 1); break;
-                case 'y': c = "" + d.getUTCFullYear(); break;
-                case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
-                case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
-                case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
-                case '0': c = ""; padNext = true; break;
-                }
-                if (c && padNext) {
-                    c = leftPad(c);
-                    padNext = false;
-                }
-                r.push(c);
-                if (!padNext)
-                    escape = false;
-            }
-            else {
-                if (c == "%")
-                    escape = true;
-                else
-                    r.push(c);
-            }
-        }
-        return r.join("");
-    };
-    
-    // round to nearby lower multiple of base
-    function floorInBase(n, base) {
-        return base * Math.floor(n / base);
+
+    function executeHooks(hook, args) {
+      args = [plot].concat(args);
+      for (var i = 0; i < hook.length; ++i)
+        hook[i].apply(this, args);
     }
-    
+
+    function initPlugins() {
+
+      // References to key classes, allowing plugins to modify them
+
+      var classes = {
+        Canvas: Canvas
+      };
+
+      for (var i = 0; i < plugins.length; ++i) {
+        var p = plugins[i];
+        p.init(plot, classes);
+        if (p.options)
+          $.extend(true, options, p.options);
+      }
+    }
+
+    function parseOptions(opts) {
+
+      $.extend(true, options, opts);
+
+      // $.extend merges arrays, rather than replacing them.  When less
+      // colors are provided than the size of the default palette, we
+      // end up with those colors plus the remaining defaults, which is
+      // not expected behavior; avoid it by replacing them here.
+
+      if (opts && opts.colors) {
+        options.colors = opts.colors;
+      }
+
+      if (options.xaxis.color == null)
+        options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+      if (options.yaxis.color == null)
+        options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+
+      if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
+        options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
+      if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
+        options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
+
+      if (options.grid.borderColor == null)
+        options.grid.borderColor = options.grid.color;
+      if (options.grid.tickColor == null)
+        options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
+
+      // Fill in defaults for axis options, including any unspecified
+      // font-spec fields, if a font-spec was provided.
+
+      // If no x/y axis options were provided, create one of each anyway,
+      // since the rest of the code assumes that they exist.
+
+      var i, axisOptions, axisCount,
+          fontSize = placeholder.css("font-size"),
+          fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
+          fontDefaults = {
+            style: placeholder.css("font-style"),
+            size: Math.round(0.8 * fontSizeDefault),
+            variant: placeholder.css("font-variant"),
+            weight: placeholder.css("font-weight"),
+            family: placeholder.css("font-family")
+          };
+
+      axisCount = options.xaxes.length || 1;
+      for (i = 0; i < axisCount; ++i) {
+
+        axisOptions = options.xaxes[i];
+        if (axisOptions && !axisOptions.tickColor) {
+          axisOptions.tickColor = axisOptions.color;
+        }
+
+        axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
+        options.xaxes[i] = axisOptions;
+
+        if (axisOptions.font) {
+          axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
+          if (!axisOptions.font.color) {
+            axisOptions.font.color = axisOptions.color;
+          }
+          if (!axisOptions.font.lineHeight) {
+            axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
+          }
+        }
+      }
+
+      axisCount = options.yaxes.length || 1;
+      for (i = 0; i < axisCount; ++i) {
+
+        axisOptions = options.yaxes[i];
+        if (axisOptions && !axisOptions.tickColor) {
+          axisOptions.tickColor = axisOptions.color;
+        }
+
+        axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
+        options.yaxes[i] = axisOptions;
+
+        if (axisOptions.font) {
+          axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
+          if (!axisOptions.font.color) {
+            axisOptions.font.color = axisOptions.color;
+          }
+          if (!axisOptions.font.lineHeight) {
+            axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
+          }
+        }
+      }
+
+      // backwards compatibility, to be removed in future
+      if (options.xaxis.noTicks && options.xaxis.ticks == null)
+        options.xaxis.ticks = options.xaxis.noTicks;
+      if (options.yaxis.noTicks && options.yaxis.ticks == null)
+        options.yaxis.ticks = options.yaxis.noTicks;
+      if (options.x2axis) {
+        options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
+        options.xaxes[1].position = "top";
+        // Override the inherit to allow the axis to auto-scale
+        if (options.x2axis.min == null) {
+          options.xaxes[1].min = null;
+        }
+        if (options.x2axis.max == null) {
+          options.xaxes[1].max = null;
+        }
+      }
+      if (options.y2axis) {
+        options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
+        options.yaxes[1].position = "right";
+        // Override the inherit to allow the axis to auto-scale
+        if (options.y2axis.min == null) {
+          options.yaxes[1].min = null;
+        }
+        if (options.y2axis.max == null) {
+          options.yaxes[1].max = null;
+        }
+      }
+      if (options.grid.coloredAreas)
+        options.grid.markings = options.grid.coloredAreas;
+      if (options.grid.coloredAreasColor)
+        options.grid.markingsColor = options.grid.coloredAreasColor;
+      if (options.lines)
+        $.extend(true, options.series.lines, options.lines);
+      if (options.points)
+        $.extend(true, options.series.points, options.points);
+      if (options.bars)
+        $.extend(true, options.series.bars, options.bars);
+      if (options.shadowSize != null)
+        options.series.shadowSize = options.shadowSize;
+      if (options.highlightColor != null)
+        options.series.highlightColor = options.highlightColor;
+
+      // save options on axes for future reference
+      for (i = 0; i < options.xaxes.length; ++i)
+        getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
+      for (i = 0; i < options.yaxes.length; ++i)
+        getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
+
+      // add hooks from options
+      for (var n in hooks)
+        if (options.hooks[n] && options.hooks[n].length)
+          hooks[n] = hooks[n].concat(options.hooks[n]);
+
+      executeHooks(hooks.processOptions, [options]);
+    }
+
+    function setData(d) {
+      series = parseData(d);
+      fillInSeriesOptions();
+      processData();
+    }
+
+    function parseData(d) {
+      var res = [];
+      for (var i = 0; i < d.length; ++i) {
+        var s = $.extend(true, {}, options.series);
+
+        if (d[i].data != null) {
+          s.data = d[i].data; // move the data instead of deep-copy
+          delete d[i].data;
+
+          $.extend(true, s, d[i]);
+
+          d[i].data = s.data;
+        }
+        else
+          s.data = d[i];
+        res.push(s);
+      }
+
+      return res;
+    }
+
+    function axisNumber(obj, coord) {
+      var a = obj[coord + "axis"];
+      if (typeof a == "object") // if we got a real axis, extract number
+        a = a.n;
+      if (typeof a != "number")
+        a = 1; // default to first axis
+      return a;
+    }
+
+    function allAxes() {
+      // return flat array without annoying null entries
+      return $.grep(xaxes.concat(yaxes), function (a) { return a; });
+    }
+
+    function canvasToAxisCoords(pos) {
+      // return an object with x/y corresponding to all used axes
+      var res = {}, i, axis;
+      for (i = 0; i < xaxes.length; ++i) {
+        axis = xaxes[i];
+        if (axis && axis.used)
+          res["x" + axis.n] = axis.c2p(pos.left);
+      }
+
+      for (i = 0; i < yaxes.length; ++i) {
+        axis = yaxes[i];
+        if (axis && axis.used)
+          res["y" + axis.n] = axis.c2p(pos.top);
+      }
+
+      if (res.x1 !== undefined)
+        res.x = res.x1;
+      if (res.y1 !== undefined)
+        res.y = res.y1;
+
+      return res;
+    }
+
+    function axisToCanvasCoords(pos) {
+      // get canvas coords from the first pair of x/y found in pos
+      var res = {}, i, axis, key;
+
+      for (i = 0; i < xaxes.length; ++i) {
+        axis = xaxes[i];
+        if (axis && axis.used) {
+          key = "x" + axis.n;
+          if (pos[key] == null && axis.n == 1)
+            key = "x";
+
+          if (pos[key] != null) {
+            res.left = axis.p2c(pos[key]);
+            break;
+          }
+        }
+      }
+
+      for (i = 0; i < yaxes.length; ++i) {
+        axis = yaxes[i];
+        if (axis && axis.used) {
+          key = "y" + axis.n;
+          if (pos[key] == null && axis.n == 1)
+            key = "y";
+
+          if (pos[key] != null) {
+            res.top = axis.p2c(pos[key]);
+            break;
+          }
+        }
+      }
+
+      return res;
+    }
+
+    function getOrCreateAxis(axes, number) {
+      if (!axes[number - 1])
+        axes[number - 1] = {
+          n: number, // save the number for future reference
+          direction: axes == xaxes ? "x" : "y",
+          options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
+        };
+
+      return axes[number - 1];
+    }
+
+    function fillInSeriesOptions() {
+
+      var neededColors = series.length, maxIndex = -1, i;
+
+      // Subtract the number of series that already have fixed colors or
+      // color indexes from the number that we still need to generate.
+
+      for (i = 0; i < series.length; ++i) {
+        var sc = series[i].color;
+        if (sc != null) {
+          neededColors--;
+          if (typeof sc == "number" && sc > maxIndex) {
+            maxIndex = sc;
+          }
+        }
+      }
+
+      // If any of the series have fixed color indexes, then we need to
+      // generate at least as many colors as the highest index.
+
+      if (neededColors <= maxIndex) {
+        neededColors = maxIndex + 1;
+      }
+
+      // Generate all the colors, using first the option colors and then
+      // variations on those colors once they're exhausted.
+
+      var c, colors = [], colorPool = options.colors,
+          colorPoolSize = colorPool.length, variation = 0;
+
+      for (i = 0; i < neededColors; i++) {
+
+        c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
+
+        // Each time we exhaust the colors in the pool we adjust
+        // a scaling factor used to produce more variations on
+        // those colors. The factor alternates negative/positive
+        // to produce lighter/darker colors.
+
+        // Reset the variation after every few cycles, or else
+        // it will end up producing only white or black colors.
+
+        if (i % colorPoolSize == 0 && i) {
+          if (variation >= 0) {
+            if (variation < 0.5) {
+              variation = -variation - 0.2;
+            } else variation = 0;
+          } else variation = -variation;
+        }
+
+        colors[i] = c.scale('rgb', 1 + variation);
+      }
+
+      // Finalize the series options, filling in their colors
+
+      var colori = 0, s;
+      for (i = 0; i < series.length; ++i) {
+        s = series[i];
+
+        // assign colors
+        if (s.color == null) {
+          s.color = colors[colori].toString();
+          ++colori;
+        }
+        else if (typeof s.color == "number")
+          s.color = colors[s.color].toString();
+
+        // turn on lines automatically in case nothing is set
+        if (s.lines.show == null) {
+          var v, show = true;
+          for (v in s)
+            if (s[v] && s[v].show) {
+              show = false;
+              break;
+            }
+          if (show)
+            s.lines.show = true;
+        }
+
+        // If nothing was provided for lines.zero, default it to match
+        // lines.fill, since areas by default should extend to zero.
+
+        if (s.lines.zero == null) {
+          s.lines.zero = !!s.lines.fill;
+        }
+
+        // setup axes
+        s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
+        s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
+      }
+    }
+
+    function processData() {
+      var topSentry = Number.POSITIVE_INFINITY,
+          bottomSentry = Number.NEGATIVE_INFINITY,
+          fakeInfinity = Number.MAX_VALUE,
+          i, j, k, m, length,
+          s, points, ps, x, y, axis, val, f, p,
+          data, format;
+
+      function updateAxis(axis, min, max) {
+        if (min < axis.datamin && min != -fakeInfinity)
+          axis.datamin = min;
+        if (max > axis.datamax && max != fakeInfinity)
+          axis.datamax = max;
+      }
+
+      $.each(allAxes(), function (_, axis) {
+        // init axis
+        axis.datamin = topSentry;
+        axis.datamax = bottomSentry;
+        axis.used = false;
+      });
+
+      for (i = 0; i < series.length; ++i) {
+        s = series[i];
+        s.datapoints = { points: [] };
+
+        executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
+      }
+
+      // first pass: clean and copy data
+      for (i = 0; i < series.length; ++i) {
+        s = series[i];
+
+        data = s.data;
+        format = s.datapoints.format;
+
+        if (!format) {
+          format = [];
+          // find out how to copy
+          format.push({ x: true, number: true, required: true });
+          format.push({ y: true, number: true, required: true });
+
+          if (s.bars.show || (s.lines.show && s.lines.fill)) {
+            var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
+            format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
+            if (s.bars.horizontal) {
+              delete format[format.length - 1].y;
+              format[format.length - 1].x = true;
+            }
+          }
+
+          s.datapoints.format = format;
+        }
+
+        if (s.datapoints.pointsize != null)
+          continue; // already filled in
+
+        s.datapoints.pointsize = format.length;
+
+        ps = s.datapoints.pointsize;
+        points = s.datapoints.points;
+
+        var insertSteps = s.lines.show && s.lines.steps;
+        s.xaxis.used = s.yaxis.used = true;
+
+        for (j = k = 0; j < data.length; ++j, k += ps) {
+          p = data[j];
+
+          var nullify = p == null;
+          if (!nullify) {
+            for (m = 0; m < ps; ++m) {
+              val = p[m];
+              f = format[m];
+
+              if (f) {
+                if (f.number && val != null) {
+                  val = +val; // convert to number
+                  if (isNaN(val))
+                    val = null;
+                  else if (val == Infinity)
+                    val = fakeInfinity;
+                  else if (val == -Infinity)
+                    val = -fakeInfinity;
+                }
+
+                if (val == null) {
+                  if (f.required)
+                    nullify = true;
+
+                  if (f.defaultValue != null)
+                    val = f.defaultValue;
+                }
+              }
+
+              points[k + m] = val;
+            }
+          }
+
+          if (nullify) {
+            for (m = 0; m < ps; ++m) {
+              val = points[k + m];
+              if (val != null) {
+                f = format[m];
+                // extract min/max info
+                if (f.autoscale !== false) {
+                  if (f.x) {
+                    updateAxis(s.xaxis, val, val);
+                  }
+                  if (f.y) {
+                    updateAxis(s.yaxis, val, val);
+                  }
+                }
+              }
+              points[k + m] = null;
+            }
+          }
+          else {
+            // a little bit of line specific stuff that
+            // perhaps shouldn't be here, but lacking
+            // better means...
+            if (insertSteps && k > 0
+                && points[k - ps] != null
+                && points[k - ps] != points[k]
+                && points[k - ps + 1] != points[k + 1]) {
+              // copy the point to make room for a middle point
+              for (m = 0; m < ps; ++m)
+                points[k + ps + m] = points[k + m];
+
+              // middle point has same y
+              points[k + 1] = points[k - ps + 1];
+
+              // we've added a point, better reflect that
+              k += ps;
+            }
+          }
+        }
+      }
+
+      // give the hooks a chance to run
+      for (i = 0; i < series.length; ++i) {
+        s = series[i];
+
+        executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
+      }
+
+      // second pass: find datamax/datamin for auto-scaling
+      for (i = 0; i < series.length; ++i) {
+        s = series[i];
+        points = s.datapoints.points;
+        ps = s.datapoints.pointsize;
+        format = s.datapoints.format;
+
+        var xmin = topSentry, ymin = topSentry,
+            xmax = bottomSentry, ymax = bottomSentry;
+
+        for (j = 0; j < points.length; j += ps) {
+          if (points[j] == null)
+            continue;
+
+          for (m = 0; m < ps; ++m) {
+            val = points[j + m];
+            f = format[m];
+            if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
+              continue;
+
+            if (f.x) {
+              if (val < xmin)
+                xmin = val;
+              if (val > xmax)
+                xmax = val;
+            }
+            if (f.y) {
+              if (val < ymin)
+                ymin = val;
+              if (val > ymax)
+                ymax = val;
+            }
+          }
+        }
+
+        if (s.bars.show) {
+          // make sure we got room for the bar on the dancing floor
+          var delta;
+
+          switch (s.bars.align) {
+            case "left":
+              delta = 0;
+              break;
+            case "right":
+              delta = -s.bars.barWidth;
+              break;
+            default:
+              delta = -s.bars.barWidth / 2;
+          }
+
+          if (s.bars.horizontal) {
+            ymin += delta;
+            ymax += delta + s.bars.barWidth;
+          }
+          else {
+            xmin += delta;
+            xmax += delta + s.bars.barWidth;
+          }
+        }
+
+        updateAxis(s.xaxis, xmin, xmax);
+        updateAxis(s.yaxis, ymin, ymax);
+      }
+
+      $.each(allAxes(), function (_, axis) {
+        if (axis.datamin == topSentry)
+          axis.datamin = null;
+        if (axis.datamax == bottomSentry)
+          axis.datamax = null;
+      });
+    }
+
+    function setupCanvases() {
+
+      // Make sure the placeholder is clear of everything except canvases
+      // from a previous plot in this container that we'll try to re-use.
+
+      placeholder.css("padding", 0) // padding messes up the positioning
+          .children().filter(function(){
+        return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
+      }).remove();
+
+      if (placeholder.css("position") == 'static')
+        placeholder.css("position", "relative"); // for positioning labels and overlay
+
+      surface = new Canvas("flot-base", placeholder);
+      overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
+
+      ctx = surface.context;
+      octx = overlay.context;
+
+      // define which element we're listening for events on
+      eventHolder = $(overlay.element).unbind();
+
+      // If we're re-using a plot object, shut down the old one
+
+      var existing = placeholder.data("plot");
+
+      if (existing) {
+        existing.shutdown();
+        overlay.clear();
+      }
+
+      // save in case we get replotted
+      placeholder.data("plot", plot);
+    }
+
+    function bindEvents() {
+      // bind events
+      if (options.grid.hoverable) {
+        eventHolder.mousemove(onMouseMove);
+
+        // Use bind, rather than .mouseleave, because we officially
+        // still support jQuery 1.2.6, which doesn't define a shortcut
+        // for mouseenter or mouseleave.  This was a bug/oversight that
+        // was fixed somewhere around 1.3.x.  We can return to using
+        // .mouseleave when we drop support for 1.2.6.
+
+        eventHolder.bind("mouseleave", onMouseLeave);
+      }
+
+      if (options.grid.clickable)
+        eventHolder.click(onClick);
+
+      executeHooks(hooks.bindEvents, [eventHolder]);
+    }
+
+    function shutdown() {
+      if (redrawTimeout)
+        clearTimeout(redrawTimeout);
+
+      eventHolder.unbind("mousemove", onMouseMove);
+      eventHolder.unbind("mouseleave", onMouseLeave);
+      eventHolder.unbind("click", onClick);
+
+      executeHooks(hooks.shutdown, [eventHolder]);
+    }
+
+    function setTransformationHelpers(axis) {
+      // set helper functions on the axis, assumes plot area
+      // has been computed already
+
+      function identity(x) { return x; }
+
+      var s, m, t = axis.options.transform || identity,
+          it = axis.options.inverseTransform;
+
+      // precompute how much the axis is scaling a point
+      // in canvas space
+      if (axis.direction == "x") {
+        s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
+        m = Math.min(t(axis.max), t(axis.min));
+      }
+      else {
+        s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
+        s = -s;
+        m = Math.max(t(axis.max), t(axis.min));
+      }
+
+      // data point to canvas coordinate
+      if (t == identity) // slight optimization
+        axis.p2c = function (p) { return (p - m) * s; };
+      else
+        axis.p2c = function (p) { return (t(p) - m) * s; };
+      // canvas coordinate to data point
+      if (!it)
+        axis.c2p = function (c) { return m + c / s; };
+      else
+        axis.c2p = function (c) { return it(m + c / s); };
+    }
+
+    function measureTickLabels(axis) {
+
+      var opts = axis.options,
+          ticks = axis.ticks || [],
+          labelWidth = opts.labelWidth || 0,
+          labelHeight = opts.labelHeight || 0,
+          maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
+          legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
+          layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
+          font = opts.font || "flot-tick-label tickLabel";
+
+      for (var i = 0; i < ticks.length; ++i) {
+
+        var t = ticks[i];
+
+        if (!t.label)
+          continue;
+
+        var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
+
+        labelWidth = Math.max(labelWidth, info.width);
+        labelHeight = Math.max(labelHeight, info.height);
+      }
+
+      axis.labelWidth = opts.labelWidth || labelWidth;
+      axis.labelHeight = opts.labelHeight || labelHeight;
+    }
+
+    function allocateAxisBoxFirstPhase(axis) {
+      // find the bounding box of the axis by looking at label
+      // widths/heights and ticks, make room by diminishing the
+      // plotOffset; this first phase only looks at one
+      // dimension per axis, the other dimension depends on the
+      // other axes so will have to wait
+
+      var lw = axis.labelWidth,
+          lh = axis.labelHeight,
+          pos = axis.options.position,
+          isXAxis = axis.direction === "x",
+          tickLength = axis.options.tickLength,
+          axisMargin = options.grid.axisMargin,
+          padding = options.grid.labelMargin,
+          innermost = true,
+          outermost = true,
+          first = true,
+          found = false;
+
+      // Determine the axis's position in its direction and on its side
+
+      $.each(isXAxis ? xaxes : yaxes, function(i, a) {
+        if (a && (a.show || a.reserveSpace)) {
+          if (a === axis) {
+            found = true;
+          } else if (a.options.position === pos) {
+            if (found) {
+              outermost = false;
+            } else {
+              innermost = false;
+            }
+          }
+          if (!found) {
+            first = false;
+          }
+        }
+      });
+
+      // The outermost axis on each side has no margin
+
+      if (outermost) {
+        axisMargin = 0;
+      }
+
+      // The ticks for the first axis in each direction stretch across
+
+      if (tickLength == null) {
+        tickLength = first ? "full" : 5;
+      }
+
+      if (!isNaN(+tickLength))
+        padding += +tickLength;
+
+      if (isXAxis) {
+        lh += padding;
+
+        if (pos == "bottom") {
+          plotOffset.bottom += lh + axisMargin;
+          axis.box = { top: surface.height - plotOffset.bottom, height: lh };
+        }
+        else {
+          axis.box = { top: plotOffset.top + axisMargin, height: lh };
+          plotOffset.top += lh + axisMargin;
+        }
+      }
+      else {
+        lw += padding;
+
+        if (pos == "left") {
+          axis.box = { left: plotOffset.left + axisMargin, width: lw };
+          plotOffset.left += lw + axisMargin;
+        }
+        else {
+          plotOffset.right += lw + axisMargin;
+          axis.box = { left: surface.width - plotOffset.right, width: lw };
+        }
+      }
+
+      // save for future reference
+      axis.position = pos;
+      axis.tickLength = tickLength;
+      axis.box.padding = padding;
+      axis.innermost = innermost;
+    }
+
+    function allocateAxisBoxSecondPhase(axis) {
+      // now that all axis boxes have been placed in one
+      // dimension, we can set the remaining dimension coordinates
+      if (axis.direction == "x") {
+        axis.box.left = plotOffset.left - axis.labelWidth / 2;
+        axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
+      }
+      else {
+        axis.box.top = plotOffset.top - axis.labelHeight / 2;
+        axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
+      }
+    }
+
+    function adjustLayoutForThingsStickingOut() {
+      // possibly adjust plot offset to ensure everything stays
+      // inside the canvas and isn't clipped off
+
+      var minMargin = options.grid.minBorderMargin,
+          axis, i;
+
+      // check stuff from the plot (FIXME: this should just read
+      // a value from the series, otherwise it's impossible to
+      // customize)
+      if (minMargin == null) {
+        minMargin = 0;
+        for (i = 0; i < series.length; ++i)
+          minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
+      }
+
+      var margins = {
+        left: minMargin,
+        right: minMargin,
+        top: minMargin,
+        bottom: minMargin
+      };
+
+      // check axis labels, note we don't check the actual
+      // labels but instead use the overall width/height to not
+      // jump as much around with replots
+      $.each(allAxes(), function (_, axis) {
+        if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
+          if (axis.direction === "x") {
+            margins.left = Math.max(margins.left, axis.labelWidth / 2);
+            margins.right = Math.max(margins.right, axis.labelWidth / 2);
+          } else {
+            margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
+            margins.top = Math.max(margins.top, axis.labelHeight / 2);
+          }
+        }
+      });
+
+      plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
+      plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
+      plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
+      plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
+    }
+
+    function setupGrid() {
+      var i, axes = allAxes(), showGrid = options.grid.show;
+
+      // Initialize the plot's offset from the edge of the canvas
+
+      for (var a in plotOffset) {
+        var margin = options.grid.margin || 0;
+        plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
+      }
+
+      executeHooks(hooks.processOffset, [plotOffset]);
+
+      // If the grid is visible, add its border width to the offset
+
+      for (var a in plotOffset) {
+        if(typeof(options.grid.borderWidth) == "object") {
+          plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
+        }
+        else {
+          plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
+        }
+      }
+
+      $.each(axes, function (_, axis) {
+        var axisOpts = axis.options;
+        axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
+        axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
+        setRange(axis);
+      });
+
+      if (showGrid) {
+
+        var allocatedAxes = $.grep(axes, function (axis) {
+          return axis.show || axis.reserveSpace;
+        });
+
+        $.each(allocatedAxes, function (_, axis) {
+          // make the ticks
+          setupTickGeneration(axis);
+          setTicks(axis);
+          snapRangeToTicks(axis, axis.ticks);
+          // find labelWidth/Height for axis
+          measureTickLabels(axis);
+        });
+
+        // with all dimensions calculated, we can compute the
+        // axis bounding boxes, start from the outside
+        // (reverse order)
+        for (i = allocatedAxes.length - 1; i >= 0; --i)
+          allocateAxisBoxFirstPhase(allocatedAxes[i]);
+
+        // make sure we've got enough space for things that
+        // might stick out
+        adjustLayoutForThingsStickingOut();
+
+        $.each(allocatedAxes, function (_, axis) {
+          allocateAxisBoxSecondPhase(axis);
+        });
+      }
+
+      plotWidth = surface.width - plotOffset.left - plotOffset.right;
+      plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
+
+      // now we got the proper plot dimensions, we can compute the scaling
+      $.each(axes, function (_, axis) {
+        setTransformationHelpers(axis);
+      });
+
+      if (showGrid) {
+        drawAxisLabels();
+      }
+
+      insertLegend();
+    }
+
+    function setRange(axis) {
+      var opts = axis.options,
+          min = +(opts.min != null ? opts.min : axis.datamin),
+          max = +(opts.max != null ? opts.max : axis.datamax),
+          delta = max - min;
+
+      if (delta == 0.0) {
+        // degenerate case
+        var widen = max == 0 ? 1 : 0.01;
+
+        if (opts.min == null)
+          min -= widen;
+        // always widen max if we couldn't widen min to ensure we
+        // don't fall into min == max which doesn't work
+        if (opts.max == null || opts.min != null)
+          max += widen;
+      }
+      else {
+        // consider autoscaling
+        var margin = opts.autoscaleMargin;
+        if (margin != null) {
+          if (opts.min == null) {
+            min -= delta * margin;
+            // make sure we don't go below zero if all values
+            // are positive
+            if (min < 0 && axis.datamin != null && axis.datamin >= 0)
+              min = 0;
+          }
+          if (opts.max == null) {
+            max += delta * margin;
+            if (max > 0 && axis.datamax != null && axis.datamax <= 0)
+              max = 0;
+          }
+        }
+      }
+      axis.min = min;
+      axis.max = max;
+    }
+
+    function setupTickGeneration(axis) {
+      var opts = axis.options;
+
+      // estimate number of ticks
+      var noTicks;
+      if (typeof opts.ticks == "number" && opts.ticks > 0)
+        noTicks = opts.ticks;
+      else
+      // heuristic based on the model a*sqrt(x) fitted to
+      // some data points that seemed reasonable
+        noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
+
+      var delta = (axis.max - axis.min) / noTicks,
+          dec = -Math.floor(Math.log(delta) / Math.LN10),
+          maxDec = opts.tickDecimals;
+
+      if (maxDec != null && dec > maxDec) {
+        dec = maxDec;
+      }
+
+      var magn = Math.pow(10, -dec),
+          norm = delta / magn, // norm is between 1.0 and 10.0
+          size;
+
+      if (norm < 1.5) {
+        size = 1;
+      } else if (norm < 3) {
+        size = 2;
+        // special case for 2.5, requires an extra decimal
+        if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+          size = 2.5;
+          ++dec;
+        }
+      } else if (norm < 7.5) {
+        size = 5;
+      } else {
+        size = 10;
+      }
+
+      size *= magn;
+
+      if (opts.minTickSize != null && size < opts.minTickSize) {
+        size = opts.minTickSize;
+      }
+
+      axis.delta = delta;
+      axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
+      axis.tickSize = opts.tickSize || size;
+
+      // Time mode was moved to a plug-in in 0.8, and since so many people use it
+      // we'll add an especially friendly reminder to make sure they included it.
+
+      if (opts.mode == "time" && !axis.tickGenerator) {
+        throw new Error("Time mode requires the flot.time plugin.");
+      }
+
+      // Flot supports base-10 axes; any other mode else is handled by a plug-in,
+      // like flot.time.js.
+
+      if (!axis.tickGenerator) {
+
+        axis.tickGenerator = function (axis) {
+
+          var ticks = [],
+              start = floorInBase(axis.min, axis.tickSize),
+              i = 0,
+              v = Number.NaN,
+              prev;
+
+          do {
+            prev = v;
+            v = start + i * axis.tickSize;
+            ticks.push(v);
+            ++i;
+          } while (v < axis.max && v != prev);
+          return ticks;
+        };
+
+        axis.tickFormatter = function (value, axis) {
+
+          var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
+          var formatted = "" + Math.round(value * factor) / factor;
+
+          // If tickDecimals was specified, ensure that we have exactly that
+          // much precision; otherwise default to the value's own precision.
+
+          if (axis.tickDecimals != null) {
+            var decimal = formatted.indexOf(".");
+            var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
+            if (precision < axis.tickDecimals) {
+              return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
+            }
+          }
+
+          return formatted;
+        };
+      }
+
+      if ($.isFunction(opts.tickFormatter))
+        axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
+
+      if (opts.alignTicksWithAxis != null) {
+        var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
+        if (otherAxis && otherAxis.used && otherAxis != axis) {
+          // consider snapping min/max to outermost nice ticks
+          var niceTicks = axis.tickGenerator(axis);
+          if (niceTicks.length > 0) {
+            if (opts.min == null)
+              axis.min = Math.min(axis.min, niceTicks[0]);
+            if (opts.max == null && niceTicks.length > 1)
+              axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
+          }
+
+          axis.tickGenerator = function (axis) {
+            // copy ticks, scaled to this axis
+            var ticks = [], v, i;
+            for (i = 0; i < otherAxis.ticks.length; ++i) {
+              v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
+              v = axis.min + v * (axis.max - axis.min);
+              ticks.push(v);
+            }
+            return ticks;
+          };
+
+          // we might need an extra decimal since forced
+          // ticks don't necessarily fit naturally
+          if (!axis.mode && opts.tickDecimals == null) {
+            var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
+                ts = axis.tickGenerator(axis);
+
+            // only proceed if the tick interval rounded
+            // with an extra decimal doesn't give us a
+            // zero at end
+            if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
+              axis.tickDecimals = extraDec;
+          }
+        }
+      }
+    }
+
+    function setTicks(axis) {
+      var oticks = axis.options.ticks, ticks = [];
+      if (oticks == null || (typeof oticks == "number" && oticks > 0))
+        ticks = axis.tickGenerator(axis);
+      else if (oticks) {
+        if ($.isFunction(oticks))
+        // generate the ticks
+          ticks = oticks(axis);
+        else
+          ticks = oticks;
+      }
+
+      // clean up/labelify the supplied ticks, copy them over
+      var i, v;
+      axis.ticks = [];
+      for (i = 0; i < ticks.length; ++i) {
+        var label = null;
+        var t = ticks[i];
+        if (typeof t == "object") {
+          v = +t[0];
+          if (t.length > 1)
+            label = t[1];
+        }
+        else
+          v = +t;
+        if (label == null)
+          label = axis.tickFormatter(v, axis);
+        if (!isNaN(v))
+          axis.ticks.push({ v: v, label: label });
+      }
+    }
+
+    function snapRangeToTicks(axis, ticks) {
+      if (axis.options.autoscaleMargin && ticks.length > 0) {
+        // snap to ticks
+        if (axis.options.min == null)
+          axis.min = Math.min(axis.min, ticks[0].v);
+        if (axis.options.max == null && ticks.length > 1)
+          axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
+      }
+    }
+
+    function draw() {
+
+      surface.clear();
+
+      executeHooks(hooks.drawBackground, [ctx]);
+
+      var grid = options.grid;
+
+      // draw background, if any
+      if (grid.show && grid.backgroundColor)
+        drawBackground();
+
+      if (grid.show && !grid.aboveData) {
+        drawGrid();
+      }
+
+      for (var i = 0; i < series.length; ++i) {
+        executeHooks(hooks.drawSeries, [ctx, series[i]]);
+        drawSeries(series[i]);
+      }
+
+      executeHooks(hooks.draw, [ctx]);
+
+      if (grid.show && grid.aboveData) {
+        drawGrid();
+      }
+
+      surface.render();
+
+      // A draw implies that either the axes or data have changed, so we
+      // should probably update the overlay highlights as well.
+
+      triggerRedrawOverlay();
+    }
+
+    function extractRange(ranges, coord) {
+      var axis, from, to, key, axes = allAxes();
+
+      for (var i = 0; i < axes.length; ++i) {
+        axis = axes[i];
+        if (axis.direction == coord) {
+          key = coord + axis.n + "axis";
+          if (!ranges[key] && axis.n == 1)
+            key = coord + "axis"; // support x1axis as xaxis
+          if (ranges[key]) {
+            from = ranges[key].from;
+            to = ranges[key].to;
+            break;
+          }
+        }
+      }
+
+      // backwards-compat stuff - to be removed in future
+      if (!ranges[key]) {
+        axis = coord == "x" ? xaxes[0] : yaxes[0];
+        from = ranges[coord + "1"];
+        to = ranges[coord + "2"];
+      }
+
+      // auto-reverse as an added bonus
+      if (from != null && to != null && from > to) {
+        var tmp = from;
+        from = to;
+        to = tmp;
+      }
+
+      return { from: from, to: to, axis: axis };
+    }
+
+    function drawBackground() {
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+
+      ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
+      ctx.fillRect(0, 0, plotWidth, plotHeight);
+      ctx.restore();
+    }
+
+    function drawGrid() {
+      var i, axes, bw, bc;
+
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+
+      // draw markings
+      var markings = options.grid.markings;
+      if (markings) {
+        if ($.isFunction(markings)) {
+          axes = plot.getAxes();
+          // xmin etc. is backwards compatibility, to be
+          // removed in the future
+          axes.xmin = axes.xaxis.min;
+          axes.xmax = axes.xaxis.max;
+          axes.ymin = axes.yaxis.min;
+          axes.ymax = axes.yaxis.max;
+
+          markings = markings(axes);
+        }
+
+        for (i = 0; i < markings.length; ++i) {
+          var m = markings[i],
+              xrange = extractRange(m, "x"),
+              yrange = extractRange(m, "y");
+
+          // fill in missing
+          if (xrange.from == null)
+            xrange.from = xrange.axis.min;
+          if (xrange.to == null)
+            xrange.to = xrange.axis.max;
+          if (yrange.from == null)
+            yrange.from = yrange.axis.min;
+          if (yrange.to == null)
+            yrange.to = yrange.axis.max;
+
+          // clip
+          if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
+              yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
+            continue;
+
+          xrange.from = Math.max(xrange.from, xrange.axis.min);
+          xrange.to = Math.min(xrange.to, xrange.axis.max);
+          yrange.from = Math.max(yrange.from, yrange.axis.min);
+          yrange.to = Math.min(yrange.to, yrange.axis.max);
+
+          var xequal = xrange.from === xrange.to,
+              yequal = yrange.from === yrange.to;
+
+          if (xequal && yequal) {
+            continue;
+          }
+
+          // then draw
+          xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
+          xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
+          yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
+          yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
+
+          if (xequal || yequal) {
+            var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
+                subPixel = lineWidth % 2 ? 0.5 : 0;
+            ctx.beginPath();
+            ctx.strokeStyle = m.color || options.grid.markingsColor;
+            ctx.lineWidth = lineWidth;
+            if (xequal) {
+              ctx.moveTo(xrange.to + subPixel, yrange.from);
+              ctx.lineTo(xrange.to + subPixel, yrange.to);
+            } else {
+              ctx.moveTo(xrange.from, yrange.to + subPixel);
+              ctx.lineTo(xrange.to, yrange.to + subPixel);
+            }
+            ctx.stroke();
+          } else {
+            ctx.fillStyle = m.color || options.grid.markingsColor;
+            ctx.fillRect(xrange.from, yrange.to,
+                xrange.to - xrange.from,
+                yrange.from - yrange.to);
+          }
+        }
+      }
+
+      // draw the ticks
+      axes = allAxes();
+      bw = options.grid.borderWidth;
+
+      for (var j = 0; j < axes.length; ++j) {
+        var axis = axes[j], box = axis.box,
+            t = axis.tickLength, x, y, xoff, yoff;
+        if (!axis.show || axis.ticks.length == 0)
+          continue;
+
+        ctx.lineWidth = 1;
+
+        // find the edges
+        if (axis.direction == "x") {
+          x = 0;
+          if (t == "full")
+            y = (axis.position == "top" ? 0 : plotHeight);
+          else
+            y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
+        }
+        else {
+          y = 0;
+          if (t == "full")
+            x = (axis.position == "left" ? 0 : plotWidth);
+          else
+            x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
+        }
+
+        // draw tick bar
+        if (!axis.innermost) {
+          ctx.strokeStyle = axis.options.color;
+          ctx.beginPath();
+          xoff = yoff = 0;
+          if (axis.direction == "x")
+            xoff = plotWidth + 1;
+          else
+            yoff = plotHeight + 1;
+
+          if (ctx.lineWidth == 1) {
+            if (axis.direction == "x") {
+              y = Math.floor(y) + 0.5;
+            } else {
+              x = Math.floor(x) + 0.5;
+            }
+          }
+
+          ctx.moveTo(x, y);
+          ctx.lineTo(x + xoff, y + yoff);
+          ctx.stroke();
+        }
+
+        // draw ticks
+
+        ctx.strokeStyle = axis.options.tickColor;
+
+        ctx.beginPath();
+        for (i = 0; i < axis.ticks.length; ++i) {
+          var v = axis.ticks[i].v;
+
+          xoff = yoff = 0;
+
+          if (isNaN(v) || v < axis.min || v > axis.max
+              // skip those lying on the axes if we got a border
+              || (t == "full"
+                  && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
+                  && (v == axis.min || v == axis.max)))
+            continue;
+
+          if (axis.direction == "x") {
+            x = axis.p2c(v);
+            yoff = t == "full" ? -plotHeight : t;
+
+            if (axis.position == "top")
+              yoff = -yoff;
+          }
+          else {
+            y = axis.p2c(v);
+            xoff = t == "full" ? -plotWidth : t;
+
+            if (axis.position == "left")
+              xoff = -xoff;
+          }
+
+          if (ctx.lineWidth == 1) {
+            if (axis.direction == "x")
+              x = Math.floor(x) + 0.5;
+            else
+              y = Math.floor(y) + 0.5;
+          }
+
+          ctx.moveTo(x, y);
+          ctx.lineTo(x + xoff, y + yoff);
+        }
+
+        ctx.stroke();
+      }
+
+
+      // draw border
+      if (bw) {
+        // If either borderWidth or borderColor is an object, then draw the border
+        // line by line instead of as one rectangle
+        bc = options.grid.borderColor;
+        if(typeof bw == "object" || typeof bc == "object") {
+          if (typeof bw !== "object") {
+            bw = {top: bw, right: bw, bottom: bw, left: bw};
+          }
+          if (typeof bc !== "object") {
+            bc = {top: bc, right: bc, bottom: bc, left: bc};
+          }
+
+          if (bw.top > 0) {
+            ctx.strokeStyle = bc.top;
+            ctx.lineWidth = bw.top;
+            ctx.beginPath();
+            ctx.moveTo(0 - bw.left, 0 - bw.top/2);
+            ctx.lineTo(plotWidth, 0 - bw.top/2);
+            ctx.stroke();
+          }
+
+          if (bw.right > 0) {
+            ctx.strokeStyle = bc.right;
+            ctx.lineWidth = bw.right;
+            ctx.beginPath();
+            ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
+            ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
+            ctx.stroke();
+          }
+
+          if (bw.bottom > 0) {
+            ctx.strokeStyle = bc.bottom;
+            ctx.lineWidth = bw.bottom;
+            ctx.beginPath();
+            ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
+            ctx.lineTo(0, plotHeight + bw.bottom / 2);
+            ctx.stroke();
+          }
+
+          if (bw.left > 0) {
+            ctx.strokeStyle = bc.left;
+            ctx.lineWidth = bw.left;
+            ctx.beginPath();
+            ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);
+            ctx.lineTo(0- bw.left/2, 0);
+            ctx.stroke();
+          }
+        }
+        else {
+          ctx.lineWidth = bw;
+          ctx.strokeStyle = options.grid.borderColor;
+          ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
+        }
+      }
+
+      ctx.restore();
+    }
+
+    function drawAxisLabels() {
+
+      $.each(allAxes(), function (_, axis) {
+        var box = axis.box,
+            legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
+            layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
+            font = axis.options.font || "flot-tick-label tickLabel",
+            tick, x, y, halign, valign;
+
+        // Remove text before checking for axis.show and ticks.length;
+        // otherwise plugins, like flot-tickrotor, that draw their own
+        // tick labels will end up with both theirs and the defaults.
+
+        surface.removeText(layer);
+
+        if (!axis.show || axis.ticks.length == 0)
+          return;
+
+        for (var i = 0; i < axis.ticks.length; ++i) {
+
+          tick = axis.ticks[i];
+          if (!tick.label || tick.v < axis.min || tick.v > axis.max)
+            continue;
+
+          if (axis.direction == "x") {
+            halign = "center";
+            x = plotOffset.left + axis.p2c(tick.v);
+            if (axis.position == "bottom") {
+              y = box.top + box.padding;
+            } else {
+              y = box.top + box.height - box.padding;
+              valign = "bottom";
+            }
+          } else {
+            valign = "middle";
+            y = plotOffset.top + axis.p2c(tick.v);
+            if (axis.position == "left") {
+              x = box.left + box.width - box.padding;
+              halign = "right";
+            } else {
+              x = box.left + box.padding;
+            }
+          }
+
+          surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
+        }
+      });
+    }
+
+    function drawSeries(series) {
+      if (series.lines.show)
+        drawSeriesLines(series);
+      if (series.bars.show)
+        drawSeriesBars(series);
+      if (series.points.show)
+        drawSeriesPoints(series);
+    }
+
+    function drawSeriesLines(series) {
+      function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
+        var points = datapoints.points,
+            ps = datapoints.pointsize,
+            prevx = null, prevy = null;
+
+        ctx.beginPath();
+        for (var i = ps; i < points.length; i += ps) {
+          var x1 = points[i - ps], y1 = points[i - ps + 1],
+              x2 = points[i], y2 = points[i + 1];
+
+          if (x1 == null || x2 == null)
+            continue;
+
+          // clip with ymin
+          if (y1 <= y2 && y1 < axisy.min) {
+            if (y2 < axisy.min)
+              continue;   // line segment is outside
+            // compute new intersection point
+            x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y1 = axisy.min;
+          }
+          else if (y2 <= y1 && y2 < axisy.min) {
+            if (y1 < axisy.min)
+              continue;
+            x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y2 = axisy.min;
+          }
+
+          // clip with ymax
+          if (y1 >= y2 && y1 > axisy.max) {
+            if (y2 > axisy.max)
+              continue;
+            x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y1 = axisy.max;
+          }
+          else if (y2 >= y1 && y2 > axisy.max) {
+            if (y1 > axisy.max)
+              continue;
+            x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y2 = axisy.max;
+          }
+
+          // clip with xmin
+          if (x1 <= x2 && x1 < axisx.min) {
+            if (x2 < axisx.min)
+              continue;
+            y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x1 = axisx.min;
+          }
+          else if (x2 <= x1 && x2 < axisx.min) {
+            if (x1 < axisx.min)
+              continue;
+            y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x2 = axisx.min;
+          }
+
+          // clip with xmax
+          if (x1 >= x2 && x1 > axisx.max) {
+            if (x2 > axisx.max)
+              continue;
+            y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x1 = axisx.max;
+          }
+          else if (x2 >= x1 && x2 > axisx.max) {
+            if (x1 > axisx.max)
+              continue;
+            y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x2 = axisx.max;
+          }
+
+          if (x1 != prevx || y1 != prevy)
+            ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+
+          prevx = x2;
+          prevy = y2;
+          ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+        }
+        ctx.stroke();
+      }
+
+      function plotLineArea(datapoints, axisx, axisy) {
+        var points = datapoints.points,
+            ps = datapoints.pointsize,
+            bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+            i = 0, top, areaOpen = false,
+            ypos = 1, segmentStart = 0, segmentEnd = 0;
+
+        // we process each segment in two turns, first forward
+        // direction to sketch out top, then once we hit the
+        // end we go backwards to sketch the bottom
+        while (true) {
+          if (ps > 0 && i > points.length + ps)
+            break;
+
+          i += ps; // ps is negative if going backwards
+
+          var x1 = points[i - ps],
+              y1 = points[i - ps + ypos],
+              x2 = points[i], y2 = points[i + ypos];
+
+          if (areaOpen) {
+            if (ps > 0 && x1 != null && x2 == null) {
+              // at turning point
+              segmentEnd = i;
+              ps = -ps;
+              ypos = 2;
+              continue;
+            }
+
+            if (ps < 0 && i == segmentStart + ps) {
+              // done with the reverse sweep
+              ctx.fill();
+              areaOpen = false;
+              ps = -ps;
+              ypos = 1;
+              i = segmentStart = segmentEnd + ps;
+              continue;
+            }
+          }
+
+          if (x1 == null || x2 == null)
+            continue;
+
+          // clip x values
+
+          // clip with xmin
+          if (x1 <= x2 && x1 < axisx.min) {
+            if (x2 < axisx.min)
+              continue;
+            y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x1 = axisx.min;
+          }
+          else if (x2 <= x1 && x2 < axisx.min) {
+            if (x1 < axisx.min)
+              continue;
+            y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x2 = axisx.min;
+          }
+
+          // clip with xmax
+          if (x1 >= x2 && x1 > axisx.max) {
+            if (x2 > axisx.max)
+              continue;
+            y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x1 = axisx.max;
+          }
+          else if (x2 >= x1 && x2 > axisx.max) {
+            if (x1 > axisx.max)
+              continue;
+            y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+            x2 = axisx.max;
+          }
+
+          if (!areaOpen) {
+            // open area
+            ctx.beginPath();
+            ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
+            areaOpen = true;
+          }
+
+          // now first check the case where both is outside
+          if (y1 >= axisy.max && y2 >= axisy.max) {
+            ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
+            ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
+            continue;
+          }
+          else if (y1 <= axisy.min && y2 <= axisy.min) {
+            ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
+            ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
+            continue;
+          }
+
+          // else it's a bit more complicated, there might
+          // be a flat maxed out rectangle first, then a
+          // triangular cutout or reverse; to find these
+          // keep track of the current x values
+          var x1old = x1, x2old = x2;
+
+          // clip the y values, without shortcutting, we
+          // go through all cases in turn
+
+          // clip with ymin
+          if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
+            x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y1 = axisy.min;
+          }
+          else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
+            x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y2 = axisy.min;
+          }
+
+          // clip with ymax
+          if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
+            x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y1 = axisy.max;
+          }
+          else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
+            x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+            y2 = axisy.max;
+          }
+
+          // if the x value was changed we got a rectangle
+          // to fill
+          if (x1 != x1old) {
+            ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
+            // it goes to (x1, y1), but we fill that below
+          }
+
+          // fill triangular section, this sometimes result
+          // in redundant points if (x1, y1) hasn't changed
+          // from previous line to, but we just ignore that
+          ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
+          ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+
+          // fill the other rectangle if it's there
+          if (x2 != x2old) {
+            ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+            ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
+          }
+        }
+      }
+
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+      ctx.lineJoin = "round";
+
+      var lw = series.lines.lineWidth,
+          sw = series.shadowSize;
+      // FIXME: consider another form of shadow when filling is turned on
+      if (lw > 0 && sw > 0) {
+        // draw shadow as a thick and thin line with transparency
+        ctx.lineWidth = sw;
+        ctx.strokeStyle = "rgba(0,0,0,0.1)";
+        // position shadow at angle from the mid of line
+        var angle = Math.PI/18;
+        plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
+        ctx.lineWidth = sw/2;
+        plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
+      }
+
+      ctx.lineWidth = lw;
+      ctx.strokeStyle = series.color;
+      var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
+      if (fillStyle) {
+        ctx.fillStyle = fillStyle;
+        plotLineArea(series.datapoints, series.xaxis, series.yaxis);
+      }
+
+      if (lw > 0)
+        plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
+      ctx.restore();
+    }
+
+    function drawSeriesPoints(series) {
+      function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
+        var points = datapoints.points, ps = datapoints.pointsize;
+
+        for (var i = 0; i < points.length; i += ps) {
+          var x = points[i], y = points[i + 1];
+          if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+            continue;
+
+          ctx.beginPath();
+          x = axisx.p2c(x);
+          y = axisy.p2c(y) + offset;
+          if (symbol == "circle")
+            ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
+          else
+            symbol(ctx, x, y, radius, shadow);
+          ctx.closePath();
+
+          if (fillStyle) {
+            ctx.fillStyle = fillStyle;
+            ctx.fill();
+          }
+          ctx.stroke();
+        }
+      }
+
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+
+      var lw = series.points.lineWidth,
+          sw = series.shadowSize,
+          radius = series.points.radius,
+          symbol = series.points.symbol;
+
+      // If the user sets the line width to 0, we change it to a very
+      // small value. A line width of 0 seems to force the default of 1.
+      // Doing the conditional here allows the shadow setting to still be
+      // optional even with a lineWidth of 0.
+
+      if( lw == 0 )
+        lw = 0.0001;
+
+      if (lw > 0 && sw > 0) {
+        // draw shadow in two steps
+        var w = sw / 2;
+        ctx.lineWidth = w;
+        ctx.strokeStyle = "rgba(0,0,0,0.1)";
+        plotPoints(series.datapoints, radius, null, w + w/2, true,
+            series.xaxis, series.yaxis, symbol);
+
+        ctx.strokeStyle = "rgba(0,0,0,0.2)";
+        plotPoints(series.datapoints, radius, null, w/2, true,
+            series.xaxis, series.yaxis, symbol);
+      }
+
+      ctx.lineWidth = lw;
+      ctx.strokeStyle = series.color;
+      plotPoints(series.datapoints, radius,
+          getFillStyle(series.points, series.color), 0, false,
+          series.xaxis, series.yaxis, symbol);
+      ctx.restore();
+    }
+
+    function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
+      var left, right, bottom, top,
+          drawLeft, drawRight, drawTop, drawBottom,
+          tmp;
+
+      // in horizontal mode, we start the bar from the left
+      // instead of from the bottom so it appears to be
+      // horizontal rather than vertical
+      if (horizontal) {
+        drawBottom = drawRight = drawTop = true;
+        drawLeft = false;
+        left = b;
+        right = x;
+        top = y + barLeft;
+        bottom = y + barRight;
+
+        // account for negative bars
+        if (right < left) {
+          tmp = right;
+          right = left;
+          left = tmp;
+          drawLeft = true;
+          drawRight = false;
+        }
+      }
+      else {
+        drawLeft = drawRight = drawTop = true;
+        drawBottom = false;
+        left = x + barLeft;
+        right = x + barRight;
+        bottom = b;
+        top = y;
+
+        // account for negative bars
+        if (top < bottom) {
+          tmp = top;
+          top = bottom;
+          bottom = tmp;
+          drawBottom = true;
+          drawTop = false;
+        }
+      }
+
+      // clip
+      if (right < axisx.min || left > axisx.max ||
+          top < axisy.min || bottom > axisy.max)
+        return;
+
+      if (left < axisx.min) {
+        left = axisx.min;
+        drawLeft = false;
+      }
+
+      if (right > axisx.max) {
+        right = axisx.max;
+        drawRight = false;
+      }
+
+      if (bottom < axisy.min) {
+        bottom = axisy.min;
+        drawBottom = false;
+      }
+
+      if (top > axisy.max) {
+        top = axisy.max;
+        drawTop = false;
+      }
+
+      left = axisx.p2c(left);
+      bottom = axisy.p2c(bottom);
+      right = axisx.p2c(right);
+      top = axisy.p2c(top);
+
+      // fill the bar
+      if (fillStyleCallback) {
+        c.fillStyle = fillStyleCallback(bottom, top);
+        c.fillRect(left, top, right - left, bottom - top)
+      }
+
+      // draw outline
+      if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
+        c.beginPath();
+
+        // FIXME: inline moveTo is buggy with excanvas
+        c.moveTo(left, bottom);
+        if (drawLeft)
+          c.lineTo(left, top);
+        else
+          c.moveTo(left, top);
+        if (drawTop)
+          c.lineTo(right, top);
+        else
+          c.moveTo(right, top);
+        if (drawRight)
+          c.lineTo(right, bottom);
+        else
+          c.moveTo(right, bottom);
+        if (drawBottom)
+          c.lineTo(left, bottom);
+        else
+          c.moveTo(left, bottom);
+        c.stroke();
+      }
+    }
+
+    function drawSeriesBars(series) {
+      function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
+        var points = datapoints.points, ps = datapoints.pointsize;
+
+        for (var i = 0; i < points.length; i += ps) {
+          if (points[i] == null)
+            continue;
+          drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
+        }
+      }
+
+      ctx.save();
+      ctx.translate(plotOffset.left, plotOffset.top);
+
+      // FIXME: figure out a way to add shadows (for instance along the right edge)
+      ctx.lineWidth = series.bars.lineWidth;
+      ctx.strokeStyle = series.color;
+
+      var barLeft;
+
+      switch (series.bars.align) {
+        case "left":
+          barLeft = 0;
+          break;
+        case "right":
+          barLeft = -series.bars.barWidth;
+          break;
+        default:
+          barLeft = -series.bars.barWidth / 2;
+      }
+
+      var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
+      plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
+      ctx.restore();
+    }
+
+    function getFillStyle(filloptions, seriesColor, bottom, top) {
+      var fill = filloptions.fill;
+      if (!fill)
+        return null;
+
+      if (filloptions.fillColor)
+        return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
+
+      var c = $.color.parse(seriesColor);
+      c.a = typeof fill == "number" ? fill : 0.4;
+      c.normalize();
+      return c.toString();
+    }
+
+    function insertLegend() {
+
+      if (options.legend.container != null) {
+        $(options.legend.container).html("");
+      } else {
+        placeholder.find(".legend").remove();
+      }
+
+      if (!options.legend.show) {
+        return;
+      }
+
+      var fragments = [], entries = [], rowStarted = false,
+          lf = options.legend.labelFormatter, s, label;
+
+      // Build a list of legend entries, with each having a label and a color
+
+      for (var i = 0; i < series.length; ++i) {
+        s = series[i];
+        if (s.label) {
+          label = lf ? lf(s.label, s) : s.label;
+          if (label) {
+            entries.push({
+              label: label,
+              color: s.color
+            });
+          }
+        }
+      }
+
+      // Sort the legend using either the default or a custom comparator
+
+      if (options.legend.sorted) {
+        if ($.isFunction(options.legend.sorted)) {
+          entries.sort(options.legend.sorted);
+        } else if (options.legend.sorted == "reverse") {
+          entries.reverse();
+        } else {
+          var ascending = options.legend.sorted != "descending";
+          entries.sort(function(a, b) {
+            return a.label == b.label ? 0 : (
+                (a.label < b.label) != ascending ? 1 : -1   // Logical XOR
+            );
+          });
+        }
+      }
+
+      // Generate markup for the list of entries, in their final order
+
+      for (var i = 0; i < entries.length; ++i) {
+
+        var entry = entries[i];
+
+        if (i % options.legend.noColumns == 0) {
+          if (rowStarted)
+            fragments.push('</tr>');
+          fragments.push('<tr>');
+          rowStarted = true;
+        }
+
+        fragments.push(
+            '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' +
+            '<td class="legendLabel">' + entry.label + '</td>'
+        );
+      }
+
+      if (rowStarted)
+        fragments.push('</tr>');
+
+      if (fragments.length == 0)
+        return;
+
+      var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
+      if (options.legend.container != null)
+        $(options.legend.container).html(table);
+      else {
+        var pos = "",
+            p = options.legend.position,
+            m = options.legend.margin;
+        if (m[0] == null)
+          m = [m, m];
+        if (p.charAt(0) == "n")
+          pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
+        else if (p.charAt(0) == "s")
+          pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
+        if (p.charAt(1) == "e")
+          pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
+        else if (p.charAt(1) == "w")
+          pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
+        var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
+        if (options.legend.backgroundOpacity != 0.0) {
+          // put in the transparent background
+          // separately to avoid blended labels and
+          // label boxes
+          var c = options.legend.backgroundColor;
+          if (c == null) {
+            c = options.grid.backgroundColor;
+            if (c && typeof c == "string")
+              c = $.color.parse(c);
+            else
+              c = $.color.extract(legend, 'background-color');
+            c.a = 1;
+            c = c.toString();
+          }
+          var div = legend.children();
+          $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
+        }
+      }
+    }
+
+
+    // interactive features
+
+    var highlights = [],
+        redrawTimeout = null;
+
+    // returns the data item the mouse is over, or null if none is found
+    function findNearbyItem(mouseX, mouseY, seriesFilter) {
+      var maxDistance = options.grid.mouseActiveRadius,
+          smallestDistance = maxDistance * maxDistance + 1,
+          item = null, foundPoint = false, i, j, ps;
+
+      for (i = series.length - 1; i >= 0; --i) {
+        if (!seriesFilter(series[i]))
+          continue;
+
+        var s = series[i],
+            axisx = s.xaxis,
+            axisy = s.yaxis,
+            points = s.datapoints.points,
+            mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+            my = axisy.c2p(mouseY),
+            maxx = maxDistance / axisx.scale,
+            maxy = maxDistance / axisy.scale;
+
+        ps = s.datapoints.pointsize;
+        // with inverse transforms, we can't use the maxx/maxy
+        // optimization, sadly
+        if (axisx.options.inverseTransform)
+          maxx = Number.MAX_VALUE;
+        if (axisy.options.inverseTransform)
+          maxy = Number.MAX_VALUE;
+
+        if (s.lines.show || s.points.show) {
+          for (j = 0; j < points.length; j += ps) {
+            var x = points[j], y = points[j + 1];
+            if (x == null)
+              continue;
+
+            // For points and lines, the cursor must be within a
+            // certain distance to the data point
+            if (x - mx > maxx || x - mx < -maxx ||
+                y - my > maxy || y - my < -maxy)
+              continue;
+
+            // We have to calculate distances in pixels, not in
+            // data units, because the scales of the axes may be different
+            var dx = Math.abs(axisx.p2c(x) - mouseX),
+                dy = Math.abs(axisy.p2c(y) - mouseY),
+                dist = dx * dx + dy * dy; // we save the sqrt
+
+            // use <= to ensure last point takes precedence
+            // (last generally means on top of)
+            if (dist < smallestDistance) {
+              smallestDistance = dist;
+              item = [i, j / ps];
+            }
+          }
+        }
+
+        if (s.bars.show && !item) { // no other point can be nearby
+
+          var barLeft, barRight;
+
+          switch (s.bars.align) {
+            case "left":
+              barLeft = 0;
+              break;
+            case "right":
+              barLeft = -s.bars.barWidth;
+              break;
+            default:
+              barLeft = -s.bars.barWidth / 2;
+          }
+
+          barRight = barLeft + s.bars.barWidth;
+
+          for (j = 0; j < points.length; j += ps) {
+            var x = points[j], y = points[j + 1], b = points[j + 2];
+            if (x == null)
+              continue;
+
+            // for a bar graph, the cursor must be inside the bar
+            if (series[i].bars.horizontal ?
+                (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
+                    my >= y + barLeft && my <= y + barRight) :
+                (mx >= x + barLeft && mx <= x + barRight &&
+                    my >= Math.min(b, y) && my <= Math.max(b, y)))
+              item = [i, j / ps];
+          }
+        }
+      }
+
+      if (item) {
+        i = item[0];
+        j = item[1];
+        ps = series[i].datapoints.pointsize;
+
+        return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
+          dataIndex: j,
+          series: series[i],
+          seriesIndex: i };
+      }
+
+      return null;
+    }
+
+    function onMouseMove(e) {
+      if (options.grid.hoverable)
+        triggerClickHoverEvent("plothover", e,
+            function (s) { return s["hoverable"] != false; });
+    }
+
+    function onMouseLeave(e) {
+      if (options.grid.hoverable)
+        triggerClickHoverEvent("plothover", e,
+            function (s) { return false; });
+    }
+
+    function onClick(e) {
+      triggerClickHoverEvent("plotclick", e,
+          function (s) { return s["clickable"] != false; });
+    }
+
+    // trigger click or hover event (they send the same parameters
+    // so we share their code)
+    function triggerClickHoverEvent(eventname, event, seriesFilter) {
+      var offset = eventHolder.offset(),
+          canvasX = event.pageX - offset.left - plotOffset.left,
+          canvasY = event.pageY - offset.top - plotOffset.top,
+          pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
+
+      pos.pageX = event.pageX;
+      pos.pageY = event.pageY;
+
+      var item = findNearbyItem(canvasX, canvasY, seriesFilter);
+
+      if (item) {
+        // fill in mouse pos for any listeners out there
+        item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
+        item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
+      }
+
+      if (options.grid.autoHighlight) {
+        // clear auto-highlights
+        for (var i = 0; i < highlights.length; ++i) {
+          var h = highlights[i];
+          if (h.auto == eventname &&
+              !(item && h.series == item.series &&
+                  h.point[0] == item.datapoint[0] &&
+                  h.point[1] == item.datapoint[1]))
+            unhighlight(h.series, h.point);
+        }
+
+        if (item)
+          highlight(item.series, item.datapoint, eventname);
+      }
+
+      placeholder.trigger(eventname, [ pos, item ]);
+    }
+
+    function triggerRedrawOverlay() {
+      var t = options.interaction.redrawOverlayInterval;
+      if (t == -1) {      // skip event queue
+        drawOverlay();
+        return;
+      }
+
+      if (!redrawTimeout)
+        redrawTimeout = setTimeout(drawOverlay, t);
+    }
+
+    function drawOverlay() {
+      redrawTimeout = null;
+
+      // draw highlights
+      octx.save();
+      overlay.clear();
+      octx.translate(plotOffset.left, plotOffset.top);
+
+      var i, hi;
+      for (i = 0; i < highlights.length; ++i) {
+        hi = highlights[i];
+
+        if (hi.series.bars.show)
+          drawBarHighlight(hi.series, hi.point);
+        else
+          drawPointHighlight(hi.series, hi.point);
+      }
+      octx.restore();
+
+      executeHooks(hooks.drawOverlay, [octx]);
+    }
+
+    function highlight(s, point, auto) {
+      if (typeof s == "number")
+        s = series[s];
+
+      if (typeof point == "number") {
+        var ps = s.datapoints.pointsize;
+        point = s.datapoints.points.slice(ps * point, ps * (point + 1));
+      }
+
+      var i = indexOfHighlight(s, point);
+      if (i == -1) {
+        highlights.push({ series: s, point: point, auto: auto });
+
+        triggerRedrawOverlay();
+      }
+      else if (!auto)
+        highlights[i].auto = false;
+    }
+
+    function unhighlight(s, point) {
+      if (s == null && point == null) {
+        highlights = [];
+        triggerRedrawOverlay();
+        return;
+      }
+
+      if (typeof s == "number")
+        s = series[s];
+
+      if (typeof point == "number") {
+        var ps = s.datapoints.pointsize;
+        point = s.datapoints.points.slice(ps * point, ps * (point + 1));
+      }
+
+      var i = indexOfHighlight(s, point);
+      if (i != -1) {
+        highlights.splice(i, 1);
+
+        triggerRedrawOverlay();
+      }
+    }
+
+    function indexOfHighlight(s, p) {
+      for (var i = 0; i < highlights.length; ++i) {
+        var h = highlights[i];
+        if (h.series == s && h.point[0] == p[0]
+            && h.point[1] == p[1])
+          return i;
+      }
+      return -1;
+    }
+
+    function drawPointHighlight(series, point) {
+      var x = point[0], y = point[1],
+          axisx = series.xaxis, axisy = series.yaxis,
+          highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
+
+      if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+        return;
+
+      var pointRadius = series.points.radius + series.points.lineWidth / 2;
+      octx.lineWidth = pointRadius;
+      octx.strokeStyle = highlightColor;
+      var radius = 1.5 * pointRadius;
+      x = axisx.p2c(x);
+      y = axisy.p2c(y);
+
+      octx.beginPath();
+      if (series.points.symbol == "circle")
+        octx.arc(x, y, radius, 0, 2 * Math.PI, false);
+      else
+        series.points.symbol(octx, x, y, radius, false);
+      octx.closePath();
+      octx.stroke();
+    }
+
+    function drawBarHighlight(series, point) {
+      var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
+          fillStyle = highlightColor,
+          barLeft;
+
+      switch (series.bars.align) {
+        case "left":
+          barLeft = 0;
+          break;
+        case "right":
+          barLeft = -series.bars.barWidth;
+          break;
+        default:
+          barLeft = -series.bars.barWidth / 2;
+      }
+
+      octx.lineWidth = series.bars.lineWidth;
+      octx.strokeStyle = highlightColor;
+
+      drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
+          function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
+    }
+
+    function getColorOrGradient(spec, bottom, top, defaultColor) {
+      if (typeof spec == "string")
+        return spec;
+      else {
+        // assume this is a gradient spec; IE currently only
+        // supports a simple vertical gradient properly, so that's
+        // what we support too
+        var gradient = ctx.createLinearGradient(0, top, 0, bottom);
+
+        for (var i = 0, l = spec.colors.length; i < l; ++i) {
+          var c = spec.colors[i];
+          if (typeof c != "string") {
+            var co = $.color.parse(defaultColor);
+            if (c.brightness != null)
+              co = co.scale('rgb', c.brightness);
+            if (c.opacity != null)
+              co.a *= c.opacity;
+            c = co.toString();
+          }
+          gradient.addColorStop(i / (l - 1), c);
+        }
+
+        return gradient;
+      }
+    }
+  }
+
+  // Add the plot function to the top level of the jQuery object
+
+  $.plot = function(placeholder, data, options) {
+    //var t0 = new Date();
+    var plot = new Plot($(placeholder), data, options, $.plot.plugins);
+    //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
+    return plot;
+  };
+
+  $.plot.version = "0.8.3";
+
+  $.plot.plugins = [];
+
+  // Also add the plot function as a chainable property
+
+  $.fn.plot = function(data, options) {
+    return this.each(function() {
+      $.plot(this, data, options);
+    });
+  };
+
+  // round to nearby lower multiple of base
+  function floorInBase(n, base) {
+    return base * Math.floor(n / base);
+  }
+
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.navigate.js b/ui/lib/flot/jquery.flot.navigate.js
index f2b9760..c96bc7e 100644
--- a/ui/lib/flot/jquery.flot.navigate.js
+++ b/ui/lib/flot/jquery.flot.navigate.js
@@ -1,336 +1,346 @@
-/*
-Flot plugin for adding panning and zooming capabilities to a plot.
+/* Flot plugin for adding the ability to pan and zoom the plot.
 
-The default behaviour is double click and scrollwheel up/down to zoom
-in, drag to pan. The plugin defines plot.zoom({ center }),
-plot.zoomOut() and plot.pan(offset) so you easily can add custom
-controls. It also fires a "plotpan" and "plotzoom" event when
-something happens, useful for synchronizing plots.
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-Options:
+The default behaviour is double click and scrollwheel up/down to zoom in, drag
+to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
+plot.pan( offset ) so you easily can add custom controls. It also fires
+"plotpan" and "plotzoom" events, useful for synchronizing plots.
 
-  zoom: {
-    interactive: false
-    trigger: "dblclick" // or "click" for single click
-    amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
-  }
-  
-  pan: {
-    interactive: false
-    cursor: "move"      // CSS mouse cursor value used when dragging, e.g. "pointer"
-    frameRate: 20
-  }
+The plugin supports these options:
 
-  xaxis, yaxis, x2axis, y2axis: {
-    zoomRange: null  // or [number, number] (min range, max range) or false
-    panRange: null   // or [number, number] (min, max) or false
-  }
-  
+	zoom: {
+		interactive: false
+		trigger: "dblclick" // or "click" for single click
+		amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
+	}
+
+	pan: {
+		interactive: false
+		cursor: "move"      // CSS mouse cursor value used when dragging, e.g. "pointer"
+		frameRate: 20
+	}
+
+	xaxis, yaxis, x2axis, y2axis: {
+		zoomRange: null  // or [ number, number ] (min range, max range) or false
+		panRange: null   // or [ number, number ] (min, max) or false
+	}
+
 "interactive" enables the built-in drag/click behaviour. If you enable
-interactive for pan, then you'll have a basic plot that supports
-moving around; the same for zoom.
+interactive for pan, then you'll have a basic plot that supports moving
+around; the same for zoom.
 
-"amount" specifies the default amount to zoom in (so 1.5 = 150%)
-relative to the current viewport.
+"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
+the current viewport.
 
-"cursor" is a standard CSS mouse cursor string used for visual
-feedback to the user when dragging.
+"cursor" is a standard CSS mouse cursor string used for visual feedback to the
+user when dragging.
 
-"frameRate" specifies the maximum number of times per second the plot
-will update itself while the user is panning around on it (set to null
-to disable intermediate pans, the plot will then not update until the
-mouse button is released).
+"frameRate" specifies the maximum number of times per second the plot will
+update itself while the user is panning around on it (set to null to disable
+intermediate pans, the plot will then not update until the mouse button is
+released).
 
-"zoomRange" is the interval in which zooming can happen, e.g. with
-zoomRange: [1, 100] the zoom will never scale the axis so that the
-difference between min and max is smaller than 1 or larger than 100.
-You can set either end to null to ignore, e.g. [1, null]. If you set
-zoomRange to false, zooming on that axis will be disabled.
+"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
+[1, 100] the zoom will never scale the axis so that the difference between min
+and max is smaller than 1 or larger than 100. You can set either end to null
+to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
+will be disabled.
 
-"panRange" confines the panning to stay within a range, e.g. with
-panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
-other. Either can be null, e.g. [-10, null]. If you set
-panRange to false, panning on that axis will be disabled.
+"panRange" confines the panning to stay within a range, e.g. with panRange:
+[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
+be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
+will be disabled.
 
 Example API usage:
 
-  plot = $.plot(...);
-  
-  // zoom default amount in on the pixel (10, 20) 
-  plot.zoom({ center: { left: 10, top: 20 } });
+	plot = $.plot(...);
 
-  // zoom out again
-  plot.zoomOut({ center: { left: 10, top: 20 } });
+	// zoom default amount in on the pixel ( 10, 20 )
+	plot.zoom({ center: { left: 10, top: 20 } });
 
-  // zoom 200% in on the pixel (10, 20) 
-  plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
-  
-  // pan 100 pixels to the left and 20 down
-  plot.pan({ left: -100, top: 20 })
+	// zoom out again
+	plot.zoomOut({ center: { left: 10, top: 20 } });
 
-Here, "center" specifies where the center of the zooming should
-happen. Note that this is defined in pixel space, not the space of the
-data points (you can use the p2c helpers on the axes in Flot to help
-you convert between these).
+	// zoom 200% in on the pixel (10, 20)
+	plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
 
-"amount" is the amount to zoom the viewport relative to the current
-range, so 1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is
-70% (zoom out). You can set the default in the options.
-  
+	// pan 100 pixels to the left and 20 down
+	plot.pan({ left: -100, top: 20 })
+
+Here, "center" specifies where the center of the zooming should happen. Note
+that this is defined in pixel space, not the space of the data points (you can
+use the p2c helpers on the axes in Flot to help you convert between these).
+
+"amount" is the amount to zoom the viewport relative to the current range, so
+1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
+can set the default in the options.
+
 */
 
-
 // First two dependencies, jquery.event.drag.js and
 // jquery.mousewheel.js, we put them inline here to save people the
 // effort of downloading them.
 
 /*
-jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)  
+jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
 Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
 */
-(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);
-
+(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);
 
 /* jquery.mousewheel.min.js
- * Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
- * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
- * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ * Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
+ * Licensed under the MIT License (LICENSE.txt).
  * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
  * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
  *
- * Version: 3.0.2
- * 
+ * Version: 3.0.6
+ *
  * Requires: 1.2.2+
  */
-(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
+(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
 
 
 
 
 (function ($) {
-    var options = {
-        xaxis: {
-            zoomRange: null, // or [number, number] (min range, max range)
-            panRange: null // or [number, number] (min, max)
-        },
-        zoom: {
-            interactive: false,
-            trigger: "dblclick", // or "click" for single click
-            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
-        },
-        pan: {
-            interactive: false,
-            cursor: "move",
-            frameRate: 20
-        }
+  var options = {
+    xaxis: {
+      zoomRange: null, // or [number, number] (min range, max range)
+      panRange: null // or [number, number] (min, max)
+    },
+    zoom: {
+      interactive: false,
+      trigger: "dblclick", // or "click" for single click
+      amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
+    },
+    pan: {
+      interactive: false,
+      cursor: "move",
+      frameRate: 20
+    }
+  };
+
+  function init(plot) {
+    function onZoomClick(e, zoomOut) {
+      var c = plot.offset();
+      c.left = e.pageX - c.left;
+      c.top = e.pageY - c.top;
+      if (zoomOut)
+        plot.zoomOut({ center: c });
+      else
+        plot.zoom({ center: c });
+    }
+
+    function onMouseWheel(e, delta) {
+      e.preventDefault();
+      onZoomClick(e, delta < 0);
+      return false;
+    }
+
+    var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
+        panTimeout = null;
+
+    function onDragStart(e) {
+      if (e.which != 1)  // only accept left-click
+        return false;
+      var c = plot.getPlaceholder().css('cursor');
+      if (c)
+        prevCursor = c;
+      plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
+      prevPageX = e.pageX;
+      prevPageY = e.pageY;
+    }
+
+    function onDrag(e) {
+      var frameRate = plot.getOptions().pan.frameRate;
+      if (panTimeout || !frameRate)
+        return;
+
+      panTimeout = setTimeout(function () {
+        plot.pan({ left: prevPageX - e.pageX,
+          top: prevPageY - e.pageY });
+        prevPageX = e.pageX;
+        prevPageY = e.pageY;
+
+        panTimeout = null;
+      }, 1 / frameRate * 1000);
+    }
+
+    function onDragEnd(e) {
+      if (panTimeout) {
+        clearTimeout(panTimeout);
+        panTimeout = null;
+      }
+
+      plot.getPlaceholder().css('cursor', prevCursor);
+      plot.pan({ left: prevPageX - e.pageX,
+        top: prevPageY - e.pageY });
+    }
+
+    function bindEvents(plot, eventHolder) {
+      var o = plot.getOptions();
+      if (o.zoom.interactive) {
+        eventHolder[o.zoom.trigger](onZoomClick);
+        eventHolder.mousewheel(onMouseWheel);
+      }
+
+      if (o.pan.interactive) {
+        eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
+        eventHolder.bind("drag", onDrag);
+        eventHolder.bind("dragend", onDragEnd);
+      }
+    }
+
+    plot.zoomOut = function (args) {
+      if (!args)
+        args = {};
+
+      if (!args.amount)
+        args.amount = plot.getOptions().zoom.amount;
+
+      args.amount = 1 / args.amount;
+      plot.zoom(args);
     };
 
-    function init(plot) {
-        function onZoomClick(e, zoomOut) {
-            var c = plot.offset();
-            c.left = e.pageX - c.left;
-            c.top = e.pageY - c.top;
-            if (zoomOut)
-                plot.zoomOut({ center: c });
-            else
-                plot.zoom({ center: c });
-        }
+    plot.zoom = function (args) {
+      if (!args)
+        args = {};
 
-        function onMouseWheel(e, delta) {
-            onZoomClick(e, delta < 0);
-            return false;
-        }
-        
-        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
-            panTimeout = null;
+      var c = args.center,
+          amount = args.amount || plot.getOptions().zoom.amount,
+          w = plot.width(), h = plot.height();
 
-        function onDragStart(e) {
-            if (e.which != 1)  // only accept left-click
-                return false;
-            var c = plot.getPlaceholder().css('cursor');
-            if (c)
-                prevCursor = c;
-            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
-            prevPageX = e.pageX;
-            prevPageY = e.pageY;
-        }
-        
-        function onDrag(e) {
-            var frameRate = plot.getOptions().pan.frameRate;
-            if (panTimeout || !frameRate)
-                return;
+      if (!c)
+        c = { left: w / 2, top: h / 2 };
 
-            panTimeout = setTimeout(function () {
-                plot.pan({ left: prevPageX - e.pageX,
-                           top: prevPageY - e.pageY });
-                prevPageX = e.pageX;
-                prevPageY = e.pageY;
-                                                    
-                panTimeout = null;
-            }, 1 / frameRate * 1000);
-        }
-
-        function onDragEnd(e) {
-            if (panTimeout) {
-                clearTimeout(panTimeout);
-                panTimeout = null;
+      var xf = c.left / w,
+          yf = c.top / h,
+          minmax = {
+            x: {
+              min: c.left - xf * w / amount,
+              max: c.left + (1 - xf) * w / amount
+            },
+            y: {
+              min: c.top - yf * h / amount,
+              max: c.top + (1 - yf) * h / amount
             }
-                    
-            plot.getPlaceholder().css('cursor', prevCursor);
-            plot.pan({ left: prevPageX - e.pageX,
-                       top: prevPageY - e.pageY });
-        }
-        
-        function bindEvents(plot, eventHolder) {
-            var o = plot.getOptions();
-            if (o.zoom.interactive) {
-                eventHolder[o.zoom.trigger](onZoomClick);
-                eventHolder.mousewheel(onMouseWheel);
-            }
+          };
 
-            if (o.pan.interactive) {
-                eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
-                eventHolder.bind("drag", onDrag);
-                eventHolder.bind("dragend", onDragEnd);
-            }
+      $.each(plot.getAxes(), function(_, axis) {
+        var opts = axis.options,
+            min = minmax[axis.direction].min,
+            max = minmax[axis.direction].max,
+            zr = opts.zoomRange,
+            pr = opts.panRange;
+
+        if (zr === false) // no zooming on this axis
+          return;
+
+        min = axis.c2p(min);
+        max = axis.c2p(max);
+        if (min > max) {
+          // make sure min < max
+          var tmp = min;
+          min = max;
+          max = tmp;
         }
 
-        plot.zoomOut = function (args) {
-            if (!args)
-                args = {};
-            
-            if (!args.amount)
-                args.amount = plot.getOptions().zoom.amount
-
-            args.amount = 1 / args.amount;
-            plot.zoom(args);
-        }
-        
-        plot.zoom = function (args) {
-            if (!args)
-                args = {};
-            
-            var c = args.center,
-                amount = args.amount || plot.getOptions().zoom.amount,
-                w = plot.width(), h = plot.height();
-
-            if (!c)
-                c = { left: w / 2, top: h / 2 };
-                
-            var xf = c.left / w,
-                yf = c.top / h,
-                minmax = {
-                    x: {
-                        min: c.left - xf * w / amount,
-                        max: c.left + (1 - xf) * w / amount
-                    },
-                    y: {
-                        min: c.top - yf * h / amount,
-                        max: c.top + (1 - yf) * h / amount
-                    }
-                };
-
-            $.each(plot.getAxes(), function(_, axis) {
-                var opts = axis.options,
-                    min = minmax[axis.direction].min,
-                    max = minmax[axis.direction].max,
-                    zr = opts.zoomRange;
-
-                if (zr === false) // no zooming on this axis
-                    return;
-                    
-                min = axis.c2p(min);
-                max = axis.c2p(max);
-                if (min > max) {
-                    // make sure min < max
-                    var tmp = min;
-                    min = max;
-                    max = tmp;
-                }
-
-                var range = max - min;
-                if (zr &&
-                    ((zr[0] != null && range < zr[0]) ||
-                     (zr[1] != null && range > zr[1])))
-                    return;
-            
-                opts.min = min;
-                opts.max = max;
-            });
-            
-            plot.setupGrid();
-            plot.draw();
-            
-            if (!args.preventEvent)
-                plot.getPlaceholder().trigger("plotzoom", [ plot ]);
+        //Check that we are in panRange
+        if (pr) {
+          if (pr[0] != null && min < pr[0]) {
+            min = pr[0];
+          }
+          if (pr[1] != null && max > pr[1]) {
+            max = pr[1];
+          }
         }
 
-        plot.pan = function (args) {
-            var delta = {
-                x: +args.left,
-                y: +args.top
-            };
+        var range = max - min;
+        if (zr &&
+            ((zr[0] != null && range < zr[0] && amount >1) ||
+                (zr[1] != null && range > zr[1] && amount <1)))
+          return;
 
-            if (isNaN(delta.x))
-                delta.x = 0;
-            if (isNaN(delta.y))
-                delta.y = 0;
+        opts.min = min;
+        opts.max = max;
+      });
 
-            $.each(plot.getAxes(), function (_, axis) {
-                var opts = axis.options,
-                    min, max, d = delta[axis.direction];
+      plot.setupGrid();
+      plot.draw();
 
-                min = axis.c2p(axis.p2c(axis.min) + d),
-                max = axis.c2p(axis.p2c(axis.max) + d);
+      if (!args.preventEvent)
+        plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
+    };
 
-                var pr = opts.panRange;
-                if (pr === false) // no panning on this axis
-                    return;
-                
-                if (pr) {
-                    // check whether we hit the wall
-                    if (pr[0] != null && pr[0] > min) {
-                        d = pr[0] - min;
-                        min += d;
-                        max += d;
-                    }
-                    
-                    if (pr[1] != null && pr[1] < max) {
-                        d = pr[1] - max;
-                        min += d;
-                        max += d;
-                    }
-                }
-                
-                opts.min = min;
-                opts.max = max;
-            });
-            
-            plot.setupGrid();
-            plot.draw();
-            
-            if (!args.preventEvent)
-                plot.getPlaceholder().trigger("plotpan", [ plot ]);
+    plot.pan = function (args) {
+      var delta = {
+        x: +args.left,
+        y: +args.top
+      };
+
+      if (isNaN(delta.x))
+        delta.x = 0;
+      if (isNaN(delta.y))
+        delta.y = 0;
+
+      $.each(plot.getAxes(), function (_, axis) {
+        var opts = axis.options,
+            min, max, d = delta[axis.direction];
+
+        min = axis.c2p(axis.p2c(axis.min) + d),
+            max = axis.c2p(axis.p2c(axis.max) + d);
+
+        var pr = opts.panRange;
+        if (pr === false) // no panning on this axis
+          return;
+
+        if (pr) {
+          // check whether we hit the wall
+          if (pr[0] != null && pr[0] > min) {
+            d = pr[0] - min;
+            min += d;
+            max += d;
+          }
+
+          if (pr[1] != null && pr[1] < max) {
+            d = pr[1] - max;
+            min += d;
+            max += d;
+          }
         }
 
-        function shutdown(plot, eventHolder) {
-            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
-            eventHolder.unbind("mousewheel", onMouseWheel);
-            eventHolder.unbind("dragstart", onDragStart);
-            eventHolder.unbind("drag", onDrag);
-            eventHolder.unbind("dragend", onDragEnd);
-            if (panTimeout)
-                clearTimeout(panTimeout);
-        }
-        
-        plot.hooks.bindEvents.push(bindEvents);
-        plot.hooks.shutdown.push(shutdown);
+        opts.min = min;
+        opts.max = max;
+      });
+
+      plot.setupGrid();
+      plot.draw();
+
+      if (!args.preventEvent)
+        plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
+    };
+
+    function shutdown(plot, eventHolder) {
+      eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
+      eventHolder.unbind("mousewheel", onMouseWheel);
+      eventHolder.unbind("dragstart", onDragStart);
+      eventHolder.unbind("drag", onDrag);
+      eventHolder.unbind("dragend", onDragEnd);
+      if (panTimeout)
+        clearTimeout(panTimeout);
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'navigate',
-        version: '1.3'
-    });
+
+    plot.hooks.bindEvents.push(bindEvents);
+    plot.hooks.shutdown.push(shutdown);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'navigate',
+    version: '1.3'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.pie.js b/ui/lib/flot/jquery.flot.pie.js
index b46c03c..cc5c25d 100644
--- a/ui/lib/flot/jquery.flot.pie.js
+++ b/ui/lib/flot/jquery.flot.pie.js
@@ -1,750 +1,820 @@
-/*
-Flot plugin for rendering pie charts. The plugin assumes the data is 
-coming is as a single data value for each series, and each of those 
-values is a positive value or zero (negative numbers don't make 
-any sense and will cause strange effects). The data values do 
-NOT need to be passed in as percentage values because it 
-internally calculates the total and percentages.
+/* Flot plugin for rendering pie charts.
 
-* Created by Brian Medendorp, June 2009
-* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-* Changes:
-	2009-10-22: lineJoin set to round
-	2009-10-23: IE full circle fix, donut
-	2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
-	2009-11-17: Added IE hover capability submitted by Anthony Aragues
-	2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
-		
+The plugin assumes that each series has a single data value, and that each
+value is a positive integer or zero.  Negative numbers don't make sense for a
+pie chart, and have unpredictable results.  The values do NOT need to be
+passed in as percentages; the plugin will calculate the total and per-slice
+percentages internally.
 
-Available options are:
-series: {
-	pie: {
-		show: true/false
-		radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
-		innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
-		startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
-		tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
-		offset: {
-			top: integer value to move the pie up or down
-			left: integer value to move the pie left or right, or 'auto'
-		},
-		stroke: {
-			color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
-			width: integer pixel width of the stroke
-		},
-		label: {
-			show: true/false, or 'auto'
-			formatter:  a user-defined function that modifies the text/style of the label text
-			radius: 0-1 for percentage of fullsize, or a specified pixel length
-			background: {
-				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
-				opacity: 0-1
+* Created by Brian Medendorp
+
+* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
+
+The plugin supports these options:
+
+	series: {
+		pie: {
+			show: true/false
+			radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
+			innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
+			startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
+			tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
+			offset: {
+				top: integer value to move the pie up or down
+				left: integer value to move the pie left or right, or 'auto'
 			},
-			threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
-		},
-		combine: {
-			threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
-			color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
-			label: any text value of what the combined slice should be labeled
-		}
-		highlight: {
-			opacity: 0-1
+			stroke: {
+				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
+				width: integer pixel width of the stroke
+			},
+			label: {
+				show: true/false, or 'auto'
+				formatter:  a user-defined function that modifies the text/style of the label text
+				radius: 0-1 for percentage of fullsize, or a specified pixel length
+				background: {
+					color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
+					opacity: 0-1
+				},
+				threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
+			},
+			combine: {
+				threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
+				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
+				label: any text value of what the combined slice should be labeled
+			}
+			highlight: {
+				opacity: 0-1
+			}
 		}
 	}
-}
 
 More detail and specific examples can be found in the included HTML file.
 
 */
 
-(function ($) 
-{
-	function init(plot) // this is the "body" of the plugin
-	{
-		var canvas = null;
-		var target = null;
-		var maxRadius = null;
-		var centerLeft = null;
-		var centerTop = null;
-		var total = 0;
-		var redraw = true;
-		var redrawAttempts = 10;
-		var shrink = 0.95;
-		var legendWidth = 0;
-		var processed = false;
-		var raw = false;
-		
-		// interactive variables	
-		var highlights = [];	
-	
-		// add hook to determine if pie plugin in enabled, and then perform necessary operations
-		plot.hooks.processOptions.push(checkPieEnabled);
-		plot.hooks.bindEvents.push(bindEvents);	
+(function($) {
 
-		// check to see if the pie plugin is enabled
-		function checkPieEnabled(plot, options)
-		{
-			if (options.series.pie.show)
-			{
-				//disable grid
-				options.grid.show = false;
-				
-				// set labels.show
-				if (options.series.pie.label.show=='auto')
-					if (options.legend.show)
-						options.series.pie.label.show = false;
-					else
-						options.series.pie.label.show = true;
-				
-				// set radius
-				if (options.series.pie.radius=='auto')
-					if (options.series.pie.label.show)
-						options.series.pie.radius = 3/4;
-					else
-						options.series.pie.radius = 1;
-						
-				// ensure sane tilt
-				if (options.series.pie.tilt>1)
-					options.series.pie.tilt=1;
-				if (options.series.pie.tilt<0)
-					options.series.pie.tilt=0;
-			
-				// add processData hook to do transformations on the data
-				plot.hooks.processDatapoints.push(processDatapoints);
-				plot.hooks.drawOverlay.push(drawOverlay);	
-				
-				// add draw hook
-				plot.hooks.draw.push(draw);
-			}
-		}
-	
-		// bind hoverable events
-		function bindEvents(plot, eventHolder) 		
-		{		
-			var options = plot.getOptions();
-			
-			if (options.series.pie.show && options.grid.hoverable)
-				eventHolder.unbind('mousemove').mousemove(onMouseMove);
-				
-			if (options.series.pie.show && options.grid.clickable)
-				eventHolder.unbind('click').click(onClick);
-		}	
-		
+  // Maximum redraw attempts when fitting labels within the plot
 
-		// debugging function that prints out an object
-		function alertObject(obj)
-		{
-			var msg = '';
-			function traverse(obj, depth)
-			{
-				if (!depth)
-					depth = 0;
-				for (var i = 0; i < obj.length; ++i)
-				{
-					for (var j=0; j<depth; j++)
-						msg += '\t';
-				
-					if( typeof obj[i] == "object")
-					{	// its an object
-						msg += ''+i+':\n';
-						traverse(obj[i], depth+1);
-					}
-					else
-					{	// its a value
-						msg += ''+i+': '+obj[i]+'\n';
-					}
-				}
-			}
-			traverse(obj);
-			alert(msg);
-		}
-		
-		function calcTotal(data)
-		{
-			for (var i = 0; i < data.length; ++i)
-			{
-				var item = parseFloat(data[i].data[0][1]);
-				if (item)
-					total += item;
-			}
-		}	
-		
-		function processDatapoints(plot, series, data, datapoints) 
-		{	
-			if (!processed)
-			{
-				processed = true;
-			
-				canvas = plot.getCanvas();
-				target = $(canvas).parent();
-				options = plot.getOptions();
-			
-				plot.setData(combine(plot.getData()));
-			}
-		}
-		
-		function setupPie()
-		{
-			legendWidth = target.children().filter('.legend').children().width();
-		
-			// calculate maximum radius and center point
-			maxRadius =  Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
-			centerTop = (canvas.height/2)+options.series.pie.offset.top;
-			centerLeft = (canvas.width/2);
-			
-			if (options.series.pie.offset.left=='auto')
-				if (options.legend.position.match('w'))
-					centerLeft += legendWidth/2;
-				else
-					centerLeft -= legendWidth/2;
-			else
-				centerLeft += options.series.pie.offset.left;
-					
-			if (centerLeft<maxRadius)
-				centerLeft = maxRadius;
-			else if (centerLeft>canvas.width-maxRadius)
-				centerLeft = canvas.width-maxRadius;
-		}
-		
-		function fixData(data)
-		{
-			for (var i = 0; i < data.length; ++i)
-			{
-				if (typeof(data[i].data)=='number')
-					data[i].data = [[1,data[i].data]];
-				else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
-				{
-					if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
-						data[i].label = data[i].data.label; // fix weirdness coming from flot
-					data[i].data = [[1,0]];
-					
-				}
-			}
-			return data;
-		}
-		
-		function combine(data)
-		{
-			data = fixData(data);
-			calcTotal(data);
-			var combined = 0;
-			var numCombined = 0;
-			var color = options.series.pie.combine.color;
-			
-			var newdata = [];
-			for (var i = 0; i < data.length; ++i)
-			{
-				// make sure its a number
-				data[i].data[0][1] = parseFloat(data[i].data[0][1]);
-				if (!data[i].data[0][1])
-					data[i].data[0][1] = 0;
-					
-				if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
-				{
-					combined += data[i].data[0][1];
-					numCombined++;
-					if (!color)
-						color = data[i].color;
-				}				
-				else
-				{
-					newdata.push({
-						data: [[1,data[i].data[0][1]]], 
-						color: data[i].color, 
-						label: data[i].label,
-						angle: (data[i].data[0][1]*(Math.PI*2))/total,
-						percent: (data[i].data[0][1]/total*100)
-					});
-				}
-			}
-			if (numCombined>0)
-				newdata.push({
-					data: [[1,combined]], 
-					color: color, 
-					label: options.series.pie.combine.label,
-					angle: (combined*(Math.PI*2))/total,
-					percent: (combined/total*100)
-				});
-			return newdata;
-		}		
-		
-		function draw(plot, newCtx)
-		{
-			if (!target) return; // if no series were passed
-			ctx = newCtx;
-		
-			setupPie();
-			var slices = plot.getData();
-		
-			var attempts = 0;
-			while (redraw && attempts<redrawAttempts)
-			{
-				redraw = false;
-				if (attempts>0)
-					maxRadius *= shrink;
-				attempts += 1;
-				clear();
-				if (options.series.pie.tilt<=0.8)
-					drawShadow();
-				drawPie();
-			}
-			if (attempts >= redrawAttempts) {
-				clear();
-				target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
-			}
-			
-			if ( plot.setSeries && plot.insertLegend )
-			{
-				plot.setSeries(slices);
-				plot.insertLegend();
-			}
-			
-			// we're actually done at this point, just defining internal functions at this point
-			
-			function clear()
-			{
-				ctx.clearRect(0,0,canvas.width,canvas.height);
-				target.children().filter('.pieLabel, .pieLabelBackground').remove();
-			}
-			
-			function drawShadow()
-			{
-				var shadowLeft = 5;
-				var shadowTop = 15;
-				var edge = 10;
-				var alpha = 0.02;
-			
-				// set radius
-				if (options.series.pie.radius>1)
-					var radius = options.series.pie.radius;
-				else
-					var radius = maxRadius * options.series.pie.radius;
-					
-				if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
-					return;	// shadow would be outside canvas, so don't draw it
-			
-				ctx.save();
-				ctx.translate(shadowLeft,shadowTop);
-				ctx.globalAlpha = alpha;
-				ctx.fillStyle = '#000';
+  var REDRAW_ATTEMPTS = 10;
 
-				// center and rotate to starting position
-				ctx.translate(centerLeft,centerTop);
-				ctx.scale(1, options.series.pie.tilt);
-				
-				//radius -= edge;
-				for (var i=1; i<=edge; i++)
-				{
-					ctx.beginPath();
-					ctx.arc(0,0,radius,0,Math.PI*2,false);
-					ctx.fill();
-					radius -= i;
-				}	
-				
-				ctx.restore();
-			}
-			
-			function drawPie()
-			{
-				startAngle = Math.PI*options.series.pie.startAngle;
-				
-				// set radius
-				if (options.series.pie.radius>1)
-					var radius = options.series.pie.radius;
-				else
-					var radius = maxRadius * options.series.pie.radius;
-				
-				// center and rotate to starting position
-				ctx.save();
-				ctx.translate(centerLeft,centerTop);
-				ctx.scale(1, options.series.pie.tilt);
-				//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
-				
-				// draw slices
-				ctx.save();
-				var currentAngle = startAngle;
-				for (var i = 0; i < slices.length; ++i)
-				{
-					slices[i].startAngle = currentAngle;
-					drawSlice(slices[i].angle, slices[i].color, true);
-				}
-				ctx.restore();
-				
-				// draw slice outlines
-				ctx.save();
-				ctx.lineWidth = options.series.pie.stroke.width;
-				currentAngle = startAngle;
-				for (var i = 0; i < slices.length; ++i)
-					drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
-				ctx.restore();
-					
-				// draw donut hole
-				drawDonutHole(ctx);
-				
-				// draw labels
-				if (options.series.pie.label.show)
-					drawLabels();
-				
-				// restore to original state
-				ctx.restore();
-				
-				function drawSlice(angle, color, fill)
-				{	
-					if (angle<=0)
-						return;
-				
-					if (fill)
-						ctx.fillStyle = color;
-					else
-					{
-						ctx.strokeStyle = color;
-						ctx.lineJoin = 'round';
-					}
-						
-					ctx.beginPath();
-					if (Math.abs(angle - Math.PI*2) > 0.000000001)
-						ctx.moveTo(0,0); // Center of the pie
-					else if ($.browser.msie)
-						angle -= 0.0001;
-					//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
-					ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
-					ctx.closePath();
-					//ctx.rotate(angle); // This doesn't work properly in Opera
-					currentAngle += angle;
-					
-					if (fill)
-						ctx.fill();
-					else
-						ctx.stroke();
-				}
-				
-				function drawLabels()
-				{
-					var currentAngle = startAngle;
-					
-					// set radius
-					if (options.series.pie.label.radius>1)
-						var radius = options.series.pie.label.radius;
-					else
-						var radius = maxRadius * options.series.pie.label.radius;
-					
-					for (var i = 0; i < slices.length; ++i)
-					{
-						if (slices[i].percent >= options.series.pie.label.threshold*100)
-							drawLabel(slices[i], currentAngle, i);
-						currentAngle += slices[i].angle;
-					}
-					
-					function drawLabel(slice, startAngle, index)
-					{
-						if (slice.data[0][1]==0)
-							return;
-							
-						// format label text
-						var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
-						if (lf)
-							text = lf(slice.label, slice);
-						else
-							text = slice.label;
-						if (plf)
-							text = plf(text, slice);
-							
-						var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
-						var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
-						var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
-						
-						var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
-						target.append(html);
-						var label = target.children('#pieLabel'+index);
-						var labelTop = (y - label.height()/2);
-						var labelLeft = (x - label.width()/2);
-						label.css('top', labelTop);
-						label.css('left', labelLeft);
-						
-						// check to make sure that the label is not outside the canvas
-						if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
-							redraw = true;
-						
-						if (options.series.pie.label.background.opacity != 0) {
-							// put in the transparent background separately to avoid blended labels and label boxes
-							var c = options.series.pie.label.background.color;
-							if (c == null) {
-								c = slice.color;
-							}
-							var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
-							$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
-						}
-					} // end individual label function
-				} // end drawLabels function
-			} // end drawPie function
-		} // end draw function
-		
-		// Placed here because it needs to be accessed from multiple locations 
-		function drawDonutHole(layer)
-		{
-			// draw donut hole
-			if(options.series.pie.innerRadius > 0)
-			{
-				// subtract the center
-				layer.save();
-				innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
-				layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
-				layer.beginPath();
-				layer.fillStyle = options.series.pie.stroke.color;
-				layer.arc(0,0,innerRadius,0,Math.PI*2,false);
-				layer.fill();
-				layer.closePath();
-				layer.restore();
-				
-				// add inner stroke
-				layer.save();
-				layer.beginPath();
-				layer.strokeStyle = options.series.pie.stroke.color;
-				layer.arc(0,0,innerRadius,0,Math.PI*2,false);
-				layer.stroke();
-				layer.closePath();
-				layer.restore();
-				// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
-			}
-		}
-		
-		//-- Additional Interactive related functions --
-		
-		function isPointInPoly(poly, pt)
-		{
-			for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
-				((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
-				&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
-				&& (c = !c);
-			return c;
-		}
-		
-		function findNearbySlice(mouseX, mouseY)
-		{
-			var slices = plot.getData(),
-				options = plot.getOptions(),
-				radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-			
-			for (var i = 0; i < slices.length; ++i) 
-			{
-				var s = slices[i];	
-				
-				if(s.pie.show)
-				{
-					ctx.save();
-					ctx.beginPath();
-					ctx.moveTo(0,0); // Center of the pie
-					//ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.
-					ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
-					ctx.closePath();
-					x = mouseX-centerLeft;
-					y = mouseY-centerTop;
-					if(ctx.isPointInPath)
-					{
-						if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
-						{
-							//alert('found slice!');
-							ctx.restore();
-							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
-						}
-					}
-					else
-					{
-						// excanvas for IE doesn;t support isPointInPath, this is a workaround. 
-						p1X = (radius * Math.cos(s.startAngle));
-						p1Y = (radius * Math.sin(s.startAngle));
-						p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
-						p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
-						p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
-						p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
-						p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
-						p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
-						p5X = (radius * Math.cos(s.startAngle+s.angle));
-						p5Y = (radius * Math.sin(s.startAngle+s.angle));
-						arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
-						arrPoint = [x,y];
-						// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
-						if(isPointInPoly(arrPoly, arrPoint))
-						{
-							ctx.restore();
-							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
-						}			
-					}
-					ctx.restore();
-				}
-			}
-			
-			return null;
-		}
+  // Factor by which to shrink the pie when fitting labels within the plot
 
-		function onMouseMove(e) 
-		{
-			triggerClickHoverEvent('plothover', e);
-		}
-		
-        function onClick(e) 
-		{
-			triggerClickHoverEvent('plotclick', e);
+  var REDRAW_SHRINK = 0.95;
+
+  function init(plot) {
+
+    var canvas = null,
+        target = null,
+        options = null,
+        maxRadius = null,
+        centerLeft = null,
+        centerTop = null,
+        processed = false,
+        ctx = null;
+
+    // interactive variables
+
+    var highlights = [];
+
+    // add hook to determine if pie plugin in enabled, and then perform necessary operations
+
+    plot.hooks.processOptions.push(function(plot, options) {
+      if (options.series.pie.show) {
+
+        options.grid.show = false;
+
+        // set labels.show
+
+        if (options.series.pie.label.show == "auto") {
+          if (options.legend.show) {
+            options.series.pie.label.show = false;
+          } else {
+            options.series.pie.label.show = true;
+          }
         }
 
-		// trigger click or hover event (they send the same parameters so we share their code)
-		function triggerClickHoverEvent(eventname, e) 
-		{
-			var offset = plot.offset(),
-				canvasX = parseInt(e.pageX - offset.left),
-				canvasY =  parseInt(e.pageY - offset.top),
-				item = findNearbySlice(canvasX, canvasY);
-			
-			if (options.grid.autoHighlight) 
-			{
-				// clear auto-highlights
-				for (var i = 0; i < highlights.length; ++i) 
-				{
-					var h = highlights[i];
-					if (h.auto == eventname && !(item && h.series == item.series))
-						unhighlight(h.series);
-				}
-			}
-			
-			// highlight the slice
-			if (item) 
-			    highlight(item.series, eventname);
-				
-			// trigger any hover bind events
-			var pos = { pageX: e.pageX, pageY: e.pageY };
-			target.trigger(eventname, [ pos, item ]);	
-		}
+        // set radius
 
-		function highlight(s, auto) 
-		{
-			if (typeof s == "number")
-				s = series[s];
+        if (options.series.pie.radius == "auto") {
+          if (options.series.pie.label.show) {
+            options.series.pie.radius = 3/4;
+          } else {
+            options.series.pie.radius = 1;
+          }
+        }
 
-			var i = indexOfHighlight(s);
-			if (i == -1) 
-			{
-				highlights.push({ series: s, auto: auto });
-				plot.triggerRedrawOverlay();
-			}
-			else if (!auto)
-				highlights[i].auto = false;
-		}
+        // ensure sane tilt
 
-		function unhighlight(s) 
-		{
-			if (s == null) 
-			{
-				highlights = [];
-				plot.triggerRedrawOverlay();
-			}
-			
-			if (typeof s == "number")
-				s = series[s];
+        if (options.series.pie.tilt > 1) {
+          options.series.pie.tilt = 1;
+        } else if (options.series.pie.tilt < 0) {
+          options.series.pie.tilt = 0;
+        }
+      }
+    });
 
-			var i = indexOfHighlight(s);
-			if (i != -1) 
-			{
-				highlights.splice(i, 1);
-				plot.triggerRedrawOverlay();
-			}
-		}
+    plot.hooks.bindEvents.push(function(plot, eventHolder) {
+      var options = plot.getOptions();
+      if (options.series.pie.show) {
+        if (options.grid.hoverable) {
+          eventHolder.unbind("mousemove").mousemove(onMouseMove);
+        }
+        if (options.grid.clickable) {
+          eventHolder.unbind("click").click(onClick);
+        }
+      }
+    });
 
-		function indexOfHighlight(s) 
-		{
-			for (var i = 0; i < highlights.length; ++i) 
-			{
-				var h = highlights[i];
-				if (h.series == s)
-					return i;
-			}
-			return -1;
-		}
+    plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
+      var options = plot.getOptions();
+      if (options.series.pie.show) {
+        processDatapoints(plot, series, data, datapoints);
+      }
+    });
 
-		function drawOverlay(plot, octx) 
-		{
-			//alert(options.series.pie.radius);
-			var options = plot.getOptions();
-			//alert(options.series.pie.radius);
-			
-			var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+    plot.hooks.drawOverlay.push(function(plot, octx) {
+      var options = plot.getOptions();
+      if (options.series.pie.show) {
+        drawOverlay(plot, octx);
+      }
+    });
 
-			octx.save();
-			octx.translate(centerLeft, centerTop);
-			octx.scale(1, options.series.pie.tilt);
-			
-			for (i = 0; i < highlights.length; ++i) 
-				drawHighlight(highlights[i].series);
-			
-			drawDonutHole(octx);
+    plot.hooks.draw.push(function(plot, newCtx) {
+      var options = plot.getOptions();
+      if (options.series.pie.show) {
+        draw(plot, newCtx);
+      }
+    });
 
-			octx.restore();
+    function processDatapoints(plot, series, datapoints) {
+      if (!processed)	{
+        processed = true;
+        canvas = plot.getCanvas();
+        target = $(canvas).parent();
+        options = plot.getOptions();
+        plot.setData(combine(plot.getData()));
+      }
+    }
 
-			function drawHighlight(series) 
-			{
-				if (series.angle < 0) return;
-				
-				//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
-				octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
-				
-				octx.beginPath();
-				if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
-					octx.moveTo(0,0); // Center of the pie
-				octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
-				octx.closePath();
-				octx.fill();
-			}
-			
-		}	
-		
-	} // end init (plugin body)
-	
-	// define pie specific options and their default values
-	var options = {
-		series: {
-			pie: {
-				show: false,
-				radius: 'auto',	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
-				innerRadius:0, /* for donut */
-				startAngle: 3/2,
-				tilt: 1,
-				offset: {
-					top: 0,
-					left: 'auto'
-				},
-				stroke: {
-					color: '#FFF',
-					width: 1
-				},
-				label: {
-					show: 'auto',
-					formatter: function(label, slice){
-						return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
-					},	// formatter function
-					radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
-					background: {
-						color: null,
-						opacity: 0
-					},
-					threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)
-				},
-				combine: {
-					threshold: -1,	// percentage at which to combine little slices into one larger slice
-					color: null,	// color to give the new slice (auto-generated if null)
-					label: 'Other'	// label to give the new slice
-				},
-				highlight: {
-					//color: '#FFF',		// will add this functionality once parseColor is available
-					opacity: 0.5
-				}
-			}
-		}
-	};
-    
-	$.plot.plugins.push({
-		init: init,
-		options: options,
-		name: "pie",
-		version: "1.0"
-	});
+    function combine(data) {
+
+      var total = 0,
+          combined = 0,
+          numCombined = 0,
+          color = options.series.pie.combine.color,
+          newdata = [];
+
+      // Fix up the raw data from Flot, ensuring the data is numeric
+
+      for (var i = 0; i < data.length; ++i) {
+
+        var value = data[i].data;
+
+        // If the data is an array, we'll assume that it's a standard
+        // Flot x-y pair, and are concerned only with the second value.
+
+        // Note how we use the original array, rather than creating a
+        // new one; this is more efficient and preserves any extra data
+        // that the user may have stored in higher indexes.
+
+        if ($.isArray(value) && value.length == 1) {
+          value = value[0];
+        }
+
+        if ($.isArray(value)) {
+          // Equivalent to $.isNumeric() but compatible with jQuery < 1.7
+          if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
+            value[1] = +value[1];
+          } else {
+            value[1] = 0;
+          }
+        } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
+          value = [1, +value];
+        } else {
+          value = [1, 0];
+        }
+
+        data[i].data = [value];
+      }
+
+      // Sum up all the slices, so we can calculate percentages for each
+
+      for (var i = 0; i < data.length; ++i) {
+        total += data[i].data[0][1];
+      }
+
+      // Count the number of slices with percentages below the combine
+      // threshold; if it turns out to be just one, we won't combine.
+
+      for (var i = 0; i < data.length; ++i) {
+        var value = data[i].data[0][1];
+        if (value / total <= options.series.pie.combine.threshold) {
+          combined += value;
+          numCombined++;
+          if (!color) {
+            color = data[i].color;
+          }
+        }
+      }
+
+      for (var i = 0; i < data.length; ++i) {
+        var value = data[i].data[0][1];
+        if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
+          newdata.push(
+              $.extend(data[i], {     /* extend to allow keeping all other original data values
+						                           and using them e.g. in labelFormatter. */
+                data: [[1, value]],
+                color: data[i].color,
+                label: data[i].label,
+                angle: value * Math.PI * 2 / total,
+                percent: value / (total / 100)
+              })
+          );
+        }
+      }
+
+      if (numCombined > 1) {
+        newdata.push({
+          data: [[1, combined]],
+          color: color,
+          label: options.series.pie.combine.label,
+          angle: combined * Math.PI * 2 / total,
+          percent: combined / (total / 100)
+        });
+      }
+
+      return newdata;
+    }
+
+    function draw(plot, newCtx) {
+
+      if (!target) {
+        return; // if no series were passed
+      }
+
+      var canvasWidth = plot.getPlaceholder().width(),
+          canvasHeight = plot.getPlaceholder().height(),
+          legendWidth = target.children().filter(".legend").children().width() || 0;
+
+      ctx = newCtx;
+
+      // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
+
+      // When combining smaller slices into an 'other' slice, we need to
+      // add a new series.  Since Flot gives plugins no way to modify the
+      // list of series, the pie plugin uses a hack where the first call
+      // to processDatapoints results in a call to setData with the new
+      // list of series, then subsequent processDatapoints do nothing.
+
+      // The plugin-global 'processed' flag is used to control this hack;
+      // it starts out false, and is set to true after the first call to
+      // processDatapoints.
+
+      // Unfortunately this turns future setData calls into no-ops; they
+      // call processDatapoints, the flag is true, and nothing happens.
+
+      // To fix this we'll set the flag back to false here in draw, when
+      // all series have been processed, so the next sequence of calls to
+      // processDatapoints once again starts out with a slice-combine.
+      // This is really a hack; in 0.9 we need to give plugins a proper
+      // way to modify series before any processing begins.
+
+      processed = false;
+
+      // calculate maximum radius and center point
+
+      maxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
+      centerTop = canvasHeight / 2 + options.series.pie.offset.top;
+      centerLeft = canvasWidth / 2;
+
+      if (options.series.pie.offset.left == "auto") {
+        if (options.legend.position.match("w")) {
+          centerLeft += legendWidth / 2;
+        } else {
+          centerLeft -= legendWidth / 2;
+        }
+        if (centerLeft < maxRadius) {
+          centerLeft = maxRadius;
+        } else if (centerLeft > canvasWidth - maxRadius) {
+          centerLeft = canvasWidth - maxRadius;
+        }
+      } else {
+        centerLeft += options.series.pie.offset.left;
+      }
+
+      var slices = plot.getData(),
+          attempts = 0;
+
+      // Keep shrinking the pie's radius until drawPie returns true,
+      // indicating that all the labels fit, or we try too many times.
+
+      do {
+        if (attempts > 0) {
+          maxRadius *= REDRAW_SHRINK;
+        }
+        attempts += 1;
+        clear();
+        if (options.series.pie.tilt <= 0.8) {
+          drawShadow();
+        }
+      } while (!drawPie() && attempts < REDRAW_ATTEMPTS)
+
+      if (attempts >= REDRAW_ATTEMPTS) {
+        clear();
+        target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
+      }
+
+      if (plot.setSeries && plot.insertLegend) {
+        plot.setSeries(slices);
+        plot.insertLegend();
+      }
+
+      // we're actually done at this point, just defining internal functions at this point
+
+      function clear() {
+        ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+        target.children().filter(".pieLabel, .pieLabelBackground").remove();
+      }
+
+      function drawShadow() {
+
+        var shadowLeft = options.series.pie.shadow.left;
+        var shadowTop = options.series.pie.shadow.top;
+        var edge = 10;
+        var alpha = options.series.pie.shadow.alpha;
+        var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+        if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
+          return;	// shadow would be outside canvas, so don't draw it
+        }
+
+        ctx.save();
+        ctx.translate(shadowLeft,shadowTop);
+        ctx.globalAlpha = alpha;
+        ctx.fillStyle = "#000";
+
+        // center and rotate to starting position
+
+        ctx.translate(centerLeft,centerTop);
+        ctx.scale(1, options.series.pie.tilt);
+
+        //radius -= edge;
+
+        for (var i = 1; i <= edge; i++) {
+          ctx.beginPath();
+          ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
+          ctx.fill();
+          radius -= i;
+        }
+
+        ctx.restore();
+      }
+
+      function drawPie() {
+
+        var startAngle = Math.PI * options.series.pie.startAngle;
+        var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+        // center and rotate to starting position
+
+        ctx.save();
+        ctx.translate(centerLeft,centerTop);
+        ctx.scale(1, options.series.pie.tilt);
+        //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
+
+        // draw slices
+
+        ctx.save();
+        var currentAngle = startAngle;
+        for (var i = 0; i < slices.length; ++i) {
+          slices[i].startAngle = currentAngle;
+          drawSlice(slices[i].angle, slices[i].color, true);
+        }
+        ctx.restore();
+
+        // draw slice outlines
+
+        if (options.series.pie.stroke.width > 0) {
+          ctx.save();
+          ctx.lineWidth = options.series.pie.stroke.width;
+          currentAngle = startAngle;
+          for (var i = 0; i < slices.length; ++i) {
+            drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
+          }
+          ctx.restore();
+        }
+
+        // draw donut hole
+
+        drawDonutHole(ctx);
+
+        ctx.restore();
+
+        // Draw the labels, returning true if they fit within the plot
+
+        if (options.series.pie.label.show) {
+          return drawLabels();
+        } else return true;
+
+        function drawSlice(angle, color, fill) {
+
+          if (angle <= 0 || isNaN(angle)) {
+            return;
+          }
+
+          if (fill) {
+            ctx.fillStyle = color;
+          } else {
+            ctx.strokeStyle = color;
+            ctx.lineJoin = "round";
+          }
+
+          ctx.beginPath();
+          if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
+            ctx.moveTo(0, 0); // Center of the pie
+          }
+
+          //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
+          ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
+          ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
+          ctx.closePath();
+          //ctx.rotate(angle); // This doesn't work properly in Opera
+          currentAngle += angle;
+
+          if (fill) {
+            ctx.fill();
+          } else {
+            ctx.stroke();
+          }
+        }
+
+        function drawLabels() {
+
+          var currentAngle = startAngle;
+          var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
+
+          for (var i = 0; i < slices.length; ++i) {
+            if (slices[i].percent >= options.series.pie.label.threshold * 100) {
+              if (!drawLabel(slices[i], currentAngle, i)) {
+                return false;
+              }
+            }
+            currentAngle += slices[i].angle;
+          }
+
+          return true;
+
+          function drawLabel(slice, startAngle, index) {
+
+            if (slice.data[0][1] == 0) {
+              return true;
+            }
+
+            // format label text
+
+            var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
+
+            if (lf) {
+              text = lf(slice.label, slice);
+            } else {
+              text = slice.label;
+            }
+
+            if (plf) {
+              text = plf(text, slice);
+            }
+
+            var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
+            var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
+            var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
+
+            var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>";
+            target.append(html);
+
+            var label = target.children("#pieLabel" + index);
+            var labelTop = (y - label.height() / 2);
+            var labelLeft = (x - label.width() / 2);
+
+            label.css("top", labelTop);
+            label.css("left", labelLeft);
+
+            // check to make sure that the label is not outside the canvas
+
+            if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
+              return false;
+            }
+
+            if (options.series.pie.label.background.opacity != 0) {
+
+              // put in the transparent background separately to avoid blended labels and label boxes
+
+              var c = options.series.pie.label.background.color;
+
+              if (c == null) {
+                c = slice.color;
+              }
+
+              var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
+              $("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>")
+                  .css("opacity", options.series.pie.label.background.opacity)
+                  .insertBefore(label);
+            }
+
+            return true;
+          } // end individual label function
+        } // end drawLabels function
+      } // end drawPie function
+    } // end draw function
+
+    // Placed here because it needs to be accessed from multiple locations
+
+    function drawDonutHole(layer) {
+      if (options.series.pie.innerRadius > 0) {
+
+        // subtract the center
+
+        layer.save();
+        var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
+        layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
+        layer.beginPath();
+        layer.fillStyle = options.series.pie.stroke.color;
+        layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
+        layer.fill();
+        layer.closePath();
+        layer.restore();
+
+        // add inner stroke
+
+        layer.save();
+        layer.beginPath();
+        layer.strokeStyle = options.series.pie.stroke.color;
+        layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
+        layer.stroke();
+        layer.closePath();
+        layer.restore();
+
+        // TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
+      }
+    }
+
+    //-- Additional Interactive related functions --
+
+    function isPointInPoly(poly, pt) {
+      for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
+        ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
+        && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
+        && (c = !c);
+      return c;
+    }
+
+    function findNearbySlice(mouseX, mouseY) {
+
+      var slices = plot.getData(),
+          options = plot.getOptions(),
+          radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
+          x, y;
+
+      for (var i = 0; i < slices.length; ++i) {
+
+        var s = slices[i];
+
+        if (s.pie.show) {
+
+          ctx.save();
+          ctx.beginPath();
+          ctx.moveTo(0, 0); // Center of the pie
+          //ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.
+          ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
+          ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
+          ctx.closePath();
+          x = mouseX - centerLeft;
+          y = mouseY - centerTop;
+
+          if (ctx.isPointInPath) {
+            if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
+              ctx.restore();
+              return {
+                datapoint: [s.percent, s.data],
+                dataIndex: 0,
+                series: s,
+                seriesIndex: i
+              };
+            }
+          } else {
+
+            // excanvas for IE doesn;t support isPointInPath, this is a workaround.
+
+            var p1X = radius * Math.cos(s.startAngle),
+                p1Y = radius * Math.sin(s.startAngle),
+                p2X = radius * Math.cos(s.startAngle + s.angle / 4),
+                p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
+                p3X = radius * Math.cos(s.startAngle + s.angle / 2),
+                p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
+                p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
+                p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
+                p5X = radius * Math.cos(s.startAngle + s.angle),
+                p5Y = radius * Math.sin(s.startAngle + s.angle),
+                arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
+                arrPoint = [x, y];
+
+            // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
+
+            if (isPointInPoly(arrPoly, arrPoint)) {
+              ctx.restore();
+              return {
+                datapoint: [s.percent, s.data],
+                dataIndex: 0,
+                series: s,
+                seriesIndex: i
+              };
+            }
+          }
+
+          ctx.restore();
+        }
+      }
+
+      return null;
+    }
+
+    function onMouseMove(e) {
+      triggerClickHoverEvent("plothover", e);
+    }
+
+    function onClick(e) {
+      triggerClickHoverEvent("plotclick", e);
+    }
+
+    // trigger click or hover event (they send the same parameters so we share their code)
+
+    function triggerClickHoverEvent(eventname, e) {
+
+      var offset = plot.offset();
+      var canvasX = parseInt(e.pageX - offset.left);
+      var canvasY =  parseInt(e.pageY - offset.top);
+      var item = findNearbySlice(canvasX, canvasY);
+
+      if (options.grid.autoHighlight) {
+
+        // clear auto-highlights
+
+        for (var i = 0; i < highlights.length; ++i) {
+          var h = highlights[i];
+          if (h.auto == eventname && !(item && h.series == item.series)) {
+            unhighlight(h.series);
+          }
+        }
+      }
+
+      // highlight the slice
+
+      if (item) {
+        highlight(item.series, eventname);
+      }
+
+      // trigger any hover bind events
+
+      var pos = { pageX: e.pageX, pageY: e.pageY };
+      target.trigger(eventname, [pos, item]);
+    }
+
+    function highlight(s, auto) {
+      //if (typeof s == "number") {
+      //	s = series[s];
+      //}
+
+      var i = indexOfHighlight(s);
+
+      if (i == -1) {
+        highlights.push({ series: s, auto: auto });
+        plot.triggerRedrawOverlay();
+      } else if (!auto) {
+        highlights[i].auto = false;
+      }
+    }
+
+    function unhighlight(s) {
+      if (s == null) {
+        highlights = [];
+        plot.triggerRedrawOverlay();
+      }
+
+      //if (typeof s == "number") {
+      //	s = series[s];
+      //}
+
+      var i = indexOfHighlight(s);
+
+      if (i != -1) {
+        highlights.splice(i, 1);
+        plot.triggerRedrawOverlay();
+      }
+    }
+
+    function indexOfHighlight(s) {
+      for (var i = 0; i < highlights.length; ++i) {
+        var h = highlights[i];
+        if (h.series == s)
+          return i;
+      }
+      return -1;
+    }
+
+    function drawOverlay(plot, octx) {
+
+      var options = plot.getOptions();
+
+      var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
+
+      octx.save();
+      octx.translate(centerLeft, centerTop);
+      octx.scale(1, options.series.pie.tilt);
+
+      for (var i = 0; i < highlights.length; ++i) {
+        drawHighlight(highlights[i].series);
+      }
+
+      drawDonutHole(octx);
+
+      octx.restore();
+
+      function drawHighlight(series) {
+
+        if (series.angle <= 0 || isNaN(series.angle)) {
+          return;
+        }
+
+        //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
+        octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
+        octx.beginPath();
+        if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
+          octx.moveTo(0, 0); // Center of the pie
+        }
+        octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
+        octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
+        octx.closePath();
+        octx.fill();
+      }
+    }
+  } // end init (plugin body)
+
+  // define pie specific options and their default values
+
+  var options = {
+    series: {
+      pie: {
+        show: false,
+        radius: "auto",	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
+        innerRadius: 0, /* for donut */
+        startAngle: 3/2,
+        tilt: 1,
+        shadow: {
+          left: 5,	// shadow left offset
+          top: 15,	// shadow top offset
+          alpha: 0.02	// shadow alpha
+        },
+        offset: {
+          top: 0,
+          left: "auto"
+        },
+        stroke: {
+          color: "#fff",
+          width: 1
+        },
+        label: {
+          show: "auto",
+          formatter: function(label, slice) {
+            return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>";
+          },	// formatter function
+          radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
+          background: {
+            color: null,
+            opacity: 0
+          },
+          threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)
+        },
+        combine: {
+          threshold: -1,	// percentage at which to combine little slices into one larger slice
+          color: null,	// color to give the new slice (auto-generated if null)
+          label: "Other"	// label to give the new slice
+        },
+        highlight: {
+          //color: "#fff",		// will add this functionality once parseColor is available
+          opacity: 0.5
+        }
+      }
+    }
+  };
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: "pie",
+    version: "1.1"
+  });
+
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.resize.js b/ui/lib/flot/jquery.flot.resize.js
index 69dfb24..b9d9c44 100644
--- a/ui/lib/flot/jquery.flot.resize.js
+++ b/ui/lib/flot/jquery.flot.resize.js
@@ -1,60 +1,59 @@
-/*
-Flot plugin for automatically redrawing plots when the placeholder
-size changes, e.g. on window resizes.
+/* Flot plugin for automatically redrawing plots as the placeholder resizes.
 
-It works by listening for changes on the placeholder div (through the
-jQuery resize event plugin) - if the size changes, it will redraw the
-plot.
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-There are no options. If you need to disable the plugin for some
-plots, you can just fix the size of their placeholders.
+It works by listening for changes on the placeholder div (through the jQuery
+resize event plugin) - if the size changes, it will redraw the plot.
+
+There are no options. If you need to disable the plugin for some plots, you
+can just fix the size of their placeholders.
+
 */
 
-
-/* Inline dependency: 
+/* Inline dependency:
  * jQuery resize event - v1.1 - 3/14/2010
  * http://benalman.com/projects/jquery-resize-plugin/
- * 
+ *
  * Copyright (c) 2010 "Cowboy" Ben Alman
  * Dual licensed under the MIT and GPL licenses.
  * http://benalman.com/about/license/
  */
-(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
-
+(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
 
 (function ($) {
-    var options = { }; // no options
+  var options = { }; // no options
 
-    function init(plot) {
-        function onResize() {
-            var placeholder = plot.getPlaceholder();
+  function init(plot) {
+    function onResize() {
+      var placeholder = plot.getPlaceholder();
 
-            // somebody might have hidden us and we can't plot
-            // when we don't have the dimensions
-            if (placeholder.width() == 0 || placeholder.height() == 0)
-                return;
+      // somebody might have hidden us and we can't plot
+      // when we don't have the dimensions
+      if (placeholder.width() == 0 || placeholder.height() == 0)
+        return;
 
-            plot.resize();
-            plot.setupGrid();
-            plot.draw();
-        }
-        
-        function bindEvents(plot, eventHolder) {
-            plot.getPlaceholder().resize(onResize);
-        }
-
-        function shutdown(plot, eventHolder) {
-            plot.getPlaceholder().unbind("resize", onResize);
-        }
-        
-        plot.hooks.bindEvents.push(bindEvents);
-        plot.hooks.shutdown.push(shutdown);
+      plot.resize();
+      plot.setupGrid();
+      plot.draw();
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'resize',
-        version: '1.0'
-    });
+
+    function bindEvents(plot, eventHolder) {
+      plot.getPlaceholder().resize(onResize);
+    }
+
+    function shutdown(plot, eventHolder) {
+      plot.getPlaceholder().unbind("resize", onResize);
+    }
+
+    plot.hooks.bindEvents.push(bindEvents);
+    plot.hooks.shutdown.push(shutdown);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'resize',
+    version: '1.0'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.selection.js b/ui/lib/flot/jquery.flot.selection.js
index 7f7b326..2608dd7 100644
--- a/ui/lib/flot/jquery.flot.selection.js
+++ b/ui/lib/flot/jquery.flot.selection.js
@@ -1,344 +1,360 @@
-/*
-Flot plugin for selecting regions.
+/* Flot plugin for selecting regions of a plot.
 
-The plugin defines the following options:
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-  selection: {
-    mode: null or "x" or "y" or "xy",
-    color: color
-  }
+The plugin supports these options:
 
-Selection support is enabled by setting the mode to one of "x", "y" or
-"xy". In "x" mode, the user will only be able to specify the x range,
-similarly for "y" mode. For "xy", the selection becomes a rectangle
-where both ranges can be specified. "color" is color of the selection
-(if you need to change the color later on, you can get to it with
-plot.getOptions().selection.color).
+selection: {
+	mode: null or "x" or "y" or "xy",
+	color: color,
+	shape: "round" or "miter" or "bevel",
+	minSize: number of pixels
+}
 
-When selection support is enabled, a "plotselected" event will be
-emitted on the DOM element you passed into the plot function. The
-event handler gets a parameter with the ranges selected on the axes,
-like this:
+Selection support is enabled by setting the mode to one of "x", "y" or "xy".
+In "x" mode, the user will only be able to specify the x range, similarly for
+"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
+specified. "color" is color of the selection (if you need to change the color
+later on, you can get to it with plot.getOptions().selection.color). "shape"
+is the shape of the corners of the selection.
 
-  placeholder.bind("plotselected", function(event, ranges) {
-    alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
-    // similar for yaxis - with multiple axes, the extra ones are in
-    // x2axis, x3axis, ...
-  });
+"minSize" is the minimum size a selection can be in pixels. This value can
+be customized to determine the smallest size a selection can be and still
+have the selection rectangle be displayed. When customizing this value, the
+fact that it refers to pixels, not axis units must be taken into account.
+Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
+minute, setting "minSize" to 1 will not make the minimum selection size 1
+minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
+"plotunselected" events from being fired when the user clicks the mouse without
+dragging.
 
-The "plotselected" event is only fired when the user has finished
-making the selection. A "plotselecting" event is fired during the
-process with the same parameters as the "plotselected" event, in case
-you want to know what's happening while it's happening,
+When selection support is enabled, a "plotselected" event will be emitted on
+the DOM element you passed into the plot function. The event handler gets a
+parameter with the ranges selected on the axes, like this:
 
-A "plotunselected" event with no arguments is emitted when the user
-clicks the mouse to remove the selection.
+	placeholder.bind( "plotselected", function( event, ranges ) {
+		alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
+		// similar for yaxis - with multiple axes, the extra ones are in
+		// x2axis, x3axis, ...
+	});
+
+The "plotselected" event is only fired when the user has finished making the
+selection. A "plotselecting" event is fired during the process with the same
+parameters as the "plotselected" event, in case you want to know what's
+happening while it's happening,
+
+A "plotunselected" event with no arguments is emitted when the user clicks the
+mouse to remove the selection. As stated above, setting "minSize" to 0 will
+destroy this behavior.
 
 The plugin allso adds the following methods to the plot object:
 
-- setSelection(ranges, preventEvent)
+- setSelection( ranges, preventEvent )
 
-  Set the selection rectangle. The passed in ranges is on the same
-  form as returned in the "plotselected" event. If the selection mode
-  is "x", you should put in either an xaxis range, if the mode is "y"
-  you need to put in an yaxis range and both xaxis and yaxis if the
-  selection mode is "xy", like this:
+  Set the selection rectangle. The passed in ranges is on the same form as
+  returned in the "plotselected" event. If the selection mode is "x", you
+  should put in either an xaxis range, if the mode is "y" you need to put in
+  an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
+  this:
 
-    setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
+	setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
 
-  setSelection will trigger the "plotselected" event when called. If
-  you don't want that to happen, e.g. if you're inside a
-  "plotselected" handler, pass true as the second parameter. If you
-  are using multiple axes, you can specify the ranges on any of those,
-  e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the
-  first one it sees.
-  
-- clearSelection(preventEvent)
+  setSelection will trigger the "plotselected" event when called. If you don't
+  want that to happen, e.g. if you're inside a "plotselected" handler, pass
+  true as the second parameter. If you are using multiple axes, you can
+  specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
+  xaxis, the plugin picks the first one it sees.
+
+- clearSelection( preventEvent )
 
   Clear the selection rectangle. Pass in true to avoid getting a
   "plotunselected" event.
 
 - getSelection()
 
-  Returns the current selection in the same format as the
-  "plotselected" event. If there's currently no selection, the
-  function returns null.
+  Returns the current selection in the same format as the "plotselected"
+  event. If there's currently no selection, the function returns null.
 
 */
 
 (function ($) {
-    function init(plot) {
-        var selection = {
-                first: { x: -1, y: -1}, second: { x: -1, y: -1},
-                show: false,
-                active: false
-            };
+  function init(plot) {
+    var selection = {
+      first: { x: -1, y: -1}, second: { x: -1, y: -1},
+      show: false,
+      active: false
+    };
 
-        // FIXME: The drag handling implemented here should be
-        // abstracted out, there's some similar code from a library in
-        // the navigation plugin, this should be massaged a bit to fit
-        // the Flot cases here better and reused. Doing this would
-        // make this plugin much slimmer.
-        var savedhandlers = {};
+    // FIXME: The drag handling implemented here should be
+    // abstracted out, there's some similar code from a library in
+    // the navigation plugin, this should be massaged a bit to fit
+    // the Flot cases here better and reused. Doing this would
+    // make this plugin much slimmer.
+    var savedhandlers = {};
 
-        var mouseUpHandler = null;
-        
-        function onMouseMove(e) {
-            if (selection.active) {
-                updateSelection(e);
-                
-                plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
-            }
-        }
+    var mouseUpHandler = null;
 
-        function onMouseDown(e) {
-            if (e.which != 1)  // only accept left-click
-                return;
-            
-            // cancel out any text selections
-            document.body.focus();
+    function onMouseMove(e) {
+      if (selection.active) {
+        updateSelection(e);
 
-            // prevent text selection and drag in old-school browsers
-            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
-                savedhandlers.onselectstart = document.onselectstart;
-                document.onselectstart = function () { return false; };
-            }
-            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
-                savedhandlers.ondrag = document.ondrag;
-                document.ondrag = function () { return false; };
-            }
-
-            setSelectionPos(selection.first, e);
-
-            selection.active = true;
-
-            // this is a bit silly, but we have to use a closure to be
-            // able to whack the same handler again
-            mouseUpHandler = function (e) { onMouseUp(e); };
-            
-            $(document).one("mouseup", mouseUpHandler);
-        }
-
-        function onMouseUp(e) {
-            mouseUpHandler = null;
-            
-            // revert drag stuff for old-school browsers
-            if (document.onselectstart !== undefined)
-                document.onselectstart = savedhandlers.onselectstart;
-            if (document.ondrag !== undefined)
-                document.ondrag = savedhandlers.ondrag;
-
-            // no more dragging
-            selection.active = false;
-            updateSelection(e);
-
-            if (selectionIsSane())
-                triggerSelectedEvent();
-            else {
-                // this counts as a clear
-                plot.getPlaceholder().trigger("plotunselected", [ ]);
-                plot.getPlaceholder().trigger("plotselecting", [ null ]);
-            }
-
-            return false;
-        }
-
-        function getSelection() {
-            if (!selectionIsSane())
-                return null;
-
-            var r = {}, c1 = selection.first, c2 = selection.second;
-            $.each(plot.getAxes(), function (name, axis) {
-                if (axis.used) {
-                    var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); 
-                    r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
-                }
-            });
-            return r;
-        }
-
-        function triggerSelectedEvent() {
-            var r = getSelection();
-
-            plot.getPlaceholder().trigger("plotselected", [ r ]);
-
-            // backwards-compat stuff, to be removed in future
-            if (r.xaxis && r.yaxis)
-                plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
-        }
-
-        function clamp(min, value, max) {
-            return value < min ? min: (value > max ? max: value);
-        }
-
-        function setSelectionPos(pos, e) {
-            var o = plot.getOptions();
-            var offset = plot.getPlaceholder().offset();
-            var plotOffset = plot.getPlotOffset();
-            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
-            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
-
-            if (o.selection.mode == "y")
-                pos.x = pos == selection.first ? 0 : plot.width();
-
-            if (o.selection.mode == "x")
-                pos.y = pos == selection.first ? 0 : plot.height();
-        }
-
-        function updateSelection(pos) {
-            if (pos.pageX == null)
-                return;
-
-            setSelectionPos(selection.second, pos);
-            if (selectionIsSane()) {
-                selection.show = true;
-                plot.triggerRedrawOverlay();
-            }
-            else
-                clearSelection(true);
-        }
-
-        function clearSelection(preventEvent) {
-            if (selection.show) {
-                selection.show = false;
-                plot.triggerRedrawOverlay();
-                if (!preventEvent)
-                    plot.getPlaceholder().trigger("plotunselected", [ ]);
-            }
-        }
-
-        // function taken from markings support in Flot
-        function extractRange(ranges, coord) {
-            var axis, from, to, key, axes = plot.getAxes();
-
-            for (var k in axes) {
-                axis = axes[k];
-                if (axis.direction == coord) {
-                    key = coord + axis.n + "axis";
-                    if (!ranges[key] && axis.n == 1)
-                        key = coord + "axis"; // support x1axis as xaxis
-                    if (ranges[key]) {
-                        from = ranges[key].from;
-                        to = ranges[key].to;
-                        break;
-                    }
-                }
-            }
-
-            // backwards-compat stuff - to be removed in future
-            if (!ranges[key]) {
-                axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
-                from = ranges[coord + "1"];
-                to = ranges[coord + "2"];
-            }
-
-            // auto-reverse as an added bonus
-            if (from != null && to != null && from > to) {
-                var tmp = from;
-                from = to;
-                to = tmp;
-            }
-            
-            return { from: from, to: to, axis: axis };
-        }
-        
-        function setSelection(ranges, preventEvent) {
-            var axis, range, o = plot.getOptions();
-
-            if (o.selection.mode == "y") {
-                selection.first.x = 0;
-                selection.second.x = plot.width();
-            }
-            else {
-                range = extractRange(ranges, "x");
-
-                selection.first.x = range.axis.p2c(range.from);
-                selection.second.x = range.axis.p2c(range.to);
-            }
-
-            if (o.selection.mode == "x") {
-                selection.first.y = 0;
-                selection.second.y = plot.height();
-            }
-            else {
-                range = extractRange(ranges, "y");
-
-                selection.first.y = range.axis.p2c(range.from);
-                selection.second.y = range.axis.p2c(range.to);
-            }
-
-            selection.show = true;
-            plot.triggerRedrawOverlay();
-            if (!preventEvent && selectionIsSane())
-                triggerSelectedEvent();
-        }
-
-        function selectionIsSane() {
-            var minSize = 5;
-            return Math.abs(selection.second.x - selection.first.x) >= minSize &&
-                Math.abs(selection.second.y - selection.first.y) >= minSize;
-        }
-
-        plot.clearSelection = clearSelection;
-        plot.setSelection = setSelection;
-        plot.getSelection = getSelection;
-
-        plot.hooks.bindEvents.push(function(plot, eventHolder) {
-            var o = plot.getOptions();
-            if (o.selection.mode != null) {
-                eventHolder.mousemove(onMouseMove);
-                eventHolder.mousedown(onMouseDown);
-            }
-        });
-
-
-        plot.hooks.drawOverlay.push(function (plot, ctx) {
-            // draw selection
-            if (selection.show && selectionIsSane()) {
-                var plotOffset = plot.getPlotOffset();
-                var o = plot.getOptions();
-
-                ctx.save();
-                ctx.translate(plotOffset.left, plotOffset.top);
-
-                var c = $.color.parse(o.selection.color);
-
-                ctx.strokeStyle = c.scale('a', 0.8).toString();
-                ctx.lineWidth = 1;
-                ctx.lineJoin = "round";
-                ctx.fillStyle = c.scale('a', 0.4).toString();
-
-                var x = Math.min(selection.first.x, selection.second.x),
-                    y = Math.min(selection.first.y, selection.second.y),
-                    w = Math.abs(selection.second.x - selection.first.x),
-                    h = Math.abs(selection.second.y - selection.first.y);
-
-                ctx.fillRect(x, y, w, h);
-                ctx.strokeRect(x, y, w, h);
-
-                ctx.restore();
-            }
-        });
-        
-        plot.hooks.shutdown.push(function (plot, eventHolder) {
-            eventHolder.unbind("mousemove", onMouseMove);
-            eventHolder.unbind("mousedown", onMouseDown);
-            
-            if (mouseUpHandler)
-                $(document).unbind("mouseup", mouseUpHandler);
-        });
-
+        plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
+      }
     }
 
-    $.plot.plugins.push({
-        init: init,
-        options: {
-            selection: {
-                mode: null, // one of null, "x", "y" or "xy"
-                color: "#e8cfac"
-            }
-        },
-        name: 'selection',
-        version: '1.1'
+    function onMouseDown(e) {
+      if (e.which != 1)  // only accept left-click
+        return;
+
+      // cancel out any text selections
+      document.body.focus();
+
+      // prevent text selection and drag in old-school browsers
+      if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
+        savedhandlers.onselectstart = document.onselectstart;
+        document.onselectstart = function () { return false; };
+      }
+      if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
+        savedhandlers.ondrag = document.ondrag;
+        document.ondrag = function () { return false; };
+      }
+
+      setSelectionPos(selection.first, e);
+
+      selection.active = true;
+
+      // this is a bit silly, but we have to use a closure to be
+      // able to whack the same handler again
+      mouseUpHandler = function (e) { onMouseUp(e); };
+
+      $(document).one("mouseup", mouseUpHandler);
+    }
+
+    function onMouseUp(e) {
+      mouseUpHandler = null;
+
+      // revert drag stuff for old-school browsers
+      if (document.onselectstart !== undefined)
+        document.onselectstart = savedhandlers.onselectstart;
+      if (document.ondrag !== undefined)
+        document.ondrag = savedhandlers.ondrag;
+
+      // no more dragging
+      selection.active = false;
+      updateSelection(e);
+
+      if (selectionIsSane())
+        triggerSelectedEvent();
+      else {
+        // this counts as a clear
+        plot.getPlaceholder().trigger("plotunselected", [ ]);
+        plot.getPlaceholder().trigger("plotselecting", [ null ]);
+      }
+
+      return false;
+    }
+
+    function getSelection() {
+      if (!selectionIsSane())
+        return null;
+
+      if (!selection.show) return null;
+
+      var r = {}, c1 = selection.first, c2 = selection.second;
+      $.each(plot.getAxes(), function (name, axis) {
+        if (axis.used) {
+          var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
+          r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
+        }
+      });
+      return r;
+    }
+
+    function triggerSelectedEvent() {
+      var r = getSelection();
+
+      plot.getPlaceholder().trigger("plotselected", [ r ]);
+
+      // backwards-compat stuff, to be removed in future
+      if (r.xaxis && r.yaxis)
+        plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
+    }
+
+    function clamp(min, value, max) {
+      return value < min ? min: (value > max ? max: value);
+    }
+
+    function setSelectionPos(pos, e) {
+      var o = plot.getOptions();
+      var offset = plot.getPlaceholder().offset();
+      var plotOffset = plot.getPlotOffset();
+      pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
+      pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
+
+      if (o.selection.mode == "y")
+        pos.x = pos == selection.first ? 0 : plot.width();
+
+      if (o.selection.mode == "x")
+        pos.y = pos == selection.first ? 0 : plot.height();
+    }
+
+    function updateSelection(pos) {
+      if (pos.pageX == null)
+        return;
+
+      setSelectionPos(selection.second, pos);
+      if (selectionIsSane()) {
+        selection.show = true;
+        plot.triggerRedrawOverlay();
+      }
+      else
+        clearSelection(true);
+    }
+
+    function clearSelection(preventEvent) {
+      if (selection.show) {
+        selection.show = false;
+        plot.triggerRedrawOverlay();
+        if (!preventEvent)
+          plot.getPlaceholder().trigger("plotunselected", [ ]);
+      }
+    }
+
+    // function taken from markings support in Flot
+    function extractRange(ranges, coord) {
+      var axis, from, to, key, axes = plot.getAxes();
+
+      for (var k in axes) {
+        axis = axes[k];
+        if (axis.direction == coord) {
+          key = coord + axis.n + "axis";
+          if (!ranges[key] && axis.n == 1)
+            key = coord + "axis"; // support x1axis as xaxis
+          if (ranges[key]) {
+            from = ranges[key].from;
+            to = ranges[key].to;
+            break;
+          }
+        }
+      }
+
+      // backwards-compat stuff - to be removed in future
+      if (!ranges[key]) {
+        axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
+        from = ranges[coord + "1"];
+        to = ranges[coord + "2"];
+      }
+
+      // auto-reverse as an added bonus
+      if (from != null && to != null && from > to) {
+        var tmp = from;
+        from = to;
+        to = tmp;
+      }
+
+      return { from: from, to: to, axis: axis };
+    }
+
+    function setSelection(ranges, preventEvent) {
+      var axis, range, o = plot.getOptions();
+
+      if (o.selection.mode == "y") {
+        selection.first.x = 0;
+        selection.second.x = plot.width();
+      }
+      else {
+        range = extractRange(ranges, "x");
+
+        selection.first.x = range.axis.p2c(range.from);
+        selection.second.x = range.axis.p2c(range.to);
+      }
+
+      if (o.selection.mode == "x") {
+        selection.first.y = 0;
+        selection.second.y = plot.height();
+      }
+      else {
+        range = extractRange(ranges, "y");
+
+        selection.first.y = range.axis.p2c(range.from);
+        selection.second.y = range.axis.p2c(range.to);
+      }
+
+      selection.show = true;
+      plot.triggerRedrawOverlay();
+      if (!preventEvent && selectionIsSane())
+        triggerSelectedEvent();
+    }
+
+    function selectionIsSane() {
+      var minSize = plot.getOptions().selection.minSize;
+      return Math.abs(selection.second.x - selection.first.x) >= minSize &&
+          Math.abs(selection.second.y - selection.first.y) >= minSize;
+    }
+
+    plot.clearSelection = clearSelection;
+    plot.setSelection = setSelection;
+    plot.getSelection = getSelection;
+
+    plot.hooks.bindEvents.push(function(plot, eventHolder) {
+      var o = plot.getOptions();
+      if (o.selection.mode != null) {
+        eventHolder.mousemove(onMouseMove);
+        eventHolder.mousedown(onMouseDown);
+      }
     });
+
+
+    plot.hooks.drawOverlay.push(function (plot, ctx) {
+      // draw selection
+      if (selection.show && selectionIsSane()) {
+        var plotOffset = plot.getPlotOffset();
+        var o = plot.getOptions();
+
+        ctx.save();
+        ctx.translate(plotOffset.left, plotOffset.top);
+
+        var c = $.color.parse(o.selection.color);
+
+        ctx.strokeStyle = c.scale('a', 0.8).toString();
+        ctx.lineWidth = 1;
+        ctx.lineJoin = o.selection.shape;
+        ctx.fillStyle = c.scale('a', 0.4).toString();
+
+        var x = Math.min(selection.first.x, selection.second.x) + 0.5,
+            y = Math.min(selection.first.y, selection.second.y) + 0.5,
+            w = Math.abs(selection.second.x - selection.first.x) - 1,
+            h = Math.abs(selection.second.y - selection.first.y) - 1;
+
+        ctx.fillRect(x, y, w, h);
+        ctx.strokeRect(x, y, w, h);
+
+        ctx.restore();
+      }
+    });
+
+    plot.hooks.shutdown.push(function (plot, eventHolder) {
+      eventHolder.unbind("mousemove", onMouseMove);
+      eventHolder.unbind("mousedown", onMouseDown);
+
+      if (mouseUpHandler)
+        $(document).unbind("mouseup", mouseUpHandler);
+    });
+
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: {
+      selection: {
+        mode: null, // one of null, "x", "y" or "xy"
+        color: "#e8cfac",
+        shape: "round", // one of "round", "miter", or "bevel"
+        minSize: 5 // minimum number of pixels
+      }
+    },
+    name: 'selection',
+    version: '1.1'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.stack.js b/ui/lib/flot/jquery.flot.stack.js
index a31d5dc..08e6052 100644
--- a/ui/lib/flot/jquery.flot.stack.js
+++ b/ui/lib/flot/jquery.flot.stack.js
@@ -1,184 +1,188 @@
-/*
-Flot plugin for stacking data sets, i.e. putting them on top of each
-other, for accumulative graphs.
+/* Flot plugin for stacking data sets rather than overlyaing them.
 
-The plugin assumes the data is sorted on x (or y if stacking
-horizontally). For line charts, it is assumed that if a line has an
-undefined gap (from a null point), then the line above it should have
-the same gap - insert zeros instead of "null" if you want another
-behaviour. This also holds for the start and end of the chart. Note
-that stacking a mix of positive and negative values in most instances
-doesn't make sense (so it looks weird).
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-Two or more series are stacked when their "stack" attribute is set to
-the same key (which can be any number or string or just "true"). To
-specify the default stack, you can set
+The plugin assumes the data is sorted on x (or y if stacking horizontally).
+For line charts, it is assumed that if a line has an undefined gap (from a
+null point), then the line above it should have the same gap - insert zeros
+instead of "null" if you want another behaviour. This also holds for the start
+and end of the chart. Note that stacking a mix of positive and negative values
+in most instances doesn't make sense (so it looks weird).
 
-  series: {
-    stack: null or true or key (number/string)
-  }
+Two or more series are stacked when their "stack" attribute is set to the same
+key (which can be any number or string or just "true"). To specify the default
+stack, you can set the stack option like this:
 
-or specify it for a specific series
+	series: {
+		stack: null/false, true, or a key (number/string)
+	}
 
-  $.plot($("#placeholder"), [{ data: [ ... ], stack: true }])
-  
-The stacking order is determined by the order of the data series in
-the array (later series end up on top of the previous).
+You can also specify it for a single series, like this:
 
-Internally, the plugin modifies the datapoints in each series, adding
-an offset to the y value. For line series, extra data points are
-inserted through interpolation. If there's a second y value, it's also
-adjusted (e.g for bar charts or filled areas).
+	$.plot( $("#placeholder"), [{
+		data: [ ... ],
+		stack: true
+	}])
+
+The stacking order is determined by the order of the data series in the array
+(later series end up on top of the previous).
+
+Internally, the plugin modifies the datapoints in each series, adding an
+offset to the y value. For line series, extra data points are inserted through
+interpolation. If there's a second y value, it's also adjusted (e.g for bar
+charts or filled areas).
+
 */
 
 (function ($) {
-    var options = {
-        series: { stack: null } // or number/string
-    };
-    
-    function init(plot) {
-        function findMatchingSeries(s, allseries) {
-            var res = null
-            for (var i = 0; i < allseries.length; ++i) {
-                if (s == allseries[i])
-                    break;
-                
-                if (allseries[i].stack == s.stack)
-                    res = allseries[i];
-            }
-            
-            return res;
-        }
-        
-        function stackData(plot, s, datapoints) {
-            if (s.stack == null)
-                return;
+  var options = {
+    series: { stack: null } // or number/string
+  };
 
-            var other = findMatchingSeries(s, plot.getData());
-            if (!other)
-                return;
+  function init(plot) {
+    function findMatchingSeries(s, allseries) {
+      var res = null;
+      for (var i = 0; i < allseries.length; ++i) {
+        if (s == allseries[i])
+          break;
 
-            var ps = datapoints.pointsize,
-                points = datapoints.points,
-                otherps = other.datapoints.pointsize,
-                otherpoints = other.datapoints.points,
-                newpoints = [],
-                px, py, intery, qx, qy, bottom,
-                withlines = s.lines.show,
-                horizontal = s.bars.horizontal,
-                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
-                withsteps = withlines && s.lines.steps,
-                fromgap = true,
-                keyOffset = horizontal ? 1 : 0,
-                accumulateOffset = horizontal ? 0 : 1,
-                i = 0, j = 0, l;
+        if (allseries[i].stack == s.stack)
+          res = allseries[i];
+      }
 
-            while (true) {
-                if (i >= points.length)
-                    break;
-
-                l = newpoints.length;
-
-                if (points[i] == null) {
-                    // copy gaps
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(points[i + m]);
-                    i += ps;
-                }
-                else if (j >= otherpoints.length) {
-                    // for lines, we can't use the rest of the points
-                    if (!withlines) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                    }
-                    i += ps;
-                }
-                else if (otherpoints[j] == null) {
-                    // oops, got a gap
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(null);
-                    fromgap = true;
-                    j += otherps;
-                }
-                else {
-                    // cases where we actually got two points
-                    px = points[i + keyOffset];
-                    py = points[i + accumulateOffset];
-                    qx = otherpoints[j + keyOffset];
-                    qy = otherpoints[j + accumulateOffset];
-                    bottom = 0;
-
-                    if (px == qx) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-
-                        newpoints[l + accumulateOffset] += qy;
-                        bottom = qy;
-                        
-                        i += ps;
-                        j += otherps;
-                    }
-                    else if (px > qx) {
-                        // we got past point below, might need to
-                        // insert interpolated extra point
-                        if (withlines && i > 0 && points[i - ps] != null) {
-                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
-                            newpoints.push(qx);
-                            newpoints.push(intery + qy);
-                            for (m = 2; m < ps; ++m)
-                                newpoints.push(points[i + m]);
-                            bottom = qy; 
-                        }
-
-                        j += otherps;
-                    }
-                    else { // px < qx
-                        if (fromgap && withlines) {
-                            // if we come from a gap, we just skip this point
-                            i += ps;
-                            continue;
-                        }
-                            
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                        
-                        // we might be able to interpolate a point below,
-                        // this can give us a better y
-                        if (withlines && j > 0 && otherpoints[j - otherps] != null)
-                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
-
-                        newpoints[l + accumulateOffset] += bottom;
-                        
-                        i += ps;
-                    }
-
-                    fromgap = false;
-                    
-                    if (l != newpoints.length && withbottom)
-                        newpoints[l + 2] += bottom;
-                }
-
-                // maintain the line steps invariant
-                if (withsteps && l != newpoints.length && l > 0
-                    && newpoints[l] != null
-                    && newpoints[l] != newpoints[l - ps]
-                    && newpoints[l + 1] != newpoints[l - ps + 1]) {
-                    for (m = 0; m < ps; ++m)
-                        newpoints[l + ps + m] = newpoints[l + m];
-                    newpoints[l + 1] = newpoints[l - ps + 1];
-                }
-            }
-
-            datapoints.points = newpoints;
-        }
-        
-        plot.hooks.processDatapoints.push(stackData);
+      return res;
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'stack',
-        version: '1.2'
-    });
+
+    function stackData(plot, s, datapoints) {
+      if (s.stack == null || s.stack === false)
+        return;
+
+      var other = findMatchingSeries(s, plot.getData());
+      if (!other)
+        return;
+
+      var ps = datapoints.pointsize,
+          points = datapoints.points,
+          otherps = other.datapoints.pointsize,
+          otherpoints = other.datapoints.points,
+          newpoints = [],
+          px, py, intery, qx, qy, bottom,
+          withlines = s.lines.show,
+          horizontal = s.bars.horizontal,
+          withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
+          withsteps = withlines && s.lines.steps,
+          fromgap = true,
+          keyOffset = horizontal ? 1 : 0,
+          accumulateOffset = horizontal ? 0 : 1,
+          i = 0, j = 0, l, m;
+
+      while (true) {
+        if (i >= points.length)
+          break;
+
+        l = newpoints.length;
+
+        if (points[i] == null) {
+          // copy gaps
+          for (m = 0; m < ps; ++m)
+            newpoints.push(points[i + m]);
+          i += ps;
+        }
+        else if (j >= otherpoints.length) {
+          // for lines, we can't use the rest of the points
+          if (!withlines) {
+            for (m = 0; m < ps; ++m)
+              newpoints.push(points[i + m]);
+          }
+          i += ps;
+        }
+        else if (otherpoints[j] == null) {
+          // oops, got a gap
+          for (m = 0; m < ps; ++m)
+            newpoints.push(null);
+          fromgap = true;
+          j += otherps;
+        }
+        else {
+          // cases where we actually got two points
+          px = points[i + keyOffset];
+          py = points[i + accumulateOffset];
+          qx = otherpoints[j + keyOffset];
+          qy = otherpoints[j + accumulateOffset];
+          bottom = 0;
+
+          if (px == qx) {
+            for (m = 0; m < ps; ++m)
+              newpoints.push(points[i + m]);
+
+            newpoints[l + accumulateOffset] += qy;
+            bottom = qy;
+
+            i += ps;
+            j += otherps;
+          }
+          else if (px > qx) {
+            // we got past point below, might need to
+            // insert interpolated extra point
+            if (withlines && i > 0 && points[i - ps] != null) {
+              intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
+              newpoints.push(qx);
+              newpoints.push(intery + qy);
+              for (m = 2; m < ps; ++m)
+                newpoints.push(points[i + m]);
+              bottom = qy;
+            }
+
+            j += otherps;
+          }
+          else { // px < qx
+            if (fromgap && withlines) {
+              // if we come from a gap, we just skip this point
+              i += ps;
+              continue;
+            }
+
+            for (m = 0; m < ps; ++m)
+              newpoints.push(points[i + m]);
+
+            // we might be able to interpolate a point below,
+            // this can give us a better y
+            if (withlines && j > 0 && otherpoints[j - otherps] != null)
+              bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
+
+            newpoints[l + accumulateOffset] += bottom;
+
+            i += ps;
+          }
+
+          fromgap = false;
+
+          if (l != newpoints.length && withbottom)
+            newpoints[l + 2] += bottom;
+        }
+
+        // maintain the line steps invariant
+        if (withsteps && l != newpoints.length && l > 0
+            && newpoints[l] != null
+            && newpoints[l] != newpoints[l - ps]
+            && newpoints[l + 1] != newpoints[l - ps + 1]) {
+          for (m = 0; m < ps; ++m)
+            newpoints[l + ps + m] = newpoints[l + m];
+          newpoints[l + 1] = newpoints[l - ps + 1];
+        }
+      }
+
+      datapoints.points = newpoints;
+    }
+
+    plot.hooks.processDatapoints.push(stackData);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'stack',
+    version: '1.2'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.symbol.js b/ui/lib/flot/jquery.flot.symbol.js
index a32fe31..f6a1f2d 100644
--- a/ui/lib/flot/jquery.flot.symbol.js
+++ b/ui/lib/flot/jquery.flot.symbol.js
@@ -1,70 +1,71 @@
-/*
-Flot plugin that adds some extra symbols for plotting points.
+/* Flot plugin that adds some extra symbols for plotting points.
 
-The symbols are accessed as strings through the standard symbol
-choice:
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-  series: {
-      points: {
-          symbol: "square" // or "diamond", "triangle", "cross"
-      }
-  }
+The symbols are accessed as strings through the standard symbol options:
+
+	series: {
+		points: {
+			symbol: "square" // or "diamond", "triangle", "cross"
+		}
+	}
 
 */
 
 (function ($) {
-    function processRawData(plot, series, datapoints) {
-        // we normalize the area of each symbol so it is approximately the
-        // same as a circle of the given radius
+  function processRawData(plot, series, datapoints) {
+    // we normalize the area of each symbol so it is approximately the
+    // same as a circle of the given radius
 
-        var handlers = {
-            square: function (ctx, x, y, radius, shadow) {
-                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
-                var size = radius * Math.sqrt(Math.PI) / 2;
-                ctx.rect(x - size, y - size, size + size, size + size);
-            },
-            diamond: function (ctx, x, y, radius, shadow) {
-                // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)
-                var size = radius * Math.sqrt(Math.PI / 2);
-                ctx.moveTo(x - size, y);
-                ctx.lineTo(x, y - size);
-                ctx.lineTo(x + size, y);
-                ctx.lineTo(x, y + size);
-                ctx.lineTo(x - size, y);
-            },
-            triangle: function (ctx, x, y, radius, shadow) {
-                // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))
-                var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
-                var height = size * Math.sin(Math.PI / 3);
-                ctx.moveTo(x - size/2, y + height/2);
-                ctx.lineTo(x + size/2, y + height/2);
-                if (!shadow) {
-                    ctx.lineTo(x, y - height/2);
-                    ctx.lineTo(x - size/2, y + height/2);
-                }
-            },
-            cross: function (ctx, x, y, radius, shadow) {
-                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
-                var size = radius * Math.sqrt(Math.PI) / 2;
-                ctx.moveTo(x - size, y - size);
-                ctx.lineTo(x + size, y + size);
-                ctx.moveTo(x - size, y + size);
-                ctx.lineTo(x + size, y - size);
-            }
+    var handlers = {
+      square: function (ctx, x, y, radius, shadow) {
+        // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
+        var size = radius * Math.sqrt(Math.PI) / 2;
+        ctx.rect(x - size, y - size, size + size, size + size);
+      },
+      diamond: function (ctx, x, y, radius, shadow) {
+        // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)
+        var size = radius * Math.sqrt(Math.PI / 2);
+        ctx.moveTo(x - size, y);
+        ctx.lineTo(x, y - size);
+        ctx.lineTo(x + size, y);
+        ctx.lineTo(x, y + size);
+        ctx.lineTo(x - size, y);
+      },
+      triangle: function (ctx, x, y, radius, shadow) {
+        // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))
+        var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
+        var height = size * Math.sin(Math.PI / 3);
+        ctx.moveTo(x - size/2, y + height/2);
+        ctx.lineTo(x + size/2, y + height/2);
+        if (!shadow) {
+          ctx.lineTo(x, y - height/2);
+          ctx.lineTo(x - size/2, y + height/2);
         }
+      },
+      cross: function (ctx, x, y, radius, shadow) {
+        // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
+        var size = radius * Math.sqrt(Math.PI) / 2;
+        ctx.moveTo(x - size, y - size);
+        ctx.lineTo(x + size, y + size);
+        ctx.moveTo(x - size, y + size);
+        ctx.lineTo(x + size, y - size);
+      }
+    };
 
-        var s = series.points.symbol;
-        if (handlers[s])
-            series.points.symbol = handlers[s];
-    }
-    
-    function init(plot) {
-        plot.hooks.processDatapoints.push(processRawData);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        name: 'symbols',
-        version: '1.0'
-    });
+    var s = series.points.symbol;
+    if (handlers[s])
+      series.points.symbol = handlers[s];
+  }
+
+  function init(plot) {
+    plot.hooks.processDatapoints.push(processRawData);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    name: 'symbols',
+    version: '1.0'
+  });
 })(jQuery);
diff --git a/ui/lib/flot/jquery.flot.threshold.js b/ui/lib/flot/jquery.flot.threshold.js
index 0b2e7ac..7e3b753 100644
--- a/ui/lib/flot/jquery.flot.threshold.js
+++ b/ui/lib/flot/jquery.flot.threshold.js
@@ -1,103 +1,142 @@
-/*
-Flot plugin for thresholding data. Controlled through the option
-"threshold" in either the global series options
+/* Flot plugin for thresholding data.
 
-  series: {
-    threshold: {
-      below: number
-      color: colorspec
-    }
-  }
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
+Licensed under the MIT license.
 
-or in a specific series
+The plugin supports these options:
 
-  $.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}])
+	series: {
+		threshold: {
+			below: number
+			color: colorspec
+		}
+	}
 
-The data points below "below" are drawn with the specified color. This
-makes it easy to mark points below 0, e.g. for budget data.
+It can also be applied to a single series, like this:
 
-Internally, the plugin works by splitting the data into two series,
-above and below the threshold. The extra series below the threshold
-will have its label cleared and the special "originSeries" attribute
-set to the original series. You may need to check for this in hover
-events.
+	$.plot( $("#placeholder"), [{
+		data: [ ... ],
+		threshold: { ... }
+	}])
+
+An array can be passed for multiple thresholding, like this:
+
+	threshold: [{
+		below: number1
+		color: color1
+	},{
+		below: number2
+		color: color2
+	}]
+
+These multiple threshold objects can be passed in any order since they are
+sorted by the processing function.
+
+The data points below "below" are drawn with the specified color. This makes
+it easy to mark points below 0, e.g. for budget data.
+
+Internally, the plugin works by splitting the data into two series, above and
+below the threshold. The extra series below the threshold will have its label
+cleared and the special "originSeries" attribute set to the original series.
+You may need to check for this in hover events.
+
 */
 
 (function ($) {
-    var options = {
-        series: { threshold: null } // or { below: number, color: color spec}
-    };
-    
-    function init(plot) {
-        function thresholdData(plot, s, datapoints) {
-            if (!s.threshold)
-                return;
-            
-            var ps = datapoints.pointsize, i, x, y, p, prevp,
-                thresholded = $.extend({}, s); // note: shallow copy
+  var options = {
+    series: { threshold: null } // or { below: number, color: color spec}
+  };
 
-            thresholded.datapoints = { points: [], pointsize: ps };
-            thresholded.label = null;
-            thresholded.color = s.threshold.color;
-            thresholded.threshold = null;
-            thresholded.originSeries = s;
-            thresholded.data = [];
+  function init(plot) {
+    function thresholdData(plot, s, datapoints, below, color) {
+      var ps = datapoints.pointsize, i, x, y, p, prevp,
+          thresholded = $.extend({}, s); // note: shallow copy
 
-            var below = s.threshold.below,
-                origpoints = datapoints.points,
-                addCrossingPoints = s.lines.show;
+      thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
+      thresholded.label = null;
+      thresholded.color = color;
+      thresholded.threshold = null;
+      thresholded.originSeries = s;
+      thresholded.data = [];
 
-            threspoints = [];
-            newpoints = [];
+      var origpoints = datapoints.points,
+          addCrossingPoints = s.lines.show;
 
-            for (i = 0; i < origpoints.length; i += ps) {
-                x = origpoints[i]
-                y = origpoints[i + 1];
+      var threspoints = [];
+      var newpoints = [];
+      var m;
 
-                prevp = p;
-                if (y < below)
-                    p = threspoints;
-                else
-                    p = newpoints;
+      for (i = 0; i < origpoints.length; i += ps) {
+        x = origpoints[i];
+        y = origpoints[i + 1];
 
-                if (addCrossingPoints && prevp != p && x != null
-                    && i > 0 && origpoints[i - ps] != null) {
-                    var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x;
-                    prevp.push(interx);
-                    prevp.push(below);
-                    for (m = 2; m < ps; ++m)
-                        prevp.push(origpoints[i + m]);
-                    
-                    p.push(null); // start new segment
-                    p.push(null);
-                    for (m = 2; m < ps; ++m)
-                        p.push(origpoints[i + m]);
-                    p.push(interx);
-                    p.push(below);
-                    for (m = 2; m < ps; ++m)
-                        p.push(origpoints[i + m]);
-                }
+        prevp = p;
+        if (y < below)
+          p = threspoints;
+        else
+          p = newpoints;
 
-                p.push(x);
-                p.push(y);
-            }
+        if (addCrossingPoints && prevp != p && x != null
+            && i > 0 && origpoints[i - ps] != null) {
+          var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
+          prevp.push(interx);
+          prevp.push(below);
+          for (m = 2; m < ps; ++m)
+            prevp.push(origpoints[i + m]);
 
-            datapoints.points = newpoints;
-            thresholded.datapoints.points = threspoints;
-            
-            if (thresholded.datapoints.points.length > 0)
-                plot.getData().push(thresholded);
-                
-            // FIXME: there are probably some edge cases left in bars
+          p.push(null); // start new segment
+          p.push(null);
+          for (m = 2; m < ps; ++m)
+            p.push(origpoints[i + m]);
+          p.push(interx);
+          p.push(below);
+          for (m = 2; m < ps; ++m)
+            p.push(origpoints[i + m]);
         }
-        
-        plot.hooks.processDatapoints.push(thresholdData);
+
+        p.push(x);
+        p.push(y);
+        for (m = 2; m < ps; ++m)
+          p.push(origpoints[i + m]);
+      }
+
+      datapoints.points = newpoints;
+      thresholded.datapoints.points = threspoints;
+
+      if (thresholded.datapoints.points.length > 0) {
+        var origIndex = $.inArray(s, plot.getData());
+        // Insert newly-generated series right after original one (to prevent it from becoming top-most)
+        plot.getData().splice(origIndex + 1, 0, thresholded);
+      }
+
+      // FIXME: there are probably some edge cases left in bars
     }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'threshold',
-        version: '1.0'
-    });
+
+    function processThresholds(plot, s, datapoints) {
+      if (!s.threshold)
+        return;
+
+      if (s.threshold instanceof Array) {
+        s.threshold.sort(function(a, b) {
+          return a.below - b.below;
+        });
+
+        $(s.threshold).each(function(i, th) {
+          thresholdData(plot, s, datapoints, th.below, th.color);
+        });
+      }
+      else {
+        thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
+      }
+    }
+
+    plot.hooks.processDatapoints.push(processThresholds);
+  }
+
+  $.plot.plugins.push({
+    init: init,
+    options: options,
+    name: 'threshold',
+    version: '1.2'
+  });
 })(jQuery);
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_flat_0_aaaaaa_40x100.png b/ui/lib/jquery-ui/css/images/ui-bg_flat_0_aaaaaa_40x100.png
deleted file mode 100755
index 5b5dab2..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_flat_0_aaaaaa_40x100.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_flat_75_ffffff_40x100.png b/ui/lib/jquery-ui/css/images/ui-bg_flat_75_ffffff_40x100.png
deleted file mode 100755
index ac8b229..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_flat_75_ffffff_40x100.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_glass_55_fbf9ee_1x400.png b/ui/lib/jquery-ui/css/images/ui-bg_glass_55_fbf9ee_1x400.png
deleted file mode 100755
index ad3d634..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_glass_55_fbf9ee_1x400.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_glass_65_ffffff_1x400.png b/ui/lib/jquery-ui/css/images/ui-bg_glass_65_ffffff_1x400.png
deleted file mode 100755
index 42ccba2..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_glass_65_ffffff_1x400.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_glass_75_dadada_1x400.png b/ui/lib/jquery-ui/css/images/ui-bg_glass_75_dadada_1x400.png
deleted file mode 100755
index 5a46b47..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_glass_75_dadada_1x400.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_glass_75_e6e6e6_1x400.png b/ui/lib/jquery-ui/css/images/ui-bg_glass_75_e6e6e6_1x400.png
deleted file mode 100755
index 86c2baa..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_glass_75_e6e6e6_1x400.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_highlight-hard_75_a7c1d2_1x100.png b/ui/lib/jquery-ui/css/images/ui-bg_highlight-hard_75_a7c1d2_1x100.png
deleted file mode 100755
index 7f5be8a..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_highlight-hard_75_a7c1d2_1x100.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/ui/lib/jquery-ui/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png
deleted file mode 100755
index 0e05810..0000000
--- a/ui/lib/jquery-ui/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-icons_222222_256x240.png b/ui/lib/jquery-ui/css/images/ui-icons_222222_256x240.png
deleted file mode 100755
index b273ff1..0000000
--- a/ui/lib/jquery-ui/css/images/ui-icons_222222_256x240.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-icons_2e83ff_256x240.png b/ui/lib/jquery-ui/css/images/ui-icons_2e83ff_256x240.png
deleted file mode 100755
index 09d1cdc..0000000
--- a/ui/lib/jquery-ui/css/images/ui-icons_2e83ff_256x240.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-icons_454545_256x240.png b/ui/lib/jquery-ui/css/images/ui-icons_454545_256x240.png
deleted file mode 100755
index 59bd45b..0000000
--- a/ui/lib/jquery-ui/css/images/ui-icons_454545_256x240.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-icons_888888_256x240.png b/ui/lib/jquery-ui/css/images/ui-icons_888888_256x240.png
deleted file mode 100755
index 6d02426..0000000
--- a/ui/lib/jquery-ui/css/images/ui-icons_888888_256x240.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/images/ui-icons_cd0a0a_256x240.png b/ui/lib/jquery-ui/css/images/ui-icons_cd0a0a_256x240.png
deleted file mode 100755
index 2ab019b..0000000
--- a/ui/lib/jquery-ui/css/images/ui-icons_cd0a0a_256x240.png
+++ /dev/null
Binary files differ
diff --git a/ui/lib/jquery-ui/css/jquery-ui.css b/ui/lib/jquery-ui/css/jquery-ui.css
deleted file mode 100755
index b87bd69..0000000
--- a/ui/lib/jquery-ui/css/jquery-ui.css
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * jQuery UI CSS Framework 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
-.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
-.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
-.ui-helper-clearfix { display: inline-block; }
-/* required comment for clearfix to work in Opera \*/
-* html .ui-helper-clearfix { height:1%; }
-.ui-helper-clearfix { display:block; }
-/* end clearfix */
-.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled { cursor: default !important; }
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-
-/*
- * jQuery UI CSS Framework 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- *
- * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=2px&bgColorHeader=a7c1d2&bgTextureHeader=04_highlight_hard.png&bgImgOpacityHeader=75&borderColorHeader=787878&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=05_inset_soft.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
- */
-
-
-/* Component containers
-----------------------------------*/
-.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
-.ui-widget .ui-widget { font-size: 1em; }
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
-.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
-.ui-widget-content a { color: #222222; }
-.ui-widget-header { border: 1px solid #787878; background: #a7c1d2 url(images/ui-bg_highlight-hard_75_a7c1d2_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
-.ui-widget-header a { color: #222222; }
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
-.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
-.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
-.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
-.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
-.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
-.ui-widget :active { outline: none; }
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
-.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
-.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; }
-.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
-.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
-.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
-.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
-.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
-.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
-.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
-.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
-.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
-
-/* positioning */
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-off { background-position: -96px -144px; }
-.ui-icon-radio-on { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 2px; -webkit-border-top-left-radius: 2px; -khtml-border-top-left-radius: 2px; border-top-left-radius: 2px; }
-.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 2px; -webkit-border-top-right-radius: 2px; -khtml-border-top-right-radius: 2px; border-top-right-radius: 2px; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 2px; -webkit-border-bottom-left-radius: 2px; -khtml-border-bottom-left-radius: 2px; border-bottom-left-radius: 2px; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 2px; -webkit-border-bottom-right-radius: 2px; -khtml-border-bottom-right-radius: 2px; border-bottom-right-radius: 2px; }
-
-/* Overlays */
-.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
-.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
- * jQuery UI Resizable 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizable#theming
- */
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
- * jQuery UI Selectable 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Selectable#theming
- */
-.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
-/*
- * jQuery UI Accordion 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Accordion#theming
- */
-/* IE/Win - Fix animation bug - #4615 */
-.ui-accordion { width: 100%; }
-.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
-.ui-accordion .ui-accordion-li-fix { display: inline; }
-.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
-.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
-.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
-.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
-.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
-.ui-accordion .ui-accordion-content-active { display: block; }
-/*
- * jQuery UI Autocomplete 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Autocomplete#theming
- */
-.ui-autocomplete { position: absolute; cursor: default; }	
-
-/* workarounds */
-* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
-
-/*
- * jQuery UI Menu 1.8.14
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Menu#theming
- */
-.ui-menu {
-	list-style:none;
-	padding: 2px;
-	margin: 0;
-	display:block;
-	float: left;
-}
-.ui-menu .ui-menu {
-	margin-top: -3px;
-}
-.ui-menu .ui-menu-item {
-	margin:0;
-	padding: 0;
-	zoom: 1;
-	float: left;
-	clear: left;
-	width: 100%;
-}
-.ui-menu .ui-menu-item a {
-	text-decoration:none;
-	display:block;
-	padding:.2em .4em;
-	line-height:1.5;
-	zoom:1;
-}
-.ui-menu .ui-menu-item a.ui-state-hover,
-.ui-menu .ui-menu-item a.ui-state-active {
-	font-weight: normal;
-	margin: -1px;
-}
-/*
- * jQuery UI Button 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Button#theming
- */
-.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
-.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
-button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
-.ui-button-icons-only { width: 3.4em; } 
-button.ui-button-icons-only { width: 3.7em; } 
-
-/*button text element */
-.ui-button .ui-button-text { display: block; line-height: 1.4;  }
-.ui-button-text-only .ui-button-text { padding: .4em 1em; }
-.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
-.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
-.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
-.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
-/* no icon support for input elements, provide padding by default */
-input.ui-button { padding: .4em 1em; }
-
-/*button icon element(s) */
-.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
-.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
-.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
-.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-
-/*button sets*/
-.ui-buttonset { margin-right: 7px; }
-.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
-
-/* workarounds */
-button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
-/*
- * jQuery UI Dialog 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Dialog#theming
- */
-.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
-.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
-.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 
-.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
-.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
-.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
-.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
-.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
-.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
-.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
-.ui-draggable .ui-dialog-titlebar { cursor: move; }
-/*
- * jQuery UI Slider 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider#theming
- */
-.ui-slider { position: relative; text-align: left; }
-.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
-.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
-
-.ui-slider-horizontal { height: .8em; }
-.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: .8em; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
- * jQuery UI Tabs 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Tabs#theming
- */
-.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
-.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
-.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
-.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
-.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
-.ui-tabs .ui-tabs-hide { display: none !important; }
-/*
- * jQuery UI Datepicker 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker#theming
- */
-.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
-.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
-.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
-.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
-.ui-datepicker .ui-datepicker-prev { left:2px; }
-.ui-datepicker .ui-datepicker-next { right:2px; }
-.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
-.ui-datepicker .ui-datepicker-next-hover { right:1px; }
-.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
-.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
-.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
-.ui-datepicker select.ui-datepicker-month, 
-.ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
-.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
-.ui-datepicker td { border: 0; padding: 1px; }
-.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
-.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
-.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi { width:auto; }
-.ui-datepicker-multi .ui-datepicker-group { float:left; }
-.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
-.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
-.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
-.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
-.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
-
-/* RTL support */
-.ui-datepicker-rtl { direction: rtl; }
-.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-
-/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
-.ui-datepicker-cover {
-    display: none; /*sorry for IE5*/
-    display/**/: block; /*sorry for IE5*/
-    position: absolute; /*must have*/
-    z-index: -1; /*must have*/
-    filter: mask(); /*must have*/
-    top: -4px; /*must have*/
-    left: -4px; /*must have*/
-    width: 200px; /*must have*/
-    height: 200px; /*must have*/
-}/*
- * jQuery UI Progressbar 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Progressbar#theming
- */
-.ui-progressbar { height:2em; text-align: left; }
-.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
diff --git a/ui/lib/jquery-ui/index.html b/ui/lib/jquery-ui/index.html
deleted file mode 100755
index 904f4dc..0000000
--- a/ui/lib/jquery-ui/index.html
+++ /dev/null
@@ -1,367 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-		<title>jQuery UI Example Page</title>
-		<link type="text/css" href="css/custom-theme/jquery-ui-1.8.14.custom.css" rel="stylesheet" />	
-		<script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
-		<script type="text/javascript" src="js/jquery-ui-1.8.14.custom.min.js"></script>
-		<script type="text/javascript">
-			$(function(){
-
-				// Accordion
-				$("#accordion").accordion({ header: "h3" });
-	
-				// Tabs
-				$('#tabs').tabs();
-	
-
-				// Dialog			
-				$('#dialog').dialog({
-					autoOpen: false,
-					width: 600,
-					buttons: {
-						"Ok": function() { 
-							$(this).dialog("close"); 
-						}, 
-						"Cancel": function() { 
-							$(this).dialog("close"); 
-						} 
-					}
-				});
-				
-				// Dialog Link
-				$('#dialog_link').click(function(){
-					$('#dialog').dialog('open');
-					return false;
-				});
-
-				// Datepicker
-				$('#datepicker').datepicker({
-					inline: true
-				});
-				
-				// Slider
-				$('#slider').slider({
-					range: true,
-					values: [17, 67]
-				});
-				
-				// Progressbar
-				$("#progressbar").progressbar({
-					value: 20 
-				});
-				
-				//hover states on the static widgets
-				$('#dialog_link, ul#icons li').hover(
-					function() { $(this).addClass('ui-state-hover'); }, 
-					function() { $(this).removeClass('ui-state-hover'); }
-				);
-				
-			});
-		</script>
-		<style type="text/css">
-			/*demo page css*/
-			body{ font: 62.5% "Trebuchet MS", sans-serif; margin: 50px;}
-			.demoHeaders { margin-top: 2em; }
-			#dialog_link {padding: .4em 1em .4em 20px;text-decoration: none;position: relative;}
-			#dialog_link span.ui-icon {margin: 0 5px 0 0;position: absolute;left: .2em;top: 50%;margin-top: -8px;}
-			ul#icons {margin: 0; padding: 0;}
-			ul#icons li {margin: 2px; position: relative; padding: 4px 0; cursor: pointer; float: left;  list-style: none;}
-			ul#icons span.ui-icon {float: left; margin: 0 4px;}
-		</style>	
-	</head>
-	<body>
-	<h1>Welcome to jQuery UI!</h1>
-	<p style="font-size: 1.3em; line-height: 1.5; margin: 1em 0; width: 50%;">This page demonstrates the widgets you downloaded using the theme you selected in the download builder. We've included and linked to minified versions of <a href="js/jquery-1.5.1.min.js">jQuery</a>, your personalized copy of <a href="js/jquery-ui-1.8.14.custom.min.js">jQuery UI (js/jquery-ui-1.8.14.custom.min.js)</a>, and <a href="css/custom-theme/jquery-ui-1.8.14.custom.css">css/custom-theme/jquery-ui-1.8.14.custom.css</a> which imports the entire jQuery UI CSS Framework. You can choose to link a subset of the CSS Framework depending on your needs. </p>
-	<p style="font-size: 1.2em; line-height: 1.5; margin: 1em 0; width: 50%;">You've downloaded components and a theme that are compatible with jQuery 1.3+. Please make sure you are using jQuery 1.3+ in your production environment.</p>	
-
-	<p style="font-weight: bold; margin: 2em 0 1em; font-size: 1.3em;">YOUR COMPONENTS:</p>
-		
-		<!-- Accordion -->
-		<h2 class="demoHeaders">Accordion</h2>
-		<div id="accordion">
-			<div>
-				<h3><a href="#">First</a></h3>
-				<div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
-			</div>
-			<div>
-				<h3><a href="#">Second</a></h3>
-				<div>Phasellus mattis tincidunt nibh.</div>
-			</div>
-			<div>
-				<h3><a href="#">Third</a></h3>
-				<div>Nam dui erat, auctor a, dignissim quis.</div>
-			</div>
-		</div>
-	
-		<!-- Tabs -->
-		<h2 class="demoHeaders">Tabs</h2>
-		<div id="tabs">
-			<ul>
-				<li><a href="#tabs-1">First</a></li>
-				<li><a href="#tabs-2">Second</a></li>
-				<li><a href="#tabs-3">Third</a></li>
-			</ul>
-			<div id="tabs-1">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div>
-			<div id="tabs-2">Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.</div>
-			<div id="tabs-3">Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.</div>
-		</div>
-	
-		<!-- Dialog NOTE: Dialog is not generated by UI in this demo so it can be visually styled in themeroller-->
-		<h2 class="demoHeaders">Dialog</h2>
-		<p><a href="#" id="dialog_link" class="ui-state-default ui-corner-all"><span class="ui-icon ui-icon-newwin"></span>Open Dialog</a></p>
-		
-		
-		<h2 class="demoHeaders">Overlay and Shadow Classes <em>(not currently used in UI widgets)</em></h2>
-		<div style="position: relative; width: 96%; height: 200px; padding:1% 4%; overflow:hidden;" class="fakewindowcontain">
-			<p>Lorem ipsum dolor sit amet,  Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. </p><p>Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. </p><p>Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. </p><p>Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. </p><p>Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. </p>
-			
-			<!-- ui-dialog -->
-			<div class="ui-overlay"><div class="ui-widget-overlay"></div><div class="ui-widget-shadow ui-corner-all" style="width: 302px; height: 152px; position: absolute; left: 50px; top: 30px;"></div></div>
-			<div style="position: absolute; width: 280px; height: 130px;left: 50px; top: 30px; padding: 10px;" class="ui-widget ui-widget-content ui-corner-all">
-				<div class="ui-dialog-content ui-widget-content" style="background: none; border: 0;">
-					<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
-				</div>
-			</div>
-		
-		</div>
-
-		
-		<!-- ui-dialog -->
-		<div id="dialog" title="Dialog Title">
-			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
-		</div>
-			
-				
-				
-		<h2 class="demoHeaders">Framework Icons (content color preview)</h2>
-		<ul id="icons" class="ui-widget ui-helper-clearfix">
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-n"><span class="ui-icon ui-icon-carat-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-ne"><span class="ui-icon ui-icon-carat-1-ne"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-e"><span class="ui-icon ui-icon-carat-1-e"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-se"><span class="ui-icon ui-icon-carat-1-se"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-s"><span class="ui-icon ui-icon-carat-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-sw"><span class="ui-icon ui-icon-carat-1-sw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-w"><span class="ui-icon ui-icon-carat-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-1-nw"><span class="ui-icon ui-icon-carat-1-nw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-n-s"><span class="ui-icon ui-icon-carat-2-n-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-carat-2-e-w"><span class="ui-icon ui-icon-carat-2-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-n"><span class="ui-icon ui-icon-triangle-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-ne"><span class="ui-icon ui-icon-triangle-1-ne"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-e"><span class="ui-icon ui-icon-triangle-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-se"><span class="ui-icon ui-icon-triangle-1-se"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-s"><span class="ui-icon ui-icon-triangle-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-sw"><span class="ui-icon ui-icon-triangle-1-sw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-w"><span class="ui-icon ui-icon-triangle-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-1-nw"><span class="ui-icon ui-icon-triangle-1-nw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-n-s"><span class="ui-icon ui-icon-triangle-2-n-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-triangle-2-e-w"><span class="ui-icon ui-icon-triangle-2-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-n"><span class="ui-icon ui-icon-arrow-1-n"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-ne"><span class="ui-icon ui-icon-arrow-1-ne"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-e"><span class="ui-icon ui-icon-arrow-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-se"><span class="ui-icon ui-icon-arrow-1-se"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-s"><span class="ui-icon ui-icon-arrow-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-sw"><span class="ui-icon ui-icon-arrow-1-sw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-w"><span class="ui-icon ui-icon-arrow-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-1-nw"><span class="ui-icon ui-icon-arrow-1-nw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-n-s"><span class="ui-icon ui-icon-arrow-2-n-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-ne-sw"><span class="ui-icon ui-icon-arrow-2-ne-sw"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-e-w"><span class="ui-icon ui-icon-arrow-2-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-2-se-nw"><span class="ui-icon ui-icon-arrow-2-se-nw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-n"><span class="ui-icon ui-icon-arrowstop-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-e"><span class="ui-icon ui-icon-arrowstop-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-s"><span class="ui-icon ui-icon-arrowstop-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowstop-1-w"><span class="ui-icon ui-icon-arrowstop-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-n"><span class="ui-icon ui-icon-arrowthick-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-ne"><span class="ui-icon ui-icon-arrowthick-1-ne"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-e"><span class="ui-icon ui-icon-arrowthick-1-e"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-se"><span class="ui-icon ui-icon-arrowthick-1-se"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-s"><span class="ui-icon ui-icon-arrowthick-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-sw"><span class="ui-icon ui-icon-arrowthick-1-sw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-w"><span class="ui-icon ui-icon-arrowthick-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-1-nw"><span class="ui-icon ui-icon-arrowthick-1-nw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-n-s"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-ne-sw"><span class="ui-icon ui-icon-arrowthick-2-ne-sw"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-e-w"><span class="ui-icon ui-icon-arrowthick-2-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthick-2-se-nw"><span class="ui-icon ui-icon-arrowthick-2-se-nw"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-n"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-e"><span class="ui-icon ui-icon-arrowthickstop-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-s"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowthickstop-1-w"><span class="ui-icon ui-icon-arrowthickstop-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-w"><span class="ui-icon ui-icon-arrowreturnthick-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-n"><span class="ui-icon ui-icon-arrowreturnthick-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-e"><span class="ui-icon ui-icon-arrowreturnthick-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturnthick-1-s"><span class="ui-icon ui-icon-arrowreturnthick-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-w"><span class="ui-icon ui-icon-arrowreturn-1-w"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-n"><span class="ui-icon ui-icon-arrowreturn-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-e"><span class="ui-icon ui-icon-arrowreturn-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowreturn-1-s"><span class="ui-icon ui-icon-arrowreturn-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-w"><span class="ui-icon ui-icon-arrowrefresh-1-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-n"><span class="ui-icon ui-icon-arrowrefresh-1-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-e"><span class="ui-icon ui-icon-arrowrefresh-1-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrowrefresh-1-s"><span class="ui-icon ui-icon-arrowrefresh-1-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4"><span class="ui-icon ui-icon-arrow-4"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-arrow-4-diag"><span class="ui-icon ui-icon-arrow-4-diag"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-extlink"><span class="ui-icon ui-icon-extlink"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-newwin"><span class="ui-icon ui-icon-newwin"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-refresh"><span class="ui-icon ui-icon-refresh"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-shuffle"><span class="ui-icon ui-icon-shuffle"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-transfer-e-w"><span class="ui-icon ui-icon-transfer-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-transferthick-e-w"><span class="ui-icon ui-icon-transferthick-e-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-collapsed"><span class="ui-icon ui-icon-folder-collapsed"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-folder-open"><span class="ui-icon ui-icon-folder-open"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-document"><span class="ui-icon ui-icon-document"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-document-b"><span class="ui-icon ui-icon-document-b"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-note"><span class="ui-icon ui-icon-note"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-mail-open"><span class="ui-icon ui-icon-mail-open"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-suitcase"><span class="ui-icon ui-icon-suitcase"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-comment"><span class="ui-icon ui-icon-comment"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-person"><span class="ui-icon ui-icon-person"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-print"><span class="ui-icon ui-icon-print"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-trash"><span class="ui-icon ui-icon-trash"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-locked"><span class="ui-icon ui-icon-locked"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-unlocked"><span class="ui-icon ui-icon-unlocked"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-bookmark"><span class="ui-icon ui-icon-bookmark"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-tag"><span class="ui-icon ui-icon-tag"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-home"><span class="ui-icon ui-icon-home"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-flag"><span class="ui-icon ui-icon-flag"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-calculator"><span class="ui-icon ui-icon-calculator"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-cart"><span class="ui-icon ui-icon-cart"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-pencil"><span class="ui-icon ui-icon-pencil"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-clock"><span class="ui-icon ui-icon-clock"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-disk"><span class="ui-icon ui-icon-disk"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-calendar"><span class="ui-icon ui-icon-calendar"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomin"><span class="ui-icon ui-icon-zoomin"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-zoomout"><span class="ui-icon ui-icon-zoomout"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-search"><span class="ui-icon ui-icon-search"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-wrench"><span class="ui-icon ui-icon-wrench"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-gear"><span class="ui-icon ui-icon-gear"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-heart"><span class="ui-icon ui-icon-heart"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-star"><span class="ui-icon ui-icon-star"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-link"><span class="ui-icon ui-icon-link"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-cancel"><span class="ui-icon ui-icon-cancel"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-plus"><span class="ui-icon ui-icon-plus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-minus"><span class="ui-icon ui-icon-minus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-minusthick"><span class="ui-icon ui-icon-minusthick"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-close"><span class="ui-icon ui-icon-close"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-closethick"><span class="ui-icon ui-icon-closethick"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-key"><span class="ui-icon ui-icon-key"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-lightbulb"><span class="ui-icon ui-icon-lightbulb"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-scissors"><span class="ui-icon ui-icon-scissors"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-clipboard"><span class="ui-icon ui-icon-clipboard"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-copy"><span class="ui-icon ui-icon-copy"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-contact"><span class="ui-icon ui-icon-contact"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-image"><span class="ui-icon ui-icon-image"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-video"><span class="ui-icon ui-icon-video"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-script"><span class="ui-icon ui-icon-script"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-alert"><span class="ui-icon ui-icon-alert"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-info"><span class="ui-icon ui-icon-info"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-notice"><span class="ui-icon ui-icon-notice"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-help"><span class="ui-icon ui-icon-help"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-bullet"><span class="ui-icon ui-icon-bullet"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-off"><span class="ui-icon ui-icon-radio-off"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-radio-on"><span class="ui-icon ui-icon-radio-on"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-w"><span class="ui-icon ui-icon-pin-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-pin-s"><span class="ui-icon ui-icon-pin-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-play"><span class="ui-icon ui-icon-play"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-pause"><span class="ui-icon ui-icon-pause"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-next"><span class="ui-icon ui-icon-seek-next"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-prev"><span class="ui-icon ui-icon-seek-prev"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-end"><span class="ui-icon ui-icon-seek-end"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-seek-first"><span class="ui-icon ui-icon-seek-first"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-stop"><span class="ui-icon ui-icon-stop"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-eject"><span class="ui-icon ui-icon-eject"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-off"><span class="ui-icon ui-icon-volume-off"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-volume-on"><span class="ui-icon ui-icon-volume-on"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-power"><span class="ui-icon ui-icon-power"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-signal-diag"><span class="ui-icon ui-icon-signal-diag"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-signal"><span class="ui-icon ui-icon-signal"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-0"><span class="ui-icon ui-icon-battery-0"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-1"><span class="ui-icon ui-icon-battery-1"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-2"><span class="ui-icon ui-icon-battery-2"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-battery-3"><span class="ui-icon ui-icon-battery-3"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-plus"><span class="ui-icon ui-icon-circle-plus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-minus"><span class="ui-icon ui-icon-circle-minus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-close"><span class="ui-icon ui-icon-circle-close"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-e"><span class="ui-icon ui-icon-circle-triangle-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-s"><span class="ui-icon ui-icon-circle-triangle-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-w"><span class="ui-icon ui-icon-circle-triangle-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-triangle-n"><span class="ui-icon ui-icon-circle-triangle-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-e"><span class="ui-icon ui-icon-circle-arrow-e"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-s"><span class="ui-icon ui-icon-circle-arrow-s"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-w"><span class="ui-icon ui-icon-circle-arrow-w"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-arrow-n"><span class="ui-icon ui-icon-circle-arrow-n"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomin"><span class="ui-icon ui-icon-circle-zoomin"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-zoomout"><span class="ui-icon ui-icon-circle-zoomout"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circle-check"><span class="ui-icon ui-icon-circle-check"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-plus"><span class="ui-icon ui-icon-circlesmall-plus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-minus"><span class="ui-icon ui-icon-circlesmall-minus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-circlesmall-close"><span class="ui-icon ui-icon-circlesmall-close"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-plus"><span class="ui-icon ui-icon-squaresmall-plus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-minus"><span class="ui-icon ui-icon-squaresmall-minus"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-squaresmall-close"><span class="ui-icon ui-icon-squaresmall-close"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-vertical"><span class="ui-icon ui-icon-grip-dotted-vertical"></span></li>
-		
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-dotted-horizontal"><span class="ui-icon ui-icon-grip-dotted-horizontal"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-vertical"><span class="ui-icon ui-icon-grip-solid-vertical"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-solid-horizontal"><span class="ui-icon ui-icon-grip-solid-horizontal"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-gripsmall-diagonal-se"><span class="ui-icon ui-icon-gripsmall-diagonal-se"></span></li>
-		<li class="ui-state-default ui-corner-all" title=".ui-icon-grip-diagonal-se"><span class="ui-icon ui-icon-grip-diagonal-se"></span></li>
-		</ul>
-
-	
-		<!-- Slider -->
-		<h2 class="demoHeaders">Slider</h2>
-		<div id="slider"></div>
-	
-		<!-- Datepicker -->
-		<h2 class="demoHeaders">Datepicker</h2>
-		<div id="datepicker"></div>
-	
-		<!-- Progressbar -->
-		<h2 class="demoHeaders">Progressbar</h2>	
-		<div id="progressbar"></div>
-			
-		<!-- Highlight / Error -->
-		<h2 class="demoHeaders">Highlight / Error</h2>
-		<div class="ui-widget">
-			<div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0 .7em;"> 
-				<p><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
-				<strong>Hey!</strong> Sample ui-state-highlight style.</p>
-			</div>
-		</div>
-		<br/>
-		<div class="ui-widget">
-			<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;"> 
-				<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span> 
-				<strong>Alert:</strong> Sample ui-state-error style.</p>
-			</div>
-		</div>
-
-	</body>
-</html>
-
-
diff --git a/ui/lib/jquery-ui/js/jquery-ui.js b/ui/lib/jquery-ui/js/jquery-ui.js
old mode 100755
new mode 100644
index 7ec85a5..0213552
--- a/ui/lib/jquery-ui/js/jquery-ui.js
+++ b/ui/lib/jquery-ui/js/jquery-ui.js
@@ -1,789 +1,18706 @@
+/*! jQuery UI - v1.12.1 - 2016-09-14
+* http://jqueryui.com
+* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+
+		// AMD. Register as an anonymous module.
+		define([ "jquery" ], factory );
+	} else {
+
+		// Browser globals
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+$.ui = $.ui || {};
+
+var version = $.ui.version = "1.12.1";
+
+
 /*!
- * jQuery UI 1.8.14
+ * jQuery UI Widget 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Widget
+//>>group: Core
+//>>description: Provides a factory for creating stateful widgets with a common API.
+//>>docs: http://api.jqueryui.com/jQuery.widget/
+//>>demos: http://jqueryui.com/widget/
+
+
+
+var widgetUuid = 0;
+var widgetSlice = Array.prototype.slice;
+
+$.cleanData = ( function( orig ) {
+	return function( elems ) {
+		var events, elem, i;
+		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
+			try {
+
+				// Only trigger remove when necessary to save time
+				events = $._data( elem, "events" );
+				if ( events && events.remove ) {
+					$( elem ).triggerHandler( "remove" );
+				}
+
+			// Http://bugs.jquery.com/ticket/8235
+			} catch ( e ) {}
+		}
+		orig( elems );
+	};
+} )( $.cleanData );
+
+$.widget = function( name, base, prototype ) {
+	var existingConstructor, constructor, basePrototype;
+
+	// ProxiedPrototype allows the provided prototype to remain unmodified
+	// so that it can be used as a mixin for multiple widgets (#8876)
+	var proxiedPrototype = {};
+
+	var namespace = name.split( "." )[ 0 ];
+	name = name.split( "." )[ 1 ];
+	var fullName = namespace + "-" + name;
+
+	if ( !prototype ) {
+		prototype = base;
+		base = $.Widget;
+	}
+
+	if ( $.isArray( prototype ) ) {
+		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
+	}
+
+	// Create selector for plugin
+	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+		return !!$.data( elem, fullName );
+	};
+
+	$[ namespace ] = $[ namespace ] || {};
+	existingConstructor = $[ namespace ][ name ];
+	constructor = $[ namespace ][ name ] = function( options, element ) {
+
+		// Allow instantiation without "new" keyword
+		if ( !this._createWidget ) {
+			return new constructor( options, element );
+		}
+
+		// Allow instantiation without initializing for simple inheritance
+		// must use "new" keyword (the code above always passes args)
+		if ( arguments.length ) {
+			this._createWidget( options, element );
+		}
+	};
+
+	// Extend with the existing constructor to carry over any static properties
+	$.extend( constructor, existingConstructor, {
+		version: prototype.version,
+
+		// Copy the object used to create the prototype in case we need to
+		// redefine the widget later
+		_proto: $.extend( {}, prototype ),
+
+		// Track widgets that inherit from this widget in case this widget is
+		// redefined after a widget inherits from it
+		_childConstructors: []
+	} );
+
+	basePrototype = new base();
+
+	// We need to make the options hash a property directly on the new instance
+	// otherwise we'll modify the options hash on the prototype that we're
+	// inheriting from
+	basePrototype.options = $.widget.extend( {}, basePrototype.options );
+	$.each( prototype, function( prop, value ) {
+		if ( !$.isFunction( value ) ) {
+			proxiedPrototype[ prop ] = value;
+			return;
+		}
+		proxiedPrototype[ prop ] = ( function() {
+			function _super() {
+				return base.prototype[ prop ].apply( this, arguments );
+			}
+
+			function _superApply( args ) {
+				return base.prototype[ prop ].apply( this, args );
+			}
+
+			return function() {
+				var __super = this._super;
+				var __superApply = this._superApply;
+				var returnValue;
+
+				this._super = _super;
+				this._superApply = _superApply;
+
+				returnValue = value.apply( this, arguments );
+
+				this._super = __super;
+				this._superApply = __superApply;
+
+				return returnValue;
+			};
+		} )();
+	} );
+	constructor.prototype = $.widget.extend( basePrototype, {
+
+		// TODO: remove support for widgetEventPrefix
+		// always use the name + a colon as the prefix, e.g., draggable:start
+		// don't prefix for widgets that aren't DOM-based
+		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
+	}, proxiedPrototype, {
+		constructor: constructor,
+		namespace: namespace,
+		widgetName: name,
+		widgetFullName: fullName
+	} );
+
+	// If this widget is being redefined then we need to find all widgets that
+	// are inheriting from it and redefine all of them so that they inherit from
+	// the new version of this widget. We're essentially trying to replace one
+	// level in the prototype chain.
+	if ( existingConstructor ) {
+		$.each( existingConstructor._childConstructors, function( i, child ) {
+			var childPrototype = child.prototype;
+
+			// Redefine the child widget using the same prototype that was
+			// originally used, but inherit from the new version of the base
+			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
+				child._proto );
+		} );
+
+		// Remove the list of existing child constructors from the old constructor
+		// so the old child constructors can be garbage collected
+		delete existingConstructor._childConstructors;
+	} else {
+		base._childConstructors.push( constructor );
+	}
+
+	$.widget.bridge( name, constructor );
+
+	return constructor;
+};
+
+$.widget.extend = function( target ) {
+	var input = widgetSlice.call( arguments, 1 );
+	var inputIndex = 0;
+	var inputLength = input.length;
+	var key;
+	var value;
+
+	for ( ; inputIndex < inputLength; inputIndex++ ) {
+		for ( key in input[ inputIndex ] ) {
+			value = input[ inputIndex ][ key ];
+			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+
+				// Clone objects
+				if ( $.isPlainObject( value ) ) {
+					target[ key ] = $.isPlainObject( target[ key ] ) ?
+						$.widget.extend( {}, target[ key ], value ) :
+
+						// Don't extend strings, arrays, etc. with objects
+						$.widget.extend( {}, value );
+
+				// Copy everything else by reference
+				} else {
+					target[ key ] = value;
+				}
+			}
+		}
+	}
+	return target;
+};
+
+$.widget.bridge = function( name, object ) {
+	var fullName = object.prototype.widgetFullName || name;
+	$.fn[ name ] = function( options ) {
+		var isMethodCall = typeof options === "string";
+		var args = widgetSlice.call( arguments, 1 );
+		var returnValue = this;
+
+		if ( isMethodCall ) {
+
+			// If this is an empty collection, we need to have the instance method
+			// return undefined instead of the jQuery instance
+			if ( !this.length && options === "instance" ) {
+				returnValue = undefined;
+			} else {
+				this.each( function() {
+					var methodValue;
+					var instance = $.data( this, fullName );
+
+					if ( options === "instance" ) {
+						returnValue = instance;
+						return false;
+					}
+
+					if ( !instance ) {
+						return $.error( "cannot call methods on " + name +
+							" prior to initialization; " +
+							"attempted to call method '" + options + "'" );
+					}
+
+					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
+						return $.error( "no such method '" + options + "' for " + name +
+							" widget instance" );
+					}
+
+					methodValue = instance[ options ].apply( instance, args );
+
+					if ( methodValue !== instance && methodValue !== undefined ) {
+						returnValue = methodValue && methodValue.jquery ?
+							returnValue.pushStack( methodValue.get() ) :
+							methodValue;
+						return false;
+					}
+				} );
+			}
+		} else {
+
+			// Allow multiple hashes to be passed on init
+			if ( args.length ) {
+				options = $.widget.extend.apply( null, [ options ].concat( args ) );
+			}
+
+			this.each( function() {
+				var instance = $.data( this, fullName );
+				if ( instance ) {
+					instance.option( options || {} );
+					if ( instance._init ) {
+						instance._init();
+					}
+				} else {
+					$.data( this, fullName, new object( options, this ) );
+				}
+			} );
+		}
+
+		return returnValue;
+	};
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+	widgetName: "widget",
+	widgetEventPrefix: "",
+	defaultElement: "<div>",
+
+	options: {
+		classes: {},
+		disabled: false,
+
+		// Callbacks
+		create: null
+	},
+
+	_createWidget: function( options, element ) {
+		element = $( element || this.defaultElement || this )[ 0 ];
+		this.element = $( element );
+		this.uuid = widgetUuid++;
+		this.eventNamespace = "." + this.widgetName + this.uuid;
+
+		this.bindings = $();
+		this.hoverable = $();
+		this.focusable = $();
+		this.classesElementLookup = {};
+
+		if ( element !== this ) {
+			$.data( element, this.widgetFullName, this );
+			this._on( true, this.element, {
+				remove: function( event ) {
+					if ( event.target === element ) {
+						this.destroy();
+					}
+				}
+			} );
+			this.document = $( element.style ?
+
+				// Element within the document
+				element.ownerDocument :
+
+				// Element is window or document
+				element.document || element );
+			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
+		}
+
+		this.options = $.widget.extend( {},
+			this.options,
+			this._getCreateOptions(),
+			options );
+
+		this._create();
+
+		if ( this.options.disabled ) {
+			this._setOptionDisabled( this.options.disabled );
+		}
+
+		this._trigger( "create", null, this._getCreateEventData() );
+		this._init();
+	},
+
+	_getCreateOptions: function() {
+		return {};
+	},
+
+	_getCreateEventData: $.noop,
+
+	_create: $.noop,
+
+	_init: $.noop,
+
+	destroy: function() {
+		var that = this;
+
+		this._destroy();
+		$.each( this.classesElementLookup, function( key, value ) {
+			that._removeClass( value, key );
+		} );
+
+		// We can probably remove the unbind calls in 2.0
+		// all event bindings should go through this._on()
+		this.element
+			.off( this.eventNamespace )
+			.removeData( this.widgetFullName );
+		this.widget()
+			.off( this.eventNamespace )
+			.removeAttr( "aria-disabled" );
+
+		// Clean up events and states
+		this.bindings.off( this.eventNamespace );
+	},
+
+	_destroy: $.noop,
+
+	widget: function() {
+		return this.element;
+	},
+
+	option: function( key, value ) {
+		var options = key;
+		var parts;
+		var curOption;
+		var i;
+
+		if ( arguments.length === 0 ) {
+
+			// Don't return a reference to the internal hash
+			return $.widget.extend( {}, this.options );
+		}
+
+		if ( typeof key === "string" ) {
+
+			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+			options = {};
+			parts = key.split( "." );
+			key = parts.shift();
+			if ( parts.length ) {
+				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+				for ( i = 0; i < parts.length - 1; i++ ) {
+					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+					curOption = curOption[ parts[ i ] ];
+				}
+				key = parts.pop();
+				if ( arguments.length === 1 ) {
+					return curOption[ key ] === undefined ? null : curOption[ key ];
+				}
+				curOption[ key ] = value;
+			} else {
+				if ( arguments.length === 1 ) {
+					return this.options[ key ] === undefined ? null : this.options[ key ];
+				}
+				options[ key ] = value;
+			}
+		}
+
+		this._setOptions( options );
+
+		return this;
+	},
+
+	_setOptions: function( options ) {
+		var key;
+
+		for ( key in options ) {
+			this._setOption( key, options[ key ] );
+		}
+
+		return this;
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "classes" ) {
+			this._setOptionClasses( value );
+		}
+
+		this.options[ key ] = value;
+
+		if ( key === "disabled" ) {
+			this._setOptionDisabled( value );
+		}
+
+		return this;
+	},
+
+	_setOptionClasses: function( value ) {
+		var classKey, elements, currentElements;
+
+		for ( classKey in value ) {
+			currentElements = this.classesElementLookup[ classKey ];
+			if ( value[ classKey ] === this.options.classes[ classKey ] ||
+					!currentElements ||
+					!currentElements.length ) {
+				continue;
+			}
+
+			// We are doing this to create a new jQuery object because the _removeClass() call
+			// on the next line is going to destroy the reference to the current elements being
+			// tracked. We need to save a copy of this collection so that we can add the new classes
+			// below.
+			elements = $( currentElements.get() );
+			this._removeClass( currentElements, classKey );
+
+			// We don't use _addClass() here, because that uses this.options.classes
+			// for generating the string of classes. We want to use the value passed in from
+			// _setOption(), this is the new value of the classes option which was passed to
+			// _setOption(). We pass this value directly to _classes().
+			elements.addClass( this._classes( {
+				element: elements,
+				keys: classKey,
+				classes: value,
+				add: true
+			} ) );
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
+
+		// If the widget is becoming disabled, then nothing is interactive
+		if ( value ) {
+			this._removeClass( this.hoverable, null, "ui-state-hover" );
+			this._removeClass( this.focusable, null, "ui-state-focus" );
+		}
+	},
+
+	enable: function() {
+		return this._setOptions( { disabled: false } );
+	},
+
+	disable: function() {
+		return this._setOptions( { disabled: true } );
+	},
+
+	_classes: function( options ) {
+		var full = [];
+		var that = this;
+
+		options = $.extend( {
+			element: this.element,
+			classes: this.options.classes || {}
+		}, options );
+
+		function processClassString( classes, checkOption ) {
+			var current, i;
+			for ( i = 0; i < classes.length; i++ ) {
+				current = that.classesElementLookup[ classes[ i ] ] || $();
+				if ( options.add ) {
+					current = $( $.unique( current.get().concat( options.element.get() ) ) );
+				} else {
+					current = $( current.not( options.element ).get() );
+				}
+				that.classesElementLookup[ classes[ i ] ] = current;
+				full.push( classes[ i ] );
+				if ( checkOption && options.classes[ classes[ i ] ] ) {
+					full.push( options.classes[ classes[ i ] ] );
+				}
+			}
+		}
+
+		this._on( options.element, {
+			"remove": "_untrackClassesElement"
+		} );
+
+		if ( options.keys ) {
+			processClassString( options.keys.match( /\S+/g ) || [], true );
+		}
+		if ( options.extra ) {
+			processClassString( options.extra.match( /\S+/g ) || [] );
+		}
+
+		return full.join( " " );
+	},
+
+	_untrackClassesElement: function( event ) {
+		var that = this;
+		$.each( that.classesElementLookup, function( key, value ) {
+			if ( $.inArray( event.target, value ) !== -1 ) {
+				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
+			}
+		} );
+	},
+
+	_removeClass: function( element, keys, extra ) {
+		return this._toggleClass( element, keys, extra, false );
+	},
+
+	_addClass: function( element, keys, extra ) {
+		return this._toggleClass( element, keys, extra, true );
+	},
+
+	_toggleClass: function( element, keys, extra, add ) {
+		add = ( typeof add === "boolean" ) ? add : extra;
+		var shift = ( typeof element === "string" || element === null ),
+			options = {
+				extra: shift ? keys : extra,
+				keys: shift ? element : keys,
+				element: shift ? this.element : element,
+				add: add
+			};
+		options.element.toggleClass( this._classes( options ), add );
+		return this;
+	},
+
+	_on: function( suppressDisabledCheck, element, handlers ) {
+		var delegateElement;
+		var instance = this;
+
+		// No suppressDisabledCheck flag, shuffle arguments
+		if ( typeof suppressDisabledCheck !== "boolean" ) {
+			handlers = element;
+			element = suppressDisabledCheck;
+			suppressDisabledCheck = false;
+		}
+
+		// No element argument, shuffle and use this.element
+		if ( !handlers ) {
+			handlers = element;
+			element = this.element;
+			delegateElement = this.widget();
+		} else {
+			element = delegateElement = $( element );
+			this.bindings = this.bindings.add( element );
+		}
+
+		$.each( handlers, function( event, handler ) {
+			function handlerProxy() {
+
+				// Allow widgets to customize the disabled handling
+				// - disabled as an array instead of boolean
+				// - disabled class as method for disabling individual parts
+				if ( !suppressDisabledCheck &&
+						( instance.options.disabled === true ||
+						$( this ).hasClass( "ui-state-disabled" ) ) ) {
+					return;
+				}
+				return ( typeof handler === "string" ? instance[ handler ] : handler )
+					.apply( instance, arguments );
+			}
+
+			// Copy the guid so direct unbinding works
+			if ( typeof handler !== "string" ) {
+				handlerProxy.guid = handler.guid =
+					handler.guid || handlerProxy.guid || $.guid++;
+			}
+
+			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
+			var eventName = match[ 1 ] + instance.eventNamespace;
+			var selector = match[ 2 ];
+
+			if ( selector ) {
+				delegateElement.on( eventName, selector, handlerProxy );
+			} else {
+				element.on( eventName, handlerProxy );
+			}
+		} );
+	},
+
+	_off: function( element, eventName ) {
+		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
+			this.eventNamespace;
+		element.off( eventName ).off( eventName );
+
+		// Clear the stack to avoid memory leaks (#10056)
+		this.bindings = $( this.bindings.not( element ).get() );
+		this.focusable = $( this.focusable.not( element ).get() );
+		this.hoverable = $( this.hoverable.not( element ).get() );
+	},
+
+	_delay: function( handler, delay ) {
+		function handlerProxy() {
+			return ( typeof handler === "string" ? instance[ handler ] : handler )
+				.apply( instance, arguments );
+		}
+		var instance = this;
+		return setTimeout( handlerProxy, delay || 0 );
+	},
+
+	_hoverable: function( element ) {
+		this.hoverable = this.hoverable.add( element );
+		this._on( element, {
+			mouseenter: function( event ) {
+				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
+			},
+			mouseleave: function( event ) {
+				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
+			}
+		} );
+	},
+
+	_focusable: function( element ) {
+		this.focusable = this.focusable.add( element );
+		this._on( element, {
+			focusin: function( event ) {
+				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
+			},
+			focusout: function( event ) {
+				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
+			}
+		} );
+	},
+
+	_trigger: function( type, event, data ) {
+		var prop, orig;
+		var callback = this.options[ type ];
+
+		data = data || {};
+		event = $.Event( event );
+		event.type = ( type === this.widgetEventPrefix ?
+			type :
+			this.widgetEventPrefix + type ).toLowerCase();
+
+		// The original event may come from any element
+		// so we need to reset the target on the new event
+		event.target = this.element[ 0 ];
+
+		// Copy original event properties over to the new event
+		orig = event.originalEvent;
+		if ( orig ) {
+			for ( prop in orig ) {
+				if ( !( prop in event ) ) {
+					event[ prop ] = orig[ prop ];
+				}
+			}
+		}
+
+		this.element.trigger( event, data );
+		return !( $.isFunction( callback ) &&
+			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
+			event.isDefaultPrevented() );
+	}
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+		if ( typeof options === "string" ) {
+			options = { effect: options };
+		}
+
+		var hasOptions;
+		var effectName = !options ?
+			method :
+			options === true || typeof options === "number" ?
+				defaultEffect :
+				options.effect || defaultEffect;
+
+		options = options || {};
+		if ( typeof options === "number" ) {
+			options = { duration: options };
+		}
+
+		hasOptions = !$.isEmptyObject( options );
+		options.complete = callback;
+
+		if ( options.delay ) {
+			element.delay( options.delay );
+		}
+
+		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+			element[ method ]( options );
+		} else if ( effectName !== method && element[ effectName ] ) {
+			element[ effectName ]( options.duration, options.easing, callback );
+		} else {
+			element.queue( function( next ) {
+				$( this )[ method ]();
+				if ( callback ) {
+					callback.call( element[ 0 ] );
+				}
+				next();
+			} );
+		}
+	};
+} );
+
+var widget = $.widget;
+
+
+/*!
+ * jQuery UI Position 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
  *
- * http://docs.jquery.com/UI
+ * http://api.jqueryui.com/position/
  */
-(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.14",
-keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();
-b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,
-"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",
-function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,
-outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a,"tabindex"),d=isNaN(b);
-return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=
-0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
-;/*!
- * jQuery UI Widget 1.8.14
+
+//>>label: Position
+//>>group: Core
+//>>description: Positions elements relative to other elements.
+//>>docs: http://api.jqueryui.com/position/
+//>>demos: http://jqueryui.com/position/
+
+
+( function() {
+var cachedScrollbarWidth,
+	max = Math.max,
+	abs = Math.abs,
+	rhorizontal = /left|center|right/,
+	rvertical = /top|center|bottom/,
+	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
+	rposition = /^\w+/,
+	rpercent = /%$/,
+	_position = $.fn.position;
+
+function getOffsets( offsets, width, height ) {
+	return [
+		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
+		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
+	];
+}
+
+function parseCss( element, property ) {
+	return parseInt( $.css( element, property ), 10 ) || 0;
+}
+
+function getDimensions( elem ) {
+	var raw = elem[ 0 ];
+	if ( raw.nodeType === 9 ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: 0, left: 0 }
+		};
+	}
+	if ( $.isWindow( raw ) ) {
+		return {
+			width: elem.width(),
+			height: elem.height(),
+			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
+		};
+	}
+	if ( raw.preventDefault ) {
+		return {
+			width: 0,
+			height: 0,
+			offset: { top: raw.pageY, left: raw.pageX }
+		};
+	}
+	return {
+		width: elem.outerWidth(),
+		height: elem.outerHeight(),
+		offset: elem.offset()
+	};
+}
+
+$.position = {
+	scrollbarWidth: function() {
+		if ( cachedScrollbarWidth !== undefined ) {
+			return cachedScrollbarWidth;
+		}
+		var w1, w2,
+			div = $( "<div " +
+				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
+				"<div style='height:100px;width:auto;'></div></div>" ),
+			innerDiv = div.children()[ 0 ];
+
+		$( "body" ).append( div );
+		w1 = innerDiv.offsetWidth;
+		div.css( "overflow", "scroll" );
+
+		w2 = innerDiv.offsetWidth;
+
+		if ( w1 === w2 ) {
+			w2 = div[ 0 ].clientWidth;
+		}
+
+		div.remove();
+
+		return ( cachedScrollbarWidth = w1 - w2 );
+	},
+	getScrollInfo: function( within ) {
+		var overflowX = within.isWindow || within.isDocument ? "" :
+				within.element.css( "overflow-x" ),
+			overflowY = within.isWindow || within.isDocument ? "" :
+				within.element.css( "overflow-y" ),
+			hasOverflowX = overflowX === "scroll" ||
+				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
+			hasOverflowY = overflowY === "scroll" ||
+				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
+		return {
+			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
+			height: hasOverflowX ? $.position.scrollbarWidth() : 0
+		};
+	},
+	getWithinInfo: function( element ) {
+		var withinElement = $( element || window ),
+			isWindow = $.isWindow( withinElement[ 0 ] ),
+			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
+			hasOffset = !isWindow && !isDocument;
+		return {
+			element: withinElement,
+			isWindow: isWindow,
+			isDocument: isDocument,
+			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
+			scrollLeft: withinElement.scrollLeft(),
+			scrollTop: withinElement.scrollTop(),
+			width: withinElement.outerWidth(),
+			height: withinElement.outerHeight()
+		};
+	}
+};
+
+$.fn.position = function( options ) {
+	if ( !options || !options.of ) {
+		return _position.apply( this, arguments );
+	}
+
+	// Make a copy, we don't want to modify arguments
+	options = $.extend( {}, options );
+
+	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
+		target = $( options.of ),
+		within = $.position.getWithinInfo( options.within ),
+		scrollInfo = $.position.getScrollInfo( within ),
+		collision = ( options.collision || "flip" ).split( " " ),
+		offsets = {};
+
+	dimensions = getDimensions( target );
+	if ( target[ 0 ].preventDefault ) {
+
+		// Force left top to allow flipping
+		options.at = "left top";
+	}
+	targetWidth = dimensions.width;
+	targetHeight = dimensions.height;
+	targetOffset = dimensions.offset;
+
+	// Clone to reuse original targetOffset later
+	basePosition = $.extend( {}, targetOffset );
+
+	// Force my and at to have valid horizontal and vertical positions
+	// if a value is missing or invalid, it will be converted to center
+	$.each( [ "my", "at" ], function() {
+		var pos = ( options[ this ] || "" ).split( " " ),
+			horizontalOffset,
+			verticalOffset;
+
+		if ( pos.length === 1 ) {
+			pos = rhorizontal.test( pos[ 0 ] ) ?
+				pos.concat( [ "center" ] ) :
+				rvertical.test( pos[ 0 ] ) ?
+					[ "center" ].concat( pos ) :
+					[ "center", "center" ];
+		}
+		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
+		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
+
+		// Calculate offsets
+		horizontalOffset = roffset.exec( pos[ 0 ] );
+		verticalOffset = roffset.exec( pos[ 1 ] );
+		offsets[ this ] = [
+			horizontalOffset ? horizontalOffset[ 0 ] : 0,
+			verticalOffset ? verticalOffset[ 0 ] : 0
+		];
+
+		// Reduce to just the positions without the offsets
+		options[ this ] = [
+			rposition.exec( pos[ 0 ] )[ 0 ],
+			rposition.exec( pos[ 1 ] )[ 0 ]
+		];
+	} );
+
+	// Normalize collision option
+	if ( collision.length === 1 ) {
+		collision[ 1 ] = collision[ 0 ];
+	}
+
+	if ( options.at[ 0 ] === "right" ) {
+		basePosition.left += targetWidth;
+	} else if ( options.at[ 0 ] === "center" ) {
+		basePosition.left += targetWidth / 2;
+	}
+
+	if ( options.at[ 1 ] === "bottom" ) {
+		basePosition.top += targetHeight;
+	} else if ( options.at[ 1 ] === "center" ) {
+		basePosition.top += targetHeight / 2;
+	}
+
+	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
+	basePosition.left += atOffset[ 0 ];
+	basePosition.top += atOffset[ 1 ];
+
+	return this.each( function() {
+		var collisionPosition, using,
+			elem = $( this ),
+			elemWidth = elem.outerWidth(),
+			elemHeight = elem.outerHeight(),
+			marginLeft = parseCss( this, "marginLeft" ),
+			marginTop = parseCss( this, "marginTop" ),
+			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
+				scrollInfo.width,
+			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
+				scrollInfo.height,
+			position = $.extend( {}, basePosition ),
+			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
+
+		if ( options.my[ 0 ] === "right" ) {
+			position.left -= elemWidth;
+		} else if ( options.my[ 0 ] === "center" ) {
+			position.left -= elemWidth / 2;
+		}
+
+		if ( options.my[ 1 ] === "bottom" ) {
+			position.top -= elemHeight;
+		} else if ( options.my[ 1 ] === "center" ) {
+			position.top -= elemHeight / 2;
+		}
+
+		position.left += myOffset[ 0 ];
+		position.top += myOffset[ 1 ];
+
+		collisionPosition = {
+			marginLeft: marginLeft,
+			marginTop: marginTop
+		};
+
+		$.each( [ "left", "top" ], function( i, dir ) {
+			if ( $.ui.position[ collision[ i ] ] ) {
+				$.ui.position[ collision[ i ] ][ dir ]( position, {
+					targetWidth: targetWidth,
+					targetHeight: targetHeight,
+					elemWidth: elemWidth,
+					elemHeight: elemHeight,
+					collisionPosition: collisionPosition,
+					collisionWidth: collisionWidth,
+					collisionHeight: collisionHeight,
+					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
+					my: options.my,
+					at: options.at,
+					within: within,
+					elem: elem
+				} );
+			}
+		} );
+
+		if ( options.using ) {
+
+			// Adds feedback as second argument to using callback, if present
+			using = function( props ) {
+				var left = targetOffset.left - position.left,
+					right = left + targetWidth - elemWidth,
+					top = targetOffset.top - position.top,
+					bottom = top + targetHeight - elemHeight,
+					feedback = {
+						target: {
+							element: target,
+							left: targetOffset.left,
+							top: targetOffset.top,
+							width: targetWidth,
+							height: targetHeight
+						},
+						element: {
+							element: elem,
+							left: position.left,
+							top: position.top,
+							width: elemWidth,
+							height: elemHeight
+						},
+						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
+						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
+					};
+				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
+					feedback.horizontal = "center";
+				}
+				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
+					feedback.vertical = "middle";
+				}
+				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
+					feedback.important = "horizontal";
+				} else {
+					feedback.important = "vertical";
+				}
+				options.using.call( this, props, feedback );
+			};
+		}
+
+		elem.offset( $.extend( position, { using: using } ) );
+	} );
+};
+
+$.ui.position = {
+	fit: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
+				outerWidth = within.width,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = withinOffset - collisionPosLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
+				newOverRight;
+
+			// Element is wider than within
+			if ( data.collisionWidth > outerWidth ) {
+
+				// Element is initially over the left side of within
+				if ( overLeft > 0 && overRight <= 0 ) {
+					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
+						withinOffset;
+					position.left += overLeft - newOverRight;
+
+				// Element is initially over right side of within
+				} else if ( overRight > 0 && overLeft <= 0 ) {
+					position.left = withinOffset;
+
+				// Element is initially over both left and right sides of within
+				} else {
+					if ( overLeft > overRight ) {
+						position.left = withinOffset + outerWidth - data.collisionWidth;
+					} else {
+						position.left = withinOffset;
+					}
+				}
+
+			// Too far left -> align with left edge
+			} else if ( overLeft > 0 ) {
+				position.left += overLeft;
+
+			// Too far right -> align with right edge
+			} else if ( overRight > 0 ) {
+				position.left -= overRight;
+
+			// Adjust based on position and margin
+			} else {
+				position.left = max( position.left - collisionPosLeft, position.left );
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
+				outerHeight = data.within.height,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = withinOffset - collisionPosTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
+				newOverBottom;
+
+			// Element is taller than within
+			if ( data.collisionHeight > outerHeight ) {
+
+				// Element is initially over the top of within
+				if ( overTop > 0 && overBottom <= 0 ) {
+					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
+						withinOffset;
+					position.top += overTop - newOverBottom;
+
+				// Element is initially over bottom of within
+				} else if ( overBottom > 0 && overTop <= 0 ) {
+					position.top = withinOffset;
+
+				// Element is initially over both top and bottom of within
+				} else {
+					if ( overTop > overBottom ) {
+						position.top = withinOffset + outerHeight - data.collisionHeight;
+					} else {
+						position.top = withinOffset;
+					}
+				}
+
+			// Too far up -> align with top
+			} else if ( overTop > 0 ) {
+				position.top += overTop;
+
+			// Too far down -> align with bottom edge
+			} else if ( overBottom > 0 ) {
+				position.top -= overBottom;
+
+			// Adjust based on position and margin
+			} else {
+				position.top = max( position.top - collisionPosTop, position.top );
+			}
+		}
+	},
+	flip: {
+		left: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.left + within.scrollLeft,
+				outerWidth = within.width,
+				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
+				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
+				overLeft = collisionPosLeft - offsetLeft,
+				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
+				myOffset = data.my[ 0 ] === "left" ?
+					-data.elemWidth :
+					data.my[ 0 ] === "right" ?
+						data.elemWidth :
+						0,
+				atOffset = data.at[ 0 ] === "left" ?
+					data.targetWidth :
+					data.at[ 0 ] === "right" ?
+						-data.targetWidth :
+						0,
+				offset = -2 * data.offset[ 0 ],
+				newOverRight,
+				newOverLeft;
+
+			if ( overLeft < 0 ) {
+				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
+					outerWidth - withinOffset;
+				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			} else if ( overRight > 0 ) {
+				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
+					atOffset + offset - offsetLeft;
+				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
+					position.left += myOffset + atOffset + offset;
+				}
+			}
+		},
+		top: function( position, data ) {
+			var within = data.within,
+				withinOffset = within.offset.top + within.scrollTop,
+				outerHeight = within.height,
+				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
+				collisionPosTop = position.top - data.collisionPosition.marginTop,
+				overTop = collisionPosTop - offsetTop,
+				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
+				top = data.my[ 1 ] === "top",
+				myOffset = top ?
+					-data.elemHeight :
+					data.my[ 1 ] === "bottom" ?
+						data.elemHeight :
+						0,
+				atOffset = data.at[ 1 ] === "top" ?
+					data.targetHeight :
+					data.at[ 1 ] === "bottom" ?
+						-data.targetHeight :
+						0,
+				offset = -2 * data.offset[ 1 ],
+				newOverTop,
+				newOverBottom;
+			if ( overTop < 0 ) {
+				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
+					outerHeight - withinOffset;
+				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			} else if ( overBottom > 0 ) {
+				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
+					offset - offsetTop;
+				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
+					position.top += myOffset + atOffset + offset;
+				}
+			}
+		}
+	},
+	flipfit: {
+		left: function() {
+			$.ui.position.flip.left.apply( this, arguments );
+			$.ui.position.fit.left.apply( this, arguments );
+		},
+		top: function() {
+			$.ui.position.flip.top.apply( this, arguments );
+			$.ui.position.fit.top.apply( this, arguments );
+		}
+	}
+};
+
+} )();
+
+var position = $.ui.position;
+
+
+/*!
+ * jQuery UI :data 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: :data Selector
+//>>group: Core
+//>>description: Selects elements which have data stored under the specified key.
+//>>docs: http://api.jqueryui.com/data-selector/
+
+
+var data = $.extend( $.expr[ ":" ], {
+	data: $.expr.createPseudo ?
+		$.expr.createPseudo( function( dataName ) {
+			return function( elem ) {
+				return !!$.data( elem, dataName );
+			};
+		} ) :
+
+		// Support: jQuery <1.8
+		function( elem, i, match ) {
+			return !!$.data( elem, match[ 3 ] );
+		}
+} );
+
+/*!
+ * jQuery UI Disable Selection 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: disableSelection
+//>>group: Core
+//>>description: Disable selection of text content within the set of matched elements.
+//>>docs: http://api.jqueryui.com/disableSelection/
+
+// This file is deprecated
+
+
+var disableSelection = $.fn.extend( {
+	disableSelection: ( function() {
+		var eventType = "onselectstart" in document.createElement( "div" ) ?
+			"selectstart" :
+			"mousedown";
+
+		return function() {
+			return this.on( eventType + ".ui-disableSelection", function( event ) {
+				event.preventDefault();
+			} );
+		};
+	} )(),
+
+	enableSelection: function() {
+		return this.off( ".ui-disableSelection" );
+	}
+} );
+
+
+/*!
+ * jQuery UI Effects 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Effects Core
+//>>group: Effects
+// jscs:disable maximumLineLength
+//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/category/effects-core/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var dataSpace = "ui-effects-",
+	dataSpaceStyle = "ui-effects-style",
+	dataSpaceAnimated = "ui-effects-animated",
+
+	// Create a local jQuery because jQuery Color relies on it and the
+	// global may not exist with AMD and a custom build (#10199)
+	jQuery = $;
+
+$.effects = {
+	effect: {}
+};
+
+/*!
+ * jQuery Color Animations v2.1.2
+ * https://github.com/jquery/jquery-color
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
  *
- * http://docs.jquery.com/UI/Widget
+ * Date: Wed Jan 16 08:47:09 2013 -0600
  */
-(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
-a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
-e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
-this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
-widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
-enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
-;/*!
- * jQuery UI Mouse 1.8.14
+( function( jQuery, undefined ) {
+
+	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
+		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
+
+	// Plusequals test for += 100 -= 100
+	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
+
+	// A set of RE's that can match strings and generate color tuples.
+	stringParsers = [ {
+			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+			parse: function( execResult ) {
+				return [
+					execResult[ 1 ],
+					execResult[ 2 ],
+					execResult[ 3 ],
+					execResult[ 4 ]
+				];
+			}
+		}, {
+			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+			parse: function( execResult ) {
+				return [
+					execResult[ 1 ] * 2.55,
+					execResult[ 2 ] * 2.55,
+					execResult[ 3 ] * 2.55,
+					execResult[ 4 ]
+				];
+			}
+		}, {
+
+			// This regex ignores A-F because it's compared against an already lowercased string
+			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
+			parse: function( execResult ) {
+				return [
+					parseInt( execResult[ 1 ], 16 ),
+					parseInt( execResult[ 2 ], 16 ),
+					parseInt( execResult[ 3 ], 16 )
+				];
+			}
+		}, {
+
+			// This regex ignores A-F because it's compared against an already lowercased string
+			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
+			parse: function( execResult ) {
+				return [
+					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+				];
+			}
+		}, {
+			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+			space: "hsla",
+			parse: function( execResult ) {
+				return [
+					execResult[ 1 ],
+					execResult[ 2 ] / 100,
+					execResult[ 3 ] / 100,
+					execResult[ 4 ]
+				];
+			}
+		} ],
+
+	// JQuery.Color( )
+	color = jQuery.Color = function( color, green, blue, alpha ) {
+		return new jQuery.Color.fn.parse( color, green, blue, alpha );
+	},
+	spaces = {
+		rgba: {
+			props: {
+				red: {
+					idx: 0,
+					type: "byte"
+				},
+				green: {
+					idx: 1,
+					type: "byte"
+				},
+				blue: {
+					idx: 2,
+					type: "byte"
+				}
+			}
+		},
+
+		hsla: {
+			props: {
+				hue: {
+					idx: 0,
+					type: "degrees"
+				},
+				saturation: {
+					idx: 1,
+					type: "percent"
+				},
+				lightness: {
+					idx: 2,
+					type: "percent"
+				}
+			}
+		}
+	},
+	propTypes = {
+		"byte": {
+			floor: true,
+			max: 255
+		},
+		"percent": {
+			max: 1
+		},
+		"degrees": {
+			mod: 360,
+			floor: true
+		}
+	},
+	support = color.support = {},
+
+	// Element for support tests
+	supportElem = jQuery( "<p>" )[ 0 ],
+
+	// Colors = jQuery.Color.names
+	colors,
+
+	// Local aliases of functions called often
+	each = jQuery.each;
+
+// Determine rgba support immediately
+supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
+support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
+
+// Define cache name and alpha properties
+// for rgba and hsla spaces
+each( spaces, function( spaceName, space ) {
+	space.cache = "_" + spaceName;
+	space.props.alpha = {
+		idx: 3,
+		type: "percent",
+		def: 1
+	};
+} );
+
+function clamp( value, prop, allowEmpty ) {
+	var type = propTypes[ prop.type ] || {};
+
+	if ( value == null ) {
+		return ( allowEmpty || !prop.def ) ? null : prop.def;
+	}
+
+	// ~~ is an short way of doing floor for positive numbers
+	value = type.floor ? ~~value : parseFloat( value );
+
+	// IE will pass in empty strings as value for alpha,
+	// which will hit this case
+	if ( isNaN( value ) ) {
+		return prop.def;
+	}
+
+	if ( type.mod ) {
+
+		// We add mod before modding to make sure that negatives values
+		// get converted properly: -10 -> 350
+		return ( value + type.mod ) % type.mod;
+	}
+
+	// For now all property types without mod have min and max
+	return 0 > value ? 0 : type.max < value ? type.max : value;
+}
+
+function stringParse( string ) {
+	var inst = color(),
+		rgba = inst._rgba = [];
+
+	string = string.toLowerCase();
+
+	each( stringParsers, function( i, parser ) {
+		var parsed,
+			match = parser.re.exec( string ),
+			values = match && parser.parse( match ),
+			spaceName = parser.space || "rgba";
+
+		if ( values ) {
+			parsed = inst[ spaceName ]( values );
+
+			// If this was an rgba parse the assignment might happen twice
+			// oh well....
+			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
+			rgba = inst._rgba = parsed._rgba;
+
+			// Exit each( stringParsers ) here because we matched
+			return false;
+		}
+	} );
+
+	// Found a stringParser that handled it
+	if ( rgba.length ) {
+
+		// If this came from a parsed string, force "transparent" when alpha is 0
+		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
+		if ( rgba.join() === "0,0,0,0" ) {
+			jQuery.extend( rgba, colors.transparent );
+		}
+		return inst;
+	}
+
+	// Named colors
+	return colors[ string ];
+}
+
+color.fn = jQuery.extend( color.prototype, {
+	parse: function( red, green, blue, alpha ) {
+		if ( red === undefined ) {
+			this._rgba = [ null, null, null, null ];
+			return this;
+		}
+		if ( red.jquery || red.nodeType ) {
+			red = jQuery( red ).css( green );
+			green = undefined;
+		}
+
+		var inst = this,
+			type = jQuery.type( red ),
+			rgba = this._rgba = [];
+
+		// More than 1 argument specified - assume ( red, green, blue, alpha )
+		if ( green !== undefined ) {
+			red = [ red, green, blue, alpha ];
+			type = "array";
+		}
+
+		if ( type === "string" ) {
+			return this.parse( stringParse( red ) || colors._default );
+		}
+
+		if ( type === "array" ) {
+			each( spaces.rgba.props, function( key, prop ) {
+				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
+			} );
+			return this;
+		}
+
+		if ( type === "object" ) {
+			if ( red instanceof color ) {
+				each( spaces, function( spaceName, space ) {
+					if ( red[ space.cache ] ) {
+						inst[ space.cache ] = red[ space.cache ].slice();
+					}
+				} );
+			} else {
+				each( spaces, function( spaceName, space ) {
+					var cache = space.cache;
+					each( space.props, function( key, prop ) {
+
+						// If the cache doesn't exist, and we know how to convert
+						if ( !inst[ cache ] && space.to ) {
+
+							// If the value was null, we don't need to copy it
+							// if the key was alpha, we don't need to copy it either
+							if ( key === "alpha" || red[ key ] == null ) {
+								return;
+							}
+							inst[ cache ] = space.to( inst._rgba );
+						}
+
+						// This is the only case where we allow nulls for ALL properties.
+						// call clamp with alwaysAllowEmpty
+						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
+					} );
+
+					// Everything defined but alpha?
+					if ( inst[ cache ] &&
+							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
+
+						// Use the default of 1
+						inst[ cache ][ 3 ] = 1;
+						if ( space.from ) {
+							inst._rgba = space.from( inst[ cache ] );
+						}
+					}
+				} );
+			}
+			return this;
+		}
+	},
+	is: function( compare ) {
+		var is = color( compare ),
+			same = true,
+			inst = this;
+
+		each( spaces, function( _, space ) {
+			var localCache,
+				isCache = is[ space.cache ];
+			if ( isCache ) {
+				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
+				each( space.props, function( _, prop ) {
+					if ( isCache[ prop.idx ] != null ) {
+						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
+						return same;
+					}
+				} );
+			}
+			return same;
+		} );
+		return same;
+	},
+	_space: function() {
+		var used = [],
+			inst = this;
+		each( spaces, function( spaceName, space ) {
+			if ( inst[ space.cache ] ) {
+				used.push( spaceName );
+			}
+		} );
+		return used.pop();
+	},
+	transition: function( other, distance ) {
+		var end = color( other ),
+			spaceName = end._space(),
+			space = spaces[ spaceName ],
+			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
+			start = startColor[ space.cache ] || space.to( startColor._rgba ),
+			result = start.slice();
+
+		end = end[ space.cache ];
+		each( space.props, function( key, prop ) {
+			var index = prop.idx,
+				startValue = start[ index ],
+				endValue = end[ index ],
+				type = propTypes[ prop.type ] || {};
+
+			// If null, don't override start value
+			if ( endValue === null ) {
+				return;
+			}
+
+			// If null - use end
+			if ( startValue === null ) {
+				result[ index ] = endValue;
+			} else {
+				if ( type.mod ) {
+					if ( endValue - startValue > type.mod / 2 ) {
+						startValue += type.mod;
+					} else if ( startValue - endValue > type.mod / 2 ) {
+						startValue -= type.mod;
+					}
+				}
+				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
+			}
+		} );
+		return this[ spaceName ]( result );
+	},
+	blend: function( opaque ) {
+
+		// If we are already opaque - return ourself
+		if ( this._rgba[ 3 ] === 1 ) {
+			return this;
+		}
+
+		var rgb = this._rgba.slice(),
+			a = rgb.pop(),
+			blend = color( opaque )._rgba;
+
+		return color( jQuery.map( rgb, function( v, i ) {
+			return ( 1 - a ) * blend[ i ] + a * v;
+		} ) );
+	},
+	toRgbaString: function() {
+		var prefix = "rgba(",
+			rgba = jQuery.map( this._rgba, function( v, i ) {
+				return v == null ? ( i > 2 ? 1 : 0 ) : v;
+			} );
+
+		if ( rgba[ 3 ] === 1 ) {
+			rgba.pop();
+			prefix = "rgb(";
+		}
+
+		return prefix + rgba.join() + ")";
+	},
+	toHslaString: function() {
+		var prefix = "hsla(",
+			hsla = jQuery.map( this.hsla(), function( v, i ) {
+				if ( v == null ) {
+					v = i > 2 ? 1 : 0;
+				}
+
+				// Catch 1 and 2
+				if ( i && i < 3 ) {
+					v = Math.round( v * 100 ) + "%";
+				}
+				return v;
+			} );
+
+		if ( hsla[ 3 ] === 1 ) {
+			hsla.pop();
+			prefix = "hsl(";
+		}
+		return prefix + hsla.join() + ")";
+	},
+	toHexString: function( includeAlpha ) {
+		var rgba = this._rgba.slice(),
+			alpha = rgba.pop();
+
+		if ( includeAlpha ) {
+			rgba.push( ~~( alpha * 255 ) );
+		}
+
+		return "#" + jQuery.map( rgba, function( v ) {
+
+			// Default to 0 when nulls exist
+			v = ( v || 0 ).toString( 16 );
+			return v.length === 1 ? "0" + v : v;
+		} ).join( "" );
+	},
+	toString: function() {
+		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
+	}
+} );
+color.fn.parse.prototype = color.fn;
+
+// Hsla conversions adapted from:
+// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
+
+function hue2rgb( p, q, h ) {
+	h = ( h + 1 ) % 1;
+	if ( h * 6 < 1 ) {
+		return p + ( q - p ) * h * 6;
+	}
+	if ( h * 2 < 1 ) {
+		return q;
+	}
+	if ( h * 3 < 2 ) {
+		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
+	}
+	return p;
+}
+
+spaces.hsla.to = function( rgba ) {
+	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
+		return [ null, null, null, rgba[ 3 ] ];
+	}
+	var r = rgba[ 0 ] / 255,
+		g = rgba[ 1 ] / 255,
+		b = rgba[ 2 ] / 255,
+		a = rgba[ 3 ],
+		max = Math.max( r, g, b ),
+		min = Math.min( r, g, b ),
+		diff = max - min,
+		add = max + min,
+		l = add * 0.5,
+		h, s;
+
+	if ( min === max ) {
+		h = 0;
+	} else if ( r === max ) {
+		h = ( 60 * ( g - b ) / diff ) + 360;
+	} else if ( g === max ) {
+		h = ( 60 * ( b - r ) / diff ) + 120;
+	} else {
+		h = ( 60 * ( r - g ) / diff ) + 240;
+	}
+
+	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
+	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
+	if ( diff === 0 ) {
+		s = 0;
+	} else if ( l <= 0.5 ) {
+		s = diff / add;
+	} else {
+		s = diff / ( 2 - add );
+	}
+	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
+};
+
+spaces.hsla.from = function( hsla ) {
+	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
+		return [ null, null, null, hsla[ 3 ] ];
+	}
+	var h = hsla[ 0 ] / 360,
+		s = hsla[ 1 ],
+		l = hsla[ 2 ],
+		a = hsla[ 3 ],
+		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
+		p = 2 * l - q;
+
+	return [
+		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
+		Math.round( hue2rgb( p, q, h ) * 255 ),
+		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
+		a
+	];
+};
+
+each( spaces, function( spaceName, space ) {
+	var props = space.props,
+		cache = space.cache,
+		to = space.to,
+		from = space.from;
+
+	// Makes rgba() and hsla()
+	color.fn[ spaceName ] = function( value ) {
+
+		// Generate a cache for this space if it doesn't exist
+		if ( to && !this[ cache ] ) {
+			this[ cache ] = to( this._rgba );
+		}
+		if ( value === undefined ) {
+			return this[ cache ].slice();
+		}
+
+		var ret,
+			type = jQuery.type( value ),
+			arr = ( type === "array" || type === "object" ) ? value : arguments,
+			local = this[ cache ].slice();
+
+		each( props, function( key, prop ) {
+			var val = arr[ type === "object" ? key : prop.idx ];
+			if ( val == null ) {
+				val = local[ prop.idx ];
+			}
+			local[ prop.idx ] = clamp( val, prop );
+		} );
+
+		if ( from ) {
+			ret = color( from( local ) );
+			ret[ cache ] = local;
+			return ret;
+		} else {
+			return color( local );
+		}
+	};
+
+	// Makes red() green() blue() alpha() hue() saturation() lightness()
+	each( props, function( key, prop ) {
+
+		// Alpha is included in more than one space
+		if ( color.fn[ key ] ) {
+			return;
+		}
+		color.fn[ key ] = function( value ) {
+			var vtype = jQuery.type( value ),
+				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
+				local = this[ fn ](),
+				cur = local[ prop.idx ],
+				match;
+
+			if ( vtype === "undefined" ) {
+				return cur;
+			}
+
+			if ( vtype === "function" ) {
+				value = value.call( this, cur );
+				vtype = jQuery.type( value );
+			}
+			if ( value == null && prop.empty ) {
+				return this;
+			}
+			if ( vtype === "string" ) {
+				match = rplusequals.exec( value );
+				if ( match ) {
+					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
+				}
+			}
+			local[ prop.idx ] = value;
+			return this[ fn ]( local );
+		};
+	} );
+} );
+
+// Add cssHook and .fx.step function for each named hook.
+// accept a space separated string of properties
+color.hook = function( hook ) {
+	var hooks = hook.split( " " );
+	each( hooks, function( i, hook ) {
+		jQuery.cssHooks[ hook ] = {
+			set: function( elem, value ) {
+				var parsed, curElem,
+					backgroundColor = "";
+
+				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
+						( parsed = stringParse( value ) ) ) ) {
+					value = color( parsed || value );
+					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
+						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
+						while (
+							( backgroundColor === "" || backgroundColor === "transparent" ) &&
+							curElem && curElem.style
+						) {
+							try {
+								backgroundColor = jQuery.css( curElem, "backgroundColor" );
+								curElem = curElem.parentNode;
+							} catch ( e ) {
+							}
+						}
+
+						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
+							backgroundColor :
+							"_default" );
+					}
+
+					value = value.toRgbaString();
+				}
+				try {
+					elem.style[ hook ] = value;
+				} catch ( e ) {
+
+					// Wrapped to prevent IE from throwing errors on "invalid" values like
+					// 'auto' or 'inherit'
+				}
+			}
+		};
+		jQuery.fx.step[ hook ] = function( fx ) {
+			if ( !fx.colorInit ) {
+				fx.start = color( fx.elem, hook );
+				fx.end = color( fx.end );
+				fx.colorInit = true;
+			}
+			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
+		};
+	} );
+
+};
+
+color.hook( stepHooks );
+
+jQuery.cssHooks.borderColor = {
+	expand: function( value ) {
+		var expanded = {};
+
+		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
+			expanded[ "border" + part + "Color" ] = value;
+		} );
+		return expanded;
+	}
+};
+
+// Basic color names only.
+// Usage of any of the other color names requires adding yourself or including
+// jquery.color.svg-names.js.
+colors = jQuery.Color.names = {
+
+	// 4.1. Basic color keywords
+	aqua: "#00ffff",
+	black: "#000000",
+	blue: "#0000ff",
+	fuchsia: "#ff00ff",
+	gray: "#808080",
+	green: "#008000",
+	lime: "#00ff00",
+	maroon: "#800000",
+	navy: "#000080",
+	olive: "#808000",
+	purple: "#800080",
+	red: "#ff0000",
+	silver: "#c0c0c0",
+	teal: "#008080",
+	white: "#ffffff",
+	yellow: "#ffff00",
+
+	// 4.2.3. "transparent" color keyword
+	transparent: [ null, null, null, 0 ],
+
+	_default: "#ffffff"
+};
+
+} )( jQuery );
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+( function() {
+
+var classAnimationActions = [ "add", "remove", "toggle" ],
+	shorthandStyles = {
+		border: 1,
+		borderBottom: 1,
+		borderColor: 1,
+		borderLeft: 1,
+		borderRight: 1,
+		borderTop: 1,
+		borderWidth: 1,
+		margin: 1,
+		padding: 1
+	};
+
+$.each(
+	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
+	function( _, prop ) {
+		$.fx.step[ prop ] = function( fx ) {
+			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
+				jQuery.style( fx.elem, prop, fx.end );
+				fx.setAttr = true;
+			}
+		};
+	}
+);
+
+function getElementStyles( elem ) {
+	var key, len,
+		style = elem.ownerDocument.defaultView ?
+			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+			elem.currentStyle,
+		styles = {};
+
+	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
+		len = style.length;
+		while ( len-- ) {
+			key = style[ len ];
+			if ( typeof style[ key ] === "string" ) {
+				styles[ $.camelCase( key ) ] = style[ key ];
+			}
+		}
+
+	// Support: Opera, IE <9
+	} else {
+		for ( key in style ) {
+			if ( typeof style[ key ] === "string" ) {
+				styles[ key ] = style[ key ];
+			}
+		}
+	}
+
+	return styles;
+}
+
+function styleDifference( oldStyle, newStyle ) {
+	var diff = {},
+		name, value;
+
+	for ( name in newStyle ) {
+		value = newStyle[ name ];
+		if ( oldStyle[ name ] !== value ) {
+			if ( !shorthandStyles[ name ] ) {
+				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
+					diff[ name ] = value;
+				}
+			}
+		}
+	}
+
+	return diff;
+}
+
+// Support: jQuery <1.8
+if ( !$.fn.addBack ) {
+	$.fn.addBack = function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	};
+}
+
+$.effects.animateClass = function( value, duration, easing, callback ) {
+	var o = $.speed( duration, easing, callback );
+
+	return this.queue( function() {
+		var animated = $( this ),
+			baseClass = animated.attr( "class" ) || "",
+			applyClassChange,
+			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
+
+		// Map the animated objects to store the original styles.
+		allAnimations = allAnimations.map( function() {
+			var el = $( this );
+			return {
+				el: el,
+				start: getElementStyles( this )
+			};
+		} );
+
+		// Apply class change
+		applyClassChange = function() {
+			$.each( classAnimationActions, function( i, action ) {
+				if ( value[ action ] ) {
+					animated[ action + "Class" ]( value[ action ] );
+				}
+			} );
+		};
+		applyClassChange();
+
+		// Map all animated objects again - calculate new styles and diff
+		allAnimations = allAnimations.map( function() {
+			this.end = getElementStyles( this.el[ 0 ] );
+			this.diff = styleDifference( this.start, this.end );
+			return this;
+		} );
+
+		// Apply original class
+		animated.attr( "class", baseClass );
+
+		// Map all animated objects again - this time collecting a promise
+		allAnimations = allAnimations.map( function() {
+			var styleInfo = this,
+				dfd = $.Deferred(),
+				opts = $.extend( {}, o, {
+					queue: false,
+					complete: function() {
+						dfd.resolve( styleInfo );
+					}
+				} );
+
+			this.el.animate( this.diff, opts );
+			return dfd.promise();
+		} );
+
+		// Once all animations have completed:
+		$.when.apply( $, allAnimations.get() ).done( function() {
+
+			// Set the final class
+			applyClassChange();
+
+			// For each animated element,
+			// clear all css properties that were animated
+			$.each( arguments, function() {
+				var el = this.el;
+				$.each( this.diff, function( key ) {
+					el.css( key, "" );
+				} );
+			} );
+
+			// This is guarnteed to be there if you use jQuery.speed()
+			// it also handles dequeuing the next anim...
+			o.complete.call( animated[ 0 ] );
+		} );
+	} );
+};
+
+$.fn.extend( {
+	addClass: ( function( orig ) {
+		return function( classNames, speed, easing, callback ) {
+			return speed ?
+				$.effects.animateClass.call( this,
+					{ add: classNames }, speed, easing, callback ) :
+				orig.apply( this, arguments );
+		};
+	} )( $.fn.addClass ),
+
+	removeClass: ( function( orig ) {
+		return function( classNames, speed, easing, callback ) {
+			return arguments.length > 1 ?
+				$.effects.animateClass.call( this,
+					{ remove: classNames }, speed, easing, callback ) :
+				orig.apply( this, arguments );
+		};
+	} )( $.fn.removeClass ),
+
+	toggleClass: ( function( orig ) {
+		return function( classNames, force, speed, easing, callback ) {
+			if ( typeof force === "boolean" || force === undefined ) {
+				if ( !speed ) {
+
+					// Without speed parameter
+					return orig.apply( this, arguments );
+				} else {
+					return $.effects.animateClass.call( this,
+						( force ? { add: classNames } : { remove: classNames } ),
+						speed, easing, callback );
+				}
+			} else {
+
+				// Without force parameter
+				return $.effects.animateClass.call( this,
+					{ toggle: classNames }, force, speed, easing );
+			}
+		};
+	} )( $.fn.toggleClass ),
+
+	switchClass: function( remove, add, speed, easing, callback ) {
+		return $.effects.animateClass.call( this, {
+			add: add,
+			remove: remove
+		}, speed, easing, callback );
+	}
+} );
+
+} )();
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+( function() {
+
+if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
+	$.expr.filters.animated = ( function( orig ) {
+		return function( elem ) {
+			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
+		};
+	} )( $.expr.filters.animated );
+}
+
+if ( $.uiBackCompat !== false ) {
+	$.extend( $.effects, {
+
+		// Saves a set of properties in a data storage
+		save: function( element, set ) {
+			var i = 0, length = set.length;
+			for ( ; i < length; i++ ) {
+				if ( set[ i ] !== null ) {
+					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
+				}
+			}
+		},
+
+		// Restores a set of previously saved properties from a data storage
+		restore: function( element, set ) {
+			var val, i = 0, length = set.length;
+			for ( ; i < length; i++ ) {
+				if ( set[ i ] !== null ) {
+					val = element.data( dataSpace + set[ i ] );
+					element.css( set[ i ], val );
+				}
+			}
+		},
+
+		setMode: function( el, mode ) {
+			if ( mode === "toggle" ) {
+				mode = el.is( ":hidden" ) ? "show" : "hide";
+			}
+			return mode;
+		},
+
+		// Wraps the element around a wrapper that copies position properties
+		createWrapper: function( element ) {
+
+			// If the element is already wrapped, return it
+			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+				return element.parent();
+			}
+
+			// Wrap the element
+			var props = {
+					width: element.outerWidth( true ),
+					height: element.outerHeight( true ),
+					"float": element.css( "float" )
+				},
+				wrapper = $( "<div></div>" )
+					.addClass( "ui-effects-wrapper" )
+					.css( {
+						fontSize: "100%",
+						background: "transparent",
+						border: "none",
+						margin: 0,
+						padding: 0
+					} ),
+
+				// Store the size in case width/height are defined in % - Fixes #5245
+				size = {
+					width: element.width(),
+					height: element.height()
+				},
+				active = document.activeElement;
+
+			// Support: Firefox
+			// Firefox incorrectly exposes anonymous content
+			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
+			try {
+				active.id;
+			} catch ( e ) {
+				active = document.body;
+			}
+
+			element.wrap( wrapper );
+
+			// Fixes #7595 - Elements lose focus when wrapped.
+			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+				$( active ).trigger( "focus" );
+			}
+
+			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
+			// lose the reference to the wrapped element
+			wrapper = element.parent();
+
+			// Transfer positioning properties to the wrapper
+			if ( element.css( "position" ) === "static" ) {
+				wrapper.css( { position: "relative" } );
+				element.css( { position: "relative" } );
+			} else {
+				$.extend( props, {
+					position: element.css( "position" ),
+					zIndex: element.css( "z-index" )
+				} );
+				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
+					props[ pos ] = element.css( pos );
+					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
+						props[ pos ] = "auto";
+					}
+				} );
+				element.css( {
+					position: "relative",
+					top: 0,
+					left: 0,
+					right: "auto",
+					bottom: "auto"
+				} );
+			}
+			element.css( size );
+
+			return wrapper.css( props ).show();
+		},
+
+		removeWrapper: function( element ) {
+			var active = document.activeElement;
+
+			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+				element.parent().replaceWith( element );
+
+				// Fixes #7595 - Elements lose focus when wrapped.
+				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+					$( active ).trigger( "focus" );
+				}
+			}
+
+			return element;
+		}
+	} );
+}
+
+$.extend( $.effects, {
+	version: "1.12.1",
+
+	define: function( name, mode, effect ) {
+		if ( !effect ) {
+			effect = mode;
+			mode = "effect";
+		}
+
+		$.effects.effect[ name ] = effect;
+		$.effects.effect[ name ].mode = mode;
+
+		return effect;
+	},
+
+	scaledDimensions: function( element, percent, direction ) {
+		if ( percent === 0 ) {
+			return {
+				height: 0,
+				width: 0,
+				outerHeight: 0,
+				outerWidth: 0
+			};
+		}
+
+		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
+			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
+
+		return {
+			height: element.height() * y,
+			width: element.width() * x,
+			outerHeight: element.outerHeight() * y,
+			outerWidth: element.outerWidth() * x
+		};
+
+	},
+
+	clipToBox: function( animation ) {
+		return {
+			width: animation.clip.right - animation.clip.left,
+			height: animation.clip.bottom - animation.clip.top,
+			left: animation.clip.left,
+			top: animation.clip.top
+		};
+	},
+
+	// Injects recently queued functions to be first in line (after "inprogress")
+	unshift: function( element, queueLength, count ) {
+		var queue = element.queue();
+
+		if ( queueLength > 1 ) {
+			queue.splice.apply( queue,
+				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
+		}
+		element.dequeue();
+	},
+
+	saveStyle: function( element ) {
+		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
+	},
+
+	restoreStyle: function( element ) {
+		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
+		element.removeData( dataSpaceStyle );
+	},
+
+	mode: function( element, mode ) {
+		var hidden = element.is( ":hidden" );
+
+		if ( mode === "toggle" ) {
+			mode = hidden ? "show" : "hide";
+		}
+		if ( hidden ? mode === "hide" : mode === "show" ) {
+			mode = "none";
+		}
+		return mode;
+	},
+
+	// Translates a [top,left] array into a baseline value
+	getBaseline: function( origin, original ) {
+		var y, x;
+
+		switch ( origin[ 0 ] ) {
+		case "top":
+			y = 0;
+			break;
+		case "middle":
+			y = 0.5;
+			break;
+		case "bottom":
+			y = 1;
+			break;
+		default:
+			y = origin[ 0 ] / original.height;
+		}
+
+		switch ( origin[ 1 ] ) {
+		case "left":
+			x = 0;
+			break;
+		case "center":
+			x = 0.5;
+			break;
+		case "right":
+			x = 1;
+			break;
+		default:
+			x = origin[ 1 ] / original.width;
+		}
+
+		return {
+			x: x,
+			y: y
+		};
+	},
+
+	// Creates a placeholder element so that the original element can be made absolute
+	createPlaceholder: function( element ) {
+		var placeholder,
+			cssPosition = element.css( "position" ),
+			position = element.position();
+
+		// Lock in margins first to account for form elements, which
+		// will change margin if you explicitly set height
+		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
+		// Support: Safari
+		element.css( {
+			marginTop: element.css( "marginTop" ),
+			marginBottom: element.css( "marginBottom" ),
+			marginLeft: element.css( "marginLeft" ),
+			marginRight: element.css( "marginRight" )
+		} )
+		.outerWidth( element.outerWidth() )
+		.outerHeight( element.outerHeight() );
+
+		if ( /^(static|relative)/.test( cssPosition ) ) {
+			cssPosition = "absolute";
+
+			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
+
+				// Convert inline to inline block to account for inline elements
+				// that turn to inline block based on content (like img)
+				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
+					"inline-block" :
+					"block",
+				visibility: "hidden",
+
+				// Margins need to be set to account for margin collapse
+				marginTop: element.css( "marginTop" ),
+				marginBottom: element.css( "marginBottom" ),
+				marginLeft: element.css( "marginLeft" ),
+				marginRight: element.css( "marginRight" ),
+				"float": element.css( "float" )
+			} )
+			.outerWidth( element.outerWidth() )
+			.outerHeight( element.outerHeight() )
+			.addClass( "ui-effects-placeholder" );
+
+			element.data( dataSpace + "placeholder", placeholder );
+		}
+
+		element.css( {
+			position: cssPosition,
+			left: position.left,
+			top: position.top
+		} );
+
+		return placeholder;
+	},
+
+	removePlaceholder: function( element ) {
+		var dataKey = dataSpace + "placeholder",
+				placeholder = element.data( dataKey );
+
+		if ( placeholder ) {
+			placeholder.remove();
+			element.removeData( dataKey );
+		}
+	},
+
+	// Removes a placeholder if it exists and restores
+	// properties that were modified during placeholder creation
+	cleanUp: function( element ) {
+		$.effects.restoreStyle( element );
+		$.effects.removePlaceholder( element );
+	},
+
+	setTransition: function( element, list, factor, value ) {
+		value = value || {};
+		$.each( list, function( i, x ) {
+			var unit = element.cssUnit( x );
+			if ( unit[ 0 ] > 0 ) {
+				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
+			}
+		} );
+		return value;
+	}
+} );
+
+// Return an effect options object for the given parameters:
+function _normalizeArguments( effect, options, speed, callback ) {
+
+	// Allow passing all options as the first parameter
+	if ( $.isPlainObject( effect ) ) {
+		options = effect;
+		effect = effect.effect;
+	}
+
+	// Convert to an object
+	effect = { effect: effect };
+
+	// Catch (effect, null, ...)
+	if ( options == null ) {
+		options = {};
+	}
+
+	// Catch (effect, callback)
+	if ( $.isFunction( options ) ) {
+		callback = options;
+		speed = null;
+		options = {};
+	}
+
+	// Catch (effect, speed, ?)
+	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
+		callback = speed;
+		speed = options;
+		options = {};
+	}
+
+	// Catch (effect, options, callback)
+	if ( $.isFunction( speed ) ) {
+		callback = speed;
+		speed = null;
+	}
+
+	// Add options to effect
+	if ( options ) {
+		$.extend( effect, options );
+	}
+
+	speed = speed || options.duration;
+	effect.duration = $.fx.off ? 0 :
+		typeof speed === "number" ? speed :
+		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
+		$.fx.speeds._default;
+
+	effect.complete = callback || options.complete;
+
+	return effect;
+}
+
+function standardAnimationOption( option ) {
+
+	// Valid standard speeds (nothing, number, named speed)
+	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
+		return true;
+	}
+
+	// Invalid strings - treat as "normal" speed
+	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
+		return true;
+	}
+
+	// Complete callback
+	if ( $.isFunction( option ) ) {
+		return true;
+	}
+
+	// Options hash (but not naming an effect)
+	if ( typeof option === "object" && !option.effect ) {
+		return true;
+	}
+
+	// Didn't match any standard API
+	return false;
+}
+
+$.fn.extend( {
+	effect: function( /* effect, options, speed, callback */ ) {
+		var args = _normalizeArguments.apply( this, arguments ),
+			effectMethod = $.effects.effect[ args.effect ],
+			defaultMode = effectMethod.mode,
+			queue = args.queue,
+			queueName = queue || "fx",
+			complete = args.complete,
+			mode = args.mode,
+			modes = [],
+			prefilter = function( next ) {
+				var el = $( this ),
+					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
+
+				// Sentinel for duck-punching the :animated psuedo-selector
+				el.data( dataSpaceAnimated, true );
+
+				// Save effect mode for later use,
+				// we can't just call $.effects.mode again later,
+				// as the .show() below destroys the initial state
+				modes.push( normalizedMode );
+
+				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
+				if ( defaultMode && ( normalizedMode === "show" ||
+						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
+					el.show();
+				}
+
+				if ( !defaultMode || normalizedMode !== "none" ) {
+					$.effects.saveStyle( el );
+				}
+
+				if ( $.isFunction( next ) ) {
+					next();
+				}
+			};
+
+		if ( $.fx.off || !effectMethod ) {
+
+			// Delegate to the original method (e.g., .show()) if possible
+			if ( mode ) {
+				return this[ mode ]( args.duration, complete );
+			} else {
+				return this.each( function() {
+					if ( complete ) {
+						complete.call( this );
+					}
+				} );
+			}
+		}
+
+		function run( next ) {
+			var elem = $( this );
+
+			function cleanup() {
+				elem.removeData( dataSpaceAnimated );
+
+				$.effects.cleanUp( elem );
+
+				if ( args.mode === "hide" ) {
+					elem.hide();
+				}
+
+				done();
+			}
+
+			function done() {
+				if ( $.isFunction( complete ) ) {
+					complete.call( elem[ 0 ] );
+				}
+
+				if ( $.isFunction( next ) ) {
+					next();
+				}
+			}
+
+			// Override mode option on a per element basis,
+			// as toggle can be either show or hide depending on element state
+			args.mode = modes.shift();
+
+			if ( $.uiBackCompat !== false && !defaultMode ) {
+				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
+
+					// Call the core method to track "olddisplay" properly
+					elem[ mode ]();
+					done();
+				} else {
+					effectMethod.call( elem[ 0 ], args, done );
+				}
+			} else {
+				if ( args.mode === "none" ) {
+
+					// Call the core method to track "olddisplay" properly
+					elem[ mode ]();
+					done();
+				} else {
+					effectMethod.call( elem[ 0 ], args, cleanup );
+				}
+			}
+		}
+
+		// Run prefilter on all elements first to ensure that
+		// any showing or hiding happens before placeholder creation,
+		// which ensures that any layout changes are correctly captured.
+		return queue === false ?
+			this.each( prefilter ).each( run ) :
+			this.queue( queueName, prefilter ).queue( queueName, run );
+	},
+
+	show: ( function( orig ) {
+		return function( option ) {
+			if ( standardAnimationOption( option ) ) {
+				return orig.apply( this, arguments );
+			} else {
+				var args = _normalizeArguments.apply( this, arguments );
+				args.mode = "show";
+				return this.effect.call( this, args );
+			}
+		};
+	} )( $.fn.show ),
+
+	hide: ( function( orig ) {
+		return function( option ) {
+			if ( standardAnimationOption( option ) ) {
+				return orig.apply( this, arguments );
+			} else {
+				var args = _normalizeArguments.apply( this, arguments );
+				args.mode = "hide";
+				return this.effect.call( this, args );
+			}
+		};
+	} )( $.fn.hide ),
+
+	toggle: ( function( orig ) {
+		return function( option ) {
+			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
+				return orig.apply( this, arguments );
+			} else {
+				var args = _normalizeArguments.apply( this, arguments );
+				args.mode = "toggle";
+				return this.effect.call( this, args );
+			}
+		};
+	} )( $.fn.toggle ),
+
+	cssUnit: function( key ) {
+		var style = this.css( key ),
+			val = [];
+
+		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
+			if ( style.indexOf( unit ) > 0 ) {
+				val = [ parseFloat( style ), unit ];
+			}
+		} );
+		return val;
+	},
+
+	cssClip: function( clipObj ) {
+		if ( clipObj ) {
+			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
+				clipObj.bottom + "px " + clipObj.left + "px)" );
+		}
+		return parseClip( this.css( "clip" ), this );
+	},
+
+	transfer: function( options, done ) {
+		var element = $( this ),
+			target = $( options.to ),
+			targetFixed = target.css( "position" ) === "fixed",
+			body = $( "body" ),
+			fixTop = targetFixed ? body.scrollTop() : 0,
+			fixLeft = targetFixed ? body.scrollLeft() : 0,
+			endPosition = target.offset(),
+			animation = {
+				top: endPosition.top - fixTop,
+				left: endPosition.left - fixLeft,
+				height: target.innerHeight(),
+				width: target.innerWidth()
+			},
+			startPosition = element.offset(),
+			transfer = $( "<div class='ui-effects-transfer'></div>" )
+				.appendTo( "body" )
+				.addClass( options.className )
+				.css( {
+					top: startPosition.top - fixTop,
+					left: startPosition.left - fixLeft,
+					height: element.innerHeight(),
+					width: element.innerWidth(),
+					position: targetFixed ? "fixed" : "absolute"
+				} )
+				.animate( animation, options.duration, options.easing, function() {
+					transfer.remove();
+					if ( $.isFunction( done ) ) {
+						done();
+					}
+				} );
+	}
+} );
+
+function parseClip( str, element ) {
+		var outerWidth = element.outerWidth(),
+			outerHeight = element.outerHeight(),
+			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
+			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
+
+		return {
+			top: parseFloat( values[ 1 ] ) || 0,
+			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
+			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
+			left: parseFloat( values[ 4 ] ) || 0
+		};
+}
+
+$.fx.step.clip = function( fx ) {
+	if ( !fx.clipInit ) {
+		fx.start = $( fx.elem ).cssClip();
+		if ( typeof fx.end === "string" ) {
+			fx.end = parseClip( fx.end, fx.elem );
+		}
+		fx.clipInit = true;
+	}
+
+	$( fx.elem ).cssClip( {
+		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
+		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
+		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
+		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
+	} );
+};
+
+} )();
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+( function() {
+
+// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
+
+var baseEasings = {};
+
+$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
+	baseEasings[ name ] = function( p ) {
+		return Math.pow( p, i + 2 );
+	};
+} );
+
+$.extend( baseEasings, {
+	Sine: function( p ) {
+		return 1 - Math.cos( p * Math.PI / 2 );
+	},
+	Circ: function( p ) {
+		return 1 - Math.sqrt( 1 - p * p );
+	},
+	Elastic: function( p ) {
+		return p === 0 || p === 1 ? p :
+			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
+	},
+	Back: function( p ) {
+		return p * p * ( 3 * p - 2 );
+	},
+	Bounce: function( p ) {
+		var pow2,
+			bounce = 4;
+
+		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
+		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
+	}
+} );
+
+$.each( baseEasings, function( name, easeIn ) {
+	$.easing[ "easeIn" + name ] = easeIn;
+	$.easing[ "easeOut" + name ] = function( p ) {
+		return 1 - easeIn( 1 - p );
+	};
+	$.easing[ "easeInOut" + name ] = function( p ) {
+		return p < 0.5 ?
+			easeIn( p * 2 ) / 2 :
+			1 - easeIn( p * -2 + 2 ) / 2;
+	};
+} );
+
+} )();
+
+var effect = $.effects;
+
+
+/*!
+ * jQuery UI Effects Blind 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Blind Effect
+//>>group: Effects
+//>>description: Blinds the element.
+//>>docs: http://api.jqueryui.com/blind-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
+	var map = {
+			up: [ "bottom", "top" ],
+			vertical: [ "bottom", "top" ],
+			down: [ "top", "bottom" ],
+			left: [ "right", "left" ],
+			horizontal: [ "right", "left" ],
+			right: [ "left", "right" ]
+		},
+		element = $( this ),
+		direction = options.direction || "up",
+		start = element.cssClip(),
+		animate = { clip: $.extend( {}, start ) },
+		placeholder = $.effects.createPlaceholder( element );
+
+	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
+
+	if ( options.mode === "show" ) {
+		element.cssClip( animate.clip );
+		if ( placeholder ) {
+			placeholder.css( $.effects.clipToBox( animate ) );
+		}
+
+		animate.clip = start;
+	}
+
+	if ( placeholder ) {
+		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
+	}
+
+	element.animate( animate, {
+		queue: false,
+		duration: options.duration,
+		easing: options.easing,
+		complete: done
+	} );
+} );
+
+
+/*!
+ * jQuery UI Effects Bounce 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Bounce Effect
+//>>group: Effects
+//>>description: Bounces an element horizontally or vertically n times.
+//>>docs: http://api.jqueryui.com/bounce-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
+	var upAnim, downAnim, refValue,
+		element = $( this ),
+
+		// Defaults:
+		mode = options.mode,
+		hide = mode === "hide",
+		show = mode === "show",
+		direction = options.direction || "up",
+		distance = options.distance,
+		times = options.times || 5,
+
+		// Number of internal animations
+		anims = times * 2 + ( show || hide ? 1 : 0 ),
+		speed = options.duration / anims,
+		easing = options.easing,
+
+		// Utility:
+		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+		motion = ( direction === "up" || direction === "left" ),
+		i = 0,
+
+		queuelen = element.queue().length;
+
+	$.effects.createPlaceholder( element );
+
+	refValue = element.css( ref );
+
+	// Default distance for the BIGGEST bounce is the outer Distance / 3
+	if ( !distance ) {
+		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
+	}
+
+	if ( show ) {
+		downAnim = { opacity: 1 };
+		downAnim[ ref ] = refValue;
+
+		// If we are showing, force opacity 0 and set the initial position
+		// then do the "first" animation
+		element
+			.css( "opacity", 0 )
+			.css( ref, motion ? -distance * 2 : distance * 2 )
+			.animate( downAnim, speed, easing );
+	}
+
+	// Start at the smallest distance if we are hiding
+	if ( hide ) {
+		distance = distance / Math.pow( 2, times - 1 );
+	}
+
+	downAnim = {};
+	downAnim[ ref ] = refValue;
+
+	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
+	for ( ; i < times; i++ ) {
+		upAnim = {};
+		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+		element
+			.animate( upAnim, speed, easing )
+			.animate( downAnim, speed, easing );
+
+		distance = hide ? distance * 2 : distance / 2;
+	}
+
+	// Last Bounce when Hiding
+	if ( hide ) {
+		upAnim = { opacity: 0 };
+		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
+
+		element.animate( upAnim, speed, easing );
+	}
+
+	element.queue( done );
+
+	$.effects.unshift( element, queuelen, anims + 1 );
+} );
+
+
+/*!
+ * jQuery UI Effects Clip 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Clip Effect
+//>>group: Effects
+//>>description: Clips the element on and off like an old TV.
+//>>docs: http://api.jqueryui.com/clip-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
+	var start,
+		animate = {},
+		element = $( this ),
+		direction = options.direction || "vertical",
+		both = direction === "both",
+		horizontal = both || direction === "horizontal",
+		vertical = both || direction === "vertical";
+
+	start = element.cssClip();
+	animate.clip = {
+		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
+		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
+		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
+		left: horizontal ? ( start.right - start.left ) / 2 : start.left
+	};
+
+	$.effects.createPlaceholder( element );
+
+	if ( options.mode === "show" ) {
+		element.cssClip( animate.clip );
+		animate.clip = start;
+	}
+
+	element.animate( animate, {
+		queue: false,
+		duration: options.duration,
+		easing: options.easing,
+		complete: done
+	} );
+
+} );
+
+
+/*!
+ * jQuery UI Effects Drop 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Drop Effect
+//>>group: Effects
+//>>description: Moves an element in one direction and hides it at the same time.
+//>>docs: http://api.jqueryui.com/drop-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
+
+	var distance,
+		element = $( this ),
+		mode = options.mode,
+		show = mode === "show",
+		direction = options.direction || "left",
+		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
+		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
+		animation = {
+			opacity: 0
+		};
+
+	$.effects.createPlaceholder( element );
+
+	distance = options.distance ||
+		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
+
+	animation[ ref ] = motion + distance;
+
+	if ( show ) {
+		element.css( animation );
+
+		animation[ ref ] = oppositeMotion + distance;
+		animation.opacity = 1;
+	}
+
+	// Animate
+	element.animate( animation, {
+		queue: false,
+		duration: options.duration,
+		easing: options.easing,
+		complete: done
+	} );
+} );
+
+
+/*!
+ * jQuery UI Effects Explode 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Explode Effect
+//>>group: Effects
+// jscs:disable maximumLineLength
+//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/explode-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
+
+	var i, j, left, top, mx, my,
+		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
+		cells = rows,
+		element = $( this ),
+		mode = options.mode,
+		show = mode === "show",
+
+		// Show and then visibility:hidden the element before calculating offset
+		offset = element.show().css( "visibility", "hidden" ).offset(),
+
+		// Width and height of a piece
+		width = Math.ceil( element.outerWidth() / cells ),
+		height = Math.ceil( element.outerHeight() / rows ),
+		pieces = [];
+
+	// Children animate complete:
+	function childComplete() {
+		pieces.push( this );
+		if ( pieces.length === rows * cells ) {
+			animComplete();
+		}
+	}
+
+	// Clone the element for each row and cell.
+	for ( i = 0; i < rows; i++ ) { // ===>
+		top = offset.top + i * height;
+		my = i - ( rows - 1 ) / 2;
+
+		for ( j = 0; j < cells; j++ ) { // |||
+			left = offset.left + j * width;
+			mx = j - ( cells - 1 ) / 2;
+
+			// Create a clone of the now hidden main element that will be absolute positioned
+			// within a wrapper div off the -left and -top equal to size of our pieces
+			element
+				.clone()
+				.appendTo( "body" )
+				.wrap( "<div></div>" )
+				.css( {
+					position: "absolute",
+					visibility: "visible",
+					left: -j * width,
+					top: -i * height
+				} )
+
+				// Select the wrapper - make it overflow: hidden and absolute positioned based on
+				// where the original was located +left and +top equal to the size of pieces
+				.parent()
+					.addClass( "ui-effects-explode" )
+					.css( {
+						position: "absolute",
+						overflow: "hidden",
+						width: width,
+						height: height,
+						left: left + ( show ? mx * width : 0 ),
+						top: top + ( show ? my * height : 0 ),
+						opacity: show ? 0 : 1
+					} )
+					.animate( {
+						left: left + ( show ? 0 : mx * width ),
+						top: top + ( show ? 0 : my * height ),
+						opacity: show ? 1 : 0
+					}, options.duration || 500, options.easing, childComplete );
+		}
+	}
+
+	function animComplete() {
+		element.css( {
+			visibility: "visible"
+		} );
+		$( pieces ).remove();
+		done();
+	}
+} );
+
+
+/*!
+ * jQuery UI Effects Fade 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Fade Effect
+//>>group: Effects
+//>>description: Fades the element.
+//>>docs: http://api.jqueryui.com/fade-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
+	var show = options.mode === "show";
+
+	$( this )
+		.css( "opacity", show ? 0 : 1 )
+		.animate( {
+			opacity: show ? 1 : 0
+		}, {
+			queue: false,
+			duration: options.duration,
+			easing: options.easing,
+			complete: done
+		} );
+} );
+
+
+/*!
+ * jQuery UI Effects Fold 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Fold Effect
+//>>group: Effects
+//>>description: Folds an element first horizontally and then vertically.
+//>>docs: http://api.jqueryui.com/fold-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
+
+	// Create element
+	var element = $( this ),
+		mode = options.mode,
+		show = mode === "show",
+		hide = mode === "hide",
+		size = options.size || 15,
+		percent = /([0-9]+)%/.exec( size ),
+		horizFirst = !!options.horizFirst,
+		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
+		duration = options.duration / 2,
+
+		placeholder = $.effects.createPlaceholder( element ),
+
+		start = element.cssClip(),
+		animation1 = { clip: $.extend( {}, start ) },
+		animation2 = { clip: $.extend( {}, start ) },
+
+		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
+
+		queuelen = element.queue().length;
+
+	if ( percent ) {
+		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
+	}
+	animation1.clip[ ref[ 0 ] ] = size;
+	animation2.clip[ ref[ 0 ] ] = size;
+	animation2.clip[ ref[ 1 ] ] = 0;
+
+	if ( show ) {
+		element.cssClip( animation2.clip );
+		if ( placeholder ) {
+			placeholder.css( $.effects.clipToBox( animation2 ) );
+		}
+
+		animation2.clip = start;
+	}
+
+	// Animate
+	element
+		.queue( function( next ) {
+			if ( placeholder ) {
+				placeholder
+					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
+					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
+			}
+
+			next();
+		} )
+		.animate( animation1, duration, options.easing )
+		.animate( animation2, duration, options.easing )
+		.queue( done );
+
+	$.effects.unshift( element, queuelen, 4 );
+} );
+
+
+/*!
+ * jQuery UI Effects Highlight 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Highlight Effect
+//>>group: Effects
+//>>description: Highlights the background of an element in a defined color for a custom duration.
+//>>docs: http://api.jqueryui.com/highlight-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
+	var element = $( this ),
+		animation = {
+			backgroundColor: element.css( "backgroundColor" )
+		};
+
+	if ( options.mode === "hide" ) {
+		animation.opacity = 0;
+	}
+
+	$.effects.saveStyle( element );
+
+	element
+		.css( {
+			backgroundImage: "none",
+			backgroundColor: options.color || "#ffff99"
+		} )
+		.animate( animation, {
+			queue: false,
+			duration: options.duration,
+			easing: options.easing,
+			complete: done
+		} );
+} );
+
+
+/*!
+ * jQuery UI Effects Size 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Size Effect
+//>>group: Effects
+//>>description: Resize an element to a specified width and height.
+//>>docs: http://api.jqueryui.com/size-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectSize = $.effects.define( "size", function( options, done ) {
+
+	// Create element
+	var baseline, factor, temp,
+		element = $( this ),
+
+		// Copy for children
+		cProps = [ "fontSize" ],
+		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
+		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
+
+		// Set options
+		mode = options.mode,
+		restore = mode !== "effect",
+		scale = options.scale || "both",
+		origin = options.origin || [ "middle", "center" ],
+		position = element.css( "position" ),
+		pos = element.position(),
+		original = $.effects.scaledDimensions( element ),
+		from = options.from || original,
+		to = options.to || $.effects.scaledDimensions( element, 0 );
+
+	$.effects.createPlaceholder( element );
+
+	if ( mode === "show" ) {
+		temp = from;
+		from = to;
+		to = temp;
+	}
+
+	// Set scaling factor
+	factor = {
+		from: {
+			y: from.height / original.height,
+			x: from.width / original.width
+		},
+		to: {
+			y: to.height / original.height,
+			x: to.width / original.width
+		}
+	};
+
+	// Scale the css box
+	if ( scale === "box" || scale === "both" ) {
+
+		// Vertical props scaling
+		if ( factor.from.y !== factor.to.y ) {
+			from = $.effects.setTransition( element, vProps, factor.from.y, from );
+			to = $.effects.setTransition( element, vProps, factor.to.y, to );
+		}
+
+		// Horizontal props scaling
+		if ( factor.from.x !== factor.to.x ) {
+			from = $.effects.setTransition( element, hProps, factor.from.x, from );
+			to = $.effects.setTransition( element, hProps, factor.to.x, to );
+		}
+	}
+
+	// Scale the content
+	if ( scale === "content" || scale === "both" ) {
+
+		// Vertical props scaling
+		if ( factor.from.y !== factor.to.y ) {
+			from = $.effects.setTransition( element, cProps, factor.from.y, from );
+			to = $.effects.setTransition( element, cProps, factor.to.y, to );
+		}
+	}
+
+	// Adjust the position properties based on the provided origin points
+	if ( origin ) {
+		baseline = $.effects.getBaseline( origin, original );
+		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
+		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
+		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
+		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
+	}
+	element.css( from );
+
+	// Animate the children if desired
+	if ( scale === "content" || scale === "both" ) {
+
+		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
+		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
+
+		// Only animate children with width attributes specified
+		// TODO: is this right? should we include anything with css width specified as well
+		element.find( "*[width]" ).each( function() {
+			var child = $( this ),
+				childOriginal = $.effects.scaledDimensions( child ),
+				childFrom = {
+					height: childOriginal.height * factor.from.y,
+					width: childOriginal.width * factor.from.x,
+					outerHeight: childOriginal.outerHeight * factor.from.y,
+					outerWidth: childOriginal.outerWidth * factor.from.x
+				},
+				childTo = {
+					height: childOriginal.height * factor.to.y,
+					width: childOriginal.width * factor.to.x,
+					outerHeight: childOriginal.height * factor.to.y,
+					outerWidth: childOriginal.width * factor.to.x
+				};
+
+			// Vertical props scaling
+			if ( factor.from.y !== factor.to.y ) {
+				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
+				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
+			}
+
+			// Horizontal props scaling
+			if ( factor.from.x !== factor.to.x ) {
+				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
+				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
+			}
+
+			if ( restore ) {
+				$.effects.saveStyle( child );
+			}
+
+			// Animate children
+			child.css( childFrom );
+			child.animate( childTo, options.duration, options.easing, function() {
+
+				// Restore children
+				if ( restore ) {
+					$.effects.restoreStyle( child );
+				}
+			} );
+		} );
+	}
+
+	// Animate
+	element.animate( to, {
+		queue: false,
+		duration: options.duration,
+		easing: options.easing,
+		complete: function() {
+
+			var offset = element.offset();
+
+			if ( to.opacity === 0 ) {
+				element.css( "opacity", from.opacity );
+			}
+
+			if ( !restore ) {
+				element
+					.css( "position", position === "static" ? "relative" : position )
+					.offset( offset );
+
+				// Need to save style here so that automatic style restoration
+				// doesn't restore to the original styles from before the animation.
+				$.effects.saveStyle( element );
+			}
+
+			done();
+		}
+	} );
+
+} );
+
+
+/*!
+ * jQuery UI Effects Scale 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Scale Effect
+//>>group: Effects
+//>>description: Grows or shrinks an element and its content.
+//>>docs: http://api.jqueryui.com/scale-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
+
+	// Create element
+	var el = $( this ),
+		mode = options.mode,
+		percent = parseInt( options.percent, 10 ) ||
+			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
+
+		newOptions = $.extend( true, {
+			from: $.effects.scaledDimensions( el ),
+			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
+			origin: options.origin || [ "middle", "center" ]
+		}, options );
+
+	// Fade option to support puff
+	if ( options.fade ) {
+		newOptions.from.opacity = 1;
+		newOptions.to.opacity = 0;
+	}
+
+	$.effects.effect.size.call( this, newOptions, done );
+} );
+
+
+/*!
+ * jQuery UI Effects Puff 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Puff Effect
+//>>group: Effects
+//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
+//>>docs: http://api.jqueryui.com/puff-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
+	var newOptions = $.extend( true, {}, options, {
+		fade: true,
+		percent: parseInt( options.percent, 10 ) || 150
+	} );
+
+	$.effects.effect.scale.call( this, newOptions, done );
+} );
+
+
+/*!
+ * jQuery UI Effects Pulsate 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Pulsate Effect
+//>>group: Effects
+//>>description: Pulsates an element n times by changing the opacity to zero and back.
+//>>docs: http://api.jqueryui.com/pulsate-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
+	var element = $( this ),
+		mode = options.mode,
+		show = mode === "show",
+		hide = mode === "hide",
+		showhide = show || hide,
+
+		// Showing or hiding leaves off the "last" animation
+		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
+		duration = options.duration / anims,
+		animateTo = 0,
+		i = 1,
+		queuelen = element.queue().length;
+
+	if ( show || !element.is( ":visible" ) ) {
+		element.css( "opacity", 0 ).show();
+		animateTo = 1;
+	}
+
+	// Anims - 1 opacity "toggles"
+	for ( ; i < anims; i++ ) {
+		element.animate( { opacity: animateTo }, duration, options.easing );
+		animateTo = 1 - animateTo;
+	}
+
+	element.animate( { opacity: animateTo }, duration, options.easing );
+
+	element.queue( done );
+
+	$.effects.unshift( element, queuelen, anims + 1 );
+} );
+
+
+/*!
+ * jQuery UI Effects Shake 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Shake Effect
+//>>group: Effects
+//>>description: Shakes an element horizontally or vertically n times.
+//>>docs: http://api.jqueryui.com/shake-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
+
+	var i = 1,
+		element = $( this ),
+		direction = options.direction || "left",
+		distance = options.distance || 20,
+		times = options.times || 3,
+		anims = times * 2 + 1,
+		speed = Math.round( options.duration / anims ),
+		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+		positiveMotion = ( direction === "up" || direction === "left" ),
+		animation = {},
+		animation1 = {},
+		animation2 = {},
+
+		queuelen = element.queue().length;
+
+	$.effects.createPlaceholder( element );
+
+	// Animation
+	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
+	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
+	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
+
+	// Animate
+	element.animate( animation, speed, options.easing );
+
+	// Shakes
+	for ( ; i < times; i++ ) {
+		element
+			.animate( animation1, speed, options.easing )
+			.animate( animation2, speed, options.easing );
+	}
+
+	element
+		.animate( animation1, speed, options.easing )
+		.animate( animation, speed / 2, options.easing )
+		.queue( done );
+
+	$.effects.unshift( element, queuelen, anims + 1 );
+} );
+
+
+/*!
+ * jQuery UI Effects Slide 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Slide Effect
+//>>group: Effects
+//>>description: Slides an element in and out of the viewport.
+//>>docs: http://api.jqueryui.com/slide-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
+	var startClip, startRef,
+		element = $( this ),
+		map = {
+			up: [ "bottom", "top" ],
+			down: [ "top", "bottom" ],
+			left: [ "right", "left" ],
+			right: [ "left", "right" ]
+		},
+		mode = options.mode,
+		direction = options.direction || "left",
+		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
+		positiveMotion = ( direction === "up" || direction === "left" ),
+		distance = options.distance ||
+			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
+		animation = {};
+
+	$.effects.createPlaceholder( element );
+
+	startClip = element.cssClip();
+	startRef = element.position()[ ref ];
+
+	// Define hide animation
+	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
+	animation.clip = element.cssClip();
+	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
+
+	// Reverse the animation if we're showing
+	if ( mode === "show" ) {
+		element.cssClip( animation.clip );
+		element.css( ref, animation[ ref ] );
+		animation.clip = startClip;
+		animation[ ref ] = startRef;
+	}
+
+	// Actually animate
+	element.animate( animation, {
+		queue: false,
+		duration: options.duration,
+		easing: options.easing,
+		complete: done
+	} );
+} );
+
+
+/*!
+ * jQuery UI Effects Transfer 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Transfer Effect
+//>>group: Effects
+//>>description: Displays a transfer effect from one element to another.
+//>>docs: http://api.jqueryui.com/transfer-effect/
+//>>demos: http://jqueryui.com/effect/
+
+
+
+var effect;
+if ( $.uiBackCompat !== false ) {
+	effect = $.effects.define( "transfer", function( options, done ) {
+		$( this ).transfer( options, done );
+	} );
+}
+var effectsEffectTransfer = effect;
+
+
+/*!
+ * jQuery UI Focusable 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: :focusable Selector
+//>>group: Core
+//>>description: Selects elements which can be focused.
+//>>docs: http://api.jqueryui.com/focusable-selector/
+
+
+
+// Selectors
+$.ui.focusable = function( element, hasTabindex ) {
+	var map, mapName, img, focusableIfVisible, fieldset,
+		nodeName = element.nodeName.toLowerCase();
+
+	if ( "area" === nodeName ) {
+		map = element.parentNode;
+		mapName = map.name;
+		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+			return false;
+		}
+		img = $( "img[usemap='#" + mapName + "']" );
+		return img.length > 0 && img.is( ":visible" );
+	}
+
+	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
+		focusableIfVisible = !element.disabled;
+
+		if ( focusableIfVisible ) {
+
+			// Form controls within a disabled fieldset are disabled.
+			// However, controls within the fieldset's legend do not get disabled.
+			// Since controls generally aren't placed inside legends, we skip
+			// this portion of the check.
+			fieldset = $( element ).closest( "fieldset" )[ 0 ];
+			if ( fieldset ) {
+				focusableIfVisible = !fieldset.disabled;
+			}
+		}
+	} else if ( "a" === nodeName ) {
+		focusableIfVisible = element.href || hasTabindex;
+	} else {
+		focusableIfVisible = hasTabindex;
+	}
+
+	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
+};
+
+// Support: IE 8 only
+// IE 8 doesn't resolve inherit to visible/hidden for computed values
+function visible( element ) {
+	var visibility = element.css( "visibility" );
+	while ( visibility === "inherit" ) {
+		element = element.parent();
+		visibility = element.css( "visibility" );
+	}
+	return visibility !== "hidden";
+}
+
+$.extend( $.expr[ ":" ], {
+	focusable: function( element ) {
+		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
+	}
+} );
+
+var focusable = $.ui.focusable;
+
+
+
+
+// Support: IE8 Only
+// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
+// with a string, so we need to find the proper form.
+var form = $.fn.form = function() {
+	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
+};
+
+
+/*!
+ * jQuery UI Form Reset Mixin 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Form Reset Mixin
+//>>group: Core
+//>>description: Refresh input widgets when their form is reset
+//>>docs: http://api.jqueryui.com/form-reset-mixin/
+
+
+
+var formResetMixin = $.ui.formResetMixin = {
+	_formResetHandler: function() {
+		var form = $( this );
+
+		// Wait for the form reset to actually happen before refreshing
+		setTimeout( function() {
+			var instances = form.data( "ui-form-reset-instances" );
+			$.each( instances, function() {
+				this.refresh();
+			} );
+		} );
+	},
+
+	_bindFormResetHandler: function() {
+		this.form = this.element.form();
+		if ( !this.form.length ) {
+			return;
+		}
+
+		var instances = this.form.data( "ui-form-reset-instances" ) || [];
+		if ( !instances.length ) {
+
+			// We don't use _on() here because we use a single event handler per form
+			this.form.on( "reset.ui-form-reset", this._formResetHandler );
+		}
+		instances.push( this );
+		this.form.data( "ui-form-reset-instances", instances );
+	},
+
+	_unbindFormResetHandler: function() {
+		if ( !this.form.length ) {
+			return;
+		}
+
+		var instances = this.form.data( "ui-form-reset-instances" );
+		instances.splice( $.inArray( this, instances ), 1 );
+		if ( instances.length ) {
+			this.form.data( "ui-form-reset-instances", instances );
+		} else {
+			this.form
+				.removeData( "ui-form-reset-instances" )
+				.off( "reset.ui-form-reset" );
+		}
+	}
+};
+
+
+/*!
+ * jQuery UI Support for jQuery core 1.7.x 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
  *
- * http://docs.jquery.com/UI/Mouse
- *
- * Depends:
- *	jquery.ui.widget.js
  */
-(function(b){var d=false;b(document).mousedown(function(){d=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(c){return a._mouseDown(c)}).bind("click."+this.widgetName,function(c){if(true===b.data(c.target,a.widgetName+".preventClickEvent")){b.removeData(c.target,a.widgetName+".preventClickEvent");c.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+
-this.widgetName)},_mouseDown:function(a){if(!d){this._mouseStarted&&this._mouseUp(a);this._mouseDownEvent=a;var c=this,f=a.which==1,g=typeof this.options.cancel=="string"?b(a.target).closest(this.options.cancel).length:false;if(!f||g||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){c.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==
-false;if(!this._mouseStarted){a.preventDefault();return true}}true===b.data(a.target,this.widgetName+".preventClickEvent")&&b.removeData(a.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(e){return c._mouseMove(e)};this._mouseUpDelegate=function(e){return c._mouseUp(e)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);a.preventDefault();return d=true}},_mouseMove:function(a){if(b.browser.msie&&
-!(document.documentMode>=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
-false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
-;/*
- * jQuery UI Position 1.8.14
+
+//>>label: jQuery 1.7 Support
+//>>group: Core
+//>>description: Support version 1.7.x of jQuery core
+
+
+
+// Support: jQuery 1.7 only
+// Not a great way to check versions, but since we only support 1.7+ and only
+// need to detect <1.8, this is a simple check that should suffice. Checking
+// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
+// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
+// 1.7 anymore). See #11197 for why we're not using feature detection.
+if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
+
+	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
+	// Unlike jQuery Core 1.8+, these only support numeric values to set the
+	// dimensions in pixels
+	$.each( [ "Width", "Height" ], function( i, name ) {
+		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+			type = name.toLowerCase(),
+			orig = {
+				innerWidth: $.fn.innerWidth,
+				innerHeight: $.fn.innerHeight,
+				outerWidth: $.fn.outerWidth,
+				outerHeight: $.fn.outerHeight
+			};
+
+		function reduce( elem, size, border, margin ) {
+			$.each( side, function() {
+				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+				if ( border ) {
+					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+				}
+				if ( margin ) {
+					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+				}
+			} );
+			return size;
+		}
+
+		$.fn[ "inner" + name ] = function( size ) {
+			if ( size === undefined ) {
+				return orig[ "inner" + name ].call( this );
+			}
+
+			return this.each( function() {
+				$( this ).css( type, reduce( this, size ) + "px" );
+			} );
+		};
+
+		$.fn[ "outer" + name ] = function( size, margin ) {
+			if ( typeof size !== "number" ) {
+				return orig[ "outer" + name ].call( this, size );
+			}
+
+			return this.each( function() {
+				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
+			} );
+		};
+	} );
+
+	$.fn.addBack = function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	};
+}
+
+;
+/*!
+ * jQuery UI Keycode 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Position
  */
-(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
-left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
-k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
-m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
-d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
-a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
-g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
-;/*
- * jQuery UI Draggable 1.8.14
+
+//>>label: Keycode
+//>>group: Core
+//>>description: Provide keycodes as keynames
+//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
+
+
+var keycode = $.ui.keyCode = {
+	BACKSPACE: 8,
+	COMMA: 188,
+	DELETE: 46,
+	DOWN: 40,
+	END: 35,
+	ENTER: 13,
+	ESCAPE: 27,
+	HOME: 36,
+	LEFT: 37,
+	PAGE_DOWN: 34,
+	PAGE_UP: 33,
+	PERIOD: 190,
+	RIGHT: 39,
+	SPACE: 32,
+	TAB: 9,
+	UP: 38
+};
+
+
+
+
+// Internal use only
+var escapeSelector = $.ui.escapeSelector = ( function() {
+	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
+	return function( selector ) {
+		return selector.replace( selectorEscape, "\\$1" );
+	};
+} )();
+
+
+/*!
+ * jQuery UI Labels 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Draggables
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.mouse.js
- *	jquery.ui.widget.js
  */
-(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
-"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b=
-this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options;this.helper=
-this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});
-this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true},
-_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=
-false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,
-10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||
-!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&
-a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=
-this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),
-10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),
-10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,
-(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!=
-"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),
-10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+
-this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&
-!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.left<g[0])e=g[0]+this.offset.click.left;
-if(a.pageY-this.offset.click.top<g[1])h=g[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>g[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.top<g[1]||h-this.offset.click.top>g[3])?h:!(h-this.offset.click.top<g[1])?h-b.grid[1]:h+b.grid[1]:h;e=b.grid[0]?this.originalPageX+Math.round((e-this.originalPageX)/
-b.grid[0])*b.grid[0]:this.originalPageX;e=g?!(e-this.offset.click.left<g[0]||e-this.offset.click.left>g[2])?e:!(e-this.offset.click.left<g[0])?e-b.grid[0]:e+b.grid[0]:e}}return{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop()),left:e-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&d.browser.version<
-526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(a,b,c){c=c||this._uiHash();d.ui.plugin.call(this,a,[b,c]);if(a=="drag")this.positionAbs=this._convertPositionTo("absolute");return d.Widget.prototype._trigger.call(this,a,b,
-c)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});d.extend(d.ui.draggable,{version:"1.8.14"});d.ui.plugin.add("draggable","connectToSortable",{start:function(a,b){var c=d(this).data("draggable"),f=c.options,e=d.extend({},b,{item:c.element});c.sortables=[];d(f.connectToSortable).each(function(){var h=d.data(this,"sortable");if(h&&!h.options.disabled){c.sortables.push({instance:h,shouldRevert:h.options.revert});
-h.refreshPositions();h._trigger("activate",a,e)}})},stop:function(a,b){alert($(this).data("draggable"));var c=d(this).data("draggable"),f=d.extend({},b,{item:c.element});d.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(a);this.instance.options.helper=this.instance.options._helper;c.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=
-false;this.instance._trigger("deactivate",a,f)}})},drag:function(a,b){var c=d(this).data("draggable"),f=this;d.each(c.sortables,function(){this.instance.positionAbs=c.positionAbs;this.instance.helperProportions=c.helperProportions;this.instance.offset.click=c.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=d(f).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",true);
-this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return b.helper[0]};a.target=this.instance.currentItem[0];this.instance._mouseCapture(a,true);this.instance._mouseStart(a,true,true);this.instance.offset.click.top=c.offset.click.top;this.instance.offset.click.left=c.offset.click.left;this.instance.offset.parent.left-=c.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=c.offset.parent.top-this.instance.offset.parent.top;
-c._trigger("toSortable",a);c.dropped=this.instance.element;c.currentItem=c.element;this.instance.fromOutside=c}this.instance.currentItem&&this.instance._mouseDrag(a)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",a,this.instance._uiHash(this.instance));this.instance._mouseStop(a,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&
-this.instance.placeholder.remove();c._trigger("fromSortable",a);c.dropped=false}})}});d.ui.plugin.add("draggable","cursor",{start:function(){var a=d("body"),b=d(this).data("draggable").options;if(a.css("cursor"))b._cursor=a.css("cursor");a.css("cursor",b.cursor)},stop:function(){if( $(this).data("draggable") ){var a=d(this).data("draggable").options;a._cursor&&d("body").css("cursor",a._cursor)}}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("opacity"))b._opacity=
-a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){if(!c.axis||c.axis!=
-"x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop+c.scrollSpeed;else if(a.pageY-b.overflowOffset.top<c.scrollSensitivity)b.scrollParent[0].scrollTop=f=b.scrollParent[0].scrollTop-c.scrollSpeed;if(!c.axis||c.axis!="y")if(b.overflowOffset.left+b.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft+c.scrollSpeed;else if(a.pageX-b.overflowOffset.left<
-c.scrollSensitivity)b.scrollParent[0].scrollLeft=f=b.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(!c.axis||c.axis!="x")if(a.pageY-d(document).scrollTop()<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()-c.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<c.scrollSensitivity)f=d(document).scrollTop(d(document).scrollTop()+c.scrollSpeed);if(!c.axis||c.axis!="y")if(a.pageX-d(document).scrollLeft()<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()-
-c.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<c.scrollSensitivity)f=d(document).scrollLeft(d(document).scrollLeft()+c.scrollSpeed)}f!==false&&d.ui.ddmanager&&!c.dropBehaviour&&d.ui.ddmanager.prepareOffsets(b,a)}});d.ui.plugin.add("draggable","snap",{start:function(){var a=d(this).data("draggable"),b=a.options;a.snapElements=[];d(b.snap.constructor!=String?b.snap.items||":data(draggable)":b.snap).each(function(){var c=d(this),f=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,
-width:c.outerWidth(),height:c.outerHeight(),top:f.top,left:f.left})})},drag:function(a,b){for(var c=d(this).data("draggable"),f=c.options,e=f.snapTolerance,h=b.offset.left,g=h+c.helperProportions.width,n=b.offset.top,o=n+c.helperProportions.height,i=c.snapElements.length-1;i>=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e<h&&h<l+e&&k-e<n&&n<m+e||j-e<h&&h<l+e&&k-e<o&&o<m+e||j-e<g&&g<l+e&&k-e<n&&n<m+e||j-e<g&&g<l+e&&k-e<o&&
-o<m+e){if(f.snapMode!="inner"){var p=Math.abs(k-o)<=e,q=Math.abs(m-n)<=e,r=Math.abs(j-g)<=e,s=Math.abs(l-h)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k-c.helperProportions.height,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j-c.helperProportions.width}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l}).left-c.margins.left}var t=
-p||q||r||s;if(f.snapMode!="outer"){p=Math.abs(k-n)<=e;q=Math.abs(m-o)<=e;r=Math.abs(j-h)<=e;s=Math.abs(l-g)<=e;if(p)b.position.top=c._convertPositionTo("relative",{top:k,left:0}).top-c.margins.top;if(q)b.position.top=c._convertPositionTo("relative",{top:m-c.helperProportions.height,left:0}).top-c.margins.top;if(r)b.position.left=c._convertPositionTo("relative",{top:0,left:j}).left-c.margins.left;if(s)b.position.left=c._convertPositionTo("relative",{top:0,left:l-c.helperProportions.width}).left-c.margins.left}if(!c.snapElements[i].snapping&&
-(p||q||r||s||t))c.options.snap.snap&&c.options.snap.snap.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=p||q||r||s||t}else{c.snapElements[i].snapping&&c.options.snap.release&&c.options.snap.release.call(c.element,a,d.extend(c._uiHash(),{snapItem:c.snapElements[i].item}));c.snapElements[i].snapping=false}}}});d.ui.plugin.add("draggable","stack",{start:function(){var a=d(this).data("draggable").options;a=d.makeArray(d(a.stack)).sort(function(c,f){return(parseInt(d(c).css("zIndex"),
-10)||0)-(parseInt(d(f).css("zIndex"),10)||0)});if(a.length){var b=parseInt(a[0].style.zIndex)||0;d(a).each(function(c){this.style.zIndex=b+c});this[0].style.zIndex=b+a.length}}});d.ui.plugin.add("draggable","zIndex",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options;if(a.css("zIndex"))b._zIndex=a.css("zIndex");a.css("zIndex",b.zIndex)},stop:function(a,b){a=d(this).data("draggable").options;a._zIndex&&d(b.helper).css("zIndex",a._zIndex)}})})(jQuery);
-;/*
- * jQuery UI Droppable 1.8.14
+
+//>>label: labels
+//>>group: Core
+//>>description: Find all the labels associated with a given input
+//>>docs: http://api.jqueryui.com/labels/
+
+
+
+var labels = $.fn.labels = function() {
+	var ancestor, selector, id, labels, ancestors;
+
+	// Check control.labels first
+	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
+		return this.pushStack( this[ 0 ].labels );
+	}
+
+	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
+	// Above browsers do not support control.labels. Everything below is to support them
+	// as well as document fragments. control.labels does not work on document fragments
+	labels = this.eq( 0 ).parents( "label" );
+
+	// Look for the label based on the id
+	id = this.attr( "id" );
+	if ( id ) {
+
+		// We don't search against the document in case the element
+		// is disconnected from the DOM
+		ancestor = this.eq( 0 ).parents().last();
+
+		// Get a full set of top level ancestors
+		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
+
+		// Create a selector for the label based on the id
+		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
+
+		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
+
+	}
+
+	// Return whatever we have found for labels
+	return this.pushStack( labels );
+};
+
+
+/*!
+ * jQuery UI Scroll Parent 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Droppables
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
- *	jquery.ui.mouse.js
- *	jquery.ui.draggable.js
  */
-(function(d){d.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,b=a.accept;this.isover=0;this.isout=1;this.accept=d.isFunction(b)?b:function(c){return c.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};d.ui.ddmanager.droppables[a.scope]=d.ui.ddmanager.droppables[a.scope]||[];d.ui.ddmanager.droppables[a.scope].push(this);
-a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=d.ui.ddmanager.droppables[this.options.scope],b=0;b<a.length;b++)a[b]==this&&a.splice(b,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,b){if(a=="accept")this.accept=d.isFunction(b)?b:function(c){return c.is(b)};d.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&
-this.element.addClass(this.options.activeClass);b&&this._trigger("activate",a,this.ui(b))},_deactivate:function(a){var b=d.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);b&&this._trigger("deactivate",a,this.ui(b))},_over:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
-this._trigger("over",a,this.ui(b))}},_out:function(a){var b=d.ui.ddmanager.current;if(!(!b||(b.currentItem||b.element)[0]==this.element[0]))if(this.accept.call(this.element[0],b.currentItem||b.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",a,this.ui(b))}},_drop:function(a,b){var c=b||d.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return false;var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
-d.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==c.options.scope&&g.accept.call(g.element[0],c.currentItem||c.element)&&d.ui.intersect(c,d.extend(g,{offset:g.element.offset()}),g.options.tolerance)){e=true;return false}});if(e)return false;if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
-a,this.ui(c));return this.element}return false},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}});d.extend(d.ui.droppable,{version:"1.8.14"});d.ui.intersect=function(a,b,c){if(!b.offset)return false;var e=(a.positionAbs||a.position.absolute).left,g=e+a.helperProportions.width,f=(a.positionAbs||a.position.absolute).top,h=f+a.helperProportions.height,i=b.offset.left,k=i+b.proportions.width,j=b.offset.top,l=j+b.proportions.height;
-switch(c){case "fit":return i<=e&&g<=k&&j<=f&&h<=l;case "intersect":return i<e+a.helperProportions.width/2&&g-a.helperProportions.width/2<k&&j<f+a.helperProportions.height/2&&h-a.helperProportions.height/2<l;case "pointer":return d.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,j,i,b.proportions.height,b.proportions.width);case "touch":return(f>=j&&f<=l||h>=j&&h<=l||f<j&&h>l)&&(e>=
-i&&e<=k||g>=i&&g<=k||e<i&&g>k);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f<c.length;f++)if(!(c[f].options.disabled||a&&!c[f].accept.call(c[f].element[0],a.currentItem||a.element))){for(var h=0;h<g.length;h++)if(g[h]==c[f].element[0]){c[f].proportions.height=0;continue a}c[f].visible=c[f].element.css("display")!=
-"none";if(c[f].visible){e=="mousedown"&&c[f]._activate.call(c[f],b);c[f].offset=c[f].element.offset();c[f].proportions={width:c[f].element[0].offsetWidth,height:c[f].element[0].offsetHeight}}}},drop:function(a,b){var c=false;d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&d.ui.intersect(a,this,this.options.tolerance))c=c||this._drop.call(this,b);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||
-a.element)){this.isout=1;this.isover=0;this._deactivate.call(this,b)}}});return c},dragStart:function(a,b){a.element.parentsUntil("body").bind("scroll.droppable",function(){a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)})},drag:function(a,b){a.options.refreshPositions&&d.ui.ddmanager.prepareOffsets(a,b);d.each(d.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var c=d.ui.intersect(a,this,this.options.tolerance);if(c=
-!c&&this.isover==1?"isout":c&&this.isover==0?"isover":null){var e;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){e=d.data(g[0],"droppable");e.greedyChild=c=="isover"?1:0}}if(e&&c=="isover"){e.isover=0;e.isout=1;e._out.call(e,b)}this[c]=1;this[c=="isout"?"isover":"isout"]=0;this[c=="isover"?"_over":"_out"].call(this,b);if(e&&c=="isout"){e.isout=0;e.isover=1;e._over.call(e,b)}}}})},dragStop:function(a,b){a.element.parentsUntil("body").unbind("scroll.droppable");
-a.options.refreshPositions||d.ui.ddmanager.prepareOffsets(a,b)}}})(jQuery);
-;/*
- * jQuery UI Resizable 1.8.14
+
+//>>label: scrollParent
+//>>group: Core
+//>>description: Get the closest ancestor element that is scrollable.
+//>>docs: http://api.jqueryui.com/scrollParent/
+
+
+
+var scrollParent = $.fn.scrollParent = function( includeHidden ) {
+	var position = this.css( "position" ),
+		excludeStaticParent = position === "absolute",
+		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
+		scrollParent = this.parents().filter( function() {
+			var parent = $( this );
+			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+				return false;
+			}
+			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
+				parent.css( "overflow-x" ) );
+		} ).eq( 0 );
+
+	return position === "fixed" || !scrollParent.length ?
+		$( this[ 0 ].ownerDocument || document ) :
+		scrollParent;
+};
+
+
+/*!
+ * jQuery UI Tabbable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizables
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.mouse.js
- *	jquery.ui.widget.js
  */
-(function(e){e.widget("ui.resizable",e.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");e.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,
-_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&e.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
-top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
-this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
-nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d<c.length;d++){var f=e.trim(c[d]),g=e('<div class="ui-resizable-handle '+("ui-resizable-"+f)+'"></div>');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor==
-String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection();
-this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();
-var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=
-false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"});
-this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff=
-{width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis];
-if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},
-_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f,
-{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight:
-Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(c<a.maxWidth)a.maxWidth=c;if(f<a.maxHeight)a.maxHeight=f}this._vBoundaries=a},_updateCache:function(b){this.offset=this.helper.offset();if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width=
-b.width},_updateRatio:function(b){var a=this.position,c=this.size,d=this.axis;if(k(b.height))b.width=b.height*this.aspectRatio;else if(k(b.width))b.height=b.width/this.aspectRatio;if(d=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(d=="nw"){b.top=a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this._vBoundaries,c=this.axis,d=k(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=k(b.height)&&a.maxHeight&&a.maxHeight<b.height,g=k(b.width)&&a.minWidth&&
-a.minWidth>b.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=
-null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var c=this._proportionallyResizeElements[a];if(!this.borderDif){var d=[c.css("borderTopWidth"),c.css("borderRightWidth"),c.css("borderBottomWidth"),c.css("borderLeftWidth")],f=[c.css("paddingTop"),c.css("paddingRight"),c.css("paddingBottom"),c.css("paddingLeft")];this.borderDif=e.map(d,function(g,h){g=parseInt(g,10)||
-0;h=parseInt(f[h],10)||0;return g+h})}e.browser.msie&&(e(b).is(":hidden")||e(b).parents(":hidden").length)||c.css({height:b.height()-this.borderDif[0]-this.borderDif[2]||0,width:b.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var b=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+
-a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+
-c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]);
-b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.14"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(),
-10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top-
-f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType?
-e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a=
-e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing,
-step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement=
-e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset;
-var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left:
-a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top-
-d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition,
-f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25,
-display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b=
-e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height=
-d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery);
-;/*
- * jQuery UI Selectable 1.8.14
+
+//>>label: :tabbable Selector
+//>>group: Core
+//>>description: Selects elements which can be tabbed to.
+//>>docs: http://api.jqueryui.com/tabbable-selector/
+
+
+
+var tabbable = $.extend( $.expr[ ":" ], {
+	tabbable: function( element ) {
+		var tabIndex = $.attr( element, "tabindex" ),
+			hasTabindex = tabIndex != null;
+		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
+	}
+} );
+
+
+/*!
+ * jQuery UI Unique ID 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Selectables
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.mouse.js
- *	jquery.ui.widget.js
  */
-(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),
-selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX,
-c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting",
-c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d=
-this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.right<b||a.top>i||a.bottom<g);else if(d.tolerance=="fit")k=a.left>b&&a.right<h&&a.top>g&&a.bottom<i;if(k){if(a.selected){a.$element.removeClass("ui-selected");a.selected=false}if(a.unselecting){a.$element.removeClass("ui-unselecting");
-a.unselecting=false}if(!a.selecting){a.$element.addClass("ui-selecting");a.selecting=true;f._trigger("selecting",c,{selecting:a.element})}}else{if(a.selecting)if(c.metaKey&&a.startselected){a.$element.removeClass("ui-selecting");a.selecting=false;a.$element.addClass("ui-selected");a.selected=true}else{a.$element.removeClass("ui-selecting");a.selecting=false;if(a.startselected){a.$element.addClass("ui-unselecting");a.unselecting=true}f._trigger("unselecting",c,{unselecting:a.element})}if(a.selected)if(!c.metaKey&&
-!a.startselected){a.$element.removeClass("ui-selected");a.selected=false;a.$element.addClass("ui-unselecting");a.unselecting=true;f._trigger("unselecting",c,{unselecting:a.element})}}}});return false}},_mouseStop:function(c){var f=this;this.dragged=false;e(".ui-unselecting",this.element[0]).each(function(){var d=e.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=false;d.startselected=false;f._trigger("unselected",c,{unselected:d.element})});e(".ui-selecting",this.element[0]).each(function(){var d=
-e.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");d.selecting=false;d.selected=true;d.startselected=true;f._trigger("selected",c,{selected:d.element})});this._trigger("stop",c);this.helper.remove();return false}});e.extend(e.ui.selectable,{version:"1.8.14"})})(jQuery);
-;/*
- * jQuery UI Sortable 1.8.14
+
+//>>label: uniqueId
+//>>group: Core
+//>>description: Functions to generate and remove uniqueId's
+//>>docs: http://api.jqueryui.com/uniqueId/
+
+
+
+var uniqueId = $.fn.extend( {
+	uniqueId: ( function() {
+		var uuid = 0;
+
+		return function() {
+			return this.each( function() {
+				if ( !this.id ) {
+					this.id = "ui-id-" + ( ++uuid );
+				}
+			} );
+		};
+	} )(),
+
+	removeUniqueId: function() {
+		return this.each( function() {
+			if ( /^ui-id-\d+$/.test( this.id ) ) {
+				$( this ).removeAttr( "id" );
+			}
+		} );
+	}
+} );
+
+
+/*!
+ * jQuery UI Accordion 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Sortables
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.mouse.js
- *	jquery.ui.widget.js
  */
-(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable");
-this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a===
-"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&
-!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,
-left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};
-this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=
-document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);
-return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<
-b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-
-b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,
-a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],
-e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();
-c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):
-this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,
-dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")},
-toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||
-this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();
-var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},
-_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();
-if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),
-this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),
-this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&
-this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=
-this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=
-d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||
-0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",
-a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-
-f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=
-this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==
-""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=
-this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a=
-{top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),
-10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?
-document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),
-10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=
-this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&
-this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();
-var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-
-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-
-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],
-this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]=
-"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",
-f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,
-this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",
-a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},
-_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.14"})})(jQuery);
-;/*
- * jQuery UI Accordion 1.8.14
+
+//>>label: Accordion
+//>>group: Widgets
+// jscs:disable maximumLineLength
+//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/accordion/
+//>>demos: http://jqueryui.com/accordion/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/accordion.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsAccordion = $.widget( "ui.accordion", {
+	version: "1.12.1",
+	options: {
+		active: 0,
+		animate: {},
+		classes: {
+			"ui-accordion-header": "ui-corner-top",
+			"ui-accordion-header-collapsed": "ui-corner-all",
+			"ui-accordion-content": "ui-corner-bottom"
+		},
+		collapsible: false,
+		event: "click",
+		header: "> li > :first-child, > :not(li):even",
+		heightStyle: "auto",
+		icons: {
+			activeHeader: "ui-icon-triangle-1-s",
+			header: "ui-icon-triangle-1-e"
+		},
+
+		// Callbacks
+		activate: null,
+		beforeActivate: null
+	},
+
+	hideProps: {
+		borderTopWidth: "hide",
+		borderBottomWidth: "hide",
+		paddingTop: "hide",
+		paddingBottom: "hide",
+		height: "hide"
+	},
+
+	showProps: {
+		borderTopWidth: "show",
+		borderBottomWidth: "show",
+		paddingTop: "show",
+		paddingBottom: "show",
+		height: "show"
+	},
+
+	_create: function() {
+		var options = this.options;
+
+		this.prevShow = this.prevHide = $();
+		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
+		this.element.attr( "role", "tablist" );
+
+		// Don't allow collapsible: false and active: false / null
+		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
+			options.active = 0;
+		}
+
+		this._processPanels();
+
+		// handle negative values
+		if ( options.active < 0 ) {
+			options.active += this.headers.length;
+		}
+		this._refresh();
+	},
+
+	_getCreateEventData: function() {
+		return {
+			header: this.active,
+			panel: !this.active.length ? $() : this.active.next()
+		};
+	},
+
+	_createIcons: function() {
+		var icon, children,
+			icons = this.options.icons;
+
+		if ( icons ) {
+			icon = $( "<span>" );
+			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
+			icon.prependTo( this.headers );
+			children = this.active.children( ".ui-accordion-header-icon" );
+			this._removeClass( children, icons.header )
+				._addClass( children, null, icons.activeHeader )
+				._addClass( this.headers, "ui-accordion-icons" );
+		}
+	},
+
+	_destroyIcons: function() {
+		this._removeClass( this.headers, "ui-accordion-icons" );
+		this.headers.children( ".ui-accordion-header-icon" ).remove();
+	},
+
+	_destroy: function() {
+		var contents;
+
+		// Clean up main element
+		this.element.removeAttr( "role" );
+
+		// Clean up headers
+		this.headers
+			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
+			.removeUniqueId();
+
+		this._destroyIcons();
+
+		// Clean up content panels
+		contents = this.headers.next()
+			.css( "display", "" )
+			.removeAttr( "role aria-hidden aria-labelledby" )
+			.removeUniqueId();
+
+		if ( this.options.heightStyle !== "content" ) {
+			contents.css( "height", "" );
+		}
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "active" ) {
+
+			// _activate() will handle invalid values and update this.options
+			this._activate( value );
+			return;
+		}
+
+		if ( key === "event" ) {
+			if ( this.options.event ) {
+				this._off( this.headers, this.options.event );
+			}
+			this._setupEvents( value );
+		}
+
+		this._super( key, value );
+
+		// Setting collapsible: false while collapsed; open first panel
+		if ( key === "collapsible" && !value && this.options.active === false ) {
+			this._activate( 0 );
+		}
+
+		if ( key === "icons" ) {
+			this._destroyIcons();
+			if ( value ) {
+				this._createIcons();
+			}
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this.element.attr( "aria-disabled", value );
+
+		// Support: IE8 Only
+		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
+		// so we need to add the disabled class to the headers and panels
+		this._toggleClass( null, "ui-state-disabled", !!value );
+		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
+			!!value );
+	},
+
+	_keydown: function( event ) {
+		if ( event.altKey || event.ctrlKey ) {
+			return;
+		}
+
+		var keyCode = $.ui.keyCode,
+			length = this.headers.length,
+			currentIndex = this.headers.index( event.target ),
+			toFocus = false;
+
+		switch ( event.keyCode ) {
+		case keyCode.RIGHT:
+		case keyCode.DOWN:
+			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+			break;
+		case keyCode.LEFT:
+		case keyCode.UP:
+			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+			break;
+		case keyCode.SPACE:
+		case keyCode.ENTER:
+			this._eventHandler( event );
+			break;
+		case keyCode.HOME:
+			toFocus = this.headers[ 0 ];
+			break;
+		case keyCode.END:
+			toFocus = this.headers[ length - 1 ];
+			break;
+		}
+
+		if ( toFocus ) {
+			$( event.target ).attr( "tabIndex", -1 );
+			$( toFocus ).attr( "tabIndex", 0 );
+			$( toFocus ).trigger( "focus" );
+			event.preventDefault();
+		}
+	},
+
+	_panelKeyDown: function( event ) {
+		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
+			$( event.currentTarget ).prev().trigger( "focus" );
+		}
+	},
+
+	refresh: function() {
+		var options = this.options;
+		this._processPanels();
+
+		// Was collapsed or no panel
+		if ( ( options.active === false && options.collapsible === true ) ||
+				!this.headers.length ) {
+			options.active = false;
+			this.active = $();
+
+		// active false only when collapsible is true
+		} else if ( options.active === false ) {
+			this._activate( 0 );
+
+		// was active, but active panel is gone
+		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+
+			// all remaining panel are disabled
+			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
+				options.active = false;
+				this.active = $();
+
+			// activate previous panel
+			} else {
+				this._activate( Math.max( 0, options.active - 1 ) );
+			}
+
+		// was active, active panel still exists
+		} else {
+
+			// make sure active index is correct
+			options.active = this.headers.index( this.active );
+		}
+
+		this._destroyIcons();
+
+		this._refresh();
+	},
+
+	_processPanels: function() {
+		var prevHeaders = this.headers,
+			prevPanels = this.panels;
+
+		this.headers = this.element.find( this.options.header );
+		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
+			"ui-state-default" );
+
+		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
+		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
+
+		// Avoid memory leaks (#10056)
+		if ( prevPanels ) {
+			this._off( prevHeaders.not( this.headers ) );
+			this._off( prevPanels.not( this.panels ) );
+		}
+	},
+
+	_refresh: function() {
+		var maxHeight,
+			options = this.options,
+			heightStyle = options.heightStyle,
+			parent = this.element.parent();
+
+		this.active = this._findActive( options.active );
+		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
+			._removeClass( this.active, "ui-accordion-header-collapsed" );
+		this._addClass( this.active.next(), "ui-accordion-content-active" );
+		this.active.next().show();
+
+		this.headers
+			.attr( "role", "tab" )
+			.each( function() {
+				var header = $( this ),
+					headerId = header.uniqueId().attr( "id" ),
+					panel = header.next(),
+					panelId = panel.uniqueId().attr( "id" );
+				header.attr( "aria-controls", panelId );
+				panel.attr( "aria-labelledby", headerId );
+			} )
+			.next()
+				.attr( "role", "tabpanel" );
+
+		this.headers
+			.not( this.active )
+				.attr( {
+					"aria-selected": "false",
+					"aria-expanded": "false",
+					tabIndex: -1
+				} )
+				.next()
+					.attr( {
+						"aria-hidden": "true"
+					} )
+					.hide();
+
+		// Make sure at least one header is in the tab order
+		if ( !this.active.length ) {
+			this.headers.eq( 0 ).attr( "tabIndex", 0 );
+		} else {
+			this.active.attr( {
+				"aria-selected": "true",
+				"aria-expanded": "true",
+				tabIndex: 0
+			} )
+				.next()
+					.attr( {
+						"aria-hidden": "false"
+					} );
+		}
+
+		this._createIcons();
+
+		this._setupEvents( options.event );
+
+		if ( heightStyle === "fill" ) {
+			maxHeight = parent.height();
+			this.element.siblings( ":visible" ).each( function() {
+				var elem = $( this ),
+					position = elem.css( "position" );
+
+				if ( position === "absolute" || position === "fixed" ) {
+					return;
+				}
+				maxHeight -= elem.outerHeight( true );
+			} );
+
+			this.headers.each( function() {
+				maxHeight -= $( this ).outerHeight( true );
+			} );
+
+			this.headers.next()
+				.each( function() {
+					$( this ).height( Math.max( 0, maxHeight -
+						$( this ).innerHeight() + $( this ).height() ) );
+				} )
+				.css( "overflow", "auto" );
+		} else if ( heightStyle === "auto" ) {
+			maxHeight = 0;
+			this.headers.next()
+				.each( function() {
+					var isVisible = $( this ).is( ":visible" );
+					if ( !isVisible ) {
+						$( this ).show();
+					}
+					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
+					if ( !isVisible ) {
+						$( this ).hide();
+					}
+				} )
+				.height( maxHeight );
+		}
+	},
+
+	_activate: function( index ) {
+		var active = this._findActive( index )[ 0 ];
+
+		// Trying to activate the already active panel
+		if ( active === this.active[ 0 ] ) {
+			return;
+		}
+
+		// Trying to collapse, simulate a click on the currently active header
+		active = active || this.active[ 0 ];
+
+		this._eventHandler( {
+			target: active,
+			currentTarget: active,
+			preventDefault: $.noop
+		} );
+	},
+
+	_findActive: function( selector ) {
+		return typeof selector === "number" ? this.headers.eq( selector ) : $();
+	},
+
+	_setupEvents: function( event ) {
+		var events = {
+			keydown: "_keydown"
+		};
+		if ( event ) {
+			$.each( event.split( " " ), function( index, eventName ) {
+				events[ eventName ] = "_eventHandler";
+			} );
+		}
+
+		this._off( this.headers.add( this.headers.next() ) );
+		this._on( this.headers, events );
+		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
+		this._hoverable( this.headers );
+		this._focusable( this.headers );
+	},
+
+	_eventHandler: function( event ) {
+		var activeChildren, clickedChildren,
+			options = this.options,
+			active = this.active,
+			clicked = $( event.currentTarget ),
+			clickedIsActive = clicked[ 0 ] === active[ 0 ],
+			collapsing = clickedIsActive && options.collapsible,
+			toShow = collapsing ? $() : clicked.next(),
+			toHide = active.next(),
+			eventData = {
+				oldHeader: active,
+				oldPanel: toHide,
+				newHeader: collapsing ? $() : clicked,
+				newPanel: toShow
+			};
+
+		event.preventDefault();
+
+		if (
+
+				// click on active header, but not collapsible
+				( clickedIsActive && !options.collapsible ) ||
+
+				// allow canceling activation
+				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+			return;
+		}
+
+		options.active = collapsing ? false : this.headers.index( clicked );
+
+		// When the call to ._toggle() comes after the class changes
+		// it causes a very odd bug in IE 8 (see #6720)
+		this.active = clickedIsActive ? $() : clicked;
+		this._toggle( eventData );
+
+		// Switch classes
+		// corner classes on the previously active header stay after the animation
+		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
+		if ( options.icons ) {
+			activeChildren = active.children( ".ui-accordion-header-icon" );
+			this._removeClass( activeChildren, null, options.icons.activeHeader )
+				._addClass( activeChildren, null, options.icons.header );
+		}
+
+		if ( !clickedIsActive ) {
+			this._removeClass( clicked, "ui-accordion-header-collapsed" )
+				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
+			if ( options.icons ) {
+				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
+				this._removeClass( clickedChildren, null, options.icons.header )
+					._addClass( clickedChildren, null, options.icons.activeHeader );
+			}
+
+			this._addClass( clicked.next(), "ui-accordion-content-active" );
+		}
+	},
+
+	_toggle: function( data ) {
+		var toShow = data.newPanel,
+			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
+
+		// Handle activating a panel during the animation for another activation
+		this.prevShow.add( this.prevHide ).stop( true, true );
+		this.prevShow = toShow;
+		this.prevHide = toHide;
+
+		if ( this.options.animate ) {
+			this._animate( toShow, toHide, data );
+		} else {
+			toHide.hide();
+			toShow.show();
+			this._toggleComplete( data );
+		}
+
+		toHide.attr( {
+			"aria-hidden": "true"
+		} );
+		toHide.prev().attr( {
+			"aria-selected": "false",
+			"aria-expanded": "false"
+		} );
+
+		// if we're switching panels, remove the old header from the tab order
+		// if we're opening from collapsed state, remove the previous header from the tab order
+		// if we're collapsing, then keep the collapsing header in the tab order
+		if ( toShow.length && toHide.length ) {
+			toHide.prev().attr( {
+				"tabIndex": -1,
+				"aria-expanded": "false"
+			} );
+		} else if ( toShow.length ) {
+			this.headers.filter( function() {
+				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
+			} )
+				.attr( "tabIndex", -1 );
+		}
+
+		toShow
+			.attr( "aria-hidden", "false" )
+			.prev()
+				.attr( {
+					"aria-selected": "true",
+					"aria-expanded": "true",
+					tabIndex: 0
+				} );
+	},
+
+	_animate: function( toShow, toHide, data ) {
+		var total, easing, duration,
+			that = this,
+			adjust = 0,
+			boxSizing = toShow.css( "box-sizing" ),
+			down = toShow.length &&
+				( !toHide.length || ( toShow.index() < toHide.index() ) ),
+			animate = this.options.animate || {},
+			options = down && animate.down || animate,
+			complete = function() {
+				that._toggleComplete( data );
+			};
+
+		if ( typeof options === "number" ) {
+			duration = options;
+		}
+		if ( typeof options === "string" ) {
+			easing = options;
+		}
+
+		// fall back from options to animation in case of partial down settings
+		easing = easing || options.easing || animate.easing;
+		duration = duration || options.duration || animate.duration;
+
+		if ( !toHide.length ) {
+			return toShow.animate( this.showProps, duration, easing, complete );
+		}
+		if ( !toShow.length ) {
+			return toHide.animate( this.hideProps, duration, easing, complete );
+		}
+
+		total = toShow.show().outerHeight();
+		toHide.animate( this.hideProps, {
+			duration: duration,
+			easing: easing,
+			step: function( now, fx ) {
+				fx.now = Math.round( now );
+			}
+		} );
+		toShow
+			.hide()
+			.animate( this.showProps, {
+				duration: duration,
+				easing: easing,
+				complete: complete,
+				step: function( now, fx ) {
+					fx.now = Math.round( now );
+					if ( fx.prop !== "height" ) {
+						if ( boxSizing === "content-box" ) {
+							adjust += fx.now;
+						}
+					} else if ( that.options.heightStyle !== "content" ) {
+						fx.now = Math.round( total - toHide.outerHeight() - adjust );
+						adjust = 0;
+					}
+				}
+			} );
+	},
+
+	_toggleComplete: function( data ) {
+		var toHide = data.oldPanel,
+			prev = toHide.prev();
+
+		this._removeClass( toHide, "ui-accordion-content-active" );
+		this._removeClass( prev, "ui-accordion-header-active" )
+			._addClass( prev, "ui-accordion-header-collapsed" );
+
+		// Work around for rendering bug in IE (#5421)
+		if ( toHide.length ) {
+			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
+		}
+		this._trigger( "activate", null, data );
+	}
+} );
+
+
+
+var safeActiveElement = $.ui.safeActiveElement = function( document ) {
+	var activeElement;
+
+	// Support: IE 9 only
+	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+	try {
+		activeElement = document.activeElement;
+	} catch ( error ) {
+		activeElement = document.body;
+	}
+
+	// Support: IE 9 - 11 only
+	// IE may return null instead of an element
+	// Interestingly, this only seems to occur when NOT in an iframe
+	if ( !activeElement ) {
+		activeElement = document.body;
+	}
+
+	// Support: IE 11 only
+	// IE11 returns a seemingly empty object in some cases when accessing
+	// document.activeElement from an <iframe>
+	if ( !activeElement.nodeName ) {
+		activeElement = document.body;
+	}
+
+	return activeElement;
+};
+
+
+/*!
+ * jQuery UI Menu 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Accordion
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
  */
-(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");
-a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
-if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
-function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a=
-this.options;if(a.icons){c("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
-this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();
-b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target);
-a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+
-c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options;
-if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
-if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(),
-e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight||
-e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",
-"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.14",
-animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);
-f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",
-paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery);
-;/*
- * jQuery UI Autocomplete 1.8.14
+
+//>>label: Menu
+//>>group: Widgets
+//>>description: Creates nestable menus.
+//>>docs: http://api.jqueryui.com/menu/
+//>>demos: http://jqueryui.com/menu/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/menu.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsMenu = $.widget( "ui.menu", {
+	version: "1.12.1",
+	defaultElement: "<ul>",
+	delay: 300,
+	options: {
+		icons: {
+			submenu: "ui-icon-caret-1-e"
+		},
+		items: "> *",
+		menus: "ul",
+		position: {
+			my: "left top",
+			at: "right top"
+		},
+		role: "menu",
+
+		// Callbacks
+		blur: null,
+		focus: null,
+		select: null
+	},
+
+	_create: function() {
+		this.activeMenu = this.element;
+
+		// Flag used to prevent firing of the click handler
+		// as the event bubbles up through nested menus
+		this.mouseHandled = false;
+		this.element
+			.uniqueId()
+			.attr( {
+				role: this.options.role,
+				tabIndex: 0
+			} );
+
+		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
+		this._on( {
+
+			// Prevent focus from sticking to links inside menu after clicking
+			// them (focus should always stay on UL during navigation).
+			"mousedown .ui-menu-item": function( event ) {
+				event.preventDefault();
+			},
+			"click .ui-menu-item": function( event ) {
+				var target = $( event.target );
+				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
+				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
+					this.select( event );
+
+					// Only set the mouseHandled flag if the event will bubble, see #9469.
+					if ( !event.isPropagationStopped() ) {
+						this.mouseHandled = true;
+					}
+
+					// Open submenu on click
+					if ( target.has( ".ui-menu" ).length ) {
+						this.expand( event );
+					} else if ( !this.element.is( ":focus" ) &&
+							active.closest( ".ui-menu" ).length ) {
+
+						// Redirect focus to the menu
+						this.element.trigger( "focus", [ true ] );
+
+						// If the active item is on the top level, let it stay active.
+						// Otherwise, blur the active item since it is no longer visible.
+						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
+							clearTimeout( this.timer );
+						}
+					}
+				}
+			},
+			"mouseenter .ui-menu-item": function( event ) {
+
+				// Ignore mouse events while typeahead is active, see #10458.
+				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
+				// is over an item in the menu
+				if ( this.previousFilter ) {
+					return;
+				}
+
+				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
+					target = $( event.currentTarget );
+
+				// Ignore bubbled events on parent items, see #11641
+				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
+					return;
+				}
+
+				// Remove ui-state-active class from siblings of the newly focused menu item
+				// to avoid a jump caused by adjacent elements both having a class with a border
+				this._removeClass( target.siblings().children( ".ui-state-active" ),
+					null, "ui-state-active" );
+				this.focus( event, target );
+			},
+			mouseleave: "collapseAll",
+			"mouseleave .ui-menu": "collapseAll",
+			focus: function( event, keepActiveItem ) {
+
+				// If there's already an active item, keep it active
+				// If not, activate the first item
+				var item = this.active || this.element.find( this.options.items ).eq( 0 );
+
+				if ( !keepActiveItem ) {
+					this.focus( event, item );
+				}
+			},
+			blur: function( event ) {
+				this._delay( function() {
+					var notContained = !$.contains(
+						this.element[ 0 ],
+						$.ui.safeActiveElement( this.document[ 0 ] )
+					);
+					if ( notContained ) {
+						this.collapseAll( event );
+					}
+				} );
+			},
+			keydown: "_keydown"
+		} );
+
+		this.refresh();
+
+		// Clicks outside of a menu collapse any open menus
+		this._on( this.document, {
+			click: function( event ) {
+				if ( this._closeOnDocumentClick( event ) ) {
+					this.collapseAll( event );
+				}
+
+				// Reset the mouseHandled flag
+				this.mouseHandled = false;
+			}
+		} );
+	},
+
+	_destroy: function() {
+		var items = this.element.find( ".ui-menu-item" )
+				.removeAttr( "role aria-disabled" ),
+			submenus = items.children( ".ui-menu-item-wrapper" )
+				.removeUniqueId()
+				.removeAttr( "tabIndex role aria-haspopup" );
+
+		// Destroy (sub)menus
+		this.element
+			.removeAttr( "aria-activedescendant" )
+			.find( ".ui-menu" ).addBack()
+				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
+					"tabIndex" )
+				.removeUniqueId()
+				.show();
+
+		submenus.children().each( function() {
+			var elem = $( this );
+			if ( elem.data( "ui-menu-submenu-caret" ) ) {
+				elem.remove();
+			}
+		} );
+	},
+
+	_keydown: function( event ) {
+		var match, prev, character, skip,
+			preventDefault = true;
+
+		switch ( event.keyCode ) {
+		case $.ui.keyCode.PAGE_UP:
+			this.previousPage( event );
+			break;
+		case $.ui.keyCode.PAGE_DOWN:
+			this.nextPage( event );
+			break;
+		case $.ui.keyCode.HOME:
+			this._move( "first", "first", event );
+			break;
+		case $.ui.keyCode.END:
+			this._move( "last", "last", event );
+			break;
+		case $.ui.keyCode.UP:
+			this.previous( event );
+			break;
+		case $.ui.keyCode.DOWN:
+			this.next( event );
+			break;
+		case $.ui.keyCode.LEFT:
+			this.collapse( event );
+			break;
+		case $.ui.keyCode.RIGHT:
+			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
+				this.expand( event );
+			}
+			break;
+		case $.ui.keyCode.ENTER:
+		case $.ui.keyCode.SPACE:
+			this._activate( event );
+			break;
+		case $.ui.keyCode.ESCAPE:
+			this.collapse( event );
+			break;
+		default:
+			preventDefault = false;
+			prev = this.previousFilter || "";
+			skip = false;
+
+			// Support number pad values
+			character = event.keyCode >= 96 && event.keyCode <= 105 ?
+				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
+
+			clearTimeout( this.filterTimer );
+
+			if ( character === prev ) {
+				skip = true;
+			} else {
+				character = prev + character;
+			}
+
+			match = this._filterMenuItems( character );
+			match = skip && match.index( this.active.next() ) !== -1 ?
+				this.active.nextAll( ".ui-menu-item" ) :
+				match;
+
+			// If no matches on the current filter, reset to the last character pressed
+			// to move down the menu to the first item that starts with that character
+			if ( !match.length ) {
+				character = String.fromCharCode( event.keyCode );
+				match = this._filterMenuItems( character );
+			}
+
+			if ( match.length ) {
+				this.focus( event, match );
+				this.previousFilter = character;
+				this.filterTimer = this._delay( function() {
+					delete this.previousFilter;
+				}, 1000 );
+			} else {
+				delete this.previousFilter;
+			}
+		}
+
+		if ( preventDefault ) {
+			event.preventDefault();
+		}
+	},
+
+	_activate: function( event ) {
+		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
+			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
+				this.expand( event );
+			} else {
+				this.select( event );
+			}
+		}
+	},
+
+	refresh: function() {
+		var menus, items, newSubmenus, newItems, newWrappers,
+			that = this,
+			icon = this.options.icons.submenu,
+			submenus = this.element.find( this.options.menus );
+
+		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
+
+		// Initialize nested menus
+		newSubmenus = submenus.filter( ":not(.ui-menu)" )
+			.hide()
+			.attr( {
+				role: this.options.role,
+				"aria-hidden": "true",
+				"aria-expanded": "false"
+			} )
+			.each( function() {
+				var menu = $( this ),
+					item = menu.prev(),
+					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
+
+				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
+				item
+					.attr( "aria-haspopup", "true" )
+					.prepend( submenuCaret );
+				menu.attr( "aria-labelledby", item.attr( "id" ) );
+			} );
+
+		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
+
+		menus = submenus.add( this.element );
+		items = menus.find( this.options.items );
+
+		// Initialize menu-items containing spaces and/or dashes only as dividers
+		items.not( ".ui-menu-item" ).each( function() {
+			var item = $( this );
+			if ( that._isDivider( item ) ) {
+				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
+			}
+		} );
+
+		// Don't refresh list items that are already adapted
+		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
+		newWrappers = newItems.children()
+			.not( ".ui-menu" )
+				.uniqueId()
+				.attr( {
+					tabIndex: -1,
+					role: this._itemRole()
+				} );
+		this._addClass( newItems, "ui-menu-item" )
+			._addClass( newWrappers, "ui-menu-item-wrapper" );
+
+		// Add aria-disabled attribute to any disabled menu item
+		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
+
+		// If the active item has been removed, blur the menu
+		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+			this.blur();
+		}
+	},
+
+	_itemRole: function() {
+		return {
+			menu: "menuitem",
+			listbox: "option"
+		}[ this.options.role ];
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "icons" ) {
+			var icons = this.element.find( ".ui-menu-icon" );
+			this._removeClass( icons, null, this.options.icons.submenu )
+				._addClass( icons, null, value.submenu );
+		}
+		this._super( key, value );
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this.element.attr( "aria-disabled", String( value ) );
+		this._toggleClass( null, "ui-state-disabled", !!value );
+	},
+
+	focus: function( event, item ) {
+		var nested, focused, activeParent;
+		this.blur( event, event && event.type === "focus" );
+
+		this._scrollIntoView( item );
+
+		this.active = item.first();
+
+		focused = this.active.children( ".ui-menu-item-wrapper" );
+		this._addClass( focused, null, "ui-state-active" );
+
+		// Only update aria-activedescendant if there's a role
+		// otherwise we assume focus is managed elsewhere
+		if ( this.options.role ) {
+			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
+		}
+
+		// Highlight active parent menu item, if any
+		activeParent = this.active
+			.parent()
+				.closest( ".ui-menu-item" )
+					.children( ".ui-menu-item-wrapper" );
+		this._addClass( activeParent, null, "ui-state-active" );
+
+		if ( event && event.type === "keydown" ) {
+			this._close();
+		} else {
+			this.timer = this._delay( function() {
+				this._close();
+			}, this.delay );
+		}
+
+		nested = item.children( ".ui-menu" );
+		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
+			this._startOpening( nested );
+		}
+		this.activeMenu = item.parent();
+
+		this._trigger( "focus", event, { item: item } );
+	},
+
+	_scrollIntoView: function( item ) {
+		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
+		if ( this._hasScroll() ) {
+			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
+			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
+			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
+			scroll = this.activeMenu.scrollTop();
+			elementHeight = this.activeMenu.height();
+			itemHeight = item.outerHeight();
+
+			if ( offset < 0 ) {
+				this.activeMenu.scrollTop( scroll + offset );
+			} else if ( offset + itemHeight > elementHeight ) {
+				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
+			}
+		}
+	},
+
+	blur: function( event, fromFocus ) {
+		if ( !fromFocus ) {
+			clearTimeout( this.timer );
+		}
+
+		if ( !this.active ) {
+			return;
+		}
+
+		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
+			null, "ui-state-active" );
+
+		this._trigger( "blur", event, { item: this.active } );
+		this.active = null;
+	},
+
+	_startOpening: function( submenu ) {
+		clearTimeout( this.timer );
+
+		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
+		// shift in the submenu position when mousing over the caret icon
+		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
+			return;
+		}
+
+		this.timer = this._delay( function() {
+			this._close();
+			this._open( submenu );
+		}, this.delay );
+	},
+
+	_open: function( submenu ) {
+		var position = $.extend( {
+			of: this.active
+		}, this.options.position );
+
+		clearTimeout( this.timer );
+		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
+			.hide()
+			.attr( "aria-hidden", "true" );
+
+		submenu
+			.show()
+			.removeAttr( "aria-hidden" )
+			.attr( "aria-expanded", "true" )
+			.position( position );
+	},
+
+	collapseAll: function( event, all ) {
+		clearTimeout( this.timer );
+		this.timer = this._delay( function() {
+
+			// If we were passed an event, look for the submenu that contains the event
+			var currentMenu = all ? this.element :
+				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
+
+			// If we found no valid submenu ancestor, use the main menu to close all
+			// sub menus anyway
+			if ( !currentMenu.length ) {
+				currentMenu = this.element;
+			}
+
+			this._close( currentMenu );
+
+			this.blur( event );
+
+			// Work around active item staying active after menu is blurred
+			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
+
+			this.activeMenu = currentMenu;
+		}, this.delay );
+	},
+
+	// With no arguments, closes the currently active menu - if nothing is active
+	// it closes all menus.  If passed an argument, it will search for menus BELOW
+	_close: function( startMenu ) {
+		if ( !startMenu ) {
+			startMenu = this.active ? this.active.parent() : this.element;
+		}
+
+		startMenu.find( ".ui-menu" )
+			.hide()
+			.attr( "aria-hidden", "true" )
+			.attr( "aria-expanded", "false" );
+	},
+
+	_closeOnDocumentClick: function( event ) {
+		return !$( event.target ).closest( ".ui-menu" ).length;
+	},
+
+	_isDivider: function( item ) {
+
+		// Match hyphen, em dash, en dash
+		return !/[^\-\u2014\u2013\s]/.test( item.text() );
+	},
+
+	collapse: function( event ) {
+		var newItem = this.active &&
+			this.active.parent().closest( ".ui-menu-item", this.element );
+		if ( newItem && newItem.length ) {
+			this._close();
+			this.focus( event, newItem );
+		}
+	},
+
+	expand: function( event ) {
+		var newItem = this.active &&
+			this.active
+				.children( ".ui-menu " )
+					.find( this.options.items )
+						.first();
+
+		if ( newItem && newItem.length ) {
+			this._open( newItem.parent() );
+
+			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
+			this._delay( function() {
+				this.focus( event, newItem );
+			} );
+		}
+	},
+
+	next: function( event ) {
+		this._move( "next", "first", event );
+	},
+
+	previous: function( event ) {
+		this._move( "prev", "last", event );
+	},
+
+	isFirstItem: function() {
+		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
+	},
+
+	isLastItem: function() {
+		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
+	},
+
+	_move: function( direction, filter, event ) {
+		var next;
+		if ( this.active ) {
+			if ( direction === "first" || direction === "last" ) {
+				next = this.active
+					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
+					.eq( -1 );
+			} else {
+				next = this.active
+					[ direction + "All" ]( ".ui-menu-item" )
+					.eq( 0 );
+			}
+		}
+		if ( !next || !next.length || !this.active ) {
+			next = this.activeMenu.find( this.options.items )[ filter ]();
+		}
+
+		this.focus( event, next );
+	},
+
+	nextPage: function( event ) {
+		var item, base, height;
+
+		if ( !this.active ) {
+			this.next( event );
+			return;
+		}
+		if ( this.isLastItem() ) {
+			return;
+		}
+		if ( this._hasScroll() ) {
+			base = this.active.offset().top;
+			height = this.element.height();
+			this.active.nextAll( ".ui-menu-item" ).each( function() {
+				item = $( this );
+				return item.offset().top - base - height < 0;
+			} );
+
+			this.focus( event, item );
+		} else {
+			this.focus( event, this.activeMenu.find( this.options.items )
+				[ !this.active ? "first" : "last" ]() );
+		}
+	},
+
+	previousPage: function( event ) {
+		var item, base, height;
+		if ( !this.active ) {
+			this.next( event );
+			return;
+		}
+		if ( this.isFirstItem() ) {
+			return;
+		}
+		if ( this._hasScroll() ) {
+			base = this.active.offset().top;
+			height = this.element.height();
+			this.active.prevAll( ".ui-menu-item" ).each( function() {
+				item = $( this );
+				return item.offset().top - base + height > 0;
+			} );
+
+			this.focus( event, item );
+		} else {
+			this.focus( event, this.activeMenu.find( this.options.items ).first() );
+		}
+	},
+
+	_hasScroll: function() {
+		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
+	},
+
+	select: function( event ) {
+
+		// TODO: It should never be possible to not have an active item at this
+		// point, but the tests don't trigger mouseenter before click.
+		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
+		var ui = { item: this.active };
+		if ( !this.active.has( ".ui-menu" ).length ) {
+			this.collapseAll( event, true );
+		}
+		this._trigger( "select", event, ui );
+	},
+
+	_filterMenuItems: function( character ) {
+		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
+			regex = new RegExp( "^" + escapedCharacter, "i" );
+
+		return this.activeMenu
+			.find( this.options.items )
+
+				// Only match on items, not dividers or other content (#10571)
+				.filter( ".ui-menu-item" )
+					.filter( function() {
+						return regex.test(
+							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
+					} );
+	}
+} );
+
+
+/*!
+ * jQuery UI Autocomplete 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Autocomplete
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
- *	jquery.ui.position.js
  */
-(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g=
-false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=
-a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};
-this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&&
-a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
-d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&
-b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source=
-this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();
-this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||
-b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var g=this;
-d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
-"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery);
-(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
--1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
-this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,
-this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
-this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||
-this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[d.fn.prop?"prop":"attr"]("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery);
-;/*
- * jQuery UI Button 1.8.14
+
+//>>label: Autocomplete
+//>>group: Widgets
+//>>description: Lists suggested words as the user is typing.
+//>>docs: http://api.jqueryui.com/autocomplete/
+//>>demos: http://jqueryui.com/autocomplete/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/autocomplete.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.autocomplete", {
+	version: "1.12.1",
+	defaultElement: "<input>",
+	options: {
+		appendTo: null,
+		autoFocus: false,
+		delay: 300,
+		minLength: 1,
+		position: {
+			my: "left top",
+			at: "left bottom",
+			collision: "none"
+		},
+		source: null,
+
+		// Callbacks
+		change: null,
+		close: null,
+		focus: null,
+		open: null,
+		response: null,
+		search: null,
+		select: null
+	},
+
+	requestIndex: 0,
+	pending: 0,
+
+	_create: function() {
+
+		// Some browsers only repeat keydown events, not keypress events,
+		// so we use the suppressKeyPress flag to determine if we've already
+		// handled the keydown event. #7269
+		// Unfortunately the code for & in keypress is the same as the up arrow,
+		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
+		// events when we know the keydown event was used to modify the
+		// search term. #7799
+		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
+			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
+			isTextarea = nodeName === "textarea",
+			isInput = nodeName === "input";
+
+		// Textareas are always multi-line
+		// Inputs are always single-line, even if inside a contentEditable element
+		// IE also treats inputs as contentEditable
+		// All other element types are determined by whether or not they're contentEditable
+		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
+
+		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
+		this.isNewMenu = true;
+
+		this._addClass( "ui-autocomplete-input" );
+		this.element.attr( "autocomplete", "off" );
+
+		this._on( this.element, {
+			keydown: function( event ) {
+				if ( this.element.prop( "readOnly" ) ) {
+					suppressKeyPress = true;
+					suppressInput = true;
+					suppressKeyPressRepeat = true;
+					return;
+				}
+
+				suppressKeyPress = false;
+				suppressInput = false;
+				suppressKeyPressRepeat = false;
+				var keyCode = $.ui.keyCode;
+				switch ( event.keyCode ) {
+				case keyCode.PAGE_UP:
+					suppressKeyPress = true;
+					this._move( "previousPage", event );
+					break;
+				case keyCode.PAGE_DOWN:
+					suppressKeyPress = true;
+					this._move( "nextPage", event );
+					break;
+				case keyCode.UP:
+					suppressKeyPress = true;
+					this._keyEvent( "previous", event );
+					break;
+				case keyCode.DOWN:
+					suppressKeyPress = true;
+					this._keyEvent( "next", event );
+					break;
+				case keyCode.ENTER:
+
+					// when menu is open and has focus
+					if ( this.menu.active ) {
+
+						// #6055 - Opera still allows the keypress to occur
+						// which causes forms to submit
+						suppressKeyPress = true;
+						event.preventDefault();
+						this.menu.select( event );
+					}
+					break;
+				case keyCode.TAB:
+					if ( this.menu.active ) {
+						this.menu.select( event );
+					}
+					break;
+				case keyCode.ESCAPE:
+					if ( this.menu.element.is( ":visible" ) ) {
+						if ( !this.isMultiLine ) {
+							this._value( this.term );
+						}
+						this.close( event );
+
+						// Different browsers have different default behavior for escape
+						// Single press can mean undo or clear
+						// Double press in IE means clear the whole form
+						event.preventDefault();
+					}
+					break;
+				default:
+					suppressKeyPressRepeat = true;
+
+					// search timeout should be triggered before the input value is changed
+					this._searchTimeout( event );
+					break;
+				}
+			},
+			keypress: function( event ) {
+				if ( suppressKeyPress ) {
+					suppressKeyPress = false;
+					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+						event.preventDefault();
+					}
+					return;
+				}
+				if ( suppressKeyPressRepeat ) {
+					return;
+				}
+
+				// Replicate some key handlers to allow them to repeat in Firefox and Opera
+				var keyCode = $.ui.keyCode;
+				switch ( event.keyCode ) {
+				case keyCode.PAGE_UP:
+					this._move( "previousPage", event );
+					break;
+				case keyCode.PAGE_DOWN:
+					this._move( "nextPage", event );
+					break;
+				case keyCode.UP:
+					this._keyEvent( "previous", event );
+					break;
+				case keyCode.DOWN:
+					this._keyEvent( "next", event );
+					break;
+				}
+			},
+			input: function( event ) {
+				if ( suppressInput ) {
+					suppressInput = false;
+					event.preventDefault();
+					return;
+				}
+				this._searchTimeout( event );
+			},
+			focus: function() {
+				this.selectedItem = null;
+				this.previous = this._value();
+			},
+			blur: function( event ) {
+				if ( this.cancelBlur ) {
+					delete this.cancelBlur;
+					return;
+				}
+
+				clearTimeout( this.searching );
+				this.close( event );
+				this._change( event );
+			}
+		} );
+
+		this._initSource();
+		this.menu = $( "<ul>" )
+			.appendTo( this._appendTo() )
+			.menu( {
+
+				// disable ARIA support, the live region takes care of that
+				role: null
+			} )
+			.hide()
+			.menu( "instance" );
+
+		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
+		this._on( this.menu.element, {
+			mousedown: function( event ) {
+
+				// prevent moving focus out of the text field
+				event.preventDefault();
+
+				// IE doesn't prevent moving focus even with event.preventDefault()
+				// so we set a flag to know when we should ignore the blur event
+				this.cancelBlur = true;
+				this._delay( function() {
+					delete this.cancelBlur;
+
+					// Support: IE 8 only
+					// Right clicking a menu item or selecting text from the menu items will
+					// result in focus moving out of the input. However, we've already received
+					// and ignored the blur event because of the cancelBlur flag set above. So
+					// we restore focus to ensure that the menu closes properly based on the user's
+					// next actions.
+					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
+						this.element.trigger( "focus" );
+					}
+				} );
+			},
+			menufocus: function( event, ui ) {
+				var label, item;
+
+				// support: Firefox
+				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
+				if ( this.isNewMenu ) {
+					this.isNewMenu = false;
+					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
+						this.menu.blur();
+
+						this.document.one( "mousemove", function() {
+							$( event.target ).trigger( event.originalEvent );
+						} );
+
+						return;
+					}
+				}
+
+				item = ui.item.data( "ui-autocomplete-item" );
+				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
+
+					// use value to match what will end up in the input, if it was a key event
+					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
+						this._value( item.value );
+					}
+				}
+
+				// Announce the value in the liveRegion
+				label = ui.item.attr( "aria-label" ) || item.value;
+				if ( label && $.trim( label ).length ) {
+					this.liveRegion.children().hide();
+					$( "<div>" ).text( label ).appendTo( this.liveRegion );
+				}
+			},
+			menuselect: function( event, ui ) {
+				var item = ui.item.data( "ui-autocomplete-item" ),
+					previous = this.previous;
+
+				// Only trigger when focus was lost (click on menu)
+				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
+					this.element.trigger( "focus" );
+					this.previous = previous;
+
+					// #6109 - IE triggers two focus events and the second
+					// is asynchronous, so we need to reset the previous
+					// term synchronously and asynchronously :-(
+					this._delay( function() {
+						this.previous = previous;
+						this.selectedItem = item;
+					} );
+				}
+
+				if ( false !== this._trigger( "select", event, { item: item } ) ) {
+					this._value( item.value );
+				}
+
+				// reset the term after the select event
+				// this allows custom select handling to work properly
+				this.term = this._value();
+
+				this.close( event );
+				this.selectedItem = item;
+			}
+		} );
+
+		this.liveRegion = $( "<div>", {
+			role: "status",
+			"aria-live": "assertive",
+			"aria-relevant": "additions"
+		} )
+			.appendTo( this.document[ 0 ].body );
+
+		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
+
+		// Turning off autocomplete prevents the browser from remembering the
+		// value when navigating through history, so we re-enable autocomplete
+		// if the page is unloaded before the widget is destroyed. #7790
+		this._on( this.window, {
+			beforeunload: function() {
+				this.element.removeAttr( "autocomplete" );
+			}
+		} );
+	},
+
+	_destroy: function() {
+		clearTimeout( this.searching );
+		this.element.removeAttr( "autocomplete" );
+		this.menu.element.remove();
+		this.liveRegion.remove();
+	},
+
+	_setOption: function( key, value ) {
+		this._super( key, value );
+		if ( key === "source" ) {
+			this._initSource();
+		}
+		if ( key === "appendTo" ) {
+			this.menu.element.appendTo( this._appendTo() );
+		}
+		if ( key === "disabled" && value && this.xhr ) {
+			this.xhr.abort();
+		}
+	},
+
+	_isEventTargetInWidget: function( event ) {
+		var menuElement = this.menu.element[ 0 ];
+
+		return event.target === this.element[ 0 ] ||
+			event.target === menuElement ||
+			$.contains( menuElement, event.target );
+	},
+
+	_closeOnClickOutside: function( event ) {
+		if ( !this._isEventTargetInWidget( event ) ) {
+			this.close();
+		}
+	},
+
+	_appendTo: function() {
+		var element = this.options.appendTo;
+
+		if ( element ) {
+			element = element.jquery || element.nodeType ?
+				$( element ) :
+				this.document.find( element ).eq( 0 );
+		}
+
+		if ( !element || !element[ 0 ] ) {
+			element = this.element.closest( ".ui-front, dialog" );
+		}
+
+		if ( !element.length ) {
+			element = this.document[ 0 ].body;
+		}
+
+		return element;
+	},
+
+	_initSource: function() {
+		var array, url,
+			that = this;
+		if ( $.isArray( this.options.source ) ) {
+			array = this.options.source;
+			this.source = function( request, response ) {
+				response( $.ui.autocomplete.filter( array, request.term ) );
+			};
+		} else if ( typeof this.options.source === "string" ) {
+			url = this.options.source;
+			this.source = function( request, response ) {
+				if ( that.xhr ) {
+					that.xhr.abort();
+				}
+				that.xhr = $.ajax( {
+					url: url,
+					data: request,
+					dataType: "json",
+					success: function( data ) {
+						response( data );
+					},
+					error: function() {
+						response( [] );
+					}
+				} );
+			};
+		} else {
+			this.source = this.options.source;
+		}
+	},
+
+	_searchTimeout: function( event ) {
+		clearTimeout( this.searching );
+		this.searching = this._delay( function() {
+
+			// Search if the value has changed, or if the user retypes the same value (see #7434)
+			var equalValues = this.term === this._value(),
+				menuVisible = this.menu.element.is( ":visible" ),
+				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
+
+			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
+				this.selectedItem = null;
+				this.search( null, event );
+			}
+		}, this.options.delay );
+	},
+
+	search: function( value, event ) {
+		value = value != null ? value : this._value();
+
+		// Always save the actual value, not the one passed as an argument
+		this.term = this._value();
+
+		if ( value.length < this.options.minLength ) {
+			return this.close( event );
+		}
+
+		if ( this._trigger( "search", event ) === false ) {
+			return;
+		}
+
+		return this._search( value );
+	},
+
+	_search: function( value ) {
+		this.pending++;
+		this._addClass( "ui-autocomplete-loading" );
+		this.cancelSearch = false;
+
+		this.source( { term: value }, this._response() );
+	},
+
+	_response: function() {
+		var index = ++this.requestIndex;
+
+		return $.proxy( function( content ) {
+			if ( index === this.requestIndex ) {
+				this.__response( content );
+			}
+
+			this.pending--;
+			if ( !this.pending ) {
+				this._removeClass( "ui-autocomplete-loading" );
+			}
+		}, this );
+	},
+
+	__response: function( content ) {
+		if ( content ) {
+			content = this._normalize( content );
+		}
+		this._trigger( "response", null, { content: content } );
+		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
+			this._suggest( content );
+			this._trigger( "open" );
+		} else {
+
+			// use ._close() instead of .close() so we don't cancel future searches
+			this._close();
+		}
+	},
+
+	close: function( event ) {
+		this.cancelSearch = true;
+		this._close( event );
+	},
+
+	_close: function( event ) {
+
+		// Remove the handler that closes the menu on outside clicks
+		this._off( this.document, "mousedown" );
+
+		if ( this.menu.element.is( ":visible" ) ) {
+			this.menu.element.hide();
+			this.menu.blur();
+			this.isNewMenu = true;
+			this._trigger( "close", event );
+		}
+	},
+
+	_change: function( event ) {
+		if ( this.previous !== this._value() ) {
+			this._trigger( "change", event, { item: this.selectedItem } );
+		}
+	},
+
+	_normalize: function( items ) {
+
+		// assume all items have the right format when the first item is complete
+		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
+			return items;
+		}
+		return $.map( items, function( item ) {
+			if ( typeof item === "string" ) {
+				return {
+					label: item,
+					value: item
+				};
+			}
+			return $.extend( {}, item, {
+				label: item.label || item.value,
+				value: item.value || item.label
+			} );
+		} );
+	},
+
+	_suggest: function( items ) {
+		var ul = this.menu.element.empty();
+		this._renderMenu( ul, items );
+		this.isNewMenu = true;
+		this.menu.refresh();
+
+		// Size and position menu
+		ul.show();
+		this._resizeMenu();
+		ul.position( $.extend( {
+			of: this.element
+		}, this.options.position ) );
+
+		if ( this.options.autoFocus ) {
+			this.menu.next();
+		}
+
+		// Listen for interactions outside of the widget (#6642)
+		this._on( this.document, {
+			mousedown: "_closeOnClickOutside"
+		} );
+	},
+
+	_resizeMenu: function() {
+		var ul = this.menu.element;
+		ul.outerWidth( Math.max(
+
+			// Firefox wraps long text (possibly a rounding bug)
+			// so we add 1px to avoid the wrapping (#7513)
+			ul.width( "" ).outerWidth() + 1,
+			this.element.outerWidth()
+		) );
+	},
+
+	_renderMenu: function( ul, items ) {
+		var that = this;
+		$.each( items, function( index, item ) {
+			that._renderItemData( ul, item );
+		} );
+	},
+
+	_renderItemData: function( ul, item ) {
+		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
+	},
+
+	_renderItem: function( ul, item ) {
+		return $( "<li>" )
+			.append( $( "<div>" ).text( item.label ) )
+			.appendTo( ul );
+	},
+
+	_move: function( direction, event ) {
+		if ( !this.menu.element.is( ":visible" ) ) {
+			this.search( null, event );
+			return;
+		}
+		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
+				this.menu.isLastItem() && /^next/.test( direction ) ) {
+
+			if ( !this.isMultiLine ) {
+				this._value( this.term );
+			}
+
+			this.menu.blur();
+			return;
+		}
+		this.menu[ direction ]( event );
+	},
+
+	widget: function() {
+		return this.menu.element;
+	},
+
+	_value: function() {
+		return this.valueMethod.apply( this.element, arguments );
+	},
+
+	_keyEvent: function( keyEvent, event ) {
+		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
+			this._move( keyEvent, event );
+
+			// Prevents moving cursor to beginning/end of the text field in some browsers
+			event.preventDefault();
+		}
+	},
+
+	// Support: Chrome <=50
+	// We should be able to just use this.element.prop( "isContentEditable" )
+	// but hidden elements always report false in Chrome.
+	// https://code.google.com/p/chromium/issues/detail?id=313082
+	_isContentEditable: function( element ) {
+		if ( !element.length ) {
+			return false;
+		}
+
+		var editable = element.prop( "contentEditable" );
+
+		if ( editable === "inherit" ) {
+		  return this._isContentEditable( element.parent() );
+		}
+
+		return editable === "true";
+	}
+} );
+
+$.extend( $.ui.autocomplete, {
+	escapeRegex: function( value ) {
+		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
+	},
+	filter: function( array, term ) {
+		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
+		return $.grep( array, function( value ) {
+			return matcher.test( value.label || value.value || value );
+		} );
+	}
+} );
+
+// Live region extension, adding a `messages` option
+// NOTE: This is an experimental API. We are still investigating
+// a full solution for string manipulation and internationalization.
+$.widget( "ui.autocomplete", $.ui.autocomplete, {
+	options: {
+		messages: {
+			noResults: "No search results.",
+			results: function( amount ) {
+				return amount + ( amount > 1 ? " results are" : " result is" ) +
+					" available, use up and down arrow keys to navigate.";
+			}
+		}
+	},
+
+	__response: function( content ) {
+		var message;
+		this._superApply( arguments );
+		if ( this.options.disabled || this.cancelSearch ) {
+			return;
+		}
+		if ( content && content.length ) {
+			message = this.options.messages.results( content.length );
+		} else {
+			message = this.options.messages.noResults;
+		}
+		this.liveRegion.children().hide();
+		$( "<div>" ).text( message ).appendTo( this.liveRegion );
+	}
+} );
+
+var widgetsAutocomplete = $.ui.autocomplete;
+
+
+/*!
+ * jQuery UI Controlgroup 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Button
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
  */
-(function(b){var h,i,j,g,l=function(){var a=b(this).find(":ui-button");setTimeout(function(){a.button("refresh")},1)},k=function(a){var c=a.name,e=a.form,f=b([]);if(c)f=e?b(e).find("[name='"+c+"']"):b("[name='"+c+"']",a.ownerDocument).filter(function(){return!this.form});return f};b.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",l);if(typeof this.options.disabled!==
-"boolean")this.options.disabled=this.element.attr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var a=this,c=this.options,e=this.type==="checkbox"||this.type==="radio",f="ui-state-hover"+(!e?" ui-state-active":"");if(c.label===null)c.label=this.buttonElement.html();if(this.element.is(":disabled"))c.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!c.disabled){b(this).addClass("ui-state-hover");
-this===h&&b(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){c.disabled||b(this).removeClass(f)}).bind("click.button",function(d){if(c.disabled){d.preventDefault();d.stopImmediatePropagation()}});this.element.bind("focus.button",function(){a.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){a.buttonElement.removeClass("ui-state-focus")});if(e){this.element.bind("change.button",function(){g||a.refresh()});this.buttonElement.bind("mousedown.button",function(d){if(!c.disabled){g=
-false;i=d.pageX;j=d.pageY}}).bind("mouseup.button",function(d){if(!c.disabled)if(i!==d.pageX||j!==d.pageY)g=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).toggleClass("ui-state-active");a.buttonElement.attr("aria-pressed",a.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(c.disabled||g)return false;b(this).addClass("ui-state-active");a.buttonElement.attr("aria-pressed",true);
-var d=a.element[0];k(d).not(d).map(function(){return b(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)});else{this.buttonElement.bind("mousedown.button",function(){if(c.disabled)return false;b(this).addClass("ui-state-active");h=this;b(document).one("mouseup",function(){h=null})}).bind("mouseup.button",function(){if(c.disabled)return false;b(this).removeClass("ui-state-active")}).bind("keydown.button",function(d){if(c.disabled)return false;if(d.keyCode==b.ui.keyCode.SPACE||
-d.keyCode==b.ui.keyCode.ENTER)b(this).addClass("ui-state-active")}).bind("keyup.button",function(){b(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(d){d.keyCode===b.ui.keyCode.SPACE&&b(this).click()})}this._setOption("disabled",c.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type===
-"radio"){var a=this.element.parents().filter(":last"),c="label[for="+this.element.attr("id")+"]";this.buttonElement=a.find(c);if(!this.buttonElement.length){a=a.length?a.siblings():this.element.siblings();this.buttonElement=a.filter(c);if(!this.buttonElement.length)this.buttonElement=a.find(c)}this.element.addClass("ui-helper-hidden-accessible");(a=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",a)}else this.buttonElement=this.element},
-widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active  ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");
-b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);if(a==="disabled")c?this.element.attr("disabled",true):this.element.removeAttr("disabled");else this._resetButton()},refresh:function(){var a=this.element.is(":disabled");a!==this.options.disabled&&this._setOption("disabled",a);if(this.type==="radio")k(this.element[0]).each(function(){b(this).is(":checked")?b(this).button("widget").addClass("ui-state-active").attr("aria-pressed",true):
-b(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",false)});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",true):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",false)},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var a=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
-c=b("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("<span class='ui-button-icon-primary ui-icon "+e.primary+"'></span>");e.secondary&&a.append("<span class='ui-button-icon-secondary ui-icon "+e.secondary+"'></span>");if(!this.options.text){d.push(f?"ui-button-icons-only":
-"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")===
-"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
-b.Widget.prototype.destroy.call(this)}})})(jQuery);
-;/*
- * jQuery UI Dialog 1.8.14
+
+//>>label: Controlgroup
+//>>group: Widgets
+//>>description: Visually groups form control widgets
+//>>docs: http://api.jqueryui.com/controlgroup/
+//>>demos: http://jqueryui.com/controlgroup/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/controlgroup.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
+
+var widgetsControlgroup = $.widget( "ui.controlgroup", {
+	version: "1.12.1",
+	defaultElement: "<div>",
+	options: {
+		direction: "horizontal",
+		disabled: null,
+		onlyVisible: true,
+		items: {
+			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
+			"controlgroupLabel": ".ui-controlgroup-label",
+			"checkboxradio": "input[type='checkbox'], input[type='radio']",
+			"selectmenu": "select",
+			"spinner": ".ui-spinner-input"
+		}
+	},
+
+	_create: function() {
+		this._enhance();
+	},
+
+	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
+	_enhance: function() {
+		this.element.attr( "role", "toolbar" );
+		this.refresh();
+	},
+
+	_destroy: function() {
+		this._callChildMethod( "destroy" );
+		this.childWidgets.removeData( "ui-controlgroup-data" );
+		this.element.removeAttr( "role" );
+		if ( this.options.items.controlgroupLabel ) {
+			this.element
+				.find( this.options.items.controlgroupLabel )
+				.find( ".ui-controlgroup-label-contents" )
+				.contents().unwrap();
+		}
+	},
+
+	_initWidgets: function() {
+		var that = this,
+			childWidgets = [];
+
+		// First we iterate over each of the items options
+		$.each( this.options.items, function( widget, selector ) {
+			var labels;
+			var options = {};
+
+			// Make sure the widget has a selector set
+			if ( !selector ) {
+				return;
+			}
+
+			if ( widget === "controlgroupLabel" ) {
+				labels = that.element.find( selector );
+				labels.each( function() {
+					var element = $( this );
+
+					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
+						return;
+					}
+					element.contents()
+						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
+				} );
+				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
+				childWidgets = childWidgets.concat( labels.get() );
+				return;
+			}
+
+			// Make sure the widget actually exists
+			if ( !$.fn[ widget ] ) {
+				return;
+			}
+
+			// We assume everything is in the middle to start because we can't determine
+			// first / last elements until all enhancments are done.
+			if ( that[ "_" + widget + "Options" ] ) {
+				options = that[ "_" + widget + "Options" ]( "middle" );
+			} else {
+				options = { classes: {} };
+			}
+
+			// Find instances of this widget inside controlgroup and init them
+			that.element
+				.find( selector )
+				.each( function() {
+					var element = $( this );
+					var instance = element[ widget ]( "instance" );
+
+					// We need to clone the default options for this type of widget to avoid
+					// polluting the variable options which has a wider scope than a single widget.
+					var instanceOptions = $.widget.extend( {}, options );
+
+					// If the button is the child of a spinner ignore it
+					// TODO: Find a more generic solution
+					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
+						return;
+					}
+
+					// Create the widget if it doesn't exist
+					if ( !instance ) {
+						instance = element[ widget ]()[ widget ]( "instance" );
+					}
+					if ( instance ) {
+						instanceOptions.classes =
+							that._resolveClassesValues( instanceOptions.classes, instance );
+					}
+					element[ widget ]( instanceOptions );
+
+					// Store an instance of the controlgroup to be able to reference
+					// from the outermost element for changing options and refresh
+					var widgetElement = element[ widget ]( "widget" );
+					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
+						instance ? instance : element[ widget ]( "instance" ) );
+
+					childWidgets.push( widgetElement[ 0 ] );
+				} );
+		} );
+
+		this.childWidgets = $( $.unique( childWidgets ) );
+		this._addClass( this.childWidgets, "ui-controlgroup-item" );
+	},
+
+	_callChildMethod: function( method ) {
+		this.childWidgets.each( function() {
+			var element = $( this ),
+				data = element.data( "ui-controlgroup-data" );
+			if ( data && data[ method ] ) {
+				data[ method ]();
+			}
+		} );
+	},
+
+	_updateCornerClass: function( element, position ) {
+		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
+		var add = this._buildSimpleOptions( position, "label" ).classes.label;
+
+		this._removeClass( element, null, remove );
+		this._addClass( element, null, add );
+	},
+
+	_buildSimpleOptions: function( position, key ) {
+		var direction = this.options.direction === "vertical";
+		var result = {
+			classes: {}
+		};
+		result.classes[ key ] = {
+			"middle": "",
+			"first": "ui-corner-" + ( direction ? "top" : "left" ),
+			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
+			"only": "ui-corner-all"
+		}[ position ];
+
+		return result;
+	},
+
+	_spinnerOptions: function( position ) {
+		var options = this._buildSimpleOptions( position, "ui-spinner" );
+
+		options.classes[ "ui-spinner-up" ] = "";
+		options.classes[ "ui-spinner-down" ] = "";
+
+		return options;
+	},
+
+	_buttonOptions: function( position ) {
+		return this._buildSimpleOptions( position, "ui-button" );
+	},
+
+	_checkboxradioOptions: function( position ) {
+		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
+	},
+
+	_selectmenuOptions: function( position ) {
+		var direction = this.options.direction === "vertical";
+		return {
+			width: direction ? "auto" : false,
+			classes: {
+				middle: {
+					"ui-selectmenu-button-open": "",
+					"ui-selectmenu-button-closed": ""
+				},
+				first: {
+					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
+					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
+				},
+				last: {
+					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
+					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
+				},
+				only: {
+					"ui-selectmenu-button-open": "ui-corner-top",
+					"ui-selectmenu-button-closed": "ui-corner-all"
+				}
+
+			}[ position ]
+		};
+	},
+
+	_resolveClassesValues: function( classes, instance ) {
+		var result = {};
+		$.each( classes, function( key ) {
+			var current = instance.options.classes[ key ] || "";
+			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
+			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
+		} );
+		return result;
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "direction" ) {
+			this._removeClass( "ui-controlgroup-" + this.options.direction );
+		}
+
+		this._super( key, value );
+		if ( key === "disabled" ) {
+			this._callChildMethod( value ? "disable" : "enable" );
+			return;
+		}
+
+		this.refresh();
+	},
+
+	refresh: function() {
+		var children,
+			that = this;
+
+		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
+
+		if ( this.options.direction === "horizontal" ) {
+			this._addClass( null, "ui-helper-clearfix" );
+		}
+		this._initWidgets();
+
+		children = this.childWidgets;
+
+		// We filter here because we need to track all childWidgets not just the visible ones
+		if ( this.options.onlyVisible ) {
+			children = children.filter( ":visible" );
+		}
+
+		if ( children.length ) {
+
+			// We do this last because we need to make sure all enhancment is done
+			// before determining first and last
+			$.each( [ "first", "last" ], function( index, value ) {
+				var instance = children[ value ]().data( "ui-controlgroup-data" );
+
+				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
+					var options = that[ "_" + instance.widgetName + "Options" ](
+						children.length === 1 ? "only" : value
+					);
+					options.classes = that._resolveClassesValues( options.classes, instance );
+					instance.element[ instance.widgetName ]( options );
+				} else {
+					that._updateCornerClass( children[ value ](), value );
+				}
+			} );
+
+			// Finally call the refresh method on each of the child widgets.
+			this._callChildMethod( "refresh" );
+		}
+	}
+} );
+
+/*!
+ * jQuery UI Checkboxradio 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Dialog
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
- *  jquery.ui.button.js
- *	jquery.ui.draggable.js
- *	jquery.ui.mouse.js
- *	jquery.ui.position.js
- *	jquery.ui.resizable.js
  */
-(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
-position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||"&#160;",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
-b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),
-h=c('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("<span></span>")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("<span></span>").addClass("ui-dialog-title").attr("id",
-e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
-a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!==
-b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=
-1;d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target===
-f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,
-function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('<button type="button"></button>').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
-handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,
-originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",
-f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):
-[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f);
-if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):
-e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||"&#160;"));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a=
-this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height-
-b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.14",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),
-create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()<c.ui.dialog.overlay.maxZ)return false})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
-height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
-b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a<b?c(window).height()+"px":a+"px"}else return c(document).height()+"px"},width:function(){var a,b;if(c.browser.msie){a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);b=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return a<b?c(window).width()+"px":a+"px"}else return c(document).width()+"px"},resize:function(){var a=c([]);c.each(c.ui.dialog.overlay.instances,function(){a=
-a.add(this)});a.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
-;/*
- * jQuery UI Slider 1.8.14
+
+//>>label: Checkboxradio
+//>>group: Widgets
+//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
+//>>docs: http://api.jqueryui.com/checkboxradio/
+//>>demos: http://jqueryui.com/checkboxradio/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/button.css
+//>>css.structure: ../../themes/base/checkboxradio.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
+	version: "1.12.1",
+	options: {
+		disabled: null,
+		label: null,
+		icon: true,
+		classes: {
+			"ui-checkboxradio-label": "ui-corner-all",
+			"ui-checkboxradio-icon": "ui-corner-all"
+		}
+	},
+
+	_getCreateOptions: function() {
+		var disabled, labels;
+		var that = this;
+		var options = this._super() || {};
+
+		// We read the type here, because it makes more sense to throw a element type error first,
+		// rather then the error for lack of a label. Often if its the wrong type, it
+		// won't have a label (e.g. calling on a div, btn, etc)
+		this._readType();
+
+		labels = this.element.labels();
+
+		// If there are multiple labels, use the last one
+		this.label = $( labels[ labels.length - 1 ] );
+		if ( !this.label.length ) {
+			$.error( "No label found for checkboxradio widget" );
+		}
+
+		this.originalLabel = "";
+
+		// We need to get the label text but this may also need to make sure it does not contain the
+		// input itself.
+		this.label.contents().not( this.element[ 0 ] ).each( function() {
+
+			// The label contents could be text, html, or a mix. We concat each element to get a
+			// string representation of the label, without the input as part of it.
+			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
+		} );
+
+		// Set the label option if we found label text
+		if ( this.originalLabel ) {
+			options.label = this.originalLabel;
+		}
+
+		disabled = this.element[ 0 ].disabled;
+		if ( disabled != null ) {
+			options.disabled = disabled;
+		}
+		return options;
+	},
+
+	_create: function() {
+		var checked = this.element[ 0 ].checked;
+
+		this._bindFormResetHandler();
+
+		if ( this.options.disabled == null ) {
+			this.options.disabled = this.element[ 0 ].disabled;
+		}
+
+		this._setOption( "disabled", this.options.disabled );
+		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
+		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
+
+		if ( this.type === "radio" ) {
+			this._addClass( this.label, "ui-checkboxradio-radio-label" );
+		}
+
+		if ( this.options.label && this.options.label !== this.originalLabel ) {
+			this._updateLabel();
+		} else if ( this.originalLabel ) {
+			this.options.label = this.originalLabel;
+		}
+
+		this._enhance();
+
+		if ( checked ) {
+			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
+			if ( this.icon ) {
+				this._addClass( this.icon, null, "ui-state-hover" );
+			}
+		}
+
+		this._on( {
+			change: "_toggleClasses",
+			focus: function() {
+				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
+			},
+			blur: function() {
+				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
+			}
+		} );
+	},
+
+	_readType: function() {
+		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
+		this.type = this.element[ 0 ].type;
+		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
+			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
+				" and element.type=" + this.type );
+		}
+	},
+
+	// Support jQuery Mobile enhanced option
+	_enhance: function() {
+		this._updateIcon( this.element[ 0 ].checked );
+	},
+
+	widget: function() {
+		return this.label;
+	},
+
+	_getRadioGroup: function() {
+		var group;
+		var name = this.element[ 0 ].name;
+		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
+
+		if ( !name ) {
+			return $( [] );
+		}
+
+		if ( this.form.length ) {
+			group = $( this.form[ 0 ].elements ).filter( nameSelector );
+		} else {
+
+			// Not inside a form, check all inputs that also are not inside a form
+			group = $( nameSelector ).filter( function() {
+				return $( this ).form().length === 0;
+			} );
+		}
+
+		return group.not( this.element );
+	},
+
+	_toggleClasses: function() {
+		var checked = this.element[ 0 ].checked;
+		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
+
+		if ( this.options.icon && this.type === "checkbox" ) {
+			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
+				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
+		}
+
+		if ( this.type === "radio" ) {
+			this._getRadioGroup()
+				.each( function() {
+					var instance = $( this ).checkboxradio( "instance" );
+
+					if ( instance ) {
+						instance._removeClass( instance.label,
+							"ui-checkboxradio-checked", "ui-state-active" );
+					}
+				} );
+		}
+	},
+
+	_destroy: function() {
+		this._unbindFormResetHandler();
+
+		if ( this.icon ) {
+			this.icon.remove();
+			this.iconSpace.remove();
+		}
+	},
+
+	_setOption: function( key, value ) {
+
+		// We don't allow the value to be set to nothing
+		if ( key === "label" && !value ) {
+			return;
+		}
+
+		this._super( key, value );
+
+		if ( key === "disabled" ) {
+			this._toggleClass( this.label, null, "ui-state-disabled", value );
+			this.element[ 0 ].disabled = value;
+
+			// Don't refresh when setting disabled
+			return;
+		}
+		this.refresh();
+	},
+
+	_updateIcon: function( checked ) {
+		var toAdd = "ui-icon ui-icon-background ";
+
+		if ( this.options.icon ) {
+			if ( !this.icon ) {
+				this.icon = $( "<span>" );
+				this.iconSpace = $( "<span> </span>" );
+				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
+			}
+
+			if ( this.type === "checkbox" ) {
+				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
+				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
+			} else {
+				toAdd += "ui-icon-blank";
+			}
+			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
+			if ( !checked ) {
+				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
+			}
+			this.icon.prependTo( this.label ).after( this.iconSpace );
+		} else if ( this.icon !== undefined ) {
+			this.icon.remove();
+			this.iconSpace.remove();
+			delete this.icon;
+		}
+	},
+
+	_updateLabel: function() {
+
+		// Remove the contents of the label ( minus the icon, icon space, and input )
+		var contents = this.label.contents().not( this.element[ 0 ] );
+		if ( this.icon ) {
+			contents = contents.not( this.icon[ 0 ] );
+		}
+		if ( this.iconSpace ) {
+			contents = contents.not( this.iconSpace[ 0 ] );
+		}
+		contents.remove();
+
+		this.label.append( this.options.label );
+	},
+
+	refresh: function() {
+		var checked = this.element[ 0 ].checked,
+			isDisabled = this.element[ 0 ].disabled;
+
+		this._updateIcon( checked );
+		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
+		if ( this.options.label !== null ) {
+			this._updateLabel();
+		}
+
+		if ( isDisabled !== this.options.disabled ) {
+			this._setOptions( { "disabled": isDisabled } );
+		}
+	}
+
+} ] );
+
+var widgetsCheckboxradio = $.ui.checkboxradio;
+
+
+/*!
+ * jQuery UI Button 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.mouse.js
- *	jquery.ui.widget.js
  */
-(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var b=this,a=this.options,c=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f=a.values&&a.values.length||1,e=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+
-this.orientation+" ui-widget ui-widget-content ui-corner-all"+(a.disabled?" ui-slider-disabled ui-disabled":""));this.range=d([]);if(a.range){if(a.range===true){if(!a.values)a.values=[this._valueMin(),this._valueMin()];if(a.values.length&&a.values.length!==2)a.values=[a.values[0],a.values[0]]}this.range=d("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(a.range==="min"||a.range==="max"?" ui-slider-range-"+a.range:""))}for(var j=c.length;j<f;j+=1)e.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>");
-this.handles=c.add(d(e.join("")).appendTo(b.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){a.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(a.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle",
-g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!b.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!b._keySliding){b._keySliding=true;d(this).addClass("ui-state-active");i=b._start(g,l);if(i===false)return}break}m=b.options.step;i=b.options.values&&b.options.values.length?
-(h=b.values(l)):(h=b.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=b._valueMin();break;case d.ui.keyCode.END:h=b._valueMax();break;case d.ui.keyCode.PAGE_UP:h=b._trimAlignValue(i+(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(i-(b._valueMax()-b._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===b._valueMax())return;h=b._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===b._valueMin())return;h=b._trimAlignValue(i-
-m);break}b._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(b._keySliding){b._keySliding=false;b._stop(g,k);b._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();
-return this},_mouseCapture:function(b){var a=this.options,c,f,e,j,g;if(a.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:b.pageX,y:b.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(a.range===true&&this.values(1)===a.min){g+=1;e=d(this.handles[g])}if(this._start(b,g)===false)return false;
-this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();a=e.offset();this._clickOffset=!d(b.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:b.pageX-a.left-e.width()/2,top:b.pageY-a.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(b,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(b){var a=
-this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,this._handleIndex,a);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(b){var a;if(this.orientation==="horizontal"){a=
-this.elementSize.width;b=b.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{a=this.elementSize.height;b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}a=b/a;if(a>1)a=1;if(a<0)a=0;if(this.orientation==="vertical")a=1-a;b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+a*b)},_start:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);
-c.values=this.values()}return this._trigger("start",b,c)},_slide:function(b,a,c){var f;if(this.options.values&&this.options.values.length){f=this.values(a?0:1);if(this.options.values.length===2&&this.options.range===true&&(a===0&&c>f||a===1&&c<f))c=f;if(c!==this.values(a)){f=this.values();f[a]=c;b=this._trigger("slide",b,{handle:this.handles[a],value:c,values:f});this.values(a?0:1);b!==false&&this.values(a,c,true)}}else if(c!==this.value()){b=this._trigger("slide",b,{handle:this.handles[a],value:c});
-b!==false&&this.value(c)}},_stop:function(b,a){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("stop",b,c)},_change:function(b,a){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[a],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(a);c.values=this.values()}this._trigger("change",b,c)}},value:function(b){if(arguments.length){this.options.value=
-this._trimAlignValue(b);this._refreshValue();this._change(null,0)}else return this._value()},values:function(b,a){var c,f,e;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(a);this._refreshValue();this._change(null,b)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e<c.length;e+=1){c[e]=this._trimAlignValue(f[e]);this._change(null,e)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(b):
-this.value();else return this._values()},_setOption:function(b,a){var c,f=0;if(d.isArray(this.options.values))f=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(b){case "disabled":if(a){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
-this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<f;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var b=this.options.value;return b=this._trimAlignValue(b)},_values:function(b){var a,c;if(arguments.length){a=this.options.values[b];
-return a=this._trimAlignValue(a)}else{a=this.options.values.slice();for(c=0;c<a.length;c+=1)a[c]=this._trimAlignValue(a[c]);return a}},_trimAlignValue:function(b){if(b<=this._valueMin())return this._valueMin();if(b>=this._valueMax())return this._valueMax();var a=this.options.step>0?this.options.step:1,c=(b-this._valueMin())%a;alignValue=b-c;if(Math.abs(c)*2>=a)alignValue+=c>0?a:-a;return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},
-_refreshValue:function(){var b=this.options.range,a=this.options,c=this,f=!this._animateOff?a.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,a.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},a.animate);
-if(h===1)c.range[f?"animate":"css"]({width:e-g+"%"},{queue:false,duration:a.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},a.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:a.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,a.animate);if(b==="min"&&this.orientation==="horizontal")this.range.stop(1,
-1)[f?"animate":"css"]({width:e+"%"},a.animate);if(b==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:a.animate});if(b==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},a.animate);if(b==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:a.animate})}}});d.extend(d.ui.slider,{version:"1.8.14"})})(jQuery);
-;/*
- * jQuery UI Tabs 1.8.14
+
+//>>label: Button
+//>>group: Widgets
+//>>description: Enhances a form with themeable buttons.
+//>>docs: http://api.jqueryui.com/button/
+//>>demos: http://jqueryui.com/button/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/button.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.button", {
+	version: "1.12.1",
+	defaultElement: "<button>",
+	options: {
+		classes: {
+			"ui-button": "ui-corner-all"
+		},
+		disabled: null,
+		icon: null,
+		iconPosition: "beginning",
+		label: null,
+		showLabel: true
+	},
+
+	_getCreateOptions: function() {
+		var disabled,
+
+			// This is to support cases like in jQuery Mobile where the base widget does have
+			// an implementation of _getCreateOptions
+			options = this._super() || {};
+
+		this.isInput = this.element.is( "input" );
+
+		disabled = this.element[ 0 ].disabled;
+		if ( disabled != null ) {
+			options.disabled = disabled;
+		}
+
+		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
+		if ( this.originalLabel ) {
+			options.label = this.originalLabel;
+		}
+
+		return options;
+	},
+
+	_create: function() {
+		if ( !this.option.showLabel & !this.options.icon ) {
+			this.options.showLabel = true;
+		}
+
+		// We have to check the option again here even though we did in _getCreateOptions,
+		// because null may have been passed on init which would override what was set in
+		// _getCreateOptions
+		if ( this.options.disabled == null ) {
+			this.options.disabled = this.element[ 0 ].disabled || false;
+		}
+
+		this.hasTitle = !!this.element.attr( "title" );
+
+		// Check to see if the label needs to be set or if its already correct
+		if ( this.options.label && this.options.label !== this.originalLabel ) {
+			if ( this.isInput ) {
+				this.element.val( this.options.label );
+			} else {
+				this.element.html( this.options.label );
+			}
+		}
+		this._addClass( "ui-button", "ui-widget" );
+		this._setOption( "disabled", this.options.disabled );
+		this._enhance();
+
+		if ( this.element.is( "a" ) ) {
+			this._on( {
+				"keyup": function( event ) {
+					if ( event.keyCode === $.ui.keyCode.SPACE ) {
+						event.preventDefault();
+
+						// Support: PhantomJS <= 1.9, IE 8 Only
+						// If a native click is available use it so we actually cause navigation
+						// otherwise just trigger a click event
+						if ( this.element[ 0 ].click ) {
+							this.element[ 0 ].click();
+						} else {
+							this.element.trigger( "click" );
+						}
+					}
+				}
+			} );
+		}
+	},
+
+	_enhance: function() {
+		if ( !this.element.is( "button" ) ) {
+			this.element.attr( "role", "button" );
+		}
+
+		if ( this.options.icon ) {
+			this._updateIcon( "icon", this.options.icon );
+			this._updateTooltip();
+		}
+	},
+
+	_updateTooltip: function() {
+		this.title = this.element.attr( "title" );
+
+		if ( !this.options.showLabel && !this.title ) {
+			this.element.attr( "title", this.options.label );
+		}
+	},
+
+	_updateIcon: function( option, value ) {
+		var icon = option !== "iconPosition",
+			position = icon ? this.options.iconPosition : value,
+			displayBlock = position === "top" || position === "bottom";
+
+		// Create icon
+		if ( !this.icon ) {
+			this.icon = $( "<span>" );
+
+			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
+
+			if ( !this.options.showLabel ) {
+				this._addClass( "ui-button-icon-only" );
+			}
+		} else if ( icon ) {
+
+			// If we are updating the icon remove the old icon class
+			this._removeClass( this.icon, null, this.options.icon );
+		}
+
+		// If we are updating the icon add the new icon class
+		if ( icon ) {
+			this._addClass( this.icon, null, value );
+		}
+
+		this._attachIcon( position );
+
+		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
+		// the iconSpace if there is one.
+		if ( displayBlock ) {
+			this._addClass( this.icon, null, "ui-widget-icon-block" );
+			if ( this.iconSpace ) {
+				this.iconSpace.remove();
+			}
+		} else {
+
+			// Position is beginning or end so remove the ui-widget-icon-block class and add the
+			// space if it does not exist
+			if ( !this.iconSpace ) {
+				this.iconSpace = $( "<span> </span>" );
+				this._addClass( this.iconSpace, "ui-button-icon-space" );
+			}
+			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
+			this._attachIconSpace( position );
+		}
+	},
+
+	_destroy: function() {
+		this.element.removeAttr( "role" );
+
+		if ( this.icon ) {
+			this.icon.remove();
+		}
+		if ( this.iconSpace ) {
+			this.iconSpace.remove();
+		}
+		if ( !this.hasTitle ) {
+			this.element.removeAttr( "title" );
+		}
+	},
+
+	_attachIconSpace: function( iconPosition ) {
+		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
+	},
+
+	_attachIcon: function( iconPosition ) {
+		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
+	},
+
+	_setOptions: function( options ) {
+		var newShowLabel = options.showLabel === undefined ?
+				this.options.showLabel :
+				options.showLabel,
+			newIcon = options.icon === undefined ? this.options.icon : options.icon;
+
+		if ( !newShowLabel && !newIcon ) {
+			options.showLabel = true;
+		}
+		this._super( options );
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "icon" ) {
+			if ( value ) {
+				this._updateIcon( key, value );
+			} else if ( this.icon ) {
+				this.icon.remove();
+				if ( this.iconSpace ) {
+					this.iconSpace.remove();
+				}
+			}
+		}
+
+		if ( key === "iconPosition" ) {
+			this._updateIcon( key, value );
+		}
+
+		// Make sure we can't end up with a button that has neither text nor icon
+		if ( key === "showLabel" ) {
+				this._toggleClass( "ui-button-icon-only", null, !value );
+				this._updateTooltip();
+		}
+
+		if ( key === "label" ) {
+			if ( this.isInput ) {
+				this.element.val( value );
+			} else {
+
+				// If there is an icon, append it, else nothing then append the value
+				// this avoids removal of the icon when setting label text
+				this.element.html( value );
+				if ( this.icon ) {
+					this._attachIcon( this.options.iconPosition );
+					this._attachIconSpace( this.options.iconPosition );
+				}
+			}
+		}
+
+		this._super( key, value );
+
+		if ( key === "disabled" ) {
+			this._toggleClass( null, "ui-state-disabled", value );
+			this.element[ 0 ].disabled = value;
+			if ( value ) {
+				this.element.blur();
+			}
+		}
+	},
+
+	refresh: function() {
+
+		// Make sure to only check disabled if its an element that supports this otherwise
+		// check for the disabled class to determine state
+		var isDisabled = this.element.is( "input, button" ) ?
+			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
+
+		if ( isDisabled !== this.options.disabled ) {
+			this._setOptions( { disabled: isDisabled } );
+		}
+
+		this._updateTooltip();
+	}
+} );
+
+// DEPRECATED
+if ( $.uiBackCompat !== false ) {
+
+	// Text and Icons options
+	$.widget( "ui.button", $.ui.button, {
+		options: {
+			text: true,
+			icons: {
+				primary: null,
+				secondary: null
+			}
+		},
+
+		_create: function() {
+			if ( this.options.showLabel && !this.options.text ) {
+				this.options.showLabel = this.options.text;
+			}
+			if ( !this.options.showLabel && this.options.text ) {
+				this.options.text = this.options.showLabel;
+			}
+			if ( !this.options.icon && ( this.options.icons.primary ||
+					this.options.icons.secondary ) ) {
+				if ( this.options.icons.primary ) {
+					this.options.icon = this.options.icons.primary;
+				} else {
+					this.options.icon = this.options.icons.secondary;
+					this.options.iconPosition = "end";
+				}
+			} else if ( this.options.icon ) {
+				this.options.icons.primary = this.options.icon;
+			}
+			this._super();
+		},
+
+		_setOption: function( key, value ) {
+			if ( key === "text" ) {
+				this._super( "showLabel", value );
+				return;
+			}
+			if ( key === "showLabel" ) {
+				this.options.text = value;
+			}
+			if ( key === "icon" ) {
+				this.options.icons.primary = value;
+			}
+			if ( key === "icons" ) {
+				if ( value.primary ) {
+					this._super( "icon", value.primary );
+					this._super( "iconPosition", "beginning" );
+				} else if ( value.secondary ) {
+					this._super( "icon", value.secondary );
+					this._super( "iconPosition", "end" );
+				}
+			}
+			this._superApply( arguments );
+		}
+	} );
+
+	$.fn.button = ( function( orig ) {
+		return function() {
+			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
+					( this.length && this[ 0 ].tagName === "INPUT" && (
+						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
+					) ) ) {
+				return orig.apply( this, arguments );
+			}
+			if ( !$.ui.checkboxradio ) {
+				$.error( "Checkboxradio widget missing" );
+			}
+			if ( arguments.length === 0 ) {
+				return this.checkboxradio( {
+					"icon": false
+				} );
+			}
+			return this.checkboxradio.apply( this, arguments );
+		};
+	} )( $.fn.button );
+
+	$.fn.buttonset = function() {
+		if ( !$.ui.controlgroup ) {
+			$.error( "Controlgroup widget missing" );
+		}
+		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
+			return this.controlgroup.apply( this,
+				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
+		}
+		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
+			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
+		}
+		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
+			arguments[ 0 ].items = {
+				button: arguments[ 0 ].items
+			};
+		}
+		return this.controlgroup.apply( this, arguments );
+	};
+}
+
+var widgetsButton = $.ui.button;
+
+
+// jscs:disable maximumLineLength
+/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
+/*!
+ * jQuery UI Datepicker 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Tabs
- *
- * Depends:
- *	jquery.ui.core.js
- *	jquery.ui.widget.js
  */
-(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&&
-e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=
-d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]||
-(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
-this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected=
-this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
-if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
-this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+
-g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",
-function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};
-this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected=
--1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
-d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=
-d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b,
-e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);
-j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();
-if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1<this.anchors.length?1:-1));e.disabled=d.map(d.grep(e.disabled,function(h){return h!=b}),function(h){return h>=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null,
-this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this},
-load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c,
-"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
-url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.14"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k<a.anchors.length?k:0)},b);j&&j.stopPropagation()});e=a._unrotate||(a._unrotate=!e?function(j){j.clientX&&
-a.rotate(null)}:function(){t=c.selected;h()});if(b){this.element.bind("tabsshow",h);this.anchors.bind(c.event+".tabs",e);h()}else{clearTimeout(a.rotation);this.element.unbind("tabsshow",h);this.anchors.unbind(c.event+".tabs",e);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
-;/*
- * jQuery UI Datepicker 1.8.14
+
+//>>label: Datepicker
+//>>group: Widgets
+//>>description: Displays a calendar from an input or inline for selecting dates.
+//>>docs: http://api.jqueryui.com/datepicker/
+//>>demos: http://jqueryui.com/datepicker/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/datepicker.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
+
+var datepicker_instActive;
+
+function datepicker_getZindex( elem ) {
+	var position, value;
+	while ( elem.length && elem[ 0 ] !== document ) {
+
+		// Ignore z-index if position is set to a value where z-index is ignored by the browser
+		// This makes behavior of this function consistent across browsers
+		// WebKit always returns auto if the element is positioned
+		position = elem.css( "position" );
+		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+
+			// IE returns 0 when zIndex is not specified
+			// other browsers return a string
+			// we ignore the case of nested elements with an explicit value of 0
+			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+			value = parseInt( elem.css( "zIndex" ), 10 );
+			if ( !isNaN( value ) && value !== 0 ) {
+				return value;
+			}
+		}
+		elem = elem.parent();
+	}
+
+	return 0;
+}
+/* Date picker manager.
+   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+   Settings for (groups of) date pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Datepicker() {
+	this._curInst = null; // The current instance in use
+	this._keyEvent = false; // If the last event was a key event
+	this._disabledInputs = []; // List of date picker inputs that have been disabled
+	this._datepickerShowing = false; // True if the popup picker is showing , false if not
+	this._inDialog = false; // True if showing within a "dialog", false if not
+	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
+	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
+	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
+	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
+	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
+	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
+	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
+	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
+	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
+	this.regional = []; // Available regional settings, indexed by language code
+	this.regional[ "" ] = { // Default regional settings
+		closeText: "Done", // Display text for close link
+		prevText: "Prev", // Display text for previous month link
+		nextText: "Next", // Display text for next month link
+		currentText: "Today", // Display text for current month link
+		monthNames: [ "January","February","March","April","May","June",
+			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
+		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
+		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
+		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
+		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
+		weekHeader: "Wk", // Column header for week of the year
+		dateFormat: "mm/dd/yy", // See format options on parseDate
+		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+		isRTL: false, // True if right-to-left language, false if left-to-right
+		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+		yearSuffix: "" // Additional text to append to the year in the month headers
+	};
+	this._defaults = { // Global defaults for all the date picker instances
+		showOn: "focus", // "focus" for popup on focus,
+			// "button" for trigger button, or "both" for either
+		showAnim: "fadeIn", // Name of jQuery animation for popup
+		showOptions: {}, // Options for enhanced animations
+		defaultDate: null, // Used when field is blank: actual date,
+			// +/-number for offset from today, null for today
+		appendText: "", // Display text following the input box, e.g. showing the format
+		buttonText: "...", // Text for trigger button
+		buttonImage: "", // URL for trigger button image
+		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+		hideIfNoPrevNext: false, // True to hide next/previous month links
+			// if not applicable, false to just disable them
+		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+		gotoCurrent: false, // True if today link goes back to current selection instead
+		changeMonth: false, // True if month can be selected directly, false if only prev/next
+		changeYear: false, // True if year can be selected directly, false if only prev/next
+		yearRange: "c-10:c+10", // Range of years to display in drop-down,
+			// either relative to today's year (-nn:+nn), relative to currently displayed year
+			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+		showOtherMonths: false, // True to show dates in other months, false to leave blank
+		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+		showWeek: false, // True to show week of the year, false to not show it
+		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+			// takes a Date and returns the number of the week for it
+		shortYearCutoff: "+10", // Short year values < this are in the current century,
+			// > this are in the previous century,
+			// string value starting with "+" for current year + value
+		minDate: null, // The earliest selectable date, or null for no limit
+		maxDate: null, // The latest selectable date, or null for no limit
+		duration: "fast", // Duration of display/closure
+		beforeShowDay: null, // Function that takes a date and returns an array with
+			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
+			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
+		beforeShow: null, // Function that takes an input field and
+			// returns a set of custom settings for the date picker
+		onSelect: null, // Define a callback function when a date is selected
+		onChangeMonthYear: null, // Define a callback function when the month or year is changed
+		onClose: null, // Define a callback function when the datepicker is closed
+		numberOfMonths: 1, // Number of months to show at a time
+		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+		stepMonths: 1, // Number of months to step back/forward
+		stepBigMonths: 12, // Number of months to step back/forward for the big links
+		altField: "", // Selector for an alternate field to store selected dates into
+		altFormat: "", // The date format to use for the alternate field
+		constrainInput: true, // The input is constrained by the current date format
+		showButtonPanel: false, // True to show button panel, false to not show it
+		autoSize: false, // True to size the input for the date format, false to leave as is
+		disabled: false // The initial disabled state
+	};
+	$.extend( this._defaults, this.regional[ "" ] );
+	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
+	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
+	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
+}
+
+$.extend( Datepicker.prototype, {
+	/* Class name added to elements to indicate already configured with a date picker. */
+	markerClassName: "hasDatepicker",
+
+	//Keep track of the maximum number of rows displayed (see #7043)
+	maxRows: 4,
+
+	// TODO rename to "widget" when switching to widget factory
+	_widgetDatepicker: function() {
+		return this.dpDiv;
+	},
+
+	/* Override the default settings for all instances of the date picker.
+	 * @param  settings  object - the new settings to use as defaults (anonymous object)
+	 * @return the manager object
+	 */
+	setDefaults: function( settings ) {
+		datepicker_extendRemove( this._defaults, settings || {} );
+		return this;
+	},
+
+	/* Attach the date picker to a jQuery selection.
+	 * @param  target	element - the target input field or division or span
+	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
+	 */
+	_attachDatepicker: function( target, settings ) {
+		var nodeName, inline, inst;
+		nodeName = target.nodeName.toLowerCase();
+		inline = ( nodeName === "div" || nodeName === "span" );
+		if ( !target.id ) {
+			this.uuid += 1;
+			target.id = "dp" + this.uuid;
+		}
+		inst = this._newInst( $( target ), inline );
+		inst.settings = $.extend( {}, settings || {} );
+		if ( nodeName === "input" ) {
+			this._connectDatepicker( target, inst );
+		} else if ( inline ) {
+			this._inlineDatepicker( target, inst );
+		}
+	},
+
+	/* Create a new instance object. */
+	_newInst: function( target, inline ) {
+		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
+		return { id: id, input: target, // associated target
+			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+			drawMonth: 0, drawYear: 0, // month being drawn
+			inline: inline, // is datepicker inline or not
+			dpDiv: ( !inline ? this.dpDiv : // presentation div
+			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
+	},
+
+	/* Attach the date picker to an input field. */
+	_connectDatepicker: function( target, inst ) {
+		var input = $( target );
+		inst.append = $( [] );
+		inst.trigger = $( [] );
+		if ( input.hasClass( this.markerClassName ) ) {
+			return;
+		}
+		this._attachments( input, inst );
+		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
+			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
+		this._autoSize( inst );
+		$.data( target, "datepicker", inst );
+
+		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
+		if ( inst.settings.disabled ) {
+			this._disableDatepicker( target );
+		}
+	},
+
+	/* Make attachments based on settings. */
+	_attachments: function( input, inst ) {
+		var showOn, buttonText, buttonImage,
+			appendText = this._get( inst, "appendText" ),
+			isRTL = this._get( inst, "isRTL" );
+
+		if ( inst.append ) {
+			inst.append.remove();
+		}
+		if ( appendText ) {
+			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
+			input[ isRTL ? "before" : "after" ]( inst.append );
+		}
+
+		input.off( "focus", this._showDatepicker );
+
+		if ( inst.trigger ) {
+			inst.trigger.remove();
+		}
+
+		showOn = this._get( inst, "showOn" );
+		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
+			input.on( "focus", this._showDatepicker );
+		}
+		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
+			buttonText = this._get( inst, "buttonText" );
+			buttonImage = this._get( inst, "buttonImage" );
+			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
+				$( "<img/>" ).addClass( this._triggerClass ).
+					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
+				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
+					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
+					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
+			input[ isRTL ? "before" : "after" ]( inst.trigger );
+			inst.trigger.on( "click", function() {
+				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
+					$.datepicker._hideDatepicker();
+				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
+					$.datepicker._hideDatepicker();
+					$.datepicker._showDatepicker( input[ 0 ] );
+				} else {
+					$.datepicker._showDatepicker( input[ 0 ] );
+				}
+				return false;
+			} );
+		}
+	},
+
+	/* Apply the maximum length for the date format. */
+	_autoSize: function( inst ) {
+		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
+			var findMax, max, maxI, i,
+				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
+				dateFormat = this._get( inst, "dateFormat" );
+
+			if ( dateFormat.match( /[DM]/ ) ) {
+				findMax = function( names ) {
+					max = 0;
+					maxI = 0;
+					for ( i = 0; i < names.length; i++ ) {
+						if ( names[ i ].length > max ) {
+							max = names[ i ].length;
+							maxI = i;
+						}
+					}
+					return maxI;
+				};
+				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
+					"monthNames" : "monthNamesShort" ) ) ) );
+				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
+					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
+			}
+			inst.input.attr( "size", this._formatDate( inst, date ).length );
+		}
+	},
+
+	/* Attach an inline date picker to a div. */
+	_inlineDatepicker: function( target, inst ) {
+		var divSpan = $( target );
+		if ( divSpan.hasClass( this.markerClassName ) ) {
+			return;
+		}
+		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
+		$.data( target, "datepicker", inst );
+		this._setDate( inst, this._getDefaultDate( inst ), true );
+		this._updateDatepicker( inst );
+		this._updateAlternate( inst );
+
+		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
+		if ( inst.settings.disabled ) {
+			this._disableDatepicker( target );
+		}
+
+		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
+		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
+		inst.dpDiv.css( "display", "block" );
+	},
+
+	/* Pop-up the date picker in a "dialog" box.
+	 * @param  input element - ignored
+	 * @param  date	string or Date - the initial date to display
+	 * @param  onSelect  function - the function to call when a date is selected
+	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
+	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
+	 *					event - with x/y coordinates or
+	 *					leave empty for default (screen centre)
+	 * @return the manager object
+	 */
+	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
+		var id, browserWidth, browserHeight, scrollX, scrollY,
+			inst = this._dialogInst; // internal instance
+
+		if ( !inst ) {
+			this.uuid += 1;
+			id = "dp" + this.uuid;
+			this._dialogInput = $( "<input type='text' id='" + id +
+				"' style='position: absolute; top: -100px; width: 0px;'/>" );
+			this._dialogInput.on( "keydown", this._doKeyDown );
+			$( "body" ).append( this._dialogInput );
+			inst = this._dialogInst = this._newInst( this._dialogInput, false );
+			inst.settings = {};
+			$.data( this._dialogInput[ 0 ], "datepicker", inst );
+		}
+		datepicker_extendRemove( inst.settings, settings || {} );
+		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
+		this._dialogInput.val( date );
+
+		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
+		if ( !this._pos ) {
+			browserWidth = document.documentElement.clientWidth;
+			browserHeight = document.documentElement.clientHeight;
+			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+			this._pos = // should use actual width/height below
+				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
+		}
+
+		// Move input on screen for focus, but hidden behind dialog
+		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
+		inst.settings.onSelect = onSelect;
+		this._inDialog = true;
+		this.dpDiv.addClass( this._dialogClass );
+		this._showDatepicker( this._dialogInput[ 0 ] );
+		if ( $.blockUI ) {
+			$.blockUI( this.dpDiv );
+		}
+		$.data( this._dialogInput[ 0 ], "datepicker", inst );
+		return this;
+	},
+
+	/* Detach a datepicker from its control.
+	 * @param  target	element - the target input field or division or span
+	 */
+	_destroyDatepicker: function( target ) {
+		var nodeName,
+			$target = $( target ),
+			inst = $.data( target, "datepicker" );
+
+		if ( !$target.hasClass( this.markerClassName ) ) {
+			return;
+		}
+
+		nodeName = target.nodeName.toLowerCase();
+		$.removeData( target, "datepicker" );
+		if ( nodeName === "input" ) {
+			inst.append.remove();
+			inst.trigger.remove();
+			$target.removeClass( this.markerClassName ).
+				off( "focus", this._showDatepicker ).
+				off( "keydown", this._doKeyDown ).
+				off( "keypress", this._doKeyPress ).
+				off( "keyup", this._doKeyUp );
+		} else if ( nodeName === "div" || nodeName === "span" ) {
+			$target.removeClass( this.markerClassName ).empty();
+		}
+
+		if ( datepicker_instActive === inst ) {
+			datepicker_instActive = null;
+		}
+	},
+
+	/* Enable the date picker to a jQuery selection.
+	 * @param  target	element - the target input field or division or span
+	 */
+	_enableDatepicker: function( target ) {
+		var nodeName, inline,
+			$target = $( target ),
+			inst = $.data( target, "datepicker" );
+
+		if ( !$target.hasClass( this.markerClassName ) ) {
+			return;
+		}
+
+		nodeName = target.nodeName.toLowerCase();
+		if ( nodeName === "input" ) {
+			target.disabled = false;
+			inst.trigger.filter( "button" ).
+				each( function() { this.disabled = false; } ).end().
+				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
+		} else if ( nodeName === "div" || nodeName === "span" ) {
+			inline = $target.children( "." + this._inlineClass );
+			inline.children().removeClass( "ui-state-disabled" );
+			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
+				prop( "disabled", false );
+		}
+		this._disabledInputs = $.map( this._disabledInputs,
+			function( value ) { return ( value === target ? null : value ); } ); // delete entry
+	},
+
+	/* Disable the date picker to a jQuery selection.
+	 * @param  target	element - the target input field or division or span
+	 */
+	_disableDatepicker: function( target ) {
+		var nodeName, inline,
+			$target = $( target ),
+			inst = $.data( target, "datepicker" );
+
+		if ( !$target.hasClass( this.markerClassName ) ) {
+			return;
+		}
+
+		nodeName = target.nodeName.toLowerCase();
+		if ( nodeName === "input" ) {
+			target.disabled = true;
+			inst.trigger.filter( "button" ).
+				each( function() { this.disabled = true; } ).end().
+				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
+		} else if ( nodeName === "div" || nodeName === "span" ) {
+			inline = $target.children( "." + this._inlineClass );
+			inline.children().addClass( "ui-state-disabled" );
+			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
+				prop( "disabled", true );
+		}
+		this._disabledInputs = $.map( this._disabledInputs,
+			function( value ) { return ( value === target ? null : value ); } ); // delete entry
+		this._disabledInputs[ this._disabledInputs.length ] = target;
+	},
+
+	/* Is the first field in a jQuery collection disabled as a datepicker?
+	 * @param  target	element - the target input field or division or span
+	 * @return boolean - true if disabled, false if enabled
+	 */
+	_isDisabledDatepicker: function( target ) {
+		if ( !target ) {
+			return false;
+		}
+		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
+			if ( this._disabledInputs[ i ] === target ) {
+				return true;
+			}
+		}
+		return false;
+	},
+
+	/* Retrieve the instance data for the target control.
+	 * @param  target  element - the target input field or division or span
+	 * @return  object - the associated instance data
+	 * @throws  error if a jQuery problem getting data
+	 */
+	_getInst: function( target ) {
+		try {
+			return $.data( target, "datepicker" );
+		}
+		catch ( err ) {
+			throw "Missing instance data for this datepicker";
+		}
+	},
+
+	/* Update or retrieve the settings for a date picker attached to an input field or division.
+	 * @param  target  element - the target input field or division or span
+	 * @param  name	object - the new settings to update or
+	 *				string - the name of the setting to change or retrieve,
+	 *				when retrieving also "all" for all instance settings or
+	 *				"defaults" for all global defaults
+	 * @param  value   any - the new value for the setting
+	 *				(omit if above is an object or to retrieve a value)
+	 */
+	_optionDatepicker: function( target, name, value ) {
+		var settings, date, minDate, maxDate,
+			inst = this._getInst( target );
+
+		if ( arguments.length === 2 && typeof name === "string" ) {
+			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
+				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
+				this._get( inst, name ) ) : null ) );
+		}
+
+		settings = name || {};
+		if ( typeof name === "string" ) {
+			settings = {};
+			settings[ name ] = value;
+		}
+
+		if ( inst ) {
+			if ( this._curInst === inst ) {
+				this._hideDatepicker();
+			}
+
+			date = this._getDateDatepicker( target, true );
+			minDate = this._getMinMaxDate( inst, "min" );
+			maxDate = this._getMinMaxDate( inst, "max" );
+			datepicker_extendRemove( inst.settings, settings );
+
+			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
+				inst.settings.minDate = this._formatDate( inst, minDate );
+			}
+			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
+				inst.settings.maxDate = this._formatDate( inst, maxDate );
+			}
+			if ( "disabled" in settings ) {
+				if ( settings.disabled ) {
+					this._disableDatepicker( target );
+				} else {
+					this._enableDatepicker( target );
+				}
+			}
+			this._attachments( $( target ), inst );
+			this._autoSize( inst );
+			this._setDate( inst, date );
+			this._updateAlternate( inst );
+			this._updateDatepicker( inst );
+		}
+	},
+
+	// Change method deprecated
+	_changeDatepicker: function( target, name, value ) {
+		this._optionDatepicker( target, name, value );
+	},
+
+	/* Redraw the date picker attached to an input field or division.
+	 * @param  target  element - the target input field or division or span
+	 */
+	_refreshDatepicker: function( target ) {
+		var inst = this._getInst( target );
+		if ( inst ) {
+			this._updateDatepicker( inst );
+		}
+	},
+
+	/* Set the dates for a jQuery selection.
+	 * @param  target element - the target input field or division or span
+	 * @param  date	Date - the new date
+	 */
+	_setDateDatepicker: function( target, date ) {
+		var inst = this._getInst( target );
+		if ( inst ) {
+			this._setDate( inst, date );
+			this._updateDatepicker( inst );
+			this._updateAlternate( inst );
+		}
+	},
+
+	/* Get the date(s) for the first entry in a jQuery selection.
+	 * @param  target element - the target input field or division or span
+	 * @param  noDefault boolean - true if no default date is to be used
+	 * @return Date - the current date
+	 */
+	_getDateDatepicker: function( target, noDefault ) {
+		var inst = this._getInst( target );
+		if ( inst && !inst.inline ) {
+			this._setDateFromField( inst, noDefault );
+		}
+		return ( inst ? this._getDate( inst ) : null );
+	},
+
+	/* Handle keystrokes. */
+	_doKeyDown: function( event ) {
+		var onSelect, dateStr, sel,
+			inst = $.datepicker._getInst( event.target ),
+			handled = true,
+			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
+
+		inst._keyEvent = true;
+		if ( $.datepicker._datepickerShowing ) {
+			switch ( event.keyCode ) {
+				case 9: $.datepicker._hideDatepicker();
+						handled = false;
+						break; // hide on tab out
+				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
+									$.datepicker._currentClass + ")", inst.dpDiv );
+						if ( sel[ 0 ] ) {
+							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
+						}
+
+						onSelect = $.datepicker._get( inst, "onSelect" );
+						if ( onSelect ) {
+							dateStr = $.datepicker._formatDate( inst );
+
+							// Trigger custom callback
+							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
+						} else {
+							$.datepicker._hideDatepicker();
+						}
+
+						return false; // don't submit the form
+				case 27: $.datepicker._hideDatepicker();
+						break; // hide on escape
+				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
+							-$.datepicker._get( inst, "stepBigMonths" ) :
+							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
+						break; // previous month/year on page up/+ ctrl
+				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
+							+$.datepicker._get( inst, "stepBigMonths" ) :
+							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
+						break; // next month/year on page down/+ ctrl
+				case 35: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._clearDate( event.target );
+						}
+						handled = event.ctrlKey || event.metaKey;
+						break; // clear on ctrl or command +end
+				case 36: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._gotoToday( event.target );
+						}
+						handled = event.ctrlKey || event.metaKey;
+						break; // current on ctrl or command +home
+				case 37: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
+						}
+						handled = event.ctrlKey || event.metaKey;
+
+						// -1 day on ctrl or command +left
+						if ( event.originalEvent.altKey ) {
+							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
+								-$.datepicker._get( inst, "stepBigMonths" ) :
+								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
+						}
+
+						// next month/year on alt +left on Mac
+						break;
+				case 38: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._adjustDate( event.target, -7, "D" );
+						}
+						handled = event.ctrlKey || event.metaKey;
+						break; // -1 week on ctrl or command +up
+				case 39: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
+						}
+						handled = event.ctrlKey || event.metaKey;
+
+						// +1 day on ctrl or command +right
+						if ( event.originalEvent.altKey ) {
+							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
+								+$.datepicker._get( inst, "stepBigMonths" ) :
+								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
+						}
+
+						// next month/year on alt +right
+						break;
+				case 40: if ( event.ctrlKey || event.metaKey ) {
+							$.datepicker._adjustDate( event.target, +7, "D" );
+						}
+						handled = event.ctrlKey || event.metaKey;
+						break; // +1 week on ctrl or command +down
+				default: handled = false;
+			}
+		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
+			$.datepicker._showDatepicker( this );
+		} else {
+			handled = false;
+		}
+
+		if ( handled ) {
+			event.preventDefault();
+			event.stopPropagation();
+		}
+	},
+
+	/* Filter entered characters - based on date format. */
+	_doKeyPress: function( event ) {
+		var chars, chr,
+			inst = $.datepicker._getInst( event.target );
+
+		if ( $.datepicker._get( inst, "constrainInput" ) ) {
+			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
+			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
+			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
+		}
+	},
+
+	/* Synchronise manual entry and field/alternate field. */
+	_doKeyUp: function( event ) {
+		var date,
+			inst = $.datepicker._getInst( event.target );
+
+		if ( inst.input.val() !== inst.lastVal ) {
+			try {
+				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
+					( inst.input ? inst.input.val() : null ),
+					$.datepicker._getFormatConfig( inst ) );
+
+				if ( date ) { // only if valid
+					$.datepicker._setDateFromField( inst );
+					$.datepicker._updateAlternate( inst );
+					$.datepicker._updateDatepicker( inst );
+				}
+			}
+			catch ( err ) {
+			}
+		}
+		return true;
+	},
+
+	/* Pop-up the date picker for a given input field.
+	 * If false returned from beforeShow event handler do not show.
+	 * @param  input  element - the input field attached to the date picker or
+	 *					event - if triggered by focus
+	 */
+	_showDatepicker: function( input ) {
+		input = input.target || input;
+		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
+			input = $( "input", input.parentNode )[ 0 ];
+		}
+
+		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
+			return;
+		}
+
+		var inst, beforeShow, beforeShowSettings, isFixed,
+			offset, showAnim, duration;
+
+		inst = $.datepicker._getInst( input );
+		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
+			$.datepicker._curInst.dpDiv.stop( true, true );
+			if ( inst && $.datepicker._datepickerShowing ) {
+				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
+			}
+		}
+
+		beforeShow = $.datepicker._get( inst, "beforeShow" );
+		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
+		if ( beforeShowSettings === false ) {
+			return;
+		}
+		datepicker_extendRemove( inst.settings, beforeShowSettings );
+
+		inst.lastVal = null;
+		$.datepicker._lastInput = input;
+		$.datepicker._setDateFromField( inst );
+
+		if ( $.datepicker._inDialog ) { // hide cursor
+			input.value = "";
+		}
+		if ( !$.datepicker._pos ) { // position below input
+			$.datepicker._pos = $.datepicker._findPos( input );
+			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
+		}
+
+		isFixed = false;
+		$( input ).parents().each( function() {
+			isFixed |= $( this ).css( "position" ) === "fixed";
+			return !isFixed;
+		} );
+
+		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
+		$.datepicker._pos = null;
+
+		//to avoid flashes on Firefox
+		inst.dpDiv.empty();
+
+		// determine sizing offscreen
+		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
+		$.datepicker._updateDatepicker( inst );
+
+		// fix width for dynamic number of date pickers
+		// and adjust position before showing
+		offset = $.datepicker._checkOffset( inst, offset, isFixed );
+		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
+			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
+			left: offset.left + "px", top: offset.top + "px" } );
+
+		if ( !inst.inline ) {
+			showAnim = $.datepicker._get( inst, "showAnim" );
+			duration = $.datepicker._get( inst, "duration" );
+			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
+			$.datepicker._datepickerShowing = true;
+
+			if ( $.effects && $.effects.effect[ showAnim ] ) {
+				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
+			} else {
+				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
+			}
+
+			if ( $.datepicker._shouldFocusInput( inst ) ) {
+				inst.input.trigger( "focus" );
+			}
+
+			$.datepicker._curInst = inst;
+		}
+	},
+
+	/* Generate the date picker content. */
+	_updateDatepicker: function( inst ) {
+		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
+		datepicker_instActive = inst; // for delegate hover events
+		inst.dpDiv.empty().append( this._generateHTML( inst ) );
+		this._attachHandlers( inst );
+
+		var origyearshtml,
+			numMonths = this._getNumberOfMonths( inst ),
+			cols = numMonths[ 1 ],
+			width = 17,
+			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
+
+		if ( activeCell.length > 0 ) {
+			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
+		}
+
+		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
+		if ( cols > 1 ) {
+			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
+		}
+		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
+			"Class" ]( "ui-datepicker-multi" );
+		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
+			"Class" ]( "ui-datepicker-rtl" );
+
+		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
+			inst.input.trigger( "focus" );
+		}
+
+		// Deffered render of the years select (to avoid flashes on Firefox)
+		if ( inst.yearshtml ) {
+			origyearshtml = inst.yearshtml;
+			setTimeout( function() {
+
+				//assure that inst.yearshtml didn't change.
+				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
+					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
+				}
+				origyearshtml = inst.yearshtml = null;
+			}, 0 );
+		}
+	},
+
+	// #6694 - don't focus the input if it's already focused
+	// this breaks the change event in IE
+	// Support: IE and jQuery <1.9
+	_shouldFocusInput: function( inst ) {
+		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+	},
+
+	/* Check positioning to remain on screen. */
+	_checkOffset: function( inst, offset, isFixed ) {
+		var dpWidth = inst.dpDiv.outerWidth(),
+			dpHeight = inst.dpDiv.outerHeight(),
+			inputWidth = inst.input ? inst.input.outerWidth() : 0,
+			inputHeight = inst.input ? inst.input.outerHeight() : 0,
+			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
+			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
+
+		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
+		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
+		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
+
+		// Now check if datepicker is showing outside window viewport - move to a better place if so.
+		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
+			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
+		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
+			Math.abs( dpHeight + inputHeight ) : 0 );
+
+		return offset;
+	},
+
+	/* Find an object's position on the screen. */
+	_findPos: function( obj ) {
+		var position,
+			inst = this._getInst( obj ),
+			isRTL = this._get( inst, "isRTL" );
+
+		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
+			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
+		}
+
+		position = $( obj ).offset();
+		return [ position.left, position.top ];
+	},
+
+	/* Hide the date picker from view.
+	 * @param  input  element - the input field attached to the date picker
+	 */
+	_hideDatepicker: function( input ) {
+		var showAnim, duration, postProcess, onClose,
+			inst = this._curInst;
+
+		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
+			return;
+		}
+
+		if ( this._datepickerShowing ) {
+			showAnim = this._get( inst, "showAnim" );
+			duration = this._get( inst, "duration" );
+			postProcess = function() {
+				$.datepicker._tidyDialog( inst );
+			};
+
+			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
+			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
+				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
+			} else {
+				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
+					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
+			}
+
+			if ( !showAnim ) {
+				postProcess();
+			}
+			this._datepickerShowing = false;
+
+			onClose = this._get( inst, "onClose" );
+			if ( onClose ) {
+				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
+			}
+
+			this._lastInput = null;
+			if ( this._inDialog ) {
+				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
+				if ( $.blockUI ) {
+					$.unblockUI();
+					$( "body" ).append( this.dpDiv );
+				}
+			}
+			this._inDialog = false;
+		}
+	},
+
+	/* Tidy up after a dialog display. */
+	_tidyDialog: function( inst ) {
+		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
+	},
+
+	/* Close date picker if clicked elsewhere. */
+	_checkExternalClick: function( event ) {
+		if ( !$.datepicker._curInst ) {
+			return;
+		}
+
+		var $target = $( event.target ),
+			inst = $.datepicker._getInst( $target[ 0 ] );
+
+		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
+				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
+				!$target.hasClass( $.datepicker.markerClassName ) &&
+				!$target.closest( "." + $.datepicker._triggerClass ).length &&
+				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
+			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
+				$.datepicker._hideDatepicker();
+		}
+	},
+
+	/* Adjust one of the date sub-fields. */
+	_adjustDate: function( id, offset, period ) {
+		var target = $( id ),
+			inst = this._getInst( target[ 0 ] );
+
+		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
+			return;
+		}
+		this._adjustInstDate( inst, offset +
+			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
+			period );
+		this._updateDatepicker( inst );
+	},
+
+	/* Action for current link. */
+	_gotoToday: function( id ) {
+		var date,
+			target = $( id ),
+			inst = this._getInst( target[ 0 ] );
+
+		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
+			inst.selectedDay = inst.currentDay;
+			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+			inst.drawYear = inst.selectedYear = inst.currentYear;
+		} else {
+			date = new Date();
+			inst.selectedDay = date.getDate();
+			inst.drawMonth = inst.selectedMonth = date.getMonth();
+			inst.drawYear = inst.selectedYear = date.getFullYear();
+		}
+		this._notifyChange( inst );
+		this._adjustDate( target );
+	},
+
+	/* Action for selecting a new month/year. */
+	_selectMonthYear: function( id, select, period ) {
+		var target = $( id ),
+			inst = this._getInst( target[ 0 ] );
+
+		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
+		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
+			parseInt( select.options[ select.selectedIndex ].value, 10 );
+
+		this._notifyChange( inst );
+		this._adjustDate( target );
+	},
+
+	/* Action for selecting a day. */
+	_selectDay: function( id, month, year, td ) {
+		var inst,
+			target = $( id );
+
+		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
+			return;
+		}
+
+		inst = this._getInst( target[ 0 ] );
+		inst.selectedDay = inst.currentDay = $( "a", td ).html();
+		inst.selectedMonth = inst.currentMonth = month;
+		inst.selectedYear = inst.currentYear = year;
+		this._selectDate( id, this._formatDate( inst,
+			inst.currentDay, inst.currentMonth, inst.currentYear ) );
+	},
+
+	/* Erase the input field and hide the date picker. */
+	_clearDate: function( id ) {
+		var target = $( id );
+		this._selectDate( target, "" );
+	},
+
+	/* Update the input field with the selected date. */
+	_selectDate: function( id, dateStr ) {
+		var onSelect,
+			target = $( id ),
+			inst = this._getInst( target[ 0 ] );
+
+		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
+		if ( inst.input ) {
+			inst.input.val( dateStr );
+		}
+		this._updateAlternate( inst );
+
+		onSelect = this._get( inst, "onSelect" );
+		if ( onSelect ) {
+			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
+		} else if ( inst.input ) {
+			inst.input.trigger( "change" ); // fire the change event
+		}
+
+		if ( inst.inline ) {
+			this._updateDatepicker( inst );
+		} else {
+			this._hideDatepicker();
+			this._lastInput = inst.input[ 0 ];
+			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
+				inst.input.trigger( "focus" ); // restore focus
+			}
+			this._lastInput = null;
+		}
+	},
+
+	/* Update any alternate field to synchronise with the main field. */
+	_updateAlternate: function( inst ) {
+		var altFormat, date, dateStr,
+			altField = this._get( inst, "altField" );
+
+		if ( altField ) { // update alternate field too
+			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
+			date = this._getDate( inst );
+			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
+			$( altField ).val( dateStr );
+		}
+	},
+
+	/* Set as beforeShowDay function to prevent selection of weekends.
+	 * @param  date  Date - the date to customise
+	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
+	 */
+	noWeekends: function( date ) {
+		var day = date.getDay();
+		return [ ( day > 0 && day < 6 ), "" ];
+	},
+
+	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+	 * @param  date  Date - the date to get the week for
+	 * @return  number - the number of the week within the year that contains this date
+	 */
+	iso8601Week: function( date ) {
+		var time,
+			checkDate = new Date( date.getTime() );
+
+		// Find Thursday of this week starting on Monday
+		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
+
+		time = checkDate.getTime();
+		checkDate.setMonth( 0 ); // Compare with Jan 1
+		checkDate.setDate( 1 );
+		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
+	},
+
+	/* Parse a string value into a date object.
+	 * See formatDate below for the possible formats.
+	 *
+	 * @param  format string - the expected format of the date
+	 * @param  value string - the date in the above format
+	 * @param  settings Object - attributes include:
+	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
+	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
+	 *					dayNames		string[7] - names of the days from Sunday (optional)
+	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
+	 *					monthNames		string[12] - names of the months (optional)
+	 * @return  Date - the extracted date value or null if value is blank
+	 */
+	parseDate: function( format, value, settings ) {
+		if ( format == null || value == null ) {
+			throw "Invalid arguments";
+		}
+
+		value = ( typeof value === "object" ? value.toString() : value + "" );
+		if ( value === "" ) {
+			return null;
+		}
+
+		var iFormat, dim, extra,
+			iValue = 0,
+			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
+			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
+				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
+			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
+			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
+			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
+			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
+			year = -1,
+			month = -1,
+			day = -1,
+			doy = -1,
+			literal = false,
+			date,
+
+			// Check whether a format character is doubled
+			lookAhead = function( match ) {
+				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
+				if ( matches ) {
+					iFormat++;
+				}
+				return matches;
+			},
+
+			// Extract a number from the string value
+			getNumber = function( match ) {
+				var isDoubled = lookAhead( match ),
+					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
+					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
+					minSize = ( match === "y" ? size : 1 ),
+					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
+					num = value.substring( iValue ).match( digits );
+				if ( !num ) {
+					throw "Missing number at position " + iValue;
+				}
+				iValue += num[ 0 ].length;
+				return parseInt( num[ 0 ], 10 );
+			},
+
+			// Extract a name from the string value and convert to an index
+			getName = function( match, shortNames, longNames ) {
+				var index = -1,
+					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
+						return [ [ k, v ] ];
+					} ).sort( function( a, b ) {
+						return -( a[ 1 ].length - b[ 1 ].length );
+					} );
+
+				$.each( names, function( i, pair ) {
+					var name = pair[ 1 ];
+					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
+						index = pair[ 0 ];
+						iValue += name.length;
+						return false;
+					}
+				} );
+				if ( index !== -1 ) {
+					return index + 1;
+				} else {
+					throw "Unknown name at position " + iValue;
+				}
+			},
+
+			// Confirm that a literal character matches the string value
+			checkLiteral = function() {
+				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
+					throw "Unexpected literal at position " + iValue;
+				}
+				iValue++;
+			};
+
+		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
+			if ( literal ) {
+				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
+					literal = false;
+				} else {
+					checkLiteral();
+				}
+			} else {
+				switch ( format.charAt( iFormat ) ) {
+					case "d":
+						day = getNumber( "d" );
+						break;
+					case "D":
+						getName( "D", dayNamesShort, dayNames );
+						break;
+					case "o":
+						doy = getNumber( "o" );
+						break;
+					case "m":
+						month = getNumber( "m" );
+						break;
+					case "M":
+						month = getName( "M", monthNamesShort, monthNames );
+						break;
+					case "y":
+						year = getNumber( "y" );
+						break;
+					case "@":
+						date = new Date( getNumber( "@" ) );
+						year = date.getFullYear();
+						month = date.getMonth() + 1;
+						day = date.getDate();
+						break;
+					case "!":
+						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
+						year = date.getFullYear();
+						month = date.getMonth() + 1;
+						day = date.getDate();
+						break;
+					case "'":
+						if ( lookAhead( "'" ) ) {
+							checkLiteral();
+						} else {
+							literal = true;
+						}
+						break;
+					default:
+						checkLiteral();
+				}
+			}
+		}
+
+		if ( iValue < value.length ) {
+			extra = value.substr( iValue );
+			if ( !/^\s+/.test( extra ) ) {
+				throw "Extra/unparsed characters found in date: " + extra;
+			}
+		}
+
+		if ( year === -1 ) {
+			year = new Date().getFullYear();
+		} else if ( year < 100 ) {
+			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+				( year <= shortYearCutoff ? 0 : -100 );
+		}
+
+		if ( doy > -1 ) {
+			month = 1;
+			day = doy;
+			do {
+				dim = this._getDaysInMonth( year, month - 1 );
+				if ( day <= dim ) {
+					break;
+				}
+				month++;
+				day -= dim;
+			} while ( true );
+		}
+
+		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
+		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
+			throw "Invalid date"; // E.g. 31/02/00
+		}
+		return date;
+	},
+
+	/* Standard date formats. */
+	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
+	COOKIE: "D, dd M yy",
+	ISO_8601: "yy-mm-dd",
+	RFC_822: "D, d M y",
+	RFC_850: "DD, dd-M-y",
+	RFC_1036: "D, d M y",
+	RFC_1123: "D, d M yy",
+	RFC_2822: "D, d M yy",
+	RSS: "D, d M y", // RFC 822
+	TICKS: "!",
+	TIMESTAMP: "@",
+	W3C: "yy-mm-dd", // ISO 8601
+
+	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
+		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
+
+	/* Format a date object into a string value.
+	 * The format can be combinations of the following:
+	 * d  - day of month (no leading zero)
+	 * dd - day of month (two digit)
+	 * o  - day of year (no leading zeros)
+	 * oo - day of year (three digit)
+	 * D  - day name short
+	 * DD - day name long
+	 * m  - month of year (no leading zero)
+	 * mm - month of year (two digit)
+	 * M  - month name short
+	 * MM - month name long
+	 * y  - year (two digit)
+	 * yy - year (four digit)
+	 * @ - Unix timestamp (ms since 01/01/1970)
+	 * ! - Windows ticks (100ns since 01/01/0001)
+	 * "..." - literal text
+	 * '' - single quote
+	 *
+	 * @param  format string - the desired format of the date
+	 * @param  date Date - the date value to format
+	 * @param  settings Object - attributes include:
+	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
+	 *					dayNames		string[7] - names of the days from Sunday (optional)
+	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
+	 *					monthNames		string[12] - names of the months (optional)
+	 * @return  string - the date in the above format
+	 */
+	formatDate: function( format, date, settings ) {
+		if ( !date ) {
+			return "";
+		}
+
+		var iFormat,
+			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
+			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
+			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
+			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
+
+			// Check whether a format character is doubled
+			lookAhead = function( match ) {
+				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
+				if ( matches ) {
+					iFormat++;
+				}
+				return matches;
+			},
+
+			// Format a number, with leading zero if necessary
+			formatNumber = function( match, value, len ) {
+				var num = "" + value;
+				if ( lookAhead( match ) ) {
+					while ( num.length < len ) {
+						num = "0" + num;
+					}
+				}
+				return num;
+			},
+
+			// Format a name, short or long as requested
+			formatName = function( match, value, shortNames, longNames ) {
+				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
+			},
+			output = "",
+			literal = false;
+
+		if ( date ) {
+			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
+				if ( literal ) {
+					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
+						literal = false;
+					} else {
+						output += format.charAt( iFormat );
+					}
+				} else {
+					switch ( format.charAt( iFormat ) ) {
+						case "d":
+							output += formatNumber( "d", date.getDate(), 2 );
+							break;
+						case "D":
+							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
+							break;
+						case "o":
+							output += formatNumber( "o",
+								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
+							break;
+						case "m":
+							output += formatNumber( "m", date.getMonth() + 1, 2 );
+							break;
+						case "M":
+							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
+							break;
+						case "y":
+							output += ( lookAhead( "y" ) ? date.getFullYear() :
+								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
+							break;
+						case "@":
+							output += date.getTime();
+							break;
+						case "!":
+							output += date.getTime() * 10000 + this._ticksTo1970;
+							break;
+						case "'":
+							if ( lookAhead( "'" ) ) {
+								output += "'";
+							} else {
+								literal = true;
+							}
+							break;
+						default:
+							output += format.charAt( iFormat );
+					}
+				}
+			}
+		}
+		return output;
+	},
+
+	/* Extract all possible characters from the date format. */
+	_possibleChars: function( format ) {
+		var iFormat,
+			chars = "",
+			literal = false,
+
+			// Check whether a format character is doubled
+			lookAhead = function( match ) {
+				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
+				if ( matches ) {
+					iFormat++;
+				}
+				return matches;
+			};
+
+		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
+			if ( literal ) {
+				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
+					literal = false;
+				} else {
+					chars += format.charAt( iFormat );
+				}
+			} else {
+				switch ( format.charAt( iFormat ) ) {
+					case "d": case "m": case "y": case "@":
+						chars += "0123456789";
+						break;
+					case "D": case "M":
+						return null; // Accept anything
+					case "'":
+						if ( lookAhead( "'" ) ) {
+							chars += "'";
+						} else {
+							literal = true;
+						}
+						break;
+					default:
+						chars += format.charAt( iFormat );
+				}
+			}
+		}
+		return chars;
+	},
+
+	/* Get a setting value, defaulting if necessary. */
+	_get: function( inst, name ) {
+		return inst.settings[ name ] !== undefined ?
+			inst.settings[ name ] : this._defaults[ name ];
+	},
+
+	/* Parse existing date and initialise date picker. */
+	_setDateFromField: function( inst, noDefault ) {
+		if ( inst.input.val() === inst.lastVal ) {
+			return;
+		}
+
+		var dateFormat = this._get( inst, "dateFormat" ),
+			dates = inst.lastVal = inst.input ? inst.input.val() : null,
+			defaultDate = this._getDefaultDate( inst ),
+			date = defaultDate,
+			settings = this._getFormatConfig( inst );
+
+		try {
+			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
+		} catch ( event ) {
+			dates = ( noDefault ? "" : dates );
+		}
+		inst.selectedDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = date.getFullYear();
+		inst.currentDay = ( dates ? date.getDate() : 0 );
+		inst.currentMonth = ( dates ? date.getMonth() : 0 );
+		inst.currentYear = ( dates ? date.getFullYear() : 0 );
+		this._adjustInstDate( inst );
+	},
+
+	/* Retrieve the default date shown on opening. */
+	_getDefaultDate: function( inst ) {
+		return this._restrictMinMax( inst,
+			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
+	},
+
+	/* A date may be specified as an exact value or a relative one. */
+	_determineDate: function( inst, date, defaultDate ) {
+		var offsetNumeric = function( offset ) {
+				var date = new Date();
+				date.setDate( date.getDate() + offset );
+				return date;
+			},
+			offsetString = function( offset ) {
+				try {
+					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
+						offset, $.datepicker._getFormatConfig( inst ) );
+				}
+				catch ( e ) {
+
+					// Ignore
+				}
+
+				var date = ( offset.toLowerCase().match( /^c/ ) ?
+					$.datepicker._getDate( inst ) : null ) || new Date(),
+					year = date.getFullYear(),
+					month = date.getMonth(),
+					day = date.getDate(),
+					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
+					matches = pattern.exec( offset );
+
+				while ( matches ) {
+					switch ( matches[ 2 ] || "d" ) {
+						case "d" : case "D" :
+							day += parseInt( matches[ 1 ], 10 ); break;
+						case "w" : case "W" :
+							day += parseInt( matches[ 1 ], 10 ) * 7; break;
+						case "m" : case "M" :
+							month += parseInt( matches[ 1 ], 10 );
+							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
+							break;
+						case "y": case "Y" :
+							year += parseInt( matches[ 1 ], 10 );
+							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
+							break;
+					}
+					matches = pattern.exec( offset );
+				}
+				return new Date( year, month, day );
+			},
+			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
+				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
+
+		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
+		if ( newDate ) {
+			newDate.setHours( 0 );
+			newDate.setMinutes( 0 );
+			newDate.setSeconds( 0 );
+			newDate.setMilliseconds( 0 );
+		}
+		return this._daylightSavingAdjust( newDate );
+	},
+
+	/* Handle switch to/from daylight saving.
+	 * Hours may be non-zero on daylight saving cut-over:
+	 * > 12 when midnight changeover, but then cannot generate
+	 * midnight datetime, so jump to 1AM, otherwise reset.
+	 * @param  date  (Date) the date to check
+	 * @return  (Date) the corrected date
+	 */
+	_daylightSavingAdjust: function( date ) {
+		if ( !date ) {
+			return null;
+		}
+		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
+		return date;
+	},
+
+	/* Set the date(s) directly. */
+	_setDate: function( inst, date, noChange ) {
+		var clear = !date,
+			origMonth = inst.selectedMonth,
+			origYear = inst.selectedYear,
+			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
+
+		inst.selectedDay = inst.currentDay = newDate.getDate();
+		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
+			this._notifyChange( inst );
+		}
+		this._adjustInstDate( inst );
+		if ( inst.input ) {
+			inst.input.val( clear ? "" : this._formatDate( inst ) );
+		}
+	},
+
+	/* Retrieve the date(s) directly. */
+	_getDate: function( inst ) {
+		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
+			this._daylightSavingAdjust( new Date(
+			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
+			return startDate;
+	},
+
+	/* Attach the onxxx handlers.  These are declared statically so
+	 * they work with static code transformers like Caja.
+	 */
+	_attachHandlers: function( inst ) {
+		var stepMonths = this._get( inst, "stepMonths" ),
+			id = "#" + inst.id.replace( /\\\\/g, "\\" );
+		inst.dpDiv.find( "[data-handler]" ).map( function() {
+			var handler = {
+				prev: function() {
+					$.datepicker._adjustDate( id, -stepMonths, "M" );
+				},
+				next: function() {
+					$.datepicker._adjustDate( id, +stepMonths, "M" );
+				},
+				hide: function() {
+					$.datepicker._hideDatepicker();
+				},
+				today: function() {
+					$.datepicker._gotoToday( id );
+				},
+				selectDay: function() {
+					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
+					return false;
+				},
+				selectMonth: function() {
+					$.datepicker._selectMonthYear( id, this, "M" );
+					return false;
+				},
+				selectYear: function() {
+					$.datepicker._selectMonthYear( id, this, "Y" );
+					return false;
+				}
+			};
+			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
+		} );
+	},
+
+	/* Generate the HTML for the current state of the date picker. */
+	_generateHTML: function( inst ) {
+		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
+			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
+			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
+			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
+			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
+			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
+			tempDate = new Date(),
+			today = this._daylightSavingAdjust(
+				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
+			isRTL = this._get( inst, "isRTL" ),
+			showButtonPanel = this._get( inst, "showButtonPanel" ),
+			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
+			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
+			numMonths = this._getNumberOfMonths( inst ),
+			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
+			stepMonths = this._get( inst, "stepMonths" ),
+			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
+			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
+				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
+			minDate = this._getMinMaxDate( inst, "min" ),
+			maxDate = this._getMinMaxDate( inst, "max" ),
+			drawMonth = inst.drawMonth - showCurrentAtPos,
+			drawYear = inst.drawYear;
+
+		if ( drawMonth < 0 ) {
+			drawMonth += 12;
+			drawYear--;
+		}
+		if ( maxDate ) {
+			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
+				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
+			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
+			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
+				drawMonth--;
+				if ( drawMonth < 0 ) {
+					drawMonth = 11;
+					drawYear--;
+				}
+			}
+		}
+		inst.drawMonth = drawMonth;
+		inst.drawYear = drawYear;
+
+		prevText = this._get( inst, "prevText" );
+		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
+			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
+			this._getFormatConfig( inst ) ) );
+
+		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
+			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
+			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
+			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) );
+
+		nextText = this._get( inst, "nextText" );
+		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
+			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
+			this._getFormatConfig( inst ) ) );
+
+		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
+			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
+			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
+			( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) );
+
+		currentText = this._get( inst, "currentText" );
+		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
+		currentText = ( !navigationAsDateFormat ? currentText :
+			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
+
+		controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
+			this._get( inst, "closeText" ) + "</button>" : "" );
+
+		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
+			( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
+			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
+
+		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
+		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
+
+		showWeek = this._get( inst, "showWeek" );
+		dayNames = this._get( inst, "dayNames" );
+		dayNamesMin = this._get( inst, "dayNamesMin" );
+		monthNames = this._get( inst, "monthNames" );
+		monthNamesShort = this._get( inst, "monthNamesShort" );
+		beforeShowDay = this._get( inst, "beforeShowDay" );
+		showOtherMonths = this._get( inst, "showOtherMonths" );
+		selectOtherMonths = this._get( inst, "selectOtherMonths" );
+		defaultDate = this._getDefaultDate( inst );
+		html = "";
+
+		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
+			group = "";
+			this.maxRows = 4;
+			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
+				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
+				cornerClass = " ui-corner-all";
+				calender = "";
+				if ( isMultiMonth ) {
+					calender += "<div class='ui-datepicker-group";
+					if ( numMonths[ 1 ] > 1 ) {
+						switch ( col ) {
+							case 0: calender += " ui-datepicker-group-first";
+								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
+							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
+								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
+							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
+						}
+					}
+					calender += "'>";
+				}
+				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
+					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
+					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
+					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
+					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
+					"</div><table class='ui-datepicker-calendar'><thead>" +
+					"<tr>";
+				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
+				for ( dow = 0; dow < 7; dow++ ) { // days of the week
+					day = ( dow + firstDay ) % 7;
+					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
+						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
+				}
+				calender += thead + "</tr></thead><tbody>";
+				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
+				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
+					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
+				}
+				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
+				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
+				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
+				this.maxRows = numRows;
+				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
+				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
+					calender += "<tr>";
+					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
+						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
+					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
+						daySettings = ( beforeShowDay ?
+							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
+						otherMonth = ( printDate.getMonth() !== drawMonth );
+						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
+							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
+						tbody += "<td class='" +
+							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
+							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
+							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
+							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
+
+							// or defaultDate is current printedDate and defaultDate is selectedDate
+							" " + this._dayOverClass : "" ) + // highlight selected day
+							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
+							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
+							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
+							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
+							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
+							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
+							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
+							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
+							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
+							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
+							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
+							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
+						printDate.setDate( printDate.getDate() + 1 );
+						printDate = this._daylightSavingAdjust( printDate );
+					}
+					calender += tbody + "</tr>";
+				}
+				drawMonth++;
+				if ( drawMonth > 11 ) {
+					drawMonth = 0;
+					drawYear++;
+				}
+				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
+							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
+				group += calender;
+			}
+			html += group;
+		}
+		html += buttonPanel;
+		inst._keyEvent = false;
+		return html;
+	},
+
+	/* Generate the month and year header. */
+	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
+			secondary, monthNames, monthNamesShort ) {
+
+		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
+			changeMonth = this._get( inst, "changeMonth" ),
+			changeYear = this._get( inst, "changeYear" ),
+			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
+			html = "<div class='ui-datepicker-title'>",
+			monthHtml = "";
+
+		// Month selection
+		if ( secondary || !changeMonth ) {
+			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
+		} else {
+			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
+			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
+			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
+			for ( month = 0; month < 12; month++ ) {
+				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
+					monthHtml += "<option value='" + month + "'" +
+						( month === drawMonth ? " selected='selected'" : "" ) +
+						">" + monthNamesShort[ month ] + "</option>";
+				}
+			}
+			monthHtml += "</select>";
+		}
+
+		if ( !showMonthAfterYear ) {
+			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
+		}
+
+		// Year selection
+		if ( !inst.yearshtml ) {
+			inst.yearshtml = "";
+			if ( secondary || !changeYear ) {
+				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
+			} else {
+
+				// determine range of years to display
+				years = this._get( inst, "yearRange" ).split( ":" );
+				thisYear = new Date().getFullYear();
+				determineYear = function( value ) {
+					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
+						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
+						parseInt( value, 10 ) ) );
+					return ( isNaN( year ) ? thisYear : year );
+				};
+				year = determineYear( years[ 0 ] );
+				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
+				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
+				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
+				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
+				for ( ; year <= endYear; year++ ) {
+					inst.yearshtml += "<option value='" + year + "'" +
+						( year === drawYear ? " selected='selected'" : "" ) +
+						">" + year + "</option>";
+				}
+				inst.yearshtml += "</select>";
+
+				html += inst.yearshtml;
+				inst.yearshtml = null;
+			}
+		}
+
+		html += this._get( inst, "yearSuffix" );
+		if ( showMonthAfterYear ) {
+			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
+		}
+		html += "</div>"; // Close datepicker_header
+		return html;
+	},
+
+	/* Adjust one of the date sub-fields. */
+	_adjustInstDate: function( inst, offset, period ) {
+		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
+			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
+			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
+			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
+
+		inst.selectedDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = date.getFullYear();
+		if ( period === "M" || period === "Y" ) {
+			this._notifyChange( inst );
+		}
+	},
+
+	/* Ensure a date is within any min/max bounds. */
+	_restrictMinMax: function( inst, date ) {
+		var minDate = this._getMinMaxDate( inst, "min" ),
+			maxDate = this._getMinMaxDate( inst, "max" ),
+			newDate = ( minDate && date < minDate ? minDate : date );
+		return ( maxDate && newDate > maxDate ? maxDate : newDate );
+	},
+
+	/* Notify change of month/year. */
+	_notifyChange: function( inst ) {
+		var onChange = this._get( inst, "onChangeMonthYear" );
+		if ( onChange ) {
+			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
+				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
+		}
+	},
+
+	/* Determine the number of months to show. */
+	_getNumberOfMonths: function( inst ) {
+		var numMonths = this._get( inst, "numberOfMonths" );
+		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
+	},
+
+	/* Determine the current maximum date - ensure no time components are set. */
+	_getMinMaxDate: function( inst, minMax ) {
+		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
+	},
+
+	/* Find the number of days in a given month. */
+	_getDaysInMonth: function( year, month ) {
+		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
+	},
+
+	/* Find the day of the week of the first of a month. */
+	_getFirstDayOfMonth: function( year, month ) {
+		return new Date( year, month, 1 ).getDay();
+	},
+
+	/* Determines if we should allow a "next/prev" month display change. */
+	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
+		var numMonths = this._getNumberOfMonths( inst ),
+			date = this._daylightSavingAdjust( new Date( curYear,
+			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
+
+		if ( offset < 0 ) {
+			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
+		}
+		return this._isInRange( inst, date );
+	},
+
+	/* Is the given date in the accepted range? */
+	_isInRange: function( inst, date ) {
+		var yearSplit, currentYear,
+			minDate = this._getMinMaxDate( inst, "min" ),
+			maxDate = this._getMinMaxDate( inst, "max" ),
+			minYear = null,
+			maxYear = null,
+			years = this._get( inst, "yearRange" );
+			if ( years ) {
+				yearSplit = years.split( ":" );
+				currentYear = new Date().getFullYear();
+				minYear = parseInt( yearSplit[ 0 ], 10 );
+				maxYear = parseInt( yearSplit[ 1 ], 10 );
+				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
+					minYear += currentYear;
+				}
+				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
+					maxYear += currentYear;
+				}
+			}
+
+		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
+			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
+			( !minYear || date.getFullYear() >= minYear ) &&
+			( !maxYear || date.getFullYear() <= maxYear ) );
+	},
+
+	/* Provide the configuration settings for formatting/parsing. */
+	_getFormatConfig: function( inst ) {
+		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
+		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
+			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
+		return { shortYearCutoff: shortYearCutoff,
+			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
+			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
+	},
+
+	/* Format the given date for display. */
+	_formatDate: function( inst, day, month, year ) {
+		if ( !day ) {
+			inst.currentDay = inst.selectedDay;
+			inst.currentMonth = inst.selectedMonth;
+			inst.currentYear = inst.selectedYear;
+		}
+		var date = ( day ? ( typeof day === "object" ? day :
+			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
+			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
+		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
+	}
+} );
+
+/*
+ * Bind hover events for datepicker elements.
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
+ * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
+ */
+function datepicker_bindHover( dpDiv ) {
+	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
+	return dpDiv.on( "mouseout", selector, function() {
+			$( this ).removeClass( "ui-state-hover" );
+			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
+				$( this ).removeClass( "ui-datepicker-prev-hover" );
+			}
+			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
+				$( this ).removeClass( "ui-datepicker-next-hover" );
+			}
+		} )
+		.on( "mouseover", selector, datepicker_handleMouseover );
+}
+
+function datepicker_handleMouseover() {
+	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
+		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
+		$( this ).addClass( "ui-state-hover" );
+		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
+			$( this ).addClass( "ui-datepicker-prev-hover" );
+		}
+		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
+			$( this ).addClass( "ui-datepicker-next-hover" );
+		}
+	}
+}
+
+/* jQuery extend now ignores nulls! */
+function datepicker_extendRemove( target, props ) {
+	$.extend( target, props );
+	for ( var name in props ) {
+		if ( props[ name ] == null ) {
+			target[ name ] = props[ name ];
+		}
+	}
+	return target;
+}
+
+/* Invoke the datepicker functionality.
+   @param  options  string - a command, optionally followed by additional parameters or
+					Object - settings for attaching new datepicker functionality
+   @return  jQuery object */
+$.fn.datepicker = function( options ) {
+
+	/* Verify an empty collection wasn't passed - Fixes #6976 */
+	if ( !this.length ) {
+		return this;
+	}
+
+	/* Initialise the date picker. */
+	if ( !$.datepicker.initialized ) {
+		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
+		$.datepicker.initialized = true;
+	}
+
+	/* Append datepicker main container to body if not exist. */
+	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
+		$( "body" ).append( $.datepicker.dpDiv );
+	}
+
+	var otherArgs = Array.prototype.slice.call( arguments, 1 );
+	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
+		return $.datepicker[ "_" + options + "Datepicker" ].
+			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
+	}
+	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
+		return $.datepicker[ "_" + options + "Datepicker" ].
+			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
+	}
+	return this.each( function() {
+		typeof options === "string" ?
+			$.datepicker[ "_" + options + "Datepicker" ].
+				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
+			$.datepicker._attachDatepicker( this, options );
+	} );
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.12.1";
+
+var widgetsDatepicker = $.datepicker;
+
+
+
+
+// This file is deprecated
+var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+/*!
+ * jQuery UI Mouse 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker
- *
- * Depends:
- *	jquery.ui.core.js
  */
-(function(d,C){function M(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
-"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
-"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
-minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=N(d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function N(a){return a.bind("mouseout",function(b){b=
-d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");b.addClass("ui-state-hover");
-b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.14"}});var A=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){H(this._defaults,
-a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,
-selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=
-h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=
-this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,
-"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",
-function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.dpDiv.show()}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);
-a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",
-this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",
-this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=
-b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",
-cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},
-_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&this._hideDatepicker();var h=this._getDateDatepicker(a,true),i=this._getMinMaxDate(e,"min"),g=this._getMinMaxDate(e,
-"max");H(e.settings,f);if(i!==null&&f.dateFormat!==C&&f.minDate===C)e.settings.minDate=this._formatDate(e,i);if(g!==null&&f.dateFormat!==C&&f.maxDate===C)e.settings.maxDate=this._formatDate(e,g);this._attachments(d(a),e);this._autoSize(e);this._setDate(e,h);this._updateAlternate(e);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,
-b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass+":not(."+d.datepicker._currentClass+")",b.dpDiv);
-c[0]?d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);
-c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||
-a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=
-d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));var c=String.fromCharCode(a.charCode==C?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);
-d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=
-d.datepicker._get(b,"beforeShow");H(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c=
-{left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");
-if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing=true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);
-J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");
-a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||
-c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+
-i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=
-this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",
-left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&
-d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=
-b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=
-!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);
-a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));
-d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%
-100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=B+1<a.length&&a.charAt(B+1)==p)&&B++;return p},m=function(p){var D=o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"&&D?4:p=="o"?3:2)+"}");p=b.substring(q).match(p);if(!p)throw"Missing number at position "+q;q+=
-p[0].length;return parseInt(p[0],10)},n=function(p,D,K){p=d.map(o(p)?K:D,function(w,x){return[[x,w]]}).sort(function(w,x){return-(w[1].length-x[1].length)});var E=-1;d.each(p,function(w,x){w=x[1];if(b.substr(q,w.length).toLowerCase()==w.toLowerCase()){E=x[0];q+=w.length;return false}});if(E!=-1)return E+1;else throw"Unknown name at position "+q;},s=function(){if(b.charAt(q)!=a.charAt(B))throw"Unexpected literal at position "+q;q++},q=0,B=0;B<a.length;B++)if(k)if(a.charAt(B)=="'"&&!o("'"))k=false;
-else s();else switch(a.charAt(B)){case "d":l=m("d");break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":j=m("m");break;case "M":j=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();j=v.getMonth()+1;l=v.getDate();break;case "'":if(o("'"))s();else k=true;break;default:s()}if(q<b.length)throw"Extra/unparsed characters found in date: "+b.substring(q);
-if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",
-TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=k+1<a.length&&a.charAt(k+1)==o)&&k++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<
-n;)m="0"+m;return m},j=function(o,m,n,s){return i(o)?s[m]:n[m]},l="",u=false;if(b)for(var k=0;k<a.length;k++)if(u)if(a.charAt(k)=="'"&&!i("'"))u=false;else l+=a.charAt(k);else switch(a.charAt(k)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=j("D",b.getDay(),e,f);break;case "o":l+=g("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=j("M",b.getMonth(),h,
-c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+="'";else u=true;break;default:l+=a.charAt(k)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+=
-"0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==C?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=
-f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=
-(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,j=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,k=u.exec(h);k;){switch(k[2]||"d"){case "d":case "D":g+=parseInt(k[1],10);break;case "w":case "W":g+=parseInt(k[1],10)*7;break;case "m":case "M":l+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break;case "y":case "Y":j+=parseInt(k[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(j,l));break}k=u.exec(h)}return new Date(j,
-l,g)};if(b=(b=b==null||b===""?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):new Date(b.getTime()))&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=
-a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),
-b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=
-this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&n<k?k:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._adjustDate('#"+a.id+"', -"+j+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+
-(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m,g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._adjustDate('#"+a.id+"', +"+j+", 'M');\" title=\""+s+'"><span class="ui-icon ui-icon-circle-triangle-'+
-(c?"w":"e")+'">'+s+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&&a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+A+'.datepicker._hideDatepicker();">'+this._get(a,
-"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,s)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+A+".datepicker._gotoToday('#"+a.id+"');\">"+j+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),B=
-this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x<i[0];x++){var O="";this.maxRows=4;for(var G=0;G<i[1];G++){var P=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",y="";if(l){y+='<div class="ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":
-"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,B,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var z=j?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":
-"";for(t=0;t<7;t++){var r=(t+h)%7;z+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+s[r]+'">'+q[r]+"</span></th>"}y+=z+"</tr></thead><tbody>";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q<z;Q++){y+="<tr>";var R=!j?"":'<td class="ui-datepicker-week-col">'+
-this._get(a,"calculateWeek")(r)+"</td>";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&r<k||o&&r>o;R+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(r.getTime()==P.getTime()&&g==a.selectedMonth&&a._keyEvent||E.getTime()==r.getTime()&&E.getTime()==P.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!D?"":" "+I[1]+(r.getTime()==u.getTime()?" "+
-this._currentClass:"")+(r.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!F||D)&&I[2]?' title="'+I[2]+'"':"")+(L?"":' onclick="DP_jQuery_'+A+".datepicker._selectDay('#"+a.id+"',"+r.getMonth()+","+r.getFullYear()+', this);return false;"')+">"+(F&&!D?"&#xa0;":L?'<span class="ui-state-default">'+r.getDate()+"</span>":'<a class="ui-state-default'+(r.getTime()==b.getTime()?" ui-state-highlight":"")+(r.getTime()==u.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+'" href="#">'+
-r.getDate()+"</a>")+"</td>";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+"</tr>"}g++;if(g>11){g=0;m++}y+="</tbody></table>"+(l?"</div>"+(i[0]>0&&G==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),
-l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='<div class="ui-datepicker-title">',o="";if(h||!j)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+A+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+A+".datepicker._clickMonthYear('#"+a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+
-n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(k+=o+(h||!(j&&l)?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):
-g;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+A+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+A+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";a.yearshtml+="</select>";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?"&#xa0;":"")+o;k+="</div>";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c==
-"Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");
-if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);
-c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,
-"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
-function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,
-[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.14";window["DP_jQuery_"+A]=d})(jQuery);
-;/*
- * jQuery UI Progressbar 1.8.14
+
+//>>label: Mouse
+//>>group: Widgets
+//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
+//>>docs: http://api.jqueryui.com/mouse/
+
+
+
+var mouseHandled = false;
+$( document ).on( "mouseup", function() {
+	mouseHandled = false;
+} );
+
+var widgetsMouse = $.widget( "ui.mouse", {
+	version: "1.12.1",
+	options: {
+		cancel: "input, textarea, button, select, option",
+		distance: 1,
+		delay: 0
+	},
+	_mouseInit: function() {
+		var that = this;
+
+		this.element
+			.on( "mousedown." + this.widgetName, function( event ) {
+				return that._mouseDown( event );
+			} )
+			.on( "click." + this.widgetName, function( event ) {
+				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
+					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
+					event.stopImmediatePropagation();
+					return false;
+				}
+			} );
+
+		this.started = false;
+	},
+
+	// TODO: make sure destroying one instance of mouse doesn't mess with
+	// other instances of mouse
+	_mouseDestroy: function() {
+		this.element.off( "." + this.widgetName );
+		if ( this._mouseMoveDelegate ) {
+			this.document
+				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
+		}
+	},
+
+	_mouseDown: function( event ) {
+
+		// don't let more than one widget handle mouseStart
+		if ( mouseHandled ) {
+			return;
+		}
+
+		this._mouseMoved = false;
+
+		// We may have missed mouseup (out of window)
+		( this._mouseStarted && this._mouseUp( event ) );
+
+		this._mouseDownEvent = event;
+
+		var that = this,
+			btnIsLeft = ( event.which === 1 ),
+
+			// event.target.nodeName works around a bug in IE 8 with
+			// disabled inputs (#7620)
+			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
+				$( event.target ).closest( this.options.cancel ).length : false );
+		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
+			return true;
+		}
+
+		this.mouseDelayMet = !this.options.delay;
+		if ( !this.mouseDelayMet ) {
+			this._mouseDelayTimer = setTimeout( function() {
+				that.mouseDelayMet = true;
+			}, this.options.delay );
+		}
+
+		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
+			this._mouseStarted = ( this._mouseStart( event ) !== false );
+			if ( !this._mouseStarted ) {
+				event.preventDefault();
+				return true;
+			}
+		}
+
+		// Click event may never have fired (Gecko & Opera)
+		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
+			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
+		}
+
+		// These delegates are required to keep context
+		this._mouseMoveDelegate = function( event ) {
+			return that._mouseMove( event );
+		};
+		this._mouseUpDelegate = function( event ) {
+			return that._mouseUp( event );
+		};
+
+		this.document
+			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+		event.preventDefault();
+
+		mouseHandled = true;
+		return true;
+	},
+
+	_mouseMove: function( event ) {
+
+		// Only check for mouseups outside the document if you've moved inside the document
+		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
+		// fire a mousemove event if content is placed under the cursor. See #7778
+		// Support: IE <9
+		if ( this._mouseMoved ) {
+
+			// IE mouseup check - mouseup happened when mouse was out of window
+			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
+					!event.button ) {
+				return this._mouseUp( event );
+
+			// Iframe mouseup check - mouseup occurred in another document
+			} else if ( !event.which ) {
+
+				// Support: Safari <=8 - 9
+				// Safari sets which to 0 if you press any of the following keys
+				// during a drag (#14461)
+				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
+						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
+					this.ignoreMissingWhich = true;
+				} else if ( !this.ignoreMissingWhich ) {
+					return this._mouseUp( event );
+				}
+			}
+		}
+
+		if ( event.which || event.button ) {
+			this._mouseMoved = true;
+		}
+
+		if ( this._mouseStarted ) {
+			this._mouseDrag( event );
+			return event.preventDefault();
+		}
+
+		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
+			this._mouseStarted =
+				( this._mouseStart( this._mouseDownEvent, event ) !== false );
+			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
+		}
+
+		return !this._mouseStarted;
+	},
+
+	_mouseUp: function( event ) {
+		this.document
+			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+		if ( this._mouseStarted ) {
+			this._mouseStarted = false;
+
+			if ( event.target === this._mouseDownEvent.target ) {
+				$.data( event.target, this.widgetName + ".preventClickEvent", true );
+			}
+
+			this._mouseStop( event );
+		}
+
+		if ( this._mouseDelayTimer ) {
+			clearTimeout( this._mouseDelayTimer );
+			delete this._mouseDelayTimer;
+		}
+
+		this.ignoreMissingWhich = false;
+		mouseHandled = false;
+		event.preventDefault();
+	},
+
+	_mouseDistanceMet: function( event ) {
+		return ( Math.max(
+				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
+				Math.abs( this._mouseDownEvent.pageY - event.pageY )
+			) >= this.options.distance
+		);
+	},
+
+	_mouseDelayMet: function( /* event */ ) {
+		return this.mouseDelayMet;
+	},
+
+	// These are placeholder methods, to be overriden by extending plugin
+	_mouseStart: function( /* event */ ) {},
+	_mouseDrag: function( /* event */ ) {},
+	_mouseStop: function( /* event */ ) {},
+	_mouseCapture: function( /* event */ ) { return true; }
+} );
+
+
+
+
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
+var plugin = $.ui.plugin = {
+	add: function( module, option, set ) {
+		var i,
+			proto = $.ui[ module ].prototype;
+		for ( i in set ) {
+			proto.plugins[ i ] = proto.plugins[ i ] || [];
+			proto.plugins[ i ].push( [ option, set[ i ] ] );
+		}
+	},
+	call: function( instance, name, args, allowDisconnected ) {
+		var i,
+			set = instance.plugins[ name ];
+
+		if ( !set ) {
+			return;
+		}
+
+		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
+				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
+			return;
+		}
+
+		for ( i = 0; i < set.length; i++ ) {
+			if ( instance.options[ set[ i ][ 0 ] ] ) {
+				set[ i ][ 1 ].apply( instance.element, args );
+			}
+		}
+	}
+};
+
+
+
+var safeBlur = $.ui.safeBlur = function( element ) {
+
+	// Support: IE9 - 10 only
+	// If the <body> is blurred, IE will switch windows, see #9420
+	if ( element && element.nodeName.toLowerCase() !== "body" ) {
+		$( element ).trigger( "blur" );
+	}
+};
+
+
+/*!
+ * jQuery UI Draggable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Progressbar
- *
- * Depends:
- *   jquery.ui.core.js
- *   jquery.ui.widget.js
  */
-(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
-this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
-this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.14"})})(jQuery);
-;/*
- * jQuery UI Effects 1.8.14
+
+//>>label: Draggable
+//>>group: Interactions
+//>>description: Enables dragging functionality for any element.
+//>>docs: http://api.jqueryui.com/draggable/
+//>>demos: http://jqueryui.com/draggable/
+//>>css.structure: ../../themes/base/draggable.css
+
+
+
+$.widget( "ui.draggable", $.ui.mouse, {
+	version: "1.12.1",
+	widgetEventPrefix: "drag",
+	options: {
+		addClasses: true,
+		appendTo: "parent",
+		axis: false,
+		connectToSortable: false,
+		containment: false,
+		cursor: "auto",
+		cursorAt: false,
+		grid: false,
+		handle: false,
+		helper: "original",
+		iframeFix: false,
+		opacity: false,
+		refreshPositions: false,
+		revert: false,
+		revertDuration: 500,
+		scope: "default",
+		scroll: true,
+		scrollSensitivity: 20,
+		scrollSpeed: 20,
+		snap: false,
+		snapMode: "both",
+		snapTolerance: 20,
+		stack: false,
+		zIndex: false,
+
+		// Callbacks
+		drag: null,
+		start: null,
+		stop: null
+	},
+	_create: function() {
+
+		if ( this.options.helper === "original" ) {
+			this._setPositionRelative();
+		}
+		if ( this.options.addClasses ) {
+			this._addClass( "ui-draggable" );
+		}
+		this._setHandleClassName();
+
+		this._mouseInit();
+	},
+
+	_setOption: function( key, value ) {
+		this._super( key, value );
+		if ( key === "handle" ) {
+			this._removeHandleClassName();
+			this._setHandleClassName();
+		}
+	},
+
+	_destroy: function() {
+		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
+			this.destroyOnClear = true;
+			return;
+		}
+		this._removeHandleClassName();
+		this._mouseDestroy();
+	},
+
+	_mouseCapture: function( event ) {
+		var o = this.options;
+
+		// Among others, prevent a drag on a resizable-handle
+		if ( this.helper || o.disabled ||
+				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
+			return false;
+		}
+
+		//Quit if we're not on a valid handle
+		this.handle = this._getHandle( event );
+		if ( !this.handle ) {
+			return false;
+		}
+
+		this._blurActiveElement( event );
+
+		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
+
+		return true;
+
+	},
+
+	_blockFrames: function( selector ) {
+		this.iframeBlocks = this.document.find( selector ).map( function() {
+			var iframe = $( this );
+
+			return $( "<div>" )
+				.css( "position", "absolute" )
+				.appendTo( iframe.parent() )
+				.outerWidth( iframe.outerWidth() )
+				.outerHeight( iframe.outerHeight() )
+				.offset( iframe.offset() )[ 0 ];
+		} );
+	},
+
+	_unblockFrames: function() {
+		if ( this.iframeBlocks ) {
+			this.iframeBlocks.remove();
+			delete this.iframeBlocks;
+		}
+	},
+
+	_blurActiveElement: function( event ) {
+		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
+			target = $( event.target );
+
+		// Don't blur if the event occurred on an element that is within
+		// the currently focused element
+		// See #10527, #12472
+		if ( target.closest( activeElement ).length ) {
+			return;
+		}
+
+		// Blur any element that currently has focus, see #4261
+		$.ui.safeBlur( activeElement );
+	},
+
+	_mouseStart: function( event ) {
+
+		var o = this.options;
+
+		//Create and append the visible helper
+		this.helper = this._createHelper( event );
+
+		this._addClass( this.helper, "ui-draggable-dragging" );
+
+		//Cache the helper size
+		this._cacheHelperProportions();
+
+		//If ddmanager is used for droppables, set the global draggable
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.current = this;
+		}
+
+		/*
+		 * - Position generation -
+		 * This block generates everything position related - it's the core of draggables.
+		 */
+
+		//Cache the margins of the original element
+		this._cacheMargins();
+
+		//Store the helper's css position
+		this.cssPosition = this.helper.css( "position" );
+		this.scrollParent = this.helper.scrollParent( true );
+		this.offsetParent = this.helper.offsetParent();
+		this.hasFixedAncestor = this.helper.parents().filter( function() {
+				return $( this ).css( "position" ) === "fixed";
+			} ).length > 0;
+
+		//The element's absolute position on the page minus margins
+		this.positionAbs = this.element.offset();
+		this._refreshOffsets( event );
+
+		//Generate the original position
+		this.originalPosition = this.position = this._generatePosition( event, false );
+		this.originalPageX = event.pageX;
+		this.originalPageY = event.pageY;
+
+		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
+
+		//Set a containment if given in the options
+		this._setContainment();
+
+		//Trigger event + callbacks
+		if ( this._trigger( "start", event ) === false ) {
+			this._clear();
+			return false;
+		}
+
+		//Recache the helper size
+		this._cacheHelperProportions();
+
+		//Prepare the droppable offsets
+		if ( $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( this, event );
+		}
+
+		// Execute the drag once - this causes the helper not to be visible before getting its
+		// correct position
+		this._mouseDrag( event, true );
+
+		// If the ddmanager is used for droppables, inform the manager that dragging has started
+		// (see #5003)
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.dragStart( this, event );
+		}
+
+		return true;
+	},
+
+	_refreshOffsets: function( event ) {
+		this.offset = {
+			top: this.positionAbs.top - this.margins.top,
+			left: this.positionAbs.left - this.margins.left,
+			scroll: false,
+			parent: this._getParentOffset(),
+			relative: this._getRelativeOffset()
+		};
+
+		this.offset.click = {
+			left: event.pageX - this.offset.left,
+			top: event.pageY - this.offset.top
+		};
+	},
+
+	_mouseDrag: function( event, noPropagation ) {
+
+		// reset any necessary cached properties (see #5009)
+		if ( this.hasFixedAncestor ) {
+			this.offset.parent = this._getParentOffset();
+		}
+
+		//Compute the helpers position
+		this.position = this._generatePosition( event, true );
+		this.positionAbs = this._convertPositionTo( "absolute" );
+
+		//Call plugins and callbacks and use the resulting position if something is returned
+		if ( !noPropagation ) {
+			var ui = this._uiHash();
+			if ( this._trigger( "drag", event, ui ) === false ) {
+				this._mouseUp( new $.Event( "mouseup", event ) );
+				return false;
+			}
+			this.position = ui.position;
+		}
+
+		this.helper[ 0 ].style.left = this.position.left + "px";
+		this.helper[ 0 ].style.top = this.position.top + "px";
+
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.drag( this, event );
+		}
+
+		return false;
+	},
+
+	_mouseStop: function( event ) {
+
+		//If we are using droppables, inform the manager about the drop
+		var that = this,
+			dropped = false;
+		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
+			dropped = $.ui.ddmanager.drop( this, event );
+		}
+
+		//if a drop comes from outside (a sortable)
+		if ( this.dropped ) {
+			dropped = this.dropped;
+			this.dropped = false;
+		}
+
+		if ( ( this.options.revert === "invalid" && !dropped ) ||
+				( this.options.revert === "valid" && dropped ) ||
+				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
+				this.options.revert.call( this.element, dropped ) )
+		) {
+			$( this.helper ).animate(
+				this.originalPosition,
+				parseInt( this.options.revertDuration, 10 ),
+				function() {
+					if ( that._trigger( "stop", event ) !== false ) {
+						that._clear();
+					}
+				}
+			);
+		} else {
+			if ( this._trigger( "stop", event ) !== false ) {
+				this._clear();
+			}
+		}
+
+		return false;
+	},
+
+	_mouseUp: function( event ) {
+		this._unblockFrames();
+
+		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
+		// (see #5003)
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.dragStop( this, event );
+		}
+
+		// Only need to focus if the event occurred on the draggable itself, see #10527
+		if ( this.handleElement.is( event.target ) ) {
+
+			// The interaction is over; whether or not the click resulted in a drag,
+			// focus the element
+			this.element.trigger( "focus" );
+		}
+
+		return $.ui.mouse.prototype._mouseUp.call( this, event );
+	},
+
+	cancel: function() {
+
+		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
+			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
+		} else {
+			this._clear();
+		}
+
+		return this;
+
+	},
+
+	_getHandle: function( event ) {
+		return this.options.handle ?
+			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
+			true;
+	},
+
+	_setHandleClassName: function() {
+		this.handleElement = this.options.handle ?
+			this.element.find( this.options.handle ) : this.element;
+		this._addClass( this.handleElement, "ui-draggable-handle" );
+	},
+
+	_removeHandleClassName: function() {
+		this._removeClass( this.handleElement, "ui-draggable-handle" );
+	},
+
+	_createHelper: function( event ) {
+
+		var o = this.options,
+			helperIsFunction = $.isFunction( o.helper ),
+			helper = helperIsFunction ?
+				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
+				( o.helper === "clone" ?
+					this.element.clone().removeAttr( "id" ) :
+					this.element );
+
+		if ( !helper.parents( "body" ).length ) {
+			helper.appendTo( ( o.appendTo === "parent" ?
+				this.element[ 0 ].parentNode :
+				o.appendTo ) );
+		}
+
+		// Http://bugs.jqueryui.com/ticket/9446
+		// a helper function can return the original element
+		// which wouldn't have been set to relative in _create
+		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
+			this._setPositionRelative();
+		}
+
+		if ( helper[ 0 ] !== this.element[ 0 ] &&
+				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
+			helper.css( "position", "absolute" );
+		}
+
+		return helper;
+
+	},
+
+	_setPositionRelative: function() {
+		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
+			this.element[ 0 ].style.position = "relative";
+		}
+	},
+
+	_adjustOffsetFromHelper: function( obj ) {
+		if ( typeof obj === "string" ) {
+			obj = obj.split( " " );
+		}
+		if ( $.isArray( obj ) ) {
+			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
+		}
+		if ( "left" in obj ) {
+			this.offset.click.left = obj.left + this.margins.left;
+		}
+		if ( "right" in obj ) {
+			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+		}
+		if ( "top" in obj ) {
+			this.offset.click.top = obj.top + this.margins.top;
+		}
+		if ( "bottom" in obj ) {
+			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+		}
+	},
+
+	_isRootNode: function( element ) {
+		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
+	},
+
+	_getParentOffset: function() {
+
+		//Get the offsetParent and cache its position
+		var po = this.offsetParent.offset(),
+			document = this.document[ 0 ];
+
+		// This is a special case where we need to modify a offset calculated on start, since the
+		// following happened:
+		// 1. The position of the helper is absolute, so it's position is calculated based on the
+		// next positioned parent
+		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
+		// the document, which means that the scroll is included in the initial calculation of the
+		// offset of the parent, and never recalculated upon drag
+		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
+			po.left += this.scrollParent.scrollLeft();
+			po.top += this.scrollParent.scrollTop();
+		}
+
+		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
+			po = { top: 0, left: 0 };
+		}
+
+		return {
+			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
+			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
+		};
+
+	},
+
+	_getRelativeOffset: function() {
+		if ( this.cssPosition !== "relative" ) {
+			return { top: 0, left: 0 };
+		}
+
+		var p = this.element.position(),
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+		return {
+			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
+				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
+				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+		};
+
+	},
+
+	_cacheMargins: function() {
+		this.margins = {
+			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
+			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
+			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
+			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
+		};
+	},
+
+	_cacheHelperProportions: function() {
+		this.helperProportions = {
+			width: this.helper.outerWidth(),
+			height: this.helper.outerHeight()
+		};
+	},
+
+	_setContainment: function() {
+
+		var isUserScrollable, c, ce,
+			o = this.options,
+			document = this.document[ 0 ];
+
+		this.relativeContainer = null;
+
+		if ( !o.containment ) {
+			this.containment = null;
+			return;
+		}
+
+		if ( o.containment === "window" ) {
+			this.containment = [
+				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+				$( window ).scrollLeft() + $( window ).width() -
+					this.helperProportions.width - this.margins.left,
+				$( window ).scrollTop() +
+					( $( window ).height() || document.body.parentNode.scrollHeight ) -
+					this.helperProportions.height - this.margins.top
+			];
+			return;
+		}
+
+		if ( o.containment === "document" ) {
+			this.containment = [
+				0,
+				0,
+				$( document ).width() - this.helperProportions.width - this.margins.left,
+				( $( document ).height() || document.body.parentNode.scrollHeight ) -
+					this.helperProportions.height - this.margins.top
+			];
+			return;
+		}
+
+		if ( o.containment.constructor === Array ) {
+			this.containment = o.containment;
+			return;
+		}
+
+		if ( o.containment === "parent" ) {
+			o.containment = this.helper[ 0 ].parentNode;
+		}
+
+		c = $( o.containment );
+		ce = c[ 0 ];
+
+		if ( !ce ) {
+			return;
+		}
+
+		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
+
+		this.containment = [
+			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
+				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
+			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
+				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
+			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
+				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
+				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
+				this.helperProportions.width -
+				this.margins.left -
+				this.margins.right,
+			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
+				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
+				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
+				this.helperProportions.height -
+				this.margins.top -
+				this.margins.bottom
+		];
+		this.relativeContainer = c;
+	},
+
+	_convertPositionTo: function( d, pos ) {
+
+		if ( !pos ) {
+			pos = this.position;
+		}
+
+		var mod = d === "absolute" ? 1 : -1,
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
+
+		return {
+			top: (
+
+				// The absolute mouse position
+				pos.top	+
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top * mod -
+				( ( this.cssPosition === "fixed" ?
+					-this.offset.scroll.top :
+					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
+			),
+			left: (
+
+				// The absolute mouse position
+				pos.left +
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left * mod	-
+				( ( this.cssPosition === "fixed" ?
+					-this.offset.scroll.left :
+					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
+			)
+		};
+
+	},
+
+	_generatePosition: function( event, constrainPosition ) {
+
+		var containment, co, top, left,
+			o = this.options,
+			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
+			pageX = event.pageX,
+			pageY = event.pageY;
+
+		// Cache the scroll
+		if ( !scrollIsRootNode || !this.offset.scroll ) {
+			this.offset.scroll = {
+				top: this.scrollParent.scrollTop(),
+				left: this.scrollParent.scrollLeft()
+			};
+		}
+
+		/*
+		 * - Position constraining -
+		 * Constrain the position to a mix of grid, containment.
+		 */
+
+		// If we are not dragging yet, we won't check for options
+		if ( constrainPosition ) {
+			if ( this.containment ) {
+				if ( this.relativeContainer ) {
+					co = this.relativeContainer.offset();
+					containment = [
+						this.containment[ 0 ] + co.left,
+						this.containment[ 1 ] + co.top,
+						this.containment[ 2 ] + co.left,
+						this.containment[ 3 ] + co.top
+					];
+				} else {
+					containment = this.containment;
+				}
+
+				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
+					pageX = containment[ 0 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
+					pageY = containment[ 1 ] + this.offset.click.top;
+				}
+				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
+					pageX = containment[ 2 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
+					pageY = containment[ 3 ] + this.offset.click.top;
+				}
+			}
+
+			if ( o.grid ) {
+
+				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
+				// argument errors in IE (see ticket #6950)
+				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
+					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
+				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
+					top - this.offset.click.top > containment[ 3 ] ) ?
+						top :
+						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
+							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
+
+				left = o.grid[ 0 ] ? this.originalPageX +
+					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
+					this.originalPageX;
+				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
+					left - this.offset.click.left > containment[ 2 ] ) ?
+						left :
+						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
+							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
+			}
+
+			if ( o.axis === "y" ) {
+				pageX = this.originalPageX;
+			}
+
+			if ( o.axis === "x" ) {
+				pageY = this.originalPageY;
+			}
+		}
+
+		return {
+			top: (
+
+				// The absolute mouse position
+				pageY -
+
+				// Click offset (relative to the element)
+				this.offset.click.top -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top +
+				( this.cssPosition === "fixed" ?
+					-this.offset.scroll.top :
+					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+			),
+			left: (
+
+				// The absolute mouse position
+				pageX -
+
+				// Click offset (relative to the element)
+				this.offset.click.left -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left +
+				( this.cssPosition === "fixed" ?
+					-this.offset.scroll.left :
+					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+			)
+		};
+
+	},
+
+	_clear: function() {
+		this._removeClass( this.helper, "ui-draggable-dragging" );
+		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
+			this.helper.remove();
+		}
+		this.helper = null;
+		this.cancelHelperRemoval = false;
+		if ( this.destroyOnClear ) {
+			this.destroy();
+		}
+	},
+
+	// From now on bulk stuff - mainly helpers
+
+	_trigger: function( type, event, ui ) {
+		ui = ui || this._uiHash();
+		$.ui.plugin.call( this, type, [ event, ui, this ], true );
+
+		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
+		if ( /^(drag|start|stop)/.test( type ) ) {
+			this.positionAbs = this._convertPositionTo( "absolute" );
+			ui.offset = this.positionAbs;
+		}
+		return $.Widget.prototype._trigger.call( this, type, event, ui );
+	},
+
+	plugins: {},
+
+	_uiHash: function() {
+		return {
+			helper: this.helper,
+			position: this.position,
+			originalPosition: this.originalPosition,
+			offset: this.positionAbs
+		};
+	}
+
+} );
+
+$.ui.plugin.add( "draggable", "connectToSortable", {
+	start: function( event, ui, draggable ) {
+		var uiSortable = $.extend( {}, ui, {
+			item: draggable.element
+		} );
+
+		draggable.sortables = [];
+		$( draggable.options.connectToSortable ).each( function() {
+			var sortable = $( this ).sortable( "instance" );
+
+			if ( sortable && !sortable.options.disabled ) {
+				draggable.sortables.push( sortable );
+
+				// RefreshPositions is called at drag start to refresh the containerCache
+				// which is used in drag. This ensures it's initialized and synchronized
+				// with any changes that might have happened on the page since initialization.
+				sortable.refreshPositions();
+				sortable._trigger( "activate", event, uiSortable );
+			}
+		} );
+	},
+	stop: function( event, ui, draggable ) {
+		var uiSortable = $.extend( {}, ui, {
+			item: draggable.element
+		} );
+
+		draggable.cancelHelperRemoval = false;
+
+		$.each( draggable.sortables, function() {
+			var sortable = this;
+
+			if ( sortable.isOver ) {
+				sortable.isOver = 0;
+
+				// Allow this sortable to handle removing the helper
+				draggable.cancelHelperRemoval = true;
+				sortable.cancelHelperRemoval = false;
+
+				// Use _storedCSS To restore properties in the sortable,
+				// as this also handles revert (#9675) since the draggable
+				// may have modified them in unexpected ways (#8809)
+				sortable._storedCSS = {
+					position: sortable.placeholder.css( "position" ),
+					top: sortable.placeholder.css( "top" ),
+					left: sortable.placeholder.css( "left" )
+				};
+
+				sortable._mouseStop( event );
+
+				// Once drag has ended, the sortable should return to using
+				// its original helper, not the shared helper from draggable
+				sortable.options.helper = sortable.options._helper;
+			} else {
+
+				// Prevent this Sortable from removing the helper.
+				// However, don't set the draggable to remove the helper
+				// either as another connected Sortable may yet handle the removal.
+				sortable.cancelHelperRemoval = true;
+
+				sortable._trigger( "deactivate", event, uiSortable );
+			}
+		} );
+	},
+	drag: function( event, ui, draggable ) {
+		$.each( draggable.sortables, function() {
+			var innermostIntersecting = false,
+				sortable = this;
+
+			// Copy over variables that sortable's _intersectsWith uses
+			sortable.positionAbs = draggable.positionAbs;
+			sortable.helperProportions = draggable.helperProportions;
+			sortable.offset.click = draggable.offset.click;
+
+			if ( sortable._intersectsWith( sortable.containerCache ) ) {
+				innermostIntersecting = true;
+
+				$.each( draggable.sortables, function() {
+
+					// Copy over variables that sortable's _intersectsWith uses
+					this.positionAbs = draggable.positionAbs;
+					this.helperProportions = draggable.helperProportions;
+					this.offset.click = draggable.offset.click;
+
+					if ( this !== sortable &&
+							this._intersectsWith( this.containerCache ) &&
+							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
+						innermostIntersecting = false;
+					}
+
+					return innermostIntersecting;
+				} );
+			}
+
+			if ( innermostIntersecting ) {
+
+				// If it intersects, we use a little isOver variable and set it once,
+				// so that the move-in stuff gets fired only once.
+				if ( !sortable.isOver ) {
+					sortable.isOver = 1;
+
+					// Store draggable's parent in case we need to reappend to it later.
+					draggable._parent = ui.helper.parent();
+
+					sortable.currentItem = ui.helper
+						.appendTo( sortable.element )
+						.data( "ui-sortable-item", true );
+
+					// Store helper option to later restore it
+					sortable.options._helper = sortable.options.helper;
+
+					sortable.options.helper = function() {
+						return ui.helper[ 0 ];
+					};
+
+					// Fire the start events of the sortable with our passed browser event,
+					// and our own helper (so it doesn't create a new one)
+					event.target = sortable.currentItem[ 0 ];
+					sortable._mouseCapture( event, true );
+					sortable._mouseStart( event, true, true );
+
+					// Because the browser event is way off the new appended portlet,
+					// modify necessary variables to reflect the changes
+					sortable.offset.click.top = draggable.offset.click.top;
+					sortable.offset.click.left = draggable.offset.click.left;
+					sortable.offset.parent.left -= draggable.offset.parent.left -
+						sortable.offset.parent.left;
+					sortable.offset.parent.top -= draggable.offset.parent.top -
+						sortable.offset.parent.top;
+
+					draggable._trigger( "toSortable", event );
+
+					// Inform draggable that the helper is in a valid drop zone,
+					// used solely in the revert option to handle "valid/invalid".
+					draggable.dropped = sortable.element;
+
+					// Need to refreshPositions of all sortables in the case that
+					// adding to one sortable changes the location of the other sortables (#9675)
+					$.each( draggable.sortables, function() {
+						this.refreshPositions();
+					} );
+
+					// Hack so receive/update callbacks work (mostly)
+					draggable.currentItem = draggable.element;
+					sortable.fromOutside = draggable;
+				}
+
+				if ( sortable.currentItem ) {
+					sortable._mouseDrag( event );
+
+					// Copy the sortable's position because the draggable's can potentially reflect
+					// a relative position, while sortable is always absolute, which the dragged
+					// element has now become. (#8809)
+					ui.position = sortable.position;
+				}
+			} else {
+
+				// If it doesn't intersect with the sortable, and it intersected before,
+				// we fake the drag stop of the sortable, but make sure it doesn't remove
+				// the helper by using cancelHelperRemoval.
+				if ( sortable.isOver ) {
+
+					sortable.isOver = 0;
+					sortable.cancelHelperRemoval = true;
+
+					// Calling sortable's mouseStop would trigger a revert,
+					// so revert must be temporarily false until after mouseStop is called.
+					sortable.options._revert = sortable.options.revert;
+					sortable.options.revert = false;
+
+					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
+					sortable._mouseStop( event, true );
+
+					// Restore sortable behaviors that were modfied
+					// when the draggable entered the sortable area (#9481)
+					sortable.options.revert = sortable.options._revert;
+					sortable.options.helper = sortable.options._helper;
+
+					if ( sortable.placeholder ) {
+						sortable.placeholder.remove();
+					}
+
+					// Restore and recalculate the draggable's offset considering the sortable
+					// may have modified them in unexpected ways. (#8809, #10669)
+					ui.helper.appendTo( draggable._parent );
+					draggable._refreshOffsets( event );
+					ui.position = draggable._generatePosition( event, true );
+
+					draggable._trigger( "fromSortable", event );
+
+					// Inform draggable that the helper is no longer in a valid drop zone
+					draggable.dropped = false;
+
+					// Need to refreshPositions of all sortables just in case removing
+					// from one sortable changes the location of other sortables (#9675)
+					$.each( draggable.sortables, function() {
+						this.refreshPositions();
+					} );
+				}
+			}
+		} );
+	}
+} );
+
+$.ui.plugin.add( "draggable", "cursor", {
+	start: function( event, ui, instance ) {
+		var t = $( "body" ),
+			o = instance.options;
+
+		if ( t.css( "cursor" ) ) {
+			o._cursor = t.css( "cursor" );
+		}
+		t.css( "cursor", o.cursor );
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+		if ( o._cursor ) {
+			$( "body" ).css( "cursor", o._cursor );
+		}
+	}
+} );
+
+$.ui.plugin.add( "draggable", "opacity", {
+	start: function( event, ui, instance ) {
+		var t = $( ui.helper ),
+			o = instance.options;
+		if ( t.css( "opacity" ) ) {
+			o._opacity = t.css( "opacity" );
+		}
+		t.css( "opacity", o.opacity );
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+		if ( o._opacity ) {
+			$( ui.helper ).css( "opacity", o._opacity );
+		}
+	}
+} );
+
+$.ui.plugin.add( "draggable", "scroll", {
+	start: function( event, ui, i ) {
+		if ( !i.scrollParentNotHidden ) {
+			i.scrollParentNotHidden = i.helper.scrollParent( false );
+		}
+
+		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
+				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
+			i.overflowOffset = i.scrollParentNotHidden.offset();
+		}
+	},
+	drag: function( event, ui, i  ) {
+
+		var o = i.options,
+			scrolled = false,
+			scrollParent = i.scrollParentNotHidden[ 0 ],
+			document = i.document[ 0 ];
+
+		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
+			if ( !o.axis || o.axis !== "x" ) {
+				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
+						o.scrollSensitivity ) {
+					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
+				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
+					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
+				}
+			}
+
+			if ( !o.axis || o.axis !== "y" ) {
+				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
+						o.scrollSensitivity ) {
+					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
+				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
+					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
+				}
+			}
+
+		} else {
+
+			if ( !o.axis || o.axis !== "x" ) {
+				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
+					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
+				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
+						o.scrollSensitivity ) {
+					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
+				}
+			}
+
+			if ( !o.axis || o.axis !== "y" ) {
+				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
+					scrolled = $( document ).scrollLeft(
+						$( document ).scrollLeft() - o.scrollSpeed
+					);
+				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
+						o.scrollSensitivity ) {
+					scrolled = $( document ).scrollLeft(
+						$( document ).scrollLeft() + o.scrollSpeed
+					);
+				}
+			}
+
+		}
+
+		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( i, event );
+		}
+
+	}
+} );
+
+$.ui.plugin.add( "draggable", "snap", {
+	start: function( event, ui, i ) {
+
+		var o = i.options;
+
+		i.snapElements = [];
+
+		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
+			.each( function() {
+				var $t = $( this ),
+					$o = $t.offset();
+				if ( this !== i.element[ 0 ] ) {
+					i.snapElements.push( {
+						item: this,
+						width: $t.outerWidth(), height: $t.outerHeight(),
+						top: $o.top, left: $o.left
+					} );
+				}
+			} );
+
+	},
+	drag: function( event, ui, inst ) {
+
+		var ts, bs, ls, rs, l, r, t, b, i, first,
+			o = inst.options,
+			d = o.snapTolerance,
+			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
+
+			l = inst.snapElements[ i ].left - inst.margins.left;
+			r = l + inst.snapElements[ i ].width;
+			t = inst.snapElements[ i ].top - inst.margins.top;
+			b = t + inst.snapElements[ i ].height;
+
+			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
+					!$.contains( inst.snapElements[ i ].item.ownerDocument,
+					inst.snapElements[ i ].item ) ) {
+				if ( inst.snapElements[ i ].snapping ) {
+					( inst.options.snap.release &&
+						inst.options.snap.release.call(
+							inst.element,
+							event,
+							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
+						) );
+				}
+				inst.snapElements[ i ].snapping = false;
+				continue;
+			}
+
+			if ( o.snapMode !== "inner" ) {
+				ts = Math.abs( t - y2 ) <= d;
+				bs = Math.abs( b - y1 ) <= d;
+				ls = Math.abs( l - x2 ) <= d;
+				rs = Math.abs( r - x1 ) <= d;
+				if ( ts ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: t - inst.helperProportions.height,
+						left: 0
+					} ).top;
+				}
+				if ( bs ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: b,
+						left: 0
+					} ).top;
+				}
+				if ( ls ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: l - inst.helperProportions.width
+					} ).left;
+				}
+				if ( rs ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: r
+					} ).left;
+				}
+			}
+
+			first = ( ts || bs || ls || rs );
+
+			if ( o.snapMode !== "outer" ) {
+				ts = Math.abs( t - y1 ) <= d;
+				bs = Math.abs( b - y2 ) <= d;
+				ls = Math.abs( l - x1 ) <= d;
+				rs = Math.abs( r - x2 ) <= d;
+				if ( ts ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: t,
+						left: 0
+					} ).top;
+				}
+				if ( bs ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: b - inst.helperProportions.height,
+						left: 0
+					} ).top;
+				}
+				if ( ls ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: l
+					} ).left;
+				}
+				if ( rs ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: r - inst.helperProportions.width
+					} ).left;
+				}
+			}
+
+			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
+				( inst.options.snap.snap &&
+					inst.options.snap.snap.call(
+						inst.element,
+						event,
+						$.extend( inst._uiHash(), {
+							snapItem: inst.snapElements[ i ].item
+						} ) ) );
+			}
+			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
+
+		}
+
+	}
+} );
+
+$.ui.plugin.add( "draggable", "stack", {
+	start: function( event, ui, instance ) {
+		var min,
+			o = instance.options,
+			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
+				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
+					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
+			} );
+
+		if ( !group.length ) { return; }
+
+		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
+		$( group ).each( function( i ) {
+			$( this ).css( "zIndex", min + i );
+		} );
+		this.css( "zIndex", ( min + group.length ) );
+	}
+} );
+
+$.ui.plugin.add( "draggable", "zIndex", {
+	start: function( event, ui, instance ) {
+		var t = $( ui.helper ),
+			o = instance.options;
+
+		if ( t.css( "zIndex" ) ) {
+			o._zIndex = t.css( "zIndex" );
+		}
+		t.css( "zIndex", o.zIndex );
+	},
+	stop: function( event, ui, instance ) {
+		var o = instance.options;
+
+		if ( o._zIndex ) {
+			$( ui.helper ).css( "zIndex", o._zIndex );
+		}
+	}
+} );
+
+var widgetsDraggable = $.ui.draggable;
+
+
+/*!
+ * jQuery UI Resizable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/
  */
-jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
-16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
-a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
-a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
-"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
-0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
-211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
-d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})};
-f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,
-[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.14",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,a){var b;switch(c[0]){case "top":b=
-0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});
-c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,
-a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);
-a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%",
-"pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*
-((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=
-e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=
-e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/
-h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);if(a<1)return-0.5*
-h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,a,b,d,e){return d-f.easing.easeOutBounce(c,
-e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
-;/*
- * jQuery UI Effects Blind 1.8.14
+
+//>>label: Resizable
+//>>group: Interactions
+//>>description: Enables resize functionality for any element.
+//>>docs: http://api.jqueryui.com/resizable/
+//>>demos: http://jqueryui.com/resizable/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/resizable.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.resizable", $.ui.mouse, {
+	version: "1.12.1",
+	widgetEventPrefix: "resize",
+	options: {
+		alsoResize: false,
+		animate: false,
+		animateDuration: "slow",
+		animateEasing: "swing",
+		aspectRatio: false,
+		autoHide: false,
+		classes: {
+			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
+		},
+		containment: false,
+		ghost: false,
+		grid: false,
+		handles: "e,s,se",
+		helper: false,
+		maxHeight: null,
+		maxWidth: null,
+		minHeight: 10,
+		minWidth: 10,
+
+		// See #7960
+		zIndex: 90,
+
+		// Callbacks
+		resize: null,
+		start: null,
+		stop: null
+	},
+
+	_num: function( value ) {
+		return parseFloat( value ) || 0;
+	},
+
+	_isNumber: function( value ) {
+		return !isNaN( parseFloat( value ) );
+	},
+
+	_hasScroll: function( el, a ) {
+
+		if ( $( el ).css( "overflow" ) === "hidden" ) {
+			return false;
+		}
+
+		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+			has = false;
+
+		if ( el[ scroll ] > 0 ) {
+			return true;
+		}
+
+		// TODO: determine which cases actually cause this to happen
+		// if the element doesn't have the scroll set, see if it's possible to
+		// set the scroll
+		el[ scroll ] = 1;
+		has = ( el[ scroll ] > 0 );
+		el[ scroll ] = 0;
+		return has;
+	},
+
+	_create: function() {
+
+		var margins,
+			o = this.options,
+			that = this;
+		this._addClass( "ui-resizable" );
+
+		$.extend( this, {
+			_aspectRatio: !!( o.aspectRatio ),
+			aspectRatio: o.aspectRatio,
+			originalElement: this.element,
+			_proportionallyResizeElements: [],
+			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
+		} );
+
+		// Wrap the element if it cannot hold child nodes
+		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
+
+			this.element.wrap(
+				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
+					position: this.element.css( "position" ),
+					width: this.element.outerWidth(),
+					height: this.element.outerHeight(),
+					top: this.element.css( "top" ),
+					left: this.element.css( "left" )
+				} )
+			);
+
+			this.element = this.element.parent().data(
+				"ui-resizable", this.element.resizable( "instance" )
+			);
+
+			this.elementIsWrapper = true;
+
+			margins = {
+				marginTop: this.originalElement.css( "marginTop" ),
+				marginRight: this.originalElement.css( "marginRight" ),
+				marginBottom: this.originalElement.css( "marginBottom" ),
+				marginLeft: this.originalElement.css( "marginLeft" )
+			};
+
+			this.element.css( margins );
+			this.originalElement.css( "margin", 0 );
+
+			// support: Safari
+			// Prevent Safari textarea resize
+			this.originalResizeStyle = this.originalElement.css( "resize" );
+			this.originalElement.css( "resize", "none" );
+
+			this._proportionallyResizeElements.push( this.originalElement.css( {
+				position: "static",
+				zoom: 1,
+				display: "block"
+			} ) );
+
+			// Support: IE9
+			// avoid IE jump (hard set the margin)
+			this.originalElement.css( margins );
+
+			this._proportionallyResize();
+		}
+
+		this._setupHandles();
+
+		if ( o.autoHide ) {
+			$( this.element )
+				.on( "mouseenter", function() {
+					if ( o.disabled ) {
+						return;
+					}
+					that._removeClass( "ui-resizable-autohide" );
+					that._handles.show();
+				} )
+				.on( "mouseleave", function() {
+					if ( o.disabled ) {
+						return;
+					}
+					if ( !that.resizing ) {
+						that._addClass( "ui-resizable-autohide" );
+						that._handles.hide();
+					}
+				} );
+		}
+
+		this._mouseInit();
+	},
+
+	_destroy: function() {
+
+		this._mouseDestroy();
+
+		var wrapper,
+			_destroy = function( exp ) {
+				$( exp )
+					.removeData( "resizable" )
+					.removeData( "ui-resizable" )
+					.off( ".resizable" )
+					.find( ".ui-resizable-handle" )
+						.remove();
+			};
+
+		// TODO: Unwrap at same DOM position
+		if ( this.elementIsWrapper ) {
+			_destroy( this.element );
+			wrapper = this.element;
+			this.originalElement.css( {
+				position: wrapper.css( "position" ),
+				width: wrapper.outerWidth(),
+				height: wrapper.outerHeight(),
+				top: wrapper.css( "top" ),
+				left: wrapper.css( "left" )
+			} ).insertAfter( wrapper );
+			wrapper.remove();
+		}
+
+		this.originalElement.css( "resize", this.originalResizeStyle );
+		_destroy( this.originalElement );
+
+		return this;
+	},
+
+	_setOption: function( key, value ) {
+		this._super( key, value );
+
+		switch ( key ) {
+		case "handles":
+			this._removeHandles();
+			this._setupHandles();
+			break;
+		default:
+			break;
+		}
+	},
+
+	_setupHandles: function() {
+		var o = this.options, handle, i, n, hname, axis, that = this;
+		this.handles = o.handles ||
+			( !$( ".ui-resizable-handle", this.element ).length ?
+				"e,s,se" : {
+					n: ".ui-resizable-n",
+					e: ".ui-resizable-e",
+					s: ".ui-resizable-s",
+					w: ".ui-resizable-w",
+					se: ".ui-resizable-se",
+					sw: ".ui-resizable-sw",
+					ne: ".ui-resizable-ne",
+					nw: ".ui-resizable-nw"
+				} );
+
+		this._handles = $();
+		if ( this.handles.constructor === String ) {
+
+			if ( this.handles === "all" ) {
+				this.handles = "n,e,s,w,se,sw,ne,nw";
+			}
+
+			n = this.handles.split( "," );
+			this.handles = {};
+
+			for ( i = 0; i < n.length; i++ ) {
+
+				handle = $.trim( n[ i ] );
+				hname = "ui-resizable-" + handle;
+				axis = $( "<div>" );
+				this._addClass( axis, "ui-resizable-handle " + hname );
+
+				axis.css( { zIndex: o.zIndex } );
+
+				this.handles[ handle ] = ".ui-resizable-" + handle;
+				this.element.append( axis );
+			}
+
+		}
+
+		this._renderAxis = function( target ) {
+
+			var i, axis, padPos, padWrapper;
+
+			target = target || this.element;
+
+			for ( i in this.handles ) {
+
+				if ( this.handles[ i ].constructor === String ) {
+					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
+				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
+					this.handles[ i ] = $( this.handles[ i ] );
+					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
+				}
+
+				if ( this.elementIsWrapper &&
+						this.originalElement[ 0 ]
+							.nodeName
+							.match( /^(textarea|input|select|button)$/i ) ) {
+					axis = $( this.handles[ i ], this.element );
+
+					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
+						axis.outerHeight() :
+						axis.outerWidth();
+
+					padPos = [ "padding",
+						/ne|nw|n/.test( i ) ? "Top" :
+						/se|sw|s/.test( i ) ? "Bottom" :
+						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
+
+					target.css( padPos, padWrapper );
+
+					this._proportionallyResize();
+				}
+
+				this._handles = this._handles.add( this.handles[ i ] );
+			}
+		};
+
+		// TODO: make renderAxis a prototype function
+		this._renderAxis( this.element );
+
+		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
+		this._handles.disableSelection();
+
+		this._handles.on( "mouseover", function() {
+			if ( !that.resizing ) {
+				if ( this.className ) {
+					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
+				}
+				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
+			}
+		} );
+
+		if ( o.autoHide ) {
+			this._handles.hide();
+			this._addClass( "ui-resizable-autohide" );
+		}
+	},
+
+	_removeHandles: function() {
+		this._handles.remove();
+	},
+
+	_mouseCapture: function( event ) {
+		var i, handle,
+			capture = false;
+
+		for ( i in this.handles ) {
+			handle = $( this.handles[ i ] )[ 0 ];
+			if ( handle === event.target || $.contains( handle, event.target ) ) {
+				capture = true;
+			}
+		}
+
+		return !this.options.disabled && capture;
+	},
+
+	_mouseStart: function( event ) {
+
+		var curleft, curtop, cursor,
+			o = this.options,
+			el = this.element;
+
+		this.resizing = true;
+
+		this._renderProxy();
+
+		curleft = this._num( this.helper.css( "left" ) );
+		curtop = this._num( this.helper.css( "top" ) );
+
+		if ( o.containment ) {
+			curleft += $( o.containment ).scrollLeft() || 0;
+			curtop += $( o.containment ).scrollTop() || 0;
+		}
+
+		this.offset = this.helper.offset();
+		this.position = { left: curleft, top: curtop };
+
+		this.size = this._helper ? {
+				width: this.helper.width(),
+				height: this.helper.height()
+			} : {
+				width: el.width(),
+				height: el.height()
+			};
+
+		this.originalSize = this._helper ? {
+				width: el.outerWidth(),
+				height: el.outerHeight()
+			} : {
+				width: el.width(),
+				height: el.height()
+			};
+
+		this.sizeDiff = {
+			width: el.outerWidth() - el.width(),
+			height: el.outerHeight() - el.height()
+		};
+
+		this.originalPosition = { left: curleft, top: curtop };
+		this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
+			o.aspectRatio :
+			( ( this.originalSize.width / this.originalSize.height ) || 1 );
+
+		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
+		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
+
+		this._addClass( "ui-resizable-resizing" );
+		this._propagate( "start", event );
+		return true;
+	},
+
+	_mouseDrag: function( event ) {
+
+		var data, props,
+			smp = this.originalMousePosition,
+			a = this.axis,
+			dx = ( event.pageX - smp.left ) || 0,
+			dy = ( event.pageY - smp.top ) || 0,
+			trigger = this._change[ a ];
+
+		this._updatePrevProperties();
+
+		if ( !trigger ) {
+			return false;
+		}
+
+		data = trigger.apply( this, [ event, dx, dy ] );
+
+		this._updateVirtualBoundaries( event.shiftKey );
+		if ( this._aspectRatio || event.shiftKey ) {
+			data = this._updateRatio( data, event );
+		}
+
+		data = this._respectSize( data, event );
+
+		this._updateCache( data );
+
+		this._propagate( "resize", event );
+
+		props = this._applyChanges();
+
+		if ( !this._helper && this._proportionallyResizeElements.length ) {
+			this._proportionallyResize();
+		}
+
+		if ( !$.isEmptyObject( props ) ) {
+			this._updatePrevProperties();
+			this._trigger( "resize", event, this.ui() );
+			this._applyChanges();
+		}
+
+		return false;
+	},
+
+	_mouseStop: function( event ) {
+
+		this.resizing = false;
+		var pr, ista, soffseth, soffsetw, s, left, top,
+			o = this.options, that = this;
+
+		if ( this._helper ) {
+
+			pr = this._proportionallyResizeElements;
+			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
+			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
+			soffsetw = ista ? 0 : that.sizeDiff.width;
+
+			s = {
+				width: ( that.helper.width()  - soffsetw ),
+				height: ( that.helper.height() - soffseth )
+			};
+			left = ( parseFloat( that.element.css( "left" ) ) +
+				( that.position.left - that.originalPosition.left ) ) || null;
+			top = ( parseFloat( that.element.css( "top" ) ) +
+				( that.position.top - that.originalPosition.top ) ) || null;
+
+			if ( !o.animate ) {
+				this.element.css( $.extend( s, { top: top, left: left } ) );
+			}
+
+			that.helper.height( that.size.height );
+			that.helper.width( that.size.width );
+
+			if ( this._helper && !o.animate ) {
+				this._proportionallyResize();
+			}
+		}
+
+		$( "body" ).css( "cursor", "auto" );
+
+		this._removeClass( "ui-resizable-resizing" );
+
+		this._propagate( "stop", event );
+
+		if ( this._helper ) {
+			this.helper.remove();
+		}
+
+		return false;
+
+	},
+
+	_updatePrevProperties: function() {
+		this.prevPosition = {
+			top: this.position.top,
+			left: this.position.left
+		};
+		this.prevSize = {
+			width: this.size.width,
+			height: this.size.height
+		};
+	},
+
+	_applyChanges: function() {
+		var props = {};
+
+		if ( this.position.top !== this.prevPosition.top ) {
+			props.top = this.position.top + "px";
+		}
+		if ( this.position.left !== this.prevPosition.left ) {
+			props.left = this.position.left + "px";
+		}
+		if ( this.size.width !== this.prevSize.width ) {
+			props.width = this.size.width + "px";
+		}
+		if ( this.size.height !== this.prevSize.height ) {
+			props.height = this.size.height + "px";
+		}
+
+		this.helper.css( props );
+
+		return props;
+	},
+
+	_updateVirtualBoundaries: function( forceAspectRatio ) {
+		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
+			o = this.options;
+
+		b = {
+			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
+			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
+			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
+			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
+		};
+
+		if ( this._aspectRatio || forceAspectRatio ) {
+			pMinWidth = b.minHeight * this.aspectRatio;
+			pMinHeight = b.minWidth / this.aspectRatio;
+			pMaxWidth = b.maxHeight * this.aspectRatio;
+			pMaxHeight = b.maxWidth / this.aspectRatio;
+
+			if ( pMinWidth > b.minWidth ) {
+				b.minWidth = pMinWidth;
+			}
+			if ( pMinHeight > b.minHeight ) {
+				b.minHeight = pMinHeight;
+			}
+			if ( pMaxWidth < b.maxWidth ) {
+				b.maxWidth = pMaxWidth;
+			}
+			if ( pMaxHeight < b.maxHeight ) {
+				b.maxHeight = pMaxHeight;
+			}
+		}
+		this._vBoundaries = b;
+	},
+
+	_updateCache: function( data ) {
+		this.offset = this.helper.offset();
+		if ( this._isNumber( data.left ) ) {
+			this.position.left = data.left;
+		}
+		if ( this._isNumber( data.top ) ) {
+			this.position.top = data.top;
+		}
+		if ( this._isNumber( data.height ) ) {
+			this.size.height = data.height;
+		}
+		if ( this._isNumber( data.width ) ) {
+			this.size.width = data.width;
+		}
+	},
+
+	_updateRatio: function( data ) {
+
+		var cpos = this.position,
+			csize = this.size,
+			a = this.axis;
+
+		if ( this._isNumber( data.height ) ) {
+			data.width = ( data.height * this.aspectRatio );
+		} else if ( this._isNumber( data.width ) ) {
+			data.height = ( data.width / this.aspectRatio );
+		}
+
+		if ( a === "sw" ) {
+			data.left = cpos.left + ( csize.width - data.width );
+			data.top = null;
+		}
+		if ( a === "nw" ) {
+			data.top = cpos.top + ( csize.height - data.height );
+			data.left = cpos.left + ( csize.width - data.width );
+		}
+
+		return data;
+	},
+
+	_respectSize: function( data ) {
+
+		var o = this._vBoundaries,
+			a = this.axis,
+			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
+			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
+			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
+			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
+			dw = this.originalPosition.left + this.originalSize.width,
+			dh = this.originalPosition.top + this.originalSize.height,
+			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
+		if ( isminw ) {
+			data.width = o.minWidth;
+		}
+		if ( isminh ) {
+			data.height = o.minHeight;
+		}
+		if ( ismaxw ) {
+			data.width = o.maxWidth;
+		}
+		if ( ismaxh ) {
+			data.height = o.maxHeight;
+		}
+
+		if ( isminw && cw ) {
+			data.left = dw - o.minWidth;
+		}
+		if ( ismaxw && cw ) {
+			data.left = dw - o.maxWidth;
+		}
+		if ( isminh && ch ) {
+			data.top = dh - o.minHeight;
+		}
+		if ( ismaxh && ch ) {
+			data.top = dh - o.maxHeight;
+		}
+
+		// Fixing jump error on top/left - bug #2330
+		if ( !data.width && !data.height && !data.left && data.top ) {
+			data.top = null;
+		} else if ( !data.width && !data.height && !data.top && data.left ) {
+			data.left = null;
+		}
+
+		return data;
+	},
+
+	_getPaddingPlusBorderDimensions: function( element ) {
+		var i = 0,
+			widths = [],
+			borders = [
+				element.css( "borderTopWidth" ),
+				element.css( "borderRightWidth" ),
+				element.css( "borderBottomWidth" ),
+				element.css( "borderLeftWidth" )
+			],
+			paddings = [
+				element.css( "paddingTop" ),
+				element.css( "paddingRight" ),
+				element.css( "paddingBottom" ),
+				element.css( "paddingLeft" )
+			];
+
+		for ( ; i < 4; i++ ) {
+			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
+			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
+		}
+
+		return {
+			height: widths[ 0 ] + widths[ 2 ],
+			width: widths[ 1 ] + widths[ 3 ]
+		};
+	},
+
+	_proportionallyResize: function() {
+
+		if ( !this._proportionallyResizeElements.length ) {
+			return;
+		}
+
+		var prel,
+			i = 0,
+			element = this.helper || this.element;
+
+		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
+
+			prel = this._proportionallyResizeElements[ i ];
+
+			// TODO: Seems like a bug to cache this.outerDimensions
+			// considering that we are in a loop.
+			if ( !this.outerDimensions ) {
+				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
+			}
+
+			prel.css( {
+				height: ( element.height() - this.outerDimensions.height ) || 0,
+				width: ( element.width() - this.outerDimensions.width ) || 0
+			} );
+
+		}
+
+	},
+
+	_renderProxy: function() {
+
+		var el = this.element, o = this.options;
+		this.elementOffset = el.offset();
+
+		if ( this._helper ) {
+
+			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
+
+			this._addClass( this.helper, this._helper );
+			this.helper.css( {
+				width: this.element.outerWidth(),
+				height: this.element.outerHeight(),
+				position: "absolute",
+				left: this.elementOffset.left + "px",
+				top: this.elementOffset.top + "px",
+				zIndex: ++o.zIndex //TODO: Don't modify option
+			} );
+
+			this.helper
+				.appendTo( "body" )
+				.disableSelection();
+
+		} else {
+			this.helper = this.element;
+		}
+
+	},
+
+	_change: {
+		e: function( event, dx ) {
+			return { width: this.originalSize.width + dx };
+		},
+		w: function( event, dx ) {
+			var cs = this.originalSize, sp = this.originalPosition;
+			return { left: sp.left + dx, width: cs.width - dx };
+		},
+		n: function( event, dx, dy ) {
+			var cs = this.originalSize, sp = this.originalPosition;
+			return { top: sp.top + dy, height: cs.height - dy };
+		},
+		s: function( event, dx, dy ) {
+			return { height: this.originalSize.height + dy };
+		},
+		se: function( event, dx, dy ) {
+			return $.extend( this._change.s.apply( this, arguments ),
+				this._change.e.apply( this, [ event, dx, dy ] ) );
+		},
+		sw: function( event, dx, dy ) {
+			return $.extend( this._change.s.apply( this, arguments ),
+				this._change.w.apply( this, [ event, dx, dy ] ) );
+		},
+		ne: function( event, dx, dy ) {
+			return $.extend( this._change.n.apply( this, arguments ),
+				this._change.e.apply( this, [ event, dx, dy ] ) );
+		},
+		nw: function( event, dx, dy ) {
+			return $.extend( this._change.n.apply( this, arguments ),
+				this._change.w.apply( this, [ event, dx, dy ] ) );
+		}
+	},
+
+	_propagate: function( n, event ) {
+		$.ui.plugin.call( this, n, [ event, this.ui() ] );
+		( n !== "resize" && this._trigger( n, event, this.ui() ) );
+	},
+
+	plugins: {},
+
+	ui: function() {
+		return {
+			originalElement: this.originalElement,
+			element: this.element,
+			helper: this.helper,
+			position: this.position,
+			size: this.size,
+			originalSize: this.originalSize,
+			originalPosition: this.originalPosition
+		};
+	}
+
+} );
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add( "resizable", "animate", {
+
+	stop: function( event ) {
+		var that = $( this ).resizable( "instance" ),
+			o = that.options,
+			pr = that._proportionallyResizeElements,
+			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
+			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
+			soffsetw = ista ? 0 : that.sizeDiff.width,
+			style = {
+				width: ( that.size.width - soffsetw ),
+				height: ( that.size.height - soffseth )
+			},
+			left = ( parseFloat( that.element.css( "left" ) ) +
+				( that.position.left - that.originalPosition.left ) ) || null,
+			top = ( parseFloat( that.element.css( "top" ) ) +
+				( that.position.top - that.originalPosition.top ) ) || null;
+
+		that.element.animate(
+			$.extend( style, top && left ? { top: top, left: left } : {} ), {
+				duration: o.animateDuration,
+				easing: o.animateEasing,
+				step: function() {
+
+					var data = {
+						width: parseFloat( that.element.css( "width" ) ),
+						height: parseFloat( that.element.css( "height" ) ),
+						top: parseFloat( that.element.css( "top" ) ),
+						left: parseFloat( that.element.css( "left" ) )
+					};
+
+					if ( pr && pr.length ) {
+						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
+					}
+
+					// Propagating resize, and updating values for each animation step
+					that._updateCache( data );
+					that._propagate( "resize", event );
+
+				}
+			}
+		);
+	}
+
+} );
+
+$.ui.plugin.add( "resizable", "containment", {
+
+	start: function() {
+		var element, p, co, ch, cw, width, height,
+			that = $( this ).resizable( "instance" ),
+			o = that.options,
+			el = that.element,
+			oc = o.containment,
+			ce = ( oc instanceof $ ) ?
+				oc.get( 0 ) :
+				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
+
+		if ( !ce ) {
+			return;
+		}
+
+		that.containerElement = $( ce );
+
+		if ( /document/.test( oc ) || oc === document ) {
+			that.containerOffset = {
+				left: 0,
+				top: 0
+			};
+			that.containerPosition = {
+				left: 0,
+				top: 0
+			};
+
+			that.parentData = {
+				element: $( document ),
+				left: 0,
+				top: 0,
+				width: $( document ).width(),
+				height: $( document ).height() || document.body.parentNode.scrollHeight
+			};
+		} else {
+			element = $( ce );
+			p = [];
+			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
+				p[ i ] = that._num( element.css( "padding" + name ) );
+			} );
+
+			that.containerOffset = element.offset();
+			that.containerPosition = element.position();
+			that.containerSize = {
+				height: ( element.innerHeight() - p[ 3 ] ),
+				width: ( element.innerWidth() - p[ 1 ] )
+			};
+
+			co = that.containerOffset;
+			ch = that.containerSize.height;
+			cw = that.containerSize.width;
+			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
+			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
+
+			that.parentData = {
+				element: ce,
+				left: co.left,
+				top: co.top,
+				width: width,
+				height: height
+			};
+		}
+	},
+
+	resize: function( event ) {
+		var woset, hoset, isParent, isOffsetRelative,
+			that = $( this ).resizable( "instance" ),
+			o = that.options,
+			co = that.containerOffset,
+			cp = that.position,
+			pRatio = that._aspectRatio || event.shiftKey,
+			cop = {
+				top: 0,
+				left: 0
+			},
+			ce = that.containerElement,
+			continueResize = true;
+
+		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
+			cop = co;
+		}
+
+		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
+			that.size.width = that.size.width +
+				( that._helper ?
+					( that.position.left - co.left ) :
+					( that.position.left - cop.left ) );
+
+			if ( pRatio ) {
+				that.size.height = that.size.width / that.aspectRatio;
+				continueResize = false;
+			}
+			that.position.left = o.helper ? co.left : 0;
+		}
+
+		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
+			that.size.height = that.size.height +
+				( that._helper ?
+					( that.position.top - co.top ) :
+					that.position.top );
+
+			if ( pRatio ) {
+				that.size.width = that.size.height * that.aspectRatio;
+				continueResize = false;
+			}
+			that.position.top = that._helper ? co.top : 0;
+		}
+
+		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
+		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
+
+		if ( isParent && isOffsetRelative ) {
+			that.offset.left = that.parentData.left + that.position.left;
+			that.offset.top = that.parentData.top + that.position.top;
+		} else {
+			that.offset.left = that.element.offset().left;
+			that.offset.top = that.element.offset().top;
+		}
+
+		woset = Math.abs( that.sizeDiff.width +
+			( that._helper ?
+				that.offset.left - cop.left :
+				( that.offset.left - co.left ) ) );
+
+		hoset = Math.abs( that.sizeDiff.height +
+			( that._helper ?
+				that.offset.top - cop.top :
+				( that.offset.top - co.top ) ) );
+
+		if ( woset + that.size.width >= that.parentData.width ) {
+			that.size.width = that.parentData.width - woset;
+			if ( pRatio ) {
+				that.size.height = that.size.width / that.aspectRatio;
+				continueResize = false;
+			}
+		}
+
+		if ( hoset + that.size.height >= that.parentData.height ) {
+			that.size.height = that.parentData.height - hoset;
+			if ( pRatio ) {
+				that.size.width = that.size.height * that.aspectRatio;
+				continueResize = false;
+			}
+		}
+
+		if ( !continueResize ) {
+			that.position.left = that.prevPosition.left;
+			that.position.top = that.prevPosition.top;
+			that.size.width = that.prevSize.width;
+			that.size.height = that.prevSize.height;
+		}
+	},
+
+	stop: function() {
+		var that = $( this ).resizable( "instance" ),
+			o = that.options,
+			co = that.containerOffset,
+			cop = that.containerPosition,
+			ce = that.containerElement,
+			helper = $( that.helper ),
+			ho = helper.offset(),
+			w = helper.outerWidth() - that.sizeDiff.width,
+			h = helper.outerHeight() - that.sizeDiff.height;
+
+		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
+			$( this ).css( {
+				left: ho.left - cop.left - co.left,
+				width: w,
+				height: h
+			} );
+		}
+
+		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
+			$( this ).css( {
+				left: ho.left - cop.left - co.left,
+				width: w,
+				height: h
+			} );
+		}
+	}
+} );
+
+$.ui.plugin.add( "resizable", "alsoResize", {
+
+	start: function() {
+		var that = $( this ).resizable( "instance" ),
+			o = that.options;
+
+		$( o.alsoResize ).each( function() {
+			var el = $( this );
+			el.data( "ui-resizable-alsoresize", {
+				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
+				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
+			} );
+		} );
+	},
+
+	resize: function( event, ui ) {
+		var that = $( this ).resizable( "instance" ),
+			o = that.options,
+			os = that.originalSize,
+			op = that.originalPosition,
+			delta = {
+				height: ( that.size.height - os.height ) || 0,
+				width: ( that.size.width - os.width ) || 0,
+				top: ( that.position.top - op.top ) || 0,
+				left: ( that.position.left - op.left ) || 0
+			};
+
+			$( o.alsoResize ).each( function() {
+				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
+					css = el.parents( ui.originalElement[ 0 ] ).length ?
+							[ "width", "height" ] :
+							[ "width", "height", "top", "left" ];
+
+				$.each( css, function( i, prop ) {
+					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
+					if ( sum && sum >= 0 ) {
+						style[ prop ] = sum || null;
+					}
+				} );
+
+				el.css( style );
+			} );
+	},
+
+	stop: function() {
+		$( this ).removeData( "ui-resizable-alsoresize" );
+	}
+} );
+
+$.ui.plugin.add( "resizable", "ghost", {
+
+	start: function() {
+
+		var that = $( this ).resizable( "instance" ), cs = that.size;
+
+		that.ghost = that.originalElement.clone();
+		that.ghost.css( {
+			opacity: 0.25,
+			display: "block",
+			position: "relative",
+			height: cs.height,
+			width: cs.width,
+			margin: 0,
+			left: 0,
+			top: 0
+		} );
+
+		that._addClass( that.ghost, "ui-resizable-ghost" );
+
+		// DEPRECATED
+		// TODO: remove after 1.12
+		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
+
+			// Ghost option
+			that.ghost.addClass( this.options.ghost );
+		}
+
+		that.ghost.appendTo( that.helper );
+
+	},
+
+	resize: function() {
+		var that = $( this ).resizable( "instance" );
+		if ( that.ghost ) {
+			that.ghost.css( {
+				position: "relative",
+				height: that.size.height,
+				width: that.size.width
+			} );
+		}
+	},
+
+	stop: function() {
+		var that = $( this ).resizable( "instance" );
+		if ( that.ghost && that.helper ) {
+			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
+		}
+	}
+
+} );
+
+$.ui.plugin.add( "resizable", "grid", {
+
+	resize: function() {
+		var outerDimensions,
+			that = $( this ).resizable( "instance" ),
+			o = that.options,
+			cs = that.size,
+			os = that.originalSize,
+			op = that.originalPosition,
+			a = that.axis,
+			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
+			gridX = ( grid[ 0 ] || 1 ),
+			gridY = ( grid[ 1 ] || 1 ),
+			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
+			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
+			newWidth = os.width + ox,
+			newHeight = os.height + oy,
+			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
+			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
+			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
+			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
+
+		o.grid = grid;
+
+		if ( isMinWidth ) {
+			newWidth += gridX;
+		}
+		if ( isMinHeight ) {
+			newHeight += gridY;
+		}
+		if ( isMaxWidth ) {
+			newWidth -= gridX;
+		}
+		if ( isMaxHeight ) {
+			newHeight -= gridY;
+		}
+
+		if ( /^(se|s|e)$/.test( a ) ) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+		} else if ( /^(ne)$/.test( a ) ) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+			that.position.top = op.top - oy;
+		} else if ( /^(sw)$/.test( a ) ) {
+			that.size.width = newWidth;
+			that.size.height = newHeight;
+			that.position.left = op.left - ox;
+		} else {
+			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
+				outerDimensions = that._getPaddingPlusBorderDimensions( this );
+			}
+
+			if ( newHeight - gridY > 0 ) {
+				that.size.height = newHeight;
+				that.position.top = op.top - oy;
+			} else {
+				newHeight = gridY - outerDimensions.height;
+				that.size.height = newHeight;
+				that.position.top = op.top + os.height - newHeight;
+			}
+			if ( newWidth - gridX > 0 ) {
+				that.size.width = newWidth;
+				that.position.left = op.left - ox;
+			} else {
+				newWidth = gridX - outerDimensions.width;
+				that.size.width = newWidth;
+				that.position.left = op.left + os.width - newWidth;
+			}
+		}
+	}
+
+} );
+
+var widgetsResizable = $.ui.resizable;
+
+
+/*!
+ * jQuery UI Dialog 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Blind
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(b){b.effects.blind=function(c){return this.queue(function(){var a=b(this),g=["position","top","bottom","left","right"],f=b.effects.setMode(a,c.options.mode||"hide"),d=c.options.direction||"vertical";b.effects.save(a,g);a.show();var e=b.effects.createWrapper(a).css({overflow:"hidden"}),h=d=="vertical"?"height":"width";d=d=="vertical"?e.height():e.width();f=="show"&&e.css(h,0);var i={};i[h]=f=="show"?d:0;e.animate(i,c.duration,c.options.easing,function(){f=="hide"&&a.hide();b.effects.restore(a,
-g);b.effects.removeWrapper(a);c.callback&&c.callback.apply(a[0],arguments);a.dequeue()})})}})(jQuery);
-;/*
- * jQuery UI Effects Bounce 1.8.14
+
+//>>label: Dialog
+//>>group: Widgets
+//>>description: Displays customizable dialog windows.
+//>>docs: http://api.jqueryui.com/dialog/
+//>>demos: http://jqueryui.com/dialog/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/dialog.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.dialog", {
+	version: "1.12.1",
+	options: {
+		appendTo: "body",
+		autoOpen: true,
+		buttons: [],
+		classes: {
+			"ui-dialog": "ui-corner-all",
+			"ui-dialog-titlebar": "ui-corner-all"
+		},
+		closeOnEscape: true,
+		closeText: "Close",
+		draggable: true,
+		hide: null,
+		height: "auto",
+		maxHeight: null,
+		maxWidth: null,
+		minHeight: 150,
+		minWidth: 150,
+		modal: false,
+		position: {
+			my: "center",
+			at: "center",
+			of: window,
+			collision: "fit",
+
+			// Ensure the titlebar is always visible
+			using: function( pos ) {
+				var topOffset = $( this ).css( pos ).offset().top;
+				if ( topOffset < 0 ) {
+					$( this ).css( "top", pos.top - topOffset );
+				}
+			}
+		},
+		resizable: true,
+		show: null,
+		title: null,
+		width: 300,
+
+		// Callbacks
+		beforeClose: null,
+		close: null,
+		drag: null,
+		dragStart: null,
+		dragStop: null,
+		focus: null,
+		open: null,
+		resize: null,
+		resizeStart: null,
+		resizeStop: null
+	},
+
+	sizeRelatedOptions: {
+		buttons: true,
+		height: true,
+		maxHeight: true,
+		maxWidth: true,
+		minHeight: true,
+		minWidth: true,
+		width: true
+	},
+
+	resizableRelatedOptions: {
+		maxHeight: true,
+		maxWidth: true,
+		minHeight: true,
+		minWidth: true
+	},
+
+	_create: function() {
+		this.originalCss = {
+			display: this.element[ 0 ].style.display,
+			width: this.element[ 0 ].style.width,
+			minHeight: this.element[ 0 ].style.minHeight,
+			maxHeight: this.element[ 0 ].style.maxHeight,
+			height: this.element[ 0 ].style.height
+		};
+		this.originalPosition = {
+			parent: this.element.parent(),
+			index: this.element.parent().children().index( this.element )
+		};
+		this.originalTitle = this.element.attr( "title" );
+		if ( this.options.title == null && this.originalTitle != null ) {
+			this.options.title = this.originalTitle;
+		}
+
+		// Dialogs can't be disabled
+		if ( this.options.disabled ) {
+			this.options.disabled = false;
+		}
+
+		this._createWrapper();
+
+		this.element
+			.show()
+			.removeAttr( "title" )
+			.appendTo( this.uiDialog );
+
+		this._addClass( "ui-dialog-content", "ui-widget-content" );
+
+		this._createTitlebar();
+		this._createButtonPane();
+
+		if ( this.options.draggable && $.fn.draggable ) {
+			this._makeDraggable();
+		}
+		if ( this.options.resizable && $.fn.resizable ) {
+			this._makeResizable();
+		}
+
+		this._isOpen = false;
+
+		this._trackFocus();
+	},
+
+	_init: function() {
+		if ( this.options.autoOpen ) {
+			this.open();
+		}
+	},
+
+	_appendTo: function() {
+		var element = this.options.appendTo;
+		if ( element && ( element.jquery || element.nodeType ) ) {
+			return $( element );
+		}
+		return this.document.find( element || "body" ).eq( 0 );
+	},
+
+	_destroy: function() {
+		var next,
+			originalPosition = this.originalPosition;
+
+		this._untrackInstance();
+		this._destroyOverlay();
+
+		this.element
+			.removeUniqueId()
+			.css( this.originalCss )
+
+			// Without detaching first, the following becomes really slow
+			.detach();
+
+		this.uiDialog.remove();
+
+		if ( this.originalTitle ) {
+			this.element.attr( "title", this.originalTitle );
+		}
+
+		next = originalPosition.parent.children().eq( originalPosition.index );
+
+		// Don't try to place the dialog next to itself (#8613)
+		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
+			next.before( this.element );
+		} else {
+			originalPosition.parent.append( this.element );
+		}
+	},
+
+	widget: function() {
+		return this.uiDialog;
+	},
+
+	disable: $.noop,
+	enable: $.noop,
+
+	close: function( event ) {
+		var that = this;
+
+		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
+			return;
+		}
+
+		this._isOpen = false;
+		this._focusedElement = null;
+		this._destroyOverlay();
+		this._untrackInstance();
+
+		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
+
+			// Hiding a focused element doesn't trigger blur in WebKit
+			// so in case we have nothing to focus on, explicitly blur the active element
+			// https://bugs.webkit.org/show_bug.cgi?id=47182
+			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
+		}
+
+		this._hide( this.uiDialog, this.options.hide, function() {
+			that._trigger( "close", event );
+		} );
+	},
+
+	isOpen: function() {
+		return this._isOpen;
+	},
+
+	moveToTop: function() {
+		this._moveToTop();
+	},
+
+	_moveToTop: function( event, silent ) {
+		var moved = false,
+			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
+				return +$( this ).css( "z-index" );
+			} ).get(),
+			zIndexMax = Math.max.apply( null, zIndices );
+
+		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
+			this.uiDialog.css( "z-index", zIndexMax + 1 );
+			moved = true;
+		}
+
+		if ( moved && !silent ) {
+			this._trigger( "focus", event );
+		}
+		return moved;
+	},
+
+	open: function() {
+		var that = this;
+		if ( this._isOpen ) {
+			if ( this._moveToTop() ) {
+				this._focusTabbable();
+			}
+			return;
+		}
+
+		this._isOpen = true;
+		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
+
+		this._size();
+		this._position();
+		this._createOverlay();
+		this._moveToTop( null, true );
+
+		// Ensure the overlay is moved to the top with the dialog, but only when
+		// opening. The overlay shouldn't move after the dialog is open so that
+		// modeless dialogs opened after the modal dialog stack properly.
+		if ( this.overlay ) {
+			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
+		}
+
+		this._show( this.uiDialog, this.options.show, function() {
+			that._focusTabbable();
+			that._trigger( "focus" );
+		} );
+
+		// Track the dialog immediately upon openening in case a focus event
+		// somehow occurs outside of the dialog before an element inside the
+		// dialog is focused (#10152)
+		this._makeFocusTarget();
+
+		this._trigger( "open" );
+	},
+
+	_focusTabbable: function() {
+
+		// Set focus to the first match:
+		// 1. An element that was focused previously
+		// 2. First element inside the dialog matching [autofocus]
+		// 3. Tabbable element inside the content element
+		// 4. Tabbable element inside the buttonpane
+		// 5. The close button
+		// 6. The dialog itself
+		var hasFocus = this._focusedElement;
+		if ( !hasFocus ) {
+			hasFocus = this.element.find( "[autofocus]" );
+		}
+		if ( !hasFocus.length ) {
+			hasFocus = this.element.find( ":tabbable" );
+		}
+		if ( !hasFocus.length ) {
+			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
+		}
+		if ( !hasFocus.length ) {
+			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
+		}
+		if ( !hasFocus.length ) {
+			hasFocus = this.uiDialog;
+		}
+		hasFocus.eq( 0 ).trigger( "focus" );
+	},
+
+	_keepFocus: function( event ) {
+		function checkFocus() {
+			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
+				isActive = this.uiDialog[ 0 ] === activeElement ||
+					$.contains( this.uiDialog[ 0 ], activeElement );
+			if ( !isActive ) {
+				this._focusTabbable();
+			}
+		}
+		event.preventDefault();
+		checkFocus.call( this );
+
+		// support: IE
+		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
+		// so we check again later
+		this._delay( checkFocus );
+	},
+
+	_createWrapper: function() {
+		this.uiDialog = $( "<div>" )
+			.hide()
+			.attr( {
+
+				// Setting tabIndex makes the div focusable
+				tabIndex: -1,
+				role: "dialog"
+			} )
+			.appendTo( this._appendTo() );
+
+		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
+		this._on( this.uiDialog, {
+			keydown: function( event ) {
+				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+						event.keyCode === $.ui.keyCode.ESCAPE ) {
+					event.preventDefault();
+					this.close( event );
+					return;
+				}
+
+				// Prevent tabbing out of dialogs
+				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
+					return;
+				}
+				var tabbables = this.uiDialog.find( ":tabbable" ),
+					first = tabbables.filter( ":first" ),
+					last = tabbables.filter( ":last" );
+
+				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
+						!event.shiftKey ) {
+					this._delay( function() {
+						first.trigger( "focus" );
+					} );
+					event.preventDefault();
+				} else if ( ( event.target === first[ 0 ] ||
+						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
+					this._delay( function() {
+						last.trigger( "focus" );
+					} );
+					event.preventDefault();
+				}
+			},
+			mousedown: function( event ) {
+				if ( this._moveToTop( event ) ) {
+					this._focusTabbable();
+				}
+			}
+		} );
+
+		// We assume that any existing aria-describedby attribute means
+		// that the dialog content is marked up properly
+		// otherwise we brute force the content as the description
+		if ( !this.element.find( "[aria-describedby]" ).length ) {
+			this.uiDialog.attr( {
+				"aria-describedby": this.element.uniqueId().attr( "id" )
+			} );
+		}
+	},
+
+	_createTitlebar: function() {
+		var uiDialogTitle;
+
+		this.uiDialogTitlebar = $( "<div>" );
+		this._addClass( this.uiDialogTitlebar,
+			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
+		this._on( this.uiDialogTitlebar, {
+			mousedown: function( event ) {
+
+				// Don't prevent click on close button (#8838)
+				// Focusing a dialog that is partially scrolled out of view
+				// causes the browser to scroll it into view, preventing the click event
+				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
+
+					// Dialog isn't getting focus when dragging (#8063)
+					this.uiDialog.trigger( "focus" );
+				}
+			}
+		} );
+
+		// Support: IE
+		// Use type="button" to prevent enter keypresses in textboxes from closing the
+		// dialog in IE (#9312)
+		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
+			.button( {
+				label: $( "<a>" ).text( this.options.closeText ).html(),
+				icon: "ui-icon-closethick",
+				showLabel: false
+			} )
+			.appendTo( this.uiDialogTitlebar );
+
+		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
+		this._on( this.uiDialogTitlebarClose, {
+			click: function( event ) {
+				event.preventDefault();
+				this.close( event );
+			}
+		} );
+
+		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
+		this._addClass( uiDialogTitle, "ui-dialog-title" );
+		this._title( uiDialogTitle );
+
+		this.uiDialogTitlebar.prependTo( this.uiDialog );
+
+		this.uiDialog.attr( {
+			"aria-labelledby": uiDialogTitle.attr( "id" )
+		} );
+	},
+
+	_title: function( title ) {
+		if ( this.options.title ) {
+			title.text( this.options.title );
+		} else {
+			title.html( "&#160;" );
+		}
+	},
+
+	_createButtonPane: function() {
+		this.uiDialogButtonPane = $( "<div>" );
+		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
+			"ui-widget-content ui-helper-clearfix" );
+
+		this.uiButtonSet = $( "<div>" )
+			.appendTo( this.uiDialogButtonPane );
+		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
+
+		this._createButtons();
+	},
+
+	_createButtons: function() {
+		var that = this,
+			buttons = this.options.buttons;
+
+		// If we already have a button pane, remove it
+		this.uiDialogButtonPane.remove();
+		this.uiButtonSet.empty();
+
+		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
+			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
+			return;
+		}
+
+		$.each( buttons, function( name, props ) {
+			var click, buttonOptions;
+			props = $.isFunction( props ) ?
+				{ click: props, text: name } :
+				props;
+
+			// Default to a non-submitting button
+			props = $.extend( { type: "button" }, props );
+
+			// Change the context for the click callback to be the main element
+			click = props.click;
+			buttonOptions = {
+				icon: props.icon,
+				iconPosition: props.iconPosition,
+				showLabel: props.showLabel,
+
+				// Deprecated options
+				icons: props.icons,
+				text: props.text
+			};
+
+			delete props.click;
+			delete props.icon;
+			delete props.iconPosition;
+			delete props.showLabel;
+
+			// Deprecated options
+			delete props.icons;
+			if ( typeof props.text === "boolean" ) {
+				delete props.text;
+			}
+
+			$( "<button></button>", props )
+				.button( buttonOptions )
+				.appendTo( that.uiButtonSet )
+				.on( "click", function() {
+					click.apply( that.element[ 0 ], arguments );
+				} );
+		} );
+		this._addClass( this.uiDialog, "ui-dialog-buttons" );
+		this.uiDialogButtonPane.appendTo( this.uiDialog );
+	},
+
+	_makeDraggable: function() {
+		var that = this,
+			options = this.options;
+
+		function filteredUi( ui ) {
+			return {
+				position: ui.position,
+				offset: ui.offset
+			};
+		}
+
+		this.uiDialog.draggable( {
+			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
+			handle: ".ui-dialog-titlebar",
+			containment: "document",
+			start: function( event, ui ) {
+				that._addClass( $( this ), "ui-dialog-dragging" );
+				that._blockFrames();
+				that._trigger( "dragStart", event, filteredUi( ui ) );
+			},
+			drag: function( event, ui ) {
+				that._trigger( "drag", event, filteredUi( ui ) );
+			},
+			stop: function( event, ui ) {
+				var left = ui.offset.left - that.document.scrollLeft(),
+					top = ui.offset.top - that.document.scrollTop();
+
+				options.position = {
+					my: "left top",
+					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
+						"top" + ( top >= 0 ? "+" : "" ) + top,
+					of: that.window
+				};
+				that._removeClass( $( this ), "ui-dialog-dragging" );
+				that._unblockFrames();
+				that._trigger( "dragStop", event, filteredUi( ui ) );
+			}
+		} );
+	},
+
+	_makeResizable: function() {
+		var that = this,
+			options = this.options,
+			handles = options.resizable,
+
+			// .ui-resizable has position: relative defined in the stylesheet
+			// but dialogs have to use absolute or fixed positioning
+			position = this.uiDialog.css( "position" ),
+			resizeHandles = typeof handles === "string" ?
+				handles :
+				"n,e,s,w,se,sw,ne,nw";
+
+		function filteredUi( ui ) {
+			return {
+				originalPosition: ui.originalPosition,
+				originalSize: ui.originalSize,
+				position: ui.position,
+				size: ui.size
+			};
+		}
+
+		this.uiDialog.resizable( {
+			cancel: ".ui-dialog-content",
+			containment: "document",
+			alsoResize: this.element,
+			maxWidth: options.maxWidth,
+			maxHeight: options.maxHeight,
+			minWidth: options.minWidth,
+			minHeight: this._minHeight(),
+			handles: resizeHandles,
+			start: function( event, ui ) {
+				that._addClass( $( this ), "ui-dialog-resizing" );
+				that._blockFrames();
+				that._trigger( "resizeStart", event, filteredUi( ui ) );
+			},
+			resize: function( event, ui ) {
+				that._trigger( "resize", event, filteredUi( ui ) );
+			},
+			stop: function( event, ui ) {
+				var offset = that.uiDialog.offset(),
+					left = offset.left - that.document.scrollLeft(),
+					top = offset.top - that.document.scrollTop();
+
+				options.height = that.uiDialog.height();
+				options.width = that.uiDialog.width();
+				options.position = {
+					my: "left top",
+					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
+						"top" + ( top >= 0 ? "+" : "" ) + top,
+					of: that.window
+				};
+				that._removeClass( $( this ), "ui-dialog-resizing" );
+				that._unblockFrames();
+				that._trigger( "resizeStop", event, filteredUi( ui ) );
+			}
+		} )
+			.css( "position", position );
+	},
+
+	_trackFocus: function() {
+		this._on( this.widget(), {
+			focusin: function( event ) {
+				this._makeFocusTarget();
+				this._focusedElement = $( event.target );
+			}
+		} );
+	},
+
+	_makeFocusTarget: function() {
+		this._untrackInstance();
+		this._trackingInstances().unshift( this );
+	},
+
+	_untrackInstance: function() {
+		var instances = this._trackingInstances(),
+			exists = $.inArray( this, instances );
+		if ( exists !== -1 ) {
+			instances.splice( exists, 1 );
+		}
+	},
+
+	_trackingInstances: function() {
+		var instances = this.document.data( "ui-dialog-instances" );
+		if ( !instances ) {
+			instances = [];
+			this.document.data( "ui-dialog-instances", instances );
+		}
+		return instances;
+	},
+
+	_minHeight: function() {
+		var options = this.options;
+
+		return options.height === "auto" ?
+			options.minHeight :
+			Math.min( options.minHeight, options.height );
+	},
+
+	_position: function() {
+
+		// Need to show the dialog to get the actual offset in the position plugin
+		var isVisible = this.uiDialog.is( ":visible" );
+		if ( !isVisible ) {
+			this.uiDialog.show();
+		}
+		this.uiDialog.position( this.options.position );
+		if ( !isVisible ) {
+			this.uiDialog.hide();
+		}
+	},
+
+	_setOptions: function( options ) {
+		var that = this,
+			resize = false,
+			resizableOptions = {};
+
+		$.each( options, function( key, value ) {
+			that._setOption( key, value );
+
+			if ( key in that.sizeRelatedOptions ) {
+				resize = true;
+			}
+			if ( key in that.resizableRelatedOptions ) {
+				resizableOptions[ key ] = value;
+			}
+		} );
+
+		if ( resize ) {
+			this._size();
+			this._position();
+		}
+		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+			this.uiDialog.resizable( "option", resizableOptions );
+		}
+	},
+
+	_setOption: function( key, value ) {
+		var isDraggable, isResizable,
+			uiDialog = this.uiDialog;
+
+		if ( key === "disabled" ) {
+			return;
+		}
+
+		this._super( key, value );
+
+		if ( key === "appendTo" ) {
+			this.uiDialog.appendTo( this._appendTo() );
+		}
+
+		if ( key === "buttons" ) {
+			this._createButtons();
+		}
+
+		if ( key === "closeText" ) {
+			this.uiDialogTitlebarClose.button( {
+
+				// Ensure that we always pass a string
+				label: $( "<a>" ).text( "" + this.options.closeText ).html()
+			} );
+		}
+
+		if ( key === "draggable" ) {
+			isDraggable = uiDialog.is( ":data(ui-draggable)" );
+			if ( isDraggable && !value ) {
+				uiDialog.draggable( "destroy" );
+			}
+
+			if ( !isDraggable && value ) {
+				this._makeDraggable();
+			}
+		}
+
+		if ( key === "position" ) {
+			this._position();
+		}
+
+		if ( key === "resizable" ) {
+
+			// currently resizable, becoming non-resizable
+			isResizable = uiDialog.is( ":data(ui-resizable)" );
+			if ( isResizable && !value ) {
+				uiDialog.resizable( "destroy" );
+			}
+
+			// Currently resizable, changing handles
+			if ( isResizable && typeof value === "string" ) {
+				uiDialog.resizable( "option", "handles", value );
+			}
+
+			// Currently non-resizable, becoming resizable
+			if ( !isResizable && value !== false ) {
+				this._makeResizable();
+			}
+		}
+
+		if ( key === "title" ) {
+			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
+		}
+	},
+
+	_size: function() {
+
+		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+		// divs will both have width and height set, so we need to reset them
+		var nonContentHeight, minContentHeight, maxContentHeight,
+			options = this.options;
+
+		// Reset content sizing
+		this.element.show().css( {
+			width: "auto",
+			minHeight: 0,
+			maxHeight: "none",
+			height: 0
+		} );
+
+		if ( options.minWidth > options.width ) {
+			options.width = options.minWidth;
+		}
+
+		// Reset wrapper sizing
+		// determine the height of all the non-content elements
+		nonContentHeight = this.uiDialog.css( {
+			height: "auto",
+			width: options.width
+		} )
+			.outerHeight();
+		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+		maxContentHeight = typeof options.maxHeight === "number" ?
+			Math.max( 0, options.maxHeight - nonContentHeight ) :
+			"none";
+
+		if ( options.height === "auto" ) {
+			this.element.css( {
+				minHeight: minContentHeight,
+				maxHeight: maxContentHeight,
+				height: "auto"
+			} );
+		} else {
+			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
+		}
+
+		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
+			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
+		}
+	},
+
+	_blockFrames: function() {
+		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
+			var iframe = $( this );
+
+			return $( "<div>" )
+				.css( {
+					position: "absolute",
+					width: iframe.outerWidth(),
+					height: iframe.outerHeight()
+				} )
+				.appendTo( iframe.parent() )
+				.offset( iframe.offset() )[ 0 ];
+		} );
+	},
+
+	_unblockFrames: function() {
+		if ( this.iframeBlocks ) {
+			this.iframeBlocks.remove();
+			delete this.iframeBlocks;
+		}
+	},
+
+	_allowInteraction: function( event ) {
+		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
+			return true;
+		}
+
+		// TODO: Remove hack when datepicker implements
+		// the .ui-front logic (#8989)
+		return !!$( event.target ).closest( ".ui-datepicker" ).length;
+	},
+
+	_createOverlay: function() {
+		if ( !this.options.modal ) {
+			return;
+		}
+
+		// We use a delay in case the overlay is created from an
+		// event that we're going to be cancelling (#2804)
+		var isOpening = true;
+		this._delay( function() {
+			isOpening = false;
+		} );
+
+		if ( !this.document.data( "ui-dialog-overlays" ) ) {
+
+			// Prevent use of anchors and inputs
+			// Using _on() for an event handler shared across many instances is
+			// safe because the dialogs stack and must be closed in reverse order
+			this._on( this.document, {
+				focusin: function( event ) {
+					if ( isOpening ) {
+						return;
+					}
+
+					if ( !this._allowInteraction( event ) ) {
+						event.preventDefault();
+						this._trackingInstances()[ 0 ]._focusTabbable();
+					}
+				}
+			} );
+		}
+
+		this.overlay = $( "<div>" )
+			.appendTo( this._appendTo() );
+
+		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
+		this._on( this.overlay, {
+			mousedown: "_keepFocus"
+		} );
+		this.document.data( "ui-dialog-overlays",
+			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
+	},
+
+	_destroyOverlay: function() {
+		if ( !this.options.modal ) {
+			return;
+		}
+
+		if ( this.overlay ) {
+			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
+
+			if ( !overlays ) {
+				this._off( this.document, "focusin" );
+				this.document.removeData( "ui-dialog-overlays" );
+			} else {
+				this.document.data( "ui-dialog-overlays", overlays );
+			}
+
+			this.overlay.remove();
+			this.overlay = null;
+		}
+	}
+} );
+
+// DEPRECATED
+// TODO: switch return back to widget declaration at top of file when this is removed
+if ( $.uiBackCompat !== false ) {
+
+	// Backcompat for dialogClass option
+	$.widget( "ui.dialog", $.ui.dialog, {
+		options: {
+			dialogClass: ""
+		},
+		_createWrapper: function() {
+			this._super();
+			this.uiDialog.addClass( this.options.dialogClass );
+		},
+		_setOption: function( key, value ) {
+			if ( key === "dialogClass" ) {
+				this.uiDialog
+					.removeClass( this.options.dialogClass )
+					.addClass( value );
+			}
+			this._superApply( arguments );
+		}
+	} );
+}
+
+var widgetsDialog = $.ui.dialog;
+
+
+/*!
+ * jQuery UI Droppable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Bounce
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(e){e.effects.bounce=function(b){return this.queue(function(){var a=e(this),l=["position","top","bottom","left","right"],h=e.effects.setMode(a,b.options.mode||"effect"),d=b.options.direction||"up",c=b.options.distance||20,m=b.options.times||5,i=b.duration||250;/show|hide/.test(h)&&l.push("opacity");e.effects.save(a,l);a.show();e.effects.createWrapper(a);var f=d=="up"||d=="down"?"top":"left";d=d=="up"||d=="left"?"pos":"neg";c=b.options.distance||(f=="top"?a.outerHeight({margin:true})/3:a.outerWidth({margin:true})/
-3);if(h=="show")a.css("opacity",0).css(f,d=="pos"?-c:c);if(h=="hide")c/=m*2;h!="hide"&&m--;if(h=="show"){var g={opacity:1};g[f]=(d=="pos"?"+=":"-=")+c;a.animate(g,i/2,b.options.easing);c/=2;m--}for(g=0;g<m;g++){var j={},k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing);c=h=="hide"?c*2:c/2}if(h=="hide"){g={opacity:0};g[f]=(d=="pos"?"-=":"+=")+c;a.animate(g,i/2,b.options.easing,function(){a.hide();e.effects.restore(a,l);e.effects.removeWrapper(a);
-b.callback&&b.callback.apply(this,arguments)})}else{j={};k={};j[f]=(d=="pos"?"-=":"+=")+c;k[f]=(d=="pos"?"+=":"-=")+c;a.animate(j,i/2,b.options.easing).animate(k,i/2,b.options.easing,function(){e.effects.restore(a,l);e.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments)})}a.queue("fx",function(){a.dequeue()});a.dequeue()})}})(jQuery);
-;/*
- * jQuery UI Effects Clip 1.8.14
+
+//>>label: Droppable
+//>>group: Interactions
+//>>description: Enables drop targets for draggable elements.
+//>>docs: http://api.jqueryui.com/droppable/
+//>>demos: http://jqueryui.com/droppable/
+
+
+
+$.widget( "ui.droppable", {
+	version: "1.12.1",
+	widgetEventPrefix: "drop",
+	options: {
+		accept: "*",
+		addClasses: true,
+		greedy: false,
+		scope: "default",
+		tolerance: "intersect",
+
+		// Callbacks
+		activate: null,
+		deactivate: null,
+		drop: null,
+		out: null,
+		over: null
+	},
+	_create: function() {
+
+		var proportions,
+			o = this.options,
+			accept = o.accept;
+
+		this.isover = false;
+		this.isout = true;
+
+		this.accept = $.isFunction( accept ) ? accept : function( d ) {
+			return d.is( accept );
+		};
+
+		this.proportions = function( /* valueToWrite */ ) {
+			if ( arguments.length ) {
+
+				// Store the droppable's proportions
+				proportions = arguments[ 0 ];
+			} else {
+
+				// Retrieve or derive the droppable's proportions
+				return proportions ?
+					proportions :
+					proportions = {
+						width: this.element[ 0 ].offsetWidth,
+						height: this.element[ 0 ].offsetHeight
+					};
+			}
+		};
+
+		this._addToManager( o.scope );
+
+		o.addClasses && this._addClass( "ui-droppable" );
+
+	},
+
+	_addToManager: function( scope ) {
+
+		// Add the reference and positions to the manager
+		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
+		$.ui.ddmanager.droppables[ scope ].push( this );
+	},
+
+	_splice: function( drop ) {
+		var i = 0;
+		for ( ; i < drop.length; i++ ) {
+			if ( drop[ i ] === this ) {
+				drop.splice( i, 1 );
+			}
+		}
+	},
+
+	_destroy: function() {
+		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+		this._splice( drop );
+	},
+
+	_setOption: function( key, value ) {
+
+		if ( key === "accept" ) {
+			this.accept = $.isFunction( value ) ? value : function( d ) {
+				return d.is( value );
+			};
+		} else if ( key === "scope" ) {
+			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
+
+			this._splice( drop );
+			this._addToManager( value );
+		}
+
+		this._super( key, value );
+	},
+
+	_activate: function( event ) {
+		var draggable = $.ui.ddmanager.current;
+
+		this._addActiveClass();
+		if ( draggable ) {
+			this._trigger( "activate", event, this.ui( draggable ) );
+		}
+	},
+
+	_deactivate: function( event ) {
+		var draggable = $.ui.ddmanager.current;
+
+		this._removeActiveClass();
+		if ( draggable ) {
+			this._trigger( "deactivate", event, this.ui( draggable ) );
+		}
+	},
+
+	_over: function( event ) {
+
+		var draggable = $.ui.ddmanager.current;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem ||
+				draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return;
+		}
+
+		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
+				draggable.element ) ) ) {
+			this._addHoverClass();
+			this._trigger( "over", event, this.ui( draggable ) );
+		}
+
+	},
+
+	_out: function( event ) {
+
+		var draggable = $.ui.ddmanager.current;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem ||
+				draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return;
+		}
+
+		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
+				draggable.element ) ) ) {
+			this._removeHoverClass();
+			this._trigger( "out", event, this.ui( draggable ) );
+		}
+
+	},
+
+	_drop: function( event, custom ) {
+
+		var draggable = custom || $.ui.ddmanager.current,
+			childrenIntersection = false;
+
+		// Bail if draggable and droppable are same element
+		if ( !draggable || ( draggable.currentItem ||
+				draggable.element )[ 0 ] === this.element[ 0 ] ) {
+			return false;
+		}
+
+		this.element
+			.find( ":data(ui-droppable)" )
+			.not( ".ui-draggable-dragging" )
+			.each( function() {
+				var inst = $( this ).droppable( "instance" );
+				if (
+					inst.options.greedy &&
+					!inst.options.disabled &&
+					inst.options.scope === draggable.options.scope &&
+					inst.accept.call(
+						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
+					) &&
+					intersect(
+						draggable,
+						$.extend( inst, { offset: inst.element.offset() } ),
+						inst.options.tolerance, event
+					)
+				) {
+					childrenIntersection = true;
+					return false; }
+			} );
+		if ( childrenIntersection ) {
+			return false;
+		}
+
+		if ( this.accept.call( this.element[ 0 ],
+				( draggable.currentItem || draggable.element ) ) ) {
+			this._removeActiveClass();
+			this._removeHoverClass();
+
+			this._trigger( "drop", event, this.ui( draggable ) );
+			return this.element;
+		}
+
+		return false;
+
+	},
+
+	ui: function( c ) {
+		return {
+			draggable: ( c.currentItem || c.element ),
+			helper: c.helper,
+			position: c.position,
+			offset: c.positionAbs
+		};
+	},
+
+	// Extension points just to make backcompat sane and avoid duplicating logic
+	// TODO: Remove in 1.13 along with call to it below
+	_addHoverClass: function() {
+		this._addClass( "ui-droppable-hover" );
+	},
+
+	_removeHoverClass: function() {
+		this._removeClass( "ui-droppable-hover" );
+	},
+
+	_addActiveClass: function() {
+		this._addClass( "ui-droppable-active" );
+	},
+
+	_removeActiveClass: function() {
+		this._removeClass( "ui-droppable-active" );
+	}
+} );
+
+var intersect = $.ui.intersect = ( function() {
+	function isOverAxis( x, reference, size ) {
+		return ( x >= reference ) && ( x < ( reference + size ) );
+	}
+
+	return function( draggable, droppable, toleranceMode, event ) {
+
+		if ( !droppable.offset ) {
+			return false;
+		}
+
+		var x1 = ( draggable.positionAbs ||
+				draggable.position.absolute ).left + draggable.margins.left,
+			y1 = ( draggable.positionAbs ||
+				draggable.position.absolute ).top + draggable.margins.top,
+			x2 = x1 + draggable.helperProportions.width,
+			y2 = y1 + draggable.helperProportions.height,
+			l = droppable.offset.left,
+			t = droppable.offset.top,
+			r = l + droppable.proportions().width,
+			b = t + droppable.proportions().height;
+
+		switch ( toleranceMode ) {
+		case "fit":
+			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
+		case "intersect":
+			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
+				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
+				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
+				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
+		case "pointer":
+			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
+				isOverAxis( event.pageX, l, droppable.proportions().width );
+		case "touch":
+			return (
+				( y1 >= t && y1 <= b ) || // Top edge touching
+				( y2 >= t && y2 <= b ) || // Bottom edge touching
+				( y1 < t && y2 > b ) // Surrounded vertically
+			) && (
+				( x1 >= l && x1 <= r ) || // Left edge touching
+				( x2 >= l && x2 <= r ) || // Right edge touching
+				( x1 < l && x2 > r ) // Surrounded horizontally
+			);
+		default:
+			return false;
+		}
+	};
+} )();
+
+/*
+	This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+	current: null,
+	droppables: { "default": [] },
+	prepareOffsets: function( t, event ) {
+
+		var i, j,
+			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
+			type = event ? event.type : null, // workaround for #2317
+			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
+
+		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
+
+			// No disabled and non-accepted
+			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
+					( t.currentItem || t.element ) ) ) ) {
+				continue;
+			}
+
+			// Filter out elements in the current dragged item
+			for ( j = 0; j < list.length; j++ ) {
+				if ( list[ j ] === m[ i ].element[ 0 ] ) {
+					m[ i ].proportions().height = 0;
+					continue droppablesLoop;
+				}
+			}
+
+			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
+			if ( !m[ i ].visible ) {
+				continue;
+			}
+
+			// Activate the droppable if used directly from draggables
+			if ( type === "mousedown" ) {
+				m[ i ]._activate.call( m[ i ], event );
+			}
+
+			m[ i ].offset = m[ i ].element.offset();
+			m[ i ].proportions( {
+				width: m[ i ].element[ 0 ].offsetWidth,
+				height: m[ i ].element[ 0 ].offsetHeight
+			} );
+
+		}
+
+	},
+	drop: function( draggable, event ) {
+
+		var dropped = false;
+
+		// Create a copy of the droppables in case the list changes during the drop (#9116)
+		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
+
+			if ( !this.options ) {
+				return;
+			}
+			if ( !this.options.disabled && this.visible &&
+					intersect( draggable, this, this.options.tolerance, event ) ) {
+				dropped = this._drop.call( this, event ) || dropped;
+			}
+
+			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
+					( draggable.currentItem || draggable.element ) ) ) {
+				this.isout = true;
+				this.isover = false;
+				this._deactivate.call( this, event );
+			}
+
+		} );
+		return dropped;
+
+	},
+	dragStart: function( draggable, event ) {
+
+		// Listen for scrolling so that if the dragging causes scrolling the position of the
+		// droppables can be recalculated (see #5003)
+		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
+			if ( !draggable.options.refreshPositions ) {
+				$.ui.ddmanager.prepareOffsets( draggable, event );
+			}
+		} );
+	},
+	drag: function( draggable, event ) {
+
+		// If you have a highly dynamic page, you might try this option. It renders positions
+		// every time you move the mouse.
+		if ( draggable.options.refreshPositions ) {
+			$.ui.ddmanager.prepareOffsets( draggable, event );
+		}
+
+		// Run through all droppables and check their positions based on specific tolerance options
+		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
+
+			if ( this.options.disabled || this.greedyChild || !this.visible ) {
+				return;
+			}
+
+			var parentInstance, scope, parent,
+				intersects = intersect( draggable, this, this.options.tolerance, event ),
+				c = !intersects && this.isover ?
+					"isout" :
+					( intersects && !this.isover ? "isover" : null );
+			if ( !c ) {
+				return;
+			}
+
+			if ( this.options.greedy ) {
+
+				// find droppable parents with same scope
+				scope = this.options.scope;
+				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
+					return $( this ).droppable( "instance" ).options.scope === scope;
+				} );
+
+				if ( parent.length ) {
+					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
+					parentInstance.greedyChild = ( c === "isover" );
+				}
+			}
+
+			// We just moved into a greedy child
+			if ( parentInstance && c === "isover" ) {
+				parentInstance.isover = false;
+				parentInstance.isout = true;
+				parentInstance._out.call( parentInstance, event );
+			}
+
+			this[ c ] = true;
+			this[ c === "isout" ? "isover" : "isout" ] = false;
+			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
+
+			// We just moved out of a greedy child
+			if ( parentInstance && c === "isout" ) {
+				parentInstance.isout = false;
+				parentInstance.isover = true;
+				parentInstance._over.call( parentInstance, event );
+			}
+		} );
+
+	},
+	dragStop: function( draggable, event ) {
+		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
+
+		// Call prepareOffsets one final time since IE does not fire return scroll events when
+		// overflow was caused by drag (see #5003)
+		if ( !draggable.options.refreshPositions ) {
+			$.ui.ddmanager.prepareOffsets( draggable, event );
+		}
+	}
+};
+
+// DEPRECATED
+// TODO: switch return back to widget declaration at top of file when this is removed
+if ( $.uiBackCompat !== false ) {
+
+	// Backcompat for activeClass and hoverClass options
+	$.widget( "ui.droppable", $.ui.droppable, {
+		options: {
+			hoverClass: false,
+			activeClass: false
+		},
+		_addActiveClass: function() {
+			this._super();
+			if ( this.options.activeClass ) {
+				this.element.addClass( this.options.activeClass );
+			}
+		},
+		_removeActiveClass: function() {
+			this._super();
+			if ( this.options.activeClass ) {
+				this.element.removeClass( this.options.activeClass );
+			}
+		},
+		_addHoverClass: function() {
+			this._super();
+			if ( this.options.hoverClass ) {
+				this.element.addClass( this.options.hoverClass );
+			}
+		},
+		_removeHoverClass: function() {
+			this._super();
+			if ( this.options.hoverClass ) {
+				this.element.removeClass( this.options.hoverClass );
+			}
+		}
+	} );
+}
+
+var widgetsDroppable = $.ui.droppable;
+
+
+/*!
+ * jQuery UI Progressbar 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Clip
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(b){b.effects.clip=function(e){return this.queue(function(){var a=b(this),i=["position","top","bottom","left","right","height","width"],f=b.effects.setMode(a,e.options.mode||"hide"),c=e.options.direction||"vertical";b.effects.save(a,i);a.show();var d=b.effects.createWrapper(a).css({overflow:"hidden"});d=a[0].tagName=="IMG"?d:a;var g={size:c=="vertical"?"height":"width",position:c=="vertical"?"top":"left"};c=c=="vertical"?d.height():d.width();if(f=="show"){d.css(g.size,0);d.css(g.position,
-c/2)}var h={};h[g.size]=f=="show"?c:0;h[g.position]=f=="show"?0:c/2;d.animate(h,{queue:false,duration:e.duration,easing:e.options.easing,complete:function(){f=="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);e.callback&&e.callback.apply(a[0],arguments);a.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Drop 1.8.14
+
+//>>label: Progressbar
+//>>group: Widgets
+// jscs:disable maximumLineLength
+//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/progressbar/
+//>>demos: http://jqueryui.com/progressbar/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/progressbar.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsProgressbar = $.widget( "ui.progressbar", {
+	version: "1.12.1",
+	options: {
+		classes: {
+			"ui-progressbar": "ui-corner-all",
+			"ui-progressbar-value": "ui-corner-left",
+			"ui-progressbar-complete": "ui-corner-right"
+		},
+		max: 100,
+		value: 0,
+
+		change: null,
+		complete: null
+	},
+
+	min: 0,
+
+	_create: function() {
+
+		// Constrain initial value
+		this.oldValue = this.options.value = this._constrainedValue();
+
+		this.element.attr( {
+
+			// Only set static values; aria-valuenow and aria-valuemax are
+			// set inside _refreshValue()
+			role: "progressbar",
+			"aria-valuemin": this.min
+		} );
+		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
+
+		this.valueDiv = $( "<div>" ).appendTo( this.element );
+		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
+		this._refreshValue();
+	},
+
+	_destroy: function() {
+		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
+
+		this.valueDiv.remove();
+	},
+
+	value: function( newValue ) {
+		if ( newValue === undefined ) {
+			return this.options.value;
+		}
+
+		this.options.value = this._constrainedValue( newValue );
+		this._refreshValue();
+	},
+
+	_constrainedValue: function( newValue ) {
+		if ( newValue === undefined ) {
+			newValue = this.options.value;
+		}
+
+		this.indeterminate = newValue === false;
+
+		// Sanitize value
+		if ( typeof newValue !== "number" ) {
+			newValue = 0;
+		}
+
+		return this.indeterminate ? false :
+			Math.min( this.options.max, Math.max( this.min, newValue ) );
+	},
+
+	_setOptions: function( options ) {
+
+		// Ensure "value" option is set after other values (like max)
+		var value = options.value;
+		delete options.value;
+
+		this._super( options );
+
+		this.options.value = this._constrainedValue( value );
+		this._refreshValue();
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "max" ) {
+
+			// Don't allow a max less than min
+			value = Math.max( this.min, value );
+		}
+		this._super( key, value );
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this.element.attr( "aria-disabled", value );
+		this._toggleClass( null, "ui-state-disabled", !!value );
+	},
+
+	_percentage: function() {
+		return this.indeterminate ?
+			100 :
+			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
+	},
+
+	_refreshValue: function() {
+		var value = this.options.value,
+			percentage = this._percentage();
+
+		this.valueDiv
+			.toggle( this.indeterminate || value > this.min )
+			.width( percentage.toFixed( 0 ) + "%" );
+
+		this
+			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
+				value === this.options.max )
+			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
+
+		if ( this.indeterminate ) {
+			this.element.removeAttr( "aria-valuenow" );
+			if ( !this.overlayDiv ) {
+				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
+				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
+			}
+		} else {
+			this.element.attr( {
+				"aria-valuemax": this.options.max,
+				"aria-valuenow": value
+			} );
+			if ( this.overlayDiv ) {
+				this.overlayDiv.remove();
+				this.overlayDiv = null;
+			}
+		}
+
+		if ( this.oldValue !== value ) {
+			this.oldValue = value;
+			this._trigger( "change" );
+		}
+		if ( value === this.options.max ) {
+			this._trigger( "complete" );
+		}
+	}
+} );
+
+
+/*!
+ * jQuery UI Selectable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Drop
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(c){c.effects.drop=function(d){return this.queue(function(){var a=c(this),h=["position","top","bottom","left","right","opacity"],e=c.effects.setMode(a,d.options.mode||"hide"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a);var f=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var g=d.options.distance||(f=="top"?a.outerHeight({margin:true})/2:a.outerWidth({margin:true})/2);if(e=="show")a.css("opacity",0).css(f,b=="pos"?-g:g);var i={opacity:e==
-"show"?1:0};i[f]=(e=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+g;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){e=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Explode 1.8.14
+
+//>>label: Selectable
+//>>group: Interactions
+//>>description: Allows groups of elements to be selected with the mouse.
+//>>docs: http://api.jqueryui.com/selectable/
+//>>demos: http://jqueryui.com/selectable/
+//>>css.structure: ../../themes/base/selectable.css
+
+
+
+var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
+	version: "1.12.1",
+	options: {
+		appendTo: "body",
+		autoRefresh: true,
+		distance: 0,
+		filter: "*",
+		tolerance: "touch",
+
+		// Callbacks
+		selected: null,
+		selecting: null,
+		start: null,
+		stop: null,
+		unselected: null,
+		unselecting: null
+	},
+	_create: function() {
+		var that = this;
+
+		this._addClass( "ui-selectable" );
+
+		this.dragged = false;
+
+		// Cache selectee children based on filter
+		this.refresh = function() {
+			that.elementPos = $( that.element[ 0 ] ).offset();
+			that.selectees = $( that.options.filter, that.element[ 0 ] );
+			that._addClass( that.selectees, "ui-selectee" );
+			that.selectees.each( function() {
+				var $this = $( this ),
+					selecteeOffset = $this.offset(),
+					pos = {
+						left: selecteeOffset.left - that.elementPos.left,
+						top: selecteeOffset.top - that.elementPos.top
+					};
+				$.data( this, "selectable-item", {
+					element: this,
+					$element: $this,
+					left: pos.left,
+					top: pos.top,
+					right: pos.left + $this.outerWidth(),
+					bottom: pos.top + $this.outerHeight(),
+					startselected: false,
+					selected: $this.hasClass( "ui-selected" ),
+					selecting: $this.hasClass( "ui-selecting" ),
+					unselecting: $this.hasClass( "ui-unselecting" )
+				} );
+			} );
+		};
+		this.refresh();
+
+		this._mouseInit();
+
+		this.helper = $( "<div>" );
+		this._addClass( this.helper, "ui-selectable-helper" );
+	},
+
+	_destroy: function() {
+		this.selectees.removeData( "selectable-item" );
+		this._mouseDestroy();
+	},
+
+	_mouseStart: function( event ) {
+		var that = this,
+			options = this.options;
+
+		this.opos = [ event.pageX, event.pageY ];
+		this.elementPos = $( this.element[ 0 ] ).offset();
+
+		if ( this.options.disabled ) {
+			return;
+		}
+
+		this.selectees = $( options.filter, this.element[ 0 ] );
+
+		this._trigger( "start", event );
+
+		$( options.appendTo ).append( this.helper );
+
+		// position helper (lasso)
+		this.helper.css( {
+			"left": event.pageX,
+			"top": event.pageY,
+			"width": 0,
+			"height": 0
+		} );
+
+		if ( options.autoRefresh ) {
+			this.refresh();
+		}
+
+		this.selectees.filter( ".ui-selected" ).each( function() {
+			var selectee = $.data( this, "selectable-item" );
+			selectee.startselected = true;
+			if ( !event.metaKey && !event.ctrlKey ) {
+				that._removeClass( selectee.$element, "ui-selected" );
+				selectee.selected = false;
+				that._addClass( selectee.$element, "ui-unselecting" );
+				selectee.unselecting = true;
+
+				// selectable UNSELECTING callback
+				that._trigger( "unselecting", event, {
+					unselecting: selectee.element
+				} );
+			}
+		} );
+
+		$( event.target ).parents().addBack().each( function() {
+			var doSelect,
+				selectee = $.data( this, "selectable-item" );
+			if ( selectee ) {
+				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
+					!selectee.$element.hasClass( "ui-selected" );
+				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
+					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
+				selectee.unselecting = !doSelect;
+				selectee.selecting = doSelect;
+				selectee.selected = doSelect;
+
+				// selectable (UN)SELECTING callback
+				if ( doSelect ) {
+					that._trigger( "selecting", event, {
+						selecting: selectee.element
+					} );
+				} else {
+					that._trigger( "unselecting", event, {
+						unselecting: selectee.element
+					} );
+				}
+				return false;
+			}
+		} );
+
+	},
+
+	_mouseDrag: function( event ) {
+
+		this.dragged = true;
+
+		if ( this.options.disabled ) {
+			return;
+		}
+
+		var tmp,
+			that = this,
+			options = this.options,
+			x1 = this.opos[ 0 ],
+			y1 = this.opos[ 1 ],
+			x2 = event.pageX,
+			y2 = event.pageY;
+
+		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
+		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
+		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
+
+		this.selectees.each( function() {
+			var selectee = $.data( this, "selectable-item" ),
+				hit = false,
+				offset = {};
+
+			//prevent helper from being selected if appendTo: selectable
+			if ( !selectee || selectee.element === that.element[ 0 ] ) {
+				return;
+			}
+
+			offset.left   = selectee.left   + that.elementPos.left;
+			offset.right  = selectee.right  + that.elementPos.left;
+			offset.top    = selectee.top    + that.elementPos.top;
+			offset.bottom = selectee.bottom + that.elementPos.top;
+
+			if ( options.tolerance === "touch" ) {
+				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
+                    offset.bottom < y1 ) );
+			} else if ( options.tolerance === "fit" ) {
+				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
+                    offset.bottom < y2 );
+			}
+
+			if ( hit ) {
+
+				// SELECT
+				if ( selectee.selected ) {
+					that._removeClass( selectee.$element, "ui-selected" );
+					selectee.selected = false;
+				}
+				if ( selectee.unselecting ) {
+					that._removeClass( selectee.$element, "ui-unselecting" );
+					selectee.unselecting = false;
+				}
+				if ( !selectee.selecting ) {
+					that._addClass( selectee.$element, "ui-selecting" );
+					selectee.selecting = true;
+
+					// selectable SELECTING callback
+					that._trigger( "selecting", event, {
+						selecting: selectee.element
+					} );
+				}
+			} else {
+
+				// UNSELECT
+				if ( selectee.selecting ) {
+					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
+						that._removeClass( selectee.$element, "ui-selecting" );
+						selectee.selecting = false;
+						that._addClass( selectee.$element, "ui-selected" );
+						selectee.selected = true;
+					} else {
+						that._removeClass( selectee.$element, "ui-selecting" );
+						selectee.selecting = false;
+						if ( selectee.startselected ) {
+							that._addClass( selectee.$element, "ui-unselecting" );
+							selectee.unselecting = true;
+						}
+
+						// selectable UNSELECTING callback
+						that._trigger( "unselecting", event, {
+							unselecting: selectee.element
+						} );
+					}
+				}
+				if ( selectee.selected ) {
+					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
+						that._removeClass( selectee.$element, "ui-selected" );
+						selectee.selected = false;
+
+						that._addClass( selectee.$element, "ui-unselecting" );
+						selectee.unselecting = true;
+
+						// selectable UNSELECTING callback
+						that._trigger( "unselecting", event, {
+							unselecting: selectee.element
+						} );
+					}
+				}
+			}
+		} );
+
+		return false;
+	},
+
+	_mouseStop: function( event ) {
+		var that = this;
+
+		this.dragged = false;
+
+		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
+			var selectee = $.data( this, "selectable-item" );
+			that._removeClass( selectee.$element, "ui-unselecting" );
+			selectee.unselecting = false;
+			selectee.startselected = false;
+			that._trigger( "unselected", event, {
+				unselected: selectee.element
+			} );
+		} );
+		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
+			var selectee = $.data( this, "selectable-item" );
+			that._removeClass( selectee.$element, "ui-selecting" )
+				._addClass( selectee.$element, "ui-selected" );
+			selectee.selecting = false;
+			selectee.selected = true;
+			selectee.startselected = true;
+			that._trigger( "selected", event, {
+				selected: selectee.element
+			} );
+		} );
+		this._trigger( "stop", event );
+
+		this.helper.remove();
+
+		return false;
+	}
+
+} );
+
+
+/*!
+ * jQuery UI Selectmenu 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Explode
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(j){j.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode=a.options.mode=="toggle"?j(this).is(":visible")?"hide":"show":a.options.mode;var b=j(this).show().css("visibility","hidden"),g=b.offset();g.top-=parseInt(b.css("marginTop"),10)||0;g.left-=parseInt(b.css("marginLeft"),10)||0;for(var h=b.outerWidth(true),i=b.outerHeight(true),e=0;e<c;e++)for(var f=
-0;f<d;f++)b.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+
-e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
-;/*
- * jQuery UI Effects Fade 1.8.14
+
+//>>label: Selectmenu
+//>>group: Widgets
+// jscs:disable maximumLineLength
+//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/selectmenu/
+//>>demos: http://jqueryui.com/selectmenu/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
+	version: "1.12.1",
+	defaultElement: "<select>",
+	options: {
+		appendTo: null,
+		classes: {
+			"ui-selectmenu-button-open": "ui-corner-top",
+			"ui-selectmenu-button-closed": "ui-corner-all"
+		},
+		disabled: null,
+		icons: {
+			button: "ui-icon-triangle-1-s"
+		},
+		position: {
+			my: "left top",
+			at: "left bottom",
+			collision: "none"
+		},
+		width: false,
+
+		// Callbacks
+		change: null,
+		close: null,
+		focus: null,
+		open: null,
+		select: null
+	},
+
+	_create: function() {
+		var selectmenuId = this.element.uniqueId().attr( "id" );
+		this.ids = {
+			element: selectmenuId,
+			button: selectmenuId + "-button",
+			menu: selectmenuId + "-menu"
+		};
+
+		this._drawButton();
+		this._drawMenu();
+		this._bindFormResetHandler();
+
+		this._rendered = false;
+		this.menuItems = $();
+	},
+
+	_drawButton: function() {
+		var icon,
+			that = this,
+			item = this._parseOption(
+				this.element.find( "option:selected" ),
+				this.element[ 0 ].selectedIndex
+			);
+
+		// Associate existing label with the new button
+		this.labels = this.element.labels().attr( "for", this.ids.button );
+		this._on( this.labels, {
+			click: function( event ) {
+				this.button.focus();
+				event.preventDefault();
+			}
+		} );
+
+		// Hide original select element
+		this.element.hide();
+
+		// Create button
+		this.button = $( "<span>", {
+			tabindex: this.options.disabled ? -1 : 0,
+			id: this.ids.button,
+			role: "combobox",
+			"aria-expanded": "false",
+			"aria-autocomplete": "list",
+			"aria-owns": this.ids.menu,
+			"aria-haspopup": "true",
+			title: this.element.attr( "title" )
+		} )
+			.insertAfter( this.element );
+
+		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
+			"ui-button ui-widget" );
+
+		icon = $( "<span>" ).appendTo( this.button );
+		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
+		this.buttonItem = this._renderButtonItem( item )
+			.appendTo( this.button );
+
+		if ( this.options.width !== false ) {
+			this._resizeButton();
+		}
+
+		this._on( this.button, this._buttonEvents );
+		this.button.one( "focusin", function() {
+
+			// Delay rendering the menu items until the button receives focus.
+			// The menu may have already been rendered via a programmatic open.
+			if ( !that._rendered ) {
+				that._refreshMenu();
+			}
+		} );
+	},
+
+	_drawMenu: function() {
+		var that = this;
+
+		// Create menu
+		this.menu = $( "<ul>", {
+			"aria-hidden": "true",
+			"aria-labelledby": this.ids.button,
+			id: this.ids.menu
+		} );
+
+		// Wrap menu
+		this.menuWrap = $( "<div>" ).append( this.menu );
+		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
+		this.menuWrap.appendTo( this._appendTo() );
+
+		// Initialize menu widget
+		this.menuInstance = this.menu
+			.menu( {
+				classes: {
+					"ui-menu": "ui-corner-bottom"
+				},
+				role: "listbox",
+				select: function( event, ui ) {
+					event.preventDefault();
+
+					// Support: IE8
+					// If the item was selected via a click, the text selection
+					// will be destroyed in IE
+					that._setSelection();
+
+					that._select( ui.item.data( "ui-selectmenu-item" ), event );
+				},
+				focus: function( event, ui ) {
+					var item = ui.item.data( "ui-selectmenu-item" );
+
+					// Prevent inital focus from firing and check if its a newly focused item
+					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
+						that._trigger( "focus", event, { item: item } );
+						if ( !that.isOpen ) {
+							that._select( item, event );
+						}
+					}
+					that.focusIndex = item.index;
+
+					that.button.attr( "aria-activedescendant",
+						that.menuItems.eq( item.index ).attr( "id" ) );
+				}
+			} )
+			.menu( "instance" );
+
+		// Don't close the menu on mouseleave
+		this.menuInstance._off( this.menu, "mouseleave" );
+
+		// Cancel the menu's collapseAll on document click
+		this.menuInstance._closeOnDocumentClick = function() {
+			return false;
+		};
+
+		// Selects often contain empty items, but never contain dividers
+		this.menuInstance._isDivider = function() {
+			return false;
+		};
+	},
+
+	refresh: function() {
+		this._refreshMenu();
+		this.buttonItem.replaceWith(
+			this.buttonItem = this._renderButtonItem(
+
+				// Fall back to an empty object in case there are no options
+				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
+			)
+		);
+		if ( this.options.width === null ) {
+			this._resizeButton();
+		}
+	},
+
+	_refreshMenu: function() {
+		var item,
+			options = this.element.find( "option" );
+
+		this.menu.empty();
+
+		this._parseOptions( options );
+		this._renderMenu( this.menu, this.items );
+
+		this.menuInstance.refresh();
+		this.menuItems = this.menu.find( "li" )
+			.not( ".ui-selectmenu-optgroup" )
+				.find( ".ui-menu-item-wrapper" );
+
+		this._rendered = true;
+
+		if ( !options.length ) {
+			return;
+		}
+
+		item = this._getSelectedItem();
+
+		// Update the menu to have the correct item focused
+		this.menuInstance.focus( null, item );
+		this._setAria( item.data( "ui-selectmenu-item" ) );
+
+		// Set disabled state
+		this._setOption( "disabled", this.element.prop( "disabled" ) );
+	},
+
+	open: function( event ) {
+		if ( this.options.disabled ) {
+			return;
+		}
+
+		// If this is the first time the menu is being opened, render the items
+		if ( !this._rendered ) {
+			this._refreshMenu();
+		} else {
+
+			// Menu clears focus on close, reset focus to selected item
+			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
+			this.menuInstance.focus( null, this._getSelectedItem() );
+		}
+
+		// If there are no options, don't open the menu
+		if ( !this.menuItems.length ) {
+			return;
+		}
+
+		this.isOpen = true;
+		this._toggleAttr();
+		this._resizeMenu();
+		this._position();
+
+		this._on( this.document, this._documentClick );
+
+		this._trigger( "open", event );
+	},
+
+	_position: function() {
+		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
+	},
+
+	close: function( event ) {
+		if ( !this.isOpen ) {
+			return;
+		}
+
+		this.isOpen = false;
+		this._toggleAttr();
+
+		this.range = null;
+		this._off( this.document );
+
+		this._trigger( "close", event );
+	},
+
+	widget: function() {
+		return this.button;
+	},
+
+	menuWidget: function() {
+		return this.menu;
+	},
+
+	_renderButtonItem: function( item ) {
+		var buttonItem = $( "<span>" );
+
+		this._setText( buttonItem, item.label );
+		this._addClass( buttonItem, "ui-selectmenu-text" );
+
+		return buttonItem;
+	},
+
+	_renderMenu: function( ul, items ) {
+		var that = this,
+			currentOptgroup = "";
+
+		$.each( items, function( index, item ) {
+			var li;
+
+			if ( item.optgroup !== currentOptgroup ) {
+				li = $( "<li>", {
+					text: item.optgroup
+				} );
+				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
+					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
+						" ui-state-disabled" :
+						"" ) );
+
+				li.appendTo( ul );
+
+				currentOptgroup = item.optgroup;
+			}
+
+			that._renderItemData( ul, item );
+		} );
+	},
+
+	_renderItemData: function( ul, item ) {
+		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
+	},
+
+	_renderItem: function( ul, item ) {
+		var li = $( "<li>" ),
+			wrapper = $( "<div>", {
+				title: item.element.attr( "title" )
+			} );
+
+		if ( item.disabled ) {
+			this._addClass( li, null, "ui-state-disabled" );
+		}
+		this._setText( wrapper, item.label );
+
+		return li.append( wrapper ).appendTo( ul );
+	},
+
+	_setText: function( element, value ) {
+		if ( value ) {
+			element.text( value );
+		} else {
+			element.html( "&#160;" );
+		}
+	},
+
+	_move: function( direction, event ) {
+		var item, next,
+			filter = ".ui-menu-item";
+
+		if ( this.isOpen ) {
+			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
+		} else {
+			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
+			filter += ":not(.ui-state-disabled)";
+		}
+
+		if ( direction === "first" || direction === "last" ) {
+			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
+		} else {
+			next = item[ direction + "All" ]( filter ).eq( 0 );
+		}
+
+		if ( next.length ) {
+			this.menuInstance.focus( event, next );
+		}
+	},
+
+	_getSelectedItem: function() {
+		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
+	},
+
+	_toggle: function( event ) {
+		this[ this.isOpen ? "close" : "open" ]( event );
+	},
+
+	_setSelection: function() {
+		var selection;
+
+		if ( !this.range ) {
+			return;
+		}
+
+		if ( window.getSelection ) {
+			selection = window.getSelection();
+			selection.removeAllRanges();
+			selection.addRange( this.range );
+
+		// Support: IE8
+		} else {
+			this.range.select();
+		}
+
+		// Support: IE
+		// Setting the text selection kills the button focus in IE, but
+		// restoring the focus doesn't kill the selection.
+		this.button.focus();
+	},
+
+	_documentClick: {
+		mousedown: function( event ) {
+			if ( !this.isOpen ) {
+				return;
+			}
+
+			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
+					$.ui.escapeSelector( this.ids.button ) ).length ) {
+				this.close( event );
+			}
+		}
+	},
+
+	_buttonEvents: {
+
+		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
+		mousedown: function() {
+			var selection;
+
+			if ( window.getSelection ) {
+				selection = window.getSelection();
+				if ( selection.rangeCount ) {
+					this.range = selection.getRangeAt( 0 );
+				}
+
+			// Support: IE8
+			} else {
+				this.range = document.selection.createRange();
+			}
+		},
+
+		click: function( event ) {
+			this._setSelection();
+			this._toggle( event );
+		},
+
+		keydown: function( event ) {
+			var preventDefault = true;
+			switch ( event.keyCode ) {
+			case $.ui.keyCode.TAB:
+			case $.ui.keyCode.ESCAPE:
+				this.close( event );
+				preventDefault = false;
+				break;
+			case $.ui.keyCode.ENTER:
+				if ( this.isOpen ) {
+					this._selectFocusedItem( event );
+				}
+				break;
+			case $.ui.keyCode.UP:
+				if ( event.altKey ) {
+					this._toggle( event );
+				} else {
+					this._move( "prev", event );
+				}
+				break;
+			case $.ui.keyCode.DOWN:
+				if ( event.altKey ) {
+					this._toggle( event );
+				} else {
+					this._move( "next", event );
+				}
+				break;
+			case $.ui.keyCode.SPACE:
+				if ( this.isOpen ) {
+					this._selectFocusedItem( event );
+				} else {
+					this._toggle( event );
+				}
+				break;
+			case $.ui.keyCode.LEFT:
+				this._move( "prev", event );
+				break;
+			case $.ui.keyCode.RIGHT:
+				this._move( "next", event );
+				break;
+			case $.ui.keyCode.HOME:
+			case $.ui.keyCode.PAGE_UP:
+				this._move( "first", event );
+				break;
+			case $.ui.keyCode.END:
+			case $.ui.keyCode.PAGE_DOWN:
+				this._move( "last", event );
+				break;
+			default:
+				this.menu.trigger( event );
+				preventDefault = false;
+			}
+
+			if ( preventDefault ) {
+				event.preventDefault();
+			}
+		}
+	},
+
+	_selectFocusedItem: function( event ) {
+		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
+		if ( !item.hasClass( "ui-state-disabled" ) ) {
+			this._select( item.data( "ui-selectmenu-item" ), event );
+		}
+	},
+
+	_select: function( item, event ) {
+		var oldIndex = this.element[ 0 ].selectedIndex;
+
+		// Change native select element
+		this.element[ 0 ].selectedIndex = item.index;
+		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
+		this._setAria( item );
+		this._trigger( "select", event, { item: item } );
+
+		if ( item.index !== oldIndex ) {
+			this._trigger( "change", event, { item: item } );
+		}
+
+		this.close( event );
+	},
+
+	_setAria: function( item ) {
+		var id = this.menuItems.eq( item.index ).attr( "id" );
+
+		this.button.attr( {
+			"aria-labelledby": id,
+			"aria-activedescendant": id
+		} );
+		this.menu.attr( "aria-activedescendant", id );
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "icons" ) {
+			var icon = this.button.find( "span.ui-icon" );
+			this._removeClass( icon, null, this.options.icons.button )
+				._addClass( icon, null, value.button );
+		}
+
+		this._super( key, value );
+
+		if ( key === "appendTo" ) {
+			this.menuWrap.appendTo( this._appendTo() );
+		}
+
+		if ( key === "width" ) {
+			this._resizeButton();
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this.menuInstance.option( "disabled", value );
+		this.button.attr( "aria-disabled", value );
+		this._toggleClass( this.button, null, "ui-state-disabled", value );
+
+		this.element.prop( "disabled", value );
+		if ( value ) {
+			this.button.attr( "tabindex", -1 );
+			this.close();
+		} else {
+			this.button.attr( "tabindex", 0 );
+		}
+	},
+
+	_appendTo: function() {
+		var element = this.options.appendTo;
+
+		if ( element ) {
+			element = element.jquery || element.nodeType ?
+				$( element ) :
+				this.document.find( element ).eq( 0 );
+		}
+
+		if ( !element || !element[ 0 ] ) {
+			element = this.element.closest( ".ui-front, dialog" );
+		}
+
+		if ( !element.length ) {
+			element = this.document[ 0 ].body;
+		}
+
+		return element;
+	},
+
+	_toggleAttr: function() {
+		this.button.attr( "aria-expanded", this.isOpen );
+
+		// We can't use two _toggleClass() calls here, because we need to make sure
+		// we always remove classes first and add them second, otherwise if both classes have the
+		// same theme class, it will be removed after we add it.
+		this._removeClass( this.button, "ui-selectmenu-button-" +
+			( this.isOpen ? "closed" : "open" ) )
+			._addClass( this.button, "ui-selectmenu-button-" +
+				( this.isOpen ? "open" : "closed" ) )
+			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
+
+		this.menu.attr( "aria-hidden", !this.isOpen );
+	},
+
+	_resizeButton: function() {
+		var width = this.options.width;
+
+		// For `width: false`, just remove inline style and stop
+		if ( width === false ) {
+			this.button.css( "width", "" );
+			return;
+		}
+
+		// For `width: null`, match the width of the original element
+		if ( width === null ) {
+			width = this.element.show().outerWidth();
+			this.element.hide();
+		}
+
+		this.button.outerWidth( width );
+	},
+
+	_resizeMenu: function() {
+		this.menu.outerWidth( Math.max(
+			this.button.outerWidth(),
+
+			// Support: IE10
+			// IE10 wraps long text (possibly a rounding bug)
+			// so we add 1px to avoid the wrapping
+			this.menu.width( "" ).outerWidth() + 1
+		) );
+	},
+
+	_getCreateOptions: function() {
+		var options = this._super();
+
+		options.disabled = this.element.prop( "disabled" );
+
+		return options;
+	},
+
+	_parseOptions: function( options ) {
+		var that = this,
+			data = [];
+		options.each( function( index, item ) {
+			data.push( that._parseOption( $( item ), index ) );
+		} );
+		this.items = data;
+	},
+
+	_parseOption: function( option, index ) {
+		var optgroup = option.parent( "optgroup" );
+
+		return {
+			element: option,
+			index: index,
+			value: option.val(),
+			label: option.text(),
+			optgroup: optgroup.attr( "label" ) || "",
+			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
+		};
+	},
+
+	_destroy: function() {
+		this._unbindFormResetHandler();
+		this.menuWrap.remove();
+		this.button.remove();
+		this.element.show();
+		this.element.removeUniqueId();
+		this.labels.attr( "for", this.ids.element );
+	}
+} ] );
+
+
+/*!
+ * jQuery UI Slider 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Fade
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Fold 1.8.14
+
+//>>label: Slider
+//>>group: Widgets
+//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
+//>>docs: http://api.jqueryui.com/slider/
+//>>demos: http://jqueryui.com/slider/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/slider.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
+	version: "1.12.1",
+	widgetEventPrefix: "slide",
+
+	options: {
+		animate: false,
+		classes: {
+			"ui-slider": "ui-corner-all",
+			"ui-slider-handle": "ui-corner-all",
+
+			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
+			// element, but worked best visually with a variety of themes
+			"ui-slider-range": "ui-corner-all ui-widget-header"
+		},
+		distance: 0,
+		max: 100,
+		min: 0,
+		orientation: "horizontal",
+		range: false,
+		step: 1,
+		value: 0,
+		values: null,
+
+		// Callbacks
+		change: null,
+		slide: null,
+		start: null,
+		stop: null
+	},
+
+	// Number of pages in a slider
+	// (how many times can you page up/down to go through the whole range)
+	numPages: 5,
+
+	_create: function() {
+		this._keySliding = false;
+		this._mouseSliding = false;
+		this._animateOff = true;
+		this._handleIndex = null;
+		this._detectOrientation();
+		this._mouseInit();
+		this._calculateNewMax();
+
+		this._addClass( "ui-slider ui-slider-" + this.orientation,
+			"ui-widget ui-widget-content" );
+
+		this._refresh();
+
+		this._animateOff = false;
+	},
+
+	_refresh: function() {
+		this._createRange();
+		this._createHandles();
+		this._setupEvents();
+		this._refreshValue();
+	},
+
+	_createHandles: function() {
+		var i, handleCount,
+			options = this.options,
+			existingHandles = this.element.find( ".ui-slider-handle" ),
+			handle = "<span tabindex='0'></span>",
+			handles = [];
+
+		handleCount = ( options.values && options.values.length ) || 1;
+
+		if ( existingHandles.length > handleCount ) {
+			existingHandles.slice( handleCount ).remove();
+			existingHandles = existingHandles.slice( 0, handleCount );
+		}
+
+		for ( i = existingHandles.length; i < handleCount; i++ ) {
+			handles.push( handle );
+		}
+
+		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
+
+		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
+
+		this.handle = this.handles.eq( 0 );
+
+		this.handles.each( function( i ) {
+			$( this )
+				.data( "ui-slider-handle-index", i )
+				.attr( "tabIndex", 0 );
+		} );
+	},
+
+	_createRange: function() {
+		var options = this.options;
+
+		if ( options.range ) {
+			if ( options.range === true ) {
+				if ( !options.values ) {
+					options.values = [ this._valueMin(), this._valueMin() ];
+				} else if ( options.values.length && options.values.length !== 2 ) {
+					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
+				} else if ( $.isArray( options.values ) ) {
+					options.values = options.values.slice( 0 );
+				}
+			}
+
+			if ( !this.range || !this.range.length ) {
+				this.range = $( "<div>" )
+					.appendTo( this.element );
+
+				this._addClass( this.range, "ui-slider-range" );
+			} else {
+				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
+
+				// Handle range switching from true to min/max
+				this.range.css( {
+					"left": "",
+					"bottom": ""
+				} );
+			}
+			if ( options.range === "min" || options.range === "max" ) {
+				this._addClass( this.range, "ui-slider-range-" + options.range );
+			}
+		} else {
+			if ( this.range ) {
+				this.range.remove();
+			}
+			this.range = null;
+		}
+	},
+
+	_setupEvents: function() {
+		this._off( this.handles );
+		this._on( this.handles, this._handleEvents );
+		this._hoverable( this.handles );
+		this._focusable( this.handles );
+	},
+
+	_destroy: function() {
+		this.handles.remove();
+		if ( this.range ) {
+			this.range.remove();
+		}
+
+		this._mouseDestroy();
+	},
+
+	_mouseCapture: function( event ) {
+		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
+			that = this,
+			o = this.options;
+
+		if ( o.disabled ) {
+			return false;
+		}
+
+		this.elementSize = {
+			width: this.element.outerWidth(),
+			height: this.element.outerHeight()
+		};
+		this.elementOffset = this.element.offset();
+
+		position = { x: event.pageX, y: event.pageY };
+		normValue = this._normValueFromMouse( position );
+		distance = this._valueMax() - this._valueMin() + 1;
+		this.handles.each( function( i ) {
+			var thisDistance = Math.abs( normValue - that.values( i ) );
+			if ( ( distance > thisDistance ) ||
+				( distance === thisDistance &&
+					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
+				distance = thisDistance;
+				closestHandle = $( this );
+				index = i;
+			}
+		} );
+
+		allowed = this._start( event, index );
+		if ( allowed === false ) {
+			return false;
+		}
+		this._mouseSliding = true;
+
+		this._handleIndex = index;
+
+		this._addClass( closestHandle, null, "ui-state-active" );
+		closestHandle.trigger( "focus" );
+
+		offset = closestHandle.offset();
+		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
+		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+			top: event.pageY - offset.top -
+				( closestHandle.height() / 2 ) -
+				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
+				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
+				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
+		};
+
+		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+			this._slide( event, index, normValue );
+		}
+		this._animateOff = true;
+		return true;
+	},
+
+	_mouseStart: function() {
+		return true;
+	},
+
+	_mouseDrag: function( event ) {
+		var position = { x: event.pageX, y: event.pageY },
+			normValue = this._normValueFromMouse( position );
+
+		this._slide( event, this._handleIndex, normValue );
+
+		return false;
+	},
+
+	_mouseStop: function( event ) {
+		this._removeClass( this.handles, null, "ui-state-active" );
+		this._mouseSliding = false;
+
+		this._stop( event, this._handleIndex );
+		this._change( event, this._handleIndex );
+
+		this._handleIndex = null;
+		this._clickOffset = null;
+		this._animateOff = false;
+
+		return false;
+	},
+
+	_detectOrientation: function() {
+		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+	},
+
+	_normValueFromMouse: function( position ) {
+		var pixelTotal,
+			pixelMouse,
+			percentMouse,
+			valueTotal,
+			valueMouse;
+
+		if ( this.orientation === "horizontal" ) {
+			pixelTotal = this.elementSize.width;
+			pixelMouse = position.x - this.elementOffset.left -
+				( this._clickOffset ? this._clickOffset.left : 0 );
+		} else {
+			pixelTotal = this.elementSize.height;
+			pixelMouse = position.y - this.elementOffset.top -
+				( this._clickOffset ? this._clickOffset.top : 0 );
+		}
+
+		percentMouse = ( pixelMouse / pixelTotal );
+		if ( percentMouse > 1 ) {
+			percentMouse = 1;
+		}
+		if ( percentMouse < 0 ) {
+			percentMouse = 0;
+		}
+		if ( this.orientation === "vertical" ) {
+			percentMouse = 1 - percentMouse;
+		}
+
+		valueTotal = this._valueMax() - this._valueMin();
+		valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+		return this._trimAlignValue( valueMouse );
+	},
+
+	_uiHash: function( index, value, values ) {
+		var uiHash = {
+			handle: this.handles[ index ],
+			handleIndex: index,
+			value: value !== undefined ? value : this.value()
+		};
+
+		if ( this._hasMultipleValues() ) {
+			uiHash.value = value !== undefined ? value : this.values( index );
+			uiHash.values = values || this.values();
+		}
+
+		return uiHash;
+	},
+
+	_hasMultipleValues: function() {
+		return this.options.values && this.options.values.length;
+	},
+
+	_start: function( event, index ) {
+		return this._trigger( "start", event, this._uiHash( index ) );
+	},
+
+	_slide: function( event, index, newVal ) {
+		var allowed, otherVal,
+			currentValue = this.value(),
+			newValues = this.values();
+
+		if ( this._hasMultipleValues() ) {
+			otherVal = this.values( index ? 0 : 1 );
+			currentValue = this.values( index );
+
+			if ( this.options.values.length === 2 && this.options.range === true ) {
+				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
+			}
+
+			newValues[ index ] = newVal;
+		}
+
+		if ( newVal === currentValue ) {
+			return;
+		}
+
+		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
+
+		// A slide can be canceled by returning false from the slide callback
+		if ( allowed === false ) {
+			return;
+		}
+
+		if ( this._hasMultipleValues() ) {
+			this.values( index, newVal );
+		} else {
+			this.value( newVal );
+		}
+	},
+
+	_stop: function( event, index ) {
+		this._trigger( "stop", event, this._uiHash( index ) );
+	},
+
+	_change: function( event, index ) {
+		if ( !this._keySliding && !this._mouseSliding ) {
+
+			//store the last changed value index for reference when handles overlap
+			this._lastChangedValue = index;
+			this._trigger( "change", event, this._uiHash( index ) );
+		}
+	},
+
+	value: function( newValue ) {
+		if ( arguments.length ) {
+			this.options.value = this._trimAlignValue( newValue );
+			this._refreshValue();
+			this._change( null, 0 );
+			return;
+		}
+
+		return this._value();
+	},
+
+	values: function( index, newValue ) {
+		var vals,
+			newValues,
+			i;
+
+		if ( arguments.length > 1 ) {
+			this.options.values[ index ] = this._trimAlignValue( newValue );
+			this._refreshValue();
+			this._change( null, index );
+			return;
+		}
+
+		if ( arguments.length ) {
+			if ( $.isArray( arguments[ 0 ] ) ) {
+				vals = this.options.values;
+				newValues = arguments[ 0 ];
+				for ( i = 0; i < vals.length; i += 1 ) {
+					vals[ i ] = this._trimAlignValue( newValues[ i ] );
+					this._change( null, i );
+				}
+				this._refreshValue();
+			} else {
+				if ( this._hasMultipleValues() ) {
+					return this._values( index );
+				} else {
+					return this.value();
+				}
+			}
+		} else {
+			return this._values();
+		}
+	},
+
+	_setOption: function( key, value ) {
+		var i,
+			valsLength = 0;
+
+		if ( key === "range" && this.options.range === true ) {
+			if ( value === "min" ) {
+				this.options.value = this._values( 0 );
+				this.options.values = null;
+			} else if ( value === "max" ) {
+				this.options.value = this._values( this.options.values.length - 1 );
+				this.options.values = null;
+			}
+		}
+
+		if ( $.isArray( this.options.values ) ) {
+			valsLength = this.options.values.length;
+		}
+
+		this._super( key, value );
+
+		switch ( key ) {
+			case "orientation":
+				this._detectOrientation();
+				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
+					._addClass( "ui-slider-" + this.orientation );
+				this._refreshValue();
+				if ( this.options.range ) {
+					this._refreshRange( value );
+				}
+
+				// Reset positioning from previous orientation
+				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
+				break;
+			case "value":
+				this._animateOff = true;
+				this._refreshValue();
+				this._change( null, 0 );
+				this._animateOff = false;
+				break;
+			case "values":
+				this._animateOff = true;
+				this._refreshValue();
+
+				// Start from the last handle to prevent unreachable handles (#9046)
+				for ( i = valsLength - 1; i >= 0; i-- ) {
+					this._change( null, i );
+				}
+				this._animateOff = false;
+				break;
+			case "step":
+			case "min":
+			case "max":
+				this._animateOff = true;
+				this._calculateNewMax();
+				this._refreshValue();
+				this._animateOff = false;
+				break;
+			case "range":
+				this._animateOff = true;
+				this._refresh();
+				this._animateOff = false;
+				break;
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this._toggleClass( null, "ui-state-disabled", !!value );
+	},
+
+	//internal value getter
+	// _value() returns value trimmed by min and max, aligned by step
+	_value: function() {
+		var val = this.options.value;
+		val = this._trimAlignValue( val );
+
+		return val;
+	},
+
+	//internal values getter
+	// _values() returns array of values trimmed by min and max, aligned by step
+	// _values( index ) returns single value trimmed by min and max, aligned by step
+	_values: function( index ) {
+		var val,
+			vals,
+			i;
+
+		if ( arguments.length ) {
+			val = this.options.values[ index ];
+			val = this._trimAlignValue( val );
+
+			return val;
+		} else if ( this._hasMultipleValues() ) {
+
+			// .slice() creates a copy of the array
+			// this copy gets trimmed by min and max and then returned
+			vals = this.options.values.slice();
+			for ( i = 0; i < vals.length; i += 1 ) {
+				vals[ i ] = this._trimAlignValue( vals[ i ] );
+			}
+
+			return vals;
+		} else {
+			return [];
+		}
+	},
+
+	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
+	_trimAlignValue: function( val ) {
+		if ( val <= this._valueMin() ) {
+			return this._valueMin();
+		}
+		if ( val >= this._valueMax() ) {
+			return this._valueMax();
+		}
+		var step = ( this.options.step > 0 ) ? this.options.step : 1,
+			valModStep = ( val - this._valueMin() ) % step,
+			alignValue = val - valModStep;
+
+		if ( Math.abs( valModStep ) * 2 >= step ) {
+			alignValue += ( valModStep > 0 ) ? step : ( -step );
+		}
+
+		// Since JavaScript has problems with large floats, round
+		// the final value to 5 digits after the decimal point (see #4124)
+		return parseFloat( alignValue.toFixed( 5 ) );
+	},
+
+	_calculateNewMax: function() {
+		var max = this.options.max,
+			min = this._valueMin(),
+			step = this.options.step,
+			aboveMin = Math.round( ( max - min ) / step ) * step;
+		max = aboveMin + min;
+		if ( max > this.options.max ) {
+
+			//If max is not divisible by step, rounding off may increase its value
+			max -= step;
+		}
+		this.max = parseFloat( max.toFixed( this._precision() ) );
+	},
+
+	_precision: function() {
+		var precision = this._precisionOf( this.options.step );
+		if ( this.options.min !== null ) {
+			precision = Math.max( precision, this._precisionOf( this.options.min ) );
+		}
+		return precision;
+	},
+
+	_precisionOf: function( num ) {
+		var str = num.toString(),
+			decimal = str.indexOf( "." );
+		return decimal === -1 ? 0 : str.length - decimal - 1;
+	},
+
+	_valueMin: function() {
+		return this.options.min;
+	},
+
+	_valueMax: function() {
+		return this.max;
+	},
+
+	_refreshRange: function( orientation ) {
+		if ( orientation === "vertical" ) {
+			this.range.css( { "width": "", "left": "" } );
+		}
+		if ( orientation === "horizontal" ) {
+			this.range.css( { "height": "", "bottom": "" } );
+		}
+	},
+
+	_refreshValue: function() {
+		var lastValPercent, valPercent, value, valueMin, valueMax,
+			oRange = this.options.range,
+			o = this.options,
+			that = this,
+			animate = ( !this._animateOff ) ? o.animate : false,
+			_set = {};
+
+		if ( this._hasMultipleValues() ) {
+			this.handles.each( function( i ) {
+				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
+					that._valueMin() ) * 100;
+				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+				if ( that.options.range === true ) {
+					if ( that.orientation === "horizontal" ) {
+						if ( i === 0 ) {
+							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+								left: valPercent + "%"
+							}, o.animate );
+						}
+						if ( i === 1 ) {
+							that.range[ animate ? "animate" : "css" ]( {
+								width: ( valPercent - lastValPercent ) + "%"
+							}, {
+								queue: false,
+								duration: o.animate
+							} );
+						}
+					} else {
+						if ( i === 0 ) {
+							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+								bottom: ( valPercent ) + "%"
+							}, o.animate );
+						}
+						if ( i === 1 ) {
+							that.range[ animate ? "animate" : "css" ]( {
+								height: ( valPercent - lastValPercent ) + "%"
+							}, {
+								queue: false,
+								duration: o.animate
+							} );
+						}
+					}
+				}
+				lastValPercent = valPercent;
+			} );
+		} else {
+			value = this.value();
+			valueMin = this._valueMin();
+			valueMax = this._valueMax();
+			valPercent = ( valueMax !== valueMin ) ?
+					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+					0;
+			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+			if ( oRange === "min" && this.orientation === "horizontal" ) {
+				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+					width: valPercent + "%"
+				}, o.animate );
+			}
+			if ( oRange === "max" && this.orientation === "horizontal" ) {
+				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+					width: ( 100 - valPercent ) + "%"
+				}, o.animate );
+			}
+			if ( oRange === "min" && this.orientation === "vertical" ) {
+				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+					height: valPercent + "%"
+				}, o.animate );
+			}
+			if ( oRange === "max" && this.orientation === "vertical" ) {
+				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
+					height: ( 100 - valPercent ) + "%"
+				}, o.animate );
+			}
+		}
+	},
+
+	_handleEvents: {
+		keydown: function( event ) {
+			var allowed, curVal, newVal, step,
+				index = $( event.target ).data( "ui-slider-handle-index" );
+
+			switch ( event.keyCode ) {
+				case $.ui.keyCode.HOME:
+				case $.ui.keyCode.END:
+				case $.ui.keyCode.PAGE_UP:
+				case $.ui.keyCode.PAGE_DOWN:
+				case $.ui.keyCode.UP:
+				case $.ui.keyCode.RIGHT:
+				case $.ui.keyCode.DOWN:
+				case $.ui.keyCode.LEFT:
+					event.preventDefault();
+					if ( !this._keySliding ) {
+						this._keySliding = true;
+						this._addClass( $( event.target ), null, "ui-state-active" );
+						allowed = this._start( event, index );
+						if ( allowed === false ) {
+							return;
+						}
+					}
+					break;
+			}
+
+			step = this.options.step;
+			if ( this._hasMultipleValues() ) {
+				curVal = newVal = this.values( index );
+			} else {
+				curVal = newVal = this.value();
+			}
+
+			switch ( event.keyCode ) {
+				case $.ui.keyCode.HOME:
+					newVal = this._valueMin();
+					break;
+				case $.ui.keyCode.END:
+					newVal = this._valueMax();
+					break;
+				case $.ui.keyCode.PAGE_UP:
+					newVal = this._trimAlignValue(
+						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
+					);
+					break;
+				case $.ui.keyCode.PAGE_DOWN:
+					newVal = this._trimAlignValue(
+						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
+					break;
+				case $.ui.keyCode.UP:
+				case $.ui.keyCode.RIGHT:
+					if ( curVal === this._valueMax() ) {
+						return;
+					}
+					newVal = this._trimAlignValue( curVal + step );
+					break;
+				case $.ui.keyCode.DOWN:
+				case $.ui.keyCode.LEFT:
+					if ( curVal === this._valueMin() ) {
+						return;
+					}
+					newVal = this._trimAlignValue( curVal - step );
+					break;
+			}
+
+			this._slide( event, index, newVal );
+		},
+		keyup: function( event ) {
+			var index = $( event.target ).data( "ui-slider-handle-index" );
+
+			if ( this._keySliding ) {
+				this._keySliding = false;
+				this._stop( event, index );
+				this._change( event, index );
+				this._removeClass( $( event.target ), null, "ui-state-active" );
+			}
+		}
+	}
+} );
+
+
+/*!
+ * jQuery UI Sortable 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Fold
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],
-10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery);
-;/*
- * jQuery UI Effects Highlight 1.8.14
+
+//>>label: Sortable
+//>>group: Interactions
+//>>description: Enables items in a list to be sorted using the mouse.
+//>>docs: http://api.jqueryui.com/sortable/
+//>>demos: http://jqueryui.com/sortable/
+//>>css.structure: ../../themes/base/sortable.css
+
+
+
+var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
+	version: "1.12.1",
+	widgetEventPrefix: "sort",
+	ready: false,
+	options: {
+		appendTo: "parent",
+		axis: false,
+		connectWith: false,
+		containment: false,
+		cursor: "auto",
+		cursorAt: false,
+		dropOnEmpty: true,
+		forcePlaceholderSize: false,
+		forceHelperSize: false,
+		grid: false,
+		handle: false,
+		helper: "original",
+		items: "> *",
+		opacity: false,
+		placeholder: false,
+		revert: false,
+		scroll: true,
+		scrollSensitivity: 20,
+		scrollSpeed: 20,
+		scope: "default",
+		tolerance: "intersect",
+		zIndex: 1000,
+
+		// Callbacks
+		activate: null,
+		beforeStop: null,
+		change: null,
+		deactivate: null,
+		out: null,
+		over: null,
+		receive: null,
+		remove: null,
+		sort: null,
+		start: null,
+		stop: null,
+		update: null
+	},
+
+	_isOverAxis: function( x, reference, size ) {
+		return ( x >= reference ) && ( x < ( reference + size ) );
+	},
+
+	_isFloating: function( item ) {
+		return ( /left|right/ ).test( item.css( "float" ) ) ||
+			( /inline|table-cell/ ).test( item.css( "display" ) );
+	},
+
+	_create: function() {
+		this.containerCache = {};
+		this._addClass( "ui-sortable" );
+
+		//Get the items
+		this.refresh();
+
+		//Let's determine the parent's offset
+		this.offset = this.element.offset();
+
+		//Initialize mouse events for interaction
+		this._mouseInit();
+
+		this._setHandleClassName();
+
+		//We're ready to go
+		this.ready = true;
+
+	},
+
+	_setOption: function( key, value ) {
+		this._super( key, value );
+
+		if ( key === "handle" ) {
+			this._setHandleClassName();
+		}
+	},
+
+	_setHandleClassName: function() {
+		var that = this;
+		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
+		$.each( this.items, function() {
+			that._addClass(
+				this.instance.options.handle ?
+					this.item.find( this.instance.options.handle ) :
+					this.item,
+				"ui-sortable-handle"
+			);
+		} );
+	},
+
+	_destroy: function() {
+		this._mouseDestroy();
+
+		for ( var i = this.items.length - 1; i >= 0; i-- ) {
+			this.items[ i ].item.removeData( this.widgetName + "-item" );
+		}
+
+		return this;
+	},
+
+	_mouseCapture: function( event, overrideHandle ) {
+		var currentItem = null,
+			validHandle = false,
+			that = this;
+
+		if ( this.reverting ) {
+			return false;
+		}
+
+		if ( this.options.disabled || this.options.type === "static" ) {
+			return false;
+		}
+
+		//We have to refresh the items data once first
+		this._refreshItems( event );
+
+		//Find out if the clicked node (or one of its parents) is a actual item in this.items
+		$( event.target ).parents().each( function() {
+			if ( $.data( this, that.widgetName + "-item" ) === that ) {
+				currentItem = $( this );
+				return false;
+			}
+		} );
+		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
+			currentItem = $( event.target );
+		}
+
+		if ( !currentItem ) {
+			return false;
+		}
+		if ( this.options.handle && !overrideHandle ) {
+			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
+				if ( this === event.target ) {
+					validHandle = true;
+				}
+			} );
+			if ( !validHandle ) {
+				return false;
+			}
+		}
+
+		this.currentItem = currentItem;
+		this._removeCurrentsFromItems();
+		return true;
+
+	},
+
+	_mouseStart: function( event, overrideHandle, noActivation ) {
+
+		var i, body,
+			o = this.options;
+
+		this.currentContainer = this;
+
+		//We only need to call refreshPositions, because the refreshItems call has been moved to
+		// mouseCapture
+		this.refreshPositions();
+
+		//Create and append the visible helper
+		this.helper = this._createHelper( event );
+
+		//Cache the helper size
+		this._cacheHelperProportions();
+
+		/*
+		 * - Position generation -
+		 * This block generates everything position related - it's the core of draggables.
+		 */
+
+		//Cache the margins of the original element
+		this._cacheMargins();
+
+		//Get the next scrolling parent
+		this.scrollParent = this.helper.scrollParent();
+
+		//The element's absolute position on the page minus margins
+		this.offset = this.currentItem.offset();
+		this.offset = {
+			top: this.offset.top - this.margins.top,
+			left: this.offset.left - this.margins.left
+		};
+
+		$.extend( this.offset, {
+			click: { //Where the click happened, relative to the element
+				left: event.pageX - this.offset.left,
+				top: event.pageY - this.offset.top
+			},
+			parent: this._getParentOffset(),
+
+			// This is a relative to absolute position minus the actual position calculation -
+			// only used for relative positioned helper
+			relative: this._getRelativeOffset()
+		} );
+
+		// Only after we got the offset, we can change the helper's position to absolute
+		// TODO: Still need to figure out a way to make relative sorting possible
+		this.helper.css( "position", "absolute" );
+		this.cssPosition = this.helper.css( "position" );
+
+		//Generate the original position
+		this.originalPosition = this._generatePosition( event );
+		this.originalPageX = event.pageX;
+		this.originalPageY = event.pageY;
+
+		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
+
+		//Cache the former DOM position
+		this.domPosition = {
+			prev: this.currentItem.prev()[ 0 ],
+			parent: this.currentItem.parent()[ 0 ]
+		};
+
+		// If the helper is not the original, hide the original so it's not playing any role during
+		// the drag, won't cause anything bad this way
+		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
+			this.currentItem.hide();
+		}
+
+		//Create the placeholder
+		this._createPlaceholder();
+
+		//Set a containment if given in the options
+		if ( o.containment ) {
+			this._setContainment();
+		}
+
+		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
+			body = this.document.find( "body" );
+
+			// Support: IE
+			this.storedCursor = body.css( "cursor" );
+			body.css( "cursor", o.cursor );
+
+			this.storedStylesheet =
+				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
+		}
+
+		if ( o.opacity ) { // opacity option
+			if ( this.helper.css( "opacity" ) ) {
+				this._storedOpacity = this.helper.css( "opacity" );
+			}
+			this.helper.css( "opacity", o.opacity );
+		}
+
+		if ( o.zIndex ) { // zIndex option
+			if ( this.helper.css( "zIndex" ) ) {
+				this._storedZIndex = this.helper.css( "zIndex" );
+			}
+			this.helper.css( "zIndex", o.zIndex );
+		}
+
+		//Prepare scrolling
+		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				this.scrollParent[ 0 ].tagName !== "HTML" ) {
+			this.overflowOffset = this.scrollParent.offset();
+		}
+
+		//Call callbacks
+		this._trigger( "start", event, this._uiHash() );
+
+		//Recache the helper size
+		if ( !this._preserveHelperProportions ) {
+			this._cacheHelperProportions();
+		}
+
+		//Post "activate" events to possible containers
+		if ( !noActivation ) {
+			for ( i = this.containers.length - 1; i >= 0; i-- ) {
+				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
+			}
+		}
+
+		//Prepare possible droppables
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.current = this;
+		}
+
+		if ( $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( this, event );
+		}
+
+		this.dragging = true;
+
+		this._addClass( this.helper, "ui-sortable-helper" );
+
+		// Execute the drag once - this causes the helper not to be visiblebefore getting its
+		// correct position
+		this._mouseDrag( event );
+		return true;
+
+	},
+
+	_mouseDrag: function( event ) {
+		var i, item, itemElement, intersection,
+			o = this.options,
+			scrolled = false;
+
+		//Compute the helpers position
+		this.position = this._generatePosition( event );
+		this.positionAbs = this._convertPositionTo( "absolute" );
+
+		if ( !this.lastPositionAbs ) {
+			this.lastPositionAbs = this.positionAbs;
+		}
+
+		//Do scrolling
+		if ( this.options.scroll ) {
+			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+					this.scrollParent[ 0 ].tagName !== "HTML" ) {
+
+				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
+						event.pageY < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollTop =
+						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
+				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollTop =
+						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
+				}
+
+				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
+						event.pageX < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollLeft = scrolled =
+						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
+				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollLeft = scrolled =
+						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
+				}
+
+			} else {
+
+				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
+					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
+				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
+						o.scrollSensitivity ) {
+					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
+				}
+
+				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
+					scrolled = this.document.scrollLeft(
+						this.document.scrollLeft() - o.scrollSpeed
+					);
+				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
+						o.scrollSensitivity ) {
+					scrolled = this.document.scrollLeft(
+						this.document.scrollLeft() + o.scrollSpeed
+					);
+				}
+
+			}
+
+			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
+				$.ui.ddmanager.prepareOffsets( this, event );
+			}
+		}
+
+		//Regenerate the absolute position used for position checks
+		this.positionAbs = this._convertPositionTo( "absolute" );
+
+		//Set the helper position
+		if ( !this.options.axis || this.options.axis !== "y" ) {
+			this.helper[ 0 ].style.left = this.position.left + "px";
+		}
+		if ( !this.options.axis || this.options.axis !== "x" ) {
+			this.helper[ 0 ].style.top = this.position.top + "px";
+		}
+
+		//Rearrange
+		for ( i = this.items.length - 1; i >= 0; i-- ) {
+
+			//Cache variables and intersection, continue if no intersection
+			item = this.items[ i ];
+			itemElement = item.item[ 0 ];
+			intersection = this._intersectsWithPointer( item );
+			if ( !intersection ) {
+				continue;
+			}
+
+			// Only put the placeholder inside the current Container, skip all
+			// items from other containers. This works because when moving
+			// an item from one container to another the
+			// currentContainer is switched before the placeholder is moved.
+			//
+			// Without this, moving items in "sub-sortables" can cause
+			// the placeholder to jitter between the outer and inner container.
+			if ( item.instance !== this.currentContainer ) {
+				continue;
+			}
+
+			// Cannot intersect with itself
+			// no useless actions that have been done before
+			// no action if the item moved is the parent of the item checked
+			if ( itemElement !== this.currentItem[ 0 ] &&
+				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
+				!$.contains( this.placeholder[ 0 ], itemElement ) &&
+				( this.options.type === "semi-dynamic" ?
+					!$.contains( this.element[ 0 ], itemElement ) :
+					true
+				)
+			) {
+
+				this.direction = intersection === 1 ? "down" : "up";
+
+				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
+					this._rearrange( event, item );
+				} else {
+					break;
+				}
+
+				this._trigger( "change", event, this._uiHash() );
+				break;
+			}
+		}
+
+		//Post events to containers
+		this._contactContainers( event );
+
+		//Interconnect with droppables
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.drag( this, event );
+		}
+
+		//Call callbacks
+		this._trigger( "sort", event, this._uiHash() );
+
+		this.lastPositionAbs = this.positionAbs;
+		return false;
+
+	},
+
+	_mouseStop: function( event, noPropagation ) {
+
+		if ( !event ) {
+			return;
+		}
+
+		//If we are using droppables, inform the manager about the drop
+		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
+			$.ui.ddmanager.drop( this, event );
+		}
+
+		if ( this.options.revert ) {
+			var that = this,
+				cur = this.placeholder.offset(),
+				axis = this.options.axis,
+				animation = {};
+
+			if ( !axis || axis === "x" ) {
+				animation.left = cur.left - this.offset.parent.left - this.margins.left +
+					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
+						0 :
+						this.offsetParent[ 0 ].scrollLeft
+					);
+			}
+			if ( !axis || axis === "y" ) {
+				animation.top = cur.top - this.offset.parent.top - this.margins.top +
+					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
+						0 :
+						this.offsetParent[ 0 ].scrollTop
+					);
+			}
+			this.reverting = true;
+			$( this.helper ).animate(
+				animation,
+				parseInt( this.options.revert, 10 ) || 500,
+				function() {
+					that._clear( event );
+				}
+			);
+		} else {
+			this._clear( event, noPropagation );
+		}
+
+		return false;
+
+	},
+
+	cancel: function() {
+
+		if ( this.dragging ) {
+
+			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
+
+			if ( this.options.helper === "original" ) {
+				this.currentItem.css( this._storedCSS );
+				this._removeClass( this.currentItem, "ui-sortable-helper" );
+			} else {
+				this.currentItem.show();
+			}
+
+			//Post deactivating events to containers
+			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
+				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
+				if ( this.containers[ i ].containerCache.over ) {
+					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
+					this.containers[ i ].containerCache.over = 0;
+				}
+			}
+
+		}
+
+		if ( this.placeholder ) {
+
+			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
+			// it unbinds ALL events from the original node!
+			if ( this.placeholder[ 0 ].parentNode ) {
+				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
+			}
+			if ( this.options.helper !== "original" && this.helper &&
+					this.helper[ 0 ].parentNode ) {
+				this.helper.remove();
+			}
+
+			$.extend( this, {
+				helper: null,
+				dragging: false,
+				reverting: false,
+				_noFinalSort: null
+			} );
+
+			if ( this.domPosition.prev ) {
+				$( this.domPosition.prev ).after( this.currentItem );
+			} else {
+				$( this.domPosition.parent ).prepend( this.currentItem );
+			}
+		}
+
+		return this;
+
+	},
+
+	serialize: function( o ) {
+
+		var items = this._getItemsAsjQuery( o && o.connected ),
+			str = [];
+		o = o || {};
+
+		$( items ).each( function() {
+			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
+				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
+			if ( res ) {
+				str.push(
+					( o.key || res[ 1 ] + "[]" ) +
+					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
+			}
+		} );
+
+		if ( !str.length && o.key ) {
+			str.push( o.key + "=" );
+		}
+
+		return str.join( "&" );
+
+	},
+
+	toArray: function( o ) {
+
+		var items = this._getItemsAsjQuery( o && o.connected ),
+			ret = [];
+
+		o = o || {};
+
+		items.each( function() {
+			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
+		} );
+		return ret;
+
+	},
+
+	/* Be careful with the following core functions */
+	_intersectsWith: function( item ) {
+
+		var x1 = this.positionAbs.left,
+			x2 = x1 + this.helperProportions.width,
+			y1 = this.positionAbs.top,
+			y2 = y1 + this.helperProportions.height,
+			l = item.left,
+			r = l + item.width,
+			t = item.top,
+			b = t + item.height,
+			dyClick = this.offset.click.top,
+			dxClick = this.offset.click.left,
+			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
+				( y1 + dyClick ) < b ),
+			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
+				( x1 + dxClick ) < r ),
+			isOverElement = isOverElementHeight && isOverElementWidth;
+
+		if ( this.options.tolerance === "pointer" ||
+			this.options.forcePointerForContainers ||
+			( this.options.tolerance !== "pointer" &&
+				this.helperProportions[ this.floating ? "width" : "height" ] >
+				item[ this.floating ? "width" : "height" ] )
+		) {
+			return isOverElement;
+		} else {
+
+			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
+				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
+				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
+				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
+
+		}
+	},
+
+	_intersectsWithPointer: function( item ) {
+		var verticalDirection, horizontalDirection,
+			isOverElementHeight = ( this.options.axis === "x" ) ||
+				this._isOverAxis(
+					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
+			isOverElementWidth = ( this.options.axis === "y" ) ||
+				this._isOverAxis(
+					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
+			isOverElement = isOverElementHeight && isOverElementWidth;
+
+		if ( !isOverElement ) {
+			return false;
+		}
+
+		verticalDirection = this._getDragVerticalDirection();
+		horizontalDirection = this._getDragHorizontalDirection();
+
+		return this.floating ?
+			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
+			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
+
+	},
+
+	_intersectsWithSides: function( item ) {
+
+		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
+				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
+			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
+				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
+			verticalDirection = this._getDragVerticalDirection(),
+			horizontalDirection = this._getDragHorizontalDirection();
+
+		if ( this.floating && horizontalDirection ) {
+			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
+				( horizontalDirection === "left" && !isOverRightHalf ) );
+		} else {
+			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
+				( verticalDirection === "up" && !isOverBottomHalf ) );
+		}
+
+	},
+
+	_getDragVerticalDirection: function() {
+		var delta = this.positionAbs.top - this.lastPositionAbs.top;
+		return delta !== 0 && ( delta > 0 ? "down" : "up" );
+	},
+
+	_getDragHorizontalDirection: function() {
+		var delta = this.positionAbs.left - this.lastPositionAbs.left;
+		return delta !== 0 && ( delta > 0 ? "right" : "left" );
+	},
+
+	refresh: function( event ) {
+		this._refreshItems( event );
+		this._setHandleClassName();
+		this.refreshPositions();
+		return this;
+	},
+
+	_connectWith: function() {
+		var options = this.options;
+		return options.connectWith.constructor === String ?
+			[ options.connectWith ] :
+			options.connectWith;
+	},
+
+	_getItemsAsjQuery: function( connected ) {
+
+		var i, j, cur, inst,
+			items = [],
+			queries = [],
+			connectWith = this._connectWith();
+
+		if ( connectWith && connected ) {
+			for ( i = connectWith.length - 1; i >= 0; i-- ) {
+				cur = $( connectWith[ i ], this.document[ 0 ] );
+				for ( j = cur.length - 1; j >= 0; j-- ) {
+					inst = $.data( cur[ j ], this.widgetFullName );
+					if ( inst && inst !== this && !inst.options.disabled ) {
+						queries.push( [ $.isFunction( inst.options.items ) ?
+							inst.options.items.call( inst.element ) :
+							$( inst.options.items, inst.element )
+								.not( ".ui-sortable-helper" )
+								.not( ".ui-sortable-placeholder" ), inst ] );
+					}
+				}
+			}
+		}
+
+		queries.push( [ $.isFunction( this.options.items ) ?
+			this.options.items
+				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
+			$( this.options.items, this.element )
+				.not( ".ui-sortable-helper" )
+				.not( ".ui-sortable-placeholder" ), this ] );
+
+		function addItems() {
+			items.push( this );
+		}
+		for ( i = queries.length - 1; i >= 0; i-- ) {
+			queries[ i ][ 0 ].each( addItems );
+		}
+
+		return $( items );
+
+	},
+
+	_removeCurrentsFromItems: function() {
+
+		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
+
+		this.items = $.grep( this.items, function( item ) {
+			for ( var j = 0; j < list.length; j++ ) {
+				if ( list[ j ] === item.item[ 0 ] ) {
+					return false;
+				}
+			}
+			return true;
+		} );
+
+	},
+
+	_refreshItems: function( event ) {
+
+		this.items = [];
+		this.containers = [ this ];
+
+		var i, j, cur, inst, targetData, _queries, item, queriesLength,
+			items = this.items,
+			queries = [ [ $.isFunction( this.options.items ) ?
+				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
+				$( this.options.items, this.element ), this ] ],
+			connectWith = this._connectWith();
+
+		//Shouldn't be run the first time through due to massive slow-down
+		if ( connectWith && this.ready ) {
+			for ( i = connectWith.length - 1; i >= 0; i-- ) {
+				cur = $( connectWith[ i ], this.document[ 0 ] );
+				for ( j = cur.length - 1; j >= 0; j-- ) {
+					inst = $.data( cur[ j ], this.widgetFullName );
+					if ( inst && inst !== this && !inst.options.disabled ) {
+						queries.push( [ $.isFunction( inst.options.items ) ?
+							inst.options.items
+								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
+							$( inst.options.items, inst.element ), inst ] );
+						this.containers.push( inst );
+					}
+				}
+			}
+		}
+
+		for ( i = queries.length - 1; i >= 0; i-- ) {
+			targetData = queries[ i ][ 1 ];
+			_queries = queries[ i ][ 0 ];
+
+			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
+				item = $( _queries[ j ] );
+
+				// Data for target checking (mouse manager)
+				item.data( this.widgetName + "-item", targetData );
+
+				items.push( {
+					item: item,
+					instance: targetData,
+					width: 0, height: 0,
+					left: 0, top: 0
+				} );
+			}
+		}
+
+	},
+
+	refreshPositions: function( fast ) {
+
+		// Determine whether items are being displayed horizontally
+		this.floating = this.items.length ?
+			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
+			false;
+
+		//This has to be redone because due to the item being moved out/into the offsetParent,
+		// the offsetParent's position will change
+		if ( this.offsetParent && this.helper ) {
+			this.offset.parent = this._getParentOffset();
+		}
+
+		var i, item, t, p;
+
+		for ( i = this.items.length - 1; i >= 0; i-- ) {
+			item = this.items[ i ];
+
+			//We ignore calculating positions of all connected containers when we're not over them
+			if ( item.instance !== this.currentContainer && this.currentContainer &&
+					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
+				continue;
+			}
+
+			t = this.options.toleranceElement ?
+				$( this.options.toleranceElement, item.item ) :
+				item.item;
+
+			if ( !fast ) {
+				item.width = t.outerWidth();
+				item.height = t.outerHeight();
+			}
+
+			p = t.offset();
+			item.left = p.left;
+			item.top = p.top;
+		}
+
+		if ( this.options.custom && this.options.custom.refreshContainers ) {
+			this.options.custom.refreshContainers.call( this );
+		} else {
+			for ( i = this.containers.length - 1; i >= 0; i-- ) {
+				p = this.containers[ i ].element.offset();
+				this.containers[ i ].containerCache.left = p.left;
+				this.containers[ i ].containerCache.top = p.top;
+				this.containers[ i ].containerCache.width =
+					this.containers[ i ].element.outerWidth();
+				this.containers[ i ].containerCache.height =
+					this.containers[ i ].element.outerHeight();
+			}
+		}
+
+		return this;
+	},
+
+	_createPlaceholder: function( that ) {
+		that = that || this;
+		var className,
+			o = that.options;
+
+		if ( !o.placeholder || o.placeholder.constructor === String ) {
+			className = o.placeholder;
+			o.placeholder = {
+				element: function() {
+
+					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
+						element = $( "<" + nodeName + ">", that.document[ 0 ] );
+
+						that._addClass( element, "ui-sortable-placeholder",
+								className || that.currentItem[ 0 ].className )
+							._removeClass( element, "ui-sortable-helper" );
+
+					if ( nodeName === "tbody" ) {
+						that._createTrPlaceholder(
+							that.currentItem.find( "tr" ).eq( 0 ),
+							$( "<tr>", that.document[ 0 ] ).appendTo( element )
+						);
+					} else if ( nodeName === "tr" ) {
+						that._createTrPlaceholder( that.currentItem, element );
+					} else if ( nodeName === "img" ) {
+						element.attr( "src", that.currentItem.attr( "src" ) );
+					}
+
+					if ( !className ) {
+						element.css( "visibility", "hidden" );
+					}
+
+					return element;
+				},
+				update: function( container, p ) {
+
+					// 1. If a className is set as 'placeholder option, we don't force sizes -
+					// the class is responsible for that
+					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
+					// class name is specified
+					if ( className && !o.forcePlaceholderSize ) {
+						return;
+					}
+
+					//If the element doesn't have a actual height by itself (without styles coming
+					// from a stylesheet), it receives the inline height from the dragged item
+					if ( !p.height() ) {
+						p.height(
+							that.currentItem.innerHeight() -
+							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
+							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
+					}
+					if ( !p.width() ) {
+						p.width(
+							that.currentItem.innerWidth() -
+							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
+							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
+					}
+				}
+			};
+		}
+
+		//Create the placeholder
+		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
+
+		//Append it after the actual current item
+		that.currentItem.after( that.placeholder );
+
+		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+		o.placeholder.update( that, that.placeholder );
+
+	},
+
+	_createTrPlaceholder: function( sourceTr, targetTr ) {
+		var that = this;
+
+		sourceTr.children().each( function() {
+			$( "<td>&#160;</td>", that.document[ 0 ] )
+				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
+				.appendTo( targetTr );
+		} );
+	},
+
+	_contactContainers: function( event ) {
+		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
+			floating, axis,
+			innermostContainer = null,
+			innermostIndex = null;
+
+		// Get innermost container that intersects with item
+		for ( i = this.containers.length - 1; i >= 0; i-- ) {
+
+			// Never consider a container that's located within the item itself
+			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
+				continue;
+			}
+
+			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
+
+				// If we've already found a container and it's more "inner" than this, then continue
+				if ( innermostContainer &&
+						$.contains(
+							this.containers[ i ].element[ 0 ],
+							innermostContainer.element[ 0 ] ) ) {
+					continue;
+				}
+
+				innermostContainer = this.containers[ i ];
+				innermostIndex = i;
+
+			} else {
+
+				// container doesn't intersect. trigger "out" event if necessary
+				if ( this.containers[ i ].containerCache.over ) {
+					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
+					this.containers[ i ].containerCache.over = 0;
+				}
+			}
+
+		}
+
+		// If no intersecting containers found, return
+		if ( !innermostContainer ) {
+			return;
+		}
+
+		// Move the item into the container if it's not there already
+		if ( this.containers.length === 1 ) {
+			if ( !this.containers[ innermostIndex ].containerCache.over ) {
+				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
+				this.containers[ innermostIndex ].containerCache.over = 1;
+			}
+		} else {
+
+			// When entering a new container, we will find the item with the least distance and
+			// append our item near it
+			dist = 10000;
+			itemWithLeastDistance = null;
+			floating = innermostContainer.floating || this._isFloating( this.currentItem );
+			posProperty = floating ? "left" : "top";
+			sizeProperty = floating ? "width" : "height";
+			axis = floating ? "pageX" : "pageY";
+
+			for ( j = this.items.length - 1; j >= 0; j-- ) {
+				if ( !$.contains(
+						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
+				) {
+					continue;
+				}
+				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
+					continue;
+				}
+
+				cur = this.items[ j ].item.offset()[ posProperty ];
+				nearBottom = false;
+				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
+					nearBottom = true;
+				}
+
+				if ( Math.abs( event[ axis ] - cur ) < dist ) {
+					dist = Math.abs( event[ axis ] - cur );
+					itemWithLeastDistance = this.items[ j ];
+					this.direction = nearBottom ? "up" : "down";
+				}
+			}
+
+			//Check if dropOnEmpty is enabled
+			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
+				return;
+			}
+
+			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
+				if ( !this.currentContainer.containerCache.over ) {
+					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
+					this.currentContainer.containerCache.over = 1;
+				}
+				return;
+			}
+
+			itemWithLeastDistance ?
+				this._rearrange( event, itemWithLeastDistance, null, true ) :
+				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
+			this._trigger( "change", event, this._uiHash() );
+			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
+			this.currentContainer = this.containers[ innermostIndex ];
+
+			//Update the placeholder
+			this.options.placeholder.update( this.currentContainer, this.placeholder );
+
+			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
+			this.containers[ innermostIndex ].containerCache.over = 1;
+		}
+
+	},
+
+	_createHelper: function( event ) {
+
+		var o = this.options,
+			helper = $.isFunction( o.helper ) ?
+				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
+				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
+
+		//Add the helper to the DOM if that didn't happen already
+		if ( !helper.parents( "body" ).length ) {
+			$( o.appendTo !== "parent" ?
+				o.appendTo :
+				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
+		}
+
+		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
+			this._storedCSS = {
+				width: this.currentItem[ 0 ].style.width,
+				height: this.currentItem[ 0 ].style.height,
+				position: this.currentItem.css( "position" ),
+				top: this.currentItem.css( "top" ),
+				left: this.currentItem.css( "left" )
+			};
+		}
+
+		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
+			helper.width( this.currentItem.width() );
+		}
+		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
+			helper.height( this.currentItem.height() );
+		}
+
+		return helper;
+
+	},
+
+	_adjustOffsetFromHelper: function( obj ) {
+		if ( typeof obj === "string" ) {
+			obj = obj.split( " " );
+		}
+		if ( $.isArray( obj ) ) {
+			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
+		}
+		if ( "left" in obj ) {
+			this.offset.click.left = obj.left + this.margins.left;
+		}
+		if ( "right" in obj ) {
+			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+		}
+		if ( "top" in obj ) {
+			this.offset.click.top = obj.top + this.margins.top;
+		}
+		if ( "bottom" in obj ) {
+			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+		}
+	},
+
+	_getParentOffset: function() {
+
+		//Get the offsetParent and cache its position
+		this.offsetParent = this.helper.offsetParent();
+		var po = this.offsetParent.offset();
+
+		// This is a special case where we need to modify a offset calculated on start, since the
+		// following happened:
+		// 1. The position of the helper is absolute, so it's position is calculated based on the
+		// next positioned parent
+		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
+		// the document, which means that the scroll is included in the initial calculation of the
+		// offset of the parent, and never recalculated upon drag
+		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
+			po.left += this.scrollParent.scrollLeft();
+			po.top += this.scrollParent.scrollTop();
+		}
+
+		// This needs to be actually done for all browsers, since pageX/pageY includes this
+		// information with an ugly IE fix
+		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
+				( this.offsetParent[ 0 ].tagName &&
+				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
+			po = { top: 0, left: 0 };
+		}
+
+		return {
+			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
+			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
+		};
+
+	},
+
+	_getRelativeOffset: function() {
+
+		if ( this.cssPosition === "relative" ) {
+			var p = this.currentItem.position();
+			return {
+				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
+					this.scrollParent.scrollTop(),
+				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
+					this.scrollParent.scrollLeft()
+			};
+		} else {
+			return { top: 0, left: 0 };
+		}
+
+	},
+
+	_cacheMargins: function() {
+		this.margins = {
+			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
+			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
+		};
+	},
+
+	_cacheHelperProportions: function() {
+		this.helperProportions = {
+			width: this.helper.outerWidth(),
+			height: this.helper.outerHeight()
+		};
+	},
+
+	_setContainment: function() {
+
+		var ce, co, over,
+			o = this.options;
+		if ( o.containment === "parent" ) {
+			o.containment = this.helper[ 0 ].parentNode;
+		}
+		if ( o.containment === "document" || o.containment === "window" ) {
+			this.containment = [
+				0 - this.offset.relative.left - this.offset.parent.left,
+				0 - this.offset.relative.top - this.offset.parent.top,
+				o.containment === "document" ?
+					this.document.width() :
+					this.window.width() - this.helperProportions.width - this.margins.left,
+				( o.containment === "document" ?
+					( this.document.height() || document.body.parentNode.scrollHeight ) :
+					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
+				) - this.helperProportions.height - this.margins.top
+			];
+		}
+
+		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
+			ce = $( o.containment )[ 0 ];
+			co = $( o.containment ).offset();
+			over = ( $( ce ).css( "overflow" ) !== "hidden" );
+
+			this.containment = [
+				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
+					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
+				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
+					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
+				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
+					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
+					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
+					this.helperProportions.width - this.margins.left,
+				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
+					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
+					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
+					this.helperProportions.height - this.margins.top
+			];
+		}
+
+	},
+
+	_convertPositionTo: function( d, pos ) {
+
+		if ( !pos ) {
+			pos = this.position;
+		}
+		var mod = d === "absolute" ? 1 : -1,
+			scroll = this.cssPosition === "absolute" &&
+				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
+					this.offsetParent :
+					this.scrollParent,
+			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
+
+		return {
+			top: (
+
+				// The absolute mouse position
+				pos.top	+
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top * mod -
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollTop() :
+					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
+			),
+			left: (
+
+				// The absolute mouse position
+				pos.left +
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left * mod	-
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
+					scroll.scrollLeft() ) * mod )
+			)
+		};
+
+	},
+
+	_generatePosition: function( event ) {
+
+		var top, left,
+			o = this.options,
+			pageX = event.pageX,
+			pageY = event.pageY,
+			scroll = this.cssPosition === "absolute" &&
+				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
+					this.offsetParent :
+					this.scrollParent,
+				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
+
+		// This is another very weird special case that only happens for relative elements:
+		// 1. If the css position is relative
+		// 2. and the scroll parent is the document or similar to the offset parent
+		// we have to refresh the relative offset during the scroll so there are no jumps
+		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
+			this.offset.relative = this._getRelativeOffset();
+		}
+
+		/*
+		 * - Position constraining -
+		 * Constrain the position to a mix of grid, containment.
+		 */
+
+		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
+
+			if ( this.containment ) {
+				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
+					pageX = this.containment[ 0 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
+					pageY = this.containment[ 1 ] + this.offset.click.top;
+				}
+				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
+					pageX = this.containment[ 2 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
+					pageY = this.containment[ 3 ] + this.offset.click.top;
+				}
+			}
+
+			if ( o.grid ) {
+				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
+					o.grid[ 1 ] ) * o.grid[ 1 ];
+				pageY = this.containment ?
+					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
+						top - this.offset.click.top <= this.containment[ 3 ] ) ?
+							top :
+							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
+								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
+								top;
+
+				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
+					o.grid[ 0 ] ) * o.grid[ 0 ];
+				pageX = this.containment ?
+					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
+						left - this.offset.click.left <= this.containment[ 2 ] ) ?
+							left :
+							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
+								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
+								left;
+			}
+
+		}
+
+		return {
+			top: (
+
+				// The absolute mouse position
+				pageY -
+
+				// Click offset (relative to the element)
+				this.offset.click.top -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top +
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollTop() :
+					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
+			),
+			left: (
+
+				// The absolute mouse position
+				pageX -
+
+				// Click offset (relative to the element)
+				this.offset.click.left -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left +
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollLeft() :
+					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
+			)
+		};
+
+	},
+
+	_rearrange: function( event, i, a, hardRefresh ) {
+
+		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
+			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
+				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
+
+		//Various things done here to improve the performance:
+		// 1. we create a setTimeout, that calls refreshPositions
+		// 2. on the instance, we have a counter variable, that get's higher after every append
+		// 3. on the local scope, we copy the counter variable, and check in the timeout,
+		// if it's still the same
+		// 4. this lets only the last addition to the timeout stack through
+		this.counter = this.counter ? ++this.counter : 1;
+		var counter = this.counter;
+
+		this._delay( function() {
+			if ( counter === this.counter ) {
+
+				//Precompute after each DOM insertion, NOT on mousemove
+				this.refreshPositions( !hardRefresh );
+			}
+		} );
+
+	},
+
+	_clear: function( event, noPropagation ) {
+
+		this.reverting = false;
+
+		// We delay all events that have to be triggered to after the point where the placeholder
+		// has been removed and everything else normalized again
+		var i,
+			delayedTriggers = [];
+
+		// We first have to update the dom position of the actual currentItem
+		// Note: don't do it if the current item is already removed (by a user), or it gets
+		// reappended (see #4088)
+		if ( !this._noFinalSort && this.currentItem.parent().length ) {
+			this.placeholder.before( this.currentItem );
+		}
+		this._noFinalSort = null;
+
+		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
+			for ( i in this._storedCSS ) {
+				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
+					this._storedCSS[ i ] = "";
+				}
+			}
+			this.currentItem.css( this._storedCSS );
+			this._removeClass( this.currentItem, "ui-sortable-helper" );
+		} else {
+			this.currentItem.show();
+		}
+
+		if ( this.fromOutside && !noPropagation ) {
+			delayedTriggers.push( function( event ) {
+				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
+			} );
+		}
+		if ( ( this.fromOutside ||
+				this.domPosition.prev !==
+				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
+				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
+
+			// Trigger update callback if the DOM position has changed
+			delayedTriggers.push( function( event ) {
+				this._trigger( "update", event, this._uiHash() );
+			} );
+		}
+
+		// Check if the items Container has Changed and trigger appropriate
+		// events.
+		if ( this !== this.currentContainer ) {
+			if ( !noPropagation ) {
+				delayedTriggers.push( function( event ) {
+					this._trigger( "remove", event, this._uiHash() );
+				} );
+				delayedTriggers.push( ( function( c ) {
+					return function( event ) {
+						c._trigger( "receive", event, this._uiHash( this ) );
+					};
+				} ).call( this, this.currentContainer ) );
+				delayedTriggers.push( ( function( c ) {
+					return function( event ) {
+						c._trigger( "update", event, this._uiHash( this ) );
+					};
+				} ).call( this, this.currentContainer ) );
+			}
+		}
+
+		//Post events to containers
+		function delayEvent( type, instance, container ) {
+			return function( event ) {
+				container._trigger( type, event, instance._uiHash( instance ) );
+			};
+		}
+		for ( i = this.containers.length - 1; i >= 0; i-- ) {
+			if ( !noPropagation ) {
+				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
+			}
+			if ( this.containers[ i ].containerCache.over ) {
+				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
+				this.containers[ i ].containerCache.over = 0;
+			}
+		}
+
+		//Do what was originally in plugins
+		if ( this.storedCursor ) {
+			this.document.find( "body" ).css( "cursor", this.storedCursor );
+			this.storedStylesheet.remove();
+		}
+		if ( this._storedOpacity ) {
+			this.helper.css( "opacity", this._storedOpacity );
+		}
+		if ( this._storedZIndex ) {
+			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
+		}
+
+		this.dragging = false;
+
+		if ( !noPropagation ) {
+			this._trigger( "beforeStop", event, this._uiHash() );
+		}
+
+		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
+		// it unbinds ALL events from the original node!
+		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
+
+		if ( !this.cancelHelperRemoval ) {
+			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
+				this.helper.remove();
+			}
+			this.helper = null;
+		}
+
+		if ( !noPropagation ) {
+			for ( i = 0; i < delayedTriggers.length; i++ ) {
+
+				// Trigger all delayed events
+				delayedTriggers[ i ].call( this, event );
+			}
+			this._trigger( "stop", event, this._uiHash() );
+		}
+
+		this.fromOutside = false;
+		return !this.cancelHelperRemoval;
+
+	},
+
+	_trigger: function() {
+		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
+			this.cancel();
+		}
+	},
+
+	_uiHash: function( _inst ) {
+		var inst = _inst || this;
+		return {
+			helper: inst.helper,
+			placeholder: inst.placeholder || $( [] ),
+			position: inst.position,
+			originalPosition: inst.originalPosition,
+			offset: inst.positionAbs,
+			item: inst.currentItem,
+			sender: _inst ? _inst.element : null
+		};
+	}
+
+} );
+
+
+/*!
+ * jQuery UI Spinner 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Highlight
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
-this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Pulsate 1.8.14
+
+//>>label: Spinner
+//>>group: Widgets
+//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
+//>>docs: http://api.jqueryui.com/spinner/
+//>>demos: http://jqueryui.com/spinner/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/spinner.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+function spinnerModifer( fn ) {
+	return function() {
+		var previous = this.element.val();
+		fn.apply( this, arguments );
+		this._refresh();
+		if ( previous !== this.element.val() ) {
+			this._trigger( "change" );
+		}
+	};
+}
+
+$.widget( "ui.spinner", {
+	version: "1.12.1",
+	defaultElement: "<input>",
+	widgetEventPrefix: "spin",
+	options: {
+		classes: {
+			"ui-spinner": "ui-corner-all",
+			"ui-spinner-down": "ui-corner-br",
+			"ui-spinner-up": "ui-corner-tr"
+		},
+		culture: null,
+		icons: {
+			down: "ui-icon-triangle-1-s",
+			up: "ui-icon-triangle-1-n"
+		},
+		incremental: true,
+		max: null,
+		min: null,
+		numberFormat: null,
+		page: 10,
+		step: 1,
+
+		change: null,
+		spin: null,
+		start: null,
+		stop: null
+	},
+
+	_create: function() {
+
+		// handle string values that need to be parsed
+		this._setOption( "max", this.options.max );
+		this._setOption( "min", this.options.min );
+		this._setOption( "step", this.options.step );
+
+		// Only format if there is a value, prevents the field from being marked
+		// as invalid in Firefox, see #9573.
+		if ( this.value() !== "" ) {
+
+			// Format the value, but don't constrain.
+			this._value( this.element.val(), true );
+		}
+
+		this._draw();
+		this._on( this._events );
+		this._refresh();
+
+		// Turning off autocomplete prevents the browser from remembering the
+		// value when navigating through history, so we re-enable autocomplete
+		// if the page is unloaded before the widget is destroyed. #7790
+		this._on( this.window, {
+			beforeunload: function() {
+				this.element.removeAttr( "autocomplete" );
+			}
+		} );
+	},
+
+	_getCreateOptions: function() {
+		var options = this._super();
+		var element = this.element;
+
+		$.each( [ "min", "max", "step" ], function( i, option ) {
+			var value = element.attr( option );
+			if ( value != null && value.length ) {
+				options[ option ] = value;
+			}
+		} );
+
+		return options;
+	},
+
+	_events: {
+		keydown: function( event ) {
+			if ( this._start( event ) && this._keydown( event ) ) {
+				event.preventDefault();
+			}
+		},
+		keyup: "_stop",
+		focus: function() {
+			this.previous = this.element.val();
+		},
+		blur: function( event ) {
+			if ( this.cancelBlur ) {
+				delete this.cancelBlur;
+				return;
+			}
+
+			this._stop();
+			this._refresh();
+			if ( this.previous !== this.element.val() ) {
+				this._trigger( "change", event );
+			}
+		},
+		mousewheel: function( event, delta ) {
+			if ( !delta ) {
+				return;
+			}
+			if ( !this.spinning && !this._start( event ) ) {
+				return false;
+			}
+
+			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
+			clearTimeout( this.mousewheelTimer );
+			this.mousewheelTimer = this._delay( function() {
+				if ( this.spinning ) {
+					this._stop( event );
+				}
+			}, 100 );
+			event.preventDefault();
+		},
+		"mousedown .ui-spinner-button": function( event ) {
+			var previous;
+
+			// We never want the buttons to have focus; whenever the user is
+			// interacting with the spinner, the focus should be on the input.
+			// If the input is focused then this.previous is properly set from
+			// when the input first received focus. If the input is not focused
+			// then we need to set this.previous based on the value before spinning.
+			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
+				this.previous : this.element.val();
+			function checkFocus() {
+				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
+				if ( !isActive ) {
+					this.element.trigger( "focus" );
+					this.previous = previous;
+
+					// support: IE
+					// IE sets focus asynchronously, so we need to check if focus
+					// moved off of the input because the user clicked on the button.
+					this._delay( function() {
+						this.previous = previous;
+					} );
+				}
+			}
+
+			// Ensure focus is on (or stays on) the text field
+			event.preventDefault();
+			checkFocus.call( this );
+
+			// Support: IE
+			// IE doesn't prevent moving focus even with event.preventDefault()
+			// so we set a flag to know when we should ignore the blur event
+			// and check (again) if focus moved off of the input.
+			this.cancelBlur = true;
+			this._delay( function() {
+				delete this.cancelBlur;
+				checkFocus.call( this );
+			} );
+
+			if ( this._start( event ) === false ) {
+				return;
+			}
+
+			this._repeat( null, $( event.currentTarget )
+				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+		},
+		"mouseup .ui-spinner-button": "_stop",
+		"mouseenter .ui-spinner-button": function( event ) {
+
+			// button will add ui-state-active if mouse was down while mouseleave and kept down
+			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
+				return;
+			}
+
+			if ( this._start( event ) === false ) {
+				return false;
+			}
+			this._repeat( null, $( event.currentTarget )
+				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
+		},
+
+		// TODO: do we really want to consider this a stop?
+		// shouldn't we just stop the repeater and wait until mouseup before
+		// we trigger the stop event?
+		"mouseleave .ui-spinner-button": "_stop"
+	},
+
+	// Support mobile enhanced option and make backcompat more sane
+	_enhance: function() {
+		this.uiSpinner = this.element
+			.attr( "autocomplete", "off" )
+			.wrap( "<span>" )
+			.parent()
+
+				// Add buttons
+				.append(
+					"<a></a><a></a>"
+				);
+	},
+
+	_draw: function() {
+		this._enhance();
+
+		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
+		this._addClass( "ui-spinner-input" );
+
+		this.element.attr( "role", "spinbutton" );
+
+		// Button bindings
+		this.buttons = this.uiSpinner.children( "a" )
+			.attr( "tabIndex", -1 )
+			.attr( "aria-hidden", true )
+			.button( {
+				classes: {
+					"ui-button": ""
+				}
+			} );
+
+		// TODO: Right now button does not support classes this is already updated in button PR
+		this._removeClass( this.buttons, "ui-corner-all" );
+
+		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
+		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
+		this.buttons.first().button( {
+			"icon": this.options.icons.up,
+			"showLabel": false
+		} );
+		this.buttons.last().button( {
+			"icon": this.options.icons.down,
+			"showLabel": false
+		} );
+
+		// IE 6 doesn't understand height: 50% for the buttons
+		// unless the wrapper has an explicit height
+		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
+				this.uiSpinner.height() > 0 ) {
+			this.uiSpinner.height( this.uiSpinner.height() );
+		}
+	},
+
+	_keydown: function( event ) {
+		var options = this.options,
+			keyCode = $.ui.keyCode;
+
+		switch ( event.keyCode ) {
+		case keyCode.UP:
+			this._repeat( null, 1, event );
+			return true;
+		case keyCode.DOWN:
+			this._repeat( null, -1, event );
+			return true;
+		case keyCode.PAGE_UP:
+			this._repeat( null, options.page, event );
+			return true;
+		case keyCode.PAGE_DOWN:
+			this._repeat( null, -options.page, event );
+			return true;
+		}
+
+		return false;
+	},
+
+	_start: function( event ) {
+		if ( !this.spinning && this._trigger( "start", event ) === false ) {
+			return false;
+		}
+
+		if ( !this.counter ) {
+			this.counter = 1;
+		}
+		this.spinning = true;
+		return true;
+	},
+
+	_repeat: function( i, steps, event ) {
+		i = i || 500;
+
+		clearTimeout( this.timer );
+		this.timer = this._delay( function() {
+			this._repeat( 40, steps, event );
+		}, i );
+
+		this._spin( steps * this.options.step, event );
+	},
+
+	_spin: function( step, event ) {
+		var value = this.value() || 0;
+
+		if ( !this.counter ) {
+			this.counter = 1;
+		}
+
+		value = this._adjustValue( value + step * this._increment( this.counter ) );
+
+		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
+			this._value( value );
+			this.counter++;
+		}
+	},
+
+	_increment: function( i ) {
+		var incremental = this.options.incremental;
+
+		if ( incremental ) {
+			return $.isFunction( incremental ) ?
+				incremental( i ) :
+				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
+		}
+
+		return 1;
+	},
+
+	_precision: function() {
+		var precision = this._precisionOf( this.options.step );
+		if ( this.options.min !== null ) {
+			precision = Math.max( precision, this._precisionOf( this.options.min ) );
+		}
+		return precision;
+	},
+
+	_precisionOf: function( num ) {
+		var str = num.toString(),
+			decimal = str.indexOf( "." );
+		return decimal === -1 ? 0 : str.length - decimal - 1;
+	},
+
+	_adjustValue: function( value ) {
+		var base, aboveMin,
+			options = this.options;
+
+		// Make sure we're at a valid step
+		// - find out where we are relative to the base (min or 0)
+		base = options.min !== null ? options.min : 0;
+		aboveMin = value - base;
+
+		// - round to the nearest step
+		aboveMin = Math.round( aboveMin / options.step ) * options.step;
+
+		// - rounding is based on 0, so adjust back to our base
+		value = base + aboveMin;
+
+		// Fix precision from bad JS floating point math
+		value = parseFloat( value.toFixed( this._precision() ) );
+
+		// Clamp the value
+		if ( options.max !== null && value > options.max ) {
+			return options.max;
+		}
+		if ( options.min !== null && value < options.min ) {
+			return options.min;
+		}
+
+		return value;
+	},
+
+	_stop: function( event ) {
+		if ( !this.spinning ) {
+			return;
+		}
+
+		clearTimeout( this.timer );
+		clearTimeout( this.mousewheelTimer );
+		this.counter = 0;
+		this.spinning = false;
+		this._trigger( "stop", event );
+	},
+
+	_setOption: function( key, value ) {
+		var prevValue, first, last;
+
+		if ( key === "culture" || key === "numberFormat" ) {
+			prevValue = this._parse( this.element.val() );
+			this.options[ key ] = value;
+			this.element.val( this._format( prevValue ) );
+			return;
+		}
+
+		if ( key === "max" || key === "min" || key === "step" ) {
+			if ( typeof value === "string" ) {
+				value = this._parse( value );
+			}
+		}
+		if ( key === "icons" ) {
+			first = this.buttons.first().find( ".ui-icon" );
+			this._removeClass( first, null, this.options.icons.up );
+			this._addClass( first, null, value.up );
+			last = this.buttons.last().find( ".ui-icon" );
+			this._removeClass( last, null, this.options.icons.down );
+			this._addClass( last, null, value.down );
+		}
+
+		this._super( key, value );
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
+		this.element.prop( "disabled", !!value );
+		this.buttons.button( value ? "disable" : "enable" );
+	},
+
+	_setOptions: spinnerModifer( function( options ) {
+		this._super( options );
+	} ),
+
+	_parse: function( val ) {
+		if ( typeof val === "string" && val !== "" ) {
+			val = window.Globalize && this.options.numberFormat ?
+				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
+		}
+		return val === "" || isNaN( val ) ? null : val;
+	},
+
+	_format: function( value ) {
+		if ( value === "" ) {
+			return "";
+		}
+		return window.Globalize && this.options.numberFormat ?
+			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
+			value;
+	},
+
+	_refresh: function() {
+		this.element.attr( {
+			"aria-valuemin": this.options.min,
+			"aria-valuemax": this.options.max,
+
+			// TODO: what should we do with values that can't be parsed?
+			"aria-valuenow": this._parse( this.element.val() )
+		} );
+	},
+
+	isValid: function() {
+		var value = this.value();
+
+		// Null is invalid
+		if ( value === null ) {
+			return false;
+		}
+
+		// If value gets adjusted, it's invalid
+		return value === this._adjustValue( value );
+	},
+
+	// Update the value without triggering change
+	_value: function( value, allowAny ) {
+		var parsed;
+		if ( value !== "" ) {
+			parsed = this._parse( value );
+			if ( parsed !== null ) {
+				if ( !allowAny ) {
+					parsed = this._adjustValue( parsed );
+				}
+				value = this._format( parsed );
+			}
+		}
+		this.element.val( value );
+		this._refresh();
+	},
+
+	_destroy: function() {
+		this.element
+			.prop( "disabled", false )
+			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
+
+		this.uiSpinner.replaceWith( this.element );
+	},
+
+	stepUp: spinnerModifer( function( steps ) {
+		this._stepUp( steps );
+	} ),
+	_stepUp: function( steps ) {
+		if ( this._start() ) {
+			this._spin( ( steps || 1 ) * this.options.step );
+			this._stop();
+		}
+	},
+
+	stepDown: spinnerModifer( function( steps ) {
+		this._stepDown( steps );
+	} ),
+	_stepDown: function( steps ) {
+		if ( this._start() ) {
+			this._spin( ( steps || 1 ) * -this.options.step );
+			this._stop();
+		}
+	},
+
+	pageUp: spinnerModifer( function( pages ) {
+		this._stepUp( ( pages || 1 ) * this.options.page );
+	} ),
+
+	pageDown: spinnerModifer( function( pages ) {
+		this._stepDown( ( pages || 1 ) * this.options.page );
+	} ),
+
+	value: function( newVal ) {
+		if ( !arguments.length ) {
+			return this._parse( this.element.val() );
+		}
+		spinnerModifer( this._value ).call( this, newVal );
+	},
+
+	widget: function() {
+		return this.uiSpinner;
+	}
+} );
+
+// DEPRECATED
+// TODO: switch return back to widget declaration at top of file when this is removed
+if ( $.uiBackCompat !== false ) {
+
+	// Backcompat for spinner html extension points
+	$.widget( "ui.spinner", $.ui.spinner, {
+		_enhance: function() {
+			this.uiSpinner = this.element
+				.attr( "autocomplete", "off" )
+				.wrap( this._uiSpinnerHtml() )
+				.parent()
+
+					// Add buttons
+					.append( this._buttonHtml() );
+		},
+		_uiSpinnerHtml: function() {
+			return "<span>";
+		},
+
+		_buttonHtml: function() {
+			return "<a></a><a></a>";
+		}
+	} );
+}
+
+var widgetsSpinner = $.ui.spinner;
+
+
+/*!
+ * jQuery UI Tabs 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Pulsate
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c<times;c++){b.animate({opacity:animateTo},duration,a.options.easing);animateTo=(animateTo+1)%2}b.animate({opacity:animateTo},duration,
-a.options.easing,function(){animateTo==0&&b.hide();a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()}).dequeue()})}})(jQuery);
-;/*
- * jQuery UI Effects Scale 1.8.14
+
+//>>label: Tabs
+//>>group: Widgets
+//>>description: Transforms a set of container elements into a tab structure.
+//>>docs: http://api.jqueryui.com/tabs/
+//>>demos: http://jqueryui.com/tabs/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/tabs.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.tabs", {
+	version: "1.12.1",
+	delay: 300,
+	options: {
+		active: null,
+		classes: {
+			"ui-tabs": "ui-corner-all",
+			"ui-tabs-nav": "ui-corner-all",
+			"ui-tabs-panel": "ui-corner-bottom",
+			"ui-tabs-tab": "ui-corner-top"
+		},
+		collapsible: false,
+		event: "click",
+		heightStyle: "content",
+		hide: null,
+		show: null,
+
+		// Callbacks
+		activate: null,
+		beforeActivate: null,
+		beforeLoad: null,
+		load: null
+	},
+
+	_isLocal: ( function() {
+		var rhash = /#.*$/;
+
+		return function( anchor ) {
+			var anchorUrl, locationUrl;
+
+			anchorUrl = anchor.href.replace( rhash, "" );
+			locationUrl = location.href.replace( rhash, "" );
+
+			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
+			try {
+				anchorUrl = decodeURIComponent( anchorUrl );
+			} catch ( error ) {}
+			try {
+				locationUrl = decodeURIComponent( locationUrl );
+			} catch ( error ) {}
+
+			return anchor.hash.length > 1 && anchorUrl === locationUrl;
+		};
+	} )(),
+
+	_create: function() {
+		var that = this,
+			options = this.options;
+
+		this.running = false;
+
+		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
+		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
+
+		this._processTabs();
+		options.active = this._initialActive();
+
+		// Take disabling tabs via class attribute from HTML
+		// into account and update option properly.
+		if ( $.isArray( options.disabled ) ) {
+			options.disabled = $.unique( options.disabled.concat(
+				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
+					return that.tabs.index( li );
+				} )
+			) ).sort();
+		}
+
+		// Check for length avoids error when initializing empty list
+		if ( this.options.active !== false && this.anchors.length ) {
+			this.active = this._findActive( options.active );
+		} else {
+			this.active = $();
+		}
+
+		this._refresh();
+
+		if ( this.active.length ) {
+			this.load( options.active );
+		}
+	},
+
+	_initialActive: function() {
+		var active = this.options.active,
+			collapsible = this.options.collapsible,
+			locationHash = location.hash.substring( 1 );
+
+		if ( active === null ) {
+
+			// check the fragment identifier in the URL
+			if ( locationHash ) {
+				this.tabs.each( function( i, tab ) {
+					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+						active = i;
+						return false;
+					}
+				} );
+			}
+
+			// Check for a tab marked active via a class
+			if ( active === null ) {
+				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
+			}
+
+			// No active tab, set to false
+			if ( active === null || active === -1 ) {
+				active = this.tabs.length ? 0 : false;
+			}
+		}
+
+		// Handle numbers: negative, out of range
+		if ( active !== false ) {
+			active = this.tabs.index( this.tabs.eq( active ) );
+			if ( active === -1 ) {
+				active = collapsible ? false : 0;
+			}
+		}
+
+		// Don't allow collapsible: false and active: false
+		if ( !collapsible && active === false && this.anchors.length ) {
+			active = 0;
+		}
+
+		return active;
+	},
+
+	_getCreateEventData: function() {
+		return {
+			tab: this.active,
+			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
+		};
+	},
+
+	_tabKeydown: function( event ) {
+		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
+			selectedIndex = this.tabs.index( focusedTab ),
+			goingForward = true;
+
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		switch ( event.keyCode ) {
+		case $.ui.keyCode.RIGHT:
+		case $.ui.keyCode.DOWN:
+			selectedIndex++;
+			break;
+		case $.ui.keyCode.UP:
+		case $.ui.keyCode.LEFT:
+			goingForward = false;
+			selectedIndex--;
+			break;
+		case $.ui.keyCode.END:
+			selectedIndex = this.anchors.length - 1;
+			break;
+		case $.ui.keyCode.HOME:
+			selectedIndex = 0;
+			break;
+		case $.ui.keyCode.SPACE:
+
+			// Activate only, no collapsing
+			event.preventDefault();
+			clearTimeout( this.activating );
+			this._activate( selectedIndex );
+			return;
+		case $.ui.keyCode.ENTER:
+
+			// Toggle (cancel delayed activation, allow collapsing)
+			event.preventDefault();
+			clearTimeout( this.activating );
+
+			// Determine if we should collapse or activate
+			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
+			return;
+		default:
+			return;
+		}
+
+		// Focus the appropriate tab, based on which key was pressed
+		event.preventDefault();
+		clearTimeout( this.activating );
+		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
+
+		// Navigating with control/command key will prevent automatic activation
+		if ( !event.ctrlKey && !event.metaKey ) {
+
+			// Update aria-selected immediately so that AT think the tab is already selected.
+			// Otherwise AT may confuse the user by stating that they need to activate the tab,
+			// but the tab will already be activated by the time the announcement finishes.
+			focusedTab.attr( "aria-selected", "false" );
+			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
+
+			this.activating = this._delay( function() {
+				this.option( "active", selectedIndex );
+			}, this.delay );
+		}
+	},
+
+	_panelKeydown: function( event ) {
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		// Ctrl+up moves focus to the current tab
+		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
+			event.preventDefault();
+			this.active.trigger( "focus" );
+		}
+	},
+
+	// Alt+page up/down moves focus to the previous/next tab (and activates)
+	_handlePageNav: function( event ) {
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
+			this._activate( this._focusNextTab( this.options.active - 1, false ) );
+			return true;
+		}
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
+			this._activate( this._focusNextTab( this.options.active + 1, true ) );
+			return true;
+		}
+	},
+
+	_findNextTab: function( index, goingForward ) {
+		var lastTabIndex = this.tabs.length - 1;
+
+		function constrain() {
+			if ( index > lastTabIndex ) {
+				index = 0;
+			}
+			if ( index < 0 ) {
+				index = lastTabIndex;
+			}
+			return index;
+		}
+
+		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
+			index = goingForward ? index + 1 : index - 1;
+		}
+
+		return index;
+	},
+
+	_focusNextTab: function( index, goingForward ) {
+		index = this._findNextTab( index, goingForward );
+		this.tabs.eq( index ).trigger( "focus" );
+		return index;
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "active" ) {
+
+			// _activate() will handle invalid values and update this.options
+			this._activate( value );
+			return;
+		}
+
+		this._super( key, value );
+
+		if ( key === "collapsible" ) {
+			this._toggleClass( "ui-tabs-collapsible", null, value );
+
+			// Setting collapsible: false while collapsed; open first panel
+			if ( !value && this.options.active === false ) {
+				this._activate( 0 );
+			}
+		}
+
+		if ( key === "event" ) {
+			this._setupEvents( value );
+		}
+
+		if ( key === "heightStyle" ) {
+			this._setupHeightStyle( value );
+		}
+	},
+
+	_sanitizeSelector: function( hash ) {
+		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+	},
+
+	refresh: function() {
+		var options = this.options,
+			lis = this.tablist.children( ":has(a[href])" );
+
+		// Get disabled tabs from class attribute from HTML
+		// this will get converted to a boolean if needed in _refresh()
+		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
+			return lis.index( tab );
+		} );
+
+		this._processTabs();
+
+		// Was collapsed or no tabs
+		if ( options.active === false || !this.anchors.length ) {
+			options.active = false;
+			this.active = $();
+
+		// was active, but active tab is gone
+		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
+
+			// all remaining tabs are disabled
+			if ( this.tabs.length === options.disabled.length ) {
+				options.active = false;
+				this.active = $();
+
+			// activate previous tab
+			} else {
+				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
+			}
+
+		// was active, active tab still exists
+		} else {
+
+			// make sure active index is correct
+			options.active = this.tabs.index( this.active );
+		}
+
+		this._refresh();
+	},
+
+	_refresh: function() {
+		this._setOptionDisabled( this.options.disabled );
+		this._setupEvents( this.options.event );
+		this._setupHeightStyle( this.options.heightStyle );
+
+		this.tabs.not( this.active ).attr( {
+			"aria-selected": "false",
+			"aria-expanded": "false",
+			tabIndex: -1
+		} );
+		this.panels.not( this._getPanelForTab( this.active ) )
+			.hide()
+			.attr( {
+				"aria-hidden": "true"
+			} );
+
+		// Make sure one tab is in the tab order
+		if ( !this.active.length ) {
+			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
+		} else {
+			this.active
+				.attr( {
+					"aria-selected": "true",
+					"aria-expanded": "true",
+					tabIndex: 0
+				} );
+			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
+			this._getPanelForTab( this.active )
+				.show()
+				.attr( {
+					"aria-hidden": "false"
+				} );
+		}
+	},
+
+	_processTabs: function() {
+		var that = this,
+			prevTabs = this.tabs,
+			prevAnchors = this.anchors,
+			prevPanels = this.panels;
+
+		this.tablist = this._getList().attr( "role", "tablist" );
+		this._addClass( this.tablist, "ui-tabs-nav",
+			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
+
+		// Prevent users from focusing disabled tabs via click
+		this.tablist
+			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
+				if ( $( this ).is( ".ui-state-disabled" ) ) {
+					event.preventDefault();
+				}
+			} )
+
+			// Support: IE <9
+			// Preventing the default action in mousedown doesn't prevent IE
+			// from focusing the element, so if the anchor gets focused, blur.
+			// We don't have to worry about focusing the previously focused
+			// element since clicking on a non-focusable element should focus
+			// the body anyway.
+			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
+				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
+					this.blur();
+				}
+			} );
+
+		this.tabs = this.tablist.find( "> li:has(a[href])" )
+			.attr( {
+				role: "tab",
+				tabIndex: -1
+			} );
+		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
+
+		this.anchors = this.tabs.map( function() {
+			return $( "a", this )[ 0 ];
+		} )
+			.attr( {
+				role: "presentation",
+				tabIndex: -1
+			} );
+		this._addClass( this.anchors, "ui-tabs-anchor" );
+
+		this.panels = $();
+
+		this.anchors.each( function( i, anchor ) {
+			var selector, panel, panelId,
+				anchorId = $( anchor ).uniqueId().attr( "id" ),
+				tab = $( anchor ).closest( "li" ),
+				originalAriaControls = tab.attr( "aria-controls" );
+
+			// Inline tab
+			if ( that._isLocal( anchor ) ) {
+				selector = anchor.hash;
+				panelId = selector.substring( 1 );
+				panel = that.element.find( that._sanitizeSelector( selector ) );
+
+			// remote tab
+			} else {
+
+				// If the tab doesn't already have aria-controls,
+				// generate an id by using a throw-away element
+				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
+				selector = "#" + panelId;
+				panel = that.element.find( selector );
+				if ( !panel.length ) {
+					panel = that._createPanel( panelId );
+					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
+				}
+				panel.attr( "aria-live", "polite" );
+			}
+
+			if ( panel.length ) {
+				that.panels = that.panels.add( panel );
+			}
+			if ( originalAriaControls ) {
+				tab.data( "ui-tabs-aria-controls", originalAriaControls );
+			}
+			tab.attr( {
+				"aria-controls": panelId,
+				"aria-labelledby": anchorId
+			} );
+			panel.attr( "aria-labelledby", anchorId );
+		} );
+
+		this.panels.attr( "role", "tabpanel" );
+		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
+
+		// Avoid memory leaks (#10056)
+		if ( prevTabs ) {
+			this._off( prevTabs.not( this.tabs ) );
+			this._off( prevAnchors.not( this.anchors ) );
+			this._off( prevPanels.not( this.panels ) );
+		}
+	},
+
+	// Allow overriding how to find the list for rare usage scenarios (#7715)
+	_getList: function() {
+		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
+	},
+
+	_createPanel: function( id ) {
+		return $( "<div>" )
+			.attr( "id", id )
+			.data( "ui-tabs-destroy", true );
+	},
+
+	_setOptionDisabled: function( disabled ) {
+		var currentItem, li, i;
+
+		if ( $.isArray( disabled ) ) {
+			if ( !disabled.length ) {
+				disabled = false;
+			} else if ( disabled.length === this.anchors.length ) {
+				disabled = true;
+			}
+		}
+
+		// Disable tabs
+		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
+			currentItem = $( li );
+			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
+				currentItem.attr( "aria-disabled", "true" );
+				this._addClass( currentItem, null, "ui-state-disabled" );
+			} else {
+				currentItem.removeAttr( "aria-disabled" );
+				this._removeClass( currentItem, null, "ui-state-disabled" );
+			}
+		}
+
+		this.options.disabled = disabled;
+
+		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
+			disabled === true );
+	},
+
+	_setupEvents: function( event ) {
+		var events = {};
+		if ( event ) {
+			$.each( event.split( " " ), function( index, eventName ) {
+				events[ eventName ] = "_eventHandler";
+			} );
+		}
+
+		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
+
+		// Always prevent the default action, even when disabled
+		this._on( true, this.anchors, {
+			click: function( event ) {
+				event.preventDefault();
+			}
+		} );
+		this._on( this.anchors, events );
+		this._on( this.tabs, { keydown: "_tabKeydown" } );
+		this._on( this.panels, { keydown: "_panelKeydown" } );
+
+		this._focusable( this.tabs );
+		this._hoverable( this.tabs );
+	},
+
+	_setupHeightStyle: function( heightStyle ) {
+		var maxHeight,
+			parent = this.element.parent();
+
+		if ( heightStyle === "fill" ) {
+			maxHeight = parent.height();
+			maxHeight -= this.element.outerHeight() - this.element.height();
+
+			this.element.siblings( ":visible" ).each( function() {
+				var elem = $( this ),
+					position = elem.css( "position" );
+
+				if ( position === "absolute" || position === "fixed" ) {
+					return;
+				}
+				maxHeight -= elem.outerHeight( true );
+			} );
+
+			this.element.children().not( this.panels ).each( function() {
+				maxHeight -= $( this ).outerHeight( true );
+			} );
+
+			this.panels.each( function() {
+				$( this ).height( Math.max( 0, maxHeight -
+					$( this ).innerHeight() + $( this ).height() ) );
+			} )
+				.css( "overflow", "auto" );
+		} else if ( heightStyle === "auto" ) {
+			maxHeight = 0;
+			this.panels.each( function() {
+				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+			} ).height( maxHeight );
+		}
+	},
+
+	_eventHandler: function( event ) {
+		var options = this.options,
+			active = this.active,
+			anchor = $( event.currentTarget ),
+			tab = anchor.closest( "li" ),
+			clickedIsActive = tab[ 0 ] === active[ 0 ],
+			collapsing = clickedIsActive && options.collapsible,
+			toShow = collapsing ? $() : this._getPanelForTab( tab ),
+			toHide = !active.length ? $() : this._getPanelForTab( active ),
+			eventData = {
+				oldTab: active,
+				oldPanel: toHide,
+				newTab: collapsing ? $() : tab,
+				newPanel: toShow
+			};
+
+		event.preventDefault();
+
+		if ( tab.hasClass( "ui-state-disabled" ) ||
+
+				// tab is already loading
+				tab.hasClass( "ui-tabs-loading" ) ||
+
+				// can't switch durning an animation
+				this.running ||
+
+				// click on active header, but not collapsible
+				( clickedIsActive && !options.collapsible ) ||
+
+				// allow canceling activation
+				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+			return;
+		}
+
+		options.active = collapsing ? false : this.tabs.index( tab );
+
+		this.active = clickedIsActive ? $() : tab;
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		if ( !toHide.length && !toShow.length ) {
+			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
+		}
+
+		if ( toShow.length ) {
+			this.load( this.tabs.index( tab ), event );
+		}
+		this._toggle( event, eventData );
+	},
+
+	// Handles show/hide for selecting tabs
+	_toggle: function( event, eventData ) {
+		var that = this,
+			toShow = eventData.newPanel,
+			toHide = eventData.oldPanel;
+
+		this.running = true;
+
+		function complete() {
+			that.running = false;
+			that._trigger( "activate", event, eventData );
+		}
+
+		function show() {
+			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
+
+			if ( toShow.length && that.options.show ) {
+				that._show( toShow, that.options.show, complete );
+			} else {
+				toShow.show();
+				complete();
+			}
+		}
+
+		// Start out by hiding, then showing, then completing
+		if ( toHide.length && this.options.hide ) {
+			this._hide( toHide, this.options.hide, function() {
+				that._removeClass( eventData.oldTab.closest( "li" ),
+					"ui-tabs-active", "ui-state-active" );
+				show();
+			} );
+		} else {
+			this._removeClass( eventData.oldTab.closest( "li" ),
+				"ui-tabs-active", "ui-state-active" );
+			toHide.hide();
+			show();
+		}
+
+		toHide.attr( "aria-hidden", "true" );
+		eventData.oldTab.attr( {
+			"aria-selected": "false",
+			"aria-expanded": "false"
+		} );
+
+		// If we're switching tabs, remove the old tab from the tab order.
+		// If we're opening from collapsed state, remove the previous tab from the tab order.
+		// If we're collapsing, then keep the collapsing tab in the tab order.
+		if ( toShow.length && toHide.length ) {
+			eventData.oldTab.attr( "tabIndex", -1 );
+		} else if ( toShow.length ) {
+			this.tabs.filter( function() {
+				return $( this ).attr( "tabIndex" ) === 0;
+			} )
+				.attr( "tabIndex", -1 );
+		}
+
+		toShow.attr( "aria-hidden", "false" );
+		eventData.newTab.attr( {
+			"aria-selected": "true",
+			"aria-expanded": "true",
+			tabIndex: 0
+		} );
+	},
+
+	_activate: function( index ) {
+		var anchor,
+			active = this._findActive( index );
+
+		// Trying to activate the already active panel
+		if ( active[ 0 ] === this.active[ 0 ] ) {
+			return;
+		}
+
+		// Trying to collapse, simulate a click on the current active header
+		if ( !active.length ) {
+			active = this.active;
+		}
+
+		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
+		this._eventHandler( {
+			target: anchor,
+			currentTarget: anchor,
+			preventDefault: $.noop
+		} );
+	},
+
+	_findActive: function( index ) {
+		return index === false ? $() : this.tabs.eq( index );
+	},
+
+	_getIndex: function( index ) {
+
+		// meta-function to give users option to provide a href string instead of a numerical index.
+		if ( typeof index === "string" ) {
+			index = this.anchors.index( this.anchors.filter( "[href$='" +
+				$.ui.escapeSelector( index ) + "']" ) );
+		}
+
+		return index;
+	},
+
+	_destroy: function() {
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		this.tablist
+			.removeAttr( "role" )
+			.off( this.eventNamespace );
+
+		this.anchors
+			.removeAttr( "role tabIndex" )
+			.removeUniqueId();
+
+		this.tabs.add( this.panels ).each( function() {
+			if ( $.data( this, "ui-tabs-destroy" ) ) {
+				$( this ).remove();
+			} else {
+				$( this ).removeAttr( "role tabIndex " +
+					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
+			}
+		} );
+
+		this.tabs.each( function() {
+			var li = $( this ),
+				prev = li.data( "ui-tabs-aria-controls" );
+			if ( prev ) {
+				li
+					.attr( "aria-controls", prev )
+					.removeData( "ui-tabs-aria-controls" );
+			} else {
+				li.removeAttr( "aria-controls" );
+			}
+		} );
+
+		this.panels.show();
+
+		if ( this.options.heightStyle !== "content" ) {
+			this.panels.css( "height", "" );
+		}
+	},
+
+	enable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === false ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = false;
+		} else {
+			index = this._getIndex( index );
+			if ( $.isArray( disabled ) ) {
+				disabled = $.map( disabled, function( num ) {
+					return num !== index ? num : null;
+				} );
+			} else {
+				disabled = $.map( this.tabs, function( li, num ) {
+					return num !== index ? num : null;
+				} );
+			}
+		}
+		this._setOptionDisabled( disabled );
+	},
+
+	disable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === true ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = true;
+		} else {
+			index = this._getIndex( index );
+			if ( $.inArray( index, disabled ) !== -1 ) {
+				return;
+			}
+			if ( $.isArray( disabled ) ) {
+				disabled = $.merge( [ index ], disabled ).sort();
+			} else {
+				disabled = [ index ];
+			}
+		}
+		this._setOptionDisabled( disabled );
+	},
+
+	load: function( index, event ) {
+		index = this._getIndex( index );
+		var that = this,
+			tab = this.tabs.eq( index ),
+			anchor = tab.find( ".ui-tabs-anchor" ),
+			panel = this._getPanelForTab( tab ),
+			eventData = {
+				tab: tab,
+				panel: panel
+			},
+			complete = function( jqXHR, status ) {
+				if ( status === "abort" ) {
+					that.panels.stop( false, true );
+				}
+
+				that._removeClass( tab, "ui-tabs-loading" );
+				panel.removeAttr( "aria-busy" );
+
+				if ( jqXHR === that.xhr ) {
+					delete that.xhr;
+				}
+			};
+
+		// Not remote
+		if ( this._isLocal( anchor[ 0 ] ) ) {
+			return;
+		}
+
+		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
+
+		// Support: jQuery <1.8
+		// jQuery <1.8 returns false if the request is canceled in beforeSend,
+		// but as of 1.8, $.ajax() always returns a jqXHR object.
+		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
+			this._addClass( tab, "ui-tabs-loading" );
+			panel.attr( "aria-busy", "true" );
+
+			this.xhr
+				.done( function( response, status, jqXHR ) {
+
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout( function() {
+						panel.html( response );
+						that._trigger( "load", event, eventData );
+
+						complete( jqXHR, status );
+					}, 1 );
+				} )
+				.fail( function( jqXHR, status ) {
+
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout( function() {
+						complete( jqXHR, status );
+					}, 1 );
+				} );
+		}
+	},
+
+	_ajaxSettings: function( anchor, event, eventData ) {
+		var that = this;
+		return {
+
+			// Support: IE <11 only
+			// Strip any hash that exists to prevent errors with the Ajax request
+			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
+			beforeSend: function( jqXHR, settings ) {
+				return that._trigger( "beforeLoad", event,
+					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
+			}
+		};
+	},
+
+	_getPanelForTab: function( tab ) {
+		var id = $( tab ).attr( "aria-controls" );
+		return this.element.find( this._sanitizeSelector( "#" + id ) );
+	}
+} );
+
+// DEPRECATED
+// TODO: Switch return back to widget declaration at top of file when this is removed
+if ( $.uiBackCompat !== false ) {
+
+	// Backcompat for ui-tab class (now ui-tabs-tab)
+	$.widget( "ui.tabs", $.ui.tabs, {
+		_processTabs: function() {
+			this._superApply( arguments );
+			this._addClass( this.tabs, "ui-tab" );
+		}
+	} );
+}
+
+var widgetsTabs = $.ui.tabs;
+
+
+/*!
+ * jQuery UI Tooltip 1.12.1
+ * http://jqueryui.com
  *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Scale
- *
- * Depends:
- *	jquery.effects.core.js
  */
-(function(c){c.effects.puff=function(b){return this.queue(function(){var a=c(this),e=c.effects.setMode(a,b.options.mode||"hide"),g=parseInt(b.options.percent,10)||150,h=g/100,i={height:a.height(),width:a.width()};c.extend(b.options,{fade:true,mode:e,percent:e=="hide"?g:100,from:e=="hide"?i:{height:i.height*h,width:i.width*h}});a.effect("scale",b.options,b.duration,b.callback);a.dequeue()})};c.effects.scale=function(b){return this.queue(function(){var a=c(this),e=c.extend(true,{},b.options),g=c.effects.setMode(a,
-b.options.mode||"effect"),h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:g=="hide"?0:100),i=b.options.direction||"both",f=b.options.origin;if(g!="effect"){e.origin=f||["middle","center"];e.restore=true}f={height:a.height(),width:a.width()};a.from=b.options.from||(g=="show"?{height:0,width:0}:f);h={y:i!="horizontal"?h/100:1,x:i!="vertical"?h/100:1};a.to={height:f.height*h.y,width:f.width*h.x};if(b.options.fade){if(g=="show"){a.from.opacity=0;a.to.opacity=1}if(g=="hide"){a.from.opacity=
-1;a.to.opacity=0}}e.from=a.from;e.to=a.to;e.mode=g;a.effect("size",e,b.duration,b.callback);a.dequeue()})};c.effects.size=function(b){return this.queue(function(){var a=c(this),e=["position","top","bottom","left","right","width","height","overflow","opacity"],g=["position","top","bottom","left","right","overflow","opacity"],h=["width","height","overflow"],i=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],
-p=c.effects.setMode(a,b.options.mode||"effect"),n=b.options.restore||false,m=b.options.scale||"both",l=b.options.origin,j={height:a.height(),width:a.width()};a.from=b.options.from||j;a.to=b.options.to||j;if(l){l=c.effects.getBaseline(l,j);a.from.top=(j.height-a.from.height)*l.y;a.from.left=(j.width-a.from.width)*l.x;a.to.top=(j.height-a.to.height)*l.y;a.to.left=(j.width-a.to.width)*l.x}var d={from:{y:a.from.height/j.height,x:a.from.width/j.width},to:{y:a.to.height/j.height,x:a.to.width/j.width}};
-if(m=="box"||m=="both"){if(d.from.y!=d.to.y){e=e.concat(f);a.from=c.effects.setTransition(a,f,d.from.y,a.from);a.to=c.effects.setTransition(a,f,d.to.y,a.to)}if(d.from.x!=d.to.x){e=e.concat(k);a.from=c.effects.setTransition(a,k,d.from.x,a.from);a.to=c.effects.setTransition(a,k,d.to.x,a.to)}}if(m=="content"||m=="both")if(d.from.y!=d.to.y){e=e.concat(i);a.from=c.effects.setTransition(a,i,d.from.y,a.from);a.to=c.effects.setTransition(a,i,d.to.y,a.to)}c.effects.save(a,n?e:g);a.show();c.effects.createWrapper(a);
-a.css("overflow","hidden").css(a.from);if(m=="content"||m=="both"){f=f.concat(["marginTop","marginBottom"]).concat(i);k=k.concat(["marginLeft","marginRight"]);h=e.concat(f).concat(k);a.find("*[width]").each(function(){child=c(this);n&&c.effects.save(child,h);var o={height:child.height(),width:child.width()};child.from={height:o.height*d.from.y,width:o.width*d.from.x};child.to={height:o.height*d.to.y,width:o.width*d.to.x};if(d.from.y!=d.to.y){child.from=c.effects.setTransition(child,f,d.from.y,child.from);
-child.to=c.effects.setTransition(child,f,d.to.y,child.to)}if(d.from.x!=d.to.x){child.from=c.effects.setTransition(child,k,d.from.x,child.from);child.to=c.effects.setTransition(child,k,d.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){n&&c.effects.restore(child,h)})})}a.animate(a.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){a.to.opacity===0&&a.css("opacity",a.from.opacity);p=="hide"&&a.hide();c.effects.restore(a,
-n?e:g);c.effects.removeWrapper(a);b.callback&&b.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Shake 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Shake
- *
- * Depends:
- *	jquery.effects.core.js
- */
-(function(d){d.effects.shake=function(a){return this.queue(function(){var b=d(this),j=["position","top","bottom","left","right"];d.effects.setMode(b,a.options.mode||"effect");var c=a.options.direction||"left",e=a.options.distance||20,l=a.options.times||3,f=a.duration||a.options.duration||140;d.effects.save(b,j);b.show();d.effects.createWrapper(b);var g=c=="up"||c=="down"?"top":"left",h=c=="up"||c=="left"?"pos":"neg";c={};var i={},k={};c[g]=(h=="pos"?"-=":"+=")+e;i[g]=(h=="pos"?"+=":"-=")+e*2;k[g]=
-(h=="pos"?"-=":"+=")+e*2;b.animate(c,f,a.options.easing);for(e=1;e<l;e++)b.animate(i,f,a.options.easing).animate(k,f,a.options.easing);b.animate(i,f,a.options.easing).animate(c,f/2,a.options.easing,function(){d.effects.restore(b,j);d.effects.removeWrapper(b);a.callback&&a.callback.apply(this,arguments)});b.queue("fx",function(){b.dequeue()});b.dequeue()})}})(jQuery);
-;/*
- * jQuery UI Effects Slide 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Slide
- *
- * Depends:
- *	jquery.effects.core.js
- */
-(function(c){c.effects.slide=function(d){return this.queue(function(){var a=c(this),h=["position","top","bottom","left","right"],f=c.effects.setMode(a,d.options.mode||"show"),b=d.options.direction||"left";c.effects.save(a,h);a.show();c.effects.createWrapper(a).css({overflow:"hidden"});var g=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left"?"pos":"neg";var e=d.options.distance||(g=="top"?a.outerHeight({margin:true}):a.outerWidth({margin:true}));if(f=="show")a.css(g,b=="pos"?isNaN(e)?"-"+e:-e:e);
-var i={};i[g]=(f=="show"?b=="pos"?"+=":"-=":b=="pos"?"-=":"+=")+e;a.animate(i,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){f=="hide"&&a.hide();c.effects.restore(a,h);c.effects.removeWrapper(a);d.callback&&d.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
-;/*
- * jQuery UI Effects Transfer 1.8.14
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Effects/Transfer
- *
- * Depends:
- *	jquery.effects.core.js
- */
-(function(e){e.effects.transfer=function(a){return this.queue(function(){var b=e(this),c=e(a.options.to),d=c.offset();c={top:d.top,left:d.left,height:c.innerHeight(),width:c.innerWidth()};d=b.offset();var f=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments);
-b.dequeue()})})}})(jQuery);
-;
\ No newline at end of file
+
+//>>label: Tooltip
+//>>group: Widgets
+//>>description: Shows additional information for any element on hover or focus.
+//>>docs: http://api.jqueryui.com/tooltip/
+//>>demos: http://jqueryui.com/tooltip/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/tooltip.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+$.widget( "ui.tooltip", {
+	version: "1.12.1",
+	options: {
+		classes: {
+			"ui-tooltip": "ui-corner-all ui-widget-shadow"
+		},
+		content: function() {
+
+			// support: IE<9, Opera in jQuery <1.7
+			// .text() can't accept undefined, so coerce to a string
+			var title = $( this ).attr( "title" ) || "";
+
+			// Escape title, since we're going from an attribute to raw HTML
+			return $( "<a>" ).text( title ).html();
+		},
+		hide: true,
+
+		// Disabled elements have inconsistent behavior across browsers (#8661)
+		items: "[title]:not([disabled])",
+		position: {
+			my: "left top+15",
+			at: "left bottom",
+			collision: "flipfit flip"
+		},
+		show: true,
+		track: false,
+
+		// Callbacks
+		close: null,
+		open: null
+	},
+
+	_addDescribedBy: function( elem, id ) {
+		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
+		describedby.push( id );
+		elem
+			.data( "ui-tooltip-id", id )
+			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
+	},
+
+	_removeDescribedBy: function( elem ) {
+		var id = elem.data( "ui-tooltip-id" ),
+			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
+			index = $.inArray( id, describedby );
+
+		if ( index !== -1 ) {
+			describedby.splice( index, 1 );
+		}
+
+		elem.removeData( "ui-tooltip-id" );
+		describedby = $.trim( describedby.join( " " ) );
+		if ( describedby ) {
+			elem.attr( "aria-describedby", describedby );
+		} else {
+			elem.removeAttr( "aria-describedby" );
+		}
+	},
+
+	_create: function() {
+		this._on( {
+			mouseover: "open",
+			focusin: "open"
+		} );
+
+		// IDs of generated tooltips, needed for destroy
+		this.tooltips = {};
+
+		// IDs of parent tooltips where we removed the title attribute
+		this.parents = {};
+
+		// Append the aria-live region so tooltips announce correctly
+		this.liveRegion = $( "<div>" )
+			.attr( {
+				role: "log",
+				"aria-live": "assertive",
+				"aria-relevant": "additions"
+			} )
+			.appendTo( this.document[ 0 ].body );
+		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
+
+		this.disabledTitles = $( [] );
+	},
+
+	_setOption: function( key, value ) {
+		var that = this;
+
+		this._super( key, value );
+
+		if ( key === "content" ) {
+			$.each( this.tooltips, function( id, tooltipData ) {
+				that._updateContent( tooltipData.element );
+			} );
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this[ value ? "_disable" : "_enable" ]();
+	},
+
+	_disable: function() {
+		var that = this;
+
+		// Close open tooltips
+		$.each( this.tooltips, function( id, tooltipData ) {
+			var event = $.Event( "blur" );
+			event.target = event.currentTarget = tooltipData.element[ 0 ];
+			that.close( event, true );
+		} );
+
+		// Remove title attributes to prevent native tooltips
+		this.disabledTitles = this.disabledTitles.add(
+			this.element.find( this.options.items ).addBack()
+				.filter( function() {
+					var element = $( this );
+					if ( element.is( "[title]" ) ) {
+						return element
+							.data( "ui-tooltip-title", element.attr( "title" ) )
+							.removeAttr( "title" );
+					}
+				} )
+		);
+	},
+
+	_enable: function() {
+
+		// restore title attributes
+		this.disabledTitles.each( function() {
+			var element = $( this );
+			if ( element.data( "ui-tooltip-title" ) ) {
+				element.attr( "title", element.data( "ui-tooltip-title" ) );
+			}
+		} );
+		this.disabledTitles = $( [] );
+	},
+
+	open: function( event ) {
+		var that = this,
+			target = $( event ? event.target : this.element )
+
+				// we need closest here due to mouseover bubbling,
+				// but always pointing at the same event target
+				.closest( this.options.items );
+
+		// No element to show a tooltip for or the tooltip is already open
+		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
+			return;
+		}
+
+		if ( target.attr( "title" ) ) {
+			target.data( "ui-tooltip-title", target.attr( "title" ) );
+		}
+
+		target.data( "ui-tooltip-open", true );
+
+		// Kill parent tooltips, custom or native, for hover
+		if ( event && event.type === "mouseover" ) {
+			target.parents().each( function() {
+				var parent = $( this ),
+					blurEvent;
+				if ( parent.data( "ui-tooltip-open" ) ) {
+					blurEvent = $.Event( "blur" );
+					blurEvent.target = blurEvent.currentTarget = this;
+					that.close( blurEvent, true );
+				}
+				if ( parent.attr( "title" ) ) {
+					parent.uniqueId();
+					that.parents[ this.id ] = {
+						element: this,
+						title: parent.attr( "title" )
+					};
+					parent.attr( "title", "" );
+				}
+			} );
+		}
+
+		this._registerCloseHandlers( event, target );
+		this._updateContent( target, event );
+	},
+
+	_updateContent: function( target, event ) {
+		var content,
+			contentOption = this.options.content,
+			that = this,
+			eventType = event ? event.type : null;
+
+		if ( typeof contentOption === "string" || contentOption.nodeType ||
+				contentOption.jquery ) {
+			return this._open( event, target, contentOption );
+		}
+
+		content = contentOption.call( target[ 0 ], function( response ) {
+
+			// IE may instantly serve a cached response for ajax requests
+			// delay this call to _open so the other call to _open runs first
+			that._delay( function() {
+
+				// Ignore async response if tooltip was closed already
+				if ( !target.data( "ui-tooltip-open" ) ) {
+					return;
+				}
+
+				// JQuery creates a special event for focusin when it doesn't
+				// exist natively. To improve performance, the native event
+				// object is reused and the type is changed. Therefore, we can't
+				// rely on the type being correct after the event finished
+				// bubbling, so we set it back to the previous value. (#8740)
+				if ( event ) {
+					event.type = eventType;
+				}
+				this._open( event, target, response );
+			} );
+		} );
+		if ( content ) {
+			this._open( event, target, content );
+		}
+	},
+
+	_open: function( event, target, content ) {
+		var tooltipData, tooltip, delayedShow, a11yContent,
+			positionOption = $.extend( {}, this.options.position );
+
+		if ( !content ) {
+			return;
+		}
+
+		// Content can be updated multiple times. If the tooltip already
+		// exists, then just update the content and bail.
+		tooltipData = this._find( target );
+		if ( tooltipData ) {
+			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
+			return;
+		}
+
+		// If we have a title, clear it to prevent the native tooltip
+		// we have to check first to avoid defining a title if none exists
+		// (we don't want to cause an element to start matching [title])
+		//
+		// We use removeAttr only for key events, to allow IE to export the correct
+		// accessible attributes. For mouse events, set to empty string to avoid
+		// native tooltip showing up (happens only when removing inside mouseover).
+		if ( target.is( "[title]" ) ) {
+			if ( event && event.type === "mouseover" ) {
+				target.attr( "title", "" );
+			} else {
+				target.removeAttr( "title" );
+			}
+		}
+
+		tooltipData = this._tooltip( target );
+		tooltip = tooltipData.tooltip;
+		this._addDescribedBy( target, tooltip.attr( "id" ) );
+		tooltip.find( ".ui-tooltip-content" ).html( content );
+
+		// Support: Voiceover on OS X, JAWS on IE <= 9
+		// JAWS announces deletions even when aria-relevant="additions"
+		// Voiceover will sometimes re-read the entire log region's contents from the beginning
+		this.liveRegion.children().hide();
+		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
+		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
+		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
+		a11yContent.appendTo( this.liveRegion );
+
+		function position( event ) {
+			positionOption.of = event;
+			if ( tooltip.is( ":hidden" ) ) {
+				return;
+			}
+			tooltip.position( positionOption );
+		}
+		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
+			this._on( this.document, {
+				mousemove: position
+			} );
+
+			// trigger once to override element-relative positioning
+			position( event );
+		} else {
+			tooltip.position( $.extend( {
+				of: target
+			}, this.options.position ) );
+		}
+
+		tooltip.hide();
+
+		this._show( tooltip, this.options.show );
+
+		// Handle tracking tooltips that are shown with a delay (#8644). As soon
+		// as the tooltip is visible, position the tooltip using the most recent
+		// event.
+		// Adds the check to add the timers only when both delay and track options are set (#14682)
+		if ( this.options.track && this.options.show && this.options.show.delay ) {
+			delayedShow = this.delayedShow = setInterval( function() {
+				if ( tooltip.is( ":visible" ) ) {
+					position( positionOption.of );
+					clearInterval( delayedShow );
+				}
+			}, $.fx.interval );
+		}
+
+		this._trigger( "open", event, { tooltip: tooltip } );
+	},
+
+	_registerCloseHandlers: function( event, target ) {
+		var events = {
+			keyup: function( event ) {
+				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
+					var fakeEvent = $.Event( event );
+					fakeEvent.currentTarget = target[ 0 ];
+					this.close( fakeEvent, true );
+				}
+			}
+		};
+
+		// Only bind remove handler for delegated targets. Non-delegated
+		// tooltips will handle this in destroy.
+		if ( target[ 0 ] !== this.element[ 0 ] ) {
+			events.remove = function() {
+				this._removeTooltip( this._find( target ).tooltip );
+			};
+		}
+
+		if ( !event || event.type === "mouseover" ) {
+			events.mouseleave = "close";
+		}
+		if ( !event || event.type === "focusin" ) {
+			events.focusout = "close";
+		}
+		this._on( true, target, events );
+	},
+
+	close: function( event ) {
+		var tooltip,
+			that = this,
+			target = $( event ? event.currentTarget : this.element ),
+			tooltipData = this._find( target );
+
+		// The tooltip may already be closed
+		if ( !tooltipData ) {
+
+			// We set ui-tooltip-open immediately upon open (in open()), but only set the
+			// additional data once there's actually content to show (in _open()). So even if the
+			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
+			// the period between open() and _open().
+			target.removeData( "ui-tooltip-open" );
+			return;
+		}
+
+		tooltip = tooltipData.tooltip;
+
+		// Disabling closes the tooltip, so we need to track when we're closing
+		// to avoid an infinite loop in case the tooltip becomes disabled on close
+		if ( tooltipData.closing ) {
+			return;
+		}
+
+		// Clear the interval for delayed tracking tooltips
+		clearInterval( this.delayedShow );
+
+		// Only set title if we had one before (see comment in _open())
+		// If the title attribute has changed since open(), don't restore
+		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
+			target.attr( "title", target.data( "ui-tooltip-title" ) );
+		}
+
+		this._removeDescribedBy( target );
+
+		tooltipData.hiding = true;
+		tooltip.stop( true );
+		this._hide( tooltip, this.options.hide, function() {
+			that._removeTooltip( $( this ) );
+		} );
+
+		target.removeData( "ui-tooltip-open" );
+		this._off( target, "mouseleave focusout keyup" );
+
+		// Remove 'remove' binding only on delegated targets
+		if ( target[ 0 ] !== this.element[ 0 ] ) {
+			this._off( target, "remove" );
+		}
+		this._off( this.document, "mousemove" );
+
+		if ( event && event.type === "mouseleave" ) {
+			$.each( this.parents, function( id, parent ) {
+				$( parent.element ).attr( "title", parent.title );
+				delete that.parents[ id ];
+			} );
+		}
+
+		tooltipData.closing = true;
+		this._trigger( "close", event, { tooltip: tooltip } );
+		if ( !tooltipData.hiding ) {
+			tooltipData.closing = false;
+		}
+	},
+
+	_tooltip: function( element ) {
+		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
+			content = $( "<div>" ).appendTo( tooltip ),
+			id = tooltip.uniqueId().attr( "id" );
+
+		this._addClass( content, "ui-tooltip-content" );
+		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
+
+		tooltip.appendTo( this._appendTo( element ) );
+
+		return this.tooltips[ id ] = {
+			element: element,
+			tooltip: tooltip
+		};
+	},
+
+	_find: function( target ) {
+		var id = target.data( "ui-tooltip-id" );
+		return id ? this.tooltips[ id ] : null;
+	},
+
+	_removeTooltip: function( tooltip ) {
+		tooltip.remove();
+		delete this.tooltips[ tooltip.attr( "id" ) ];
+	},
+
+	_appendTo: function( target ) {
+		var element = target.closest( ".ui-front, dialog" );
+
+		if ( !element.length ) {
+			element = this.document[ 0 ].body;
+		}
+
+		return element;
+	},
+
+	_destroy: function() {
+		var that = this;
+
+		// Close open tooltips
+		$.each( this.tooltips, function( id, tooltipData ) {
+
+			// Delegate to close method to handle common cleanup
+			var event = $.Event( "blur" ),
+				element = tooltipData.element;
+			event.target = event.currentTarget = element[ 0 ];
+			that.close( event, true );
+
+			// Remove immediately; destroying an open tooltip doesn't use the
+			// hide animation
+			$( "#" + id ).remove();
+
+			// Restore the title
+			if ( element.data( "ui-tooltip-title" ) ) {
+
+				// If the title attribute has changed since open(), don't restore
+				if ( !element.attr( "title" ) ) {
+					element.attr( "title", element.data( "ui-tooltip-title" ) );
+				}
+				element.removeData( "ui-tooltip-title" );
+			}
+		} );
+		this.liveRegion.remove();
+	}
+} );
+
+// DEPRECATED
+// TODO: Switch return back to widget declaration at top of file when this is removed
+if ( $.uiBackCompat !== false ) {
+
+	// Backcompat for tooltipClass option
+	$.widget( "ui.tooltip", $.ui.tooltip, {
+		options: {
+			tooltipClass: null
+		},
+		_tooltip: function() {
+			var tooltipData = this._superApply( arguments );
+			if ( this.options.tooltipClass ) {
+				tooltipData.tooltip.addClass( this.options.tooltipClass );
+			}
+			return tooltipData;
+		}
+	} );
+}
+
+var widgetsTooltip = $.ui.tooltip;
+
+
+
+
+}));
\ No newline at end of file
diff --git a/ui/lib/jquery.js b/ui/lib/jquery.js
index 11e6d06..debcd7a 100644
--- a/ui/lib/jquery.js
+++ b/ui/lib/jquery.js
@@ -1,6703 +1,8543 @@
 /*!
- * jQuery JavaScript Library v1.6.4
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
+ * jQuery JavaScript Library v3.3.1
+ * https://jquery.com/
  *
  * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
+ * https://sizzlejs.com/
  *
- * Date: Mon Sep 12 18:54:48 2011 -0400
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2018-01-20T17:24Z
  */
-(function( window, undefined ) {
+( function( global, factory ) {
 
-// Use the correct document accordingly with window argument (sandbox)
-var document = window.document,
-	navigator = window.navigator,
-	location = window.location;
-var jQuery = (function() {
+  "use strict";
 
-// Define a local copy of jQuery
-var jQuery = function( selector, context ) {
-		// The jQuery object is actually just the init constructor 'enhanced'
-		return new jQuery.fn.init( selector, context, rootjQuery );
-	},
+  if ( typeof module === "object" && typeof module.exports === "object" ) {
 
-	// Map over jQuery in case of overwrite
-	_jQuery = window.jQuery,
-
-	// Map over the $ in case of overwrite
-	_$ = window.$,
-
-	// A central reference to the root jQuery(document)
-	rootjQuery,
-
-	// A simple way to check for HTML strings or ID strings
-	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
-	quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
-
-	// Check if a string has a non-whitespace character in it
-	rnotwhite = /\S/,
-
-	// Used for trimming whitespace
-	trimLeft = /^\s+/,
-	trimRight = /\s+$/,
-
-	// Check for digits
-	rdigit = /\d/,
-
-	// Match a standalone tag
-	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
-
-	// JSON RegExp
-	rvalidchars = /^[\],:{}\s]*$/,
-	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
-	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
-	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
-
-	// Useragent RegExp
-	rwebkit = /(webkit)[ \/]([\w.]+)/,
-	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
-	rmsie = /(msie) ([\w.]+)/,
-	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
-
-	// Matches dashed string for camelizing
-	rdashAlpha = /-([a-z]|[0-9])/ig,
-	rmsPrefix = /^-ms-/,
-
-	// Used by jQuery.camelCase as callback to replace()
-	fcamelCase = function( all, letter ) {
-		return ( letter + "" ).toUpperCase();
-	},
-
-	// Keep a UserAgent string for use with jQuery.browser
-	userAgent = navigator.userAgent,
-
-	// For matching the engine and version of the browser
-	browserMatch,
-
-	// The deferred used on DOM ready
-	readyList,
-
-	// The ready event handler
-	DOMContentLoaded,
-
-	// Save a reference to some core methods
-	toString = Object.prototype.toString,
-	hasOwn = Object.prototype.hasOwnProperty,
-	push = Array.prototype.push,
-	slice = Array.prototype.slice,
-	trim = String.prototype.trim,
-	indexOf = Array.prototype.indexOf,
-
-	// [[Class]] -> type pairs
-	class2type = {};
-
-jQuery.fn = jQuery.prototype = {
-	constructor: jQuery,
-	init: function( selector, context, rootjQuery ) {
-		var match, elem, ret, doc;
-
-		// Handle $(""), $(null), or $(undefined)
-		if ( !selector ) {
-			return this;
-		}
-
-		// Handle $(DOMElement)
-		if ( selector.nodeType ) {
-			this.context = this[0] = selector;
-			this.length = 1;
-			return this;
-		}
-
-		// The body element only exists once, optimize finding it
-		if ( selector === "body" && !context && document.body ) {
-			this.context = document;
-			this[0] = document.body;
-			this.selector = selector;
-			this.length = 1;
-			return this;
-		}
-
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			// Are we dealing with HTML string or an ID?
-			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
-				// Assume that strings that start and end with <> are HTML and skip the regex check
-				match = [ null, selector, null ];
-
-			} else {
-				match = quickExpr.exec( selector );
-			}
-
-			// Verify a match, and that no context was specified for #id
-			if ( match && (match[1] || !context) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[1] ) {
-					context = context instanceof jQuery ? context[0] : context;
-					doc = (context ? context.ownerDocument || context : document);
-
-					// If a single string is passed in and it's a single tag
-					// just do a createElement and skip the rest
-					ret = rsingleTag.exec( selector );
-
-					if ( ret ) {
-						if ( jQuery.isPlainObject( context ) ) {
-							selector = [ document.createElement( ret[1] ) ];
-							jQuery.fn.attr.call( selector, context, true );
-
-						} else {
-							selector = [ doc.createElement( ret[1] ) ];
-						}
-
-					} else {
-						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
-						selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
-					}
-
-					return jQuery.merge( this, selector );
-
-				// HANDLE: $("#id")
-				} else {
-					elem = document.getElementById( match[2] );
-
-					// Check parentNode to catch when Blackberry 4.6 returns
-					// nodes that are no longer in the document #6963
-					if ( elem && elem.parentNode ) {
-						// Handle the case where IE and Opera return items
-						// by name instead of ID
-						if ( elem.id !== match[2] ) {
-							return rootjQuery.find( selector );
-						}
-
-						// Otherwise, we inject the element directly into the jQuery object
-						this.length = 1;
-						this[0] = elem;
-					}
-
-					this.context = document;
-					this.selector = selector;
-					return this;
-				}
-
-			// HANDLE: $(expr, $(...))
-			} else if ( !context || context.jquery ) {
-				return (context || rootjQuery).find( selector );
-
-			// HANDLE: $(expr, context)
-			// (which is just equivalent to: $(context).find(expr)
-			} else {
-				return this.constructor( context ).find( selector );
-			}
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) ) {
-			return rootjQuery.ready( selector );
-		}
-
-		if (selector.selector !== undefined) {
-			this.selector = selector.selector;
-			this.context = selector.context;
-		}
-
-		return jQuery.makeArray( selector, this );
-	},
-
-	// Start with an empty selector
-	selector: "",
-
-	// The current version of jQuery being used
-	jquery: "1.6.4",
-
-	// The default length of a jQuery object is 0
-	length: 0,
-
-	// The number of elements contained in the matched element set
-	size: function() {
-		return this.length;
-	},
-
-	toArray: function() {
-		return slice.call( this, 0 );
-	},
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-		return num == null ?
-
-			// Return a 'clean' array
-			this.toArray() :
-
-			// Return just the object
-			( num < 0 ? this[ this.length + num ] : this[ num ] );
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems, name, selector ) {
-		// Build a new jQuery matched element set
-		var ret = this.constructor();
-
-		if ( jQuery.isArray( elems ) ) {
-			push.apply( ret, elems );
-
-		} else {
-			jQuery.merge( ret, elems );
-		}
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-
-		ret.context = this.context;
-
-		if ( name === "find" ) {
-			ret.selector = this.selector + (this.selector ? " " : "") + selector;
-		} else if ( name ) {
-			ret.selector = this.selector + "." + name + "(" + selector + ")";
-		}
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Execute a callback for every element in the matched set.
-	// (You can seed the arguments with an array of args, but this is
-	// only used internally.)
-	each: function( callback, args ) {
-		return jQuery.each( this, callback, args );
-	},
-
-	ready: function( fn ) {
-		// Attach the listeners
-		jQuery.bindReady();
-
-		// Add the callback
-		readyList.done( fn );
-
-		return this;
-	},
-
-	eq: function( i ) {
-		return i === -1 ?
-			this.slice( i ) :
-			this.slice( i, +i + 1 );
-	},
-
-	first: function() {
-		return this.eq( 0 );
-	},
-
-	last: function() {
-		return this.eq( -1 );
-	},
-
-	slice: function() {
-		return this.pushStack( slice.apply( this, arguments ),
-			"slice", slice.call(arguments).join(",") );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map(this, function( elem, i ) {
-			return callback.call( elem, i, elem );
-		}));
-	},
-
-	end: function() {
-		return this.prevObject || this.constructor(null);
-	},
-
-	// For internal use only.
-	// Behaves like an Array's method, not like a jQuery method.
-	push: push,
-	sort: [].sort,
-	splice: [].splice
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-jQuery.extend = jQuery.fn.extend = function() {
-	var options, name, src, copy, copyIsArray, clone,
-		target = arguments[0] || {},
-		i = 1,
-		length = arguments.length,
-		deep = false;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-		target = arguments[1] || {};
-		// skip the boolean and the target
-		i = 2;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
-		target = {};
-	}
-
-	// extend jQuery itself if only one argument is passed
-	if ( length === i ) {
-		target = this;
-		--i;
-	}
-
-	for ( ; i < length; i++ ) {
-		// Only deal with non-null/undefined values
-		if ( (options = arguments[ i ]) != null ) {
-			// Extend the base object
-			for ( name in options ) {
-				src = target[ name ];
-				copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy ) {
-					continue;
-				}
-
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
-					if ( copyIsArray ) {
-						copyIsArray = false;
-						clone = src && jQuery.isArray(src) ? src : [];
-
-					} else {
-						clone = src && jQuery.isPlainObject(src) ? src : {};
-					}
-
-					// Never move original objects, clone them
-					target[ name ] = jQuery.extend( deep, clone, copy );
-
-				// Don't bring in undefined values
-				} else if ( copy !== undefined ) {
-					target[ name ] = copy;
-				}
-			}
-		}
-	}
-
-	// Return the modified object
-	return target;
-};
-
-jQuery.extend({
-	noConflict: function( deep ) {
-		if ( window.$ === jQuery ) {
-			window.$ = _$;
-		}
-
-		if ( deep && window.jQuery === jQuery ) {
-			window.jQuery = _jQuery;
-		}
-
-		return jQuery;
-	},
-
-	// Is the DOM ready to be used? Set to true once it occurs.
-	isReady: false,
-
-	// A counter to track how many items to wait for before
-	// the ready event fires. See #6781
-	readyWait: 1,
-
-	// Hold (or release) the ready event
-	holdReady: function( hold ) {
-		if ( hold ) {
-			jQuery.readyWait++;
-		} else {
-			jQuery.ready( true );
-		}
-	},
-
-	// Handle when the DOM is ready
-	ready: function( wait ) {
-		// Either a released hold or an DOMready/load event and not yet ready
-		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
-			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
-			if ( !document.body ) {
-				return setTimeout( jQuery.ready, 1 );
-			}
-
-			// Remember that the DOM is ready
-			jQuery.isReady = true;
-
-			// If a normal DOM Ready event fired, decrement, and wait if need be
-			if ( wait !== true && --jQuery.readyWait > 0 ) {
-				return;
-			}
-
-			// If there are functions bound, to execute
-			readyList.resolveWith( document, [ jQuery ] );
-
-			// Trigger any bound ready events
-			if ( jQuery.fn.trigger ) {
-				jQuery( document ).trigger( "ready" ).unbind( "ready" );
-			}
-		}
-	},
-
-	bindReady: function() {
-		if ( readyList ) {
-			return;
-		}
-
-		readyList = jQuery._Deferred();
-
-		// Catch cases where $(document).ready() is called after the
-		// browser event has already occurred.
-		if ( document.readyState === "complete" ) {
-			// Handle it asynchronously to allow scripts the opportunity to delay ready
-			return setTimeout( jQuery.ready, 1 );
-		}
-
-		// Mozilla, Opera and webkit nightlies currently support this event
-		if ( document.addEventListener ) {
-			// Use the handy event callback
-			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
-			// A fallback to window.onload, that will always work
-			window.addEventListener( "load", jQuery.ready, false );
-
-		// If IE event model is used
-		} else if ( document.attachEvent ) {
-			// ensure firing before onload,
-			// maybe late but safe also for iframes
-			document.attachEvent( "onreadystatechange", DOMContentLoaded );
-
-			// A fallback to window.onload, that will always work
-			window.attachEvent( "onload", jQuery.ready );
-
-			// If IE and not a frame
-			// continually check to see if the document is ready
-			var toplevel = false;
-
-			try {
-				toplevel = window.frameElement == null;
-			} catch(e) {}
-
-			if ( document.documentElement.doScroll && toplevel ) {
-				doScrollCheck();
-			}
-		}
-	},
-
-	// See test/unit/core.js for details concerning isFunction.
-	// Since version 1.3, DOM methods and functions like alert
-	// aren't supported. They return false on IE (#2968).
-	isFunction: function( obj ) {
-		return jQuery.type(obj) === "function";
-	},
-
-	isArray: Array.isArray || function( obj ) {
-		return jQuery.type(obj) === "array";
-	},
-
-	// A crude way of determining if an object is a window
-	isWindow: function( obj ) {
-		return obj && typeof obj === "object" && "setInterval" in obj;
-	},
-
-	isNaN: function( obj ) {
-		return obj == null || !rdigit.test( obj ) || isNaN( obj );
-	},
-
-	type: function( obj ) {
-		return obj == null ?
-			String( obj ) :
-			class2type[ toString.call(obj) ] || "object";
-	},
-
-	isPlainObject: function( obj ) {
-		// Must be an Object.
-		// Because of IE, we also have to check the presence of the constructor property.
-		// Make sure that DOM nodes and window objects don't pass through, as well
-		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
-			return false;
-		}
-
-		try {
-			// Not own constructor property must be Object
-			if ( obj.constructor &&
-				!hasOwn.call(obj, "constructor") &&
-				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
-				return false;
-			}
-		} catch ( e ) {
-			// IE8,9 Will throw exceptions on certain host objects #9897
-			return false;
-		}
-
-		// Own properties are enumerated firstly, so to speed up,
-		// if last one is own, then all properties are own.
-
-		var key;
-		for ( key in obj ) {}
-
-		return key === undefined || hasOwn.call( obj, key );
-	},
-
-	isEmptyObject: function( obj ) {
-		for ( var name in obj ) {
-			return false;
-		}
-		return true;
-	},
-
-	error: function( msg ) {
-		throw msg;
-	},
-
-	parseJSON: function( data ) {
-		if ( typeof data !== "string" || !data ) {
-			return null;
-		}
-
-		// Make sure leading/trailing whitespace is removed (IE can't handle it)
-		data = jQuery.trim( data );
-
-		// Attempt to parse using the native JSON parser first
-		if ( window.JSON && window.JSON.parse ) {
-			return window.JSON.parse( data );
-		}
-
-		// Make sure the incoming data is actual JSON
-		// Logic borrowed from http://json.org/json2.js
-		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
-			.replace( rvalidtokens, "]" )
-			.replace( rvalidbraces, "")) ) {
-
-			return (new Function( "return " + data ))();
-
-		}
-		jQuery.error( "Invalid JSON: " + data );
-	},
-
-	// Cross-browser xml parsing
-	parseXML: function( data ) {
-		var xml, tmp;
-		try {
-			if ( window.DOMParser ) { // Standard
-				tmp = new DOMParser();
-				xml = tmp.parseFromString( data , "text/xml" );
-			} else { // IE
-				xml = new ActiveXObject( "Microsoft.XMLDOM" );
-				xml.async = "false";
-				xml.loadXML( data );
-			}
-		} catch( e ) {
-			xml = undefined;
-		}
-		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
-			jQuery.error( "Invalid XML: " + data );
-		}
-		return xml;
-	},
-
-	noop: function() {},
-
-	// Evaluates a script in a global context
-	// Workarounds based on findings by Jim Driscoll
-	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
-	globalEval: function( data ) {
-		if ( data && rnotwhite.test( data ) ) {
-			// We use execScript on Internet Explorer
-			// We use an anonymous function so that context is window
-			// rather than jQuery in Firefox
-			( window.execScript || function( data ) {
-				window[ "eval" ].call( window, data );
-			} )( data );
-		}
-	},
-
-	// Convert dashed to camelCase; used by the css and data modules
-	// Microsoft forgot to hump their vendor prefix (#9572)
-	camelCase: function( string ) {
-		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
-	},
-
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
-	},
-
-	// args is for internal usage only
-	each: function( object, callback, args ) {
-		var name, i = 0,
-			length = object.length,
-			isObj = length === undefined || jQuery.isFunction( object );
-
-		if ( args ) {
-			if ( isObj ) {
-				for ( name in object ) {
-					if ( callback.apply( object[ name ], args ) === false ) {
-						break;
-					}
-				}
-			} else {
-				for ( ; i < length; ) {
-					if ( callback.apply( object[ i++ ], args ) === false ) {
-						break;
-					}
-				}
-			}
-
-		// A special, fast, case for the most common use of each
-		} else {
-			if ( isObj ) {
-				for ( name in object ) {
-					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
-						break;
-					}
-				}
-			} else {
-				for ( ; i < length; ) {
-					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
-						break;
-					}
-				}
-			}
-		}
-
-		return object;
-	},
-
-	// Use native String.trim function wherever possible
-	trim: trim ?
-		function( text ) {
-			return text == null ?
-				"" :
-				trim.call( text );
-		} :
-
-		// Otherwise use our own trimming functionality
-		function( text ) {
-			return text == null ?
-				"" :
-				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
-		},
-
-	// results is for internal usage only
-	makeArray: function( array, results ) {
-		var ret = results || [];
-
-		if ( array != null ) {
-			// The window, strings (and functions) also have 'length'
-			// The extra typeof function check is to prevent crashes
-			// in Safari 2 (See: #3039)
-			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
-			var type = jQuery.type( array );
-
-			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
-				push.call( ret, array );
-			} else {
-				jQuery.merge( ret, array );
-			}
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, array ) {
-		if ( !array ) {
-			return -1;
-		}
-
-		if ( indexOf ) {
-			return indexOf.call( array, elem );
-		}
-
-		for ( var i = 0, length = array.length; i < length; i++ ) {
-			if ( array[ i ] === elem ) {
-				return i;
-			}
-		}
-
-		return -1;
-	},
-
-	merge: function( first, second ) {
-		var i = first.length,
-			j = 0;
-
-		if ( typeof second.length === "number" ) {
-			for ( var l = second.length; j < l; j++ ) {
-				first[ i++ ] = second[ j ];
-			}
-
-		} else {
-			while ( second[j] !== undefined ) {
-				first[ i++ ] = second[ j++ ];
-			}
-		}
-
-		first.length = i;
-
-		return first;
-	},
-
-	grep: function( elems, callback, inv ) {
-		var ret = [], retVal;
-		inv = !!inv;
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( var i = 0, length = elems.length; i < length; i++ ) {
-			retVal = !!callback( elems[ i ], i );
-			if ( inv !== retVal ) {
-				ret.push( elems[ i ] );
-			}
-		}
-
-		return ret;
-	},
-
-	// arg is for internal usage only
-	map: function( elems, callback, arg ) {
-		var value, key, ret = [],
-			i = 0,
-			length = elems.length,
-			// jquery objects are treated as arrays
-			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
-
-		// Go through the array, translating each of the items to their
-		if ( isArray ) {
-			for ( ; i < length; i++ ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret[ ret.length ] = value;
-				}
-			}
-
-		// Go through every key on the object,
-		} else {
-			for ( key in elems ) {
-				value = callback( elems[ key ], key, arg );
-
-				if ( value != null ) {
-					ret[ ret.length ] = value;
-				}
-			}
-		}
-
-		// Flatten any nested arrays
-		return ret.concat.apply( [], ret );
-	},
-
-	// A global GUID counter for objects
-	guid: 1,
-
-	// Bind a function to a context, optionally partially applying any
-	// arguments.
-	proxy: function( fn, context ) {
-		if ( typeof context === "string" ) {
-			var tmp = fn[ context ];
-			context = fn;
-			fn = tmp;
-		}
-
-		// Quick check to determine if target is callable, in the spec
-		// this throws a TypeError, but we will just return undefined.
-		if ( !jQuery.isFunction( fn ) ) {
-			return undefined;
-		}
-
-		// Simulated bind
-		var args = slice.call( arguments, 2 ),
-			proxy = function() {
-				return fn.apply( context, args.concat( slice.call( arguments ) ) );
-			};
-
-		// Set the guid of unique handler to the same of original handler, so it can be removed
-		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
-
-		return proxy;
-	},
-
-	// Mutifunctional method to get and set values to a collection
-	// The value/s can optionally be executed if it's a function
-	access: function( elems, key, value, exec, fn, pass ) {
-		var length = elems.length;
-
-		// Setting many attributes
-		if ( typeof key === "object" ) {
-			for ( var k in key ) {
-				jQuery.access( elems, k, key[k], exec, fn, value );
-			}
-			return elems;
-		}
-
-		// Setting one attribute
-		if ( value !== undefined ) {
-			// Optionally, function values get executed if exec is true
-			exec = !pass && exec && jQuery.isFunction(value);
-
-			for ( var i = 0; i < length; i++ ) {
-				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
-			}
-
-			return elems;
-		}
-
-		// Getting an attribute
-		return length ? fn( elems[0], key ) : undefined;
-	},
-
-	now: function() {
-		return (new Date()).getTime();
-	},
-
-	// Use of jQuery.browser is frowned upon.
-	// More details: http://docs.jquery.com/Utilities/jQuery.browser
-	uaMatch: function( ua ) {
-		ua = ua.toLowerCase();
-
-		var match = rwebkit.exec( ua ) ||
-			ropera.exec( ua ) ||
-			rmsie.exec( ua ) ||
-			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
-			[];
-
-		return { browser: match[1] || "", version: match[2] || "0" };
-	},
-
-	sub: function() {
-		function jQuerySub( selector, context ) {
-			return new jQuerySub.fn.init( selector, context );
-		}
-		jQuery.extend( true, jQuerySub, this );
-		jQuerySub.superclass = this;
-		jQuerySub.fn = jQuerySub.prototype = this();
-		jQuerySub.fn.constructor = jQuerySub;
-		jQuerySub.sub = this.sub;
-		jQuerySub.fn.init = function init( selector, context ) {
-			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
-				context = jQuerySub( context );
-			}
-
-			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
-		};
-		jQuerySub.fn.init.prototype = jQuerySub.fn;
-		var rootjQuerySub = jQuerySub(document);
-		return jQuerySub;
-	},
-
-	browser: {}
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
-	class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-browserMatch = jQuery.uaMatch( userAgent );
-if ( browserMatch.browser ) {
-	jQuery.browser[ browserMatch.browser ] = true;
-	jQuery.browser.version = browserMatch.version;
-}
-
-// Deprecated, use jQuery.browser.webkit instead
-if ( jQuery.browser.webkit ) {
-	jQuery.browser.safari = true;
-}
-
-// IE doesn't match non-breaking spaces with \s
-if ( rnotwhite.test( "\xA0" ) ) {
-	trimLeft = /^[\s\xA0]+/;
-	trimRight = /[\s\xA0]+$/;
-}
-
-// All jQuery objects should point back to these
-rootjQuery = jQuery(document);
-
-// Cleanup functions for the document ready method
-if ( document.addEventListener ) {
-	DOMContentLoaded = function() {
-		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-		jQuery.ready();
-	};
-
-} else if ( document.attachEvent ) {
-	DOMContentLoaded = function() {
-		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
-		if ( document.readyState === "complete" ) {
-			document.detachEvent( "onreadystatechange", DOMContentLoaded );
-			jQuery.ready();
-		}
-	};
-}
-
-// The DOM ready check for Internet Explorer
-function doScrollCheck() {
-	if ( jQuery.isReady ) {
-		return;
-	}
-
-	try {
-		// If IE is used, use the trick by Diego Perini
-		// http://javascript.nwbox.com/IEContentLoaded/
-		document.documentElement.doScroll("left");
-	} catch(e) {
-		setTimeout( doScrollCheck, 1 );
-		return;
-	}
-
-	// and execute any waiting functions
-	jQuery.ready();
-}
-
-return jQuery;
-
-})();
-
-
-var // Promise methods
-	promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
-	// Static reference to slice
-	sliceDeferred = [].slice;
-
-jQuery.extend({
-	// Create a simple deferred (one callbacks list)
-	_Deferred: function() {
-		var // callbacks list
-			callbacks = [],
-			// stored [ context , args ]
-			fired,
-			// to avoid firing when already doing so
-			firing,
-			// flag to know if the deferred has been cancelled
-			cancelled,
-			// the deferred itself
-			deferred  = {
-
-				// done( f1, f2, ...)
-				done: function() {
-					if ( !cancelled ) {
-						var args = arguments,
-							i,
-							length,
-							elem,
-							type,
-							_fired;
-						if ( fired ) {
-							_fired = fired;
-							fired = 0;
-						}
-						for ( i = 0, length = args.length; i < length; i++ ) {
-							elem = args[ i ];
-							type = jQuery.type( elem );
-							if ( type === "array" ) {
-								deferred.done.apply( deferred, elem );
-							} else if ( type === "function" ) {
-								callbacks.push( elem );
-							}
-						}
-						if ( _fired ) {
-							deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
-						}
-					}
-					return this;
-				},
-
-				// resolve with given context and args
-				resolveWith: function( context, args ) {
-					if ( !cancelled && !fired && !firing ) {
-						// make sure args are available (#8421)
-						args = args || [];
-						firing = 1;
-						try {
-							while( callbacks[ 0 ] ) {
-								callbacks.shift().apply( context, args );
-							}
-						}
-						finally {
-							fired = [ context, args ];
-							firing = 0;
-						}
-					}
-					return this;
-				},
-
-				// resolve with this as context and given arguments
-				resolve: function() {
-					deferred.resolveWith( this, arguments );
-					return this;
-				},
-
-				// Has this deferred been resolved?
-				isResolved: function() {
-					return !!( firing || fired );
-				},
-
-				// Cancel
-				cancel: function() {
-					cancelled = 1;
-					callbacks = [];
-					return this;
-				}
-			};
-
-		return deferred;
-	},
-
-	// Full fledged deferred (two callbacks list)
-	Deferred: function( func ) {
-		var deferred = jQuery._Deferred(),
-			failDeferred = jQuery._Deferred(),
-			promise;
-		// Add errorDeferred methods, then and promise
-		jQuery.extend( deferred, {
-			then: function( doneCallbacks, failCallbacks ) {
-				deferred.done( doneCallbacks ).fail( failCallbacks );
-				return this;
-			},
-			always: function() {
-				return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
-			},
-			fail: failDeferred.done,
-			rejectWith: failDeferred.resolveWith,
-			reject: failDeferred.resolve,
-			isRejected: failDeferred.isResolved,
-			pipe: function( fnDone, fnFail ) {
-				return jQuery.Deferred(function( newDefer ) {
-					jQuery.each( {
-						done: [ fnDone, "resolve" ],
-						fail: [ fnFail, "reject" ]
-					}, function( handler, data ) {
-						var fn = data[ 0 ],
-							action = data[ 1 ],
-							returned;
-						if ( jQuery.isFunction( fn ) ) {
-							deferred[ handler ](function() {
-								returned = fn.apply( this, arguments );
-								if ( returned && jQuery.isFunction( returned.promise ) ) {
-									returned.promise().then( newDefer.resolve, newDefer.reject );
-								} else {
-									newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
-								}
-							});
-						} else {
-							deferred[ handler ]( newDefer[ action ] );
-						}
-					});
-				}).promise();
-			},
-			// Get a promise for this deferred
-			// If obj is provided, the promise aspect is added to the object
-			promise: function( obj ) {
-				if ( obj == null ) {
-					if ( promise ) {
-						return promise;
-					}
-					promise = obj = {};
-				}
-				var i = promiseMethods.length;
-				while( i-- ) {
-					obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
-				}
-				return obj;
-			}
-		});
-		// Make sure only one callback list will be used
-		deferred.done( failDeferred.cancel ).fail( deferred.cancel );
-		// Unexpose cancel
-		delete deferred.cancel;
-		// Call given func if any
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-		return deferred;
-	},
-
-	// Deferred helper
-	when: function( firstParam ) {
-		var args = arguments,
-			i = 0,
-			length = args.length,
-			count = length,
-			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
-				firstParam :
-				jQuery.Deferred();
-		function resolveFunc( i ) {
-			return function( value ) {
-				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
-				if ( !( --count ) ) {
-					// Strange bug in FF4:
-					// Values changed onto the arguments object sometimes end up as undefined values
-					// outside the $.when method. Cloning the object into a fresh array solves the issue
-					deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
-				}
-			};
-		}
-		if ( length > 1 ) {
-			for( ; i < length; i++ ) {
-				if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
-					args[ i ].promise().then( resolveFunc(i), deferred.reject );
-				} else {
-					--count;
-				}
-			}
-			if ( !count ) {
-				deferred.resolveWith( deferred, args );
-			}
-		} else if ( deferred !== firstParam ) {
-			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
-		}
-		return deferred.promise();
-	}
-});
-
-
-
-jQuery.support = (function() {
-
-	var div = document.createElement( "div" ),
-		documentElement = document.documentElement,
-		all,
-		a,
-		select,
-		opt,
-		input,
-		marginDiv,
-		support,
-		fragment,
-		body,
-		testElementParent,
-		testElement,
-		testElementStyle,
-		tds,
-		events,
-		eventName,
-		i,
-		isSupported;
-
-	// Preliminary tests
-	div.setAttribute("className", "t");
-	div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
-
-
-	all = div.getElementsByTagName( "*" );
-	a = div.getElementsByTagName( "a" )[ 0 ];
-
-	// Can't get basic test support
-	if ( !all || !all.length || !a ) {
-		return {};
-	}
-
-	// First batch of supports tests
-	select = document.createElement( "select" );
-	opt = select.appendChild( document.createElement("option") );
-	input = div.getElementsByTagName( "input" )[ 0 ];
-
-	support = {
-		// IE strips leading whitespace when .innerHTML is used
-		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
-
-		// Make sure that tbody elements aren't automatically inserted
-		// IE will insert them into empty tables
-		tbody: !div.getElementsByTagName( "tbody" ).length,
-
-		// Make sure that link elements get serialized correctly by innerHTML
-		// This requires a wrapper element in IE
-		htmlSerialize: !!div.getElementsByTagName( "link" ).length,
-
-		// Get the style information from getAttribute
-		// (IE uses .cssText instead)
-		style: /top/.test( a.getAttribute("style") ),
-
-		// Make sure that URLs aren't manipulated
-		// (IE normalizes it by default)
-		hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
-
-		// Make sure that element opacity exists
-		// (IE uses filter instead)
-		// Use a regex to work around a WebKit issue. See #5145
-		opacity: /^0.55$/.test( a.style.opacity ),
-
-		// Verify style float existence
-		// (IE uses styleFloat instead of cssFloat)
-		cssFloat: !!a.style.cssFloat,
-
-		// Make sure that if no value is specified for a checkbox
-		// that it defaults to "on".
-		// (WebKit defaults to "" instead)
-		checkOn: ( input.value === "on" ),
-
-		// Make sure that a selected-by-default option has a working selected property.
-		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
-		optSelected: opt.selected,
-
-		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
-		getSetAttribute: div.className !== "t",
-
-		// Will be defined later
-		submitBubbles: true,
-		changeBubbles: true,
-		focusinBubbles: false,
-		deleteExpando: true,
-		noCloneEvent: true,
-		inlineBlockNeedsLayout: false,
-		shrinkWrapBlocks: false,
-		reliableMarginRight: true
-	};
-
-	// Make sure checked status is properly cloned
-	input.checked = true;
-	support.noCloneChecked = input.cloneNode( true ).checked;
-
-	// Make sure that the options inside disabled selects aren't marked as disabled
-	// (WebKit marks them as disabled)
-	select.disabled = true;
-	support.optDisabled = !opt.disabled;
-
-	// Test to see if it's possible to delete an expando from an element
-	// Fails in Internet Explorer
-	try {
-		delete div.test;
-	} catch( e ) {
-		support.deleteExpando = false;
-	}
-
-	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
-		div.attachEvent( "onclick", function() {
-			// Cloning a node shouldn't copy over any
-			// bound event handlers (IE does this)
-			support.noCloneEvent = false;
-		});
-		div.cloneNode( true ).fireEvent( "onclick" );
-	}
-
-	// Check if a radio maintains it's value
-	// after being appended to the DOM
-	input = document.createElement("input");
-	input.value = "t";
-	input.setAttribute("type", "radio");
-	support.radioValue = input.value === "t";
-
-	input.setAttribute("checked", "checked");
-	div.appendChild( input );
-	fragment = document.createDocumentFragment();
-	fragment.appendChild( div.firstChild );
-
-	// WebKit doesn't clone checked state correctly in fragments
-	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
-	div.innerHTML = "";
-
-	// Figure out if the W3C box model works as expected
-	div.style.width = div.style.paddingLeft = "1px";
-
-	body = document.getElementsByTagName( "body" )[ 0 ];
-	// We use our own, invisible, body unless the body is already present
-	// in which case we use a div (#9239)
-	testElement = document.createElement( body ? "div" : "body" );
-	testElementStyle = {
-		visibility: "hidden",
-		width: 0,
-		height: 0,
-		border: 0,
-		margin: 0,
-		background: "none"
-	};
-	if ( body ) {
-		jQuery.extend( testElementStyle, {
-			position: "absolute",
-			left: "-1000px",
-			top: "-1000px"
-		});
-	}
-	for ( i in testElementStyle ) {
-		testElement.style[ i ] = testElementStyle[ i ];
-	}
-	testElement.appendChild( div );
-	testElementParent = body || documentElement;
-	testElementParent.insertBefore( testElement, testElementParent.firstChild );
-
-	// Check if a disconnected checkbox will retain its checked
-	// value of true after appended to the DOM (IE6/7)
-	support.appendChecked = input.checked;
-
-	support.boxModel = div.offsetWidth === 2;
-
-	if ( "zoom" in div.style ) {
-		// Check if natively block-level elements act like inline-block
-		// elements when setting their display to 'inline' and giving
-		// them layout
-		// (IE < 8 does this)
-		div.style.display = "inline";
-		div.style.zoom = 1;
-		support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
-
-		// Check if elements with layout shrink-wrap their children
-		// (IE 6 does this)
-		div.style.display = "";
-		div.innerHTML = "<div style='width:4px;'></div>";
-		support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
-	}
-
-	div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
-	tds = div.getElementsByTagName( "td" );
-
-	// Check if table cells still have offsetWidth/Height when they are set
-	// to display:none and there are still other visible table cells in a
-	// table row; if so, offsetWidth/Height are not reliable for use when
-	// determining if an element has been hidden directly using
-	// display:none (it is still safe to use offsets if a parent element is
-	// hidden; don safety goggles and see bug #4512 for more information).
-	// (only IE 8 fails this test)
-	isSupported = ( tds[ 0 ].offsetHeight === 0 );
-
-	tds[ 0 ].style.display = "";
-	tds[ 1 ].style.display = "none";
-
-	// Check if empty table cells still have offsetWidth/Height
-	// (IE < 8 fail this test)
-	support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
-	div.innerHTML = "";
-
-	// Check if div with explicit width and no margin-right incorrectly
-	// gets computed margin-right based on width of container. For more
-	// info see bug #3333
-	// Fails in WebKit before Feb 2011 nightlies
-	// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-	if ( document.defaultView && document.defaultView.getComputedStyle ) {
-		marginDiv = document.createElement( "div" );
-		marginDiv.style.width = "0";
-		marginDiv.style.marginRight = "0";
-		div.appendChild( marginDiv );
-		support.reliableMarginRight =
-			( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
-	}
-
-	// Remove the body element we added
-	testElement.innerHTML = "";
-	testElementParent.removeChild( testElement );
-
-	// Technique from Juriy Zaytsev
-	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
-	// We only care about the case where non-standard event systems
-	// are used, namely in IE. Short-circuiting here helps us to
-	// avoid an eval call (in setAttribute) which can cause CSP
-	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
-	if ( div.attachEvent ) {
-		for( i in {
-			submit: 1,
-			change: 1,
-			focusin: 1
-		} ) {
-			eventName = "on" + i;
-			isSupported = ( eventName in div );
-			if ( !isSupported ) {
-				div.setAttribute( eventName, "return;" );
-				isSupported = ( typeof div[ eventName ] === "function" );
-			}
-			support[ i + "Bubbles" ] = isSupported;
-		}
-	}
-
-	// Null connected elements to avoid leaks in IE
-	testElement = fragment = select = opt = body = marginDiv = div = input = null;
-
-	return support;
-})();
-
-// Keep track of boxModel
-jQuery.boxModel = jQuery.support.boxModel;
-
-
-
-
-var rbrace = /^(?:\{.*\}|\[.*\])$/,
-	rmultiDash = /([A-Z])/g;
-
-jQuery.extend({
-	cache: {},
-
-	// Please use with caution
-	uuid: 0,
-
-	// Unique for each copy of jQuery on the page
-	// Non-digits removed to match rinlinejQuery
-	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
-
-	// The following elements throw uncatchable exceptions if you
-	// attempt to add expando properties to them.
-	noData: {
-		"embed": true,
-		// Ban all objects except for Flash (which handle expandos)
-		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
-		"applet": true
-	},
-
-	hasData: function( elem ) {
-		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
-
-		return !!elem && !isEmptyDataObject( elem );
-	},
-
-	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
-		if ( !jQuery.acceptData( elem ) ) {
-			return;
-		}
-
-		var thisCache, ret,
-			internalKey = jQuery.expando,
-			getByName = typeof name === "string",
-
-			// We have to handle DOM nodes and JS objects differently because IE6-7
-			// can't GC object references properly across the DOM-JS boundary
-			isNode = elem.nodeType,
-
-			// Only DOM nodes need the global jQuery cache; JS object data is
-			// attached directly to the object so GC can occur automatically
-			cache = isNode ? jQuery.cache : elem,
-
-			// Only defining an ID for JS objects if its cache already exists allows
-			// the code to shortcut on the same path as a DOM node with no cache
-			id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
-
-		// Avoid doing any more work than we need to when trying to get data on an
-		// object that has no data at all
-		if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
-			return;
-		}
-
-		if ( !id ) {
-			// Only DOM nodes need a new unique ID for each element since their data
-			// ends up in the global cache
-			if ( isNode ) {
-				elem[ jQuery.expando ] = id = ++jQuery.uuid;
-			} else {
-				id = jQuery.expando;
-			}
-		}
-
-		if ( !cache[ id ] ) {
-			cache[ id ] = {};
-
-			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
-			// metadata on plain JS objects when the object is serialized using
-			// JSON.stringify
-			if ( !isNode ) {
-				cache[ id ].toJSON = jQuery.noop;
-			}
-		}
-
-		// An object can be passed to jQuery.data instead of a key/value pair; this gets
-		// shallow copied over onto the existing cache
-		if ( typeof name === "object" || typeof name === "function" ) {
-			if ( pvt ) {
-				cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
-			} else {
-				cache[ id ] = jQuery.extend(cache[ id ], name);
-			}
-		}
-
-		thisCache = cache[ id ];
-
-		// Internal jQuery data is stored in a separate object inside the object's data
-		// cache in order to avoid key collisions between internal data and user-defined
-		// data
-		if ( pvt ) {
-			if ( !thisCache[ internalKey ] ) {
-				thisCache[ internalKey ] = {};
-			}
-
-			thisCache = thisCache[ internalKey ];
-		}
-
-		if ( data !== undefined ) {
-			thisCache[ jQuery.camelCase( name ) ] = data;
-		}
-
-		// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
-		// not attempt to inspect the internal events object using jQuery.data, as this
-		// internal data object is undocumented and subject to change.
-		if ( name === "events" && !thisCache[name] ) {
-			return thisCache[ internalKey ] && thisCache[ internalKey ].events;
-		}
-
-		// Check for both converted-to-camel and non-converted data property names
-		// If a data property was specified
-		if ( getByName ) {
-
-			// First Try to find as-is property data
-			ret = thisCache[ name ];
-
-			// Test for null|undefined property data
-			if ( ret == null ) {
-
-				// Try to find the camelCased property
-				ret = thisCache[ jQuery.camelCase( name ) ];
-			}
-		} else {
-			ret = thisCache;
-		}
-
-		return ret;
-	},
-
-	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
-		if ( !jQuery.acceptData( elem ) ) {
-			return;
-		}
-
-		var thisCache,
-
-			// Reference to internal data cache key
-			internalKey = jQuery.expando,
-
-			isNode = elem.nodeType,
-
-			// See jQuery.data for more information
-			cache = isNode ? jQuery.cache : elem,
-
-			// See jQuery.data for more information
-			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
-
-		// If there is already no cache entry for this object, there is no
-		// purpose in continuing
-		if ( !cache[ id ] ) {
-			return;
-		}
-
-		if ( name ) {
-
-			thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
-
-			if ( thisCache ) {
-
-				// Support interoperable removal of hyphenated or camelcased keys
-				if ( !thisCache[ name ] ) {
-					name = jQuery.camelCase( name );
-				}
-
-				delete thisCache[ name ];
-
-				// If there is no data left in the cache, we want to continue
-				// and let the cache object itself get destroyed
-				if ( !isEmptyDataObject(thisCache) ) {
-					return;
-				}
-			}
-		}
-
-		// See jQuery.data for more information
-		if ( pvt ) {
-			delete cache[ id ][ internalKey ];
-
-			// Don't destroy the parent cache unless the internal data object
-			// had been the only thing left in it
-			if ( !isEmptyDataObject(cache[ id ]) ) {
-				return;
-			}
-		}
-
-		var internalCache = cache[ id ][ internalKey ];
-
-		// Browsers that fail expando deletion also refuse to delete expandos on
-		// the window, but it will allow it on all other JS objects; other browsers
-		// don't care
-		// Ensure that `cache` is not a window object #10080
-		if ( jQuery.support.deleteExpando || !cache.setInterval ) {
-			delete cache[ id ];
-		} else {
-			cache[ id ] = null;
-		}
-
-		// We destroyed the entire user cache at once because it's faster than
-		// iterating through each key, but we need to continue to persist internal
-		// data if it existed
-		if ( internalCache ) {
-			cache[ id ] = {};
-			// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
-			// metadata on plain JS objects when the object is serialized using
-			// JSON.stringify
-			if ( !isNode ) {
-				cache[ id ].toJSON = jQuery.noop;
-			}
-
-			cache[ id ][ internalKey ] = internalCache;
-
-		// Otherwise, we need to eliminate the expando on the node to avoid
-		// false lookups in the cache for entries that no longer exist
-		} else if ( isNode ) {
-			// IE does not allow us to delete expando properties from nodes,
-			// nor does it have a removeAttribute function on Document nodes;
-			// we must handle all of these cases
-			if ( jQuery.support.deleteExpando ) {
-				delete elem[ jQuery.expando ];
-			} else if ( elem.removeAttribute ) {
-				elem.removeAttribute( jQuery.expando );
-			} else {
-				elem[ jQuery.expando ] = null;
-			}
-		}
-	},
-
-	// For internal use only.
-	_data: function( elem, name, data ) {
-		return jQuery.data( elem, name, data, true );
-	},
-
-	// A method for determining if a DOM node can handle the data expando
-	acceptData: function( elem ) {
-		if ( elem.nodeName ) {
-			var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
-
-			if ( match ) {
-				return !(match === true || elem.getAttribute("classid") !== match);
-			}
-		}
-
-		return true;
-	}
-});
-
-jQuery.fn.extend({
-	data: function( key, value ) {
-		var data = null;
-
-		if ( typeof key === "undefined" ) {
-			if ( this.length ) {
-				data = jQuery.data( this[0] );
-
-				if ( this[0].nodeType === 1 ) {
-			    var attr = this[0].attributes, name;
-					for ( var i = 0, l = attr.length; i < l; i++ ) {
-						name = attr[i].name;
-
-						if ( name.indexOf( "data-" ) === 0 ) {
-							name = jQuery.camelCase( name.substring(5) );
-
-							dataAttr( this[0], name, data[ name ] );
-						}
-					}
-				}
-			}
-
-			return data;
-
-		} else if ( typeof key === "object" ) {
-			return this.each(function() {
-				jQuery.data( this, key );
-			});
-		}
-
-		var parts = key.split(".");
-		parts[1] = parts[1] ? "." + parts[1] : "";
-
-		if ( value === undefined ) {
-			data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
-			// Try to fetch any internally stored data first
-			if ( data === undefined && this.length ) {
-				data = jQuery.data( this[0], key );
-				data = dataAttr( this[0], key, data );
-			}
-
-			return data === undefined && parts[1] ?
-				this.data( parts[0] ) :
-				data;
-
-		} else {
-			return this.each(function() {
-				var $this = jQuery( this ),
-					args = [ parts[0], value ];
-
-				$this.triggerHandler( "setData" + parts[1] + "!", args );
-				jQuery.data( this, key, value );
-				$this.triggerHandler( "changeData" + parts[1] + "!", args );
-			});
-		}
-	},
-
-	removeData: function( key ) {
-		return this.each(function() {
-			jQuery.removeData( this, key );
-		});
-	}
-});
-
-function dataAttr( elem, key, data ) {
-	// If nothing was found internally, try to fetch any
-	// data from the HTML5 data-* attribute
-	if ( data === undefined && elem.nodeType === 1 ) {
-
-		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
-
-		data = elem.getAttribute( name );
-
-		if ( typeof data === "string" ) {
-			try {
-				data = data === "true" ? true :
-				data === "false" ? false :
-				data === "null" ? null :
-				!jQuery.isNaN( data ) ? parseFloat( data ) :
-					rbrace.test( data ) ? jQuery.parseJSON( data ) :
-					data;
-			} catch( e ) {}
-
-			// Make sure we set the data so it isn't changed later
-			jQuery.data( elem, key, data );
-
-		} else {
-			data = undefined;
-		}
-	}
-
-	return data;
-}
-
-// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
-// property to be considered empty objects; this property always exists in
-// order to make sure JSON.stringify does not expose internal metadata
-function isEmptyDataObject( obj ) {
-	for ( var name in obj ) {
-		if ( name !== "toJSON" ) {
-			return false;
-		}
-	}
-
-	return true;
-}
-
-
-
-
-function handleQueueMarkDefer( elem, type, src ) {
-	var deferDataKey = type + "defer",
-		queueDataKey = type + "queue",
-		markDataKey = type + "mark",
-		defer = jQuery.data( elem, deferDataKey, undefined, true );
-	if ( defer &&
-		( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
-		( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
-		// Give room for hard-coded callbacks to fire first
-		// and eventually mark/queue something else on the element
-		setTimeout( function() {
-			if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
-				!jQuery.data( elem, markDataKey, undefined, true ) ) {
-				jQuery.removeData( elem, deferDataKey, true );
-				defer.resolve();
-			}
-		}, 0 );
-	}
-}
-
-jQuery.extend({
-
-	_mark: function( elem, type ) {
-		if ( elem ) {
-			type = (type || "fx") + "mark";
-			jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
-		}
-	},
-
-	_unmark: function( force, elem, type ) {
-		if ( force !== true ) {
-			type = elem;
-			elem = force;
-			force = false;
-		}
-		if ( elem ) {
-			type = type || "fx";
-			var key = type + "mark",
-				count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
-			if ( count ) {
-				jQuery.data( elem, key, count, true );
-			} else {
-				jQuery.removeData( elem, key, true );
-				handleQueueMarkDefer( elem, type, "mark" );
-			}
-		}
-	},
-
-	queue: function( elem, type, data ) {
-		if ( elem ) {
-			type = (type || "fx") + "queue";
-			var q = jQuery.data( elem, type, undefined, true );
-			// Speed up dequeue by getting out quickly if this is just a lookup
-			if ( data ) {
-				if ( !q || jQuery.isArray(data) ) {
-					q = jQuery.data( elem, type, jQuery.makeArray(data), true );
-				} else {
-					q.push( data );
-				}
-			}
-			return q || [];
-		}
-	},
-
-	dequeue: function( elem, type ) {
-		type = type || "fx";
-
-		var queue = jQuery.queue( elem, type ),
-			fn = queue.shift(),
-			defer;
-
-		// If the fx queue is dequeued, always remove the progress sentinel
-		if ( fn === "inprogress" ) {
-			fn = queue.shift();
-		}
-
-		if ( fn ) {
-			// Add a progress sentinel to prevent the fx queue from being
-			// automatically dequeued
-			if ( type === "fx" ) {
-				queue.unshift("inprogress");
-			}
-
-			fn.call(elem, function() {
-				jQuery.dequeue(elem, type);
-			});
-		}
-
-		if ( !queue.length ) {
-			jQuery.removeData( elem, type + "queue", true );
-			handleQueueMarkDefer( elem, type, "queue" );
-		}
-	}
-});
-
-jQuery.fn.extend({
-	queue: function( type, data ) {
-		if ( typeof type !== "string" ) {
-			data = type;
-			type = "fx";
-		}
-
-		if ( data === undefined ) {
-			return jQuery.queue( this[0], type );
-		}
-		return this.each(function() {
-			var queue = jQuery.queue( this, type, data );
-
-			if ( type === "fx" && queue[0] !== "inprogress" ) {
-				jQuery.dequeue( this, type );
-			}
-		});
-	},
-	dequeue: function( type ) {
-		return this.each(function() {
-			jQuery.dequeue( this, type );
-		});
-	},
-	// Based off of the plugin by Clint Helfers, with permission.
-	// http://blindsignals.com/index.php/2009/07/jquery-delay/
-	delay: function( time, type ) {
-		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
-		type = type || "fx";
-
-		return this.queue( type, function() {
-			var elem = this;
-			setTimeout(function() {
-				jQuery.dequeue( elem, type );
-			}, time );
-		});
-	},
-	clearQueue: function( type ) {
-		return this.queue( type || "fx", [] );
-	},
-	// Get a promise resolved when queues of a certain type
-	// are emptied (fx is the type by default)
-	promise: function( type, object ) {
-		if ( typeof type !== "string" ) {
-			object = type;
-			type = undefined;
-		}
-		type = type || "fx";
-		var defer = jQuery.Deferred(),
-			elements = this,
-			i = elements.length,
-			count = 1,
-			deferDataKey = type + "defer",
-			queueDataKey = type + "queue",
-			markDataKey = type + "mark",
-			tmp;
-		function resolve() {
-			if ( !( --count ) ) {
-				defer.resolveWith( elements, [ elements ] );
-			}
-		}
-		while( i-- ) {
-			if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
-					( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
-						jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
-					jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
-				count++;
-				tmp.done( resolve );
-			}
-		}
-		resolve();
-		return defer.promise();
-	}
-});
-
-
-
-
-var rclass = /[\n\t\r]/g,
-	rspace = /\s+/,
-	rreturn = /\r/g,
-	rtype = /^(?:button|input)$/i,
-	rfocusable = /^(?:button|input|object|select|textarea)$/i,
-	rclickable = /^a(?:rea)?$/i,
-	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
-	nodeHook, boolHook;
-
-jQuery.fn.extend({
-	attr: function( name, value ) {
-		return jQuery.access( this, name, value, true, jQuery.attr );
-	},
-
-	removeAttr: function( name ) {
-		return this.each(function() {
-			jQuery.removeAttr( this, name );
-		});
-	},
-	
-	prop: function( name, value ) {
-		return jQuery.access( this, name, value, true, jQuery.prop );
-	},
-	
-	removeProp: function( name ) {
-		name = jQuery.propFix[ name ] || name;
-		return this.each(function() {
-			// try/catch handles cases where IE balks (such as removing a property on window)
-			try {
-				this[ name ] = undefined;
-				delete this[ name ];
-			} catch( e ) {}
-		});
-	},
-
-	addClass: function( value ) {
-		var classNames, i, l, elem,
-			setClass, c, cl;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( j ) {
-				jQuery( this ).addClass( value.call(this, j, this.className) );
-			});
-		}
-
-		if ( value && typeof value === "string" ) {
-			classNames = value.split( rspace );
-
-			for ( i = 0, l = this.length; i < l; i++ ) {
-				elem = this[ i ];
-
-				if ( elem.nodeType === 1 ) {
-					if ( !elem.className && classNames.length === 1 ) {
-						elem.className = value;
-
-					} else {
-						setClass = " " + elem.className + " ";
-
-						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
-							if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
-								setClass += classNames[ c ] + " ";
-							}
-						}
-						elem.className = jQuery.trim( setClass );
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	removeClass: function( value ) {
-		var classNames, i, l, elem, className, c, cl;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( j ) {
-				jQuery( this ).removeClass( value.call(this, j, this.className) );
-			});
-		}
-
-		if ( (value && typeof value === "string") || value === undefined ) {
-			classNames = (value || "").split( rspace );
-
-			for ( i = 0, l = this.length; i < l; i++ ) {
-				elem = this[ i ];
-
-				if ( elem.nodeType === 1 && elem.className ) {
-					if ( value ) {
-						className = (" " + elem.className + " ").replace( rclass, " " );
-						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
-							className = className.replace(" " + classNames[ c ] + " ", " ");
-						}
-						elem.className = jQuery.trim( className );
-
-					} else {
-						elem.className = "";
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	toggleClass: function( value, stateVal ) {
-		var type = typeof value,
-			isBool = typeof stateVal === "boolean";
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( i ) {
-				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
-			});
-		}
-
-		return this.each(function() {
-			if ( type === "string" ) {
-				// toggle individual class names
-				var className,
-					i = 0,
-					self = jQuery( this ),
-					state = stateVal,
-					classNames = value.split( rspace );
-
-				while ( (className = classNames[ i++ ]) ) {
-					// check each className given, space seperated list
-					state = isBool ? state : !self.hasClass( className );
-					self[ state ? "addClass" : "removeClass" ]( className );
-				}
-
-			} else if ( type === "undefined" || type === "boolean" ) {
-				if ( this.className ) {
-					// store className if set
-					jQuery._data( this, "__className__", this.className );
-				}
-
-				// toggle whole className
-				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
-			}
-		});
-	},
-
-	hasClass: function( selector ) {
-		var className = " " + selector + " ";
-		for ( var i = 0, l = this.length; i < l; i++ ) {
-			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
-				return true;
-			}
-		}
-
-		return false;
-	},
-
-	val: function( value ) {
-		var hooks, ret,
-			elem = this[0];
-		
-		if ( !arguments.length ) {
-			if ( elem ) {
-				hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
-
-				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
-					return ret;
-				}
-
-				ret = elem.value;
-
-				return typeof ret === "string" ? 
-					// handle most common string cases
-					ret.replace(rreturn, "") : 
-					// handle cases where value is null/undef or number
-					ret == null ? "" : ret;
-			}
-
-			return undefined;
-		}
-
-		var isFunction = jQuery.isFunction( value );
-
-		return this.each(function( i ) {
-			var self = jQuery(this), val;
-
-			if ( this.nodeType !== 1 ) {
-				return;
-			}
-
-			if ( isFunction ) {
-				val = value.call( this, i, self.val() );
-			} else {
-				val = value;
-			}
-
-			// Treat null/undefined as ""; convert numbers to string
-			if ( val == null ) {
-				val = "";
-			} else if ( typeof val === "number" ) {
-				val += "";
-			} else if ( jQuery.isArray( val ) ) {
-				val = jQuery.map(val, function ( value ) {
-					return value == null ? "" : value + "";
-				});
-			}
-
-			hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
-
-			// If set returns undefined, fall back to normal setting
-			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
-				this.value = val;
-			}
-		});
-	}
-});
-
-jQuery.extend({
-	valHooks: {
-		option: {
-			get: function( elem ) {
-				// attributes.value is undefined in Blackberry 4.7 but
-				// uses .value. See #6932
-				var val = elem.attributes.value;
-				return !val || val.specified ? elem.value : elem.text;
-			}
-		},
-		select: {
-			get: function( elem ) {
-				var value,
-					index = elem.selectedIndex,
-					values = [],
-					options = elem.options,
-					one = elem.type === "select-one";
-
-				// Nothing was selected
-				if ( index < 0 ) {
-					return null;
-				}
-
-				// Loop through all the selected options
-				for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
-					var option = options[ i ];
-
-					// Don't return options that are disabled or in a disabled optgroup
-					if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
-							(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
-
-						// Get the specific value for the option
-						value = jQuery( option ).val();
-
-						// We don't need an array for one selects
-						if ( one ) {
-							return value;
-						}
-
-						// Multi-Selects return an array
-						values.push( value );
-					}
-				}
-
-				// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
-				if ( one && !values.length && options.length ) {
-					return jQuery( options[ index ] ).val();
-				}
-
-				return values;
-			},
-
-			set: function( elem, value ) {
-				var values = jQuery.makeArray( value );
-
-				jQuery(elem).find("option").each(function() {
-					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
-				});
-
-				if ( !values.length ) {
-					elem.selectedIndex = -1;
-				}
-				return values;
-			}
-		}
-	},
-
-	attrFn: {
-		val: true,
-		css: true,
-		html: true,
-		text: true,
-		data: true,
-		width: true,
-		height: true,
-		offset: true
-	},
-	
-	attrFix: {
-		// Always normalize to ensure hook usage
-		tabindex: "tabIndex"
-	},
-	
-	attr: function( elem, name, value, pass ) {
-		var nType = elem.nodeType;
-		
-		// don't get/set attributes on text, comment and attribute nodes
-		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-			return undefined;
-		}
-
-		if ( pass && name in jQuery.attrFn ) {
-			return jQuery( elem )[ name ]( value );
-		}
-
-		// Fallback to prop when attributes are not supported
-		if ( !("getAttribute" in elem) ) {
-			return jQuery.prop( elem, name, value );
-		}
-
-		var ret, hooks,
-			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
-		// Normalize the name if needed
-		if ( notxml ) {
-			name = jQuery.attrFix[ name ] || name;
-
-			hooks = jQuery.attrHooks[ name ];
-
-			if ( !hooks ) {
-				// Use boolHook for boolean attributes
-				if ( rboolean.test( name ) ) {
-					hooks = boolHook;
-
-				// Use nodeHook if available( IE6/7 )
-				} else if ( nodeHook ) {
-					hooks = nodeHook;
-				}
-			}
-		}
-
-		if ( value !== undefined ) {
-
-			if ( value === null ) {
-				jQuery.removeAttr( elem, name );
-				return undefined;
-
-			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
-				return ret;
-
-			} else {
-				elem.setAttribute( name, "" + value );
-				return value;
-			}
-
-		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
-			return ret;
-
-		} else {
-
-			ret = elem.getAttribute( name );
-
-			// Non-existent attributes return null, we normalize to undefined
-			return ret === null ?
-				undefined :
-				ret;
-		}
-	},
-
-	removeAttr: function( elem, name ) {
-		var propName;
-		if ( elem.nodeType === 1 ) {
-			name = jQuery.attrFix[ name ] || name;
-
-			jQuery.attr( elem, name, "" );
-			elem.removeAttribute( name );
-
-			// Set corresponding property to false for boolean attributes
-			if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
-				elem[ propName ] = false;
-			}
-		}
-	},
-
-	attrHooks: {
-		type: {
-			set: function( elem, value ) {
-				// We can't allow the type property to be changed (since it causes problems in IE)
-				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
-					jQuery.error( "type property can't be changed" );
-				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
-					// Setting the type on a radio button after the value resets the value in IE6-9
-					// Reset value to it's default in case type is set after value
-					// This is for element creation
-					var val = elem.value;
-					elem.setAttribute( "type", value );
-					if ( val ) {
-						elem.value = val;
-					}
-					return value;
-				}
-			}
-		},
-		// Use the value property for back compat
-		// Use the nodeHook for button elements in IE6/7 (#1954)
-		value: {
-			get: function( elem, name ) {
-				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
-					return nodeHook.get( elem, name );
-				}
-				return name in elem ?
-					elem.value :
-					null;
-			},
-			set: function( elem, value, name ) {
-				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
-					return nodeHook.set( elem, value, name );
-				}
-				// Does not return so that setAttribute is also used
-				elem.value = value;
-			}
-		}
-	},
-
-	propFix: {
-		tabindex: "tabIndex",
-		readonly: "readOnly",
-		"for": "htmlFor",
-		"class": "className",
-		maxlength: "maxLength",
-		cellspacing: "cellSpacing",
-		cellpadding: "cellPadding",
-		rowspan: "rowSpan",
-		colspan: "colSpan",
-		usemap: "useMap",
-		frameborder: "frameBorder",
-		contenteditable: "contentEditable"
-	},
-	
-	prop: function( elem, name, value ) {
-		var nType = elem.nodeType;
-
-		// don't get/set properties on text, comment and attribute nodes
-		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-			return undefined;
-		}
-
-		var ret, hooks,
-			notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
-		if ( notxml ) {
-			// Fix name and attach hooks
-			name = jQuery.propFix[ name ] || name;
-			hooks = jQuery.propHooks[ name ];
-		}
-
-		if ( value !== undefined ) {
-			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
-				return ret;
-
-			} else {
-				return (elem[ name ] = value);
-			}
-
-		} else {
-			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
-				return ret;
-
-			} else {
-				return elem[ name ];
-			}
-		}
-	},
-	
-	propHooks: {
-		tabIndex: {
-			get: function( elem ) {
-				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
-				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-				var attributeNode = elem.getAttributeNode("tabindex");
-
-				return attributeNode && attributeNode.specified ?
-					parseInt( attributeNode.value, 10 ) :
-					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
-						0 :
-						undefined;
-			}
-		}
-	}
-});
-
-// Add the tabindex propHook to attrHooks for back-compat
-jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;
-
-// Hook for boolean attributes
-boolHook = {
-	get: function( elem, name ) {
-		// Align boolean attributes with corresponding properties
-		// Fall back to attribute presence where some booleans are not supported
-		var attrNode;
-		return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?
-			name.toLowerCase() :
-			undefined;
-	},
-	set: function( elem, value, name ) {
-		var propName;
-		if ( value === false ) {
-			// Remove boolean attributes when set to false
-			jQuery.removeAttr( elem, name );
-		} else {
-			// value is true since we know at this point it's type boolean and not false
-			// Set boolean attributes to the same name and set the DOM property
-			propName = jQuery.propFix[ name ] || name;
-			if ( propName in elem ) {
-				// Only set the IDL specifically if it already exists on the element
-				elem[ propName ] = true;
-			}
-
-			elem.setAttribute( name, name.toLowerCase() );
-		}
-		return name;
-	}
-};
-
-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !jQuery.support.getSetAttribute ) {
-	
-	// Use this for any attribute in IE6/7
-	// This fixes almost every IE6/7 issue
-	nodeHook = jQuery.valHooks.button = {
-		get: function( elem, name ) {
-			var ret;
-			ret = elem.getAttributeNode( name );
-			// Return undefined if nodeValue is empty string
-			return ret && ret.nodeValue !== "" ?
-				ret.nodeValue :
-				undefined;
-		},
-		set: function( elem, value, name ) {
-			// Set the existing or create a new attribute node
-			var ret = elem.getAttributeNode( name );
-			if ( !ret ) {
-				ret = document.createAttribute( name );
-				elem.setAttributeNode( ret );
-			}
-			return (ret.nodeValue = value + "");
-		}
-	};
-
-	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
-	// This is for removals
-	jQuery.each([ "width", "height" ], function( i, name ) {
-		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
-			set: function( elem, value ) {
-				if ( value === "" ) {
-					elem.setAttribute( name, "auto" );
-					return value;
-				}
-			}
-		});
-	});
-}
-
-
-// Some attributes require a special call on IE
-if ( !jQuery.support.hrefNormalized ) {
-	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
-		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
-			get: function( elem ) {
-				var ret = elem.getAttribute( name, 2 );
-				return ret === null ? undefined : ret;
-			}
-		});
-	});
-}
-
-if ( !jQuery.support.style ) {
-	jQuery.attrHooks.style = {
-		get: function( elem ) {
-			// Return undefined in the case of empty string
-			// Normalize to lowercase since IE uppercases css property names
-			return elem.style.cssText.toLowerCase() || undefined;
-		},
-		set: function( elem, value ) {
-			return (elem.style.cssText = "" + value);
-		}
-	};
-}
-
-// Safari mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !jQuery.support.optSelected ) {
-	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
-		get: function( elem ) {
-			var parent = elem.parentNode;
-
-			if ( parent ) {
-				parent.selectedIndex;
-
-				// Make sure that it also works with optgroups, see #5701
-				if ( parent.parentNode ) {
-					parent.parentNode.selectedIndex;
-				}
-			}
-			return null;
-		}
-	});
-}
-
-// Radios and checkboxes getter/setter
-if ( !jQuery.support.checkOn ) {
-	jQuery.each([ "radio", "checkbox" ], function() {
-		jQuery.valHooks[ this ] = {
-			get: function( elem ) {
-				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
-				return elem.getAttribute("value") === null ? "on" : elem.value;
-			}
-		};
-	});
-}
-jQuery.each([ "radio", "checkbox" ], function() {
-	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
-		set: function( elem, value ) {
-			if ( jQuery.isArray( value ) ) {
-				return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
-			}
-		}
-	});
-});
-
-
-
-
-var rnamespaces = /\.(.*)$/,
-	rformElems = /^(?:textarea|input|select)$/i,
-	rperiod = /\./g,
-	rspaces = / /g,
-	rescape = /[^\w\s.|`]/g,
-	fcleanup = function( nm ) {
-		return nm.replace(rescape, "\\$&");
-	};
-
-/*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code originated from
- * Dean Edwards' addEvent library.
- */
-jQuery.event = {
-
-	// Bind an event to an element
-	// Original by Dean Edwards
-	add: function( elem, types, handler, data ) {
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		if ( handler === false ) {
-			handler = returnFalse;
-		} else if ( !handler ) {
-			// Fixes bug #7229. Fix recommended by jdalton
-			return;
-		}
-
-		var handleObjIn, handleObj;
-
-		if ( handler.handler ) {
-			handleObjIn = handler;
-			handler = handleObjIn.handler;
-		}
-
-		// Make sure that the function being executed has a unique ID
-		if ( !handler.guid ) {
-			handler.guid = jQuery.guid++;
-		}
-
-		// Init the element's event structure
-		var elemData = jQuery._data( elem );
-
-		// If no elemData is found then we must be trying to bind to one of the
-		// banned noData elements
-		if ( !elemData ) {
-			return;
-		}
-
-		var events = elemData.events,
-			eventHandle = elemData.handle;
-
-		if ( !events ) {
-			elemData.events = events = {};
-		}
-
-		if ( !eventHandle ) {
-			elemData.handle = eventHandle = function( e ) {
-				// Discard the second event of a jQuery.event.trigger() and
-				// when an event is called after a page has unloaded
-				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
-					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
-					undefined;
-			};
-		}
-
-		// Add elem as a property of the handle function
-		// This is to prevent a memory leak with non-native events in IE.
-		eventHandle.elem = elem;
-
-		// Handle multiple events separated by a space
-		// jQuery(...).bind("mouseover mouseout", fn);
-		types = types.split(" ");
-
-		var type, i = 0, namespaces;
-
-		while ( (type = types[ i++ ]) ) {
-			handleObj = handleObjIn ?
-				jQuery.extend({}, handleObjIn) :
-				{ handler: handler, data: data };
-
-			// Namespaced event handlers
-			if ( type.indexOf(".") > -1 ) {
-				namespaces = type.split(".");
-				type = namespaces.shift();
-				handleObj.namespace = namespaces.slice(0).sort().join(".");
-
-			} else {
-				namespaces = [];
-				handleObj.namespace = "";
-			}
-
-			handleObj.type = type;
-			if ( !handleObj.guid ) {
-				handleObj.guid = handler.guid;
-			}
-
-			// Get the current list of functions bound to this event
-			var handlers = events[ type ],
-				special = jQuery.event.special[ type ] || {};
-
-			// Init the event handler queue
-			if ( !handlers ) {
-				handlers = events[ type ] = [];
-
-				// Check for a special event handler
-				// Only use addEventListener/attachEvent if the special
-				// events handler returns false
-				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-					// Bind the global event handler to the element
-					if ( elem.addEventListener ) {
-						elem.addEventListener( type, eventHandle, false );
-
-					} else if ( elem.attachEvent ) {
-						elem.attachEvent( "on" + type, eventHandle );
-					}
-				}
-			}
-
-			if ( special.add ) {
-				special.add.call( elem, handleObj );
-
-				if ( !handleObj.handler.guid ) {
-					handleObj.handler.guid = handler.guid;
-				}
-			}
-
-			// Add the function to the element's handler list
-			handlers.push( handleObj );
-
-			// Keep track of which events have been used, for event optimization
-			jQuery.event.global[ type ] = true;
-		}
-
-		// Nullify elem to prevent memory leaks in IE
-		elem = null;
-	},
-
-	global: {},
-
-	// Detach an event or set of events from an element
-	remove: function( elem, types, handler, pos ) {
-		// don't do events on text and comment nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		if ( handler === false ) {
-			handler = returnFalse;
-		}
-
-		var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
-			elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
-			events = elemData && elemData.events;
-
-		if ( !elemData || !events ) {
-			return;
-		}
-
-		// types is actually an event object here
-		if ( types && types.type ) {
-			handler = types.handler;
-			types = types.type;
-		}
-
-		// Unbind all events for the element
-		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
-			types = types || "";
-
-			for ( type in events ) {
-				jQuery.event.remove( elem, type + types );
-			}
-
-			return;
-		}
-
-		// Handle multiple events separated by a space
-		// jQuery(...).unbind("mouseover mouseout", fn);
-		types = types.split(" ");
-
-		while ( (type = types[ i++ ]) ) {
-			origType = type;
-			handleObj = null;
-			all = type.indexOf(".") < 0;
-			namespaces = [];
-
-			if ( !all ) {
-				// Namespaced event handlers
-				namespaces = type.split(".");
-				type = namespaces.shift();
-
-				namespace = new RegExp("(^|\\.)" +
-					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
-			}
-
-			eventType = events[ type ];
-
-			if ( !eventType ) {
-				continue;
-			}
-
-			if ( !handler ) {
-				for ( j = 0; j < eventType.length; j++ ) {
-					handleObj = eventType[ j ];
-
-					if ( all || namespace.test( handleObj.namespace ) ) {
-						jQuery.event.remove( elem, origType, handleObj.handler, j );
-						eventType.splice( j--, 1 );
-					}
-				}
-
-				continue;
-			}
-
-			special = jQuery.event.special[ type ] || {};
-
-			for ( j = pos || 0; j < eventType.length; j++ ) {
-				handleObj = eventType[ j ];
-
-				if ( handler.guid === handleObj.guid ) {
-					// remove the given handler for the given type
-					if ( all || namespace.test( handleObj.namespace ) ) {
-						if ( pos == null ) {
-							eventType.splice( j--, 1 );
-						}
-
-						if ( special.remove ) {
-							special.remove.call( elem, handleObj );
-						}
-					}
-
-					if ( pos != null ) {
-						break;
-					}
-				}
-			}
-
-			// remove generic event handler if no more handlers exist
-			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
-				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
-					jQuery.removeEvent( elem, type, elemData.handle );
-				}
-
-				ret = null;
-				delete events[ type ];
-			}
-		}
-
-		// Remove the expando if it's no longer used
-		if ( jQuery.isEmptyObject( events ) ) {
-			var handle = elemData.handle;
-			if ( handle ) {
-				handle.elem = null;
-			}
-
-			delete elemData.events;
-			delete elemData.handle;
-
-			if ( jQuery.isEmptyObject( elemData ) ) {
-				jQuery.removeData( elem, undefined, true );
-			}
-		}
-	},
-	
-	// Events that are safe to short-circuit if no handlers are attached.
-	// Native DOM events should not be added, they may have inline handlers.
-	customEvent: {
-		"getData": true,
-		"setData": true,
-		"changeData": true
-	},
-
-	trigger: function( event, data, elem, onlyHandlers ) {
-		// Event object or event type
-		var type = event.type || event,
-			namespaces = [],
-			exclusive;
-
-		if ( type.indexOf("!") >= 0 ) {
-			// Exclusive events trigger only for the exact event (no namespaces)
-			type = type.slice(0, -1);
-			exclusive = true;
-		}
-
-		if ( type.indexOf(".") >= 0 ) {
-			// Namespaced trigger; create a regexp to match event type in handle()
-			namespaces = type.split(".");
-			type = namespaces.shift();
-			namespaces.sort();
-		}
-
-		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
-			// No jQuery handlers for this event type, and it can't have inline handlers
-			return;
-		}
-
-		// Caller can pass in an Event, Object, or just an event type string
-		event = typeof event === "object" ?
-			// jQuery.Event object
-			event[ jQuery.expando ] ? event :
-			// Object literal
-			new jQuery.Event( type, event ) :
-			// Just the event type (string)
-			new jQuery.Event( type );
-
-		event.type = type;
-		event.exclusive = exclusive;
-		event.namespace = namespaces.join(".");
-		event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
-		
-		// triggerHandler() and global events don't bubble or run the default action
-		if ( onlyHandlers || !elem ) {
-			event.preventDefault();
-			event.stopPropagation();
-		}
-
-		// Handle a global trigger
-		if ( !elem ) {
-			// TODO: Stop taunting the data cache; remove global events and always attach to document
-			jQuery.each( jQuery.cache, function() {
-				// internalKey variable is just used to make it easier to find
-				// and potentially change this stuff later; currently it just
-				// points to jQuery.expando
-				var internalKey = jQuery.expando,
-					internalCache = this[ internalKey ];
-				if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
-					jQuery.event.trigger( event, data, internalCache.handle.elem );
-				}
-			});
-			return;
-		}
-
-		// Don't do events on text and comment nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		// Clean up the event in case it is being reused
-		event.result = undefined;
-		event.target = elem;
-
-		// Clone any incoming data and prepend the event, creating the handler arg list
-		data = data != null ? jQuery.makeArray( data ) : [];
-		data.unshift( event );
-
-		var cur = elem,
-			// IE doesn't like method names with a colon (#3533, #8272)
-			ontype = type.indexOf(":") < 0 ? "on" + type : "";
-
-		// Fire event on the current element, then bubble up the DOM tree
-		do {
-			var handle = jQuery._data( cur, "handle" );
-
-			event.currentTarget = cur;
-			if ( handle ) {
-				handle.apply( cur, data );
-			}
-
-			// Trigger an inline bound script
-			if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
-				event.result = false;
-				event.preventDefault();
-			}
-
-			// Bubble up to document, then to window
-			cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
-		} while ( cur && !event.isPropagationStopped() );
-
-		// If nobody prevented the default action, do it now
-		if ( !event.isDefaultPrevented() ) {
-			var old,
-				special = jQuery.event.special[ type ] || {};
-
-			if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
-				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
-
-				// Call a native DOM method on the target with the same name name as the event.
-				// Can't use an .isFunction)() check here because IE6/7 fails that test.
-				// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
-				try {
-					if ( ontype && elem[ type ] ) {
-						// Don't re-trigger an onFOO event when we call its FOO() method
-						old = elem[ ontype ];
-
-						if ( old ) {
-							elem[ ontype ] = null;
-						}
-
-						jQuery.event.triggered = type;
-						elem[ type ]();
-					}
-				} catch ( ieError ) {}
-
-				if ( old ) {
-					elem[ ontype ] = old;
-				}
-
-				jQuery.event.triggered = undefined;
-			}
-		}
-		
-		return event.result;
-	},
-
-	handle: function( event ) {
-		event = jQuery.event.fix( event || window.event );
-		// Snapshot the handlers list since a called handler may add/remove events.
-		var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
-			run_all = !event.exclusive && !event.namespace,
-			args = Array.prototype.slice.call( arguments, 0 );
-
-		// Use the fix-ed Event rather than the (read-only) native event
-		args[0] = event;
-		event.currentTarget = this;
-
-		for ( var j = 0, l = handlers.length; j < l; j++ ) {
-			var handleObj = handlers[ j ];
-
-			// Triggered event must 1) be non-exclusive and have no namespace, or
-			// 2) have namespace(s) a subset or equal to those in the bound event.
-			if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
-				// Pass in a reference to the handler function itself
-				// So that we can later remove it
-				event.handler = handleObj.handler;
-				event.data = handleObj.data;
-				event.handleObj = handleObj;
-
-				var ret = handleObj.handler.apply( this, args );
-
-				if ( ret !== undefined ) {
-					event.result = ret;
-					if ( ret === false ) {
-						event.preventDefault();
-						event.stopPropagation();
-					}
-				}
-
-				if ( event.isImmediatePropagationStopped() ) {
-					break;
-				}
-			}
-		}
-		return event.result;
-	},
-
-	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
-
-	fix: function( event ) {
-		if ( event[ jQuery.expando ] ) {
-			return event;
-		}
-
-		// store a copy of the original event object
-		// and "clone" to set read-only properties
-		var originalEvent = event;
-		event = jQuery.Event( originalEvent );
-
-		for ( var i = this.props.length, prop; i; ) {
-			prop = this.props[ --i ];
-			event[ prop ] = originalEvent[ prop ];
-		}
-
-		// Fix target property, if necessary
-		if ( !event.target ) {
-			// Fixes #1925 where srcElement might not be defined either
-			event.target = event.srcElement || document;
-		}
-
-		// check if target is a textnode (safari)
-		if ( event.target.nodeType === 3 ) {
-			event.target = event.target.parentNode;
-		}
-
-		// Add relatedTarget, if necessary
-		if ( !event.relatedTarget && event.fromElement ) {
-			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
-		}
-
-		// Calculate pageX/Y if missing and clientX/Y available
-		if ( event.pageX == null && event.clientX != null ) {
-			var eventDocument = event.target.ownerDocument || document,
-				doc = eventDocument.documentElement,
-				body = eventDocument.body;
-
-			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
-			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
-		}
-
-		// Add which for key events
-		if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
-			event.which = event.charCode != null ? event.charCode : event.keyCode;
-		}
-
-		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
-		if ( !event.metaKey && event.ctrlKey ) {
-			event.metaKey = event.ctrlKey;
-		}
-
-		// Add which for click: 1 === left; 2 === middle; 3 === right
-		// Note: button is not normalized, so don't use it
-		if ( !event.which && event.button !== undefined ) {
-			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
-		}
-
-		return event;
-	},
-
-	// Deprecated, use jQuery.guid instead
-	guid: 1E8,
-
-	// Deprecated, use jQuery.proxy instead
-	proxy: jQuery.proxy,
-
-	special: {
-		ready: {
-			// Make sure the ready event is setup
-			setup: jQuery.bindReady,
-			teardown: jQuery.noop
-		},
-
-		live: {
-			add: function( handleObj ) {
-				jQuery.event.add( this,
-					liveConvert( handleObj.origType, handleObj.selector ),
-					jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
-			},
-
-			remove: function( handleObj ) {
-				jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
-			}
-		},
-
-		beforeunload: {
-			setup: function( data, namespaces, eventHandle ) {
-				// We only want to do this special case on windows
-				if ( jQuery.isWindow( this ) ) {
-					this.onbeforeunload = eventHandle;
-				}
-			},
-
-			teardown: function( namespaces, eventHandle ) {
-				if ( this.onbeforeunload === eventHandle ) {
-					this.onbeforeunload = null;
-				}
-			}
-		}
-	}
-};
-
-jQuery.removeEvent = document.removeEventListener ?
-	function( elem, type, handle ) {
-		if ( elem.removeEventListener ) {
-			elem.removeEventListener( type, handle, false );
-		}
-	} :
-	function( elem, type, handle ) {
-		if ( elem.detachEvent ) {
-			elem.detachEvent( "on" + type, handle );
-		}
-	};
-
-jQuery.Event = function( src, props ) {
-	// Allow instantiation without the 'new' keyword
-	if ( !this.preventDefault ) {
-		return new jQuery.Event( src, props );
-	}
-
-	// Event object
-	if ( src && src.type ) {
-		this.originalEvent = src;
-		this.type = src.type;
-
-		// Events bubbling up the document may have been marked as prevented
-		// by a handler lower down the tree; reflect the correct value.
-		this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
-			src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
-
-	// Event type
-	} else {
-		this.type = src;
-	}
-
-	// Put explicitly provided properties onto the event object
-	if ( props ) {
-		jQuery.extend( this, props );
-	}
-
-	// timeStamp is buggy for some events on Firefox(#3843)
-	// So we won't rely on the native value
-	this.timeStamp = jQuery.now();
-
-	// Mark it as fixed
-	this[ jQuery.expando ] = true;
-};
-
-function returnFalse() {
-	return false;
-}
-function returnTrue() {
-	return true;
-}
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
-	preventDefault: function() {
-		this.isDefaultPrevented = returnTrue;
-
-		var e = this.originalEvent;
-		if ( !e ) {
-			return;
-		}
-
-		// if preventDefault exists run it on the original event
-		if ( e.preventDefault ) {
-			e.preventDefault();
-
-		// otherwise set the returnValue property of the original event to false (IE)
-		} else {
-			e.returnValue = false;
-		}
-	},
-	stopPropagation: function() {
-		this.isPropagationStopped = returnTrue;
-
-		var e = this.originalEvent;
-		if ( !e ) {
-			return;
-		}
-		// if stopPropagation exists run it on the original event
-		if ( e.stopPropagation ) {
-			e.stopPropagation();
-		}
-		// otherwise set the cancelBubble property of the original event to true (IE)
-		e.cancelBubble = true;
-	},
-	stopImmediatePropagation: function() {
-		this.isImmediatePropagationStopped = returnTrue;
-		this.stopPropagation();
-	},
-	isDefaultPrevented: returnFalse,
-	isPropagationStopped: returnFalse,
-	isImmediatePropagationStopped: returnFalse
-};
-
-// Checks if an event happened on an element within another element
-// Used in jQuery.event.special.mouseenter and mouseleave handlers
-var withinElement = function( event ) {
-
-	// Check if mouse(over|out) are still within the same parent element
-	var related = event.relatedTarget,
-		inside = false,
-		eventType = event.type;
-
-	event.type = event.data;
-
-	if ( related !== this ) {
-
-		if ( related ) {
-			inside = jQuery.contains( this, related );
-		}
-
-		if ( !inside ) {
-
-			jQuery.event.handle.apply( this, arguments );
-
-			event.type = eventType;
-		}
-	}
-},
-
-// In case of event delegation, we only need to rename the event.type,
-// liveHandler will take care of the rest.
-delegate = function( event ) {
-	event.type = event.data;
-	jQuery.event.handle.apply( this, arguments );
-};
-
-// Create mouseenter and mouseleave events
-jQuery.each({
-	mouseenter: "mouseover",
-	mouseleave: "mouseout"
-}, function( orig, fix ) {
-	jQuery.event.special[ orig ] = {
-		setup: function( data ) {
-			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
-		},
-		teardown: function( data ) {
-			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
-		}
-	};
-});
-
-// submit delegation
-if ( !jQuery.support.submitBubbles ) {
-
-	jQuery.event.special.submit = {
-		setup: function( data, namespaces ) {
-			if ( !jQuery.nodeName( this, "form" ) ) {
-				jQuery.event.add(this, "click.specialSubmit", function( e ) {
-					// Avoid triggering error on non-existent type attribute in IE VML (#7071)
-					var elem = e.target,
-						type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
-
-					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
-						trigger( "submit", this, arguments );
-					}
-				});
-
-				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
-					var elem = e.target,
-						type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
-
-					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
-						trigger( "submit", this, arguments );
-					}
-				});
-
-			} else {
-				return false;
-			}
-		},
-
-		teardown: function( namespaces ) {
-			jQuery.event.remove( this, ".specialSubmit" );
-		}
-	};
-
-}
-
-// change delegation, happens here so we have bind.
-if ( !jQuery.support.changeBubbles ) {
-
-	var changeFilters,
-
-	getVal = function( elem ) {
-		var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
-			val = elem.value;
-
-		if ( type === "radio" || type === "checkbox" ) {
-			val = elem.checked;
-
-		} else if ( type === "select-multiple" ) {
-			val = elem.selectedIndex > -1 ?
-				jQuery.map( elem.options, function( elem ) {
-					return elem.selected;
-				}).join("-") :
-				"";
-
-		} else if ( jQuery.nodeName( elem, "select" ) ) {
-			val = elem.selectedIndex;
-		}
-
-		return val;
-	},
-
-	testChange = function testChange( e ) {
-		var elem = e.target, data, val;
-
-		if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
-			return;
-		}
-
-		data = jQuery._data( elem, "_change_data" );
-		val = getVal(elem);
-
-		// the current data will be also retrieved by beforeactivate
-		if ( e.type !== "focusout" || elem.type !== "radio" ) {
-			jQuery._data( elem, "_change_data", val );
-		}
-
-		if ( data === undefined || val === data ) {
-			return;
-		}
-
-		if ( data != null || val ) {
-			e.type = "change";
-			e.liveFired = undefined;
-			jQuery.event.trigger( e, arguments[1], elem );
-		}
-	};
-
-	jQuery.event.special.change = {
-		filters: {
-			focusout: testChange,
-
-			beforedeactivate: testChange,
-
-			click: function( e ) {
-				var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
-
-				if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
-					testChange.call( this, e );
-				}
-			},
-
-			// Change has to be called before submit
-			// Keydown will be called before keypress, which is used in submit-event delegation
-			keydown: function( e ) {
-				var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
-
-				if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
-					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
-					type === "select-multiple" ) {
-					testChange.call( this, e );
-				}
-			},
-
-			// Beforeactivate happens also before the previous element is blurred
-			// with this event you can't trigger a change event, but you can store
-			// information
-			beforeactivate: function( e ) {
-				var elem = e.target;
-				jQuery._data( elem, "_change_data", getVal(elem) );
-			}
-		},
-
-		setup: function( data, namespaces ) {
-			if ( this.type === "file" ) {
-				return false;
-			}
-
-			for ( var type in changeFilters ) {
-				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
-			}
-
-			return rformElems.test( this.nodeName );
-		},
-
-		teardown: function( namespaces ) {
-			jQuery.event.remove( this, ".specialChange" );
-
-			return rformElems.test( this.nodeName );
-		}
-	};
-
-	changeFilters = jQuery.event.special.change.filters;
-
-	// Handle when the input is .focus()'d
-	changeFilters.focus = changeFilters.beforeactivate;
-}
-
-function trigger( type, elem, args ) {
-	// Piggyback on a donor event to simulate a different one.
-	// Fake originalEvent to avoid donor's stopPropagation, but if the
-	// simulated event prevents default then we do the same on the donor.
-	// Don't pass args or remember liveFired; they apply to the donor event.
-	var event = jQuery.extend( {}, args[ 0 ] );
-	event.type = type;
-	event.originalEvent = {};
-	event.liveFired = undefined;
-	jQuery.event.handle.call( elem, event );
-	if ( event.isDefaultPrevented() ) {
-		args[ 0 ].preventDefault();
-	}
-}
-
-// Create "bubbling" focus and blur events
-if ( !jQuery.support.focusinBubbles ) {
-	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
-		// Attach a single capturing handler while someone wants focusin/focusout
-		var attaches = 0;
-
-		jQuery.event.special[ fix ] = {
-			setup: function() {
-				if ( attaches++ === 0 ) {
-					document.addEventListener( orig, handler, true );
-				}
-			},
-			teardown: function() {
-				if ( --attaches === 0 ) {
-					document.removeEventListener( orig, handler, true );
-				}
-			}
-		};
-
-		function handler( donor ) {
-			// Donor event is always a native one; fix it and switch its type.
-			// Let focusin/out handler cancel the donor focus/blur event.
-			var e = jQuery.event.fix( donor );
-			e.type = fix;
-			e.originalEvent = {};
-			jQuery.event.trigger( e, null, e.target );
-			if ( e.isDefaultPrevented() ) {
-				donor.preventDefault();
-			}
-		}
-	});
-}
-
-jQuery.each(["bind", "one"], function( i, name ) {
-	jQuery.fn[ name ] = function( type, data, fn ) {
-		var handler;
-
-		// Handle object literals
-		if ( typeof type === "object" ) {
-			for ( var key in type ) {
-				this[ name ](key, data, type[key], fn);
-			}
-			return this;
-		}
-
-		if ( arguments.length === 2 || data === false ) {
-			fn = data;
-			data = undefined;
-		}
-
-		if ( name === "one" ) {
-			handler = function( event ) {
-				jQuery( this ).unbind( event, handler );
-				return fn.apply( this, arguments );
-			};
-			handler.guid = fn.guid || jQuery.guid++;
-		} else {
-			handler = fn;
-		}
-
-		if ( type === "unload" && name !== "one" ) {
-			this.one( type, data, fn );
-
-		} else {
-			for ( var i = 0, l = this.length; i < l; i++ ) {
-				jQuery.event.add( this[i], type, handler, data );
-			}
-		}
-
-		return this;
-	};
-});
-
-jQuery.fn.extend({
-	unbind: function( type, fn ) {
-		// Handle object literals
-		if ( typeof type === "object" && !type.preventDefault ) {
-			for ( var key in type ) {
-				this.unbind(key, type[key]);
-			}
-
-		} else {
-			for ( var i = 0, l = this.length; i < l; i++ ) {
-				jQuery.event.remove( this[i], type, fn );
-			}
-		}
-
-		return this;
-	},
-
-	delegate: function( selector, types, data, fn ) {
-		return this.live( types, data, fn, selector );
-	},
-
-	undelegate: function( selector, types, fn ) {
-		if ( arguments.length === 0 ) {
-			return this.unbind( "live" );
-
-		} else {
-			return this.die( types, null, fn, selector );
-		}
-	},
-
-	trigger: function( type, data ) {
-		return this.each(function() {
-			jQuery.event.trigger( type, data, this );
-		});
-	},
-
-	triggerHandler: function( type, data ) {
-		if ( this[0] ) {
-			return jQuery.event.trigger( type, data, this[0], true );
-		}
-	},
-
-	toggle: function( fn ) {
-		// Save reference to arguments for access in closure
-		var args = arguments,
-			guid = fn.guid || jQuery.guid++,
-			i = 0,
-			toggler = function( event ) {
-				// Figure out which function to execute
-				var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
-				jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
-				// Make sure that clicks stop
-				event.preventDefault();
-
-				// and execute the function
-				return args[ lastToggle ].apply( this, arguments ) || false;
-			};
-
-		// link all the functions, so any of them can unbind this click handler
-		toggler.guid = guid;
-		while ( i < args.length ) {
-			args[ i++ ].guid = guid;
-		}
-
-		return this.click( toggler );
-	},
-
-	hover: function( fnOver, fnOut ) {
-		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
-	}
-});
-
-var liveMap = {
-	focus: "focusin",
-	blur: "focusout",
-	mouseenter: "mouseover",
-	mouseleave: "mouseout"
-};
-
-jQuery.each(["live", "die"], function( i, name ) {
-	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
-		var type, i = 0, match, namespaces, preType,
-			selector = origSelector || this.selector,
-			context = origSelector ? this : jQuery( this.context );
-
-		if ( typeof types === "object" && !types.preventDefault ) {
-			for ( var key in types ) {
-				context[ name ]( key, data, types[key], selector );
-			}
-
-			return this;
-		}
-
-		if ( name === "die" && !types &&
-					origSelector && origSelector.charAt(0) === "." ) {
-
-			context.unbind( origSelector );
-
-			return this;
-		}
-
-		if ( data === false || jQuery.isFunction( data ) ) {
-			fn = data || returnFalse;
-			data = undefined;
-		}
-
-		types = (types || "").split(" ");
-
-		while ( (type = types[ i++ ]) != null ) {
-			match = rnamespaces.exec( type );
-			namespaces = "";
-
-			if ( match )  {
-				namespaces = match[0];
-				type = type.replace( rnamespaces, "" );
-			}
-
-			if ( type === "hover" ) {
-				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
-				continue;
-			}
-
-			preType = type;
-
-			if ( liveMap[ type ] ) {
-				types.push( liveMap[ type ] + namespaces );
-				type = type + namespaces;
-
-			} else {
-				type = (liveMap[ type ] || type) + namespaces;
-			}
-
-			if ( name === "live" ) {
-				// bind live handler
-				for ( var j = 0, l = context.length; j < l; j++ ) {
-					jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
-						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
-				}
-
-			} else {
-				// unbind live handler
-				context.unbind( "live." + liveConvert( type, selector ), fn );
-			}
-		}
-
-		return this;
-	};
-});
-
-function liveHandler( event ) {
-	var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
-		elems = [],
-		selectors = [],
-		events = jQuery._data( this, "events" );
-
-	// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
-	if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
-		return;
-	}
-
-	if ( event.namespace ) {
-		namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
-	}
-
-	event.liveFired = this;
-
-	var live = events.live.slice(0);
-
-	for ( j = 0; j < live.length; j++ ) {
-		handleObj = live[j];
-
-		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
-			selectors.push( handleObj.selector );
-
-		} else {
-			live.splice( j--, 1 );
-		}
-	}
-
-	match = jQuery( event.target ).closest( selectors, event.currentTarget );
-
-	for ( i = 0, l = match.length; i < l; i++ ) {
-		close = match[i];
-
-		for ( j = 0; j < live.length; j++ ) {
-			handleObj = live[j];
-
-			if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
-				elem = close.elem;
-				related = null;
-
-				// Those two events require additional checking
-				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
-					event.type = handleObj.preType;
-					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
-
-					// Make sure not to accidentally match a child element with the same selector
-					if ( related && jQuery.contains( elem, related ) ) {
-						related = elem;
-					}
-				}
-
-				if ( !related || related !== elem ) {
-					elems.push({ elem: elem, handleObj: handleObj, level: close.level });
-				}
-			}
-		}
-	}
-
-	for ( i = 0, l = elems.length; i < l; i++ ) {
-		match = elems[i];
-
-		if ( maxLevel && match.level > maxLevel ) {
-			break;
-		}
-
-		event.currentTarget = match.elem;
-		event.data = match.handleObj.data;
-		event.handleObj = match.handleObj;
-
-		ret = match.handleObj.origHandler.apply( match.elem, arguments );
-
-		if ( ret === false || event.isPropagationStopped() ) {
-			maxLevel = match.level;
-
-			if ( ret === false ) {
-				stop = false;
-			}
-			if ( event.isImmediatePropagationStopped() ) {
-				break;
-			}
-		}
-	}
-
-	return stop;
-}
-
-function liveConvert( type, selector ) {
-	return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
-}
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
-	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
-	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
-
-	// Handle event binding
-	jQuery.fn[ name ] = function( data, fn ) {
-		if ( fn == null ) {
-			fn = data;
-			data = null;
-		}
-
-		return arguments.length > 0 ?
-			this.bind( name, data, fn ) :
-			this.trigger( name );
-	};
-
-	if ( jQuery.attrFn ) {
-		jQuery.attrFn[ name ] = true;
-	}
-});
-
-
-
-/*!
- * Sizzle CSS Selector Engine
- *  Copyright 2011, The Dojo Foundation
- *  Released under the MIT, BSD, and GPL Licenses.
- *  More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
-	done = 0,
-	toString = Object.prototype.toString,
-	hasDuplicate = false,
-	baseHasDuplicate = true,
-	rBackslash = /\\/g,
-	rNonWord = /\W/;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-//   Thus far that includes Google Chrome.
-[0, 0].sort(function() {
-	baseHasDuplicate = false;
-	return 0;
-});
-
-var Sizzle = function( selector, context, results, seed ) {
-	results = results || [];
-	context = context || document;
-
-	var origContext = context;
-
-	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
-		return [];
-	}
-	
-	if ( !selector || typeof selector !== "string" ) {
-		return results;
-	}
-
-	var m, set, checkSet, extra, ret, cur, pop, i,
-		prune = true,
-		contextXML = Sizzle.isXML( context ),
-		parts = [],
-		soFar = selector;
-	
-	// Reset the position of the chunker regexp (start from head)
-	do {
-		chunker.exec( "" );
-		m = chunker.exec( soFar );
-
-		if ( m ) {
-			soFar = m[3];
-		
-			parts.push( m[1] );
-		
-			if ( m[2] ) {
-				extra = m[3];
-				break;
-			}
-		}
-	} while ( m );
-
-	if ( parts.length > 1 && origPOS.exec( selector ) ) {
-
-		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
-			set = posProcess( parts[0] + parts[1], context );
-
-		} else {
-			set = Expr.relative[ parts[0] ] ?
-				[ context ] :
-				Sizzle( parts.shift(), context );
-
-			while ( parts.length ) {
-				selector = parts.shift();
-
-				if ( Expr.relative[ selector ] ) {
-					selector += parts.shift();
-				}
-				
-				set = posProcess( selector, set );
-			}
-		}
-
-	} else {
-		// Take a shortcut and set the context if the root selector is an ID
-		// (but not if it'll be faster if the inner selector is an ID)
-		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
-				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
-
-			ret = Sizzle.find( parts.shift(), context, contextXML );
-			context = ret.expr ?
-				Sizzle.filter( ret.expr, ret.set )[0] :
-				ret.set[0];
-		}
-
-		if ( context ) {
-			ret = seed ?
-				{ expr: parts.pop(), set: makeArray(seed) } :
-				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
-
-			set = ret.expr ?
-				Sizzle.filter( ret.expr, ret.set ) :
-				ret.set;
-
-			if ( parts.length > 0 ) {
-				checkSet = makeArray( set );
-
-			} else {
-				prune = false;
-			}
-
-			while ( parts.length ) {
-				cur = parts.pop();
-				pop = cur;
-
-				if ( !Expr.relative[ cur ] ) {
-					cur = "";
-				} else {
-					pop = parts.pop();
-				}
-
-				if ( pop == null ) {
-					pop = context;
-				}
-
-				Expr.relative[ cur ]( checkSet, pop, contextXML );
-			}
-
-		} else {
-			checkSet = parts = [];
-		}
-	}
-
-	if ( !checkSet ) {
-		checkSet = set;
-	}
-
-	if ( !checkSet ) {
-		Sizzle.error( cur || selector );
-	}
-
-	if ( toString.call(checkSet) === "[object Array]" ) {
-		if ( !prune ) {
-			results.push.apply( results, checkSet );
-
-		} else if ( context && context.nodeType === 1 ) {
-			for ( i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
-					results.push( set[i] );
-				}
-			}
-
-		} else {
-			for ( i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
-					results.push( set[i] );
-				}
-			}
-		}
-
-	} else {
-		makeArray( checkSet, results );
-	}
-
-	if ( extra ) {
-		Sizzle( extra, origContext, results, seed );
-		Sizzle.uniqueSort( results );
-	}
-
-	return results;
-};
-
-Sizzle.uniqueSort = function( results ) {
-	if ( sortOrder ) {
-		hasDuplicate = baseHasDuplicate;
-		results.sort( sortOrder );
-
-		if ( hasDuplicate ) {
-			for ( var i = 1; i < results.length; i++ ) {
-				if ( results[i] === results[ i - 1 ] ) {
-					results.splice( i--, 1 );
-				}
-			}
-		}
-	}
-
-	return results;
-};
-
-Sizzle.matches = function( expr, set ) {
-	return Sizzle( expr, null, null, set );
-};
-
-Sizzle.matchesSelector = function( node, expr ) {
-	return Sizzle( expr, null, null, [node] ).length > 0;
-};
-
-Sizzle.find = function( expr, context, isXML ) {
-	var set;
-
-	if ( !expr ) {
-		return [];
-	}
-
-	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
-		var match,
-			type = Expr.order[i];
-		
-		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
-			var left = match[1];
-			match.splice( 1, 1 );
-
-			if ( left.substr( left.length - 1 ) !== "\\" ) {
-				match[1] = (match[1] || "").replace( rBackslash, "" );
-				set = Expr.find[ type ]( match, context, isXML );
-
-				if ( set != null ) {
-					expr = expr.replace( Expr.match[ type ], "" );
-					break;
-				}
-			}
-		}
-	}
-
-	if ( !set ) {
-		set = typeof context.getElementsByTagName !== "undefined" ?
-			context.getElementsByTagName( "*" ) :
-			[];
-	}
-
-	return { set: set, expr: expr };
-};
-
-Sizzle.filter = function( expr, set, inplace, not ) {
-	var match, anyFound,
-		old = expr,
-		result = [],
-		curLoop = set,
-		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
-
-	while ( expr && set.length ) {
-		for ( var type in Expr.filter ) {
-			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
-				var found, item,
-					filter = Expr.filter[ type ],
-					left = match[1];
-
-				anyFound = false;
-
-				match.splice(1,1);
-
-				if ( left.substr( left.length - 1 ) === "\\" ) {
-					continue;
-				}
-
-				if ( curLoop === result ) {
-					result = [];
-				}
-
-				if ( Expr.preFilter[ type ] ) {
-					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
-					if ( !match ) {
-						anyFound = found = true;
-
-					} else if ( match === true ) {
-						continue;
-					}
-				}
-
-				if ( match ) {
-					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
-						if ( item ) {
-							found = filter( item, match, i, curLoop );
-							var pass = not ^ !!found;
-
-							if ( inplace && found != null ) {
-								if ( pass ) {
-									anyFound = true;
-
-								} else {
-									curLoop[i] = false;
-								}
-
-							} else if ( pass ) {
-								result.push( item );
-								anyFound = true;
-							}
-						}
-					}
-				}
-
-				if ( found !== undefined ) {
-					if ( !inplace ) {
-						curLoop = result;
-					}
-
-					expr = expr.replace( Expr.match[ type ], "" );
-
-					if ( !anyFound ) {
-						return [];
-					}
-
-					break;
-				}
-			}
-		}
-
-		// Improper expression
-		if ( expr === old ) {
-			if ( anyFound == null ) {
-				Sizzle.error( expr );
-
-			} else {
-				break;
-			}
-		}
-
-		old = expr;
-	}
-
-	return curLoop;
-};
-
-Sizzle.error = function( msg ) {
-	throw "Syntax error, unrecognized expression: " + msg;
-};
-
-var Expr = Sizzle.selectors = {
-	order: [ "ID", "NAME", "TAG" ],
-
-	match: {
-		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
-		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
-		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
-		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
-		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
-		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
-		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
-		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
-	},
-
-	leftMatch: {},
-
-	attrMap: {
-		"class": "className",
-		"for": "htmlFor"
-	},
-
-	attrHandle: {
-		href: function( elem ) {
-			return elem.getAttribute( "href" );
-		},
-		type: function( elem ) {
-			return elem.getAttribute( "type" );
-		}
-	},
-
-	relative: {
-		"+": function(checkSet, part){
-			var isPartStr = typeof part === "string",
-				isTag = isPartStr && !rNonWord.test( part ),
-				isPartStrNotTag = isPartStr && !isTag;
-
-			if ( isTag ) {
-				part = part.toLowerCase();
-			}
-
-			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
-				if ( (elem = checkSet[i]) ) {
-					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
-					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
-						elem || false :
-						elem === part;
-				}
-			}
-
-			if ( isPartStrNotTag ) {
-				Sizzle.filter( part, checkSet, true );
-			}
-		},
-
-		">": function( checkSet, part ) {
-			var elem,
-				isPartStr = typeof part === "string",
-				i = 0,
-				l = checkSet.length;
-
-			if ( isPartStr && !rNonWord.test( part ) ) {
-				part = part.toLowerCase();
-
-				for ( ; i < l; i++ ) {
-					elem = checkSet[i];
-
-					if ( elem ) {
-						var parent = elem.parentNode;
-						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
-					}
-				}
-
-			} else {
-				for ( ; i < l; i++ ) {
-					elem = checkSet[i];
-
-					if ( elem ) {
-						checkSet[i] = isPartStr ?
-							elem.parentNode :
-							elem.parentNode === part;
-					}
-				}
-
-				if ( isPartStr ) {
-					Sizzle.filter( part, checkSet, true );
-				}
-			}
-		},
-
-		"": function(checkSet, part, isXML){
-			var nodeCheck,
-				doneName = done++,
-				checkFn = dirCheck;
-
-			if ( typeof part === "string" && !rNonWord.test( part ) ) {
-				part = part.toLowerCase();
-				nodeCheck = part;
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
-		},
-
-		"~": function( checkSet, part, isXML ) {
-			var nodeCheck,
-				doneName = done++,
-				checkFn = dirCheck;
-
-			if ( typeof part === "string" && !rNonWord.test( part ) ) {
-				part = part.toLowerCase();
-				nodeCheck = part;
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
-		}
-	},
-
-	find: {
-		ID: function( match, context, isXML ) {
-			if ( typeof context.getElementById !== "undefined" && !isXML ) {
-				var m = context.getElementById(match[1]);
-				// Check parentNode to catch when Blackberry 4.6 returns
-				// nodes that are no longer in the document #6963
-				return m && m.parentNode ? [m] : [];
-			}
-		},
-
-		NAME: function( match, context ) {
-			if ( typeof context.getElementsByName !== "undefined" ) {
-				var ret = [],
-					results = context.getElementsByName( match[1] );
-
-				for ( var i = 0, l = results.length; i < l; i++ ) {
-					if ( results[i].getAttribute("name") === match[1] ) {
-						ret.push( results[i] );
-					}
-				}
-
-				return ret.length === 0 ? null : ret;
-			}
-		},
-
-		TAG: function( match, context ) {
-			if ( typeof context.getElementsByTagName !== "undefined" ) {
-				return context.getElementsByTagName( match[1] );
-			}
-		}
-	},
-	preFilter: {
-		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
-			match = " " + match[1].replace( rBackslash, "" ) + " ";
-
-			if ( isXML ) {
-				return match;
-			}
-
-			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
-				if ( elem ) {
-					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
-						if ( !inplace ) {
-							result.push( elem );
-						}
-
-					} else if ( inplace ) {
-						curLoop[i] = false;
-					}
-				}
-			}
-
-			return false;
-		},
-
-		ID: function( match ) {
-			return match[1].replace( rBackslash, "" );
-		},
-
-		TAG: function( match, curLoop ) {
-			return match[1].replace( rBackslash, "" ).toLowerCase();
-		},
-
-		CHILD: function( match ) {
-			if ( match[1] === "nth" ) {
-				if ( !match[2] ) {
-					Sizzle.error( match[0] );
-				}
-
-				match[2] = match[2].replace(/^\+|\s*/g, '');
-
-				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
-				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
-					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
-					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
-				// calculate the numbers (first)n+(last) including if they are negative
-				match[2] = (test[1] + (test[2] || 1)) - 0;
-				match[3] = test[3] - 0;
-			}
-			else if ( match[2] ) {
-				Sizzle.error( match[0] );
-			}
-
-			// TODO: Move to normal caching system
-			match[0] = done++;
-
-			return match;
-		},
-
-		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
-			var name = match[1] = match[1].replace( rBackslash, "" );
-			
-			if ( !isXML && Expr.attrMap[name] ) {
-				match[1] = Expr.attrMap[name];
-			}
-
-			// Handle if an un-quoted value was used
-			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
-
-			if ( match[2] === "~=" ) {
-				match[4] = " " + match[4] + " ";
-			}
-
-			return match;
-		},
-
-		PSEUDO: function( match, curLoop, inplace, result, not ) {
-			if ( match[1] === "not" ) {
-				// If we're dealing with a complex expression, or a simple one
-				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
-					match[3] = Sizzle(match[3], null, null, curLoop);
-
-				} else {
-					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-
-					if ( !inplace ) {
-						result.push.apply( result, ret );
-					}
-
-					return false;
-				}
-
-			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
-				return true;
-			}
-			
-			return match;
-		},
-
-		POS: function( match ) {
-			match.unshift( true );
-
-			return match;
-		}
-	},
-	
-	filters: {
-		enabled: function( elem ) {
-			return elem.disabled === false && elem.type !== "hidden";
-		},
-
-		disabled: function( elem ) {
-			return elem.disabled === true;
-		},
-
-		checked: function( elem ) {
-			return elem.checked === true;
-		},
-		
-		selected: function( elem ) {
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			if ( elem.parentNode ) {
-				elem.parentNode.selectedIndex;
-			}
-			
-			return elem.selected === true;
-		},
-
-		parent: function( elem ) {
-			return !!elem.firstChild;
-		},
-
-		empty: function( elem ) {
-			return !elem.firstChild;
-		},
-
-		has: function( elem, i, match ) {
-			return !!Sizzle( match[3], elem ).length;
-		},
-
-		header: function( elem ) {
-			return (/h\d/i).test( elem.nodeName );
-		},
-
-		text: function( elem ) {
-			var attr = elem.getAttribute( "type" ), type = elem.type;
-			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
-			// use getAttribute instead to test this case
-			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
-		},
-
-		radio: function( elem ) {
-			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
-		},
-
-		checkbox: function( elem ) {
-			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
-		},
-
-		file: function( elem ) {
-			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
-		},
-
-		password: function( elem ) {
-			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
-		},
-
-		submit: function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return (name === "input" || name === "button") && "submit" === elem.type;
-		},
-
-		image: function( elem ) {
-			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
-		},
-
-		reset: function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return (name === "input" || name === "button") && "reset" === elem.type;
-		},
-
-		button: function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return name === "input" && "button" === elem.type || name === "button";
-		},
-
-		input: function( elem ) {
-			return (/input|select|textarea|button/i).test( elem.nodeName );
-		},
-
-		focus: function( elem ) {
-			return elem === elem.ownerDocument.activeElement;
-		}
-	},
-	setFilters: {
-		first: function( elem, i ) {
-			return i === 0;
-		},
-
-		last: function( elem, i, match, array ) {
-			return i === array.length - 1;
-		},
-
-		even: function( elem, i ) {
-			return i % 2 === 0;
-		},
-
-		odd: function( elem, i ) {
-			return i % 2 === 1;
-		},
-
-		lt: function( elem, i, match ) {
-			return i < match[3] - 0;
-		},
-
-		gt: function( elem, i, match ) {
-			return i > match[3] - 0;
-		},
-
-		nth: function( elem, i, match ) {
-			return match[3] - 0 === i;
-		},
-
-		eq: function( elem, i, match ) {
-			return match[3] - 0 === i;
-		}
-	},
-	filter: {
-		PSEUDO: function( elem, match, i, array ) {
-			var name = match[1],
-				filter = Expr.filters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-
-			} else if ( name === "contains" ) {
-				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
-
-			} else if ( name === "not" ) {
-				var not = match[3];
-
-				for ( var j = 0, l = not.length; j < l; j++ ) {
-					if ( not[j] === elem ) {
-						return false;
-					}
-				}
-
-				return true;
-
-			} else {
-				Sizzle.error( name );
-			}
-		},
-
-		CHILD: function( elem, match ) {
-			var type = match[1],
-				node = elem;
-
-			switch ( type ) {
-				case "only":
-				case "first":
-					while ( (node = node.previousSibling) )	 {
-						if ( node.nodeType === 1 ) { 
-							return false; 
-						}
-					}
-
-					if ( type === "first" ) { 
-						return true; 
-					}
-
-					node = elem;
-
-				case "last":
-					while ( (node = node.nextSibling) )	 {
-						if ( node.nodeType === 1 ) { 
-							return false; 
-						}
-					}
-
-					return true;
-
-				case "nth":
-					var first = match[2],
-						last = match[3];
-
-					if ( first === 1 && last === 0 ) {
-						return true;
-					}
-					
-					var doneName = match[0],
-						parent = elem.parentNode;
-	
-					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
-						var count = 0;
-						
-						for ( node = parent.firstChild; node; node = node.nextSibling ) {
-							if ( node.nodeType === 1 ) {
-								node.nodeIndex = ++count;
-							}
-						} 
-
-						parent.sizcache = doneName;
-					}
-					
-					var diff = elem.nodeIndex - last;
-
-					if ( first === 0 ) {
-						return diff === 0;
-
-					} else {
-						return ( diff % first === 0 && diff / first >= 0 );
-					}
-			}
-		},
-
-		ID: function( elem, match ) {
-			return elem.nodeType === 1 && elem.getAttribute("id") === match;
-		},
-
-		TAG: function( elem, match ) {
-			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
-		},
-		
-		CLASS: function( elem, match ) {
-			return (" " + (elem.className || elem.getAttribute("class")) + " ")
-				.indexOf( match ) > -1;
-		},
-
-		ATTR: function( elem, match ) {
-			var name = match[1],
-				result = Expr.attrHandle[ name ] ?
-					Expr.attrHandle[ name ]( elem ) :
-					elem[ name ] != null ?
-						elem[ name ] :
-						elem.getAttribute( name ),
-				value = result + "",
-				type = match[2],
-				check = match[4];
-
-			return result == null ?
-				type === "!=" :
-				type === "=" ?
-				value === check :
-				type === "*=" ?
-				value.indexOf(check) >= 0 :
-				type === "~=" ?
-				(" " + value + " ").indexOf(check) >= 0 :
-				!check ?
-				value && result !== false :
-				type === "!=" ?
-				value !== check :
-				type === "^=" ?
-				value.indexOf(check) === 0 :
-				type === "$=" ?
-				value.substr(value.length - check.length) === check :
-				type === "|=" ?
-				value === check || value.substr(0, check.length + 1) === check + "-" :
-				false;
-		},
-
-		POS: function( elem, match, i, array ) {
-			var name = match[2],
-				filter = Expr.setFilters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-			}
-		}
-	}
-};
-
-var origPOS = Expr.match.POS,
-	fescape = function(all, num){
-		return "\\" + (num - 0 + 1);
-	};
-
-for ( var type in Expr.match ) {
-	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
-	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
-}
-
-var makeArray = function( array, results ) {
-	array = Array.prototype.slice.call( array, 0 );
-
-	if ( results ) {
-		results.push.apply( results, array );
-		return results;
-	}
-	
-	return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-// Also verifies that the returned array holds DOM nodes
-// (which is not the case in the Blackberry browser)
-try {
-	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
-
-// Provide a fallback method if it does not work
-} catch( e ) {
-	makeArray = function( array, results ) {
-		var i = 0,
-			ret = results || [];
-
-		if ( toString.call(array) === "[object Array]" ) {
-			Array.prototype.push.apply( ret, array );
-
-		} else {
-			if ( typeof array.length === "number" ) {
-				for ( var l = array.length; i < l; i++ ) {
-					ret.push( array[i] );
-				}
-
-			} else {
-				for ( ; array[i]; i++ ) {
-					ret.push( array[i] );
-				}
-			}
-		}
-
-		return ret;
-	};
-}
-
-var sortOrder, siblingCheck;
-
-if ( document.documentElement.compareDocumentPosition ) {
-	sortOrder = function( a, b ) {
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
-			return a.compareDocumentPosition ? -1 : 1;
-		}
-
-		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
-	};
-
-} else {
-	sortOrder = function( a, b ) {
-		// The nodes are identical, we can exit early
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-
-		// Fallback to using sourceIndex (in IE) if it's available on both nodes
-		} else if ( a.sourceIndex && b.sourceIndex ) {
-			return a.sourceIndex - b.sourceIndex;
-		}
-
-		var al, bl,
-			ap = [],
-			bp = [],
-			aup = a.parentNode,
-			bup = b.parentNode,
-			cur = aup;
-
-		// If the nodes are siblings (or identical) we can do a quick check
-		if ( aup === bup ) {
-			return siblingCheck( a, b );
-
-		// If no parents were found then the nodes are disconnected
-		} else if ( !aup ) {
-			return -1;
-
-		} else if ( !bup ) {
-			return 1;
-		}
-
-		// Otherwise they're somewhere else in the tree so we need
-		// to build up a full list of the parentNodes for comparison
-		while ( cur ) {
-			ap.unshift( cur );
-			cur = cur.parentNode;
-		}
-
-		cur = bup;
-
-		while ( cur ) {
-			bp.unshift( cur );
-			cur = cur.parentNode;
-		}
-
-		al = ap.length;
-		bl = bp.length;
-
-		// Start walking down the tree looking for a discrepancy
-		for ( var i = 0; i < al && i < bl; i++ ) {
-			if ( ap[i] !== bp[i] ) {
-				return siblingCheck( ap[i], bp[i] );
-			}
-		}
-
-		// We ended someplace up the tree so do a sibling check
-		return i === al ?
-			siblingCheck( a, bp[i], -1 ) :
-			siblingCheck( ap[i], b, 1 );
-	};
-
-	siblingCheck = function( a, b, ret ) {
-		if ( a === b ) {
-			return ret;
-		}
-
-		var cur = a.nextSibling;
-
-		while ( cur ) {
-			if ( cur === b ) {
-				return -1;
-			}
-
-			cur = cur.nextSibling;
-		}
-
-		return 1;
-	};
-}
-
-// Utility function for retreiving the text value of an array of DOM nodes
-Sizzle.getText = function( elems ) {
-	var ret = "", elem;
-
-	for ( var i = 0; elems[i]; i++ ) {
-		elem = elems[i];
-
-		// Get the text from text nodes and CDATA nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
-			ret += elem.nodeValue;
-
-		// Traverse everything else, except comment nodes
-		} else if ( elem.nodeType !== 8 ) {
-			ret += Sizzle.getText( elem.childNodes );
-		}
-	}
-
-	return ret;
-};
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
-	// We're going to inject a fake input element with a specified name
-	var form = document.createElement("div"),
-		id = "script" + (new Date()).getTime(),
-		root = document.documentElement;
-
-	form.innerHTML = "<a name='" + id + "'/>";
-
-	// Inject it into the root element, check its status, and remove it quickly
-	root.insertBefore( form, root.firstChild );
-
-	// The workaround has to do additional checks after a getElementById
-	// Which slows things down for other browsers (hence the branching)
-	if ( document.getElementById( id ) ) {
-		Expr.find.ID = function( match, context, isXML ) {
-			if ( typeof context.getElementById !== "undefined" && !isXML ) {
-				var m = context.getElementById(match[1]);
-
-				return m ?
-					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
-						[m] :
-						undefined :
-					[];
-			}
-		};
-
-		Expr.filter.ID = function( elem, match ) {
-			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-
-			return elem.nodeType === 1 && node && node.nodeValue === match;
-		};
-	}
-
-	root.removeChild( form );
-
-	// release memory in IE
-	root = form = null;
-})();
-
-(function(){
-	// Check to see if the browser returns only elements
-	// when doing getElementsByTagName("*")
-
-	// Create a fake element
-	var div = document.createElement("div");
-	div.appendChild( document.createComment("") );
-
-	// Make sure no comments are found
-	if ( div.getElementsByTagName("*").length > 0 ) {
-		Expr.find.TAG = function( match, context ) {
-			var results = context.getElementsByTagName( match[1] );
-
-			// Filter out possible comments
-			if ( match[1] === "*" ) {
-				var tmp = [];
-
-				for ( var i = 0; results[i]; i++ ) {
-					if ( results[i].nodeType === 1 ) {
-						tmp.push( results[i] );
-					}
-				}
-
-				results = tmp;
-			}
-
-			return results;
-		};
-	}
-
-	// Check to see if an attribute returns normalized href attributes
-	div.innerHTML = "<a href='#'></a>";
-
-	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
-			div.firstChild.getAttribute("href") !== "#" ) {
-
-		Expr.attrHandle.href = function( elem ) {
-			return elem.getAttribute( "href", 2 );
-		};
-	}
-
-	// release memory in IE
-	div = null;
-})();
-
-if ( document.querySelectorAll ) {
-	(function(){
-		var oldSizzle = Sizzle,
-			div = document.createElement("div"),
-			id = "__sizzle__";
-
-		div.innerHTML = "<p class='TEST'></p>";
-
-		// Safari can't handle uppercase or unicode characters when
-		// in quirks mode.
-		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
-			return;
-		}
-	
-		Sizzle = function( query, context, extra, seed ) {
-			context = context || document;
-
-			// Only use querySelectorAll on non-XML documents
-			// (ID selectors don't work in non-HTML documents)
-			if ( !seed && !Sizzle.isXML(context) ) {
-				// See if we find a selector to speed up
-				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-				
-				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
-					// Speed-up: Sizzle("TAG")
-					if ( match[1] ) {
-						return makeArray( context.getElementsByTagName( query ), extra );
-					
-					// Speed-up: Sizzle(".CLASS")
-					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
-						return makeArray( context.getElementsByClassName( match[2] ), extra );
-					}
-				}
-				
-				if ( context.nodeType === 9 ) {
-					// Speed-up: Sizzle("body")
-					// The body element only exists once, optimize finding it
-					if ( query === "body" && context.body ) {
-						return makeArray( [ context.body ], extra );
-						
-					// Speed-up: Sizzle("#ID")
-					} else if ( match && match[3] ) {
-						var elem = context.getElementById( match[3] );
-
-						// Check parentNode to catch when Blackberry 4.6 returns
-						// nodes that are no longer in the document #6963
-						if ( elem && elem.parentNode ) {
-							// Handle the case where IE and Opera return items
-							// by name instead of ID
-							if ( elem.id === match[3] ) {
-								return makeArray( [ elem ], extra );
-							}
-							
-						} else {
-							return makeArray( [], extra );
-						}
-					}
-					
-					try {
-						return makeArray( context.querySelectorAll(query), extra );
-					} catch(qsaError) {}
-
-				// qSA works strangely on Element-rooted queries
-				// We can work around this by specifying an extra ID on the root
-				// and working up from there (Thanks to Andrew Dupont for the technique)
-				// IE 8 doesn't work on object elements
-				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
-					var oldContext = context,
-						old = context.getAttribute( "id" ),
-						nid = old || id,
-						hasParent = context.parentNode,
-						relativeHierarchySelector = /^\s*[+~]/.test( query );
-
-					if ( !old ) {
-						context.setAttribute( "id", nid );
-					} else {
-						nid = nid.replace( /'/g, "\\$&" );
-					}
-					if ( relativeHierarchySelector && hasParent ) {
-						context = context.parentNode;
-					}
-
-					try {
-						if ( !relativeHierarchySelector || hasParent ) {
-							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
-						}
-
-					} catch(pseudoError) {
-					} finally {
-						if ( !old ) {
-							oldContext.removeAttribute( "id" );
-						}
-					}
-				}
-			}
-		
-			return oldSizzle(query, context, extra, seed);
-		};
-
-		for ( var prop in oldSizzle ) {
-			Sizzle[ prop ] = oldSizzle[ prop ];
-		}
-
-		// release memory in IE
-		div = null;
-	})();
-}
-
-(function(){
-	var html = document.documentElement,
-		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
-
-	if ( matches ) {
-		// Check to see if it's possible to do matchesSelector
-		// on a disconnected node (IE 9 fails this)
-		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
-			pseudoWorks = false;
-
-		try {
-			// This should fail with an exception
-			// Gecko does not error, returns false instead
-			matches.call( document.documentElement, "[test!='']:sizzle" );
-	
-		} catch( pseudoError ) {
-			pseudoWorks = true;
-		}
-
-		Sizzle.matchesSelector = function( node, expr ) {
-			// Make sure that attribute selectors are quoted
-			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
-			if ( !Sizzle.isXML( node ) ) {
-				try { 
-					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
-						var ret = matches.call( node, expr );
-
-						// IE 9's matchesSelector returns false on disconnected nodes
-						if ( ret || !disconnectedMatch ||
-								// As well, disconnected nodes are said to be in a document
-								// fragment in IE 9, so check for that
-								node.document && node.document.nodeType !== 11 ) {
-							return ret;
-						}
-					}
-				} catch(e) {}
-			}
-
-			return Sizzle(expr, null, null, [node]).length > 0;
-		};
-	}
-})();
-
-(function(){
-	var div = document.createElement("div");
-
-	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
-	// Opera can't find a second classname (in 9.6)
-	// Also, make sure that getElementsByClassName actually exists
-	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
-		return;
-	}
-
-	// Safari caches class attributes, doesn't catch changes (in 3.2)
-	div.lastChild.className = "e";
-
-	if ( div.getElementsByClassName("e").length === 1 ) {
-		return;
-	}
-	
-	Expr.order.splice(1, 0, "CLASS");
-	Expr.find.CLASS = function( match, context, isXML ) {
-		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
-			return context.getElementsByClassName(match[1]);
-		}
-	};
-
-	// release memory in IE
-	div = null;
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-
-		if ( elem ) {
-			var match = false;
-
-			elem = elem[dir];
-
-			while ( elem ) {
-				if ( elem.sizcache === doneName ) {
-					match = checkSet[elem.sizset];
-					break;
-				}
-
-				if ( elem.nodeType === 1 && !isXML ){
-					elem.sizcache = doneName;
-					elem.sizset = i;
-				}
-
-				if ( elem.nodeName.toLowerCase() === cur ) {
-					match = elem;
-					break;
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-
-		if ( elem ) {
-			var match = false;
-			
-			elem = elem[dir];
-
-			while ( elem ) {
-				if ( elem.sizcache === doneName ) {
-					match = checkSet[elem.sizset];
-					break;
-				}
-
-				if ( elem.nodeType === 1 ) {
-					if ( !isXML ) {
-						elem.sizcache = doneName;
-						elem.sizset = i;
-					}
-
-					if ( typeof cur !== "string" ) {
-						if ( elem === cur ) {
-							match = true;
-							break;
-						}
-
-					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
-						match = elem;
-						break;
-					}
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-if ( document.documentElement.contains ) {
-	Sizzle.contains = function( a, b ) {
-		return a !== b && (a.contains ? a.contains(b) : true);
-	};
-
-} else if ( document.documentElement.compareDocumentPosition ) {
-	Sizzle.contains = function( a, b ) {
-		return !!(a.compareDocumentPosition(b) & 16);
-	};
-
-} else {
-	Sizzle.contains = function() {
-		return false;
-	};
-}
-
-Sizzle.isXML = function( elem ) {
-	// documentElement is verified for cases where it doesn't yet exist
-	// (such as loading iframes in IE - #4833) 
-	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
-
-	return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-var posProcess = function( selector, context ) {
-	var match,
-		tmpSet = [],
-		later = "",
-		root = context.nodeType ? [context] : context;
-
-	// Position selectors must be done after the filter
-	// And so must :not(positional) so we move all PSEUDOs to the end
-	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
-		later += match[0];
-		selector = selector.replace( Expr.match.PSEUDO, "" );
-	}
-
-	selector = Expr.relative[selector] ? selector + "*" : selector;
-
-	for ( var i = 0, l = root.length; i < l; i++ ) {
-		Sizzle( selector, root[i], tmpSet );
-	}
-
-	return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.filters;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-})();
-
-
-var runtil = /Until$/,
-	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
-	// Note: This RegExp should be improved, or likely pulled from Sizzle
-	rmultiselector = /,/,
-	isSimple = /^.[^:#\[\.,]*$/,
-	slice = Array.prototype.slice,
-	POS = jQuery.expr.match.POS,
-	// methods guaranteed to produce a unique set when starting from a unique set
-	guaranteedUnique = {
-		children: true,
-		contents: true,
-		next: true,
-		prev: true
-	};
-
-jQuery.fn.extend({
-	find: function( selector ) {
-		var self = this,
-			i, l;
-
-		if ( typeof selector !== "string" ) {
-			return jQuery( selector ).filter(function() {
-				for ( i = 0, l = self.length; i < l; i++ ) {
-					if ( jQuery.contains( self[ i ], this ) ) {
-						return true;
-					}
-				}
-			});
-		}
-
-		var ret = this.pushStack( "", "find", selector ),
-			length, n, r;
-
-		for ( i = 0, l = this.length; i < l; i++ ) {
-			length = ret.length;
-			jQuery.find( selector, this[i], ret );
-
-			if ( i > 0 ) {
-				// Make sure that the results are unique
-				for ( n = length; n < ret.length; n++ ) {
-					for ( r = 0; r < length; r++ ) {
-						if ( ret[r] === ret[n] ) {
-							ret.splice(n--, 1);
-							break;
-						}
-					}
-				}
-			}
-		}
-
-		return ret;
-	},
-
-	has: function( target ) {
-		var targets = jQuery( target );
-		return this.filter(function() {
-			for ( var i = 0, l = targets.length; i < l; i++ ) {
-				if ( jQuery.contains( this, targets[i] ) ) {
-					return true;
-				}
-			}
-		});
-	},
-
-	not: function( selector ) {
-		return this.pushStack( winnow(this, selector, false), "not", selector);
-	},
-
-	filter: function( selector ) {
-		return this.pushStack( winnow(this, selector, true), "filter", selector );
-	},
-
-	is: function( selector ) {
-		return !!selector && ( typeof selector === "string" ?
-			jQuery.filter( selector, this ).length > 0 :
-			this.filter( selector ).length > 0 );
-	},
-
-	closest: function( selectors, context ) {
-		var ret = [], i, l, cur = this[0];
-		
-		// Array
-		if ( jQuery.isArray( selectors ) ) {
-			var match, selector,
-				matches = {},
-				level = 1;
-
-			if ( cur && selectors.length ) {
-				for ( i = 0, l = selectors.length; i < l; i++ ) {
-					selector = selectors[i];
-
-					if ( !matches[ selector ] ) {
-						matches[ selector ] = POS.test( selector ) ?
-							jQuery( selector, context || this.context ) :
-							selector;
-					}
-				}
-
-				while ( cur && cur.ownerDocument && cur !== context ) {
-					for ( selector in matches ) {
-						match = matches[ selector ];
-
-						if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
-							ret.push({ selector: selector, elem: cur, level: level });
-						}
-					}
-
-					cur = cur.parentNode;
-					level++;
-				}
-			}
-
-			return ret;
-		}
-
-		// String
-		var pos = POS.test( selectors ) || typeof selectors !== "string" ?
-				jQuery( selectors, context || this.context ) :
-				0;
-
-		for ( i = 0, l = this.length; i < l; i++ ) {
-			cur = this[i];
-
-			while ( cur ) {
-				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
-					ret.push( cur );
-					break;
-
-				} else {
-					cur = cur.parentNode;
-					if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
-						break;
-					}
-				}
-			}
-		}
-
-		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
-
-		return this.pushStack( ret, "closest", selectors );
-	},
-
-	// Determine the position of an element within
-	// the matched set of elements
-	index: function( elem ) {
-
-		// No argument, return index in parent
-		if ( !elem ) {
-			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
-		}
-
-		// index in selector
-		if ( typeof elem === "string" ) {
-			return jQuery.inArray( this[0], jQuery( elem ) );
-		}
-
-		// Locate the position of the desired element
-		return jQuery.inArray(
-			// If it receives a jQuery object, the first element is used
-			elem.jquery ? elem[0] : elem, this );
-	},
-
-	add: function( selector, context ) {
-		var set = typeof selector === "string" ?
-				jQuery( selector, context ) :
-				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
-			all = jQuery.merge( this.get(), set );
-
-		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
-			all :
-			jQuery.unique( all ) );
-	},
-
-	andSelf: function() {
-		return this.add( this.prevObject );
-	}
-});
-
-// A painfully simple check to see if an element is disconnected
-// from a document (should be improved, where feasible).
-function isDisconnected( node ) {
-	return !node || !node.parentNode || node.parentNode.nodeType === 11;
-}
-
-jQuery.each({
-	parent: function( elem ) {
-		var parent = elem.parentNode;
-		return parent && parent.nodeType !== 11 ? parent : null;
-	},
-	parents: function( elem ) {
-		return jQuery.dir( elem, "parentNode" );
-	},
-	parentsUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "parentNode", until );
-	},
-	next: function( elem ) {
-		return jQuery.nth( elem, 2, "nextSibling" );
-	},
-	prev: function( elem ) {
-		return jQuery.nth( elem, 2, "previousSibling" );
-	},
-	nextAll: function( elem ) {
-		return jQuery.dir( elem, "nextSibling" );
-	},
-	prevAll: function( elem ) {
-		return jQuery.dir( elem, "previousSibling" );
-	},
-	nextUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "nextSibling", until );
-	},
-	prevUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "previousSibling", until );
-	},
-	siblings: function( elem ) {
-		return jQuery.sibling( elem.parentNode.firstChild, elem );
-	},
-	children: function( elem ) {
-		return jQuery.sibling( elem.firstChild );
-	},
-	contents: function( elem ) {
-		return jQuery.nodeName( elem, "iframe" ) ?
-			elem.contentDocument || elem.contentWindow.document :
-			jQuery.makeArray( elem.childNodes );
-	}
-}, function( name, fn ) {
-	jQuery.fn[ name ] = function( until, selector ) {
-		var ret = jQuery.map( this, fn, until ),
-			// The variable 'args' was introduced in
-			// https://github.com/jquery/jquery/commit/52a0238
-			// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
-			// http://code.google.com/p/v8/issues/detail?id=1050
-			args = slice.call(arguments);
-
-		if ( !runtil.test( name ) ) {
-			selector = until;
-		}
-
-		if ( selector && typeof selector === "string" ) {
-			ret = jQuery.filter( selector, ret );
-		}
-
-		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
-
-		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
-			ret = ret.reverse();
-		}
-
-		return this.pushStack( ret, name, args.join(",") );
-	};
-});
-
-jQuery.extend({
-	filter: function( expr, elems, not ) {
-		if ( not ) {
-			expr = ":not(" + expr + ")";
-		}
-
-		return elems.length === 1 ?
-			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
-			jQuery.find.matches(expr, elems);
-	},
-
-	dir: function( elem, dir, until ) {
-		var matched = [],
-			cur = elem[ dir ];
-
-		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
-			if ( cur.nodeType === 1 ) {
-				matched.push( cur );
-			}
-			cur = cur[dir];
-		}
-		return matched;
-	},
-
-	nth: function( cur, result, dir, elem ) {
-		result = result || 1;
-		var num = 0;
-
-		for ( ; cur; cur = cur[dir] ) {
-			if ( cur.nodeType === 1 && ++num === result ) {
-				break;
-			}
-		}
-
-		return cur;
-	},
-
-	sibling: function( n, elem ) {
-		var r = [];
-
-		for ( ; n; n = n.nextSibling ) {
-			if ( n.nodeType === 1 && n !== elem ) {
-				r.push( n );
-			}
-		}
-
-		return r;
-	}
-});
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, keep ) {
-
-	// Can't pass null or undefined to indexOf in Firefox 4
-	// Set to 0 to skip string check
-	qualifier = qualifier || 0;
-
-	if ( jQuery.isFunction( qualifier ) ) {
-		return jQuery.grep(elements, function( elem, i ) {
-			var retVal = !!qualifier.call( elem, i, elem );
-			return retVal === keep;
-		});
-
-	} else if ( qualifier.nodeType ) {
-		return jQuery.grep(elements, function( elem, i ) {
-			return (elem === qualifier) === keep;
-		});
-
-	} else if ( typeof qualifier === "string" ) {
-		var filtered = jQuery.grep(elements, function( elem ) {
-			return elem.nodeType === 1;
-		});
-
-		if ( isSimple.test( qualifier ) ) {
-			return jQuery.filter(qualifier, filtered, !keep);
-		} else {
-			qualifier = jQuery.filter( qualifier, filtered );
-		}
-	}
-
-	return jQuery.grep(elements, function( elem, i ) {
-		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
-	});
-}
-
-
-
-
-var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
-	rleadingWhitespace = /^\s+/,
-	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
-	rtagName = /<([\w:]+)/,
-	rtbody = /<tbody/i,
-	rhtml = /<|&#?\w+;/,
-	rnocache = /<(?:script|object|embed|option|style)/i,
-	// checked="checked" or checked
-	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-	rscriptType = /\/(java|ecma)script/i,
-	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
-	wrapMap = {
-		option: [ 1, "<select multiple='multiple'>", "</select>" ],
-		legend: [ 1, "<fieldset>", "</fieldset>" ],
-		thead: [ 1, "<table>", "</table>" ],
-		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
-		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
-		area: [ 1, "<map>", "</map>" ],
-		_default: [ 0, "", "" ]
-	};
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// IE can't serialize <link> and <script> tags normally
-if ( !jQuery.support.htmlSerialize ) {
-	wrapMap._default = [ 1, "div<div>", "</div>" ];
-}
-
-jQuery.fn.extend({
-	text: function( text ) {
-		if ( jQuery.isFunction(text) ) {
-			return this.each(function(i) {
-				var self = jQuery( this );
-
-				self.text( text.call(this, i, self.text()) );
-			});
-		}
-
-		if ( typeof text !== "object" && text !== undefined ) {
-			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-		}
-
-		return jQuery.text( this );
-	},
-
-	wrapAll: function( html ) {
-		if ( jQuery.isFunction( html ) ) {
-			return this.each(function(i) {
-				jQuery(this).wrapAll( html.call(this, i) );
-			});
-		}
-
-		if ( this[0] ) {
-			// The elements to wrap the target around
-			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
-			if ( this[0].parentNode ) {
-				wrap.insertBefore( this[0] );
-			}
-
-			wrap.map(function() {
-				var elem = this;
-
-				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
-					elem = elem.firstChild;
-				}
-
-				return elem;
-			}).append( this );
-		}
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		if ( jQuery.isFunction( html ) ) {
-			return this.each(function(i) {
-				jQuery(this).wrapInner( html.call(this, i) );
-			});
-		}
-
-		return this.each(function() {
-			var self = jQuery( this ),
-				contents = self.contents();
-
-			if ( contents.length ) {
-				contents.wrapAll( html );
-
-			} else {
-				self.append( html );
-			}
-		});
-	},
-
-	wrap: function( html ) {
-		return this.each(function() {
-			jQuery( this ).wrapAll( html );
-		});
-	},
-
-	unwrap: function() {
-		return this.parent().each(function() {
-			if ( !jQuery.nodeName( this, "body" ) ) {
-				jQuery( this ).replaceWith( this.childNodes );
-			}
-		}).end();
-	},
-
-	append: function() {
-		return this.domManip(arguments, true, function( elem ) {
-			if ( this.nodeType === 1 ) {
-				this.appendChild( elem );
-			}
-		});
-	},
-
-	prepend: function() {
-		return this.domManip(arguments, true, function( elem ) {
-			if ( this.nodeType === 1 ) {
-				this.insertBefore( elem, this.firstChild );
-			}
-		});
-	},
-
-	before: function() {
-		if ( this[0] && this[0].parentNode ) {
-			return this.domManip(arguments, false, function( elem ) {
-				this.parentNode.insertBefore( elem, this );
-			});
-		} else if ( arguments.length ) {
-			var set = jQuery(arguments[0]);
-			set.push.apply( set, this.toArray() );
-			return this.pushStack( set, "before", arguments );
-		}
-	},
-
-	after: function() {
-		if ( this[0] && this[0].parentNode ) {
-			return this.domManip(arguments, false, function( elem ) {
-				this.parentNode.insertBefore( elem, this.nextSibling );
-			});
-		} else if ( arguments.length ) {
-			var set = this.pushStack( this, "after", arguments );
-			set.push.apply( set, jQuery(arguments[0]).toArray() );
-			return set;
-		}
-	},
-
-	// keepData is for internal use only--do not document
-	remove: function( selector, keepData ) {
-		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
-			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
-				if ( !keepData && elem.nodeType === 1 ) {
-					jQuery.cleanData( elem.getElementsByTagName("*") );
-					jQuery.cleanData( [ elem ] );
-				}
-
-				if ( elem.parentNode ) {
-					elem.parentNode.removeChild( elem );
-				}
-			}
-		}
-
-		return this;
-	},
-
-	empty: function() {
-		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
-			// Remove element nodes and prevent memory leaks
-			if ( elem.nodeType === 1 ) {
-				jQuery.cleanData( elem.getElementsByTagName("*") );
-			}
-
-			// Remove any remaining nodes
-			while ( elem.firstChild ) {
-				elem.removeChild( elem.firstChild );
-			}
-		}
-
-		return this;
-	},
-
-	clone: function( dataAndEvents, deepDataAndEvents ) {
-		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
-		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
-		return this.map( function () {
-			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
-		});
-	},
-
-	html: function( value ) {
-		if ( value === undefined ) {
-			return this[0] && this[0].nodeType === 1 ?
-				this[0].innerHTML.replace(rinlinejQuery, "") :
-				null;
-
-		// See if we can take a shortcut and just use innerHTML
-		} else if ( typeof value === "string" && !rnocache.test( value ) &&
-			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
-			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
-
-			value = value.replace(rxhtmlTag, "<$1></$2>");
-
-			try {
-				for ( var i = 0, l = this.length; i < l; i++ ) {
-					// Remove element nodes and prevent memory leaks
-					if ( this[i].nodeType === 1 ) {
-						jQuery.cleanData( this[i].getElementsByTagName("*") );
-						this[i].innerHTML = value;
-					}
-				}
-
-			// If using innerHTML throws an exception, use the fallback method
-			} catch(e) {
-				this.empty().append( value );
-			}
-
-		} else if ( jQuery.isFunction( value ) ) {
-			this.each(function(i){
-				var self = jQuery( this );
-
-				self.html( value.call(this, i, self.html()) );
-			});
-
-		} else {
-			this.empty().append( value );
-		}
-
-		return this;
-	},
-
-	replaceWith: function( value ) {
-		if ( this[0] && this[0].parentNode ) {
-			// Make sure that the elements are removed from the DOM before they are inserted
-			// this can help fix replacing a parent with child elements
-			if ( jQuery.isFunction( value ) ) {
-				return this.each(function(i) {
-					var self = jQuery(this), old = self.html();
-					self.replaceWith( value.call( this, i, old ) );
-				});
-			}
-
-			if ( typeof value !== "string" ) {
-				value = jQuery( value ).detach();
-			}
-
-			return this.each(function() {
-				var next = this.nextSibling,
-					parent = this.parentNode;
-
-				jQuery( this ).remove();
-
-				if ( next ) {
-					jQuery(next).before( value );
-				} else {
-					jQuery(parent).append( value );
-				}
-			});
-		} else {
-			return this.length ?
-				this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
-				this;
-		}
-	},
-
-	detach: function( selector ) {
-		return this.remove( selector, true );
-	},
-
-	domManip: function( args, table, callback ) {
-		var results, first, fragment, parent,
-			value = args[0],
-			scripts = [];
-
-		// We can't cloneNode fragments that contain checked, in WebKit
-		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
-			return this.each(function() {
-				jQuery(this).domManip( args, table, callback, true );
-			});
-		}
-
-		if ( jQuery.isFunction(value) ) {
-			return this.each(function(i) {
-				var self = jQuery(this);
-				args[0] = value.call(this, i, table ? self.html() : undefined);
-				self.domManip( args, table, callback );
-			});
-		}
-
-		if ( this[0] ) {
-			parent = value && value.parentNode;
-
-			// If we're in a fragment, just use that instead of building a new one
-			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
-				results = { fragment: parent };
-
-			} else {
-				results = jQuery.buildFragment( args, this, scripts );
-			}
-
-			fragment = results.fragment;
-
-			if ( fragment.childNodes.length === 1 ) {
-				first = fragment = fragment.firstChild;
-			} else {
-				first = fragment.firstChild;
-			}
-
-			if ( first ) {
-				table = table && jQuery.nodeName( first, "tr" );
-
-				for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
-					callback.call(
-						table ?
-							root(this[i], first) :
-							this[i],
-						// Make sure that we do not leak memory by inadvertently discarding
-						// the original fragment (which might have attached data) instead of
-						// using it; in addition, use the original fragment object for the last
-						// item instead of first because it can end up being emptied incorrectly
-						// in certain situations (Bug #8070).
-						// Fragments from the fragment cache must always be cloned and never used
-						// in place.
-						results.cacheable || (l > 1 && i < lastIndex) ?
-							jQuery.clone( fragment, true, true ) :
-							fragment
-					);
-				}
-			}
-
-			if ( scripts.length ) {
-				jQuery.each( scripts, evalScript );
-			}
-		}
-
-		return this;
-	}
-});
-
-function root( elem, cur ) {
-	return jQuery.nodeName(elem, "table") ?
-		(elem.getElementsByTagName("tbody")[0] ||
-		elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
-		elem;
-}
-
-function cloneCopyEvent( src, dest ) {
-
-	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
-		return;
-	}
-
-	var internalKey = jQuery.expando,
-		oldData = jQuery.data( src ),
-		curData = jQuery.data( dest, oldData );
-
-	// Switch to use the internal data object, if it exists, for the next
-	// stage of data copying
-	if ( (oldData = oldData[ internalKey ]) ) {
-		var events = oldData.events;
-				curData = curData[ internalKey ] = jQuery.extend({}, oldData);
-
-		if ( events ) {
-			delete curData.handle;
-			curData.events = {};
-
-			for ( var type in events ) {
-				for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
-					jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
-				}
-			}
-		}
-	}
-}
-
-function cloneFixAttributes( src, dest ) {
-	var nodeName;
-
-	// We do not need to do anything for non-Elements
-	if ( dest.nodeType !== 1 ) {
-		return;
-	}
-
-	// clearAttributes removes the attributes, which we don't want,
-	// but also removes the attachEvent events, which we *do* want
-	if ( dest.clearAttributes ) {
-		dest.clearAttributes();
-	}
-
-	// mergeAttributes, in contrast, only merges back on the
-	// original attributes, not the events
-	if ( dest.mergeAttributes ) {
-		dest.mergeAttributes( src );
-	}
-
-	nodeName = dest.nodeName.toLowerCase();
-
-	// IE6-8 fail to clone children inside object elements that use
-	// the proprietary classid attribute value (rather than the type
-	// attribute) to identify the type of content to display
-	if ( nodeName === "object" ) {
-		dest.outerHTML = src.outerHTML;
-
-	} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
-		// IE6-8 fails to persist the checked state of a cloned checkbox
-		// or radio button. Worse, IE6-7 fail to give the cloned element
-		// a checked appearance if the defaultChecked value isn't also set
-		if ( src.checked ) {
-			dest.defaultChecked = dest.checked = src.checked;
-		}
-
-		// IE6-7 get confused and end up setting the value of a cloned
-		// checkbox/radio button to an empty string instead of "on"
-		if ( dest.value !== src.value ) {
-			dest.value = src.value;
-		}
-
-	// IE6-8 fails to return the selected option to the default selected
-	// state when cloning options
-	} else if ( nodeName === "option" ) {
-		dest.selected = src.defaultSelected;
-
-	// IE6-8 fails to set the defaultValue to the correct value when
-	// cloning other types of input fields
-	} else if ( nodeName === "input" || nodeName === "textarea" ) {
-		dest.defaultValue = src.defaultValue;
-	}
-
-	// Event data gets referenced instead of copied if the expando
-	// gets copied too
-	dest.removeAttribute( jQuery.expando );
-}
-
-jQuery.buildFragment = function( args, nodes, scripts ) {
-	var fragment, cacheable, cacheresults, doc;
-
-  // nodes may contain either an explicit document object,
-  // a jQuery collection or context object.
-  // If nodes[0] contains a valid object to assign to doc
-  if ( nodes && nodes[0] ) {
-    doc = nodes[0].ownerDocument || nodes[0];
+    // For CommonJS and CommonJS-like environments where a proper `window`
+    // is present, execute the factory and get jQuery.
+    // For environments that do not have a `window` with a `document`
+    // (such as Node.js), expose a factory as module.exports.
+    // This accentuates the need for the creation of a real `window`.
+    // e.g. var jQuery = require("jquery")(window);
+    // See ticket #14549 for more info.
+    module.exports = global.document ?
+        factory( global, true ) :
+        function( w ) {
+          if ( !w.document ) {
+            throw new Error( "jQuery requires a window with a document" );
+          }
+          return factory( w );
+        };
+  } else {
+    factory( global );
   }
 
-  // Ensure that an attr object doesn't incorrectly stand in as a document object
-	// Chrome and Firefox seem to allow this to occur and will throw exception
-	// Fixes #8950
-	if ( !doc.createDocumentFragment ) {
-		doc = document;
-	}
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+  "use strict";
+
+  var arr = [];
+
+  var document = window.document;
+
+  var getProto = Object.getPrototypeOf;
+
+  var slice = arr.slice;
+
+  var concat = arr.concat;
+
+  var push = arr.push;
+
+  var indexOf = arr.indexOf;
+
+  var class2type = {};
+
+  var toString = class2type.toString;
+
+  var hasOwn = class2type.hasOwnProperty;
+
+  var fnToString = hasOwn.toString;
+
+  var ObjectFunctionString = fnToString.call( Object );
+
+  var support = {};
+
+  var isFunction = function isFunction( obj ) {
+
+    // Support: Chrome <=57, Firefox <=52
+    // In some browsers, typeof returns "function" for HTML <object> elements
+    // (i.e., `typeof document.createElement( "object" ) === "function"`).
+    // We don't want to classify *any* DOM node as a function.
+    return typeof obj === "function" && typeof obj.nodeType !== "number";
+  };
+
+
+  var isWindow = function isWindow( obj ) {
+    return obj != null && obj === obj.window;
+  };
+
+
+
+
+  var preservedScriptAttributes = {
+    type: true,
+    src: true,
+    noModule: true
+  };
+
+  function DOMEval( code, doc, node ) {
+    doc = doc || document;
+
+    var i,
+        script = doc.createElement( "script" );
+
+    script.text = code;
+    if ( node ) {
+      for ( i in preservedScriptAttributes ) {
+        if ( node[ i ] ) {
+          script[ i ] = node[ i ];
+        }
+      }
+    }
+    doc.head.appendChild( script ).parentNode.removeChild( script );
+  }
+
+
+  function toType( obj ) {
+    if ( obj == null ) {
+      return obj + "";
+    }
+
+    // Support: Android <=2.3 only (functionish RegExp)
+    return typeof obj === "object" || typeof obj === "function" ?
+        class2type[ toString.call( obj ) ] || "object" :
+        typeof obj;
+  }
+  /* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+  var
+      version = "3.3.1",
+
+      // Define a local copy of jQuery
+      jQuery = function( selector, context ) {
+
+        // The jQuery object is actually just the init constructor 'enhanced'
+        // Need init if jQuery is called (just allow error to be thrown if not included)
+        return new jQuery.fn.init( selector, context );
+      },
+
+      // Support: Android <=4.0 only
+      // Make sure we trim BOM and NBSP
+      rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+
+  jQuery.fn = jQuery.prototype = {
+
+    // The current version of jQuery being used
+    jquery: version,
+
+    constructor: jQuery,
+
+    // The default length of a jQuery object is 0
+    length: 0,
+
+    toArray: function() {
+      return slice.call( this );
+    },
+
+    // Get the Nth element in the matched element set OR
+    // Get the whole matched element set as a clean array
+    get: function( num ) {
+
+      // Return all the elements in a clean array
+      if ( num == null ) {
+        return slice.call( this );
+      }
+
+      // Return just the one element from the set
+      return num < 0 ? this[ num + this.length ] : this[ num ];
+    },
+
+    // Take an array of elements and push it onto the stack
+    // (returning the new matched element set)
+    pushStack: function( elems ) {
+
+      // Build a new jQuery matched element set
+      var ret = jQuery.merge( this.constructor(), elems );
+
+      // Add the old object onto the stack (as a reference)
+      ret.prevObject = this;
+
+      // Return the newly-formed element set
+      return ret;
+    },
+
+    // Execute a callback for every element in the matched set.
+    each: function( callback ) {
+      return jQuery.each( this, callback );
+    },
+
+    map: function( callback ) {
+      return this.pushStack( jQuery.map( this, function( elem, i ) {
+        return callback.call( elem, i, elem );
+      } ) );
+    },
+
+    slice: function() {
+      return this.pushStack( slice.apply( this, arguments ) );
+    },
+
+    first: function() {
+      return this.eq( 0 );
+    },
+
+    last: function() {
+      return this.eq( -1 );
+    },
+
+    eq: function( i ) {
+      var len = this.length,
+          j = +i + ( i < 0 ? len : 0 );
+      return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+    },
+
+    end: function() {
+      return this.prevObject || this.constructor();
+    },
+
+    // For internal use only.
+    // Behaves like an Array's method, not like a jQuery method.
+    push: push,
+    sort: arr.sort,
+    splice: arr.splice
+  };
+
+  jQuery.extend = jQuery.fn.extend = function() {
+    var options, name, src, copy, copyIsArray, clone,
+        target = arguments[ 0 ] || {},
+        i = 1,
+        length = arguments.length,
+        deep = false;
+
+    // Handle a deep copy situation
+    if ( typeof target === "boolean" ) {
+      deep = target;
+
+      // Skip the boolean and the target
+      target = arguments[ i ] || {};
+      i++;
+    }
+
+    // Handle case when target is a string or something (possible in deep copy)
+    if ( typeof target !== "object" && !isFunction( target ) ) {
+      target = {};
+    }
+
+    // Extend jQuery itself if only one argument is passed
+    if ( i === length ) {
+      target = this;
+      i--;
+    }
+
+    for ( ; i < length; i++ ) {
+
+      // Only deal with non-null/undefined values
+      if ( ( options = arguments[ i ] ) != null ) {
+
+        // Extend the base object
+        for ( name in options ) {
+          src = target[ name ];
+          copy = options[ name ];
+
+          // Prevent never-ending loop
+          if ( target === copy ) {
+            continue;
+          }
+
+          // Recurse if we're merging plain objects or arrays
+          if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+              ( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+            if ( copyIsArray ) {
+              copyIsArray = false;
+              clone = src && Array.isArray( src ) ? src : [];
+
+            } else {
+              clone = src && jQuery.isPlainObject( src ) ? src : {};
+            }
+
+            // Never move original objects, clone them
+            target[ name ] = jQuery.extend( deep, clone, copy );
+
+            // Don't bring in undefined values
+          } else if ( copy !== undefined ) {
+            target[ name ] = copy;
+          }
+        }
+      }
+    }
+
+    // Return the modified object
+    return target;
+  };
+
+  jQuery.extend( {
+
+    // Unique for each copy of jQuery on the page
+    expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+    // Assume jQuery is ready without the ready module
+    isReady: true,
+
+    error: function( msg ) {
+      throw new Error( msg );
+    },
+
+    noop: function() {},
+
+    isPlainObject: function( obj ) {
+      var proto, Ctor;
+
+      // Detect obvious negatives
+      // Use toString instead of jQuery.type to catch host objects
+      if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+        return false;
+      }
+
+      proto = getProto( obj );
+
+      // Objects with no prototype (e.g., `Object.create( null )`) are plain
+      if ( !proto ) {
+        return true;
+      }
+
+      // Objects with prototype are plain iff they were constructed by a global Object function
+      Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+      return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+    },
+
+    isEmptyObject: function( obj ) {
+
+      /* eslint-disable no-unused-vars */
+      // See https://github.com/eslint/eslint/issues/6125
+      var name;
+
+      for ( name in obj ) {
+        return false;
+      }
+      return true;
+    },
+
+    // Evaluates a script in a global context
+    globalEval: function( code ) {
+      DOMEval( code );
+    },
+
+    each: function( obj, callback ) {
+      var length, i = 0;
+
+      if ( isArrayLike( obj ) ) {
+        length = obj.length;
+        for ( ; i < length; i++ ) {
+          if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+            break;
+          }
+        }
+      } else {
+        for ( i in obj ) {
+          if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+            break;
+          }
+        }
+      }
+
+      return obj;
+    },
+
+    // Support: Android <=4.0 only
+    trim: function( text ) {
+      return text == null ?
+          "" :
+          ( text + "" ).replace( rtrim, "" );
+    },
+
+    // results is for internal usage only
+    makeArray: function( arr, results ) {
+      var ret = results || [];
+
+      if ( arr != null ) {
+        if ( isArrayLike( Object( arr ) ) ) {
+          jQuery.merge( ret,
+              typeof arr === "string" ?
+                  [ arr ] : arr
+          );
+        } else {
+          push.call( ret, arr );
+        }
+      }
+
+      return ret;
+    },
+
+    inArray: function( elem, arr, i ) {
+      return arr == null ? -1 : indexOf.call( arr, elem, i );
+    },
+
+    // Support: Android <=4.0 only, PhantomJS 1 only
+    // push.apply(_, arraylike) throws on ancient WebKit
+    merge: function( first, second ) {
+      var len = +second.length,
+          j = 0,
+          i = first.length;
+
+      for ( ; j < len; j++ ) {
+        first[ i++ ] = second[ j ];
+      }
+
+      first.length = i;
+
+      return first;
+    },
+
+    grep: function( elems, callback, invert ) {
+      var callbackInverse,
+          matches = [],
+          i = 0,
+          length = elems.length,
+          callbackExpect = !invert;
+
+      // Go through the array, only saving the items
+      // that pass the validator function
+      for ( ; i < length; i++ ) {
+        callbackInverse = !callback( elems[ i ], i );
+        if ( callbackInverse !== callbackExpect ) {
+          matches.push( elems[ i ] );
+        }
+      }
+
+      return matches;
+    },
+
+    // arg is for internal usage only
+    map: function( elems, callback, arg ) {
+      var length, value,
+          i = 0,
+          ret = [];
+
+      // Go through the array, translating each of the items to their new values
+      if ( isArrayLike( elems ) ) {
+        length = elems.length;
+        for ( ; i < length; i++ ) {
+          value = callback( elems[ i ], i, arg );
+
+          if ( value != null ) {
+            ret.push( value );
+          }
+        }
+
+        // Go through every key on the object,
+      } else {
+        for ( i in elems ) {
+          value = callback( elems[ i ], i, arg );
+
+          if ( value != null ) {
+            ret.push( value );
+          }
+        }
+      }
+
+      // Flatten any nested arrays
+      return concat.apply( [], ret );
+    },
+
+    // A global GUID counter for objects
+    guid: 1,
+
+    // jQuery.support is not used in Core but other projects attach their
+    // properties to it so it needs to exist.
+    support: support
+  } );
+
+  if ( typeof Symbol === "function" ) {
+    jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+  }
+
+// Populate the class2type map
+  jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+      function( i, name ) {
+        class2type[ "[object " + name + "]" ] = name.toLowerCase();
+      } );
+
+  function isArrayLike( obj ) {
+
+    // Support: real iOS 8.2 only (not reproducible in simulator)
+    // `in` check used to prevent JIT error (gh-2145)
+    // hasOwn isn't used here due to false negatives
+    // regarding Nodelist length in IE
+    var length = !!obj && "length" in obj && obj.length,
+        type = toType( obj );
+
+    if ( isFunction( obj ) || isWindow( obj ) ) {
+      return false;
+    }
+
+    return type === "array" || length === 0 ||
+        typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+  }
+  var Sizzle =
+      /*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+      (function( window ) {
+
+        var i,
+            support,
+            Expr,
+            getText,
+            isXML,
+            tokenize,
+            compile,
+            select,
+            outermostContext,
+            sortInput,
+            hasDuplicate,
+
+            // Local document vars
+            setDocument,
+            document,
+            docElem,
+            documentIsHTML,
+            rbuggyQSA,
+            rbuggyMatches,
+            matches,
+            contains,
+
+            // Instance-specific data
+            expando = "sizzle" + 1 * new Date(),
+            preferredDoc = window.document,
+            dirruns = 0,
+            done = 0,
+            classCache = createCache(),
+            tokenCache = createCache(),
+            compilerCache = createCache(),
+            sortOrder = function( a, b ) {
+              if ( a === b ) {
+                hasDuplicate = true;
+              }
+              return 0;
+            },
+
+            // Instance methods
+            hasOwn = ({}).hasOwnProperty,
+            arr = [],
+            pop = arr.pop,
+            push_native = arr.push,
+            push = arr.push,
+            slice = arr.slice,
+            // Use a stripped-down indexOf as it's faster than native
+            // https://jsperf.com/thor-indexof-vs-for/5
+            indexOf = function( list, elem ) {
+              var i = 0,
+                  len = list.length;
+              for ( ; i < len; i++ ) {
+                if ( list[i] === elem ) {
+                  return i;
+                }
+              }
+              return -1;
+            },
+
+            booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+            // Regular expressions
+
+            // http://www.w3.org/TR/css3-selectors/#whitespace
+            whitespace = "[\\x20\\t\\r\\n\\f]",
+
+            // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+            identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+            // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+            attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+                // Operator (capture 2)
+                "*([*^$|!~]?=)" + whitespace +
+                // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+                "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+                "*\\]",
+
+            pseudos = ":(" + identifier + ")(?:\\((" +
+                // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+                // 1. quoted (capture 3; capture 4 or capture 5)
+                "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+                // 2. simple (capture 6)
+                "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+                // 3. anything else (capture 2)
+                ".*" +
+                ")\\)|)",
+
+            // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+            rwhitespace = new RegExp( whitespace + "+", "g" ),
+            rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+            rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+            rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+            rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+            rpseudo = new RegExp( pseudos ),
+            ridentifier = new RegExp( "^" + identifier + "$" ),
+
+            matchExpr = {
+              "ID": new RegExp( "^#(" + identifier + ")" ),
+              "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+              "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+              "ATTR": new RegExp( "^" + attributes ),
+              "PSEUDO": new RegExp( "^" + pseudos ),
+              "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                  "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                  "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+              "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+              // For use in libraries implementing .is()
+              // We use this for POS matching in `select`
+              "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                  whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+            },
+
+            rinputs = /^(?:input|select|textarea|button)$/i,
+            rheader = /^h\d$/i,
+
+            rnative = /^[^{]+\{\s*\[native \w/,
+
+            // Easily-parseable/retrievable ID or TAG or CLASS selectors
+            rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+            rsibling = /[+~]/,
+
+            // CSS escapes
+            // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+            runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+            funescape = function( _, escaped, escapedWhitespace ) {
+              var high = "0x" + escaped - 0x10000;
+              // NaN means non-codepoint
+              // Support: Firefox<24
+              // Workaround erroneous numeric interpretation of +"0x"
+              return high !== high || escapedWhitespace ?
+                  escaped :
+                  high < 0 ?
+                      // BMP codepoint
+                      String.fromCharCode( high + 0x10000 ) :
+                      // Supplemental Plane codepoint (surrogate pair)
+                      String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+            },
+
+            // CSS string/identifier serialization
+            // https://drafts.csswg.org/cssom/#common-serializing-idioms
+            rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+            fcssescape = function( ch, asCodePoint ) {
+              if ( asCodePoint ) {
+
+                // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+                if ( ch === "\0" ) {
+                  return "\uFFFD";
+                }
+
+                // Control characters and (dependent upon position) numbers get escaped as code points
+                return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+              }
+
+              // Other potentially-special ASCII characters get backslash-escaped
+              return "\\" + ch;
+            },
+
+            // Used for iframes
+            // See setDocument()
+            // Removing the function wrapper causes a "Permission Denied"
+            // error in IE
+            unloadHandler = function() {
+              setDocument();
+            },
+
+            disabledAncestor = addCombinator(
+                function( elem ) {
+                  return elem.disabled === true && ("form" in elem || "label" in elem);
+                },
+                { dir: "parentNode", next: "legend" }
+            );
+
+// Optimize for push.apply( _, NodeList )
+        try {
+          push.apply(
+              (arr = slice.call( preferredDoc.childNodes )),
+              preferredDoc.childNodes
+          );
+          // Support: Android<4.0
+          // Detect silently failing push.apply
+          arr[ preferredDoc.childNodes.length ].nodeType;
+        } catch ( e ) {
+          push = { apply: arr.length ?
+
+                // Leverage slice if possible
+                function( target, els ) {
+                  push_native.apply( target, slice.call(els) );
+                } :
+
+                // Support: IE<9
+                // Otherwise append directly
+                function( target, els ) {
+                  var j = target.length,
+                      i = 0;
+                  // Can't trust NodeList.length
+                  while ( (target[j++] = els[i++]) ) {}
+                  target.length = j - 1;
+                }
+          };
+        }
+
+        function Sizzle( selector, context, results, seed ) {
+          var m, i, elem, nid, match, groups, newSelector,
+              newContext = context && context.ownerDocument,
+
+              // nodeType defaults to 9, since context defaults to document
+              nodeType = context ? context.nodeType : 9;
+
+          results = results || [];
+
+          // Return early from calls with invalid selector or context
+          if ( typeof selector !== "string" || !selector ||
+              nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+            return results;
+          }
+
+          // Try to shortcut find operations (as opposed to filters) in HTML documents
+          if ( !seed ) {
+
+            if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+              setDocument( context );
+            }
+            context = context || document;
+
+            if ( documentIsHTML ) {
+
+              // If the selector is sufficiently simple, try using a "get*By*" DOM method
+              // (excepting DocumentFragment context, where the methods don't exist)
+              if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+                // ID selector
+                if ( (m = match[1]) ) {
+
+                  // Document context
+                  if ( nodeType === 9 ) {
+                    if ( (elem = context.getElementById( m )) ) {
+
+                      // Support: IE, Opera, Webkit
+                      // TODO: identify versions
+                      // getElementById can match elements by name instead of ID
+                      if ( elem.id === m ) {
+                        results.push( elem );
+                        return results;
+                      }
+                    } else {
+                      return results;
+                    }
+
+                    // Element context
+                  } else {
+
+                    // Support: IE, Opera, Webkit
+                    // TODO: identify versions
+                    // getElementById can match elements by name instead of ID
+                    if ( newContext && (elem = newContext.getElementById( m )) &&
+                        contains( context, elem ) &&
+                        elem.id === m ) {
+
+                      results.push( elem );
+                      return results;
+                    }
+                  }
+
+                  // Type selector
+                } else if ( match[2] ) {
+                  push.apply( results, context.getElementsByTagName( selector ) );
+                  return results;
+
+                  // Class selector
+                } else if ( (m = match[3]) && support.getElementsByClassName &&
+                    context.getElementsByClassName ) {
+
+                  push.apply( results, context.getElementsByClassName( m ) );
+                  return results;
+                }
+              }
+
+              // Take advantage of querySelectorAll
+              if ( support.qsa &&
+                  !compilerCache[ selector + " " ] &&
+                  (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+                if ( nodeType !== 1 ) {
+                  newContext = context;
+                  newSelector = selector;
+
+                  // qSA looks outside Element context, which is not what we want
+                  // Thanks to Andrew Dupont for this workaround technique
+                  // Support: IE <=8
+                  // Exclude object elements
+                } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+                  // Capture the context ID, setting it first if necessary
+                  if ( (nid = context.getAttribute( "id" )) ) {
+                    nid = nid.replace( rcssescape, fcssescape );
+                  } else {
+                    context.setAttribute( "id", (nid = expando) );
+                  }
+
+                  // Prefix every selector in the list
+                  groups = tokenize( selector );
+                  i = groups.length;
+                  while ( i-- ) {
+                    groups[i] = "#" + nid + " " + toSelector( groups[i] );
+                  }
+                  newSelector = groups.join( "," );
+
+                  // Expand context for sibling selectors
+                  newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+                      context;
+                }
+
+                if ( newSelector ) {
+                  try {
+                    push.apply( results,
+                        newContext.querySelectorAll( newSelector )
+                    );
+                    return results;
+                  } catch ( qsaError ) {
+                  } finally {
+                    if ( nid === expando ) {
+                      context.removeAttribute( "id" );
+                    }
+                  }
+                }
+              }
+            }
+          }
+
+          // All others
+          return select( selector.replace( rtrim, "$1" ), context, results, seed );
+        }
+
+        /**
+         * Create key-value caches of limited size
+         * @returns {function(string, object)} Returns the Object data after storing it on itself with
+         *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+         *	deleting the oldest entry
+         */
+        function createCache() {
+          var keys = [];
+
+          function cache( key, value ) {
+            // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+            if ( keys.push( key + " " ) > Expr.cacheLength ) {
+              // Only keep the most recent entries
+              delete cache[ keys.shift() ];
+            }
+            return (cache[ key + " " ] = value);
+          }
+          return cache;
+        }
+
+        /**
+         * Mark a function for special use by Sizzle
+         * @param {Function} fn The function to mark
+         */
+        function markFunction( fn ) {
+          fn[ expando ] = true;
+          return fn;
+        }
+
+        /**
+         * Support testing using an element
+         * @param {Function} fn Passed the created element and returns a boolean result
+         */
+        function assert( fn ) {
+          var el = document.createElement("fieldset");
+
+          try {
+            return !!fn( el );
+          } catch (e) {
+            return false;
+          } finally {
+            // Remove from its parent by default
+            if ( el.parentNode ) {
+              el.parentNode.removeChild( el );
+            }
+            // release memory in IE
+            el = null;
+          }
+        }
+
+        /**
+         * Adds the same handler for all of the specified attrs
+         * @param {String} attrs Pipe-separated list of attributes
+         * @param {Function} handler The method that will be applied
+         */
+        function addHandle( attrs, handler ) {
+          var arr = attrs.split("|"),
+              i = arr.length;
+
+          while ( i-- ) {
+            Expr.attrHandle[ arr[i] ] = handler;
+          }
+        }
+
+        /**
+         * Checks document order of two siblings
+         * @param {Element} a
+         * @param {Element} b
+         * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+         */
+        function siblingCheck( a, b ) {
+          var cur = b && a,
+              diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                  a.sourceIndex - b.sourceIndex;
+
+          // Use IE sourceIndex if available on both nodes
+          if ( diff ) {
+            return diff;
+          }
+
+          // Check if b follows a
+          if ( cur ) {
+            while ( (cur = cur.nextSibling) ) {
+              if ( cur === b ) {
+                return -1;
+              }
+            }
+          }
+
+          return a ? 1 : -1;
+        }
+
+        /**
+         * Returns a function to use in pseudos for input types
+         * @param {String} type
+         */
+        function createInputPseudo( type ) {
+          return function( elem ) {
+            var name = elem.nodeName.toLowerCase();
+            return name === "input" && elem.type === type;
+          };
+        }
+
+        /**
+         * Returns a function to use in pseudos for buttons
+         * @param {String} type
+         */
+        function createButtonPseudo( type ) {
+          return function( elem ) {
+            var name = elem.nodeName.toLowerCase();
+            return (name === "input" || name === "button") && elem.type === type;
+          };
+        }
+
+        /**
+         * Returns a function to use in pseudos for :enabled/:disabled
+         * @param {Boolean} disabled true for :disabled; false for :enabled
+         */
+        function createDisabledPseudo( disabled ) {
+
+          // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+          return function( elem ) {
+
+            // Only certain elements can match :enabled or :disabled
+            // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+            // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+            if ( "form" in elem ) {
+
+              // Check for inherited disabledness on relevant non-disabled elements:
+              // * listed form-associated elements in a disabled fieldset
+              //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
+              //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+              // * option elements in a disabled optgroup
+              //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+              // All such elements have a "form" property.
+              if ( elem.parentNode && elem.disabled === false ) {
+
+                // Option elements defer to a parent optgroup if present
+                if ( "label" in elem ) {
+                  if ( "label" in elem.parentNode ) {
+                    return elem.parentNode.disabled === disabled;
+                  } else {
+                    return elem.disabled === disabled;
+                  }
+                }
+
+                // Support: IE 6 - 11
+                // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+                return elem.isDisabled === disabled ||
+
+                    // Where there is no isDisabled, check manually
+                    /* jshint -W018 */
+                    elem.isDisabled !== !disabled &&
+                    disabledAncestor( elem ) === disabled;
+              }
+
+              return elem.disabled === disabled;
+
+              // Try to winnow out elements that can't be disabled before trusting the disabled property.
+              // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+              // even exist on them, let alone have a boolean value.
+            } else if ( "label" in elem ) {
+              return elem.disabled === disabled;
+            }
+
+            // Remaining elements are neither :enabled nor :disabled
+            return false;
+          };
+        }
+
+        /**
+         * Returns a function to use in pseudos for positionals
+         * @param {Function} fn
+         */
+        function createPositionalPseudo( fn ) {
+          return markFunction(function( argument ) {
+            argument = +argument;
+            return markFunction(function( seed, matches ) {
+              var j,
+                  matchIndexes = fn( [], seed.length, argument ),
+                  i = matchIndexes.length;
+
+              // Match elements found at the specified indexes
+              while ( i-- ) {
+                if ( seed[ (j = matchIndexes[i]) ] ) {
+                  seed[j] = !(matches[j] = seed[j]);
+                }
+              }
+            });
+          });
+        }
+
+        /**
+         * Checks a node for validity as a Sizzle context
+         * @param {Element|Object=} context
+         * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+         */
+        function testContext( context ) {
+          return context && typeof context.getElementsByTagName !== "undefined" && context;
+        }
+
+// Expose support vars for convenience
+        support = Sizzle.support = {};
+
+        /**
+         * Detects XML nodes
+         * @param {Element|Object} elem An element or a document
+         * @returns {Boolean} True iff elem is a non-HTML XML node
+         */
+        isXML = Sizzle.isXML = function( elem ) {
+          // documentElement is verified for cases where it doesn't yet exist
+          // (such as loading iframes in IE - #4833)
+          var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+          return documentElement ? documentElement.nodeName !== "HTML" : false;
+        };
+
+        /**
+         * Sets document-related variables once based on the current document
+         * @param {Element|Object} [doc] An element or document object to use to set the document
+         * @returns {Object} Returns the current document
+         */
+        setDocument = Sizzle.setDocument = function( node ) {
+          var hasCompare, subWindow,
+              doc = node ? node.ownerDocument || node : preferredDoc;
+
+          // Return early if doc is invalid or already selected
+          if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+            return document;
+          }
+
+          // Update global variables
+          document = doc;
+          docElem = document.documentElement;
+          documentIsHTML = !isXML( document );
+
+          // Support: IE 9-11, Edge
+          // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+          if ( preferredDoc !== document &&
+              (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+            // Support: IE 11, Edge
+            if ( subWindow.addEventListener ) {
+              subWindow.addEventListener( "unload", unloadHandler, false );
+
+              // Support: IE 9 - 10 only
+            } else if ( subWindow.attachEvent ) {
+              subWindow.attachEvent( "onunload", unloadHandler );
+            }
+          }
+
+          /* Attributes
+	---------------------------------------------------------------------- */
+
+          // Support: IE<8
+          // Verify that getAttribute really returns attributes and not properties
+          // (excepting IE8 booleans)
+          support.attributes = assert(function( el ) {
+            el.className = "i";
+            return !el.getAttribute("className");
+          });
+
+          /* getElement(s)By*
+	---------------------------------------------------------------------- */
+
+          // Check if getElementsByTagName("*") returns only elements
+          support.getElementsByTagName = assert(function( el ) {
+            el.appendChild( document.createComment("") );
+            return !el.getElementsByTagName("*").length;
+          });
+
+          // Support: IE<9
+          support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+          // Support: IE<10
+          // Check if getElementById returns elements by name
+          // The broken getElementById methods don't pick up programmatically-set names,
+          // so use a roundabout getElementsByName test
+          support.getById = assert(function( el ) {
+            docElem.appendChild( el ).id = expando;
+            return !document.getElementsByName || !document.getElementsByName( expando ).length;
+          });
+
+          // ID filter and find
+          if ( support.getById ) {
+            Expr.filter["ID"] = function( id ) {
+              var attrId = id.replace( runescape, funescape );
+              return function( elem ) {
+                return elem.getAttribute("id") === attrId;
+              };
+            };
+            Expr.find["ID"] = function( id, context ) {
+              if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                var elem = context.getElementById( id );
+                return elem ? [ elem ] : [];
+              }
+            };
+          } else {
+            Expr.filter["ID"] =  function( id ) {
+              var attrId = id.replace( runescape, funescape );
+              return function( elem ) {
+                var node = typeof elem.getAttributeNode !== "undefined" &&
+                    elem.getAttributeNode("id");
+                return node && node.value === attrId;
+              };
+            };
+
+            // Support: IE 6 - 7 only
+            // getElementById is not reliable as a find shortcut
+            Expr.find["ID"] = function( id, context ) {
+              if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                var node, i, elems,
+                    elem = context.getElementById( id );
+
+                if ( elem ) {
+
+                  // Verify the id attribute
+                  node = elem.getAttributeNode("id");
+                  if ( node && node.value === id ) {
+                    return [ elem ];
+                  }
+
+                  // Fall back on getElementsByName
+                  elems = context.getElementsByName( id );
+                  i = 0;
+                  while ( (elem = elems[i++]) ) {
+                    node = elem.getAttributeNode("id");
+                    if ( node && node.value === id ) {
+                      return [ elem ];
+                    }
+                  }
+                }
+
+                return [];
+              }
+            };
+          }
+
+          // Tag
+          Expr.find["TAG"] = support.getElementsByTagName ?
+              function( tag, context ) {
+                if ( typeof context.getElementsByTagName !== "undefined" ) {
+                  return context.getElementsByTagName( tag );
+
+                  // DocumentFragment nodes don't have gEBTN
+                } else if ( support.qsa ) {
+                  return context.querySelectorAll( tag );
+                }
+              } :
+
+              function( tag, context ) {
+                var elem,
+                    tmp = [],
+                    i = 0,
+                    // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+                    results = context.getElementsByTagName( tag );
+
+                // Filter out possible comments
+                if ( tag === "*" ) {
+                  while ( (elem = results[i++]) ) {
+                    if ( elem.nodeType === 1 ) {
+                      tmp.push( elem );
+                    }
+                  }
+
+                  return tmp;
+                }
+                return results;
+              };
+
+          // Class
+          Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+            if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+              return context.getElementsByClassName( className );
+            }
+          };
+
+          /* QSA/matchesSelector
+	---------------------------------------------------------------------- */
+
+          // QSA and matchesSelector support
+
+          // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+          rbuggyMatches = [];
+
+          // qSa(:focus) reports false when true (Chrome 21)
+          // We allow this because of a bug in IE8/9 that throws an error
+          // whenever `document.activeElement` is accessed on an iframe
+          // So, we allow :focus to pass through QSA all the time to avoid the IE error
+          // See https://bugs.jquery.com/ticket/13378
+          rbuggyQSA = [];
+
+          if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+            // Build QSA regex
+            // Regex strategy adopted from Diego Perini
+            assert(function( el ) {
+              // Select is set to empty string on purpose
+              // This is to test IE's treatment of not explicitly
+              // setting a boolean content attribute,
+              // since its presence should be enough
+              // https://bugs.jquery.com/ticket/12359
+              docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
+                  "<select id='" + expando + "-\r\\' msallowcapture=''>" +
+                  "<option selected=''></option></select>";
+
+              // Support: IE8, Opera 11-12.16
+              // Nothing should be selected when empty strings follow ^= or $= or *=
+              // The test attribute must be unknown in Opera but "safe" for WinRT
+              // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+              if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+                rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+              }
+
+              // Support: IE8
+              // Boolean attributes and "value" are not treated correctly
+              if ( !el.querySelectorAll("[selected]").length ) {
+                rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+              }
+
+              // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+              if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+                rbuggyQSA.push("~=");
+              }
+
+              // Webkit/Opera - :checked should return selected option elements
+              // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+              // IE8 throws error here and will not see later tests
+              if ( !el.querySelectorAll(":checked").length ) {
+                rbuggyQSA.push(":checked");
+              }
+
+              // Support: Safari 8+, iOS 8+
+              // https://bugs.webkit.org/show_bug.cgi?id=136851
+              // In-page `selector#id sibling-combinator selector` fails
+              if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+                rbuggyQSA.push(".#.+[+~]");
+              }
+            });
+
+            assert(function( el ) {
+              el.innerHTML = "<a href='' disabled='disabled'></a>" +
+                  "<select disabled='disabled'><option/></select>";
+
+              // Support: Windows 8 Native Apps
+              // The type and name attributes are restricted during .innerHTML assignment
+              var input = document.createElement("input");
+              input.setAttribute( "type", "hidden" );
+              el.appendChild( input ).setAttribute( "name", "D" );
+
+              // Support: IE8
+              // Enforce case-sensitivity of name attribute
+              if ( el.querySelectorAll("[name=d]").length ) {
+                rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+              }
+
+              // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+              // IE8 throws error here and will not see later tests
+              if ( el.querySelectorAll(":enabled").length !== 2 ) {
+                rbuggyQSA.push( ":enabled", ":disabled" );
+              }
+
+              // Support: IE9-11+
+              // IE's :disabled selector does not pick up the children of disabled fieldsets
+              docElem.appendChild( el ).disabled = true;
+              if ( el.querySelectorAll(":disabled").length !== 2 ) {
+                rbuggyQSA.push( ":enabled", ":disabled" );
+              }
+
+              // Opera 10-11 does not throw on post-comma invalid pseudos
+              el.querySelectorAll("*,:x");
+              rbuggyQSA.push(",.*:");
+            });
+          }
+
+          if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+              docElem.webkitMatchesSelector ||
+              docElem.mozMatchesSelector ||
+              docElem.oMatchesSelector ||
+              docElem.msMatchesSelector) )) ) {
+
+            assert(function( el ) {
+              // Check to see if it's possible to do matchesSelector
+              // on a disconnected node (IE 9)
+              support.disconnectedMatch = matches.call( el, "*" );
+
+              // This should fail with an exception
+              // Gecko does not error, returns false instead
+              matches.call( el, "[s!='']:x" );
+              rbuggyMatches.push( "!=", pseudos );
+            });
+          }
+
+          rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+          rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+          /* Contains
+	---------------------------------------------------------------------- */
+          hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+          // Element contains another
+          // Purposefully self-exclusive
+          // As in, an element does not contain itself
+          contains = hasCompare || rnative.test( docElem.contains ) ?
+              function( a, b ) {
+                var adown = a.nodeType === 9 ? a.documentElement : a,
+                    bup = b && b.parentNode;
+                return a === bup || !!( bup && bup.nodeType === 1 && (
+                    adown.contains ?
+                        adown.contains( bup ) :
+                        a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+                ));
+              } :
+              function( a, b ) {
+                if ( b ) {
+                  while ( (b = b.parentNode) ) {
+                    if ( b === a ) {
+                      return true;
+                    }
+                  }
+                }
+                return false;
+              };
+
+          /* Sorting
+	---------------------------------------------------------------------- */
+
+          // Document order sorting
+          sortOrder = hasCompare ?
+              function( a, b ) {
+
+                // Flag for duplicate removal
+                if ( a === b ) {
+                  hasDuplicate = true;
+                  return 0;
+                }
+
+                // Sort on method existence if only one input has compareDocumentPosition
+                var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+                if ( compare ) {
+                  return compare;
+                }
+
+                // Calculate position if both inputs belong to the same document
+                compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+                    a.compareDocumentPosition( b ) :
+
+                    // Otherwise we know they are disconnected
+                    1;
+
+                // Disconnected nodes
+                if ( compare & 1 ||
+                    (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+                  // Choose the first element that is related to our preferred document
+                  if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+                    return -1;
+                  }
+                  if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+                    return 1;
+                  }
+
+                  // Maintain original order
+                  return sortInput ?
+                      ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+                      0;
+                }
+
+                return compare & 4 ? -1 : 1;
+              } :
+              function( a, b ) {
+                // Exit early if the nodes are identical
+                if ( a === b ) {
+                  hasDuplicate = true;
+                  return 0;
+                }
+
+                var cur,
+                    i = 0,
+                    aup = a.parentNode,
+                    bup = b.parentNode,
+                    ap = [ a ],
+                    bp = [ b ];
+
+                // Parentless nodes are either documents or disconnected
+                if ( !aup || !bup ) {
+                  return a === document ? -1 :
+                      b === document ? 1 :
+                          aup ? -1 :
+                              bup ? 1 :
+                                  sortInput ?
+                                      ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+                                      0;
+
+                  // If the nodes are siblings, we can do a quick check
+                } else if ( aup === bup ) {
+                  return siblingCheck( a, b );
+                }
+
+                // Otherwise we need full lists of their ancestors for comparison
+                cur = a;
+                while ( (cur = cur.parentNode) ) {
+                  ap.unshift( cur );
+                }
+                cur = b;
+                while ( (cur = cur.parentNode) ) {
+                  bp.unshift( cur );
+                }
+
+                // Walk down the tree looking for a discrepancy
+                while ( ap[i] === bp[i] ) {
+                  i++;
+                }
+
+                return i ?
+                    // Do a sibling check if the nodes have a common ancestor
+                    siblingCheck( ap[i], bp[i] ) :
+
+                    // Otherwise nodes in our document sort first
+                    ap[i] === preferredDoc ? -1 :
+                        bp[i] === preferredDoc ? 1 :
+                            0;
+              };
+
+          return document;
+        };
+
+        Sizzle.matches = function( expr, elements ) {
+          return Sizzle( expr, null, null, elements );
+        };
+
+        Sizzle.matchesSelector = function( elem, expr ) {
+          // Set document vars if needed
+          if ( ( elem.ownerDocument || elem ) !== document ) {
+            setDocument( elem );
+          }
+
+          // Make sure that attribute selectors are quoted
+          expr = expr.replace( rattributeQuotes, "='$1']" );
+
+          if ( support.matchesSelector && documentIsHTML &&
+              !compilerCache[ expr + " " ] &&
+              ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+              ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+            try {
+              var ret = matches.call( elem, expr );
+
+              // IE 9's matchesSelector returns false on disconnected nodes
+              if ( ret || support.disconnectedMatch ||
+                  // As well, disconnected nodes are said to be in a document
+                  // fragment in IE 9
+                  elem.document && elem.document.nodeType !== 11 ) {
+                return ret;
+              }
+            } catch (e) {}
+          }
+
+          return Sizzle( expr, document, null, [ elem ] ).length > 0;
+        };
+
+        Sizzle.contains = function( context, elem ) {
+          // Set document vars if needed
+          if ( ( context.ownerDocument || context ) !== document ) {
+            setDocument( context );
+          }
+          return contains( context, elem );
+        };
+
+        Sizzle.attr = function( elem, name ) {
+          // Set document vars if needed
+          if ( ( elem.ownerDocument || elem ) !== document ) {
+            setDocument( elem );
+          }
+
+          var fn = Expr.attrHandle[ name.toLowerCase() ],
+              // Don't get fooled by Object.prototype properties (jQuery #13807)
+              val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+                  fn( elem, name, !documentIsHTML ) :
+                  undefined;
+
+          return val !== undefined ?
+              val :
+              support.attributes || !documentIsHTML ?
+                  elem.getAttribute( name ) :
+                  (val = elem.getAttributeNode(name)) && val.specified ?
+                      val.value :
+                      null;
+        };
+
+        Sizzle.escape = function( sel ) {
+          return (sel + "").replace( rcssescape, fcssescape );
+        };
+
+        Sizzle.error = function( msg ) {
+          throw new Error( "Syntax error, unrecognized expression: " + msg );
+        };
+
+        /**
+         * Document sorting and removing duplicates
+         * @param {ArrayLike} results
+         */
+        Sizzle.uniqueSort = function( results ) {
+          var elem,
+              duplicates = [],
+              j = 0,
+              i = 0;
+
+          // Unless we *know* we can detect duplicates, assume their presence
+          hasDuplicate = !support.detectDuplicates;
+          sortInput = !support.sortStable && results.slice( 0 );
+          results.sort( sortOrder );
+
+          if ( hasDuplicate ) {
+            while ( (elem = results[i++]) ) {
+              if ( elem === results[ i ] ) {
+                j = duplicates.push( i );
+              }
+            }
+            while ( j-- ) {
+              results.splice( duplicates[ j ], 1 );
+            }
+          }
+
+          // Clear input after sorting to release objects
+          // See https://github.com/jquery/sizzle/pull/225
+          sortInput = null;
+
+          return results;
+        };
+
+        /**
+         * Utility function for retrieving the text value of an array of DOM nodes
+         * @param {Array|Element} elem
+         */
+        getText = Sizzle.getText = function( elem ) {
+          var node,
+              ret = "",
+              i = 0,
+              nodeType = elem.nodeType;
+
+          if ( !nodeType ) {
+            // If no nodeType, this is expected to be an array
+            while ( (node = elem[i++]) ) {
+              // Do not traverse comment nodes
+              ret += getText( node );
+            }
+          } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+            // Use textContent for elements
+            // innerText usage removed for consistency of new lines (jQuery #11153)
+            if ( typeof elem.textContent === "string" ) {
+              return elem.textContent;
+            } else {
+              // Traverse its children
+              for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                ret += getText( elem );
+              }
+            }
+          } else if ( nodeType === 3 || nodeType === 4 ) {
+            return elem.nodeValue;
+          }
+          // Do not include comment or processing instruction nodes
+
+          return ret;
+        };
+
+        Expr = Sizzle.selectors = {
+
+          // Can be adjusted by the user
+          cacheLength: 50,
+
+          createPseudo: markFunction,
+
+          match: matchExpr,
+
+          attrHandle: {},
+
+          find: {},
+
+          relative: {
+            ">": { dir: "parentNode", first: true },
+            " ": { dir: "parentNode" },
+            "+": { dir: "previousSibling", first: true },
+            "~": { dir: "previousSibling" }
+          },
+
+          preFilter: {
+            "ATTR": function( match ) {
+              match[1] = match[1].replace( runescape, funescape );
+
+              // Move the given value to match[3] whether quoted or unquoted
+              match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+              if ( match[2] === "~=" ) {
+                match[3] = " " + match[3] + " ";
+              }
+
+              return match.slice( 0, 4 );
+            },
+
+            "CHILD": function( match ) {
+              /* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+              match[1] = match[1].toLowerCase();
+
+              if ( match[1].slice( 0, 3 ) === "nth" ) {
+                // nth-* requires argument
+                if ( !match[3] ) {
+                  Sizzle.error( match[0] );
+                }
+
+                // numeric x and y parameters for Expr.filter.CHILD
+                // remember that false/true cast respectively to 0/1
+                match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+                match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+                // other types prohibit arguments
+              } else if ( match[3] ) {
+                Sizzle.error( match[0] );
+              }
+
+              return match;
+            },
+
+            "PSEUDO": function( match ) {
+              var excess,
+                  unquoted = !match[6] && match[2];
+
+              if ( matchExpr["CHILD"].test( match[0] ) ) {
+                return null;
+              }
+
+              // Accept quoted arguments as-is
+              if ( match[3] ) {
+                match[2] = match[4] || match[5] || "";
+
+                // Strip excess characters from unquoted arguments
+              } else if ( unquoted && rpseudo.test( unquoted ) &&
+                  // Get excess from tokenize (recursively)
+                  (excess = tokenize( unquoted, true )) &&
+                  // advance to the next closing parenthesis
+                  (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+                // excess is a negative index
+                match[0] = match[0].slice( 0, excess );
+                match[2] = unquoted.slice( 0, excess );
+              }
+
+              // Return only captures needed by the pseudo filter method (type and argument)
+              return match.slice( 0, 3 );
+            }
+          },
+
+          filter: {
+
+            "TAG": function( nodeNameSelector ) {
+              var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+              return nodeNameSelector === "*" ?
+                  function() { return true; } :
+                  function( elem ) {
+                    return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                  };
+            },
+
+            "CLASS": function( className ) {
+              var pattern = classCache[ className + " " ];
+
+              return pattern ||
+                  (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+                  classCache( className, function( elem ) {
+                    return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+                  });
+            },
+
+            "ATTR": function( name, operator, check ) {
+              return function( elem ) {
+                var result = Sizzle.attr( elem, name );
+
+                if ( result == null ) {
+                  return operator === "!=";
+                }
+                if ( !operator ) {
+                  return true;
+                }
+
+                result += "";
+
+                return operator === "=" ? result === check :
+                    operator === "!=" ? result !== check :
+                        operator === "^=" ? check && result.indexOf( check ) === 0 :
+                            operator === "*=" ? check && result.indexOf( check ) > -1 :
+                                operator === "$=" ? check && result.slice( -check.length ) === check :
+                                    operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+                                        operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+                                            false;
+              };
+            },
+
+            "CHILD": function( type, what, argument, first, last ) {
+              var simple = type.slice( 0, 3 ) !== "nth",
+                  forward = type.slice( -4 ) !== "last",
+                  ofType = what === "of-type";
+
+              return first === 1 && last === 0 ?
+
+                  // Shortcut for :nth-*(n)
+                  function( elem ) {
+                    return !!elem.parentNode;
+                  } :
+
+                  function( elem, context, xml ) {
+                    var cache, uniqueCache, outerCache, node, nodeIndex, start,
+                        dir = simple !== forward ? "nextSibling" : "previousSibling",
+                        parent = elem.parentNode,
+                        name = ofType && elem.nodeName.toLowerCase(),
+                        useCache = !xml && !ofType,
+                        diff = false;
+
+                    if ( parent ) {
+
+                      // :(first|last|only)-(child|of-type)
+                      if ( simple ) {
+                        while ( dir ) {
+                          node = elem;
+                          while ( (node = node[ dir ]) ) {
+                            if ( ofType ?
+                                node.nodeName.toLowerCase() === name :
+                                node.nodeType === 1 ) {
+
+                              return false;
+                            }
+                          }
+                          // Reverse direction for :only-* (if we haven't yet done so)
+                          start = dir = type === "only" && !start && "nextSibling";
+                        }
+                        return true;
+                      }
+
+                      start = [ forward ? parent.firstChild : parent.lastChild ];
+
+                      // non-xml :nth-child(...) stores cache data on `parent`
+                      if ( forward && useCache ) {
+
+                        // Seek `elem` from a previously-cached index
+
+                        // ...in a gzip-friendly way
+                        node = parent;
+                        outerCache = node[ expando ] || (node[ expando ] = {});
+
+                        // Support: IE <9 only
+                        // Defend against cloned attroperties (jQuery gh-1709)
+                        uniqueCache = outerCache[ node.uniqueID ] ||
+                            (outerCache[ node.uniqueID ] = {});
+
+                        cache = uniqueCache[ type ] || [];
+                        nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+                        diff = nodeIndex && cache[ 2 ];
+                        node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                        while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+                            // Fallback to seeking `elem` from the start
+                            (diff = nodeIndex = 0) || start.pop()) ) {
+
+                          // When found, cache indexes on `parent` and break
+                          if ( node.nodeType === 1 && ++diff && node === elem ) {
+                            uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+                            break;
+                          }
+                        }
+
+                      } else {
+                        // Use previously-cached element index if available
+                        if ( useCache ) {
+                          // ...in a gzip-friendly way
+                          node = elem;
+                          outerCache = node[ expando ] || (node[ expando ] = {});
+
+                          // Support: IE <9 only
+                          // Defend against cloned attroperties (jQuery gh-1709)
+                          uniqueCache = outerCache[ node.uniqueID ] ||
+                              (outerCache[ node.uniqueID ] = {});
+
+                          cache = uniqueCache[ type ] || [];
+                          nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+                          diff = nodeIndex;
+                        }
+
+                        // xml :nth-child(...)
+                        // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+                        if ( diff === false ) {
+                          // Use the same loop as above to seek `elem` from the start
+                          while ( (node = ++nodeIndex && node && node[ dir ] ||
+                              (diff = nodeIndex = 0) || start.pop()) ) {
+
+                            if ( ( ofType ?
+                                node.nodeName.toLowerCase() === name :
+                                node.nodeType === 1 ) &&
+                                ++diff ) {
+
+                              // Cache the index of each encountered element
+                              if ( useCache ) {
+                                outerCache = node[ expando ] || (node[ expando ] = {});
+
+                                // Support: IE <9 only
+                                // Defend against cloned attroperties (jQuery gh-1709)
+                                uniqueCache = outerCache[ node.uniqueID ] ||
+                                    (outerCache[ node.uniqueID ] = {});
+
+                                uniqueCache[ type ] = [ dirruns, diff ];
+                              }
+
+                              if ( node === elem ) {
+                                break;
+                              }
+                            }
+                          }
+                        }
+                      }
+
+                      // Incorporate the offset, then check against cycle size
+                      diff -= last;
+                      return diff === first || ( diff % first === 0 && diff / first >= 0 );
+                    }
+                  };
+            },
+
+            "PSEUDO": function( pseudo, argument ) {
+              // pseudo-class names are case-insensitive
+              // http://www.w3.org/TR/selectors/#pseudo-classes
+              // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+              // Remember that setFilters inherits from pseudos
+              var args,
+                  fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                      Sizzle.error( "unsupported pseudo: " + pseudo );
+
+              // The user may use createPseudo to indicate that
+              // arguments are needed to create the filter function
+              // just as Sizzle does
+              if ( fn[ expando ] ) {
+                return fn( argument );
+              }
+
+              // But maintain support for old signatures
+              if ( fn.length > 1 ) {
+                args = [ pseudo, pseudo, "", argument ];
+                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                    markFunction(function( seed, matches ) {
+                      var idx,
+                          matched = fn( seed, argument ),
+                          i = matched.length;
+                      while ( i-- ) {
+                        idx = indexOf( seed, matched[i] );
+                        seed[ idx ] = !( matches[ idx ] = matched[i] );
+                      }
+                    }) :
+                    function( elem ) {
+                      return fn( elem, 0, args );
+                    };
+              }
+
+              return fn;
+            }
+          },
+
+          pseudos: {
+            // Potentially complex pseudos
+            "not": markFunction(function( selector ) {
+              // Trim the selector passed to compile
+              // to avoid treating leading and trailing
+              // spaces as combinators
+              var input = [],
+                  results = [],
+                  matcher = compile( selector.replace( rtrim, "$1" ) );
+
+              return matcher[ expando ] ?
+                  markFunction(function( seed, matches, context, xml ) {
+                    var elem,
+                        unmatched = matcher( seed, null, xml, [] ),
+                        i = seed.length;
+
+                    // Match elements unmatched by `matcher`
+                    while ( i-- ) {
+                      if ( (elem = unmatched[i]) ) {
+                        seed[i] = !(matches[i] = elem);
+                      }
+                    }
+                  }) :
+                  function( elem, context, xml ) {
+                    input[0] = elem;
+                    matcher( input, null, xml, results );
+                    // Don't keep the element (issue #299)
+                    input[0] = null;
+                    return !results.pop();
+                  };
+            }),
+
+            "has": markFunction(function( selector ) {
+              return function( elem ) {
+                return Sizzle( selector, elem ).length > 0;
+              };
+            }),
+
+            "contains": markFunction(function( text ) {
+              text = text.replace( runescape, funescape );
+              return function( elem ) {
+                return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+              };
+            }),
+
+            // "Whether an element is represented by a :lang() selector
+            // is based solely on the element's language value
+            // being equal to the identifier C,
+            // or beginning with the identifier C immediately followed by "-".
+            // The matching of C against the element's language value is performed case-insensitively.
+            // The identifier C does not have to be a valid language name."
+            // http://www.w3.org/TR/selectors/#lang-pseudo
+            "lang": markFunction( function( lang ) {
+              // lang value must be a valid identifier
+              if ( !ridentifier.test(lang || "") ) {
+                Sizzle.error( "unsupported lang: " + lang );
+              }
+              lang = lang.replace( runescape, funescape ).toLowerCase();
+              return function( elem ) {
+                var elemLang;
+                do {
+                  if ( (elemLang = documentIsHTML ?
+                      elem.lang :
+                      elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+                    elemLang = elemLang.toLowerCase();
+                    return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+                  }
+                } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                return false;
+              };
+            }),
+
+            // Miscellaneous
+            "target": function( elem ) {
+              var hash = window.location && window.location.hash;
+              return hash && hash.slice( 1 ) === elem.id;
+            },
+
+            "root": function( elem ) {
+              return elem === docElem;
+            },
+
+            "focus": function( elem ) {
+              return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+            },
+
+            // Boolean properties
+            "enabled": createDisabledPseudo( false ),
+            "disabled": createDisabledPseudo( true ),
+
+            "checked": function( elem ) {
+              // In CSS3, :checked should return both checked and selected elements
+              // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+              var nodeName = elem.nodeName.toLowerCase();
+              return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+            },
+
+            "selected": function( elem ) {
+              // Accessing this property makes selected-by-default
+              // options in Safari work properly
+              if ( elem.parentNode ) {
+                elem.parentNode.selectedIndex;
+              }
+
+              return elem.selected === true;
+            },
+
+            // Contents
+            "empty": function( elem ) {
+              // http://www.w3.org/TR/selectors/#empty-pseudo
+              // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+              //   but not by others (comment: 8; processing instruction: 7; etc.)
+              // nodeType < 6 works because attributes (2) do not appear as children
+              for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                if ( elem.nodeType < 6 ) {
+                  return false;
+                }
+              }
+              return true;
+            },
+
+            "parent": function( elem ) {
+              return !Expr.pseudos["empty"]( elem );
+            },
+
+            // Element/input types
+            "header": function( elem ) {
+              return rheader.test( elem.nodeName );
+            },
+
+            "input": function( elem ) {
+              return rinputs.test( elem.nodeName );
+            },
+
+            "button": function( elem ) {
+              var name = elem.nodeName.toLowerCase();
+              return name === "input" && elem.type === "button" || name === "button";
+            },
+
+            "text": function( elem ) {
+              var attr;
+              return elem.nodeName.toLowerCase() === "input" &&
+                  elem.type === "text" &&
+
+                  // Support: IE<8
+                  // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+                  ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+            },
+
+            // Position-in-collection
+            "first": createPositionalPseudo(function() {
+              return [ 0 ];
+            }),
+
+            "last": createPositionalPseudo(function( matchIndexes, length ) {
+              return [ length - 1 ];
+            }),
+
+            "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+              return [ argument < 0 ? argument + length : argument ];
+            }),
+
+            "even": createPositionalPseudo(function( matchIndexes, length ) {
+              var i = 0;
+              for ( ; i < length; i += 2 ) {
+                matchIndexes.push( i );
+              }
+              return matchIndexes;
+            }),
+
+            "odd": createPositionalPseudo(function( matchIndexes, length ) {
+              var i = 1;
+              for ( ; i < length; i += 2 ) {
+                matchIndexes.push( i );
+              }
+              return matchIndexes;
+            }),
+
+            "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+              var i = argument < 0 ? argument + length : argument;
+              for ( ; --i >= 0; ) {
+                matchIndexes.push( i );
+              }
+              return matchIndexes;
+            }),
+
+            "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+              var i = argument < 0 ? argument + length : argument;
+              for ( ; ++i < length; ) {
+                matchIndexes.push( i );
+              }
+              return matchIndexes;
+            })
+          }
+        };
+
+        Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+        for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+          Expr.pseudos[ i ] = createInputPseudo( i );
+        }
+        for ( i in { submit: true, reset: true } ) {
+          Expr.pseudos[ i ] = createButtonPseudo( i );
+        }
+
+// Easy API for creating new setFilters
+        function setFilters() {}
+        setFilters.prototype = Expr.filters = Expr.pseudos;
+        Expr.setFilters = new setFilters();
+
+        tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+          var matched, match, tokens, type,
+              soFar, groups, preFilters,
+              cached = tokenCache[ selector + " " ];
+
+          if ( cached ) {
+            return parseOnly ? 0 : cached.slice( 0 );
+          }
+
+          soFar = selector;
+          groups = [];
+          preFilters = Expr.preFilter;
+
+          while ( soFar ) {
+
+            // Comma and first run
+            if ( !matched || (match = rcomma.exec( soFar )) ) {
+              if ( match ) {
+                // Don't consume trailing commas as valid
+                soFar = soFar.slice( match[0].length ) || soFar;
+              }
+              groups.push( (tokens = []) );
+            }
+
+            matched = false;
+
+            // Combinators
+            if ( (match = rcombinators.exec( soFar )) ) {
+              matched = match.shift();
+              tokens.push({
+                value: matched,
+                // Cast descendant combinators to space
+                type: match[0].replace( rtrim, " " )
+              });
+              soFar = soFar.slice( matched.length );
+            }
+
+            // Filters
+            for ( type in Expr.filter ) {
+              if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+                  (match = preFilters[ type ]( match ))) ) {
+                matched = match.shift();
+                tokens.push({
+                  value: matched,
+                  type: type,
+                  matches: match
+                });
+                soFar = soFar.slice( matched.length );
+              }
+            }
+
+            if ( !matched ) {
+              break;
+            }
+          }
+
+          // Return the length of the invalid excess
+          // if we're just parsing
+          // Otherwise, throw an error or return tokens
+          return parseOnly ?
+              soFar.length :
+              soFar ?
+                  Sizzle.error( selector ) :
+                  // Cache the tokens
+                  tokenCache( selector, groups ).slice( 0 );
+        };
+
+        function toSelector( tokens ) {
+          var i = 0,
+              len = tokens.length,
+              selector = "";
+          for ( ; i < len; i++ ) {
+            selector += tokens[i].value;
+          }
+          return selector;
+        }
+
+        function addCombinator( matcher, combinator, base ) {
+          var dir = combinator.dir,
+              skip = combinator.next,
+              key = skip || dir,
+              checkNonElements = base && key === "parentNode",
+              doneName = done++;
+
+          return combinator.first ?
+              // Check against closest ancestor/preceding element
+              function( elem, context, xml ) {
+                while ( (elem = elem[ dir ]) ) {
+                  if ( elem.nodeType === 1 || checkNonElements ) {
+                    return matcher( elem, context, xml );
+                  }
+                }
+                return false;
+              } :
+
+              // Check against all ancestor/preceding elements
+              function( elem, context, xml ) {
+                var oldCache, uniqueCache, outerCache,
+                    newCache = [ dirruns, doneName ];
+
+                // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+                if ( xml ) {
+                  while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                      if ( matcher( elem, context, xml ) ) {
+                        return true;
+                      }
+                    }
+                  }
+                } else {
+                  while ( (elem = elem[ dir ]) ) {
+                    if ( elem.nodeType === 1 || checkNonElements ) {
+                      outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+                      // Support: IE <9 only
+                      // Defend against cloned attroperties (jQuery gh-1709)
+                      uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+                      if ( skip && skip === elem.nodeName.toLowerCase() ) {
+                        elem = elem[ dir ] || elem;
+                      } else if ( (oldCache = uniqueCache[ key ]) &&
+                          oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+                        // Assign to newCache so results back-propagate to previous elements
+                        return (newCache[ 2 ] = oldCache[ 2 ]);
+                      } else {
+                        // Reuse newcache so results back-propagate to previous elements
+                        uniqueCache[ key ] = newCache;
+
+                        // A match means we're done; a fail means we have to keep checking
+                        if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+                          return true;
+                        }
+                      }
+                    }
+                  }
+                }
+                return false;
+              };
+        }
+
+        function elementMatcher( matchers ) {
+          return matchers.length > 1 ?
+              function( elem, context, xml ) {
+                var i = matchers.length;
+                while ( i-- ) {
+                  if ( !matchers[i]( elem, context, xml ) ) {
+                    return false;
+                  }
+                }
+                return true;
+              } :
+              matchers[0];
+        }
+
+        function multipleContexts( selector, contexts, results ) {
+          var i = 0,
+              len = contexts.length;
+          for ( ; i < len; i++ ) {
+            Sizzle( selector, contexts[i], results );
+          }
+          return results;
+        }
+
+        function condense( unmatched, map, filter, context, xml ) {
+          var elem,
+              newUnmatched = [],
+              i = 0,
+              len = unmatched.length,
+              mapped = map != null;
+
+          for ( ; i < len; i++ ) {
+            if ( (elem = unmatched[i]) ) {
+              if ( !filter || filter( elem, context, xml ) ) {
+                newUnmatched.push( elem );
+                if ( mapped ) {
+                  map.push( i );
+                }
+              }
+            }
+          }
+
+          return newUnmatched;
+        }
+
+        function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+          if ( postFilter && !postFilter[ expando ] ) {
+            postFilter = setMatcher( postFilter );
+          }
+          if ( postFinder && !postFinder[ expando ] ) {
+            postFinder = setMatcher( postFinder, postSelector );
+          }
+          return markFunction(function( seed, results, context, xml ) {
+            var temp, i, elem,
+                preMap = [],
+                postMap = [],
+                preexisting = results.length,
+
+                // Get initial elements from seed or context
+                elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+                // Prefilter to get matcher input, preserving a map for seed-results synchronization
+                matcherIn = preFilter && ( seed || !selector ) ?
+                    condense( elems, preMap, preFilter, context, xml ) :
+                    elems,
+
+                matcherOut = matcher ?
+                    // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+                    postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+                        // ...intermediate processing is necessary
+                        [] :
+
+                        // ...otherwise use results directly
+                        results :
+                    matcherIn;
+
+            // Find primary matches
+            if ( matcher ) {
+              matcher( matcherIn, matcherOut, context, xml );
+            }
+
+            // Apply postFilter
+            if ( postFilter ) {
+              temp = condense( matcherOut, postMap );
+              postFilter( temp, [], context, xml );
+
+              // Un-match failing elements by moving them back to matcherIn
+              i = temp.length;
+              while ( i-- ) {
+                if ( (elem = temp[i]) ) {
+                  matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                }
+              }
+            }
+
+            if ( seed ) {
+              if ( postFinder || preFilter ) {
+                if ( postFinder ) {
+                  // Get the final matcherOut by condensing this intermediate into postFinder contexts
+                  temp = [];
+                  i = matcherOut.length;
+                  while ( i-- ) {
+                    if ( (elem = matcherOut[i]) ) {
+                      // Restore matcherIn since elem is not yet a final match
+                      temp.push( (matcherIn[i] = elem) );
+                    }
+                  }
+                  postFinder( null, (matcherOut = []), temp, xml );
+                }
+
+                // Move matched elements from seed to results to keep them synchronized
+                i = matcherOut.length;
+                while ( i-- ) {
+                  if ( (elem = matcherOut[i]) &&
+                      (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+                    seed[temp] = !(results[temp] = elem);
+                  }
+                }
+              }
+
+              // Add elements to results, through postFinder if defined
+            } else {
+              matcherOut = condense(
+                  matcherOut === results ?
+                      matcherOut.splice( preexisting, matcherOut.length ) :
+                      matcherOut
+              );
+              if ( postFinder ) {
+                postFinder( null, results, matcherOut, xml );
+              } else {
+                push.apply( results, matcherOut );
+              }
+            }
+          });
+        }
+
+        function matcherFromTokens( tokens ) {
+          var checkContext, matcher, j,
+              len = tokens.length,
+              leadingRelative = Expr.relative[ tokens[0].type ],
+              implicitRelative = leadingRelative || Expr.relative[" "],
+              i = leadingRelative ? 1 : 0,
+
+              // The foundational matcher ensures that elements are reachable from top-level context(s)
+              matchContext = addCombinator( function( elem ) {
+                return elem === checkContext;
+              }, implicitRelative, true ),
+              matchAnyContext = addCombinator( function( elem ) {
+                return indexOf( checkContext, elem ) > -1;
+              }, implicitRelative, true ),
+              matchers = [ function( elem, context, xml ) {
+                var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+                    (checkContext = context).nodeType ?
+                        matchContext( elem, context, xml ) :
+                        matchAnyContext( elem, context, xml ) );
+                // Avoid hanging onto element (issue #299)
+                checkContext = null;
+                return ret;
+              } ];
+
+          for ( ; i < len; i++ ) {
+            if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+              matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+            } else {
+              matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+              // Return special upon seeing a positional matcher
+              if ( matcher[ expando ] ) {
+                // Find the next relative operator (if any) for proper handling
+                j = ++i;
+                for ( ; j < len; j++ ) {
+                  if ( Expr.relative[ tokens[j].type ] ) {
+                    break;
+                  }
+                }
+                return setMatcher(
+                    i > 1 && elementMatcher( matchers ),
+                    i > 1 && toSelector(
+                    // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+                    tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+                    ).replace( rtrim, "$1" ),
+                    matcher,
+                    i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                    j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+                    j < len && toSelector( tokens )
+                );
+              }
+              matchers.push( matcher );
+            }
+          }
+
+          return elementMatcher( matchers );
+        }
+
+        function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+          var bySet = setMatchers.length > 0,
+              byElement = elementMatchers.length > 0,
+              superMatcher = function( seed, context, xml, results, outermost ) {
+                var elem, j, matcher,
+                    matchedCount = 0,
+                    i = "0",
+                    unmatched = seed && [],
+                    setMatched = [],
+                    contextBackup = outermostContext,
+                    // We must always have either seed elements or outermost context
+                    elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+                    // Use integer dirruns iff this is the outermost matcher
+                    dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+                    len = elems.length;
+
+                if ( outermost ) {
+                  outermostContext = context === document || context || outermost;
+                }
+
+                // Add elements passing elementMatchers directly to results
+                // Support: IE<9, Safari
+                // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
+                for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+                  if ( byElement && elem ) {
+                    j = 0;
+                    if ( !context && elem.ownerDocument !== document ) {
+                      setDocument( elem );
+                      xml = !documentIsHTML;
+                    }
+                    while ( (matcher = elementMatchers[j++]) ) {
+                      if ( matcher( elem, context || document, xml) ) {
+                        results.push( elem );
+                        break;
+                      }
+                    }
+                    if ( outermost ) {
+                      dirruns = dirrunsUnique;
+                    }
+                  }
+
+                  // Track unmatched elements for set filters
+                  if ( bySet ) {
+                    // They will have gone through all possible matchers
+                    if ( (elem = !matcher && elem) ) {
+                      matchedCount--;
+                    }
+
+                    // Lengthen the array for every element, matched or not
+                    if ( seed ) {
+                      unmatched.push( elem );
+                    }
+                  }
+                }
+
+                // `i` is now the count of elements visited above, and adding it to `matchedCount`
+                // makes the latter nonnegative.
+                matchedCount += i;
+
+                // Apply set filters to unmatched elements
+                // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+                // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+                // no element matchers and no seed.
+                // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+                // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+                // numerically zero.
+                if ( bySet && i !== matchedCount ) {
+                  j = 0;
+                  while ( (matcher = setMatchers[j++]) ) {
+                    matcher( unmatched, setMatched, context, xml );
+                  }
+
+                  if ( seed ) {
+                    // Reintegrate element matches to eliminate the need for sorting
+                    if ( matchedCount > 0 ) {
+                      while ( i-- ) {
+                        if ( !(unmatched[i] || setMatched[i]) ) {
+                          setMatched[i] = pop.call( results );
+                        }
+                      }
+                    }
+
+                    // Discard index placeholder values to get only actual matches
+                    setMatched = condense( setMatched );
+                  }
+
+                  // Add matches to results
+                  push.apply( results, setMatched );
+
+                  // Seedless set matches succeeding multiple successful matchers stipulate sorting
+                  if ( outermost && !seed && setMatched.length > 0 &&
+                      ( matchedCount + setMatchers.length ) > 1 ) {
+
+                    Sizzle.uniqueSort( results );
+                  }
+                }
+
+                // Override manipulation of globals by nested matchers
+                if ( outermost ) {
+                  dirruns = dirrunsUnique;
+                  outermostContext = contextBackup;
+                }
+
+                return unmatched;
+              };
+
+          return bySet ?
+              markFunction( superMatcher ) :
+              superMatcher;
+        }
+
+        compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+          var i,
+              setMatchers = [],
+              elementMatchers = [],
+              cached = compilerCache[ selector + " " ];
+
+          if ( !cached ) {
+            // Generate a function of recursive functions that can be used to check each element
+            if ( !match ) {
+              match = tokenize( selector );
+            }
+            i = match.length;
+            while ( i-- ) {
+              cached = matcherFromTokens( match[i] );
+              if ( cached[ expando ] ) {
+                setMatchers.push( cached );
+              } else {
+                elementMatchers.push( cached );
+              }
+            }
+
+            // Cache the compiled function
+            cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+            // Save selector and tokenization
+            cached.selector = selector;
+          }
+          return cached;
+        };
+
+        /**
+         * A low-level selection function that works with Sizzle's compiled
+         *  selector functions
+         * @param {String|Function} selector A selector or a pre-compiled
+         *  selector function built with Sizzle.compile
+         * @param {Element} context
+         * @param {Array} [results]
+         * @param {Array} [seed] A set of elements to match against
+         */
+        select = Sizzle.select = function( selector, context, results, seed ) {
+          var i, tokens, token, type, find,
+              compiled = typeof selector === "function" && selector,
+              match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+          results = results || [];
+
+          // Try to minimize operations if there is only one selector in the list and no seed
+          // (the latter of which guarantees us context)
+          if ( match.length === 1 ) {
+
+            // Reduce context if the leading compound selector is an ID
+            tokens = match[0] = match[0].slice( 0 );
+            if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
+
+              context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+              if ( !context ) {
+                return results;
+
+                // Precompiled matchers will still verify ancestry, so step up a level
+              } else if ( compiled ) {
+                context = context.parentNode;
+              }
+
+              selector = selector.slice( tokens.shift().value.length );
+            }
+
+            // Fetch a seed set for right-to-left matching
+            i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+            while ( i-- ) {
+              token = tokens[i];
+
+              // Abort if we hit a combinator
+              if ( Expr.relative[ (type = token.type) ] ) {
+                break;
+              }
+              if ( (find = Expr.find[ type ]) ) {
+                // Search, expanding context for leading sibling combinators
+                if ( (seed = find(
+                    token.matches[0].replace( runescape, funescape ),
+                    rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+                )) ) {
+
+                  // If seed is empty or no tokens remain, we can return early
+                  tokens.splice( i, 1 );
+                  selector = seed.length && toSelector( tokens );
+                  if ( !selector ) {
+                    push.apply( results, seed );
+                    return results;
+                  }
+
+                  break;
+                }
+              }
+            }
+          }
+
+          // Compile and execute a filtering function if one is not provided
+          // Provide `match` to avoid retokenization if we modified the selector above
+          ( compiled || compile( selector, match ) )(
+              seed,
+              context,
+              !documentIsHTML,
+              results,
+              !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+          );
+          return results;
+        };
+
+// One-time assignments
+
+// Sort stability
+        support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+        support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+        setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+        support.sortDetached = assert(function( el ) {
+          // Should return 1, but returns 4 (following)
+          return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+        });
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+        if ( !assert(function( el ) {
+          el.innerHTML = "<a href='#'></a>";
+          return el.firstChild.getAttribute("href") === "#" ;
+        }) ) {
+          addHandle( "type|href|height|width", function( elem, name, isXML ) {
+            if ( !isXML ) {
+              return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+            }
+          });
+        }
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+        if ( !support.attributes || !assert(function( el ) {
+          el.innerHTML = "<input/>";
+          el.firstChild.setAttribute( "value", "" );
+          return el.firstChild.getAttribute( "value" ) === "";
+        }) ) {
+          addHandle( "value", function( elem, name, isXML ) {
+            if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+              return elem.defaultValue;
+            }
+          });
+        }
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+        if ( !assert(function( el ) {
+          return el.getAttribute("disabled") == null;
+        }) ) {
+          addHandle( booleans, function( elem, name, isXML ) {
+            var val;
+            if ( !isXML ) {
+              return elem[ name ] === true ? name.toLowerCase() :
+                  (val = elem.getAttributeNode( name )) && val.specified ?
+                      val.value :
+                      null;
+            }
+          });
+        }
+
+        return Sizzle;
+
+      })( window );
+
+
+
+  jQuery.find = Sizzle;
+  jQuery.expr = Sizzle.selectors;
+
+// Deprecated
+  jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+  jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+  jQuery.text = Sizzle.getText;
+  jQuery.isXMLDoc = Sizzle.isXML;
+  jQuery.contains = Sizzle.contains;
+  jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+  var dir = function( elem, dir, until ) {
+    var matched = [],
+        truncate = until !== undefined;
+
+    while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+      if ( elem.nodeType === 1 ) {
+        if ( truncate && jQuery( elem ).is( until ) ) {
+          break;
+        }
+        matched.push( elem );
+      }
+    }
+    return matched;
+  };
+
+
+  var siblings = function( n, elem ) {
+    var matched = [];
+
+    for ( ; n; n = n.nextSibling ) {
+      if ( n.nodeType === 1 && n !== elem ) {
+        matched.push( n );
+      }
+    }
+
+    return matched;
+  };
+
+
+  var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+  function nodeName( elem, name ) {
+
+    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+  };
+  var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+// Implement the identical functionality for filter and not
+  function winnow( elements, qualifier, not ) {
+    if ( isFunction( qualifier ) ) {
+      return jQuery.grep( elements, function( elem, i ) {
+        return !!qualifier.call( elem, i, elem ) !== not;
+      } );
+    }
+
+    // Single element
+    if ( qualifier.nodeType ) {
+      return jQuery.grep( elements, function( elem ) {
+        return ( elem === qualifier ) !== not;
+      } );
+    }
+
+    // Arraylike of elements (jQuery, arguments, Array)
+    if ( typeof qualifier !== "string" ) {
+      return jQuery.grep( elements, function( elem ) {
+        return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+      } );
+    }
+
+    // Filtered directly for both simple and complex selectors
+    return jQuery.filter( qualifier, elements, not );
+  }
+
+  jQuery.filter = function( expr, elems, not ) {
+    var elem = elems[ 0 ];
+
+    if ( not ) {
+      expr = ":not(" + expr + ")";
+    }
+
+    if ( elems.length === 1 && elem.nodeType === 1 ) {
+      return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+    }
+
+    return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+      return elem.nodeType === 1;
+    } ) );
+  };
+
+  jQuery.fn.extend( {
+    find: function( selector ) {
+      var i, ret,
+          len = this.length,
+          self = this;
+
+      if ( typeof selector !== "string" ) {
+        return this.pushStack( jQuery( selector ).filter( function() {
+          for ( i = 0; i < len; i++ ) {
+            if ( jQuery.contains( self[ i ], this ) ) {
+              return true;
+            }
+          }
+        } ) );
+      }
+
+      ret = this.pushStack( [] );
+
+      for ( i = 0; i < len; i++ ) {
+        jQuery.find( selector, self[ i ], ret );
+      }
+
+      return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+    },
+    filter: function( selector ) {
+      return this.pushStack( winnow( this, selector || [], false ) );
+    },
+    not: function( selector ) {
+      return this.pushStack( winnow( this, selector || [], true ) );
+    },
+    is: function( selector ) {
+      return !!winnow(
+          this,
+
+          // If this is a positional/relative selector, check membership in the returned set
+          // so $("p:first").is("p:last") won't return true for a doc with two "p".
+          typeof selector === "string" && rneedsContext.test( selector ) ?
+              jQuery( selector ) :
+              selector || [],
+          false
+      ).length;
+    }
+  } );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+  var rootjQuery,
+
+      // A simple way to check for HTML strings
+      // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+      // Strict HTML recognition (#11290: must start with <)
+      // Shortcut simple #id case for speed
+      rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+      init = jQuery.fn.init = function( selector, context, root ) {
+        var match, elem;
+
+        // HANDLE: $(""), $(null), $(undefined), $(false)
+        if ( !selector ) {
+          return this;
+        }
+
+        // Method init() accepts an alternate rootjQuery
+        // so migrate can support jQuery.sub (gh-2101)
+        root = root || rootjQuery;
+
+        // Handle HTML strings
+        if ( typeof selector === "string" ) {
+          if ( selector[ 0 ] === "<" &&
+              selector[ selector.length - 1 ] === ">" &&
+              selector.length >= 3 ) {
+
+            // Assume that strings that start and end with <> are HTML and skip the regex check
+            match = [ null, selector, null ];
+
+          } else {
+            match = rquickExpr.exec( selector );
+          }
+
+          // Match html or make sure no context is specified for #id
+          if ( match && ( match[ 1 ] || !context ) ) {
+
+            // HANDLE: $(html) -> $(array)
+            if ( match[ 1 ] ) {
+              context = context instanceof jQuery ? context[ 0 ] : context;
+
+              // Option to run scripts is true for back-compat
+              // Intentionally let the error be thrown if parseHTML is not present
+              jQuery.merge( this, jQuery.parseHTML(
+                  match[ 1 ],
+                  context && context.nodeType ? context.ownerDocument || context : document,
+                  true
+              ) );
+
+              // HANDLE: $(html, props)
+              if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+                for ( match in context ) {
+
+                  // Properties of context are called as methods if possible
+                  if ( isFunction( this[ match ] ) ) {
+                    this[ match ]( context[ match ] );
+
+                    // ...and otherwise set as attributes
+                  } else {
+                    this.attr( match, context[ match ] );
+                  }
+                }
+              }
+
+              return this;
+
+              // HANDLE: $(#id)
+            } else {
+              elem = document.getElementById( match[ 2 ] );
+
+              if ( elem ) {
+
+                // Inject the element directly into the jQuery object
+                this[ 0 ] = elem;
+                this.length = 1;
+              }
+              return this;
+            }
+
+            // HANDLE: $(expr, $(...))
+          } else if ( !context || context.jquery ) {
+            return ( context || root ).find( selector );
+
+            // HANDLE: $(expr, context)
+            // (which is just equivalent to: $(context).find(expr)
+          } else {
+            return this.constructor( context ).find( selector );
+          }
+
+          // HANDLE: $(DOMElement)
+        } else if ( selector.nodeType ) {
+          this[ 0 ] = selector;
+          this.length = 1;
+          return this;
+
+          // HANDLE: $(function)
+          // Shortcut for document ready
+        } else if ( isFunction( selector ) ) {
+          return root.ready !== undefined ?
+              root.ready( selector ) :
+
+              // Execute immediately if ready is not present
+              selector( jQuery );
+        }
+
+        return jQuery.makeArray( selector, this );
+      };
+
+// Give the init function the jQuery prototype for later instantiation
+  init.prototype = jQuery.fn;
+
+// Initialize central reference
+  rootjQuery = jQuery( document );
+
+
+  var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+      // Methods guaranteed to produce a unique set when starting from a unique set
+      guaranteedUnique = {
+        children: true,
+        contents: true,
+        next: true,
+        prev: true
+      };
+
+  jQuery.fn.extend( {
+    has: function( target ) {
+      var targets = jQuery( target, this ),
+          l = targets.length;
+
+      return this.filter( function() {
+        var i = 0;
+        for ( ; i < l; i++ ) {
+          if ( jQuery.contains( this, targets[ i ] ) ) {
+            return true;
+          }
+        }
+      } );
+    },
+
+    closest: function( selectors, context ) {
+      var cur,
+          i = 0,
+          l = this.length,
+          matched = [],
+          targets = typeof selectors !== "string" && jQuery( selectors );
+
+      // Positional selectors never match, since there's no _selection_ context
+      if ( !rneedsContext.test( selectors ) ) {
+        for ( ; i < l; i++ ) {
+          for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+            // Always skip document fragments
+            if ( cur.nodeType < 11 && ( targets ?
+                targets.index( cur ) > -1 :
+
+                // Don't pass non-elements to Sizzle
+                cur.nodeType === 1 &&
+                jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+              matched.push( cur );
+              break;
+            }
+          }
+        }
+      }
+
+      return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+    },
+
+    // Determine the position of an element within the set
+    index: function( elem ) {
+
+      // No argument, return index in parent
+      if ( !elem ) {
+        return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+      }
+
+      // Index in selector
+      if ( typeof elem === "string" ) {
+        return indexOf.call( jQuery( elem ), this[ 0 ] );
+      }
+
+      // Locate the position of the desired element
+      return indexOf.call( this,
+
+          // If it receives a jQuery object, the first element is used
+          elem.jquery ? elem[ 0 ] : elem
+      );
+    },
+
+    add: function( selector, context ) {
+      return this.pushStack(
+          jQuery.uniqueSort(
+              jQuery.merge( this.get(), jQuery( selector, context ) )
+          )
+      );
+    },
+
+    addBack: function( selector ) {
+      return this.add( selector == null ?
+          this.prevObject : this.prevObject.filter( selector )
+      );
+    }
+  } );
+
+  function sibling( cur, dir ) {
+    while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+    return cur;
+  }
+
+  jQuery.each( {
+    parent: function( elem ) {
+      var parent = elem.parentNode;
+      return parent && parent.nodeType !== 11 ? parent : null;
+    },
+    parents: function( elem ) {
+      return dir( elem, "parentNode" );
+    },
+    parentsUntil: function( elem, i, until ) {
+      return dir( elem, "parentNode", until );
+    },
+    next: function( elem ) {
+      return sibling( elem, "nextSibling" );
+    },
+    prev: function( elem ) {
+      return sibling( elem, "previousSibling" );
+    },
+    nextAll: function( elem ) {
+      return dir( elem, "nextSibling" );
+    },
+    prevAll: function( elem ) {
+      return dir( elem, "previousSibling" );
+    },
+    nextUntil: function( elem, i, until ) {
+      return dir( elem, "nextSibling", until );
+    },
+    prevUntil: function( elem, i, until ) {
+      return dir( elem, "previousSibling", until );
+    },
+    siblings: function( elem ) {
+      return siblings( ( elem.parentNode || {} ).firstChild, elem );
+    },
+    children: function( elem ) {
+      return siblings( elem.firstChild );
+    },
+    contents: function( elem ) {
+      if ( nodeName( elem, "iframe" ) ) {
+        return elem.contentDocument;
+      }
+
+      // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+      // Treat the template element as a regular one in browsers that
+      // don't support it.
+      if ( nodeName( elem, "template" ) ) {
+        elem = elem.content || elem;
+      }
+
+      return jQuery.merge( [], elem.childNodes );
+    }
+  }, function( name, fn ) {
+    jQuery.fn[ name ] = function( until, selector ) {
+      var matched = jQuery.map( this, fn, until );
+
+      if ( name.slice( -5 ) !== "Until" ) {
+        selector = until;
+      }
+
+      if ( selector && typeof selector === "string" ) {
+        matched = jQuery.filter( selector, matched );
+      }
+
+      if ( this.length > 1 ) {
+
+        // Remove duplicates
+        if ( !guaranteedUnique[ name ] ) {
+          jQuery.uniqueSort( matched );
+        }
+
+        // Reverse order for parents* and prev-derivatives
+        if ( rparentsprev.test( name ) ) {
+          matched.reverse();
+        }
+      }
+
+      return this.pushStack( matched );
+    };
+  } );
+  var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+  function createOptions( options ) {
+    var object = {};
+    jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
+      object[ flag ] = true;
+    } );
+    return object;
+  }
+
+  /*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+  jQuery.Callbacks = function( options ) {
+
+    // Convert options from String-formatted to Object-formatted if needed
+    // (we check in cache first)
+    options = typeof options === "string" ?
+        createOptions( options ) :
+        jQuery.extend( {}, options );
+
+    var // Flag to know if list is currently firing
+        firing,
+
+        // Last fire value for non-forgettable lists
+        memory,
+
+        // Flag to know if list was already fired
+        fired,
+
+        // Flag to prevent firing
+        locked,
+
+        // Actual callback list
+        list = [],
+
+        // Queue of execution data for repeatable lists
+        queue = [],
+
+        // Index of currently firing callback (modified by add/remove as needed)
+        firingIndex = -1,
+
+        // Fire callbacks
+        fire = function() {
+
+          // Enforce single-firing
+          locked = locked || options.once;
+
+          // Execute callbacks for all pending executions,
+          // respecting firingIndex overrides and runtime changes
+          fired = firing = true;
+          for ( ; queue.length; firingIndex = -1 ) {
+            memory = queue.shift();
+            while ( ++firingIndex < list.length ) {
+
+              // Run callback and check for early termination
+              if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+                  options.stopOnFalse ) {
+
+                // Jump to end and forget the data so .add doesn't re-fire
+                firingIndex = list.length;
+                memory = false;
+              }
+            }
+          }
+
+          // Forget the data if we're done with it
+          if ( !options.memory ) {
+            memory = false;
+          }
+
+          firing = false;
+
+          // Clean up if we're done firing for good
+          if ( locked ) {
+
+            // Keep an empty list if we have data for future add calls
+            if ( memory ) {
+              list = [];
+
+              // Otherwise, this object is spent
+            } else {
+              list = "";
+            }
+          }
+        },
+
+        // Actual Callbacks object
+        self = {
+
+          // Add a callback or a collection of callbacks to the list
+          add: function() {
+            if ( list ) {
+
+              // If we have memory from a past run, we should fire after adding
+              if ( memory && !firing ) {
+                firingIndex = list.length - 1;
+                queue.push( memory );
+              }
+
+              ( function add( args ) {
+                jQuery.each( args, function( _, arg ) {
+                  if ( isFunction( arg ) ) {
+                    if ( !options.unique || !self.has( arg ) ) {
+                      list.push( arg );
+                    }
+                  } else if ( arg && arg.length && toType( arg ) !== "string" ) {
+
+                    // Inspect recursively
+                    add( arg );
+                  }
+                } );
+              } )( arguments );
+
+              if ( memory && !firing ) {
+                fire();
+              }
+            }
+            return this;
+          },
+
+          // Remove a callback from the list
+          remove: function() {
+            jQuery.each( arguments, function( _, arg ) {
+              var index;
+              while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+                list.splice( index, 1 );
+
+                // Handle firing indexes
+                if ( index <= firingIndex ) {
+                  firingIndex--;
+                }
+              }
+            } );
+            return this;
+          },
+
+          // Check if a given callback is in the list.
+          // If no argument is given, return whether or not list has callbacks attached.
+          has: function( fn ) {
+            return fn ?
+                jQuery.inArray( fn, list ) > -1 :
+                list.length > 0;
+          },
+
+          // Remove all callbacks from the list
+          empty: function() {
+            if ( list ) {
+              list = [];
+            }
+            return this;
+          },
+
+          // Disable .fire and .add
+          // Abort any current/pending executions
+          // Clear all callbacks and values
+          disable: function() {
+            locked = queue = [];
+            list = memory = "";
+            return this;
+          },
+          disabled: function() {
+            return !list;
+          },
+
+          // Disable .fire
+          // Also disable .add unless we have memory (since it would have no effect)
+          // Abort any pending executions
+          lock: function() {
+            locked = queue = [];
+            if ( !memory && !firing ) {
+              list = memory = "";
+            }
+            return this;
+          },
+          locked: function() {
+            return !!locked;
+          },
+
+          // Call all callbacks with the given context and arguments
+          fireWith: function( context, args ) {
+            if ( !locked ) {
+              args = args || [];
+              args = [ context, args.slice ? args.slice() : args ];
+              queue.push( args );
+              if ( !firing ) {
+                fire();
+              }
+            }
+            return this;
+          },
+
+          // Call all the callbacks with the given arguments
+          fire: function() {
+            self.fireWith( this, arguments );
+            return this;
+          },
+
+          // To know if the callbacks have already been called at least once
+          fired: function() {
+            return !!fired;
+          }
+        };
+
+    return self;
+  };
+
+
+  function Identity( v ) {
+    return v;
+  }
+  function Thrower( ex ) {
+    throw ex;
+  }
+
+  function adoptValue( value, resolve, reject, noValue ) {
+    var method;
+
+    try {
+
+      // Check for promise aspect first to privilege synchronous behavior
+      if ( value && isFunction( ( method = value.promise ) ) ) {
+        method.call( value ).done( resolve ).fail( reject );
+
+        // Other thenables
+      } else if ( value && isFunction( ( method = value.then ) ) ) {
+        method.call( value, resolve, reject );
+
+        // Other non-thenables
+      } else {
+
+        // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+        // * false: [ value ].slice( 0 ) => resolve( value )
+        // * true: [ value ].slice( 1 ) => resolve()
+        resolve.apply( undefined, [ value ].slice( noValue ) );
+      }
+
+      // For Promises/A+, convert exceptions into rejections
+      // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+      // Deferred#then to conditionally suppress rejection.
+    } catch ( value ) {
+
+      // Support: Android 4.0 only
+      // Strict mode functions invoked without .call/.apply get global-object context
+      reject.apply( undefined, [ value ] );
+    }
+  }
+
+  jQuery.extend( {
+
+    Deferred: function( func ) {
+      var tuples = [
+
+            // action, add listener, callbacks,
+            // ... .then handlers, argument index, [final state]
+            [ "notify", "progress", jQuery.Callbacks( "memory" ),
+              jQuery.Callbacks( "memory" ), 2 ],
+            [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+              jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+            [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+              jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+          ],
+          state = "pending",
+          promise = {
+            state: function() {
+              return state;
+            },
+            always: function() {
+              deferred.done( arguments ).fail( arguments );
+              return this;
+            },
+            "catch": function( fn ) {
+              return promise.then( null, fn );
+            },
+
+            // Keep pipe for back-compat
+            pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+              var fns = arguments;
+
+              return jQuery.Deferred( function( newDefer ) {
+                jQuery.each( tuples, function( i, tuple ) {
+
+                  // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+                  var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+                  // deferred.progress(function() { bind to newDefer or newDefer.notify })
+                  // deferred.done(function() { bind to newDefer or newDefer.resolve })
+                  // deferred.fail(function() { bind to newDefer or newDefer.reject })
+                  deferred[ tuple[ 1 ] ]( function() {
+                    var returned = fn && fn.apply( this, arguments );
+                    if ( returned && isFunction( returned.promise ) ) {
+                      returned.promise()
+                          .progress( newDefer.notify )
+                          .done( newDefer.resolve )
+                          .fail( newDefer.reject );
+                    } else {
+                      newDefer[ tuple[ 0 ] + "With" ](
+                          this,
+                          fn ? [ returned ] : arguments
+                      );
+                    }
+                  } );
+                } );
+                fns = null;
+              } ).promise();
+            },
+            then: function( onFulfilled, onRejected, onProgress ) {
+              var maxDepth = 0;
+              function resolve( depth, deferred, handler, special ) {
+                return function() {
+                  var that = this,
+                      args = arguments,
+                      mightThrow = function() {
+                        var returned, then;
+
+                        // Support: Promises/A+ section 2.3.3.3.3
+                        // https://promisesaplus.com/#point-59
+                        // Ignore double-resolution attempts
+                        if ( depth < maxDepth ) {
+                          return;
+                        }
+
+                        returned = handler.apply( that, args );
+
+                        // Support: Promises/A+ section 2.3.1
+                        // https://promisesaplus.com/#point-48
+                        if ( returned === deferred.promise() ) {
+                          throw new TypeError( "Thenable self-resolution" );
+                        }
+
+                        // Support: Promises/A+ sections 2.3.3.1, 3.5
+                        // https://promisesaplus.com/#point-54
+                        // https://promisesaplus.com/#point-75
+                        // Retrieve `then` only once
+                        then = returned &&
+
+                            // Support: Promises/A+ section 2.3.4
+                            // https://promisesaplus.com/#point-64
+                            // Only check objects and functions for thenability
+                            ( typeof returned === "object" ||
+                                typeof returned === "function" ) &&
+                            returned.then;
+
+                        // Handle a returned thenable
+                        if ( isFunction( then ) ) {
+
+                          // Special processors (notify) just wait for resolution
+                          if ( special ) {
+                            then.call(
+                                returned,
+                                resolve( maxDepth, deferred, Identity, special ),
+                                resolve( maxDepth, deferred, Thrower, special )
+                            );
+
+                            // Normal processors (resolve) also hook into progress
+                          } else {
+
+                            // ...and disregard older resolution values
+                            maxDepth++;
+
+                            then.call(
+                                returned,
+                                resolve( maxDepth, deferred, Identity, special ),
+                                resolve( maxDepth, deferred, Thrower, special ),
+                                resolve( maxDepth, deferred, Identity,
+                                    deferred.notifyWith )
+                            );
+                          }
+
+                          // Handle all other returned values
+                        } else {
+
+                          // Only substitute handlers pass on context
+                          // and multiple values (non-spec behavior)
+                          if ( handler !== Identity ) {
+                            that = undefined;
+                            args = [ returned ];
+                          }
+
+                          // Process the value(s)
+                          // Default process is resolve
+                          ( special || deferred.resolveWith )( that, args );
+                        }
+                      },
+
+                      // Only normal processors (resolve) catch and reject exceptions
+                      process = special ?
+                          mightThrow :
+                          function() {
+                            try {
+                              mightThrow();
+                            } catch ( e ) {
+
+                              if ( jQuery.Deferred.exceptionHook ) {
+                                jQuery.Deferred.exceptionHook( e,
+                                    process.stackTrace );
+                              }
+
+                              // Support: Promises/A+ section 2.3.3.3.4.1
+                              // https://promisesaplus.com/#point-61
+                              // Ignore post-resolution exceptions
+                              if ( depth + 1 >= maxDepth ) {
+
+                                // Only substitute handlers pass on context
+                                // and multiple values (non-spec behavior)
+                                if ( handler !== Thrower ) {
+                                  that = undefined;
+                                  args = [ e ];
+                                }
+
+                                deferred.rejectWith( that, args );
+                              }
+                            }
+                          };
+
+                  // Support: Promises/A+ section 2.3.3.3.1
+                  // https://promisesaplus.com/#point-57
+                  // Re-resolve promises immediately to dodge false rejection from
+                  // subsequent errors
+                  if ( depth ) {
+                    process();
+                  } else {
+
+                    // Call an optional hook to record the stack, in case of exception
+                    // since it's otherwise lost when execution goes async
+                    if ( jQuery.Deferred.getStackHook ) {
+                      process.stackTrace = jQuery.Deferred.getStackHook();
+                    }
+                    window.setTimeout( process );
+                  }
+                };
+              }
+
+              return jQuery.Deferred( function( newDefer ) {
+
+                // progress_handlers.add( ... )
+                tuples[ 0 ][ 3 ].add(
+                    resolve(
+                        0,
+                        newDefer,
+                        isFunction( onProgress ) ?
+                            onProgress :
+                            Identity,
+                        newDefer.notifyWith
+                    )
+                );
+
+                // fulfilled_handlers.add( ... )
+                tuples[ 1 ][ 3 ].add(
+                    resolve(
+                        0,
+                        newDefer,
+                        isFunction( onFulfilled ) ?
+                            onFulfilled :
+                            Identity
+                    )
+                );
+
+                // rejected_handlers.add( ... )
+                tuples[ 2 ][ 3 ].add(
+                    resolve(
+                        0,
+                        newDefer,
+                        isFunction( onRejected ) ?
+                            onRejected :
+                            Thrower
+                    )
+                );
+              } ).promise();
+            },
+
+            // Get a promise for this deferred
+            // If obj is provided, the promise aspect is added to the object
+            promise: function( obj ) {
+              return obj != null ? jQuery.extend( obj, promise ) : promise;
+            }
+          },
+          deferred = {};
+
+      // Add list-specific methods
+      jQuery.each( tuples, function( i, tuple ) {
+        var list = tuple[ 2 ],
+            stateString = tuple[ 5 ];
+
+        // promise.progress = list.add
+        // promise.done = list.add
+        // promise.fail = list.add
+        promise[ tuple[ 1 ] ] = list.add;
+
+        // Handle state
+        if ( stateString ) {
+          list.add(
+              function() {
+
+                // state = "resolved" (i.e., fulfilled)
+                // state = "rejected"
+                state = stateString;
+              },
+
+              // rejected_callbacks.disable
+              // fulfilled_callbacks.disable
+              tuples[ 3 - i ][ 2 ].disable,
+
+              // rejected_handlers.disable
+              // fulfilled_handlers.disable
+              tuples[ 3 - i ][ 3 ].disable,
+
+              // progress_callbacks.lock
+              tuples[ 0 ][ 2 ].lock,
+
+              // progress_handlers.lock
+              tuples[ 0 ][ 3 ].lock
+          );
+        }
+
+        // progress_handlers.fire
+        // fulfilled_handlers.fire
+        // rejected_handlers.fire
+        list.add( tuple[ 3 ].fire );
+
+        // deferred.notify = function() { deferred.notifyWith(...) }
+        // deferred.resolve = function() { deferred.resolveWith(...) }
+        // deferred.reject = function() { deferred.rejectWith(...) }
+        deferred[ tuple[ 0 ] ] = function() {
+          deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
+          return this;
+        };
+
+        // deferred.notifyWith = list.fireWith
+        // deferred.resolveWith = list.fireWith
+        // deferred.rejectWith = list.fireWith
+        deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+      } );
+
+      // Make the deferred a promise
+      promise.promise( deferred );
+
+      // Call given func if any
+      if ( func ) {
+        func.call( deferred, deferred );
+      }
+
+      // All done!
+      return deferred;
+    },
+
+    // Deferred helper
+    when: function( singleValue ) {
+      var
+
+          // count of uncompleted subordinates
+          remaining = arguments.length,
+
+          // count of unprocessed arguments
+          i = remaining,
+
+          // subordinate fulfillment data
+          resolveContexts = Array( i ),
+          resolveValues = slice.call( arguments ),
+
+          // the master Deferred
+          master = jQuery.Deferred(),
+
+          // subordinate callback factory
+          updateFunc = function( i ) {
+            return function( value ) {
+              resolveContexts[ i ] = this;
+              resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+              if ( !( --remaining ) ) {
+                master.resolveWith( resolveContexts, resolveValues );
+              }
+            };
+          };
+
+      // Single- and empty arguments are adopted like Promise.resolve
+      if ( remaining <= 1 ) {
+        adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+            !remaining );
+
+        // Use .then() to unwrap secondary thenables (cf. gh-3000)
+        if ( master.state() === "pending" ||
+            isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+          return master.then();
+        }
+      }
+
+      // Multiple arguments are aggregated like Promise.all array elements
+      while ( i-- ) {
+        adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+      }
+
+      return master.promise();
+    }
+  } );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+  var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+  jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+    // Support: IE 8 - 9 only
+    // Console exists when dev tools are open, which can happen at any time
+    if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+      window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+    }
+  };
+
+
+
+
+  jQuery.readyException = function( error ) {
+    window.setTimeout( function() {
+      throw error;
+    } );
+  };
+
+
+
+
+// The deferred used on DOM ready
+  var readyList = jQuery.Deferred();
+
+  jQuery.fn.ready = function( fn ) {
+
+    readyList
+        .then( fn )
+
+        // Wrap jQuery.readyException in a function so that the lookup
+        // happens at the time of error handling instead of callback
+        // registration.
+        .catch( function( error ) {
+          jQuery.readyException( error );
+        } );
+
+    return this;
+  };
+
+  jQuery.extend( {
+
+    // Is the DOM ready to be used? Set to true once it occurs.
+    isReady: false,
+
+    // A counter to track how many items to wait for before
+    // the ready event fires. See #6781
+    readyWait: 1,
+
+    // Handle when the DOM is ready
+    ready: function( wait ) {
+
+      // Abort if there are pending holds or we're already ready
+      if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+        return;
+      }
+
+      // Remember that the DOM is ready
+      jQuery.isReady = true;
+
+      // If a normal DOM Ready event fired, decrement, and wait if need be
+      if ( wait !== true && --jQuery.readyWait > 0 ) {
+        return;
+      }
+
+      // If there are functions bound, to execute
+      readyList.resolveWith( document, [ jQuery ] );
+    }
+  } );
+
+  jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+  function completed() {
+    document.removeEventListener( "DOMContentLoaded", completed );
+    window.removeEventListener( "load", completed );
+    jQuery.ready();
+  }
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+  if ( document.readyState === "complete" ||
+      ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+    // Handle it asynchronously to allow scripts the opportunity to delay ready
+    window.setTimeout( jQuery.ready );
+
+  } else {
+
+    // Use the handy event callback
+    document.addEventListener( "DOMContentLoaded", completed );
+
+    // A fallback to window.onload, that will always work
+    window.addEventListener( "load", completed );
+  }
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+  var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+    var i = 0,
+        len = elems.length,
+        bulk = key == null;
+
+    // Sets many values
+    if ( toType( key ) === "object" ) {
+      chainable = true;
+      for ( i in key ) {
+        access( elems, fn, i, key[ i ], true, emptyGet, raw );
+      }
+
+      // Sets one value
+    } else if ( value !== undefined ) {
+      chainable = true;
+
+      if ( !isFunction( value ) ) {
+        raw = true;
+      }
+
+      if ( bulk ) {
+
+        // Bulk operations run against the entire set
+        if ( raw ) {
+          fn.call( elems, value );
+          fn = null;
+
+          // ...except when executing function values
+        } else {
+          bulk = fn;
+          fn = function( elem, key, value ) {
+            return bulk.call( jQuery( elem ), value );
+          };
+        }
+      }
+
+      if ( fn ) {
+        for ( ; i < len; i++ ) {
+          fn(
+              elems[ i ], key, raw ?
+                  value :
+                  value.call( elems[ i ], i, fn( elems[ i ], key ) )
+          );
+        }
+      }
+    }
+
+    if ( chainable ) {
+      return elems;
+    }
+
+    // Gets
+    if ( bulk ) {
+      return fn.call( elems );
+    }
+
+    return len ? fn( elems[ 0 ], key ) : emptyGet;
+  };
+
+
+// Matches dashed string for camelizing
+  var rmsPrefix = /^-ms-/,
+      rdashAlpha = /-([a-z])/g;
+
+// Used by camelCase as callback to replace()
+  function fcamelCase( all, letter ) {
+    return letter.toUpperCase();
+  }
+
+// Convert dashed to camelCase; used by the css and data modules
+// Support: IE <=9 - 11, Edge 12 - 15
+// Microsoft forgot to hump their vendor prefix (#9572)
+  function camelCase( string ) {
+    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+  }
+  var acceptData = function( owner ) {
+
+    // Accepts only:
+    //  - Node
+    //    - Node.ELEMENT_NODE
+    //    - Node.DOCUMENT_NODE
+    //  - Object
+    //    - Any
+    return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+  };
+
+
+
+
+  function Data() {
+    this.expando = jQuery.expando + Data.uid++;
+  }
+
+  Data.uid = 1;
+
+  Data.prototype = {
+
+    cache: function( owner ) {
+
+      // Check if the owner object already has a cache
+      var value = owner[ this.expando ];
+
+      // If not, create one
+      if ( !value ) {
+        value = {};
+
+        // We can accept data for non-element nodes in modern browsers,
+        // but we should not, see #8335.
+        // Always return an empty object.
+        if ( acceptData( owner ) ) {
+
+          // If it is a node unlikely to be stringify-ed or looped over
+          // use plain assignment
+          if ( owner.nodeType ) {
+            owner[ this.expando ] = value;
+
+            // Otherwise secure it in a non-enumerable property
+            // configurable must be true to allow the property to be
+            // deleted when data is removed
+          } else {
+            Object.defineProperty( owner, this.expando, {
+              value: value,
+              configurable: true
+            } );
+          }
+        }
+      }
+
+      return value;
+    },
+    set: function( owner, data, value ) {
+      var prop,
+          cache = this.cache( owner );
+
+      // Handle: [ owner, key, value ] args
+      // Always use camelCase key (gh-2257)
+      if ( typeof data === "string" ) {
+        cache[ camelCase( data ) ] = value;
+
+        // Handle: [ owner, { properties } ] args
+      } else {
+
+        // Copy the properties one-by-one to the cache object
+        for ( prop in data ) {
+          cache[ camelCase( prop ) ] = data[ prop ];
+        }
+      }
+      return cache;
+    },
+    get: function( owner, key ) {
+      return key === undefined ?
+          this.cache( owner ) :
+
+          // Always use camelCase key (gh-2257)
+          owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
+    },
+    access: function( owner, key, value ) {
+
+      // In cases where either:
+      //
+      //   1. No key was specified
+      //   2. A string key was specified, but no value provided
+      //
+      // Take the "read" path and allow the get method to determine
+      // which value to return, respectively either:
+      //
+      //   1. The entire cache object
+      //   2. The data stored at the key
+      //
+      if ( key === undefined ||
+          ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+        return this.get( owner, key );
+      }
+
+      // When the key is not a string, or both a key and value
+      // are specified, set or extend (existing objects) with either:
+      //
+      //   1. An object of properties
+      //   2. A key and value
+      //
+      this.set( owner, key, value );
+
+      // Since the "set" path can have two possible entry points
+      // return the expected data based on which path was taken[*]
+      return value !== undefined ? value : key;
+    },
+    remove: function( owner, key ) {
+      var i,
+          cache = owner[ this.expando ];
+
+      if ( cache === undefined ) {
+        return;
+      }
+
+      if ( key !== undefined ) {
+
+        // Support array or space separated string of keys
+        if ( Array.isArray( key ) ) {
+
+          // If key is an array of keys...
+          // We always set camelCase keys, so remove that.
+          key = key.map( camelCase );
+        } else {
+          key = camelCase( key );
+
+          // If a key with the spaces exists, use it.
+          // Otherwise, create an array by matching non-whitespace
+          key = key in cache ?
+              [ key ] :
+              ( key.match( rnothtmlwhite ) || [] );
+        }
+
+        i = key.length;
+
+        while ( i-- ) {
+          delete cache[ key[ i ] ];
+        }
+      }
+
+      // Remove the expando if there's no more data
+      if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+        // Support: Chrome <=35 - 45
+        // Webkit & Blink performance suffers when deleting properties
+        // from DOM nodes, so set to undefined instead
+        // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+        if ( owner.nodeType ) {
+          owner[ this.expando ] = undefined;
+        } else {
+          delete owner[ this.expando ];
+        }
+      }
+    },
+    hasData: function( owner ) {
+      var cache = owner[ this.expando ];
+      return cache !== undefined && !jQuery.isEmptyObject( cache );
+    }
+  };
+  var dataPriv = new Data();
+
+  var dataUser = new Data();
+
+
+
+//	Implementation Summary
+//
+//	1. Enforce API surface and semantic compatibility with 1.9.x branch
+//	2. Improve the module's maintainability by reducing the storage
+//		paths to a single mechanism.
+//	3. Use the same single mechanism to support "private" and "user" data.
+//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+//	5. Avoid exposing implementation details on user objects (eg. expando properties)
+//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+  var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+      rmultiDash = /[A-Z]/g;
+
+  function getData( data ) {
+    if ( data === "true" ) {
+      return true;
+    }
+
+    if ( data === "false" ) {
+      return false;
+    }
+
+    if ( data === "null" ) {
+      return null;
+    }
+
+    // Only convert to a number if it doesn't change the string
+    if ( data === +data + "" ) {
+      return +data;
+    }
+
+    if ( rbrace.test( data ) ) {
+      return JSON.parse( data );
+    }
+
+    return data;
+  }
+
+  function dataAttr( elem, key, data ) {
+    var name;
+
+    // If nothing was found internally, try to fetch any
+    // data from the HTML5 data-* attribute
+    if ( data === undefined && elem.nodeType === 1 ) {
+      name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+      data = elem.getAttribute( name );
+
+      if ( typeof data === "string" ) {
+        try {
+          data = getData( data );
+        } catch ( e ) {}
+
+        // Make sure we set the data so it isn't changed later
+        dataUser.set( elem, key, data );
+      } else {
+        data = undefined;
+      }
+    }
+    return data;
+  }
+
+  jQuery.extend( {
+    hasData: function( elem ) {
+      return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+    },
+
+    data: function( elem, name, data ) {
+      return dataUser.access( elem, name, data );
+    },
+
+    removeData: function( elem, name ) {
+      dataUser.remove( elem, name );
+    },
+
+    // TODO: Now that all calls to _data and _removeData have been replaced
+    // with direct calls to dataPriv methods, these can be deprecated.
+    _data: function( elem, name, data ) {
+      return dataPriv.access( elem, name, data );
+    },
+
+    _removeData: function( elem, name ) {
+      dataPriv.remove( elem, name );
+    }
+  } );
+
+  jQuery.fn.extend( {
+    data: function( key, value ) {
+      var i, name, data,
+          elem = this[ 0 ],
+          attrs = elem && elem.attributes;
+
+      // Gets all values
+      if ( key === undefined ) {
+        if ( this.length ) {
+          data = dataUser.get( elem );
+
+          if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+            i = attrs.length;
+            while ( i-- ) {
+
+              // Support: IE 11 only
+              // The attrs elements can be null (#14894)
+              if ( attrs[ i ] ) {
+                name = attrs[ i ].name;
+                if ( name.indexOf( "data-" ) === 0 ) {
+                  name = camelCase( name.slice( 5 ) );
+                  dataAttr( elem, name, data[ name ] );
+                }
+              }
+            }
+            dataPriv.set( elem, "hasDataAttrs", true );
+          }
+        }
+
+        return data;
+      }
+
+      // Sets multiple values
+      if ( typeof key === "object" ) {
+        return this.each( function() {
+          dataUser.set( this, key );
+        } );
+      }
+
+      return access( this, function( value ) {
+        var data;
+
+        // The calling jQuery object (element matches) is not empty
+        // (and therefore has an element appears at this[ 0 ]) and the
+        // `value` parameter was not undefined. An empty jQuery object
+        // will result in `undefined` for elem = this[ 0 ] which will
+        // throw an exception if an attempt to read a data cache is made.
+        if ( elem && value === undefined ) {
+
+          // Attempt to get data from the cache
+          // The key will always be camelCased in Data
+          data = dataUser.get( elem, key );
+          if ( data !== undefined ) {
+            return data;
+          }
+
+          // Attempt to "discover" the data in
+          // HTML5 custom data-* attrs
+          data = dataAttr( elem, key );
+          if ( data !== undefined ) {
+            return data;
+          }
+
+          // We tried really hard, but the data doesn't exist.
+          return;
+        }
+
+        // Set the data...
+        this.each( function() {
+
+          // We always store the camelCased key
+          dataUser.set( this, key, value );
+        } );
+      }, null, value, arguments.length > 1, null, true );
+    },
+
+    removeData: function( key ) {
+      return this.each( function() {
+        dataUser.remove( this, key );
+      } );
+    }
+  } );
+
+
+  jQuery.extend( {
+    queue: function( elem, type, data ) {
+      var queue;
+
+      if ( elem ) {
+        type = ( type || "fx" ) + "queue";
+        queue = dataPriv.get( elem, type );
+
+        // Speed up dequeue by getting out quickly if this is just a lookup
+        if ( data ) {
+          if ( !queue || Array.isArray( data ) ) {
+            queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+          } else {
+            queue.push( data );
+          }
+        }
+        return queue || [];
+      }
+    },
+
+    dequeue: function( elem, type ) {
+      type = type || "fx";
+
+      var queue = jQuery.queue( elem, type ),
+          startLength = queue.length,
+          fn = queue.shift(),
+          hooks = jQuery._queueHooks( elem, type ),
+          next = function() {
+            jQuery.dequeue( elem, type );
+          };
+
+      // If the fx queue is dequeued, always remove the progress sentinel
+      if ( fn === "inprogress" ) {
+        fn = queue.shift();
+        startLength--;
+      }
+
+      if ( fn ) {
+
+        // Add a progress sentinel to prevent the fx queue from being
+        // automatically dequeued
+        if ( type === "fx" ) {
+          queue.unshift( "inprogress" );
+        }
+
+        // Clear up the last queue stop function
+        delete hooks.stop;
+        fn.call( elem, next, hooks );
+      }
+
+      if ( !startLength && hooks ) {
+        hooks.empty.fire();
+      }
+    },
+
+    // Not public - generate a queueHooks object, or return the current one
+    _queueHooks: function( elem, type ) {
+      var key = type + "queueHooks";
+      return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+        empty: jQuery.Callbacks( "once memory" ).add( function() {
+          dataPriv.remove( elem, [ type + "queue", key ] );
+        } )
+      } );
+    }
+  } );
+
+  jQuery.fn.extend( {
+    queue: function( type, data ) {
+      var setter = 2;
+
+      if ( typeof type !== "string" ) {
+        data = type;
+        type = "fx";
+        setter--;
+      }
+
+      if ( arguments.length < setter ) {
+        return jQuery.queue( this[ 0 ], type );
+      }
+
+      return data === undefined ?
+          this :
+          this.each( function() {
+            var queue = jQuery.queue( this, type, data );
+
+            // Ensure a hooks for this queue
+            jQuery._queueHooks( this, type );
+
+            if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+              jQuery.dequeue( this, type );
+            }
+          } );
+    },
+    dequeue: function( type ) {
+      return this.each( function() {
+        jQuery.dequeue( this, type );
+      } );
+    },
+    clearQueue: function( type ) {
+      return this.queue( type || "fx", [] );
+    },
+
+    // Get a promise resolved when queues of a certain type
+    // are emptied (fx is the type by default)
+    promise: function( type, obj ) {
+      var tmp,
+          count = 1,
+          defer = jQuery.Deferred(),
+          elements = this,
+          i = this.length,
+          resolve = function() {
+            if ( !( --count ) ) {
+              defer.resolveWith( elements, [ elements ] );
+            }
+          };
+
+      if ( typeof type !== "string" ) {
+        obj = type;
+        type = undefined;
+      }
+      type = type || "fx";
+
+      while ( i-- ) {
+        tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+        if ( tmp && tmp.empty ) {
+          count++;
+          tmp.empty.add( resolve );
+        }
+      }
+      resolve();
+      return defer.promise( obj );
+    }
+  } );
+  var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+  var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+  var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+  var isHiddenWithinTree = function( elem, el ) {
+
+    // isHiddenWithinTree might be called from jQuery#filter function;
+    // in that case, element will be second argument
+    elem = el || elem;
+
+    // Inline style trumps all
+    return elem.style.display === "none" ||
+        elem.style.display === "" &&
+
+        // Otherwise, check computed style
+        // Support: Firefox <=43 - 45
+        // Disconnected elements can have computed display: none, so first confirm that elem is
+        // in the document.
+        jQuery.contains( elem.ownerDocument, elem ) &&
+
+        jQuery.css( elem, "display" ) === "none";
+  };
+
+  var swap = function( elem, options, callback, args ) {
+    var ret, name,
+        old = {};
+
+    // Remember the old values, and insert the new ones
+    for ( name in options ) {
+      old[ name ] = elem.style[ name ];
+      elem.style[ name ] = options[ name ];
+    }
+
+    ret = callback.apply( elem, args || [] );
+
+    // Revert the old values
+    for ( name in options ) {
+      elem.style[ name ] = old[ name ];
+    }
+
+    return ret;
+  };
+
+
+
+
+  function adjustCSS( elem, prop, valueParts, tween ) {
+    var adjusted, scale,
+        maxIterations = 20,
+        currentValue = tween ?
+            function() {
+              return tween.cur();
+            } :
+            function() {
+              return jQuery.css( elem, prop, "" );
+            },
+        initial = currentValue(),
+        unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+        // Starting value computation is required for potential unit mismatches
+        initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+            rcssNum.exec( jQuery.css( elem, prop ) );
+
+    if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+      // Support: Firefox <=54
+      // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+      initial = initial / 2;
+
+      // Trust units reported by jQuery.css
+      unit = unit || initialInUnit[ 3 ];
+
+      // Iteratively approximate from a nonzero starting point
+      initialInUnit = +initial || 1;
+
+      while ( maxIterations-- ) {
+
+        // Evaluate and update our best guess (doubling guesses that zero out).
+        // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
+        jQuery.style( elem, prop, initialInUnit + unit );
+        if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
+          maxIterations = 0;
+        }
+        initialInUnit = initialInUnit / scale;
+
+      }
+
+      initialInUnit = initialInUnit * 2;
+      jQuery.style( elem, prop, initialInUnit + unit );
+
+      // Make sure we update the tween properties later on
+      valueParts = valueParts || [];
+    }
+
+    if ( valueParts ) {
+      initialInUnit = +initialInUnit || +initial || 0;
+
+      // Apply relative offset (+=/-=) if specified
+      adjusted = valueParts[ 1 ] ?
+          initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+          +valueParts[ 2 ];
+      if ( tween ) {
+        tween.unit = unit;
+        tween.start = initialInUnit;
+        tween.end = adjusted;
+      }
+    }
+    return adjusted;
+  }
+
+
+  var defaultDisplayMap = {};
+
+  function getDefaultDisplay( elem ) {
+    var temp,
+        doc = elem.ownerDocument,
+        nodeName = elem.nodeName,
+        display = defaultDisplayMap[ nodeName ];
+
+    if ( display ) {
+      return display;
+    }
+
+    temp = doc.body.appendChild( doc.createElement( nodeName ) );
+    display = jQuery.css( temp, "display" );
+
+    temp.parentNode.removeChild( temp );
+
+    if ( display === "none" ) {
+      display = "block";
+    }
+    defaultDisplayMap[ nodeName ] = display;
+
+    return display;
+  }
+
+  function showHide( elements, show ) {
+    var display, elem,
+        values = [],
+        index = 0,
+        length = elements.length;
+
+    // Determine new display value for elements that need to change
+    for ( ; index < length; index++ ) {
+      elem = elements[ index ];
+      if ( !elem.style ) {
+        continue;
+      }
+
+      display = elem.style.display;
+      if ( show ) {
+
+        // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+        // check is required in this first loop unless we have a nonempty display value (either
+        // inline or about-to-be-restored)
+        if ( display === "none" ) {
+          values[ index ] = dataPriv.get( elem, "display" ) || null;
+          if ( !values[ index ] ) {
+            elem.style.display = "";
+          }
+        }
+        if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+          values[ index ] = getDefaultDisplay( elem );
+        }
+      } else {
+        if ( display !== "none" ) {
+          values[ index ] = "none";
+
+          // Remember what we're overwriting
+          dataPriv.set( elem, "display", display );
+        }
+      }
+    }
+
+    // Set the display of the elements in a second loop to avoid constant reflow
+    for ( index = 0; index < length; index++ ) {
+      if ( values[ index ] != null ) {
+        elements[ index ].style.display = values[ index ];
+      }
+    }
+
+    return elements;
+  }
+
+  jQuery.fn.extend( {
+    show: function() {
+      return showHide( this, true );
+    },
+    hide: function() {
+      return showHide( this );
+    },
+    toggle: function( state ) {
+      if ( typeof state === "boolean" ) {
+        return state ? this.show() : this.hide();
+      }
+
+      return this.each( function() {
+        if ( isHiddenWithinTree( this ) ) {
+          jQuery( this ).show();
+        } else {
+          jQuery( this ).hide();
+        }
+      } );
+    }
+  } );
+  var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+  var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+  var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+  var wrapMap = {
+
+    // Support: IE <=9 only
+    option: [ 1, "<select multiple='multiple'>", "</select>" ],
+
+    // XHTML parsers do not magically insert elements in the
+    // same way that tag soup parsers do. So we cannot shorten
+    // this by omitting <tbody> or other required elements.
+    thead: [ 1, "<table>", "</table>" ],
+    col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
+    tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+    td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+    _default: [ 0, "", "" ]
+  };
+
+// Support: IE <=9 only
+  wrapMap.optgroup = wrapMap.option;
+
+  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+  wrapMap.th = wrapMap.td;
+
+
+  function getAll( context, tag ) {
+
+    // Support: IE <=9 - 11 only
+    // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+    var ret;
+
+    if ( typeof context.getElementsByTagName !== "undefined" ) {
+      ret = context.getElementsByTagName( tag || "*" );
+
+    } else if ( typeof context.querySelectorAll !== "undefined" ) {
+      ret = context.querySelectorAll( tag || "*" );
+
+    } else {
+      ret = [];
+    }
+
+    if ( tag === undefined || tag && nodeName( context, tag ) ) {
+      return jQuery.merge( [ context ], ret );
+    }
+
+    return ret;
+  }
+
+
+// Mark scripts as having already been evaluated
+  function setGlobalEval( elems, refElements ) {
+    var i = 0,
+        l = elems.length;
+
+    for ( ; i < l; i++ ) {
+      dataPriv.set(
+          elems[ i ],
+          "globalEval",
+          !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+      );
+    }
+  }
+
+
+  var rhtml = /<|&#?\w+;/;
+
+  function buildFragment( elems, context, scripts, selection, ignored ) {
+    var elem, tmp, tag, wrap, contains, j,
+        fragment = context.createDocumentFragment(),
+        nodes = [],
+        i = 0,
+        l = elems.length;
+
+    for ( ; i < l; i++ ) {
+      elem = elems[ i ];
+
+      if ( elem || elem === 0 ) {
+
+        // Add nodes directly
+        if ( toType( elem ) === "object" ) {
+
+          // Support: Android <=4.0 only, PhantomJS 1 only
+          // push.apply(_, arraylike) throws on ancient WebKit
+          jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+          // Convert non-html into a text node
+        } else if ( !rhtml.test( elem ) ) {
+          nodes.push( context.createTextNode( elem ) );
+
+          // Convert html into DOM nodes
+        } else {
+          tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+          // Deserialize a standard representation
+          tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+          wrap = wrapMap[ tag ] || wrapMap._default;
+          tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+          // Descend through wrappers to the right content
+          j = wrap[ 0 ];
+          while ( j-- ) {
+            tmp = tmp.lastChild;
+          }
+
+          // Support: Android <=4.0 only, PhantomJS 1 only
+          // push.apply(_, arraylike) throws on ancient WebKit
+          jQuery.merge( nodes, tmp.childNodes );
+
+          // Remember the top-level container
+          tmp = fragment.firstChild;
+
+          // Ensure the created nodes are orphaned (#12392)
+          tmp.textContent = "";
+        }
+      }
+    }
+
+    // Remove wrapper from fragment
+    fragment.textContent = "";
+
+    i = 0;
+    while ( ( elem = nodes[ i++ ] ) ) {
+
+      // Skip elements already in the context collection (trac-4087)
+      if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+        if ( ignored ) {
+          ignored.push( elem );
+        }
+        continue;
+      }
+
+      contains = jQuery.contains( elem.ownerDocument, elem );
+
+      // Append to fragment
+      tmp = getAll( fragment.appendChild( elem ), "script" );
+
+      // Preserve script evaluation history
+      if ( contains ) {
+        setGlobalEval( tmp );
+      }
+
+      // Capture executables
+      if ( scripts ) {
+        j = 0;
+        while ( ( elem = tmp[ j++ ] ) ) {
+          if ( rscriptType.test( elem.type || "" ) ) {
+            scripts.push( elem );
+          }
+        }
+      }
+    }
+
+    return fragment;
+  }
+
+
+  ( function() {
+    var fragment = document.createDocumentFragment(),
+        div = fragment.appendChild( document.createElement( "div" ) ),
+        input = document.createElement( "input" );
+
+    // Support: Android 4.0 - 4.3 only
+    // Check state lost if the name is set (#11217)
+    // Support: Windows Web Apps (WWA)
+    // `name` and `type` must use .setAttribute for WWA (#14901)
+    input.setAttribute( "type", "radio" );
+    input.setAttribute( "checked", "checked" );
+    input.setAttribute( "name", "t" );
+
+    div.appendChild( input );
+
+    // Support: Android <=4.1 only
+    // Older WebKit doesn't clone checked state correctly in fragments
+    support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+    // Support: IE <=11 only
+    // Make sure textarea (and checkbox) defaultValue is properly cloned
+    div.innerHTML = "<textarea>x</textarea>";
+    support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+  } )();
+  var documentElement = document.documentElement;
+
+
+
+  var
+      rkeyEvent = /^key/,
+      rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+      rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+  function returnTrue() {
+    return true;
+  }
+
+  function returnFalse() {
+    return false;
+  }
+
+// Support: IE <=9 only
+// See #13393 for more info
+  function safeActiveElement() {
+    try {
+      return document.activeElement;
+    } catch ( err ) { }
+  }
+
+  function on( elem, types, selector, data, fn, one ) {
+    var origFn, type;
+
+    // Types can be a map of types/handlers
+    if ( typeof types === "object" ) {
+
+      // ( types-Object, selector, data )
+      if ( typeof selector !== "string" ) {
+
+        // ( types-Object, data )
+        data = data || selector;
+        selector = undefined;
+      }
+      for ( type in types ) {
+        on( elem, type, selector, data, types[ type ], one );
+      }
+      return elem;
+    }
+
+    if ( data == null && fn == null ) {
+
+      // ( types, fn )
+      fn = selector;
+      data = selector = undefined;
+    } else if ( fn == null ) {
+      if ( typeof selector === "string" ) {
+
+        // ( types, selector, fn )
+        fn = data;
+        data = undefined;
+      } else {
+
+        // ( types, data, fn )
+        fn = data;
+        data = selector;
+        selector = undefined;
+      }
+    }
+    if ( fn === false ) {
+      fn = returnFalse;
+    } else if ( !fn ) {
+      return elem;
+    }
+
+    if ( one === 1 ) {
+      origFn = fn;
+      fn = function( event ) {
+
+        // Can use an empty set, since event contains the info
+        jQuery().off( event );
+        return origFn.apply( this, arguments );
+      };
+
+      // Use same guid so caller can remove using origFn
+      fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+    }
+    return elem.each( function() {
+      jQuery.event.add( this, types, fn, data, selector );
+    } );
+  }
+
+  /*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+  jQuery.event = {
+
+    global: {},
+
+    add: function( elem, types, handler, data, selector ) {
+
+      var handleObjIn, eventHandle, tmp,
+          events, t, handleObj,
+          special, handlers, type, namespaces, origType,
+          elemData = dataPriv.get( elem );
+
+      // Don't attach events to noData or text/comment nodes (but allow plain objects)
+      if ( !elemData ) {
+        return;
+      }
+
+      // Caller can pass in an object of custom data in lieu of the handler
+      if ( handler.handler ) {
+        handleObjIn = handler;
+        handler = handleObjIn.handler;
+        selector = handleObjIn.selector;
+      }
+
+      // Ensure that invalid selectors throw exceptions at attach time
+      // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+      if ( selector ) {
+        jQuery.find.matchesSelector( documentElement, selector );
+      }
+
+      // Make sure that the handler has a unique ID, used to find/remove it later
+      if ( !handler.guid ) {
+        handler.guid = jQuery.guid++;
+      }
+
+      // Init the element's event structure and main handler, if this is the first
+      if ( !( events = elemData.events ) ) {
+        events = elemData.events = {};
+      }
+      if ( !( eventHandle = elemData.handle ) ) {
+        eventHandle = elemData.handle = function( e ) {
+
+          // Discard the second event of a jQuery.event.trigger() and
+          // when an event is called after a page has unloaded
+          return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+              jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+        };
+      }
+
+      // Handle multiple events separated by a space
+      types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+      t = types.length;
+      while ( t-- ) {
+        tmp = rtypenamespace.exec( types[ t ] ) || [];
+        type = origType = tmp[ 1 ];
+        namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+        // There *must* be a type, no attaching namespace-only handlers
+        if ( !type ) {
+          continue;
+        }
+
+        // If event changes its type, use the special event handlers for the changed type
+        special = jQuery.event.special[ type ] || {};
+
+        // If selector defined, determine special event api type, otherwise given type
+        type = ( selector ? special.delegateType : special.bindType ) || type;
+
+        // Update special based on newly reset type
+        special = jQuery.event.special[ type ] || {};
+
+        // handleObj is passed to all event handlers
+        handleObj = jQuery.extend( {
+          type: type,
+          origType: origType,
+          data: data,
+          handler: handler,
+          guid: handler.guid,
+          selector: selector,
+          needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+          namespace: namespaces.join( "." )
+        }, handleObjIn );
+
+        // Init the event handler queue if we're the first
+        if ( !( handlers = events[ type ] ) ) {
+          handlers = events[ type ] = [];
+          handlers.delegateCount = 0;
+
+          // Only use addEventListener if the special events handler returns false
+          if ( !special.setup ||
+              special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+            if ( elem.addEventListener ) {
+              elem.addEventListener( type, eventHandle );
+            }
+          }
+        }
+
+        if ( special.add ) {
+          special.add.call( elem, handleObj );
+
+          if ( !handleObj.handler.guid ) {
+            handleObj.handler.guid = handler.guid;
+          }
+        }
+
+        // Add to the element's handler list, delegates in front
+        if ( selector ) {
+          handlers.splice( handlers.delegateCount++, 0, handleObj );
+        } else {
+          handlers.push( handleObj );
+        }
+
+        // Keep track of which events have ever been used, for event optimization
+        jQuery.event.global[ type ] = true;
+      }
+
+    },
+
+    // Detach an event or set of events from an element
+    remove: function( elem, types, handler, selector, mappedTypes ) {
+
+      var j, origCount, tmp,
+          events, t, handleObj,
+          special, handlers, type, namespaces, origType,
+          elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+      if ( !elemData || !( events = elemData.events ) ) {
+        return;
+      }
+
+      // Once for each type.namespace in types; type may be omitted
+      types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+      t = types.length;
+      while ( t-- ) {
+        tmp = rtypenamespace.exec( types[ t ] ) || [];
+        type = origType = tmp[ 1 ];
+        namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+        // Unbind all events (on this namespace, if provided) for the element
+        if ( !type ) {
+          for ( type in events ) {
+            jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+          }
+          continue;
+        }
+
+        special = jQuery.event.special[ type ] || {};
+        type = ( selector ? special.delegateType : special.bindType ) || type;
+        handlers = events[ type ] || [];
+        tmp = tmp[ 2 ] &&
+            new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+        // Remove matching events
+        origCount = j = handlers.length;
+        while ( j-- ) {
+          handleObj = handlers[ j ];
+
+          if ( ( mappedTypes || origType === handleObj.origType ) &&
+              ( !handler || handler.guid === handleObj.guid ) &&
+              ( !tmp || tmp.test( handleObj.namespace ) ) &&
+              ( !selector || selector === handleObj.selector ||
+                  selector === "**" && handleObj.selector ) ) {
+            handlers.splice( j, 1 );
+
+            if ( handleObj.selector ) {
+              handlers.delegateCount--;
+            }
+            if ( special.remove ) {
+              special.remove.call( elem, handleObj );
+            }
+          }
+        }
+
+        // Remove generic event handler if we removed something and no more handlers exist
+        // (avoids potential for endless recursion during removal of special event handlers)
+        if ( origCount && !handlers.length ) {
+          if ( !special.teardown ||
+              special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+            jQuery.removeEvent( elem, type, elemData.handle );
+          }
+
+          delete events[ type ];
+        }
+      }
+
+      // Remove data and the expando if it's no longer used
+      if ( jQuery.isEmptyObject( events ) ) {
+        dataPriv.remove( elem, "handle events" );
+      }
+    },
+
+    dispatch: function( nativeEvent ) {
+
+      // Make a writable jQuery.Event from the native event object
+      var event = jQuery.event.fix( nativeEvent );
+
+      var i, j, ret, matched, handleObj, handlerQueue,
+          args = new Array( arguments.length ),
+          handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+          special = jQuery.event.special[ event.type ] || {};
+
+      // Use the fix-ed jQuery.Event rather than the (read-only) native event
+      args[ 0 ] = event;
+
+      for ( i = 1; i < arguments.length; i++ ) {
+        args[ i ] = arguments[ i ];
+      }
+
+      event.delegateTarget = this;
+
+      // Call the preDispatch hook for the mapped type, and let it bail if desired
+      if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+        return;
+      }
+
+      // Determine handlers
+      handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+      // Run delegates first; they may want to stop propagation beneath us
+      i = 0;
+      while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+        event.currentTarget = matched.elem;
+
+        j = 0;
+        while ( ( handleObj = matched.handlers[ j++ ] ) &&
+        !event.isImmediatePropagationStopped() ) {
+
+          // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+          // a subset or equal to those in the bound event (both can have no namespace).
+          if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+            event.handleObj = handleObj;
+            event.data = handleObj.data;
+
+            ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+                handleObj.handler ).apply( matched.elem, args );
+
+            if ( ret !== undefined ) {
+              if ( ( event.result = ret ) === false ) {
+                event.preventDefault();
+                event.stopPropagation();
+              }
+            }
+          }
+        }
+      }
+
+      // Call the postDispatch hook for the mapped type
+      if ( special.postDispatch ) {
+        special.postDispatch.call( this, event );
+      }
+
+      return event.result;
+    },
+
+    handlers: function( event, handlers ) {
+      var i, handleObj, sel, matchedHandlers, matchedSelectors,
+          handlerQueue = [],
+          delegateCount = handlers.delegateCount,
+          cur = event.target;
+
+      // Find delegate handlers
+      if ( delegateCount &&
+
+          // Support: IE <=9
+          // Black-hole SVG <use> instance trees (trac-13180)
+          cur.nodeType &&
+
+          // Support: Firefox <=42
+          // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+          // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+          // Support: IE 11 only
+          // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+          !( event.type === "click" && event.button >= 1 ) ) {
+
+        for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+          // Don't check non-elements (#13208)
+          // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+          if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+            matchedHandlers = [];
+            matchedSelectors = {};
+            for ( i = 0; i < delegateCount; i++ ) {
+              handleObj = handlers[ i ];
+
+              // Don't conflict with Object.prototype properties (#13203)
+              sel = handleObj.selector + " ";
+
+              if ( matchedSelectors[ sel ] === undefined ) {
+                matchedSelectors[ sel ] = handleObj.needsContext ?
+                    jQuery( sel, this ).index( cur ) > -1 :
+                    jQuery.find( sel, this, null, [ cur ] ).length;
+              }
+              if ( matchedSelectors[ sel ] ) {
+                matchedHandlers.push( handleObj );
+              }
+            }
+            if ( matchedHandlers.length ) {
+              handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+            }
+          }
+        }
+      }
+
+      // Add the remaining (directly-bound) handlers
+      cur = this;
+      if ( delegateCount < handlers.length ) {
+        handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+      }
+
+      return handlerQueue;
+    },
+
+    addProp: function( name, hook ) {
+      Object.defineProperty( jQuery.Event.prototype, name, {
+        enumerable: true,
+        configurable: true,
+
+        get: isFunction( hook ) ?
+            function() {
+              if ( this.originalEvent ) {
+                return hook( this.originalEvent );
+              }
+            } :
+            function() {
+              if ( this.originalEvent ) {
+                return this.originalEvent[ name ];
+              }
+            },
+
+        set: function( value ) {
+          Object.defineProperty( this, name, {
+            enumerable: true,
+            configurable: true,
+            writable: true,
+            value: value
+          } );
+        }
+      } );
+    },
+
+    fix: function( originalEvent ) {
+      return originalEvent[ jQuery.expando ] ?
+          originalEvent :
+          new jQuery.Event( originalEvent );
+    },
+
+    special: {
+      load: {
+
+        // Prevent triggered image.load events from bubbling to window.load
+        noBubble: true
+      },
+      focus: {
+
+        // Fire native event if possible so blur/focus sequence is correct
+        trigger: function() {
+          if ( this !== safeActiveElement() && this.focus ) {
+            this.focus();
+            return false;
+          }
+        },
+        delegateType: "focusin"
+      },
+      blur: {
+        trigger: function() {
+          if ( this === safeActiveElement() && this.blur ) {
+            this.blur();
+            return false;
+          }
+        },
+        delegateType: "focusout"
+      },
+      click: {
+
+        // For checkbox, fire native event so checked state will be right
+        trigger: function() {
+          if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+            this.click();
+            return false;
+          }
+        },
+
+        // For cross-browser consistency, don't fire native .click() on links
+        _default: function( event ) {
+          return nodeName( event.target, "a" );
+        }
+      },
+
+      beforeunload: {
+        postDispatch: function( event ) {
+
+          // Support: Firefox 20+
+          // Firefox doesn't alert if the returnValue field is not set.
+          if ( event.result !== undefined && event.originalEvent ) {
+            event.originalEvent.returnValue = event.result;
+          }
+        }
+      }
+    }
+  };
+
+  jQuery.removeEvent = function( elem, type, handle ) {
+
+    // This "if" is needed for plain objects
+    if ( elem.removeEventListener ) {
+      elem.removeEventListener( type, handle );
+    }
+  };
+
+  jQuery.Event = function( src, props ) {
+
+    // Allow instantiation without the 'new' keyword
+    if ( !( this instanceof jQuery.Event ) ) {
+      return new jQuery.Event( src, props );
+    }
+
+    // Event object
+    if ( src && src.type ) {
+      this.originalEvent = src;
+      this.type = src.type;
+
+      // Events bubbling up the document may have been marked as prevented
+      // by a handler lower down the tree; reflect the correct value.
+      this.isDefaultPrevented = src.defaultPrevented ||
+      src.defaultPrevented === undefined &&
+
+      // Support: Android <=2.3 only
+      src.returnValue === false ?
+          returnTrue :
+          returnFalse;
+
+      // Create target properties
+      // Support: Safari <=6 - 7 only
+      // Target should not be a text node (#504, #13143)
+      this.target = ( src.target && src.target.nodeType === 3 ) ?
+          src.target.parentNode :
+          src.target;
+
+      this.currentTarget = src.currentTarget;
+      this.relatedTarget = src.relatedTarget;
+
+      // Event type
+    } else {
+      this.type = src;
+    }
+
+    // Put explicitly provided properties onto the event object
+    if ( props ) {
+      jQuery.extend( this, props );
+    }
+
+    // Create a timestamp if incoming event doesn't have one
+    this.timeStamp = src && src.timeStamp || Date.now();
+
+    // Mark it as fixed
+    this[ jQuery.expando ] = true;
+  };
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+  jQuery.Event.prototype = {
+    constructor: jQuery.Event,
+    isDefaultPrevented: returnFalse,
+    isPropagationStopped: returnFalse,
+    isImmediatePropagationStopped: returnFalse,
+    isSimulated: false,
+
+    preventDefault: function() {
+      var e = this.originalEvent;
+
+      this.isDefaultPrevented = returnTrue;
+
+      if ( e && !this.isSimulated ) {
+        e.preventDefault();
+      }
+    },
+    stopPropagation: function() {
+      var e = this.originalEvent;
+
+      this.isPropagationStopped = returnTrue;
+
+      if ( e && !this.isSimulated ) {
+        e.stopPropagation();
+      }
+    },
+    stopImmediatePropagation: function() {
+      var e = this.originalEvent;
+
+      this.isImmediatePropagationStopped = returnTrue;
+
+      if ( e && !this.isSimulated ) {
+        e.stopImmediatePropagation();
+      }
+
+      this.stopPropagation();
+    }
+  };
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+  jQuery.each( {
+    altKey: true,
+    bubbles: true,
+    cancelable: true,
+    changedTouches: true,
+    ctrlKey: true,
+    detail: true,
+    eventPhase: true,
+    metaKey: true,
+    pageX: true,
+    pageY: true,
+    shiftKey: true,
+    view: true,
+    "char": true,
+    charCode: true,
+    key: true,
+    keyCode: true,
+    button: true,
+    buttons: true,
+    clientX: true,
+    clientY: true,
+    offsetX: true,
+    offsetY: true,
+    pointerId: true,
+    pointerType: true,
+    screenX: true,
+    screenY: true,
+    targetTouches: true,
+    toElement: true,
+    touches: true,
+
+    which: function( event ) {
+      var button = event.button;
+
+      // Add which for key events
+      if ( event.which == null && rkeyEvent.test( event.type ) ) {
+        return event.charCode != null ? event.charCode : event.keyCode;
+      }
+
+      // Add which for click: 1 === left; 2 === middle; 3 === right
+      if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+        if ( button & 1 ) {
+          return 1;
+        }
+
+        if ( button & 2 ) {
+          return 3;
+        }
+
+        if ( button & 4 ) {
+          return 2;
+        }
+
+        return 0;
+      }
+
+      return event.which;
+    }
+  }, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+  jQuery.each( {
+    mouseenter: "mouseover",
+    mouseleave: "mouseout",
+    pointerenter: "pointerover",
+    pointerleave: "pointerout"
+  }, function( orig, fix ) {
+    jQuery.event.special[ orig ] = {
+      delegateType: fix,
+      bindType: fix,
+
+      handle: function( event ) {
+        var ret,
+            target = this,
+            related = event.relatedTarget,
+            handleObj = event.handleObj;
+
+        // For mouseenter/leave call the handler if related is outside the target.
+        // NB: No relatedTarget if the mouse left/entered the browser window
+        if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+          event.type = handleObj.origType;
+          ret = handleObj.handler.apply( this, arguments );
+          event.type = fix;
+        }
+        return ret;
+      }
+    };
+  } );
+
+  jQuery.fn.extend( {
+
+    on: function( types, selector, data, fn ) {
+      return on( this, types, selector, data, fn );
+    },
+    one: function( types, selector, data, fn ) {
+      return on( this, types, selector, data, fn, 1 );
+    },
+    off: function( types, selector, fn ) {
+      var handleObj, type;
+      if ( types && types.preventDefault && types.handleObj ) {
+
+        // ( event )  dispatched jQuery.Event
+        handleObj = types.handleObj;
+        jQuery( types.delegateTarget ).off(
+            handleObj.namespace ?
+                handleObj.origType + "." + handleObj.namespace :
+                handleObj.origType,
+            handleObj.selector,
+            handleObj.handler
+        );
+        return this;
+      }
+      if ( typeof types === "object" ) {
+
+        // ( types-object [, selector] )
+        for ( type in types ) {
+          this.off( type, selector, types[ type ] );
+        }
+        return this;
+      }
+      if ( selector === false || typeof selector === "function" ) {
+
+        // ( types [, fn] )
+        fn = selector;
+        selector = undefined;
+      }
+      if ( fn === false ) {
+        fn = returnFalse;
+      }
+      return this.each( function() {
+        jQuery.event.remove( this, types, fn, selector );
+      } );
+    }
+  } );
+
+
+  var
+
+      /* eslint-disable max-len */
+
+      // See https://github.com/eslint/eslint/issues/3229
+      rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+      /* eslint-enable */
+
+      // Support: IE <=10 - 11, Edge 12 - 13 only
+      // In IE/Edge using regex groups here causes severe slowdowns.
+      // See https://connect.microsoft.com/IE/feedback/details/1736512/
+      rnoInnerhtml = /<script|<style|<link/i,
+
+      // checked="checked" or checked
+      rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+      rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
+
+// Prefer a tbody over its parent table for containing new rows
+  function manipulationTarget( elem, content ) {
+    if ( nodeName( elem, "table" ) &&
+        nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
+
+      return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
+    }
+
+    return elem;
+  }
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+  function disableScript( elem ) {
+    elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
+    return elem;
+  }
+  function restoreScript( elem ) {
+    if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
+      elem.type = elem.type.slice( 5 );
+    } else {
+      elem.removeAttribute( "type" );
+    }
+
+    return elem;
+  }
+
+  function cloneCopyEvent( src, dest ) {
+    var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+    if ( dest.nodeType !== 1 ) {
+      return;
+    }
+
+    // 1. Copy private data: events, handlers, etc.
+    if ( dataPriv.hasData( src ) ) {
+      pdataOld = dataPriv.access( src );
+      pdataCur = dataPriv.set( dest, pdataOld );
+      events = pdataOld.events;
+
+      if ( events ) {
+        delete pdataCur.handle;
+        pdataCur.events = {};
+
+        for ( type in events ) {
+          for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+            jQuery.event.add( dest, type, events[ type ][ i ] );
+          }
+        }
+      }
+    }
+
+    // 2. Copy user data
+    if ( dataUser.hasData( src ) ) {
+      udataOld = dataUser.access( src );
+      udataCur = jQuery.extend( {}, udataOld );
+
+      dataUser.set( dest, udataCur );
+    }
+  }
+
+// Fix IE bugs, see support tests
+  function fixInput( src, dest ) {
+    var nodeName = dest.nodeName.toLowerCase();
+
+    // Fails to persist the checked state of a cloned checkbox or radio button.
+    if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+      dest.checked = src.checked;
+
+      // Fails to return the selected option to the default selected state when cloning options
+    } else if ( nodeName === "input" || nodeName === "textarea" ) {
+      dest.defaultValue = src.defaultValue;
+    }
+  }
+
+  function domManip( collection, args, callback, ignored ) {
+
+    // Flatten any nested arrays
+    args = concat.apply( [], args );
+
+    var fragment, first, scripts, hasScripts, node, doc,
+        i = 0,
+        l = collection.length,
+        iNoClone = l - 1,
+        value = args[ 0 ],
+        valueIsFunction = isFunction( value );
+
+    // We can't cloneNode fragments that contain checked, in WebKit
+    if ( valueIsFunction ||
+        ( l > 1 && typeof value === "string" &&
+            !support.checkClone && rchecked.test( value ) ) ) {
+      return collection.each( function( index ) {
+        var self = collection.eq( index );
+        if ( valueIsFunction ) {
+          args[ 0 ] = value.call( this, index, self.html() );
+        }
+        domManip( self, args, callback, ignored );
+      } );
+    }
+
+    if ( l ) {
+      fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
+      first = fragment.firstChild;
+
+      if ( fragment.childNodes.length === 1 ) {
+        fragment = first;
+      }
+
+      // Require either new content or an interest in ignored elements to invoke the callback
+      if ( first || ignored ) {
+        scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+        hasScripts = scripts.length;
+
+        // Use the original fragment for the last item
+        // instead of the first because it can end up
+        // being emptied incorrectly in certain situations (#8070).
+        for ( ; i < l; i++ ) {
+          node = fragment;
+
+          if ( i !== iNoClone ) {
+            node = jQuery.clone( node, true, true );
+
+            // Keep references to cloned scripts for later restoration
+            if ( hasScripts ) {
+
+              // Support: Android <=4.0 only, PhantomJS 1 only
+              // push.apply(_, arraylike) throws on ancient WebKit
+              jQuery.merge( scripts, getAll( node, "script" ) );
+            }
+          }
+
+          callback.call( collection[ i ], node, i );
+        }
+
+        if ( hasScripts ) {
+          doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+          // Reenable scripts
+          jQuery.map( scripts, restoreScript );
+
+          // Evaluate executable scripts on first document insertion
+          for ( i = 0; i < hasScripts; i++ ) {
+            node = scripts[ i ];
+            if ( rscriptType.test( node.type || "" ) &&
+                !dataPriv.access( node, "globalEval" ) &&
+                jQuery.contains( doc, node ) ) {
+
+              if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
+
+                // Optional AJAX dependency, but won't run scripts if not present
+                if ( jQuery._evalUrl ) {
+                  jQuery._evalUrl( node.src );
+                }
+              } else {
+                DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node );
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return collection;
+  }
+
+  function remove( elem, selector, keepData ) {
+    var node,
+        nodes = selector ? jQuery.filter( selector, elem ) : elem,
+        i = 0;
+
+    for ( ; ( node = nodes[ i ] ) != null; i++ ) {
+      if ( !keepData && node.nodeType === 1 ) {
+        jQuery.cleanData( getAll( node ) );
+      }
+
+      if ( node.parentNode ) {
+        if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
+          setGlobalEval( getAll( node, "script" ) );
+        }
+        node.parentNode.removeChild( node );
+      }
+    }
+
+    return elem;
+  }
+
+  jQuery.extend( {
+    htmlPrefilter: function( html ) {
+      return html.replace( rxhtmlTag, "<$1></$2>" );
+    },
+
+    clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+      var i, l, srcElements, destElements,
+          clone = elem.cloneNode( true ),
+          inPage = jQuery.contains( elem.ownerDocument, elem );
+
+      // Fix IE cloning issues
+      if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
+          !jQuery.isXMLDoc( elem ) ) {
+
+        // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
+        destElements = getAll( clone );
+        srcElements = getAll( elem );
+
+        for ( i = 0, l = srcElements.length; i < l; i++ ) {
+          fixInput( srcElements[ i ], destElements[ i ] );
+        }
+      }
+
+      // Copy the events from the original to the clone
+      if ( dataAndEvents ) {
+        if ( deepDataAndEvents ) {
+          srcElements = srcElements || getAll( elem );
+          destElements = destElements || getAll( clone );
+
+          for ( i = 0, l = srcElements.length; i < l; i++ ) {
+            cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+          }
+        } else {
+          cloneCopyEvent( elem, clone );
+        }
+      }
+
+      // Preserve script evaluation history
+      destElements = getAll( clone, "script" );
+      if ( destElements.length > 0 ) {
+        setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+      }
+
+      // Return the cloned set
+      return clone;
+    },
+
+    cleanData: function( elems ) {
+      var data, elem, type,
+          special = jQuery.event.special,
+          i = 0;
+
+      for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
+        if ( acceptData( elem ) ) {
+          if ( ( data = elem[ dataPriv.expando ] ) ) {
+            if ( data.events ) {
+              for ( type in data.events ) {
+                if ( special[ type ] ) {
+                  jQuery.event.remove( elem, type );
+
+                  // This is a shortcut to avoid jQuery.event.remove's overhead
+                } else {
+                  jQuery.removeEvent( elem, type, data.handle );
+                }
+              }
+            }
+
+            // Support: Chrome <=35 - 45+
+            // Assign undefined instead of using delete, see Data#remove
+            elem[ dataPriv.expando ] = undefined;
+          }
+          if ( elem[ dataUser.expando ] ) {
+
+            // Support: Chrome <=35 - 45+
+            // Assign undefined instead of using delete, see Data#remove
+            elem[ dataUser.expando ] = undefined;
+          }
+        }
+      }
+    }
+  } );
+
+  jQuery.fn.extend( {
+    detach: function( selector ) {
+      return remove( this, selector, true );
+    },
+
+    remove: function( selector ) {
+      return remove( this, selector );
+    },
+
+    text: function( value ) {
+      return access( this, function( value ) {
+        return value === undefined ?
+            jQuery.text( this ) :
+            this.empty().each( function() {
+              if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                this.textContent = value;
+              }
+            } );
+      }, null, value, arguments.length );
+    },
+
+    append: function() {
+      return domManip( this, arguments, function( elem ) {
+        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+          var target = manipulationTarget( this, elem );
+          target.appendChild( elem );
+        }
+      } );
+    },
+
+    prepend: function() {
+      return domManip( this, arguments, function( elem ) {
+        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+          var target = manipulationTarget( this, elem );
+          target.insertBefore( elem, target.firstChild );
+        }
+      } );
+    },
+
+    before: function() {
+      return domManip( this, arguments, function( elem ) {
+        if ( this.parentNode ) {
+          this.parentNode.insertBefore( elem, this );
+        }
+      } );
+    },
+
+    after: function() {
+      return domManip( this, arguments, function( elem ) {
+        if ( this.parentNode ) {
+          this.parentNode.insertBefore( elem, this.nextSibling );
+        }
+      } );
+    },
+
+    empty: function() {
+      var elem,
+          i = 0;
+
+      for ( ; ( elem = this[ i ] ) != null; i++ ) {
+        if ( elem.nodeType === 1 ) {
+
+          // Prevent memory leaks
+          jQuery.cleanData( getAll( elem, false ) );
+
+          // Remove any remaining nodes
+          elem.textContent = "";
+        }
+      }
+
+      return this;
+    },
+
+    clone: function( dataAndEvents, deepDataAndEvents ) {
+      dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+      deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+      return this.map( function() {
+        return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+      } );
+    },
+
+    html: function( value ) {
+      return access( this, function( value ) {
+        var elem = this[ 0 ] || {},
+            i = 0,
+            l = this.length;
+
+        if ( value === undefined && elem.nodeType === 1 ) {
+          return elem.innerHTML;
+        }
+
+        // See if we can take a shortcut and just use innerHTML
+        if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+            !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+
+          value = jQuery.htmlPrefilter( value );
+
+          try {
+            for ( ; i < l; i++ ) {
+              elem = this[ i ] || {};
+
+              // Remove element nodes and prevent memory leaks
+              if ( elem.nodeType === 1 ) {
+                jQuery.cleanData( getAll( elem, false ) );
+                elem.innerHTML = value;
+              }
+            }
+
+            elem = 0;
+
+            // If using innerHTML throws an exception, use the fallback method
+          } catch ( e ) {}
+        }
+
+        if ( elem ) {
+          this.empty().append( value );
+        }
+      }, null, value, arguments.length );
+    },
+
+    replaceWith: function() {
+      var ignored = [];
+
+      // Make the changes, replacing each non-ignored context element with the new content
+      return domManip( this, arguments, function( elem ) {
+        var parent = this.parentNode;
+
+        if ( jQuery.inArray( this, ignored ) < 0 ) {
+          jQuery.cleanData( getAll( this ) );
+          if ( parent ) {
+            parent.replaceChild( elem, this );
+          }
+        }
+
+        // Force callback invocation
+      }, ignored );
+    }
+  } );
+
+  jQuery.each( {
+    appendTo: "append",
+    prependTo: "prepend",
+    insertBefore: "before",
+    insertAfter: "after",
+    replaceAll: "replaceWith"
+  }, function( name, original ) {
+    jQuery.fn[ name ] = function( selector ) {
+      var elems,
+          ret = [],
+          insert = jQuery( selector ),
+          last = insert.length - 1,
+          i = 0;
+
+      for ( ; i <= last; i++ ) {
+        elems = i === last ? this : this.clone( true );
+        jQuery( insert[ i ] )[ original ]( elems );
+
+        // Support: Android <=4.0 only, PhantomJS 1 only
+        // .get() because push.apply(_, arraylike) throws on ancient WebKit
+        push.apply( ret, elems.get() );
+      }
+
+      return this.pushStack( ret );
+    };
+  } );
+  var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+  var getStyles = function( elem ) {
+
+    // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
+    // IE throws on elements created in popups
+    // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+    var view = elem.ownerDocument.defaultView;
+
+    if ( !view || !view.opener ) {
+      view = window;
+    }
+
+    return view.getComputedStyle( elem );
+  };
+
+  var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
+
+
+
+  ( function() {
+
+    // Executing both pixelPosition & boxSizingReliable tests require only one layout
+    // so they're executed at the same time to save the second computation.
+    function computeStyleTests() {
+
+      // This is a singleton, we need to execute it only once
+      if ( !div ) {
+        return;
+      }
+
+      container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
+          "margin-top:1px;padding:0;border:0";
+      div.style.cssText =
+          "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
+          "margin:auto;border:1px;padding:1px;" +
+          "width:60%;top:1%";
+      documentElement.appendChild( container ).appendChild( div );
+
+      var divStyle = window.getComputedStyle( div );
+      pixelPositionVal = divStyle.top !== "1%";
+
+      // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
+      reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
+
+      // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
+      // Some styles come back with percentage values, even though they shouldn't
+      div.style.right = "60%";
+      pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
+
+      // Support: IE 9 - 11 only
+      // Detect misreporting of content dimensions for box-sizing:border-box elements
+      boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
+
+      // Support: IE 9 only
+      // Detect overflow:scroll screwiness (gh-3699)
+      div.style.position = "absolute";
+      scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
+
+      documentElement.removeChild( container );
+
+      // Nullify the div so it wouldn't be stored in the memory and
+      // it will also be a sign that checks already performed
+      div = null;
+    }
+
+    function roundPixelMeasures( measure ) {
+      return Math.round( parseFloat( measure ) );
+    }
+
+    var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
+        reliableMarginLeftVal,
+        container = document.createElement( "div" ),
+        div = document.createElement( "div" );
+
+    // Finish early in limited (non-browser) environments
+    if ( !div.style ) {
+      return;
+    }
+
+    // Support: IE <=9 - 11 only
+    // Style of cloned element affects source element cloned (#8908)
+    div.style.backgroundClip = "content-box";
+    div.cloneNode( true ).style.backgroundClip = "";
+    support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+    jQuery.extend( support, {
+      boxSizingReliable: function() {
+        computeStyleTests();
+        return boxSizingReliableVal;
+      },
+      pixelBoxStyles: function() {
+        computeStyleTests();
+        return pixelBoxStylesVal;
+      },
+      pixelPosition: function() {
+        computeStyleTests();
+        return pixelPositionVal;
+      },
+      reliableMarginLeft: function() {
+        computeStyleTests();
+        return reliableMarginLeftVal;
+      },
+      scrollboxSize: function() {
+        computeStyleTests();
+        return scrollboxSizeVal;
+      }
+    } );
+  } )();
+
+
+  function curCSS( elem, name, computed ) {
+    var width, minWidth, maxWidth, ret,
+
+        // Support: Firefox 51+
+        // Retrieving style before computed somehow
+        // fixes an issue with getting wrong values
+        // on detached elements
+        style = elem.style;
+
+    computed = computed || getStyles( elem );
+
+    // getPropertyValue is needed for:
+    //   .css('filter') (IE 9 only, #12537)
+    //   .css('--customProperty) (#3144)
+    if ( computed ) {
+      ret = computed.getPropertyValue( name ) || computed[ name ];
+
+      if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+        ret = jQuery.style( elem, name );
+      }
+
+      // A tribute to the "awesome hack by Dean Edwards"
+      // Android Browser returns percentage for some values,
+      // but width seems to be reliably pixels.
+      // This is against the CSSOM draft spec:
+      // https://drafts.csswg.org/cssom/#resolved-values
+      if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
+
+        // Remember the original values
+        width = style.width;
+        minWidth = style.minWidth;
+        maxWidth = style.maxWidth;
+
+        // Put in the new values to get a computed value out
+        style.minWidth = style.maxWidth = style.width = ret;
+        ret = computed.width;
+
+        // Revert the changed values
+        style.width = width;
+        style.minWidth = minWidth;
+        style.maxWidth = maxWidth;
+      }
+    }
+
+    return ret !== undefined ?
+
+        // Support: IE <=9 - 11 only
+        // IE returns zIndex value as an integer.
+        ret + "" :
+        ret;
+  }
+
+
+  function addGetHookIf( conditionFn, hookFn ) {
+
+    // Define the hook, we'll check on the first run if it's really needed.
+    return {
+      get: function() {
+        if ( conditionFn() ) {
+
+          // Hook not needed (or it's not possible to use it due
+          // to missing dependency), remove it.
+          delete this.get;
+          return;
+        }
+
+        // Hook needed; redefine it so that the support test is not executed again.
+        return ( this.get = hookFn ).apply( this, arguments );
+      }
+    };
+  }
+
+
+  var
+
+      // Swappable if display is none or starts with table
+      // except "table", "table-cell", or "table-caption"
+      // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+      rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+      rcustomProp = /^--/,
+      cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+      cssNormalTransform = {
+        letterSpacing: "0",
+        fontWeight: "400"
+      },
+
+      cssPrefixes = [ "Webkit", "Moz", "ms" ],
+      emptyStyle = document.createElement( "div" ).style;
+
+// Return a css property mapped to a potentially vendor prefixed property
+  function vendorPropName( name ) {
+
+    // Shortcut for names that are not vendor prefixed
+    if ( name in emptyStyle ) {
+      return name;
+    }
+
+    // Check for vendor prefixed names
+    var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
+        i = cssPrefixes.length;
+
+    while ( i-- ) {
+      name = cssPrefixes[ i ] + capName;
+      if ( name in emptyStyle ) {
+        return name;
+      }
+    }
+  }
+
+// Return a property mapped along what jQuery.cssProps suggests or to
+// a vendor prefixed property.
+  function finalPropName( name ) {
+    var ret = jQuery.cssProps[ name ];
+    if ( !ret ) {
+      ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
+    }
+    return ret;
+  }
+
+  function setPositiveNumber( elem, value, subtract ) {
+
+    // Any relative (+/-) values have already been
+    // normalized at this point
+    var matches = rcssNum.exec( value );
+    return matches ?
+
+        // Guard against undefined "subtract", e.g., when used as in cssHooks
+        Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
+        value;
+  }
+
+  function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
+    var i = dimension === "width" ? 1 : 0,
+        extra = 0,
+        delta = 0;
+
+    // Adjustment may not be necessary
+    if ( box === ( isBorderBox ? "border" : "content" ) ) {
+      return 0;
+    }
+
+    for ( ; i < 4; i += 2 ) {
+
+      // Both box models exclude margin
+      if ( box === "margin" ) {
+        delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
+      }
+
+      // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
+      if ( !isBorderBox ) {
+
+        // Add padding
+        delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+        // For "border" or "margin", add border
+        if ( box !== "padding" ) {
+          delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+
+          // But still keep track of it otherwise
+        } else {
+          extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+        }
+
+        // If we get here with a border-box (content + padding + border), we're seeking "content" or
+        // "padding" or "margin"
+      } else {
+
+        // For "content", subtract padding
+        if ( box === "content" ) {
+          delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+        }
+
+        // For "content" or "padding", subtract border
+        if ( box !== "margin" ) {
+          delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+        }
+      }
+    }
+
+    // Account for positive content-box scroll gutter when requested by providing computedVal
+    if ( !isBorderBox && computedVal >= 0 ) {
+
+      // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
+      // Assuming integer scroll gutter, subtract the rest and round down
+      delta += Math.max( 0, Math.ceil(
+          elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+          computedVal -
+          delta -
+          extra -
+          0.5
+      ) );
+    }
+
+    return delta;
+  }
+
+  function getWidthOrHeight( elem, dimension, extra ) {
+
+    // Start with computed style
+    var styles = getStyles( elem ),
+        val = curCSS( elem, dimension, styles ),
+        isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+        valueIsBorderBox = isBorderBox;
+
+    // Support: Firefox <=54
+    // Return a confounding non-pixel value or feign ignorance, as appropriate.
+    if ( rnumnonpx.test( val ) ) {
+      if ( !extra ) {
+        return val;
+      }
+      val = "auto";
+    }
+
+    // Check for style in case a browser which returns unreliable values
+    // for getComputedStyle silently falls back to the reliable elem.style
+    valueIsBorderBox = valueIsBorderBox &&
+        ( support.boxSizingReliable() || val === elem.style[ dimension ] );
+
+    // Fall back to offsetWidth/offsetHeight when value is "auto"
+    // This happens for inline elements with no explicit setting (gh-3571)
+    // Support: Android <=4.1 - 4.3 only
+    // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
+    if ( val === "auto" ||
+        !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) {
+
+      val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
+
+      // offsetWidth/offsetHeight provide border-box values
+      valueIsBorderBox = true;
+    }
+
+    // Normalize "" and auto
+    val = parseFloat( val ) || 0;
+
+    // Adjust for the element's box model
+    return ( val +
+        boxModelAdjustment(
+            elem,
+            dimension,
+            extra || ( isBorderBox ? "border" : "content" ),
+            valueIsBorderBox,
+            styles,
+
+            // Provide the current computed size to request scroll gutter calculation (gh-3589)
+            val
+        )
+    ) + "px";
+  }
+
+  jQuery.extend( {
+
+    // Add in style property hooks for overriding the default
+    // behavior of getting and setting a style property
+    cssHooks: {
+      opacity: {
+        get: function( elem, computed ) {
+          if ( computed ) {
+
+            // We should always get a number back from opacity
+            var ret = curCSS( elem, "opacity" );
+            return ret === "" ? "1" : ret;
+          }
+        }
+      }
+    },
+
+    // Don't automatically add "px" to these possibly-unitless properties
+    cssNumber: {
+      "animationIterationCount": true,
+      "columnCount": true,
+      "fillOpacity": true,
+      "flexGrow": true,
+      "flexShrink": true,
+      "fontWeight": true,
+      "lineHeight": true,
+      "opacity": true,
+      "order": true,
+      "orphans": true,
+      "widows": true,
+      "zIndex": true,
+      "zoom": true
+    },
+
+    // Add in properties whose names you wish to fix before
+    // setting or getting the value
+    cssProps: {},
+
+    // Get and set the style property on a DOM Node
+    style: function( elem, name, value, extra ) {
+
+      // Don't set styles on text and comment nodes
+      if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+        return;
+      }
+
+      // Make sure that we're working with the right name
+      var ret, type, hooks,
+          origName = camelCase( name ),
+          isCustomProp = rcustomProp.test( name ),
+          style = elem.style;
+
+      // Make sure that we're working with the right name. We don't
+      // want to query the value if it is a CSS custom property
+      // since they are user-defined.
+      if ( !isCustomProp ) {
+        name = finalPropName( origName );
+      }
+
+      // Gets hook for the prefixed version, then unprefixed version
+      hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+      // Check if we're setting a value
+      if ( value !== undefined ) {
+        type = typeof value;
+
+        // Convert "+=" or "-=" to relative numbers (#7345)
+        if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
+          value = adjustCSS( elem, name, ret );
+
+          // Fixes bug #9237
+          type = "number";
+        }
+
+        // Make sure that null and NaN values aren't set (#7116)
+        if ( value == null || value !== value ) {
+          return;
+        }
+
+        // If a number was passed in, add the unit (except for certain CSS properties)
+        if ( type === "number" ) {
+          value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
+        }
+
+        // background-* props affect original clone's values
+        if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
+          style[ name ] = "inherit";
+        }
+
+        // If a hook was provided, use that value, otherwise just set the specified value
+        if ( !hooks || !( "set" in hooks ) ||
+            ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
+
+          if ( isCustomProp ) {
+            style.setProperty( name, value );
+          } else {
+            style[ name ] = value;
+          }
+        }
+
+      } else {
+
+        // If a hook was provided get the non-computed value from there
+        if ( hooks && "get" in hooks &&
+            ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
+
+          return ret;
+        }
+
+        // Otherwise just get the value from the style object
+        return style[ name ];
+      }
+    },
+
+    css: function( elem, name, extra, styles ) {
+      var val, num, hooks,
+          origName = camelCase( name ),
+          isCustomProp = rcustomProp.test( name );
+
+      // Make sure that we're working with the right name. We don't
+      // want to modify the value if it is a CSS custom property
+      // since they are user-defined.
+      if ( !isCustomProp ) {
+        name = finalPropName( origName );
+      }
+
+      // Try prefixed name followed by the unprefixed name
+      hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+      // If a hook was provided get the computed value from there
+      if ( hooks && "get" in hooks ) {
+        val = hooks.get( elem, true, extra );
+      }
+
+      // Otherwise, if a way to get the computed value exists, use that
+      if ( val === undefined ) {
+        val = curCSS( elem, name, styles );
+      }
+
+      // Convert "normal" to computed value
+      if ( val === "normal" && name in cssNormalTransform ) {
+        val = cssNormalTransform[ name ];
+      }
+
+      // Make numeric if forced or a qualifier was provided and val looks numeric
+      if ( extra === "" || extra ) {
+        num = parseFloat( val );
+        return extra === true || isFinite( num ) ? num || 0 : val;
+      }
+
+      return val;
+    }
+  } );
+
+  jQuery.each( [ "height", "width" ], function( i, dimension ) {
+    jQuery.cssHooks[ dimension ] = {
+      get: function( elem, computed, extra ) {
+        if ( computed ) {
+
+          // Certain elements can have dimension info if we invisibly show them
+          // but it must have a current display style that would benefit
+          return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
+
+          // Support: Safari 8+
+          // Table columns in Safari have non-zero offsetWidth & zero
+          // getBoundingClientRect().width unless display is changed.
+          // Support: IE <=11 only
+          // Running getBoundingClientRect on a disconnected node
+          // in IE throws an error.
+          ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
+              swap( elem, cssShow, function() {
+                return getWidthOrHeight( elem, dimension, extra );
+              } ) :
+              getWidthOrHeight( elem, dimension, extra );
+        }
+      },
+
+      set: function( elem, value, extra ) {
+        var matches,
+            styles = getStyles( elem ),
+            isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+            subtract = extra && boxModelAdjustment(
+                elem,
+                dimension,
+                extra,
+                isBorderBox,
+                styles
+            );
+
+        // Account for unreliable border-box dimensions by comparing offset* to computed and
+        // faking a content-box to get border and padding (gh-3699)
+        if ( isBorderBox && support.scrollboxSize() === styles.position ) {
+          subtract -= Math.ceil(
+              elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+              parseFloat( styles[ dimension ] ) -
+              boxModelAdjustment( elem, dimension, "border", false, styles ) -
+              0.5
+          );
+        }
+
+        // Convert to pixels if value adjustment is needed
+        if ( subtract && ( matches = rcssNum.exec( value ) ) &&
+            ( matches[ 3 ] || "px" ) !== "px" ) {
+
+          elem.style[ dimension ] = value;
+          value = jQuery.css( elem, dimension );
+        }
+
+        return setPositiveNumber( elem, value, subtract );
+      }
+    };
+  } );
+
+  jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
+      function( elem, computed ) {
+        if ( computed ) {
+          return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
+              elem.getBoundingClientRect().left -
+              swap( elem, { marginLeft: 0 }, function() {
+                return elem.getBoundingClientRect().left;
+              } )
+          ) + "px";
+        }
+      }
+  );
+
+// These hooks are used by animate to expand properties
+  jQuery.each( {
+    margin: "",
+    padding: "",
+    border: "Width"
+  }, function( prefix, suffix ) {
+    jQuery.cssHooks[ prefix + suffix ] = {
+      expand: function( value ) {
+        var i = 0,
+            expanded = {},
+
+            // Assumes a single number if not a string
+            parts = typeof value === "string" ? value.split( " " ) : [ value ];
+
+        for ( ; i < 4; i++ ) {
+          expanded[ prefix + cssExpand[ i ] + suffix ] =
+              parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+        }
+
+        return expanded;
+      }
+    };
+
+    if ( prefix !== "margin" ) {
+      jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+    }
+  } );
+
+  jQuery.fn.extend( {
+    css: function( name, value ) {
+      return access( this, function( elem, name, value ) {
+        var styles, len,
+            map = {},
+            i = 0;
+
+        if ( Array.isArray( name ) ) {
+          styles = getStyles( elem );
+          len = name.length;
+
+          for ( ; i < len; i++ ) {
+            map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+          }
+
+          return map;
+        }
+
+        return value !== undefined ?
+            jQuery.style( elem, name, value ) :
+            jQuery.css( elem, name );
+      }, name, value, arguments.length > 1 );
+    }
+  } );
+
+
+  function Tween( elem, options, prop, end, easing ) {
+    return new Tween.prototype.init( elem, options, prop, end, easing );
+  }
+  jQuery.Tween = Tween;
+
+  Tween.prototype = {
+    constructor: Tween,
+    init: function( elem, options, prop, end, easing, unit ) {
+      this.elem = elem;
+      this.prop = prop;
+      this.easing = easing || jQuery.easing._default;
+      this.options = options;
+      this.start = this.now = this.cur();
+      this.end = end;
+      this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+    },
+    cur: function() {
+      var hooks = Tween.propHooks[ this.prop ];
+
+      return hooks && hooks.get ?
+          hooks.get( this ) :
+          Tween.propHooks._default.get( this );
+    },
+    run: function( percent ) {
+      var eased,
+          hooks = Tween.propHooks[ this.prop ];
+
+      if ( this.options.duration ) {
+        this.pos = eased = jQuery.easing[ this.easing ](
+            percent, this.options.duration * percent, 0, 1, this.options.duration
+        );
+      } else {
+        this.pos = eased = percent;
+      }
+      this.now = ( this.end - this.start ) * eased + this.start;
+
+      if ( this.options.step ) {
+        this.options.step.call( this.elem, this.now, this );
+      }
+
+      if ( hooks && hooks.set ) {
+        hooks.set( this );
+      } else {
+        Tween.propHooks._default.set( this );
+      }
+      return this;
+    }
+  };
+
+  Tween.prototype.init.prototype = Tween.prototype;
+
+  Tween.propHooks = {
+    _default: {
+      get: function( tween ) {
+        var result;
+
+        // Use a property on the element directly when it is not a DOM element,
+        // or when there is no matching style property that exists.
+        if ( tween.elem.nodeType !== 1 ||
+            tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
+          return tween.elem[ tween.prop ];
+        }
+
+        // Passing an empty string as a 3rd parameter to .css will automatically
+        // attempt a parseFloat and fallback to a string if the parse fails.
+        // Simple values such as "10px" are parsed to Float;
+        // complex values such as "rotate(1rad)" are returned as-is.
+        result = jQuery.css( tween.elem, tween.prop, "" );
+
+        // Empty strings, null, undefined and "auto" are converted to 0.
+        return !result || result === "auto" ? 0 : result;
+      },
+      set: function( tween ) {
+
+        // Use step hook for back compat.
+        // Use cssHook if its there.
+        // Use .style if available and use plain properties where available.
+        if ( jQuery.fx.step[ tween.prop ] ) {
+          jQuery.fx.step[ tween.prop ]( tween );
+        } else if ( tween.elem.nodeType === 1 &&
+            ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
+                jQuery.cssHooks[ tween.prop ] ) ) {
+          jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+        } else {
+          tween.elem[ tween.prop ] = tween.now;
+        }
+      }
+    }
+  };
+
+// Support: IE <=9 only
+// Panic based approach to setting things on disconnected nodes
+  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+    set: function( tween ) {
+      if ( tween.elem.nodeType && tween.elem.parentNode ) {
+        tween.elem[ tween.prop ] = tween.now;
+      }
+    }
+  };
+
+  jQuery.easing = {
+    linear: function( p ) {
+      return p;
+    },
+    swing: function( p ) {
+      return 0.5 - Math.cos( p * Math.PI ) / 2;
+    },
+    _default: "swing"
+  };
+
+  jQuery.fx = Tween.prototype.init;
+
+// Back compat <1.8 extension point
+  jQuery.fx.step = {};
+
+
+
+
+  var
+      fxNow, inProgress,
+      rfxtypes = /^(?:toggle|show|hide)$/,
+      rrun = /queueHooks$/;
+
+  function schedule() {
+    if ( inProgress ) {
+      if ( document.hidden === false && window.requestAnimationFrame ) {
+        window.requestAnimationFrame( schedule );
+      } else {
+        window.setTimeout( schedule, jQuery.fx.interval );
+      }
+
+      jQuery.fx.tick();
+    }
+  }
+
+// Animations created synchronously will run synchronously
+  function createFxNow() {
+    window.setTimeout( function() {
+      fxNow = undefined;
+    } );
+    return ( fxNow = Date.now() );
+  }
+
+// Generate parameters to create a standard animation
+  function genFx( type, includeWidth ) {
+    var which,
+        i = 0,
+        attrs = { height: type };
+
+    // If we include width, step value is 1 to do all cssExpand values,
+    // otherwise step value is 2 to skip over Left and Right
+    includeWidth = includeWidth ? 1 : 0;
+    for ( ; i < 4; i += 2 - includeWidth ) {
+      which = cssExpand[ i ];
+      attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+    }
+
+    if ( includeWidth ) {
+      attrs.opacity = attrs.width = type;
+    }
+
+    return attrs;
+  }
+
+  function createTween( value, prop, animation ) {
+    var tween,
+        collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
+        index = 0,
+        length = collection.length;
+    for ( ; index < length; index++ ) {
+      if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
+
+        // We're done with this property
+        return tween;
+      }
+    }
+  }
+
+  function defaultPrefilter( elem, props, opts ) {
+    var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
+        isBox = "width" in props || "height" in props,
+        anim = this,
+        orig = {},
+        style = elem.style,
+        hidden = elem.nodeType && isHiddenWithinTree( elem ),
+        dataShow = dataPriv.get( elem, "fxshow" );
+
+    // Queue-skipping animations hijack the fx hooks
+    if ( !opts.queue ) {
+      hooks = jQuery._queueHooks( elem, "fx" );
+      if ( hooks.unqueued == null ) {
+        hooks.unqueued = 0;
+        oldfire = hooks.empty.fire;
+        hooks.empty.fire = function() {
+          if ( !hooks.unqueued ) {
+            oldfire();
+          }
+        };
+      }
+      hooks.unqueued++;
+
+      anim.always( function() {
+
+        // Ensure the complete handler is called before this completes
+        anim.always( function() {
+          hooks.unqueued--;
+          if ( !jQuery.queue( elem, "fx" ).length ) {
+            hooks.empty.fire();
+          }
+        } );
+      } );
+    }
+
+    // Detect show/hide animations
+    for ( prop in props ) {
+      value = props[ prop ];
+      if ( rfxtypes.test( value ) ) {
+        delete props[ prop ];
+        toggle = toggle || value === "toggle";
+        if ( value === ( hidden ? "hide" : "show" ) ) {
+
+          // Pretend to be hidden if this is a "show" and
+          // there is still data from a stopped show/hide
+          if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+            hidden = true;
+
+            // Ignore all other no-op show/hide data
+          } else {
+            continue;
+          }
+        }
+        orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+      }
+    }
+
+    // Bail out if this is a no-op like .hide().hide()
+    propTween = !jQuery.isEmptyObject( props );
+    if ( !propTween && jQuery.isEmptyObject( orig ) ) {
+      return;
+    }
+
+    // Restrict "overflow" and "display" styles during box animations
+    if ( isBox && elem.nodeType === 1 ) {
+
+      // Support: IE <=9 - 11, Edge 12 - 15
+      // Record all 3 overflow attributes because IE does not infer the shorthand
+      // from identically-valued overflowX and overflowY and Edge just mirrors
+      // the overflowX value there.
+      opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+      // Identify a display type, preferring old show/hide data over the CSS cascade
+      restoreDisplay = dataShow && dataShow.display;
+      if ( restoreDisplay == null ) {
+        restoreDisplay = dataPriv.get( elem, "display" );
+      }
+      display = jQuery.css( elem, "display" );
+      if ( display === "none" ) {
+        if ( restoreDisplay ) {
+          display = restoreDisplay;
+        } else {
+
+          // Get nonempty value(s) by temporarily forcing visibility
+          showHide( [ elem ], true );
+          restoreDisplay = elem.style.display || restoreDisplay;
+          display = jQuery.css( elem, "display" );
+          showHide( [ elem ] );
+        }
+      }
+
+      // Animate inline elements as inline-block
+      if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
+        if ( jQuery.css( elem, "float" ) === "none" ) {
+
+          // Restore the original display value at the end of pure show/hide animations
+          if ( !propTween ) {
+            anim.done( function() {
+              style.display = restoreDisplay;
+            } );
+            if ( restoreDisplay == null ) {
+              display = style.display;
+              restoreDisplay = display === "none" ? "" : display;
+            }
+          }
+          style.display = "inline-block";
+        }
+      }
+    }
+
+    if ( opts.overflow ) {
+      style.overflow = "hidden";
+      anim.always( function() {
+        style.overflow = opts.overflow[ 0 ];
+        style.overflowX = opts.overflow[ 1 ];
+        style.overflowY = opts.overflow[ 2 ];
+      } );
+    }
+
+    // Implement show/hide animations
+    propTween = false;
+    for ( prop in orig ) {
+
+      // General show/hide setup for this element animation
+      if ( !propTween ) {
+        if ( dataShow ) {
+          if ( "hidden" in dataShow ) {
+            hidden = dataShow.hidden;
+          }
+        } else {
+          dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
+        }
+
+        // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
+        if ( toggle ) {
+          dataShow.hidden = !hidden;
+        }
+
+        // Show elements before animating them
+        if ( hidden ) {
+          showHide( [ elem ], true );
+        }
+
+        /* eslint-disable no-loop-func */
+
+        anim.done( function() {
+
+          /* eslint-enable no-loop-func */
+
+          // The final step of a "hide" animation is actually hiding the element
+          if ( !hidden ) {
+            showHide( [ elem ] );
+          }
+          dataPriv.remove( elem, "fxshow" );
+          for ( prop in orig ) {
+            jQuery.style( elem, prop, orig[ prop ] );
+          }
+        } );
+      }
+
+      // Per-property setup
+      propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+      if ( !( prop in dataShow ) ) {
+        dataShow[ prop ] = propTween.start;
+        if ( hidden ) {
+          propTween.end = propTween.start;
+          propTween.start = 0;
+        }
+      }
+    }
+  }
+
+  function propFilter( props, specialEasing ) {
+    var index, name, easing, value, hooks;
+
+    // camelCase, specialEasing and expand cssHook pass
+    for ( index in props ) {
+      name = camelCase( index );
+      easing = specialEasing[ name ];
+      value = props[ index ];
+      if ( Array.isArray( value ) ) {
+        easing = value[ 1 ];
+        value = props[ index ] = value[ 0 ];
+      }
+
+      if ( index !== name ) {
+        props[ name ] = value;
+        delete props[ index ];
+      }
+
+      hooks = jQuery.cssHooks[ name ];
+      if ( hooks && "expand" in hooks ) {
+        value = hooks.expand( value );
+        delete props[ name ];
+
+        // Not quite $.extend, this won't overwrite existing keys.
+        // Reusing 'index' because we have the correct "name"
+        for ( index in value ) {
+          if ( !( index in props ) ) {
+            props[ index ] = value[ index ];
+            specialEasing[ index ] = easing;
+          }
+        }
+      } else {
+        specialEasing[ name ] = easing;
+      }
+    }
+  }
+
+  function Animation( elem, properties, options ) {
+    var result,
+        stopped,
+        index = 0,
+        length = Animation.prefilters.length,
+        deferred = jQuery.Deferred().always( function() {
+
+          // Don't match elem in the :animated selector
+          delete tick.elem;
+        } ),
+        tick = function() {
+          if ( stopped ) {
+            return false;
+          }
+          var currentTime = fxNow || createFxNow(),
+              remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+
+              // Support: Android 2.3 only
+              // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
+              temp = remaining / animation.duration || 0,
+              percent = 1 - temp,
+              index = 0,
+              length = animation.tweens.length;
+
+          for ( ; index < length; index++ ) {
+            animation.tweens[ index ].run( percent );
+          }
+
+          deferred.notifyWith( elem, [ animation, percent, remaining ] );
+
+          // If there's more to do, yield
+          if ( percent < 1 && length ) {
+            return remaining;
+          }
+
+          // If this was an empty animation, synthesize a final progress notification
+          if ( !length ) {
+            deferred.notifyWith( elem, [ animation, 1, 0 ] );
+          }
+
+          // Resolve the animation and report its conclusion
+          deferred.resolveWith( elem, [ animation ] );
+          return false;
+        },
+        animation = deferred.promise( {
+          elem: elem,
+          props: jQuery.extend( {}, properties ),
+          opts: jQuery.extend( true, {
+            specialEasing: {},
+            easing: jQuery.easing._default
+          }, options ),
+          originalProperties: properties,
+          originalOptions: options,
+          startTime: fxNow || createFxNow(),
+          duration: options.duration,
+          tweens: [],
+          createTween: function( prop, end ) {
+            var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                animation.opts.specialEasing[ prop ] || animation.opts.easing );
+            animation.tweens.push( tween );
+            return tween;
+          },
+          stop: function( gotoEnd ) {
+            var index = 0,
+
+                // If we are going to the end, we want to run all the tweens
+                // otherwise we skip this part
+                length = gotoEnd ? animation.tweens.length : 0;
+            if ( stopped ) {
+              return this;
+            }
+            stopped = true;
+            for ( ; index < length; index++ ) {
+              animation.tweens[ index ].run( 1 );
+            }
+
+            // Resolve when we played the last frame; otherwise, reject
+            if ( gotoEnd ) {
+              deferred.notifyWith( elem, [ animation, 1, 0 ] );
+              deferred.resolveWith( elem, [ animation, gotoEnd ] );
+            } else {
+              deferred.rejectWith( elem, [ animation, gotoEnd ] );
+            }
+            return this;
+          }
+        } ),
+        props = animation.props;
+
+    propFilter( props, animation.opts.specialEasing );
+
+    for ( ; index < length; index++ ) {
+      result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
+      if ( result ) {
+        if ( isFunction( result.stop ) ) {
+          jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
+              result.stop.bind( result );
+        }
+        return result;
+      }
+    }
+
+    jQuery.map( props, createTween, animation );
+
+    if ( isFunction( animation.opts.start ) ) {
+      animation.opts.start.call( elem, animation );
+    }
+
+    // Attach callbacks from options
+    animation
+        .progress( animation.opts.progress )
+        .done( animation.opts.done, animation.opts.complete )
+        .fail( animation.opts.fail )
+        .always( animation.opts.always );
+
+    jQuery.fx.timer(
+        jQuery.extend( tick, {
+          elem: elem,
+          anim: animation,
+          queue: animation.opts.queue
+        } )
+    );
+
+    return animation;
+  }
+
+  jQuery.Animation = jQuery.extend( Animation, {
+
+    tweeners: {
+      "*": [ function( prop, value ) {
+        var tween = this.createTween( prop, value );
+        adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
+        return tween;
+      } ]
+    },
+
+    tweener: function( props, callback ) {
+      if ( isFunction( props ) ) {
+        callback = props;
+        props = [ "*" ];
+      } else {
+        props = props.match( rnothtmlwhite );
+      }
+
+      var prop,
+          index = 0,
+          length = props.length;
+
+      for ( ; index < length; index++ ) {
+        prop = props[ index ];
+        Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
+        Animation.tweeners[ prop ].unshift( callback );
+      }
+    },
+
+    prefilters: [ defaultPrefilter ],
+
+    prefilter: function( callback, prepend ) {
+      if ( prepend ) {
+        Animation.prefilters.unshift( callback );
+      } else {
+        Animation.prefilters.push( callback );
+      }
+    }
+  } );
+
+  jQuery.speed = function( speed, easing, fn ) {
+    var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+      complete: fn || !fn && easing ||
+          isFunction( speed ) && speed,
+      duration: speed,
+      easing: fn && easing || easing && !isFunction( easing ) && easing
+    };
+
+    // Go to the end state if fx are off
+    if ( jQuery.fx.off ) {
+      opt.duration = 0;
+
+    } else {
+      if ( typeof opt.duration !== "number" ) {
+        if ( opt.duration in jQuery.fx.speeds ) {
+          opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+        } else {
+          opt.duration = jQuery.fx.speeds._default;
+        }
+      }
+    }
+
+    // Normalize opt.queue - true/undefined/null -> "fx"
+    if ( opt.queue == null || opt.queue === true ) {
+      opt.queue = "fx";
+    }
+
+    // Queueing
+    opt.old = opt.complete;
+
+    opt.complete = function() {
+      if ( isFunction( opt.old ) ) {
+        opt.old.call( this );
+      }
+
+      if ( opt.queue ) {
+        jQuery.dequeue( this, opt.queue );
+      }
+    };
+
+    return opt;
+  };
+
+  jQuery.fn.extend( {
+    fadeTo: function( speed, to, easing, callback ) {
+
+      // Show any hidden elements after setting opacity to 0
+      return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
+
+      // Animate to the value specified
+          .end().animate( { opacity: to }, speed, easing, callback );
+    },
+    animate: function( prop, speed, easing, callback ) {
+      var empty = jQuery.isEmptyObject( prop ),
+          optall = jQuery.speed( speed, easing, callback ),
+          doAnimation = function() {
+
+            // Operate on a copy of prop so per-property easing won't be lost
+            var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+            // Empty animations, or finishing resolves immediately
+            if ( empty || dataPriv.get( this, "finish" ) ) {
+              anim.stop( true );
+            }
+          };
+      doAnimation.finish = doAnimation;
+
+      return empty || optall.queue === false ?
+          this.each( doAnimation ) :
+          this.queue( optall.queue, doAnimation );
+    },
+    stop: function( type, clearQueue, gotoEnd ) {
+      var stopQueue = function( hooks ) {
+        var stop = hooks.stop;
+        delete hooks.stop;
+        stop( gotoEnd );
+      };
+
+      if ( typeof type !== "string" ) {
+        gotoEnd = clearQueue;
+        clearQueue = type;
+        type = undefined;
+      }
+      if ( clearQueue && type !== false ) {
+        this.queue( type || "fx", [] );
+      }
+
+      return this.each( function() {
+        var dequeue = true,
+            index = type != null && type + "queueHooks",
+            timers = jQuery.timers,
+            data = dataPriv.get( this );
+
+        if ( index ) {
+          if ( data[ index ] && data[ index ].stop ) {
+            stopQueue( data[ index ] );
+          }
+        } else {
+          for ( index in data ) {
+            if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+              stopQueue( data[ index ] );
+            }
+          }
+        }
+
+        for ( index = timers.length; index--; ) {
+          if ( timers[ index ].elem === this &&
+              ( type == null || timers[ index ].queue === type ) ) {
+
+            timers[ index ].anim.stop( gotoEnd );
+            dequeue = false;
+            timers.splice( index, 1 );
+          }
+        }
+
+        // Start the next in the queue if the last step wasn't forced.
+        // Timers currently will call their complete callbacks, which
+        // will dequeue but only if they were gotoEnd.
+        if ( dequeue || !gotoEnd ) {
+          jQuery.dequeue( this, type );
+        }
+      } );
+    },
+    finish: function( type ) {
+      if ( type !== false ) {
+        type = type || "fx";
+      }
+      return this.each( function() {
+        var index,
+            data = dataPriv.get( this ),
+            queue = data[ type + "queue" ],
+            hooks = data[ type + "queueHooks" ],
+            timers = jQuery.timers,
+            length = queue ? queue.length : 0;
+
+        // Enable finishing flag on private data
+        data.finish = true;
+
+        // Empty the queue first
+        jQuery.queue( this, type, [] );
+
+        if ( hooks && hooks.stop ) {
+          hooks.stop.call( this, true );
+        }
+
+        // Look for any active animations, and finish them
+        for ( index = timers.length; index--; ) {
+          if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+            timers[ index ].anim.stop( true );
+            timers.splice( index, 1 );
+          }
+        }
+
+        // Look for any animations in the old queue and finish them
+        for ( index = 0; index < length; index++ ) {
+          if ( queue[ index ] && queue[ index ].finish ) {
+            queue[ index ].finish.call( this );
+          }
+        }
+
+        // Turn off finishing flag
+        delete data.finish;
+      } );
+    }
+  } );
+
+  jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
+    var cssFn = jQuery.fn[ name ];
+    jQuery.fn[ name ] = function( speed, easing, callback ) {
+      return speed == null || typeof speed === "boolean" ?
+          cssFn.apply( this, arguments ) :
+          this.animate( genFx( name, true ), speed, easing, callback );
+    };
+  } );
+
+// Generate shortcuts for custom animations
+  jQuery.each( {
+    slideDown: genFx( "show" ),
+    slideUp: genFx( "hide" ),
+    slideToggle: genFx( "toggle" ),
+    fadeIn: { opacity: "show" },
+    fadeOut: { opacity: "hide" },
+    fadeToggle: { opacity: "toggle" }
+  }, function( name, props ) {
+    jQuery.fn[ name ] = function( speed, easing, callback ) {
+      return this.animate( props, speed, easing, callback );
+    };
+  } );
+
+  jQuery.timers = [];
+  jQuery.fx.tick = function() {
+    var timer,
+        i = 0,
+        timers = jQuery.timers;
+
+    fxNow = Date.now();
+
+    for ( ; i < timers.length; i++ ) {
+      timer = timers[ i ];
+
+      // Run the timer and safely remove it when done (allowing for external removal)
+      if ( !timer() && timers[ i ] === timer ) {
+        timers.splice( i--, 1 );
+      }
+    }
+
+    if ( !timers.length ) {
+      jQuery.fx.stop();
+    }
+    fxNow = undefined;
+  };
+
+  jQuery.fx.timer = function( timer ) {
+    jQuery.timers.push( timer );
+    jQuery.fx.start();
+  };
+
+  jQuery.fx.interval = 13;
+  jQuery.fx.start = function() {
+    if ( inProgress ) {
+      return;
+    }
+
+    inProgress = true;
+    schedule();
+  };
+
+  jQuery.fx.stop = function() {
+    inProgress = null;
+  };
+
+  jQuery.fx.speeds = {
+    slow: 600,
+    fast: 200,
+
+    // Default speed
+    _default: 400
+  };
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+  jQuery.fn.delay = function( time, type ) {
+    time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+    type = type || "fx";
+
+    return this.queue( type, function( next, hooks ) {
+      var timeout = window.setTimeout( next, time );
+      hooks.stop = function() {
+        window.clearTimeout( timeout );
+      };
+    } );
+  };
+
+
+  ( function() {
+    var input = document.createElement( "input" ),
+        select = document.createElement( "select" ),
+        opt = select.appendChild( document.createElement( "option" ) );
+
+    input.type = "checkbox";
+
+    // Support: Android <=4.3 only
+    // Default value for a checkbox should be "on"
+    support.checkOn = input.value !== "";
+
+    // Support: IE <=11 only
+    // Must access selectedIndex to make default options select
+    support.optSelected = opt.selected;
+
+    // Support: IE <=11 only
+    // An input loses its value after becoming a radio
+    input = document.createElement( "input" );
+    input.value = "t";
+    input.type = "radio";
+    support.radioValue = input.value === "t";
+  } )();
+
+
+  var boolHook,
+      attrHandle = jQuery.expr.attrHandle;
+
+  jQuery.fn.extend( {
+    attr: function( name, value ) {
+      return access( this, jQuery.attr, name, value, arguments.length > 1 );
+    },
+
+    removeAttr: function( name ) {
+      return this.each( function() {
+        jQuery.removeAttr( this, name );
+      } );
+    }
+  } );
+
+  jQuery.extend( {
+    attr: function( elem, name, value ) {
+      var ret, hooks,
+          nType = elem.nodeType;
+
+      // Don't get/set attributes on text, comment and attribute nodes
+      if ( nType === 3 || nType === 8 || nType === 2 ) {
+        return;
+      }
+
+      // Fallback to prop when attributes are not supported
+      if ( typeof elem.getAttribute === "undefined" ) {
+        return jQuery.prop( elem, name, value );
+      }
+
+      // Attribute hooks are determined by the lowercase version
+      // Grab necessary hook if one is defined
+      if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+        hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
+            ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
+      }
+
+      if ( value !== undefined ) {
+        if ( value === null ) {
+          jQuery.removeAttr( elem, name );
+          return;
+        }
+
+        if ( hooks && "set" in hooks &&
+            ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+          return ret;
+        }
+
+        elem.setAttribute( name, value + "" );
+        return value;
+      }
+
+      if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+        return ret;
+      }
+
+      ret = jQuery.find.attr( elem, name );
+
+      // Non-existent attributes return null, we normalize to undefined
+      return ret == null ? undefined : ret;
+    },
+
+    attrHooks: {
+      type: {
+        set: function( elem, value ) {
+          if ( !support.radioValue && value === "radio" &&
+              nodeName( elem, "input" ) ) {
+            var val = elem.value;
+            elem.setAttribute( "type", value );
+            if ( val ) {
+              elem.value = val;
+            }
+            return value;
+          }
+        }
+      }
+    },
+
+    removeAttr: function( elem, value ) {
+      var name,
+          i = 0,
+
+          // Attribute names can contain non-HTML whitespace characters
+          // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+          attrNames = value && value.match( rnothtmlwhite );
+
+      if ( attrNames && elem.nodeType === 1 ) {
+        while ( ( name = attrNames[ i++ ] ) ) {
+          elem.removeAttribute( name );
+        }
+      }
+    }
+  } );
+
+// Hooks for boolean attributes
+  boolHook = {
+    set: function( elem, value, name ) {
+      if ( value === false ) {
+
+        // Remove boolean attributes when set to false
+        jQuery.removeAttr( elem, name );
+      } else {
+        elem.setAttribute( name, name );
+      }
+      return name;
+    }
+  };
+
+  jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+    var getter = attrHandle[ name ] || jQuery.find.attr;
+
+    attrHandle[ name ] = function( elem, name, isXML ) {
+      var ret, handle,
+          lowercaseName = name.toLowerCase();
+
+      if ( !isXML ) {
+
+        // Avoid an infinite loop by temporarily removing this function from the getter
+        handle = attrHandle[ lowercaseName ];
+        attrHandle[ lowercaseName ] = ret;
+        ret = getter( elem, name, isXML ) != null ?
+            lowercaseName :
+            null;
+        attrHandle[ lowercaseName ] = handle;
+      }
+      return ret;
+    };
+  } );
+
+
+
+
+  var rfocusable = /^(?:input|select|textarea|button)$/i,
+      rclickable = /^(?:a|area)$/i;
+
+  jQuery.fn.extend( {
+    prop: function( name, value ) {
+      return access( this, jQuery.prop, name, value, arguments.length > 1 );
+    },
+
+    removeProp: function( name ) {
+      return this.each( function() {
+        delete this[ jQuery.propFix[ name ] || name ];
+      } );
+    }
+  } );
+
+  jQuery.extend( {
+    prop: function( elem, name, value ) {
+      var ret, hooks,
+          nType = elem.nodeType;
+
+      // Don't get/set properties on text, comment and attribute nodes
+      if ( nType === 3 || nType === 8 || nType === 2 ) {
+        return;
+      }
+
+      if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+
+        // Fix name and attach hooks
+        name = jQuery.propFix[ name ] || name;
+        hooks = jQuery.propHooks[ name ];
+      }
+
+      if ( value !== undefined ) {
+        if ( hooks && "set" in hooks &&
+            ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+          return ret;
+        }
+
+        return ( elem[ name ] = value );
+      }
+
+      if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+        return ret;
+      }
+
+      return elem[ name ];
+    },
+
+    propHooks: {
+      tabIndex: {
+        get: function( elem ) {
+
+          // Support: IE <=9 - 11 only
+          // elem.tabIndex doesn't always return the
+          // correct value when it hasn't been explicitly set
+          // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+          // Use proper attribute retrieval(#12072)
+          var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+          if ( tabindex ) {
+            return parseInt( tabindex, 10 );
+          }
+
+          if (
+              rfocusable.test( elem.nodeName ) ||
+              rclickable.test( elem.nodeName ) &&
+              elem.href
+          ) {
+            return 0;
+          }
+
+          return -1;
+        }
+      }
+    },
+
+    propFix: {
+      "for": "htmlFor",
+      "class": "className"
+    }
+  } );
+
+// Support: IE <=11 only
+// Accessing the selectedIndex property
+// forces the browser to respect setting selected
+// on the option
+// The getter ensures a default option is selected
+// when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
+  if ( !support.optSelected ) {
+    jQuery.propHooks.selected = {
+      get: function( elem ) {
+
+        /* eslint no-unused-expressions: "off" */
+
+        var parent = elem.parentNode;
+        if ( parent && parent.parentNode ) {
+          parent.parentNode.selectedIndex;
+        }
+        return null;
+      },
+      set: function( elem ) {
+
+        /* eslint no-unused-expressions: "off" */
+
+        var parent = elem.parentNode;
+        if ( parent ) {
+          parent.selectedIndex;
+
+          if ( parent.parentNode ) {
+            parent.parentNode.selectedIndex;
+          }
+        }
+      }
+    };
+  }
+
+  jQuery.each( [
+    "tabIndex",
+    "readOnly",
+    "maxLength",
+    "cellSpacing",
+    "cellPadding",
+    "rowSpan",
+    "colSpan",
+    "useMap",
+    "frameBorder",
+    "contentEditable"
+  ], function() {
+    jQuery.propFix[ this.toLowerCase() ] = this;
+  } );
+
+
+
+
+  // Strip and collapse whitespace according to HTML spec
+  // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
+  function stripAndCollapse( value ) {
+    var tokens = value.match( rnothtmlwhite ) || [];
+    return tokens.join( " " );
+  }
+
+
+  function getClass( elem ) {
+    return elem.getAttribute && elem.getAttribute( "class" ) || "";
+  }
+
+  function classesToArray( value ) {
+    if ( Array.isArray( value ) ) {
+      return value;
+    }
+    if ( typeof value === "string" ) {
+      return value.match( rnothtmlwhite ) || [];
+    }
+    return [];
+  }
+
+  jQuery.fn.extend( {
+    addClass: function( value ) {
+      var classes, elem, cur, curValue, clazz, j, finalValue,
+          i = 0;
+
+      if ( isFunction( value ) ) {
+        return this.each( function( j ) {
+          jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+        } );
+      }
+
+      classes = classesToArray( value );
+
+      if ( classes.length ) {
+        while ( ( elem = this[ i++ ] ) ) {
+          curValue = getClass( elem );
+          cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+          if ( cur ) {
+            j = 0;
+            while ( ( clazz = classes[ j++ ] ) ) {
+              if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+                cur += clazz + " ";
+              }
+            }
+
+            // Only assign if different to avoid unneeded rendering.
+            finalValue = stripAndCollapse( cur );
+            if ( curValue !== finalValue ) {
+              elem.setAttribute( "class", finalValue );
+            }
+          }
+        }
+      }
+
+      return this;
+    },
+
+    removeClass: function( value ) {
+      var classes, elem, cur, curValue, clazz, j, finalValue,
+          i = 0;
+
+      if ( isFunction( value ) ) {
+        return this.each( function( j ) {
+          jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+        } );
+      }
+
+      if ( !arguments.length ) {
+        return this.attr( "class", "" );
+      }
+
+      classes = classesToArray( value );
+
+      if ( classes.length ) {
+        while ( ( elem = this[ i++ ] ) ) {
+          curValue = getClass( elem );
+
+          // This expression is here for better compressibility (see addClass)
+          cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+          if ( cur ) {
+            j = 0;
+            while ( ( clazz = classes[ j++ ] ) ) {
+
+              // Remove *all* instances
+              while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
+                cur = cur.replace( " " + clazz + " ", " " );
+              }
+            }
+
+            // Only assign if different to avoid unneeded rendering.
+            finalValue = stripAndCollapse( cur );
+            if ( curValue !== finalValue ) {
+              elem.setAttribute( "class", finalValue );
+            }
+          }
+        }
+      }
+
+      return this;
+    },
+
+    toggleClass: function( value, stateVal ) {
+      var type = typeof value,
+          isValidValue = type === "string" || Array.isArray( value );
+
+      if ( typeof stateVal === "boolean" && isValidValue ) {
+        return stateVal ? this.addClass( value ) : this.removeClass( value );
+      }
+
+      if ( isFunction( value ) ) {
+        return this.each( function( i ) {
+          jQuery( this ).toggleClass(
+              value.call( this, i, getClass( this ), stateVal ),
+              stateVal
+          );
+        } );
+      }
+
+      return this.each( function() {
+        var className, i, self, classNames;
+
+        if ( isValidValue ) {
+
+          // Toggle individual class names
+          i = 0;
+          self = jQuery( this );
+          classNames = classesToArray( value );
+
+          while ( ( className = classNames[ i++ ] ) ) {
+
+            // Check each className given, space separated list
+            if ( self.hasClass( className ) ) {
+              self.removeClass( className );
+            } else {
+              self.addClass( className );
+            }
+          }
 
-	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
-	// Cloning options loses the selected state, so don't cache them
-	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
-	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
-	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
-		args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+          // Toggle whole class name
+        } else if ( value === undefined || type === "boolean" ) {
+          className = getClass( this );
+          if ( className ) {
 
-		cacheable = true;
+            // Store className if set
+            dataPriv.set( this, "__className__", className );
+          }
 
-		cacheresults = jQuery.fragments[ args[0] ];
-		if ( cacheresults && cacheresults !== 1 ) {
-			fragment = cacheresults;
-		}
-	}
+          // If the element has a class name or if we're passed `false`,
+          // then remove the whole classname (if there was one, the above saved it).
+          // Otherwise bring back whatever was previously saved (if anything),
+          // falling back to the empty string if nothing was stored.
+          if ( this.setAttribute ) {
+            this.setAttribute( "class",
+                className || value === false ?
+                    "" :
+                    dataPriv.get( this, "__className__" ) || ""
+            );
+          }
+        }
+      } );
+    },
 
-	if ( !fragment ) {
-		fragment = doc.createDocumentFragment();
-		jQuery.clean( args, doc, fragment, scripts );
-	}
+    hasClass: function( selector ) {
+      var className, elem,
+          i = 0;
 
-	if ( cacheable ) {
-		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
-	}
+      className = " " + selector + " ";
+      while ( ( elem = this[ i++ ] ) ) {
+        if ( elem.nodeType === 1 &&
+            ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+          return true;
+        }
+      }
 
-	return { fragment: fragment, cacheable: cacheable };
-};
+      return false;
+    }
+  } );
 
-jQuery.fragments = {};
 
-jQuery.each({
-	appendTo: "append",
-	prependTo: "prepend",
-	insertBefore: "before",
-	insertAfter: "after",
-	replaceAll: "replaceWith"
-}, function( name, original ) {
-	jQuery.fn[ name ] = function( selector ) {
-		var ret = [],
-			insert = jQuery( selector ),
-			parent = this.length === 1 && this[0].parentNode;
 
-		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
-			insert[ original ]( this[0] );
-			return this;
 
-		} else {
-			for ( var i = 0, l = insert.length; i < l; i++ ) {
-				var elems = (i > 0 ? this.clone(true) : this).get();
-				jQuery( insert[i] )[ original ]( elems );
-				ret = ret.concat( elems );
-			}
+  var rreturn = /\r/g;
 
-			return this.pushStack( ret, name, insert.selector );
-		}
-	};
-});
+  jQuery.fn.extend( {
+    val: function( value ) {
+      var hooks, ret, valueIsFunction,
+          elem = this[ 0 ];
 
-function getAll( elem ) {
-	if ( "getElementsByTagName" in elem ) {
-		return elem.getElementsByTagName( "*" );
+      if ( !arguments.length ) {
+        if ( elem ) {
+          hooks = jQuery.valHooks[ elem.type ] ||
+              jQuery.valHooks[ elem.nodeName.toLowerCase() ];
 
-	} else if ( "querySelectorAll" in elem ) {
-		return elem.querySelectorAll( "*" );
+          if ( hooks &&
+              "get" in hooks &&
+              ( ret = hooks.get( elem, "value" ) ) !== undefined
+          ) {
+            return ret;
+          }
 
-	} else {
-		return [];
-	}
-}
+          ret = elem.value;
 
-// Used in clean, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
-	if ( elem.type === "checkbox" || elem.type === "radio" ) {
-		elem.defaultChecked = elem.checked;
-	}
-}
-// Finds all inputs and passes them to fixDefaultChecked
-function findInputs( elem ) {
-	if ( jQuery.nodeName( elem, "input" ) ) {
-		fixDefaultChecked( elem );
-	} else if ( "getElementsByTagName" in elem ) {
-		jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
-	}
-}
+          // Handle most common string cases
+          if ( typeof ret === "string" ) {
+            return ret.replace( rreturn, "" );
+          }
 
-jQuery.extend({
-	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
-		var clone = elem.cloneNode(true),
-				srcElements,
-				destElements,
-				i;
+          // Handle cases where value is null/undef or number
+          return ret == null ? "" : ret;
+        }
 
-		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
-				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
-			// IE copies events bound via attachEvent when using cloneNode.
-			// Calling detachEvent on the clone will also remove the events
-			// from the original. In order to get around this, we use some
-			// proprietary methods to clear the events. Thanks to MooTools
-			// guys for this hotness.
+        return;
+      }
 
-			cloneFixAttributes( elem, clone );
+      valueIsFunction = isFunction( value );
 
-			// Using Sizzle here is crazy slow, so we use getElementsByTagName
-			// instead
-			srcElements = getAll( elem );
-			destElements = getAll( clone );
+      return this.each( function( i ) {
+        var val;
 
-			// Weird iteration because IE will replace the length property
-			// with an element if you are cloning the body and one of the
-			// elements on the page has a name or id of "length"
-			for ( i = 0; srcElements[i]; ++i ) {
-				// Ensure that the destination node is not null; Fixes #9587
-				if ( destElements[i] ) {
-					cloneFixAttributes( srcElements[i], destElements[i] );
-				}
-			}
-		}
+        if ( this.nodeType !== 1 ) {
+          return;
+        }
 
-		// Copy the events from the original to the clone
-		if ( dataAndEvents ) {
-			cloneCopyEvent( elem, clone );
+        if ( valueIsFunction ) {
+          val = value.call( this, i, jQuery( this ).val() );
+        } else {
+          val = value;
+        }
 
-			if ( deepDataAndEvents ) {
-				srcElements = getAll( elem );
-				destElements = getAll( clone );
+        // Treat null/undefined as ""; convert numbers to string
+        if ( val == null ) {
+          val = "";
 
-				for ( i = 0; srcElements[i]; ++i ) {
-					cloneCopyEvent( srcElements[i], destElements[i] );
-				}
-			}
-		}
+        } else if ( typeof val === "number" ) {
+          val += "";
 
-		srcElements = destElements = null;
+        } else if ( Array.isArray( val ) ) {
+          val = jQuery.map( val, function( value ) {
+            return value == null ? "" : value + "";
+          } );
+        }
 
-		// Return the cloned set
-		return clone;
-	},
+        hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
 
-	clean: function( elems, context, fragment, scripts ) {
-		var checkScriptType;
+        // If set returns undefined, fall back to normal setting
+        if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
+          this.value = val;
+        }
+      } );
+    }
+  } );
 
-		context = context || document;
+  jQuery.extend( {
+    valHooks: {
+      option: {
+        get: function( elem ) {
 
-		// !context.createElement fails in IE with an error but returns typeof 'object'
-		if ( typeof context.createElement === "undefined" ) {
-			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-		}
+          var val = jQuery.find.attr( elem, "value" );
+          return val != null ?
+              val :
 
-		var ret = [], j;
+              // Support: IE <=10 - 11 only
+              // option.text throws exceptions (#14686, #14858)
+              // Strip and collapse whitespace
+              // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+              stripAndCollapse( jQuery.text( elem ) );
+        }
+      },
+      select: {
+        get: function( elem ) {
+          var value, option, i,
+              options = elem.options,
+              index = elem.selectedIndex,
+              one = elem.type === "select-one",
+              values = one ? null : [],
+              max = one ? index + 1 : options.length;
 
-		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
-			if ( typeof elem === "number" ) {
-				elem += "";
-			}
+          if ( index < 0 ) {
+            i = max;
 
-			if ( !elem ) {
-				continue;
-			}
+          } else {
+            i = one ? index : 0;
+          }
 
-			// Convert html string into DOM nodes
-			if ( typeof elem === "string" ) {
-				if ( !rhtml.test( elem ) ) {
-					elem = context.createTextNode( elem );
-				} else {
-					// Fix "XHTML"-style tags in all browsers
-					elem = elem.replace(rxhtmlTag, "<$1></$2>");
+          // Loop through all the selected options
+          for ( ; i < max; i++ ) {
+            option = options[ i ];
 
-					// Trim whitespace, otherwise indexOf won't work as expected
-					var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
-						wrap = wrapMap[ tag ] || wrapMap._default,
-						depth = wrap[0],
-						div = context.createElement("div");
+            // Support: IE <=9 only
+            // IE8-9 doesn't update selected after form reset (#2551)
+            if ( ( option.selected || i === index ) &&
 
-					// Go to html and back, then peel off extra wrappers
-					div.innerHTML = wrap[1] + elem + wrap[2];
+                // Don't return options that are disabled or in a disabled optgroup
+                !option.disabled &&
+                ( !option.parentNode.disabled ||
+                    !nodeName( option.parentNode, "optgroup" ) ) ) {
 
-					// Move to the right depth
-					while ( depth-- ) {
-						div = div.lastChild;
-					}
+              // Get the specific value for the option
+              value = jQuery( option ).val();
 
-					// Remove IE's autoinserted <tbody> from table fragments
-					if ( !jQuery.support.tbody ) {
+              // We don't need an array for one selects
+              if ( one ) {
+                return value;
+              }
 
-						// String was a <table>, *may* have spurious <tbody>
-						var hasBody = rtbody.test(elem),
-							tbody = tag === "table" && !hasBody ?
-								div.firstChild && div.firstChild.childNodes :
+              // Multi-Selects return an array
+              values.push( value );
+            }
+          }
 
-								// String was a bare <thead> or <tfoot>
-								wrap[1] === "<table>" && !hasBody ?
-									div.childNodes :
-									[];
+          return values;
+        },
 
-						for ( j = tbody.length - 1; j >= 0 ; --j ) {
-							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
-								tbody[ j ].parentNode.removeChild( tbody[ j ] );
-							}
-						}
-					}
+        set: function( elem, value ) {
+          var optionSet, option,
+              options = elem.options,
+              values = jQuery.makeArray( value ),
+              i = options.length;
 
-					// IE completely kills leading whitespace when innerHTML is used
-					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
-						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
-					}
+          while ( i-- ) {
+            option = options[ i ];
 
-					elem = div.childNodes;
-				}
-			}
+            /* eslint-disable no-cond-assign */
 
-			// Resets defaultChecked for any radios and checkboxes
-			// about to be appended to the DOM in IE 6/7 (#8060)
-			var len;
-			if ( !jQuery.support.appendChecked ) {
-				if ( elem[0] && typeof (len = elem.length) === "number" ) {
-					for ( j = 0; j < len; j++ ) {
-						findInputs( elem[j] );
-					}
-				} else {
-					findInputs( elem );
-				}
-			}
+            if ( option.selected =
+                jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
+            ) {
+              optionSet = true;
+            }
 
-			if ( elem.nodeType ) {
-				ret.push( elem );
-			} else {
-				ret = jQuery.merge( ret, elem );
-			}
-		}
+            /* eslint-enable no-cond-assign */
+          }
 
-		if ( fragment ) {
-			checkScriptType = function( elem ) {
-				return !elem.type || rscriptType.test( elem.type );
-			};
-			for ( i = 0; ret[i]; i++ ) {
-				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
-					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+          // Force browsers to behave consistently when non-matching value is set
+          if ( !optionSet ) {
+            elem.selectedIndex = -1;
+          }
+          return values;
+        }
+      }
+    }
+  } );
 
-				} else {
-					if ( ret[i].nodeType === 1 ) {
-						var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+// Radios and checkboxes getter/setter
+  jQuery.each( [ "radio", "checkbox" ], function() {
+    jQuery.valHooks[ this ] = {
+      set: function( elem, value ) {
+        if ( Array.isArray( value ) ) {
+          return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
+        }
+      }
+    };
+    if ( !support.checkOn ) {
+      jQuery.valHooks[ this ].get = function( elem ) {
+        return elem.getAttribute( "value" ) === null ? "on" : elem.value;
+      };
+    }
+  } );
 
-						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
-					}
-					fragment.appendChild( ret[i] );
-				}
-			}
-		}
 
-		return ret;
-	},
 
-	cleanData: function( elems ) {
-		var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
-			deleteExpando = jQuery.support.deleteExpando;
 
-		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
-			if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
-				continue;
-			}
+// Return jQuery for attributes-only inclusion
 
-			id = elem[ jQuery.expando ];
 
-			if ( id ) {
-				data = cache[ id ] && cache[ id ][ internalKey ];
+  support.focusin = "onfocusin" in window;
 
-				if ( data && data.events ) {
-					for ( var type in data.events ) {
-						if ( special[ type ] ) {
-							jQuery.event.remove( elem, type );
 
-						// This is a shortcut to avoid jQuery.event.remove's overhead
-						} else {
-							jQuery.removeEvent( elem, type, data.handle );
-						}
-					}
+  var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+      stopPropagationCallback = function( e ) {
+        e.stopPropagation();
+      };
 
-					// Null the DOM reference to avoid IE6/7/8 leak (#7054)
-					if ( data.handle ) {
-						data.handle.elem = null;
-					}
-				}
+  jQuery.extend( jQuery.event, {
 
-				if ( deleteExpando ) {
-					delete elem[ jQuery.expando ];
+    trigger: function( event, data, elem, onlyHandlers ) {
 
-				} else if ( elem.removeAttribute ) {
-					elem.removeAttribute( jQuery.expando );
-				}
+      var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
+          eventPath = [ elem || document ],
+          type = hasOwn.call( event, "type" ) ? event.type : event,
+          namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
 
-				delete cache[ id ];
-			}
-		}
-	}
-});
+      cur = lastElement = tmp = elem = elem || document;
 
-function evalScript( i, elem ) {
-	if ( elem.src ) {
-		jQuery.ajax({
-			url: elem.src,
-			async: false,
-			dataType: "script"
-		});
-	} else {
-		jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
-	}
+      // Don't do events on text and comment nodes
+      if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+        return;
+      }
 
-	if ( elem.parentNode ) {
-		elem.parentNode.removeChild( elem );
-	}
-}
+      // focus/blur morphs to focusin/out; ensure we're not firing them right now
+      if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+        return;
+      }
 
+      if ( type.indexOf( "." ) > -1 ) {
 
+        // Namespaced trigger; create a regexp to match event type in handle()
+        namespaces = type.split( "." );
+        type = namespaces.shift();
+        namespaces.sort();
+      }
+      ontype = type.indexOf( ":" ) < 0 && "on" + type;
 
+      // Caller can pass in a jQuery.Event object, Object, or just an event type string
+      event = event[ jQuery.expando ] ?
+          event :
+          new jQuery.Event( type, typeof event === "object" && event );
 
-var ralpha = /alpha\([^)]*\)/i,
-	ropacity = /opacity=([^)]*)/,
-	// fixed for IE9, see #8346
-	rupper = /([A-Z]|^ms)/g,
-	rnumpx = /^-?\d+(?:px)?$/i,
-	rnum = /^-?\d/,
-	rrelNum = /^([\-+])=([\-+.\de]+)/,
+      // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+      event.isTrigger = onlyHandlers ? 2 : 3;
+      event.namespace = namespaces.join( "." );
+      event.rnamespace = event.namespace ?
+          new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
+          null;
 
-	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
-	cssWidth = [ "Left", "Right" ],
-	cssHeight = [ "Top", "Bottom" ],
-	curCSS,
+      // Clean up the event in case it is being reused
+      event.result = undefined;
+      if ( !event.target ) {
+        event.target = elem;
+      }
 
-	getComputedStyle,
-	currentStyle;
+      // Clone any incoming data and prepend the event, creating the handler arg list
+      data = data == null ?
+          [ event ] :
+          jQuery.makeArray( data, [ event ] );
 
-jQuery.fn.css = function( name, value ) {
-	// Setting 'undefined' is a no-op
-	if ( arguments.length === 2 && value === undefined ) {
-		return this;
-	}
+      // Allow special events to draw outside the lines
+      special = jQuery.event.special[ type ] || {};
+      if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+        return;
+      }
 
-	return jQuery.access( this, name, value, true, function( elem, name, value ) {
-		return value !== undefined ?
-			jQuery.style( elem, name, value ) :
-			jQuery.css( elem, name );
-	});
-};
+      // Determine event propagation path in advance, per W3C events spec (#9951)
+      // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+      if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
 
-jQuery.extend({
-	// Add in style property hooks for overriding the default
-	// behavior of getting and setting a style property
-	cssHooks: {
-		opacity: {
-			get: function( elem, computed ) {
-				if ( computed ) {
-					// We should always get a number back from opacity
-					var ret = curCSS( elem, "opacity", "opacity" );
-					return ret === "" ? "1" : ret;
+        bubbleType = special.delegateType || type;
+        if ( !rfocusMorph.test( bubbleType + type ) ) {
+          cur = cur.parentNode;
+        }
+        for ( ; cur; cur = cur.parentNode ) {
+          eventPath.push( cur );
+          tmp = cur;
+        }
 
-				} else {
-					return elem.style.opacity;
-				}
-			}
-		}
-	},
+        // Only add window if we got to document (e.g., not plain obj or detached DOM)
+        if ( tmp === ( elem.ownerDocument || document ) ) {
+          eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+        }
+      }
 
-	// Exclude the following css properties to add px
-	cssNumber: {
-		"fillOpacity": true,
-		"fontWeight": true,
-		"lineHeight": true,
-		"opacity": true,
-		"orphans": true,
-		"widows": true,
-		"zIndex": true,
-		"zoom": true
-	},
+      // Fire handlers on the event path
+      i = 0;
+      while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
+        lastElement = cur;
+        event.type = i > 1 ?
+            bubbleType :
+            special.bindType || type;
 
-	// Add in properties whose names you wish to fix before
-	// setting or getting the value
-	cssProps: {
-		// normalize float css property
-		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
-	},
+        // jQuery handler
+        handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
+            dataPriv.get( cur, "handle" );
+        if ( handle ) {
+          handle.apply( cur, data );
+        }
 
-	// Get and set the style property on a DOM Node
-	style: function( elem, name, value, extra ) {
-		// Don't set styles on text and comment nodes
-		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-			return;
-		}
+        // Native handler
+        handle = ontype && cur[ ontype ];
+        if ( handle && handle.apply && acceptData( cur ) ) {
+          event.result = handle.apply( cur, data );
+          if ( event.result === false ) {
+            event.preventDefault();
+          }
+        }
+      }
+      event.type = type;
 
-		// Make sure that we're working with the right name
-		var ret, type, origName = jQuery.camelCase( name ),
-			style = elem.style, hooks = jQuery.cssHooks[ origName ];
+      // If nobody prevented the default action, do it now
+      if ( !onlyHandlers && !event.isDefaultPrevented() ) {
 
-		name = jQuery.cssProps[ origName ] || origName;
+        if ( ( !special._default ||
+            special._default.apply( eventPath.pop(), data ) === false ) &&
+            acceptData( elem ) ) {
 
-		// Check if we're setting a value
-		if ( value !== undefined ) {
-			type = typeof value;
+          // Call a native DOM method on the target with the same name as the event.
+          // Don't do default actions on window, that's where global variables be (#6170)
+          if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
 
-			// convert relative number strings (+= or -=) to relative numbers. #7345
-			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
-				value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
-				// Fixes bug #9237
-				type = "number";
-			}
+            // Don't re-trigger an onFOO event when we call its FOO() method
+            tmp = elem[ ontype ];
 
-			// Make sure that NaN and null values aren't set. See: #7116
-			if ( value == null || type === "number" && isNaN( value ) ) {
-				return;
-			}
+            if ( tmp ) {
+              elem[ ontype ] = null;
+            }
 
-			// If a number was passed in, add 'px' to the (except for certain CSS properties)
-			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
-				value += "px";
-			}
+            // Prevent re-triggering of the same event, since we already bubbled it above
+            jQuery.event.triggered = type;
 
-			// If a hook was provided, use that value, otherwise just set the specified value
-			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
-				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
-				// Fixes bug #5509
-				try {
-					style[ name ] = value;
-				} catch(e) {}
-			}
+            if ( event.isPropagationStopped() ) {
+              lastElement.addEventListener( type, stopPropagationCallback );
+            }
 
-		} else {
-			// If a hook was provided get the non-computed value from there
-			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
-				return ret;
-			}
+            elem[ type ]();
 
-			// Otherwise just get the value from the style object
-			return style[ name ];
-		}
-	},
+            if ( event.isPropagationStopped() ) {
+              lastElement.removeEventListener( type, stopPropagationCallback );
+            }
 
-	css: function( elem, name, extra ) {
-		var ret, hooks;
+            jQuery.event.triggered = undefined;
 
-		// Make sure that we're working with the right name
-		name = jQuery.camelCase( name );
-		hooks = jQuery.cssHooks[ name ];
-		name = jQuery.cssProps[ name ] || name;
+            if ( tmp ) {
+              elem[ ontype ] = tmp;
+            }
+          }
+        }
+      }
 
-		// cssFloat needs a special treatment
-		if ( name === "cssFloat" ) {
-			name = "float";
-		}
+      return event.result;
+    },
 
-		// If a hook was provided get the computed value from there
-		if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
-			return ret;
+    // Piggyback on a donor event to simulate a different one
+    // Used only for `focus(in | out)` events
+    simulate: function( type, elem, event ) {
+      var e = jQuery.extend(
+          new jQuery.Event(),
+          event,
+          {
+            type: type,
+            isSimulated: true
+          }
+      );
 
-		// Otherwise, if a way to get the computed value exists, use that
-		} else if ( curCSS ) {
-			return curCSS( elem, name );
-		}
-	},
+      jQuery.event.trigger( e, null, elem );
+    }
 
-	// A method for quickly swapping in/out CSS properties to get correct calculations
-	swap: function( elem, options, callback ) {
-		var old = {};
+  } );
 
-		// Remember the old values, and insert the new ones
-		for ( var name in options ) {
-			old[ name ] = elem.style[ name ];
-			elem.style[ name ] = options[ name ];
-		}
+  jQuery.fn.extend( {
 
-		callback.call( elem );
+    trigger: function( type, data ) {
+      return this.each( function() {
+        jQuery.event.trigger( type, data, this );
+      } );
+    },
+    triggerHandler: function( type, data ) {
+      var elem = this[ 0 ];
+      if ( elem ) {
+        return jQuery.event.trigger( type, data, elem, true );
+      }
+    }
+  } );
 
-		// Revert the old values
-		for ( name in options ) {
-			elem.style[ name ] = old[ name ];
-		}
-	}
-});
 
-// DEPRECATED, Use jQuery.css() instead
-jQuery.curCSS = jQuery.css;
+// Support: Firefox <=44
+// Firefox doesn't have focus(in | out) events
+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+//
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
+// focus(in | out) events fire after focus & blur events,
+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
+  if ( !support.focusin ) {
+    jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
 
-jQuery.each(["height", "width"], function( i, name ) {
-	jQuery.cssHooks[ name ] = {
-		get: function( elem, computed, extra ) {
-			var val;
+      // Attach a single capturing handler on the document while someone wants focusin/focusout
+      var handler = function( event ) {
+        jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
+      };
 
-			if ( computed ) {
-				if ( elem.offsetWidth !== 0 ) {
-					return getWH( elem, name, extra );
-				} else {
-					jQuery.swap( elem, cssShow, function() {
-						val = getWH( elem, name, extra );
-					});
-				}
+      jQuery.event.special[ fix ] = {
+        setup: function() {
+          var doc = this.ownerDocument || this,
+              attaches = dataPriv.access( doc, fix );
 
-				return val;
-			}
-		},
+          if ( !attaches ) {
+            doc.addEventListener( orig, handler, true );
+          }
+          dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
+        },
+        teardown: function() {
+          var doc = this.ownerDocument || this,
+              attaches = dataPriv.access( doc, fix ) - 1;
 
-		set: function( elem, value ) {
-			if ( rnumpx.test( value ) ) {
-				// ignore negative width and height values #1599
-				value = parseFloat( value );
+          if ( !attaches ) {
+            doc.removeEventListener( orig, handler, true );
+            dataPriv.remove( doc, fix );
 
-				if ( value >= 0 ) {
-					return value + "px";
-				}
+          } else {
+            dataPriv.access( doc, fix, attaches );
+          }
+        }
+      };
+    } );
+  }
+  var location = window.location;
 
-			} else {
-				return value;
-			}
-		}
-	};
-});
+  var nonce = Date.now();
 
-if ( !jQuery.support.opacity ) {
-	jQuery.cssHooks.opacity = {
-		get: function( elem, computed ) {
-			// IE uses filters for opacity
-			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
-				( parseFloat( RegExp.$1 ) / 100 ) + "" :
-				computed ? "1" : "";
-		},
+  var rquery = ( /\?/ );
 
-		set: function( elem, value ) {
-			var style = elem.style,
-				currentStyle = elem.currentStyle,
-				opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")",
-				filter = currentStyle && currentStyle.filter || style.filter || "";
 
-			// IE has trouble with opacity if it does not have layout
-			// Force it by setting the zoom level
-			style.zoom = 1;
 
-			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
-			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
+// Cross-browser xml parsing
+  jQuery.parseXML = function( data ) {
+    var xml;
+    if ( !data || typeof data !== "string" ) {
+      return null;
+    }
 
-				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
-				// if "filter:" is present at all, clearType is disabled, we want to avoid this
-				// style.removeAttribute is IE Only, but so apparently is this code path...
-				style.removeAttribute( "filter" );
+    // Support: IE 9 - 11 only
+    // IE throws on parseFromString with invalid input.
+    try {
+      xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
+    } catch ( e ) {
+      xml = undefined;
+    }
 
-				// if there there is no filter style applied in a css rule, we are done
-				if ( currentStyle && !currentStyle.filter ) {
-					return;
-				}
-			}
+    if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+      jQuery.error( "Invalid XML: " + data );
+    }
+    return xml;
+  };
 
-			// otherwise, set new filter values
-			style.filter = ralpha.test( filter ) ?
-				filter.replace( ralpha, opacity ) :
-				filter + " " + opacity;
-		}
-	};
-}
 
-jQuery(function() {
-	// This hook cannot be added until DOM ready because the support test
-	// for it is not run until after DOM ready
-	if ( !jQuery.support.reliableMarginRight ) {
-		jQuery.cssHooks.marginRight = {
-			get: function( elem, computed ) {
-				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-				// Work around by temporarily setting element display to inline-block
-				var ret;
-				jQuery.swap( elem, { "display": "inline-block" }, function() {
-					if ( computed ) {
-						ret = curCSS( elem, "margin-right", "marginRight" );
-					} else {
-						ret = elem.style.marginRight;
-					}
-				});
-				return ret;
-			}
-		};
-	}
-});
+  var
+      rbracket = /\[\]$/,
+      rCRLF = /\r?\n/g,
+      rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+      rsubmittable = /^(?:input|select|textarea|keygen)/i;
 
-if ( document.defaultView && document.defaultView.getComputedStyle ) {
-	getComputedStyle = function( elem, name ) {
-		var ret, defaultView, computedStyle;
+  function buildParams( prefix, obj, traditional, add ) {
+    var name;
 
-		name = name.replace( rupper, "-$1" ).toLowerCase();
+    if ( Array.isArray( obj ) ) {
 
-		if ( !(defaultView = elem.ownerDocument.defaultView) ) {
-			return undefined;
-		}
+      // Serialize array item.
+      jQuery.each( obj, function( i, v ) {
+        if ( traditional || rbracket.test( prefix ) ) {
 
-		if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
-			ret = computedStyle.getPropertyValue( name );
-			if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
-				ret = jQuery.style( elem, name );
-			}
-		}
+          // Treat each array item as a scalar.
+          add( prefix, v );
 
-		return ret;
-	};
-}
+        } else {
 
-if ( document.documentElement.currentStyle ) {
-	currentStyle = function( elem, name ) {
-		var left,
-			ret = elem.currentStyle && elem.currentStyle[ name ],
-			rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
-			style = elem.style;
+          // Item is non-scalar (array or object), encode its numeric index.
+          buildParams(
+              prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
+              v,
+              traditional,
+              add
+          );
+        }
+      } );
 
-		// From the awesome hack by Dean Edwards
-		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+    } else if ( !traditional && toType( obj ) === "object" ) {
 
-		// If we're not dealing with a regular pixel number
-		// but a number that has a weird ending, we need to convert it to pixels
-		if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
-			// Remember the original values
-			left = style.left;
+      // Serialize object item.
+      for ( name in obj ) {
+        buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+      }
 
-			// Put in the new values to get a computed value out
-			if ( rsLeft ) {
-				elem.runtimeStyle.left = elem.currentStyle.left;
-			}
-			style.left = name === "fontSize" ? "1em" : (ret || 0);
-			ret = style.pixelLeft + "px";
+    } else {
 
-			// Revert the changed values
-			style.left = left;
-			if ( rsLeft ) {
-				elem.runtimeStyle.left = rsLeft;
-			}
-		}
+      // Serialize scalar item.
+      add( prefix, obj );
+    }
+  }
 
-		return ret === "" ? "auto" : ret;
-	};
-}
+// Serialize an array of form elements or a set of
+// key/values into a query string
+  jQuery.param = function( a, traditional ) {
+    var prefix,
+        s = [],
+        add = function( key, valueOrFunction ) {
 
-curCSS = getComputedStyle || currentStyle;
+          // If value is a function, invoke it and use its return value
+          var value = isFunction( valueOrFunction ) ?
+              valueOrFunction() :
+              valueOrFunction;
 
-function getWH( elem, name, extra ) {
+          s[ s.length ] = encodeURIComponent( key ) + "=" +
+              encodeURIComponent( value == null ? "" : value );
+        };
 
-	// Start with offset property
-	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
-		which = name === "width" ? cssWidth : cssHeight;
+    // If an array was passed in, assume that it is an array of form elements.
+    if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
 
-	if ( val > 0 ) {
-		if ( extra !== "border" ) {
-			jQuery.each( which, function() {
-				if ( !extra ) {
-					val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
-				}
-				if ( extra === "margin" ) {
-					val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
-				} else {
-					val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
-				}
-			});
-		}
+      // Serialize the form elements
+      jQuery.each( a, function() {
+        add( this.name, this.value );
+      } );
 
-		return val + "px";
-	}
+    } else {
 
-	// Fall back to computed then uncomputed css if necessary
-	val = curCSS( elem, name, name );
-	if ( val < 0 || val == null ) {
-		val = elem.style[ name ] || 0;
-	}
-	// Normalize "", auto, and prepare for extra
-	val = parseFloat( val ) || 0;
+      // If traditional, encode the "old" way (the way 1.3.2 or older
+      // did it), otherwise encode params recursively.
+      for ( prefix in a ) {
+        buildParams( prefix, a[ prefix ], traditional, add );
+      }
+    }
 
-	// Add padding, border, margin
-	if ( extra ) {
-		jQuery.each( which, function() {
-			val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
-			if ( extra !== "padding" ) {
-				val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
-			}
-			if ( extra === "margin" ) {
-				val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
-			}
-		});
-	}
+    // Return the resulting serialization
+    return s.join( "&" );
+  };
 
-	return val + "px";
-}
+  jQuery.fn.extend( {
+    serialize: function() {
+      return jQuery.param( this.serializeArray() );
+    },
+    serializeArray: function() {
+      return this.map( function() {
 
-if ( jQuery.expr && jQuery.expr.filters ) {
-	jQuery.expr.filters.hidden = function( elem ) {
-		var width = elem.offsetWidth,
-			height = elem.offsetHeight;
+        // Can add propHook for "elements" to filter or add form elements
+        var elements = jQuery.prop( this, "elements" );
+        return elements ? jQuery.makeArray( elements ) : this;
+      } )
+          .filter( function() {
+            var type = this.type;
 
-		return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
-	};
+            // Use .is( ":disabled" ) so that fieldset[disabled] works
+            return this.name && !jQuery( this ).is( ":disabled" ) &&
+                rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                ( this.checked || !rcheckableType.test( type ) );
+          } )
+          .map( function( i, elem ) {
+            var val = jQuery( this ).val();
 
-	jQuery.expr.filters.visible = function( elem ) {
-		return !jQuery.expr.filters.hidden( elem );
-	};
-}
+            if ( val == null ) {
+              return null;
+            }
 
+            if ( Array.isArray( val ) ) {
+              return jQuery.map( val, function( val ) {
+                return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+              } );
+            }
 
+            return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+          } ).get();
+    }
+  } );
 
 
-var r20 = /%20/g,
-	rbracket = /\[\]$/,
-	rCRLF = /\r?\n/g,
-	rhash = /#.*$/,
-	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
-	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
-	// #7653, #8125, #8152: local protocol detection
-	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
-	rnoContent = /^(?:GET|HEAD)$/,
-	rprotocol = /^\/\//,
-	rquery = /\?/,
-	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
-	rselectTextarea = /^(?:select|textarea)/i,
-	rspacesAjax = /\s+/,
-	rts = /([?&])_=[^&]*/,
-	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+  var
+      r20 = /%20/g,
+      rhash = /#.*$/,
+      rantiCache = /([?&])_=[^&]*/,
+      rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
 
-	// Keep a copy of the old load method
-	_load = jQuery.fn.load,
+      // #7653, #8125, #8152: local protocol detection
+      rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+      rnoContent = /^(?:GET|HEAD)$/,
+      rprotocol = /^\/\//,
 
-	/* Prefilters
+      /* Prefilters
 	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
 	 * 2) These are called:
 	 *    - BEFORE asking for a transport
@@ -6706,2341 +8546,1819 @@
 	 * 4) the catchall symbol "*" can be used
 	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
 	 */
-	prefilters = {},
+      prefilters = {},
 
-	/* Transports bindings
+      /* Transports bindings
 	 * 1) key is the dataType
 	 * 2) the catchall symbol "*" can be used
 	 * 3) selection will start with transport dataType and THEN go to "*" if needed
 	 */
-	transports = {},
+      transports = {},
 
-	// Document location
-	ajaxLocation,
+      // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+      allTypes = "*/".concat( "*" ),
 
-	// Document location segments
-	ajaxLocParts,
-	
-	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
-	allTypes = ["*/"] + ["*"];
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
-	ajaxLocation = location.href;
-} catch( e ) {
-	// Use the href attribute of an A element
-	// since IE will modify it given document.location
-	ajaxLocation = document.createElement( "a" );
-	ajaxLocation.href = "";
-	ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+      // Anchor tag for parsing the document origin
+      originAnchor = document.createElement( "a" );
+  originAnchor.href = location.href;
 
 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
+  function addToPrefiltersOrTransports( structure ) {
 
-	// dataTypeExpression is optional and defaults to "*"
-	return function( dataTypeExpression, func ) {
+    // dataTypeExpression is optional and defaults to "*"
+    return function( dataTypeExpression, func ) {
 
-		if ( typeof dataTypeExpression !== "string" ) {
-			func = dataTypeExpression;
-			dataTypeExpression = "*";
-		}
+      if ( typeof dataTypeExpression !== "string" ) {
+        func = dataTypeExpression;
+        dataTypeExpression = "*";
+      }
 
-		if ( jQuery.isFunction( func ) ) {
-			var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
-				i = 0,
-				length = dataTypes.length,
-				dataType,
-				list,
-				placeBefore;
+      var dataType,
+          i = 0,
+          dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
 
-			// For each dataType in the dataTypeExpression
-			for(; i < length; i++ ) {
-				dataType = dataTypes[ i ];
-				// We control if we're asked to add before
-				// any existing element
-				placeBefore = /^\+/.test( dataType );
-				if ( placeBefore ) {
-					dataType = dataType.substr( 1 ) || "*";
-				}
-				list = structure[ dataType ] = structure[ dataType ] || [];
-				// then we add to the structure accordingly
-				list[ placeBefore ? "unshift" : "push" ]( func );
-			}
-		}
-	};
-}
+      if ( isFunction( func ) ) {
+
+        // For each dataType in the dataTypeExpression
+        while ( ( dataType = dataTypes[ i++ ] ) ) {
+
+          // Prepend if requested
+          if ( dataType[ 0 ] === "+" ) {
+            dataType = dataType.slice( 1 ) || "*";
+            ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
+
+            // Otherwise append
+          } else {
+            ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
+          }
+        }
+      }
+    };
+  }
 
 // Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
-		dataType /* internal */, inspected /* internal */ ) {
+  function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
 
-	dataType = dataType || options.dataTypes[ 0 ];
-	inspected = inspected || {};
+    var inspected = {},
+        seekingTransport = ( structure === transports );
 
-	inspected[ dataType ] = true;
+    function inspect( dataType ) {
+      var selected;
+      inspected[ dataType ] = true;
+      jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+        var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+        if ( typeof dataTypeOrTransport === "string" &&
+            !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
 
-	var list = structure[ dataType ],
-		i = 0,
-		length = list ? list.length : 0,
-		executeOnly = ( structure === prefilters ),
-		selection;
+          options.dataTypes.unshift( dataTypeOrTransport );
+          inspect( dataTypeOrTransport );
+          return false;
+        } else if ( seekingTransport ) {
+          return !( selected = dataTypeOrTransport );
+        }
+      } );
+      return selected;
+    }
 
-	for(; i < length && ( executeOnly || !selection ); i++ ) {
-		selection = list[ i ]( options, originalOptions, jqXHR );
-		// If we got redirected to another dataType
-		// we try there if executing only and not done already
-		if ( typeof selection === "string" ) {
-			if ( !executeOnly || inspected[ selection ] ) {
-				selection = undefined;
-			} else {
-				options.dataTypes.unshift( selection );
-				selection = inspectPrefiltersOrTransports(
-						structure, options, originalOptions, jqXHR, selection, inspected );
-			}
-		}
-	}
-	// If we're only executing or nothing was selected
-	// we try the catchall dataType if not done already
-	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
-		selection = inspectPrefiltersOrTransports(
-				structure, options, originalOptions, jqXHR, "*", inspected );
-	}
-	// unnecessary when only executing (prefilters)
-	// but it'll be ignored by the caller in that case
-	return selection;
-}
+    return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+  }
 
 // A special extend for ajax options
 // that takes "flat" options (not to be deep extended)
 // Fixes #9887
-function ajaxExtend( target, src ) {
-	var key, deep,
-		flatOptions = jQuery.ajaxSettings.flatOptions || {};
-	for( key in src ) {
-		if ( src[ key ] !== undefined ) {
-			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
-		}
-	}
-	if ( deep ) {
-		jQuery.extend( true, target, deep );
-	}
-}
+  function ajaxExtend( target, src ) {
+    var key, deep,
+        flatOptions = jQuery.ajaxSettings.flatOptions || {};
 
-jQuery.fn.extend({
-	load: function( url, params, callback ) {
-		if ( typeof url !== "string" && _load ) {
-			return _load.apply( this, arguments );
+    for ( key in src ) {
+      if ( src[ key ] !== undefined ) {
+        ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+      }
+    }
+    if ( deep ) {
+      jQuery.extend( true, target, deep );
+    }
 
-		// Don't do a request if no elements are being requested
-		} else if ( !this.length ) {
-			return this;
-		}
+    return target;
+  }
 
-		var off = url.indexOf( " " );
-		if ( off >= 0 ) {
-			var selector = url.slice( off, url.length );
-			url = url.slice( 0, off );
-		}
+  /* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+  function ajaxHandleResponses( s, jqXHR, responses ) {
 
-		// Default to a GET request
-		var type = "GET";
+    var ct, type, finalDataType, firstDataType,
+        contents = s.contents,
+        dataTypes = s.dataTypes;
 
-		// If the second parameter was provided
-		if ( params ) {
-			// If it's a function
-			if ( jQuery.isFunction( params ) ) {
-				// We assume that it's the callback
-				callback = params;
-				params = undefined;
+    // Remove auto dataType and get content-type in the process
+    while ( dataTypes[ 0 ] === "*" ) {
+      dataTypes.shift();
+      if ( ct === undefined ) {
+        ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
+      }
+    }
 
-			// Otherwise, build a param string
-			} else if ( typeof params === "object" ) {
-				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
-				type = "POST";
-			}
-		}
+    // Check if we're dealing with a known content-type
+    if ( ct ) {
+      for ( type in contents ) {
+        if ( contents[ type ] && contents[ type ].test( ct ) ) {
+          dataTypes.unshift( type );
+          break;
+        }
+      }
+    }
 
-		var self = this;
+    // Check to see if we have a response for the expected dataType
+    if ( dataTypes[ 0 ] in responses ) {
+      finalDataType = dataTypes[ 0 ];
+    } else {
 
-		// Request the remote document
-		jQuery.ajax({
-			url: url,
-			type: type,
-			dataType: "html",
-			data: params,
-			// Complete callback (responseText is used internally)
-			complete: function( jqXHR, status, responseText ) {
-				// Store the response as specified by the jqXHR object
-				responseText = jqXHR.responseText;
-				// If successful, inject the HTML into all the matched elements
-				if ( jqXHR.isResolved() ) {
-					// #4825: Get the actual response in case
-					// a dataFilter is present in ajaxSettings
-					jqXHR.done(function( r ) {
-						responseText = r;
-					});
-					// See if a selector was specified
-					self.html( selector ?
-						// Create a dummy div to hold the results
-						jQuery("<div>")
-							// inject the contents of the document in, removing the scripts
-							// to avoid any 'Permission Denied' errors in IE
-							.append(responseText.replace(rscript, ""))
+      // Try convertible dataTypes
+      for ( type in responses ) {
+        if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
+          finalDataType = type;
+          break;
+        }
+        if ( !firstDataType ) {
+          firstDataType = type;
+        }
+      }
 
-							// Locate the specified elements
-							.find(selector) :
+      // Or just use first one
+      finalDataType = finalDataType || firstDataType;
+    }
 
-						// If not, just inject the full result
-						responseText );
-				}
+    // If we found a dataType
+    // We add the dataType to the list if needed
+    // and return the corresponding response
+    if ( finalDataType ) {
+      if ( finalDataType !== dataTypes[ 0 ] ) {
+        dataTypes.unshift( finalDataType );
+      }
+      return responses[ finalDataType ];
+    }
+  }
 
-				if ( callback ) {
-					self.each( callback, [ responseText, status, jqXHR ] );
-				}
-			}
-		});
+  /* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+  function ajaxConvert( s, response, jqXHR, isSuccess ) {
+    var conv2, current, conv, tmp, prev,
+        converters = {},
 
-		return this;
-	},
+        // Work with a copy of dataTypes in case we need to modify it for conversion
+        dataTypes = s.dataTypes.slice();
 
-	serialize: function() {
-		return jQuery.param( this.serializeArray() );
-	},
+    // Create converters map with lowercased keys
+    if ( dataTypes[ 1 ] ) {
+      for ( conv in s.converters ) {
+        converters[ conv.toLowerCase() ] = s.converters[ conv ];
+      }
+    }
 
-	serializeArray: function() {
-		return this.map(function(){
-			return this.elements ? jQuery.makeArray( this.elements ) : this;
-		})
-		.filter(function(){
-			return this.name && !this.disabled &&
-				( this.checked || rselectTextarea.test( this.nodeName ) ||
-					rinput.test( this.type ) );
-		})
-		.map(function( i, elem ){
-			var val = jQuery( this ).val();
+    current = dataTypes.shift();
 
-			return val == null ?
-				null :
-				jQuery.isArray( val ) ?
-					jQuery.map( val, function( val, i ){
-						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-					}) :
-					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-		}).get();
-	}
-});
+    // Convert to each sequential dataType
+    while ( current ) {
 
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
-	jQuery.fn[ o ] = function( f ){
-		return this.bind( o, f );
-	};
-});
+      if ( s.responseFields[ current ] ) {
+        jqXHR[ s.responseFields[ current ] ] = response;
+      }
 
-jQuery.each( [ "get", "post" ], function( i, method ) {
-	jQuery[ method ] = function( url, data, callback, type ) {
-		// shift arguments if data argument was omitted
-		if ( jQuery.isFunction( data ) ) {
-			type = type || callback;
-			callback = data;
-			data = undefined;
-		}
+      // Apply the dataFilter if provided
+      if ( !prev && isSuccess && s.dataFilter ) {
+        response = s.dataFilter( response, s.dataType );
+      }
 
-		return jQuery.ajax({
-			type: method,
-			url: url,
-			data: data,
-			success: callback,
-			dataType: type
-		});
-	};
-});
+      prev = current;
+      current = dataTypes.shift();
 
-jQuery.extend({
+      if ( current ) {
 
-	getScript: function( url, callback ) {
-		return jQuery.get( url, undefined, callback, "script" );
-	},
+        // There's only work to do if current dataType is non-auto
+        if ( current === "*" ) {
 
-	getJSON: function( url, data, callback ) {
-		return jQuery.get( url, data, callback, "json" );
-	},
+          current = prev;
 
-	// Creates a full fledged settings object into target
-	// with both ajaxSettings and settings fields.
-	// If target is omitted, writes into ajaxSettings.
-	ajaxSetup: function( target, settings ) {
-		if ( settings ) {
-			// Building a settings object
-			ajaxExtend( target, jQuery.ajaxSettings );
-		} else {
-			// Extending ajaxSettings
-			settings = target;
-			target = jQuery.ajaxSettings;
-		}
-		ajaxExtend( target, settings );
-		return target;
-	},
+          // Convert response if prev dataType is non-auto and differs from current
+        } else if ( prev !== "*" && prev !== current ) {
 
-	ajaxSettings: {
-		url: ajaxLocation,
-		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
-		global: true,
-		type: "GET",
-		contentType: "application/x-www-form-urlencoded",
-		processData: true,
-		async: true,
-		/*
+          // Seek a direct converter
+          conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+          // If none found, seek a pair
+          if ( !conv ) {
+            for ( conv2 in converters ) {
+
+              // If conv2 outputs current
+              tmp = conv2.split( " " );
+              if ( tmp[ 1 ] === current ) {
+
+                // If prev can be converted to accepted input
+                conv = converters[ prev + " " + tmp[ 0 ] ] ||
+                    converters[ "* " + tmp[ 0 ] ];
+                if ( conv ) {
+
+                  // Condense equivalence converters
+                  if ( conv === true ) {
+                    conv = converters[ conv2 ];
+
+                    // Otherwise, insert the intermediate dataType
+                  } else if ( converters[ conv2 ] !== true ) {
+                    current = tmp[ 0 ];
+                    dataTypes.unshift( tmp[ 1 ] );
+                  }
+                  break;
+                }
+              }
+            }
+          }
+
+          // Apply converter (if not an equivalence)
+          if ( conv !== true ) {
+
+            // Unless errors are allowed to bubble, catch and return them
+            if ( conv && s.throws ) {
+              response = conv( response );
+            } else {
+              try {
+                response = conv( response );
+              } catch ( e ) {
+                return {
+                  state: "parsererror",
+                  error: conv ? e : "No conversion from " + prev + " to " + current
+                };
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return { state: "success", data: response };
+  }
+
+  jQuery.extend( {
+
+    // Counter for holding the number of active queries
+    active: 0,
+
+    // Last-Modified header cache for next request
+    lastModified: {},
+    etag: {},
+
+    ajaxSettings: {
+      url: location.href,
+      type: "GET",
+      isLocal: rlocalProtocol.test( location.protocol ),
+      global: true,
+      processData: true,
+      async: true,
+      contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
+      /*
 		timeout: 0,
 		data: null,
 		dataType: null,
 		username: null,
 		password: null,
 		cache: null,
+		throws: false,
 		traditional: false,
 		headers: {},
 		*/
 
-		accepts: {
-			xml: "application/xml, text/xml",
-			html: "text/html",
-			text: "text/plain",
-			json: "application/json, text/javascript",
-			"*": allTypes
-		},
+      accepts: {
+        "*": allTypes,
+        text: "text/plain",
+        html: "text/html",
+        xml: "application/xml, text/xml",
+        json: "application/json, text/javascript"
+      },
 
-		contents: {
-			xml: /xml/,
-			html: /html/,
-			json: /json/
-		},
+      contents: {
+        xml: /\bxml\b/,
+        html: /\bhtml/,
+        json: /\bjson\b/
+      },
 
-		responseFields: {
-			xml: "responseXML",
-			text: "responseText"
-		},
+      responseFields: {
+        xml: "responseXML",
+        text: "responseText",
+        json: "responseJSON"
+      },
 
-		// List of data converters
-		// 1) key format is "source_type destination_type" (a single space in-between)
-		// 2) the catchall symbol "*" can be used for source_type
-		converters: {
+      // Data converters
+      // Keys separate source (or catchall "*") and destination types with a single space
+      converters: {
 
-			// Convert anything to text
-			"* text": window.String,
+        // Convert anything to text
+        "* text": String,
 
-			// Text to html (true = no transformation)
-			"text html": true,
+        // Text to html (true = no transformation)
+        "text html": true,
 
-			// Evaluate text as a json expression
-			"text json": jQuery.parseJSON,
+        // Evaluate text as a json expression
+        "text json": JSON.parse,
 
-			// Parse text as xml
-			"text xml": jQuery.parseXML
-		},
+        // Parse text as xml
+        "text xml": jQuery.parseXML
+      },
 
-		// For options that shouldn't be deep extended:
-		// you can add your own custom options here if
-		// and when you create one that shouldn't be
-		// deep extended (see ajaxExtend)
-		flatOptions: {
-			context: true,
-			url: true
-		}
-	},
+      // For options that shouldn't be deep extended:
+      // you can add your own custom options here if
+      // and when you create one that shouldn't be
+      // deep extended (see ajaxExtend)
+      flatOptions: {
+        url: true,
+        context: true
+      }
+    },
 
-	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
-	ajaxTransport: addToPrefiltersOrTransports( transports ),
+    // Creates a full fledged settings object into target
+    // with both ajaxSettings and settings fields.
+    // If target is omitted, writes into ajaxSettings.
+    ajaxSetup: function( target, settings ) {
+      return settings ?
 
-	// Main method
-	ajax: function( url, options ) {
+          // Building a settings object
+          ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
 
-		// If url is an object, simulate pre-1.5 signature
-		if ( typeof url === "object" ) {
-			options = url;
-			url = undefined;
-		}
+          // Extending ajaxSettings
+          ajaxExtend( jQuery.ajaxSettings, target );
+    },
 
-		// Force options to be an object
-		options = options || {};
+    ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+    ajaxTransport: addToPrefiltersOrTransports( transports ),
 
-		var // Create the final options object
-			s = jQuery.ajaxSetup( {}, options ),
-			// Callbacks context
-			callbackContext = s.context || s,
-			// Context for global events
-			// It's the callbackContext if one was provided in the options
-			// and if it's a DOM node or a jQuery collection
-			globalEventContext = callbackContext !== s &&
-				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
-						jQuery( callbackContext ) : jQuery.event,
-			// Deferreds
-			deferred = jQuery.Deferred(),
-			completeDeferred = jQuery._Deferred(),
-			// Status-dependent callbacks
-			statusCode = s.statusCode || {},
-			// ifModified key
-			ifModifiedKey,
-			// Headers (they are sent all at once)
-			requestHeaders = {},
-			requestHeadersNames = {},
-			// Response headers
-			responseHeadersString,
-			responseHeaders,
-			// transport
-			transport,
-			// timeout handle
-			timeoutTimer,
-			// Cross-domain detection vars
-			parts,
-			// The jqXHR state
-			state = 0,
-			// To know if global events are to be dispatched
-			fireGlobals,
-			// Loop variable
-			i,
-			// Fake xhr
-			jqXHR = {
+    // Main method
+    ajax: function( url, options ) {
 
-				readyState: 0,
+      // If url is an object, simulate pre-1.5 signature
+      if ( typeof url === "object" ) {
+        options = url;
+        url = undefined;
+      }
 
-				// Caches the header
-				setRequestHeader: function( name, value ) {
-					if ( !state ) {
-						var lname = name.toLowerCase();
-						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
-						requestHeaders[ name ] = value;
-					}
-					return this;
-				},
+      // Force options to be an object
+      options = options || {};
 
-				// Raw string
-				getAllResponseHeaders: function() {
-					return state === 2 ? responseHeadersString : null;
-				},
+      var transport,
 
-				// Builds headers hashtable if needed
-				getResponseHeader: function( key ) {
-					var match;
-					if ( state === 2 ) {
-						if ( !responseHeaders ) {
-							responseHeaders = {};
-							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
-								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
-							}
-						}
-						match = responseHeaders[ key.toLowerCase() ];
-					}
-					return match === undefined ? null : match;
-				},
+          // URL without anti-cache param
+          cacheURL,
 
-				// Overrides response content-type header
-				overrideMimeType: function( type ) {
-					if ( !state ) {
-						s.mimeType = type;
-					}
-					return this;
-				},
+          // Response headers
+          responseHeadersString,
+          responseHeaders,
 
-				// Cancel the request
-				abort: function( statusText ) {
-					statusText = statusText || "abort";
-					if ( transport ) {
-						transport.abort( statusText );
-					}
-					done( 0, statusText );
-					return this;
-				}
-			};
+          // timeout handle
+          timeoutTimer,
 
-		// Callback for when everything is done
-		// It is defined here because jslint complains if it is declared
-		// at the end of the function (which would be more logical and readable)
-		function done( status, nativeStatusText, responses, headers ) {
+          // Url cleanup var
+          urlAnchor,
 
-			// Called once
-			if ( state === 2 ) {
-				return;
-			}
+          // Request state (becomes false upon send and true upon completion)
+          completed,
 
-			// State is "done" now
-			state = 2;
+          // To know if global events are to be dispatched
+          fireGlobals,
 
-			// Clear timeout if it exists
-			if ( timeoutTimer ) {
-				clearTimeout( timeoutTimer );
-			}
+          // Loop variable
+          i,
 
-			// Dereference transport for early garbage collection
-			// (no matter how long the jqXHR object will be used)
-			transport = undefined;
+          // uncached part of the url
+          uncached,
 
-			// Cache response headers
-			responseHeadersString = headers || "";
+          // Create the final options object
+          s = jQuery.ajaxSetup( {}, options ),
 
-			// Set readyState
-			jqXHR.readyState = status > 0 ? 4 : 0;
+          // Callbacks context
+          callbackContext = s.context || s,
 
-			var isSuccess,
-				success,
-				error,
-				statusText = nativeStatusText,
-				response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
-				lastModified,
-				etag;
+          // Context for global events is callbackContext if it is a DOM node or jQuery collection
+          globalEventContext = s.context &&
+          ( callbackContext.nodeType || callbackContext.jquery ) ?
+              jQuery( callbackContext ) :
+              jQuery.event,
 
-			// If successful, handle type chaining
-			if ( status >= 200 && status < 300 || status === 304 ) {
+          // Deferreds
+          deferred = jQuery.Deferred(),
+          completeDeferred = jQuery.Callbacks( "once memory" ),
 
-				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-				if ( s.ifModified ) {
+          // Status-dependent callbacks
+          statusCode = s.statusCode || {},
 
-					if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
-						jQuery.lastModified[ ifModifiedKey ] = lastModified;
-					}
-					if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
-						jQuery.etag[ ifModifiedKey ] = etag;
-					}
-				}
+          // Headers (they are sent all at once)
+          requestHeaders = {},
+          requestHeadersNames = {},
 
-				// If not modified
-				if ( status === 304 ) {
+          // Default abort message
+          strAbort = "canceled",
 
-					statusText = "notmodified";
-					isSuccess = true;
+          // Fake xhr
+          jqXHR = {
+            readyState: 0,
 
-				// If we have data
-				} else {
+            // Builds headers hashtable if needed
+            getResponseHeader: function( key ) {
+              var match;
+              if ( completed ) {
+                if ( !responseHeaders ) {
+                  responseHeaders = {};
+                  while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                    responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+                  }
+                }
+                match = responseHeaders[ key.toLowerCase() ];
+              }
+              return match == null ? null : match;
+            },
 
-					try {
-						success = ajaxConvert( s, response );
-						statusText = "success";
-						isSuccess = true;
-					} catch(e) {
-						// We have a parsererror
-						statusText = "parsererror";
-						error = e;
-					}
-				}
-			} else {
-				// We extract error from statusText
-				// then normalize statusText and status for non-aborts
-				error = statusText;
-				if( !statusText || status ) {
-					statusText = "error";
-					if ( status < 0 ) {
-						status = 0;
-					}
-				}
-			}
+            // Raw string
+            getAllResponseHeaders: function() {
+              return completed ? responseHeadersString : null;
+            },
 
-			// Set data for the fake xhr object
-			jqXHR.status = status;
-			jqXHR.statusText = "" + ( nativeStatusText || statusText );
+            // Caches the header
+            setRequestHeader: function( name, value ) {
+              if ( completed == null ) {
+                name = requestHeadersNames[ name.toLowerCase() ] =
+                    requestHeadersNames[ name.toLowerCase() ] || name;
+                requestHeaders[ name ] = value;
+              }
+              return this;
+            },
 
-			// Success/Error
-			if ( isSuccess ) {
-				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
-			} else {
-				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
-			}
+            // Overrides response content-type header
+            overrideMimeType: function( type ) {
+              if ( completed == null ) {
+                s.mimeType = type;
+              }
+              return this;
+            },
 
-			// Status-dependent callbacks
-			jqXHR.statusCode( statusCode );
-			statusCode = undefined;
+            // Status-dependent callbacks
+            statusCode: function( map ) {
+              var code;
+              if ( map ) {
+                if ( completed ) {
 
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
-						[ jqXHR, s, isSuccess ? success : error ] );
-			}
+                  // Execute the appropriate callbacks
+                  jqXHR.always( map[ jqXHR.status ] );
+                } else {
 
-			// Complete
-			completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
+                  // Lazy-add the new callbacks in a way that preserves old ones
+                  for ( code in map ) {
+                    statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                  }
+                }
+              }
+              return this;
+            },
 
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
-				// Handle the global AJAX counter
-				if ( !( --jQuery.active ) ) {
-					jQuery.event.trigger( "ajaxStop" );
-				}
-			}
-		}
+            // Cancel the request
+            abort: function( statusText ) {
+              var finalText = statusText || strAbort;
+              if ( transport ) {
+                transport.abort( finalText );
+              }
+              done( 0, finalText );
+              return this;
+            }
+          };
 
-		// Attach deferreds
-		deferred.promise( jqXHR );
-		jqXHR.success = jqXHR.done;
-		jqXHR.error = jqXHR.fail;
-		jqXHR.complete = completeDeferred.done;
+      // Attach deferreds
+      deferred.promise( jqXHR );
 
-		// Status-dependent callbacks
-		jqXHR.statusCode = function( map ) {
-			if ( map ) {
-				var tmp;
-				if ( state < 2 ) {
-					for( tmp in map ) {
-						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
-					}
-				} else {
-					tmp = map[ jqXHR.status ];
-					jqXHR.then( tmp, tmp );
-				}
-			}
-			return this;
-		};
+      // Add protocol if not provided (prefilters might expect it)
+      // Handle falsy url in the settings object (#10093: consistency with old signature)
+      // We also use the url parameter if available
+      s.url = ( ( url || s.url || location.href ) + "" )
+          .replace( rprotocol, location.protocol + "//" );
 
-		// Remove hash character (#7531: and string promotion)
-		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
-		// We also use the url parameter if available
-		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+      // Alias method option to type as per ticket #12004
+      s.type = options.method || options.type || s.method || s.type;
 
-		// Extract dataTypes list
-		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+      // Extract dataTypes list
+      s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
 
-		// Determine if a cross-domain request is in order
-		if ( s.crossDomain == null ) {
-			parts = rurl.exec( s.url.toLowerCase() );
-			s.crossDomain = !!( parts &&
-				( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
-					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
-						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
-			);
-		}
+      // A cross-domain request is in order when the origin doesn't match the current origin.
+      if ( s.crossDomain == null ) {
+        urlAnchor = document.createElement( "a" );
 
-		// Convert data if not already a string
-		if ( s.data && s.processData && typeof s.data !== "string" ) {
-			s.data = jQuery.param( s.data, s.traditional );
-		}
+        // Support: IE <=8 - 11, Edge 12 - 15
+        // IE throws exception on accessing the href property if url is malformed,
+        // e.g. http://example.com:80x/
+        try {
+          urlAnchor.href = s.url;
 
-		// Apply prefilters
-		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+          // Support: IE <=8 - 11 only
+          // Anchor's host property isn't correctly set when s.url is relative
+          urlAnchor.href = urlAnchor.href;
+          s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
+              urlAnchor.protocol + "//" + urlAnchor.host;
+        } catch ( e ) {
+
+          // If there is an error parsing the URL, assume it is crossDomain,
+          // it can be rejected by the transport if it is invalid
+          s.crossDomain = true;
+        }
+      }
+
+      // Convert data if not already a string
+      if ( s.data && s.processData && typeof s.data !== "string" ) {
+        s.data = jQuery.param( s.data, s.traditional );
+      }
+
+      // Apply prefilters
+      inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+      // If request was aborted inside a prefilter, stop there
+      if ( completed ) {
+        return jqXHR;
+      }
+
+      // We can fire global events as of now if asked to
+      // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+      fireGlobals = jQuery.event && s.global;
+
+      // Watch for a new set of requests
+      if ( fireGlobals && jQuery.active++ === 0 ) {
+        jQuery.event.trigger( "ajaxStart" );
+      }
+
+      // Uppercase the type
+      s.type = s.type.toUpperCase();
+
+      // Determine if request has content
+      s.hasContent = !rnoContent.test( s.type );
+
+      // Save the URL in case we're toying with the If-Modified-Since
+      // and/or If-None-Match header later on
+      // Remove hash to simplify url manipulation
+      cacheURL = s.url.replace( rhash, "" );
+
+      // More options handling for requests with no content
+      if ( !s.hasContent ) {
+
+        // Remember the hash so we can put it back
+        uncached = s.url.slice( cacheURL.length );
+
+        // If data is available and should be processed, append data to url
+        if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
+          cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
+
+          // #9682: remove data so that it's not used in an eventual retry
+          delete s.data;
+        }
+
+        // Add or update anti-cache param if needed
+        if ( s.cache === false ) {
+          cacheURL = cacheURL.replace( rantiCache, "$1" );
+          uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
+        }
+
+        // Put hash and anti-cache on the URL that will be requested (gh-1732)
+        s.url = cacheURL + uncached;
+
+        // Change '%20' to '+' if this is encoded form body content (gh-2658)
+      } else if ( s.data && s.processData &&
+          ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
+        s.data = s.data.replace( r20, "+" );
+      }
+
+      // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+      if ( s.ifModified ) {
+        if ( jQuery.lastModified[ cacheURL ] ) {
+          jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+        }
+        if ( jQuery.etag[ cacheURL ] ) {
+          jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+        }
+      }
+
+      // Set the correct header, if data is being sent
+      if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+        jqXHR.setRequestHeader( "Content-Type", s.contentType );
+      }
+
+      // Set the Accepts header for the server, depending on the dataType
+      jqXHR.setRequestHeader(
+          "Accept",
+          s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
+              s.accepts[ s.dataTypes[ 0 ] ] +
+              ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+              s.accepts[ "*" ]
+      );
+
+      // Check for headers option
+      for ( i in s.headers ) {
+        jqXHR.setRequestHeader( i, s.headers[ i ] );
+      }
+
+      // Allow custom headers/mimetypes and early abort
+      if ( s.beforeSend &&
+          ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
+
+        // Abort if not done already and return
+        return jqXHR.abort();
+      }
+
+      // Aborting is no longer a cancellation
+      strAbort = "abort";
+
+      // Install callbacks on deferreds
+      completeDeferred.add( s.complete );
+      jqXHR.done( s.success );
+      jqXHR.fail( s.error );
+
+      // Get transport
+      transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+      // If no transport, we auto-abort
+      if ( !transport ) {
+        done( -1, "No Transport" );
+      } else {
+        jqXHR.readyState = 1;
+
+        // Send global event
+        if ( fireGlobals ) {
+          globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+        }
+
+        // If request was aborted inside ajaxSend, stop there
+        if ( completed ) {
+          return jqXHR;
+        }
+
+        // Timeout
+        if ( s.async && s.timeout > 0 ) {
+          timeoutTimer = window.setTimeout( function() {
+            jqXHR.abort( "timeout" );
+          }, s.timeout );
+        }
+
+        try {
+          completed = false;
+          transport.send( requestHeaders, done );
+        } catch ( e ) {
+
+          // Rethrow post-completion exceptions
+          if ( completed ) {
+            throw e;
+          }
+
+          // Propagate others as results
+          done( -1, e );
+        }
+      }
+
+      // Callback for when everything is done
+      function done( status, nativeStatusText, responses, headers ) {
+        var isSuccess, success, error, response, modified,
+            statusText = nativeStatusText;
+
+        // Ignore repeat invocations
+        if ( completed ) {
+          return;
+        }
+
+        completed = true;
+
+        // Clear timeout if it exists
+        if ( timeoutTimer ) {
+          window.clearTimeout( timeoutTimer );
+        }
+
+        // Dereference transport for early garbage collection
+        // (no matter how long the jqXHR object will be used)
+        transport = undefined;
+
+        // Cache response headers
+        responseHeadersString = headers || "";
+
+        // Set readyState
+        jqXHR.readyState = status > 0 ? 4 : 0;
+
+        // Determine if successful
+        isSuccess = status >= 200 && status < 300 || status === 304;
+
+        // Get response data
+        if ( responses ) {
+          response = ajaxHandleResponses( s, jqXHR, responses );
+        }
+
+        // Convert no matter what (that way responseXXX fields are always set)
+        response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+        // If successful, handle type chaining
+        if ( isSuccess ) {
+
+          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+          if ( s.ifModified ) {
+            modified = jqXHR.getResponseHeader( "Last-Modified" );
+            if ( modified ) {
+              jQuery.lastModified[ cacheURL ] = modified;
+            }
+            modified = jqXHR.getResponseHeader( "etag" );
+            if ( modified ) {
+              jQuery.etag[ cacheURL ] = modified;
+            }
+          }
+
+          // if no content
+          if ( status === 204 || s.type === "HEAD" ) {
+            statusText = "nocontent";
 
-		// If request was aborted inside a prefiler, stop there
-		if ( state === 2 ) {
-			return false;
-		}
+            // if not modified
+          } else if ( status === 304 ) {
+            statusText = "notmodified";
 
-		// We can fire global events as of now if asked to
-		fireGlobals = s.global;
+            // If we have data, let's convert it
+          } else {
+            statusText = response.state;
+            success = response.data;
+            error = response.error;
+            isSuccess = !error;
+          }
+        } else {
 
-		// Uppercase the type
-		s.type = s.type.toUpperCase();
+          // Extract error from statusText and normalize for non-aborts
+          error = statusText;
+          if ( status || !statusText ) {
+            statusText = "error";
+            if ( status < 0 ) {
+              status = 0;
+            }
+          }
+        }
 
-		// Determine if request has content
-		s.hasContent = !rnoContent.test( s.type );
+        // Set data for the fake xhr object
+        jqXHR.status = status;
+        jqXHR.statusText = ( nativeStatusText || statusText ) + "";
 
-		// Watch for a new set of requests
-		if ( fireGlobals && jQuery.active++ === 0 ) {
-			jQuery.event.trigger( "ajaxStart" );
-		}
+        // Success/Error
+        if ( isSuccess ) {
+          deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+        } else {
+          deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+        }
 
-		// More options handling for requests with no content
-		if ( !s.hasContent ) {
+        // Status-dependent callbacks
+        jqXHR.statusCode( statusCode );
+        statusCode = undefined;
 
-			// If data is available, append data to url
-			if ( s.data ) {
-				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
-				// #9682: remove data so that it's not used in an eventual retry
-				delete s.data;
-			}
+        if ( fireGlobals ) {
+          globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+              [ jqXHR, s, isSuccess ? success : error ] );
+        }
 
-			// Get ifModifiedKey before adding the anti-cache parameter
-			ifModifiedKey = s.url;
+        // Complete
+        completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
 
-			// Add anti-cache in url if needed
-			if ( s.cache === false ) {
+        if ( fireGlobals ) {
+          globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
 
-				var ts = jQuery.now(),
-					// try replacing _= if it is there
-					ret = s.url.replace( rts, "$1_=" + ts );
+          // Handle the global AJAX counter
+          if ( !( --jQuery.active ) ) {
+            jQuery.event.trigger( "ajaxStop" );
+          }
+        }
+      }
 
-				// if nothing was replaced, add timestamp to the end
-				s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
-			}
-		}
+      return jqXHR;
+    },
 
-		// Set the correct header, if data is being sent
-		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-			jqXHR.setRequestHeader( "Content-Type", s.contentType );
-		}
+    getJSON: function( url, data, callback ) {
+      return jQuery.get( url, data, callback, "json" );
+    },
 
-		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-		if ( s.ifModified ) {
-			ifModifiedKey = ifModifiedKey || s.url;
-			if ( jQuery.lastModified[ ifModifiedKey ] ) {
-				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
-			}
-			if ( jQuery.etag[ ifModifiedKey ] ) {
-				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
-			}
-		}
+    getScript: function( url, callback ) {
+      return jQuery.get( url, undefined, callback, "script" );
+    }
+  } );
 
-		// Set the Accepts header for the server, depending on the dataType
-		jqXHR.setRequestHeader(
-			"Accept",
-			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
-				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
-				s.accepts[ "*" ]
-		);
+  jQuery.each( [ "get", "post" ], function( i, method ) {
+    jQuery[ method ] = function( url, data, callback, type ) {
 
-		// Check for headers option
-		for ( i in s.headers ) {
-			jqXHR.setRequestHeader( i, s.headers[ i ] );
-		}
+      // Shift arguments if data argument was omitted
+      if ( isFunction( data ) ) {
+        type = type || callback;
+        callback = data;
+        data = undefined;
+      }
 
-		// Allow custom headers/mimetypes and early abort
-		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
-				// Abort if not done already
-				jqXHR.abort();
-				return false;
+      // The url can be an options object (which then must have .url)
+      return jQuery.ajax( jQuery.extend( {
+        url: url,
+        type: method,
+        dataType: type,
+        data: data,
+        success: callback
+      }, jQuery.isPlainObject( url ) && url ) );
+    };
+  } );
 
-		}
 
-		// Install callbacks on deferreds
-		for ( i in { success: 1, error: 1, complete: 1 } ) {
-			jqXHR[ i ]( s[ i ] );
-		}
+  jQuery._evalUrl = function( url ) {
+    return jQuery.ajax( {
+      url: url,
 
-		// Get transport
-		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+      // Make this explicit, since user can override this through ajaxSetup (#11264)
+      type: "GET",
+      dataType: "script",
+      cache: true,
+      async: false,
+      global: false,
+      "throws": true
+    } );
+  };
 
-		// If no transport, we auto-abort
-		if ( !transport ) {
-			done( -1, "No Transport" );
-		} else {
-			jqXHR.readyState = 1;
-			// Send global event
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
-			}
-			// Timeout
-			if ( s.async && s.timeout > 0 ) {
-				timeoutTimer = setTimeout( function(){
-					jqXHR.abort( "timeout" );
-				}, s.timeout );
-			}
 
-			try {
-				state = 1;
-				transport.send( requestHeaders, done );
-			} catch (e) {
-				// Propagate exception as error if not done
-				if ( state < 2 ) {
-					done( -1, e );
-				// Simply rethrow otherwise
-				} else {
-					jQuery.error( e );
-				}
-			}
-		}
+  jQuery.fn.extend( {
+    wrapAll: function( html ) {
+      var wrap;
 
-		return jqXHR;
-	},
+      if ( this[ 0 ] ) {
+        if ( isFunction( html ) ) {
+          html = html.call( this[ 0 ] );
+        }
 
-	// Serialize an array of form elements or a set of
-	// key/values into a query string
-	param: function( a, traditional ) {
-		var s = [],
-			add = function( key, value ) {
-				// If value is a function, invoke it and return its value
-				value = jQuery.isFunction( value ) ? value() : value;
-				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
-			};
+        // The elements to wrap the target around
+        wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
 
-		// Set traditional to true for jQuery <= 1.3.2 behavior.
-		if ( traditional === undefined ) {
-			traditional = jQuery.ajaxSettings.traditional;
-		}
+        if ( this[ 0 ].parentNode ) {
+          wrap.insertBefore( this[ 0 ] );
+        }
 
-		// If an array was passed in, assume that it is an array of form elements.
-		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-			// Serialize the form elements
-			jQuery.each( a, function() {
-				add( this.name, this.value );
-			});
+        wrap.map( function() {
+          var elem = this;
 
-		} else {
-			// If traditional, encode the "old" way (the way 1.3.2 or older
-			// did it), otherwise encode params recursively.
-			for ( var prefix in a ) {
-				buildParams( prefix, a[ prefix ], traditional, add );
-			}
-		}
+          while ( elem.firstElementChild ) {
+            elem = elem.firstElementChild;
+          }
 
-		// Return the resulting serialization
-		return s.join( "&" ).replace( r20, "+" );
-	}
-});
+          return elem;
+        } ).append( this );
+      }
 
-function buildParams( prefix, obj, traditional, add ) {
-	if ( jQuery.isArray( obj ) ) {
-		// Serialize array item.
-		jQuery.each( obj, function( i, v ) {
-			if ( traditional || rbracket.test( prefix ) ) {
-				// Treat each array item as a scalar.
-				add( prefix, v );
+      return this;
+    },
 
-			} else {
-				// If array item is non-scalar (array or object), encode its
-				// numeric index to resolve deserialization ambiguity issues.
-				// Note that rack (as of 1.0.0) can't currently deserialize
-				// nested arrays properly, and attempting to do so may cause
-				// a server error. Possible fixes are to modify rack's
-				// deserialization algorithm or to provide an option or flag
-				// to force array serialization to be shallow.
-				buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
-			}
-		});
+    wrapInner: function( html ) {
+      if ( isFunction( html ) ) {
+        return this.each( function( i ) {
+          jQuery( this ).wrapInner( html.call( this, i ) );
+        } );
+      }
 
-	} else if ( !traditional && obj != null && typeof obj === "object" ) {
-		// Serialize object item.
-		for ( var name in obj ) {
-			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-		}
+      return this.each( function() {
+        var self = jQuery( this ),
+            contents = self.contents();
 
-	} else {
-		// Serialize scalar item.
-		add( prefix, obj );
-	}
-}
+        if ( contents.length ) {
+          contents.wrapAll( html );
 
-// This is still on the jQuery object... for now
-// Want to move this to jQuery.ajax some day
-jQuery.extend({
+        } else {
+          self.append( html );
+        }
+      } );
+    },
 
-	// Counter for holding the number of active queries
-	active: 0,
+    wrap: function( html ) {
+      var htmlIsFunction = isFunction( html );
 
-	// Last-Modified header cache for next request
-	lastModified: {},
-	etag: {}
+      return this.each( function( i ) {
+        jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
+      } );
+    },
 
-});
+    unwrap: function( selector ) {
+      this.parent( selector ).not( "body" ).each( function() {
+        jQuery( this ).replaceWith( this.childNodes );
+      } );
+      return this;
+    }
+  } );
 
-/* Handles responses to an ajax request:
- * - sets all responseXXX fields accordingly
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
 
-	var contents = s.contents,
-		dataTypes = s.dataTypes,
-		responseFields = s.responseFields,
-		ct,
-		type,
-		finalDataType,
-		firstDataType;
+  jQuery.expr.pseudos.hidden = function( elem ) {
+    return !jQuery.expr.pseudos.visible( elem );
+  };
+  jQuery.expr.pseudos.visible = function( elem ) {
+    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
+  };
 
-	// Fill responseXXX fields
-	for( type in responseFields ) {
-		if ( type in responses ) {
-			jqXHR[ responseFields[type] ] = responses[ type ];
-		}
-	}
 
-	// Remove auto dataType and get content-type in the process
-	while( dataTypes[ 0 ] === "*" ) {
-		dataTypes.shift();
-		if ( ct === undefined ) {
-			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
-		}
-	}
 
-	// Check if we're dealing with a known content-type
-	if ( ct ) {
-		for ( type in contents ) {
-			if ( contents[ type ] && contents[ type ].test( ct ) ) {
-				dataTypes.unshift( type );
-				break;
-			}
-		}
-	}
 
-	// Check to see if we have a response for the expected dataType
-	if ( dataTypes[ 0 ] in responses ) {
-		finalDataType = dataTypes[ 0 ];
-	} else {
-		// Try convertible dataTypes
-		for ( type in responses ) {
-			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
-				finalDataType = type;
-				break;
-			}
-			if ( !firstDataType ) {
-				firstDataType = type;
-			}
-		}
-		// Or just use first one
-		finalDataType = finalDataType || firstDataType;
-	}
+  jQuery.ajaxSettings.xhr = function() {
+    try {
+      return new window.XMLHttpRequest();
+    } catch ( e ) {}
+  };
 
-	// If we found a dataType
-	// We add the dataType to the list if needed
-	// and return the corresponding response
-	if ( finalDataType ) {
-		if ( finalDataType !== dataTypes[ 0 ] ) {
-			dataTypes.unshift( finalDataType );
-		}
-		return responses[ finalDataType ];
-	}
-}
+  var xhrSuccessStatus = {
 
-// Chain conversions given the request and the original response
-function ajaxConvert( s, response ) {
+        // File protocol always yields status code 0, assume 200
+        0: 200,
 
-	// Apply the dataFilter if provided
-	if ( s.dataFilter ) {
-		response = s.dataFilter( response, s.dataType );
-	}
+        // Support: IE <=9 only
+        // #1450: sometimes IE returns 1223 when it should be 204
+        1223: 204
+      },
+      xhrSupported = jQuery.ajaxSettings.xhr();
 
-	var dataTypes = s.dataTypes,
-		converters = {},
-		i,
-		key,
-		length = dataTypes.length,
-		tmp,
-		// Current and previous dataTypes
-		current = dataTypes[ 0 ],
-		prev,
-		// Conversion expression
-		conversion,
-		// Conversion function
-		conv,
-		// Conversion functions (transitive conversion)
-		conv1,
-		conv2;
+  support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+  support.ajax = xhrSupported = !!xhrSupported;
 
-	// For each dataType in the chain
-	for( i = 1; i < length; i++ ) {
+  jQuery.ajaxTransport( function( options ) {
+    var callback, errorCallback;
 
-		// Create converters map
-		// with lowercased keys
-		if ( i === 1 ) {
-			for( key in s.converters ) {
-				if( typeof key === "string" ) {
-					converters[ key.toLowerCase() ] = s.converters[ key ];
-				}
-			}
-		}
+    // Cross domain only allowed if supported through XMLHttpRequest
+    if ( support.cors || xhrSupported && !options.crossDomain ) {
+      return {
+        send: function( headers, complete ) {
+          var i,
+              xhr = options.xhr();
 
-		// Get the dataTypes
-		prev = current;
-		current = dataTypes[ i ];
+          xhr.open(
+              options.type,
+              options.url,
+              options.async,
+              options.username,
+              options.password
+          );
 
-		// If current is auto dataType, update it to prev
-		if( current === "*" ) {
-			current = prev;
-		// If no auto and dataTypes are actually different
-		} else if ( prev !== "*" && prev !== current ) {
+          // Apply custom fields if provided
+          if ( options.xhrFields ) {
+            for ( i in options.xhrFields ) {
+              xhr[ i ] = options.xhrFields[ i ];
+            }
+          }
 
-			// Get the converter
-			conversion = prev + " " + current;
-			conv = converters[ conversion ] || converters[ "* " + current ];
+          // Override mime type if needed
+          if ( options.mimeType && xhr.overrideMimeType ) {
+            xhr.overrideMimeType( options.mimeType );
+          }
 
-			// If there is no direct converter, search transitively
-			if ( !conv ) {
-				conv2 = undefined;
-				for( conv1 in converters ) {
-					tmp = conv1.split( " " );
-					if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
-						conv2 = converters[ tmp[1] + " " + current ];
-						if ( conv2 ) {
-							conv1 = converters[ conv1 ];
-							if ( conv1 === true ) {
-								conv = conv2;
-							} else if ( conv2 === true ) {
-								conv = conv1;
-							}
-							break;
-						}
-					}
-				}
-			}
-			// If we found no converter, dispatch an error
-			if ( !( conv || conv2 ) ) {
-				jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
-			}
-			// If found converter is not an equivalence
-			if ( conv !== true ) {
-				// Convert with 1 or 2 converters accordingly
-				response = conv ? conv( response ) : conv2( conv1(response) );
-			}
-		}
-	}
-	return response;
-}
+          // X-Requested-With header
+          // For cross-domain requests, seeing as conditions for a preflight are
+          // akin to a jigsaw puzzle, we simply never set it to be sure.
+          // (it can always be set on a per-request basis or even using ajaxSetup)
+          // For same-domain requests, won't change header if already provided.
+          if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
+            headers[ "X-Requested-With" ] = "XMLHttpRequest";
+          }
 
+          // Set headers
+          for ( i in headers ) {
+            xhr.setRequestHeader( i, headers[ i ] );
+          }
 
+          // Callback
+          callback = function( type ) {
+            return function() {
+              if ( callback ) {
+                callback = errorCallback = xhr.onload =
+                    xhr.onerror = xhr.onabort = xhr.ontimeout =
+                        xhr.onreadystatechange = null;
 
+                if ( type === "abort" ) {
+                  xhr.abort();
+                } else if ( type === "error" ) {
 
-var jsc = jQuery.now(),
-	jsre = /(\=)\?(&|$)|\?\?/i;
+                  // Support: IE <=9 only
+                  // On a manual native abort, IE9 throws
+                  // errors on any property access that is not readyState
+                  if ( typeof xhr.status !== "number" ) {
+                    complete( 0, "error" );
+                  } else {
+                    complete(
 
-// Default jsonp settings
-jQuery.ajaxSetup({
-	jsonp: "callback",
-	jsonpCallback: function() {
-		return jQuery.expando + "_" + ( jsc++ );
-	}
-});
+                        // File: protocol always yields status 0; see #8605, #14207
+                        xhr.status,
+                        xhr.statusText
+                    );
+                  }
+                } else {
+                  complete(
+                      xhrSuccessStatus[ xhr.status ] || xhr.status,
+                      xhr.statusText,
 
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+                      // Support: IE <=9 only
+                      // IE9 has no XHR2 but throws on binary (trac-11426)
+                      // For XHR2 non-text, let the caller handle it (gh-2498)
+                      ( xhr.responseType || "text" ) !== "text"  ||
+                      typeof xhr.responseText !== "string" ?
+                          { binary: xhr.response } :
+                          { text: xhr.responseText },
+                      xhr.getAllResponseHeaders()
+                  );
+                }
+              }
+            };
+          };
 
-	var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
-		( typeof s.data === "string" );
+          // Listen to events
+          xhr.onload = callback();
+          errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
 
-	if ( s.dataTypes[ 0 ] === "jsonp" ||
-		s.jsonp !== false && ( jsre.test( s.url ) ||
-				inspectData && jsre.test( s.data ) ) ) {
+          // Support: IE 9 only
+          // Use onreadystatechange to replace onabort
+          // to handle uncaught aborts
+          if ( xhr.onabort !== undefined ) {
+            xhr.onabort = errorCallback;
+          } else {
+            xhr.onreadystatechange = function() {
 
-		var responseContainer,
-			jsonpCallback = s.jsonpCallback =
-				jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
-			previous = window[ jsonpCallback ],
-			url = s.url,
-			data = s.data,
-			replace = "$1" + jsonpCallback + "$2";
+              // Check readyState before timeout as it changes
+              if ( xhr.readyState === 4 ) {
 
-		if ( s.jsonp !== false ) {
-			url = url.replace( jsre, replace );
-			if ( s.url === url ) {
-				if ( inspectData ) {
-					data = data.replace( jsre, replace );
-				}
-				if ( s.data === data ) {
-					// Add callback manually
-					url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
-				}
-			}
-		}
+                // Allow onerror to be called first,
+                // but that will not handle a native abort
+                // Also, save errorCallback to a variable
+                // as xhr.onerror cannot be accessed
+                window.setTimeout( function() {
+                  if ( callback ) {
+                    errorCallback();
+                  }
+                } );
+              }
+            };
+          }
 
-		s.url = url;
-		s.data = data;
+          // Create the abort callback
+          callback = callback( "abort" );
 
-		// Install callback
-		window[ jsonpCallback ] = function( response ) {
-			responseContainer = [ response ];
-		};
+          try {
 
-		// Clean-up function
-		jqXHR.always(function() {
-			// Set callback back to previous value
-			window[ jsonpCallback ] = previous;
-			// Call if it was a function and we have a response
-			if ( responseContainer && jQuery.isFunction( previous ) ) {
-				window[ jsonpCallback ]( responseContainer[ 0 ] );
-			}
-		});
+            // Do send the request (this may raise an exception)
+            xhr.send( options.hasContent && options.data || null );
+          } catch ( e ) {
 
-		// Use data converter to retrieve json after script execution
-		s.converters["script json"] = function() {
-			if ( !responseContainer ) {
-				jQuery.error( jsonpCallback + " was not called" );
-			}
-			return responseContainer[ 0 ];
-		};
+            // #14683: Only rethrow if this hasn't been notified as an error yet
+            if ( callback ) {
+              throw e;
+            }
+          }
+        },
 
-		// force json dataType
-		s.dataTypes[ 0 ] = "json";
+        abort: function() {
+          if ( callback ) {
+            callback();
+          }
+        }
+      };
+    }
+  } );
 
-		// Delegate to script
-		return "script";
-	}
-});
 
 
 
+// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
+  jQuery.ajaxPrefilter( function( s ) {
+    if ( s.crossDomain ) {
+      s.contents.script = false;
+    }
+  } );
 
 // Install script dataType
-jQuery.ajaxSetup({
-	accepts: {
-		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
-	},
-	contents: {
-		script: /javascript|ecmascript/
-	},
-	converters: {
-		"text script": function( text ) {
-			jQuery.globalEval( text );
-			return text;
-		}
-	}
-});
+  jQuery.ajaxSetup( {
+    accepts: {
+      script: "text/javascript, application/javascript, " +
+          "application/ecmascript, application/x-ecmascript"
+    },
+    contents: {
+      script: /\b(?:java|ecma)script\b/
+    },
+    converters: {
+      "text script": function( text ) {
+        jQuery.globalEval( text );
+        return text;
+      }
+    }
+  } );
 
-// Handle cache's special case and global
-jQuery.ajaxPrefilter( "script", function( s ) {
-	if ( s.cache === undefined ) {
-		s.cache = false;
-	}
-	if ( s.crossDomain ) {
-		s.type = "GET";
-		s.global = false;
-	}
-});
+// Handle cache's special case and crossDomain
+  jQuery.ajaxPrefilter( "script", function( s ) {
+    if ( s.cache === undefined ) {
+      s.cache = false;
+    }
+    if ( s.crossDomain ) {
+      s.type = "GET";
+    }
+  } );
 
 // Bind script tag hack transport
-jQuery.ajaxTransport( "script", function(s) {
+  jQuery.ajaxTransport( "script", function( s ) {
 
-	// This transport only deals with cross domain requests
-	if ( s.crossDomain ) {
+    // This transport only deals with cross domain requests
+    if ( s.crossDomain ) {
+      var script, callback;
+      return {
+        send: function( _, complete ) {
+          script = jQuery( "<script>" ).prop( {
+            charset: s.scriptCharset,
+            src: s.url
+          } ).on(
+              "load error",
+              callback = function( evt ) {
+                script.remove();
+                callback = null;
+                if ( evt ) {
+                  complete( evt.type === "error" ? 404 : 200, evt.type );
+                }
+              }
+          );
 
-		var script,
-			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+          // Use native DOM manipulation to avoid our domManip AJAX trickery
+          document.head.appendChild( script[ 0 ] );
+        },
+        abort: function() {
+          if ( callback ) {
+            callback();
+          }
+        }
+      };
+    }
+  } );
 
-		return {
 
-			send: function( _, callback ) {
 
-				script = document.createElement( "script" );
 
-				script.async = "async";
+  var oldCallbacks = [],
+      rjsonp = /(=)\?(?=&|$)|\?\?/;
 
-				if ( s.scriptCharset ) {
-					script.charset = s.scriptCharset;
-				}
+// Default jsonp settings
+  jQuery.ajaxSetup( {
+    jsonp: "callback",
+    jsonpCallback: function() {
+      var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+      this[ callback ] = true;
+      return callback;
+    }
+  } );
 
-				script.src = s.url;
+// Detect, normalize options and install callbacks for jsonp requests
+  jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
 
-				// Attach handlers for all browsers
-				script.onload = script.onreadystatechange = function( _, isAbort ) {
+    var callbackName, overwritten, responseContainer,
+        jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+                "url" :
+                typeof s.data === "string" &&
+                ( s.contentType || "" )
+                    .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
+                rjsonp.test( s.data ) && "data"
+        );
 
-					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+    // Handle iff the expected data type is "jsonp" or we have a parameter to set
+    if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
 
-						// Handle memory leak in IE
-						script.onload = script.onreadystatechange = null;
+      // Get callback name, remembering preexisting value associated with it
+      callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
+          s.jsonpCallback() :
+          s.jsonpCallback;
 
-						// Remove the script
-						if ( head && script.parentNode ) {
-							head.removeChild( script );
-						}
+      // Insert callback into url or form data
+      if ( jsonProp ) {
+        s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+      } else if ( s.jsonp !== false ) {
+        s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+      }
 
-						// Dereference the script
-						script = undefined;
+      // Use data converter to retrieve json after script execution
+      s.converters[ "script json" ] = function() {
+        if ( !responseContainer ) {
+          jQuery.error( callbackName + " was not called" );
+        }
+        return responseContainer[ 0 ];
+      };
 
-						// Callback if not abort
-						if ( !isAbort ) {
-							callback( 200, "success" );
-						}
-					}
-				};
-				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
-				// This arises when a base node is used (#2709 and #4378).
-				head.insertBefore( script, head.firstChild );
-			},
+      // Force json dataType
+      s.dataTypes[ 0 ] = "json";
 
-			abort: function() {
-				if ( script ) {
-					script.onload( 0, 1 );
-				}
-			}
-		};
-	}
-});
+      // Install callback
+      overwritten = window[ callbackName ];
+      window[ callbackName ] = function() {
+        responseContainer = arguments;
+      };
 
+      // Clean-up function (fires after converters)
+      jqXHR.always( function() {
 
+        // If previous value didn't exist - remove it
+        if ( overwritten === undefined ) {
+          jQuery( window ).removeProp( callbackName );
 
+          // Otherwise restore preexisting value
+        } else {
+          window[ callbackName ] = overwritten;
+        }
 
-var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
-	xhrOnUnloadAbort = window.ActiveXObject ? function() {
-		// Abort all pending requests
-		for ( var key in xhrCallbacks ) {
-			xhrCallbacks[ key ]( 0, 1 );
-		}
-	} : false,
-	xhrId = 0,
-	xhrCallbacks;
+        // Save back as free
+        if ( s[ callbackName ] ) {
 
-// Functions to create xhrs
-function createStandardXHR() {
-	try {
-		return new window.XMLHttpRequest();
-	} catch( e ) {}
-}
+          // Make sure that re-using the options doesn't screw things around
+          s.jsonpCallback = originalSettings.jsonpCallback;
 
-function createActiveXHR() {
-	try {
-		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
-	} catch( e ) {}
-}
+          // Save the callback name for future use
+          oldCallbacks.push( callbackName );
+        }
 
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject ?
-	/* Microsoft failed to properly
-	 * implement the XMLHttpRequest in IE7 (can't request local files),
-	 * so we use the ActiveXObject when it is available
-	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
-	 * we need a fallback.
-	 */
-	function() {
-		return !this.isLocal && createStandardXHR() || createActiveXHR();
-	} :
-	// For all other browsers, use the standard XMLHttpRequest object
-	createStandardXHR;
+        // Call if it was a function and we have a response
+        if ( responseContainer && isFunction( overwritten ) ) {
+          overwritten( responseContainer[ 0 ] );
+        }
 
-// Determine support properties
-(function( xhr ) {
-	jQuery.extend( jQuery.support, {
-		ajax: !!xhr,
-		cors: !!xhr && ( "withCredentials" in xhr )
-	});
-})( jQuery.ajaxSettings.xhr() );
+        responseContainer = overwritten = undefined;
+      } );
 
-// Create transport if the browser can provide an xhr
-if ( jQuery.support.ajax ) {
+      // Delegate to script
+      return "script";
+    }
+  } );
 
-	jQuery.ajaxTransport(function( s ) {
-		// Cross domain only allowed if supported through XMLHttpRequest
-		if ( !s.crossDomain || jQuery.support.cors ) {
 
-			var callback;
 
-			return {
-				send: function( headers, complete ) {
 
-					// Get a new xhr
-					var xhr = s.xhr(),
-						handle,
-						i;
+// Support: Safari 8 only
+// In Safari 8 documents created via document.implementation.createHTMLDocument
+// collapse sibling forms: the second one becomes a child of the first one.
+// Because of that, this security measure has to be disabled in Safari 8.
+// https://bugs.webkit.org/show_bug.cgi?id=137337
+  support.createHTMLDocument = ( function() {
+    var body = document.implementation.createHTMLDocument( "" ).body;
+    body.innerHTML = "<form></form><form></form>";
+    return body.childNodes.length === 2;
+  } )();
 
-					// Open the socket
-					// Passing null username, generates a login popup on Opera (#2865)
-					if ( s.username ) {
-						xhr.open( s.type, s.url, s.async, s.username, s.password );
-					} else {
-						xhr.open( s.type, s.url, s.async );
-					}
 
-					// Apply custom fields if provided
-					if ( s.xhrFields ) {
-						for ( i in s.xhrFields ) {
-							xhr[ i ] = s.xhrFields[ i ];
-						}
-					}
+// Argument "data" should be string of html
+// context (optional): If specified, the fragment will be created in this context,
+// defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+  jQuery.parseHTML = function( data, context, keepScripts ) {
+    if ( typeof data !== "string" ) {
+      return [];
+    }
+    if ( typeof context === "boolean" ) {
+      keepScripts = context;
+      context = false;
+    }
 
-					// Override mime type if needed
-					if ( s.mimeType && xhr.overrideMimeType ) {
-						xhr.overrideMimeType( s.mimeType );
-					}
+    var base, parsed, scripts;
 
-					// X-Requested-With header
-					// For cross-domain requests, seeing as conditions for a preflight are
-					// akin to a jigsaw puzzle, we simply never set it to be sure.
-					// (it can always be set on a per-request basis or even using ajaxSetup)
-					// For same-domain requests, won't change header if already provided.
-					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
-						headers[ "X-Requested-With" ] = "XMLHttpRequest";
-					}
+    if ( !context ) {
 
-					// Need an extra try/catch for cross domain requests in Firefox 3
-					try {
-						for ( i in headers ) {
-							xhr.setRequestHeader( i, headers[ i ] );
-						}
-					} catch( _ ) {}
+      // Stop scripts or inline event handlers from being executed immediately
+      // by using document.implementation
+      if ( support.createHTMLDocument ) {
+        context = document.implementation.createHTMLDocument( "" );
 
-					// Do send the request
-					// This may raise an exception which is actually
-					// handled in jQuery.ajax (so no try/catch here)
-					xhr.send( ( s.hasContent && s.data ) || null );
+        // Set the base href for the created document
+        // so any parsed elements with URLs
+        // are based on the document's URL (gh-2965)
+        base = context.createElement( "base" );
+        base.href = document.location.href;
+        context.head.appendChild( base );
+      } else {
+        context = document;
+      }
+    }
 
-					// Listener
-					callback = function( _, isAbort ) {
+    parsed = rsingleTag.exec( data );
+    scripts = !keepScripts && [];
 
-						var status,
-							statusText,
-							responseHeaders,
-							responses,
-							xml;
+    // Single tag
+    if ( parsed ) {
+      return [ context.createElement( parsed[ 1 ] ) ];
+    }
 
-						// Firefox throws exceptions when accessing properties
-						// of an xhr when a network error occured
-						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
-						try {
+    parsed = buildFragment( [ data ], context, scripts );
 
-							// Was never called and is aborted or complete
-							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+    if ( scripts && scripts.length ) {
+      jQuery( scripts ).remove();
+    }
 
-								// Only called once
-								callback = undefined;
+    return jQuery.merge( [], parsed.childNodes );
+  };
 
-								// Do not keep as active anymore
-								if ( handle ) {
-									xhr.onreadystatechange = jQuery.noop;
-									if ( xhrOnUnloadAbort ) {
-										delete xhrCallbacks[ handle ];
-									}
-								}
 
-								// If it's an abort
-								if ( isAbort ) {
-									// Abort it manually if needed
-									if ( xhr.readyState !== 4 ) {
-										xhr.abort();
-									}
-								} else {
-									status = xhr.status;
-									responseHeaders = xhr.getAllResponseHeaders();
-									responses = {};
-									xml = xhr.responseXML;
+  /**
+   * Load a url into a page
+   */
+  jQuery.fn.load = function( url, params, callback ) {
+    var selector, type, response,
+        self = this,
+        off = url.indexOf( " " );
 
-									// Construct response list
-									if ( xml && xml.documentElement /* #4958 */ ) {
-										responses.xml = xml;
-									}
-									responses.text = xhr.responseText;
+    if ( off > -1 ) {
+      selector = stripAndCollapse( url.slice( off ) );
+      url = url.slice( 0, off );
+    }
 
-									// Firefox throws an exception when accessing
-									// statusText for faulty cross-domain requests
-									try {
-										statusText = xhr.statusText;
-									} catch( e ) {
-										// We normalize with Webkit giving an empty statusText
-										statusText = "";
-									}
+    // If it's a function
+    if ( isFunction( params ) ) {
 
-									// Filter status for non standard behaviors
+      // We assume that it's the callback
+      callback = params;
+      params = undefined;
 
-									// If the request is local and we have data: assume a success
-									// (success with no data won't get notified, that's the best we
-									// can do given current implementations)
-									if ( !status && s.isLocal && !s.crossDomain ) {
-										status = responses.text ? 200 : 404;
-									// IE - #1450: sometimes returns 1223 when it should be 204
-									} else if ( status === 1223 ) {
-										status = 204;
-									}
-								}
-							}
-						} catch( firefoxAccessException ) {
-							if ( !isAbort ) {
-								complete( -1, firefoxAccessException );
-							}
-						}
+      // Otherwise, build a param string
+    } else if ( params && typeof params === "object" ) {
+      type = "POST";
+    }
 
-						// Call complete if needed
-						if ( responses ) {
-							complete( status, statusText, responses, responseHeaders );
-						}
-					};
+    // If we have elements to modify, make the request
+    if ( self.length > 0 ) {
+      jQuery.ajax( {
+        url: url,
 
-					// if we're in sync mode or it's in cache
-					// and has been retrieved directly (IE6 & IE7)
-					// we need to manually fire the callback
-					if ( !s.async || xhr.readyState === 4 ) {
-						callback();
-					} else {
-						handle = ++xhrId;
-						if ( xhrOnUnloadAbort ) {
-							// Create the active xhrs callbacks list if needed
-							// and attach the unload handler
-							if ( !xhrCallbacks ) {
-								xhrCallbacks = {};
-								jQuery( window ).unload( xhrOnUnloadAbort );
-							}
-							// Add to list of active xhrs callbacks
-							xhrCallbacks[ handle ] = callback;
-						}
-						xhr.onreadystatechange = callback;
-					}
-				},
+        // If "type" variable is undefined, then "GET" method will be used.
+        // Make value of this field explicit since
+        // user can override it through ajaxSetup method
+        type: type || "GET",
+        dataType: "html",
+        data: params
+      } ).done( function( responseText ) {
 
-				abort: function() {
-					if ( callback ) {
-						callback(0,1);
-					}
-				}
-			};
-		}
-	});
-}
+        // Save response for use in complete callback
+        response = arguments;
 
+        self.html( selector ?
 
+            // If a selector was specified, locate the right elements in a dummy div
+            // Exclude scripts to avoid IE 'Permission Denied' errors
+            jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
 
+            // Otherwise use the full result
+            responseText );
 
-var elemdisplay = {},
-	iframe, iframeDoc,
-	rfxtypes = /^(?:toggle|show|hide)$/,
-	rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
-	timerId,
-	fxAttrs = [
-		// height animations
-		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
-		// width animations
-		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
-		// opacity animations
-		[ "opacity" ]
-	],
-	fxNow;
+        // If the request succeeds, this function gets "data", "status", "jqXHR"
+        // but they are ignored because response was set above.
+        // If it fails, this function gets "jqXHR", "status", "error"
+      } ).always( callback && function( jqXHR, status ) {
+        self.each( function() {
+          callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
+        } );
+      } );
+    }
 
-jQuery.fn.extend({
-	show: function( speed, easing, callback ) {
-		var elem, display;
+    return this;
+  };
 
-		if ( speed || speed === 0 ) {
-			return this.animate( genFx("show", 3), speed, easing, callback);
 
-		} else {
-			for ( var i = 0, j = this.length; i < j; i++ ) {
-				elem = this[i];
 
-				if ( elem.style ) {
-					display = elem.style.display;
 
-					// Reset the inline display of this element to learn if it is
-					// being hidden by cascaded rules or not
-					if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
-						display = elem.style.display = "";
-					}
+// Attach a bunch of functions for handling common AJAX events
+  jQuery.each( [
+    "ajaxStart",
+    "ajaxStop",
+    "ajaxComplete",
+    "ajaxError",
+    "ajaxSuccess",
+    "ajaxSend"
+  ], function( i, type ) {
+    jQuery.fn[ type ] = function( fn ) {
+      return this.on( type, fn );
+    };
+  } );
 
-					// Set elements which have been overridden with display: none
-					// in a stylesheet to whatever the default browser style is
-					// for such an element
-					if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
-						jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
-					}
-				}
-			}
 
-			// Set the display of most of the elements in a second loop
-			// to avoid the constant reflow
-			for ( i = 0; i < j; i++ ) {
-				elem = this[i];
 
-				if ( elem.style ) {
-					display = elem.style.display;
 
-					if ( display === "" || display === "none" ) {
-						elem.style.display = jQuery._data(elem, "olddisplay") || "";
-					}
-				}
-			}
+  jQuery.expr.pseudos.animated = function( elem ) {
+    return jQuery.grep( jQuery.timers, function( fn ) {
+      return elem === fn.elem;
+    } ).length;
+  };
 
-			return this;
-		}
-	},
 
-	hide: function( speed, easing, callback ) {
-		if ( speed || speed === 0 ) {
-			return this.animate( genFx("hide", 3), speed, easing, callback);
 
-		} else {
-			for ( var i = 0, j = this.length; i < j; i++ ) {
-				if ( this[i].style ) {
-					var display = jQuery.css( this[i], "display" );
 
-					if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
-						jQuery._data( this[i], "olddisplay", display );
-					}
-				}
-			}
+  jQuery.offset = {
+    setOffset: function( elem, options, i ) {
+      var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+          position = jQuery.css( elem, "position" ),
+          curElem = jQuery( elem ),
+          props = {};
 
-			// Set the display of the elements in a second loop
-			// to avoid the constant reflow
-			for ( i = 0; i < j; i++ ) {
-				if ( this[i].style ) {
-					this[i].style.display = "none";
-				}
-			}
+      // Set position first, in-case top/left are set even on static elem
+      if ( position === "static" ) {
+        elem.style.position = "relative";
+      }
 
-			return this;
-		}
-	},
+      curOffset = curElem.offset();
+      curCSSTop = jQuery.css( elem, "top" );
+      curCSSLeft = jQuery.css( elem, "left" );
+      calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+          ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
 
-	// Save the old toggle function
-	_toggle: jQuery.fn.toggle,
+      // Need to be able to calculate position if either
+      // top or left is auto and position is either absolute or fixed
+      if ( calculatePosition ) {
+        curPosition = curElem.position();
+        curTop = curPosition.top;
+        curLeft = curPosition.left;
 
-	toggle: function( fn, fn2, callback ) {
-		var bool = typeof fn === "boolean";
+      } else {
+        curTop = parseFloat( curCSSTop ) || 0;
+        curLeft = parseFloat( curCSSLeft ) || 0;
+      }
 
-		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
-			this._toggle.apply( this, arguments );
+      if ( isFunction( options ) ) {
 
-		} else if ( fn == null || bool ) {
-			this.each(function() {
-				var state = bool ? fn : jQuery(this).is(":hidden");
-				jQuery(this)[ state ? "show" : "hide" ]();
-			});
+        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
+        options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
+      }
 
-		} else {
-			this.animate(genFx("toggle", 3), fn, fn2, callback);
-		}
+      if ( options.top != null ) {
+        props.top = ( options.top - curOffset.top ) + curTop;
+      }
+      if ( options.left != null ) {
+        props.left = ( options.left - curOffset.left ) + curLeft;
+      }
 
-		return this;
-	},
+      if ( "using" in options ) {
+        options.using.call( elem, props );
 
-	fadeTo: function( speed, to, easing, callback ) {
-		return this.filter(":hidden").css("opacity", 0).show().end()
-					.animate({opacity: to}, speed, easing, callback);
-	},
+      } else {
+        curElem.css( props );
+      }
+    }
+  };
 
-	animate: function( prop, speed, easing, callback ) {
-		var optall = jQuery.speed(speed, easing, callback);
+  jQuery.fn.extend( {
 
-		if ( jQuery.isEmptyObject( prop ) ) {
-			return this.each( optall.complete, [ false ] );
-		}
+    // offset() relates an element's border box to the document origin
+    offset: function( options ) {
 
-		// Do not change referenced properties as per-property easing will be lost
-		prop = jQuery.extend( {}, prop );
+      // Preserve chaining for setter
+      if ( arguments.length ) {
+        return options === undefined ?
+            this :
+            this.each( function( i ) {
+              jQuery.offset.setOffset( this, options, i );
+            } );
+      }
 
-		return this[ optall.queue === false ? "each" : "queue" ](function() {
-			// XXX 'this' does not always have a nodeName when running the
-			// test suite
+      var rect, win,
+          elem = this[ 0 ];
 
-			if ( optall.queue === false ) {
-				jQuery._mark( this );
-			}
+      if ( !elem ) {
+        return;
+      }
 
-			var opt = jQuery.extend( {}, optall ),
-				isElement = this.nodeType === 1,
-				hidden = isElement && jQuery(this).is(":hidden"),
-				name, val, p,
-				display, e,
-				parts, start, end, unit;
+      // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
+      // Support: IE <=11 only
+      // Running getBoundingClientRect on a
+      // disconnected node in IE throws an error
+      if ( !elem.getClientRects().length ) {
+        return { top: 0, left: 0 };
+      }
 
-			// will store per property easing and be used to determine when an animation is complete
-			opt.animatedProperties = {};
+      // Get document-relative position by adding viewport scroll to viewport-relative gBCR
+      rect = elem.getBoundingClientRect();
+      win = elem.ownerDocument.defaultView;
+      return {
+        top: rect.top + win.pageYOffset,
+        left: rect.left + win.pageXOffset
+      };
+    },
 
-			for ( p in prop ) {
+    // position() relates an element's margin box to its offset parent's padding box
+    // This corresponds to the behavior of CSS absolute positioning
+    position: function() {
+      if ( !this[ 0 ] ) {
+        return;
+      }
 
-				// property name normalization
-				name = jQuery.camelCase( p );
-				if ( p !== name ) {
-					prop[ name ] = prop[ p ];
-					delete prop[ p ];
-				}
+      var offsetParent, offset, doc,
+          elem = this[ 0 ],
+          parentOffset = { top: 0, left: 0 };
 
-				val = prop[ name ];
+      // position:fixed elements are offset from the viewport, which itself always has zero offset
+      if ( jQuery.css( elem, "position" ) === "fixed" ) {
 
-				// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
-				if ( jQuery.isArray( val ) ) {
-					opt.animatedProperties[ name ] = val[ 1 ];
-					val = prop[ name ] = val[ 0 ];
-				} else {
-					opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
-				}
+        // Assume position:fixed implies availability of getBoundingClientRect
+        offset = elem.getBoundingClientRect();
 
-				if ( val === "hide" && hidden || val === "show" && !hidden ) {
-					return opt.complete.call( this );
-				}
+      } else {
+        offset = this.offset();
 
-				if ( isElement && ( name === "height" || name === "width" ) ) {
-					// Make sure that nothing sneaks out
-					// Record all 3 overflow attributes because IE does not
-					// change the overflow attribute when overflowX and
-					// overflowY are set to the same value
-					opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+        // Account for the *real* offset parent, which can be the document or its root element
+        // when a statically positioned element is identified
+        doc = elem.ownerDocument;
+        offsetParent = elem.offsetParent || doc.documentElement;
+        while ( offsetParent &&
+        ( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
+        jQuery.css( offsetParent, "position" ) === "static" ) {
 
-					// Set display property to inline-block for height/width
-					// animations on inline elements that are having width/height
-					// animated
-					if ( jQuery.css( this, "display" ) === "inline" &&
-							jQuery.css( this, "float" ) === "none" ) {
-						if ( !jQuery.support.inlineBlockNeedsLayout ) {
-							this.style.display = "inline-block";
+          offsetParent = offsetParent.parentNode;
+        }
+        if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
 
-						} else {
-							display = defaultDisplay( this.nodeName );
-
-							// inline-level elements accept inline-block;
-							// block-level elements need to be inline with layout
-							if ( display === "inline" ) {
-								this.style.display = "inline-block";
-
-							} else {
-								this.style.display = "inline";
-								this.style.zoom = 1;
-							}
-						}
-					}
-				}
-			}
-
-			if ( opt.overflow != null ) {
-				this.style.overflow = "hidden";
-			}
-
-			for ( p in prop ) {
-				e = new jQuery.fx( this, opt, p );
-				val = prop[ p ];
-
-				if ( rfxtypes.test(val) ) {
-					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
-
-				} else {
-					parts = rfxnum.exec( val );
-					start = e.cur();
-
-					if ( parts ) {
-						end = parseFloat( parts[2] );
-						unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
-
-						// We need to compute starting value
-						if ( unit !== "px" ) {
-							jQuery.style( this, p, (end || 1) + unit);
-							start = ((end || 1) / e.cur()) * start;
-							jQuery.style( this, p, start + unit);
-						}
-
-						// If a +=/-= token was provided, we're doing a relative animation
-						if ( parts[1] ) {
-							end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
-						}
-
-						e.custom( start, end, unit );
-
-					} else {
-						e.custom( start, val, "" );
-					}
-				}
-			}
-
-			// For JS strict compliance
-			return true;
-		});
-	},
-
-	stop: function( clearQueue, gotoEnd ) {
-		if ( clearQueue ) {
-			this.queue([]);
-		}
-
-		this.each(function() {
-			var timers = jQuery.timers,
-				i = timers.length;
-			// clear marker counters if we know they won't be
-			if ( !gotoEnd ) {
-				jQuery._unmark( true, this );
-			}
-			while ( i-- ) {
-				if ( timers[i].elem === this ) {
-					if (gotoEnd) {
-						// force the next step to be the last
-						timers[i](true);
-					}
-
-					timers.splice(i, 1);
-				}
-			}
-		});
-
-		// start the next in the queue if the last step wasn't forced
-		if ( !gotoEnd ) {
-			this.dequeue();
-		}
-
-		return this;
-	}
-
-});
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
-	setTimeout( clearFxNow, 0 );
-	return ( fxNow = jQuery.now() );
-}
-
-function clearFxNow() {
-	fxNow = undefined;
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, num ) {
-	var obj = {};
-
-	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
-		obj[ this ] = type;
-	});
-
-	return obj;
-}
-
-// Generate shortcuts for custom animations
-jQuery.each({
-	slideDown: genFx("show", 1),
-	slideUp: genFx("hide", 1),
-	slideToggle: genFx("toggle", 1),
-	fadeIn: { opacity: "show" },
-	fadeOut: { opacity: "hide" },
-	fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return this.animate( props, speed, easing, callback );
-	};
-});
-
-jQuery.extend({
-	speed: function( speed, easing, fn ) {
-		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
-			complete: fn || !fn && easing ||
-				jQuery.isFunction( speed ) && speed,
-			duration: speed,
-			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
-		};
-
-		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
-			opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
-
-		// Queueing
-		opt.old = opt.complete;
-		opt.complete = function( noUnmark ) {
-			if ( jQuery.isFunction( opt.old ) ) {
-				opt.old.call( this );
-			}
-
-			if ( opt.queue !== false ) {
-				jQuery.dequeue( this );
-			} else if ( noUnmark !== false ) {
-				jQuery._unmark( this );
-			}
-		};
-
-		return opt;
-	},
-
-	easing: {
-		linear: function( p, n, firstNum, diff ) {
-			return firstNum + diff * p;
-		},
-		swing: function( p, n, firstNum, diff ) {
-			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
-		}
-	},
-
-	timers: [],
-
-	fx: function( elem, options, prop ) {
-		this.options = options;
-		this.elem = elem;
-		this.prop = prop;
-
-		options.orig = options.orig || {};
-	}
-
-});
-
-jQuery.fx.prototype = {
-	// Simple function for setting a style value
-	update: function() {
-		if ( this.options.step ) {
-			this.options.step.call( this.elem, this.now, this );
-		}
-
-		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
-	},
-
-	// Get the current size
-	cur: function() {
-		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
-			return this.elem[ this.prop ];
-		}
-
-		var parsed,
-			r = jQuery.css( this.elem, this.prop );
-		// Empty strings, null, undefined and "auto" are converted to 0,
-		// complex values such as "rotate(1rad)" are returned as is,
-		// simple values such as "10px" are parsed to Float.
-		return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
-	},
-
-	// Start an animation from one number to another
-	custom: function( from, to, unit ) {
-		var self = this,
-			fx = jQuery.fx;
-
-		this.startTime = fxNow || createFxNow();
-		this.start = from;
-		this.end = to;
-		this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
-		this.now = this.start;
-		this.pos = this.state = 0;
-
-		function t( gotoEnd ) {
-			return self.step(gotoEnd);
-		}
-
-		t.elem = this.elem;
-
-		if ( t() && jQuery.timers.push(t) && !timerId ) {
-			timerId = setInterval( fx.tick, fx.interval );
-		}
-	},
-
-	// Simple 'show' function
-	show: function() {
-		// Remember where we started, so that we can go back to it later
-		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
-		this.options.show = true;
-
-		// Begin the animation
-		// Make sure that we start at a small width/height to avoid any
-		// flash of content
-		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
-
-		// Start by showing the element
-		jQuery( this.elem ).show();
-	},
-
-	// Simple 'hide' function
-	hide: function() {
-		// Remember where we started, so that we can go back to it later
-		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
-		this.options.hide = true;
-
-		// Begin the animation
-		this.custom(this.cur(), 0);
-	},
-
-	// Each step of an animation
-	step: function( gotoEnd ) {
-		var t = fxNow || createFxNow(),
-			done = true,
-			elem = this.elem,
-			options = this.options,
-			i, n;
-
-		if ( gotoEnd || t >= options.duration + this.startTime ) {
-			this.now = this.end;
-			this.pos = this.state = 1;
-			this.update();
-
-			options.animatedProperties[ this.prop ] = true;
-
-			for ( i in options.animatedProperties ) {
-				if ( options.animatedProperties[i] !== true ) {
-					done = false;
-				}
-			}
-
-			if ( done ) {
-				// Reset the overflow
-				if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
-
-					jQuery.each( [ "", "X", "Y" ], function (index, value) {
-						elem.style[ "overflow" + value ] = options.overflow[index];
-					});
-				}
-
-				// Hide the element if the "hide" operation was done
-				if ( options.hide ) {
-					jQuery(elem).hide();
-				}
-
-				// Reset the properties, if the item has been hidden or shown
-				if ( options.hide || options.show ) {
-					for ( var p in options.animatedProperties ) {
-						jQuery.style( elem, p, options.orig[p] );
-					}
-				}
-
-				// Execute the complete function
-				options.complete.call( elem );
-			}
-
-			return false;
-
-		} else {
-			// classical easing cannot be used with an Infinity duration
-			if ( options.duration == Infinity ) {
-				this.now = t;
-			} else {
-				n = t - this.startTime;
-				this.state = n / options.duration;
-
-				// Perform the easing function, defaults to swing
-				this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
-				this.now = this.start + ((this.end - this.start) * this.pos);
-			}
-			// Perform the next step of the animation
-			this.update();
-		}
-
-		return true;
-	}
-};
-
-jQuery.extend( jQuery.fx, {
-	tick: function() {
-		for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
-			if ( !timers[i]() ) {
-				timers.splice(i--, 1);
-			}
-		}
-
-		if ( !timers.length ) {
-			jQuery.fx.stop();
-		}
-	},
-
-	interval: 13,
-
-	stop: function() {
-		clearInterval( timerId );
-		timerId = null;
-	},
-
-	speeds: {
-		slow: 600,
-		fast: 200,
-		// Default speed
-		_default: 400
-	},
-
-	step: {
-		opacity: function( fx ) {
-			jQuery.style( fx.elem, "opacity", fx.now );
-		},
-
-		_default: function( fx ) {
-			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
-				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
-			} else {
-				fx.elem[ fx.prop ] = fx.now;
-			}
-		}
-	}
-});
-
-if ( jQuery.expr && jQuery.expr.filters ) {
-	jQuery.expr.filters.animated = function( elem ) {
-		return jQuery.grep(jQuery.timers, function( fn ) {
-			return elem === fn.elem;
-		}).length;
-	};
-}
-
-// Try to restore the default display value of an element
-function defaultDisplay( nodeName ) {
-
-	if ( !elemdisplay[ nodeName ] ) {
-
-		var body = document.body,
-			elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
-			display = elem.css( "display" );
-
-		elem.remove();
-
-		// If the simple way fails,
-		// get element's real default display by attaching it to a temp iframe
-		if ( display === "none" || display === "" ) {
-			// No iframe to use yet, so create it
-			if ( !iframe ) {
-				iframe = document.createElement( "iframe" );
-				iframe.frameBorder = iframe.width = iframe.height = 0;
-			}
-
-			body.appendChild( iframe );
-
-			// Create a cacheable copy of the iframe document on first call.
-			// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
-			// document to it; WebKit & Firefox won't allow reusing the iframe document.
-			if ( !iframeDoc || !iframe.createElement ) {
-				iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
-				iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
-				iframeDoc.close();
-			}
-
-			elem = iframeDoc.createElement( nodeName );
-
-			iframeDoc.body.appendChild( elem );
-
-			display = jQuery.css( elem, "display" );
-
-			body.removeChild( iframe );
-		}
-
-		// Store the correct default display
-		elemdisplay[ nodeName ] = display;
-	}
-
-	return elemdisplay[ nodeName ];
-}
-
-
-
-
-var rtable = /^t(?:able|d|h)$/i,
-	rroot = /^(?:body|html)$/i;
-
-if ( "getBoundingClientRect" in document.documentElement ) {
-	jQuery.fn.offset = function( options ) {
-		var elem = this[0], box;
-
-		if ( options ) {
-			return this.each(function( i ) {
-				jQuery.offset.setOffset( this, options, i );
-			});
-		}
-
-		if ( !elem || !elem.ownerDocument ) {
-			return null;
-		}
-
-		if ( elem === elem.ownerDocument.body ) {
-			return jQuery.offset.bodyOffset( elem );
-		}
-
-		try {
-			box = elem.getBoundingClientRect();
-		} catch(e) {}
-
-		var doc = elem.ownerDocument,
-			docElem = doc.documentElement;
-
-		// Make sure we're not dealing with a disconnected DOM node
-		if ( !box || !jQuery.contains( docElem, elem ) ) {
-			return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
-		}
-
-		var body = doc.body,
-			win = getWindow(doc),
-			clientTop  = docElem.clientTop  || body.clientTop  || 0,
-			clientLeft = docElem.clientLeft || body.clientLeft || 0,
-			scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
-			scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
-			top  = box.top  + scrollTop  - clientTop,
-			left = box.left + scrollLeft - clientLeft;
-
-		return { top: top, left: left };
-	};
-
-} else {
-	jQuery.fn.offset = function( options ) {
-		var elem = this[0];
-
-		if ( options ) {
-			return this.each(function( i ) {
-				jQuery.offset.setOffset( this, options, i );
-			});
-		}
-
-		if ( !elem || !elem.ownerDocument ) {
-			return null;
-		}
-
-		if ( elem === elem.ownerDocument.body ) {
-			return jQuery.offset.bodyOffset( elem );
-		}
-
-		jQuery.offset.initialize();
-
-		var computedStyle,
-			offsetParent = elem.offsetParent,
-			prevOffsetParent = elem,
-			doc = elem.ownerDocument,
-			docElem = doc.documentElement,
-			body = doc.body,
-			defaultView = doc.defaultView,
-			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
-			top = elem.offsetTop,
-			left = elem.offsetLeft;
-
-		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
-			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
-				break;
-			}
-
-			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
-			top  -= elem.scrollTop;
-			left -= elem.scrollLeft;
-
-			if ( elem === offsetParent ) {
-				top  += elem.offsetTop;
-				left += elem.offsetLeft;
-
-				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
-					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
-					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
-				}
-
-				prevOffsetParent = offsetParent;
-				offsetParent = elem.offsetParent;
-			}
-
-			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
-				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
-				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
-			}
-
-			prevComputedStyle = computedStyle;
-		}
-
-		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
-			top  += body.offsetTop;
-			left += body.offsetLeft;
-		}
-
-		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
-			top  += Math.max( docElem.scrollTop, body.scrollTop );
-			left += Math.max( docElem.scrollLeft, body.scrollLeft );
-		}
-
-		return { top: top, left: left };
-	};
-}
-
-jQuery.offset = {
-	initialize: function() {
-		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
-			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
-
-		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
-
-		container.innerHTML = html;
-		body.insertBefore( container, body.firstChild );
-		innerDiv = container.firstChild;
-		checkDiv = innerDiv.firstChild;
-		td = innerDiv.nextSibling.firstChild.firstChild;
-
-		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
-		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
-
-		checkDiv.style.position = "fixed";
-		checkDiv.style.top = "20px";
-
-		// safari subtracts parent border width here which is 5px
-		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
-		checkDiv.style.position = checkDiv.style.top = "";
-
-		innerDiv.style.overflow = "hidden";
-		innerDiv.style.position = "relative";
-
-		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
-
-		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
-
-		body.removeChild( container );
-		jQuery.offset.initialize = jQuery.noop;
-	},
-
-	bodyOffset: function( body ) {
-		var top = body.offsetTop,
-			left = body.offsetLeft;
-
-		jQuery.offset.initialize();
-
-		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
-			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
-			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
-		}
-
-		return { top: top, left: left };
-	},
-
-	setOffset: function( elem, options, i ) {
-		var position = jQuery.css( elem, "position" );
-
-		// set position first, in-case top/left are set even on static elem
-		if ( position === "static" ) {
-			elem.style.position = "relative";
-		}
-
-		var curElem = jQuery( elem ),
-			curOffset = curElem.offset(),
-			curCSSTop = jQuery.css( elem, "top" ),
-			curCSSLeft = jQuery.css( elem, "left" ),
-			calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
-			props = {}, curPosition = {}, curTop, curLeft;
-
-		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
-		if ( calculatePosition ) {
-			curPosition = curElem.position();
-			curTop = curPosition.top;
-			curLeft = curPosition.left;
-		} else {
-			curTop = parseFloat( curCSSTop ) || 0;
-			curLeft = parseFloat( curCSSLeft ) || 0;
-		}
-
-		if ( jQuery.isFunction( options ) ) {
-			options = options.call( elem, i, curOffset );
-		}
-
-		if (options.top != null) {
-			props.top = (options.top - curOffset.top) + curTop;
-		}
-		if (options.left != null) {
-			props.left = (options.left - curOffset.left) + curLeft;
-		}
-
-		if ( "using" in options ) {
-			options.using.call( elem, props );
-		} else {
-			curElem.css( props );
-		}
-	}
-};
-
-
-jQuery.fn.extend({
-	position: function() {
-		if ( !this[0] ) {
-			return null;
-		}
-
-		var elem = this[0],
-
-		// Get *real* offsetParent
-		offsetParent = this.offsetParent(),
-
-		// Get correct offsets
-		offset       = this.offset(),
-		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
-
-		// Subtract element margins
-		// note: when an element has margin: auto the offsetLeft and marginLeft
-		// are the same in Safari causing offset.left to incorrectly be 0
-		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
-		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+          // Incorporate borders into its offset, since they are outside its content origin
+          parentOffset = jQuery( offsetParent ).offset();
+          parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
+          parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
+        }
+      }
 
-		// Add offsetParent borders
-		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
-		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+      // Subtract parent offsets and element margins
+      return {
+        top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+        left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+      };
+    },
 
-		// Subtract the two offsets
-		return {
-			top:  offset.top  - parentOffset.top,
-			left: offset.left - parentOffset.left
-		};
-	},
+    // This method will return documentElement in the following cases:
+    // 1) For the element inside the iframe without offsetParent, this method will return
+    //    documentElement of the parent window
+    // 2) For the hidden or detached element
+    // 3) For body or html element, i.e. in case of the html node - it will return itself
+    //
+    // but those exceptions were never presented as a real life use-cases
+    // and might be considered as more preferable results.
+    //
+    // This logic, however, is not guaranteed and can change at any point in the future
+    offsetParent: function() {
+      return this.map( function() {
+        var offsetParent = this.offsetParent;
 
-	offsetParent: function() {
-		return this.map(function() {
-			var offsetParent = this.offsetParent || document.body;
-			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
-				offsetParent = offsetParent.offsetParent;
-			}
-			return offsetParent;
-		});
-	}
-});
+        while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
+          offsetParent = offsetParent.offsetParent;
+        }
 
+        return offsetParent || documentElement;
+      } );
+    }
+  } );
 
 // Create scrollLeft and scrollTop methods
-jQuery.each( ["Left", "Top"], function( i, name ) {
-	var method = "scroll" + name;
+  jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+    var top = "pageYOffset" === prop;
 
-	jQuery.fn[ method ] = function( val ) {
-		var elem, win;
+    jQuery.fn[ method ] = function( val ) {
+      return access( this, function( elem, method, val ) {
 
-		if ( val === undefined ) {
-			elem = this[ 0 ];
+        // Coalesce documents and windows
+        var win;
+        if ( isWindow( elem ) ) {
+          win = elem;
+        } else if ( elem.nodeType === 9 ) {
+          win = elem.defaultView;
+        }
 
-			if ( !elem ) {
-				return null;
-			}
+        if ( val === undefined ) {
+          return win ? win[ prop ] : elem[ method ];
+        }
 
-			win = getWindow( elem );
+        if ( win ) {
+          win.scrollTo(
+              !top ? val : win.pageXOffset,
+              top ? val : win.pageYOffset
+          );
 
-			// Return the scroll offset
-			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
-				jQuery.support.boxModel && win.document.documentElement[ method ] ||
-					win.document.body[ method ] :
-				elem[ method ];
-		}
+        } else {
+          elem[ method ] = val;
+        }
+      }, method, val, arguments.length );
+    };
+  } );
 
-		// Set the scroll offset
-		return this.each(function() {
-			win = getWindow( this );
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
+// getComputedStyle returns percent when specified for top/left/bottom/right;
+// rather than make the css module depend on the offset module, just check for it here
+  jQuery.each( [ "top", "left" ], function( i, prop ) {
+    jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+        function( elem, computed ) {
+          if ( computed ) {
+            computed = curCSS( elem, prop );
 
-			if ( win ) {
-				win.scrollTo(
-					!i ? val : jQuery( win ).scrollLeft(),
-					 i ? val : jQuery( win ).scrollTop()
-				);
+            // If curCSS returns percentage, fallback to offset
+            return rnumnonpx.test( computed ) ?
+                jQuery( elem ).position()[ prop ] + "px" :
+                computed;
+          }
+        }
+    );
+  } );
 
-			} else {
-				this[ method ] = val;
-			}
-		});
-	};
-});
 
-function getWindow( elem ) {
-	return jQuery.isWindow( elem ) ?
-		elem :
-		elem.nodeType === 9 ?
-			elem.defaultView || elem.parentWindow :
-			false;
-}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+  jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+    jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
+        function( defaultExtra, funcName ) {
+
+          // Margin is only for outerHeight, outerWidth
+          jQuery.fn[ funcName ] = function( margin, value ) {
+            var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+                extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+            return access( this, function( elem, type, value ) {
+              var doc;
+
+              if ( isWindow( elem ) ) {
+
+                // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
+                return funcName.indexOf( "outer" ) === 0 ?
+                    elem[ "inner" + name ] :
+                    elem.document.documentElement[ "client" + name ];
+              }
+
+              // Get document width or height
+              if ( elem.nodeType === 9 ) {
+                doc = elem.documentElement;
+
+                // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
+                // whichever is greatest
+                return Math.max(
+                    elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+                    elem.body[ "offset" + name ], doc[ "offset" + name ],
+                    doc[ "client" + name ]
+                );
+              }
+
+              return value === undefined ?
+
+                  // Get width or height on the element, requesting but not forcing parseFloat
+                  jQuery.css( elem, type, extra ) :
+
+                  // Set width or height on the element
+                  jQuery.style( elem, type, value, extra );
+            }, type, chainable ? margin : undefined, chainable );
+          };
+        } );
+  } );
+
+
+  jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
+      "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+      "change select submit keydown keypress keyup contextmenu" ).split( " " ),
+      function( i, name ) {
+
+        // Handle event binding
+        jQuery.fn[ name ] = function( data, fn ) {
+          return arguments.length > 0 ?
+              this.on( name, null, data, fn ) :
+              this.trigger( name );
+        };
+      } );
+
+  jQuery.fn.extend( {
+    hover: function( fnOver, fnOut ) {
+      return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+    }
+  } );
 
 
 
 
-// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
-jQuery.each([ "Height", "Width" ], function( i, name ) {
+  jQuery.fn.extend( {
 
-	var type = name.toLowerCase();
+    bind: function( types, data, fn ) {
+      return this.on( types, null, data, fn );
+    },
+    unbind: function( types, fn ) {
+      return this.off( types, null, fn );
+    },
 
-	// innerHeight and innerWidth
-	jQuery.fn[ "inner" + name ] = function() {
-		var elem = this[0];
-		return elem && elem.style ?
-			parseFloat( jQuery.css( elem, type, "padding" ) ) :
-			null;
-	};
+    delegate: function( selector, types, data, fn ) {
+      return this.on( types, selector, data, fn );
+    },
+    undelegate: function( selector, types, fn ) {
 
-	// outerHeight and outerWidth
-	jQuery.fn[ "outer" + name ] = function( margin ) {
-		var elem = this[0];
-		return elem && elem.style ?
-			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
-			null;
-	};
+      // ( namespace ) or ( selector, types [, fn] )
+      return arguments.length === 1 ?
+          this.off( selector, "**" ) :
+          this.off( types, selector || "**", fn );
+    }
+  } );
 
-	jQuery.fn[ type ] = function( size ) {
-		// Get window width or height
-		var elem = this[0];
-		if ( !elem ) {
-			return size == null ? null : this;
-		}
+// Bind a function to a context, optionally partially applying any
+// arguments.
+// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
+// However, it is not slated for removal any time soon
+  jQuery.proxy = function( fn, context ) {
+    var tmp, args, proxy;
 
-		if ( jQuery.isFunction( size ) ) {
-			return this.each(function( i ) {
-				var self = jQuery( this );
-				self[ type ]( size.call( this, i, self[ type ]() ) );
-			});
-		}
+    if ( typeof context === "string" ) {
+      tmp = fn[ context ];
+      context = fn;
+      fn = tmp;
+    }
 
-		if ( jQuery.isWindow( elem ) ) {
-			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
-			// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
-			var docElemProp = elem.document.documentElement[ "client" + name ],
-				body = elem.document.body;
-			return elem.document.compatMode === "CSS1Compat" && docElemProp ||
-				body && body[ "client" + name ] || docElemProp;
+    // Quick check to determine if target is callable, in the spec
+    // this throws a TypeError, but we will just return undefined.
+    if ( !isFunction( fn ) ) {
+      return undefined;
+    }
 
-		// Get document width or height
-		} else if ( elem.nodeType === 9 ) {
-			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
-			return Math.max(
-				elem.documentElement["client" + name],
-				elem.body["scroll" + name], elem.documentElement["scroll" + name],
-				elem.body["offset" + name], elem.documentElement["offset" + name]
-			);
+    // Simulated bind
+    args = slice.call( arguments, 2 );
+    proxy = function() {
+      return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+    };
 
-		// Get or set width or height on the element
-		} else if ( size === undefined ) {
-			var orig = jQuery.css( elem, type ),
-				ret = parseFloat( orig );
+    // Set the guid of unique handler to the same of original handler, so it can be removed
+    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
 
-			return jQuery.isNaN( ret ) ? orig : ret;
+    return proxy;
+  };
 
-		// Set the width or height on the element (default to pixels if value is unitless)
-		} else {
-			return this.css( type, typeof size === "string" ? size : size + "px" );
-		}
-	};
+  jQuery.holdReady = function( hold ) {
+    if ( hold ) {
+      jQuery.readyWait++;
+    } else {
+      jQuery.ready( true );
+    }
+  };
+  jQuery.isArray = Array.isArray;
+  jQuery.parseJSON = JSON.parse;
+  jQuery.nodeName = nodeName;
+  jQuery.isFunction = isFunction;
+  jQuery.isWindow = isWindow;
+  jQuery.camelCase = camelCase;
+  jQuery.type = toType;
 
-});
+  jQuery.now = Date.now;
+
+  jQuery.isNumeric = function( obj ) {
+
+    // As of jQuery 3.0, isNumeric is limited to
+    // strings and numbers (primitives or objects)
+    // that can be coerced to finite numbers (gh-2662)
+    var type = jQuery.type( obj );
+    return ( type === "number" || type === "string" ) &&
+
+        // parseFloat NaNs numeric-cast false positives ("")
+        // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+        // subtraction forces infinities to NaN
+        !isNaN( obj - parseFloat( obj ) );
+  };
 
 
-// Expose jQuery to the global object
-window.jQuery = window.$ = jQuery;
-})(window);
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+  if ( typeof define === "function" && define.amd ) {
+    define( "jquery", [], function() {
+      return jQuery;
+    } );
+  }
+
+
+
+
+  var
+
+      // Map over jQuery in case of overwrite
+      _jQuery = window.jQuery,
+
+      // Map over the $ in case of overwrite
+      _$ = window.$;
+
+  jQuery.noConflict = function( deep ) {
+    if ( window.$ === jQuery ) {
+      window.$ = _$;
+    }
+
+    if ( deep && window.jQuery === jQuery ) {
+      window.jQuery = _jQuery;
+    }
+
+    return jQuery;
+  };
+
+// Expose jQuery and $ identifiers, even in AMD
+// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+  if ( !noGlobal ) {
+    window.jQuery = window.$ = jQuery;
+  }
+
+
+
+
+  return jQuery;
+} );
\ No newline at end of file
diff --git a/ui/lib/jquery.validate.additional-methods.js b/ui/lib/jquery.validate.additional-methods.js
index 811b4f7..668cb51 100644
--- a/ui/lib/jquery.validate.additional-methods.js
+++ b/ui/lib/jquery.validate.additional-methods.js
@@ -1,931 +1,1158 @@
 /*!
- * jQuery Validation Plugin v1.13.0
+ * jQuery Validation Plugin v1.17.0
  *
- * http://jqueryvalidation.org/
+ * https://jqueryvalidation.org/
  *
- * Copyright (c) 2014 Jörn Zaefferer
+ * Copyright (c) 2017 Jörn Zaefferer
  * Released under the MIT license
  */
 (function( factory ) {
-	if ( typeof define === "function" && define.amd ) {
-		define( ["jquery", "./jquery.validate"], factory );
-	} else {
-		factory( jQuery );
-	}
+  if ( typeof define === "function" && define.amd ) {
+    define( ["jquery", "./jquery.validate"], factory );
+  } else if (typeof module === "object" && module.exports) {
+    module.exports = factory( require( "jquery" ) );
+  } else {
+    factory( jQuery );
+  }
 }(function( $ ) {
 
-(function() {
+  ( function() {
 
-	function stripHtml(value) {
-		// remove html tags and space chars
-		return value.replace(/<.[^<>]*?>/g, " ").replace(/&nbsp;|&#160;/gi, " ")
-		// remove punctuation
-		.replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "");
-	}
+    function stripHtml( value ) {
 
-	$.validator.addMethod("maxWords", function(value, element, params) {
-		return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params;
-	}, $.validator.format("Please enter {0} words or less."));
+      // Remove html tags and space chars
+      return value.replace( /<.[^<>]*?>/g, " " ).replace( /&nbsp;|&#160;/gi, " " )
 
-	$.validator.addMethod("minWords", function(value, element, params) {
-		return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params;
-	}, $.validator.format("Please enter at least {0} words."));
+      // Remove punctuation
+          .replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" );
+    }
 
-	$.validator.addMethod("rangeWords", function(value, element, params) {
-		var valueStripped = stripHtml(value),
-			regex = /\b\w+\b/g;
-		return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1];
-	}, $.validator.format("Please enter between {0} and {1} words."));
+    $.validator.addMethod( "maxWords", function( value, element, params ) {
+      return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params;
+    }, $.validator.format( "Please enter {0} words or less." ) );
 
-}());
+    $.validator.addMethod( "minWords", function( value, element, params ) {
+      return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params;
+    }, $.validator.format( "Please enter at least {0} words." ) );
+
+    $.validator.addMethod( "rangeWords", function( value, element, params ) {
+      var valueStripped = stripHtml( value ),
+          regex = /\b\w+\b/g;
+      return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ];
+    }, $.validator.format( "Please enter between {0} and {1} words." ) );
+
+  }() );
 
 // Accept a value from a file input based on a required mimetype
-$.validator.addMethod("accept", function(value, element, param) {
-	// Split mime on commas in case we have multiple types we can accept
-	var typeParam = typeof param === "string" ? param.replace(/\s/g, "").replace(/,/g, "|") : "image/*",
-	optionalValue = this.optional(element),
-	i, file;
+  $.validator.addMethod( "accept", function( value, element, param ) {
 
-	// Element is optional
-	if (optionalValue) {
-		return optionalValue;
-	}
+    // Split mime on commas in case we have multiple types we can accept
+    var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*",
+        optionalValue = this.optional( element ),
+        i, file, regex;
 
-	if ($(element).attr("type") === "file") {
-		// If we are using a wildcard, make it regex friendly
-		typeParam = typeParam.replace(/\*/g, ".*");
+    // Element is optional
+    if ( optionalValue ) {
+      return optionalValue;
+    }
 
-		// Check if the element has a FileList before checking each file
-		if (element.files && element.files.length) {
-			for (i = 0; i < element.files.length; i++) {
-				file = element.files[i];
+    if ( $( element ).attr( "type" ) === "file" ) {
 
-				// Grab the mimetype from the loaded file, verify it matches
-				if (!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) {
-					return false;
-				}
-			}
-		}
-	}
+      // Escape string to be used in the regex
+      // see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
+      // Escape also "/*" as "/.*" as a wildcard
+      typeParam = typeParam
+          .replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" )
+          .replace( /,/g, "|" )
+          .replace( /\/\*/g, "/.*" );
 
-	// Either return true because we've validated each file, or because the
-	// browser does not support element.files and the FileList feature
-	return true;
-}, $.validator.format("Please enter a value with a valid mimetype."));
+      // Check if the element has a FileList before checking each file
+      if ( element.files && element.files.length ) {
+        regex = new RegExp( ".?(" + typeParam + ")$", "i" );
+        for ( i = 0; i < element.files.length; i++ ) {
+          file = element.files[ i ];
 
-$.validator.addMethod("alphanumeric", function(value, element) {
-	return this.optional(element) || /^\w+$/i.test(value);
-}, "Letters, numbers, and underscores only please");
+          // Grab the mimetype from the loaded file, verify it matches
+          if ( !file.type.match( regex ) ) {
+            return false;
+          }
+        }
+      }
+    }
 
-/*
- * Dutch bank account numbers (not 'giro' numbers) have 9 digits
- * and pass the '11 check'.
- * We accept the notation with spaces, as that is common.
- * acceptable: 123456789 or 12 34 56 789
- */
-$.validator.addMethod("bankaccountNL", function(value, element) {
-	if (this.optional(element)) {
-		return true;
-	}
-	if (!(/^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test(value))) {
-		return false;
-	}
-	// now '11 check'
-	var account = value.replace(/ /g, ""), // remove spaces
-		sum = 0,
-		len = account.length,
-		pos, factor, digit;
-	for ( pos = 0; pos < len; pos++ ) {
-		factor = len - pos;
-		digit = account.substring(pos, pos + 1);
-		sum = sum + factor * digit;
-	}
-	return sum % 11 === 0;
-}, "Please specify a valid bank account number");
+    // Either return true because we've validated each file, or because the
+    // browser does not support element.files and the FileList feature
+    return true;
+  }, $.validator.format( "Please enter a value with a valid mimetype." ) );
 
-$.validator.addMethod("bankorgiroaccountNL", function(value, element) {
-	return this.optional(element) ||
-			($.validator.methods.bankaccountNL.call(this, value, element)) ||
-			($.validator.methods.giroaccountNL.call(this, value, element));
-}, "Please specify a valid bank or giro account number");
+  $.validator.addMethod( "alphanumeric", function( value, element ) {
+    return this.optional( element ) || /^\w+$/i.test( value );
+  }, "Letters, numbers, and underscores only please" );
 
-/**
- * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
- *
- * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
- *
- * BIC definition in detail:
- * - First 4 characters - bank code (only letters)
- * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
- * - Next 2 characters - location code (letters and digits)
- *   a. shall not start with '0' or '1'
- *   b. second character must be a letter ('O' is not allowed) or one of the following digits ('0' for test (therefore not allowed), '1' for passive participant and '2' for active participant)
- * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
- */
-$.validator.addMethod("bic", function(value, element) {
-    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value );
-}, "Please specify a valid BIC code");
+  /*
+   * Dutch bank account numbers (not 'giro' numbers) have 9 digits
+   * and pass the '11 check'.
+   * We accept the notation with spaces, as that is common.
+   * acceptable: 123456789 or 12 34 56 789
+   */
+  $.validator.addMethod( "bankaccountNL", function( value, element ) {
+    if ( this.optional( element ) ) {
+      return true;
+    }
+    if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) {
+      return false;
+    }
 
-/*
- * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
- * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
- */
-$.validator.addMethod( "cifES", function( value ) {
-	"use strict";
+    // Now '11 check'
+    var account = value.replace( / /g, "" ), // Remove spaces
+        sum = 0,
+        len = account.length,
+        pos, factor, digit;
+    for ( pos = 0; pos < len; pos++ ) {
+      factor = len - pos;
+      digit = account.substring( pos, pos + 1 );
+      sum = sum + factor * digit;
+    }
+    return sum % 11 === 0;
+  }, "Please specify a valid bank account number" );
 
-	var num = [],
-		controlDigit, sum, i, count, tmp, secondDigit;
+  $.validator.addMethod( "bankorgiroaccountNL", function( value, element ) {
+    return this.optional( element ) ||
+        ( $.validator.methods.bankaccountNL.call( this, value, element ) ) ||
+        ( $.validator.methods.giroaccountNL.call( this, value, element ) );
+  }, "Please specify a valid bank or giro account number" );
 
-	value = value.toUpperCase();
+  /**
+   * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
+   *
+   * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
+   *
+   * Validation is case-insensitive. Please make sure to normalize input yourself.
+   *
+   * BIC definition in detail:
+   * - First 4 characters - bank code (only letters)
+   * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
+   * - Next 2 characters - location code (letters and digits)
+   *   a. shall not start with '0' or '1'
+   *   b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing)
+   * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
+   */
+  $.validator.addMethod( "bic", function( value, element ) {
+    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() );
+  }, "Please specify a valid BIC code" );
 
-	// Quick format test
-	if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
-		return false;
-	}
+  /*
+   * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
+   * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
+   *
+   * Spanish CIF structure:
+   *
+   * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ]
+   *
+   * Where:
+   *
+   * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW]
+   * P: 2 characters. Province.
+   * N: 5 characters. Secuencial Number within the province.
+   * C: 1 character. Control Digit: [0-9A-J].
+   *
+   * [ T ]: Kind of Organizations. Possible values:
+   *
+   *   A. Corporations
+   *   B. LLCs
+   *   C. General partnerships
+   *   D. Companies limited partnerships
+   *   E. Communities of goods
+   *   F. Cooperative Societies
+   *   G. Associations
+   *   H. Communities of homeowners in horizontal property regime
+   *   J. Civil Societies
+   *   K. Old format
+   *   L. Old format
+   *   M. Old format
+   *   N. Nonresident entities
+   *   P. Local authorities
+   *   Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
+   *   R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
+   *   S. Organs of State Administration and regions
+   *   V. Agrarian Transformation
+   *   W. Permanent establishments of non-resident in Spain
+   *
+   * [ C ]: Control Digit. It can be a number or a letter depending on T value:
+   * [ T ]  -->  [ C ]
+   * ------    ----------
+   *   A         Number
+   *   B         Number
+   *   E         Number
+   *   H         Number
+   *   K         Letter
+   *   P         Letter
+   *   Q         Letter
+   *   S         Letter
+   *
+   */
+  $.validator.addMethod( "cifES", function( value, element ) {
+    "use strict";
 
-	for ( i = 0; i < 9; i++ ) {
-		num[ i ] = parseInt( value.charAt( i ), 10 );
-	}
+    if ( this.optional( element ) ) {
+      return true;
+    }
 
-	// Algorithm for checking CIF codes
-	sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
-	for ( count = 1; count < 8; count += 2 ) {
-		tmp = ( 2 * num[ count ] ).toString();
-		secondDigit = tmp.charAt( 1 );
+    var cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi );
+    var letter  = value.substring( 0, 1 ), // [ T ]
+        number  = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ]
+        control = value.substring( 8, 9 ), // [ C ]
+        all_sum = 0,
+        even_sum = 0,
+        odd_sum = 0,
+        i, n,
+        control_digit,
+        control_letter;
 
-		sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === "" ? 0 : parseInt( secondDigit, 10 ) );
-	}
+    function isOdd( n ) {
+      return n % 2 === 0;
+    }
 
-	/* The first (position 1) is a letter following the following criteria:
-	 *	A. Corporations
-	 *	B. LLCs
-	 *	C. General partnerships
-	 *	D. Companies limited partnerships
-	 *	E. Communities of goods
-	 *	F. Cooperative Societies
-	 *	G. Associations
-	 *	H. Communities of homeowners in horizontal property regime
-	 *	J. Civil Societies
-	 *	K. Old format
-	 *	L. Old format
-	 *	M. Old format
-	 *	N. Nonresident entities
-	 *	P. Local authorities
-	 *	Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
-	 *	R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
-	 *	S. Organs of State Administration and regions
-	 *	V. Agrarian Transformation
-	 *	W. Permanent establishments of non-resident in Spain
-	 */
-	if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
-		sum += "";
-		controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
-		value += controlDigit;
-		return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
-	}
+    // Quick format test
+    if ( value.length !== 9 || !cifRegEx.test( value ) ) {
+      return false;
+    }
 
-	return false;
+    for ( i = 0; i < number.length; i++ ) {
+      n = parseInt( number[ i ], 10 );
 
-}, "Please specify a valid CIF number." );
+      // Odd positions
+      if ( isOdd( i ) ) {
 
-/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
- * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
- * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
- */
-$.validator.addMethod("creditcardtypes", function(value, element, param) {
-	if (/[^0-9\-]+/.test(value)) {
-		return false;
-	}
+        // Odd positions are multiplied first.
+        n *= 2;
 
-	value = value.replace(/\D/g, "");
+        // If the multiplication is bigger than 10 we need to adjust
+        odd_sum += n < 10 ? n : n - 9;
 
-	var validTypes = 0x0000;
+        // Even positions
+        // Just sum them
+      } else {
+        even_sum += n;
+      }
+    }
 
-	if (param.mastercard) {
-		validTypes |= 0x0001;
-	}
-	if (param.visa) {
-		validTypes |= 0x0002;
-	}
-	if (param.amex) {
-		validTypes |= 0x0004;
-	}
-	if (param.dinersclub) {
-		validTypes |= 0x0008;
-	}
-	if (param.enroute) {
-		validTypes |= 0x0010;
-	}
-	if (param.discover) {
-		validTypes |= 0x0020;
-	}
-	if (param.jcb) {
-		validTypes |= 0x0040;
-	}
-	if (param.unknown) {
-		validTypes |= 0x0080;
-	}
-	if (param.all) {
-		validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
-	}
-	if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
-		return value.length === 16;
-	}
-	if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
-		return value.length === 16;
-	}
-	if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
-		return value.length === 15;
-	}
-	if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
-		return value.length === 14;
-	}
-	if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
-		return value.length === 15;
-	}
-	if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
-		return value.length === 16;
-	}
-	if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
-		return value.length === 16;
-	}
-	if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
-		return value.length === 15;
-	}
-	if (validTypes & 0x0080) { //unknown
-		return true;
-	}
-	return false;
-}, "Please enter a valid credit card number.");
+    all_sum = even_sum + odd_sum;
+    control_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString();
+    control_digit = parseInt( control_digit, 10 ) > 9 ? "0" : control_digit;
+    control_letter = "JABCDEFGHI".substr( control_digit, 1 ).toString();
 
-/**
- * Validates currencies with any given symbols by @jameslouiz
- * Symbols can be optional or required. Symbols required by default
- *
- * Usage examples:
- *  currency: ["£", false] - Use false for soft currency validation
- *  currency: ["$", false]
- *  currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
- *
- *  <input class="currencyInput" name="currencyInput">
- *
- * Soft symbol checking
- *  currencyInput: {
- *     currency: ["$", false]
- *  }
- *
- * Strict symbol checking (default)
- *  currencyInput: {
- *     currency: "$"
- *     //OR
- *     currency: ["$", true]
- *  }
- *
- * Multiple Symbols
- *  currencyInput: {
- *     currency: "$,£,¢"
- *  }
- */
-$.validator.addMethod("currency", function(value, element, param) {
+    // Control must be a digit
+    if ( letter.match( /[ABEH]/ ) ) {
+      return control === control_digit;
+
+      // Control must be a letter
+    } else if ( letter.match( /[KPQS]/ ) ) {
+      return control === control_letter;
+    }
+
+    // Can be either
+    return control === control_digit || control === control_letter;
+
+  }, "Please specify a valid CIF number." );
+
+  /*
+   * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.
+   * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.
+   */
+  $.validator.addMethod( "cpfBR", function( value ) {
+
+    // Removing special characters from value
+    value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
+
+    // Checking value to have 11 digits only
+    if ( value.length !== 11 ) {
+      return false;
+    }
+
+    var sum = 0,
+        firstCN, secondCN, checkResult, i;
+
+    firstCN = parseInt( value.substring( 9, 10 ), 10 );
+    secondCN = parseInt( value.substring( 10, 11 ), 10 );
+
+    checkResult = function( sum, cn ) {
+      var result = ( sum * 10 ) % 11;
+      if ( ( result === 10 ) || ( result === 11 ) ) {
+        result = 0;
+      }
+      return ( result === cn );
+    };
+
+    // Checking for dump data
+    if ( value === "" ||
+        value === "00000000000" ||
+        value === "11111111111" ||
+        value === "22222222222" ||
+        value === "33333333333" ||
+        value === "44444444444" ||
+        value === "55555555555" ||
+        value === "66666666666" ||
+        value === "77777777777" ||
+        value === "88888888888" ||
+        value === "99999999999"
+    ) {
+      return false;
+    }
+
+    // Step 1 - using first Check Number:
+    for ( i = 1; i <= 9; i++ ) {
+      sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i );
+    }
+
+    // If first Check Number (CN) is valid, move to Step 2 - using second Check Number:
+    if ( checkResult( sum, firstCN ) ) {
+      sum = 0;
+      for ( i = 1; i <= 10; i++ ) {
+        sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i );
+      }
+      return checkResult( sum, secondCN );
+    }
+    return false;
+
+  }, "Please specify a valid CPF number" );
+
+// https://jqueryvalidation.org/creditcard-method/
+// based on https://en.wikipedia.org/wiki/Luhn_algorithm
+  $.validator.addMethod( "creditcard", function( value, element ) {
+    if ( this.optional( element ) ) {
+      return "dependency-mismatch";
+    }
+
+    // Accept only spaces, digits and dashes
+    if ( /[^0-9 \-]+/.test( value ) ) {
+      return false;
+    }
+
+    var nCheck = 0,
+        nDigit = 0,
+        bEven = false,
+        n, cDigit;
+
+    value = value.replace( /\D/g, "" );
+
+    // Basing min and max length on
+    // https://developer.ean.com/general_info/Valid_Credit_Card_Types
+    if ( value.length < 13 || value.length > 19 ) {
+      return false;
+    }
+
+    for ( n = value.length - 1; n >= 0; n-- ) {
+      cDigit = value.charAt( n );
+      nDigit = parseInt( cDigit, 10 );
+      if ( bEven ) {
+        if ( ( nDigit *= 2 ) > 9 ) {
+          nDigit -= 9;
+        }
+      }
+
+      nCheck += nDigit;
+      bEven = !bEven;
+    }
+
+    return ( nCheck % 10 ) === 0;
+  }, "Please enter a valid credit card number." );
+
+  /* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
+   * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
+   * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
+   */
+  $.validator.addMethod( "creditcardtypes", function( value, element, param ) {
+    if ( /[^0-9\-]+/.test( value ) ) {
+      return false;
+    }
+
+    value = value.replace( /\D/g, "" );
+
+    var validTypes = 0x0000;
+
+    if ( param.mastercard ) {
+      validTypes |= 0x0001;
+    }
+    if ( param.visa ) {
+      validTypes |= 0x0002;
+    }
+    if ( param.amex ) {
+      validTypes |= 0x0004;
+    }
+    if ( param.dinersclub ) {
+      validTypes |= 0x0008;
+    }
+    if ( param.enroute ) {
+      validTypes |= 0x0010;
+    }
+    if ( param.discover ) {
+      validTypes |= 0x0020;
+    }
+    if ( param.jcb ) {
+      validTypes |= 0x0040;
+    }
+    if ( param.unknown ) {
+      validTypes |= 0x0080;
+    }
+    if ( param.all ) {
+      validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
+    }
+    if ( validTypes & 0x0001 && /^(5[12345])/.test( value ) ) { // Mastercard
+      return value.length === 16;
+    }
+    if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa
+      return value.length === 16;
+    }
+    if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex
+      return value.length === 15;
+    }
+    if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub
+      return value.length === 14;
+    }
+    if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute
+      return value.length === 15;
+    }
+    if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover
+      return value.length === 16;
+    }
+    if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb
+      return value.length === 16;
+    }
+    if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb
+      return value.length === 15;
+    }
+    if ( validTypes & 0x0080 ) { // Unknown
+      return true;
+    }
+    return false;
+  }, "Please enter a valid credit card number." );
+
+  /**
+   * Validates currencies with any given symbols by @jameslouiz
+   * Symbols can be optional or required. Symbols required by default
+   *
+   * Usage examples:
+   *  currency: ["£", false] - Use false for soft currency validation
+   *  currency: ["$", false]
+   *  currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
+   *
+   *  <input class="currencyInput" name="currencyInput">
+   *
+   * Soft symbol checking
+   *  currencyInput: {
+   *     currency: ["$", false]
+   *  }
+   *
+   * Strict symbol checking (default)
+   *  currencyInput: {
+   *     currency: "$"
+   *     //OR
+   *     currency: ["$", true]
+   *  }
+   *
+   * Multiple Symbols
+   *  currencyInput: {
+   *     currency: "$,£,¢"
+   *  }
+   */
+  $.validator.addMethod( "currency", function( value, element, param ) {
     var isParamString = typeof param === "string",
-        symbol = isParamString ? param : param[0],
-        soft = isParamString ? true : param[1],
+        symbol = isParamString ? param : param[ 0 ],
+        soft = isParamString ? true : param[ 1 ],
         regex;
 
-    symbol = symbol.replace(/,/g, "");
+    symbol = symbol.replace( /,/g, "" );
     symbol = soft ? symbol + "]" : symbol + "]?";
     regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
-    regex = new RegExp(regex);
-    return this.optional(element) || regex.test(value);
+    regex = new RegExp( regex );
+    return this.optional( element ) || regex.test( value );
 
-}, "Please specify a valid currency");
+  }, "Please specify a valid currency" );
 
-$.validator.addMethod("dateFA", function(value, element) {
-	return this.optional(element) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(value);
-}, "Please enter a correct date");
+  $.validator.addMethod( "dateFA", function( value, element ) {
+    return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value );
+  }, $.validator.messages.date );
 
-/**
- * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
- *
- * @example $.validator.methods.date("01/01/1900")
- * @result true
- *
- * @example $.validator.methods.date("01/13/1990")
- * @result false
- *
- * @example $.validator.methods.date("01.01.1900")
- * @result false
- *
- * @example <input name="pippo" class="{dateITA:true}" />
- * @desc Declares an optional input element whose value must be a valid date.
- *
- * @name $.validator.methods.dateITA
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod("dateITA", function(value, element) {
-	var check = false,
-		re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
-		adata, gg, mm, aaaa, xdata;
-	if ( re.test(value)) {
-		adata = value.split("/");
-		gg = parseInt(adata[0], 10);
-		mm = parseInt(adata[1], 10);
-		aaaa = parseInt(adata[2], 10);
-		xdata = new Date(aaaa, mm - 1, gg, 12, 0, 0, 0);
-		if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth () === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
-			check = true;
-		} else {
-			check = false;
-		}
-	} else {
-		check = false;
-	}
-	return this.optional(element) || check;
-}, "Please enter a correct date");
+  /**
+   * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
+   *
+   * @example $.validator.methods.date("01/01/1900")
+   * @result true
+   *
+   * @example $.validator.methods.date("01/13/1990")
+   * @result false
+   *
+   * @example $.validator.methods.date("01.01.1900")
+   * @result false
+   *
+   * @example <input name="pippo" class="{dateITA:true}" />
+   * @desc Declares an optional input element whose value must be a valid date.
+   *
+   * @name $.validator.methods.dateITA
+   * @type Boolean
+   * @cat Plugins/Validate/Methods
+   */
+  $.validator.addMethod( "dateITA", function( value, element ) {
+    var check = false,
+        re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
+        adata, gg, mm, aaaa, xdata;
+    if ( re.test( value ) ) {
+      adata = value.split( "/" );
+      gg = parseInt( adata[ 0 ], 10 );
+      mm = parseInt( adata[ 1 ], 10 );
+      aaaa = parseInt( adata[ 2 ], 10 );
+      xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );
+      if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
+        check = true;
+      } else {
+        check = false;
+      }
+    } else {
+      check = false;
+    }
+    return this.optional( element ) || check;
+  }, $.validator.messages.date );
 
-$.validator.addMethod("dateNL", function(value, element) {
-	return this.optional(element) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(value);
-}, "Please enter a correct date");
+  $.validator.addMethod( "dateNL", function( value, element ) {
+    return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value );
+  }, $.validator.messages.date );
 
 // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
-$.validator.addMethod("extension", function(value, element, param) {
-	param = typeof param === "string" ? param.replace(/,/g, "|") : "png|jpe?g|gif";
-	return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
-}, $.validator.format("Please enter a value with a valid extension."));
+  $.validator.addMethod( "extension", function( value, element, param ) {
+    param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif";
+    return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) );
+  }, $.validator.format( "Please enter a value with a valid extension." ) );
 
-/**
- * Dutch giro account numbers (not bank numbers) have max 7 digits
- */
-$.validator.addMethod("giroaccountNL", function(value, element) {
-	return this.optional(element) || /^[0-9]{1,7}$/.test(value);
-}, "Please specify a valid giro account number");
+  /**
+   * Dutch giro account numbers (not bank numbers) have max 7 digits
+   */
+  $.validator.addMethod( "giroaccountNL", function( value, element ) {
+    return this.optional( element ) || /^[0-9]{1,7}$/.test( value );
+  }, "Please specify a valid giro account number" );
 
-/**
- * IBAN is the international bank account number.
- * It has a country - specific format, that is checked here too
- */
-$.validator.addMethod("iban", function(value, element) {
-	// some quick simple tests to prevent needless work
-	if (this.optional(element)) {
-		return true;
-	}
+  /**
+   * IBAN is the international bank account number.
+   * It has a country - specific format, that is checked here too
+   *
+   * Validation is case-insensitive. Please make sure to normalize input yourself.
+   */
+  $.validator.addMethod( "iban", function( value, element ) {
 
-	// remove spaces and to upper case
-	var iban = value.replace(/ /g, "").toUpperCase(),
-		ibancheckdigits = "",
-		leadingZeroes = true,
-		cRest = "",
-		cOperator = "",
-		countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
+    // Some quick simple tests to prevent needless work
+    if ( this.optional( element ) ) {
+      return true;
+    }
 
-	if (!(/^([a-zA-Z0-9]{4} ){2,8}[a-zA-Z0-9]{1,4}|[a-zA-Z0-9]{12,34}$/.test(iban))) {
-		return false;
-	}
+    // Remove spaces and to upper case
+    var iban = value.replace( / /g, "" ).toUpperCase(),
+        ibancheckdigits = "",
+        leadingZeroes = true,
+        cRest = "",
+        cOperator = "",
+        countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
 
-	// check the country code and find the country specific format
-	countrycode = iban.substring(0, 2);
-	bbancountrypatterns = {
-		"AL": "\\d{8}[\\dA-Z]{16}",
-		"AD": "\\d{8}[\\dA-Z]{12}",
-		"AT": "\\d{16}",
-		"AZ": "[\\dA-Z]{4}\\d{20}",
-		"BE": "\\d{12}",
-		"BH": "[A-Z]{4}[\\dA-Z]{14}",
-		"BA": "\\d{16}",
-		"BR": "\\d{23}[A-Z][\\dA-Z]",
-		"BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
-		"CR": "\\d{17}",
-		"HR": "\\d{17}",
-		"CY": "\\d{8}[\\dA-Z]{16}",
-		"CZ": "\\d{20}",
-		"DK": "\\d{14}",
-		"DO": "[A-Z]{4}\\d{20}",
-		"EE": "\\d{16}",
-		"FO": "\\d{14}",
-		"FI": "\\d{14}",
-		"FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
-		"GE": "[\\dA-Z]{2}\\d{16}",
-		"DE": "\\d{18}",
-		"GI": "[A-Z]{4}[\\dA-Z]{15}",
-		"GR": "\\d{7}[\\dA-Z]{16}",
-		"GL": "\\d{14}",
-		"GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
-		"HU": "\\d{24}",
-		"IS": "\\d{22}",
-		"IE": "[\\dA-Z]{4}\\d{14}",
-		"IL": "\\d{19}",
-		"IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
-		"KZ": "\\d{3}[\\dA-Z]{13}",
-		"KW": "[A-Z]{4}[\\dA-Z]{22}",
-		"LV": "[A-Z]{4}[\\dA-Z]{13}",
-		"LB": "\\d{4}[\\dA-Z]{20}",
-		"LI": "\\d{5}[\\dA-Z]{12}",
-		"LT": "\\d{16}",
-		"LU": "\\d{3}[\\dA-Z]{13}",
-		"MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
-		"MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
-		"MR": "\\d{23}",
-		"MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
-		"MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
-		"MD": "[\\dA-Z]{2}\\d{18}",
-		"ME": "\\d{18}",
-		"NL": "[A-Z]{4}\\d{10}",
-		"NO": "\\d{11}",
-		"PK": "[\\dA-Z]{4}\\d{16}",
-		"PS": "[\\dA-Z]{4}\\d{21}",
-		"PL": "\\d{24}",
-		"PT": "\\d{21}",
-		"RO": "[A-Z]{4}[\\dA-Z]{16}",
-		"SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
-		"SA": "\\d{2}[\\dA-Z]{18}",
-		"RS": "\\d{18}",
-		"SK": "\\d{20}",
-		"SI": "\\d{15}",
-		"ES": "\\d{20}",
-		"SE": "\\d{20}",
-		"CH": "\\d{5}[\\dA-Z]{12}",
-		"TN": "\\d{20}",
-		"TR": "\\d{5}[\\dA-Z]{17}",
-		"AE": "\\d{3}\\d{16}",
-		"GB": "[A-Z]{4}\\d{14}",
-		"VG": "[\\dA-Z]{4}\\d{16}"
-	};
+    // Check for IBAN code length.
+    // It contains:
+    // country code ISO 3166-1 - two letters,
+    // two check digits,
+    // Basic Bank Account Number (BBAN) - up to 30 chars
+    var minimalIBANlength = 5;
+    if ( iban.length < minimalIBANlength ) {
+      return false;
+    }
 
-	bbanpattern = bbancountrypatterns[countrycode];
-	// As new countries will start using IBAN in the
-	// future, we only check if the countrycode is known.
-	// This prevents false negatives, while almost all
-	// false positives introduced by this, will be caught
-	// by the checksum validation below anyway.
-	// Strict checking should return FALSE for unknown
-	// countries.
-	if (typeof bbanpattern !== "undefined") {
-		ibanregexp = new RegExp("^[A-Z]{2}\\d{2}" + bbanpattern + "$", "");
-		if (!(ibanregexp.test(iban))) {
-			return false; // invalid country specific format
-		}
-	}
+    // Check the country code and find the country specific format
+    countrycode = iban.substring( 0, 2 );
+    bbancountrypatterns = {
+      "AL": "\\d{8}[\\dA-Z]{16}",
+      "AD": "\\d{8}[\\dA-Z]{12}",
+      "AT": "\\d{16}",
+      "AZ": "[\\dA-Z]{4}\\d{20}",
+      "BE": "\\d{12}",
+      "BH": "[A-Z]{4}[\\dA-Z]{14}",
+      "BA": "\\d{16}",
+      "BR": "\\d{23}[A-Z][\\dA-Z]",
+      "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
+      "CR": "\\d{17}",
+      "HR": "\\d{17}",
+      "CY": "\\d{8}[\\dA-Z]{16}",
+      "CZ": "\\d{20}",
+      "DK": "\\d{14}",
+      "DO": "[A-Z]{4}\\d{20}",
+      "EE": "\\d{16}",
+      "FO": "\\d{14}",
+      "FI": "\\d{14}",
+      "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
+      "GE": "[\\dA-Z]{2}\\d{16}",
+      "DE": "\\d{18}",
+      "GI": "[A-Z]{4}[\\dA-Z]{15}",
+      "GR": "\\d{7}[\\dA-Z]{16}",
+      "GL": "\\d{14}",
+      "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
+      "HU": "\\d{24}",
+      "IS": "\\d{22}",
+      "IE": "[\\dA-Z]{4}\\d{14}",
+      "IL": "\\d{19}",
+      "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
+      "KZ": "\\d{3}[\\dA-Z]{13}",
+      "KW": "[A-Z]{4}[\\dA-Z]{22}",
+      "LV": "[A-Z]{4}[\\dA-Z]{13}",
+      "LB": "\\d{4}[\\dA-Z]{20}",
+      "LI": "\\d{5}[\\dA-Z]{12}",
+      "LT": "\\d{16}",
+      "LU": "\\d{3}[\\dA-Z]{13}",
+      "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
+      "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
+      "MR": "\\d{23}",
+      "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
+      "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
+      "MD": "[\\dA-Z]{2}\\d{18}",
+      "ME": "\\d{18}",
+      "NL": "[A-Z]{4}\\d{10}",
+      "NO": "\\d{11}",
+      "PK": "[\\dA-Z]{4}\\d{16}",
+      "PS": "[\\dA-Z]{4}\\d{21}",
+      "PL": "\\d{24}",
+      "PT": "\\d{21}",
+      "RO": "[A-Z]{4}[\\dA-Z]{16}",
+      "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
+      "SA": "\\d{2}[\\dA-Z]{18}",
+      "RS": "\\d{18}",
+      "SK": "\\d{20}",
+      "SI": "\\d{15}",
+      "ES": "\\d{20}",
+      "SE": "\\d{20}",
+      "CH": "\\d{5}[\\dA-Z]{12}",
+      "TN": "\\d{20}",
+      "TR": "\\d{5}[\\dA-Z]{17}",
+      "AE": "\\d{3}\\d{16}",
+      "GB": "[A-Z]{4}\\d{14}",
+      "VG": "[\\dA-Z]{4}\\d{16}"
+    };
 
-	// now check the checksum, first convert to digits
-	ibancheck = iban.substring(4, iban.length) + iban.substring(0, 4);
-	for (i = 0; i < ibancheck.length; i++) {
-		charAt = ibancheck.charAt(i);
-		if (charAt !== "0") {
-			leadingZeroes = false;
-		}
-		if (!leadingZeroes) {
-			ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(charAt);
-		}
-	}
+    bbanpattern = bbancountrypatterns[ countrycode ];
 
-	// calculate the result of: ibancheckdigits % 97
-	for (p = 0; p < ibancheckdigits.length; p++) {
-		cChar = ibancheckdigits.charAt(p);
-		cOperator = "" + cRest + "" + cChar;
-		cRest = cOperator % 97;
-	}
-	return cRest === 1;
-}, "Please specify a valid IBAN");
+    // As new countries will start using IBAN in the
+    // future, we only check if the countrycode is known.
+    // This prevents false negatives, while almost all
+    // false positives introduced by this, will be caught
+    // by the checksum validation below anyway.
+    // Strict checking should return FALSE for unknown
+    // countries.
+    if ( typeof bbanpattern !== "undefined" ) {
+      ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" );
+      if ( !( ibanregexp.test( iban ) ) ) {
+        return false; // Invalid country specific format
+      }
+    }
 
-$.validator.addMethod("integer", function(value, element) {
-	return this.optional(element) || /^-?\d+$/.test(value);
-}, "A positive or negative non-decimal number please");
+    // Now check the checksum, first convert to digits
+    ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 );
+    for ( i = 0; i < ibancheck.length; i++ ) {
+      charAt = ibancheck.charAt( i );
+      if ( charAt !== "0" ) {
+        leadingZeroes = false;
+      }
+      if ( !leadingZeroes ) {
+        ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt );
+      }
+    }
 
-$.validator.addMethod("ipv4", function(value, element) {
-	return this.optional(element) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value);
-}, "Please enter a valid IP v4 address.");
+    // Calculate the result of: ibancheckdigits % 97
+    for ( p = 0; p < ibancheckdigits.length; p++ ) {
+      cChar = ibancheckdigits.charAt( p );
+      cOperator = "" + cRest + "" + cChar;
+      cRest = cOperator % 97;
+    }
+    return cRest === 1;
+  }, "Please specify a valid IBAN" );
 
-$.validator.addMethod("ipv6", function(value, element) {
-        if (value == '::')
-            return true;
+  $.validator.addMethod( "integer", function( value, element ) {
+    return this.optional( element ) || /^-?\d+$/.test( value );
+  }, "A positive or negative non-decimal number please" );
 
-	return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);
-}, "Please enter a valid IP v6 address.");
+  $.validator.addMethod( "ipv4", function( value, element ) {
+    return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value );
+  }, "Please enter a valid IP v4 address." );
 
-$.validator.addMethod("lettersonly", function(value, element) {
-	return this.optional(element) || /^[a-z]+$/i.test(value);
-}, "Letters only please");
+  $.validator.addMethod( "ipv6", function( value, element ) {
+    return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value );
+  }, "Please enter a valid IP v6 address." );
 
-$.validator.addMethod("letterswithbasicpunc", function(value, element) {
-	return this.optional(element) || /^[a-z\-.,()'"\s]+$/i.test(value);
-}, "Letters or punctuation only please");
+  $.validator.addMethod( "lettersonly", function( value, element ) {
+    return this.optional( element ) || /^[a-z]+$/i.test( value );
+  }, "Letters only please" );
 
-$.validator.addMethod("mobileNL", function(value, element) {
-	return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
-}, "Please specify a valid mobile number");
+  $.validator.addMethod( "letterswithbasicpunc", function( value, element ) {
+    return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value );
+  }, "Letters or punctuation only please" );
 
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-$.validator.addMethod("mobileUK", function(phone_number, element) {
-	phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
-	return this.optional(element) || phone_number.length > 9 &&
-		phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/);
-}, "Please specify a valid mobile number");
+  $.validator.addMethod( "mobileNL", function( value, element ) {
+    return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
+  }, "Please specify a valid mobile number" );
 
-/*
- * The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
- */
-$.validator.addMethod( "nieES", function( value ) {
-	"use strict";
+  /* For UK phone functions, do the following server side processing:
+   * Compare original input with this RegEx pattern:
+   * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
+   * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
+   * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
+   * A number of very detailed GB telephone number RegEx patterns can also be found at:
+   * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
+   */
+  $.validator.addMethod( "mobileUK", function( phone_number, element ) {
+    phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
+    return this.optional( element ) || phone_number.length > 9 &&
+        phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ );
+  }, "Please specify a valid mobile number" );
 
-	value = value.toUpperCase();
+  $.validator.addMethod( "netmask", function( value, element ) {
+    return this.optional( element ) || /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test( value );
+  }, "Please enter a valid netmask." );
 
-	// Basic format test
-	if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
-		return false;
-	}
+  /*
+   * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish
+   * authorities to any foreigner.
+   *
+   * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal
+   * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to
+   * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter.
+   */
+  $.validator.addMethod( "nieES", function( value, element ) {
+    "use strict";
 
-	// Test NIE
-	//T
-	if ( /^[T]{1}/.test( value ) ) {
-		return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
-	}
+    if ( this.optional( element ) ) {
+      return true;
+    }
 
-	//XYZ
-	if ( /^[XYZ]{1}/.test( value ) ) {
-		return (
-			value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
-				value.replace( "X", "0" )
-					.replace( "Y", "1" )
-					.replace( "Z", "2" )
-					.substring( 0, 8 ) % 23
-			)
-		);
-	}
+    var nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi );
+    var validChars = "TRWAGMYFPDXBNJZSQVHLCKET",
+        letter = value.substr( value.length - 1 ).toUpperCase(),
+        number;
 
-	return false;
+    value = value.toString().toUpperCase();
 
-}, "Please specify a valid NIE number." );
+    // Quick format test
+    if ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) {
+      return false;
+    }
 
-/*
- * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
- */
-$.validator.addMethod( "nifES", function( value ) {
-	"use strict";
+    // X means same number
+    // Y means number + 10000000
+    // Z means number + 20000000
+    value = value.replace( /^[X]/, "0" )
+        .replace( /^[Y]/, "1" )
+        .replace( /^[Z]/, "2" );
 
-	value = value.toUpperCase();
+    number = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 );
 
-	// Basic format test
-	if ( !value.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)") ) {
-		return false;
-	}
+    return validChars.charAt( parseInt( number, 10 ) % 23 ) === letter;
 
-	// Test NIF
-	if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
-		return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
-	}
-	// Test specials NIF (starts with K, L or M)
-	if ( /^[KLM]{1}/.test( value ) ) {
-		return ( value[ 8 ] === String.fromCharCode( 64 ) );
-	}
+  }, "Please specify a valid NIE number." );
 
-	return false;
+  /*
+   * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
+   */
+  $.validator.addMethod( "nifES", function( value, element ) {
+    "use strict";
 
-}, "Please specify a valid NIF number." );
+    if ( this.optional( element ) ) {
+      return true;
+    }
 
-$.validator.addMethod("nowhitespace", function(value, element) {
-	return this.optional(element) || /^\S+$/i.test(value);
-}, "No white space please");
+    value = value.toUpperCase();
 
-/**
-* Return true if the field value matches the given format RegExp
-*
-* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
-* @result true
-*
-* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
-* @result false
-*
-* @name $.validator.methods.pattern
-* @type Boolean
-* @cat Plugins/Validate/Methods
-*/
-$.validator.addMethod("pattern", function(value, element, param) {
-	if (this.optional(element)) {
-		return true;
-	}
-	if (typeof param === "string") {
-		param = new RegExp(param);
-	}
-	return param.test(value);
-}, "Invalid format.");
+    // Basic format test
+    if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
+      return false;
+    }
 
-/**
- * Dutch phone numbers have 10 digits (or 11 and start with +31).
- */
-$.validator.addMethod("phoneNL", function(value, element) {
-	return this.optional(element) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(value);
-}, "Please specify a valid phone number.");
+    // Test NIF
+    if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
+      return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
+    }
 
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-$.validator.addMethod("phoneUK", function(phone_number, element) {
-	phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
-	return this.optional(element) || phone_number.length > 9 &&
-		phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/);
-}, "Please specify a valid phone number");
+    // Test specials NIF (starts with K, L or M)
+    if ( /^[KLM]{1}/.test( value ) ) {
+      return ( value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 1 ) % 23 ) );
+    }
 
-/**
- * matches US phone number format
- *
- * where the area code may not start with 1 and the prefix may not start with 1
- * allows '-' or ' ' as a separator and allows parens around area code
- * some people may want to put a '1' in front of their number
- *
- * 1(212)-999-2345 or
- * 212 999 2344 or
- * 212-999-0983
- *
- * but not
- * 111-123-5434
- * and not
- * 212 123 4567
- */
-$.validator.addMethod("phoneUS", function(phone_number, element) {
-	phone_number = phone_number.replace(/\s+/g, "");
-	return this.optional(element) || phone_number.length > 9 &&
-		phone_number.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/);
-}, "Please specify a valid phone number");
+    return false;
 
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
-$.validator.addMethod("phonesUK", function(phone_number, element) {
-	phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
-	return this.optional(element) || phone_number.length > 9 &&
-		phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/);
-}, "Please specify a valid uk phone number");
+  }, "Please specify a valid NIF number." );
 
-/**
- * Matches a valid Canadian Postal Code
- *
- * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
- * @result true
- *
- * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
- * @result false
- *
- * @name jQuery.validator.methods.postalCodeCA
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod( "postalCodeCA", function( value, element ) {
-	return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test( value );
-}, "Please specify a valid postal code" );
+  /*
+   * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies
+   */
+  $.validator.addMethod( "nipPL", function( value ) {
+    "use strict";
 
-/* Matches Italian postcode (CAP) */
-$.validator.addMethod("postalcodeIT", function(value, element) {
-	return this.optional(element) || /^\d{5}$/.test(value);
-}, "Please specify a valid postal code");
+    value = value.replace( /[^0-9]/g, "" );
 
-$.validator.addMethod("postalcodeNL", function(value, element) {
-	return this.optional(element) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(value);
-}, "Please specify a valid postal code");
+    if ( value.length !== 10 ) {
+      return false;
+    }
+
+    var arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ];
+    var intSum = 0;
+    for ( var i = 0; i < 9; i++ ) {
+      intSum += arrSteps[ i ] * value[ i ];
+    }
+    var int2 = intSum % 11;
+    var intControlNr = ( int2 === 10 ) ? 0 : int2;
+
+    return ( intControlNr === parseInt( value[ 9 ], 10 ) );
+  }, "Please specify a valid NIP number." );
+
+  $.validator.addMethod( "notEqualTo", function( value, element, param ) {
+    return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param );
+  }, "Please enter a different value, values must not be the same." );
+
+  $.validator.addMethod( "nowhitespace", function( value, element ) {
+    return this.optional( element ) || /^\S+$/i.test( value );
+  }, "No white space please" );
+
+  /**
+   * Return true if the field value matches the given format RegExp
+   *
+   * @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
+   * @result true
+   *
+   * @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
+   * @result false
+   *
+   * @name $.validator.methods.pattern
+   * @type Boolean
+   * @cat Plugins/Validate/Methods
+   */
+  $.validator.addMethod( "pattern", function( value, element, param ) {
+    if ( this.optional( element ) ) {
+      return true;
+    }
+    if ( typeof param === "string" ) {
+      param = new RegExp( "^(?:" + param + ")$" );
+    }
+    return param.test( value );
+  }, "Invalid format." );
+
+  /**
+   * Dutch phone numbers have 10 digits (or 11 and start with +31).
+   */
+  $.validator.addMethod( "phoneNL", function( value, element ) {
+    return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
+  }, "Please specify a valid phone number." );
+
+  /* For UK phone functions, do the following server side processing:
+   * Compare original input with this RegEx pattern:
+   * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
+   * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
+   * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
+   * A number of very detailed GB telephone number RegEx patterns can also be found at:
+   * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
+   */
+
+// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
+  $.validator.addMethod( "phonesUK", function( phone_number, element ) {
+    phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
+    return this.optional( element ) || phone_number.length > 9 &&
+        phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ );
+  }, "Please specify a valid uk phone number" );
+
+  /* For UK phone functions, do the following server side processing:
+   * Compare original input with this RegEx pattern:
+   * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
+   * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
+   * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
+   * A number of very detailed GB telephone number RegEx patterns can also be found at:
+   * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
+   */
+  $.validator.addMethod( "phoneUK", function( phone_number, element ) {
+    phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
+    return this.optional( element ) || phone_number.length > 9 &&
+        phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ );
+  }, "Please specify a valid phone number" );
+
+  /**
+   * Matches US phone number format
+   *
+   * where the area code may not start with 1 and the prefix may not start with 1
+   * allows '-' or ' ' as a separator and allows parens around area code
+   * some people may want to put a '1' in front of their number
+   *
+   * 1(212)-999-2345 or
+   * 212 999 2344 or
+   * 212-999-0983
+   *
+   * but not
+   * 111-123-5434
+   * and not
+   * 212 123 4567
+   */
+  $.validator.addMethod( "phoneUS", function( phone_number, element ) {
+    phone_number = phone_number.replace( /\s+/g, "" );
+    return this.optional( element ) || phone_number.length > 9 &&
+        phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/ );
+  }, "Please specify a valid phone number" );
+
+  /*
+  * Valida CEPs do brasileiros:
+  *
+  * Formatos aceitos:
+  * 99999-999
+  * 99.999-999
+  * 99999999
+  */
+  $.validator.addMethod( "postalcodeBR", function( cep_value, element ) {
+    return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
+  }, "Informe um CEP válido." );
+
+  /**
+   * Matches a valid Canadian Postal Code
+   *
+   * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
+   * @result true
+   *
+   * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
+   * @result false
+   *
+   * @name jQuery.validator.methods.postalCodeCA
+   * @type Boolean
+   * @cat Plugins/Validate/Methods
+   */
+  $.validator.addMethod( "postalCodeCA", function( value, element ) {
+    return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value );
+  }, "Please specify a valid postal code" );
+
+  /* Matches Italian postcode (CAP) */
+  $.validator.addMethod( "postalcodeIT", function( value, element ) {
+    return this.optional( element ) || /^\d{5}$/.test( value );
+  }, "Please specify a valid postal code" );
+
+  $.validator.addMethod( "postalcodeNL", function( value, element ) {
+    return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value );
+  }, "Please specify a valid postal code" );
 
 // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
-$.validator.addMethod("postcodeUK", function(value, element) {
-	return this.optional(element) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(value);
-}, "Please specify a valid UK postcode");
+  $.validator.addMethod( "postcodeUK", function( value, element ) {
+    return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value );
+  }, "Please specify a valid UK postcode" );
 
-/*
- * Lets you say "at least X inputs that match selector Y must be filled."
- *
- * The end result is that neither of these inputs:
- *
- *	<input class="productinfo" name="partnumber">
- *	<input class="productinfo" name="description">
- *
- *	...will validate unless at least one of them is filled.
- *
- * partnumber:	{require_from_group: [1,".productinfo"]},
- * description: {require_from_group: [1,".productinfo"]}
- *
- * options[0]: number of fields that must be filled in the group
- * options[1]: CSS selector that defines the group of conditionally required fields
- */
-$.validator.addMethod("require_from_group", function(value, element, options) {
-	var $fields = $(options[1], element.form),
-		$fieldsFirst = $fields.eq(0),
-		validator = $fieldsFirst.data("valid_req_grp") ? $fieldsFirst.data("valid_req_grp") : $.extend({}, this),
-		isValid = $fields.filter(function() {
-			return validator.elementValue(this);
-		}).length >= options[0];
+  /*
+   * Lets you say "at least X inputs that match selector Y must be filled."
+   *
+   * The end result is that neither of these inputs:
+   *
+   *	<input class="productinfo" name="partnumber">
+   *	<input class="productinfo" name="description">
+   *
+   *	...will validate unless at least one of them is filled.
+   *
+   * partnumber:	{require_from_group: [1,".productinfo"]},
+   * description: {require_from_group: [1,".productinfo"]}
+   *
+   * options[0]: number of fields that must be filled in the group
+   * options[1]: CSS selector that defines the group of conditionally required fields
+   */
+  $.validator.addMethod( "require_from_group", function( value, element, options ) {
+    var $fields = $( options[ 1 ], element.form ),
+        $fieldsFirst = $fields.eq( 0 ),
+        validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ),
+        isValid = $fields.filter( function() {
+          return validator.elementValue( this );
+        } ).length >= options[ 0 ];
 
-	// Store the cloned validator for future validation
-	$fieldsFirst.data("valid_req_grp", validator);
+    // Store the cloned validator for future validation
+    $fieldsFirst.data( "valid_req_grp", validator );
 
-	// If element isn't being validated, run each require_from_group field's validation rules
-	if (!$(element).data("being_validated")) {
-		$fields.data("being_validated", true);
-		$fields.each(function() {
-			validator.element(this);
-		});
-		$fields.data("being_validated", false);
-	}
-	return isValid;
-}, $.validator.format("Please fill at least {0} of these fields."));
+    // If element isn't being validated, run each require_from_group field's validation rules
+    if ( !$( element ).data( "being_validated" ) ) {
+      $fields.data( "being_validated", true );
+      $fields.each( function() {
+        validator.element( this );
+      } );
+      $fields.data( "being_validated", false );
+    }
+    return isValid;
+  }, $.validator.format( "Please fill at least {0} of these fields." ) );
 
-/*
- * Lets you say "either at least X inputs that match selector Y must be filled,
- * OR they must all be skipped (left blank)."
- *
- * The end result, is that none of these inputs:
- *
- *	<input class="productinfo" name="partnumber">
- *	<input class="productinfo" name="description">
- *	<input class="productinfo" name="color">
- *
- *	...will validate unless either at least two of them are filled,
- *	OR none of them are.
- *
- * partnumber:	{skip_or_fill_minimum: [2,".productinfo"]},
- * description: {skip_or_fill_minimum: [2,".productinfo"]},
- * color:		{skip_or_fill_minimum: [2,".productinfo"]}
- *
- * options[0]: number of fields that must be filled in the group
- * options[1]: CSS selector that defines the group of conditionally required fields
- *
- */
-$.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
-	var $fields = $(options[1], element.form),
-		$fieldsFirst = $fields.eq(0),
-		validator = $fieldsFirst.data("valid_skip") ? $fieldsFirst.data("valid_skip") : $.extend({}, this),
-		numberFilled = $fields.filter(function() {
-			return validator.elementValue(this);
-		}).length,
-		isValid = numberFilled === 0 || numberFilled >= options[0];
+  /*
+   * Lets you say "either at least X inputs that match selector Y must be filled,
+   * OR they must all be skipped (left blank)."
+   *
+   * The end result, is that none of these inputs:
+   *
+   *	<input class="productinfo" name="partnumber">
+   *	<input class="productinfo" name="description">
+   *	<input class="productinfo" name="color">
+   *
+   *	...will validate unless either at least two of them are filled,
+   *	OR none of them are.
+   *
+   * partnumber:	{skip_or_fill_minimum: [2,".productinfo"]},
+   * description: {skip_or_fill_minimum: [2,".productinfo"]},
+   * color:		{skip_or_fill_minimum: [2,".productinfo"]}
+   *
+   * options[0]: number of fields that must be filled in the group
+   * options[1]: CSS selector that defines the group of conditionally required fields
+   *
+   */
+  $.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) {
+    var $fields = $( options[ 1 ], element.form ),
+        $fieldsFirst = $fields.eq( 0 ),
+        validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ),
+        numberFilled = $fields.filter( function() {
+          return validator.elementValue( this );
+        } ).length,
+        isValid = numberFilled === 0 || numberFilled >= options[ 0 ];
 
-	// Store the cloned validator for future validation
-	$fieldsFirst.data("valid_skip", validator);
+    // Store the cloned validator for future validation
+    $fieldsFirst.data( "valid_skip", validator );
 
-	// If element isn't being validated, run each skip_or_fill_minimum field's validation rules
-	if (!$(element).data("being_validated")) {
-		$fields.data("being_validated", true);
-		$fields.each(function() {
-			validator.element(this);
-		});
-		$fields.data("being_validated", false);
-	}
-	return isValid;
-}, $.validator.format("Please either skip these fields or fill at least {0} of them."));
+    // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
+    if ( !$( element ).data( "being_validated" ) ) {
+      $fields.data( "being_validated", true );
+      $fields.each( function() {
+        validator.element( this );
+      } );
+      $fields.data( "being_validated", false );
+    }
+    return isValid;
+  }, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) );
 
-/* Validates US States and/or Territories by @jdforsythe
- * Can be case insensitive or require capitalization - default is case insensitive
- * Can include US Territories or not - default does not
- * Can include US Military postal abbreviations (AA, AE, AP) - default does not
- *
- * Note: "States" always includes DC (District of Colombia)
- *
- * Usage examples:
- *
- *  This is the default - case insensitive, no territories, no military zones
- *  stateInput: {
- *     caseSensitive: false,
- *     includeTerritories: false,
- *     includeMilitary: false
- *  }
- *
- *  Only allow capital letters, no territories, no military zones
- *  stateInput: {
- *     caseSensitive: false
- *  }
- *
- *  Case insensitive, include territories but not military zones
- *  stateInput: {
- *     includeTerritories: true
- *  }
- *
- *  Only allow capital letters, include territories and military zones
- *  stateInput: {
- *     caseSensitive: true,
- *     includeTerritories: true,
- *     includeMilitary: true
- *  }
- *
- *
- *
- */
+  /* Validates US States and/or Territories by @jdforsythe
+   * Can be case insensitive or require capitalization - default is case insensitive
+   * Can include US Territories or not - default does not
+   * Can include US Military postal abbreviations (AA, AE, AP) - default does not
+   *
+   * Note: "States" always includes DC (District of Colombia)
+   *
+   * Usage examples:
+   *
+   *  This is the default - case insensitive, no territories, no military zones
+   *  stateInput: {
+   *     caseSensitive: false,
+   *     includeTerritories: false,
+   *     includeMilitary: false
+   *  }
+   *
+   *  Only allow capital letters, no territories, no military zones
+   *  stateInput: {
+   *     caseSensitive: false
+   *  }
+   *
+   *  Case insensitive, include territories but not military zones
+   *  stateInput: {
+   *     includeTerritories: true
+   *  }
+   *
+   *  Only allow capital letters, include territories and military zones
+   *  stateInput: {
+   *     caseSensitive: true,
+   *     includeTerritories: true,
+   *     includeMilitary: true
+   *  }
+   *
+   */
+  $.validator.addMethod( "stateUS", function( value, element, options ) {
+    var isDefault = typeof options === "undefined",
+        caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
+        includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
+        includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
+        regex;
 
-jQuery.validator.addMethod("stateUS", function(value, element, options) {
-	var isDefault = typeof options === "undefined",
-		caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
-		includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
-		includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
-		regex;
+    if ( !includeTerritories && !includeMilitary ) {
+      regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
+    } else if ( includeTerritories && includeMilitary ) {
+      regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
+    } else if ( includeTerritories ) {
+      regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
+    } else {
+      regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
+    }
 
-	if (!includeTerritories && !includeMilitary) {
-		regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
-	} else if (includeTerritories && includeMilitary) {
-		regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
-	} else if (includeTerritories) {
-		regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
-	} else {
-		regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
-	}
-
-	regex = caseSensitive ? new RegExp(regex) : new RegExp(regex, "i");
-	return this.optional(element) || regex.test(value);
-},
-"Please specify a valid state");
+    regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" );
+    return this.optional( element ) || regex.test( value );
+  }, "Please specify a valid state" );
 
 // TODO check if value starts with <, otherwise don't try stripping anything
-$.validator.addMethod("strippedminlength", function(value, element, param) {
-	return $(value).text().length >= param;
-}, $.validator.format("Please enter at least {0} characters"));
+  $.validator.addMethod( "strippedminlength", function( value, element, param ) {
+    return $( value ).text().length >= param;
+  }, $.validator.format( "Please enter at least {0} characters" ) );
 
-$.validator.addMethod("time", function(value, element) {
-	return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){1,2}$/.test(value);
-}, "Please enter a valid time, between 00:00 and 23:59");
+  $.validator.addMethod( "time", function( value, element ) {
+    return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
+  }, "Please enter a valid time, between 00:00 and 23:59" );
 
-$.validator.addMethod("time12h", function(value, element) {
-	return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
-}, "Please enter a valid time in 12-hour am/pm format");
+  $.validator.addMethod( "time12h", function( value, element ) {
+    return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value );
+  }, "Please enter a valid time in 12-hour am/pm format" );
 
-// same as url, but TLD is optional
-$.validator.addMethod("url2", function(value, element) {
-	return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
-}, $.validator.messages.url);
+// Same as url, but TLD is optional
+  $.validator.addMethod( "url2", function( value, element ) {
+    return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
+  }, $.validator.messages.url );
 
-/**
- * Return true, if the value is a valid vehicle identification number (VIN).
- *
- * Works with all kind of text inputs.
- *
- * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
- * @desc Declares a required input element whose value must be a valid vehicle identification number.
- *
- * @name $.validator.methods.vinUS
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod("vinUS", function(v) {
-	if (v.length !== 17) {
-		return false;
-	}
+  /**
+   * Return true, if the value is a valid vehicle identification number (VIN).
+   *
+   * Works with all kind of text inputs.
+   *
+   * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
+   * @desc Declares a required input element whose value must be a valid vehicle identification number.
+   *
+   * @name $.validator.methods.vinUS
+   * @type Boolean
+   * @cat Plugins/Validate/Methods
+   */
+  $.validator.addMethod( "vinUS", function( v ) {
+    if ( v.length !== 17 ) {
+      return false;
+    }
 
-	var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
-		VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
-		FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
-		rs = 0,
-		i, n, d, f, cd, cdv;
+    var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
+        VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
+        FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
+        rs = 0,
+        i, n, d, f, cd, cdv;
 
-	for (i = 0; i < 17; i++) {
-		f = FL[i];
-		d = v.slice(i, i + 1);
-		if (i === 8) {
-			cdv = d;
-		}
-		if (!isNaN(d)) {
-			d *= f;
-		} else {
-			for (n = 0; n < LL.length; n++) {
-				if (d.toUpperCase() === LL[n]) {
-					d = VL[n];
-					d *= f;
-					if (isNaN(cdv) && n === 8) {
-						cdv = LL[n];
-					}
-					break;
-				}
-			}
-		}
-		rs += d;
-	}
-	cd = rs % 11;
-	if (cd === 10) {
-		cd = "X";
-	}
-	if (cd === cdv) {
-		return true;
-	}
-	return false;
-}, "The specified vehicle identification number (VIN) is invalid.");
+    for ( i = 0; i < 17; i++ ) {
+      f = FL[ i ];
+      d = v.slice( i, i + 1 );
+      if ( i === 8 ) {
+        cdv = d;
+      }
+      if ( !isNaN( d ) ) {
+        d *= f;
+      } else {
+        for ( n = 0; n < LL.length; n++ ) {
+          if ( d.toUpperCase() === LL[ n ] ) {
+            d = VL[ n ];
+            d *= f;
+            if ( isNaN( cdv ) && n === 8 ) {
+              cdv = LL[ n ];
+            }
+            break;
+          }
+        }
+      }
+      rs += d;
+    }
+    cd = rs % 11;
+    if ( cd === 10 ) {
+      cd = "X";
+    }
+    if ( cd === cdv ) {
+      return true;
+    }
+    return false;
+  }, "The specified vehicle identification number (VIN) is invalid." );
 
-$.validator.addMethod("zipcodeUS", function(value, element) {
-	return this.optional(element) || /^\d{5}(-\d{4})?$/.test(value);
-}, "The specified US ZIP Code is invalid");
+  $.validator.addMethod( "zipcodeUS", function( value, element ) {
+    return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value );
+  }, "The specified US ZIP Code is invalid" );
 
-$.validator.addMethod("ziprange", function(value, element) {
-	return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value);
-}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx");
-
-}));
+  $.validator.addMethod( "ziprange", function( value, element ) {
+    return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value );
+  }, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" );
+  return $;
+}));
\ No newline at end of file
diff --git a/ui/lib/jquery.validate.js b/ui/lib/jquery.validate.js
index 3b6c812..abc357d1 100644
--- a/ui/lib/jquery.validate.js
+++ b/ui/lib/jquery.validate.js
@@ -1,24 +1,27 @@
-/*!
- * jQuery Validation Plugin v1.13.0
- *
- * http://jqueryvalidation.org/
- *
- * Copyright (c) 2014 Jörn Zaefferer
- * Released under the MIT license
- */
-(function( factory ) {
-	if ( typeof define === "function" && define.amd ) {
-		define( ["jquery"], factory );
-	} else {
-		factory( jQuery );
-	}
-}(function( $ ) {
+/*!
+ * jQuery Validation Plugin v1.17.0
+ *
+ * https://jqueryvalidation.org/
+ *
+ * Copyright (c) 2017 Jörn Zaefferer
+ * Released under the MIT license
+ */
+(function( factory ) {
+	if ( typeof define === "function" && define.amd ) {
+		define( ["jquery"], factory );
+	} else if (typeof module === "object" && module.exports) {
+		module.exports = factory( require( "jquery" ) );
+	} else {
+		factory( jQuery );
+	}
+}(function( $ ) {
+
+$.extend( $.fn, {
 
-$.extend($.fn, {
-	// http://jqueryvalidation.org/validate/
+	// https://jqueryvalidation.org/validate/
 	validate: function( options ) {
 
-		// if nothing is selected, return nothing; can't chain anyway
+		// If nothing is selected, return nothing; can't chain anyway
 		if ( !this.length ) {
 			if ( options && options.debug && window.console ) {
 				console.warn( "Nothing selected, can't validate, returning nothing." );
@@ -26,7 +29,7 @@
 			return;
 		}
 
-		// check if a validator for this form was already created
+		// Check if a validator for this form was already created
 		var validator = $.data( this[ 0 ], "validator" );
 		if ( validator ) {
 			return validator;
@@ -40,48 +43,61 @@
 
 		if ( validator.settings.onsubmit ) {
 
-			this.validateDelegate( ":submit", "click", function( event ) {
-				if ( validator.settings.submitHandler ) {
-					validator.submitButton = event.target;
-				}
-				// allow suppressing validation by adding a cancel class to the submit button
-				if ( $( event.target ).hasClass( "cancel" ) ) {
+			this.on( "click.validate", ":submit", function( event ) {
+
+				// Track the used submit button to properly handle scripted
+				// submits later.
+				validator.submitButton = event.currentTarget;
+
+				// Allow suppressing validation by adding a cancel class to the submit button
+				if ( $( this ).hasClass( "cancel" ) ) {
 					validator.cancelSubmit = true;
 				}
 
-				// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
-				if ( $( event.target ).attr( "formnovalidate" ) !== undefined ) {
+				// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
+				if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
 					validator.cancelSubmit = true;
 				}
-			});
+			} );
 
-			// validate the form on submit
-			this.submit( function( event ) {
+			// Validate the form on submit
+			this.on( "submit.validate", function( event ) {
 				if ( validator.settings.debug ) {
-					// prevent form submit to be able to see console output
+
+					// Prevent form submit to be able to see console output
 					event.preventDefault();
 				}
 				function handle() {
-					var hidden;
+					var hidden, result;
+
+					// Insert a hidden input as a replacement for the missing submit button
+					// The hidden input is inserted in two cases:
+					//   - A user defined a `submitHandler`
+					//   - There was a pending request due to `remote` method and `stopRequest()`
+					//     was called to submit the form in case it's valid
+					if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
+						hidden = $( "<input type='hidden'/>" )
+							.attr( "name", validator.submitButton.name )
+							.val( $( validator.submitButton ).val() )
+							.appendTo( validator.currentForm );
+					}
+
 					if ( validator.settings.submitHandler ) {
-						if ( validator.submitButton ) {
-							// insert a hidden input as a replacement for the missing submit button
-							hidden = $( "<input type='hidden'/>" )
-								.attr( "name", validator.submitButton.name )
-								.val( $( validator.submitButton ).val() )
-								.appendTo( validator.currentForm );
-						}
-						validator.settings.submitHandler.call( validator, validator.currentForm, event );
-						if ( validator.submitButton ) {
-							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
+						result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
+						if ( hidden ) {
+
+							// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
 							hidden.remove();
 						}
+						if ( result !== undefined ) {
+							return result;
+						}
 						return false;
 					}
 					return true;
 				}
 
-				// prevent submit for invalid forms or custom submit handlers
+				// Prevent submit for invalid forms or custom submit handlers
 				if ( validator.cancelSubmit ) {
 					validator.cancelSubmit = false;
 					return handle();
@@ -96,41 +112,52 @@
 					validator.focusInvalid();
 					return false;
 				}
-			});
+			} );
 		}
 
 		return validator;
 	},
-	// http://jqueryvalidation.org/valid/
+
+	// https://jqueryvalidation.org/valid/
 	valid: function() {
-		var valid, validator;
+		var valid, validator, errorList;
 
 		if ( $( this[ 0 ] ).is( "form" ) ) {
 			valid = this.validate().form();
 		} else {
+			errorList = [];
 			valid = true;
 			validator = $( this[ 0 ].form ).validate();
 			this.each( function() {
 				valid = validator.element( this ) && valid;
-			});
+				if ( !valid ) {
+					errorList = errorList.concat( validator.errorList );
+				}
+			} );
+			validator.errorList = errorList;
 		}
 		return valid;
 	},
-	// attributes: space separated list of attributes to retrieve and remove
-	removeAttrs: function( attributes ) {
-		var result = {},
-			$element = this;
-		$.each( attributes.split( /\s/ ), function( index, value ) {
-			result[ value ] = $element.attr( value );
-			$element.removeAttr( value );
-		});
-		return result;
-	},
-	// http://jqueryvalidation.org/rules/
+
+	// https://jqueryvalidation.org/rules/
 	rules: function( command, argument ) {
 		var element = this[ 0 ],
 			settings, staticRules, existingRules, data, param, filtered;
 
+		// If nothing is selected, return empty object; can't chain anyway
+		if ( element == null ) {
+			return;
+		}
+
+		if ( !element.form && element.hasAttribute( "contenteditable" ) ) {
+			element.form = this.closest( "form" )[ 0 ];
+			element.name = this.attr( "name" );
+		}
+
+		if ( element.form == null ) {
+			return;
+		}
+
 		if ( command ) {
 			settings = $.data( element.form, "validator" ).settings;
 			staticRules = settings.rules;
@@ -138,7 +165,8 @@
 			switch ( command ) {
 			case "add":
 				$.extend( existingRules, $.validator.normalizeRule( argument ) );
-				// remove messages from rules, but allow them to be set separately
+
+				// Remove messages from rules, but allow them to be set separately
 				delete existingRules.messages;
 				staticRules[ element.name ] = existingRules;
 				if ( argument.messages ) {
@@ -154,10 +182,7 @@
 				$.each( argument.split( /\s/ ), function( index, method ) {
 					filtered[ method ] = existingRules[ method ];
 					delete existingRules[ method ];
-					if ( method === "required" ) {
-						$( element ).removeAttr( "aria-required" );
-					}
-				});
+				} );
 				return filtered;
 			}
 		}
@@ -171,49 +196,52 @@
 			$.validator.staticRules( element )
 		), element );
 
-		// make sure required is at front
+		// Make sure required is at front
 		if ( data.required ) {
 			param = data.required;
 			delete data.required;
 			data = $.extend( { required: param }, data );
-			$( element ).attr( "aria-required", "true" );
 		}
 
-		// make sure remote is at back
+		// Make sure remote is at back
 		if ( data.remote ) {
 			param = data.remote;
 			delete data.remote;
-			data = $.extend( data, { remote: param });
+			data = $.extend( data, { remote: param } );
 		}
 
 		return data;
 	}
-});
+} );
 
 // Custom selectors
-$.extend( $.expr[ ":" ], {
-	// http://jqueryvalidation.org/blank-selector/
+$.extend( $.expr.pseudos || $.expr[ ":" ], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
+
+	// https://jqueryvalidation.org/blank-selector/
 	blank: function( a ) {
 		return !$.trim( "" + $( a ).val() );
 	},
-	// http://jqueryvalidation.org/filled-selector/
+
+	// https://jqueryvalidation.org/filled-selector/
 	filled: function( a ) {
-		return !!$.trim( "" + $( a ).val() );
+		var val = $( a ).val();
+		return val !== null && !!$.trim( "" + val );
 	},
-	// http://jqueryvalidation.org/unchecked-selector/
+
+	// https://jqueryvalidation.org/unchecked-selector/
 	unchecked: function( a ) {
 		return !$( a ).prop( "checked" );
 	}
-});
+} );
 
-// constructor for validator
+// Constructor for validator
 $.validator = function( options, form ) {
 	this.settings = $.extend( true, {}, $.validator.defaults, options );
 	this.currentForm = form;
 	this.init();
 };
 
-// http://jqueryvalidation.org/jQuery.validator.format/
+// https://jqueryvalidation.org/jQuery.validator.format/
 $.validator.format = function( source, params ) {
 	if ( arguments.length === 1 ) {
 		return function() {
@@ -222,6 +250,9 @@
 			return $.validator.format.apply( this, args );
 		};
 	}
+	if ( params === undefined ) {
+		return source;
+	}
 	if ( arguments.length > 2 && params.constructor !== Array  ) {
 		params = $.makeArray( arguments ).slice( 1 );
 	}
@@ -231,8 +262,8 @@
 	$.each( params, function( i, n ) {
 		source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
 			return n;
-		});
-	});
+		} );
+	} );
 	return source;
 };
 
@@ -243,8 +274,10 @@
 		groups: {},
 		rules: {},
 		errorClass: "error",
+		pendingClass: "pending",
 		validClass: "valid",
 		errorElement: "label",
+		focusCleanup: false,
 		focusInvalid: true,
 		errorContainer: $( [] ),
 		errorLabelContainer: $( [] ),
@@ -254,8 +287,8 @@
 		onfocusin: function( element ) {
 			this.lastActive = element;
 
-			// hide error label and remove error class on focus if enabled
-			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
+			// Hide error label and remove error class on focus if enabled
+			if ( this.settings.focusCleanup ) {
 				if ( this.settings.unhighlight ) {
 					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
 				}
@@ -268,18 +301,39 @@
 			}
 		},
 		onkeyup: function( element, event ) {
-			if ( event.which === 9 && this.elementValue( element ) === "" ) {
+
+			// Avoid revalidate the field when pressing one of the following keys
+			// Shift       => 16
+			// Ctrl        => 17
+			// Alt         => 18
+			// Caps lock   => 20
+			// End         => 35
+			// Home        => 36
+			// Left arrow  => 37
+			// Up arrow    => 38
+			// Right arrow => 39
+			// Down arrow  => 40
+			// Insert      => 45
+			// Num lock    => 144
+			// AltGr key   => 225
+			var excludedKeys = [
+				16, 17, 18, 20, 35, 36, 37,
+				38, 39, 40, 45, 144, 225
+			];
+
+			if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
 				return;
-			} else if ( element.name in this.submitted || element === this.lastElement ) {
+			} else if ( element.name in this.submitted || element.name in this.invalid ) {
 				this.element( element );
 			}
 		},
 		onclick: function( element ) {
-			// click on selects, radiobuttons and checkboxes
+
+			// Click on selects, radiobuttons and checkboxes
 			if ( element.name in this.submitted ) {
 				this.element( element );
 
-			// or option elements, check parent select in that case
+			// Or option elements, check parent select in that case
 			} else if ( element.parentNode.name in this.submitted ) {
 				this.element( element.parentNode );
 			}
@@ -300,7 +354,7 @@
 		}
 	},
 
-	// http://jqueryvalidation.org/jQuery.validator.setDefaults/
+	// https://jqueryvalidation.org/jQuery.validator.setDefaults/
 	setDefaults: function( settings ) {
 		$.extend( $.validator.defaults, settings );
 	},
@@ -311,17 +365,17 @@
 		email: "Please enter a valid email address.",
 		url: "Please enter a valid URL.",
 		date: "Please enter a valid date.",
-		dateISO: "Please enter a valid date ( ISO ).",
+		dateISO: "Please enter a valid date (ISO).",
 		number: "Please enter a valid number.",
 		digits: "Please enter only digits.",
-		creditcard: "Please enter a valid credit card number.",
 		equalTo: "Please enter the same value again.",
 		maxlength: $.validator.format( "Please enter no more than {0} characters." ),
 		minlength: $.validator.format( "Please enter at least {0} characters." ),
 		rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
 		range: $.validator.format( "Please enter a value between {0} and {1}." ),
 		max: $.validator.format( "Please enter a value less than or equal to {0}." ),
-		min: $.validator.format( "Please enter a value greater than or equal to {0}." )
+		min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
+		step: $.validator.format( "Please enter a multiple of {0}." )
 	},
 
 	autoCreateRanges: false,
@@ -347,48 +401,52 @@
 				}
 				$.each( value, function( index, name ) {
 					groups[ name ] = key;
-				});
-			});
+				} );
+			} );
 			rules = this.settings.rules;
 			$.each( rules, function( key, value ) {
 				rules[ key ] = $.validator.normalizeRule( value );
-			});
+			} );
 
 			function delegate( event ) {
-				var validator = $.data( this[ 0 ].form, "validator" ),
+
+				// Set form expando on contenteditable
+				if ( !this.form && this.hasAttribute( "contenteditable" ) ) {
+					this.form = $( this ).closest( "form" )[ 0 ];
+					this.name = $( this ).attr( "name" );
+				}
+
+				var validator = $.data( this.form, "validator" ),
 					eventType = "on" + event.type.replace( /^validate/, "" ),
 					settings = validator.settings;
-				if ( settings[ eventType ] && !this.is( settings.ignore ) ) {
-					settings[ eventType ].call( validator, this[ 0 ], event );
+				if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
+					settings[ eventType ].call( validator, this, event );
 				}
 			}
+
 			$( this.currentForm )
-				.validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " +
-					"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
-					"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
-					"[type='week'], [type='time'], [type='datetime-local'], " +
-					"[type='range'], [type='color'], [type='radio'], [type='checkbox']",
-					"focusin focusout keyup", delegate)
+				.on( "focusin.validate focusout.validate keyup.validate",
+					":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
+					"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
+					"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
+					"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
+
 				// Support: Chrome, oldIE
 				// "select" is provided as event.target when clicking a option
-				.validateDelegate("select, option, [type='radio'], [type='checkbox']", "click", delegate);
+				.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
 
 			if ( this.settings.invalidHandler ) {
-				$( this.currentForm ).bind( "invalid-form.validate", this.settings.invalidHandler );
+				$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
 			}
-
-			// Add aria-required to any Static/Data/Class required fields before first validation
-			// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
-			$( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
 		},
 
-		// http://jqueryvalidation.org/Validator.form/
+		// https://jqueryvalidation.org/Validator.form/
 		form: function() {
 			this.checkForm();
 			$.extend( this.submitted, this.errorMap );
-			this.invalid = $.extend({}, this.errorMap );
+			this.invalid = $.extend( {}, this.errorMap );
 			if ( !this.valid() ) {
-				$( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
+				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
 			}
 			this.showErrors();
 			return this.valid();
@@ -402,13 +460,13 @@
 			return this.valid();
 		},
 
-		// http://jqueryvalidation.org/Validator.element/
+		// https://jqueryvalidation.org/Validator.element/
 		element: function( element ) {
 			var cleanElement = this.clean( element ),
 				checkElement = this.validationTargetFor( cleanElement ),
-				result = true;
-
-			this.lastElement = checkElement;
+				v = this,
+				result = true,
+				rs, group;
 
 			if ( checkElement === undefined ) {
 				delete this.invalid[ cleanElement.name ];
@@ -416,40 +474,61 @@
 				this.prepareElement( checkElement );
 				this.currentElements = $( checkElement );
 
-				result = this.check( checkElement ) !== false;
-				if ( result ) {
-					delete this.invalid[ checkElement.name ];
+				// If this element is grouped, then validate all group elements already
+				// containing a value
+				group = this.groups[ checkElement.name ];
+				if ( group ) {
+					$.each( this.groups, function( name, testgroup ) {
+						if ( testgroup === group && name !== checkElement.name ) {
+							cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
+							if ( cleanElement && cleanElement.name in v.invalid ) {
+								v.currentElements.push( cleanElement );
+								result = v.check( cleanElement ) && result;
+							}
+						}
+					} );
+				}
+
+				rs = this.check( checkElement ) !== false;
+				result = result && rs;
+				if ( rs ) {
+					this.invalid[ checkElement.name ] = false;
 				} else {
 					this.invalid[ checkElement.name ] = true;
 				}
-			}
-			// Add aria-invalid status for screen readers
-			$( element ).attr( "aria-invalid", !result );
 
-			if ( !this.numberOfInvalids() ) {
-				// Hide error containers on last error
-				this.toHide = this.toHide.add( this.containers );
+				if ( !this.numberOfInvalids() ) {
+
+					// Hide error containers on last error
+					this.toHide = this.toHide.add( this.containers );
+				}
+				this.showErrors();
+
+				// Add aria-invalid status for screen readers
+				$( element ).attr( "aria-invalid", !rs );
 			}
-			this.showErrors();
+
 			return result;
 		},
 
-		// http://jqueryvalidation.org/Validator.showErrors/
+		// https://jqueryvalidation.org/Validator.showErrors/
 		showErrors: function( errors ) {
 			if ( errors ) {
-				// add items to error list and map
+				var validator = this;
+
+				// Add items to error list and map
 				$.extend( this.errorMap, errors );
-				this.errorList = [];
-				for ( var name in errors ) {
-					this.errorList.push({
-						message: errors[ name ],
-						element: this.findByName( name )[ 0 ]
-					});
-				}
-				// remove items from success list
+				this.errorList = $.map( this.errorMap, function( message, name ) {
+					return {
+						message: message,
+						element: validator.findByName( name )[ 0 ]
+					};
+				} );
+
+				// Remove items from success list
 				this.successList = $.grep( this.successList, function( element ) {
 					return !( element.name in errors );
-				});
+				} );
 			}
 			if ( this.settings.showErrors ) {
 				this.settings.showErrors.call( this, this.errorMap, this.errorList );
@@ -458,19 +537,36 @@
 			}
 		},
 
-		// http://jqueryvalidation.org/Validator.resetForm/
+		// https://jqueryvalidation.org/Validator.resetForm/
 		resetForm: function() {
 			if ( $.fn.resetForm ) {
 				$( this.currentForm ).resetForm();
 			}
+			this.invalid = {};
 			this.submitted = {};
-			this.lastElement = null;
 			this.prepareForm();
 			this.hideErrors();
-			this.elements()
+			var elements = this.elements()
+				.removeData( "previousValue" )
+				.removeAttr( "aria-invalid" );
+
+			this.resetElements( elements );
+		},
+
+		resetElements: function( elements ) {
+			var i;
+
+			if ( this.settings.unhighlight ) {
+				for ( i = 0; elements[ i ]; i++ ) {
+					this.settings.unhighlight.call( this, elements[ i ],
+						this.settings.errorClass, "" );
+					this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
+				}
+			} else {
+				elements
 					.removeClass( this.settings.errorClass )
-					.removeData( "previousValue" )
-					.removeAttr( "aria-invalid" );
+					.removeClass( this.settings.validClass );
+			}
 		},
 
 		numberOfInvalids: function() {
@@ -482,7 +578,12 @@
 			var count = 0,
 				i;
 			for ( i in obj ) {
-				count++;
+
+				// This check allows counting elements with empty error
+				// message as invalid elements
+				if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
+					count++;
+				}
 			}
 			return count;
 		},
@@ -507,13 +608,15 @@
 		focusInvalid: function() {
 			if ( this.settings.focusInvalid ) {
 				try {
-					$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
+					$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
 					.filter( ":visible" )
 					.focus()
-					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
+
+					// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
 					.trigger( "focusin" );
 				} catch ( e ) {
-					// ignore IE throwing errors when focusing hidden elements
+
+					// Ignore IE throwing errors when focusing hidden elements
 				}
 			}
 		},
@@ -522,31 +625,38 @@
 			var lastActive = this.lastActive;
 			return lastActive && $.grep( this.errorList, function( n ) {
 				return n.element.name === lastActive.name;
-			}).length === 1 && lastActive;
+			} ).length === 1 && lastActive;
 		},
 
 		elements: function() {
 			var validator = this,
 				rulesCache = {};
 
-			// select all valid inputs inside the form (no submit or reset buttons)
+			// Select all valid inputs inside the form (no submit or reset buttons)
 			return $( this.currentForm )
-			.find( "input, select, textarea" )
-			.not( ":submit, :reset, :image, [disabled]" )
+			.find( "input, select, textarea, [contenteditable]" )
+			.not( ":submit, :reset, :image, :disabled" )
 			.not( this.settings.ignore )
 			.filter( function() {
-				if ( !this.name && validator.settings.debug && window.console ) {
+				var name = this.name || $( this ).attr( "name" ); // For contenteditable
+				if ( !name && validator.settings.debug && window.console ) {
 					console.error( "%o has no name assigned", this );
 				}
 
-				// select only the first element for each name, and only those with rules specified
-				if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
+				// Set form expando on contenteditable
+				if ( this.hasAttribute( "contenteditable" ) ) {
+					this.form = $( this ).closest( "form" )[ 0 ];
+					this.name = name;
+				}
+
+				// Select only the first element for each name, and only those with rules specified
+				if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
 					return false;
 				}
 
-				rulesCache[ this.name ] = true;
+				rulesCache[ name ] = true;
 				return true;
-			});
+			} );
 		},
 
 		clean: function( selector ) {
@@ -558,12 +668,16 @@
 			return $( this.settings.errorElement + "." + errorClass, this.errorContext );
 		},
 
-		reset: function() {
+		resetInternals: function() {
 			this.successList = [];
 			this.errorList = [];
 			this.errorMap = {};
 			this.toShow = $( [] );
 			this.toHide = $( [] );
+		},
+
+		reset: function() {
+			this.resetInternals();
 			this.currentElements = $( [] );
 		},
 
@@ -578,19 +692,48 @@
 		},
 
 		elementValue: function( element ) {
-			var val,
-				$element = $( element ),
-				type = element.type;
+			var $element = $( element ),
+				type = element.type,
+				val, idx;
 
 			if ( type === "radio" || type === "checkbox" ) {
-				return $( "input[name='" + element.name + "']:checked" ).val();
+				return this.findByName( element.name ).filter( ":checked" ).val();
 			} else if ( type === "number" && typeof element.validity !== "undefined" ) {
-				return element.validity.badInput ? false : $element.val();
+				return element.validity.badInput ? "NaN" : $element.val();
 			}
 
-			val = $element.val();
+			if ( element.hasAttribute( "contenteditable" ) ) {
+				val = $element.text();
+			} else {
+				val = $element.val();
+			}
+
+			if ( type === "file" ) {
+
+				// Modern browser (chrome & safari)
+				if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
+					return val.substr( 12 );
+				}
+
+				// Legacy browsers
+				// Unix-based path
+				idx = val.lastIndexOf( "/" );
+				if ( idx >= 0 ) {
+					return val.substr( idx + 1 );
+				}
+
+				// Windows-based path
+				idx = val.lastIndexOf( "\\" );
+				if ( idx >= 0 ) {
+					return val.substr( idx + 1 );
+				}
+
+				// Just the file name
+				return val;
+			}
+
 			if ( typeof val === "string" ) {
-				return val.replace(/\r/g, "" );
+				return val.replace( /\r/g, "" );
 			}
 			return val;
 		},
@@ -601,18 +744,39 @@
 			var rules = $( element ).rules(),
 				rulesCount = $.map( rules, function( n, i ) {
 					return i;
-				}).length,
+				} ).length,
 				dependencyMismatch = false,
 				val = this.elementValue( element ),
-				result, method, rule;
+				result, method, rule, normalizer;
+
+			// Prioritize the local normalizer defined for this element over the global one
+			// if the former exists, otherwise user the global one in case it exists.
+			if ( typeof rules.normalizer === "function" ) {
+				normalizer = rules.normalizer;
+			} else if (	typeof this.settings.normalizer === "function" ) {
+				normalizer = this.settings.normalizer;
+			}
+
+			// If normalizer is defined, then call it to retreive the changed value instead
+			// of using the real one.
+			// Note that `this` in the normalizer is `element`.
+			if ( normalizer ) {
+				val = normalizer.call( element, val );
+
+				if ( typeof val !== "string" ) {
+					throw new TypeError( "The normalizer should return a string value." );
+				}
+
+				// Delete the normalizer from rules to avoid treating it as a pre-defined method.
+				delete rules.normalizer;
+			}
 
 			for ( method in rules ) {
 				rule = { method: method, parameters: rules[ method ] };
 				try {
-
 					result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
 
-					// if a method indicates that the field is optional and therefore valid,
+					// If a method indicates that the field is optional and therefore valid,
 					// don't mark it as valid when there are no other rules
 					if ( result === "dependency-mismatch" && rulesCount === 1 ) {
 						dependencyMismatch = true;
@@ -633,6 +797,10 @@
 					if ( this.settings.debug && window.console ) {
 						console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
 					}
+					if ( e instanceof TypeError ) {
+						e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
+					}
+
 					throw e;
 				}
 			}
@@ -645,7 +813,7 @@
 			return true;
 		},
 
-		// return the custom message for the given element and validation method
+		// Return the custom message for the given element and validation method
 		// specified in the element's HTML5 data attribute
 		// return the generic message if present and no method specific message is present
 		customDataMessage: function( element, method ) {
@@ -653,15 +821,15 @@
 				method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
 		},
 
-		// return the custom message for the given element name and validation method
+		// Return the custom message for the given element name and validation method
 		customMessage: function( name, method ) {
 			var m = this.settings.messages[ name ];
-			return m && ( m.constructor === String ? m : m[ method ]);
+			return m && ( m.constructor === String ? m : m[ method ] );
 		},
 
-		// return the first defined argument, allowing empty strings
+		// Return the first defined argument, allowing empty strings
 		findDefined: function() {
-			for ( var i = 0; i < arguments.length; i++) {
+			for ( var i = 0; i < arguments.length; i++ ) {
 				if ( arguments[ i ] !== undefined ) {
 					return arguments[ i ];
 				}
@@ -669,30 +837,47 @@
 			return undefined;
 		},
 
-		defaultMessage: function( element, method ) {
-			return this.findDefined(
-				this.customMessage( element.name, method ),
-				this.customDataMessage( element, method ),
-				// title is never undefined, so handle empty string as undefined
-				!this.settings.ignoreTitle && element.title || undefined,
-				$.validator.messages[ method ],
-				"<strong>Warning: No message defined for " + element.name + "</strong>"
-			);
-		},
+		// The second parameter 'rule' used to be a string, and extended to an object literal
+		// of the following form:
+		// rule = {
+		//     method: "method name",
+		//     parameters: "the given method parameters"
+		// }
+		//
+		// The old behavior still supported, kept to maintain backward compatibility with
+		// old code, and will be removed in the next major release.
+		defaultMessage: function( element, rule ) {
+			if ( typeof rule === "string" ) {
+				rule = { method: rule };
+			}
 
-		formatAndAdd: function( element, rule ) {
-			var message = this.defaultMessage( element, rule.method ),
+			var message = this.findDefined(
+					this.customMessage( element.name, rule.method ),
+					this.customDataMessage( element, rule.method ),
+
+					// 'title' is never undefined, so handle empty string as undefined
+					!this.settings.ignoreTitle && element.title || undefined,
+					$.validator.messages[ rule.method ],
+					"<strong>Warning: No message defined for " + element.name + "</strong>"
+				),
 				theregex = /\$?\{(\d+)\}/g;
 			if ( typeof message === "function" ) {
 				message = message.call( this, rule.parameters, element );
 			} else if ( theregex.test( message ) ) {
 				message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
 			}
-			this.errorList.push({
+
+			return message;
+		},
+
+		formatAndAdd: function( element, rule ) {
+			var message = this.defaultMessage( element, rule );
+
+			this.errorList.push( {
 				message: message,
 				element: element,
 				method: rule.method
-			});
+			} );
 
 			this.errorMap[ element.name ] = message;
 			this.submitted[ element.name ] = message;
@@ -737,23 +922,27 @@
 		},
 
 		invalidElements: function() {
-			return $( this.errorList ).map(function() {
+			return $( this.errorList ).map( function() {
 				return this.element;
-			});
+			} );
 		},
 
 		showLabel: function( element, message ) {
-			var place, group, errorID,
+			var place, group, errorID, v,
 				error = this.errorsFor( element ),
 				elementID = this.idOrName( element ),
 				describedBy = $( element ).attr( "aria-describedby" );
+
 			if ( error.length ) {
-				// refresh error/success class
+
+				// Refresh error/success class
 				error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
-				// replace message on existing label
+
+				// Replace message on existing label
 				error.html( message );
 			} else {
-				// create error element
+
+				// Create error element
 				error = $( "<" + this.settings.errorElement + ">" )
 					.attr( "id", elementID + "-error" )
 					.addClass( this.settings.errorClass )
@@ -762,31 +951,35 @@
 				// Maintain reference to the element to be placed into the DOM
 				place = error;
 				if ( this.settings.wrapper ) {
-					// make sure the element is visible, even in IE
+
+					// Make sure the element is visible, even in IE
 					// actually showing the wrapped element is handled elsewhere
 					place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
 				}
 				if ( this.labelContainer.length ) {
 					this.labelContainer.append( place );
 				} else if ( this.settings.errorPlacement ) {
-					this.settings.errorPlacement( place, $( element ) );
+					this.settings.errorPlacement.call( this, place, $( element ) );
 				} else {
 					place.insertAfter( element );
 				}
 
 				// Link error back to the element
 				if ( error.is( "label" ) ) {
+
 					// If the error is a label, then associate using 'for'
 					error.attr( "for", elementID );
-				} else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) {
+
 					// If the element is not a child of an associated label, then it's necessary
 					// to explicitly apply aria-describedby
-
+				} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
 					errorID = error.attr( "id" );
+
 					// Respect existing non-error aria-describedby
 					if ( !describedBy ) {
 						describedBy = errorID;
-					} else if ( !describedBy.match( new RegExp( "\b" + errorID + "\b" ) ) ) {
+					} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
+
 						// Add to end of list if not already present
 						describedBy += " " + errorID;
 					}
@@ -795,12 +988,13 @@
 					// If this element is grouped, then assign to all elements in the same group
 					group = this.groups[ element.name ];
 					if ( group ) {
-						$.each( this.groups, function( name, testgroup ) {
+						v = this;
+						$.each( v.groups, function( name, testgroup ) {
 							if ( testgroup === group ) {
-								$( "[name='" + name + "']", this.currentForm )
+								$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
 									.attr( "aria-describedby", error.attr( "id" ) );
 							}
-						});
+						} );
 					}
 				}
 			}
@@ -816,28 +1010,41 @@
 		},
 
 		errorsFor: function( element ) {
-			var name = this.idOrName( element ),
+			var name = this.escapeCssMeta( this.idOrName( element ) ),
 				describer = $( element ).attr( "aria-describedby" ),
 				selector = "label[for='" + name + "'], label[for='" + name + "'] *";
-			// aria-describedby should directly reference the error element
+
+			// 'aria-describedby' should directly reference the error element
 			if ( describer ) {
-				selector = selector + ", #" + describer.replace( /\s+/g, ", #" );
+				selector = selector + ", #" + this.escapeCssMeta( describer )
+					.replace( /\s+/g, ", #" );
 			}
+
 			return this
 				.errors()
 				.filter( selector );
 		},
 
+		// See https://api.jquery.com/category/selectors/, for CSS
+		// meta-characters that should be escaped in order to be used with JQuery
+		// as a literal part of a name/id or any selector.
+		escapeCssMeta: function( string ) {
+			return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
+		},
+
 		idOrName: function( element ) {
 			return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
 		},
 
 		validationTargetFor: function( element ) {
-			// if radio/checkbox, validate first element in group instead
+
+			// If radio/checkbox, validate first element in group instead
 			if ( this.checkable( element ) ) {
-				element = this.findByName( element.name ).not( this.settings.ignore )[ 0 ];
+				element = this.findByName( element.name );
 			}
-			return element;
+
+			// Always apply ignore filter
+			return $( element ).not( this.settings.ignore )[ 0 ];
 		},
 
 		checkable: function( element ) {
@@ -845,7 +1052,7 @@
 		},
 
 		findByName: function( name ) {
-			return $( this.currentForm ).find( "[name='" + name + "']" );
+			return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
 		},
 
 		getLength: function( value, element ) {
@@ -861,7 +1068,7 @@
 		},
 
 		depend: function( param, element ) {
-			return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true;
+			return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
 		},
 
 		dependTypes: {
@@ -884,32 +1091,58 @@
 		startRequest: function( element ) {
 			if ( !this.pending[ element.name ] ) {
 				this.pendingRequest++;
+				$( element ).addClass( this.settings.pendingClass );
 				this.pending[ element.name ] = true;
 			}
 		},
 
 		stopRequest: function( element, valid ) {
 			this.pendingRequest--;
-			// sometimes synchronization fails, make sure pendingRequest is never < 0
+
+			// Sometimes synchronization fails, make sure pendingRequest is never < 0
 			if ( this.pendingRequest < 0 ) {
 				this.pendingRequest = 0;
 			}
 			delete this.pending[ element.name ];
+			$( element ).removeClass( this.settings.pendingClass );
 			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
 				$( this.currentForm ).submit();
+
+				// Remove the hidden input that was used as a replacement for the
+				// missing submit button. The hidden input is added by `handle()`
+				// to ensure that the value of the used submit button is passed on
+				// for scripted submits triggered by this method
+				if ( this.submitButton ) {
+					$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
+				}
+
 				this.formSubmitted = false;
-			} else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) {
-				$( this.currentForm ).triggerHandler( "invalid-form", [ this ]);
+			} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
+				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
 				this.formSubmitted = false;
 			}
 		},
 
-		previousValue: function( element ) {
+		previousValue: function( element, method ) {
+			method = typeof method === "string" && method || "remote";
+
 			return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
 				old: null,
 				valid: true,
-				message: this.defaultMessage( element, "remote" )
-			});
+				message: this.defaultMessage( element, { method: method } )
+			} );
+		},
+
+		// Cleans up all forms and elements, removes validator-specific events
+		destroy: function() {
+			this.resetForm();
+
+			$( this.currentForm )
+				.off( ".validate" )
+				.removeData( "validator" )
+				.find( ".validate-equalTo-blur" )
+					.off( ".validate-equalTo" )
+					.removeClass( "validate-equalTo-blur" );
 		}
 
 	},
@@ -940,13 +1173,36 @@
 		if ( classes ) {
 			$.each( classes.split( " " ), function() {
 				if ( this in $.validator.classRuleSettings ) {
-					$.extend( rules, $.validator.classRuleSettings[ this ]);
+					$.extend( rules, $.validator.classRuleSettings[ this ] );
 				}
-			});
+			} );
 		}
 		return rules;
 	},
 
+	normalizeAttributeRule: function( rules, type, method, value ) {
+
+		// Convert the value to a number for number inputs, and for text for backwards compability
+		// allows type="date" and others to be compared as strings
+		if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
+			value = Number( value );
+
+			// Support Opera Mini, which returns NaN for undefined minlength
+			if ( isNaN( value ) ) {
+				value = undefined;
+			}
+		}
+
+		if ( value || value === 0 ) {
+			rules[ method ] = value;
+		} else if ( type === method && type !== "range" ) {
+
+			// Exception: the jquery validate 'range' method
+			// does not test for the html5 'range' type
+			rules[ method ] = true;
+		}
+	},
+
 	attributeRules: function( element ) {
 		var rules = {},
 			$element = $( element ),
@@ -955,36 +1211,26 @@
 
 		for ( method in $.validator.methods ) {
 
-			// support for <input required> in both html5 and older browsers
+			// Support for <input required> in both html5 and older browsers
 			if ( method === "required" ) {
 				value = element.getAttribute( method );
+
 				// Some browsers return an empty string for the required attribute
 				// and non-HTML5 browsers might have required="" markup
 				if ( value === "" ) {
 					value = true;
 				}
-				// force non-HTML5 browsers to return bool
+
+				// Force non-HTML5 browsers to return bool
 				value = !!value;
 			} else {
 				value = $element.attr( method );
 			}
 
-			// convert the value to a number for number inputs, and for text for backwards compability
-			// allows type="date" and others to be compared as strings
-			if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
-				value = Number( value );
-			}
-
-			if ( value || value === 0 ) {
-				rules[ method ] = value;
-			} else if ( type === method && type !== "range" ) {
-				// exception: the jquery validate 'range' method
-				// does not test for the html5 'range' type
-				rules[ method ] = true;
-			}
+			this.normalizeAttributeRule( rules, type, method, value );
 		}
 
-		// maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
+		// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
 		if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
 			delete rules.maxlength;
 		}
@@ -993,13 +1239,14 @@
 	},
 
 	dataRules: function( element ) {
-		var method, value,
-			rules = {}, $element = $( element );
+		var rules = {},
+			$element = $( element ),
+			type = element.getAttribute( "type" ),
+			method, value;
+
 		for ( method in $.validator.methods ) {
 			value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
-			if ( value !== undefined ) {
-				rules[ method ] = value;
-			}
+			this.normalizeAttributeRule( rules, type, method, value );
 		}
 		return rules;
 	},
@@ -1015,9 +1262,11 @@
 	},
 
 	normalizeRules: function( rules, element ) {
-		// handle dependency check
+
+		// Handle dependency check
 		$.each( rules, function( prop, val ) {
-			// ignore rule when param is explicitly false, eg. required:false
+
+			// Ignore rule when param is explicitly false, eg. required:false
 			if ( val === false ) {
 				delete rules[ prop ];
 				return;
@@ -1035,42 +1284,44 @@
 				if ( keepRule ) {
 					rules[ prop ] = val.param !== undefined ? val.param : true;
 				} else {
+					$.data( element.form, "validator" ).resetElements( $( element ) );
 					delete rules[ prop ];
 				}
 			}
-		});
+		} );
 
-		// evaluate parameters
+		// Evaluate parameters
 		$.each( rules, function( rule, parameter ) {
-			rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter;
-		});
+			rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
+		} );
 
-		// clean number parameters
-		$.each([ "minlength", "maxlength" ], function() {
+		// Clean number parameters
+		$.each( [ "minlength", "maxlength" ], function() {
 			if ( rules[ this ] ) {
 				rules[ this ] = Number( rules[ this ] );
 			}
-		});
-		$.each([ "rangelength", "range" ], function() {
+		} );
+		$.each( [ "rangelength", "range" ], function() {
 			var parts;
 			if ( rules[ this ] ) {
 				if ( $.isArray( rules[ this ] ) ) {
-					rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ];
+					rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
 				} else if ( typeof rules[ this ] === "string" ) {
-					parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ );
-					rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ];
+					parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
+					rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
 				}
 			}
-		});
+		} );
 
 		if ( $.validator.autoCreateRanges ) {
-			// auto-create ranges
-			if ( rules.min && rules.max ) {
+
+			// Auto-create ranges
+			if ( rules.min != null && rules.max != null ) {
 				rules.range = [ rules.min, rules.max ];
 				delete rules.min;
 				delete rules.max;
 			}
-			if ( rules.minlength && rules.maxlength ) {
+			if ( rules.minlength != null && rules.maxlength != null ) {
 				rules.rangelength = [ rules.minlength, rules.maxlength ];
 				delete rules.minlength;
 				delete rules.maxlength;
@@ -1086,13 +1337,13 @@
 			var transformed = {};
 			$.each( data.split( /\s/ ), function() {
 				transformed[ this ] = true;
-			});
+			} );
 			data = transformed;
 		}
 		return data;
 	},
 
-	// http://jqueryvalidation.org/jQuery.validator.addMethod/
+	// https://jqueryvalidation.org/jQuery.validator.addMethod/
 	addMethod: function( name, method, message ) {
 		$.validator.methods[ name ] = method;
 		$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
@@ -1101,172 +1352,181 @@
 		}
 	},
 
+	// https://jqueryvalidation.org/jQuery.validator.methods/
 	methods: {
 
-		// http://jqueryvalidation.org/required-method/
+		// https://jqueryvalidation.org/required-method/
 		required: function( value, element, param ) {
-			// check if dependency is met
+
+			// Check if dependency is met
 			if ( !this.depend( param, element ) ) {
 				return "dependency-mismatch";
 			}
 			if ( element.nodeName.toLowerCase() === "select" ) {
-				// could be an array for select-multiple or a string, both are fine this way
+
+				// Could be an array for select-multiple or a string, both are fine this way
 				var val = $( element ).val();
 				return val && val.length > 0;
 			}
 			if ( this.checkable( element ) ) {
 				return this.getLength( value, element ) > 0;
 			}
-			return $.trim( value ).length > 0;
+			return value.length > 0;
 		},
 
-		// http://jqueryvalidation.org/email-method/
+		// https://jqueryvalidation.org/email-method/
 		email: function( value, element ) {
-			// From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
+
+			// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
 			// Retrieved 2014-01-14
 			// If you have a problem with this implementation, report a bug against the above spec
 			// Or use custom methods to implement your own email validation
 			return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
 		},
 
-		// http://jqueryvalidation.org/url-method/
+		// https://jqueryvalidation.org/url-method/
 		url: function( value, element ) {
-			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
-			return this.optional( element ) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
+
+			// Copyright (c) 2010-2013 Diego Perini, MIT licensed
+			// https://gist.github.com/dperini/729294
+			// see also https://mathiasbynens.be/demo/url-regex
+			// modified to allow protocol-relative URLs
+			return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
 		},
 
-		// http://jqueryvalidation.org/date-method/
+		// https://jqueryvalidation.org/date-method/
 		date: function( value, element ) {
 			return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
 		},
 
-		// http://jqueryvalidation.org/dateISO-method/
+		// https://jqueryvalidation.org/dateISO-method/
 		dateISO: function( value, element ) {
 			return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
 		},
 
-		// http://jqueryvalidation.org/number-method/
+		// https://jqueryvalidation.org/number-method/
 		number: function( value, element ) {
-			return this.optional( element ) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
+			return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
 		},
 
-		// http://jqueryvalidation.org/digits-method/
+		// https://jqueryvalidation.org/digits-method/
 		digits: function( value, element ) {
 			return this.optional( element ) || /^\d+$/.test( value );
 		},
 
-		// http://jqueryvalidation.org/creditcard-method/
-		// based on http://en.wikipedia.org/wiki/Luhn/
-		creditcard: function( value, element ) {
-			if ( this.optional( element ) ) {
-				return "dependency-mismatch";
-			}
-			// accept only spaces, digits and dashes
-			if ( /[^0-9 \-]+/.test( value ) ) {
-				return false;
-			}
-			var nCheck = 0,
-				nDigit = 0,
-				bEven = false,
-				n, cDigit;
-
-			value = value.replace( /\D/g, "" );
-
-			// Basing min and max length on
-			// http://developer.ean.com/general_info/Valid_Credit_Card_Types
-			if ( value.length < 13 || value.length > 19 ) {
-				return false;
-			}
-
-			for ( n = value.length - 1; n >= 0; n--) {
-				cDigit = value.charAt( n );
-				nDigit = parseInt( cDigit, 10 );
-				if ( bEven ) {
-					if ( ( nDigit *= 2 ) > 9 ) {
-						nDigit -= 9;
-					}
-				}
-				nCheck += nDigit;
-				bEven = !bEven;
-			}
-
-			return ( nCheck % 10 ) === 0;
-		},
-
-		// http://jqueryvalidation.org/minlength-method/
+		// https://jqueryvalidation.org/minlength-method/
 		minlength: function( value, element, param ) {
-			var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
+			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
 			return this.optional( element ) || length >= param;
 		},
 
-		// http://jqueryvalidation.org/maxlength-method/
+		// https://jqueryvalidation.org/maxlength-method/
 		maxlength: function( value, element, param ) {
-			var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
+			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
 			return this.optional( element ) || length <= param;
 		},
 
-		// http://jqueryvalidation.org/rangelength-method/
+		// https://jqueryvalidation.org/rangelength-method/
 		rangelength: function( value, element, param ) {
-			var length = $.isArray( value ) ? value.length : this.getLength( $.trim( value ), element );
+			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
 			return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
 		},
 
-		// http://jqueryvalidation.org/min-method/
+		// https://jqueryvalidation.org/min-method/
 		min: function( value, element, param ) {
 			return this.optional( element ) || value >= param;
 		},
 
-		// http://jqueryvalidation.org/max-method/
+		// https://jqueryvalidation.org/max-method/
 		max: function( value, element, param ) {
 			return this.optional( element ) || value <= param;
 		},
 
-		// http://jqueryvalidation.org/range-method/
+		// https://jqueryvalidation.org/range-method/
 		range: function( value, element, param ) {
 			return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
 		},
 
-		// http://jqueryvalidation.org/equalTo-method/
+		// https://jqueryvalidation.org/step-method/
+		step: function( value, element, param ) {
+			var type = $( element ).attr( "type" ),
+				errorMessage = "Step attribute on input type " + type + " is not supported.",
+				supportedTypes = [ "text", "number", "range" ],
+				re = new RegExp( "\\b" + type + "\\b" ),
+				notSupported = type && !re.test( supportedTypes.join() ),
+				decimalPlaces = function( num ) {
+					var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
+					if ( !match ) {
+						return 0;
+					}
+
+					// Number of digits right of decimal point.
+					return match[ 1 ] ? match[ 1 ].length : 0;
+				},
+				toInt = function( num ) {
+					return Math.round( num * Math.pow( 10, decimals ) );
+				},
+				valid = true,
+				decimals;
+
+			// Works only for text, number and range input types
+			// TODO find a way to support input types date, datetime, datetime-local, month, time and week
+			if ( notSupported ) {
+				throw new Error( errorMessage );
+			}
+
+			decimals = decimalPlaces( param );
+
+			// Value can't have too many decimals
+			if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
+				valid = false;
+			}
+
+			return this.optional( element ) || valid;
+		},
+
+		// https://jqueryvalidation.org/equalTo-method/
 		equalTo: function( value, element, param ) {
-			// bind to the blur event of the target in order to revalidate whenever the target field is updated
-			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
+
+			// Bind to the blur event of the target in order to revalidate whenever the target field is updated
 			var target = $( param );
-			if ( this.settings.onfocusout ) {
-				target.unbind( ".validate-equalTo" ).bind( "blur.validate-equalTo", function() {
+			if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
+				target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
 					$( element ).valid();
-				});
+				} );
 			}
 			return value === target.val();
 		},
 
-		// http://jqueryvalidation.org/remote-method/
-		remote: function( value, element, param ) {
+		// https://jqueryvalidation.org/remote-method/
+		remote: function( value, element, param, method ) {
 			if ( this.optional( element ) ) {
 				return "dependency-mismatch";
 			}
 
-			var previous = this.previousValue( element ),
-				validator, data;
+			method = typeof method === "string" && method || "remote";
 
-			if (!this.settings.messages[ element.name ] ) {
+			var previous = this.previousValue( element, method ),
+				validator, data, optionDataString;
+
+			if ( !this.settings.messages[ element.name ] ) {
 				this.settings.messages[ element.name ] = {};
 			}
-			previous.originalMessage = this.settings.messages[ element.name ].remote;
-			this.settings.messages[ element.name ].remote = previous.message;
+			previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
+			this.settings.messages[ element.name ][ method ] = previous.message;
 
 			param = typeof param === "string" && { url: param } || param;
-
-			if ( previous.old === value ) {
+			optionDataString = $.param( $.extend( { data: value }, param.data ) );
+			if ( previous.old === optionDataString ) {
 				return previous.valid;
 			}
 
-			previous.old = value;
+			previous.old = optionDataString;
 			validator = this;
 			this.startRequest( element );
 			data = {};
 			data[ element.name ] = value;
 			$.ajax( $.extend( true, {
-				url: param,
 				mode: "abort",
 				port: "validate" + element.name,
 				dataType: "json",
@@ -1276,18 +1536,19 @@
 					var valid = response === true || response === "true",
 						errors, message, submitted;
 
-					validator.settings.messages[ element.name ].remote = previous.originalMessage;
+					validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
 					if ( valid ) {
 						submitted = validator.formSubmitted;
-						validator.prepareElement( element );
+						validator.resetInternals();
+						validator.toHide = validator.errorsFor( element );
 						validator.formSubmitted = submitted;
 						validator.successList.push( element );
-						delete validator.invalid[ element.name ];
+						validator.invalid[ element.name ] = false;
 						validator.showErrors();
 					} else {
 						errors = {};
-						message = response || validator.defaultMessage( element, "remote" );
-						errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message;
+						message = response || validator.defaultMessage( element, { method: method, parameters: value } );
+						errors[ element.name ] = previous.message = message;
 						validator.invalid[ element.name ] = true;
 						validator.showErrors( errors );
 					}
@@ -1297,61 +1558,44 @@
 			}, param ) );
 			return "pending";
 		}
-
 	}
 
-});
-
-$.format = function deprecated() {
-	throw "$.format has been deprecated. Please use $.validator.format instead.";
-};
-
-// ajax mode: abort
+} );
+
+// Ajax mode: abort
 // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
 // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
 
 var pendingRequests = {},
 	ajax;
+
 // Use a prefilter if available (1.5+)
 if ( $.ajaxPrefilter ) {
-	$.ajaxPrefilter(function( settings, _, xhr ) {
+	$.ajaxPrefilter( function( settings, _, xhr ) {
 		var port = settings.port;
 		if ( settings.mode === "abort" ) {
-			if ( pendingRequests[port] ) {
-				pendingRequests[port].abort();
+			if ( pendingRequests[ port ] ) {
+				pendingRequests[ port ].abort();
 			}
-			pendingRequests[port] = xhr;
+			pendingRequests[ port ] = xhr;
 		}
-	});
+	} );
 } else {
+
 	// Proxy ajax
 	ajax = $.ajax;
 	$.ajax = function( settings ) {
 		var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
 			port = ( "port" in settings ? settings : $.ajaxSettings ).port;
 		if ( mode === "abort" ) {
-			if ( pendingRequests[port] ) {
-				pendingRequests[port].abort();
+			if ( pendingRequests[ port ] ) {
+				pendingRequests[ port ].abort();
 			}
-			pendingRequests[port] = ajax.apply(this, arguments);
-			return pendingRequests[port];
+			pendingRequests[ port ] = ajax.apply( this, arguments );
+			return pendingRequests[ port ];
 		}
-		return ajax.apply(this, arguments);
+		return ajax.apply( this, arguments );
 	};
 }
-
-// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
-// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
-
-$.extend($.fn, {
-	validateDelegate: function( delegate, type, handler ) {
-		return this.bind(type, function( event ) {
-			var target = $(event.target);
-			if ( target.is(delegate) ) {
-				return handler.apply(target, arguments);
-			}
-		});
-	}
-});
-
+return $;
 }));
\ No newline at end of file
diff --git a/ui/modules/vpc/vpc.js b/ui/modules/vpc/vpc.js
index c07f444..ceeea3e 100644
--- a/ui/modules/vpc/vpc.js
+++ b/ui/modules/vpc/vpc.js
@@ -384,7 +384,7 @@
                 args.complete($chart);
               }
 
-              if ($chart.find('.connector-line.highlighted').size()) {
+              if ($chart.find('.connector-line.highlighted').length) {
                 $info.appendTo($chart).append(
                   $('<span>').addClass('color-key'),
                   $('<span>').html('= Contains a public network')
diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js
index 192c284..d2d6c1c 100644
--- a/ui/scripts/accounts.js
+++ b/ui/scripts/accounts.js
@@ -97,7 +97,6 @@
                             label: 'label.add.ldap.account',
                             isHeader: true,
                             preFilter: function(args) {
-                                //if (isAdmin() && true) { //for testing only
                                 if (isAdmin() && isLdapEnabled()) {
                                     return true;
                                 } else {
@@ -1360,9 +1359,6 @@
                                 };
 
                                 var password = args.data.password;
-                                if (md5Hashed) {
-                                    password = $.md5(password);
-                                }
                                 $.extend(data, {
                                     password: password
                                 });
@@ -1480,6 +1476,14 @@
                                                 form: {
                                                     title: 'label.action.change.password',
                                                     fields: {
+                                                        currentPassword: {
+                                                            label: 'label.current.password',
+                                                            isPassword: true,
+                                                            validation: {
+                                                                required: !(isAdmin() || isDomainAdmin())
+                                                            },
+                                                            id: 'currentPassword'
+                                                        },
                                                         newPassword: {
                                                             label: 'label.new.password',
                                                             isPassword: true,
@@ -1500,16 +1504,13 @@
                                                 },
                                                 after: function(args) {
                                                     start();
-
+                                                    var currentPassword = args.data.currentPassword;
                                                     var password = args.data.newPassword;
-
-                                                    if (md5Hashed)
-                                                        password = $.md5(password);
-
                                                     $.ajax({
                                                         url: createURL('updateUser'),
                                                         data: {
                                                             id: context.users[0].id,
+                                                            currentPassword: currentPassword,
                                                             password: password
                                                         },
                                                         type: "POST",
@@ -1522,6 +1523,9 @@
                                                     });
                                                 }
                                             });
+                                            if(isAdmin() || isDomainAdmin()){
+                                                $('div[rel=currentPassword]').hide();
+                                            }
                                         } else {
                                             cloudStack.dialog.notice({ message: _l('error.could.not.change.your.password.because.non.native.user') });
                                         }
diff --git a/ui/scripts/accountsWizard.js b/ui/scripts/accountsWizard.js
index 7fc4014..5b8e9a6 100644
--- a/ui/scripts/accountsWizard.js
+++ b/ui/scripts/accountsWizard.js
@@ -205,21 +205,11 @@
             }
 
             if (!ldapStatus) {
-                var password = args.data.password;
-                if (md5Hashed) {
-                    password = $.md5(password);
-                }
                 array1.push("&email=" + args.data.email);
                 array1.push("&firstname=" + args.data.firstname);
                 array1.push("&lastname=" + args.data.lastname);
 
-                password = args.data.password;
-                if (md5Hashed) {
-                    password = $.md5(password);
-                } else {
-                    password = todb(password);
-                }
-                array1.push("&password=" + password);
+                cloudStack.addPasswordToCommandUrlParameterArray(array1, args.data.password);
             }
 
             array1.push("&domainid=" + args.data.domainid);
diff --git a/ui/scripts/autoscaler.js b/ui/scripts/autoscaler.js
index e8ac044..da963fc 100644
--- a/ui/scripts/autoscaler.js
+++ b/ui/scripts/autoscaler.js
@@ -414,27 +414,20 @@
                     isHidden: true,
                     dependsOn: 'isAdvanced',
                     select: function(args) {
-                        $.ajax({
-                            url: createURL("listDiskOfferings&listAll=true"),
-                            dataType: "json",
-                            async: true,
-                            success: function(json) {
-                                var diskofferings = json.listdiskofferingsresponse.diskoffering;
-                                var items = [];
-                                items.push({
-                                    id: "",
-                                    description: ""
-                                });
-                                $(diskofferings).each(function() {
-                                    items.push({
-                                        id: this.id,
-                                        description: this.name
-                                    });
-                                });
-                                args.response.success({
-                                    data: items
-                                });
-                            }
+                        var diskOfferings = cloudStack.listDiskOfferings({listAll: true});
+                        var items = [];
+                        items.push({
+                            id: "",
+                            description: ""
+                        });
+                        $(diskOfferings).each(function() {
+                            items.push({
+                                id: this.id,
+                                description: this.name
+                            });
+                        });
+                        args.response.success({
+                            data: items
                         });
                     }
                 },
diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js
index 1190133..7faa8c5 100644
--- a/ui/scripts/cloudStack.js
+++ b/ui/scripts/cloudStack.js
@@ -223,13 +223,7 @@
                 var array1 = [];
                 array1.push("&username=" + encodeURIComponent(args.data.username));
 
-                var password;
-                if (md5HashedLogin)
-                    password = $.md5(args.data.password);
-                else
-                    password = todb(args.data.password);
-                array1.push("&password=" + password);
-
+                cloudStack.addPasswordToCommandUrlParameterArray(array1, args.data.password);
                 var domain;
                 if (args.data.domain != null && args.data.domain.length > 0) {
                     if (args.data.domain.charAt(0) != "/")
@@ -456,10 +450,10 @@
                 });
 
                 // Logout action
-                $('#user-options a').live('click', function() {
-                    loginArgs.logoutAction({
-                        context: cloudStack.context
-                    });
+                $(document).on('click', '#user-options a', function() {
+                  loginArgs.logoutAction({
+                    context: cloudStack.context
+                  });
                 });
 
                 window._reloadUI = function() {
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index f229d24..de8f472 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -1683,19 +1683,16 @@
                     dataProvider: function(args) {
                         var data = {};
                         listViewDataProvider(args, data);
-
-                        $.ajax({
-                            url: createURL('listDiskOfferings&isrecursive=true'),
+                        var listDiskOfferingsOptions = {
+                            isRecursive: true,
                             data: data,
-                            success: function(json) {
-                                var items = json.listdiskofferingsresponse.diskoffering;
-                                args.response.success({
-                                    data: items
-                                });
-                            },
                             error: function(data) {
                                 args.response.error(parseXMLHttpResponse(data));
                             }
+                        };
+                        var diskOfferings = cloudStack.listDiskOfferings(listDiskOfferingsOptions);
+                        args.response.success({
+                            data: diskOfferings
                         });
                     },
 
@@ -2297,16 +2294,14 @@
                                     var data = {
                                         id: args.context.diskOfferings[0].id
                                     };
-                                    $.ajax({
-                                        url: createURL('listDiskOfferings&isrecursive=true'),
-                                        data: data,
-                                        success: function(json) {
-                                            var item = json.listdiskofferingsresponse.diskoffering[0];
-                                            args.response.success({
-                                                actionFilter: diskOfferingActionfilter,
-                                                data: item
-                                            });
-                                        }
+                                    var listDiskOfferingsOptions = {
+                                        isRecursive: true,
+                                        data: data
+                                    };
+                                    var diskOfferings = cloudStack.listDiskOfferings(listDiskOfferingsOptions);
+                                    args.response.success({
+                                        actionFilter: diskOfferingActionfilter,
+                                        data: diskOfferings[0]
                                     });
                                 }
                             }
@@ -2562,7 +2557,7 @@
                                             $conservemode.find("input[type=checkbox]").removeAttr("disabled");
                                         }
 
-                                        $(':ui-dialog').dialog('option', 'position', 'center');
+                                        $('div.ui-dialog').css('top', '24px');
 
                                         //CS-16612 show all services regardless of guestIpType(Shared/Isolated)
                                         /*
@@ -3006,9 +3001,9 @@
                                                                                 });
                                                                             }
                                                                         } else { //canenableindividualservice == true
-                                                                            if ($thisProviderDropdown.context.name in providerDropdownsForciblyChangedTogether) { //if this provider dropdown is one of provider dropdowns forcibly changed together earlier, make other forcibly changed provider dropdowns restore default option (i.e. 1st option in dropdown)
+                                                                            if (this.name in providerDropdownsForciblyChangedTogether) { //if this provider dropdown is one of provider dropdowns forcibly changed together earlier, make other forcibly changed provider dropdowns restore default option (i.e. 1st option in dropdown)
                                                                                 for (var key in providerDropdownsForciblyChangedTogether) {
-                                                                                    if (key == $thisProviderDropdown.context.name)
+                                                                                    if (key == this.name)
                                                                                         continue; //skip to next item in for loop
                                                                                     else
                                                                                         $("select[name='" + key + "'] option:first").attr("selected", "selected");
diff --git a/ui/scripts/domains.js b/ui/scripts/domains.js
index 1f65ff4..9e96f49 100644
--- a/ui/scripts/domains.js
+++ b/ui/scripts/domains.js
@@ -69,11 +69,23 @@
                                 async: false,
                                 success: function(json) {
                                     var jid = json.deletedomainresponse.jobid;
+                                    var wasDomainDeletedWithSuccess = false;
+                                    $.ajax({
+                                        url: createURL("queryAsyncJobResult&jobId=" + jid),
+                                        dataType: "json",
+                                        async: false,
+                                        success: function(json) {
+                                            wasDomainDeletedWithSuccess = json.queryasyncjobresultresponse.jobresultcode ==  0;
+                                        }
+                                    });
                                     args.response.success({
                                         _custom: {
                                             jobId: jid
                                         }
                                     });
+                                    if(!wasDomainDeletedWithSuccess){
+                                        return;
+                                    }
 
                                     // Quick fix for proper UI reaction to delete domain
                                     var $item = $('.name.selected').closest('li');
diff --git a/ui/scripts/events.js b/ui/scripts/events.js
index 82550a9..948f881 100644
--- a/ui/scripts/events.js
+++ b/ui/scripts/events.js
@@ -49,6 +49,9 @@
                         account: {
                             label: 'label.account'
                         },
+                        username: {
+                            label: 'label.username'
+                        },
                         domain: {
                             label: 'label.domain'
                         },
@@ -331,6 +334,15 @@
                                 else
                                     return true;
                             }
+                        },
+                        username: {
+                            label: 'label.username',
+                            isHidden: function(args) {
+                                if (isAdmin() || isDomainAdmin())
+                                    return false;
+                                else
+                                    return true;
+                            }
                         }
                     },
 
diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js
index eba8e68..ab03978 100644
--- a/ui/scripts/globalSettings.js
+++ b/ui/scripts/globalSettings.js
@@ -214,8 +214,8 @@
                             },
                             action: function(args) {
                                 var array = [];
-                                array.push("&hostname=" + todb(args.data.hostname));
-                                array.push("&port=" + todb(args.data.port));;
+                                array.push("&hostname=" + encodeURIComponent(args.data.hostname));
+                                array.push("&port=" + encodeURIComponent(args.data.port));
                                 $.ajax({
                                     url: createURL("addLdapConfiguration" + array.join("")),
                                     dataType: "json",
diff --git a/ui/scripts/installWizard.js b/ui/scripts/installWizard.js
index 9d7c23d..8ba82dd 100644
--- a/ui/scripts/installWizard.js
+++ b/ui/scripts/installWizard.js
@@ -35,7 +35,7 @@
                 url: createURL('updateUser'),
                 data: {
                     id: cloudStack.context.users[0].userid,
-                    password: md5Hashed ? $.md5(args.data.password) : args.data.password
+                    password: args.data.password
                 },
                 type: 'POST',
                 dataType: 'json',
diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js
index a3d735a..351ca7b 100644
--- a/ui/scripts/instanceWizard.js
+++ b/ui/scripts/instanceWizard.js
@@ -1095,7 +1095,7 @@
             var userdata = args.data.userdata;
             if (userdata != null && userdata.length > 0) {
                 $.extend(deployVmData, {
-                    userdata : todb(btoa(userdata))
+                    userdata : encodeURIComponent(btoa(userdata))
                 });
             }
 
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index f33aac0..7a959df 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -112,6 +112,35 @@
                         label: 'label.expunge',
                         isBoolean: true,
                         isChecked: false
+                    },
+                    volumes: {
+                        label: 'label.delete.volumes',
+                        isBoolean: true,
+                        isChecked: true,
+                        isHidden: true,
+                    },
+                    volumeids: {
+                        label: 'label.delete.volumes',
+                        dependsOn: 'volumes',
+                        isBoolean: true,
+                        isHidden: false,
+                        emptyMessage: 'label.volume.empty',
+                        multiDataArray: true,
+                        multiData: function(args) {
+                            $.ajax({
+                                url: createURL("listVolumes&virtualMachineId=" + args.context.instances[0].id) + "&type=DATADISK",
+                                  dataType: "json",
+                                  async: true,
+                                  success: function(json) {
+                                    var volumes = json.listvolumesresponse.volume;
+                                    args.response.success({
+                                        descriptionField: 'name',
+                                        valueField: 'id',
+                                        data: volumes
+                                    });
+                                  }
+                            });
+                        }
                     }
                 }
             },
@@ -126,6 +155,26 @@
                             expunge: true
                         });
                     }
+                    if (args.data.volumes == 'on') {
+
+                        var regex = RegExp('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
+
+                        var selectedVolumes = [];
+
+                        for (var key in args.data) {
+                            var matches = key.match(regex);
+
+                            if (matches != null) {
+                                selectedVolumes.push(key);
+                            }
+                        }
+
+                        $.extend(data, {
+                            volumeids: $(selectedVolumes).map(function(index, volume) {
+                                return volume;
+                            }).toArray().join(',')
+                        });
+                    }
                     $.ajax({
                         url: createURL('destroyVirtualMachine'),
                         data: data,
@@ -228,14 +277,7 @@
                     var array1 = [];
                     array1.push("&snapshotmemory=" + (args.data.snapshotMemory == "on"));
                     array1.push("&quiescevm=" + (args.data.quiescevm == "on"));
-                    var displayname = args.data.name;
-                    if (displayname != null && displayname.length > 0) {
-                        array1.push("&name=" + todb(displayname));
-                    }
-                    var description = args.data.description;
-                    if (description != null && description.length > 0) {
-                        array1.push("&description=" + todb(description));
-                    }
+                    cloudStack.addNameAndDescriptionToCommandUrlParameterArray(array1, args.data);
                     $.ajax({
                         url: createURL("createVMSnapshot&virtualmachineid=" + instance.id + array1.join("")),
                         dataType: "json",
@@ -2872,6 +2914,9 @@
                             type: {
                                 label: 'label.type'
                             },
+                            macaddress: {
+                              label: 'label.mac.address'
+                            },
                             ipaddress: {
                                 label: 'label.ip.address'
                             },
diff --git a/ui/scripts/lbCertificatePolicy.js b/ui/scripts/lbCertificatePolicy.js
index 538e33d..433e49b 100644
--- a/ui/scripts/lbCertificatePolicy.js
+++ b/ui/scripts/lbCertificatePolicy.js
@@ -51,6 +51,13 @@
                                 async: false,
                                 data: item,
                                 success: function(json) {
+                                    if(!json.listsslcertsresponse || !json.listsslcertsresponse.sslcert){
+                                        args.response.success({
+                                            data: {id: 'No certificates ID', 
+                                                    description: 'No certificates found'}
+                                        });
+                                        return;
+                                    }
                                     var items = json.listsslcertsresponse.sslcert;
                                     args.response.success({
                                         data: $.map(items, function(item) {
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 34b68f2..6e50a99 100644
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -1782,7 +1782,7 @@
                                         label: 'label.ip.address',
                                         validation: {
                                             required: false,
-                                            ipv4: true
+                                            ipv4AndIpv6AddressValidator: true
                                         }
                                     }
                                 }
@@ -2445,7 +2445,7 @@
                                                     var $tierSelect = $(".ui-dialog-content").find('.tier-select select');
 
                                                     // if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later
-                                                    if ($tierSelect.size() == 0) {
+                                                    if ($tierSelect.length == 0) {
                                                         args.response.success({
                                                             data: null
                                                         });
@@ -4588,7 +4588,7 @@
                                             label: 'label.cidr',
                                             isHidden: true,
                                             validation: {
-                                                ipv46cidr: true
+                                                ipv46cidrs: true
                                             }
                                         },
                                         'accountname': {
@@ -4798,7 +4798,7 @@
                                             label: 'label.cidr',
                                             isHidden: true,
                                             validation: {
-                                                ipv46cidr: true
+                                                ipv46cidrs: true
                                             }
                                         },
                                         'accountname': {
diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js
index e2ad3ba..995b841 100644
--- a/ui/scripts/sharedFunctions.js
+++ b/ui/scripts/sharedFunctions.js
@@ -45,10 +45,6 @@
 var ERROR_INTERNET_CANNOT_CONNECT = 12029;
 var ERROR_VMOPS_ACCOUNT_ERROR = 531;
 
-// Default password is MD5 hashed.  Set the following variable to false to disable this.
-var md5Hashed = false;
-var md5HashedLogin = false;
-
 //page size for API call (e.g."listXXXXXXX&pagesize=N" )
 var pageSize = 20;
 //var pageSize = 1; //for testing only
@@ -184,11 +180,8 @@
         return urlString;
     }
 
-    function todb(val) {
-        return encodeURIComponent(val);
-    }
 
-    //LB provider map
+//LB provider map
 var lbProviderMap = {
     "publicLb": {
         "non-vpc": ["VirtualRouter", "Netscaler", "F5"],
@@ -354,6 +347,10 @@
                     label: 'label.vlan.id',
                     docID: 'helpGuestNetworkZoneVLANID'
                 },
+                bypassVlanOverlapCheck: {
+                    label: 'label.bypass.vlan.overlap.check',
+                    isBoolean: true
+                },
                 isolatedpvlanId: {
                     label: 'label.secondary.isolated.vlan.id'
                 },
@@ -679,7 +676,7 @@
                     label: 'label.ipv6.gateway',
                     docID: 'helpGuestNetworkZoneGateway',
                     validation: {
-                        ipv6: true
+                    	ipv6CustomJqueryValidator: true
                     }
                 },
                 ip6cidr: {
@@ -692,14 +689,14 @@
                     label: 'label.ipv6.start.ip',
                     docID: 'helpGuestNetworkZoneStartIP',
                     validation: {
-                        ipv6: true
+                    	ipv6CustomJqueryValidator: true
                     }
                 },
                 endipv6: {
                     label: 'label.ipv6.end.ip',
                     docID: 'helpGuestNetworkZoneEndIP',
                     validation: {
-                        ipv6: true
+                    	ipv6CustomJqueryValidator: true
                     }
                },
                 //IPv6 (end)
@@ -739,16 +736,19 @@
 
             if (selectedNetworkOfferingObj.guestiptype == "Shared")
                 array1.push("&physicalnetworkid=" + args.data.physicalNetworkId);
+            
+            cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array1, "name", args.data.name);
+            cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array1, "displayText", args.data.description);
 
-            array1.push("&name=" + todb(args.data.name));
-            array1.push("&displayText=" + todb(args.data.description));
-
-            if (($form.find('.form-item[rel=vlanId]').css("display") != "none") && (args.data.vlanId != null && args.data.vlanId.length > 0))
-                array1.push("&vlan=" + todb(args.data.vlanId));
-
-            if (($form.find('.form-item[rel=isolatedpvlanId]').css("display") != "none") && (args.data.isolatedpvlanId != null && args.data.isolatedpvlanId.length > 0))
-                array1.push("&isolatedpvlan=" + todb(args.data.isolatedpvlanId));
-
+            if ($form.find('.form-item[rel=vlanId]').css("display") != "none"){
+                cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.vlanId)
+            }
+            if ($form.find('.form-item[rel=bypassVlanOverlapCheck]').css("display") != "none"){
+                array1.push("&bypassVlanOverlapCheck=" + encodeURIComponent((args.data.bypassVlanOverlapCheck == "on")));
+            }
+            if (($form.find('.form-item[rel=isolatedpvlanId]').css("display") != "none") && (args.data.isolatedpvlanId != null && args.data.isolatedpvlanId.length > 0)){
+                array1.push("&isolatedpvlan=" + encodeURIComponent(args.data.isolatedpvlanId));
+            }
             if ($form.find('.form-item[rel=domainId]').css("display") != "none") {
                 array1.push("&domainId=" + args.data.domainId);
 
@@ -761,7 +761,7 @@
                 } else { //domain-specific
                     array1.push("&acltype=domain");
 
-                    if ($form.find('.form-item[rel=subdomainaccess]:visible input:checked').size())
+                    if ($form.find('.form-item[rel=subdomainaccess]:visible input:checked').length)
                         array1.push("&subdomainaccess=true");
                     else
                         array1.push("&subdomainaccess=false");
@@ -792,9 +792,9 @@
                 array1.push("&endipv6=" + args.data.endipv6);
             //IPv6 (end)
 
-            if (args.data.networkdomain != null && args.data.networkdomain.length > 0)
-                array1.push("&networkdomain=" + todb(args.data.networkdomain));
-
+            if (args.data.networkdomain != null && args.data.networkdomain.length > 0){
+                array1.push("&networkdomain=" + encodeURIComponent(args.data.networkdomain));
+            }
             $.ajax({
                 url: createURL("createNetwork" + array1.join("")),
                 dataType: "json",
@@ -923,9 +923,13 @@
                             url: createURL('listNetworkOfferings'),
                             data: data,
                             success: function(json) {
-                                networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
+                                if(!json.listnetworkofferingsresponse || !json.listnetworkofferingsresponse.networkoffering){
+                                    return;
+                                }
+                                var networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
                                 args.$select.change(function() {
                                     var $vlan = args.$select.closest('form').find('[rel=vlan]');
+                                    var $bypassVlanOverlapCheck = args.$select.closest('form').find('[rel=bypassVlanOverlapCheck]');
                                     var networkOffering = $.grep(
                                         networkOfferingObjs, function(netoffer) {
                                             return netoffer.id == args.$select.val();
@@ -934,8 +938,10 @@
 
                                     if (networkOffering.specifyvlan) {
                                         $vlan.css('display', 'inline-block');
+                                        $bypassVlanOverlapCheck.css('display', 'inline-block');
                                     } else {
                                         $vlan.hide();
+                                        $bypassVlanOverlapCheck.hide();
                                     }
                                 });
 
@@ -959,6 +965,11 @@
                     },
                     isHidden: true
                 },
+                bypassVlanOverlapCheck: {
+                    label: 'label.bypass.vlan.overlap.check',
+                    isBoolean: true,
+                    isHidden: true
+                  },
 
                 domain: {
                     label: 'label.domain',
@@ -1033,7 +1044,8 @@
 
             if (args.$form.find('.form-item[rel=vlan]').css('display') != 'none') {
                 $.extend(dataObj, {
-                    vlan: args.data.vlan
+                    vlan: args.data.vlan,
+                    bypassVlanOverlapCheck: (args.data.bypassVlanOverlapCheck == "on")
                 });
             }
 
@@ -2563,7 +2575,7 @@
         return false;
     }
 
-    if (!$.validator.methods.ipv6.call(this, parts[0], element))
+    if (!$.validator.methods.ipv6CustomJqueryValidator.call(this, parts[0], element))
         return false;
 
     if (parts[1] != Number(parts[1]).toString()) //making sure that "", " ", "00", "0 ","2  ", etc. will not pass
@@ -2596,6 +2608,19 @@
     return true;
 }, "The specified IPv4 CIDR is invalid.");
 
+$.validator.addMethod("ipv46cidrs", function(value, element) {
+    var result = true;
+    if (value) {
+        var validatorThis = this;
+        value.split(',').forEach(function(item){
+            if (result && !$.validator.methods.ipv46cidr.call(validatorThis, item.trim(), element)) {
+                result = false;
+            }
+        })
+    }
+    return result;
+}, "The specified IPv4/IPv6 CIDR input is invalid.");
+
 $.validator.addMethod("ipv46cidr", function(value, element) {
     if (this.optional(element) && value.length == 0)
         return true;
@@ -2606,6 +2631,23 @@
     return false;
 }, "The specified IPv4/IPv6 CIDR is invalid.");
 
+jQuery.validator.addMethod("ipv4AndIpv6AddressValidator", function(value, element) {
+    if (this.optional(element) && value.length == 0) {
+        return true;
+	}
+    if (jQuery.validator.methods.ipv4.call(this, value, element) || jQuery.validator.methods.ipv6CustomJqueryValidator.call(this, value, element)) {
+        return true;
+    }
+    return false;
+}, "The specified IPv4/IPv6 address is invalid.");
+
+jQuery.validator.addMethod("ipv6CustomJqueryValidator", function(value, element) {
+    if (value == '::'){
+    	return true;
+    }
+    return jQuery.validator.methods.ipv6.call(this, value, element);
+}, "The specified IPv6 address is invalid.");
+
 
 $.validator.addMethod("allzonesonly", function(value, element){
 
@@ -2615,3 +2657,270 @@
 
 },
 "All Zones cannot be combined with any other zone");
+
+cloudStack.createTemplateMethod = function (isSnapshot){
+	return {
+        label: 'label.create.template',
+        messages: {
+            confirm: function(args) {
+                return 'message.create.template';
+            },
+            notification: function(args) {
+                return 'label.create.template';
+            }
+        },
+        createForm: {
+            title: 'label.create.template',
+            preFilter: cloudStack.preFilter.createTemplate,
+            desc: '',
+            preFilter: function(args) {
+                if (args.context.volumes[0].hypervisor == "XenServer") {
+                    if (isAdmin()) {
+                        args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css('display', 'inline-block');
+                    }
+                }
+            },
+            fields: {
+                name: {
+                    label: 'label.name',
+                    validation: {
+                        required: true
+                    }
+                },
+                displayText: {
+                    label: 'label.description',
+                    validation: {
+                        required: true
+                    }
+                },
+                xenserverToolsVersion61plus: {
+                    label: 'label.xenserver.tools.version.61.plus',
+                    isBoolean: true,
+                    isChecked: function (args) {
+                        var b = false;
+                        var vmObj;
+                        $.ajax({
+                            url: createURL("listVirtualMachines"),
+                            data: {
+                                id: args.context.volumes[0].virtualmachineid
+                            },
+                            async: false,
+                            success: function(json) {
+                                vmObj = json.listvirtualmachinesresponse.virtualmachine[0];
+                            }
+                        });
+                        if (vmObj == undefined) { //e.g. VM has failed over
+                            if (isAdmin()) {
+                                $.ajax({
+                                    url: createURL('listConfigurations'),
+                                    data: {
+                                        name: 'xenserver.pvdriver.version'
+                                    },
+                                    async: false,
+                                    success: function (json) {
+                                        if (json.listconfigurationsresponse.configuration != null && json.listconfigurationsresponse.configuration[0].value == 'xenserver61') {
+                                            b = true;
+                                        }
+                                    }
+                                });
+                            }
+                        } else {
+                             if ('details' in vmObj && 'hypervisortoolsversion' in vmObj.details) {
+                                 if (vmObj.details.hypervisortoolsversion == 'xenserver61')
+                                     b = true;
+                                 else
+                                     b = false;
+                             }
+                        }
+                        return b;
+                    },
+                    isHidden: true
+                },
+                osTypeId: {
+                    label: 'label.os.type',
+                    select: function(args) {
+                        $.ajax({
+                            url: createURL("listOsTypes"),
+                            dataType: "json",
+                            async: true,
+                            success: function(json) {
+                                var ostypes = json.listostypesresponse.ostype;
+                                var items = [];
+                                $(ostypes).each(function() {
+                                    items.push({
+                                        id: this.id,
+                                        description: this.description
+                                    });
+                                });
+                                args.response.success({
+                                    data: items
+                                });
+                            }
+                        });
+                    }
+                },
+                isPublic: {
+                    label: 'label.public',
+                    isBoolean: true
+                },
+                isPasswordEnabled: {
+                    label: 'label.password.enabled',
+                    isBoolean: true
+                },
+                isFeatured: {
+                    label: 'label.featured',
+                    isBoolean: true
+                },
+                isdynamicallyscalable: {
+                    label: 'label.dynamically.scalable',
+                    isBoolean: true
+                },
+                requireshvm: {
+                    label: 'label.hvm',
+                    docID: 'helpRegisterTemplateHvm',
+                    isBoolean: true,
+                    isHidden: false,
+                    isChecked: false
+                }
+            }
+        },
+        action: function(args) {
+            var data = {
+                name: args.data.name,
+                displayText: args.data.displayText,
+                osTypeId: args.data.osTypeId,
+                isPublic: (args.data.isPublic == "on"),
+                passwordEnabled: (args.data.isPasswordEnabled == "on"),
+                isdynamicallyscalable: (args.data.isdynamicallyscalable == "on"),
+                requireshvm: (args.data.requireshvm == "on")
+            };
+            
+            if(isSnapshot){
+            	data.snapshotid = args.context.snapshots[0].id;
+            } else{
+            	data.volumeId = args.context.volumes[0].id;
+            }
+            if (args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") {
+                $.extend(data, {
+                    isfeatured: (args.data.isFeatured == "on")
+                });
+            }
+
+            //XenServer only (starts here)
+            if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').length > 0) {
+                if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css("display") != "none") {
+                    $.extend(data, {
+                        'details[0].hypervisortoolsversion': (args.data.xenserverToolsVersion61plus == "on") ? "xenserver61" : "xenserver56"
+                    });
+                }
+            }
+            //XenServer only (ends here)
+
+            $.ajax({
+                url: createURL('createTemplate'),
+                data: data,
+                success: function(json) {
+                    var jid = json.createtemplateresponse.jobid;
+                    args.response.success({
+                        _custom: {
+                            jobId: jid,
+                            getUpdatedItem: function(json) {
+                                return {}; //no properties in this volume needs to be updated
+                            },
+                            getActionFilter: function() {
+                                return volumeActionfilter;
+                            }
+                        }
+                    });
+                }
+            });
+        },
+        notification: {
+            poll: pollAsyncJobResult
+        }
+    };
+};
+
+cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty = function(array, parameterName, value){
+    if (value != null && value.length > 0) {
+        array.push("&" + parameterName + "=" + encodeURIComponent(value));
+    }
+}
+
+cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty = function(array, username, password){
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "username", username);
+    cloudStack.addPasswordToCommandUrlParameterArray(array, password);
+};
+
+cloudStack.addPasswordToCommandUrlParameterArray = function(array, password){
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "password", password);
+};
+
+/**
+ * We will only add the name and description data to the array of parameters if they are not null.
+ * Moreover, we expect the name parameter to be a property ('name') of data object. 
+ * The description must be a property called 'description' in the data object.   
+ */
+cloudStack.addNameAndDescriptionToCommandUrlParameterArray = function (array, data){
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "name", data.name);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "description", data.description);
+};
+
+cloudStack.addNewSizeToCommandUrlParameterArrayIfItIsNotNullAndHigherThanZero = function(array, newSize){
+    if(newSize == undefined || newSize == null){
+        return;
+    }
+    var newSizeAsNumber = new Number(newSize);
+    if(isNaN(newSizeAsNumber)){
+        return;
+    }
+    if (newSizeAsNumber > 0) {
+        array.push("&size=" + encodeURIComponent(newSize));
+    }
+};
+
+cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty = function(array, vlan){
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "vlan", vlan);
+};
+
+cloudStack.createArrayOfParametersForCreatePodCommand = function (zoneId, data){
+    var array =[];
+    array.push("&zoneId=" + zoneId);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "name", data.podName);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "gateway", data.podGateway);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "netmask", data.podNetmask);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "startIp", data.podStartIp);
+    cloudStack.addParameterToCommandUrlParameterArrayIfValueIsNotEmpty(array, "endIp", data.podEndIp);
+    return array;
+}
+
+cloudStack.listDiskOfferings = function(options){
+    var defaultOptions = {
+            listAll: false,
+            isRecursive: false,
+            error: function(data) {
+                args.response.error(data);
+            }
+    };
+    var mergedOptions = $.extend({}, defaultOptions, options);
+    
+    var listDiskOfferingsUrl = "listDiskOfferings";
+    if(mergedOptions.listAll){
+        listDiskOfferingsUrl = listDiskOfferingsUrl + "&listall=true";
+    }
+    if(mergedOptions.isRecursive){
+        listDiskOfferingsUrl = listDiskOfferingsUrl + "&isrecursive=true";
+    }
+    var diskOfferings = undefined;
+    $.ajax({
+        url: createURL(listDiskOfferingsUrl),
+        data: mergedOptions.data,
+        dataType: "json",
+        async: false,
+        success: function(json) {
+            diskOfferings = json.listdiskofferingsresponse.diskoffering;
+        },
+        error: mergedOptions.error
+    });
+    return diskOfferings;
+};
diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js
index e9b6138..06fe41e 100644
--- a/ui/scripts/storage.js
+++ b/ui/scripts/storage.js
@@ -15,8 +15,165 @@
 // specific language governing permissions and limitations
 // under the License.
 (function(cloudStack) {
+    var migrateVolumeCreateFormAction = {
+            title: 'label.migrate.volume',
+            fields: {
+                storagePool: {
+                    label: 'label.storage.pool',
+                    validation: {
+                        required: true
+                    },
+                    select: function(args) {
+                        var mapStoragePoolsByUuid = new Map();
+                        var volumeId = args.context.volumes[0].id;
+                        
+                        var volumeBeingMigrated = undefined;
+                        $.ajax({
+                            url: createURL("listVolumes&id=" + volumeId),
+                            dataType: "json",
+                            async: false,
+                            success: function(json){
+                                volumeBeingMigrated = json.listvolumesresponse.volume[0]; 
+                            }
+                        });
+                        
+                        var currentStoragePool = undefined;
+                        $.ajax({
+                            url: createURL("listStoragePools&id=" + volumeBeingMigrated.storageid),
+                            dataType: "json",
+                            async: false,
+                            success: function(json){
+                                currentStoragePool = json.liststoragepoolsresponse.storagepool[0]; 
+                            }
+                        });
+                        var isVolumeNotAttachedToVm = volumeBeingMigrated.virtualmachineid == undefined;
+                        var urlToRetrieveStoragePools = "findStoragePoolsForMigration&id=" + args.context.volumes[0].id;
+                        if(isVolumeNotAttachedToVm){
+                            urlToRetrieveStoragePools = "listStoragePools&zoneid=" + args.context.volumes[0].zoneid;
+                        }
+                        $.ajax({
+                            url: createURL(urlToRetrieveStoragePools),
+                            dataType: "json",
+                            async: true,
+                            success: function(json) {
+                                var pools = undefined;
+                                if(isVolumeNotAttachedToVm){
+                                    pools = json.liststoragepoolsresponse.storagepool;
+                                }else{
+                                    pools = json.findstoragepoolsformigrationresponse.storagepool;
+                                }
+                                var items = [];
+                                $(pools).each(function() {
+                                    mapStoragePoolsByUuid.set(this.id, this);
+                                    var description = this.name;
+                                    if(!isVolumeNotAttachedToVm){
+                                        description = description + " (" + (this.suitableformigration ? "Suitable" : "Not Suitable") + ")";
+                                    }
+                                    items.push({
+                                        id: this.id,
+                                        description: description
+                                    });
+                                });
+                                args.response.success({
+                                    data: items
+                                });
+                                var diskOfferings = cloudStack.listDiskOfferings({listAll: true});
+                                $('select[name=storagePool]').change(function(){
+                                    var uuidOfStoragePoolSelected = $(this).val();
+                                    var storagePoolSelected = mapStoragePoolsByUuid.get(uuidOfStoragePoolSelected);
+                                    
+                                    if(currentStoragePool.scope === storagePoolSelected.scope){
+                                        $('div[rel=newDiskOffering],div[rel=useNewDiskOffering]').hide();
+                                    }else{
+                                        $('div[rel=newDiskOffering],div[rel=useNewDiskOffering]').show();
+                                    }
+                                    var storageType = 'shared';
+                                    if(storagePoolSelected.scope == 'HOST'){
+                                        storageType = 'local';
+                                    }
+                                    $(diskOfferings).each(function(){
+                                        var diskOfferingOption = $('option[value=' + this.id + ']');
+                                        if(this.storagetype == storageType){
+                                            diskOfferingOption.show();
+                                        }else{
+                                            diskOfferingOption.hide();
+                                        }
+                                    });
+                                    var firstAvailableDiskOfferingForStorageType = $('select#label_disk_newOffering').children('option:visible').first().attr('value');
+                                    $('select#label_disk_newOffering').attr('value', firstAvailableDiskOfferingForStorageType);
+                                });
+                                var functionHideShowNewDiskOfferint = function(){
+                                    if($('div[rel=useNewDiskOffering] input[type=checkbox]').is(':checked')){
+                                        $('div[rel=newDiskOffering]').show();
+                                    }else{
+                                        $('div[rel=newDiskOffering]').hide();
+                                    }  
+                                };
+                                $('div[rel=useNewDiskOffering] input[type=checkbox]').click(functionHideShowNewDiskOfferint);
+                                
+                                $('select[name=storagePool]').change();
+                                functionHideShowNewDiskOfferint();
+                            }
+                        });
+                    }
+                },
+            useNewDiskOffering:{
+                label: 'label.migrate.volume.newDiskOffering',
+                desc: 'label.migrate.volume.newDiskOffering.desc',
+                validation: {
+                    required: false
+                   },
+                isEditable: true, 
+                isBoolean: true,
+                defaultValue: 'Yes'
+            },
+            newDiskOffering: {
+                label: 'label.disk.newOffering',
+                desc: 'label.disk.newOffering.description',
+                validation: {
+                    required: false
+                   },
+                select: function(args){
+                    var diskOfferings = cloudStack.listDiskOfferings({listAll: true});
+                    var items = [];
+                    $(diskOfferings).each(function() {
+                        items.push({
+                            id: this.id,
+                            description: this.name
+                        });
+                    });
+                    args.response.success({
+                        data: items
+                    });
+                   }
+               }
+           }
+        };
+    var functionMigrateVolume = function(args) {
+        var volumeBeingMigrated = args.context.volumes[0];
+        var isLiveMigrate = volumeBeingMigrated.vmstate == 'Running';
+        
+        var migrateVolumeUrl = "migrateVolume&livemigrate="+ isLiveMigrate +"&storageid=" + args.data.storagePool + "&volumeid=" + volumeBeingMigrated.id;
+        if($('div[rel=useNewDiskOffering] input[name=useNewDiskOffering]:checkbox').is(':checked')){
+            migrateVolumeUrl = migrateVolumeUrl + '&newdiskofferingid=' + $('div[rel=newDiskOffering] select').val();
+        }
+        $.ajax({
+            url: createURL(migrateVolumeUrl),
+            dataType: "json",
+            async: true,
+            success: function(json) {
+                $(window).trigger('cloudStack.fullRefresh');
+                var jid = json.migratevolumeresponse.jobid;
+                args.response.success({
+                    _custom: {
+                        jobId: jid
+                    }
+                });
+            }
+        });
+    }
 
-    var diskofferingObjs, selectedDiskOfferingObj;
+    var selectedDiskOfferingObj = null;
 
     cloudStack.sections.storage = {
         title: 'label.storage',
@@ -128,36 +285,28 @@
                                         label: 'label.disk.offering',
                                         docID: 'helpVolumeDiskOffering',
                                         select: function(args) {
-                                            $.ajax({
-                                                url: createURL("listDiskOfferings"),
-                                                dataType: "json",
-                                                async: false,
-                                                success: function(json) {
-                                                    diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
-                                                    var items = [];
-                                                    $(diskofferingObjs).each(function() {
-                                                        items.push({
-                                                            id: this.id,
-                                                            description: this.displaytext
-                                                        });
-                                                    });
-                                                    args.response.success({
-                                                        data: items
-                                                    });
-                                                }
+                                            var diskOfferings = cloudStack.listDiskOfferings({});
+                                            var items = [];
+                                            $(diskOfferings).each(function() {
+                                                items.push({
+                                                    id: this.id,
+                                                    description: this.displaytext
+                                                });
                                             });
-
+                                            args.response.success({
+                                                data: items
+                                            });
                                             args.$select.change(function() {
                                                 var diskOfferingId = $(this).val();
-                                                $(diskofferingObjs).each(function() {
+                                                $(diskOfferings).each(function() {
                                                     if (this.id == diskOfferingId) {
                                                         selectedDiskOfferingObj = this;
                                                         return false; //break the $.each() loop
                                                     }
                                                 });
-                                                if (selectedDiskOfferingObj == null)
+                                                if (selectedDiskOfferingObj == null){
                                                     return;
-
+                                                }
                                                 var $form = $(this).closest('form');
                                                 var $diskSize = $form.find('.form-item[rel=diskSize]');
                                                 if (selectedDiskOfferingObj.iscustomized == true) {
@@ -361,60 +510,44 @@
                                         label: 'label.custom.disk.offering',
                                         docID: 'helpVolumeDiskOffering',
                                         select: function(args) {
-                                            var diskofferingObjs;
-                                            $.ajax({
-                                                url: createURL("listDiskOfferings"),
-                                                dataType: "json",
-                                                async: false,
-                                                success: function(json) {
-                                                    diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
-                                                    var items = [{
-                                                        id: '',
-                                                        description: ''
-                                                    }];
-                                                    $(diskofferingObjs).each(function() {
-                                                        if (this.iscustomized == true) {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.displaytext
-                                                            });
-                                                        }
-                                                    });
-                                                    args.response.success({
-                                                        data: items
+                                            var diskOfferings = cloudStack.listDiskOfferings({});
+                                            var items = [{
+                                                id: '',
+                                                description: ''
+                                            }];
+                                            $(diskOfferings).each(function() {
+                                                if (this.iscustomized == true) {
+                                                    items.push({
+                                                        id: this.id,
+                                                        description: this.displaytext
                                                     });
                                                 }
                                             });
+                                            args.response.success({
+                                                data: items
+                                            });
                                         }
                                     },
                                     diskOffering: {
                                         label: 'label.custom.disk.offering',
                                         docID: 'helpVolumeDiskOffering',
                                         select: function(args) {
-                                            var diskofferingObjs;
-                                            $.ajax({
-                                                url: createURL("listDiskOfferings"),
-                                                dataType: "json",
-                                                async: false,
-                                                success: function(json) {
-                                                    diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
-                                                    var items = [{
-                                                        id: '',
-                                                        description: ''
-                                                    }];
-                                                    $(diskofferingObjs).each(function() {
-                                                        if (this.iscustomized == true) {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.displaytext
-                                                            });
-                                                        }
-                                                    });
-                                                    args.response.success({
-                                                        data: items
+                                            var diskOfferings = cloudStack.listDiskOfferings({});
+                                            var items = [{
+                                                id: '',
+                                                description: ''
+                                            }];
+                                            $(diskOfferings).each(function() {
+                                                if (this.iscustomized == true) {
+                                                    items.push({
+                                                        id: this.id,
+                                                        description: this.displaytext
                                                     });
                                                 }
                                             });
+                                            args.response.success({
+                                                data: items
+                                            });
                                         }
                                     },
                                     checksum: {
@@ -746,7 +879,6 @@
                             label: 'label.snapshots'
                         },
                         actions: {
-
                             migrateVolume: {
                                 label: 'label.migrate.volume',
                                 messages: {
@@ -758,56 +890,9 @@
                                     }
                                 },
 
-                                createForm: {
-                                    title: 'label.migrate.volume',
-                                    desc: '',
-                                    fields: {
-                                        storagePool: {
-                                            label: 'label.storage.pool',
-                                            validation: {
-                                                required: true
-                                            },
-                                            select: function(args) {
-                                                $.ajax({
-                                                    url: createURL("findStoragePoolsForMigration&id=" + args.context.volumes[0].id),
-                                                    dataType: "json",
-                                                    async: true,
-                                                    success: function(json) {
-                                                        var pools = json.findstoragepoolsformigrationresponse.storagepool;
-                                                        var items = [];
-                                                        $(pools).each(function() {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.name + " (" + (this.suitableformigration ? "Suitable" : "Not Suitable") + ")"
-                                                            });
-                                                        });
-                                                        args.response.success({
-                                                            data: items
-                                                        });
+                                createForm: migrateVolumeCreateFormAction,
 
-                                                    }
-                                                });
-                                            }
-                                        }
-                                    }
-
-                                },
-
-                                action: function(args) {
-                                    $.ajax({
-                                        url: createURL("migrateVolume&livemigrate=true&storageid=" + args.data.storagePool + "&volumeid=" + args.context.volumes[0].id),
-                                        dataType: "json",
-                                        async: true,
-                                        success: function(json) {
-                                            var jid = json.migratevolumeresponse.jobid;
-                                            args.response.success({
-                                                _custom: {
-                                                    jobId: jid
-                                                }
-                                            });
-                                        }
-                                    });
-                                },
+                                action: functionMigrateVolume,
                                 notification: {
                                     poll: pollAsyncJobResult
                                 }
@@ -1302,175 +1387,8 @@
                                 }
                             },
 
-                            createTemplate: {
-                                label: 'label.create.template',
-                                messages: {
-                                    confirm: function(args) {
-                                        return 'message.create.template';
-                                    },
-                                    notification: function(args) {
-                                        return 'label.create.template';
-                                    }
-                                },
-                                createForm: {
-                                    title: 'label.create.template',
-                                    preFilter: cloudStack.preFilter.createTemplate,
-                                    desc: '',
-                                    preFilter: function(args) {
-                                        if (args.context.volumes[0].hypervisor == "XenServer") {
-                                            args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css('display', 'inline-block');
-
-                                        }
-                                    },
-                                    fields: {
-                                        name: {
-                                            label: 'label.name',
-                                            validation: {
-                                                required: true
-                                            }
-                                        },
-                                        displayText: {
-                                            label: 'label.description',
-                                            validation: {
-                                                required: true
-                                            }
-                                        },
-                                        xenserverToolsVersion61plus: {
-                                            label: 'label.xenserver.tools.version.61.plus',
-                                            isBoolean: true,
-                                            isChecked: function (args) {
-                                                var b = false;
-                                                var vmObj;
-                                                $.ajax({
-                                                    url: createURL("listVirtualMachines"),
-                                                    data: {
-                                                        id: args.context.volumes[0].virtualmachineid
-                                                    },
-                                                    async: false,
-                                                    success: function(json) {
-                                                        vmObj = json.listvirtualmachinesresponse.virtualmachine[0];
-                                                    }
-                                                });
-                                                if (vmObj == undefined) { //e.g. VM has failed over
-                                                    if (isAdmin()) {
-                                                        $.ajax({
-                                                            url: createURL('listConfigurations'),
-                                                            data: {
-                                                                name: 'xenserver.pvdriver.version'
-                                                            },
-                                                            async: false,
-                                                            success: function (json) {
-                                                                if (json.listconfigurationsresponse.configuration != null && json.listconfigurationsresponse.configuration[0].value == 'xenserver61') {
-                                                                    b = true;
-                                                                }
-                                                            }
-                                                        });
-                                                    }
-                                                } else {
-                                                     if ('details' in vmObj && 'hypervisortoolsversion' in vmObj.details) {
-                                                         if (vmObj.details.hypervisortoolsversion == 'xenserver61')
-                                                             b = true;
-                                                         else
-                                                             b = false;
-                                                     }
-                                                }
-                                                return b;
-                                            },
-                                            isHidden: true
-                                        },
-                                        osTypeId: {
-                                            label: 'label.os.type',
-                                            select: function(args) {
-                                                $.ajax({
-                                                    url: createURL("listOsTypes"),
-                                                    dataType: "json",
-                                                    async: true,
-                                                    success: function(json) {
-                                                        var ostypes = json.listostypesresponse.ostype;
-                                                        var items = [];
-                                                        $(ostypes).each(function() {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.description
-                                                            });
-                                                        });
-                                                        args.response.success({
-                                                            data: items
-                                                        });
-                                                    }
-                                                });
-                                            }
-                                        },
-                                        isPublic: {
-                                            label: 'label.public',
-                                            isBoolean: true
-                                        },
-                                        isPasswordEnabled: {
-                                            label: 'label.password.enabled',
-                                            isBoolean: true
-                                        },
-                                        isFeatured: {
-                                            label: 'label.featured',
-                                            isBoolean: true
-                                        },
-                                        isdynamicallyscalable: {
-                                            label: 'label.dynamically.scalable',
-                                            isBoolean: true
-                                        }
-                                    }
-                                },
-                                action: function(args) {
-                                    var data = {
-                                        volumeId: args.context.volumes[0].id,
-                                        name: args.data.name,
-                                        displayText: args.data.displayText,
-                                        osTypeId: args.data.osTypeId,
-                                        isPublic: (args.data.isPublic == "on"),
-                                        passwordEnabled: (args.data.isPasswordEnabled == "on"),
-                                        isdynamicallyscalable: (args.data.isdynamicallyscalable == "on")
-
-                                    };
-
-                                    if (args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") {
-                                        $.extend(data, {
-                                            isfeatured: (args.data.isFeatured == "on")
-                                        });
-                                    }
-
-                                    //XenServer only (starts here)
-                                    if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').length > 0) {
-                                        if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css("display") != "none") {
-                                            $.extend(data, {
-                                                'details[0].hypervisortoolsversion': (args.data.xenserverToolsVersion61plus == "on") ? "xenserver61" : "xenserver56"
-                                            });
-                                        }
-                                    }
-                                    //XenServer only (ends here)
-
-                                    $.ajax({
-                                        url: createURL('createTemplate'),
-                                        data: data,
-                                        success: function(json) {
-                                            var jid = json.createtemplateresponse.jobid;
-                                            args.response.success({
-                                                _custom: {
-                                                    jobId: jid,
-                                                    getUpdatedItem: function(json) {
-                                                        return {}; //no properties in this volume needs to be updated
-                                                    },
-                                                    getActionFilter: function() {
-                                                        return volumeActionfilter;
-                                                    }
-                                                }
-                                            });
-                                        }
-                                    });
-                                },
-                                notification: {
-                                    poll: pollAsyncJobResult
-                                }
-                            },
-
+                            createTemplate: cloudStack.createTemplateMethod(false),
+                            
                             migrateToAnotherStorage: {
                                 label: 'label.migrate.volume.to.primary.storage',
                                 messages: {
@@ -1481,59 +1399,8 @@
                                         return 'label.migrate.volume.to.primary.storage';
                                     }
                                 },
-                                createForm: {
-                                    title: 'label.migrate.volume.to.primary.storage',
-                                    desc: '',
-                                    fields: {
-                                        storageId: {
-                                            label: 'label.primary.storage',
-                                            validation: {
-                                                required: true
-                                            },
-                                            select: function(args) {
-                                                $.ajax({
-                                                    url: createURL("listStoragePools&zoneid=" + args.context.volumes[0].zoneid),
-                                                    dataType: "json",
-                                                    async: true,
-                                                    success: function(json) {
-                                                        var pools = json.liststoragepoolsresponse.storagepool;
-                                                        var items = [];
-                                                        $(pools).each(function() {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.name
-                                                            });
-                                                        });
-                                                        args.response.success({
-                                                            data: items
-                                                        });
-                                                    }
-                                                });
-                                            }
-                                        }
-                                    }
-                                },
-                                action: function(args) {
-                                    $.ajax({
-                                        url: createURL("migrateVolume&storageid=" + args.data.storageId + "&volumeid=" + args.context.volumes[0].id),
-                                        dataType: "json",
-                                        async: true,
-                                        success: function(json) {
-                                            var jid = json.migratevolumeresponse.jobid;
-                                            args.response.success({
-                                                _custom: {
-                                                    jobId: jid,
-                                                    getUpdatedItem: function(json) {
-                                                        return json.queryasyncjobresultresponse.jobresult.volume;
-                                                    },
-                                                    getActionFilter: function() {
-                                                        return volumeActionfilter;
-                                                    }
-                                                }
-                                            });
-                                        }
-                                    });
-                                },
+                                createForm: $.extend({}, migrateVolumeCreateFormAction, {title: 'label.migrate.volume.to.primary.storage'}),
+                                action: functionMigrateVolume,
                                 notification: {
                                     poll: pollAsyncJobResult
                                 }
@@ -1597,25 +1464,18 @@
                                                     });
                                                     return;
                                                 }
-
-                                                $.ajax({
-                                                    url: createURL("listDiskOfferings"),
-                                                    dataType: "json",
-                                                    success: function(json) {
-                                                        diskofferingObjs = json.listdiskofferingsresponse.diskoffering;
-                                                        var items = [];
-                                                        $(diskofferingObjs).each(function() {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.displaytext
-                                                            });
-                                                        });
-                                                        args.response.success({
-                                                            data: items
-                                                        });
-                                                    }
+                                                var diskOfferings = cloudStack.listDiskOfferings({});
+                                                var items = [];
+                                                $(diskOfferings).each(function() {
+                                                    items.push({
+                                                        id: this.id,
+                                                        description: this.displaytext
+                                                    });
                                                 });
-
+                                                args.response.success({
+                                                    data: items
+                                                });
+                                                
                                                 args.$select.change(function() {
                                                     if(args.context.volumes[0].type == "ROOT") {
                                                         selectedDiskOfferingObj = null;
@@ -1623,15 +1483,15 @@
                                                     }
 
                                                     var diskOfferingId = $(this).val();
-                                                    $(diskofferingObjs).each(function() {
+                                                    $(diskOfferings).each(function() {
                                                         if (this.id == diskOfferingId) {
                                                             selectedDiskOfferingObj = this;
                                                             return false; //break the $.each() loop
                                                         }
                                                     });
-                                                    if (selectedDiskOfferingObj == null)
+                                                    if (selectedDiskOfferingObj == null){
                                                         return;
-
+                                                    }
                                                     var $form = $(this).closest('form');
 
                                                     var $shrinkok = $form.find('.form-item[rel=shrinkok]');
@@ -1695,45 +1555,31 @@
                                 },
                                 action: function(args) {
                                     var array1 = [];
-                                    var newSize;
-                                    if (selectedDiskOfferingObj == null || selectedDiskOfferingObj.iscustomized == true) {
-                                        newSize = args.data.newsize;
-                                        if (newSize != null && newSize.length > 0) {
-                                            array1.push("&size=" + todb(newSize));
-                                        }
-                                    } else {
+                                    if(args.$form.find('.form-item[rel=shrinkok]').css("display") != "none") {
+                                        array1.push("&shrinkok=" + (args.data.shrinkok == "on"));
+                                    }
 
-                                        if(args.$form.find('.form-item[rel=shrinkok]').css("display") != "none") {
-                                            array1.push("&shrinkok=" + (args.data.shrinkok == "on"));
-                                        }
+                                    var newDiskOffering = args.data.newdiskoffering;
+                                    if (newDiskOffering != null && newDiskOffering.length > 0) {
+                                        array1.push("&diskofferingid=" + encodeURIComponent(newDiskOffering));
+                                    }
+                                    if (selectedDiskOfferingObj.iscustomized == true) {
+                                        cloudStack.addNewSizeToCommandUrlParameterArrayIfItIsNotNullAndHigherThanZero(array1, args.data.newsize);
+                                    }
 
-                                        var newDiskOffering = args.data.newdiskoffering;
+                                    var minIops;
+                                    var maxIops
+                                    if (selectedDiskOfferingObj.iscustomizediops == true) {
+                                        minIops = args.data.minIops;
+                                        maxIops = args.data.maxIops;
+                                    }
 
-                                        if (selectedDiskOfferingObj.iscustomized == true) {
-                                            newSize = args.data.newsize;
-                                        }
-                                        if (newDiskOffering != null && newDiskOffering.length > 0) {
-                                            array1.push("&diskofferingid=" + todb(newDiskOffering));
-                                        }
-                                        if (newSize != null && newSize.length > 0) {
-                                            array1.push("&size=" + todb(newSize));
-                                        }
+                                    if (minIops != null && minIops.length > 0) {
+                                        array1.push("&miniops=" + encodeURIComponent(minIops));
+                                    }
 
-                                        var minIops;
-                                        var maxIops
-
-                                        if (selectedDiskOfferingObj.iscustomizediops == true) {
-                                            minIops = args.data.minIops;
-                                            maxIops = args.data.maxIops;
-                                        }
-
-                                        if (minIops != null && minIops.length > 0) {
-                                            array1.push("&miniops=" + todb(minIops));
-                                        }
-
-                                        if (maxIops != null && maxIops.length > 0) {
-                                            array1.push("&maxiops=" + todb(maxIops));
-                                        }
+                                    if (maxIops != null && maxIops.length > 0) {
+                                        array1.push("&maxiops=" + encodeURIComponent(maxIops));
                                     }
                                     //if original disk size  > new disk size
                                     if ((args.context.volumes[0].type == "ROOT")
@@ -2102,103 +1948,7 @@
                     detailView: {
                         name: 'Snapshot detail',
                         actions: {
-                            createTemplate: {
-                                label: 'label.create.template',
-                                messages: {
-                                    confirm: function(args) {
-                                        return 'message.create.template';
-                                    },
-                                    notification: function(args) {
-                                        return 'label.create.template';
-                                    }
-                                },
-                                createForm: {
-                                    title: 'label.create.template',
-                                    desc: '',
-                                    fields: {
-                                        name: {
-                                            label: 'label.name',
-                                            validation: {
-                                                required: true
-                                            }
-                                        },
-                                        displayText: {
-                                            label: 'label.description',
-                                            validation: {
-                                                required: true
-                                            }
-                                        },
-                                        osTypeId: {
-                                            label: 'label.os.type',
-                                            select: function(args) {
-                                                $.ajax({
-                                                    url: createURL("listOsTypes"),
-                                                    dataType: "json",
-                                                    async: true,
-                                                    success: function(json) {
-                                                        var ostypes = json.listostypesresponse.ostype;
-                                                        var items = [];
-                                                        $(ostypes).each(function() {
-                                                            items.push({
-                                                                id: this.id,
-                                                                description: this.description
-                                                            });
-                                                        });
-                                                        args.response.success({
-                                                            data: items
-                                                        });
-                                                    }
-                                                });
-                                            }
-                                        },
-                                        isPublic: {
-                                            label: 'label.public',
-                                            isBoolean: true
-                                        },
-                                        isPasswordEnabled: {
-                                            label: 'label.password.enabled',
-                                            isBoolean: true
-                                        },
-                                        isdynamicallyscalable: {
-                                            label: 'label.dynamically.scalable',
-                                            isBoolean: true
-                                        }
-                                    }
-                                },
-                                action: function(args) {
-                                    var data = {
-                                        snapshotid: args.context.snapshots[0].id,
-                                        name: args.data.name,
-                                        displayText: args.data.displayText,
-                                        osTypeId: args.data.osTypeId,
-                                        isPublic: (args.data.isPublic == "on"),
-                                        passwordEnabled: (args.data.isPasswordEnabled == "on"),
-                                        isdynamicallyscalable: (args.data.isdynamicallyscalable == "on")
-                                    };
-
-                                    $.ajax({
-                                        url: createURL('createTemplate'),
-                                        data: data,
-                                        success: function(json) {
-                                            var jid = json.createtemplateresponse.jobid;
-                                            args.response.success({
-                                                _custom: {
-                                                    jobId: jid,
-                                                    getUpdatedItem: function(json) {
-                                                        return {}; //nothing in this snapshot needs to be updated
-                                                    },
-                                                    getActionFilter: function() {
-                                                        return snapshotActionfilter;
-                                                    }
-                                                }
-                                            });
-                                        }
-                                    });
-                                },
-                                notification: {
-                                    poll: pollAsyncJobResult
-                                }
-                            },
+                            createTemplate: cloudStack.createTemplateMethod(true),
 
                             createVolume: {
                                 label: 'label.action.create.volume',
@@ -2816,7 +2566,7 @@
                     }
                 } else { // Disk not attached
                     allowedActions.push("remove");
-                    if (jsonObj.state == "Ready" && isAdmin() && jsonObj.storagetype == "shared") {
+                    if (jsonObj.state == "Ready" && isAdmin()) {
                         allowedActions.push("migrateToAnotherStorage");
                     }
                     allowedActions.push("attachDisk");
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 284dad4..e721581 100755
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -279,6 +279,7 @@
                         data.systemVmCount = response.systemvms;
                         data.virtualRouterCount = response.routers;
                         data.socketCount = response.cpusockets;
+                        data.managementServerCount = response.managementservers;
                         args.response.success({
                             data: data
                         });
@@ -480,10 +481,12 @@
                                                 var array1 =[];
                                                 array1.push("&zoneId=" + args.context.zones[0].id);
 
-                                                if (args.data.vlan != null && args.data.vlan.length > 0)
-                                                array1.push("&vlan=" + todb(args.data.vlan)); else
-                                                array1.push("&vlan=untagged");
-
+                                                var vlan = "untagged";
+                                                if (args.data.vlan != null && args.data.vlan.length > 0){
+                                                    vlan = args.data.vlan;
+                                                }
+                                                cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, vlan);
+                                                
                                                 array1.push("&gateway=" + args.data.gateway);
                                                 array1.push("&netmask=" + args.data.netmask);
                                                 array1.push("&startip=" + args.data.startip);
@@ -818,11 +821,9 @@
                                                 var array1 =[];
                                                 array1.push("&zoneId=" + args.context.zones[0].id);
                                                 array1.push("&podid=" + args.data.podid);
-
                                                 array1.push("&gateway=" + args.data.gateway);
 
-                                                if (args.data.vlan != null && args.data.vlan.length > 0)
-                                                array1.push("&vlan=" + todb(args.data.vlan));
+                                                cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.vlan);
 
                                                 array1.push("&netmask=" + args.data.netmask);
                                                 array1.push("&startip=" + args.data.startip);
@@ -1050,9 +1051,7 @@
                                                 if (args.data.systemvms) {
                                                     array1.push("&forsystemvms=" + (args.data.systemvms == "on" ? "true" : "false"));
                                                 }
-
-                                                if (args.data.vlan != null && args.data.vlan.length > 0)
-                                                    array1.push("&vlan=" + todb(args.data.vlan));
+                                                cloudStack.addVlanToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.vlan);
 
                                                 $.ajax({
                                                     url: createURL("createManagementNetworkIpRange" + array1.join("")),
@@ -1561,16 +1560,16 @@
                                                 label: 'label.edit',
                                                 action: function (args) {
                                                     var array1 =[];
-                                                    array1.push("&name=" + todb(args.data.name));
-                                                    array1.push("&displaytext=" + todb(args.data.displaytext));
+                                                    array1.push("&name=" + encodeURIComponent(args.data.name));
+                                                    array1.push("&displaytext=" + encodeURIComponent(args.data.displaytext));
 
                                                     //args.data.networkdomain is null when networkdomain field is hidden
                                                     if (args.data.networkdomain != null && args.data.networkdomain != selectedGuestNetworkObj.networkdomain)
-                                                    array1.push("&networkdomain=" + todb(args.data.networkdomain));
+                                                    array1.push("&networkdomain=" + encodeURIComponent(args.data.networkdomain));
 
                                                     //args.data.networkofferingid is null when networkofferingid field is hidden
                                                     if (args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) {
-                                                        array1.push("&networkofferingid=" + todb(args.data.networkofferingid));
+                                                        array1.push("&networkofferingid=" + encodeURIComponent(args.data.networkofferingid));
 
                                                         if (args.context.networks[0].type == "Isolated") {
                                                             //Isolated network
@@ -3846,6 +3845,91 @@
                                                 }
                                             },
 
+                                            diagnostics: {
+                                                label: 'label.action.run.diagnostics',
+                                                messages: {
+                                                    notification: function (args) {
+                                                        return 'label.action.run.diagnostics';
+                                                    },
+                                                    complete: function(args) {
+                                                        var exitcode = _l('message.diagnostics.exitcode');
+                                                        exitcode = exitcode.replace('var', args.exitcode);
+                                                        var stderr = _l('message.diagnostics.stderr');
+                                                        stderr = stderr.replace('var', args.stderr);
+                                                        var stdout = _l('message.diagnostics.stdout');
+                                                        stdout = stdout.replace('var', args.stdout);
+                                                        var msg = "<div style='text-align: left; overflow-y: auto'>" + exitcode + "<br><br>" + stderr + "<br><br>" + stdout + "</div>";
+                                                        return msg;
+                                                    }
+                                                },
+                                                createForm: {
+                                                    title: 'label.action.run.diagnostics',
+                                                    desc: '',
+                                                    fields: {
+                                                        type: {
+                                                            label: 'label.run.diagnostics.type',
+                                                            validation: {
+                                                                required: true
+                                                            },
+                                                            select: function (args) {
+                                                                var items = [];
+                                                                items.push({
+                                                                    id: "ping",
+                                                                    description: "Ping"
+                                                                });
+                                                                items.push({
+                                                                    id: "traceroute",
+                                                                    description: "Traceroute"
+                                                                });
+                                                                items.push({
+                                                                    id: "arping",
+                                                                    description: "Arping"
+                                                                });
+                                                                args.response.success({
+                                                                    data: items
+                                                                });
+                                                            }
+                                                        },
+                                                        destination: {
+                                                            label: 'label.run.diagnostics.destination',
+                                                            validation: {
+                                                                required: true
+                                                            }
+                                                        },
+                                                        extra: {
+                                                            label: 'label.run.diagnostics.extra'
+                                                        }
+
+                                                    }
+                                                },
+                                                action: function (args) {
+                                                    $.ajax({
+                                                        url: createURL("runDiagnostics&targetid=" + args.context.systemVMs[0].id + "&ipaddress=" + args.data.destination + "&type=" + args.data.type + "&params=" + args.data.extra),
+                                                        dataType: "json",
+                                                        async: true,
+                                                        success: function(json) {
+                                                            var jid = json.rundiagnosticsresponse.jobid;
+                                                            args.response.success({
+                                                                _custom: {
+                                                                    jobId : jid,
+                                                                    getUpdatedItem: function (json) {
+                                                                        return json.queryasyncjobresultresponse.jobresult.diagnostics;
+
+                                                                    },
+                                                                    getActionFilter: function(){
+                                                                        return systemvmActionfilter;
+                                                                   }
+                                                                }
+
+                                                            });
+                                                        }
+                                                    }); //end ajax
+                                                },
+                                                notification: {
+                                                    poll: pollAsyncJobResult
+                                                }
+                                            },
+
                                             viewConsole: {
                                                 label: 'label.view.console',
                                                 action: {
@@ -7937,6 +8021,58 @@
                                         }
                                     },
 
+                                    updateVmwareDc: {
+                                        label: 'label.update.vmware.datacenter',
+                                        messages: {
+                                            confirm: function (args) {
+                                                return 'label.update.vmware.datacenter';
+                                            },
+                                            notification: function (args) {
+                                                return 'label.update.vmware.datacenter';
+                                            }
+                                        },
+                                        createForm: {
+                                            title: 'label.update.vmware.datacenter',
+                                            fields: {
+                                                name: {
+                                                    label: 'label.vmware.datacenter.name'
+                                                },
+                                                vcenter: {
+                                                    label: 'label.vmware.datacenter.vcenter'
+                                                },
+                                                username: {
+                                                    label: 'label.username'
+                                                },
+                                                password: {
+                                                    label: 'label.password',
+                                                    isPassword: true
+                                                }
+                                            }
+                                        },
+                                        action: function (args) {
+                                            var data = args.data;
+                                            data.zoneid = args.context.physicalResources[0].id;
+                                            $.ajax({
+                                                url: createURL('updateVmwareDc'),
+                                                data: data,
+                                                success: function (json) {
+                                                    args.response.success({
+                                                        data: args.context.physicalResources[0]
+                                                    });
+                                                },
+                                                error: function (XMLHttpResponse) {
+                                                    var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
+                                                    args.response.error(errorMsg);
+                                                }
+                                            });
+                                        },
+                                        notification: {
+                                            poll: function (args) {
+                                                args.complete();
+                                            }
+                                        }
+                                    },
+
                                     removeVmwareDc: {
                                         label: 'label.remove.vmware.datacenter',
                                         messages: {
@@ -8101,7 +8237,7 @@
                                             //EXPLICIT DEDICATION
                                             var array2 =[];
                                             if (args.data.accountId != "")
-                                            array2.push("&account=" + todb(args.data.accountId));
+                                            array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
                                             $.ajax({
                                                 url: createURL("dedicateZone&zoneId=" +
@@ -8198,23 +8334,23 @@
                                         label: 'label.edit',
                                         action: function (args) {
                                             var array1 =[];
-                                            array1.push("&name=" + todb(args.data.name));
-                                            array1.push("&dns1=" + todb(args.data.dns1));
-                                            array1.push("&dns2=" + todb(args.data.dns2));
+                                            array1.push("&name=" + encodeURIComponent(args.data.name));
+                                            array1.push("&dns1=" + encodeURIComponent(args.data.dns1));
+                                            array1.push("&dns2=" + encodeURIComponent(args.data.dns2));
                                             //dns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
-                                            array1.push("&ip6dns1=" + todb(args.data.ip6dns1));
+                                            array1.push("&ip6dns1=" + encodeURIComponent(args.data.ip6dns1));
                                             //p6dns1 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
-                                            array1.push("&ip6dns2=" + todb(args.data.ip6dns2));
+                                            array1.push("&ip6dns2=" + encodeURIComponent(args.data.ip6dns2));
                                             //ip6dns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
 
                                             if (selectedZoneObj.networktype == "Advanced" && args.data.guestcidraddress) {
-                                                array1.push("&guestcidraddress=" + todb(args.data.guestcidraddress));
+                                                array1.push("&guestcidraddress=" + encodeURIComponent(args.data.guestcidraddress));
                                             }
 
-                                            array1.push("&internaldns1=" + todb(args.data.internaldns1));
-                                            array1.push("&internaldns2=" + todb(args.data.internaldns2));
+                                            array1.push("&internaldns1=" + encodeURIComponent(args.data.internaldns1));
+                                            array1.push("&internaldns2=" + encodeURIComponent(args.data.internaldns2));
                                             //internaldns2 can be empty ("") when passed to API, so a user gets to update this field from an existing value to blank.
-                                            array1.push("&domain=" + todb(args.data.domain));
+                                            array1.push("&domain=" + encodeURIComponent(args.data.domain));
                                             array1.push("&localstorageenabled=" + (args.data.localstorageenabled == 'on'));
                                             $.ajax({
                                                 url: createURL("updateZone&id=" + args.context.physicalResources[0].id + array1.join("")),
@@ -8863,6 +8999,91 @@
                                                         }
                                                     },
 
+                                                    diagnostics: {
+                                                        label: 'label.action.run.diagnostics',
+                                                        messages: {
+                                                            notification: function (args) {
+                                                                return 'label.action.run.diagnostics';
+                                                            },
+                                                            complete: function(args) {
+                                                                var exitcode = _l('message.diagnostics.exitcode');
+                                                                exitcode = exitcode.replace('var', args.exitcode);
+                                                                var stderr = _l('message.diagnostics.stderr');
+                                                                stderr = stderr.replace('var', args.stderr);
+                                                                var stdout = _l('message.diagnostics.stdout');
+                                                                stdout = stdout.replace('var', args.stdout);
+                                                                var msg = "<div style='text-align: left; overflow-y: auto'>" + exitcode + "<br><br>" + stderr + "<br><br>" + stdout + "</div>";
+                                                                return msg;
+                                                            }
+                                                        },
+                                                        createForm: {
+                                                            title: 'label.action.run.diagnostics',
+                                                            desc: '',
+                                                            fields: {
+                                                                type: {
+                                                                    label: 'label.run.diagnostics.type',
+                                                                    validation: {
+                                                                        required: true
+                                                                    },
+                                                                    select: function (args) {
+                                                                        var items = [];
+                                                                        items.push({
+                                                                            id: "ping",
+                                                                            description: "Ping"
+                                                                        });
+                                                                        items.push({
+                                                                            id: "traceroute",
+                                                                            description: "Traceroute"
+                                                                        });
+                                                                        items.push({
+                                                                            id: "arping",
+                                                                            description: "Arping"
+                                                                        });
+                                                                        args.response.success({
+                                                                            data: items
+                                                                        });
+                                                                    }
+                                                                },
+                                                                destination: {
+                                                                    label: 'label.run.diagnostics.destination',
+                                                                    validation: {
+                                                                        required: true
+                                                                    }
+                                                                },
+                                                                extra: {
+                                                                    label: 'label.run.diagnostics.extra'
+                                                                }
+
+                                                            }
+                                                        },
+                                                        action: function (args) {
+                                                            $.ajax({
+                                                                url: createURL("runDiagnostics&targetid=" + args.context.systemVMs[0].id + "&ipaddress=" + args.data.destination + "&type=" + args.data.type + "&params=" + args.data.extra),
+                                                                dataType: "json",
+                                                                async: true,
+                                                                success: function(json) {
+                                                                    var jid = json.rundiagnosticsresponse.jobid;
+                                                                    args.response.success({
+                                                                        _custom: {
+                                                                            jobId : jid,
+                                                                            getUpdatedItem: function (json) {
+                                                                                return json.queryasyncjobresultresponse.jobresult.diagnostics;
+
+                                                                            },
+                                                                            getActionFilter: function(){
+                                                                                return systemvmActionfilter;
+                                                                           }
+                                                                        }
+
+                                                                    });
+                                                                }
+                                                            }); //end ajax
+                                                        },
+                                                        notification: {
+                                                            poll: pollAsyncJobResult
+                                                        }
+                                                    },
+
                                                     scaleUp: {
                                                         label: 'label.change.service.offering',
                                                         createForm: {
@@ -9736,6 +9957,40 @@
                             };
 
                             return listView;
+                        },
+
+                        managementServers: function () {
+                            var listView = {
+                                id: 'managementservers',
+                                fields: {
+                                    name: {
+                                        label: 'label.name'
+                                    },
+                                    id: {
+                                        label: 'label.uuid'
+                                    },
+                                    state: {
+                                        label: 'label.state',
+                                        indicator: {
+                                            'Up': 'on',
+                                            'Down': 'off'
+                                        }
+                                    },
+                                    version: {
+                                        label: 'label.version'
+                                    }
+                                },
+                                dataProvider: function (args) {
+                                        $.ajax({
+                                            url: createURL('listManagementServers'),
+                                            async: false,
+                                            success: function (json) {
+                                                args.response.success({ data: json.listmanagementserversresponse.managementserver });
+                                            }
+                                        });
+                                    }
+                                };
+                            return listView;
                         }
                     }
                 }
@@ -10189,6 +10444,92 @@
                                         }
                                     },
 
+                                    // VR Diagnostics
+                                    diagnostics: {
+                                        label: 'label.action.run.diagnostics',
+                                        messages: {
+                                            notification: function (args) {
+                                                return 'label.action.run.diagnostics';
+                                            },
+                                            complete: function(args) {
+                                                var exitcode = _l('message.diagnostics.exitcode');
+                                                exitcode = exitcode.replace('var', args.exitcode);
+                                                var stderr = _l('message.diagnostics.stderr');
+                                                stderr = stderr.replace('var', args.stderr);
+                                                var stdout = _l('message.diagnostics.stdout');
+                                                stdout = stdout.replace('var', args.stdout);
+                                                var msg = "<div style='text-align: left; overflow-y: auto'>" + exitcode + "<br><br>" + stderr + "<br><br>" + stdout + "</div>";
+                                                return msg;
+                                            }
+                                        },
+                                        createForm: {
+                                            title: 'label.action.run.diagnostics',
+                                            desc: '',
+                                            fields: {
+                                                type: {
+                                                    label: 'label.run.diagnostics.type',
+                                                    validation: {
+                                                        required: true
+                                                    },
+                                                    select: function (args) {
+                                                        var items = [];
+                                                        items.push({
+                                                            id: "ping",
+                                                            description: "Ping"
+                                                        });
+                                                        items.push({
+                                                            id: "traceroute",
+                                                            description: "Traceroute"
+                                                        });
+                                                        items.push({
+                                                            id: "arping",
+                                                            description: "Arping"
+                                                        });
+                                                        args.response.success({
+                                                            data: items
+                                                        });
+                                                    }
+                                                },
+                                                destination: {
+                                                    label: 'label.run.diagnostics.destination',
+                                                    validation: {
+                                                        required: true
+                                                    }
+                                                },
+                                                extra: {
+                                                    label: 'label.run.diagnostics.extra'
+                                                }
+
+                                            }
+                                        },
+                                        action: function (args) {
+                                            $.ajax({
+                                                url: createURL("runDiagnostics&targetid=" + args.context.routers[0].id + "&ipaddress=" + args.data.destination + "&type=" + args.data.type + "&params=" + args.data.extra),
+                                                dataType: "json",
+                                                async: true,
+                                                success: function(json) {
+                                                    var jid = json.rundiagnosticsresponse.jobid;
+                                                    args.response.success({
+                                                        _custom: {
+                                                            jobId : jid,
+                                                            getUpdatedItem: function (json) {
+                                                                return json.queryasyncjobresultresponse.jobresult.diagnostics;
+
+                                                            },
+                                                            getActionFilter: function(){
+                                                                return routerActionfilter;
+                                                           }
+                                                        }
+
+                                                    });
+                                                }
+                                            }); //end ajax
+                                        },
+                                        notification: {
+                                            poll: pollAsyncJobResult
+                                        }
+                                    },
+
                                     scaleUp: { //*** Infrastructure > Virtual Routers > change service offering ***
                                         label: 'label.change.service.offering',
                                         createForm: {
@@ -11454,6 +11795,91 @@
                                 }
                             },
 
+                            diagnostics: {
+                                label: 'label.action.run.diagnostics',
+                                messages: {
+                                    notification: function (args) {
+                                        return 'label.action.run.diagnostics';
+                                    },
+                                    complete: function(args) {
+                                        var exitcode = _l('message.diagnostics.exitcode');
+                                        exitcode = exitcode.replace('var', args.exitcode);
+                                        var stderr = _l('message.diagnostics.stderr');
+                                        stderr = stderr.replace('var', args.stderr);
+                                        var stdout = _l('message.diagnostics.stdout');
+                                        stdout = stdout.replace('var', args.stdout);
+                                        var msg = "<div style='text-align: left; overflow-y: auto'>" + exitcode + "<br><br>" + stderr + "<br><br>" + stdout + "</div>";
+                                        return msg;
+                                    }
+                                },
+                                createForm: {
+                                    title: 'label.action.run.diagnostics',
+                                    desc: '',
+                                    fields: {
+                                        type: {
+                                            label: 'label.run.diagnostics.type',
+                                            validation: {
+                                                required: true
+                                            },
+                                            select: function (args) {
+                                                var items = [];
+                                                items.push({
+                                                    id: "ping",
+                                                    description: "Ping"
+                                                });
+                                                items.push({
+                                                    id: "traceroute",
+                                                    description: "Traceroute"
+                                                });
+                                                items.push({
+                                                    id: "arping",
+                                                    description: "Arping"
+                                                });
+                                                args.response.success({
+                                                    data: items
+                                                });
+                                            }
+                                        },
+                                        destination: {
+                                            label: 'label.run.diagnostics.destination',
+                                            validation: {
+                                                required: true
+                                            }
+                                        },
+                                        extra: {
+                                            label: 'label.run.diagnostics.extra'
+                                        }
+
+                                    }
+                                },
+                                action: function (args) {
+                                    $.ajax({
+                                        url: createURL("runDiagnostics&targetid=" + args.context.systemVMs[0].id + "&ipaddress=" + args.data.destination + "&type=" + args.data.type + "&params=" + args.data.extra),
+                                        dataType: "json",
+                                        async: true,
+                                        success: function(json) {
+                                            var jid = json.rundiagnosticsresponse.jobid;
+                                            args.response.success({
+                                                _custom: {
+                                                    jobId : jid,
+                                                    getUpdatedItem: function (json) {
+                                                        return json.queryasyncjobresultresponse.jobresult.diagnostics;
+
+                                                    },
+                                                    getActionFilter: function(){
+                                                        return systemvmActionfilter;
+                                                   }
+                                                }
+
+                                            });
+                                        }
+                                    }); //end ajax
+                                },
+                                notification: {
+                                    poll: pollAsyncJobResult
+                                }
+                            },
+
                             scaleUp: { //*** Infrastructure > System VMs (consoleProxy or SSVM) > change service offering ***
                                 label: 'label.change.service.offering',
                                 createForm: {
@@ -11547,8 +11973,6 @@
                                 }
                             },
 
-
-
                             viewConsole: {
                                 label: 'label.view.console',
                                 action: {
@@ -13668,14 +14092,14 @@
                                 };
 
                                 array1.push("&zoneId=" + args.data.zoneid);
-                                array1.push("&name=" + todb(args.data.podname));
-                                array1.push("&gateway=" + todb(args.data.reservedSystemGateway));
-                                array1.push("&netmask=" + todb(args.data.reservedSystemNetmask));
-                                array1.push("&startIp=" + todb(args.data.reservedSystemStartIp));
+                                array1.push("&name=" + encodeURIComponent(args.data.podname));
+                                array1.push("&gateway=" + encodeURIComponent(args.data.reservedSystemGateway));
+                                array1.push("&netmask=" + encodeURIComponent(args.data.reservedSystemNetmask));
+                                array1.push("&startIp=" + encodeURIComponent(args.data.reservedSystemStartIp));
 
                                 var endip = args.data.reservedSystemEndIp; //optional
                                 if (endip != null && endip.length > 0)
-                                array1.push("&endIp=" + todb(endip));
+                                array1.push("&endIp=" + encodeURIComponent(endip));
                                 var podId = null;
                                 $.ajax({
                                     url: createURL("createPod" + array1.join("")),
@@ -13689,7 +14113,7 @@
                                         if (args.$form.find('.form-item[rel=isDedicated]').find('input[type=checkbox]').is(':Checked') == true) {
                                             var array2 =[];
                                             if (args.data.accountId != "")
-                                            array2.push("&account=" + todb(args.data.accountId));
+                                            array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
                                             if (podId != null) {
                                                 $.ajax({
@@ -13768,11 +14192,11 @@
                                 action: function (args) {
                                     var array1 =[];
 
-                                    array1.push("&name=" + todb(args.data.name));
-                                    array1.push("&netmask=" + todb(args.data.netmask));
+                                    array1.push("&name=" + encodeURIComponent(args.data.name));
+                                    array1.push("&netmask=" + encodeURIComponent(args.data.netmask));
 
                                     if (args.data.gateway != null && args.data.gateway.length > 0)
-                                    array1.push("&gateway=" + todb(args.data.gateway));
+                                    array1.push("&gateway=" + encodeURIComponent(args.data.gateway));
 
                                     $.ajax({
                                         url: createURL("updatePod&id=" + args.context.pods[0].id + array1.join("")),
@@ -13883,7 +14307,7 @@
                                     //EXPLICIT DEDICATION
                                     var array2 =[];
                                     if (args.data.accountId != "")
-                                    array2.push("&account=" + todb(args.data.accountId));
+                                    array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
                                     $.ajax({
                                         url: createURL("dedicatePod&podId=" +
@@ -14729,13 +15153,12 @@
 
                                 var clusterName = args.data.name;
                                 if (args.data.hypervisor == "Ovm3") {
-                                     array1.push("&ovm3pool=" + todb(args.data.ovm3pool));
-                                     array1.push("&ovm3cluster=" + todb(args.data.ovm3cluster));
-                                     array1.push("&ovm3vip=" + todb(args.data.ovm3vip));
+                                     array1.push("&ovm3pool=" + encodeURIComponent(args.data.ovm3pool));
+                                     array1.push("&ovm3cluster=" + encodeURIComponent(args.data.ovm3cluster));
+                                     array1.push("&ovm3vip=" + encodeURIComponent(args.data.ovm3vip));
                                 }
                                 if (args.data.hypervisor == "VMware") {
-                                    array1.push("&username=" + todb(args.data.vCenterUsername));
-                                    array1.push("&password=" + todb(args.data.vCenterPassword));
+                                    cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.vCenterUsername, args.data.vCenterPassword);
 
                                     //vSwitch Public Type
                                     if (args.$form.find('.form-item[rel=vSwitchPublicType]').css('display') != 'none' && args.data.vSwitchPublicType != "") {
@@ -14802,11 +15225,11 @@
                                     url = "http://" + hostname; else
                                     url = hostname;
                                     url += "/" + dcName + "/" + clusterName;
-                                    array1.push("&url=" + todb(url));
+                                    array1.push("&url=" + encodeURIComponent(url));
 
                                     clusterName = hostname + "/" + dcName + "/" + clusterName; //override clusterName
                                 }
-                                array1.push("&clustername=" + todb(clusterName));
+                                array1.push("&clustername=" + encodeURIComponent(clusterName));
                                 var clusterId = null;
                                 $.ajax({
                                     url: createURL("addCluster" + array1.join("")),
@@ -14820,7 +15243,7 @@
                                         var array2 =[];
                                         if (args.$form.find('.form-item[rel=isDedicated]').find('input[type=checkbox]').is(':Checked') == true) {
                                             if (args.data.accountId != "")
-                                            array2.push("&account=" + todb(args.data.accountId));
+                                            array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
                                             if (clusterId != null) {
                                                 $.ajax({
@@ -15052,7 +15475,7 @@
                                     //EXPLICIT DEDICATION
                                     var array2 =[];
                                     if (args.data.accountId != "")
-                                    array2.push("&account=" + todb(args.data.accountId));
+                                    array2.push("&account=" + encodeURIComponent(args.data.accountId));
                                     $.ajax({
                                         url: createURL("dedicateCluster&clusterId=" +
                                         args.context.clusters[0].id +
@@ -16319,7 +16742,7 @@
 
                                         if (args.$form.find('.form-item[rel=isDedicated]').find('input[type=checkbox]').is(':Checked') == true) {
                                             if (args.data.accountId != "")
-                                            array2.push("&account=" + todb(args.data.accountId));
+                                            array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
 
                                             if (hostId != null) {
@@ -16399,7 +16822,7 @@
                                 label: 'label.edit',
                                 action: function (args) {
                                     var array1 =[];
-                                    array1.push("&hosttags=" + todb(args.data.hosttags));
+                                    array1.push("&hosttags=" + encodeURIComponent(args.data.hosttags));
 
                                     if (args.data.oscategoryid != null && args.data.oscategoryid.length > 0)
                                         array1.push("&osCategoryId=" + args.data.oscategoryid);
@@ -16483,7 +16906,7 @@
                                     //EXPLICIT DEDICATION
                                     var array2 =[];
                                     if (args.data.accountId != "")
-                                    array2.push("&account=" + todb(args.data.accountId));
+                                    array2.push("&account=" + encodeURIComponent(args.data.accountId));
 
                                     $.ajax({
                                         url: createURL("dedicateHost&hostId=" +
@@ -17466,6 +17889,9 @@
                                     },
                                     cpusockets: {
                                         label: 'label.number.of.cpu.sockets'
+                                    },
+                                    managementServers: {
+                                        label: 'label.number.of.management.servers'
                                     }
                                 }, {
 
@@ -18734,7 +19160,7 @@
                             /******************************/
                             action: function (args) {
                                 var array1 =[];
-                                array1.push("&scope=" + todb(args.data.scope));
+                                array1.push("&scope=" + encodeURIComponent(args.data.scope));
 
                                 array1.push("&zoneid=" + args.data.zoneid);
 
@@ -18755,9 +19181,9 @@
                                     array1.push("&hostid=" + args.data.hostId);
                                 }
 
-                                array1.push("&name=" + todb(args.data.name));
+                                array1.push("&name=" + encodeURIComponent(args.data.name));
 
-                                array1.push("&provider=" + todb(args.data.provider));
+                                array1.push("&provider=" + encodeURIComponent(args.data.provider));
 
                                 if (args.data.provider == "DefaultPrimary")
                                 {
@@ -18774,7 +19200,7 @@
                                             path = "/" + path;
                                         url = smbURL(server, path);
                                         array1.push("&details[0].user=" + args.data.smbUsername);
-                                        array1.push("&details[1].password=" + todb(args.data.smbPassword));
+                                        array1.push("&details[1].password=" + encodeURIComponent(args.data.smbPassword));
                                         array1.push("&details[2].domain=" + args.data.smbDomain);
                                     } else if (args.data.protocol == "PreSetup") {
                                         var path = args.data.path;
@@ -18824,7 +19250,7 @@
                                         url = "";
                                     }
 
-                                    array1.push("&url=" + todb(url));
+                                    array1.push("&url=" + encodeURIComponent(url));
                                 }
                                 else
                                 {
@@ -18842,13 +19268,13 @@
 
                                     if (args.data.url != null && args.data.url.length > 0)
                                     {
-                                        array1.push("&url=" + todb(args.data.url));
+                                        array1.push("&url=" + encodeURIComponent(args.data.url));
                                     }
                                 }
 
                                 if (args.data.storageTags != null && args.data.storageTags.length > 0)
                                 {
-                                    array1.push("&tags=" + todb(args.data.storageTags));
+                                    array1.push("&tags=" + encodeURIComponent(args.data.storageTags));
                                 }
 
                                 if ("custom" in args.response) {
@@ -18913,7 +19339,7 @@
                                 label: 'label.edit',
                                 action: function (args) {
                                     var array1 =[];
-                                    array1.push("&tags=" + todb(args.data.tags));
+                                    array1.push("&tags=" + encodeURIComponent(args.data.tags));
 
                                     if (args.data.disksizetotal != null && args.data.disksizetotal.length > 0) {
                                         var diskSizeTotal = args.data.disksizetotal.split(",").join("");
@@ -19839,7 +20265,7 @@
                                                 select: function (args) {
                                                     /*
                                                     UI no longer gets providers from "listStorageProviders&type=image" because:
-                                                    (1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI).
+                                                    (1) Not all of returned values are handled by UI.
                                                     (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image"
                                                      */
                                                     var items =[ {
@@ -21140,14 +21566,13 @@
     function addExternalLoadBalancer(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&networkdevicetype=" + todb(args.data.networkdevicetype));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password);
+        array1.push("&networkdevicetype=" + encodeURIComponent(args.data.networkdevicetype));
 
         if (apiCmd == "addNetscalerLoadBalancer") {
             array1.push("&gslbprovider=" + (args.data.gslbprovider == "on"));
-            array1.push("&gslbproviderpublicip=" + todb(args.data.gslbproviderpublicip));
-            array1.push("&gslbproviderprivateip=" + todb(args.data.gslbproviderprivateip));
+            array1.push("&gslbproviderpublicip=" + encodeURIComponent(args.data.gslbproviderpublicip));
+            array1.push("&gslbproviderprivateip=" + encodeURIComponent(args.data.gslbproviderprivateip));
         }
 
         //construct URL starts here
@@ -21224,7 +21649,7 @@
         url.push("lbdevicededicated=" + dedicated.toString());
 
 
-        array1.push("&url=" + todb(url.join("")));
+        array1.push("&url=" + encodeURIComponent(url.join("")));
         //construct URL ends here
 
         $.ajax({
@@ -21250,9 +21675,8 @@
     function addExternalFirewall(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&networkdevicetype=" + todb(args.data.networkdevicetype));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password); 
+        array1.push("&networkdevicetype=" + encodeURIComponent(args.data.networkdevicetype));
 
         //construct URL starts here
         var url =[];
@@ -21406,7 +21830,7 @@
         }
         // END - Palo Alto Specific Fields
 
-        array1.push("&url=" + todb(url.join("")));
+        array1.push("&url=" + encodeURIComponent(url.join("")));
         //construct URL ends here
 
         $.ajax({
@@ -21432,19 +21856,18 @@
     function addNiciraNvpDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&hostname=" + todb(args.data.host));
-        array1.push("&transportzoneuuid=" + todb(args.data.transportzoneuuid));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, rgs.data.username, args.data.password);
+        array1.push("&hostname=" + encodeURIComponent(args.data.host));
+        array1.push("&transportzoneuuid=" + encodeURIComponent(args.data.transportzoneuuid));
 
         var l3GatewayServiceUuid = args.data.l3gatewayserviceuuid;
         if (l3GatewayServiceUuid != null && l3GatewayServiceUuid.length > 0) {
-            array1.push("&l3gatewayserviceuuid=" + todb(args.data.l3gatewayserviceuuid));
+            array1.push("&l3gatewayserviceuuid=" + encodeURIComponent(args.data.l3gatewayserviceuuid));
         }
 		
 		var l2GatewayServiceUuid = args.data.l2gatewayserviceuuid;
         if (l2GatewayServiceUuid != null && l2GatewayServiceUuid.length > 0) {
-            array1.push("&l2gatewayserviceuuid=" + todb(args.data.l2gatewayserviceuuid));
+            array1.push("&l2gatewayserviceuuid=" + encodeURIComponent(args.data.l2gatewayserviceuuid));
         }
 
         $.ajax({
@@ -21470,9 +21893,8 @@
     function addBrocadeVcsDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&hostname=" + todb(args.data.host));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password);
+        array1.push("&hostname=" + encodeURIComponent(args.data.host));
 
         $.ajax({
             url: createURL(apiCmd + array1.join("")),
@@ -21497,9 +21919,8 @@
     function addOpenDaylightController(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&url=" + todb(args.data.url));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password);
+        array1.push("&url=" + encodeURIComponent(args.data.url));
 
         $.ajax({
             url: createURL(apiCmd + array1.join("")),
@@ -21524,9 +21945,9 @@
     function addBigSwitchBcfDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 =[];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&hostname=" + todb(args.data.host));
-        array1.push("&username=" + args.data.username);
-        array1.push("&password=" + args.data.password);
+        array1.push("&hostname=" + encodeURIComponent(args.data.host));
+        array1.push("&username=" + encodeURIComponent(args.data.username));
+        cloudStack.addPasswordToCommandUrlParameterArray(array1, args.data.password);
         array1.push("&nat=" + (args.data.nat == 'on' ? "true": "false"));
 
         $.ajax({
@@ -21551,13 +21972,12 @@
     function addNuageVspDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
         var array1 = [];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&hostname=" + todb(args.data.hostname));
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&port=" + todb(args.data.port));
-        array1.push("&apiversion=" + todb(args.data.apiversion));
-        array1.push("&retrycount=" + todb(args.data.retrycount));
-        array1.push("&retryinterval=" + todb(args.data.retryinterval));
+        array1.push("&hostname=" + encodeURIComponent(args.data.hostname));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password);
+        array1.push("&port=" + encodeURIComponent(args.data.port));
+        array1.push("&apiversion=" + encodeURIComponent(args.data.apiversion));
+        array1.push("&retrycount=" + encodeURIComponent(args.data.retrycount));
+        array1.push("&retryinterval=" + encodeURIComponent(args.data.retryinterval));
 
         $.ajax({
             url: createURL(apiCmd + array1.join("")),
@@ -21582,9 +22002,8 @@
     function addGloboDnsHost(args, physicalNetworkObj, apiCmd, apiCmdRes) {
         var array1 = [];
         array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
-        array1.push("&username=" + todb(args.data.username));
-        array1.push("&password=" + todb(args.data.password));
-        array1.push("&url=" + todb(args.data.url));
+        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.username, args.data.password);
+        array1.push("&url=" + encodeURIComponent(args.data.url));
 
         $.ajax({
             url: createURL(apiCmd + array1.join("")),
@@ -21745,20 +22164,9 @@
                                                                                                                                     dataType: "json",
                                                                                                                                     async: false,
                                                                                                                                     success: function (json) {
-                                                                                                                                        //create pod
-                                                                                                                                        var array3 =[];
-                                                                                                                                        array3.push("&zoneId=" + newZoneObj.id);
-                                                                                                                                        array3.push("&name=" + todb(args.data.podName));
-                                                                                                                                        array3.push("&gateway=" + todb(args.data.podGateway));
-                                                                                                                                        array3.push("&netmask=" + todb(args.data.podNetmask));
-                                                                                                                                        array3.push("&startIp=" + todb(args.data.podStartIp));
-
-                                                                                                                                        var endip = args.data.podEndIp; //optional
-                                                                                                                                        if (endip != null && endip.length > 0)
-                                                                                                                                        array3.push("&endIp=" + todb(endip));
-
+                                                                                                                                        var arrayOfParameters = cloudStack.createArrayOfParametersForCreatePodCommand(newZoneObj.id, args.data);
                                                                                                                                         $.ajax({
-                                                                                                                                            url: createURL("createPod" + array3.join("")),
+                                                                                                                                            url: createURL("createPod" + arrayOfParameters.join("")),
                                                                                                                                             dataType: "json",
                                                                                                                                             async: false,
                                                                                                                                             success: function (json) {
@@ -21796,20 +22204,9 @@
                                                                                                         dataType: "json",
                                                                                                         async: false,
                                                                                                         success: function (json) {
-                                                                                                            //create pod
-                                                                                                            var array3 =[];
-                                                                                                            array3.push("&zoneId=" + newZoneObj.id);
-                                                                                                            array3.push("&name=" + todb(args.data.podName));
-                                                                                                            array3.push("&gateway=" + todb(args.data.podGateway));
-                                                                                                            array3.push("&netmask=" + todb(args.data.podNetmask));
-                                                                                                            array3.push("&startIp=" + todb(args.data.podStartIp));
-
-                                                                                                            var endip = args.data.podEndIp; //optional
-                                                                                                            if (endip != null && endip.length > 0)
-                                                                                                            array3.push("&endIp=" + todb(endip));
-
+                                                                                                            var arrayOfParameters = cloudStack.createArrayOfParametersForCreatePodCommand(newZoneObj.id, args.data);
                                                                                                             $.ajax({
-                                                                                                                url: createURL("createPod" + array3.join("")),
+                                                                                                                url: createURL("createPod" + arrayOfParameters.join("")),
                                                                                                                 dataType: "json",
                                                                                                                 async: false,
                                                                                                                 success: function (json) {
@@ -21823,21 +22220,9 @@
                                                                                                     });
                                                                                                 }
                                                                                             } else {
-                                                                                                //Advanced zone
-                                                                                                //create pod
-                                                                                                var array3 =[];
-                                                                                                array3.push("&zoneId=" + newZoneObj.id);
-                                                                                                array3.push("&name=" + todb(args.data.podName));
-                                                                                                array3.push("&gateway=" + todb(args.data.podGateway));
-                                                                                                array3.push("&netmask=" + todb(args.data.podNetmask));
-                                                                                                array3.push("&startIp=" + todb(args.data.podStartIp));
-
-                                                                                                var endip = args.data.podEndIp; //optional
-                                                                                                if (endip != null && endip.length > 0)
-                                                                                                array3.push("&endIp=" + todb(endip));
-
+                                                                                                var arrayOfParameters = cloudStack.createArrayOfParametersForCreatePodCommand(newZoneObj.id, args.data);
                                                                                                 $.ajax({
-                                                                                                    url: createURL("createPod" + array3.join("")),
+                                                                                                    url: createURL("createPod" + arrayOfParameters.join("")),
                                                                                                     dataType: "json",
                                                                                                     async: false,
                                                                                                     success: function (json) {
@@ -21897,9 +22282,12 @@
         var jsonObj = args.context.item;
         var allowedActions =[ 'enableSwift'];
 
-        if (jsonObj.vmwaredcId == null)
-        allowedActions.push('addVmwareDc'); else
-        allowedActions.push('removeVmwareDc');
+        if (jsonObj.vmwaredcId == null) {
+            allowedActions.push('addVmwareDc');
+        } else {
+            allowedActions.push('updateVmwareDc');
+            allowedActions.push('removeVmwareDc');
+        }
 
         if (jsonObj.domainid != null)
         allowedActions.push("releaseDedicatedZone"); else
@@ -22142,8 +22530,10 @@
             allowedActions.push("remove");
             allowedActions.push("viewConsole");
 
-            if (isAdmin())
-            allowedActions.push("migrate");
+            if (isAdmin()) {
+                allowedActions.push("migrate");
+                allowedActions.push("diagnostics");
+            }
         } else if (jsonObj.state == 'Starting') {
             if (isAdmin()) {
                 allowedActions.push("viewConsole");
@@ -22193,8 +22583,10 @@
             }
 
             allowedActions.push("viewConsole");
-            if (isAdmin())
-            allowedActions.push("migrate");
+            if (isAdmin()) {
+                allowedActions.push("migrate");
+                allowedActions.push("diagnostics");
+            }
         } else if (jsonObj.state == 'Starting') {
             if (isAdmin()) {
                 allowedActions.push("viewConsole");
diff --git a/ui/scripts/ui-custom/accountsWizard.js b/ui/scripts/ui-custom/accountsWizard.js
index c9e1e45..a932887 100644
--- a/ui/scripts/ui-custom/accountsWizard.js
+++ b/ui/scripts/ui-custom/accountsWizard.js
@@ -94,7 +94,7 @@
 
                 $wizard.click(function(event) {
                     var $target = $(event.target);
-                    if ($target.closest('button.next').size()) {
+                    if ($target.closest('button.next').length) {
                         $form.validate();
                         if ($form.valid()) {
                             completeAction();
@@ -104,7 +104,7 @@
                         }
                     }
 
-                    if ($target.closest('button.cancel').size()) {
+                    if ($target.closest('button.cancel').length) {
                         close();
                         return false;
                     }
@@ -112,14 +112,14 @@
 
                 if (ldapStatus) {
                     var $table = $wizard.find('.ldap-account-choice tbody');
-                    $("#label_ldap_group_name").live("keypress", function(event) {
+                    $("#label_ldap_group_name").on("keypress", function(event) {
                         if ($table.find("#tr-groupname-message").length === 0) {
                             $("<tr id='tr-groupname-message'>").appendTo($table).append("<td colspan=\"4\">"+_l('message.ldap.group.import')+"</td>");
                         }
                         $table.find("tr").hide();
                         $table.find("#tr-groupname-message").show();
                     });
-                    $("#label_ldap_group_name").live("blur", function(event) {
+                    $("#label_ldap_group_name").on("blur", function(event) {
                         if (!$(this).val()) {
                             $table.find("tr").show();
                             $table.find("#tr-groupname-message").hide();
@@ -322,13 +322,14 @@
                     });
                 }
 
-                return $wizard.dialog({
+                var $dialog = $wizard.dialog({
                     title: ldapStatus ? _l('label.add.LDAP.account') : _l('label.add.account'),
                     width: ldapStatus ? 800 : 330,
                     height: ldapStatus ? 500 : 500,
-                    closeOnEscape: false,
-                    zIndex: 5000
-                }).closest('.ui-dialog').overlay();
+                    closeOnEscape: false
+                });
+                
+                return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
             };
 
             accountsWizard(args);
diff --git a/ui/scripts/ui-custom/affinity.js b/ui/scripts/ui-custom/affinity.js
index e4a87dd..d074093 100644
--- a/ui/scripts/ui-custom/affinity.js
+++ b/ui/scripts/ui-custom/affinity.js
@@ -136,8 +136,8 @@
                         });
                     }
                 }]
-            }).parent('.ui-dialog').overlay();
-
+            });
+            cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dataList);
             // Add tier select dialog
             if (tierSelect) {
                 var $toolbar = $dataList.find('.toolbar');
diff --git a/ui/scripts/ui-custom/enableStaticNAT.js b/ui/scripts/ui-custom/enableStaticNAT.js
index e469ca9..37d7180 100644
--- a/ui/scripts/ui-custom/enableStaticNAT.js
+++ b/ui/scripts/ui-custom/enableStaticNAT.js
@@ -70,7 +70,7 @@
                 listView: listView
             }).dialog({
                 dialogClass: 'multi-edit-add-list panel',
-                width: 825,
+                width: 875,
                 title: _l('label.select.vm.for.static.nat'),
                 buttons: [{
                     text: _l('label.apply'),
@@ -85,7 +85,7 @@
 
                         if (!$dataList.find(
                             'input[type=radio]:checked, input[type=checkbox]:checked'
-                        ).size()) {
+                        ).length) {
                             cloudStack.dialog.notice({
                                 message: _l('message.select.instance')
                             });
@@ -138,7 +138,9 @@
                         });
                     }
                 }]
-            }).parent('.ui-dialog').overlay();
+            });
+            
+            cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dataList);
 
             // Add tier select dialog
             if (tierSelect) {
diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js
index e951705..9b41e35 100644
--- a/ui/scripts/ui-custom/instanceWizard.js
+++ b/ui/scripts/ui-custom/instanceWizard.js
@@ -60,12 +60,12 @@
                     data['new-network-ip'] = $form.find('.new-network .select.advanced .specify-ip input[type=text]').val();
 
                     // Handle multi-disk service offerings
-                    if ($form.find('.multi-disk-select-container').size()) {
+                    if ($form.find('.multi-disk-select-container').length) {
                         data['disk-offerings-multi'] = [];
 
                         var $diskGroups = $form.find('.disk-select-group');
                         var $selectedDisks = $.grep($diskGroups, function (diskGroup) {
-                            return $(diskGroup).find('input[type=checkbox]:checked').size();
+                            return $(diskGroup).find('input[type=checkbox]:checked').length;
                         });
 
                         $selectedDisks.map(function (disk) {
@@ -86,7 +86,7 @@
                             success: function(args) {
                                 var $listView = $('.list-view.instances');
 
-                                if ($listView.size()) {
+                                if ($listView.length) {
                                     var $loading = $('.list-view.instances').listView('prependItem', {
                                         data: [{
                                             name: data.displayname ? data.displayname : _l('label.new.vm'),
@@ -104,7 +104,7 @@
                                 listViewArgs.complete({
                                     _custom: args._custom,
                                     messageArgs: cloudStack.serializeForm($form),
-                                    $item: $listView.size() ? $loading : $('<div>')
+                                    $item: $listView.length ? $loading : $('<div>')
                                 });
 
                                 close();
@@ -158,17 +158,17 @@
 
                                             var $checkedOtherSelect = $otherSelects.filter(function() {
                                                 return $(this).not('.single-select') &&
-                                                    $(this).find('input[type=checkbox]:checked').size() &&
-                                                    $(this).find('input[type=radio]:checked').size();
+                                                    $(this).find('input[type=checkbox]:checked').length &&
+                                                    $(this).find('input[type=radio]:checked').length;
                                             });
 
-                                            if (!$checkedOtherSelect.size() &&
-                                                !$('.new-network:visible input[type=radio]:checked').size()) {
+                                            if (!$checkedOtherSelect.length &&
+                                                !$('.new-network:visible input[type=radio]:checked').length) {
                                                 $(this).closest('.select').find('input[type=radio]').click();
                                             }
                                         }
 
-                                        if ((!$otherSelects.size()) &&
+                                        if ((!$otherSelects.length) &&
                                             $newNetwork.find('input[type=checkbox]').is(':unchecked')) {
                                             // Set as default
                                             $(this).closest('.select').find('input[type=radio]').click();
@@ -268,10 +268,9 @@
 
                 var dataGenerators = {
                     setup: function($step, formData) {
-                        var originalValues = function(formData) {
-                            $step.find('select').val(
-                                formData.zoneid
-                            );
+                        var originalValues = function(formData, initialValue) {
+                            var selectedValue = formData.zoneid || initialValue;
+                            $step.find('select').val(selectedValue);
 
                             $step.find('input[type=radio]').filter(function() {
                                 return $(this).val() == formData['select-template'];
@@ -282,7 +281,11 @@
                             response: {
                                 success: function(args) {
                                     // Zones
-                                    $(args.data.zones).each(function() {
+                                    var initialValue = '';
+                                    $(args.data.zones).each(function( index ) {
+                                        if(index == 0){
+                                          initialValue = this.id;
+                                        }
                                         $step.find('.select-zone select').append(
                                             $('<option>')
                                             .attr({
@@ -293,7 +296,7 @@
                                         );
                                     });
 
-                                    originalValues(formData);
+                                    originalValues(formData, initialValue);
                                 }
                             }
                         };
@@ -309,7 +312,7 @@
                                 return $(this).val() == formData.templateid;
                             });
 
-                            if (!$selected.size()) {
+                            if (!$selected.length) {
                                 $inputs.filter(':first').click();
                             } else {
                                 $selected.click();
@@ -541,7 +544,7 @@
                                 return $(this).val() == formData.diskofferingid;
                             }).click();
 
-                            if (!$targetInput.size()) {
+                            if (!$targetInput.length) {
                                 $step.find('input[type=radio]:visible').filter(':first').click();
                             }
                         };
@@ -620,7 +623,7 @@
                                                 $group.toggleClass('selected');
                                                 $group.find('.select:first input[type=radio]').click();
 
-                                                if (!$multiDiskSelect.find('input[type=checkbox]:checked').size()) {
+                                                if (!$multiDiskSelect.find('input[type=checkbox]:checked').length) {
                                                     $step.find('.no-thanks input[type=radio]').click();
                                                 } else {
                                                     $step.find('.no-thanks input[type=radio]').attr('checked', false);
@@ -655,10 +658,10 @@
                                         var item = $.grep(args.data.diskOfferings, function(elem) {
                                             return elem.id == val;
                                         })[0];
-                                        var isMultiDisk = $step.find('.multi-disk-select').size();
+                                        var isMultiDisk = $step.find('.multi-disk-select').length;
 
                                         // Uncheck any multi-select groups
-                                        if ($target.closest('.no-thanks').size() && isMultiDisk) {
+                                        if ($target.closest('.no-thanks').length && isMultiDisk) {
                                             $step.find('.disk-select-group input[type=checkbox]:checked').click();
                                             $(this).attr('checked', true);
 
@@ -881,7 +884,7 @@
                             var $checkbox = $step.find('.new-network input[type=checkbox]');
                             var $newNetwork = $checkbox.closest('.new-network');
 
-                            if ($step.find('.select.my-networks .select-container .select:visible').size()) {
+                            if ($step.find('.select.my-networks .select-container .select:visible').length) {
                                 $checkbox.attr('checked', false);
                                 $newNetwork.addClass('unselected');
                             } else {
@@ -1023,7 +1026,7 @@
                                         );
 
                                         // Cleanup
-                                        if ($select.closest('.new-network').size()) {
+                                        if ($select.closest('.new-network').length) {
                                             $select.find('.advanced-options, .specify-ip').remove();
                                         }
 
@@ -1077,10 +1080,10 @@
                                 fieldName = $input.html();
                             } else if ($input.is('input[type=radio]')) {
                                 // Choosen New network as default
-                                if ($input.parents('div.new-network').size()) {
+                                if ($input.parents('div.new-network').length) {
                                     fieldName = $input.closest('div.new-network').find('input[name="new-network-name"]').val();
                                     // Choosen Network from existed
-                                } else if ($input.parents('div.my-networks').size()) {
+                                } else if ($input.parents('div.my-networks').length) {
                                     fieldName = $input.closest('div.select').find('.select-desc .name').html();
                                 } else {
                                     fieldName = $input.parent().find('.select-desc .name').html();
@@ -1124,7 +1127,7 @@
                     var targetIndex = index - 1;
 
                     if (index <= 1) targetIndex = 0;
-                    if (targetIndex == $steps.size()) {
+                    if (targetIndex == $steps.length) {
                         completeAction();
                         return;
                     }
@@ -1182,7 +1185,7 @@
                     }).fadeOut('slow');
 
                     setTimeout(function() {
-                        if (!$targetStep.find('input[type=radio]:checked').size()) {
+                        if (!$targetStep.find('input[type=radio]:checked').length) {
                             $targetStep.find('input[type=radio]:first').click();
                         }
                     }, 50);
@@ -1194,10 +1197,10 @@
                     var $activeStep = $form.find('.step:visible');
 
                     // Next button
-                    if ($target.closest('div.button.next').size()) {
+                    if ($target.closest('div.button.next').length) {
                         //step 2 - select template/ISO
                         if($activeStep.hasClass('select-iso')) {
-                            if ($activeStep.find('.content:visible input:checked').size() == 0) {
+                            if ($activeStep.find('.content:visible input:checked').length == 0) {
                                 cloudStack.dialog.notice({
                                     message: 'message.step.1.continue'
                                 });
@@ -1210,7 +1213,7 @@
                         }
 
                         //step 6 - select network
-                        if ($activeStep.find('.wizard-step-conditional.select-network:visible').size() > 0) {
+                        if ($activeStep.find('.wizard-step-conditional.select-network:visible').length > 0) {
                             var data = $activeStep.data('my-networks');
 
                             if (!data) {
@@ -1219,7 +1222,7 @@
                                 )['my-networks']);
                             }
 
-                            if ($activeStep.find('input[type=checkbox]:checked').size() == 0) { //if no checkbox is checked
+                            if ($activeStep.find('input[type=checkbox]:checked').length == 0) { //if no checkbox is checked
                                 cloudStack.dialog.notice({
                                     message: 'message.step.4.continue'
                                 });
@@ -1234,7 +1237,7 @@
                                 if (advSGFilter == 0) { //when total number of selected sg networks is 0, then 'Select Security Group' is skipped, go to step 6 directly
                                     showStep(6);
                                 } else { //when total number of selected sg networks > 0
-                                    if ($activeStep.find('input[type=checkbox]:checked').size() > 1) { //when total number of selected networks > 1
+                                    if ($activeStep.find('input[type=checkbox]:checked').length > 1) { //when total number of selected networks > 1
                                         cloudStack.dialog.notice({
                                             message: "Can't create a vm with multiple networks one of which is Security Group enabled"
                                         });
@@ -1246,7 +1249,7 @@
 
                         //step 6 - review (spcifiy displyname, group as well)
                         if ($activeStep.hasClass('review')) {
-                            if ($activeStep.find('input[name=displayname]').size() > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
+                            if ($activeStep.find('input[name=displayname]').length > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
                                 //validate
                                 var b = cloudStack.validate.vmHostName($activeStep.find('input[name=displayname]').val());
                                 if (b == false)
@@ -1255,7 +1258,7 @@
                         }
 
                         if (!$form.valid()) {
-                            if ($form.find('input.error:visible, select.error:visible').size()) {
+                            if ($form.find('input.error:visible, select.error:visible').length) {
                                 return false;
                             }
                         }
@@ -1270,7 +1273,7 @@
                     }
 
                     // Previous button
-                    if ($target.closest('div.button.previous').size()) {
+                    if ($target.closest('div.button.previous').length) {
                         var $step = $steps.filter(':visible');
                         var $networkStep = $steps.filter('.network');
                         var index = $step.index();
@@ -1278,10 +1281,10 @@
                         $networkStep.removeClass('next-use-security-groups');
 
                         if (index) {
-                            if (index == $steps.size() - 1 && $networkStep.hasClass('next-use-security-groups')) {
+                            if (index == $steps.length - 1 && $networkStep.hasClass('next-use-security-groups')) {
                                 showStep(5);
-                            } else if ($activeStep.find('.select-security-group:visible').size() &&
-                                $activeStep.find('.select-network.no-add-network').size()) {
+                            } else if ($activeStep.find('.select-security-group:visible').length &&
+                                $activeStep.find('.select-network.no-add-network').length) {
                                 showStep(5);
                             } else {
                                 showStep(index);
@@ -1292,14 +1295,14 @@
                     }
 
                     // Close button
-                    if ($target.closest('div.button.cancel').size()) {
+                    if ($target.closest('div.button.cancel').length) {
                         close();
 
                         return false;
                     }
 
                     // Edit link
-                    if ($target.closest('div.edit').size()) {
+                    if ($target.closest('div.edit').length) {
                         var $edit = $target.closest('div.edit');
 
                         showStep($edit.find('a').attr('href'));
@@ -1359,15 +1362,18 @@
                     $wizard.find('div.data-disk-offering span.custom-disk-size').html(_s(old));
                 });
 
-
-                return $wizard.dialog({
+                
+                var wizardDialog = $wizard.dialog({
                     title: _l('label.vm.add'),
                     width: 896,
                     height: 570,
-                    closeOnEscape: false,
-                    zIndex: 5000
-                })
-                    .closest('.ui-dialog').overlay();
+                    closeOnEscape: false
+                });
+                var wizardDialogDiv = wizardDialog.closest('.ui-dialog');
+                wizardDialogDiv.css('z-index', 5001);
+                
+                $('button.ui-dialog-titlebar-close').remove()
+                return wizardDialogDiv.overlay();
             };
 
             instanceWizard(args);
diff --git a/ui/scripts/ui-custom/migrate.js b/ui/scripts/ui-custom/migrate.js
index fa94070..40a6d41 100644
--- a/ui/scripts/ui-custom/migrate.js
+++ b/ui/scripts/ui-custom/migrate.js
@@ -100,6 +100,7 @@
 
                             $('div.overlay').fadeOut(function() {
                                 $('div.overlay').remove();
+                                $(':ui-dialog').dialog('destroy');
                             });
                         }
                         else {
@@ -121,7 +122,8 @@
                         });
                     }
                 }]
-            }).parent('.ui-dialog').overlay();
+            });
+            cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dataList);
         };
     };
 }(cloudStack, jQuery));
diff --git a/ui/scripts/ui-custom/physicalResources.js b/ui/scripts/ui-custom/physicalResources.js
index e815fc5..d0aaaf9 100644
--- a/ui/scripts/ui-custom/physicalResources.js
+++ b/ui/scripts/ui-custom/physicalResources.js
@@ -71,7 +71,7 @@
             return $dashboard
                 .click(function(event) {
                     var $target = $(event.target);
-                    if ($target.closest('[view-all-target]').size()) {
+                    if ($target.closest('[view-all-target]').length) {
                         var targetID = $target.closest('[view-all-target]').attr('view-all-target');
                         args.$browser.cloudBrowser('addPanel', {
                             title: $target.closest('[view-all-title]').attr('view-all-title'),
diff --git a/ui/scripts/ui-custom/pluginListing.js b/ui/scripts/ui-custom/pluginListing.js
index fce7daa..357d676 100644
--- a/ui/scripts/ui-custom/pluginListing.js
+++ b/ui/scripts/ui-custom/pluginListing.js
@@ -54,7 +54,7 @@
                 $plugin.click(function() {
                     var $mainSection = $('#navigation ul li').filter('.' + plugin.id);
 
-                    if ($mainSection.size()) {
+                    if ($mainSection.length) {
                         $mainSection.click();
 
                         return;
diff --git a/ui/scripts/ui-custom/projects.js b/ui/scripts/ui-custom/projects.js
index f6a2321..efffd2a 100644
--- a/ui/scripts/ui-custom/projects.js
+++ b/ui/scripts/ui-custom/projects.js
@@ -270,12 +270,12 @@
             $tabs.find('ul li:first').addClass('first');
             $tabs.find('ul li:last').addClass('last');
 
-            $tabs.bind('tabsshow', function(event, ui) {
-                var $panel = $(ui.panel);
+            $tabs.bind('tabsactivate', function(event, ui) {
+                var $panel = $(ui.newPanel);
                 var $management = $panel.find('.management');
                 var $managementInvite = $panel.find('.management-invite');
 
-                if ($management.size()) {
+                if ($management.length) {
                     $management.children().remove();
                     $management.append(pageElems.userManagement({
                         context: cloudStack.context
@@ -284,7 +284,7 @@
                     return true;
                 }
 
-                if ($managementInvite.size()) {
+                if ($managementInvite.length) {
                     $managementInvite.children().remove();
                     $managementInvite.append(pageElems.userManagement({
                         context: cloudStack.context,
@@ -635,7 +635,7 @@
 
             // Initial load
             loadData(function() {
-                if (!$list.find('li').size()) {
+                if (!$list.find('li').length) {
                     cloudStack.dialog.notice({
                         message: isAdmin() || isDomainAdmin() || g_userProjectsEnabled ? _l('message.no.projects') : _l('message.no.projects.adminOnly')
                     }).closest('.ui-dialog');
@@ -705,11 +705,12 @@
      * Initiate new project flow
      */
     var addProject = function() {
-        pageElems.newProjectForm().dialog({
+        var $dialog = pageElems.newProjectForm().dialog({
             title: _l('label.new.project'),
             closeOnEscape: false,
             width: 760
-        }).closest('.ui-dialog').overlay();
+        });
+        cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
     };
 
     var deleteProject = function(args) {
diff --git a/ui/scripts/ui-custom/recurringSnapshots.js b/ui/scripts/ui-custom/recurringSnapshots.js
index c32aa99..6d0eefd 100644
--- a/ui/scripts/ui-custom/recurringSnapshots.js
+++ b/ui/scripts/ui-custom/recurringSnapshots.js
@@ -117,7 +117,7 @@
                         return $(this).index() == index;
                     });
 
-                    if ($tr.size() && $tr.hasClass('active')) {
+                    if ($tr.length && $tr.hasClass('active')) {
                         $(this).addClass('disabled ui-state-disabled');
                     } else {
                         $(this).removeClass('disabled ui-state-disabled');
@@ -126,7 +126,7 @@
                     if ($(this).is('.ui-tabs-selected.ui-state-disabled')) {
                         $snapshots.find('form').show();
 
-                        if ($snapshots.find('li.ui-state-disabled').size() == $snapshots.find('li').size()) {
+                        if ($snapshots.find('li.ui-state-disabled').length == $snapshots.find('li').length) {
                             $snapshots.find('form').hide();
                         } else {
                             $snapshots.find('li:not(.ui-state-disabled):first a').click();
@@ -207,9 +207,9 @@
                         });
                     }
                 }]
-            }).closest('.ui-dialog').overlay();
+            });
 
-            return $dialog;
+            return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
         };
     };
 }(cloudStack, jQuery));
diff --git a/ui/scripts/ui-custom/regions.js b/ui/scripts/ui-custom/regions.js
index b075940..e950c12 100644
--- a/ui/scripts/ui-custom/regions.js
+++ b/ui/scripts/ui-custom/regions.js
@@ -96,7 +96,7 @@
             var $li = $target.closest('li');
             var region, url;
 
-            if ($li.size() && !$li.hasClass('active')) {
+            if ($li.length && !$li.hasClass('active')) {
                 region = $li.data('region-data');
                 url = region.endpoint;
                 id = region.id;
diff --git a/ui/scripts/ui-custom/uploadVolume.js b/ui/scripts/ui-custom/uploadVolume.js
index 432bfe4..2283de1 100644
--- a/ui/scripts/ui-custom/uploadVolume.js
+++ b/ui/scripts/ui-custom/uploadVolume.js
@@ -30,7 +30,7 @@
 
             if (!$uploadVolume.find(
                 'input[type=radio]:checked, input[type=checkbox]:checked'
-            ).size()) {
+            ).length) {
                 cloudStack.dialog.notice({
                     message: _l('message.select.instance')
                 });
diff --git a/ui/scripts/ui-custom/vpc.js b/ui/scripts/ui-custom/vpc.js
index 69a40c9..5444874 100644
--- a/ui/scripts/ui-custom/vpc.js
+++ b/ui/scripts/ui-custom/vpc.js
@@ -409,7 +409,7 @@
 
             // Title shows tier details
             $title.click(function() {
-                if ($browser && $browser.size()) { // Fix null exception, if add tier returns error
+                if ($browser && $browser.length) { // Fix null exception, if add tier returns error
                     $browser.cloudBrowser('addPanel', {
                         title: name,
                         maximizeIfSelected: true,
@@ -545,7 +545,7 @@
             );
 
             var showAddTierDialog = function() {
-                if ($(this).find('.loading-overlay').size()) {
+                if ($(this).find('.loading-overlay').length) {
                     return false;
                 }
 
diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js
index 7906478..5d38d27 100644
--- a/ui/scripts/ui-custom/zoneWizard.js
+++ b/ui/scripts/ui-custom/zoneWizard.js
@@ -22,7 +22,7 @@
         if (!options) options = {};
 
         var $forms = $wizard.find('form').filter(function() {
-            return !options.all ? !$(this).closest('.multi-edit').size() : true;
+            return !options.all ? !$(this).closest('.multi-edit').length : true;
         });
         var $physicalNetworkItems = $wizard.find(
             '.steps .setup-physical-network .select-container.multi'
@@ -33,7 +33,7 @@
             '.steps .setup-storage-traffic .data-body .data-item');
         var groupedForms = {};
 
-        if ($physicalNetworkItems.find('li.traffic-type-draggable.storage').size()) {
+        if ($physicalNetworkItems.find('li.traffic-type-draggable.storage').length) {
             $wizard.find('li.conditional.storage-traffic').show();
         } else {
             $wizard.find('li.conditional.storage-traffic').hide();
@@ -93,7 +93,7 @@
                     // Traffic type configuration data
                     trafficTypeConfiguration: trafficTypeConfiguration,
 
-                    guestConfiguration: $guestForm.size() ? cloudStack.serializeForm($guestForm) : null
+                    guestConfiguration: $guestForm.length ? cloudStack.serializeForm($guestForm) : null
                 };
             }
         );
@@ -172,7 +172,7 @@
      */
     var customValidation = {
         networkRanges: function($form) {
-            if ($form.closest('.multi-edit').find('.data-item').size()) {
+            if ($form.closest('.multi-edit').find('.data-item').length) {
                 return true;
             }
 
@@ -184,7 +184,7 @@
 
         physicalNetworks: function($form) {
             var $enabledPhysicalNetworks = $form.filter(':not(.disabled)').filter(function() {
-                return $(this).find('.traffic-type-draggable').size();
+                return $(this).find('.traffic-type-draggable').length;
             });
             var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
             var $configuredTrafficTypes = $trafficTypes.filter(function() {
@@ -193,8 +193,8 @@
                 return ($trafficType.data('traffic-type-data') != null);
             });
 
-            if ($enabledPhysicalNetworks.size() > 1 &&
-                $configuredTrafficTypes.size() != $trafficTypes.size()) {
+            if ($enabledPhysicalNetworks.length > 1 &&
+                $configuredTrafficTypes.length != $trafficTypes.length) {
                 cloudStack.dialog.notice({
                     message: _l('message.configure.all.traffic.types')
                 });
@@ -215,9 +215,9 @@
         var $physicalNetworks = $step.find('.select-container.multi');
         var isCustomValidated;
 
-        if ($multiEditForm.size()) {
+        if ($multiEditForm.length) {
             isCustomValidated = customValidation.networkRanges($multiEditForm);
-        } else if ($physicalNetworks.size()) {
+        } else if ($physicalNetworks.length) {
             isCustomValidated = customValidation.physicalNetworks($physicalNetworks);
         } else {
             isCustomValidated = true;
@@ -240,7 +240,7 @@
             var $existingPhysicalNetworks = physicalNetwork.getNetworks($wizard);
 
             // Initialize physical networks
-            if (!$existingPhysicalNetworks.size()) {
+            if (!$existingPhysicalNetworks.length) {
                 physicalNetwork.add($wizard);
             } else if (!isAdvancedNetwork($wizard)) {
                 $existingPhysicalNetworks.filter(':first').siblings().each(function() {
@@ -459,12 +459,12 @@
                 return $(this).attr('traffic-type-id') == trafficTypeID;
             });
 
-            if (physicalNetwork.isTrafficTypeClone($trafficType) && !$container.closest('.select-container.multi').size()) {
+            if (physicalNetwork.isTrafficTypeClone($trafficType) && !$container.closest('.select-container.multi').length) {
                 // Get traffic type from original container
                 return $trafficType.filter(function() {
                     return $(this).closest(
                         physicalNetwork.getOriginalTrafficContainer($trafficType)
-                    ).size();
+                    ).length;
                 });
             }
 
@@ -516,10 +516,10 @@
             var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
             var $dropArea = $physicalNetwork.find('.drop-container ul');
 
-            if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size()) return false;
+            if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length) return false;
 
             if (physicalNetwork.isTrafficTypeClone($trafficType)) {
-                if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).size()) {
+                if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).length) {
                     $trafficType = $trafficType.clone()
                         .removeClass('disabled')
                         .appendTo($dropArea)
@@ -563,7 +563,7 @@
                 );
 
                 if (physicalNetwork.isTrafficTypeClone($trafficType) &&
-                    $physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size() > 1) {
+                    $physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length > 1) {
                     $trafficType.remove();
                 }
             }
@@ -580,10 +580,10 @@
                 return false;
 
             var $emptyContainers = $containers.filter(function() {
-                return !$(this).find('li').size();
+                return !$(this).find('li').length;
             });
 
-            return !$emptyContainers.size() ? $containers.size() : false;
+            return !$emptyContainers.length ? $containers.length : false;
         },
 
         /**
@@ -598,7 +598,7 @@
             $allPhysicalNetworks.each(function() {
                 var $ul = $(this).find('.drop-container ul');
 
-                if (!$(this).find('li').size()) {
+                if (!$(this).find('li').length) {
                     $(this).addClass('disabled');
                     $ul.fadeOut();
                 } else {
@@ -609,8 +609,8 @@
 
             $containers.each(function() {
                 var $currentContainer = $(this);
-                if (!$currentContainer.find('li').size() &&
-                    $containers.size() > containerTotal) {
+                if (!$currentContainer.find('li').length &&
+                    $containers.length > containerTotal) {
                     $currentContainer.remove();
                 }
             });
@@ -753,7 +753,7 @@
 
                     $ul.addClass('active');
 
-                    if (!$ul.find('li').size()) {
+                    if (!$ul.find('li').length) {
                         $(this).closest('.select-container.multi').removeClass('disabled');
                         $ul.fadeIn();
                     }
@@ -772,7 +772,7 @@
                     var trafficTypeData = ui.draggable.data('traffic-type-data');
 
                     if (trafficTypeID == 'guest' &&
-                        ui.draggable.closest('.select-container.multi').size()) {
+                        ui.draggable.closest('.select-container.multi').length) {
                         ui.draggable.remove();
                     }
 
@@ -880,7 +880,7 @@
 
             // Only use networks w/ guest traffic type
             $physicalNetworks = $physicalNetworks.filter(function() {
-                return $(this).find('li.guest').size();
+                return $(this).find('li.guest').length;
 
                 return true;
             });
@@ -1101,7 +1101,7 @@
                 var targetIndex = index - 1;
 
                 if (index <= 1) targetIndex = 0;
-                if (targetIndex == $steps.size()) {
+                if (targetIndex == $steps.length) {
                     completeAction();
                 }
 
@@ -1130,7 +1130,7 @@
                 }
 
                 if (formID) {
-                    if (!$targetStep.find('form').size()) {
+                    if (!$targetStep.find('form').length) {
                         makeForm(args, formID, formState).appendTo($targetStep.find('.content.input-area .select-container'));
 
                         setTimeout(function() {
@@ -1185,7 +1185,7 @@
                         }
                 }
 
-                if ($uiCustom.size()) {
+                if ($uiCustom.length) {
                     $uiCustom.each(function() {
                         var $item = $(this);
                         var id = $item.attr('ui-custom');
@@ -1210,7 +1210,7 @@
                 $nextButton.removeClass('final post-launch');
 
                 // Show launch button if last step
-                if ($targetStep.index() == $steps.size() - 1 || options.nextStep) {
+                if ($targetStep.index() == $steps.length - 1 || options.nextStep) {
                     $nextButton.find('span').html(options.nextStep ? _l('label.save.changes') : _l('label.launch.zone'));
                     $nextButton.addClass('final');
 
@@ -1225,7 +1225,7 @@
                 }).toggleClass('active');
 
                 setTimeout(function() {
-                    if (!$targetStep.find('input[type=radio]:checked').size()) {
+                    if (!$targetStep.find('input[type=radio]:checked').length) {
                         $targetStep.find('input[type=radio]:first').click();
                     }
                 }, 50);
@@ -1329,25 +1329,25 @@
                 }
 
                 // Next button
-                if ($target.closest('div.button.next').size()) {
+                if ($target.closest('div.button.next').length) {
                     var $step = $steps.filter(':visible');
                     // Validation
                     var $form = $('form:visible').filter(function() {
                         // Don't include multi-edit (validation happens separately)
-                        return !$(this).closest('.multi-edit').size();
+                        return !$(this).closest('.multi-edit').length;
                     });
 
                     // Handle validation for custom UI components
                     var isCustomValidated = checkCustomValidation($step);
-                    if (($form.size() && !$form.valid()) || !isCustomValidated) {
-                        if (($form && $form.find('.error:visible').size()) || !isCustomValidated)
+                    if (($form.length && !$form.valid()) || !isCustomValidated) {
+                        if (($form && $form.find('.error:visible').length) || !isCustomValidated)
                             return false;
                     }
 
                     //when hypervisor is BareMetal (begin)
                     var data = getData($wizard);
                     if (('zone' in data) && (data.zone.hypervisor == 'BareMetal')) {
-                        if ($('.zone-wizard:visible').find('#add_zone_guest_traffic_desc:visible').size() > 0) { //$steps.filter(':visible').index() == 6
+                        if ($('.zone-wizard:visible').find('#add_zone_guest_traffic_desc:visible').length > 0) { //$steps.filter(':visible').index() == 6
                             showStep('launch');
                             completeAction();
                             return false;
@@ -1355,10 +1355,10 @@
                     }
                     //when hypervisor is BareMetal (end)
 
-                    if (!$target.closest('.button.next.final').size())
+                    if (!$target.closest('.button.next.final').length)
                         showStep($steps.filter(':visible').index() + 2);
                     else {
-                        if ($target.closest('.button.next.final.post-launch').size()) {
+                        if ($target.closest('.button.next.final.post-launch').length) {
                             showStep('launch');
                         }
 
@@ -1369,21 +1369,21 @@
                 }
 
                 // Previous button
-                if ($target.closest('div.button.previous').size()) {
+                if ($target.closest('div.button.previous').length) {
                     showStep($steps.filter(':visible').index(), true);
 
                     return false;
                 }
 
                 // Close button
-                if ($target.closest('div.button.cancel').size()) {
+                if ($target.closest('div.button.cancel').length) {
                     close();
 
                     return false;
                 }
 
                 // Edit link
-                if ($target.closest('div.edit').size()) {
+                if ($target.closest('div.edit').length) {
                     var $edit = $target.closest('div.edit');
 
                     showStep($edit.find('a').attr('href'));
@@ -1395,7 +1395,7 @@
                 var $editTrafficTypeButton = $target.closest('.drop-container .traffic-type-draggable .edit-traffic-type');
                 var $trafficType = $editTrafficTypeButton.closest('.traffic-type-draggable');
 
-                if ($editTrafficTypeButton.size()) {
+                if ($editTrafficTypeButton.length) {
                     physicalNetwork.editTrafficTypeDialog($trafficType);
 
                     return false;
@@ -1423,14 +1423,15 @@
 
             showStep(1);
 
-            return $wizard.dialog({
+            var $dialog = $wizard.dialog({
                 title: _l('label.installWizard.addZone.title'),
                 closeOnEscape: false,
                 width: 750,
                 height: 665,
-                zIndex: 5000,
                 resizable: false
-            }).closest('.ui-dialog').overlay();
+            });
+            
+            return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
         };
     };
 })(jQuery, cloudStack);
diff --git a/ui/scripts/ui/core.js b/ui/scripts/ui/core.js
index 0c481d0..3f8bb44 100644
--- a/ui/scripts/ui/core.js
+++ b/ui/scripts/ui/core.js
@@ -181,7 +181,7 @@
                         }).join(',')
                     );
 
-                    if ($target.closest('.select.project-view').size()) {
+                    if ($target.closest('.select.project-view').length) {
                         $('#cloudStack3-container').addClass('project-view');
                         $projectSwitcher.addClass('alt');
                         $projectSwitcher.find('.select.project-view').addClass('active')
@@ -329,7 +329,8 @@
                     var $logo = $('<div>').addClass('logo').text(_l('label.app.name')),
                         $version = $('<div>').addClass('version').text(g_cloudstackversion),
                         $about = $('<div>').addClass('about').append($logo).append($version);
-                    $about.dialog({
+                    
+                    var $aboutDialog = $about.dialog({
                         modal: true,
                         width: 300,
                         title: _l('label.about.app'),
@@ -341,8 +342,8 @@
                                 $(':ui-dialog, .overlay').remove();
                             }
                         }
-                    }).closest('.ui-dialog').overlay();
-
+                    });
+                    cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($aboutDialog);
                     return false;
                 });
             }
@@ -403,9 +404,9 @@
         function checkHoveredLabel($target) {
             var $multiWizard = $('div.ui-dialog div.multi-wizard');
             if (($target.is('label[for]') && !$target.parents('body.login')) ||
-                ($multiWizard.size() &&
-                    ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) ||
-                    ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size())
+                ($multiWizard.length &&
+                    ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').length) ||
+                    ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').length)
                 ))
                 return true;
 
@@ -418,7 +419,7 @@
             if (checkHoveredLabel($target)) {
                 $target.addClass('label-hovered');
             }
-            if ($target.closest('#user, #user-options').size()) {
+            if ($target.closest('#user, #user-options').length) {
                 return false;
             } else $('#user-options').hide();
 
@@ -440,19 +441,19 @@
             var $multiWizard = $('div.ui-dialog div.multi-wizard');
 
             // Wizard: trigger click event for input when click it label
-            if ($multiWizard.size()) {
-                if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) {
+            if ($multiWizard.length) {
+                if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').length) {
                     $target.prev('input').trigger('click');
                 }
-                if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size()) {
+                if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').length) {
                     $target.parent('div.select-desc').prev('input').trigger('click');
                 }
             }
 
-            if (!$container.size()) return true;
+            if (!$container.length) return true;
 
             // Navigation items
-            if ($target.closest('li.navigation-item').size() && $target.closest('#navigation').size()) {
+            if ($target.closest('li.navigation-item').length && $target.closest('#navigation').length) {
                 var $navItem = $target.closest('li.navigation-item');
 
                 if ($navItem.is('.disabled')) return false;
@@ -462,7 +463,7 @@
             }
 
             // Browser expand
-            if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').size()) {
+            if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').length) {
                 $browser.cloudBrowser('toggleMaximizePanel', {
                     panel: $target.closest('div.panel')
                 });
@@ -477,7 +478,7 @@
             }
 
             // User options
-            if ($target.closest('#user div.icon.options').size()) {
+            if ($target.closest('#user div.icon.options').length) {
                 $('#user-options').toggle();
 
                 return false;
diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js
index c518859..cce70e7 100644
--- a/ui/scripts/ui/dialog.js
+++ b/ui/scripts/ui/dialog.js
@@ -78,7 +78,7 @@
             var ret = function() {
                 $('.overlay').remove();
 
-                return $formContainer.dialog({
+                var $dialog = $formContainer.dialog({
                     dialogClass: args.form.isWarning ? 'create-form warning' : 'create-form',
                     closeOnEscape: false,
                     draggable: false,
@@ -117,10 +117,11 @@
                         text: _l('label.cancel'),
                         'class': 'cancel',
                         click: function() {
+                            $(this).dialog('destroy');
+
                             $('div.overlay').remove();
                             $('.tooltip-box').remove();
                             $formContainer.remove();
-                            $(this).dialog('destroy');
 
                             $('.hovered-elem').hide();
 
@@ -129,7 +130,9 @@
                             }
                         }
                     }]
-                }).closest('.ui-dialog').overlay();
+                });
+                
+                return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
             };
 
             var isLastAsync = function(idx) {
@@ -379,7 +382,7 @@
 
                                 // Make sure all data is loaded to pass to select fn
                                 dependsOnLoaded = $.inArray(
-                                    true, $dependsOn.map(function(index, item) { return $(item).find('option').size() ? true : false; })
+                                    true, $dependsOn.map(function(index, item) { return $(item).find('option').length ? true : false; })
                                 ) > -1;
 
                                 if (!dependsOnLoaded) {
@@ -430,6 +433,68 @@
                             );
                         });
 
+                    } else if (field.multiDataArray) {
+
+                        $input = $('<div>');
+
+                        multiArgs = {
+                            context: args.context,
+                            response: {
+                                success: function(args) {
+                                    if (args.data == undefined || args.data.length == 0) {
+
+                                        var label = field.emptyMessage != null ? field.emptyMessage : 'No data available';
+
+                                        $input
+                                            .addClass('value')
+                                            .appendTo($value)
+                                            .append(
+                                                $('<label>').html(_l(label))
+                                            );
+
+                                    } else {
+
+                                        $input.addClass('multi-array').addClass(key).appendTo($value);
+
+                                        $(args.data).each(function() {
+
+                                            var id;
+                                            if (field.valueField)
+                                                id = this[field.valueField];
+                                             else
+                                                id = this.id !== undefined ? this.id : this.name;
+
+                                            var desc;
+                                            if (args.descriptionField)
+                                                desc = this[args.descriptionField];
+                                            else
+                                                desc = _l(this.description);
+
+                                            $input.append(
+                                                $('<div>')
+                                                    .addClass('item')
+                                                    .append(
+                                                        $.merge(
+                                                            $('<div>').addClass('name').html(_l(desc)),
+                                                            $('<div>').addClass('value').append(
+                                                                $('<input>').attr({
+                                                                    name: id,
+                                                                    type: 'checkbox'
+                                                                })
+                                                                .data('json-obj', this)
+                                                                .appendTo($value)
+                                                            )
+                                                        )
+                                                    )
+                                            );
+                                        });
+                                    }
+                                }
+                            }
+                        }
+
+                        multiFn = field.multiData;
+                        multiFn(multiArgs);
                     } else {
                         $input = $('<input>').attr({
                             name: key,
@@ -711,7 +776,7 @@
 
                 if (!$formContainer.find('form').valid()) {
                     // Ignore hidden field validation
-                    if ($formContainer.find('input.error:visible, select.error:visible').size()) {
+                    if ($formContainer.find('input.error:visible, select.error:visible').length) {
                         return false;
                     }
                 }
@@ -905,7 +970,7 @@
                     click: function() {
                         if (!$listView.find(
                             'input[type=radio]:checked, input[type=checkbox]:checked'
-                        ).size()) {
+                        ).length) {
                             cloudStack.dialog.notice({
                                 message: _l('message.select.instance')
                             });
@@ -985,7 +1050,7 @@
          * Confirmation dialog
          */
         confirm: function(args) {
-            return $(
+            var $dialog = $(
                 $('<span>').addClass('message').html(
                     _l(args.message)
                 )
@@ -993,7 +1058,6 @@
                 title: args.isWarning ? _l('label.warning') : _l('label.confirmation'),
                 dialogClass: args.isWarning ? 'confirm warning': 'confirm',
                 closeOnEscape: false,
-                zIndex: 5000,
                 buttons: [{
                     text: _l('label.no'),
                     'class': 'cancel',
@@ -1015,7 +1079,9 @@
                         $('.hovered-elem').hide();
                     }
                 }]
-            }).closest('.ui-dialog').overlay();
+            });
+            
+            return  cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
         },
 
         /**
@@ -1023,7 +1089,7 @@
          */
         notice: function(args) {
             if (args.message) {
-                return $(
+                var $dialog = $(
                     $('<span>').addClass('message').html(
                         _l(args.message)
                     )
@@ -1031,7 +1097,6 @@
                     title: _l('label.status'),
                     dialogClass: 'notice',
                     closeOnEscape: false,
-                    zIndex: 5000,
                     buttons: [{
                         text: _l('label.close'),
                         'class': 'close',
@@ -1039,11 +1104,13 @@
                             $(this).dialog('destroy');
                             if (args.clickAction) args.clickAction();
                             $('.hovered-elem').hide();
+                            $('div.overlay').hide();
                         }
                     }]
                 });
+                             
+                return cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog, 5001);
             }
-
             return false;
         }
     };
diff --git a/ui/scripts/ui/events.js b/ui/scripts/ui/events.js
index a7eff84..ffb0baa 100644
--- a/ui/scripts/ui/events.js
+++ b/ui/scripts/ui/events.js
@@ -41,7 +41,7 @@
                 var data, elem;
 
                 $elem = $target.closest('.cloudStack-elem.' + widget);
-                if (!$elem.size())
+                if (!$elem.length)
                     return true;
 
                 $widget = $('.cloudStack-widget.' + widget);
diff --git a/ui/scripts/ui/utils.js b/ui/scripts/ui/utils.js
index 524aed6..ec2ecda 100644
--- a/ui/scripts/ui/utils.js
+++ b/ui/scripts/ui/utils.js
@@ -145,4 +145,18 @@
             min: $.validator.format(_l('messgae.validate.min'))
         });
     };
+    
+    var applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton = function($dialog, customZindex){
+        var defaultZindex = 5000;
+        if(!customZindex){
+            customZindex = defaultZindex;
+        }
+        $('button.ui-dialog-titlebar-close').remove()
+        
+        var $dialogDiv = $dialog.closest('.ui-dialog');
+        $dialogDiv.css('z-index', customZindex);
+        
+        return $dialogDiv.overlay();
+    };
+    cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton = applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton;
 })(jQuery, cloudStack);
diff --git a/ui/scripts/ui/widgets/cloudBrowser.js b/ui/scripts/ui/widgets/cloudBrowser.js
index b7a5c38..dc38450 100644
--- a/ui/scripts/ui/widgets/cloudBrowser.js
+++ b/ui/scripts/ui/widgets/cloudBrowser.js
@@ -95,7 +95,7 @@
          */
         width: function($container, options) {
             options = options ? options : {};
-            var width = $container.find('div.panel').size() < 1 || !options.partial ?
+            var width = $container.find('div.panel').length < 1 || !options.partial ?
                 $container.width() : $container.width() - $container.width() / 4;
 
             return width;
@@ -105,7 +105,7 @@
          * Get left position
          */
         position: function($container, options) {
-            return $container.find('div.panel').size() <= 1 || !options.partial ?
+            return $container.find('div.panel').length <= 1 || !options.partial ?
                 0 : _panel.width($container, options) - _panel.width($container, options) / 1.5;
         },
 
@@ -340,7 +340,7 @@
         }
     });
 
-    $('#breadcrumbs li').live('click', cloudStack.ui.event.bind(
+    $(document).on('click', '#breadcrumbs li', cloudStack.ui.event.bind(
         'cloudBrowser', {
             'breadcrumb': function($target, $browser, data) {
 
diff --git a/ui/scripts/ui/widgets/dataTable.js b/ui/scripts/ui/widgets/dataTable.js
index 216487f..e59b6e9 100644
--- a/ui/scripts/ui/widgets/dataTable.js
+++ b/ui/scripts/ui/widgets/dataTable.js
@@ -228,9 +228,9 @@
                 $tbody.width($thead.width());
             }
 
-            if ($ths.size() > $tds.size()) {
+            if ($ths.length > $tds.length) {
                 $ths.width(
-                    $table.width() / $ths.size()
+                    $table.width() / $ths.length
                 );
                 return false;
             }
@@ -281,7 +281,7 @@
 
         var init = function() {
             var noSelect = options && options.noSelect == true ? true : false;
-            if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
+            if (!$table.closest('div.data-table').length && !$table.hasClass('no-split')) {
                 reattachTable();
                 $table.find('tbody').closest('table').addClass('body');
             }
@@ -304,7 +304,7 @@
             $table.bind('click', function(event) {
                 var $tr = $(event.target).closest('tr');
 
-                if (!$tr.size() || noSelect) return true;
+                if (!$tr.length || noSelect) return true;
                 var rowIndex = $tr.index();
 
                 toggleSelectRow(rowIndex);
diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js
index 2ce72a2..cca7063 100644
--- a/ui/scripts/ui/widgets/detailView.js
+++ b/ui/scripts/ui/widgets/detailView.js
@@ -23,7 +23,7 @@
 
         var $listView = $row.closest('.list-view');
 
-        if (!$listView.parents('html').size()) return;
+        if (!$listView.parents('html').length) return;
 
         var $newRow;
         var jsonObj = $row.data('json-obj');
@@ -56,6 +56,15 @@
         }
     };
 
+    var tabEvents = {
+        create: function(event, ui) {
+          manageTabsContent(event, ui);
+        },
+        activate: function(event, ui) {
+          manageTabsContent(event, ui);
+        }
+    };
+
     /**
      * Available UI actions to perform for buttons
      */
@@ -114,7 +123,7 @@
                     }
                 ).appendTo($detailView);
 
-                $detailView.tabs();
+                $detailView.tabs(tabEvents);
             };
 
             var performAction = function(data, options) {
@@ -172,7 +181,7 @@
                                         viewArgs.onActionComplete();
                                     }
 
-                                    if (!$detailView.parents('html').size()) {
+                                    if (!$detailView.parents('html').length) {
                                         replaceListViewItem(null, args.data, {
                                             $row: $row
                                         });
@@ -222,7 +231,7 @@
                                 cloudStack.ui.notifications.add(
                                     notification,
                                     function(args2) { //name parameter as "args2" instead of "args" to avoid override "args" from success: function(args) {
-                                        if ($detailView.parents('html').size()) {
+                                        if ($detailView.parents('html').length) {
                                             $loading.remove();
 
                                             if (!noRefresh && !viewArgs.compact) {
@@ -376,7 +385,7 @@
                             var $tbody = $row.closest('tbody');
 
                             $row.remove();
-                            if (!$tbody.find('tr').size()) {
+                            if (!$tbody.find('tr').length) {
                                 $("<tr>").addClass('empty').append(
                                     $("<td>").html(_l('label.no.data'))
                                 ).appendTo($tbody);
@@ -413,7 +422,7 @@
                                 var $tbody = $row.closest('tbody');
 
                                 $row.remove();
-                                if (!$tbody.find('tr').size()) {
+                                if (!$tbody.find('tr').length) {
                                     $("<tr>").addClass('empty').append(
                                         $("<td>").html(_l('label.no.data'))
                                     ).appendTo($tbody);
@@ -439,11 +448,11 @@
             $detailView.addClass('edit-mode');
             var token_value = "";
 
-            if ($detailView.find('.button.done').size()) return false;
+            if ($detailView.find('.button.done').length) return false;
 
             // Convert value TDs
             var $inputs = $detailView.find('input, select, textarea').filter(function() {
-                return !$(this).closest('.tagger').size() && !$(this).attr('type') == 'submit';
+                return !$(this).closest('.tagger').length && !$(this).attr('type') == 'submit';
             });
             var action = args.actions[args.actionName];
             var id = $detailView.data('view-args').id;
@@ -476,7 +485,7 @@
                 var $token;
                 var tags_value = "";
                 $inputs.each(function() {
-                    if ($(this).closest('.tagger').size()) return true;
+                    if ($(this).closest('.tagger').length) return true;
 
                     var $input = $(this);
                     var $value = $input.closest('td.value span');
@@ -525,9 +534,9 @@
 
                 // Remove Edit form
                 var $form = $detailView.find('form').filter(function() {
-                    return !$(this).closest('.tagger').size();
+                    return !$(this).closest('.tagger').length;
                 });
-                if ($form.size()) {
+                if ($form.length) {
                     var $mainGroups = $form.find('div.main-groups').detach();
                     $form.parent('div').append($mainGroups);
                     $form.remove();
@@ -539,7 +548,7 @@
             // Put in original values
             var cancelEdits = function($inputs, $editButton) {
                 $inputs.each(function() {
-                    if ($(this).closest('.tagger').size()) return true;
+                    if ($(this).closest('.tagger').length) return true;
 
                     var $input = $(this);
                     var $value = $input.closest('td.value span');
@@ -561,7 +570,7 @@
             };
 
             var applyEdits = function($inputs, $editButton) {
-                if ($inputs.size()) {
+                if ($inputs.length) {
                     $inputs.animate({
                         opacity: 0.5
                     }, 500);
@@ -606,7 +615,7 @@
                                 } else {
                                     $loading.appendTo($detailView);
                                     cloudStack.ui.notifications.add(
-                                        $.extend(true, {}, action.notification, notificationArgs),
+                                        $.extend(true, {}, notificationArgs, action.notification),
                                         function(args) {
                                             replaceListViewItem($detailView, data);
 
@@ -634,16 +643,16 @@
 
             $editButton.click(function() {
                 var $inputs = $detailView.find('input, select, textarea').filter(function() {
-                    return !$(this).closest('.tagger').size();
+                    return !$(this).closest('.tagger').length;
                 });
                 var $form = $detailView.find('form').filter(function() {
-                    return !$(this).closest('.tagger').size();
+                    return !$(this).closest('.tagger').length;
                 });
 
                 if ($(this).hasClass('done')) {
                     if (!$form.valid()) {
                         // Ignore hidden field validation
-                        if ($form.find('input.error:visible, select.error:visible').size()) {
+                        if ($form.find('input.error:visible, select.error:visible').length) {
                             return false;
                         }
                     }
@@ -796,7 +805,7 @@
                 return true;
             });
 
-            if ($detailView.find('td.value span:data(detail-view-is-editable)').size()) {
+            if ($detailView.find('td.value span:data(detail-view-is-editable)').length) {
                 var $detailsEdit = $detailView.find('div.main-groups').detach(),
                     $detailsEditForm = $('<form>').append($detailsEdit);
 
@@ -805,7 +814,7 @@
 
             // Setup form validation
             var $form = $detailView.find('form').filter(function() {
-                return !$(this).closest('.tagger').size();
+                return !$(this).closest('.tagger').length;
             });
             $form.validate();
             $form.find('input, select').each(function() {
@@ -976,7 +985,7 @@
             });
 
             var $actionButtons = $actions.find('div.action:not(.text)');
-            if ($actionButtons.size() == 1)
+            if ($actionButtons.length == 1)
                 $actionButtons.addClass('single');
             else {
                 $actionButtons.filter(':first').addClass('first');
@@ -1180,7 +1189,7 @@
                     context: context
                 }) : true
             ) : true;
-            if ($actions && ($actions.find('div.action').size() || (detailViewArgs.viewAll && showViewAll))) {
+            if ($actions && ($actions.find('div.action').length || (detailViewArgs.viewAll && showViewAll))) {
                 $actions.prependTo($firstRow.closest('div.detail-group').closest('.details'));
             }
             if (detailViewArgs.viewAll && showViewAll) {
@@ -1559,35 +1568,44 @@
             }
         }
 
-        $detailView.tabs({
-            select: function() {
+        $detailView.tabs(
+            $.extend(true, {}, tabEvents, {
+              select: function() {
                 // Cleanup old tab content
                 $detailView.find('.detail-group').children().remove();
-            }
-        });
+              }}
+            )
+        );
 
         return $detailView;
     };
 
-    // Setup tab events
-    $(document).bind('tabsshow', function(event, ui) {
+    var manageTabsContent = function(event, ui){
         var $target = $(event.target);
 
         if (!$target.hasClass('detail-view') || $target.hasClass('detail-view ui-state-active')) return true;
 
-        var $targetDetailGroup = $(ui.panel);
+        var $targetDetailGroup = undefined;
+        if(ui.panel){
+            $targetDetailGroup = $(ui.panel);
+        }else{
+            $targetDetailGroup = $(ui.newPanel);
+        }
+        if(!$targetDetailGroup){
+            throw 'Could not find a panel to load tab\'s data';
+        }
         loadTabContent($targetDetailGroup, $target.data('view-args'));
 
         return true;
-    });
+    };
 
     // View all links
-    $('a').live('click', function(event) {
+    $(document).on('click', 'a', function(event) {
         var $target = $(event.target);
         var $viewAll = $target.closest('td.view-all a');
         var viewAllArgs;
 
-        if ($target.closest('div.detail-view').size() && $target.closest('td.view-all a').size()) {
+        if ($target.closest('div.detail-view').length && $target.closest('td.view-all a').length) {
             viewAllArgs = $viewAll.data('detail-view-link-view-all');
             viewAll(
                 viewAllArgs.custom ?
@@ -1615,7 +1633,7 @@
         var $target = $(event.target);
 
         // Refresh
-        if ($target.closest('div.toolbar div.refresh').size()) {
+        if ($target.closest('div.toolbar div.refresh').length) {
             loadTabContent(
                 $target.closest('div.detail-view').find('div.detail-group:visible'),
                 $target.closest('div.detail-view').data('view-args'),
@@ -1626,8 +1644,8 @@
         }
 
         // Detail action
-        if ($target.closest('div.detail-view [detail-action], div.detail-view .action.text').size() &&
-            !$target.closest('.list-view').size()) {
+        if ($target.closest('div.detail-view [detail-action], div.detail-view .action.text').length &&
+            !$target.closest('.list-view').length) {
             var $action = $target.closest('.action').find('[detail-action]');
             var actionName = $action.attr('detail-action');
             var actionCallback = $action.data('detail-view-action-callback');
diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js
index 74c536e..3315aad 100644
--- a/ui/scripts/ui/widgets/listView.js
+++ b/ui/scripts/ui/widgets/listView.js
@@ -294,7 +294,7 @@
                                                 }
 
                                                 if (needsRefresh) {
-                                                    if ($listView.closest('.detail-view').size()) {
+                                                    if ($listView.closest('.detail-view').length) {
                                                         $('.detail-view:last .button.refresh').click();
                                                     } else {
                                                         $loading.remove();
@@ -375,7 +375,7 @@
                                 }
 
                                 if (needsRefresh) {
-                                    if (!$listView.closest('.detail-view').size()) {
+                                    if (!$listView.closest('.detail-view').length) {
                                         $loading.remove();
                                     }
                                 }
@@ -1120,8 +1120,9 @@
                 else
                     $detailView = args.pageGenerator(data).appendTo($newPanel);
 
-                if (complete) complete($detailView);
-
+                if (complete){
+                    complete($detailView);
+                }
                 return $detailView;
             }
         };
@@ -1147,7 +1148,7 @@
 
         if (!(data && data.length)) {
             $listView.data('end-of-table', true);
-            if (!$tbody.find('tr').size()) {
+            if (!$tbody.find('tr').length) {
                 return [
                     $('<tr>').addClass('empty last').append(
                         $('<td>').html(_l('label.no.data'))
@@ -1185,8 +1186,8 @@
                     .addClass('multiSelectCheckbox')
                     .click(function() {
                         var checked = $(this).is(':checked');
-                        var numRows = $(this).parents('tbody').find('input.multiSelectCheckbox').size();
-                        var numRowsChecked = $(this).parents('tbody').find('input.multiSelectCheckbox:checked').size();
+                        var numRows = $(this).parents('tbody').find('input.multiSelectCheckbox').length;
+                        var numRowsChecked = $(this).parents('tbody').find('input.multiSelectCheckbox:checked').length;
                         var enabled = checked || (numRowsChecked > 0);
 
                         toggleMultiSelectActions($td.closest('.list-view'), enabled);
@@ -1325,7 +1326,7 @@
                         true, {},
                         $tr.closest('.list-view').data('view-args').context
                     );
-                    var rowIndex = $tr.closest('tbody').find('tr').size() - ($tr.index());
+                    var rowIndex = $tr.closest('tbody').find('tr').length - ($tr.index());
 
                     context[viewArgs.activeSection] = $tr.data('json-obj');
 
@@ -1629,11 +1630,11 @@
                             position: 'absolute',
                             left: $quickView.offset().left + $quickView.outerWidth() - $quickViewTooltip.width() - 2*(parseInt($quickView.css('border-left-width')) + parseInt($quickView.css('border-right-width'))),
                             top: $quickView.offset().top,
-                            zIndex: $tr.closest('.panel').zIndex() + 1
+                            zIndex: $tr.closest('.panel').css("zIndex") + 1
                         });
 
                         $quickViewTooltip.mouseleave(function() {
-                            if (!$('.overlay:visible').size()) {
+                            if (!$('.overlay:visible').length) {
                                 $quickViewTooltip.remove();
                             }
                         });
@@ -1661,7 +1662,7 @@
                 $('<td>')
                 .addClass('loading icon')
                 .attr({
-                    'colspan': $table.find('th').size()
+                    'colspan': $table.find('th').length
                 })
         );
 
@@ -1829,7 +1830,7 @@
 
         // Clear out any existing list view
         var $existingListView = $container.find('div.list-view');
-        if ($existingListView.size()) {
+        if ($existingListView.length) {
             $existingListView.remove();
         }
 
@@ -1883,7 +1884,7 @@
             }
         }
 
-        if ($switcher && $switcher.find('option').size() == 1) {
+        if ($switcher && $switcher.find('option').length == 1) {
             listViewData = args.sections[
                 $switcher.find('select').val()
             ].listView;
@@ -2017,7 +2018,7 @@
             var code = (event.keyCode ? event.keyCode : event.which);
             var $input = $listView.find('input:focus');
 
-            if ($input.size() && $input.hasClass('edit') && code === 13) {
+            if ($input.length && $input.hasClass('edit') && code === 13) {
                 uiActions.edit($input.closest('tr'), {
                     callback: listViewData.actions.edit.action
                 });
@@ -2077,7 +2078,7 @@
             return true;
         });
         $listView.find('select').bind('change', function(event) {
-            if ($(event.target).closest('.section-select').size()) return true;
+            if ($(event.target).closest('.section-select').length) return true;
             if ((event.type == 'click' ||
                     event.type == 'mouseup') &&
                 ($(event.target).is('select') ||
@@ -2123,7 +2124,7 @@
         };
 
         $listView.find('.advanced-search .icon').bind('click', function(event) {
-            if ($listView.find('.advanced-search .form-container:visible').size()) {
+            if ($listView.find('.advanced-search .form-container:visible').length) {
                 closeAdvancedSearch();
 
                 return false;
@@ -2180,7 +2181,7 @@
                 listView = args.sections[args.activeSection].listView;
             }
             if (listView && listView.disableInfiniteScrolling) return false;
-            if ($listView.find('tr.last, td.loading:visible').size()) return false;
+            if ($listView.find('tr.last, td.loading:visible').length) return false;
 
             clearTimeout(infScrollTimer);
             infScrollTimer = setTimeout(function() {
@@ -2245,12 +2246,12 @@
             var id = $target.closest('tr').data('list-view-item-id');
             var jsonObj = $target.closest('tr').data('jsonObj');
             var detailViewArgs;
-            var detailViewPresent = ($target.closest('div.data-table tr td.first').size() &&
-                listViewData.detailView && !$target.closest('div.edit').size()) && !listViewData.detailView.noPanelView;
+            var detailViewPresent = ($target.closest('div.data-table tr td.first').length &&
+                listViewData.detailView && !$target.closest('div.edit').length) && !listViewData.detailView.noPanelView;
             var uiCustom = args.uiCustom == true ? true : false;
 
             // Click on first item will trigger detail view (if present)
-            if (detailViewPresent && !uiCustom && !$target.closest('.empty, .loading').size()) {
+            if (detailViewPresent && !uiCustom && !$target.closest('.empty, .loading').length) {
                 var $loading = $('<div>').addClass('loading-overlay');
                 $target.closest('div.data-table').prepend($loading); //overlay the whole listView, so users can't click another row until click-handling for this row is done (e.g. API response is back)
 
@@ -2316,9 +2317,9 @@
 
             // Action icons
             if (!$target.closest('td.actions').hasClass('reorder') &&
-                ($target.closest('td.actions').size() ||
-                    $target.closest('.action.add').size() ||
-                    $target.closest('.action.main-action').size())) {
+                ($target.closest('td.actions').length ||
+                    $target.closest('.action.add').length ||
+                    $target.closest('.action.main-action').length)) {
                 var actionID = $target.closest('.action').data('list-view-action-id');
                 var $tr;
 
@@ -2326,8 +2327,8 @@
                     return false;
                 }
 
-                if ($target.closest('.action.add').size() ||
-                    $target.closest('.action.main-action:not(.multiSelectAction)').size()) {
+                if ($target.closest('.action.add').length ||
+                    $target.closest('.action.main-action:not(.multiSelectAction)').length) {
                     $tr = $target.closest('div.list-view').find('tr:first'); // Dummy row
                 } else {
                     if (listViewData.actions[actionID].isMultiSelectAction) {
@@ -2359,7 +2360,7 @@
             }
 
             // Section switcher
-            if ($target.is('a') && $target.closest('div.section-switcher').size()) {
+            if ($target.is('a') && $target.closest('div.section-switcher').length) {
                 makeListView($container, args, $target.data('list-view-section-id'));
 
                 return false;
@@ -2459,7 +2460,7 @@
 
                 if (preFilter) {
                     $selectedVMs = $listView.find('tbody tr').filter(function() {
-                        return $(this).find('td.multiselect input[type=checkbox]:checked').size()
+                        return $(this).find('td.multiselect input[type=checkbox]:checked').length
                     });
                     context[$listView.data('view-args').activeSection] = $selectedVMs.map(function(index, item) {
                         return $(item).data('json-obj');
diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js
index c3fa97c..62ca231 100755
--- a/ui/scripts/ui/widgets/multiEdit.js
+++ b/ui/scripts/ui/widgets/multiEdit.js
@@ -79,7 +79,10 @@
                 });
             }
 
-
+            var $actions = undefined;
+            if(options.editOptionsFirst){
+            	$actions = $('<td>').addClass('multi-actions').appendTo($item.find('tr'));
+            }
             // Setup columns
             $.each(fields, function(fieldName, field) {
                 if (!field || (options.ignoreEmptyFields && !data[fieldName])) {
@@ -160,8 +163,9 @@
                 }
 
                 if (!field.isPassword) {
+                	$td.attr('title', data[fieldName]);
                     if (field.edit) {
-                        // Edit fields append value of data
+                    	// Edit fields append value of data
                         if (field.range) {
                             var start = _s(data[field.range[0]]);
                             var end = _s(data[field.range[1]]);
@@ -177,7 +181,6 @@
                             } else {
                                 $td.append($('<span>').html(_s(data[fieldName])));
                             }
-                            $td.attr('title', data[fieldName]);
                         }
                     } else if (field.isBoolean) {
                         var $checkbox = $('<input>');
@@ -226,7 +229,7 @@
                             $td.append($select);
                         }
                         else {
-                            var matchingValue = $matchingOption.size() ?
+                            var matchingValue = $matchingOption.length ?
                                 $matchingOption.html() : data[fieldName];
 
                             $td.append($('<span>').html(_s(matchingValue)));
@@ -240,7 +243,7 @@
 
                                 var $subItems = $td.closest('.data-item').find('.expandable-listing tr');
 
-                                if ($subItems.size()) {
+                                if ($subItems.length) {
                                     context.subItemData = $subItems.map(function() {
                                         return $(this).data('json-obj');
                                     });
@@ -324,9 +327,9 @@
                 return true;
             });
 
-            // Actions column
-            var $actions = $('<td>').addClass('multi-actions').appendTo($item.find('tr'));
-
+            if(!options.editOptionsFirst){
+            	var $actions = $('<td>').addClass('multi-actions').appendTo($item.find('tr'));
+            }
             // Align action column width
             $actions.width($multi.find('th.multi-actions').width() + 4);
 
@@ -499,31 +502,28 @@
                     .attr('title', _l('label.edit.tags'))
                     .append($('<span></span>').addClass('icon'))
                     .click(function() {
-                        $('<div>')
-                            .dialog({
-                                dialogClass: 'editTags',
-                                title: _l('label.edit.tags'),
-                                width: 400,
-                                buttons: [{
-                                    text: _l('label.done'),
-                                    'class': 'ok',
-                                    click: function() {
-                                        $(this).dialog('destroy');
-                                        $('div.overlay:last').remove();
-
-                                        return true;
-                                    }
-                                }]
-                            })
-                            .append(
-                                $('<div></div>').addClass('multi-edit-tags').tagger($.extend(true, {}, options.tags, {
-                                    context: $.extend(true, {}, options.context, {
-                                        multiRule: [multiRule]
-                                    })
-                                }))
-                        )
-                            .closest('.ui-dialog').overlay();
-
+                        var $dialog = $('<div>').dialog({
+                                            dialogClass: 'editTags',
+                                            title: _l('label.edit.tags'),
+                                            width: 400,
+                                            buttons: [{
+                                                text: _l('label.done'),
+                                                'class': 'ok',
+                                                click: function() {
+                                                    $(this).dialog('destroy');
+                                                    $('div.overlay:last').remove();
+            
+                                                    return true;
+                                                }
+                                            }]
+                                        }).append(
+                                            $('<div></div>').addClass('multi-edit-tags').tagger($.extend(true, {}, options.tags, {
+                                                context: $.extend(true, {}, options.context, {
+                                                    multiRule: [multiRule]
+                                                })
+                                            }))
+                                        );
+                             cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
                         return false;
                     })
                 )
@@ -598,7 +598,7 @@
                     text: _l('label.apply'),
                     'class': 'ok',
                     click: function() {
-                        if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').size()) {
+                        if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').length) {
                             cloudStack.dialog.notice({
                                 message: _l('message.select.item')
                             });
@@ -647,7 +647,8 @@
                         });
                     }
                 }]
-            }).parent('.ui-dialog').overlay();
+            });
+            cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dataList);
         },
 
         /**
@@ -659,7 +660,7 @@
             );
 
             $multi.find('.data tr').filter(function() {
-                return !$(this).closest('.expandable-listing').size();
+                return !$(this).closest('.expandable-listing').length;
             }).each(function() {
                 var $tr = $(this);
 
@@ -905,16 +906,20 @@
         var $thead = $('<tr>').appendTo(
             $('<thead>').appendTo($inputTable)
         );
-        var $inputForm = $('<tr>').appendTo(
-            $('<tbody>').appendTo($inputTable)
-        );
+        if (!args.doNotShowInputTable){
+	        var $inputForm = $('<tr>').appendTo(
+	            $('<tbody>').appendTo($inputTable)
+	        );
+        }
         var $dataBody = $('<div>').addClass('data-body').appendTo($dataTable);
 
         // Setup input table headers
 
         if (reorder) {
             $('<th>').addClass('reorder').appendTo($thead);
-            $('<td>').addClass('reorder').appendTo($inputForm);
+            if (!args.doNotShowInputTable){
+            	$('<td>').addClass('reorder').appendTo($inputForm);
+            }
             $multi.find('.data-body').sortable({
                 handle: '.action.moveDrag',
 
@@ -924,8 +929,8 @@
                     $loading.prependTo($multi);
                     reorder.moveDrag.action({
                         targetIndex: ui.item.index(),
-                        nextItem: ui.item.next().size() ? ui.item.next().data('json-obj') : null,
-                        prevItem: ui.item.prev().size() ? ui.item.prev().data('json-obj') : null,
+                        nextItem: ui.item.next().length ? ui.item.next().data('json-obj') : null,
+                        prevItem: ui.item.prev().length ? ui.item.prev().data('json-obj') : null,
                         context: $.extend(true, {}, context, {
                             // Passes all rules, so that each index can be updated
                             multiRule: [ui.item.data('json-obj')]
@@ -946,6 +951,13 @@
             });
         }
 
+        if (args.editOptionsFirst && args.actions && !args.noHeaderActionsColumn) {
+            $thead.append($('<th></th>').html(_l('label.actions')).addClass('multi-actions'));
+            if (!args.doNotShowInputTable){
+            	$inputForm.append($('<td></td>').addClass('multi-actions'));
+            }
+        }
+        
         $.each(args.fields, function(fieldName, field) {
             if (!field) return true;
 
@@ -954,7 +966,10 @@
             $th.appendTo($thead);
             var $td = $('<td>').addClass(fieldName);
             $td.attr('rel', fieldName);
-            $td.appendTo($inputForm);
+            
+            if (!args.doNotShowInputTable){
+            	$td.appendTo($inputForm);
+            }
 
             var isHidden = $.isFunction(field.isHidden) ?
                     field.isHidden({ context: context }) : field.isHidden;
@@ -1071,7 +1086,10 @@
                 ).appendTo($td);
             }
 
-            if (field.desc) $input.attr('title', field.desc);
+            if (field.desc){ 
+            	$input.attr('title', field.desc);
+            	$th.attr('title', _l(field.desc));
+            }
         });
 
         // Setup header fields
@@ -1093,134 +1111,137 @@
                 .prependTo($multi);
         }
 
-        if (args.actions && !args.noHeaderActionsColumn) {
+        if (!args.editOptionsFirst && args.actions && !args.noHeaderActionsColumn) {
             $thead.append($('<th></th>').html(_l('label.actions')).addClass('multi-actions'));
-            $inputForm.append($('<td></td>').addClass('multi-actions'));
+            if (!args.doNotShowInputTable){
+            	$inputForm.append($('<td></td>').addClass('multi-actions'));
+            }
         }
-
-        $addVM.bind('click', function() {
-            // Validate form first
-            if (!$multiForm.valid()) {
-                if ($multiForm.find('input.error:visible').size()) {
-                    return false;
-                }
-            }
-
-            var $dataList;
-            var addItem = function(itemData) {
-                var data = {};
-
-                $.each(getMultiData($multi), function(key, value) {
-                    if (value != '') {
-                        data[key] = value;
-                    }
-                });
-
-                // Append custom data
-                var $customFields = $multi.find('tbody td').filter(function() {
-                    return $(this).data('multi-custom-data');
-                });
-
-                $customFields.each(function() {
-                    var $field = $(this);
-                    var fieldID = $field.attr('rel');
-                    var fieldData = $field.data('multi-custom-data');
-
-                    data[fieldID] = fieldData;
-                });
-
-                // Loading appearance
-                var $loading = _medit.loadingItem($multi, _l('label.adding') + '...');
-                $dataBody.prepend($loading);
-
-                // Clear out fields
-                $multi.find('input').each(function() {
-                    var $input = $(this);
-
-                    if ($input.is(":checkbox")) {
-                        $input.attr({
-                            checked: false
-                        });
-                    } else if ($input.data('multi-default-value')) {
-                        $input.val($input.data('multi-default-value'));
-                    } else {
-                        $input.val('');
-                    }
-                });
-                $multi.find('tbody td').each(function() {
-                    var $item = $(this);
-
-                    if ($item.data('multi-custom-data')) {
-                        $item.data('multi-custom-data', null);
-                    }
-                });
-
-                // Apply action
-                args.add.action({
-                    context: context,
-                    data: data,
-                    itemData: itemData,
-                    $multi: $multi,
-                    response: {
-                        success: function(successArgs) {
-                            var notification = successArgs ? successArgs.notification : null;
-                            if (notification) {
-                                $('.notifications').notifications('add', {
-                                    section: 'network',
-                                    desc: notification.label,
-                                    interval: 3000,
-                                    _custom: successArgs._custom,
-                                    poll: function(pollArgs) {
-                                        var complete = pollArgs.complete;
-                                        var error = pollArgs.error;
-
-                                        notification.poll({
-                                            _custom: pollArgs._custom,
-                                            complete: function(completeArgs) {
-                                                complete(args);
-                                                $loading.remove();
-                                                getData();
-                                            },
-
-                                            error: function(args) {
-                                                error(args);
-                                                $loading.remove();
-
-                                                return cloudStack.dialog.error(args);
-                                            }
-                                        });
-                                    }
-                                });
-                            } else {
-                                $loading.remove();
-                                getData();
-                            }
-                        },
-
-                        error: cloudStack.dialog.error(function() {
-                            $loading.remove();
-                        })
-                    }
-                });
-            };
-
-            if (args.noSelect) {
-                // Don't append instance data
-                addItem([]);
-
-                return true;
-            }
-
-            _medit.vmList($multi,
-                args.listView,
-                args.context,
-                multipleAdd, _l('label.add.vms'),
-                addItem);
-
-            return true;
-        });
-
+        if($addVM){
+	        $addVM.bind('click', function() {
+	            // Validate form first
+	            if (!$multiForm.valid()) {
+	                if ($multiForm.find('input.error:visible').length) {
+	                    return false;
+	                }
+	            }
+	
+	            var $dataList;
+	            var addItem = function(itemData) {
+	                var data = {};
+	
+	                $.each(getMultiData($multi), function(key, value) {
+	                    if (value != '') {
+	                        data[key] = value;
+	                    }
+	                });
+	
+	                // Append custom data
+	                var $customFields = $multi.find('tbody td').filter(function() {
+	                    return $(this).data('multi-custom-data');
+	                });
+	
+	                $customFields.each(function() {
+	                    var $field = $(this);
+	                    var fieldID = $field.attr('rel');
+	                    var fieldData = $field.data('multi-custom-data');
+	
+	                    data[fieldID] = fieldData;
+	                });
+	
+	                // Loading appearance
+	                var $loading = _medit.loadingItem($multi, _l('label.adding') + '...');
+	                $dataBody.prepend($loading);
+	
+	                // Clear out fields
+	                $multi.find('input').each(function() {
+	                    var $input = $(this);
+	
+	                    if ($input.is(":checkbox")) {
+	                        $input.attr({
+	                            checked: false
+	                        });
+	                    } else if ($input.data('multi-default-value')) {
+	                        $input.val($input.data('multi-default-value'));
+	                    } else {
+	                        $input.val('');
+	                    }
+	                });
+	                $multi.find('tbody td').each(function() {
+	                    var $item = $(this);
+	
+	                    if ($item.data('multi-custom-data')) {
+	                        $item.data('multi-custom-data', null);
+	                    }
+	                });
+	
+	                // Apply action
+	                args.add.action({
+	                    context: context,
+	                    data: data,
+	                    itemData: itemData,
+	                    $multi: $multi,
+	                    response: {
+	                        success: function(successArgs) {
+	                            var notification = successArgs ? successArgs.notification : null;
+	                            if (notification) {
+	                                $('.notifications').notifications('add', {
+	                                    section: 'network',
+	                                    desc: notification.label,
+	                                    interval: 3000,
+	                                    _custom: successArgs._custom,
+	                                    poll: function(pollArgs) {
+	                                        var complete = pollArgs.complete;
+	                                        var error = pollArgs.error;
+	
+	                                        notification.poll({
+	                                            _custom: pollArgs._custom,
+	                                            complete: function(completeArgs) {
+	                                                complete(args);
+	                                                $loading.remove();
+	                                                getData();
+	                                            },
+	
+	                                            error: function(args) {
+	                                                error(args);
+	                                                $loading.remove();
+	
+	                                                return cloudStack.dialog.error(args);
+	                                            }
+	                                        });
+	                                    }
+	                                });
+	                            } else {
+	                                $loading.remove();
+	                                getData();
+	                            }
+	                        },
+	
+	                        error: cloudStack.dialog.error(function() {
+	                            $loading.remove();
+	                        })
+	                    }
+	                });
+	            };
+	
+	            if (args.noSelect) {
+	                // Don't append instance data
+	                addItem([]);
+	
+	                return true;
+	            }
+	
+	            _medit.vmList($multi,
+	                args.listView,
+	                args.context,
+	                multipleAdd, _l('label.add.vms'),
+	                addItem);
+	
+	            return true;
+	        });
+        }
         var listView = args.listView;
+        var editOptionsFirst = args.editOptionsFirst;
         var getData = function() {
             dataProvider({
                 context: context,
@@ -1247,7 +1268,8 @@
                                     listView: listView,
                                     tags: tags,
                                     reorder: reorder,
-                                    selectPermission: selectPermission
+                                    selectPermission: selectPermission,
+                                    editOptionsFirst: editOptionsFirst
                                 }
                             ).appendTo($dataBody);
                         });
diff --git a/ui/scripts/ui/widgets/notifications.js b/ui/scripts/ui/widgets/notifications.js
index 5fd91f1..6ff9e74 100644
--- a/ui/scripts/ui/widgets/notifications.js
+++ b/ui/scripts/ui/widgets/notifications.js
@@ -145,8 +145,8 @@
         resetTotal: function($popup) {
             var $total = $popup.data('notifications-attach-to').find('div.total span');
             var $items = $popup.find('ul li');
-            var total = $items.size();
-            var completed = $items.filter(':not(.pending)').size();
+            var total = $items.length;
+            var completed = $items.filter(':not(.pending)').length;
             var newTotal = total - completed;
 
             if (newTotal < 0) newTotal = completed;
@@ -331,7 +331,7 @@
         var $attachTo, $popup;
 
         // Notifications header area
-        if ($target.closest('.notifications').size()) {
+        if ($target.closest('.notifications').length) {
             $attachTo = $target.closest('.notifications');
             $popup = $attachTo.data('notifications-popup');
             notifications.popup.show($popup, $attachTo);
@@ -352,11 +352,11 @@
         }
 
         // Popup
-        if ($target.closest('div.notification-box').size()) {
+        if ($target.closest('div.notification-box').length) {
             $popup = $target.closest('div.notification-box');
 
             // Clear list
-            if ($target.closest('.button.clear-list').size()) {
+            if ($target.closest('.button.clear-list').length) {
                 notifications.clear($popup);
             }
 
@@ -379,7 +379,7 @@
     $(window).resize(function(event) {
         var $popup = $('div.notification-box:visible');
 
-        if ($popup.size())
+        if ($popup.length)
             notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
     });
 })(window.jQuery, window.cloudStack, window._l);
diff --git a/ui/scripts/ui/widgets/toolTip.js b/ui/scripts/ui/widgets/toolTip.js
index 747c448..6e11e32 100644
--- a/ui/scripts/ui/widgets/toolTip.js
+++ b/ui/scripts/ui/widgets/toolTip.js
@@ -34,7 +34,8 @@
                 $(this.element).focus(hoverHandler);
                 $(this.element).blur(outHandler);
             } else if (this.options.mode == 'manual') {}
-
+            
+            $(this.element).data('toolTipOptions', this.options);
             $(this.element).data('$tooltip', $tooltip);
 
             // Add arrow
@@ -100,14 +101,14 @@
     });
 
     function hoverHandler(event) {
-        //Fetch Options
-        var o = $.data(this, 'toolTip').options;
-
         //Element who raised the event
         var $this = $(this);
 
+        var toolTipOptionObject = $this.data('toolTipOptions');
+        
+
         //Helper functon for Positioning and Calling Callback function
-        prepare($this, o);
+        prepare($this, toolTipOptionObject);
 
         //Call Show method of the tooltip Widget,
         //Show method should play on any required animations
@@ -115,15 +116,18 @@
     };
 
     function outHandler(event) {
+        //Element who raised the event
+        var $this = $(this);
+        
         //Fetch Options
-        var o = $.data(this, 'toolTip').options;
+        var toolTipOptionObject = $this.data('toolTipOptions');
 
         //Get tooptip Element
-        var $tooltip = $(o.toolTip);
+        var $tooltip = $(toolTipOptionObject.toolTip);
 
         //If call back method defined, initiate the call
-        if ($.data(this, 'toolTip').options.onHide) {
-            $.data(this, 'toolTip').options.onHide.call(this, {
+        if (toolTipOptionObject.onHide) {
+            toolTipOptionObject.onHide.call(this, {
                 target: $(this)
             });
         }
@@ -161,7 +165,7 @@
 
         // Fix overlay
         setTimeout(function() {
-            $('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10);
+            $('.tooltip-box').css( "zIndex", $(':ui-dialog').css("zIndex") + 10);
         });
 
     };
diff --git a/ui/scripts/ui/widgets/treeView.js b/ui/scripts/ui/widgets/treeView.js
index c948e10..eb923a9 100644
--- a/ui/scripts/ui/widgets/treeView.js
+++ b/ui/scripts/ui/widgets/treeView.js
@@ -103,7 +103,7 @@
             var $li = $target.closest('li');
 
             if ($target.is('li div.expand') && $li.data('tree-view-item-obj')) {
-                if ($li.find('ul').size()) {
+                if ($li.find('ul').length) {
                     $li.find('ul').remove();
                     $li.removeClass('expanded');
 
@@ -128,7 +128,7 @@
                 $treeView.find('li .name').removeClass('selected');
                 $target.addClass('selected');
 
-                if ($browser && $browser.size()) {
+                if ($browser && $browser.length) {
                     $browser.cloudBrowser('addPanel', {
                         partial: true,
                         title: $target.html(),
diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js
index 3ce0a9f..27b0c16 100644
--- a/ui/scripts/vpc.js
+++ b/ui/scripts/vpc.js
@@ -15,6 +15,57 @@
 // specific language governing permissions and limitations
 // under the License.
 (function($, cloudStack) {
+    //The drag and drop function to order ACL rules does not have access to the whole ACL.
+    //Therefore, we store the "state-hash" of the list being displayed for use in the drag and drop function.
+    var accessControlListConsistentyHashForDragAndDropFunction = "";
+
+    var isNumeric = function (n) {
+        return !isNaN(parseFloat(n));
+    };
+    var createSafeCsvValue = function(value){
+        if(value){
+            return '"' + value + '"';
+        }
+        return "";
+    };
+    
+    var generateCsvForAclRules = function(aclRules){
+        var csv = createSafeCsvValue('id') + ',';
+        for(var field in aclRuleFields){
+            var fieldLabel = aclRuleFields[field].label;
+            var fieldLabelTranslated = _l(fieldLabel);
+            csv = csv + createSafeCsvValue(fieldLabelTranslated) + ',';
+        }
+        csv = csv.substr(0, csv.length - 1) + '\n';
+        if(!aclRules){
+            return csv;
+        }
+        aclRules.forEach(function(entry){
+            csv = csv + 
+            createSafeCsvValue(entry.id) + ',' + 
+            createSafeCsvValue(entry.number) + ',' +
+            createSafeCsvValue(entry.cidrlist) + ',' +
+            createSafeCsvValue(entry.action) + ',' ;
+            
+            if(isNumeric(entry.protocol)){
+                csv = csv +
+                createSafeCsvValue(_l('label.protocol.number')) + ',' +
+                createSafeCsvValue(entry.protocol) + ',';
+            }else{
+                csv = csv +
+                createSafeCsvValue(entry.protocol) + ',' +
+                createSafeCsvValue('') + ',';
+            }
+            csv = csv +
+            createSafeCsvValue(entry.startport) + ',' +
+            createSafeCsvValue(entry.endport) + ',' +
+            createSafeCsvValue(entry.icmptype) + ',' +
+            createSafeCsvValue(entry.icmpcode) + ',' +
+            createSafeCsvValue(entry.traffictype) + ',' +
+            createSafeCsvValue(entry.reason) + '\n';
+        });
+        return csv;
+    };
     var assignVMAction = function() {
         return {
             label: 'label.assign.vms',
@@ -190,63 +241,14 @@
         };
     };
 
-    var aclMultiEdit = {
-        noSelect: true,
-
-        reorder: {
-            moveDrag: {
-                action: function(args) {
-                    var rule = args.context.multiRule[0];
-                    var number = 0;
-                    var prevItem = args.prevItem ? args.prevItem.number : null;
-                    var nextItem = args.nextItem ? args.nextItem.number : null;
-
-                    if (!nextItem) { // Last item
-                        number = prevItem + 100;
-                    } else {
-                        if (nextItem - prevItem <= 10) {
-                            number = nextItem - parseInt(((nextItem - prevItem) / 2));
-                        } else {
-                            number = nextItem > 1 ? nextItem - 10 : 1;
-                        }
-                    }
-
-                    $.ajax({
-                        url: createURL('updateNetworkACLItem'),
-                        data: {
-                            id: rule.id,
-                            number: number
-                        },
-                        success: function(json) {
-                            var pollTimer = setInterval(function() {
-                                pollAsyncJobResult({
-                                    _custom: {
-                                        jobId: json.createnetworkaclresponse.jobid
-                                    },
-                                    complete: function() {
-                                        clearInterval(pollTimer);
-                                        args.response.success();
-                                    },
-                                    error: function(errorMsg) {
-                                        clearInterval(pollTimer);
-                                        args.response.error(errorMsg);
-                                    }
-                                });
-                            }, 1000);
-                        }
-                    });
-                }
-            }
-        },
-        fields: {
-
+    var aclRuleFields = {
             'number': {
-                label: 'label.rule.number',
+                label: 'label.rule.number.short',
+                desc: 'label.rule.number',
                 edit: true,
                 isEditable: true
 
             },
-
             'cidrlist': {
                 edit: true,
                 label: 'label.cidr',
@@ -322,6 +324,13 @@
                                 $portFields.hide();
                             } else if ($(this).val() == 'all') {
                                 $portFields.hide();
+                                $portFields.attr('disabled', 'disabled');
+                                
+                                $icmpFields.hide();
+                                $icmpFields.attr('disabled', 'disabled');
+                                
+                                $protocolFields.attr('disabled', 'disabled');
+                                $protocolFields.hide();
                             } else {
                                 $otherFields.show();
                                 $icmpFields.hide();
@@ -378,8 +387,14 @@
                                 $otherFields.hide();
                                 $otherFields.parent().find('label.error').hide();
                             } else if ($(this).val() == 'all') {
-                                $portFields.attr('disabled', 'disabled');
                                 $portFields.hide();
+                                $portFields.attr('disabled', 'disabled');
+
+                                $icmpFields.hide();
+                                $icmpFields.attr('disabled', 'disabled');
+
+                                $protocolFields.hide();
+                                $protocolFields.attr('disabled', 'disabled');
                             } else {
                                 $otherFields.show();
                                 $otherFields.parent().find('label.error').hide();
@@ -420,7 +435,8 @@
             },
 
             'protocolnumber': {
-                label: 'label.protocol.number',
+                label: 'label.protocol.number.short',
+                desc: 'label.protocol.number',
                 edit: true,
                 isEditable: true
             },
@@ -436,6 +452,45 @@
                 isOptional: true,
                 isEditable: true
             },
+            'icmptype': {
+                edit: true,
+                label: 'ICMP.type',
+                desc: 'ICMP.type.desc',
+                defaultValue: '-1',
+                isEditable: true
+            },
+            'icmpcode': {
+                edit: true,
+                label: 'ICMP.code',
+                desc: 'ICMP.code.desc',
+                defaultValue: '-1',
+                isEditable: true
+            },
+            'traffictype': {
+                label: 'label.traffic.type',
+                isEditable: true,
+                select: function(args) {
+                    args.response.success({
+                        data: [{
+                            name: 'Ingress',
+                            description: 'Ingress'
+                        }, {
+                            name: 'Egress',
+                            description: 'Egress'
+                        }]
+                    });
+                }
+            },
+            'reason': {
+                edit: true,
+                label: 'label.acl.reason',
+                desc: 'label.acl.reason.description',
+                isEditable: true,
+                isTextarea: true
+           }
+    };
+    
+    var aclRuleFieldsForMultiEdit = {
             'networkid': {
                 label: 'label.select.tier',
                 select: function(args) {
@@ -472,43 +527,52 @@
                     });
                 }
             },
-            'icmptype': {
-                edit: true,
-                label: 'ICMP.type',
-                isDisabled: true,
-                desc: 'Please specify -1 if you want to allow all ICMP types',
-                defaultValue: '-1',
-                isEditable: true
-            },
-            'icmpcode': {
-                edit: true,
-                label: 'ICMP.code',
-                isDisabled: true,
-                desc: 'Please specify -1 if you want to allow all ICMP codes',
-                defaultValue: '-1',
-                isEditable: true
-            },
-            'traffictype': {
-                label: 'label.traffic.type',
-                isEditable: true,
-                select: function(args) {
-                    args.response.success({
-                        data: [{
-                            name: 'Ingress',
-                            description: 'Ingress'
-                        }, {
-                            name: 'Egress',
-                            description: 'Egress'
-                        }]
+    };
+    
+    jQuery.extend(aclRuleFieldsForMultiEdit, aclRuleFields);
+    
+    var aclMultiEdit = {
+    	doNotShowInputTable: true,
+    	editOptionsFirst: true,
+        noSelect: true,
+        reorder: {
+            moveDrag: {
+                action: function(args) {
+                    var rule = args.context.multiRule[0];
+                    
+                    var previousRuleId = args.prevItem ? args.prevItem.id : undefined;
+                    var nextRuleId = args.nextItem ? args.nextItem.id : undefined;
+                     
+                    $.ajax({
+                        url: createURL('moveNetworkAclItem'),
+                        data: {
+                            id: rule.id,
+                            previousaclruleid: previousRuleId, 
+                            nextaclruleid: nextRuleId,
+                            aclconsistencyhash: accessControlListConsistentyHashForDragAndDropFunction
+                        },
+                        success: function(json) {
+                            var pollTimer = setInterval(function() {
+                                pollAsyncJobResult({
+                                    _custom: {
+                                        jobId: json.moveNetworkAclItemResponse.jobid
+                                    },
+                                    complete: function() {
+                                        clearInterval(pollTimer);
+                                        args.response.success();
+                                    },
+                                    error: function(errorMsg) {
+                                        clearInterval(pollTimer);
+                                        args.response.error(errorMsg);
+                                    }
+                                });
+                            }, 1000);
+                        }
                     });
                 }
-            },
-            'add-rule': {
-                label: 'label.add.rule',
-                addButton: true
             }
         },
-
+        fields: aclRuleFieldsForMultiEdit,
         tags: cloudStack.api.tags({
             resourceType: 'NetworkACL',
             contextId: 'multiRule'
@@ -580,7 +644,8 @@
                         number: args.data.number,
                         protocol: args.data.protocol,
                         traffictype: args.data.traffictype,
-                        action: args.data.action
+                        action: args.data.action,
+                        reason: args.data.reason
                     };
 
                     if (data.protocol === 'tcp' || data.protocol === 'udp') {
@@ -602,10 +667,11 @@
 
                         delete args.data.protocolnumber;
                     }
-
+                    data.partialupgrade = false;
                     $.ajax({
                         url: createURL('updateNetworkACLItem'),
                         data: data,
+                        type: "POST",
                         success: function(json) {
                             args.response.success({
                                 _custom: {
@@ -983,32 +1049,6 @@
                                     });
                                 }
                             },
-
-                            /*
-              rules: {
-                title: 'label.rules',
-                multiple: true,
-                fields: [
-                  {
-                    sourceport: { label: 'Source Port' },
-                    instanceport: { label: 'Instance Port' }
-                  }
-                ],
-                dataProvider: function(args) {
-                  $.ajax({
-                    url: createURL('listLoadBalancers'),
-                    data: {
-                      id: args.context.internalLoadBalancers[0].id
-                    },
-                    success: function(json) {
-                      var item = json.listloadbalancersresponse.loadbalancer[0];
-                      args.response.success({ data: item.loadbalancerrule });
-                    }
-                  });
-                }
-              },
-              */
-
                             assignedVms: {
                                 title: 'label.assigned.vms',
                                 listView: {
@@ -1286,6 +1326,37 @@
                                 notification: {
                                     poll: pollAsyncJobResult
                                 }
+                            },
+                            edit: {
+                                label: 'label.edit.acl.list',
+                                action: function(args) {
+                                    var data = args.data;
+                                    data.id = args.context.aclLists[0].id;
+                                    $.ajax({
+                                        url: createURL('updateNetworkACLList'),
+                                        type: "POST",
+                                        data: data,
+                                        success: function(json) {
+                                            var jid = json.updatenetworkacllistresponse.jobid;
+                                            args.response.success({
+                                                _custom: {
+                                                    jobId: jid,
+                                                    getUpdatedItem: function() {
+                                                        $(window).trigger('cloudStack.fullRefresh');
+                                                        jQuery('div[id=breadcrumbs] ul:visible li span').last().html(data.name);
+                                                    }
+                                                }
+                                            });
+                                        },
+                                        error: function(json) {
+                                            args.response.error(parseXMLHttpResponse(json));
+                                        }
+                                    });
+                                },
+                                notification: {
+                                    poll: pollAsyncJobResult,
+                                    desc: 'label.edit.acl.list'
+                                }
                             }
                         },
 
@@ -1298,7 +1369,8 @@
                                         isEditable: true
                                     },
                                     description: {
-                                        label: 'label.description'
+                                        label: 'label.description',
+                                        isEditable: true  
                                     },
                                     id: {
                                         label: 'label.id'
@@ -1313,6 +1385,7 @@
                                                 var allowedActions = [];
                                                 if (items.vpcid != null) {
                                                     allowedActions.push("remove");
+                                                    allowedActions.push("edit");
                                                 }
                                                 return allowedActions;
                                             }
@@ -1330,38 +1403,103 @@
                                             networkid: false
                                         },
                                         dataProvider: function(args) {
+                                            var aclListId = args.context.aclLists[0].id;
                                             $.ajax({
-                                                url: createURL('listNetworkACLs&aclid=' + args.context.aclLists[0].id),
+                                                url: createURL('listNetworkACLs&aclid=' + aclListId),
                                                 success: function(json) {
-                                                    var items = json.listnetworkaclsresponse.networkacl.sort(function(a, b) {
-                                                        return a.number - b.number;
-                                                    }).map(function(acl) {
-                                                        if (parseInt(acl.protocol)) { // protocol number
-                                                            acl.protocolnumber = acl.protocol;
-                                                            acl.protocol = "protocolnumber";
-                                                        }
+                                                    var items = json.listnetworkaclsresponse.networkacl;
 
-                                                        return acl;
-                                                    });
+                                                    if(items){
+                                                        items.sort(function(a, b) {
+                                                            return a.number - b.number;
+                                                        }).map(function(acl) {
+                                                            if (parseInt(acl.protocol)) { // protocol number
+                                                                acl.protocolnumber = acl.protocol;
+                                                                acl.protocol = "protocolnumber";
+                                                            }
+    
+                                                            return acl;
+                                                        });
+                                                        var allUuids = '';
+                                                        items.forEach(function(aclRule){
+                                                                            allUuids += aclRule.id;
+                                                                      });
+                                                        accessControlListConsistentyHashForDragAndDropFunction = $.md5(allUuids);
+                                                    }
 
                                                     args.response.success({
                                                         data: items
-                                                        /* {
-                               cidrlist: '10.1.1.0/24',
-                               protocol: 'TCP',
-                               startport: 22, endport: 22,
-                               networkid: 0,
-                               traffictype: 'Egress'
-                               },
-                               {
-                               cidrlist: '10.2.1.0/24',
-                               protocol: 'UDP',
-                               startport: 56, endport: 72,
-                               networkid: 0,
-                               trafficType: 'Ingress'
-                               }
-                               ]*/
                                                     });
+                                                    if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.add').length === 0){
+                                                        var $addAclRuleDivButton = jQuery('<div>').addClass('button add');
+                                                        var $spanAddAclRuleButtonMessage = jQuery('<span>').html(_l('label.add.ACL'));
+                                                        
+                                                        $addAclRuleDivButton.html($spanAddAclRuleButtonMessage);
+                                                        $addAclRuleDivButton.click(function(){
+                                                        	cloudStack.dialog.createForm({
+                                                        		 form: {
+                                                                     title: 'label.add.rule',
+                                                                     desc: 'label.add.rule.desc',
+                                                                     fields: aclRuleFields
+                                                                 },
+                                                                 after: function(argsLocal) {
+                                                                	 var data = argsLocal.data;
+                                                                	 data.aclid = argsLocal.context.aclLists[0].id;
+                                                                	 if(data.protocol != 'icmp'){
+                                                                		 data.icmpcode = undefined;
+                                                                		 data.icmptype  = undefined;
+                                                                	 }
+                                                                	 if(data.protocol != 'protocolnumber'){
+                                                                		 data.protocolnumber = undefined;
+                                                                	 }else{
+                                                                	     data.protocol = data.protocolnumber;
+                                                                	     data.protocolnumber = undefined;
+                                                                	 }
+                                                                	 if(data.protocol === 'all'){
+                                                                		 data.startport = undefined;
+                                                                		 data.endport = undefined;
+                                                                	 }
+                                                                     $.ajax({
+                                                                         url: createURL('createNetworkACL'),
+                                                                         data: argsLocal.data,
+                                                                         type: "POST",
+                                                                         success: function(json) {
+                                                                        	 jQuery('button.cancel:visible').click();
+                                                                        	 jQuery('div.toolbar:visible div.refresh').click();
+                                                                         }
+                                                                     });
+                                                                 },
+                                                                 context: args.context
+                                                        	});
+                                                        });
+                                                        jQuery('#details-tab-aclRules').siblings('div.toolbar').append($addAclRuleDivButton);
+                                                    }
+                                                    if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.export').length === 0){
+                                                        var $exportAclsDivButton = jQuery('<div>').addClass('button export');
+                                                        var $linkExportAclRulesButtonMessage = jQuery('<a>').html(_l('label.acl.export'));
+                                                        
+                                                        $exportAclsDivButton.html($linkExportAclRulesButtonMessage);
+                                                        $exportAclsDivButton.click(function(){
+                                                            
+                                                            $.ajax({
+                                                                url: createURL('listNetworkACLs&aclid=' + aclListId),
+                                                                type: "GET",
+                                                                async: false,
+                                                                success: function(json) {
+                                                                    var acls = json.listnetworkaclsresponse.networkacl;
+                                                                    var csv = generateCsvForAclRules(acls);
+                                                                    
+                                                                    window.URL = window.URL || window.webkiURL;
+                                                                    var blob = new Blob([csv]);
+                                                                    var blobURL = window.URL.createObjectURL(blob);
+                                                                    
+                                                                    $linkExportAclRulesButtonMessage.attr("href", blobURL);
+                                                                    $linkExportAclRulesButtonMessage.attr("download", "aclRules.csv");
+                                                                }
+                                                            });
+                                                        });
+                                                        jQuery('#details-tab-aclRules').siblings('div.toolbar').append($exportAclsDivButton);
+                                                    }
                                                 }
                                             });
                                         }
@@ -3091,16 +3229,16 @@
                         },
                         action: function(args) {
                             var array1 = [];
-                            array1.push("&name=" + todb(args.data.name));
-                            array1.push("&displaytext=" + todb(args.data.displaytext));
+                            array1.push("&name=" + encodeURIComponent(args.data.name));
+                            array1.push("&displaytext=" + encodeURIComponent(args.data.displaytext));
 
                             //args.data.networkdomain is null when networkdomain field is hidden
                             if (args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain)
-                                array1.push("&networkdomain=" + todb(args.data.networkdomain));
+                                array1.push("&networkdomain=" + encodeURIComponent(args.data.networkdomain));
 
                             //args.data.networkofferingid is null when networkofferingid field is hidden
                             if (args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) {
-                                array1.push("&networkofferingid=" + todb(args.data.networkofferingid));
+                                array1.push("&networkofferingid=" + encodeURIComponent(args.data.networkofferingid));
 
                                 if (args.context.networks[0].type == "Isolated") { //Isolated network
                                     cloudStack.dialog.confirm({
@@ -4344,18 +4482,6 @@
                                     return capability.name == 'LbSchemes';
                                 }) : [];
 
-                                /*      var lbSchemes = $.grep(
-                  $.grep(
-                    tier.service,
-                    function(service) {
-                      return service.name == 'Lb';
-                    }
-                  )[0].capability,
-                  function(capability) {
-                    return capability.name == 'LbSchemes';
-                  }
-                );*/
-
                                 var hasLbScheme = function(schemeVal) {
                                     return $.grep(
                                         lbSchemes,
@@ -4388,7 +4514,6 @@
                                 });
                             })
                         });
-
                         if (error) {
                             cloudStack.dialog.notice({
                                 message: 'Error loading dashboard data.'
diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js
index eedf16a..7373ea6 100755
--- a/ui/scripts/zoneWizard.js
+++ b/ui/scripts/zoneWizard.js
@@ -1908,7 +1908,7 @@
                                     } else {
                                         /*
                                         UI no longer gets providers from "listStorageProviders&type=image" because:
-                                        (1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI).
+                                        (1) Not all of returned values are handled by UI.
                                         (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image"
                                         */
                                         storageproviders.push({ id: 'NFS', description: 'NFS'});
@@ -2272,7 +2272,7 @@
 
                     var array1 = [];
                     var networkType = args.data.zone.networkType; //"Basic", "Advanced"
-                    array1.push("&networktype=" + todb(networkType));
+                    array1.push("&networktype=" + encodeURIComponent(networkType));
 
                     if (networkType == "Basic") {
                         if (selectedNetworkOfferingHavingSG == true)
@@ -2284,13 +2284,13 @@
                             array1.push("&securitygroupenabled=false");
 
                             if (args.data.zone.guestcidraddress != null && args.data.zone.guestcidraddress.length > 0)
-                                array1.push("&guestcidraddress=" + todb(args.data.zone.guestcidraddress));
+                                array1.push("&guestcidraddress=" + encodeURIComponent(args.data.zone.guestcidraddress));
                         } else { // args.data.zone.sgEnabled    == true
                             array1.push("&securitygroupenabled=true");
                         }
                     }
 
-                    array1.push("&name=" + todb(args.data.zone.name));
+                    array1.push("&name=" + encodeURIComponent(args.data.zone.name));
 
                     if (args.data.zone.localstorageenabled == 'on') {
                         array1.push("&localstorageenabled=true");
@@ -2298,25 +2298,25 @@
 
                     //IPv4
                     if (args.data.zone.ip4dns1 != null && args.data.zone.ip4dns1.length > 0)
-                        array1.push("&dns1=" + todb(args.data.zone.ip4dns1));
+                        array1.push("&dns1=" + encodeURIComponent(args.data.zone.ip4dns1));
                     if (args.data.zone.ip4dns2 != null && args.data.zone.ip4dns2.length > 0)
-                        array1.push("&dns2=" + todb(args.data.zone.ip4dns2));
+                        array1.push("&dns2=" + encodeURIComponent(args.data.zone.ip4dns2));
 
                     //IPv6
                     if (args.data.zone.ip6dns1 != null && args.data.zone.ip6dns1.length > 0)
-                        array1.push("&ip6dns1=" + todb(args.data.zone.ip6dns1));
+                        array1.push("&ip6dns1=" + encodeURIComponent(args.data.zone.ip6dns1));
                     if (args.data.zone.ip6dns2 != null && args.data.zone.ip6dns2.length > 0)
-                        array1.push("&ip6dns2=" + todb(args.data.zone.ip6dns2));
+                        array1.push("&ip6dns2=" + encodeURIComponent(args.data.zone.ip6dns2));
 
 
-                    array1.push("&internaldns1=" + todb(args.data.zone.internaldns1));
+                    array1.push("&internaldns1=" + encodeURIComponent(args.data.zone.internaldns1));
 
                     var internaldns2 = args.data.zone.internaldns2;
                     if (internaldns2 != null && internaldns2.length > 0)
-                        array1.push("&internaldns2=" + todb(internaldns2));
+                        array1.push("&internaldns2=" + encodeURIComponent(internaldns2));
 
                     if (args.data.zone.networkdomain != null && args.data.zone.networkdomain.length > 0)
-                        array1.push("&domain=" + todb(args.data.zone.networkdomain));
+                        array1.push("&domain=" + encodeURIComponent(args.data.zone.networkdomain));
 
                     $.ajax({
                         url: createURL("createZone" + array1.join("")),
@@ -2374,7 +2374,7 @@
                         //Basic zone has only one physical network
                         var array1 = [];
                         if ("physicalNetworks" in args.data) { //from add-zone-wizard
-                            array1.push("&name=" + todb(args.data.physicalNetworks[0].name));
+                            array1.push("&name=" + encodeURIComponent(args.data.physicalNetworks[0].name));
                         } else { //from quick-install-wizard
                             array1.push("&name=PhysicalNetworkInBasicZone");
                         }
@@ -2595,9 +2595,9 @@
                         $(args.data.physicalNetworks).each(function(index) {
                             var thisPhysicalNetwork = this;
                             var array1 = [];
-                            array1.push("&name=" + todb(thisPhysicalNetwork.name));
+                            array1.push("&name=" + encodeURIComponent(thisPhysicalNetwork.name));
                             if (thisPhysicalNetwork.isolationMethod != null && thisPhysicalNetwork.isolationMethod.length > 0)
-                                array1.push("&isolationmethods=" + todb(thisPhysicalNetwork.isolationMethod));
+                                array1.push("&isolationmethods=" + encodeURIComponent(thisPhysicalNetwork.isolationMethod));
                             $.ajax({
                                 url: createURL("createPhysicalNetwork&zoneid=" + args.data.returnedZone.id + array1.join("")),
                                 dataType: "json",
@@ -3701,12 +3701,11 @@
 
                     var array1 = [];
                     array1.push("&physicalnetworkid=" + args.data.returnedBasicPhysicalNetwork.id);
-                    array1.push("&username=" + todb(args.data.basicPhysicalNetwork.username));
-                    array1.push("&password=" + todb(args.data.basicPhysicalNetwork.password));
-                    array1.push("&networkdevicetype=" + todb(args.data.basicPhysicalNetwork.networkdevicetype));
+                    cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.basicPhysicalNetwork.username, args.data.basicPhysicalNetwork.password);
+                    array1.push("&networkdevicetype=" + encodeURIComponent(args.data.basicPhysicalNetwork.networkdevicetype));
                     array1.push("&gslbprovider=" + (args.data.basicPhysicalNetwork.gslbprovider == "on"));
-                    array1.push("&gslbproviderpublicip=" + todb(args.data.basicPhysicalNetwork.gslbproviderpublicip));
-                    array1.push("&gslbproviderprivateip=" + todb(args.data.basicPhysicalNetwork.gslbproviderprivateip));
+                    array1.push("&gslbproviderpublicip=" + encodeURIComponent(args.data.basicPhysicalNetwork.gslbproviderpublicip));
+                    array1.push("&gslbproviderprivateip=" + encodeURIComponent(args.data.basicPhysicalNetwork.gslbproviderprivateip));
 
                     //construct URL starts here
                     var url = [];
@@ -3781,7 +3780,7 @@
                     url.push("lbdevicededicated=" + dedicated.toString());
 
 
-                    array1.push("&url=" + todb(url.join("")));
+                    array1.push("&url=" + encodeURIComponent(url.join("")));
                     //construct URL ends here
 
                     $.ajax({
@@ -3905,14 +3904,14 @@
 
                     var array3 = [];
                     array3.push("&zoneId=" + args.data.returnedZone.id);
-                    array3.push("&name=" + todb(args.data.pod.name));
-                    array3.push("&gateway=" + todb(args.data.pod.reservedSystemGateway));
-                    array3.push("&netmask=" + todb(args.data.pod.reservedSystemNetmask));
-                    array3.push("&startIp=" + todb(args.data.pod.reservedSystemStartIp));
+                    array3.push("&name=" + encodeURIComponent(args.data.pod.name));
+                    array3.push("&gateway=" + encodeURIComponent(args.data.pod.reservedSystemGateway));
+                    array3.push("&netmask=" + encodeURIComponent(args.data.pod.reservedSystemNetmask));
+                    array3.push("&startIp=" + encodeURIComponent(args.data.pod.reservedSystemStartIp));
 
                     var endip = args.data.pod.reservedSystemEndIp; //optional
                     if (endip != null && endip.length > 0)
-                        array3.push("&endIp=" + todb(endip));
+                        array3.push("&endIp=" + encodeURIComponent(endip));
 
                     $.ajax({
                         url: createURL("createPod" + array3.join("")),
@@ -3962,7 +3961,7 @@
                             array1.push("&zoneId=" + args.data.returnedZone.id);
 
                             if (this.vlanid != null && this.vlanid.length > 0)
-                                array1.push("&vlan=" + todb(this.vlanid));
+                                array1.push("&vlan=" + encodeURIComponent(this.vlanid));
                             else
                                 array1.push("&vlan=untagged");
 
@@ -4202,7 +4201,7 @@
                                 });
 
                                 $.ajax({
-                                    url: createURL("updatePhysicalNetwork&id=" + returnedId + "&vlan=" + todb(vlan)),
+                                    url: createURL("updatePhysicalNetwork&id=" + returnedId + "&vlan=" + encodeURIComponent(vlan)),
                                     dataType: "json",
                                     success: function(json) {
                                         var jobId = json.updatephysicalnetworkresponse.jobid;
@@ -4273,8 +4272,7 @@
                     var clusterName = args.data.cluster.name;
 
                     if (args.data.cluster.hypervisor == "VMware") {
-                        array1.push("&username=" + todb(args.data.cluster.vCenterUsername));
-                        array1.push("&password=" + todb(args.data.cluster.vCenterPassword));
+                        cloudStack.addUsernameAndPasswordToCommandUrlParameterArrayIfItIsNotNullAndNotEmpty(array1, args.data.cluster.vCenterUsername, args.data.cluster.vCenterPassword);
 
                         if (args.data.cluster.vsmipaddress != null && args.data.cluster.vsmipaddress.length > 0) {
                             array1.push('&vsmipaddress=' + args.data.cluster.vsmipaddress);
@@ -4297,10 +4295,10 @@
                         else
                             url = hostname;
                         url += "/" + dcName + "/" + clusterName;
-                        array1.push("&url=" + todb(url));
+                        array1.push("&url=" + encodeURIComponent(url));
                         clusterName = hostname + "/" + dcName + "/" + clusterName; //override clusterName
                     }
-                    array1.push("&clustername=" + todb(clusterName));
+                    array1.push("&clustername=" + encodeURIComponent(clusterName));
 
                     if (args.data.cluster.hypervisor == "VMware") {
                         var vmwareData = {
@@ -4466,15 +4464,15 @@
                     array1.push("&zoneid=" + args.data.returnedZone.id);
                     array1.push("&podId=" + args.data.returnedPod.id);
                     array1.push("&clusterid=" + args.data.returnedCluster.id);
-                    array1.push("&name=" + todb(args.data.primaryStorage.name));
-                    array1.push("&scope=" + todb(args.data.primaryStorage.scope));
+                    array1.push("&name=" + encodeURIComponent(args.data.primaryStorage.name));
+                    array1.push("&scope=" + encodeURIComponent(args.data.primaryStorage.scope));
 
                     //zone-wide-primary-storage is supported only for KVM and VMWare
                     if (args.data.primaryStorage.scope == "zone") { //hypervisor type of the hosts in zone that will be attached to this storage pool. KVM, VMware supported as of now.
                         if(args.data.cluster.hypervisor != undefined) {
-                            array1.push("&hypervisor=" + todb(args.data.cluster.hypervisor));
+                            array1.push("&hypervisor=" + encodeURIComponent(args.data.cluster.hypervisor));
                         } else if(args.data.returnedCluster.hypervisortype != undefined) {
-                            array1.push("&hypervisor=" + todb(args.data.returnedCluster.hypervisortype));
+                            array1.push("&hypervisor=" + encodeURIComponent(args.data.returnedCluster.hypervisortype));
                         } else {
                             cloudStack.dialog.notice({
                                 message: "Error: args.data.cluster.hypervisor is undefined. So is args.data.returnedCluster.hypervisortype (zone-wide-primary-storage)"
@@ -4495,7 +4493,7 @@
                             path = "/" + path;
                         url = smbURL(server, path);
                         array1.push("&details[0].user=" + args.data.primaryStorage.smbUsername);
-                        array1.push("&details[1].password=" + todb(args.data.primaryStorage.smbPassword));
+                        array1.push("&details[1].password=" + encodeURIComponent(args.data.primaryStorage.smbPassword));
                         array1.push("&details[2].domain=" + args.data.primaryStorage.smbDomain);
                     } else if (args.data.primaryStorage.protocol == "PreSetup") {
                         var path = args.data.primaryStorage.path;
@@ -4536,10 +4534,10 @@
                         var lun = args.data.primaryStorage.lun;
                         url = iscsiURL(server, iqn, lun);
                     }
-                    array1.push("&url=" + todb(url));
+                    array1.push("&url=" + encodeURIComponent(url));
 
                     if (args.data.primaryStorage.storageTags != null && args.data.primaryStorage.storageTags.length > 0)
-                        array1.push("&tags=" + todb(args.data.primaryStorage.storageTags));
+                        array1.push("&tags=" + encodeURIComponent(args.data.primaryStorage.storageTags));
 
                     $.ajax({
                         url: createURL("createStoragePool" + array1.join("")),
diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js
index 43c42f9..059b152 100644
--- a/ui/tests/test.widget.listView.js
+++ b/ui/tests/test.widget.listView.js
@@ -43,11 +43,11 @@
         var $toolbar = $listView.find('> .toolbar');
         var $table = $listView.find('> .data-table');
 
-        equal($listView.size(), 1, 'List view present');
-        equal($toolbar.size(), 1, 'Toolbar present');
-        equal($table.size(), 1, 'Data table div present');
-        equal($table.find('> .fixed-header table thead tr').size(), 1, 'Fixed header present');
-        equal($table.find('> table.body tbody').size(), 1, 'Body table present');
+        equal($listView.length, 1, 'List view present');
+        equal($toolbar.length, 1, 'Toolbar present');
+        equal($table.length, 1, 'Data table div present');
+        equal($table.find('> .fixed-header table thead tr').length, 1, 'Fixed header present');
+        equal($table.find('> table.body tbody').length, 1, 'Body table present');
     });
 
     test('Fields: basic', function() {
@@ -60,7 +60,7 @@
         });
         var $fields = $listView.find('.fixed-header table thead tr th');
 
-        equal($fields.size(), 1, 'Column present');
+        equal($fields.length, 1, 'Column present');
         ok($fields.hasClass('fieldA'), 'Has ID as classname');
         equal($fields.html(), 'TestFieldA', 'Has correct label');
     });
@@ -82,7 +82,7 @@
         $.each(testFields, function(k, v) {
             var $field = $fields.filter('.' + k);
 
-            equal($field.size(), 1, k + '-> Column present');
+            equal($field.length, 1, k + '-> Column present');
             equal($field.html(), v.label, k + '-> Has correct label');
         });
     });
@@ -90,8 +90,8 @@
     test('Data loading state', function() {
         var $listView = listView();
 
-        equal($listView.find('table.body tr.loading').size(), 1, 'Row has loading state');
-        equal($listView.find('table.body tr.loading td.loading.icon').size(), 1, 'Row cell has loading icon');
+        equal($listView.find('table.body tr.loading').length, 1, 'Row has loading state');
+        equal($listView.find('table.body tr.loading td.loading.icon').length, 1, 'Row cell has loading icon');
     });
 
     asyncTest('Data provider: basic', function() {
@@ -111,7 +111,7 @@
             }
         });
 
-        equal($listView.find('.data-table table.body tbody tr.empty td').size(), 1, 'Body table has empty table row');
+        equal($listView.find('.data-table table.body tbody tr.empty td').length, 1, 'Body table has empty table row');
         equal($listView.find('.data-table table.body tbody tr.empty td').html(), 'label.no.data', 'Empty contents notice displayed');
     });
 
@@ -134,8 +134,8 @@
             }
         });
 
-        equal($listView.find('table.body tbody tr').size(), 1, 'Body table has table row');
-        equal($listView.find('table.body tbody tr td').size(), 2, 'Body table has table cells');
+        equal($listView.find('table.body tbody tr').length, 1, 'Body table has table row');
+        equal($listView.find('table.body tbody tr td').length, 2, 'Body table has table cells');
         equal($listView.find('table.body tbody tr td.fieldA > span').html(), 'FieldDataA', 'FieldDataA content present');
         equal($listView.find('table.body tbody tr td.fieldB > span').html(), 'FieldDataB', 'FieldDataB content present');
     });
@@ -163,7 +163,7 @@
             }
         });
 
-        equal($listView.find('table.body tbody tr').size(), 3, 'Body table has correct # of table rows');
+        equal($listView.find('table.body tbody tr').length, 3, 'Body table has correct # of table rows');
 
         $(testData).map(function(index, data) {
             var $tr = $listView.find('table.body tbody tr').filter(function() {
@@ -198,9 +198,9 @@
             }
         });
 
-        equal($listView.find('table tr th').size(), 2, 'Correct number of header columns present');
-        equal($listView.find('table.body tbody tr td').size(), 2, 'Correct number of data body columns present');
-        ok(!$listView.find('table.body tbody td.fieldHidden').size(), 'Hidden field not present');
+        equal($listView.find('table tr th').length, 2, 'Correct number of header columns present');
+        equal($listView.find('table.body tbody tr td').length, 2, 'Correct number of data body columns present');
+        ok(!$listView.find('table.body tbody td.fieldHidden').length, 'Hidden field not present');
     });
 
     test('Filter dropdown', function() {
@@ -229,7 +229,7 @@
         var $filters = $listView.find('.filters select');
 
         var testFilterDropdownContent = function() {
-            equal($filters.find('option').size(), 2, 'Correct # of filters present');
+            equal($filters.find('option').length, 2, 'Correct # of filters present');
             equal($filters.find('option:first').html(), 'FilterOnLabel', 'Filter on label present');
             equal($filters.find('option:last').html(), 'FilterOffLabel', 'Filter off label present');
         };
diff --git a/usage/pom.xml b/usage/pom.xml
index 429da5e..031b9ff 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -1,216 +1,217 @@
-<!-- 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. -->
+<!--
+  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-usage</artifactId>
-  <name>Apache CloudStack Usage Server</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-api</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-schema</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-components-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
+    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-usage</artifactId>
+    <name>Apache CloudStack Usage Server</name>
+    <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-framework-quota</artifactId>
-        <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-daemon</groupId>
-      <artifactId>commons-daemon</artifactId>
-    </dependency>
-     <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <version>${cs.mysql.version}</version>
-      <scope>provided</scope>
-    </dependency>
-     <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-api</artifactId>
-        <version>1.7.22</version>
-      </dependency>
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-log4j12</artifactId>
-        <version>1.7.22</version>
-      </dependency>
-    <dependency>
-      <groupId>org.dbunit</groupId>
-      <artifactId>dbunit</artifactId>
-      <version>2.5.4</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <resources>
-      <resource>
-        <directory>resources</directory>
-      </resource>
-    </resources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <excludes>
-            <exclude>com/cloud/usage/UsageManagerTest.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>copy-dependencies</id>
-            <phase>package</phase>
-            <goals>
-              <goal>copy-dependencies</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
-              <includeScope>runtime</includeScope>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <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/transformed">
-                  <fileset dir="${basedir}/../client/conf">
-                    <include name="**/db.properties.in" />
-                  </fileset>
-                  <globmapper from="*.in" to="*" />
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}" />
-                    </filterreader>
-                  </filterchain>
-                </copy>
-              </target>
-              <target>
-                <copy overwrite="true" todir="${basedir}/target/transformed">
-                  <fileset dir="${basedir}/conf">
-                    <include name="*.in" />
-                  </fileset>
-                  <globmapper from="*.in" to="*" />
-                  <filterchain>
-                    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
-                      <param type="propertiesfile" value="${cs.replace.properties}" />
-                    </filterreader>
-                  </filterchain>
-                </copy>
-              </target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>usage</id>
-      <activation>
-        <property>
-          <name>run</name>
-        </property>
-      </activation>
-      <build>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-schema</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-components-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-quota</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-daemon</groupId>
+            <artifactId>commons-daemon</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dbunit</groupId>
+            <artifactId>dbunit</artifactId>
+            <version>${cs.dbunit.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
         <plugins>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-            <dependencies>
-              <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-usage</artifactId>
-                <version>${project.version}</version>
-              </dependency>
-            </dependencies>
-            <executions>
-              <execution>
-                <phase>process-test-resources</phase>
-                <id>run-usage</id>
-                <goals>
-                  <goal>java</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <includeProjectDependencies>true</includeProjectDependencies>
-              <includePluginDependencies>true</includePluginDependencies>
-              <executableDependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-usage</artifactId>
-              </executableDependency>
-              <mainClass>com.cloud.usage.UsageServer</mainClass>
-              <arguments />
-              <systemProperties>
-                <systemProperty>
-                  <key>catalina.home</key>
-                  <value>${project.parent.basedir}/utils</value>
-                </systemProperty>
-              </systemProperties>
-            </configuration>
-          </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>com/cloud/usage/UsageManagerTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
+                            <includeScope>runtime</includeScope>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <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/transformed">
+                                    <fileset dir="${basedir}/../client/conf">
+                                        <include name="**/db.properties.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                            </target>
+                            <target>
+                                <copy overwrite="true" todir="${basedir}/target/transformed">
+                                    <fileset dir="${basedir}/conf">
+                                        <include name="*.in" />
+                                    </fileset>
+                                    <globmapper from="*.in" to="*" />
+                                    <filterchain>
+                                        <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+                                            <param type="propertiesfile" value="${cs.replace.properties}" />
+                                        </filterreader>
+                                    </filterchain>
+                                </copy>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>integration</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+    </build>
+    <profiles>
+        <profile>
+            <id>usage</id>
+            <activation>
+                <property>
+                    <name>run</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.apache.cloudstack</groupId>
+                                <artifactId>cloud-usage</artifactId>
+                                <version>${project.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <phase>process-test-resources</phase>
+                                <id>run-usage</id>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <includeProjectDependencies>true</includeProjectDependencies>
+                            <includePluginDependencies>true</includePluginDependencies>
+                            <executableDependency>
+                                <groupId>org.apache.cloudstack</groupId>
+                                <artifactId>cloud-usage</artifactId>
+                            </executableDependency>
+                            <mainClass>com.cloud.usage.UsageServer</mainClass>
+                            <arguments />
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>catalina.home</key>
+                                    <value>${project.parent.basedir}/utils</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>integration</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/usage/src/com/cloud/usage/StorageTypes.java b/usage/src/main/java/com/cloud/usage/StorageTypes.java
similarity index 100%
rename from usage/src/com/cloud/usage/StorageTypes.java
rename to usage/src/main/java/com/cloud/usage/StorageTypes.java
diff --git a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
similarity index 100%
rename from usage/src/com/cloud/usage/UsageAlertManagerImpl.java
rename to usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
diff --git a/usage/src/com/cloud/usage/UsageManager.java b/usage/src/main/java/com/cloud/usage/UsageManager.java
similarity index 100%
rename from usage/src/com/cloud/usage/UsageManager.java
rename to usage/src/main/java/com/cloud/usage/UsageManager.java
diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java
similarity index 100%
rename from usage/src/com/cloud/usage/UsageManagerImpl.java
rename to usage/src/main/java/com/cloud/usage/UsageManagerImpl.java
diff --git a/usage/src/com/cloud/usage/UsageSanityChecker.java b/usage/src/main/java/com/cloud/usage/UsageSanityChecker.java
similarity index 100%
rename from usage/src/com/cloud/usage/UsageSanityChecker.java
rename to usage/src/main/java/com/cloud/usage/UsageSanityChecker.java
diff --git a/usage/src/com/cloud/usage/UsageServer.java b/usage/src/main/java/com/cloud/usage/UsageServer.java
similarity index 100%
rename from usage/src/com/cloud/usage/UsageServer.java
rename to usage/src/main/java/com/cloud/usage/UsageServer.java
diff --git a/usage/src/com/cloud/usage/parser/IPAddressUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/IPAddressUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/IPAddressUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/IPAddressUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/LoadBalancerUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/LoadBalancerUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/LoadBalancerUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworkOfferingUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/NetworkOfferingUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/NetworkOfferingUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/NetworkUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworkUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/NetworkUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/NetworkUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/PortForwardingUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/PortForwardingUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/PortForwardingUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/SecurityGroupUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/SecurityGroupUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/SecurityGroupUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/StorageUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/StorageUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/StorageUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/StorageUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/UsageParser.java b/usage/src/main/java/com/cloud/usage/parser/UsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/UsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/UsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VMInstanceUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VMInstanceUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VMInstanceUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java b/usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java
diff --git a/usage/src/com/cloud/usage/parser/VMSnapshotUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VMSnapshotUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/VPNUserUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VPNUserUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VPNUserUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VPNUserUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/VmDiskUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VmDiskUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VmDiskUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VmDiskUsageParser.java
diff --git a/usage/src/com/cloud/usage/parser/VolumeUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java
similarity index 100%
rename from usage/src/com/cloud/usage/parser/VolumeUsageParser.java
rename to usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java
diff --git a/usage/resources/usageApplicationContext.xml b/usage/src/main/resources/usageApplicationContext.xml
similarity index 100%
rename from usage/resources/usageApplicationContext.xml
rename to usage/src/main/resources/usageApplicationContext.xml
diff --git a/usage/test/com/cloud/usage/UsageManagerTest.java b/usage/src/test/java/com/cloud/usage/UsageManagerTest.java
similarity index 100%
rename from usage/test/com/cloud/usage/UsageManagerTest.java
rename to usage/src/test/java/com/cloud/usage/UsageManagerTest.java
diff --git a/usage/test/com/cloud/usage/UsageManagerTestConfiguration.java b/usage/src/test/java/com/cloud/usage/UsageManagerTestConfiguration.java
similarity index 100%
rename from usage/test/com/cloud/usage/UsageManagerTestConfiguration.java
rename to usage/src/test/java/com/cloud/usage/UsageManagerTestConfiguration.java
diff --git a/usage/test/com/cloud/usage/UsageSanityCheckerIT.java b/usage/src/test/java/com/cloud/usage/UsageSanityCheckerIT.java
similarity index 100%
rename from usage/test/com/cloud/usage/UsageSanityCheckerIT.java
rename to usage/src/test/java/com/cloud/usage/UsageSanityCheckerIT.java
diff --git a/usage/test/com/cloud/usage/UsageSanityCheckerTest.java b/usage/src/test/java/com/cloud/usage/UsageSanityCheckerTest.java
similarity index 100%
rename from usage/test/com/cloud/usage/UsageSanityCheckerTest.java
rename to usage/src/test/java/com/cloud/usage/UsageSanityCheckerTest.java
diff --git a/usage/test/resources/UsageManagerTestContext.xml b/usage/src/test/resources/UsageManagerTestContext.xml
similarity index 100%
rename from usage/test/resources/UsageManagerTestContext.xml
rename to usage/src/test/resources/UsageManagerTestContext.xml
diff --git a/usage/test/resources/cloud1.xml b/usage/src/test/resources/cloud1.xml
similarity index 100%
rename from usage/test/resources/cloud1.xml
rename to usage/src/test/resources/cloud1.xml
diff --git a/usage/test/resources/cloud2.xml b/usage/src/test/resources/cloud2.xml
similarity index 100%
rename from usage/test/resources/cloud2.xml
rename to usage/src/test/resources/cloud2.xml
diff --git a/usage/test/resources/cloud3.xml b/usage/src/test/resources/cloud3.xml
similarity index 100%
rename from usage/test/resources/cloud3.xml
rename to usage/src/test/resources/cloud3.xml
diff --git a/usage/test/resources/cloud_usage1.xml b/usage/src/test/resources/cloud_usage1.xml
similarity index 100%
rename from usage/test/resources/cloud_usage1.xml
rename to usage/src/test/resources/cloud_usage1.xml
diff --git a/usage/test/resources/cloud_usage2.xml b/usage/src/test/resources/cloud_usage2.xml
similarity index 100%
rename from usage/test/resources/cloud_usage2.xml
rename to usage/src/test/resources/cloud_usage2.xml
diff --git a/usage/test/resources/cloud_usage3.xml b/usage/src/test/resources/cloud_usage3.xml
similarity index 100%
rename from usage/test/resources/cloud_usage3.xml
rename to usage/src/test/resources/cloud_usage3.xml
diff --git a/usage/test/resources/db.properties b/usage/src/test/resources/db.properties
similarity index 100%
rename from usage/test/resources/db.properties
rename to usage/src/test/resources/db.properties
diff --git a/utils/pom.xml b/utils/pom.xml
index 923163b..43b6503 100755
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -1,250 +1,231 @@
 <!--
+  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
 
-    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
 
-      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.
-
+  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-utils</artifactId>
-  <name>Apache CloudStack Utils</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-    <relativePath>../pom.xml</relativePath>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-managed-context</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-ca</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.aspectj</groupId>
-      <artifactId>aspectjweaver</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>cglib</groupId>
-      <artifactId>cglib-nodep</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-validator</groupId>
-      <artifactId>commons-validator</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcprov-jdk15on</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcpkix-jdk15on</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.jcraft</groupId>
-      <artifactId>jsch</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jasypt</groupId>
-      <artifactId>jasypt</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.trilead</groupId>
-      <artifactId>trilead-ssh2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.amazonaws</groupId>
-      <artifactId>aws-java-sdk-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.amazonaws</groupId>
-      <artifactId>aws-java-sdk-s3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>apache-log4j-extras</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.googlecode.java-ipv6</groupId>
-      <artifactId>java-ipv6</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-configuration</groupId>
-      <artifactId>commons-configuration</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.servlet</groupId>
-      <artifactId>javax.servlet-api</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <!-- Test dependency in mysql for db tests -->
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <scope>provided</scope>
-      <version>${cs.commons-io.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.reflections</groupId>
-      <artifactId>reflections</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.owasp.esapi</groupId>
-      <artifactId>esapi</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis-ext</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>xerces</groupId>
-          <artifactId>xmlParserAPIs</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>commons-beanutils</groupId>
-          <artifactId>commons-beanutils-core</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.opensaml</groupId>
-      <artifactId>opensaml</artifactId>
-      <version>${cs.opensaml.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-net</groupId>
-      <artifactId>commons-net</artifactId>
-      <version>3.6</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava-testlib</artifactId>
-      <version>${cs.guava-testlib.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>${cs.jackson.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <sourceDirectory>src/main/java</sourceDirectory>
-    <testSourceDirectory>src/test/java</testSourceDirectory>
-    <outputDirectory>target/classes</outputDirectory>
-    <testOutputDirectory>target/test-classes</testOutputDirectory>
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-      </resource>
-    </resources>
-    <testResources>
-      <testResource>
-        <directory>src/test/resources</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <excludes>
-            <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
-            <exclude>com/cloud/utils/db/*Test*</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>integration</id>
-      <build>
+    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-utils</artifactId>
+    <name>Apache CloudStack Utils</name>
+    <parent>
+        <groupId>org.apache.cloudstack</groupId>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-managed-context</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-ca</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-validator</groupId>
+            <artifactId>commons-validator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jasypt</groupId>
+            <artifactId>jasypt</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.trilead</groupId>
+            <artifactId>trilead-ssh2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.amazonaws</groupId>
+            <artifactId>aws-java-sdk-s3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>apache-log4j-extras</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.googlecode.java-ipv6</groupId>
+            <artifactId>java-ipv6</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Test dependency in mysql for db tests -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>xml-apis</groupId>
+                    <artifactId>xml-apis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.owasp.esapi</groupId>
+            <artifactId>esapi</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>xml-apis</groupId>
+                    <artifactId>xml-apis</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>xml-apis</groupId>
+                    <artifactId>xml-apis-ext</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>xerces</groupId>
+                    <artifactId>xmlParserAPIs</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-beanutils</groupId>
+                    <artifactId>commons-beanutils-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.opensaml</groupId>
+            <artifactId>opensaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava-testlib</artifactId>
+            <version>${cs.guava-testlib.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${cs.jackson.version}</version>
+        </dependency>
+    </dependencies>
+    <build>
         <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
+                        <exclude>com/cloud/utils/db/*Test*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
         </plugins>
-      </build>
-    </profile>
-  </profiles>
+    </build>
+    <profiles>
+        <profile>
+            <id>integration</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/utils/src/main/java/com/cloud/maint/Version.java b/utils/src/main/java/com/cloud/maint/Version.java
deleted file mode 100644
index 925806e..0000000
--- a/utils/src/main/java/com/cloud/maint/Version.java
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package com.cloud.maint;
-
-public class Version {
-    /**
-     * Compares two version strings and see which one is higher version.
-     * @param ver1
-     * @param ver2
-     * @return positive if ver1 is higher.  negative if ver1 is lower; zero if the same.
-     */
-    public static int compare(String ver1, String ver2) {
-        String[] tokens1 = ver1.split("[.]");
-        String[] tokens2 = ver2.split("[.]");
-//        assert(tokens1.length <= tokens2.length);
-
-        int compareLength = Math.min(tokens1.length, tokens2.length);
-        for (int i = 0; i < compareLength; i++) {
-            long version1 = Long.parseLong(tokens1[i]);
-            long version2 = Long.parseLong(tokens2[i]);
-            if (version1 != version2) {
-                return version1 < version2 ? -1 : 1;
-            }
-        }
-
-        if (tokens1.length > tokens2.length) {
-            return 1;
-        } else if (tokens1.length < tokens2.length) {
-            return -1;
-        }
-
-        return 0;
-    }
-
-    public static String trimToPatch(String version) {
-        int index = version.indexOf("-");
-
-        if (index > 0)
-            version = version.substring(0, index);
-
-        String[] tokens = version.split("[.]");
-
-        if (tokens.length < 3)
-            return "0";
-        return tokens[0] + "." + tokens[1] + "." + tokens[2];
-    }
-
-    public static String trimRouterVersion(String version) {
-        String[] tokens = version.split(" ");
-        if (tokens.length >= 3 && tokens[2].matches("[0-9]+(\\.[0-9]+)*")) {
-            return tokens[2];
-        }
-        return "0";
-    }
-
-    public static void main(String[] args) {
-        System.out.println("Result is " + compare(args[0], args[1]));
-    }
-
-}
diff --git a/utils/src/main/java/com/cloud/utils/DateUtil.java b/utils/src/main/java/com/cloud/utils/DateUtil.java
index 9f046d1..8c55268 100644
--- a/utils/src/main/java/com/cloud/utils/DateUtil.java
+++ b/utils/src/main/java/com/cloud/utils/DateUtil.java
@@ -26,6 +26,10 @@
 import java.util.Date;
 import java.util.TimeZone;
 
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.OffsetDateTime;
+
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class DateUtil {
@@ -33,19 +37,33 @@
     public static final String YYYYMMDD_FORMAT = "yyyyMMddHHmmss";
     private static final DateFormat s_outputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
 
+    private static final DateTimeFormatter[] parseFormats = new DateTimeFormatter[]{
+        DateTimeFormatter.ISO_OFFSET_DATE_TIME,
+        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"),
+        DateTimeFormatter.ISO_INSTANT,
+        // with milliseconds
+        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSX"),
+        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ"),
+        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"),
+        // legacy and non-sensical format
+        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'Z")
+    };
+
     public static Date currentGMTTime() {
         // Date object always stores miliseconds offset based on GMT internally
         return new Date();
     }
 
-    // yyyy-MM-ddTHH:mm:ssZZZZ or yyyy-MM-ddTHH:mm:ssZxxxx
     public static Date parseTZDateString(String str) throws ParseException {
-        try {
-            return s_outputFormat.parse(str);
-        } catch (ParseException e) {
-            final DateFormat dfParse = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'Z");
-            return dfParse.parse(str);
+        for (DateTimeFormatter formatter : parseFormats) {
+            try {
+                OffsetDateTime dt = OffsetDateTime.parse(str, formatter);
+                return Date.from(dt.toInstant());
+            } catch (DateTimeParseException e) {
+                // do nothing
+            }
         }
+        throw new ParseException("Unparseable date: \"" + str + "\"", 0);
     }
 
     public static Date parseDateString(TimeZone tz, String dateString) {
diff --git a/utils/src/main/java/com/cloud/utils/StringUtils.java b/utils/src/main/java/com/cloud/utils/StringUtils.java
index f7ef0bc..e858bee 100644
--- a/utils/src/main/java/com/cloud/utils/StringUtils.java
+++ b/utils/src/main/java/com/cloud/utils/StringUtils.java
@@ -28,8 +28,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.owasp.esapi.StringUtilities;
-
 public class StringUtils {
     private static final char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 
@@ -75,13 +73,22 @@
     public static String join(final String delimiter, final Object... components) {
         return org.apache.commons.lang.StringUtils.join(components, delimiter);
     }
+    /**
+     * @deprecated
+     * Please use org.apache.commons.lang.StringUtils.isBlank() as a replacement
+     */
+    @Deprecated
+    public static boolean isBlank(String str) {
+        return org.apache.commons.lang.StringUtils.isBlank(str);
+    }
 
+    /**
+     * @deprecated
+     * Please use org.apache.commons.lang.StringUtils.isNotBlank() as a replacement
+     */
+    @Deprecated
     public static boolean isNotBlank(final String str) {
-        if (str != null && str.trim().length() > 0) {
-            return true;
-        }
-
-        return false;
+        return org.apache.commons.lang.StringUtils.isNotBlank(str);
     }
 
     public static String cleanupTags(String tags) {
@@ -254,24 +261,6 @@
         return lstTags1.containsAll(lstTags2) && lstTags2.containsAll(lstTags1);
     }
 
-    public static String stripControlCharacters(final String s) {
-        return StringUtilities.stripControls(s);
-    }
-
-    public static int formatForOutput(final String text, final int start, final int columns, final char separator) {
-        if (start >= text.length()) {
-            return -1;
-        }
-
-        int end = start + columns;
-        if (end > text.length()) {
-            end = text.length();
-        }
-        final String searchable = text.substring(start, end);
-        final int found = searchable.lastIndexOf(separator);
-        return found > 0 ? found : end - start;
-    }
-
     public static Map<String, String> stringToMap(final String s) {
         final Map<String, String> map = new HashMap<String, String>();
         final String[] elements = s.split(";");
diff --git a/utils/src/main/java/com/cloud/utils/db/UUIDManager.java b/utils/src/main/java/com/cloud/utils/db/UUIDManager.java
index cac1876..737480a 100644
--- a/utils/src/main/java/com/cloud/utils/db/UUIDManager.java
+++ b/utils/src/main/java/com/cloud/utils/db/UUIDManager.java
@@ -45,4 +45,6 @@
      * .
      */
     <T> void checkUuidSimple(String uuid, Class<T> entityType);
+
+    public <T> String getUuid(Class<T> entityType, Long customId);
 }
diff --git a/utils/src/main/java/com/cloud/utils/net/MacAddress.java b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
index b9118cf..d7ac9e3 100644
--- a/utils/src/main/java/com/cloud/utils/net/MacAddress.java
+++ b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
@@ -31,12 +31,10 @@
 
 import org.apache.log4j.Logger;
 
-import com.cloud.utils.NumbersUtil;
-
 /**
- * copied from the public domain utility from John Burkard.
- * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
- * @version 2.1.3
+ * This class retrieves the (first) MAC address for the machine is it is loaded on and stores it statically for retrieval.
+ * It can also be used for formatting MAC addresses.
+ * copied fnd addpeted rom the public domain utility from John Burkard.
  **/
 public class MacAddress {
     private static final Logger s_logger = Logger.getLogger(MacAddress.class);
@@ -70,19 +68,6 @@
         formatter.format("%02x%s%02x%s%02x%s%02x%s%02x%s%02x", _addr >> 40 & 0xff, separator, _addr >> 32 & 0xff, separator, _addr >> 24 & 0xff, separator,
             _addr >> 16 & 0xff, separator, _addr >> 8 & 0xff, separator, _addr & 0xff);
         return buff.toString();
-
-        /*
-
-        String str = Long.toHexString(_addr);
-
-        for (int i = str.length() - 1; i >= 0; i--) {
-            buff.append(str.charAt(i));
-            if (separator != null && (str.length() - i) % 2 == 0) {
-                buff.append(separator);
-            }
-        }
-        return buff.reverse().toString();
-         */
     }
 
     @Override
@@ -242,13 +227,6 @@
         return null;
     }
 
-    public static void main(String[] args) {
-        MacAddress addr = MacAddress.getMacAddress();
-        System.out.println("addr in integer is " + addr.toLong());
-        System.out.println("addr in bytes is " + NumbersUtil.bytesToString(addr.toByteArray(), 0, addr.toByteArray().length));
-        System.out.println("addr in char is " + addr.toString(":"));
-    }
-
     /**
      * Parses a <code>long</code> from a hex encoded number. This method will skip
      * all characters that are not 0-9 and a-f (the String is lower cased first).
@@ -258,7 +236,7 @@
      * @return a <code>long</code>
      * @throws NullPointerException if the String is <code>null</code>
      */
-    public static long parseLong(String s) throws NullPointerException {
+    private static long parseLong(String s) throws NullPointerException {
         s = s.toLowerCase();
         long out = 0;
         byte shifts = 0;
@@ -279,35 +257,6 @@
     }
 
     /**
-     * Parses an <code>int</code> from a hex encoded number. This method will skip
-     * all characters that are not 0-9 and a-f (the String is lower cased first).
-     * Returns 0 if the String does not contain any interesting characters.
-     *
-     * @param s the String to extract an <code>int</code> from, may not be <code>null</code>
-     * @return an <code>int</code>
-     * @throws NullPointerException if the String is <code>null</code>
-     */
-    public static int parseInt(String s) throws NullPointerException {
-        s = s.toLowerCase();
-        int out = 0;
-        byte shifts = 0;
-        char c;
-        for (int i = 0; i < s.length() && shifts < 8; i++) {
-            c = s.charAt(i);
-            if ((c > 47) && (c < 58)) {
-                out <<= 4;
-                ++shifts;
-                out |= c - 48;
-            } else if ((c > 96) && (c < 103)) {
-                ++shifts;
-                out <<= 4;
-                out |= c - 87;
-            }
-        }
-        return out;
-    }
-
-    /**
      * Parses a <code>short</code> from a hex encoded number. This method will skip
      * all characters that are not 0-9 and a-f (the String is lower cased first).
      * Returns 0 if the String does not contain any interesting characters.
@@ -316,7 +265,7 @@
      * @return a <code>short</code>
      * @throws NullPointerException if the String is <code>null</code>
      */
-    public static short parseShort(String s) throws NullPointerException {
+    private static short parseShort(String s) throws NullPointerException {
         s = s.toLowerCase();
         short out = 0;
         byte shifts = 0;
@@ -335,33 +284,4 @@
         }
         return out;
     }
-
-    /**
-     * Parses a <code>byte</code> from a hex encoded number. This method will skip
-     * all characters that are not 0-9 and a-f (the String is lower cased first).
-     * Returns 0 if the String does not contain any interesting characters.
-     *
-     * @param s the String to extract a <code>byte</code> from, may not be <code>null</code>
-     * @return a <code>byte</code>
-     * @throws NullPointerException if the String is <code>null</code>
-     */
-    public static byte parseByte(String s) throws NullPointerException {
-        s = s.toLowerCase();
-        byte out = 0;
-        byte shifts = 0;
-        char c;
-        for (int i = 0; i < s.length() && shifts < 2; i++) {
-            c = s.charAt(i);
-            if ((c > 47) && (c < 58)) {
-                out <<= 4;
-                ++shifts;
-                out |= c - 48;
-            } else if ((c > 96) && (c < 103)) {
-                ++shifts;
-                out <<= 4;
-                out |= c - 87;
-            }
-        }
-        return out;
-    }
 }
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 afe73f1..dce6c25 100644
--- a/utils/src/main/java/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/main/java/com/cloud/utils/net/NetUtils.java
@@ -23,9 +23,9 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.math.BigInteger;
-import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
@@ -88,6 +88,10 @@
     private final static Random s_rand = new Random(System.currentTimeMillis());
     private final static long prefix = 0x1e;
 
+    // RFC4291 IPv6 EUI-64
+    public final static int IPV6_EUI64_11TH_BYTE = -1;
+    public final static int IPV6_EUI64_12TH_BYTE = -2;
+
     public static long createSequenceBasedMacAddress(final long macAddress, long globalConfig) {
         /*
             Logic for generating MAC address:
@@ -113,6 +117,18 @@
         return "localhost";
     }
 
+    public static String getCanonicalHostName() {
+        try {
+            InetAddress localAddr = InetAddress.getLocalHost();
+            if (localAddr != null) {
+                return localAddr.getCanonicalHostName();
+            }
+        } catch (UnknownHostException e) {
+            s_logger.warn("UnknownHostException when trying to get canonical host name. ", e);
+        }
+        return "localhost";
+    }
+
     public static InetAddress getLocalInetAddress() {
         try {
             return InetAddress.getLocalHost();
@@ -479,9 +495,23 @@
         return validator.isValidInet4Address(ip);
     }
 
+    /**
+     * Returns true if the given IPv4 address is in the specific Ipv4 range
+     */
+    public static boolean isIpInRange(final String ipInRange, final String startIP, final String endIP) {
+        if (ipInRange == null || !validIpRange(startIP, endIP))
+            return false;
+
+        final long ipInRangeLong = NetUtils.ip2Long(ipInRange);
+        final long startIPLong = NetUtils.ip2Long(startIP);
+        final long endIPLong = NetUtils.ip2Long(endIP);
+
+        return startIPLong <= ipInRangeLong && ipInRangeLong <= endIPLong;
+    }
+
     public static boolean is31PrefixCidr(final String cidr) {
         final boolean isValidCird = isValidIp4Cidr(cidr);
-        if (isValidCird){
+        if (isValidCird) {
             final String[] cidrPair = cidr.split("\\/");
             final String cidrSize = cidrPair[1];
 
@@ -1568,4 +1598,43 @@
         return EUI64Address(IPv6Network.LINK_LOCAL_NETWORK, macAddress);
     }
 
+    /**
+     * When using StateLess Address AutoConfiguration (SLAAC) for IPv6 the addresses
+     * choosen by hosts in a network are based on the 48-bit MAC address and this is expanded to 64-bits
+     * with EUI-64
+     * FFFE is inserted into the address and these can be identified
+     *
+     * By converting the IPv6 Address to a byte array we can check the 11th and 12th byte to see if the
+     * address is EUI064.
+     *
+     * See RFC4291 for more information
+     *
+     * @param address IPv6Address to be checked
+     * @return True if Address is EUI-64 IPv6
+     */
+    public static boolean isIPv6EUI64(final IPv6Address address) {
+        byte[] bytes = address.toByteArray();
+        return (bytes[11] == IPV6_EUI64_11TH_BYTE && bytes[12] == IPV6_EUI64_12TH_BYTE);
+    }
+
+    public static boolean isIPv6EUI64(final String address) {
+        return NetUtils.isIPv6EUI64(IPv6Address.fromString(address));
+    }
+
+    /**
+     * Returns true if the given IP address is IPv4 or false if it is an IPv6. If it is an invalid IP address it throws an exception.
+     */
+    public static boolean isIpv4(String ipAddr) {
+        boolean isIpv4 = true;
+        if (ipAddr != null) {
+            if (!NetUtils.isValidIp4(ipAddr)) {
+                isIpv4 = false;
+            }
+            if (!NetUtils.isValidIp6(ipAddr) && !isIpv4) {
+                throw new IllegalArgumentException("Invalid ip address " + ipAddr);
+            }
+        }
+        return isIpv4;
+    }
+
 }
diff --git a/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java b/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
index 4dfd4e2..9090de7 100755
--- a/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
+++ b/utils/src/main/java/com/cloud/utils/nicira/nvp/plugin/NiciraNvpApiVersion.java
@@ -21,7 +21,7 @@
 
 import org.apache.log4j.Logger;
 
-import com.cloud.maint.Version;
+import org.apache.cloudstack.utils.CloudStackVersion;
 
 public class NiciraNvpApiVersion {
     private static final Logger s_logger = Logger.getLogger(NiciraNvpApiVersion.class);
@@ -33,8 +33,10 @@
     }
 
     public static synchronized boolean isApiVersionLowerThan(String apiVersion){
-        if (niciraApiVersion == null) return false;
-        int compare = Version.compare(niciraApiVersion, apiVersion);
+        if (niciraApiVersion == null) {
+            return false;
+        }
+        int compare = CloudStackVersion.compare(niciraApiVersion, apiVersion);
         return (compare < 0);
     }
 
diff --git a/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java b/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
index 035f69e..8bd2b6f 100644
--- a/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
+++ b/utils/src/main/java/org/apache/cloudstack/utils/CloudStackVersion.java
@@ -39,50 +39,8 @@
  */
 public final class CloudStackVersion implements Comparable<CloudStackVersion> {
 
-    private final static Pattern VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");
-
-    /**
-     *
-     * Parses a <code>String</code> representation of a version that conforms one of the following
-     * formats into a <code>CloudStackVersion</code> instance:
-     * <ul>
-     *     <li><code><major version>.<minor version>.<patch release></code></li>
-     *     <li><code><major version>.<minor version>.<patch release>.<security release></code></li>
-     *     <li><code><major version>.<minor version>.<patch release>.<security release>-<any string></code></li>
-     * </ul>
-     *
-     * If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
-     * will be dropped.
-     *
-     * @param value The value to parse which must be non-blank and conform the formats listed above
-     *
-     * @return <code>value</code> parsed into a <code>CloudStackVersion</code> instance
-     *
-     * @since 4.8.2
-     *
-     */
-    public static CloudStackVersion parse(final String value) {
-
-        // Strip out any legacy patch information from the version string ...
-        final String trimmedValue = substringBefore(value, "-");
-
-        checkArgument(isNotBlank(trimmedValue), CloudStackVersion.class.getName() + ".parse(String) requires a non-blank value");
-        checkArgument(VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + "parse(String) passed " +
-                value + ", but requires a value in the format of int.int.int(.int)(-<legacy patch>)");
-
-        final String[] components = trimmedValue.split("\\.");
-
-        checkState(components != null && (components.length == 3 || components.length == 4), "Expected " + value +
-                " to parse to 3 or 4 positions.");
-
-        final int majorRelease = Integer.valueOf(components[0]);
-        final int minorRelease = Integer.valueOf(components[1]);
-        final int patchRelease = Integer.valueOf(components[2]);
-        final Integer securityRelease = components.length == 3 ? null : Integer.valueOf(components[3]);
-
-        return new CloudStackVersion(majorRelease, minorRelease, patchRelease, securityRelease);
-
-    }
+    private final static Pattern NUMBER_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+");
+    private final static Pattern FULL_VERSION_FORMAT = Pattern.compile("(\\d+\\.){2}(\\d+\\.)?\\d+(-[a-zA-Z]+)?(-\\d+)?(-SNAPSHOT)?");
 
     private final int majorRelease;
     private final int minorRelease;
@@ -106,17 +64,63 @@
 
     }
 
-    private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {
+    /**
+     *
+     * Parses a <code>String</code> representation of a version that conforms one of the following
+     * formats into a <code>CloudStackVersion</code> instance:
+     * <ul>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;</code></li>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;</code></li>
+     *     <li><code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;.&lt;security&gt;.&lt;security&gt;-&lt;any string&gt;</code></li>
+     * </ul>
+     *
+     * If the string contains a suffix that begins with a "-" character, then the "-" and all characters following it
+     * will be dropped.
+     *
+     * @param value The value to parse which must be non-blank and conform the formats listed above
+     *
+     * @return <code>value</code> parsed into a <code>CloudStackVersion</code> instance
+     *
+     * @since 4.8.2
+     *
+     */
+    public static CloudStackVersion parse(final String value) {
 
-        checkArgument(values != null);
-        checkArgument(values.size() == 3 || values.size() == 4);
+        // Strip out any legacy patch information from the version string ...
+        final String trimmedValue = substringBefore(value, "-");
 
-        if (values.size() == 3) {
-            return ImmutableList.<Integer>builder().addAll(values).add(0).build();
-        }
+        checkArgument(isNotBlank(trimmedValue), CloudStackVersion.class.getName() + ".parse(String) requires a non-blank value");
+        checkArgument(NUMBER_VERSION_FORMAT.matcher(trimmedValue).matches(), CloudStackVersion.class.getName() + ".parse(String) passed " +
+                value + ", but requires a value in the format of int.int.int(.int)(-<legacy patch>)");
 
-        return values;
+        final String[] components = trimmedValue.split("\\.");
 
+        checkState(components != null && (components.length == 3 || components.length == 4), "Expected " + value +
+                " to parse to 3 or 4 positions.");
+
+        final int majorRelease = Integer.valueOf(components[0]);
+        final int minorRelease = Integer.valueOf(components[1]);
+        final int patchRelease = Integer.valueOf(components[2]);
+        final Integer securityRelease = components.length == 3 ? null : Integer.valueOf(components[3]);
+
+        return new CloudStackVersion(majorRelease, minorRelease, patchRelease, securityRelease);
+
+    }
+
+    /**
+     * Shortcut method to {@link #parse(String)} and {@link #compareTo(CloudStackVersion)} two versions
+     *
+     * @param version1 the first value to be parsed and compared
+     * @param version2 the second value to be parsed and compared
+     *
+     * @return A value less than zero (0) indicates <code>version1</code> is less than <code>version2</code>.  A value
+     *         equal to zero (0) indicates <code>version1</code> equals <code>version2</code>.  A value greater than zero (0)
+     *         indicates <code>version1</code> is greater than <code>version2</code>.
+     *
+     * @since 4.12.0.0
+     */
+    public static int compare(String version1, String version2) {
+        return parse(version1).compareTo(parse(version2));
     }
 
     /**
@@ -125,7 +129,7 @@
      * A couple of notes about the comparison rules for this method:
      * <ul>
      *     <li>Three position versions are normalized to four position versions with the security release being
-     *         defaulted to zero (0).  For example, for the purposes of comparision, <code>4.8.1</code> would be
+     *         defaulted to zero (0).  For example, for the purposes of comparison, <code>4.8.1</code> would be
      *         normalized to <code>4.8.1.0</code> for all comparison operations.</li>
      *     <li>A three position version with a null security release is considered equal to a four position
      *         version number where the major release, minor release, and patch release are the same and the security
@@ -167,6 +171,43 @@
     }
 
     /**
+     * Trim full version from router version. Valid versions are:
+     *
+     * <ul>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]]</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]]-&lt;branding&gt;</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]][-&lt;branding&gt;]-SNAPSHOT</li>
+     *    <li><code>&lt;major&gt;.&lt;minor&gt;[.&lt;patch&gt;[.&lt;security&gt;]][-&lt;branding&gt;]-&lt;epoch timestamp&gt;</li>
+     * </ul>
+     *
+     * @param version to trim
+     *
+     * @return actual trimmed version
+     */
+    public static String trimRouterVersion(String version) {
+        final String[] tokens = version.split(" ");
+
+        if (tokens.length >= 3 && FULL_VERSION_FORMAT.matcher(tokens[2]).matches()) {
+            return tokens[2];
+        }
+
+        return "0";
+    }
+
+    private static ImmutableList<Integer> normalizeVersionValues(final ImmutableList<Integer> values) {
+
+        checkArgument(values != null);
+        checkArgument(values.size() == 3 || values.size() == 4);
+
+        if (values.size() == 3) {
+            return ImmutableList.<Integer>builder().addAll(values).add(0).build();
+        }
+
+        return values;
+
+    }
+
+    /**
      *
      * @return The components of this version as an {@link ImmutableList} in order of major release, minor release,
      * patch release, and security release
@@ -187,6 +228,22 @@
 
     }
 
+    public int getMajorRelease() {
+        return majorRelease;
+    }
+
+    public int getMinorRelease() {
+        return minorRelease;
+    }
+
+    public int getPatchRelease() {
+        return patchRelease;
+    }
+
+    public Integer getSecurityRelease() {
+        return securityRelease;
+    }
+
     @Override
     public boolean equals(final Object thatObject) {
 
@@ -215,21 +272,4 @@
     public String toString() {
         return Joiner.on(".").join(asList());
     }
-
-    public int getMajorRelease() {
-        return majorRelease;
-    }
-
-    public int getMinorRelease() {
-        return minorRelease;
-    }
-
-    public int getPatchRelease() {
-        return patchRelease;
-    }
-
-    public Integer getSecurityRelease() {
-        return securityRelease;
-    }
-
 }
diff --git a/utils/src/main/java/org/apache/cloudstack/utils/graphite/GraphiteClient.java b/utils/src/main/java/org/apache/cloudstack/utils/graphite/GraphiteClient.java
index 4143f09..9c9d48a 100644
--- a/utils/src/main/java/org/apache/cloudstack/utils/graphite/GraphiteClient.java
+++ b/utils/src/main/java/org/apache/cloudstack/utils/graphite/GraphiteClient.java
@@ -67,7 +67,7 @@
      *
      * @param metrics the metrics as key-value-pairs
      */
-    public void sendMetrics(Map<String, Integer> metrics) {
+    public void sendMetrics(Map<Object, Object> metrics) {
         sendMetrics(metrics, getCurrentSystemTime());
     }
 
@@ -77,12 +77,12 @@
      * @param metrics the metrics as key-value-pairs
      * @param timeStamp the timestamp
      */
-    public void sendMetrics(Map<String, Integer> metrics, long timeStamp) {
+    public void sendMetrics(Map<Object, Object> metrics, long timeStamp) {
         try (DatagramSocket sock = new DatagramSocket()){
             java.security.Security.setProperty("networkaddress.cache.ttl", "0");
             InetAddress addr = InetAddress.getByName(this.graphiteHost);
 
-            for (Map.Entry<String, Integer> metric: metrics.entrySet()) {
+            for (Map.Entry<Object, Object> metric : metrics.entrySet()) {
                 byte[] message = new String(metric.getKey() + " " + metric.getValue() + " " + timeStamp + "\n").getBytes();
                 DatagramPacket packet = new DatagramPacket(message, message.length, addr, graphitePort);
                 sock.send(packet);
diff --git a/utils/src/test/java/com/cloud/utils/DateUtilTest.java b/utils/src/test/java/com/cloud/utils/DateUtilTest.java
index 190adea..98b4d11 100644
--- a/utils/src/test/java/com/cloud/utils/DateUtilTest.java
+++ b/utils/src/test/java/com/cloud/utils/DateUtilTest.java
@@ -21,10 +21,15 @@
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.TimeZone;
 
+import java.time.format.DateTimeFormatter;
+import java.time.OffsetDateTime;
+
 import com.cloud.utils.DateUtil.IntervalType;
 
 import org.junit.Test;
@@ -32,7 +37,6 @@
 import static org.junit.Assert.assertEquals;
 
 public class DateUtilTest {
-
     // command line test tool
     public static void main(String[] args) {
         TimeZone localTimezone = Calendar.getInstance().getTimeZone();
@@ -56,7 +60,7 @@
         String str = dfDate.format(time);
         Date dtParsed = DateUtil.parseTZDateString(str);
 
-        assertEquals(time.toString(), dtParsed.toString());
+        assertEquals(str, time.toString(), dtParsed.toString());
     }
 
     @Test
@@ -66,6 +70,64 @@
         String str = dfDate.format(time);
         Date dtParsed = DateUtil.parseTZDateString(str);
 
-        assertEquals(time.toString(), dtParsed.toString());
+        assertEquals(str, time.toString(), dtParsed.toString());
+    }
+
+    @Test
+    public void zonedTimeFormatIsoOffsetDateTime() throws ParseException {
+        Instant moment = Instant.now();
+        Date time = Date.from(moment);
+        String str = OffsetDateTime.ofInstant(moment, ZoneId.systemDefault()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+        Date dtParsed = DateUtil.parseTZDateString(str);
+
+        assertEquals(str, time.toString(), dtParsed.toString());
+    }
+
+    @Test
+    public void zonedTimeFormatIsoInstant() throws ParseException {
+        Instant moment = Instant.now();
+        Date time = Date.from(moment);
+        String str = OffsetDateTime.ofInstant(moment, ZoneId.systemDefault()).format(DateTimeFormatter.ISO_INSTANT);
+
+        Date dtParsed = DateUtil.parseTZDateString(str);
+
+        assertEquals(str, time.toString(), dtParsed.toString());
+    }
+
+    @Test
+    public void zonedTimeFormatIsoOffsetDateTimeMs() throws ParseException {
+        Instant moment = Instant.now();
+        Date time = Date.from(moment);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSX");
+        String str = OffsetDateTime.ofInstant(moment, ZoneId.systemDefault()).format(formatter);
+
+        Date dtParsed = DateUtil.parseTZDateString(str);
+
+        assertEquals(str, time.toString(), dtParsed.toString());
+    }
+
+    @Test
+    public void zonedTimeFormatIsoInstantMs() throws ParseException {
+        Instant moment = Instant.now();
+        Date time = Date.from(moment);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'");
+        String str = OffsetDateTime.ofInstant(moment, ZoneId.of("UTC")).format(formatter);
+
+        Date dtParsed = DateUtil.parseTZDateString(str);
+
+        assertEquals(str, time.toString(), dtParsed.toString());
+    }
+
+    @Test
+    public void zonedTimeFormatIsoNoColonZMs() throws ParseException {
+        Instant moment = Instant.now();
+        Date time = Date.from(moment);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ");
+        String str = OffsetDateTime.ofInstant(moment, ZoneId.systemDefault()).format(formatter);
+
+        Date dtParsed = DateUtil.parseTZDateString(str);
+
+        assertEquals(str, time.toString(), dtParsed.toString());
     }
 }
diff --git a/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java b/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
index 845a435..42b03b7 100644
--- a/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
+++ b/utils/src/test/java/com/cloud/utils/net/MacAddressTest.java
@@ -51,10 +51,4 @@
     // TODO    public final void testToString() throws Exception {
     // TODO    public final void testGetMacAddress() throws Exception {
     // TODO    public final void testParse() throws Exception {
-    // TODO    public final void testMain() throws Exception {
-    // TODO    public final void testParseLong() throws Exception {
-    // TODO    public final void testParseInt() throws Exception {
-    // TODO    public final void testParseShort() throws Exception {
-    // TODO    public final void testParseByte() throws Exception {
-
 }
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 262e928..173704a 100644
--- a/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java
@@ -680,10 +680,33 @@
     }
 
     @Test
+    public void testIsIpv4() {
+        assertTrue(NetUtils.isIpv4("192.168.1.1"));
+        assertFalse(NetUtils.isIpv4("2a01:4f8:130:2192::2"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIsIpv4ExpectException() {
+        NetUtils.isIpv4("test");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIsIpv4ExpectException2() {
+        NetUtils.isIpv4("2001:db8:300::/64");
+    }
+
     public void testAllIpsOfDefaultNic() {
         final String defaultHostIp = NetUtils.getDefaultHostIp();
         if (defaultHostIp != null) {
             assertTrue(NetUtils.getAllDefaultNicIps().stream().anyMatch(defaultHostIp::contains));
         }
     }
+
+    @Test
+    public void testIsIPv6EUI64() {
+        assertTrue(NetUtils.isIPv6EUI64("fe80::5054:8fff:fe9f:af61"));
+        assertTrue(NetUtils.isIPv6EUI64("2a00:f10:305:0:464:64ff:fe00:4e0"));
+        assertFalse(NetUtils.isIPv6EUI64("2001:db8::100:1"));
+        assertFalse(NetUtils.isIPv6EUI64("2a01:4f9:2a:185f::2"));
+    }
 }
diff --git a/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java b/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
index ab576bb..eb7a76a 100644
--- a/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
+++ b/utils/src/test/java/org/apache/cloudstack/utils/CloudStackVersionTest.java
@@ -31,7 +31,12 @@
 public final class CloudStackVersionTest {
 
     @Test
-    @DataProvider({ "1.2.3, 1.2.3", "1.2.3.4, 1.2.3.4", "1.2.3-12, 1.2.3", "1.2.3.4-14, 1.2.3.4" })
+    @DataProvider({
+        "1.2.3, 1.2.3",
+        "1.2.3.4, 1.2.3.4",
+        "1.2.3-12, 1.2.3",
+        "1.2.3.4-14, 1.2.3.4"
+    })
     public void testValidParse(final String inputValue, final String expectedVersion) {
         final CloudStackVersion version = CloudStackVersion.parse(inputValue);
         assertNotNull(version);
@@ -39,13 +44,26 @@
     }
 
     @Test(expected = IllegalArgumentException.class)
-    @DataProvider({ "1.2", "1", "1.2.3.4.5", "aaaa", "", "  ", "1.2.3.4.5"})
+    @DataProvider({
+        "1.2",
+        "1",
+        "1.2.3.4.5",
+        "aaaa",
+        "",
+        "  ",
+        "1.2.3.4.5"
+    })
     public void testInvalidParse(final String invalidValue) {
         CloudStackVersion.parse(invalidValue);
     }
 
     @Test
-    @DataProvider({ "1.0.0", "1.0.0.0", "1.2.3", "1.2.3.4" })
+    @DataProvider({
+        "1.0.0",
+        "1.0.0.0",
+        "1.2.3",
+        "1.2.3.4"
+    })
     public void testEquals(final String value) {
 
         final CloudStackVersion version = CloudStackVersion.parse(value);
@@ -62,16 +80,19 @@
 
     @Test
     @DataProvider({
-            "1.0.0.0, 1.0.0.0",
-            "1.0.0, 1.0.0",
-            "1.0.0.0, 1.0.0",
-            "1.0.0-10, 1.0.0-10",
-            "1.0.0-10, 1.0.0",
-            "1.0.0.0, 1.0.0-10",
-            "1.0.0.0, 1.0.0.0-10",
-            "1.0.0-10, 1.0.0-11",
-            "1.0.0-10, 1.0.0.0-14",
-            "1.0.0.0-14, 1.0.0.0-15"
+        "1.0.0.0, 1.0.0.0",
+        "1.0.0, 1.0.0",
+        "1.0.0.0, 1.0.0",
+        "1.0.0-10, 1.0.0-10",
+        "1.0.0-10, 1.0.0",
+        "1.0.0.0, 1.0.0-10",
+        "1.0.0.0, 1.0.0.0-10",
+        "1.0.0-10, 1.0.0-11",
+        "1.0.0-10, 1.0.0.0-14",
+        "1.0.0.0-14, 1.0.0.0-15",
+        "1.0.0.0-SNAPSHOT, 1.0.0.0-SNAPSHOT",
+        "1.0.0.0-branding, 1.0.0.0-branding",
+        "1.0.0.0-1518453362, 1.0.0.0-1519453362"
     })
     public void testEqualCompareTo(final String value, final String thatValue) {
 
@@ -88,21 +109,44 @@
 
     @Test
     @DataProvider({
-            "1.2.3.4, 1.2.3",
-            "1.2.3, 1.0.0.0",
-            "1.2.3.4, 1.0.0",
-            "2.0.0, 1.2.3",
-            "2.0.0, 1.2.3.4",
-            "2.0.0.0, 1.2.3",
-            "2.0.0.0, 1.2.3.4",
-            "2.0.0.0, 1.2.3",
-            "1.3.0, 1.2.3.4",
-            "1.3.0.0, 1.2.3.4",
-            "1.3.0.0, 1.2.3",
-            "1.2.3.4-10, 1.0.0.0-5",
-            "1.2.3-10, 1.0.0-5",
-            "1.2.3.4, 1.0.0.0-5",
-            "1.2.3.4-10, 1.0.0"
+        "1.0.0.0, 1.0.0.0",
+        "1.0.0, 1.0.0",
+        "1.0.0.0, 1.0.0",
+        "1.0.0-10, 1.0.0-10",
+        "1.0.0-10, 1.0.0",
+        "1.0.0.0, 1.0.0-10",
+        "1.0.0.0, 1.0.0.0-10",
+        "1.0.0-10, 1.0.0-11",
+        "1.0.0-10, 1.0.0.0-14",
+        "1.0.0.0-14, 1.0.0.0-15",
+        "1.0.0.0-SNAPSHOT, 1.0.0.0-SNAPSHOT",
+        "1.0.0.0-branding, 1.0.0.0-branding",
+        "1.0.0.0-1518453362, 1.0.0.0-1519453362"
+    })
+    public void testEqualCompareDirect(final String value, final String thatValue) {
+
+        assertEquals(0, CloudStackVersion.compare(value, thatValue));
+        assertEquals(0, CloudStackVersion.compare(thatValue, value));
+
+    }
+
+    @Test
+    @DataProvider({
+        "1.2.3.4, 1.2.3",
+        "1.2.3, 1.0.0.0",
+        "1.2.3.4, 1.0.0",
+        "2.0.0, 1.2.3",
+        "2.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "2.0.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "1.3.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3",
+        "1.2.3.4-10, 1.0.0.0-5",
+        "1.2.3-10, 1.0.0-5",
+        "1.2.3.4, 1.0.0.0-5",
+        "1.2.3.4-10, 1.0.0"
     })
     public void testGreaterThanAndLessThanCompareTo(final String value, final String thatValue) {
 
@@ -117,4 +161,47 @@
 
     }
 
+    @Test
+    @DataProvider({
+        "1.2.3.4, 1.2.3",
+        "1.2.3, 1.0.0.0",
+        "1.2.3.4, 1.0.0",
+        "2.0.0, 1.2.3",
+        "2.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "2.0.0.0, 1.2.3.4",
+        "2.0.0.0, 1.2.3",
+        "1.3.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3.4",
+        "1.3.0.0, 1.2.3",
+        "1.2.3.4-10, 1.0.0.0-5",
+        "1.2.3-10, 1.0.0-5",
+        "1.2.3.4, 1.0.0.0-5",
+        "1.2.3.4-10, 1.0.0"
+    })
+    public void testGreaterThanAndLessThanCompareDirect(final String value, final String thatValue) {
+
+        assertEquals(1, CloudStackVersion.compare(value, thatValue));
+        assertEquals(-1, CloudStackVersion.compare(thatValue, value));
+
+    }
+
+    @Test
+    @DataProvider({
+        "Cloudstack Release 1.2.3 Mon Jan  1 10:10:10 UTC 2018, 1.2.3",
+        "Cloudstack Release 1.2.3.4 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4",
+        "Cloudstack Release 1.2.3-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-1519453362 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-1519453362",
+        "Cloudstack Release 1.2.3.4-brnading-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-brnading-SNAPSHOT",
+        "Cloudstack Release 1.2.3.4-brnading-1519453362 Mon Jan  1 10:10:10 UTC 2018, 1.2.3.4-brnading-1519453362",
+        "Cloudstack Release 1.2 Mon Jan  1 10:10:10 UTC 2018, 0",
+        "Cloudstack Release 1.2-SNAPSHOT Mon Jan  1 10:10:10 UTC 2018, 0",
+        "Cloud stack Release 1.2.3.4 Mon Jan  1 10:10:10 UTC 2018, 0"
+    })
+    public void testTrimRouterVersion(final String value, final String expected) {
+
+        assertEquals(expected, CloudStackVersion.trimRouterVersion(value));
+
+    }
 }
diff --git a/version-info.in b/version-info.in
deleted file mode 100644
index c0c21e7..0000000
--- a/version-info.in
+++ /dev/null
@@ -1,27 +0,0 @@
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-
-
-
-This is the version information for the manifests in the JAR files.
-
-Implementation_Version:                           @Implementation_Version@
-
-This file exists solely to trigger ant recompilation if it is needed.
-Otherwise, JAR files and all the dependent files are brought from cache.
-This file does not get installed or used in any other way other than
-during the build process.
diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml
index 2c7cc1d..ded2c21 100644
--- a/vmware-base/pom.xml
+++ b/vmware-base/pom.xml
@@ -1,73 +1,73 @@
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
+  or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
+  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
+  with the License.  You may obtain a copy of the License at
 
-  http://www.apache.org/licenses/LICENSE-2.0
+    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
+  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-vmware-base</artifactId>
-  <name>Apache CloudStack VMware Base</name>
-  <parent>
-    <groupId>org.apache.cloudstack</groupId>
-    <artifactId>cloudstack</artifactId>
-    <version>4.11.4.0-SNAPSHOT</version>
-  </parent>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-utils</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-framework-db</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
+    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-vmware-base</artifactId>
+    <name>Apache CloudStack VMware Base</name>
+    <parent>
         <groupId>org.apache.cloudstack</groupId>
-        <artifactId>cloud-api</artifactId>
-        <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-engine-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.cloud.com.vmware</groupId>
-      <artifactId>vmware-vim25</artifactId>
-      <version>${cs.vmware.api.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.axis</groupId>
-      <artifactId>axis-jaxrpc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>wsdl4j</groupId>
-      <artifactId>wsdl4j</artifactId>
-    </dependency>
-  </dependencies>
+        <artifactId>cloudstack</artifactId>
+        <version>4.12.0.0</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-framework-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cloudstack</groupId>
+            <artifactId>cloud-engine-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.cloud.com.vmware</groupId>
+            <artifactId>vmware-vim25</artifactId>
+            <version>${cs.vmware.api.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis-jaxrpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>wsdl4j</groupId>
+            <artifactId>wsdl4j</artifactId>
+        </dependency>
+    </dependencies>
 </project>
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java
deleted file mode 100644
index a0eee2d..0000000
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.mo;
-
-import java.util.ArrayList;
-
-import org.apache.log4j.Logger;
-
-import com.vmware.vim25.HostDatastoreBrowserSearchResults;
-import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
-import com.vmware.vim25.ManagedObjectReference;
-
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-
-public class HostDatastoreBrowserMO extends BaseMO {
-
-    private static final Logger s_logger = Logger.getLogger(HostDatastoreBrowserMO.class);
-
-    public HostDatastoreBrowserMO(VmwareContext context, ManagedObjectReference morHostDatastoreBrowser) {
-        super(context, morHostDatastoreBrowser);
-    }
-
-    public HostDatastoreBrowserMO(VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public void DeleteFile(String datastoreFullPath) throws Exception {
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - deleteFile(). target mor: " + _mor.getValue() + ", file datastore path: " + datastoreFullPath);
-
-        _context.getService().deleteFile(_mor, datastoreFullPath);
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - deleteFile() done");
-    }
-
-    public HostDatastoreBrowserSearchResults searchDatastore(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception {
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - searchDatastore(). target mor: " + _mor.getValue() + ", file datastore path: " + datastorePath);
-
-        try {
-            ManagedObjectReference morTask = _context.getService().searchDatastoreTask(_mor, datastorePath, searchSpec);
-
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (result) {
-                _context.waitForTaskProgressDone(morTask);
-
-                return (HostDatastoreBrowserSearchResults)_context.getVimClient().getDynamicProperty(morTask, "info.result");
-            } else {
-                s_logger.error("VMware searchDaastore_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-        } finally {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - searchDatastore() done");
-        }
-
-        return null;
-    }
-
-    public HostDatastoreBrowserSearchResults searchDatastore(String datastorePath, String fileName, boolean caseInsensitive) throws Exception {
-        HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec();
-        spec.setSearchCaseInsensitive(caseInsensitive);
-        spec.getMatchPattern().add(fileName);
-
-        return searchDatastore(datastorePath, spec);
-    }
-
-    @SuppressWarnings("unchecked")
-    public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception {
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - searchDatastoreSubFolders(). target mor: " + _mor.getValue() + ", file datastore path: " + datastorePath);
-
-        try {
-            ManagedObjectReference morTask = _context.getService().searchDatastoreSubFoldersTask(_mor, datastorePath, searchSpec);
-
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (result) {
-                _context.waitForTaskProgressDone(morTask);
-
-                return (ArrayList<HostDatastoreBrowserSearchResults>)_context.getVimClient().getDynamicProperty(morTask, "info.result");
-            } else {
-                s_logger.error("VMware searchDaastoreSubFolders_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-        } finally {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - searchDatastore() done");
-        }
-
-        return null;
-    }
-
-    public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, String fileName, boolean caseInsensitive) throws Exception {
-        HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec();
-        spec.setSearchCaseInsensitive(caseInsensitive);
-        spec.getMatchPattern().add(fileName);
-
-        return searchDatastoreSubFolders(datastorePath, spec);
-    }
-}
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
deleted file mode 100644
index 1ab325b..0000000
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ /dev/null
@@ -1,3434 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.mo;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import com.google.gson.Gson;
-import com.vmware.vim25.ArrayOfManagedObjectReference;
-import com.vmware.vim25.ChoiceOption;
-import com.vmware.vim25.CustomFieldStringValue;
-import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
-import com.vmware.vim25.DynamicProperty;
-import com.vmware.vim25.ElementDescription;
-import com.vmware.vim25.GuestInfo;
-import com.vmware.vim25.GuestOsDescriptor;
-import com.vmware.vim25.HttpNfcLeaseDeviceUrl;
-import com.vmware.vim25.HttpNfcLeaseInfo;
-import com.vmware.vim25.HttpNfcLeaseState;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.ObjectContent;
-import com.vmware.vim25.ObjectSpec;
-import com.vmware.vim25.OptionValue;
-import com.vmware.vim25.OvfCreateDescriptorParams;
-import com.vmware.vim25.OvfCreateDescriptorResult;
-import com.vmware.vim25.OvfFile;
-import com.vmware.vim25.ParaVirtualSCSIController;
-import com.vmware.vim25.PropertyFilterSpec;
-import com.vmware.vim25.PropertySpec;
-import com.vmware.vim25.TraversalSpec;
-import com.vmware.vim25.VirtualBusLogicController;
-import com.vmware.vim25.VirtualCdrom;
-import com.vmware.vim25.VirtualCdromIsoBackingInfo;
-import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
-import com.vmware.vim25.VirtualController;
-import com.vmware.vim25.VirtualDevice;
-import com.vmware.vim25.VirtualDeviceBackingInfo;
-import com.vmware.vim25.VirtualDeviceConfigSpec;
-import com.vmware.vim25.VirtualDeviceConfigSpecFileOperation;
-import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
-import com.vmware.vim25.VirtualDeviceConnectInfo;
-import com.vmware.vim25.VirtualDisk;
-import com.vmware.vim25.VirtualDiskFlatVer1BackingInfo;
-import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
-import com.vmware.vim25.VirtualDiskMode;
-import com.vmware.vim25.VirtualDiskRawDiskMappingVer1BackingInfo;
-import com.vmware.vim25.VirtualDiskSparseVer1BackingInfo;
-import com.vmware.vim25.VirtualDiskSparseVer2BackingInfo;
-import com.vmware.vim25.VirtualDiskType;
-import com.vmware.vim25.VirtualEthernetCard;
-import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
-import com.vmware.vim25.VirtualHardwareOption;
-import com.vmware.vim25.VirtualIDEController;
-import com.vmware.vim25.VirtualLsiLogicController;
-import com.vmware.vim25.VirtualLsiLogicSASController;
-import com.vmware.vim25.VirtualMachineCloneSpec;
-import com.vmware.vim25.VirtualMachineConfigInfo;
-import com.vmware.vim25.VirtualMachineConfigOption;
-import com.vmware.vim25.VirtualMachineConfigSpec;
-import com.vmware.vim25.VirtualMachineConfigSummary;
-import com.vmware.vim25.VirtualMachineFileInfo;
-import com.vmware.vim25.VirtualMachineFileLayoutEx;
-import com.vmware.vim25.VirtualMachineMessage;
-import com.vmware.vim25.VirtualMachineMovePriority;
-import com.vmware.vim25.VirtualMachinePowerState;
-import com.vmware.vim25.VirtualMachineQuestionInfo;
-import com.vmware.vim25.VirtualMachineRelocateDiskMoveOptions;
-import com.vmware.vim25.VirtualMachineRelocateSpec;
-import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
-import com.vmware.vim25.VirtualMachineRuntimeInfo;
-import com.vmware.vim25.VirtualMachineSnapshotInfo;
-import com.vmware.vim25.VirtualMachineSnapshotTree;
-import com.vmware.vim25.VirtualSCSIController;
-import com.vmware.vim25.VirtualSCSISharing;
-
-import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.hypervisor.vmware.util.VmwareHelper;
-import com.cloud.utils.ActionDelegate;
-import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.script.Script;
-
-public class VirtualMachineMO extends BaseMO {
-    private static final Logger s_logger = Logger.getLogger(VirtualMachineMO.class);
-    private static final ExecutorService MonitorServiceExecutor = Executors.newCachedThreadPool(new NamedThreadFactory("VM-Question-Monitor"));
-
-    public static final String ANSWER_YES = "0";
-    public static final String ANSWER_NO = "1";
-
-    private ManagedObjectReference _vmEnvironmentBrowser = null;
-
-    public VirtualMachineMO(VmwareContext context, ManagedObjectReference morVm) {
-        super(context, morVm);
-    }
-
-    public VirtualMachineMO(VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public Pair<DatacenterMO, String> getOwnerDatacenter() throws Exception {
-        return DatacenterMO.getOwnerDatacenter(getContext(), getMor());
-    }
-
-    public Pair<DatastoreMO, String> getOwnerDatastore(String dsFullPath) throws Exception {
-        String dsName = DatastoreFile.getDatastoreNameFromPath(dsFullPath);
-
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("Datastore");
-        pSpec.getPathSet().add("name");
-
-        TraversalSpec vmDatastoreTraversal = new TraversalSpec();
-        vmDatastoreTraversal.setType("VirtualMachine");
-        vmDatastoreTraversal.setPath("datastore");
-        vmDatastoreTraversal.setName("vmDatastoreTraversal");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.TRUE);
-        oSpec.getSelectSet().add(vmDatastoreTraversal);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-
-        if (ocs != null) {
-            for (ObjectContent oc : ocs) {
-                DynamicProperty prop = oc.getPropSet().get(0);
-                if (prop.getVal().toString().equals(dsName)) {
-                    return new Pair<DatastoreMO, String>(new DatastoreMO(_context, oc.getObj()), dsName);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public HostMO getRunningHost() throws Exception {
-        VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
-        return new HostMO(_context, runtimeInfo.getHost());
-    }
-
-    public String getVmName() throws Exception {
-        return (String)getContext().getVimClient().getDynamicProperty(_mor, "name");
-    }
-
-    public GuestInfo getVmGuestInfo() throws Exception {
-        return (GuestInfo)getContext().getVimClient().getDynamicProperty(_mor, "guest");
-    }
-
-    public void answerVM(String questionId, String choice) throws Exception {
-        getContext().getService().answerVM(_mor, questionId, choice);
-    }
-
-    public boolean isVMwareToolsRunning() throws Exception {
-        GuestInfo guestInfo = getVmGuestInfo();
-        if (guestInfo != null) {
-            if ("guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus()))
-                return true;
-        }
-        return false;
-    }
-
-    public boolean powerOn() throws Exception {
-        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON)
-            return true;
-
-        ManagedObjectReference morTask = _context.getService().powerOnVMTask(_mor, null);
-        // Monitor VM questions
-        final Boolean[] flags = {false};
-        final VirtualMachineMO vmMo = this;
-        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                s_logger.info("VM Question monitor started...");
-
-                while (!flags[0]) {
-                    try {
-                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
-                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
-                        if (question != null) {
-                            s_logger.info("Question id: " + question.getId());
-                            s_logger.info("Question text: " + question.getText());
-                            if (question.getMessage() != null) {
-                                for (VirtualMachineMessage msg : question.getMessage()) {
-                                    if (s_logger.isInfoEnabled()) {
-                                        s_logger.info("msg id: " + msg.getId());
-                                        s_logger.info("msg text: " + msg.getText());
-                                    }
-                                    if ("msg.uuid.altered".equalsIgnoreCase(msg.getId())) {
-                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId()
-                                                + ", we will automatically answer as 'moved it' to address out of band HA for the VM");
-                                        vmMo.answerVM(question.getId(), "1");
-                                        break;
-                                    }
-                                }
-                            }
-
-                            if (s_logger.isTraceEnabled())
-                                s_logger.trace("These are the choices we can have just in case");
-                            ChoiceOption choice = question.getChoice();
-                            if (choice != null) {
-                                for (ElementDescription info : choice.getChoiceInfo()) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("Choice option key: " + info.getKey());
-                                        s_logger.trace("Choice option label: " + info.getLabel());
-                                    }
-                                }
-                            }
-                        }
-                    } catch (Throwable e) {
-                        s_logger.error("Unexpected exception: ", e);
-                    }
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {
-                        s_logger.debug("[ignored] interupted while dealing with vm questions.");
-                    }
-                }
-                s_logger.info("VM Question monitor stopped");
-            }
-        });
-
-        try {
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (result) {
-                _context.waitForTaskProgressDone(morTask);
-                return true;
-            } else {
-                s_logger.error("VMware powerOnVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-        } finally {
-            // make sure to let VM question monitor exit
-            flags[0] = true;
-        }
-
-        return false;
-    }
-
-    public boolean powerOff() throws Exception {
-        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF)
-            return true;
-
-        return powerOffNoCheck();
-    }
-
-    public boolean safePowerOff(int shutdownWaitMs) throws Exception {
-
-        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF)
-            return true;
-
-        if (isVMwareToolsRunning()) {
-            try {
-                String vmName = getName();
-
-                s_logger.info("Try gracefully shut down VM " + vmName);
-                shutdown();
-
-                long startTick = System.currentTimeMillis();
-                while (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF && System.currentTimeMillis() - startTick < shutdownWaitMs) {
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {
-                        s_logger.debug("[ignored] interupted while powering of vm.");
-                    }
-                }
-
-                if (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF) {
-                    s_logger.info("can not gracefully shutdown VM within " + (shutdownWaitMs / 1000) + " seconds, we will perform force power off on VM " + vmName);
-                    return powerOffNoCheck();
-                }
-
-                return true;
-            } catch (Exception e) {
-                s_logger.warn("Failed to do guest-os graceful shutdown due to " + VmwareHelper.getExceptionMessage(e));
-            }
-        }
-
-        return powerOffNoCheck();
-    }
-
-    private boolean powerOffNoCheck() throws Exception {
-        ManagedObjectReference morTask = _context.getService().powerOffVMTask(_mor);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-
-            // It seems that even if a power-off task is returned done, VM state may still not be marked,
-            // wait up to 5 seconds to make sure to avoid race conditioning for immediate following on operations
-            // that relies on a powered-off VM
-            long startTick = System.currentTimeMillis();
-            while (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF && System.currentTimeMillis() - startTick < 5000) {
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    s_logger.debug("[ignored] interupted while powering of vm unconditionaly.");
-                }
-            }
-            return true;
-        } else {
-            if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF) {
-                // to help deal with possible race-condition
-                s_logger.info("Current power-off task failed. However, VM has been switched to the state we are expecting for");
-                return true;
-            }
-
-            s_logger.error("VMware powerOffVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public VirtualMachinePowerState getResetSafePowerState() throws Exception {
-
-        VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
-
-        // This is really ugly, there is a case that when windows guest VM is doing sysprep, the temporary
-        // rebooting process may let us pick up a "poweredOff" state during VMsync process, this can trigger
-        // a series actions. Unfortunately, from VMware API we can not distinguish power state into such details.
-        // We hope by giving it 3 second to re-read the state can cover this as a short-term solution.
-        //
-        // In the future, VMsync should not kick off CloudStack action (this is not a HA case) based on VM
-        // state report, until then we can remove this hacking fix
-        for (int i = 0; i < 3; i++) {
-            powerState = (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
-            if (powerState == VirtualMachinePowerState.POWERED_OFF) {
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    s_logger.debug("[ignored] interupted while pausing after power off.");
-                }
-            } else {
-                break;
-            }
-        }
-
-        return powerState;
-    }
-
-    public VirtualMachinePowerState getPowerState() throws Exception {
-        return (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
-    }
-
-    public boolean reset() throws Exception {
-        ManagedObjectReference morTask = _context.getService().resetVMTask(_mor);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware resetVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public void shutdown() throws Exception {
-        _context.getService().shutdownGuest(_mor);
-    }
-
-    public void rebootGuest() throws Exception {
-        _context.getService().rebootGuest(_mor);
-    }
-
-    public void markAsTemplate() throws Exception {
-        _context.getService().markAsTemplate(_mor);
-    }
-
-    public boolean isTemplate() throws Exception {
-        VirtualMachineConfigInfo configInfo = getConfigInfo();
-        return configInfo.isTemplate();
-    }
-
-    public boolean migrate(ManagedObjectReference morRp, ManagedObjectReference morTargetHost) throws Exception {
-        ManagedObjectReference morTask = _context.getService().migrateVMTask(_mor, morRp, morTargetHost, VirtualMachineMovePriority.DEFAULT_PRIORITY, null);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware migrateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public boolean changeDatastore(VirtualMachineRelocateSpec relocateSpec) throws Exception {
-        ManagedObjectReference morTask = _context.getVimClient().getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware RelocateVM_Task to change datastore failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public boolean changeHost(VirtualMachineRelocateSpec relocateSpec) throws Exception {
-        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware RelocateVM_Task to change host failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
-        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
-        relocateSpec.setHost(morTargetHost);
-
-        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public VirtualMachineSnapshotInfo getSnapshotInfo() throws Exception {
-        return (VirtualMachineSnapshotInfo)_context.getVimClient().getDynamicProperty(_mor, "snapshot");
-    }
-
-    public boolean createSnapshot(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception {
-        return createSnapshotGetReference(snapshotName, snapshotDescription, dumpMemory, quiesce) != null;
-    }
-
-    public ManagedObjectReference createSnapshotGetReference(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception {
-        long apiTimeout = _context.getVimClient().getVcenterSessionTimeout();
-        ManagedObjectReference morTask = _context.getService().createSnapshotTask(_mor, snapshotName, snapshotDescription, dumpMemory, quiesce);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-
-            ManagedObjectReference morSnapshot = null;
-
-            // We still need to wait until the object appear in vCenter
-            long startTick = System.currentTimeMillis();
-
-            while (System.currentTimeMillis() - startTick < apiTimeout) {
-                morSnapshot = getSnapshotMor(snapshotName);
-
-                if (morSnapshot != null) {
-                    break;
-                }
-
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    s_logger.debug("[ignored] interupted while waiting for snapshot to be done.");
-                }
-            }
-
-            if (morSnapshot == null) {
-                s_logger.error("We've been waiting for over " + apiTimeout + " milli seconds for snapshot MOR to be appearing in vCenter after CreateSnapshot task is done, " +
-                        "but it is still not there?!");
-
-                return null;
-            }
-
-            s_logger.debug("Waited for " + (System.currentTimeMillis() - startTick) + " seconds for snapshot object [" + snapshotName + "] to appear in vCenter.");
-
-            return morSnapshot;
-        } else {
-            s_logger.error("VMware createSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return null;
-    }
-
-    public boolean removeSnapshot(String snapshotName, boolean removeChildren) throws Exception {
-        ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
-        if (morSnapshot == null) {
-            s_logger.warn("Unable to find snapshot: " + snapshotName);
-            return false;
-        }
-
-        ManagedObjectReference morTask = _context.getService().removeSnapshotTask(morSnapshot, removeChildren, true);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware removeSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public boolean revertToSnapshot(String snapshotName) throws Exception {
-        ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
-        if (morSnapshot == null) {
-            s_logger.warn("Unable to find snapshot: " + snapshotName);
-            return false;
-        }
-        ManagedObjectReference morTask = _context.getService().revertToSnapshotTask(morSnapshot, _mor, null);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware revert to snapshot failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    /**
-     * Deletes all of the snapshots of a VM.
-     */
-    public void consolidateAllSnapshots() throws Exception {
-        ManagedObjectReference task = _context.getService().removeAllSnapshotsTask(_mor, true);
-
-        boolean result = _context.getVimClient().waitForTask(task);
-
-        if (result) {
-            _context.waitForTaskProgressDone(task);
-        } else {
-            throw new Exception("Unable to register VM due to the following issue: " + TaskMO.getTaskFailureInfo(_context, task));
-        }
-    }
-
-    public boolean removeAllSnapshots() throws Exception {
-        VirtualMachineSnapshotInfo snapshotInfo = getSnapshotInfo();
-
-        if (snapshotInfo != null && snapshotInfo.getRootSnapshotList() != null) {
-            List<VirtualMachineSnapshotTree> tree = snapshotInfo.getRootSnapshotList();
-            for (VirtualMachineSnapshotTree treeNode : tree) {
-                ManagedObjectReference morTask = _context.getService().removeSnapshotTask(treeNode.getSnapshot(), true, true);
-                boolean result = _context.getVimClient().waitForTask(morTask);
-                if (result) {
-                    _context.waitForTaskProgressDone(morTask);
-                } else {
-                    s_logger.error("VMware removeSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public String
-    getSnapshotDiskFileDatastorePath(VirtualMachineFileInfo vmFileInfo, List<Pair<ManagedObjectReference, String>> datastoreMounts, String snapshotDiskFile)
-            throws Exception {
-
-        // if file path start with "/", need to search all datastore mounts on the host in order
-        // to form fully qualified datastore path
-        if (snapshotDiskFile.startsWith("/")) {
-            for (Pair<ManagedObjectReference, String> mount : datastoreMounts) {
-                if (snapshotDiskFile.startsWith(mount.second())) {
-                    DatastoreMO dsMo = new DatastoreMO(_context, mount.first());
-
-                    String dsFullPath = String.format("[%s] %s", dsMo.getName(), snapshotDiskFile.substring(mount.second().length() + 1));
-                    s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + dsFullPath);
-                    return dsFullPath;
-                }
-            }
-
-            s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + snapshotDiskFile);
-            return snapshotDiskFile;
-        } else {
-
-            // snapshot directory string from VirtualMachineFileInfo ends with /
-            String dsFullPath = vmFileInfo.getSnapshotDirectory() + snapshotDiskFile;
-            s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + dsFullPath);
-            return dsFullPath;
-        }
-    }
-
-    public SnapshotDescriptor getSnapshotDescriptor() throws Exception {
-
-        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
-
-        String dsPath = getSnapshotDescriptorDatastorePath();
-        assert (dsPath != null);
-        String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), dsPath);
-        byte[] content = getContext().getResourceContent(url);
-
-        if (content == null || content.length < 1) {
-            s_logger.warn("Snapshot descriptor file (vsd) does not exist anymore?");
-        }
-
-        SnapshotDescriptor descriptor = new SnapshotDescriptor();
-        descriptor.parse(content);
-        return descriptor;
-    }
-
-    public String getSnapshotDescriptorDatastorePath() throws Exception {
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("VirtualMachine");
-        pSpec.getPathSet().add("name");
-        pSpec.getPathSet().add("config.files");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.FALSE);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-        assert (ocs != null);
-
-        String vmName = null;
-        VirtualMachineFileInfo fileInfo = null;
-
-        assert (ocs.size() == 1);
-        for (ObjectContent oc : ocs) {
-            List<DynamicProperty> props = oc.getPropSet();
-            if (props != null) {
-                assert (props.size() == 2);
-
-                for (DynamicProperty prop : props) {
-                    if (prop.getName().equals("name")) {
-                        vmName = prop.getVal().toString();
-                    } else {
-                        fileInfo = (VirtualMachineFileInfo)prop.getVal();
-                    }
-                }
-            }
-        }
-        assert (vmName != null);
-        assert (fileInfo != null);
-
-        // .vmsd file exists at the same directory of .vmx file
-        DatastoreFile vmxFile = new DatastoreFile(fileInfo.getVmPathName());
-        return vmxFile.getCompanionPath(vmName + ".vmsd");
-    }
-
-    public ManagedObjectReference getSnapshotMor(String snapshotName) throws Exception {
-        VirtualMachineSnapshotInfo info = getSnapshotInfo();
-        if (info != null) {
-            List<VirtualMachineSnapshotTree> snapTree = info.getRootSnapshotList();
-            return VmwareHelper.findSnapshotInTree(snapTree, snapshotName);
-        }
-        return null;
-    }
-
-    public boolean hasSnapshot() throws Exception {
-        VirtualMachineSnapshotInfo info = getSnapshotInfo();
-        if (info != null) {
-            ManagedObjectReference currentSnapshot = info.getCurrentSnapshot();
-            if (currentSnapshot != null) {
-                return true;
-            }
-            List<VirtualMachineSnapshotTree> rootSnapshotList = info.getRootSnapshotList();
-            if (rootSnapshotList != null && rootSnapshotList.size() > 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean createFullClone(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs)
-            throws Exception {
-
-        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
-        VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec();
-        cloneSpec.setLocation(relocSpec);
-        cloneSpec.setPowerOn(false);
-        cloneSpec.setTemplate(false);
-
-        relocSpec.setDatastore(morDs);
-        relocSpec.setPool(morResourcePool);
-        ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public boolean createLinkedClone(String cloneName, ManagedObjectReference morBaseSnapshot, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool,
-            ManagedObjectReference morDs) throws Exception {
-
-        assert (morBaseSnapshot != null);
-        assert (morFolder != null);
-        assert (morResourcePool != null);
-        assert (morDs != null);
-
-        VirtualDisk[] independentDisks = getAllIndependentDiskDevice();
-        VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
-        if (independentDisks.length > 0) {
-            List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(independentDisks.length);
-            for (int i = 0; i < independentDisks.length; i++) {
-                VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
-                loc.setDatastore(morDs);
-                loc.setDiskId(independentDisks[i].getKey());
-                loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
-                diskLocator.add(loc);
-            }
-
-            rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
-            rSpec.getDisk().addAll(diskLocator);
-        } else {
-            rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
-        }
-        rSpec.setPool(morResourcePool);
-
-        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
-        cloneSpec.setPowerOn(false);
-        cloneSpec.setTemplate(false);
-        cloneSpec.setLocation(rSpec);
-        cloneSpec.setSnapshot(morBaseSnapshot);
-
-        ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
-    public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception {
-        return (VirtualMachineRuntimeInfo)_context.getVimClient().getDynamicProperty(_mor, "runtime");
-    }
-
-    public VirtualMachineConfigInfo getConfigInfo() throws Exception {
-        return (VirtualMachineConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "config");
-    }
-
-    public boolean isToolsInstallerMounted() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "runtime.toolsInstallerMounted");
-    }
-    public GuestInfo getGuestInfo() throws Exception {
-        return (GuestInfo)_context.getVimClient().getDynamicProperty(_mor, "guest");
-    }
-
-    public VirtualMachineConfigSummary getConfigSummary() throws Exception {
-        return (VirtualMachineConfigSummary)_context.getVimClient().getDynamicProperty(_mor, "summary.config");
-    }
-
-    public VirtualMachineFileInfo getFileInfo() throws Exception {
-        return (VirtualMachineFileInfo)_context.getVimClient().getDynamicProperty(_mor, "config.files");
-    }
-
-    public VirtualMachineFileLayoutEx getFileLayout() throws Exception {
-        VirtualMachineFileLayoutEx fileLayout = null;
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("VirtualMachine");
-        pSpec.getPathSet().add("layoutEx");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.FALSE);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-
-        if (ocs != null) {
-            for (ObjectContent oc : ocs) {
-                List<DynamicProperty> props = oc.getPropSet();
-                if (props != null) {
-                    for (DynamicProperty prop : props) {
-                        if (prop.getName().equals("layoutEx")) {
-                            fileLayout = (VirtualMachineFileLayoutEx)prop.getVal();
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        return fileLayout;
-    }
-
-    @Override
-    public ManagedObjectReference getParentMor() throws Exception {
-        return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
-    }
-
-    public String[] getNetworks() throws Exception {
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("Network");
-        pSpec.getPathSet().add("name");
-
-        TraversalSpec vm2NetworkTraversal = new TraversalSpec();
-        vm2NetworkTraversal.setType("VirtualMachine");
-        vm2NetworkTraversal.setPath("network");
-        vm2NetworkTraversal.setName("vm2NetworkTraversal");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.TRUE);
-        oSpec.getSelectSet().add(vm2NetworkTraversal);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-
-        List<String> networks = new ArrayList<String>();
-        if (ocs != null && ocs.size() > 0) {
-            for (ObjectContent oc : ocs) {
-                networks.add(oc.getPropSet().get(0).getVal().toString());
-            }
-        }
-        return networks.toArray(new String[0]);
-    }
-
-    public List<NetworkDetails> getNetworksWithDetails() throws Exception {
-        List<NetworkDetails> networks = new ArrayList<NetworkDetails>();
-
-        int gcTagKey = getCustomFieldKey("Network", CustomFieldConstants.CLOUD_GC);
-
-        if (gcTagKey == 0) {
-            gcTagKey = getCustomFieldKey("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
-            s_logger.debug("The custom key for dvPortGroup is : " + gcTagKey);
-        }
-
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("Network");
-        pSpec.getPathSet().add("name");
-        pSpec.getPathSet().add("vm");
-        pSpec.getPathSet().add(String.format("value[%d]", gcTagKey));
-
-        TraversalSpec vm2NetworkTraversal = new TraversalSpec();
-        vm2NetworkTraversal.setType("VirtualMachine");
-        vm2NetworkTraversal.setPath("network");
-        vm2NetworkTraversal.setName("vm2NetworkTraversal");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.TRUE);
-        oSpec.getSelectSet().add(vm2NetworkTraversal);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-
-        if (ocs != null && ocs.size() > 0) {
-            for (ObjectContent oc : ocs) {
-                ArrayOfManagedObjectReference morVms = null;
-                String gcTagValue = null;
-                String name = null;
-
-                for (DynamicProperty prop : oc.getPropSet()) {
-                    if (prop.getName().equals("name"))
-                        name = prop.getVal().toString();
-                    else if (prop.getName().equals("vm"))
-                        morVms = (ArrayOfManagedObjectReference)prop.getVal();
-                    else if (prop.getName().startsWith("value[")) {
-                        CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
-                        if (val != null)
-                            gcTagValue = val.getValue();
-                    }
-                }
-
-                NetworkDetails details =
-                        new NetworkDetails(name, oc.getObj(), (morVms != null ? morVms.getManagedObjectReference().toArray(
-                                new ManagedObjectReference[morVms.getManagedObjectReference().size()]) : null), gcTagValue);
-
-                networks.add(details);
-            }
-            s_logger.debug("Retrieved " + networks.size() + " networks with key : " + gcTagKey);
-        }
-
-        return networks;
-    }
-
-    public List<DatastoreMO> getAllDatastores() throws Exception {
-        PropertySpec pSpec = new PropertySpec();
-        pSpec.setType("Datastore");
-        pSpec.getPathSet().add("name");
-
-        TraversalSpec vmDatastoreTraversal = new TraversalSpec();
-        vmDatastoreTraversal.setType("VirtualMachine");
-        vmDatastoreTraversal.setPath("datastore");
-        vmDatastoreTraversal.setName("vmDatastoreTraversal");
-
-        ObjectSpec oSpec = new ObjectSpec();
-        oSpec.setObj(_mor);
-        oSpec.setSkip(Boolean.TRUE);
-        oSpec.getSelectSet().add(vmDatastoreTraversal);
-
-        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
-        pfSpec.getPropSet().add(pSpec);
-        pfSpec.getObjectSet().add(oSpec);
-        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
-        pfSpecArr.add(pfSpec);
-
-        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
-
-        List<DatastoreMO> datastores = new ArrayList<DatastoreMO>();
-        if (CollectionUtils.isNotEmpty(ocs)) {
-            for (ObjectContent oc : ocs) {
-                datastores.add(new DatastoreMO(_context, oc.getObj()));
-            }
-        }
-        return datastores;
-    }
-
-    /**
-     * Retrieve path info to access VM files via vSphere web interface
-     * @return [0] vm-name, [1] data-center-name, [2] datastore-name
-     * @throws Exception
-     */
-    public String[] getHttpAccessPathInfo() throws Exception {
-        String[] pathInfo = new String[3];
-
-        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-
-        VirtualMachineFileInfo fileInfo = getFileInfo();
-        String vmxFilePath = fileInfo.getVmPathName();
-        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
-        assert (vmxPathTokens.length == 4);
-        pathInfo[1] = vmxPathTokens[1].trim();                            // vSphere vm name
-        pathInfo[2] = dcInfo.second();                                    // vSphere datacenter name
-        pathInfo[3] = vmxPathTokens[0].trim();                            // vSphere datastore name
-        return pathInfo;
-    }
-
-    public String getVmxHttpAccessUrl() throws Exception {
-        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-
-        VirtualMachineFileInfo fileInfo = getFileInfo();
-        String vmxFilePath = fileInfo.getVmPathName();
-        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
-
-        StringBuffer sb = new StringBuffer("https://" + _context.getServerAddress() + "/folder/");
-        sb.append(URLEncoder.encode(vmxPathTokens[2].trim(), "UTF-8"));
-        sb.append("/");
-        sb.append(URLEncoder.encode(vmxPathTokens[3].trim(), "UTF-8"));
-        sb.append("?dcPath=");
-        sb.append(URLEncoder.encode(dcInfo.second(), "UTF-8"));
-        sb.append("&dsName=");
-        sb.append(URLEncoder.encode(vmxPathTokens[1].trim(), "UTF-8"));
-
-        return sb.toString();
-    }
-
-    public boolean setVncConfigInfo(boolean enableVnc, String vncPassword, int vncPort, String keyboard) throws Exception {
-        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-        OptionValue[] vncOptions = VmwareHelper.composeVncOptions(null, enableVnc, vncPassword, vncPort, keyboard);
-        vmConfigSpec.getExtraConfig().addAll(Arrays.asList(vncOptions));
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public boolean configureVm(VirtualMachineConfigSpec vmConfigSpec) throws Exception {
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public boolean configureVm(Ternary<VirtualDevice, VirtualDeviceConfigSpecOperation, VirtualDeviceConfigSpecFileOperation>[] devices) throws Exception {
-
-        assert (devices != null);
-
-        VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[devices.length];
-        int i = 0;
-        for (Ternary<VirtualDevice, VirtualDeviceConfigSpecOperation, VirtualDeviceConfigSpecFileOperation> deviceTernary : devices) {
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(deviceTernary.first());
-            deviceConfigSpec.setOperation(deviceTernary.second());
-            deviceConfigSpec.setFileOperation(deviceTernary.third());
-            deviceConfigSpecArray[i++] = deviceConfigSpec;
-        }
-        configSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
-
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, configSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-
-    public Pair<String, Integer> getVncPort(String hostNetworkName) throws Exception {
-        HostMO hostMo = getRunningHost();
-        VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(hostNetworkName);
-
-        VirtualMachineConfigInfo configInfo = getConfigInfo();
-        List<OptionValue> values = configInfo.getExtraConfig();
-
-        if (values != null) {
-            for (OptionValue option : values) {
-                if (option.getKey().equals("RemoteDisplay.vnc.port")) {
-                    String value = (String)option.getValue();
-                    if (value != null) {
-                        return new Pair<String, Integer>(summary.getHostIp(), Integer.parseInt(value));
-                    }
-                }
-            }
-        }
-        return new Pair<String, Integer>(summary.getHostIp(), 0);
-    }
-
-    // vmdkDatastorePath: [datastore name] vmdkFilePath
-    public void createDisk(String vmdkDatastorePath, int sizeInMb, ManagedObjectReference morDs, int controllerKey) throws Exception {
-        createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey);
-    }
-
-    // vmdkDatastorePath: [datastore name] vmdkFilePath
-    public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, int sizeInMb,
-            ManagedObjectReference morDs, int controllerKey) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - createDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", sizeInMb: " + sizeInMb +
-                    ", diskType: " + diskType + ", diskMode: " + diskMode + ", rdmDeviceName: " + rdmDeviceName + ", datastore: " + morDs.getValue() + ", controllerKey: " +
-                    controllerKey);
-
-        assert (vmdkDatastorePath != null);
-        assert (morDs != null);
-
-        int ideControllerKey = getIDEDeviceControllerKey();
-        if (controllerKey < 0) {
-            controllerKey = ideControllerKey;
-        }
-
-        VirtualDisk newDisk = new VirtualDisk();
-        if (diskType == VirtualDiskType.THIN || diskType == VirtualDiskType.PREALLOCATED || diskType == VirtualDiskType.EAGER_ZEROED_THICK) {
-
-            VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
-            backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
-            if (diskType == VirtualDiskType.THIN) {
-                backingInfo.setThinProvisioned(true);
-            } else {
-                backingInfo.setThinProvisioned(false);
-            }
-
-            if (diskType == VirtualDiskType.EAGER_ZEROED_THICK) {
-                backingInfo.setEagerlyScrub(true);
-            } else {
-                backingInfo.setEagerlyScrub(false);
-            }
-
-            backingInfo.setDatastore(morDs);
-            backingInfo.setFileName(vmdkDatastorePath);
-            newDisk.setBacking(backingInfo);
-        } else if (diskType == VirtualDiskType.RDM || diskType == VirtualDiskType.RDMP) {
-            VirtualDiskRawDiskMappingVer1BackingInfo backingInfo = new VirtualDiskRawDiskMappingVer1BackingInfo();
-            if (diskType == VirtualDiskType.RDM) {
-                backingInfo.setCompatibilityMode("virtualMode");
-            } else {
-                backingInfo.setCompatibilityMode("physicalMode");
-            }
-            backingInfo.setDeviceName(rdmDeviceName);
-            if (diskType == VirtualDiskType.RDM) {
-                backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
-            }
-
-            backingInfo.setDatastore(morDs);
-            backingInfo.setFileName(vmdkDatastorePath);
-            newDisk.setBacking(backingInfo);
-        }
-
-        int deviceNumber = getNextDeviceNumber(controllerKey);
-
-        newDisk.setControllerKey(controllerKey);
-        newDisk.setKey(-deviceNumber);
-        newDisk.setUnitNumber(deviceNumber);
-        newDisk.setCapacityInKB(sizeInMb * 1024);
-
-        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-        deviceConfigSpec.setDevice(newDisk);
-        deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.CREATE);
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-
-        if (!result) {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - createDisk() done(failed)");
-            throw new Exception("Unable to create disk " + vmdkDatastorePath + " due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        _context.waitForTaskProgressDone(morTask);
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - createDisk() done(successfully)");
-    }
-
-    public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception {
-        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
-        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
-        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
-        if (!isVmfsSparseFile) {
-            String currentAdapterType = vmdkFileDescriptor.getAdapterType();
-            if (!currentAdapterType.equalsIgnoreCase(newAdapterType)) {
-                s_logger.info("Updating adapter type to " + newAdapterType + " for VMDK file " + vmdkFileName);
-                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType);
-                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
-                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
-                s_logger.info("Updated VMDK file " + vmdkFileName);
-            }
-        }
-    }
-
-    public void updateAdapterTypeIfRequired(String vmdkFileName) throws Exception {
-        // Validate existing adapter type of VMDK file. Update it with a supported adapter type if validation fails.
-        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
-        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
-
-        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
-        if (!isVmfsSparseFile) {
-            String currentAdapterTypeStr = vmdkFileDescriptor.getAdapterType();
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Detected adapter type  " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
-            }
-            VmdkAdapterType currentAdapterType = VmdkAdapterType.getType(currentAdapterTypeStr);
-            if (currentAdapterType == VmdkAdapterType.none) {
-                // Value of currentAdapterType can be VmdkAdapterType.none only if adapter type of vmdk is set to either
-                // lsisas1068 (SAS controller) or pvscsi (Vmware Paravirtual) only. Valid adapter type for those controllers is lsilogic.
-                // Hence use adapter type lsilogic. Other adapter types ide, lsilogic, buslogic are valid and does not need to be modified.
-                VmdkAdapterType newAdapterType = VmdkAdapterType.lsilogic;
-                s_logger.debug("Updating adapter type to " + newAdapterType + " from " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
-                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString());
-                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
-
-                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
-                s_logger.debug("Updated VMDK file " + vmdkFileName);
-            }
-        }
-    }
-
-    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception {
-
-        if(s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
-                            + new Gson().toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue());
-        int controllerKey = 0;
-        int unitNumber = 0;
-
-        if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
-            // IDE virtual disk cannot be added if VM is running
-            if (getPowerState() == VirtualMachinePowerState.POWERED_ON) {
-                throw new Exception("Adding a virtual disk over IDE controller is not supported while VM is running in VMware hypervisor. Please re-try when VM is not running.");
-            }
-            // Get next available unit number and controller key
-            int ideDeviceCount = getNumberOfIDEDevices();
-            if (ideDeviceCount >= VmwareHelper.MAX_IDE_CONTROLLER_COUNT * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER) {
-                throw new Exception("Maximum limit of  devices supported on IDE controllers [" + VmwareHelper.MAX_IDE_CONTROLLER_COUNT
-                        * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER + "] is reached.");
-            }
-            controllerKey = getIDEControllerKey(ideDeviceCount);
-            unitNumber = getFreeUnitNumberOnIDEController(controllerKey);
-        } else {
-            controllerKey = getScsiDiskControllerKey(diskController);
-            unitNumber = -1;
-        }
-        synchronized (_mor.getValue().intern()) {
-            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1);
-            controllerKey = newDisk.getControllerKey();
-            unitNumber = newDisk.getUnitNumber();
-            VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking();
-            String vmdkFileName = backingInfo.getFileName();
-            DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
-            VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
-            if (vmdkAdapterType == VmdkAdapterType.none) {
-                String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
-                    vmdkFileName + "] with controller : " + diskControllerType;
-                s_logger.debug(message);
-                throw new Exception(message);
-            }
-            updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString());
-            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            deviceConfigSpec.setDevice(newDisk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-
-            if (!result) {
-                if (s_logger.isTraceEnabled())
-                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
-                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-
-            _context.waitForTaskProgressDone(morTask);
-        }
-
-        if(s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
-    }
-
-    private int getControllerBusNumber(int controllerKey) throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualController && device.getKey() == controllerKey) {
-                    return ((VirtualController)device).getBusNumber();
-                }
-            }
-        }
-        throw new Exception("SCSI Controller with key " + controllerKey + " is Not Found");
-
-    }
-
-    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) +
-                    ", datastore: " + morDs.getValue());
-
-        synchronized (_mor.getValue().intern()) {
-            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1);
-            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            deviceConfigSpec.setDevice(newDisk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-
-            if (!result) {
-                if (s_logger.isTraceEnabled())
-                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
-                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-
-            _context.waitForTaskProgressDone(morTask);
-        }
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
-    }
-
-    public void attachDisk(Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain, int controllerKey) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain));
-
-        synchronized (_mor.getValue().intern()) {
-            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1);
-            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            deviceConfigSpec.setDevice(newDisk);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-
-            if (!result) {
-                if (s_logger.isTraceEnabled())
-                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
-                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-
-            _context.waitForTaskProgressDone(morTask);
-        }
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
-    }
-
-    // vmdkDatastorePath: [datastore name] vmdkFilePath
-    public List<Pair<String, ManagedObjectReference>> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", deleteBacking: " +
-                    deleteBackingFile);
-
-        // Note: if VM has been taken snapshot, original backing file will be renamed, therefore, when we try to find the matching
-        // VirtualDisk, we only perform prefix matching
-        Pair<VirtualDisk, String> deviceInfo = getDiskDevice(vmdkDatastorePath);
-        if (deviceInfo == null) {
-            s_logger.warn("vCenter API trace - detachDisk() done (failed)");
-            throw new Exception("No such disk device: " + vmdkDatastorePath);
-        }
-
-        // IDE virtual disk cannot be detached if VM is running
-        if (deviceInfo.second() != null && deviceInfo.second().contains("ide")) {
-            if (getPowerState() == VirtualMachinePowerState.POWERED_ON) {
-                throw new Exception("Removing a virtual disk over IDE controller is not supported while VM is running in VMware hypervisor. " +
-                        "Please re-try when VM is not running.");
-            }
-        }
-
-        List<Pair<String, ManagedObjectReference>> chain = getDiskDatastorePathChain(deviceInfo.first(), true);
-
-        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-        deviceConfigSpec.setDevice(deviceInfo.first());
-        if (deleteBackingFile) {
-            deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.DESTROY);
-        }
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-
-        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-
-        if (!result) {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - detachDisk() done (failed)");
-
-            throw new Exception("Failed to detach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        _context.waitForTaskProgressDone(morTask);
-
-        // VMware does not update snapshot references to the detached disk, we have to work around it
-        SnapshotDescriptor snapshotDescriptor = null;
-        try {
-            snapshotDescriptor = getSnapshotDescriptor();
-        } catch (Exception e) {
-            s_logger.info("Unable to retrieve snapshot descriptor, will skip updating snapshot reference");
-        }
-
-        if (snapshotDescriptor != null) {
-            for (Pair<String, ManagedObjectReference> pair : chain) {
-                DatastoreFile dsFile = new DatastoreFile(pair.first());
-                snapshotDescriptor.removeDiskReferenceFromSnapshot(dsFile.getFileName());
-            }
-
-            Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
-            String dsPath = getSnapshotDescriptorDatastorePath();
-            assert (dsPath != null);
-            String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), dsPath);
-            getContext().uploadResourceContent(url, snapshotDescriptor.getVmsdContent());
-        }
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachDisk() done (successfully)");
-        return chain;
-    }
-
-    public void detachAllDisks() throws Exception {
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachAllDisk(). target MOR: " + _mor.getValue());
-
-        VirtualDisk[] disks = getAllDiskDevice();
-        if (disks.length > 0) {
-            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[disks.length];
-
-            for (int i = 0; i < disks.length; i++) {
-                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                deviceConfigSpecArray[i].setDevice(disks[i]);
-                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-            }
-            reConfigSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
-
-            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-
-            if (!result) {
-                if (s_logger.isTraceEnabled())
-                    s_logger.trace("vCenter API trace - detachAllDisk() done(failed)");
-                throw new Exception("Failed to detach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-
-            _context.waitForTaskProgressDone(morTask);
-        }
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachAllDisk() done(successfully)");
-    }
-
-    // isoDatastorePath: [datastore name] isoFilePath
-    public void attachIso(String isoDatastorePath, ManagedObjectReference morDs, boolean connect, boolean connectAtBoot) throws Exception {
-        attachIso(isoDatastorePath, morDs, connect, connectAtBoot, null);
-    }
-
-    // isoDatastorePath: [datastore name] isoFilePath
-    public void attachIso(String isoDatastorePath, ManagedObjectReference morDs,
-    boolean connect, boolean connectAtBoot, Integer key) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - attachIso(). target MOR: " + _mor.getValue() + ", isoDatastorePath: " + isoDatastorePath + ", datastore: " +
-                    morDs.getValue() + ", connect: " + connect + ", connectAtBoot: " + connectAtBoot);
-
-        assert (isoDatastorePath != null);
-        assert (morDs != null);
-
-        boolean newCdRom = false;
-        VirtualCdrom cdRom;
-        if (key == null) {
-            cdRom = (VirtualCdrom) getIsoDevice();
-        } else {
-            cdRom = (VirtualCdrom) getIsoDevice(key);
-        }
-        if (cdRom == null) {
-            newCdRom = true;
-            cdRom = new VirtualCdrom();
-            cdRom.setControllerKey(getIDEDeviceControllerKey());
-
-            int deviceNumber = getNextIDEDeviceNumber();
-            cdRom.setUnitNumber(deviceNumber);
-            cdRom.setKey(-deviceNumber);
-        }
-
-        VirtualDeviceConnectInfo cInfo = new VirtualDeviceConnectInfo();
-        cInfo.setConnected(connect);
-        cInfo.setStartConnected(connectAtBoot);
-        cdRom.setConnectable(cInfo);
-
-        VirtualCdromIsoBackingInfo backingInfo = new VirtualCdromIsoBackingInfo();
-        backingInfo.setFileName(isoDatastorePath);
-        backingInfo.setDatastore(morDs);
-        cdRom.setBacking(backingInfo);
-
-        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-        //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-        deviceConfigSpec.setDevice(cdRom);
-        if (newCdRom) {
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-        } else {
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-        }
-
-        //deviceConfigSpecArray[0] = deviceConfigSpec;
-        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-
-        if (!result) {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - detachIso() done(failed)");
-            throw new Exception("Failed to attach ISO due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        _context.waitForTaskProgressDone(morTask);
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachIso() done(successfully)");
-    }
-
-    public int detachIso(String isoDatastorePath) throws Exception {
-        return detachIso(isoDatastorePath, false);
-    }
-
-    public int detachIso(String isoDatastorePath, final boolean force) throws Exception {
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - detachIso(). target MOR: " + _mor.getValue() + ", isoDatastorePath: " + isoDatastorePath);
-
-        VirtualDevice device = getIsoDevice(isoDatastorePath);
-        if (device == null) {
-            if (s_logger.isTraceEnabled())
-                s_logger.trace("vCenter API trace - detachIso() done(failed)");
-            throw new Exception("Unable to find a CDROM device");
-        }
-
-        VirtualCdromRemotePassthroughBackingInfo backingInfo = new VirtualCdromRemotePassthroughBackingInfo();
-        backingInfo.setDeviceName("");
-        device.setBacking(backingInfo);
-
-        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-        //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-        deviceConfigSpec.setDevice(device);
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-        //deviceConfigSpecArray[0] = deviceConfigSpec;
-        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-
-        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-
-        // Monitor VM questions
-        final Boolean[] flags = {false};
-        final VirtualMachineMO vmMo = this;
-        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                s_logger.info("VM Question monitor started...");
-
-                while (!flags[0]) {
-                    try {
-                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
-                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
-                        if (question != null) {
-                            if (s_logger.isTraceEnabled()) {
-                                s_logger.trace("Question id: " + question.getId());
-                                s_logger.trace("Question text: " + question.getText());
-                            }
-                            if (question.getMessage() != null) {
-                                for (VirtualMachineMessage msg : question.getMessage()) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("msg id: " + msg.getId());
-                                        s_logger.trace("msg text: " + msg.getText());
-                                    }
-                                    if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msg.getId())) {
-                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId() +
-                                                ", for safe operation we will automatically decline it");
-                                        vmMo.answerVM(question.getId(), force ? ANSWER_YES : ANSWER_NO);
-                                        break;
-                                    }
-                                }
-                            } else if (question.getText() != null) {
-                                String text = question.getText();
-                                String msgId;
-                                String msgText;
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("question text : " + text);
-                                }
-                                String[] tokens = text.split(":");
-                                msgId = tokens[0];
-                                msgText = tokens[1];
-                                if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msgId)) {
-                                    s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + question.getId() +
-                                            ". Message id : " + msgId + ". Message text : " + msgText + ", for safe operation we will automatically decline it.");
-                                    vmMo.answerVM(question.getId(), force ? ANSWER_YES : ANSWER_NO);
-                                }
-                            }
-
-                            ChoiceOption choice = question.getChoice();
-                            if (choice != null) {
-                                for (ElementDescription info : choice.getChoiceInfo()) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("Choice option key: " + info.getKey());
-                                        s_logger.trace("Choice option label: " + info.getLabel());
-                                    }
-                                }
-                            }
-                        }
-                    } catch (Throwable e) {
-                        s_logger.error("Unexpected exception: ", e);
-                    }
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {
-                        s_logger.debug("[ignored] interupted while handling vm question about iso detach.");
-                    }
-                }
-                s_logger.info("VM Question monitor stopped");
-            }
-        });
-        try {
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (!result) {
-                if (s_logger.isDebugEnabled())
-                    s_logger.trace("vCenter API trace - detachIso() done(failed)");
-                throw new Exception("Failed to detachIso due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-            }
-            _context.waitForTaskProgressDone(morTask);
-            s_logger.trace("vCenter API trace - detachIso() done(successfully)");
-        } finally {
-            flags[0] = true;
-            future.cancel(true);
-        }
-        return device.getKey();
-    }
-
-    public Pair<VmdkFileDescriptor, byte[]> getVmdkFileInfo(String vmdkDatastorePath) throws Exception {
-
-        if (s_logger.isTraceEnabled())
-            s_logger.trace("vCenter API trace - getVmdkFileInfo(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath);
-
-        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
-
-        String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkDatastorePath);
-        byte[] content = getContext().getResourceContent(url);
-        VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
-        descriptor.parse(content);
-
-        Pair<VmdkFileDescriptor, byte[]> result = new Pair<VmdkFileDescriptor, byte[]>(descriptor, content);
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("vCenter API trace - getVmdkFileInfo() done");
-            s_logger.trace("VMDK file descriptor: " + new Gson().toJson(result.first()));
-        }
-        return result;
-    }
-
-    public void exportVm(String exportDir, String exportName, boolean packToOva, boolean leaveOvaFileOnly) throws Exception {
-        ManagedObjectReference morOvf = _context.getServiceContent().getOvfManager();
-
-        VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
-        HostMO hostMo = new HostMO(_context, runtimeInfo.getHost());
-        String hostName = hostMo.getHostName();
-        String vmName = getVmName();
-
-        DatacenterMO dcMo = new DatacenterMO(_context, hostMo.getHyperHostDatacenter());
-
-        if (runtimeInfo.getPowerState() != VirtualMachinePowerState.POWERED_OFF) {
-            String msg = "Unable to export VM because it is not at powerdOff state. vmName: " + vmName + ", host: " + hostName;
-            s_logger.error(msg);
-            throw new Exception(msg);
-        }
-
-        ManagedObjectReference morLease = _context.getService().exportVm(getMor());
-        if (morLease == null) {
-            s_logger.error("exportVm() failed");
-            throw new Exception("exportVm() failed");
-        }
-
-        HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(_context, morLease);
-        HttpNfcLeaseState state = leaseMo.waitState(new HttpNfcLeaseState[] {HttpNfcLeaseState.READY, HttpNfcLeaseState.ERROR});
-
-        try {
-            if (state == HttpNfcLeaseState.READY) {
-                final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter();
-
-                boolean success = false;
-                List<String> fileNames = new ArrayList<String>();
-                try {
-                    HttpNfcLeaseInfo leaseInfo = leaseMo.getLeaseInfo();
-                    final long totalBytes = leaseInfo.getTotalDiskCapacityInKB() * 1024;
-                    long totalBytesDownloaded = 0;
-
-                    List<HttpNfcLeaseDeviceUrl> deviceUrls = leaseInfo.getDeviceUrl();
-                    s_logger.info("volss: copy vmdk and ovf file starts " + System.currentTimeMillis());
-                    if (deviceUrls != null) {
-                        OvfFile[] ovfFiles = new OvfFile[deviceUrls.size()];
-                        for (int i = 0; i < deviceUrls.size(); i++) {
-                            String deviceId = deviceUrls.get(i).getKey();
-                            String deviceUrlStr = deviceUrls.get(i).getUrl();
-                            String orgDiskFileName = deviceUrlStr.substring(deviceUrlStr.lastIndexOf("/") + 1);
-                            String diskFileName = String.format("%s-disk%d%s", exportName, i, VmwareHelper.getFileExtension(orgDiskFileName, ".vmdk"));
-                            String diskUrlStr = deviceUrlStr.replace("*", hostName);
-                            diskUrlStr = HypervisorHostHelper.resolveHostNameInUrl(dcMo, diskUrlStr);
-                            String diskLocalPath = exportDir + File.separator + diskFileName;
-                            fileNames.add(diskLocalPath);
-
-                            if (s_logger.isInfoEnabled()) {
-                                s_logger.info("Download VMDK file for export. url: " + deviceUrlStr);
-                            }
-                            long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate<Long>() {
-                                @Override
-                                public void action(Long param) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("Download progress " + param + "/" + totalBytes);
-                                    }
-                                    progressReporter.reportProgress((int)(param * 100 / totalBytes));
-                                }
-                            });
-                            totalBytesDownloaded += lengthOfDiskFile;
-
-                            OvfFile ovfFile = new OvfFile();
-                            ovfFile.setPath(diskFileName);
-                            ovfFile.setDeviceId(deviceId);
-                            ovfFile.setSize(lengthOfDiskFile);
-                            ovfFiles[i] = ovfFile;
-                        }
-
-                        // write OVF descriptor file
-                        OvfCreateDescriptorParams ovfDescParams = new OvfCreateDescriptorParams();
-                        ovfDescParams.getOvfFiles().addAll(Arrays.asList(ovfFiles));
-                        OvfCreateDescriptorResult ovfCreateDescriptorResult = _context.getService().createDescriptor(morOvf, getMor(), ovfDescParams);
-                        String ovfPath = exportDir + File.separator + exportName + ".ovf";
-                        fileNames.add(ovfPath);
-
-                        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath),"UTF-8");
-                        out.write(ovfCreateDescriptorResult.getOvfDescriptor());
-                        out.close();
-
-                        // tar files into OVA
-                        if (packToOva) {
-                            // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
-                            s_logger.info("Sync file system before we package OVA...");
-
-                            Script commandSync = new Script(true, "sync", 0, s_logger);
-                            commandSync.execute();
-
-                            Script command = new Script(false, "tar", 0, s_logger);
-                            command.setWorkDir(exportDir);
-                            command.add("-cf", exportName + ".ova");
-                            command.add(exportName + ".ovf");        // OVF file should be the first file in OVA archive
-                            for (String name : fileNames) {
-                                command.add((new File(name).getName()));
-                            }
-
-                            s_logger.info("Package OVA with commmand: " + command.toString());
-                            command.execute();
-
-                            // to be safe, physically test existence of the target OVA file
-                            if ((new File(exportDir + File.separator + exportName + ".ova")).exists()) {
-                                success = true;
-                            } else {
-                                s_logger.error(exportDir + File.separator + exportName + ".ova is not created as expected");
-                            }
-                        } else {
-                            success = true;
-                        }
-                    }
-                    s_logger.info("volss: copy vmdk and ovf file finishes " + System.currentTimeMillis());
-                } catch (Throwable e) {
-                    s_logger.error("Unexpected exception ", e);
-                } finally {
-                    progressReporter.close();
-
-                    if (leaveOvaFileOnly) {
-                        for (String name : fileNames) {
-                            new File(name).delete();
-                        }
-                    }
-
-                    if (!success)
-                        throw new Exception("Unable to finish the whole process to package as a OVA file");
-                }
-            }
-        } finally {
-            leaseMo.updateLeaseProgress(100);
-            leaseMo.completeLease();
-        }
-    }
-
-    // snapshot directory in format of: /vmfs/volumes/<datastore name>/<path>
-    @Deprecated
-    public void setSnapshotDirectory(String snapshotDir) throws Exception {
-        VirtualMachineFileInfo fileInfo = getFileInfo();
-        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
-        String vmxUrl = _context.composeDatastoreBrowseUrl(dcInfo.second(), fileInfo.getVmPathName());
-        byte[] vmxContent = _context.getResourceContent(vmxUrl);
-
-        BufferedReader in = null;
-        BufferedWriter out = null;
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-        boolean replaced = false;
-        try {
-            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent),"UTF-8"));
-            out = new BufferedWriter(new OutputStreamWriter(bos,"UTF-8"));
-            String line;
-            while ((line = in.readLine()) != null) {
-                if (line.startsWith("workingDir")) {
-                    replaced = true;
-                    out.write(String.format("workingDir=\"%s\"", snapshotDir));
-                    out.newLine();
-                } else {
-                    out.write(line);
-                    out.newLine();
-                }
-            }
-
-            if (!replaced) {
-                out.newLine();
-                out.write(String.format("workingDir=\"%s\"", snapshotDir));
-                out.newLine();
-            }
-        } finally {
-            if (in != null) {
-                in.close();
-            }
-            if (out != null) {
-                out.close();
-            }
-        }
-        _context.uploadResourceContent(vmxUrl, bos.toByteArray());
-
-        // It seems that I don't need to do re-registration. VMware has bug in writing the correct snapshot's VMDK path to
-        // its disk backing info anyway.
-        // redoRegistration();
-    }
-
-    // destName does not contain extension name
-    public void backupCurrentSnapshot(String deviceName, ManagedObjectReference morDestDs, String destDsDirectory, String destName, boolean includeBase) throws Exception {
-
-        SnapshotDescriptor descriptor = getSnapshotDescriptor();
-        SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
-        if (snapshotInfo.length == 0) {
-            String msg = "No snapshot found in this VM";
-            throw new Exception(msg);
-        }
-
-        HostMO hostMo = getRunningHost();
-        DatacenterMO dcMo = getOwnerDatacenter().first();
-        List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
-        VirtualMachineFileInfo vmFileInfo = getFileInfo();
-
-        List<Ternary<String, String, String>> backupInfo = new ArrayList<Ternary<String, String, String>>();
-
-        for (int i = 0; i < snapshotInfo.length; i++) {
-            if (!includeBase && i == snapshotInfo.length - 1) {
-                break;
-            }
-
-            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
-            if (disks != null) {
-                String destBaseFileName;
-                String destFileName;
-                String destParentFileName;
-                for (SnapshotDescriptor.DiskInfo disk : disks) {
-                    if (deviceName == null || deviceName.equals(disk.getDeviceName())) {
-                        String srcVmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName());
-                        Pair<DatastoreMO, String> srcDsInfo = getOwnerDatastore(srcVmdkFullDsPath);
-
-                        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(srcVmdkFullDsPath);
-                        String srcVmdkBaseFilePath = DatastoreFile.getCompanionDatastorePath(srcVmdkFullDsPath, vmdkInfo.first().getBaseFileName());
-
-                        destFileName = destName + (snapshotInfo.length - i - 1) + ".vmdk";
-                        if (vmdkInfo.first().getParentFileName() != null) {
-                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-delta.vmdk";
-                            destParentFileName = destName + (snapshotInfo.length - i - 2) + ".vmdk";
-                        } else {
-                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-flat.vmdk";
-                            destParentFileName = null;
-                        }
-
-                        s_logger.info("Copy VMDK base file " + srcVmdkBaseFilePath + " to " + destDsDirectory + "/" + destBaseFileName);
-                        srcDsInfo.first().copyDatastoreFile(srcVmdkBaseFilePath, dcMo.getMor(), morDestDs, destDsDirectory + "/" + destBaseFileName, dcMo.getMor(), true);
-
-                        byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkContentBaseInfo(vmdkInfo.second(), destBaseFileName, destParentFileName);
-                        String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destFileName);
-
-                        s_logger.info("Upload VMDK content file to " + destDsDirectory + "/" + destFileName);
-                        getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
-
-                        backupInfo.add(new Ternary<String, String, String>(destFileName, destBaseFileName, destParentFileName));
-                    }
-                }
-            }
-        }
-
-        byte[] vdiskInfo = VmwareHelper.composeDiskInfo(backupInfo, snapshotInfo.length, includeBase);
-        String vdiskUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destName + ".vdisk");
-        getContext().uploadResourceContent(vdiskUploadUrl, vdiskInfo);
-    }
-
-    public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) throws Exception {
-        HostMO hostMo = getRunningHost();
-        List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
-        VirtualMachineFileInfo vmFileInfo = getFileInfo();
-
-        SnapshotDescriptor descriptor = getSnapshotDescriptor();
-        SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
-
-        List<String> diskDsFullPaths = new ArrayList<String>();
-        for (int i = 0; i < snapshotInfo.length; i++) {
-            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
-            if (disks != null) {
-                for (SnapshotDescriptor.DiskInfo disk : disks) {
-                    String deviceNameInDisk = disk.getDeviceName();
-                    if (diskDevice == null || diskDevice.equalsIgnoreCase(deviceNameInDisk)) {
-                        String vmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName());
-                        diskDsFullPaths.add(vmdkFullDsPath);
-                    }
-                }
-            }
-        }
-        return diskDsFullPaths.toArray(new String[0]);
-    }
-
-    // return the disk chain (VMDK datastore paths) for cloned snapshot
-    public Pair<VirtualMachineMO, String[]> cloneFromCurrentSnapshot(String clonedVmName, int cpuSpeedMHz, int memoryMb, String diskDevice, ManagedObjectReference morDs)
-            throws Exception {
-        assert (morDs != null);
-        String[] disks = getCurrentSnapshotDiskChainDatastorePaths(diskDevice);
-        VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs);
-        return new Pair<VirtualMachineMO, String[]>(clonedVm, disks);
-    }
-
-    public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs) throws Exception {
-        assert (disks != null);
-        assert (disks.length >= 1);
-
-        HostMO hostMo = getRunningHost();
-
-        VirtualMachineMO clonedVmMo = HypervisorHostHelper.createWorkerVM(hostMo, new DatastoreMO(hostMo.getContext(), morDs), clonedVmName);
-        if (clonedVmMo == null)
-            throw new Exception("Unable to find just-created blank VM");
-
-        boolean bSuccess = false;
-        try {
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-            VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, null, -1, disks, morDs, -1, 1);
-
-            deviceConfigSpec.setDevice(device);
-            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            clonedVmMo.configureVm(vmConfigSpec);
-            bSuccess = true;
-            return clonedVmMo;
-        } finally {
-            if (!bSuccess) {
-                clonedVmMo.detachAllDisks();
-                clonedVmMo.destroy();
-            }
-        }
-    }
-
-    public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception {
-        GuestOsDescriptor guestOsDescriptor = null;
-        String guestId = guestOsId;
-        if (guestId == null) {
-            guestId = getGuestId();
-        }
-        ManagedObjectReference vmEnvironmentBrowser = _context.getVimClient().getMoRefProp(_mor, "environmentBrowser");
-        VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(vmEnvironmentBrowser, null, null);
-        List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor();
-        for (GuestOsDescriptor descriptor : guestDescriptors) {
-            if (guestId != null && guestId.equalsIgnoreCase(descriptor.getId())) {
-                guestOsDescriptor = descriptor;
-                break;
-            }
-        }
-        return guestOsDescriptor;
-    }
-
-    public void plugDevice(VirtualDevice device) throws Exception {
-        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-        deviceConfigSpec.setDevice(device);
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-        if (!configureVm(vmConfigSpec)) {
-            throw new Exception("Failed to add devices");
-        }
-    }
-
-    public void tearDownDevice(VirtualDevice device) throws Exception {
-        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-        deviceConfigSpec.setDevice(device);
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-
-        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-        if (!configureVm(vmConfigSpec)) {
-            throw new Exception("Failed to detach devices");
-        }
-    }
-
-    public void tearDownDevices(Class<?>[] deviceClasses) throws Exception {
-        VirtualDevice[] devices = getMatchedDevices(deviceClasses);
-
-        if (devices.length > 0) {
-            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[devices.length];
-
-            for (int i = 0; i < devices.length; i++) {
-                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
-                deviceConfigSpecArray[i].setDevice(devices[i]);
-                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-                vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[i]);
-            }
-
-            if (!configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to detach devices");
-            }
-        }
-    }
-
-    public void copyAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception {
-        VirtualDevice[] disks = getAllDiskDevice();
-        DatacenterMO dcMo = getOwnerDatacenter().first();
-        if (disks != null) {
-            for (VirtualDevice disk : disks) {
-                List<Pair<String, ManagedObjectReference>> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain);
-                for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
-                    DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second());
-
-                    DatastoreFile srcFile = new DatastoreFile(fileItem.first());
-                    DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
-
-                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
-
-                    vmdkDescriptor = getVmdkFileInfo(fileItem.first());
-
-                    s_logger.info("Copy VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
-                    srcDsMo.copyDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
-
-                    if (vmdkDescriptor != null) {
-                        String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
-                        String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName);
-                        destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
-
-                        s_logger.info("Copy VM disk file " + baseFilePath + " to " + destFile.getPath());
-                        srcDsMo.copyDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
-                    }
-                }
-            }
-        }
-    }
-
-    public List<String> getVmdkFileBaseNames() throws Exception {
-        List<String> vmdkFileBaseNames = new ArrayList<String>();
-        VirtualDevice[] devices = getAllDiskDevice();
-        for(VirtualDevice device : devices) {
-            if(device instanceof VirtualDisk) {
-                vmdkFileBaseNames.add(getVmdkFileBaseName((VirtualDisk)device));
-            }
-        }
-        return vmdkFileBaseNames;
-    }
-
-    public String getVmdkFileBaseName(VirtualDisk disk) throws Exception {
-        String vmdkFileBaseName = null;
-        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
-        if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-            VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
-            vmdkFileBaseName = dsBackingFile.getFileBaseName();
-        }
-        return vmdkFileBaseName;
-    }
-
-    // this method relies on un-offical VMware API
-    @Deprecated
-    public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception {
-        VirtualDevice[] disks = getAllDiskDevice();
-        DatacenterMO dcMo = getOwnerDatacenter().first();
-        if (disks != null) {
-            for (VirtualDevice disk : disks) {
-                List<Pair<String, ManagedObjectReference>> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain);
-                for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
-                    DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second());
-
-                    DatastoreFile srcFile = new DatastoreFile(fileItem.first());
-                    DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
-
-                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
-                    vmdkDescriptor = getVmdkFileInfo(fileItem.first());
-
-                    s_logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
-                    srcDsMo.moveDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
-
-                    if (vmdkDescriptor != null) {
-                        String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
-                        String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName);
-                        destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
-
-                        s_logger.info("Move VM disk file " + baseFilePath + " to " + destFile.getPath());
-                        srcDsMo.moveDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
-                    }
-                }
-            }
-        }
-    }
-
-    public int getPvScsiDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof ParaVirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public int getPvScsiDeviceControllerKey() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof ParaVirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        assert (false);
-        throw new Exception("VMware Paravirtual SCSI Controller Not Found");
-    }
-
-    public void ensurePvScsiDeviceController(int requiredNumScsiControllers, int availableBusNum) throws Exception {
-        VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-        int busNum = availableBusNum;
-        while (busNum < requiredNumScsiControllers) {
-            ParaVirtualSCSIController scsiController = new ParaVirtualSCSIController();
-
-            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-            scsiController.setBusNumber(busNum);
-            scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
-            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-            scsiControllerSpec.setDevice(scsiController);
-            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            vmConfig.getDeviceChange().add(scsiControllerSpec);
-            busNum++;
-        }
-
-        if (configureVm(vmConfig)) {
-            throw new Exception("Unable to add Scsi controllers to the VM " + getName());
-        } else {
-            s_logger.info("Successfully added " + requiredNumScsiControllers + " SCSI controllers.");
-        }
-    }
-
-    public String getRecommendedDiskController(String guestOsId) throws Exception {
-        String recommendedController;
-        GuestOsDescriptor guestOsDescriptor = getGuestOsDescriptor(guestOsId);
-        recommendedController = VmwareHelper.getRecommendedDiskControllerFromDescriptor(guestOsDescriptor);
-        return recommendedController;
-    }
-
-    public boolean isPvScsiSupported() throws Exception {
-        int virtualHardwareVersion;
-
-        virtualHardwareVersion = getVirtualHardwareVersion();
-
-        // Check if virtual machine is using hardware version 7 or later.
-        if (virtualHardwareVersion < 7) {
-            s_logger.error("The virtual hardware version of the VM is " + virtualHardwareVersion
-                    + ", which doesn't support PV SCSI controller type for virtual harddisks. Please upgrade this VM's virtual hardware version to 7 or later.");
-            return false;
-        }
-        return true;
-    }
-
-    // Would be useful if there exists multiple sub types of SCSI controllers per VM are supported in CloudStack f
-    public int getScsiDiskControllerKey(String diskController) throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicController) {
-                    return ((VirtualLsiLogicController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicSASController) {
-                    return ((VirtualLsiLogicSASController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof ParaVirtualSCSIController) {
-                    return ((ParaVirtualSCSIController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualBusLogicController) {
-                    return ((VirtualBusLogicController)device).getKey();
-                }
-            }
-        }
-
-        assert (false);
-        throw new IllegalStateException("Scsi disk controller of type " + diskController + " not found among configured devices.");
-    }
-
-    public int getScsiDiskControllerKeyNoException(String diskController) throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicController) {
-                    return ((VirtualLsiLogicController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicSASController) {
-                    return ((VirtualLsiLogicSASController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof ParaVirtualSCSIController) {
-                    return ((ParaVirtualSCSIController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
-                        && device instanceof VirtualBusLogicController) {
-                    return ((VirtualBusLogicController)device).getKey();
-                }
-            }
-        }
-        return -1;
-    }
-
-    public int getNextScsiDiskDeviceNumber() throws Exception {
-        int scsiControllerKey = getScsiDeviceControllerKey();
-        int deviceNumber = getNextDeviceNumber(scsiControllerKey);
-
-        return deviceNumber;
-    }
-
-    public int getScsiDeviceControllerKey() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        assert (false);
-        throw new Exception("SCSI Controller Not Found");
-    }
-
-    public int getGenericScsiDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public int getScsiDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-            getDynamicProperty(_mor, "config.hardware.device");
-
-        if(devices != null && devices.size() > 0) {
-            for(VirtualDevice device : devices) {
-                if(device instanceof VirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public void ensureLsiLogicDeviceControllers(int count, int availableBusNum) throws Exception {
-        int scsiControllerKey = getLsiLogicDeviceControllerKeyNoException();
-        if (scsiControllerKey < 0) {
-            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-            int busNum = availableBusNum;
-            while (busNum < count) {
-                VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
-                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-                scsiController.setBusNumber(busNum);
-                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
-                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-                scsiControllerSpec.setDevice(scsiController);
-                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                vmConfig.getDeviceChange().add(scsiControllerSpec);
-                busNum++;
-            }
-            if (configureVm(vmConfig)) {
-                throw new Exception("Unable to add Lsi Logic controllers to the VM " + getName());
-            } else {
-                s_logger.info("Successfully added " + count + " LsiLogic Parallel SCSI controllers.");
-            }
-        }
-    }
-
-    private int getLsiLogicDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualLsiLogicController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public void ensureScsiDeviceController() throws Exception {
-        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
-        if (scsiControllerKey < 0) {
-            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-            // Scsi controller
-            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
-            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-            scsiController.setBusNumber(0);
-            scsiController.setKey(1);
-            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-            scsiControllerSpec.setDevice(scsiController);
-            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            vmConfig.getDeviceChange().add(scsiControllerSpec);
-            if (configureVm(vmConfig)) {
-                throw new Exception("Unable to add Scsi controller");
-            }
-        }
-    }
-
-    public void ensureScsiDeviceControllers(int count, int availableBusNum) throws Exception {
-        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
-        if (scsiControllerKey < 0) {
-            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-            int busNum = availableBusNum;
-            while (busNum < count) {
-            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
-            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-                scsiController.setBusNumber(busNum);
-                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
-            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-            scsiControllerSpec.setDevice(scsiController);
-            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-            vmConfig.getDeviceChange().add(scsiControllerSpec);
-                busNum++;
-            }
-            if (configureVm(vmConfig)) {
-                throw new Exception("Unable to add Scsi controllers to the VM " + getName());
-            } else {
-                s_logger.info("Successfully added " + count + " SCSI controllers.");
-            }
-        }
-    }
-
-    // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
-    public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath) throws Exception {
-        final String zeroLengthString = "";
-
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        ArrayList<Pair<VirtualDisk, String>> partialMatchingDiskDevices = new ArrayList<>();
-
-        DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath);
-
-        String srcBaseName = dsSrcFile.getFileBaseName();
-        String trimmedSrcBaseName = VmwareHelper.trimSnapshotDeltaPostfix(srcBaseName);
-        String srcDatastoreName = dsSrcFile.getDatastoreName() != null ? dsSrcFile.getDatastoreName() : zeroLengthString;
-
-        s_logger.info("Look for disk device info for volume : " + vmdkDatastorePath + " with base name: " + srcBaseName);
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
-
-                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
-
-                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-
-                        do {
-                            s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName());
-
-                            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
-
-                            String backingDatastoreName = dsBackingFile.getDatastoreName() != null ? dsBackingFile.getDatastoreName() : zeroLengthString;
-
-                            if (srcDatastoreName.equals(zeroLengthString)) {
-                                backingDatastoreName = zeroLengthString;
-                            }
-
-                            if (srcDatastoreName.equalsIgnoreCase(backingDatastoreName)) {
-                                String backingBaseName = dsBackingFile.getFileBaseName();
-
-                                if (backingBaseName.equalsIgnoreCase(srcBaseName)) {
-                                    String deviceNumbering = getDeviceBusName(devices, device);
-
-                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
-
-                                    return new Pair<>((VirtualDisk)device, deviceNumbering);
-                                }
-
-                                if (backingBaseName.contains(trimmedSrcBaseName)) {
-                                    String deviceNumbering = getDeviceBusName(devices, device);
-
-                                    partialMatchingDiskDevices.add(new Pair<>((VirtualDisk)device, deviceNumbering));
-                                }
-                            }
-
-                            diskBackingInfo = diskBackingInfo.getParent();
-                        } while (diskBackingInfo != null);
-                    }
-                }
-            }
-        }
-
-        // No disk device was found with an exact match for the volume path, hence look for disk device that matches the trimmed name.
-        s_logger.info("No disk device with an exact match found for volume : " + vmdkDatastorePath + ". Look for disk device info against trimmed base name: " + srcBaseName);
-
-        if (partialMatchingDiskDevices != null) {
-            if (partialMatchingDiskDevices.size() == 1) {
-                VirtualDiskFlatVer2BackingInfo matchingDiskBackingInfo = (VirtualDiskFlatVer2BackingInfo)partialMatchingDiskDevices.get(0).first().getBacking();
-
-                s_logger.info("Disk backing : " + matchingDiskBackingInfo.getFileName() + " matches ==> " + partialMatchingDiskDevices.get(0).second());
-
-                return partialMatchingDiskDevices.get(0);
-            } else if (partialMatchingDiskDevices.size() > 1) {
-                s_logger.warn("Disk device info lookup for volume: " + vmdkDatastorePath + " failed as multiple disk devices were found to match" +
-                        " volume's trimmed base name: " + trimmedSrcBaseName);
-
-                return null;
-            }
-        }
-
-        s_logger.warn("Disk device info lookup for volume: " + vmdkDatastorePath + " failed as no matching disk device found");
-
-        return null;
-    }
-
-    // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
-    public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath);
-        String srcBaseName = dsSrcFile.getFileBaseName();
-        String trimmedSrcBaseName = VmwareHelper.trimSnapshotDeltaPostfix(srcBaseName);
-
-        if (matchExactly) {
-            s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with base name: " + srcBaseName);
-        } else {
-            s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with trimmed base name: " + trimmedSrcBaseName);
-        }
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
-
-                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
-                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-                        do {
-                            s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName());
-
-                            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
-                            String backingBaseName = dsBackingFile.getFileBaseName();
-                            if (matchExactly) {
-                                if (backingBaseName.equalsIgnoreCase(srcBaseName)) {
-                                    String deviceNumbering = getDeviceBusName(devices, device);
-
-                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
-                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
-                                }
-                            } else {
-                                if (backingBaseName.contains(trimmedSrcBaseName)) {
-                                    String deviceNumbering = getDeviceBusName(devices, device);
-
-                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
-                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
-                                }
-                            }
-
-                            diskBackingInfo = diskBackingInfo.getParent();
-                        } while (diskBackingInfo != null);
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
-
-                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
-                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-
-                        String deviceNumbering = getDeviceBusName(devices, device);
-                        if (deviceNumbering.equals(deviceBusName))
-                            return diskBackingInfo.getFileName();
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public VirtualDisk getDiskDeviceByDeviceBusName(String deviceBusName) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    String deviceNumbering = getDeviceBusName(devices, device);
-                    if (deviceNumbering.equals(deviceBusName))
-                        return (VirtualDisk)device;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception {
-        VirtualMachineDiskInfoBuilder builder = new VirtualMachineDiskInfoBuilder();
-
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
-                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-
-                        while (diskBackingInfo != null) {
-                            String deviceBusName = getDeviceBusName(devices, device);
-                            builder.addDisk(deviceBusName, diskBackingInfo.getFileName());
-                            diskBackingInfo = diskBackingInfo.getParent();
-                        }
-                    }
-                }
-            }
-        }
-
-        return builder;
-    }
-
-    public List<Pair<Integer, ManagedObjectReference>> getAllDiskDatastores() throws Exception {
-        List<Pair<Integer, ManagedObjectReference>> disks = new ArrayList<Pair<Integer, ManagedObjectReference>>();
-
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
-                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-                        disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getKey()), diskBackingInfo.getDatastore()));
-                    }
-                }
-            }
-        }
-
-        return disks;
-    }
-
-
-    @Deprecated
-    public List<Pair<String, ManagedObjectReference>> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception {
-        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
-        if (!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) {
-            throw new Exception("Unsupported VirtualDeviceBackingInfo");
-        }
-
-        List<Pair<String, ManagedObjectReference>> pathList = new ArrayList<Pair<String, ManagedObjectReference>>();
-        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
-
-        if (!followChain) {
-            pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
-            return pathList;
-        }
-
-        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
-        VirtualMachineFileInfo vmFilesInfo = getFileInfo();
-        DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory());
-        DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName());
-
-        do {
-            if (diskBackingInfo.getParent() != null) {
-                pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
-                diskBackingInfo = diskBackingInfo.getParent();
-            } else {
-                // try getting parent info from VMDK file itself
-                byte[] content = null;
-                try {
-                    String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName());
-                    content = getContext().getResourceContent(url);
-                    if (content == null || content.length == 0) {
-                        break;
-                    }
-
-                    pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
-                } catch (Exception e) {
-                    // if snapshot directory has been changed to place other than default. VMware has a bug
-                    // that its corresponding disk backing info is not updated correctly. therefore, we will try search
-                    // in snapshot directory one more time
-                    DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName());
-                    String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName());
-
-                    String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath);
-                    content = getContext().getResourceContent(url);
-                    if (content == null || content.length == 0) {
-                        break;
-                    }
-
-                    pathList.add(new Pair<String, ManagedObjectReference>(vmdkFullDsPath, diskBackingInfo.getDatastore()));
-                }
-
-                VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
-                descriptor.parse(content);
-                if (descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) {
-                    // create a fake one
-                    VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo();
-                    parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore());
-
-                    String parentFileName = descriptor.getParentFileName();
-                    if (parentFileName.startsWith("/")) {
-                        int fileNameStartPos = parentFileName.lastIndexOf("/");
-                        parentFileName = parentFileName.substring(fileNameStartPos + 1);
-                        parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName));
-                    } else {
-                        parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName));
-                    }
-                    diskBackingInfo = parentDiskBackingInfo;
-                } else {
-                    break;
-                }
-            }
-        } while (diskBackingInfo != null);
-
-        return pathList;
-    }
-
-    private String getDeviceBusName(List<VirtualDevice> allDevices, VirtualDevice theDevice) throws Exception {
-        for (VirtualDevice device : allDevices) {
-            if (device.getKey() == theDevice.getControllerKey().intValue()) {
-                if (device instanceof VirtualIDEController) {
-                    return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber());
-                } else if (device instanceof VirtualSCSIController) {
-                    return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber());
-                } else {
-                    throw new Exception("Device controller is not supported yet");
-                }
-            }
-        }
-        throw new Exception("Unable to find device controller");
-    }
-
-    public List<VirtualDisk> getVirtualDisks() throws Exception {
-        List<VirtualDisk> virtualDisks = new ArrayList<VirtualDisk>();
-
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        for (VirtualDevice device : devices) {
-            if (device instanceof VirtualDisk) {
-                virtualDisks.add((VirtualDisk)device);
-            }
-        }
-
-        return virtualDisks;
-    }
-
-    public List<String> detachAllDisksExcept(String vmdkBaseName, String deviceBusName) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
-        List<String> detachedDiskFiles = new ArrayList<String>();
-
-        for (VirtualDevice device : devices) {
-            if (device instanceof VirtualDisk) {
-                VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
-
-                VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)device.getBacking();
-
-                DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
-                String backingBaseName = dsBackingFile.getFileBaseName();
-                String deviceNumbering = getDeviceBusName(devices, device);
-                if (backingBaseName.equalsIgnoreCase(vmdkBaseName) || (deviceBusName != null && deviceBusName.equals(deviceNumbering))) {
-                    continue;
-                } else {
-                    s_logger.info("Detach " + diskBackingInfo.getFileName() + " from " + getName());
-
-                    detachedDiskFiles.add(diskBackingInfo.getFileName());
-
-                    deviceConfigSpec.setDevice(device);
-                    deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-
-                    reConfigSpec.getDeviceChange().add(deviceConfigSpec);
-                }
-            }
-        }
-
-        if (detachedDiskFiles.size() > 0) {
-            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (result) {
-                _context.waitForTaskProgressDone(morTask);
-            } else {
-                s_logger.warn("Unable to reconfigure the VM to detach disks");
-                throw new Exception("Unable to reconfigure the VM to detach disks");
-            }
-        }
-
-        return detachedDiskFiles;
-    }
-
-    public List<VirtualDevice> getAllDeviceList() throws Exception {
-        return _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-    }
-
-    public VirtualDisk[] getAllDiskDevice() throws Exception {
-        List<VirtualDisk> deviceList = new ArrayList<VirtualDisk>();
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    deviceList.add((VirtualDisk)device);
-                }
-            }
-        }
-
-        return deviceList.toArray(new VirtualDisk[0]);
-    }
-
-    public VirtualDisk getDiskDeviceByBusName(List<VirtualDevice> allDevices, String busName) throws Exception {
-        for (VirtualDevice device : allDevices) {
-            if (device instanceof VirtualDisk) {
-                VirtualDisk disk = (VirtualDisk)device;
-                String diskBusName = getDeviceBusName(allDevices, disk);
-                if (busName.equalsIgnoreCase(diskBusName))
-                    return disk;
-            }
-        }
-
-        return null;
-    }
-
-    public VirtualDisk[] getAllIndependentDiskDevice() throws Exception {
-        List<VirtualDisk> independentDisks = new ArrayList<VirtualDisk>();
-        VirtualDisk[] allDisks = getAllDiskDevice();
-        if (allDisks.length > 0) {
-            for (VirtualDisk disk : allDisks) {
-                String diskMode = "";
-                if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) {
-                    diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode();
-                } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
-                    diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode();
-                } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) {
-                    diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode();
-                } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) {
-                    diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode();
-                } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) {
-                    diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode();
-                }
-
-                if (diskMode.indexOf("independent") != -1) {
-                    independentDisks.add(disk);
-                }
-            }
-        }
-
-        return independentDisks.toArray(new VirtualDisk[0]);
-    }
-
-    public int tryGetIDEDeviceControllerKey() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualIDEController) {
-                    return ((VirtualIDEController)device).getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public int getIDEDeviceControllerKey() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualIDEController) {
-                    return ((VirtualIDEController)device).getKey();
-                }
-            }
-        }
-
-        assert (false);
-        throw new Exception("IDE Controller Not Found");
-    }
-
-    public int getIDEControllerKey(int ideUnitNumber) throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-            getDynamicProperty(_mor, "config.hardware.device");
-
-        int requiredIdeController = ideUnitNumber / VmwareHelper.MAX_IDE_CONTROLLER_COUNT;
-
-        int ideControllerCount = 0;
-        if(devices != null && devices.size() > 0) {
-            for(VirtualDevice device : devices) {
-                if(device instanceof VirtualIDEController) {
-                    if (ideControllerCount == requiredIdeController) {
-                        return ((VirtualIDEController)device).getKey();
-                    }
-                    ideControllerCount++;
-                }
-            }
-        }
-
-        assert(false);
-        throw new Exception("IDE Controller Not Found");
-    }
-
-    public int getNumberOfIDEDevices() throws Exception {
-        int ideDeviceCount = 0;
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualIDEController) {
-                    ideDeviceCount += ((VirtualIDEController)device).getDevice().size();
-                }
-            }
-        }
-        return ideDeviceCount;
-    }
-
-    public int getFreeUnitNumberOnIDEController(int controllerKey) throws Exception {
-        int freeUnitNumber = 0;
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        int deviceCount = 0;
-        int ideDeviceUnitNumber = -1;
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk && (controllerKey == device.getControllerKey())) {
-                    deviceCount++;
-                    ideDeviceUnitNumber = device.getUnitNumber();
-                }
-            }
-        }
-        if (deviceCount == 1) {
-            if (ideDeviceUnitNumber == 0) {
-                freeUnitNumber = 1;
-            } // else freeUnitNumber is already initialized to 0
-        } else if (deviceCount == 2) {
-            throw new Exception("IDE controller with key [" + controllerKey + "] already has 2 device attached. Cannot attach more than the limit of 2.");
-        }
-        return freeUnitNumber;
-    }
-    public int getNextIDEDeviceNumber() throws Exception {
-        int controllerKey = getIDEDeviceControllerKey();
-        return getNextDeviceNumber(controllerKey);
-    }
-
-    public VirtualDevice getIsoDevice() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualCdrom) {
-                    return device;
-                }
-            }
-        }
-        return null;
-    }
-
-    public VirtualDevice getIsoDevice(int key) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualCdrom && device.getKey() == key) {
-                    return device;
-                }
-            }
-        }
-        return null;
-    }
-
-    public VirtualDevice getIsoDevice(String filename) throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-        if(devices != null && devices.size() > 0) {
-            for(VirtualDevice device : devices) {
-                if(device instanceof VirtualCdrom && device.getBacking() instanceof VirtualCdromIsoBackingInfo &&
-                        ((VirtualCdromIsoBackingInfo)device.getBacking()).getFileName().equals(filename)) {
-                    return device;
-                }
-            }
-        }
-        return null;
-    }
-
-    public int getNextDeviceNumber(int controllerKey) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        List<Integer> existingUnitNumbers = new ArrayList<Integer>();
-        int deviceNumber = 0;
-        int scsiControllerKey = getGenericScsiDeviceControllerKeyNoException();
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) {
-                    existingUnitNumbers.add(device.getUnitNumber());
-                }
-            }
-        }
-        while (true) {
-            // Next device number should be the lowest device number on the key that is not in use and is not reserved.
-            if (!existingUnitNumbers.contains(Integer.valueOf(deviceNumber))) {
-                if (controllerKey != scsiControllerKey || !VmwareHelper.isReservedScsiDeviceNumber(deviceNumber))
-                    break;
-            }
-            ++deviceNumber;
-        }
-        return deviceNumber;
-    }
-
-    private List<VirtualDevice> getNicDevices(boolean sorted) throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        List<VirtualDevice> nics = new ArrayList<VirtualDevice>();
-        if (devices != null) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualEthernetCard) {
-                    nics.add(device);
-                }
-            }
-        }
-
-        if (sorted) {
-            Collections.sort(nics, new Comparator<VirtualDevice>() {
-                @Override
-                public int compare(VirtualDevice arg0, VirtualDevice arg1) {
-                    int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1;
-                    int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1;
-                    if (unitNumber0 < unitNumber1)
-                        return -1;
-                    else if (unitNumber0 > unitNumber1)
-                        return 1;
-                    return 0;
-                }
-            });
-        }
-
-        return nics;
-    }
-
-    public VirtualDevice[] getNicDevices() throws Exception {
-        return getNicDevices(false).toArray(new VirtualDevice[0]);
-    }
-
-    public VirtualDevice getNicDeviceByIndex(int index) throws Exception {
-        List<VirtualDevice> nics = getNicDevices(true);
-        try {
-            return nics.get(index);
-        } catch (IndexOutOfBoundsException e) {
-            // Not found
-            return null;
-        }
-    }
-
-    public Pair<Integer, VirtualDevice> getNicDeviceIndex(String networkNamePrefix) throws Exception {
-        List<VirtualDevice> nics = getNicDevices(true);
-
-        int index = 0;
-        String attachedNetworkSummary;
-        String dvPortGroupName;
-        for (VirtualDevice nic : nics) {
-            attachedNetworkSummary = ((VirtualEthernetCard)nic).getDeviceInfo().getSummary();
-            if (attachedNetworkSummary.startsWith(networkNamePrefix)) {
-                return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
-            } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary") || attachedNetworkSummary.startsWith("DVSwitch")) {
-                dvPortGroupName = getDvPortGroupName((VirtualEthernetCard)nic);
-                if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) {
-                    s_logger.debug("Found a dvPortGroup already associated with public NIC.");
-                    return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
-                }
-            }
-            index++;
-        }
-        return new Pair<Integer, VirtualDevice>(new Integer(-1), null);
-    }
-
-    public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception {
-        VirtualEthernetCardDistributedVirtualPortBackingInfo dvpBackingInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo)nic.getBacking();
-        DistributedVirtualSwitchPortConnection dvsPort = dvpBackingInfo.getPort();
-        String dvPortGroupKey = dvsPort.getPortgroupKey();
-        ManagedObjectReference dvPortGroupMor = new ManagedObjectReference();
-        dvPortGroupMor.setValue(dvPortGroupKey);
-        dvPortGroupMor.setType("DistributedVirtualPortgroup");
-        return (String)_context.getVimClient().getDynamicProperty(dvPortGroupMor, "name");
-    }
-
-    public VirtualDevice[] getMatchedDevices(Class<?>[] deviceClasses) throws Exception {
-        assert (deviceClasses != null);
-
-        List<VirtualDevice> returnList = new ArrayList<VirtualDevice>();
-
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null) {
-            for (VirtualDevice device : devices) {
-                for (Class<?> clz : deviceClasses) {
-                    if (clz.isInstance(device)) {
-                        returnList.add(device);
-                        break;
-                    }
-                }
-            }
-        }
-
-        return returnList.toArray(new VirtualDevice[0]);
-    }
-
-    public void mountToolsInstaller() throws Exception {
-        _context.getService().mountToolsInstaller(_mor);
-    }
-
-    public boolean unmountToolsInstaller() throws Exception {
-        // Monitor VM questions
-        final Boolean[] flags = {false};
-        final VirtualMachineMO vmMo = this;
-        final boolean[] encounterQuestion = new boolean[1];
-        encounterQuestion[0] = false;
-        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                s_logger.info("VM Question monitor started...");
-
-                while (!flags[0]) {
-                    try {
-                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
-                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
-                        if (question != null) {
-                            encounterQuestion[0] = true;
-                            if (s_logger.isTraceEnabled()) {
-                                s_logger.trace("Question id: " + question.getId());
-                                s_logger.trace("Question text: " + question.getText());
-                            }
-
-                            if (question.getMessage() != null) {
-                                for (VirtualMachineMessage msg : question.getMessage()) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("msg id: " + msg.getId());
-                                        s_logger.trace("msg text: " + msg.getText());
-                                    }
-                                    if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msg.getId())) {
-                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId() +
-                                                ", for safe operation we will automatically decline it");
-                                        vmMo.answerVM(question.getId(), ANSWER_NO);
-                                        break;
-                                    }
-                                }
-                            } else if (question.getText() != null) {
-                                String text = question.getText();
-                                String msgId;
-                                String msgText;
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("question text : " + text);
-                                }
-                                String[] tokens = text.split(":");
-                                msgId = tokens[0];
-                                msgText = tokens[1];
-                                if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msgId)) {
-                                    s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + question.getId() +
-                                            ". Message id : " + msgId + ". Message text : " + msgText + ", for safe operation we will automatically decline it.");
-                                    vmMo.answerVM(question.getId(), ANSWER_NO);
-                                }
-                            }
-
-                            ChoiceOption choice = question.getChoice();
-                            if (choice != null) {
-                                for (ElementDescription info : choice.getChoiceInfo()) {
-                                    if (s_logger.isTraceEnabled()) {
-                                        s_logger.trace("Choice option key: " + info.getKey());
-                                        s_logger.trace("Choice option label: " + info.getLabel());
-                                    }
-                                }
-                            }
-                        }
-                    } catch (Throwable e) {
-                        s_logger.error("Unexpected exception: ", e);
-                    }
-
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {
-                        s_logger.debug("[ignored] interupted while handling vm question about umount tools install.");
-                    }
-                }
-
-                s_logger.info("VM Question monitor stopped");
-            }
-        });
-
-        try {
-            _context.getService().unmountToolsInstaller(_mor);
-        } finally {
-            flags[0] = true;
-            future.cancel(true);
-        }
-        if (encounterQuestion[0]) {
-            s_logger.warn("cdrom is locked by VM. Failed to detach the ISO.");
-            return false;
-        } else {
-            s_logger.info("Successfully unmounted tools installer from VM.");
-            return true;
-        }
-    }
-
-    public void redoRegistration(ManagedObjectReference morHost) throws Exception {
-        String vmName = getVmName();
-        VirtualMachineFileInfo vmFileInfo = getFileInfo();
-        boolean isTemplate = isTemplate();
-
-        HostMO hostMo;
-        if (morHost != null)
-            hostMo = new HostMO(getContext(), morHost);
-        else
-            hostMo = getRunningHost();
-
-        ManagedObjectReference morFolder = getParentMor();
-        ManagedObjectReference morPool = hostMo.getHyperHostOwnerResourcePool();
-
-        _context.getService().unregisterVM(_mor);
-
-        ManagedObjectReference morTask = _context.getService().registerVMTask(morFolder, vmFileInfo.getVmPathName(), vmName, false, morPool, hostMo.getMor());
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (!result) {
-            throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        } else {
-            _context.waitForTaskProgressDone(morTask);
-            if (isTemplate) {
-                VirtualMachineMO vmNewRegistration = hostMo.findVmOnHyperHost(vmName);
-                assert (vmNewRegistration != null);
-                vmNewRegistration.markAsTemplate();
-            }
-        }
-    }
-
-    public long getHotAddMemoryIncrementSizeInMb() throws Exception {
-        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize");
-    }
-
-    public long getHotAddMemoryLimitInMb() throws Exception {
-        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit");
-    }
-    public String getGuestId() throws Exception {
-        return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId");
-    }
-
-    public int getCoresPerSocket() throws Exception {
-        // number of cores per socket is 1 in case of ESXi. It's not defined explicitly and the property is support since vSphere API 5.0.
-        String apiVersion = HypervisorHostHelper.getVcenterApiVersion(_context);
-        if (apiVersion.compareTo("5.0") < 0) {
-            return 1;
-        }
-        Integer coresPerSocket = (Integer)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket");
-        return coresPerSocket != null ? coresPerSocket : 1;
-    }
-
-    public int getVirtualHardwareVersion() throws Exception {
-        VirtualHardwareOption vhOption = getVirtualHardwareOption();
-        return vhOption.getHwVersion();
-    }
-
-    public VirtualHardwareOption getVirtualHardwareOption() throws Exception {
-        VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
-        return vmConfigOption.getHardwareOptions();
-    }
-
-    private ManagedObjectReference getEnvironmentBrowser() throws Exception {
-        if (_vmEnvironmentBrowser == null) {
-            _vmEnvironmentBrowser = _context.getVimClient().getMoRefProp(_mor, "environmentBrowser");
-        }
-        return _vmEnvironmentBrowser;
-    }
-
-    public boolean isCpuHotAddSupported(String guestOsId) throws Exception {
-        boolean guestOsSupportsCpuHotAdd = false;
-        boolean virtualHardwareSupportsCpuHotAdd = false;
-        GuestOsDescriptor guestOsDescriptor;
-        int virtualHardwareVersion;
-        int numCoresPerSocket;
-
-        guestOsDescriptor = getGuestOsDescriptor(guestOsId);
-        virtualHardwareVersion = getVirtualHardwareVersion();
-
-        // Check if guest operating system supports cpu hotadd
-        if (guestOsDescriptor.isSupportsCpuHotAdd()) {
-            guestOsSupportsCpuHotAdd = true;
-        }
-
-        // Check if virtual machine is using hardware version 8 or later.
-        // If hardware version is 7, then only 1 core per socket is supported. Hot adding multi-core vcpus is not allowed if hardware version is 7.
-        if (virtualHardwareVersion >= 8) {
-            virtualHardwareSupportsCpuHotAdd = true;
-        } else if (virtualHardwareVersion == 7) {
-            // Check if virtual machine has only 1 core per socket.
-            numCoresPerSocket = getCoresPerSocket();
-            if (numCoresPerSocket == 1) {
-                virtualHardwareSupportsCpuHotAdd = true;
-            }
-        }
-        return guestOsSupportsCpuHotAdd && virtualHardwareSupportsCpuHotAdd;
-    }
-
-    public boolean isMemoryHotAddSupported(String guestOsId) throws Exception {
-        boolean guestOsSupportsMemoryHotAdd = false;
-        boolean virtualHardwareSupportsMemoryHotAdd = false;
-        GuestOsDescriptor guestOsDescriptor;
-        int virtualHardwareVersion;
-
-        guestOsDescriptor = getGuestOsDescriptor(guestOsId);
-        virtualHardwareVersion = getVirtualHardwareVersion();
-
-        // Check if guest operating system supports memory hotadd
-        if (guestOsDescriptor != null && guestOsDescriptor.isSupportsMemoryHotAdd()) {
-            guestOsSupportsMemoryHotAdd = true;
-        }
-        // Check if virtual machine is using hardware version 7 or later.
-        if (virtualHardwareVersion >= 7) {
-            virtualHardwareSupportsMemoryHotAdd = true;
-        }
-        return guestOsSupportsMemoryHotAdd && virtualHardwareSupportsMemoryHotAdd;
-    }
-    public void ensureLsiLogicSasDeviceControllers(int count, int availableBusNum) throws Exception {
-        int scsiControllerKey = getLsiLogicSasDeviceControllerKeyNoException();
-        if (scsiControllerKey < 0) {
-            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-            int busNum = availableBusNum;
-            while (busNum < count) {
-                VirtualLsiLogicSASController scsiController = new VirtualLsiLogicSASController();
-                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-                scsiController.setBusNumber(busNum);
-                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
-                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-                scsiControllerSpec.setDevice(scsiController);
-                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                vmConfig.getDeviceChange().add(scsiControllerSpec);
-                busNum++;
-            }
-            if (configureVm(vmConfig)) {
-                throw new Exception("Unable to add Scsi controller of type LsiLogic SAS.");
-            }
-        }
-
-    }
-
-    private int getLsiLogicSasDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualLsiLogicSASController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public void ensureBusLogicDeviceControllers(int count, int availableBusNum) throws Exception {
-        int scsiControllerKey = getBusLogicDeviceControllerKeyNoException();
-        if (scsiControllerKey < 0) {
-            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
-
-            int busNum = availableBusNum;
-            while (busNum < count) {
-                VirtualBusLogicController scsiController = new VirtualBusLogicController();
-
-                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
-                scsiController.setBusNumber(busNum);
-                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
-                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
-                scsiControllerSpec.setDevice(scsiController);
-                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-                vmConfig.getDeviceChange().add(scsiControllerSpec);
-                busNum++;
-            }
-
-            if (configureVm(vmConfig)) {
-                throw new Exception("Unable to add Scsi BusLogic controllers to the VM " + getName());
-            } else {
-                s_logger.info("Successfully added " + count + " SCSI BusLogic controllers.");
-            }
-        }
-    }
-
-    private int getBusLogicDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualBusLogicController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public Ternary<Integer, Integer, DiskControllerType> getScsiControllerInfo() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
-
-        int scsiControllerCount = 0;
-        int busNum = -1;
-        DiskControllerType controllerType = DiskControllerType.lsilogic;
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualSCSIController) {
-                    scsiControllerCount++;
-                    int deviceBus = ((VirtualSCSIController)device).getBusNumber();
-                    if (busNum < deviceBus) {
-                        busNum = deviceBus;
-                    }
-                    if (device instanceof VirtualLsiLogicController) {
-                        controllerType = DiskControllerType.lsilogic;
-                    } else if (device instanceof VirtualLsiLogicSASController) {
-                        controllerType = DiskControllerType.lsisas1068;
-                    } else if (device instanceof VirtualBusLogicController) {
-                        controllerType = DiskControllerType.buslogic;
-                    } else if (device instanceof ParaVirtualSCSIController) {
-                        controllerType = DiskControllerType.pvscsi;
-                    }
-                }
-            }
-        }
-
-        return new Ternary<Integer, Integer, DiskControllerType>(scsiControllerCount, busNum, controllerType);
-    }
-
-    public int getNumberOfVirtualDisks() throws Exception {
-        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
-
-        s_logger.info("Counting disk devices attached to VM " + getVmName());
-        int count = 0;
-
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualDisk) {
-                    count++;
-                }
-            }
-        }
-        return count;
-    }
-
-    public boolean consolidateVmDisks() throws Exception {
-        ManagedObjectReference morTask = _context.getService().consolidateVMDisksTask(_mor);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware ConsolidateVMDisks_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-        return false;
-    }
-}
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/BaseMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/BaseMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreFile.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreFile.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreFile.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreFile.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DiskControllerType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DiskControllerType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/DiskControllerType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DiskControllerType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DistributedVirtualSwitchMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DistributedVirtualSwitchMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/DistributedVirtualSwitchMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DistributedVirtualSwitchMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/FeatureKeyConstants.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/FeatureKeyConstants.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/FeatureKeyConstants.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/FeatureKeyConstants.java
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java
new file mode 100644
index 0000000..4110bfc
--- /dev/null
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreBrowserMO.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.mo;
+
+import java.util.ArrayList;
+
+import org.apache.log4j.Logger;
+
+import com.vmware.vim25.HostDatastoreBrowserSearchResults;
+import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
+import com.vmware.vim25.ManagedObjectReference;
+
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+
+public class HostDatastoreBrowserMO extends BaseMO {
+
+    private static final Logger s_logger = Logger.getLogger(HostDatastoreBrowserMO.class);
+
+    public HostDatastoreBrowserMO(VmwareContext context, ManagedObjectReference morHostDatastoreBrowser) {
+        super(context, morHostDatastoreBrowser);
+    }
+
+    public HostDatastoreBrowserMO(VmwareContext context, String morType, String morValue) {
+        super(context, morType, morValue);
+    }
+
+    public void DeleteFile(String datastoreFullPath) throws Exception {
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - deleteFile(). target mor: " + _mor.getValue() + ", file datastore path: " + datastoreFullPath);
+
+        _context.getService().deleteFile(_mor, datastoreFullPath);
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - deleteFile() done");
+    }
+
+    public HostDatastoreBrowserSearchResults searchDatastore(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception {
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - searchDatastore(). target mor: " + _mor.getValue() + ", file datastore path: " + datastorePath);
+
+        try {
+            ManagedObjectReference morTask = _context.getService().searchDatastoreTask(_mor, datastorePath, searchSpec);
+
+            boolean result = _context.getVimClient().waitForTask(morTask);
+            if (result) {
+                _context.waitForTaskProgressDone(morTask);
+
+                return (HostDatastoreBrowserSearchResults)_context.getVimClient().getDynamicProperty(morTask, "info.result");
+            } else {
+                s_logger.error("VMware searchDaastore_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+        } finally {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - searchDatastore() done");
+        }
+
+        return null;
+    }
+
+    public HostDatastoreBrowserSearchResults searchDatastore(String datastorePath, String fileName, boolean caseInsensitive) throws Exception {
+        HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec();
+        spec.setSearchCaseInsensitive(caseInsensitive);
+        spec.getMatchPattern().add(fileName);
+
+        return searchDatastore(datastorePath, spec);
+    }
+
+    @SuppressWarnings("unchecked")
+    public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, HostDatastoreBrowserSearchSpec searchSpec) throws Exception {
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - searchDatastoreSubFolders(). target mor: " + _mor.getValue() + ", file datastore path: " + datastorePath);
+
+        try {
+            ManagedObjectReference morTask = _context.getService().searchDatastoreSubFoldersTask(_mor, datastorePath, searchSpec);
+
+            boolean result = _context.getVimClient().waitForTask(morTask);
+            if (result) {
+                _context.waitForTaskProgressDone(morTask);
+
+                return (ArrayList<HostDatastoreBrowserSearchResults>)_context.getVimClient().getDynamicProperty(morTask, "info.result");
+            } else {
+                s_logger.error("VMware searchDaastoreSubFolders_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+        } finally {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - searchDatastoreSubFolders() done");
+        }
+
+        return null;
+    }
+
+    public ArrayList<HostDatastoreBrowserSearchResults> searchDatastoreSubFolders(String datastorePath, String fileName, boolean caseInsensitive) throws Exception {
+        HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec();
+        spec.setSearchCaseInsensitive(caseInsensitive);
+        spec.getMatchPattern().add(fileName);
+
+        return searchDatastoreSubFolders(datastorePath, spec);
+    }
+}
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostFirewallSystemMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostFirewallSystemMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostFirewallSystemMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostFirewallSystemMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostNetworkSystemMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostNetworkSystemMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostNetworkSystemMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostNetworkSystemMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostStorageSystemMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostStorageSystemMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostStorageSystemMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostStorageSystemMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostVirtualNicType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostVirtualNicType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HostVirtualNicType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostVirtualNicType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HttpNfcLeaseMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HttpNfcLeaseMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HttpNfcLeaseMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HttpNfcLeaseMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/LicenseAssignmentManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/LicenseAssignmentManagerMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/LicenseAssignmentManagerMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/LicenseAssignmentManagerMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/LicenseManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/LicenseManagerMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/LicenseManagerMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/LicenseManagerMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/NetworkDetails.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/NetworkDetails.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/NetworkDetails.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/NetworkDetails.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/NetworkMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/NetworkMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/NetworkMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/NetworkMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/PerfCounterInfoMapper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PerfCounterInfoMapper.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/PerfCounterInfoMapper.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PerfCounterInfoMapper.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/PerfManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PerfManagerMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/PerfManagerMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PerfManagerMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ScsiDiskControllerType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ScsiDiskControllerType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/ScsiDiskControllerType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ScsiDiskControllerType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/SnapshotDescriptor.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/TaskMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/TaskMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VersioningContants.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VersioningContants.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VersioningContants.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VersioningContants.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualDiskManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualDiskManagerMO.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualDiskManagerMO.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualDiskManagerMO.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualEthernetCardType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualEthernetCardType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualEthernetCardType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualEthernetCardType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineDiskInfoBuilder.java
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
new file mode 100644
index 0000000..d9d03d1
--- /dev/null
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -0,0 +1,3451 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.mo;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+
+import com.google.gson.Gson;
+import com.vmware.vim25.ArrayOfManagedObjectReference;
+import com.vmware.vim25.ChoiceOption;
+import com.vmware.vim25.CustomFieldStringValue;
+import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
+import com.vmware.vim25.DynamicProperty;
+import com.vmware.vim25.ElementDescription;
+import com.vmware.vim25.GuestInfo;
+import com.vmware.vim25.GuestOsDescriptor;
+import com.vmware.vim25.HttpNfcLeaseDeviceUrl;
+import com.vmware.vim25.HttpNfcLeaseInfo;
+import com.vmware.vim25.HttpNfcLeaseState;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.ObjectContent;
+import com.vmware.vim25.ObjectSpec;
+import com.vmware.vim25.OptionValue;
+import com.vmware.vim25.OvfCreateDescriptorParams;
+import com.vmware.vim25.OvfCreateDescriptorResult;
+import com.vmware.vim25.OvfFile;
+import com.vmware.vim25.ParaVirtualSCSIController;
+import com.vmware.vim25.PropertyFilterSpec;
+import com.vmware.vim25.PropertySpec;
+import com.vmware.vim25.TraversalSpec;
+import com.vmware.vim25.VirtualBusLogicController;
+import com.vmware.vim25.VirtualCdrom;
+import com.vmware.vim25.VirtualCdromIsoBackingInfo;
+import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
+import com.vmware.vim25.VirtualController;
+import com.vmware.vim25.VirtualDevice;
+import com.vmware.vim25.VirtualDeviceBackingInfo;
+import com.vmware.vim25.VirtualDeviceConfigSpec;
+import com.vmware.vim25.VirtualDeviceConfigSpecFileOperation;
+import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
+import com.vmware.vim25.VirtualDeviceConnectInfo;
+import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualDiskFlatVer1BackingInfo;
+import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
+import com.vmware.vim25.VirtualDiskMode;
+import com.vmware.vim25.VirtualDiskRawDiskMappingVer1BackingInfo;
+import com.vmware.vim25.VirtualDiskSparseVer1BackingInfo;
+import com.vmware.vim25.VirtualDiskSparseVer2BackingInfo;
+import com.vmware.vim25.VirtualDiskType;
+import com.vmware.vim25.VirtualEthernetCard;
+import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
+import com.vmware.vim25.VirtualHardwareOption;
+import com.vmware.vim25.VirtualIDEController;
+import com.vmware.vim25.VirtualLsiLogicController;
+import com.vmware.vim25.VirtualLsiLogicSASController;
+import com.vmware.vim25.VirtualMachineCloneSpec;
+import com.vmware.vim25.VirtualMachineConfigInfo;
+import com.vmware.vim25.VirtualMachineConfigOption;
+import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.VirtualMachineConfigSummary;
+import com.vmware.vim25.VirtualMachineFileInfo;
+import com.vmware.vim25.VirtualMachineFileLayoutEx;
+import com.vmware.vim25.VirtualMachineMessage;
+import com.vmware.vim25.VirtualMachineMovePriority;
+import com.vmware.vim25.VirtualMachinePowerState;
+import com.vmware.vim25.VirtualMachineQuestionInfo;
+import com.vmware.vim25.VirtualMachineRelocateDiskMoveOptions;
+import com.vmware.vim25.VirtualMachineRelocateSpec;
+import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
+import com.vmware.vim25.VirtualMachineRuntimeInfo;
+import com.vmware.vim25.VirtualMachineSnapshotInfo;
+import com.vmware.vim25.VirtualMachineSnapshotTree;
+import com.vmware.vim25.VirtualSCSIController;
+import com.vmware.vim25.VirtualSCSISharing;
+
+import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.hypervisor.vmware.util.VmwareHelper;
+import com.cloud.utils.ActionDelegate;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.concurrency.NamedThreadFactory;
+import com.cloud.utils.script.Script;
+
+public class VirtualMachineMO extends BaseMO {
+    private static final Logger s_logger = Logger.getLogger(VirtualMachineMO.class);
+    private static final ExecutorService MonitorServiceExecutor = Executors.newCachedThreadPool(new NamedThreadFactory("VM-Question-Monitor"));
+
+    public static final String ANSWER_YES = "0";
+    public static final String ANSWER_NO = "1";
+
+    private ManagedObjectReference _vmEnvironmentBrowser = null;
+
+    public VirtualMachineMO(VmwareContext context, ManagedObjectReference morVm) {
+        super(context, morVm);
+    }
+
+    public VirtualMachineMO(VmwareContext context, String morType, String morValue) {
+        super(context, morType, morValue);
+    }
+
+    public Pair<DatacenterMO, String> getOwnerDatacenter() throws Exception {
+        return DatacenterMO.getOwnerDatacenter(getContext(), getMor());
+    }
+
+    public Pair<DatastoreMO, String> getOwnerDatastore(String dsFullPath) throws Exception {
+        String dsName = DatastoreFile.getDatastoreNameFromPath(dsFullPath);
+
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("Datastore");
+        pSpec.getPathSet().add("name");
+
+        TraversalSpec vmDatastoreTraversal = new TraversalSpec();
+        vmDatastoreTraversal.setType("VirtualMachine");
+        vmDatastoreTraversal.setPath("datastore");
+        vmDatastoreTraversal.setName("vmDatastoreTraversal");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.TRUE);
+        oSpec.getSelectSet().add(vmDatastoreTraversal);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        if (ocs != null) {
+            for (ObjectContent oc : ocs) {
+                DynamicProperty prop = oc.getPropSet().get(0);
+                if (prop.getVal().toString().equals(dsName)) {
+                    return new Pair<DatastoreMO, String>(new DatastoreMO(_context, oc.getObj()), dsName);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public HostMO getRunningHost() throws Exception {
+        VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
+        return new HostMO(_context, runtimeInfo.getHost());
+    }
+
+    public String getVmName() throws Exception {
+        return (String)getContext().getVimClient().getDynamicProperty(_mor, "name");
+    }
+
+    public GuestInfo getVmGuestInfo() throws Exception {
+        return (GuestInfo)getContext().getVimClient().getDynamicProperty(_mor, "guest");
+    }
+
+    public void answerVM(String questionId, String choice) throws Exception {
+        getContext().getService().answerVM(_mor, questionId, choice);
+    }
+
+    public boolean isVMwareToolsRunning() throws Exception {
+        GuestInfo guestInfo = getVmGuestInfo();
+        if (guestInfo != null) {
+            if ("guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus()))
+                return true;
+        }
+        return false;
+    }
+
+    public boolean powerOn() throws Exception {
+        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_ON)
+            return true;
+
+        ManagedObjectReference morTask = _context.getService().powerOnVMTask(_mor, null);
+        // Monitor VM questions
+        final Boolean[] flags = {false};
+        final VirtualMachineMO vmMo = this;
+        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
+            @Override
+            public void run() {
+                s_logger.info("VM Question monitor started...");
+
+                while (!flags[0]) {
+                    try {
+                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
+                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
+                        if (question != null) {
+                            s_logger.info("Question id: " + question.getId());
+                            s_logger.info("Question text: " + question.getText());
+                            if (question.getMessage() != null) {
+                                for (VirtualMachineMessage msg : question.getMessage()) {
+                                    if (s_logger.isInfoEnabled()) {
+                                        s_logger.info("msg id: " + msg.getId());
+                                        s_logger.info("msg text: " + msg.getText());
+                                    }
+                                    if ("msg.uuid.altered".equalsIgnoreCase(msg.getId())) {
+                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId()
+                                                + ", we will automatically answer as 'moved it' to address out of band HA for the VM");
+                                        vmMo.answerVM(question.getId(), "1");
+                                        break;
+                                    }
+                                }
+                            }
+
+                            if (s_logger.isTraceEnabled())
+                                s_logger.trace("These are the choices we can have just in case");
+                            ChoiceOption choice = question.getChoice();
+                            if (choice != null) {
+                                for (ElementDescription info : choice.getChoiceInfo()) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("Choice option key: " + info.getKey());
+                                        s_logger.trace("Choice option label: " + info.getLabel());
+                                    }
+                                }
+                            }
+                        }
+                    } catch (Throwable e) {
+                        s_logger.error("Unexpected exception: ", e);
+                    }
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        s_logger.debug("[ignored] interupted while dealing with vm questions.");
+                    }
+                }
+                s_logger.info("VM Question monitor stopped");
+            }
+        });
+
+        try {
+            boolean result = _context.getVimClient().waitForTask(morTask);
+            if (result) {
+                _context.waitForTaskProgressDone(morTask);
+                return true;
+            } else {
+                s_logger.error("VMware powerOnVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+        } finally {
+            // make sure to let VM question monitor exit
+            flags[0] = true;
+        }
+
+        return false;
+    }
+
+    public boolean powerOff() throws Exception {
+        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF)
+            return true;
+
+        return powerOffNoCheck();
+    }
+
+    public boolean safePowerOff(int shutdownWaitMs) throws Exception {
+
+        if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF)
+            return true;
+
+        if (isVMwareToolsRunning()) {
+            try {
+                String vmName = getName();
+
+                s_logger.info("Try gracefully shut down VM " + vmName);
+                shutdown();
+
+                long startTick = System.currentTimeMillis();
+                while (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF && System.currentTimeMillis() - startTick < shutdownWaitMs) {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        s_logger.debug("[ignored] interupted while powering of vm.");
+                    }
+                }
+
+                if (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF) {
+                    s_logger.info("can not gracefully shutdown VM within " + (shutdownWaitMs / 1000) + " seconds, we will perform force power off on VM " + vmName);
+                    return powerOffNoCheck();
+                }
+
+                return true;
+            } catch (Exception e) {
+                s_logger.warn("Failed to do guest-os graceful shutdown due to " + VmwareHelper.getExceptionMessage(e));
+            }
+        }
+
+        return powerOffNoCheck();
+    }
+
+    private boolean powerOffNoCheck() throws Exception {
+        ManagedObjectReference morTask = _context.getService().powerOffVMTask(_mor);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+
+            // It seems that even if a power-off task is returned done, VM state may still not be marked,
+            // wait up to 5 seconds to make sure to avoid race conditioning for immediate following on operations
+            // that relies on a powered-off VM
+            long startTick = System.currentTimeMillis();
+            while (getResetSafePowerState() != VirtualMachinePowerState.POWERED_OFF && System.currentTimeMillis() - startTick < 5000) {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    s_logger.debug("[ignored] interupted while powering of vm unconditionaly.");
+                }
+            }
+            return true;
+        } else {
+            if (getResetSafePowerState() == VirtualMachinePowerState.POWERED_OFF) {
+                // to help deal with possible race-condition
+                s_logger.info("Current power-off task failed. However, VM has been switched to the state we are expecting for");
+                return true;
+            }
+
+            s_logger.error("VMware powerOffVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public VirtualMachinePowerState getResetSafePowerState() throws Exception {
+
+        VirtualMachinePowerState powerState = VirtualMachinePowerState.POWERED_OFF;
+
+        // This is really ugly, there is a case that when windows guest VM is doing sysprep, the temporary
+        // rebooting process may let us pick up a "poweredOff" state during VMsync process, this can trigger
+        // a series actions. Unfortunately, from VMware API we can not distinguish power state into such details.
+        // We hope by giving it 3 second to re-read the state can cover this as a short-term solution.
+        //
+        // In the future, VMsync should not kick off CloudStack action (this is not a HA case) based on VM
+        // state report, until then we can remove this hacking fix
+        for (int i = 0; i < 3; i++) {
+            powerState = (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
+            if (powerState == VirtualMachinePowerState.POWERED_OFF) {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    s_logger.debug("[ignored] interupted while pausing after power off.");
+                }
+            } else {
+                break;
+            }
+        }
+
+        return powerState;
+    }
+
+    public VirtualMachinePowerState getPowerState() throws Exception {
+        return (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState");
+    }
+
+    public boolean reset() throws Exception {
+        ManagedObjectReference morTask = _context.getService().resetVMTask(_mor);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware resetVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public void shutdown() throws Exception {
+        _context.getService().shutdownGuest(_mor);
+    }
+
+    public void rebootGuest() throws Exception {
+        _context.getService().rebootGuest(_mor);
+    }
+
+    public void markAsTemplate() throws Exception {
+        _context.getService().markAsTemplate(_mor);
+    }
+
+    public boolean isTemplate() throws Exception {
+        VirtualMachineConfigInfo configInfo = getConfigInfo();
+        return configInfo.isTemplate();
+    }
+
+    public boolean migrate(ManagedObjectReference morRp, ManagedObjectReference morTargetHost) throws Exception {
+        ManagedObjectReference morTask = _context.getService().migrateVMTask(_mor, morRp, morTargetHost, VirtualMachineMovePriority.DEFAULT_PRIORITY, null);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware migrateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public boolean changeDatastore(VirtualMachineRelocateSpec relocateSpec) throws Exception {
+        ManagedObjectReference morTask = _context.getVimClient().getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware RelocateVM_Task to change datastore failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public boolean changeHost(VirtualMachineRelocateSpec relocateSpec) throws Exception {
+        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware RelocateVM_Task to change host failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public boolean changeDatastore(ManagedObjectReference morDataStore) throws Exception {
+        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
+        relocateSpec.setDatastore(morDataStore);
+
+        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware change datastore relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
+        VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
+        relocateSpec.setHost(morTargetHost);
+
+        ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public VirtualMachineSnapshotInfo getSnapshotInfo() throws Exception {
+        return (VirtualMachineSnapshotInfo)_context.getVimClient().getDynamicProperty(_mor, "snapshot");
+    }
+
+    public boolean createSnapshot(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception {
+        return createSnapshotGetReference(snapshotName, snapshotDescription, dumpMemory, quiesce) != null;
+    }
+
+    public ManagedObjectReference createSnapshotGetReference(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception {
+        long apiTimeout = _context.getVimClient().getVcenterSessionTimeout();
+        ManagedObjectReference morTask = _context.getService().createSnapshotTask(_mor, snapshotName, snapshotDescription, dumpMemory, quiesce);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+
+            ManagedObjectReference morSnapshot = null;
+
+            // We still need to wait until the object appear in vCenter
+            long startTick = System.currentTimeMillis();
+
+            while (System.currentTimeMillis() - startTick < apiTimeout) {
+                morSnapshot = getSnapshotMor(snapshotName);
+
+                if (morSnapshot != null) {
+                    break;
+                }
+
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    s_logger.debug("[ignored] interupted while waiting for snapshot to be done.");
+                }
+            }
+
+            if (morSnapshot == null) {
+                s_logger.error("We've been waiting for over " + apiTimeout + " milli seconds for snapshot MOR to be appearing in vCenter after CreateSnapshot task is done, " +
+                        "but it is still not there?!");
+
+                return null;
+            }
+
+            s_logger.debug("Waited for " + (System.currentTimeMillis() - startTick) + " seconds for snapshot object [" + snapshotName + "] to appear in vCenter.");
+
+            return morSnapshot;
+        } else {
+            s_logger.error("VMware createSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return null;
+    }
+
+    public boolean removeSnapshot(String snapshotName, boolean removeChildren) throws Exception {
+        ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
+        if (morSnapshot == null) {
+            s_logger.warn("Unable to find snapshot: " + snapshotName);
+            return false;
+        }
+
+        ManagedObjectReference morTask = _context.getService().removeSnapshotTask(morSnapshot, removeChildren, true);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware removeSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public boolean revertToSnapshot(String snapshotName) throws Exception {
+        ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
+        if (morSnapshot == null) {
+            s_logger.warn("Unable to find snapshot: " + snapshotName);
+            return false;
+        }
+        ManagedObjectReference morTask = _context.getService().revertToSnapshotTask(morSnapshot, _mor, null);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware revert to snapshot failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    /**
+     * Deletes all of the snapshots of a VM.
+     */
+    public void consolidateAllSnapshots() throws Exception {
+        ManagedObjectReference task = _context.getService().removeAllSnapshotsTask(_mor, true);
+
+        boolean result = _context.getVimClient().waitForTask(task);
+
+        if (result) {
+            _context.waitForTaskProgressDone(task);
+        } else {
+            throw new Exception("Unable to register VM due to the following issue: " + TaskMO.getTaskFailureInfo(_context, task));
+        }
+    }
+
+    public boolean removeAllSnapshots() throws Exception {
+        VirtualMachineSnapshotInfo snapshotInfo = getSnapshotInfo();
+
+        if (snapshotInfo != null && snapshotInfo.getRootSnapshotList() != null) {
+            List<VirtualMachineSnapshotTree> tree = snapshotInfo.getRootSnapshotList();
+            for (VirtualMachineSnapshotTree treeNode : tree) {
+                ManagedObjectReference morTask = _context.getService().removeSnapshotTask(treeNode.getSnapshot(), true, true);
+                boolean result = _context.getVimClient().waitForTask(morTask);
+                if (result) {
+                    _context.waitForTaskProgressDone(morTask);
+                } else {
+                    s_logger.error("VMware removeSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public String
+    getSnapshotDiskFileDatastorePath(VirtualMachineFileInfo vmFileInfo, List<Pair<ManagedObjectReference, String>> datastoreMounts, String snapshotDiskFile)
+            throws Exception {
+
+        // if file path start with "/", need to search all datastore mounts on the host in order
+        // to form fully qualified datastore path
+        if (snapshotDiskFile.startsWith("/")) {
+            for (Pair<ManagedObjectReference, String> mount : datastoreMounts) {
+                if (snapshotDiskFile.startsWith(mount.second())) {
+                    DatastoreMO dsMo = new DatastoreMO(_context, mount.first());
+
+                    String dsFullPath = String.format("[%s] %s", dsMo.getName(), snapshotDiskFile.substring(mount.second().length() + 1));
+                    s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + dsFullPath);
+                    return dsFullPath;
+                }
+            }
+
+            s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + snapshotDiskFile);
+            return snapshotDiskFile;
+        } else {
+
+            // snapshot directory string from VirtualMachineFileInfo ends with /
+            String dsFullPath = vmFileInfo.getSnapshotDirectory() + snapshotDiskFile;
+            s_logger.info("Convert snapshot disk file name to datastore path. " + snapshotDiskFile + "->" + dsFullPath);
+            return dsFullPath;
+        }
+    }
+
+    public SnapshotDescriptor getSnapshotDescriptor() throws Exception {
+
+        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
+
+        String dsPath = getSnapshotDescriptorDatastorePath();
+        assert (dsPath != null);
+        String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), dsPath);
+        byte[] content = getContext().getResourceContent(url);
+
+        if (content == null || content.length < 1) {
+            s_logger.warn("Snapshot descriptor file (vsd) does not exist anymore?");
+        }
+
+        SnapshotDescriptor descriptor = new SnapshotDescriptor();
+        descriptor.parse(content);
+        return descriptor;
+    }
+
+    public String getSnapshotDescriptorDatastorePath() throws Exception {
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("VirtualMachine");
+        pSpec.getPathSet().add("name");
+        pSpec.getPathSet().add("config.files");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.FALSE);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+        assert (ocs != null);
+
+        String vmName = null;
+        VirtualMachineFileInfo fileInfo = null;
+
+        assert (ocs.size() == 1);
+        for (ObjectContent oc : ocs) {
+            List<DynamicProperty> props = oc.getPropSet();
+            if (props != null) {
+                assert (props.size() == 2);
+
+                for (DynamicProperty prop : props) {
+                    if (prop.getName().equals("name")) {
+                        vmName = prop.getVal().toString();
+                    } else {
+                        fileInfo = (VirtualMachineFileInfo)prop.getVal();
+                    }
+                }
+            }
+        }
+        assert (vmName != null);
+        assert (fileInfo != null);
+
+        // .vmsd file exists at the same directory of .vmx file
+        DatastoreFile vmxFile = new DatastoreFile(fileInfo.getVmPathName());
+        return vmxFile.getCompanionPath(vmName + ".vmsd");
+    }
+
+    public ManagedObjectReference getSnapshotMor(String snapshotName) throws Exception {
+        VirtualMachineSnapshotInfo info = getSnapshotInfo();
+        if (info != null) {
+            List<VirtualMachineSnapshotTree> snapTree = info.getRootSnapshotList();
+            return VmwareHelper.findSnapshotInTree(snapTree, snapshotName);
+        }
+        return null;
+    }
+
+    public boolean hasSnapshot() throws Exception {
+        VirtualMachineSnapshotInfo info = getSnapshotInfo();
+        if (info != null) {
+            ManagedObjectReference currentSnapshot = info.getCurrentSnapshot();
+            if (currentSnapshot != null) {
+                return true;
+            }
+            List<VirtualMachineSnapshotTree> rootSnapshotList = info.getRootSnapshotList();
+            if (rootSnapshotList != null && rootSnapshotList.size() > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean createFullClone(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs)
+            throws Exception {
+
+        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
+        VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec();
+        cloneSpec.setLocation(relocSpec);
+        cloneSpec.setPowerOn(false);
+        cloneSpec.setTemplate(false);
+
+        relocSpec.setDatastore(morDs);
+        relocSpec.setPool(morResourcePool);
+        ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public boolean createLinkedClone(String cloneName, ManagedObjectReference morBaseSnapshot, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool,
+            ManagedObjectReference morDs) throws Exception {
+
+        assert (morBaseSnapshot != null);
+        assert (morFolder != null);
+        assert (morResourcePool != null);
+        assert (morDs != null);
+
+        VirtualDisk[] independentDisks = getAllIndependentDiskDevice();
+        VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
+        if (independentDisks.length > 0) {
+            List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(independentDisks.length);
+            for (int i = 0; i < independentDisks.length; i++) {
+                VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
+                loc.setDatastore(morDs);
+                loc.setDiskId(independentDisks[i].getKey());
+                loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
+                diskLocator.add(loc);
+            }
+
+            rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
+            rSpec.getDisk().addAll(diskLocator);
+        } else {
+            rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
+        }
+        rSpec.setPool(morResourcePool);
+
+        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
+        cloneSpec.setPowerOn(false);
+        cloneSpec.setTemplate(false);
+        cloneSpec.setLocation(rSpec);
+        cloneSpec.setSnapshot(morBaseSnapshot);
+
+        ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        return false;
+    }
+
+    public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception {
+        return (VirtualMachineRuntimeInfo)_context.getVimClient().getDynamicProperty(_mor, "runtime");
+    }
+
+    public VirtualMachineConfigInfo getConfigInfo() throws Exception {
+        return (VirtualMachineConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "config");
+    }
+
+    public boolean isToolsInstallerMounted() throws Exception {
+        return _context.getVimClient().getDynamicProperty(_mor, "runtime.toolsInstallerMounted");
+    }
+    public GuestInfo getGuestInfo() throws Exception {
+        return (GuestInfo)_context.getVimClient().getDynamicProperty(_mor, "guest");
+    }
+
+    public VirtualMachineConfigSummary getConfigSummary() throws Exception {
+        return (VirtualMachineConfigSummary)_context.getVimClient().getDynamicProperty(_mor, "summary.config");
+    }
+
+    public VirtualMachineFileInfo getFileInfo() throws Exception {
+        return (VirtualMachineFileInfo)_context.getVimClient().getDynamicProperty(_mor, "config.files");
+    }
+
+    public VirtualMachineFileLayoutEx getFileLayout() throws Exception {
+        VirtualMachineFileLayoutEx fileLayout = null;
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("VirtualMachine");
+        pSpec.getPathSet().add("layoutEx");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.FALSE);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        if (ocs != null) {
+            for (ObjectContent oc : ocs) {
+                List<DynamicProperty> props = oc.getPropSet();
+                if (props != null) {
+                    for (DynamicProperty prop : props) {
+                        if (prop.getName().equals("layoutEx")) {
+                            fileLayout = (VirtualMachineFileLayoutEx)prop.getVal();
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        return fileLayout;
+    }
+
+    @Override
+    public ManagedObjectReference getParentMor() throws Exception {
+        return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
+    }
+
+    public String[] getNetworks() throws Exception {
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("Network");
+        pSpec.getPathSet().add("name");
+
+        TraversalSpec vm2NetworkTraversal = new TraversalSpec();
+        vm2NetworkTraversal.setType("VirtualMachine");
+        vm2NetworkTraversal.setPath("network");
+        vm2NetworkTraversal.setName("vm2NetworkTraversal");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.TRUE);
+        oSpec.getSelectSet().add(vm2NetworkTraversal);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        List<String> networks = new ArrayList<String>();
+        if (ocs != null && ocs.size() > 0) {
+            for (ObjectContent oc : ocs) {
+                networks.add(oc.getPropSet().get(0).getVal().toString());
+            }
+        }
+        return networks.toArray(new String[0]);
+    }
+
+    public List<NetworkDetails> getNetworksWithDetails() throws Exception {
+        List<NetworkDetails> networks = new ArrayList<NetworkDetails>();
+
+        int gcTagKey = getCustomFieldKey("Network", CustomFieldConstants.CLOUD_GC);
+
+        if (gcTagKey == 0) {
+            gcTagKey = getCustomFieldKey("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
+            s_logger.debug("The custom key for dvPortGroup is : " + gcTagKey);
+        }
+
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("Network");
+        pSpec.getPathSet().add("name");
+        pSpec.getPathSet().add("vm");
+        pSpec.getPathSet().add(String.format("value[%d]", gcTagKey));
+
+        TraversalSpec vm2NetworkTraversal = new TraversalSpec();
+        vm2NetworkTraversal.setType("VirtualMachine");
+        vm2NetworkTraversal.setPath("network");
+        vm2NetworkTraversal.setName("vm2NetworkTraversal");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.TRUE);
+        oSpec.getSelectSet().add(vm2NetworkTraversal);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        if (ocs != null && ocs.size() > 0) {
+            for (ObjectContent oc : ocs) {
+                ArrayOfManagedObjectReference morVms = null;
+                String gcTagValue = null;
+                String name = null;
+
+                for (DynamicProperty prop : oc.getPropSet()) {
+                    if (prop.getName().equals("name"))
+                        name = prop.getVal().toString();
+                    else if (prop.getName().equals("vm"))
+                        morVms = (ArrayOfManagedObjectReference)prop.getVal();
+                    else if (prop.getName().startsWith("value[")) {
+                        CustomFieldStringValue val = (CustomFieldStringValue)prop.getVal();
+                        if (val != null)
+                            gcTagValue = val.getValue();
+                    }
+                }
+
+                NetworkDetails details =
+                        new NetworkDetails(name, oc.getObj(), (morVms != null ? morVms.getManagedObjectReference().toArray(
+                                new ManagedObjectReference[morVms.getManagedObjectReference().size()]) : null), gcTagValue);
+
+                networks.add(details);
+            }
+            s_logger.debug("Retrieved " + networks.size() + " networks with key : " + gcTagKey);
+        }
+
+        return networks;
+    }
+
+    public List<DatastoreMO> getAllDatastores() throws Exception {
+        PropertySpec pSpec = new PropertySpec();
+        pSpec.setType("Datastore");
+        pSpec.getPathSet().add("name");
+
+        TraversalSpec vmDatastoreTraversal = new TraversalSpec();
+        vmDatastoreTraversal.setType("VirtualMachine");
+        vmDatastoreTraversal.setPath("datastore");
+        vmDatastoreTraversal.setName("vmDatastoreTraversal");
+
+        ObjectSpec oSpec = new ObjectSpec();
+        oSpec.setObj(_mor);
+        oSpec.setSkip(Boolean.TRUE);
+        oSpec.getSelectSet().add(vmDatastoreTraversal);
+
+        PropertyFilterSpec pfSpec = new PropertyFilterSpec();
+        pfSpec.getPropSet().add(pSpec);
+        pfSpec.getObjectSet().add(oSpec);
+        List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
+        pfSpecArr.add(pfSpec);
+
+        List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
+
+        List<DatastoreMO> datastores = new ArrayList<DatastoreMO>();
+        if (CollectionUtils.isNotEmpty(ocs)) {
+            for (ObjectContent oc : ocs) {
+                datastores.add(new DatastoreMO(_context, oc.getObj()));
+            }
+        }
+        return datastores;
+    }
+
+    /**
+     * Retrieve path info to access VM files via vSphere web interface
+     * @return [0] vm-name, [1] data-center-name, [2] datastore-name
+     * @throws Exception
+     */
+    public String[] getHttpAccessPathInfo() throws Exception {
+        String[] pathInfo = new String[3];
+
+        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+
+        VirtualMachineFileInfo fileInfo = getFileInfo();
+        String vmxFilePath = fileInfo.getVmPathName();
+        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
+        assert (vmxPathTokens.length == 4);
+        pathInfo[1] = vmxPathTokens[1].trim();                            // vSphere vm name
+        pathInfo[2] = dcInfo.second();                                    // vSphere datacenter name
+        pathInfo[3] = vmxPathTokens[0].trim();                            // vSphere datastore name
+        return pathInfo;
+    }
+
+    public String getVmxHttpAccessUrl() throws Exception {
+        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+
+        VirtualMachineFileInfo fileInfo = getFileInfo();
+        String vmxFilePath = fileInfo.getVmPathName();
+        String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/");
+
+        StringBuffer sb = new StringBuffer("https://" + _context.getServerAddress() + "/folder/");
+        sb.append(URLEncoder.encode(vmxPathTokens[2].trim(), "UTF-8"));
+        sb.append("/");
+        sb.append(URLEncoder.encode(vmxPathTokens[3].trim(), "UTF-8"));
+        sb.append("?dcPath=");
+        sb.append(URLEncoder.encode(dcInfo.second(), "UTF-8"));
+        sb.append("&dsName=");
+        sb.append(URLEncoder.encode(vmxPathTokens[1].trim(), "UTF-8"));
+
+        return sb.toString();
+    }
+
+    public boolean setVncConfigInfo(boolean enableVnc, String vncPassword, int vncPort, String keyboard) throws Exception {
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        OptionValue[] vncOptions = VmwareHelper.composeVncOptions(null, enableVnc, vncPassword, vncPort, keyboard);
+        vmConfigSpec.getExtraConfig().addAll(Arrays.asList(vncOptions));
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public boolean configureVm(VirtualMachineConfigSpec vmConfigSpec) throws Exception {
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public boolean configureVm(Ternary<VirtualDevice, VirtualDeviceConfigSpecOperation, VirtualDeviceConfigSpecFileOperation>[] devices) throws Exception {
+
+        assert (devices != null);
+
+        VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[devices.length];
+        int i = 0;
+        for (Ternary<VirtualDevice, VirtualDeviceConfigSpecOperation, VirtualDeviceConfigSpecFileOperation> deviceTernary : devices) {
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+            deviceConfigSpec.setDevice(deviceTernary.first());
+            deviceConfigSpec.setOperation(deviceTernary.second());
+            deviceConfigSpec.setFileOperation(deviceTernary.third());
+            deviceConfigSpecArray[i++] = deviceConfigSpec;
+        }
+        configSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
+
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, configSpec);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+
+    public Pair<String, Integer> getVncPort(String hostNetworkName) throws Exception {
+        HostMO hostMo = getRunningHost();
+        VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(hostNetworkName);
+
+        VirtualMachineConfigInfo configInfo = getConfigInfo();
+        List<OptionValue> values = configInfo.getExtraConfig();
+
+        if (values != null) {
+            for (OptionValue option : values) {
+                if (option.getKey().equals("RemoteDisplay.vnc.port")) {
+                    String value = (String)option.getValue();
+                    if (value != null) {
+                        return new Pair<String, Integer>(summary.getHostIp(), Integer.parseInt(value));
+                    }
+                }
+            }
+        }
+        return new Pair<String, Integer>(summary.getHostIp(), 0);
+    }
+
+    // vmdkDatastorePath: [datastore name] vmdkFilePath
+    public void createDisk(String vmdkDatastorePath, int sizeInMb, ManagedObjectReference morDs, int controllerKey) throws Exception {
+        createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey);
+    }
+
+    // vmdkDatastorePath: [datastore name] vmdkFilePath
+    public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, int sizeInMb,
+            ManagedObjectReference morDs, int controllerKey) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - createDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", sizeInMb: " + sizeInMb +
+                    ", diskType: " + diskType + ", diskMode: " + diskMode + ", rdmDeviceName: " + rdmDeviceName + ", datastore: " + morDs.getValue() + ", controllerKey: " +
+                    controllerKey);
+
+        assert (vmdkDatastorePath != null);
+        assert (morDs != null);
+
+        int ideControllerKey = getIDEDeviceControllerKey();
+        if (controllerKey < 0) {
+            controllerKey = ideControllerKey;
+        }
+
+        VirtualDisk newDisk = new VirtualDisk();
+        if (diskType == VirtualDiskType.THIN || diskType == VirtualDiskType.PREALLOCATED || diskType == VirtualDiskType.EAGER_ZEROED_THICK) {
+
+            VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
+            backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
+            if (diskType == VirtualDiskType.THIN) {
+                backingInfo.setThinProvisioned(true);
+            } else {
+                backingInfo.setThinProvisioned(false);
+            }
+
+            if (diskType == VirtualDiskType.EAGER_ZEROED_THICK) {
+                backingInfo.setEagerlyScrub(true);
+            } else {
+                backingInfo.setEagerlyScrub(false);
+            }
+
+            backingInfo.setDatastore(morDs);
+            backingInfo.setFileName(vmdkDatastorePath);
+            newDisk.setBacking(backingInfo);
+        } else if (diskType == VirtualDiskType.RDM || diskType == VirtualDiskType.RDMP) {
+            VirtualDiskRawDiskMappingVer1BackingInfo backingInfo = new VirtualDiskRawDiskMappingVer1BackingInfo();
+            if (diskType == VirtualDiskType.RDM) {
+                backingInfo.setCompatibilityMode("virtualMode");
+            } else {
+                backingInfo.setCompatibilityMode("physicalMode");
+            }
+            backingInfo.setDeviceName(rdmDeviceName);
+            if (diskType == VirtualDiskType.RDM) {
+                backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
+            }
+
+            backingInfo.setDatastore(morDs);
+            backingInfo.setFileName(vmdkDatastorePath);
+            newDisk.setBacking(backingInfo);
+        }
+
+        int deviceNumber = getNextDeviceNumber(controllerKey);
+
+        newDisk.setControllerKey(controllerKey);
+        newDisk.setKey(-deviceNumber);
+        newDisk.setUnitNumber(deviceNumber);
+        newDisk.setCapacityInKB(sizeInMb * 1024);
+
+        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+        deviceConfigSpec.setDevice(newDisk);
+        deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.CREATE);
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+
+        if (!result) {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - createDisk() done(failed)");
+            throw new Exception("Unable to create disk " + vmdkDatastorePath + " due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        _context.waitForTaskProgressDone(morTask);
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - createDisk() done(successfully)");
+    }
+
+    public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception {
+        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
+        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
+        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
+        if (!isVmfsSparseFile) {
+            String currentAdapterType = vmdkFileDescriptor.getAdapterType();
+            if (!currentAdapterType.equalsIgnoreCase(newAdapterType)) {
+                s_logger.info("Updating adapter type to " + newAdapterType + " for VMDK file " + vmdkFileName);
+                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType);
+                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
+                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+                s_logger.info("Updated VMDK file " + vmdkFileName);
+            }
+        }
+    }
+
+    public void updateAdapterTypeIfRequired(String vmdkFileName) throws Exception {
+        // Validate existing adapter type of VMDK file. Update it with a supported adapter type if validation fails.
+        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
+        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
+
+        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
+        if (!isVmfsSparseFile) {
+            String currentAdapterTypeStr = vmdkFileDescriptor.getAdapterType();
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Detected adapter type  " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
+            }
+            VmdkAdapterType currentAdapterType = VmdkAdapterType.getType(currentAdapterTypeStr);
+            if (currentAdapterType == VmdkAdapterType.none) {
+                // Value of currentAdapterType can be VmdkAdapterType.none only if adapter type of vmdk is set to either
+                // lsisas1068 (SAS controller) or pvscsi (Vmware Paravirtual) only. Valid adapter type for those controllers is lsilogic.
+                // Hence use adapter type lsilogic. Other adapter types ide, lsilogic, buslogic are valid and does not need to be modified.
+                VmdkAdapterType newAdapterType = VmdkAdapterType.lsilogic;
+                s_logger.debug("Updating adapter type to " + newAdapterType + " from " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
+                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString());
+                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName);
+
+                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+                s_logger.debug("Updated VMDK file " + vmdkFileName);
+            }
+        }
+    }
+
+    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception {
+
+        if(s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
+                            + new Gson().toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue());
+        int controllerKey = 0;
+        int unitNumber = 0;
+
+        if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
+            // IDE virtual disk cannot be added if VM is running
+            if (getPowerState() == VirtualMachinePowerState.POWERED_ON) {
+                throw new Exception("Adding a virtual disk over IDE controller is not supported while VM is running in VMware hypervisor. Please re-try when VM is not running.");
+            }
+            // Get next available unit number and controller key
+            int ideDeviceCount = getNumberOfIDEDevices();
+            if (ideDeviceCount >= VmwareHelper.MAX_IDE_CONTROLLER_COUNT * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER) {
+                throw new Exception("Maximum limit of  devices supported on IDE controllers [" + VmwareHelper.MAX_IDE_CONTROLLER_COUNT
+                        * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER + "] is reached.");
+            }
+            controllerKey = getIDEControllerKey(ideDeviceCount);
+            unitNumber = getFreeUnitNumberOnIDEController(controllerKey);
+        } else {
+            controllerKey = getScsiDiskControllerKey(diskController);
+            unitNumber = -1;
+        }
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1);
+            controllerKey = newDisk.getControllerKey();
+            unitNumber = newDisk.getUnitNumber();
+            VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking();
+            String vmdkFileName = backingInfo.getFileName();
+            DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
+            VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
+            if (vmdkAdapterType == VmdkAdapterType.none) {
+                String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
+                    vmdkFileName + "] with controller : " + diskControllerType;
+                s_logger.debug(message);
+                throw new Exception(message);
+            }
+            updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString());
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if(s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
+    private int getControllerBusNumber(int controllerKey) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualController && device.getKey() == controllerKey) {
+                    return ((VirtualController)device).getBusNumber();
+                }
+            }
+        }
+        throw new Exception("SCSI Controller with key " + controllerKey + " is Not Found");
+
+    }
+
+    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) +
+                    ", datastore: " + morDs.getValue());
+
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1);
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
+    public void attachDisk(Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain, int controllerKey) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain));
+
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1);
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
+    // vmdkDatastorePath: [datastore name] vmdkFilePath
+    public List<Pair<String, ManagedObjectReference>> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - detachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", deleteBacking: " +
+                    deleteBackingFile);
+
+        // Note: if VM has been taken snapshot, original backing file will be renamed, therefore, when we try to find the matching
+        // VirtualDisk, we only perform prefix matching
+        Pair<VirtualDisk, String> deviceInfo = getDiskDevice(vmdkDatastorePath);
+        if (deviceInfo == null) {
+            s_logger.warn("vCenter API trace - detachDisk() done (failed)");
+            throw new Exception("No such disk device: " + vmdkDatastorePath);
+        }
+
+        // IDE virtual disk cannot be detached if VM is running
+        if (deviceInfo.second() != null && deviceInfo.second().contains("ide")) {
+            if (getPowerState() == VirtualMachinePowerState.POWERED_ON) {
+                throw new Exception("Removing a virtual disk over IDE controller is not supported while VM is running in VMware hypervisor. " +
+                        "Please re-try when VM is not running.");
+            }
+        }
+
+        List<Pair<String, ManagedObjectReference>> chain = getDiskDatastorePathChain(deviceInfo.first(), true);
+
+        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+        deviceConfigSpec.setDevice(deviceInfo.first());
+        if (deleteBackingFile) {
+            deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.DESTROY);
+        }
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+
+        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+
+        if (!result) {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - detachDisk() done (failed)");
+
+            throw new Exception("Failed to detach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        _context.waitForTaskProgressDone(morTask);
+
+        // VMware does not update snapshot references to the detached disk, we have to work around it
+        SnapshotDescriptor snapshotDescriptor = null;
+        try {
+            snapshotDescriptor = getSnapshotDescriptor();
+        } catch (Exception e) {
+            s_logger.info("Unable to retrieve snapshot descriptor, will skip updating snapshot reference");
+        }
+
+        if (snapshotDescriptor != null) {
+            for (Pair<String, ManagedObjectReference> pair : chain) {
+                DatastoreFile dsFile = new DatastoreFile(pair.first());
+                snapshotDescriptor.removeDiskReferenceFromSnapshot(dsFile.getFileName());
+            }
+
+            Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
+            String dsPath = getSnapshotDescriptorDatastorePath();
+            assert (dsPath != null);
+            String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), dsPath);
+            getContext().uploadResourceContent(url, snapshotDescriptor.getVmsdContent());
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - detachDisk() done (successfully)");
+        return chain;
+    }
+
+    public void detachAllDisks() throws Exception {
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - detachAllDisk(). target MOR: " + _mor.getValue());
+
+        VirtualDisk[] disks = getAllDiskDevice();
+        if (disks.length > 0) {
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[disks.length];
+
+            for (int i = 0; i < disks.length; i++) {
+                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                deviceConfigSpecArray[i].setDevice(disks[i]);
+                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+            }
+            reConfigSpec.getDeviceChange().addAll(Arrays.asList(deviceConfigSpecArray));
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - detachAllDisk() done(failed)");
+                throw new Exception("Failed to detach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - detachAllDisk() done(successfully)");
+    }
+
+    // isoDatastorePath: [datastore name] isoFilePath
+    public void attachIso(String isoDatastorePath, ManagedObjectReference morDs, boolean connect, boolean connectAtBoot) throws Exception {
+        attachIso(isoDatastorePath, morDs, connect, connectAtBoot, null);
+    }
+
+    // isoDatastorePath: [datastore name] isoFilePath
+    public void attachIso(String isoDatastorePath, ManagedObjectReference morDs,
+    boolean connect, boolean connectAtBoot, Integer key) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachIso(). target MOR: " + _mor.getValue() + ", isoDatastorePath: " + isoDatastorePath + ", datastore: " +
+                    morDs.getValue() + ", connect: " + connect + ", connectAtBoot: " + connectAtBoot);
+
+        assert (isoDatastorePath != null);
+        assert (morDs != null);
+
+        boolean newCdRom = false;
+        VirtualCdrom cdRom;
+        if (key == null) {
+            cdRom = (VirtualCdrom) getIsoDevice();
+        } else {
+            cdRom = (VirtualCdrom) getIsoDevice(key);
+        }
+        if (cdRom == null) {
+            newCdRom = true;
+            cdRom = new VirtualCdrom();
+            cdRom.setControllerKey(getIDEDeviceControllerKey());
+
+            int deviceNumber = getNextIDEDeviceNumber();
+            cdRom.setUnitNumber(deviceNumber);
+            cdRom.setKey(-deviceNumber);
+        }
+
+        VirtualDeviceConnectInfo cInfo = new VirtualDeviceConnectInfo();
+        cInfo.setConnected(connect);
+        cInfo.setStartConnected(connectAtBoot);
+        cdRom.setConnectable(cInfo);
+
+        VirtualCdromIsoBackingInfo backingInfo = new VirtualCdromIsoBackingInfo();
+        backingInfo.setFileName(isoDatastorePath);
+        backingInfo.setDatastore(morDs);
+        cdRom.setBacking(backingInfo);
+
+        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+        //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+        deviceConfigSpec.setDevice(cdRom);
+        if (newCdRom) {
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+        } else {
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+        }
+
+        //deviceConfigSpecArray[0] = deviceConfigSpec;
+        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+
+        if (!result) {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - attachIso() done(failed)");
+            throw new Exception("Failed to attach ISO due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+
+        _context.waitForTaskProgressDone(morTask);
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachIso() done(successfully)");
+    }
+
+    public int detachIso(String isoDatastorePath) throws Exception {
+        return detachIso(isoDatastorePath, false);
+    }
+
+    public int detachIso(String isoDatastorePath, final boolean force) throws Exception {
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - detachIso(). target MOR: " + _mor.getValue() + ", isoDatastorePath: " + isoDatastorePath);
+
+        VirtualDevice device = getIsoDevice(isoDatastorePath);
+        if (device == null) {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - detachIso() done(failed)");
+            throw new Exception("Unable to find a CDROM device");
+        }
+
+        VirtualCdromRemotePassthroughBackingInfo backingInfo = new VirtualCdromRemotePassthroughBackingInfo();
+        backingInfo.setDeviceName("");
+        device.setBacking(backingInfo);
+
+        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+        //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+        deviceConfigSpec.setDevice(device);
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
+
+        //deviceConfigSpecArray[0] = deviceConfigSpec;
+        reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+        ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+
+        // Monitor VM questions
+        final Boolean[] flags = {false};
+        final VirtualMachineMO vmMo = this;
+        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
+            @Override
+            public void run() {
+                s_logger.info("VM Question monitor started...");
+
+                while (!flags[0]) {
+                    try {
+                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
+                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
+                        if (question != null) {
+                            if (s_logger.isTraceEnabled()) {
+                                s_logger.trace("Question id: " + question.getId());
+                                s_logger.trace("Question text: " + question.getText());
+                            }
+                            if (question.getMessage() != null) {
+                                for (VirtualMachineMessage msg : question.getMessage()) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("msg id: " + msg.getId());
+                                        s_logger.trace("msg text: " + msg.getText());
+                                    }
+                                    if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msg.getId())) {
+                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId() +
+                                                ", for safe operation we will automatically decline it");
+                                        vmMo.answerVM(question.getId(), force ? ANSWER_YES : ANSWER_NO);
+                                        break;
+                                    }
+                                }
+                            } else if (question.getText() != null) {
+                                String text = question.getText();
+                                String msgId;
+                                String msgText;
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("question text : " + text);
+                                }
+                                String[] tokens = text.split(":");
+                                msgId = tokens[0];
+                                msgText = tokens[1];
+                                if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msgId)) {
+                                    s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + question.getId() +
+                                            ". Message id : " + msgId + ". Message text : " + msgText + ", for safe operation we will automatically decline it.");
+                                    vmMo.answerVM(question.getId(), force ? ANSWER_YES : ANSWER_NO);
+                                }
+                            }
+
+                            ChoiceOption choice = question.getChoice();
+                            if (choice != null) {
+                                for (ElementDescription info : choice.getChoiceInfo()) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("Choice option key: " + info.getKey());
+                                        s_logger.trace("Choice option label: " + info.getLabel());
+                                    }
+                                }
+                            }
+                        }
+                    } catch (Throwable e) {
+                        s_logger.error("Unexpected exception: ", e);
+                    }
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        s_logger.debug("[ignored] interupted while handling vm question about iso detach.");
+                    }
+                }
+                s_logger.info("VM Question monitor stopped");
+            }
+        });
+        try {
+            boolean result = _context.getVimClient().waitForTask(morTask);
+            if (!result) {
+                if (s_logger.isDebugEnabled())
+                    s_logger.trace("vCenter API trace - detachIso() done(failed)");
+                throw new Exception("Failed to detachIso due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+            _context.waitForTaskProgressDone(morTask);
+            s_logger.trace("vCenter API trace - detachIso() done(successfully)");
+        } finally {
+            flags[0] = true;
+            future.cancel(true);
+        }
+        return device.getKey();
+    }
+
+    public Pair<VmdkFileDescriptor, byte[]> getVmdkFileInfo(String vmdkDatastorePath) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - getVmdkFileInfo(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath);
+
+        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
+
+        String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkDatastorePath);
+        byte[] content = getContext().getResourceContent(url);
+        VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
+        descriptor.parse(content);
+
+        Pair<VmdkFileDescriptor, byte[]> result = new Pair<VmdkFileDescriptor, byte[]>(descriptor, content);
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("vCenter API trace - getVmdkFileInfo() done");
+            s_logger.trace("VMDK file descriptor: " + new Gson().toJson(result.first()));
+        }
+        return result;
+    }
+
+    public void exportVm(String exportDir, String exportName, boolean packToOva, boolean leaveOvaFileOnly) throws Exception {
+        ManagedObjectReference morOvf = _context.getServiceContent().getOvfManager();
+
+        VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo();
+        HostMO hostMo = new HostMO(_context, runtimeInfo.getHost());
+        String hostName = hostMo.getHostName();
+        String vmName = getVmName();
+
+        DatacenterMO dcMo = new DatacenterMO(_context, hostMo.getHyperHostDatacenter());
+
+        if (runtimeInfo.getPowerState() != VirtualMachinePowerState.POWERED_OFF) {
+            String msg = "Unable to export VM because it is not at powerdOff state. vmName: " + vmName + ", host: " + hostName;
+            s_logger.error(msg);
+            throw new Exception(msg);
+        }
+
+        ManagedObjectReference morLease = _context.getService().exportVm(getMor());
+        if (morLease == null) {
+            s_logger.error("exportVm() failed");
+            throw new Exception("exportVm() failed");
+        }
+
+        HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(_context, morLease);
+        HttpNfcLeaseState state = leaseMo.waitState(new HttpNfcLeaseState[] {HttpNfcLeaseState.READY, HttpNfcLeaseState.ERROR});
+
+        try {
+            if (state == HttpNfcLeaseState.READY) {
+                final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter();
+
+                boolean success = false;
+                List<String> fileNames = new ArrayList<String>();
+                try {
+                    HttpNfcLeaseInfo leaseInfo = leaseMo.getLeaseInfo();
+                    final long totalBytes = leaseInfo.getTotalDiskCapacityInKB() * 1024;
+                    long totalBytesDownloaded = 0;
+
+                    List<HttpNfcLeaseDeviceUrl> deviceUrls = leaseInfo.getDeviceUrl();
+                    s_logger.info("volss: copy vmdk and ovf file starts " + System.currentTimeMillis());
+                    if (deviceUrls != null) {
+                        OvfFile[] ovfFiles = new OvfFile[deviceUrls.size()];
+                        for (int i = 0; i < deviceUrls.size(); i++) {
+                            String deviceId = deviceUrls.get(i).getKey();
+                            String deviceUrlStr = deviceUrls.get(i).getUrl();
+                            String orgDiskFileName = deviceUrlStr.substring(deviceUrlStr.lastIndexOf("/") + 1);
+                            String diskFileName = String.format("%s-disk%d%s", exportName, i, VmwareHelper.getFileExtension(orgDiskFileName, ".vmdk"));
+                            String diskUrlStr = deviceUrlStr.replace("*", hostName);
+                            diskUrlStr = HypervisorHostHelper.resolveHostNameInUrl(dcMo, diskUrlStr);
+                            String diskLocalPath = exportDir + File.separator + diskFileName;
+                            fileNames.add(diskLocalPath);
+
+                            if (s_logger.isInfoEnabled()) {
+                                s_logger.info("Download VMDK file for export. url: " + deviceUrlStr);
+                            }
+                            long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate<Long>() {
+                                @Override
+                                public void action(Long param) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("Download progress " + param + "/" + totalBytes);
+                                    }
+                                    progressReporter.reportProgress((int)(param * 100 / totalBytes));
+                                }
+                            });
+                            totalBytesDownloaded += lengthOfDiskFile;
+
+                            OvfFile ovfFile = new OvfFile();
+                            ovfFile.setPath(diskFileName);
+                            ovfFile.setDeviceId(deviceId);
+                            ovfFile.setSize(lengthOfDiskFile);
+                            ovfFiles[i] = ovfFile;
+                        }
+
+                        // write OVF descriptor file
+                        OvfCreateDescriptorParams ovfDescParams = new OvfCreateDescriptorParams();
+                        ovfDescParams.getOvfFiles().addAll(Arrays.asList(ovfFiles));
+                        OvfCreateDescriptorResult ovfCreateDescriptorResult = _context.getService().createDescriptor(morOvf, getMor(), ovfDescParams);
+                        String ovfPath = exportDir + File.separator + exportName + ".ovf";
+                        fileNames.add(ovfPath);
+
+                        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath),"UTF-8");
+                        out.write(ovfCreateDescriptorResult.getOvfDescriptor());
+                        out.close();
+
+                        // tar files into OVA
+                        if (packToOva) {
+                            // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
+                            s_logger.info("Sync file system before we package OVA...");
+
+                            Script commandSync = new Script(true, "sync", 0, s_logger);
+                            commandSync.execute();
+
+                            Script command = new Script(false, "tar", 0, s_logger);
+                            command.setWorkDir(exportDir);
+                            command.add("-cf", exportName + ".ova");
+                            command.add(exportName + ".ovf");        // OVF file should be the first file in OVA archive
+                            for (String name : fileNames) {
+                                command.add((new File(name).getName()));
+                            }
+
+                            s_logger.info("Package OVA with commmand: " + command.toString());
+                            command.execute();
+
+                            // to be safe, physically test existence of the target OVA file
+                            if ((new File(exportDir + File.separator + exportName + ".ova")).exists()) {
+                                success = true;
+                            } else {
+                                s_logger.error(exportDir + File.separator + exportName + ".ova is not created as expected");
+                            }
+                        } else {
+                            success = true;
+                        }
+                    }
+                    s_logger.info("volss: copy vmdk and ovf file finishes " + System.currentTimeMillis());
+                } catch (Throwable e) {
+                    s_logger.error("Unexpected exception ", e);
+                } finally {
+                    progressReporter.close();
+
+                    if (leaveOvaFileOnly) {
+                        for (String name : fileNames) {
+                            new File(name).delete();
+                        }
+                    }
+
+                    if (!success)
+                        throw new Exception("Unable to finish the whole process to package as a OVA file");
+                }
+            }
+        } finally {
+            leaseMo.updateLeaseProgress(100);
+            leaseMo.completeLease();
+        }
+    }
+
+    // snapshot directory in format of: /vmfs/volumes/<datastore name>/<path>
+    @Deprecated
+    public void setSnapshotDirectory(String snapshotDir) throws Exception {
+        VirtualMachineFileInfo fileInfo = getFileInfo();
+        Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+        String vmxUrl = _context.composeDatastoreBrowseUrl(dcInfo.second(), fileInfo.getVmPathName());
+        byte[] vmxContent = _context.getResourceContent(vmxUrl);
+
+        BufferedReader in = null;
+        BufferedWriter out = null;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        boolean replaced = false;
+        try {
+            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent),"UTF-8"));
+            out = new BufferedWriter(new OutputStreamWriter(bos,"UTF-8"));
+            String line;
+            while ((line = in.readLine()) != null) {
+                if (line.startsWith("workingDir")) {
+                    replaced = true;
+                    out.write(String.format("workingDir=\"%s\"", snapshotDir));
+                    out.newLine();
+                } else {
+                    out.write(line);
+                    out.newLine();
+                }
+            }
+
+            if (!replaced) {
+                out.newLine();
+                out.write(String.format("workingDir=\"%s\"", snapshotDir));
+                out.newLine();
+            }
+        } finally {
+            if (in != null) {
+                in.close();
+            }
+            if (out != null) {
+                out.close();
+            }
+        }
+        _context.uploadResourceContent(vmxUrl, bos.toByteArray());
+
+        // It seems that I don't need to do re-registration. VMware has bug in writing the correct snapshot's VMDK path to
+        // its disk backing info anyway.
+        // redoRegistration();
+    }
+
+    // destName does not contain extension name
+    public void backupCurrentSnapshot(String deviceName, ManagedObjectReference morDestDs, String destDsDirectory, String destName, boolean includeBase) throws Exception {
+
+        SnapshotDescriptor descriptor = getSnapshotDescriptor();
+        SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
+        if (snapshotInfo.length == 0) {
+            String msg = "No snapshot found in this VM";
+            throw new Exception(msg);
+        }
+
+        HostMO hostMo = getRunningHost();
+        DatacenterMO dcMo = getOwnerDatacenter().first();
+        List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
+        VirtualMachineFileInfo vmFileInfo = getFileInfo();
+
+        List<Ternary<String, String, String>> backupInfo = new ArrayList<Ternary<String, String, String>>();
+
+        for (int i = 0; i < snapshotInfo.length; i++) {
+            if (!includeBase && i == snapshotInfo.length - 1) {
+                break;
+            }
+
+            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
+            if (disks != null) {
+                String destBaseFileName;
+                String destFileName;
+                String destParentFileName;
+                for (SnapshotDescriptor.DiskInfo disk : disks) {
+                    if (deviceName == null || deviceName.equals(disk.getDeviceName())) {
+                        String srcVmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName());
+                        Pair<DatastoreMO, String> srcDsInfo = getOwnerDatastore(srcVmdkFullDsPath);
+
+                        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(srcVmdkFullDsPath);
+                        String srcVmdkBaseFilePath = DatastoreFile.getCompanionDatastorePath(srcVmdkFullDsPath, vmdkInfo.first().getBaseFileName());
+
+                        destFileName = destName + (snapshotInfo.length - i - 1) + ".vmdk";
+                        if (vmdkInfo.first().getParentFileName() != null) {
+                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-delta.vmdk";
+                            destParentFileName = destName + (snapshotInfo.length - i - 2) + ".vmdk";
+                        } else {
+                            destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-flat.vmdk";
+                            destParentFileName = null;
+                        }
+
+                        s_logger.info("Copy VMDK base file " + srcVmdkBaseFilePath + " to " + destDsDirectory + "/" + destBaseFileName);
+                        srcDsInfo.first().copyDatastoreFile(srcVmdkBaseFilePath, dcMo.getMor(), morDestDs, destDsDirectory + "/" + destBaseFileName, dcMo.getMor(), true);
+
+                        byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkContentBaseInfo(vmdkInfo.second(), destBaseFileName, destParentFileName);
+                        String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destFileName);
+
+                        s_logger.info("Upload VMDK content file to " + destDsDirectory + "/" + destFileName);
+                        getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+
+                        backupInfo.add(new Ternary<String, String, String>(destFileName, destBaseFileName, destParentFileName));
+                    }
+                }
+            }
+        }
+
+        byte[] vdiskInfo = VmwareHelper.composeDiskInfo(backupInfo, snapshotInfo.length, includeBase);
+        String vdiskUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destName + ".vdisk");
+        getContext().uploadResourceContent(vdiskUploadUrl, vdiskInfo);
+    }
+
+    public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) throws Exception {
+        HostMO hostMo = getRunningHost();
+        List<Pair<ManagedObjectReference, String>> mounts = hostMo.getDatastoreMountsOnHost();
+        VirtualMachineFileInfo vmFileInfo = getFileInfo();
+
+        SnapshotDescriptor descriptor = getSnapshotDescriptor();
+        SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain();
+
+        List<String> diskDsFullPaths = new ArrayList<String>();
+        for (int i = 0; i < snapshotInfo.length; i++) {
+            SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks();
+            if (disks != null) {
+                for (SnapshotDescriptor.DiskInfo disk : disks) {
+                    String deviceNameInDisk = disk.getDeviceName();
+                    if (diskDevice == null || diskDevice.equalsIgnoreCase(deviceNameInDisk)) {
+                        String vmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName());
+                        diskDsFullPaths.add(vmdkFullDsPath);
+                    }
+                }
+            }
+        }
+        return diskDsFullPaths.toArray(new String[0]);
+    }
+
+    // return the disk chain (VMDK datastore paths) for cloned snapshot
+    public Pair<VirtualMachineMO, String[]> cloneFromCurrentSnapshot(String clonedVmName, int cpuSpeedMHz, int memoryMb, String diskDevice, ManagedObjectReference morDs)
+            throws Exception {
+        assert (morDs != null);
+        String[] disks = getCurrentSnapshotDiskChainDatastorePaths(diskDevice);
+        VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs);
+        return new Pair<VirtualMachineMO, String[]>(clonedVm, disks);
+    }
+
+    public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs) throws Exception {
+        assert (disks != null);
+        assert (disks.length >= 1);
+
+        HostMO hostMo = getRunningHost();
+
+        VirtualMachineMO clonedVmMo = HypervisorHostHelper.createWorkerVM(hostMo, new DatastoreMO(hostMo.getContext(), morDs), clonedVmName);
+        if (clonedVmMo == null)
+            throw new Exception("Unable to find just-created blank VM");
+
+        boolean bSuccess = false;
+        try {
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, null, -1, disks, morDs, -1, 1);
+
+            deviceConfigSpec.setDevice(device);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+            clonedVmMo.configureVm(vmConfigSpec);
+            bSuccess = true;
+            return clonedVmMo;
+        } finally {
+            if (!bSuccess) {
+                clonedVmMo.detachAllDisks();
+                clonedVmMo.destroy();
+            }
+        }
+    }
+
+    public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception {
+        GuestOsDescriptor guestOsDescriptor = null;
+        String guestId = guestOsId;
+        if (guestId == null) {
+            guestId = getGuestId();
+        }
+        ManagedObjectReference vmEnvironmentBrowser = _context.getVimClient().getMoRefProp(_mor, "environmentBrowser");
+        VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(vmEnvironmentBrowser, null, null);
+        List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor();
+        for (GuestOsDescriptor descriptor : guestDescriptors) {
+            if (guestId != null && guestId.equalsIgnoreCase(descriptor.getId())) {
+                guestOsDescriptor = descriptor;
+                break;
+            }
+        }
+        return guestOsDescriptor;
+    }
+
+    public void plugDevice(VirtualDevice device) throws Exception {
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+        deviceConfigSpec.setDevice(device);
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+        if (!configureVm(vmConfigSpec)) {
+            throw new Exception("Failed to add devices");
+        }
+    }
+
+    public void tearDownDevice(VirtualDevice device) throws Exception {
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+        deviceConfigSpec.setDevice(device);
+        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+
+        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+        if (!configureVm(vmConfigSpec)) {
+            throw new Exception("Failed to detach devices");
+        }
+    }
+
+    public void tearDownDevices(Class<?>[] deviceClasses) throws Exception {
+        VirtualDevice[] devices = getMatchedDevices(deviceClasses);
+
+        if (devices.length > 0) {
+            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[devices.length];
+
+            for (int i = 0; i < devices.length; i++) {
+                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
+                deviceConfigSpecArray[i].setDevice(devices[i]);
+                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+                vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[i]);
+            }
+
+            if (!configureVm(vmConfigSpec)) {
+                throw new Exception("Failed to detach devices");
+            }
+        }
+    }
+
+    public void copyAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception {
+        VirtualDevice[] disks = getAllDiskDevice();
+        DatacenterMO dcMo = getOwnerDatacenter().first();
+        if (disks != null) {
+            for (VirtualDevice disk : disks) {
+                List<Pair<String, ManagedObjectReference>> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain);
+                for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
+                    DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second());
+
+                    DatastoreFile srcFile = new DatastoreFile(fileItem.first());
+                    DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
+
+                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
+
+                    vmdkDescriptor = getVmdkFileInfo(fileItem.first());
+
+                    s_logger.info("Copy VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
+                    srcDsMo.copyDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+
+                    if (vmdkDescriptor != null) {
+                        String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
+                        String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName);
+                        destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
+
+                        s_logger.info("Copy VM disk file " + baseFilePath + " to " + destFile.getPath());
+                        srcDsMo.copyDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+                    }
+                }
+            }
+        }
+    }
+
+    public List<String> getVmdkFileBaseNames() throws Exception {
+        List<String> vmdkFileBaseNames = new ArrayList<String>();
+        VirtualDevice[] devices = getAllDiskDevice();
+        for(VirtualDevice device : devices) {
+            if(device instanceof VirtualDisk) {
+                vmdkFileBaseNames.add(getVmdkFileBaseName((VirtualDisk)device));
+            }
+        }
+        return vmdkFileBaseNames;
+    }
+
+    public String getVmdkFileBaseName(VirtualDisk disk) throws Exception {
+        String vmdkFileBaseName = null;
+        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
+        if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+            VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
+            vmdkFileBaseName = dsBackingFile.getFileBaseName();
+        }
+        return vmdkFileBaseName;
+    }
+
+    // this method relies on un-offical VMware API
+    @Deprecated
+    public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception {
+        VirtualDevice[] disks = getAllDiskDevice();
+        DatacenterMO dcMo = getOwnerDatacenter().first();
+        if (disks != null) {
+            for (VirtualDevice disk : disks) {
+                List<Pair<String, ManagedObjectReference>> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain);
+                for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
+                    DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second());
+
+                    DatastoreFile srcFile = new DatastoreFile(fileItem.first());
+                    DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName());
+
+                    Pair<VmdkFileDescriptor, byte[]> vmdkDescriptor = null;
+                    vmdkDescriptor = getVmdkFileInfo(fileItem.first());
+
+                    s_logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
+                    srcDsMo.moveDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+
+                    if (vmdkDescriptor != null) {
+                        String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
+                        String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName);
+                        destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
+
+                        s_logger.info("Move VM disk file " + baseFilePath + " to " + destFile.getPath());
+                        srcDsMo.moveDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
+                    }
+                }
+            }
+        }
+    }
+
+    public int getPvScsiDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public int getPvScsiDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception("VMware Paravirtual SCSI Controller Not Found");
+    }
+
+    public void ensurePvScsiDeviceController(int requiredNumScsiControllers, int availableBusNum) throws Exception {
+        VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+        int busNum = availableBusNum;
+        while (busNum < requiredNumScsiControllers) {
+            ParaVirtualSCSIController scsiController = new ParaVirtualSCSIController();
+
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+            scsiController.setBusNumber(busNum);
+            scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+            busNum++;
+        }
+
+        if (configureVm(vmConfig)) {
+            throw new Exception("Unable to add Scsi controllers to the VM " + getName());
+        } else {
+            s_logger.info("Successfully added " + requiredNumScsiControllers + " SCSI controllers.");
+        }
+    }
+
+    public String getRecommendedDiskController(String guestOsId) throws Exception {
+        String recommendedController;
+        GuestOsDescriptor guestOsDescriptor = getGuestOsDescriptor(guestOsId);
+        recommendedController = VmwareHelper.getRecommendedDiskControllerFromDescriptor(guestOsDescriptor);
+        return recommendedController;
+    }
+
+    public boolean isPvScsiSupported() throws Exception {
+        int virtualHardwareVersion;
+
+        virtualHardwareVersion = getVirtualHardwareVersion();
+
+        // Check if virtual machine is using hardware version 7 or later.
+        if (virtualHardwareVersion < 7) {
+            s_logger.error("The virtual hardware version of the VM is " + virtualHardwareVersion
+                    + ", which doesn't support PV SCSI controller type for virtual harddisks. Please upgrade this VM's virtual hardware version to 7 or later.");
+            return false;
+        }
+        return true;
+    }
+
+    // Would be useful if there exists multiple sub types of SCSI controllers per VM are supported in CloudStack f
+    public int getScsiDiskControllerKey(String diskController) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicController) {
+                    return ((VirtualLsiLogicController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicSASController) {
+                    return ((VirtualLsiLogicSASController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof ParaVirtualSCSIController) {
+                    return ((ParaVirtualSCSIController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualBusLogicController) {
+                    return ((VirtualBusLogicController)device).getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new IllegalStateException("Scsi disk controller of type " + diskController + " not found among configured devices.");
+    }
+
+    public int getScsiDiskControllerKeyNoException(String diskController) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicController) {
+                    return ((VirtualLsiLogicController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicSASController) {
+                    return ((VirtualLsiLogicSASController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof ParaVirtualSCSIController) {
+                    return ((ParaVirtualSCSIController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualBusLogicController) {
+                    return ((VirtualBusLogicController)device).getKey();
+                }
+            }
+        }
+        return -1;
+    }
+
+    public int getNextScsiDiskDeviceNumber() throws Exception {
+        int scsiControllerKey = getScsiDeviceControllerKey();
+        int deviceNumber = getNextDeviceNumber(scsiControllerKey);
+
+        return deviceNumber;
+    }
+
+    public int getScsiDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception("SCSI Controller Not Found");
+    }
+
+    public int getGenericScsiDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public int getScsiDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+            getDynamicProperty(_mor, "config.hardware.device");
+
+        if(devices != null && devices.size() > 0) {
+            for(VirtualDevice device : devices) {
+                if(device instanceof VirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public void ensureLsiLogicDeviceControllers(int count, int availableBusNum) throws Exception {
+        int scsiControllerKey = getLsiLogicDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+                VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+                scsiControllerSpec.setDevice(scsiController);
+                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Lsi Logic controllers to the VM " + getName());
+            } else {
+                s_logger.info("Successfully added " + count + " LsiLogic Parallel SCSI controllers.");
+            }
+        }
+    }
+
+    private int getLsiLogicDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualLsiLogicController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public void ensureScsiDeviceController() throws Exception {
+        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            // Scsi controller
+            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+            scsiController.setBusNumber(0);
+            scsiController.setKey(1);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controller");
+            }
+        }
+    }
+
+    public void ensureScsiDeviceControllers(int count, int availableBusNum) throws Exception {
+        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controllers to the VM " + getName());
+            } else {
+                s_logger.info("Successfully added " + count + " SCSI controllers.");
+            }
+        }
+    }
+
+    // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
+    public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath) throws Exception {
+        final String zeroLengthString = "";
+
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        ArrayList<Pair<VirtualDisk, String>> partialMatchingDiskDevices = new ArrayList<>();
+
+        DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath);
+
+        String srcBaseName = dsSrcFile.getFileBaseName();
+        String trimmedSrcBaseName = VmwareHelper.trimSnapshotDeltaPostfix(srcBaseName);
+        String srcDatastoreName = dsSrcFile.getDatastoreName() != null ? dsSrcFile.getDatastoreName() : zeroLengthString;
+
+        s_logger.info("Look for disk device info for volume : " + vmdkDatastorePath + " with base name: " + srcBaseName);
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
+
+                    VirtualDeviceBackingInfo backingInfo = device.getBacking();
+
+                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+
+                        do {
+                            s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName());
+
+                            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
+
+                            String backingDatastoreName = dsBackingFile.getDatastoreName() != null ? dsBackingFile.getDatastoreName() : zeroLengthString;
+
+                            if (srcDatastoreName.equals(zeroLengthString)) {
+                                backingDatastoreName = zeroLengthString;
+                            }
+
+                            if (srcDatastoreName.equalsIgnoreCase(backingDatastoreName)) {
+                                String backingBaseName = dsBackingFile.getFileBaseName();
+
+                                if (backingBaseName.equalsIgnoreCase(srcBaseName)) {
+                                    String deviceNumbering = getDeviceBusName(devices, device);
+
+                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
+
+                                    return new Pair<>((VirtualDisk)device, deviceNumbering);
+                                }
+
+                                if (backingBaseName.contains(trimmedSrcBaseName)) {
+                                    String deviceNumbering = getDeviceBusName(devices, device);
+
+                                    partialMatchingDiskDevices.add(new Pair<>((VirtualDisk)device, deviceNumbering));
+                                }
+                            }
+
+                            diskBackingInfo = diskBackingInfo.getParent();
+                        } while (diskBackingInfo != null);
+                    }
+                }
+            }
+        }
+
+        // No disk device was found with an exact match for the volume path, hence look for disk device that matches the trimmed name.
+        s_logger.info("No disk device with an exact match found for volume : " + vmdkDatastorePath + ". Look for disk device info against trimmed base name: " + srcBaseName);
+
+        if (partialMatchingDiskDevices != null) {
+            if (partialMatchingDiskDevices.size() == 1) {
+                VirtualDiskFlatVer2BackingInfo matchingDiskBackingInfo = (VirtualDiskFlatVer2BackingInfo)partialMatchingDiskDevices.get(0).first().getBacking();
+
+                s_logger.info("Disk backing : " + matchingDiskBackingInfo.getFileName() + " matches ==> " + partialMatchingDiskDevices.get(0).second());
+
+                return partialMatchingDiskDevices.get(0);
+            } else if (partialMatchingDiskDevices.size() > 1) {
+                s_logger.warn("Disk device info lookup for volume: " + vmdkDatastorePath + " failed as multiple disk devices were found to match" +
+                        " volume's trimmed base name: " + trimmedSrcBaseName);
+
+                return null;
+            }
+        }
+
+        s_logger.warn("Disk device info lookup for volume: " + vmdkDatastorePath + " failed as no matching disk device found");
+
+        return null;
+    }
+
+    // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
+    public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath);
+        String srcBaseName = dsSrcFile.getFileBaseName();
+        String trimmedSrcBaseName = VmwareHelper.trimSnapshotDeltaPostfix(srcBaseName);
+
+        if (matchExactly) {
+            s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with base name: " + srcBaseName);
+        } else {
+            s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with trimmed base name: " + trimmedSrcBaseName);
+        }
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
+
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
+                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+                        do {
+                            s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName());
+
+                            DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
+                            String backingBaseName = dsBackingFile.getFileBaseName();
+                            if (matchExactly) {
+                                if (backingBaseName.equalsIgnoreCase(srcBaseName)) {
+                                    String deviceNumbering = getDeviceBusName(devices, device);
+
+                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
+                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
+                                }
+                            } else {
+                                if (backingBaseName.contains(trimmedSrcBaseName)) {
+                                    String deviceNumbering = getDeviceBusName(devices, device);
+
+                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
+                                    return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
+                                }
+                            }
+
+                            diskBackingInfo = diskBackingInfo.getParent();
+                        } while (diskBackingInfo != null);
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber());
+
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
+                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+
+                        String deviceNumbering = getDeviceBusName(devices, device);
+                        if (deviceNumbering.equals(deviceBusName))
+                            return diskBackingInfo.getFileName();
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public VirtualDisk getDiskDeviceByDeviceBusName(String deviceBusName) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    String deviceNumbering = getDeviceBusName(devices, device);
+                    if (deviceNumbering.equals(deviceBusName))
+                        return (VirtualDisk)device;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception {
+        VirtualMachineDiskInfoBuilder builder = new VirtualMachineDiskInfoBuilder();
+
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
+                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+
+                        while (diskBackingInfo != null) {
+                            String deviceBusName = getDeviceBusName(devices, device);
+                            builder.addDisk(deviceBusName, diskBackingInfo.getFileName());
+                            diskBackingInfo = diskBackingInfo.getParent();
+                        }
+                    }
+                }
+            }
+        }
+
+        return builder;
+    }
+
+    public List<Pair<Integer, ManagedObjectReference>> getAllDiskDatastores() throws Exception {
+        List<Pair<Integer, ManagedObjectReference>> disks = new ArrayList<Pair<Integer, ManagedObjectReference>>();
+
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
+                    if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
+                        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+                        disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getKey()), diskBackingInfo.getDatastore()));
+                    }
+                }
+            }
+        }
+
+        return disks;
+    }
+
+
+    @Deprecated
+    public List<Pair<String, ManagedObjectReference>> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception {
+        VirtualDeviceBackingInfo backingInfo = disk.getBacking();
+        if (!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) {
+            throw new Exception("Unsupported VirtualDeviceBackingInfo");
+        }
+
+        List<Pair<String, ManagedObjectReference>> pathList = new ArrayList<Pair<String, ManagedObjectReference>>();
+        VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+
+        if (!followChain) {
+            pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
+            return pathList;
+        }
+
+        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
+        VirtualMachineFileInfo vmFilesInfo = getFileInfo();
+        DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory());
+        DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName());
+
+        do {
+            if (diskBackingInfo.getParent() != null) {
+                pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
+                diskBackingInfo = diskBackingInfo.getParent();
+            } else {
+                // try getting parent info from VMDK file itself
+                byte[] content = null;
+                try {
+                    String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName());
+                    content = getContext().getResourceContent(url);
+                    if (content == null || content.length == 0) {
+                        break;
+                    }
+
+                    pathList.add(new Pair<String, ManagedObjectReference>(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore()));
+                } catch (Exception e) {
+                    // if snapshot directory has been changed to place other than default. VMware has a bug
+                    // that its corresponding disk backing info is not updated correctly. therefore, we will try search
+                    // in snapshot directory one more time
+                    DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName());
+                    String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName());
+
+                    String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath);
+                    content = getContext().getResourceContent(url);
+                    if (content == null || content.length == 0) {
+                        break;
+                    }
+
+                    pathList.add(new Pair<String, ManagedObjectReference>(vmdkFullDsPath, diskBackingInfo.getDatastore()));
+                }
+
+                VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
+                descriptor.parse(content);
+                if (descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) {
+                    // create a fake one
+                    VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo();
+                    parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore());
+
+                    String parentFileName = descriptor.getParentFileName();
+                    if (parentFileName.startsWith("/")) {
+                        int fileNameStartPos = parentFileName.lastIndexOf("/");
+                        parentFileName = parentFileName.substring(fileNameStartPos + 1);
+                        parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName));
+                    } else {
+                        parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName));
+                    }
+                    diskBackingInfo = parentDiskBackingInfo;
+                } else {
+                    break;
+                }
+            }
+        } while (diskBackingInfo != null);
+
+        return pathList;
+    }
+
+    private String getDeviceBusName(List<VirtualDevice> allDevices, VirtualDevice theDevice) throws Exception {
+        for (VirtualDevice device : allDevices) {
+            if (device.getKey() == theDevice.getControllerKey().intValue()) {
+                if (device instanceof VirtualIDEController) {
+                    return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber());
+                } else if (device instanceof VirtualSCSIController) {
+                    return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber());
+                } else {
+                    throw new Exception("Device controller is not supported yet");
+                }
+            }
+        }
+        throw new Exception("Unable to find device controller");
+    }
+
+    public List<VirtualDisk> getVirtualDisks() throws Exception {
+        List<VirtualDisk> virtualDisks = new ArrayList<VirtualDisk>();
+
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        for (VirtualDevice device : devices) {
+            if (device instanceof VirtualDisk) {
+                virtualDisks.add((VirtualDisk)device);
+            }
+        }
+
+        return virtualDisks;
+    }
+
+    public List<String> detachAllDisksExcept(String vmdkBaseName, String deviceBusName) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+        List<String> detachedDiskFiles = new ArrayList<String>();
+
+        for (VirtualDevice device : devices) {
+            if (device instanceof VirtualDisk) {
+                VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+                VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)device.getBacking();
+
+                DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName());
+                String backingBaseName = dsBackingFile.getFileBaseName();
+                String deviceNumbering = getDeviceBusName(devices, device);
+                if (backingBaseName.equalsIgnoreCase(vmdkBaseName) || (deviceBusName != null && deviceBusName.equals(deviceNumbering))) {
+                    continue;
+                } else {
+                    s_logger.info("Detach " + diskBackingInfo.getFileName() + " from " + getName());
+
+                    detachedDiskFiles.add(diskBackingInfo.getFileName());
+
+                    deviceConfigSpec.setDevice(device);
+                    deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
+
+                    reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+                }
+            }
+        }
+
+        if (detachedDiskFiles.size() > 0) {
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+            if (result) {
+                _context.waitForTaskProgressDone(morTask);
+            } else {
+                s_logger.warn("Unable to reconfigure the VM to detach disks");
+                throw new Exception("Unable to reconfigure the VM to detach disks");
+            }
+        }
+
+        return detachedDiskFiles;
+    }
+
+    public List<VirtualDevice> getAllDeviceList() throws Exception {
+        return _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+    }
+
+    public VirtualDisk[] getAllDiskDevice() throws Exception {
+        List<VirtualDisk> deviceList = new ArrayList<VirtualDisk>();
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    deviceList.add((VirtualDisk)device);
+                }
+            }
+        }
+
+        return deviceList.toArray(new VirtualDisk[0]);
+    }
+
+    public VirtualDisk getDiskDeviceByBusName(List<VirtualDevice> allDevices, String busName) throws Exception {
+        for (VirtualDevice device : allDevices) {
+            if (device instanceof VirtualDisk) {
+                VirtualDisk disk = (VirtualDisk)device;
+                String diskBusName = getDeviceBusName(allDevices, disk);
+                if (busName.equalsIgnoreCase(diskBusName))
+                    return disk;
+            }
+        }
+
+        return null;
+    }
+
+    public VirtualDisk[] getAllIndependentDiskDevice() throws Exception {
+        List<VirtualDisk> independentDisks = new ArrayList<VirtualDisk>();
+        VirtualDisk[] allDisks = getAllDiskDevice();
+        if (allDisks.length > 0) {
+            for (VirtualDisk disk : allDisks) {
+                String diskMode = "";
+                if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) {
+                    diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) {
+                    diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) {
+                    diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) {
+                    diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode();
+                } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) {
+                    diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode();
+                }
+
+                if (diskMode.indexOf("independent") != -1) {
+                    independentDisks.add(disk);
+                }
+            }
+        }
+
+        return independentDisks.toArray(new VirtualDisk[0]);
+    }
+
+    public int tryGetIDEDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualIDEController) {
+                    return ((VirtualIDEController)device).getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public int getIDEDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualIDEController) {
+                    return ((VirtualIDEController)device).getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception("IDE Controller Not Found");
+    }
+
+    public int getIDEControllerKey(int ideUnitNumber) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+            getDynamicProperty(_mor, "config.hardware.device");
+
+        int requiredIdeController = ideUnitNumber / VmwareHelper.MAX_IDE_CONTROLLER_COUNT;
+
+        int ideControllerCount = 0;
+        if(devices != null && devices.size() > 0) {
+            for(VirtualDevice device : devices) {
+                if(device instanceof VirtualIDEController) {
+                    if (ideControllerCount == requiredIdeController) {
+                        return ((VirtualIDEController)device).getKey();
+                    }
+                    ideControllerCount++;
+                }
+            }
+        }
+
+        assert(false);
+        throw new Exception("IDE Controller Not Found");
+    }
+
+    public int getNumberOfIDEDevices() throws Exception {
+        int ideDeviceCount = 0;
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualIDEController) {
+                    ideDeviceCount += ((VirtualIDEController)device).getDevice().size();
+                }
+            }
+        }
+        return ideDeviceCount;
+    }
+
+    public int getFreeUnitNumberOnIDEController(int controllerKey) throws Exception {
+        int freeUnitNumber = 0;
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        int deviceCount = 0;
+        int ideDeviceUnitNumber = -1;
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk && (controllerKey == device.getControllerKey())) {
+                    deviceCount++;
+                    ideDeviceUnitNumber = device.getUnitNumber();
+                }
+            }
+        }
+        if (deviceCount == 1) {
+            if (ideDeviceUnitNumber == 0) {
+                freeUnitNumber = 1;
+            } // else freeUnitNumber is already initialized to 0
+        } else if (deviceCount == 2) {
+            throw new Exception("IDE controller with key [" + controllerKey + "] already has 2 device attached. Cannot attach more than the limit of 2.");
+        }
+        return freeUnitNumber;
+    }
+    public int getNextIDEDeviceNumber() throws Exception {
+        int controllerKey = getIDEDeviceControllerKey();
+        return getNextDeviceNumber(controllerKey);
+    }
+
+    public VirtualDevice getIsoDevice() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualCdrom) {
+                    return device;
+                }
+            }
+        }
+        return null;
+    }
+
+    public VirtualDevice getIsoDevice(int key) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualCdrom && device.getKey() == key) {
+                    return device;
+                }
+            }
+        }
+        return null;
+    }
+
+    public VirtualDevice getIsoDevice(String filename) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+        if(devices != null && devices.size() > 0) {
+            for(VirtualDevice device : devices) {
+                if(device instanceof VirtualCdrom && device.getBacking() instanceof VirtualCdromIsoBackingInfo &&
+                        ((VirtualCdromIsoBackingInfo)device.getBacking()).getFileName().equals(filename)) {
+                    return device;
+                }
+            }
+        }
+        return null;
+    }
+
+    public int getNextDeviceNumber(int controllerKey) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        List<Integer> existingUnitNumbers = new ArrayList<Integer>();
+        int deviceNumber = 0;
+        int scsiControllerKey = getGenericScsiDeviceControllerKeyNoException();
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) {
+                    existingUnitNumbers.add(device.getUnitNumber());
+                }
+            }
+        }
+        while (true) {
+            // Next device number should be the lowest device number on the key that is not in use and is not reserved.
+            if (!existingUnitNumbers.contains(Integer.valueOf(deviceNumber))) {
+                if (controllerKey != scsiControllerKey || !VmwareHelper.isReservedScsiDeviceNumber(deviceNumber))
+                    break;
+            }
+            ++deviceNumber;
+        }
+        return deviceNumber;
+    }
+
+    private List<VirtualDevice> getNicDevices(boolean sorted) throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        List<VirtualDevice> nics = new ArrayList<VirtualDevice>();
+        if (devices != null) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualEthernetCard) {
+                    nics.add(device);
+                }
+            }
+        }
+
+        if (sorted) {
+            Collections.sort(nics, new Comparator<VirtualDevice>() {
+                @Override
+                public int compare(VirtualDevice arg0, VirtualDevice arg1) {
+                    int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1;
+                    int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1;
+                    if (unitNumber0 < unitNumber1)
+                        return -1;
+                    else if (unitNumber0 > unitNumber1)
+                        return 1;
+                    return 0;
+                }
+            });
+        }
+
+        return nics;
+    }
+
+    public VirtualDevice[] getNicDevices() throws Exception {
+        return getNicDevices(false).toArray(new VirtualDevice[0]);
+    }
+
+    public VirtualDevice getNicDeviceByIndex(int index) throws Exception {
+        List<VirtualDevice> nics = getNicDevices(true);
+        try {
+            return nics.get(index);
+        } catch (IndexOutOfBoundsException e) {
+            // Not found
+            return null;
+        }
+    }
+
+    public Pair<Integer, VirtualDevice> getNicDeviceIndex(String networkNamePrefix) throws Exception {
+        List<VirtualDevice> nics = getNicDevices(true);
+
+        int index = 0;
+        String attachedNetworkSummary;
+        String dvPortGroupName;
+        for (VirtualDevice nic : nics) {
+            attachedNetworkSummary = ((VirtualEthernetCard)nic).getDeviceInfo().getSummary();
+            if (attachedNetworkSummary.startsWith(networkNamePrefix)) {
+                return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
+            } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary") || attachedNetworkSummary.startsWith("DVSwitch")) {
+                dvPortGroupName = getDvPortGroupName((VirtualEthernetCard)nic);
+                if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) {
+                    s_logger.debug("Found a dvPortGroup already associated with public NIC.");
+                    return new Pair<Integer, VirtualDevice>(new Integer(index), nic);
+                }
+            }
+            index++;
+        }
+        return new Pair<Integer, VirtualDevice>(new Integer(-1), null);
+    }
+
+    public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception {
+        VirtualEthernetCardDistributedVirtualPortBackingInfo dvpBackingInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo)nic.getBacking();
+        DistributedVirtualSwitchPortConnection dvsPort = dvpBackingInfo.getPort();
+        String dvPortGroupKey = dvsPort.getPortgroupKey();
+        ManagedObjectReference dvPortGroupMor = new ManagedObjectReference();
+        dvPortGroupMor.setValue(dvPortGroupKey);
+        dvPortGroupMor.setType("DistributedVirtualPortgroup");
+        return (String)_context.getVimClient().getDynamicProperty(dvPortGroupMor, "name");
+    }
+
+    public VirtualDevice[] getMatchedDevices(Class<?>[] deviceClasses) throws Exception {
+        assert (deviceClasses != null);
+
+        List<VirtualDevice> returnList = new ArrayList<VirtualDevice>();
+
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null) {
+            for (VirtualDevice device : devices) {
+                for (Class<?> clz : deviceClasses) {
+                    if (clz.isInstance(device)) {
+                        returnList.add(device);
+                        break;
+                    }
+                }
+            }
+        }
+
+        return returnList.toArray(new VirtualDevice[0]);
+    }
+
+    public void mountToolsInstaller() throws Exception {
+        _context.getService().mountToolsInstaller(_mor);
+    }
+
+    public boolean unmountToolsInstaller() throws Exception {
+        // Monitor VM questions
+        final Boolean[] flags = {false};
+        final VirtualMachineMO vmMo = this;
+        final boolean[] encounterQuestion = new boolean[1];
+        encounterQuestion[0] = false;
+        Future<?> future = MonitorServiceExecutor.submit(new Runnable() {
+            @Override
+            public void run() {
+                s_logger.info("VM Question monitor started...");
+
+                while (!flags[0]) {
+                    try {
+                        VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo();
+                        VirtualMachineQuestionInfo question = runtimeInfo.getQuestion();
+                        if (question != null) {
+                            encounterQuestion[0] = true;
+                            if (s_logger.isTraceEnabled()) {
+                                s_logger.trace("Question id: " + question.getId());
+                                s_logger.trace("Question text: " + question.getText());
+                            }
+
+                            if (question.getMessage() != null) {
+                                for (VirtualMachineMessage msg : question.getMessage()) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("msg id: " + msg.getId());
+                                        s_logger.trace("msg text: " + msg.getText());
+                                    }
+                                    if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msg.getId())) {
+                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId() +
+                                                ", for safe operation we will automatically decline it");
+                                        vmMo.answerVM(question.getId(), ANSWER_NO);
+                                        break;
+                                    }
+                                }
+                            } else if (question.getText() != null) {
+                                String text = question.getText();
+                                String msgId;
+                                String msgText;
+                                if (s_logger.isDebugEnabled()) {
+                                    s_logger.debug("question text : " + text);
+                                }
+                                String[] tokens = text.split(":");
+                                msgId = tokens[0];
+                                msgText = tokens[1];
+                                if ("msg.cdromdisconnect.locked".equalsIgnoreCase(msgId)) {
+                                    s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + question.getId() +
+                                            ". Message id : " + msgId + ". Message text : " + msgText + ", for safe operation we will automatically decline it.");
+                                    vmMo.answerVM(question.getId(), ANSWER_NO);
+                                }
+                            }
+
+                            ChoiceOption choice = question.getChoice();
+                            if (choice != null) {
+                                for (ElementDescription info : choice.getChoiceInfo()) {
+                                    if (s_logger.isTraceEnabled()) {
+                                        s_logger.trace("Choice option key: " + info.getKey());
+                                        s_logger.trace("Choice option label: " + info.getLabel());
+                                    }
+                                }
+                            }
+                        }
+                    } catch (Throwable e) {
+                        s_logger.error("Unexpected exception: ", e);
+                    }
+
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        s_logger.debug("[ignored] interupted while handling vm question about umount tools install.");
+                    }
+                }
+
+                s_logger.info("VM Question monitor stopped");
+            }
+        });
+
+        try {
+            _context.getService().unmountToolsInstaller(_mor);
+        } finally {
+            flags[0] = true;
+            future.cancel(true);
+        }
+        if (encounterQuestion[0]) {
+            s_logger.warn("cdrom is locked by VM. Failed to detach the ISO.");
+            return false;
+        } else {
+            s_logger.info("Successfully unmounted tools installer from VM.");
+            return true;
+        }
+    }
+
+    public void redoRegistration(ManagedObjectReference morHost) throws Exception {
+        String vmName = getVmName();
+        VirtualMachineFileInfo vmFileInfo = getFileInfo();
+        boolean isTemplate = isTemplate();
+
+        HostMO hostMo;
+        if (morHost != null)
+            hostMo = new HostMO(getContext(), morHost);
+        else
+            hostMo = getRunningHost();
+
+        ManagedObjectReference morFolder = getParentMor();
+        ManagedObjectReference morPool = hostMo.getHyperHostOwnerResourcePool();
+
+        _context.getService().unregisterVM(_mor);
+
+        ManagedObjectReference morTask = _context.getService().registerVMTask(morFolder, vmFileInfo.getVmPathName(), vmName, false, morPool, hostMo.getMor());
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (!result) {
+            throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        } else {
+            _context.waitForTaskProgressDone(morTask);
+            if (isTemplate) {
+                VirtualMachineMO vmNewRegistration = hostMo.findVmOnHyperHost(vmName);
+                assert (vmNewRegistration != null);
+                vmNewRegistration.markAsTemplate();
+            }
+        }
+    }
+
+    public long getHotAddMemoryIncrementSizeInMb() throws Exception {
+        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize");
+    }
+
+    public long getHotAddMemoryLimitInMb() throws Exception {
+        return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit");
+    }
+    public String getGuestId() throws Exception {
+        return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId");
+    }
+
+    public int getCoresPerSocket() throws Exception {
+        // number of cores per socket is 1 in case of ESXi. It's not defined explicitly and the property is support since vSphere API 5.0.
+        String apiVersion = HypervisorHostHelper.getVcenterApiVersion(_context);
+        if (apiVersion.compareTo("5.0") < 0) {
+            return 1;
+        }
+        Integer coresPerSocket = (Integer)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket");
+        return coresPerSocket != null ? coresPerSocket : 1;
+    }
+
+    public int getVirtualHardwareVersion() throws Exception {
+        VirtualHardwareOption vhOption = getVirtualHardwareOption();
+        return vhOption.getHwVersion();
+    }
+
+    public VirtualHardwareOption getVirtualHardwareOption() throws Exception {
+        VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(getEnvironmentBrowser(), null, null);
+        return vmConfigOption.getHardwareOptions();
+    }
+
+    private ManagedObjectReference getEnvironmentBrowser() throws Exception {
+        if (_vmEnvironmentBrowser == null) {
+            _vmEnvironmentBrowser = _context.getVimClient().getMoRefProp(_mor, "environmentBrowser");
+        }
+        return _vmEnvironmentBrowser;
+    }
+
+    public boolean isCpuHotAddSupported(String guestOsId) throws Exception {
+        boolean guestOsSupportsCpuHotAdd = false;
+        boolean virtualHardwareSupportsCpuHotAdd = false;
+        GuestOsDescriptor guestOsDescriptor;
+        int virtualHardwareVersion;
+        int numCoresPerSocket;
+
+        guestOsDescriptor = getGuestOsDescriptor(guestOsId);
+        virtualHardwareVersion = getVirtualHardwareVersion();
+
+        // Check if guest operating system supports cpu hotadd
+        if (guestOsDescriptor.isSupportsCpuHotAdd()) {
+            guestOsSupportsCpuHotAdd = true;
+        }
+
+        // Check if virtual machine is using hardware version 8 or later.
+        // If hardware version is 7, then only 1 core per socket is supported. Hot adding multi-core vcpus is not allowed if hardware version is 7.
+        if (virtualHardwareVersion >= 8) {
+            virtualHardwareSupportsCpuHotAdd = true;
+        } else if (virtualHardwareVersion == 7) {
+            // Check if virtual machine has only 1 core per socket.
+            numCoresPerSocket = getCoresPerSocket();
+            if (numCoresPerSocket == 1) {
+                virtualHardwareSupportsCpuHotAdd = true;
+            }
+        }
+        return guestOsSupportsCpuHotAdd && virtualHardwareSupportsCpuHotAdd;
+    }
+
+    public boolean isMemoryHotAddSupported(String guestOsId) throws Exception {
+        boolean guestOsSupportsMemoryHotAdd = false;
+        boolean virtualHardwareSupportsMemoryHotAdd = false;
+        GuestOsDescriptor guestOsDescriptor;
+        int virtualHardwareVersion;
+
+        guestOsDescriptor = getGuestOsDescriptor(guestOsId);
+        virtualHardwareVersion = getVirtualHardwareVersion();
+
+        // Check if guest operating system supports memory hotadd
+        if (guestOsDescriptor != null && guestOsDescriptor.isSupportsMemoryHotAdd()) {
+            guestOsSupportsMemoryHotAdd = true;
+        }
+        // Check if virtual machine is using hardware version 7 or later.
+        if (virtualHardwareVersion >= 7) {
+            virtualHardwareSupportsMemoryHotAdd = true;
+        }
+        return guestOsSupportsMemoryHotAdd && virtualHardwareSupportsMemoryHotAdd;
+    }
+    public void ensureLsiLogicSasDeviceControllers(int count, int availableBusNum) throws Exception {
+        int scsiControllerKey = getLsiLogicSasDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+                VirtualLsiLogicSASController scsiController = new VirtualLsiLogicSASController();
+                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+                scsiControllerSpec.setDevice(scsiController);
+                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controller of type LsiLogic SAS.");
+            }
+        }
+
+    }
+
+    private int getLsiLogicSasDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualLsiLogicSASController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public void ensureBusLogicDeviceControllers(int count, int availableBusNum) throws Exception {
+        int scsiControllerKey = getBusLogicDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+                VirtualBusLogicController scsiController = new VirtualBusLogicController();
+
+                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+                scsiControllerSpec.setDevice(scsiController);
+                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi BusLogic controllers to the VM " + getName());
+            } else {
+                s_logger.info("Successfully added " + count + " SCSI BusLogic controllers.");
+            }
+        }
+    }
+
+    private int getBusLogicDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualBusLogicController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public Ternary<Integer, Integer, DiskControllerType> getScsiControllerInfo() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        int scsiControllerCount = 0;
+        int busNum = -1;
+        DiskControllerType controllerType = DiskControllerType.lsilogic;
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualSCSIController) {
+                    scsiControllerCount++;
+                    int deviceBus = ((VirtualSCSIController)device).getBusNumber();
+                    if (busNum < deviceBus) {
+                        busNum = deviceBus;
+                    }
+                    if (device instanceof VirtualLsiLogicController) {
+                        controllerType = DiskControllerType.lsilogic;
+                    } else if (device instanceof VirtualLsiLogicSASController) {
+                        controllerType = DiskControllerType.lsisas1068;
+                    } else if (device instanceof VirtualBusLogicController) {
+                        controllerType = DiskControllerType.buslogic;
+                    } else if (device instanceof ParaVirtualSCSIController) {
+                        controllerType = DiskControllerType.pvscsi;
+                    }
+                }
+            }
+        }
+
+        return new Ternary<Integer, Integer, DiskControllerType>(scsiControllerCount, busNum, controllerType);
+    }
+
+    public int getNumberOfVirtualDisks() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
+
+        s_logger.info("Counting disk devices attached to VM " + getVmName());
+        int count = 0;
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+    public boolean consolidateVmDisks() throws Exception {
+        ManagedObjectReference morTask = _context.getService().consolidateVMDisksTask(_mor);
+        boolean result = _context.getVimClient().waitForTask(morTask);
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+            return true;
+        } else {
+            s_logger.error("VMware ConsolidateVMDisks_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
+        return false;
+    }
+}
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualSwitchType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHostType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHostType.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHostType.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHostType.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostNetworkSummary.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostNetworkSummary.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostNetworkSummary.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostNetworkSummary.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostResourceSummary.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostResourceSummary.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostResourceSummary.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHostResourceSummary.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContext.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContextPool.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareContextPool.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContextPool.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareGuestOsMapper.java
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
similarity index 100%
rename from vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
rename to vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/DatastoreMOTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/DatastoreMOTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/mo/DatastoreMOTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/DatastoreMOTest.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/TestVmwareContextFactory.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/VmwareMOTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/VmwareMOTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/mo/VmwareMOTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/VmwareMOTest.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/util/VmwareContextPoolTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareContextPoolTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/util/VmwareContextPoolTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareContextPoolTest.java
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/util/VmwareContextTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareContextTest.java
similarity index 100%
rename from vmware-base/test/com/cloud/hypervisor/vmware/util/VmwareContextTest.java
rename to vmware-base/src/test/java/com/cloud/hypervisor/vmware/util/VmwareContextTest.java
